aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormixa108 <mixa108@yandex-team.com>2023-11-16 19:41:57 +0300
committermixa108 <mixa108@yandex-team.com>2023-11-16 20:39:42 +0300
commit177b2aacb85a58acd19ca2e22d79c6030cd4c68b (patch)
tree948ffeb9b1aa2a741b4a89fbecdffee6460f1031
parentb098c151d43da3ece1440d49d69bf76061429aeb (diff)
downloadydb-177b2aacb85a58acd19ca2e22d79c6030cd4c68b.tar.gz
bump go ver 1.21.3
bump go to 1.21.3 build go.conf Golang 1.20.6 -> 1.21.3 init Golang 1.20.6 -> 1.21.3: copy blame
-rw-r--r--build/conf/go.conf9
-rw-r--r--build/external_resources/go_tools/go1.21.json19
-rw-r--r--build/external_resources/go_tools/ya.make2
-rw-r--r--build/mapping.conf.json20
-rw-r--r--contrib/go/_std_1.20/src/archive/tar/common.go732
-rw-r--r--contrib/go/_std_1.20/src/archive/tar/reader.go879
-rw-r--r--contrib/go/_std_1.20/src/archive/tar/ya.make25
-rw-r--r--contrib/go/_std_1.20/src/archive/zip/reader.go961
-rw-r--r--contrib/go/_std_1.20/src/archive/zip/struct.go415
-rw-r--r--contrib/go/_std_1.20/src/archive/zip/ya.make10
-rw-r--r--contrib/go/_std_1.20/src/bufio/bufio.go828
-rw-r--r--contrib/go/_std_1.20/src/bufio/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/bytes/buffer.go473
-rw-r--r--contrib/go/_std_1.20/src/bytes/bytes.go1381
-rw-r--r--contrib/go/_std_1.20/src/bytes/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/compress/flate/inflate.go825
-rw-r--r--contrib/go/_std_1.20/src/compress/flate/ya.make13
-rw-r--r--contrib/go/_std_1.20/src/compress/gzip/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/compress/zlib/reader.go180
-rw-r--r--contrib/go/_std_1.20/src/compress/zlib/writer.go193
-rw-r--r--contrib/go/_std_1.20/src/compress/zlib/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/container/heap/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/container/list/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/context/context.go653
-rw-r--r--contrib/go/_std_1.20/src/context/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/crypto/aes/asm_arm64.s281
-rw-r--r--contrib/go/_std_1.20/src/crypto/aes/gcm_arm64.s1021
-rw-r--r--contrib/go/_std_1.20/src/crypto/aes/ya.make26
-rw-r--r--contrib/go/_std_1.20/src/crypto/cipher/ya.make13
-rw-r--r--contrib/go/_std_1.20/src/crypto/des/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/crypto/dsa/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/crypto/ecdh/ecdh.go184
-rw-r--r--contrib/go/_std_1.20/src/crypto/ecdh/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/crypto/ecdsa/ecdsa.go660
-rw-r--r--contrib/go/_std_1.20/src/crypto/ecdsa/ya.make10
-rw-r--r--contrib/go/_std_1.20/src/crypto/ed25519/ed25519.go337
-rw-r--r--contrib/go/_std_1.20/src/crypto/ed25519/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/crypto/elliptic/elliptic.go275
-rw-r--r--contrib/go/_std_1.20/src/crypto/elliptic/params.go333
-rw-r--r--contrib/go/_std_1.20/src/crypto/elliptic/ya.make10
-rw-r--r--contrib/go/_std_1.20/src/crypto/hmac/hmac.go180
-rw-r--r--contrib/go/_std_1.20/src/crypto/hmac/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/alias/alias.go30
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/bigmod/nat.go703
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/bigmod/nat_amd64.go8
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/bigmod/nat_amd64.s68
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/bigmod/nat_noasm.go11
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/bigmod/ya.make20
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/boring/bcache/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/boring/sig/ya.make19
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/boring/ya.make15
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/edwards25519/edwards25519.go426
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_generic.go266
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/ya.make28
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/edwards25519/scalar.go343
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/edwards25519/ya.make16
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/ya.make18
-rw-r--r--contrib/go/_std_1.20/src/crypto/internal/nistec/ya.make31
-rw-r--r--contrib/go/_std_1.20/src/crypto/md5/md5block_decl.go13
-rw-r--r--contrib/go/_std_1.20/src/crypto/md5/ya.make21
-rw-r--r--contrib/go/_std_1.20/src/crypto/rand/rand.go44
-rw-r--r--contrib/go/_std_1.20/src/crypto/rand/rand_getrandom.go48
-rw-r--r--contrib/go/_std_1.20/src/crypto/rand/ya.make28
-rw-r--r--contrib/go/_std_1.20/src/crypto/rc4/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/crypto/rsa/pkcs1v15.go375
-rw-r--r--contrib/go/_std_1.20/src/crypto/rsa/pss.go372
-rw-r--r--contrib/go/_std_1.20/src/crypto/rsa/rsa.go737
-rw-r--r--contrib/go/_std_1.20/src/crypto/rsa/ya.make10
-rw-r--r--contrib/go/_std_1.20/src/crypto/sha1/notboring.go20
-rw-r--r--contrib/go/_std_1.20/src/crypto/sha1/sha1block.go83
-rw-r--r--contrib/go/_std_1.20/src/crypto/sha1/sha1block_amd64.s1500
-rw-r--r--contrib/go/_std_1.20/src/crypto/sha1/ya.make32
-rw-r--r--contrib/go/_std_1.20/src/crypto/sha256/sha256block_amd64.go9
-rw-r--r--contrib/go/_std_1.20/src/crypto/sha256/sha256block_amd64.s1031
-rw-r--r--contrib/go/_std_1.20/src/crypto/sha256/sha256block_decl.go11
-rw-r--r--contrib/go/_std_1.20/src/crypto/sha256/ya.make23
-rw-r--r--contrib/go/_std_1.20/src/crypto/sha512/ya.make22
-rw-r--r--contrib/go/_std_1.20/src/crypto/subtle/ya.make22
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/alert.go99
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/cache.go95
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/cipher_suites.go702
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/common.go1510
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/conn.go1570
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/handshake_client.go1031
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/handshake_client_tls13.go709
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/handshake_messages.go1852
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/handshake_server.go890
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/handshake_server_tls13.go893
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/key_schedule.go158
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/prf.go283
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/ticket.go185
-rw-r--r--contrib/go/_std_1.20/src/crypto/tls/ya.make24
-rw-r--r--contrib/go/_std_1.20/src/crypto/x509/internal/macos/ya.make14
-rw-r--r--contrib/go/_std_1.20/src/crypto/x509/parser.go1175
-rw-r--r--contrib/go/_std_1.20/src/crypto/x509/pkcs8.go175
-rw-r--r--contrib/go/_std_1.20/src/crypto/x509/root.go72
-rw-r--r--contrib/go/_std_1.20/src/crypto/x509/root_unix.go108
-rw-r--r--contrib/go/_std_1.20/src/crypto/x509/root_windows.go276
-rw-r--r--contrib/go/_std_1.20/src/crypto/x509/sec1.go136
-rw-r--r--contrib/go/_std_1.20/src/crypto/x509/verify.go1179
-rw-r--r--contrib/go/_std_1.20/src/crypto/x509/x509.go2370
-rw-r--r--contrib/go/_std_1.20/src/crypto/x509/ya.make40
-rw-r--r--contrib/go/_std_1.20/src/crypto/ya.make30
-rw-r--r--contrib/go/_std_1.20/src/database/sql/convert.go591
-rw-r--r--contrib/go/_std_1.20/src/database/sql/driver/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/database/sql/sql.go3406
-rw-r--r--contrib/go/_std_1.20/src/database/sql/ya.make13
-rw-r--r--contrib/go/_std_1.20/src/debug/dwarf/class_string.go37
-rw-r--r--contrib/go/_std_1.20/src/debug/dwarf/entry.go1218
-rw-r--r--contrib/go/_std_1.20/src/debug/dwarf/ya.make17
-rw-r--r--contrib/go/_std_1.20/src/debug/elf/elf.go3478
-rw-r--r--contrib/go/_std_1.20/src/debug/elf/file.go1649
-rw-r--r--contrib/go/_std_1.20/src/debug/elf/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/embed/embed.go432
-rw-r--r--contrib/go/_std_1.20/src/embed/ya.make11
-rw-r--r--contrib/go/_std_1.20/src/encoding/ascii85/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/encoding/asn1/asn1.go1122
-rw-r--r--contrib/go/_std_1.20/src/encoding/asn1/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/encoding/base32/base32.go549
-rw-r--r--contrib/go/_std_1.20/src/encoding/base32/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/encoding/base64/base64.go627
-rw-r--r--contrib/go/_std_1.20/src/encoding/base64/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/encoding/binary/binary.go804
-rw-r--r--contrib/go/_std_1.20/src/encoding/binary/varint.go166
-rw-r--r--contrib/go/_std_1.20/src/encoding/binary/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/encoding/csv/reader.go465
-rw-r--r--contrib/go/_std_1.20/src/encoding/csv/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/encoding/encoding.go48
-rw-r--r--contrib/go/_std_1.20/src/encoding/gob/dec_helpers.go544
-rw-r--r--contrib/go/_std_1.20/src/encoding/gob/decode.go1308
-rw-r--r--contrib/go/_std_1.20/src/encoding/gob/doc.go423
-rw-r--r--contrib/go/_std_1.20/src/encoding/gob/encode.go705
-rw-r--r--contrib/go/_std_1.20/src/encoding/gob/encoder.go258
-rw-r--r--contrib/go/_std_1.20/src/encoding/gob/type.go913
-rw-r--r--contrib/go/_std_1.20/src/encoding/gob/ya.make15
-rw-r--r--contrib/go/_std_1.20/src/encoding/hex/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/encoding/json/decode.go1311
-rw-r--r--contrib/go/_std_1.20/src/encoding/json/encode.go1417
-rw-r--r--contrib/go/_std_1.20/src/encoding/json/fold.go141
-rw-r--r--contrib/go/_std_1.20/src/encoding/json/indent.go143
-rw-r--r--contrib/go/_std_1.20/src/encoding/json/stream.go515
-rw-r--r--contrib/go/_std_1.20/src/encoding/json/ya.make14
-rw-r--r--contrib/go/_std_1.20/src/encoding/pem/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/encoding/xml/marshal.go1129
-rw-r--r--contrib/go/_std_1.20/src/encoding/xml/read.go775
-rw-r--r--contrib/go/_std_1.20/src/encoding/xml/xml.go2057
-rw-r--r--contrib/go/_std_1.20/src/encoding/xml/ya.make10
-rw-r--r--contrib/go/_std_1.20/src/errors/errors.go72
-rw-r--r--contrib/go/_std_1.20/src/errors/join.go51
-rw-r--r--contrib/go/_std_1.20/src/errors/wrap.go135
-rw-r--r--contrib/go/_std_1.20/src/errors/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/expvar/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/flag/flag.go1182
-rw-r--r--contrib/go/_std_1.20/src/flag/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/fmt/print.go1226
-rw-r--r--contrib/go/_std_1.20/src/fmt/scan.go1238
-rw-r--r--contrib/go/_std_1.20/src/fmt/ya.make11
-rw-r--r--contrib/go/_std_1.20/src/go/ast/ast.go1074
-rw-r--r--contrib/go/_std_1.20/src/go/ast/filter.go495
-rw-r--r--contrib/go/_std_1.20/src/go/ast/ya.make14
-rw-r--r--contrib/go/_std_1.20/src/go/build/build.go2012
-rw-r--r--contrib/go/_std_1.20/src/go/build/constraint/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/go/build/read.go600
-rw-r--r--contrib/go/_std_1.20/src/go/build/syslist.go80
-rw-r--r--contrib/go/_std_1.20/src/go/build/ya.make16
-rw-r--r--contrib/go/_std_1.20/src/go/build/zcgo.go50
-rw-r--r--contrib/go/_std_1.20/src/go/constant/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/go/doc/comment/print.go290
-rw-r--r--contrib/go/_std_1.20/src/go/doc/comment/std.go44
-rw-r--r--contrib/go/_std_1.20/src/go/doc/comment/ya.make13
-rw-r--r--contrib/go/_std_1.20/src/go/doc/ya.make17
-rw-r--r--contrib/go/_std_1.20/src/go/format/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/go/importer/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/go/internal/gccgoimporter/ya.make10
-rw-r--r--contrib/go/_std_1.20/src/go/internal/gcimporter/gcimporter.go245
-rw-r--r--contrib/go/_std_1.20/src/go/internal/gcimporter/ureader.go682
-rw-r--r--contrib/go/_std_1.20/src/go/internal/gcimporter/ya.make11
-rw-r--r--contrib/go/_std_1.20/src/go/internal/srcimporter/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/go/parser/parser.go2864
-rw-r--r--contrib/go/_std_1.20/src/go/parser/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/go/printer/printer.go1436
-rw-r--r--contrib/go/_std_1.20/src/go/printer/ya.make10
-rw-r--r--contrib/go/_std_1.20/src/go/scanner/scanner.go957
-rw-r--r--contrib/go/_std_1.20/src/go/scanner/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/go/token/position.go556
-rw-r--r--contrib/go/_std_1.20/src/go/token/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/go/types/api.go492
-rw-r--r--contrib/go/_std_1.20/src/go/types/array.go25
-rw-r--r--contrib/go/_std_1.20/src/go/types/assignments.go475
-rw-r--r--contrib/go/_std_1.20/src/go/types/basic.go82
-rw-r--r--contrib/go/_std_1.20/src/go/types/builtins.go1017
-rw-r--r--contrib/go/_std_1.20/src/go/types/call.go817
-rw-r--r--contrib/go/_std_1.20/src/go/types/chan.go35
-rw-r--r--contrib/go/_std_1.20/src/go/types/check.go578
-rw-r--r--contrib/go/_std_1.20/src/go/types/context.go144
-rw-r--r--contrib/go/_std_1.20/src/go/types/conversions.go296
-rw-r--r--contrib/go/_std_1.20/src/go/types/decl.go937
-rw-r--r--contrib/go/_std_1.20/src/go/types/errors.go390
-rw-r--r--contrib/go/_std_1.20/src/go/types/eval.go99
-rw-r--r--contrib/go/_std_1.20/src/go/types/expr.go1826
-rw-r--r--contrib/go/_std_1.20/src/go/types/gccgosizes.go41
-rw-r--r--contrib/go/_std_1.20/src/go/types/index.go456
-rw-r--r--contrib/go/_std_1.20/src/go/types/infer.go773
-rw-r--r--contrib/go/_std_1.20/src/go/types/instantiate.go366
-rw-r--r--contrib/go/_std_1.20/src/go/types/interface.go233
-rw-r--r--contrib/go/_std_1.20/src/go/types/lookup.go543
-rw-r--r--contrib/go/_std_1.20/src/go/types/map.go24
-rw-r--r--contrib/go/_std_1.20/src/go/types/methodset.go238
-rw-r--r--contrib/go/_std_1.20/src/go/types/mono.go337
-rw-r--r--contrib/go/_std_1.20/src/go/types/named.go656
-rw-r--r--contrib/go/_std_1.20/src/go/types/object.go568
-rw-r--r--contrib/go/_std_1.20/src/go/types/objset.go31
-rw-r--r--contrib/go/_std_1.20/src/go/types/operand.go368
-rw-r--r--contrib/go/_std_1.20/src/go/types/package.go74
-rw-r--r--contrib/go/_std_1.20/src/go/types/pointer.go19
-rw-r--r--contrib/go/_std_1.20/src/go/types/predicates.go497
-rw-r--r--contrib/go/_std_1.20/src/go/types/resolver.go726
-rw-r--r--contrib/go/_std_1.20/src/go/types/scope.go292
-rw-r--r--contrib/go/_std_1.20/src/go/types/selection.go142
-rw-r--r--contrib/go/_std_1.20/src/go/types/signature.go321
-rw-r--r--contrib/go/_std_1.20/src/go/types/sizes.go296
-rw-r--r--contrib/go/_std_1.20/src/go/types/slice.go19
-rw-r--r--contrib/go/_std_1.20/src/go/types/stmt.go962
-rw-r--r--contrib/go/_std_1.20/src/go/types/struct.go218
-rw-r--r--contrib/go/_std_1.20/src/go/types/subst.go421
-rw-r--r--contrib/go/_std_1.20/src/go/types/termlist.go161
-rw-r--r--contrib/go/_std_1.20/src/go/types/tuple.go34
-rw-r--r--contrib/go/_std_1.20/src/go/types/type.go124
-rw-r--r--contrib/go/_std_1.20/src/go/types/typelists.go69
-rw-r--r--contrib/go/_std_1.20/src/go/types/typeparam.go158
-rw-r--r--contrib/go/_std_1.20/src/go/types/typeset.go434
-rw-r--r--contrib/go/_std_1.20/src/go/types/typestring.go491
-rw-r--r--contrib/go/_std_1.20/src/go/types/typeterm.go165
-rw-r--r--contrib/go/_std_1.20/src/go/types/typexpr.go521
-rw-r--r--contrib/go/_std_1.20/src/go/types/unify.go583
-rw-r--r--contrib/go/_std_1.20/src/go/types/union.go200
-rw-r--r--contrib/go/_std_1.20/src/go/types/universe.go284
-rw-r--r--contrib/go/_std_1.20/src/go/types/validtype.go256
-rw-r--r--contrib/go/_std_1.20/src/go/types/version.go83
-rw-r--r--contrib/go/_std_1.20/src/go/types/ya.make63
-rw-r--r--contrib/go/_std_1.20/src/hash/adler32/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/hash/crc32/ya.make22
-rw-r--r--contrib/go/_std_1.20/src/hash/crc64/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/hash/fnv/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/hash/maphash/maphash.go308
-rw-r--r--contrib/go/_std_1.20/src/hash/maphash/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/hash/ya.make15
-rw-r--r--contrib/go/_std_1.20/src/html/template/attr_string.go16
-rw-r--r--contrib/go/_std_1.20/src/html/template/context.go268
-rw-r--r--contrib/go/_std_1.20/src/html/template/delim_string.go16
-rw-r--r--contrib/go/_std_1.20/src/html/template/doc.go242
-rw-r--r--contrib/go/_std_1.20/src/html/template/element_string.go16
-rw-r--r--contrib/go/_std_1.20/src/html/template/error.go249
-rw-r--r--contrib/go/_std_1.20/src/html/template/escape.go978
-rw-r--r--contrib/go/_std_1.20/src/html/template/state_string.go49
-rw-r--r--contrib/go/_std_1.20/src/html/template/transition.go597
-rw-r--r--contrib/go/_std_1.20/src/html/template/urlpart_string.go16
-rw-r--r--contrib/go/_std_1.20/src/html/template/ya.make24
-rw-r--r--contrib/go/_std_1.20/src/html/ya.make12
-rw-r--r--contrib/go/_std_1.20/src/image/color/ya.make12
-rw-r--r--contrib/go/_std_1.20/src/image/ya.make20
-rw-r--r--contrib/go/_std_1.20/src/internal/abi/abi.go126
-rw-r--r--contrib/go/_std_1.20/src/internal/abi/ya.make20
-rw-r--r--contrib/go/_std_1.20/src/internal/buildcfg/cfg.go234
-rw-r--r--contrib/go/_std_1.20/src/internal/buildcfg/exp.go190
-rw-r--r--contrib/go/_std_1.20/src/internal/buildcfg/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/internal/buildcfg/zbootstrap.go18
-rw-r--r--contrib/go/_std_1.20/src/internal/bytealg/bytealg.go150
-rw-r--r--contrib/go/_std_1.20/src/internal/bytealg/index_native.go19
-rw-r--r--contrib/go/_std_1.20/src/internal/bytealg/ya.make35
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/cformat/format.go340
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/cformat/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/cmddefs.go73
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/cmerge/merge.go104
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/cmerge/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/decodecounter/decodecounterfile.go373
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/decodemeta/decode.go128
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/defs.go374
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/encodecounter/encode.go284
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/pods/pods.go194
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/pods/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/slicereader/slicereader.go98
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/slicereader/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/slicewriter/slicewriter.go80
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/slicewriter/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/coverage/ya.make26
-rw-r--r--contrib/go/_std_1.20/src/internal/cpu/cpu.go223
-rw-r--r--contrib/go/_std_1.20/src/internal/cpu/cpu_arm64.go70
-rw-r--r--contrib/go/_std_1.20/src/internal/cpu/cpu_arm64_hwcap.go62
-rw-r--r--contrib/go/_std_1.20/src/internal/cpu/ya.make42
-rw-r--r--contrib/go/_std_1.20/src/internal/fmtsort/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/fuzz/fuzz.go1083
-rw-r--r--contrib/go/_std_1.20/src/internal/fuzz/worker.go1184
-rw-r--r--contrib/go/_std_1.20/src/internal/fuzz/ya.make36
-rw-r--r--contrib/go/_std_1.20/src/internal/goarch/ya.make21
-rw-r--r--contrib/go/_std_1.20/src/internal/godebug/godebug.go165
-rw-r--r--contrib/go/_std_1.20/src/internal/godebug/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/goexperiment/exp_coverageredesign_off.go9
-rw-r--r--contrib/go/_std_1.20/src/internal/goexperiment/exp_unified_off.go9
-rw-r--r--contrib/go/_std_1.20/src/internal/goexperiment/flags.go103
-rw-r--r--contrib/go/_std_1.20/src/internal/goexperiment/ya.make18
-rw-r--r--contrib/go/_std_1.20/src/internal/goos/ya.make28
-rw-r--r--contrib/go/_std_1.20/src/internal/goos/zgoos_darwin.go25
-rw-r--r--contrib/go/_std_1.20/src/internal/goos/zgoos_linux.go25
-rw-r--r--contrib/go/_std_1.20/src/internal/goos/zgoos_windows.go25
-rw-r--r--contrib/go/_std_1.20/src/internal/goroot/gc.go131
-rw-r--r--contrib/go/_std_1.20/src/internal/goroot/importcfg.go66
-rw-r--r--contrib/go/_std_1.20/src/internal/goroot/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/internal/goversion/goversion.go12
-rw-r--r--contrib/go/_std_1.20/src/internal/intern/intern.go181
-rw-r--r--contrib/go/_std_1.20/src/internal/intern/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/itoa/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/pkgbits/syncmarker_string.go89
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/errno_unix.go33
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/fcntl_libc.go15
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/fcntl_syscall.go20
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/fd_fsync_darwin.go21
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/fd_fsync_posix.go20
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/fd_poll_runtime.go170
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/fd_posix.go79
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/fd_unix.go799
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/fd_windows.go1321
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/hook_unix.go15
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/sendfile_windows.go81
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/sock_cloexec.go22
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/sockopt.go36
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/splice_linux.go231
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/sys_cloexec.go36
-rw-r--r--contrib/go/_std_1.20/src/internal/poll/ya.make60
-rw-r--r--contrib/go/_std_1.20/src/internal/profile/legacy_profile.go1268
-rw-r--r--contrib/go/_std_1.20/src/internal/profile/profile.go613
-rw-r--r--contrib/go/_std_1.20/src/internal/profile/ya.make13
-rw-r--r--contrib/go/_std_1.20/src/internal/race/ya.make23
-rw-r--r--contrib/go/_std_1.20/src/internal/reflectlite/swapper.go78
-rw-r--r--contrib/go/_std_1.20/src/internal/reflectlite/type.go974
-rw-r--r--contrib/go/_std_1.20/src/internal/reflectlite/value.go477
-rw-r--r--contrib/go/_std_1.20/src/internal/reflectlite/ya.make10
-rw-r--r--contrib/go/_std_1.20/src/internal/safefilepath/ya.make25
-rw-r--r--contrib/go/_std_1.20/src/internal/saferio/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/singleflight/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/execenv/execenv_windows.go54
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/execenv/ya.make21
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_darwin.go8
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_linux.go17
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/unix/getrandom.go39
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/unix/net_darwin.go161
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/unix/nonblocking.go25
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/unix/nonblocking_libc.go30
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/unix/ya.make62
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/windows/net_windows.go18
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/windows/registry/value.go372
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/windows/registry/ya.make14
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/windows/syscall_windows.go369
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/windows/sysdll/ya.make11
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/windows/ya.make25
-rw-r--r--contrib/go/_std_1.20/src/internal/syscall/windows/zsyscall_windows.go354
-rw-r--r--contrib/go/_std_1.20/src/internal/types/errors/codes.go1442
-rw-r--r--contrib/go/_std_1.20/src/internal/types/errors/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/unsafeheader/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/internal/xcoff/ar.go228
-rw-r--r--contrib/go/_std_1.20/src/internal/xcoff/file.go692
-rw-r--r--contrib/go/_std_1.20/src/internal/xcoff/xcoff.go367
-rw-r--r--contrib/go/_std_1.20/src/internal/xcoff/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/io/fs/readdir.go77
-rw-r--r--contrib/go/_std_1.20/src/io/fs/walk.go137
-rw-r--r--contrib/go/_std_1.20/src/io/fs/ya.make13
-rw-r--r--contrib/go/_std_1.20/src/io/io.go710
-rw-r--r--contrib/go/_std_1.20/src/io/ioutil/ioutil.go95
-rw-r--r--contrib/go/_std_1.20/src/io/ioutil/tempfile.go41
-rw-r--r--contrib/go/_std_1.20/src/io/ioutil/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/io/ya.make14
-rw-r--r--contrib/go/_std_1.20/src/log/log.go410
-rw-r--r--contrib/go/_std_1.20/src/log/syslog/ya.make21
-rw-r--r--contrib/go/_std_1.20/src/log/ya.make11
-rw-r--r--contrib/go/_std_1.20/src/math/asinh.go77
-rw-r--r--contrib/go/_std_1.20/src/math/big/accuracy_string.go17
-rw-r--r--contrib/go/_std_1.20/src/math/big/doc.go99
-rw-r--r--contrib/go/_std_1.20/src/math/big/float.go1729
-rw-r--r--contrib/go/_std_1.20/src/math/big/floatconv.go302
-rw-r--r--contrib/go/_std_1.20/src/math/big/floatmarsh.go127
-rw-r--r--contrib/go/_std_1.20/src/math/big/int.go1293
-rw-r--r--contrib/go/_std_1.20/src/math/big/roundingmode_string.go16
-rw-r--r--contrib/go/_std_1.20/src/math/big/ya.make40
-rw-r--r--contrib/go/_std_1.20/src/math/bits/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/math/cmplx/ya.make20
-rw-r--r--contrib/go/_std_1.20/src/math/dim.go94
-rw-r--r--contrib/go/_std_1.20/src/math/fma.go170
-rw-r--r--contrib/go/_std_1.20/src/math/log_amd64.s112
-rw-r--r--contrib/go/_std_1.20/src/math/pow.go157
-rw-r--r--contrib/go/_std_1.20/src/math/rand/rand.go473
-rw-r--r--contrib/go/_std_1.20/src/math/rand/rng.go252
-rw-r--r--contrib/go/_std_1.20/src/math/rand/ya.make11
-rw-r--r--contrib/go/_std_1.20/src/math/ya.make90
-rw-r--r--contrib/go/_std_1.20/src/mime/multipart/formdata.go301
-rw-r--r--contrib/go/_std_1.20/src/mime/multipart/multipart.go487
-rw-r--r--contrib/go/_std_1.20/src/mime/multipart/ya.make10
-rw-r--r--contrib/go/_std_1.20/src/mime/quotedprintable/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/mime/type_unix.go126
-rw-r--r--contrib/go/_std_1.20/src/mime/ya.make33
-rw-r--r--contrib/go/_std_1.20/src/net/cgo_unix.go412
-rw-r--r--contrib/go/_std_1.20/src/net/cgo_unix_cgo.go76
-rw-r--r--contrib/go/_std_1.20/src/net/cgo_unix_syscall.go109
-rw-r--r--contrib/go/_std_1.20/src/net/cgo_windows.go13
-rw-r--r--contrib/go/_std_1.20/src/net/conf.go357
-rw-r--r--contrib/go/_std_1.20/src/net/dial.go740
-rw-r--r--contrib/go/_std_1.20/src/net/dnsclient_unix.go866
-rw-r--r--contrib/go/_std_1.20/src/net/dnsconfig_unix.go168
-rw-r--r--contrib/go/_std_1.20/src/net/dnsconfig_windows.go58
-rw-r--r--contrib/go/_std_1.20/src/net/error_posix.go21
-rw-r--r--contrib/go/_std_1.20/src/net/error_unix.go16
-rw-r--r--contrib/go/_std_1.20/src/net/fd_unix.go206
-rw-r--r--contrib/go/_std_1.20/src/net/fd_windows.go178
-rw-r--r--contrib/go/_std_1.20/src/net/hook_unix.go20
-rw-r--r--contrib/go/_std_1.20/src/net/hosts.go165
-rw-r--r--contrib/go/_std_1.20/src/net/http/cgi/host.go413
-rw-r--r--contrib/go/_std_1.20/src/net/http/cgi/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/net/http/client.go1024
-rw-r--r--contrib/go/_std_1.20/src/net/http/cookiejar/jar.go540
-rw-r--r--contrib/go/_std_1.20/src/net/http/cookiejar/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/net/http/doc.go106
-rw-r--r--contrib/go/_std_1.20/src/net/http/fcgi/fcgi.go270
-rw-r--r--contrib/go/_std_1.20/src/net/http/fcgi/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/net/http/h2_bundle.go11240
-rw-r--r--contrib/go/_std_1.20/src/net/http/http.go159
-rw-r--r--contrib/go/_std_1.20/src/net/http/httptest/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/net/http/httptrace/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/net/http/httputil/reverseproxy.go839
-rw-r--r--contrib/go/_std_1.20/src/net/http/httputil/ya.make10
-rw-r--r--contrib/go/_std_1.20/src/net/http/internal/ascii/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/net/http/internal/ya.make12
-rw-r--r--contrib/go/_std_1.20/src/net/http/pprof/pprof.go456
-rw-r--r--contrib/go/_std_1.20/src/net/http/pprof/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/net/http/request.go1462
-rw-r--r--contrib/go/_std_1.20/src/net/http/responsecontroller.go122
-rw-r--r--contrib/go/_std_1.20/src/net/http/roundtrip.go18
-rw-r--r--contrib/go/_std_1.20/src/net/http/server.go3644
-rw-r--r--contrib/go/_std_1.20/src/net/http/socks_bundle.go473
-rw-r--r--contrib/go/_std_1.20/src/net/http/transfer.go1124
-rw-r--r--contrib/go/_std_1.20/src/net/http/transport.go2924
-rw-r--r--contrib/go/_std_1.20/src/net/http/transport_default_other.go17
-rw-r--r--contrib/go/_std_1.20/src/net/http/ya.make40
-rw-r--r--contrib/go/_std_1.20/src/net/internal/socktest/switch_unix.go29
-rw-r--r--contrib/go/_std_1.20/src/net/internal/socktest/sys_unix.go193
-rw-r--r--contrib/go/_std_1.20/src/net/internal/socktest/ya.make30
-rw-r--r--contrib/go/_std_1.20/src/net/ip.go765
-rw-r--r--contrib/go/_std_1.20/src/net/iprawsock_posix.go159
-rw-r--r--contrib/go/_std_1.20/src/net/ipsock_posix.go232
-rw-r--r--contrib/go/_std_1.20/src/net/lookup.go910
-rw-r--r--contrib/go/_std_1.20/src/net/lookup_unix.go158
-rw-r--r--contrib/go/_std_1.20/src/net/lookup_windows.go436
-rw-r--r--contrib/go/_std_1.20/src/net/mail/message.go911
-rw-r--r--contrib/go/_std_1.20/src/net/net.go771
-rw-r--r--contrib/go/_std_1.20/src/net/netip/netip.go1493
-rw-r--r--contrib/go/_std_1.20/src/net/netip/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/net/port_unix.go57
-rw-r--r--contrib/go/_std_1.20/src/net/rawconn.go81
-rw-r--r--contrib/go/_std_1.20/src/net/rpc/jsonrpc/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/net/rpc/server.go725
-rw-r--r--contrib/go/_std_1.20/src/net/rpc/ya.make13
-rw-r--r--contrib/go/_std_1.20/src/net/sendfile_linux.go53
-rw-r--r--contrib/go/_std_1.20/src/net/smtp/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/net/sock_cloexec.go25
-rw-r--r--contrib/go/_std_1.20/src/net/sockaddr_posix.go34
-rw-r--r--contrib/go/_std_1.20/src/net/splice_linux.go44
-rw-r--r--contrib/go/_std_1.20/src/net/tcpsock.go380
-rw-r--r--contrib/go/_std_1.20/src/net/tcpsock_posix.go179
-rw-r--r--contrib/go/_std_1.20/src/net/textproto/ya.make11
-rw-r--r--contrib/go/_std_1.20/src/net/udpsock_posix.go287
-rw-r--r--contrib/go/_std_1.20/src/net/unixsock.go352
-rw-r--r--contrib/go/_std_1.20/src/net/unixsock_posix.go245
-rw-r--r--contrib/go/_std_1.20/src/net/unixsock_readmsg_other.go11
-rw-r--r--contrib/go/_std_1.20/src/net/url/url.go1268
-rw-r--r--contrib/go/_std_1.20/src/net/url/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/net/ya.make149
-rw-r--r--contrib/go/_std_1.20/src/os/dir_darwin.go131
-rw-r--r--contrib/go/_std_1.20/src/os/dir_unix.go194
-rw-r--r--contrib/go/_std_1.20/src/os/dir_windows.go75
-rw-r--r--contrib/go/_std_1.20/src/os/error.go141
-rw-r--r--contrib/go/_std_1.20/src/os/error_posix.go18
-rw-r--r--contrib/go/_std_1.20/src/os/exec.go178
-rw-r--r--contrib/go/_std_1.20/src/os/exec/exec.go1303
-rw-r--r--contrib/go/_std_1.20/src/os/exec/internal/fdtest/exists_unix.go19
-rw-r--r--contrib/go/_std_1.20/src/os/exec/internal/fdtest/ya.make21
-rw-r--r--contrib/go/_std_1.20/src/os/exec/lp_unix.go79
-rw-r--r--contrib/go/_std_1.20/src/os/exec/lp_windows.go141
-rw-r--r--contrib/go/_std_1.20/src/os/exec/ya.make32
-rw-r--r--contrib/go/_std_1.20/src/os/exec_posix.go136
-rw-r--r--contrib/go/_std_1.20/src/os/exec_unix.go106
-rw-r--r--contrib/go/_std_1.20/src/os/executable_procfs.go37
-rw-r--r--contrib/go/_std_1.20/src/os/file.go730
-rw-r--r--contrib/go/_std_1.20/src/os/file_posix.go250
-rw-r--r--contrib/go/_std_1.20/src/os/file_unix.go465
-rw-r--r--contrib/go/_std_1.20/src/os/file_windows.go509
-rw-r--r--contrib/go/_std_1.20/src/os/path_unix.go75
-rw-r--r--contrib/go/_std_1.20/src/os/pipe2_unix.go22
-rw-r--r--contrib/go/_std_1.20/src/os/pipe_unix.go28
-rw-r--r--contrib/go/_std_1.20/src/os/readfrom_linux.go46
-rw-r--r--contrib/go/_std_1.20/src/os/removeall_at.go192
-rw-r--r--contrib/go/_std_1.20/src/os/signal/doc.go232
-rw-r--r--contrib/go/_std_1.20/src/os/signal/signal_unix.go62
-rw-r--r--contrib/go/_std_1.20/src/os/signal/ya.make10
-rw-r--r--contrib/go/_std_1.20/src/os/stat_unix.go52
-rw-r--r--contrib/go/_std_1.20/src/os/stat_windows.go106
-rw-r--r--contrib/go/_std_1.20/src/os/sticky_bsd.go11
-rw-r--r--contrib/go/_std_1.20/src/os/sticky_notbsd.go9
-rw-r--r--contrib/go/_std_1.20/src/os/sys_bsd.go17
-rw-r--r--contrib/go/_std_1.20/src/os/tempfile.go128
-rw-r--r--contrib/go/_std_1.20/src/os/types_windows.go219
-rw-r--r--contrib/go/_std_1.20/src/os/wait_unimp.go22
-rw-r--r--contrib/go/_std_1.20/src/os/ya.make93
-rw-r--r--contrib/go/_std_1.20/src/path/filepath/path.go666
-rw-r--r--contrib/go/_std_1.20/src/path/filepath/path_unix.go57
-rw-r--r--contrib/go/_std_1.20/src/path/filepath/symlink.go147
-rw-r--r--contrib/go/_std_1.20/src/path/filepath/symlink_windows.go120
-rw-r--r--contrib/go/_std_1.20/src/path/filepath/ya.make30
-rw-r--r--contrib/go/_std_1.20/src/path/ya.make12
-rw-r--r--contrib/go/_std_1.20/src/reflect/abi.go510
-rw-r--r--contrib/go/_std_1.20/src/reflect/deepequal.go238
-rw-r--r--contrib/go/_std_1.20/src/reflect/makefunc.go176
-rw-r--r--contrib/go/_std_1.20/src/reflect/swapper.go78
-rw-r--r--contrib/go/_std_1.20/src/reflect/type.go3186
-rw-r--r--contrib/go/_std_1.20/src/reflect/value.go3860
-rw-r--r--contrib/go/_std_1.20/src/reflect/ya.make30
-rw-r--r--contrib/go/_std_1.20/src/regexp/regexp.go1285
-rw-r--r--contrib/go/_std_1.20/src/regexp/syntax/op_string.go26
-rw-r--r--contrib/go/_std_1.20/src/regexp/syntax/prog.go347
-rw-r--r--contrib/go/_std_1.20/src/regexp/syntax/ya.make14
-rw-r--r--contrib/go/_std_1.20/src/regexp/ya.make14
-rw-r--r--contrib/go/_std_1.20/src/runtime/alg.go353
-rw-r--r--contrib/go/_std_1.20/src/runtime/arena.go1003
-rw-r--r--contrib/go/_std_1.20/src/runtime/asm.s10
-rw-r--r--contrib/go/_std_1.20/src/runtime/asm_amd64.s2066
-rw-r--r--contrib/go/_std_1.20/src/runtime/asm_arm64.s1525
-rw-r--r--contrib/go/_std_1.20/src/runtime/atomic_pointer.go98
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo.go54
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/asm_amd64.s34
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/asm_arm64.s37
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/callbacks.go107
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/cgo.go40
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/gcc_context.c21
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/gcc_fatalf.c23
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/gcc_libinit.c113
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/gcc_mmap.c39
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/gcc_setenv.c28
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/gcc_sigaction.c82
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/gcc_traceback.c44
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/handle.go144
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/libcgo.h151
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/linux_syscall.c85
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgo/ya.make123
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgocall.go641
-rw-r--r--contrib/go/_std_1.20/src/runtime/cgocheck.go268
-rw-r--r--contrib/go/_std_1.20/src/runtime/chan.go851
-rw-r--r--contrib/go/_std_1.20/src/runtime/checkptr.go109
-rw-r--r--contrib/go/_std_1.20/src/runtime/coverage/apis.go178
-rw-r--r--contrib/go/_std_1.20/src/runtime/coverage/emit.go667
-rw-r--r--contrib/go/_std_1.20/src/runtime/coverage/testsupport.go234
-rw-r--r--contrib/go/_std_1.20/src/runtime/coverage/ya.make11
-rw-r--r--contrib/go/_std_1.20/src/runtime/cpuflags_arm64.go17
-rw-r--r--contrib/go/_std_1.20/src/runtime/cpuprof.go237
-rw-r--r--contrib/go/_std_1.20/src/runtime/cputicks.go11
-rw-r--r--contrib/go/_std_1.20/src/runtime/debug.go115
-rw-r--r--contrib/go/_std_1.20/src/runtime/debug/mod.go287
-rw-r--r--contrib/go/_std_1.20/src/runtime/debug/ya.make11
-rw-r--r--contrib/go/_std_1.20/src/runtime/debugcall.go252
-rw-r--r--contrib/go/_std_1.20/src/runtime/debuglog.go831
-rw-r--r--contrib/go/_std_1.20/src/runtime/defs_darwin_amd64.go375
-rw-r--r--contrib/go/_std_1.20/src/runtime/defs_linux_amd64.go288
-rw-r--r--contrib/go/_std_1.20/src/runtime/defs_linux_arm64.go210
-rw-r--r--contrib/go/_std_1.20/src/runtime/defs_windows.go84
-rw-r--r--contrib/go/_std_1.20/src/runtime/defs_windows_amd64.go94
-rw-r--r--contrib/go/_std_1.20/src/runtime/duff_amd64.s427
-rw-r--r--contrib/go/_std_1.20/src/runtime/error.go330
-rw-r--r--contrib/go/_std_1.20/src/runtime/exithook.go69
-rw-r--r--contrib/go/_std_1.20/src/runtime/extern.go322
-rw-r--r--contrib/go/_std_1.20/src/runtime/funcdata.h56
-rw-r--r--contrib/go/_std_1.20/src/runtime/heapdump.go748
-rw-r--r--contrib/go/_std_1.20/src/runtime/iface.go533
-rw-r--r--contrib/go/_std_1.20/src/runtime/internal/atomic/ya.make25
-rw-r--r--contrib/go/_std_1.20/src/runtime/internal/math/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/runtime/internal/sys/intrinsics.go110
-rw-r--r--contrib/go/_std_1.20/src/runtime/internal/sys/intrinsics_common.go109
-rw-r--r--contrib/go/_std_1.20/src/runtime/internal/sys/ya.make13
-rw-r--r--contrib/go/_std_1.20/src/runtime/internal/syscall/defs_linux.go10
-rw-r--r--contrib/go/_std_1.20/src/runtime/internal/syscall/syscall_linux.go66
-rw-r--r--contrib/go/_std_1.20/src/runtime/internal/syscall/ya.make26
-rw-r--r--contrib/go/_std_1.20/src/runtime/internal/ya.make17
-rw-r--r--contrib/go/_std_1.20/src/runtime/lfstack.go69
-rw-r--r--contrib/go/_std_1.20/src/runtime/lfstack_64bit.go70
-rw-r--r--contrib/go/_std_1.20/src/runtime/lockrank.go184
-rw-r--r--contrib/go/_std_1.20/src/runtime/lockrank_off.go66
-rw-r--r--contrib/go/_std_1.20/src/runtime/malloc.go1562
-rw-r--r--contrib/go/_std_1.20/src/runtime/map.go1418
-rw-r--r--contrib/go/_std_1.20/src/runtime/map_fast32.go462
-rw-r--r--contrib/go/_std_1.20/src/runtime/map_fast64.go470
-rw-r--r--contrib/go/_std_1.20/src/runtime/map_faststr.go485
-rw-r--r--contrib/go/_std_1.20/src/runtime/mbarrier.go346
-rw-r--r--contrib/go/_std_1.20/src/runtime/mbitmap.go1501
-rw-r--r--contrib/go/_std_1.20/src/runtime/mcentral.go257
-rw-r--r--contrib/go/_std_1.20/src/runtime/mem.go143
-rw-r--r--contrib/go/_std_1.20/src/runtime/mem_darwin.go70
-rw-r--r--contrib/go/_std_1.20/src/runtime/mem_linux.go193
-rw-r--r--contrib/go/_std_1.20/src/runtime/mem_windows.go128
-rw-r--r--contrib/go/_std_1.20/src/runtime/metrics.go723
-rw-r--r--contrib/go/_std_1.20/src/runtime/metrics/description.go380
-rw-r--r--contrib/go/_std_1.20/src/runtime/metrics/doc.go283
-rw-r--r--contrib/go/_std_1.20/src/runtime/metrics/ya.make11
-rw-r--r--contrib/go/_std_1.20/src/runtime/mfinal.go518
-rw-r--r--contrib/go/_std_1.20/src/runtime/mfixalloc.go111
-rw-r--r--contrib/go/_std_1.20/src/runtime/mgc.go1801
-rw-r--r--contrib/go/_std_1.20/src/runtime/mgclimit.go483
-rw-r--r--contrib/go/_std_1.20/src/runtime/mgcmark.go1598
-rw-r--r--contrib/go/_std_1.20/src/runtime/mgcpacer.go1427
-rw-r--r--contrib/go/_std_1.20/src/runtime/mgcscavenge.go1186
-rw-r--r--contrib/go/_std_1.20/src/runtime/mgcsweep.go967
-rw-r--r--contrib/go/_std_1.20/src/runtime/mheap.go2228
-rw-r--r--contrib/go/_std_1.20/src/runtime/mpagealloc.go1002
-rw-r--r--contrib/go/_std_1.20/src/runtime/mpagealloc_64bit.go257
-rw-r--r--contrib/go/_std_1.20/src/runtime/mpagecache.go176
-rw-r--r--contrib/go/_std_1.20/src/runtime/mpallocbits.go446
-rw-r--r--contrib/go/_std_1.20/src/runtime/mprof.go1281
-rw-r--r--contrib/go/_std_1.20/src/runtime/mspanset.go404
-rw-r--r--contrib/go/_std_1.20/src/runtime/mstats.go903
-rw-r--r--contrib/go/_std_1.20/src/runtime/mwbbuf.go290
-rw-r--r--contrib/go/_std_1.20/src/runtime/netpoll.go657
-rw-r--r--contrib/go/_std_1.20/src/runtime/netpoll_epoll.go167
-rw-r--r--contrib/go/_std_1.20/src/runtime/netpoll_kqueue.go190
-rw-r--r--contrib/go/_std_1.20/src/runtime/netpoll_windows.go159
-rw-r--r--contrib/go/_std_1.20/src/runtime/os_darwin.go475
-rw-r--r--contrib/go/_std_1.20/src/runtime/os_linux.go920
-rw-r--r--contrib/go/_std_1.20/src/runtime/os_windows.go1470
-rw-r--r--contrib/go/_std_1.20/src/runtime/panic.go1376
-rw-r--r--contrib/go/_std_1.20/src/runtime/plugin.go137
-rw-r--r--contrib/go/_std_1.20/src/runtime/pprof/proto.go761
-rw-r--r--contrib/go/_std_1.20/src/runtime/pprof/runtime.go45
-rw-r--r--contrib/go/_std_1.20/src/runtime/pprof/ya.make36
-rw-r--r--contrib/go/_std_1.20/src/runtime/preempt.go452
-rw-r--r--contrib/go/_std_1.20/src/runtime/print.go301
-rw-r--r--contrib/go/_std_1.20/src/runtime/proc.go6547
-rw-r--r--contrib/go/_std_1.20/src/runtime/profbuf.go560
-rw-r--r--contrib/go/_std_1.20/src/runtime/race/ya.make52
-rw-r--r--contrib/go/_std_1.20/src/runtime/relax_stub.go17
-rw-r--r--contrib/go/_std_1.20/src/runtime/rt0_windows_amd64.s31
-rw-r--r--contrib/go/_std_1.20/src/runtime/runtime.go116
-rw-r--r--contrib/go/_std_1.20/src/runtime/runtime1.go563
-rw-r--r--contrib/go/_std_1.20/src/runtime/runtime2.go1190
-rw-r--r--contrib/go/_std_1.20/src/runtime/select.go632
-rw-r--r--contrib/go/_std_1.20/src/runtime/sema.go633
-rw-r--r--contrib/go/_std_1.20/src/runtime/signal_arm64.go96
-rw-r--r--contrib/go/_std_1.20/src/runtime/signal_unix.go1358
-rw-r--r--contrib/go/_std_1.20/src/runtime/signal_windows.go335
-rw-r--r--contrib/go/_std_1.20/src/runtime/sizeclasses.go97
-rw-r--r--contrib/go/_std_1.20/src/runtime/slice.go347
-rw-r--r--contrib/go/_std_1.20/src/runtime/stack.go1345
-rw-r--r--contrib/go/_std_1.20/src/runtime/stkframe.go289
-rw-r--r--contrib/go/_std_1.20/src/runtime/string.go584
-rw-r--r--contrib/go/_std_1.20/src/runtime/stubs.go480
-rw-r--r--contrib/go/_std_1.20/src/runtime/stubs2.go44
-rw-r--r--contrib/go/_std_1.20/src/runtime/stubs3.go9
-rw-r--r--contrib/go/_std_1.20/src/runtime/stubs_amd64.go49
-rw-r--r--contrib/go/_std_1.20/src/runtime/stubs_arm64.go23
-rw-r--r--contrib/go/_std_1.20/src/runtime/symtab.go1214
-rw-r--r--contrib/go/_std_1.20/src/runtime/sys_darwin.go608
-rw-r--r--contrib/go/_std_1.20/src/runtime/sys_darwin_amd64.s952
-rw-r--r--contrib/go/_std_1.20/src/runtime/sys_linux_amd64.s703
-rw-r--r--contrib/go/_std_1.20/src/runtime/sys_linux_arm64.s801
-rw-r--r--contrib/go/_std_1.20/src/runtime/sys_windows_amd64.s445
-rw-r--r--contrib/go/_std_1.20/src/runtime/syscall_windows.go559
-rw-r--r--contrib/go/_std_1.20/src/runtime/textflag.h39
-rw-r--r--contrib/go/_std_1.20/src/runtime/time.go1144
-rw-r--r--contrib/go/_std_1.20/src/runtime/timestub2.go9
-rw-r--r--contrib/go/_std_1.20/src/runtime/trace.go1579
-rw-r--r--contrib/go/_std_1.20/src/runtime/trace/annotation.go198
-rw-r--r--contrib/go/_std_1.20/src/runtime/trace/trace.go154
-rw-r--r--contrib/go/_std_1.20/src/runtime/trace/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/runtime/traceback.go1377
-rw-r--r--contrib/go/_std_1.20/src/runtime/type.go713
-rw-r--r--contrib/go/_std_1.20/src/runtime/typekind.go43
-rw-r--r--contrib/go/_std_1.20/src/runtime/unsafe.go98
-rw-r--r--contrib/go/_std_1.20/src/runtime/ya.make342
-rw-r--r--contrib/go/_std_1.20/src/runtime/zcallback_windows.s2013
-rw-r--r--contrib/go/_std_1.20/src/sort/sort.go262
-rw-r--r--contrib/go/_std_1.20/src/sort/ya.make11
-rw-r--r--contrib/go/_std_1.20/src/strconv/doc.go56
-rw-r--r--contrib/go/_std_1.20/src/strconv/isprint.go719
-rw-r--r--contrib/go/_std_1.20/src/strconv/ya.make20
-rw-r--r--contrib/go/_std_1.20/src/strings/builder.go117
-rw-r--r--contrib/go/_std_1.20/src/strings/reader.go160
-rw-r--r--contrib/go/_std_1.20/src/strings/strings.go1289
-rw-r--r--contrib/go/_std_1.20/src/strings/ya.make13
-rw-r--r--contrib/go/_std_1.20/src/sync/atomic/doc.go192
-rw-r--r--contrib/go/_std_1.20/src/sync/atomic/type.go200
-rw-r--r--contrib/go/_std_1.20/src/sync/atomic/ya.make19
-rw-r--r--contrib/go/_std_1.20/src/sync/rwmutex.go231
-rw-r--r--contrib/go/_std_1.20/src/sync/ya.make20
-rw-r--r--contrib/go/_std_1.20/src/syscall/dirent.go102
-rw-r--r--contrib/go/_std_1.20/src/syscall/dll_windows.go311
-rw-r--r--contrib/go/_std_1.20/src/syscall/env_unix.go150
-rw-r--r--contrib/go/_std_1.20/src/syscall/env_windows.go97
-rw-r--r--contrib/go/_std_1.20/src/syscall/exec_libc2.go288
-rw-r--r--contrib/go/_std_1.20/src/syscall/exec_linux.go706
-rw-r--r--contrib/go/_std_1.20/src/syscall/exec_unix.go311
-rw-r--r--contrib/go/_std_1.20/src/syscall/exec_windows.go432
-rw-r--r--contrib/go/_std_1.20/src/syscall/forkpipe.go21
-rw-r--r--contrib/go/_std_1.20/src/syscall/netlink_linux.go178
-rw-r--r--contrib/go/_std_1.20/src/syscall/ptrace_darwin.go14
-rw-r--r--contrib/go/_std_1.20/src/syscall/security_windows.go379
-rw-r--r--contrib/go/_std_1.20/src/syscall/syscall_bsd.go532
-rw-r--r--contrib/go/_std_1.20/src/syscall/syscall_darwin_amd64.go67
-rw-r--r--contrib/go/_std_1.20/src/syscall/syscall_linux.go1274
-rw-r--r--contrib/go/_std_1.20/src/syscall/syscall_unix.go519
-rw-r--r--contrib/go/_std_1.20/src/syscall/syscall_windows.go1347
-rw-r--r--contrib/go/_std_1.20/src/syscall/timestruct.go36
-rw-r--r--contrib/go/_std_1.20/src/syscall/ya.make128
-rw-r--r--contrib/go/_std_1.20/src/syscall/zsyscall_darwin_amd64.go2024
-rw-r--r--contrib/go/_std_1.20/src/syscall/zsyscall_linux_amd64.go1648
-rw-r--r--contrib/go/_std_1.20/src/syscall/zsyscall_linux_arm64.go1563
-rw-r--r--contrib/go/_std_1.20/src/syscall/zsyscall_windows.go1478
-rw-r--r--contrib/go/_std_1.20/src/testing/cover.go121
-rw-r--r--contrib/go/_std_1.20/src/testing/example.go102
-rw-r--r--contrib/go/_std_1.20/src/testing/fstest/mapfs.go240
-rw-r--r--contrib/go/_std_1.20/src/testing/fstest/testfs.go624
-rw-r--r--contrib/go/_std_1.20/src/testing/fstest/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/testing/iotest/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/testing/newcover.go48
-rw-r--r--contrib/go/_std_1.20/src/testing/quick/quick.go385
-rw-r--r--contrib/go/_std_1.20/src/testing/quick/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/testing/run_example.go66
-rw-r--r--contrib/go/_std_1.20/src/testing/testing.go2284
-rw-r--r--contrib/go/_std_1.20/src/testing/ya.make40
-rw-r--r--contrib/go/_std_1.20/src/text/scanner/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/text/tabwriter/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/text/template/doc.go464
-rw-r--r--contrib/go/_std_1.20/src/text/template/funcs.go776
-rw-r--r--contrib/go/_std_1.20/src/text/template/parse/ya.make9
-rw-r--r--contrib/go/_std_1.20/src/text/template/ya.make16
-rw-r--r--contrib/go/_std_1.20/src/time/format.go1686
-rw-r--r--contrib/go/_std_1.20/src/time/sys_unix.go54
-rw-r--r--contrib/go/_std_1.20/src/time/tick.go73
-rw-r--r--contrib/go/_std_1.20/src/time/tzdata/tzdata.go111
-rw-r--r--contrib/go/_std_1.20/src/time/tzdata/ya.make8
-rw-r--r--contrib/go/_std_1.20/src/time/tzdata/zipdata.go6690
-rw-r--r--contrib/go/_std_1.20/src/time/ya.make40
-rw-r--r--contrib/go/_std_1.20/src/time/zoneinfo_abbrs_windows.go155
-rw-r--r--contrib/go/_std_1.20/src/time/zoneinfo_read.go597
-rw-r--r--contrib/go/_std_1.20/src/time/zoneinfo_unix.go67
-rw-r--r--contrib/go/_std_1.20/src/unicode/tables.go8054
-rw-r--r--contrib/go/_std_1.20/src/unicode/utf16/utf16.go125
-rw-r--r--contrib/go/_std_1.20/src/unicode/utf16/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/unicode/utf8/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/unicode/ya.make16
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/ya.make21
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/ya.make22
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go816
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/builder.go342
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/alias/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/ya.make22
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/net/dns/dnsmessage/message.go2677
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/net/dns/dnsmessage/ya.make7
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/hpack.go523
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/tables13.0.0.go4840
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/trie.go72
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/ya.make12
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/ya.make23
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go71
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/hwcap_linux.go56
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/ya.make54
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go1956
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/forminfo.go279
-rw-r--r--contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go7761
-rw-r--r--contrib/go/_std_1.21/src/archive/tar/common.go736
-rw-r--r--contrib/go/_std_1.21/src/archive/tar/format.go (renamed from contrib/go/_std_1.20/src/archive/tar/format.go)0
-rw-r--r--contrib/go/_std_1.21/src/archive/tar/reader.go882
-rw-r--r--contrib/go/_std_1.21/src/archive/tar/stat_actime1.go (renamed from contrib/go/_std_1.20/src/archive/tar/stat_actime1.go)0
-rw-r--r--contrib/go/_std_1.21/src/archive/tar/stat_actime2.go (renamed from contrib/go/_std_1.20/src/archive/tar/stat_actime2.go)0
-rw-r--r--contrib/go/_std_1.21/src/archive/tar/stat_unix.go (renamed from contrib/go/_std_1.20/src/archive/tar/stat_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/archive/tar/strconv.go (renamed from contrib/go/_std_1.20/src/archive/tar/strconv.go)0
-rw-r--r--contrib/go/_std_1.21/src/archive/tar/writer.go (renamed from contrib/go/_std_1.20/src/archive/tar/writer.go)0
-rw-r--r--contrib/go/_std_1.21/src/archive/tar/ya.make38
-rw-r--r--contrib/go/_std_1.21/src/archive/zip/reader.go979
-rw-r--r--contrib/go/_std_1.21/src/archive/zip/register.go (renamed from contrib/go/_std_1.20/src/archive/zip/register.go)0
-rw-r--r--contrib/go/_std_1.21/src/archive/zip/struct.go419
-rw-r--r--contrib/go/_std_1.21/src/archive/zip/writer.go (renamed from contrib/go/_std_1.20/src/archive/zip/writer.go)0
-rw-r--r--contrib/go/_std_1.21/src/archive/zip/ya.make22
-rw-r--r--contrib/go/_std_1.21/src/bufio/bufio.go842
-rw-r--r--contrib/go/_std_1.21/src/bufio/scan.go (renamed from contrib/go/_std_1.20/src/bufio/scan.go)0
-rw-r--r--contrib/go/_std_1.21/src/bufio/ya.make19
-rw-r--r--contrib/go/_std_1.21/src/bytes/buffer.go482
-rw-r--r--contrib/go/_std_1.21/src/bytes/bytes.go1396
-rw-r--r--contrib/go/_std_1.21/src/bytes/reader.go (renamed from contrib/go/_std_1.20/src/bytes/reader.go)0
-rw-r--r--contrib/go/_std_1.21/src/bytes/ya.make26
-rw-r--r--contrib/go/_std_1.21/src/cmp/cmp.go59
-rw-r--r--contrib/go/_std_1.21/src/cmp/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/compress/flate/deflate.go (renamed from contrib/go/_std_1.20/src/compress/flate/deflate.go)0
-rw-r--r--contrib/go/_std_1.21/src/compress/flate/deflatefast.go (renamed from contrib/go/_std_1.20/src/compress/flate/deflatefast.go)0
-rw-r--r--contrib/go/_std_1.21/src/compress/flate/dict_decoder.go (renamed from contrib/go/_std_1.20/src/compress/flate/dict_decoder.go)0
-rw-r--r--contrib/go/_std_1.21/src/compress/flate/huffman_bit_writer.go (renamed from contrib/go/_std_1.20/src/compress/flate/huffman_bit_writer.go)0
-rw-r--r--contrib/go/_std_1.21/src/compress/flate/huffman_code.go (renamed from contrib/go/_std_1.20/src/compress/flate/huffman_code.go)0
-rw-r--r--contrib/go/_std_1.21/src/compress/flate/inflate.go836
-rw-r--r--contrib/go/_std_1.21/src/compress/flate/token.go (renamed from contrib/go/_std_1.20/src/compress/flate/token.go)0
-rw-r--r--contrib/go/_std_1.21/src/compress/flate/ya.make28
-rw-r--r--contrib/go/_std_1.21/src/compress/gzip/gunzip.go (renamed from contrib/go/_std_1.20/src/compress/gzip/gunzip.go)0
-rw-r--r--contrib/go/_std_1.21/src/compress/gzip/gzip.go (renamed from contrib/go/_std_1.20/src/compress/gzip/gzip.go)0
-rw-r--r--contrib/go/_std_1.21/src/compress/gzip/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/compress/zlib/reader.go181
-rw-r--r--contrib/go/_std_1.21/src/compress/zlib/writer.go193
-rw-r--r--contrib/go/_std_1.21/src/compress/zlib/ya.make18
-rw-r--r--contrib/go/_std_1.21/src/container/heap/heap.go (renamed from contrib/go/_std_1.20/src/container/heap/heap.go)0
-rw-r--r--contrib/go/_std_1.21/src/container/heap/ya.make17
-rw-r--r--contrib/go/_std_1.21/src/container/list/list.go (renamed from contrib/go/_std_1.20/src/container/list/list.go)0
-rw-r--r--contrib/go/_std_1.21/src/container/list/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/context/context.go785
-rw-r--r--contrib/go/_std_1.21/src/context/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/crypto/aes/aes_gcm.go (renamed from contrib/go/_std_1.20/src/crypto/aes/aes_gcm.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/aes/asm_amd64.s (renamed from contrib/go/_std_1.20/src/crypto/aes/asm_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/aes/asm_arm64.s281
-rw-r--r--contrib/go/_std_1.21/src/crypto/aes/block.go (renamed from contrib/go/_std_1.20/src/crypto/aes/block.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/aes/cipher.go (renamed from contrib/go/_std_1.20/src/crypto/aes/cipher.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/aes/cipher_asm.go (renamed from contrib/go/_std_1.20/src/crypto/aes/cipher_asm.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/aes/const.go (renamed from contrib/go/_std_1.20/src/crypto/aes/const.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/aes/gcm_amd64.s (renamed from contrib/go/_std_1.20/src/crypto/aes/gcm_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/aes/gcm_arm64.s1021
-rw-r--r--contrib/go/_std_1.21/src/crypto/aes/modes.go (renamed from contrib/go/_std_1.20/src/crypto/aes/modes.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/aes/ya.make34
-rw-r--r--contrib/go/_std_1.21/src/crypto/cipher/cbc.go (renamed from contrib/go/_std_1.20/src/crypto/cipher/cbc.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/cipher/cfb.go (renamed from contrib/go/_std_1.20/src/crypto/cipher/cfb.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/cipher/cipher.go (renamed from contrib/go/_std_1.20/src/crypto/cipher/cipher.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/cipher/ctr.go (renamed from contrib/go/_std_1.20/src/crypto/cipher/ctr.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/cipher/gcm.go (renamed from contrib/go/_std_1.20/src/crypto/cipher/gcm.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/cipher/io.go (renamed from contrib/go/_std_1.20/src/crypto/cipher/io.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/cipher/ofb.go (renamed from contrib/go/_std_1.20/src/crypto/cipher/ofb.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/cipher/ya.make31
-rw-r--r--contrib/go/_std_1.21/src/crypto/crypto.go (renamed from contrib/go/_std_1.20/src/crypto/crypto.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/des/block.go (renamed from contrib/go/_std_1.20/src/crypto/des/block.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/des/cipher.go (renamed from contrib/go/_std_1.20/src/crypto/des/cipher.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/des/const.go (renamed from contrib/go/_std_1.20/src/crypto/des/const.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/des/ya.make16
-rw-r--r--contrib/go/_std_1.21/src/crypto/dsa/dsa.go (renamed from contrib/go/_std_1.20/src/crypto/dsa/dsa.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/dsa/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/crypto/ecdh/ecdh.go188
-rw-r--r--contrib/go/_std_1.21/src/crypto/ecdh/nist.go (renamed from contrib/go/_std_1.20/src/crypto/ecdh/nist.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/ecdh/x25519.go (renamed from contrib/go/_std_1.20/src/crypto/ecdh/x25519.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/ecdh/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/crypto/ecdsa/ecdsa.go672
-rw-r--r--contrib/go/_std_1.21/src/crypto/ecdsa/ecdsa_legacy.go (renamed from contrib/go/_std_1.20/src/crypto/ecdsa/ecdsa_legacy.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/ecdsa/ecdsa_noasm.go (renamed from contrib/go/_std_1.20/src/crypto/ecdsa/ecdsa_noasm.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/ecdsa/notboring.go (renamed from contrib/go/_std_1.20/src/crypto/ecdsa/notboring.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/ecdsa/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/crypto/ed25519/ed25519.go344
-rw-r--r--contrib/go/_std_1.21/src/crypto/ed25519/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/crypto/elliptic/elliptic.go280
-rw-r--r--contrib/go/_std_1.21/src/crypto/elliptic/nistec.go (renamed from contrib/go/_std_1.20/src/crypto/elliptic/nistec.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/elliptic/nistec_p256.go (renamed from contrib/go/_std_1.20/src/crypto/elliptic/nistec_p256.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/elliptic/params.go334
-rw-r--r--contrib/go/_std_1.21/src/crypto/elliptic/ya.make19
-rw-r--r--contrib/go/_std_1.21/src/crypto/hmac/hmac.go180
-rw-r--r--contrib/go/_std_1.21/src/crypto/hmac/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/alias/alias.go30
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/alias/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/bigmod/nat.go770
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/bigmod/nat_amd64.s1230
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/bigmod/nat_arm64.s69
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/bigmod/nat_asm.go28
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/bigmod/ya.make25
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/bbig/big.go (renamed from contrib/go/_std_1.20/src/crypto/internal/boring/bbig/big.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/bbig/ya.make (renamed from contrib/go/_std_1.20/src/crypto/internal/boring/bbig/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/bcache/cache.go (renamed from contrib/go/_std_1.20/src/crypto/internal/boring/bcache/cache.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/bcache/stub.s (renamed from contrib/go/_std_1.20/src/crypto/internal/boring/bcache/stub.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/bcache/ya.make13
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/doc.go (renamed from contrib/go/_std_1.20/src/crypto/internal/boring/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go (renamed from contrib/go/_std_1.20/src/crypto/internal/boring/notboring.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/sig/sig.go (renamed from contrib/go/_std_1.20/src/crypto/internal/boring/sig/sig.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/sig/sig_amd64.s (renamed from contrib/go/_std_1.20/src/crypto/internal/boring/sig/sig_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/sig/sig_other.s (renamed from contrib/go/_std_1.20/src/crypto/internal/boring/sig/sig_other.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/sig/ya.make19
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/boring/ya.make16
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/doc.go (renamed from contrib/go/_std_1.20/src/crypto/internal/edwards25519/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/edwards25519.go426
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe.go (renamed from contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_amd64.go (renamed from contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_amd64.s (renamed from contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_amd64_noasm.go (renamed from contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_amd64_noasm.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_arm64.go (renamed from contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_arm64.s (renamed from contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_arm64_noasm.go (renamed from contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_arm64_noasm.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_generic.go266
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/ya.make37
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/scalar.go343
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/scalar_fiat.go (renamed from contrib/go/_std_1.20/src/crypto/internal/edwards25519/scalar_fiat.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/scalarmult.go (renamed from contrib/go/_std_1.20/src/crypto/internal/edwards25519/scalarmult.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/tables.go (renamed from contrib/go/_std_1.20/src/crypto/internal/edwards25519/tables.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/edwards25519/ya.make24
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p224.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p224.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p224_fiat64.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p224_fiat64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p224_invert.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p224_invert.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p256.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p256.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p256_fiat64.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p256_fiat64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p256_invert.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p256_invert.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p384.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p384.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p384_fiat64.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p384_fiat64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p384_invert.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p384_invert.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p521.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p521.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p521_fiat64.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p521_fiat64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p521_invert.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p521_invert.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/ya.make23
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/nistec.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/nistec.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/p224.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/p224.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/p224_sqrt.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/p224_sqrt.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/p256_asm.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/p256_asm.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/p256_asm_amd64.s (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/p256_asm_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/p256_asm_arm64.s (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/p256_asm_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/p256_asm_table.bin (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/p256_asm_table.bin)bin88064 -> 88064 bytes
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/p256_ordinv.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/p256_ordinv.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/p384.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/p384.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/p521.go (renamed from contrib/go/_std_1.20/src/crypto/internal/nistec/p521.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/nistec/ya.make38
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/randutil/randutil.go (renamed from contrib/go/_std_1.20/src/crypto/internal/randutil/randutil.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/randutil/ya.make (renamed from contrib/go/_std_1.20/src/crypto/internal/randutil/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/internal/ya.make (renamed from contrib/go/_std_1.20/src/crypto/internal/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/md5/md5.go (renamed from contrib/go/_std_1.20/src/crypto/md5/md5.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/md5/md5block.go (renamed from contrib/go/_std_1.20/src/crypto/md5/md5block.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/md5/md5block_amd64.s (renamed from contrib/go/_std_1.20/src/crypto/md5/md5block_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/md5/md5block_arm64.s (renamed from contrib/go/_std_1.20/src/crypto/md5/md5block_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/md5/md5block_decl.go12
-rw-r--r--contrib/go/_std_1.21/src/crypto/md5/ya.make28
-rw-r--r--contrib/go/_std_1.21/src/crypto/rand/rand.go45
-rw-r--r--contrib/go/_std_1.21/src/crypto/rand/rand_getentropy.go (renamed from contrib/go/_std_1.20/src/crypto/rand/rand_getentropy.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/rand/rand_getrandom.go48
-rw-r--r--contrib/go/_std_1.21/src/crypto/rand/rand_unix.go (renamed from contrib/go/_std_1.20/src/crypto/rand/rand_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/rand/rand_windows.go (renamed from contrib/go/_std_1.20/src/crypto/rand/rand_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/rand/util.go (renamed from contrib/go/_std_1.20/src/crypto/rand/util.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/rand/ya.make42
-rw-r--r--contrib/go/_std_1.21/src/crypto/rc4/rc4.go (renamed from contrib/go/_std_1.20/src/crypto/rc4/rc4.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/rc4/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/crypto/rsa/notboring.go (renamed from contrib/go/_std_1.20/src/crypto/rsa/notboring.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/rsa/pkcs1v15.go393
-rw-r--r--contrib/go/_std_1.21/src/crypto/rsa/pss.go382
-rw-r--r--contrib/go/_std_1.21/src/crypto/rsa/rsa.go781
-rw-r--r--contrib/go/_std_1.21/src/crypto/rsa/ya.make23
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha1/boring.go (renamed from contrib/go/_std_1.20/src/crypto/sha1/boring.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha1/sha1.go (renamed from contrib/go/_std_1.20/src/crypto/sha1/sha1.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha1/sha1block.go83
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha1/sha1block_amd64.go (renamed from contrib/go/_std_1.20/src/crypto/sha1/sha1block_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha1/sha1block_amd64.s1500
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha1/sha1block_arm64.go (renamed from contrib/go/_std_1.20/src/crypto/sha1/sha1block_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha1/sha1block_arm64.s (renamed from contrib/go/_std_1.20/src/crypto/sha1/sha1block_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha1/ya.make38
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha256/sha256.go (renamed from contrib/go/_std_1.20/src/crypto/sha256/sha256.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha256/sha256block.go (renamed from contrib/go/_std_1.20/src/crypto/sha256/sha256block.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha256/sha256block_amd64.go10
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha256/sha256block_amd64.s1173
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha256/sha256block_arm64.go (renamed from contrib/go/_std_1.20/src/crypto/sha256/sha256block_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha256/sha256block_arm64.s (renamed from contrib/go/_std_1.20/src/crypto/sha256/sha256block_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha256/sha256block_decl.go10
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha256/ya.make30
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha512/sha512.go (renamed from contrib/go/_std_1.20/src/crypto/sha512/sha512.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha512/sha512block.go (renamed from contrib/go/_std_1.20/src/crypto/sha512/sha512block.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha512/sha512block_amd64.go (renamed from contrib/go/_std_1.20/src/crypto/sha512/sha512block_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha512/sha512block_amd64.s (renamed from contrib/go/_std_1.20/src/crypto/sha512/sha512block_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha512/sha512block_arm64.go (renamed from contrib/go/_std_1.20/src/crypto/sha512/sha512block_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha512/sha512block_arm64.s (renamed from contrib/go/_std_1.20/src/crypto/sha512/sha512block_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/sha512/ya.make27
-rw-r--r--contrib/go/_std_1.21/src/crypto/subtle/constant_time.go (renamed from contrib/go/_std_1.20/src/crypto/subtle/constant_time.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/subtle/xor.go (renamed from contrib/go/_std_1.20/src/crypto/subtle/xor.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/subtle/xor_amd64.go (renamed from contrib/go/_std_1.20/src/crypto/subtle/xor_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/subtle/xor_amd64.s (renamed from contrib/go/_std_1.20/src/crypto/subtle/xor_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/subtle/xor_arm64.go (renamed from contrib/go/_std_1.20/src/crypto/subtle/xor_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/subtle/xor_arm64.s (renamed from contrib/go/_std_1.20/src/crypto/subtle/xor_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/subtle/ya.make29
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/alert.go109
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/auth.go (renamed from contrib/go/_std_1.20/src/crypto/tls/auth.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/cache.go95
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go694
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/common.go1547
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/common_string.go (renamed from contrib/go/_std_1.20/src/crypto/tls/common_string.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/conn.go1655
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/handshake_client.go1140
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go772
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/handshake_messages.go1903
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/handshake_server.go954
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go991
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/key_agreement.go (renamed from contrib/go/_std_1.20/src/crypto/tls/key_agreement.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/key_schedule.go159
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/notboring.go (renamed from contrib/go/_std_1.20/src/crypto/tls/notboring.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/prf.go292
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/quic.go421
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/ticket.go421
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/tls.go (renamed from contrib/go/_std_1.20/src/crypto/tls/tls.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/tls/ya.make54
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/cert_pool.go (renamed from contrib/go/_std_1.20/src/crypto/x509/cert_pool.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/internal/macos/corefoundation.go (renamed from contrib/go/_std_1.20/src/crypto/x509/internal/macos/corefoundation.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/internal/macos/corefoundation.s (renamed from contrib/go/_std_1.20/src/crypto/x509/internal/macos/corefoundation.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/internal/macos/security.go (renamed from contrib/go/_std_1.20/src/crypto/x509/internal/macos/security.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/internal/macos/security.s (renamed from contrib/go/_std_1.20/src/crypto/x509/internal/macos/security.s)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/internal/macos/ya.make17
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/internal/ya.make (renamed from contrib/go/_std_1.20/src/crypto/x509/internal/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/notboring.go (renamed from contrib/go/_std_1.20/src/crypto/x509/notboring.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/parser.go1193
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/pem_decrypt.go (renamed from contrib/go/_std_1.20/src/crypto/x509/pem_decrypt.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/pkcs1.go (renamed from contrib/go/_std_1.20/src/crypto/x509/pkcs1.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/pkcs8.go175
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/pkix/pkix.go (renamed from contrib/go/_std_1.20/src/crypto/x509/pkix/pkix.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/pkix/ya.make (renamed from contrib/go/_std_1.20/src/crypto/x509/pkix/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/root.go75
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/root_darwin.go (renamed from contrib/go/_std_1.20/src/crypto/x509/root_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/root_linux.go (renamed from contrib/go/_std_1.20/src/crypto/x509/root_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/root_unix.go108
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/root_windows.go277
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/sec1.go136
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/verify.go1176
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/x509.go2470
-rw-r--r--contrib/go/_std_1.21/src/crypto/x509/ya.make64
-rw-r--r--contrib/go/_std_1.21/src/crypto/ya.make32
-rw-r--r--contrib/go/_std_1.21/src/database/sql/convert.go591
-rw-r--r--contrib/go/_std_1.21/src/database/sql/ctxutil.go (renamed from contrib/go/_std_1.20/src/database/sql/ctxutil.go)0
-rw-r--r--contrib/go/_std_1.21/src/database/sql/driver/driver.go (renamed from contrib/go/_std_1.20/src/database/sql/driver/driver.go)0
-rw-r--r--contrib/go/_std_1.21/src/database/sql/driver/types.go (renamed from contrib/go/_std_1.20/src/database/sql/driver/types.go)0
-rw-r--r--contrib/go/_std_1.21/src/database/sql/driver/ya.make13
-rw-r--r--contrib/go/_std_1.21/src/database/sql/sql.go3503
-rw-r--r--contrib/go/_std_1.21/src/database/sql/ya.make25
-rw-r--r--contrib/go/_std_1.21/src/debug/dwarf/attr_string.go (renamed from contrib/go/_std_1.20/src/debug/dwarf/attr_string.go)0
-rw-r--r--contrib/go/_std_1.21/src/debug/dwarf/buf.go (renamed from contrib/go/_std_1.20/src/debug/dwarf/buf.go)0
-rw-r--r--contrib/go/_std_1.21/src/debug/dwarf/class_string.go42
-rw-r--r--contrib/go/_std_1.21/src/debug/dwarf/const.go (renamed from contrib/go/_std_1.20/src/debug/dwarf/const.go)0
-rw-r--r--contrib/go/_std_1.21/src/debug/dwarf/entry.go1221
-rw-r--r--contrib/go/_std_1.21/src/debug/dwarf/line.go (renamed from contrib/go/_std_1.20/src/debug/dwarf/line.go)0
-rw-r--r--contrib/go/_std_1.21/src/debug/dwarf/open.go (renamed from contrib/go/_std_1.20/src/debug/dwarf/open.go)0
-rw-r--r--contrib/go/_std_1.21/src/debug/dwarf/tag_string.go (renamed from contrib/go/_std_1.20/src/debug/dwarf/tag_string.go)0
-rw-r--r--contrib/go/_std_1.21/src/debug/dwarf/type.go (renamed from contrib/go/_std_1.20/src/debug/dwarf/type.go)0
-rw-r--r--contrib/go/_std_1.21/src/debug/dwarf/typeunit.go (renamed from contrib/go/_std_1.20/src/debug/dwarf/typeunit.go)0
-rw-r--r--contrib/go/_std_1.21/src/debug/dwarf/unit.go (renamed from contrib/go/_std_1.20/src/debug/dwarf/unit.go)0
-rw-r--r--contrib/go/_std_1.21/src/debug/dwarf/ya.make31
-rw-r--r--contrib/go/_std_1.21/src/debug/elf/elf.go3600
-rw-r--r--contrib/go/_std_1.21/src/debug/elf/file.go1676
-rw-r--r--contrib/go/_std_1.21/src/debug/elf/reader.go (renamed from contrib/go/_std_1.20/src/debug/elf/reader.go)0
-rw-r--r--contrib/go/_std_1.21/src/debug/elf/ya.make18
-rw-r--r--contrib/go/_std_1.21/src/embed/embed.go448
-rw-r--r--contrib/go/_std_1.21/src/embed/ya.make15
-rw-r--r--contrib/go/_std_1.21/src/encoding/ascii85/ascii85.go (renamed from contrib/go/_std_1.20/src/encoding/ascii85/ascii85.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/ascii85/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/encoding/asn1/asn1.go1125
-rw-r--r--contrib/go/_std_1.21/src/encoding/asn1/common.go (renamed from contrib/go/_std_1.20/src/encoding/asn1/common.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/asn1/marshal.go (renamed from contrib/go/_std_1.20/src/encoding/asn1/marshal.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/asn1/ya.make17
-rw-r--r--contrib/go/_std_1.21/src/encoding/base32/base32.go552
-rw-r--r--contrib/go/_std_1.21/src/encoding/base32/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/encoding/base64/base64.go630
-rw-r--r--contrib/go/_std_1.21/src/encoding/base64/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/encoding/binary/binary.go811
-rw-r--r--contrib/go/_std_1.21/src/encoding/binary/native_endian_little.go14
-rw-r--r--contrib/go/_std_1.21/src/encoding/binary/varint.go166
-rw-r--r--contrib/go/_std_1.21/src/encoding/binary/ya.make19
-rw-r--r--contrib/go/_std_1.21/src/encoding/csv/reader.go466
-rw-r--r--contrib/go/_std_1.21/src/encoding/csv/writer.go (renamed from contrib/go/_std_1.20/src/encoding/csv/writer.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/csv/ya.make18
-rw-r--r--contrib/go/_std_1.21/src/encoding/encoding.go54
-rw-r--r--contrib/go/_std_1.21/src/encoding/gob/dec_helpers.go548
-rw-r--r--contrib/go/_std_1.21/src/encoding/gob/decode.go1306
-rw-r--r--contrib/go/_std_1.21/src/encoding/gob/decoder.go (renamed from contrib/go/_std_1.20/src/encoding/gob/decoder.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/gob/doc.go423
-rw-r--r--contrib/go/_std_1.21/src/encoding/gob/enc_helpers.go (renamed from contrib/go/_std_1.20/src/encoding/gob/enc_helpers.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/gob/encode.go670
-rw-r--r--contrib/go/_std_1.21/src/encoding/gob/encoder.go258
-rw-r--r--contrib/go/_std_1.21/src/encoding/gob/error.go (renamed from contrib/go/_std_1.20/src/encoding/gob/error.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/gob/type.go944
-rw-r--r--contrib/go/_std_1.21/src/encoding/gob/ya.make32
-rw-r--r--contrib/go/_std_1.21/src/encoding/hex/hex.go (renamed from contrib/go/_std_1.20/src/encoding/hex/hex.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/hex/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/encoding/json/decode.go1291
-rw-r--r--contrib/go/_std_1.21/src/encoding/json/encode.go1283
-rw-r--r--contrib/go/_std_1.21/src/encoding/json/fold.go48
-rw-r--r--contrib/go/_std_1.21/src/encoding/json/indent.go174
-rw-r--r--contrib/go/_std_1.21/src/encoding/json/scanner.go (renamed from contrib/go/_std_1.20/src/encoding/json/scanner.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/json/stream.go511
-rw-r--r--contrib/go/_std_1.21/src/encoding/json/tables.go (renamed from contrib/go/_std_1.20/src/encoding/json/tables.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/json/tags.go (renamed from contrib/go/_std_1.20/src/encoding/json/tags.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/json/ya.make36
-rw-r--r--contrib/go/_std_1.21/src/encoding/pem/pem.go (renamed from contrib/go/_std_1.20/src/encoding/pem/pem.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/pem/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/encoding/xml/marshal.go1135
-rw-r--r--contrib/go/_std_1.21/src/encoding/xml/read.go777
-rw-r--r--contrib/go/_std_1.21/src/encoding/xml/typeinfo.go (renamed from contrib/go/_std_1.20/src/encoding/xml/typeinfo.go)0
-rw-r--r--contrib/go/_std_1.21/src/encoding/xml/xml.go2060
-rw-r--r--contrib/go/_std_1.21/src/encoding/xml/ya.make26
-rw-r--r--contrib/go/_std_1.21/src/encoding/ya.make (renamed from contrib/go/_std_1.20/src/encoding/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/errors/errors.go87
-rw-r--r--contrib/go/_std_1.21/src/errors/join.go53
-rw-r--r--contrib/go/_std_1.21/src/errors/wrap.go136
-rw-r--r--contrib/go/_std_1.21/src/errors/ya.make19
-rw-r--r--contrib/go/_std_1.21/src/expvar/expvar.go (renamed from contrib/go/_std_1.20/src/expvar/expvar.go)0
-rw-r--r--contrib/go/_std_1.21/src/expvar/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/flag/flag.go1231
-rw-r--r--contrib/go/_std_1.21/src/flag/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/fmt/doc.go (renamed from contrib/go/_std_1.20/src/fmt/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/fmt/errors.go (renamed from contrib/go/_std_1.20/src/fmt/errors.go)0
-rw-r--r--contrib/go/_std_1.21/src/fmt/format.go (renamed from contrib/go/_std_1.20/src/fmt/format.go)0
-rw-r--r--contrib/go/_std_1.21/src/fmt/print.go1226
-rw-r--r--contrib/go/_std_1.21/src/fmt/scan.go1238
-rw-r--r--contrib/go/_std_1.21/src/fmt/ya.make27
-rw-r--r--contrib/go/_std_1.21/src/go/ast/ast.go1112
-rw-r--r--contrib/go/_std_1.21/src/go/ast/commentmap.go (renamed from contrib/go/_std_1.20/src/go/ast/commentmap.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/ast/filter.go495
-rw-r--r--contrib/go/_std_1.21/src/go/ast/import.go (renamed from contrib/go/_std_1.20/src/go/ast/import.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/ast/print.go (renamed from contrib/go/_std_1.20/src/go/ast/print.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/ast/resolve.go (renamed from contrib/go/_std_1.20/src/go/ast/resolve.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/ast/scope.go (renamed from contrib/go/_std_1.20/src/go/ast/scope.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/ast/walk.go (renamed from contrib/go/_std_1.20/src/go/ast/walk.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/ast/ya.make29
-rw-r--r--contrib/go/_std_1.21/src/go/build/build.go2036
-rw-r--r--contrib/go/_std_1.21/src/go/build/constraint/expr.go (renamed from contrib/go/_std_1.20/src/go/build/constraint/expr.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/build/constraint/vers.go105
-rw-r--r--contrib/go/_std_1.21/src/go/build/constraint/ya.make16
-rw-r--r--contrib/go/_std_1.21/src/go/build/doc.go (renamed from contrib/go/_std_1.20/src/go/build/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/build/gc.go (renamed from contrib/go/_std_1.20/src/go/build/gc.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/build/read.go612
-rw-r--r--contrib/go/_std_1.21/src/go/build/syslist.go81
-rw-r--r--contrib/go/_std_1.21/src/go/build/ya.make23
-rw-r--r--contrib/go/_std_1.21/src/go/build/zcgo.go5
-rw-r--r--contrib/go/_std_1.21/src/go/constant/kind_string.go (renamed from contrib/go/_std_1.20/src/go/constant/kind_string.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/constant/value.go (renamed from contrib/go/_std_1.20/src/go/constant/value.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/constant/ya.make15
-rw-r--r--contrib/go/_std_1.21/src/go/doc/comment.go (renamed from contrib/go/_std_1.20/src/go/doc/comment.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/doc/comment/doc.go (renamed from contrib/go/_std_1.20/src/go/doc/comment/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/doc/comment/html.go (renamed from contrib/go/_std_1.20/src/go/doc/comment/html.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/doc/comment/markdown.go (renamed from contrib/go/_std_1.20/src/go/doc/comment/markdown.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/doc/comment/parse.go (renamed from contrib/go/_std_1.20/src/go/doc/comment/parse.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/doc/comment/print.go288
-rw-r--r--contrib/go/_std_1.21/src/go/doc/comment/std.go47
-rw-r--r--contrib/go/_std_1.21/src/go/doc/comment/text.go (renamed from contrib/go/_std_1.20/src/go/doc/comment/text.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/doc/comment/ya.make24
-rw-r--r--contrib/go/_std_1.21/src/go/doc/doc.go (renamed from contrib/go/_std_1.20/src/go/doc/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/doc/example.go (renamed from contrib/go/_std_1.20/src/go/doc/example.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/doc/exports.go (renamed from contrib/go/_std_1.20/src/go/doc/exports.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/doc/filter.go (renamed from contrib/go/_std_1.20/src/go/doc/filter.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/doc/reader.go (renamed from contrib/go/_std_1.20/src/go/doc/reader.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/doc/synopsis.go (renamed from contrib/go/_std_1.20/src/go/doc/synopsis.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/doc/ya.make26
-rw-r--r--contrib/go/_std_1.21/src/go/format/format.go (renamed from contrib/go/_std_1.20/src/go/format/format.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/format/internal.go (renamed from contrib/go/_std_1.20/src/go/format/internal.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/format/ya.make18
-rw-r--r--contrib/go/_std_1.21/src/go/importer/importer.go (renamed from contrib/go/_std_1.20/src/go/importer/importer.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/importer/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/go/internal/gccgoimporter/ar.go (renamed from contrib/go/_std_1.20/src/go/internal/gccgoimporter/ar.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/internal/gccgoimporter/gccgoinstallation.go (renamed from contrib/go/_std_1.20/src/go/internal/gccgoimporter/gccgoinstallation.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/internal/gccgoimporter/importer.go (renamed from contrib/go/_std_1.20/src/go/internal/gccgoimporter/importer.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/internal/gccgoimporter/parser.go (renamed from contrib/go/_std_1.20/src/go/internal/gccgoimporter/parser.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/internal/gccgoimporter/ya.make19
-rw-r--r--contrib/go/_std_1.21/src/go/internal/gcimporter/exportdata.go (renamed from contrib/go/_std_1.20/src/go/internal/gcimporter/exportdata.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/internal/gcimporter/gcimporter.go248
-rw-r--r--contrib/go/_std_1.21/src/go/internal/gcimporter/iimport.go (renamed from contrib/go/_std_1.20/src/go/internal/gcimporter/iimport.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/internal/gcimporter/support.go (renamed from contrib/go/_std_1.20/src/go/internal/gcimporter/support.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/internal/gcimporter/ureader.go657
-rw-r--r--contrib/go/_std_1.21/src/go/internal/gcimporter/ya.make16
-rw-r--r--contrib/go/_std_1.21/src/go/internal/srcimporter/srcimporter.go (renamed from contrib/go/_std_1.20/src/go/internal/srcimporter/srcimporter.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/internal/srcimporter/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/go/internal/typeparams/typeparams.go (renamed from contrib/go/_std_1.20/src/go/internal/typeparams/typeparams.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/internal/typeparams/ya.make (renamed from contrib/go/_std_1.20/src/go/internal/typeparams/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/go/parser/interface.go (renamed from contrib/go/_std_1.20/src/go/parser/interface.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/parser/parser.go2882
-rw-r--r--contrib/go/_std_1.21/src/go/parser/resolver.go (renamed from contrib/go/_std_1.20/src/go/parser/resolver.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/parser/ya.make22
-rw-r--r--contrib/go/_std_1.21/src/go/printer/comment.go (renamed from contrib/go/_std_1.20/src/go/printer/comment.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/printer/gobuild.go (renamed from contrib/go/_std_1.20/src/go/printer/gobuild.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/printer/nodes.go (renamed from contrib/go/_std_1.20/src/go/printer/nodes.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/printer/printer.go1436
-rw-r--r--contrib/go/_std_1.21/src/go/printer/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/go/scanner/errors.go (renamed from contrib/go/_std_1.20/src/go/scanner/errors.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/scanner/scanner.go958
-rw-r--r--contrib/go/_std_1.21/src/go/scanner/ya.make15
-rw-r--r--contrib/go/_std_1.21/src/go/token/position.go565
-rw-r--r--contrib/go/_std_1.21/src/go/token/serialize.go (renamed from contrib/go/_std_1.20/src/go/token/serialize.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/token/token.go (renamed from contrib/go/_std_1.20/src/go/token/token.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/token/ya.make21
-rw-r--r--contrib/go/_std_1.21/src/go/types/api.go503
-rw-r--r--contrib/go/_std_1.21/src/go/types/array.go27
-rw-r--r--contrib/go/_std_1.21/src/go/types/assignments.go565
-rw-r--r--contrib/go/_std_1.21/src/go/types/basic.go84
-rw-r--r--contrib/go/_std_1.21/src/go/types/builtins.go1046
-rw-r--r--contrib/go/_std_1.21/src/go/types/call.go1037
-rw-r--r--contrib/go/_std_1.21/src/go/types/chan.go37
-rw-r--r--contrib/go/_std_1.21/src/go/types/check.go634
-rw-r--r--contrib/go/_std_1.21/src/go/types/const.go307
-rw-r--r--contrib/go/_std_1.21/src/go/types/context.go146
-rw-r--r--contrib/go/_std_1.21/src/go/types/conversions.go296
-rw-r--r--contrib/go/_std_1.21/src/go/types/decl.go932
-rw-r--r--contrib/go/_std_1.21/src/go/types/errors.go400
-rw-r--r--contrib/go/_std_1.21/src/go/types/eval.go99
-rw-r--r--contrib/go/_std_1.21/src/go/types/expr.go1601
-rw-r--r--contrib/go/_std_1.21/src/go/types/exprstring.go (renamed from contrib/go/_std_1.20/src/go/types/exprstring.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/types/gccgosizes.go43
-rw-r--r--contrib/go/_std_1.21/src/go/types/generate.go8
-rw-r--r--contrib/go/_std_1.21/src/go/types/index.go457
-rw-r--r--contrib/go/_std_1.21/src/go/types/infer.go768
-rw-r--r--contrib/go/_std_1.21/src/go/types/initorder.go (renamed from contrib/go/_std_1.20/src/go/types/initorder.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/types/instantiate.go359
-rw-r--r--contrib/go/_std_1.21/src/go/types/interface.go233
-rw-r--r--contrib/go/_std_1.21/src/go/types/labels.go (renamed from contrib/go/_std_1.20/src/go/types/labels.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/types/lookup.go587
-rw-r--r--contrib/go/_std_1.21/src/go/types/map.go26
-rw-r--r--contrib/go/_std_1.21/src/go/types/methodset.go246
-rw-r--r--contrib/go/_std_1.21/src/go/types/mono.go337
-rw-r--r--contrib/go/_std_1.21/src/go/types/named.go658
-rw-r--r--contrib/go/_std_1.21/src/go/types/object.go613
-rw-r--r--contrib/go/_std_1.21/src/go/types/objset.go33
-rw-r--r--contrib/go/_std_1.21/src/go/types/operand.go374
-rw-r--r--contrib/go/_std_1.21/src/go/types/package.go82
-rw-r--r--contrib/go/_std_1.21/src/go/types/pointer.go21
-rw-r--r--contrib/go/_std_1.21/src/go/types/predicates.go534
-rw-r--r--contrib/go/_std_1.21/src/go/types/resolver.go751
-rw-r--r--contrib/go/_std_1.21/src/go/types/return.go (renamed from contrib/go/_std_1.20/src/go/types/return.go)0
-rw-r--r--contrib/go/_std_1.21/src/go/types/scope.go294
-rw-r--r--contrib/go/_std_1.21/src/go/types/selection.go144
-rw-r--r--contrib/go/_std_1.21/src/go/types/signature.go320
-rw-r--r--contrib/go/_std_1.21/src/go/types/sizes.go345
-rw-r--r--contrib/go/_std_1.21/src/go/types/slice.go21
-rw-r--r--contrib/go/_std_1.21/src/go/types/stmt.go962
-rw-r--r--contrib/go/_std_1.21/src/go/types/struct.go218
-rw-r--r--contrib/go/_std_1.21/src/go/types/subst.go423
-rw-r--r--contrib/go/_std_1.21/src/go/types/termlist.go163
-rw-r--r--contrib/go/_std_1.21/src/go/types/tuple.go36
-rw-r--r--contrib/go/_std_1.21/src/go/types/type.go15
-rw-r--r--contrib/go/_std_1.21/src/go/types/typelists.go71
-rw-r--r--contrib/go/_std_1.21/src/go/types/typeparam.go158
-rw-r--r--contrib/go/_std_1.21/src/go/types/typeset.go414
-rw-r--r--contrib/go/_std_1.21/src/go/types/typestring.go500
-rw-r--r--contrib/go/_std_1.21/src/go/types/typeterm.go167
-rw-r--r--contrib/go/_std_1.21/src/go/types/typexpr.go522
-rw-r--r--contrib/go/_std_1.21/src/go/types/under.go116
-rw-r--r--contrib/go/_std_1.21/src/go/types/unify.go795
-rw-r--r--contrib/go/_std_1.21/src/go/types/union.go200
-rw-r--r--contrib/go/_std_1.21/src/go/types/universe.go290
-rw-r--r--contrib/go/_std_1.21/src/go/types/util.go22
-rw-r--r--contrib/go/_std_1.21/src/go/types/validtype.go258
-rw-r--r--contrib/go/_std_1.21/src/go/types/version.go154
-rw-r--r--contrib/go/_std_1.21/src/go/types/ya.make108
-rw-r--r--contrib/go/_std_1.21/src/hash/adler32/adler32.go (renamed from contrib/go/_std_1.20/src/hash/adler32/adler32.go)0
-rw-r--r--contrib/go/_std_1.21/src/hash/adler32/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/hash/crc32/crc32.go (renamed from contrib/go/_std_1.20/src/hash/crc32/crc32.go)0
-rw-r--r--contrib/go/_std_1.21/src/hash/crc32/crc32_amd64.go (renamed from contrib/go/_std_1.20/src/hash/crc32/crc32_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/hash/crc32/crc32_amd64.s (renamed from contrib/go/_std_1.20/src/hash/crc32/crc32_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/hash/crc32/crc32_arm64.go (renamed from contrib/go/_std_1.20/src/hash/crc32/crc32_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/hash/crc32/crc32_arm64.s (renamed from contrib/go/_std_1.20/src/hash/crc32/crc32_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/hash/crc32/crc32_generic.go (renamed from contrib/go/_std_1.20/src/hash/crc32/crc32_generic.go)0
-rw-r--r--contrib/go/_std_1.21/src/hash/crc32/ya.make29
-rw-r--r--contrib/go/_std_1.21/src/hash/crc64/crc64.go (renamed from contrib/go/_std_1.20/src/hash/crc64/crc64.go)0
-rw-r--r--contrib/go/_std_1.21/src/hash/crc64/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/hash/fnv/fnv.go (renamed from contrib/go/_std_1.20/src/hash/fnv/fnv.go)0
-rw-r--r--contrib/go/_std_1.21/src/hash/fnv/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/hash/hash.go (renamed from contrib/go/_std_1.20/src/hash/hash.go)0
-rw-r--r--contrib/go/_std_1.21/src/hash/maphash/maphash.go277
-rw-r--r--contrib/go/_std_1.21/src/hash/maphash/maphash_runtime.go43
-rw-r--r--contrib/go/_std_1.21/src/hash/maphash/ya.make18
-rw-r--r--contrib/go/_std_1.21/src/hash/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/html/entity.go (renamed from contrib/go/_std_1.20/src/html/entity.go)0
-rw-r--r--contrib/go/_std_1.21/src/html/escape.go (renamed from contrib/go/_std_1.20/src/html/escape.go)0
-rw-r--r--contrib/go/_std_1.21/src/html/template/attr.go (renamed from contrib/go/_std_1.20/src/html/template/attr.go)0
-rw-r--r--contrib/go/_std_1.21/src/html/template/attr_string.go28
-rw-r--r--contrib/go/_std_1.21/src/html/template/content.go (renamed from contrib/go/_std_1.20/src/html/template/content.go)0
-rw-r--r--contrib/go/_std_1.21/src/html/template/context.go286
-rw-r--r--contrib/go/_std_1.21/src/html/template/css.go (renamed from contrib/go/_std_1.20/src/html/template/css.go)0
-rw-r--r--contrib/go/_std_1.21/src/html/template/delim_string.go26
-rw-r--r--contrib/go/_std_1.21/src/html/template/doc.go242
-rw-r--r--contrib/go/_std_1.21/src/html/template/element_string.go27
-rw-r--r--contrib/go/_std_1.21/src/html/template/error.go244
-rw-r--r--contrib/go/_std_1.21/src/html/template/escape.go1008
-rw-r--r--contrib/go/_std_1.21/src/html/template/html.go (renamed from contrib/go/_std_1.20/src/html/template/html.go)0
-rw-r--r--contrib/go/_std_1.21/src/html/template/js.go (renamed from contrib/go/_std_1.20/src/html/template/js.go)0
-rw-r--r--contrib/go/_std_1.21/src/html/template/jsctx_string.go (renamed from contrib/go/_std_1.20/src/html/template/jsctx_string.go)0
-rw-r--r--contrib/go/_std_1.21/src/html/template/state_string.go51
-rw-r--r--contrib/go/_std_1.21/src/html/template/template.go (renamed from contrib/go/_std_1.20/src/html/template/template.go)0
-rw-r--r--contrib/go/_std_1.21/src/html/template/transition.go634
-rw-r--r--contrib/go/_std_1.21/src/html/template/url.go (renamed from contrib/go/_std_1.20/src/html/template/url.go)0
-rw-r--r--contrib/go/_std_1.21/src/html/template/urlpart_string.go26
-rw-r--r--contrib/go/_std_1.21/src/html/template/ya.make46
-rw-r--r--contrib/go/_std_1.21/src/html/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/image/color/color.go (renamed from contrib/go/_std_1.20/src/image/color/color.go)0
-rw-r--r--contrib/go/_std_1.21/src/image/color/ya.make17
-rw-r--r--contrib/go/_std_1.21/src/image/color/ycbcr.go (renamed from contrib/go/_std_1.20/src/image/color/ycbcr.go)0
-rw-r--r--contrib/go/_std_1.21/src/image/format.go (renamed from contrib/go/_std_1.20/src/image/format.go)0
-rw-r--r--contrib/go/_std_1.21/src/image/geom.go (renamed from contrib/go/_std_1.20/src/image/geom.go)0
-rw-r--r--contrib/go/_std_1.21/src/image/image.go (renamed from contrib/go/_std_1.20/src/image/image.go)0
-rw-r--r--contrib/go/_std_1.21/src/image/names.go (renamed from contrib/go/_std_1.20/src/image/names.go)0
-rw-r--r--contrib/go/_std_1.21/src/image/ya.make31
-rw-r--r--contrib/go/_std_1.21/src/image/ycbcr.go (renamed from contrib/go/_std_1.20/src/image/ycbcr.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/abi.go102
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/abi_amd64.go (renamed from contrib/go/_std_1.20/src/internal/abi/abi_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/abi_arm64.go (renamed from contrib/go/_std_1.20/src/internal/abi/abi_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/abi_test.s (renamed from contrib/go/_std_1.20/src/internal/abi/abi_test.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/compiletype.go167
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/funcpc.go31
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/map.go14
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/stack.go33
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/stub.s7
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/symtab.go106
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/type.go712
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/unsafestring_go120.go18
-rw-r--r--contrib/go/_std_1.21/src/internal/abi/ya.make35
-rw-r--r--contrib/go/_std_1.21/src/internal/bisect/bisect.go795
-rw-r--r--contrib/go/_std_1.21/src/internal/bisect/ya.make7
-rw-r--r--contrib/go/_std_1.21/src/internal/buildcfg/cfg.go235
-rw-r--r--contrib/go/_std_1.21/src/internal/buildcfg/exp.go189
-rw-r--r--contrib/go/_std_1.21/src/internal/buildcfg/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go18
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/bytealg.go155
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/compare_amd64.s (renamed from contrib/go/_std_1.20/src/internal/bytealg/compare_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/compare_arm64.s (renamed from contrib/go/_std_1.20/src/internal/bytealg/compare_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/compare_native.go (renamed from contrib/go/_std_1.20/src/internal/bytealg/compare_native.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/count_amd64.s (renamed from contrib/go/_std_1.20/src/internal/bytealg/count_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/count_arm64.s (renamed from contrib/go/_std_1.20/src/internal/bytealg/count_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/count_native.go (renamed from contrib/go/_std_1.20/src/internal/bytealg/count_native.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/equal_amd64.s (renamed from contrib/go/_std_1.20/src/internal/bytealg/equal_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/equal_arm64.s (renamed from contrib/go/_std_1.20/src/internal/bytealg/equal_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/equal_generic.go (renamed from contrib/go/_std_1.20/src/internal/bytealg/equal_generic.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/equal_native.go (renamed from contrib/go/_std_1.20/src/internal/bytealg/equal_native.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/index_amd64.go (renamed from contrib/go/_std_1.20/src/internal/bytealg/index_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/index_amd64.s (renamed from contrib/go/_std_1.20/src/internal/bytealg/index_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/index_arm64.go (renamed from contrib/go/_std_1.20/src/internal/bytealg/index_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/index_arm64.s (renamed from contrib/go/_std_1.20/src/internal/bytealg/index_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/index_native.go19
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/indexbyte_amd64.s (renamed from contrib/go/_std_1.20/src/internal/bytealg/indexbyte_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/indexbyte_arm64.s (renamed from contrib/go/_std_1.20/src/internal/bytealg/indexbyte_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/indexbyte_native.go (renamed from contrib/go/_std_1.20/src/internal/bytealg/indexbyte_native.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/bytealg/ya.make35
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/calloc/batchcounteralloc.go (renamed from contrib/go/_std_1.20/src/internal/coverage/calloc/batchcounteralloc.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/calloc/ya.make (renamed from contrib/go/_std_1.20/src/internal/coverage/calloc/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/cformat/format.go352
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/cformat/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/cmddefs.go87
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/cmerge/merge.go127
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/cmerge/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/decodecounter/decodecounterfile.go373
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/decodecounter/ya.make (renamed from contrib/go/_std_1.20/src/internal/coverage/decodecounter/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/decodemeta/decode.go136
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/decodemeta/decodefile.go (renamed from contrib/go/_std_1.20/src/internal/coverage/decodemeta/decodefile.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/decodemeta/ya.make (renamed from contrib/go/_std_1.20/src/internal/coverage/decodemeta/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/defs.go374
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/encodecounter/encode.go297
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/encodecounter/ya.make (renamed from contrib/go/_std_1.20/src/internal/coverage/encodecounter/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/encodemeta/encode.go (renamed from contrib/go/_std_1.20/src/internal/coverage/encodemeta/encode.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/encodemeta/encodefile.go (renamed from contrib/go/_std_1.20/src/internal/coverage/encodemeta/encodefile.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/encodemeta/ya.make (renamed from contrib/go/_std_1.20/src/internal/coverage/encodemeta/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/pkid.go (renamed from contrib/go/_std_1.20/src/internal/coverage/pkid.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/pods/pods.go197
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/pods/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/rtcov/rtcov.go (renamed from contrib/go/_std_1.20/src/internal/coverage/rtcov/rtcov.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/rtcov/ya.make (renamed from contrib/go/_std_1.20/src/internal/coverage/rtcov/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/slicereader/slicereader.go123
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/slicereader/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/slicewriter/slicewriter.go80
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/slicewriter/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/stringtab/stringtab.go (renamed from contrib/go/_std_1.20/src/internal/coverage/stringtab/stringtab.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/stringtab/ya.make (renamed from contrib/go/_std_1.20/src/internal/coverage/stringtab/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/uleb128/uleb128.go (renamed from contrib/go/_std_1.20/src/internal/coverage/uleb128/uleb128.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/uleb128/ya.make (renamed from contrib/go/_std_1.20/src/internal/coverage/uleb128/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/coverage/ya.make26
-rw-r--r--contrib/go/_std_1.21/src/internal/cpu/cpu.go222
-rw-r--r--contrib/go/_std_1.21/src/internal/cpu/cpu.s (renamed from contrib/go/_std_1.20/src/internal/cpu/cpu.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/cpu/cpu_arm64.go69
-rw-r--r--contrib/go/_std_1.21/src/internal/cpu/cpu_arm64.s (renamed from contrib/go/_std_1.20/src/internal/cpu/cpu_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/cpu/cpu_arm64_hwcap.go66
-rw-r--r--contrib/go/_std_1.21/src/internal/cpu/cpu_arm64_linux.go (renamed from contrib/go/_std_1.20/src/internal/cpu/cpu_arm64_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/cpu/cpu_no_name.go (renamed from contrib/go/_std_1.20/src/internal/cpu/cpu_no_name.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/cpu/cpu_x86.go (renamed from contrib/go/_std_1.20/src/internal/cpu/cpu_x86.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/cpu/cpu_x86.s (renamed from contrib/go/_std_1.20/src/internal/cpu/cpu_x86.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/cpu/ya.make53
-rw-r--r--contrib/go/_std_1.21/src/internal/fmtsort/sort.go (renamed from contrib/go/_std_1.20/src/internal/fmtsort/sort.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fmtsort/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/counters_supported.go (renamed from contrib/go/_std_1.20/src/internal/fuzz/counters_supported.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/coverage.go (renamed from contrib/go/_std_1.20/src/internal/fuzz/coverage.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/encoding.go (renamed from contrib/go/_std_1.20/src/internal/fuzz/encoding.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/fuzz.go1102
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/mem.go (renamed from contrib/go/_std_1.20/src/internal/fuzz/mem.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/minimize.go (renamed from contrib/go/_std_1.20/src/internal/fuzz/minimize.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/mutator.go (renamed from contrib/go/_std_1.20/src/internal/fuzz/mutator.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/mutators_byteslice.go (renamed from contrib/go/_std_1.20/src/internal/fuzz/mutators_byteslice.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/pcg.go (renamed from contrib/go/_std_1.20/src/internal/fuzz/pcg.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/queue.go (renamed from contrib/go/_std_1.20/src/internal/fuzz/queue.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/sys_posix.go (renamed from contrib/go/_std_1.20/src/internal/fuzz/sys_posix.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/sys_windows.go (renamed from contrib/go/_std_1.20/src/internal/fuzz/sys_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/trace.go (renamed from contrib/go/_std_1.20/src/internal/fuzz/trace.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/worker.go1195
-rw-r--r--contrib/go/_std_1.21/src/internal/fuzz/ya.make48
-rw-r--r--contrib/go/_std_1.21/src/internal/goarch/goarch.go (renamed from contrib/go/_std_1.20/src/internal/goarch/goarch.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goarch/goarch_amd64.go (renamed from contrib/go/_std_1.20/src/internal/goarch/goarch_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goarch/goarch_arm64.go (renamed from contrib/go/_std_1.20/src/internal/goarch/goarch_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goarch/ya.make21
-rw-r--r--contrib/go/_std_1.21/src/internal/goarch/zgoarch_amd64.go (renamed from contrib/go/_std_1.20/src/internal/goarch/zgoarch_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goarch/zgoarch_arm64.go (renamed from contrib/go/_std_1.20/src/internal/goarch/zgoarch_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/godebug/godebug.go291
-rw-r--r--contrib/go/_std_1.21/src/internal/godebug/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/internal/godebugs/table.go69
-rw-r--r--contrib/go/_std_1.21/src/internal/godebugs/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_arenas_off.go (renamed from contrib/go/_std_1.20/src/internal/goexperiment/exp_arenas_off.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_boringcrypto_off.go (renamed from contrib/go/_std_1.20/src/internal/goexperiment/exp_boringcrypto_off.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_cacheprog_off.go9
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_cgocheck2_off.go9
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_coverageredesign_on.go9
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_fieldtrack_off.go (renamed from contrib/go/_std_1.20/src/internal/goexperiment/exp_fieldtrack_off.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_heapminimum512kib_off.go (renamed from contrib/go/_std_1.20/src/internal/goexperiment/exp_heapminimum512kib_off.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_loopvar_off.go9
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_pagetrace_off.go (renamed from contrib/go/_std_1.20/src/internal/goexperiment/exp_pagetrace_off.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_preemptibleloops_off.go (renamed from contrib/go/_std_1.20/src/internal/goexperiment/exp_preemptibleloops_off.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_regabiargs_on.go (renamed from contrib/go/_std_1.20/src/internal/goexperiment/exp_regabiargs_on.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_regabiwrappers_on.go (renamed from contrib/go/_std_1.20/src/internal/goexperiment/exp_regabiwrappers_on.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/exp_staticlockranking_off.go (renamed from contrib/go/_std_1.20/src/internal/goexperiment/exp_staticlockranking_off.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/flags.go112
-rw-r--r--contrib/go/_std_1.21/src/internal/goexperiment/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/internal/goos/goos.go (renamed from contrib/go/_std_1.20/src/internal/goos/goos.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goos/nonunix.go (renamed from contrib/go/_std_1.20/src/internal/goos/nonunix.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goos/unix.go (renamed from contrib/go/_std_1.20/src/internal/goos/unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/goos/ya.make28
-rw-r--r--contrib/go/_std_1.21/src/internal/goos/zgoos_darwin.go26
-rw-r--r--contrib/go/_std_1.21/src/internal/goos/zgoos_linux.go26
-rw-r--r--contrib/go/_std_1.21/src/internal/goos/zgoos_windows.go26
-rw-r--r--contrib/go/_std_1.21/src/internal/goroot/gc.go131
-rw-r--r--contrib/go/_std_1.21/src/internal/goroot/ya.make7
-rw-r--r--contrib/go/_std_1.21/src/internal/goversion/goversion.go12
-rw-r--r--contrib/go/_std_1.21/src/internal/goversion/ya.make (renamed from contrib/go/_std_1.20/src/internal/goversion/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/intern/intern.go181
-rw-r--r--contrib/go/_std_1.21/src/internal/intern/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/internal/itoa/itoa.go (renamed from contrib/go/_std_1.20/src/internal/itoa/itoa.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/itoa/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/internal/lazyregexp/lazyre.go (renamed from contrib/go/_std_1.20/src/internal/lazyregexp/lazyre.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/lazyregexp/ya.make (renamed from contrib/go/_std_1.20/src/internal/lazyregexp/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/nettrace/nettrace.go (renamed from contrib/go/_std_1.20/src/internal/nettrace/nettrace.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/nettrace/ya.make (renamed from contrib/go/_std_1.20/src/internal/nettrace/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/oserror/errors.go (renamed from contrib/go/_std_1.20/src/internal/oserror/errors.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/oserror/ya.make (renamed from contrib/go/_std_1.20/src/internal/oserror/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/pkgbits/codes.go (renamed from contrib/go/_std_1.20/src/internal/pkgbits/codes.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/pkgbits/decoder.go (renamed from contrib/go/_std_1.20/src/internal/pkgbits/decoder.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/pkgbits/doc.go (renamed from contrib/go/_std_1.20/src/internal/pkgbits/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/pkgbits/encoder.go (renamed from contrib/go/_std_1.20/src/internal/pkgbits/encoder.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/pkgbits/flags.go (renamed from contrib/go/_std_1.20/src/internal/pkgbits/flags.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/pkgbits/reloc.go (renamed from contrib/go/_std_1.20/src/internal/pkgbits/reloc.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/pkgbits/support.go (renamed from contrib/go/_std_1.20/src/internal/pkgbits/support.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/pkgbits/sync.go (renamed from contrib/go/_std_1.20/src/internal/pkgbits/sync.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/pkgbits/syncmarker_string.go92
-rw-r--r--contrib/go/_std_1.21/src/internal/pkgbits/ya.make (renamed from contrib/go/_std_1.20/src/internal/pkgbits/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/platform/supported.go286
-rw-r--r--contrib/go/_std_1.21/src/internal/platform/ya.make13
-rw-r--r--contrib/go/_std_1.21/src/internal/platform/zosarch.go114
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/copy_file_range_linux.go (renamed from contrib/go/_std_1.20/src/internal/poll/copy_file_range_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/errno_unix.go33
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/errno_windows.go (renamed from contrib/go/_std_1.20/src/internal/poll/errno_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd.go (renamed from contrib/go/_std_1.20/src/internal/poll/fd.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd_fsync_darwin.go24
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd_fsync_posix.go20
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd_fsync_windows.go (renamed from contrib/go/_std_1.20/src/internal/poll/fd_fsync_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd_mutex.go (renamed from contrib/go/_std_1.20/src/internal/poll/fd_mutex.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd_opendir_darwin.go (renamed from contrib/go/_std_1.20/src/internal/poll/fd_opendir_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd_poll_runtime.go170
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd_posix.go79
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd_unix.go741
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd_unixjs.go79
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd_windows.go1332
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd_writev_libc.go (renamed from contrib/go/_std_1.20/src/internal/poll/fd_writev_libc.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/fd_writev_unix.go (renamed from contrib/go/_std_1.20/src/internal/poll/fd_writev_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/hook_cloexec.go (renamed from contrib/go/_std_1.20/src/internal/poll/hook_cloexec.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/hook_unix.go15
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/hook_windows.go (renamed from contrib/go/_std_1.20/src/internal/poll/hook_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/iovec_unix.go (renamed from contrib/go/_std_1.20/src/internal/poll/iovec_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/sendfile_bsd.go (renamed from contrib/go/_std_1.20/src/internal/poll/sendfile_bsd.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/sendfile_linux.go (renamed from contrib/go/_std_1.20/src/internal/poll/sendfile_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/sendfile_windows.go84
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/sock_cloexec.go49
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/sockopt.go45
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/sockopt_linux.go (renamed from contrib/go/_std_1.20/src/internal/poll/sockopt_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/sockopt_unix.go (renamed from contrib/go/_std_1.20/src/internal/poll/sockopt_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/sockopt_windows.go (renamed from contrib/go/_std_1.20/src/internal/poll/sockopt_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/sockoptip.go (renamed from contrib/go/_std_1.20/src/internal/poll/sockoptip.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/splice_linux.go233
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/sys_cloexec.go36
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/writev.go (renamed from contrib/go/_std_1.20/src/internal/poll/writev.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/poll/ya.make92
-rw-r--r--contrib/go/_std_1.21/src/internal/profile/encode.go (renamed from contrib/go/_std_1.20/src/internal/profile/encode.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/profile/filter.go (renamed from contrib/go/_std_1.20/src/internal/profile/filter.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/profile/legacy_profile.go1268
-rw-r--r--contrib/go/_std_1.21/src/internal/profile/merge.go (renamed from contrib/go/_std_1.20/src/internal/profile/merge.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/profile/profile.go613
-rw-r--r--contrib/go/_std_1.21/src/internal/profile/proto.go (renamed from contrib/go/_std_1.20/src/internal/profile/proto.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/profile/prune.go (renamed from contrib/go/_std_1.20/src/internal/profile/prune.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/profile/ya.make21
-rw-r--r--contrib/go/_std_1.21/src/internal/race/doc.go (renamed from contrib/go/_std_1.20/src/internal/race/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/race/norace.go (renamed from contrib/go/_std_1.20/src/internal/race/norace.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/race/ya.make24
-rw-r--r--contrib/go/_std_1.21/src/internal/reflectlite/asm.s (renamed from contrib/go/_std_1.20/src/internal/reflectlite/asm.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/reflectlite/swapper.go78
-rw-r--r--contrib/go/_std_1.21/src/internal/reflectlite/type.go659
-rw-r--r--contrib/go/_std_1.21/src/internal/reflectlite/value.go478
-rw-r--r--contrib/go/_std_1.21/src/internal/reflectlite/ya.make22
-rw-r--r--contrib/go/_std_1.21/src/internal/safefilepath/path.go (renamed from contrib/go/_std_1.20/src/internal/safefilepath/path.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/safefilepath/path_other.go (renamed from contrib/go/_std_1.20/src/internal/safefilepath/path_other.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go (renamed from contrib/go/_std_1.20/src/internal/safefilepath/path_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/safefilepath/ya.make30
-rw-r--r--contrib/go/_std_1.21/src/internal/saferio/io.go (renamed from contrib/go/_std_1.20/src/internal/saferio/io.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/saferio/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/internal/singleflight/singleflight.go (renamed from contrib/go/_std_1.20/src/internal/singleflight/singleflight.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/singleflight/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/execenv/execenv_default.go (renamed from contrib/go/_std_1.20/src/internal/syscall/execenv/execenv_default.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/execenv/execenv_windows.go47
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/execenv/ya.make21
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/asm_darwin.s (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/asm_darwin.s)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/at.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/at.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/at_fstatat.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/at_fstatat.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/at_libc2.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/at_libc2.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_darwin.go10
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_fstatat_linux.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_fstatat_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_linux.go19
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/constants.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/constants.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/copy_file_range_linux.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/copy_file_range_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/eaccess_linux.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/eaccess_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/eaccess_other.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/eaccess_other.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/fcntl_unix.go26
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/getentropy_darwin.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/getentropy_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/getrandom.go39
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/getrandom_linux.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/getrandom_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/kernel_version_linux.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/kernel_version_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/kernel_version_other.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/kernel_version_other.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/net.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/net.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/net_darwin.go162
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/nonblocking_unix.go21
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/pty_darwin.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/pty_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/sysnum_linux_amd64.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/sysnum_linux_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/sysnum_linux_generic.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/sysnum_linux_generic.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/user_darwin.go (renamed from contrib/go/_std_1.20/src/internal/syscall/unix/user_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/unix/ya.make64
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/memory_windows.go (renamed from contrib/go/_std_1.20/src/internal/syscall/windows/memory_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/net_windows.go40
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/psapi_windows.go (renamed from contrib/go/_std_1.20/src/internal/syscall/windows/psapi_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/registry/key.go (renamed from contrib/go/_std_1.20/src/internal/syscall/windows/registry/key.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/registry/syscall.go (renamed from contrib/go/_std_1.20/src/internal/syscall/windows/registry/syscall.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/registry/value.go372
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/registry/ya.make24
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/registry/zsyscall_windows.go (renamed from contrib/go/_std_1.20/src/internal/syscall/windows/registry/zsyscall_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go (renamed from contrib/go/_std_1.20/src/internal/syscall/windows/reparse_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/security_windows.go (renamed from contrib/go/_std_1.20/src/internal/syscall/windows/security_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/symlink_windows.go (renamed from contrib/go/_std_1.20/src/internal/syscall/windows/symlink_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go379
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/sysdll/sysdll.go (renamed from contrib/go/_std_1.20/src/internal/syscall/windows/sysdll/sysdll.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/sysdll/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/ya.make33
-rw-r--r--contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go388
-rw-r--r--contrib/go/_std_1.21/src/internal/sysinfo/sysinfo.go (renamed from contrib/go/_std_1.20/src/internal/sysinfo/sysinfo.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/sysinfo/ya.make (renamed from contrib/go/_std_1.20/src/internal/sysinfo/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/testlog/exit.go (renamed from contrib/go/_std_1.20/src/internal/testlog/exit.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/testlog/log.go (renamed from contrib/go/_std_1.20/src/internal/testlog/log.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/testlog/ya.make (renamed from contrib/go/_std_1.20/src/internal/testlog/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/internal/types/errors/code_string.go199
-rw-r--r--contrib/go/_std_1.21/src/internal/types/errors/codes.go1477
-rw-r--r--contrib/go/_std_1.21/src/internal/types/errors/ya.make13
-rw-r--r--contrib/go/_std_1.21/src/internal/unsafeheader/unsafeheader.go (renamed from contrib/go/_std_1.20/src/internal/unsafeheader/unsafeheader.go)0
-rw-r--r--contrib/go/_std_1.21/src/internal/unsafeheader/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/internal/xcoff/ar.go226
-rw-r--r--contrib/go/_std_1.21/src/internal/xcoff/file.go697
-rw-r--r--contrib/go/_std_1.21/src/internal/xcoff/xcoff.go367
-rw-r--r--contrib/go/_std_1.21/src/internal/xcoff/ya.make17
-rw-r--r--contrib/go/_std_1.21/src/internal/zstd/bits.go130
-rw-r--r--contrib/go/_std_1.21/src/internal/zstd/block.go436
-rw-r--r--contrib/go/_std_1.21/src/internal/zstd/fse.go437
-rw-r--r--contrib/go/_std_1.21/src/internal/zstd/huff.go204
-rw-r--r--contrib/go/_std_1.21/src/internal/zstd/literals.go330
-rw-r--r--contrib/go/_std_1.21/src/internal/zstd/xxhash.go148
-rw-r--r--contrib/go/_std_1.21/src/internal/zstd/ya.make23
-rw-r--r--contrib/go/_std_1.21/src/internal/zstd/zstd.go508
-rw-r--r--contrib/go/_std_1.21/src/io/fs/format.go76
-rw-r--r--contrib/go/_std_1.21/src/io/fs/fs.go (renamed from contrib/go/_std_1.20/src/io/fs/fs.go)0
-rw-r--r--contrib/go/_std_1.21/src/io/fs/glob.go (renamed from contrib/go/_std_1.20/src/io/fs/glob.go)0
-rw-r--r--contrib/go/_std_1.21/src/io/fs/readdir.go81
-rw-r--r--contrib/go/_std_1.21/src/io/fs/readfile.go (renamed from contrib/go/_std_1.20/src/io/fs/readfile.go)0
-rw-r--r--contrib/go/_std_1.21/src/io/fs/stat.go (renamed from contrib/go/_std_1.20/src/io/fs/stat.go)0
-rw-r--r--contrib/go/_std_1.21/src/io/fs/sub.go (renamed from contrib/go/_std_1.20/src/io/fs/sub.go)0
-rw-r--r--contrib/go/_std_1.21/src/io/fs/walk.go141
-rw-r--r--contrib/go/_std_1.21/src/io/fs/ya.make29
-rw-r--r--contrib/go/_std_1.21/src/io/io.go718
-rw-r--r--contrib/go/_std_1.21/src/io/ioutil/ioutil.go95
-rw-r--r--contrib/go/_std_1.21/src/io/ioutil/tempfile.go41
-rw-r--r--contrib/go/_std_1.21/src/io/ioutil/ya.make17
-rw-r--r--contrib/go/_std_1.21/src/io/multi.go (renamed from contrib/go/_std_1.20/src/io/multi.go)0
-rw-r--r--contrib/go/_std_1.21/src/io/pipe.go (renamed from contrib/go/_std_1.20/src/io/pipe.go)0
-rw-r--r--contrib/go/_std_1.21/src/io/ya.make23
-rw-r--r--contrib/go/_std_1.21/src/log/internal/internal.go12
-rw-r--r--contrib/go/_std_1.21/src/log/internal/ya.make7
-rw-r--r--contrib/go/_std_1.21/src/log/log.go458
-rw-r--r--contrib/go/_std_1.21/src/log/slog/attr.go102
-rw-r--r--contrib/go/_std_1.21/src/log/slog/doc.go320
-rw-r--r--contrib/go/_std_1.21/src/log/slog/handler.go567
-rw-r--r--contrib/go/_std_1.21/src/log/slog/internal/benchmarks/benchmarks.go50
-rw-r--r--contrib/go/_std_1.21/src/log/slog/internal/benchmarks/handlers.go148
-rw-r--r--contrib/go/_std_1.21/src/log/slog/internal/benchmarks/ya.make16
-rw-r--r--contrib/go/_std_1.21/src/log/slog/internal/buffer/buffer.go84
-rw-r--r--contrib/go/_std_1.21/src/log/slog/internal/buffer/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/log/slog/internal/ignorepc.go9
-rw-r--r--contrib/go/_std_1.21/src/log/slog/internal/slogtest/slogtest.go18
-rw-r--r--contrib/go/_std_1.21/src/log/slog/internal/slogtest/ya.make7
-rw-r--r--contrib/go/_std_1.21/src/log/slog/internal/ya.make13
-rw-r--r--contrib/go/_std_1.21/src/log/slog/json_handler.go336
-rw-r--r--contrib/go/_std_1.21/src/log/slog/level.go200
-rw-r--r--contrib/go/_std_1.21/src/log/slog/logger.go296
-rw-r--r--contrib/go/_std_1.21/src/log/slog/record.go225
-rw-r--r--contrib/go/_std_1.21/src/log/slog/text_handler.go163
-rw-r--r--contrib/go/_std_1.21/src/log/slog/value.go520
-rw-r--r--contrib/go/_std_1.21/src/log/slog/ya.make41
-rw-r--r--contrib/go/_std_1.21/src/log/syslog/doc.go (renamed from contrib/go/_std_1.20/src/log/syslog/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/log/syslog/syslog.go (renamed from contrib/go/_std_1.20/src/log/syslog/syslog.go)0
-rw-r--r--contrib/go/_std_1.21/src/log/syslog/syslog_unix.go (renamed from contrib/go/_std_1.20/src/log/syslog/syslog_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/log/syslog/ya.make32
-rw-r--r--contrib/go/_std_1.21/src/log/ya.make17
-rw-r--r--contrib/go/_std_1.21/src/math/abs.go (renamed from contrib/go/_std_1.20/src/math/abs.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/acosh.go (renamed from contrib/go/_std_1.20/src/math/acosh.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/asin.go (renamed from contrib/go/_std_1.20/src/math/asin.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/asinh.go77
-rw-r--r--contrib/go/_std_1.21/src/math/atan.go (renamed from contrib/go/_std_1.20/src/math/atan.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/atan2.go (renamed from contrib/go/_std_1.20/src/math/atan2.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/atanh.go (renamed from contrib/go/_std_1.20/src/math/atanh.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/accuracy_string.go26
-rw-r--r--contrib/go/_std_1.21/src/math/big/arith.go (renamed from contrib/go/_std_1.20/src/math/big/arith.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/arith_amd64.go (renamed from contrib/go/_std_1.20/src/math/big/arith_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/arith_amd64.s (renamed from contrib/go/_std_1.20/src/math/big/arith_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/arith_arm64.s (renamed from contrib/go/_std_1.20/src/math/big/arith_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/arith_decl.go (renamed from contrib/go/_std_1.20/src/math/big/arith_decl.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/decimal.go (renamed from contrib/go/_std_1.20/src/math/big/decimal.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/doc.go98
-rw-r--r--contrib/go/_std_1.21/src/math/big/float.go1736
-rw-r--r--contrib/go/_std_1.21/src/math/big/floatconv.go302
-rw-r--r--contrib/go/_std_1.21/src/math/big/floatmarsh.go131
-rw-r--r--contrib/go/_std_1.21/src/math/big/ftoa.go (renamed from contrib/go/_std_1.20/src/math/big/ftoa.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/int.go1321
-rw-r--r--contrib/go/_std_1.21/src/math/big/intconv.go (renamed from contrib/go/_std_1.20/src/math/big/intconv.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/intmarsh.go (renamed from contrib/go/_std_1.20/src/math/big/intmarsh.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/nat.go (renamed from contrib/go/_std_1.20/src/math/big/nat.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/natconv.go (renamed from contrib/go/_std_1.20/src/math/big/natconv.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/natdiv.go (renamed from contrib/go/_std_1.20/src/math/big/natdiv.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/prime.go (renamed from contrib/go/_std_1.20/src/math/big/prime.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/rat.go (renamed from contrib/go/_std_1.20/src/math/big/rat.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/ratconv.go (renamed from contrib/go/_std_1.20/src/math/big/ratconv.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/ratmarsh.go (renamed from contrib/go/_std_1.20/src/math/big/ratmarsh.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/roundingmode_string.go28
-rw-r--r--contrib/go/_std_1.21/src/math/big/sqrt.go (renamed from contrib/go/_std_1.20/src/math/big/sqrt.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/big/ya.make73
-rw-r--r--contrib/go/_std_1.21/src/math/bits.go (renamed from contrib/go/_std_1.20/src/math/bits.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/bits/bits.go (renamed from contrib/go/_std_1.20/src/math/bits/bits.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/bits/bits_errors.go (renamed from contrib/go/_std_1.20/src/math/bits/bits_errors.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/bits/bits_tables.go (renamed from contrib/go/_std_1.20/src/math/bits/bits_tables.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/bits/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/math/cbrt.go (renamed from contrib/go/_std_1.20/src/math/cbrt.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/abs.go (renamed from contrib/go/_std_1.20/src/math/cmplx/abs.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/asin.go (renamed from contrib/go/_std_1.20/src/math/cmplx/asin.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/conj.go (renamed from contrib/go/_std_1.20/src/math/cmplx/conj.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/exp.go (renamed from contrib/go/_std_1.20/src/math/cmplx/exp.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/isinf.go (renamed from contrib/go/_std_1.20/src/math/cmplx/isinf.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/isnan.go (renamed from contrib/go/_std_1.20/src/math/cmplx/isnan.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/log.go (renamed from contrib/go/_std_1.20/src/math/cmplx/log.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/phase.go (renamed from contrib/go/_std_1.20/src/math/cmplx/phase.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/polar.go (renamed from contrib/go/_std_1.20/src/math/cmplx/polar.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/pow.go (renamed from contrib/go/_std_1.20/src/math/cmplx/pow.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/rect.go (renamed from contrib/go/_std_1.20/src/math/cmplx/rect.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/sin.go (renamed from contrib/go/_std_1.20/src/math/cmplx/sin.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/sqrt.go (renamed from contrib/go/_std_1.20/src/math/cmplx/sqrt.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/tan.go (renamed from contrib/go/_std_1.20/src/math/cmplx/tan.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/cmplx/ya.make30
-rw-r--r--contrib/go/_std_1.21/src/math/const.go (renamed from contrib/go/_std_1.20/src/math/const.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/copysign.go (renamed from contrib/go/_std_1.20/src/math/copysign.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/dim.go100
-rw-r--r--contrib/go/_std_1.21/src/math/dim_amd64.s (renamed from contrib/go/_std_1.20/src/math/dim_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/math/dim_arm64.s (renamed from contrib/go/_std_1.20/src/math/dim_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/math/dim_asm.go (renamed from contrib/go/_std_1.20/src/math/dim_asm.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/erf.go (renamed from contrib/go/_std_1.20/src/math/erf.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/erfinv.go (renamed from contrib/go/_std_1.20/src/math/erfinv.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/exp.go (renamed from contrib/go/_std_1.20/src/math/exp.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/exp2_asm.go (renamed from contrib/go/_std_1.20/src/math/exp2_asm.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/exp2_noasm.go (renamed from contrib/go/_std_1.20/src/math/exp2_noasm.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/exp_amd64.go (renamed from contrib/go/_std_1.20/src/math/exp_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/exp_amd64.s (renamed from contrib/go/_std_1.20/src/math/exp_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/math/exp_arm64.s (renamed from contrib/go/_std_1.20/src/math/exp_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/math/exp_asm.go (renamed from contrib/go/_std_1.20/src/math/exp_asm.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/expm1.go (renamed from contrib/go/_std_1.20/src/math/expm1.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/floor.go (renamed from contrib/go/_std_1.20/src/math/floor.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/floor_amd64.s (renamed from contrib/go/_std_1.20/src/math/floor_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/math/floor_arm64.s (renamed from contrib/go/_std_1.20/src/math/floor_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/math/floor_asm.go (renamed from contrib/go/_std_1.20/src/math/floor_asm.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/fma.go175
-rw-r--r--contrib/go/_std_1.21/src/math/frexp.go (renamed from contrib/go/_std_1.20/src/math/frexp.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/gamma.go (renamed from contrib/go/_std_1.20/src/math/gamma.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/hypot.go (renamed from contrib/go/_std_1.20/src/math/hypot.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/hypot_amd64.s (renamed from contrib/go/_std_1.20/src/math/hypot_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/math/hypot_asm.go (renamed from contrib/go/_std_1.20/src/math/hypot_asm.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/hypot_noasm.go (renamed from contrib/go/_std_1.20/src/math/hypot_noasm.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/j0.go (renamed from contrib/go/_std_1.20/src/math/j0.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/j1.go (renamed from contrib/go/_std_1.20/src/math/j1.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/jn.go (renamed from contrib/go/_std_1.20/src/math/jn.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/ldexp.go (renamed from contrib/go/_std_1.20/src/math/ldexp.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/lgamma.go (renamed from contrib/go/_std_1.20/src/math/lgamma.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/log.go (renamed from contrib/go/_std_1.20/src/math/log.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/log10.go (renamed from contrib/go/_std_1.20/src/math/log10.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/log1p.go (renamed from contrib/go/_std_1.20/src/math/log1p.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/log_amd64.s112
-rw-r--r--contrib/go/_std_1.21/src/math/log_asm.go (renamed from contrib/go/_std_1.20/src/math/log_asm.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/log_stub.go (renamed from contrib/go/_std_1.20/src/math/log_stub.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/logb.go (renamed from contrib/go/_std_1.20/src/math/logb.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/mod.go (renamed from contrib/go/_std_1.20/src/math/mod.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/modf.go (renamed from contrib/go/_std_1.20/src/math/modf.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/modf_arm64.s (renamed from contrib/go/_std_1.20/src/math/modf_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/math/modf_asm.go (renamed from contrib/go/_std_1.20/src/math/modf_asm.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/modf_noasm.go (renamed from contrib/go/_std_1.20/src/math/modf_noasm.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/nextafter.go (renamed from contrib/go/_std_1.20/src/math/nextafter.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/pow.go166
-rw-r--r--contrib/go/_std_1.21/src/math/pow10.go (renamed from contrib/go/_std_1.20/src/math/pow10.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/rand/exp.go (renamed from contrib/go/_std_1.20/src/math/rand/exp.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/rand/normal.go (renamed from contrib/go/_std_1.20/src/math/rand/normal.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/rand/rand.go548
-rw-r--r--contrib/go/_std_1.21/src/math/rand/rng.go252
-rw-r--r--contrib/go/_std_1.21/src/math/rand/ya.make25
-rw-r--r--contrib/go/_std_1.21/src/math/rand/zipf.go (renamed from contrib/go/_std_1.20/src/math/rand/zipf.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/remainder.go (renamed from contrib/go/_std_1.20/src/math/remainder.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/signbit.go (renamed from contrib/go/_std_1.20/src/math/signbit.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/sin.go (renamed from contrib/go/_std_1.20/src/math/sin.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/sincos.go (renamed from contrib/go/_std_1.20/src/math/sincos.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/sinh.go (renamed from contrib/go/_std_1.20/src/math/sinh.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/sqrt.go (renamed from contrib/go/_std_1.20/src/math/sqrt.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/stubs.go (renamed from contrib/go/_std_1.20/src/math/stubs.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/tan.go (renamed from contrib/go/_std_1.20/src/math/tan.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/tanh.go (renamed from contrib/go/_std_1.20/src/math/tanh.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/trig_reduce.go (renamed from contrib/go/_std_1.20/src/math/trig_reduce.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/unsafe.go (renamed from contrib/go/_std_1.20/src/math/unsafe.go)0
-rw-r--r--contrib/go/_std_1.21/src/math/ya.make99
-rw-r--r--contrib/go/_std_1.21/src/mime/encodedword.go (renamed from contrib/go/_std_1.20/src/mime/encodedword.go)0
-rw-r--r--contrib/go/_std_1.21/src/mime/grammar.go (renamed from contrib/go/_std_1.20/src/mime/grammar.go)0
-rw-r--r--contrib/go/_std_1.21/src/mime/mediatype.go (renamed from contrib/go/_std_1.20/src/mime/mediatype.go)0
-rw-r--r--contrib/go/_std_1.21/src/mime/multipart/formdata.go306
-rw-r--r--contrib/go/_std_1.21/src/mime/multipart/multipart.go488
-rw-r--r--contrib/go/_std_1.21/src/mime/multipart/readmimeheader.go (renamed from contrib/go/_std_1.20/src/mime/multipart/readmimeheader.go)0
-rw-r--r--contrib/go/_std_1.21/src/mime/multipart/writer.go (renamed from contrib/go/_std_1.20/src/mime/multipart/writer.go)0
-rw-r--r--contrib/go/_std_1.21/src/mime/multipart/ya.make21
-rw-r--r--contrib/go/_std_1.21/src/mime/quotedprintable/reader.go (renamed from contrib/go/_std_1.20/src/mime/quotedprintable/reader.go)0
-rw-r--r--contrib/go/_std_1.21/src/mime/quotedprintable/writer.go (renamed from contrib/go/_std_1.20/src/mime/quotedprintable/writer.go)0
-rw-r--r--contrib/go/_std_1.21/src/mime/quotedprintable/ya.make18
-rw-r--r--contrib/go/_std_1.21/src/mime/type.go (renamed from contrib/go/_std_1.20/src/mime/type.go)0
-rw-r--r--contrib/go/_std_1.21/src/mime/type_unix.go126
-rw-r--r--contrib/go/_std_1.21/src/mime/type_windows.go (renamed from contrib/go/_std_1.20/src/mime/type_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/mime/ya.make45
-rw-r--r--contrib/go/_std_1.21/src/net/addrselect.go (renamed from contrib/go/_std_1.20/src/net/addrselect.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/cgo_darwin.go (renamed from contrib/go/_std_1.20/src/net/cgo_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/cgo_linux.go (renamed from contrib/go/_std_1.20/src/net/cgo_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/cgo_resnew.go (renamed from contrib/go/_std_1.20/src/net/cgo_resnew.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/cgo_socknew.go (renamed from contrib/go/_std_1.20/src/net/cgo_socknew.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/cgo_unix.go370
-rw-r--r--contrib/go/_std_1.21/src/net/cgo_unix_cgo.go80
-rw-r--r--contrib/go/_std_1.21/src/net/cgo_unix_cgo_darwin.go21
-rw-r--r--contrib/go/_std_1.21/src/net/cgo_unix_cgo_res.go (renamed from contrib/go/_std_1.20/src/net/cgo_unix_cgo_res.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/cgo_unix_syscall.go102
-rw-r--r--contrib/go/_std_1.21/src/net/conf.go523
-rw-r--r--contrib/go/_std_1.21/src/net/dial.go837
-rw-r--r--contrib/go/_std_1.21/src/net/dnsclient.go (renamed from contrib/go/_std_1.20/src/net/dnsclient.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/dnsclient_unix.go879
-rw-r--r--contrib/go/_std_1.21/src/net/dnsconfig.go (renamed from contrib/go/_std_1.20/src/net/dnsconfig.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/dnsconfig_unix.go167
-rw-r--r--contrib/go/_std_1.21/src/net/dnsconfig_windows.go63
-rw-r--r--contrib/go/_std_1.21/src/net/error_posix.go21
-rw-r--r--contrib/go/_std_1.21/src/net/error_unix.go16
-rw-r--r--contrib/go/_std_1.21/src/net/error_windows.go (renamed from contrib/go/_std_1.20/src/net/error_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/fd_posix.go (renamed from contrib/go/_std_1.20/src/net/fd_posix.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/fd_unix.go206
-rw-r--r--contrib/go/_std_1.21/src/net/fd_windows.go205
-rw-r--r--contrib/go/_std_1.21/src/net/file.go (renamed from contrib/go/_std_1.20/src/net/file.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/file_unix.go (renamed from contrib/go/_std_1.20/src/net/file_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/file_windows.go (renamed from contrib/go/_std_1.20/src/net/file_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/hook.go (renamed from contrib/go/_std_1.20/src/net/hook.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/hook_unix.go20
-rw-r--r--contrib/go/_std_1.21/src/net/hook_windows.go (renamed from contrib/go/_std_1.20/src/net/hook_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/hosts.go165
-rw-r--r--contrib/go/_std_1.21/src/net/http/cgi/child.go (renamed from contrib/go/_std_1.20/src/net/http/cgi/child.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/cgi/host.go413
-rw-r--r--contrib/go/_std_1.21/src/net/http/cgi/ya.make18
-rw-r--r--contrib/go/_std_1.21/src/net/http/client.go1032
-rw-r--r--contrib/go/_std_1.21/src/net/http/clone.go (renamed from contrib/go/_std_1.20/src/net/http/clone.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/cookie.go (renamed from contrib/go/_std_1.20/src/net/http/cookie.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/cookiejar/jar.go540
-rw-r--r--contrib/go/_std_1.21/src/net/http/cookiejar/punycode.go (renamed from contrib/go/_std_1.20/src/net/http/cookiejar/punycode.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/cookiejar/ya.make21
-rw-r--r--contrib/go/_std_1.21/src/net/http/doc.go110
-rw-r--r--contrib/go/_std_1.21/src/net/http/fcgi/child.go (renamed from contrib/go/_std_1.20/src/net/http/fcgi/child.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/fcgi/fcgi.go277
-rw-r--r--contrib/go/_std_1.21/src/net/http/fcgi/ya.make13
-rw-r--r--contrib/go/_std_1.21/src/net/http/filetransport.go (renamed from contrib/go/_std_1.20/src/net/http/filetransport.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/fs.go (renamed from contrib/go/_std_1.20/src/net/http/fs.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/h2_bundle.go11492
-rw-r--r--contrib/go/_std_1.21/src/net/http/h2_error.go (renamed from contrib/go/_std_1.20/src/net/http/h2_error.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/header.go (renamed from contrib/go/_std_1.20/src/net/http/header.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/http.go165
-rw-r--r--contrib/go/_std_1.21/src/net/http/httptest/httptest.go (renamed from contrib/go/_std_1.20/src/net/http/httptest/httptest.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/httptest/recorder.go (renamed from contrib/go/_std_1.20/src/net/http/httptest/recorder.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/httptest/server.go (renamed from contrib/go/_std_1.20/src/net/http/httptest/server.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/httptest/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/net/http/httptrace/trace.go (renamed from contrib/go/_std_1.20/src/net/http/httptrace/trace.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/httptrace/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/net/http/httputil/dump.go (renamed from contrib/go/_std_1.20/src/net/http/httputil/dump.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/httputil/httputil.go (renamed from contrib/go/_std_1.20/src/net/http/httputil/httputil.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/httputil/persist.go (renamed from contrib/go/_std_1.20/src/net/http/httputil/persist.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/httputil/reverseproxy.go834
-rw-r--r--contrib/go/_std_1.21/src/net/http/httputil/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/net/http/internal/ascii/print.go (renamed from contrib/go/_std_1.20/src/net/http/internal/ascii/print.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/internal/ascii/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/net/http/internal/chunked.go (renamed from contrib/go/_std_1.20/src/net/http/internal/chunked.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/internal/testcert/testcert.go (renamed from contrib/go/_std_1.20/src/net/http/internal/testcert/testcert.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/internal/testcert/ya.make (renamed from contrib/go/_std_1.20/src/net/http/internal/testcert/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/internal/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/net/http/jar.go (renamed from contrib/go/_std_1.20/src/net/http/jar.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/method.go (renamed from contrib/go/_std_1.20/src/net/http/method.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/pprof/pprof.go464
-rw-r--r--contrib/go/_std_1.21/src/net/http/pprof/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/net/http/request.go1488
-rw-r--r--contrib/go/_std_1.21/src/net/http/response.go (renamed from contrib/go/_std_1.20/src/net/http/response.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/responsecontroller.go147
-rw-r--r--contrib/go/_std_1.21/src/net/http/roundtrip.go18
-rw-r--r--contrib/go/_std_1.21/src/net/http/server.go3645
-rw-r--r--contrib/go/_std_1.21/src/net/http/sniff.go (renamed from contrib/go/_std_1.20/src/net/http/sniff.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/socks_bundle.go473
-rw-r--r--contrib/go/_std_1.21/src/net/http/status.go (renamed from contrib/go/_std_1.20/src/net/http/status.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/http/transfer.go1124
-rw-r--r--contrib/go/_std_1.21/src/net/http/transport.go2942
-rw-r--r--contrib/go/_std_1.21/src/net/http/transport_default_other.go16
-rw-r--r--contrib/go/_std_1.21/src/net/http/ya.make74
-rw-r--r--contrib/go/_std_1.21/src/net/interface.go (renamed from contrib/go/_std_1.20/src/net/interface.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/interface_bsd.go (renamed from contrib/go/_std_1.20/src/net/interface_bsd.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/interface_darwin.go (renamed from contrib/go/_std_1.20/src/net/interface_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/interface_linux.go (renamed from contrib/go/_std_1.20/src/net/interface_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/interface_windows.go (renamed from contrib/go/_std_1.20/src/net/interface_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/internal/socktest/switch.go (renamed from contrib/go/_std_1.20/src/net/internal/socktest/switch.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/internal/socktest/switch_posix.go (renamed from contrib/go/_std_1.20/src/net/internal/socktest/switch_posix.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/internal/socktest/switch_unix.go29
-rw-r--r--contrib/go/_std_1.21/src/net/internal/socktest/switch_windows.go (renamed from contrib/go/_std_1.20/src/net/internal/socktest/switch_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/internal/socktest/sys_cloexec.go (renamed from contrib/go/_std_1.20/src/net/internal/socktest/sys_cloexec.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/internal/socktest/sys_unix.go193
-rw-r--r--contrib/go/_std_1.21/src/net/internal/socktest/sys_windows.go (renamed from contrib/go/_std_1.20/src/net/internal/socktest/sys_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/internal/socktest/ya.make41
-rw-r--r--contrib/go/_std_1.21/src/net/internal/ya.make (renamed from contrib/go/_std_1.20/src/net/internal/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/net/ip.go542
-rw-r--r--contrib/go/_std_1.21/src/net/iprawsock.go (renamed from contrib/go/_std_1.20/src/net/iprawsock.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/iprawsock_posix.go159
-rw-r--r--contrib/go/_std_1.21/src/net/ipsock.go (renamed from contrib/go/_std_1.20/src/net/ipsock.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/ipsock_posix.go232
-rw-r--r--contrib/go/_std_1.21/src/net/lookup.go908
-rw-r--r--contrib/go/_std_1.21/src/net/lookup_unix.go149
-rw-r--r--contrib/go/_std_1.21/src/net/lookup_windows.go455
-rw-r--r--contrib/go/_std_1.21/src/net/mac.go (renamed from contrib/go/_std_1.20/src/net/mac.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/mail/message.go911
-rw-r--r--contrib/go/_std_1.21/src/net/mail/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/net/mptcpsock_linux.go127
-rw-r--r--contrib/go/_std_1.21/src/net/mptcpsock_stub.go23
-rw-r--r--contrib/go/_std_1.21/src/net/net.go767
-rw-r--r--contrib/go/_std_1.21/src/net/netcgo_off.go9
-rw-r--r--contrib/go/_std_1.21/src/net/netgo_off.go9
-rw-r--r--contrib/go/_std_1.21/src/net/netip/leaf_alts.go (renamed from contrib/go/_std_1.20/src/net/netip/leaf_alts.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/netip/netip.go1481
-rw-r--r--contrib/go/_std_1.21/src/net/netip/uint128.go (renamed from contrib/go/_std_1.20/src/net/netip/uint128.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/netip/ya.make25
-rw-r--r--contrib/go/_std_1.21/src/net/nss.go (renamed from contrib/go/_std_1.20/src/net/nss.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/parse.go (renamed from contrib/go/_std_1.20/src/net/parse.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/pipe.go (renamed from contrib/go/_std_1.20/src/net/pipe.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/port.go (renamed from contrib/go/_std_1.20/src/net/port.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/port_unix.go57
-rw-r--r--contrib/go/_std_1.21/src/net/rawconn.go96
-rw-r--r--contrib/go/_std_1.21/src/net/rpc/client.go (renamed from contrib/go/_std_1.20/src/net/rpc/client.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/rpc/debug.go (renamed from contrib/go/_std_1.20/src/net/rpc/debug.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/rpc/jsonrpc/client.go (renamed from contrib/go/_std_1.20/src/net/rpc/jsonrpc/client.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/rpc/jsonrpc/server.go (renamed from contrib/go/_std_1.20/src/net/rpc/jsonrpc/server.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/rpc/jsonrpc/ya.make13
-rw-r--r--contrib/go/_std_1.21/src/net/rpc/server.go725
-rw-r--r--contrib/go/_std_1.21/src/net/rpc/ya.make18
-rw-r--r--contrib/go/_std_1.21/src/net/sendfile_linux.go53
-rw-r--r--contrib/go/_std_1.21/src/net/sendfile_unix_alt.go (renamed from contrib/go/_std_1.20/src/net/sendfile_unix_alt.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sendfile_windows.go (renamed from contrib/go/_std_1.20/src/net/sendfile_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/smtp/auth.go (renamed from contrib/go/_std_1.20/src/net/smtp/auth.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/smtp/smtp.go (renamed from contrib/go/_std_1.20/src/net/smtp/smtp.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/smtp/ya.make15
-rw-r--r--contrib/go/_std_1.21/src/net/sock_bsd.go (renamed from contrib/go/_std_1.20/src/net/sock_bsd.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sock_cloexec.go48
-rw-r--r--contrib/go/_std_1.21/src/net/sock_linux.go (renamed from contrib/go/_std_1.20/src/net/sock_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sock_posix.go (renamed from contrib/go/_std_1.20/src/net/sock_posix.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sock_windows.go (renamed from contrib/go/_std_1.20/src/net/sock_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sockaddr_posix.go34
-rw-r--r--contrib/go/_std_1.21/src/net/sockopt_bsd.go (renamed from contrib/go/_std_1.20/src/net/sockopt_bsd.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sockopt_linux.go (renamed from contrib/go/_std_1.20/src/net/sockopt_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sockopt_posix.go (renamed from contrib/go/_std_1.20/src/net/sockopt_posix.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sockopt_windows.go (renamed from contrib/go/_std_1.20/src/net/sockopt_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sockoptip_bsdvar.go (renamed from contrib/go/_std_1.20/src/net/sockoptip_bsdvar.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sockoptip_linux.go (renamed from contrib/go/_std_1.20/src/net/sockoptip_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sockoptip_posix.go (renamed from contrib/go/_std_1.20/src/net/sockoptip_posix.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sockoptip_windows.go (renamed from contrib/go/_std_1.20/src/net/sockoptip_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/splice_linux.go44
-rw-r--r--contrib/go/_std_1.21/src/net/splice_stub.go (renamed from contrib/go/_std_1.20/src/net/splice_stub.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/sys_cloexec.go (renamed from contrib/go/_std_1.20/src/net/sys_cloexec.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/tcpsock.go398
-rw-r--r--contrib/go/_std_1.21/src/net/tcpsock_posix.go187
-rw-r--r--contrib/go/_std_1.21/src/net/tcpsockopt_darwin.go (renamed from contrib/go/_std_1.20/src/net/tcpsockopt_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/tcpsockopt_posix.go (renamed from contrib/go/_std_1.20/src/net/tcpsockopt_posix.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/tcpsockopt_unix.go (renamed from contrib/go/_std_1.20/src/net/tcpsockopt_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/tcpsockopt_windows.go (renamed from contrib/go/_std_1.20/src/net/tcpsockopt_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/textproto/header.go (renamed from contrib/go/_std_1.20/src/net/textproto/header.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/textproto/pipeline.go (renamed from contrib/go/_std_1.20/src/net/textproto/pipeline.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/textproto/reader.go (renamed from contrib/go/_std_1.20/src/net/textproto/reader.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/textproto/textproto.go (renamed from contrib/go/_std_1.20/src/net/textproto/textproto.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/textproto/writer.go (renamed from contrib/go/_std_1.20/src/net/textproto/writer.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/textproto/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/net/udpsock.go (renamed from contrib/go/_std_1.20/src/net/udpsock.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/udpsock_posix.go287
-rw-r--r--contrib/go/_std_1.21/src/net/unixsock.go352
-rw-r--r--contrib/go/_std_1.21/src/net/unixsock_posix.go245
-rw-r--r--contrib/go/_std_1.21/src/net/unixsock_readmsg_cloexec.go (renamed from contrib/go/_std_1.20/src/net/unixsock_readmsg_cloexec.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/unixsock_readmsg_cmsg_cloexec.go (renamed from contrib/go/_std_1.20/src/net/unixsock_readmsg_cmsg_cloexec.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/unixsock_readmsg_other.go11
-rw-r--r--contrib/go/_std_1.21/src/net/url/url.go1265
-rw-r--r--contrib/go/_std_1.21/src/net/url/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/net/writev_unix.go (renamed from contrib/go/_std_1.20/src/net/writev_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/net/ya.make254
-rw-r--r--contrib/go/_std_1.21/src/os/dir.go (renamed from contrib/go/_std_1.20/src/os/dir.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/dir_darwin.go140
-rw-r--r--contrib/go/_std_1.21/src/os/dir_unix.go198
-rw-r--r--contrib/go/_std_1.21/src/os/dir_windows.go80
-rw-r--r--contrib/go/_std_1.21/src/os/dirent_linux.go (renamed from contrib/go/_std_1.20/src/os/dirent_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/endian_little.go (renamed from contrib/go/_std_1.20/src/os/endian_little.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/env.go (renamed from contrib/go/_std_1.20/src/os/env.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/error.go141
-rw-r--r--contrib/go/_std_1.21/src/os/error_errno.go (renamed from contrib/go/_std_1.20/src/os/error_errno.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/error_posix.go18
-rw-r--r--contrib/go/_std_1.21/src/os/exec.go180
-rw-r--r--contrib/go/_std_1.21/src/os/exec/exec.go1303
-rw-r--r--contrib/go/_std_1.21/src/os/exec/exec_unix.go (renamed from contrib/go/_std_1.20/src/os/exec/exec_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/exec/exec_windows.go (renamed from contrib/go/_std_1.20/src/os/exec/exec_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/exec/internal/fdtest/exists_unix.go19
-rw-r--r--contrib/go/_std_1.21/src/os/exec/internal/fdtest/exists_windows.go (renamed from contrib/go/_std_1.20/src/os/exec/internal/fdtest/exists_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/exec/internal/fdtest/ya.make26
-rw-r--r--contrib/go/_std_1.21/src/os/exec/internal/ya.make (renamed from contrib/go/_std_1.20/src/os/exec/internal/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/os/exec/lp_unix.go82
-rw-r--r--contrib/go/_std_1.21/src/os/exec/lp_windows.go145
-rw-r--r--contrib/go/_std_1.21/src/os/exec/ya.make66
-rw-r--r--contrib/go/_std_1.21/src/os/exec_posix.go136
-rw-r--r--contrib/go/_std_1.21/src/os/exec_unix.go106
-rw-r--r--contrib/go/_std_1.21/src/os/exec_windows.go (renamed from contrib/go/_std_1.20/src/os/exec_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/executable.go (renamed from contrib/go/_std_1.20/src/os/executable.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/executable_darwin.go (renamed from contrib/go/_std_1.20/src/os/executable_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/executable_procfs.go37
-rw-r--r--contrib/go/_std_1.21/src/os/executable_windows.go (renamed from contrib/go/_std_1.20/src/os/executable_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/file.go770
-rw-r--r--contrib/go/_std_1.21/src/os/file_open_unix.go17
-rw-r--r--contrib/go/_std_1.21/src/os/file_posix.go256
-rw-r--r--contrib/go/_std_1.21/src/os/file_unix.go498
-rw-r--r--contrib/go/_std_1.21/src/os/file_windows.go524
-rw-r--r--contrib/go/_std_1.21/src/os/getwd.go (renamed from contrib/go/_std_1.20/src/os/getwd.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/path.go (renamed from contrib/go/_std_1.20/src/os/path.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/path_unix.go75
-rw-r--r--contrib/go/_std_1.21/src/os/path_windows.go (renamed from contrib/go/_std_1.20/src/os/path_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/pipe2_unix.go22
-rw-r--r--contrib/go/_std_1.21/src/os/pipe_unix.go28
-rw-r--r--contrib/go/_std_1.21/src/os/proc.go (renamed from contrib/go/_std_1.20/src/os/proc.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/rawconn.go (renamed from contrib/go/_std_1.20/src/os/rawconn.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/readfrom_linux.go124
-rw-r--r--contrib/go/_std_1.21/src/os/readfrom_stub.go (renamed from contrib/go/_std_1.20/src/os/readfrom_stub.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/removeall_at.go199
-rw-r--r--contrib/go/_std_1.21/src/os/removeall_noat.go (renamed from contrib/go/_std_1.20/src/os/removeall_noat.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/rlimit.go (renamed from contrib/go/_std_1.20/src/os/rlimit.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/rlimit_darwin.go (renamed from contrib/go/_std_1.20/src/os/rlimit_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/rlimit_stub.go (renamed from contrib/go/_std_1.20/src/os/rlimit_stub.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/signal/doc.go232
-rw-r--r--contrib/go/_std_1.21/src/os/signal/sig.s (renamed from contrib/go/_std_1.20/src/os/signal/sig.s)0
-rw-r--r--contrib/go/_std_1.21/src/os/signal/signal.go (renamed from contrib/go/_std_1.20/src/os/signal/signal.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/signal/signal_unix.go62
-rw-r--r--contrib/go/_std_1.21/src/os/signal/ya.make40
-rw-r--r--contrib/go/_std_1.21/src/os/stat.go (renamed from contrib/go/_std_1.20/src/os/stat.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/stat_darwin.go (renamed from contrib/go/_std_1.20/src/os/stat_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/stat_linux.go (renamed from contrib/go/_std_1.20/src/os/stat_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/stat_unix.go52
-rw-r--r--contrib/go/_std_1.21/src/os/stat_windows.go136
-rw-r--r--contrib/go/_std_1.21/src/os/sticky_bsd.go11
-rw-r--r--contrib/go/_std_1.21/src/os/sticky_notbsd.go9
-rw-r--r--contrib/go/_std_1.21/src/os/str.go (renamed from contrib/go/_std_1.20/src/os/str.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/sys.go (renamed from contrib/go/_std_1.20/src/os/sys.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/sys_bsd.go17
-rw-r--r--contrib/go/_std_1.21/src/os/sys_linux.go (renamed from contrib/go/_std_1.20/src/os/sys_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/sys_unix.go (renamed from contrib/go/_std_1.20/src/os/sys_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/sys_windows.go (renamed from contrib/go/_std_1.20/src/os/sys_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/tempfile.go128
-rw-r--r--contrib/go/_std_1.21/src/os/types.go (renamed from contrib/go/_std_1.20/src/os/types.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/types_unix.go (renamed from contrib/go/_std_1.20/src/os/types_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/types_windows.go246
-rw-r--r--contrib/go/_std_1.21/src/os/user/cgo_listgroups_unix.go (renamed from contrib/go/_std_1.20/src/os/user/cgo_listgroups_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/user/cgo_lookup_cgo.go (renamed from contrib/go/_std_1.20/src/os/user/cgo_lookup_cgo.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/user/cgo_lookup_syscall.go (renamed from contrib/go/_std_1.20/src/os/user/cgo_lookup_syscall.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/user/cgo_lookup_unix.go (renamed from contrib/go/_std_1.20/src/os/user/cgo_lookup_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/user/getgrouplist_syscall.go (renamed from contrib/go/_std_1.20/src/os/user/getgrouplist_syscall.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/user/getgrouplist_unix.go (renamed from contrib/go/_std_1.20/src/os/user/getgrouplist_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/user/lookup.go (renamed from contrib/go/_std_1.20/src/os/user/lookup.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/user/lookup_windows.go (renamed from contrib/go/_std_1.20/src/os/user/lookup_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/user/user.go (renamed from contrib/go/_std_1.20/src/os/user/user.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/user/ya.make (renamed from contrib/go/_std_1.20/src/os/user/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/os/wait_unimp.go21
-rw-r--r--contrib/go/_std_1.21/src/os/wait_waitid.go (renamed from contrib/go/_std_1.20/src/os/wait_waitid.go)0
-rw-r--r--contrib/go/_std_1.21/src/os/ya.make147
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/match.go (renamed from contrib/go/_std_1.20/src/path/filepath/match.go)0
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/path.go682
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/path_unix.go57
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/path_windows.go (renamed from contrib/go/_std_1.20/src/path/filepath/path_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/symlink.go149
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/symlink_unix.go (renamed from contrib/go/_std_1.20/src/path/filepath/symlink_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/symlink_windows.go118
-rw-r--r--contrib/go/_std_1.21/src/path/filepath/ya.make55
-rw-r--r--contrib/go/_std_1.21/src/path/match.go (renamed from contrib/go/_std_1.20/src/path/match.go)0
-rw-r--r--contrib/go/_std_1.21/src/path/path.go (renamed from contrib/go/_std_1.20/src/path/path.go)0
-rw-r--r--contrib/go/_std_1.21/src/path/ya.make18
-rw-r--r--contrib/go/_std_1.21/src/reflect/abi.go510
-rw-r--r--contrib/go/_std_1.21/src/reflect/asm_amd64.s (renamed from contrib/go/_std_1.20/src/reflect/asm_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/reflect/asm_arm64.s (renamed from contrib/go/_std_1.20/src/reflect/asm_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/reflect/deepequal.go238
-rw-r--r--contrib/go/_std_1.21/src/reflect/float32reg_generic.go (renamed from contrib/go/_std_1.20/src/reflect/float32reg_generic.go)0
-rw-r--r--contrib/go/_std_1.21/src/reflect/internal/example1/example.go (renamed from contrib/go/_std_1.20/src/reflect/internal/example1/example.go)0
-rw-r--r--contrib/go/_std_1.21/src/reflect/internal/example1/ya.make (renamed from contrib/go/_std_1.20/src/reflect/internal/example1/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/reflect/internal/example2/example.go (renamed from contrib/go/_std_1.20/src/reflect/internal/example2/example.go)0
-rw-r--r--contrib/go/_std_1.21/src/reflect/internal/example2/ya.make (renamed from contrib/go/_std_1.20/src/reflect/internal/example2/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/reflect/internal/ya.make (renamed from contrib/go/_std_1.20/src/reflect/internal/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/reflect/makefunc.go176
-rw-r--r--contrib/go/_std_1.21/src/reflect/swapper.go79
-rw-r--r--contrib/go/_std_1.21/src/reflect/type.go2911
-rw-r--r--contrib/go/_std_1.21/src/reflect/value.go3962
-rw-r--r--contrib/go/_std_1.21/src/reflect/visiblefields.go (renamed from contrib/go/_std_1.20/src/reflect/visiblefields.go)0
-rw-r--r--contrib/go/_std_1.21/src/reflect/ya.make43
-rw-r--r--contrib/go/_std_1.21/src/regexp/backtrack.go (renamed from contrib/go/_std_1.20/src/regexp/backtrack.go)0
-rw-r--r--contrib/go/_std_1.21/src/regexp/exec.go (renamed from contrib/go/_std_1.20/src/regexp/exec.go)0
-rw-r--r--contrib/go/_std_1.21/src/regexp/onepass.go (renamed from contrib/go/_std_1.20/src/regexp/onepass.go)0
-rw-r--r--contrib/go/_std_1.21/src/regexp/regexp.go1306
-rw-r--r--contrib/go/_std_1.21/src/regexp/syntax/compile.go (renamed from contrib/go/_std_1.20/src/regexp/syntax/compile.go)0
-rw-r--r--contrib/go/_std_1.21/src/regexp/syntax/doc.go (renamed from contrib/go/_std_1.20/src/regexp/syntax/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/regexp/syntax/op_string.go52
-rw-r--r--contrib/go/_std_1.21/src/regexp/syntax/parse.go (renamed from contrib/go/_std_1.20/src/regexp/syntax/parse.go)0
-rw-r--r--contrib/go/_std_1.21/src/regexp/syntax/perl_groups.go (renamed from contrib/go/_std_1.20/src/regexp/syntax/perl_groups.go)0
-rw-r--r--contrib/go/_std_1.21/src/regexp/syntax/prog.go349
-rw-r--r--contrib/go/_std_1.21/src/regexp/syntax/regexp.go (renamed from contrib/go/_std_1.20/src/regexp/syntax/regexp.go)0
-rw-r--r--contrib/go/_std_1.21/src/regexp/syntax/simplify.go (renamed from contrib/go/_std_1.20/src/regexp/syntax/simplify.go)0
-rw-r--r--contrib/go/_std_1.21/src/regexp/syntax/ya.make23
-rw-r--r--contrib/go/_std_1.21/src/regexp/ya.make24
-rw-r--r--contrib/go/_std_1.21/src/runtime/alg.go354
-rw-r--r--contrib/go/_std_1.21/src/runtime/arena.go1003
-rw-r--r--contrib/go/_std_1.21/src/runtime/asan0.go (renamed from contrib/go/_std_1.20/src/runtime/asan0.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/asm.s14
-rw-r--r--contrib/go/_std_1.21/src/runtime/asm_amd64.h (renamed from contrib/go/_std_1.20/src/runtime/asm_amd64.h)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/asm_amd64.s2093
-rw-r--r--contrib/go/_std_1.21/src/runtime/asm_arm64.s1573
-rw-r--r--contrib/go/_std_1.21/src/runtime/atomic_arm64.s (renamed from contrib/go/_std_1.20/src/runtime/atomic_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/atomic_pointer.go114
-rw-r--r--contrib/go/_std_1.21/src/runtime/auxv_none.go (renamed from contrib/go/_std_1.20/src/runtime/auxv_none.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo.go63
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/abi_amd64.h (renamed from contrib/go/_std_1.20/src/runtime/cgo/abi_amd64.h)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/abi_arm64.h (renamed from contrib/go/_std_1.20/src/runtime/cgo/abi_arm64.h)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s42
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s45
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/callbacks.go152
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/callbacks_traceback.go (renamed from contrib/go/_std_1.20/src/runtime/cgo/callbacks_traceback.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/cgo.go40
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_amd64.S (renamed from contrib/go/_std_1.20/src/runtime/cgo/gcc_amd64.S)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_arm64.S (renamed from contrib/go/_std_1.20/src/runtime/cgo/gcc_arm64.S)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_context.c20
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_darwin_amd64.c (renamed from contrib/go/_std_1.20/src/runtime/cgo/gcc_darwin_amd64.c)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_fatalf.c23
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_libinit.c147
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_linux_amd64.c (renamed from contrib/go/_std_1.20/src/runtime/cgo/gcc_linux_amd64.c)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_linux_arm64.c (renamed from contrib/go/_std_1.20/src/runtime/cgo/gcc_linux_arm64.c)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_mmap.c39
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_setenv.c27
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_sigaction.c82
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_stack_darwin.c20
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_stack_unix.c40
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_traceback.c46
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/gcc_util.c (renamed from contrib/go/_std_1.20/src/runtime/cgo/gcc_util.c)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/handle.go144
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/iscgo.go (renamed from contrib/go/_std_1.20/src/runtime/cgo/iscgo.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/libcgo.h156
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/libcgo_unix.h (renamed from contrib/go/_std_1.20/src/runtime/cgo/libcgo_unix.h)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/linux.go (renamed from contrib/go/_std_1.20/src/runtime/cgo/linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/linux_syscall.c85
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/mmap.go (renamed from contrib/go/_std_1.20/src/runtime/cgo/mmap.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/setenv.go (renamed from contrib/go/_std_1.20/src/runtime/cgo/setenv.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/sigaction.go (renamed from contrib/go/_std_1.20/src/runtime/cgo/sigaction.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo/ya.make128
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo_mmap.go (renamed from contrib/go/_std_1.20/src/runtime/cgo_mmap.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgo_sigaction.go (renamed from contrib/go/_std_1.20/src/runtime/cgo_sigaction.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgocall.go657
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgocallback.go (renamed from contrib/go/_std_1.20/src/runtime/cgocallback.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cgocheck.go292
-rw-r--r--contrib/go/_std_1.21/src/runtime/chan.go851
-rw-r--r--contrib/go/_std_1.21/src/runtime/checkptr.go109
-rw-r--r--contrib/go/_std_1.21/src/runtime/compiler.go (renamed from contrib/go/_std_1.20/src/runtime/compiler.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/complex.go (renamed from contrib/go/_std_1.20/src/runtime/complex.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/coverage/apis.go184
-rw-r--r--contrib/go/_std_1.21/src/runtime/coverage/dummy.s (renamed from contrib/go/_std_1.20/src/runtime/coverage/dummy.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/coverage/emit.go622
-rw-r--r--contrib/go/_std_1.21/src/runtime/coverage/hooks.go (renamed from contrib/go/_std_1.20/src/runtime/coverage/hooks.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/coverage/testsupport.go323
-rw-r--r--contrib/go/_std_1.21/src/runtime/coverage/ya.make19
-rw-r--r--contrib/go/_std_1.21/src/runtime/covercounter.go (renamed from contrib/go/_std_1.20/src/runtime/covercounter.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/covermeta.go (renamed from contrib/go/_std_1.20/src/runtime/covermeta.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cpuflags.go (renamed from contrib/go/_std_1.20/src/runtime/cpuflags.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cpuflags_amd64.go (renamed from contrib/go/_std_1.20/src/runtime/cpuflags_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/cpuflags_arm64.go17
-rw-r--r--contrib/go/_std_1.21/src/runtime/cpuprof.go241
-rw-r--r--contrib/go/_std_1.21/src/runtime/cputicks.go11
-rw-r--r--contrib/go/_std_1.21/src/runtime/create_file_nounix.go (renamed from contrib/go/_std_1.20/src/runtime/create_file_nounix.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/create_file_unix.go (renamed from contrib/go/_std_1.20/src/runtime/create_file_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/debug.go115
-rw-r--r--contrib/go/_std_1.21/src/runtime/debug/debug.s (renamed from contrib/go/_std_1.20/src/runtime/debug/debug.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/debug/garbage.go (renamed from contrib/go/_std_1.20/src/runtime/debug/garbage.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/debug/mod.go287
-rw-r--r--contrib/go/_std_1.21/src/runtime/debug/stack.go (renamed from contrib/go/_std_1.20/src/runtime/debug/stack.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/debug/stubs.go (renamed from contrib/go/_std_1.20/src/runtime/debug/stubs.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/debug/ya.make29
-rw-r--r--contrib/go/_std_1.21/src/runtime/debugcall.go257
-rw-r--r--contrib/go/_std_1.21/src/runtime/debuglog.go831
-rw-r--r--contrib/go/_std_1.21/src/runtime/debuglog_off.go (renamed from contrib/go/_std_1.20/src/runtime/debuglog_off.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/defs_darwin_amd64.go373
-rw-r--r--contrib/go/_std_1.21/src/runtime/defs_linux_amd64.go289
-rw-r--r--contrib/go/_std_1.21/src/runtime/defs_linux_arm64.go211
-rw-r--r--contrib/go/_std_1.21/src/runtime/defs_windows.go90
-rw-r--r--contrib/go/_std_1.21/src/runtime/defs_windows_amd64.go100
-rw-r--r--contrib/go/_std_1.21/src/runtime/duff_amd64.s427
-rw-r--r--contrib/go/_std_1.21/src/runtime/duff_arm64.s (renamed from contrib/go/_std_1.20/src/runtime/duff_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/env_posix.go (renamed from contrib/go/_std_1.20/src/runtime/env_posix.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/error.go330
-rw-r--r--contrib/go/_std_1.21/src/runtime/exithook.go69
-rw-r--r--contrib/go/_std_1.21/src/runtime/extern.go341
-rw-r--r--contrib/go/_std_1.21/src/runtime/fastlog2.go (renamed from contrib/go/_std_1.20/src/runtime/fastlog2.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/fastlog2table.go (renamed from contrib/go/_std_1.20/src/runtime/fastlog2table.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/float.go (renamed from contrib/go/_std_1.20/src/runtime/float.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/funcdata.h56
-rw-r--r--contrib/go/_std_1.21/src/runtime/go_tls.h (renamed from contrib/go/_std_1.20/src/runtime/go_tls.h)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/hash64.go (renamed from contrib/go/_std_1.20/src/runtime/hash64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/heapdump.go752
-rw-r--r--contrib/go/_std_1.21/src/runtime/histogram.go (renamed from contrib/go/_std_1.20/src/runtime/histogram.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/iface.go534
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/atomic/atomic_amd64.go (renamed from contrib/go/_std_1.20/src/runtime/internal/atomic/atomic_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/atomic/atomic_amd64.s (renamed from contrib/go/_std_1.20/src/runtime/internal/atomic/atomic_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/atomic/atomic_arm64.go (renamed from contrib/go/_std_1.20/src/runtime/internal/atomic/atomic_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/atomic/atomic_arm64.s (renamed from contrib/go/_std_1.20/src/runtime/internal/atomic/atomic_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/atomic/doc.go (renamed from contrib/go/_std_1.20/src/runtime/internal/atomic/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/atomic/stubs.go (renamed from contrib/go/_std_1.20/src/runtime/internal/atomic/stubs.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/atomic/types.go (renamed from contrib/go/_std_1.20/src/runtime/internal/atomic/types.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/atomic/types_64bit.go (renamed from contrib/go/_std_1.20/src/runtime/internal/atomic/types_64bit.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/atomic/unaligned.go (renamed from contrib/go/_std_1.20/src/runtime/internal/atomic/unaligned.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/atomic/ya.make33
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/math/math.go (renamed from contrib/go/_std_1.20/src/runtime/internal/math/math.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/math/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/startlinetest/func_amd64.go (renamed from contrib/go/_std_1.20/src/runtime/internal/startlinetest/func_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/startlinetest/func_amd64.s (renamed from contrib/go/_std_1.20/src/runtime/internal/startlinetest/func_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/startlinetest/ya.make (renamed from contrib/go/_std_1.20/src/runtime/internal/startlinetest/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/sys/consts.go (renamed from contrib/go/_std_1.20/src/runtime/internal/sys/consts.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/sys/consts_norace.go (renamed from contrib/go/_std_1.20/src/runtime/internal/sys/consts_norace.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/sys/intrinsics.go208
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/sys/nih.go (renamed from contrib/go/_std_1.20/src/runtime/internal/sys/nih.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/sys/sys.go (renamed from contrib/go/_std_1.20/src/runtime/internal/sys/sys.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/sys/ya.make17
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/sys/zversion.go (renamed from contrib/go/_std_1.20/src/runtime/internal/sys/zversion.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/syscall/asm_linux_amd64.s (renamed from contrib/go/_std_1.20/src/runtime/internal/syscall/asm_linux_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/syscall/asm_linux_arm64.s (renamed from contrib/go/_std_1.20/src/runtime/internal/syscall/asm_linux_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/syscall/defs_linux_amd64.go (renamed from contrib/go/_std_1.20/src/runtime/internal/syscall/defs_linux_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/syscall/defs_linux_arm64.go (renamed from contrib/go/_std_1.20/src/runtime/internal/syscall/defs_linux_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/syscall/syscall_linux.go62
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/syscall/ya.make33
-rw-r--r--contrib/go/_std_1.21/src/runtime/internal/ya.make18
-rw-r--r--contrib/go/_std_1.21/src/runtime/lfstack.go77
-rw-r--r--contrib/go/_std_1.21/src/runtime/lock_futex.go (renamed from contrib/go/_std_1.20/src/runtime/lock_futex.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/lock_sema.go (renamed from contrib/go/_std_1.20/src/runtime/lock_sema.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/lockrank.go187
-rw-r--r--contrib/go/_std_1.21/src/runtime/lockrank_off.go68
-rw-r--r--contrib/go/_std_1.21/src/runtime/malloc.go1632
-rw-r--r--contrib/go/_std_1.21/src/runtime/map.go1724
-rw-r--r--contrib/go/_std_1.21/src/runtime/map_fast32.go462
-rw-r--r--contrib/go/_std_1.21/src/runtime/map_fast64.go470
-rw-r--r--contrib/go/_std_1.21/src/runtime/map_faststr.go485
-rw-r--r--contrib/go/_std_1.21/src/runtime/mbarrier.go347
-rw-r--r--contrib/go/_std_1.21/src/runtime/mbitmap.go1501
-rw-r--r--contrib/go/_std_1.21/src/runtime/mcache.go (renamed from contrib/go/_std_1.20/src/runtime/mcache.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/mcentral.go257
-rw-r--r--contrib/go/_std_1.21/src/runtime/mcheckmark.go (renamed from contrib/go/_std_1.20/src/runtime/mcheckmark.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/mem.go156
-rw-r--r--contrib/go/_std_1.21/src/runtime/mem_darwin.go76
-rw-r--r--contrib/go/_std_1.21/src/runtime/mem_linux.go173
-rw-r--r--contrib/go/_std_1.21/src/runtime/mem_windows.go134
-rw-r--r--contrib/go/_std_1.21/src/runtime/memclr_amd64.s (renamed from contrib/go/_std_1.20/src/runtime/memclr_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/memclr_arm64.s (renamed from contrib/go/_std_1.20/src/runtime/memclr_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/memmove_amd64.s (renamed from contrib/go/_std_1.20/src/runtime/memmove_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/memmove_arm64.s (renamed from contrib/go/_std_1.20/src/runtime/memmove_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/metrics.go855
-rw-r--r--contrib/go/_std_1.21/src/runtime/metrics/description.go453
-rw-r--r--contrib/go/_std_1.21/src/runtime/metrics/doc.go400
-rw-r--r--contrib/go/_std_1.21/src/runtime/metrics/histogram.go (renamed from contrib/go/_std_1.20/src/runtime/metrics/histogram.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/metrics/sample.go (renamed from contrib/go/_std_1.20/src/runtime/metrics/sample.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/metrics/value.go (renamed from contrib/go/_std_1.20/src/runtime/metrics/value.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/metrics/ya.make19
-rw-r--r--contrib/go/_std_1.21/src/runtime/mfinal.go525
-rw-r--r--contrib/go/_std_1.21/src/runtime/mfixalloc.go111
-rw-r--r--contrib/go/_std_1.21/src/runtime/mgc.go1816
-rw-r--r--contrib/go/_std_1.21/src/runtime/mgclimit.go484
-rw-r--r--contrib/go/_std_1.21/src/runtime/mgcmark.go1598
-rw-r--r--contrib/go/_std_1.21/src/runtime/mgcpacer.go1445
-rw-r--r--contrib/go/_std_1.21/src/runtime/mgcscavenge.go1473
-rw-r--r--contrib/go/_std_1.21/src/runtime/mgcstack.go (renamed from contrib/go/_std_1.20/src/runtime/mgcstack.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/mgcsweep.go982
-rw-r--r--contrib/go/_std_1.21/src/runtime/mgcwork.go (renamed from contrib/go/_std_1.20/src/runtime/mgcwork.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/mheap.go2260
-rw-r--r--contrib/go/_std_1.21/src/runtime/minmax.go72
-rw-r--r--contrib/go/_std_1.21/src/runtime/mpagealloc.go1077
-rw-r--r--contrib/go/_std_1.21/src/runtime/mpagealloc_64bit.go258
-rw-r--r--contrib/go/_std_1.21/src/runtime/mpagecache.go183
-rw-r--r--contrib/go/_std_1.21/src/runtime/mpallocbits.go446
-rw-r--r--contrib/go/_std_1.21/src/runtime/mprof.go1278
-rw-r--r--contrib/go/_std_1.21/src/runtime/mranges.go (renamed from contrib/go/_std_1.20/src/runtime/mranges.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/msan0.go (renamed from contrib/go/_std_1.20/src/runtime/msan0.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/msize.go (renamed from contrib/go/_std_1.20/src/runtime/msize.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/mspanset.go404
-rw-r--r--contrib/go/_std_1.21/src/runtime/mstats.go969
-rw-r--r--contrib/go/_std_1.21/src/runtime/mwbbuf.go270
-rw-r--r--contrib/go/_std_1.21/src/runtime/nbpipe_pipe.go (renamed from contrib/go/_std_1.20/src/runtime/nbpipe_pipe.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/nbpipe_pipe2.go (renamed from contrib/go/_std_1.20/src/runtime/nbpipe_pipe2.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/netpoll.go694
-rw-r--r--contrib/go/_std_1.21/src/runtime/netpoll_epoll.go172
-rw-r--r--contrib/go/_std_1.21/src/runtime/netpoll_kqueue.go215
-rw-r--r--contrib/go/_std_1.21/src/runtime/netpoll_windows.go160
-rw-r--r--contrib/go/_std_1.21/src/runtime/nonwindows_stub.go21
-rw-r--r--contrib/go/_std_1.21/src/runtime/os_darwin.go476
-rw-r--r--contrib/go/_std_1.21/src/runtime/os_linux.go918
-rw-r--r--contrib/go/_std_1.21/src/runtime/os_linux_arm64.go (renamed from contrib/go/_std_1.20/src/runtime/os_linux_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/os_linux_generic.go (renamed from contrib/go/_std_1.20/src/runtime/os_linux_generic.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/os_linux_noauxv.go (renamed from contrib/go/_std_1.20/src/runtime/os_linux_noauxv.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/os_linux_x86.go (renamed from contrib/go/_std_1.20/src/runtime/os_linux_x86.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/os_nonopenbsd.go (renamed from contrib/go/_std_1.20/src/runtime/os_nonopenbsd.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/os_unix.go19
-rw-r--r--contrib/go/_std_1.21/src/runtime/os_unix_nonlinux.go (renamed from contrib/go/_std_1.20/src/runtime/os_unix_nonlinux.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/os_windows.go1445
-rw-r--r--contrib/go/_std_1.21/src/runtime/pagetrace_off.go (renamed from contrib/go/_std_1.20/src/runtime/pagetrace_off.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/panic.go1419
-rw-r--r--contrib/go/_std_1.21/src/runtime/pinner.go380
-rw-r--r--contrib/go/_std_1.21/src/runtime/plugin.go137
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/elf.go (renamed from contrib/go/_std_1.20/src/runtime/pprof/elf.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/label.go (renamed from contrib/go/_std_1.20/src/runtime/pprof/label.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/map.go (renamed from contrib/go/_std_1.20/src/runtime/pprof/map.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/pe.go (renamed from contrib/go/_std_1.20/src/runtime/pprof/pe.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/pprof.go (renamed from contrib/go/_std_1.20/src/runtime/pprof/pprof.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/pprof_rusage.go (renamed from contrib/go/_std_1.20/src/runtime/pprof/pprof_rusage.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/pprof_windows.go (renamed from contrib/go/_std_1.20/src/runtime/pprof/pprof_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/proto.go761
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/proto_other.go (renamed from contrib/go/_std_1.20/src/runtime/pprof/proto_other.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/proto_windows.go (renamed from contrib/go/_std_1.20/src/runtime/pprof/proto_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/protobuf.go (renamed from contrib/go/_std_1.20/src/runtime/pprof/protobuf.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/protomem.go (renamed from contrib/go/_std_1.20/src/runtime/pprof/protomem.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/runtime.go52
-rw-r--r--contrib/go/_std_1.21/src/runtime/pprof/ya.make52
-rw-r--r--contrib/go/_std_1.21/src/runtime/preempt.go447
-rw-r--r--contrib/go/_std_1.21/src/runtime/preempt_amd64.s (renamed from contrib/go/_std_1.20/src/runtime/preempt_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/preempt_arm64.s (renamed from contrib/go/_std_1.20/src/runtime/preempt_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/preempt_nonwindows.go (renamed from contrib/go/_std_1.20/src/runtime/preempt_nonwindows.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/print.go301
-rw-r--r--contrib/go/_std_1.21/src/runtime/proc.go6762
-rw-r--r--contrib/go/_std_1.21/src/runtime/profbuf.go561
-rw-r--r--contrib/go/_std_1.21/src/runtime/proflabel.go (renamed from contrib/go/_std_1.20/src/runtime/proflabel.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/race/doc.go (renamed from contrib/go/_std_1.20/src/runtime/race/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/race/internal/amd64v1/doc.go (renamed from contrib/go/_std_1.20/src/runtime/race/internal/amd64v1/doc.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/race/internal/amd64v1/ya.make (renamed from contrib/go/_std_1.20/src/runtime/race/internal/amd64v1/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/race/internal/ya.make (renamed from contrib/go/_std_1.20/src/runtime/race/internal/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/race/race_darwin_amd64.go (renamed from contrib/go/_std_1.20/src/runtime/race/race_darwin_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/race/race_linux_arm64.syso (renamed from contrib/go/_std_1.20/src/runtime/race/race_linux_arm64.syso)bin530736 -> 530736 bytes
-rw-r--r--contrib/go/_std_1.21/src/runtime/race/race_v1_amd64.go (renamed from contrib/go/_std_1.20/src/runtime/race/race_v1_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/race/ya.make51
-rw-r--r--contrib/go/_std_1.21/src/runtime/race0.go (renamed from contrib/go/_std_1.20/src/runtime/race0.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/rdebug.go (renamed from contrib/go/_std_1.20/src/runtime/rdebug.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/retry.go (renamed from contrib/go/_std_1.20/src/runtime/retry.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/rt0_darwin_amd64.s (renamed from contrib/go/_std_1.20/src/runtime/rt0_darwin_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/rt0_linux_amd64.s (renamed from contrib/go/_std_1.20/src/runtime/rt0_linux_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/rt0_linux_arm64.s (renamed from contrib/go/_std_1.20/src/runtime/rt0_linux_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/rt0_windows_amd64.s36
-rw-r--r--contrib/go/_std_1.21/src/runtime/runtime.go162
-rw-r--r--contrib/go/_std_1.21/src/runtime/runtime1.go655
-rw-r--r--contrib/go/_std_1.21/src/runtime/runtime2.go1193
-rw-r--r--contrib/go/_std_1.21/src/runtime/runtime_boring.go (renamed from contrib/go/_std_1.20/src/runtime/runtime_boring.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/rwmutex.go (renamed from contrib/go/_std_1.20/src/runtime/rwmutex.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/security_issetugid.go (renamed from contrib/go/_std_1.20/src/runtime/security_issetugid.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/security_linux.go (renamed from contrib/go/_std_1.20/src/runtime/security_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/security_nonunix.go (renamed from contrib/go/_std_1.20/src/runtime/security_nonunix.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/security_unix.go (renamed from contrib/go/_std_1.20/src/runtime/security_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/select.go632
-rw-r--r--contrib/go/_std_1.21/src/runtime/sema.go633
-rw-r--r--contrib/go/_std_1.21/src/runtime/signal_amd64.go (renamed from contrib/go/_std_1.20/src/runtime/signal_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/signal_arm64.go107
-rw-r--r--contrib/go/_std_1.21/src/runtime/signal_darwin.go (renamed from contrib/go/_std_1.20/src/runtime/signal_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/signal_darwin_amd64.go (renamed from contrib/go/_std_1.20/src/runtime/signal_darwin_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/signal_linux_amd64.go (renamed from contrib/go/_std_1.20/src/runtime/signal_linux_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/signal_linux_arm64.go (renamed from contrib/go/_std_1.20/src/runtime/signal_linux_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/signal_unix.go1371
-rw-r--r--contrib/go/_std_1.21/src/runtime/signal_windows.go445
-rw-r--r--contrib/go/_std_1.21/src/runtime/sigqueue.go (renamed from contrib/go/_std_1.20/src/runtime/sigqueue.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/sigqueue_note.go (renamed from contrib/go/_std_1.20/src/runtime/sigqueue_note.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/sigtab_linux_generic.go (renamed from contrib/go/_std_1.20/src/runtime/sigtab_linux_generic.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/sizeclasses.go98
-rw-r--r--contrib/go/_std_1.21/src/runtime/slice.go355
-rw-r--r--contrib/go/_std_1.21/src/runtime/softfloat64.go (renamed from contrib/go/_std_1.20/src/runtime/softfloat64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/stack.go1347
-rw-r--r--contrib/go/_std_1.21/src/runtime/stkframe.go289
-rw-r--r--contrib/go/_std_1.21/src/runtime/string.go588
-rw-r--r--contrib/go/_std_1.21/src/runtime/stubs.go499
-rw-r--r--contrib/go/_std_1.21/src/runtime/stubs2.go44
-rw-r--r--contrib/go/_std_1.21/src/runtime/stubs3.go10
-rw-r--r--contrib/go/_std_1.21/src/runtime/stubs_amd64.go53
-rw-r--r--contrib/go/_std_1.21/src/runtime/stubs_arm64.go27
-rw-r--r--contrib/go/_std_1.21/src/runtime/stubs_linux.go (renamed from contrib/go/_std_1.20/src/runtime/stubs_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/stubs_nonlinux.go (renamed from contrib/go/_std_1.20/src/runtime/stubs_nonlinux.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/symtab.go1125
-rw-r--r--contrib/go/_std_1.21/src/runtime/symtabinl.go116
-rw-r--r--contrib/go/_std_1.21/src/runtime/sys_arm64.go (renamed from contrib/go/_std_1.20/src/runtime/sys_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/sys_darwin.go603
-rw-r--r--contrib/go/_std_1.21/src/runtime/sys_darwin_amd64.s798
-rw-r--r--contrib/go/_std_1.21/src/runtime/sys_libc.go (renamed from contrib/go/_std_1.20/src/runtime/sys_libc.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/sys_linux_amd64.s706
-rw-r--r--contrib/go/_std_1.21/src/runtime/sys_linux_arm64.s787
-rw-r--r--contrib/go/_std_1.21/src/runtime/sys_nonppc64x.go (renamed from contrib/go/_std_1.20/src/runtime/sys_nonppc64x.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/sys_windows_amd64.s319
-rw-r--r--contrib/go/_std_1.21/src/runtime/sys_x86.go (renamed from contrib/go/_std_1.20/src/runtime/sys_x86.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/syscall_windows.go546
-rw-r--r--contrib/go/_std_1.21/src/runtime/tagptr.go14
-rw-r--r--contrib/go/_std_1.21/src/runtime/tagptr_64bit.go89
-rw-r--r--contrib/go/_std_1.21/src/runtime/test_amd64.go7
-rw-r--r--contrib/go/_std_1.21/src/runtime/test_amd64.s7
-rw-r--r--contrib/go/_std_1.21/src/runtime/test_stubs.go9
-rw-r--r--contrib/go/_std_1.21/src/runtime/textflag.h38
-rw-r--r--contrib/go/_std_1.21/src/runtime/time.go1144
-rw-r--r--contrib/go/_std_1.21/src/runtime/time_linux_amd64.s (renamed from contrib/go/_std_1.20/src/runtime/time_linux_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/time_nofake.go (renamed from contrib/go/_std_1.20/src/runtime/time_nofake.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/time_windows.h (renamed from contrib/go/_std_1.20/src/runtime/time_windows.h)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/time_windows_amd64.s (renamed from contrib/go/_std_1.20/src/runtime/time_windows_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/timeasm.go (renamed from contrib/go/_std_1.20/src/runtime/timeasm.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/timestub.go (renamed from contrib/go/_std_1.20/src/runtime/timestub.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/timestub2.go10
-rw-r--r--contrib/go/_std_1.21/src/runtime/tls_arm64.h (renamed from contrib/go/_std_1.20/src/runtime/tls_arm64.h)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/tls_arm64.s (renamed from contrib/go/_std_1.20/src/runtime/tls_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/tls_stub.go (renamed from contrib/go/_std_1.20/src/runtime/tls_stub.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/tls_windows_amd64.go (renamed from contrib/go/_std_1.20/src/runtime/tls_windows_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/trace.go1818
-rw-r--r--contrib/go/_std_1.21/src/runtime/trace/annotation.go198
-rw-r--r--contrib/go/_std_1.21/src/runtime/trace/trace.go154
-rw-r--r--contrib/go/_std_1.21/src/runtime/trace/ya.make18
-rw-r--r--contrib/go/_std_1.21/src/runtime/traceback.go1643
-rw-r--r--contrib/go/_std_1.21/src/runtime/type.go469
-rw-r--r--contrib/go/_std_1.21/src/runtime/typekind.go43
-rw-r--r--contrib/go/_std_1.21/src/runtime/unsafe.go114
-rw-r--r--contrib/go/_std_1.21/src/runtime/utf8.go (renamed from contrib/go/_std_1.20/src/runtime/utf8.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/vdso_elf64.go (renamed from contrib/go/_std_1.20/src/runtime/vdso_elf64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/vdso_in_none.go (renamed from contrib/go/_std_1.20/src/runtime/vdso_in_none.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/vdso_linux.go (renamed from contrib/go/_std_1.20/src/runtime/vdso_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/vdso_linux_amd64.go (renamed from contrib/go/_std_1.20/src/runtime/vdso_linux_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/vdso_linux_arm64.go (renamed from contrib/go/_std_1.20/src/runtime/vdso_linux_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/write_err.go (renamed from contrib/go/_std_1.20/src/runtime/write_err.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/ya.make480
-rw-r--r--contrib/go/_std_1.21/src/runtime/zcallback_windows.go (renamed from contrib/go/_std_1.20/src/runtime/zcallback_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/runtime/zcallback_windows.s2015
-rw-r--r--contrib/go/_std_1.21/src/slices/slices.go498
-rw-r--r--contrib/go/_std_1.21/src/slices/sort.go192
-rw-r--r--contrib/go/_std_1.21/src/slices/ya.make21
-rw-r--r--contrib/go/_std_1.21/src/slices/zsortanyfunc.go479
-rw-r--r--contrib/go/_std_1.21/src/slices/zsortordered.go481
-rw-r--r--contrib/go/_std_1.21/src/sort/search.go (renamed from contrib/go/_std_1.20/src/sort/search.go)0
-rw-r--r--contrib/go/_std_1.21/src/sort/slice.go (renamed from contrib/go/_std_1.20/src/sort/slice.go)0
-rw-r--r--contrib/go/_std_1.21/src/sort/sort.go283
-rw-r--r--contrib/go/_std_1.21/src/sort/ya.make27
-rw-r--r--contrib/go/_std_1.21/src/sort/zsortfunc.go (renamed from contrib/go/_std_1.20/src/sort/zsortfunc.go)0
-rw-r--r--contrib/go/_std_1.21/src/sort/zsortinterface.go (renamed from contrib/go/_std_1.20/src/sort/zsortinterface.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/atob.go (renamed from contrib/go/_std_1.20/src/strconv/atob.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/atoc.go (renamed from contrib/go/_std_1.20/src/strconv/atoc.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/atof.go (renamed from contrib/go/_std_1.20/src/strconv/atof.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/atoi.go (renamed from contrib/go/_std_1.20/src/strconv/atoi.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/bytealg.go (renamed from contrib/go/_std_1.20/src/strconv/bytealg.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/ctoa.go (renamed from contrib/go/_std_1.20/src/strconv/ctoa.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/decimal.go (renamed from contrib/go/_std_1.20/src/strconv/decimal.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/doc.go56
-rw-r--r--contrib/go/_std_1.21/src/strconv/eisel_lemire.go (renamed from contrib/go/_std_1.20/src/strconv/eisel_lemire.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/ftoa.go (renamed from contrib/go/_std_1.20/src/strconv/ftoa.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/ftoaryu.go (renamed from contrib/go/_std_1.20/src/strconv/ftoaryu.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/isprint.go752
-rw-r--r--contrib/go/_std_1.21/src/strconv/itoa.go (renamed from contrib/go/_std_1.20/src/strconv/itoa.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/quote.go (renamed from contrib/go/_std_1.20/src/strconv/quote.go)0
-rw-r--r--contrib/go/_std_1.21/src/strconv/ya.make44
-rw-r--r--contrib/go/_std_1.21/src/strings/builder.go118
-rw-r--r--contrib/go/_std_1.21/src/strings/clone.go (renamed from contrib/go/_std_1.20/src/strings/clone.go)0
-rw-r--r--contrib/go/_std_1.21/src/strings/compare.go (renamed from contrib/go/_std_1.20/src/strings/compare.go)0
-rw-r--r--contrib/go/_std_1.21/src/strings/reader.go160
-rw-r--r--contrib/go/_std_1.21/src/strings/replace.go (renamed from contrib/go/_std_1.20/src/strings/replace.go)0
-rw-r--r--contrib/go/_std_1.21/src/strings/search.go (renamed from contrib/go/_std_1.20/src/strings/search.go)0
-rw-r--r--contrib/go/_std_1.21/src/strings/strings.go1305
-rw-r--r--contrib/go/_std_1.21/src/strings/ya.make29
-rw-r--r--contrib/go/_std_1.21/src/sync/atomic/asm.s (renamed from contrib/go/_std_1.20/src/sync/atomic/asm.s)0
-rw-r--r--contrib/go/_std_1.21/src/sync/atomic/doc.go192
-rw-r--r--contrib/go/_std_1.21/src/sync/atomic/type.go200
-rw-r--r--contrib/go/_std_1.21/src/sync/atomic/value.go (renamed from contrib/go/_std_1.20/src/sync/atomic/value.go)0
-rw-r--r--contrib/go/_std_1.21/src/sync/atomic/ya.make28
-rw-r--r--contrib/go/_std_1.21/src/sync/cond.go (renamed from contrib/go/_std_1.20/src/sync/cond.go)0
-rw-r--r--contrib/go/_std_1.21/src/sync/map.go (renamed from contrib/go/_std_1.20/src/sync/map.go)0
-rw-r--r--contrib/go/_std_1.21/src/sync/mutex.go (renamed from contrib/go/_std_1.20/src/sync/mutex.go)0
-rw-r--r--contrib/go/_std_1.21/src/sync/once.go (renamed from contrib/go/_std_1.20/src/sync/once.go)0
-rw-r--r--contrib/go/_std_1.21/src/sync/oncefunc.go97
-rw-r--r--contrib/go/_std_1.21/src/sync/pool.go (renamed from contrib/go/_std_1.20/src/sync/pool.go)0
-rw-r--r--contrib/go/_std_1.21/src/sync/poolqueue.go (renamed from contrib/go/_std_1.20/src/sync/poolqueue.go)0
-rw-r--r--contrib/go/_std_1.21/src/sync/runtime.go (renamed from contrib/go/_std_1.20/src/sync/runtime.go)0
-rw-r--r--contrib/go/_std_1.21/src/sync/runtime2.go (renamed from contrib/go/_std_1.20/src/sync/runtime2.go)0
-rw-r--r--contrib/go/_std_1.21/src/sync/rwmutex.go244
-rw-r--r--contrib/go/_std_1.21/src/sync/waitgroup.go (renamed from contrib/go/_std_1.20/src/sync/waitgroup.go)0
-rw-r--r--contrib/go/_std_1.21/src/sync/ya.make39
-rw-r--r--contrib/go/_std_1.21/src/syscall/asan0.go (renamed from contrib/go/_std_1.20/src/syscall/asan0.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/asm_darwin_amd64.s (renamed from contrib/go/_std_1.20/src/syscall/asm_darwin_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/asm_linux_amd64.s (renamed from contrib/go/_std_1.20/src/syscall/asm_linux_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/asm_linux_arm64.s (renamed from contrib/go/_std_1.20/src/syscall/asm_linux_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/bpf_darwin.go (renamed from contrib/go/_std_1.20/src/syscall/bpf_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/dirent.go107
-rw-r--r--contrib/go/_std_1.21/src/syscall/dll_windows.go287
-rw-r--r--contrib/go/_std_1.21/src/syscall/endian_little.go (renamed from contrib/go/_std_1.20/src/syscall/endian_little.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/env_unix.go150
-rw-r--r--contrib/go/_std_1.21/src/syscall/env_windows.go96
-rw-r--r--contrib/go/_std_1.21/src/syscall/exec_libc2.go291
-rw-r--r--contrib/go/_std_1.21/src/syscall/exec_linux.go719
-rw-r--r--contrib/go/_std_1.21/src/syscall/exec_unix.go307
-rw-r--r--contrib/go/_std_1.21/src/syscall/exec_windows.go432
-rw-r--r--contrib/go/_std_1.21/src/syscall/flock.go (renamed from contrib/go/_std_1.20/src/syscall/flock.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/flock_darwin.go (renamed from contrib/go/_std_1.20/src/syscall/flock_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/forkpipe.go30
-rw-r--r--contrib/go/_std_1.21/src/syscall/forkpipe2.go98
-rw-r--r--contrib/go/_std_1.21/src/syscall/lsf_linux.go (renamed from contrib/go/_std_1.20/src/syscall/lsf_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/msan0.go (renamed from contrib/go/_std_1.20/src/syscall/msan0.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/net.go (renamed from contrib/go/_std_1.20/src/syscall/net.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/netlink_linux.go188
-rw-r--r--contrib/go/_std_1.21/src/syscall/ptrace_darwin.go21
-rw-r--r--contrib/go/_std_1.21/src/syscall/rlimit.go (renamed from contrib/go/_std_1.20/src/syscall/rlimit.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/rlimit_darwin.go (renamed from contrib/go/_std_1.20/src/syscall/rlimit_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/rlimit_stub.go (renamed from contrib/go/_std_1.20/src/syscall/rlimit_stub.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/route_bsd.go (renamed from contrib/go/_std_1.20/src/syscall/route_bsd.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/route_darwin.go (renamed from contrib/go/_std_1.20/src/syscall/route_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/security_windows.go378
-rw-r--r--contrib/go/_std_1.21/src/syscall/setuidgid_linux.go (renamed from contrib/go/_std_1.20/src/syscall/setuidgid_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/sockcmsg_linux.go (renamed from contrib/go/_std_1.20/src/syscall/sockcmsg_linux.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/sockcmsg_unix.go (renamed from contrib/go/_std_1.20/src/syscall/sockcmsg_unix.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/sockcmsg_unix_other.go (renamed from contrib/go/_std_1.20/src/syscall/sockcmsg_unix_other.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/syscall.go (renamed from contrib/go/_std_1.20/src/syscall/syscall.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/syscall_bsd.go531
-rw-r--r--contrib/go/_std_1.21/src/syscall/syscall_darwin.go (renamed from contrib/go/_std_1.20/src/syscall/syscall_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/syscall_darwin_amd64.go68
-rw-r--r--contrib/go/_std_1.21/src/syscall/syscall_linux.go1284
-rw-r--r--contrib/go/_std_1.21/src/syscall/syscall_linux_accept4.go (renamed from contrib/go/_std_1.20/src/syscall/syscall_linux_accept4.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/syscall_linux_amd64.go (renamed from contrib/go/_std_1.20/src/syscall/syscall_linux_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/syscall_linux_arm64.go (renamed from contrib/go/_std_1.20/src/syscall/syscall_linux_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/syscall_unix.go522
-rw-r--r--contrib/go/_std_1.21/src/syscall/syscall_windows.go1439
-rw-r--r--contrib/go/_std_1.21/src/syscall/time_nofake.go (renamed from contrib/go/_std_1.20/src/syscall/time_nofake.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/timestruct.go36
-rw-r--r--contrib/go/_std_1.21/src/syscall/types_windows.go (renamed from contrib/go/_std_1.20/src/syscall/types_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/types_windows_amd64.go (renamed from contrib/go/_std_1.20/src/syscall/types_windows_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/wtf8_windows.go92
-rw-r--r--contrib/go/_std_1.21/src/syscall/ya.make130
-rw-r--r--contrib/go/_std_1.21/src/syscall/zerrors_darwin_amd64.go (renamed from contrib/go/_std_1.20/src/syscall/zerrors_darwin_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/zerrors_linux_amd64.go (renamed from contrib/go/_std_1.20/src/syscall/zerrors_linux_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/zerrors_linux_arm64.go (renamed from contrib/go/_std_1.20/src/syscall/zerrors_linux_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/zerrors_windows.go (renamed from contrib/go/_std_1.20/src/syscall/zerrors_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/zsyscall_darwin_amd64.go2035
-rw-r--r--contrib/go/_std_1.21/src/syscall/zsyscall_darwin_amd64.s (renamed from contrib/go/_std_1.20/src/syscall/zsyscall_darwin_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/zsyscall_linux_amd64.go1658
-rw-r--r--contrib/go/_std_1.21/src/syscall/zsyscall_linux_arm64.go1573
-rw-r--r--contrib/go/_std_1.21/src/syscall/zsyscall_windows.go1478
-rw-r--r--contrib/go/_std_1.21/src/syscall/zsysnum_darwin_amd64.go (renamed from contrib/go/_std_1.20/src/syscall/zsysnum_darwin_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/zsysnum_linux_amd64.go (renamed from contrib/go/_std_1.20/src/syscall/zsysnum_linux_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/zsysnum_linux_arm64.go (renamed from contrib/go/_std_1.20/src/syscall/zsysnum_linux_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/ztypes_darwin_amd64.go (renamed from contrib/go/_std_1.20/src/syscall/ztypes_darwin_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/ztypes_linux_amd64.go (renamed from contrib/go/_std_1.20/src/syscall/ztypes_linux_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/syscall/ztypes_linux_arm64.go (renamed from contrib/go/_std_1.20/src/syscall/ztypes_linux_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/testing/allocs.go (renamed from contrib/go/_std_1.20/src/testing/allocs.go)0
-rw-r--r--contrib/go/_std_1.21/src/testing/benchmark.go (renamed from contrib/go/_std_1.20/src/testing/benchmark.go)0
-rw-r--r--contrib/go/_std_1.21/src/testing/cover.go124
-rw-r--r--contrib/go/_std_1.21/src/testing/example.go101
-rw-r--r--contrib/go/_std_1.21/src/testing/fstest/mapfs.go244
-rw-r--r--contrib/go/_std_1.21/src/testing/fstest/testfs.go624
-rw-r--r--contrib/go/_std_1.21/src/testing/fstest/ya.make16
-rw-r--r--contrib/go/_std_1.21/src/testing/fuzz.go (renamed from contrib/go/_std_1.20/src/testing/fuzz.go)0
-rw-r--r--contrib/go/_std_1.21/src/testing/internal/testdeps/deps.go (renamed from contrib/go/_std_1.20/src/testing/internal/testdeps/deps.go)0
-rw-r--r--contrib/go/_std_1.21/src/testing/internal/testdeps/ya.make (renamed from contrib/go/_std_1.20/src/testing/internal/testdeps/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/testing/internal/ya.make (renamed from contrib/go/_std_1.20/src/testing/internal/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/testing/iotest/logger.go (renamed from contrib/go/_std_1.20/src/testing/iotest/logger.go)0
-rw-r--r--contrib/go/_std_1.21/src/testing/iotest/reader.go (renamed from contrib/go/_std_1.20/src/testing/iotest/reader.go)0
-rw-r--r--contrib/go/_std_1.21/src/testing/iotest/writer.go (renamed from contrib/go/_std_1.20/src/testing/iotest/writer.go)0
-rw-r--r--contrib/go/_std_1.21/src/testing/iotest/ya.make20
-rw-r--r--contrib/go/_std_1.21/src/testing/match.go (renamed from contrib/go/_std_1.20/src/testing/match.go)0
-rw-r--r--contrib/go/_std_1.21/src/testing/newcover.go59
-rw-r--r--contrib/go/_std_1.21/src/testing/quick/quick.go385
-rw-r--r--contrib/go/_std_1.21/src/testing/quick/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/testing/run_example.go66
-rw-r--r--contrib/go/_std_1.21/src/testing/slogtest/slogtest.go322
-rw-r--r--contrib/go/_std_1.21/src/testing/slogtest/ya.make12
-rw-r--r--contrib/go/_std_1.21/src/testing/testing.go2302
-rw-r--r--contrib/go/_std_1.21/src/testing/testing_other.go (renamed from contrib/go/_std_1.20/src/testing/testing_other.go)0
-rw-r--r--contrib/go/_std_1.21/src/testing/testing_windows.go (renamed from contrib/go/_std_1.20/src/testing/testing_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/testing/ya.make57
-rw-r--r--contrib/go/_std_1.21/src/text/scanner/scanner.go (renamed from contrib/go/_std_1.20/src/text/scanner/scanner.go)0
-rw-r--r--contrib/go/_std_1.21/src/text/scanner/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/text/tabwriter/tabwriter.go (renamed from contrib/go/_std_1.20/src/text/tabwriter/tabwriter.go)0
-rw-r--r--contrib/go/_std_1.21/src/text/tabwriter/ya.make15
-rw-r--r--contrib/go/_std_1.21/src/text/template/doc.go464
-rw-r--r--contrib/go/_std_1.21/src/text/template/exec.go (renamed from contrib/go/_std_1.20/src/text/template/exec.go)0
-rw-r--r--contrib/go/_std_1.21/src/text/template/funcs.go776
-rw-r--r--contrib/go/_std_1.21/src/text/template/helper.go (renamed from contrib/go/_std_1.20/src/text/template/helper.go)0
-rw-r--r--contrib/go/_std_1.21/src/text/template/option.go (renamed from contrib/go/_std_1.20/src/text/template/option.go)0
-rw-r--r--contrib/go/_std_1.21/src/text/template/parse/lex.go (renamed from contrib/go/_std_1.20/src/text/template/parse/lex.go)0
-rw-r--r--contrib/go/_std_1.21/src/text/template/parse/node.go (renamed from contrib/go/_std_1.20/src/text/template/parse/node.go)0
-rw-r--r--contrib/go/_std_1.21/src/text/template/parse/parse.go (renamed from contrib/go/_std_1.20/src/text/template/parse/parse.go)0
-rw-r--r--contrib/go/_std_1.21/src/text/template/parse/ya.make17
-rw-r--r--contrib/go/_std_1.21/src/text/template/template.go (renamed from contrib/go/_std_1.20/src/text/template/template.go)0
-rw-r--r--contrib/go/_std_1.21/src/text/template/ya.make28
-rw-r--r--contrib/go/_std_1.21/src/time/format.go1686
-rw-r--r--contrib/go/_std_1.21/src/time/format_rfc3339.go (renamed from contrib/go/_std_1.20/src/time/format_rfc3339.go)0
-rw-r--r--contrib/go/_std_1.21/src/time/sleep.go (renamed from contrib/go/_std_1.20/src/time/sleep.go)0
-rw-r--r--contrib/go/_std_1.21/src/time/sys_unix.go62
-rw-r--r--contrib/go/_std_1.21/src/time/sys_windows.go (renamed from contrib/go/_std_1.20/src/time/sys_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/time/tick.go71
-rw-r--r--contrib/go/_std_1.21/src/time/time.go (renamed from contrib/go/_std_1.20/src/time/time.go)0
-rw-r--r--contrib/go/_std_1.21/src/time/tzdata/tzdata.go111
-rw-r--r--contrib/go/_std_1.21/src/time/tzdata/ya.make8
-rw-r--r--contrib/go/_std_1.21/src/time/tzdata/zzipdata.go5
-rw-r--r--contrib/go/_std_1.21/src/time/ya.make64
-rw-r--r--contrib/go/_std_1.21/src/time/zoneinfo.go (renamed from contrib/go/_std_1.20/src/time/zoneinfo.go)0
-rw-r--r--contrib/go/_std_1.21/src/time/zoneinfo_abbrs_windows.go155
-rw-r--r--contrib/go/_std_1.21/src/time/zoneinfo_goroot.go (renamed from contrib/go/_std_1.20/src/time/zoneinfo_goroot.go)0
-rw-r--r--contrib/go/_std_1.21/src/time/zoneinfo_read.go597
-rw-r--r--contrib/go/_std_1.21/src/time/zoneinfo_unix.go69
-rw-r--r--contrib/go/_std_1.21/src/time/zoneinfo_windows.go (renamed from contrib/go/_std_1.20/src/time/zoneinfo_windows.go)0
-rw-r--r--contrib/go/_std_1.21/src/unicode/casetables.go (renamed from contrib/go/_std_1.20/src/unicode/casetables.go)0
-rw-r--r--contrib/go/_std_1.21/src/unicode/digit.go (renamed from contrib/go/_std_1.20/src/unicode/digit.go)0
-rw-r--r--contrib/go/_std_1.21/src/unicode/graphic.go (renamed from contrib/go/_std_1.20/src/unicode/graphic.go)0
-rw-r--r--contrib/go/_std_1.21/src/unicode/letter.go (renamed from contrib/go/_std_1.20/src/unicode/letter.go)0
-rw-r--r--contrib/go/_std_1.21/src/unicode/tables.go8378
-rw-r--r--contrib/go/_std_1.21/src/unicode/utf16/utf16.go133
-rw-r--r--contrib/go/_std_1.21/src/unicode/utf16/ya.make14
-rw-r--r--contrib/go/_std_1.21/src/unicode/utf8/utf8.go (renamed from contrib/go/_std_1.20/src/unicode/utf8/utf8.go)0
-rw-r--r--contrib/go/_std_1.21/src/unicode/utf8/ya.make15
-rw-r--r--contrib/go/_std_1.21/src/unicode/ya.make24
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/chacha_generic.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/chacha_generic.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/xor.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/xor.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/ya.make21
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/ya.make22
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go824
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/asn1/ya.make (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/asn1/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/builder.go345
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/string.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/string.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/ya.make (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/hkdf/hkdf.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/hkdf/hkdf.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/hkdf/ya.make (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/hkdf/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/alias/alias.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/alias/alias.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/alias/ya.make (renamed from contrib/go/_std_1.20/src/crypto/internal/alias/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/ya.make22
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/dns/dnsmessage/message.go2694
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/dns/dnsmessage/ya.make (renamed from contrib/go/_std_1.20/src/net/mail/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpguts/guts.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpguts/guts.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpguts/httplex.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpguts/httplex.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpguts/ya.make (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpguts/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpproxy/proxy.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpproxy/proxy.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpproxy/ya.make (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpproxy/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/encode.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/encode.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/hpack.go523
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/huffman.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/huffman.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/static_table.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/static_table.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/tables.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/tables.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/ya.make (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/go118.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/go118.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/idna10.0.0.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/idna10.0.0.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/punycode.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/punycode.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/tables13.0.0.go4960
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/trie.go51
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/trie13.0.0.go31
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/trieval.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/trieval.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/ya.make13
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/address.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/address.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/binary.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/binary.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/empty.s (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/empty.s)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/interface.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/interface.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/interface_classic.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/interface_classic.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/interface_multicast.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/interface_multicast.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/message.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/message.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/route.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/route.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/route_classic.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/route_classic.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/sys.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/sys.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/sys_darwin.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/sys_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/syscall.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/syscall.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/ya.make26
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/zsys_darwin.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/zsys_darwin.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/byteorder.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/byteorder.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_arm64.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_arm64.s (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_arm64.s)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go111
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_x86.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_x86.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_x86.s (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_x86.s)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/endian_little.go11
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/hwcap_linux.go71
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/parse.go43
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/proc_cpuinfo_linux.go54
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/runtime_auxv.go16
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/ya.make58
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/secure/bidirule/bidirule.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/secure/bidirule/bidirule.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/secure/bidirule/ya.make (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/secure/bidirule/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/transform/transform.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/transform/transform.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/transform/ya.make (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/transform/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/bidi.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/bidi.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/bracket.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/bracket.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/core.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/core.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/prop.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/prop.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go1956
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/trieval.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/trieval.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/ya.make (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/ya.make)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/composition.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/composition.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/forminfo.go279
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/input.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/input.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/iter.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/iter.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/normalize.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/normalize.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/readwriter.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/readwriter.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go7761
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/transform.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/transform.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/trie.go (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/trie.go)0
-rw-r--r--contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/ya.make (renamed from contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/ya.make)0
-rw-r--r--vendor/github.com/pkg/errors/gotest/ya.make2
-rw-r--r--vendor/github.com/stretchr/testify/assert/gotest/ya.make2
-rw-r--r--vendor/modernc.org/mathutil/ya.make2
2649 files changed, 325939 insertions, 310849 deletions
diff --git a/build/conf/go.conf b/build/conf/go.conf
index ee48dfe476..be69e6717b 100644
--- a/build/conf/go.conf
+++ b/build/conf/go.conf
@@ -59,8 +59,11 @@ elsewhen ($ARCH_ARM64) {
GO_HOST_TARG_PARAMS=++host-os $GO_HOST_OS ++host-arch $GO_HOST_ARCH ++targ-os $GO_TARG_OS ++targ-arch $GO_TARG_ARCH
# tag:go-specific
-GOSTD_VERSION=1.20
-when ($GOSTD_VERSION == "1.20") {
+GOSTD_VERSION=1.21
+when ($GOSTD_VERSION == "1.21") {
+ GOSTD=contrib/go/_std_1.21/src
+}
+elsewhen ($GOSTD_VERSION == "1.20") {
GOSTD=contrib/go/_std_1.20/src
}
otherwise {
@@ -707,7 +710,7 @@ module _GO_BASE_UNIT: _BASE_UNIT {
_GO_CGO1_WRAPPER_FLAGS=--build-prefix=__ARCADIA_BUILD_ROOT_PREFIX__ --source-prefix=__ARCADIA_SOURCE_ROOT_PREFIX__
}
"yolint" ? {
- _GO_VET=yes
+ _GO_VET=no
PEERDIR+=build/external_resources/yolint
_GO_VET_TOOL=${YOLINT_RESOURCE_GLOBAL}/yolint
_GO_VET_FLAGS=-migration.config=${input:"${ARCADIA_ROOT}/build/rules/go/migrations.yaml"} -scopelint.config=${input:"${ARCADIA_ROOT}/build/rules/go/extended_lint.yaml"}
diff --git a/build/external_resources/go_tools/go1.21.json b/build/external_resources/go_tools/go1.21.json
new file mode 100644
index 0000000000..329da39b4e
--- /dev/null
+++ b/build/external_resources/go_tools/go1.21.json
@@ -0,0 +1,19 @@
+{
+ "by_platform": {
+ "darwin-arm64": {
+ "uri": "sbr:5324697653"
+ },
+ "darwin-x86_64": {
+ "uri": "sbr:5324689878"
+ },
+ "linux-x86_64": {
+ "uri": "sbr:5324670083"
+ },
+ "linux-aarch64": {
+ "uri": "sbr:5324680539"
+ },
+ "win32-x86_64": {
+ "uri": "sbr:5324707942"
+ }
+ }
+}
diff --git a/build/external_resources/go_tools/ya.make b/build/external_resources/go_tools/ya.make
index d93a451b55..24807da914 100644
--- a/build/external_resources/go_tools/ya.make
+++ b/build/external_resources/go_tools/ya.make
@@ -2,6 +2,8 @@ RESOURCES_LIBRARY()
IF(GOSTD_VERSION == 1.20)
DECLARE_EXTERNAL_HOST_RESOURCES_BUNDLE_BY_JSON(GO_TOOLS go1.20.json)
+ELSEIF(GOSTD_VERSION == 1.21)
+ DECLARE_EXTERNAL_HOST_RESOURCES_BUNDLE_BY_JSON(GO_TOOLS go1.21.json)
ELSE()
MESSAGE(FATAL_ERROR Unsupported version [${GOSTD_VERSION}] of Go Standard Library)
ENDIF()
diff --git a/build/mapping.conf.json b/build/mapping.conf.json
index ad3965a93c..5d434ec838 100644
--- a/build/mapping.conf.json
+++ b/build/mapping.conf.json
@@ -21,11 +21,11 @@
"4561490451": "http://devtools-registry.s3.yandex.net/4561490451",
"5002675116": "http://devtools-registry.s3.yandex.net/5002675116",
"3676654632": "http://devtools-registry.s3.yandex.net/3676654632",
- "4773516480": "http://devtools-registry.s3.yandex.net/4773516480",
- "4773521027": "http://devtools-registry.s3.yandex.net/4773521027",
- "4773507347": "http://devtools-registry.s3.yandex.net/4773507347",
- "4773511397": "http://devtools-registry.s3.yandex.net/4773511397",
- "4773525032": "http://devtools-registry.s3.yandex.net/4773525032",
+ "5324689878": "http://devtools-registry.s3.yandex.net/5324689878",
+ "5324697653": "http://devtools-registry.s3.yandex.net/5324697653",
+ "5324670083": "http://devtools-registry.s3.yandex.net/5324670083",
+ "5324680539": "http://devtools-registry.s3.yandex.net/5324680539",
+ "5324707942": "http://devtools-registry.s3.yandex.net/5324707942",
"1966560555": "http://devtools-registry.s3.yandex.net/1966560555",
"309054781": "http://devtools-registry.s3.yandex.net/309054781",
"5298918458": "http://devtools-registry.s3.yandex.net/5298918458",
@@ -120,11 +120,11 @@
"4561490451": "JAVA_JDK_ENVIRONMENT-linux-arm64-17.0.7+7-jdk-linux-aarch64.yandex.tgz",
"5002675116": "JAVA_JDK_ENVIRONMENT-windows-17.0.7+7-jdk-windows-amd64.yandex.tgz",
"3676654632": "JAVA_JDK_ENVIRONMENT-windows-19.0.1.1-jdk-windows-i686.yandex.tgz",
- "4773516480": "OTHER_RESOURCE-none-1.20.6-y_go1.20.6.darwin-amd64.tar.gz",
- "4773521027": "OTHER_RESOURCE-none-1.20.6-y_go1.20.6.darwin-arm64.tar.gz",
- "4773507347": "OTHER_RESOURCE-none-1.20.6-y_go1.20.6.linux-amd64.tar.gz",
- "4773511397": "OTHER_RESOURCE-none-1.20.6-y_go1.20.6.linux-arm64.tar.gz",
- "4773525032": "OTHER_RESOURCE-none-1.20.6-y_go1.20.6.windows-amd64.tar.gz",
+ "5324689878": "OTHER_RESOURCE-none-1.21.3-y_go1.21.3.darwin-amd64.tar.gz",
+ "5324697653": "OTHER_RESOURCE-none-1.21.3-y_go1.21.3.darwin-arm64.tar.gz",
+ "5324670083": "OTHER_RESOURCE-none-1.21.3-y_go1.21.3.linux-amd64.tar.gz",
+ "5324680539": "OTHER_RESOURCE-none-1.21.3-y_go1.21.3.linux-arm64.tar.gz",
+ "5324707942": "OTHER_RESOURCE-none-1.21.3-y_go1.21.3.windows-amd64.tar.gz",
"1966560555": "Ubuntu 14 x86-64 native SDK (patched, v3)",
"309054781": "Ubuntu 16 x86-64 -> Ubuntu 16 aarch64 cross SDK",
"5298918458": "bin-gdb-reloc-ya-linux-aarch64-62901b3b39a8b08c2d39a3bf08a1fc3a6d76eb78",
diff --git a/contrib/go/_std_1.20/src/archive/tar/common.go b/contrib/go/_std_1.20/src/archive/tar/common.go
deleted file mode 100644
index 38216ac13f..0000000000
--- a/contrib/go/_std_1.20/src/archive/tar/common.go
+++ /dev/null
@@ -1,732 +0,0 @@
-// Copyright 2009 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 tar implements access to tar archives.
-//
-// Tape archives (tar) are a file format for storing a sequence of files that
-// can be read and written in a streaming manner.
-// This package aims to cover most variations of the format,
-// including those produced by GNU and BSD tar tools.
-package tar
-
-import (
- "errors"
- "fmt"
- "internal/godebug"
- "io/fs"
- "math"
- "path"
- "reflect"
- "strconv"
- "strings"
- "time"
-)
-
-// BUG: Use of the Uid and Gid fields in Header could overflow on 32-bit
-// architectures. If a large value is encountered when decoding, the result
-// stored in Header will be the truncated version.
-
-var tarinsecurepath = godebug.New("tarinsecurepath")
-
-var (
- ErrHeader = errors.New("archive/tar: invalid tar header")
- ErrWriteTooLong = errors.New("archive/tar: write too long")
- ErrFieldTooLong = errors.New("archive/tar: header field too long")
- ErrWriteAfterClose = errors.New("archive/tar: write after close")
- ErrInsecurePath = errors.New("archive/tar: insecure file path")
- errMissData = errors.New("archive/tar: sparse file references non-existent data")
- errUnrefData = errors.New("archive/tar: sparse file contains unreferenced data")
- errWriteHole = errors.New("archive/tar: write non-NUL byte in sparse hole")
-)
-
-type headerError []string
-
-func (he headerError) Error() string {
- const prefix = "archive/tar: cannot encode header"
- var ss []string
- for _, s := range he {
- if s != "" {
- ss = append(ss, s)
- }
- }
- if len(ss) == 0 {
- return prefix
- }
- return fmt.Sprintf("%s: %v", prefix, strings.Join(ss, "; and "))
-}
-
-// Type flags for Header.Typeflag.
-const (
- // Type '0' indicates a regular file.
- TypeReg = '0'
-
- // Deprecated: Use TypeReg instead.
- TypeRegA = '\x00'
-
- // Type '1' to '6' are header-only flags and may not have a data body.
- TypeLink = '1' // Hard link
- TypeSymlink = '2' // Symbolic link
- TypeChar = '3' // Character device node
- TypeBlock = '4' // Block device node
- TypeDir = '5' // Directory
- TypeFifo = '6' // FIFO node
-
- // Type '7' is reserved.
- TypeCont = '7'
-
- // Type 'x' is used by the PAX format to store key-value records that
- // are only relevant to the next file.
- // This package transparently handles these types.
- TypeXHeader = 'x'
-
- // Type 'g' is used by the PAX format to store key-value records that
- // are relevant to all subsequent files.
- // This package only supports parsing and composing such headers,
- // but does not currently support persisting the global state across files.
- TypeXGlobalHeader = 'g'
-
- // Type 'S' indicates a sparse file in the GNU format.
- TypeGNUSparse = 'S'
-
- // Types 'L' and 'K' are used by the GNU format for a meta file
- // used to store the path or link name for the next file.
- // This package transparently handles these types.
- TypeGNULongName = 'L'
- TypeGNULongLink = 'K'
-)
-
-// Keywords for PAX extended header records.
-const (
- paxNone = "" // Indicates that no PAX key is suitable
- paxPath = "path"
- paxLinkpath = "linkpath"
- paxSize = "size"
- paxUid = "uid"
- paxGid = "gid"
- paxUname = "uname"
- paxGname = "gname"
- paxMtime = "mtime"
- paxAtime = "atime"
- paxCtime = "ctime" // Removed from later revision of PAX spec, but was valid
- paxCharset = "charset" // Currently unused
- paxComment = "comment" // Currently unused
-
- paxSchilyXattr = "SCHILY.xattr."
-
- // Keywords for GNU sparse files in a PAX extended header.
- paxGNUSparse = "GNU.sparse."
- paxGNUSparseNumBlocks = "GNU.sparse.numblocks"
- paxGNUSparseOffset = "GNU.sparse.offset"
- paxGNUSparseNumBytes = "GNU.sparse.numbytes"
- paxGNUSparseMap = "GNU.sparse.map"
- paxGNUSparseName = "GNU.sparse.name"
- paxGNUSparseMajor = "GNU.sparse.major"
- paxGNUSparseMinor = "GNU.sparse.minor"
- paxGNUSparseSize = "GNU.sparse.size"
- paxGNUSparseRealSize = "GNU.sparse.realsize"
-)
-
-// basicKeys is a set of the PAX keys for which we have built-in support.
-// This does not contain "charset" or "comment", which are both PAX-specific,
-// so adding them as first-class features of Header is unlikely.
-// Users can use the PAXRecords field to set it themselves.
-var basicKeys = map[string]bool{
- paxPath: true, paxLinkpath: true, paxSize: true, paxUid: true, paxGid: true,
- paxUname: true, paxGname: true, paxMtime: true, paxAtime: true, paxCtime: true,
-}
-
-// A Header represents a single header in a tar archive.
-// Some fields may not be populated.
-//
-// For forward compatibility, users that retrieve a Header from Reader.Next,
-// mutate it in some ways, and then pass it back to Writer.WriteHeader
-// should do so by creating a new Header and copying the fields
-// that they are interested in preserving.
-type Header struct {
- // Typeflag is the type of header entry.
- // The zero value is automatically promoted to either TypeReg or TypeDir
- // depending on the presence of a trailing slash in Name.
- Typeflag byte
-
- Name string // Name of file entry
- Linkname string // Target name of link (valid for TypeLink or TypeSymlink)
-
- Size int64 // Logical file size in bytes
- Mode int64 // Permission and mode bits
- Uid int // User ID of owner
- Gid int // Group ID of owner
- Uname string // User name of owner
- Gname string // Group name of owner
-
- // If the Format is unspecified, then Writer.WriteHeader rounds ModTime
- // to the nearest second and ignores the AccessTime and ChangeTime fields.
- //
- // To use AccessTime or ChangeTime, specify the Format as PAX or GNU.
- // To use sub-second resolution, specify the Format as PAX.
- ModTime time.Time // Modification time
- AccessTime time.Time // Access time (requires either PAX or GNU support)
- ChangeTime time.Time // Change time (requires either PAX or GNU support)
-
- Devmajor int64 // Major device number (valid for TypeChar or TypeBlock)
- Devminor int64 // Minor device number (valid for TypeChar or TypeBlock)
-
- // Xattrs stores extended attributes as PAX records under the
- // "SCHILY.xattr." namespace.
- //
- // The following are semantically equivalent:
- // h.Xattrs[key] = value
- // h.PAXRecords["SCHILY.xattr."+key] = value
- //
- // When Writer.WriteHeader is called, the contents of Xattrs will take
- // precedence over those in PAXRecords.
- //
- // Deprecated: Use PAXRecords instead.
- Xattrs map[string]string
-
- // PAXRecords is a map of PAX extended header records.
- //
- // User-defined records should have keys of the following form:
- // VENDOR.keyword
- // Where VENDOR is some namespace in all uppercase, and keyword may
- // not contain the '=' character (e.g., "GOLANG.pkg.version").
- // The key and value should be non-empty UTF-8 strings.
- //
- // When Writer.WriteHeader is called, PAX records derived from the
- // other fields in Header take precedence over PAXRecords.
- PAXRecords map[string]string
-
- // Format specifies the format of the tar header.
- //
- // This is set by Reader.Next as a best-effort guess at the format.
- // Since the Reader liberally reads some non-compliant files,
- // it is possible for this to be FormatUnknown.
- //
- // If the format is unspecified when Writer.WriteHeader is called,
- // then it uses the first format (in the order of USTAR, PAX, GNU)
- // capable of encoding this Header (see Format).
- Format Format
-}
-
-// sparseEntry represents a Length-sized fragment at Offset in the file.
-type sparseEntry struct{ Offset, Length int64 }
-
-func (s sparseEntry) endOffset() int64 { return s.Offset + s.Length }
-
-// A sparse file can be represented as either a sparseDatas or a sparseHoles.
-// As long as the total size is known, they are equivalent and one can be
-// converted to the other form and back. The various tar formats with sparse
-// file support represent sparse files in the sparseDatas form. That is, they
-// specify the fragments in the file that has data, and treat everything else as
-// having zero bytes. As such, the encoding and decoding logic in this package
-// deals with sparseDatas.
-//
-// However, the external API uses sparseHoles instead of sparseDatas because the
-// zero value of sparseHoles logically represents a normal file (i.e., there are
-// no holes in it). On the other hand, the zero value of sparseDatas implies
-// that the file has no data in it, which is rather odd.
-//
-// As an example, if the underlying raw file contains the 10-byte data:
-//
-// var compactFile = "abcdefgh"
-//
-// And the sparse map has the following entries:
-//
-// var spd sparseDatas = []sparseEntry{
-// {Offset: 2, Length: 5}, // Data fragment for 2..6
-// {Offset: 18, Length: 3}, // Data fragment for 18..20
-// }
-// var sph sparseHoles = []sparseEntry{
-// {Offset: 0, Length: 2}, // Hole fragment for 0..1
-// {Offset: 7, Length: 11}, // Hole fragment for 7..17
-// {Offset: 21, Length: 4}, // Hole fragment for 21..24
-// }
-//
-// Then the content of the resulting sparse file with a Header.Size of 25 is:
-//
-// var sparseFile = "\x00"*2 + "abcde" + "\x00"*11 + "fgh" + "\x00"*4
-type (
- sparseDatas []sparseEntry
- sparseHoles []sparseEntry
-)
-
-// validateSparseEntries reports whether sp is a valid sparse map.
-// It does not matter whether sp represents data fragments or hole fragments.
-func validateSparseEntries(sp []sparseEntry, size int64) bool {
- // Validate all sparse entries. These are the same checks as performed by
- // the BSD tar utility.
- if size < 0 {
- return false
- }
- var pre sparseEntry
- for _, cur := range sp {
- switch {
- case cur.Offset < 0 || cur.Length < 0:
- return false // Negative values are never okay
- case cur.Offset > math.MaxInt64-cur.Length:
- return false // Integer overflow with large length
- case cur.endOffset() > size:
- return false // Region extends beyond the actual size
- case pre.endOffset() > cur.Offset:
- return false // Regions cannot overlap and must be in order
- }
- pre = cur
- }
- return true
-}
-
-// alignSparseEntries mutates src and returns dst where each fragment's
-// starting offset is aligned up to the nearest block edge, and each
-// ending offset is aligned down to the nearest block edge.
-//
-// Even though the Go tar Reader and the BSD tar utility can handle entries
-// with arbitrary offsets and lengths, the GNU tar utility can only handle
-// offsets and lengths that are multiples of blockSize.
-func alignSparseEntries(src []sparseEntry, size int64) []sparseEntry {
- dst := src[:0]
- for _, s := range src {
- pos, end := s.Offset, s.endOffset()
- pos += blockPadding(+pos) // Round-up to nearest blockSize
- if end != size {
- end -= blockPadding(-end) // Round-down to nearest blockSize
- }
- if pos < end {
- dst = append(dst, sparseEntry{Offset: pos, Length: end - pos})
- }
- }
- return dst
-}
-
-// invertSparseEntries converts a sparse map from one form to the other.
-// If the input is sparseHoles, then it will output sparseDatas and vice-versa.
-// The input must have been already validated.
-//
-// This function mutates src and returns a normalized map where:
-// - adjacent fragments are coalesced together
-// - only the last fragment may be empty
-// - the endOffset of the last fragment is the total size
-func invertSparseEntries(src []sparseEntry, size int64) []sparseEntry {
- dst := src[:0]
- var pre sparseEntry
- for _, cur := range src {
- if cur.Length == 0 {
- continue // Skip empty fragments
- }
- pre.Length = cur.Offset - pre.Offset
- if pre.Length > 0 {
- dst = append(dst, pre) // Only add non-empty fragments
- }
- pre.Offset = cur.endOffset()
- }
- pre.Length = size - pre.Offset // Possibly the only empty fragment
- return append(dst, pre)
-}
-
-// fileState tracks the number of logical (includes sparse holes) and physical
-// (actual in tar archive) bytes remaining for the current file.
-//
-// Invariant: logicalRemaining >= physicalRemaining
-type fileState interface {
- logicalRemaining() int64
- physicalRemaining() int64
-}
-
-// allowedFormats determines which formats can be used.
-// The value returned is the logical OR of multiple possible formats.
-// If the value is FormatUnknown, then the input Header cannot be encoded
-// and an error is returned explaining why.
-//
-// As a by-product of checking the fields, this function returns paxHdrs, which
-// contain all fields that could not be directly encoded.
-// A value receiver ensures that this method does not mutate the source Header.
-func (h Header) allowedFormats() (format Format, paxHdrs map[string]string, err error) {
- format = FormatUSTAR | FormatPAX | FormatGNU
- paxHdrs = make(map[string]string)
-
- var whyNoUSTAR, whyNoPAX, whyNoGNU string
- var preferPAX bool // Prefer PAX over USTAR
- verifyString := func(s string, size int, name, paxKey string) {
- // NUL-terminator is optional for path and linkpath.
- // Technically, it is required for uname and gname,
- // but neither GNU nor BSD tar checks for it.
- tooLong := len(s) > size
- allowLongGNU := paxKey == paxPath || paxKey == paxLinkpath
- if hasNUL(s) || (tooLong && !allowLongGNU) {
- whyNoGNU = fmt.Sprintf("GNU cannot encode %s=%q", name, s)
- format.mustNotBe(FormatGNU)
- }
- if !isASCII(s) || tooLong {
- canSplitUSTAR := paxKey == paxPath
- if _, _, ok := splitUSTARPath(s); !canSplitUSTAR || !ok {
- whyNoUSTAR = fmt.Sprintf("USTAR cannot encode %s=%q", name, s)
- format.mustNotBe(FormatUSTAR)
- }
- if paxKey == paxNone {
- whyNoPAX = fmt.Sprintf("PAX cannot encode %s=%q", name, s)
- format.mustNotBe(FormatPAX)
- } else {
- paxHdrs[paxKey] = s
- }
- }
- if v, ok := h.PAXRecords[paxKey]; ok && v == s {
- paxHdrs[paxKey] = v
- }
- }
- verifyNumeric := func(n int64, size int, name, paxKey string) {
- if !fitsInBase256(size, n) {
- whyNoGNU = fmt.Sprintf("GNU cannot encode %s=%d", name, n)
- format.mustNotBe(FormatGNU)
- }
- if !fitsInOctal(size, n) {
- whyNoUSTAR = fmt.Sprintf("USTAR cannot encode %s=%d", name, n)
- format.mustNotBe(FormatUSTAR)
- if paxKey == paxNone {
- whyNoPAX = fmt.Sprintf("PAX cannot encode %s=%d", name, n)
- format.mustNotBe(FormatPAX)
- } else {
- paxHdrs[paxKey] = strconv.FormatInt(n, 10)
- }
- }
- if v, ok := h.PAXRecords[paxKey]; ok && v == strconv.FormatInt(n, 10) {
- paxHdrs[paxKey] = v
- }
- }
- verifyTime := func(ts time.Time, size int, name, paxKey string) {
- if ts.IsZero() {
- return // Always okay
- }
- if !fitsInBase256(size, ts.Unix()) {
- whyNoGNU = fmt.Sprintf("GNU cannot encode %s=%v", name, ts)
- format.mustNotBe(FormatGNU)
- }
- isMtime := paxKey == paxMtime
- fitsOctal := fitsInOctal(size, ts.Unix())
- if (isMtime && !fitsOctal) || !isMtime {
- whyNoUSTAR = fmt.Sprintf("USTAR cannot encode %s=%v", name, ts)
- format.mustNotBe(FormatUSTAR)
- }
- needsNano := ts.Nanosecond() != 0
- if !isMtime || !fitsOctal || needsNano {
- preferPAX = true // USTAR may truncate sub-second measurements
- if paxKey == paxNone {
- whyNoPAX = fmt.Sprintf("PAX cannot encode %s=%v", name, ts)
- format.mustNotBe(FormatPAX)
- } else {
- paxHdrs[paxKey] = formatPAXTime(ts)
- }
- }
- if v, ok := h.PAXRecords[paxKey]; ok && v == formatPAXTime(ts) {
- paxHdrs[paxKey] = v
- }
- }
-
- // Check basic fields.
- var blk block
- v7 := blk.toV7()
- ustar := blk.toUSTAR()
- gnu := blk.toGNU()
- verifyString(h.Name, len(v7.name()), "Name", paxPath)
- verifyString(h.Linkname, len(v7.linkName()), "Linkname", paxLinkpath)
- verifyString(h.Uname, len(ustar.userName()), "Uname", paxUname)
- verifyString(h.Gname, len(ustar.groupName()), "Gname", paxGname)
- verifyNumeric(h.Mode, len(v7.mode()), "Mode", paxNone)
- verifyNumeric(int64(h.Uid), len(v7.uid()), "Uid", paxUid)
- verifyNumeric(int64(h.Gid), len(v7.gid()), "Gid", paxGid)
- verifyNumeric(h.Size, len(v7.size()), "Size", paxSize)
- verifyNumeric(h.Devmajor, len(ustar.devMajor()), "Devmajor", paxNone)
- verifyNumeric(h.Devminor, len(ustar.devMinor()), "Devminor", paxNone)
- verifyTime(h.ModTime, len(v7.modTime()), "ModTime", paxMtime)
- verifyTime(h.AccessTime, len(gnu.accessTime()), "AccessTime", paxAtime)
- verifyTime(h.ChangeTime, len(gnu.changeTime()), "ChangeTime", paxCtime)
-
- // Check for header-only types.
- var whyOnlyPAX, whyOnlyGNU string
- switch h.Typeflag {
- case TypeReg, TypeChar, TypeBlock, TypeFifo, TypeGNUSparse:
- // Exclude TypeLink and TypeSymlink, since they may reference directories.
- if strings.HasSuffix(h.Name, "/") {
- return FormatUnknown, nil, headerError{"filename may not have trailing slash"}
- }
- case TypeXHeader, TypeGNULongName, TypeGNULongLink:
- return FormatUnknown, nil, headerError{"cannot manually encode TypeXHeader, TypeGNULongName, or TypeGNULongLink headers"}
- case TypeXGlobalHeader:
- h2 := Header{Name: h.Name, Typeflag: h.Typeflag, Xattrs: h.Xattrs, PAXRecords: h.PAXRecords, Format: h.Format}
- if !reflect.DeepEqual(h, h2) {
- return FormatUnknown, nil, headerError{"only PAXRecords should be set for TypeXGlobalHeader"}
- }
- whyOnlyPAX = "only PAX supports TypeXGlobalHeader"
- format.mayOnlyBe(FormatPAX)
- }
- if !isHeaderOnlyType(h.Typeflag) && h.Size < 0 {
- return FormatUnknown, nil, headerError{"negative size on header-only type"}
- }
-
- // Check PAX records.
- if len(h.Xattrs) > 0 {
- for k, v := range h.Xattrs {
- paxHdrs[paxSchilyXattr+k] = v
- }
- whyOnlyPAX = "only PAX supports Xattrs"
- format.mayOnlyBe(FormatPAX)
- }
- if len(h.PAXRecords) > 0 {
- for k, v := range h.PAXRecords {
- switch _, exists := paxHdrs[k]; {
- case exists:
- continue // Do not overwrite existing records
- case h.Typeflag == TypeXGlobalHeader:
- paxHdrs[k] = v // Copy all records
- case !basicKeys[k] && !strings.HasPrefix(k, paxGNUSparse):
- paxHdrs[k] = v // Ignore local records that may conflict
- }
- }
- whyOnlyPAX = "only PAX supports PAXRecords"
- format.mayOnlyBe(FormatPAX)
- }
- for k, v := range paxHdrs {
- if !validPAXRecord(k, v) {
- return FormatUnknown, nil, headerError{fmt.Sprintf("invalid PAX record: %q", k+" = "+v)}
- }
- }
-
- // TODO(dsnet): Re-enable this when adding sparse support.
- // See https://golang.org/issue/22735
- /*
- // Check sparse files.
- if len(h.SparseHoles) > 0 || h.Typeflag == TypeGNUSparse {
- if isHeaderOnlyType(h.Typeflag) {
- return FormatUnknown, nil, headerError{"header-only type cannot be sparse"}
- }
- if !validateSparseEntries(h.SparseHoles, h.Size) {
- return FormatUnknown, nil, headerError{"invalid sparse holes"}
- }
- if h.Typeflag == TypeGNUSparse {
- whyOnlyGNU = "only GNU supports TypeGNUSparse"
- format.mayOnlyBe(FormatGNU)
- } else {
- whyNoGNU = "GNU supports sparse files only with TypeGNUSparse"
- format.mustNotBe(FormatGNU)
- }
- whyNoUSTAR = "USTAR does not support sparse files"
- format.mustNotBe(FormatUSTAR)
- }
- */
-
- // Check desired format.
- if wantFormat := h.Format; wantFormat != FormatUnknown {
- if wantFormat.has(FormatPAX) && !preferPAX {
- wantFormat.mayBe(FormatUSTAR) // PAX implies USTAR allowed too
- }
- format.mayOnlyBe(wantFormat) // Set union of formats allowed and format wanted
- }
- if format == FormatUnknown {
- switch h.Format {
- case FormatUSTAR:
- err = headerError{"Format specifies USTAR", whyNoUSTAR, whyOnlyPAX, whyOnlyGNU}
- case FormatPAX:
- err = headerError{"Format specifies PAX", whyNoPAX, whyOnlyGNU}
- case FormatGNU:
- err = headerError{"Format specifies GNU", whyNoGNU, whyOnlyPAX}
- default:
- err = headerError{whyNoUSTAR, whyNoPAX, whyNoGNU, whyOnlyPAX, whyOnlyGNU}
- }
- }
- return format, paxHdrs, err
-}
-
-// FileInfo returns an fs.FileInfo for the Header.
-func (h *Header) FileInfo() fs.FileInfo {
- return headerFileInfo{h}
-}
-
-// headerFileInfo implements fs.FileInfo.
-type headerFileInfo struct {
- h *Header
-}
-
-func (fi headerFileInfo) Size() int64 { return fi.h.Size }
-func (fi headerFileInfo) IsDir() bool { return fi.Mode().IsDir() }
-func (fi headerFileInfo) ModTime() time.Time { return fi.h.ModTime }
-func (fi headerFileInfo) Sys() any { return fi.h }
-
-// Name returns the base name of the file.
-func (fi headerFileInfo) Name() string {
- if fi.IsDir() {
- return path.Base(path.Clean(fi.h.Name))
- }
- return path.Base(fi.h.Name)
-}
-
-// Mode returns the permission and mode bits for the headerFileInfo.
-func (fi headerFileInfo) Mode() (mode fs.FileMode) {
- // Set file permission bits.
- mode = fs.FileMode(fi.h.Mode).Perm()
-
- // Set setuid, setgid and sticky bits.
- if fi.h.Mode&c_ISUID != 0 {
- mode |= fs.ModeSetuid
- }
- if fi.h.Mode&c_ISGID != 0 {
- mode |= fs.ModeSetgid
- }
- if fi.h.Mode&c_ISVTX != 0 {
- mode |= fs.ModeSticky
- }
-
- // Set file mode bits; clear perm, setuid, setgid, and sticky bits.
- switch m := fs.FileMode(fi.h.Mode) &^ 07777; m {
- case c_ISDIR:
- mode |= fs.ModeDir
- case c_ISFIFO:
- mode |= fs.ModeNamedPipe
- case c_ISLNK:
- mode |= fs.ModeSymlink
- case c_ISBLK:
- mode |= fs.ModeDevice
- case c_ISCHR:
- mode |= fs.ModeDevice
- mode |= fs.ModeCharDevice
- case c_ISSOCK:
- mode |= fs.ModeSocket
- }
-
- switch fi.h.Typeflag {
- case TypeSymlink:
- mode |= fs.ModeSymlink
- case TypeChar:
- mode |= fs.ModeDevice
- mode |= fs.ModeCharDevice
- case TypeBlock:
- mode |= fs.ModeDevice
- case TypeDir:
- mode |= fs.ModeDir
- case TypeFifo:
- mode |= fs.ModeNamedPipe
- }
-
- return mode
-}
-
-// sysStat, if non-nil, populates h from system-dependent fields of fi.
-var sysStat func(fi fs.FileInfo, h *Header) error
-
-const (
- // Mode constants from the USTAR spec:
- // See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06
- c_ISUID = 04000 // Set uid
- c_ISGID = 02000 // Set gid
- c_ISVTX = 01000 // Save text (sticky bit)
-
- // Common Unix mode constants; these are not defined in any common tar standard.
- // Header.FileInfo understands these, but FileInfoHeader will never produce these.
- c_ISDIR = 040000 // Directory
- c_ISFIFO = 010000 // FIFO
- c_ISREG = 0100000 // Regular file
- c_ISLNK = 0120000 // Symbolic link
- c_ISBLK = 060000 // Block special file
- c_ISCHR = 020000 // Character special file
- c_ISSOCK = 0140000 // Socket
-)
-
-// FileInfoHeader creates a partially-populated Header from fi.
-// If fi describes a symlink, FileInfoHeader records link as the link target.
-// If fi describes a directory, a slash is appended to the name.
-//
-// Since fs.FileInfo's Name method only returns the base name of
-// the file it describes, it may be necessary to modify Header.Name
-// to provide the full path name of the file.
-func FileInfoHeader(fi fs.FileInfo, link string) (*Header, error) {
- if fi == nil {
- return nil, errors.New("archive/tar: FileInfo is nil")
- }
- fm := fi.Mode()
- h := &Header{
- Name: fi.Name(),
- ModTime: fi.ModTime(),
- Mode: int64(fm.Perm()), // or'd with c_IS* constants later
- }
- switch {
- case fm.IsRegular():
- h.Typeflag = TypeReg
- h.Size = fi.Size()
- case fi.IsDir():
- h.Typeflag = TypeDir
- h.Name += "/"
- case fm&fs.ModeSymlink != 0:
- h.Typeflag = TypeSymlink
- h.Linkname = link
- case fm&fs.ModeDevice != 0:
- if fm&fs.ModeCharDevice != 0 {
- h.Typeflag = TypeChar
- } else {
- h.Typeflag = TypeBlock
- }
- case fm&fs.ModeNamedPipe != 0:
- h.Typeflag = TypeFifo
- case fm&fs.ModeSocket != 0:
- return nil, fmt.Errorf("archive/tar: sockets not supported")
- default:
- return nil, fmt.Errorf("archive/tar: unknown file mode %v", fm)
- }
- if fm&fs.ModeSetuid != 0 {
- h.Mode |= c_ISUID
- }
- if fm&fs.ModeSetgid != 0 {
- h.Mode |= c_ISGID
- }
- if fm&fs.ModeSticky != 0 {
- h.Mode |= c_ISVTX
- }
- // If possible, populate additional fields from OS-specific
- // FileInfo fields.
- if sys, ok := fi.Sys().(*Header); ok {
- // This FileInfo came from a Header (not the OS). Use the
- // original Header to populate all remaining fields.
- h.Uid = sys.Uid
- h.Gid = sys.Gid
- h.Uname = sys.Uname
- h.Gname = sys.Gname
- h.AccessTime = sys.AccessTime
- h.ChangeTime = sys.ChangeTime
- if sys.Xattrs != nil {
- h.Xattrs = make(map[string]string)
- for k, v := range sys.Xattrs {
- h.Xattrs[k] = v
- }
- }
- if sys.Typeflag == TypeLink {
- // hard link
- h.Typeflag = TypeLink
- h.Size = 0
- h.Linkname = sys.Linkname
- }
- if sys.PAXRecords != nil {
- h.PAXRecords = make(map[string]string)
- for k, v := range sys.PAXRecords {
- h.PAXRecords[k] = v
- }
- }
- }
- if sysStat != nil {
- return h, sysStat(fi, h)
- }
- return h, nil
-}
-
-// isHeaderOnlyType checks if the given type flag is of the type that has no
-// data section even if a size is specified.
-func isHeaderOnlyType(flag byte) bool {
- switch flag {
- case TypeLink, TypeSymlink, TypeChar, TypeBlock, TypeDir, TypeFifo:
- return true
- default:
- return false
- }
-}
-
-func min(a, b int64) int64 {
- if a < b {
- return a
- }
- return b
-}
diff --git a/contrib/go/_std_1.20/src/archive/tar/reader.go b/contrib/go/_std_1.20/src/archive/tar/reader.go
deleted file mode 100644
index 768ca1968d..0000000000
--- a/contrib/go/_std_1.20/src/archive/tar/reader.go
+++ /dev/null
@@ -1,879 +0,0 @@
-// Copyright 2009 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 tar
-
-import (
- "bytes"
- "io"
- "path/filepath"
- "strconv"
- "strings"
- "time"
-)
-
-// Reader provides sequential access to the contents of a tar archive.
-// Reader.Next advances to the next file in the archive (including the first),
-// and then Reader can be treated as an io.Reader to access the file's data.
-type Reader struct {
- r io.Reader
- pad int64 // Amount of padding (ignored) after current file entry
- curr fileReader // Reader for current file entry
- blk block // Buffer to use as temporary local storage
-
- // err is a persistent error.
- // It is only the responsibility of every exported method of Reader to
- // ensure that this error is sticky.
- err error
-}
-
-type fileReader interface {
- io.Reader
- fileState
-
- WriteTo(io.Writer) (int64, error)
-}
-
-// NewReader creates a new Reader reading from r.
-func NewReader(r io.Reader) *Reader {
- return &Reader{r: r, curr: &regFileReader{r, 0}}
-}
-
-// Next advances to the next entry in the tar archive.
-// The Header.Size determines how many bytes can be read for the next file.
-// Any remaining data in the current file is automatically discarded.
-// At the end of the archive, Next returns the error io.EOF.
-//
-// If Next encounters a non-local name (as defined by [filepath.IsLocal])
-// and the GODEBUG environment variable contains `tarinsecurepath=0`,
-// Next returns the header with an ErrInsecurePath error.
-// A future version of Go may introduce this behavior by default.
-// Programs that want to accept non-local names can ignore
-// the ErrInsecurePath error and use the returned header.
-func (tr *Reader) Next() (*Header, error) {
- if tr.err != nil {
- return nil, tr.err
- }
- hdr, err := tr.next()
- tr.err = err
- if err == nil && tarinsecurepath.Value() == "0" && !filepath.IsLocal(hdr.Name) {
- err = ErrInsecurePath
- }
- return hdr, err
-}
-
-func (tr *Reader) next() (*Header, error) {
- var paxHdrs map[string]string
- var gnuLongName, gnuLongLink string
-
- // Externally, Next iterates through the tar archive as if it is a series of
- // files. Internally, the tar format often uses fake "files" to add meta
- // data that describes the next file. These meta data "files" should not
- // normally be visible to the outside. As such, this loop iterates through
- // one or more "header files" until it finds a "normal file".
- format := FormatUSTAR | FormatPAX | FormatGNU
- for {
- // Discard the remainder of the file and any padding.
- if err := discard(tr.r, tr.curr.physicalRemaining()); err != nil {
- return nil, err
- }
- if _, err := tryReadFull(tr.r, tr.blk[:tr.pad]); err != nil {
- return nil, err
- }
- tr.pad = 0
-
- hdr, rawHdr, err := tr.readHeader()
- if err != nil {
- return nil, err
- }
- if err := tr.handleRegularFile(hdr); err != nil {
- return nil, err
- }
- format.mayOnlyBe(hdr.Format)
-
- // Check for PAX/GNU special headers and files.
- switch hdr.Typeflag {
- case TypeXHeader, TypeXGlobalHeader:
- format.mayOnlyBe(FormatPAX)
- paxHdrs, err = parsePAX(tr)
- if err != nil {
- return nil, err
- }
- if hdr.Typeflag == TypeXGlobalHeader {
- mergePAX(hdr, paxHdrs)
- return &Header{
- Name: hdr.Name,
- Typeflag: hdr.Typeflag,
- Xattrs: hdr.Xattrs,
- PAXRecords: hdr.PAXRecords,
- Format: format,
- }, nil
- }
- continue // This is a meta header affecting the next header
- case TypeGNULongName, TypeGNULongLink:
- format.mayOnlyBe(FormatGNU)
- realname, err := readSpecialFile(tr)
- if err != nil {
- return nil, err
- }
-
- var p parser
- switch hdr.Typeflag {
- case TypeGNULongName:
- gnuLongName = p.parseString(realname)
- case TypeGNULongLink:
- gnuLongLink = p.parseString(realname)
- }
- continue // This is a meta header affecting the next header
- default:
- // The old GNU sparse format is handled here since it is technically
- // just a regular file with additional attributes.
-
- if err := mergePAX(hdr, paxHdrs); err != nil {
- return nil, err
- }
- if gnuLongName != "" {
- hdr.Name = gnuLongName
- }
- if gnuLongLink != "" {
- hdr.Linkname = gnuLongLink
- }
- if hdr.Typeflag == TypeRegA {
- if strings.HasSuffix(hdr.Name, "/") {
- hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories
- } else {
- hdr.Typeflag = TypeReg
- }
- }
-
- // The extended headers may have updated the size.
- // Thus, setup the regFileReader again after merging PAX headers.
- if err := tr.handleRegularFile(hdr); err != nil {
- return nil, err
- }
-
- // Sparse formats rely on being able to read from the logical data
- // section; there must be a preceding call to handleRegularFile.
- if err := tr.handleSparseFile(hdr, rawHdr); err != nil {
- return nil, err
- }
-
- // Set the final guess at the format.
- if format.has(FormatUSTAR) && format.has(FormatPAX) {
- format.mayOnlyBe(FormatUSTAR)
- }
- hdr.Format = format
- return hdr, nil // This is a file, so stop
- }
- }
-}
-
-// handleRegularFile sets up the current file reader and padding such that it
-// can only read the following logical data section. It will properly handle
-// special headers that contain no data section.
-func (tr *Reader) handleRegularFile(hdr *Header) error {
- nb := hdr.Size
- if isHeaderOnlyType(hdr.Typeflag) {
- nb = 0
- }
- if nb < 0 {
- return ErrHeader
- }
-
- tr.pad = blockPadding(nb)
- tr.curr = &regFileReader{r: tr.r, nb: nb}
- return nil
-}
-
-// handleSparseFile checks if the current file is a sparse format of any type
-// and sets the curr reader appropriately.
-func (tr *Reader) handleSparseFile(hdr *Header, rawHdr *block) error {
- var spd sparseDatas
- var err error
- if hdr.Typeflag == TypeGNUSparse {
- spd, err = tr.readOldGNUSparseMap(hdr, rawHdr)
- } else {
- spd, err = tr.readGNUSparsePAXHeaders(hdr)
- }
-
- // If sp is non-nil, then this is a sparse file.
- // Note that it is possible for len(sp) == 0.
- if err == nil && spd != nil {
- if isHeaderOnlyType(hdr.Typeflag) || !validateSparseEntries(spd, hdr.Size) {
- return ErrHeader
- }
- sph := invertSparseEntries(spd, hdr.Size)
- tr.curr = &sparseFileReader{tr.curr, sph, 0}
- }
- return err
-}
-
-// readGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers.
-// If they are found, then this function reads the sparse map and returns it.
-// This assumes that 0.0 headers have already been converted to 0.1 headers
-// by the PAX header parsing logic.
-func (tr *Reader) readGNUSparsePAXHeaders(hdr *Header) (sparseDatas, error) {
- // Identify the version of GNU headers.
- var is1x0 bool
- major, minor := hdr.PAXRecords[paxGNUSparseMajor], hdr.PAXRecords[paxGNUSparseMinor]
- switch {
- case major == "0" && (minor == "0" || minor == "1"):
- is1x0 = false
- case major == "1" && minor == "0":
- is1x0 = true
- case major != "" || minor != "":
- return nil, nil // Unknown GNU sparse PAX version
- case hdr.PAXRecords[paxGNUSparseMap] != "":
- is1x0 = false // 0.0 and 0.1 did not have explicit version records, so guess
- default:
- return nil, nil // Not a PAX format GNU sparse file.
- }
- hdr.Format.mayOnlyBe(FormatPAX)
-
- // Update hdr from GNU sparse PAX headers.
- if name := hdr.PAXRecords[paxGNUSparseName]; name != "" {
- hdr.Name = name
- }
- size := hdr.PAXRecords[paxGNUSparseSize]
- if size == "" {
- size = hdr.PAXRecords[paxGNUSparseRealSize]
- }
- if size != "" {
- n, err := strconv.ParseInt(size, 10, 64)
- if err != nil {
- return nil, ErrHeader
- }
- hdr.Size = n
- }
-
- // Read the sparse map according to the appropriate format.
- if is1x0 {
- return readGNUSparseMap1x0(tr.curr)
- }
- return readGNUSparseMap0x1(hdr.PAXRecords)
-}
-
-// mergePAX merges paxHdrs into hdr for all relevant fields of Header.
-func mergePAX(hdr *Header, paxHdrs map[string]string) (err error) {
- for k, v := range paxHdrs {
- if v == "" {
- continue // Keep the original USTAR value
- }
- var id64 int64
- switch k {
- case paxPath:
- hdr.Name = v
- case paxLinkpath:
- hdr.Linkname = v
- case paxUname:
- hdr.Uname = v
- case paxGname:
- hdr.Gname = v
- case paxUid:
- id64, err = strconv.ParseInt(v, 10, 64)
- hdr.Uid = int(id64) // Integer overflow possible
- case paxGid:
- id64, err = strconv.ParseInt(v, 10, 64)
- hdr.Gid = int(id64) // Integer overflow possible
- case paxAtime:
- hdr.AccessTime, err = parsePAXTime(v)
- case paxMtime:
- hdr.ModTime, err = parsePAXTime(v)
- case paxCtime:
- hdr.ChangeTime, err = parsePAXTime(v)
- case paxSize:
- hdr.Size, err = strconv.ParseInt(v, 10, 64)
- default:
- if strings.HasPrefix(k, paxSchilyXattr) {
- if hdr.Xattrs == nil {
- hdr.Xattrs = make(map[string]string)
- }
- hdr.Xattrs[k[len(paxSchilyXattr):]] = v
- }
- }
- if err != nil {
- return ErrHeader
- }
- }
- hdr.PAXRecords = paxHdrs
- return nil
-}
-
-// parsePAX parses PAX headers.
-// If an extended header (type 'x') is invalid, ErrHeader is returned.
-func parsePAX(r io.Reader) (map[string]string, error) {
- buf, err := readSpecialFile(r)
- if err != nil {
- return nil, err
- }
- sbuf := string(buf)
-
- // For GNU PAX sparse format 0.0 support.
- // This function transforms the sparse format 0.0 headers into format 0.1
- // headers since 0.0 headers were not PAX compliant.
- var sparseMap []string
-
- paxHdrs := make(map[string]string)
- for len(sbuf) > 0 {
- key, value, residual, err := parsePAXRecord(sbuf)
- if err != nil {
- return nil, ErrHeader
- }
- sbuf = residual
-
- switch key {
- case paxGNUSparseOffset, paxGNUSparseNumBytes:
- // Validate sparse header order and value.
- if (len(sparseMap)%2 == 0 && key != paxGNUSparseOffset) ||
- (len(sparseMap)%2 == 1 && key != paxGNUSparseNumBytes) ||
- strings.Contains(value, ",") {
- return nil, ErrHeader
- }
- sparseMap = append(sparseMap, value)
- default:
- paxHdrs[key] = value
- }
- }
- if len(sparseMap) > 0 {
- paxHdrs[paxGNUSparseMap] = strings.Join(sparseMap, ",")
- }
- return paxHdrs, nil
-}
-
-// readHeader reads the next block header and assumes that the underlying reader
-// is already aligned to a block boundary. It returns the raw block of the
-// header in case further processing is required.
-//
-// The err will be set to io.EOF only when one of the following occurs:
-// - Exactly 0 bytes are read and EOF is hit.
-// - Exactly 1 block of zeros is read and EOF is hit.
-// - At least 2 blocks of zeros are read.
-func (tr *Reader) readHeader() (*Header, *block, error) {
- // Two blocks of zero bytes marks the end of the archive.
- if _, err := io.ReadFull(tr.r, tr.blk[:]); err != nil {
- return nil, nil, err // EOF is okay here; exactly 0 bytes read
- }
- if bytes.Equal(tr.blk[:], zeroBlock[:]) {
- if _, err := io.ReadFull(tr.r, tr.blk[:]); err != nil {
- return nil, nil, err // EOF is okay here; exactly 1 block of zeros read
- }
- if bytes.Equal(tr.blk[:], zeroBlock[:]) {
- return nil, nil, io.EOF // normal EOF; exactly 2 block of zeros read
- }
- return nil, nil, ErrHeader // Zero block and then non-zero block
- }
-
- // Verify the header matches a known format.
- format := tr.blk.getFormat()
- if format == FormatUnknown {
- return nil, nil, ErrHeader
- }
-
- var p parser
- hdr := new(Header)
-
- // Unpack the V7 header.
- v7 := tr.blk.toV7()
- hdr.Typeflag = v7.typeFlag()[0]
- hdr.Name = p.parseString(v7.name())
- hdr.Linkname = p.parseString(v7.linkName())
- hdr.Size = p.parseNumeric(v7.size())
- hdr.Mode = p.parseNumeric(v7.mode())
- hdr.Uid = int(p.parseNumeric(v7.uid()))
- hdr.Gid = int(p.parseNumeric(v7.gid()))
- hdr.ModTime = time.Unix(p.parseNumeric(v7.modTime()), 0)
-
- // Unpack format specific fields.
- if format > formatV7 {
- ustar := tr.blk.toUSTAR()
- hdr.Uname = p.parseString(ustar.userName())
- hdr.Gname = p.parseString(ustar.groupName())
- hdr.Devmajor = p.parseNumeric(ustar.devMajor())
- hdr.Devminor = p.parseNumeric(ustar.devMinor())
-
- var prefix string
- switch {
- case format.has(FormatUSTAR | FormatPAX):
- hdr.Format = format
- ustar := tr.blk.toUSTAR()
- prefix = p.parseString(ustar.prefix())
-
- // For Format detection, check if block is properly formatted since
- // the parser is more liberal than what USTAR actually permits.
- notASCII := func(r rune) bool { return r >= 0x80 }
- if bytes.IndexFunc(tr.blk[:], notASCII) >= 0 {
- hdr.Format = FormatUnknown // Non-ASCII characters in block.
- }
- nul := func(b []byte) bool { return int(b[len(b)-1]) == 0 }
- if !(nul(v7.size()) && nul(v7.mode()) && nul(v7.uid()) && nul(v7.gid()) &&
- nul(v7.modTime()) && nul(ustar.devMajor()) && nul(ustar.devMinor())) {
- hdr.Format = FormatUnknown // Numeric fields must end in NUL
- }
- case format.has(formatSTAR):
- star := tr.blk.toSTAR()
- prefix = p.parseString(star.prefix())
- hdr.AccessTime = time.Unix(p.parseNumeric(star.accessTime()), 0)
- hdr.ChangeTime = time.Unix(p.parseNumeric(star.changeTime()), 0)
- case format.has(FormatGNU):
- hdr.Format = format
- var p2 parser
- gnu := tr.blk.toGNU()
- if b := gnu.accessTime(); b[0] != 0 {
- hdr.AccessTime = time.Unix(p2.parseNumeric(b), 0)
- }
- if b := gnu.changeTime(); b[0] != 0 {
- hdr.ChangeTime = time.Unix(p2.parseNumeric(b), 0)
- }
-
- // Prior to Go1.8, the Writer had a bug where it would output
- // an invalid tar file in certain rare situations because the logic
- // incorrectly believed that the old GNU format had a prefix field.
- // This is wrong and leads to an output file that mangles the
- // atime and ctime fields, which are often left unused.
- //
- // In order to continue reading tar files created by former, buggy
- // versions of Go, we skeptically parse the atime and ctime fields.
- // If we are unable to parse them and the prefix field looks like
- // an ASCII string, then we fallback on the pre-Go1.8 behavior
- // of treating these fields as the USTAR prefix field.
- //
- // Note that this will not use the fallback logic for all possible
- // files generated by a pre-Go1.8 toolchain. If the generated file
- // happened to have a prefix field that parses as valid
- // atime and ctime fields (e.g., when they are valid octal strings),
- // then it is impossible to distinguish between a valid GNU file
- // and an invalid pre-Go1.8 file.
- //
- // See https://golang.org/issues/12594
- // See https://golang.org/issues/21005
- if p2.err != nil {
- hdr.AccessTime, hdr.ChangeTime = time.Time{}, time.Time{}
- ustar := tr.blk.toUSTAR()
- if s := p.parseString(ustar.prefix()); isASCII(s) {
- prefix = s
- }
- hdr.Format = FormatUnknown // Buggy file is not GNU
- }
- }
- if len(prefix) > 0 {
- hdr.Name = prefix + "/" + hdr.Name
- }
- }
- return hdr, &tr.blk, p.err
-}
-
-// readOldGNUSparseMap reads the sparse map from the old GNU sparse format.
-// The sparse map is stored in the tar header if it's small enough.
-// If it's larger than four entries, then one or more extension headers are used
-// to store the rest of the sparse map.
-//
-// The Header.Size does not reflect the size of any extended headers used.
-// Thus, this function will read from the raw io.Reader to fetch extra headers.
-// This method mutates blk in the process.
-func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, error) {
- // Make sure that the input format is GNU.
- // Unfortunately, the STAR format also has a sparse header format that uses
- // the same type flag but has a completely different layout.
- if blk.getFormat() != FormatGNU {
- return nil, ErrHeader
- }
- hdr.Format.mayOnlyBe(FormatGNU)
-
- var p parser
- hdr.Size = p.parseNumeric(blk.toGNU().realSize())
- if p.err != nil {
- return nil, p.err
- }
- s := blk.toGNU().sparse()
- spd := make(sparseDatas, 0, s.maxEntries())
- for {
- for i := 0; i < s.maxEntries(); i++ {
- // This termination condition is identical to GNU and BSD tar.
- if s.entry(i).offset()[0] == 0x00 {
- break // Don't return, need to process extended headers (even if empty)
- }
- offset := p.parseNumeric(s.entry(i).offset())
- length := p.parseNumeric(s.entry(i).length())
- if p.err != nil {
- return nil, p.err
- }
- spd = append(spd, sparseEntry{Offset: offset, Length: length})
- }
-
- if s.isExtended()[0] > 0 {
- // There are more entries. Read an extension header and parse its entries.
- if _, err := mustReadFull(tr.r, blk[:]); err != nil {
- return nil, err
- }
- s = blk.toSparse()
- continue
- }
- return spd, nil // Done
- }
-}
-
-// readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format
-// version 1.0. The format of the sparse map consists of a series of
-// newline-terminated numeric fields. The first field is the number of entries
-// and is always present. Following this are the entries, consisting of two
-// fields (offset, length). This function must stop reading at the end
-// boundary of the block containing the last newline.
-//
-// Note that the GNU manual says that numeric values should be encoded in octal
-// format. However, the GNU tar utility itself outputs these values in decimal.
-// As such, this library treats values as being encoded in decimal.
-func readGNUSparseMap1x0(r io.Reader) (sparseDatas, error) {
- var (
- cntNewline int64
- buf bytes.Buffer
- blk block
- )
-
- // feedTokens copies data in blocks from r into buf until there are
- // at least cnt newlines in buf. It will not read more blocks than needed.
- feedTokens := func(n int64) error {
- for cntNewline < n {
- if _, err := mustReadFull(r, blk[:]); err != nil {
- return err
- }
- buf.Write(blk[:])
- for _, c := range blk {
- if c == '\n' {
- cntNewline++
- }
- }
- }
- return nil
- }
-
- // nextToken gets the next token delimited by a newline. This assumes that
- // at least one newline exists in the buffer.
- nextToken := func() string {
- cntNewline--
- tok, _ := buf.ReadString('\n')
- return strings.TrimRight(tok, "\n")
- }
-
- // Parse for the number of entries.
- // Use integer overflow resistant math to check this.
- if err := feedTokens(1); err != nil {
- return nil, err
- }
- numEntries, err := strconv.ParseInt(nextToken(), 10, 0) // Intentionally parse as native int
- if err != nil || numEntries < 0 || int(2*numEntries) < int(numEntries) {
- return nil, ErrHeader
- }
-
- // Parse for all member entries.
- // numEntries is trusted after this since a potential attacker must have
- // committed resources proportional to what this library used.
- if err := feedTokens(2 * numEntries); err != nil {
- return nil, err
- }
- spd := make(sparseDatas, 0, numEntries)
- for i := int64(0); i < numEntries; i++ {
- offset, err1 := strconv.ParseInt(nextToken(), 10, 64)
- length, err2 := strconv.ParseInt(nextToken(), 10, 64)
- if err1 != nil || err2 != nil {
- return nil, ErrHeader
- }
- spd = append(spd, sparseEntry{Offset: offset, Length: length})
- }
- return spd, nil
-}
-
-// readGNUSparseMap0x1 reads the sparse map as stored in GNU's PAX sparse format
-// version 0.1. The sparse map is stored in the PAX headers.
-func readGNUSparseMap0x1(paxHdrs map[string]string) (sparseDatas, error) {
- // Get number of entries.
- // Use integer overflow resistant math to check this.
- numEntriesStr := paxHdrs[paxGNUSparseNumBlocks]
- numEntries, err := strconv.ParseInt(numEntriesStr, 10, 0) // Intentionally parse as native int
- if err != nil || numEntries < 0 || int(2*numEntries) < int(numEntries) {
- return nil, ErrHeader
- }
-
- // There should be two numbers in sparseMap for each entry.
- sparseMap := strings.Split(paxHdrs[paxGNUSparseMap], ",")
- if len(sparseMap) == 1 && sparseMap[0] == "" {
- sparseMap = sparseMap[:0]
- }
- if int64(len(sparseMap)) != 2*numEntries {
- return nil, ErrHeader
- }
-
- // Loop through the entries in the sparse map.
- // numEntries is trusted now.
- spd := make(sparseDatas, 0, numEntries)
- for len(sparseMap) >= 2 {
- offset, err1 := strconv.ParseInt(sparseMap[0], 10, 64)
- length, err2 := strconv.ParseInt(sparseMap[1], 10, 64)
- if err1 != nil || err2 != nil {
- return nil, ErrHeader
- }
- spd = append(spd, sparseEntry{Offset: offset, Length: length})
- sparseMap = sparseMap[2:]
- }
- return spd, nil
-}
-
-// Read reads from the current file in the tar archive.
-// It returns (0, io.EOF) when it reaches the end of that file,
-// until Next is called to advance to the next file.
-//
-// If the current file is sparse, then the regions marked as a hole
-// are read back as NUL-bytes.
-//
-// Calling Read on special types like TypeLink, TypeSymlink, TypeChar,
-// TypeBlock, TypeDir, and TypeFifo returns (0, io.EOF) regardless of what
-// the Header.Size claims.
-func (tr *Reader) Read(b []byte) (int, error) {
- if tr.err != nil {
- return 0, tr.err
- }
- n, err := tr.curr.Read(b)
- if err != nil && err != io.EOF {
- tr.err = err
- }
- return n, err
-}
-
-// writeTo writes the content of the current file to w.
-// The bytes written matches the number of remaining bytes in the current file.
-//
-// If the current file is sparse and w is an io.WriteSeeker,
-// then writeTo uses Seek to skip past holes defined in Header.SparseHoles,
-// assuming that skipped regions are filled with NULs.
-// This always writes the last byte to ensure w is the right size.
-//
-// TODO(dsnet): Re-export this when adding sparse file support.
-// See https://golang.org/issue/22735
-func (tr *Reader) writeTo(w io.Writer) (int64, error) {
- if tr.err != nil {
- return 0, tr.err
- }
- n, err := tr.curr.WriteTo(w)
- if err != nil {
- tr.err = err
- }
- return n, err
-}
-
-// regFileReader is a fileReader for reading data from a regular file entry.
-type regFileReader struct {
- r io.Reader // Underlying Reader
- nb int64 // Number of remaining bytes to read
-}
-
-func (fr *regFileReader) Read(b []byte) (n int, err error) {
- if int64(len(b)) > fr.nb {
- b = b[:fr.nb]
- }
- if len(b) > 0 {
- n, err = fr.r.Read(b)
- fr.nb -= int64(n)
- }
- switch {
- case err == io.EOF && fr.nb > 0:
- return n, io.ErrUnexpectedEOF
- case err == nil && fr.nb == 0:
- return n, io.EOF
- default:
- return n, err
- }
-}
-
-func (fr *regFileReader) WriteTo(w io.Writer) (int64, error) {
- return io.Copy(w, struct{ io.Reader }{fr})
-}
-
-// logicalRemaining implements fileState.logicalRemaining.
-func (fr regFileReader) logicalRemaining() int64 {
- return fr.nb
-}
-
-// physicalRemaining implements fileState.physicalRemaining.
-func (fr regFileReader) physicalRemaining() int64 {
- return fr.nb
-}
-
-// sparseFileReader is a fileReader for reading data from a sparse file entry.
-type sparseFileReader struct {
- fr fileReader // Underlying fileReader
- sp sparseHoles // Normalized list of sparse holes
- pos int64 // Current position in sparse file
-}
-
-func (sr *sparseFileReader) Read(b []byte) (n int, err error) {
- finished := int64(len(b)) >= sr.logicalRemaining()
- if finished {
- b = b[:sr.logicalRemaining()]
- }
-
- b0 := b
- endPos := sr.pos + int64(len(b))
- for endPos > sr.pos && err == nil {
- var nf int // Bytes read in fragment
- holeStart, holeEnd := sr.sp[0].Offset, sr.sp[0].endOffset()
- if sr.pos < holeStart { // In a data fragment
- bf := b[:min(int64(len(b)), holeStart-sr.pos)]
- nf, err = tryReadFull(sr.fr, bf)
- } else { // In a hole fragment
- bf := b[:min(int64(len(b)), holeEnd-sr.pos)]
- nf, err = tryReadFull(zeroReader{}, bf)
- }
- b = b[nf:]
- sr.pos += int64(nf)
- if sr.pos >= holeEnd && len(sr.sp) > 1 {
- sr.sp = sr.sp[1:] // Ensure last fragment always remains
- }
- }
-
- n = len(b0) - len(b)
- switch {
- case err == io.EOF:
- return n, errMissData // Less data in dense file than sparse file
- case err != nil:
- return n, err
- case sr.logicalRemaining() == 0 && sr.physicalRemaining() > 0:
- return n, errUnrefData // More data in dense file than sparse file
- case finished:
- return n, io.EOF
- default:
- return n, nil
- }
-}
-
-func (sr *sparseFileReader) WriteTo(w io.Writer) (n int64, err error) {
- ws, ok := w.(io.WriteSeeker)
- if ok {
- if _, err := ws.Seek(0, io.SeekCurrent); err != nil {
- ok = false // Not all io.Seeker can really seek
- }
- }
- if !ok {
- return io.Copy(w, struct{ io.Reader }{sr})
- }
-
- var writeLastByte bool
- pos0 := sr.pos
- for sr.logicalRemaining() > 0 && !writeLastByte && err == nil {
- var nf int64 // Size of fragment
- holeStart, holeEnd := sr.sp[0].Offset, sr.sp[0].endOffset()
- if sr.pos < holeStart { // In a data fragment
- nf = holeStart - sr.pos
- nf, err = io.CopyN(ws, sr.fr, nf)
- } else { // In a hole fragment
- nf = holeEnd - sr.pos
- if sr.physicalRemaining() == 0 {
- writeLastByte = true
- nf--
- }
- _, err = ws.Seek(nf, io.SeekCurrent)
- }
- sr.pos += nf
- if sr.pos >= holeEnd && len(sr.sp) > 1 {
- sr.sp = sr.sp[1:] // Ensure last fragment always remains
- }
- }
-
- // If the last fragment is a hole, then seek to 1-byte before EOF, and
- // write a single byte to ensure the file is the right size.
- if writeLastByte && err == nil {
- _, err = ws.Write([]byte{0})
- sr.pos++
- }
-
- n = sr.pos - pos0
- switch {
- case err == io.EOF:
- return n, errMissData // Less data in dense file than sparse file
- case err != nil:
- return n, err
- case sr.logicalRemaining() == 0 && sr.physicalRemaining() > 0:
- return n, errUnrefData // More data in dense file than sparse file
- default:
- return n, nil
- }
-}
-
-func (sr sparseFileReader) logicalRemaining() int64 {
- return sr.sp[len(sr.sp)-1].endOffset() - sr.pos
-}
-func (sr sparseFileReader) physicalRemaining() int64 {
- return sr.fr.physicalRemaining()
-}
-
-type zeroReader struct{}
-
-func (zeroReader) Read(b []byte) (int, error) {
- for i := range b {
- b[i] = 0
- }
- return len(b), nil
-}
-
-// mustReadFull is like io.ReadFull except it returns
-// io.ErrUnexpectedEOF when io.EOF is hit before len(b) bytes are read.
-func mustReadFull(r io.Reader, b []byte) (int, error) {
- n, err := tryReadFull(r, b)
- if err == io.EOF {
- err = io.ErrUnexpectedEOF
- }
- return n, err
-}
-
-// tryReadFull is like io.ReadFull except it returns
-// io.EOF when it is hit before len(b) bytes are read.
-func tryReadFull(r io.Reader, b []byte) (n int, err error) {
- for len(b) > n && err == nil {
- var nn int
- nn, err = r.Read(b[n:])
- n += nn
- }
- if len(b) == n && err == io.EOF {
- err = nil
- }
- return n, err
-}
-
-// readSpecialFile is like io.ReadAll except it returns
-// ErrFieldTooLong if more than maxSpecialFileSize is read.
-func readSpecialFile(r io.Reader) ([]byte, error) {
- buf, err := io.ReadAll(io.LimitReader(r, maxSpecialFileSize+1))
- if len(buf) > maxSpecialFileSize {
- return nil, ErrFieldTooLong
- }
- return buf, err
-}
-
-// discard skips n bytes in r, reporting an error if unable to do so.
-func discard(r io.Reader, n int64) error {
- // If possible, Seek to the last byte before the end of the data section.
- // Do this because Seek is often lazy about reporting errors; this will mask
- // the fact that the stream may be truncated. We can rely on the
- // io.CopyN done shortly afterwards to trigger any IO errors.
- var seekSkipped int64 // Number of bytes skipped via Seek
- if sr, ok := r.(io.Seeker); ok && n > 1 {
- // Not all io.Seeker can actually Seek. For example, os.Stdin implements
- // io.Seeker, but calling Seek always returns an error and performs
- // no action. Thus, we try an innocent seek to the current position
- // to see if Seek is really supported.
- pos1, err := sr.Seek(0, io.SeekCurrent)
- if pos1 >= 0 && err == nil {
- // Seek seems supported, so perform the real Seek.
- pos2, err := sr.Seek(n-1, io.SeekCurrent)
- if pos2 < 0 || err != nil {
- return err
- }
- seekSkipped = pos2 - pos1
- }
- }
-
- copySkipped, err := io.CopyN(io.Discard, r, n-seekSkipped)
- if err == io.EOF && seekSkipped+copySkipped < n {
- err = io.ErrUnexpectedEOF
- }
- return err
-}
diff --git a/contrib/go/_std_1.20/src/archive/tar/ya.make b/contrib/go/_std_1.20/src/archive/tar/ya.make
deleted file mode 100644
index 1e58918832..0000000000
--- a/contrib/go/_std_1.20/src/archive/tar/ya.make
+++ /dev/null
@@ -1,25 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- common.go
- format.go
- reader.go
- strconv.go
- writer.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- stat_actime2.go
- stat_unix.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- stat_actime1.go
- stat_unix.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/archive/zip/reader.go b/contrib/go/_std_1.20/src/archive/zip/reader.go
deleted file mode 100644
index a1554d2c52..0000000000
--- a/contrib/go/_std_1.20/src/archive/zip/reader.go
+++ /dev/null
@@ -1,961 +0,0 @@
-// Copyright 2010 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 zip
-
-import (
- "bufio"
- "encoding/binary"
- "errors"
- "hash"
- "hash/crc32"
- "internal/godebug"
- "io"
- "io/fs"
- "os"
- "path"
- "path/filepath"
- "sort"
- "strings"
- "sync"
- "time"
-)
-
-var zipinsecurepath = godebug.New("zipinsecurepath")
-
-var (
- ErrFormat = errors.New("zip: not a valid zip file")
- ErrAlgorithm = errors.New("zip: unsupported compression algorithm")
- ErrChecksum = errors.New("zip: checksum error")
- ErrInsecurePath = errors.New("zip: insecure file path")
-)
-
-// A Reader serves content from a ZIP archive.
-type Reader struct {
- r io.ReaderAt
- File []*File
- Comment string
- decompressors map[uint16]Decompressor
-
- // Some JAR files are zip files with a prefix that is a bash script.
- // The baseOffset field is the start of the zip file proper.
- baseOffset int64
-
- // fileList is a list of files sorted by ename,
- // for use by the Open method.
- fileListOnce sync.Once
- fileList []fileListEntry
-}
-
-// A ReadCloser is a Reader that must be closed when no longer needed.
-type ReadCloser struct {
- f *os.File
- Reader
-}
-
-// A File is a single file in a ZIP archive.
-// The file information is in the embedded FileHeader.
-// The file content can be accessed by calling Open.
-type File struct {
- FileHeader
- zip *Reader
- zipr io.ReaderAt
- headerOffset int64 // includes overall ZIP archive baseOffset
- zip64 bool // zip64 extended information extra field presence
-}
-
-// OpenReader will open the Zip file specified by name and return a ReadCloser.
-func OpenReader(name string) (*ReadCloser, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- fi, err := f.Stat()
- if err != nil {
- f.Close()
- return nil, err
- }
- r := new(ReadCloser)
- if err := r.init(f, fi.Size()); err != nil {
- f.Close()
- return nil, err
- }
- r.f = f
- return r, nil
-}
-
-// NewReader returns a new Reader reading from r, which is assumed to
-// have the given size in bytes.
-//
-// If any file inside the archive uses a non-local name
-// (as defined by [filepath.IsLocal]) or a name containing backslashes
-// and the GODEBUG environment variable contains `zipinsecurepath=0`,
-// NewReader returns the reader with an ErrInsecurePath error.
-// A future version of Go may introduce this behavior by default.
-// Programs that want to accept non-local names can ignore
-// the ErrInsecurePath error and use the returned reader.
-func NewReader(r io.ReaderAt, size int64) (*Reader, error) {
- if size < 0 {
- return nil, errors.New("zip: size cannot be negative")
- }
- zr := new(Reader)
- if err := zr.init(r, size); err != nil {
- return nil, err
- }
- for _, f := range zr.File {
- if f.Name == "" {
- // Zip permits an empty file name field.
- continue
- }
- if zipinsecurepath.Value() != "0" {
- continue
- }
- // The zip specification states that names must use forward slashes,
- // so consider any backslashes in the name insecure.
- if !filepath.IsLocal(f.Name) || strings.Contains(f.Name, `\`) {
- return zr, ErrInsecurePath
- }
- }
- return zr, nil
-}
-
-func (z *Reader) init(r io.ReaderAt, size int64) error {
- end, baseOffset, err := readDirectoryEnd(r, size)
- if err != nil {
- return err
- }
- z.r = r
- z.baseOffset = baseOffset
- // Since the number of directory records is not validated, it is not
- // safe to preallocate z.File without first checking that the specified
- // number of files is reasonable, since a malformed archive may
- // indicate it contains up to 1 << 128 - 1 files. Since each file has a
- // header which will be _at least_ 30 bytes we can safely preallocate
- // if (data size / 30) >= end.directoryRecords.
- if end.directorySize < uint64(size) && (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
- z.File = make([]*File, 0, end.directoryRecords)
- }
- z.Comment = end.comment
- rs := io.NewSectionReader(r, 0, size)
- if _, err = rs.Seek(z.baseOffset+int64(end.directoryOffset), io.SeekStart); err != nil {
- return err
- }
- buf := bufio.NewReader(rs)
-
- // The count of files inside a zip is truncated to fit in a uint16.
- // Gloss over this by reading headers until we encounter
- // a bad one, and then only report an ErrFormat or UnexpectedEOF if
- // the file count modulo 65536 is incorrect.
- for {
- f := &File{zip: z, zipr: r}
- err = readDirectoryHeader(f, buf)
-
- // For compatibility with other zip programs,
- // if we have a non-zero base offset and can't read
- // the first directory header, try again with a zero
- // base offset.
- if err == ErrFormat && z.baseOffset != 0 && len(z.File) == 0 {
- z.baseOffset = 0
- if _, err = rs.Seek(int64(end.directoryOffset), io.SeekStart); err != nil {
- return err
- }
- buf.Reset(rs)
- continue
- }
-
- if err == ErrFormat || err == io.ErrUnexpectedEOF {
- break
- }
- if err != nil {
- return err
- }
- f.headerOffset += z.baseOffset
- z.File = append(z.File, f)
- }
- if uint16(len(z.File)) != uint16(end.directoryRecords) { // only compare 16 bits here
- // Return the readDirectoryHeader error if we read
- // the wrong number of directory entries.
- return err
- }
- return nil
-}
-
-// RegisterDecompressor registers or overrides a custom decompressor for a
-// specific method ID. If a decompressor for a given method is not found,
-// Reader will default to looking up the decompressor at the package level.
-func (z *Reader) RegisterDecompressor(method uint16, dcomp Decompressor) {
- if z.decompressors == nil {
- z.decompressors = make(map[uint16]Decompressor)
- }
- z.decompressors[method] = dcomp
-}
-
-func (z *Reader) decompressor(method uint16) Decompressor {
- dcomp := z.decompressors[method]
- if dcomp == nil {
- dcomp = decompressor(method)
- }
- return dcomp
-}
-
-// Close closes the Zip file, rendering it unusable for I/O.
-func (rc *ReadCloser) Close() error {
- return rc.f.Close()
-}
-
-// DataOffset returns the offset of the file's possibly-compressed
-// data, relative to the beginning of the zip file.
-//
-// Most callers should instead use Open, which transparently
-// decompresses data and verifies checksums.
-func (f *File) DataOffset() (offset int64, err error) {
- bodyOffset, err := f.findBodyOffset()
- if err != nil {
- return
- }
- return f.headerOffset + bodyOffset, nil
-}
-
-// Open returns a ReadCloser that provides access to the File's contents.
-// Multiple files may be read concurrently.
-func (f *File) Open() (io.ReadCloser, error) {
- bodyOffset, err := f.findBodyOffset()
- if err != nil {
- return nil, err
- }
- if strings.HasSuffix(f.Name, "/") {
- // The ZIP specification (APPNOTE.TXT) specifies that directories, which
- // are technically zero-byte files, must not have any associated file
- // data. We previously tried failing here if f.CompressedSize64 != 0,
- // but it turns out that a number of implementations (namely, the Java
- // jar tool) don't properly set the storage method on directories
- // resulting in a file with compressed size > 0 but uncompressed size ==
- // 0. We still want to fail when a directory has associated uncompressed
- // data, but we are tolerant of cases where the uncompressed size is
- // zero but compressed size is not.
- if f.UncompressedSize64 != 0 {
- return &dirReader{ErrFormat}, nil
- } else {
- return &dirReader{io.EOF}, nil
- }
- }
- size := int64(f.CompressedSize64)
- r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, size)
- dcomp := f.zip.decompressor(f.Method)
- if dcomp == nil {
- return nil, ErrAlgorithm
- }
- var rc io.ReadCloser = dcomp(r)
- var desr io.Reader
- if f.hasDataDescriptor() {
- desr = io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+size, dataDescriptorLen)
- }
- rc = &checksumReader{
- rc: rc,
- hash: crc32.NewIEEE(),
- f: f,
- desr: desr,
- }
- return rc, nil
-}
-
-// OpenRaw returns a Reader that provides access to the File's contents without
-// decompression.
-func (f *File) OpenRaw() (io.Reader, error) {
- bodyOffset, err := f.findBodyOffset()
- if err != nil {
- return nil, err
- }
- r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, int64(f.CompressedSize64))
- return r, nil
-}
-
-type dirReader struct {
- err error
-}
-
-func (r *dirReader) Read([]byte) (int, error) {
- return 0, r.err
-}
-
-func (r *dirReader) Close() error {
- return nil
-}
-
-type checksumReader struct {
- rc io.ReadCloser
- hash hash.Hash32
- nread uint64 // number of bytes read so far
- f *File
- desr io.Reader // if non-nil, where to read the data descriptor
- err error // sticky error
-}
-
-func (r *checksumReader) Stat() (fs.FileInfo, error) {
- return headerFileInfo{&r.f.FileHeader}, nil
-}
-
-func (r *checksumReader) Read(b []byte) (n int, err error) {
- if r.err != nil {
- return 0, r.err
- }
- n, err = r.rc.Read(b)
- r.hash.Write(b[:n])
- r.nread += uint64(n)
- if r.nread > r.f.UncompressedSize64 {
- return 0, ErrFormat
- }
- if err == nil {
- return
- }
- if err == io.EOF {
- if r.nread != r.f.UncompressedSize64 {
- return 0, io.ErrUnexpectedEOF
- }
- if r.desr != nil {
- if err1 := readDataDescriptor(r.desr, r.f); err1 != nil {
- if err1 == io.EOF {
- err = io.ErrUnexpectedEOF
- } else {
- err = err1
- }
- } else if r.hash.Sum32() != r.f.CRC32 {
- err = ErrChecksum
- }
- } else {
- // If there's not a data descriptor, we still compare
- // the CRC32 of what we've read against the file header
- // or TOC's CRC32, if it seems like it was set.
- if r.f.CRC32 != 0 && r.hash.Sum32() != r.f.CRC32 {
- err = ErrChecksum
- }
- }
- }
- r.err = err
- return
-}
-
-func (r *checksumReader) Close() error { return r.rc.Close() }
-
-// findBodyOffset does the minimum work to verify the file has a header
-// and returns the file body offset.
-func (f *File) findBodyOffset() (int64, error) {
- var buf [fileHeaderLen]byte
- if _, err := f.zipr.ReadAt(buf[:], f.headerOffset); err != nil {
- return 0, err
- }
- b := readBuf(buf[:])
- if sig := b.uint32(); sig != fileHeaderSignature {
- return 0, ErrFormat
- }
- b = b[22:] // skip over most of the header
- filenameLen := int(b.uint16())
- extraLen := int(b.uint16())
- return int64(fileHeaderLen + filenameLen + extraLen), nil
-}
-
-// readDirectoryHeader attempts to read a directory header from r.
-// It returns io.ErrUnexpectedEOF if it cannot read a complete header,
-// and ErrFormat if it doesn't find a valid header signature.
-func readDirectoryHeader(f *File, r io.Reader) error {
- var buf [directoryHeaderLen]byte
- if _, err := io.ReadFull(r, buf[:]); err != nil {
- return err
- }
- b := readBuf(buf[:])
- if sig := b.uint32(); sig != directoryHeaderSignature {
- return ErrFormat
- }
- f.CreatorVersion = b.uint16()
- f.ReaderVersion = b.uint16()
- f.Flags = b.uint16()
- f.Method = b.uint16()
- f.ModifiedTime = b.uint16()
- f.ModifiedDate = b.uint16()
- f.CRC32 = b.uint32()
- f.CompressedSize = b.uint32()
- f.UncompressedSize = b.uint32()
- f.CompressedSize64 = uint64(f.CompressedSize)
- f.UncompressedSize64 = uint64(f.UncompressedSize)
- filenameLen := int(b.uint16())
- extraLen := int(b.uint16())
- commentLen := int(b.uint16())
- b = b[4:] // skipped start disk number and internal attributes (2x uint16)
- f.ExternalAttrs = b.uint32()
- f.headerOffset = int64(b.uint32())
- d := make([]byte, filenameLen+extraLen+commentLen)
- if _, err := io.ReadFull(r, d); err != nil {
- return err
- }
- f.Name = string(d[:filenameLen])
- f.Extra = d[filenameLen : filenameLen+extraLen]
- f.Comment = string(d[filenameLen+extraLen:])
-
- // Determine the character encoding.
- utf8Valid1, utf8Require1 := detectUTF8(f.Name)
- utf8Valid2, utf8Require2 := detectUTF8(f.Comment)
- switch {
- case !utf8Valid1 || !utf8Valid2:
- // Name and Comment definitely not UTF-8.
- f.NonUTF8 = true
- case !utf8Require1 && !utf8Require2:
- // Name and Comment use only single-byte runes that overlap with UTF-8.
- f.NonUTF8 = false
- default:
- // Might be UTF-8, might be some other encoding; preserve existing flag.
- // Some ZIP writers use UTF-8 encoding without setting the UTF-8 flag.
- // Since it is impossible to always distinguish valid UTF-8 from some
- // other encoding (e.g., GBK or Shift-JIS), we trust the flag.
- f.NonUTF8 = f.Flags&0x800 == 0
- }
-
- needUSize := f.UncompressedSize == ^uint32(0)
- needCSize := f.CompressedSize == ^uint32(0)
- needHeaderOffset := f.headerOffset == int64(^uint32(0))
-
- // Best effort to find what we need.
- // Other zip authors might not even follow the basic format,
- // and we'll just ignore the Extra content in that case.
- var modified time.Time
-parseExtras:
- for extra := readBuf(f.Extra); len(extra) >= 4; { // need at least tag and size
- fieldTag := extra.uint16()
- fieldSize := int(extra.uint16())
- if len(extra) < fieldSize {
- break
- }
- fieldBuf := extra.sub(fieldSize)
-
- switch fieldTag {
- case zip64ExtraID:
- f.zip64 = true
-
- // update directory values from the zip64 extra block.
- // They should only be consulted if the sizes read earlier
- // are maxed out.
- // See golang.org/issue/13367.
- if needUSize {
- needUSize = false
- if len(fieldBuf) < 8 {
- return ErrFormat
- }
- f.UncompressedSize64 = fieldBuf.uint64()
- }
- if needCSize {
- needCSize = false
- if len(fieldBuf) < 8 {
- return ErrFormat
- }
- f.CompressedSize64 = fieldBuf.uint64()
- }
- if needHeaderOffset {
- needHeaderOffset = false
- if len(fieldBuf) < 8 {
- return ErrFormat
- }
- f.headerOffset = int64(fieldBuf.uint64())
- }
- case ntfsExtraID:
- if len(fieldBuf) < 4 {
- continue parseExtras
- }
- fieldBuf.uint32() // reserved (ignored)
- for len(fieldBuf) >= 4 { // need at least tag and size
- attrTag := fieldBuf.uint16()
- attrSize := int(fieldBuf.uint16())
- if len(fieldBuf) < attrSize {
- continue parseExtras
- }
- attrBuf := fieldBuf.sub(attrSize)
- if attrTag != 1 || attrSize != 24 {
- continue // Ignore irrelevant attributes
- }
-
- const ticksPerSecond = 1e7 // Windows timestamp resolution
- ts := int64(attrBuf.uint64()) // ModTime since Windows epoch
- secs := int64(ts / ticksPerSecond)
- nsecs := (1e9 / ticksPerSecond) * int64(ts%ticksPerSecond)
- epoch := time.Date(1601, time.January, 1, 0, 0, 0, 0, time.UTC)
- modified = time.Unix(epoch.Unix()+secs, nsecs)
- }
- case unixExtraID, infoZipUnixExtraID:
- if len(fieldBuf) < 8 {
- continue parseExtras
- }
- fieldBuf.uint32() // AcTime (ignored)
- ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
- modified = time.Unix(ts, 0)
- case extTimeExtraID:
- if len(fieldBuf) < 5 || fieldBuf.uint8()&1 == 0 {
- continue parseExtras
- }
- ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
- modified = time.Unix(ts, 0)
- }
- }
-
- msdosModified := msDosTimeToTime(f.ModifiedDate, f.ModifiedTime)
- f.Modified = msdosModified
- if !modified.IsZero() {
- f.Modified = modified.UTC()
-
- // If legacy MS-DOS timestamps are set, we can use the delta between
- // the legacy and extended versions to estimate timezone offset.
- //
- // A non-UTC timezone is always used (even if offset is zero).
- // Thus, FileHeader.Modified.Location() == time.UTC is useful for
- // determining whether extended timestamps are present.
- // This is necessary for users that need to do additional time
- // calculations when dealing with legacy ZIP formats.
- if f.ModifiedTime != 0 || f.ModifiedDate != 0 {
- f.Modified = modified.In(timeZone(msdosModified.Sub(modified)))
- }
- }
-
- // Assume that uncompressed size 2³²-1 could plausibly happen in
- // an old zip32 file that was sharding inputs into the largest chunks
- // possible (or is just malicious; search the web for 42.zip).
- // If needUSize is true still, it means we didn't see a zip64 extension.
- // As long as the compressed size is not also 2³²-1 (implausible)
- // and the header is not also 2³²-1 (equally implausible),
- // accept the uncompressed size 2³²-1 as valid.
- // If nothing else, this keeps archive/zip working with 42.zip.
- _ = needUSize
-
- if needCSize || needHeaderOffset {
- return ErrFormat
- }
-
- return nil
-}
-
-func readDataDescriptor(r io.Reader, f *File) error {
- var buf [dataDescriptorLen]byte
- // The spec says: "Although not originally assigned a
- // signature, the value 0x08074b50 has commonly been adopted
- // as a signature value for the data descriptor record.
- // Implementers should be aware that ZIP files may be
- // encountered with or without this signature marking data
- // descriptors and should account for either case when reading
- // ZIP files to ensure compatibility."
- //
- // dataDescriptorLen includes the size of the signature but
- // first read just those 4 bytes to see if it exists.
- if _, err := io.ReadFull(r, buf[:4]); err != nil {
- return err
- }
- off := 0
- maybeSig := readBuf(buf[:4])
- if maybeSig.uint32() != dataDescriptorSignature {
- // No data descriptor signature. Keep these four
- // bytes.
- off += 4
- }
- if _, err := io.ReadFull(r, buf[off:12]); err != nil {
- return err
- }
- b := readBuf(buf[:12])
- if b.uint32() != f.CRC32 {
- return ErrChecksum
- }
-
- // The two sizes that follow here can be either 32 bits or 64 bits
- // but the spec is not very clear on this and different
- // interpretations has been made causing incompatibilities. We
- // already have the sizes from the central directory so we can
- // just ignore these.
-
- return nil
-}
-
-func readDirectoryEnd(r io.ReaderAt, size int64) (dir *directoryEnd, baseOffset int64, err error) {
- // look for directoryEndSignature in the last 1k, then in the last 65k
- var buf []byte
- var directoryEndOffset int64
- for i, bLen := range []int64{1024, 65 * 1024} {
- if bLen > size {
- bLen = size
- }
- buf = make([]byte, int(bLen))
- if _, err := r.ReadAt(buf, size-bLen); err != nil && err != io.EOF {
- return nil, 0, err
- }
- if p := findSignatureInBlock(buf); p >= 0 {
- buf = buf[p:]
- directoryEndOffset = size - bLen + int64(p)
- break
- }
- if i == 1 || bLen == size {
- return nil, 0, ErrFormat
- }
- }
-
- // read header into struct
- b := readBuf(buf[4:]) // skip signature
- d := &directoryEnd{
- diskNbr: uint32(b.uint16()),
- dirDiskNbr: uint32(b.uint16()),
- dirRecordsThisDisk: uint64(b.uint16()),
- directoryRecords: uint64(b.uint16()),
- directorySize: uint64(b.uint32()),
- directoryOffset: uint64(b.uint32()),
- commentLen: b.uint16(),
- }
- l := int(d.commentLen)
- if l > len(b) {
- return nil, 0, errors.New("zip: invalid comment length")
- }
- d.comment = string(b[:l])
-
- // These values mean that the file can be a zip64 file
- if d.directoryRecords == 0xffff || d.directorySize == 0xffff || d.directoryOffset == 0xffffffff {
- p, err := findDirectory64End(r, directoryEndOffset)
- if err == nil && p >= 0 {
- directoryEndOffset = p
- err = readDirectory64End(r, p, d)
- }
- if err != nil {
- return nil, 0, err
- }
- }
-
- baseOffset = directoryEndOffset - int64(d.directorySize) - int64(d.directoryOffset)
-
- // Make sure directoryOffset points to somewhere in our file.
- if o := baseOffset + int64(d.directoryOffset); o < 0 || o >= size {
- return nil, 0, ErrFormat
- }
- return d, baseOffset, nil
-}
-
-// findDirectory64End tries to read the zip64 locator just before the
-// directory end and returns the offset of the zip64 directory end if
-// found.
-func findDirectory64End(r io.ReaderAt, directoryEndOffset int64) (int64, error) {
- locOffset := directoryEndOffset - directory64LocLen
- if locOffset < 0 {
- return -1, nil // no need to look for a header outside the file
- }
- buf := make([]byte, directory64LocLen)
- if _, err := r.ReadAt(buf, locOffset); err != nil {
- return -1, err
- }
- b := readBuf(buf)
- if sig := b.uint32(); sig != directory64LocSignature {
- return -1, nil
- }
- if b.uint32() != 0 { // number of the disk with the start of the zip64 end of central directory
- return -1, nil // the file is not a valid zip64-file
- }
- p := b.uint64() // relative offset of the zip64 end of central directory record
- if b.uint32() != 1 { // total number of disks
- return -1, nil // the file is not a valid zip64-file
- }
- return int64(p), nil
-}
-
-// readDirectory64End reads the zip64 directory end and updates the
-// directory end with the zip64 directory end values.
-func readDirectory64End(r io.ReaderAt, offset int64, d *directoryEnd) (err error) {
- buf := make([]byte, directory64EndLen)
- if _, err := r.ReadAt(buf, offset); err != nil {
- return err
- }
-
- b := readBuf(buf)
- if sig := b.uint32(); sig != directory64EndSignature {
- return ErrFormat
- }
-
- b = b[12:] // skip dir size, version and version needed (uint64 + 2x uint16)
- d.diskNbr = b.uint32() // number of this disk
- d.dirDiskNbr = b.uint32() // number of the disk with the start of the central directory
- d.dirRecordsThisDisk = b.uint64() // total number of entries in the central directory on this disk
- d.directoryRecords = b.uint64() // total number of entries in the central directory
- d.directorySize = b.uint64() // size of the central directory
- d.directoryOffset = b.uint64() // offset of start of central directory with respect to the starting disk number
-
- return nil
-}
-
-func findSignatureInBlock(b []byte) int {
- for i := len(b) - directoryEndLen; i >= 0; i-- {
- // defined from directoryEndSignature in struct.go
- if b[i] == 'P' && b[i+1] == 'K' && b[i+2] == 0x05 && b[i+3] == 0x06 {
- // n is length of comment
- n := int(b[i+directoryEndLen-2]) | int(b[i+directoryEndLen-1])<<8
- if n+directoryEndLen+i <= len(b) {
- return i
- }
- }
- }
- return -1
-}
-
-type readBuf []byte
-
-func (b *readBuf) uint8() uint8 {
- v := (*b)[0]
- *b = (*b)[1:]
- return v
-}
-
-func (b *readBuf) uint16() uint16 {
- v := binary.LittleEndian.Uint16(*b)
- *b = (*b)[2:]
- return v
-}
-
-func (b *readBuf) uint32() uint32 {
- v := binary.LittleEndian.Uint32(*b)
- *b = (*b)[4:]
- return v
-}
-
-func (b *readBuf) uint64() uint64 {
- v := binary.LittleEndian.Uint64(*b)
- *b = (*b)[8:]
- return v
-}
-
-func (b *readBuf) sub(n int) readBuf {
- b2 := (*b)[:n]
- *b = (*b)[n:]
- return b2
-}
-
-// A fileListEntry is a File and its ename.
-// If file == nil, the fileListEntry describes a directory without metadata.
-type fileListEntry struct {
- name string
- file *File
- isDir bool
- isDup bool
-}
-
-type fileInfoDirEntry interface {
- fs.FileInfo
- fs.DirEntry
-}
-
-func (e *fileListEntry) stat() (fileInfoDirEntry, error) {
- if e.isDup {
- return nil, errors.New(e.name + ": duplicate entries in zip file")
- }
- if !e.isDir {
- return headerFileInfo{&e.file.FileHeader}, nil
- }
- return e, nil
-}
-
-// Only used for directories.
-func (f *fileListEntry) Name() string { _, elem, _ := split(f.name); return elem }
-func (f *fileListEntry) Size() int64 { return 0 }
-func (f *fileListEntry) Mode() fs.FileMode { return fs.ModeDir | 0555 }
-func (f *fileListEntry) Type() fs.FileMode { return fs.ModeDir }
-func (f *fileListEntry) IsDir() bool { return true }
-func (f *fileListEntry) Sys() any { return nil }
-
-func (f *fileListEntry) ModTime() time.Time {
- if f.file == nil {
- return time.Time{}
- }
- return f.file.FileHeader.Modified.UTC()
-}
-
-func (f *fileListEntry) Info() (fs.FileInfo, error) { return f, nil }
-
-// toValidName coerces name to be a valid name for fs.FS.Open.
-func toValidName(name string) string {
- name = strings.ReplaceAll(name, `\`, `/`)
- p := path.Clean(name)
-
- p = strings.TrimPrefix(p, "/")
-
- for strings.HasPrefix(p, "../") {
- p = p[len("../"):]
- }
-
- return p
-}
-
-func (r *Reader) initFileList() {
- r.fileListOnce.Do(func() {
- // files and knownDirs map from a file/directory name
- // to an index into the r.fileList entry that we are
- // building. They are used to mark duplicate entries.
- files := make(map[string]int)
- knownDirs := make(map[string]int)
-
- // dirs[name] is true if name is known to be a directory,
- // because it appears as a prefix in a path.
- dirs := make(map[string]bool)
-
- for _, file := range r.File {
- isDir := len(file.Name) > 0 && file.Name[len(file.Name)-1] == '/'
- name := toValidName(file.Name)
- if name == "" {
- continue
- }
-
- if idx, ok := files[name]; ok {
- r.fileList[idx].isDup = true
- continue
- }
- if idx, ok := knownDirs[name]; ok {
- r.fileList[idx].isDup = true
- continue
- }
-
- for dir := path.Dir(name); dir != "."; dir = path.Dir(dir) {
- dirs[dir] = true
- }
-
- idx := len(r.fileList)
- entry := fileListEntry{
- name: name,
- file: file,
- isDir: isDir,
- }
- r.fileList = append(r.fileList, entry)
- if isDir {
- knownDirs[name] = idx
- } else {
- files[name] = idx
- }
- }
- for dir := range dirs {
- if _, ok := knownDirs[dir]; !ok {
- if idx, ok := files[dir]; ok {
- r.fileList[idx].isDup = true
- } else {
- entry := fileListEntry{
- name: dir,
- file: nil,
- isDir: true,
- }
- r.fileList = append(r.fileList, entry)
- }
- }
- }
-
- sort.Slice(r.fileList, func(i, j int) bool { return fileEntryLess(r.fileList[i].name, r.fileList[j].name) })
- })
-}
-
-func fileEntryLess(x, y string) bool {
- xdir, xelem, _ := split(x)
- ydir, yelem, _ := split(y)
- return xdir < ydir || xdir == ydir && xelem < yelem
-}
-
-// Open opens the named file in the ZIP archive,
-// using the semantics of fs.FS.Open:
-// paths are always slash separated, with no
-// leading / or ../ elements.
-func (r *Reader) Open(name string) (fs.File, error) {
- r.initFileList()
-
- if !fs.ValidPath(name) {
- return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrInvalid}
- }
- e := r.openLookup(name)
- if e == nil {
- return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
- }
- if e.isDir {
- return &openDir{e, r.openReadDir(name), 0}, nil
- }
- rc, err := e.file.Open()
- if err != nil {
- return nil, err
- }
- return rc.(fs.File), nil
-}
-
-func split(name string) (dir, elem string, isDir bool) {
- if len(name) > 0 && name[len(name)-1] == '/' {
- isDir = true
- name = name[:len(name)-1]
- }
- i := len(name) - 1
- for i >= 0 && name[i] != '/' {
- i--
- }
- if i < 0 {
- return ".", name, isDir
- }
- return name[:i], name[i+1:], isDir
-}
-
-var dotFile = &fileListEntry{name: "./", isDir: true}
-
-func (r *Reader) openLookup(name string) *fileListEntry {
- if name == "." {
- return dotFile
- }
-
- dir, elem, _ := split(name)
- files := r.fileList
- i := sort.Search(len(files), func(i int) bool {
- idir, ielem, _ := split(files[i].name)
- return idir > dir || idir == dir && ielem >= elem
- })
- if i < len(files) {
- fname := files[i].name
- if fname == name || len(fname) == len(name)+1 && fname[len(name)] == '/' && fname[:len(name)] == name {
- return &files[i]
- }
- }
- return nil
-}
-
-func (r *Reader) openReadDir(dir string) []fileListEntry {
- files := r.fileList
- i := sort.Search(len(files), func(i int) bool {
- idir, _, _ := split(files[i].name)
- return idir >= dir
- })
- j := sort.Search(len(files), func(j int) bool {
- jdir, _, _ := split(files[j].name)
- return jdir > dir
- })
- return files[i:j]
-}
-
-type openDir struct {
- e *fileListEntry
- files []fileListEntry
- offset int
-}
-
-func (d *openDir) Close() error { return nil }
-func (d *openDir) Stat() (fs.FileInfo, error) { return d.e.stat() }
-
-func (d *openDir) Read([]byte) (int, error) {
- return 0, &fs.PathError{Op: "read", Path: d.e.name, Err: errors.New("is a directory")}
-}
-
-func (d *openDir) ReadDir(count int) ([]fs.DirEntry, error) {
- n := len(d.files) - d.offset
- if count > 0 && n > count {
- n = count
- }
- if n == 0 {
- if count <= 0 {
- return nil, nil
- }
- return nil, io.EOF
- }
- list := make([]fs.DirEntry, n)
- for i := range list {
- s, err := d.files[d.offset+i].stat()
- if err != nil {
- return nil, err
- }
- list[i] = s
- }
- d.offset += n
- return list, nil
-}
diff --git a/contrib/go/_std_1.20/src/archive/zip/struct.go b/contrib/go/_std_1.20/src/archive/zip/struct.go
deleted file mode 100644
index 9c37084778..0000000000
--- a/contrib/go/_std_1.20/src/archive/zip/struct.go
+++ /dev/null
@@ -1,415 +0,0 @@
-// Copyright 2010 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 zip provides support for reading and writing ZIP archives.
-
-See the [ZIP specification] for details.
-
-This package does not support disk spanning.
-
-A note about ZIP64:
-
-To be backwards compatible the FileHeader has both 32 and 64 bit Size
-fields. The 64 bit fields will always contain the correct value and
-for normal archives both fields will be the same. For files requiring
-the ZIP64 format the 32 bit fields will be 0xffffffff and the 64 bit
-fields must be used instead.
-
-[ZIP specification]: https://www.pkware.com/appnote
-*/
-package zip
-
-import (
- "io/fs"
- "path"
- "time"
-)
-
-// Compression methods.
-const (
- Store uint16 = 0 // no compression
- Deflate uint16 = 8 // DEFLATE compressed
-)
-
-const (
- fileHeaderSignature = 0x04034b50
- directoryHeaderSignature = 0x02014b50
- directoryEndSignature = 0x06054b50
- directory64LocSignature = 0x07064b50
- directory64EndSignature = 0x06064b50
- dataDescriptorSignature = 0x08074b50 // de-facto standard; required by OS X Finder
- fileHeaderLen = 30 // + filename + extra
- directoryHeaderLen = 46 // + filename + extra + comment
- directoryEndLen = 22 // + comment
- dataDescriptorLen = 16 // four uint32: descriptor signature, crc32, compressed size, size
- dataDescriptor64Len = 24 // two uint32: signature, crc32 | two uint64: compressed size, size
- directory64LocLen = 20 //
- directory64EndLen = 56 // + extra
-
- // Constants for the first byte in CreatorVersion.
- creatorFAT = 0
- creatorUnix = 3
- creatorNTFS = 11
- creatorVFAT = 14
- creatorMacOSX = 19
-
- // Version numbers.
- zipVersion20 = 20 // 2.0
- zipVersion45 = 45 // 4.5 (reads and writes zip64 archives)
-
- // Limits for non zip64 files.
- uint16max = (1 << 16) - 1
- uint32max = (1 << 32) - 1
-
- // Extra header IDs.
- //
- // IDs 0..31 are reserved for official use by PKWARE.
- // IDs above that range are defined by third-party vendors.
- // Since ZIP lacked high precision timestamps (nor a official specification
- // of the timezone used for the date fields), many competing extra fields
- // have been invented. Pervasive use effectively makes them "official".
- //
- // See http://mdfs.net/Docs/Comp/Archiving/Zip/ExtraField
- zip64ExtraID = 0x0001 // Zip64 extended information
- ntfsExtraID = 0x000a // NTFS
- unixExtraID = 0x000d // UNIX
- extTimeExtraID = 0x5455 // Extended timestamp
- infoZipUnixExtraID = 0x5855 // Info-ZIP Unix extension
-)
-
-// FileHeader describes a file within a ZIP file.
-// See the [ZIP specification] for details.
-//
-// [ZIP specification]: https://www.pkware.com/appnote
-type FileHeader struct {
- // Name is the name of the file.
- //
- // It must be a relative path, not start with a drive letter (such as "C:"),
- // and must use forward slashes instead of back slashes. A trailing slash
- // indicates that this file is a directory and should have no data.
- Name string
-
- // Comment is any arbitrary user-defined string shorter than 64KiB.
- Comment string
-
- // NonUTF8 indicates that Name and Comment are not encoded in UTF-8.
- //
- // By specification, the only other encoding permitted should be CP-437,
- // but historically many ZIP readers interpret Name and Comment as whatever
- // the system's local character encoding happens to be.
- //
- // This flag should only be set if the user intends to encode a non-portable
- // ZIP file for a specific localized region. Otherwise, the Writer
- // automatically sets the ZIP format's UTF-8 flag for valid UTF-8 strings.
- NonUTF8 bool
-
- CreatorVersion uint16
- ReaderVersion uint16
- Flags uint16
-
- // Method is the compression method. If zero, Store is used.
- Method uint16
-
- // Modified is the modified time of the file.
- //
- // When reading, an extended timestamp is preferred over the legacy MS-DOS
- // date field, and the offset between the times is used as the timezone.
- // If only the MS-DOS date is present, the timezone is assumed to be UTC.
- //
- // When writing, an extended timestamp (which is timezone-agnostic) is
- // always emitted. The legacy MS-DOS date field is encoded according to the
- // location of the Modified time.
- Modified time.Time
-
- // ModifiedTime is an MS-DOS-encoded time.
- //
- // Deprecated: Use Modified instead.
- ModifiedTime uint16
-
- // ModifiedDate is an MS-DOS-encoded date.
- //
- // Deprecated: Use Modified instead.
- ModifiedDate uint16
-
- // CRC32 is the CRC32 checksum of the file content.
- CRC32 uint32
-
- // CompressedSize is the compressed size of the file in bytes.
- // If either the uncompressed or compressed size of the file
- // does not fit in 32 bits, CompressedSize is set to ^uint32(0).
- //
- // Deprecated: Use CompressedSize64 instead.
- CompressedSize uint32
-
- // UncompressedSize is the compressed size of the file in bytes.
- // If either the uncompressed or compressed size of the file
- // does not fit in 32 bits, CompressedSize is set to ^uint32(0).
- //
- // Deprecated: Use UncompressedSize64 instead.
- UncompressedSize uint32
-
- // CompressedSize64 is the compressed size of the file in bytes.
- CompressedSize64 uint64
-
- // UncompressedSize64 is the uncompressed size of the file in bytes.
- UncompressedSize64 uint64
-
- Extra []byte
- ExternalAttrs uint32 // Meaning depends on CreatorVersion
-}
-
-// FileInfo returns an fs.FileInfo for the FileHeader.
-func (h *FileHeader) FileInfo() fs.FileInfo {
- return headerFileInfo{h}
-}
-
-// headerFileInfo implements fs.FileInfo.
-type headerFileInfo struct {
- fh *FileHeader
-}
-
-func (fi headerFileInfo) Name() string { return path.Base(fi.fh.Name) }
-func (fi headerFileInfo) Size() int64 {
- if fi.fh.UncompressedSize64 > 0 {
- return int64(fi.fh.UncompressedSize64)
- }
- return int64(fi.fh.UncompressedSize)
-}
-func (fi headerFileInfo) IsDir() bool { return fi.Mode().IsDir() }
-func (fi headerFileInfo) ModTime() time.Time {
- if fi.fh.Modified.IsZero() {
- return fi.fh.ModTime()
- }
- return fi.fh.Modified.UTC()
-}
-func (fi headerFileInfo) Mode() fs.FileMode { return fi.fh.Mode() }
-func (fi headerFileInfo) Type() fs.FileMode { return fi.fh.Mode().Type() }
-func (fi headerFileInfo) Sys() any { return fi.fh }
-
-func (fi headerFileInfo) Info() (fs.FileInfo, error) { return fi, nil }
-
-// FileInfoHeader creates a partially-populated FileHeader from an
-// fs.FileInfo.
-// Because fs.FileInfo's Name method returns only the base name of
-// the file it describes, it may be necessary to modify the Name field
-// of the returned header to provide the full path name of the file.
-// If compression is desired, callers should set the FileHeader.Method
-// field; it is unset by default.
-func FileInfoHeader(fi fs.FileInfo) (*FileHeader, error) {
- size := fi.Size()
- fh := &FileHeader{
- Name: fi.Name(),
- UncompressedSize64: uint64(size),
- }
- fh.SetModTime(fi.ModTime())
- fh.SetMode(fi.Mode())
- if fh.UncompressedSize64 > uint32max {
- fh.UncompressedSize = uint32max
- } else {
- fh.UncompressedSize = uint32(fh.UncompressedSize64)
- }
- return fh, nil
-}
-
-type directoryEnd struct {
- diskNbr uint32 // unused
- dirDiskNbr uint32 // unused
- dirRecordsThisDisk uint64 // unused
- directoryRecords uint64
- directorySize uint64
- directoryOffset uint64 // relative to file
- commentLen uint16
- comment string
-}
-
-// timeZone returns a *time.Location based on the provided offset.
-// If the offset is non-sensible, then this uses an offset of zero.
-func timeZone(offset time.Duration) *time.Location {
- const (
- minOffset = -12 * time.Hour // E.g., Baker island at -12:00
- maxOffset = +14 * time.Hour // E.g., Line island at +14:00
- offsetAlias = 15 * time.Minute // E.g., Nepal at +5:45
- )
- offset = offset.Round(offsetAlias)
- if offset < minOffset || maxOffset < offset {
- offset = 0
- }
- return time.FixedZone("", int(offset/time.Second))
-}
-
-// msDosTimeToTime converts an MS-DOS date and time into a time.Time.
-// The resolution is 2s.
-// See: https://msdn.microsoft.com/en-us/library/ms724247(v=VS.85).aspx
-func msDosTimeToTime(dosDate, dosTime uint16) time.Time {
- return time.Date(
- // date bits 0-4: day of month; 5-8: month; 9-15: years since 1980
- int(dosDate>>9+1980),
- time.Month(dosDate>>5&0xf),
- int(dosDate&0x1f),
-
- // time bits 0-4: second/2; 5-10: minute; 11-15: hour
- int(dosTime>>11),
- int(dosTime>>5&0x3f),
- int(dosTime&0x1f*2),
- 0, // nanoseconds
-
- time.UTC,
- )
-}
-
-// timeToMsDosTime converts a time.Time to an MS-DOS date and time.
-// The resolution is 2s.
-// See: https://msdn.microsoft.com/en-us/library/ms724274(v=VS.85).aspx
-func timeToMsDosTime(t time.Time) (fDate uint16, fTime uint16) {
- fDate = uint16(t.Day() + int(t.Month())<<5 + (t.Year()-1980)<<9)
- fTime = uint16(t.Second()/2 + t.Minute()<<5 + t.Hour()<<11)
- return
-}
-
-// ModTime returns the modification time in UTC using the legacy
-// ModifiedDate and ModifiedTime fields.
-//
-// Deprecated: Use Modified instead.
-func (h *FileHeader) ModTime() time.Time {
- return msDosTimeToTime(h.ModifiedDate, h.ModifiedTime)
-}
-
-// SetModTime sets the Modified, ModifiedTime, and ModifiedDate fields
-// to the given time in UTC.
-//
-// Deprecated: Use Modified instead.
-func (h *FileHeader) SetModTime(t time.Time) {
- t = t.UTC() // Convert to UTC for compatibility
- h.Modified = t
- h.ModifiedDate, h.ModifiedTime = timeToMsDosTime(t)
-}
-
-const (
- // Unix constants. The specification doesn't mention them,
- // but these seem to be the values agreed on by tools.
- s_IFMT = 0xf000
- s_IFSOCK = 0xc000
- s_IFLNK = 0xa000
- s_IFREG = 0x8000
- s_IFBLK = 0x6000
- s_IFDIR = 0x4000
- s_IFCHR = 0x2000
- s_IFIFO = 0x1000
- s_ISUID = 0x800
- s_ISGID = 0x400
- s_ISVTX = 0x200
-
- msdosDir = 0x10
- msdosReadOnly = 0x01
-)
-
-// Mode returns the permission and mode bits for the FileHeader.
-func (h *FileHeader) Mode() (mode fs.FileMode) {
- switch h.CreatorVersion >> 8 {
- case creatorUnix, creatorMacOSX:
- mode = unixModeToFileMode(h.ExternalAttrs >> 16)
- case creatorNTFS, creatorVFAT, creatorFAT:
- mode = msdosModeToFileMode(h.ExternalAttrs)
- }
- if len(h.Name) > 0 && h.Name[len(h.Name)-1] == '/' {
- mode |= fs.ModeDir
- }
- return mode
-}
-
-// SetMode changes the permission and mode bits for the FileHeader.
-func (h *FileHeader) SetMode(mode fs.FileMode) {
- h.CreatorVersion = h.CreatorVersion&0xff | creatorUnix<<8
- h.ExternalAttrs = fileModeToUnixMode(mode) << 16
-
- // set MSDOS attributes too, as the original zip does.
- if mode&fs.ModeDir != 0 {
- h.ExternalAttrs |= msdosDir
- }
- if mode&0200 == 0 {
- h.ExternalAttrs |= msdosReadOnly
- }
-}
-
-// isZip64 reports whether the file size exceeds the 32 bit limit
-func (h *FileHeader) isZip64() bool {
- return h.CompressedSize64 >= uint32max || h.UncompressedSize64 >= uint32max
-}
-
-func (f *FileHeader) hasDataDescriptor() bool {
- return f.Flags&0x8 != 0
-}
-
-func msdosModeToFileMode(m uint32) (mode fs.FileMode) {
- if m&msdosDir != 0 {
- mode = fs.ModeDir | 0777
- } else {
- mode = 0666
- }
- if m&msdosReadOnly != 0 {
- mode &^= 0222
- }
- return mode
-}
-
-func fileModeToUnixMode(mode fs.FileMode) uint32 {
- var m uint32
- switch mode & fs.ModeType {
- default:
- m = s_IFREG
- case fs.ModeDir:
- m = s_IFDIR
- case fs.ModeSymlink:
- m = s_IFLNK
- case fs.ModeNamedPipe:
- m = s_IFIFO
- case fs.ModeSocket:
- m = s_IFSOCK
- case fs.ModeDevice:
- m = s_IFBLK
- case fs.ModeDevice | fs.ModeCharDevice:
- m = s_IFCHR
- }
- if mode&fs.ModeSetuid != 0 {
- m |= s_ISUID
- }
- if mode&fs.ModeSetgid != 0 {
- m |= s_ISGID
- }
- if mode&fs.ModeSticky != 0 {
- m |= s_ISVTX
- }
- return m | uint32(mode&0777)
-}
-
-func unixModeToFileMode(m uint32) fs.FileMode {
- mode := fs.FileMode(m & 0777)
- switch m & s_IFMT {
- case s_IFBLK:
- mode |= fs.ModeDevice
- case s_IFCHR:
- mode |= fs.ModeDevice | fs.ModeCharDevice
- case s_IFDIR:
- mode |= fs.ModeDir
- case s_IFIFO:
- mode |= fs.ModeNamedPipe
- case s_IFLNK:
- mode |= fs.ModeSymlink
- case s_IFREG:
- // nothing to do
- case s_IFSOCK:
- mode |= fs.ModeSocket
- }
- if m&s_ISGID != 0 {
- mode |= fs.ModeSetgid
- }
- if m&s_ISUID != 0 {
- mode |= fs.ModeSetuid
- }
- if m&s_ISVTX != 0 {
- mode |= fs.ModeSticky
- }
- return mode
-}
diff --git a/contrib/go/_std_1.20/src/archive/zip/ya.make b/contrib/go/_std_1.20/src/archive/zip/ya.make
deleted file mode 100644
index 9db6e66aa9..0000000000
--- a/contrib/go/_std_1.20/src/archive/zip/ya.make
+++ /dev/null
@@ -1,10 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- reader.go
- register.go
- struct.go
- writer.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/bufio/bufio.go b/contrib/go/_std_1.20/src/bufio/bufio.go
deleted file mode 100644
index 5a88def0c7..0000000000
--- a/contrib/go/_std_1.20/src/bufio/bufio.go
+++ /dev/null
@@ -1,828 +0,0 @@
-// Copyright 2009 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 bufio implements buffered I/O. It wraps an io.Reader or io.Writer
-// object, creating another object (Reader or Writer) that also implements
-// the interface but provides buffering and some help for textual I/O.
-package bufio
-
-import (
- "bytes"
- "errors"
- "io"
- "strings"
- "unicode/utf8"
-)
-
-const (
- defaultBufSize = 4096
-)
-
-var (
- ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte")
- ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune")
- ErrBufferFull = errors.New("bufio: buffer full")
- ErrNegativeCount = errors.New("bufio: negative count")
-)
-
-// Buffered input.
-
-// Reader implements buffering for an io.Reader object.
-type Reader struct {
- buf []byte
- rd io.Reader // reader provided by the client
- r, w int // buf read and write positions
- err error
- lastByte int // last byte read for UnreadByte; -1 means invalid
- lastRuneSize int // size of last rune read for UnreadRune; -1 means invalid
-}
-
-const minReadBufferSize = 16
-const maxConsecutiveEmptyReads = 100
-
-// NewReaderSize returns a new Reader whose buffer has at least the specified
-// size. If the argument io.Reader is already a Reader with large enough
-// size, it returns the underlying Reader.
-func NewReaderSize(rd io.Reader, size int) *Reader {
- // Is it already a Reader?
- b, ok := rd.(*Reader)
- if ok && len(b.buf) >= size {
- return b
- }
- if size < minReadBufferSize {
- size = minReadBufferSize
- }
- r := new(Reader)
- r.reset(make([]byte, size), rd)
- return r
-}
-
-// NewReader returns a new Reader whose buffer has the default size.
-func NewReader(rd io.Reader) *Reader {
- return NewReaderSize(rd, defaultBufSize)
-}
-
-// Size returns the size of the underlying buffer in bytes.
-func (b *Reader) Size() int { return len(b.buf) }
-
-// Reset discards any buffered data, resets all state, and switches
-// the buffered reader to read from r.
-// Calling Reset on the zero value of Reader initializes the internal buffer
-// to the default size.
-func (b *Reader) Reset(r io.Reader) {
- if b.buf == nil {
- b.buf = make([]byte, defaultBufSize)
- }
- b.reset(b.buf, r)
-}
-
-func (b *Reader) reset(buf []byte, r io.Reader) {
- *b = Reader{
- buf: buf,
- rd: r,
- lastByte: -1,
- lastRuneSize: -1,
- }
-}
-
-var errNegativeRead = errors.New("bufio: reader returned negative count from Read")
-
-// fill reads a new chunk into the buffer.
-func (b *Reader) fill() {
- // Slide existing data to beginning.
- if b.r > 0 {
- copy(b.buf, b.buf[b.r:b.w])
- b.w -= b.r
- b.r = 0
- }
-
- if b.w >= len(b.buf) {
- panic("bufio: tried to fill full buffer")
- }
-
- // Read new data: try a limited number of times.
- for i := maxConsecutiveEmptyReads; i > 0; i-- {
- n, err := b.rd.Read(b.buf[b.w:])
- if n < 0 {
- panic(errNegativeRead)
- }
- b.w += n
- if err != nil {
- b.err = err
- return
- }
- if n > 0 {
- return
- }
- }
- b.err = io.ErrNoProgress
-}
-
-func (b *Reader) readErr() error {
- err := b.err
- b.err = nil
- return err
-}
-
-// Peek returns the next n bytes without advancing the reader. The bytes stop
-// being valid at the next read call. If Peek returns fewer than n bytes, it
-// also returns an error explaining why the read is short. The error is
-// ErrBufferFull if n is larger than b's buffer size.
-//
-// Calling Peek prevents a UnreadByte or UnreadRune call from succeeding
-// until the next read operation.
-func (b *Reader) Peek(n int) ([]byte, error) {
- if n < 0 {
- return nil, ErrNegativeCount
- }
-
- b.lastByte = -1
- b.lastRuneSize = -1
-
- for b.w-b.r < n && b.w-b.r < len(b.buf) && b.err == nil {
- b.fill() // b.w-b.r < len(b.buf) => buffer is not full
- }
-
- if n > len(b.buf) {
- return b.buf[b.r:b.w], ErrBufferFull
- }
-
- // 0 <= n <= len(b.buf)
- var err error
- if avail := b.w - b.r; avail < n {
- // not enough data in buffer
- n = avail
- err = b.readErr()
- if err == nil {
- err = ErrBufferFull
- }
- }
- return b.buf[b.r : b.r+n], err
-}
-
-// Discard skips the next n bytes, returning the number of bytes discarded.
-//
-// If Discard skips fewer than n bytes, it also returns an error.
-// If 0 <= n <= b.Buffered(), Discard is guaranteed to succeed without
-// reading from the underlying io.Reader.
-func (b *Reader) Discard(n int) (discarded int, err error) {
- if n < 0 {
- return 0, ErrNegativeCount
- }
- if n == 0 {
- return
- }
-
- b.lastByte = -1
- b.lastRuneSize = -1
-
- remain := n
- for {
- skip := b.Buffered()
- if skip == 0 {
- b.fill()
- skip = b.Buffered()
- }
- if skip > remain {
- skip = remain
- }
- b.r += skip
- remain -= skip
- if remain == 0 {
- return n, nil
- }
- if b.err != nil {
- return n - remain, b.readErr()
- }
- }
-}
-
-// Read reads data into p.
-// It returns the number of bytes read into p.
-// The bytes are taken from at most one Read on the underlying Reader,
-// hence n may be less than len(p).
-// To read exactly len(p) bytes, use io.ReadFull(b, p).
-// If the underlying Reader can return a non-zero count with io.EOF,
-// then this Read method can do so as well; see the [io.Reader] docs.
-func (b *Reader) Read(p []byte) (n int, err error) {
- n = len(p)
- if n == 0 {
- if b.Buffered() > 0 {
- return 0, nil
- }
- return 0, b.readErr()
- }
- if b.r == b.w {
- if b.err != nil {
- return 0, b.readErr()
- }
- if len(p) >= len(b.buf) {
- // Large read, empty buffer.
- // Read directly into p to avoid copy.
- n, b.err = b.rd.Read(p)
- if n < 0 {
- panic(errNegativeRead)
- }
- if n > 0 {
- b.lastByte = int(p[n-1])
- b.lastRuneSize = -1
- }
- return n, b.readErr()
- }
- // One read.
- // Do not use b.fill, which will loop.
- b.r = 0
- b.w = 0
- n, b.err = b.rd.Read(b.buf)
- if n < 0 {
- panic(errNegativeRead)
- }
- if n == 0 {
- return 0, b.readErr()
- }
- b.w += n
- }
-
- // copy as much as we can
- // Note: if the slice panics here, it is probably because
- // the underlying reader returned a bad count. See issue 49795.
- n = copy(p, b.buf[b.r:b.w])
- b.r += n
- b.lastByte = int(b.buf[b.r-1])
- b.lastRuneSize = -1
- return n, nil
-}
-
-// ReadByte reads and returns a single byte.
-// If no byte is available, returns an error.
-func (b *Reader) ReadByte() (byte, error) {
- b.lastRuneSize = -1
- for b.r == b.w {
- if b.err != nil {
- return 0, b.readErr()
- }
- b.fill() // buffer is empty
- }
- c := b.buf[b.r]
- b.r++
- b.lastByte = int(c)
- return c, nil
-}
-
-// UnreadByte unreads the last byte. Only the most recently read byte can be unread.
-//
-// UnreadByte returns an error if the most recent method called on the
-// Reader was not a read operation. Notably, Peek, Discard, and WriteTo are not
-// considered read operations.
-func (b *Reader) UnreadByte() error {
- if b.lastByte < 0 || b.r == 0 && b.w > 0 {
- return ErrInvalidUnreadByte
- }
- // b.r > 0 || b.w == 0
- if b.r > 0 {
- b.r--
- } else {
- // b.r == 0 && b.w == 0
- b.w = 1
- }
- b.buf[b.r] = byte(b.lastByte)
- b.lastByte = -1
- b.lastRuneSize = -1
- return nil
-}
-
-// ReadRune reads a single UTF-8 encoded Unicode character and returns the
-// rune and its size in bytes. If the encoded rune is invalid, it consumes one byte
-// and returns unicode.ReplacementChar (U+FFFD) with a size of 1.
-func (b *Reader) ReadRune() (r rune, size int, err error) {
- for b.r+utf8.UTFMax > b.w && !utf8.FullRune(b.buf[b.r:b.w]) && b.err == nil && b.w-b.r < len(b.buf) {
- b.fill() // b.w-b.r < len(buf) => buffer is not full
- }
- b.lastRuneSize = -1
- if b.r == b.w {
- return 0, 0, b.readErr()
- }
- r, size = rune(b.buf[b.r]), 1
- if r >= utf8.RuneSelf {
- r, size = utf8.DecodeRune(b.buf[b.r:b.w])
- }
- b.r += size
- b.lastByte = int(b.buf[b.r-1])
- b.lastRuneSize = size
- return r, size, nil
-}
-
-// UnreadRune unreads the last rune. If the most recent method called on
-// the Reader was not a ReadRune, UnreadRune returns an error. (In this
-// regard it is stricter than UnreadByte, which will unread the last byte
-// from any read operation.)
-func (b *Reader) UnreadRune() error {
- if b.lastRuneSize < 0 || b.r < b.lastRuneSize {
- return ErrInvalidUnreadRune
- }
- b.r -= b.lastRuneSize
- b.lastByte = -1
- b.lastRuneSize = -1
- return nil
-}
-
-// Buffered returns the number of bytes that can be read from the current buffer.
-func (b *Reader) Buffered() int { return b.w - b.r }
-
-// ReadSlice reads until the first occurrence of delim in the input,
-// returning a slice pointing at the bytes in the buffer.
-// The bytes stop being valid at the next read.
-// If ReadSlice encounters an error before finding a delimiter,
-// it returns all the data in the buffer and the error itself (often io.EOF).
-// ReadSlice fails with error ErrBufferFull if the buffer fills without a delim.
-// Because the data returned from ReadSlice will be overwritten
-// by the next I/O operation, most clients should use
-// ReadBytes or ReadString instead.
-// ReadSlice returns err != nil if and only if line does not end in delim.
-func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
- s := 0 // search start index
- for {
- // Search buffer.
- if i := bytes.IndexByte(b.buf[b.r+s:b.w], delim); i >= 0 {
- i += s
- line = b.buf[b.r : b.r+i+1]
- b.r += i + 1
- break
- }
-
- // Pending error?
- if b.err != nil {
- line = b.buf[b.r:b.w]
- b.r = b.w
- err = b.readErr()
- break
- }
-
- // Buffer full?
- if b.Buffered() >= len(b.buf) {
- b.r = b.w
- line = b.buf
- err = ErrBufferFull
- break
- }
-
- s = b.w - b.r // do not rescan area we scanned before
-
- b.fill() // buffer is not full
- }
-
- // Handle last byte, if any.
- if i := len(line) - 1; i >= 0 {
- b.lastByte = int(line[i])
- b.lastRuneSize = -1
- }
-
- return
-}
-
-// ReadLine is a low-level line-reading primitive. Most callers should use
-// ReadBytes('\n') or ReadString('\n') instead or use a Scanner.
-//
-// ReadLine tries to return a single line, not including the end-of-line bytes.
-// If the line was too long for the buffer then isPrefix is set and the
-// beginning of the line is returned. The rest of the line will be returned
-// from future calls. isPrefix will be false when returning the last fragment
-// of the line. The returned buffer is only valid until the next call to
-// ReadLine. ReadLine either returns a non-nil line or it returns an error,
-// never both.
-//
-// The text returned from ReadLine does not include the line end ("\r\n" or "\n").
-// No indication or error is given if the input ends without a final line end.
-// Calling UnreadByte after ReadLine will always unread the last byte read
-// (possibly a character belonging to the line end) even if that byte is not
-// part of the line returned by ReadLine.
-func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) {
- line, err = b.ReadSlice('\n')
- if err == ErrBufferFull {
- // Handle the case where "\r\n" straddles the buffer.
- if len(line) > 0 && line[len(line)-1] == '\r' {
- // Put the '\r' back on buf and drop it from line.
- // Let the next call to ReadLine check for "\r\n".
- if b.r == 0 {
- // should be unreachable
- panic("bufio: tried to rewind past start of buffer")
- }
- b.r--
- line = line[:len(line)-1]
- }
- return line, true, nil
- }
-
- if len(line) == 0 {
- if err != nil {
- line = nil
- }
- return
- }
- err = nil
-
- if line[len(line)-1] == '\n' {
- drop := 1
- if len(line) > 1 && line[len(line)-2] == '\r' {
- drop = 2
- }
- line = line[:len(line)-drop]
- }
- return
-}
-
-// collectFragments reads until the first occurrence of delim in the input. It
-// returns (slice of full buffers, remaining bytes before delim, total number
-// of bytes in the combined first two elements, error).
-// The complete result is equal to
-// `bytes.Join(append(fullBuffers, finalFragment), nil)`, which has a
-// length of `totalLen`. The result is structured in this way to allow callers
-// to minimize allocations and copies.
-func (b *Reader) collectFragments(delim byte) (fullBuffers [][]byte, finalFragment []byte, totalLen int, err error) {
- var frag []byte
- // Use ReadSlice to look for delim, accumulating full buffers.
- for {
- var e error
- frag, e = b.ReadSlice(delim)
- if e == nil { // got final fragment
- break
- }
- if e != ErrBufferFull { // unexpected error
- err = e
- break
- }
-
- // Make a copy of the buffer.
- buf := bytes.Clone(frag)
- fullBuffers = append(fullBuffers, buf)
- totalLen += len(buf)
- }
-
- totalLen += len(frag)
- return fullBuffers, frag, totalLen, err
-}
-
-// ReadBytes reads until the first occurrence of delim in the input,
-// returning a slice containing the data up to and including the delimiter.
-// If ReadBytes encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadBytes returns err != nil if and only if the returned data does not end in
-// delim.
-// For simple uses, a Scanner may be more convenient.
-func (b *Reader) ReadBytes(delim byte) ([]byte, error) {
- full, frag, n, err := b.collectFragments(delim)
- // Allocate new buffer to hold the full pieces and the fragment.
- buf := make([]byte, n)
- n = 0
- // Copy full pieces and fragment in.
- for i := range full {
- n += copy(buf[n:], full[i])
- }
- copy(buf[n:], frag)
- return buf, err
-}
-
-// ReadString reads until the first occurrence of delim in the input,
-// returning a string containing the data up to and including the delimiter.
-// If ReadString encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadString returns err != nil if and only if the returned data does not end in
-// delim.
-// For simple uses, a Scanner may be more convenient.
-func (b *Reader) ReadString(delim byte) (string, error) {
- full, frag, n, err := b.collectFragments(delim)
- // Allocate new buffer to hold the full pieces and the fragment.
- var buf strings.Builder
- buf.Grow(n)
- // Copy full pieces and fragment in.
- for _, fb := range full {
- buf.Write(fb)
- }
- buf.Write(frag)
- return buf.String(), err
-}
-
-// WriteTo implements io.WriterTo.
-// This may make multiple calls to the Read method of the underlying Reader.
-// If the underlying reader supports the WriteTo method,
-// this calls the underlying WriteTo without buffering.
-func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
- b.lastByte = -1
- b.lastRuneSize = -1
-
- n, err = b.writeBuf(w)
- if err != nil {
- return
- }
-
- if r, ok := b.rd.(io.WriterTo); ok {
- m, err := r.WriteTo(w)
- n += m
- return n, err
- }
-
- if w, ok := w.(io.ReaderFrom); ok {
- m, err := w.ReadFrom(b.rd)
- n += m
- return n, err
- }
-
- if b.w-b.r < len(b.buf) {
- b.fill() // buffer not full
- }
-
- for b.r < b.w {
- // b.r < b.w => buffer is not empty
- m, err := b.writeBuf(w)
- n += m
- if err != nil {
- return n, err
- }
- b.fill() // buffer is empty
- }
-
- if b.err == io.EOF {
- b.err = nil
- }
-
- return n, b.readErr()
-}
-
-var errNegativeWrite = errors.New("bufio: writer returned negative count from Write")
-
-// writeBuf writes the Reader's buffer to the writer.
-func (b *Reader) writeBuf(w io.Writer) (int64, error) {
- n, err := w.Write(b.buf[b.r:b.w])
- if n < 0 {
- panic(errNegativeWrite)
- }
- b.r += n
- return int64(n), err
-}
-
-// buffered output
-
-// Writer implements buffering for an io.Writer object.
-// If an error occurs writing to a Writer, no more data will be
-// accepted and all subsequent writes, and Flush, will return the error.
-// After all data has been written, the client should call the
-// Flush method to guarantee all data has been forwarded to
-// the underlying io.Writer.
-type Writer struct {
- err error
- buf []byte
- n int
- wr io.Writer
-}
-
-// NewWriterSize returns a new Writer whose buffer has at least the specified
-// size. If the argument io.Writer is already a Writer with large enough
-// size, it returns the underlying Writer.
-func NewWriterSize(w io.Writer, size int) *Writer {
- // Is it already a Writer?
- b, ok := w.(*Writer)
- if ok && len(b.buf) >= size {
- return b
- }
- if size <= 0 {
- size = defaultBufSize
- }
- return &Writer{
- buf: make([]byte, size),
- wr: w,
- }
-}
-
-// NewWriter returns a new Writer whose buffer has the default size.
-// If the argument io.Writer is already a Writer with large enough buffer size,
-// it returns the underlying Writer.
-func NewWriter(w io.Writer) *Writer {
- return NewWriterSize(w, defaultBufSize)
-}
-
-// Size returns the size of the underlying buffer in bytes.
-func (b *Writer) Size() int { return len(b.buf) }
-
-// Reset discards any unflushed buffered data, clears any error, and
-// resets b to write its output to w.
-// Calling Reset on the zero value of Writer initializes the internal buffer
-// to the default size.
-func (b *Writer) Reset(w io.Writer) {
- if b.buf == nil {
- b.buf = make([]byte, defaultBufSize)
- }
- b.err = nil
- b.n = 0
- b.wr = w
-}
-
-// Flush writes any buffered data to the underlying io.Writer.
-func (b *Writer) Flush() error {
- if b.err != nil {
- return b.err
- }
- if b.n == 0 {
- return nil
- }
- n, err := b.wr.Write(b.buf[0:b.n])
- if n < b.n && err == nil {
- err = io.ErrShortWrite
- }
- if err != nil {
- if n > 0 && n < b.n {
- copy(b.buf[0:b.n-n], b.buf[n:b.n])
- }
- b.n -= n
- b.err = err
- return err
- }
- b.n = 0
- return nil
-}
-
-// Available returns how many bytes are unused in the buffer.
-func (b *Writer) Available() int { return len(b.buf) - b.n }
-
-// AvailableBuffer returns an empty buffer with b.Available() capacity.
-// This buffer is intended to be appended to and
-// passed to an immediately succeeding Write call.
-// The buffer is only valid until the next write operation on b.
-func (b *Writer) AvailableBuffer() []byte {
- return b.buf[b.n:][:0]
-}
-
-// Buffered returns the number of bytes that have been written into the current buffer.
-func (b *Writer) Buffered() int { return b.n }
-
-// Write writes the contents of p into the buffer.
-// It returns the number of bytes written.
-// If nn < len(p), it also returns an error explaining
-// why the write is short.
-func (b *Writer) Write(p []byte) (nn int, err error) {
- for len(p) > b.Available() && b.err == nil {
- var n int
- if b.Buffered() == 0 {
- // Large write, empty buffer.
- // Write directly from p to avoid copy.
- n, b.err = b.wr.Write(p)
- } else {
- n = copy(b.buf[b.n:], p)
- b.n += n
- b.Flush()
- }
- nn += n
- p = p[n:]
- }
- if b.err != nil {
- return nn, b.err
- }
- n := copy(b.buf[b.n:], p)
- b.n += n
- nn += n
- return nn, nil
-}
-
-// WriteByte writes a single byte.
-func (b *Writer) WriteByte(c byte) error {
- if b.err != nil {
- return b.err
- }
- if b.Available() <= 0 && b.Flush() != nil {
- return b.err
- }
- b.buf[b.n] = c
- b.n++
- return nil
-}
-
-// WriteRune writes a single Unicode code point, returning
-// the number of bytes written and any error.
-func (b *Writer) WriteRune(r rune) (size int, err error) {
- // Compare as uint32 to correctly handle negative runes.
- if uint32(r) < utf8.RuneSelf {
- err = b.WriteByte(byte(r))
- if err != nil {
- return 0, err
- }
- return 1, nil
- }
- if b.err != nil {
- return 0, b.err
- }
- n := b.Available()
- if n < utf8.UTFMax {
- if b.Flush(); b.err != nil {
- return 0, b.err
- }
- n = b.Available()
- if n < utf8.UTFMax {
- // Can only happen if buffer is silly small.
- return b.WriteString(string(r))
- }
- }
- size = utf8.EncodeRune(b.buf[b.n:], r)
- b.n += size
- return size, nil
-}
-
-// WriteString writes a string.
-// It returns the number of bytes written.
-// If the count is less than len(s), it also returns an error explaining
-// why the write is short.
-func (b *Writer) WriteString(s string) (int, error) {
- var sw io.StringWriter
- tryStringWriter := true
-
- nn := 0
- for len(s) > b.Available() && b.err == nil {
- var n int
- if b.Buffered() == 0 && sw == nil && tryStringWriter {
- // Check at most once whether b.wr is a StringWriter.
- sw, tryStringWriter = b.wr.(io.StringWriter)
- }
- if b.Buffered() == 0 && tryStringWriter {
- // Large write, empty buffer, and the underlying writer supports
- // WriteString: forward the write to the underlying StringWriter.
- // This avoids an extra copy.
- n, b.err = sw.WriteString(s)
- } else {
- n = copy(b.buf[b.n:], s)
- b.n += n
- b.Flush()
- }
- nn += n
- s = s[n:]
- }
- if b.err != nil {
- return nn, b.err
- }
- n := copy(b.buf[b.n:], s)
- b.n += n
- nn += n
- return nn, nil
-}
-
-// ReadFrom implements io.ReaderFrom. If the underlying writer
-// supports the ReadFrom method, this calls the underlying ReadFrom.
-// If there is buffered data and an underlying ReadFrom, this fills
-// the buffer and writes it before calling ReadFrom.
-func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
- if b.err != nil {
- return 0, b.err
- }
- readerFrom, readerFromOK := b.wr.(io.ReaderFrom)
- var m int
- for {
- if b.Available() == 0 {
- if err1 := b.Flush(); err1 != nil {
- return n, err1
- }
- }
- if readerFromOK && b.Buffered() == 0 {
- nn, err := readerFrom.ReadFrom(r)
- b.err = err
- n += nn
- return n, err
- }
- nr := 0
- for nr < maxConsecutiveEmptyReads {
- m, err = r.Read(b.buf[b.n:])
- if m != 0 || err != nil {
- break
- }
- nr++
- }
- if nr == maxConsecutiveEmptyReads {
- return n, io.ErrNoProgress
- }
- b.n += m
- n += int64(m)
- if err != nil {
- break
- }
- }
- if err == io.EOF {
- // If we filled the buffer exactly, flush preemptively.
- if b.Available() == 0 {
- err = b.Flush()
- } else {
- err = nil
- }
- }
- return n, err
-}
-
-// buffered input and output
-
-// ReadWriter stores pointers to a Reader and a Writer.
-// It implements io.ReadWriter.
-type ReadWriter struct {
- *Reader
- *Writer
-}
-
-// NewReadWriter allocates a new ReadWriter that dispatches to r and w.
-func NewReadWriter(r *Reader, w *Writer) *ReadWriter {
- return &ReadWriter{r, w}
-}
diff --git a/contrib/go/_std_1.20/src/bufio/ya.make b/contrib/go/_std_1.20/src/bufio/ya.make
deleted file mode 100644
index dffafbea69..0000000000
--- a/contrib/go/_std_1.20/src/bufio/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- bufio.go
- scan.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/bytes/buffer.go b/contrib/go/_std_1.20/src/bytes/buffer.go
deleted file mode 100644
index ee83fd8b36..0000000000
--- a/contrib/go/_std_1.20/src/bytes/buffer.go
+++ /dev/null
@@ -1,473 +0,0 @@
-// Copyright 2009 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 bytes
-
-// Simple byte buffer for marshaling data.
-
-import (
- "errors"
- "io"
- "unicode/utf8"
-)
-
-// smallBufferSize is an initial allocation minimal capacity.
-const smallBufferSize = 64
-
-// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
-// The zero value for Buffer is an empty buffer ready to use.
-type Buffer struct {
- buf []byte // contents are the bytes buf[off : len(buf)]
- off int // read at &buf[off], write at &buf[len(buf)]
- lastRead readOp // last read operation, so that Unread* can work correctly.
-}
-
-// The readOp constants describe the last action performed on
-// the buffer, so that UnreadRune and UnreadByte can check for
-// invalid usage. opReadRuneX constants are chosen such that
-// converted to int they correspond to the rune size that was read.
-type readOp int8
-
-// Don't use iota for these, as the values need to correspond with the
-// names and comments, which is easier to see when being explicit.
-const (
- opRead readOp = -1 // Any other read operation.
- opInvalid readOp = 0 // Non-read operation.
- opReadRune1 readOp = 1 // Read rune of size 1.
- opReadRune2 readOp = 2 // Read rune of size 2.
- opReadRune3 readOp = 3 // Read rune of size 3.
- opReadRune4 readOp = 4 // Read rune of size 4.
-)
-
-// ErrTooLarge is passed to panic if memory cannot be allocated to store data in a buffer.
-var ErrTooLarge = errors.New("bytes.Buffer: too large")
-var errNegativeRead = errors.New("bytes.Buffer: reader returned negative count from Read")
-
-const maxInt = int(^uint(0) >> 1)
-
-// Bytes returns a slice of length b.Len() holding the unread portion of the buffer.
-// The slice is valid for use only until the next buffer modification (that is,
-// only until the next call to a method like Read, Write, Reset, or Truncate).
-// The slice aliases the buffer content at least until the next buffer modification,
-// so immediate changes to the slice will affect the result of future reads.
-func (b *Buffer) Bytes() []byte { return b.buf[b.off:] }
-
-// String returns the contents of the unread portion of the buffer
-// as a string. If the Buffer is a nil pointer, it returns "<nil>".
-//
-// To build strings more efficiently, see the strings.Builder type.
-func (b *Buffer) String() string {
- if b == nil {
- // Special case, useful in debugging.
- return "<nil>"
- }
- return string(b.buf[b.off:])
-}
-
-// empty reports whether the unread portion of the buffer is empty.
-func (b *Buffer) empty() bool { return len(b.buf) <= b.off }
-
-// Len returns the number of bytes of the unread portion of the buffer;
-// b.Len() == len(b.Bytes()).
-func (b *Buffer) Len() int { return len(b.buf) - b.off }
-
-// Cap returns the capacity of the buffer's underlying byte slice, that is, the
-// total space allocated for the buffer's data.
-func (b *Buffer) Cap() int { return cap(b.buf) }
-
-// Truncate discards all but the first n unread bytes from the buffer
-// but continues to use the same allocated storage.
-// It panics if n is negative or greater than the length of the buffer.
-func (b *Buffer) Truncate(n int) {
- if n == 0 {
- b.Reset()
- return
- }
- b.lastRead = opInvalid
- if n < 0 || n > b.Len() {
- panic("bytes.Buffer: truncation out of range")
- }
- b.buf = b.buf[:b.off+n]
-}
-
-// Reset resets the buffer to be empty,
-// but it retains the underlying storage for use by future writes.
-// Reset is the same as Truncate(0).
-func (b *Buffer) Reset() {
- b.buf = b.buf[:0]
- b.off = 0
- b.lastRead = opInvalid
-}
-
-// tryGrowByReslice is a inlineable version of grow for the fast-case where the
-// internal buffer only needs to be resliced.
-// It returns the index where bytes should be written and whether it succeeded.
-func (b *Buffer) tryGrowByReslice(n int) (int, bool) {
- if l := len(b.buf); n <= cap(b.buf)-l {
- b.buf = b.buf[:l+n]
- return l, true
- }
- return 0, false
-}
-
-// grow grows the buffer to guarantee space for n more bytes.
-// It returns the index where bytes should be written.
-// If the buffer can't grow it will panic with ErrTooLarge.
-func (b *Buffer) grow(n int) int {
- m := b.Len()
- // If buffer is empty, reset to recover space.
- if m == 0 && b.off != 0 {
- b.Reset()
- }
- // Try to grow by means of a reslice.
- if i, ok := b.tryGrowByReslice(n); ok {
- return i
- }
- if b.buf == nil && n <= smallBufferSize {
- b.buf = make([]byte, n, smallBufferSize)
- return 0
- }
- c := cap(b.buf)
- if n <= c/2-m {
- // We can slide things down instead of allocating a new
- // slice. We only need m+n <= c to slide, but
- // we instead let capacity get twice as large so we
- // don't spend all our time copying.
- copy(b.buf, b.buf[b.off:])
- } else if c > maxInt-c-n {
- panic(ErrTooLarge)
- } else {
- // Add b.off to account for b.buf[:b.off] being sliced off the front.
- b.buf = growSlice(b.buf[b.off:], b.off+n)
- }
- // Restore b.off and len(b.buf).
- b.off = 0
- b.buf = b.buf[:m+n]
- return m
-}
-
-// Grow grows the buffer's capacity, if necessary, to guarantee space for
-// another n bytes. After Grow(n), at least n bytes can be written to the
-// buffer without another allocation.
-// If n is negative, Grow will panic.
-// If the buffer can't grow it will panic with ErrTooLarge.
-func (b *Buffer) Grow(n int) {
- if n < 0 {
- panic("bytes.Buffer.Grow: negative count")
- }
- m := b.grow(n)
- b.buf = b.buf[:m]
-}
-
-// Write appends the contents of p to the buffer, growing the buffer as
-// needed. The return value n is the length of p; err is always nil. If the
-// buffer becomes too large, Write will panic with ErrTooLarge.
-func (b *Buffer) Write(p []byte) (n int, err error) {
- b.lastRead = opInvalid
- m, ok := b.tryGrowByReslice(len(p))
- if !ok {
- m = b.grow(len(p))
- }
- return copy(b.buf[m:], p), nil
-}
-
-// WriteString appends the contents of s to the buffer, growing the buffer as
-// needed. The return value n is the length of s; err is always nil. If the
-// buffer becomes too large, WriteString will panic with ErrTooLarge.
-func (b *Buffer) WriteString(s string) (n int, err error) {
- b.lastRead = opInvalid
- m, ok := b.tryGrowByReslice(len(s))
- if !ok {
- m = b.grow(len(s))
- }
- return copy(b.buf[m:], s), nil
-}
-
-// MinRead is the minimum slice size passed to a Read call by
-// Buffer.ReadFrom. As long as the Buffer has at least MinRead bytes beyond
-// what is required to hold the contents of r, ReadFrom will not grow the
-// underlying buffer.
-const MinRead = 512
-
-// ReadFrom reads data from r until EOF and appends it to the buffer, growing
-// the buffer as needed. The return value n is the number of bytes read. Any
-// error except io.EOF encountered during the read is also returned. If the
-// buffer becomes too large, ReadFrom will panic with ErrTooLarge.
-func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
- b.lastRead = opInvalid
- for {
- i := b.grow(MinRead)
- b.buf = b.buf[:i]
- m, e := r.Read(b.buf[i:cap(b.buf)])
- if m < 0 {
- panic(errNegativeRead)
- }
-
- b.buf = b.buf[:i+m]
- n += int64(m)
- if e == io.EOF {
- return n, nil // e is EOF, so return nil explicitly
- }
- if e != nil {
- return n, e
- }
- }
-}
-
-// growSlice grows b by n, preserving the original content of b.
-// If the allocation fails, it panics with ErrTooLarge.
-func growSlice(b []byte, n int) []byte {
- defer func() {
- if recover() != nil {
- panic(ErrTooLarge)
- }
- }()
- // TODO(http://golang.org/issue/51462): We should rely on the append-make
- // pattern so that the compiler can call runtime.growslice. For example:
- // return append(b, make([]byte, n)...)
- // This avoids unnecessary zero-ing of the first len(b) bytes of the
- // allocated slice, but this pattern causes b to escape onto the heap.
- //
- // Instead use the append-make pattern with a nil slice to ensure that
- // we allocate buffers rounded up to the closest size class.
- c := len(b) + n // ensure enough space for n elements
- if c < 2*cap(b) {
- // The growth rate has historically always been 2x. In the future,
- // we could rely purely on append to determine the growth rate.
- c = 2 * cap(b)
- }
- b2 := append([]byte(nil), make([]byte, c)...)
- copy(b2, b)
- return b2[:len(b)]
-}
-
-// WriteTo writes data to w until the buffer is drained or an error occurs.
-// The return value n is the number of bytes written; it always fits into an
-// int, but it is int64 to match the io.WriterTo interface. Any error
-// encountered during the write is also returned.
-func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {
- b.lastRead = opInvalid
- if nBytes := b.Len(); nBytes > 0 {
- m, e := w.Write(b.buf[b.off:])
- if m > nBytes {
- panic("bytes.Buffer.WriteTo: invalid Write count")
- }
- b.off += m
- n = int64(m)
- if e != nil {
- return n, e
- }
- // all bytes should have been written, by definition of
- // Write method in io.Writer
- if m != nBytes {
- return n, io.ErrShortWrite
- }
- }
- // Buffer is now empty; reset.
- b.Reset()
- return n, nil
-}
-
-// WriteByte appends the byte c to the buffer, growing the buffer as needed.
-// The returned error is always nil, but is included to match bufio.Writer's
-// WriteByte. If the buffer becomes too large, WriteByte will panic with
-// ErrTooLarge.
-func (b *Buffer) WriteByte(c byte) error {
- b.lastRead = opInvalid
- m, ok := b.tryGrowByReslice(1)
- if !ok {
- m = b.grow(1)
- }
- b.buf[m] = c
- return nil
-}
-
-// WriteRune appends the UTF-8 encoding of Unicode code point r to the
-// buffer, returning its length and an error, which is always nil but is
-// included to match bufio.Writer's WriteRune. The buffer is grown as needed;
-// if it becomes too large, WriteRune will panic with ErrTooLarge.
-func (b *Buffer) WriteRune(r rune) (n int, err error) {
- // Compare as uint32 to correctly handle negative runes.
- if uint32(r) < utf8.RuneSelf {
- b.WriteByte(byte(r))
- return 1, nil
- }
- b.lastRead = opInvalid
- m, ok := b.tryGrowByReslice(utf8.UTFMax)
- if !ok {
- m = b.grow(utf8.UTFMax)
- }
- b.buf = utf8.AppendRune(b.buf[:m], r)
- return len(b.buf) - m, nil
-}
-
-// Read reads the next len(p) bytes from the buffer or until the buffer
-// is drained. The return value n is the number of bytes read. If the
-// buffer has no data to return, err is io.EOF (unless len(p) is zero);
-// otherwise it is nil.
-func (b *Buffer) Read(p []byte) (n int, err error) {
- b.lastRead = opInvalid
- if b.empty() {
- // Buffer is empty, reset to recover space.
- b.Reset()
- if len(p) == 0 {
- return 0, nil
- }
- return 0, io.EOF
- }
- n = copy(p, b.buf[b.off:])
- b.off += n
- if n > 0 {
- b.lastRead = opRead
- }
- return n, nil
-}
-
-// Next returns a slice containing the next n bytes from the buffer,
-// advancing the buffer as if the bytes had been returned by Read.
-// If there are fewer than n bytes in the buffer, Next returns the entire buffer.
-// The slice is only valid until the next call to a read or write method.
-func (b *Buffer) Next(n int) []byte {
- b.lastRead = opInvalid
- m := b.Len()
- if n > m {
- n = m
- }
- data := b.buf[b.off : b.off+n]
- b.off += n
- if n > 0 {
- b.lastRead = opRead
- }
- return data
-}
-
-// ReadByte reads and returns the next byte from the buffer.
-// If no byte is available, it returns error io.EOF.
-func (b *Buffer) ReadByte() (byte, error) {
- if b.empty() {
- // Buffer is empty, reset to recover space.
- b.Reset()
- return 0, io.EOF
- }
- c := b.buf[b.off]
- b.off++
- b.lastRead = opRead
- return c, nil
-}
-
-// ReadRune reads and returns the next UTF-8-encoded
-// Unicode code point from the buffer.
-// If no bytes are available, the error returned is io.EOF.
-// If the bytes are an erroneous UTF-8 encoding, it
-// consumes one byte and returns U+FFFD, 1.
-func (b *Buffer) ReadRune() (r rune, size int, err error) {
- if b.empty() {
- // Buffer is empty, reset to recover space.
- b.Reset()
- return 0, 0, io.EOF
- }
- c := b.buf[b.off]
- if c < utf8.RuneSelf {
- b.off++
- b.lastRead = opReadRune1
- return rune(c), 1, nil
- }
- r, n := utf8.DecodeRune(b.buf[b.off:])
- b.off += n
- b.lastRead = readOp(n)
- return r, n, nil
-}
-
-// UnreadRune unreads the last rune returned by ReadRune.
-// If the most recent read or write operation on the buffer was
-// not a successful ReadRune, UnreadRune returns an error. (In this regard
-// it is stricter than UnreadByte, which will unread the last byte
-// from any read operation.)
-func (b *Buffer) UnreadRune() error {
- if b.lastRead <= opInvalid {
- return errors.New("bytes.Buffer: UnreadRune: previous operation was not a successful ReadRune")
- }
- if b.off >= int(b.lastRead) {
- b.off -= int(b.lastRead)
- }
- b.lastRead = opInvalid
- return nil
-}
-
-var errUnreadByte = errors.New("bytes.Buffer: UnreadByte: previous operation was not a successful read")
-
-// UnreadByte unreads the last byte returned by the most recent successful
-// read operation that read at least one byte. If a write has happened since
-// the last read, if the last read returned an error, or if the read read zero
-// bytes, UnreadByte returns an error.
-func (b *Buffer) UnreadByte() error {
- if b.lastRead == opInvalid {
- return errUnreadByte
- }
- b.lastRead = opInvalid
- if b.off > 0 {
- b.off--
- }
- return nil
-}
-
-// ReadBytes reads until the first occurrence of delim in the input,
-// returning a slice containing the data up to and including the delimiter.
-// If ReadBytes encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadBytes returns err != nil if and only if the returned data does not end in
-// delim.
-func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) {
- slice, err := b.readSlice(delim)
- // return a copy of slice. The buffer's backing array may
- // be overwritten by later calls.
- line = append(line, slice...)
- return line, err
-}
-
-// readSlice is like ReadBytes but returns a reference to internal buffer data.
-func (b *Buffer) readSlice(delim byte) (line []byte, err error) {
- i := IndexByte(b.buf[b.off:], delim)
- end := b.off + i + 1
- if i < 0 {
- end = len(b.buf)
- err = io.EOF
- }
- line = b.buf[b.off:end]
- b.off = end
- b.lastRead = opRead
- return line, err
-}
-
-// ReadString reads until the first occurrence of delim in the input,
-// returning a string containing the data up to and including the delimiter.
-// If ReadString encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadString returns err != nil if and only if the returned data does not end
-// in delim.
-func (b *Buffer) ReadString(delim byte) (line string, err error) {
- slice, err := b.readSlice(delim)
- return string(slice), err
-}
-
-// NewBuffer creates and initializes a new Buffer using buf as its
-// initial contents. The new Buffer takes ownership of buf, and the
-// caller should not use buf after this call. NewBuffer is intended to
-// prepare a Buffer to read existing data. It can also be used to set
-// the initial size of the internal buffer for writing. To do that,
-// buf should have the desired capacity but a length of zero.
-//
-// In most cases, new(Buffer) (or just declaring a Buffer variable) is
-// sufficient to initialize a Buffer.
-func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }
-
-// NewBufferString creates and initializes a new Buffer using string s as its
-// initial contents. It is intended to prepare a buffer to read an existing
-// string.
-//
-// In most cases, new(Buffer) (or just declaring a Buffer variable) is
-// sufficient to initialize a Buffer.
-func NewBufferString(s string) *Buffer {
- return &Buffer{buf: []byte(s)}
-}
diff --git a/contrib/go/_std_1.20/src/bytes/bytes.go b/contrib/go/_std_1.20/src/bytes/bytes.go
deleted file mode 100644
index e2e5d5fda7..0000000000
--- a/contrib/go/_std_1.20/src/bytes/bytes.go
+++ /dev/null
@@ -1,1381 +0,0 @@
-// Copyright 2009 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 bytes implements functions for the manipulation of byte slices.
-// It is analogous to the facilities of the strings package.
-package bytes
-
-import (
- "internal/bytealg"
- "unicode"
- "unicode/utf8"
-)
-
-// Equal reports whether a and b
-// are the same length and contain the same bytes.
-// A nil argument is equivalent to an empty slice.
-func Equal(a, b []byte) bool {
- // Neither cmd/compile nor gccgo allocates for these string conversions.
- return string(a) == string(b)
-}
-
-// Compare returns an integer comparing two byte slices lexicographically.
-// The result will be 0 if a == b, -1 if a < b, and +1 if a > b.
-// A nil argument is equivalent to an empty slice.
-func Compare(a, b []byte) int {
- return bytealg.Compare(a, b)
-}
-
-// explode splits s into a slice of UTF-8 sequences, one per Unicode code point (still slices of bytes),
-// up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes.
-func explode(s []byte, n int) [][]byte {
- if n <= 0 || n > len(s) {
- n = len(s)
- }
- a := make([][]byte, n)
- var size int
- na := 0
- for len(s) > 0 {
- if na+1 >= n {
- a[na] = s
- na++
- break
- }
- _, size = utf8.DecodeRune(s)
- a[na] = s[0:size:size]
- s = s[size:]
- na++
- }
- return a[0:na]
-}
-
-// Count counts the number of non-overlapping instances of sep in s.
-// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
-func Count(s, sep []byte) int {
- // special case
- if len(sep) == 0 {
- return utf8.RuneCount(s) + 1
- }
- if len(sep) == 1 {
- return bytealg.Count(s, sep[0])
- }
- n := 0
- for {
- i := Index(s, sep)
- if i == -1 {
- return n
- }
- n++
- s = s[i+len(sep):]
- }
-}
-
-// Contains reports whether subslice is within b.
-func Contains(b, subslice []byte) bool {
- return Index(b, subslice) != -1
-}
-
-// ContainsAny reports whether any of the UTF-8-encoded code points in chars are within b.
-func ContainsAny(b []byte, chars string) bool {
- return IndexAny(b, chars) >= 0
-}
-
-// ContainsRune reports whether the rune is contained in the UTF-8-encoded byte slice b.
-func ContainsRune(b []byte, r rune) bool {
- return IndexRune(b, r) >= 0
-}
-
-// IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b.
-func IndexByte(b []byte, c byte) int {
- return bytealg.IndexByte(b, c)
-}
-
-func indexBytePortable(s []byte, c byte) int {
- for i, b := range s {
- if b == c {
- return i
- }
- }
- return -1
-}
-
-// LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s.
-func LastIndex(s, sep []byte) int {
- n := len(sep)
- switch {
- case n == 0:
- return len(s)
- case n == 1:
- return LastIndexByte(s, sep[0])
- case n == len(s):
- if Equal(s, sep) {
- return 0
- }
- return -1
- case n > len(s):
- return -1
- }
- // Rabin-Karp search from the end of the string
- hashss, pow := bytealg.HashStrRevBytes(sep)
- last := len(s) - n
- var h uint32
- for i := len(s) - 1; i >= last; i-- {
- h = h*bytealg.PrimeRK + uint32(s[i])
- }
- if h == hashss && Equal(s[last:], sep) {
- return last
- }
- for i := last - 1; i >= 0; i-- {
- h *= bytealg.PrimeRK
- h += uint32(s[i])
- h -= pow * uint32(s[i+n])
- if h == hashss && Equal(s[i:i+n], sep) {
- return i
- }
- }
- return -1
-}
-
-// LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
-func LastIndexByte(s []byte, c byte) int {
- for i := len(s) - 1; i >= 0; i-- {
- if s[i] == c {
- return i
- }
- }
- return -1
-}
-
-// IndexRune interprets s as a sequence of UTF-8-encoded code points.
-// It returns the byte index of the first occurrence in s of the given rune.
-// It returns -1 if rune is not present in s.
-// If r is utf8.RuneError, it returns the first instance of any
-// invalid UTF-8 byte sequence.
-func IndexRune(s []byte, r rune) int {
- switch {
- case 0 <= r && r < utf8.RuneSelf:
- return IndexByte(s, byte(r))
- case r == utf8.RuneError:
- for i := 0; i < len(s); {
- r1, n := utf8.DecodeRune(s[i:])
- if r1 == utf8.RuneError {
- return i
- }
- i += n
- }
- return -1
- case !utf8.ValidRune(r):
- return -1
- default:
- var b [utf8.UTFMax]byte
- n := utf8.EncodeRune(b[:], r)
- return Index(s, b[:n])
- }
-}
-
-// IndexAny interprets s as a sequence of UTF-8-encoded Unicode code points.
-// It returns the byte index of the first occurrence in s of any of the Unicode
-// code points in chars. It returns -1 if chars is empty or if there is no code
-// point in common.
-func IndexAny(s []byte, chars string) int {
- if chars == "" {
- // Avoid scanning all of s.
- return -1
- }
- if len(s) == 1 {
- r := rune(s[0])
- if r >= utf8.RuneSelf {
- // search utf8.RuneError.
- for _, r = range chars {
- if r == utf8.RuneError {
- return 0
- }
- }
- return -1
- }
- if bytealg.IndexByteString(chars, s[0]) >= 0 {
- return 0
- }
- return -1
- }
- if len(chars) == 1 {
- r := rune(chars[0])
- if r >= utf8.RuneSelf {
- r = utf8.RuneError
- }
- return IndexRune(s, r)
- }
- if len(s) > 8 {
- if as, isASCII := makeASCIISet(chars); isASCII {
- for i, c := range s {
- if as.contains(c) {
- return i
- }
- }
- return -1
- }
- }
- var width int
- for i := 0; i < len(s); i += width {
- r := rune(s[i])
- if r < utf8.RuneSelf {
- if bytealg.IndexByteString(chars, s[i]) >= 0 {
- return i
- }
- width = 1
- continue
- }
- r, width = utf8.DecodeRune(s[i:])
- if r != utf8.RuneError {
- // r is 2 to 4 bytes
- if len(chars) == width {
- if chars == string(r) {
- return i
- }
- continue
- }
- // Use bytealg.IndexString for performance if available.
- if bytealg.MaxLen >= width {
- if bytealg.IndexString(chars, string(r)) >= 0 {
- return i
- }
- continue
- }
- }
- for _, ch := range chars {
- if r == ch {
- return i
- }
- }
- }
- return -1
-}
-
-// LastIndexAny interprets s as a sequence of UTF-8-encoded Unicode code
-// points. It returns the byte index of the last occurrence in s of any of
-// the Unicode code points in chars. It returns -1 if chars is empty or if
-// there is no code point in common.
-func LastIndexAny(s []byte, chars string) int {
- if chars == "" {
- // Avoid scanning all of s.
- return -1
- }
- if len(s) > 8 {
- if as, isASCII := makeASCIISet(chars); isASCII {
- for i := len(s) - 1; i >= 0; i-- {
- if as.contains(s[i]) {
- return i
- }
- }
- return -1
- }
- }
- if len(s) == 1 {
- r := rune(s[0])
- if r >= utf8.RuneSelf {
- for _, r = range chars {
- if r == utf8.RuneError {
- return 0
- }
- }
- return -1
- }
- if bytealg.IndexByteString(chars, s[0]) >= 0 {
- return 0
- }
- return -1
- }
- if len(chars) == 1 {
- cr := rune(chars[0])
- if cr >= utf8.RuneSelf {
- cr = utf8.RuneError
- }
- for i := len(s); i > 0; {
- r, size := utf8.DecodeLastRune(s[:i])
- i -= size
- if r == cr {
- return i
- }
- }
- return -1
- }
- for i := len(s); i > 0; {
- r := rune(s[i-1])
- if r < utf8.RuneSelf {
- if bytealg.IndexByteString(chars, s[i-1]) >= 0 {
- return i - 1
- }
- i--
- continue
- }
- r, size := utf8.DecodeLastRune(s[:i])
- i -= size
- if r != utf8.RuneError {
- // r is 2 to 4 bytes
- if len(chars) == size {
- if chars == string(r) {
- return i
- }
- continue
- }
- // Use bytealg.IndexString for performance if available.
- if bytealg.MaxLen >= size {
- if bytealg.IndexString(chars, string(r)) >= 0 {
- return i
- }
- continue
- }
- }
- for _, ch := range chars {
- if r == ch {
- return i
- }
- }
- }
- return -1
-}
-
-// Generic split: splits after each instance of sep,
-// including sepSave bytes of sep in the subslices.
-func genSplit(s, sep []byte, sepSave, n int) [][]byte {
- if n == 0 {
- return nil
- }
- if len(sep) == 0 {
- return explode(s, n)
- }
- if n < 0 {
- n = Count(s, sep) + 1
- }
- if n > len(s)+1 {
- n = len(s) + 1
- }
-
- a := make([][]byte, n)
- n--
- i := 0
- for i < n {
- m := Index(s, sep)
- if m < 0 {
- break
- }
- a[i] = s[: m+sepSave : m+sepSave]
- s = s[m+len(sep):]
- i++
- }
- a[i] = s
- return a[:i+1]
-}
-
-// SplitN slices s into subslices separated by sep and returns a slice of
-// the subslices between those separators.
-// If sep is empty, SplitN splits after each UTF-8 sequence.
-// The count determines the number of subslices to return:
-//
-// n > 0: at most n subslices; the last subslice will be the unsplit remainder.
-// n == 0: the result is nil (zero subslices)
-// n < 0: all subslices
-//
-// To split around the first instance of a separator, see Cut.
-func SplitN(s, sep []byte, n int) [][]byte { return genSplit(s, sep, 0, n) }
-
-// SplitAfterN slices s into subslices after each instance of sep and
-// returns a slice of those subslices.
-// If sep is empty, SplitAfterN splits after each UTF-8 sequence.
-// The count determines the number of subslices to return:
-//
-// n > 0: at most n subslices; the last subslice will be the unsplit remainder.
-// n == 0: the result is nil (zero subslices)
-// n < 0: all subslices
-func SplitAfterN(s, sep []byte, n int) [][]byte {
- return genSplit(s, sep, len(sep), n)
-}
-
-// Split slices s into all subslices separated by sep and returns a slice of
-// the subslices between those separators.
-// If sep is empty, Split splits after each UTF-8 sequence.
-// It is equivalent to SplitN with a count of -1.
-//
-// To split around the first instance of a separator, see Cut.
-func Split(s, sep []byte) [][]byte { return genSplit(s, sep, 0, -1) }
-
-// SplitAfter slices s into all subslices after each instance of sep and
-// returns a slice of those subslices.
-// If sep is empty, SplitAfter splits after each UTF-8 sequence.
-// It is equivalent to SplitAfterN with a count of -1.
-func SplitAfter(s, sep []byte) [][]byte {
- return genSplit(s, sep, len(sep), -1)
-}
-
-var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
-
-// Fields interprets s as a sequence of UTF-8-encoded code points.
-// It splits the slice s around each instance of one or more consecutive white space
-// characters, as defined by unicode.IsSpace, returning a slice of subslices of s or an
-// empty slice if s contains only white space.
-func Fields(s []byte) [][]byte {
- // First count the fields.
- // This is an exact count if s is ASCII, otherwise it is an approximation.
- n := 0
- wasSpace := 1
- // setBits is used to track which bits are set in the bytes of s.
- setBits := uint8(0)
- for i := 0; i < len(s); i++ {
- r := s[i]
- setBits |= r
- isSpace := int(asciiSpace[r])
- n += wasSpace & ^isSpace
- wasSpace = isSpace
- }
-
- if setBits >= utf8.RuneSelf {
- // Some runes in the input slice are not ASCII.
- return FieldsFunc(s, unicode.IsSpace)
- }
-
- // ASCII fast path
- a := make([][]byte, n)
- na := 0
- fieldStart := 0
- i := 0
- // Skip spaces in the front of the input.
- for i < len(s) && asciiSpace[s[i]] != 0 {
- i++
- }
- fieldStart = i
- for i < len(s) {
- if asciiSpace[s[i]] == 0 {
- i++
- continue
- }
- a[na] = s[fieldStart:i:i]
- na++
- i++
- // Skip spaces in between fields.
- for i < len(s) && asciiSpace[s[i]] != 0 {
- i++
- }
- fieldStart = i
- }
- if fieldStart < len(s) { // Last field might end at EOF.
- a[na] = s[fieldStart:len(s):len(s)]
- }
- return a
-}
-
-// FieldsFunc interprets s as a sequence of UTF-8-encoded code points.
-// It splits the slice s at each run of code points c satisfying f(c) and
-// returns a slice of subslices of s. If all code points in s satisfy f(c), or
-// len(s) == 0, an empty slice is returned.
-//
-// FieldsFunc makes no guarantees about the order in which it calls f(c)
-// and assumes that f always returns the same value for a given c.
-func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
- // A span is used to record a slice of s of the form s[start:end].
- // The start index is inclusive and the end index is exclusive.
- type span struct {
- start int
- end int
- }
- spans := make([]span, 0, 32)
-
- // Find the field start and end indices.
- // Doing this in a separate pass (rather than slicing the string s
- // and collecting the result substrings right away) is significantly
- // more efficient, possibly due to cache effects.
- start := -1 // valid span start if >= 0
- for i := 0; i < len(s); {
- size := 1
- r := rune(s[i])
- if r >= utf8.RuneSelf {
- r, size = utf8.DecodeRune(s[i:])
- }
- if f(r) {
- if start >= 0 {
- spans = append(spans, span{start, i})
- start = -1
- }
- } else {
- if start < 0 {
- start = i
- }
- }
- i += size
- }
-
- // Last field might end at EOF.
- if start >= 0 {
- spans = append(spans, span{start, len(s)})
- }
-
- // Create subslices from recorded field indices.
- a := make([][]byte, len(spans))
- for i, span := range spans {
- a[i] = s[span.start:span.end:span.end]
- }
-
- return a
-}
-
-// Join concatenates the elements of s to create a new byte slice. The separator
-// sep is placed between elements in the resulting slice.
-func Join(s [][]byte, sep []byte) []byte {
- if len(s) == 0 {
- return []byte{}
- }
- if len(s) == 1 {
- // Just return a copy.
- return append([]byte(nil), s[0]...)
- }
- n := len(sep) * (len(s) - 1)
- for _, v := range s {
- n += len(v)
- }
-
- b := make([]byte, n)
- bp := copy(b, s[0])
- for _, v := range s[1:] {
- bp += copy(b[bp:], sep)
- bp += copy(b[bp:], v)
- }
- return b
-}
-
-// HasPrefix tests whether the byte slice s begins with prefix.
-func HasPrefix(s, prefix []byte) bool {
- return len(s) >= len(prefix) && Equal(s[0:len(prefix)], prefix)
-}
-
-// HasSuffix tests whether the byte slice s ends with suffix.
-func HasSuffix(s, suffix []byte) bool {
- return len(s) >= len(suffix) && Equal(s[len(s)-len(suffix):], suffix)
-}
-
-// Map returns a copy of the byte slice s with all its characters modified
-// according to the mapping function. If mapping returns a negative value, the character is
-// dropped from the byte slice with no replacement. The characters in s and the
-// output are interpreted as UTF-8-encoded code points.
-func Map(mapping func(r rune) rune, s []byte) []byte {
- // In the worst case, the slice can grow when mapped, making
- // things unpleasant. But it's so rare we barge in assuming it's
- // fine. It could also shrink but that falls out naturally.
- b := make([]byte, 0, len(s))
- for i := 0; i < len(s); {
- wid := 1
- r := rune(s[i])
- if r >= utf8.RuneSelf {
- r, wid = utf8.DecodeRune(s[i:])
- }
- r = mapping(r)
- if r >= 0 {
- b = utf8.AppendRune(b, r)
- }
- i += wid
- }
- return b
-}
-
-// Repeat returns a new byte slice consisting of count copies of b.
-//
-// It panics if count is negative or if the result of (len(b) * count)
-// overflows.
-func Repeat(b []byte, count int) []byte {
- if count == 0 {
- return []byte{}
- }
- // Since we cannot return an error on overflow,
- // we should panic if the repeat will generate
- // an overflow.
- // See golang.org/issue/16237.
- if count < 0 {
- panic("bytes: negative Repeat count")
- } else if len(b)*count/count != len(b) {
- panic("bytes: Repeat count causes overflow")
- }
-
- if len(b) == 0 {
- return []byte{}
- }
-
- n := len(b) * count
-
- // Past a certain chunk size it is counterproductive to use
- // larger chunks as the source of the write, as when the source
- // is too large we are basically just thrashing the CPU D-cache.
- // So if the result length is larger than an empirically-found
- // limit (8KB), we stop growing the source string once the limit
- // is reached and keep reusing the same source string - that
- // should therefore be always resident in the L1 cache - until we
- // have completed the construction of the result.
- // This yields significant speedups (up to +100%) in cases where
- // the result length is large (roughly, over L2 cache size).
- const chunkLimit = 8 * 1024
- chunkMax := n
- if chunkMax > chunkLimit {
- chunkMax = chunkLimit / len(b) * len(b)
- if chunkMax == 0 {
- chunkMax = len(b)
- }
- }
- nb := make([]byte, n)
- bp := copy(nb, b)
- for bp < len(nb) {
- chunk := bp
- if chunk > chunkMax {
- chunk = chunkMax
- }
- bp += copy(nb[bp:], nb[:chunk])
- }
- return nb
-}
-
-// ToUpper returns a copy of the byte slice s with all Unicode letters mapped to
-// their upper case.
-func ToUpper(s []byte) []byte {
- isASCII, hasLower := true, false
- for i := 0; i < len(s); i++ {
- c := s[i]
- if c >= utf8.RuneSelf {
- isASCII = false
- break
- }
- hasLower = hasLower || ('a' <= c && c <= 'z')
- }
-
- if isASCII { // optimize for ASCII-only byte slices.
- if !hasLower {
- // Just return a copy.
- return append([]byte(""), s...)
- }
- b := make([]byte, len(s))
- for i := 0; i < len(s); i++ {
- c := s[i]
- if 'a' <= c && c <= 'z' {
- c -= 'a' - 'A'
- }
- b[i] = c
- }
- return b
- }
- return Map(unicode.ToUpper, s)
-}
-
-// ToLower returns a copy of the byte slice s with all Unicode letters mapped to
-// their lower case.
-func ToLower(s []byte) []byte {
- isASCII, hasUpper := true, false
- for i := 0; i < len(s); i++ {
- c := s[i]
- if c >= utf8.RuneSelf {
- isASCII = false
- break
- }
- hasUpper = hasUpper || ('A' <= c && c <= 'Z')
- }
-
- if isASCII { // optimize for ASCII-only byte slices.
- if !hasUpper {
- return append([]byte(""), s...)
- }
- b := make([]byte, len(s))
- for i := 0; i < len(s); i++ {
- c := s[i]
- if 'A' <= c && c <= 'Z' {
- c += 'a' - 'A'
- }
- b[i] = c
- }
- return b
- }
- return Map(unicode.ToLower, s)
-}
-
-// ToTitle treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their title case.
-func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) }
-
-// ToUpperSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
-// upper case, giving priority to the special casing rules.
-func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte {
- return Map(c.ToUpper, s)
-}
-
-// ToLowerSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
-// lower case, giving priority to the special casing rules.
-func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte {
- return Map(c.ToLower, s)
-}
-
-// ToTitleSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
-// title case, giving priority to the special casing rules.
-func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte {
- return Map(c.ToTitle, s)
-}
-
-// ToValidUTF8 treats s as UTF-8-encoded bytes and returns a copy with each run of bytes
-// representing invalid UTF-8 replaced with the bytes in replacement, which may be empty.
-func ToValidUTF8(s, replacement []byte) []byte {
- b := make([]byte, 0, len(s)+len(replacement))
- invalid := false // previous byte was from an invalid UTF-8 sequence
- for i := 0; i < len(s); {
- c := s[i]
- if c < utf8.RuneSelf {
- i++
- invalid = false
- b = append(b, c)
- continue
- }
- _, wid := utf8.DecodeRune(s[i:])
- if wid == 1 {
- i++
- if !invalid {
- invalid = true
- b = append(b, replacement...)
- }
- continue
- }
- invalid = false
- b = append(b, s[i:i+wid]...)
- i += wid
- }
- return b
-}
-
-// isSeparator reports whether the rune could mark a word boundary.
-// TODO: update when package unicode captures more of the properties.
-func isSeparator(r rune) bool {
- // ASCII alphanumerics and underscore are not separators
- if r <= 0x7F {
- switch {
- case '0' <= r && r <= '9':
- return false
- case 'a' <= r && r <= 'z':
- return false
- case 'A' <= r && r <= 'Z':
- return false
- case r == '_':
- return false
- }
- return true
- }
- // Letters and digits are not separators
- if unicode.IsLetter(r) || unicode.IsDigit(r) {
- return false
- }
- // Otherwise, all we can do for now is treat spaces as separators.
- return unicode.IsSpace(r)
-}
-
-// Title treats s as UTF-8-encoded bytes and returns a copy with all Unicode letters that begin
-// words mapped to their title case.
-//
-// Deprecated: The rule Title uses for word boundaries does not handle Unicode
-// punctuation properly. Use golang.org/x/text/cases instead.
-func Title(s []byte) []byte {
- // Use a closure here to remember state.
- // Hackish but effective. Depends on Map scanning in order and calling
- // the closure once per rune.
- prev := ' '
- return Map(
- func(r rune) rune {
- if isSeparator(prev) {
- prev = r
- return unicode.ToTitle(r)
- }
- prev = r
- return r
- },
- s)
-}
-
-// TrimLeftFunc treats s as UTF-8-encoded bytes and returns a subslice of s by slicing off
-// all leading UTF-8-encoded code points c that satisfy f(c).
-func TrimLeftFunc(s []byte, f func(r rune) bool) []byte {
- i := indexFunc(s, f, false)
- if i == -1 {
- return nil
- }
- return s[i:]
-}
-
-// TrimRightFunc returns a subslice of s by slicing off all trailing
-// UTF-8-encoded code points c that satisfy f(c).
-func TrimRightFunc(s []byte, f func(r rune) bool) []byte {
- i := lastIndexFunc(s, f, false)
- if i >= 0 && s[i] >= utf8.RuneSelf {
- _, wid := utf8.DecodeRune(s[i:])
- i += wid
- } else {
- i++
- }
- return s[0:i]
-}
-
-// TrimFunc returns a subslice of s by slicing off all leading and trailing
-// UTF-8-encoded code points c that satisfy f(c).
-func TrimFunc(s []byte, f func(r rune) bool) []byte {
- return TrimRightFunc(TrimLeftFunc(s, f), f)
-}
-
-// TrimPrefix returns s without the provided leading prefix string.
-// If s doesn't start with prefix, s is returned unchanged.
-func TrimPrefix(s, prefix []byte) []byte {
- if HasPrefix(s, prefix) {
- return s[len(prefix):]
- }
- return s
-}
-
-// TrimSuffix returns s without the provided trailing suffix string.
-// If s doesn't end with suffix, s is returned unchanged.
-func TrimSuffix(s, suffix []byte) []byte {
- if HasSuffix(s, suffix) {
- return s[:len(s)-len(suffix)]
- }
- return s
-}
-
-// IndexFunc interprets s as a sequence of UTF-8-encoded code points.
-// It returns the byte index in s of the first Unicode
-// code point satisfying f(c), or -1 if none do.
-func IndexFunc(s []byte, f func(r rune) bool) int {
- return indexFunc(s, f, true)
-}
-
-// LastIndexFunc interprets s as a sequence of UTF-8-encoded code points.
-// It returns the byte index in s of the last Unicode
-// code point satisfying f(c), or -1 if none do.
-func LastIndexFunc(s []byte, f func(r rune) bool) int {
- return lastIndexFunc(s, f, true)
-}
-
-// indexFunc is the same as IndexFunc except that if
-// truth==false, the sense of the predicate function is
-// inverted.
-func indexFunc(s []byte, f func(r rune) bool, truth bool) int {
- start := 0
- for start < len(s) {
- wid := 1
- r := rune(s[start])
- if r >= utf8.RuneSelf {
- r, wid = utf8.DecodeRune(s[start:])
- }
- if f(r) == truth {
- return start
- }
- start += wid
- }
- return -1
-}
-
-// lastIndexFunc is the same as LastIndexFunc except that if
-// truth==false, the sense of the predicate function is
-// inverted.
-func lastIndexFunc(s []byte, f func(r rune) bool, truth bool) int {
- for i := len(s); i > 0; {
- r, size := rune(s[i-1]), 1
- if r >= utf8.RuneSelf {
- r, size = utf8.DecodeLastRune(s[0:i])
- }
- i -= size
- if f(r) == truth {
- return i
- }
- }
- return -1
-}
-
-// asciiSet is a 32-byte value, where each bit represents the presence of a
-// given ASCII character in the set. The 128-bits of the lower 16 bytes,
-// starting with the least-significant bit of the lowest word to the
-// most-significant bit of the highest word, map to the full range of all
-// 128 ASCII characters. The 128-bits of the upper 16 bytes will be zeroed,
-// ensuring that any non-ASCII character will be reported as not in the set.
-// This allocates a total of 32 bytes even though the upper half
-// is unused to avoid bounds checks in asciiSet.contains.
-type asciiSet [8]uint32
-
-// makeASCIISet creates a set of ASCII characters and reports whether all
-// characters in chars are ASCII.
-func makeASCIISet(chars string) (as asciiSet, ok bool) {
- for i := 0; i < len(chars); i++ {
- c := chars[i]
- if c >= utf8.RuneSelf {
- return as, false
- }
- as[c/32] |= 1 << (c % 32)
- }
- return as, true
-}
-
-// contains reports whether c is inside the set.
-func (as *asciiSet) contains(c byte) bool {
- return (as[c/32] & (1 << (c % 32))) != 0
-}
-
-// containsRune is a simplified version of strings.ContainsRune
-// to avoid importing the strings package.
-// We avoid bytes.ContainsRune to avoid allocating a temporary copy of s.
-func containsRune(s string, r rune) bool {
- for _, c := range s {
- if c == r {
- return true
- }
- }
- return false
-}
-
-// Trim returns a subslice of s by slicing off all leading and
-// trailing UTF-8-encoded code points contained in cutset.
-func Trim(s []byte, cutset string) []byte {
- if len(s) == 0 {
- // This is what we've historically done.
- return nil
- }
- if cutset == "" {
- return s
- }
- if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
- return trimLeftByte(trimRightByte(s, cutset[0]), cutset[0])
- }
- if as, ok := makeASCIISet(cutset); ok {
- return trimLeftASCII(trimRightASCII(s, &as), &as)
- }
- return trimLeftUnicode(trimRightUnicode(s, cutset), cutset)
-}
-
-// TrimLeft returns a subslice of s by slicing off all leading
-// UTF-8-encoded code points contained in cutset.
-func TrimLeft(s []byte, cutset string) []byte {
- if len(s) == 0 {
- // This is what we've historically done.
- return nil
- }
- if cutset == "" {
- return s
- }
- if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
- return trimLeftByte(s, cutset[0])
- }
- if as, ok := makeASCIISet(cutset); ok {
- return trimLeftASCII(s, &as)
- }
- return trimLeftUnicode(s, cutset)
-}
-
-func trimLeftByte(s []byte, c byte) []byte {
- for len(s) > 0 && s[0] == c {
- s = s[1:]
- }
- if len(s) == 0 {
- // This is what we've historically done.
- return nil
- }
- return s
-}
-
-func trimLeftASCII(s []byte, as *asciiSet) []byte {
- for len(s) > 0 {
- if !as.contains(s[0]) {
- break
- }
- s = s[1:]
- }
- if len(s) == 0 {
- // This is what we've historically done.
- return nil
- }
- return s
-}
-
-func trimLeftUnicode(s []byte, cutset string) []byte {
- for len(s) > 0 {
- r, n := rune(s[0]), 1
- if r >= utf8.RuneSelf {
- r, n = utf8.DecodeRune(s)
- }
- if !containsRune(cutset, r) {
- break
- }
- s = s[n:]
- }
- if len(s) == 0 {
- // This is what we've historically done.
- return nil
- }
- return s
-}
-
-// TrimRight returns a subslice of s by slicing off all trailing
-// UTF-8-encoded code points that are contained in cutset.
-func TrimRight(s []byte, cutset string) []byte {
- if len(s) == 0 || cutset == "" {
- return s
- }
- if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
- return trimRightByte(s, cutset[0])
- }
- if as, ok := makeASCIISet(cutset); ok {
- return trimRightASCII(s, &as)
- }
- return trimRightUnicode(s, cutset)
-}
-
-func trimRightByte(s []byte, c byte) []byte {
- for len(s) > 0 && s[len(s)-1] == c {
- s = s[:len(s)-1]
- }
- return s
-}
-
-func trimRightASCII(s []byte, as *asciiSet) []byte {
- for len(s) > 0 {
- if !as.contains(s[len(s)-1]) {
- break
- }
- s = s[:len(s)-1]
- }
- return s
-}
-
-func trimRightUnicode(s []byte, cutset string) []byte {
- for len(s) > 0 {
- r, n := rune(s[len(s)-1]), 1
- if r >= utf8.RuneSelf {
- r, n = utf8.DecodeLastRune(s)
- }
- if !containsRune(cutset, r) {
- break
- }
- s = s[:len(s)-n]
- }
- return s
-}
-
-// TrimSpace returns a subslice of s by slicing off all leading and
-// trailing white space, as defined by Unicode.
-func TrimSpace(s []byte) []byte {
- // Fast path for ASCII: look for the first ASCII non-space byte
- start := 0
- for ; start < len(s); start++ {
- c := s[start]
- if c >= utf8.RuneSelf {
- // If we run into a non-ASCII byte, fall back to the
- // slower unicode-aware method on the remaining bytes
- return TrimFunc(s[start:], unicode.IsSpace)
- }
- if asciiSpace[c] == 0 {
- break
- }
- }
-
- // Now look for the first ASCII non-space byte from the end
- stop := len(s)
- for ; stop > start; stop-- {
- c := s[stop-1]
- if c >= utf8.RuneSelf {
- return TrimFunc(s[start:stop], unicode.IsSpace)
- }
- if asciiSpace[c] == 0 {
- break
- }
- }
-
- // At this point s[start:stop] starts and ends with an ASCII
- // non-space bytes, so we're done. Non-ASCII cases have already
- // been handled above.
- if start == stop {
- // Special case to preserve previous TrimLeftFunc behavior,
- // returning nil instead of empty slice if all spaces.
- return nil
- }
- return s[start:stop]
-}
-
-// Runes interprets s as a sequence of UTF-8-encoded code points.
-// It returns a slice of runes (Unicode code points) equivalent to s.
-func Runes(s []byte) []rune {
- t := make([]rune, utf8.RuneCount(s))
- i := 0
- for len(s) > 0 {
- r, l := utf8.DecodeRune(s)
- t[i] = r
- i++
- s = s[l:]
- }
- return t
-}
-
-// Replace returns a copy of the slice s with the first n
-// non-overlapping instances of old replaced by new.
-// If old is empty, it matches at the beginning of the slice
-// and after each UTF-8 sequence, yielding up to k+1 replacements
-// for a k-rune slice.
-// If n < 0, there is no limit on the number of replacements.
-func Replace(s, old, new []byte, n int) []byte {
- m := 0
- if n != 0 {
- // Compute number of replacements.
- m = Count(s, old)
- }
- if m == 0 {
- // Just return a copy.
- return append([]byte(nil), s...)
- }
- if n < 0 || m < n {
- n = m
- }
-
- // Apply replacements to buffer.
- t := make([]byte, len(s)+n*(len(new)-len(old)))
- w := 0
- start := 0
- for i := 0; i < n; i++ {
- j := start
- if len(old) == 0 {
- if i > 0 {
- _, wid := utf8.DecodeRune(s[start:])
- j += wid
- }
- } else {
- j += Index(s[start:], old)
- }
- w += copy(t[w:], s[start:j])
- w += copy(t[w:], new)
- start = j + len(old)
- }
- w += copy(t[w:], s[start:])
- return t[0:w]
-}
-
-// ReplaceAll returns a copy of the slice s with all
-// non-overlapping instances of old replaced by new.
-// If old is empty, it matches at the beginning of the slice
-// and after each UTF-8 sequence, yielding up to k+1 replacements
-// for a k-rune slice.
-func ReplaceAll(s, old, new []byte) []byte {
- return Replace(s, old, new, -1)
-}
-
-// EqualFold reports whether s and t, interpreted as UTF-8 strings,
-// are equal under simple Unicode case-folding, which is a more general
-// form of case-insensitivity.
-func EqualFold(s, t []byte) bool {
- // ASCII fast path
- i := 0
- for ; i < len(s) && i < len(t); i++ {
- sr := s[i]
- tr := t[i]
- if sr|tr >= utf8.RuneSelf {
- goto hasUnicode
- }
-
- // Easy case.
- if tr == sr {
- continue
- }
-
- // Make sr < tr to simplify what follows.
- if tr < sr {
- tr, sr = sr, tr
- }
- // ASCII only, sr/tr must be upper/lower case
- if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
- continue
- }
- return false
- }
- // Check if we've exhausted both strings.
- return len(s) == len(t)
-
-hasUnicode:
- s = s[i:]
- t = t[i:]
- for len(s) != 0 && len(t) != 0 {
- // Extract first rune from each.
- var sr, tr rune
- if s[0] < utf8.RuneSelf {
- sr, s = rune(s[0]), s[1:]
- } else {
- r, size := utf8.DecodeRune(s)
- sr, s = r, s[size:]
- }
- if t[0] < utf8.RuneSelf {
- tr, t = rune(t[0]), t[1:]
- } else {
- r, size := utf8.DecodeRune(t)
- tr, t = r, t[size:]
- }
-
- // If they match, keep going; if not, return false.
-
- // Easy case.
- if tr == sr {
- continue
- }
-
- // Make sr < tr to simplify what follows.
- if tr < sr {
- tr, sr = sr, tr
- }
- // Fast check for ASCII.
- if tr < utf8.RuneSelf {
- // ASCII only, sr/tr must be upper/lower case
- if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
- continue
- }
- return false
- }
-
- // General case. SimpleFold(x) returns the next equivalent rune > x
- // or wraps around to smaller values.
- r := unicode.SimpleFold(sr)
- for r != sr && r < tr {
- r = unicode.SimpleFold(r)
- }
- if r == tr {
- continue
- }
- return false
- }
-
- // One string is empty. Are both?
- return len(s) == len(t)
-}
-
-// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
-func Index(s, sep []byte) int {
- n := len(sep)
- switch {
- case n == 0:
- return 0
- case n == 1:
- return IndexByte(s, sep[0])
- case n == len(s):
- if Equal(sep, s) {
- return 0
- }
- return -1
- case n > len(s):
- return -1
- case n <= bytealg.MaxLen:
- // Use brute force when s and sep both are small
- if len(s) <= bytealg.MaxBruteForce {
- return bytealg.Index(s, sep)
- }
- c0 := sep[0]
- c1 := sep[1]
- i := 0
- t := len(s) - n + 1
- fails := 0
- for i < t {
- if s[i] != c0 {
- // IndexByte is faster than bytealg.Index, so use it as long as
- // we're not getting lots of false positives.
- o := IndexByte(s[i+1:t], c0)
- if o < 0 {
- return -1
- }
- i += o + 1
- }
- if s[i+1] == c1 && Equal(s[i:i+n], sep) {
- return i
- }
- fails++
- i++
- // Switch to bytealg.Index when IndexByte produces too many false positives.
- if fails > bytealg.Cutover(i) {
- r := bytealg.Index(s[i:], sep)
- if r >= 0 {
- return r + i
- }
- return -1
- }
- }
- return -1
- }
- c0 := sep[0]
- c1 := sep[1]
- i := 0
- fails := 0
- t := len(s) - n + 1
- for i < t {
- if s[i] != c0 {
- o := IndexByte(s[i+1:t], c0)
- if o < 0 {
- break
- }
- i += o + 1
- }
- if s[i+1] == c1 && Equal(s[i:i+n], sep) {
- return i
- }
- i++
- fails++
- if fails >= 4+i>>4 && i < t {
- // Give up on IndexByte, it isn't skipping ahead
- // far enough to be better than Rabin-Karp.
- // Experiments (using IndexPeriodic) suggest
- // the cutover is about 16 byte skips.
- // TODO: if large prefixes of sep are matching
- // we should cutover at even larger average skips,
- // because Equal becomes that much more expensive.
- // This code does not take that effect into account.
- j := bytealg.IndexRabinKarpBytes(s[i:], sep)
- if j < 0 {
- return -1
- }
- return i + j
- }
- }
- return -1
-}
-
-// Cut slices s around the first instance of sep,
-// returning the text before and after sep.
-// The found result reports whether sep appears in s.
-// If sep does not appear in s, cut returns s, nil, false.
-//
-// Cut returns slices of the original slice s, not copies.
-func Cut(s, sep []byte) (before, after []byte, found bool) {
- if i := Index(s, sep); i >= 0 {
- return s[:i], s[i+len(sep):], true
- }
- return s, nil, false
-}
-
-// Clone returns a copy of b[:len(b)].
-// The result may have additional unused capacity.
-// Clone(nil) returns nil.
-func Clone(b []byte) []byte {
- if b == nil {
- return nil
- }
- return append([]byte{}, b...)
-}
-
-// CutPrefix returns s without the provided leading prefix byte slice
-// and reports whether it found the prefix.
-// If s doesn't start with prefix, CutPrefix returns s, false.
-// If prefix is the empty byte slice, CutPrefix returns s, true.
-//
-// CutPrefix returns slices of the original slice s, not copies.
-func CutPrefix(s, prefix []byte) (after []byte, found bool) {
- if !HasPrefix(s, prefix) {
- return s, false
- }
- return s[len(prefix):], true
-}
-
-// CutSuffix returns s without the provided ending suffix byte slice
-// and reports whether it found the suffix.
-// If s doesn't end with suffix, CutSuffix returns s, false.
-// If suffix is the empty byte slice, CutSuffix returns s, true.
-//
-// CutSuffix returns slices of the original slice s, not copies.
-func CutSuffix(s, suffix []byte) (before []byte, found bool) {
- if !HasSuffix(s, suffix) {
- return s, false
- }
- return s[:len(s)-len(suffix)], true
-}
diff --git a/contrib/go/_std_1.20/src/bytes/ya.make b/contrib/go/_std_1.20/src/bytes/ya.make
deleted file mode 100644
index 5247d6a129..0000000000
--- a/contrib/go/_std_1.20/src/bytes/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- buffer.go
- bytes.go
- reader.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/compress/flate/inflate.go b/contrib/go/_std_1.20/src/compress/flate/inflate.go
deleted file mode 100644
index 7efd4477ed..0000000000
--- a/contrib/go/_std_1.20/src/compress/flate/inflate.go
+++ /dev/null
@@ -1,825 +0,0 @@
-// Copyright 2009 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 flate implements the DEFLATE compressed data format, described in
-// RFC 1951. The gzip and zlib packages implement access to DEFLATE-based file
-// formats.
-package flate
-
-import (
- "bufio"
- "io"
- "math/bits"
- "strconv"
- "sync"
-)
-
-const (
- maxCodeLen = 16 // max length of Huffman code
- // The next three numbers come from the RFC section 3.2.7, with the
- // additional proviso in section 3.2.5 which implies that distance codes
- // 30 and 31 should never occur in compressed data.
- maxNumLit = 286
- maxNumDist = 30
- numCodes = 19 // number of codes in Huffman meta-code
-)
-
-// Initialize the fixedHuffmanDecoder only once upon first use.
-var fixedOnce sync.Once
-var fixedHuffmanDecoder huffmanDecoder
-
-// A CorruptInputError reports the presence of corrupt input at a given offset.
-type CorruptInputError int64
-
-func (e CorruptInputError) Error() string {
- return "flate: corrupt input before offset " + strconv.FormatInt(int64(e), 10)
-}
-
-// An InternalError reports an error in the flate code itself.
-type InternalError string
-
-func (e InternalError) Error() string { return "flate: internal error: " + string(e) }
-
-// A ReadError reports an error encountered while reading input.
-//
-// Deprecated: No longer returned.
-type ReadError struct {
- Offset int64 // byte offset where error occurred
- Err error // error returned by underlying Read
-}
-
-func (e *ReadError) Error() string {
- return "flate: read error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error()
-}
-
-// A WriteError reports an error encountered while writing output.
-//
-// Deprecated: No longer returned.
-type WriteError struct {
- Offset int64 // byte offset where error occurred
- Err error // error returned by underlying Write
-}
-
-func (e *WriteError) Error() string {
- return "flate: write error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error()
-}
-
-// Resetter resets a ReadCloser returned by NewReader or NewReaderDict
-// to switch to a new underlying Reader. This permits reusing a ReadCloser
-// instead of allocating a new one.
-type Resetter interface {
- // Reset discards any buffered data and resets the Resetter as if it was
- // newly initialized with the given reader.
- Reset(r io.Reader, dict []byte) error
-}
-
-// The data structure for decoding Huffman tables is based on that of
-// zlib. There is a lookup table of a fixed bit width (huffmanChunkBits),
-// For codes smaller than the table width, there are multiple entries
-// (each combination of trailing bits has the same value). For codes
-// larger than the table width, the table contains a link to an overflow
-// table. The width of each entry in the link table is the maximum code
-// size minus the chunk width.
-//
-// Note that you can do a lookup in the table even without all bits
-// filled. Since the extra bits are zero, and the DEFLATE Huffman codes
-// have the property that shorter codes come before longer ones, the
-// bit length estimate in the result is a lower bound on the actual
-// number of bits.
-//
-// See the following:
-// https://github.com/madler/zlib/raw/master/doc/algorithm.txt
-
-// chunk & 15 is number of bits
-// chunk >> 4 is value, including table link
-
-const (
- huffmanChunkBits = 9
- huffmanNumChunks = 1 << huffmanChunkBits
- huffmanCountMask = 15
- huffmanValueShift = 4
-)
-
-type huffmanDecoder struct {
- min int // the minimum code length
- chunks [huffmanNumChunks]uint32 // chunks as described above
- links [][]uint32 // overflow links
- linkMask uint32 // mask the width of the link table
-}
-
-// Initialize Huffman decoding tables from array of code lengths.
-// Following this function, h is guaranteed to be initialized into a complete
-// tree (i.e., neither over-subscribed nor under-subscribed). The exception is a
-// degenerate case where the tree has only a single symbol with length 1. Empty
-// trees are permitted.
-func (h *huffmanDecoder) init(lengths []int) bool {
- // Sanity enables additional runtime tests during Huffman
- // table construction. It's intended to be used during
- // development to supplement the currently ad-hoc unit tests.
- const sanity = false
-
- if h.min != 0 {
- *h = huffmanDecoder{}
- }
-
- // Count number of codes of each length,
- // compute min and max length.
- var count [maxCodeLen]int
- var min, max int
- for _, n := range lengths {
- if n == 0 {
- continue
- }
- if min == 0 || n < min {
- min = n
- }
- if n > max {
- max = n
- }
- count[n]++
- }
-
- // Empty tree. The decompressor.huffSym function will fail later if the tree
- // is used. Technically, an empty tree is only valid for the HDIST tree and
- // not the HCLEN and HLIT tree. However, a stream with an empty HCLEN tree
- // is guaranteed to fail since it will attempt to use the tree to decode the
- // codes for the HLIT and HDIST trees. Similarly, an empty HLIT tree is
- // guaranteed to fail later since the compressed data section must be
- // composed of at least one symbol (the end-of-block marker).
- if max == 0 {
- return true
- }
-
- code := 0
- var nextcode [maxCodeLen]int
- for i := min; i <= max; i++ {
- code <<= 1
- nextcode[i] = code
- code += count[i]
- }
-
- // Check that the coding is complete (i.e., that we've
- // assigned all 2-to-the-max possible bit sequences).
- // Exception: To be compatible with zlib, we also need to
- // accept degenerate single-code codings. See also
- // TestDegenerateHuffmanCoding.
- if code != 1<<uint(max) && !(code == 1 && max == 1) {
- return false
- }
-
- h.min = min
- if max > huffmanChunkBits {
- numLinks := 1 << (uint(max) - huffmanChunkBits)
- h.linkMask = uint32(numLinks - 1)
-
- // create link tables
- link := nextcode[huffmanChunkBits+1] >> 1
- h.links = make([][]uint32, huffmanNumChunks-link)
- for j := uint(link); j < huffmanNumChunks; j++ {
- reverse := int(bits.Reverse16(uint16(j)))
- reverse >>= uint(16 - huffmanChunkBits)
- off := j - uint(link)
- if sanity && h.chunks[reverse] != 0 {
- panic("impossible: overwriting existing chunk")
- }
- h.chunks[reverse] = uint32(off<<huffmanValueShift | (huffmanChunkBits + 1))
- h.links[off] = make([]uint32, numLinks)
- }
- }
-
- for i, n := range lengths {
- if n == 0 {
- continue
- }
- code := nextcode[n]
- nextcode[n]++
- chunk := uint32(i<<huffmanValueShift | n)
- reverse := int(bits.Reverse16(uint16(code)))
- reverse >>= uint(16 - n)
- if n <= huffmanChunkBits {
- for off := reverse; off < len(h.chunks); off += 1 << uint(n) {
- // We should never need to overwrite
- // an existing chunk. Also, 0 is
- // never a valid chunk, because the
- // lower 4 "count" bits should be
- // between 1 and 15.
- if sanity && h.chunks[off] != 0 {
- panic("impossible: overwriting existing chunk")
- }
- h.chunks[off] = chunk
- }
- } else {
- j := reverse & (huffmanNumChunks - 1)
- if sanity && h.chunks[j]&huffmanCountMask != huffmanChunkBits+1 {
- // Longer codes should have been
- // associated with a link table above.
- panic("impossible: not an indirect chunk")
- }
- value := h.chunks[j] >> huffmanValueShift
- linktab := h.links[value]
- reverse >>= huffmanChunkBits
- for off := reverse; off < len(linktab); off += 1 << uint(n-huffmanChunkBits) {
- if sanity && linktab[off] != 0 {
- panic("impossible: overwriting existing chunk")
- }
- linktab[off] = chunk
- }
- }
- }
-
- if sanity {
- // Above we've sanity checked that we never overwrote
- // an existing entry. Here we additionally check that
- // we filled the tables completely.
- for i, chunk := range h.chunks {
- if chunk == 0 {
- // As an exception, in the degenerate
- // single-code case, we allow odd
- // chunks to be missing.
- if code == 1 && i%2 == 1 {
- continue
- }
- panic("impossible: missing chunk")
- }
- }
- for _, linktab := range h.links {
- for _, chunk := range linktab {
- if chunk == 0 {
- panic("impossible: missing chunk")
- }
- }
- }
- }
-
- return true
-}
-
-// The actual read interface needed by NewReader.
-// If the passed in io.Reader does not also have ReadByte,
-// the NewReader will introduce its own buffering.
-type Reader interface {
- io.Reader
- io.ByteReader
-}
-
-// Decompress state.
-type decompressor struct {
- // Input source.
- r Reader
- roffset int64
-
- // Input bits, in top of b.
- b uint32
- nb uint
-
- // Huffman decoders for literal/length, distance.
- h1, h2 huffmanDecoder
-
- // Length arrays used to define Huffman codes.
- bits *[maxNumLit + maxNumDist]int
- codebits *[numCodes]int
-
- // Output history, buffer.
- dict dictDecoder
-
- // Temporary buffer (avoids repeated allocation).
- buf [4]byte
-
- // Next step in the decompression,
- // and decompression state.
- step func(*decompressor)
- stepState int
- final bool
- err error
- toRead []byte
- hl, hd *huffmanDecoder
- copyLen int
- copyDist int
-}
-
-func (f *decompressor) nextBlock() {
- for f.nb < 1+2 {
- if f.err = f.moreBits(); f.err != nil {
- return
- }
- }
- f.final = f.b&1 == 1
- f.b >>= 1
- typ := f.b & 3
- f.b >>= 2
- f.nb -= 1 + 2
- switch typ {
- case 0:
- f.dataBlock()
- case 1:
- // compressed, fixed Huffman tables
- f.hl = &fixedHuffmanDecoder
- f.hd = nil
- f.huffmanBlock()
- case 2:
- // compressed, dynamic Huffman tables
- if f.err = f.readHuffman(); f.err != nil {
- break
- }
- f.hl = &f.h1
- f.hd = &f.h2
- f.huffmanBlock()
- default:
- // 3 is reserved.
- f.err = CorruptInputError(f.roffset)
- }
-}
-
-func (f *decompressor) Read(b []byte) (int, error) {
- for {
- if len(f.toRead) > 0 {
- n := copy(b, f.toRead)
- f.toRead = f.toRead[n:]
- if len(f.toRead) == 0 {
- return n, f.err
- }
- return n, nil
- }
- if f.err != nil {
- return 0, f.err
- }
- f.step(f)
- if f.err != nil && len(f.toRead) == 0 {
- f.toRead = f.dict.readFlush() // Flush what's left in case of error
- }
- }
-}
-
-func (f *decompressor) Close() error {
- if f.err == io.EOF {
- return nil
- }
- return f.err
-}
-
-// RFC 1951 section 3.2.7.
-// Compression with dynamic Huffman codes
-
-var codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
-
-func (f *decompressor) readHuffman() error {
- // HLIT[5], HDIST[5], HCLEN[4].
- for f.nb < 5+5+4 {
- if err := f.moreBits(); err != nil {
- return err
- }
- }
- nlit := int(f.b&0x1F) + 257
- if nlit > maxNumLit {
- return CorruptInputError(f.roffset)
- }
- f.b >>= 5
- ndist := int(f.b&0x1F) + 1
- if ndist > maxNumDist {
- return CorruptInputError(f.roffset)
- }
- f.b >>= 5
- nclen := int(f.b&0xF) + 4
- // numCodes is 19, so nclen is always valid.
- f.b >>= 4
- f.nb -= 5 + 5 + 4
-
- // (HCLEN+4)*3 bits: code lengths in the magic codeOrder order.
- for i := 0; i < nclen; i++ {
- for f.nb < 3 {
- if err := f.moreBits(); err != nil {
- return err
- }
- }
- f.codebits[codeOrder[i]] = int(f.b & 0x7)
- f.b >>= 3
- f.nb -= 3
- }
- for i := nclen; i < len(codeOrder); i++ {
- f.codebits[codeOrder[i]] = 0
- }
- if !f.h1.init(f.codebits[0:]) {
- return CorruptInputError(f.roffset)
- }
-
- // HLIT + 257 code lengths, HDIST + 1 code lengths,
- // using the code length Huffman code.
- for i, n := 0, nlit+ndist; i < n; {
- x, err := f.huffSym(&f.h1)
- if err != nil {
- return err
- }
- if x < 16 {
- // Actual length.
- f.bits[i] = x
- i++
- continue
- }
- // Repeat previous length or zero.
- var rep int
- var nb uint
- var b int
- switch x {
- default:
- return InternalError("unexpected length code")
- case 16:
- rep = 3
- nb = 2
- if i == 0 {
- return CorruptInputError(f.roffset)
- }
- b = f.bits[i-1]
- case 17:
- rep = 3
- nb = 3
- b = 0
- case 18:
- rep = 11
- nb = 7
- b = 0
- }
- for f.nb < nb {
- if err := f.moreBits(); err != nil {
- return err
- }
- }
- rep += int(f.b & uint32(1<<nb-1))
- f.b >>= nb
- f.nb -= nb
- if i+rep > n {
- return CorruptInputError(f.roffset)
- }
- for j := 0; j < rep; j++ {
- f.bits[i] = b
- i++
- }
- }
-
- if !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) {
- return CorruptInputError(f.roffset)
- }
-
- // As an optimization, we can initialize the min bits to read at a time
- // for the HLIT tree to the length of the EOB marker since we know that
- // every block must terminate with one. This preserves the property that
- // we never read any extra bytes after the end of the DEFLATE stream.
- if f.h1.min < f.bits[endBlockMarker] {
- f.h1.min = f.bits[endBlockMarker]
- }
-
- return nil
-}
-
-// Decode a single Huffman block from f.
-// hl and hd are the Huffman states for the lit/length values
-// and the distance values, respectively. If hd == nil, using the
-// fixed distance encoding associated with fixed Huffman blocks.
-func (f *decompressor) huffmanBlock() {
- const (
- stateInit = iota // Zero value must be stateInit
- stateDict
- )
-
- switch f.stepState {
- case stateInit:
- goto readLiteral
- case stateDict:
- goto copyHistory
- }
-
-readLiteral:
- // Read literal and/or (length, distance) according to RFC section 3.2.3.
- {
- v, err := f.huffSym(f.hl)
- if err != nil {
- f.err = err
- return
- }
- var n uint // number of bits extra
- var length int
- switch {
- case v < 256:
- f.dict.writeByte(byte(v))
- if f.dict.availWrite() == 0 {
- f.toRead = f.dict.readFlush()
- f.step = (*decompressor).huffmanBlock
- f.stepState = stateInit
- return
- }
- goto readLiteral
- case v == 256:
- f.finishBlock()
- return
- // otherwise, reference to older data
- case v < 265:
- length = v - (257 - 3)
- n = 0
- case v < 269:
- length = v*2 - (265*2 - 11)
- n = 1
- case v < 273:
- length = v*4 - (269*4 - 19)
- n = 2
- case v < 277:
- length = v*8 - (273*8 - 35)
- n = 3
- case v < 281:
- length = v*16 - (277*16 - 67)
- n = 4
- case v < 285:
- length = v*32 - (281*32 - 131)
- n = 5
- case v < maxNumLit:
- length = 258
- n = 0
- default:
- f.err = CorruptInputError(f.roffset)
- return
- }
- if n > 0 {
- for f.nb < n {
- if err = f.moreBits(); err != nil {
- f.err = err
- return
- }
- }
- length += int(f.b & uint32(1<<n-1))
- f.b >>= n
- f.nb -= n
- }
-
- var dist int
- if f.hd == nil {
- for f.nb < 5 {
- if err = f.moreBits(); err != nil {
- f.err = err
- return
- }
- }
- dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3)))
- f.b >>= 5
- f.nb -= 5
- } else {
- if dist, err = f.huffSym(f.hd); err != nil {
- f.err = err
- return
- }
- }
-
- switch {
- case dist < 4:
- dist++
- case dist < maxNumDist:
- nb := uint(dist-2) >> 1
- // have 1 bit in bottom of dist, need nb more.
- extra := (dist & 1) << nb
- for f.nb < nb {
- if err = f.moreBits(); err != nil {
- f.err = err
- return
- }
- }
- extra |= int(f.b & uint32(1<<nb-1))
- f.b >>= nb
- f.nb -= nb
- dist = 1<<(nb+1) + 1 + extra
- default:
- f.err = CorruptInputError(f.roffset)
- return
- }
-
- // No check on length; encoding can be prescient.
- if dist > f.dict.histSize() {
- f.err = CorruptInputError(f.roffset)
- return
- }
-
- f.copyLen, f.copyDist = length, dist
- goto copyHistory
- }
-
-copyHistory:
- // Perform a backwards copy according to RFC section 3.2.3.
- {
- cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen)
- if cnt == 0 {
- cnt = f.dict.writeCopy(f.copyDist, f.copyLen)
- }
- f.copyLen -= cnt
-
- if f.dict.availWrite() == 0 || f.copyLen > 0 {
- f.toRead = f.dict.readFlush()
- f.step = (*decompressor).huffmanBlock // We need to continue this work
- f.stepState = stateDict
- return
- }
- goto readLiteral
- }
-}
-
-// Copy a single uncompressed data block from input to output.
-func (f *decompressor) dataBlock() {
- // Uncompressed.
- // Discard current half-byte.
- f.nb = 0
- f.b = 0
-
- // Length then ones-complement of length.
- nr, err := io.ReadFull(f.r, f.buf[0:4])
- f.roffset += int64(nr)
- if err != nil {
- f.err = noEOF(err)
- return
- }
- n := int(f.buf[0]) | int(f.buf[1])<<8
- nn := int(f.buf[2]) | int(f.buf[3])<<8
- if uint16(nn) != uint16(^n) {
- f.err = CorruptInputError(f.roffset)
- return
- }
-
- if n == 0 {
- f.toRead = f.dict.readFlush()
- f.finishBlock()
- return
- }
-
- f.copyLen = n
- f.copyData()
-}
-
-// copyData copies f.copyLen bytes from the underlying reader into f.hist.
-// It pauses for reads when f.hist is full.
-func (f *decompressor) copyData() {
- buf := f.dict.writeSlice()
- if len(buf) > f.copyLen {
- buf = buf[:f.copyLen]
- }
-
- cnt, err := io.ReadFull(f.r, buf)
- f.roffset += int64(cnt)
- f.copyLen -= cnt
- f.dict.writeMark(cnt)
- if err != nil {
- f.err = noEOF(err)
- return
- }
-
- if f.dict.availWrite() == 0 || f.copyLen > 0 {
- f.toRead = f.dict.readFlush()
- f.step = (*decompressor).copyData
- return
- }
- f.finishBlock()
-}
-
-func (f *decompressor) finishBlock() {
- if f.final {
- if f.dict.availRead() > 0 {
- f.toRead = f.dict.readFlush()
- }
- f.err = io.EOF
- }
- f.step = (*decompressor).nextBlock
-}
-
-// noEOF returns err, unless err == io.EOF, in which case it returns io.ErrUnexpectedEOF.
-func noEOF(e error) error {
- if e == io.EOF {
- return io.ErrUnexpectedEOF
- }
- return e
-}
-
-func (f *decompressor) moreBits() error {
- c, err := f.r.ReadByte()
- if err != nil {
- return noEOF(err)
- }
- f.roffset++
- f.b |= uint32(c) << f.nb
- f.nb += 8
- return nil
-}
-
-// Read the next Huffman-encoded symbol from f according to h.
-func (f *decompressor) huffSym(h *huffmanDecoder) (int, error) {
- // Since a huffmanDecoder can be empty or be composed of a degenerate tree
- // with single element, huffSym must error on these two edge cases. In both
- // cases, the chunks slice will be 0 for the invalid sequence, leading it
- // satisfy the n == 0 check below.
- n := uint(h.min)
- // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
- // but is smart enough to keep local variables in registers, so use nb and b,
- // inline call to moreBits and reassign b,nb back to f on return.
- nb, b := f.nb, f.b
- for {
- for nb < n {
- c, err := f.r.ReadByte()
- if err != nil {
- f.b = b
- f.nb = nb
- return 0, noEOF(err)
- }
- f.roffset++
- b |= uint32(c) << (nb & 31)
- nb += 8
- }
- chunk := h.chunks[b&(huffmanNumChunks-1)]
- n = uint(chunk & huffmanCountMask)
- if n > huffmanChunkBits {
- chunk = h.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&h.linkMask]
- n = uint(chunk & huffmanCountMask)
- }
- if n <= nb {
- if n == 0 {
- f.b = b
- f.nb = nb
- f.err = CorruptInputError(f.roffset)
- return 0, f.err
- }
- f.b = b >> (n & 31)
- f.nb = nb - n
- return int(chunk >> huffmanValueShift), nil
- }
- }
-}
-
-func makeReader(r io.Reader) Reader {
- if rr, ok := r.(Reader); ok {
- return rr
- }
- return bufio.NewReader(r)
-}
-
-func fixedHuffmanDecoderInit() {
- fixedOnce.Do(func() {
- // These come from the RFC section 3.2.6.
- var bits [288]int
- for i := 0; i < 144; i++ {
- bits[i] = 8
- }
- for i := 144; i < 256; i++ {
- bits[i] = 9
- }
- for i := 256; i < 280; i++ {
- bits[i] = 7
- }
- for i := 280; i < 288; i++ {
- bits[i] = 8
- }
- fixedHuffmanDecoder.init(bits[:])
- })
-}
-
-func (f *decompressor) Reset(r io.Reader, dict []byte) error {
- *f = decompressor{
- r: makeReader(r),
- bits: f.bits,
- codebits: f.codebits,
- dict: f.dict,
- step: (*decompressor).nextBlock,
- }
- f.dict.init(maxMatchOffset, dict)
- return nil
-}
-
-// NewReader returns a new ReadCloser that can be used
-// to read the uncompressed version of r.
-// If r does not also implement io.ByteReader,
-// the decompressor may read more data than necessary from r.
-// The reader returns io.EOF after the final block in the DEFLATE stream has
-// been encountered. Any trailing data after the final block is ignored.
-//
-// The ReadCloser returned by NewReader also implements Resetter.
-func NewReader(r io.Reader) io.ReadCloser {
- fixedHuffmanDecoderInit()
-
- var f decompressor
- f.r = makeReader(r)
- f.bits = new([maxNumLit + maxNumDist]int)
- f.codebits = new([numCodes]int)
- f.step = (*decompressor).nextBlock
- f.dict.init(maxMatchOffset, nil)
- return &f
-}
-
-// NewReaderDict is like NewReader but initializes the reader
-// with a preset dictionary. The returned Reader behaves as if
-// the uncompressed data stream started with the given dictionary,
-// which has already been read. NewReaderDict is typically used
-// to read data compressed by NewWriterDict.
-//
-// The ReadCloser returned by NewReader also implements Resetter.
-func NewReaderDict(r io.Reader, dict []byte) io.ReadCloser {
- fixedHuffmanDecoderInit()
-
- var f decompressor
- f.r = makeReader(r)
- f.bits = new([maxNumLit + maxNumDist]int)
- f.codebits = new([numCodes]int)
- f.step = (*decompressor).nextBlock
- f.dict.init(maxMatchOffset, dict)
- return &f
-}
diff --git a/contrib/go/_std_1.20/src/compress/flate/ya.make b/contrib/go/_std_1.20/src/compress/flate/ya.make
deleted file mode 100644
index 5d3ce7b15d..0000000000
--- a/contrib/go/_std_1.20/src/compress/flate/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- deflate.go
- deflatefast.go
- dict_decoder.go
- huffman_bit_writer.go
- huffman_code.go
- inflate.go
- token.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/compress/gzip/ya.make b/contrib/go/_std_1.20/src/compress/gzip/ya.make
deleted file mode 100644
index 255ce9bd9c..0000000000
--- a/contrib/go/_std_1.20/src/compress/gzip/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- gunzip.go
- gzip.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/compress/zlib/reader.go b/contrib/go/_std_1.20/src/compress/zlib/reader.go
deleted file mode 100644
index 343a18bf68..0000000000
--- a/contrib/go/_std_1.20/src/compress/zlib/reader.go
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright 2009 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 zlib implements reading and writing of zlib format compressed data,
-as specified in RFC 1950.
-
-The implementation provides filters that uncompress during reading
-and compress during writing. For example, to write compressed data
-to a buffer:
-
- var b bytes.Buffer
- w := zlib.NewWriter(&b)
- w.Write([]byte("hello, world\n"))
- w.Close()
-
-and to read that data back:
-
- r, err := zlib.NewReader(&b)
- io.Copy(os.Stdout, r)
- r.Close()
-*/
-package zlib
-
-import (
- "bufio"
- "compress/flate"
- "errors"
- "hash"
- "hash/adler32"
- "io"
-)
-
-const (
- zlibDeflate = 8
- zlibMaxWindow = 7
-)
-
-var (
- // ErrChecksum is returned when reading ZLIB data that has an invalid checksum.
- ErrChecksum = errors.New("zlib: invalid checksum")
- // ErrDictionary is returned when reading ZLIB data that has an invalid dictionary.
- ErrDictionary = errors.New("zlib: invalid dictionary")
- // ErrHeader is returned when reading ZLIB data that has an invalid header.
- ErrHeader = errors.New("zlib: invalid header")
-)
-
-type reader struct {
- r flate.Reader
- decompressor io.ReadCloser
- digest hash.Hash32
- err error
- scratch [4]byte
-}
-
-// Resetter resets a ReadCloser returned by NewReader or NewReaderDict
-// to switch to a new underlying Reader. This permits reusing a ReadCloser
-// instead of allocating a new one.
-type Resetter interface {
- // Reset discards any buffered data and resets the Resetter as if it was
- // newly initialized with the given reader.
- Reset(r io.Reader, dict []byte) error
-}
-
-// NewReader creates a new ReadCloser.
-// Reads from the returned ReadCloser read and decompress data from r.
-// If r does not implement io.ByteReader, the decompressor may read more
-// data than necessary from r.
-// It is the caller's responsibility to call Close on the ReadCloser when done.
-//
-// The ReadCloser returned by NewReader also implements Resetter.
-func NewReader(r io.Reader) (io.ReadCloser, error) {
- return NewReaderDict(r, nil)
-}
-
-// NewReaderDict is like NewReader but uses a preset dictionary.
-// NewReaderDict ignores the dictionary if the compressed data does not refer to it.
-// If the compressed data refers to a different dictionary, NewReaderDict returns ErrDictionary.
-//
-// The ReadCloser returned by NewReaderDict also implements Resetter.
-func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error) {
- z := new(reader)
- err := z.Reset(r, dict)
- if err != nil {
- return nil, err
- }
- return z, nil
-}
-
-func (z *reader) Read(p []byte) (int, error) {
- if z.err != nil {
- return 0, z.err
- }
-
- var n int
- n, z.err = z.decompressor.Read(p)
- z.digest.Write(p[0:n])
- if z.err != io.EOF {
- // In the normal case we return here.
- return n, z.err
- }
-
- // Finished file; check checksum.
- if _, err := io.ReadFull(z.r, z.scratch[0:4]); err != nil {
- if err == io.EOF {
- err = io.ErrUnexpectedEOF
- }
- z.err = err
- return n, z.err
- }
- // ZLIB (RFC 1950) is big-endian, unlike GZIP (RFC 1952).
- checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3])
- if checksum != z.digest.Sum32() {
- z.err = ErrChecksum
- return n, z.err
- }
- return n, io.EOF
-}
-
-// Calling Close does not close the wrapped io.Reader originally passed to NewReader.
-// In order for the ZLIB checksum to be verified, the reader must be
-// fully consumed until the io.EOF.
-func (z *reader) Close() error {
- if z.err != nil && z.err != io.EOF {
- return z.err
- }
- z.err = z.decompressor.Close()
- return z.err
-}
-
-func (z *reader) Reset(r io.Reader, dict []byte) error {
- *z = reader{decompressor: z.decompressor}
- if fr, ok := r.(flate.Reader); ok {
- z.r = fr
- } else {
- z.r = bufio.NewReader(r)
- }
-
- // Read the header (RFC 1950 section 2.2.).
- _, z.err = io.ReadFull(z.r, z.scratch[0:2])
- if z.err != nil {
- if z.err == io.EOF {
- z.err = io.ErrUnexpectedEOF
- }
- return z.err
- }
- h := uint(z.scratch[0])<<8 | uint(z.scratch[1])
- if (z.scratch[0]&0x0f != zlibDeflate) || (z.scratch[0]>>4 > zlibMaxWindow) || (h%31 != 0) {
- z.err = ErrHeader
- return z.err
- }
- haveDict := z.scratch[1]&0x20 != 0
- if haveDict {
- _, z.err = io.ReadFull(z.r, z.scratch[0:4])
- if z.err != nil {
- if z.err == io.EOF {
- z.err = io.ErrUnexpectedEOF
- }
- return z.err
- }
- checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3])
- if checksum != adler32.Checksum(dict) {
- z.err = ErrDictionary
- return z.err
- }
- }
-
- if z.decompressor == nil {
- if haveDict {
- z.decompressor = flate.NewReaderDict(z.r, dict)
- } else {
- z.decompressor = flate.NewReader(z.r)
- }
- } else {
- z.decompressor.(flate.Resetter).Reset(z.r, dict)
- }
- z.digest = adler32.New()
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/compress/zlib/writer.go b/contrib/go/_std_1.20/src/compress/zlib/writer.go
deleted file mode 100644
index 9986e3834d..0000000000
--- a/contrib/go/_std_1.20/src/compress/zlib/writer.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2009 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 zlib
-
-import (
- "compress/flate"
- "encoding/binary"
- "fmt"
- "hash"
- "hash/adler32"
- "io"
-)
-
-// These constants are copied from the flate package, so that code that imports
-// "compress/zlib" does not also have to import "compress/flate".
-const (
- NoCompression = flate.NoCompression
- BestSpeed = flate.BestSpeed
- BestCompression = flate.BestCompression
- DefaultCompression = flate.DefaultCompression
- HuffmanOnly = flate.HuffmanOnly
-)
-
-// A Writer takes data written to it and writes the compressed
-// form of that data to an underlying writer (see NewWriter).
-type Writer struct {
- w io.Writer
- level int
- dict []byte
- compressor *flate.Writer
- digest hash.Hash32
- err error
- scratch [4]byte
- wroteHeader bool
-}
-
-// NewWriter creates a new Writer.
-// Writes to the returned Writer are compressed and written to w.
-//
-// It is the caller's responsibility to call Close on the Writer when done.
-// Writes may be buffered and not flushed until Close.
-func NewWriter(w io.Writer) *Writer {
- z, _ := NewWriterLevelDict(w, DefaultCompression, nil)
- return z
-}
-
-// NewWriterLevel is like NewWriter but specifies the compression level instead
-// of assuming DefaultCompression.
-//
-// The compression level can be DefaultCompression, NoCompression, HuffmanOnly
-// or any integer value between BestSpeed and BestCompression inclusive.
-// The error returned will be nil if the level is valid.
-func NewWriterLevel(w io.Writer, level int) (*Writer, error) {
- return NewWriterLevelDict(w, level, nil)
-}
-
-// NewWriterLevelDict is like NewWriterLevel but specifies a dictionary to
-// compress with.
-//
-// The dictionary may be nil. If not, its contents should not be modified until
-// the Writer is closed.
-func NewWriterLevelDict(w io.Writer, level int, dict []byte) (*Writer, error) {
- if level < HuffmanOnly || level > BestCompression {
- return nil, fmt.Errorf("zlib: invalid compression level: %d", level)
- }
- return &Writer{
- w: w,
- level: level,
- dict: dict,
- }, nil
-}
-
-// Reset clears the state of the Writer z such that it is equivalent to its
-// initial state from NewWriterLevel or NewWriterLevelDict, but instead writing
-// to w.
-func (z *Writer) Reset(w io.Writer) {
- z.w = w
- // z.level and z.dict left unchanged.
- if z.compressor != nil {
- z.compressor.Reset(w)
- }
- if z.digest != nil {
- z.digest.Reset()
- }
- z.err = nil
- z.scratch = [4]byte{}
- z.wroteHeader = false
-}
-
-// writeHeader writes the ZLIB header.
-func (z *Writer) writeHeader() (err error) {
- z.wroteHeader = true
- // ZLIB has a two-byte header (as documented in RFC 1950).
- // The first four bits is the CINFO (compression info), which is 7 for the default deflate window size.
- // The next four bits is the CM (compression method), which is 8 for deflate.
- z.scratch[0] = 0x78
- // The next two bits is the FLEVEL (compression level). The four values are:
- // 0=fastest, 1=fast, 2=default, 3=best.
- // The next bit, FDICT, is set if a dictionary is given.
- // The final five FCHECK bits form a mod-31 checksum.
- switch z.level {
- case -2, 0, 1:
- z.scratch[1] = 0 << 6
- case 2, 3, 4, 5:
- z.scratch[1] = 1 << 6
- case 6, -1:
- z.scratch[1] = 2 << 6
- case 7, 8, 9:
- z.scratch[1] = 3 << 6
- default:
- panic("unreachable")
- }
- if z.dict != nil {
- z.scratch[1] |= 1 << 5
- }
- z.scratch[1] += uint8(31 - (uint16(z.scratch[0])<<8+uint16(z.scratch[1]))%31)
- if _, err = z.w.Write(z.scratch[0:2]); err != nil {
- return err
- }
- if z.dict != nil {
- // The next four bytes are the Adler-32 checksum of the dictionary.
- binary.BigEndian.PutUint32(z.scratch[:], adler32.Checksum(z.dict))
- if _, err = z.w.Write(z.scratch[0:4]); err != nil {
- return err
- }
- }
- if z.compressor == nil {
- // Initialize deflater unless the Writer is being reused
- // after a Reset call.
- z.compressor, err = flate.NewWriterDict(z.w, z.level, z.dict)
- if err != nil {
- return err
- }
- z.digest = adler32.New()
- }
- return nil
-}
-
-// Write writes a compressed form of p to the underlying io.Writer. The
-// compressed bytes are not necessarily flushed until the Writer is closed or
-// explicitly flushed.
-func (z *Writer) Write(p []byte) (n int, err error) {
- if !z.wroteHeader {
- z.err = z.writeHeader()
- }
- if z.err != nil {
- return 0, z.err
- }
- if len(p) == 0 {
- return 0, nil
- }
- n, err = z.compressor.Write(p)
- if err != nil {
- z.err = err
- return
- }
- z.digest.Write(p)
- return
-}
-
-// Flush flushes the Writer to its underlying io.Writer.
-func (z *Writer) Flush() error {
- if !z.wroteHeader {
- z.err = z.writeHeader()
- }
- if z.err != nil {
- return z.err
- }
- z.err = z.compressor.Flush()
- return z.err
-}
-
-// Close closes the Writer, flushing any unwritten data to the underlying
-// io.Writer, but does not close the underlying io.Writer.
-func (z *Writer) Close() error {
- if !z.wroteHeader {
- z.err = z.writeHeader()
- }
- if z.err != nil {
- return z.err
- }
- z.err = z.compressor.Close()
- if z.err != nil {
- return z.err
- }
- checksum := z.digest.Sum32()
- // ZLIB (RFC 1950) is big-endian, unlike GZIP (RFC 1952).
- binary.BigEndian.PutUint32(z.scratch[:], checksum)
- _, z.err = z.w.Write(z.scratch[0:4])
- return z.err
-}
diff --git a/contrib/go/_std_1.20/src/compress/zlib/ya.make b/contrib/go/_std_1.20/src/compress/zlib/ya.make
deleted file mode 100644
index 262cbbb45f..0000000000
--- a/contrib/go/_std_1.20/src/compress/zlib/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- reader.go
- writer.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/container/heap/ya.make b/contrib/go/_std_1.20/src/container/heap/ya.make
deleted file mode 100644
index f9996996e3..0000000000
--- a/contrib/go/_std_1.20/src/container/heap/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- heap.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/container/list/ya.make b/contrib/go/_std_1.20/src/container/list/ya.make
deleted file mode 100644
index 9c6d4d7612..0000000000
--- a/contrib/go/_std_1.20/src/container/list/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- list.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/context/context.go b/contrib/go/_std_1.20/src/context/context.go
deleted file mode 100644
index f3fe1a474e..0000000000
--- a/contrib/go/_std_1.20/src/context/context.go
+++ /dev/null
@@ -1,653 +0,0 @@
-// Copyright 2014 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 context defines the Context type, which carries deadlines,
-// cancellation signals, and other request-scoped values across API boundaries
-// and between processes.
-//
-// Incoming requests to a server should create a Context, and outgoing
-// calls to servers should accept a Context. The chain of function
-// calls between them must propagate the Context, optionally replacing
-// it with a derived Context created using WithCancel, WithDeadline,
-// WithTimeout, or WithValue. When a Context is canceled, all
-// Contexts derived from it are also canceled.
-//
-// The WithCancel, WithDeadline, and WithTimeout functions take a
-// Context (the parent) and return a derived Context (the child) and a
-// CancelFunc. Calling the CancelFunc cancels the child and its
-// children, removes the parent's reference to the child, and stops
-// any associated timers. Failing to call the CancelFunc leaks the
-// child and its children until the parent is canceled or the timer
-// fires. The go vet tool checks that CancelFuncs are used on all
-// control-flow paths.
-//
-// The WithCancelCause function returns a CancelCauseFunc, which
-// takes an error and records it as the cancellation cause. Calling
-// Cause on the canceled context or any of its children retrieves
-// the cause. If no cause is specified, Cause(ctx) returns the same
-// value as ctx.Err().
-//
-// Programs that use Contexts should follow these rules to keep interfaces
-// consistent across packages and enable static analysis tools to check context
-// propagation:
-//
-// Do not store Contexts inside a struct type; instead, pass a Context
-// explicitly to each function that needs it. The Context should be the first
-// parameter, typically named ctx:
-//
-// func DoSomething(ctx context.Context, arg Arg) error {
-// // ... use ctx ...
-// }
-//
-// Do not pass a nil Context, even if a function permits it. Pass context.TODO
-// if you are unsure about which Context to use.
-//
-// Use context Values only for request-scoped data that transits processes and
-// APIs, not for passing optional parameters to functions.
-//
-// The same Context may be passed to functions running in different goroutines;
-// Contexts are safe for simultaneous use by multiple goroutines.
-//
-// See https://blog.golang.org/context for example code for a server that uses
-// Contexts.
-package context
-
-import (
- "errors"
- "internal/reflectlite"
- "sync"
- "sync/atomic"
- "time"
-)
-
-// A Context carries a deadline, a cancellation signal, and other values across
-// API boundaries.
-//
-// Context's methods may be called by multiple goroutines simultaneously.
-type Context interface {
- // Deadline returns the time when work done on behalf of this context
- // should be canceled. Deadline returns ok==false when no deadline is
- // set. Successive calls to Deadline return the same results.
- Deadline() (deadline time.Time, ok bool)
-
- // Done returns a channel that's closed when work done on behalf of this
- // context should be canceled. Done may return nil if this context can
- // never be canceled. Successive calls to Done return the same value.
- // The close of the Done channel may happen asynchronously,
- // after the cancel function returns.
- //
- // WithCancel arranges for Done to be closed when cancel is called;
- // WithDeadline arranges for Done to be closed when the deadline
- // expires; WithTimeout arranges for Done to be closed when the timeout
- // elapses.
- //
- // Done is provided for use in select statements:
- //
- // // Stream generates values with DoSomething and sends them to out
- // // until DoSomething returns an error or ctx.Done is closed.
- // func Stream(ctx context.Context, out chan<- Value) error {
- // for {
- // v, err := DoSomething(ctx)
- // if err != nil {
- // return err
- // }
- // select {
- // case <-ctx.Done():
- // return ctx.Err()
- // case out <- v:
- // }
- // }
- // }
- //
- // See https://blog.golang.org/pipelines for more examples of how to use
- // a Done channel for cancellation.
- Done() <-chan struct{}
-
- // If Done is not yet closed, Err returns nil.
- // If Done is closed, Err returns a non-nil error explaining why:
- // Canceled if the context was canceled
- // or DeadlineExceeded if the context's deadline passed.
- // After Err returns a non-nil error, successive calls to Err return the same error.
- Err() error
-
- // Value returns the value associated with this context for key, or nil
- // if no value is associated with key. Successive calls to Value with
- // the same key returns the same result.
- //
- // Use context values only for request-scoped data that transits
- // processes and API boundaries, not for passing optional parameters to
- // functions.
- //
- // A key identifies a specific value in a Context. Functions that wish
- // to store values in Context typically allocate a key in a global
- // variable then use that key as the argument to context.WithValue and
- // Context.Value. A key can be any type that supports equality;
- // packages should define keys as an unexported type to avoid
- // collisions.
- //
- // Packages that define a Context key should provide type-safe accessors
- // for the values stored using that key:
- //
- // // Package user defines a User type that's stored in Contexts.
- // package user
- //
- // import "context"
- //
- // // User is the type of value stored in the Contexts.
- // type User struct {...}
- //
- // // key is an unexported type for keys defined in this package.
- // // This prevents collisions with keys defined in other packages.
- // type key int
- //
- // // userKey is the key for user.User values in Contexts. It is
- // // unexported; clients use user.NewContext and user.FromContext
- // // instead of using this key directly.
- // var userKey key
- //
- // // NewContext returns a new Context that carries value u.
- // func NewContext(ctx context.Context, u *User) context.Context {
- // return context.WithValue(ctx, userKey, u)
- // }
- //
- // // FromContext returns the User value stored in ctx, if any.
- // func FromContext(ctx context.Context) (*User, bool) {
- // u, ok := ctx.Value(userKey).(*User)
- // return u, ok
- // }
- Value(key any) any
-}
-
-// Canceled is the error returned by Context.Err when the context is canceled.
-var Canceled = errors.New("context canceled")
-
-// DeadlineExceeded is the error returned by Context.Err when the context's
-// deadline passes.
-var DeadlineExceeded error = deadlineExceededError{}
-
-type deadlineExceededError struct{}
-
-func (deadlineExceededError) Error() string { return "context deadline exceeded" }
-func (deadlineExceededError) Timeout() bool { return true }
-func (deadlineExceededError) Temporary() bool { return true }
-
-// An emptyCtx is never canceled, has no values, and has no deadline. It is not
-// struct{}, since vars of this type must have distinct addresses.
-type emptyCtx int
-
-func (*emptyCtx) Deadline() (deadline time.Time, ok bool) {
- return
-}
-
-func (*emptyCtx) Done() <-chan struct{} {
- return nil
-}
-
-func (*emptyCtx) Err() error {
- return nil
-}
-
-func (*emptyCtx) Value(key any) any {
- return nil
-}
-
-func (e *emptyCtx) String() string {
- switch e {
- case background:
- return "context.Background"
- case todo:
- return "context.TODO"
- }
- return "unknown empty Context"
-}
-
-var (
- background = new(emptyCtx)
- todo = new(emptyCtx)
-)
-
-// Background returns a non-nil, empty Context. It is never canceled, has no
-// values, and has no deadline. It is typically used by the main function,
-// initialization, and tests, and as the top-level Context for incoming
-// requests.
-func Background() Context {
- return background
-}
-
-// TODO returns a non-nil, empty Context. Code should use context.TODO when
-// it's unclear which Context to use or it is not yet available (because the
-// surrounding function has not yet been extended to accept a Context
-// parameter).
-func TODO() Context {
- return todo
-}
-
-// A CancelFunc tells an operation to abandon its work.
-// A CancelFunc does not wait for the work to stop.
-// A CancelFunc may be called by multiple goroutines simultaneously.
-// After the first call, subsequent calls to a CancelFunc do nothing.
-type CancelFunc func()
-
-// WithCancel returns a copy of parent with a new Done channel. The returned
-// context's Done channel is closed when the returned cancel function is called
-// or when the parent context's Done channel is closed, whichever happens first.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
- c := withCancel(parent)
- return c, func() { c.cancel(true, Canceled, nil) }
-}
-
-// A CancelCauseFunc behaves like a CancelFunc but additionally sets the cancellation cause.
-// This cause can be retrieved by calling Cause on the canceled Context or on
-// any of its derived Contexts.
-//
-// If the context has already been canceled, CancelCauseFunc does not set the cause.
-// For example, if childContext is derived from parentContext:
-// - if parentContext is canceled with cause1 before childContext is canceled with cause2,
-// then Cause(parentContext) == Cause(childContext) == cause1
-// - if childContext is canceled with cause2 before parentContext is canceled with cause1,
-// then Cause(parentContext) == cause1 and Cause(childContext) == cause2
-type CancelCauseFunc func(cause error)
-
-// WithCancelCause behaves like WithCancel but returns a CancelCauseFunc instead of a CancelFunc.
-// Calling cancel with a non-nil error (the "cause") records that error in ctx;
-// it can then be retrieved using Cause(ctx).
-// Calling cancel with nil sets the cause to Canceled.
-//
-// Example use:
-//
-// ctx, cancel := context.WithCancelCause(parent)
-// cancel(myError)
-// ctx.Err() // returns context.Canceled
-// context.Cause(ctx) // returns myError
-func WithCancelCause(parent Context) (ctx Context, cancel CancelCauseFunc) {
- c := withCancel(parent)
- return c, func(cause error) { c.cancel(true, Canceled, cause) }
-}
-
-func withCancel(parent Context) *cancelCtx {
- if parent == nil {
- panic("cannot create context from nil parent")
- }
- c := newCancelCtx(parent)
- propagateCancel(parent, c)
- return c
-}
-
-// Cause returns a non-nil error explaining why c was canceled.
-// The first cancellation of c or one of its parents sets the cause.
-// If that cancellation happened via a call to CancelCauseFunc(err),
-// then Cause returns err.
-// Otherwise Cause(c) returns the same value as c.Err().
-// Cause returns nil if c has not been canceled yet.
-func Cause(c Context) error {
- if cc, ok := c.Value(&cancelCtxKey).(*cancelCtx); ok {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- return cc.cause
- }
- return nil
-}
-
-// newCancelCtx returns an initialized cancelCtx.
-func newCancelCtx(parent Context) *cancelCtx {
- return &cancelCtx{Context: parent}
-}
-
-// goroutines counts the number of goroutines ever created; for testing.
-var goroutines atomic.Int32
-
-// propagateCancel arranges for child to be canceled when parent is.
-func propagateCancel(parent Context, child canceler) {
- done := parent.Done()
- if done == nil {
- return // parent is never canceled
- }
-
- select {
- case <-done:
- // parent is already canceled
- child.cancel(false, parent.Err(), Cause(parent))
- return
- default:
- }
-
- if p, ok := parentCancelCtx(parent); ok {
- p.mu.Lock()
- if p.err != nil {
- // parent has already been canceled
- child.cancel(false, p.err, p.cause)
- } else {
- if p.children == nil {
- p.children = make(map[canceler]struct{})
- }
- p.children[child] = struct{}{}
- }
- p.mu.Unlock()
- } else {
- goroutines.Add(1)
- go func() {
- select {
- case <-parent.Done():
- child.cancel(false, parent.Err(), Cause(parent))
- case <-child.Done():
- }
- }()
- }
-}
-
-// &cancelCtxKey is the key that a cancelCtx returns itself for.
-var cancelCtxKey int
-
-// parentCancelCtx returns the underlying *cancelCtx for parent.
-// It does this by looking up parent.Value(&cancelCtxKey) to find
-// the innermost enclosing *cancelCtx and then checking whether
-// parent.Done() matches that *cancelCtx. (If not, the *cancelCtx
-// has been wrapped in a custom implementation providing a
-// different done channel, in which case we should not bypass it.)
-func parentCancelCtx(parent Context) (*cancelCtx, bool) {
- done := parent.Done()
- if done == closedchan || done == nil {
- return nil, false
- }
- p, ok := parent.Value(&cancelCtxKey).(*cancelCtx)
- if !ok {
- return nil, false
- }
- pdone, _ := p.done.Load().(chan struct{})
- if pdone != done {
- return nil, false
- }
- return p, true
-}
-
-// removeChild removes a context from its parent.
-func removeChild(parent Context, child canceler) {
- p, ok := parentCancelCtx(parent)
- if !ok {
- return
- }
- p.mu.Lock()
- if p.children != nil {
- delete(p.children, child)
- }
- p.mu.Unlock()
-}
-
-// A canceler is a context type that can be canceled directly. The
-// implementations are *cancelCtx and *timerCtx.
-type canceler interface {
- cancel(removeFromParent bool, err, cause error)
- Done() <-chan struct{}
-}
-
-// closedchan is a reusable closed channel.
-var closedchan = make(chan struct{})
-
-func init() {
- close(closedchan)
-}
-
-// A cancelCtx can be canceled. When canceled, it also cancels any children
-// that implement canceler.
-type cancelCtx struct {
- Context
-
- mu sync.Mutex // protects following fields
- done atomic.Value // of chan struct{}, created lazily, closed by first cancel call
- children map[canceler]struct{} // set to nil by the first cancel call
- err error // set to non-nil by the first cancel call
- cause error // set to non-nil by the first cancel call
-}
-
-func (c *cancelCtx) Value(key any) any {
- if key == &cancelCtxKey {
- return c
- }
- return value(c.Context, key)
-}
-
-func (c *cancelCtx) Done() <-chan struct{} {
- d := c.done.Load()
- if d != nil {
- return d.(chan struct{})
- }
- c.mu.Lock()
- defer c.mu.Unlock()
- d = c.done.Load()
- if d == nil {
- d = make(chan struct{})
- c.done.Store(d)
- }
- return d.(chan struct{})
-}
-
-func (c *cancelCtx) Err() error {
- c.mu.Lock()
- err := c.err
- c.mu.Unlock()
- return err
-}
-
-type stringer interface {
- String() string
-}
-
-func contextName(c Context) string {
- if s, ok := c.(stringer); ok {
- return s.String()
- }
- return reflectlite.TypeOf(c).String()
-}
-
-func (c *cancelCtx) String() string {
- return contextName(c.Context) + ".WithCancel"
-}
-
-// cancel closes c.done, cancels each of c's children, and, if
-// removeFromParent is true, removes c from its parent's children.
-// cancel sets c.cause to cause if this is the first time c is canceled.
-func (c *cancelCtx) cancel(removeFromParent bool, err, cause error) {
- if err == nil {
- panic("context: internal error: missing cancel error")
- }
- if cause == nil {
- cause = err
- }
- c.mu.Lock()
- if c.err != nil {
- c.mu.Unlock()
- return // already canceled
- }
- c.err = err
- c.cause = cause
- d, _ := c.done.Load().(chan struct{})
- if d == nil {
- c.done.Store(closedchan)
- } else {
- close(d)
- }
- for child := range c.children {
- // NOTE: acquiring the child's lock while holding parent's lock.
- child.cancel(false, err, cause)
- }
- c.children = nil
- c.mu.Unlock()
-
- if removeFromParent {
- removeChild(c.Context, c)
- }
-}
-
-// WithDeadline returns a copy of the parent context with the deadline adjusted
-// to be no later than d. If the parent's deadline is already earlier than d,
-// WithDeadline(parent, d) is semantically equivalent to parent. The returned
-// context's Done channel is closed when the deadline expires, when the returned
-// cancel function is called, or when the parent context's Done channel is
-// closed, whichever happens first.
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete.
-func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {
- if parent == nil {
- panic("cannot create context from nil parent")
- }
- if cur, ok := parent.Deadline(); ok && cur.Before(d) {
- // The current deadline is already sooner than the new one.
- return WithCancel(parent)
- }
- c := &timerCtx{
- cancelCtx: newCancelCtx(parent),
- deadline: d,
- }
- propagateCancel(parent, c)
- dur := time.Until(d)
- if dur <= 0 {
- c.cancel(true, DeadlineExceeded, nil) // deadline has already passed
- return c, func() { c.cancel(false, Canceled, nil) }
- }
- c.mu.Lock()
- defer c.mu.Unlock()
- if c.err == nil {
- c.timer = time.AfterFunc(dur, func() {
- c.cancel(true, DeadlineExceeded, nil)
- })
- }
- return c, func() { c.cancel(true, Canceled, nil) }
-}
-
-// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
-// implement Done and Err. It implements cancel by stopping its timer then
-// delegating to cancelCtx.cancel.
-type timerCtx struct {
- *cancelCtx
- timer *time.Timer // Under cancelCtx.mu.
-
- deadline time.Time
-}
-
-func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
- return c.deadline, true
-}
-
-func (c *timerCtx) String() string {
- return contextName(c.cancelCtx.Context) + ".WithDeadline(" +
- c.deadline.String() + " [" +
- time.Until(c.deadline).String() + "])"
-}
-
-func (c *timerCtx) cancel(removeFromParent bool, err, cause error) {
- c.cancelCtx.cancel(false, err, cause)
- if removeFromParent {
- // Remove this timerCtx from its parent cancelCtx's children.
- removeChild(c.cancelCtx.Context, c)
- }
- c.mu.Lock()
- if c.timer != nil {
- c.timer.Stop()
- c.timer = nil
- }
- c.mu.Unlock()
-}
-
-// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
-//
-// Canceling this context releases resources associated with it, so code should
-// call cancel as soon as the operations running in this Context complete:
-//
-// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
-// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
-// defer cancel() // releases resources if slowOperation completes before timeout elapses
-// return slowOperation(ctx)
-// }
-func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
- return WithDeadline(parent, time.Now().Add(timeout))
-}
-
-// WithValue returns a copy of parent in which the value associated with key is
-// val.
-//
-// Use context Values only for request-scoped data that transits processes and
-// APIs, not for passing optional parameters to functions.
-//
-// The provided key must be comparable and should not be of type
-// string or any other built-in type to avoid collisions between
-// packages using context. Users of WithValue should define their own
-// types for keys. To avoid allocating when assigning to an
-// interface{}, context keys often have concrete type
-// struct{}. Alternatively, exported context key variables' static
-// type should be a pointer or interface.
-func WithValue(parent Context, key, val any) Context {
- if parent == nil {
- panic("cannot create context from nil parent")
- }
- if key == nil {
- panic("nil key")
- }
- if !reflectlite.TypeOf(key).Comparable() {
- panic("key is not comparable")
- }
- return &valueCtx{parent, key, val}
-}
-
-// A valueCtx carries a key-value pair. It implements Value for that key and
-// delegates all other calls to the embedded Context.
-type valueCtx struct {
- Context
- key, val any
-}
-
-// stringify tries a bit to stringify v, without using fmt, since we don't
-// want context depending on the unicode tables. This is only used by
-// *valueCtx.String().
-func stringify(v any) string {
- switch s := v.(type) {
- case stringer:
- return s.String()
- case string:
- return s
- }
- return "<not Stringer>"
-}
-
-func (c *valueCtx) String() string {
- return contextName(c.Context) + ".WithValue(type " +
- reflectlite.TypeOf(c.key).String() +
- ", val " + stringify(c.val) + ")"
-}
-
-func (c *valueCtx) Value(key any) any {
- if c.key == key {
- return c.val
- }
- return value(c.Context, key)
-}
-
-func value(c Context, key any) any {
- for {
- switch ctx := c.(type) {
- case *valueCtx:
- if key == ctx.key {
- return ctx.val
- }
- c = ctx.Context
- case *cancelCtx:
- if key == &cancelCtxKey {
- return c
- }
- c = ctx.Context
- case *timerCtx:
- if key == &cancelCtxKey {
- return ctx.cancelCtx
- }
- c = ctx.Context
- case *emptyCtx:
- return nil
- default:
- return c.Value(key)
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/context/ya.make b/contrib/go/_std_1.20/src/context/ya.make
deleted file mode 100644
index 81076096a2..0000000000
--- a/contrib/go/_std_1.20/src/context/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- context.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/aes/asm_arm64.s b/contrib/go/_std_1.20/src/crypto/aes/asm_arm64.s
deleted file mode 100644
index 13aee5ca29..0000000000
--- a/contrib/go/_std_1.20/src/crypto/aes/asm_arm64.s
+++ /dev/null
@@ -1,281 +0,0 @@
-// Copyright 2017 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.
-
-#include "textflag.h"
-DATA rotInvSRows<>+0x00(SB)/8, $0x080f0205040b0e01
-DATA rotInvSRows<>+0x08(SB)/8, $0x00070a0d0c030609
-GLOBL rotInvSRows<>(SB), (NOPTR+RODATA), $16
-DATA invSRows<>+0x00(SB)/8, $0x0b0e0104070a0d00
-DATA invSRows<>+0x08(SB)/8, $0x0306090c0f020508
-GLOBL invSRows<>(SB), (NOPTR+RODATA), $16
-// func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
-TEXT ·encryptBlockAsm(SB),NOSPLIT,$0
- MOVD nr+0(FP), R9
- MOVD xk+8(FP), R10
- MOVD dst+16(FP), R11
- MOVD src+24(FP), R12
-
- VLD1 (R12), [V0.B16]
-
- CMP $12, R9
- BLT enc128
- BEQ enc196
-enc256:
- VLD1.P 32(R10), [V1.B16, V2.B16]
- AESE V1.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V2.B16, V0.B16
- AESMC V0.B16, V0.B16
-enc196:
- VLD1.P 32(R10), [V3.B16, V4.B16]
- AESE V3.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V4.B16, V0.B16
- AESMC V0.B16, V0.B16
-enc128:
- VLD1.P 64(R10), [V5.B16, V6.B16, V7.B16, V8.B16]
- VLD1.P 64(R10), [V9.B16, V10.B16, V11.B16, V12.B16]
- VLD1.P 48(R10), [V13.B16, V14.B16, V15.B16]
- AESE V5.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V6.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V7.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V8.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V9.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V10.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V11.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V12.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V13.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V14.B16, V0.B16
- VEOR V0.B16, V15.B16, V0.B16
- VST1 [V0.B16], (R11)
- RET
-
-// func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
-TEXT ·decryptBlockAsm(SB),NOSPLIT,$0
- MOVD nr+0(FP), R9
- MOVD xk+8(FP), R10
- MOVD dst+16(FP), R11
- MOVD src+24(FP), R12
-
- VLD1 (R12), [V0.B16]
-
- CMP $12, R9
- BLT dec128
- BEQ dec196
-dec256:
- VLD1.P 32(R10), [V1.B16, V2.B16]
- AESD V1.B16, V0.B16
- AESIMC V0.B16, V0.B16
- AESD V2.B16, V0.B16
- AESIMC V0.B16, V0.B16
-dec196:
- VLD1.P 32(R10), [V3.B16, V4.B16]
- AESD V3.B16, V0.B16
- AESIMC V0.B16, V0.B16
- AESD V4.B16, V0.B16
- AESIMC V0.B16, V0.B16
-dec128:
- VLD1.P 64(R10), [V5.B16, V6.B16, V7.B16, V8.B16]
- VLD1.P 64(R10), [V9.B16, V10.B16, V11.B16, V12.B16]
- VLD1.P 48(R10), [V13.B16, V14.B16, V15.B16]
- AESD V5.B16, V0.B16
- AESIMC V0.B16, V0.B16
- AESD V6.B16, V0.B16
- AESIMC V0.B16, V0.B16
- AESD V7.B16, V0.B16
- AESIMC V0.B16, V0.B16
- AESD V8.B16, V0.B16
- AESIMC V0.B16, V0.B16
- AESD V9.B16, V0.B16
- AESIMC V0.B16, V0.B16
- AESD V10.B16, V0.B16
- AESIMC V0.B16, V0.B16
- AESD V11.B16, V0.B16
- AESIMC V0.B16, V0.B16
- AESD V12.B16, V0.B16
- AESIMC V0.B16, V0.B16
- AESD V13.B16, V0.B16
- AESIMC V0.B16, V0.B16
- AESD V14.B16, V0.B16
- VEOR V0.B16, V15.B16, V0.B16
- VST1 [V0.B16], (R11)
- RET
-
-// func expandKeyAsm(nr int, key *byte, enc, dec *uint32) {
-// Note that round keys are stored in uint128 format, not uint32
-TEXT ·expandKeyAsm(SB),NOSPLIT,$0
- MOVD nr+0(FP), R8
- MOVD key+8(FP), R9
- MOVD enc+16(FP), R10
- MOVD dec+24(FP), R11
- LDP rotInvSRows<>(SB), (R0, R1)
- VMOV R0, V3.D[0]
- VMOV R1, V3.D[1]
- VEOR V0.B16, V0.B16, V0.B16 // All zeroes
- MOVW $1, R13
- TBZ $1, R8, ks192
- TBNZ $2, R8, ks256
- LDPW (R9), (R4, R5)
- LDPW 8(R9), (R6, R7)
- STPW.P (R4, R5), 8(R10)
- STPW.P (R6, R7), 8(R10)
- MOVW $0x1b, R14
-ks128Loop:
- VMOV R7, V2.S[0]
- WORD $0x4E030042 // TBL V3.B16, [V2.B16], V2.B16
- AESE V0.B16, V2.B16 // Use AES to compute the SBOX
- EORW R13, R4
- LSLW $1, R13 // Compute next Rcon
- ANDSW $0x100, R13, ZR
- CSELW NE, R14, R13, R13 // Fake modulo
- SUBS $1, R8
- VMOV V2.S[0], R0
- EORW R0, R4
- EORW R4, R5
- EORW R5, R6
- EORW R6, R7
- STPW.P (R4, R5), 8(R10)
- STPW.P (R6, R7), 8(R10)
- BNE ks128Loop
- CBZ R11, ksDone // If dec is nil we are done
- SUB $176, R10
- // Decryption keys are encryption keys with InverseMixColumns applied
- VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
- VMOV V0.B16, V7.B16
- AESIMC V1.B16, V6.B16
- AESIMC V2.B16, V5.B16
- AESIMC V3.B16, V4.B16
- VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
- AESIMC V0.B16, V11.B16
- AESIMC V1.B16, V10.B16
- AESIMC V2.B16, V9.B16
- AESIMC V3.B16, V8.B16
- VLD1 (R10), [V0.B16, V1.B16, V2.B16]
- AESIMC V0.B16, V14.B16
- AESIMC V1.B16, V13.B16
- VMOV V2.B16, V12.B16
- VST1.P [V12.B16, V13.B16, V14.B16], 48(R11)
- VST1.P [V8.B16, V9.B16, V10.B16, V11.B16], 64(R11)
- VST1 [V4.B16, V5.B16, V6.B16, V7.B16], (R11)
- B ksDone
-ks192:
- LDPW (R9), (R2, R3)
- LDPW 8(R9), (R4, R5)
- LDPW 16(R9), (R6, R7)
- STPW.P (R2, R3), 8(R10)
- STPW.P (R4, R5), 8(R10)
- SUB $4, R8
-ks192Loop:
- STPW.P (R6, R7), 8(R10)
- VMOV R7, V2.S[0]
- WORD $0x4E030042 //TBL V3.B16, [V2.B16], V2.B16
- AESE V0.B16, V2.B16
- EORW R13, R2
- LSLW $1, R13
- SUBS $1, R8
- VMOV V2.S[0], R0
- EORW R0, R2
- EORW R2, R3
- EORW R3, R4
- EORW R4, R5
- EORW R5, R6
- EORW R6, R7
- STPW.P (R2, R3), 8(R10)
- STPW.P (R4, R5), 8(R10)
- BNE ks192Loop
- CBZ R11, ksDone
- SUB $208, R10
- VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
- VMOV V0.B16, V7.B16
- AESIMC V1.B16, V6.B16
- AESIMC V2.B16, V5.B16
- AESIMC V3.B16, V4.B16
- VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
- AESIMC V0.B16, V11.B16
- AESIMC V1.B16, V10.B16
- AESIMC V2.B16, V9.B16
- AESIMC V3.B16, V8.B16
- VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
- AESIMC V0.B16, V15.B16
- AESIMC V1.B16, V14.B16
- AESIMC V2.B16, V13.B16
- AESIMC V3.B16, V12.B16
- VLD1 (R10), [V0.B16]
- VST1.P [V0.B16], 16(R11)
- VST1.P [V12.B16, V13.B16, V14.B16, V15.B16], 64(R11)
- VST1.P [V8.B16, V9.B16, V10.B16, V11.B16], 64(R11)
- VST1 [V4.B16, V5.B16, V6.B16, V7.B16], (R11)
- B ksDone
-ks256:
- LDP invSRows<>(SB), (R0, R1)
- VMOV R0, V4.D[0]
- VMOV R1, V4.D[1]
- LDPW (R9), (R0, R1)
- LDPW 8(R9), (R2, R3)
- LDPW 16(R9), (R4, R5)
- LDPW 24(R9), (R6, R7)
- STPW.P (R0, R1), 8(R10)
- STPW.P (R2, R3), 8(R10)
- SUB $7, R8
-ks256Loop:
- STPW.P (R4, R5), 8(R10)
- STPW.P (R6, R7), 8(R10)
- VMOV R7, V2.S[0]
- WORD $0x4E030042 //TBL V3.B16, [V2.B16], V2.B16
- AESE V0.B16, V2.B16
- EORW R13, R0
- LSLW $1, R13
- SUBS $1, R8
- VMOV V2.S[0], R9
- EORW R9, R0
- EORW R0, R1
- EORW R1, R2
- EORW R2, R3
- VMOV R3, V2.S[0]
- WORD $0x4E040042 //TBL V3.B16, [V2.B16], V2.B16
- AESE V0.B16, V2.B16
- VMOV V2.S[0], R9
- EORW R9, R4
- EORW R4, R5
- EORW R5, R6
- EORW R6, R7
- STPW.P (R0, R1), 8(R10)
- STPW.P (R2, R3), 8(R10)
- BNE ks256Loop
- CBZ R11, ksDone
- SUB $240, R10
- VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
- VMOV V0.B16, V7.B16
- AESIMC V1.B16, V6.B16
- AESIMC V2.B16, V5.B16
- AESIMC V3.B16, V4.B16
- VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
- AESIMC V0.B16, V11.B16
- AESIMC V1.B16, V10.B16
- AESIMC V2.B16, V9.B16
- AESIMC V3.B16, V8.B16
- VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
- AESIMC V0.B16, V15.B16
- AESIMC V1.B16, V14.B16
- AESIMC V2.B16, V13.B16
- AESIMC V3.B16, V12.B16
- VLD1 (R10), [V0.B16, V1.B16, V2.B16]
- AESIMC V0.B16, V18.B16
- AESIMC V1.B16, V17.B16
- VMOV V2.B16, V16.B16
- VST1.P [V16.B16, V17.B16, V18.B16], 48(R11)
- VST1.P [V12.B16, V13.B16, V14.B16, V15.B16], 64(R11)
- VST1.P [V8.B16, V9.B16, V10.B16, V11.B16], 64(R11)
- VST1 [V4.B16, V5.B16, V6.B16, V7.B16], (R11)
-ksDone:
- RET
diff --git a/contrib/go/_std_1.20/src/crypto/aes/gcm_arm64.s b/contrib/go/_std_1.20/src/crypto/aes/gcm_arm64.s
deleted file mode 100644
index 61c868cd0c..0000000000
--- a/contrib/go/_std_1.20/src/crypto/aes/gcm_arm64.s
+++ /dev/null
@@ -1,1021 +0,0 @@
-// Copyright 2018 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.
-
-#include "textflag.h"
-
-#define B0 V0
-#define B1 V1
-#define B2 V2
-#define B3 V3
-#define B4 V4
-#define B5 V5
-#define B6 V6
-#define B7 V7
-
-#define ACC0 V8
-#define ACC1 V9
-#define ACCM V10
-
-#define T0 V11
-#define T1 V12
-#define T2 V13
-#define T3 V14
-
-#define POLY V15
-#define ZERO V16
-#define INC V17
-#define CTR V18
-
-#define K0 V19
-#define K1 V20
-#define K2 V21
-#define K3 V22
-#define K4 V23
-#define K5 V24
-#define K6 V25
-#define K7 V26
-#define K8 V27
-#define K9 V28
-#define K10 V29
-#define K11 V30
-#define KLAST V31
-
-#define reduce() \
- VEOR ACC0.B16, ACCM.B16, ACCM.B16 \
- VEOR ACC1.B16, ACCM.B16, ACCM.B16 \
- VEXT $8, ZERO.B16, ACCM.B16, T0.B16 \
- VEXT $8, ACCM.B16, ZERO.B16, ACCM.B16 \
- VEOR ACCM.B16, ACC0.B16, ACC0.B16 \
- VEOR T0.B16, ACC1.B16, ACC1.B16 \
- VPMULL POLY.D1, ACC0.D1, T0.Q1 \
- VEXT $8, ACC0.B16, ACC0.B16, ACC0.B16 \
- VEOR T0.B16, ACC0.B16, ACC0.B16 \
- VPMULL POLY.D1, ACC0.D1, T0.Q1 \
- VEOR T0.B16, ACC1.B16, ACC1.B16 \
- VEXT $8, ACC1.B16, ACC1.B16, ACC1.B16 \
- VEOR ACC1.B16, ACC0.B16, ACC0.B16 \
-
-// func gcmAesFinish(productTable *[256]byte, tagMask, T *[16]byte, pLen, dLen uint64)
-TEXT ·gcmAesFinish(SB),NOSPLIT,$0
-#define pTbl R0
-#define tMsk R1
-#define tPtr R2
-#define plen R3
-#define dlen R4
-
- MOVD $0xC2, R1
- LSL $56, R1
- MOVD $1, R0
- VMOV R1, POLY.D[0]
- VMOV R0, POLY.D[1]
- VEOR ZERO.B16, ZERO.B16, ZERO.B16
-
- MOVD productTable+0(FP), pTbl
- MOVD tagMask+8(FP), tMsk
- MOVD T+16(FP), tPtr
- MOVD pLen+24(FP), plen
- MOVD dLen+32(FP), dlen
-
- VLD1 (tPtr), [ACC0.B16]
- VLD1 (tMsk), [B1.B16]
-
- LSL $3, plen
- LSL $3, dlen
-
- VMOV dlen, B0.D[0]
- VMOV plen, B0.D[1]
-
- ADD $14*16, pTbl
- VLD1.P (pTbl), [T1.B16, T2.B16]
-
- VEOR ACC0.B16, B0.B16, B0.B16
-
- VEXT $8, B0.B16, B0.B16, T0.B16
- VEOR B0.B16, T0.B16, T0.B16
- VPMULL B0.D1, T1.D1, ACC1.Q1
- VPMULL2 B0.D2, T1.D2, ACC0.Q1
- VPMULL T0.D1, T2.D1, ACCM.Q1
-
- reduce()
-
- VREV64 ACC0.B16, ACC0.B16
- VEOR B1.B16, ACC0.B16, ACC0.B16
-
- VST1 [ACC0.B16], (tPtr)
- RET
-#undef pTbl
-#undef tMsk
-#undef tPtr
-#undef plen
-#undef dlen
-
-// func gcmAesInit(productTable *[256]byte, ks []uint32)
-TEXT ·gcmAesInit(SB),NOSPLIT,$0
-#define pTbl R0
-#define KS R1
-#define NR R2
-#define I R3
- MOVD productTable+0(FP), pTbl
- MOVD ks_base+8(FP), KS
- MOVD ks_len+16(FP), NR
-
- MOVD $0xC2, I
- LSL $56, I
- VMOV I, POLY.D[0]
- MOVD $1, I
- VMOV I, POLY.D[1]
- VEOR ZERO.B16, ZERO.B16, ZERO.B16
-
- // Encrypt block 0 with the AES key to generate the hash key H
- VLD1.P 64(KS), [T0.B16, T1.B16, T2.B16, T3.B16]
- VEOR B0.B16, B0.B16, B0.B16
- AESE T0.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE T1.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE T2.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE T3.B16, B0.B16
- AESMC B0.B16, B0.B16
- VLD1.P 64(KS), [T0.B16, T1.B16, T2.B16, T3.B16]
- AESE T0.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE T1.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE T2.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE T3.B16, B0.B16
- AESMC B0.B16, B0.B16
- TBZ $4, NR, initEncFinish
- VLD1.P 32(KS), [T0.B16, T1.B16]
- AESE T0.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE T1.B16, B0.B16
- AESMC B0.B16, B0.B16
- TBZ $3, NR, initEncFinish
- VLD1.P 32(KS), [T0.B16, T1.B16]
- AESE T0.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE T1.B16, B0.B16
- AESMC B0.B16, B0.B16
-initEncFinish:
- VLD1 (KS), [T0.B16, T1.B16, T2.B16]
- AESE T0.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE T1.B16, B0.B16
- VEOR T2.B16, B0.B16, B0.B16
-
- VREV64 B0.B16, B0.B16
-
- // Multiply by 2 modulo P
- VMOV B0.D[0], I
- ASR $63, I
- VMOV I, T1.D[0]
- VMOV I, T1.D[1]
- VAND POLY.B16, T1.B16, T1.B16
- VUSHR $63, B0.D2, T2.D2
- VEXT $8, ZERO.B16, T2.B16, T2.B16
- VSHL $1, B0.D2, B0.D2
- VEOR T1.B16, B0.B16, B0.B16
- VEOR T2.B16, B0.B16, B0.B16 // Can avoid this when VSLI is available
-
- // Karatsuba pre-computation
- VEXT $8, B0.B16, B0.B16, B1.B16
- VEOR B0.B16, B1.B16, B1.B16
-
- ADD $14*16, pTbl
- VST1 [B0.B16, B1.B16], (pTbl)
- SUB $2*16, pTbl
-
- VMOV B0.B16, B2.B16
- VMOV B1.B16, B3.B16
-
- MOVD $7, I
-
-initLoop:
- // Compute powers of H
- SUBS $1, I
-
- VPMULL B0.D1, B2.D1, T1.Q1
- VPMULL2 B0.D2, B2.D2, T0.Q1
- VPMULL B1.D1, B3.D1, T2.Q1
- VEOR T0.B16, T2.B16, T2.B16
- VEOR T1.B16, T2.B16, T2.B16
- VEXT $8, ZERO.B16, T2.B16, T3.B16
- VEXT $8, T2.B16, ZERO.B16, T2.B16
- VEOR T2.B16, T0.B16, T0.B16
- VEOR T3.B16, T1.B16, T1.B16
- VPMULL POLY.D1, T0.D1, T2.Q1
- VEXT $8, T0.B16, T0.B16, T0.B16
- VEOR T2.B16, T0.B16, T0.B16
- VPMULL POLY.D1, T0.D1, T2.Q1
- VEXT $8, T0.B16, T0.B16, T0.B16
- VEOR T2.B16, T0.B16, T0.B16
- VEOR T1.B16, T0.B16, B2.B16
- VMOV B2.B16, B3.B16
- VEXT $8, B2.B16, B2.B16, B2.B16
- VEOR B2.B16, B3.B16, B3.B16
-
- VST1 [B2.B16, B3.B16], (pTbl)
- SUB $2*16, pTbl
-
- BNE initLoop
- RET
-#undef I
-#undef NR
-#undef KS
-#undef pTbl
-
-// func gcmAesData(productTable *[256]byte, data []byte, T *[16]byte)
-TEXT ·gcmAesData(SB),NOSPLIT,$0
-#define pTbl R0
-#define aut R1
-#define tPtr R2
-#define autLen R3
-#define H0 R4
-#define pTblSave R5
-
-#define mulRound(X) \
- VLD1.P 32(pTbl), [T1.B16, T2.B16] \
- VREV64 X.B16, X.B16 \
- VEXT $8, X.B16, X.B16, T0.B16 \
- VEOR X.B16, T0.B16, T0.B16 \
- VPMULL X.D1, T1.D1, T3.Q1 \
- VEOR T3.B16, ACC1.B16, ACC1.B16 \
- VPMULL2 X.D2, T1.D2, T3.Q1 \
- VEOR T3.B16, ACC0.B16, ACC0.B16 \
- VPMULL T0.D1, T2.D1, T3.Q1 \
- VEOR T3.B16, ACCM.B16, ACCM.B16
-
- MOVD productTable+0(FP), pTbl
- MOVD data_base+8(FP), aut
- MOVD data_len+16(FP), autLen
- MOVD T+32(FP), tPtr
-
- VEOR ACC0.B16, ACC0.B16, ACC0.B16
- CBZ autLen, dataBail
-
- MOVD $0xC2, H0
- LSL $56, H0
- VMOV H0, POLY.D[0]
- MOVD $1, H0
- VMOV H0, POLY.D[1]
- VEOR ZERO.B16, ZERO.B16, ZERO.B16
- MOVD pTbl, pTblSave
-
- CMP $13, autLen
- BEQ dataTLS
- CMP $128, autLen
- BLT startSinglesLoop
- B octetsLoop
-
-dataTLS:
- ADD $14*16, pTbl
- VLD1.P (pTbl), [T1.B16, T2.B16]
- VEOR B0.B16, B0.B16, B0.B16
-
- MOVD (aut), H0
- VMOV H0, B0.D[0]
- MOVW 8(aut), H0
- VMOV H0, B0.S[2]
- MOVB 12(aut), H0
- VMOV H0, B0.B[12]
-
- MOVD $0, autLen
- B dataMul
-
-octetsLoop:
- CMP $128, autLen
- BLT startSinglesLoop
- SUB $128, autLen
-
- VLD1.P 32(aut), [B0.B16, B1.B16]
-
- VLD1.P 32(pTbl), [T1.B16, T2.B16]
- VREV64 B0.B16, B0.B16
- VEOR ACC0.B16, B0.B16, B0.B16
- VEXT $8, B0.B16, B0.B16, T0.B16
- VEOR B0.B16, T0.B16, T0.B16
- VPMULL B0.D1, T1.D1, ACC1.Q1
- VPMULL2 B0.D2, T1.D2, ACC0.Q1
- VPMULL T0.D1, T2.D1, ACCM.Q1
-
- mulRound(B1)
- VLD1.P 32(aut), [B2.B16, B3.B16]
- mulRound(B2)
- mulRound(B3)
- VLD1.P 32(aut), [B4.B16, B5.B16]
- mulRound(B4)
- mulRound(B5)
- VLD1.P 32(aut), [B6.B16, B7.B16]
- mulRound(B6)
- mulRound(B7)
-
- MOVD pTblSave, pTbl
- reduce()
- B octetsLoop
-
-startSinglesLoop:
-
- ADD $14*16, pTbl
- VLD1.P (pTbl), [T1.B16, T2.B16]
-
-singlesLoop:
-
- CMP $16, autLen
- BLT dataEnd
- SUB $16, autLen
-
- VLD1.P 16(aut), [B0.B16]
-dataMul:
- VREV64 B0.B16, B0.B16
- VEOR ACC0.B16, B0.B16, B0.B16
-
- VEXT $8, B0.B16, B0.B16, T0.B16
- VEOR B0.B16, T0.B16, T0.B16
- VPMULL B0.D1, T1.D1, ACC1.Q1
- VPMULL2 B0.D2, T1.D2, ACC0.Q1
- VPMULL T0.D1, T2.D1, ACCM.Q1
-
- reduce()
-
- B singlesLoop
-
-dataEnd:
-
- CBZ autLen, dataBail
- VEOR B0.B16, B0.B16, B0.B16
- ADD autLen, aut
-
-dataLoadLoop:
- MOVB.W -1(aut), H0
- VEXT $15, B0.B16, ZERO.B16, B0.B16
- VMOV H0, B0.B[0]
- SUBS $1, autLen
- BNE dataLoadLoop
- B dataMul
-
-dataBail:
- VST1 [ACC0.B16], (tPtr)
- RET
-
-#undef pTbl
-#undef aut
-#undef tPtr
-#undef autLen
-#undef H0
-#undef pTblSave
-
-// func gcmAesEnc(productTable *[256]byte, dst, src []byte, ctr, T *[16]byte, ks []uint32)
-TEXT ·gcmAesEnc(SB),NOSPLIT,$0
-#define pTbl R0
-#define dstPtr R1
-#define ctrPtr R2
-#define srcPtr R3
-#define ks R4
-#define tPtr R5
-#define srcPtrLen R6
-#define aluCTR R7
-#define aluTMP R8
-#define aluK R9
-#define NR R10
-#define H0 R11
-#define H1 R12
-#define curK R13
-#define pTblSave R14
-
-#define aesrndx8(K) \
- AESE K.B16, B0.B16 \
- AESMC B0.B16, B0.B16 \
- AESE K.B16, B1.B16 \
- AESMC B1.B16, B1.B16 \
- AESE K.B16, B2.B16 \
- AESMC B2.B16, B2.B16 \
- AESE K.B16, B3.B16 \
- AESMC B3.B16, B3.B16 \
- AESE K.B16, B4.B16 \
- AESMC B4.B16, B4.B16 \
- AESE K.B16, B5.B16 \
- AESMC B5.B16, B5.B16 \
- AESE K.B16, B6.B16 \
- AESMC B6.B16, B6.B16 \
- AESE K.B16, B7.B16 \
- AESMC B7.B16, B7.B16
-
-#define aesrndlastx8(K) \
- AESE K.B16, B0.B16 \
- AESE K.B16, B1.B16 \
- AESE K.B16, B2.B16 \
- AESE K.B16, B3.B16 \
- AESE K.B16, B4.B16 \
- AESE K.B16, B5.B16 \
- AESE K.B16, B6.B16 \
- AESE K.B16, B7.B16
-
- MOVD productTable+0(FP), pTbl
- MOVD dst+8(FP), dstPtr
- MOVD src_base+32(FP), srcPtr
- MOVD src_len+40(FP), srcPtrLen
- MOVD ctr+56(FP), ctrPtr
- MOVD T+64(FP), tPtr
- MOVD ks_base+72(FP), ks
- MOVD ks_len+80(FP), NR
-
- MOVD $0xC2, H1
- LSL $56, H1
- MOVD $1, H0
- VMOV H1, POLY.D[0]
- VMOV H0, POLY.D[1]
- VEOR ZERO.B16, ZERO.B16, ZERO.B16
- // Compute NR from len(ks)
- MOVD pTbl, pTblSave
- // Current tag, after AAD
- VLD1 (tPtr), [ACC0.B16]
- VEOR ACC1.B16, ACC1.B16, ACC1.B16
- VEOR ACCM.B16, ACCM.B16, ACCM.B16
- // Prepare initial counter, and the increment vector
- VLD1 (ctrPtr), [CTR.B16]
- VEOR INC.B16, INC.B16, INC.B16
- MOVD $1, H0
- VMOV H0, INC.S[3]
- VREV32 CTR.B16, CTR.B16
- VADD CTR.S4, INC.S4, CTR.S4
- // Skip to <8 blocks loop
- CMP $128, srcPtrLen
-
- MOVD ks, H0
- // For AES-128 round keys are stored in: K0 .. K10, KLAST
- VLD1.P 64(H0), [K0.B16, K1.B16, K2.B16, K3.B16]
- VLD1.P 64(H0), [K4.B16, K5.B16, K6.B16, K7.B16]
- VLD1.P 48(H0), [K8.B16, K9.B16, K10.B16]
- VMOV K10.B16, KLAST.B16
-
- BLT startSingles
- // There are at least 8 blocks to encrypt
- TBZ $4, NR, octetsLoop
-
- // For AES-192 round keys occupy: K0 .. K7, K10, K11, K8, K9, KLAST
- VMOV K8.B16, K10.B16
- VMOV K9.B16, K11.B16
- VMOV KLAST.B16, K8.B16
- VLD1.P 16(H0), [K9.B16]
- VLD1.P 16(H0), [KLAST.B16]
- TBZ $3, NR, octetsLoop
- // For AES-256 round keys occupy: K0 .. K7, K10, K11, mem, mem, K8, K9, KLAST
- VMOV KLAST.B16, K8.B16
- VLD1.P 16(H0), [K9.B16]
- VLD1.P 16(H0), [KLAST.B16]
- ADD $10*16, ks, H0
- MOVD H0, curK
-
-octetsLoop:
- SUB $128, srcPtrLen
-
- VMOV CTR.B16, B0.B16
- VADD B0.S4, INC.S4, B1.S4
- VREV32 B0.B16, B0.B16
- VADD B1.S4, INC.S4, B2.S4
- VREV32 B1.B16, B1.B16
- VADD B2.S4, INC.S4, B3.S4
- VREV32 B2.B16, B2.B16
- VADD B3.S4, INC.S4, B4.S4
- VREV32 B3.B16, B3.B16
- VADD B4.S4, INC.S4, B5.S4
- VREV32 B4.B16, B4.B16
- VADD B5.S4, INC.S4, B6.S4
- VREV32 B5.B16, B5.B16
- VADD B6.S4, INC.S4, B7.S4
- VREV32 B6.B16, B6.B16
- VADD B7.S4, INC.S4, CTR.S4
- VREV32 B7.B16, B7.B16
-
- aesrndx8(K0)
- aesrndx8(K1)
- aesrndx8(K2)
- aesrndx8(K3)
- aesrndx8(K4)
- aesrndx8(K5)
- aesrndx8(K6)
- aesrndx8(K7)
- TBZ $4, NR, octetsFinish
- aesrndx8(K10)
- aesrndx8(K11)
- TBZ $3, NR, octetsFinish
- VLD1.P 32(curK), [T1.B16, T2.B16]
- aesrndx8(T1)
- aesrndx8(T2)
- MOVD H0, curK
-octetsFinish:
- aesrndx8(K8)
- aesrndlastx8(K9)
-
- VEOR KLAST.B16, B0.B16, B0.B16
- VEOR KLAST.B16, B1.B16, B1.B16
- VEOR KLAST.B16, B2.B16, B2.B16
- VEOR KLAST.B16, B3.B16, B3.B16
- VEOR KLAST.B16, B4.B16, B4.B16
- VEOR KLAST.B16, B5.B16, B5.B16
- VEOR KLAST.B16, B6.B16, B6.B16
- VEOR KLAST.B16, B7.B16, B7.B16
-
- VLD1.P 32(srcPtr), [T1.B16, T2.B16]
- VEOR B0.B16, T1.B16, B0.B16
- VEOR B1.B16, T2.B16, B1.B16
- VST1.P [B0.B16, B1.B16], 32(dstPtr)
- VLD1.P 32(srcPtr), [T1.B16, T2.B16]
- VEOR B2.B16, T1.B16, B2.B16
- VEOR B3.B16, T2.B16, B3.B16
- VST1.P [B2.B16, B3.B16], 32(dstPtr)
- VLD1.P 32(srcPtr), [T1.B16, T2.B16]
- VEOR B4.B16, T1.B16, B4.B16
- VEOR B5.B16, T2.B16, B5.B16
- VST1.P [B4.B16, B5.B16], 32(dstPtr)
- VLD1.P 32(srcPtr), [T1.B16, T2.B16]
- VEOR B6.B16, T1.B16, B6.B16
- VEOR B7.B16, T2.B16, B7.B16
- VST1.P [B6.B16, B7.B16], 32(dstPtr)
-
- VLD1.P 32(pTbl), [T1.B16, T2.B16]
- VREV64 B0.B16, B0.B16
- VEOR ACC0.B16, B0.B16, B0.B16
- VEXT $8, B0.B16, B0.B16, T0.B16
- VEOR B0.B16, T0.B16, T0.B16
- VPMULL B0.D1, T1.D1, ACC1.Q1
- VPMULL2 B0.D2, T1.D2, ACC0.Q1
- VPMULL T0.D1, T2.D1, ACCM.Q1
-
- mulRound(B1)
- mulRound(B2)
- mulRound(B3)
- mulRound(B4)
- mulRound(B5)
- mulRound(B6)
- mulRound(B7)
- MOVD pTblSave, pTbl
- reduce()
-
- CMP $128, srcPtrLen
- BGE octetsLoop
-
-startSingles:
- CBZ srcPtrLen, done
- ADD $14*16, pTbl
- // Preload H and its Karatsuba precomp
- VLD1.P (pTbl), [T1.B16, T2.B16]
- // Preload AES round keys
- ADD $128, ks
- VLD1.P 48(ks), [K8.B16, K9.B16, K10.B16]
- VMOV K10.B16, KLAST.B16
- TBZ $4, NR, singlesLoop
- VLD1.P 32(ks), [B1.B16, B2.B16]
- VMOV B2.B16, KLAST.B16
- TBZ $3, NR, singlesLoop
- VLD1.P 32(ks), [B3.B16, B4.B16]
- VMOV B4.B16, KLAST.B16
-
-singlesLoop:
- CMP $16, srcPtrLen
- BLT tail
- SUB $16, srcPtrLen
-
- VLD1.P 16(srcPtr), [T0.B16]
- VEOR KLAST.B16, T0.B16, T0.B16
-
- VREV32 CTR.B16, B0.B16
- VADD CTR.S4, INC.S4, CTR.S4
-
- AESE K0.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K1.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K2.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K3.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K4.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K5.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K6.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K7.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K8.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K9.B16, B0.B16
- TBZ $4, NR, singlesLast
- AESMC B0.B16, B0.B16
- AESE K10.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE B1.B16, B0.B16
- TBZ $3, NR, singlesLast
- AESMC B0.B16, B0.B16
- AESE B2.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE B3.B16, B0.B16
-singlesLast:
- VEOR T0.B16, B0.B16, B0.B16
-encReduce:
- VST1.P [B0.B16], 16(dstPtr)
-
- VREV64 B0.B16, B0.B16
- VEOR ACC0.B16, B0.B16, B0.B16
-
- VEXT $8, B0.B16, B0.B16, T0.B16
- VEOR B0.B16, T0.B16, T0.B16
- VPMULL B0.D1, T1.D1, ACC1.Q1
- VPMULL2 B0.D2, T1.D2, ACC0.Q1
- VPMULL T0.D1, T2.D1, ACCM.Q1
-
- reduce()
-
- B singlesLoop
-tail:
- CBZ srcPtrLen, done
-
- VEOR T0.B16, T0.B16, T0.B16
- VEOR T3.B16, T3.B16, T3.B16
- MOVD $0, H1
- SUB $1, H1
- ADD srcPtrLen, srcPtr
-
- TBZ $3, srcPtrLen, ld4
- MOVD.W -8(srcPtr), H0
- VMOV H0, T0.D[0]
- VMOV H1, T3.D[0]
-ld4:
- TBZ $2, srcPtrLen, ld2
- MOVW.W -4(srcPtr), H0
- VEXT $12, T0.B16, ZERO.B16, T0.B16
- VEXT $12, T3.B16, ZERO.B16, T3.B16
- VMOV H0, T0.S[0]
- VMOV H1, T3.S[0]
-ld2:
- TBZ $1, srcPtrLen, ld1
- MOVH.W -2(srcPtr), H0
- VEXT $14, T0.B16, ZERO.B16, T0.B16
- VEXT $14, T3.B16, ZERO.B16, T3.B16
- VMOV H0, T0.H[0]
- VMOV H1, T3.H[0]
-ld1:
- TBZ $0, srcPtrLen, ld0
- MOVB.W -1(srcPtr), H0
- VEXT $15, T0.B16, ZERO.B16, T0.B16
- VEXT $15, T3.B16, ZERO.B16, T3.B16
- VMOV H0, T0.B[0]
- VMOV H1, T3.B[0]
-ld0:
-
- MOVD ZR, srcPtrLen
- VEOR KLAST.B16, T0.B16, T0.B16
- VREV32 CTR.B16, B0.B16
-
- AESE K0.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K1.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K2.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K3.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K4.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K5.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K6.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K7.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K8.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K9.B16, B0.B16
- TBZ $4, NR, tailLast
- AESMC B0.B16, B0.B16
- AESE K10.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE B1.B16, B0.B16
- TBZ $3, NR, tailLast
- AESMC B0.B16, B0.B16
- AESE B2.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE B3.B16, B0.B16
-
-tailLast:
- VEOR T0.B16, B0.B16, B0.B16
- VAND T3.B16, B0.B16, B0.B16
- B encReduce
-
-done:
- VST1 [ACC0.B16], (tPtr)
- RET
-
-// func gcmAesDec(productTable *[256]byte, dst, src []byte, ctr, T *[16]byte, ks []uint32)
-TEXT ·gcmAesDec(SB),NOSPLIT,$0
- MOVD productTable+0(FP), pTbl
- MOVD dst+8(FP), dstPtr
- MOVD src_base+32(FP), srcPtr
- MOVD src_len+40(FP), srcPtrLen
- MOVD ctr+56(FP), ctrPtr
- MOVD T+64(FP), tPtr
- MOVD ks_base+72(FP), ks
- MOVD ks_len+80(FP), NR
-
- MOVD $0xC2, H1
- LSL $56, H1
- MOVD $1, H0
- VMOV H1, POLY.D[0]
- VMOV H0, POLY.D[1]
- VEOR ZERO.B16, ZERO.B16, ZERO.B16
- // Compute NR from len(ks)
- MOVD pTbl, pTblSave
- // Current tag, after AAD
- VLD1 (tPtr), [ACC0.B16]
- VEOR ACC1.B16, ACC1.B16, ACC1.B16
- VEOR ACCM.B16, ACCM.B16, ACCM.B16
- // Prepare initial counter, and the increment vector
- VLD1 (ctrPtr), [CTR.B16]
- VEOR INC.B16, INC.B16, INC.B16
- MOVD $1, H0
- VMOV H0, INC.S[3]
- VREV32 CTR.B16, CTR.B16
- VADD CTR.S4, INC.S4, CTR.S4
-
- MOVD ks, H0
- // For AES-128 round keys are stored in: K0 .. K10, KLAST
- VLD1.P 64(H0), [K0.B16, K1.B16, K2.B16, K3.B16]
- VLD1.P 64(H0), [K4.B16, K5.B16, K6.B16, K7.B16]
- VLD1.P 48(H0), [K8.B16, K9.B16, K10.B16]
- VMOV K10.B16, KLAST.B16
-
- // Skip to <8 blocks loop
- CMP $128, srcPtrLen
- BLT startSingles
- // There are at least 8 blocks to encrypt
- TBZ $4, NR, octetsLoop
-
- // For AES-192 round keys occupy: K0 .. K7, K10, K11, K8, K9, KLAST
- VMOV K8.B16, K10.B16
- VMOV K9.B16, K11.B16
- VMOV KLAST.B16, K8.B16
- VLD1.P 16(H0), [K9.B16]
- VLD1.P 16(H0), [KLAST.B16]
- TBZ $3, NR, octetsLoop
- // For AES-256 round keys occupy: K0 .. K7, K10, K11, mem, mem, K8, K9, KLAST
- VMOV KLAST.B16, K8.B16
- VLD1.P 16(H0), [K9.B16]
- VLD1.P 16(H0), [KLAST.B16]
- ADD $10*16, ks, H0
- MOVD H0, curK
-
-octetsLoop:
- SUB $128, srcPtrLen
-
- VMOV CTR.B16, B0.B16
- VADD B0.S4, INC.S4, B1.S4
- VREV32 B0.B16, B0.B16
- VADD B1.S4, INC.S4, B2.S4
- VREV32 B1.B16, B1.B16
- VADD B2.S4, INC.S4, B3.S4
- VREV32 B2.B16, B2.B16
- VADD B3.S4, INC.S4, B4.S4
- VREV32 B3.B16, B3.B16
- VADD B4.S4, INC.S4, B5.S4
- VREV32 B4.B16, B4.B16
- VADD B5.S4, INC.S4, B6.S4
- VREV32 B5.B16, B5.B16
- VADD B6.S4, INC.S4, B7.S4
- VREV32 B6.B16, B6.B16
- VADD B7.S4, INC.S4, CTR.S4
- VREV32 B7.B16, B7.B16
-
- aesrndx8(K0)
- aesrndx8(K1)
- aesrndx8(K2)
- aesrndx8(K3)
- aesrndx8(K4)
- aesrndx8(K5)
- aesrndx8(K6)
- aesrndx8(K7)
- TBZ $4, NR, octetsFinish
- aesrndx8(K10)
- aesrndx8(K11)
- TBZ $3, NR, octetsFinish
- VLD1.P 32(curK), [T1.B16, T2.B16]
- aesrndx8(T1)
- aesrndx8(T2)
- MOVD H0, curK
-octetsFinish:
- aesrndx8(K8)
- aesrndlastx8(K9)
-
- VEOR KLAST.B16, B0.B16, T1.B16
- VEOR KLAST.B16, B1.B16, T2.B16
- VEOR KLAST.B16, B2.B16, B2.B16
- VEOR KLAST.B16, B3.B16, B3.B16
- VEOR KLAST.B16, B4.B16, B4.B16
- VEOR KLAST.B16, B5.B16, B5.B16
- VEOR KLAST.B16, B6.B16, B6.B16
- VEOR KLAST.B16, B7.B16, B7.B16
-
- VLD1.P 32(srcPtr), [B0.B16, B1.B16]
- VEOR B0.B16, T1.B16, T1.B16
- VEOR B1.B16, T2.B16, T2.B16
- VST1.P [T1.B16, T2.B16], 32(dstPtr)
-
- VLD1.P 32(pTbl), [T1.B16, T2.B16]
- VREV64 B0.B16, B0.B16
- VEOR ACC0.B16, B0.B16, B0.B16
- VEXT $8, B0.B16, B0.B16, T0.B16
- VEOR B0.B16, T0.B16, T0.B16
- VPMULL B0.D1, T1.D1, ACC1.Q1
- VPMULL2 B0.D2, T1.D2, ACC0.Q1
- VPMULL T0.D1, T2.D1, ACCM.Q1
- mulRound(B1)
-
- VLD1.P 32(srcPtr), [B0.B16, B1.B16]
- VEOR B2.B16, B0.B16, T1.B16
- VEOR B3.B16, B1.B16, T2.B16
- VST1.P [T1.B16, T2.B16], 32(dstPtr)
- mulRound(B0)
- mulRound(B1)
-
- VLD1.P 32(srcPtr), [B0.B16, B1.B16]
- VEOR B4.B16, B0.B16, T1.B16
- VEOR B5.B16, B1.B16, T2.B16
- VST1.P [T1.B16, T2.B16], 32(dstPtr)
- mulRound(B0)
- mulRound(B1)
-
- VLD1.P 32(srcPtr), [B0.B16, B1.B16]
- VEOR B6.B16, B0.B16, T1.B16
- VEOR B7.B16, B1.B16, T2.B16
- VST1.P [T1.B16, T2.B16], 32(dstPtr)
- mulRound(B0)
- mulRound(B1)
-
- MOVD pTblSave, pTbl
- reduce()
-
- CMP $128, srcPtrLen
- BGE octetsLoop
-
-startSingles:
- CBZ srcPtrLen, done
- ADD $14*16, pTbl
- // Preload H and its Karatsuba precomp
- VLD1.P (pTbl), [T1.B16, T2.B16]
- // Preload AES round keys
- ADD $128, ks
- VLD1.P 48(ks), [K8.B16, K9.B16, K10.B16]
- VMOV K10.B16, KLAST.B16
- TBZ $4, NR, singlesLoop
- VLD1.P 32(ks), [B1.B16, B2.B16]
- VMOV B2.B16, KLAST.B16
- TBZ $3, NR, singlesLoop
- VLD1.P 32(ks), [B3.B16, B4.B16]
- VMOV B4.B16, KLAST.B16
-
-singlesLoop:
- CMP $16, srcPtrLen
- BLT tail
- SUB $16, srcPtrLen
-
- VLD1.P 16(srcPtr), [T0.B16]
- VREV64 T0.B16, B5.B16
- VEOR KLAST.B16, T0.B16, T0.B16
-
- VREV32 CTR.B16, B0.B16
- VADD CTR.S4, INC.S4, CTR.S4
-
- AESE K0.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K1.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K2.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K3.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K4.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K5.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K6.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K7.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K8.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K9.B16, B0.B16
- TBZ $4, NR, singlesLast
- AESMC B0.B16, B0.B16
- AESE K10.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE B1.B16, B0.B16
- TBZ $3, NR, singlesLast
- AESMC B0.B16, B0.B16
- AESE B2.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE B3.B16, B0.B16
-singlesLast:
- VEOR T0.B16, B0.B16, B0.B16
-
- VST1.P [B0.B16], 16(dstPtr)
-
- VEOR ACC0.B16, B5.B16, B5.B16
- VEXT $8, B5.B16, B5.B16, T0.B16
- VEOR B5.B16, T0.B16, T0.B16
- VPMULL B5.D1, T1.D1, ACC1.Q1
- VPMULL2 B5.D2, T1.D2, ACC0.Q1
- VPMULL T0.D1, T2.D1, ACCM.Q1
- reduce()
-
- B singlesLoop
-tail:
- CBZ srcPtrLen, done
-
- VREV32 CTR.B16, B0.B16
- VADD CTR.S4, INC.S4, CTR.S4
-
- AESE K0.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K1.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K2.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K3.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K4.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K5.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K6.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K7.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K8.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE K9.B16, B0.B16
- TBZ $4, NR, tailLast
- AESMC B0.B16, B0.B16
- AESE K10.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE B1.B16, B0.B16
- TBZ $3, NR, tailLast
- AESMC B0.B16, B0.B16
- AESE B2.B16, B0.B16
- AESMC B0.B16, B0.B16
- AESE B3.B16, B0.B16
-tailLast:
- VEOR KLAST.B16, B0.B16, B0.B16
-
- // Assuming it is safe to load past dstPtr due to the presence of the tag
- VLD1 (srcPtr), [B5.B16]
-
- VEOR B5.B16, B0.B16, B0.B16
-
- VEOR T3.B16, T3.B16, T3.B16
- MOVD $0, H1
- SUB $1, H1
-
- TBZ $3, srcPtrLen, ld4
- VMOV B0.D[0], H0
- MOVD.P H0, 8(dstPtr)
- VMOV H1, T3.D[0]
- VEXT $8, ZERO.B16, B0.B16, B0.B16
-ld4:
- TBZ $2, srcPtrLen, ld2
- VMOV B0.S[0], H0
- MOVW.P H0, 4(dstPtr)
- VEXT $12, T3.B16, ZERO.B16, T3.B16
- VMOV H1, T3.S[0]
- VEXT $4, ZERO.B16, B0.B16, B0.B16
-ld2:
- TBZ $1, srcPtrLen, ld1
- VMOV B0.H[0], H0
- MOVH.P H0, 2(dstPtr)
- VEXT $14, T3.B16, ZERO.B16, T3.B16
- VMOV H1, T3.H[0]
- VEXT $2, ZERO.B16, B0.B16, B0.B16
-ld1:
- TBZ $0, srcPtrLen, ld0
- VMOV B0.B[0], H0
- MOVB.P H0, 1(dstPtr)
- VEXT $15, T3.B16, ZERO.B16, T3.B16
- VMOV H1, T3.B[0]
-ld0:
-
- VAND T3.B16, B5.B16, B5.B16
- VREV64 B5.B16, B5.B16
-
- VEOR ACC0.B16, B5.B16, B5.B16
- VEXT $8, B5.B16, B5.B16, T0.B16
- VEOR B5.B16, T0.B16, T0.B16
- VPMULL B5.D1, T1.D1, ACC1.Q1
- VPMULL2 B5.D2, T1.D2, ACC0.Q1
- VPMULL T0.D1, T2.D1, ACCM.Q1
- reduce()
-done:
- VST1 [ACC0.B16], (tPtr)
-
- RET
diff --git a/contrib/go/_std_1.20/src/crypto/aes/ya.make b/contrib/go/_std_1.20/src/crypto/aes/ya.make
deleted file mode 100644
index c2ae4ddeb2..0000000000
--- a/contrib/go/_std_1.20/src/crypto/aes/ya.make
+++ /dev/null
@@ -1,26 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- aes_gcm.go
- block.go
- cipher.go
- cipher_asm.go
- const.go
- modes.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- asm_arm64.s
- gcm_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- asm_amd64.s
- gcm_amd64.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/cipher/ya.make b/contrib/go/_std_1.20/src/crypto/cipher/ya.make
deleted file mode 100644
index 176c194ebb..0000000000
--- a/contrib/go/_std_1.20/src/crypto/cipher/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- cbc.go
- cfb.go
- cipher.go
- ctr.go
- gcm.go
- io.go
- ofb.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/des/ya.make b/contrib/go/_std_1.20/src/crypto/des/ya.make
deleted file mode 100644
index 6a390c6a2c..0000000000
--- a/contrib/go/_std_1.20/src/crypto/des/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- block.go
- cipher.go
- const.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/dsa/ya.make b/contrib/go/_std_1.20/src/crypto/dsa/ya.make
deleted file mode 100644
index 47b1766da4..0000000000
--- a/contrib/go/_std_1.20/src/crypto/dsa/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- dsa.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/ecdh/ecdh.go b/contrib/go/_std_1.20/src/crypto/ecdh/ecdh.go
deleted file mode 100644
index 74420559b5..0000000000
--- a/contrib/go/_std_1.20/src/crypto/ecdh/ecdh.go
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2022 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 ecdh implements Elliptic Curve Diffie-Hellman over
-// NIST curves and Curve25519.
-package ecdh
-
-import (
- "crypto"
- "crypto/internal/boring"
- "crypto/subtle"
- "errors"
- "io"
- "sync"
-)
-
-type Curve interface {
- // GenerateKey generates a new PrivateKey from rand.
- GenerateKey(rand io.Reader) (*PrivateKey, error)
-
- // NewPrivateKey checks that key is valid and returns a PrivateKey.
- //
- // For NIST curves, this follows SEC 1, Version 2.0, Section 2.3.6, which
- // amounts to decoding the bytes as a fixed length big endian integer and
- // checking that the result is lower than the order of the curve. The zero
- // private key is also rejected, as the encoding of the corresponding public
- // key would be irregular.
- //
- // For X25519, this only checks the scalar length.
- NewPrivateKey(key []byte) (*PrivateKey, error)
-
- // NewPublicKey checks that key is valid and returns a PublicKey.
- //
- // For NIST curves, this decodes an uncompressed point according to SEC 1,
- // Version 2.0, Section 2.3.4. Compressed encodings and the point at
- // infinity are rejected.
- //
- // For X25519, this only checks the u-coordinate length. Adversarially
- // selected public keys can cause ECDH to return an error.
- NewPublicKey(key []byte) (*PublicKey, error)
-
- // ecdh performs a ECDH exchange and returns the shared secret. It's exposed
- // as the PrivateKey.ECDH method.
- //
- // The private method also allow us to expand the ECDH interface with more
- // methods in the future without breaking backwards compatibility.
- ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error)
-
- // privateKeyToPublicKey converts a PrivateKey to a PublicKey. It's exposed
- // as the PrivateKey.PublicKey method.
- //
- // This method always succeeds: for X25519, the zero key can't be
- // constructed due to clamping; for NIST curves, it is rejected by
- // NewPrivateKey.
- privateKeyToPublicKey(*PrivateKey) *PublicKey
-}
-
-// PublicKey is an ECDH public key, usually a peer's ECDH share sent over the wire.
-//
-// These keys can be parsed with [crypto/x509.ParsePKIXPublicKey] and encoded
-// with [crypto/x509.MarshalPKIXPublicKey]. For NIST curves, they then need to
-// be converted with [crypto/ecdsa.PublicKey.ECDH] after parsing.
-type PublicKey struct {
- curve Curve
- publicKey []byte
- boring *boring.PublicKeyECDH
-}
-
-// Bytes returns a copy of the encoding of the public key.
-func (k *PublicKey) Bytes() []byte {
- // Copy the public key to a fixed size buffer that can get allocated on the
- // caller's stack after inlining.
- var buf [133]byte
- return append(buf[:0], k.publicKey...)
-}
-
-// Equal returns whether x represents the same public key as k.
-//
-// Note that there can be equivalent public keys with different encodings which
-// would return false from this check but behave the same way as inputs to ECDH.
-//
-// This check is performed in constant time as long as the key types and their
-// curve match.
-func (k *PublicKey) Equal(x crypto.PublicKey) bool {
- xx, ok := x.(*PublicKey)
- if !ok {
- return false
- }
- return k.curve == xx.curve &&
- subtle.ConstantTimeCompare(k.publicKey, xx.publicKey) == 1
-}
-
-func (k *PublicKey) Curve() Curve {
- return k.curve
-}
-
-// PrivateKey is an ECDH private key, usually kept secret.
-//
-// These keys can be parsed with [crypto/x509.ParsePKCS8PrivateKey] and encoded
-// with [crypto/x509.MarshalPKCS8PrivateKey]. For NIST curves, they then need to
-// be converted with [crypto/ecdsa.PrivateKey.ECDH] after parsing.
-type PrivateKey struct {
- curve Curve
- privateKey []byte
- boring *boring.PrivateKeyECDH
- // publicKey is set under publicKeyOnce, to allow loading private keys with
- // NewPrivateKey without having to perform a scalar multiplication.
- publicKey *PublicKey
- publicKeyOnce sync.Once
-}
-
-// ECDH performs a ECDH exchange and returns the shared secret. The PrivateKey
-// and PublicKey must use the same curve.
-//
-// For NIST curves, this performs ECDH as specified in SEC 1, Version 2.0,
-// Section 3.3.1, and returns the x-coordinate encoded according to SEC 1,
-// Version 2.0, Section 2.3.5. The result is never the point at infinity.
-//
-// For X25519, this performs ECDH as specified in RFC 7748, Section 6.1. If
-// the result is the all-zero value, ECDH returns an error.
-func (k *PrivateKey) ECDH(remote *PublicKey) ([]byte, error) {
- if k.curve != remote.curve {
- return nil, errors.New("crypto/ecdh: private key and public key curves do not match")
- }
- return k.curve.ecdh(k, remote)
-}
-
-// Bytes returns a copy of the encoding of the private key.
-func (k *PrivateKey) Bytes() []byte {
- // Copy the private key to a fixed size buffer that can get allocated on the
- // caller's stack after inlining.
- var buf [66]byte
- return append(buf[:0], k.privateKey...)
-}
-
-// Equal returns whether x represents the same private key as k.
-//
-// Note that there can be equivalent private keys with different encodings which
-// would return false from this check but behave the same way as inputs to ECDH.
-//
-// This check is performed in constant time as long as the key types and their
-// curve match.
-func (k *PrivateKey) Equal(x crypto.PrivateKey) bool {
- xx, ok := x.(*PrivateKey)
- if !ok {
- return false
- }
- return k.curve == xx.curve &&
- subtle.ConstantTimeCompare(k.privateKey, xx.privateKey) == 1
-}
-
-func (k *PrivateKey) Curve() Curve {
- return k.curve
-}
-
-func (k *PrivateKey) PublicKey() *PublicKey {
- k.publicKeyOnce.Do(func() {
- if k.boring != nil {
- // Because we already checked in NewPrivateKey that the key is valid,
- // there should not be any possible errors from BoringCrypto,
- // so we turn the error into a panic.
- // (We can't return it anyhow.)
- kpub, err := k.boring.PublicKey()
- if err != nil {
- panic("boringcrypto: " + err.Error())
- }
- k.publicKey = &PublicKey{
- curve: k.curve,
- publicKey: kpub.Bytes(),
- boring: kpub,
- }
- } else {
- k.publicKey = k.curve.privateKeyToPublicKey(k)
- }
- })
- return k.publicKey
-}
-
-// Public implements the implicit interface of all standard library private
-// keys. See the docs of crypto.PrivateKey.
-func (k *PrivateKey) Public() crypto.PublicKey {
- return k.PublicKey()
-}
diff --git a/contrib/go/_std_1.20/src/crypto/ecdh/ya.make b/contrib/go/_std_1.20/src/crypto/ecdh/ya.make
deleted file mode 100644
index 996f40b76b..0000000000
--- a/contrib/go/_std_1.20/src/crypto/ecdh/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- ecdh.go
- nist.go
- x25519.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/ecdsa/ecdsa.go b/contrib/go/_std_1.20/src/crypto/ecdsa/ecdsa.go
deleted file mode 100644
index 03a9a72ddd..0000000000
--- a/contrib/go/_std_1.20/src/crypto/ecdsa/ecdsa.go
+++ /dev/null
@@ -1,660 +0,0 @@
-// Copyright 2011 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 ecdsa implements the Elliptic Curve Digital Signature Algorithm, as
-// defined in FIPS 186-4 and SEC 1, Version 2.0.
-//
-// Signatures generated by this package are not deterministic, but entropy is
-// mixed with the private key and the message, achieving the same level of
-// security in case of randomness source failure.
-package ecdsa
-
-// [FIPS 186-4] references ANSI X9.62-2005 for the bulk of the ECDSA algorithm.
-// That standard is not freely available, which is a problem in an open source
-// implementation, because not only the implementer, but also any maintainer,
-// contributor, reviewer, auditor, and learner needs access to it. Instead, this
-// package references and follows the equivalent [SEC 1, Version 2.0].
-//
-// [FIPS 186-4]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
-// [SEC 1, Version 2.0]: https://www.secg.org/sec1-v2.pdf
-
-import (
- "bytes"
- "crypto"
- "crypto/aes"
- "crypto/cipher"
- "crypto/ecdh"
- "crypto/elliptic"
- "crypto/internal/bigmod"
- "crypto/internal/boring"
- "crypto/internal/boring/bbig"
- "crypto/internal/nistec"
- "crypto/internal/randutil"
- "crypto/sha512"
- "crypto/subtle"
- "errors"
- "io"
- "math/big"
- "sync"
-
- "golang.org/x/crypto/cryptobyte"
- "golang.org/x/crypto/cryptobyte/asn1"
-)
-
-// PublicKey represents an ECDSA public key.
-type PublicKey struct {
- elliptic.Curve
- X, Y *big.Int
-}
-
-// Any methods implemented on PublicKey might need to also be implemented on
-// PrivateKey, as the latter embeds the former and will expose its methods.
-
-// ECDH returns k as a [ecdh.PublicKey]. It returns an error if the key is
-// invalid according to the definition of [ecdh.Curve.NewPublicKey], or if the
-// Curve is not supported by crypto/ecdh.
-func (k *PublicKey) ECDH() (*ecdh.PublicKey, error) {
- c := curveToECDH(k.Curve)
- if c == nil {
- return nil, errors.New("ecdsa: unsupported curve by crypto/ecdh")
- }
- if !k.Curve.IsOnCurve(k.X, k.Y) {
- return nil, errors.New("ecdsa: invalid public key")
- }
- return c.NewPublicKey(elliptic.Marshal(k.Curve, k.X, k.Y))
-}
-
-// Equal reports whether pub and x have the same value.
-//
-// Two keys are only considered to have the same value if they have the same Curve value.
-// Note that for example elliptic.P256() and elliptic.P256().Params() are different
-// values, as the latter is a generic not constant time implementation.
-func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
- xx, ok := x.(*PublicKey)
- if !ok {
- return false
- }
- return bigIntEqual(pub.X, xx.X) && bigIntEqual(pub.Y, xx.Y) &&
- // Standard library Curve implementations are singletons, so this check
- // will work for those. Other Curves might be equivalent even if not
- // singletons, but there is no definitive way to check for that, and
- // better to err on the side of safety.
- pub.Curve == xx.Curve
-}
-
-// PrivateKey represents an ECDSA private key.
-type PrivateKey struct {
- PublicKey
- D *big.Int
-}
-
-// ECDH returns k as a [ecdh.PrivateKey]. It returns an error if the key is
-// invalid according to the definition of [ecdh.Curve.NewPrivateKey], or if the
-// Curve is not supported by crypto/ecdh.
-func (k *PrivateKey) ECDH() (*ecdh.PrivateKey, error) {
- c := curveToECDH(k.Curve)
- if c == nil {
- return nil, errors.New("ecdsa: unsupported curve by crypto/ecdh")
- }
- size := (k.Curve.Params().N.BitLen() + 7) / 8
- if k.D.BitLen() > size*8 {
- return nil, errors.New("ecdsa: invalid private key")
- }
- return c.NewPrivateKey(k.D.FillBytes(make([]byte, size)))
-}
-
-func curveToECDH(c elliptic.Curve) ecdh.Curve {
- switch c {
- case elliptic.P256():
- return ecdh.P256()
- case elliptic.P384():
- return ecdh.P384()
- case elliptic.P521():
- return ecdh.P521()
- default:
- return nil
- }
-}
-
-// Public returns the public key corresponding to priv.
-func (priv *PrivateKey) Public() crypto.PublicKey {
- return &priv.PublicKey
-}
-
-// Equal reports whether priv and x have the same value.
-//
-// See PublicKey.Equal for details on how Curve is compared.
-func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
- xx, ok := x.(*PrivateKey)
- if !ok {
- return false
- }
- return priv.PublicKey.Equal(&xx.PublicKey) && bigIntEqual(priv.D, xx.D)
-}
-
-// bigIntEqual reports whether a and b are equal leaking only their bit length
-// through timing side-channels.
-func bigIntEqual(a, b *big.Int) bool {
- return subtle.ConstantTimeCompare(a.Bytes(), b.Bytes()) == 1
-}
-
-// Sign signs digest with priv, reading randomness from rand. The opts argument
-// is not currently used but, in keeping with the crypto.Signer interface,
-// should be the hash function used to digest the message.
-//
-// This method implements crypto.Signer, which is an interface to support keys
-// where the private part is kept in, for example, a hardware module. Common
-// uses can use the SignASN1 function in this package directly.
-func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
- return SignASN1(rand, priv, digest)
-}
-
-// GenerateKey generates a public and private key pair.
-func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
- randutil.MaybeReadByte(rand)
-
- if boring.Enabled && rand == boring.RandReader {
- x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name)
- if err != nil {
- return nil, err
- }
- return &PrivateKey{PublicKey: PublicKey{Curve: c, X: bbig.Dec(x), Y: bbig.Dec(y)}, D: bbig.Dec(d)}, nil
- }
- boring.UnreachableExceptTests()
-
- switch c.Params() {
- case elliptic.P224().Params():
- return generateNISTEC(p224(), rand)
- case elliptic.P256().Params():
- return generateNISTEC(p256(), rand)
- case elliptic.P384().Params():
- return generateNISTEC(p384(), rand)
- case elliptic.P521().Params():
- return generateNISTEC(p521(), rand)
- default:
- return generateLegacy(c, rand)
- }
-}
-
-func generateNISTEC[Point nistPoint[Point]](c *nistCurve[Point], rand io.Reader) (*PrivateKey, error) {
- k, Q, err := randomPoint(c, rand)
- if err != nil {
- return nil, err
- }
-
- priv := new(PrivateKey)
- priv.PublicKey.Curve = c.curve
- priv.D = new(big.Int).SetBytes(k.Bytes(c.N))
- priv.PublicKey.X, priv.PublicKey.Y, err = c.pointToAffine(Q)
- if err != nil {
- return nil, err
- }
- return priv, nil
-}
-
-// randomPoint returns a random scalar and the corresponding point using the
-// procedure given in FIPS 186-4, Appendix B.5.2 (rejection sampling).
-func randomPoint[Point nistPoint[Point]](c *nistCurve[Point], rand io.Reader) (k *bigmod.Nat, p Point, err error) {
- k = bigmod.NewNat()
- for {
- b := make([]byte, c.N.Size())
- if _, err = io.ReadFull(rand, b); err != nil {
- return
- }
-
- // Mask off any excess bits to increase the chance of hitting a value in
- // (0, N). These are the most dangerous lines in the package and maybe in
- // the library: a single bit of bias in the selection of nonces would likely
- // lead to key recovery, but no tests would fail. Look but DO NOT TOUCH.
- if excess := len(b)*8 - c.N.BitLen(); excess > 0 {
- // Just to be safe, assert that this only happens for the one curve that
- // doesn't have a round number of bits.
- if excess != 0 && c.curve.Params().Name != "P-521" {
- panic("ecdsa: internal error: unexpectedly masking off bits")
- }
- b[0] >>= excess
- }
-
- // FIPS 186-4 makes us check k <= N - 2 and then add one.
- // Checking 0 < k <= N - 1 is strictly equivalent.
- // None of this matters anyway because the chance of selecting
- // zero is cryptographically negligible.
- if _, err = k.SetBytes(b, c.N); err == nil && k.IsZero() == 0 {
- break
- }
-
- if testingOnlyRejectionSamplingLooped != nil {
- testingOnlyRejectionSamplingLooped()
- }
- }
-
- p, err = c.newPoint().ScalarBaseMult(k.Bytes(c.N))
- return
-}
-
-// testingOnlyRejectionSamplingLooped is called when rejection sampling in
-// randomPoint rejects a candidate for being higher than the modulus.
-var testingOnlyRejectionSamplingLooped func()
-
-// errNoAsm is returned by signAsm and verifyAsm when the assembly
-// implementation is not available.
-var errNoAsm = errors.New("no assembly implementation available")
-
-// SignASN1 signs a hash (which should be the result of hashing a larger message)
-// using the private key, priv. If the hash is longer than the bit-length of the
-// private key's curve order, the hash will be truncated to that length. It
-// returns the ASN.1 encoded signature.
-func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
- randutil.MaybeReadByte(rand)
-
- if boring.Enabled && rand == boring.RandReader {
- b, err := boringPrivateKey(priv)
- if err != nil {
- return nil, err
- }
- return boring.SignMarshalECDSA(b, hash)
- }
- boring.UnreachableExceptTests()
-
- csprng, err := mixedCSPRNG(rand, priv, hash)
- if err != nil {
- return nil, err
- }
-
- if sig, err := signAsm(priv, csprng, hash); err != errNoAsm {
- return sig, err
- }
-
- switch priv.Curve.Params() {
- case elliptic.P224().Params():
- return signNISTEC(p224(), priv, csprng, hash)
- case elliptic.P256().Params():
- return signNISTEC(p256(), priv, csprng, hash)
- case elliptic.P384().Params():
- return signNISTEC(p384(), priv, csprng, hash)
- case elliptic.P521().Params():
- return signNISTEC(p521(), priv, csprng, hash)
- default:
- return signLegacy(priv, csprng, hash)
- }
-}
-
-func signNISTEC[Point nistPoint[Point]](c *nistCurve[Point], priv *PrivateKey, csprng io.Reader, hash []byte) (sig []byte, err error) {
- // SEC 1, Version 2.0, Section 4.1.3
-
- k, R, err := randomPoint(c, csprng)
- if err != nil {
- return nil, err
- }
-
- // kInv = k⁻¹
- kInv := bigmod.NewNat()
- inverse(c, kInv, k)
-
- Rx, err := R.BytesX()
- if err != nil {
- return nil, err
- }
- r, err := bigmod.NewNat().SetOverflowingBytes(Rx, c.N)
- if err != nil {
- return nil, err
- }
-
- // The spec wants us to retry here, but the chance of hitting this condition
- // on a large prime-order group like the NIST curves we support is
- // cryptographically negligible. If we hit it, something is awfully wrong.
- if r.IsZero() == 1 {
- return nil, errors.New("ecdsa: internal error: r is zero")
- }
-
- e := bigmod.NewNat()
- hashToNat(c, e, hash)
-
- s, err := bigmod.NewNat().SetBytes(priv.D.Bytes(), c.N)
- if err != nil {
- return nil, err
- }
- s.Mul(r, c.N)
- s.Add(e, c.N)
- s.Mul(kInv, c.N)
-
- // Again, the chance of this happening is cryptographically negligible.
- if s.IsZero() == 1 {
- return nil, errors.New("ecdsa: internal error: s is zero")
- }
-
- return encodeSignature(r.Bytes(c.N), s.Bytes(c.N))
-}
-
-func encodeSignature(r, s []byte) ([]byte, error) {
- var b cryptobyte.Builder
- b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
- addASN1IntBytes(b, r)
- addASN1IntBytes(b, s)
- })
- return b.Bytes()
-}
-
-// addASN1IntBytes encodes in ASN.1 a positive integer represented as
-// a big-endian byte slice with zero or more leading zeroes.
-func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) {
- for len(bytes) > 0 && bytes[0] == 0 {
- bytes = bytes[1:]
- }
- if len(bytes) == 0 {
- b.SetError(errors.New("invalid integer"))
- return
- }
- b.AddASN1(asn1.INTEGER, func(c *cryptobyte.Builder) {
- if bytes[0]&0x80 != 0 {
- c.AddUint8(0)
- }
- c.AddBytes(bytes)
- })
-}
-
-// inverse sets kInv to the inverse of k modulo the order of the curve.
-func inverse[Point nistPoint[Point]](c *nistCurve[Point], kInv, k *bigmod.Nat) {
- if c.curve.Params().Name == "P-256" {
- kBytes, err := nistec.P256OrdInverse(k.Bytes(c.N))
- // Some platforms don't implement P256OrdInverse, and always return an error.
- if err == nil {
- _, err := kInv.SetBytes(kBytes, c.N)
- if err != nil {
- panic("ecdsa: internal error: P256OrdInverse produced an invalid value")
- }
- return
- }
- }
-
- // Calculate the inverse of s in GF(N) using Fermat's method
- // (exponentiation modulo P - 2, per Euler's theorem)
- kInv.Exp(k, c.nMinus2, c.N)
-}
-
-// hashToNat sets e to the left-most bits of hash, according to
-// SEC 1, Section 4.1.3, point 5 and Section 4.1.4, point 3.
-func hashToNat[Point nistPoint[Point]](c *nistCurve[Point], e *bigmod.Nat, hash []byte) {
- // ECDSA asks us to take the left-most log2(N) bits of hash, and use them as
- // an integer modulo N. This is the absolute worst of all worlds: we still
- // have to reduce, because the result might still overflow N, but to take
- // the left-most bits for P-521 we have to do a right shift.
- if size := c.N.Size(); len(hash) >= size {
- hash = hash[:size]
- if excess := len(hash)*8 - c.N.BitLen(); excess > 0 {
- hash = bytes.Clone(hash)
- for i := len(hash) - 1; i >= 0; i-- {
- hash[i] >>= excess
- if i > 0 {
- hash[i] |= hash[i-1] << (8 - excess)
- }
- }
- }
- }
- _, err := e.SetOverflowingBytes(hash, c.N)
- if err != nil {
- panic("ecdsa: internal error: truncated hash is too long")
- }
-}
-
-// mixedCSPRNG returns a CSPRNG that mixes entropy from rand with the message
-// and the private key, to protect the key in case rand fails. This is
-// equivalent in security to RFC 6979 deterministic nonce generation, but still
-// produces randomized signatures.
-func mixedCSPRNG(rand io.Reader, priv *PrivateKey, hash []byte) (io.Reader, error) {
- // This implementation derives the nonce from an AES-CTR CSPRNG keyed by:
- //
- // SHA2-512(priv.D || entropy || hash)[:32]
- //
- // The CSPRNG key is indifferentiable from a random oracle as shown in
- // [Coron], the AES-CTR stream is indifferentiable from a random oracle
- // under standard cryptographic assumptions (see [Larsson] for examples).
- //
- // [Coron]: https://cs.nyu.edu/~dodis/ps/merkle.pdf
- // [Larsson]: https://web.archive.org/web/20040719170906/https://www.nada.kth.se/kurser/kth/2D1441/semteo03/lecturenotes/assump.pdf
-
- // Get 256 bits of entropy from rand.
- entropy := make([]byte, 32)
- if _, err := io.ReadFull(rand, entropy); err != nil {
- return nil, err
- }
-
- // Initialize an SHA-512 hash context; digest...
- md := sha512.New()
- md.Write(priv.D.Bytes()) // the private key,
- md.Write(entropy) // the entropy,
- md.Write(hash) // and the input hash;
- key := md.Sum(nil)[:32] // and compute ChopMD-256(SHA-512),
- // which is an indifferentiable MAC.
-
- // Create an AES-CTR instance to use as a CSPRNG.
- block, err := aes.NewCipher(key)
- if err != nil {
- return nil, err
- }
-
- // Create a CSPRNG that xors a stream of zeros with
- // the output of the AES-CTR instance.
- const aesIV = "IV for ECDSA CTR"
- return &cipher.StreamReader{
- R: zeroReader,
- S: cipher.NewCTR(block, []byte(aesIV)),
- }, nil
-}
-
-type zr struct{}
-
-var zeroReader = zr{}
-
-// Read replaces the contents of dst with zeros. It is safe for concurrent use.
-func (zr) Read(dst []byte) (n int, err error) {
- for i := range dst {
- dst[i] = 0
- }
- return len(dst), nil
-}
-
-// VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the
-// public key, pub. Its return value records whether the signature is valid.
-func VerifyASN1(pub *PublicKey, hash, sig []byte) bool {
- if boring.Enabled {
- key, err := boringPublicKey(pub)
- if err != nil {
- return false
- }
- return boring.VerifyECDSA(key, hash, sig)
- }
- boring.UnreachableExceptTests()
-
- if err := verifyAsm(pub, hash, sig); err != errNoAsm {
- return err == nil
- }
-
- switch pub.Curve.Params() {
- case elliptic.P224().Params():
- return verifyNISTEC(p224(), pub, hash, sig)
- case elliptic.P256().Params():
- return verifyNISTEC(p256(), pub, hash, sig)
- case elliptic.P384().Params():
- return verifyNISTEC(p384(), pub, hash, sig)
- case elliptic.P521().Params():
- return verifyNISTEC(p521(), pub, hash, sig)
- default:
- return verifyLegacy(pub, hash, sig)
- }
-}
-
-func verifyNISTEC[Point nistPoint[Point]](c *nistCurve[Point], pub *PublicKey, hash, sig []byte) bool {
- rBytes, sBytes, err := parseSignature(sig)
- if err != nil {
- return false
- }
-
- Q, err := c.pointFromAffine(pub.X, pub.Y)
- if err != nil {
- return false
- }
-
- // SEC 1, Version 2.0, Section 4.1.4
-
- r, err := bigmod.NewNat().SetBytes(rBytes, c.N)
- if err != nil || r.IsZero() == 1 {
- return false
- }
- s, err := bigmod.NewNat().SetBytes(sBytes, c.N)
- if err != nil || s.IsZero() == 1 {
- return false
- }
-
- e := bigmod.NewNat()
- hashToNat(c, e, hash)
-
- // w = s⁻¹
- w := bigmod.NewNat()
- inverse(c, w, s)
-
- // p₁ = [e * s⁻¹]G
- p1, err := c.newPoint().ScalarBaseMult(e.Mul(w, c.N).Bytes(c.N))
- if err != nil {
- return false
- }
- // p₂ = [r * s⁻¹]Q
- p2, err := Q.ScalarMult(Q, w.Mul(r, c.N).Bytes(c.N))
- if err != nil {
- return false
- }
- // BytesX returns an error for the point at infinity.
- Rx, err := p1.Add(p1, p2).BytesX()
- if err != nil {
- return false
- }
-
- v, err := bigmod.NewNat().SetOverflowingBytes(Rx, c.N)
- if err != nil {
- return false
- }
-
- return v.Equal(r) == 1
-}
-
-func parseSignature(sig []byte) (r, s []byte, err error) {
- var inner cryptobyte.String
- input := cryptobyte.String(sig)
- if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
- !input.Empty() ||
- !inner.ReadASN1Integer(&r) ||
- !inner.ReadASN1Integer(&s) ||
- !inner.Empty() {
- return nil, nil, errors.New("invalid ASN.1")
- }
- return r, s, nil
-}
-
-type nistCurve[Point nistPoint[Point]] struct {
- newPoint func() Point
- curve elliptic.Curve
- N *bigmod.Modulus
- nMinus2 []byte
-}
-
-// nistPoint is a generic constraint for the nistec Point types.
-type nistPoint[T any] interface {
- Bytes() []byte
- BytesX() ([]byte, error)
- SetBytes([]byte) (T, error)
- Add(T, T) T
- ScalarMult(T, []byte) (T, error)
- ScalarBaseMult([]byte) (T, error)
-}
-
-// pointFromAffine is used to convert the PublicKey to a nistec Point.
-func (curve *nistCurve[Point]) pointFromAffine(x, y *big.Int) (p Point, err error) {
- bitSize := curve.curve.Params().BitSize
- // Reject values that would not get correctly encoded.
- if x.Sign() < 0 || y.Sign() < 0 {
- return p, errors.New("negative coordinate")
- }
- if x.BitLen() > bitSize || y.BitLen() > bitSize {
- return p, errors.New("overflowing coordinate")
- }
- // Encode the coordinates and let SetBytes reject invalid points.
- byteLen := (bitSize + 7) / 8
- buf := make([]byte, 1+2*byteLen)
- buf[0] = 4 // uncompressed point
- x.FillBytes(buf[1 : 1+byteLen])
- y.FillBytes(buf[1+byteLen : 1+2*byteLen])
- return curve.newPoint().SetBytes(buf)
-}
-
-// pointToAffine is used to convert a nistec Point to a PublicKey.
-func (curve *nistCurve[Point]) pointToAffine(p Point) (x, y *big.Int, err error) {
- out := p.Bytes()
- if len(out) == 1 && out[0] == 0 {
- // This is the encoding of the point at infinity.
- return nil, nil, errors.New("ecdsa: public key point is the infinity")
- }
- byteLen := (curve.curve.Params().BitSize + 7) / 8
- x = new(big.Int).SetBytes(out[1 : 1+byteLen])
- y = new(big.Int).SetBytes(out[1+byteLen:])
- return x, y, nil
-}
-
-var p224Once sync.Once
-var _p224 *nistCurve[*nistec.P224Point]
-
-func p224() *nistCurve[*nistec.P224Point] {
- p224Once.Do(func() {
- _p224 = &nistCurve[*nistec.P224Point]{
- newPoint: func() *nistec.P224Point { return nistec.NewP224Point() },
- }
- precomputeParams(_p224, elliptic.P224())
- })
- return _p224
-}
-
-var p256Once sync.Once
-var _p256 *nistCurve[*nistec.P256Point]
-
-func p256() *nistCurve[*nistec.P256Point] {
- p256Once.Do(func() {
- _p256 = &nistCurve[*nistec.P256Point]{
- newPoint: func() *nistec.P256Point { return nistec.NewP256Point() },
- }
- precomputeParams(_p256, elliptic.P256())
- })
- return _p256
-}
-
-var p384Once sync.Once
-var _p384 *nistCurve[*nistec.P384Point]
-
-func p384() *nistCurve[*nistec.P384Point] {
- p384Once.Do(func() {
- _p384 = &nistCurve[*nistec.P384Point]{
- newPoint: func() *nistec.P384Point { return nistec.NewP384Point() },
- }
- precomputeParams(_p384, elliptic.P384())
- })
- return _p384
-}
-
-var p521Once sync.Once
-var _p521 *nistCurve[*nistec.P521Point]
-
-func p521() *nistCurve[*nistec.P521Point] {
- p521Once.Do(func() {
- _p521 = &nistCurve[*nistec.P521Point]{
- newPoint: func() *nistec.P521Point { return nistec.NewP521Point() },
- }
- precomputeParams(_p521, elliptic.P521())
- })
- return _p521
-}
-
-func precomputeParams[Point nistPoint[Point]](c *nistCurve[Point], curve elliptic.Curve) {
- params := curve.Params()
- c.curve = curve
- c.N = bigmod.NewModulusFromBig(params.N)
- c.nMinus2 = new(big.Int).Sub(params.N, big.NewInt(2)).Bytes()
-}
diff --git a/contrib/go/_std_1.20/src/crypto/ecdsa/ya.make b/contrib/go/_std_1.20/src/crypto/ecdsa/ya.make
deleted file mode 100644
index bbafb07580..0000000000
--- a/contrib/go/_std_1.20/src/crypto/ecdsa/ya.make
+++ /dev/null
@@ -1,10 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- ecdsa.go
- ecdsa_legacy.go
- ecdsa_noasm.go
- notboring.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/ed25519/ed25519.go b/contrib/go/_std_1.20/src/crypto/ed25519/ed25519.go
deleted file mode 100644
index a45d056851..0000000000
--- a/contrib/go/_std_1.20/src/crypto/ed25519/ed25519.go
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright 2016 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 ed25519 implements the Ed25519 signature algorithm. See
-// https://ed25519.cr.yp.to/.
-//
-// These functions are also compatible with the “Ed25519” function defined in
-// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
-// representation includes a public key suffix to make multiple signing
-// operations with the same key more efficient. This package refers to the RFC
-// 8032 private key as the “seed”.
-package ed25519
-
-import (
- "bytes"
- "crypto"
- "crypto/internal/edwards25519"
- cryptorand "crypto/rand"
- "crypto/sha512"
- "errors"
- "io"
- "strconv"
-)
-
-const (
- // PublicKeySize is the size, in bytes, of public keys as used in this package.
- PublicKeySize = 32
- // PrivateKeySize is the size, in bytes, of private keys as used in this package.
- PrivateKeySize = 64
- // SignatureSize is the size, in bytes, of signatures generated and verified by this package.
- SignatureSize = 64
- // SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
- SeedSize = 32
-)
-
-// PublicKey is the type of Ed25519 public keys.
-type PublicKey []byte
-
-// Any methods implemented on PublicKey might need to also be implemented on
-// PrivateKey, as the latter embeds the former and will expose its methods.
-
-// Equal reports whether pub and x have the same value.
-func (pub PublicKey) Equal(x crypto.PublicKey) bool {
- xx, ok := x.(PublicKey)
- if !ok {
- return false
- }
- return bytes.Equal(pub, xx)
-}
-
-// PrivateKey is the type of Ed25519 private keys. It implements [crypto.Signer].
-type PrivateKey []byte
-
-// Public returns the [PublicKey] corresponding to priv.
-func (priv PrivateKey) Public() crypto.PublicKey {
- publicKey := make([]byte, PublicKeySize)
- copy(publicKey, priv[32:])
- return PublicKey(publicKey)
-}
-
-// Equal reports whether priv and x have the same value.
-func (priv PrivateKey) Equal(x crypto.PrivateKey) bool {
- xx, ok := x.(PrivateKey)
- if !ok {
- return false
- }
- return bytes.Equal(priv, xx)
-}
-
-// Seed returns the private key seed corresponding to priv. It is provided for
-// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
-// in this package.
-func (priv PrivateKey) Seed() []byte {
- return bytes.Clone(priv[:SeedSize])
-}
-
-// Sign signs the given message with priv. rand is ignored.
-//
-// If opts.HashFunc() is [crypto.SHA512], the pre-hashed variant Ed25519ph is used
-// and message is expected to be a SHA-512 hash, otherwise opts.HashFunc() must
-// be [crypto.Hash](0) and the message must not be hashed, as Ed25519 performs two
-// passes over messages to be signed.
-//
-// A value of type [Options] can be used as opts, or crypto.Hash(0) or
-// crypto.SHA512 directly to select plain Ed25519 or Ed25519ph, respectively.
-func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
- hash := opts.HashFunc()
- context := ""
- if opts, ok := opts.(*Options); ok {
- context = opts.Context
- }
- if l := len(context); l > 255 {
- return nil, errors.New("ed25519: bad Ed25519ph context length: " + strconv.Itoa(l))
- }
- switch {
- case hash == crypto.SHA512: // Ed25519ph
- if l := len(message); l != sha512.Size {
- return nil, errors.New("ed25519: bad Ed25519ph message hash length: " + strconv.Itoa(l))
- }
- signature := make([]byte, SignatureSize)
- sign(signature, priv, message, domPrefixPh, context)
- return signature, nil
- case hash == crypto.Hash(0) && context != "": // Ed25519ctx
- signature := make([]byte, SignatureSize)
- sign(signature, priv, message, domPrefixCtx, context)
- return signature, nil
- case hash == crypto.Hash(0): // Ed25519
- return Sign(priv, message), nil
- default:
- return nil, errors.New("ed25519: expected opts.HashFunc() zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)")
- }
-}
-
-// Options can be used with [PrivateKey.Sign] or [VerifyWithOptions]
-// to select Ed25519 variants.
-type Options struct {
- // Hash can be zero for regular Ed25519, or crypto.SHA512 for Ed25519ph.
- Hash crypto.Hash
-
- // Context, if not empty, selects Ed25519ctx or provides the context string
- // for Ed25519ph. It can be at most 255 bytes in length.
- Context string
-}
-
-// HashFunc returns o.Hash.
-func (o *Options) HashFunc() crypto.Hash { return o.Hash }
-
-// GenerateKey generates a public/private key pair using entropy from rand.
-// If rand is nil, [crypto/rand.Reader] will be used.
-func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
- if rand == nil {
- rand = cryptorand.Reader
- }
-
- seed := make([]byte, SeedSize)
- if _, err := io.ReadFull(rand, seed); err != nil {
- return nil, nil, err
- }
-
- privateKey := NewKeyFromSeed(seed)
- publicKey := make([]byte, PublicKeySize)
- copy(publicKey, privateKey[32:])
-
- return publicKey, privateKey, nil
-}
-
-// NewKeyFromSeed calculates a private key from a seed. It will panic if
-// len(seed) is not [SeedSize]. This function is provided for interoperability
-// with RFC 8032. RFC 8032's private keys correspond to seeds in this
-// package.
-func NewKeyFromSeed(seed []byte) PrivateKey {
- // Outline the function body so that the returned key can be stack-allocated.
- privateKey := make([]byte, PrivateKeySize)
- newKeyFromSeed(privateKey, seed)
- return privateKey
-}
-
-func newKeyFromSeed(privateKey, seed []byte) {
- if l := len(seed); l != SeedSize {
- panic("ed25519: bad seed length: " + strconv.Itoa(l))
- }
-
- h := sha512.Sum512(seed)
- s, err := edwards25519.NewScalar().SetBytesWithClamping(h[:32])
- if err != nil {
- panic("ed25519: internal error: setting scalar failed")
- }
- A := (&edwards25519.Point{}).ScalarBaseMult(s)
-
- publicKey := A.Bytes()
-
- copy(privateKey, seed)
- copy(privateKey[32:], publicKey)
-}
-
-// Sign signs the message with privateKey and returns a signature. It will
-// panic if len(privateKey) is not [PrivateKeySize].
-func Sign(privateKey PrivateKey, message []byte) []byte {
- // Outline the function body so that the returned signature can be
- // stack-allocated.
- signature := make([]byte, SignatureSize)
- sign(signature, privateKey, message, domPrefixPure, "")
- return signature
-}
-
-// Domain separation prefixes used to disambiguate Ed25519/Ed25519ph/Ed25519ctx.
-// See RFC 8032, Section 2 and Section 5.1.
-const (
- // domPrefixPure is empty for pure Ed25519.
- domPrefixPure = ""
- // domPrefixPh is dom2(phflag=1) for Ed25519ph. It must be followed by the
- // uint8-length prefixed context.
- domPrefixPh = "SigEd25519 no Ed25519 collisions\x01"
- // domPrefixCtx is dom2(phflag=0) for Ed25519ctx. It must be followed by the
- // uint8-length prefixed context.
- domPrefixCtx = "SigEd25519 no Ed25519 collisions\x00"
-)
-
-func sign(signature, privateKey, message []byte, domPrefix, context string) {
- if l := len(privateKey); l != PrivateKeySize {
- panic("ed25519: bad private key length: " + strconv.Itoa(l))
- }
- seed, publicKey := privateKey[:SeedSize], privateKey[SeedSize:]
-
- h := sha512.Sum512(seed)
- s, err := edwards25519.NewScalar().SetBytesWithClamping(h[:32])
- if err != nil {
- panic("ed25519: internal error: setting scalar failed")
- }
- prefix := h[32:]
-
- mh := sha512.New()
- if domPrefix != domPrefixPure {
- mh.Write([]byte(domPrefix))
- mh.Write([]byte{byte(len(context))})
- mh.Write([]byte(context))
- }
- mh.Write(prefix)
- mh.Write(message)
- messageDigest := make([]byte, 0, sha512.Size)
- messageDigest = mh.Sum(messageDigest)
- r, err := edwards25519.NewScalar().SetUniformBytes(messageDigest)
- if err != nil {
- panic("ed25519: internal error: setting scalar failed")
- }
-
- R := (&edwards25519.Point{}).ScalarBaseMult(r)
-
- kh := sha512.New()
- if domPrefix != domPrefixPure {
- kh.Write([]byte(domPrefix))
- kh.Write([]byte{byte(len(context))})
- kh.Write([]byte(context))
- }
- kh.Write(R.Bytes())
- kh.Write(publicKey)
- kh.Write(message)
- hramDigest := make([]byte, 0, sha512.Size)
- hramDigest = kh.Sum(hramDigest)
- k, err := edwards25519.NewScalar().SetUniformBytes(hramDigest)
- if err != nil {
- panic("ed25519: internal error: setting scalar failed")
- }
-
- S := edwards25519.NewScalar().MultiplyAdd(k, s, r)
-
- copy(signature[:32], R.Bytes())
- copy(signature[32:], S.Bytes())
-}
-
-// Verify reports whether sig is a valid signature of message by publicKey. It
-// will panic if len(publicKey) is not [PublicKeySize].
-func Verify(publicKey PublicKey, message, sig []byte) bool {
- return verify(publicKey, message, sig, domPrefixPure, "")
-}
-
-// VerifyWithOptions reports whether sig is a valid signature of message by
-// publicKey. A valid signature is indicated by returning a nil error. It will
-// panic if len(publicKey) is not [PublicKeySize].
-//
-// If opts.Hash is [crypto.SHA512], the pre-hashed variant Ed25519ph is used and
-// message is expected to be a SHA-512 hash, otherwise opts.Hash must be
-// [crypto.Hash](0) and the message must not be hashed, as Ed25519 performs two
-// passes over messages to be signed.
-func VerifyWithOptions(publicKey PublicKey, message, sig []byte, opts *Options) error {
- switch {
- case opts.Hash == crypto.SHA512: // Ed25519ph
- if l := len(message); l != sha512.Size {
- return errors.New("ed25519: bad Ed25519ph message hash length: " + strconv.Itoa(l))
- }
- if l := len(opts.Context); l > 255 {
- return errors.New("ed25519: bad Ed25519ph context length: " + strconv.Itoa(l))
- }
- if !verify(publicKey, message, sig, domPrefixPh, opts.Context) {
- return errors.New("ed25519: invalid signature")
- }
- return nil
- case opts.Hash == crypto.Hash(0) && opts.Context != "": // Ed25519ctx
- if l := len(opts.Context); l > 255 {
- return errors.New("ed25519: bad Ed25519ctx context length: " + strconv.Itoa(l))
- }
- if !verify(publicKey, message, sig, domPrefixCtx, opts.Context) {
- return errors.New("ed25519: invalid signature")
- }
- return nil
- case opts.Hash == crypto.Hash(0): // Ed25519
- if !verify(publicKey, message, sig, domPrefixPure, "") {
- return errors.New("ed25519: invalid signature")
- }
- return nil
- default:
- return errors.New("ed25519: expected opts.Hash zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)")
- }
-}
-
-func verify(publicKey PublicKey, message, sig []byte, domPrefix, context string) bool {
- if l := len(publicKey); l != PublicKeySize {
- panic("ed25519: bad public key length: " + strconv.Itoa(l))
- }
-
- if len(sig) != SignatureSize || sig[63]&224 != 0 {
- return false
- }
-
- A, err := (&edwards25519.Point{}).SetBytes(publicKey)
- if err != nil {
- return false
- }
-
- kh := sha512.New()
- if domPrefix != domPrefixPure {
- kh.Write([]byte(domPrefix))
- kh.Write([]byte{byte(len(context))})
- kh.Write([]byte(context))
- }
- kh.Write(sig[:32])
- kh.Write(publicKey)
- kh.Write(message)
- hramDigest := make([]byte, 0, sha512.Size)
- hramDigest = kh.Sum(hramDigest)
- k, err := edwards25519.NewScalar().SetUniformBytes(hramDigest)
- if err != nil {
- panic("ed25519: internal error: setting scalar failed")
- }
-
- S, err := edwards25519.NewScalar().SetCanonicalBytes(sig[32:])
- if err != nil {
- return false
- }
-
- // [S]B = R + [k]A --> [k](-A) + [S]B = R
- minusA := (&edwards25519.Point{}).Negate(A)
- R := (&edwards25519.Point{}).VarTimeDoubleScalarBaseMult(k, minusA, S)
-
- return bytes.Equal(sig[:32], R.Bytes())
-}
diff --git a/contrib/go/_std_1.20/src/crypto/ed25519/ya.make b/contrib/go/_std_1.20/src/crypto/ed25519/ya.make
deleted file mode 100644
index 73cedd7489..0000000000
--- a/contrib/go/_std_1.20/src/crypto/ed25519/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- ed25519.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/elliptic/elliptic.go b/contrib/go/_std_1.20/src/crypto/elliptic/elliptic.go
deleted file mode 100644
index 6b07f5b7ed..0000000000
--- a/contrib/go/_std_1.20/src/crypto/elliptic/elliptic.go
+++ /dev/null
@@ -1,275 +0,0 @@
-// Copyright 2010 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 elliptic implements the standard NIST P-224, P-256, P-384, and P-521
-// elliptic curves over prime fields.
-//
-// The P224(), P256(), P384() and P521() values are necessary to use the crypto/ecdsa package.
-// Most other uses should migrate to the more efficient and safer crypto/ecdh package.
-package elliptic
-
-import (
- "io"
- "math/big"
- "sync"
-)
-
-// A Curve represents a short-form Weierstrass curve with a=-3.
-//
-// The behavior of Add, Double, and ScalarMult when the input is not a point on
-// the curve is undefined.
-//
-// Note that the conventional point at infinity (0, 0) is not considered on the
-// curve, although it can be returned by Add, Double, ScalarMult, or
-// ScalarBaseMult (but not the Unmarshal or UnmarshalCompressed functions).
-type Curve interface {
- // Params returns the parameters for the curve.
- Params() *CurveParams
-
- // IsOnCurve reports whether the given (x,y) lies on the curve.
- //
- // Note: this is a low-level unsafe API. For ECDH, use the crypto/ecdh
- // package. The NewPublicKey methods of NIST curves in crypto/ecdh accept
- // the same encoding as the Unmarshal function, and perform on-curve checks.
- IsOnCurve(x, y *big.Int) bool
-
- // Add returns the sum of (x1,y1) and (x2,y2).
- //
- // Note: this is a low-level unsafe API.
- Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int)
-
- // Double returns 2*(x,y).
- //
- // Note: this is a low-level unsafe API.
- Double(x1, y1 *big.Int) (x, y *big.Int)
-
- // ScalarMult returns k*(x,y) where k is an integer in big-endian form.
- //
- // Note: this is a low-level unsafe API. For ECDH, use the crypto/ecdh
- // package. Most uses of ScalarMult can be replaced by a call to the ECDH
- // methods of NIST curves in crypto/ecdh.
- ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int)
-
- // ScalarBaseMult returns k*G, where G is the base point of the group
- // and k is an integer in big-endian form.
- //
- // Note: this is a low-level unsafe API. For ECDH, use the crypto/ecdh
- // package. Most uses of ScalarBaseMult can be replaced by a call to the
- // PrivateKey.PublicKey method in crypto/ecdh.
- ScalarBaseMult(k []byte) (x, y *big.Int)
-}
-
-var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
-
-// GenerateKey returns a public/private key pair. The private key is
-// generated using the given reader, which must return random data.
-//
-// Note: for ECDH, use the GenerateKey methods of the crypto/ecdh package;
-// for ECDSA, use the GenerateKey function of the crypto/ecdsa package.
-func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error) {
- N := curve.Params().N
- bitSize := N.BitLen()
- byteLen := (bitSize + 7) / 8
- priv = make([]byte, byteLen)
-
- for x == nil {
- _, err = io.ReadFull(rand, priv)
- if err != nil {
- return
- }
- // We have to mask off any excess bits in the case that the size of the
- // underlying field is not a whole number of bytes.
- priv[0] &= mask[bitSize%8]
- // This is because, in tests, rand will return all zeros and we don't
- // want to get the point at infinity and loop forever.
- priv[1] ^= 0x42
-
- // If the scalar is out of range, sample another random number.
- if new(big.Int).SetBytes(priv).Cmp(N) >= 0 {
- continue
- }
-
- x, y = curve.ScalarBaseMult(priv)
- }
- return
-}
-
-// Marshal converts a point on the curve into the uncompressed form specified in
-// SEC 1, Version 2.0, Section 2.3.3. If the point is not on the curve (or is
-// the conventional point at infinity), the behavior is undefined.
-//
-// Note: for ECDH, use the crypto/ecdh package. This function returns an
-// encoding equivalent to that of PublicKey.Bytes in crypto/ecdh.
-func Marshal(curve Curve, x, y *big.Int) []byte {
- panicIfNotOnCurve(curve, x, y)
-
- byteLen := (curve.Params().BitSize + 7) / 8
-
- ret := make([]byte, 1+2*byteLen)
- ret[0] = 4 // uncompressed point
-
- x.FillBytes(ret[1 : 1+byteLen])
- y.FillBytes(ret[1+byteLen : 1+2*byteLen])
-
- return ret
-}
-
-// MarshalCompressed converts a point on the curve into the compressed form
-// specified in SEC 1, Version 2.0, Section 2.3.3. If the point is not on the
-// curve (or is the conventional point at infinity), the behavior is undefined.
-func MarshalCompressed(curve Curve, x, y *big.Int) []byte {
- panicIfNotOnCurve(curve, x, y)
- byteLen := (curve.Params().BitSize + 7) / 8
- compressed := make([]byte, 1+byteLen)
- compressed[0] = byte(y.Bit(0)) | 2
- x.FillBytes(compressed[1:])
- return compressed
-}
-
-// unmarshaler is implemented by curves with their own constant-time Unmarshal.
-//
-// There isn't an equivalent interface for Marshal/MarshalCompressed because
-// that doesn't involve any mathematical operations, only FillBytes and Bit.
-type unmarshaler interface {
- Unmarshal([]byte) (x, y *big.Int)
- UnmarshalCompressed([]byte) (x, y *big.Int)
-}
-
-// Assert that the known curves implement unmarshaler.
-var _ = []unmarshaler{p224, p256, p384, p521}
-
-// Unmarshal converts a point, serialized by Marshal, into an x, y pair. It is
-// an error if the point is not in uncompressed form, is not on the curve, or is
-// the point at infinity. On error, x = nil.
-//
-// Note: for ECDH, use the crypto/ecdh package. This function accepts an
-// encoding equivalent to that of the NewPublicKey methods in crypto/ecdh.
-func Unmarshal(curve Curve, data []byte) (x, y *big.Int) {
- if c, ok := curve.(unmarshaler); ok {
- return c.Unmarshal(data)
- }
-
- byteLen := (curve.Params().BitSize + 7) / 8
- if len(data) != 1+2*byteLen {
- return nil, nil
- }
- if data[0] != 4 { // uncompressed form
- return nil, nil
- }
- p := curve.Params().P
- x = new(big.Int).SetBytes(data[1 : 1+byteLen])
- y = new(big.Int).SetBytes(data[1+byteLen:])
- if x.Cmp(p) >= 0 || y.Cmp(p) >= 0 {
- return nil, nil
- }
- if !curve.IsOnCurve(x, y) {
- return nil, nil
- }
- return
-}
-
-// UnmarshalCompressed converts a point, serialized by MarshalCompressed, into
-// an x, y pair. It is an error if the point is not in compressed form, is not
-// on the curve, or is the point at infinity. On error, x = nil.
-func UnmarshalCompressed(curve Curve, data []byte) (x, y *big.Int) {
- if c, ok := curve.(unmarshaler); ok {
- return c.UnmarshalCompressed(data)
- }
-
- byteLen := (curve.Params().BitSize + 7) / 8
- if len(data) != 1+byteLen {
- return nil, nil
- }
- if data[0] != 2 && data[0] != 3 { // compressed form
- return nil, nil
- }
- p := curve.Params().P
- x = new(big.Int).SetBytes(data[1:])
- if x.Cmp(p) >= 0 {
- return nil, nil
- }
- // y² = x³ - 3x + b
- y = curve.Params().polynomial(x)
- y = y.ModSqrt(y, p)
- if y == nil {
- return nil, nil
- }
- if byte(y.Bit(0)) != data[0]&1 {
- y.Neg(y).Mod(y, p)
- }
- if !curve.IsOnCurve(x, y) {
- return nil, nil
- }
- return
-}
-
-func panicIfNotOnCurve(curve Curve, x, y *big.Int) {
- // (0, 0) is the point at infinity by convention. It's ok to operate on it,
- // although IsOnCurve is documented to return false for it. See Issue 37294.
- if x.Sign() == 0 && y.Sign() == 0 {
- return
- }
-
- if !curve.IsOnCurve(x, y) {
- panic("crypto/elliptic: attempted operation on invalid point")
- }
-}
-
-var initonce sync.Once
-
-func initAll() {
- initP224()
- initP256()
- initP384()
- initP521()
-}
-
-// P224 returns a Curve which implements NIST P-224 (FIPS 186-3, section D.2.2),
-// also known as secp224r1. The CurveParams.Name of this Curve is "P-224".
-//
-// Multiple invocations of this function will return the same value, so it can
-// be used for equality checks and switch statements.
-//
-// The cryptographic operations are implemented using constant-time algorithms.
-func P224() Curve {
- initonce.Do(initAll)
- return p224
-}
-
-// P256 returns a Curve which implements NIST P-256 (FIPS 186-3, section D.2.3),
-// also known as secp256r1 or prime256v1. The CurveParams.Name of this Curve is
-// "P-256".
-//
-// Multiple invocations of this function will return the same value, so it can
-// be used for equality checks and switch statements.
-//
-// The cryptographic operations are implemented using constant-time algorithms.
-func P256() Curve {
- initonce.Do(initAll)
- return p256
-}
-
-// P384 returns a Curve which implements NIST P-384 (FIPS 186-3, section D.2.4),
-// also known as secp384r1. The CurveParams.Name of this Curve is "P-384".
-//
-// Multiple invocations of this function will return the same value, so it can
-// be used for equality checks and switch statements.
-//
-// The cryptographic operations are implemented using constant-time algorithms.
-func P384() Curve {
- initonce.Do(initAll)
- return p384
-}
-
-// P521 returns a Curve which implements NIST P-521 (FIPS 186-3, section D.2.5),
-// also known as secp521r1. The CurveParams.Name of this Curve is "P-521".
-//
-// Multiple invocations of this function will return the same value, so it can
-// be used for equality checks and switch statements.
-//
-// The cryptographic operations are implemented using constant-time algorithms.
-func P521() Curve {
- initonce.Do(initAll)
- return p521
-}
diff --git a/contrib/go/_std_1.20/src/crypto/elliptic/params.go b/contrib/go/_std_1.20/src/crypto/elliptic/params.go
deleted file mode 100644
index c4e9784ce2..0000000000
--- a/contrib/go/_std_1.20/src/crypto/elliptic/params.go
+++ /dev/null
@@ -1,333 +0,0 @@
-// 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 elliptic
-
-import "math/big"
-
-// CurveParams contains the parameters of an elliptic curve and also provides
-// a generic, non-constant time implementation of Curve.
-//
-// Note: Custom curves (those not returned by P224(), P256(), P384(), and P521())
-// are not guaranteed to provide any security property.
-type CurveParams struct {
- P *big.Int // the order of the underlying field
- N *big.Int // the order of the base point
- B *big.Int // the constant of the curve equation
- Gx, Gy *big.Int // (x,y) of the base point
- BitSize int // the size of the underlying field
- Name string // the canonical name of the curve
-}
-
-func (curve *CurveParams) Params() *CurveParams {
- return curve
-}
-
-// CurveParams operates, internally, on Jacobian coordinates. For a given
-// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
-// where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole
-// calculation can be performed within the transform (as in ScalarMult and
-// ScalarBaseMult). But even for Add and Double, it's faster to apply and
-// reverse the transform than to operate in affine coordinates.
-
-// polynomial returns x³ - 3x + b.
-func (curve *CurveParams) polynomial(x *big.Int) *big.Int {
- x3 := new(big.Int).Mul(x, x)
- x3.Mul(x3, x)
-
- threeX := new(big.Int).Lsh(x, 1)
- threeX.Add(threeX, x)
-
- x3.Sub(x3, threeX)
- x3.Add(x3, curve.B)
- x3.Mod(x3, curve.P)
-
- return x3
-}
-
-// IsOnCurve implements Curve.IsOnCurve.
-//
-// Note: the CurveParams methods are not guaranteed to
-// provide any security property. For ECDH, use the crypto/ecdh package.
-// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
-// from P224(), P256(), P384(), or P521().
-func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool {
- // If there is a dedicated constant-time implementation for this curve operation,
- // use that instead of the generic one.
- if specific, ok := matchesSpecificCurve(curve); ok {
- return specific.IsOnCurve(x, y)
- }
-
- if x.Sign() < 0 || x.Cmp(curve.P) >= 0 ||
- y.Sign() < 0 || y.Cmp(curve.P) >= 0 {
- return false
- }
-
- // y² = x³ - 3x + b
- y2 := new(big.Int).Mul(y, y)
- y2.Mod(y2, curve.P)
-
- return curve.polynomial(x).Cmp(y2) == 0
-}
-
-// zForAffine returns a Jacobian Z value for the affine point (x, y). If x and
-// y are zero, it assumes that they represent the point at infinity because (0,
-// 0) is not on the any of the curves handled here.
-func zForAffine(x, y *big.Int) *big.Int {
- z := new(big.Int)
- if x.Sign() != 0 || y.Sign() != 0 {
- z.SetInt64(1)
- }
- return z
-}
-
-// affineFromJacobian reverses the Jacobian transform. See the comment at the
-// top of the file. If the point is ∞ it returns 0, 0.
-func (curve *CurveParams) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
- if z.Sign() == 0 {
- return new(big.Int), new(big.Int)
- }
-
- zinv := new(big.Int).ModInverse(z, curve.P)
- zinvsq := new(big.Int).Mul(zinv, zinv)
-
- xOut = new(big.Int).Mul(x, zinvsq)
- xOut.Mod(xOut, curve.P)
- zinvsq.Mul(zinvsq, zinv)
- yOut = new(big.Int).Mul(y, zinvsq)
- yOut.Mod(yOut, curve.P)
- return
-}
-
-// Add implements Curve.Add.
-//
-// Note: the CurveParams methods are not guaranteed to
-// provide any security property. For ECDH, use the crypto/ecdh package.
-// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
-// from P224(), P256(), P384(), or P521().
-func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
- // If there is a dedicated constant-time implementation for this curve operation,
- // use that instead of the generic one.
- if specific, ok := matchesSpecificCurve(curve); ok {
- return specific.Add(x1, y1, x2, y2)
- }
- panicIfNotOnCurve(curve, x1, y1)
- panicIfNotOnCurve(curve, x2, y2)
-
- z1 := zForAffine(x1, y1)
- z2 := zForAffine(x2, y2)
- return curve.affineFromJacobian(curve.addJacobian(x1, y1, z1, x2, y2, z2))
-}
-
-// addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
-// (x2, y2, z2) and returns their sum, also in Jacobian form.
-func (curve *CurveParams) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
- // See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
- x3, y3, z3 := new(big.Int), new(big.Int), new(big.Int)
- if z1.Sign() == 0 {
- x3.Set(x2)
- y3.Set(y2)
- z3.Set(z2)
- return x3, y3, z3
- }
- if z2.Sign() == 0 {
- x3.Set(x1)
- y3.Set(y1)
- z3.Set(z1)
- return x3, y3, z3
- }
-
- z1z1 := new(big.Int).Mul(z1, z1)
- z1z1.Mod(z1z1, curve.P)
- z2z2 := new(big.Int).Mul(z2, z2)
- z2z2.Mod(z2z2, curve.P)
-
- u1 := new(big.Int).Mul(x1, z2z2)
- u1.Mod(u1, curve.P)
- u2 := new(big.Int).Mul(x2, z1z1)
- u2.Mod(u2, curve.P)
- h := new(big.Int).Sub(u2, u1)
- xEqual := h.Sign() == 0
- if h.Sign() == -1 {
- h.Add(h, curve.P)
- }
- i := new(big.Int).Lsh(h, 1)
- i.Mul(i, i)
- j := new(big.Int).Mul(h, i)
-
- s1 := new(big.Int).Mul(y1, z2)
- s1.Mul(s1, z2z2)
- s1.Mod(s1, curve.P)
- s2 := new(big.Int).Mul(y2, z1)
- s2.Mul(s2, z1z1)
- s2.Mod(s2, curve.P)
- r := new(big.Int).Sub(s2, s1)
- if r.Sign() == -1 {
- r.Add(r, curve.P)
- }
- yEqual := r.Sign() == 0
- if xEqual && yEqual {
- return curve.doubleJacobian(x1, y1, z1)
- }
- r.Lsh(r, 1)
- v := new(big.Int).Mul(u1, i)
-
- x3.Set(r)
- x3.Mul(x3, x3)
- x3.Sub(x3, j)
- x3.Sub(x3, v)
- x3.Sub(x3, v)
- x3.Mod(x3, curve.P)
-
- y3.Set(r)
- v.Sub(v, x3)
- y3.Mul(y3, v)
- s1.Mul(s1, j)
- s1.Lsh(s1, 1)
- y3.Sub(y3, s1)
- y3.Mod(y3, curve.P)
-
- z3.Add(z1, z2)
- z3.Mul(z3, z3)
- z3.Sub(z3, z1z1)
- z3.Sub(z3, z2z2)
- z3.Mul(z3, h)
- z3.Mod(z3, curve.P)
-
- return x3, y3, z3
-}
-
-// Double implements Curve.Double.
-//
-// Note: the CurveParams methods are not guaranteed to
-// provide any security property. For ECDH, use the crypto/ecdh package.
-// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
-// from P224(), P256(), P384(), or P521().
-func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
- // If there is a dedicated constant-time implementation for this curve operation,
- // use that instead of the generic one.
- if specific, ok := matchesSpecificCurve(curve); ok {
- return specific.Double(x1, y1)
- }
- panicIfNotOnCurve(curve, x1, y1)
-
- z1 := zForAffine(x1, y1)
- return curve.affineFromJacobian(curve.doubleJacobian(x1, y1, z1))
-}
-
-// doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
-// returns its double, also in Jacobian form.
-func (curve *CurveParams) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
- // See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
- delta := new(big.Int).Mul(z, z)
- delta.Mod(delta, curve.P)
- gamma := new(big.Int).Mul(y, y)
- gamma.Mod(gamma, curve.P)
- alpha := new(big.Int).Sub(x, delta)
- if alpha.Sign() == -1 {
- alpha.Add(alpha, curve.P)
- }
- alpha2 := new(big.Int).Add(x, delta)
- alpha.Mul(alpha, alpha2)
- alpha2.Set(alpha)
- alpha.Lsh(alpha, 1)
- alpha.Add(alpha, alpha2)
-
- beta := alpha2.Mul(x, gamma)
-
- x3 := new(big.Int).Mul(alpha, alpha)
- beta8 := new(big.Int).Lsh(beta, 3)
- beta8.Mod(beta8, curve.P)
- x3.Sub(x3, beta8)
- if x3.Sign() == -1 {
- x3.Add(x3, curve.P)
- }
- x3.Mod(x3, curve.P)
-
- z3 := new(big.Int).Add(y, z)
- z3.Mul(z3, z3)
- z3.Sub(z3, gamma)
- if z3.Sign() == -1 {
- z3.Add(z3, curve.P)
- }
- z3.Sub(z3, delta)
- if z3.Sign() == -1 {
- z3.Add(z3, curve.P)
- }
- z3.Mod(z3, curve.P)
-
- beta.Lsh(beta, 2)
- beta.Sub(beta, x3)
- if beta.Sign() == -1 {
- beta.Add(beta, curve.P)
- }
- y3 := alpha.Mul(alpha, beta)
-
- gamma.Mul(gamma, gamma)
- gamma.Lsh(gamma, 3)
- gamma.Mod(gamma, curve.P)
-
- y3.Sub(y3, gamma)
- if y3.Sign() == -1 {
- y3.Add(y3, curve.P)
- }
- y3.Mod(y3, curve.P)
-
- return x3, y3, z3
-}
-
-// ScalarMult implements Curve.ScalarMult.
-//
-// Note: the CurveParams methods are not guaranteed to
-// provide any security property. For ECDH, use the crypto/ecdh package.
-// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
-// from P224(), P256(), P384(), or P521().
-func (curve *CurveParams) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
- // If there is a dedicated constant-time implementation for this curve operation,
- // use that instead of the generic one.
- if specific, ok := matchesSpecificCurve(curve); ok {
- return specific.ScalarMult(Bx, By, k)
- }
- panicIfNotOnCurve(curve, Bx, By)
-
- Bz := new(big.Int).SetInt64(1)
- x, y, z := new(big.Int), new(big.Int), new(big.Int)
-
- for _, byte := range k {
- for bitNum := 0; bitNum < 8; bitNum++ {
- x, y, z = curve.doubleJacobian(x, y, z)
- if byte&0x80 == 0x80 {
- x, y, z = curve.addJacobian(Bx, By, Bz, x, y, z)
- }
- byte <<= 1
- }
- }
-
- return curve.affineFromJacobian(x, y, z)
-}
-
-// ScalarBaseMult implements Curve.ScalarBaseMult.
-//
-// Note: the CurveParams methods are not guaranteed to
-// provide any security property. For ECDH, use the crypto/ecdh package.
-// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
-// from P224(), P256(), P384(), or P521().
-func (curve *CurveParams) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
- // If there is a dedicated constant-time implementation for this curve operation,
- // use that instead of the generic one.
- if specific, ok := matchesSpecificCurve(curve); ok {
- return specific.ScalarBaseMult(k)
- }
-
- return curve.ScalarMult(curve.Gx, curve.Gy, k)
-}
-
-func matchesSpecificCurve(params *CurveParams) (Curve, bool) {
- for _, c := range []Curve{p224, p256, p384, p521} {
- if params == c.Params() {
- return c, true
- }
- }
- return nil, false
-}
diff --git a/contrib/go/_std_1.20/src/crypto/elliptic/ya.make b/contrib/go/_std_1.20/src/crypto/elliptic/ya.make
deleted file mode 100644
index 72fe8d0d6b..0000000000
--- a/contrib/go/_std_1.20/src/crypto/elliptic/ya.make
+++ /dev/null
@@ -1,10 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- elliptic.go
- nistec.go
- nistec_p256.go
- params.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/hmac/hmac.go b/contrib/go/_std_1.20/src/crypto/hmac/hmac.go
deleted file mode 100644
index ed3ebc0602..0000000000
--- a/contrib/go/_std_1.20/src/crypto/hmac/hmac.go
+++ /dev/null
@@ -1,180 +0,0 @@
-// Copyright 2009 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 hmac implements the Keyed-Hash Message Authentication Code (HMAC) as
-defined in U.S. Federal Information Processing Standards Publication 198.
-An HMAC is a cryptographic hash that uses a key to sign a message.
-The receiver verifies the hash by recomputing it using the same key.
-
-Receivers should be careful to use Equal to compare MACs in order to avoid
-timing side-channels:
-
- // ValidMAC reports whether messageMAC is a valid HMAC tag for message.
- func ValidMAC(message, messageMAC, key []byte) bool {
- mac := hmac.New(sha256.New, key)
- mac.Write(message)
- expectedMAC := mac.Sum(nil)
- return hmac.Equal(messageMAC, expectedMAC)
- }
-*/
-package hmac
-
-import (
- "crypto/internal/boring"
- "crypto/subtle"
- "hash"
-)
-
-// FIPS 198-1:
-// https://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf
-
-// key is zero padded to the block size of the hash function
-// ipad = 0x36 byte repeated for key length
-// opad = 0x5c byte repeated for key length
-// hmac = H([key ^ opad] H([key ^ ipad] text))
-
-// Marshalable is the combination of encoding.BinaryMarshaler and
-// encoding.BinaryUnmarshaler. Their method definitions are repeated here to
-// avoid a dependency on the encoding package.
-type marshalable interface {
- MarshalBinary() ([]byte, error)
- UnmarshalBinary([]byte) error
-}
-
-type hmac struct {
- opad, ipad []byte
- outer, inner hash.Hash
-
- // If marshaled is true, then opad and ipad do not contain a padded
- // copy of the key, but rather the marshaled state of outer/inner after
- // opad/ipad has been fed into it.
- marshaled bool
-}
-
-func (h *hmac) Sum(in []byte) []byte {
- origLen := len(in)
- in = h.inner.Sum(in)
-
- if h.marshaled {
- if err := h.outer.(marshalable).UnmarshalBinary(h.opad); err != nil {
- panic(err)
- }
- } else {
- h.outer.Reset()
- h.outer.Write(h.opad)
- }
- h.outer.Write(in[origLen:])
- return h.outer.Sum(in[:origLen])
-}
-
-func (h *hmac) Write(p []byte) (n int, err error) {
- return h.inner.Write(p)
-}
-
-func (h *hmac) Size() int { return h.outer.Size() }
-func (h *hmac) BlockSize() int { return h.inner.BlockSize() }
-
-func (h *hmac) Reset() {
- if h.marshaled {
- if err := h.inner.(marshalable).UnmarshalBinary(h.ipad); err != nil {
- panic(err)
- }
- return
- }
-
- h.inner.Reset()
- h.inner.Write(h.ipad)
-
- // If the underlying hash is marshalable, we can save some time by
- // saving a copy of the hash state now, and restoring it on future
- // calls to Reset and Sum instead of writing ipad/opad every time.
- //
- // If either hash is unmarshalable for whatever reason,
- // it's safe to bail out here.
- marshalableInner, innerOK := h.inner.(marshalable)
- if !innerOK {
- return
- }
- marshalableOuter, outerOK := h.outer.(marshalable)
- if !outerOK {
- return
- }
-
- imarshal, err := marshalableInner.MarshalBinary()
- if err != nil {
- return
- }
-
- h.outer.Reset()
- h.outer.Write(h.opad)
- omarshal, err := marshalableOuter.MarshalBinary()
- if err != nil {
- return
- }
-
- // Marshaling succeeded; save the marshaled state for later
- h.ipad = imarshal
- h.opad = omarshal
- h.marshaled = true
-}
-
-// New returns a new HMAC hash using the given hash.Hash type and key.
-// New functions like sha256.New from crypto/sha256 can be used as h.
-// h must return a new Hash every time it is called.
-// Note that unlike other hash implementations in the standard library,
-// the returned Hash does not implement encoding.BinaryMarshaler
-// or encoding.BinaryUnmarshaler.
-func New(h func() hash.Hash, key []byte) hash.Hash {
- if boring.Enabled {
- hm := boring.NewHMAC(h, key)
- if hm != nil {
- return hm
- }
- // BoringCrypto did not recognize h, so fall through to standard Go code.
- }
- hm := new(hmac)
- hm.outer = h()
- hm.inner = h()
- unique := true
- func() {
- defer func() {
- // The comparison might panic if the underlying types are not comparable.
- _ = recover()
- }()
- if hm.outer == hm.inner {
- unique = false
- }
- }()
- if !unique {
- panic("crypto/hmac: hash generation function does not produce unique values")
- }
- blocksize := hm.inner.BlockSize()
- hm.ipad = make([]byte, blocksize)
- hm.opad = make([]byte, blocksize)
- if len(key) > blocksize {
- // If key is too big, hash it.
- hm.outer.Write(key)
- key = hm.outer.Sum(nil)
- }
- copy(hm.ipad, key)
- copy(hm.opad, key)
- for i := range hm.ipad {
- hm.ipad[i] ^= 0x36
- }
- for i := range hm.opad {
- hm.opad[i] ^= 0x5c
- }
- hm.inner.Write(hm.ipad)
-
- return hm
-}
-
-// Equal compares two MACs for equality without leaking timing information.
-func Equal(mac1, mac2 []byte) bool {
- // We don't have to be constant time if the lengths of the MACs are
- // different as that suggests that a completely different hash function
- // was used.
- return subtle.ConstantTimeCompare(mac1, mac2) == 1
-}
diff --git a/contrib/go/_std_1.20/src/crypto/hmac/ya.make b/contrib/go/_std_1.20/src/crypto/hmac/ya.make
deleted file mode 100644
index 5002bbb744..0000000000
--- a/contrib/go/_std_1.20/src/crypto/hmac/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- hmac.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/internal/alias/alias.go b/contrib/go/_std_1.20/src/crypto/internal/alias/alias.go
deleted file mode 100644
index 936cc253e3..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/alias/alias.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 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 alias implements memory alaising tests.
-// This code also exists as golang.org/x/crypto/internal/alias.
-package alias
-
-import "unsafe"
-
-// AnyOverlap reports whether x and y share memory at any (not necessarily
-// corresponding) index. The memory beyond the slice length is ignored.
-func AnyOverlap(x, y []byte) bool {
- return len(x) > 0 && len(y) > 0 &&
- uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
- uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
-}
-
-// InexactOverlap reports whether x and y share memory at any non-corresponding
-// index. The memory beyond the slice length is ignored. Note that x and y can
-// have different lengths and still not have any inexact overlap.
-//
-// InexactOverlap can be used to implement the requirements of the crypto/cipher
-// AEAD, Block, BlockMode and Stream interfaces.
-func InexactOverlap(x, y []byte) bool {
- if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
- return false
- }
- return AnyOverlap(x, y)
-}
diff --git a/contrib/go/_std_1.20/src/crypto/internal/bigmod/nat.go b/contrib/go/_std_1.20/src/crypto/internal/bigmod/nat.go
deleted file mode 100644
index 804316f504..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/bigmod/nat.go
+++ /dev/null
@@ -1,703 +0,0 @@
-// 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 bigmod
-
-import (
- "errors"
- "math/big"
- "math/bits"
-)
-
-const (
- // _W is the number of bits we use for our limbs.
- _W = bits.UintSize - 1
- // _MASK selects _W bits from a full machine word.
- _MASK = (1 << _W) - 1
-)
-
-// choice represents a constant-time boolean. The value of choice is always
-// either 1 or 0. We use an int instead of bool in order to make decisions in
-// constant time by turning it into a mask.
-type choice uint
-
-func not(c choice) choice { return 1 ^ c }
-
-const yes = choice(1)
-const no = choice(0)
-
-// ctSelect returns x if on == 1, and y if on == 0. The execution time of this
-// function does not depend on its inputs. If on is any value besides 1 or 0,
-// the result is undefined.
-func ctSelect(on choice, x, y uint) uint {
- // When on == 1, mask is 0b111..., otherwise mask is 0b000...
- mask := -uint(on)
- // When mask is all zeros, we just have y, otherwise, y cancels with itself.
- return y ^ (mask & (y ^ x))
-}
-
-// ctEq returns 1 if x == y, and 0 otherwise. The execution time of this
-// function does not depend on its inputs.
-func ctEq(x, y uint) choice {
- // If x != y, then either x - y or y - x will generate a carry.
- _, c1 := bits.Sub(x, y, 0)
- _, c2 := bits.Sub(y, x, 0)
- return not(choice(c1 | c2))
-}
-
-// ctGeq returns 1 if x >= y, and 0 otherwise. The execution time of this
-// function does not depend on its inputs.
-func ctGeq(x, y uint) choice {
- // If x < y, then x - y generates a carry.
- _, carry := bits.Sub(x, y, 0)
- return not(choice(carry))
-}
-
-// Nat represents an arbitrary natural number
-//
-// Each Nat has an announced length, which is the number of limbs it has stored.
-// Operations on this number are allowed to leak this length, but will not leak
-// any information about the values contained in those limbs.
-type Nat struct {
- // limbs is a little-endian representation in base 2^W with
- // W = bits.UintSize - 1. The top bit is always unset between operations.
- //
- // The top bit is left unset to optimize Montgomery multiplication, in the
- // inner loop of exponentiation. Using fully saturated limbs would leave us
- // working with 129-bit numbers on 64-bit platforms, wasting a lot of space,
- // and thus time.
- limbs []uint
-}
-
-// preallocTarget is the size in bits of the numbers used to implement the most
-// common and most performant RSA key size. It's also enough to cover some of
-// the operations of key sizes up to 4096.
-const preallocTarget = 2048
-const preallocLimbs = (preallocTarget + _W - 1) / _W
-
-// NewNat returns a new nat with a size of zero, just like new(Nat), but with
-// the preallocated capacity to hold a number of up to preallocTarget bits.
-// NewNat inlines, so the allocation can live on the stack.
-func NewNat() *Nat {
- limbs := make([]uint, 0, preallocLimbs)
- return &Nat{limbs}
-}
-
-// expand expands x to n limbs, leaving its value unchanged.
-func (x *Nat) expand(n int) *Nat {
- if len(x.limbs) > n {
- panic("bigmod: internal error: shrinking nat")
- }
- if cap(x.limbs) < n {
- newLimbs := make([]uint, n)
- copy(newLimbs, x.limbs)
- x.limbs = newLimbs
- return x
- }
- extraLimbs := x.limbs[len(x.limbs):n]
- for i := range extraLimbs {
- extraLimbs[i] = 0
- }
- x.limbs = x.limbs[:n]
- return x
-}
-
-// reset returns a zero nat of n limbs, reusing x's storage if n <= cap(x.limbs).
-func (x *Nat) reset(n int) *Nat {
- if cap(x.limbs) < n {
- x.limbs = make([]uint, n)
- return x
- }
- for i := range x.limbs {
- x.limbs[i] = 0
- }
- x.limbs = x.limbs[:n]
- return x
-}
-
-// set assigns x = y, optionally resizing x to the appropriate size.
-func (x *Nat) set(y *Nat) *Nat {
- x.reset(len(y.limbs))
- copy(x.limbs, y.limbs)
- return x
-}
-
-// setBig assigns x = n, optionally resizing n to the appropriate size.
-//
-// The announced length of x is set based on the actual bit size of the input,
-// ignoring leading zeroes.
-func (x *Nat) setBig(n *big.Int) *Nat {
- requiredLimbs := (n.BitLen() + _W - 1) / _W
- x.reset(requiredLimbs)
-
- outI := 0
- shift := 0
- limbs := n.Bits()
- for i := range limbs {
- xi := uint(limbs[i])
- x.limbs[outI] |= (xi << shift) & _MASK
- outI++
- if outI == requiredLimbs {
- return x
- }
- x.limbs[outI] = xi >> (_W - shift)
- shift++ // this assumes bits.UintSize - _W = 1
- if shift == _W {
- shift = 0
- outI++
- }
- }
- return x
-}
-
-// Bytes returns x as a zero-extended big-endian byte slice. The size of the
-// slice will match the size of m.
-//
-// x must have the same size as m and it must be reduced modulo m.
-func (x *Nat) Bytes(m *Modulus) []byte {
- bytes := make([]byte, m.Size())
- shift := 0
- outI := len(bytes) - 1
- for _, limb := range x.limbs {
- remainingBits := _W
- for remainingBits >= 8 {
- bytes[outI] |= byte(limb) << shift
- consumed := 8 - shift
- limb >>= consumed
- remainingBits -= consumed
- shift = 0
- outI--
- if outI < 0 {
- return bytes
- }
- }
- bytes[outI] = byte(limb)
- shift = remainingBits
- }
- return bytes
-}
-
-// SetBytes assigns x = b, where b is a slice of big-endian bytes.
-// SetBytes returns an error if b >= m.
-//
-// The output will be resized to the size of m and overwritten.
-func (x *Nat) SetBytes(b []byte, m *Modulus) (*Nat, error) {
- if err := x.setBytes(b, m); err != nil {
- return nil, err
- }
- if x.cmpGeq(m.nat) == yes {
- return nil, errors.New("input overflows the modulus")
- }
- return x, nil
-}
-
-// SetOverflowingBytes assigns x = b, where b is a slice of big-endian bytes. SetOverflowingBytes
-// returns an error if b has a longer bit length than m, but reduces overflowing
-// values up to 2^⌈log2(m)⌉ - 1.
-//
-// The output will be resized to the size of m and overwritten.
-func (x *Nat) SetOverflowingBytes(b []byte, m *Modulus) (*Nat, error) {
- if err := x.setBytes(b, m); err != nil {
- return nil, err
- }
- leading := _W - bitLen(x.limbs[len(x.limbs)-1])
- if leading < m.leading {
- return nil, errors.New("input overflows the modulus")
- }
- x.sub(x.cmpGeq(m.nat), m.nat)
- return x, nil
-}
-
-func (x *Nat) setBytes(b []byte, m *Modulus) error {
- outI := 0
- shift := 0
- x.resetFor(m)
- for i := len(b) - 1; i >= 0; i-- {
- bi := b[i]
- x.limbs[outI] |= uint(bi) << shift
- shift += 8
- if shift >= _W {
- shift -= _W
- x.limbs[outI] &= _MASK
- overflow := bi >> (8 - shift)
- outI++
- if outI >= len(x.limbs) {
- if overflow > 0 || i > 0 {
- return errors.New("input overflows the modulus")
- }
- break
- }
- x.limbs[outI] = uint(overflow)
- }
- }
- return nil
-}
-
-// Equal returns 1 if x == y, and 0 otherwise.
-//
-// Both operands must have the same announced length.
-func (x *Nat) Equal(y *Nat) choice {
- // Eliminate bounds checks in the loop.
- size := len(x.limbs)
- xLimbs := x.limbs[:size]
- yLimbs := y.limbs[:size]
-
- equal := yes
- for i := 0; i < size; i++ {
- equal &= ctEq(xLimbs[i], yLimbs[i])
- }
- return equal
-}
-
-// IsZero returns 1 if x == 0, and 0 otherwise.
-func (x *Nat) IsZero() choice {
- // Eliminate bounds checks in the loop.
- size := len(x.limbs)
- xLimbs := x.limbs[:size]
-
- zero := yes
- for i := 0; i < size; i++ {
- zero &= ctEq(xLimbs[i], 0)
- }
- return zero
-}
-
-// cmpGeq returns 1 if x >= y, and 0 otherwise.
-//
-// Both operands must have the same announced length.
-func (x *Nat) cmpGeq(y *Nat) choice {
- // Eliminate bounds checks in the loop.
- size := len(x.limbs)
- xLimbs := x.limbs[:size]
- yLimbs := y.limbs[:size]
-
- var c uint
- for i := 0; i < size; i++ {
- c = (xLimbs[i] - yLimbs[i] - c) >> _W
- }
- // If there was a carry, then subtracting y underflowed, so
- // x is not greater than or equal to y.
- return not(choice(c))
-}
-
-// assign sets x <- y if on == 1, and does nothing otherwise.
-//
-// Both operands must have the same announced length.
-func (x *Nat) assign(on choice, y *Nat) *Nat {
- // Eliminate bounds checks in the loop.
- size := len(x.limbs)
- xLimbs := x.limbs[:size]
- yLimbs := y.limbs[:size]
-
- for i := 0; i < size; i++ {
- xLimbs[i] = ctSelect(on, yLimbs[i], xLimbs[i])
- }
- return x
-}
-
-// add computes x += y if on == 1, and does nothing otherwise. It returns the
-// carry of the addition regardless of on.
-//
-// Both operands must have the same announced length.
-func (x *Nat) add(on choice, y *Nat) (c uint) {
- // Eliminate bounds checks in the loop.
- size := len(x.limbs)
- xLimbs := x.limbs[:size]
- yLimbs := y.limbs[:size]
-
- for i := 0; i < size; i++ {
- res := xLimbs[i] + yLimbs[i] + c
- xLimbs[i] = ctSelect(on, res&_MASK, xLimbs[i])
- c = res >> _W
- }
- return
-}
-
-// sub computes x -= y if on == 1, and does nothing otherwise. It returns the
-// borrow of the subtraction regardless of on.
-//
-// Both operands must have the same announced length.
-func (x *Nat) sub(on choice, y *Nat) (c uint) {
- // Eliminate bounds checks in the loop.
- size := len(x.limbs)
- xLimbs := x.limbs[:size]
- yLimbs := y.limbs[:size]
-
- for i := 0; i < size; i++ {
- res := xLimbs[i] - yLimbs[i] - c
- xLimbs[i] = ctSelect(on, res&_MASK, xLimbs[i])
- c = res >> _W
- }
- return
-}
-
-// Modulus is used for modular arithmetic, precomputing relevant constants.
-//
-// Moduli are assumed to be odd numbers. Moduli can also leak the exact
-// number of bits needed to store their value, and are stored without padding.
-//
-// Their actual value is still kept secret.
-type Modulus struct {
- // The underlying natural number for this modulus.
- //
- // This will be stored without any padding, and shouldn't alias with any
- // other natural number being used.
- nat *Nat
- leading int // number of leading zeros in the modulus
- m0inv uint // -nat.limbs[0]⁻¹ mod _W
- rr *Nat // R*R for montgomeryRepresentation
-}
-
-// rr returns R*R with R = 2^(_W * n) and n = len(m.nat.limbs).
-func rr(m *Modulus) *Nat {
- rr := NewNat().ExpandFor(m)
- // R*R is 2^(2 * _W * n). We can safely get 2^(_W * (n - 1)) by setting the
- // most significant limb to 1. We then get to R*R by shifting left by _W
- // n + 1 times.
- n := len(rr.limbs)
- rr.limbs[n-1] = 1
- for i := n - 1; i < 2*n; i++ {
- rr.shiftIn(0, m) // x = x * 2^_W mod m
- }
- return rr
-}
-
-// minusInverseModW computes -x⁻¹ mod _W with x odd.
-//
-// This operation is used to precompute a constant involved in Montgomery
-// multiplication.
-func minusInverseModW(x uint) uint {
- // Every iteration of this loop doubles the least-significant bits of
- // correct inverse in y. The first three bits are already correct (1⁻¹ = 1,
- // 3⁻¹ = 3, 5⁻¹ = 5, and 7⁻¹ = 7 mod 8), so doubling five times is enough
- // for 61 bits (and wastes only one iteration for 31 bits).
- //
- // See https://crypto.stackexchange.com/a/47496.
- y := x
- for i := 0; i < 5; i++ {
- y = y * (2 - x*y)
- }
- return (1 << _W) - (y & _MASK)
-}
-
-// NewModulusFromBig creates a new Modulus from a [big.Int].
-//
-// The Int must be odd. The number of significant bits must be leakable.
-func NewModulusFromBig(n *big.Int) *Modulus {
- m := &Modulus{}
- m.nat = NewNat().setBig(n)
- m.leading = _W - bitLen(m.nat.limbs[len(m.nat.limbs)-1])
- m.m0inv = minusInverseModW(m.nat.limbs[0])
- m.rr = rr(m)
- return m
-}
-
-// bitLen is a version of bits.Len that only leaks the bit length of n, but not
-// its value. bits.Len and bits.LeadingZeros use a lookup table for the
-// low-order bits on some architectures.
-func bitLen(n uint) int {
- var len int
- // We assume, here and elsewhere, that comparison to zero is constant time
- // with respect to different non-zero values.
- for n != 0 {
- len++
- n >>= 1
- }
- return len
-}
-
-// Size returns the size of m in bytes.
-func (m *Modulus) Size() int {
- return (m.BitLen() + 7) / 8
-}
-
-// BitLen returns the size of m in bits.
-func (m *Modulus) BitLen() int {
- return len(m.nat.limbs)*_W - int(m.leading)
-}
-
-// Nat returns m as a Nat. The return value must not be written to.
-func (m *Modulus) Nat() *Nat {
- return m.nat
-}
-
-// shiftIn calculates x = x << _W + y mod m.
-//
-// This assumes that x is already reduced mod m, and that y < 2^_W.
-func (x *Nat) shiftIn(y uint, m *Modulus) *Nat {
- d := NewNat().resetFor(m)
-
- // Eliminate bounds checks in the loop.
- size := len(m.nat.limbs)
- xLimbs := x.limbs[:size]
- dLimbs := d.limbs[:size]
- mLimbs := m.nat.limbs[:size]
-
- // Each iteration of this loop computes x = 2x + b mod m, where b is a bit
- // from y. Effectively, it left-shifts x and adds y one bit at a time,
- // reducing it every time.
- //
- // To do the reduction, each iteration computes both 2x + b and 2x + b - m.
- // The next iteration (and finally the return line) will use either result
- // based on whether the subtraction underflowed.
- needSubtraction := no
- for i := _W - 1; i >= 0; i-- {
- carry := (y >> i) & 1
- var borrow uint
- for i := 0; i < size; i++ {
- l := ctSelect(needSubtraction, dLimbs[i], xLimbs[i])
-
- res := l<<1 + carry
- xLimbs[i] = res & _MASK
- carry = res >> _W
-
- res = xLimbs[i] - mLimbs[i] - borrow
- dLimbs[i] = res & _MASK
- borrow = res >> _W
- }
- // See Add for how carry (aka overflow), borrow (aka underflow), and
- // needSubtraction relate.
- needSubtraction = ctEq(carry, borrow)
- }
- return x.assign(needSubtraction, d)
-}
-
-// Mod calculates out = x mod m.
-//
-// This works regardless how large the value of x is.
-//
-// The output will be resized to the size of m and overwritten.
-func (out *Nat) Mod(x *Nat, m *Modulus) *Nat {
- out.resetFor(m)
- // Working our way from the most significant to the least significant limb,
- // we can insert each limb at the least significant position, shifting all
- // previous limbs left by _W. This way each limb will get shifted by the
- // correct number of bits. We can insert at least N - 1 limbs without
- // overflowing m. After that, we need to reduce every time we shift.
- i := len(x.limbs) - 1
- // For the first N - 1 limbs we can skip the actual shifting and position
- // them at the shifted position, which starts at min(N - 2, i).
- start := len(m.nat.limbs) - 2
- if i < start {
- start = i
- }
- for j := start; j >= 0; j-- {
- out.limbs[j] = x.limbs[i]
- i--
- }
- // We shift in the remaining limbs, reducing modulo m each time.
- for i >= 0 {
- out.shiftIn(x.limbs[i], m)
- i--
- }
- return out
-}
-
-// ExpandFor ensures out has the right size to work with operations modulo m.
-//
-// The announced size of out must be smaller than or equal to that of m.
-func (out *Nat) ExpandFor(m *Modulus) *Nat {
- return out.expand(len(m.nat.limbs))
-}
-
-// resetFor ensures out has the right size to work with operations modulo m.
-//
-// out is zeroed and may start at any size.
-func (out *Nat) resetFor(m *Modulus) *Nat {
- return out.reset(len(m.nat.limbs))
-}
-
-// Sub computes x = x - y mod m.
-//
-// The length of both operands must be the same as the modulus. Both operands
-// must already be reduced modulo m.
-func (x *Nat) Sub(y *Nat, m *Modulus) *Nat {
- underflow := x.sub(yes, y)
- // If the subtraction underflowed, add m.
- x.add(choice(underflow), m.nat)
- return x
-}
-
-// Add computes x = x + y mod m.
-//
-// The length of both operands must be the same as the modulus. Both operands
-// must already be reduced modulo m.
-func (x *Nat) Add(y *Nat, m *Modulus) *Nat {
- overflow := x.add(yes, y)
- underflow := not(x.cmpGeq(m.nat)) // x < m
-
- // Three cases are possible:
- //
- // - overflow = 0, underflow = 0
- //
- // In this case, addition fits in our limbs, but we can still subtract away
- // m without an underflow, so we need to perform the subtraction to reduce
- // our result.
- //
- // - overflow = 0, underflow = 1
- //
- // The addition fits in our limbs, but we can't subtract m without
- // underflowing. The result is already reduced.
- //
- // - overflow = 1, underflow = 1
- //
- // The addition does not fit in our limbs, and the subtraction's borrow
- // would cancel out with the addition's carry. We need to subtract m to
- // reduce our result.
- //
- // The overflow = 1, underflow = 0 case is not possible, because y is at
- // most m - 1, and if adding m - 1 overflows, then subtracting m must
- // necessarily underflow.
- needSubtraction := ctEq(overflow, uint(underflow))
-
- x.sub(needSubtraction, m.nat)
- return x
-}
-
-// montgomeryRepresentation calculates x = x * R mod m, with R = 2^(_W * n) and
-// n = len(m.nat.limbs).
-//
-// Faster Montgomery multiplication replaces standard modular multiplication for
-// numbers in this representation.
-//
-// This assumes that x is already reduced mod m.
-func (x *Nat) montgomeryRepresentation(m *Modulus) *Nat {
- // A Montgomery multiplication (which computes a * b / R) by R * R works out
- // to a multiplication by R, which takes the value out of the Montgomery domain.
- return x.montgomeryMul(NewNat().set(x), m.rr, m)
-}
-
-// montgomeryReduction calculates x = x / R mod m, with R = 2^(_W * n) and
-// n = len(m.nat.limbs).
-//
-// This assumes that x is already reduced mod m.
-func (x *Nat) montgomeryReduction(m *Modulus) *Nat {
- // By Montgomery multiplying with 1 not in Montgomery representation, we
- // convert out back from Montgomery representation, because it works out to
- // dividing by R.
- t0 := NewNat().set(x)
- t1 := NewNat().ExpandFor(m)
- t1.limbs[0] = 1
- return x.montgomeryMul(t0, t1, m)
-}
-
-// montgomeryMul calculates d = a * b / R mod m, with R = 2^(_W * n) and
-// n = len(m.nat.limbs), using the Montgomery Multiplication technique.
-//
-// All inputs should be the same length, not aliasing d, and already
-// reduced modulo m. d will be resized to the size of m and overwritten.
-func (d *Nat) montgomeryMul(a *Nat, b *Nat, m *Modulus) *Nat {
- d.resetFor(m)
- if len(a.limbs) != len(m.nat.limbs) || len(b.limbs) != len(m.nat.limbs) {
- panic("bigmod: invalid montgomeryMul input")
- }
-
- // See https://bearssl.org/bigint.html#montgomery-reduction-and-multiplication
- // for a description of the algorithm implemented mostly in montgomeryLoop.
- // See Add for how overflow, underflow, and needSubtraction relate.
- overflow := montgomeryLoop(d.limbs, a.limbs, b.limbs, m.nat.limbs, m.m0inv)
- underflow := not(d.cmpGeq(m.nat)) // d < m
- needSubtraction := ctEq(overflow, uint(underflow))
- d.sub(needSubtraction, m.nat)
-
- return d
-}
-
-func montgomeryLoopGeneric(d, a, b, m []uint, m0inv uint) (overflow uint) {
- // Eliminate bounds checks in the loop.
- size := len(d)
- a = a[:size]
- b = b[:size]
- m = m[:size]
-
- for _, ai := range a {
- // This is an unrolled iteration of the loop below with j = 0.
- hi, lo := bits.Mul(ai, b[0])
- z_lo, c := bits.Add(d[0], lo, 0)
- f := (z_lo * m0inv) & _MASK // (d[0] + a[i] * b[0]) * m0inv
- z_hi, _ := bits.Add(0, hi, c)
- hi, lo = bits.Mul(f, m[0])
- z_lo, c = bits.Add(z_lo, lo, 0)
- z_hi, _ = bits.Add(z_hi, hi, c)
- carry := z_hi<<1 | z_lo>>_W
-
- for j := 1; j < size; j++ {
- // z = d[j] + a[i] * b[j] + f * m[j] + carry <= 2^(2W+1) - 2^(W+1) + 2^W
- hi, lo := bits.Mul(ai, b[j])
- z_lo, c := bits.Add(d[j], lo, 0)
- z_hi, _ := bits.Add(0, hi, c)
- hi, lo = bits.Mul(f, m[j])
- z_lo, c = bits.Add(z_lo, lo, 0)
- z_hi, _ = bits.Add(z_hi, hi, c)
- z_lo, c = bits.Add(z_lo, carry, 0)
- z_hi, _ = bits.Add(z_hi, 0, c)
- d[j-1] = z_lo & _MASK
- carry = z_hi<<1 | z_lo>>_W // carry <= 2^(W+1) - 2
- }
-
- z := overflow + carry // z <= 2^(W+1) - 1
- d[size-1] = z & _MASK
- overflow = z >> _W // overflow <= 1
- }
- return
-}
-
-// Mul calculates x *= y mod m.
-//
-// x and y must already be reduced modulo m, they must share its announced
-// length, and they may not alias.
-func (x *Nat) Mul(y *Nat, m *Modulus) *Nat {
- // A Montgomery multiplication by a value out of the Montgomery domain
- // takes the result out of Montgomery representation.
- xR := NewNat().set(x).montgomeryRepresentation(m) // xR = x * R mod m
- return x.montgomeryMul(xR, y, m) // x = xR * y / R mod m
-}
-
-// Exp calculates out = x^e mod m.
-//
-// The exponent e is represented in big-endian order. The output will be resized
-// to the size of m and overwritten. x must already be reduced modulo m.
-func (out *Nat) Exp(x *Nat, e []byte, m *Modulus) *Nat {
- // We use a 4 bit window. For our RSA workload, 4 bit windows are faster
- // than 2 bit windows, but use an extra 12 nats worth of scratch space.
- // Using bit sizes that don't divide 8 are more complex to implement.
-
- table := [(1 << 4) - 1]*Nat{ // table[i] = x ^ (i+1)
- // newNat calls are unrolled so they are allocated on the stack.
- NewNat(), NewNat(), NewNat(), NewNat(), NewNat(),
- NewNat(), NewNat(), NewNat(), NewNat(), NewNat(),
- NewNat(), NewNat(), NewNat(), NewNat(), NewNat(),
- }
- table[0].set(x).montgomeryRepresentation(m)
- for i := 1; i < len(table); i++ {
- table[i].montgomeryMul(table[i-1], table[0], m)
- }
-
- out.resetFor(m)
- out.limbs[0] = 1
- out.montgomeryRepresentation(m)
- t0 := NewNat().ExpandFor(m)
- t1 := NewNat().ExpandFor(m)
- for _, b := range e {
- for _, j := range []int{4, 0} {
- // Square four times.
- t1.montgomeryMul(out, out, m)
- out.montgomeryMul(t1, t1, m)
- t1.montgomeryMul(out, out, m)
- out.montgomeryMul(t1, t1, m)
-
- // Select x^k in constant time from the table.
- k := uint((b >> j) & 0b1111)
- for i := range table {
- t0.assign(ctEq(k, uint(i+1)), table[i])
- }
-
- // Multiply by x^k, discarding the result if k = 0.
- t1.montgomeryMul(out, t0, m)
- out.assign(not(ctEq(k, 0)), t1)
- }
- }
-
- return out.montgomeryReduction(m)
-}
diff --git a/contrib/go/_std_1.20/src/crypto/internal/bigmod/nat_amd64.go b/contrib/go/_std_1.20/src/crypto/internal/bigmod/nat_amd64.go
deleted file mode 100644
index e94778245d..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/bigmod/nat_amd64.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Code generated by command: go run nat_amd64_asm.go -out ../nat_amd64.s -stubs ../nat_amd64.go -pkg bigmod. DO NOT EDIT.
-
-//go:build amd64 && gc && !purego
-
-package bigmod
-
-//go:noescape
-func montgomeryLoop(d []uint, a []uint, b []uint, m []uint, m0inv uint) uint
diff --git a/contrib/go/_std_1.20/src/crypto/internal/bigmod/nat_amd64.s b/contrib/go/_std_1.20/src/crypto/internal/bigmod/nat_amd64.s
deleted file mode 100644
index 12b7629984..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/bigmod/nat_amd64.s
+++ /dev/null
@@ -1,68 +0,0 @@
-// Code generated by command: go run nat_amd64_asm.go -out ../nat_amd64.s -stubs ../nat_amd64.go -pkg bigmod. DO NOT EDIT.
-
-//go:build amd64 && gc && !purego
-
-// func montgomeryLoop(d []uint, a []uint, b []uint, m []uint, m0inv uint) uint
-TEXT ·montgomeryLoop(SB), $8-112
- MOVQ d_len+8(FP), CX
- MOVQ d_base+0(FP), BX
- MOVQ b_base+48(FP), SI
- MOVQ m_base+72(FP), DI
- MOVQ m0inv+96(FP), R8
- XORQ R9, R9
- XORQ R10, R10
-
-outerLoop:
- MOVQ a_base+24(FP), R11
- MOVQ (R11)(R10*8), R11
- MOVQ (SI), AX
- MULQ R11
- MOVQ AX, R13
- MOVQ DX, R12
- ADDQ (BX), R13
- ADCQ $0x00, R12
- MOVQ R8, R14
- IMULQ R13, R14
- BTRQ $0x3f, R14
- MOVQ (DI), AX
- MULQ R14
- ADDQ AX, R13
- ADCQ DX, R12
- SHRQ $0x3f, R12, R13
- XORQ R12, R12
- INCQ R12
- JMP innerLoopCondition
-
-innerLoop:
- MOVQ (SI)(R12*8), AX
- MULQ R11
- MOVQ AX, BP
- MOVQ DX, R15
- MOVQ (DI)(R12*8), AX
- MULQ R14
- ADDQ AX, BP
- ADCQ DX, R15
- ADDQ (BX)(R12*8), BP
- ADCQ $0x00, R15
- ADDQ R13, BP
- ADCQ $0x00, R15
- MOVQ BP, AX
- BTRQ $0x3f, AX
- MOVQ AX, -8(BX)(R12*8)
- SHRQ $0x3f, R15, BP
- MOVQ BP, R13
- INCQ R12
-
-innerLoopCondition:
- CMPQ CX, R12
- JGT innerLoop
- ADDQ R13, R9
- MOVQ R9, AX
- BTRQ $0x3f, AX
- MOVQ AX, -8(BX)(CX*8)
- SHRQ $0x3f, R9
- INCQ R10
- CMPQ CX, R10
- JGT outerLoop
- MOVQ R9, ret+104(FP)
- RET
diff --git a/contrib/go/_std_1.20/src/crypto/internal/bigmod/nat_noasm.go b/contrib/go/_std_1.20/src/crypto/internal/bigmod/nat_noasm.go
deleted file mode 100644
index 870b44519d..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/bigmod/nat_noasm.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2022 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.
-
-//go:build !amd64 || !gc || purego
-
-package bigmod
-
-func montgomeryLoop(d, a, b, m []uint, m0inv uint) uint {
- return montgomeryLoopGeneric(d, a, b, m, m0inv)
-}
diff --git a/contrib/go/_std_1.20/src/crypto/internal/bigmod/ya.make b/contrib/go/_std_1.20/src/crypto/internal/bigmod/ya.make
deleted file mode 100644
index 64ebe96b0d..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/bigmod/ya.make
+++ /dev/null
@@ -1,20 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- nat.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- nat_noasm.go
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- nat_amd64.go
- nat_amd64.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/internal/boring/bcache/ya.make b/contrib/go/_std_1.20/src/crypto/internal/boring/bcache/ya.make
deleted file mode 100644
index c81c5411ec..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/boring/bcache/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- cache.go
- stub.s
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/internal/boring/sig/ya.make b/contrib/go/_std_1.20/src/crypto/internal/boring/sig/ya.make
deleted file mode 100644
index ee1f72e64a..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/boring/sig/ya.make
+++ /dev/null
@@ -1,19 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- sig.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- sig_other.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- sig_amd64.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/internal/boring/ya.make b/contrib/go/_std_1.20/src/crypto/internal/boring/ya.make
deleted file mode 100644
index ebbf201ef2..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/boring/ya.make
+++ /dev/null
@@ -1,15 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- doc.go
- goboringcrypto.h
- notboring.go
-)
-
-END()
-
-RECURSE(
- bbig
- bcache
- sig
-)
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/edwards25519.go b/contrib/go/_std_1.20/src/crypto/internal/edwards25519/edwards25519.go
deleted file mode 100644
index 71e9c097a9..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/edwards25519.go
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright (c) 2017 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 edwards25519
-
-import (
- "crypto/internal/edwards25519/field"
- "errors"
-)
-
-// Point types.
-
-type projP1xP1 struct {
- X, Y, Z, T field.Element
-}
-
-type projP2 struct {
- X, Y, Z field.Element
-}
-
-// Point represents a point on the edwards25519 curve.
-//
-// This type works similarly to math/big.Int, and all arguments and receivers
-// are allowed to alias.
-//
-// The zero value is NOT valid, and it may be used only as a receiver.
-type Point struct {
- // The point is internally represented in extended coordinates (X, Y, Z, T)
- // where x = X/Z, y = Y/Z, and xy = T/Z per https://eprint.iacr.org/2008/522.
- x, y, z, t field.Element
-
- // Make the type not comparable (i.e. used with == or as a map key), as
- // equivalent points can be represented by different Go values.
- _ incomparable
-}
-
-type incomparable [0]func()
-
-func checkInitialized(points ...*Point) {
- for _, p := range points {
- if p.x == (field.Element{}) && p.y == (field.Element{}) {
- panic("edwards25519: use of uninitialized Point")
- }
- }
-}
-
-type projCached struct {
- YplusX, YminusX, Z, T2d field.Element
-}
-
-type affineCached struct {
- YplusX, YminusX, T2d field.Element
-}
-
-// Constructors.
-
-func (v *projP2) Zero() *projP2 {
- v.X.Zero()
- v.Y.One()
- v.Z.One()
- return v
-}
-
-// identity is the point at infinity.
-var identity, _ = new(Point).SetBytes([]byte{
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
-
-// NewIdentityPoint returns a new Point set to the identity.
-func NewIdentityPoint() *Point {
- return new(Point).Set(identity)
-}
-
-// generator is the canonical curve basepoint. See TestGenerator for the
-// correspondence of this encoding with the values in RFC 8032.
-var generator, _ = new(Point).SetBytes([]byte{
- 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66})
-
-// NewGeneratorPoint returns a new Point set to the canonical generator.
-func NewGeneratorPoint() *Point {
- return new(Point).Set(generator)
-}
-
-func (v *projCached) Zero() *projCached {
- v.YplusX.One()
- v.YminusX.One()
- v.Z.One()
- v.T2d.Zero()
- return v
-}
-
-func (v *affineCached) Zero() *affineCached {
- v.YplusX.One()
- v.YminusX.One()
- v.T2d.Zero()
- return v
-}
-
-// Assignments.
-
-// Set sets v = u, and returns v.
-func (v *Point) Set(u *Point) *Point {
- *v = *u
- return v
-}
-
-// Encoding.
-
-// Bytes returns the canonical 32-byte encoding of v, according to RFC 8032,
-// Section 5.1.2.
-func (v *Point) Bytes() []byte {
- // This function is outlined to make the allocations inline in the caller
- // rather than happen on the heap.
- var buf [32]byte
- return v.bytes(&buf)
-}
-
-func (v *Point) bytes(buf *[32]byte) []byte {
- checkInitialized(v)
-
- var zInv, x, y field.Element
- zInv.Invert(&v.z) // zInv = 1 / Z
- x.Multiply(&v.x, &zInv) // x = X / Z
- y.Multiply(&v.y, &zInv) // y = Y / Z
-
- out := copyFieldElement(buf, &y)
- out[31] |= byte(x.IsNegative() << 7)
- return out
-}
-
-var feOne = new(field.Element).One()
-
-// SetBytes sets v = x, where x is a 32-byte encoding of v. If x does not
-// represent a valid point on the curve, SetBytes returns nil and an error and
-// the receiver is unchanged. Otherwise, SetBytes returns v.
-//
-// Note that SetBytes accepts all non-canonical encodings of valid points.
-// That is, it follows decoding rules that match most implementations in
-// the ecosystem rather than RFC 8032.
-func (v *Point) SetBytes(x []byte) (*Point, error) {
- // Specifically, the non-canonical encodings that are accepted are
- // 1) the ones where the field element is not reduced (see the
- // (*field.Element).SetBytes docs) and
- // 2) the ones where the x-coordinate is zero and the sign bit is set.
- //
- // Read more at https://hdevalence.ca/blog/2020-10-04-its-25519am,
- // specifically the "Canonical A, R" section.
-
- y, err := new(field.Element).SetBytes(x)
- if err != nil {
- return nil, errors.New("edwards25519: invalid point encoding length")
- }
-
- // -x² + y² = 1 + dx²y²
- // x² + dx²y² = x²(dy² + 1) = y² - 1
- // x² = (y² - 1) / (dy² + 1)
-
- // u = y² - 1
- y2 := new(field.Element).Square(y)
- u := new(field.Element).Subtract(y2, feOne)
-
- // v = dy² + 1
- vv := new(field.Element).Multiply(y2, d)
- vv = vv.Add(vv, feOne)
-
- // x = +√(u/v)
- xx, wasSquare := new(field.Element).SqrtRatio(u, vv)
- if wasSquare == 0 {
- return nil, errors.New("edwards25519: invalid point encoding")
- }
-
- // Select the negative square root if the sign bit is set.
- xxNeg := new(field.Element).Negate(xx)
- xx = xx.Select(xxNeg, xx, int(x[31]>>7))
-
- v.x.Set(xx)
- v.y.Set(y)
- v.z.One()
- v.t.Multiply(xx, y) // xy = T / Z
-
- return v, nil
-}
-
-func copyFieldElement(buf *[32]byte, v *field.Element) []byte {
- copy(buf[:], v.Bytes())
- return buf[:]
-}
-
-// Conversions.
-
-func (v *projP2) FromP1xP1(p *projP1xP1) *projP2 {
- v.X.Multiply(&p.X, &p.T)
- v.Y.Multiply(&p.Y, &p.Z)
- v.Z.Multiply(&p.Z, &p.T)
- return v
-}
-
-func (v *projP2) FromP3(p *Point) *projP2 {
- v.X.Set(&p.x)
- v.Y.Set(&p.y)
- v.Z.Set(&p.z)
- return v
-}
-
-func (v *Point) fromP1xP1(p *projP1xP1) *Point {
- v.x.Multiply(&p.X, &p.T)
- v.y.Multiply(&p.Y, &p.Z)
- v.z.Multiply(&p.Z, &p.T)
- v.t.Multiply(&p.X, &p.Y)
- return v
-}
-
-func (v *Point) fromP2(p *projP2) *Point {
- v.x.Multiply(&p.X, &p.Z)
- v.y.Multiply(&p.Y, &p.Z)
- v.z.Square(&p.Z)
- v.t.Multiply(&p.X, &p.Y)
- return v
-}
-
-// d is a constant in the curve equation.
-var d, _ = new(field.Element).SetBytes([]byte{
- 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
- 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
- 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
- 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52})
-var d2 = new(field.Element).Add(d, d)
-
-func (v *projCached) FromP3(p *Point) *projCached {
- v.YplusX.Add(&p.y, &p.x)
- v.YminusX.Subtract(&p.y, &p.x)
- v.Z.Set(&p.z)
- v.T2d.Multiply(&p.t, d2)
- return v
-}
-
-func (v *affineCached) FromP3(p *Point) *affineCached {
- v.YplusX.Add(&p.y, &p.x)
- v.YminusX.Subtract(&p.y, &p.x)
- v.T2d.Multiply(&p.t, d2)
-
- var invZ field.Element
- invZ.Invert(&p.z)
- v.YplusX.Multiply(&v.YplusX, &invZ)
- v.YminusX.Multiply(&v.YminusX, &invZ)
- v.T2d.Multiply(&v.T2d, &invZ)
- return v
-}
-
-// (Re)addition and subtraction.
-
-// Add sets v = p + q, and returns v.
-func (v *Point) Add(p, q *Point) *Point {
- checkInitialized(p, q)
- qCached := new(projCached).FromP3(q)
- result := new(projP1xP1).Add(p, qCached)
- return v.fromP1xP1(result)
-}
-
-// Subtract sets v = p - q, and returns v.
-func (v *Point) Subtract(p, q *Point) *Point {
- checkInitialized(p, q)
- qCached := new(projCached).FromP3(q)
- result := new(projP1xP1).Sub(p, qCached)
- return v.fromP1xP1(result)
-}
-
-func (v *projP1xP1) Add(p *Point, q *projCached) *projP1xP1 {
- var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element
-
- YplusX.Add(&p.y, &p.x)
- YminusX.Subtract(&p.y, &p.x)
-
- PP.Multiply(&YplusX, &q.YplusX)
- MM.Multiply(&YminusX, &q.YminusX)
- TT2d.Multiply(&p.t, &q.T2d)
- ZZ2.Multiply(&p.z, &q.Z)
-
- ZZ2.Add(&ZZ2, &ZZ2)
-
- v.X.Subtract(&PP, &MM)
- v.Y.Add(&PP, &MM)
- v.Z.Add(&ZZ2, &TT2d)
- v.T.Subtract(&ZZ2, &TT2d)
- return v
-}
-
-func (v *projP1xP1) Sub(p *Point, q *projCached) *projP1xP1 {
- var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element
-
- YplusX.Add(&p.y, &p.x)
- YminusX.Subtract(&p.y, &p.x)
-
- PP.Multiply(&YplusX, &q.YminusX) // flipped sign
- MM.Multiply(&YminusX, &q.YplusX) // flipped sign
- TT2d.Multiply(&p.t, &q.T2d)
- ZZ2.Multiply(&p.z, &q.Z)
-
- ZZ2.Add(&ZZ2, &ZZ2)
-
- v.X.Subtract(&PP, &MM)
- v.Y.Add(&PP, &MM)
- v.Z.Subtract(&ZZ2, &TT2d) // flipped sign
- v.T.Add(&ZZ2, &TT2d) // flipped sign
- return v
-}
-
-func (v *projP1xP1) AddAffine(p *Point, q *affineCached) *projP1xP1 {
- var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element
-
- YplusX.Add(&p.y, &p.x)
- YminusX.Subtract(&p.y, &p.x)
-
- PP.Multiply(&YplusX, &q.YplusX)
- MM.Multiply(&YminusX, &q.YminusX)
- TT2d.Multiply(&p.t, &q.T2d)
-
- Z2.Add(&p.z, &p.z)
-
- v.X.Subtract(&PP, &MM)
- v.Y.Add(&PP, &MM)
- v.Z.Add(&Z2, &TT2d)
- v.T.Subtract(&Z2, &TT2d)
- return v
-}
-
-func (v *projP1xP1) SubAffine(p *Point, q *affineCached) *projP1xP1 {
- var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element
-
- YplusX.Add(&p.y, &p.x)
- YminusX.Subtract(&p.y, &p.x)
-
- PP.Multiply(&YplusX, &q.YminusX) // flipped sign
- MM.Multiply(&YminusX, &q.YplusX) // flipped sign
- TT2d.Multiply(&p.t, &q.T2d)
-
- Z2.Add(&p.z, &p.z)
-
- v.X.Subtract(&PP, &MM)
- v.Y.Add(&PP, &MM)
- v.Z.Subtract(&Z2, &TT2d) // flipped sign
- v.T.Add(&Z2, &TT2d) // flipped sign
- return v
-}
-
-// Doubling.
-
-func (v *projP1xP1) Double(p *projP2) *projP1xP1 {
- var XX, YY, ZZ2, XplusYsq field.Element
-
- XX.Square(&p.X)
- YY.Square(&p.Y)
- ZZ2.Square(&p.Z)
- ZZ2.Add(&ZZ2, &ZZ2)
- XplusYsq.Add(&p.X, &p.Y)
- XplusYsq.Square(&XplusYsq)
-
- v.Y.Add(&YY, &XX)
- v.Z.Subtract(&YY, &XX)
-
- v.X.Subtract(&XplusYsq, &v.Y)
- v.T.Subtract(&ZZ2, &v.Z)
- return v
-}
-
-// Negation.
-
-// Negate sets v = -p, and returns v.
-func (v *Point) Negate(p *Point) *Point {
- checkInitialized(p)
- v.x.Negate(&p.x)
- v.y.Set(&p.y)
- v.z.Set(&p.z)
- v.t.Negate(&p.t)
- return v
-}
-
-// Equal returns 1 if v is equivalent to u, and 0 otherwise.
-func (v *Point) Equal(u *Point) int {
- checkInitialized(v, u)
-
- var t1, t2, t3, t4 field.Element
- t1.Multiply(&v.x, &u.z)
- t2.Multiply(&u.x, &v.z)
- t3.Multiply(&v.y, &u.z)
- t4.Multiply(&u.y, &v.z)
-
- return t1.Equal(&t2) & t3.Equal(&t4)
-}
-
-// Constant-time operations
-
-// Select sets v to a if cond == 1 and to b if cond == 0.
-func (v *projCached) Select(a, b *projCached, cond int) *projCached {
- v.YplusX.Select(&a.YplusX, &b.YplusX, cond)
- v.YminusX.Select(&a.YminusX, &b.YminusX, cond)
- v.Z.Select(&a.Z, &b.Z, cond)
- v.T2d.Select(&a.T2d, &b.T2d, cond)
- return v
-}
-
-// Select sets v to a if cond == 1 and to b if cond == 0.
-func (v *affineCached) Select(a, b *affineCached, cond int) *affineCached {
- v.YplusX.Select(&a.YplusX, &b.YplusX, cond)
- v.YminusX.Select(&a.YminusX, &b.YminusX, cond)
- v.T2d.Select(&a.T2d, &b.T2d, cond)
- return v
-}
-
-// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0.
-func (v *projCached) CondNeg(cond int) *projCached {
- v.YplusX.Swap(&v.YminusX, cond)
- v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond)
- return v
-}
-
-// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0.
-func (v *affineCached) CondNeg(cond int) *affineCached {
- v.YplusX.Swap(&v.YminusX, cond)
- v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond)
- return v
-}
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_generic.go b/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_generic.go
deleted file mode 100644
index d6667b27be..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_generic.go
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright (c) 2017 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 field
-
-import "math/bits"
-
-// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
-// bits.Mul64 and bits.Add64 intrinsics.
-type uint128 struct {
- lo, hi uint64
-}
-
-// mul64 returns a * b.
-func mul64(a, b uint64) uint128 {
- hi, lo := bits.Mul64(a, b)
- return uint128{lo, hi}
-}
-
-// addMul64 returns v + a * b.
-func addMul64(v uint128, a, b uint64) uint128 {
- hi, lo := bits.Mul64(a, b)
- lo, c := bits.Add64(lo, v.lo, 0)
- hi, _ = bits.Add64(hi, v.hi, c)
- return uint128{lo, hi}
-}
-
-// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits.
-func shiftRightBy51(a uint128) uint64 {
- return (a.hi << (64 - 51)) | (a.lo >> 51)
-}
-
-func feMulGeneric(v, a, b *Element) {
- a0 := a.l0
- a1 := a.l1
- a2 := a.l2
- a3 := a.l3
- a4 := a.l4
-
- b0 := b.l0
- b1 := b.l1
- b2 := b.l2
- b3 := b.l3
- b4 := b.l4
-
- // Limb multiplication works like pen-and-paper columnar multiplication, but
- // with 51-bit limbs instead of digits.
- //
- // a4 a3 a2 a1 a0 x
- // b4 b3 b2 b1 b0 =
- // ------------------------
- // a4b0 a3b0 a2b0 a1b0 a0b0 +
- // a4b1 a3b1 a2b1 a1b1 a0b1 +
- // a4b2 a3b2 a2b2 a1b2 a0b2 +
- // a4b3 a3b3 a2b3 a1b3 a0b3 +
- // a4b4 a3b4 a2b4 a1b4 a0b4 =
- // ----------------------------------------------
- // r8 r7 r6 r5 r4 r3 r2 r1 r0
- //
- // We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to
- // reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5,
- // r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc.
- //
- // Reduction can be carried out simultaneously to multiplication. For
- // example, we do not compute r5: whenever the result of a multiplication
- // belongs to r5, like a1b4, we multiply it by 19 and add the result to r0.
- //
- // a4b0 a3b0 a2b0 a1b0 a0b0 +
- // a3b1 a2b1 a1b1 a0b1 19×a4b1 +
- // a2b2 a1b2 a0b2 19×a4b2 19×a3b2 +
- // a1b3 a0b3 19×a4b3 19×a3b3 19×a2b3 +
- // a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4 =
- // --------------------------------------
- // r4 r3 r2 r1 r0
- //
- // Finally we add up the columns into wide, overlapping limbs.
-
- a1_19 := a1 * 19
- a2_19 := a2 * 19
- a3_19 := a3 * 19
- a4_19 := a4 * 19
-
- // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
- r0 := mul64(a0, b0)
- r0 = addMul64(r0, a1_19, b4)
- r0 = addMul64(r0, a2_19, b3)
- r0 = addMul64(r0, a3_19, b2)
- r0 = addMul64(r0, a4_19, b1)
-
- // r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
- r1 := mul64(a0, b1)
- r1 = addMul64(r1, a1, b0)
- r1 = addMul64(r1, a2_19, b4)
- r1 = addMul64(r1, a3_19, b3)
- r1 = addMul64(r1, a4_19, b2)
-
- // r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
- r2 := mul64(a0, b2)
- r2 = addMul64(r2, a1, b1)
- r2 = addMul64(r2, a2, b0)
- r2 = addMul64(r2, a3_19, b4)
- r2 = addMul64(r2, a4_19, b3)
-
- // r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
- r3 := mul64(a0, b3)
- r3 = addMul64(r3, a1, b2)
- r3 = addMul64(r3, a2, b1)
- r3 = addMul64(r3, a3, b0)
- r3 = addMul64(r3, a4_19, b4)
-
- // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
- r4 := mul64(a0, b4)
- r4 = addMul64(r4, a1, b3)
- r4 = addMul64(r4, a2, b2)
- r4 = addMul64(r4, a3, b1)
- r4 = addMul64(r4, a4, b0)
-
- // After the multiplication, we need to reduce (carry) the five coefficients
- // to obtain a result with limbs that are at most slightly larger than 2⁵¹,
- // to respect the Element invariant.
- //
- // Overall, the reduction works the same as carryPropagate, except with
- // wider inputs: we take the carry for each coefficient by shifting it right
- // by 51, and add it to the limb above it. The top carry is multiplied by 19
- // according to the reduction identity and added to the lowest limb.
- //
- // The largest coefficient (r0) will be at most 111 bits, which guarantees
- // that all carries are at most 111 - 51 = 60 bits, which fits in a uint64.
- //
- // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
- // r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²)
- // r0 < (1 + 19 × 4) × 2⁵² × 2⁵²
- // r0 < 2⁷ × 2⁵² × 2⁵²
- // r0 < 2¹¹¹
- //
- // Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most
- // 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and
- // allows us to easily apply the reduction identity.
- //
- // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
- // r4 < 5 × 2⁵² × 2⁵²
- // r4 < 2¹⁰⁷
- //
-
- c0 := shiftRightBy51(r0)
- c1 := shiftRightBy51(r1)
- c2 := shiftRightBy51(r2)
- c3 := shiftRightBy51(r3)
- c4 := shiftRightBy51(r4)
-
- rr0 := r0.lo&maskLow51Bits + c4*19
- rr1 := r1.lo&maskLow51Bits + c0
- rr2 := r2.lo&maskLow51Bits + c1
- rr3 := r3.lo&maskLow51Bits + c2
- rr4 := r4.lo&maskLow51Bits + c3
-
- // Now all coefficients fit into 64-bit registers but are still too large to
- // be passed around as a Element. We therefore do one last carry chain,
- // where the carries will be small enough to fit in the wiggle room above 2⁵¹.
- *v = Element{rr0, rr1, rr2, rr3, rr4}
- v.carryPropagate()
-}
-
-func feSquareGeneric(v, a *Element) {
- l0 := a.l0
- l1 := a.l1
- l2 := a.l2
- l3 := a.l3
- l4 := a.l4
-
- // Squaring works precisely like multiplication above, but thanks to its
- // symmetry we get to group a few terms together.
- //
- // l4 l3 l2 l1 l0 x
- // l4 l3 l2 l1 l0 =
- // ------------------------
- // l4l0 l3l0 l2l0 l1l0 l0l0 +
- // l4l1 l3l1 l2l1 l1l1 l0l1 +
- // l4l2 l3l2 l2l2 l1l2 l0l2 +
- // l4l3 l3l3 l2l3 l1l3 l0l3 +
- // l4l4 l3l4 l2l4 l1l4 l0l4 =
- // ----------------------------------------------
- // r8 r7 r6 r5 r4 r3 r2 r1 r0
- //
- // l4l0 l3l0 l2l0 l1l0 l0l0 +
- // l3l1 l2l1 l1l1 l0l1 19×l4l1 +
- // l2l2 l1l2 l0l2 19×l4l2 19×l3l2 +
- // l1l3 l0l3 19×l4l3 19×l3l3 19×l2l3 +
- // l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4 =
- // --------------------------------------
- // r4 r3 r2 r1 r0
- //
- // With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with
- // only three Mul64 and four Add64, instead of five and eight.
-
- l0_2 := l0 * 2
- l1_2 := l1 * 2
-
- l1_38 := l1 * 38
- l2_38 := l2 * 38
- l3_38 := l3 * 38
-
- l3_19 := l3 * 19
- l4_19 := l4 * 19
-
- // r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3)
- r0 := mul64(l0, l0)
- r0 = addMul64(r0, l1_38, l4)
- r0 = addMul64(r0, l2_38, l3)
-
- // r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
- r1 := mul64(l0_2, l1)
- r1 = addMul64(r1, l2_38, l4)
- r1 = addMul64(r1, l3_19, l3)
-
- // r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4
- r2 := mul64(l0_2, l2)
- r2 = addMul64(r2, l1, l1)
- r2 = addMul64(r2, l3_38, l4)
-
- // r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
- r3 := mul64(l0_2, l3)
- r3 = addMul64(r3, l1_2, l2)
- r3 = addMul64(r3, l4_19, l4)
-
- // r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2
- r4 := mul64(l0_2, l4)
- r4 = addMul64(r4, l1_2, l3)
- r4 = addMul64(r4, l2, l2)
-
- c0 := shiftRightBy51(r0)
- c1 := shiftRightBy51(r1)
- c2 := shiftRightBy51(r2)
- c3 := shiftRightBy51(r3)
- c4 := shiftRightBy51(r4)
-
- rr0 := r0.lo&maskLow51Bits + c4*19
- rr1 := r1.lo&maskLow51Bits + c0
- rr2 := r2.lo&maskLow51Bits + c1
- rr3 := r3.lo&maskLow51Bits + c2
- rr4 := r4.lo&maskLow51Bits + c3
-
- *v = Element{rr0, rr1, rr2, rr3, rr4}
- v.carryPropagate()
-}
-
-// carryPropagate brings the limbs below 52 bits by applying the reduction
-// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry.
-func (v *Element) carryPropagateGeneric() *Element {
- c0 := v.l0 >> 51
- c1 := v.l1 >> 51
- c2 := v.l2 >> 51
- c3 := v.l3 >> 51
- c4 := v.l4 >> 51
-
- // c4 is at most 64 - 51 = 13 bits, so c4*19 is at most 18 bits, and
- // the final l0 will be at most 52 bits. Similarly for the rest.
- v.l0 = v.l0&maskLow51Bits + c4*19
- v.l1 = v.l1&maskLow51Bits + c0
- v.l2 = v.l2&maskLow51Bits + c1
- v.l3 = v.l3&maskLow51Bits + c2
- v.l4 = v.l4&maskLow51Bits + c3
-
- return v
-}
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/ya.make b/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/ya.make
deleted file mode 100644
index b49bda6b63..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/ya.make
+++ /dev/null
@@ -1,28 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- fe.go
- fe_generic.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- fe_amd64_noasm.go
- fe_arm64.go
- fe_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- fe_amd64.go
- fe_amd64.s
- fe_arm64_noasm.go
- )
-ENDIF()
-
-END()
-
-#RECURSE(
-# _asm
-#)
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/scalar.go b/contrib/go/_std_1.20/src/crypto/internal/edwards25519/scalar.go
deleted file mode 100644
index d34ecea33e..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/scalar.go
+++ /dev/null
@@ -1,343 +0,0 @@
-// Copyright (c) 2016 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 edwards25519
-
-import (
- "encoding/binary"
- "errors"
-)
-
-// A Scalar is an integer modulo
-//
-// l = 2^252 + 27742317777372353535851937790883648493
-//
-// which is the prime order of the edwards25519 group.
-//
-// This type works similarly to math/big.Int, and all arguments and
-// receivers are allowed to alias.
-//
-// The zero value is a valid zero element.
-type Scalar struct {
- // s is the scalar in the Montgomery domain, in the format of the
- // fiat-crypto implementation.
- s fiatScalarMontgomeryDomainFieldElement
-}
-
-// The field implementation in scalar_fiat.go is generated by the fiat-crypto
-// project (https://github.com/mit-plv/fiat-crypto) at version v0.0.9 (23d2dbc)
-// from a formally verified model.
-//
-// fiat-crypto code comes under the following license.
-//
-// Copyright (c) 2015-2020 The fiat-crypto Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// THIS SOFTWARE IS PROVIDED BY the fiat-crypto authors "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design,
-// Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-
-// NewScalar returns a new zero Scalar.
-func NewScalar() *Scalar {
- return &Scalar{}
-}
-
-// MultiplyAdd sets s = x * y + z mod l, and returns s. It is equivalent to
-// using Multiply and then Add.
-func (s *Scalar) MultiplyAdd(x, y, z *Scalar) *Scalar {
- // Make a copy of z in case it aliases s.
- zCopy := new(Scalar).Set(z)
- return s.Multiply(x, y).Add(s, zCopy)
-}
-
-// Add sets s = x + y mod l, and returns s.
-func (s *Scalar) Add(x, y *Scalar) *Scalar {
- // s = 1 * x + y mod l
- fiatScalarAdd(&s.s, &x.s, &y.s)
- return s
-}
-
-// Subtract sets s = x - y mod l, and returns s.
-func (s *Scalar) Subtract(x, y *Scalar) *Scalar {
- // s = -1 * y + x mod l
- fiatScalarSub(&s.s, &x.s, &y.s)
- return s
-}
-
-// Negate sets s = -x mod l, and returns s.
-func (s *Scalar) Negate(x *Scalar) *Scalar {
- // s = -1 * x + 0 mod l
- fiatScalarOpp(&s.s, &x.s)
- return s
-}
-
-// Multiply sets s = x * y mod l, and returns s.
-func (s *Scalar) Multiply(x, y *Scalar) *Scalar {
- // s = x * y + 0 mod l
- fiatScalarMul(&s.s, &x.s, &y.s)
- return s
-}
-
-// Set sets s = x, and returns s.
-func (s *Scalar) Set(x *Scalar) *Scalar {
- *s = *x
- return s
-}
-
-// SetUniformBytes sets s = x mod l, where x is a 64-byte little-endian integer.
-// If x is not of the right length, SetUniformBytes returns nil and an error,
-// and the receiver is unchanged.
-//
-// SetUniformBytes can be used to set s to an uniformly distributed value given
-// 64 uniformly distributed random bytes.
-func (s *Scalar) SetUniformBytes(x []byte) (*Scalar, error) {
- if len(x) != 64 {
- return nil, errors.New("edwards25519: invalid SetUniformBytes input length")
- }
-
- // We have a value x of 512 bits, but our fiatScalarFromBytes function
- // expects an input lower than l, which is a little over 252 bits.
- //
- // Instead of writing a reduction function that operates on wider inputs, we
- // can interpret x as the sum of three shorter values a, b, and c.
- //
- // x = a + b * 2^168 + c * 2^336 mod l
- //
- // We then precompute 2^168 and 2^336 modulo l, and perform the reduction
- // with two multiplications and two additions.
-
- s.setShortBytes(x[:21])
- t := new(Scalar).setShortBytes(x[21:42])
- s.Add(s, t.Multiply(t, scalarTwo168))
- t.setShortBytes(x[42:])
- s.Add(s, t.Multiply(t, scalarTwo336))
-
- return s, nil
-}
-
-// scalarTwo168 and scalarTwo336 are 2^168 and 2^336 modulo l, encoded as a
-// fiatScalarMontgomeryDomainFieldElement, which is a little-endian 4-limb value
-// in the 2^256 Montgomery domain.
-var scalarTwo168 = &Scalar{s: [4]uint64{0x5b8ab432eac74798, 0x38afddd6de59d5d7,
- 0xa2c131b399411b7c, 0x6329a7ed9ce5a30}}
-var scalarTwo336 = &Scalar{s: [4]uint64{0xbd3d108e2b35ecc5, 0x5c3a3718bdf9c90b,
- 0x63aa97a331b4f2ee, 0x3d217f5be65cb5c}}
-
-// setShortBytes sets s = x mod l, where x is a little-endian integer shorter
-// than 32 bytes.
-func (s *Scalar) setShortBytes(x []byte) *Scalar {
- if len(x) >= 32 {
- panic("edwards25519: internal error: setShortBytes called with a long string")
- }
- var buf [32]byte
- copy(buf[:], x)
- fiatScalarFromBytes((*[4]uint64)(&s.s), &buf)
- fiatScalarToMontgomery(&s.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&s.s))
- return s
-}
-
-// SetCanonicalBytes sets s = x, where x is a 32-byte little-endian encoding of
-// s, and returns s. If x is not a canonical encoding of s, SetCanonicalBytes
-// returns nil and an error, and the receiver is unchanged.
-func (s *Scalar) SetCanonicalBytes(x []byte) (*Scalar, error) {
- if len(x) != 32 {
- return nil, errors.New("invalid scalar length")
- }
- if !isReduced(x) {
- return nil, errors.New("invalid scalar encoding")
- }
-
- fiatScalarFromBytes((*[4]uint64)(&s.s), (*[32]byte)(x))
- fiatScalarToMontgomery(&s.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&s.s))
-
- return s, nil
-}
-
-// scalarMinusOneBytes is l - 1 in little endian.
-var scalarMinusOneBytes = [32]byte{236, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16}
-
-// isReduced returns whether the given scalar in 32-byte little endian encoded
-// form is reduced modulo l.
-func isReduced(s []byte) bool {
- if len(s) != 32 {
- return false
- }
-
- for i := len(s) - 1; i >= 0; i-- {
- switch {
- case s[i] > scalarMinusOneBytes[i]:
- return false
- case s[i] < scalarMinusOneBytes[i]:
- return true
- }
- }
- return true
-}
-
-// SetBytesWithClamping applies the buffer pruning described in RFC 8032,
-// Section 5.1.5 (also known as clamping) and sets s to the result. The input
-// must be 32 bytes, and it is not modified. If x is not of the right length,
-// SetBytesWithClamping returns nil and an error, and the receiver is unchanged.
-//
-// Note that since Scalar values are always reduced modulo the prime order of
-// the curve, the resulting value will not preserve any of the cofactor-clearing
-// properties that clamping is meant to provide. It will however work as
-// expected as long as it is applied to points on the prime order subgroup, like
-// in Ed25519. In fact, it is lost to history why RFC 8032 adopted the
-// irrelevant RFC 7748 clamping, but it is now required for compatibility.
-func (s *Scalar) SetBytesWithClamping(x []byte) (*Scalar, error) {
- // The description above omits the purpose of the high bits of the clamping
- // for brevity, but those are also lost to reductions, and are also
- // irrelevant to edwards25519 as they protect against a specific
- // implementation bug that was once observed in a generic Montgomery ladder.
- if len(x) != 32 {
- return nil, errors.New("edwards25519: invalid SetBytesWithClamping input length")
- }
-
- // We need to use the wide reduction from SetUniformBytes, since clamping
- // sets the 2^254 bit, making the value higher than the order.
- var wideBytes [64]byte
- copy(wideBytes[:], x[:])
- wideBytes[0] &= 248
- wideBytes[31] &= 63
- wideBytes[31] |= 64
- return s.SetUniformBytes(wideBytes[:])
-}
-
-// Bytes returns the canonical 32-byte little-endian encoding of s.
-func (s *Scalar) Bytes() []byte {
- // This function is outlined to make the allocations inline in the caller
- // rather than happen on the heap.
- var encoded [32]byte
- return s.bytes(&encoded)
-}
-
-func (s *Scalar) bytes(out *[32]byte) []byte {
- var ss fiatScalarNonMontgomeryDomainFieldElement
- fiatScalarFromMontgomery(&ss, &s.s)
- fiatScalarToBytes(out, (*[4]uint64)(&ss))
- return out[:]
-}
-
-// Equal returns 1 if s and t are equal, and 0 otherwise.
-func (s *Scalar) Equal(t *Scalar) int {
- var diff fiatScalarMontgomeryDomainFieldElement
- fiatScalarSub(&diff, &s.s, &t.s)
- var nonzero uint64
- fiatScalarNonzero(&nonzero, (*[4]uint64)(&diff))
- nonzero |= nonzero >> 32
- nonzero |= nonzero >> 16
- nonzero |= nonzero >> 8
- nonzero |= nonzero >> 4
- nonzero |= nonzero >> 2
- nonzero |= nonzero >> 1
- return int(^nonzero) & 1
-}
-
-// nonAdjacentForm computes a width-w non-adjacent form for this scalar.
-//
-// w must be between 2 and 8, or nonAdjacentForm will panic.
-func (s *Scalar) nonAdjacentForm(w uint) [256]int8 {
- // This implementation is adapted from the one
- // in curve25519-dalek and is documented there:
- // https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871
- b := s.Bytes()
- if b[31] > 127 {
- panic("scalar has high bit set illegally")
- }
- if w < 2 {
- panic("w must be at least 2 by the definition of NAF")
- } else if w > 8 {
- panic("NAF digits must fit in int8")
- }
-
- var naf [256]int8
- var digits [5]uint64
-
- for i := 0; i < 4; i++ {
- digits[i] = binary.LittleEndian.Uint64(b[i*8:])
- }
-
- width := uint64(1 << w)
- windowMask := uint64(width - 1)
-
- pos := uint(0)
- carry := uint64(0)
- for pos < 256 {
- indexU64 := pos / 64
- indexBit := pos % 64
- var bitBuf uint64
- if indexBit < 64-w {
- // This window's bits are contained in a single u64
- bitBuf = digits[indexU64] >> indexBit
- } else {
- // Combine the current 64 bits with bits from the next 64
- bitBuf = (digits[indexU64] >> indexBit) | (digits[1+indexU64] << (64 - indexBit))
- }
-
- // Add carry into the current window
- window := carry + (bitBuf & windowMask)
-
- if window&1 == 0 {
- // If the window value is even, preserve the carry and continue.
- // Why is the carry preserved?
- // If carry == 0 and window & 1 == 0,
- // then the next carry should be 0
- // If carry == 1 and window & 1 == 0,
- // then bit_buf & 1 == 1 so the next carry should be 1
- pos += 1
- continue
- }
-
- if window < width/2 {
- carry = 0
- naf[pos] = int8(window)
- } else {
- carry = 1
- naf[pos] = int8(window) - int8(width)
- }
-
- pos += w
- }
- return naf
-}
-
-func (s *Scalar) signedRadix16() [64]int8 {
- b := s.Bytes()
- if b[31] > 127 {
- panic("scalar has high bit set illegally")
- }
-
- var digits [64]int8
-
- // Compute unsigned radix-16 digits:
- for i := 0; i < 32; i++ {
- digits[2*i] = int8(b[i] & 15)
- digits[2*i+1] = int8((b[i] >> 4) & 15)
- }
-
- // Recenter coefficients:
- for i := 0; i < 63; i++ {
- carry := (digits[i] + 8) >> 4
- digits[i] -= carry << 4
- digits[i+1] += carry
- }
-
- return digits
-}
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/ya.make b/contrib/go/_std_1.20/src/crypto/internal/edwards25519/ya.make
deleted file mode 100644
index 460f85fa5c..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/ya.make
+++ /dev/null
@@ -1,16 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- doc.go
- edwards25519.go
- scalar.go
- scalar_fiat.go
- scalarmult.go
- tables.go
-)
-
-END()
-
-RECURSE(
- field
-)
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/ya.make b/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/ya.make
deleted file mode 100644
index d15fe35916..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/ya.make
+++ /dev/null
@@ -1,18 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- p224.go
- p224_fiat64.go
- p224_invert.go
- p256.go
- p256_fiat64.go
- p256_invert.go
- p384.go
- p384_fiat64.go
- p384_invert.go
- p521.go
- p521_fiat64.go
- p521_invert.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/ya.make b/contrib/go/_std_1.20/src/crypto/internal/nistec/ya.make
deleted file mode 100644
index 49fa117357..0000000000
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/ya.make
+++ /dev/null
@@ -1,31 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- nistec.go
- p224.go
- p224_sqrt.go
- p256_asm.go
- p256_ordinv.go
- p384.go
- p521.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- p256_asm_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- p256_asm_amd64.s
- )
-ENDIF()
-
-GO_EMBED_PATTERN(p256_asm_table.bin)
-
-END()
-
-RECURSE(
- fiat
-)
diff --git a/contrib/go/_std_1.20/src/crypto/md5/md5block_decl.go b/contrib/go/_std_1.20/src/crypto/md5/md5block_decl.go
deleted file mode 100644
index 6716a0c9db..0000000000
--- a/contrib/go/_std_1.20/src/crypto/md5/md5block_decl.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 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.
-
-//go:build amd64 || 386 || arm || ppc64le || ppc64 || s390x || arm64
-
-package md5
-
-const haveAsm = true
-
-//go:noescape
-
-func block(dig *digest, p []byte)
diff --git a/contrib/go/_std_1.20/src/crypto/md5/ya.make b/contrib/go/_std_1.20/src/crypto/md5/ya.make
deleted file mode 100644
index 7f1d363332..0000000000
--- a/contrib/go/_std_1.20/src/crypto/md5/ya.make
+++ /dev/null
@@ -1,21 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- md5.go
- md5block.go
- md5block_decl.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- md5block_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- md5block_amd64.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/rand/rand.go b/contrib/go/_std_1.20/src/crypto/rand/rand.go
deleted file mode 100644
index af85b966df..0000000000
--- a/contrib/go/_std_1.20/src/crypto/rand/rand.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2010 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 rand implements a cryptographically secure
-// random number generator.
-package rand
-
-import "io"
-
-// Reader is a global, shared instance of a cryptographically
-// secure random number generator.
-//
-// On Linux, FreeBSD, Dragonfly and Solaris, Reader uses getrandom(2) if
-// available, /dev/urandom otherwise.
-// On OpenBSD and macOS, Reader uses getentropy(2).
-// On other Unix-like systems, Reader reads from /dev/urandom.
-// On Windows systems, Reader uses the RtlGenRandom API.
-// On Wasm, Reader uses the Web Crypto API.
-var Reader io.Reader
-
-// Read is a helper function that calls Reader.Read using io.ReadFull.
-// On return, n == len(b) if and only if err == nil.
-func Read(b []byte) (n int, err error) {
- return io.ReadFull(Reader, b)
-}
-
-// batched returns a function that calls f to populate a []byte by chunking it
-// into subslices of, at most, readMax bytes.
-func batched(f func([]byte) error, readMax int) func([]byte) error {
- return func(out []byte) error {
- for len(out) > 0 {
- read := len(out)
- if read > readMax {
- read = readMax
- }
- if err := f(out[:read]); err != nil {
- return err
- }
- out = out[read:]
- }
- return nil
- }
-}
diff --git a/contrib/go/_std_1.20/src/crypto/rand/rand_getrandom.go b/contrib/go/_std_1.20/src/crypto/rand/rand_getrandom.go
deleted file mode 100644
index 478aa5c459..0000000000
--- a/contrib/go/_std_1.20/src/crypto/rand/rand_getrandom.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2014 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.
-
-//go:build linux || freebsd || dragonfly || solaris
-
-package rand
-
-import (
- "internal/syscall/unix"
- "runtime"
- "syscall"
-)
-
-func init() {
- var maxGetRandomRead int
- switch runtime.GOOS {
- case "linux", "android":
- // Per the manpage:
- // When reading from the urandom source, a maximum of 33554431 bytes
- // is returned by a single call to getrandom() on systems where int
- // has a size of 32 bits.
- maxGetRandomRead = (1 << 25) - 1
- case "freebsd", "dragonfly", "solaris", "illumos":
- maxGetRandomRead = 1 << 8
- default:
- panic("no maximum specified for GetRandom")
- }
- altGetRandom = batched(getRandom, maxGetRandomRead)
-}
-
-// If the kernel is too old to support the getrandom syscall(),
-// unix.GetRandom will immediately return ENOSYS and we will then fall back to
-// reading from /dev/urandom in rand_unix.go. unix.GetRandom caches the ENOSYS
-// result so we only suffer the syscall overhead once in this case.
-// If the kernel supports the getrandom() syscall, unix.GetRandom will block
-// until the kernel has sufficient randomness (as we don't use GRND_NONBLOCK).
-// In this case, unix.GetRandom will not return an error.
-func getRandom(p []byte) error {
- n, err := unix.GetRandom(p, 0)
- if err != nil {
- return err
- }
- if n != len(p) {
- return syscall.EIO
- }
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/crypto/rand/ya.make b/contrib/go/_std_1.20/src/crypto/rand/ya.make
deleted file mode 100644
index 6db711082a..0000000000
--- a/contrib/go/_std_1.20/src/crypto/rand/ya.make
+++ /dev/null
@@ -1,28 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- rand.go
- util.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- rand_getentropy.go
- rand_unix.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- rand_getrandom.go
- rand_unix.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- rand_windows.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/rc4/ya.make b/contrib/go/_std_1.20/src/crypto/rc4/ya.make
deleted file mode 100644
index c1cc0d1a39..0000000000
--- a/contrib/go/_std_1.20/src/crypto/rc4/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- rc4.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/rsa/pkcs1v15.go b/contrib/go/_std_1.20/src/crypto/rsa/pkcs1v15.go
deleted file mode 100644
index e51b9d2ca7..0000000000
--- a/contrib/go/_std_1.20/src/crypto/rsa/pkcs1v15.go
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright 2009 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 rsa
-
-import (
- "crypto"
- "crypto/internal/boring"
- "crypto/internal/randutil"
- "crypto/subtle"
- "errors"
- "io"
-)
-
-// This file implements encryption and decryption using PKCS #1 v1.5 padding.
-
-// PKCS1v15DecryptOptions is for passing options to PKCS #1 v1.5 decryption using
-// the crypto.Decrypter interface.
-type PKCS1v15DecryptOptions struct {
- // SessionKeyLen is the length of the session key that is being
- // decrypted. If not zero, then a padding error during decryption will
- // cause a random plaintext of this length to be returned rather than
- // an error. These alternatives happen in constant time.
- SessionKeyLen int
-}
-
-// EncryptPKCS1v15 encrypts the given message with RSA and the padding
-// scheme from PKCS #1 v1.5. The message must be no longer than the
-// length of the public modulus minus 11 bytes.
-//
-// The random parameter is used as a source of entropy to ensure that
-// encrypting the same message twice doesn't result in the same
-// ciphertext.
-//
-// WARNING: use of this function to encrypt plaintexts other than
-// session keys is dangerous. Use RSA OAEP in new protocols.
-func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, error) {
- randutil.MaybeReadByte(random)
-
- if err := checkPub(pub); err != nil {
- return nil, err
- }
- k := pub.Size()
- if len(msg) > k-11 {
- return nil, ErrMessageTooLong
- }
-
- if boring.Enabled && random == boring.RandReader {
- bkey, err := boringPublicKey(pub)
- if err != nil {
- return nil, err
- }
- return boring.EncryptRSAPKCS1(bkey, msg)
- }
- boring.UnreachableExceptTests()
-
- // EM = 0x00 || 0x02 || PS || 0x00 || M
- em := make([]byte, k)
- em[1] = 2
- ps, mm := em[2:len(em)-len(msg)-1], em[len(em)-len(msg):]
- err := nonZeroRandomBytes(ps, random)
- if err != nil {
- return nil, err
- }
- em[len(em)-len(msg)-1] = 0
- copy(mm, msg)
-
- if boring.Enabled {
- var bkey *boring.PublicKeyRSA
- bkey, err = boringPublicKey(pub)
- if err != nil {
- return nil, err
- }
- return boring.EncryptRSANoPadding(bkey, em)
- }
-
- return encrypt(pub, em)
-}
-
-// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS #1 v1.5.
-// The random parameter is legacy and ignored, and it can be as nil.
-//
-// Note that whether this function returns an error or not discloses secret
-// information. If an attacker can cause this function to run repeatedly and
-// learn whether each instance returned an error then they can decrypt and
-// forge signatures as if they had the private key. See
-// DecryptPKCS1v15SessionKey for a way of solving this problem.
-func DecryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error) {
- if err := checkPub(&priv.PublicKey); err != nil {
- return nil, err
- }
-
- if boring.Enabled {
- bkey, err := boringPrivateKey(priv)
- if err != nil {
- return nil, err
- }
- out, err := boring.DecryptRSAPKCS1(bkey, ciphertext)
- if err != nil {
- return nil, ErrDecryption
- }
- return out, nil
- }
-
- valid, out, index, err := decryptPKCS1v15(priv, ciphertext)
- if err != nil {
- return nil, err
- }
- if valid == 0 {
- return nil, ErrDecryption
- }
- return out[index:], nil
-}
-
-// DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding scheme from PKCS #1 v1.5.
-// The random parameter is legacy and ignored, and it can be as nil.
-// It returns an error if the ciphertext is the wrong length or if the
-// ciphertext is greater than the public modulus. Otherwise, no error is
-// returned. If the padding is valid, the resulting plaintext message is copied
-// into key. Otherwise, key is unchanged. These alternatives occur in constant
-// time. It is intended that the user of this function generate a random
-// session key beforehand and continue the protocol with the resulting value.
-// This will remove any possibility that an attacker can learn any information
-// about the plaintext.
-// See “Chosen Ciphertext Attacks Against Protocols Based on the RSA
-// Encryption Standard PKCS #1”, Daniel Bleichenbacher, Advances in Cryptology
-// (Crypto '98).
-//
-// Note that if the session key is too small then it may be possible for an
-// attacker to brute-force it. If they can do that then they can learn whether
-// a random value was used (because it'll be different for the same ciphertext)
-// and thus whether the padding was correct. This defeats the point of this
-// function. Using at least a 16-byte key will protect against this attack.
-func DecryptPKCS1v15SessionKey(random io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error {
- if err := checkPub(&priv.PublicKey); err != nil {
- return err
- }
- k := priv.Size()
- if k-(len(key)+3+8) < 0 {
- return ErrDecryption
- }
-
- valid, em, index, err := decryptPKCS1v15(priv, ciphertext)
- if err != nil {
- return err
- }
-
- if len(em) != k {
- // This should be impossible because decryptPKCS1v15 always
- // returns the full slice.
- return ErrDecryption
- }
-
- valid &= subtle.ConstantTimeEq(int32(len(em)-index), int32(len(key)))
- subtle.ConstantTimeCopy(valid, key, em[len(em)-len(key):])
- return nil
-}
-
-// decryptPKCS1v15 decrypts ciphertext using priv. It returns one or zero in
-// valid that indicates whether the plaintext was correctly structured.
-// In either case, the plaintext is returned in em so that it may be read
-// independently of whether it was valid in order to maintain constant memory
-// access patterns. If the plaintext was valid then index contains the index of
-// the original message in em, to allow constant time padding removal.
-func decryptPKCS1v15(priv *PrivateKey, ciphertext []byte) (valid int, em []byte, index int, err error) {
- k := priv.Size()
- if k < 11 {
- err = ErrDecryption
- return
- }
-
- if boring.Enabled {
- var bkey *boring.PrivateKeyRSA
- bkey, err = boringPrivateKey(priv)
- if err != nil {
- return
- }
- em, err = boring.DecryptRSANoPadding(bkey, ciphertext)
- if err != nil {
- return
- }
- } else {
- em, err = decrypt(priv, ciphertext, noCheck)
- if err != nil {
- return
- }
- }
-
- firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
- secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2)
-
- // The remainder of the plaintext must be a string of non-zero random
- // octets, followed by a 0, followed by the message.
- // lookingForIndex: 1 iff we are still looking for the zero.
- // index: the offset of the first zero byte.
- lookingForIndex := 1
-
- for i := 2; i < len(em); i++ {
- equals0 := subtle.ConstantTimeByteEq(em[i], 0)
- index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
- lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
- }
-
- // The PS padding must be at least 8 bytes long, and it starts two
- // bytes into em.
- validPS := subtle.ConstantTimeLessOrEq(2+8, index)
-
- valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & validPS
- index = subtle.ConstantTimeSelect(valid, index+1, 0)
- return valid, em, index, nil
-}
-
-// nonZeroRandomBytes fills the given slice with non-zero random octets.
-func nonZeroRandomBytes(s []byte, random io.Reader) (err error) {
- _, err = io.ReadFull(random, s)
- if err != nil {
- return
- }
-
- for i := 0; i < len(s); i++ {
- for s[i] == 0 {
- _, err = io.ReadFull(random, s[i:i+1])
- if err != nil {
- return
- }
- // In tests, the PRNG may return all zeros so we do
- // this to break the loop.
- s[i] ^= 0x42
- }
- }
-
- return
-}
-
-// These are ASN1 DER structures:
-//
-// DigestInfo ::= SEQUENCE {
-// digestAlgorithm AlgorithmIdentifier,
-// digest OCTET STRING
-// }
-//
-// For performance, we don't use the generic ASN1 encoder. Rather, we
-// precompute a prefix of the digest value that makes a valid ASN1 DER string
-// with the correct contents.
-var hashPrefixes = map[crypto.Hash][]byte{
- crypto.MD5: {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
- crypto.SHA1: {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
- crypto.SHA224: {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
- crypto.SHA256: {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
- crypto.SHA384: {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
- crypto.SHA512: {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
- crypto.MD5SHA1: {}, // A special TLS case which doesn't use an ASN1 prefix.
- crypto.RIPEMD160: {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
-}
-
-// SignPKCS1v15 calculates the signature of hashed using
-// RSASSA-PKCS1-V1_5-SIGN from RSA PKCS #1 v1.5. Note that hashed must
-// be the result of hashing the input message using the given hash
-// function. If hash is zero, hashed is signed directly. This isn't
-// advisable except for interoperability.
-//
-// The random parameter is legacy and ignored, and it can be as nil.
-//
-// This function is deterministic. Thus, if the set of possible
-// messages is small, an attacker may be able to build a map from
-// messages to signatures and identify the signed messages. As ever,
-// signatures provide authenticity, not confidentiality.
-func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
- hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
- if err != nil {
- return nil, err
- }
-
- tLen := len(prefix) + hashLen
- k := priv.Size()
- if k < tLen+11 {
- return nil, ErrMessageTooLong
- }
-
- if boring.Enabled {
- bkey, err := boringPrivateKey(priv)
- if err != nil {
- return nil, err
- }
- return boring.SignRSAPKCS1v15(bkey, hash, hashed)
- }
-
- // EM = 0x00 || 0x01 || PS || 0x00 || T
- em := make([]byte, k)
- em[1] = 1
- for i := 2; i < k-tLen-1; i++ {
- em[i] = 0xff
- }
- copy(em[k-tLen:k-hashLen], prefix)
- copy(em[k-hashLen:k], hashed)
-
- return decrypt(priv, em, withCheck)
-}
-
-// VerifyPKCS1v15 verifies an RSA PKCS #1 v1.5 signature.
-// hashed is the result of hashing the input message using the given hash
-// function and sig is the signature. A valid signature is indicated by
-// returning a nil error. If hash is zero then hashed is used directly. This
-// isn't advisable except for interoperability.
-func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
- if boring.Enabled {
- bkey, err := boringPublicKey(pub)
- if err != nil {
- return err
- }
- if err := boring.VerifyRSAPKCS1v15(bkey, hash, hashed, sig); err != nil {
- return ErrVerification
- }
- return nil
- }
-
- hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
- if err != nil {
- return err
- }
-
- tLen := len(prefix) + hashLen
- k := pub.Size()
- if k < tLen+11 {
- return ErrVerification
- }
-
- // RFC 8017 Section 8.2.2: If the length of the signature S is not k
- // octets (where k is the length in octets of the RSA modulus n), output
- // "invalid signature" and stop.
- if k != len(sig) {
- return ErrVerification
- }
-
- em, err := encrypt(pub, sig)
- if err != nil {
- return ErrVerification
- }
- // EM = 0x00 || 0x01 || PS || 0x00 || T
-
- ok := subtle.ConstantTimeByteEq(em[0], 0)
- ok &= subtle.ConstantTimeByteEq(em[1], 1)
- ok &= subtle.ConstantTimeCompare(em[k-hashLen:k], hashed)
- ok &= subtle.ConstantTimeCompare(em[k-tLen:k-hashLen], prefix)
- ok &= subtle.ConstantTimeByteEq(em[k-tLen-1], 0)
-
- for i := 2; i < k-tLen-1; i++ {
- ok &= subtle.ConstantTimeByteEq(em[i], 0xff)
- }
-
- if ok != 1 {
- return ErrVerification
- }
-
- return nil
-}
-
-func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte, err error) {
- // Special case: crypto.Hash(0) is used to indicate that the data is
- // signed directly.
- if hash == 0 {
- return inLen, nil, nil
- }
-
- hashLen = hash.Size()
- if inLen != hashLen {
- return 0, nil, errors.New("crypto/rsa: input must be hashed message")
- }
- prefix, ok := hashPrefixes[hash]
- if !ok {
- return 0, nil, errors.New("crypto/rsa: unsupported hash function")
- }
- return
-}
diff --git a/contrib/go/_std_1.20/src/crypto/rsa/pss.go b/contrib/go/_std_1.20/src/crypto/rsa/pss.go
deleted file mode 100644
index f7d23b55ef..0000000000
--- a/contrib/go/_std_1.20/src/crypto/rsa/pss.go
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright 2013 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 rsa
-
-// This file implements the RSASSA-PSS signature scheme according to RFC 8017.
-
-import (
- "bytes"
- "crypto"
- "crypto/internal/boring"
- "errors"
- "hash"
- "io"
-)
-
-// Per RFC 8017, Section 9.1
-//
-// EM = MGF1 xor DB || H( 8*0x00 || mHash || salt ) || 0xbc
-//
-// where
-//
-// DB = PS || 0x01 || salt
-//
-// and PS can be empty so
-//
-// emLen = dbLen + hLen + 1 = psLen + sLen + hLen + 2
-//
-
-func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byte, error) {
- // See RFC 8017, Section 9.1.1.
-
- hLen := hash.Size()
- sLen := len(salt)
- emLen := (emBits + 7) / 8
-
- // 1. If the length of M is greater than the input limitation for the
- // hash function (2^61 - 1 octets for SHA-1), output "message too
- // long" and stop.
- //
- // 2. Let mHash = Hash(M), an octet string of length hLen.
-
- if len(mHash) != hLen {
- return nil, errors.New("crypto/rsa: input must be hashed with given hash")
- }
-
- // 3. If emLen < hLen + sLen + 2, output "encoding error" and stop.
-
- if emLen < hLen+sLen+2 {
- return nil, ErrMessageTooLong
- }
-
- em := make([]byte, emLen)
- psLen := emLen - sLen - hLen - 2
- db := em[:psLen+1+sLen]
- h := em[psLen+1+sLen : emLen-1]
-
- // 4. Generate a random octet string salt of length sLen; if sLen = 0,
- // then salt is the empty string.
- //
- // 5. Let
- // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt;
- //
- // M' is an octet string of length 8 + hLen + sLen with eight
- // initial zero octets.
- //
- // 6. Let H = Hash(M'), an octet string of length hLen.
-
- var prefix [8]byte
-
- hash.Write(prefix[:])
- hash.Write(mHash)
- hash.Write(salt)
-
- h = hash.Sum(h[:0])
- hash.Reset()
-
- // 7. Generate an octet string PS consisting of emLen - sLen - hLen - 2
- // zero octets. The length of PS may be 0.
- //
- // 8. Let DB = PS || 0x01 || salt; DB is an octet string of length
- // emLen - hLen - 1.
-
- db[psLen] = 0x01
- copy(db[psLen+1:], salt)
-
- // 9. Let dbMask = MGF(H, emLen - hLen - 1).
- //
- // 10. Let maskedDB = DB \xor dbMask.
-
- mgf1XOR(db, hash, h)
-
- // 11. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in
- // maskedDB to zero.
-
- db[0] &= 0xff >> (8*emLen - emBits)
-
- // 12. Let EM = maskedDB || H || 0xbc.
- em[emLen-1] = 0xbc
-
- // 13. Output EM.
- return em, nil
-}
-
-func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error {
- // See RFC 8017, Section 9.1.2.
-
- hLen := hash.Size()
- if sLen == PSSSaltLengthEqualsHash {
- sLen = hLen
- }
- emLen := (emBits + 7) / 8
- if emLen != len(em) {
- return errors.New("rsa: internal error: inconsistent length")
- }
-
- // 1. If the length of M is greater than the input limitation for the
- // hash function (2^61 - 1 octets for SHA-1), output "inconsistent"
- // and stop.
- //
- // 2. Let mHash = Hash(M), an octet string of length hLen.
- if hLen != len(mHash) {
- return ErrVerification
- }
-
- // 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop.
- if emLen < hLen+sLen+2 {
- return ErrVerification
- }
-
- // 4. If the rightmost octet of EM does not have hexadecimal value
- // 0xbc, output "inconsistent" and stop.
- if em[emLen-1] != 0xbc {
- return ErrVerification
- }
-
- // 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and
- // let H be the next hLen octets.
- db := em[:emLen-hLen-1]
- h := em[emLen-hLen-1 : emLen-1]
-
- // 6. If the leftmost 8 * emLen - emBits bits of the leftmost octet in
- // maskedDB are not all equal to zero, output "inconsistent" and
- // stop.
- var bitMask byte = 0xff >> (8*emLen - emBits)
- if em[0] & ^bitMask != 0 {
- return ErrVerification
- }
-
- // 7. Let dbMask = MGF(H, emLen - hLen - 1).
- //
- // 8. Let DB = maskedDB \xor dbMask.
- mgf1XOR(db, hash, h)
-
- // 9. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in DB
- // to zero.
- db[0] &= bitMask
-
- // If we don't know the salt length, look for the 0x01 delimiter.
- if sLen == PSSSaltLengthAuto {
- psLen := bytes.IndexByte(db, 0x01)
- if psLen < 0 {
- return ErrVerification
- }
- sLen = len(db) - psLen - 1
- }
-
- // 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
- // or if the octet at position emLen - hLen - sLen - 1 (the leftmost
- // position is "position 1") does not have hexadecimal value 0x01,
- // output "inconsistent" and stop.
- psLen := emLen - hLen - sLen - 2
- for _, e := range db[:psLen] {
- if e != 0x00 {
- return ErrVerification
- }
- }
- if db[psLen] != 0x01 {
- return ErrVerification
- }
-
- // 11. Let salt be the last sLen octets of DB.
- salt := db[len(db)-sLen:]
-
- // 12. Let
- // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ;
- // M' is an octet string of length 8 + hLen + sLen with eight
- // initial zero octets.
- //
- // 13. Let H' = Hash(M'), an octet string of length hLen.
- var prefix [8]byte
- hash.Write(prefix[:])
- hash.Write(mHash)
- hash.Write(salt)
-
- h0 := hash.Sum(nil)
-
- // 14. If H = H', output "consistent." Otherwise, output "inconsistent."
- if !bytes.Equal(h0, h) { // TODO: constant time?
- return ErrVerification
- }
- return nil
-}
-
-// signPSSWithSalt calculates the signature of hashed using PSS with specified salt.
-// Note that hashed must be the result of hashing the input message using the
-// given hash function. salt is a random sequence of bytes whose length will be
-// later used to verify the signature.
-func signPSSWithSalt(priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) ([]byte, error) {
- emBits := priv.N.BitLen() - 1
- em, err := emsaPSSEncode(hashed, emBits, salt, hash.New())
- if err != nil {
- return nil, err
- }
-
- if boring.Enabled {
- bkey, err := boringPrivateKey(priv)
- if err != nil {
- return nil, err
- }
- // Note: BoringCrypto always does decrypt "withCheck".
- // (It's not just decrypt.)
- s, err := boring.DecryptRSANoPadding(bkey, em)
- if err != nil {
- return nil, err
- }
- return s, nil
- }
-
- // RFC 8017: "Note that the octet length of EM will be one less than k if
- // modBits - 1 is divisible by 8 and equal to k otherwise, where k is the
- // length in octets of the RSA modulus n." 🙄
- //
- // This is extremely annoying, as all other encrypt and decrypt inputs are
- // always the exact same size as the modulus. Since it only happens for
- // weird modulus sizes, fix it by padding inefficiently.
- if emLen, k := len(em), priv.Size(); emLen < k {
- emNew := make([]byte, k)
- copy(emNew[k-emLen:], em)
- em = emNew
- }
-
- return decrypt(priv, em, withCheck)
-}
-
-const (
- // PSSSaltLengthAuto causes the salt in a PSS signature to be as large
- // as possible when signing, and to be auto-detected when verifying.
- PSSSaltLengthAuto = 0
- // PSSSaltLengthEqualsHash causes the salt length to equal the length
- // of the hash used in the signature.
- PSSSaltLengthEqualsHash = -1
-)
-
-// PSSOptions contains options for creating and verifying PSS signatures.
-type PSSOptions struct {
- // SaltLength controls the length of the salt used in the PSS signature. It
- // can either be a positive number of bytes, or one of the special
- // PSSSaltLength constants.
- SaltLength int
-
- // Hash is the hash function used to generate the message digest. If not
- // zero, it overrides the hash function passed to SignPSS. It's required
- // when using PrivateKey.Sign.
- Hash crypto.Hash
-}
-
-// HashFunc returns opts.Hash so that PSSOptions implements crypto.SignerOpts.
-func (opts *PSSOptions) HashFunc() crypto.Hash {
- return opts.Hash
-}
-
-func (opts *PSSOptions) saltLength() int {
- if opts == nil {
- return PSSSaltLengthAuto
- }
- return opts.SaltLength
-}
-
-var invalidSaltLenErr = errors.New("crypto/rsa: PSSOptions.SaltLength cannot be negative")
-
-// SignPSS calculates the signature of digest using PSS.
-//
-// digest must be the result of hashing the input message using the given hash
-// function. The opts argument may be nil, in which case sensible defaults are
-// used. If opts.Hash is set, it overrides hash.
-func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, opts *PSSOptions) ([]byte, error) {
- if boring.Enabled && rand == boring.RandReader {
- bkey, err := boringPrivateKey(priv)
- if err != nil {
- return nil, err
- }
- return boring.SignRSAPSS(bkey, hash, digest, opts.saltLength())
- }
- boring.UnreachableExceptTests()
-
- if opts != nil && opts.Hash != 0 {
- hash = opts.Hash
- }
-
- saltLength := opts.saltLength()
- switch saltLength {
- case PSSSaltLengthAuto:
- saltLength = (priv.N.BitLen()-1+7)/8 - 2 - hash.Size()
- if saltLength < 0 {
- return nil, ErrMessageTooLong
- }
- case PSSSaltLengthEqualsHash:
- saltLength = hash.Size()
- default:
- // If we get here saltLength is either > 0 or < -1, in the
- // latter case we fail out.
- if saltLength <= 0 {
- return nil, invalidSaltLenErr
- }
- }
- salt := make([]byte, saltLength)
- if _, err := io.ReadFull(rand, salt); err != nil {
- return nil, err
- }
- return signPSSWithSalt(priv, hash, digest, salt)
-}
-
-// VerifyPSS verifies a PSS signature.
-//
-// A valid signature is indicated by returning a nil error. digest must be the
-// result of hashing the input message using the given hash function. The opts
-// argument may be nil, in which case sensible defaults are used. opts.Hash is
-// ignored.
-func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *PSSOptions) error {
- if boring.Enabled {
- bkey, err := boringPublicKey(pub)
- if err != nil {
- return err
- }
- if err := boring.VerifyRSAPSS(bkey, hash, digest, sig, opts.saltLength()); err != nil {
- return ErrVerification
- }
- return nil
- }
- if len(sig) != pub.Size() {
- return ErrVerification
- }
- // Salt length must be either one of the special constants (-1 or 0)
- // or otherwise positive. If it is < PSSSaltLengthEqualsHash (-1)
- // we return an error.
- if opts.saltLength() < PSSSaltLengthEqualsHash {
- return invalidSaltLenErr
- }
-
- emBits := pub.N.BitLen() - 1
- emLen := (emBits + 7) / 8
- em, err := encrypt(pub, sig)
- if err != nil {
- return ErrVerification
- }
-
- // Like in signPSSWithSalt, deal with mismatches between emLen and the size
- // of the modulus. The spec would have us wire emLen into the encoding
- // function, but we'd rather always encode to the size of the modulus and
- // then strip leading zeroes if necessary. This only happens for weird
- // modulus sizes anyway.
- for len(em) > emLen && len(em) > 0 {
- if em[0] != 0 {
- return ErrVerification
- }
- em = em[1:]
- }
-
- return emsaPSSVerify(digest, em, emBits, opts.saltLength(), hash.New())
-}
diff --git a/contrib/go/_std_1.20/src/crypto/rsa/rsa.go b/contrib/go/_std_1.20/src/crypto/rsa/rsa.go
deleted file mode 100644
index 63bc8dad1a..0000000000
--- a/contrib/go/_std_1.20/src/crypto/rsa/rsa.go
+++ /dev/null
@@ -1,737 +0,0 @@
-// Copyright 2009 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 rsa implements RSA encryption as specified in PKCS #1 and RFC 8017.
-//
-// RSA is a single, fundamental operation that is used in this package to
-// implement either public-key encryption or public-key signatures.
-//
-// The original specification for encryption and signatures with RSA is PKCS #1
-// and the terms "RSA encryption" and "RSA signatures" by default refer to
-// PKCS #1 version 1.5. However, that specification has flaws and new designs
-// should use version 2, usually called by just OAEP and PSS, where
-// possible.
-//
-// Two sets of interfaces are included in this package. When a more abstract
-// interface isn't necessary, there are functions for encrypting/decrypting
-// with v1.5/OAEP and signing/verifying with v1.5/PSS. If one needs to abstract
-// over the public key primitive, the PrivateKey type implements the
-// Decrypter and Signer interfaces from the crypto package.
-//
-// Operations in this package are implemented using constant-time algorithms,
-// except for [GenerateKey], [PrivateKey.Precompute], and [PrivateKey.Validate].
-// Every other operation only leaks the bit size of the involved values, which
-// all depend on the selected key size.
-package rsa
-
-import (
- "crypto"
- "crypto/internal/bigmod"
- "crypto/internal/boring"
- "crypto/internal/boring/bbig"
- "crypto/internal/randutil"
- "crypto/rand"
- "crypto/subtle"
- "encoding/binary"
- "errors"
- "hash"
- "io"
- "math"
- "math/big"
-)
-
-var bigOne = big.NewInt(1)
-
-// A PublicKey represents the public part of an RSA key.
-type PublicKey struct {
- N *big.Int // modulus
- E int // public exponent
-}
-
-// Any methods implemented on PublicKey might need to also be implemented on
-// PrivateKey, as the latter embeds the former and will expose its methods.
-
-// Size returns the modulus size in bytes. Raw signatures and ciphertexts
-// for or by this public key will have the same size.
-func (pub *PublicKey) Size() int {
- return (pub.N.BitLen() + 7) / 8
-}
-
-// Equal reports whether pub and x have the same value.
-func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
- xx, ok := x.(*PublicKey)
- if !ok {
- return false
- }
- return pub.N.Cmp(xx.N) == 0 && pub.E == xx.E
-}
-
-// OAEPOptions is an interface for passing options to OAEP decryption using the
-// crypto.Decrypter interface.
-type OAEPOptions struct {
- // Hash is the hash function that will be used when generating the mask.
- Hash crypto.Hash
-
- // MGFHash is the hash function used for MGF1.
- // If zero, Hash is used instead.
- MGFHash crypto.Hash
-
- // Label is an arbitrary byte string that must be equal to the value
- // used when encrypting.
- Label []byte
-}
-
-var (
- errPublicModulus = errors.New("crypto/rsa: missing public modulus")
- errPublicExponentSmall = errors.New("crypto/rsa: public exponent too small")
- errPublicExponentLarge = errors.New("crypto/rsa: public exponent too large")
-)
-
-// checkPub sanity checks the public key before we use it.
-// We require pub.E to fit into a 32-bit integer so that we
-// do not have different behavior depending on whether
-// int is 32 or 64 bits. See also
-// https://www.imperialviolet.org/2012/03/16/rsae.html.
-func checkPub(pub *PublicKey) error {
- if pub.N == nil {
- return errPublicModulus
- }
- if pub.E < 2 {
- return errPublicExponentSmall
- }
- if pub.E > 1<<31-1 {
- return errPublicExponentLarge
- }
- return nil
-}
-
-// A PrivateKey represents an RSA key
-type PrivateKey struct {
- PublicKey // public part.
- D *big.Int // private exponent
- Primes []*big.Int // prime factors of N, has >= 2 elements.
-
- // Precomputed contains precomputed values that speed up RSA operations,
- // if available. It must be generated by calling PrivateKey.Precompute and
- // must not be modified.
- Precomputed PrecomputedValues
-}
-
-// Public returns the public key corresponding to priv.
-func (priv *PrivateKey) Public() crypto.PublicKey {
- return &priv.PublicKey
-}
-
-// Equal reports whether priv and x have equivalent values. It ignores
-// Precomputed values.
-func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
- xx, ok := x.(*PrivateKey)
- if !ok {
- return false
- }
- if !priv.PublicKey.Equal(&xx.PublicKey) || priv.D.Cmp(xx.D) != 0 {
- return false
- }
- if len(priv.Primes) != len(xx.Primes) {
- return false
- }
- for i := range priv.Primes {
- if priv.Primes[i].Cmp(xx.Primes[i]) != 0 {
- return false
- }
- }
- return true
-}
-
-// Sign signs digest with priv, reading randomness from rand. If opts is a
-// *PSSOptions then the PSS algorithm will be used, otherwise PKCS #1 v1.5 will
-// be used. digest must be the result of hashing the input message using
-// opts.HashFunc().
-//
-// This method implements crypto.Signer, which is an interface to support keys
-// where the private part is kept in, for example, a hardware module. Common
-// uses should use the Sign* functions in this package directly.
-func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
- if pssOpts, ok := opts.(*PSSOptions); ok {
- return SignPSS(rand, priv, pssOpts.Hash, digest, pssOpts)
- }
-
- return SignPKCS1v15(rand, priv, opts.HashFunc(), digest)
-}
-
-// Decrypt decrypts ciphertext with priv. If opts is nil or of type
-// *PKCS1v15DecryptOptions then PKCS #1 v1.5 decryption is performed. Otherwise
-// opts must have type *OAEPOptions and OAEP decryption is done.
-func (priv *PrivateKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error) {
- if opts == nil {
- return DecryptPKCS1v15(rand, priv, ciphertext)
- }
-
- switch opts := opts.(type) {
- case *OAEPOptions:
- if opts.MGFHash == 0 {
- return decryptOAEP(opts.Hash.New(), opts.Hash.New(), rand, priv, ciphertext, opts.Label)
- } else {
- return decryptOAEP(opts.Hash.New(), opts.MGFHash.New(), rand, priv, ciphertext, opts.Label)
- }
-
- case *PKCS1v15DecryptOptions:
- if l := opts.SessionKeyLen; l > 0 {
- plaintext = make([]byte, l)
- if _, err := io.ReadFull(rand, plaintext); err != nil {
- return nil, err
- }
- if err := DecryptPKCS1v15SessionKey(rand, priv, ciphertext, plaintext); err != nil {
- return nil, err
- }
- return plaintext, nil
- } else {
- return DecryptPKCS1v15(rand, priv, ciphertext)
- }
-
- default:
- return nil, errors.New("crypto/rsa: invalid options for Decrypt")
- }
-}
-
-type PrecomputedValues struct {
- Dp, Dq *big.Int // D mod (P-1) (or mod Q-1)
- Qinv *big.Int // Q^-1 mod P
-
- // CRTValues is used for the 3rd and subsequent primes. Due to a
- // historical accident, the CRT for the first two primes is handled
- // differently in PKCS #1 and interoperability is sufficiently
- // important that we mirror this.
- //
- // Note: these values are still filled in by Precompute for
- // backwards compatibility but are not used. Multi-prime RSA is very rare,
- // and is implemented by this package without CRT optimizations to limit
- // complexity.
- CRTValues []CRTValue
-
- n, p, q *bigmod.Modulus // moduli for CRT with Montgomery precomputed constants
-}
-
-// CRTValue contains the precomputed Chinese remainder theorem values.
-type CRTValue struct {
- Exp *big.Int // D mod (prime-1).
- Coeff *big.Int // R·Coeff ≡ 1 mod Prime.
- R *big.Int // product of primes prior to this (inc p and q).
-}
-
-// Validate performs basic sanity checks on the key.
-// It returns nil if the key is valid, or else an error describing a problem.
-func (priv *PrivateKey) Validate() error {
- if err := checkPub(&priv.PublicKey); err != nil {
- return err
- }
-
- // Check that Πprimes == n.
- modulus := new(big.Int).Set(bigOne)
- for _, prime := range priv.Primes {
- // Any primes ≤ 1 will cause divide-by-zero panics later.
- if prime.Cmp(bigOne) <= 0 {
- return errors.New("crypto/rsa: invalid prime value")
- }
- modulus.Mul(modulus, prime)
- }
- if modulus.Cmp(priv.N) != 0 {
- return errors.New("crypto/rsa: invalid modulus")
- }
-
- // Check that de ≡ 1 mod p-1, for each prime.
- // This implies that e is coprime to each p-1 as e has a multiplicative
- // inverse. Therefore e is coprime to lcm(p-1,q-1,r-1,...) =
- // exponent(ℤ/nℤ). It also implies that a^de ≡ a mod p as a^(p-1) ≡ 1
- // mod p. Thus a^de ≡ a mod n for all a coprime to n, as required.
- congruence := new(big.Int)
- de := new(big.Int).SetInt64(int64(priv.E))
- de.Mul(de, priv.D)
- for _, prime := range priv.Primes {
- pminus1 := new(big.Int).Sub(prime, bigOne)
- congruence.Mod(de, pminus1)
- if congruence.Cmp(bigOne) != 0 {
- return errors.New("crypto/rsa: invalid exponents")
- }
- }
- return nil
-}
-
-// GenerateKey generates an RSA keypair of the given bit size using the
-// random source random (for example, crypto/rand.Reader).
-func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) {
- return GenerateMultiPrimeKey(random, 2, bits)
-}
-
-// GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit
-// size and the given random source.
-//
-// Table 1 in "[On the Security of Multi-prime RSA]" suggests maximum numbers of
-// primes for a given bit size.
-//
-// Although the public keys are compatible (actually, indistinguishable) from
-// the 2-prime case, the private keys are not. Thus it may not be possible to
-// export multi-prime private keys in certain formats or to subsequently import
-// them into other code.
-//
-// This package does not implement CRT optimizations for multi-prime RSA, so the
-// keys with more than two primes will have worse performance.
-//
-// Note: The use of this function with a number of primes different from
-// two is not recommended for the above security, compatibility, and performance
-// reasons. Use GenerateKey instead.
-//
-// [On the Security of Multi-prime RSA]: http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
-func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) {
- randutil.MaybeReadByte(random)
-
- if boring.Enabled && random == boring.RandReader && nprimes == 2 &&
- (bits == 2048 || bits == 3072 || bits == 4096) {
- bN, bE, bD, bP, bQ, bDp, bDq, bQinv, err := boring.GenerateKeyRSA(bits)
- if err != nil {
- return nil, err
- }
- N := bbig.Dec(bN)
- E := bbig.Dec(bE)
- D := bbig.Dec(bD)
- P := bbig.Dec(bP)
- Q := bbig.Dec(bQ)
- Dp := bbig.Dec(bDp)
- Dq := bbig.Dec(bDq)
- Qinv := bbig.Dec(bQinv)
- e64 := E.Int64()
- if !E.IsInt64() || int64(int(e64)) != e64 {
- return nil, errors.New("crypto/rsa: generated key exponent too large")
- }
- key := &PrivateKey{
- PublicKey: PublicKey{
- N: N,
- E: int(e64),
- },
- D: D,
- Primes: []*big.Int{P, Q},
- Precomputed: PrecomputedValues{
- Dp: Dp,
- Dq: Dq,
- Qinv: Qinv,
- CRTValues: make([]CRTValue, 0), // non-nil, to match Precompute
- n: bigmod.NewModulusFromBig(N),
- p: bigmod.NewModulusFromBig(P),
- q: bigmod.NewModulusFromBig(Q),
- },
- }
- return key, nil
- }
-
- priv := new(PrivateKey)
- priv.E = 65537
-
- if nprimes < 2 {
- return nil, errors.New("crypto/rsa: GenerateMultiPrimeKey: nprimes must be >= 2")
- }
-
- if bits < 64 {
- primeLimit := float64(uint64(1) << uint(bits/nprimes))
- // pi approximates the number of primes less than primeLimit
- pi := primeLimit / (math.Log(primeLimit) - 1)
- // Generated primes start with 11 (in binary) so we can only
- // use a quarter of them.
- pi /= 4
- // Use a factor of two to ensure that key generation terminates
- // in a reasonable amount of time.
- pi /= 2
- if pi <= float64(nprimes) {
- return nil, errors.New("crypto/rsa: too few primes of given length to generate an RSA key")
- }
- }
-
- primes := make([]*big.Int, nprimes)
-
-NextSetOfPrimes:
- for {
- todo := bits
- // crypto/rand should set the top two bits in each prime.
- // Thus each prime has the form
- // p_i = 2^bitlen(p_i) × 0.11... (in base 2).
- // And the product is:
- // P = 2^todo × α
- // where α is the product of nprimes numbers of the form 0.11...
- //
- // If α < 1/2 (which can happen for nprimes > 2), we need to
- // shift todo to compensate for lost bits: the mean value of 0.11...
- // is 7/8, so todo + shift - nprimes * log2(7/8) ~= bits - 1/2
- // will give good results.
- if nprimes >= 7 {
- todo += (nprimes - 2) / 5
- }
- for i := 0; i < nprimes; i++ {
- var err error
- primes[i], err = rand.Prime(random, todo/(nprimes-i))
- if err != nil {
- return nil, err
- }
- todo -= primes[i].BitLen()
- }
-
- // Make sure that primes is pairwise unequal.
- for i, prime := range primes {
- for j := 0; j < i; j++ {
- if prime.Cmp(primes[j]) == 0 {
- continue NextSetOfPrimes
- }
- }
- }
-
- n := new(big.Int).Set(bigOne)
- totient := new(big.Int).Set(bigOne)
- pminus1 := new(big.Int)
- for _, prime := range primes {
- n.Mul(n, prime)
- pminus1.Sub(prime, bigOne)
- totient.Mul(totient, pminus1)
- }
- if n.BitLen() != bits {
- // This should never happen for nprimes == 2 because
- // crypto/rand should set the top two bits in each prime.
- // For nprimes > 2 we hope it does not happen often.
- continue NextSetOfPrimes
- }
-
- priv.D = new(big.Int)
- e := big.NewInt(int64(priv.E))
- ok := priv.D.ModInverse(e, totient)
-
- if ok != nil {
- priv.Primes = primes
- priv.N = n
- break
- }
- }
-
- priv.Precompute()
- return priv, nil
-}
-
-// incCounter increments a four byte, big-endian counter.
-func incCounter(c *[4]byte) {
- if c[3]++; c[3] != 0 {
- return
- }
- if c[2]++; c[2] != 0 {
- return
- }
- if c[1]++; c[1] != 0 {
- return
- }
- c[0]++
-}
-
-// mgf1XOR XORs the bytes in out with a mask generated using the MGF1 function
-// specified in PKCS #1 v2.1.
-func mgf1XOR(out []byte, hash hash.Hash, seed []byte) {
- var counter [4]byte
- var digest []byte
-
- done := 0
- for done < len(out) {
- hash.Write(seed)
- hash.Write(counter[0:4])
- digest = hash.Sum(digest[:0])
- hash.Reset()
-
- for i := 0; i < len(digest) && done < len(out); i++ {
- out[done] ^= digest[i]
- done++
- }
- incCounter(&counter)
- }
-}
-
-// ErrMessageTooLong is returned when attempting to encrypt or sign a message
-// which is too large for the size of the key. When using SignPSS, this can also
-// be returned if the size of the salt is too large.
-var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA key size")
-
-func encrypt(pub *PublicKey, plaintext []byte) ([]byte, error) {
- boring.Unreachable()
-
- N := bigmod.NewModulusFromBig(pub.N)
- m, err := bigmod.NewNat().SetBytes(plaintext, N)
- if err != nil {
- return nil, err
- }
- e := intToBytes(pub.E)
-
- return bigmod.NewNat().Exp(m, e, N).Bytes(N), nil
-}
-
-// intToBytes returns i as a big-endian slice of bytes with no leading zeroes,
-// leaking only the bit size of i through timing side-channels.
-func intToBytes(i int) []byte {
- b := make([]byte, 8)
- binary.BigEndian.PutUint64(b, uint64(i))
- for len(b) > 1 && b[0] == 0 {
- b = b[1:]
- }
- return b
-}
-
-// EncryptOAEP encrypts the given message with RSA-OAEP.
-//
-// OAEP is parameterised by a hash function that is used as a random oracle.
-// Encryption and decryption of a given message must use the same hash function
-// and sha256.New() is a reasonable choice.
-//
-// The random parameter is used as a source of entropy to ensure that
-// encrypting the same message twice doesn't result in the same ciphertext.
-//
-// The label parameter may contain arbitrary data that will not be encrypted,
-// but which gives important context to the message. For example, if a given
-// public key is used to encrypt two types of messages then distinct label
-// values could be used to ensure that a ciphertext for one purpose cannot be
-// used for another by an attacker. If not required it can be empty.
-//
-// The message must be no longer than the length of the public modulus minus
-// twice the hash length, minus a further 2.
-func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error) {
- if err := checkPub(pub); err != nil {
- return nil, err
- }
- hash.Reset()
- k := pub.Size()
- if len(msg) > k-2*hash.Size()-2 {
- return nil, ErrMessageTooLong
- }
-
- if boring.Enabled && random == boring.RandReader {
- bkey, err := boringPublicKey(pub)
- if err != nil {
- return nil, err
- }
- return boring.EncryptRSAOAEP(hash, hash, bkey, msg, label)
- }
- boring.UnreachableExceptTests()
-
- hash.Write(label)
- lHash := hash.Sum(nil)
- hash.Reset()
-
- em := make([]byte, k)
- seed := em[1 : 1+hash.Size()]
- db := em[1+hash.Size():]
-
- copy(db[0:hash.Size()], lHash)
- db[len(db)-len(msg)-1] = 1
- copy(db[len(db)-len(msg):], msg)
-
- _, err := io.ReadFull(random, seed)
- if err != nil {
- return nil, err
- }
-
- mgf1XOR(db, hash, seed)
- mgf1XOR(seed, hash, db)
-
- if boring.Enabled {
- var bkey *boring.PublicKeyRSA
- bkey, err = boringPublicKey(pub)
- if err != nil {
- return nil, err
- }
- return boring.EncryptRSANoPadding(bkey, em)
- }
-
- return encrypt(pub, em)
-}
-
-// ErrDecryption represents a failure to decrypt a message.
-// It is deliberately vague to avoid adaptive attacks.
-var ErrDecryption = errors.New("crypto/rsa: decryption error")
-
-// ErrVerification represents a failure to verify a signature.
-// It is deliberately vague to avoid adaptive attacks.
-var ErrVerification = errors.New("crypto/rsa: verification error")
-
-// Precompute performs some calculations that speed up private key operations
-// in the future.
-func (priv *PrivateKey) Precompute() {
- if priv.Precomputed.n == nil && len(priv.Primes) == 2 {
- priv.Precomputed.n = bigmod.NewModulusFromBig(priv.N)
- priv.Precomputed.p = bigmod.NewModulusFromBig(priv.Primes[0])
- priv.Precomputed.q = bigmod.NewModulusFromBig(priv.Primes[1])
- }
-
- // Fill in the backwards-compatibility *big.Int values.
- if priv.Precomputed.Dp != nil {
- return
- }
-
- priv.Precomputed.Dp = new(big.Int).Sub(priv.Primes[0], bigOne)
- priv.Precomputed.Dp.Mod(priv.D, priv.Precomputed.Dp)
-
- priv.Precomputed.Dq = new(big.Int).Sub(priv.Primes[1], bigOne)
- priv.Precomputed.Dq.Mod(priv.D, priv.Precomputed.Dq)
-
- priv.Precomputed.Qinv = new(big.Int).ModInverse(priv.Primes[1], priv.Primes[0])
-
- r := new(big.Int).Mul(priv.Primes[0], priv.Primes[1])
- priv.Precomputed.CRTValues = make([]CRTValue, len(priv.Primes)-2)
- for i := 2; i < len(priv.Primes); i++ {
- prime := priv.Primes[i]
- values := &priv.Precomputed.CRTValues[i-2]
-
- values.Exp = new(big.Int).Sub(prime, bigOne)
- values.Exp.Mod(priv.D, values.Exp)
-
- values.R = new(big.Int).Set(r)
- values.Coeff = new(big.Int).ModInverse(r, prime)
-
- r.Mul(r, prime)
- }
-}
-
-const withCheck = true
-const noCheck = false
-
-// decrypt performs an RSA decryption of ciphertext into out. If check is true,
-// m^e is calculated and compared with ciphertext, in order to defend against
-// errors in the CRT computation.
-func decrypt(priv *PrivateKey, ciphertext []byte, check bool) ([]byte, error) {
- if len(priv.Primes) <= 2 {
- boring.Unreachable()
- }
-
- var (
- err error
- m, c *bigmod.Nat
- N *bigmod.Modulus
- t0 = bigmod.NewNat()
- )
- if priv.Precomputed.n == nil {
- N = bigmod.NewModulusFromBig(priv.N)
- c, err = bigmod.NewNat().SetBytes(ciphertext, N)
- if err != nil {
- return nil, ErrDecryption
- }
- m = bigmod.NewNat().Exp(c, priv.D.Bytes(), N)
- } else {
- N = priv.Precomputed.n
- P, Q := priv.Precomputed.p, priv.Precomputed.q
- Qinv, err := bigmod.NewNat().SetBytes(priv.Precomputed.Qinv.Bytes(), P)
- if err != nil {
- return nil, ErrDecryption
- }
- c, err = bigmod.NewNat().SetBytes(ciphertext, N)
- if err != nil {
- return nil, ErrDecryption
- }
-
- // m = c ^ Dp mod p
- m = bigmod.NewNat().Exp(t0.Mod(c, P), priv.Precomputed.Dp.Bytes(), P)
- // m2 = c ^ Dq mod q
- m2 := bigmod.NewNat().Exp(t0.Mod(c, Q), priv.Precomputed.Dq.Bytes(), Q)
- // m = m - m2 mod p
- m.Sub(t0.Mod(m2, P), P)
- // m = m * Qinv mod p
- m.Mul(Qinv, P)
- // m = m * q mod N
- m.ExpandFor(N).Mul(t0.Mod(Q.Nat(), N), N)
- // m = m + m2 mod N
- m.Add(m2.ExpandFor(N), N)
- }
-
- if check {
- c1 := bigmod.NewNat().Exp(m, intToBytes(priv.E), N)
- if c1.Equal(c) != 1 {
- return nil, ErrDecryption
- }
- }
-
- return m.Bytes(N), nil
-}
-
-// DecryptOAEP decrypts ciphertext using RSA-OAEP.
-//
-// OAEP is parameterised by a hash function that is used as a random oracle.
-// Encryption and decryption of a given message must use the same hash function
-// and sha256.New() is a reasonable choice.
-//
-// The random parameter is legacy and ignored, and it can be as nil.
-//
-// The label parameter must match the value given when encrypting. See
-// EncryptOAEP for details.
-func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
- return decryptOAEP(hash, hash, random, priv, ciphertext, label)
-}
-
-func decryptOAEP(hash, mgfHash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
- if err := checkPub(&priv.PublicKey); err != nil {
- return nil, err
- }
- k := priv.Size()
- if len(ciphertext) > k ||
- k < hash.Size()*2+2 {
- return nil, ErrDecryption
- }
-
- if boring.Enabled {
- bkey, err := boringPrivateKey(priv)
- if err != nil {
- return nil, err
- }
- out, err := boring.DecryptRSAOAEP(hash, mgfHash, bkey, ciphertext, label)
- if err != nil {
- return nil, ErrDecryption
- }
- return out, nil
- }
-
- em, err := decrypt(priv, ciphertext, noCheck)
- if err != nil {
- return nil, err
- }
-
- hash.Write(label)
- lHash := hash.Sum(nil)
- hash.Reset()
-
- firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
-
- seed := em[1 : hash.Size()+1]
- db := em[hash.Size()+1:]
-
- mgf1XOR(seed, mgfHash, db)
- mgf1XOR(db, mgfHash, seed)
-
- lHash2 := db[0:hash.Size()]
-
- // We have to validate the plaintext in constant time in order to avoid
- // attacks like: J. Manger. A Chosen Ciphertext Attack on RSA Optimal
- // Asymmetric Encryption Padding (OAEP) as Standardized in PKCS #1
- // v2.0. In J. Kilian, editor, Advances in Cryptology.
- lHash2Good := subtle.ConstantTimeCompare(lHash, lHash2)
-
- // The remainder of the plaintext must be zero or more 0x00, followed
- // by 0x01, followed by the message.
- // lookingForIndex: 1 iff we are still looking for the 0x01
- // index: the offset of the first 0x01 byte
- // invalid: 1 iff we saw a non-zero byte before the 0x01.
- var lookingForIndex, index, invalid int
- lookingForIndex = 1
- rest := db[hash.Size():]
-
- for i := 0; i < len(rest); i++ {
- equals0 := subtle.ConstantTimeByteEq(rest[i], 0)
- equals1 := subtle.ConstantTimeByteEq(rest[i], 1)
- index = subtle.ConstantTimeSelect(lookingForIndex&equals1, i, index)
- lookingForIndex = subtle.ConstantTimeSelect(equals1, 0, lookingForIndex)
- invalid = subtle.ConstantTimeSelect(lookingForIndex&^equals0, 1, invalid)
- }
-
- if firstByteIsZero&lHash2Good&^invalid&^lookingForIndex != 1 {
- return nil, ErrDecryption
- }
-
- return rest[index+1:], nil
-}
diff --git a/contrib/go/_std_1.20/src/crypto/rsa/ya.make b/contrib/go/_std_1.20/src/crypto/rsa/ya.make
deleted file mode 100644
index 8d0e96203a..0000000000
--- a/contrib/go/_std_1.20/src/crypto/rsa/ya.make
+++ /dev/null
@@ -1,10 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- notboring.go
- pkcs1v15.go
- pss.go
- rsa.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/sha1/notboring.go b/contrib/go/_std_1.20/src/crypto/sha1/notboring.go
deleted file mode 100644
index 42ef87937f..0000000000
--- a/contrib/go/_std_1.20/src/crypto/sha1/notboring.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2009 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.
-
-//go:build cmd_go_bootstrap || !cgo
-// +build cmd_go_bootstrap !cgo
-
-package sha1
-
-import (
- "hash"
-)
-
-const boringEnabled = false
-
-func boringNewSHA1() hash.Hash { panic("boringcrypto: not available") }
-
-func boringUnreachable() {}
-
-func boringSHA1([]byte) [20]byte { panic("boringcrypto: not available") }
diff --git a/contrib/go/_std_1.20/src/crypto/sha1/sha1block.go b/contrib/go/_std_1.20/src/crypto/sha1/sha1block.go
deleted file mode 100644
index 321d34351c..0000000000
--- a/contrib/go/_std_1.20/src/crypto/sha1/sha1block.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2009 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 sha1
-
-import (
- "math/bits"
-)
-
-const (
- _K0 = 0x5A827999
- _K1 = 0x6ED9EBA1
- _K2 = 0x8F1BBCDC
- _K3 = 0xCA62C1D6
-)
-
-// blockGeneric is a portable, pure Go version of the SHA-1 block step.
-// It's used by sha1block_generic.go and tests.
-func blockGeneric(dig *digest, p []byte) {
- var w [16]uint32
-
- h0, h1, h2, h3, h4 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4]
- for len(p) >= chunk {
- // Can interlace the computation of w with the
- // rounds below if needed for speed.
- for i := 0; i < 16; i++ {
- j := i * 4
- w[i] = uint32(p[j])<<24 | uint32(p[j+1])<<16 | uint32(p[j+2])<<8 | uint32(p[j+3])
- }
-
- a, b, c, d, e := h0, h1, h2, h3, h4
-
- // Each of the four 20-iteration rounds
- // differs only in the computation of f and
- // the choice of K (_K0, _K1, etc).
- i := 0
- for ; i < 16; i++ {
- f := b&c | (^b)&d
- t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K0
- a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
- }
- for ; i < 20; i++ {
- tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
- w[i&0xf] = tmp<<1 | tmp>>(32-1)
-
- f := b&c | (^b)&d
- t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K0
- a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
- }
- for ; i < 40; i++ {
- tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
- w[i&0xf] = tmp<<1 | tmp>>(32-1)
- f := b ^ c ^ d
- t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K1
- a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
- }
- for ; i < 60; i++ {
- tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
- w[i&0xf] = tmp<<1 | tmp>>(32-1)
- f := ((b | c) & d) | (b & c)
- t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K2
- a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
- }
- for ; i < 80; i++ {
- tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
- w[i&0xf] = tmp<<1 | tmp>>(32-1)
- f := b ^ c ^ d
- t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K3
- a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
- }
-
- h0 += a
- h1 += b
- h2 += c
- h3 += d
- h4 += e
-
- p = p[chunk:]
- }
-
- dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4] = h0, h1, h2, h3, h4
-}
diff --git a/contrib/go/_std_1.20/src/crypto/sha1/sha1block_amd64.s b/contrib/go/_std_1.20/src/crypto/sha1/sha1block_amd64.s
deleted file mode 100644
index 42f03fb268..0000000000
--- a/contrib/go/_std_1.20/src/crypto/sha1/sha1block_amd64.s
+++ /dev/null
@@ -1,1500 +0,0 @@
-// Copyright 2013 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.
-
-// AVX2 version by Intel, same algorithm as code in Linux kernel:
-// https://github.com/torvalds/linux/blob/master/arch/x86/crypto/sha1_avx2_x86_64_asm.S
-// Authors:
-// Ilya Albrekht <ilya.albrekht@intel.com>
-// Maxim Locktyukhin <maxim.locktyukhin@intel.com>
-// Ronen Zohar <ronen.zohar@intel.com>
-// Chandramouli Narayanan <mouli@linux.intel.com>
-
-
-#include "textflag.h"
-
-// SHA-1 block routine. See sha1block.go for Go equivalent.
-//
-// There are 80 rounds of 4 types:
-// - rounds 0-15 are type 1 and load data (ROUND1 macro).
-// - rounds 16-19 are type 1 and do not load data (ROUND1x macro).
-// - rounds 20-39 are type 2 and do not load data (ROUND2 macro).
-// - rounds 40-59 are type 3 and do not load data (ROUND3 macro).
-// - rounds 60-79 are type 4 and do not load data (ROUND4 macro).
-//
-// Each round loads or shuffles the data, then computes a per-round
-// function of b, c, d, and then mixes the result into and rotates the
-// five registers a, b, c, d, e holding the intermediate results.
-//
-// The register rotation is implemented by rotating the arguments to
-// the round macros instead of by explicit move instructions.
-
-#define LOAD(index) \
- MOVL (index*4)(SI), R10; \
- BSWAPL R10; \
- MOVL R10, (index*4)(SP)
-
-#define SHUFFLE(index) \
- MOVL (((index)&0xf)*4)(SP), R10; \
- XORL (((index-3)&0xf)*4)(SP), R10; \
- XORL (((index-8)&0xf)*4)(SP), R10; \
- XORL (((index-14)&0xf)*4)(SP), R10; \
- ROLL $1, R10; \
- MOVL R10, (((index)&0xf)*4)(SP)
-
-#define FUNC1(a, b, c, d, e) \
- MOVL d, R9; \
- XORL c, R9; \
- ANDL b, R9; \
- XORL d, R9
-
-#define FUNC2(a, b, c, d, e) \
- MOVL b, R9; \
- XORL c, R9; \
- XORL d, R9
-
-#define FUNC3(a, b, c, d, e) \
- MOVL b, R8; \
- ORL c, R8; \
- ANDL d, R8; \
- MOVL b, R9; \
- ANDL c, R9; \
- ORL R8, R9
-
-#define FUNC4 FUNC2
-
-#define MIX(a, b, c, d, e, const) \
- ROLL $30, b; \
- ADDL R9, e; \
- MOVL a, R8; \
- ROLL $5, R8; \
- LEAL const(e)(R10*1), e; \
- ADDL R8, e
-
-#define ROUND1(a, b, c, d, e, index) \
- LOAD(index); \
- FUNC1(a, b, c, d, e); \
- MIX(a, b, c, d, e, 0x5A827999)
-
-#define ROUND1x(a, b, c, d, e, index) \
- SHUFFLE(index); \
- FUNC1(a, b, c, d, e); \
- MIX(a, b, c, d, e, 0x5A827999)
-
-#define ROUND2(a, b, c, d, e, index) \
- SHUFFLE(index); \
- FUNC2(a, b, c, d, e); \
- MIX(a, b, c, d, e, 0x6ED9EBA1)
-
-#define ROUND3(a, b, c, d, e, index) \
- SHUFFLE(index); \
- FUNC3(a, b, c, d, e); \
- MIX(a, b, c, d, e, 0x8F1BBCDC)
-
-#define ROUND4(a, b, c, d, e, index) \
- SHUFFLE(index); \
- FUNC4(a, b, c, d, e); \
- MIX(a, b, c, d, e, 0xCA62C1D6)
-
-TEXT ·blockAMD64(SB),NOSPLIT,$64-32
- MOVQ dig+0(FP), BP
- MOVQ p_base+8(FP), SI
- MOVQ p_len+16(FP), DX
- SHRQ $6, DX
- SHLQ $6, DX
-
- LEAQ (SI)(DX*1), DI
- MOVL (0*4)(BP), AX
- MOVL (1*4)(BP), BX
- MOVL (2*4)(BP), CX
- MOVL (3*4)(BP), DX
- MOVL (4*4)(BP), BP
-
- CMPQ SI, DI
- JEQ end
-
-loop:
- MOVL AX, R11
- MOVL BX, R12
- MOVL CX, R13
- MOVL DX, R14
- MOVL BP, R15
-
- ROUND1(AX, BX, CX, DX, BP, 0)
- ROUND1(BP, AX, BX, CX, DX, 1)
- ROUND1(DX, BP, AX, BX, CX, 2)
- ROUND1(CX, DX, BP, AX, BX, 3)
- ROUND1(BX, CX, DX, BP, AX, 4)
- ROUND1(AX, BX, CX, DX, BP, 5)
- ROUND1(BP, AX, BX, CX, DX, 6)
- ROUND1(DX, BP, AX, BX, CX, 7)
- ROUND1(CX, DX, BP, AX, BX, 8)
- ROUND1(BX, CX, DX, BP, AX, 9)
- ROUND1(AX, BX, CX, DX, BP, 10)
- ROUND1(BP, AX, BX, CX, DX, 11)
- ROUND1(DX, BP, AX, BX, CX, 12)
- ROUND1(CX, DX, BP, AX, BX, 13)
- ROUND1(BX, CX, DX, BP, AX, 14)
- ROUND1(AX, BX, CX, DX, BP, 15)
-
- ROUND1x(BP, AX, BX, CX, DX, 16)
- ROUND1x(DX, BP, AX, BX, CX, 17)
- ROUND1x(CX, DX, BP, AX, BX, 18)
- ROUND1x(BX, CX, DX, BP, AX, 19)
-
- ROUND2(AX, BX, CX, DX, BP, 20)
- ROUND2(BP, AX, BX, CX, DX, 21)
- ROUND2(DX, BP, AX, BX, CX, 22)
- ROUND2(CX, DX, BP, AX, BX, 23)
- ROUND2(BX, CX, DX, BP, AX, 24)
- ROUND2(AX, BX, CX, DX, BP, 25)
- ROUND2(BP, AX, BX, CX, DX, 26)
- ROUND2(DX, BP, AX, BX, CX, 27)
- ROUND2(CX, DX, BP, AX, BX, 28)
- ROUND2(BX, CX, DX, BP, AX, 29)
- ROUND2(AX, BX, CX, DX, BP, 30)
- ROUND2(BP, AX, BX, CX, DX, 31)
- ROUND2(DX, BP, AX, BX, CX, 32)
- ROUND2(CX, DX, BP, AX, BX, 33)
- ROUND2(BX, CX, DX, BP, AX, 34)
- ROUND2(AX, BX, CX, DX, BP, 35)
- ROUND2(BP, AX, BX, CX, DX, 36)
- ROUND2(DX, BP, AX, BX, CX, 37)
- ROUND2(CX, DX, BP, AX, BX, 38)
- ROUND2(BX, CX, DX, BP, AX, 39)
-
- ROUND3(AX, BX, CX, DX, BP, 40)
- ROUND3(BP, AX, BX, CX, DX, 41)
- ROUND3(DX, BP, AX, BX, CX, 42)
- ROUND3(CX, DX, BP, AX, BX, 43)
- ROUND3(BX, CX, DX, BP, AX, 44)
- ROUND3(AX, BX, CX, DX, BP, 45)
- ROUND3(BP, AX, BX, CX, DX, 46)
- ROUND3(DX, BP, AX, BX, CX, 47)
- ROUND3(CX, DX, BP, AX, BX, 48)
- ROUND3(BX, CX, DX, BP, AX, 49)
- ROUND3(AX, BX, CX, DX, BP, 50)
- ROUND3(BP, AX, BX, CX, DX, 51)
- ROUND3(DX, BP, AX, BX, CX, 52)
- ROUND3(CX, DX, BP, AX, BX, 53)
- ROUND3(BX, CX, DX, BP, AX, 54)
- ROUND3(AX, BX, CX, DX, BP, 55)
- ROUND3(BP, AX, BX, CX, DX, 56)
- ROUND3(DX, BP, AX, BX, CX, 57)
- ROUND3(CX, DX, BP, AX, BX, 58)
- ROUND3(BX, CX, DX, BP, AX, 59)
-
- ROUND4(AX, BX, CX, DX, BP, 60)
- ROUND4(BP, AX, BX, CX, DX, 61)
- ROUND4(DX, BP, AX, BX, CX, 62)
- ROUND4(CX, DX, BP, AX, BX, 63)
- ROUND4(BX, CX, DX, BP, AX, 64)
- ROUND4(AX, BX, CX, DX, BP, 65)
- ROUND4(BP, AX, BX, CX, DX, 66)
- ROUND4(DX, BP, AX, BX, CX, 67)
- ROUND4(CX, DX, BP, AX, BX, 68)
- ROUND4(BX, CX, DX, BP, AX, 69)
- ROUND4(AX, BX, CX, DX, BP, 70)
- ROUND4(BP, AX, BX, CX, DX, 71)
- ROUND4(DX, BP, AX, BX, CX, 72)
- ROUND4(CX, DX, BP, AX, BX, 73)
- ROUND4(BX, CX, DX, BP, AX, 74)
- ROUND4(AX, BX, CX, DX, BP, 75)
- ROUND4(BP, AX, BX, CX, DX, 76)
- ROUND4(DX, BP, AX, BX, CX, 77)
- ROUND4(CX, DX, BP, AX, BX, 78)
- ROUND4(BX, CX, DX, BP, AX, 79)
-
- ADDL R11, AX
- ADDL R12, BX
- ADDL R13, CX
- ADDL R14, DX
- ADDL R15, BP
-
- ADDQ $64, SI
- CMPQ SI, DI
- JB loop
-
-end:
- MOVQ dig+0(FP), DI
- MOVL AX, (0*4)(DI)
- MOVL BX, (1*4)(DI)
- MOVL CX, (2*4)(DI)
- MOVL DX, (3*4)(DI)
- MOVL BP, (4*4)(DI)
- RET
-
-
-// This is the implementation using AVX2, BMI1 and BMI2. It is based on:
-// "SHA-1 implementation with Intel(R) AVX2 instruction set extensions"
-// From http://software.intel.com/en-us/articles
-// (look for improving-the-performance-of-the-secure-hash-algorithm-1)
-// This implementation is 2x unrolled, and interleaves vector instructions,
-// used to precompute W, with scalar computation of current round
-// for optimal scheduling.
-
-// Trivial helper macros.
-#define UPDATE_HASH(A,TB,C,D,E) \
- ADDL (R9), A \
- MOVL A, (R9) \
- ADDL 4(R9), TB \
- MOVL TB, 4(R9) \
- ADDL 8(R9), C \
- MOVL C, 8(R9) \
- ADDL 12(R9), D \
- MOVL D, 12(R9) \
- ADDL 16(R9), E \
- MOVL E, 16(R9)
-
-
-
-// Helper macros for PRECALC, which does precomputations
-#define PRECALC_0(OFFSET) \
- VMOVDQU OFFSET(R10),X0
-
-#define PRECALC_1(OFFSET) \
- VINSERTI128 $1, OFFSET(R13), Y0, Y0
-
-#define PRECALC_2(YREG) \
- VPSHUFB Y10, Y0, YREG
-
-#define PRECALC_4(YREG,K_OFFSET) \
- VPADDD K_OFFSET(R8), YREG, Y0
-
-#define PRECALC_7(OFFSET) \
- VMOVDQU Y0, (OFFSET*2)(R14)
-
-
-// Message scheduling pre-compute for rounds 0-15
-// R13 is a pointer to even 64-byte block
-// R10 is a pointer to odd 64-byte block
-// R14 is a pointer to temp buffer
-// X0 is used as temp register
-// YREG is clobbered as part of computation
-// OFFSET chooses 16 byte chunk within a block
-// R8 is a pointer to constants block
-// K_OFFSET chooses K constants relevant to this round
-// X10 holds swap mask
-#define PRECALC_00_15(OFFSET,YREG) \
- PRECALC_0(OFFSET) \
- PRECALC_1(OFFSET) \
- PRECALC_2(YREG) \
- PRECALC_4(YREG,0x0) \
- PRECALC_7(OFFSET)
-
-
-// Helper macros for PRECALC_16_31
-#define PRECALC_16(REG_SUB_16,REG_SUB_12,REG_SUB_4,REG) \
- VPALIGNR $8, REG_SUB_16, REG_SUB_12, REG \ // w[i-14]
- VPSRLDQ $4, REG_SUB_4, Y0 // w[i-3]
-
-#define PRECALC_17(REG_SUB_16,REG_SUB_8,REG) \
- VPXOR REG_SUB_8, REG, REG \
- VPXOR REG_SUB_16, Y0, Y0
-
-#define PRECALC_18(REG) \
- VPXOR Y0, REG, REG \
- VPSLLDQ $12, REG, Y9
-
-#define PRECALC_19(REG) \
- VPSLLD $1, REG, Y0 \
- VPSRLD $31, REG, REG
-
-#define PRECALC_20(REG) \
- VPOR REG, Y0, Y0 \
- VPSLLD $2, Y9, REG
-
-#define PRECALC_21(REG) \
- VPSRLD $30, Y9, Y9 \
- VPXOR REG, Y0, Y0
-
-#define PRECALC_23(REG,K_OFFSET,OFFSET) \
- VPXOR Y9, Y0, REG \
- VPADDD K_OFFSET(R8), REG, Y0 \
- VMOVDQU Y0, (OFFSET)(R14)
-
-// Message scheduling pre-compute for rounds 16-31
-// calculating last 32 w[i] values in 8 XMM registers
-// pre-calculate K+w[i] values and store to mem
-// for later load by ALU add instruction.
-// "brute force" vectorization for rounds 16-31 only
-// due to w[i]->w[i-3] dependency.
-// clobbers 5 input ymm registers REG_SUB*
-// uses X0 and X9 as temp registers
-// As always, R8 is a pointer to constants block
-// and R14 is a pointer to temp buffer
-#define PRECALC_16_31(REG,REG_SUB_4,REG_SUB_8,REG_SUB_12,REG_SUB_16,K_OFFSET,OFFSET) \
- PRECALC_16(REG_SUB_16,REG_SUB_12,REG_SUB_4,REG) \
- PRECALC_17(REG_SUB_16,REG_SUB_8,REG) \
- PRECALC_18(REG) \
- PRECALC_19(REG) \
- PRECALC_20(REG) \
- PRECALC_21(REG) \
- PRECALC_23(REG,K_OFFSET,OFFSET)
-
-
-// Helper macros for PRECALC_32_79
-#define PRECALC_32(REG_SUB_8,REG_SUB_4) \
- VPALIGNR $8, REG_SUB_8, REG_SUB_4, Y0
-
-#define PRECALC_33(REG_SUB_28,REG) \
- VPXOR REG_SUB_28, REG, REG
-
-#define PRECALC_34(REG_SUB_16) \
- VPXOR REG_SUB_16, Y0, Y0
-
-#define PRECALC_35(REG) \
- VPXOR Y0, REG, REG
-
-#define PRECALC_36(REG) \
- VPSLLD $2, REG, Y0
-
-#define PRECALC_37(REG) \
- VPSRLD $30, REG, REG \
- VPOR REG, Y0, REG
-
-#define PRECALC_39(REG,K_OFFSET,OFFSET) \
- VPADDD K_OFFSET(R8), REG, Y0 \
- VMOVDQU Y0, (OFFSET)(R14)
-
-// Message scheduling pre-compute for rounds 32-79
-// In SHA-1 specification we have:
-// w[i] = (w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]) rol 1
-// Which is the same as:
-// w[i] = (w[i-6] ^ w[i-16] ^ w[i-28] ^ w[i-32]) rol 2
-// This allows for more efficient vectorization,
-// since w[i]->w[i-3] dependency is broken
-#define PRECALC_32_79(REG,REG_SUB_4,REG_SUB_8,REG_SUB_16,REG_SUB_28,K_OFFSET,OFFSET) \
- PRECALC_32(REG_SUB_8,REG_SUB_4) \
- PRECALC_33(REG_SUB_28,REG) \
- PRECALC_34(REG_SUB_16) \
- PRECALC_35(REG) \
- PRECALC_36(REG) \
- PRECALC_37(REG) \
- PRECALC_39(REG,K_OFFSET,OFFSET)
-
-#define PRECALC \
- PRECALC_00_15(0,Y15) \
- PRECALC_00_15(0x10,Y14) \
- PRECALC_00_15(0x20,Y13) \
- PRECALC_00_15(0x30,Y12) \
- PRECALC_16_31(Y8,Y12,Y13,Y14,Y15,0,0x80) \
- PRECALC_16_31(Y7,Y8,Y12,Y13,Y14,0x20,0xa0) \
- PRECALC_16_31(Y5,Y7,Y8,Y12,Y13,0x20,0xc0) \
- PRECALC_16_31(Y3,Y5,Y7,Y8,Y12,0x20,0xe0) \
- PRECALC_32_79(Y15,Y3,Y5,Y8,Y14,0x20,0x100) \
- PRECALC_32_79(Y14,Y15,Y3,Y7,Y13,0x20,0x120) \
- PRECALC_32_79(Y13,Y14,Y15,Y5,Y12,0x40,0x140) \
- PRECALC_32_79(Y12,Y13,Y14,Y3,Y8,0x40,0x160) \
- PRECALC_32_79(Y8,Y12,Y13,Y15,Y7,0x40,0x180) \
- PRECALC_32_79(Y7,Y8,Y12,Y14,Y5,0x40,0x1a0) \
- PRECALC_32_79(Y5,Y7,Y8,Y13,Y3,0x40,0x1c0) \
- PRECALC_32_79(Y3,Y5,Y7,Y12,Y15,0x60,0x1e0) \
- PRECALC_32_79(Y15,Y3,Y5,Y8,Y14,0x60,0x200) \
- PRECALC_32_79(Y14,Y15,Y3,Y7,Y13,0x60,0x220) \
- PRECALC_32_79(Y13,Y14,Y15,Y5,Y12,0x60,0x240) \
- PRECALC_32_79(Y12,Y13,Y14,Y3,Y8,0x60,0x260)
-
-// Macros calculating individual rounds have general form
-// CALC_ROUND_PRE + PRECALC_ROUND + CALC_ROUND_POST
-// CALC_ROUND_{PRE,POST} macros follow
-
-#define CALC_F1_PRE(OFFSET,REG_A,REG_B,REG_C,REG_E) \
- ADDL OFFSET(R15),REG_E \
- ANDNL REG_C,REG_A,BP \
- LEAL (REG_E)(REG_B*1), REG_E \ // Add F from the previous round
- RORXL $0x1b, REG_A, R12 \
- RORXL $2, REG_A, REG_B // for next round
-
-// Calculate F for the next round
-#define CALC_F1_POST(REG_A,REG_B,REG_E) \
- ANDL REG_B,REG_A \ // b&c
- XORL BP, REG_A \ // F1 = (b&c) ^ (~b&d)
- LEAL (REG_E)(R12*1), REG_E // E += A >>> 5
-
-
-// Registers are cyclically rotated DX -> AX -> DI -> SI -> BX -> CX
-#define CALC_0 \
- MOVL SI, BX \ // Precalculating first round
- RORXL $2, SI, SI \
- ANDNL AX, BX, BP \
- ANDL DI, BX \
- XORL BP, BX \
- CALC_F1_PRE(0x0,CX,BX,DI,DX) \
- PRECALC_0(0x80) \
- CALC_F1_POST(CX,SI,DX)
-
-#define CALC_1 \
- CALC_F1_PRE(0x4,DX,CX,SI,AX) \
- PRECALC_1(0x80) \
- CALC_F1_POST(DX,BX,AX)
-
-#define CALC_2 \
- CALC_F1_PRE(0x8,AX,DX,BX,DI) \
- PRECALC_2(Y15) \
- CALC_F1_POST(AX,CX,DI)
-
-#define CALC_3 \
- CALC_F1_PRE(0xc,DI,AX,CX,SI) \
- CALC_F1_POST(DI,DX,SI)
-
-#define CALC_4 \
- CALC_F1_PRE(0x20,SI,DI,DX,BX) \
- PRECALC_4(Y15,0x0) \
- CALC_F1_POST(SI,AX,BX)
-
-#define CALC_5 \
- CALC_F1_PRE(0x24,BX,SI,AX,CX) \
- CALC_F1_POST(BX,DI,CX)
-
-#define CALC_6 \
- CALC_F1_PRE(0x28,CX,BX,DI,DX) \
- CALC_F1_POST(CX,SI,DX)
-
-#define CALC_7 \
- CALC_F1_PRE(0x2c,DX,CX,SI,AX) \
- PRECALC_7(0x0) \
- CALC_F1_POST(DX,BX,AX)
-
-#define CALC_8 \
- CALC_F1_PRE(0x40,AX,DX,BX,DI) \
- PRECALC_0(0x90) \
- CALC_F1_POST(AX,CX,DI)
-
-#define CALC_9 \
- CALC_F1_PRE(0x44,DI,AX,CX,SI) \
- PRECALC_1(0x90) \
- CALC_F1_POST(DI,DX,SI)
-
-#define CALC_10 \
- CALC_F1_PRE(0x48,SI,DI,DX,BX) \
- PRECALC_2(Y14) \
- CALC_F1_POST(SI,AX,BX)
-
-#define CALC_11 \
- CALC_F1_PRE(0x4c,BX,SI,AX,CX) \
- CALC_F1_POST(BX,DI,CX)
-
-#define CALC_12 \
- CALC_F1_PRE(0x60,CX,BX,DI,DX) \
- PRECALC_4(Y14,0x0) \
- CALC_F1_POST(CX,SI,DX)
-
-#define CALC_13 \
- CALC_F1_PRE(0x64,DX,CX,SI,AX) \
- CALC_F1_POST(DX,BX,AX)
-
-#define CALC_14 \
- CALC_F1_PRE(0x68,AX,DX,BX,DI) \
- CALC_F1_POST(AX,CX,DI)
-
-#define CALC_15 \
- CALC_F1_PRE(0x6c,DI,AX,CX,SI) \
- PRECALC_7(0x10) \
- CALC_F1_POST(DI,DX,SI)
-
-#define CALC_16 \
- CALC_F1_PRE(0x80,SI,DI,DX,BX) \
- PRECALC_0(0xa0) \
- CALC_F1_POST(SI,AX,BX)
-
-#define CALC_17 \
- CALC_F1_PRE(0x84,BX,SI,AX,CX) \
- PRECALC_1(0xa0) \
- CALC_F1_POST(BX,DI,CX)
-
-#define CALC_18 \
- CALC_F1_PRE(0x88,CX,BX,DI,DX) \
- PRECALC_2(Y13) \
- CALC_F1_POST(CX,SI,DX)
-
-
-#define CALC_F2_PRE(OFFSET,REG_A,REG_B,REG_E) \
- ADDL OFFSET(R15),REG_E \
- LEAL (REG_E)(REG_B*1), REG_E \ // Add F from the previous round
- RORXL $0x1b, REG_A, R12 \
- RORXL $2, REG_A, REG_B // for next round
-
-#define CALC_F2_POST(REG_A,REG_B,REG_C,REG_E) \
- XORL REG_B, REG_A \
- ADDL R12, REG_E \
- XORL REG_C, REG_A
-
-#define CALC_19 \
- CALC_F2_PRE(0x8c,DX,CX,AX) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_20 \
- CALC_F2_PRE(0xa0,AX,DX,DI) \
- PRECALC_4(Y13,0x0) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_21 \
- CALC_F2_PRE(0xa4,DI,AX,SI) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_22 \
- CALC_F2_PRE(0xa8,SI,DI,BX) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_23 \
- CALC_F2_PRE(0xac,BX,SI,CX) \
- PRECALC_7(0x20) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_24 \
- CALC_F2_PRE(0xc0,CX,BX,DX) \
- PRECALC_0(0xb0) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_25 \
- CALC_F2_PRE(0xc4,DX,CX,AX) \
- PRECALC_1(0xb0) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_26 \
- CALC_F2_PRE(0xc8,AX,DX,DI) \
- PRECALC_2(Y12) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_27 \
- CALC_F2_PRE(0xcc,DI,AX,SI) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_28 \
- CALC_F2_PRE(0xe0,SI,DI,BX) \
- PRECALC_4(Y12,0x0) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_29 \
- CALC_F2_PRE(0xe4,BX,SI,CX) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_30 \
- CALC_F2_PRE(0xe8,CX,BX,DX) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_31 \
- CALC_F2_PRE(0xec,DX,CX,AX) \
- PRECALC_7(0x30) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_32 \
- CALC_F2_PRE(0x100,AX,DX,DI) \
- PRECALC_16(Y15,Y14,Y12,Y8) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_33 \
- CALC_F2_PRE(0x104,DI,AX,SI) \
- PRECALC_17(Y15,Y13,Y8) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_34 \
- CALC_F2_PRE(0x108,SI,DI,BX) \
- PRECALC_18(Y8) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_35 \
- CALC_F2_PRE(0x10c,BX,SI,CX) \
- PRECALC_19(Y8) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_36 \
- CALC_F2_PRE(0x120,CX,BX,DX) \
- PRECALC_20(Y8) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_37 \
- CALC_F2_PRE(0x124,DX,CX,AX) \
- PRECALC_21(Y8) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_38 \
- CALC_F2_PRE(0x128,AX,DX,DI) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-
-#define CALC_F3_PRE(OFFSET,REG_E) \
- ADDL OFFSET(R15),REG_E
-
-#define CALC_F3_POST(REG_A,REG_B,REG_C,REG_E,REG_TB) \
- LEAL (REG_E)(REG_TB*1), REG_E \ // Add F from the previous round
- MOVL REG_B, BP \
- ORL REG_A, BP \
- RORXL $0x1b, REG_A, R12 \
- RORXL $2, REG_A, REG_TB \
- ANDL REG_C, BP \ // Calculate F for the next round
- ANDL REG_B, REG_A \
- ORL BP, REG_A \
- ADDL R12, REG_E
-
-#define CALC_39 \
- CALC_F3_PRE(0x12c,SI) \
- PRECALC_23(Y8,0x0,0x80) \
- CALC_F3_POST(DI,DX,CX,SI,AX)
-
-#define CALC_40 \
- CALC_F3_PRE(0x140,BX) \
- PRECALC_16(Y14,Y13,Y8,Y7) \
- CALC_F3_POST(SI,AX,DX,BX,DI)
-
-#define CALC_41 \
- CALC_F3_PRE(0x144,CX) \
- PRECALC_17(Y14,Y12,Y7) \
- CALC_F3_POST(BX,DI,AX,CX,SI)
-
-#define CALC_42 \
- CALC_F3_PRE(0x148,DX) \
- PRECALC_18(Y7) \
- CALC_F3_POST(CX,SI,DI,DX,BX)
-
-#define CALC_43 \
- CALC_F3_PRE(0x14c,AX) \
- PRECALC_19(Y7) \
- CALC_F3_POST(DX,BX,SI,AX,CX)
-
-#define CALC_44 \
- CALC_F3_PRE(0x160,DI) \
- PRECALC_20(Y7) \
- CALC_F3_POST(AX,CX,BX,DI,DX)
-
-#define CALC_45 \
- CALC_F3_PRE(0x164,SI) \
- PRECALC_21(Y7) \
- CALC_F3_POST(DI,DX,CX,SI,AX)
-
-#define CALC_46 \
- CALC_F3_PRE(0x168,BX) \
- CALC_F3_POST(SI,AX,DX,BX,DI)
-
-#define CALC_47 \
- CALC_F3_PRE(0x16c,CX) \
- VPXOR Y9, Y0, Y7 \
- VPADDD 0x20(R8), Y7, Y0 \
- VMOVDQU Y0, 0xa0(R14) \
- CALC_F3_POST(BX,DI,AX,CX,SI)
-
-#define CALC_48 \
- CALC_F3_PRE(0x180,DX) \
- PRECALC_16(Y13,Y12,Y7,Y5) \
- CALC_F3_POST(CX,SI,DI,DX,BX)
-
-#define CALC_49 \
- CALC_F3_PRE(0x184,AX) \
- PRECALC_17(Y13,Y8,Y5) \
- CALC_F3_POST(DX,BX,SI,AX,CX)
-
-#define CALC_50 \
- CALC_F3_PRE(0x188,DI) \
- PRECALC_18(Y5) \
- CALC_F3_POST(AX,CX,BX,DI,DX)
-
-#define CALC_51 \
- CALC_F3_PRE(0x18c,SI) \
- PRECALC_19(Y5) \
- CALC_F3_POST(DI,DX,CX,SI,AX)
-
-#define CALC_52 \
- CALC_F3_PRE(0x1a0,BX) \
- PRECALC_20(Y5) \
- CALC_F3_POST(SI,AX,DX,BX,DI)
-
-#define CALC_53 \
- CALC_F3_PRE(0x1a4,CX) \
- PRECALC_21(Y5) \
- CALC_F3_POST(BX,DI,AX,CX,SI)
-
-#define CALC_54 \
- CALC_F3_PRE(0x1a8,DX) \
- CALC_F3_POST(CX,SI,DI,DX,BX)
-
-#define CALC_55 \
- CALC_F3_PRE(0x1ac,AX) \
- PRECALC_23(Y5,0x20,0xc0) \
- CALC_F3_POST(DX,BX,SI,AX,CX)
-
-#define CALC_56 \
- CALC_F3_PRE(0x1c0,DI) \
- PRECALC_16(Y12,Y8,Y5,Y3) \
- CALC_F3_POST(AX,CX,BX,DI,DX)
-
-#define CALC_57 \
- CALC_F3_PRE(0x1c4,SI) \
- PRECALC_17(Y12,Y7,Y3) \
- CALC_F3_POST(DI,DX,CX,SI,AX)
-
-#define CALC_58 \
- CALC_F3_PRE(0x1c8,BX) \
- PRECALC_18(Y3) \
- CALC_F3_POST(SI,AX,DX,BX,DI)
-
-#define CALC_59 \
- CALC_F2_PRE(0x1cc,BX,SI,CX) \
- PRECALC_19(Y3) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_60 \
- CALC_F2_PRE(0x1e0,CX,BX,DX) \
- PRECALC_20(Y3) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_61 \
- CALC_F2_PRE(0x1e4,DX,CX,AX) \
- PRECALC_21(Y3) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_62 \
- CALC_F2_PRE(0x1e8,AX,DX,DI) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_63 \
- CALC_F2_PRE(0x1ec,DI,AX,SI) \
- PRECALC_23(Y3,0x20,0xe0) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_64 \
- CALC_F2_PRE(0x200,SI,DI,BX) \
- PRECALC_32(Y5,Y3) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_65 \
- CALC_F2_PRE(0x204,BX,SI,CX) \
- PRECALC_33(Y14,Y15) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_66 \
- CALC_F2_PRE(0x208,CX,BX,DX) \
- PRECALC_34(Y8) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_67 \
- CALC_F2_PRE(0x20c,DX,CX,AX) \
- PRECALC_35(Y15) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_68 \
- CALC_F2_PRE(0x220,AX,DX,DI) \
- PRECALC_36(Y15) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_69 \
- CALC_F2_PRE(0x224,DI,AX,SI) \
- PRECALC_37(Y15) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_70 \
- CALC_F2_PRE(0x228,SI,DI,BX) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_71 \
- CALC_F2_PRE(0x22c,BX,SI,CX) \
- PRECALC_39(Y15,0x20,0x100) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_72 \
- CALC_F2_PRE(0x240,CX,BX,DX) \
- PRECALC_32(Y3,Y15) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_73 \
- CALC_F2_PRE(0x244,DX,CX,AX) \
- PRECALC_33(Y13,Y14) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_74 \
- CALC_F2_PRE(0x248,AX,DX,DI) \
- PRECALC_34(Y7) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_75 \
- CALC_F2_PRE(0x24c,DI,AX,SI) \
- PRECALC_35(Y14) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_76 \
- CALC_F2_PRE(0x260,SI,DI,BX) \
- PRECALC_36(Y14) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_77 \
- CALC_F2_PRE(0x264,BX,SI,CX) \
- PRECALC_37(Y14) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_78 \
- CALC_F2_PRE(0x268,CX,BX,DX) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_79 \
- ADDL 0x26c(R15), AX \
- LEAL (AX)(CX*1), AX \
- RORXL $0x1b, DX, R12 \
- PRECALC_39(Y14,0x20,0x120) \
- ADDL R12, AX
-
-// Similar to CALC_0
-#define CALC_80 \
- MOVL CX, DX \
- RORXL $2, CX, CX \
- ANDNL SI, DX, BP \
- ANDL BX, DX \
- XORL BP, DX \
- CALC_F1_PRE(0x10,AX,DX,BX,DI) \
- PRECALC_32(Y15,Y14) \
- CALC_F1_POST(AX,CX,DI)
-
-#define CALC_81 \
- CALC_F1_PRE(0x14,DI,AX,CX,SI) \
- PRECALC_33(Y12,Y13) \
- CALC_F1_POST(DI,DX,SI)
-
-#define CALC_82 \
- CALC_F1_PRE(0x18,SI,DI,DX,BX) \
- PRECALC_34(Y5) \
- CALC_F1_POST(SI,AX,BX)
-
-#define CALC_83 \
- CALC_F1_PRE(0x1c,BX,SI,AX,CX) \
- PRECALC_35(Y13) \
- CALC_F1_POST(BX,DI,CX)
-
-#define CALC_84 \
- CALC_F1_PRE(0x30,CX,BX,DI,DX) \
- PRECALC_36(Y13) \
- CALC_F1_POST(CX,SI,DX)
-
-#define CALC_85 \
- CALC_F1_PRE(0x34,DX,CX,SI,AX) \
- PRECALC_37(Y13) \
- CALC_F1_POST(DX,BX,AX)
-
-#define CALC_86 \
- CALC_F1_PRE(0x38,AX,DX,BX,DI) \
- CALC_F1_POST(AX,CX,DI)
-
-#define CALC_87 \
- CALC_F1_PRE(0x3c,DI,AX,CX,SI) \
- PRECALC_39(Y13,0x40,0x140) \
- CALC_F1_POST(DI,DX,SI)
-
-#define CALC_88 \
- CALC_F1_PRE(0x50,SI,DI,DX,BX) \
- PRECALC_32(Y14,Y13) \
- CALC_F1_POST(SI,AX,BX)
-
-#define CALC_89 \
- CALC_F1_PRE(0x54,BX,SI,AX,CX) \
- PRECALC_33(Y8,Y12) \
- CALC_F1_POST(BX,DI,CX)
-
-#define CALC_90 \
- CALC_F1_PRE(0x58,CX,BX,DI,DX) \
- PRECALC_34(Y3) \
- CALC_F1_POST(CX,SI,DX)
-
-#define CALC_91 \
- CALC_F1_PRE(0x5c,DX,CX,SI,AX) \
- PRECALC_35(Y12) \
- CALC_F1_POST(DX,BX,AX)
-
-#define CALC_92 \
- CALC_F1_PRE(0x70,AX,DX,BX,DI) \
- PRECALC_36(Y12) \
- CALC_F1_POST(AX,CX,DI)
-
-#define CALC_93 \
- CALC_F1_PRE(0x74,DI,AX,CX,SI) \
- PRECALC_37(Y12) \
- CALC_F1_POST(DI,DX,SI)
-
-#define CALC_94 \
- CALC_F1_PRE(0x78,SI,DI,DX,BX) \
- CALC_F1_POST(SI,AX,BX)
-
-#define CALC_95 \
- CALC_F1_PRE(0x7c,BX,SI,AX,CX) \
- PRECALC_39(Y12,0x40,0x160) \
- CALC_F1_POST(BX,DI,CX)
-
-#define CALC_96 \
- CALC_F1_PRE(0x90,CX,BX,DI,DX) \
- PRECALC_32(Y13,Y12) \
- CALC_F1_POST(CX,SI,DX)
-
-#define CALC_97 \
- CALC_F1_PRE(0x94,DX,CX,SI,AX) \
- PRECALC_33(Y7,Y8) \
- CALC_F1_POST(DX,BX,AX)
-
-#define CALC_98 \
- CALC_F1_PRE(0x98,AX,DX,BX,DI) \
- PRECALC_34(Y15) \
- CALC_F1_POST(AX,CX,DI)
-
-#define CALC_99 \
- CALC_F2_PRE(0x9c,DI,AX,SI) \
- PRECALC_35(Y8) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_100 \
- CALC_F2_PRE(0xb0,SI,DI,BX) \
- PRECALC_36(Y8) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_101 \
- CALC_F2_PRE(0xb4,BX,SI,CX) \
- PRECALC_37(Y8) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_102 \
- CALC_F2_PRE(0xb8,CX,BX,DX) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_103 \
- CALC_F2_PRE(0xbc,DX,CX,AX) \
- PRECALC_39(Y8,0x40,0x180) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_104 \
- CALC_F2_PRE(0xd0,AX,DX,DI) \
- PRECALC_32(Y12,Y8) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_105 \
- CALC_F2_PRE(0xd4,DI,AX,SI) \
- PRECALC_33(Y5,Y7) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_106 \
- CALC_F2_PRE(0xd8,SI,DI,BX) \
- PRECALC_34(Y14) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_107 \
- CALC_F2_PRE(0xdc,BX,SI,CX) \
- PRECALC_35(Y7) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_108 \
- CALC_F2_PRE(0xf0,CX,BX,DX) \
- PRECALC_36(Y7) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_109 \
- CALC_F2_PRE(0xf4,DX,CX,AX) \
- PRECALC_37(Y7) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_110 \
- CALC_F2_PRE(0xf8,AX,DX,DI) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_111 \
- CALC_F2_PRE(0xfc,DI,AX,SI) \
- PRECALC_39(Y7,0x40,0x1a0) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_112 \
- CALC_F2_PRE(0x110,SI,DI,BX) \
- PRECALC_32(Y8,Y7) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_113 \
- CALC_F2_PRE(0x114,BX,SI,CX) \
- PRECALC_33(Y3,Y5) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_114 \
- CALC_F2_PRE(0x118,CX,BX,DX) \
- PRECALC_34(Y13) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_115 \
- CALC_F2_PRE(0x11c,DX,CX,AX) \
- PRECALC_35(Y5) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_116 \
- CALC_F2_PRE(0x130,AX,DX,DI) \
- PRECALC_36(Y5) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_117 \
- CALC_F2_PRE(0x134,DI,AX,SI) \
- PRECALC_37(Y5) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_118 \
- CALC_F2_PRE(0x138,SI,DI,BX) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_119 \
- CALC_F3_PRE(0x13c,CX) \
- PRECALC_39(Y5,0x40,0x1c0) \
- CALC_F3_POST(BX,DI,AX,CX,SI)
-
-#define CALC_120 \
- CALC_F3_PRE(0x150,DX) \
- PRECALC_32(Y7,Y5) \
- CALC_F3_POST(CX,SI,DI,DX,BX)
-
-#define CALC_121 \
- CALC_F3_PRE(0x154,AX) \
- PRECALC_33(Y15,Y3) \
- CALC_F3_POST(DX,BX,SI,AX,CX)
-
-#define CALC_122 \
- CALC_F3_PRE(0x158,DI) \
- PRECALC_34(Y12) \
- CALC_F3_POST(AX,CX,BX,DI,DX)
-
-#define CALC_123 \
- CALC_F3_PRE(0x15c,SI) \
- PRECALC_35(Y3) \
- CALC_F3_POST(DI,DX,CX,SI,AX)
-
-#define CALC_124 \
- CALC_F3_PRE(0x170,BX) \
- PRECALC_36(Y3) \
- CALC_F3_POST(SI,AX,DX,BX,DI)
-
-#define CALC_125 \
- CALC_F3_PRE(0x174,CX) \
- PRECALC_37(Y3) \
- CALC_F3_POST(BX,DI,AX,CX,SI)
-
-#define CALC_126 \
- CALC_F3_PRE(0x178,DX) \
- CALC_F3_POST(CX,SI,DI,DX,BX)
-
-#define CALC_127 \
- CALC_F3_PRE(0x17c,AX) \
- PRECALC_39(Y3,0x60,0x1e0) \
- CALC_F3_POST(DX,BX,SI,AX,CX)
-
-#define CALC_128 \
- CALC_F3_PRE(0x190,DI) \
- PRECALC_32(Y5,Y3) \
- CALC_F3_POST(AX,CX,BX,DI,DX)
-
-#define CALC_129 \
- CALC_F3_PRE(0x194,SI) \
- PRECALC_33(Y14,Y15) \
- CALC_F3_POST(DI,DX,CX,SI,AX)
-
-#define CALC_130 \
- CALC_F3_PRE(0x198,BX) \
- PRECALC_34(Y8) \
- CALC_F3_POST(SI,AX,DX,BX,DI)
-
-#define CALC_131 \
- CALC_F3_PRE(0x19c,CX) \
- PRECALC_35(Y15) \
- CALC_F3_POST(BX,DI,AX,CX,SI)
-
-#define CALC_132 \
- CALC_F3_PRE(0x1b0,DX) \
- PRECALC_36(Y15) \
- CALC_F3_POST(CX,SI,DI,DX,BX)
-
-#define CALC_133 \
- CALC_F3_PRE(0x1b4,AX) \
- PRECALC_37(Y15) \
- CALC_F3_POST(DX,BX,SI,AX,CX)
-
-#define CALC_134 \
- CALC_F3_PRE(0x1b8,DI) \
- CALC_F3_POST(AX,CX,BX,DI,DX)
-
-#define CALC_135 \
- CALC_F3_PRE(0x1bc,SI) \
- PRECALC_39(Y15,0x60,0x200) \
- CALC_F3_POST(DI,DX,CX,SI,AX)
-
-#define CALC_136 \
- CALC_F3_PRE(0x1d0,BX) \
- PRECALC_32(Y3,Y15) \
- CALC_F3_POST(SI,AX,DX,BX,DI)
-
-#define CALC_137 \
- CALC_F3_PRE(0x1d4,CX) \
- PRECALC_33(Y13,Y14) \
- CALC_F3_POST(BX,DI,AX,CX,SI)
-
-#define CALC_138 \
- CALC_F3_PRE(0x1d8,DX) \
- PRECALC_34(Y7) \
- CALC_F3_POST(CX,SI,DI,DX,BX)
-
-#define CALC_139 \
- CALC_F2_PRE(0x1dc,DX,CX,AX) \
- PRECALC_35(Y14) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_140 \
- CALC_F2_PRE(0x1f0,AX,DX,DI) \
- PRECALC_36(Y14) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_141 \
- CALC_F2_PRE(0x1f4,DI,AX,SI) \
- PRECALC_37(Y14) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_142 \
- CALC_F2_PRE(0x1f8,SI,DI,BX) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_143 \
- CALC_F2_PRE(0x1fc,BX,SI,CX) \
- PRECALC_39(Y14,0x60,0x220) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_144 \
- CALC_F2_PRE(0x210,CX,BX,DX) \
- PRECALC_32(Y15,Y14) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_145 \
- CALC_F2_PRE(0x214,DX,CX,AX) \
- PRECALC_33(Y12,Y13) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_146 \
- CALC_F2_PRE(0x218,AX,DX,DI) \
- PRECALC_34(Y5) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_147 \
- CALC_F2_PRE(0x21c,DI,AX,SI) \
- PRECALC_35(Y13) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_148 \
- CALC_F2_PRE(0x230,SI,DI,BX) \
- PRECALC_36(Y13) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_149 \
- CALC_F2_PRE(0x234,BX,SI,CX) \
- PRECALC_37(Y13) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_150 \
- CALC_F2_PRE(0x238,CX,BX,DX) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_151 \
- CALC_F2_PRE(0x23c,DX,CX,AX) \
- PRECALC_39(Y13,0x60,0x240) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_152 \
- CALC_F2_PRE(0x250,AX,DX,DI) \
- PRECALC_32(Y14,Y13) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_153 \
- CALC_F2_PRE(0x254,DI,AX,SI) \
- PRECALC_33(Y8,Y12) \
- CALC_F2_POST(DI,DX,CX,SI)
-
-#define CALC_154 \
- CALC_F2_PRE(0x258,SI,DI,BX) \
- PRECALC_34(Y3) \
- CALC_F2_POST(SI,AX,DX,BX)
-
-#define CALC_155 \
- CALC_F2_PRE(0x25c,BX,SI,CX) \
- PRECALC_35(Y12) \
- CALC_F2_POST(BX,DI,AX,CX)
-
-#define CALC_156 \
- CALC_F2_PRE(0x270,CX,BX,DX) \
- PRECALC_36(Y12) \
- CALC_F2_POST(CX,SI,DI,DX)
-
-#define CALC_157 \
- CALC_F2_PRE(0x274,DX,CX,AX) \
- PRECALC_37(Y12) \
- CALC_F2_POST(DX,BX,SI,AX)
-
-#define CALC_158 \
- CALC_F2_PRE(0x278,AX,DX,DI) \
- CALC_F2_POST(AX,CX,BX,DI)
-
-#define CALC_159 \
- ADDL 0x27c(R15),SI \
- LEAL (SI)(AX*1), SI \
- RORXL $0x1b, DI, R12 \
- PRECALC_39(Y12,0x60,0x260) \
- ADDL R12, SI
-
-
-
-#define CALC \
- MOVL (R9), CX \
- MOVL 4(R9), SI \
- MOVL 8(R9), DI \
- MOVL 12(R9), AX \
- MOVL 16(R9), DX \
- MOVQ SP, R14 \
- LEAQ (2*4*80+32)(SP), R15 \
- PRECALC \ // Precalc WK for first 2 blocks
- XCHGQ R15, R14 \
-loop: \ // this loops is unrolled
- CMPQ R10, R8 \ // we use R8 value (set below) as a signal of a last block
- JNE begin \
- VZEROUPPER \
- RET \
-begin: \
- CALC_0 \
- CALC_1 \
- CALC_2 \
- CALC_3 \
- CALC_4 \
- CALC_5 \
- CALC_6 \
- CALC_7 \
- CALC_8 \
- CALC_9 \
- CALC_10 \
- CALC_11 \
- CALC_12 \
- CALC_13 \
- CALC_14 \
- CALC_15 \
- CALC_16 \
- CALC_17 \
- CALC_18 \
- CALC_19 \
- CALC_20 \
- CALC_21 \
- CALC_22 \
- CALC_23 \
- CALC_24 \
- CALC_25 \
- CALC_26 \
- CALC_27 \
- CALC_28 \
- CALC_29 \
- CALC_30 \
- CALC_31 \
- CALC_32 \
- CALC_33 \
- CALC_34 \
- CALC_35 \
- CALC_36 \
- CALC_37 \
- CALC_38 \
- CALC_39 \
- CALC_40 \
- CALC_41 \
- CALC_42 \
- CALC_43 \
- CALC_44 \
- CALC_45 \
- CALC_46 \
- CALC_47 \
- CALC_48 \
- CALC_49 \
- CALC_50 \
- CALC_51 \
- CALC_52 \
- CALC_53 \
- CALC_54 \
- CALC_55 \
- CALC_56 \
- CALC_57 \
- CALC_58 \
- CALC_59 \
- ADDQ $128, R10 \ // move to next even-64-byte block
- CMPQ R10, R11 \ // is current block the last one?
- CMOVQCC R8, R10 \ // signal the last iteration smartly
- CALC_60 \
- CALC_61 \
- CALC_62 \
- CALC_63 \
- CALC_64 \
- CALC_65 \
- CALC_66 \
- CALC_67 \
- CALC_68 \
- CALC_69 \
- CALC_70 \
- CALC_71 \
- CALC_72 \
- CALC_73 \
- CALC_74 \
- CALC_75 \
- CALC_76 \
- CALC_77 \
- CALC_78 \
- CALC_79 \
- UPDATE_HASH(AX,DX,BX,SI,DI) \
- CMPQ R10, R8 \ // is current block the last one?
- JE loop\
- MOVL DX, CX \
- CALC_80 \
- CALC_81 \
- CALC_82 \
- CALC_83 \
- CALC_84 \
- CALC_85 \
- CALC_86 \
- CALC_87 \
- CALC_88 \
- CALC_89 \
- CALC_90 \
- CALC_91 \
- CALC_92 \
- CALC_93 \
- CALC_94 \
- CALC_95 \
- CALC_96 \
- CALC_97 \
- CALC_98 \
- CALC_99 \
- CALC_100 \
- CALC_101 \
- CALC_102 \
- CALC_103 \
- CALC_104 \
- CALC_105 \
- CALC_106 \
- CALC_107 \
- CALC_108 \
- CALC_109 \
- CALC_110 \
- CALC_111 \
- CALC_112 \
- CALC_113 \
- CALC_114 \
- CALC_115 \
- CALC_116 \
- CALC_117 \
- CALC_118 \
- CALC_119 \
- CALC_120 \
- CALC_121 \
- CALC_122 \
- CALC_123 \
- CALC_124 \
- CALC_125 \
- CALC_126 \
- CALC_127 \
- CALC_128 \
- CALC_129 \
- CALC_130 \
- CALC_131 \
- CALC_132 \
- CALC_133 \
- CALC_134 \
- CALC_135 \
- CALC_136 \
- CALC_137 \
- CALC_138 \
- CALC_139 \
- ADDQ $128, R13 \ //move to next even-64-byte block
- CMPQ R13, R11 \ //is current block the last one?
- CMOVQCC R8, R10 \
- CALC_140 \
- CALC_141 \
- CALC_142 \
- CALC_143 \
- CALC_144 \
- CALC_145 \
- CALC_146 \
- CALC_147 \
- CALC_148 \
- CALC_149 \
- CALC_150 \
- CALC_151 \
- CALC_152 \
- CALC_153 \
- CALC_154 \
- CALC_155 \
- CALC_156 \
- CALC_157 \
- CALC_158 \
- CALC_159 \
- UPDATE_HASH(SI,DI,DX,CX,BX) \
- MOVL SI, R12 \ //Reset state for AVX2 reg permutation
- MOVL DI, SI \
- MOVL DX, DI \
- MOVL BX, DX \
- MOVL CX, AX \
- MOVL R12, CX \
- XCHGQ R15, R14 \
- JMP loop
-
-
-
-TEXT ·blockAVX2(SB),$1408-32
-
- MOVQ dig+0(FP), DI
- MOVQ p_base+8(FP), SI
- MOVQ p_len+16(FP), DX
- SHRQ $6, DX
- SHLQ $6, DX
-
- MOVQ $K_XMM_AR<>(SB), R8
-
- MOVQ DI, R9
- MOVQ SI, R10
- LEAQ 64(SI), R13
-
- ADDQ SI, DX
- ADDQ $64, DX
- MOVQ DX, R11
-
- CMPQ R13, R11
- CMOVQCC R8, R13
-
- VMOVDQU BSWAP_SHUFB_CTL<>(SB), Y10
-
- CALC // RET is inside macros
-
-DATA K_XMM_AR<>+0x00(SB)/4,$0x5a827999
-DATA K_XMM_AR<>+0x04(SB)/4,$0x5a827999
-DATA K_XMM_AR<>+0x08(SB)/4,$0x5a827999
-DATA K_XMM_AR<>+0x0c(SB)/4,$0x5a827999
-DATA K_XMM_AR<>+0x10(SB)/4,$0x5a827999
-DATA K_XMM_AR<>+0x14(SB)/4,$0x5a827999
-DATA K_XMM_AR<>+0x18(SB)/4,$0x5a827999
-DATA K_XMM_AR<>+0x1c(SB)/4,$0x5a827999
-DATA K_XMM_AR<>+0x20(SB)/4,$0x6ed9eba1
-DATA K_XMM_AR<>+0x24(SB)/4,$0x6ed9eba1
-DATA K_XMM_AR<>+0x28(SB)/4,$0x6ed9eba1
-DATA K_XMM_AR<>+0x2c(SB)/4,$0x6ed9eba1
-DATA K_XMM_AR<>+0x30(SB)/4,$0x6ed9eba1
-DATA K_XMM_AR<>+0x34(SB)/4,$0x6ed9eba1
-DATA K_XMM_AR<>+0x38(SB)/4,$0x6ed9eba1
-DATA K_XMM_AR<>+0x3c(SB)/4,$0x6ed9eba1
-DATA K_XMM_AR<>+0x40(SB)/4,$0x8f1bbcdc
-DATA K_XMM_AR<>+0x44(SB)/4,$0x8f1bbcdc
-DATA K_XMM_AR<>+0x48(SB)/4,$0x8f1bbcdc
-DATA K_XMM_AR<>+0x4c(SB)/4,$0x8f1bbcdc
-DATA K_XMM_AR<>+0x50(SB)/4,$0x8f1bbcdc
-DATA K_XMM_AR<>+0x54(SB)/4,$0x8f1bbcdc
-DATA K_XMM_AR<>+0x58(SB)/4,$0x8f1bbcdc
-DATA K_XMM_AR<>+0x5c(SB)/4,$0x8f1bbcdc
-DATA K_XMM_AR<>+0x60(SB)/4,$0xca62c1d6
-DATA K_XMM_AR<>+0x64(SB)/4,$0xca62c1d6
-DATA K_XMM_AR<>+0x68(SB)/4,$0xca62c1d6
-DATA K_XMM_AR<>+0x6c(SB)/4,$0xca62c1d6
-DATA K_XMM_AR<>+0x70(SB)/4,$0xca62c1d6
-DATA K_XMM_AR<>+0x74(SB)/4,$0xca62c1d6
-DATA K_XMM_AR<>+0x78(SB)/4,$0xca62c1d6
-DATA K_XMM_AR<>+0x7c(SB)/4,$0xca62c1d6
-GLOBL K_XMM_AR<>(SB),RODATA,$128
-
-DATA BSWAP_SHUFB_CTL<>+0x00(SB)/4,$0x00010203
-DATA BSWAP_SHUFB_CTL<>+0x04(SB)/4,$0x04050607
-DATA BSWAP_SHUFB_CTL<>+0x08(SB)/4,$0x08090a0b
-DATA BSWAP_SHUFB_CTL<>+0x0c(SB)/4,$0x0c0d0e0f
-DATA BSWAP_SHUFB_CTL<>+0x10(SB)/4,$0x00010203
-DATA BSWAP_SHUFB_CTL<>+0x14(SB)/4,$0x04050607
-DATA BSWAP_SHUFB_CTL<>+0x18(SB)/4,$0x08090a0b
-DATA BSWAP_SHUFB_CTL<>+0x1c(SB)/4,$0x0c0d0e0f
-GLOBL BSWAP_SHUFB_CTL<>(SB),RODATA,$32
diff --git a/contrib/go/_std_1.20/src/crypto/sha1/ya.make b/contrib/go/_std_1.20/src/crypto/sha1/ya.make
deleted file mode 100644
index f945e76bae..0000000000
--- a/contrib/go/_std_1.20/src/crypto/sha1/ya.make
+++ /dev/null
@@ -1,32 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- sha1.go
- sha1block.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- sha1block_arm64.go
- sha1block_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- sha1block_amd64.go
- sha1block_amd64.s
- )
-ENDIF()
-
-IF (CGO_ENABLED)
- SRCS(
- boring.go
- )
-ELSE()
- SRCS(
- notboring.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/sha256/sha256block_amd64.go b/contrib/go/_std_1.20/src/crypto/sha256/sha256block_amd64.go
deleted file mode 100644
index 27464e2c12..0000000000
--- a/contrib/go/_std_1.20/src/crypto/sha256/sha256block_amd64.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2017 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 sha256
-
-import "internal/cpu"
-
-var useAVX2 = cpu.X86.HasAVX2 && cpu.X86.HasBMI2
diff --git a/contrib/go/_std_1.20/src/crypto/sha256/sha256block_amd64.s b/contrib/go/_std_1.20/src/crypto/sha256/sha256block_amd64.s
deleted file mode 100644
index f6af47c50e..0000000000
--- a/contrib/go/_std_1.20/src/crypto/sha256/sha256block_amd64.s
+++ /dev/null
@@ -1,1031 +0,0 @@
-// Copyright 2013 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.
-
-#include "textflag.h"
-
-// SHA256 block routine. See sha256block.go for Go equivalent.
-//
-// The algorithm is detailed in FIPS 180-4:
-//
-// https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
-
-// The avx2-version is described in an Intel White-Paper:
-// "Fast SHA-256 Implementations on Intel Architecture Processors"
-// To find it, surf to http://www.intel.com/p/en_US/embedded
-// and search for that title.
-// AVX2 version by Intel, same algorithm as code in Linux kernel:
-// https://github.com/torvalds/linux/blob/master/arch/x86/crypto/sha256-avx2-asm.S
-// by
-// James Guilford <james.guilford@intel.com>
-// Kirk Yap <kirk.s.yap@intel.com>
-// Tim Chen <tim.c.chen@linux.intel.com>
-
-// Wt = Mt; for 0 <= t <= 15
-// Wt = SIGMA1(Wt-2) + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
-//
-// a = H0
-// b = H1
-// c = H2
-// d = H3
-// e = H4
-// f = H5
-// g = H6
-// h = H7
-//
-// for t = 0 to 63 {
-// T1 = h + BIGSIGMA1(e) + Ch(e,f,g) + Kt + Wt
-// T2 = BIGSIGMA0(a) + Maj(a,b,c)
-// h = g
-// g = f
-// f = e
-// e = d + T1
-// d = c
-// c = b
-// b = a
-// a = T1 + T2
-// }
-//
-// H0 = a + H0
-// H1 = b + H1
-// H2 = c + H2
-// H3 = d + H3
-// H4 = e + H4
-// H5 = f + H5
-// H6 = g + H6
-// H7 = h + H7
-
-// Wt = Mt; for 0 <= t <= 15
-#define MSGSCHEDULE0(index) \
- MOVL (index*4)(SI), AX; \
- BSWAPL AX; \
- MOVL AX, (index*4)(BP)
-
-// Wt = SIGMA1(Wt-2) + Wt-7 + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
-// SIGMA0(x) = ROTR(7,x) XOR ROTR(18,x) XOR SHR(3,x)
-// SIGMA1(x) = ROTR(17,x) XOR ROTR(19,x) XOR SHR(10,x)
-#define MSGSCHEDULE1(index) \
- MOVL ((index-2)*4)(BP), AX; \
- MOVL AX, CX; \
- RORL $17, AX; \
- MOVL CX, DX; \
- RORL $19, CX; \
- SHRL $10, DX; \
- MOVL ((index-15)*4)(BP), BX; \
- XORL CX, AX; \
- MOVL BX, CX; \
- XORL DX, AX; \
- RORL $7, BX; \
- MOVL CX, DX; \
- SHRL $3, DX; \
- RORL $18, CX; \
- ADDL ((index-7)*4)(BP), AX; \
- XORL CX, BX; \
- XORL DX, BX; \
- ADDL ((index-16)*4)(BP), BX; \
- ADDL BX, AX; \
- MOVL AX, ((index)*4)(BP)
-
-// Calculate T1 in AX - uses AX, CX and DX registers.
-// h is also used as an accumulator. Wt is passed in AX.
-// T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + Kt + Wt
-// BIGSIGMA1(x) = ROTR(6,x) XOR ROTR(11,x) XOR ROTR(25,x)
-// Ch(x, y, z) = (x AND y) XOR (NOT x AND z)
-#define SHA256T1(const, e, f, g, h) \
- ADDL AX, h; \
- MOVL e, AX; \
- ADDL $const, h; \
- MOVL e, CX; \
- RORL $6, AX; \
- MOVL e, DX; \
- RORL $11, CX; \
- XORL CX, AX; \
- MOVL e, CX; \
- RORL $25, DX; \
- ANDL f, CX; \
- XORL AX, DX; \
- MOVL e, AX; \
- NOTL AX; \
- ADDL DX, h; \
- ANDL g, AX; \
- XORL CX, AX; \
- ADDL h, AX
-
-// Calculate T2 in BX - uses BX, CX, DX and DI registers.
-// T2 = BIGSIGMA0(a) + Maj(a, b, c)
-// BIGSIGMA0(x) = ROTR(2,x) XOR ROTR(13,x) XOR ROTR(22,x)
-// Maj(x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
-#define SHA256T2(a, b, c) \
- MOVL a, DI; \
- MOVL c, BX; \
- RORL $2, DI; \
- MOVL a, DX; \
- ANDL b, BX; \
- RORL $13, DX; \
- MOVL a, CX; \
- ANDL c, CX; \
- XORL DX, DI; \
- XORL CX, BX; \
- MOVL a, DX; \
- MOVL b, CX; \
- RORL $22, DX; \
- ANDL a, CX; \
- XORL CX, BX; \
- XORL DX, DI; \
- ADDL DI, BX
-
-// Calculate T1 and T2, then e = d + T1 and a = T1 + T2.
-// The values for e and a are stored in d and h, ready for rotation.
-#define SHA256ROUND(index, const, a, b, c, d, e, f, g, h) \
- SHA256T1(const, e, f, g, h); \
- SHA256T2(a, b, c); \
- MOVL BX, h; \
- ADDL AX, d; \
- ADDL AX, h
-
-#define SHA256ROUND0(index, const, a, b, c, d, e, f, g, h) \
- MSGSCHEDULE0(index); \
- SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
-
-#define SHA256ROUND1(index, const, a, b, c, d, e, f, g, h) \
- MSGSCHEDULE1(index); \
- SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
-
-
-// Definitions for AVX2 version
-
-// addm (mem), reg
-// Add reg to mem using reg-mem add and store
-#define addm(P1, P2) \
- ADDL P2, P1; \
- MOVL P1, P2
-
-#define XDWORD0 Y4
-#define XDWORD1 Y5
-#define XDWORD2 Y6
-#define XDWORD3 Y7
-
-#define XWORD0 X4
-#define XWORD1 X5
-#define XWORD2 X6
-#define XWORD3 X7
-
-#define XTMP0 Y0
-#define XTMP1 Y1
-#define XTMP2 Y2
-#define XTMP3 Y3
-#define XTMP4 Y8
-#define XTMP5 Y11
-
-#define XFER Y9
-
-#define BYTE_FLIP_MASK Y13 // mask to convert LE -> BE
-#define X_BYTE_FLIP_MASK X13
-
-#define NUM_BYTES DX
-#define INP DI
-
-#define CTX SI // Beginning of digest in memory (a, b, c, ... , h)
-
-#define a AX
-#define b BX
-#define c CX
-#define d R8
-#define e DX
-#define f R9
-#define g R10
-#define h R11
-
-#define old_h R11
-
-#define TBL BP
-
-#define SRND SI // SRND is same register as CTX
-
-#define T1 R12
-
-#define y0 R13
-#define y1 R14
-#define y2 R15
-#define y3 DI
-
-// Offsets
-#define XFER_SIZE 2*64*4
-#define INP_END_SIZE 8
-#define INP_SIZE 8
-
-#define _XFER 0
-#define _INP_END _XFER + XFER_SIZE
-#define _INP _INP_END + INP_END_SIZE
-#define STACK_SIZE _INP + INP_SIZE
-
-#define ROUND_AND_SCHED_N_0(disp, a, b, c, d, e, f, g, h, XDWORD0, XDWORD1, XDWORD2, XDWORD3) \
- ; \ // ############################# RND N + 0 ############################//
- MOVL a, y3; \ // y3 = a // MAJA
- RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
- RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
- ; \
- ADDL (disp + 0*4)(SP)(SRND*1), h; \ // h = k + w + h // disp = k + w
- ORL c, y3; \ // y3 = a|c // MAJA
- VPALIGNR $4, XDWORD2, XDWORD3, XTMP0; \ // XTMP0 = W[-7]
- MOVL f, y2; \ // y2 = f // CH
- RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
- ; \
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
- XORL g, y2; \ // y2 = f^g // CH
- VPADDD XDWORD0, XTMP0, XTMP0; \ // XTMP0 = W[-7] + W[-16] // y1 = (e >> 6) // S1
- RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
- ; \
- ANDL e, y2; \ // y2 = (f^g)&e // CH
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
- RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
- ADDL h, d; \ // d = k + w + h + d // --
- ; \
- ANDL b, y3; \ // y3 = (a|c)&b // MAJA
- VPALIGNR $4, XDWORD0, XDWORD1, XTMP1; \ // XTMP1 = W[-15]
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
- RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
- ; \
- XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
- VPSRLD $7, XTMP1, XTMP2; \
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
- MOVL a, T1; \ // T1 = a // MAJB
- ANDL c, T1; \ // T1 = a&c // MAJB
- ; \
- ADDL y0, y2; \ // y2 = S1 + CH // --
- VPSLLD $(32-7), XTMP1, XTMP3; \
- ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
- ADDL y1, h; \ // h = k + w + h + S0 // --
- ; \
- ADDL y2, d; \ // d = k + w + h + d + S1 + CH = d + t1 // --
- VPOR XTMP2, XTMP3, XTMP3; \ // XTMP3 = W[-15] ror 7
- ; \
- VPSRLD $18, XTMP1, XTMP2; \
- ADDL y2, h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
- ADDL y3, h // h = t1 + S0 + MAJ // --
-
-#define ROUND_AND_SCHED_N_1(disp, a, b, c, d, e, f, g, h, XDWORD0, XDWORD1, XDWORD2, XDWORD3) \
- ; \ // ################################### RND N + 1 ############################
- ; \
- MOVL a, y3; \ // y3 = a // MAJA
- RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
- RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
- ADDL (disp + 1*4)(SP)(SRND*1), h; \ // h = k + w + h // --
- ORL c, y3; \ // y3 = a|c // MAJA
- ; \
- VPSRLD $3, XTMP1, XTMP4; \ // XTMP4 = W[-15] >> 3
- MOVL f, y2; \ // y2 = f // CH
- RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
- XORL g, y2; \ // y2 = f^g // CH
- ; \
- RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
- RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
- ANDL e, y2; \ // y2 = (f^g)&e // CH
- ADDL h, d; \ // d = k + w + h + d // --
- ; \
- VPSLLD $(32-18), XTMP1, XTMP1; \
- ANDL b, y3; \ // y3 = (a|c)&b // MAJA
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
- ; \
- VPXOR XTMP1, XTMP3, XTMP3; \
- RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
- XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
- ; \
- VPXOR XTMP2, XTMP3, XTMP3; \ // XTMP3 = W[-15] ror 7 ^ W[-15] ror 18
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
- MOVL a, T1; \ // T1 = a // MAJB
- ANDL c, T1; \ // T1 = a&c // MAJB
- ADDL y0, y2; \ // y2 = S1 + CH // --
- ; \
- VPXOR XTMP4, XTMP3, XTMP1; \ // XTMP1 = s0
- VPSHUFD $0xFA, XDWORD3, XTMP2; \ // XTMP2 = W[-2] {BBAA}
- ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
- ADDL y1, h; \ // h = k + w + h + S0 // --
- ; \
- VPADDD XTMP1, XTMP0, XTMP0; \ // XTMP0 = W[-16] + W[-7] + s0
- ADDL y2, d; \ // d = k + w + h + d + S1 + CH = d + t1 // --
- ADDL y2, h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
- ADDL y3, h; \ // h = t1 + S0 + MAJ // --
- ; \
- VPSRLD $10, XTMP2, XTMP4 // XTMP4 = W[-2] >> 10 {BBAA}
-
-#define ROUND_AND_SCHED_N_2(disp, a, b, c, d, e, f, g, h, XDWORD0, XDWORD1, XDWORD2, XDWORD3) \
- ; \ // ################################### RND N + 2 ############################
- ; \
- MOVL a, y3; \ // y3 = a // MAJA
- RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
- ADDL (disp + 2*4)(SP)(SRND*1), h; \ // h = k + w + h // --
- ; \
- VPSRLQ $19, XTMP2, XTMP3; \ // XTMP3 = W[-2] ror 19 {xBxA}
- RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
- ORL c, y3; \ // y3 = a|c // MAJA
- MOVL f, y2; \ // y2 = f // CH
- XORL g, y2; \ // y2 = f^g // CH
- ; \
- RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
- VPSRLQ $17, XTMP2, XTMP2; \ // XTMP2 = W[-2] ror 17 {xBxA}
- ANDL e, y2; \ // y2 = (f^g)&e // CH
- ; \
- RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
- VPXOR XTMP3, XTMP2, XTMP2; \
- ADDL h, d; \ // d = k + w + h + d // --
- ANDL b, y3; \ // y3 = (a|c)&b // MAJA
- ; \
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
- RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
- VPXOR XTMP2, XTMP4, XTMP4; \ // XTMP4 = s1 {xBxA}
- XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
- ; \
- VPSHUFB shuff_00BA<>(SB), XTMP4, XTMP4;\ // XTMP4 = s1 {00BA}
- ; \
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
- RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
- VPADDD XTMP4, XTMP0, XTMP0; \ // XTMP0 = {..., ..., W[1], W[0]}
- ; \
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
- MOVL a, T1; \ // T1 = a // MAJB
- ANDL c, T1; \ // T1 = a&c // MAJB
- ADDL y0, y2; \ // y2 = S1 + CH // --
- VPSHUFD $80, XTMP0, XTMP2; \ // XTMP2 = W[-2] {DDCC}
- ; \
- ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
- ADDL y1, h; \ // h = k + w + h + S0 // --
- ADDL y2, d; \ // d = k + w + h + d + S1 + CH = d + t1 // --
- ADDL y2, h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
- ; \
- ADDL y3, h // h = t1 + S0 + MAJ // --
-
-#define ROUND_AND_SCHED_N_3(disp, a, b, c, d, e, f, g, h, XDWORD0, XDWORD1, XDWORD2, XDWORD3) \
- ; \ // ################################### RND N + 3 ############################
- ; \
- MOVL a, y3; \ // y3 = a // MAJA
- RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
- RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
- ADDL (disp + 3*4)(SP)(SRND*1), h; \ // h = k + w + h // --
- ORL c, y3; \ // y3 = a|c // MAJA
- ; \
- VPSRLD $10, XTMP2, XTMP5; \ // XTMP5 = W[-2] >> 10 {DDCC}
- MOVL f, y2; \ // y2 = f // CH
- RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
- XORL g, y2; \ // y2 = f^g // CH
- ; \
- VPSRLQ $19, XTMP2, XTMP3; \ // XTMP3 = W[-2] ror 19 {xDxC}
- RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
- ANDL e, y2; \ // y2 = (f^g)&e // CH
- ADDL h, d; \ // d = k + w + h + d // --
- ANDL b, y3; \ // y3 = (a|c)&b // MAJA
- ; \
- VPSRLQ $17, XTMP2, XTMP2; \ // XTMP2 = W[-2] ror 17 {xDxC}
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
- XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
- ; \
- VPXOR XTMP3, XTMP2, XTMP2; \
- RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
- ADDL y0, y2; \ // y2 = S1 + CH // --
- ; \
- VPXOR XTMP2, XTMP5, XTMP5; \ // XTMP5 = s1 {xDxC}
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
- ADDL y2, d; \ // d = k + w + h + d + S1 + CH = d + t1 // --
- ; \
- RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
- ; \
- VPSHUFB shuff_DC00<>(SB), XTMP5, XTMP5;\ // XTMP5 = s1 {DC00}
- ; \
- VPADDD XTMP0, XTMP5, XDWORD0; \ // XDWORD0 = {W[3], W[2], W[1], W[0]}
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
- MOVL a, T1; \ // T1 = a // MAJB
- ANDL c, T1; \ // T1 = a&c // MAJB
- ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
- ; \
- ADDL y1, h; \ // h = k + w + h + S0 // --
- ADDL y2, h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
- ADDL y3, h // h = t1 + S0 + MAJ // --
-
-#define DO_ROUND_N_0(disp, a, b, c, d, e, f, g, h, old_h) \
- ; \ // ################################### RND N + 0 ###########################
- MOVL f, y2; \ // y2 = f // CH
- RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
- RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
- XORL g, y2; \ // y2 = f^g // CH
- ; \
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
- RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
- ANDL e, y2; \ // y2 = (f^g)&e // CH
- ; \
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
- RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
- XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
- RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
- MOVL a, y3; \ // y3 = a // MAJA
- ; \
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
- RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
- ADDL (disp + 0*4)(SP)(SRND*1), h; \ // h = k + w + h // --
- ORL c, y3; \ // y3 = a|c // MAJA
- ; \
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
- MOVL a, T1; \ // T1 = a // MAJB
- ANDL b, y3; \ // y3 = (a|c)&b // MAJA
- ANDL c, T1; \ // T1 = a&c // MAJB
- ADDL y0, y2; \ // y2 = S1 + CH // --
- ; \
- ADDL h, d; \ // d = k + w + h + d // --
- ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
- ADDL y1, h; \ // h = k + w + h + S0 // --
- ADDL y2, d // d = k + w + h + d + S1 + CH = d + t1 // --
-
-#define DO_ROUND_N_1(disp, a, b, c, d, e, f, g, h, old_h) \
- ; \ // ################################### RND N + 1 ###########################
- ADDL y2, old_h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0 // --
- MOVL f, y2; \ // y2 = f // CH
- RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
- RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
- XORL g, y2; \ // y2 = f^g // CH
- ; \
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
- RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
- ANDL e, y2; \ // y2 = (f^g)&e // CH
- ADDL y3, old_h; \ // h = t1 + S0 + MAJ // --
- ; \
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
- RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
- XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
- RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
- MOVL a, y3; \ // y3 = a // MAJA
- ; \
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
- RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
- ADDL (disp + 1*4)(SP)(SRND*1), h; \ // h = k + w + h // --
- ORL c, y3; \ // y3 = a|c // MAJA
- ; \
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
- MOVL a, T1; \ // T1 = a // MAJB
- ANDL b, y3; \ // y3 = (a|c)&b // MAJA
- ANDL c, T1; \ // T1 = a&c // MAJB
- ADDL y0, y2; \ // y2 = S1 + CH // --
- ; \
- ADDL h, d; \ // d = k + w + h + d // --
- ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
- ADDL y1, h; \ // h = k + w + h + S0 // --
- ; \
- ADDL y2, d // d = k + w + h + d + S1 + CH = d + t1 // --
-
-#define DO_ROUND_N_2(disp, a, b, c, d, e, f, g, h, old_h) \
- ; \ // ################################### RND N + 2 ##############################
- ADDL y2, old_h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
- MOVL f, y2; \ // y2 = f // CH
- RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
- RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
- XORL g, y2; \ // y2 = f^g // CH
- ; \
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
- RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
- ANDL e, y2; \ // y2 = (f^g)&e // CH
- ADDL y3, old_h; \ // h = t1 + S0 + MAJ // --
- ; \
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
- RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
- XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
- RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
- MOVL a, y3; \ // y3 = a // MAJA
- ; \
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
- RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
- ADDL (disp + 2*4)(SP)(SRND*1), h; \ // h = k + w + h // --
- ORL c, y3; \ // y3 = a|c // MAJA
- ; \
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
- MOVL a, T1; \ // T1 = a // MAJB
- ANDL b, y3; \ // y3 = (a|c)&b // MAJA
- ANDL c, T1; \ // T1 = a&c // MAJB
- ADDL y0, y2; \ // y2 = S1 + CH // --
- ; \
- ADDL h, d; \ // d = k + w + h + d // --
- ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
- ADDL y1, h; \ // h = k + w + h + S0 // --
- ; \
- ADDL y2, d // d = k + w + h + d + S1 + CH = d + t1 // --
-
-#define DO_ROUND_N_3(disp, a, b, c, d, e, f, g, h, old_h) \
- ; \ // ################################### RND N + 3 ###########################
- ADDL y2, old_h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
- MOVL f, y2; \ // y2 = f // CH
- RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
- RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
- XORL g, y2; \ // y2 = f^g // CH
- ; \
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
- RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
- ANDL e, y2; \ // y2 = (f^g)&e // CH
- ADDL y3, old_h; \ // h = t1 + S0 + MAJ // --
- ; \
- XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
- RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
- XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
- RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
- MOVL a, y3; \ // y3 = a // MAJA
- ; \
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
- RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
- ADDL (disp + 3*4)(SP)(SRND*1), h; \ // h = k + w + h // --
- ORL c, y3; \ // y3 = a|c // MAJA
- ; \
- XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
- MOVL a, T1; \ // T1 = a // MAJB
- ANDL b, y3; \ // y3 = (a|c)&b // MAJA
- ANDL c, T1; \ // T1 = a&c // MAJB
- ADDL y0, y2; \ // y2 = S1 + CH // --
- ; \
- ADDL h, d; \ // d = k + w + h + d // --
- ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
- ADDL y1, h; \ // h = k + w + h + S0 // --
- ; \
- ADDL y2, d; \ // d = k + w + h + d + S1 + CH = d + t1 // --
- ; \
- ADDL y2, h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
- ; \
- ADDL y3, h // h = t1 + S0 + MAJ // --
-
-TEXT ·block(SB), 0, $536-32
- CMPB ·useAVX2(SB), $1
- JE avx2
-
- MOVQ p_base+8(FP), SI
- MOVQ p_len+16(FP), DX
- SHRQ $6, DX
- SHLQ $6, DX
-
- LEAQ (SI)(DX*1), DI
- MOVQ DI, 256(SP)
- CMPQ SI, DI
- JEQ end
-
- MOVQ dig+0(FP), BP
- MOVL (0*4)(BP), R8 // a = H0
- MOVL (1*4)(BP), R9 // b = H1
- MOVL (2*4)(BP), R10 // c = H2
- MOVL (3*4)(BP), R11 // d = H3
- MOVL (4*4)(BP), R12 // e = H4
- MOVL (5*4)(BP), R13 // f = H5
- MOVL (6*4)(BP), R14 // g = H6
- MOVL (7*4)(BP), R15 // h = H7
-
-loop:
- MOVQ SP, BP
-
- SHA256ROUND0(0, 0x428a2f98, R8, R9, R10, R11, R12, R13, R14, R15)
- SHA256ROUND0(1, 0x71374491, R15, R8, R9, R10, R11, R12, R13, R14)
- SHA256ROUND0(2, 0xb5c0fbcf, R14, R15, R8, R9, R10, R11, R12, R13)
- SHA256ROUND0(3, 0xe9b5dba5, R13, R14, R15, R8, R9, R10, R11, R12)
- SHA256ROUND0(4, 0x3956c25b, R12, R13, R14, R15, R8, R9, R10, R11)
- SHA256ROUND0(5, 0x59f111f1, R11, R12, R13, R14, R15, R8, R9, R10)
- SHA256ROUND0(6, 0x923f82a4, R10, R11, R12, R13, R14, R15, R8, R9)
- SHA256ROUND0(7, 0xab1c5ed5, R9, R10, R11, R12, R13, R14, R15, R8)
- SHA256ROUND0(8, 0xd807aa98, R8, R9, R10, R11, R12, R13, R14, R15)
- SHA256ROUND0(9, 0x12835b01, R15, R8, R9, R10, R11, R12, R13, R14)
- SHA256ROUND0(10, 0x243185be, R14, R15, R8, R9, R10, R11, R12, R13)
- SHA256ROUND0(11, 0x550c7dc3, R13, R14, R15, R8, R9, R10, R11, R12)
- SHA256ROUND0(12, 0x72be5d74, R12, R13, R14, R15, R8, R9, R10, R11)
- SHA256ROUND0(13, 0x80deb1fe, R11, R12, R13, R14, R15, R8, R9, R10)
- SHA256ROUND0(14, 0x9bdc06a7, R10, R11, R12, R13, R14, R15, R8, R9)
- SHA256ROUND0(15, 0xc19bf174, R9, R10, R11, R12, R13, R14, R15, R8)
-
- SHA256ROUND1(16, 0xe49b69c1, R8, R9, R10, R11, R12, R13, R14, R15)
- SHA256ROUND1(17, 0xefbe4786, R15, R8, R9, R10, R11, R12, R13, R14)
- SHA256ROUND1(18, 0x0fc19dc6, R14, R15, R8, R9, R10, R11, R12, R13)
- SHA256ROUND1(19, 0x240ca1cc, R13, R14, R15, R8, R9, R10, R11, R12)
- SHA256ROUND1(20, 0x2de92c6f, R12, R13, R14, R15, R8, R9, R10, R11)
- SHA256ROUND1(21, 0x4a7484aa, R11, R12, R13, R14, R15, R8, R9, R10)
- SHA256ROUND1(22, 0x5cb0a9dc, R10, R11, R12, R13, R14, R15, R8, R9)
- SHA256ROUND1(23, 0x76f988da, R9, R10, R11, R12, R13, R14, R15, R8)
- SHA256ROUND1(24, 0x983e5152, R8, R9, R10, R11, R12, R13, R14, R15)
- SHA256ROUND1(25, 0xa831c66d, R15, R8, R9, R10, R11, R12, R13, R14)
- SHA256ROUND1(26, 0xb00327c8, R14, R15, R8, R9, R10, R11, R12, R13)
- SHA256ROUND1(27, 0xbf597fc7, R13, R14, R15, R8, R9, R10, R11, R12)
- SHA256ROUND1(28, 0xc6e00bf3, R12, R13, R14, R15, R8, R9, R10, R11)
- SHA256ROUND1(29, 0xd5a79147, R11, R12, R13, R14, R15, R8, R9, R10)
- SHA256ROUND1(30, 0x06ca6351, R10, R11, R12, R13, R14, R15, R8, R9)
- SHA256ROUND1(31, 0x14292967, R9, R10, R11, R12, R13, R14, R15, R8)
- SHA256ROUND1(32, 0x27b70a85, R8, R9, R10, R11, R12, R13, R14, R15)
- SHA256ROUND1(33, 0x2e1b2138, R15, R8, R9, R10, R11, R12, R13, R14)
- SHA256ROUND1(34, 0x4d2c6dfc, R14, R15, R8, R9, R10, R11, R12, R13)
- SHA256ROUND1(35, 0x53380d13, R13, R14, R15, R8, R9, R10, R11, R12)
- SHA256ROUND1(36, 0x650a7354, R12, R13, R14, R15, R8, R9, R10, R11)
- SHA256ROUND1(37, 0x766a0abb, R11, R12, R13, R14, R15, R8, R9, R10)
- SHA256ROUND1(38, 0x81c2c92e, R10, R11, R12, R13, R14, R15, R8, R9)
- SHA256ROUND1(39, 0x92722c85, R9, R10, R11, R12, R13, R14, R15, R8)
- SHA256ROUND1(40, 0xa2bfe8a1, R8, R9, R10, R11, R12, R13, R14, R15)
- SHA256ROUND1(41, 0xa81a664b, R15, R8, R9, R10, R11, R12, R13, R14)
- SHA256ROUND1(42, 0xc24b8b70, R14, R15, R8, R9, R10, R11, R12, R13)
- SHA256ROUND1(43, 0xc76c51a3, R13, R14, R15, R8, R9, R10, R11, R12)
- SHA256ROUND1(44, 0xd192e819, R12, R13, R14, R15, R8, R9, R10, R11)
- SHA256ROUND1(45, 0xd6990624, R11, R12, R13, R14, R15, R8, R9, R10)
- SHA256ROUND1(46, 0xf40e3585, R10, R11, R12, R13, R14, R15, R8, R9)
- SHA256ROUND1(47, 0x106aa070, R9, R10, R11, R12, R13, R14, R15, R8)
- SHA256ROUND1(48, 0x19a4c116, R8, R9, R10, R11, R12, R13, R14, R15)
- SHA256ROUND1(49, 0x1e376c08, R15, R8, R9, R10, R11, R12, R13, R14)
- SHA256ROUND1(50, 0x2748774c, R14, R15, R8, R9, R10, R11, R12, R13)
- SHA256ROUND1(51, 0x34b0bcb5, R13, R14, R15, R8, R9, R10, R11, R12)
- SHA256ROUND1(52, 0x391c0cb3, R12, R13, R14, R15, R8, R9, R10, R11)
- SHA256ROUND1(53, 0x4ed8aa4a, R11, R12, R13, R14, R15, R8, R9, R10)
- SHA256ROUND1(54, 0x5b9cca4f, R10, R11, R12, R13, R14, R15, R8, R9)
- SHA256ROUND1(55, 0x682e6ff3, R9, R10, R11, R12, R13, R14, R15, R8)
- SHA256ROUND1(56, 0x748f82ee, R8, R9, R10, R11, R12, R13, R14, R15)
- SHA256ROUND1(57, 0x78a5636f, R15, R8, R9, R10, R11, R12, R13, R14)
- SHA256ROUND1(58, 0x84c87814, R14, R15, R8, R9, R10, R11, R12, R13)
- SHA256ROUND1(59, 0x8cc70208, R13, R14, R15, R8, R9, R10, R11, R12)
- SHA256ROUND1(60, 0x90befffa, R12, R13, R14, R15, R8, R9, R10, R11)
- SHA256ROUND1(61, 0xa4506ceb, R11, R12, R13, R14, R15, R8, R9, R10)
- SHA256ROUND1(62, 0xbef9a3f7, R10, R11, R12, R13, R14, R15, R8, R9)
- SHA256ROUND1(63, 0xc67178f2, R9, R10, R11, R12, R13, R14, R15, R8)
-
- MOVQ dig+0(FP), BP
- ADDL (0*4)(BP), R8 // H0 = a + H0
- MOVL R8, (0*4)(BP)
- ADDL (1*4)(BP), R9 // H1 = b + H1
- MOVL R9, (1*4)(BP)
- ADDL (2*4)(BP), R10 // H2 = c + H2
- MOVL R10, (2*4)(BP)
- ADDL (3*4)(BP), R11 // H3 = d + H3
- MOVL R11, (3*4)(BP)
- ADDL (4*4)(BP), R12 // H4 = e + H4
- MOVL R12, (4*4)(BP)
- ADDL (5*4)(BP), R13 // H5 = f + H5
- MOVL R13, (5*4)(BP)
- ADDL (6*4)(BP), R14 // H6 = g + H6
- MOVL R14, (6*4)(BP)
- ADDL (7*4)(BP), R15 // H7 = h + H7
- MOVL R15, (7*4)(BP)
-
- ADDQ $64, SI
- CMPQ SI, 256(SP)
- JB loop
-
-end:
- RET
-
-avx2:
- MOVQ dig+0(FP), CTX // d.h[8]
- MOVQ p_base+8(FP), INP
- MOVQ p_len+16(FP), NUM_BYTES
-
- LEAQ -64(INP)(NUM_BYTES*1), NUM_BYTES // Pointer to the last block
- MOVQ NUM_BYTES, _INP_END(SP)
-
- CMPQ NUM_BYTES, INP
- JE avx2_only_one_block
-
- // Load initial digest
- MOVL 0(CTX), a // a = H0
- MOVL 4(CTX), b // b = H1
- MOVL 8(CTX), c // c = H2
- MOVL 12(CTX), d // d = H3
- MOVL 16(CTX), e // e = H4
- MOVL 20(CTX), f // f = H5
- MOVL 24(CTX), g // g = H6
- MOVL 28(CTX), h // h = H7
-
-avx2_loop0: // at each iteration works with one block (512 bit)
-
- VMOVDQU (0*32)(INP), XTMP0
- VMOVDQU (1*32)(INP), XTMP1
- VMOVDQU (2*32)(INP), XTMP2
- VMOVDQU (3*32)(INP), XTMP3
-
- VMOVDQU flip_mask<>(SB), BYTE_FLIP_MASK
-
- // Apply Byte Flip Mask: LE -> BE
- VPSHUFB BYTE_FLIP_MASK, XTMP0, XTMP0
- VPSHUFB BYTE_FLIP_MASK, XTMP1, XTMP1
- VPSHUFB BYTE_FLIP_MASK, XTMP2, XTMP2
- VPSHUFB BYTE_FLIP_MASK, XTMP3, XTMP3
-
- // Transpose data into high/low parts
- VPERM2I128 $0x20, XTMP2, XTMP0, XDWORD0 // w3, w2, w1, w0
- VPERM2I128 $0x31, XTMP2, XTMP0, XDWORD1 // w7, w6, w5, w4
- VPERM2I128 $0x20, XTMP3, XTMP1, XDWORD2 // w11, w10, w9, w8
- VPERM2I128 $0x31, XTMP3, XTMP1, XDWORD3 // w15, w14, w13, w12
-
- MOVQ $K256<>(SB), TBL // Loading address of table with round-specific constants
-
-avx2_last_block_enter:
- ADDQ $64, INP
- MOVQ INP, _INP(SP)
- XORQ SRND, SRND
-
-avx2_loop1: // for w0 - w47
- // Do 4 rounds and scheduling
- VPADDD 0*32(TBL)(SRND*1), XDWORD0, XFER
- VMOVDQU XFER, (_XFER + 0*32)(SP)(SRND*1)
- ROUND_AND_SCHED_N_0(_XFER + 0*32, a, b, c, d, e, f, g, h, XDWORD0, XDWORD1, XDWORD2, XDWORD3)
- ROUND_AND_SCHED_N_1(_XFER + 0*32, h, a, b, c, d, e, f, g, XDWORD0, XDWORD1, XDWORD2, XDWORD3)
- ROUND_AND_SCHED_N_2(_XFER + 0*32, g, h, a, b, c, d, e, f, XDWORD0, XDWORD1, XDWORD2, XDWORD3)
- ROUND_AND_SCHED_N_3(_XFER + 0*32, f, g, h, a, b, c, d, e, XDWORD0, XDWORD1, XDWORD2, XDWORD3)
-
- // Do 4 rounds and scheduling
- VPADDD 1*32(TBL)(SRND*1), XDWORD1, XFER
- VMOVDQU XFER, (_XFER + 1*32)(SP)(SRND*1)
- ROUND_AND_SCHED_N_0(_XFER + 1*32, e, f, g, h, a, b, c, d, XDWORD1, XDWORD2, XDWORD3, XDWORD0)
- ROUND_AND_SCHED_N_1(_XFER + 1*32, d, e, f, g, h, a, b, c, XDWORD1, XDWORD2, XDWORD3, XDWORD0)
- ROUND_AND_SCHED_N_2(_XFER + 1*32, c, d, e, f, g, h, a, b, XDWORD1, XDWORD2, XDWORD3, XDWORD0)
- ROUND_AND_SCHED_N_3(_XFER + 1*32, b, c, d, e, f, g, h, a, XDWORD1, XDWORD2, XDWORD3, XDWORD0)
-
- // Do 4 rounds and scheduling
- VPADDD 2*32(TBL)(SRND*1), XDWORD2, XFER
- VMOVDQU XFER, (_XFER + 2*32)(SP)(SRND*1)
- ROUND_AND_SCHED_N_0(_XFER + 2*32, a, b, c, d, e, f, g, h, XDWORD2, XDWORD3, XDWORD0, XDWORD1)
- ROUND_AND_SCHED_N_1(_XFER + 2*32, h, a, b, c, d, e, f, g, XDWORD2, XDWORD3, XDWORD0, XDWORD1)
- ROUND_AND_SCHED_N_2(_XFER + 2*32, g, h, a, b, c, d, e, f, XDWORD2, XDWORD3, XDWORD0, XDWORD1)
- ROUND_AND_SCHED_N_3(_XFER + 2*32, f, g, h, a, b, c, d, e, XDWORD2, XDWORD3, XDWORD0, XDWORD1)
-
- // Do 4 rounds and scheduling
- VPADDD 3*32(TBL)(SRND*1), XDWORD3, XFER
- VMOVDQU XFER, (_XFER + 3*32)(SP)(SRND*1)
- ROUND_AND_SCHED_N_0(_XFER + 3*32, e, f, g, h, a, b, c, d, XDWORD3, XDWORD0, XDWORD1, XDWORD2)
- ROUND_AND_SCHED_N_1(_XFER + 3*32, d, e, f, g, h, a, b, c, XDWORD3, XDWORD0, XDWORD1, XDWORD2)
- ROUND_AND_SCHED_N_2(_XFER + 3*32, c, d, e, f, g, h, a, b, XDWORD3, XDWORD0, XDWORD1, XDWORD2)
- ROUND_AND_SCHED_N_3(_XFER + 3*32, b, c, d, e, f, g, h, a, XDWORD3, XDWORD0, XDWORD1, XDWORD2)
-
- ADDQ $4*32, SRND
- CMPQ SRND, $3*4*32
- JB avx2_loop1
-
-avx2_loop2:
- // w48 - w63 processed with no scheduling (last 16 rounds)
- VPADDD 0*32(TBL)(SRND*1), XDWORD0, XFER
- VMOVDQU XFER, (_XFER + 0*32)(SP)(SRND*1)
- DO_ROUND_N_0(_XFER + 0*32, a, b, c, d, e, f, g, h, h)
- DO_ROUND_N_1(_XFER + 0*32, h, a, b, c, d, e, f, g, h)
- DO_ROUND_N_2(_XFER + 0*32, g, h, a, b, c, d, e, f, g)
- DO_ROUND_N_3(_XFER + 0*32, f, g, h, a, b, c, d, e, f)
-
- VPADDD 1*32(TBL)(SRND*1), XDWORD1, XFER
- VMOVDQU XFER, (_XFER + 1*32)(SP)(SRND*1)
- DO_ROUND_N_0(_XFER + 1*32, e, f, g, h, a, b, c, d, e)
- DO_ROUND_N_1(_XFER + 1*32, d, e, f, g, h, a, b, c, d)
- DO_ROUND_N_2(_XFER + 1*32, c, d, e, f, g, h, a, b, c)
- DO_ROUND_N_3(_XFER + 1*32, b, c, d, e, f, g, h, a, b)
-
- ADDQ $2*32, SRND
-
- VMOVDQU XDWORD2, XDWORD0
- VMOVDQU XDWORD3, XDWORD1
-
- CMPQ SRND, $4*4*32
- JB avx2_loop2
-
- MOVQ dig+0(FP), CTX // d.h[8]
- MOVQ _INP(SP), INP
-
- addm( 0(CTX), a)
- addm( 4(CTX), b)
- addm( 8(CTX), c)
- addm( 12(CTX), d)
- addm( 16(CTX), e)
- addm( 20(CTX), f)
- addm( 24(CTX), g)
- addm( 28(CTX), h)
-
- CMPQ _INP_END(SP), INP
- JB done_hash
-
- XORQ SRND, SRND
-
-avx2_loop3: // Do second block using previously scheduled results
- DO_ROUND_N_0(_XFER + 0*32 + 16, a, b, c, d, e, f, g, h, a)
- DO_ROUND_N_1(_XFER + 0*32 + 16, h, a, b, c, d, e, f, g, h)
- DO_ROUND_N_2(_XFER + 0*32 + 16, g, h, a, b, c, d, e, f, g)
- DO_ROUND_N_3(_XFER + 0*32 + 16, f, g, h, a, b, c, d, e, f)
-
- DO_ROUND_N_0(_XFER + 1*32 + 16, e, f, g, h, a, b, c, d, e)
- DO_ROUND_N_1(_XFER + 1*32 + 16, d, e, f, g, h, a, b, c, d)
- DO_ROUND_N_2(_XFER + 1*32 + 16, c, d, e, f, g, h, a, b, c)
- DO_ROUND_N_3(_XFER + 1*32 + 16, b, c, d, e, f, g, h, a, b)
-
- ADDQ $2*32, SRND
- CMPQ SRND, $4*4*32
- JB avx2_loop3
-
- MOVQ dig+0(FP), CTX // d.h[8]
- MOVQ _INP(SP), INP
- ADDQ $64, INP
-
- addm( 0(CTX), a)
- addm( 4(CTX), b)
- addm( 8(CTX), c)
- addm( 12(CTX), d)
- addm( 16(CTX), e)
- addm( 20(CTX), f)
- addm( 24(CTX), g)
- addm( 28(CTX), h)
-
- CMPQ _INP_END(SP), INP
- JA avx2_loop0
- JB done_hash
-
-avx2_do_last_block:
-
- VMOVDQU 0(INP), XWORD0
- VMOVDQU 16(INP), XWORD1
- VMOVDQU 32(INP), XWORD2
- VMOVDQU 48(INP), XWORD3
-
- VMOVDQU flip_mask<>(SB), BYTE_FLIP_MASK
-
- VPSHUFB X_BYTE_FLIP_MASK, XWORD0, XWORD0
- VPSHUFB X_BYTE_FLIP_MASK, XWORD1, XWORD1
- VPSHUFB X_BYTE_FLIP_MASK, XWORD2, XWORD2
- VPSHUFB X_BYTE_FLIP_MASK, XWORD3, XWORD3
-
- MOVQ $K256<>(SB), TBL
-
- JMP avx2_last_block_enter
-
-avx2_only_one_block:
- // Load initial digest
- MOVL 0(CTX), a // a = H0
- MOVL 4(CTX), b // b = H1
- MOVL 8(CTX), c // c = H2
- MOVL 12(CTX), d // d = H3
- MOVL 16(CTX), e // e = H4
- MOVL 20(CTX), f // f = H5
- MOVL 24(CTX), g // g = H6
- MOVL 28(CTX), h // h = H7
-
- JMP avx2_do_last_block
-
-done_hash:
- VZEROUPPER
- RET
-
-// shuffle byte order from LE to BE
-DATA flip_mask<>+0x00(SB)/8, $0x0405060700010203
-DATA flip_mask<>+0x08(SB)/8, $0x0c0d0e0f08090a0b
-DATA flip_mask<>+0x10(SB)/8, $0x0405060700010203
-DATA flip_mask<>+0x18(SB)/8, $0x0c0d0e0f08090a0b
-GLOBL flip_mask<>(SB), 8, $32
-
-// shuffle xBxA -> 00BA
-DATA shuff_00BA<>+0x00(SB)/8, $0x0b0a090803020100
-DATA shuff_00BA<>+0x08(SB)/8, $0xFFFFFFFFFFFFFFFF
-DATA shuff_00BA<>+0x10(SB)/8, $0x0b0a090803020100
-DATA shuff_00BA<>+0x18(SB)/8, $0xFFFFFFFFFFFFFFFF
-GLOBL shuff_00BA<>(SB), 8, $32
-
-// shuffle xDxC -> DC00
-DATA shuff_DC00<>+0x00(SB)/8, $0xFFFFFFFFFFFFFFFF
-DATA shuff_DC00<>+0x08(SB)/8, $0x0b0a090803020100
-DATA shuff_DC00<>+0x10(SB)/8, $0xFFFFFFFFFFFFFFFF
-DATA shuff_DC00<>+0x18(SB)/8, $0x0b0a090803020100
-GLOBL shuff_DC00<>(SB), 8, $32
-
-// Round specific constants
-DATA K256<>+0x00(SB)/4, $0x428a2f98 // k1
-DATA K256<>+0x04(SB)/4, $0x71374491 // k2
-DATA K256<>+0x08(SB)/4, $0xb5c0fbcf // k3
-DATA K256<>+0x0c(SB)/4, $0xe9b5dba5 // k4
-DATA K256<>+0x10(SB)/4, $0x428a2f98 // k1
-DATA K256<>+0x14(SB)/4, $0x71374491 // k2
-DATA K256<>+0x18(SB)/4, $0xb5c0fbcf // k3
-DATA K256<>+0x1c(SB)/4, $0xe9b5dba5 // k4
-
-DATA K256<>+0x20(SB)/4, $0x3956c25b // k5 - k8
-DATA K256<>+0x24(SB)/4, $0x59f111f1
-DATA K256<>+0x28(SB)/4, $0x923f82a4
-DATA K256<>+0x2c(SB)/4, $0xab1c5ed5
-DATA K256<>+0x30(SB)/4, $0x3956c25b
-DATA K256<>+0x34(SB)/4, $0x59f111f1
-DATA K256<>+0x38(SB)/4, $0x923f82a4
-DATA K256<>+0x3c(SB)/4, $0xab1c5ed5
-
-DATA K256<>+0x40(SB)/4, $0xd807aa98 // k9 - k12
-DATA K256<>+0x44(SB)/4, $0x12835b01
-DATA K256<>+0x48(SB)/4, $0x243185be
-DATA K256<>+0x4c(SB)/4, $0x550c7dc3
-DATA K256<>+0x50(SB)/4, $0xd807aa98
-DATA K256<>+0x54(SB)/4, $0x12835b01
-DATA K256<>+0x58(SB)/4, $0x243185be
-DATA K256<>+0x5c(SB)/4, $0x550c7dc3
-
-DATA K256<>+0x60(SB)/4, $0x72be5d74 // k13 - k16
-DATA K256<>+0x64(SB)/4, $0x80deb1fe
-DATA K256<>+0x68(SB)/4, $0x9bdc06a7
-DATA K256<>+0x6c(SB)/4, $0xc19bf174
-DATA K256<>+0x70(SB)/4, $0x72be5d74
-DATA K256<>+0x74(SB)/4, $0x80deb1fe
-DATA K256<>+0x78(SB)/4, $0x9bdc06a7
-DATA K256<>+0x7c(SB)/4, $0xc19bf174
-
-DATA K256<>+0x80(SB)/4, $0xe49b69c1 // k17 - k20
-DATA K256<>+0x84(SB)/4, $0xefbe4786
-DATA K256<>+0x88(SB)/4, $0x0fc19dc6
-DATA K256<>+0x8c(SB)/4, $0x240ca1cc
-DATA K256<>+0x90(SB)/4, $0xe49b69c1
-DATA K256<>+0x94(SB)/4, $0xefbe4786
-DATA K256<>+0x98(SB)/4, $0x0fc19dc6
-DATA K256<>+0x9c(SB)/4, $0x240ca1cc
-
-DATA K256<>+0xa0(SB)/4, $0x2de92c6f // k21 - k24
-DATA K256<>+0xa4(SB)/4, $0x4a7484aa
-DATA K256<>+0xa8(SB)/4, $0x5cb0a9dc
-DATA K256<>+0xac(SB)/4, $0x76f988da
-DATA K256<>+0xb0(SB)/4, $0x2de92c6f
-DATA K256<>+0xb4(SB)/4, $0x4a7484aa
-DATA K256<>+0xb8(SB)/4, $0x5cb0a9dc
-DATA K256<>+0xbc(SB)/4, $0x76f988da
-
-DATA K256<>+0xc0(SB)/4, $0x983e5152 // k25 - k28
-DATA K256<>+0xc4(SB)/4, $0xa831c66d
-DATA K256<>+0xc8(SB)/4, $0xb00327c8
-DATA K256<>+0xcc(SB)/4, $0xbf597fc7
-DATA K256<>+0xd0(SB)/4, $0x983e5152
-DATA K256<>+0xd4(SB)/4, $0xa831c66d
-DATA K256<>+0xd8(SB)/4, $0xb00327c8
-DATA K256<>+0xdc(SB)/4, $0xbf597fc7
-
-DATA K256<>+0xe0(SB)/4, $0xc6e00bf3 // k29 - k32
-DATA K256<>+0xe4(SB)/4, $0xd5a79147
-DATA K256<>+0xe8(SB)/4, $0x06ca6351
-DATA K256<>+0xec(SB)/4, $0x14292967
-DATA K256<>+0xf0(SB)/4, $0xc6e00bf3
-DATA K256<>+0xf4(SB)/4, $0xd5a79147
-DATA K256<>+0xf8(SB)/4, $0x06ca6351
-DATA K256<>+0xfc(SB)/4, $0x14292967
-
-DATA K256<>+0x100(SB)/4, $0x27b70a85
-DATA K256<>+0x104(SB)/4, $0x2e1b2138
-DATA K256<>+0x108(SB)/4, $0x4d2c6dfc
-DATA K256<>+0x10c(SB)/4, $0x53380d13
-DATA K256<>+0x110(SB)/4, $0x27b70a85
-DATA K256<>+0x114(SB)/4, $0x2e1b2138
-DATA K256<>+0x118(SB)/4, $0x4d2c6dfc
-DATA K256<>+0x11c(SB)/4, $0x53380d13
-
-DATA K256<>+0x120(SB)/4, $0x650a7354
-DATA K256<>+0x124(SB)/4, $0x766a0abb
-DATA K256<>+0x128(SB)/4, $0x81c2c92e
-DATA K256<>+0x12c(SB)/4, $0x92722c85
-DATA K256<>+0x130(SB)/4, $0x650a7354
-DATA K256<>+0x134(SB)/4, $0x766a0abb
-DATA K256<>+0x138(SB)/4, $0x81c2c92e
-DATA K256<>+0x13c(SB)/4, $0x92722c85
-
-DATA K256<>+0x140(SB)/4, $0xa2bfe8a1
-DATA K256<>+0x144(SB)/4, $0xa81a664b
-DATA K256<>+0x148(SB)/4, $0xc24b8b70
-DATA K256<>+0x14c(SB)/4, $0xc76c51a3
-DATA K256<>+0x150(SB)/4, $0xa2bfe8a1
-DATA K256<>+0x154(SB)/4, $0xa81a664b
-DATA K256<>+0x158(SB)/4, $0xc24b8b70
-DATA K256<>+0x15c(SB)/4, $0xc76c51a3
-
-DATA K256<>+0x160(SB)/4, $0xd192e819
-DATA K256<>+0x164(SB)/4, $0xd6990624
-DATA K256<>+0x168(SB)/4, $0xf40e3585
-DATA K256<>+0x16c(SB)/4, $0x106aa070
-DATA K256<>+0x170(SB)/4, $0xd192e819
-DATA K256<>+0x174(SB)/4, $0xd6990624
-DATA K256<>+0x178(SB)/4, $0xf40e3585
-DATA K256<>+0x17c(SB)/4, $0x106aa070
-
-DATA K256<>+0x180(SB)/4, $0x19a4c116
-DATA K256<>+0x184(SB)/4, $0x1e376c08
-DATA K256<>+0x188(SB)/4, $0x2748774c
-DATA K256<>+0x18c(SB)/4, $0x34b0bcb5
-DATA K256<>+0x190(SB)/4, $0x19a4c116
-DATA K256<>+0x194(SB)/4, $0x1e376c08
-DATA K256<>+0x198(SB)/4, $0x2748774c
-DATA K256<>+0x19c(SB)/4, $0x34b0bcb5
-
-DATA K256<>+0x1a0(SB)/4, $0x391c0cb3
-DATA K256<>+0x1a4(SB)/4, $0x4ed8aa4a
-DATA K256<>+0x1a8(SB)/4, $0x5b9cca4f
-DATA K256<>+0x1ac(SB)/4, $0x682e6ff3
-DATA K256<>+0x1b0(SB)/4, $0x391c0cb3
-DATA K256<>+0x1b4(SB)/4, $0x4ed8aa4a
-DATA K256<>+0x1b8(SB)/4, $0x5b9cca4f
-DATA K256<>+0x1bc(SB)/4, $0x682e6ff3
-
-DATA K256<>+0x1c0(SB)/4, $0x748f82ee
-DATA K256<>+0x1c4(SB)/4, $0x78a5636f
-DATA K256<>+0x1c8(SB)/4, $0x84c87814
-DATA K256<>+0x1cc(SB)/4, $0x8cc70208
-DATA K256<>+0x1d0(SB)/4, $0x748f82ee
-DATA K256<>+0x1d4(SB)/4, $0x78a5636f
-DATA K256<>+0x1d8(SB)/4, $0x84c87814
-DATA K256<>+0x1dc(SB)/4, $0x8cc70208
-
-DATA K256<>+0x1e0(SB)/4, $0x90befffa
-DATA K256<>+0x1e4(SB)/4, $0xa4506ceb
-DATA K256<>+0x1e8(SB)/4, $0xbef9a3f7
-DATA K256<>+0x1ec(SB)/4, $0xc67178f2
-DATA K256<>+0x1f0(SB)/4, $0x90befffa
-DATA K256<>+0x1f4(SB)/4, $0xa4506ceb
-DATA K256<>+0x1f8(SB)/4, $0xbef9a3f7
-DATA K256<>+0x1fc(SB)/4, $0xc67178f2
-
-GLOBL K256<>(SB), (NOPTR + RODATA), $512
diff --git a/contrib/go/_std_1.20/src/crypto/sha256/sha256block_decl.go b/contrib/go/_std_1.20/src/crypto/sha256/sha256block_decl.go
deleted file mode 100644
index 18ba1c0ec1..0000000000
--- a/contrib/go/_std_1.20/src/crypto/sha256/sha256block_decl.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2013 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.
-
-//go:build 386 || amd64 || s390x || ppc64le || ppc64
-
-package sha256
-
-//go:noescape
-
-func block(dig *digest, p []byte)
diff --git a/contrib/go/_std_1.20/src/crypto/sha256/ya.make b/contrib/go/_std_1.20/src/crypto/sha256/ya.make
deleted file mode 100644
index 0eabff3645..0000000000
--- a/contrib/go/_std_1.20/src/crypto/sha256/ya.make
+++ /dev/null
@@ -1,23 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- sha256.go
- sha256block.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- sha256block_arm64.go
- sha256block_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- sha256block_amd64.go
- sha256block_amd64.s
- sha256block_decl.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/sha512/ya.make b/contrib/go/_std_1.20/src/crypto/sha512/ya.make
deleted file mode 100644
index 7e0fb8e3bc..0000000000
--- a/contrib/go/_std_1.20/src/crypto/sha512/ya.make
+++ /dev/null
@@ -1,22 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- sha512.go
- sha512block.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- sha512block_arm64.go
- sha512block_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- sha512block_amd64.go
- sha512block_amd64.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/subtle/ya.make b/contrib/go/_std_1.20/src/crypto/subtle/ya.make
deleted file mode 100644
index 835787832e..0000000000
--- a/contrib/go/_std_1.20/src/crypto/subtle/ya.make
+++ /dev/null
@@ -1,22 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- constant_time.go
- xor.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- xor_arm64.go
- xor_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- xor_amd64.go
- xor_amd64.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/tls/alert.go b/contrib/go/_std_1.20/src/crypto/tls/alert.go
deleted file mode 100644
index 4790b73724..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/alert.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2009 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 tls
-
-import "strconv"
-
-type alert uint8
-
-const (
- // alert level
- alertLevelWarning = 1
- alertLevelError = 2
-)
-
-const (
- alertCloseNotify alert = 0
- alertUnexpectedMessage alert = 10
- alertBadRecordMAC alert = 20
- alertDecryptionFailed alert = 21
- alertRecordOverflow alert = 22
- alertDecompressionFailure alert = 30
- alertHandshakeFailure alert = 40
- alertBadCertificate alert = 42
- alertUnsupportedCertificate alert = 43
- alertCertificateRevoked alert = 44
- alertCertificateExpired alert = 45
- alertCertificateUnknown alert = 46
- alertIllegalParameter alert = 47
- alertUnknownCA alert = 48
- alertAccessDenied alert = 49
- alertDecodeError alert = 50
- alertDecryptError alert = 51
- alertExportRestriction alert = 60
- alertProtocolVersion alert = 70
- alertInsufficientSecurity alert = 71
- alertInternalError alert = 80
- alertInappropriateFallback alert = 86
- alertUserCanceled alert = 90
- alertNoRenegotiation alert = 100
- alertMissingExtension alert = 109
- alertUnsupportedExtension alert = 110
- alertCertificateUnobtainable alert = 111
- alertUnrecognizedName alert = 112
- alertBadCertificateStatusResponse alert = 113
- alertBadCertificateHashValue alert = 114
- alertUnknownPSKIdentity alert = 115
- alertCertificateRequired alert = 116
- alertNoApplicationProtocol alert = 120
-)
-
-var alertText = map[alert]string{
- alertCloseNotify: "close notify",
- alertUnexpectedMessage: "unexpected message",
- alertBadRecordMAC: "bad record MAC",
- alertDecryptionFailed: "decryption failed",
- alertRecordOverflow: "record overflow",
- alertDecompressionFailure: "decompression failure",
- alertHandshakeFailure: "handshake failure",
- alertBadCertificate: "bad certificate",
- alertUnsupportedCertificate: "unsupported certificate",
- alertCertificateRevoked: "revoked certificate",
- alertCertificateExpired: "expired certificate",
- alertCertificateUnknown: "unknown certificate",
- alertIllegalParameter: "illegal parameter",
- alertUnknownCA: "unknown certificate authority",
- alertAccessDenied: "access denied",
- alertDecodeError: "error decoding message",
- alertDecryptError: "error decrypting message",
- alertExportRestriction: "export restriction",
- alertProtocolVersion: "protocol version not supported",
- alertInsufficientSecurity: "insufficient security level",
- alertInternalError: "internal error",
- alertInappropriateFallback: "inappropriate fallback",
- alertUserCanceled: "user canceled",
- alertNoRenegotiation: "no renegotiation",
- alertMissingExtension: "missing extension",
- alertUnsupportedExtension: "unsupported extension",
- alertCertificateUnobtainable: "certificate unobtainable",
- alertUnrecognizedName: "unrecognized name",
- alertBadCertificateStatusResponse: "bad certificate status response",
- alertBadCertificateHashValue: "bad certificate hash value",
- alertUnknownPSKIdentity: "unknown PSK identity",
- alertCertificateRequired: "certificate required",
- alertNoApplicationProtocol: "no application protocol",
-}
-
-func (e alert) String() string {
- s, ok := alertText[e]
- if ok {
- return "tls: " + s
- }
- return "tls: alert(" + strconv.Itoa(int(e)) + ")"
-}
-
-func (e alert) Error() string {
- return e.String()
-}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/cache.go b/contrib/go/_std_1.20/src/crypto/tls/cache.go
deleted file mode 100644
index fc8f2c0844..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/cache.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2022 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 tls
-
-import (
- "crypto/x509"
- "runtime"
- "sync"
- "sync/atomic"
-)
-
-type cacheEntry struct {
- refs atomic.Int64
- cert *x509.Certificate
-}
-
-// certCache implements an intern table for reference counted x509.Certificates,
-// implemented in a similar fashion to BoringSSL's CRYPTO_BUFFER_POOL. This
-// allows for a single x509.Certificate to be kept in memory and referenced from
-// multiple Conns. Returned references should not be mutated by callers. Certificates
-// are still safe to use after they are removed from the cache.
-//
-// Certificates are returned wrapped in a activeCert struct that should be held by
-// the caller. When references to the activeCert are freed, the number of references
-// to the certificate in the cache is decremented. Once the number of references
-// reaches zero, the entry is evicted from the cache.
-//
-// The main difference between this implementation and CRYPTO_BUFFER_POOL is that
-// CRYPTO_BUFFER_POOL is a more generic structure which supports blobs of data,
-// rather than specific structures. Since we only care about x509.Certificates,
-// certCache is implemented as a specific cache, rather than a generic one.
-//
-// See https://boringssl.googlesource.com/boringssl/+/master/include/openssl/pool.h
-// and https://boringssl.googlesource.com/boringssl/+/master/crypto/pool/pool.c
-// for the BoringSSL reference.
-type certCache struct {
- sync.Map
-}
-
-var clientCertCache = new(certCache)
-
-// activeCert is a handle to a certificate held in the cache. Once there are
-// no alive activeCerts for a given certificate, the certificate is removed
-// from the cache by a finalizer.
-type activeCert struct {
- cert *x509.Certificate
-}
-
-// active increments the number of references to the entry, wraps the
-// certificate in the entry in a activeCert, and sets the finalizer.
-//
-// Note that there is a race between active and the finalizer set on the
-// returned activeCert, triggered if active is called after the ref count is
-// decremented such that refs may be > 0 when evict is called. We consider this
-// safe, since the caller holding an activeCert for an entry that is no longer
-// in the cache is fine, with the only side effect being the memory overhead of
-// there being more than one distinct reference to a certificate alive at once.
-func (cc *certCache) active(e *cacheEntry) *activeCert {
- e.refs.Add(1)
- a := &activeCert{e.cert}
- runtime.SetFinalizer(a, func(_ *activeCert) {
- if e.refs.Add(-1) == 0 {
- cc.evict(e)
- }
- })
- return a
-}
-
-// evict removes a cacheEntry from the cache.
-func (cc *certCache) evict(e *cacheEntry) {
- cc.Delete(string(e.cert.Raw))
-}
-
-// newCert returns a x509.Certificate parsed from der. If there is already a copy
-// of the certificate in the cache, a reference to the existing certificate will
-// be returned. Otherwise, a fresh certificate will be added to the cache, and
-// the reference returned. The returned reference should not be mutated.
-func (cc *certCache) newCert(der []byte) (*activeCert, error) {
- if entry, ok := cc.Load(string(der)); ok {
- return cc.active(entry.(*cacheEntry)), nil
- }
-
- cert, err := x509.ParseCertificate(der)
- if err != nil {
- return nil, err
- }
-
- entry := &cacheEntry{cert: cert}
- if entry, loaded := cc.LoadOrStore(string(der), entry); loaded {
- return cc.active(entry.(*cacheEntry)), nil
- }
- return cc.active(entry), nil
-}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/cipher_suites.go b/contrib/go/_std_1.20/src/crypto/tls/cipher_suites.go
deleted file mode 100644
index 04e6dfe018..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/cipher_suites.go
+++ /dev/null
@@ -1,702 +0,0 @@
-// Copyright 2010 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 tls
-
-import (
- "crypto"
- "crypto/aes"
- "crypto/cipher"
- "crypto/des"
- "crypto/hmac"
- "crypto/internal/boring"
- "crypto/rc4"
- "crypto/sha1"
- "crypto/sha256"
- "fmt"
- "hash"
- "internal/cpu"
- "runtime"
-
- "golang.org/x/crypto/chacha20poly1305"
-)
-
-// CipherSuite is a TLS cipher suite. Note that most functions in this package
-// accept and expose cipher suite IDs instead of this type.
-type CipherSuite struct {
- ID uint16
- Name string
-
- // Supported versions is the list of TLS protocol versions that can
- // negotiate this cipher suite.
- SupportedVersions []uint16
-
- // Insecure is true if the cipher suite has known security issues
- // due to its primitives, design, or implementation.
- Insecure bool
-}
-
-var (
- supportedUpToTLS12 = []uint16{VersionTLS10, VersionTLS11, VersionTLS12}
- supportedOnlyTLS12 = []uint16{VersionTLS12}
- supportedOnlyTLS13 = []uint16{VersionTLS13}
-)
-
-// CipherSuites returns a list of cipher suites currently implemented by this
-// package, excluding those with security issues, which are returned by
-// InsecureCipherSuites.
-//
-// The list is sorted by ID. Note that the default cipher suites selected by
-// this package might depend on logic that can't be captured by a static list,
-// and might not match those returned by this function.
-func CipherSuites() []*CipherSuite {
- return []*CipherSuite{
- {TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
- {TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
- {TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
- {TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
-
- {TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256", supportedOnlyTLS13, false},
- {TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384", supportedOnlyTLS13, false},
- {TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256", supportedOnlyTLS13, false},
-
- {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
- {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
- {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
- {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
- {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
- {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
- {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
- {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
- {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
- {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
- }
-}
-
-// InsecureCipherSuites returns a list of cipher suites currently implemented by
-// this package and which have security issues.
-//
-// Most applications should not use the cipher suites in this list, and should
-// only use those returned by CipherSuites.
-func InsecureCipherSuites() []*CipherSuite {
- // This list includes RC4, CBC_SHA256, and 3DES cipher suites. See
- // cipherSuitesPreferenceOrder for details.
- return []*CipherSuite{
- {TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
- {TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
- {TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
- {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
- {TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
- {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
- {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
- {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
- }
-}
-
-// CipherSuiteName returns the standard name for the passed cipher suite ID
-// (e.g. "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), or a fallback representation
-// of the ID value if the cipher suite is not implemented by this package.
-func CipherSuiteName(id uint16) string {
- for _, c := range CipherSuites() {
- if c.ID == id {
- return c.Name
- }
- }
- for _, c := range InsecureCipherSuites() {
- if c.ID == id {
- return c.Name
- }
- }
- return fmt.Sprintf("0x%04X", id)
-}
-
-const (
- // suiteECDHE indicates that the cipher suite involves elliptic curve
- // Diffie-Hellman. This means that it should only be selected when the
- // client indicates that it supports ECC with a curve and point format
- // that we're happy with.
- suiteECDHE = 1 << iota
- // suiteECSign indicates that the cipher suite involves an ECDSA or
- // EdDSA signature and therefore may only be selected when the server's
- // certificate is ECDSA or EdDSA. If this is not set then the cipher suite
- // is RSA based.
- suiteECSign
- // suiteTLS12 indicates that the cipher suite should only be advertised
- // and accepted when using TLS 1.2.
- suiteTLS12
- // suiteSHA384 indicates that the cipher suite uses SHA384 as the
- // handshake hash.
- suiteSHA384
-)
-
-// A cipherSuite is a TLS 1.0–1.2 cipher suite, and defines the key exchange
-// mechanism, as well as the cipher+MAC pair or the AEAD.
-type cipherSuite struct {
- id uint16
- // the lengths, in bytes, of the key material needed for each component.
- keyLen int
- macLen int
- ivLen int
- ka func(version uint16) keyAgreement
- // flags is a bitmask of the suite* values, above.
- flags int
- cipher func(key, iv []byte, isRead bool) any
- mac func(key []byte) hash.Hash
- aead func(key, fixedNonce []byte) aead
-}
-
-var cipherSuites = []*cipherSuite{ // TODO: replace with a map, since the order doesn't matter.
- {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
- {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
- {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
- {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadAESGCM},
- {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
- {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
- {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil},
- {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
- {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, cipherAES, macSHA256, nil},
- {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
- {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
- {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
- {TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
- {TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
- {TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil},
- {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
- {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
- {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
- {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
- {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil},
- {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil},
- {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherRC4, macSHA1, nil},
-}
-
-// selectCipherSuite returns the first TLS 1.0–1.2 cipher suite from ids which
-// is also in supportedIDs and passes the ok filter.
-func selectCipherSuite(ids, supportedIDs []uint16, ok func(*cipherSuite) bool) *cipherSuite {
- for _, id := range ids {
- candidate := cipherSuiteByID(id)
- if candidate == nil || !ok(candidate) {
- continue
- }
-
- for _, suppID := range supportedIDs {
- if id == suppID {
- return candidate
- }
- }
- }
- return nil
-}
-
-// A cipherSuiteTLS13 defines only the pair of the AEAD algorithm and hash
-// algorithm to be used with HKDF. See RFC 8446, Appendix B.4.
-type cipherSuiteTLS13 struct {
- id uint16
- keyLen int
- aead func(key, fixedNonce []byte) aead
- hash crypto.Hash
-}
-
-var cipherSuitesTLS13 = []*cipherSuiteTLS13{ // TODO: replace with a map.
- {TLS_AES_128_GCM_SHA256, 16, aeadAESGCMTLS13, crypto.SHA256},
- {TLS_CHACHA20_POLY1305_SHA256, 32, aeadChaCha20Poly1305, crypto.SHA256},
- {TLS_AES_256_GCM_SHA384, 32, aeadAESGCMTLS13, crypto.SHA384},
-}
-
-// cipherSuitesPreferenceOrder is the order in which we'll select (on the
-// server) or advertise (on the client) TLS 1.0–1.2 cipher suites.
-//
-// Cipher suites are filtered but not reordered based on the application and
-// peer's preferences, meaning we'll never select a suite lower in this list if
-// any higher one is available. This makes it more defensible to keep weaker
-// cipher suites enabled, especially on the server side where we get the last
-// word, since there are no known downgrade attacks on cipher suites selection.
-//
-// The list is sorted by applying the following priority rules, stopping at the
-// first (most important) applicable one:
-//
-// - Anything else comes before RC4
-//
-// RC4 has practically exploitable biases. See https://www.rc4nomore.com.
-//
-// - Anything else comes before CBC_SHA256
-//
-// SHA-256 variants of the CBC ciphersuites don't implement any Lucky13
-// countermeasures. See http://www.isg.rhul.ac.uk/tls/Lucky13.html and
-// https://www.imperialviolet.org/2013/02/04/luckythirteen.html.
-//
-// - Anything else comes before 3DES
-//
-// 3DES has 64-bit blocks, which makes it fundamentally susceptible to
-// birthday attacks. See https://sweet32.info.
-//
-// - ECDHE comes before anything else
-//
-// Once we got the broken stuff out of the way, the most important
-// property a cipher suite can have is forward secrecy. We don't
-// implement FFDHE, so that means ECDHE.
-//
-// - AEADs come before CBC ciphers
-//
-// Even with Lucky13 countermeasures, MAC-then-Encrypt CBC cipher suites
-// are fundamentally fragile, and suffered from an endless sequence of
-// padding oracle attacks. See https://eprint.iacr.org/2015/1129,
-// https://www.imperialviolet.org/2014/12/08/poodleagain.html, and
-// https://blog.cloudflare.com/yet-another-padding-oracle-in-openssl-cbc-ciphersuites/.
-//
-// - AES comes before ChaCha20
-//
-// When AES hardware is available, AES-128-GCM and AES-256-GCM are faster
-// than ChaCha20Poly1305.
-//
-// When AES hardware is not available, AES-128-GCM is one or more of: much
-// slower, way more complex, and less safe (because not constant time)
-// than ChaCha20Poly1305.
-//
-// We use this list if we think both peers have AES hardware, and
-// cipherSuitesPreferenceOrderNoAES otherwise.
-//
-// - AES-128 comes before AES-256
-//
-// The only potential advantages of AES-256 are better multi-target
-// margins, and hypothetical post-quantum properties. Neither apply to
-// TLS, and AES-256 is slower due to its four extra rounds (which don't
-// contribute to the advantages above).
-//
-// - ECDSA comes before RSA
-//
-// The relative order of ECDSA and RSA cipher suites doesn't matter,
-// as they depend on the certificate. Pick one to get a stable order.
-var cipherSuitesPreferenceOrder = []uint16{
- // AEADs w/ ECDHE
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-
- // CBC w/ ECDHE
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
-
- // AEADs w/o ECDHE
- TLS_RSA_WITH_AES_128_GCM_SHA256,
- TLS_RSA_WITH_AES_256_GCM_SHA384,
-
- // CBC w/o ECDHE
- TLS_RSA_WITH_AES_128_CBC_SHA,
- TLS_RSA_WITH_AES_256_CBC_SHA,
-
- // 3DES
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
- TLS_RSA_WITH_3DES_EDE_CBC_SHA,
-
- // CBC_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
- TLS_RSA_WITH_AES_128_CBC_SHA256,
-
- // RC4
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- TLS_RSA_WITH_RC4_128_SHA,
-}
-
-var cipherSuitesPreferenceOrderNoAES = []uint16{
- // ChaCha20Poly1305
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
-
- // AES-GCM w/ ECDHE
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
-
- // The rest of cipherSuitesPreferenceOrder.
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
- TLS_RSA_WITH_AES_128_GCM_SHA256,
- TLS_RSA_WITH_AES_256_GCM_SHA384,
- TLS_RSA_WITH_AES_128_CBC_SHA,
- TLS_RSA_WITH_AES_256_CBC_SHA,
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
- TLS_RSA_WITH_3DES_EDE_CBC_SHA,
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
- TLS_RSA_WITH_AES_128_CBC_SHA256,
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- TLS_RSA_WITH_RC4_128_SHA,
-}
-
-// disabledCipherSuites are not used unless explicitly listed in
-// Config.CipherSuites. They MUST be at the end of cipherSuitesPreferenceOrder.
-var disabledCipherSuites = []uint16{
- // CBC_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
- TLS_RSA_WITH_AES_128_CBC_SHA256,
-
- // RC4
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- TLS_RSA_WITH_RC4_128_SHA,
-}
-
-var (
- defaultCipherSuitesLen = len(cipherSuitesPreferenceOrder) - len(disabledCipherSuites)
- defaultCipherSuites = cipherSuitesPreferenceOrder[:defaultCipherSuitesLen]
-)
-
-// defaultCipherSuitesTLS13 is also the preference order, since there are no
-// disabled by default TLS 1.3 cipher suites. The same AES vs ChaCha20 logic as
-// cipherSuitesPreferenceOrder applies.
-var defaultCipherSuitesTLS13 = []uint16{
- TLS_AES_128_GCM_SHA256,
- TLS_AES_256_GCM_SHA384,
- TLS_CHACHA20_POLY1305_SHA256,
-}
-
-var defaultCipherSuitesTLS13NoAES = []uint16{
- TLS_CHACHA20_POLY1305_SHA256,
- TLS_AES_128_GCM_SHA256,
- TLS_AES_256_GCM_SHA384,
-}
-
-var (
- hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ
- hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
- // Keep in sync with crypto/aes/cipher_s390x.go.
- hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR &&
- (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)
-
- hasAESGCMHardwareSupport = runtime.GOARCH == "amd64" && hasGCMAsmAMD64 ||
- runtime.GOARCH == "arm64" && hasGCMAsmARM64 ||
- runtime.GOARCH == "s390x" && hasGCMAsmS390X
-)
-
-var aesgcmCiphers = map[uint16]bool{
- // TLS 1.2
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: true,
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: true,
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true,
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true,
- // TLS 1.3
- TLS_AES_128_GCM_SHA256: true,
- TLS_AES_256_GCM_SHA384: true,
-}
-
-var nonAESGCMAEADCiphers = map[uint16]bool{
- // TLS 1.2
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: true,
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: true,
- // TLS 1.3
- TLS_CHACHA20_POLY1305_SHA256: true,
-}
-
-// aesgcmPreferred returns whether the first known cipher in the preference list
-// is an AES-GCM cipher, implying the peer has hardware support for it.
-func aesgcmPreferred(ciphers []uint16) bool {
- for _, cID := range ciphers {
- if c := cipherSuiteByID(cID); c != nil {
- return aesgcmCiphers[cID]
- }
- if c := cipherSuiteTLS13ByID(cID); c != nil {
- return aesgcmCiphers[cID]
- }
- }
- return false
-}
-
-func cipherRC4(key, iv []byte, isRead bool) any {
- cipher, _ := rc4.NewCipher(key)
- return cipher
-}
-
-func cipher3DES(key, iv []byte, isRead bool) any {
- block, _ := des.NewTripleDESCipher(key)
- if isRead {
- return cipher.NewCBCDecrypter(block, iv)
- }
- return cipher.NewCBCEncrypter(block, iv)
-}
-
-func cipherAES(key, iv []byte, isRead bool) any {
- block, _ := aes.NewCipher(key)
- if isRead {
- return cipher.NewCBCDecrypter(block, iv)
- }
- return cipher.NewCBCEncrypter(block, iv)
-}
-
-// macSHA1 returns a SHA-1 based constant time MAC.
-func macSHA1(key []byte) hash.Hash {
- h := sha1.New
- // The BoringCrypto SHA1 does not have a constant-time
- // checksum function, so don't try to use it.
- if !boring.Enabled {
- h = newConstantTimeHash(h)
- }
- return hmac.New(h, key)
-}
-
-// macSHA256 returns a SHA-256 based MAC. This is only supported in TLS 1.2 and
-// is currently only used in disabled-by-default cipher suites.
-func macSHA256(key []byte) hash.Hash {
- return hmac.New(sha256.New, key)
-}
-
-type aead interface {
- cipher.AEAD
-
- // explicitNonceLen returns the number of bytes of explicit nonce
- // included in each record. This is eight for older AEADs and
- // zero for modern ones.
- explicitNonceLen() int
-}
-
-const (
- aeadNonceLength = 12
- noncePrefixLength = 4
-)
-
-// prefixNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to
-// each call.
-type prefixNonceAEAD struct {
- // nonce contains the fixed part of the nonce in the first four bytes.
- nonce [aeadNonceLength]byte
- aead cipher.AEAD
-}
-
-func (f *prefixNonceAEAD) NonceSize() int { return aeadNonceLength - noncePrefixLength }
-func (f *prefixNonceAEAD) Overhead() int { return f.aead.Overhead() }
-func (f *prefixNonceAEAD) explicitNonceLen() int { return f.NonceSize() }
-
-func (f *prefixNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
- copy(f.nonce[4:], nonce)
- return f.aead.Seal(out, f.nonce[:], plaintext, additionalData)
-}
-
-func (f *prefixNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {
- copy(f.nonce[4:], nonce)
- return f.aead.Open(out, f.nonce[:], ciphertext, additionalData)
-}
-
-// xorNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce
-// before each call.
-type xorNonceAEAD struct {
- nonceMask [aeadNonceLength]byte
- aead cipher.AEAD
-}
-
-func (f *xorNonceAEAD) NonceSize() int { return 8 } // 64-bit sequence number
-func (f *xorNonceAEAD) Overhead() int { return f.aead.Overhead() }
-func (f *xorNonceAEAD) explicitNonceLen() int { return 0 }
-
-func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
- for i, b := range nonce {
- f.nonceMask[4+i] ^= b
- }
- result := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData)
- for i, b := range nonce {
- f.nonceMask[4+i] ^= b
- }
-
- return result
-}
-
-func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {
- for i, b := range nonce {
- f.nonceMask[4+i] ^= b
- }
- result, err := f.aead.Open(out, f.nonceMask[:], ciphertext, additionalData)
- for i, b := range nonce {
- f.nonceMask[4+i] ^= b
- }
-
- return result, err
-}
-
-func aeadAESGCM(key, noncePrefix []byte) aead {
- if len(noncePrefix) != noncePrefixLength {
- panic("tls: internal error: wrong nonce length")
- }
- aes, err := aes.NewCipher(key)
- if err != nil {
- panic(err)
- }
- var aead cipher.AEAD
- if boring.Enabled {
- aead, err = boring.NewGCMTLS(aes)
- } else {
- boring.Unreachable()
- aead, err = cipher.NewGCM(aes)
- }
- if err != nil {
- panic(err)
- }
-
- ret := &prefixNonceAEAD{aead: aead}
- copy(ret.nonce[:], noncePrefix)
- return ret
-}
-
-func aeadAESGCMTLS13(key, nonceMask []byte) aead {
- if len(nonceMask) != aeadNonceLength {
- panic("tls: internal error: wrong nonce length")
- }
- aes, err := aes.NewCipher(key)
- if err != nil {
- panic(err)
- }
- aead, err := cipher.NewGCM(aes)
- if err != nil {
- panic(err)
- }
-
- ret := &xorNonceAEAD{aead: aead}
- copy(ret.nonceMask[:], nonceMask)
- return ret
-}
-
-func aeadChaCha20Poly1305(key, nonceMask []byte) aead {
- if len(nonceMask) != aeadNonceLength {
- panic("tls: internal error: wrong nonce length")
- }
- aead, err := chacha20poly1305.New(key)
- if err != nil {
- panic(err)
- }
-
- ret := &xorNonceAEAD{aead: aead}
- copy(ret.nonceMask[:], nonceMask)
- return ret
-}
-
-type constantTimeHash interface {
- hash.Hash
- ConstantTimeSum(b []byte) []byte
-}
-
-// cthWrapper wraps any hash.Hash that implements ConstantTimeSum, and replaces
-// with that all calls to Sum. It's used to obtain a ConstantTimeSum-based HMAC.
-type cthWrapper struct {
- h constantTimeHash
-}
-
-func (c *cthWrapper) Size() int { return c.h.Size() }
-func (c *cthWrapper) BlockSize() int { return c.h.BlockSize() }
-func (c *cthWrapper) Reset() { c.h.Reset() }
-func (c *cthWrapper) Write(p []byte) (int, error) { return c.h.Write(p) }
-func (c *cthWrapper) Sum(b []byte) []byte { return c.h.ConstantTimeSum(b) }
-
-func newConstantTimeHash(h func() hash.Hash) func() hash.Hash {
- boring.Unreachable()
- return func() hash.Hash {
- return &cthWrapper{h().(constantTimeHash)}
- }
-}
-
-// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3.
-func tls10MAC(h hash.Hash, out, seq, header, data, extra []byte) []byte {
- h.Reset()
- h.Write(seq)
- h.Write(header)
- h.Write(data)
- res := h.Sum(out)
- if extra != nil {
- h.Write(extra)
- }
- return res
-}
-
-func rsaKA(version uint16) keyAgreement {
- return rsaKeyAgreement{}
-}
-
-func ecdheECDSAKA(version uint16) keyAgreement {
- return &ecdheKeyAgreement{
- isRSA: false,
- version: version,
- }
-}
-
-func ecdheRSAKA(version uint16) keyAgreement {
- return &ecdheKeyAgreement{
- isRSA: true,
- version: version,
- }
-}
-
-// mutualCipherSuite returns a cipherSuite given a list of supported
-// ciphersuites and the id requested by the peer.
-func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
- for _, id := range have {
- if id == want {
- return cipherSuiteByID(id)
- }
- }
- return nil
-}
-
-func cipherSuiteByID(id uint16) *cipherSuite {
- for _, cipherSuite := range cipherSuites {
- if cipherSuite.id == id {
- return cipherSuite
- }
- }
- return nil
-}
-
-func mutualCipherSuiteTLS13(have []uint16, want uint16) *cipherSuiteTLS13 {
- for _, id := range have {
- if id == want {
- return cipherSuiteTLS13ByID(id)
- }
- }
- return nil
-}
-
-func cipherSuiteTLS13ByID(id uint16) *cipherSuiteTLS13 {
- for _, cipherSuite := range cipherSuitesTLS13 {
- if cipherSuite.id == id {
- return cipherSuite
- }
- }
- return nil
-}
-
-// A list of cipher suite IDs that are, or have been, implemented by this
-// package.
-//
-// See https://www.iana.org/assignments/tls-parameters/tls-parameters.xml
-const (
- // TLS 1.0 - 1.2 cipher suites.
- TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
- TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
- TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
- TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
- TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c
- TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c
- TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d
- TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
- TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca8
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9
-
- // TLS 1.3 cipher suites.
- TLS_AES_128_GCM_SHA256 uint16 = 0x1301
- TLS_AES_256_GCM_SHA384 uint16 = 0x1302
- TLS_CHACHA20_POLY1305_SHA256 uint16 = 0x1303
-
- // TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator
- // that the client is doing version fallback. See RFC 7507.
- TLS_FALLBACK_SCSV uint16 = 0x5600
-
- // Legacy names for the corresponding cipher suites with the correct _SHA256
- // suffix, retained for backward compatibility.
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
-)
diff --git a/contrib/go/_std_1.20/src/crypto/tls/common.go b/contrib/go/_std_1.20/src/crypto/tls/common.go
deleted file mode 100644
index 5394d64ac6..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/common.go
+++ /dev/null
@@ -1,1510 +0,0 @@
-// Copyright 2009 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 tls
-
-import (
- "bytes"
- "container/list"
- "context"
- "crypto"
- "crypto/ecdsa"
- "crypto/ed25519"
- "crypto/elliptic"
- "crypto/rand"
- "crypto/rsa"
- "crypto/sha512"
- "crypto/x509"
- "errors"
- "fmt"
- "io"
- "net"
- "strings"
- "sync"
- "time"
-)
-
-const (
- VersionTLS10 = 0x0301
- VersionTLS11 = 0x0302
- VersionTLS12 = 0x0303
- VersionTLS13 = 0x0304
-
- // Deprecated: SSLv3 is cryptographically broken, and is no longer
- // supported by this package. See golang.org/issue/32716.
- VersionSSL30 = 0x0300
-)
-
-const (
- maxPlaintext = 16384 // maximum plaintext payload length
- maxCiphertext = 16384 + 2048 // maximum ciphertext payload length
- maxCiphertextTLS13 = 16384 + 256 // maximum ciphertext length in TLS 1.3
- recordHeaderLen = 5 // record header length
- maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB)
- maxUselessRecords = 16 // maximum number of consecutive non-advancing records
-)
-
-// TLS record types.
-type recordType uint8
-
-const (
- recordTypeChangeCipherSpec recordType = 20
- recordTypeAlert recordType = 21
- recordTypeHandshake recordType = 22
- recordTypeApplicationData recordType = 23
-)
-
-// TLS handshake message types.
-const (
- typeHelloRequest uint8 = 0
- typeClientHello uint8 = 1
- typeServerHello uint8 = 2
- typeNewSessionTicket uint8 = 4
- typeEndOfEarlyData uint8 = 5
- typeEncryptedExtensions uint8 = 8
- typeCertificate uint8 = 11
- typeServerKeyExchange uint8 = 12
- typeCertificateRequest uint8 = 13
- typeServerHelloDone uint8 = 14
- typeCertificateVerify uint8 = 15
- typeClientKeyExchange uint8 = 16
- typeFinished uint8 = 20
- typeCertificateStatus uint8 = 22
- typeKeyUpdate uint8 = 24
- typeNextProtocol uint8 = 67 // Not IANA assigned
- typeMessageHash uint8 = 254 // synthetic message
-)
-
-// TLS compression types.
-const (
- compressionNone uint8 = 0
-)
-
-// TLS extension numbers
-const (
- extensionServerName uint16 = 0
- extensionStatusRequest uint16 = 5
- extensionSupportedCurves uint16 = 10 // supported_groups in TLS 1.3, see RFC 8446, Section 4.2.7
- extensionSupportedPoints uint16 = 11
- extensionSignatureAlgorithms uint16 = 13
- extensionALPN uint16 = 16
- extensionSCT uint16 = 18
- extensionSessionTicket uint16 = 35
- extensionPreSharedKey uint16 = 41
- extensionEarlyData uint16 = 42
- extensionSupportedVersions uint16 = 43
- extensionCookie uint16 = 44
- extensionPSKModes uint16 = 45
- extensionCertificateAuthorities uint16 = 47
- extensionSignatureAlgorithmsCert uint16 = 50
- extensionKeyShare uint16 = 51
- extensionRenegotiationInfo uint16 = 0xff01
-)
-
-// TLS signaling cipher suite values
-const (
- scsvRenegotiation uint16 = 0x00ff
-)
-
-// CurveID is the type of a TLS identifier for an elliptic curve. See
-// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8.
-//
-// In TLS 1.3, this type is called NamedGroup, but at this time this library
-// only supports Elliptic Curve based groups. See RFC 8446, Section 4.2.7.
-type CurveID uint16
-
-const (
- CurveP256 CurveID = 23
- CurveP384 CurveID = 24
- CurveP521 CurveID = 25
- X25519 CurveID = 29
-)
-
-// TLS 1.3 Key Share. See RFC 8446, Section 4.2.8.
-type keyShare struct {
- group CurveID
- data []byte
-}
-
-// TLS 1.3 PSK Key Exchange Modes. See RFC 8446, Section 4.2.9.
-const (
- pskModePlain uint8 = 0
- pskModeDHE uint8 = 1
-)
-
-// TLS 1.3 PSK Identity. Can be a Session Ticket, or a reference to a saved
-// session. See RFC 8446, Section 4.2.11.
-type pskIdentity struct {
- label []byte
- obfuscatedTicketAge uint32
-}
-
-// TLS Elliptic Curve Point Formats
-// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
-const (
- pointFormatUncompressed uint8 = 0
-)
-
-// TLS CertificateStatusType (RFC 3546)
-const (
- statusTypeOCSP uint8 = 1
-)
-
-// Certificate types (for certificateRequestMsg)
-const (
- certTypeRSASign = 1
- certTypeECDSASign = 64 // ECDSA or EdDSA keys, see RFC 8422, Section 3.
-)
-
-// Signature algorithms (for internal signaling use). Starting at 225 to avoid overlap with
-// TLS 1.2 codepoints (RFC 5246, Appendix A.4.1), with which these have nothing to do.
-const (
- signaturePKCS1v15 uint8 = iota + 225
- signatureRSAPSS
- signatureECDSA
- signatureEd25519
-)
-
-// directSigning is a standard Hash value that signals that no pre-hashing
-// should be performed, and that the input should be signed directly. It is the
-// hash function associated with the Ed25519 signature scheme.
-var directSigning crypto.Hash = 0
-
-// defaultSupportedSignatureAlgorithms contains the signature and hash algorithms that
-// the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+
-// CertificateRequest. The two fields are merged to match with TLS 1.3.
-// Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc.
-var defaultSupportedSignatureAlgorithms = []SignatureScheme{
- PSSWithSHA256,
- ECDSAWithP256AndSHA256,
- Ed25519,
- PSSWithSHA384,
- PSSWithSHA512,
- PKCS1WithSHA256,
- PKCS1WithSHA384,
- PKCS1WithSHA512,
- ECDSAWithP384AndSHA384,
- ECDSAWithP521AndSHA512,
- PKCS1WithSHA1,
- ECDSAWithSHA1,
-}
-
-// helloRetryRequestRandom is set as the Random value of a ServerHello
-// to signal that the message is actually a HelloRetryRequest.
-var helloRetryRequestRandom = []byte{ // See RFC 8446, Section 4.1.3.
- 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
- 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
- 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
- 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C,
-}
-
-const (
- // downgradeCanaryTLS12 or downgradeCanaryTLS11 is embedded in the server
- // random as a downgrade protection if the server would be capable of
- // negotiating a higher version. See RFC 8446, Section 4.1.3.
- downgradeCanaryTLS12 = "DOWNGRD\x01"
- downgradeCanaryTLS11 = "DOWNGRD\x00"
-)
-
-// testingOnlyForceDowngradeCanary is set in tests to force the server side to
-// include downgrade canaries even if it's using its highers supported version.
-var testingOnlyForceDowngradeCanary bool
-
-// ConnectionState records basic TLS details about the connection.
-type ConnectionState struct {
- // Version is the TLS version used by the connection (e.g. VersionTLS12).
- Version uint16
-
- // HandshakeComplete is true if the handshake has concluded.
- HandshakeComplete bool
-
- // DidResume is true if this connection was successfully resumed from a
- // previous session with a session ticket or similar mechanism.
- DidResume bool
-
- // CipherSuite is the cipher suite negotiated for the connection (e.g.
- // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_AES_128_GCM_SHA256).
- CipherSuite uint16
-
- // NegotiatedProtocol is the application protocol negotiated with ALPN.
- NegotiatedProtocol string
-
- // NegotiatedProtocolIsMutual used to indicate a mutual NPN negotiation.
- //
- // Deprecated: this value is always true.
- NegotiatedProtocolIsMutual bool
-
- // ServerName is the value of the Server Name Indication extension sent by
- // the client. It's available both on the server and on the client side.
- ServerName string
-
- // PeerCertificates are the parsed certificates sent by the peer, in the
- // order in which they were sent. The first element is the leaf certificate
- // that the connection is verified against.
- //
- // On the client side, it can't be empty. On the server side, it can be
- // empty if Config.ClientAuth is not RequireAnyClientCert or
- // RequireAndVerifyClientCert.
- //
- // PeerCertificates and its contents should not be modified.
- PeerCertificates []*x509.Certificate
-
- // VerifiedChains is a list of one or more chains where the first element is
- // PeerCertificates[0] and the last element is from Config.RootCAs (on the
- // client side) or Config.ClientCAs (on the server side).
- //
- // On the client side, it's set if Config.InsecureSkipVerify is false. On
- // the server side, it's set if Config.ClientAuth is VerifyClientCertIfGiven
- // (and the peer provided a certificate) or RequireAndVerifyClientCert.
- //
- // VerifiedChains and its contents should not be modified.
- VerifiedChains [][]*x509.Certificate
-
- // SignedCertificateTimestamps is a list of SCTs provided by the peer
- // through the TLS handshake for the leaf certificate, if any.
- SignedCertificateTimestamps [][]byte
-
- // OCSPResponse is a stapled Online Certificate Status Protocol (OCSP)
- // response provided by the peer for the leaf certificate, if any.
- OCSPResponse []byte
-
- // TLSUnique contains the "tls-unique" channel binding value (see RFC 5929,
- // Section 3). This value will be nil for TLS 1.3 connections and for all
- // resumed connections.
- //
- // Deprecated: there are conditions in which this value might not be unique
- // to a connection. See the Security Considerations sections of RFC 5705 and
- // RFC 7627, and https://mitls.org/pages/attacks/3SHAKE#channelbindings.
- TLSUnique []byte
-
- // ekm is a closure exposed via ExportKeyingMaterial.
- ekm func(label string, context []byte, length int) ([]byte, error)
-}
-
-// ExportKeyingMaterial returns length bytes of exported key material in a new
-// slice as defined in RFC 5705. If context is nil, it is not used as part of
-// the seed. If the connection was set to allow renegotiation via
-// Config.Renegotiation, this function will return an error.
-func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
- return cs.ekm(label, context, length)
-}
-
-// ClientAuthType declares the policy the server will follow for
-// TLS Client Authentication.
-type ClientAuthType int
-
-const (
- // NoClientCert indicates that no client certificate should be requested
- // during the handshake, and if any certificates are sent they will not
- // be verified.
- NoClientCert ClientAuthType = iota
- // RequestClientCert indicates that a client certificate should be requested
- // during the handshake, but does not require that the client send any
- // certificates.
- RequestClientCert
- // RequireAnyClientCert indicates that a client certificate should be requested
- // during the handshake, and that at least one certificate is required to be
- // sent by the client, but that certificate is not required to be valid.
- RequireAnyClientCert
- // VerifyClientCertIfGiven indicates that a client certificate should be requested
- // during the handshake, but does not require that the client sends a
- // certificate. If the client does send a certificate it is required to be
- // valid.
- VerifyClientCertIfGiven
- // RequireAndVerifyClientCert indicates that a client certificate should be requested
- // during the handshake, and that at least one valid certificate is required
- // to be sent by the client.
- RequireAndVerifyClientCert
-)
-
-// requiresClientCert reports whether the ClientAuthType requires a client
-// certificate to be provided.
-func requiresClientCert(c ClientAuthType) bool {
- switch c {
- case RequireAnyClientCert, RequireAndVerifyClientCert:
- return true
- default:
- return false
- }
-}
-
-// ClientSessionState contains the state needed by clients to resume TLS
-// sessions.
-type ClientSessionState struct {
- sessionTicket []uint8 // Encrypted ticket used for session resumption with server
- vers uint16 // TLS version negotiated for the session
- cipherSuite uint16 // Ciphersuite negotiated for the session
- masterSecret []byte // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret
- serverCertificates []*x509.Certificate // Certificate chain presented by the server
- verifiedChains [][]*x509.Certificate // Certificate chains we built for verification
- receivedAt time.Time // When the session ticket was received from the server
- ocspResponse []byte // Stapled OCSP response presented by the server
- scts [][]byte // SCTs presented by the server
-
- // TLS 1.3 fields.
- nonce []byte // Ticket nonce sent by the server, to derive PSK
- useBy time.Time // Expiration of the ticket lifetime as set by the server
- ageAdd uint32 // Random obfuscation factor for sending the ticket age
-}
-
-// ClientSessionCache is a cache of ClientSessionState objects that can be used
-// by a client to resume a TLS session with a given server. ClientSessionCache
-// implementations should expect to be called concurrently from different
-// goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not
-// SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which
-// are supported via this interface.
-type ClientSessionCache interface {
- // Get searches for a ClientSessionState associated with the given key.
- // On return, ok is true if one was found.
- Get(sessionKey string) (session *ClientSessionState, ok bool)
-
- // Put adds the ClientSessionState to the cache with the given key. It might
- // get called multiple times in a connection if a TLS 1.3 server provides
- // more than one session ticket. If called with a nil *ClientSessionState,
- // it should remove the cache entry.
- Put(sessionKey string, cs *ClientSessionState)
-}
-
-//go:generate stringer -type=SignatureScheme,CurveID,ClientAuthType -output=common_string.go
-
-// SignatureScheme identifies a signature algorithm supported by TLS. See
-// RFC 8446, Section 4.2.3.
-type SignatureScheme uint16
-
-const (
- // RSASSA-PKCS1-v1_5 algorithms.
- PKCS1WithSHA256 SignatureScheme = 0x0401
- PKCS1WithSHA384 SignatureScheme = 0x0501
- PKCS1WithSHA512 SignatureScheme = 0x0601
-
- // RSASSA-PSS algorithms with public key OID rsaEncryption.
- PSSWithSHA256 SignatureScheme = 0x0804
- PSSWithSHA384 SignatureScheme = 0x0805
- PSSWithSHA512 SignatureScheme = 0x0806
-
- // ECDSA algorithms. Only constrained to a specific curve in TLS 1.3.
- ECDSAWithP256AndSHA256 SignatureScheme = 0x0403
- ECDSAWithP384AndSHA384 SignatureScheme = 0x0503
- ECDSAWithP521AndSHA512 SignatureScheme = 0x0603
-
- // EdDSA algorithms.
- Ed25519 SignatureScheme = 0x0807
-
- // Legacy signature and hash algorithms for TLS 1.2.
- PKCS1WithSHA1 SignatureScheme = 0x0201
- ECDSAWithSHA1 SignatureScheme = 0x0203
-)
-
-// ClientHelloInfo contains information from a ClientHello message in order to
-// guide application logic in the GetCertificate and GetConfigForClient callbacks.
-type ClientHelloInfo struct {
- // CipherSuites lists the CipherSuites supported by the client (e.g.
- // TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).
- CipherSuites []uint16
-
- // ServerName indicates the name of the server requested by the client
- // in order to support virtual hosting. ServerName is only set if the
- // client is using SNI (see RFC 4366, Section 3.1).
- ServerName string
-
- // SupportedCurves lists the elliptic curves supported by the client.
- // SupportedCurves is set only if the Supported Elliptic Curves
- // Extension is being used (see RFC 4492, Section 5.1.1).
- SupportedCurves []CurveID
-
- // SupportedPoints lists the point formats supported by the client.
- // SupportedPoints is set only if the Supported Point Formats Extension
- // is being used (see RFC 4492, Section 5.1.2).
- SupportedPoints []uint8
-
- // SignatureSchemes lists the signature and hash schemes that the client
- // is willing to verify. SignatureSchemes is set only if the Signature
- // Algorithms Extension is being used (see RFC 5246, Section 7.4.1.4.1).
- SignatureSchemes []SignatureScheme
-
- // SupportedProtos lists the application protocols supported by the client.
- // SupportedProtos is set only if the Application-Layer Protocol
- // Negotiation Extension is being used (see RFC 7301, Section 3.1).
- //
- // Servers can select a protocol by setting Config.NextProtos in a
- // GetConfigForClient return value.
- SupportedProtos []string
-
- // SupportedVersions lists the TLS versions supported by the client.
- // For TLS versions less than 1.3, this is extrapolated from the max
- // version advertised by the client, so values other than the greatest
- // might be rejected if used.
- SupportedVersions []uint16
-
- // Conn is the underlying net.Conn for the connection. Do not read
- // from, or write to, this connection; that will cause the TLS
- // connection to fail.
- Conn net.Conn
-
- // config is embedded by the GetCertificate or GetConfigForClient caller,
- // for use with SupportsCertificate.
- config *Config
-
- // ctx is the context of the handshake that is in progress.
- ctx context.Context
-}
-
-// Context returns the context of the handshake that is in progress.
-// This context is a child of the context passed to HandshakeContext,
-// if any, and is canceled when the handshake concludes.
-func (c *ClientHelloInfo) Context() context.Context {
- return c.ctx
-}
-
-// CertificateRequestInfo contains information from a server's
-// CertificateRequest message, which is used to demand a certificate and proof
-// of control from a client.
-type CertificateRequestInfo struct {
- // AcceptableCAs contains zero or more, DER-encoded, X.501
- // Distinguished Names. These are the names of root or intermediate CAs
- // that the server wishes the returned certificate to be signed by. An
- // empty slice indicates that the server has no preference.
- AcceptableCAs [][]byte
-
- // SignatureSchemes lists the signature schemes that the server is
- // willing to verify.
- SignatureSchemes []SignatureScheme
-
- // Version is the TLS version that was negotiated for this connection.
- Version uint16
-
- // ctx is the context of the handshake that is in progress.
- ctx context.Context
-}
-
-// Context returns the context of the handshake that is in progress.
-// This context is a child of the context passed to HandshakeContext,
-// if any, and is canceled when the handshake concludes.
-func (c *CertificateRequestInfo) Context() context.Context {
- return c.ctx
-}
-
-// RenegotiationSupport enumerates the different levels of support for TLS
-// renegotiation. TLS renegotiation is the act of performing subsequent
-// handshakes on a connection after the first. This significantly complicates
-// the state machine and has been the source of numerous, subtle security
-// issues. Initiating a renegotiation is not supported, but support for
-// accepting renegotiation requests may be enabled.
-//
-// Even when enabled, the server may not change its identity between handshakes
-// (i.e. the leaf certificate must be the same). Additionally, concurrent
-// handshake and application data flow is not permitted so renegotiation can
-// only be used with protocols that synchronise with the renegotiation, such as
-// HTTPS.
-//
-// Renegotiation is not defined in TLS 1.3.
-type RenegotiationSupport int
-
-const (
- // RenegotiateNever disables renegotiation.
- RenegotiateNever RenegotiationSupport = iota
-
- // RenegotiateOnceAsClient allows a remote server to request
- // renegotiation once per connection.
- RenegotiateOnceAsClient
-
- // RenegotiateFreelyAsClient allows a remote server to repeatedly
- // request renegotiation.
- RenegotiateFreelyAsClient
-)
-
-// A Config structure is used to configure a TLS client or server.
-// After one has been passed to a TLS function it must not be
-// modified. A Config may be reused; the tls package will also not
-// modify it.
-type Config struct {
- // Rand provides the source of entropy for nonces and RSA blinding.
- // If Rand is nil, TLS uses the cryptographic random reader in package
- // crypto/rand.
- // The Reader must be safe for use by multiple goroutines.
- Rand io.Reader
-
- // Time returns the current time as the number of seconds since the epoch.
- // If Time is nil, TLS uses time.Now.
- Time func() time.Time
-
- // Certificates contains one or more certificate chains to present to the
- // other side of the connection. The first certificate compatible with the
- // peer's requirements is selected automatically.
- //
- // Server configurations must set one of Certificates, GetCertificate or
- // GetConfigForClient. Clients doing client-authentication may set either
- // Certificates or GetClientCertificate.
- //
- // Note: if there are multiple Certificates, and they don't have the
- // optional field Leaf set, certificate selection will incur a significant
- // per-handshake performance cost.
- Certificates []Certificate
-
- // NameToCertificate maps from a certificate name to an element of
- // Certificates. Note that a certificate name can be of the form
- // '*.example.com' and so doesn't have to be a domain name as such.
- //
- // Deprecated: NameToCertificate only allows associating a single
- // certificate with a given name. Leave this field nil to let the library
- // select the first compatible chain from Certificates.
- NameToCertificate map[string]*Certificate
-
- // GetCertificate returns a Certificate based on the given
- // ClientHelloInfo. It will only be called if the client supplies SNI
- // information or if Certificates is empty.
- //
- // If GetCertificate is nil or returns nil, then the certificate is
- // retrieved from NameToCertificate. If NameToCertificate is nil, the
- // best element of Certificates will be used.
- //
- // Once a Certificate is returned it should not be modified.
- GetCertificate func(*ClientHelloInfo) (*Certificate, error)
-
- // GetClientCertificate, if not nil, is called when a server requests a
- // certificate from a client. If set, the contents of Certificates will
- // be ignored.
- //
- // If GetClientCertificate returns an error, the handshake will be
- // aborted and that error will be returned. Otherwise
- // GetClientCertificate must return a non-nil Certificate. If
- // Certificate.Certificate is empty then no certificate will be sent to
- // the server. If this is unacceptable to the server then it may abort
- // the handshake.
- //
- // GetClientCertificate may be called multiple times for the same
- // connection if renegotiation occurs or if TLS 1.3 is in use.
- //
- // Once a Certificate is returned it should not be modified.
- GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error)
-
- // GetConfigForClient, if not nil, is called after a ClientHello is
- // received from a client. It may return a non-nil Config in order to
- // change the Config that will be used to handle this connection. If
- // the returned Config is nil, the original Config will be used. The
- // Config returned by this callback may not be subsequently modified.
- //
- // If GetConfigForClient is nil, the Config passed to Server() will be
- // used for all connections.
- //
- // If SessionTicketKey was explicitly set on the returned Config, or if
- // SetSessionTicketKeys was called on the returned Config, those keys will
- // be used. Otherwise, the original Config keys will be used (and possibly
- // rotated if they are automatically managed).
- GetConfigForClient func(*ClientHelloInfo) (*Config, error)
-
- // VerifyPeerCertificate, if not nil, is called after normal
- // certificate verification by either a TLS client or server. It
- // receives the raw ASN.1 certificates provided by the peer and also
- // any verified chains that normal processing found. If it returns a
- // non-nil error, the handshake is aborted and that error results.
- //
- // If normal verification fails then the handshake will abort before
- // considering this callback. If normal verification is disabled by
- // setting InsecureSkipVerify, or (for a server) when ClientAuth is
- // RequestClientCert or RequireAnyClientCert, then this callback will
- // be considered but the verifiedChains argument will always be nil.
- //
- // verifiedChains and its contents should not be modified.
- VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
-
- // VerifyConnection, if not nil, is called after normal certificate
- // verification and after VerifyPeerCertificate by either a TLS client
- // or server. If it returns a non-nil error, the handshake is aborted
- // and that error results.
- //
- // If normal verification fails then the handshake will abort before
- // considering this callback. This callback will run for all connections
- // regardless of InsecureSkipVerify or ClientAuth settings.
- VerifyConnection func(ConnectionState) error
-
- // RootCAs defines the set of root certificate authorities
- // that clients use when verifying server certificates.
- // If RootCAs is nil, TLS uses the host's root CA set.
- RootCAs *x509.CertPool
-
- // NextProtos is a list of supported application level protocols, in
- // order of preference. If both peers support ALPN, the selected
- // protocol will be one from this list, and the connection will fail
- // if there is no mutually supported protocol. If NextProtos is empty
- // or the peer doesn't support ALPN, the connection will succeed and
- // ConnectionState.NegotiatedProtocol will be empty.
- NextProtos []string
-
- // ServerName is used to verify the hostname on the returned
- // certificates unless InsecureSkipVerify is given. It is also included
- // in the client's handshake to support virtual hosting unless it is
- // an IP address.
- ServerName string
-
- // ClientAuth determines the server's policy for
- // TLS Client Authentication. The default is NoClientCert.
- ClientAuth ClientAuthType
-
- // ClientCAs defines the set of root certificate authorities
- // that servers use if required to verify a client certificate
- // by the policy in ClientAuth.
- ClientCAs *x509.CertPool
-
- // InsecureSkipVerify controls whether a client verifies the server's
- // certificate chain and host name. If InsecureSkipVerify is true, crypto/tls
- // accepts any certificate presented by the server and any host name in that
- // certificate. In this mode, TLS is susceptible to machine-in-the-middle
- // attacks unless custom verification is used. This should be used only for
- // testing or in combination with VerifyConnection or VerifyPeerCertificate.
- InsecureSkipVerify bool
-
- // CipherSuites is a list of enabled TLS 1.0–1.2 cipher suites. The order of
- // the list is ignored. Note that TLS 1.3 ciphersuites are not configurable.
- //
- // If CipherSuites is nil, a safe default list is used. The default cipher
- // suites might change over time.
- CipherSuites []uint16
-
- // PreferServerCipherSuites is a legacy field and has no effect.
- //
- // It used to control whether the server would follow the client's or the
- // server's preference. Servers now select the best mutually supported
- // cipher suite based on logic that takes into account inferred client
- // hardware, server hardware, and security.
- //
- // Deprecated: PreferServerCipherSuites is ignored.
- PreferServerCipherSuites bool
-
- // SessionTicketsDisabled may be set to true to disable session ticket and
- // PSK (resumption) support. Note that on clients, session ticket support is
- // also disabled if ClientSessionCache is nil.
- SessionTicketsDisabled bool
-
- // SessionTicketKey is used by TLS servers to provide session resumption.
- // See RFC 5077 and the PSK mode of RFC 8446. If zero, it will be filled
- // with random data before the first server handshake.
- //
- // Deprecated: if this field is left at zero, session ticket keys will be
- // automatically rotated every day and dropped after seven days. For
- // customizing the rotation schedule or synchronizing servers that are
- // terminating connections for the same host, use SetSessionTicketKeys.
- SessionTicketKey [32]byte
-
- // ClientSessionCache is a cache of ClientSessionState entries for TLS
- // session resumption. It is only used by clients.
- ClientSessionCache ClientSessionCache
-
- // MinVersion contains the minimum TLS version that is acceptable.
- //
- // By default, TLS 1.2 is currently used as the minimum when acting as a
- // client, and TLS 1.0 when acting as a server. TLS 1.0 is the minimum
- // supported by this package, both as a client and as a server.
- //
- // The client-side default can temporarily be reverted to TLS 1.0 by
- // including the value "x509sha1=1" in the GODEBUG environment variable.
- // Note that this option will be removed in Go 1.19 (but it will still be
- // possible to set this field to VersionTLS10 explicitly).
- MinVersion uint16
-
- // MaxVersion contains the maximum TLS version that is acceptable.
- //
- // By default, the maximum version supported by this package is used,
- // which is currently TLS 1.3.
- MaxVersion uint16
-
- // CurvePreferences contains the elliptic curves that will be used in
- // an ECDHE handshake, in preference order. If empty, the default will
- // be used. The client will use the first preference as the type for
- // its key share in TLS 1.3. This may change in the future.
- CurvePreferences []CurveID
-
- // DynamicRecordSizingDisabled disables adaptive sizing of TLS records.
- // When true, the largest possible TLS record size is always used. When
- // false, the size of TLS records may be adjusted in an attempt to
- // improve latency.
- DynamicRecordSizingDisabled bool
-
- // Renegotiation controls what types of renegotiation are supported.
- // The default, none, is correct for the vast majority of applications.
- Renegotiation RenegotiationSupport
-
- // KeyLogWriter optionally specifies a destination for TLS master secrets
- // in NSS key log format that can be used to allow external programs
- // such as Wireshark to decrypt TLS connections.
- // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.
- // Use of KeyLogWriter compromises security and should only be
- // used for debugging.
- KeyLogWriter io.Writer
-
- // mutex protects sessionTicketKeys and autoSessionTicketKeys.
- mutex sync.RWMutex
- // sessionTicketKeys contains zero or more ticket keys. If set, it means
- // the keys were set with SessionTicketKey or SetSessionTicketKeys. The
- // first key is used for new tickets and any subsequent keys can be used to
- // decrypt old tickets. The slice contents are not protected by the mutex
- // and are immutable.
- sessionTicketKeys []ticketKey
- // autoSessionTicketKeys is like sessionTicketKeys but is owned by the
- // auto-rotation logic. See Config.ticketKeys.
- autoSessionTicketKeys []ticketKey
-}
-
-const (
- // ticketKeyNameLen is the number of bytes of identifier that is prepended to
- // an encrypted session ticket in order to identify the key used to encrypt it.
- ticketKeyNameLen = 16
-
- // ticketKeyLifetime is how long a ticket key remains valid and can be used to
- // resume a client connection.
- ticketKeyLifetime = 7 * 24 * time.Hour // 7 days
-
- // ticketKeyRotation is how often the server should rotate the session ticket key
- // that is used for new tickets.
- ticketKeyRotation = 24 * time.Hour
-)
-
-// ticketKey is the internal representation of a session ticket key.
-type ticketKey struct {
- // keyName is an opaque byte string that serves to identify the session
- // ticket key. It's exposed as plaintext in every session ticket.
- keyName [ticketKeyNameLen]byte
- aesKey [16]byte
- hmacKey [16]byte
- // created is the time at which this ticket key was created. See Config.ticketKeys.
- created time.Time
-}
-
-// ticketKeyFromBytes converts from the external representation of a session
-// ticket key to a ticketKey. Externally, session ticket keys are 32 random
-// bytes and this function expands that into sufficient name and key material.
-func (c *Config) ticketKeyFromBytes(b [32]byte) (key ticketKey) {
- hashed := sha512.Sum512(b[:])
- copy(key.keyName[:], hashed[:ticketKeyNameLen])
- copy(key.aesKey[:], hashed[ticketKeyNameLen:ticketKeyNameLen+16])
- copy(key.hmacKey[:], hashed[ticketKeyNameLen+16:ticketKeyNameLen+32])
- key.created = c.time()
- return key
-}
-
-// maxSessionTicketLifetime is the maximum allowed lifetime of a TLS 1.3 session
-// ticket, and the lifetime we set for tickets we send.
-const maxSessionTicketLifetime = 7 * 24 * time.Hour
-
-// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a Config that is
-// being used concurrently by a TLS client or server.
-func (c *Config) Clone() *Config {
- if c == nil {
- return nil
- }
- c.mutex.RLock()
- defer c.mutex.RUnlock()
- return &Config{
- Rand: c.Rand,
- Time: c.Time,
- Certificates: c.Certificates,
- NameToCertificate: c.NameToCertificate,
- GetCertificate: c.GetCertificate,
- GetClientCertificate: c.GetClientCertificate,
- GetConfigForClient: c.GetConfigForClient,
- VerifyPeerCertificate: c.VerifyPeerCertificate,
- VerifyConnection: c.VerifyConnection,
- RootCAs: c.RootCAs,
- NextProtos: c.NextProtos,
- ServerName: c.ServerName,
- ClientAuth: c.ClientAuth,
- ClientCAs: c.ClientCAs,
- InsecureSkipVerify: c.InsecureSkipVerify,
- CipherSuites: c.CipherSuites,
- PreferServerCipherSuites: c.PreferServerCipherSuites,
- SessionTicketsDisabled: c.SessionTicketsDisabled,
- SessionTicketKey: c.SessionTicketKey,
- ClientSessionCache: c.ClientSessionCache,
- MinVersion: c.MinVersion,
- MaxVersion: c.MaxVersion,
- CurvePreferences: c.CurvePreferences,
- DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
- Renegotiation: c.Renegotiation,
- KeyLogWriter: c.KeyLogWriter,
- sessionTicketKeys: c.sessionTicketKeys,
- autoSessionTicketKeys: c.autoSessionTicketKeys,
- }
-}
-
-// deprecatedSessionTicketKey is set as the prefix of SessionTicketKey if it was
-// randomized for backwards compatibility but is not in use.
-var deprecatedSessionTicketKey = []byte("DEPRECATED")
-
-// initLegacySessionTicketKeyRLocked ensures the legacy SessionTicketKey field is
-// randomized if empty, and that sessionTicketKeys is populated from it otherwise.
-func (c *Config) initLegacySessionTicketKeyRLocked() {
- // Don't write if SessionTicketKey is already defined as our deprecated string,
- // or if it is defined by the user but sessionTicketKeys is already set.
- if c.SessionTicketKey != [32]byte{} &&
- (bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) || len(c.sessionTicketKeys) > 0) {
- return
- }
-
- // We need to write some data, so get an exclusive lock and re-check any conditions.
- c.mutex.RUnlock()
- defer c.mutex.RLock()
- c.mutex.Lock()
- defer c.mutex.Unlock()
- if c.SessionTicketKey == [32]byte{} {
- if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {
- panic(fmt.Sprintf("tls: unable to generate random session ticket key: %v", err))
- }
- // Write the deprecated prefix at the beginning so we know we created
- // it. This key with the DEPRECATED prefix isn't used as an actual
- // session ticket key, and is only randomized in case the application
- // reuses it for some reason.
- copy(c.SessionTicketKey[:], deprecatedSessionTicketKey)
- } else if !bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) && len(c.sessionTicketKeys) == 0 {
- c.sessionTicketKeys = []ticketKey{c.ticketKeyFromBytes(c.SessionTicketKey)}
- }
-
-}
-
-// ticketKeys returns the ticketKeys for this connection.
-// If configForClient has explicitly set keys, those will
-// be returned. Otherwise, the keys on c will be used and
-// may be rotated if auto-managed.
-// During rotation, any expired session ticket keys are deleted from
-// c.sessionTicketKeys. If the session ticket key that is currently
-// encrypting tickets (ie. the first ticketKey in c.sessionTicketKeys)
-// is not fresh, then a new session ticket key will be
-// created and prepended to c.sessionTicketKeys.
-func (c *Config) ticketKeys(configForClient *Config) []ticketKey {
- // If the ConfigForClient callback returned a Config with explicitly set
- // keys, use those, otherwise just use the original Config.
- if configForClient != nil {
- configForClient.mutex.RLock()
- if configForClient.SessionTicketsDisabled {
- return nil
- }
- configForClient.initLegacySessionTicketKeyRLocked()
- if len(configForClient.sessionTicketKeys) != 0 {
- ret := configForClient.sessionTicketKeys
- configForClient.mutex.RUnlock()
- return ret
- }
- configForClient.mutex.RUnlock()
- }
-
- c.mutex.RLock()
- defer c.mutex.RUnlock()
- if c.SessionTicketsDisabled {
- return nil
- }
- c.initLegacySessionTicketKeyRLocked()
- if len(c.sessionTicketKeys) != 0 {
- return c.sessionTicketKeys
- }
- // Fast path for the common case where the key is fresh enough.
- if len(c.autoSessionTicketKeys) > 0 && c.time().Sub(c.autoSessionTicketKeys[0].created) < ticketKeyRotation {
- return c.autoSessionTicketKeys
- }
-
- // autoSessionTicketKeys are managed by auto-rotation.
- c.mutex.RUnlock()
- defer c.mutex.RLock()
- c.mutex.Lock()
- defer c.mutex.Unlock()
- // Re-check the condition in case it changed since obtaining the new lock.
- if len(c.autoSessionTicketKeys) == 0 || c.time().Sub(c.autoSessionTicketKeys[0].created) >= ticketKeyRotation {
- var newKey [32]byte
- if _, err := io.ReadFull(c.rand(), newKey[:]); err != nil {
- panic(fmt.Sprintf("unable to generate random session ticket key: %v", err))
- }
- valid := make([]ticketKey, 0, len(c.autoSessionTicketKeys)+1)
- valid = append(valid, c.ticketKeyFromBytes(newKey))
- for _, k := range c.autoSessionTicketKeys {
- // While rotating the current key, also remove any expired ones.
- if c.time().Sub(k.created) < ticketKeyLifetime {
- valid = append(valid, k)
- }
- }
- c.autoSessionTicketKeys = valid
- }
- return c.autoSessionTicketKeys
-}
-
-// SetSessionTicketKeys updates the session ticket keys for a server.
-//
-// The first key will be used when creating new tickets, while all keys can be
-// used for decrypting tickets. It is safe to call this function while the
-// server is running in order to rotate the session ticket keys. The function
-// will panic if keys is empty.
-//
-// Calling this function will turn off automatic session ticket key rotation.
-//
-// If multiple servers are terminating connections for the same host they should
-// all have the same session ticket keys. If the session ticket keys leaks,
-// previously recorded and future TLS connections using those keys might be
-// compromised.
-func (c *Config) SetSessionTicketKeys(keys [][32]byte) {
- if len(keys) == 0 {
- panic("tls: keys must have at least one key")
- }
-
- newKeys := make([]ticketKey, len(keys))
- for i, bytes := range keys {
- newKeys[i] = c.ticketKeyFromBytes(bytes)
- }
-
- c.mutex.Lock()
- c.sessionTicketKeys = newKeys
- c.mutex.Unlock()
-}
-
-func (c *Config) rand() io.Reader {
- r := c.Rand
- if r == nil {
- return rand.Reader
- }
- return r
-}
-
-func (c *Config) time() time.Time {
- t := c.Time
- if t == nil {
- t = time.Now
- }
- return t()
-}
-
-func (c *Config) cipherSuites() []uint16 {
- if needFIPS() {
- return fipsCipherSuites(c)
- }
- if c.CipherSuites != nil {
- return c.CipherSuites
- }
- return defaultCipherSuites
-}
-
-var supportedVersions = []uint16{
- VersionTLS13,
- VersionTLS12,
- VersionTLS11,
- VersionTLS10,
-}
-
-// roleClient and roleServer are meant to call supportedVersions and parents
-// with more readability at the callsite.
-const roleClient = true
-const roleServer = false
-
-func (c *Config) supportedVersions(isClient bool) []uint16 {
- versions := make([]uint16, 0, len(supportedVersions))
- for _, v := range supportedVersions {
- if needFIPS() && (v < fipsMinVersion(c) || v > fipsMaxVersion(c)) {
- continue
- }
- if (c == nil || c.MinVersion == 0) &&
- isClient && v < VersionTLS12 {
- continue
- }
- if c != nil && c.MinVersion != 0 && v < c.MinVersion {
- continue
- }
- if c != nil && c.MaxVersion != 0 && v > c.MaxVersion {
- continue
- }
- versions = append(versions, v)
- }
- return versions
-}
-
-func (c *Config) maxSupportedVersion(isClient bool) uint16 {
- supportedVersions := c.supportedVersions(isClient)
- if len(supportedVersions) == 0 {
- return 0
- }
- return supportedVersions[0]
-}
-
-// supportedVersionsFromMax returns a list of supported versions derived from a
-// legacy maximum version value. Note that only versions supported by this
-// library are returned. Any newer peer will use supportedVersions anyway.
-func supportedVersionsFromMax(maxVersion uint16) []uint16 {
- versions := make([]uint16, 0, len(supportedVersions))
- for _, v := range supportedVersions {
- if v > maxVersion {
- continue
- }
- versions = append(versions, v)
- }
- return versions
-}
-
-var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521}
-
-func (c *Config) curvePreferences() []CurveID {
- if needFIPS() {
- return fipsCurvePreferences(c)
- }
- if c == nil || len(c.CurvePreferences) == 0 {
- return defaultCurvePreferences
- }
- return c.CurvePreferences
-}
-
-func (c *Config) supportsCurve(curve CurveID) bool {
- for _, cc := range c.curvePreferences() {
- if cc == curve {
- return true
- }
- }
- return false
-}
-
-// mutualVersion returns the protocol version to use given the advertised
-// versions of the peer. Priority is given to the peer preference order.
-func (c *Config) mutualVersion(isClient bool, peerVersions []uint16) (uint16, bool) {
- supportedVersions := c.supportedVersions(isClient)
- for _, peerVersion := range peerVersions {
- for _, v := range supportedVersions {
- if v == peerVersion {
- return v, true
- }
- }
- }
- return 0, false
-}
-
-var errNoCertificates = errors.New("tls: no certificates configured")
-
-// getCertificate returns the best certificate for the given ClientHelloInfo,
-// defaulting to the first element of c.Certificates.
-func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) {
- if c.GetCertificate != nil &&
- (len(c.Certificates) == 0 || len(clientHello.ServerName) > 0) {
- cert, err := c.GetCertificate(clientHello)
- if cert != nil || err != nil {
- return cert, err
- }
- }
-
- if len(c.Certificates) == 0 {
- return nil, errNoCertificates
- }
-
- if len(c.Certificates) == 1 {
- // There's only one choice, so no point doing any work.
- return &c.Certificates[0], nil
- }
-
- if c.NameToCertificate != nil {
- name := strings.ToLower(clientHello.ServerName)
- if cert, ok := c.NameToCertificate[name]; ok {
- return cert, nil
- }
- if len(name) > 0 {
- labels := strings.Split(name, ".")
- labels[0] = "*"
- wildcardName := strings.Join(labels, ".")
- if cert, ok := c.NameToCertificate[wildcardName]; ok {
- return cert, nil
- }
- }
- }
-
- for _, cert := range c.Certificates {
- if err := clientHello.SupportsCertificate(&cert); err == nil {
- return &cert, nil
- }
- }
-
- // If nothing matches, return the first certificate.
- return &c.Certificates[0], nil
-}
-
-// SupportsCertificate returns nil if the provided certificate is supported by
-// the client that sent the ClientHello. Otherwise, it returns an error
-// describing the reason for the incompatibility.
-//
-// If this ClientHelloInfo was passed to a GetConfigForClient or GetCertificate
-// callback, this method will take into account the associated Config. Note that
-// if GetConfigForClient returns a different Config, the change can't be
-// accounted for by this method.
-//
-// This function will call x509.ParseCertificate unless c.Leaf is set, which can
-// incur a significant performance cost.
-func (chi *ClientHelloInfo) SupportsCertificate(c *Certificate) error {
- // Note we don't currently support certificate_authorities nor
- // signature_algorithms_cert, and don't check the algorithms of the
- // signatures on the chain (which anyway are a SHOULD, see RFC 8446,
- // Section 4.4.2.2).
-
- config := chi.config
- if config == nil {
- config = &Config{}
- }
- vers, ok := config.mutualVersion(roleServer, chi.SupportedVersions)
- if !ok {
- return errors.New("no mutually supported protocol versions")
- }
-
- // If the client specified the name they are trying to connect to, the
- // certificate needs to be valid for it.
- if chi.ServerName != "" {
- x509Cert, err := c.leaf()
- if err != nil {
- return fmt.Errorf("failed to parse certificate: %w", err)
- }
- if err := x509Cert.VerifyHostname(chi.ServerName); err != nil {
- return fmt.Errorf("certificate is not valid for requested server name: %w", err)
- }
- }
-
- // supportsRSAFallback returns nil if the certificate and connection support
- // the static RSA key exchange, and unsupported otherwise. The logic for
- // supporting static RSA is completely disjoint from the logic for
- // supporting signed key exchanges, so we just check it as a fallback.
- supportsRSAFallback := func(unsupported error) error {
- // TLS 1.3 dropped support for the static RSA key exchange.
- if vers == VersionTLS13 {
- return unsupported
- }
- // The static RSA key exchange works by decrypting a challenge with the
- // RSA private key, not by signing, so check the PrivateKey implements
- // crypto.Decrypter, like *rsa.PrivateKey does.
- if priv, ok := c.PrivateKey.(crypto.Decrypter); ok {
- if _, ok := priv.Public().(*rsa.PublicKey); !ok {
- return unsupported
- }
- } else {
- return unsupported
- }
- // Finally, there needs to be a mutual cipher suite that uses the static
- // RSA key exchange instead of ECDHE.
- rsaCipherSuite := selectCipherSuite(chi.CipherSuites, config.cipherSuites(), func(c *cipherSuite) bool {
- if c.flags&suiteECDHE != 0 {
- return false
- }
- if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
- return false
- }
- return true
- })
- if rsaCipherSuite == nil {
- return unsupported
- }
- return nil
- }
-
- // If the client sent the signature_algorithms extension, ensure it supports
- // schemes we can use with this certificate and TLS version.
- if len(chi.SignatureSchemes) > 0 {
- if _, err := selectSignatureScheme(vers, c, chi.SignatureSchemes); err != nil {
- return supportsRSAFallback(err)
- }
- }
-
- // In TLS 1.3 we are done because supported_groups is only relevant to the
- // ECDHE computation, point format negotiation is removed, cipher suites are
- // only relevant to the AEAD choice, and static RSA does not exist.
- if vers == VersionTLS13 {
- return nil
- }
-
- // The only signed key exchange we support is ECDHE.
- if !supportsECDHE(config, chi.SupportedCurves, chi.SupportedPoints) {
- return supportsRSAFallback(errors.New("client doesn't support ECDHE, can only use legacy RSA key exchange"))
- }
-
- var ecdsaCipherSuite bool
- if priv, ok := c.PrivateKey.(crypto.Signer); ok {
- switch pub := priv.Public().(type) {
- case *ecdsa.PublicKey:
- var curve CurveID
- switch pub.Curve {
- case elliptic.P256():
- curve = CurveP256
- case elliptic.P384():
- curve = CurveP384
- case elliptic.P521():
- curve = CurveP521
- default:
- return supportsRSAFallback(unsupportedCertificateError(c))
- }
- var curveOk bool
- for _, c := range chi.SupportedCurves {
- if c == curve && config.supportsCurve(c) {
- curveOk = true
- break
- }
- }
- if !curveOk {
- return errors.New("client doesn't support certificate curve")
- }
- ecdsaCipherSuite = true
- case ed25519.PublicKey:
- if vers < VersionTLS12 || len(chi.SignatureSchemes) == 0 {
- return errors.New("connection doesn't support Ed25519")
- }
- ecdsaCipherSuite = true
- case *rsa.PublicKey:
- default:
- return supportsRSAFallback(unsupportedCertificateError(c))
- }
- } else {
- return supportsRSAFallback(unsupportedCertificateError(c))
- }
-
- // Make sure that there is a mutually supported cipher suite that works with
- // this certificate. Cipher suite selection will then apply the logic in
- // reverse to pick it. See also serverHandshakeState.cipherSuiteOk.
- cipherSuite := selectCipherSuite(chi.CipherSuites, config.cipherSuites(), func(c *cipherSuite) bool {
- if c.flags&suiteECDHE == 0 {
- return false
- }
- if c.flags&suiteECSign != 0 {
- if !ecdsaCipherSuite {
- return false
- }
- } else {
- if ecdsaCipherSuite {
- return false
- }
- }
- if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
- return false
- }
- return true
- })
- if cipherSuite == nil {
- return supportsRSAFallback(errors.New("client doesn't support any cipher suites compatible with the certificate"))
- }
-
- return nil
-}
-
-// SupportsCertificate returns nil if the provided certificate is supported by
-// the server that sent the CertificateRequest. Otherwise, it returns an error
-// describing the reason for the incompatibility.
-func (cri *CertificateRequestInfo) SupportsCertificate(c *Certificate) error {
- if _, err := selectSignatureScheme(cri.Version, c, cri.SignatureSchemes); err != nil {
- return err
- }
-
- if len(cri.AcceptableCAs) == 0 {
- return nil
- }
-
- for j, cert := range c.Certificate {
- x509Cert := c.Leaf
- // Parse the certificate if this isn't the leaf node, or if
- // chain.Leaf was nil.
- if j != 0 || x509Cert == nil {
- var err error
- if x509Cert, err = x509.ParseCertificate(cert); err != nil {
- return fmt.Errorf("failed to parse certificate #%d in the chain: %w", j, err)
- }
- }
-
- for _, ca := range cri.AcceptableCAs {
- if bytes.Equal(x509Cert.RawIssuer, ca) {
- return nil
- }
- }
- }
- return errors.New("chain is not signed by an acceptable CA")
-}
-
-// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate
-// from the CommonName and SubjectAlternateName fields of each of the leaf
-// certificates.
-//
-// Deprecated: NameToCertificate only allows associating a single certificate
-// with a given name. Leave that field nil to let the library select the first
-// compatible chain from Certificates.
-func (c *Config) BuildNameToCertificate() {
- c.NameToCertificate = make(map[string]*Certificate)
- for i := range c.Certificates {
- cert := &c.Certificates[i]
- x509Cert, err := cert.leaf()
- if err != nil {
- continue
- }
- // If SANs are *not* present, some clients will consider the certificate
- // valid for the name in the Common Name.
- if x509Cert.Subject.CommonName != "" && len(x509Cert.DNSNames) == 0 {
- c.NameToCertificate[x509Cert.Subject.CommonName] = cert
- }
- for _, san := range x509Cert.DNSNames {
- c.NameToCertificate[san] = cert
- }
- }
-}
-
-const (
- keyLogLabelTLS12 = "CLIENT_RANDOM"
- keyLogLabelClientHandshake = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"
- keyLogLabelServerHandshake = "SERVER_HANDSHAKE_TRAFFIC_SECRET"
- keyLogLabelClientTraffic = "CLIENT_TRAFFIC_SECRET_0"
- keyLogLabelServerTraffic = "SERVER_TRAFFIC_SECRET_0"
-)
-
-func (c *Config) writeKeyLog(label string, clientRandom, secret []byte) error {
- if c.KeyLogWriter == nil {
- return nil
- }
-
- logLine := fmt.Appendf(nil, "%s %x %x\n", label, clientRandom, secret)
-
- writerMutex.Lock()
- _, err := c.KeyLogWriter.Write(logLine)
- writerMutex.Unlock()
-
- return err
-}
-
-// writerMutex protects all KeyLogWriters globally. It is rarely enabled,
-// and is only for debugging, so a global mutex saves space.
-var writerMutex sync.Mutex
-
-// A Certificate is a chain of one or more certificates, leaf first.
-type Certificate struct {
- Certificate [][]byte
- // PrivateKey contains the private key corresponding to the public key in
- // Leaf. This must implement crypto.Signer with an RSA, ECDSA or Ed25519 PublicKey.
- // For a server up to TLS 1.2, it can also implement crypto.Decrypter with
- // an RSA PublicKey.
- PrivateKey crypto.PrivateKey
- // SupportedSignatureAlgorithms is an optional list restricting what
- // signature algorithms the PrivateKey can be used for.
- SupportedSignatureAlgorithms []SignatureScheme
- // OCSPStaple contains an optional OCSP response which will be served
- // to clients that request it.
- OCSPStaple []byte
- // SignedCertificateTimestamps contains an optional list of Signed
- // Certificate Timestamps which will be served to clients that request it.
- SignedCertificateTimestamps [][]byte
- // Leaf is the parsed form of the leaf certificate, which may be initialized
- // using x509.ParseCertificate to reduce per-handshake processing. If nil,
- // the leaf certificate will be parsed as needed.
- Leaf *x509.Certificate
-}
-
-// leaf returns the parsed leaf certificate, either from c.Leaf or by parsing
-// the corresponding c.Certificate[0].
-func (c *Certificate) leaf() (*x509.Certificate, error) {
- if c.Leaf != nil {
- return c.Leaf, nil
- }
- return x509.ParseCertificate(c.Certificate[0])
-}
-
-type handshakeMessage interface {
- marshal() ([]byte, error)
- unmarshal([]byte) bool
-}
-
-// lruSessionCache is a ClientSessionCache implementation that uses an LRU
-// caching strategy.
-type lruSessionCache struct {
- sync.Mutex
-
- m map[string]*list.Element
- q *list.List
- capacity int
-}
-
-type lruSessionCacheEntry struct {
- sessionKey string
- state *ClientSessionState
-}
-
-// NewLRUClientSessionCache returns a ClientSessionCache with the given
-// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
-// is used instead.
-func NewLRUClientSessionCache(capacity int) ClientSessionCache {
- const defaultSessionCacheCapacity = 64
-
- if capacity < 1 {
- capacity = defaultSessionCacheCapacity
- }
- return &lruSessionCache{
- m: make(map[string]*list.Element),
- q: list.New(),
- capacity: capacity,
- }
-}
-
-// Put adds the provided (sessionKey, cs) pair to the cache. If cs is nil, the entry
-// corresponding to sessionKey is removed from the cache instead.
-func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) {
- c.Lock()
- defer c.Unlock()
-
- if elem, ok := c.m[sessionKey]; ok {
- if cs == nil {
- c.q.Remove(elem)
- delete(c.m, sessionKey)
- } else {
- entry := elem.Value.(*lruSessionCacheEntry)
- entry.state = cs
- c.q.MoveToFront(elem)
- }
- return
- }
-
- if c.q.Len() < c.capacity {
- entry := &lruSessionCacheEntry{sessionKey, cs}
- c.m[sessionKey] = c.q.PushFront(entry)
- return
- }
-
- elem := c.q.Back()
- entry := elem.Value.(*lruSessionCacheEntry)
- delete(c.m, entry.sessionKey)
- entry.sessionKey = sessionKey
- entry.state = cs
- c.q.MoveToFront(elem)
- c.m[sessionKey] = elem
-}
-
-// Get returns the ClientSessionState value associated with a given key. It
-// returns (nil, false) if no value is found.
-func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
- c.Lock()
- defer c.Unlock()
-
- if elem, ok := c.m[sessionKey]; ok {
- c.q.MoveToFront(elem)
- return elem.Value.(*lruSessionCacheEntry).state, true
- }
- return nil, false
-}
-
-var emptyConfig Config
-
-func defaultConfig() *Config {
- return &emptyConfig
-}
-
-func unexpectedMessageError(wanted, got any) error {
- return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted)
-}
-
-func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlgorithms []SignatureScheme) bool {
- for _, s := range supportedSignatureAlgorithms {
- if s == sigAlg {
- return true
- }
- }
- return false
-}
-
-// CertificateVerificationError is returned when certificate verification fails during the handshake.
-type CertificateVerificationError struct {
- // UnverifiedCertificates and its contents should not be modified.
- UnverifiedCertificates []*x509.Certificate
- Err error
-}
-
-func (e *CertificateVerificationError) Error() string {
- return fmt.Sprintf("tls: failed to verify certificate: %s", e.Err)
-}
-
-func (e *CertificateVerificationError) Unwrap() error {
- return e.Err
-}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/conn.go b/contrib/go/_std_1.20/src/crypto/tls/conn.go
deleted file mode 100644
index 1eefb17206..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/conn.go
+++ /dev/null
@@ -1,1570 +0,0 @@
-// Copyright 2010 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.
-
-// TLS low level connection and record layer
-
-package tls
-
-import (
- "bytes"
- "context"
- "crypto/cipher"
- "crypto/subtle"
- "crypto/x509"
- "errors"
- "fmt"
- "hash"
- "io"
- "net"
- "sync"
- "sync/atomic"
- "time"
-)
-
-// A Conn represents a secured connection.
-// It implements the net.Conn interface.
-type Conn struct {
- // constant
- conn net.Conn
- isClient bool
- handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake
-
- // isHandshakeComplete is true if the connection is currently transferring
- // application data (i.e. is not currently processing a handshake).
- // isHandshakeComplete is true implies handshakeErr == nil.
- isHandshakeComplete atomic.Bool
- // constant after handshake; protected by handshakeMutex
- handshakeMutex sync.Mutex
- handshakeErr error // error resulting from handshake
- vers uint16 // TLS version
- haveVers bool // version has been negotiated
- config *Config // configuration passed to constructor
- // handshakes counts the number of handshakes performed on the
- // connection so far. If renegotiation is disabled then this is either
- // zero or one.
- handshakes int
- didResume bool // whether this connection was a session resumption
- cipherSuite uint16
- ocspResponse []byte // stapled OCSP response
- scts [][]byte // signed certificate timestamps from server
- peerCertificates []*x509.Certificate
- // activeCertHandles contains the cache handles to certificates in
- // peerCertificates that are used to track active references.
- activeCertHandles []*activeCert
- // verifiedChains contains the certificate chains that we built, as
- // opposed to the ones presented by the server.
- verifiedChains [][]*x509.Certificate
- // serverName contains the server name indicated by the client, if any.
- serverName string
- // secureRenegotiation is true if the server echoed the secure
- // renegotiation extension. (This is meaningless as a server because
- // renegotiation is not supported in that case.)
- secureRenegotiation bool
- // ekm is a closure for exporting keying material.
- ekm func(label string, context []byte, length int) ([]byte, error)
- // resumptionSecret is the resumption_master_secret for handling
- // NewSessionTicket messages. nil if config.SessionTicketsDisabled.
- resumptionSecret []byte
-
- // ticketKeys is the set of active session ticket keys for this
- // connection. The first one is used to encrypt new tickets and
- // all are tried to decrypt tickets.
- ticketKeys []ticketKey
-
- // clientFinishedIsFirst is true if the client sent the first Finished
- // message during the most recent handshake. This is recorded because
- // the first transmitted Finished message is the tls-unique
- // channel-binding value.
- clientFinishedIsFirst bool
-
- // closeNotifyErr is any error from sending the alertCloseNotify record.
- closeNotifyErr error
- // closeNotifySent is true if the Conn attempted to send an
- // alertCloseNotify record.
- closeNotifySent bool
-
- // clientFinished and serverFinished contain the Finished message sent
- // by the client or server in the most recent handshake. This is
- // retained to support the renegotiation extension and tls-unique
- // channel-binding.
- clientFinished [12]byte
- serverFinished [12]byte
-
- // clientProtocol is the negotiated ALPN protocol.
- clientProtocol string
-
- // input/output
- in, out halfConn
- rawInput bytes.Buffer // raw input, starting with a record header
- input bytes.Reader // application data waiting to be read, from rawInput.Next
- hand bytes.Buffer // handshake data waiting to be read
- buffering bool // whether records are buffered in sendBuf
- sendBuf []byte // a buffer of records waiting to be sent
-
- // bytesSent counts the bytes of application data sent.
- // packetsSent counts packets.
- bytesSent int64
- packetsSent int64
-
- // retryCount counts the number of consecutive non-advancing records
- // received by Conn.readRecord. That is, records that neither advance the
- // handshake, nor deliver application data. Protected by in.Mutex.
- retryCount int
-
- // activeCall indicates whether Close has been call in the low bit.
- // the rest of the bits are the number of goroutines in Conn.Write.
- activeCall atomic.Int32
-
- tmp [16]byte
-}
-
-// Access to net.Conn methods.
-// Cannot just embed net.Conn because that would
-// export the struct field too.
-
-// LocalAddr returns the local network address.
-func (c *Conn) LocalAddr() net.Addr {
- return c.conn.LocalAddr()
-}
-
-// RemoteAddr returns the remote network address.
-func (c *Conn) RemoteAddr() net.Addr {
- return c.conn.RemoteAddr()
-}
-
-// SetDeadline sets the read and write deadlines associated with the connection.
-// A zero value for t means Read and Write will not time out.
-// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
-func (c *Conn) SetDeadline(t time.Time) error {
- return c.conn.SetDeadline(t)
-}
-
-// SetReadDeadline sets the read deadline on the underlying connection.
-// A zero value for t means Read will not time out.
-func (c *Conn) SetReadDeadline(t time.Time) error {
- return c.conn.SetReadDeadline(t)
-}
-
-// SetWriteDeadline sets the write deadline on the underlying connection.
-// A zero value for t means Write will not time out.
-// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
-func (c *Conn) SetWriteDeadline(t time.Time) error {
- return c.conn.SetWriteDeadline(t)
-}
-
-// NetConn returns the underlying connection that is wrapped by c.
-// Note that writing to or reading from this connection directly will corrupt the
-// TLS session.
-func (c *Conn) NetConn() net.Conn {
- return c.conn
-}
-
-// A halfConn represents one direction of the record layer
-// connection, either sending or receiving.
-type halfConn struct {
- sync.Mutex
-
- err error // first permanent error
- version uint16 // protocol version
- cipher any // cipher algorithm
- mac hash.Hash
- seq [8]byte // 64-bit sequence number
-
- scratchBuf [13]byte // to avoid allocs; interface method args escape
-
- nextCipher any // next encryption state
- nextMac hash.Hash // next MAC algorithm
-
- trafficSecret []byte // current TLS 1.3 traffic secret
-}
-
-type permanentError struct {
- err net.Error
-}
-
-func (e *permanentError) Error() string { return e.err.Error() }
-func (e *permanentError) Unwrap() error { return e.err }
-func (e *permanentError) Timeout() bool { return e.err.Timeout() }
-func (e *permanentError) Temporary() bool { return false }
-
-func (hc *halfConn) setErrorLocked(err error) error {
- if e, ok := err.(net.Error); ok {
- hc.err = &permanentError{err: e}
- } else {
- hc.err = err
- }
- return hc.err
-}
-
-// prepareCipherSpec sets the encryption and MAC states
-// that a subsequent changeCipherSpec will use.
-func (hc *halfConn) prepareCipherSpec(version uint16, cipher any, mac hash.Hash) {
- hc.version = version
- hc.nextCipher = cipher
- hc.nextMac = mac
-}
-
-// changeCipherSpec changes the encryption and MAC states
-// to the ones previously passed to prepareCipherSpec.
-func (hc *halfConn) changeCipherSpec() error {
- if hc.nextCipher == nil || hc.version == VersionTLS13 {
- return alertInternalError
- }
- hc.cipher = hc.nextCipher
- hc.mac = hc.nextMac
- hc.nextCipher = nil
- hc.nextMac = nil
- for i := range hc.seq {
- hc.seq[i] = 0
- }
- return nil
-}
-
-func (hc *halfConn) setTrafficSecret(suite *cipherSuiteTLS13, secret []byte) {
- hc.trafficSecret = secret
- key, iv := suite.trafficKey(secret)
- hc.cipher = suite.aead(key, iv)
- for i := range hc.seq {
- hc.seq[i] = 0
- }
-}
-
-// incSeq increments the sequence number.
-func (hc *halfConn) incSeq() {
- for i := 7; i >= 0; i-- {
- hc.seq[i]++
- if hc.seq[i] != 0 {
- return
- }
- }
-
- // Not allowed to let sequence number wrap.
- // Instead, must renegotiate before it does.
- // Not likely enough to bother.
- panic("TLS: sequence number wraparound")
-}
-
-// explicitNonceLen returns the number of bytes of explicit nonce or IV included
-// in each record. Explicit nonces are present only in CBC modes after TLS 1.0
-// and in certain AEAD modes in TLS 1.2.
-func (hc *halfConn) explicitNonceLen() int {
- if hc.cipher == nil {
- return 0
- }
-
- switch c := hc.cipher.(type) {
- case cipher.Stream:
- return 0
- case aead:
- return c.explicitNonceLen()
- case cbcMode:
- // TLS 1.1 introduced a per-record explicit IV to fix the BEAST attack.
- if hc.version >= VersionTLS11 {
- return c.BlockSize()
- }
- return 0
- default:
- panic("unknown cipher type")
- }
-}
-
-// extractPadding returns, in constant time, the length of the padding to remove
-// from the end of payload. It also returns a byte which is equal to 255 if the
-// padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2.
-func extractPadding(payload []byte) (toRemove int, good byte) {
- if len(payload) < 1 {
- return 0, 0
- }
-
- paddingLen := payload[len(payload)-1]
- t := uint(len(payload)-1) - uint(paddingLen)
- // if len(payload) >= (paddingLen - 1) then the MSB of t is zero
- good = byte(int32(^t) >> 31)
-
- // The maximum possible padding length plus the actual length field
- toCheck := 256
- // The length of the padded data is public, so we can use an if here
- if toCheck > len(payload) {
- toCheck = len(payload)
- }
-
- for i := 0; i < toCheck; i++ {
- t := uint(paddingLen) - uint(i)
- // if i <= paddingLen then the MSB of t is zero
- mask := byte(int32(^t) >> 31)
- b := payload[len(payload)-1-i]
- good &^= mask&paddingLen ^ mask&b
- }
-
- // We AND together the bits of good and replicate the result across
- // all the bits.
- good &= good << 4
- good &= good << 2
- good &= good << 1
- good = uint8(int8(good) >> 7)
-
- // Zero the padding length on error. This ensures any unchecked bytes
- // are included in the MAC. Otherwise, an attacker that could
- // distinguish MAC failures from padding failures could mount an attack
- // similar to POODLE in SSL 3.0: given a good ciphertext that uses a
- // full block's worth of padding, replace the final block with another
- // block. If the MAC check passed but the padding check failed, the
- // last byte of that block decrypted to the block size.
- //
- // See also macAndPaddingGood logic below.
- paddingLen &= good
-
- toRemove = int(paddingLen) + 1
- return
-}
-
-func roundUp(a, b int) int {
- return a + (b-a%b)%b
-}
-
-// cbcMode is an interface for block ciphers using cipher block chaining.
-type cbcMode interface {
- cipher.BlockMode
- SetIV([]byte)
-}
-
-// decrypt authenticates and decrypts the record if protection is active at
-// this stage. The returned plaintext might overlap with the input.
-func (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) {
- var plaintext []byte
- typ := recordType(record[0])
- payload := record[recordHeaderLen:]
-
- // In TLS 1.3, change_cipher_spec messages are to be ignored without being
- // decrypted. See RFC 8446, Appendix D.4.
- if hc.version == VersionTLS13 && typ == recordTypeChangeCipherSpec {
- return payload, typ, nil
- }
-
- paddingGood := byte(255)
- paddingLen := 0
-
- explicitNonceLen := hc.explicitNonceLen()
-
- if hc.cipher != nil {
- switch c := hc.cipher.(type) {
- case cipher.Stream:
- c.XORKeyStream(payload, payload)
- case aead:
- if len(payload) < explicitNonceLen {
- return nil, 0, alertBadRecordMAC
- }
- nonce := payload[:explicitNonceLen]
- if len(nonce) == 0 {
- nonce = hc.seq[:]
- }
- payload = payload[explicitNonceLen:]
-
- var additionalData []byte
- if hc.version == VersionTLS13 {
- additionalData = record[:recordHeaderLen]
- } else {
- additionalData = append(hc.scratchBuf[:0], hc.seq[:]...)
- additionalData = append(additionalData, record[:3]...)
- n := len(payload) - c.Overhead()
- additionalData = append(additionalData, byte(n>>8), byte(n))
- }
-
- var err error
- plaintext, err = c.Open(payload[:0], nonce, payload, additionalData)
- if err != nil {
- return nil, 0, alertBadRecordMAC
- }
- case cbcMode:
- blockSize := c.BlockSize()
- minPayload := explicitNonceLen + roundUp(hc.mac.Size()+1, blockSize)
- if len(payload)%blockSize != 0 || len(payload) < minPayload {
- return nil, 0, alertBadRecordMAC
- }
-
- if explicitNonceLen > 0 {
- c.SetIV(payload[:explicitNonceLen])
- payload = payload[explicitNonceLen:]
- }
- c.CryptBlocks(payload, payload)
-
- // In a limited attempt to protect against CBC padding oracles like
- // Lucky13, the data past paddingLen (which is secret) is passed to
- // the MAC function as extra data, to be fed into the HMAC after
- // computing the digest. This makes the MAC roughly constant time as
- // long as the digest computation is constant time and does not
- // affect the subsequent write, modulo cache effects.
- paddingLen, paddingGood = extractPadding(payload)
- default:
- panic("unknown cipher type")
- }
-
- if hc.version == VersionTLS13 {
- if typ != recordTypeApplicationData {
- return nil, 0, alertUnexpectedMessage
- }
- if len(plaintext) > maxPlaintext+1 {
- return nil, 0, alertRecordOverflow
- }
- // Remove padding and find the ContentType scanning from the end.
- for i := len(plaintext) - 1; i >= 0; i-- {
- if plaintext[i] != 0 {
- typ = recordType(plaintext[i])
- plaintext = plaintext[:i]
- break
- }
- if i == 0 {
- return nil, 0, alertUnexpectedMessage
- }
- }
- }
- } else {
- plaintext = payload
- }
-
- if hc.mac != nil {
- macSize := hc.mac.Size()
- if len(payload) < macSize {
- return nil, 0, alertBadRecordMAC
- }
-
- n := len(payload) - macSize - paddingLen
- n = subtle.ConstantTimeSelect(int(uint32(n)>>31), 0, n) // if n < 0 { n = 0 }
- record[3] = byte(n >> 8)
- record[4] = byte(n)
- remoteMAC := payload[n : n+macSize]
- localMAC := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload[:n], payload[n+macSize:])
-
- // This is equivalent to checking the MACs and paddingGood
- // separately, but in constant-time to prevent distinguishing
- // padding failures from MAC failures. Depending on what value
- // of paddingLen was returned on bad padding, distinguishing
- // bad MAC from bad padding can lead to an attack.
- //
- // See also the logic at the end of extractPadding.
- macAndPaddingGood := subtle.ConstantTimeCompare(localMAC, remoteMAC) & int(paddingGood)
- if macAndPaddingGood != 1 {
- return nil, 0, alertBadRecordMAC
- }
-
- plaintext = payload[:n]
- }
-
- hc.incSeq()
- return plaintext, typ, nil
-}
-
-// sliceForAppend extends the input slice by n bytes. head is the full extended
-// slice, while tail is the appended part. If the original slice has sufficient
-// capacity no allocation is performed.
-func sliceForAppend(in []byte, n int) (head, tail []byte) {
- if total := len(in) + n; cap(in) >= total {
- head = in[:total]
- } else {
- head = make([]byte, total)
- copy(head, in)
- }
- tail = head[len(in):]
- return
-}
-
-// encrypt encrypts payload, adding the appropriate nonce and/or MAC, and
-// appends it to record, which must already contain the record header.
-func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, error) {
- if hc.cipher == nil {
- return append(record, payload...), nil
- }
-
- var explicitNonce []byte
- if explicitNonceLen := hc.explicitNonceLen(); explicitNonceLen > 0 {
- record, explicitNonce = sliceForAppend(record, explicitNonceLen)
- if _, isCBC := hc.cipher.(cbcMode); !isCBC && explicitNonceLen < 16 {
- // The AES-GCM construction in TLS has an explicit nonce so that the
- // nonce can be random. However, the nonce is only 8 bytes which is
- // too small for a secure, random nonce. Therefore we use the
- // sequence number as the nonce. The 3DES-CBC construction also has
- // an 8 bytes nonce but its nonces must be unpredictable (see RFC
- // 5246, Appendix F.3), forcing us to use randomness. That's not
- // 3DES' biggest problem anyway because the birthday bound on block
- // collision is reached first due to its similarly small block size
- // (see the Sweet32 attack).
- copy(explicitNonce, hc.seq[:])
- } else {
- if _, err := io.ReadFull(rand, explicitNonce); err != nil {
- return nil, err
- }
- }
- }
-
- var dst []byte
- switch c := hc.cipher.(type) {
- case cipher.Stream:
- mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil)
- record, dst = sliceForAppend(record, len(payload)+len(mac))
- c.XORKeyStream(dst[:len(payload)], payload)
- c.XORKeyStream(dst[len(payload):], mac)
- case aead:
- nonce := explicitNonce
- if len(nonce) == 0 {
- nonce = hc.seq[:]
- }
-
- if hc.version == VersionTLS13 {
- record = append(record, payload...)
-
- // Encrypt the actual ContentType and replace the plaintext one.
- record = append(record, record[0])
- record[0] = byte(recordTypeApplicationData)
-
- n := len(payload) + 1 + c.Overhead()
- record[3] = byte(n >> 8)
- record[4] = byte(n)
-
- record = c.Seal(record[:recordHeaderLen],
- nonce, record[recordHeaderLen:], record[:recordHeaderLen])
- } else {
- additionalData := append(hc.scratchBuf[:0], hc.seq[:]...)
- additionalData = append(additionalData, record[:recordHeaderLen]...)
- record = c.Seal(record, nonce, payload, additionalData)
- }
- case cbcMode:
- mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil)
- blockSize := c.BlockSize()
- plaintextLen := len(payload) + len(mac)
- paddingLen := blockSize - plaintextLen%blockSize
- record, dst = sliceForAppend(record, plaintextLen+paddingLen)
- copy(dst, payload)
- copy(dst[len(payload):], mac)
- for i := plaintextLen; i < len(dst); i++ {
- dst[i] = byte(paddingLen - 1)
- }
- if len(explicitNonce) > 0 {
- c.SetIV(explicitNonce)
- }
- c.CryptBlocks(dst, dst)
- default:
- panic("unknown cipher type")
- }
-
- // Update length to include nonce, MAC and any block padding needed.
- n := len(record) - recordHeaderLen
- record[3] = byte(n >> 8)
- record[4] = byte(n)
- hc.incSeq()
-
- return record, nil
-}
-
-// RecordHeaderError is returned when a TLS record header is invalid.
-type RecordHeaderError struct {
- // Msg contains a human readable string that describes the error.
- Msg string
- // RecordHeader contains the five bytes of TLS record header that
- // triggered the error.
- RecordHeader [5]byte
- // Conn provides the underlying net.Conn in the case that a client
- // sent an initial handshake that didn't look like TLS.
- // It is nil if there's already been a handshake or a TLS alert has
- // been written to the connection.
- Conn net.Conn
-}
-
-func (e RecordHeaderError) Error() string { return "tls: " + e.Msg }
-
-func (c *Conn) newRecordHeaderError(conn net.Conn, msg string) (err RecordHeaderError) {
- err.Msg = msg
- err.Conn = conn
- copy(err.RecordHeader[:], c.rawInput.Bytes())
- return err
-}
-
-func (c *Conn) readRecord() error {
- return c.readRecordOrCCS(false)
-}
-
-func (c *Conn) readChangeCipherSpec() error {
- return c.readRecordOrCCS(true)
-}
-
-// readRecordOrCCS reads one or more TLS records from the connection and
-// updates the record layer state. Some invariants:
-// - c.in must be locked
-// - c.input must be empty
-//
-// During the handshake one and only one of the following will happen:
-// - c.hand grows
-// - c.in.changeCipherSpec is called
-// - an error is returned
-//
-// After the handshake one and only one of the following will happen:
-// - c.hand grows
-// - c.input is set
-// - an error is returned
-func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {
- if c.in.err != nil {
- return c.in.err
- }
- handshakeComplete := c.isHandshakeComplete.Load()
-
- // This function modifies c.rawInput, which owns the c.input memory.
- if c.input.Len() != 0 {
- return c.in.setErrorLocked(errors.New("tls: internal error: attempted to read record with pending application data"))
- }
- c.input.Reset(nil)
-
- // Read header, payload.
- if err := c.readFromUntil(c.conn, recordHeaderLen); err != nil {
- // RFC 8446, Section 6.1 suggests that EOF without an alertCloseNotify
- // is an error, but popular web sites seem to do this, so we accept it
- // if and only if at the record boundary.
- if err == io.ErrUnexpectedEOF && c.rawInput.Len() == 0 {
- err = io.EOF
- }
- if e, ok := err.(net.Error); !ok || !e.Temporary() {
- c.in.setErrorLocked(err)
- }
- return err
- }
- hdr := c.rawInput.Bytes()[:recordHeaderLen]
- typ := recordType(hdr[0])
-
- // No valid TLS record has a type of 0x80, however SSLv2 handshakes
- // start with a uint16 length where the MSB is set and the first record
- // is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
- // an SSLv2 client.
- if !handshakeComplete && typ == 0x80 {
- c.sendAlert(alertProtocolVersion)
- return c.in.setErrorLocked(c.newRecordHeaderError(nil, "unsupported SSLv2 handshake received"))
- }
-
- vers := uint16(hdr[1])<<8 | uint16(hdr[2])
- n := int(hdr[3])<<8 | int(hdr[4])
- if c.haveVers && c.vers != VersionTLS13 && vers != c.vers {
- c.sendAlert(alertProtocolVersion)
- msg := fmt.Sprintf("received record with version %x when expecting version %x", vers, c.vers)
- return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg))
- }
- if !c.haveVers {
- // First message, be extra suspicious: this might not be a TLS
- // client. Bail out before reading a full 'body', if possible.
- // The current max version is 3.3 so if the version is >= 16.0,
- // it's probably not real.
- if (typ != recordTypeAlert && typ != recordTypeHandshake) || vers >= 0x1000 {
- return c.in.setErrorLocked(c.newRecordHeaderError(c.conn, "first record does not look like a TLS handshake"))
- }
- }
- if c.vers == VersionTLS13 && n > maxCiphertextTLS13 || n > maxCiphertext {
- c.sendAlert(alertRecordOverflow)
- msg := fmt.Sprintf("oversized record received with length %d", n)
- return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg))
- }
- if err := c.readFromUntil(c.conn, recordHeaderLen+n); err != nil {
- if e, ok := err.(net.Error); !ok || !e.Temporary() {
- c.in.setErrorLocked(err)
- }
- return err
- }
-
- // Process message.
- record := c.rawInput.Next(recordHeaderLen + n)
- data, typ, err := c.in.decrypt(record)
- if err != nil {
- return c.in.setErrorLocked(c.sendAlert(err.(alert)))
- }
- if len(data) > maxPlaintext {
- return c.in.setErrorLocked(c.sendAlert(alertRecordOverflow))
- }
-
- // Application Data messages are always protected.
- if c.in.cipher == nil && typ == recordTypeApplicationData {
- return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
- }
-
- if typ != recordTypeAlert && typ != recordTypeChangeCipherSpec && len(data) > 0 {
- // This is a state-advancing message: reset the retry count.
- c.retryCount = 0
- }
-
- // Handshake messages MUST NOT be interleaved with other record types in TLS 1.3.
- if c.vers == VersionTLS13 && typ != recordTypeHandshake && c.hand.Len() > 0 {
- return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
- }
-
- switch typ {
- default:
- return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-
- case recordTypeAlert:
- if len(data) != 2 {
- return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
- }
- if alert(data[1]) == alertCloseNotify {
- return c.in.setErrorLocked(io.EOF)
- }
- if c.vers == VersionTLS13 {
- return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
- }
- switch data[0] {
- case alertLevelWarning:
- // Drop the record on the floor and retry.
- return c.retryReadRecord(expectChangeCipherSpec)
- case alertLevelError:
- return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
- default:
- return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
- }
-
- case recordTypeChangeCipherSpec:
- if len(data) != 1 || data[0] != 1 {
- return c.in.setErrorLocked(c.sendAlert(alertDecodeError))
- }
- // Handshake messages are not allowed to fragment across the CCS.
- if c.hand.Len() > 0 {
- return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
- }
- // In TLS 1.3, change_cipher_spec records are ignored until the
- // Finished. See RFC 8446, Appendix D.4. Note that according to Section
- // 5, a server can send a ChangeCipherSpec before its ServerHello, when
- // c.vers is still unset. That's not useful though and suspicious if the
- // server then selects a lower protocol version, so don't allow that.
- if c.vers == VersionTLS13 {
- return c.retryReadRecord(expectChangeCipherSpec)
- }
- if !expectChangeCipherSpec {
- return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
- }
- if err := c.in.changeCipherSpec(); err != nil {
- return c.in.setErrorLocked(c.sendAlert(err.(alert)))
- }
-
- case recordTypeApplicationData:
- if !handshakeComplete || expectChangeCipherSpec {
- return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
- }
- // Some OpenSSL servers send empty records in order to randomize the
- // CBC IV. Ignore a limited number of empty records.
- if len(data) == 0 {
- return c.retryReadRecord(expectChangeCipherSpec)
- }
- // Note that data is owned by c.rawInput, following the Next call above,
- // to avoid copying the plaintext. This is safe because c.rawInput is
- // not read from or written to until c.input is drained.
- c.input.Reset(data)
-
- case recordTypeHandshake:
- if len(data) == 0 || expectChangeCipherSpec {
- return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
- }
- c.hand.Write(data)
- }
-
- return nil
-}
-
-// retryReadRecord recurs into readRecordOrCCS to drop a non-advancing record, like
-// a warning alert, empty application_data, or a change_cipher_spec in TLS 1.3.
-func (c *Conn) retryReadRecord(expectChangeCipherSpec bool) error {
- c.retryCount++
- if c.retryCount > maxUselessRecords {
- c.sendAlert(alertUnexpectedMessage)
- return c.in.setErrorLocked(errors.New("tls: too many ignored records"))
- }
- return c.readRecordOrCCS(expectChangeCipherSpec)
-}
-
-// atLeastReader reads from R, stopping with EOF once at least N bytes have been
-// read. It is different from an io.LimitedReader in that it doesn't cut short
-// the last Read call, and in that it considers an early EOF an error.
-type atLeastReader struct {
- R io.Reader
- N int64
-}
-
-func (r *atLeastReader) Read(p []byte) (int, error) {
- if r.N <= 0 {
- return 0, io.EOF
- }
- n, err := r.R.Read(p)
- r.N -= int64(n) // won't underflow unless len(p) >= n > 9223372036854775809
- if r.N > 0 && err == io.EOF {
- return n, io.ErrUnexpectedEOF
- }
- if r.N <= 0 && err == nil {
- return n, io.EOF
- }
- return n, err
-}
-
-// readFromUntil reads from r into c.rawInput until c.rawInput contains
-// at least n bytes or else returns an error.
-func (c *Conn) readFromUntil(r io.Reader, n int) error {
- if c.rawInput.Len() >= n {
- return nil
- }
- needs := n - c.rawInput.Len()
- // There might be extra input waiting on the wire. Make a best effort
- // attempt to fetch it so that it can be used in (*Conn).Read to
- // "predict" closeNotify alerts.
- c.rawInput.Grow(needs + bytes.MinRead)
- _, err := c.rawInput.ReadFrom(&atLeastReader{r, int64(needs)})
- return err
-}
-
-// sendAlert sends a TLS alert message.
-func (c *Conn) sendAlertLocked(err alert) error {
- switch err {
- case alertNoRenegotiation, alertCloseNotify:
- c.tmp[0] = alertLevelWarning
- default:
- c.tmp[0] = alertLevelError
- }
- c.tmp[1] = byte(err)
-
- _, writeErr := c.writeRecordLocked(recordTypeAlert, c.tmp[0:2])
- if err == alertCloseNotify {
- // closeNotify is a special case in that it isn't an error.
- return writeErr
- }
-
- return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
-}
-
-// sendAlert sends a TLS alert message.
-func (c *Conn) sendAlert(err alert) error {
- c.out.Lock()
- defer c.out.Unlock()
- return c.sendAlertLocked(err)
-}
-
-const (
- // tcpMSSEstimate is a conservative estimate of the TCP maximum segment
- // size (MSS). A constant is used, rather than querying the kernel for
- // the actual MSS, to avoid complexity. The value here is the IPv6
- // minimum MTU (1280 bytes) minus the overhead of an IPv6 header (40
- // bytes) and a TCP header with timestamps (32 bytes).
- tcpMSSEstimate = 1208
-
- // recordSizeBoostThreshold is the number of bytes of application data
- // sent after which the TLS record size will be increased to the
- // maximum.
- recordSizeBoostThreshold = 128 * 1024
-)
-
-// maxPayloadSizeForWrite returns the maximum TLS payload size to use for the
-// next application data record. There is the following trade-off:
-//
-// - For latency-sensitive applications, such as web browsing, each TLS
-// record should fit in one TCP segment.
-// - For throughput-sensitive applications, such as large file transfers,
-// larger TLS records better amortize framing and encryption overheads.
-//
-// A simple heuristic that works well in practice is to use small records for
-// the first 1MB of data, then use larger records for subsequent data, and
-// reset back to smaller records after the connection becomes idle. See "High
-// Performance Web Networking", Chapter 4, or:
-// https://www.igvita.com/2013/10/24/optimizing-tls-record-size-and-buffering-latency/
-//
-// In the interests of simplicity and determinism, this code does not attempt
-// to reset the record size once the connection is idle, however.
-func (c *Conn) maxPayloadSizeForWrite(typ recordType) int {
- if c.config.DynamicRecordSizingDisabled || typ != recordTypeApplicationData {
- return maxPlaintext
- }
-
- if c.bytesSent >= recordSizeBoostThreshold {
- return maxPlaintext
- }
-
- // Subtract TLS overheads to get the maximum payload size.
- payloadBytes := tcpMSSEstimate - recordHeaderLen - c.out.explicitNonceLen()
- if c.out.cipher != nil {
- switch ciph := c.out.cipher.(type) {
- case cipher.Stream:
- payloadBytes -= c.out.mac.Size()
- case cipher.AEAD:
- payloadBytes -= ciph.Overhead()
- case cbcMode:
- blockSize := ciph.BlockSize()
- // The payload must fit in a multiple of blockSize, with
- // room for at least one padding byte.
- payloadBytes = (payloadBytes & ^(blockSize - 1)) - 1
- // The MAC is appended before padding so affects the
- // payload size directly.
- payloadBytes -= c.out.mac.Size()
- default:
- panic("unknown cipher type")
- }
- }
- if c.vers == VersionTLS13 {
- payloadBytes-- // encrypted ContentType
- }
-
- // Allow packet growth in arithmetic progression up to max.
- pkt := c.packetsSent
- c.packetsSent++
- if pkt > 1000 {
- return maxPlaintext // avoid overflow in multiply below
- }
-
- n := payloadBytes * int(pkt+1)
- if n > maxPlaintext {
- n = maxPlaintext
- }
- return n
-}
-
-func (c *Conn) write(data []byte) (int, error) {
- if c.buffering {
- c.sendBuf = append(c.sendBuf, data...)
- return len(data), nil
- }
-
- n, err := c.conn.Write(data)
- c.bytesSent += int64(n)
- return n, err
-}
-
-func (c *Conn) flush() (int, error) {
- if len(c.sendBuf) == 0 {
- return 0, nil
- }
-
- n, err := c.conn.Write(c.sendBuf)
- c.bytesSent += int64(n)
- c.sendBuf = nil
- c.buffering = false
- return n, err
-}
-
-// outBufPool pools the record-sized scratch buffers used by writeRecordLocked.
-var outBufPool = sync.Pool{
- New: func() any {
- return new([]byte)
- },
-}
-
-// writeRecordLocked writes a TLS record with the given type and payload to the
-// connection and updates the record layer state.
-func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {
- outBufPtr := outBufPool.Get().(*[]byte)
- outBuf := *outBufPtr
- defer func() {
- // You might be tempted to simplify this by just passing &outBuf to Put,
- // but that would make the local copy of the outBuf slice header escape
- // to the heap, causing an allocation. Instead, we keep around the
- // pointer to the slice header returned by Get, which is already on the
- // heap, and overwrite and return that.
- *outBufPtr = outBuf
- outBufPool.Put(outBufPtr)
- }()
-
- var n int
- for len(data) > 0 {
- m := len(data)
- if maxPayload := c.maxPayloadSizeForWrite(typ); m > maxPayload {
- m = maxPayload
- }
-
- _, outBuf = sliceForAppend(outBuf[:0], recordHeaderLen)
- outBuf[0] = byte(typ)
- vers := c.vers
- if vers == 0 {
- // Some TLS servers fail if the record version is
- // greater than TLS 1.0 for the initial ClientHello.
- vers = VersionTLS10
- } else if vers == VersionTLS13 {
- // TLS 1.3 froze the record layer version to 1.2.
- // See RFC 8446, Section 5.1.
- vers = VersionTLS12
- }
- outBuf[1] = byte(vers >> 8)
- outBuf[2] = byte(vers)
- outBuf[3] = byte(m >> 8)
- outBuf[4] = byte(m)
-
- var err error
- outBuf, err = c.out.encrypt(outBuf, data[:m], c.config.rand())
- if err != nil {
- return n, err
- }
- if _, err := c.write(outBuf); err != nil {
- return n, err
- }
- n += m
- data = data[m:]
- }
-
- if typ == recordTypeChangeCipherSpec && c.vers != VersionTLS13 {
- if err := c.out.changeCipherSpec(); err != nil {
- return n, c.sendAlertLocked(err.(alert))
- }
- }
-
- return n, nil
-}
-
-// writeHandshakeRecord writes a handshake message to the connection and updates
-// the record layer state. If transcript is non-nil the marshalled message is
-// written to it.
-func (c *Conn) writeHandshakeRecord(msg handshakeMessage, transcript transcriptHash) (int, error) {
- c.out.Lock()
- defer c.out.Unlock()
-
- data, err := msg.marshal()
- if err != nil {
- return 0, err
- }
- if transcript != nil {
- transcript.Write(data)
- }
-
- return c.writeRecordLocked(recordTypeHandshake, data)
-}
-
-// writeChangeCipherRecord writes a ChangeCipherSpec message to the connection and
-// updates the record layer state.
-func (c *Conn) writeChangeCipherRecord() error {
- c.out.Lock()
- defer c.out.Unlock()
- _, err := c.writeRecordLocked(recordTypeChangeCipherSpec, []byte{1})
- return err
-}
-
-// readHandshake reads the next handshake message from
-// the record layer. If transcript is non-nil, the message
-// is written to the passed transcriptHash.
-func (c *Conn) readHandshake(transcript transcriptHash) (any, error) {
- for c.hand.Len() < 4 {
- if err := c.readRecord(); err != nil {
- return nil, err
- }
- }
-
- data := c.hand.Bytes()
- n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
- if n > maxHandshake {
- c.sendAlertLocked(alertInternalError)
- return nil, c.in.setErrorLocked(fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake))
- }
- for c.hand.Len() < 4+n {
- if err := c.readRecord(); err != nil {
- return nil, err
- }
- }
- data = c.hand.Next(4 + n)
- var m handshakeMessage
- switch data[0] {
- case typeHelloRequest:
- m = new(helloRequestMsg)
- case typeClientHello:
- m = new(clientHelloMsg)
- case typeServerHello:
- m = new(serverHelloMsg)
- case typeNewSessionTicket:
- if c.vers == VersionTLS13 {
- m = new(newSessionTicketMsgTLS13)
- } else {
- m = new(newSessionTicketMsg)
- }
- case typeCertificate:
- if c.vers == VersionTLS13 {
- m = new(certificateMsgTLS13)
- } else {
- m = new(certificateMsg)
- }
- case typeCertificateRequest:
- if c.vers == VersionTLS13 {
- m = new(certificateRequestMsgTLS13)
- } else {
- m = &certificateRequestMsg{
- hasSignatureAlgorithm: c.vers >= VersionTLS12,
- }
- }
- case typeCertificateStatus:
- m = new(certificateStatusMsg)
- case typeServerKeyExchange:
- m = new(serverKeyExchangeMsg)
- case typeServerHelloDone:
- m = new(serverHelloDoneMsg)
- case typeClientKeyExchange:
- m = new(clientKeyExchangeMsg)
- case typeCertificateVerify:
- m = &certificateVerifyMsg{
- hasSignatureAlgorithm: c.vers >= VersionTLS12,
- }
- case typeFinished:
- m = new(finishedMsg)
- case typeEncryptedExtensions:
- m = new(encryptedExtensionsMsg)
- case typeEndOfEarlyData:
- m = new(endOfEarlyDataMsg)
- case typeKeyUpdate:
- m = new(keyUpdateMsg)
- default:
- return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
- }
-
- // The handshake message unmarshalers
- // expect to be able to keep references to data,
- // so pass in a fresh copy that won't be overwritten.
- data = append([]byte(nil), data...)
-
- if !m.unmarshal(data) {
- return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
- }
-
- if transcript != nil {
- transcript.Write(data)
- }
-
- return m, nil
-}
-
-var (
- errShutdown = errors.New("tls: protocol is shutdown")
-)
-
-// Write writes data to the connection.
-//
-// As Write calls Handshake, in order to prevent indefinite blocking a deadline
-// must be set for both Read and Write before Write is called when the handshake
-// has not yet completed. See SetDeadline, SetReadDeadline, and
-// SetWriteDeadline.
-func (c *Conn) Write(b []byte) (int, error) {
- // interlock with Close below
- for {
- x := c.activeCall.Load()
- if x&1 != 0 {
- return 0, net.ErrClosed
- }
- if c.activeCall.CompareAndSwap(x, x+2) {
- break
- }
- }
- defer c.activeCall.Add(-2)
-
- if err := c.Handshake(); err != nil {
- return 0, err
- }
-
- c.out.Lock()
- defer c.out.Unlock()
-
- if err := c.out.err; err != nil {
- return 0, err
- }
-
- if !c.isHandshakeComplete.Load() {
- return 0, alertInternalError
- }
-
- if c.closeNotifySent {
- return 0, errShutdown
- }
-
- // TLS 1.0 is susceptible to a chosen-plaintext
- // attack when using block mode ciphers due to predictable IVs.
- // This can be prevented by splitting each Application Data
- // record into two records, effectively randomizing the IV.
- //
- // https://www.openssl.org/~bodo/tls-cbc.txt
- // https://bugzilla.mozilla.org/show_bug.cgi?id=665814
- // https://www.imperialviolet.org/2012/01/15/beastfollowup.html
-
- var m int
- if len(b) > 1 && c.vers == VersionTLS10 {
- if _, ok := c.out.cipher.(cipher.BlockMode); ok {
- n, err := c.writeRecordLocked(recordTypeApplicationData, b[:1])
- if err != nil {
- return n, c.out.setErrorLocked(err)
- }
- m, b = 1, b[1:]
- }
- }
-
- n, err := c.writeRecordLocked(recordTypeApplicationData, b)
- return n + m, c.out.setErrorLocked(err)
-}
-
-// handleRenegotiation processes a HelloRequest handshake message.
-func (c *Conn) handleRenegotiation() error {
- if c.vers == VersionTLS13 {
- return errors.New("tls: internal error: unexpected renegotiation")
- }
-
- msg, err := c.readHandshake(nil)
- if err != nil {
- return err
- }
-
- helloReq, ok := msg.(*helloRequestMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(helloReq, msg)
- }
-
- if !c.isClient {
- return c.sendAlert(alertNoRenegotiation)
- }
-
- switch c.config.Renegotiation {
- case RenegotiateNever:
- return c.sendAlert(alertNoRenegotiation)
- case RenegotiateOnceAsClient:
- if c.handshakes > 1 {
- return c.sendAlert(alertNoRenegotiation)
- }
- case RenegotiateFreelyAsClient:
- // Ok.
- default:
- c.sendAlert(alertInternalError)
- return errors.New("tls: unknown Renegotiation value")
- }
-
- c.handshakeMutex.Lock()
- defer c.handshakeMutex.Unlock()
-
- c.isHandshakeComplete.Store(false)
- if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil {
- c.handshakes++
- }
- return c.handshakeErr
-}
-
-// handlePostHandshakeMessage processes a handshake message arrived after the
-// handshake is complete. Up to TLS 1.2, it indicates the start of a renegotiation.
-func (c *Conn) handlePostHandshakeMessage() error {
- if c.vers != VersionTLS13 {
- return c.handleRenegotiation()
- }
-
- msg, err := c.readHandshake(nil)
- if err != nil {
- return err
- }
-
- c.retryCount++
- if c.retryCount > maxUselessRecords {
- c.sendAlert(alertUnexpectedMessage)
- return c.in.setErrorLocked(errors.New("tls: too many non-advancing records"))
- }
-
- switch msg := msg.(type) {
- case *newSessionTicketMsgTLS13:
- return c.handleNewSessionTicket(msg)
- case *keyUpdateMsg:
- return c.handleKeyUpdate(msg)
- default:
- c.sendAlert(alertUnexpectedMessage)
- return fmt.Errorf("tls: received unexpected handshake message of type %T", msg)
- }
-}
-
-func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
- cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
- if cipherSuite == nil {
- return c.in.setErrorLocked(c.sendAlert(alertInternalError))
- }
-
- newSecret := cipherSuite.nextTrafficSecret(c.in.trafficSecret)
- c.in.setTrafficSecret(cipherSuite, newSecret)
-
- if keyUpdate.updateRequested {
- c.out.Lock()
- defer c.out.Unlock()
-
- msg := &keyUpdateMsg{}
- msgBytes, err := msg.marshal()
- if err != nil {
- return err
- }
- _, err = c.writeRecordLocked(recordTypeHandshake, msgBytes)
- if err != nil {
- // Surface the error at the next write.
- c.out.setErrorLocked(err)
- return nil
- }
-
- newSecret := cipherSuite.nextTrafficSecret(c.out.trafficSecret)
- c.out.setTrafficSecret(cipherSuite, newSecret)
- }
-
- return nil
-}
-
-// Read reads data from the connection.
-//
-// As Read calls Handshake, in order to prevent indefinite blocking a deadline
-// must be set for both Read and Write before Read is called when the handshake
-// has not yet completed. See SetDeadline, SetReadDeadline, and
-// SetWriteDeadline.
-func (c *Conn) Read(b []byte) (int, error) {
- if err := c.Handshake(); err != nil {
- return 0, err
- }
- if len(b) == 0 {
- // Put this after Handshake, in case people were calling
- // Read(nil) for the side effect of the Handshake.
- return 0, nil
- }
-
- c.in.Lock()
- defer c.in.Unlock()
-
- for c.input.Len() == 0 {
- if err := c.readRecord(); err != nil {
- return 0, err
- }
- for c.hand.Len() > 0 {
- if err := c.handlePostHandshakeMessage(); err != nil {
- return 0, err
- }
- }
- }
-
- n, _ := c.input.Read(b)
-
- // If a close-notify alert is waiting, read it so that we can return (n,
- // EOF) instead of (n, nil), to signal to the HTTP response reading
- // goroutine that the connection is now closed. This eliminates a race
- // where the HTTP response reading goroutine would otherwise not observe
- // the EOF until its next read, by which time a client goroutine might
- // have already tried to reuse the HTTP connection for a new request.
- // See https://golang.org/cl/76400046 and https://golang.org/issue/3514
- if n != 0 && c.input.Len() == 0 && c.rawInput.Len() > 0 &&
- recordType(c.rawInput.Bytes()[0]) == recordTypeAlert {
- if err := c.readRecord(); err != nil {
- return n, err // will be io.EOF on closeNotify
- }
- }
-
- return n, nil
-}
-
-// Close closes the connection.
-func (c *Conn) Close() error {
- // Interlock with Conn.Write above.
- var x int32
- for {
- x = c.activeCall.Load()
- if x&1 != 0 {
- return net.ErrClosed
- }
- if c.activeCall.CompareAndSwap(x, x|1) {
- break
- }
- }
- if x != 0 {
- // io.Writer and io.Closer should not be used concurrently.
- // If Close is called while a Write is currently in-flight,
- // interpret that as a sign that this Close is really just
- // being used to break the Write and/or clean up resources and
- // avoid sending the alertCloseNotify, which may block
- // waiting on handshakeMutex or the c.out mutex.
- return c.conn.Close()
- }
-
- var alertErr error
- if c.isHandshakeComplete.Load() {
- if err := c.closeNotify(); err != nil {
- alertErr = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", err)
- }
- }
-
- if err := c.conn.Close(); err != nil {
- return err
- }
- return alertErr
-}
-
-var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake complete")
-
-// CloseWrite shuts down the writing side of the connection. It should only be
-// called once the handshake has completed and does not call CloseWrite on the
-// underlying connection. Most callers should just use Close.
-func (c *Conn) CloseWrite() error {
- if !c.isHandshakeComplete.Load() {
- return errEarlyCloseWrite
- }
-
- return c.closeNotify()
-}
-
-func (c *Conn) closeNotify() error {
- c.out.Lock()
- defer c.out.Unlock()
-
- if !c.closeNotifySent {
- // Set a Write Deadline to prevent possibly blocking forever.
- c.SetWriteDeadline(time.Now().Add(time.Second * 5))
- c.closeNotifyErr = c.sendAlertLocked(alertCloseNotify)
- c.closeNotifySent = true
- // Any subsequent writes will fail.
- c.SetWriteDeadline(time.Now())
- }
- return c.closeNotifyErr
-}
-
-// Handshake runs the client or server handshake
-// protocol if it has not yet been run.
-//
-// Most uses of this package need not call Handshake explicitly: the
-// first Read or Write will call it automatically.
-//
-// For control over canceling or setting a timeout on a handshake, use
-// HandshakeContext or the Dialer's DialContext method instead.
-func (c *Conn) Handshake() error {
- return c.HandshakeContext(context.Background())
-}
-
-// HandshakeContext runs the client or server handshake
-// protocol if it has not yet been run.
-//
-// The provided Context must be non-nil. If the context is canceled before
-// the handshake is complete, the handshake is interrupted and an error is returned.
-// Once the handshake has completed, cancellation of the context will not affect the
-// connection.
-//
-// Most uses of this package need not call HandshakeContext explicitly: the
-// first Read or Write will call it automatically.
-func (c *Conn) HandshakeContext(ctx context.Context) error {
- // Delegate to unexported method for named return
- // without confusing documented signature.
- return c.handshakeContext(ctx)
-}
-
-func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
- // Fast sync/atomic-based exit if there is no handshake in flight and the
- // last one succeeded without an error. Avoids the expensive context setup
- // and mutex for most Read and Write calls.
- if c.isHandshakeComplete.Load() {
- return nil
- }
-
- handshakeCtx, cancel := context.WithCancel(ctx)
- // Note: defer this before starting the "interrupter" goroutine
- // so that we can tell the difference between the input being canceled and
- // this cancellation. In the former case, we need to close the connection.
- defer cancel()
-
- // Start the "interrupter" goroutine, if this context might be canceled.
- // (The background context cannot).
- //
- // The interrupter goroutine waits for the input context to be done and
- // closes the connection if this happens before the function returns.
- if ctx.Done() != nil {
- done := make(chan struct{})
- interruptRes := make(chan error, 1)
- defer func() {
- close(done)
- if ctxErr := <-interruptRes; ctxErr != nil {
- // Return context error to user.
- ret = ctxErr
- }
- }()
- go func() {
- select {
- case <-handshakeCtx.Done():
- // Close the connection, discarding the error
- _ = c.conn.Close()
- interruptRes <- handshakeCtx.Err()
- case <-done:
- interruptRes <- nil
- }
- }()
- }
-
- c.handshakeMutex.Lock()
- defer c.handshakeMutex.Unlock()
-
- if err := c.handshakeErr; err != nil {
- return err
- }
- if c.isHandshakeComplete.Load() {
- return nil
- }
-
- c.in.Lock()
- defer c.in.Unlock()
-
- c.handshakeErr = c.handshakeFn(handshakeCtx)
- if c.handshakeErr == nil {
- c.handshakes++
- } else {
- // If an error occurred during the handshake try to flush the
- // alert that might be left in the buffer.
- c.flush()
- }
-
- if c.handshakeErr == nil && !c.isHandshakeComplete.Load() {
- c.handshakeErr = errors.New("tls: internal error: handshake should have had a result")
- }
- if c.handshakeErr != nil && c.isHandshakeComplete.Load() {
- panic("tls: internal error: handshake returned an error but is marked successful")
- }
-
- return c.handshakeErr
-}
-
-// ConnectionState returns basic TLS details about the connection.
-func (c *Conn) ConnectionState() ConnectionState {
- c.handshakeMutex.Lock()
- defer c.handshakeMutex.Unlock()
- return c.connectionStateLocked()
-}
-
-func (c *Conn) connectionStateLocked() ConnectionState {
- var state ConnectionState
- state.HandshakeComplete = c.isHandshakeComplete.Load()
- state.Version = c.vers
- state.NegotiatedProtocol = c.clientProtocol
- state.DidResume = c.didResume
- state.NegotiatedProtocolIsMutual = true
- state.ServerName = c.serverName
- state.CipherSuite = c.cipherSuite
- state.PeerCertificates = c.peerCertificates
- state.VerifiedChains = c.verifiedChains
- state.SignedCertificateTimestamps = c.scts
- state.OCSPResponse = c.ocspResponse
- if !c.didResume && c.vers != VersionTLS13 {
- if c.clientFinishedIsFirst {
- state.TLSUnique = c.clientFinished[:]
- } else {
- state.TLSUnique = c.serverFinished[:]
- }
- }
- if c.config.Renegotiation != RenegotiateNever {
- state.ekm = noExportedKeyingMaterial
- } else {
- state.ekm = c.ekm
- }
- return state
-}
-
-// OCSPResponse returns the stapled OCSP response from the TLS server, if
-// any. (Only valid for client connections.)
-func (c *Conn) OCSPResponse() []byte {
- c.handshakeMutex.Lock()
- defer c.handshakeMutex.Unlock()
-
- return c.ocspResponse
-}
-
-// VerifyHostname checks that the peer certificate chain is valid for
-// connecting to host. If so, it returns nil; if not, it returns an error
-// describing the problem.
-func (c *Conn) VerifyHostname(host string) error {
- c.handshakeMutex.Lock()
- defer c.handshakeMutex.Unlock()
- if !c.isClient {
- return errors.New("tls: VerifyHostname called on TLS server connection")
- }
- if !c.isHandshakeComplete.Load() {
- return errors.New("tls: handshake has not yet been performed")
- }
- if len(c.verifiedChains) == 0 {
- return errors.New("tls: handshake did not verify certificate chain")
- }
- return c.peerCertificates[0].VerifyHostname(host)
-}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/handshake_client.go b/contrib/go/_std_1.20/src/crypto/tls/handshake_client.go
deleted file mode 100644
index 63d86b9f3a..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/handshake_client.go
+++ /dev/null
@@ -1,1031 +0,0 @@
-// Copyright 2009 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 tls
-
-import (
- "bytes"
- "context"
- "crypto"
- "crypto/ecdh"
- "crypto/ecdsa"
- "crypto/ed25519"
- "crypto/rsa"
- "crypto/subtle"
- "crypto/x509"
- "errors"
- "fmt"
- "hash"
- "io"
- "net"
- "strings"
- "time"
-)
-
-type clientHandshakeState struct {
- c *Conn
- ctx context.Context
- serverHello *serverHelloMsg
- hello *clientHelloMsg
- suite *cipherSuite
- finishedHash finishedHash
- masterSecret []byte
- session *ClientSessionState
-}
-
-var testingOnlyForceClientHelloSignatureAlgorithms []SignatureScheme
-
-func (c *Conn) makeClientHello() (*clientHelloMsg, *ecdh.PrivateKey, error) {
- config := c.config
- if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
- return nil, nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
- }
-
- nextProtosLength := 0
- for _, proto := range config.NextProtos {
- if l := len(proto); l == 0 || l > 255 {
- return nil, nil, errors.New("tls: invalid NextProtos value")
- } else {
- nextProtosLength += 1 + l
- }
- }
- if nextProtosLength > 0xffff {
- return nil, nil, errors.New("tls: NextProtos values too large")
- }
-
- supportedVersions := config.supportedVersions(roleClient)
- if len(supportedVersions) == 0 {
- return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
- }
-
- clientHelloVersion := config.maxSupportedVersion(roleClient)
- // The version at the beginning of the ClientHello was capped at TLS 1.2
- // for compatibility reasons. The supported_versions extension is used
- // to negotiate versions now. See RFC 8446, Section 4.2.1.
- if clientHelloVersion > VersionTLS12 {
- clientHelloVersion = VersionTLS12
- }
-
- hello := &clientHelloMsg{
- vers: clientHelloVersion,
- compressionMethods: []uint8{compressionNone},
- random: make([]byte, 32),
- sessionId: make([]byte, 32),
- ocspStapling: true,
- scts: true,
- serverName: hostnameInSNI(config.ServerName),
- supportedCurves: config.curvePreferences(),
- supportedPoints: []uint8{pointFormatUncompressed},
- secureRenegotiationSupported: true,
- alpnProtocols: config.NextProtos,
- supportedVersions: supportedVersions,
- }
-
- if c.handshakes > 0 {
- hello.secureRenegotiation = c.clientFinished[:]
- }
-
- preferenceOrder := cipherSuitesPreferenceOrder
- if !hasAESGCMHardwareSupport {
- preferenceOrder = cipherSuitesPreferenceOrderNoAES
- }
- configCipherSuites := config.cipherSuites()
- hello.cipherSuites = make([]uint16, 0, len(configCipherSuites))
-
- for _, suiteId := range preferenceOrder {
- suite := mutualCipherSuite(configCipherSuites, suiteId)
- if suite == nil {
- continue
- }
- // Don't advertise TLS 1.2-only cipher suites unless
- // we're attempting TLS 1.2.
- if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
- continue
- }
- hello.cipherSuites = append(hello.cipherSuites, suiteId)
- }
-
- _, err := io.ReadFull(config.rand(), hello.random)
- if err != nil {
- return nil, nil, errors.New("tls: short read from Rand: " + err.Error())
- }
-
- // A random session ID is used to detect when the server accepted a ticket
- // and is resuming a session (see RFC 5077). In TLS 1.3, it's always set as
- // a compatibility measure (see RFC 8446, Section 4.1.2).
- if _, err := io.ReadFull(config.rand(), hello.sessionId); err != nil {
- return nil, nil, errors.New("tls: short read from Rand: " + err.Error())
- }
-
- if hello.vers >= VersionTLS12 {
- hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
- }
- if testingOnlyForceClientHelloSignatureAlgorithms != nil {
- hello.supportedSignatureAlgorithms = testingOnlyForceClientHelloSignatureAlgorithms
- }
-
- var key *ecdh.PrivateKey
- if hello.supportedVersions[0] == VersionTLS13 {
- if hasAESGCMHardwareSupport {
- hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
- } else {
- hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...)
- }
-
- curveID := config.curvePreferences()[0]
- if _, ok := curveForCurveID(curveID); !ok {
- return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve")
- }
- key, err = generateECDHEKey(config.rand(), curveID)
- if err != nil {
- return nil, nil, err
- }
- hello.keyShares = []keyShare{{group: curveID, data: key.PublicKey().Bytes()}}
- }
-
- return hello, key, nil
-}
-
-func (c *Conn) clientHandshake(ctx context.Context) (err error) {
- if c.config == nil {
- c.config = defaultConfig()
- }
-
- // This may be a renegotiation handshake, in which case some fields
- // need to be reset.
- c.didResume = false
-
- hello, ecdheKey, err := c.makeClientHello()
- if err != nil {
- return err
- }
- c.serverName = hello.serverName
-
- cacheKey, session, earlySecret, binderKey, err := c.loadSession(hello)
- if err != nil {
- return err
- }
- if cacheKey != "" && session != nil {
- defer func() {
- // If we got a handshake failure when resuming a session, throw away
- // the session ticket. See RFC 5077, Section 3.2.
- //
- // RFC 8446 makes no mention of dropping tickets on failure, but it
- // does require servers to abort on invalid binders, so we need to
- // delete tickets to recover from a corrupted PSK.
- if err != nil {
- c.config.ClientSessionCache.Put(cacheKey, nil)
- }
- }()
- }
-
- if _, err := c.writeHandshakeRecord(hello, nil); err != nil {
- return err
- }
-
- // serverHelloMsg is not included in the transcript
- msg, err := c.readHandshake(nil)
- if err != nil {
- return err
- }
-
- serverHello, ok := msg.(*serverHelloMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(serverHello, msg)
- }
-
- if err := c.pickTLSVersion(serverHello); err != nil {
- return err
- }
-
- // If we are negotiating a protocol version that's lower than what we
- // support, check for the server downgrade canaries.
- // See RFC 8446, Section 4.1.3.
- maxVers := c.config.maxSupportedVersion(roleClient)
- tls12Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS12
- tls11Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS11
- if maxVers == VersionTLS13 && c.vers <= VersionTLS12 && (tls12Downgrade || tls11Downgrade) ||
- maxVers == VersionTLS12 && c.vers <= VersionTLS11 && tls11Downgrade {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: downgrade attempt detected, possibly due to a MitM attack or a broken middlebox")
- }
-
- if c.vers == VersionTLS13 {
- hs := &clientHandshakeStateTLS13{
- c: c,
- ctx: ctx,
- serverHello: serverHello,
- hello: hello,
- ecdheKey: ecdheKey,
- session: session,
- earlySecret: earlySecret,
- binderKey: binderKey,
- }
-
- // In TLS 1.3, session tickets are delivered after the handshake.
- return hs.handshake()
- }
-
- hs := &clientHandshakeState{
- c: c,
- ctx: ctx,
- serverHello: serverHello,
- hello: hello,
- session: session,
- }
-
- if err := hs.handshake(); err != nil {
- return err
- }
-
- // If we had a successful handshake and hs.session is different from
- // the one already cached - cache a new one.
- if cacheKey != "" && hs.session != nil && session != hs.session {
- c.config.ClientSessionCache.Put(cacheKey, hs.session)
- }
-
- return nil
-}
-
-func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
- session *ClientSessionState, earlySecret, binderKey []byte, err error) {
- if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil {
- return "", nil, nil, nil, nil
- }
-
- hello.ticketSupported = true
-
- if hello.supportedVersions[0] == VersionTLS13 {
- // Require DHE on resumption as it guarantees forward secrecy against
- // compromise of the session ticket key. See RFC 8446, Section 4.2.9.
- hello.pskModes = []uint8{pskModeDHE}
- }
-
- // Session resumption is not allowed if renegotiating because
- // renegotiation is primarily used to allow a client to send a client
- // certificate, which would be skipped if session resumption occurred.
- if c.handshakes != 0 {
- return "", nil, nil, nil, nil
- }
-
- // Try to resume a previously negotiated TLS session, if available.
- cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
- session, ok := c.config.ClientSessionCache.Get(cacheKey)
- if !ok || session == nil {
- return cacheKey, nil, nil, nil, nil
- }
-
- // Check that version used for the previous session is still valid.
- versOk := false
- for _, v := range hello.supportedVersions {
- if v == session.vers {
- versOk = true
- break
- }
- }
- if !versOk {
- return cacheKey, nil, nil, nil, nil
- }
-
- // Check that the cached server certificate is not expired, and that it's
- // valid for the ServerName. This should be ensured by the cache key, but
- // protect the application from a faulty ClientSessionCache implementation.
- if !c.config.InsecureSkipVerify {
- if len(session.verifiedChains) == 0 {
- // The original connection had InsecureSkipVerify, while this doesn't.
- return cacheKey, nil, nil, nil, nil
- }
- serverCert := session.serverCertificates[0]
- if c.config.time().After(serverCert.NotAfter) {
- // Expired certificate, delete the entry.
- c.config.ClientSessionCache.Put(cacheKey, nil)
- return cacheKey, nil, nil, nil, nil
- }
- if err := serverCert.VerifyHostname(c.config.ServerName); err != nil {
- return cacheKey, nil, nil, nil, nil
- }
- }
-
- if session.vers != VersionTLS13 {
- // In TLS 1.2 the cipher suite must match the resumed session. Ensure we
- // are still offering it.
- if mutualCipherSuite(hello.cipherSuites, session.cipherSuite) == nil {
- return cacheKey, nil, nil, nil, nil
- }
-
- hello.sessionTicket = session.sessionTicket
- return
- }
-
- // Check that the session ticket is not expired.
- if c.config.time().After(session.useBy) {
- c.config.ClientSessionCache.Put(cacheKey, nil)
- return cacheKey, nil, nil, nil, nil
- }
-
- // In TLS 1.3 the KDF hash must match the resumed session. Ensure we
- // offer at least one cipher suite with that hash.
- cipherSuite := cipherSuiteTLS13ByID(session.cipherSuite)
- if cipherSuite == nil {
- return cacheKey, nil, nil, nil, nil
- }
- cipherSuiteOk := false
- for _, offeredID := range hello.cipherSuites {
- offeredSuite := cipherSuiteTLS13ByID(offeredID)
- if offeredSuite != nil && offeredSuite.hash == cipherSuite.hash {
- cipherSuiteOk = true
- break
- }
- }
- if !cipherSuiteOk {
- return cacheKey, nil, nil, nil, nil
- }
-
- // Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1.
- ticketAge := uint32(c.config.time().Sub(session.receivedAt) / time.Millisecond)
- identity := pskIdentity{
- label: session.sessionTicket,
- obfuscatedTicketAge: ticketAge + session.ageAdd,
- }
- hello.pskIdentities = []pskIdentity{identity}
- hello.pskBinders = [][]byte{make([]byte, cipherSuite.hash.Size())}
-
- // Compute the PSK binders. See RFC 8446, Section 4.2.11.2.
- psk := cipherSuite.expandLabel(session.masterSecret, "resumption",
- session.nonce, cipherSuite.hash.Size())
- earlySecret = cipherSuite.extract(psk, nil)
- binderKey = cipherSuite.deriveSecret(earlySecret, resumptionBinderLabel, nil)
- transcript := cipherSuite.hash.New()
- helloBytes, err := hello.marshalWithoutBinders()
- if err != nil {
- return "", nil, nil, nil, err
- }
- transcript.Write(helloBytes)
- pskBinders := [][]byte{cipherSuite.finishedHash(binderKey, transcript)}
- if err := hello.updateBinders(pskBinders); err != nil {
- return "", nil, nil, nil, err
- }
-
- return
-}
-
-func (c *Conn) pickTLSVersion(serverHello *serverHelloMsg) error {
- peerVersion := serverHello.vers
- if serverHello.supportedVersion != 0 {
- peerVersion = serverHello.supportedVersion
- }
-
- vers, ok := c.config.mutualVersion(roleClient, []uint16{peerVersion})
- if !ok {
- c.sendAlert(alertProtocolVersion)
- return fmt.Errorf("tls: server selected unsupported protocol version %x", peerVersion)
- }
-
- c.vers = vers
- c.haveVers = true
- c.in.version = vers
- c.out.version = vers
-
- return nil
-}
-
-// Does the handshake, either a full one or resumes old session. Requires hs.c,
-// hs.hello, hs.serverHello, and, optionally, hs.session to be set.
-func (hs *clientHandshakeState) handshake() error {
- c := hs.c
-
- isResume, err := hs.processServerHello()
- if err != nil {
- return err
- }
-
- hs.finishedHash = newFinishedHash(c.vers, hs.suite)
-
- // No signatures of the handshake are needed in a resumption.
- // Otherwise, in a full handshake, if we don't have any certificates
- // configured then we will never send a CertificateVerify message and
- // thus no signatures are needed in that case either.
- if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) {
- hs.finishedHash.discardHandshakeBuffer()
- }
-
- if err := transcriptMsg(hs.hello, &hs.finishedHash); err != nil {
- return err
- }
- if err := transcriptMsg(hs.serverHello, &hs.finishedHash); err != nil {
- return err
- }
-
- c.buffering = true
- c.didResume = isResume
- if isResume {
- if err := hs.establishKeys(); err != nil {
- return err
- }
- if err := hs.readSessionTicket(); err != nil {
- return err
- }
- if err := hs.readFinished(c.serverFinished[:]); err != nil {
- return err
- }
- c.clientFinishedIsFirst = false
- // Make sure the connection is still being verified whether or not this
- // is a resumption. Resumptions currently don't reverify certificates so
- // they don't call verifyServerCertificate. See Issue 31641.
- if c.config.VerifyConnection != nil {
- if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
- c.sendAlert(alertBadCertificate)
- return err
- }
- }
- if err := hs.sendFinished(c.clientFinished[:]); err != nil {
- return err
- }
- if _, err := c.flush(); err != nil {
- return err
- }
- } else {
- if err := hs.doFullHandshake(); err != nil {
- return err
- }
- if err := hs.establishKeys(); err != nil {
- return err
- }
- if err := hs.sendFinished(c.clientFinished[:]); err != nil {
- return err
- }
- if _, err := c.flush(); err != nil {
- return err
- }
- c.clientFinishedIsFirst = true
- if err := hs.readSessionTicket(); err != nil {
- return err
- }
- if err := hs.readFinished(c.serverFinished[:]); err != nil {
- return err
- }
- }
-
- c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)
- c.isHandshakeComplete.Store(true)
-
- return nil
-}
-
-func (hs *clientHandshakeState) pickCipherSuite() error {
- if hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil {
- hs.c.sendAlert(alertHandshakeFailure)
- return errors.New("tls: server chose an unconfigured cipher suite")
- }
-
- hs.c.cipherSuite = hs.suite.id
- return nil
-}
-
-func (hs *clientHandshakeState) doFullHandshake() error {
- c := hs.c
-
- msg, err := c.readHandshake(&hs.finishedHash)
- if err != nil {
- return err
- }
- certMsg, ok := msg.(*certificateMsg)
- if !ok || len(certMsg.certificates) == 0 {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(certMsg, msg)
- }
-
- msg, err = c.readHandshake(&hs.finishedHash)
- if err != nil {
- return err
- }
-
- cs, ok := msg.(*certificateStatusMsg)
- if ok {
- // RFC4366 on Certificate Status Request:
- // The server MAY return a "certificate_status" message.
-
- if !hs.serverHello.ocspStapling {
- // If a server returns a "CertificateStatus" message, then the
- // server MUST have included an extension of type "status_request"
- // with empty "extension_data" in the extended server hello.
-
- c.sendAlert(alertUnexpectedMessage)
- return errors.New("tls: received unexpected CertificateStatus message")
- }
-
- c.ocspResponse = cs.response
-
- msg, err = c.readHandshake(&hs.finishedHash)
- if err != nil {
- return err
- }
- }
-
- if c.handshakes == 0 {
- // If this is the first handshake on a connection, process and
- // (optionally) verify the server's certificates.
- if err := c.verifyServerCertificate(certMsg.certificates); err != nil {
- return err
- }
- } else {
- // This is a renegotiation handshake. We require that the
- // server's identity (i.e. leaf certificate) is unchanged and
- // thus any previous trust decision is still valid.
- //
- // See https://mitls.org/pages/attacks/3SHAKE for the
- // motivation behind this requirement.
- if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
- c.sendAlert(alertBadCertificate)
- return errors.New("tls: server's identity changed during renegotiation")
- }
- }
-
- keyAgreement := hs.suite.ka(c.vers)
-
- skx, ok := msg.(*serverKeyExchangeMsg)
- if ok {
- err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)
- if err != nil {
- c.sendAlert(alertUnexpectedMessage)
- return err
- }
-
- msg, err = c.readHandshake(&hs.finishedHash)
- if err != nil {
- return err
- }
- }
-
- var chainToSend *Certificate
- var certRequested bool
- certReq, ok := msg.(*certificateRequestMsg)
- if ok {
- certRequested = true
-
- cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq)
- if chainToSend, err = c.getClientCertificate(cri); err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
-
- msg, err = c.readHandshake(&hs.finishedHash)
- if err != nil {
- return err
- }
- }
-
- shd, ok := msg.(*serverHelloDoneMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(shd, msg)
- }
-
- // If the server requested a certificate then we have to send a
- // Certificate message, even if it's empty because we don't have a
- // certificate to send.
- if certRequested {
- certMsg = new(certificateMsg)
- certMsg.certificates = chainToSend.Certificate
- if _, err := hs.c.writeHandshakeRecord(certMsg, &hs.finishedHash); err != nil {
- return err
- }
- }
-
- preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0])
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
- if ckx != nil {
- if _, err := hs.c.writeHandshakeRecord(ckx, &hs.finishedHash); err != nil {
- return err
- }
- }
-
- if chainToSend != nil && len(chainToSend.Certificate) > 0 {
- certVerify := &certificateVerifyMsg{}
-
- key, ok := chainToSend.PrivateKey.(crypto.Signer)
- if !ok {
- c.sendAlert(alertInternalError)
- return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
- }
-
- var sigType uint8
- var sigHash crypto.Hash
- if c.vers >= VersionTLS12 {
- signatureAlgorithm, err := selectSignatureScheme(c.vers, chainToSend, certReq.supportedSignatureAlgorithms)
- if err != nil {
- c.sendAlert(alertIllegalParameter)
- return err
- }
- sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)
- if err != nil {
- return c.sendAlert(alertInternalError)
- }
- certVerify.hasSignatureAlgorithm = true
- certVerify.signatureAlgorithm = signatureAlgorithm
- } else {
- sigType, sigHash, err = legacyTypeAndHashFromPublicKey(key.Public())
- if err != nil {
- c.sendAlert(alertIllegalParameter)
- return err
- }
- }
-
- signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash)
- signOpts := crypto.SignerOpts(sigHash)
- if sigType == signatureRSAPSS {
- signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
- }
- certVerify.signature, err = key.Sign(c.config.rand(), signed, signOpts)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
-
- if _, err := hs.c.writeHandshakeRecord(certVerify, &hs.finishedHash); err != nil {
- return err
- }
- }
-
- hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
- if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil {
- c.sendAlert(alertInternalError)
- return errors.New("tls: failed to write to key log: " + err.Error())
- }
-
- hs.finishedHash.discardHandshakeBuffer()
-
- return nil
-}
-
-func (hs *clientHandshakeState) establishKeys() error {
- c := hs.c
-
- clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
- keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
- var clientCipher, serverCipher any
- var clientHash, serverHash hash.Hash
- if hs.suite.cipher != nil {
- clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
- clientHash = hs.suite.mac(clientMAC)
- serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
- serverHash = hs.suite.mac(serverMAC)
- } else {
- clientCipher = hs.suite.aead(clientKey, clientIV)
- serverCipher = hs.suite.aead(serverKey, serverIV)
- }
-
- c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
- c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
- return nil
-}
-
-func (hs *clientHandshakeState) serverResumedSession() bool {
- // If the server responded with the same sessionId then it means the
- // sessionTicket is being used to resume a TLS session.
- return hs.session != nil && hs.hello.sessionId != nil &&
- bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
-}
-
-func (hs *clientHandshakeState) processServerHello() (bool, error) {
- c := hs.c
-
- if err := hs.pickCipherSuite(); err != nil {
- return false, err
- }
-
- if hs.serverHello.compressionMethod != compressionNone {
- c.sendAlert(alertUnexpectedMessage)
- return false, errors.New("tls: server selected unsupported compression format")
- }
-
- if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
- c.secureRenegotiation = true
- if len(hs.serverHello.secureRenegotiation) != 0 {
- c.sendAlert(alertHandshakeFailure)
- return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
- }
- }
-
- if c.handshakes > 0 && c.secureRenegotiation {
- var expectedSecureRenegotiation [24]byte
- copy(expectedSecureRenegotiation[:], c.clientFinished[:])
- copy(expectedSecureRenegotiation[12:], c.serverFinished[:])
- if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {
- c.sendAlert(alertHandshakeFailure)
- return false, errors.New("tls: incorrect renegotiation extension contents")
- }
- }
-
- if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol); err != nil {
- c.sendAlert(alertUnsupportedExtension)
- return false, err
- }
- c.clientProtocol = hs.serverHello.alpnProtocol
-
- c.scts = hs.serverHello.scts
-
- if !hs.serverResumedSession() {
- return false, nil
- }
-
- if hs.session.vers != c.vers {
- c.sendAlert(alertHandshakeFailure)
- return false, errors.New("tls: server resumed a session with a different version")
- }
-
- if hs.session.cipherSuite != hs.suite.id {
- c.sendAlert(alertHandshakeFailure)
- return false, errors.New("tls: server resumed a session with a different cipher suite")
- }
-
- // Restore masterSecret, peerCerts, and ocspResponse from previous state
- hs.masterSecret = hs.session.masterSecret
- c.peerCertificates = hs.session.serverCertificates
- c.verifiedChains = hs.session.verifiedChains
- c.ocspResponse = hs.session.ocspResponse
- // Let the ServerHello SCTs override the session SCTs from the original
- // connection, if any are provided
- if len(c.scts) == 0 && len(hs.session.scts) != 0 {
- c.scts = hs.session.scts
- }
-
- return true, nil
-}
-
-// checkALPN ensure that the server's choice of ALPN protocol is compatible with
-// the protocols that we advertised in the Client Hello.
-func checkALPN(clientProtos []string, serverProto string) error {
- if serverProto == "" {
- return nil
- }
- if len(clientProtos) == 0 {
- return errors.New("tls: server advertised unrequested ALPN extension")
- }
- for _, proto := range clientProtos {
- if proto == serverProto {
- return nil
- }
- }
- return errors.New("tls: server selected unadvertised ALPN protocol")
-}
-
-func (hs *clientHandshakeState) readFinished(out []byte) error {
- c := hs.c
-
- if err := c.readChangeCipherSpec(); err != nil {
- return err
- }
-
- // finishedMsg is included in the transcript, but not until after we
- // check the client version, since the state before this message was
- // sent is used during verification.
- msg, err := c.readHandshake(nil)
- if err != nil {
- return err
- }
- serverFinished, ok := msg.(*finishedMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(serverFinished, msg)
- }
-
- verify := hs.finishedHash.serverSum(hs.masterSecret)
- if len(verify) != len(serverFinished.verifyData) ||
- subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
- c.sendAlert(alertHandshakeFailure)
- return errors.New("tls: server's Finished message was incorrect")
- }
-
- if err := transcriptMsg(serverFinished, &hs.finishedHash); err != nil {
- return err
- }
-
- copy(out, verify)
- return nil
-}
-
-func (hs *clientHandshakeState) readSessionTicket() error {
- if !hs.serverHello.ticketSupported {
- return nil
- }
-
- c := hs.c
- msg, err := c.readHandshake(&hs.finishedHash)
- if err != nil {
- return err
- }
- sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(sessionTicketMsg, msg)
- }
-
- hs.session = &ClientSessionState{
- sessionTicket: sessionTicketMsg.ticket,
- vers: c.vers,
- cipherSuite: hs.suite.id,
- masterSecret: hs.masterSecret,
- serverCertificates: c.peerCertificates,
- verifiedChains: c.verifiedChains,
- receivedAt: c.config.time(),
- ocspResponse: c.ocspResponse,
- scts: c.scts,
- }
-
- return nil
-}
-
-func (hs *clientHandshakeState) sendFinished(out []byte) error {
- c := hs.c
-
- if err := c.writeChangeCipherRecord(); err != nil {
- return err
- }
-
- finished := new(finishedMsg)
- finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
- if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil {
- return err
- }
- copy(out, finished.verifyData)
- return nil
-}
-
-// verifyServerCertificate parses and verifies the provided chain, setting
-// c.verifiedChains and c.peerCertificates or sending the appropriate alert.
-func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
- activeHandles := make([]*activeCert, len(certificates))
- certs := make([]*x509.Certificate, len(certificates))
- for i, asn1Data := range certificates {
- cert, err := clientCertCache.newCert(asn1Data)
- if err != nil {
- c.sendAlert(alertBadCertificate)
- return errors.New("tls: failed to parse certificate from server: " + err.Error())
- }
- activeHandles[i] = cert
- certs[i] = cert.cert
- }
-
- if !c.config.InsecureSkipVerify {
- opts := x509.VerifyOptions{
- Roots: c.config.RootCAs,
- CurrentTime: c.config.time(),
- DNSName: c.config.ServerName,
- Intermediates: x509.NewCertPool(),
- }
-
- for _, cert := range certs[1:] {
- opts.Intermediates.AddCert(cert)
- }
- var err error
- c.verifiedChains, err = certs[0].Verify(opts)
- if err != nil {
- c.sendAlert(alertBadCertificate)
- return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
- }
- }
-
- switch certs[0].PublicKey.(type) {
- case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
- break
- default:
- c.sendAlert(alertUnsupportedCertificate)
- return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
- }
-
- c.activeCertHandles = activeHandles
- c.peerCertificates = certs
-
- if c.config.VerifyPeerCertificate != nil {
- if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
- c.sendAlert(alertBadCertificate)
- return err
- }
- }
-
- if c.config.VerifyConnection != nil {
- if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
- c.sendAlert(alertBadCertificate)
- return err
- }
- }
-
- return nil
-}
-
-// certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS
-// <= 1.2 CertificateRequest, making an effort to fill in missing information.
-func certificateRequestInfoFromMsg(ctx context.Context, vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
- cri := &CertificateRequestInfo{
- AcceptableCAs: certReq.certificateAuthorities,
- Version: vers,
- ctx: ctx,
- }
-
- var rsaAvail, ecAvail bool
- for _, certType := range certReq.certificateTypes {
- switch certType {
- case certTypeRSASign:
- rsaAvail = true
- case certTypeECDSASign:
- ecAvail = true
- }
- }
-
- if !certReq.hasSignatureAlgorithm {
- // Prior to TLS 1.2, signature schemes did not exist. In this case we
- // make up a list based on the acceptable certificate types, to help
- // GetClientCertificate and SupportsCertificate select the right certificate.
- // The hash part of the SignatureScheme is a lie here, because
- // TLS 1.0 and 1.1 always use MD5+SHA1 for RSA and SHA1 for ECDSA.
- switch {
- case rsaAvail && ecAvail:
- cri.SignatureSchemes = []SignatureScheme{
- ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512,
- PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1,
- }
- case rsaAvail:
- cri.SignatureSchemes = []SignatureScheme{
- PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1,
- }
- case ecAvail:
- cri.SignatureSchemes = []SignatureScheme{
- ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512,
- }
- }
- return cri
- }
-
- // Filter the signature schemes based on the certificate types.
- // See RFC 5246, Section 7.4.4 (where it calls this "somewhat complicated").
- cri.SignatureSchemes = make([]SignatureScheme, 0, len(certReq.supportedSignatureAlgorithms))
- for _, sigScheme := range certReq.supportedSignatureAlgorithms {
- sigType, _, err := typeAndHashFromSignatureScheme(sigScheme)
- if err != nil {
- continue
- }
- switch sigType {
- case signatureECDSA, signatureEd25519:
- if ecAvail {
- cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme)
- }
- case signatureRSAPSS, signaturePKCS1v15:
- if rsaAvail {
- cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme)
- }
- }
- }
-
- return cri
-}
-
-func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate, error) {
- if c.config.GetClientCertificate != nil {
- return c.config.GetClientCertificate(cri)
- }
-
- for _, chain := range c.config.Certificates {
- if err := cri.SupportsCertificate(&chain); err != nil {
- continue
- }
- return &chain, nil
- }
-
- // No acceptable certificate found. Don't send a certificate.
- return new(Certificate), nil
-}
-
-// clientSessionCacheKey returns a key used to cache sessionTickets that could
-// be used to resume previously negotiated TLS sessions with a server.
-func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
- if len(config.ServerName) > 0 {
- return config.ServerName
- }
- return serverAddr.String()
-}
-
-// hostnameInSNI converts name into an appropriate hostname for SNI.
-// Literal IP addresses and absolute FQDNs are not permitted as SNI values.
-// See RFC 6066, Section 3.
-func hostnameInSNI(name string) string {
- host := name
- if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
- host = host[1 : len(host)-1]
- }
- if i := strings.LastIndex(host, "%"); i > 0 {
- host = host[:i]
- }
- if net.ParseIP(host) != nil {
- return ""
- }
- for len(name) > 0 && name[len(name)-1] == '.' {
- name = name[:len(name)-1]
- }
- return name
-}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/handshake_client_tls13.go b/contrib/go/_std_1.20/src/crypto/tls/handshake_client_tls13.go
deleted file mode 100644
index 4a8661085e..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/handshake_client_tls13.go
+++ /dev/null
@@ -1,709 +0,0 @@
-// Copyright 2018 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 tls
-
-import (
- "bytes"
- "context"
- "crypto"
- "crypto/ecdh"
- "crypto/hmac"
- "crypto/rsa"
- "errors"
- "hash"
- "time"
-)
-
-type clientHandshakeStateTLS13 struct {
- c *Conn
- ctx context.Context
- serverHello *serverHelloMsg
- hello *clientHelloMsg
- ecdheKey *ecdh.PrivateKey
-
- session *ClientSessionState
- earlySecret []byte
- binderKey []byte
-
- certReq *certificateRequestMsgTLS13
- usingPSK bool
- sentDummyCCS bool
- suite *cipherSuiteTLS13
- transcript hash.Hash
- masterSecret []byte
- trafficSecret []byte // client_application_traffic_secret_0
-}
-
-// handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheKey, and,
-// optionally, hs.session, hs.earlySecret and hs.binderKey to be set.
-func (hs *clientHandshakeStateTLS13) handshake() error {
- c := hs.c
-
- if needFIPS() {
- return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
- }
-
- // The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
- // sections 4.1.2 and 4.1.3.
- if c.handshakes > 0 {
- c.sendAlert(alertProtocolVersion)
- return errors.New("tls: server selected TLS 1.3 in a renegotiation")
- }
-
- // Consistency check on the presence of a keyShare and its parameters.
- if hs.ecdheKey == nil || len(hs.hello.keyShares) != 1 {
- return c.sendAlert(alertInternalError)
- }
-
- if err := hs.checkServerHelloOrHRR(); err != nil {
- return err
- }
-
- hs.transcript = hs.suite.hash.New()
-
- if err := transcriptMsg(hs.hello, hs.transcript); err != nil {
- return err
- }
-
- if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
- if err := hs.sendDummyChangeCipherSpec(); err != nil {
- return err
- }
- if err := hs.processHelloRetryRequest(); err != nil {
- return err
- }
- }
-
- if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
- return err
- }
-
- c.buffering = true
- if err := hs.processServerHello(); err != nil {
- return err
- }
- if err := hs.sendDummyChangeCipherSpec(); err != nil {
- return err
- }
- if err := hs.establishHandshakeKeys(); err != nil {
- return err
- }
- if err := hs.readServerParameters(); err != nil {
- return err
- }
- if err := hs.readServerCertificate(); err != nil {
- return err
- }
- if err := hs.readServerFinished(); err != nil {
- return err
- }
- if err := hs.sendClientCertificate(); err != nil {
- return err
- }
- if err := hs.sendClientFinished(); err != nil {
- return err
- }
- if _, err := c.flush(); err != nil {
- return err
- }
-
- c.isHandshakeComplete.Store(true)
-
- return nil
-}
-
-// checkServerHelloOrHRR does validity checks that apply to both ServerHello and
-// HelloRetryRequest messages. It sets hs.suite.
-func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error {
- c := hs.c
-
- if hs.serverHello.supportedVersion == 0 {
- c.sendAlert(alertMissingExtension)
- return errors.New("tls: server selected TLS 1.3 using the legacy version field")
- }
-
- if hs.serverHello.supportedVersion != VersionTLS13 {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server selected an invalid version after a HelloRetryRequest")
- }
-
- if hs.serverHello.vers != VersionTLS12 {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server sent an incorrect legacy version")
- }
-
- if hs.serverHello.ocspStapling ||
- hs.serverHello.ticketSupported ||
- hs.serverHello.secureRenegotiationSupported ||
- len(hs.serverHello.secureRenegotiation) != 0 ||
- len(hs.serverHello.alpnProtocol) != 0 ||
- len(hs.serverHello.scts) != 0 {
- c.sendAlert(alertUnsupportedExtension)
- return errors.New("tls: server sent a ServerHello extension forbidden in TLS 1.3")
- }
-
- if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server did not echo the legacy session ID")
- }
-
- if hs.serverHello.compressionMethod != compressionNone {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server selected unsupported compression format")
- }
-
- selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite)
- if hs.suite != nil && selectedSuite != hs.suite {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server changed cipher suite after a HelloRetryRequest")
- }
- if selectedSuite == nil {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server chose an unconfigured cipher suite")
- }
- hs.suite = selectedSuite
- c.cipherSuite = hs.suite.id
-
- return nil
-}
-
-// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
-// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
-func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
- if hs.sentDummyCCS {
- return nil
- }
- hs.sentDummyCCS = true
-
- return hs.c.writeChangeCipherRecord()
-}
-
-// processHelloRetryRequest handles the HRR in hs.serverHello, modifies and
-// resends hs.hello, and reads the new ServerHello into hs.serverHello.
-func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
- c := hs.c
-
- // The first ClientHello gets double-hashed into the transcript upon a
- // HelloRetryRequest. (The idea is that the server might offload transcript
- // storage to the client in the cookie.) See RFC 8446, Section 4.4.1.
- chHash := hs.transcript.Sum(nil)
- hs.transcript.Reset()
- hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
- hs.transcript.Write(chHash)
- if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
- return err
- }
-
- // The only HelloRetryRequest extensions we support are key_share and
- // cookie, and clients must abort the handshake if the HRR would not result
- // in any change in the ClientHello.
- if hs.serverHello.selectedGroup == 0 && hs.serverHello.cookie == nil {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server sent an unnecessary HelloRetryRequest message")
- }
-
- if hs.serverHello.cookie != nil {
- hs.hello.cookie = hs.serverHello.cookie
- }
-
- if hs.serverHello.serverShare.group != 0 {
- c.sendAlert(alertDecodeError)
- return errors.New("tls: received malformed key_share extension")
- }
-
- // If the server sent a key_share extension selecting a group, ensure it's
- // a group we advertised but did not send a key share for, and send a key
- // share for it this time.
- if curveID := hs.serverHello.selectedGroup; curveID != 0 {
- curveOK := false
- for _, id := range hs.hello.supportedCurves {
- if id == curveID {
- curveOK = true
- break
- }
- }
- if !curveOK {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server selected unsupported group")
- }
- if sentID, _ := curveIDForCurve(hs.ecdheKey.Curve()); sentID == curveID {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
- }
- if _, ok := curveForCurveID(curveID); !ok {
- c.sendAlert(alertInternalError)
- return errors.New("tls: CurvePreferences includes unsupported curve")
- }
- key, err := generateECDHEKey(c.config.rand(), curveID)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
- hs.ecdheKey = key
- hs.hello.keyShares = []keyShare{{group: curveID, data: key.PublicKey().Bytes()}}
- }
-
- hs.hello.raw = nil
- if len(hs.hello.pskIdentities) > 0 {
- pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite)
- if pskSuite == nil {
- return c.sendAlert(alertInternalError)
- }
- if pskSuite.hash == hs.suite.hash {
- // Update binders and obfuscated_ticket_age.
- ticketAge := uint32(c.config.time().Sub(hs.session.receivedAt) / time.Millisecond)
- hs.hello.pskIdentities[0].obfuscatedTicketAge = ticketAge + hs.session.ageAdd
-
- transcript := hs.suite.hash.New()
- transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
- transcript.Write(chHash)
- if err := transcriptMsg(hs.serverHello, transcript); err != nil {
- return err
- }
- helloBytes, err := hs.hello.marshalWithoutBinders()
- if err != nil {
- return err
- }
- transcript.Write(helloBytes)
- pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)}
- if err := hs.hello.updateBinders(pskBinders); err != nil {
- return err
- }
- } else {
- // Server selected a cipher suite incompatible with the PSK.
- hs.hello.pskIdentities = nil
- hs.hello.pskBinders = nil
- }
- }
-
- if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil {
- return err
- }
-
- // serverHelloMsg is not included in the transcript
- msg, err := c.readHandshake(nil)
- if err != nil {
- return err
- }
-
- serverHello, ok := msg.(*serverHelloMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(serverHello, msg)
- }
- hs.serverHello = serverHello
-
- if err := hs.checkServerHelloOrHRR(); err != nil {
- return err
- }
-
- return nil
-}
-
-func (hs *clientHandshakeStateTLS13) processServerHello() error {
- c := hs.c
-
- if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
- c.sendAlert(alertUnexpectedMessage)
- return errors.New("tls: server sent two HelloRetryRequest messages")
- }
-
- if len(hs.serverHello.cookie) != 0 {
- c.sendAlert(alertUnsupportedExtension)
- return errors.New("tls: server sent a cookie in a normal ServerHello")
- }
-
- if hs.serverHello.selectedGroup != 0 {
- c.sendAlert(alertDecodeError)
- return errors.New("tls: malformed key_share extension")
- }
-
- if hs.serverHello.serverShare.group == 0 {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server did not send a key share")
- }
- if sentID, _ := curveIDForCurve(hs.ecdheKey.Curve()); hs.serverHello.serverShare.group != sentID {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server selected unsupported group")
- }
-
- if !hs.serverHello.selectedIdentityPresent {
- return nil
- }
-
- if int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server selected an invalid PSK")
- }
-
- if len(hs.hello.pskIdentities) != 1 || hs.session == nil {
- return c.sendAlert(alertInternalError)
- }
- pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite)
- if pskSuite == nil {
- return c.sendAlert(alertInternalError)
- }
- if pskSuite.hash != hs.suite.hash {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: server selected an invalid PSK and cipher suite pair")
- }
-
- hs.usingPSK = true
- c.didResume = true
- c.peerCertificates = hs.session.serverCertificates
- c.verifiedChains = hs.session.verifiedChains
- c.ocspResponse = hs.session.ocspResponse
- c.scts = hs.session.scts
- return nil
-}
-
-func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
- c := hs.c
-
- peerKey, err := hs.ecdheKey.Curve().NewPublicKey(hs.serverHello.serverShare.data)
- if err != nil {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: invalid server key share")
- }
- sharedKey, err := hs.ecdheKey.ECDH(peerKey)
- if err != nil {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: invalid server key share")
- }
-
- earlySecret := hs.earlySecret
- if !hs.usingPSK {
- earlySecret = hs.suite.extract(nil, nil)
- }
-
- handshakeSecret := hs.suite.extract(sharedKey,
- hs.suite.deriveSecret(earlySecret, "derived", nil))
-
- clientSecret := hs.suite.deriveSecret(handshakeSecret,
- clientHandshakeTrafficLabel, hs.transcript)
- c.out.setTrafficSecret(hs.suite, clientSecret)
- serverSecret := hs.suite.deriveSecret(handshakeSecret,
- serverHandshakeTrafficLabel, hs.transcript)
- c.in.setTrafficSecret(hs.suite, serverSecret)
-
- err = c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
- err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.hello.random, serverSecret)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
-
- hs.masterSecret = hs.suite.extract(nil,
- hs.suite.deriveSecret(handshakeSecret, "derived", nil))
-
- return nil
-}
-
-func (hs *clientHandshakeStateTLS13) readServerParameters() error {
- c := hs.c
-
- msg, err := c.readHandshake(hs.transcript)
- if err != nil {
- return err
- }
-
- encryptedExtensions, ok := msg.(*encryptedExtensionsMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(encryptedExtensions, msg)
- }
-
- if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol); err != nil {
- c.sendAlert(alertUnsupportedExtension)
- return err
- }
- c.clientProtocol = encryptedExtensions.alpnProtocol
-
- return nil
-}
-
-func (hs *clientHandshakeStateTLS13) readServerCertificate() error {
- c := hs.c
-
- // Either a PSK or a certificate is always used, but not both.
- // See RFC 8446, Section 4.1.1.
- if hs.usingPSK {
- // Make sure the connection is still being verified whether or not this
- // is a resumption. Resumptions currently don't reverify certificates so
- // they don't call verifyServerCertificate. See Issue 31641.
- if c.config.VerifyConnection != nil {
- if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
- c.sendAlert(alertBadCertificate)
- return err
- }
- }
- return nil
- }
-
- msg, err := c.readHandshake(hs.transcript)
- if err != nil {
- return err
- }
-
- certReq, ok := msg.(*certificateRequestMsgTLS13)
- if ok {
- hs.certReq = certReq
-
- msg, err = c.readHandshake(hs.transcript)
- if err != nil {
- return err
- }
- }
-
- certMsg, ok := msg.(*certificateMsgTLS13)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(certMsg, msg)
- }
- if len(certMsg.certificate.Certificate) == 0 {
- c.sendAlert(alertDecodeError)
- return errors.New("tls: received empty certificates message")
- }
-
- c.scts = certMsg.certificate.SignedCertificateTimestamps
- c.ocspResponse = certMsg.certificate.OCSPStaple
-
- if err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil {
- return err
- }
-
- // certificateVerifyMsg is included in the transcript, but not until
- // after we verify the handshake signature, since the state before
- // this message was sent is used.
- msg, err = c.readHandshake(nil)
- if err != nil {
- return err
- }
-
- certVerify, ok := msg.(*certificateVerifyMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(certVerify, msg)
- }
-
- // See RFC 8446, Section 4.4.3.
- if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: certificate used with invalid signature algorithm")
- }
- sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
- if err != nil {
- return c.sendAlert(alertInternalError)
- }
- if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: certificate used with invalid signature algorithm")
- }
- signed := signedMessage(sigHash, serverSignatureContext, hs.transcript)
- if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey,
- sigHash, signed, certVerify.signature); err != nil {
- c.sendAlert(alertDecryptError)
- return errors.New("tls: invalid signature by the server certificate: " + err.Error())
- }
-
- if err := transcriptMsg(certVerify, hs.transcript); err != nil {
- return err
- }
-
- return nil
-}
-
-func (hs *clientHandshakeStateTLS13) readServerFinished() error {
- c := hs.c
-
- // finishedMsg is included in the transcript, but not until after we
- // check the client version, since the state before this message was
- // sent is used during verification.
- msg, err := c.readHandshake(nil)
- if err != nil {
- return err
- }
-
- finished, ok := msg.(*finishedMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(finished, msg)
- }
-
- expectedMAC := hs.suite.finishedHash(c.in.trafficSecret, hs.transcript)
- if !hmac.Equal(expectedMAC, finished.verifyData) {
- c.sendAlert(alertDecryptError)
- return errors.New("tls: invalid server finished hash")
- }
-
- if err := transcriptMsg(finished, hs.transcript); err != nil {
- return err
- }
-
- // Derive secrets that take context through the server Finished.
-
- hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret,
- clientApplicationTrafficLabel, hs.transcript)
- serverSecret := hs.suite.deriveSecret(hs.masterSecret,
- serverApplicationTrafficLabel, hs.transcript)
- c.in.setTrafficSecret(hs.suite, serverSecret)
-
- err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
- err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.hello.random, serverSecret)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
-
- c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript)
-
- return nil
-}
-
-func (hs *clientHandshakeStateTLS13) sendClientCertificate() error {
- c := hs.c
-
- if hs.certReq == nil {
- return nil
- }
-
- cert, err := c.getClientCertificate(&CertificateRequestInfo{
- AcceptableCAs: hs.certReq.certificateAuthorities,
- SignatureSchemes: hs.certReq.supportedSignatureAlgorithms,
- Version: c.vers,
- ctx: hs.ctx,
- })
- if err != nil {
- return err
- }
-
- certMsg := new(certificateMsgTLS13)
-
- certMsg.certificate = *cert
- certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0
- certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0
-
- if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != nil {
- return err
- }
-
- // If we sent an empty certificate message, skip the CertificateVerify.
- if len(cert.Certificate) == 0 {
- return nil
- }
-
- certVerifyMsg := new(certificateVerifyMsg)
- certVerifyMsg.hasSignatureAlgorithm = true
-
- certVerifyMsg.signatureAlgorithm, err = selectSignatureScheme(c.vers, cert, hs.certReq.supportedSignatureAlgorithms)
- if err != nil {
- // getClientCertificate returned a certificate incompatible with the
- // CertificateRequestInfo supported signature algorithms.
- c.sendAlert(alertHandshakeFailure)
- return err
- }
-
- sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerifyMsg.signatureAlgorithm)
- if err != nil {
- return c.sendAlert(alertInternalError)
- }
-
- signed := signedMessage(sigHash, clientSignatureContext, hs.transcript)
- signOpts := crypto.SignerOpts(sigHash)
- if sigType == signatureRSAPSS {
- signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
- }
- sig, err := cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts)
- if err != nil {
- c.sendAlert(alertInternalError)
- return errors.New("tls: failed to sign handshake: " + err.Error())
- }
- certVerifyMsg.signature = sig
-
- if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); err != nil {
- return err
- }
-
- return nil
-}
-
-func (hs *clientHandshakeStateTLS13) sendClientFinished() error {
- c := hs.c
-
- finished := &finishedMsg{
- verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
- }
-
- if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != nil {
- return err
- }
-
- c.out.setTrafficSecret(hs.suite, hs.trafficSecret)
-
- if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil {
- c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
- resumptionLabel, hs.transcript)
- }
-
- return nil
-}
-
-func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error {
- if !c.isClient {
- c.sendAlert(alertUnexpectedMessage)
- return errors.New("tls: received new session ticket from a client")
- }
-
- if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil {
- return nil
- }
-
- // See RFC 8446, Section 4.6.1.
- if msg.lifetime == 0 {
- return nil
- }
- lifetime := time.Duration(msg.lifetime) * time.Second
- if lifetime > maxSessionTicketLifetime {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: received a session ticket with invalid lifetime")
- }
-
- cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
- if cipherSuite == nil || c.resumptionSecret == nil {
- return c.sendAlert(alertInternalError)
- }
-
- // Save the resumption_master_secret and nonce instead of deriving the PSK
- // to do the least amount of work on NewSessionTicket messages before we
- // know if the ticket will be used. Forward secrecy of resumed connections
- // is guaranteed by the requirement for pskModeDHE.
- session := &ClientSessionState{
- sessionTicket: msg.label,
- vers: c.vers,
- cipherSuite: c.cipherSuite,
- masterSecret: c.resumptionSecret,
- serverCertificates: c.peerCertificates,
- verifiedChains: c.verifiedChains,
- receivedAt: c.config.time(),
- nonce: msg.nonce,
- useBy: c.config.time().Add(lifetime),
- ageAdd: msg.ageAdd,
- ocspResponse: c.ocspResponse,
- scts: c.scts,
- }
-
- cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
- c.config.ClientSessionCache.Put(cacheKey, session)
-
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/handshake_messages.go b/contrib/go/_std_1.20/src/crypto/tls/handshake_messages.go
deleted file mode 100644
index 695aacf126..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/handshake_messages.go
+++ /dev/null
@@ -1,1852 +0,0 @@
-// Copyright 2009 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 tls
-
-import (
- "errors"
- "fmt"
- "strings"
-
- "golang.org/x/crypto/cryptobyte"
-)
-
-// The marshalingFunction type is an adapter to allow the use of ordinary
-// functions as cryptobyte.MarshalingValue.
-type marshalingFunction func(b *cryptobyte.Builder) error
-
-func (f marshalingFunction) Marshal(b *cryptobyte.Builder) error {
- return f(b)
-}
-
-// addBytesWithLength appends a sequence of bytes to the cryptobyte.Builder. If
-// the length of the sequence is not the value specified, it produces an error.
-func addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) {
- b.AddValue(marshalingFunction(func(b *cryptobyte.Builder) error {
- if len(v) != n {
- return fmt.Errorf("invalid value length: expected %d, got %d", n, len(v))
- }
- b.AddBytes(v)
- return nil
- }))
-}
-
-// addUint64 appends a big-endian, 64-bit value to the cryptobyte.Builder.
-func addUint64(b *cryptobyte.Builder, v uint64) {
- b.AddUint32(uint32(v >> 32))
- b.AddUint32(uint32(v))
-}
-
-// readUint64 decodes a big-endian, 64-bit value into out and advances over it.
-// It reports whether the read was successful.
-func readUint64(s *cryptobyte.String, out *uint64) bool {
- var hi, lo uint32
- if !s.ReadUint32(&hi) || !s.ReadUint32(&lo) {
- return false
- }
- *out = uint64(hi)<<32 | uint64(lo)
- return true
-}
-
-// readUint8LengthPrefixed acts like s.ReadUint8LengthPrefixed, but targets a
-// []byte instead of a cryptobyte.String.
-func readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
- return s.ReadUint8LengthPrefixed((*cryptobyte.String)(out))
-}
-
-// readUint16LengthPrefixed acts like s.ReadUint16LengthPrefixed, but targets a
-// []byte instead of a cryptobyte.String.
-func readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
- return s.ReadUint16LengthPrefixed((*cryptobyte.String)(out))
-}
-
-// readUint24LengthPrefixed acts like s.ReadUint24LengthPrefixed, but targets a
-// []byte instead of a cryptobyte.String.
-func readUint24LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
- return s.ReadUint24LengthPrefixed((*cryptobyte.String)(out))
-}
-
-type clientHelloMsg struct {
- raw []byte
- vers uint16
- random []byte
- sessionId []byte
- cipherSuites []uint16
- compressionMethods []uint8
- serverName string
- ocspStapling bool
- supportedCurves []CurveID
- supportedPoints []uint8
- ticketSupported bool
- sessionTicket []uint8
- supportedSignatureAlgorithms []SignatureScheme
- supportedSignatureAlgorithmsCert []SignatureScheme
- secureRenegotiationSupported bool
- secureRenegotiation []byte
- alpnProtocols []string
- scts bool
- supportedVersions []uint16
- cookie []byte
- keyShares []keyShare
- earlyData bool
- pskModes []uint8
- pskIdentities []pskIdentity
- pskBinders [][]byte
-}
-
-func (m *clientHelloMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- var exts cryptobyte.Builder
- if len(m.serverName) > 0 {
- // RFC 6066, Section 3
- exts.AddUint16(extensionServerName)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint8(0) // name_type = host_name
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes([]byte(m.serverName))
- })
- })
- })
- }
- if m.ocspStapling {
- // RFC 4366, Section 3.6
- exts.AddUint16(extensionStatusRequest)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint8(1) // status_type = ocsp
- exts.AddUint16(0) // empty responder_id_list
- exts.AddUint16(0) // empty request_extensions
- })
- }
- if len(m.supportedCurves) > 0 {
- // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
- exts.AddUint16(extensionSupportedCurves)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- for _, curve := range m.supportedCurves {
- exts.AddUint16(uint16(curve))
- }
- })
- })
- }
- if len(m.supportedPoints) > 0 {
- // RFC 4492, Section 5.1.2
- exts.AddUint16(extensionSupportedPoints)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(m.supportedPoints)
- })
- })
- }
- if m.ticketSupported {
- // RFC 5077, Section 3.2
- exts.AddUint16(extensionSessionTicket)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(m.sessionTicket)
- })
- }
- if len(m.supportedSignatureAlgorithms) > 0 {
- // RFC 5246, Section 7.4.1.4.1
- exts.AddUint16(extensionSignatureAlgorithms)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- for _, sigAlgo := range m.supportedSignatureAlgorithms {
- exts.AddUint16(uint16(sigAlgo))
- }
- })
- })
- }
- if len(m.supportedSignatureAlgorithmsCert) > 0 {
- // RFC 8446, Section 4.2.3
- exts.AddUint16(extensionSignatureAlgorithmsCert)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- for _, sigAlgo := range m.supportedSignatureAlgorithmsCert {
- exts.AddUint16(uint16(sigAlgo))
- }
- })
- })
- }
- if m.secureRenegotiationSupported {
- // RFC 5746, Section 3.2
- exts.AddUint16(extensionRenegotiationInfo)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(m.secureRenegotiation)
- })
- })
- }
- if len(m.alpnProtocols) > 0 {
- // RFC 7301, Section 3.1
- exts.AddUint16(extensionALPN)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- for _, proto := range m.alpnProtocols {
- exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes([]byte(proto))
- })
- }
- })
- })
- }
- if m.scts {
- // RFC 6962, Section 3.3.1
- exts.AddUint16(extensionSCT)
- exts.AddUint16(0) // empty extension_data
- }
- if len(m.supportedVersions) > 0 {
- // RFC 8446, Section 4.2.1
- exts.AddUint16(extensionSupportedVersions)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
- for _, vers := range m.supportedVersions {
- exts.AddUint16(vers)
- }
- })
- })
- }
- if len(m.cookie) > 0 {
- // RFC 8446, Section 4.2.2
- exts.AddUint16(extensionCookie)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(m.cookie)
- })
- })
- }
- if len(m.keyShares) > 0 {
- // RFC 8446, Section 4.2.8
- exts.AddUint16(extensionKeyShare)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- for _, ks := range m.keyShares {
- exts.AddUint16(uint16(ks.group))
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(ks.data)
- })
- }
- })
- })
- }
- if m.earlyData {
- // RFC 8446, Section 4.2.10
- exts.AddUint16(extensionEarlyData)
- exts.AddUint16(0) // empty extension_data
- }
- if len(m.pskModes) > 0 {
- // RFC 8446, Section 4.2.9
- exts.AddUint16(extensionPSKModes)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(m.pskModes)
- })
- })
- }
- if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension
- // RFC 8446, Section 4.2.11
- exts.AddUint16(extensionPreSharedKey)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- for _, psk := range m.pskIdentities {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(psk.label)
- })
- exts.AddUint32(psk.obfuscatedTicketAge)
- }
- })
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- for _, binder := range m.pskBinders {
- exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(binder)
- })
- }
- })
- })
- }
- extBytes, err := exts.Bytes()
- if err != nil {
- return nil, err
- }
-
- var b cryptobyte.Builder
- b.AddUint8(typeClientHello)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16(m.vers)
- addBytesWithLength(b, m.random, 32)
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.sessionId)
- })
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- for _, suite := range m.cipherSuites {
- b.AddUint16(suite)
- }
- })
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.compressionMethods)
- })
-
- if len(extBytes) > 0 {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(extBytes)
- })
- }
- })
-
- m.raw, err = b.Bytes()
- return m.raw, err
-}
-
-// marshalWithoutBinders returns the ClientHello through the
-// PreSharedKeyExtension.identities field, according to RFC 8446, Section
-// 4.2.11.2. Note that m.pskBinders must be set to slices of the correct length.
-func (m *clientHelloMsg) marshalWithoutBinders() ([]byte, error) {
- bindersLen := 2 // uint16 length prefix
- for _, binder := range m.pskBinders {
- bindersLen += 1 // uint8 length prefix
- bindersLen += len(binder)
- }
-
- fullMessage, err := m.marshal()
- if err != nil {
- return nil, err
- }
- return fullMessage[:len(fullMessage)-bindersLen], nil
-}
-
-// updateBinders updates the m.pskBinders field, if necessary updating the
-// cached marshaled representation. The supplied binders must have the same
-// length as the current m.pskBinders.
-func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) error {
- if len(pskBinders) != len(m.pskBinders) {
- return errors.New("tls: internal error: pskBinders length mismatch")
- }
- for i := range m.pskBinders {
- if len(pskBinders[i]) != len(m.pskBinders[i]) {
- return errors.New("tls: internal error: pskBinders length mismatch")
- }
- }
- m.pskBinders = pskBinders
- if m.raw != nil {
- helloBytes, err := m.marshalWithoutBinders()
- if err != nil {
- return err
- }
- lenWithoutBinders := len(helloBytes)
- b := cryptobyte.NewFixedBuilder(m.raw[:lenWithoutBinders])
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- for _, binder := range m.pskBinders {
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(binder)
- })
- }
- })
- if out, err := b.Bytes(); err != nil || len(out) != len(m.raw) {
- return errors.New("tls: internal error: failed to update binders")
- }
- }
-
- return nil
-}
-
-func (m *clientHelloMsg) unmarshal(data []byte) bool {
- *m = clientHelloMsg{raw: data}
- s := cryptobyte.String(data)
-
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) ||
- !readUint8LengthPrefixed(&s, &m.sessionId) {
- return false
- }
-
- var cipherSuites cryptobyte.String
- if !s.ReadUint16LengthPrefixed(&cipherSuites) {
- return false
- }
- m.cipherSuites = []uint16{}
- m.secureRenegotiationSupported = false
- for !cipherSuites.Empty() {
- var suite uint16
- if !cipherSuites.ReadUint16(&suite) {
- return false
- }
- if suite == scsvRenegotiation {
- m.secureRenegotiationSupported = true
- }
- m.cipherSuites = append(m.cipherSuites, suite)
- }
-
- if !readUint8LengthPrefixed(&s, &m.compressionMethods) {
- return false
- }
-
- if s.Empty() {
- // ClientHello is optionally followed by extension data
- return true
- }
-
- var extensions cryptobyte.String
- if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
- return false
- }
-
- seenExts := make(map[uint16]bool)
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
-
- if seenExts[extension] {
- return false
- }
- seenExts[extension] = true
-
- switch extension {
- case extensionServerName:
- // RFC 6066, Section 3
- var nameList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() {
- return false
- }
- for !nameList.Empty() {
- var nameType uint8
- var serverName cryptobyte.String
- if !nameList.ReadUint8(&nameType) ||
- !nameList.ReadUint16LengthPrefixed(&serverName) ||
- serverName.Empty() {
- return false
- }
- if nameType != 0 {
- continue
- }
- if len(m.serverName) != 0 {
- // Multiple names of the same name_type are prohibited.
- return false
- }
- m.serverName = string(serverName)
- // An SNI value may not include a trailing dot.
- if strings.HasSuffix(m.serverName, ".") {
- return false
- }
- }
- case extensionStatusRequest:
- // RFC 4366, Section 3.6
- var statusType uint8
- var ignored cryptobyte.String
- if !extData.ReadUint8(&statusType) ||
- !extData.ReadUint16LengthPrefixed(&ignored) ||
- !extData.ReadUint16LengthPrefixed(&ignored) {
- return false
- }
- m.ocspStapling = statusType == statusTypeOCSP
- case extensionSupportedCurves:
- // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
- var curves cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&curves) || curves.Empty() {
- return false
- }
- for !curves.Empty() {
- var curve uint16
- if !curves.ReadUint16(&curve) {
- return false
- }
- m.supportedCurves = append(m.supportedCurves, CurveID(curve))
- }
- case extensionSupportedPoints:
- // RFC 4492, Section 5.1.2
- if !readUint8LengthPrefixed(&extData, &m.supportedPoints) ||
- len(m.supportedPoints) == 0 {
- return false
- }
- case extensionSessionTicket:
- // RFC 5077, Section 3.2
- m.ticketSupported = true
- extData.ReadBytes(&m.sessionTicket, len(extData))
- case extensionSignatureAlgorithms:
- // RFC 5246, Section 7.4.1.4.1
- var sigAndAlgs cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
- return false
- }
- for !sigAndAlgs.Empty() {
- var sigAndAlg uint16
- if !sigAndAlgs.ReadUint16(&sigAndAlg) {
- return false
- }
- m.supportedSignatureAlgorithms = append(
- m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg))
- }
- case extensionSignatureAlgorithmsCert:
- // RFC 8446, Section 4.2.3
- var sigAndAlgs cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
- return false
- }
- for !sigAndAlgs.Empty() {
- var sigAndAlg uint16
- if !sigAndAlgs.ReadUint16(&sigAndAlg) {
- return false
- }
- m.supportedSignatureAlgorithmsCert = append(
- m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg))
- }
- case extensionRenegotiationInfo:
- // RFC 5746, Section 3.2
- if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {
- return false
- }
- m.secureRenegotiationSupported = true
- case extensionALPN:
- // RFC 7301, Section 3.1
- var protoList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
- return false
- }
- for !protoList.Empty() {
- var proto cryptobyte.String
- if !protoList.ReadUint8LengthPrefixed(&proto) || proto.Empty() {
- return false
- }
- m.alpnProtocols = append(m.alpnProtocols, string(proto))
- }
- case extensionSCT:
- // RFC 6962, Section 3.3.1
- m.scts = true
- case extensionSupportedVersions:
- // RFC 8446, Section 4.2.1
- var versList cryptobyte.String
- if !extData.ReadUint8LengthPrefixed(&versList) || versList.Empty() {
- return false
- }
- for !versList.Empty() {
- var vers uint16
- if !versList.ReadUint16(&vers) {
- return false
- }
- m.supportedVersions = append(m.supportedVersions, vers)
- }
- case extensionCookie:
- // RFC 8446, Section 4.2.2
- if !readUint16LengthPrefixed(&extData, &m.cookie) ||
- len(m.cookie) == 0 {
- return false
- }
- case extensionKeyShare:
- // RFC 8446, Section 4.2.8
- var clientShares cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&clientShares) {
- return false
- }
- for !clientShares.Empty() {
- var ks keyShare
- if !clientShares.ReadUint16((*uint16)(&ks.group)) ||
- !readUint16LengthPrefixed(&clientShares, &ks.data) ||
- len(ks.data) == 0 {
- return false
- }
- m.keyShares = append(m.keyShares, ks)
- }
- case extensionEarlyData:
- // RFC 8446, Section 4.2.10
- m.earlyData = true
- case extensionPSKModes:
- // RFC 8446, Section 4.2.9
- if !readUint8LengthPrefixed(&extData, &m.pskModes) {
- return false
- }
- case extensionPreSharedKey:
- // RFC 8446, Section 4.2.11
- if !extensions.Empty() {
- return false // pre_shared_key must be the last extension
- }
- var identities cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&identities) || identities.Empty() {
- return false
- }
- for !identities.Empty() {
- var psk pskIdentity
- if !readUint16LengthPrefixed(&identities, &psk.label) ||
- !identities.ReadUint32(&psk.obfuscatedTicketAge) ||
- len(psk.label) == 0 {
- return false
- }
- m.pskIdentities = append(m.pskIdentities, psk)
- }
- var binders cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&binders) || binders.Empty() {
- return false
- }
- for !binders.Empty() {
- var binder []byte
- if !readUint8LengthPrefixed(&binders, &binder) ||
- len(binder) == 0 {
- return false
- }
- m.pskBinders = append(m.pskBinders, binder)
- }
- default:
- // Ignore unknown extensions.
- continue
- }
-
- if !extData.Empty() {
- return false
- }
- }
-
- return true
-}
-
-type serverHelloMsg struct {
- raw []byte
- vers uint16
- random []byte
- sessionId []byte
- cipherSuite uint16
- compressionMethod uint8
- ocspStapling bool
- ticketSupported bool
- secureRenegotiationSupported bool
- secureRenegotiation []byte
- alpnProtocol string
- scts [][]byte
- supportedVersion uint16
- serverShare keyShare
- selectedIdentityPresent bool
- selectedIdentity uint16
- supportedPoints []uint8
-
- // HelloRetryRequest extensions
- cookie []byte
- selectedGroup CurveID
-}
-
-func (m *serverHelloMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- var exts cryptobyte.Builder
- if m.ocspStapling {
- exts.AddUint16(extensionStatusRequest)
- exts.AddUint16(0) // empty extension_data
- }
- if m.ticketSupported {
- exts.AddUint16(extensionSessionTicket)
- exts.AddUint16(0) // empty extension_data
- }
- if m.secureRenegotiationSupported {
- exts.AddUint16(extensionRenegotiationInfo)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(m.secureRenegotiation)
- })
- })
- }
- if len(m.alpnProtocol) > 0 {
- exts.AddUint16(extensionALPN)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes([]byte(m.alpnProtocol))
- })
- })
- })
- }
- if len(m.scts) > 0 {
- exts.AddUint16(extensionSCT)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- for _, sct := range m.scts {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(sct)
- })
- }
- })
- })
- }
- if m.supportedVersion != 0 {
- exts.AddUint16(extensionSupportedVersions)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16(m.supportedVersion)
- })
- }
- if m.serverShare.group != 0 {
- exts.AddUint16(extensionKeyShare)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16(uint16(m.serverShare.group))
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(m.serverShare.data)
- })
- })
- }
- if m.selectedIdentityPresent {
- exts.AddUint16(extensionPreSharedKey)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16(m.selectedIdentity)
- })
- }
-
- if len(m.cookie) > 0 {
- exts.AddUint16(extensionCookie)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(m.cookie)
- })
- })
- }
- if m.selectedGroup != 0 {
- exts.AddUint16(extensionKeyShare)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint16(uint16(m.selectedGroup))
- })
- }
- if len(m.supportedPoints) > 0 {
- exts.AddUint16(extensionSupportedPoints)
- exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
- exts.AddBytes(m.supportedPoints)
- })
- })
- }
-
- extBytes, err := exts.Bytes()
- if err != nil {
- return nil, err
- }
-
- var b cryptobyte.Builder
- b.AddUint8(typeServerHello)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16(m.vers)
- addBytesWithLength(b, m.random, 32)
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.sessionId)
- })
- b.AddUint16(m.cipherSuite)
- b.AddUint8(m.compressionMethod)
-
- if len(extBytes) > 0 {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(extBytes)
- })
- }
- })
-
- m.raw, err = b.Bytes()
- return m.raw, err
-}
-
-func (m *serverHelloMsg) unmarshal(data []byte) bool {
- *m = serverHelloMsg{raw: data}
- s := cryptobyte.String(data)
-
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) ||
- !readUint8LengthPrefixed(&s, &m.sessionId) ||
- !s.ReadUint16(&m.cipherSuite) ||
- !s.ReadUint8(&m.compressionMethod) {
- return false
- }
-
- if s.Empty() {
- // ServerHello is optionally followed by extension data
- return true
- }
-
- var extensions cryptobyte.String
- if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
- return false
- }
-
- seenExts := make(map[uint16]bool)
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
-
- if seenExts[extension] {
- return false
- }
- seenExts[extension] = true
-
- switch extension {
- case extensionStatusRequest:
- m.ocspStapling = true
- case extensionSessionTicket:
- m.ticketSupported = true
- case extensionRenegotiationInfo:
- if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {
- return false
- }
- m.secureRenegotiationSupported = true
- case extensionALPN:
- var protoList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
- return false
- }
- var proto cryptobyte.String
- if !protoList.ReadUint8LengthPrefixed(&proto) ||
- proto.Empty() || !protoList.Empty() {
- return false
- }
- m.alpnProtocol = string(proto)
- case extensionSCT:
- var sctList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {
- return false
- }
- for !sctList.Empty() {
- var sct []byte
- if !readUint16LengthPrefixed(&sctList, &sct) ||
- len(sct) == 0 {
- return false
- }
- m.scts = append(m.scts, sct)
- }
- case extensionSupportedVersions:
- if !extData.ReadUint16(&m.supportedVersion) {
- return false
- }
- case extensionCookie:
- if !readUint16LengthPrefixed(&extData, &m.cookie) ||
- len(m.cookie) == 0 {
- return false
- }
- case extensionKeyShare:
- // This extension has different formats in SH and HRR, accept either
- // and let the handshake logic decide. See RFC 8446, Section 4.2.8.
- if len(extData) == 2 {
- if !extData.ReadUint16((*uint16)(&m.selectedGroup)) {
- return false
- }
- } else {
- if !extData.ReadUint16((*uint16)(&m.serverShare.group)) ||
- !readUint16LengthPrefixed(&extData, &m.serverShare.data) {
- return false
- }
- }
- case extensionPreSharedKey:
- m.selectedIdentityPresent = true
- if !extData.ReadUint16(&m.selectedIdentity) {
- return false
- }
- case extensionSupportedPoints:
- // RFC 4492, Section 5.1.2
- if !readUint8LengthPrefixed(&extData, &m.supportedPoints) ||
- len(m.supportedPoints) == 0 {
- return false
- }
- default:
- // Ignore unknown extensions.
- continue
- }
-
- if !extData.Empty() {
- return false
- }
- }
-
- return true
-}
-
-type encryptedExtensionsMsg struct {
- raw []byte
- alpnProtocol string
-}
-
-func (m *encryptedExtensionsMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- var b cryptobyte.Builder
- b.AddUint8(typeEncryptedExtensions)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- if len(m.alpnProtocol) > 0 {
- b.AddUint16(extensionALPN)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes([]byte(m.alpnProtocol))
- })
- })
- })
- }
- })
- })
-
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
-}
-
-func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
- *m = encryptedExtensionsMsg{raw: data}
- s := cryptobyte.String(data)
-
- var extensions cryptobyte.String
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
- return false
- }
-
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
-
- switch extension {
- case extensionALPN:
- var protoList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
- return false
- }
- var proto cryptobyte.String
- if !protoList.ReadUint8LengthPrefixed(&proto) ||
- proto.Empty() || !protoList.Empty() {
- return false
- }
- m.alpnProtocol = string(proto)
- default:
- // Ignore unknown extensions.
- continue
- }
-
- if !extData.Empty() {
- return false
- }
- }
-
- return true
-}
-
-type endOfEarlyDataMsg struct{}
-
-func (m *endOfEarlyDataMsg) marshal() ([]byte, error) {
- x := make([]byte, 4)
- x[0] = typeEndOfEarlyData
- return x, nil
-}
-
-func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool {
- return len(data) == 4
-}
-
-type keyUpdateMsg struct {
- raw []byte
- updateRequested bool
-}
-
-func (m *keyUpdateMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- var b cryptobyte.Builder
- b.AddUint8(typeKeyUpdate)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- if m.updateRequested {
- b.AddUint8(1)
- } else {
- b.AddUint8(0)
- }
- })
-
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
-}
-
-func (m *keyUpdateMsg) unmarshal(data []byte) bool {
- m.raw = data
- s := cryptobyte.String(data)
-
- var updateRequested uint8
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint8(&updateRequested) || !s.Empty() {
- return false
- }
- switch updateRequested {
- case 0:
- m.updateRequested = false
- case 1:
- m.updateRequested = true
- default:
- return false
- }
- return true
-}
-
-type newSessionTicketMsgTLS13 struct {
- raw []byte
- lifetime uint32
- ageAdd uint32
- nonce []byte
- label []byte
- maxEarlyData uint32
-}
-
-func (m *newSessionTicketMsgTLS13) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- var b cryptobyte.Builder
- b.AddUint8(typeNewSessionTicket)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint32(m.lifetime)
- b.AddUint32(m.ageAdd)
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.nonce)
- })
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.label)
- })
-
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- if m.maxEarlyData > 0 {
- b.AddUint16(extensionEarlyData)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint32(m.maxEarlyData)
- })
- }
- })
- })
-
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
-}
-
-func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool {
- *m = newSessionTicketMsgTLS13{raw: data}
- s := cryptobyte.String(data)
-
- var extensions cryptobyte.String
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint32(&m.lifetime) ||
- !s.ReadUint32(&m.ageAdd) ||
- !readUint8LengthPrefixed(&s, &m.nonce) ||
- !readUint16LengthPrefixed(&s, &m.label) ||
- !s.ReadUint16LengthPrefixed(&extensions) ||
- !s.Empty() {
- return false
- }
-
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
-
- switch extension {
- case extensionEarlyData:
- if !extData.ReadUint32(&m.maxEarlyData) {
- return false
- }
- default:
- // Ignore unknown extensions.
- continue
- }
-
- if !extData.Empty() {
- return false
- }
- }
-
- return true
-}
-
-type certificateRequestMsgTLS13 struct {
- raw []byte
- ocspStapling bool
- scts bool
- supportedSignatureAlgorithms []SignatureScheme
- supportedSignatureAlgorithmsCert []SignatureScheme
- certificateAuthorities [][]byte
-}
-
-func (m *certificateRequestMsgTLS13) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- var b cryptobyte.Builder
- b.AddUint8(typeCertificateRequest)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- // certificate_request_context (SHALL be zero length unless used for
- // post-handshake authentication)
- b.AddUint8(0)
-
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- if m.ocspStapling {
- b.AddUint16(extensionStatusRequest)
- b.AddUint16(0) // empty extension_data
- }
- if m.scts {
- // RFC 8446, Section 4.4.2.1 makes no mention of
- // signed_certificate_timestamp in CertificateRequest, but
- // "Extensions in the Certificate message from the client MUST
- // correspond to extensions in the CertificateRequest message
- // from the server." and it appears in the table in Section 4.2.
- b.AddUint16(extensionSCT)
- b.AddUint16(0) // empty extension_data
- }
- if len(m.supportedSignatureAlgorithms) > 0 {
- b.AddUint16(extensionSignatureAlgorithms)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- for _, sigAlgo := range m.supportedSignatureAlgorithms {
- b.AddUint16(uint16(sigAlgo))
- }
- })
- })
- }
- if len(m.supportedSignatureAlgorithmsCert) > 0 {
- b.AddUint16(extensionSignatureAlgorithmsCert)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- for _, sigAlgo := range m.supportedSignatureAlgorithmsCert {
- b.AddUint16(uint16(sigAlgo))
- }
- })
- })
- }
- if len(m.certificateAuthorities) > 0 {
- b.AddUint16(extensionCertificateAuthorities)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- for _, ca := range m.certificateAuthorities {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(ca)
- })
- }
- })
- })
- }
- })
- })
-
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
-}
-
-func (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool {
- *m = certificateRequestMsgTLS13{raw: data}
- s := cryptobyte.String(data)
-
- var context, extensions cryptobyte.String
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||
- !s.ReadUint16LengthPrefixed(&extensions) ||
- !s.Empty() {
- return false
- }
-
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
-
- switch extension {
- case extensionStatusRequest:
- m.ocspStapling = true
- case extensionSCT:
- m.scts = true
- case extensionSignatureAlgorithms:
- var sigAndAlgs cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
- return false
- }
- for !sigAndAlgs.Empty() {
- var sigAndAlg uint16
- if !sigAndAlgs.ReadUint16(&sigAndAlg) {
- return false
- }
- m.supportedSignatureAlgorithms = append(
- m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg))
- }
- case extensionSignatureAlgorithmsCert:
- var sigAndAlgs cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
- return false
- }
- for !sigAndAlgs.Empty() {
- var sigAndAlg uint16
- if !sigAndAlgs.ReadUint16(&sigAndAlg) {
- return false
- }
- m.supportedSignatureAlgorithmsCert = append(
- m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg))
- }
- case extensionCertificateAuthorities:
- var auths cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&auths) || auths.Empty() {
- return false
- }
- for !auths.Empty() {
- var ca []byte
- if !readUint16LengthPrefixed(&auths, &ca) || len(ca) == 0 {
- return false
- }
- m.certificateAuthorities = append(m.certificateAuthorities, ca)
- }
- default:
- // Ignore unknown extensions.
- continue
- }
-
- if !extData.Empty() {
- return false
- }
- }
-
- return true
-}
-
-type certificateMsg struct {
- raw []byte
- certificates [][]byte
-}
-
-func (m *certificateMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- var i int
- for _, slice := range m.certificates {
- i += len(slice)
- }
-
- length := 3 + 3*len(m.certificates) + i
- x := make([]byte, 4+length)
- x[0] = typeCertificate
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
-
- certificateOctets := length - 3
- x[4] = uint8(certificateOctets >> 16)
- x[5] = uint8(certificateOctets >> 8)
- x[6] = uint8(certificateOctets)
-
- y := x[7:]
- for _, slice := range m.certificates {
- y[0] = uint8(len(slice) >> 16)
- y[1] = uint8(len(slice) >> 8)
- y[2] = uint8(len(slice))
- copy(y[3:], slice)
- y = y[3+len(slice):]
- }
-
- m.raw = x
- return m.raw, nil
-}
-
-func (m *certificateMsg) unmarshal(data []byte) bool {
- if len(data) < 7 {
- return false
- }
-
- m.raw = data
- certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
- if uint32(len(data)) != certsLen+7 {
- return false
- }
-
- numCerts := 0
- d := data[7:]
- for certsLen > 0 {
- if len(d) < 4 {
- return false
- }
- certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
- if uint32(len(d)) < 3+certLen {
- return false
- }
- d = d[3+certLen:]
- certsLen -= 3 + certLen
- numCerts++
- }
-
- m.certificates = make([][]byte, numCerts)
- d = data[7:]
- for i := 0; i < numCerts; i++ {
- certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
- m.certificates[i] = d[3 : 3+certLen]
- d = d[3+certLen:]
- }
-
- return true
-}
-
-type certificateMsgTLS13 struct {
- raw []byte
- certificate Certificate
- ocspStapling bool
- scts bool
-}
-
-func (m *certificateMsgTLS13) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- var b cryptobyte.Builder
- b.AddUint8(typeCertificate)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint8(0) // certificate_request_context
-
- certificate := m.certificate
- if !m.ocspStapling {
- certificate.OCSPStaple = nil
- }
- if !m.scts {
- certificate.SignedCertificateTimestamps = nil
- }
- marshalCertificate(b, certificate)
- })
-
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
-}
-
-func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) {
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- for i, cert := range certificate.Certificate {
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(cert)
- })
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- if i > 0 {
- // This library only supports OCSP and SCT for leaf certificates.
- return
- }
- if certificate.OCSPStaple != nil {
- b.AddUint16(extensionStatusRequest)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint8(statusTypeOCSP)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(certificate.OCSPStaple)
- })
- })
- }
- if certificate.SignedCertificateTimestamps != nil {
- b.AddUint16(extensionSCT)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- for _, sct := range certificate.SignedCertificateTimestamps {
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(sct)
- })
- }
- })
- })
- }
- })
- }
- })
-}
-
-func (m *certificateMsgTLS13) unmarshal(data []byte) bool {
- *m = certificateMsgTLS13{raw: data}
- s := cryptobyte.String(data)
-
- var context cryptobyte.String
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||
- !unmarshalCertificate(&s, &m.certificate) ||
- !s.Empty() {
- return false
- }
-
- m.scts = m.certificate.SignedCertificateTimestamps != nil
- m.ocspStapling = m.certificate.OCSPStaple != nil
-
- return true
-}
-
-func unmarshalCertificate(s *cryptobyte.String, certificate *Certificate) bool {
- var certList cryptobyte.String
- if !s.ReadUint24LengthPrefixed(&certList) {
- return false
- }
- for !certList.Empty() {
- var cert []byte
- var extensions cryptobyte.String
- if !readUint24LengthPrefixed(&certList, &cert) ||
- !certList.ReadUint16LengthPrefixed(&extensions) {
- return false
- }
- certificate.Certificate = append(certificate.Certificate, cert)
- for !extensions.Empty() {
- var extension uint16
- var extData cryptobyte.String
- if !extensions.ReadUint16(&extension) ||
- !extensions.ReadUint16LengthPrefixed(&extData) {
- return false
- }
- if len(certificate.Certificate) > 1 {
- // This library only supports OCSP and SCT for leaf certificates.
- continue
- }
-
- switch extension {
- case extensionStatusRequest:
- var statusType uint8
- if !extData.ReadUint8(&statusType) || statusType != statusTypeOCSP ||
- !readUint24LengthPrefixed(&extData, &certificate.OCSPStaple) ||
- len(certificate.OCSPStaple) == 0 {
- return false
- }
- case extensionSCT:
- var sctList cryptobyte.String
- if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {
- return false
- }
- for !sctList.Empty() {
- var sct []byte
- if !readUint16LengthPrefixed(&sctList, &sct) ||
- len(sct) == 0 {
- return false
- }
- certificate.SignedCertificateTimestamps = append(
- certificate.SignedCertificateTimestamps, sct)
- }
- default:
- // Ignore unknown extensions.
- continue
- }
-
- if !extData.Empty() {
- return false
- }
- }
- }
- return true
-}
-
-type serverKeyExchangeMsg struct {
- raw []byte
- key []byte
-}
-
-func (m *serverKeyExchangeMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- length := len(m.key)
- x := make([]byte, length+4)
- x[0] = typeServerKeyExchange
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- copy(x[4:], m.key)
-
- m.raw = x
- return x, nil
-}
-
-func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
- m.raw = data
- if len(data) < 4 {
- return false
- }
- m.key = data[4:]
- return true
-}
-
-type certificateStatusMsg struct {
- raw []byte
- response []byte
-}
-
-func (m *certificateStatusMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- var b cryptobyte.Builder
- b.AddUint8(typeCertificateStatus)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddUint8(statusTypeOCSP)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.response)
- })
- })
-
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
-}
-
-func (m *certificateStatusMsg) unmarshal(data []byte) bool {
- m.raw = data
- s := cryptobyte.String(data)
-
- var statusType uint8
- if !s.Skip(4) || // message type and uint24 length field
- !s.ReadUint8(&statusType) || statusType != statusTypeOCSP ||
- !readUint24LengthPrefixed(&s, &m.response) ||
- len(m.response) == 0 || !s.Empty() {
- return false
- }
- return true
-}
-
-type serverHelloDoneMsg struct{}
-
-func (m *serverHelloDoneMsg) marshal() ([]byte, error) {
- x := make([]byte, 4)
- x[0] = typeServerHelloDone
- return x, nil
-}
-
-func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
- return len(data) == 4
-}
-
-type clientKeyExchangeMsg struct {
- raw []byte
- ciphertext []byte
-}
-
-func (m *clientKeyExchangeMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
- length := len(m.ciphertext)
- x := make([]byte, length+4)
- x[0] = typeClientKeyExchange
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- copy(x[4:], m.ciphertext)
-
- m.raw = x
- return x, nil
-}
-
-func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
- m.raw = data
- if len(data) < 4 {
- return false
- }
- l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
- if l != len(data)-4 {
- return false
- }
- m.ciphertext = data[4:]
- return true
-}
-
-type finishedMsg struct {
- raw []byte
- verifyData []byte
-}
-
-func (m *finishedMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- var b cryptobyte.Builder
- b.AddUint8(typeFinished)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.verifyData)
- })
-
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
-}
-
-func (m *finishedMsg) unmarshal(data []byte) bool {
- m.raw = data
- s := cryptobyte.String(data)
- return s.Skip(1) &&
- readUint24LengthPrefixed(&s, &m.verifyData) &&
- s.Empty()
-}
-
-type certificateRequestMsg struct {
- raw []byte
- // hasSignatureAlgorithm indicates whether this message includes a list of
- // supported signature algorithms. This change was introduced with TLS 1.2.
- hasSignatureAlgorithm bool
-
- certificateTypes []byte
- supportedSignatureAlgorithms []SignatureScheme
- certificateAuthorities [][]byte
-}
-
-func (m *certificateRequestMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- // See RFC 4346, Section 7.4.4.
- length := 1 + len(m.certificateTypes) + 2
- casLength := 0
- for _, ca := range m.certificateAuthorities {
- casLength += 2 + len(ca)
- }
- length += casLength
-
- if m.hasSignatureAlgorithm {
- length += 2 + 2*len(m.supportedSignatureAlgorithms)
- }
-
- x := make([]byte, 4+length)
- x[0] = typeCertificateRequest
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
-
- x[4] = uint8(len(m.certificateTypes))
-
- copy(x[5:], m.certificateTypes)
- y := x[5+len(m.certificateTypes):]
-
- if m.hasSignatureAlgorithm {
- n := len(m.supportedSignatureAlgorithms) * 2
- y[0] = uint8(n >> 8)
- y[1] = uint8(n)
- y = y[2:]
- for _, sigAlgo := range m.supportedSignatureAlgorithms {
- y[0] = uint8(sigAlgo >> 8)
- y[1] = uint8(sigAlgo)
- y = y[2:]
- }
- }
-
- y[0] = uint8(casLength >> 8)
- y[1] = uint8(casLength)
- y = y[2:]
- for _, ca := range m.certificateAuthorities {
- y[0] = uint8(len(ca) >> 8)
- y[1] = uint8(len(ca))
- y = y[2:]
- copy(y, ca)
- y = y[len(ca):]
- }
-
- m.raw = x
- return m.raw, nil
-}
-
-func (m *certificateRequestMsg) unmarshal(data []byte) bool {
- m.raw = data
-
- if len(data) < 5 {
- return false
- }
-
- length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
- if uint32(len(data))-4 != length {
- return false
- }
-
- numCertTypes := int(data[4])
- data = data[5:]
- if numCertTypes == 0 || len(data) <= numCertTypes {
- return false
- }
-
- m.certificateTypes = make([]byte, numCertTypes)
- if copy(m.certificateTypes, data) != numCertTypes {
- return false
- }
-
- data = data[numCertTypes:]
-
- if m.hasSignatureAlgorithm {
- if len(data) < 2 {
- return false
- }
- sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
- data = data[2:]
- if sigAndHashLen&1 != 0 {
- return false
- }
- if len(data) < int(sigAndHashLen) {
- return false
- }
- numSigAlgos := sigAndHashLen / 2
- m.supportedSignatureAlgorithms = make([]SignatureScheme, numSigAlgos)
- for i := range m.supportedSignatureAlgorithms {
- m.supportedSignatureAlgorithms[i] = SignatureScheme(data[0])<<8 | SignatureScheme(data[1])
- data = data[2:]
- }
- }
-
- if len(data) < 2 {
- return false
- }
- casLength := uint16(data[0])<<8 | uint16(data[1])
- data = data[2:]
- if len(data) < int(casLength) {
- return false
- }
- cas := make([]byte, casLength)
- copy(cas, data)
- data = data[casLength:]
-
- m.certificateAuthorities = nil
- for len(cas) > 0 {
- if len(cas) < 2 {
- return false
- }
- caLen := uint16(cas[0])<<8 | uint16(cas[1])
- cas = cas[2:]
-
- if len(cas) < int(caLen) {
- return false
- }
-
- m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
- cas = cas[caLen:]
- }
-
- return len(data) == 0
-}
-
-type certificateVerifyMsg struct {
- raw []byte
- hasSignatureAlgorithm bool // format change introduced in TLS 1.2
- signatureAlgorithm SignatureScheme
- signature []byte
-}
-
-func (m *certificateVerifyMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- var b cryptobyte.Builder
- b.AddUint8(typeCertificateVerify)
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- if m.hasSignatureAlgorithm {
- b.AddUint16(uint16(m.signatureAlgorithm))
- }
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.signature)
- })
- })
-
- var err error
- m.raw, err = b.Bytes()
- return m.raw, err
-}
-
-func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
- m.raw = data
- s := cryptobyte.String(data)
-
- if !s.Skip(4) { // message type and uint24 length field
- return false
- }
- if m.hasSignatureAlgorithm {
- if !s.ReadUint16((*uint16)(&m.signatureAlgorithm)) {
- return false
- }
- }
- return readUint16LengthPrefixed(&s, &m.signature) && s.Empty()
-}
-
-type newSessionTicketMsg struct {
- raw []byte
- ticket []byte
-}
-
-func (m *newSessionTicketMsg) marshal() ([]byte, error) {
- if m.raw != nil {
- return m.raw, nil
- }
-
- // See RFC 5077, Section 3.3.
- ticketLen := len(m.ticket)
- length := 2 + 4 + ticketLen
- x := make([]byte, 4+length)
- x[0] = typeNewSessionTicket
- x[1] = uint8(length >> 16)
- x[2] = uint8(length >> 8)
- x[3] = uint8(length)
- x[8] = uint8(ticketLen >> 8)
- x[9] = uint8(ticketLen)
- copy(x[10:], m.ticket)
-
- m.raw = x
-
- return m.raw, nil
-}
-
-func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
- m.raw = data
-
- if len(data) < 10 {
- return false
- }
-
- length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
- if uint32(len(data))-4 != length {
- return false
- }
-
- ticketLen := int(data[8])<<8 + int(data[9])
- if len(data)-10 != ticketLen {
- return false
- }
-
- m.ticket = data[10:]
-
- return true
-}
-
-type helloRequestMsg struct {
-}
-
-func (*helloRequestMsg) marshal() ([]byte, error) {
- return []byte{typeHelloRequest, 0, 0, 0}, nil
-}
-
-func (*helloRequestMsg) unmarshal(data []byte) bool {
- return len(data) == 4
-}
-
-type transcriptHash interface {
- Write([]byte) (int, error)
-}
-
-// transcriptMsg is a helper used to marshal and hash messages which typically
-// are not written to the wire, and as such aren't hashed during Conn.writeRecord.
-func transcriptMsg(msg handshakeMessage, h transcriptHash) error {
- data, err := msg.marshal()
- if err != nil {
- return err
- }
- h.Write(data)
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/handshake_server.go b/contrib/go/_std_1.20/src/crypto/tls/handshake_server.go
deleted file mode 100644
index e22f284cfb..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/handshake_server.go
+++ /dev/null
@@ -1,890 +0,0 @@
-// Copyright 2009 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 tls
-
-import (
- "context"
- "crypto"
- "crypto/ecdsa"
- "crypto/ed25519"
- "crypto/rsa"
- "crypto/subtle"
- "crypto/x509"
- "errors"
- "fmt"
- "hash"
- "io"
- "time"
-)
-
-// serverHandshakeState contains details of a server handshake in progress.
-// It's discarded once the handshake has completed.
-type serverHandshakeState struct {
- c *Conn
- ctx context.Context
- clientHello *clientHelloMsg
- hello *serverHelloMsg
- suite *cipherSuite
- ecdheOk bool
- ecSignOk bool
- rsaDecryptOk bool
- rsaSignOk bool
- sessionState *sessionState
- finishedHash finishedHash
- masterSecret []byte
- cert *Certificate
-}
-
-// serverHandshake performs a TLS handshake as a server.
-func (c *Conn) serverHandshake(ctx context.Context) error {
- clientHello, err := c.readClientHello(ctx)
- if err != nil {
- return err
- }
-
- if c.vers == VersionTLS13 {
- hs := serverHandshakeStateTLS13{
- c: c,
- ctx: ctx,
- clientHello: clientHello,
- }
- return hs.handshake()
- }
-
- hs := serverHandshakeState{
- c: c,
- ctx: ctx,
- clientHello: clientHello,
- }
- return hs.handshake()
-}
-
-func (hs *serverHandshakeState) handshake() error {
- c := hs.c
-
- if err := hs.processClientHello(); err != nil {
- return err
- }
-
- // For an overview of TLS handshaking, see RFC 5246, Section 7.3.
- c.buffering = true
- if hs.checkForResumption() {
- // The client has included a session ticket and so we do an abbreviated handshake.
- c.didResume = true
- if err := hs.doResumeHandshake(); err != nil {
- return err
- }
- if err := hs.establishKeys(); err != nil {
- return err
- }
- if err := hs.sendSessionTicket(); err != nil {
- return err
- }
- if err := hs.sendFinished(c.serverFinished[:]); err != nil {
- return err
- }
- if _, err := c.flush(); err != nil {
- return err
- }
- c.clientFinishedIsFirst = false
- if err := hs.readFinished(nil); err != nil {
- return err
- }
- } else {
- // The client didn't include a session ticket, or it wasn't
- // valid so we do a full handshake.
- if err := hs.pickCipherSuite(); err != nil {
- return err
- }
- if err := hs.doFullHandshake(); err != nil {
- return err
- }
- if err := hs.establishKeys(); err != nil {
- return err
- }
- if err := hs.readFinished(c.clientFinished[:]); err != nil {
- return err
- }
- c.clientFinishedIsFirst = true
- c.buffering = true
- if err := hs.sendSessionTicket(); err != nil {
- return err
- }
- if err := hs.sendFinished(nil); err != nil {
- return err
- }
- if _, err := c.flush(); err != nil {
- return err
- }
- }
-
- c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random)
- c.isHandshakeComplete.Store(true)
-
- return nil
-}
-
-// readClientHello reads a ClientHello message and selects the protocol version.
-func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
- // clientHelloMsg is included in the transcript, but we haven't initialized
- // it yet. The respective handshake functions will record it themselves.
- msg, err := c.readHandshake(nil)
- if err != nil {
- return nil, err
- }
- clientHello, ok := msg.(*clientHelloMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return nil, unexpectedMessageError(clientHello, msg)
- }
-
- var configForClient *Config
- originalConfig := c.config
- if c.config.GetConfigForClient != nil {
- chi := clientHelloInfo(ctx, c, clientHello)
- if configForClient, err = c.config.GetConfigForClient(chi); err != nil {
- c.sendAlert(alertInternalError)
- return nil, err
- } else if configForClient != nil {
- c.config = configForClient
- }
- }
- c.ticketKeys = originalConfig.ticketKeys(configForClient)
-
- clientVersions := clientHello.supportedVersions
- if len(clientHello.supportedVersions) == 0 {
- clientVersions = supportedVersionsFromMax(clientHello.vers)
- }
- c.vers, ok = c.config.mutualVersion(roleServer, clientVersions)
- if !ok {
- c.sendAlert(alertProtocolVersion)
- return nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions)
- }
- c.haveVers = true
- c.in.version = c.vers
- c.out.version = c.vers
-
- return clientHello, nil
-}
-
-func (hs *serverHandshakeState) processClientHello() error {
- c := hs.c
-
- hs.hello = new(serverHelloMsg)
- hs.hello.vers = c.vers
-
- foundCompression := false
- // We only support null compression, so check that the client offered it.
- for _, compression := range hs.clientHello.compressionMethods {
- if compression == compressionNone {
- foundCompression = true
- break
- }
- }
-
- if !foundCompression {
- c.sendAlert(alertHandshakeFailure)
- return errors.New("tls: client does not support uncompressed connections")
- }
-
- hs.hello.random = make([]byte, 32)
- serverRandom := hs.hello.random
- // Downgrade protection canaries. See RFC 8446, Section 4.1.3.
- maxVers := c.config.maxSupportedVersion(roleServer)
- if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary {
- if c.vers == VersionTLS12 {
- copy(serverRandom[24:], downgradeCanaryTLS12)
- } else {
- copy(serverRandom[24:], downgradeCanaryTLS11)
- }
- serverRandom = serverRandom[:24]
- }
- _, err := io.ReadFull(c.config.rand(), serverRandom)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
-
- if len(hs.clientHello.secureRenegotiation) != 0 {
- c.sendAlert(alertHandshakeFailure)
- return errors.New("tls: initial handshake had non-empty renegotiation extension")
- }
-
- hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported
- hs.hello.compressionMethod = compressionNone
- if len(hs.clientHello.serverName) > 0 {
- c.serverName = hs.clientHello.serverName
- }
-
- selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
- if err != nil {
- c.sendAlert(alertNoApplicationProtocol)
- return err
- }
- hs.hello.alpnProtocol = selectedProto
- c.clientProtocol = selectedProto
-
- hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
- if err != nil {
- if err == errNoCertificates {
- c.sendAlert(alertUnrecognizedName)
- } else {
- c.sendAlert(alertInternalError)
- }
- return err
- }
- if hs.clientHello.scts {
- hs.hello.scts = hs.cert.SignedCertificateTimestamps
- }
-
- hs.ecdheOk = supportsECDHE(c.config, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints)
-
- if hs.ecdheOk && len(hs.clientHello.supportedPoints) > 0 {
- // Although omitting the ec_point_formats extension is permitted, some
- // old OpenSSL version will refuse to handshake if not present.
- //
- // Per RFC 4492, section 5.1.2, implementations MUST support the
- // uncompressed point format. See golang.org/issue/31943.
- hs.hello.supportedPoints = []uint8{pointFormatUncompressed}
- }
-
- if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok {
- switch priv.Public().(type) {
- case *ecdsa.PublicKey:
- hs.ecSignOk = true
- case ed25519.PublicKey:
- hs.ecSignOk = true
- case *rsa.PublicKey:
- hs.rsaSignOk = true
- default:
- c.sendAlert(alertInternalError)
- return fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public())
- }
- }
- if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok {
- switch priv.Public().(type) {
- case *rsa.PublicKey:
- hs.rsaDecryptOk = true
- default:
- c.sendAlert(alertInternalError)
- return fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public())
- }
- }
-
- return nil
-}
-
-// negotiateALPN picks a shared ALPN protocol that both sides support in server
-// preference order. If ALPN is not configured or the peer doesn't support it,
-// it returns "" and no error.
-func negotiateALPN(serverProtos, clientProtos []string) (string, error) {
- if len(serverProtos) == 0 || len(clientProtos) == 0 {
- return "", nil
- }
- var http11fallback bool
- for _, s := range serverProtos {
- for _, c := range clientProtos {
- if s == c {
- return s, nil
- }
- if s == "h2" && c == "http/1.1" {
- http11fallback = true
- }
- }
- }
- // As a special case, let http/1.1 clients connect to h2 servers as if they
- // didn't support ALPN. We used not to enforce protocol overlap, so over
- // time a number of HTTP servers were configured with only "h2", but
- // expected to accept connections from "http/1.1" clients. See Issue 46310.
- if http11fallback {
- return "", nil
- }
- return "", fmt.Errorf("tls: client requested unsupported application protocols (%s)", clientProtos)
-}
-
-// supportsECDHE returns whether ECDHE key exchanges can be used with this
-// pre-TLS 1.3 client.
-func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8) bool {
- supportsCurve := false
- for _, curve := range supportedCurves {
- if c.supportsCurve(curve) {
- supportsCurve = true
- break
- }
- }
-
- supportsPointFormat := false
- for _, pointFormat := range supportedPoints {
- if pointFormat == pointFormatUncompressed {
- supportsPointFormat = true
- break
- }
- }
- // Per RFC 8422, Section 5.1.2, if the Supported Point Formats extension is
- // missing, uncompressed points are supported. If supportedPoints is empty,
- // the extension must be missing, as an empty extension body is rejected by
- // the parser. See https://go.dev/issue/49126.
- if len(supportedPoints) == 0 {
- supportsPointFormat = true
- }
-
- return supportsCurve && supportsPointFormat
-}
-
-func (hs *serverHandshakeState) pickCipherSuite() error {
- c := hs.c
-
- preferenceOrder := cipherSuitesPreferenceOrder
- if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
- preferenceOrder = cipherSuitesPreferenceOrderNoAES
- }
-
- configCipherSuites := c.config.cipherSuites()
- preferenceList := make([]uint16, 0, len(configCipherSuites))
- for _, suiteID := range preferenceOrder {
- for _, id := range configCipherSuites {
- if id == suiteID {
- preferenceList = append(preferenceList, id)
- break
- }
- }
- }
-
- hs.suite = selectCipherSuite(preferenceList, hs.clientHello.cipherSuites, hs.cipherSuiteOk)
- if hs.suite == nil {
- c.sendAlert(alertHandshakeFailure)
- return errors.New("tls: no cipher suite supported by both client and server")
- }
- c.cipherSuite = hs.suite.id
-
- for _, id := range hs.clientHello.cipherSuites {
- if id == TLS_FALLBACK_SCSV {
- // The client is doing a fallback connection. See RFC 7507.
- if hs.clientHello.vers < c.config.maxSupportedVersion(roleServer) {
- c.sendAlert(alertInappropriateFallback)
- return errors.New("tls: client using inappropriate protocol fallback")
- }
- break
- }
- }
-
- return nil
-}
-
-func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool {
- if c.flags&suiteECDHE != 0 {
- if !hs.ecdheOk {
- return false
- }
- if c.flags&suiteECSign != 0 {
- if !hs.ecSignOk {
- return false
- }
- } else if !hs.rsaSignOk {
- return false
- }
- } else if !hs.rsaDecryptOk {
- return false
- }
- if hs.c.vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
- return false
- }
- return true
-}
-
-// checkForResumption reports whether we should perform resumption on this connection.
-func (hs *serverHandshakeState) checkForResumption() bool {
- c := hs.c
-
- if c.config.SessionTicketsDisabled {
- return false
- }
-
- plaintext, usedOldKey := c.decryptTicket(hs.clientHello.sessionTicket)
- if plaintext == nil {
- return false
- }
- hs.sessionState = &sessionState{usedOldKey: usedOldKey}
- ok := hs.sessionState.unmarshal(plaintext)
- if !ok {
- return false
- }
-
- createdAt := time.Unix(int64(hs.sessionState.createdAt), 0)
- if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
- return false
- }
-
- // Never resume a session for a different TLS version.
- if c.vers != hs.sessionState.vers {
- return false
- }
-
- cipherSuiteOk := false
- // Check that the client is still offering the ciphersuite in the session.
- for _, id := range hs.clientHello.cipherSuites {
- if id == hs.sessionState.cipherSuite {
- cipherSuiteOk = true
- break
- }
- }
- if !cipherSuiteOk {
- return false
- }
-
- // Check that we also support the ciphersuite from the session.
- hs.suite = selectCipherSuite([]uint16{hs.sessionState.cipherSuite},
- c.config.cipherSuites(), hs.cipherSuiteOk)
- if hs.suite == nil {
- return false
- }
-
- sessionHasClientCerts := len(hs.sessionState.certificates) != 0
- needClientCerts := requiresClientCert(c.config.ClientAuth)
- if needClientCerts && !sessionHasClientCerts {
- return false
- }
- if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
- return false
- }
-
- return true
-}
-
-func (hs *serverHandshakeState) doResumeHandshake() error {
- c := hs.c
-
- hs.hello.cipherSuite = hs.suite.id
- c.cipherSuite = hs.suite.id
- // We echo the client's session ID in the ServerHello to let it know
- // that we're doing a resumption.
- hs.hello.sessionId = hs.clientHello.sessionId
- hs.hello.ticketSupported = hs.sessionState.usedOldKey
- hs.finishedHash = newFinishedHash(c.vers, hs.suite)
- hs.finishedHash.discardHandshakeBuffer()
- if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil {
- return err
- }
- if _, err := hs.c.writeHandshakeRecord(hs.hello, &hs.finishedHash); err != nil {
- return err
- }
-
- if err := c.processCertsFromClient(Certificate{
- Certificate: hs.sessionState.certificates,
- }); err != nil {
- return err
- }
-
- if c.config.VerifyConnection != nil {
- if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
- c.sendAlert(alertBadCertificate)
- return err
- }
- }
-
- hs.masterSecret = hs.sessionState.masterSecret
-
- return nil
-}
-
-func (hs *serverHandshakeState) doFullHandshake() error {
- c := hs.c
-
- if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
- hs.hello.ocspStapling = true
- }
-
- hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled
- hs.hello.cipherSuite = hs.suite.id
-
- hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite)
- if c.config.ClientAuth == NoClientCert {
- // No need to keep a full record of the handshake if client
- // certificates won't be used.
- hs.finishedHash.discardHandshakeBuffer()
- }
- if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil {
- return err
- }
- if _, err := hs.c.writeHandshakeRecord(hs.hello, &hs.finishedHash); err != nil {
- return err
- }
-
- certMsg := new(certificateMsg)
- certMsg.certificates = hs.cert.Certificate
- if _, err := hs.c.writeHandshakeRecord(certMsg, &hs.finishedHash); err != nil {
- return err
- }
-
- if hs.hello.ocspStapling {
- certStatus := new(certificateStatusMsg)
- certStatus.response = hs.cert.OCSPStaple
- if _, err := hs.c.writeHandshakeRecord(certStatus, &hs.finishedHash); err != nil {
- return err
- }
- }
-
- keyAgreement := hs.suite.ka(c.vers)
- skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert, hs.clientHello, hs.hello)
- if err != nil {
- c.sendAlert(alertHandshakeFailure)
- return err
- }
- if skx != nil {
- if _, err := hs.c.writeHandshakeRecord(skx, &hs.finishedHash); err != nil {
- return err
- }
- }
-
- var certReq *certificateRequestMsg
- if c.config.ClientAuth >= RequestClientCert {
- // Request a client certificate
- certReq = new(certificateRequestMsg)
- certReq.certificateTypes = []byte{
- byte(certTypeRSASign),
- byte(certTypeECDSASign),
- }
- if c.vers >= VersionTLS12 {
- certReq.hasSignatureAlgorithm = true
- certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
- }
-
- // An empty list of certificateAuthorities signals to
- // the client that it may send any certificate in response
- // to our request. When we know the CAs we trust, then
- // we can send them down, so that the client can choose
- // an appropriate certificate to give to us.
- if c.config.ClientCAs != nil {
- certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
- }
- if _, err := hs.c.writeHandshakeRecord(certReq, &hs.finishedHash); err != nil {
- return err
- }
- }
-
- helloDone := new(serverHelloDoneMsg)
- if _, err := hs.c.writeHandshakeRecord(helloDone, &hs.finishedHash); err != nil {
- return err
- }
-
- if _, err := c.flush(); err != nil {
- return err
- }
-
- var pub crypto.PublicKey // public key for client auth, if any
-
- msg, err := c.readHandshake(&hs.finishedHash)
- if err != nil {
- return err
- }
-
- // If we requested a client certificate, then the client must send a
- // certificate message, even if it's empty.
- if c.config.ClientAuth >= RequestClientCert {
- certMsg, ok := msg.(*certificateMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(certMsg, msg)
- }
-
- if err := c.processCertsFromClient(Certificate{
- Certificate: certMsg.certificates,
- }); err != nil {
- return err
- }
- if len(certMsg.certificates) != 0 {
- pub = c.peerCertificates[0].PublicKey
- }
-
- msg, err = c.readHandshake(&hs.finishedHash)
- if err != nil {
- return err
- }
- }
- if c.config.VerifyConnection != nil {
- if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
- c.sendAlert(alertBadCertificate)
- return err
- }
- }
-
- // Get client key exchange
- ckx, ok := msg.(*clientKeyExchangeMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(ckx, msg)
- }
-
- preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers)
- if err != nil {
- c.sendAlert(alertHandshakeFailure)
- return err
- }
- hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random)
- if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
-
- // If we received a client cert in response to our certificate request message,
- // the client will send us a certificateVerifyMsg immediately after the
- // clientKeyExchangeMsg. This message is a digest of all preceding
- // handshake-layer messages that is signed using the private key corresponding
- // to the client's certificate. This allows us to verify that the client is in
- // possession of the private key of the certificate.
- if len(c.peerCertificates) > 0 {
- // certificateVerifyMsg is included in the transcript, but not until
- // after we verify the handshake signature, since the state before
- // this message was sent is used.
- msg, err = c.readHandshake(nil)
- if err != nil {
- return err
- }
- certVerify, ok := msg.(*certificateVerifyMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(certVerify, msg)
- }
-
- var sigType uint8
- var sigHash crypto.Hash
- if c.vers >= VersionTLS12 {
- if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: client certificate used with invalid signature algorithm")
- }
- sigType, sigHash, err = typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
- if err != nil {
- return c.sendAlert(alertInternalError)
- }
- } else {
- sigType, sigHash, err = legacyTypeAndHashFromPublicKey(pub)
- if err != nil {
- c.sendAlert(alertIllegalParameter)
- return err
- }
- }
-
- signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash)
- if err := verifyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil {
- c.sendAlert(alertDecryptError)
- return errors.New("tls: invalid signature by the client certificate: " + err.Error())
- }
-
- if err := transcriptMsg(certVerify, &hs.finishedHash); err != nil {
- return err
- }
- }
-
- hs.finishedHash.discardHandshakeBuffer()
-
- return nil
-}
-
-func (hs *serverHandshakeState) establishKeys() error {
- c := hs.c
-
- clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
- keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
-
- var clientCipher, serverCipher any
- var clientHash, serverHash hash.Hash
-
- if hs.suite.aead == nil {
- clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
- clientHash = hs.suite.mac(clientMAC)
- serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
- serverHash = hs.suite.mac(serverMAC)
- } else {
- clientCipher = hs.suite.aead(clientKey, clientIV)
- serverCipher = hs.suite.aead(serverKey, serverIV)
- }
-
- c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
- c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
-
- return nil
-}
-
-func (hs *serverHandshakeState) readFinished(out []byte) error {
- c := hs.c
-
- if err := c.readChangeCipherSpec(); err != nil {
- return err
- }
-
- // finishedMsg is included in the transcript, but not until after we
- // check the client version, since the state before this message was
- // sent is used during verification.
- msg, err := c.readHandshake(nil)
- if err != nil {
- return err
- }
- clientFinished, ok := msg.(*finishedMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(clientFinished, msg)
- }
-
- verify := hs.finishedHash.clientSum(hs.masterSecret)
- if len(verify) != len(clientFinished.verifyData) ||
- subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
- c.sendAlert(alertHandshakeFailure)
- return errors.New("tls: client's Finished message is incorrect")
- }
-
- if err := transcriptMsg(clientFinished, &hs.finishedHash); err != nil {
- return err
- }
-
- copy(out, verify)
- return nil
-}
-
-func (hs *serverHandshakeState) sendSessionTicket() error {
- // ticketSupported is set in a resumption handshake if the
- // ticket from the client was encrypted with an old session
- // ticket key and thus a refreshed ticket should be sent.
- if !hs.hello.ticketSupported {
- return nil
- }
-
- c := hs.c
- m := new(newSessionTicketMsg)
-
- createdAt := uint64(c.config.time().Unix())
- if hs.sessionState != nil {
- // If this is re-wrapping an old key, then keep
- // the original time it was created.
- createdAt = hs.sessionState.createdAt
- }
-
- var certsFromClient [][]byte
- for _, cert := range c.peerCertificates {
- certsFromClient = append(certsFromClient, cert.Raw)
- }
- state := sessionState{
- vers: c.vers,
- cipherSuite: hs.suite.id,
- createdAt: createdAt,
- masterSecret: hs.masterSecret,
- certificates: certsFromClient,
- }
- stateBytes, err := state.marshal()
- if err != nil {
- return err
- }
- m.ticket, err = c.encryptTicket(stateBytes)
- if err != nil {
- return err
- }
-
- if _, err := hs.c.writeHandshakeRecord(m, &hs.finishedHash); err != nil {
- return err
- }
-
- return nil
-}
-
-func (hs *serverHandshakeState) sendFinished(out []byte) error {
- c := hs.c
-
- if err := c.writeChangeCipherRecord(); err != nil {
- return err
- }
-
- finished := new(finishedMsg)
- finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
- if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil {
- return err
- }
-
- copy(out, finished.verifyData)
-
- return nil
-}
-
-// processCertsFromClient takes a chain of client certificates either from a
-// Certificates message or from a sessionState and verifies them. It returns
-// the public key of the leaf certificate.
-func (c *Conn) processCertsFromClient(certificate Certificate) error {
- certificates := certificate.Certificate
- certs := make([]*x509.Certificate, len(certificates))
- var err error
- for i, asn1Data := range certificates {
- if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
- c.sendAlert(alertBadCertificate)
- return errors.New("tls: failed to parse client certificate: " + err.Error())
- }
- }
-
- if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) {
- c.sendAlert(alertBadCertificate)
- return errors.New("tls: client didn't provide a certificate")
- }
-
- if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
- opts := x509.VerifyOptions{
- Roots: c.config.ClientCAs,
- CurrentTime: c.config.time(),
- Intermediates: x509.NewCertPool(),
- KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
- }
-
- for _, cert := range certs[1:] {
- opts.Intermediates.AddCert(cert)
- }
-
- chains, err := certs[0].Verify(opts)
- if err != nil {
- c.sendAlert(alertBadCertificate)
- return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
- }
-
- c.verifiedChains = chains
- }
-
- c.peerCertificates = certs
- c.ocspResponse = certificate.OCSPStaple
- c.scts = certificate.SignedCertificateTimestamps
-
- if len(certs) > 0 {
- switch certs[0].PublicKey.(type) {
- case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:
- default:
- c.sendAlert(alertUnsupportedCertificate)
- return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey)
- }
- }
-
- if c.config.VerifyPeerCertificate != nil {
- if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
- c.sendAlert(alertBadCertificate)
- return err
- }
- }
-
- return nil
-}
-
-func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
- supportedVersions := clientHello.supportedVersions
- if len(clientHello.supportedVersions) == 0 {
- supportedVersions = supportedVersionsFromMax(clientHello.vers)
- }
-
- return &ClientHelloInfo{
- CipherSuites: clientHello.cipherSuites,
- ServerName: clientHello.serverName,
- SupportedCurves: clientHello.supportedCurves,
- SupportedPoints: clientHello.supportedPoints,
- SignatureSchemes: clientHello.supportedSignatureAlgorithms,
- SupportedProtos: clientHello.alpnProtocols,
- SupportedVersions: supportedVersions,
- Conn: c.conn,
- config: c.config,
- ctx: ctx,
- }
-}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/handshake_server_tls13.go b/contrib/go/_std_1.20/src/crypto/tls/handshake_server_tls13.go
deleted file mode 100644
index b7b568cd84..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/handshake_server_tls13.go
+++ /dev/null
@@ -1,893 +0,0 @@
-// Copyright 2018 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 tls
-
-import (
- "bytes"
- "context"
- "crypto"
- "crypto/hmac"
- "crypto/rsa"
- "encoding/binary"
- "errors"
- "hash"
- "io"
- "time"
-)
-
-// maxClientPSKIdentities is the number of client PSK identities the server will
-// attempt to validate. It will ignore the rest not to let cheap ClientHello
-// messages cause too much work in session ticket decryption attempts.
-const maxClientPSKIdentities = 5
-
-type serverHandshakeStateTLS13 struct {
- c *Conn
- ctx context.Context
- clientHello *clientHelloMsg
- hello *serverHelloMsg
- sentDummyCCS bool
- usingPSK bool
- suite *cipherSuiteTLS13
- cert *Certificate
- sigAlg SignatureScheme
- earlySecret []byte
- sharedKey []byte
- handshakeSecret []byte
- masterSecret []byte
- trafficSecret []byte // client_application_traffic_secret_0
- transcript hash.Hash
- clientFinished []byte
-}
-
-func (hs *serverHandshakeStateTLS13) handshake() error {
- c := hs.c
-
- if needFIPS() {
- return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
- }
-
- // For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2.
- if err := hs.processClientHello(); err != nil {
- return err
- }
- if err := hs.checkForResumption(); err != nil {
- return err
- }
- if err := hs.pickCertificate(); err != nil {
- return err
- }
- c.buffering = true
- if err := hs.sendServerParameters(); err != nil {
- return err
- }
- if err := hs.sendServerCertificate(); err != nil {
- return err
- }
- if err := hs.sendServerFinished(); err != nil {
- return err
- }
- // Note that at this point we could start sending application data without
- // waiting for the client's second flight, but the application might not
- // expect the lack of replay protection of the ClientHello parameters.
- if _, err := c.flush(); err != nil {
- return err
- }
- if err := hs.readClientCertificate(); err != nil {
- return err
- }
- if err := hs.readClientFinished(); err != nil {
- return err
- }
-
- c.isHandshakeComplete.Store(true)
-
- return nil
-}
-
-func (hs *serverHandshakeStateTLS13) processClientHello() error {
- c := hs.c
-
- hs.hello = new(serverHelloMsg)
-
- // TLS 1.3 froze the ServerHello.legacy_version field, and uses
- // supported_versions instead. See RFC 8446, sections 4.1.3 and 4.2.1.
- hs.hello.vers = VersionTLS12
- hs.hello.supportedVersion = c.vers
-
- if len(hs.clientHello.supportedVersions) == 0 {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: client used the legacy version field to negotiate TLS 1.3")
- }
-
- // Abort if the client is doing a fallback and landing lower than what we
- // support. See RFC 7507, which however does not specify the interaction
- // with supported_versions. The only difference is that with
- // supported_versions a client has a chance to attempt a [TLS 1.2, TLS 1.4]
- // handshake in case TLS 1.3 is broken but 1.2 is not. Alas, in that case,
- // it will have to drop the TLS_FALLBACK_SCSV protection if it falls back to
- // TLS 1.2, because a TLS 1.3 server would abort here. The situation before
- // supported_versions was not better because there was just no way to do a
- // TLS 1.4 handshake without risking the server selecting TLS 1.3.
- for _, id := range hs.clientHello.cipherSuites {
- if id == TLS_FALLBACK_SCSV {
- // Use c.vers instead of max(supported_versions) because an attacker
- // could defeat this by adding an arbitrary high version otherwise.
- if c.vers < c.config.maxSupportedVersion(roleServer) {
- c.sendAlert(alertInappropriateFallback)
- return errors.New("tls: client using inappropriate protocol fallback")
- }
- break
- }
- }
-
- if len(hs.clientHello.compressionMethods) != 1 ||
- hs.clientHello.compressionMethods[0] != compressionNone {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: TLS 1.3 client supports illegal compression methods")
- }
-
- hs.hello.random = make([]byte, 32)
- if _, err := io.ReadFull(c.config.rand(), hs.hello.random); err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
-
- if len(hs.clientHello.secureRenegotiation) != 0 {
- c.sendAlert(alertHandshakeFailure)
- return errors.New("tls: initial handshake had non-empty renegotiation extension")
- }
-
- if hs.clientHello.earlyData {
- // See RFC 8446, Section 4.2.10 for the complicated behavior required
- // here. The scenario is that a different server at our address offered
- // to accept early data in the past, which we can't handle. For now, all
- // 0-RTT enabled session tickets need to expire before a Go server can
- // replace a server or join a pool. That's the same requirement that
- // applies to mixing or replacing with any TLS 1.2 server.
- c.sendAlert(alertUnsupportedExtension)
- return errors.New("tls: client sent unexpected early data")
- }
-
- hs.hello.sessionId = hs.clientHello.sessionId
- hs.hello.compressionMethod = compressionNone
-
- preferenceList := defaultCipherSuitesTLS13
- if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
- preferenceList = defaultCipherSuitesTLS13NoAES
- }
- for _, suiteID := range preferenceList {
- hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID)
- if hs.suite != nil {
- break
- }
- }
- if hs.suite == nil {
- c.sendAlert(alertHandshakeFailure)
- return errors.New("tls: no cipher suite supported by both client and server")
- }
- c.cipherSuite = hs.suite.id
- hs.hello.cipherSuite = hs.suite.id
- hs.transcript = hs.suite.hash.New()
-
- // Pick the ECDHE group in server preference order, but give priority to
- // groups with a key share, to avoid a HelloRetryRequest round-trip.
- var selectedGroup CurveID
- var clientKeyShare *keyShare
-GroupSelection:
- for _, preferredGroup := range c.config.curvePreferences() {
- for _, ks := range hs.clientHello.keyShares {
- if ks.group == preferredGroup {
- selectedGroup = ks.group
- clientKeyShare = &ks
- break GroupSelection
- }
- }
- if selectedGroup != 0 {
- continue
- }
- for _, group := range hs.clientHello.supportedCurves {
- if group == preferredGroup {
- selectedGroup = group
- break
- }
- }
- }
- if selectedGroup == 0 {
- c.sendAlert(alertHandshakeFailure)
- return errors.New("tls: no ECDHE curve supported by both client and server")
- }
- if clientKeyShare == nil {
- if err := hs.doHelloRetryRequest(selectedGroup); err != nil {
- return err
- }
- clientKeyShare = &hs.clientHello.keyShares[0]
- }
-
- if _, ok := curveForCurveID(selectedGroup); !ok {
- c.sendAlert(alertInternalError)
- return errors.New("tls: CurvePreferences includes unsupported curve")
- }
- key, err := generateECDHEKey(c.config.rand(), selectedGroup)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
- hs.hello.serverShare = keyShare{group: selectedGroup, data: key.PublicKey().Bytes()}
- peerKey, err := key.Curve().NewPublicKey(clientKeyShare.data)
- if err != nil {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: invalid client key share")
- }
- hs.sharedKey, err = key.ECDH(peerKey)
- if err != nil {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: invalid client key share")
- }
-
- c.serverName = hs.clientHello.serverName
- return nil
-}
-
-func (hs *serverHandshakeStateTLS13) checkForResumption() error {
- c := hs.c
-
- if c.config.SessionTicketsDisabled {
- return nil
- }
-
- modeOK := false
- for _, mode := range hs.clientHello.pskModes {
- if mode == pskModeDHE {
- modeOK = true
- break
- }
- }
- if !modeOK {
- return nil
- }
-
- if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: invalid or missing PSK binders")
- }
- if len(hs.clientHello.pskIdentities) == 0 {
- return nil
- }
-
- for i, identity := range hs.clientHello.pskIdentities {
- if i >= maxClientPSKIdentities {
- break
- }
-
- plaintext, _ := c.decryptTicket(identity.label)
- if plaintext == nil {
- continue
- }
- sessionState := new(sessionStateTLS13)
- if ok := sessionState.unmarshal(plaintext); !ok {
- continue
- }
-
- createdAt := time.Unix(int64(sessionState.createdAt), 0)
- if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
- continue
- }
-
- // We don't check the obfuscated ticket age because it's affected by
- // clock skew and it's only a freshness signal useful for shrinking the
- // window for replay attacks, which don't affect us as we don't do 0-RTT.
-
- pskSuite := cipherSuiteTLS13ByID(sessionState.cipherSuite)
- if pskSuite == nil || pskSuite.hash != hs.suite.hash {
- continue
- }
-
- // PSK connections don't re-establish client certificates, but carry
- // them over in the session ticket. Ensure the presence of client certs
- // in the ticket is consistent with the configured requirements.
- sessionHasClientCerts := len(sessionState.certificate.Certificate) != 0
- needClientCerts := requiresClientCert(c.config.ClientAuth)
- if needClientCerts && !sessionHasClientCerts {
- continue
- }
- if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
- continue
- }
-
- psk := hs.suite.expandLabel(sessionState.resumptionSecret, "resumption",
- nil, hs.suite.hash.Size())
- hs.earlySecret = hs.suite.extract(psk, nil)
- binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil)
- // Clone the transcript in case a HelloRetryRequest was recorded.
- transcript := cloneHash(hs.transcript, hs.suite.hash)
- if transcript == nil {
- c.sendAlert(alertInternalError)
- return errors.New("tls: internal error: failed to clone hash")
- }
- clientHelloBytes, err := hs.clientHello.marshalWithoutBinders()
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
- transcript.Write(clientHelloBytes)
- pskBinder := hs.suite.finishedHash(binderKey, transcript)
- if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) {
- c.sendAlert(alertDecryptError)
- return errors.New("tls: invalid PSK binder")
- }
-
- c.didResume = true
- if err := c.processCertsFromClient(sessionState.certificate); err != nil {
- return err
- }
-
- hs.hello.selectedIdentityPresent = true
- hs.hello.selectedIdentity = uint16(i)
- hs.usingPSK = true
- return nil
- }
-
- return nil
-}
-
-// cloneHash uses the encoding.BinaryMarshaler and encoding.BinaryUnmarshaler
-// interfaces implemented by standard library hashes to clone the state of in
-// to a new instance of h. It returns nil if the operation fails.
-func cloneHash(in hash.Hash, h crypto.Hash) hash.Hash {
- // Recreate the interface to avoid importing encoding.
- type binaryMarshaler interface {
- MarshalBinary() (data []byte, err error)
- UnmarshalBinary(data []byte) error
- }
- marshaler, ok := in.(binaryMarshaler)
- if !ok {
- return nil
- }
- state, err := marshaler.MarshalBinary()
- if err != nil {
- return nil
- }
- out := h.New()
- unmarshaler, ok := out.(binaryMarshaler)
- if !ok {
- return nil
- }
- if err := unmarshaler.UnmarshalBinary(state); err != nil {
- return nil
- }
- return out
-}
-
-func (hs *serverHandshakeStateTLS13) pickCertificate() error {
- c := hs.c
-
- // Only one of PSK and certificates are used at a time.
- if hs.usingPSK {
- return nil
- }
-
- // signature_algorithms is required in TLS 1.3. See RFC 8446, Section 4.2.3.
- if len(hs.clientHello.supportedSignatureAlgorithms) == 0 {
- return c.sendAlert(alertMissingExtension)
- }
-
- certificate, err := c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
- if err != nil {
- if err == errNoCertificates {
- c.sendAlert(alertUnrecognizedName)
- } else {
- c.sendAlert(alertInternalError)
- }
- return err
- }
- hs.sigAlg, err = selectSignatureScheme(c.vers, certificate, hs.clientHello.supportedSignatureAlgorithms)
- if err != nil {
- // getCertificate returned a certificate that is unsupported or
- // incompatible with the client's signature algorithms.
- c.sendAlert(alertHandshakeFailure)
- return err
- }
- hs.cert = certificate
-
- return nil
-}
-
-// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
-// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
-func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
- if hs.sentDummyCCS {
- return nil
- }
- hs.sentDummyCCS = true
-
- return hs.c.writeChangeCipherRecord()
-}
-
-func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error {
- c := hs.c
-
- // The first ClientHello gets double-hashed into the transcript upon a
- // HelloRetryRequest. See RFC 8446, Section 4.4.1.
- if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil {
- return err
- }
- chHash := hs.transcript.Sum(nil)
- hs.transcript.Reset()
- hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
- hs.transcript.Write(chHash)
-
- helloRetryRequest := &serverHelloMsg{
- vers: hs.hello.vers,
- random: helloRetryRequestRandom,
- sessionId: hs.hello.sessionId,
- cipherSuite: hs.hello.cipherSuite,
- compressionMethod: hs.hello.compressionMethod,
- supportedVersion: hs.hello.supportedVersion,
- selectedGroup: selectedGroup,
- }
-
- if _, err := hs.c.writeHandshakeRecord(helloRetryRequest, hs.transcript); err != nil {
- return err
- }
-
- if err := hs.sendDummyChangeCipherSpec(); err != nil {
- return err
- }
-
- // clientHelloMsg is not included in the transcript.
- msg, err := c.readHandshake(nil)
- if err != nil {
- return err
- }
-
- clientHello, ok := msg.(*clientHelloMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(clientHello, msg)
- }
-
- if len(clientHello.keyShares) != 1 || clientHello.keyShares[0].group != selectedGroup {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: client sent invalid key share in second ClientHello")
- }
-
- if clientHello.earlyData {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: client indicated early data in second ClientHello")
- }
-
- if illegalClientHelloChange(clientHello, hs.clientHello) {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: client illegally modified second ClientHello")
- }
-
- hs.clientHello = clientHello
- return nil
-}
-
-// illegalClientHelloChange reports whether the two ClientHello messages are
-// different, with the exception of the changes allowed before and after a
-// HelloRetryRequest. See RFC 8446, Section 4.1.2.
-func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool {
- if len(ch.supportedVersions) != len(ch1.supportedVersions) ||
- len(ch.cipherSuites) != len(ch1.cipherSuites) ||
- len(ch.supportedCurves) != len(ch1.supportedCurves) ||
- len(ch.supportedSignatureAlgorithms) != len(ch1.supportedSignatureAlgorithms) ||
- len(ch.supportedSignatureAlgorithmsCert) != len(ch1.supportedSignatureAlgorithmsCert) ||
- len(ch.alpnProtocols) != len(ch1.alpnProtocols) {
- return true
- }
- for i := range ch.supportedVersions {
- if ch.supportedVersions[i] != ch1.supportedVersions[i] {
- return true
- }
- }
- for i := range ch.cipherSuites {
- if ch.cipherSuites[i] != ch1.cipherSuites[i] {
- return true
- }
- }
- for i := range ch.supportedCurves {
- if ch.supportedCurves[i] != ch1.supportedCurves[i] {
- return true
- }
- }
- for i := range ch.supportedSignatureAlgorithms {
- if ch.supportedSignatureAlgorithms[i] != ch1.supportedSignatureAlgorithms[i] {
- return true
- }
- }
- for i := range ch.supportedSignatureAlgorithmsCert {
- if ch.supportedSignatureAlgorithmsCert[i] != ch1.supportedSignatureAlgorithmsCert[i] {
- return true
- }
- }
- for i := range ch.alpnProtocols {
- if ch.alpnProtocols[i] != ch1.alpnProtocols[i] {
- return true
- }
- }
- return ch.vers != ch1.vers ||
- !bytes.Equal(ch.random, ch1.random) ||
- !bytes.Equal(ch.sessionId, ch1.sessionId) ||
- !bytes.Equal(ch.compressionMethods, ch1.compressionMethods) ||
- ch.serverName != ch1.serverName ||
- ch.ocspStapling != ch1.ocspStapling ||
- !bytes.Equal(ch.supportedPoints, ch1.supportedPoints) ||
- ch.ticketSupported != ch1.ticketSupported ||
- !bytes.Equal(ch.sessionTicket, ch1.sessionTicket) ||
- ch.secureRenegotiationSupported != ch1.secureRenegotiationSupported ||
- !bytes.Equal(ch.secureRenegotiation, ch1.secureRenegotiation) ||
- ch.scts != ch1.scts ||
- !bytes.Equal(ch.cookie, ch1.cookie) ||
- !bytes.Equal(ch.pskModes, ch1.pskModes)
-}
-
-func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
- c := hs.c
-
- if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil {
- return err
- }
- if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil {
- return err
- }
-
- if err := hs.sendDummyChangeCipherSpec(); err != nil {
- return err
- }
-
- earlySecret := hs.earlySecret
- if earlySecret == nil {
- earlySecret = hs.suite.extract(nil, nil)
- }
- hs.handshakeSecret = hs.suite.extract(hs.sharedKey,
- hs.suite.deriveSecret(earlySecret, "derived", nil))
-
- clientSecret := hs.suite.deriveSecret(hs.handshakeSecret,
- clientHandshakeTrafficLabel, hs.transcript)
- c.in.setTrafficSecret(hs.suite, clientSecret)
- serverSecret := hs.suite.deriveSecret(hs.handshakeSecret,
- serverHandshakeTrafficLabel, hs.transcript)
- c.out.setTrafficSecret(hs.suite, serverSecret)
-
- err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
- err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.clientHello.random, serverSecret)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
-
- encryptedExtensions := new(encryptedExtensionsMsg)
-
- selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
- if err != nil {
- c.sendAlert(alertNoApplicationProtocol)
- return err
- }
- encryptedExtensions.alpnProtocol = selectedProto
- c.clientProtocol = selectedProto
-
- if _, err := hs.c.writeHandshakeRecord(encryptedExtensions, hs.transcript); err != nil {
- return err
- }
-
- return nil
-}
-
-func (hs *serverHandshakeStateTLS13) requestClientCert() bool {
- return hs.c.config.ClientAuth >= RequestClientCert && !hs.usingPSK
-}
-
-func (hs *serverHandshakeStateTLS13) sendServerCertificate() error {
- c := hs.c
-
- // Only one of PSK and certificates are used at a time.
- if hs.usingPSK {
- return nil
- }
-
- if hs.requestClientCert() {
- // Request a client certificate
- certReq := new(certificateRequestMsgTLS13)
- certReq.ocspStapling = true
- certReq.scts = true
- certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
- if c.config.ClientCAs != nil {
- certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
- }
-
- if _, err := hs.c.writeHandshakeRecord(certReq, hs.transcript); err != nil {
- return err
- }
- }
-
- certMsg := new(certificateMsgTLS13)
-
- certMsg.certificate = *hs.cert
- certMsg.scts = hs.clientHello.scts && len(hs.cert.SignedCertificateTimestamps) > 0
- certMsg.ocspStapling = hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0
-
- if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != nil {
- return err
- }
-
- certVerifyMsg := new(certificateVerifyMsg)
- certVerifyMsg.hasSignatureAlgorithm = true
- certVerifyMsg.signatureAlgorithm = hs.sigAlg
-
- sigType, sigHash, err := typeAndHashFromSignatureScheme(hs.sigAlg)
- if err != nil {
- return c.sendAlert(alertInternalError)
- }
-
- signed := signedMessage(sigHash, serverSignatureContext, hs.transcript)
- signOpts := crypto.SignerOpts(sigHash)
- if sigType == signatureRSAPSS {
- signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
- }
- sig, err := hs.cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts)
- if err != nil {
- public := hs.cert.PrivateKey.(crypto.Signer).Public()
- if rsaKey, ok := public.(*rsa.PublicKey); ok && sigType == signatureRSAPSS &&
- rsaKey.N.BitLen()/8 < sigHash.Size()*2+2 { // key too small for RSA-PSS
- c.sendAlert(alertHandshakeFailure)
- } else {
- c.sendAlert(alertInternalError)
- }
- return errors.New("tls: failed to sign handshake: " + err.Error())
- }
- certVerifyMsg.signature = sig
-
- if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); err != nil {
- return err
- }
-
- return nil
-}
-
-func (hs *serverHandshakeStateTLS13) sendServerFinished() error {
- c := hs.c
-
- finished := &finishedMsg{
- verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
- }
-
- if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != nil {
- return err
- }
-
- // Derive secrets that take context through the server Finished.
-
- hs.masterSecret = hs.suite.extract(nil,
- hs.suite.deriveSecret(hs.handshakeSecret, "derived", nil))
-
- hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret,
- clientApplicationTrafficLabel, hs.transcript)
- serverSecret := hs.suite.deriveSecret(hs.masterSecret,
- serverApplicationTrafficLabel, hs.transcript)
- c.out.setTrafficSecret(hs.suite, serverSecret)
-
- err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
- err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.clientHello.random, serverSecret)
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
-
- c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript)
-
- // If we did not request client certificates, at this point we can
- // precompute the client finished and roll the transcript forward to send
- // session tickets in our first flight.
- if !hs.requestClientCert() {
- if err := hs.sendSessionTickets(); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool {
- if hs.c.config.SessionTicketsDisabled {
- return false
- }
-
- // Don't send tickets the client wouldn't use. See RFC 8446, Section 4.2.9.
- for _, pskMode := range hs.clientHello.pskModes {
- if pskMode == pskModeDHE {
- return true
- }
- }
- return false
-}
-
-func (hs *serverHandshakeStateTLS13) sendSessionTickets() error {
- c := hs.c
-
- hs.clientFinished = hs.suite.finishedHash(c.in.trafficSecret, hs.transcript)
- finishedMsg := &finishedMsg{
- verifyData: hs.clientFinished,
- }
- if err := transcriptMsg(finishedMsg, hs.transcript); err != nil {
- return err
- }
-
- if !hs.shouldSendSessionTickets() {
- return nil
- }
-
- resumptionSecret := hs.suite.deriveSecret(hs.masterSecret,
- resumptionLabel, hs.transcript)
-
- m := new(newSessionTicketMsgTLS13)
-
- var certsFromClient [][]byte
- for _, cert := range c.peerCertificates {
- certsFromClient = append(certsFromClient, cert.Raw)
- }
- state := sessionStateTLS13{
- cipherSuite: hs.suite.id,
- createdAt: uint64(c.config.time().Unix()),
- resumptionSecret: resumptionSecret,
- certificate: Certificate{
- Certificate: certsFromClient,
- OCSPStaple: c.ocspResponse,
- SignedCertificateTimestamps: c.scts,
- },
- }
- stateBytes, err := state.marshal()
- if err != nil {
- c.sendAlert(alertInternalError)
- return err
- }
- m.label, err = c.encryptTicket(stateBytes)
- if err != nil {
- return err
- }
- m.lifetime = uint32(maxSessionTicketLifetime / time.Second)
-
- // ticket_age_add is a random 32-bit value. See RFC 8446, section 4.6.1
- // The value is not stored anywhere; we never need to check the ticket age
- // because 0-RTT is not supported.
- ageAdd := make([]byte, 4)
- _, err = hs.c.config.rand().Read(ageAdd)
- if err != nil {
- return err
- }
- m.ageAdd = binary.LittleEndian.Uint32(ageAdd)
-
- // ticket_nonce, which must be unique per connection, is always left at
- // zero because we only ever send one ticket per connection.
-
- if _, err := c.writeHandshakeRecord(m, nil); err != nil {
- return err
- }
-
- return nil
-}
-
-func (hs *serverHandshakeStateTLS13) readClientCertificate() error {
- c := hs.c
-
- if !hs.requestClientCert() {
- // Make sure the connection is still being verified whether or not
- // the server requested a client certificate.
- if c.config.VerifyConnection != nil {
- if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
- c.sendAlert(alertBadCertificate)
- return err
- }
- }
- return nil
- }
-
- // If we requested a client certificate, then the client must send a
- // certificate message. If it's empty, no CertificateVerify is sent.
-
- msg, err := c.readHandshake(hs.transcript)
- if err != nil {
- return err
- }
-
- certMsg, ok := msg.(*certificateMsgTLS13)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(certMsg, msg)
- }
-
- if err := c.processCertsFromClient(certMsg.certificate); err != nil {
- return err
- }
-
- if c.config.VerifyConnection != nil {
- if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
- c.sendAlert(alertBadCertificate)
- return err
- }
- }
-
- if len(certMsg.certificate.Certificate) != 0 {
- // certificateVerifyMsg is included in the transcript, but not until
- // after we verify the handshake signature, since the state before
- // this message was sent is used.
- msg, err = c.readHandshake(nil)
- if err != nil {
- return err
- }
-
- certVerify, ok := msg.(*certificateVerifyMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(certVerify, msg)
- }
-
- // See RFC 8446, Section 4.4.3.
- if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: client certificate used with invalid signature algorithm")
- }
- sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
- if err != nil {
- return c.sendAlert(alertInternalError)
- }
- if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 {
- c.sendAlert(alertIllegalParameter)
- return errors.New("tls: client certificate used with invalid signature algorithm")
- }
- signed := signedMessage(sigHash, clientSignatureContext, hs.transcript)
- if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey,
- sigHash, signed, certVerify.signature); err != nil {
- c.sendAlert(alertDecryptError)
- return errors.New("tls: invalid signature by the client certificate: " + err.Error())
- }
-
- if err := transcriptMsg(certVerify, hs.transcript); err != nil {
- return err
- }
- }
-
- // If we waited until the client certificates to send session tickets, we
- // are ready to do it now.
- if err := hs.sendSessionTickets(); err != nil {
- return err
- }
-
- return nil
-}
-
-func (hs *serverHandshakeStateTLS13) readClientFinished() error {
- c := hs.c
-
- // finishedMsg is not included in the transcript.
- msg, err := c.readHandshake(nil)
- if err != nil {
- return err
- }
-
- finished, ok := msg.(*finishedMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(finished, msg)
- }
-
- if !hmac.Equal(hs.clientFinished, finished.verifyData) {
- c.sendAlert(alertDecryptError)
- return errors.New("tls: invalid client finished hash")
- }
-
- c.in.setTrafficSecret(hs.suite, hs.trafficSecret)
-
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/key_schedule.go b/contrib/go/_std_1.20/src/crypto/tls/key_schedule.go
deleted file mode 100644
index ae8f80a7cf..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/key_schedule.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2018 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 tls
-
-import (
- "crypto/ecdh"
- "crypto/hmac"
- "errors"
- "fmt"
- "hash"
- "io"
-
- "golang.org/x/crypto/cryptobyte"
- "golang.org/x/crypto/hkdf"
-)
-
-// This file contains the functions necessary to compute the TLS 1.3 key
-// schedule. See RFC 8446, Section 7.
-
-const (
- resumptionBinderLabel = "res binder"
- clientHandshakeTrafficLabel = "c hs traffic"
- serverHandshakeTrafficLabel = "s hs traffic"
- clientApplicationTrafficLabel = "c ap traffic"
- serverApplicationTrafficLabel = "s ap traffic"
- exporterLabel = "exp master"
- resumptionLabel = "res master"
- trafficUpdateLabel = "traffic upd"
-)
-
-// expandLabel implements HKDF-Expand-Label from RFC 8446, Section 7.1.
-func (c *cipherSuiteTLS13) expandLabel(secret []byte, label string, context []byte, length int) []byte {
- var hkdfLabel cryptobyte.Builder
- hkdfLabel.AddUint16(uint16(length))
- hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes([]byte("tls13 "))
- b.AddBytes([]byte(label))
- })
- hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(context)
- })
- hkdfLabelBytes, err := hkdfLabel.Bytes()
- if err != nil {
- // Rather than calling BytesOrPanic, we explicitly handle this error, in
- // order to provide a reasonable error message. It should be basically
- // impossible for this to panic, and routing errors back through the
- // tree rooted in this function is quite painful. The labels are fixed
- // size, and the context is either a fixed-length computed hash, or
- // parsed from a field which has the same length limitation. As such, an
- // error here is likely to only be caused during development.
- //
- // NOTE: another reasonable approach here might be to return a
- // randomized slice if we encounter an error, which would break the
- // connection, but avoid panicking. This would perhaps be safer but
- // significantly more confusing to users.
- panic(fmt.Errorf("failed to construct HKDF label: %s", err))
- }
- out := make([]byte, length)
- n, err := hkdf.Expand(c.hash.New, secret, hkdfLabelBytes).Read(out)
- if err != nil || n != length {
- panic("tls: HKDF-Expand-Label invocation failed unexpectedly")
- }
- return out
-}
-
-// deriveSecret implements Derive-Secret from RFC 8446, Section 7.1.
-func (c *cipherSuiteTLS13) deriveSecret(secret []byte, label string, transcript hash.Hash) []byte {
- if transcript == nil {
- transcript = c.hash.New()
- }
- return c.expandLabel(secret, label, transcript.Sum(nil), c.hash.Size())
-}
-
-// extract implements HKDF-Extract with the cipher suite hash.
-func (c *cipherSuiteTLS13) extract(newSecret, currentSecret []byte) []byte {
- if newSecret == nil {
- newSecret = make([]byte, c.hash.Size())
- }
- return hkdf.Extract(c.hash.New, newSecret, currentSecret)
-}
-
-// nextTrafficSecret generates the next traffic secret, given the current one,
-// according to RFC 8446, Section 7.2.
-func (c *cipherSuiteTLS13) nextTrafficSecret(trafficSecret []byte) []byte {
- return c.expandLabel(trafficSecret, trafficUpdateLabel, nil, c.hash.Size())
-}
-
-// trafficKey generates traffic keys according to RFC 8446, Section 7.3.
-func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) {
- key = c.expandLabel(trafficSecret, "key", nil, c.keyLen)
- iv = c.expandLabel(trafficSecret, "iv", nil, aeadNonceLength)
- return
-}
-
-// finishedHash generates the Finished verify_data or PskBinderEntry according
-// to RFC 8446, Section 4.4.4. See sections 4.4 and 4.2.11.2 for the baseKey
-// selection.
-func (c *cipherSuiteTLS13) finishedHash(baseKey []byte, transcript hash.Hash) []byte {
- finishedKey := c.expandLabel(baseKey, "finished", nil, c.hash.Size())
- verifyData := hmac.New(c.hash.New, finishedKey)
- verifyData.Write(transcript.Sum(nil))
- return verifyData.Sum(nil)
-}
-
-// exportKeyingMaterial implements RFC5705 exporters for TLS 1.3 according to
-// RFC 8446, Section 7.5.
-func (c *cipherSuiteTLS13) exportKeyingMaterial(masterSecret []byte, transcript hash.Hash) func(string, []byte, int) ([]byte, error) {
- expMasterSecret := c.deriveSecret(masterSecret, exporterLabel, transcript)
- return func(label string, context []byte, length int) ([]byte, error) {
- secret := c.deriveSecret(expMasterSecret, label, nil)
- h := c.hash.New()
- h.Write(context)
- return c.expandLabel(secret, "exporter", h.Sum(nil), length), nil
- }
-}
-
-// generateECDHEKey returns a PrivateKey that implements Diffie-Hellman
-// according to RFC 8446, Section 4.2.8.2.
-func generateECDHEKey(rand io.Reader, curveID CurveID) (*ecdh.PrivateKey, error) {
- curve, ok := curveForCurveID(curveID)
- if !ok {
- return nil, errors.New("tls: internal error: unsupported curve")
- }
-
- return curve.GenerateKey(rand)
-}
-
-func curveForCurveID(id CurveID) (ecdh.Curve, bool) {
- switch id {
- case X25519:
- return ecdh.X25519(), true
- case CurveP256:
- return ecdh.P256(), true
- case CurveP384:
- return ecdh.P384(), true
- case CurveP521:
- return ecdh.P521(), true
- default:
- return nil, false
- }
-}
-
-func curveIDForCurve(curve ecdh.Curve) (CurveID, bool) {
- switch curve {
- case ecdh.X25519():
- return X25519, true
- case ecdh.P256():
- return CurveP256, true
- case ecdh.P384():
- return CurveP384, true
- case ecdh.P521():
- return CurveP521, true
- default:
- return 0, false
- }
-}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/prf.go b/contrib/go/_std_1.20/src/crypto/tls/prf.go
deleted file mode 100644
index b60166dee3..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/prf.go
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2009 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 tls
-
-import (
- "crypto"
- "crypto/hmac"
- "crypto/md5"
- "crypto/sha1"
- "crypto/sha256"
- "crypto/sha512"
- "errors"
- "fmt"
- "hash"
-)
-
-// Split a premaster secret in two as specified in RFC 4346, Section 5.
-func splitPreMasterSecret(secret []byte) (s1, s2 []byte) {
- s1 = secret[0 : (len(secret)+1)/2]
- s2 = secret[len(secret)/2:]
- return
-}
-
-// pHash implements the P_hash function, as defined in RFC 4346, Section 5.
-func pHash(result, secret, seed []byte, hash func() hash.Hash) {
- h := hmac.New(hash, secret)
- h.Write(seed)
- a := h.Sum(nil)
-
- j := 0
- for j < len(result) {
- h.Reset()
- h.Write(a)
- h.Write(seed)
- b := h.Sum(nil)
- copy(result[j:], b)
- j += len(b)
-
- h.Reset()
- h.Write(a)
- a = h.Sum(nil)
- }
-}
-
-// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5.
-func prf10(result, secret, label, seed []byte) {
- hashSHA1 := sha1.New
- hashMD5 := md5.New
-
- labelAndSeed := make([]byte, len(label)+len(seed))
- copy(labelAndSeed, label)
- copy(labelAndSeed[len(label):], seed)
-
- s1, s2 := splitPreMasterSecret(secret)
- pHash(result, s1, labelAndSeed, hashMD5)
- result2 := make([]byte, len(result))
- pHash(result2, s2, labelAndSeed, hashSHA1)
-
- for i, b := range result2 {
- result[i] ^= b
- }
-}
-
-// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5.
-func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) {
- return func(result, secret, label, seed []byte) {
- labelAndSeed := make([]byte, len(label)+len(seed))
- copy(labelAndSeed, label)
- copy(labelAndSeed[len(label):], seed)
-
- pHash(result, secret, labelAndSeed, hashFunc)
- }
-}
-
-const (
- masterSecretLength = 48 // Length of a master secret in TLS 1.1.
- finishedVerifyLength = 12 // Length of verify_data in a Finished message.
-)
-
-var masterSecretLabel = []byte("master secret")
-var keyExpansionLabel = []byte("key expansion")
-var clientFinishedLabel = []byte("client finished")
-var serverFinishedLabel = []byte("server finished")
-
-func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) {
- switch version {
- case VersionTLS10, VersionTLS11:
- return prf10, crypto.Hash(0)
- case VersionTLS12:
- if suite.flags&suiteSHA384 != 0 {
- return prf12(sha512.New384), crypto.SHA384
- }
- return prf12(sha256.New), crypto.SHA256
- default:
- panic("unknown version")
- }
-}
-
-func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) {
- prf, _ := prfAndHashForVersion(version, suite)
- return prf
-}
-
-// masterFromPreMasterSecret generates the master secret from the pre-master
-// secret. See RFC 5246, Section 8.1.
-func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte {
- seed := make([]byte, 0, len(clientRandom)+len(serverRandom))
- seed = append(seed, clientRandom...)
- seed = append(seed, serverRandom...)
-
- masterSecret := make([]byte, masterSecretLength)
- prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed)
- return masterSecret
-}
-
-// keysFromMasterSecret generates the connection keys from the master
-// secret, given the lengths of the MAC key, cipher key and IV, as defined in
-// RFC 2246, Section 6.3.
-func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
- seed := make([]byte, 0, len(serverRandom)+len(clientRandom))
- seed = append(seed, serverRandom...)
- seed = append(seed, clientRandom...)
-
- n := 2*macLen + 2*keyLen + 2*ivLen
- keyMaterial := make([]byte, n)
- prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed)
- clientMAC = keyMaterial[:macLen]
- keyMaterial = keyMaterial[macLen:]
- serverMAC = keyMaterial[:macLen]
- keyMaterial = keyMaterial[macLen:]
- clientKey = keyMaterial[:keyLen]
- keyMaterial = keyMaterial[keyLen:]
- serverKey = keyMaterial[:keyLen]
- keyMaterial = keyMaterial[keyLen:]
- clientIV = keyMaterial[:ivLen]
- keyMaterial = keyMaterial[ivLen:]
- serverIV = keyMaterial[:ivLen]
- return
-}
-
-func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash {
- var buffer []byte
- if version >= VersionTLS12 {
- buffer = []byte{}
- }
-
- prf, hash := prfAndHashForVersion(version, cipherSuite)
- if hash != 0 {
- return finishedHash{hash.New(), hash.New(), nil, nil, buffer, version, prf}
- }
-
- return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), buffer, version, prf}
-}
-
-// A finishedHash calculates the hash of a set of handshake messages suitable
-// for including in a Finished message.
-type finishedHash struct {
- client hash.Hash
- server hash.Hash
-
- // Prior to TLS 1.2, an additional MD5 hash is required.
- clientMD5 hash.Hash
- serverMD5 hash.Hash
-
- // In TLS 1.2, a full buffer is sadly required.
- buffer []byte
-
- version uint16
- prf func(result, secret, label, seed []byte)
-}
-
-func (h *finishedHash) Write(msg []byte) (n int, err error) {
- h.client.Write(msg)
- h.server.Write(msg)
-
- if h.version < VersionTLS12 {
- h.clientMD5.Write(msg)
- h.serverMD5.Write(msg)
- }
-
- if h.buffer != nil {
- h.buffer = append(h.buffer, msg...)
- }
-
- return len(msg), nil
-}
-
-func (h finishedHash) Sum() []byte {
- if h.version >= VersionTLS12 {
- return h.client.Sum(nil)
- }
-
- out := make([]byte, 0, md5.Size+sha1.Size)
- out = h.clientMD5.Sum(out)
- return h.client.Sum(out)
-}
-
-// clientSum returns the contents of the verify_data member of a client's
-// Finished message.
-func (h finishedHash) clientSum(masterSecret []byte) []byte {
- out := make([]byte, finishedVerifyLength)
- h.prf(out, masterSecret, clientFinishedLabel, h.Sum())
- return out
-}
-
-// serverSum returns the contents of the verify_data member of a server's
-// Finished message.
-func (h finishedHash) serverSum(masterSecret []byte) []byte {
- out := make([]byte, finishedVerifyLength)
- h.prf(out, masterSecret, serverFinishedLabel, h.Sum())
- return out
-}
-
-// hashForClientCertificate returns the handshake messages so far, pre-hashed if
-// necessary, suitable for signing by a TLS client certificate.
-func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash) []byte {
- if (h.version >= VersionTLS12 || sigType == signatureEd25519) && h.buffer == nil {
- panic("tls: handshake hash for a client certificate requested after discarding the handshake buffer")
- }
-
- if sigType == signatureEd25519 {
- return h.buffer
- }
-
- if h.version >= VersionTLS12 {
- hash := hashAlg.New()
- hash.Write(h.buffer)
- return hash.Sum(nil)
- }
-
- if sigType == signatureECDSA {
- return h.server.Sum(nil)
- }
-
- return h.Sum()
-}
-
-// discardHandshakeBuffer is called when there is no more need to
-// buffer the entirety of the handshake messages.
-func (h *finishedHash) discardHandshakeBuffer() {
- h.buffer = nil
-}
-
-// noExportedKeyingMaterial is used as a value of
-// ConnectionState.ekm when renegotiation is enabled and thus
-// we wish to fail all key-material export requests.
-func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
- return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled")
-}
-
-// ekmFromMasterSecret generates exported keying material as defined in RFC 5705.
-func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) {
- return func(label string, context []byte, length int) ([]byte, error) {
- switch label {
- case "client finished", "server finished", "master secret", "key expansion":
- // These values are reserved and may not be used.
- return nil, fmt.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label)
- }
-
- seedLen := len(serverRandom) + len(clientRandom)
- if context != nil {
- seedLen += 2 + len(context)
- }
- seed := make([]byte, 0, seedLen)
-
- seed = append(seed, clientRandom...)
- seed = append(seed, serverRandom...)
-
- if context != nil {
- if len(context) >= 1<<16 {
- return nil, fmt.Errorf("crypto/tls: ExportKeyingMaterial context too long")
- }
- seed = append(seed, byte(len(context)>>8), byte(len(context)))
- seed = append(seed, context...)
- }
-
- keyMaterial := make([]byte, length)
- prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed)
- return keyMaterial, nil
- }
-}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/ticket.go b/contrib/go/_std_1.20/src/crypto/tls/ticket.go
deleted file mode 100644
index b82ccd141e..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/ticket.go
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2012 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 tls
-
-import (
- "bytes"
- "crypto/aes"
- "crypto/cipher"
- "crypto/hmac"
- "crypto/sha256"
- "crypto/subtle"
- "errors"
- "io"
-
- "golang.org/x/crypto/cryptobyte"
-)
-
-// sessionState contains the information that is serialized into a session
-// ticket in order to later resume a connection.
-type sessionState struct {
- vers uint16
- cipherSuite uint16
- createdAt uint64
- masterSecret []byte // opaque master_secret<1..2^16-1>;
- // struct { opaque certificate<1..2^24-1> } Certificate;
- certificates [][]byte // Certificate certificate_list<0..2^24-1>;
-
- // usedOldKey is true if the ticket from which this session came from
- // was encrypted with an older key and thus should be refreshed.
- usedOldKey bool
-}
-
-func (m *sessionState) marshal() ([]byte, error) {
- var b cryptobyte.Builder
- b.AddUint16(m.vers)
- b.AddUint16(m.cipherSuite)
- addUint64(&b, m.createdAt)
- b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.masterSecret)
- })
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- for _, cert := range m.certificates {
- b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(cert)
- })
- }
- })
- return b.Bytes()
-}
-
-func (m *sessionState) unmarshal(data []byte) bool {
- *m = sessionState{usedOldKey: m.usedOldKey}
- s := cryptobyte.String(data)
- if ok := s.ReadUint16(&m.vers) &&
- s.ReadUint16(&m.cipherSuite) &&
- readUint64(&s, &m.createdAt) &&
- readUint16LengthPrefixed(&s, &m.masterSecret) &&
- len(m.masterSecret) != 0; !ok {
- return false
- }
- var certList cryptobyte.String
- if !s.ReadUint24LengthPrefixed(&certList) {
- return false
- }
- for !certList.Empty() {
- var cert []byte
- if !readUint24LengthPrefixed(&certList, &cert) {
- return false
- }
- m.certificates = append(m.certificates, cert)
- }
- return s.Empty()
-}
-
-// sessionStateTLS13 is the content of a TLS 1.3 session ticket. Its first
-// version (revision = 0) doesn't carry any of the information needed for 0-RTT
-// validation and the nonce is always empty.
-type sessionStateTLS13 struct {
- // uint8 version = 0x0304;
- // uint8 revision = 0;
- cipherSuite uint16
- createdAt uint64
- resumptionSecret []byte // opaque resumption_master_secret<1..2^8-1>;
- certificate Certificate // CertificateEntry certificate_list<0..2^24-1>;
-}
-
-func (m *sessionStateTLS13) marshal() ([]byte, error) {
- var b cryptobyte.Builder
- b.AddUint16(VersionTLS13)
- b.AddUint8(0) // revision
- b.AddUint16(m.cipherSuite)
- addUint64(&b, m.createdAt)
- b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
- b.AddBytes(m.resumptionSecret)
- })
- marshalCertificate(&b, m.certificate)
- return b.Bytes()
-}
-
-func (m *sessionStateTLS13) unmarshal(data []byte) bool {
- *m = sessionStateTLS13{}
- s := cryptobyte.String(data)
- var version uint16
- var revision uint8
- return s.ReadUint16(&version) &&
- version == VersionTLS13 &&
- s.ReadUint8(&revision) &&
- revision == 0 &&
- s.ReadUint16(&m.cipherSuite) &&
- readUint64(&s, &m.createdAt) &&
- readUint8LengthPrefixed(&s, &m.resumptionSecret) &&
- len(m.resumptionSecret) != 0 &&
- unmarshalCertificate(&s, &m.certificate) &&
- s.Empty()
-}
-
-func (c *Conn) encryptTicket(state []byte) ([]byte, error) {
- if len(c.ticketKeys) == 0 {
- return nil, errors.New("tls: internal error: session ticket keys unavailable")
- }
-
- encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(state)+sha256.Size)
- keyName := encrypted[:ticketKeyNameLen]
- iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
- macBytes := encrypted[len(encrypted)-sha256.Size:]
-
- if _, err := io.ReadFull(c.config.rand(), iv); err != nil {
- return nil, err
- }
- key := c.ticketKeys[0]
- copy(keyName, key.keyName[:])
- block, err := aes.NewCipher(key.aesKey[:])
- if err != nil {
- return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error())
- }
- cipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], state)
-
- mac := hmac.New(sha256.New, key.hmacKey[:])
- mac.Write(encrypted[:len(encrypted)-sha256.Size])
- mac.Sum(macBytes[:0])
-
- return encrypted, nil
-}
-
-func (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey bool) {
- if len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size {
- return nil, false
- }
-
- keyName := encrypted[:ticketKeyNameLen]
- iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
- macBytes := encrypted[len(encrypted)-sha256.Size:]
- ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size]
-
- keyIndex := -1
- for i, candidateKey := range c.ticketKeys {
- if bytes.Equal(keyName, candidateKey.keyName[:]) {
- keyIndex = i
- break
- }
- }
- if keyIndex == -1 {
- return nil, false
- }
- key := &c.ticketKeys[keyIndex]
-
- mac := hmac.New(sha256.New, key.hmacKey[:])
- mac.Write(encrypted[:len(encrypted)-sha256.Size])
- expected := mac.Sum(nil)
-
- if subtle.ConstantTimeCompare(macBytes, expected) != 1 {
- return nil, false
- }
-
- block, err := aes.NewCipher(key.aesKey[:])
- if err != nil {
- return nil, false
- }
- plaintext = make([]byte, len(ciphertext))
- cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)
-
- return plaintext, keyIndex > 0
-}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/ya.make b/contrib/go/_std_1.20/src/crypto/tls/ya.make
deleted file mode 100644
index c2e66b016c..0000000000
--- a/contrib/go/_std_1.20/src/crypto/tls/ya.make
+++ /dev/null
@@ -1,24 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- alert.go
- auth.go
- cache.go
- cipher_suites.go
- common.go
- common_string.go
- conn.go
- handshake_client.go
- handshake_client_tls13.go
- handshake_messages.go
- handshake_server.go
- handshake_server_tls13.go
- key_agreement.go
- key_schedule.go
- notboring.go
- prf.go
- ticket.go
- tls.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/x509/internal/macos/ya.make b/contrib/go/_std_1.20/src/crypto/x509/internal/macos/ya.make
deleted file mode 100644
index 19255651fb..0000000000
--- a/contrib/go/_std_1.20/src/crypto/x509/internal/macos/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-GO_LIBRARY()
-
-BUILD_ONLY_IF(WARNING OS_DARWIN)
-
-IF (OS_DARWIN)
- SRCS(
- corefoundation.go
- corefoundation.s
- security.go
- security.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/crypto/x509/parser.go b/contrib/go/_std_1.20/src/crypto/x509/parser.go
deleted file mode 100644
index 6ea30178d9..0000000000
--- a/contrib/go/_std_1.20/src/crypto/x509/parser.go
+++ /dev/null
@@ -1,1175 +0,0 @@
-// 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 x509
-
-import (
- "bytes"
- "crypto/dsa"
- "crypto/ecdh"
- "crypto/ecdsa"
- "crypto/ed25519"
- "crypto/elliptic"
- "crypto/rsa"
- "crypto/x509/pkix"
- "encoding/asn1"
- "errors"
- "fmt"
- "math/big"
- "net"
- "net/url"
- "strconv"
- "strings"
- "time"
- "unicode/utf16"
- "unicode/utf8"
-
- "golang.org/x/crypto/cryptobyte"
- cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
-)
-
-// isPrintable reports whether the given b is in the ASN.1 PrintableString set.
-// This is a simplified version of encoding/asn1.isPrintable.
-func isPrintable(b byte) bool {
- return 'a' <= b && b <= 'z' ||
- 'A' <= b && b <= 'Z' ||
- '0' <= b && b <= '9' ||
- '\'' <= b && b <= ')' ||
- '+' <= b && b <= '/' ||
- b == ' ' ||
- b == ':' ||
- b == '=' ||
- b == '?' ||
- // This is technically not allowed in a PrintableString.
- // However, x509 certificates with wildcard strings don't
- // always use the correct string type so we permit it.
- b == '*' ||
- // This is not technically allowed either. However, not
- // only is it relatively common, but there are also a
- // handful of CA certificates that contain it. At least
- // one of which will not expire until 2027.
- b == '&'
-}
-
-// parseASN1String parses the ASN.1 string types T61String, PrintableString,
-// UTF8String, BMPString, IA5String, and NumericString. This is mostly copied
-// from the respective encoding/asn1.parse... methods, rather than just
-// increasing the API surface of that package.
-func parseASN1String(tag cryptobyte_asn1.Tag, value []byte) (string, error) {
- switch tag {
- case cryptobyte_asn1.T61String:
- return string(value), nil
- case cryptobyte_asn1.PrintableString:
- for _, b := range value {
- if !isPrintable(b) {
- return "", errors.New("invalid PrintableString")
- }
- }
- return string(value), nil
- case cryptobyte_asn1.UTF8String:
- if !utf8.Valid(value) {
- return "", errors.New("invalid UTF-8 string")
- }
- return string(value), nil
- case cryptobyte_asn1.Tag(asn1.TagBMPString):
- if len(value)%2 != 0 {
- return "", errors.New("invalid BMPString")
- }
-
- // Strip terminator if present.
- if l := len(value); l >= 2 && value[l-1] == 0 && value[l-2] == 0 {
- value = value[:l-2]
- }
-
- s := make([]uint16, 0, len(value)/2)
- for len(value) > 0 {
- s = append(s, uint16(value[0])<<8+uint16(value[1]))
- value = value[2:]
- }
-
- return string(utf16.Decode(s)), nil
- case cryptobyte_asn1.IA5String:
- s := string(value)
- if isIA5String(s) != nil {
- return "", errors.New("invalid IA5String")
- }
- return s, nil
- case cryptobyte_asn1.Tag(asn1.TagNumericString):
- for _, b := range value {
- if !('0' <= b && b <= '9' || b == ' ') {
- return "", errors.New("invalid NumericString")
- }
- }
- return string(value), nil
- }
- return "", fmt.Errorf("unsupported string type: %v", tag)
-}
-
-// parseName parses a DER encoded Name as defined in RFC 5280. We may
-// want to export this function in the future for use in crypto/tls.
-func parseName(raw cryptobyte.String) (*pkix.RDNSequence, error) {
- if !raw.ReadASN1(&raw, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: invalid RDNSequence")
- }
-
- var rdnSeq pkix.RDNSequence
- for !raw.Empty() {
- var rdnSet pkix.RelativeDistinguishedNameSET
- var set cryptobyte.String
- if !raw.ReadASN1(&set, cryptobyte_asn1.SET) {
- return nil, errors.New("x509: invalid RDNSequence")
- }
- for !set.Empty() {
- var atav cryptobyte.String
- if !set.ReadASN1(&atav, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: invalid RDNSequence: invalid attribute")
- }
- var attr pkix.AttributeTypeAndValue
- if !atav.ReadASN1ObjectIdentifier(&attr.Type) {
- return nil, errors.New("x509: invalid RDNSequence: invalid attribute type")
- }
- var rawValue cryptobyte.String
- var valueTag cryptobyte_asn1.Tag
- if !atav.ReadAnyASN1(&rawValue, &valueTag) {
- return nil, errors.New("x509: invalid RDNSequence: invalid attribute value")
- }
- var err error
- attr.Value, err = parseASN1String(valueTag, rawValue)
- if err != nil {
- return nil, fmt.Errorf("x509: invalid RDNSequence: invalid attribute value: %s", err)
- }
- rdnSet = append(rdnSet, attr)
- }
-
- rdnSeq = append(rdnSeq, rdnSet)
- }
-
- return &rdnSeq, nil
-}
-
-func parseAI(der cryptobyte.String) (pkix.AlgorithmIdentifier, error) {
- ai := pkix.AlgorithmIdentifier{}
- if !der.ReadASN1ObjectIdentifier(&ai.Algorithm) {
- return ai, errors.New("x509: malformed OID")
- }
- if der.Empty() {
- return ai, nil
- }
- var params cryptobyte.String
- var tag cryptobyte_asn1.Tag
- if !der.ReadAnyASN1Element(&params, &tag) {
- return ai, errors.New("x509: malformed parameters")
- }
- ai.Parameters.Tag = int(tag)
- ai.Parameters.FullBytes = params
- return ai, nil
-}
-
-func parseTime(der *cryptobyte.String) (time.Time, error) {
- var t time.Time
- switch {
- case der.PeekASN1Tag(cryptobyte_asn1.UTCTime):
- if !der.ReadASN1UTCTime(&t) {
- return t, errors.New("x509: malformed UTCTime")
- }
- case der.PeekASN1Tag(cryptobyte_asn1.GeneralizedTime):
- if !der.ReadASN1GeneralizedTime(&t) {
- return t, errors.New("x509: malformed GeneralizedTime")
- }
- default:
- return t, errors.New("x509: unsupported time format")
- }
- return t, nil
-}
-
-func parseValidity(der cryptobyte.String) (time.Time, time.Time, error) {
- notBefore, err := parseTime(&der)
- if err != nil {
- return time.Time{}, time.Time{}, err
- }
- notAfter, err := parseTime(&der)
- if err != nil {
- return time.Time{}, time.Time{}, err
- }
-
- return notBefore, notAfter, nil
-}
-
-func parseExtension(der cryptobyte.String) (pkix.Extension, error) {
- var ext pkix.Extension
- if !der.ReadASN1ObjectIdentifier(&ext.Id) {
- return ext, errors.New("x509: malformed extension OID field")
- }
- if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
- if !der.ReadASN1Boolean(&ext.Critical) {
- return ext, errors.New("x509: malformed extension critical field")
- }
- }
- var val cryptobyte.String
- if !der.ReadASN1(&val, cryptobyte_asn1.OCTET_STRING) {
- return ext, errors.New("x509: malformed extension value field")
- }
- ext.Value = val
- return ext, nil
-}
-
-func parsePublicKey(keyData *publicKeyInfo) (any, error) {
- oid := keyData.Algorithm.Algorithm
- params := keyData.Algorithm.Parameters
- der := cryptobyte.String(keyData.PublicKey.RightAlign())
- switch {
- case oid.Equal(oidPublicKeyRSA):
- // RSA public keys must have a NULL in the parameters.
- // See RFC 3279, Section 2.3.1.
- if !bytes.Equal(params.FullBytes, asn1.NullBytes) {
- return nil, errors.New("x509: RSA key missing NULL parameters")
- }
-
- p := &pkcs1PublicKey{N: new(big.Int)}
- if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: invalid RSA public key")
- }
- if !der.ReadASN1Integer(p.N) {
- return nil, errors.New("x509: invalid RSA modulus")
- }
- if !der.ReadASN1Integer(&p.E) {
- return nil, errors.New("x509: invalid RSA public exponent")
- }
-
- if p.N.Sign() <= 0 {
- return nil, errors.New("x509: RSA modulus is not a positive number")
- }
- if p.E <= 0 {
- return nil, errors.New("x509: RSA public exponent is not a positive number")
- }
-
- pub := &rsa.PublicKey{
- E: p.E,
- N: p.N,
- }
- return pub, nil
- case oid.Equal(oidPublicKeyECDSA):
- paramsDer := cryptobyte.String(params.FullBytes)
- namedCurveOID := new(asn1.ObjectIdentifier)
- if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {
- return nil, errors.New("x509: invalid ECDSA parameters")
- }
- namedCurve := namedCurveFromOID(*namedCurveOID)
- if namedCurve == nil {
- return nil, errors.New("x509: unsupported elliptic curve")
- }
- x, y := elliptic.Unmarshal(namedCurve, der)
- if x == nil {
- return nil, errors.New("x509: failed to unmarshal elliptic curve point")
- }
- pub := &ecdsa.PublicKey{
- Curve: namedCurve,
- X: x,
- Y: y,
- }
- return pub, nil
- case oid.Equal(oidPublicKeyEd25519):
- // RFC 8410, Section 3
- // > For all of the OIDs, the parameters MUST be absent.
- if len(params.FullBytes) != 0 {
- return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")
- }
- if len(der) != ed25519.PublicKeySize {
- return nil, errors.New("x509: wrong Ed25519 public key size")
- }
- return ed25519.PublicKey(der), nil
- case oid.Equal(oidPublicKeyX25519):
- // RFC 8410, Section 3
- // > For all of the OIDs, the parameters MUST be absent.
- if len(params.FullBytes) != 0 {
- return nil, errors.New("x509: X25519 key encoded with illegal parameters")
- }
- return ecdh.X25519().NewPublicKey(der)
- case oid.Equal(oidPublicKeyDSA):
- y := new(big.Int)
- if !der.ReadASN1Integer(y) {
- return nil, errors.New("x509: invalid DSA public key")
- }
- pub := &dsa.PublicKey{
- Y: y,
- Parameters: dsa.Parameters{
- P: new(big.Int),
- Q: new(big.Int),
- G: new(big.Int),
- },
- }
- paramsDer := cryptobyte.String(params.FullBytes)
- if !paramsDer.ReadASN1(&paramsDer, cryptobyte_asn1.SEQUENCE) ||
- !paramsDer.ReadASN1Integer(pub.Parameters.P) ||
- !paramsDer.ReadASN1Integer(pub.Parameters.Q) ||
- !paramsDer.ReadASN1Integer(pub.Parameters.G) {
- return nil, errors.New("x509: invalid DSA parameters")
- }
- if pub.Y.Sign() <= 0 || pub.Parameters.P.Sign() <= 0 ||
- pub.Parameters.Q.Sign() <= 0 || pub.Parameters.G.Sign() <= 0 {
- return nil, errors.New("x509: zero or negative DSA parameter")
- }
- return pub, nil
- default:
- return nil, errors.New("x509: unknown public key algorithm")
- }
-}
-
-func parseKeyUsageExtension(der cryptobyte.String) (KeyUsage, error) {
- var usageBits asn1.BitString
- if !der.ReadASN1BitString(&usageBits) {
- return 0, errors.New("x509: invalid key usage")
- }
-
- var usage int
- for i := 0; i < 9; i++ {
- if usageBits.At(i) != 0 {
- usage |= 1 << uint(i)
- }
- }
- return KeyUsage(usage), nil
-}
-
-func parseBasicConstraintsExtension(der cryptobyte.String) (bool, int, error) {
- var isCA bool
- if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
- return false, 0, errors.New("x509: invalid basic constraints a")
- }
- if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
- if !der.ReadASN1Boolean(&isCA) {
- return false, 0, errors.New("x509: invalid basic constraints b")
- }
- }
- maxPathLen := -1
- if !der.Empty() && der.PeekASN1Tag(cryptobyte_asn1.INTEGER) {
- if !der.ReadASN1Integer(&maxPathLen) {
- return false, 0, errors.New("x509: invalid basic constraints c")
- }
- }
-
- // TODO: map out.MaxPathLen to 0 if it has the -1 default value? (Issue 19285)
- return isCA, maxPathLen, nil
-}
-
-func forEachSAN(der cryptobyte.String, callback func(tag int, data []byte) error) error {
- if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
- return errors.New("x509: invalid subject alternative names")
- }
- for !der.Empty() {
- var san cryptobyte.String
- var tag cryptobyte_asn1.Tag
- if !der.ReadAnyASN1(&san, &tag) {
- return errors.New("x509: invalid subject alternative name")
- }
- if err := callback(int(tag^0x80), san); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func parseSANExtension(der cryptobyte.String) (dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL, err error) {
- err = forEachSAN(der, func(tag int, data []byte) error {
- switch tag {
- case nameTypeEmail:
- email := string(data)
- if err := isIA5String(email); err != nil {
- return errors.New("x509: SAN rfc822Name is malformed")
- }
- emailAddresses = append(emailAddresses, email)
- case nameTypeDNS:
- name := string(data)
- if err := isIA5String(name); err != nil {
- return errors.New("x509: SAN dNSName is malformed")
- }
- dnsNames = append(dnsNames, string(name))
- case nameTypeURI:
- uriStr := string(data)
- if err := isIA5String(uriStr); err != nil {
- return errors.New("x509: SAN uniformResourceIdentifier is malformed")
- }
- uri, err := url.Parse(uriStr)
- if err != nil {
- return fmt.Errorf("x509: cannot parse URI %q: %s", uriStr, err)
- }
- if len(uri.Host) > 0 {
- if _, ok := domainToReverseLabels(uri.Host); !ok {
- return fmt.Errorf("x509: cannot parse URI %q: invalid domain", uriStr)
- }
- }
- uris = append(uris, uri)
- case nameTypeIP:
- switch len(data) {
- case net.IPv4len, net.IPv6len:
- ipAddresses = append(ipAddresses, data)
- default:
- return errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len(data)))
- }
- }
-
- return nil
- })
-
- return
-}
-
-func parseExtKeyUsageExtension(der cryptobyte.String) ([]ExtKeyUsage, []asn1.ObjectIdentifier, error) {
- var extKeyUsages []ExtKeyUsage
- var unknownUsages []asn1.ObjectIdentifier
- if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
- return nil, nil, errors.New("x509: invalid extended key usages")
- }
- for !der.Empty() {
- var eku asn1.ObjectIdentifier
- if !der.ReadASN1ObjectIdentifier(&eku) {
- return nil, nil, errors.New("x509: invalid extended key usages")
- }
- if extKeyUsage, ok := extKeyUsageFromOID(eku); ok {
- extKeyUsages = append(extKeyUsages, extKeyUsage)
- } else {
- unknownUsages = append(unknownUsages, eku)
- }
- }
- return extKeyUsages, unknownUsages, nil
-}
-
-func parseCertificatePoliciesExtension(der cryptobyte.String) ([]asn1.ObjectIdentifier, error) {
- var oids []asn1.ObjectIdentifier
- if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: invalid certificate policies")
- }
- for !der.Empty() {
- var cp cryptobyte.String
- if !der.ReadASN1(&cp, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: invalid certificate policies")
- }
- var oid asn1.ObjectIdentifier
- if !cp.ReadASN1ObjectIdentifier(&oid) {
- return nil, errors.New("x509: invalid certificate policies")
- }
- oids = append(oids, oid)
- }
-
- return oids, nil
-}
-
-// isValidIPMask reports whether mask consists of zero or more 1 bits, followed by zero bits.
-func isValidIPMask(mask []byte) bool {
- seenZero := false
-
- for _, b := range mask {
- if seenZero {
- if b != 0 {
- return false
- }
-
- continue
- }
-
- switch b {
- case 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe:
- seenZero = true
- case 0xff:
- default:
- return false
- }
- }
-
- return true
-}
-
-func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandled bool, err error) {
- // RFC 5280, 4.2.1.10
-
- // NameConstraints ::= SEQUENCE {
- // permittedSubtrees [0] GeneralSubtrees OPTIONAL,
- // excludedSubtrees [1] GeneralSubtrees OPTIONAL }
- //
- // GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
- //
- // GeneralSubtree ::= SEQUENCE {
- // base GeneralName,
- // minimum [0] BaseDistance DEFAULT 0,
- // maximum [1] BaseDistance OPTIONAL }
- //
- // BaseDistance ::= INTEGER (0..MAX)
-
- outer := cryptobyte.String(e.Value)
- var toplevel, permitted, excluded cryptobyte.String
- var havePermitted, haveExcluded bool
- if !outer.ReadASN1(&toplevel, cryptobyte_asn1.SEQUENCE) ||
- !outer.Empty() ||
- !toplevel.ReadOptionalASN1(&permitted, &havePermitted, cryptobyte_asn1.Tag(0).ContextSpecific().Constructed()) ||
- !toplevel.ReadOptionalASN1(&excluded, &haveExcluded, cryptobyte_asn1.Tag(1).ContextSpecific().Constructed()) ||
- !toplevel.Empty() {
- return false, errors.New("x509: invalid NameConstraints extension")
- }
-
- if !havePermitted && !haveExcluded || len(permitted) == 0 && len(excluded) == 0 {
- // From RFC 5280, Section 4.2.1.10:
- // “either the permittedSubtrees field
- // or the excludedSubtrees MUST be
- // present”
- return false, errors.New("x509: empty name constraints extension")
- }
-
- getValues := func(subtrees cryptobyte.String) (dnsNames []string, ips []*net.IPNet, emails, uriDomains []string, err error) {
- for !subtrees.Empty() {
- var seq, value cryptobyte.String
- var tag cryptobyte_asn1.Tag
- if !subtrees.ReadASN1(&seq, cryptobyte_asn1.SEQUENCE) ||
- !seq.ReadAnyASN1(&value, &tag) {
- return nil, nil, nil, nil, fmt.Errorf("x509: invalid NameConstraints extension")
- }
-
- var (
- dnsTag = cryptobyte_asn1.Tag(2).ContextSpecific()
- emailTag = cryptobyte_asn1.Tag(1).ContextSpecific()
- ipTag = cryptobyte_asn1.Tag(7).ContextSpecific()
- uriTag = cryptobyte_asn1.Tag(6).ContextSpecific()
- )
-
- switch tag {
- case dnsTag:
- domain := string(value)
- if err := isIA5String(domain); err != nil {
- return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
- }
-
- trimmedDomain := domain
- if len(trimmedDomain) > 0 && trimmedDomain[0] == '.' {
- // constraints can have a leading
- // period to exclude the domain
- // itself, but that's not valid in a
- // normal domain name.
- trimmedDomain = trimmedDomain[1:]
- }
- if _, ok := domainToReverseLabels(trimmedDomain); !ok {
- return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse dnsName constraint %q", domain)
- }
- dnsNames = append(dnsNames, domain)
-
- case ipTag:
- l := len(value)
- var ip, mask []byte
-
- switch l {
- case 8:
- ip = value[:4]
- mask = value[4:]
-
- case 32:
- ip = value[:16]
- mask = value[16:]
-
- default:
- return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained value of length %d", l)
- }
-
- if !isValidIPMask(mask) {
- return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained invalid mask %x", mask)
- }
-
- ips = append(ips, &net.IPNet{IP: net.IP(ip), Mask: net.IPMask(mask)})
-
- case emailTag:
- constraint := string(value)
- if err := isIA5String(constraint); err != nil {
- return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
- }
-
- // If the constraint contains an @ then
- // it specifies an exact mailbox name.
- if strings.Contains(constraint, "@") {
- if _, ok := parseRFC2821Mailbox(constraint); !ok {
- return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
- }
- } else {
- // Otherwise it's a domain name.
- domain := constraint
- if len(domain) > 0 && domain[0] == '.' {
- domain = domain[1:]
- }
- if _, ok := domainToReverseLabels(domain); !ok {
- return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
- }
- }
- emails = append(emails, constraint)
-
- case uriTag:
- domain := string(value)
- if err := isIA5String(domain); err != nil {
- return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
- }
-
- if net.ParseIP(domain) != nil {
- return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q: cannot be IP address", domain)
- }
-
- trimmedDomain := domain
- if len(trimmedDomain) > 0 && trimmedDomain[0] == '.' {
- // constraints can have a leading
- // period to exclude the domain itself,
- // but that's not valid in a normal
- // domain name.
- trimmedDomain = trimmedDomain[1:]
- }
- if _, ok := domainToReverseLabels(trimmedDomain); !ok {
- return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q", domain)
- }
- uriDomains = append(uriDomains, domain)
-
- default:
- unhandled = true
- }
- }
-
- return dnsNames, ips, emails, uriDomains, nil
- }
-
- if out.PermittedDNSDomains, out.PermittedIPRanges, out.PermittedEmailAddresses, out.PermittedURIDomains, err = getValues(permitted); err != nil {
- return false, err
- }
- if out.ExcludedDNSDomains, out.ExcludedIPRanges, out.ExcludedEmailAddresses, out.ExcludedURIDomains, err = getValues(excluded); err != nil {
- return false, err
- }
- out.PermittedDNSDomainsCritical = e.Critical
-
- return unhandled, nil
-}
-
-func processExtensions(out *Certificate) error {
- var err error
- for _, e := range out.Extensions {
- unhandled := false
-
- if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 {
- switch e.Id[3] {
- case 15:
- out.KeyUsage, err = parseKeyUsageExtension(e.Value)
- if err != nil {
- return err
- }
- case 19:
- out.IsCA, out.MaxPathLen, err = parseBasicConstraintsExtension(e.Value)
- if err != nil {
- return err
- }
- out.BasicConstraintsValid = true
- out.MaxPathLenZero = out.MaxPathLen == 0
- case 17:
- out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(e.Value)
- if err != nil {
- return err
- }
-
- if len(out.DNSNames) == 0 && len(out.EmailAddresses) == 0 && len(out.IPAddresses) == 0 && len(out.URIs) == 0 {
- // If we didn't parse anything then we do the critical check, below.
- unhandled = true
- }
-
- case 30:
- unhandled, err = parseNameConstraintsExtension(out, e)
- if err != nil {
- return err
- }
-
- case 31:
- // RFC 5280, 4.2.1.13
-
- // CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
- //
- // DistributionPoint ::= SEQUENCE {
- // distributionPoint [0] DistributionPointName OPTIONAL,
- // reasons [1] ReasonFlags OPTIONAL,
- // cRLIssuer [2] GeneralNames OPTIONAL }
- //
- // DistributionPointName ::= CHOICE {
- // fullName [0] GeneralNames,
- // nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
- val := cryptobyte.String(e.Value)
- if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {
- return errors.New("x509: invalid CRL distribution points")
- }
- for !val.Empty() {
- var dpDER cryptobyte.String
- if !val.ReadASN1(&dpDER, cryptobyte_asn1.SEQUENCE) {
- return errors.New("x509: invalid CRL distribution point")
- }
- var dpNameDER cryptobyte.String
- var dpNamePresent bool
- if !dpDER.ReadOptionalASN1(&dpNameDER, &dpNamePresent, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
- return errors.New("x509: invalid CRL distribution point")
- }
- if !dpNamePresent {
- continue
- }
- if !dpNameDER.ReadASN1(&dpNameDER, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
- return errors.New("x509: invalid CRL distribution point")
- }
- for !dpNameDER.Empty() {
- if !dpNameDER.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {
- break
- }
- var uri cryptobyte.String
- if !dpNameDER.ReadASN1(&uri, cryptobyte_asn1.Tag(6).ContextSpecific()) {
- return errors.New("x509: invalid CRL distribution point")
- }
- out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(uri))
- }
- }
-
- case 35:
- // RFC 5280, 4.2.1.1
- val := cryptobyte.String(e.Value)
- var akid cryptobyte.String
- if !val.ReadASN1(&akid, cryptobyte_asn1.SEQUENCE) {
- return errors.New("x509: invalid authority key identifier")
- }
- if akid.PeekASN1Tag(cryptobyte_asn1.Tag(0).ContextSpecific()) {
- if !akid.ReadASN1(&akid, cryptobyte_asn1.Tag(0).ContextSpecific()) {
- return errors.New("x509: invalid authority key identifier")
- }
- out.AuthorityKeyId = akid
- }
- case 37:
- out.ExtKeyUsage, out.UnknownExtKeyUsage, err = parseExtKeyUsageExtension(e.Value)
- if err != nil {
- return err
- }
- case 14:
- // RFC 5280, 4.2.1.2
- val := cryptobyte.String(e.Value)
- var skid cryptobyte.String
- if !val.ReadASN1(&skid, cryptobyte_asn1.OCTET_STRING) {
- return errors.New("x509: invalid subject key identifier")
- }
- out.SubjectKeyId = skid
- case 32:
- out.PolicyIdentifiers, err = parseCertificatePoliciesExtension(e.Value)
- if err != nil {
- return err
- }
- default:
- // Unknown extensions are recorded if critical.
- unhandled = true
- }
- } else if e.Id.Equal(oidExtensionAuthorityInfoAccess) {
- // RFC 5280 4.2.2.1: Authority Information Access
- val := cryptobyte.String(e.Value)
- if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {
- return errors.New("x509: invalid authority info access")
- }
- for !val.Empty() {
- var aiaDER cryptobyte.String
- if !val.ReadASN1(&aiaDER, cryptobyte_asn1.SEQUENCE) {
- return errors.New("x509: invalid authority info access")
- }
- var method asn1.ObjectIdentifier
- if !aiaDER.ReadASN1ObjectIdentifier(&method) {
- return errors.New("x509: invalid authority info access")
- }
- if !aiaDER.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {
- continue
- }
- if !aiaDER.ReadASN1(&aiaDER, cryptobyte_asn1.Tag(6).ContextSpecific()) {
- return errors.New("x509: invalid authority info access")
- }
- switch {
- case method.Equal(oidAuthorityInfoAccessOcsp):
- out.OCSPServer = append(out.OCSPServer, string(aiaDER))
- case method.Equal(oidAuthorityInfoAccessIssuers):
- out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(aiaDER))
- }
- }
- } else {
- // Unknown extensions are recorded if critical.
- unhandled = true
- }
-
- if e.Critical && unhandled {
- out.UnhandledCriticalExtensions = append(out.UnhandledCriticalExtensions, e.Id)
- }
- }
-
- return nil
-}
-
-func parseCertificate(der []byte) (*Certificate, error) {
- cert := &Certificate{}
-
- input := cryptobyte.String(der)
- // we read the SEQUENCE including length and tag bytes so that
- // we can populate Certificate.Raw, before unwrapping the
- // SEQUENCE so it can be operated on
- if !input.ReadASN1Element(&input, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed certificate")
- }
- cert.Raw = input
- if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed certificate")
- }
-
- var tbs cryptobyte.String
- // do the same trick again as above to extract the raw
- // bytes for Certificate.RawTBSCertificate
- if !input.ReadASN1Element(&tbs, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed tbs certificate")
- }
- cert.RawTBSCertificate = tbs
- if !tbs.ReadASN1(&tbs, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed tbs certificate")
- }
-
- if !tbs.ReadOptionalASN1Integer(&cert.Version, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific(), 0) {
- return nil, errors.New("x509: malformed version")
- }
- if cert.Version < 0 {
- return nil, errors.New("x509: malformed version")
- }
- // for backwards compat reasons Version is one-indexed,
- // rather than zero-indexed as defined in 5280
- cert.Version++
- if cert.Version > 3 {
- return nil, errors.New("x509: invalid version")
- }
-
- serial := new(big.Int)
- if !tbs.ReadASN1Integer(serial) {
- return nil, errors.New("x509: malformed serial number")
- }
- // we ignore the presence of negative serial numbers because
- // of their prevalence, despite them being invalid
- // TODO(rolandshoemaker): revisit this decision, there are currently
- // only 10 trusted certificates with negative serial numbers
- // according to censys.io.
- cert.SerialNumber = serial
-
- var sigAISeq cryptobyte.String
- if !tbs.ReadASN1(&sigAISeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed signature algorithm identifier")
- }
- // Before parsing the inner algorithm identifier, extract
- // the outer algorithm identifier and make sure that they
- // match.
- var outerSigAISeq cryptobyte.String
- if !input.ReadASN1(&outerSigAISeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed algorithm identifier")
- }
- if !bytes.Equal(outerSigAISeq, sigAISeq) {
- return nil, errors.New("x509: inner and outer signature algorithm identifiers don't match")
- }
- sigAI, err := parseAI(sigAISeq)
- if err != nil {
- return nil, err
- }
- cert.SignatureAlgorithm = getSignatureAlgorithmFromAI(sigAI)
-
- var issuerSeq cryptobyte.String
- if !tbs.ReadASN1Element(&issuerSeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed issuer")
- }
- cert.RawIssuer = issuerSeq
- issuerRDNs, err := parseName(issuerSeq)
- if err != nil {
- return nil, err
- }
- cert.Issuer.FillFromRDNSequence(issuerRDNs)
-
- var validity cryptobyte.String
- if !tbs.ReadASN1(&validity, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed validity")
- }
- cert.NotBefore, cert.NotAfter, err = parseValidity(validity)
- if err != nil {
- return nil, err
- }
-
- var subjectSeq cryptobyte.String
- if !tbs.ReadASN1Element(&subjectSeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed issuer")
- }
- cert.RawSubject = subjectSeq
- subjectRDNs, err := parseName(subjectSeq)
- if err != nil {
- return nil, err
- }
- cert.Subject.FillFromRDNSequence(subjectRDNs)
-
- var spki cryptobyte.String
- if !tbs.ReadASN1Element(&spki, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed spki")
- }
- cert.RawSubjectPublicKeyInfo = spki
- if !spki.ReadASN1(&spki, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed spki")
- }
- var pkAISeq cryptobyte.String
- if !spki.ReadASN1(&pkAISeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed public key algorithm identifier")
- }
- pkAI, err := parseAI(pkAISeq)
- if err != nil {
- return nil, err
- }
- cert.PublicKeyAlgorithm = getPublicKeyAlgorithmFromOID(pkAI.Algorithm)
- var spk asn1.BitString
- if !spki.ReadASN1BitString(&spk) {
- return nil, errors.New("x509: malformed subjectPublicKey")
- }
- if cert.PublicKeyAlgorithm != UnknownPublicKeyAlgorithm {
- cert.PublicKey, err = parsePublicKey(&publicKeyInfo{
- Algorithm: pkAI,
- PublicKey: spk,
- })
- if err != nil {
- return nil, err
- }
- }
-
- if cert.Version > 1 {
- if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(1).ContextSpecific()) {
- return nil, errors.New("x509: malformed issuerUniqueID")
- }
- if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(2).ContextSpecific()) {
- return nil, errors.New("x509: malformed subjectUniqueID")
- }
- if cert.Version == 3 {
- var extensions cryptobyte.String
- var present bool
- if !tbs.ReadOptionalASN1(&extensions, &present, cryptobyte_asn1.Tag(3).Constructed().ContextSpecific()) {
- return nil, errors.New("x509: malformed extensions")
- }
- if present {
- seenExts := make(map[string]bool)
- if !extensions.ReadASN1(&extensions, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed extensions")
- }
- for !extensions.Empty() {
- var extension cryptobyte.String
- if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed extension")
- }
- ext, err := parseExtension(extension)
- if err != nil {
- return nil, err
- }
- oidStr := ext.Id.String()
- if seenExts[oidStr] {
- return nil, errors.New("x509: certificate contains duplicate extensions")
- }
- seenExts[oidStr] = true
- cert.Extensions = append(cert.Extensions, ext)
- }
- err = processExtensions(cert)
- if err != nil {
- return nil, err
- }
- }
- }
- }
-
- var signature asn1.BitString
- if !input.ReadASN1BitString(&signature) {
- return nil, errors.New("x509: malformed signature")
- }
- cert.Signature = signature.RightAlign()
-
- return cert, nil
-}
-
-// ParseCertificate parses a single certificate from the given ASN.1 DER data.
-func ParseCertificate(der []byte) (*Certificate, error) {
- cert, err := parseCertificate(der)
- if err != nil {
- return nil, err
- }
- if len(der) != len(cert.Raw) {
- return nil, errors.New("x509: trailing data")
- }
- return cert, err
-}
-
-// ParseCertificates parses one or more certificates from the given ASN.1 DER
-// data. The certificates must be concatenated with no intermediate padding.
-func ParseCertificates(der []byte) ([]*Certificate, error) {
- var certs []*Certificate
- for len(der) > 0 {
- cert, err := parseCertificate(der)
- if err != nil {
- return nil, err
- }
- certs = append(certs, cert)
- der = der[len(cert.Raw):]
- }
- return certs, nil
-}
-
-// The X.509 standards confusingly 1-indexed the version names, but 0-indexed
-// the actual encoded version, so the version for X.509v2 is 1.
-const x509v2Version = 1
-
-// ParseRevocationList parses a X509 v2 Certificate Revocation List from the given
-// ASN.1 DER data.
-func ParseRevocationList(der []byte) (*RevocationList, error) {
- rl := &RevocationList{}
-
- input := cryptobyte.String(der)
- // we read the SEQUENCE including length and tag bytes so that
- // we can populate RevocationList.Raw, before unwrapping the
- // SEQUENCE so it can be operated on
- if !input.ReadASN1Element(&input, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed crl")
- }
- rl.Raw = input
- if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed crl")
- }
-
- var tbs cryptobyte.String
- // do the same trick again as above to extract the raw
- // bytes for Certificate.RawTBSCertificate
- if !input.ReadASN1Element(&tbs, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed tbs crl")
- }
- rl.RawTBSRevocationList = tbs
- if !tbs.ReadASN1(&tbs, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed tbs crl")
- }
-
- var version int
- if !tbs.PeekASN1Tag(cryptobyte_asn1.INTEGER) {
- return nil, errors.New("x509: unsupported crl version")
- }
- if !tbs.ReadASN1Integer(&version) {
- return nil, errors.New("x509: malformed crl")
- }
- if version != x509v2Version {
- return nil, fmt.Errorf("x509: unsupported crl version: %d", version)
- }
-
- var sigAISeq cryptobyte.String
- if !tbs.ReadASN1(&sigAISeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed signature algorithm identifier")
- }
- // Before parsing the inner algorithm identifier, extract
- // the outer algorithm identifier and make sure that they
- // match.
- var outerSigAISeq cryptobyte.String
- if !input.ReadASN1(&outerSigAISeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed algorithm identifier")
- }
- if !bytes.Equal(outerSigAISeq, sigAISeq) {
- return nil, errors.New("x509: inner and outer signature algorithm identifiers don't match")
- }
- sigAI, err := parseAI(sigAISeq)
- if err != nil {
- return nil, err
- }
- rl.SignatureAlgorithm = getSignatureAlgorithmFromAI(sigAI)
-
- var signature asn1.BitString
- if !input.ReadASN1BitString(&signature) {
- return nil, errors.New("x509: malformed signature")
- }
- rl.Signature = signature.RightAlign()
-
- var issuerSeq cryptobyte.String
- if !tbs.ReadASN1Element(&issuerSeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed issuer")
- }
- rl.RawIssuer = issuerSeq
- issuerRDNs, err := parseName(issuerSeq)
- if err != nil {
- return nil, err
- }
- rl.Issuer.FillFromRDNSequence(issuerRDNs)
-
- rl.ThisUpdate, err = parseTime(&tbs)
- if err != nil {
- return nil, err
- }
- if tbs.PeekASN1Tag(cryptobyte_asn1.GeneralizedTime) || tbs.PeekASN1Tag(cryptobyte_asn1.UTCTime) {
- rl.NextUpdate, err = parseTime(&tbs)
- if err != nil {
- return nil, err
- }
- }
-
- if tbs.PeekASN1Tag(cryptobyte_asn1.SEQUENCE) {
- var revokedSeq cryptobyte.String
- if !tbs.ReadASN1(&revokedSeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed crl")
- }
- for !revokedSeq.Empty() {
- var certSeq cryptobyte.String
- if !revokedSeq.ReadASN1(&certSeq, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed crl")
- }
- rc := pkix.RevokedCertificate{}
- rc.SerialNumber = new(big.Int)
- if !certSeq.ReadASN1Integer(rc.SerialNumber) {
- return nil, errors.New("x509: malformed serial number")
- }
- rc.RevocationTime, err = parseTime(&certSeq)
- if err != nil {
- return nil, err
- }
- var extensions cryptobyte.String
- var present bool
- if !certSeq.ReadOptionalASN1(&extensions, &present, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed extensions")
- }
- if present {
- for !extensions.Empty() {
- var extension cryptobyte.String
- if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed extension")
- }
- ext, err := parseExtension(extension)
- if err != nil {
- return nil, err
- }
- rc.Extensions = append(rc.Extensions, ext)
- }
- }
-
- rl.RevokedCertificates = append(rl.RevokedCertificates, rc)
- }
- }
-
- var extensions cryptobyte.String
- var present bool
- if !tbs.ReadOptionalASN1(&extensions, &present, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
- return nil, errors.New("x509: malformed extensions")
- }
- if present {
- if !extensions.ReadASN1(&extensions, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed extensions")
- }
- for !extensions.Empty() {
- var extension cryptobyte.String
- if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) {
- return nil, errors.New("x509: malformed extension")
- }
- ext, err := parseExtension(extension)
- if err != nil {
- return nil, err
- }
- if ext.Id.Equal(oidExtensionAuthorityKeyId) {
- rl.AuthorityKeyId = ext.Value
- } else if ext.Id.Equal(oidExtensionCRLNumber) {
- value := cryptobyte.String(ext.Value)
- rl.Number = new(big.Int)
- if !value.ReadASN1Integer(rl.Number) {
- return nil, errors.New("x509: malformed crl number")
- }
- }
- rl.Extensions = append(rl.Extensions, ext)
- }
- }
-
- return rl, nil
-}
diff --git a/contrib/go/_std_1.20/src/crypto/x509/pkcs8.go b/contrib/go/_std_1.20/src/crypto/x509/pkcs8.go
deleted file mode 100644
index 2d085e0a96..0000000000
--- a/contrib/go/_std_1.20/src/crypto/x509/pkcs8.go
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright 2011 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 x509
-
-import (
- "crypto/ecdh"
- "crypto/ecdsa"
- "crypto/ed25519"
- "crypto/rsa"
- "crypto/x509/pkix"
- "encoding/asn1"
- "errors"
- "fmt"
-)
-
-// pkcs8 reflects an ASN.1, PKCS #8 PrivateKey. See
-// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn
-// and RFC 5208.
-type pkcs8 struct {
- Version int
- Algo pkix.AlgorithmIdentifier
- PrivateKey []byte
- // optional attributes omitted.
-}
-
-// ParsePKCS8PrivateKey parses an unencrypted private key in PKCS #8, ASN.1 DER form.
-//
-// It returns a *rsa.PrivateKey, a *ecdsa.PrivateKey, a ed25519.PrivateKey (not
-// a pointer), or a *ecdh.PrivateKey (for X25519). More types might be supported
-// in the future.
-//
-// This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY".
-func ParsePKCS8PrivateKey(der []byte) (key any, err error) {
- var privKey pkcs8
- if _, err := asn1.Unmarshal(der, &privKey); err != nil {
- if _, err := asn1.Unmarshal(der, &ecPrivateKey{}); err == nil {
- return nil, errors.New("x509: failed to parse private key (use ParseECPrivateKey instead for this key format)")
- }
- if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil {
- return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)")
- }
- return nil, err
- }
- switch {
- case privKey.Algo.Algorithm.Equal(oidPublicKeyRSA):
- key, err = ParsePKCS1PrivateKey(privKey.PrivateKey)
- if err != nil {
- return nil, errors.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error())
- }
- return key, nil
-
- case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA):
- bytes := privKey.Algo.Parameters.FullBytes
- namedCurveOID := new(asn1.ObjectIdentifier)
- if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil {
- namedCurveOID = nil
- }
- key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey)
- if err != nil {
- return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error())
- }
- return key, nil
-
- case privKey.Algo.Algorithm.Equal(oidPublicKeyEd25519):
- if l := len(privKey.Algo.Parameters.FullBytes); l != 0 {
- return nil, errors.New("x509: invalid Ed25519 private key parameters")
- }
- var curvePrivateKey []byte
- if _, err := asn1.Unmarshal(privKey.PrivateKey, &curvePrivateKey); err != nil {
- return nil, fmt.Errorf("x509: invalid Ed25519 private key: %v", err)
- }
- if l := len(curvePrivateKey); l != ed25519.SeedSize {
- return nil, fmt.Errorf("x509: invalid Ed25519 private key length: %d", l)
- }
- return ed25519.NewKeyFromSeed(curvePrivateKey), nil
-
- case privKey.Algo.Algorithm.Equal(oidPublicKeyX25519):
- if l := len(privKey.Algo.Parameters.FullBytes); l != 0 {
- return nil, errors.New("x509: invalid X25519 private key parameters")
- }
- var curvePrivateKey []byte
- if _, err := asn1.Unmarshal(privKey.PrivateKey, &curvePrivateKey); err != nil {
- return nil, fmt.Errorf("x509: invalid X25519 private key: %v", err)
- }
- return ecdh.X25519().NewPrivateKey(curvePrivateKey)
-
- default:
- return nil, fmt.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm)
- }
-}
-
-// MarshalPKCS8PrivateKey converts a private key to PKCS #8, ASN.1 DER form.
-//
-// The following key types are currently supported: *rsa.PrivateKey,
-// *ecdsa.PrivateKey, ed25519.PrivateKey (not a pointer), and *ecdh.PrivateKey.
-// Unsupported key types result in an error.
-//
-// This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY".
-func MarshalPKCS8PrivateKey(key any) ([]byte, error) {
- var privKey pkcs8
-
- switch k := key.(type) {
- case *rsa.PrivateKey:
- privKey.Algo = pkix.AlgorithmIdentifier{
- Algorithm: oidPublicKeyRSA,
- Parameters: asn1.NullRawValue,
- }
- privKey.PrivateKey = MarshalPKCS1PrivateKey(k)
-
- case *ecdsa.PrivateKey:
- oid, ok := oidFromNamedCurve(k.Curve)
- if !ok {
- return nil, errors.New("x509: unknown curve while marshaling to PKCS#8")
- }
- oidBytes, err := asn1.Marshal(oid)
- if err != nil {
- return nil, errors.New("x509: failed to marshal curve OID: " + err.Error())
- }
- privKey.Algo = pkix.AlgorithmIdentifier{
- Algorithm: oidPublicKeyECDSA,
- Parameters: asn1.RawValue{
- FullBytes: oidBytes,
- },
- }
- if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil {
- return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error())
- }
-
- case ed25519.PrivateKey:
- privKey.Algo = pkix.AlgorithmIdentifier{
- Algorithm: oidPublicKeyEd25519,
- }
- curvePrivateKey, err := asn1.Marshal(k.Seed())
- if err != nil {
- return nil, fmt.Errorf("x509: failed to marshal private key: %v", err)
- }
- privKey.PrivateKey = curvePrivateKey
-
- case *ecdh.PrivateKey:
- if k.Curve() == ecdh.X25519() {
- privKey.Algo = pkix.AlgorithmIdentifier{
- Algorithm: oidPublicKeyX25519,
- }
- var err error
- if privKey.PrivateKey, err = asn1.Marshal(k.Bytes()); err != nil {
- return nil, fmt.Errorf("x509: failed to marshal private key: %v", err)
- }
- } else {
- oid, ok := oidFromECDHCurve(k.Curve())
- if !ok {
- return nil, errors.New("x509: unknown curve while marshaling to PKCS#8")
- }
- oidBytes, err := asn1.Marshal(oid)
- if err != nil {
- return nil, errors.New("x509: failed to marshal curve OID: " + err.Error())
- }
- privKey.Algo = pkix.AlgorithmIdentifier{
- Algorithm: oidPublicKeyECDSA,
- Parameters: asn1.RawValue{
- FullBytes: oidBytes,
- },
- }
- if privKey.PrivateKey, err = marshalECDHPrivateKey(k); err != nil {
- return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error())
- }
- }
-
- default:
- return nil, fmt.Errorf("x509: unknown key type while marshaling PKCS#8: %T", key)
- }
-
- return asn1.Marshal(privKey)
-}
diff --git a/contrib/go/_std_1.20/src/crypto/x509/root.go b/contrib/go/_std_1.20/src/crypto/x509/root.go
deleted file mode 100644
index d6b07a18dc..0000000000
--- a/contrib/go/_std_1.20/src/crypto/x509/root.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2012 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 x509
-
-import (
- "internal/godebug"
- "sync"
-)
-
-var (
- once sync.Once
- systemRootsMu sync.RWMutex
- systemRoots *CertPool
- systemRootsErr error
- fallbacksSet bool
-)
-
-func systemRootsPool() *CertPool {
- once.Do(initSystemRoots)
- systemRootsMu.RLock()
- defer systemRootsMu.RUnlock()
- return systemRoots
-}
-
-func initSystemRoots() {
- systemRootsMu.Lock()
- defer systemRootsMu.Unlock()
- systemRoots, systemRootsErr = loadSystemRoots()
- if systemRootsErr != nil {
- systemRoots = nil
- }
-}
-
-var forceFallback = godebug.New("x509usefallbackroots")
-
-// SetFallbackRoots sets the roots to use during certificate verification, if no
-// custom roots are specified and a platform verifier or a system certificate
-// pool is not available (for instance in a container which does not have a root
-// certificate bundle). SetFallbackRoots will panic if roots is nil.
-//
-// SetFallbackRoots may only be called once, if called multiple times it will
-// panic.
-//
-// The fallback behavior can be forced on all platforms, even when there is a
-// system certificate pool, by setting GODEBUG=x509usefallbackroots=1 (note that
-// on Windows and macOS this will disable usage of the platform verification
-// APIs and cause the pure Go verifier to be used). Setting
-// x509usefallbackroots=1 without calling SetFallbackRoots has no effect.
-func SetFallbackRoots(roots *CertPool) {
- if roots == nil {
- panic("roots must be non-nil")
- }
-
- // trigger initSystemRoots if it hasn't already been called before we
- // take the lock
- _ = systemRootsPool()
-
- systemRootsMu.Lock()
- defer systemRootsMu.Unlock()
-
- if fallbacksSet {
- panic("SetFallbackRoots has already been called")
- }
- fallbacksSet = true
-
- if systemRoots != nil && (systemRoots.len() > 0 || systemRoots.systemPool) && forceFallback.Value() != "1" {
- return
- }
- systemRoots, systemRootsErr = roots, nil
-}
diff --git a/contrib/go/_std_1.20/src/crypto/x509/root_unix.go b/contrib/go/_std_1.20/src/crypto/x509/root_unix.go
deleted file mode 100644
index aa54f891ca..0000000000
--- a/contrib/go/_std_1.20/src/crypto/x509/root_unix.go
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2011 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.
-
-//go:build aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
-
-package x509
-
-import (
- "io/fs"
- "os"
- "path/filepath"
- "strings"
-)
-
-const (
- // certFileEnv is the environment variable which identifies where to locate
- // the SSL certificate file. If set this overrides the system default.
- certFileEnv = "SSL_CERT_FILE"
-
- // certDirEnv is the environment variable which identifies which directory
- // to check for SSL certificate files. If set this overrides the system default.
- // It is a colon separated list of directories.
- // See https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html.
- certDirEnv = "SSL_CERT_DIR"
-)
-
-func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
- return nil, nil
-}
-
-func loadSystemRoots() (*CertPool, error) {
- roots := NewCertPool()
-
- files := certFiles
- if f := os.Getenv(certFileEnv); f != "" {
- files = []string{f}
- }
-
- var firstErr error
- for _, file := range files {
- data, err := os.ReadFile(file)
- if err == nil {
- roots.AppendCertsFromPEM(data)
- break
- }
- if firstErr == nil && !os.IsNotExist(err) {
- firstErr = err
- }
- }
-
- dirs := certDirectories
- if d := os.Getenv(certDirEnv); d != "" {
- // OpenSSL and BoringSSL both use ":" as the SSL_CERT_DIR separator.
- // See:
- // * https://golang.org/issue/35325
- // * https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html
- dirs = strings.Split(d, ":")
- }
-
- for _, directory := range dirs {
- fis, err := readUniqueDirectoryEntries(directory)
- if err != nil {
- if firstErr == nil && !os.IsNotExist(err) {
- firstErr = err
- }
- continue
- }
- for _, fi := range fis {
- data, err := os.ReadFile(directory + "/" + fi.Name())
- if err == nil {
- roots.AppendCertsFromPEM(data)
- }
- }
- }
-
- if roots.len() > 0 || firstErr == nil {
- return roots, nil
- }
-
- return nil, firstErr
-}
-
-// readUniqueDirectoryEntries is like os.ReadDir but omits
-// symlinks that point within the directory.
-func readUniqueDirectoryEntries(dir string) ([]fs.DirEntry, error) {
- files, err := os.ReadDir(dir)
- if err != nil {
- return nil, err
- }
- uniq := files[:0]
- for _, f := range files {
- if !isSameDirSymlink(f, dir) {
- uniq = append(uniq, f)
- }
- }
- return uniq, nil
-}
-
-// isSameDirSymlink reports whether fi in dir is a symlink with a
-// target not containing a slash.
-func isSameDirSymlink(f fs.DirEntry, dir string) bool {
- if f.Type()&fs.ModeSymlink == 0 {
- return false
- }
- target, err := os.Readlink(filepath.Join(dir, f.Name()))
- return err == nil && !strings.Contains(target, "/")
-}
diff --git a/contrib/go/_std_1.20/src/crypto/x509/root_windows.go b/contrib/go/_std_1.20/src/crypto/x509/root_windows.go
deleted file mode 100644
index 76d6e6ac70..0000000000
--- a/contrib/go/_std_1.20/src/crypto/x509/root_windows.go
+++ /dev/null
@@ -1,276 +0,0 @@
-// Copyright 2012 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 x509
-
-import (
- "bytes"
- "errors"
- "syscall"
- "unsafe"
-)
-
-func loadSystemRoots() (*CertPool, error) {
- return &CertPool{systemPool: true}, nil
-}
-
-// Creates a new *syscall.CertContext representing the leaf certificate in an in-memory
-// certificate store containing itself and all of the intermediate certificates specified
-// in the opts.Intermediates CertPool.
-//
-// A pointer to the in-memory store is available in the returned CertContext's Store field.
-// The store is automatically freed when the CertContext is freed using
-// syscall.CertFreeCertificateContext.
-func createStoreContext(leaf *Certificate, opts *VerifyOptions) (*syscall.CertContext, error) {
- var storeCtx *syscall.CertContext
-
- leafCtx, err := syscall.CertCreateCertificateContext(syscall.X509_ASN_ENCODING|syscall.PKCS_7_ASN_ENCODING, &leaf.Raw[0], uint32(len(leaf.Raw)))
- if err != nil {
- return nil, err
- }
- defer syscall.CertFreeCertificateContext(leafCtx)
-
- handle, err := syscall.CertOpenStore(syscall.CERT_STORE_PROV_MEMORY, 0, 0, syscall.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, 0)
- if err != nil {
- return nil, err
- }
- defer syscall.CertCloseStore(handle, 0)
-
- err = syscall.CertAddCertificateContextToStore(handle, leafCtx, syscall.CERT_STORE_ADD_ALWAYS, &storeCtx)
- if err != nil {
- return nil, err
- }
-
- if opts.Intermediates != nil {
- for i := 0; i < opts.Intermediates.len(); i++ {
- intermediate, err := opts.Intermediates.cert(i)
- if err != nil {
- return nil, err
- }
- ctx, err := syscall.CertCreateCertificateContext(syscall.X509_ASN_ENCODING|syscall.PKCS_7_ASN_ENCODING, &intermediate.Raw[0], uint32(len(intermediate.Raw)))
- if err != nil {
- return nil, err
- }
-
- err = syscall.CertAddCertificateContextToStore(handle, ctx, syscall.CERT_STORE_ADD_ALWAYS, nil)
- syscall.CertFreeCertificateContext(ctx)
- if err != nil {
- return nil, err
- }
- }
- }
-
- return storeCtx, nil
-}
-
-// extractSimpleChain extracts the final certificate chain from a CertSimpleChain.
-func extractSimpleChain(simpleChain **syscall.CertSimpleChain, count int) (chain []*Certificate, err error) {
- if simpleChain == nil || count == 0 {
- return nil, errors.New("x509: invalid simple chain")
- }
-
- simpleChains := unsafe.Slice(simpleChain, count)
- lastChain := simpleChains[count-1]
- elements := unsafe.Slice(lastChain.Elements, lastChain.NumElements)
- for i := 0; i < int(lastChain.NumElements); i++ {
- // Copy the buf, since ParseCertificate does not create its own copy.
- cert := elements[i].CertContext
- encodedCert := unsafe.Slice(cert.EncodedCert, cert.Length)
- buf := bytes.Clone(encodedCert)
- parsedCert, err := ParseCertificate(buf)
- if err != nil {
- return nil, err
- }
- chain = append(chain, parsedCert)
- }
-
- return chain, nil
-}
-
-// checkChainTrustStatus checks the trust status of the certificate chain, translating
-// any errors it finds into Go errors in the process.
-func checkChainTrustStatus(c *Certificate, chainCtx *syscall.CertChainContext) error {
- if chainCtx.TrustStatus.ErrorStatus != syscall.CERT_TRUST_NO_ERROR {
- status := chainCtx.TrustStatus.ErrorStatus
- switch status {
- case syscall.CERT_TRUST_IS_NOT_TIME_VALID:
- return CertificateInvalidError{c, Expired, ""}
- case syscall.CERT_TRUST_IS_NOT_VALID_FOR_USAGE:
- return CertificateInvalidError{c, IncompatibleUsage, ""}
- // TODO(filippo): surface more error statuses.
- default:
- return UnknownAuthorityError{c, nil, nil}
- }
- }
- return nil
-}
-
-// checkChainSSLServerPolicy checks that the certificate chain in chainCtx is valid for
-// use as a certificate chain for a SSL/TLS server.
-func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertChainContext, opts *VerifyOptions) error {
- servernamep, err := syscall.UTF16PtrFromString(opts.DNSName)
- if err != nil {
- return err
- }
- sslPara := &syscall.SSLExtraCertChainPolicyPara{
- AuthType: syscall.AUTHTYPE_SERVER,
- ServerName: servernamep,
- }
- sslPara.Size = uint32(unsafe.Sizeof(*sslPara))
-
- para := &syscall.CertChainPolicyPara{
- ExtraPolicyPara: (syscall.Pointer)(unsafe.Pointer(sslPara)),
- }
- para.Size = uint32(unsafe.Sizeof(*para))
-
- status := syscall.CertChainPolicyStatus{}
- err = syscall.CertVerifyCertificateChainPolicy(syscall.CERT_CHAIN_POLICY_SSL, chainCtx, para, &status)
- if err != nil {
- return err
- }
-
- // TODO(mkrautz): use the lChainIndex and lElementIndex fields
- // of the CertChainPolicyStatus to provide proper context, instead
- // using c.
- if status.Error != 0 {
- switch status.Error {
- case syscall.CERT_E_EXPIRED:
- return CertificateInvalidError{c, Expired, ""}
- case syscall.CERT_E_CN_NO_MATCH:
- return HostnameError{c, opts.DNSName}
- case syscall.CERT_E_UNTRUSTEDROOT:
- return UnknownAuthorityError{c, nil, nil}
- default:
- return UnknownAuthorityError{c, nil, nil}
- }
- }
-
- return nil
-}
-
-// windowsExtKeyUsageOIDs are the C NUL-terminated string representations of the
-// OIDs for use with the Windows API.
-var windowsExtKeyUsageOIDs = make(map[ExtKeyUsage][]byte, len(extKeyUsageOIDs))
-
-func init() {
- for _, eku := range extKeyUsageOIDs {
- windowsExtKeyUsageOIDs[eku.extKeyUsage] = []byte(eku.oid.String() + "\x00")
- }
-}
-
-func verifyChain(c *Certificate, chainCtx *syscall.CertChainContext, opts *VerifyOptions) (chain []*Certificate, err error) {
- err = checkChainTrustStatus(c, chainCtx)
- if err != nil {
- return nil, err
- }
-
- if opts != nil && len(opts.DNSName) > 0 {
- err = checkChainSSLServerPolicy(c, chainCtx, opts)
- if err != nil {
- return nil, err
- }
- }
-
- chain, err = extractSimpleChain(chainCtx.Chains, int(chainCtx.ChainCount))
- if err != nil {
- return nil, err
- }
- if len(chain) == 0 {
- return nil, errors.New("x509: internal error: system verifier returned an empty chain")
- }
-
- // Mitigate CVE-2020-0601, where the Windows system verifier might be
- // tricked into using custom curve parameters for a trusted root, by
- // double-checking all ECDSA signatures. If the system was tricked into
- // using spoofed parameters, the signature will be invalid for the correct
- // ones we parsed. (We don't support custom curves ourselves.)
- for i, parent := range chain[1:] {
- if parent.PublicKeyAlgorithm != ECDSA {
- continue
- }
- if err := parent.CheckSignature(chain[i].SignatureAlgorithm,
- chain[i].RawTBSCertificate, chain[i].Signature); err != nil {
- return nil, err
- }
- }
- return chain, nil
-}
-
-// systemVerify is like Verify, except that it uses CryptoAPI calls
-// to build certificate chains and verify them.
-func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
- storeCtx, err := createStoreContext(c, opts)
- if err != nil {
- return nil, err
- }
- defer syscall.CertFreeCertificateContext(storeCtx)
-
- para := new(syscall.CertChainPara)
- para.Size = uint32(unsafe.Sizeof(*para))
-
- keyUsages := opts.KeyUsages
- if len(keyUsages) == 0 {
- keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
- }
- oids := make([]*byte, 0, len(keyUsages))
- for _, eku := range keyUsages {
- if eku == ExtKeyUsageAny {
- oids = nil
- break
- }
- if oid, ok := windowsExtKeyUsageOIDs[eku]; ok {
- oids = append(oids, &oid[0])
- }
- }
- if oids != nil {
- para.RequestedUsage.Type = syscall.USAGE_MATCH_TYPE_OR
- para.RequestedUsage.Usage.Length = uint32(len(oids))
- para.RequestedUsage.Usage.UsageIdentifiers = &oids[0]
- } else {
- para.RequestedUsage.Type = syscall.USAGE_MATCH_TYPE_AND
- para.RequestedUsage.Usage.Length = 0
- para.RequestedUsage.Usage.UsageIdentifiers = nil
- }
-
- var verifyTime *syscall.Filetime
- if opts != nil && !opts.CurrentTime.IsZero() {
- ft := syscall.NsecToFiletime(opts.CurrentTime.UnixNano())
- verifyTime = &ft
- }
-
- // The default is to return only the highest quality chain,
- // setting this flag will add additional lower quality contexts.
- // These are returned in the LowerQualityChains field.
- const CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS = 0x00000080
-
- // CertGetCertificateChain will traverse Windows's root stores in an attempt to build a verified certificate chain
- var topCtx *syscall.CertChainContext
- err = syscall.CertGetCertificateChain(syscall.Handle(0), storeCtx, verifyTime, storeCtx.Store, para, CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS, 0, &topCtx)
- if err != nil {
- return nil, err
- }
- defer syscall.CertFreeCertificateChain(topCtx)
-
- chain, topErr := verifyChain(c, topCtx, opts)
- if topErr == nil {
- chains = append(chains, chain)
- }
-
- if lqCtxCount := topCtx.LowerQualityChainCount; lqCtxCount > 0 {
- lqCtxs := unsafe.Slice(topCtx.LowerQualityChains, lqCtxCount)
- for _, ctx := range lqCtxs {
- chain, err := verifyChain(c, ctx, opts)
- if err == nil {
- chains = append(chains, chain)
- }
- }
- }
-
- if len(chains) == 0 {
- // Return the error from the highest quality context.
- return nil, topErr
- }
-
- return chains, nil
-}
diff --git a/contrib/go/_std_1.20/src/crypto/x509/sec1.go b/contrib/go/_std_1.20/src/crypto/x509/sec1.go
deleted file mode 100644
index 027c17c43c..0000000000
--- a/contrib/go/_std_1.20/src/crypto/x509/sec1.go
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2012 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 x509
-
-import (
- "crypto/ecdh"
- "crypto/ecdsa"
- "crypto/elliptic"
- "encoding/asn1"
- "errors"
- "fmt"
- "math/big"
-)
-
-const ecPrivKeyVersion = 1
-
-// ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure.
-// References:
-//
-// RFC 5915
-// SEC1 - http://www.secg.org/sec1-v2.pdf
-//
-// Per RFC 5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in
-// most cases it is not.
-type ecPrivateKey struct {
- Version int
- PrivateKey []byte
- NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
- PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"`
-}
-
-// ParseECPrivateKey parses an EC private key in SEC 1, ASN.1 DER form.
-//
-// This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY".
-func ParseECPrivateKey(der []byte) (*ecdsa.PrivateKey, error) {
- return parseECPrivateKey(nil, der)
-}
-
-// MarshalECPrivateKey converts an EC private key to SEC 1, ASN.1 DER form.
-//
-// This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY".
-// For a more flexible key format which is not EC specific, use
-// MarshalPKCS8PrivateKey.
-func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) {
- oid, ok := oidFromNamedCurve(key.Curve)
- if !ok {
- return nil, errors.New("x509: unknown elliptic curve")
- }
-
- return marshalECPrivateKeyWithOID(key, oid)
-}
-
-// marshalECPrivateKeyWithOID marshals an EC private key into ASN.1, DER format and
-// sets the curve ID to the given OID, or omits it if OID is nil.
-func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectIdentifier) ([]byte, error) {
- if !key.Curve.IsOnCurve(key.X, key.Y) {
- return nil, errors.New("invalid elliptic key public key")
- }
- privateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8)
- return asn1.Marshal(ecPrivateKey{
- Version: 1,
- PrivateKey: key.D.FillBytes(privateKey),
- NamedCurveOID: oid,
- PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)},
- })
-}
-
-// marshalECPrivateKeyWithOID marshals an EC private key into ASN.1, DER format
-// suitable for NIST curves.
-func marshalECDHPrivateKey(key *ecdh.PrivateKey) ([]byte, error) {
- return asn1.Marshal(ecPrivateKey{
- Version: 1,
- PrivateKey: key.Bytes(),
- PublicKey: asn1.BitString{Bytes: key.PublicKey().Bytes()},
- })
-}
-
-// parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure.
-// The OID for the named curve may be provided from another source (such as
-// the PKCS8 container) - if it is provided then use this instead of the OID
-// that may exist in the EC private key structure.
-func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) {
- var privKey ecPrivateKey
- if _, err := asn1.Unmarshal(der, &privKey); err != nil {
- if _, err := asn1.Unmarshal(der, &pkcs8{}); err == nil {
- return nil, errors.New("x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)")
- }
- if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil {
- return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)")
- }
- return nil, errors.New("x509: failed to parse EC private key: " + err.Error())
- }
- if privKey.Version != ecPrivKeyVersion {
- return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version)
- }
-
- var curve elliptic.Curve
- if namedCurveOID != nil {
- curve = namedCurveFromOID(*namedCurveOID)
- } else {
- curve = namedCurveFromOID(privKey.NamedCurveOID)
- }
- if curve == nil {
- return nil, errors.New("x509: unknown elliptic curve")
- }
-
- k := new(big.Int).SetBytes(privKey.PrivateKey)
- curveOrder := curve.Params().N
- if k.Cmp(curveOrder) >= 0 {
- return nil, errors.New("x509: invalid elliptic curve private key value")
- }
- priv := new(ecdsa.PrivateKey)
- priv.Curve = curve
- priv.D = k
-
- privateKey := make([]byte, (curveOrder.BitLen()+7)/8)
-
- // Some private keys have leading zero padding. This is invalid
- // according to [SEC1], but this code will ignore it.
- for len(privKey.PrivateKey) > len(privateKey) {
- if privKey.PrivateKey[0] != 0 {
- return nil, errors.New("x509: invalid private key length")
- }
- privKey.PrivateKey = privKey.PrivateKey[1:]
- }
-
- // Some private keys remove all leading zeros, this is also invalid
- // according to [SEC1] but since OpenSSL used to do this, we ignore
- // this too.
- copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
- priv.X, priv.Y = curve.ScalarBaseMult(privateKey)
-
- return priv, nil
-}
diff --git a/contrib/go/_std_1.20/src/crypto/x509/verify.go b/contrib/go/_std_1.20/src/crypto/x509/verify.go
deleted file mode 100644
index 0b01f8b475..0000000000
--- a/contrib/go/_std_1.20/src/crypto/x509/verify.go
+++ /dev/null
@@ -1,1179 +0,0 @@
-// Copyright 2011 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 x509
-
-import (
- "bytes"
- "crypto"
- "crypto/x509/pkix"
- "errors"
- "fmt"
- "net"
- "net/url"
- "reflect"
- "runtime"
- "strings"
- "time"
- "unicode/utf8"
-)
-
-type InvalidReason int
-
-const (
- // NotAuthorizedToSign results when a certificate is signed by another
- // which isn't marked as a CA certificate.
- NotAuthorizedToSign InvalidReason = iota
- // Expired results when a certificate has expired, based on the time
- // given in the VerifyOptions.
- Expired
- // CANotAuthorizedForThisName results when an intermediate or root
- // certificate has a name constraint which doesn't permit a DNS or
- // other name (including IP address) in the leaf certificate.
- CANotAuthorizedForThisName
- // TooManyIntermediates results when a path length constraint is
- // violated.
- TooManyIntermediates
- // IncompatibleUsage results when the certificate's key usage indicates
- // that it may only be used for a different purpose.
- IncompatibleUsage
- // NameMismatch results when the subject name of a parent certificate
- // does not match the issuer name in the child.
- NameMismatch
- // NameConstraintsWithoutSANs is a legacy error and is no longer returned.
- NameConstraintsWithoutSANs
- // UnconstrainedName results when a CA certificate contains permitted
- // name constraints, but leaf certificate contains a name of an
- // unsupported or unconstrained type.
- UnconstrainedName
- // TooManyConstraints results when the number of comparison operations
- // needed to check a certificate exceeds the limit set by
- // VerifyOptions.MaxConstraintComparisions. This limit exists to
- // prevent pathological certificates can consuming excessive amounts of
- // CPU time to verify.
- TooManyConstraints
- // CANotAuthorizedForExtKeyUsage results when an intermediate or root
- // certificate does not permit a requested extended key usage.
- CANotAuthorizedForExtKeyUsage
-)
-
-// CertificateInvalidError results when an odd error occurs. Users of this
-// library probably want to handle all these errors uniformly.
-type CertificateInvalidError struct {
- Cert *Certificate
- Reason InvalidReason
- Detail string
-}
-
-func (e CertificateInvalidError) Error() string {
- switch e.Reason {
- case NotAuthorizedToSign:
- return "x509: certificate is not authorized to sign other certificates"
- case Expired:
- return "x509: certificate has expired or is not yet valid: " + e.Detail
- case CANotAuthorizedForThisName:
- return "x509: a root or intermediate certificate is not authorized to sign for this name: " + e.Detail
- case CANotAuthorizedForExtKeyUsage:
- return "x509: a root or intermediate certificate is not authorized for an extended key usage: " + e.Detail
- case TooManyIntermediates:
- return "x509: too many intermediates for path length constraint"
- case IncompatibleUsage:
- return "x509: certificate specifies an incompatible key usage"
- case NameMismatch:
- return "x509: issuer name does not match subject from issuing certificate"
- case NameConstraintsWithoutSANs:
- return "x509: issuer has name constraints but leaf doesn't have a SAN extension"
- case UnconstrainedName:
- return "x509: issuer has name constraints but leaf contains unknown or unconstrained name: " + e.Detail
- }
- return "x509: unknown error"
-}
-
-// HostnameError results when the set of authorized names doesn't match the
-// requested name.
-type HostnameError struct {
- Certificate *Certificate
- Host string
-}
-
-func (h HostnameError) Error() string {
- c := h.Certificate
-
- if !c.hasSANExtension() && matchHostnames(c.Subject.CommonName, h.Host) {
- return "x509: certificate relies on legacy Common Name field, use SANs instead"
- }
-
- var valid string
- if ip := net.ParseIP(h.Host); ip != nil {
- // Trying to validate an IP
- if len(c.IPAddresses) == 0 {
- return "x509: cannot validate certificate for " + h.Host + " because it doesn't contain any IP SANs"
- }
- for _, san := range c.IPAddresses {
- if len(valid) > 0 {
- valid += ", "
- }
- valid += san.String()
- }
- } else {
- valid = strings.Join(c.DNSNames, ", ")
- }
-
- if len(valid) == 0 {
- return "x509: certificate is not valid for any names, but wanted to match " + h.Host
- }
- return "x509: certificate is valid for " + valid + ", not " + h.Host
-}
-
-// UnknownAuthorityError results when the certificate issuer is unknown
-type UnknownAuthorityError struct {
- Cert *Certificate
- // hintErr contains an error that may be helpful in determining why an
- // authority wasn't found.
- hintErr error
- // hintCert contains a possible authority certificate that was rejected
- // because of the error in hintErr.
- hintCert *Certificate
-}
-
-func (e UnknownAuthorityError) Error() string {
- s := "x509: certificate signed by unknown authority"
- if e.hintErr != nil {
- certName := e.hintCert.Subject.CommonName
- if len(certName) == 0 {
- if len(e.hintCert.Subject.Organization) > 0 {
- certName = e.hintCert.Subject.Organization[0]
- } else {
- certName = "serial:" + e.hintCert.SerialNumber.String()
- }
- }
- s += fmt.Sprintf(" (possibly because of %q while trying to verify candidate authority certificate %q)", e.hintErr, certName)
- }
- return s
-}
-
-// SystemRootsError results when we fail to load the system root certificates.
-type SystemRootsError struct {
- Err error
-}
-
-func (se SystemRootsError) Error() string {
- msg := "x509: failed to load system roots and no roots provided"
- if se.Err != nil {
- return msg + "; " + se.Err.Error()
- }
- return msg
-}
-
-func (se SystemRootsError) Unwrap() error { return se.Err }
-
-// errNotParsed is returned when a certificate without ASN.1 contents is
-// verified. Platform-specific verification needs the ASN.1 contents.
-var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificate")
-
-// VerifyOptions contains parameters for Certificate.Verify.
-type VerifyOptions struct {
- // DNSName, if set, is checked against the leaf certificate with
- // Certificate.VerifyHostname or the platform verifier.
- DNSName string
-
- // Intermediates is an optional pool of certificates that are not trust
- // anchors, but can be used to form a chain from the leaf certificate to a
- // root certificate.
- Intermediates *CertPool
- // Roots is the set of trusted root certificates the leaf certificate needs
- // to chain up to. If nil, the system roots or the platform verifier are used.
- Roots *CertPool
-
- // CurrentTime is used to check the validity of all certificates in the
- // chain. If zero, the current time is used.
- CurrentTime time.Time
-
- // KeyUsages specifies which Extended Key Usage values are acceptable. A
- // chain is accepted if it allows any of the listed values. An empty list
- // means ExtKeyUsageServerAuth. To accept any key usage, include ExtKeyUsageAny.
- KeyUsages []ExtKeyUsage
-
- // MaxConstraintComparisions is the maximum number of comparisons to
- // perform when checking a given certificate's name constraints. If
- // zero, a sensible default is used. This limit prevents pathological
- // certificates from consuming excessive amounts of CPU time when
- // validating. It does not apply to the platform verifier.
- MaxConstraintComparisions int
-}
-
-const (
- leafCertificate = iota
- intermediateCertificate
- rootCertificate
-)
-
-// rfc2821Mailbox represents a “mailbox” (which is an email address to most
-// people) by breaking it into the “local” (i.e. before the '@') and “domain”
-// parts.
-type rfc2821Mailbox struct {
- local, domain string
-}
-
-// parseRFC2821Mailbox parses an email address into local and domain parts,
-// based on the ABNF for a “Mailbox” from RFC 2821. According to RFC 5280,
-// Section 4.2.1.6 that's correct for an rfc822Name from a certificate: “The
-// format of an rfc822Name is a "Mailbox" as defined in RFC 2821, Section 4.1.2”.
-func parseRFC2821Mailbox(in string) (mailbox rfc2821Mailbox, ok bool) {
- if len(in) == 0 {
- return mailbox, false
- }
-
- localPartBytes := make([]byte, 0, len(in)/2)
-
- if in[0] == '"' {
- // Quoted-string = DQUOTE *qcontent DQUOTE
- // non-whitespace-control = %d1-8 / %d11 / %d12 / %d14-31 / %d127
- // qcontent = qtext / quoted-pair
- // qtext = non-whitespace-control /
- // %d33 / %d35-91 / %d93-126
- // quoted-pair = ("\" text) / obs-qp
- // text = %d1-9 / %d11 / %d12 / %d14-127 / obs-text
- //
- // (Names beginning with “obs-” are the obsolete syntax from RFC 2822,
- // Section 4. Since it has been 16 years, we no longer accept that.)
- in = in[1:]
- QuotedString:
- for {
- if len(in) == 0 {
- return mailbox, false
- }
- c := in[0]
- in = in[1:]
-
- switch {
- case c == '"':
- break QuotedString
-
- case c == '\\':
- // quoted-pair
- if len(in) == 0 {
- return mailbox, false
- }
- if in[0] == 11 ||
- in[0] == 12 ||
- (1 <= in[0] && in[0] <= 9) ||
- (14 <= in[0] && in[0] <= 127) {
- localPartBytes = append(localPartBytes, in[0])
- in = in[1:]
- } else {
- return mailbox, false
- }
-
- case c == 11 ||
- c == 12 ||
- // Space (char 32) is not allowed based on the
- // BNF, but RFC 3696 gives an example that
- // assumes that it is. Several “verified”
- // errata continue to argue about this point.
- // We choose to accept it.
- c == 32 ||
- c == 33 ||
- c == 127 ||
- (1 <= c && c <= 8) ||
- (14 <= c && c <= 31) ||
- (35 <= c && c <= 91) ||
- (93 <= c && c <= 126):
- // qtext
- localPartBytes = append(localPartBytes, c)
-
- default:
- return mailbox, false
- }
- }
- } else {
- // Atom ("." Atom)*
- NextChar:
- for len(in) > 0 {
- // atext from RFC 2822, Section 3.2.4
- c := in[0]
-
- switch {
- case c == '\\':
- // Examples given in RFC 3696 suggest that
- // escaped characters can appear outside of a
- // quoted string. Several “verified” errata
- // continue to argue the point. We choose to
- // accept it.
- in = in[1:]
- if len(in) == 0 {
- return mailbox, false
- }
- fallthrough
-
- case ('0' <= c && c <= '9') ||
- ('a' <= c && c <= 'z') ||
- ('A' <= c && c <= 'Z') ||
- c == '!' || c == '#' || c == '$' || c == '%' ||
- c == '&' || c == '\'' || c == '*' || c == '+' ||
- c == '-' || c == '/' || c == '=' || c == '?' ||
- c == '^' || c == '_' || c == '`' || c == '{' ||
- c == '|' || c == '}' || c == '~' || c == '.':
- localPartBytes = append(localPartBytes, in[0])
- in = in[1:]
-
- default:
- break NextChar
- }
- }
-
- if len(localPartBytes) == 0 {
- return mailbox, false
- }
-
- // From RFC 3696, Section 3:
- // “period (".") may also appear, but may not be used to start
- // or end the local part, nor may two or more consecutive
- // periods appear.”
- twoDots := []byte{'.', '.'}
- if localPartBytes[0] == '.' ||
- localPartBytes[len(localPartBytes)-1] == '.' ||
- bytes.Contains(localPartBytes, twoDots) {
- return mailbox, false
- }
- }
-
- if len(in) == 0 || in[0] != '@' {
- return mailbox, false
- }
- in = in[1:]
-
- // The RFC species a format for domains, but that's known to be
- // violated in practice so we accept that anything after an '@' is the
- // domain part.
- if _, ok := domainToReverseLabels(in); !ok {
- return mailbox, false
- }
-
- mailbox.local = string(localPartBytes)
- mailbox.domain = in
- return mailbox, true
-}
-
-// domainToReverseLabels converts a textual domain name like foo.example.com to
-// the list of labels in reverse order, e.g. ["com", "example", "foo"].
-func domainToReverseLabels(domain string) (reverseLabels []string, ok bool) {
- for len(domain) > 0 {
- if i := strings.LastIndexByte(domain, '.'); i == -1 {
- reverseLabels = append(reverseLabels, domain)
- domain = ""
- } else {
- reverseLabels = append(reverseLabels, domain[i+1:])
- domain = domain[:i]
- }
- }
-
- if len(reverseLabels) > 0 && len(reverseLabels[0]) == 0 {
- // An empty label at the end indicates an absolute value.
- return nil, false
- }
-
- for _, label := range reverseLabels {
- if len(label) == 0 {
- // Empty labels are otherwise invalid.
- return nil, false
- }
-
- for _, c := range label {
- if c < 33 || c > 126 {
- // Invalid character.
- return nil, false
- }
- }
- }
-
- return reverseLabels, true
-}
-
-func matchEmailConstraint(mailbox rfc2821Mailbox, constraint string) (bool, error) {
- // If the constraint contains an @, then it specifies an exact mailbox
- // name.
- if strings.Contains(constraint, "@") {
- constraintMailbox, ok := parseRFC2821Mailbox(constraint)
- if !ok {
- return false, fmt.Errorf("x509: internal error: cannot parse constraint %q", constraint)
- }
- return mailbox.local == constraintMailbox.local && strings.EqualFold(mailbox.domain, constraintMailbox.domain), nil
- }
-
- // Otherwise the constraint is like a DNS constraint of the domain part
- // of the mailbox.
- return matchDomainConstraint(mailbox.domain, constraint)
-}
-
-func matchURIConstraint(uri *url.URL, constraint string) (bool, error) {
- // From RFC 5280, Section 4.2.1.10:
- // “a uniformResourceIdentifier that does not include an authority
- // component with a host name specified as a fully qualified domain
- // name (e.g., if the URI either does not include an authority
- // component or includes an authority component in which the host name
- // is specified as an IP address), then the application MUST reject the
- // certificate.”
-
- host := uri.Host
- if len(host) == 0 {
- return false, fmt.Errorf("URI with empty host (%q) cannot be matched against constraints", uri.String())
- }
-
- if strings.Contains(host, ":") && !strings.HasSuffix(host, "]") {
- var err error
- host, _, err = net.SplitHostPort(uri.Host)
- if err != nil {
- return false, err
- }
- }
-
- if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") ||
- net.ParseIP(host) != nil {
- return false, fmt.Errorf("URI with IP (%q) cannot be matched against constraints", uri.String())
- }
-
- return matchDomainConstraint(host, constraint)
-}
-
-func matchIPConstraint(ip net.IP, constraint *net.IPNet) (bool, error) {
- if len(ip) != len(constraint.IP) {
- return false, nil
- }
-
- for i := range ip {
- if mask := constraint.Mask[i]; ip[i]&mask != constraint.IP[i]&mask {
- return false, nil
- }
- }
-
- return true, nil
-}
-
-func matchDomainConstraint(domain, constraint string) (bool, error) {
- // The meaning of zero length constraints is not specified, but this
- // code follows NSS and accepts them as matching everything.
- if len(constraint) == 0 {
- return true, nil
- }
-
- domainLabels, ok := domainToReverseLabels(domain)
- if !ok {
- return false, fmt.Errorf("x509: internal error: cannot parse domain %q", domain)
- }
-
- // RFC 5280 says that a leading period in a domain name means that at
- // least one label must be prepended, but only for URI and email
- // constraints, not DNS constraints. The code also supports that
- // behaviour for DNS constraints.
-
- mustHaveSubdomains := false
- if constraint[0] == '.' {
- mustHaveSubdomains = true
- constraint = constraint[1:]
- }
-
- constraintLabels, ok := domainToReverseLabels(constraint)
- if !ok {
- return false, fmt.Errorf("x509: internal error: cannot parse domain %q", constraint)
- }
-
- if len(domainLabels) < len(constraintLabels) ||
- (mustHaveSubdomains && len(domainLabels) == len(constraintLabels)) {
- return false, nil
- }
-
- for i, constraintLabel := range constraintLabels {
- if !strings.EqualFold(constraintLabel, domainLabels[i]) {
- return false, nil
- }
- }
-
- return true, nil
-}
-
-// checkNameConstraints checks that c permits a child certificate to claim the
-// given name, of type nameType. The argument parsedName contains the parsed
-// form of name, suitable for passing to the match function. The total number
-// of comparisons is tracked in the given count and should not exceed the given
-// limit.
-func (c *Certificate) checkNameConstraints(count *int,
- maxConstraintComparisons int,
- nameType string,
- name string,
- parsedName any,
- match func(parsedName, constraint any) (match bool, err error),
- permitted, excluded any) error {
-
- excludedValue := reflect.ValueOf(excluded)
-
- *count += excludedValue.Len()
- if *count > maxConstraintComparisons {
- return CertificateInvalidError{c, TooManyConstraints, ""}
- }
-
- for i := 0; i < excludedValue.Len(); i++ {
- constraint := excludedValue.Index(i).Interface()
- match, err := match(parsedName, constraint)
- if err != nil {
- return CertificateInvalidError{c, CANotAuthorizedForThisName, err.Error()}
- }
-
- if match {
- return CertificateInvalidError{c, CANotAuthorizedForThisName, fmt.Sprintf("%s %q is excluded by constraint %q", nameType, name, constraint)}
- }
- }
-
- permittedValue := reflect.ValueOf(permitted)
-
- *count += permittedValue.Len()
- if *count > maxConstraintComparisons {
- return CertificateInvalidError{c, TooManyConstraints, ""}
- }
-
- ok := true
- for i := 0; i < permittedValue.Len(); i++ {
- constraint := permittedValue.Index(i).Interface()
-
- var err error
- if ok, err = match(parsedName, constraint); err != nil {
- return CertificateInvalidError{c, CANotAuthorizedForThisName, err.Error()}
- }
-
- if ok {
- break
- }
- }
-
- if !ok {
- return CertificateInvalidError{c, CANotAuthorizedForThisName, fmt.Sprintf("%s %q is not permitted by any constraint", nameType, name)}
- }
-
- return nil
-}
-
-// isValid performs validity checks on c given that it is a candidate to append
-// to the chain in currentChain.
-func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *VerifyOptions) error {
- if len(c.UnhandledCriticalExtensions) > 0 {
- return UnhandledCriticalExtension{}
- }
-
- if len(currentChain) > 0 {
- child := currentChain[len(currentChain)-1]
- if !bytes.Equal(child.RawIssuer, c.RawSubject) {
- return CertificateInvalidError{c, NameMismatch, ""}
- }
- }
-
- now := opts.CurrentTime
- if now.IsZero() {
- now = time.Now()
- }
- if now.Before(c.NotBefore) {
- return CertificateInvalidError{
- Cert: c,
- Reason: Expired,
- Detail: fmt.Sprintf("current time %s is before %s", now.Format(time.RFC3339), c.NotBefore.Format(time.RFC3339)),
- }
- } else if now.After(c.NotAfter) {
- return CertificateInvalidError{
- Cert: c,
- Reason: Expired,
- Detail: fmt.Sprintf("current time %s is after %s", now.Format(time.RFC3339), c.NotAfter.Format(time.RFC3339)),
- }
- }
-
- maxConstraintComparisons := opts.MaxConstraintComparisions
- if maxConstraintComparisons == 0 {
- maxConstraintComparisons = 250000
- }
- comparisonCount := 0
-
- var leaf *Certificate
- if certType == intermediateCertificate || certType == rootCertificate {
- if len(currentChain) == 0 {
- return errors.New("x509: internal error: empty chain when appending CA cert")
- }
- leaf = currentChain[0]
- }
-
- if (certType == intermediateCertificate || certType == rootCertificate) &&
- c.hasNameConstraints() {
- toCheck := []*Certificate{}
- if leaf.hasSANExtension() {
- toCheck = append(toCheck, leaf)
- }
- if c.hasSANExtension() {
- toCheck = append(toCheck, c)
- }
- for _, sanCert := range toCheck {
- err := forEachSAN(sanCert.getSANExtension(), func(tag int, data []byte) error {
- switch tag {
- case nameTypeEmail:
- name := string(data)
- mailbox, ok := parseRFC2821Mailbox(name)
- if !ok {
- return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox)
- }
-
- if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "email address", name, mailbox,
- func(parsedName, constraint any) (bool, error) {
- return matchEmailConstraint(parsedName.(rfc2821Mailbox), constraint.(string))
- }, c.PermittedEmailAddresses, c.ExcludedEmailAddresses); err != nil {
- return err
- }
-
- case nameTypeDNS:
- name := string(data)
- if _, ok := domainToReverseLabels(name); !ok {
- return fmt.Errorf("x509: cannot parse dnsName %q", name)
- }
-
- if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "DNS name", name, name,
- func(parsedName, constraint any) (bool, error) {
- return matchDomainConstraint(parsedName.(string), constraint.(string))
- }, c.PermittedDNSDomains, c.ExcludedDNSDomains); err != nil {
- return err
- }
-
- case nameTypeURI:
- name := string(data)
- uri, err := url.Parse(name)
- if err != nil {
- return fmt.Errorf("x509: internal error: URI SAN %q failed to parse", name)
- }
-
- if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "URI", name, uri,
- func(parsedName, constraint any) (bool, error) {
- return matchURIConstraint(parsedName.(*url.URL), constraint.(string))
- }, c.PermittedURIDomains, c.ExcludedURIDomains); err != nil {
- return err
- }
-
- case nameTypeIP:
- ip := net.IP(data)
- if l := len(ip); l != net.IPv4len && l != net.IPv6len {
- return fmt.Errorf("x509: internal error: IP SAN %x failed to parse", data)
- }
-
- if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "IP address", ip.String(), ip,
- func(parsedName, constraint any) (bool, error) {
- return matchIPConstraint(parsedName.(net.IP), constraint.(*net.IPNet))
- }, c.PermittedIPRanges, c.ExcludedIPRanges); err != nil {
- return err
- }
-
- default:
- // Unknown SAN types are ignored.
- }
-
- return nil
- })
-
- if err != nil {
- return err
- }
- }
- }
-
- // KeyUsage status flags are ignored. From Engineering Security, Peter
- // Gutmann: A European government CA marked its signing certificates as
- // being valid for encryption only, but no-one noticed. Another
- // European CA marked its signature keys as not being valid for
- // signatures. A different CA marked its own trusted root certificate
- // as being invalid for certificate signing. Another national CA
- // distributed a certificate to be used to encrypt data for the
- // country’s tax authority that was marked as only being usable for
- // digital signatures but not for encryption. Yet another CA reversed
- // the order of the bit flags in the keyUsage due to confusion over
- // encoding endianness, essentially setting a random keyUsage in
- // certificates that it issued. Another CA created a self-invalidating
- // certificate by adding a certificate policy statement stipulating
- // that the certificate had to be used strictly as specified in the
- // keyUsage, and a keyUsage containing a flag indicating that the RSA
- // encryption key could only be used for Diffie-Hellman key agreement.
-
- if certType == intermediateCertificate && (!c.BasicConstraintsValid || !c.IsCA) {
- return CertificateInvalidError{c, NotAuthorizedToSign, ""}
- }
-
- if c.BasicConstraintsValid && c.MaxPathLen >= 0 {
- numIntermediates := len(currentChain) - 1
- if numIntermediates > c.MaxPathLen {
- return CertificateInvalidError{c, TooManyIntermediates, ""}
- }
- }
-
- if !boringAllowCert(c) {
- // IncompatibleUsage is not quite right here,
- // but it's also the "no chains found" error
- // and is close enough.
- return CertificateInvalidError{c, IncompatibleUsage, ""}
- }
-
- return nil
-}
-
-// Verify attempts to verify c by building one or more chains from c to a
-// certificate in opts.Roots, using certificates in opts.Intermediates if
-// needed. If successful, it returns one or more chains where the first
-// element of the chain is c and the last element is from opts.Roots.
-//
-// If opts.Roots is nil, the platform verifier might be used, and
-// verification details might differ from what is described below. If system
-// roots are unavailable the returned error will be of type SystemRootsError.
-//
-// Name constraints in the intermediates will be applied to all names claimed
-// in the chain, not just opts.DNSName. Thus it is invalid for a leaf to claim
-// example.com if an intermediate doesn't permit it, even if example.com is not
-// the name being validated. Note that DirectoryName constraints are not
-// supported.
-//
-// Name constraint validation follows the rules from RFC 5280, with the
-// addition that DNS name constraints may use the leading period format
-// defined for emails and URIs. When a constraint has a leading period
-// it indicates that at least one additional label must be prepended to
-// the constrained name to be considered valid.
-//
-// Extended Key Usage values are enforced nested down a chain, so an intermediate
-// or root that enumerates EKUs prevents a leaf from asserting an EKU not in that
-// list. (While this is not specified, it is common practice in order to limit
-// the types of certificates a CA can issue.)
-//
-// Certificates that use SHA1WithRSA and ECDSAWithSHA1 signatures are not supported,
-// and will not be used to build chains.
-//
-// Certificates other than c in the returned chains should not be modified.
-//
-// WARNING: this function doesn't do any revocation checking.
-func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
- // Platform-specific verification needs the ASN.1 contents so
- // this makes the behavior consistent across platforms.
- if len(c.Raw) == 0 {
- return nil, errNotParsed
- }
- for i := 0; i < opts.Intermediates.len(); i++ {
- c, err := opts.Intermediates.cert(i)
- if err != nil {
- return nil, fmt.Errorf("crypto/x509: error fetching intermediate: %w", err)
- }
- if len(c.Raw) == 0 {
- return nil, errNotParsed
- }
- }
-
- // Use platform verifiers, where available, if Roots is from SystemCertPool.
- if runtime.GOOS == "windows" || runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
- // Don't use the system verifier if the system pool was replaced with a non-system pool,
- // i.e. if SetFallbackRoots was called with x509usefallbackroots=1.
- systemPool := systemRootsPool()
- if opts.Roots == nil && (systemPool == nil || systemPool.systemPool) {
- return c.systemVerify(&opts)
- }
- if opts.Roots != nil && opts.Roots.systemPool {
- platformChains, err := c.systemVerify(&opts)
- // If the platform verifier succeeded, or there are no additional
- // roots, return the platform verifier result. Otherwise, continue
- // with the Go verifier.
- if err == nil || opts.Roots.len() == 0 {
- return platformChains, err
- }
- }
- }
-
- if opts.Roots == nil {
- opts.Roots = systemRootsPool()
- if opts.Roots == nil {
- return nil, SystemRootsError{systemRootsErr}
- }
- }
-
- err = c.isValid(leafCertificate, nil, &opts)
- if err != nil {
- return
- }
-
- if len(opts.DNSName) > 0 {
- err = c.VerifyHostname(opts.DNSName)
- if err != nil {
- return
- }
- }
-
- var candidateChains [][]*Certificate
- if opts.Roots.contains(c) {
- candidateChains = [][]*Certificate{{c}}
- } else {
- candidateChains, err = c.buildChains([]*Certificate{c}, nil, &opts)
- if err != nil {
- return nil, err
- }
- }
-
- if len(opts.KeyUsages) == 0 {
- opts.KeyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
- }
-
- for _, eku := range opts.KeyUsages {
- if eku == ExtKeyUsageAny {
- // If any key usage is acceptable, no need to check the chain for
- // key usages.
- return candidateChains, nil
- }
- }
-
- chains = make([][]*Certificate, 0, len(candidateChains))
- for _, candidate := range candidateChains {
- if checkChainForKeyUsage(candidate, opts.KeyUsages) {
- chains = append(chains, candidate)
- }
- }
-
- if len(chains) == 0 {
- return nil, CertificateInvalidError{c, IncompatibleUsage, ""}
- }
-
- return chains, nil
-}
-
-func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate {
- n := make([]*Certificate, len(chain)+1)
- copy(n, chain)
- n[len(chain)] = cert
- return n
-}
-
-// alreadyInChain checks whether a candidate certificate is present in a chain.
-// Rather than doing a direct byte for byte equivalency check, we check if the
-// subject, public key, and SAN, if present, are equal. This prevents loops that
-// are created by mutual cross-signatures, or other cross-signature bridge
-// oddities.
-func alreadyInChain(candidate *Certificate, chain []*Certificate) bool {
- type pubKeyEqual interface {
- Equal(crypto.PublicKey) bool
- }
-
- var candidateSAN *pkix.Extension
- for _, ext := range candidate.Extensions {
- if ext.Id.Equal(oidExtensionSubjectAltName) {
- candidateSAN = &ext
- break
- }
- }
-
- for _, cert := range chain {
- if !bytes.Equal(candidate.RawSubject, cert.RawSubject) {
- continue
- }
- if !candidate.PublicKey.(pubKeyEqual).Equal(cert.PublicKey) {
- continue
- }
- var certSAN *pkix.Extension
- for _, ext := range cert.Extensions {
- if ext.Id.Equal(oidExtensionSubjectAltName) {
- certSAN = &ext
- break
- }
- }
- if candidateSAN == nil && certSAN == nil {
- return true
- } else if candidateSAN == nil || certSAN == nil {
- return false
- }
- if bytes.Equal(candidateSAN.Value, certSAN.Value) {
- return true
- }
- }
- return false
-}
-
-// maxChainSignatureChecks is the maximum number of CheckSignatureFrom calls
-// that an invocation of buildChains will (transitively) make. Most chains are
-// less than 15 certificates long, so this leaves space for multiple chains and
-// for failed checks due to different intermediates having the same Subject.
-const maxChainSignatureChecks = 100
-
-func (c *Certificate) buildChains(currentChain []*Certificate, sigChecks *int, opts *VerifyOptions) (chains [][]*Certificate, err error) {
- var (
- hintErr error
- hintCert *Certificate
- )
-
- considerCandidate := func(certType int, candidate *Certificate) {
- if alreadyInChain(candidate, currentChain) {
- return
- }
-
- if sigChecks == nil {
- sigChecks = new(int)
- }
- *sigChecks++
- if *sigChecks > maxChainSignatureChecks {
- err = errors.New("x509: signature check attempts limit reached while verifying certificate chain")
- return
- }
-
- if err := c.CheckSignatureFrom(candidate); err != nil {
- if hintErr == nil {
- hintErr = err
- hintCert = candidate
- }
- return
- }
-
- err = candidate.isValid(certType, currentChain, opts)
- if err != nil {
- if hintErr == nil {
- hintErr = err
- hintCert = candidate
- }
- return
- }
-
- switch certType {
- case rootCertificate:
- chains = append(chains, appendToFreshChain(currentChain, candidate))
- case intermediateCertificate:
- var childChains [][]*Certificate
- childChains, err = candidate.buildChains(appendToFreshChain(currentChain, candidate), sigChecks, opts)
- chains = append(chains, childChains...)
- }
- }
-
- for _, root := range opts.Roots.findPotentialParents(c) {
- considerCandidate(rootCertificate, root)
- }
- for _, intermediate := range opts.Intermediates.findPotentialParents(c) {
- considerCandidate(intermediateCertificate, intermediate)
- }
-
- if len(chains) > 0 {
- err = nil
- }
- if len(chains) == 0 && err == nil {
- err = UnknownAuthorityError{c, hintErr, hintCert}
- }
-
- return
-}
-
-func validHostnamePattern(host string) bool { return validHostname(host, true) }
-func validHostnameInput(host string) bool { return validHostname(host, false) }
-
-// validHostname reports whether host is a valid hostname that can be matched or
-// matched against according to RFC 6125 2.2, with some leniency to accommodate
-// legacy values.
-func validHostname(host string, isPattern bool) bool {
- if !isPattern {
- host = strings.TrimSuffix(host, ".")
- }
- if len(host) == 0 {
- return false
- }
-
- for i, part := range strings.Split(host, ".") {
- if part == "" {
- // Empty label.
- return false
- }
- if isPattern && i == 0 && part == "*" {
- // Only allow full left-most wildcards, as those are the only ones
- // we match, and matching literal '*' characters is probably never
- // the expected behavior.
- continue
- }
- for j, c := range part {
- if 'a' <= c && c <= 'z' {
- continue
- }
- if '0' <= c && c <= '9' {
- continue
- }
- if 'A' <= c && c <= 'Z' {
- continue
- }
- if c == '-' && j != 0 {
- continue
- }
- if c == '_' {
- // Not a valid character in hostnames, but commonly
- // found in deployments outside the WebPKI.
- continue
- }
- return false
- }
- }
-
- return true
-}
-
-func matchExactly(hostA, hostB string) bool {
- if hostA == "" || hostA == "." || hostB == "" || hostB == "." {
- return false
- }
- return toLowerCaseASCII(hostA) == toLowerCaseASCII(hostB)
-}
-
-func matchHostnames(pattern, host string) bool {
- pattern = toLowerCaseASCII(pattern)
- host = toLowerCaseASCII(strings.TrimSuffix(host, "."))
-
- if len(pattern) == 0 || len(host) == 0 {
- return false
- }
-
- patternParts := strings.Split(pattern, ".")
- hostParts := strings.Split(host, ".")
-
- if len(patternParts) != len(hostParts) {
- return false
- }
-
- for i, patternPart := range patternParts {
- if i == 0 && patternPart == "*" {
- continue
- }
- if patternPart != hostParts[i] {
- return false
- }
- }
-
- return true
-}
-
-// toLowerCaseASCII returns a lower-case version of in. See RFC 6125 6.4.1. We use
-// an explicitly ASCII function to avoid any sharp corners resulting from
-// performing Unicode operations on DNS labels.
-func toLowerCaseASCII(in string) string {
- // If the string is already lower-case then there's nothing to do.
- isAlreadyLowerCase := true
- for _, c := range in {
- if c == utf8.RuneError {
- // If we get a UTF-8 error then there might be
- // upper-case ASCII bytes in the invalid sequence.
- isAlreadyLowerCase = false
- break
- }
- if 'A' <= c && c <= 'Z' {
- isAlreadyLowerCase = false
- break
- }
- }
-
- if isAlreadyLowerCase {
- return in
- }
-
- out := []byte(in)
- for i, c := range out {
- if 'A' <= c && c <= 'Z' {
- out[i] += 'a' - 'A'
- }
- }
- return string(out)
-}
-
-// VerifyHostname returns nil if c is a valid certificate for the named host.
-// Otherwise it returns an error describing the mismatch.
-//
-// IP addresses can be optionally enclosed in square brackets and are checked
-// against the IPAddresses field. Other names are checked case insensitively
-// against the DNSNames field. If the names are valid hostnames, the certificate
-// fields can have a wildcard as the left-most label.
-//
-// Note that the legacy Common Name field is ignored.
-func (c *Certificate) VerifyHostname(h string) error {
- // IP addresses may be written in [ ].
- candidateIP := h
- if len(h) >= 3 && h[0] == '[' && h[len(h)-1] == ']' {
- candidateIP = h[1 : len(h)-1]
- }
- if ip := net.ParseIP(candidateIP); ip != nil {
- // We only match IP addresses against IP SANs.
- // See RFC 6125, Appendix B.2.
- for _, candidate := range c.IPAddresses {
- if ip.Equal(candidate) {
- return nil
- }
- }
- return HostnameError{c, candidateIP}
- }
-
- candidateName := toLowerCaseASCII(h) // Save allocations inside the loop.
- validCandidateName := validHostnameInput(candidateName)
-
- for _, match := range c.DNSNames {
- // Ideally, we'd only match valid hostnames according to RFC 6125 like
- // browsers (more or less) do, but in practice Go is used in a wider
- // array of contexts and can't even assume DNS resolution. Instead,
- // always allow perfect matches, and only apply wildcard and trailing
- // dot processing to valid hostnames.
- if validCandidateName && validHostnamePattern(match) {
- if matchHostnames(match, candidateName) {
- return nil
- }
- } else {
- if matchExactly(match, candidateName) {
- return nil
- }
- }
- }
-
- return HostnameError{c, h}
-}
-
-func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool {
- usages := make([]ExtKeyUsage, len(keyUsages))
- copy(usages, keyUsages)
-
- if len(chain) == 0 {
- return false
- }
-
- usagesRemaining := len(usages)
-
- // We walk down the list and cross out any usages that aren't supported
- // by each certificate. If we cross out all the usages, then the chain
- // is unacceptable.
-
-NextCert:
- for i := len(chain) - 1; i >= 0; i-- {
- cert := chain[i]
- if len(cert.ExtKeyUsage) == 0 && len(cert.UnknownExtKeyUsage) == 0 {
- // The certificate doesn't have any extended key usage specified.
- continue
- }
-
- for _, usage := range cert.ExtKeyUsage {
- if usage == ExtKeyUsageAny {
- // The certificate is explicitly good for any usage.
- continue NextCert
- }
- }
-
- const invalidUsage ExtKeyUsage = -1
-
- NextRequestedUsage:
- for i, requestedUsage := range usages {
- if requestedUsage == invalidUsage {
- continue
- }
-
- for _, usage := range cert.ExtKeyUsage {
- if requestedUsage == usage {
- continue NextRequestedUsage
- }
- }
-
- usages[i] = invalidUsage
- usagesRemaining--
- if usagesRemaining == 0 {
- return false
- }
- }
- }
-
- return true
-}
diff --git a/contrib/go/_std_1.20/src/crypto/x509/x509.go b/contrib/go/_std_1.20/src/crypto/x509/x509.go
deleted file mode 100644
index f2e8bf6b05..0000000000
--- a/contrib/go/_std_1.20/src/crypto/x509/x509.go
+++ /dev/null
@@ -1,2370 +0,0 @@
-// Copyright 2009 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 x509 implements a subset of the X.509 standard.
-//
-// It allows parsing and generating certificates, certificate signing
-// requests, certificate revocation lists, and encoded public and private keys.
-// It provides a certificate verifier, complete with a chain builder.
-//
-// The package targets the X.509 technical profile defined by the IETF (RFC
-// 2459/3280/5280), and as further restricted by the CA/Browser Forum Baseline
-// Requirements. There is minimal support for features outside of these
-// profiles, as the primary goal of the package is to provide compatibility
-// with the publicly trusted TLS certificate ecosystem and its policies and
-// constraints.
-//
-// On macOS and Windows, certificate verification is handled by system APIs, but
-// the package aims to apply consistent validation rules across operating
-// systems.
-package x509
-
-import (
- "bytes"
- "crypto"
- "crypto/ecdh"
- "crypto/ecdsa"
- "crypto/ed25519"
- "crypto/elliptic"
- "crypto/rsa"
- "crypto/sha1"
- // Explicitly import these for their crypto.RegisterHash init side-effects.
- // Keep these as blank imports, even if they're imported above.
- _ "crypto/sha1"
- _ "crypto/sha256"
- _ "crypto/sha512"
- "crypto/x509/pkix"
- "encoding/asn1"
- "encoding/pem"
- "errors"
- "fmt"
- "internal/godebug"
- "io"
- "math/big"
- "net"
- "net/url"
- "strconv"
- "time"
- "unicode"
-
- "golang.org/x/crypto/cryptobyte"
- cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
-)
-
-// pkixPublicKey reflects a PKIX public key structure. See SubjectPublicKeyInfo
-// in RFC 3280.
-type pkixPublicKey struct {
- Algo pkix.AlgorithmIdentifier
- BitString asn1.BitString
-}
-
-// ParsePKIXPublicKey parses a public key in PKIX, ASN.1 DER form. The encoded
-// public key is a SubjectPublicKeyInfo structure (see RFC 5280, Section 4.1).
-//
-// It returns a *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey,
-// ed25519.PublicKey (not a pointer), or *ecdh.PublicKey (for X25519).
-// More types might be supported in the future.
-//
-// This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY".
-func ParsePKIXPublicKey(derBytes []byte) (pub any, err error) {
- var pki publicKeyInfo
- if rest, err := asn1.Unmarshal(derBytes, &pki); err != nil {
- if _, err := asn1.Unmarshal(derBytes, &pkcs1PublicKey{}); err == nil {
- return nil, errors.New("x509: failed to parse public key (use ParsePKCS1PublicKey instead for this key format)")
- }
- return nil, err
- } else if len(rest) != 0 {
- return nil, errors.New("x509: trailing data after ASN.1 of public-key")
- }
- return parsePublicKey(&pki)
-}
-
-func marshalPublicKey(pub any) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) {
- switch pub := pub.(type) {
- case *rsa.PublicKey:
- publicKeyBytes, err = asn1.Marshal(pkcs1PublicKey{
- N: pub.N,
- E: pub.E,
- })
- if err != nil {
- return nil, pkix.AlgorithmIdentifier{}, err
- }
- publicKeyAlgorithm.Algorithm = oidPublicKeyRSA
- // This is a NULL parameters value which is required by
- // RFC 3279, Section 2.3.1.
- publicKeyAlgorithm.Parameters = asn1.NullRawValue
- case *ecdsa.PublicKey:
- oid, ok := oidFromNamedCurve(pub.Curve)
- if !ok {
- return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve")
- }
- if !pub.Curve.IsOnCurve(pub.X, pub.Y) {
- return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: invalid elliptic curve public key")
- }
- publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
- publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA
- var paramBytes []byte
- paramBytes, err = asn1.Marshal(oid)
- if err != nil {
- return
- }
- publicKeyAlgorithm.Parameters.FullBytes = paramBytes
- case ed25519.PublicKey:
- publicKeyBytes = pub
- publicKeyAlgorithm.Algorithm = oidPublicKeyEd25519
- case *ecdh.PublicKey:
- publicKeyBytes = pub.Bytes()
- if pub.Curve() == ecdh.X25519() {
- publicKeyAlgorithm.Algorithm = oidPublicKeyX25519
- } else {
- oid, ok := oidFromECDHCurve(pub.Curve())
- if !ok {
- return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve")
- }
- publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA
- var paramBytes []byte
- paramBytes, err = asn1.Marshal(oid)
- if err != nil {
- return
- }
- publicKeyAlgorithm.Parameters.FullBytes = paramBytes
- }
- default:
- return nil, pkix.AlgorithmIdentifier{}, fmt.Errorf("x509: unsupported public key type: %T", pub)
- }
-
- return publicKeyBytes, publicKeyAlgorithm, nil
-}
-
-// MarshalPKIXPublicKey converts a public key to PKIX, ASN.1 DER form.
-// The encoded public key is a SubjectPublicKeyInfo structure
-// (see RFC 5280, Section 4.1).
-//
-// The following key types are currently supported: *rsa.PublicKey,
-// *ecdsa.PublicKey, ed25519.PublicKey (not a pointer), and *ecdh.PublicKey.
-// Unsupported key types result in an error.
-//
-// This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY".
-func MarshalPKIXPublicKey(pub any) ([]byte, error) {
- var publicKeyBytes []byte
- var publicKeyAlgorithm pkix.AlgorithmIdentifier
- var err error
-
- if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil {
- return nil, err
- }
-
- pkix := pkixPublicKey{
- Algo: publicKeyAlgorithm,
- BitString: asn1.BitString{
- Bytes: publicKeyBytes,
- BitLength: 8 * len(publicKeyBytes),
- },
- }
-
- ret, _ := asn1.Marshal(pkix)
- return ret, nil
-}
-
-// These structures reflect the ASN.1 structure of X.509 certificates.:
-
-type certificate struct {
- TBSCertificate tbsCertificate
- SignatureAlgorithm pkix.AlgorithmIdentifier
- SignatureValue asn1.BitString
-}
-
-type tbsCertificate struct {
- Raw asn1.RawContent
- Version int `asn1:"optional,explicit,default:0,tag:0"`
- SerialNumber *big.Int
- SignatureAlgorithm pkix.AlgorithmIdentifier
- Issuer asn1.RawValue
- Validity validity
- Subject asn1.RawValue
- PublicKey publicKeyInfo
- UniqueId asn1.BitString `asn1:"optional,tag:1"`
- SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"`
- Extensions []pkix.Extension `asn1:"omitempty,optional,explicit,tag:3"`
-}
-
-type dsaAlgorithmParameters struct {
- P, Q, G *big.Int
-}
-
-type validity struct {
- NotBefore, NotAfter time.Time
-}
-
-type publicKeyInfo struct {
- Raw asn1.RawContent
- Algorithm pkix.AlgorithmIdentifier
- PublicKey asn1.BitString
-}
-
-// RFC 5280, 4.2.1.1
-type authKeyId struct {
- Id []byte `asn1:"optional,tag:0"`
-}
-
-type SignatureAlgorithm int
-
-const (
- UnknownSignatureAlgorithm SignatureAlgorithm = iota
-
- MD2WithRSA // Unsupported.
- MD5WithRSA // Only supported for signing, not verification.
- SHA1WithRSA // Only supported for signing, and verification of CRLs, CSRs, and OCSP responses.
- SHA256WithRSA
- SHA384WithRSA
- SHA512WithRSA
- DSAWithSHA1 // Unsupported.
- DSAWithSHA256 // Unsupported.
- ECDSAWithSHA1 // Only supported for signing, and verification of CRLs, CSRs, and OCSP responses.
- ECDSAWithSHA256
- ECDSAWithSHA384
- ECDSAWithSHA512
- SHA256WithRSAPSS
- SHA384WithRSAPSS
- SHA512WithRSAPSS
- PureEd25519
-)
-
-func (algo SignatureAlgorithm) isRSAPSS() bool {
- switch algo {
- case SHA256WithRSAPSS, SHA384WithRSAPSS, SHA512WithRSAPSS:
- return true
- default:
- return false
- }
-}
-
-func (algo SignatureAlgorithm) String() string {
- for _, details := range signatureAlgorithmDetails {
- if details.algo == algo {
- return details.name
- }
- }
- return strconv.Itoa(int(algo))
-}
-
-type PublicKeyAlgorithm int
-
-const (
- UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
- RSA
- DSA // Only supported for parsing.
- ECDSA
- Ed25519
-)
-
-var publicKeyAlgoName = [...]string{
- RSA: "RSA",
- DSA: "DSA",
- ECDSA: "ECDSA",
- Ed25519: "Ed25519",
-}
-
-func (algo PublicKeyAlgorithm) String() string {
- if 0 < algo && int(algo) < len(publicKeyAlgoName) {
- return publicKeyAlgoName[algo]
- }
- return strconv.Itoa(int(algo))
-}
-
-// OIDs for signature algorithms
-//
-// pkcs-1 OBJECT IDENTIFIER ::= {
-// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
-//
-// RFC 3279 2.2.1 RSA Signature Algorithms
-//
-// md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
-//
-// md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
-//
-// sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
-//
-// dsaWithSha1 OBJECT IDENTIFIER ::= {
-// iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 }
-//
-// RFC 3279 2.2.3 ECDSA Signature Algorithm
-//
-// ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
-// iso(1) member-body(2) us(840) ansi-x962(10045)
-// signatures(4) ecdsa-with-SHA1(1)}
-//
-// RFC 4055 5 PKCS #1 Version 1.5
-//
-// sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
-//
-// sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
-//
-// sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
-//
-// RFC 5758 3.1 DSA Signature Algorithms
-//
-// dsaWithSha256 OBJECT IDENTIFIER ::= {
-// joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)
-// csor(3) algorithms(4) id-dsa-with-sha2(3) 2}
-//
-// RFC 5758 3.2 ECDSA Signature Algorithm
-//
-// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
-// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
-//
-// ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
-// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
-//
-// ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
-// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
-//
-// RFC 8410 3 Curve25519 and Curve448 Algorithm Identifiers
-//
-// id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
-var (
- oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
- oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
- oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
- oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
- oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
- oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
- oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
- oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
- oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2}
- oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
- oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
- oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
- oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
- oidSignatureEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
-
- oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}
- oidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2}
- oidSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3}
-
- oidMGF1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 8}
-
- // oidISOSignatureSHA1WithRSA means the same as oidSignatureSHA1WithRSA
- // but it's specified by ISO. Microsoft's makecert.exe has been known
- // to produce certificates with this OID.
- oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29}
-)
-
-var signatureAlgorithmDetails = []struct {
- algo SignatureAlgorithm
- name string
- oid asn1.ObjectIdentifier
- pubKeyAlgo PublicKeyAlgorithm
- hash crypto.Hash
-}{
- {MD2WithRSA, "MD2-RSA", oidSignatureMD2WithRSA, RSA, crypto.Hash(0) /* no value for MD2 */},
- {MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, RSA, crypto.MD5},
- {SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, RSA, crypto.SHA1},
- {SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, RSA, crypto.SHA1},
- {SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, RSA, crypto.SHA256},
- {SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, RSA, crypto.SHA384},
- {SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, RSA, crypto.SHA512},
- {SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA256},
- {SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA384},
- {SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA512},
- {DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, DSA, crypto.SHA1},
- {DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, DSA, crypto.SHA256},
- {ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, ECDSA, crypto.SHA1},
- {ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, ECDSA, crypto.SHA256},
- {ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, ECDSA, crypto.SHA384},
- {ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, ECDSA, crypto.SHA512},
- {PureEd25519, "Ed25519", oidSignatureEd25519, Ed25519, crypto.Hash(0) /* no pre-hashing */},
-}
-
-// hashToPSSParameters contains the DER encoded RSA PSS parameters for the
-// SHA256, SHA384, and SHA512 hashes as defined in RFC 3447, Appendix A.2.3.
-// The parameters contain the following values:
-// - hashAlgorithm contains the associated hash identifier with NULL parameters
-// - maskGenAlgorithm always contains the default mgf1SHA1 identifier
-// - saltLength contains the length of the associated hash
-// - trailerField always contains the default trailerFieldBC value
-var hashToPSSParameters = map[crypto.Hash]asn1.RawValue{
- crypto.SHA256: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 162, 3, 2, 1, 32}},
- crypto.SHA384: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 162, 3, 2, 1, 48}},
- crypto.SHA512: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 162, 3, 2, 1, 64}},
-}
-
-// pssParameters reflects the parameters in an AlgorithmIdentifier that
-// specifies RSA PSS. See RFC 3447, Appendix A.2.3.
-type pssParameters struct {
- // The following three fields are not marked as
- // optional because the default values specify SHA-1,
- // which is no longer suitable for use in signatures.
- Hash pkix.AlgorithmIdentifier `asn1:"explicit,tag:0"`
- MGF pkix.AlgorithmIdentifier `asn1:"explicit,tag:1"`
- SaltLength int `asn1:"explicit,tag:2"`
- TrailerField int `asn1:"optional,explicit,tag:3,default:1"`
-}
-
-func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm {
- if ai.Algorithm.Equal(oidSignatureEd25519) {
- // RFC 8410, Section 3
- // > For all of the OIDs, the parameters MUST be absent.
- if len(ai.Parameters.FullBytes) != 0 {
- return UnknownSignatureAlgorithm
- }
- }
-
- if !ai.Algorithm.Equal(oidSignatureRSAPSS) {
- for _, details := range signatureAlgorithmDetails {
- if ai.Algorithm.Equal(details.oid) {
- return details.algo
- }
- }
- return UnknownSignatureAlgorithm
- }
-
- // RSA PSS is special because it encodes important parameters
- // in the Parameters.
-
- var params pssParameters
- if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, &params); err != nil {
- return UnknownSignatureAlgorithm
- }
-
- var mgf1HashFunc pkix.AlgorithmIdentifier
- if _, err := asn1.Unmarshal(params.MGF.Parameters.FullBytes, &mgf1HashFunc); err != nil {
- return UnknownSignatureAlgorithm
- }
-
- // PSS is greatly overburdened with options. This code forces them into
- // three buckets by requiring that the MGF1 hash function always match the
- // message hash function (as recommended in RFC 3447, Section 8.1), that the
- // salt length matches the hash length, and that the trailer field has the
- // default value.
- if (len(params.Hash.Parameters.FullBytes) != 0 && !bytes.Equal(params.Hash.Parameters.FullBytes, asn1.NullBytes)) ||
- !params.MGF.Algorithm.Equal(oidMGF1) ||
- !mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) ||
- (len(mgf1HashFunc.Parameters.FullBytes) != 0 && !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, asn1.NullBytes)) ||
- params.TrailerField != 1 {
- return UnknownSignatureAlgorithm
- }
-
- switch {
- case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32:
- return SHA256WithRSAPSS
- case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48:
- return SHA384WithRSAPSS
- case params.Hash.Algorithm.Equal(oidSHA512) && params.SaltLength == 64:
- return SHA512WithRSAPSS
- }
-
- return UnknownSignatureAlgorithm
-}
-
-var (
- // RFC 3279, 2.3 Public Key Algorithms
- //
- // pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
- // rsadsi(113549) pkcs(1) 1 }
- //
- // rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
- //
- // id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
- // x9-57(10040) x9cm(4) 1 }
- oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
- oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
- // RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
- //
- // id-ecPublicKey OBJECT IDENTIFIER ::= {
- // iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
- oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
- // RFC 8410, Section 3
- //
- // id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 }
- // id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
- oidPublicKeyX25519 = asn1.ObjectIdentifier{1, 3, 101, 110}
- oidPublicKeyEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
-)
-
-// getPublicKeyAlgorithmFromOID returns the exposed PublicKeyAlgorithm
-// identifier for public key types supported in certificates and CSRs. Marshal
-// and Parse functions may support a different set of public key types.
-func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm {
- switch {
- case oid.Equal(oidPublicKeyRSA):
- return RSA
- case oid.Equal(oidPublicKeyDSA):
- return DSA
- case oid.Equal(oidPublicKeyECDSA):
- return ECDSA
- case oid.Equal(oidPublicKeyEd25519):
- return Ed25519
- }
- return UnknownPublicKeyAlgorithm
-}
-
-// RFC 5480, 2.1.1.1. Named Curve
-//
-// secp224r1 OBJECT IDENTIFIER ::= {
-// iso(1) identified-organization(3) certicom(132) curve(0) 33 }
-//
-// secp256r1 OBJECT IDENTIFIER ::= {
-// iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
-// prime(1) 7 }
-//
-// secp384r1 OBJECT IDENTIFIER ::= {
-// iso(1) identified-organization(3) certicom(132) curve(0) 34 }
-//
-// secp521r1 OBJECT IDENTIFIER ::= {
-// iso(1) identified-organization(3) certicom(132) curve(0) 35 }
-//
-// NB: secp256r1 is equivalent to prime256v1
-var (
- oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
- oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
- oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
- oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
-)
-
-func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
- switch {
- case oid.Equal(oidNamedCurveP224):
- return elliptic.P224()
- case oid.Equal(oidNamedCurveP256):
- return elliptic.P256()
- case oid.Equal(oidNamedCurveP384):
- return elliptic.P384()
- case oid.Equal(oidNamedCurveP521):
- return elliptic.P521()
- }
- return nil
-}
-
-func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
- switch curve {
- case elliptic.P224():
- return oidNamedCurveP224, true
- case elliptic.P256():
- return oidNamedCurveP256, true
- case elliptic.P384():
- return oidNamedCurveP384, true
- case elliptic.P521():
- return oidNamedCurveP521, true
- }
-
- return nil, false
-}
-
-func oidFromECDHCurve(curve ecdh.Curve) (asn1.ObjectIdentifier, bool) {
- switch curve {
- case ecdh.X25519():
- return oidPublicKeyX25519, true
- case ecdh.P256():
- return oidNamedCurveP256, true
- case ecdh.P384():
- return oidNamedCurveP384, true
- case ecdh.P521():
- return oidNamedCurveP521, true
- }
-
- return nil, false
-}
-
-// KeyUsage represents the set of actions that are valid for a given key. It's
-// a bitmap of the KeyUsage* constants.
-type KeyUsage int
-
-const (
- KeyUsageDigitalSignature KeyUsage = 1 << iota
- KeyUsageContentCommitment
- KeyUsageKeyEncipherment
- KeyUsageDataEncipherment
- KeyUsageKeyAgreement
- KeyUsageCertSign
- KeyUsageCRLSign
- KeyUsageEncipherOnly
- KeyUsageDecipherOnly
-)
-
-// RFC 5280, 4.2.1.12 Extended Key Usage
-//
-// anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
-//
-// id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
-//
-// id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
-// id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
-// id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
-// id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
-// id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
-// id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 }
-var (
- oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0}
- oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1}
- oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2}
- oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3}
- oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4}
- oidExtKeyUsageIPSECEndSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5}
- oidExtKeyUsageIPSECTunnel = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6}
- oidExtKeyUsageIPSECUser = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7}
- oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}
- oidExtKeyUsageOCSPSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9}
- oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3}
- oidExtKeyUsageNetscapeServerGatedCrypto = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1}
- oidExtKeyUsageMicrosoftCommercialCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 22}
- oidExtKeyUsageMicrosoftKernelCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 61, 1, 1}
-)
-
-// ExtKeyUsage represents an extended set of actions that are valid for a given key.
-// Each of the ExtKeyUsage* constants define a unique action.
-type ExtKeyUsage int
-
-const (
- ExtKeyUsageAny ExtKeyUsage = iota
- ExtKeyUsageServerAuth
- ExtKeyUsageClientAuth
- ExtKeyUsageCodeSigning
- ExtKeyUsageEmailProtection
- ExtKeyUsageIPSECEndSystem
- ExtKeyUsageIPSECTunnel
- ExtKeyUsageIPSECUser
- ExtKeyUsageTimeStamping
- ExtKeyUsageOCSPSigning
- ExtKeyUsageMicrosoftServerGatedCrypto
- ExtKeyUsageNetscapeServerGatedCrypto
- ExtKeyUsageMicrosoftCommercialCodeSigning
- ExtKeyUsageMicrosoftKernelCodeSigning
-)
-
-// extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID.
-var extKeyUsageOIDs = []struct {
- extKeyUsage ExtKeyUsage
- oid asn1.ObjectIdentifier
-}{
- {ExtKeyUsageAny, oidExtKeyUsageAny},
- {ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth},
- {ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth},
- {ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning},
- {ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection},
- {ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem},
- {ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel},
- {ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser},
- {ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping},
- {ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning},
- {ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto},
- {ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto},
- {ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning},
- {ExtKeyUsageMicrosoftKernelCodeSigning, oidExtKeyUsageMicrosoftKernelCodeSigning},
-}
-
-func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok bool) {
- for _, pair := range extKeyUsageOIDs {
- if oid.Equal(pair.oid) {
- return pair.extKeyUsage, true
- }
- }
- return
-}
-
-func oidFromExtKeyUsage(eku ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) {
- for _, pair := range extKeyUsageOIDs {
- if eku == pair.extKeyUsage {
- return pair.oid, true
- }
- }
- return
-}
-
-// A Certificate represents an X.509 certificate.
-type Certificate struct {
- Raw []byte // Complete ASN.1 DER content (certificate, signature algorithm and signature).
- RawTBSCertificate []byte // Certificate part of raw ASN.1 DER content.
- RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo.
- RawSubject []byte // DER encoded Subject
- RawIssuer []byte // DER encoded Issuer
-
- Signature []byte
- SignatureAlgorithm SignatureAlgorithm
-
- PublicKeyAlgorithm PublicKeyAlgorithm
- PublicKey any
-
- Version int
- SerialNumber *big.Int
- Issuer pkix.Name
- Subject pkix.Name
- NotBefore, NotAfter time.Time // Validity bounds.
- KeyUsage KeyUsage
-
- // Extensions contains raw X.509 extensions. When parsing certificates,
- // this can be used to extract non-critical extensions that are not
- // parsed by this package. When marshaling certificates, the Extensions
- // field is ignored, see ExtraExtensions.
- Extensions []pkix.Extension
-
- // ExtraExtensions contains extensions to be copied, raw, into any
- // marshaled certificates. Values override any extensions that would
- // otherwise be produced based on the other fields. The ExtraExtensions
- // field is not populated when parsing certificates, see Extensions.
- ExtraExtensions []pkix.Extension
-
- // UnhandledCriticalExtensions contains a list of extension IDs that
- // were not (fully) processed when parsing. Verify will fail if this
- // slice is non-empty, unless verification is delegated to an OS
- // library which understands all the critical extensions.
- //
- // Users can access these extensions using Extensions and can remove
- // elements from this slice if they believe that they have been
- // handled.
- UnhandledCriticalExtensions []asn1.ObjectIdentifier
-
- ExtKeyUsage []ExtKeyUsage // Sequence of extended key usages.
- UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package.
-
- // BasicConstraintsValid indicates whether IsCA, MaxPathLen,
- // and MaxPathLenZero are valid.
- BasicConstraintsValid bool
- IsCA bool
-
- // MaxPathLen and MaxPathLenZero indicate the presence and
- // value of the BasicConstraints' "pathLenConstraint".
- //
- // When parsing a certificate, a positive non-zero MaxPathLen
- // means that the field was specified, -1 means it was unset,
- // and MaxPathLenZero being true mean that the field was
- // explicitly set to zero. The case of MaxPathLen==0 with MaxPathLenZero==false
- // should be treated equivalent to -1 (unset).
- //
- // When generating a certificate, an unset pathLenConstraint
- // can be requested with either MaxPathLen == -1 or using the
- // zero value for both MaxPathLen and MaxPathLenZero.
- MaxPathLen int
- // MaxPathLenZero indicates that BasicConstraintsValid==true
- // and MaxPathLen==0 should be interpreted as an actual
- // maximum path length of zero. Otherwise, that combination is
- // interpreted as MaxPathLen not being set.
- MaxPathLenZero bool
-
- SubjectKeyId []byte
- AuthorityKeyId []byte
-
- // RFC 5280, 4.2.2.1 (Authority Information Access)
- OCSPServer []string
- IssuingCertificateURL []string
-
- // Subject Alternate Name values. (Note that these values may not be valid
- // if invalid values were contained within a parsed certificate. For
- // example, an element of DNSNames may not be a valid DNS domain name.)
- DNSNames []string
- EmailAddresses []string
- IPAddresses []net.IP
- URIs []*url.URL
-
- // Name constraints
- PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical.
- PermittedDNSDomains []string
- ExcludedDNSDomains []string
- PermittedIPRanges []*net.IPNet
- ExcludedIPRanges []*net.IPNet
- PermittedEmailAddresses []string
- ExcludedEmailAddresses []string
- PermittedURIDomains []string
- ExcludedURIDomains []string
-
- // CRL Distribution Points
- CRLDistributionPoints []string
-
- PolicyIdentifiers []asn1.ObjectIdentifier
-}
-
-// ErrUnsupportedAlgorithm results from attempting to perform an operation that
-// involves algorithms that are not currently implemented.
-var ErrUnsupportedAlgorithm = errors.New("x509: cannot verify signature: algorithm unimplemented")
-
-// An InsecureAlgorithmError indicates that the SignatureAlgorithm used to
-// generate the signature is not secure, and the signature has been rejected.
-//
-// To temporarily restore support for SHA-1 signatures, include the value
-// "x509sha1=1" in the GODEBUG environment variable. Note that this option will
-// be removed in a future release.
-type InsecureAlgorithmError SignatureAlgorithm
-
-func (e InsecureAlgorithmError) Error() string {
- var override string
- if SignatureAlgorithm(e) == SHA1WithRSA || SignatureAlgorithm(e) == ECDSAWithSHA1 {
- override = " (temporarily override with GODEBUG=x509sha1=1)"
- }
- return fmt.Sprintf("x509: cannot verify signature: insecure algorithm %v", SignatureAlgorithm(e)) + override
-}
-
-// ConstraintViolationError results when a requested usage is not permitted by
-// a certificate. For example: checking a signature when the public key isn't a
-// certificate signing key.
-type ConstraintViolationError struct{}
-
-func (ConstraintViolationError) Error() string {
- return "x509: invalid signature: parent certificate cannot sign this kind of certificate"
-}
-
-func (c *Certificate) Equal(other *Certificate) bool {
- if c == nil || other == nil {
- return c == other
- }
- return bytes.Equal(c.Raw, other.Raw)
-}
-
-func (c *Certificate) hasSANExtension() bool {
- return oidInExtensions(oidExtensionSubjectAltName, c.Extensions)
-}
-
-// CheckSignatureFrom verifies that the signature on c is a valid signature from parent.
-//
-// This is a low-level API that performs very limited checks, and not a full
-// path verifier. Most users should use [Certificate.Verify] instead.
-func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
- // RFC 5280, 4.2.1.9:
- // "If the basic constraints extension is not present in a version 3
- // certificate, or the extension is present but the cA boolean is not
- // asserted, then the certified public key MUST NOT be used to verify
- // certificate signatures."
- if parent.Version == 3 && !parent.BasicConstraintsValid ||
- parent.BasicConstraintsValid && !parent.IsCA {
- return ConstraintViolationError{}
- }
-
- if parent.KeyUsage != 0 && parent.KeyUsage&KeyUsageCertSign == 0 {
- return ConstraintViolationError{}
- }
-
- if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
- return ErrUnsupportedAlgorithm
- }
-
- return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature, parent.PublicKey, false)
-}
-
-// CheckSignature verifies that signature is a valid signature over signed from
-// c's public key.
-//
-// This is a low-level API that performs no validity checks on the certificate.
-//
-// [MD5WithRSA] signatures are rejected, while [SHA1WithRSA] and [ECDSAWithSHA1]
-// signatures are currently accepted.
-func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) error {
- return checkSignature(algo, signed, signature, c.PublicKey, true)
-}
-
-func (c *Certificate) hasNameConstraints() bool {
- return oidInExtensions(oidExtensionNameConstraints, c.Extensions)
-}
-
-func (c *Certificate) getSANExtension() []byte {
- for _, e := range c.Extensions {
- if e.Id.Equal(oidExtensionSubjectAltName) {
- return e.Value
- }
- }
- return nil
-}
-
-func signaturePublicKeyAlgoMismatchError(expectedPubKeyAlgo PublicKeyAlgorithm, pubKey any) error {
- return fmt.Errorf("x509: signature algorithm specifies an %s public key, but have public key of type %T", expectedPubKeyAlgo.String(), pubKey)
-}
-
-var x509sha1 = godebug.New("x509sha1")
-
-// checkSignature verifies that signature is a valid signature over signed from
-// a crypto.PublicKey.
-func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey crypto.PublicKey, allowSHA1 bool) (err error) {
- var hashType crypto.Hash
- var pubKeyAlgo PublicKeyAlgorithm
-
- for _, details := range signatureAlgorithmDetails {
- if details.algo == algo {
- hashType = details.hash
- pubKeyAlgo = details.pubKeyAlgo
- }
- }
-
- switch hashType {
- case crypto.Hash(0):
- if pubKeyAlgo != Ed25519 {
- return ErrUnsupportedAlgorithm
- }
- case crypto.MD5:
- return InsecureAlgorithmError(algo)
- case crypto.SHA1:
- // SHA-1 signatures are mostly disabled. See go.dev/issue/41682.
- if !allowSHA1 && x509sha1.Value() != "1" {
- return InsecureAlgorithmError(algo)
- }
- fallthrough
- default:
- if !hashType.Available() {
- return ErrUnsupportedAlgorithm
- }
- h := hashType.New()
- h.Write(signed)
- signed = h.Sum(nil)
- }
-
- switch pub := publicKey.(type) {
- case *rsa.PublicKey:
- if pubKeyAlgo != RSA {
- return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)
- }
- if algo.isRSAPSS() {
- return rsa.VerifyPSS(pub, hashType, signed, signature, &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash})
- } else {
- return rsa.VerifyPKCS1v15(pub, hashType, signed, signature)
- }
- case *ecdsa.PublicKey:
- if pubKeyAlgo != ECDSA {
- return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)
- }
- if !ecdsa.VerifyASN1(pub, signed, signature) {
- return errors.New("x509: ECDSA verification failure")
- }
- return
- case ed25519.PublicKey:
- if pubKeyAlgo != Ed25519 {
- return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)
- }
- if !ed25519.Verify(pub, signed, signature) {
- return errors.New("x509: Ed25519 verification failure")
- }
- return
- }
- return ErrUnsupportedAlgorithm
-}
-
-// CheckCRLSignature checks that the signature in crl is from c.
-//
-// Deprecated: Use RevocationList.CheckSignatureFrom instead.
-func (c *Certificate) CheckCRLSignature(crl *pkix.CertificateList) error {
- algo := getSignatureAlgorithmFromAI(crl.SignatureAlgorithm)
- return c.CheckSignature(algo, crl.TBSCertList.Raw, crl.SignatureValue.RightAlign())
-}
-
-type UnhandledCriticalExtension struct{}
-
-func (h UnhandledCriticalExtension) Error() string {
- return "x509: unhandled critical extension"
-}
-
-type basicConstraints struct {
- IsCA bool `asn1:"optional"`
- MaxPathLen int `asn1:"optional,default:-1"`
-}
-
-// RFC 5280 4.2.1.4
-type policyInformation struct {
- Policy asn1.ObjectIdentifier
- // policyQualifiers omitted
-}
-
-const (
- nameTypeEmail = 1
- nameTypeDNS = 2
- nameTypeURI = 6
- nameTypeIP = 7
-)
-
-// RFC 5280, 4.2.2.1
-type authorityInfoAccess struct {
- Method asn1.ObjectIdentifier
- Location asn1.RawValue
-}
-
-// RFC 5280, 4.2.1.14
-type distributionPoint struct {
- DistributionPoint distributionPointName `asn1:"optional,tag:0"`
- Reason asn1.BitString `asn1:"optional,tag:1"`
- CRLIssuer asn1.RawValue `asn1:"optional,tag:2"`
-}
-
-type distributionPointName struct {
- FullName []asn1.RawValue `asn1:"optional,tag:0"`
- RelativeName pkix.RDNSequence `asn1:"optional,tag:1"`
-}
-
-func reverseBitsInAByte(in byte) byte {
- b1 := in>>4 | in<<4
- b2 := b1>>2&0x33 | b1<<2&0xcc
- b3 := b2>>1&0x55 | b2<<1&0xaa
- return b3
-}
-
-// asn1BitLength returns the bit-length of bitString by considering the
-// most-significant bit in a byte to be the "first" bit. This convention
-// matches ASN.1, but differs from almost everything else.
-func asn1BitLength(bitString []byte) int {
- bitLen := len(bitString) * 8
-
- for i := range bitString {
- b := bitString[len(bitString)-i-1]
-
- for bit := uint(0); bit < 8; bit++ {
- if (b>>bit)&1 == 1 {
- return bitLen
- }
- bitLen--
- }
- }
-
- return 0
-}
-
-var (
- oidExtensionSubjectKeyId = []int{2, 5, 29, 14}
- oidExtensionKeyUsage = []int{2, 5, 29, 15}
- oidExtensionExtendedKeyUsage = []int{2, 5, 29, 37}
- oidExtensionAuthorityKeyId = []int{2, 5, 29, 35}
- oidExtensionBasicConstraints = []int{2, 5, 29, 19}
- oidExtensionSubjectAltName = []int{2, 5, 29, 17}
- oidExtensionCertificatePolicies = []int{2, 5, 29, 32}
- oidExtensionNameConstraints = []int{2, 5, 29, 30}
- oidExtensionCRLDistributionPoints = []int{2, 5, 29, 31}
- oidExtensionAuthorityInfoAccess = []int{1, 3, 6, 1, 5, 5, 7, 1, 1}
- oidExtensionCRLNumber = []int{2, 5, 29, 20}
-)
-
-var (
- oidAuthorityInfoAccessOcsp = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1}
- oidAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2}
-)
-
-// oidInExtensions reports whether an extension with the given oid exists in
-// extensions.
-func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) bool {
- for _, e := range extensions {
- if e.Id.Equal(oid) {
- return true
- }
- }
- return false
-}
-
-// marshalSANs marshals a list of addresses into a the contents of an X.509
-// SubjectAlternativeName extension.
-func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL) (derBytes []byte, err error) {
- var rawValues []asn1.RawValue
- for _, name := range dnsNames {
- if err := isIA5String(name); err != nil {
- return nil, err
- }
- rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeDNS, Class: 2, Bytes: []byte(name)})
- }
- for _, email := range emailAddresses {
- if err := isIA5String(email); err != nil {
- return nil, err
- }
- rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeEmail, Class: 2, Bytes: []byte(email)})
- }
- for _, rawIP := range ipAddresses {
- // If possible, we always want to encode IPv4 addresses in 4 bytes.
- ip := rawIP.To4()
- if ip == nil {
- ip = rawIP
- }
- rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeIP, Class: 2, Bytes: ip})
- }
- for _, uri := range uris {
- uriStr := uri.String()
- if err := isIA5String(uriStr); err != nil {
- return nil, err
- }
- rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte(uriStr)})
- }
- return asn1.Marshal(rawValues)
-}
-
-func isIA5String(s string) error {
- for _, r := range s {
- // Per RFC5280 "IA5String is limited to the set of ASCII characters"
- if r > unicode.MaxASCII {
- return fmt.Errorf("x509: %q cannot be encoded as an IA5String", s)
- }
- }
-
- return nil
-}
-
-func buildCertExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId []byte, subjectKeyId []byte) (ret []pkix.Extension, err error) {
- ret = make([]pkix.Extension, 10 /* maximum number of elements. */)
- n := 0
-
- if template.KeyUsage != 0 &&
- !oidInExtensions(oidExtensionKeyUsage, template.ExtraExtensions) {
- ret[n], err = marshalKeyUsage(template.KeyUsage)
- if err != nil {
- return nil, err
- }
- n++
- }
-
- if (len(template.ExtKeyUsage) > 0 || len(template.UnknownExtKeyUsage) > 0) &&
- !oidInExtensions(oidExtensionExtendedKeyUsage, template.ExtraExtensions) {
- ret[n], err = marshalExtKeyUsage(template.ExtKeyUsage, template.UnknownExtKeyUsage)
- if err != nil {
- return nil, err
- }
- n++
- }
-
- if template.BasicConstraintsValid && !oidInExtensions(oidExtensionBasicConstraints, template.ExtraExtensions) {
- ret[n], err = marshalBasicConstraints(template.IsCA, template.MaxPathLen, template.MaxPathLenZero)
- if err != nil {
- return nil, err
- }
- n++
- }
-
- if len(subjectKeyId) > 0 && !oidInExtensions(oidExtensionSubjectKeyId, template.ExtraExtensions) {
- ret[n].Id = oidExtensionSubjectKeyId
- ret[n].Value, err = asn1.Marshal(subjectKeyId)
- if err != nil {
- return
- }
- n++
- }
-
- if len(authorityKeyId) > 0 && !oidInExtensions(oidExtensionAuthorityKeyId, template.ExtraExtensions) {
- ret[n].Id = oidExtensionAuthorityKeyId
- ret[n].Value, err = asn1.Marshal(authKeyId{authorityKeyId})
- if err != nil {
- return
- }
- n++
- }
-
- if (len(template.OCSPServer) > 0 || len(template.IssuingCertificateURL) > 0) &&
- !oidInExtensions(oidExtensionAuthorityInfoAccess, template.ExtraExtensions) {
- ret[n].Id = oidExtensionAuthorityInfoAccess
- var aiaValues []authorityInfoAccess
- for _, name := range template.OCSPServer {
- aiaValues = append(aiaValues, authorityInfoAccess{
- Method: oidAuthorityInfoAccessOcsp,
- Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},
- })
- }
- for _, name := range template.IssuingCertificateURL {
- aiaValues = append(aiaValues, authorityInfoAccess{
- Method: oidAuthorityInfoAccessIssuers,
- Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},
- })
- }
- ret[n].Value, err = asn1.Marshal(aiaValues)
- if err != nil {
- return
- }
- n++
- }
-
- if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) &&
- !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {
- ret[n].Id = oidExtensionSubjectAltName
- // From RFC 5280, Section 4.2.1.6:
- // “If the subject field contains an empty sequence ... then
- // subjectAltName extension ... is marked as critical”
- ret[n].Critical = subjectIsEmpty
- ret[n].Value, err = marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses, template.URIs)
- if err != nil {
- return
- }
- n++
- }
-
- if len(template.PolicyIdentifiers) > 0 &&
- !oidInExtensions(oidExtensionCertificatePolicies, template.ExtraExtensions) {
- ret[n], err = marshalCertificatePolicies(template.PolicyIdentifiers)
- if err != nil {
- return nil, err
- }
- n++
- }
-
- if (len(template.PermittedDNSDomains) > 0 || len(template.ExcludedDNSDomains) > 0 ||
- len(template.PermittedIPRanges) > 0 || len(template.ExcludedIPRanges) > 0 ||
- len(template.PermittedEmailAddresses) > 0 || len(template.ExcludedEmailAddresses) > 0 ||
- len(template.PermittedURIDomains) > 0 || len(template.ExcludedURIDomains) > 0) &&
- !oidInExtensions(oidExtensionNameConstraints, template.ExtraExtensions) {
- ret[n].Id = oidExtensionNameConstraints
- ret[n].Critical = template.PermittedDNSDomainsCritical
-
- ipAndMask := func(ipNet *net.IPNet) []byte {
- maskedIP := ipNet.IP.Mask(ipNet.Mask)
- ipAndMask := make([]byte, 0, len(maskedIP)+len(ipNet.Mask))
- ipAndMask = append(ipAndMask, maskedIP...)
- ipAndMask = append(ipAndMask, ipNet.Mask...)
- return ipAndMask
- }
-
- serialiseConstraints := func(dns []string, ips []*net.IPNet, emails []string, uriDomains []string) (der []byte, err error) {
- var b cryptobyte.Builder
-
- for _, name := range dns {
- if err = isIA5String(name); err != nil {
- return nil, err
- }
-
- b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
- b.AddASN1(cryptobyte_asn1.Tag(2).ContextSpecific(), func(b *cryptobyte.Builder) {
- b.AddBytes([]byte(name))
- })
- })
- }
-
- for _, ipNet := range ips {
- b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
- b.AddASN1(cryptobyte_asn1.Tag(7).ContextSpecific(), func(b *cryptobyte.Builder) {
- b.AddBytes(ipAndMask(ipNet))
- })
- })
- }
-
- for _, email := range emails {
- if err = isIA5String(email); err != nil {
- return nil, err
- }
-
- b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
- b.AddASN1(cryptobyte_asn1.Tag(1).ContextSpecific(), func(b *cryptobyte.Builder) {
- b.AddBytes([]byte(email))
- })
- })
- }
-
- for _, uriDomain := range uriDomains {
- if err = isIA5String(uriDomain); err != nil {
- return nil, err
- }
-
- b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
- b.AddASN1(cryptobyte_asn1.Tag(6).ContextSpecific(), func(b *cryptobyte.Builder) {
- b.AddBytes([]byte(uriDomain))
- })
- })
- }
-
- return b.Bytes()
- }
-
- permitted, err := serialiseConstraints(template.PermittedDNSDomains, template.PermittedIPRanges, template.PermittedEmailAddresses, template.PermittedURIDomains)
- if err != nil {
- return nil, err
- }
-
- excluded, err := serialiseConstraints(template.ExcludedDNSDomains, template.ExcludedIPRanges, template.ExcludedEmailAddresses, template.ExcludedURIDomains)
- if err != nil {
- return nil, err
- }
-
- var b cryptobyte.Builder
- b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
- if len(permitted) > 0 {
- b.AddASN1(cryptobyte_asn1.Tag(0).ContextSpecific().Constructed(), func(b *cryptobyte.Builder) {
- b.AddBytes(permitted)
- })
- }
-
- if len(excluded) > 0 {
- b.AddASN1(cryptobyte_asn1.Tag(1).ContextSpecific().Constructed(), func(b *cryptobyte.Builder) {
- b.AddBytes(excluded)
- })
- }
- })
-
- ret[n].Value, err = b.Bytes()
- if err != nil {
- return nil, err
- }
- n++
- }
-
- if len(template.CRLDistributionPoints) > 0 &&
- !oidInExtensions(oidExtensionCRLDistributionPoints, template.ExtraExtensions) {
- ret[n].Id = oidExtensionCRLDistributionPoints
-
- var crlDp []distributionPoint
- for _, name := range template.CRLDistributionPoints {
- dp := distributionPoint{
- DistributionPoint: distributionPointName{
- FullName: []asn1.RawValue{
- {Tag: 6, Class: 2, Bytes: []byte(name)},
- },
- },
- }
- crlDp = append(crlDp, dp)
- }
-
- ret[n].Value, err = asn1.Marshal(crlDp)
- if err != nil {
- return
- }
- n++
- }
-
- // Adding another extension here? Remember to update the maximum number
- // of elements in the make() at the top of the function and the list of
- // template fields used in CreateCertificate documentation.
-
- return append(ret[:n], template.ExtraExtensions...), nil
-}
-
-func marshalKeyUsage(ku KeyUsage) (pkix.Extension, error) {
- ext := pkix.Extension{Id: oidExtensionKeyUsage, Critical: true}
-
- var a [2]byte
- a[0] = reverseBitsInAByte(byte(ku))
- a[1] = reverseBitsInAByte(byte(ku >> 8))
-
- l := 1
- if a[1] != 0 {
- l = 2
- }
-
- bitString := a[:l]
- var err error
- ext.Value, err = asn1.Marshal(asn1.BitString{Bytes: bitString, BitLength: asn1BitLength(bitString)})
- return ext, err
-}
-
-func marshalExtKeyUsage(extUsages []ExtKeyUsage, unknownUsages []asn1.ObjectIdentifier) (pkix.Extension, error) {
- ext := pkix.Extension{Id: oidExtensionExtendedKeyUsage}
-
- oids := make([]asn1.ObjectIdentifier, len(extUsages)+len(unknownUsages))
- for i, u := range extUsages {
- if oid, ok := oidFromExtKeyUsage(u); ok {
- oids[i] = oid
- } else {
- return ext, errors.New("x509: unknown extended key usage")
- }
- }
-
- copy(oids[len(extUsages):], unknownUsages)
-
- var err error
- ext.Value, err = asn1.Marshal(oids)
- return ext, err
-}
-
-func marshalBasicConstraints(isCA bool, maxPathLen int, maxPathLenZero bool) (pkix.Extension, error) {
- ext := pkix.Extension{Id: oidExtensionBasicConstraints, Critical: true}
- // Leaving MaxPathLen as zero indicates that no maximum path
- // length is desired, unless MaxPathLenZero is set. A value of
- // -1 causes encoding/asn1 to omit the value as desired.
- if maxPathLen == 0 && !maxPathLenZero {
- maxPathLen = -1
- }
- var err error
- ext.Value, err = asn1.Marshal(basicConstraints{isCA, maxPathLen})
- return ext, err
-}
-
-func marshalCertificatePolicies(policyIdentifiers []asn1.ObjectIdentifier) (pkix.Extension, error) {
- ext := pkix.Extension{Id: oidExtensionCertificatePolicies}
- policies := make([]policyInformation, len(policyIdentifiers))
- for i, policy := range policyIdentifiers {
- policies[i].Policy = policy
- }
- var err error
- ext.Value, err = asn1.Marshal(policies)
- return ext, err
-}
-
-func buildCSRExtensions(template *CertificateRequest) ([]pkix.Extension, error) {
- var ret []pkix.Extension
-
- if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) &&
- !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {
- sanBytes, err := marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses, template.URIs)
- if err != nil {
- return nil, err
- }
-
- ret = append(ret, pkix.Extension{
- Id: oidExtensionSubjectAltName,
- Value: sanBytes,
- })
- }
-
- return append(ret, template.ExtraExtensions...), nil
-}
-
-func subjectBytes(cert *Certificate) ([]byte, error) {
- if len(cert.RawSubject) > 0 {
- return cert.RawSubject, nil
- }
-
- return asn1.Marshal(cert.Subject.ToRDNSequence())
-}
-
-// signingParamsForPublicKey returns the parameters to use for signing with
-// priv. If requestedSigAlgo is not zero then it overrides the default
-// signature algorithm.
-func signingParamsForPublicKey(pub any, requestedSigAlgo SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {
- var pubType PublicKeyAlgorithm
-
- switch pub := pub.(type) {
- case *rsa.PublicKey:
- pubType = RSA
- hashFunc = crypto.SHA256
- sigAlgo.Algorithm = oidSignatureSHA256WithRSA
- sigAlgo.Parameters = asn1.NullRawValue
-
- case *ecdsa.PublicKey:
- pubType = ECDSA
-
- switch pub.Curve {
- case elliptic.P224(), elliptic.P256():
- hashFunc = crypto.SHA256
- sigAlgo.Algorithm = oidSignatureECDSAWithSHA256
- case elliptic.P384():
- hashFunc = crypto.SHA384
- sigAlgo.Algorithm = oidSignatureECDSAWithSHA384
- case elliptic.P521():
- hashFunc = crypto.SHA512
- sigAlgo.Algorithm = oidSignatureECDSAWithSHA512
- default:
- err = errors.New("x509: unknown elliptic curve")
- }
-
- case ed25519.PublicKey:
- pubType = Ed25519
- sigAlgo.Algorithm = oidSignatureEd25519
-
- default:
- err = errors.New("x509: only RSA, ECDSA and Ed25519 keys supported")
- }
-
- if err != nil {
- return
- }
-
- if requestedSigAlgo == 0 {
- return
- }
-
- found := false
- for _, details := range signatureAlgorithmDetails {
- if details.algo == requestedSigAlgo {
- if details.pubKeyAlgo != pubType {
- err = errors.New("x509: requested SignatureAlgorithm does not match private key type")
- return
- }
- sigAlgo.Algorithm, hashFunc = details.oid, details.hash
- if hashFunc == 0 && pubType != Ed25519 {
- err = errors.New("x509: cannot sign with hash function requested")
- return
- }
- if hashFunc == crypto.MD5 {
- err = errors.New("x509: signing with MD5 is not supported")
- return
- }
- if requestedSigAlgo.isRSAPSS() {
- sigAlgo.Parameters = hashToPSSParameters[hashFunc]
- }
- found = true
- break
- }
- }
-
- if !found {
- err = errors.New("x509: unknown SignatureAlgorithm")
- }
-
- return
-}
-
-// emptyASN1Subject is the ASN.1 DER encoding of an empty Subject, which is
-// just an empty SEQUENCE.
-var emptyASN1Subject = []byte{0x30, 0}
-
-// CreateCertificate creates a new X.509 v3 certificate based on a template.
-// The following members of template are currently used:
-//
-// - AuthorityKeyId
-// - BasicConstraintsValid
-// - CRLDistributionPoints
-// - DNSNames
-// - EmailAddresses
-// - ExcludedDNSDomains
-// - ExcludedEmailAddresses
-// - ExcludedIPRanges
-// - ExcludedURIDomains
-// - ExtKeyUsage
-// - ExtraExtensions
-// - IPAddresses
-// - IsCA
-// - IssuingCertificateURL
-// - KeyUsage
-// - MaxPathLen
-// - MaxPathLenZero
-// - NotAfter
-// - NotBefore
-// - OCSPServer
-// - PermittedDNSDomains
-// - PermittedDNSDomainsCritical
-// - PermittedEmailAddresses
-// - PermittedIPRanges
-// - PermittedURIDomains
-// - PolicyIdentifiers
-// - SerialNumber
-// - SignatureAlgorithm
-// - Subject
-// - SubjectKeyId
-// - URIs
-// - UnknownExtKeyUsage
-//
-// The certificate is signed by parent. If parent is equal to template then the
-// certificate is self-signed. The parameter pub is the public key of the
-// certificate to be generated and priv is the private key of the signer.
-//
-// The returned slice is the certificate in DER encoding.
-//
-// The currently supported key types are *rsa.PublicKey, *ecdsa.PublicKey and
-// ed25519.PublicKey. pub must be a supported key type, and priv must be a
-// crypto.Signer with a supported public key.
-//
-// The AuthorityKeyId will be taken from the SubjectKeyId of parent, if any,
-// unless the resulting certificate is self-signed. Otherwise the value from
-// template will be used.
-//
-// If SubjectKeyId from template is empty and the template is a CA, SubjectKeyId
-// will be generated from the hash of the public key.
-func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv any) ([]byte, error) {
- key, ok := priv.(crypto.Signer)
- if !ok {
- return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
- }
-
- if template.SerialNumber == nil {
- return nil, errors.New("x509: no SerialNumber given")
- }
-
- // RFC 5280 Section 4.1.2.2: serial number must positive
- //
- // We _should_ also restrict serials to <= 20 octets, but it turns out a lot of people
- // get this wrong, in part because the encoding can itself alter the length of the
- // serial. For now we accept these non-conformant serials.
- if template.SerialNumber.Sign() == -1 {
- return nil, errors.New("x509: serial number must be positive")
- }
-
- if template.BasicConstraintsValid && !template.IsCA && template.MaxPathLen != -1 && (template.MaxPathLen != 0 || template.MaxPathLenZero) {
- return nil, errors.New("x509: only CAs are allowed to specify MaxPathLen")
- }
-
- hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(key.Public(), template.SignatureAlgorithm)
- if err != nil {
- return nil, err
- }
-
- publicKeyBytes, publicKeyAlgorithm, err := marshalPublicKey(pub)
- if err != nil {
- return nil, err
- }
- if getPublicKeyAlgorithmFromOID(publicKeyAlgorithm.Algorithm) == UnknownPublicKeyAlgorithm {
- return nil, fmt.Errorf("x509: unsupported public key type: %T", pub)
- }
-
- asn1Issuer, err := subjectBytes(parent)
- if err != nil {
- return nil, err
- }
-
- asn1Subject, err := subjectBytes(template)
- if err != nil {
- return nil, err
- }
-
- authorityKeyId := template.AuthorityKeyId
- if !bytes.Equal(asn1Issuer, asn1Subject) && len(parent.SubjectKeyId) > 0 {
- authorityKeyId = parent.SubjectKeyId
- }
-
- subjectKeyId := template.SubjectKeyId
- if len(subjectKeyId) == 0 && template.IsCA {
- // SubjectKeyId generated using method 1 in RFC 5280, Section 4.2.1.2:
- // (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
- // value of the BIT STRING subjectPublicKey (excluding the tag,
- // length, and number of unused bits).
- h := sha1.Sum(publicKeyBytes)
- subjectKeyId = h[:]
- }
-
- // Check that the signer's public key matches the private key, if available.
- type privateKey interface {
- Equal(crypto.PublicKey) bool
- }
- if privPub, ok := key.Public().(privateKey); !ok {
- return nil, errors.New("x509: internal error: supported public key does not implement Equal")
- } else if parent.PublicKey != nil && !privPub.Equal(parent.PublicKey) {
- return nil, errors.New("x509: provided PrivateKey doesn't match parent's PublicKey")
- }
-
- extensions, err := buildCertExtensions(template, bytes.Equal(asn1Subject, emptyASN1Subject), authorityKeyId, subjectKeyId)
- if err != nil {
- return nil, err
- }
-
- encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}
- c := tbsCertificate{
- Version: 2,
- SerialNumber: template.SerialNumber,
- SignatureAlgorithm: signatureAlgorithm,
- Issuer: asn1.RawValue{FullBytes: asn1Issuer},
- Validity: validity{template.NotBefore.UTC(), template.NotAfter.UTC()},
- Subject: asn1.RawValue{FullBytes: asn1Subject},
- PublicKey: publicKeyInfo{nil, publicKeyAlgorithm, encodedPublicKey},
- Extensions: extensions,
- }
-
- tbsCertContents, err := asn1.Marshal(c)
- if err != nil {
- return nil, err
- }
- c.Raw = tbsCertContents
-
- signed := tbsCertContents
- if hashFunc != 0 {
- h := hashFunc.New()
- h.Write(signed)
- signed = h.Sum(nil)
- }
-
- var signerOpts crypto.SignerOpts = hashFunc
- if template.SignatureAlgorithm != 0 && template.SignatureAlgorithm.isRSAPSS() {
- signerOpts = &rsa.PSSOptions{
- SaltLength: rsa.PSSSaltLengthEqualsHash,
- Hash: hashFunc,
- }
- }
-
- var signature []byte
- signature, err = key.Sign(rand, signed, signerOpts)
- if err != nil {
- return nil, err
- }
-
- signedCert, err := asn1.Marshal(certificate{
- c,
- signatureAlgorithm,
- asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
- })
- if err != nil {
- return nil, err
- }
-
- // Check the signature to ensure the crypto.Signer behaved correctly.
- if err := checkSignature(getSignatureAlgorithmFromAI(signatureAlgorithm), c.Raw, signature, key.Public(), true); err != nil {
- return nil, fmt.Errorf("x509: signature over certificate returned by signer is invalid: %w", err)
- }
-
- return signedCert, nil
-}
-
-// pemCRLPrefix is the magic string that indicates that we have a PEM encoded
-// CRL.
-var pemCRLPrefix = []byte("-----BEGIN X509 CRL")
-
-// pemType is the type of a PEM encoded CRL.
-var pemType = "X509 CRL"
-
-// ParseCRL parses a CRL from the given bytes. It's often the case that PEM
-// encoded CRLs will appear where they should be DER encoded, so this function
-// will transparently handle PEM encoding as long as there isn't any leading
-// garbage.
-//
-// Deprecated: Use ParseRevocationList instead.
-func ParseCRL(crlBytes []byte) (*pkix.CertificateList, error) {
- if bytes.HasPrefix(crlBytes, pemCRLPrefix) {
- block, _ := pem.Decode(crlBytes)
- if block != nil && block.Type == pemType {
- crlBytes = block.Bytes
- }
- }
- return ParseDERCRL(crlBytes)
-}
-
-// ParseDERCRL parses a DER encoded CRL from the given bytes.
-//
-// Deprecated: Use ParseRevocationList instead.
-func ParseDERCRL(derBytes []byte) (*pkix.CertificateList, error) {
- certList := new(pkix.CertificateList)
- if rest, err := asn1.Unmarshal(derBytes, certList); err != nil {
- return nil, err
- } else if len(rest) != 0 {
- return nil, errors.New("x509: trailing data after CRL")
- }
- return certList, nil
-}
-
-// CreateCRL returns a DER encoded CRL, signed by this Certificate, that
-// contains the given list of revoked certificates.
-//
-// Deprecated: this method does not generate an RFC 5280 conformant X.509 v2 CRL.
-// To generate a standards compliant CRL, use CreateRevocationList instead.
-func (c *Certificate) CreateCRL(rand io.Reader, priv any, revokedCerts []pkix.RevokedCertificate, now, expiry time.Time) (crlBytes []byte, err error) {
- key, ok := priv.(crypto.Signer)
- if !ok {
- return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
- }
-
- hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(key.Public(), 0)
- if err != nil {
- return nil, err
- }
-
- // Force revocation times to UTC per RFC 5280.
- revokedCertsUTC := make([]pkix.RevokedCertificate, len(revokedCerts))
- for i, rc := range revokedCerts {
- rc.RevocationTime = rc.RevocationTime.UTC()
- revokedCertsUTC[i] = rc
- }
-
- tbsCertList := pkix.TBSCertificateList{
- Version: 1,
- Signature: signatureAlgorithm,
- Issuer: c.Subject.ToRDNSequence(),
- ThisUpdate: now.UTC(),
- NextUpdate: expiry.UTC(),
- RevokedCertificates: revokedCertsUTC,
- }
-
- // Authority Key Id
- if len(c.SubjectKeyId) > 0 {
- var aki pkix.Extension
- aki.Id = oidExtensionAuthorityKeyId
- aki.Value, err = asn1.Marshal(authKeyId{Id: c.SubjectKeyId})
- if err != nil {
- return
- }
- tbsCertList.Extensions = append(tbsCertList.Extensions, aki)
- }
-
- tbsCertListContents, err := asn1.Marshal(tbsCertList)
- if err != nil {
- return
- }
-
- signed := tbsCertListContents
- if hashFunc != 0 {
- h := hashFunc.New()
- h.Write(signed)
- signed = h.Sum(nil)
- }
-
- var signature []byte
- signature, err = key.Sign(rand, signed, hashFunc)
- if err != nil {
- return
- }
-
- return asn1.Marshal(pkix.CertificateList{
- TBSCertList: tbsCertList,
- SignatureAlgorithm: signatureAlgorithm,
- SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
- })
-}
-
-// CertificateRequest represents a PKCS #10, certificate signature request.
-type CertificateRequest struct {
- Raw []byte // Complete ASN.1 DER content (CSR, signature algorithm and signature).
- RawTBSCertificateRequest []byte // Certificate request info part of raw ASN.1 DER content.
- RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo.
- RawSubject []byte // DER encoded Subject.
-
- Version int
- Signature []byte
- SignatureAlgorithm SignatureAlgorithm
-
- PublicKeyAlgorithm PublicKeyAlgorithm
- PublicKey any
-
- Subject pkix.Name
-
- // Attributes contains the CSR attributes that can parse as
- // pkix.AttributeTypeAndValueSET.
- //
- // Deprecated: Use Extensions and ExtraExtensions instead for parsing and
- // generating the requestedExtensions attribute.
- Attributes []pkix.AttributeTypeAndValueSET
-
- // Extensions contains all requested extensions, in raw form. When parsing
- // CSRs, this can be used to extract extensions that are not parsed by this
- // package.
- Extensions []pkix.Extension
-
- // ExtraExtensions contains extensions to be copied, raw, into any CSR
- // marshaled by CreateCertificateRequest. Values override any extensions
- // that would otherwise be produced based on the other fields but are
- // overridden by any extensions specified in Attributes.
- //
- // The ExtraExtensions field is not populated by ParseCertificateRequest,
- // see Extensions instead.
- ExtraExtensions []pkix.Extension
-
- // Subject Alternate Name values.
- DNSNames []string
- EmailAddresses []string
- IPAddresses []net.IP
- URIs []*url.URL
-}
-
-// These structures reflect the ASN.1 structure of X.509 certificate
-// signature requests (see RFC 2986):
-
-type tbsCertificateRequest struct {
- Raw asn1.RawContent
- Version int
- Subject asn1.RawValue
- PublicKey publicKeyInfo
- RawAttributes []asn1.RawValue `asn1:"tag:0"`
-}
-
-type certificateRequest struct {
- Raw asn1.RawContent
- TBSCSR tbsCertificateRequest
- SignatureAlgorithm pkix.AlgorithmIdentifier
- SignatureValue asn1.BitString
-}
-
-// oidExtensionRequest is a PKCS #9 OBJECT IDENTIFIER that indicates requested
-// extensions in a CSR.
-var oidExtensionRequest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 14}
-
-// newRawAttributes converts AttributeTypeAndValueSETs from a template
-// CertificateRequest's Attributes into tbsCertificateRequest RawAttributes.
-func newRawAttributes(attributes []pkix.AttributeTypeAndValueSET) ([]asn1.RawValue, error) {
- var rawAttributes []asn1.RawValue
- b, err := asn1.Marshal(attributes)
- if err != nil {
- return nil, err
- }
- rest, err := asn1.Unmarshal(b, &rawAttributes)
- if err != nil {
- return nil, err
- }
- if len(rest) != 0 {
- return nil, errors.New("x509: failed to unmarshal raw CSR Attributes")
- }
- return rawAttributes, nil
-}
-
-// parseRawAttributes Unmarshals RawAttributes into AttributeTypeAndValueSETs.
-func parseRawAttributes(rawAttributes []asn1.RawValue) []pkix.AttributeTypeAndValueSET {
- var attributes []pkix.AttributeTypeAndValueSET
- for _, rawAttr := range rawAttributes {
- var attr pkix.AttributeTypeAndValueSET
- rest, err := asn1.Unmarshal(rawAttr.FullBytes, &attr)
- // Ignore attributes that don't parse into pkix.AttributeTypeAndValueSET
- // (i.e.: challengePassword or unstructuredName).
- if err == nil && len(rest) == 0 {
- attributes = append(attributes, attr)
- }
- }
- return attributes
-}
-
-// parseCSRExtensions parses the attributes from a CSR and extracts any
-// requested extensions.
-func parseCSRExtensions(rawAttributes []asn1.RawValue) ([]pkix.Extension, error) {
- // pkcs10Attribute reflects the Attribute structure from RFC 2986, Section 4.1.
- type pkcs10Attribute struct {
- Id asn1.ObjectIdentifier
- Values []asn1.RawValue `asn1:"set"`
- }
-
- var ret []pkix.Extension
- requestedExts := make(map[string]bool)
- for _, rawAttr := range rawAttributes {
- var attr pkcs10Attribute
- if rest, err := asn1.Unmarshal(rawAttr.FullBytes, &attr); err != nil || len(rest) != 0 || len(attr.Values) == 0 {
- // Ignore attributes that don't parse.
- continue
- }
-
- if !attr.Id.Equal(oidExtensionRequest) {
- continue
- }
-
- var extensions []pkix.Extension
- if _, err := asn1.Unmarshal(attr.Values[0].FullBytes, &extensions); err != nil {
- return nil, err
- }
- for _, ext := range extensions {
- oidStr := ext.Id.String()
- if requestedExts[oidStr] {
- return nil, errors.New("x509: certificate request contains duplicate requested extensions")
- }
- requestedExts[oidStr] = true
- }
- ret = append(ret, extensions...)
- }
-
- return ret, nil
-}
-
-// CreateCertificateRequest creates a new certificate request based on a
-// template. The following members of template are used:
-//
-// - SignatureAlgorithm
-// - Subject
-// - DNSNames
-// - EmailAddresses
-// - IPAddresses
-// - URIs
-// - ExtraExtensions
-// - Attributes (deprecated)
-//
-// priv is the private key to sign the CSR with, and the corresponding public
-// key will be included in the CSR. It must implement crypto.Signer and its
-// Public() method must return a *rsa.PublicKey or a *ecdsa.PublicKey or a
-// ed25519.PublicKey. (A *rsa.PrivateKey, *ecdsa.PrivateKey or
-// ed25519.PrivateKey satisfies this.)
-//
-// The returned slice is the certificate request in DER encoding.
-func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv any) (csr []byte, err error) {
- key, ok := priv.(crypto.Signer)
- if !ok {
- return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
- }
-
- var hashFunc crypto.Hash
- var sigAlgo pkix.AlgorithmIdentifier
- hashFunc, sigAlgo, err = signingParamsForPublicKey(key.Public(), template.SignatureAlgorithm)
- if err != nil {
- return nil, err
- }
-
- var publicKeyBytes []byte
- var publicKeyAlgorithm pkix.AlgorithmIdentifier
- publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(key.Public())
- if err != nil {
- return nil, err
- }
-
- extensions, err := buildCSRExtensions(template)
- if err != nil {
- return nil, err
- }
-
- // Make a copy of template.Attributes because we may alter it below.
- attributes := make([]pkix.AttributeTypeAndValueSET, 0, len(template.Attributes))
- for _, attr := range template.Attributes {
- values := make([][]pkix.AttributeTypeAndValue, len(attr.Value))
- copy(values, attr.Value)
- attributes = append(attributes, pkix.AttributeTypeAndValueSET{
- Type: attr.Type,
- Value: values,
- })
- }
-
- extensionsAppended := false
- if len(extensions) > 0 {
- // Append the extensions to an existing attribute if possible.
- for _, atvSet := range attributes {
- if !atvSet.Type.Equal(oidExtensionRequest) || len(atvSet.Value) == 0 {
- continue
- }
-
- // specifiedExtensions contains all the extensions that we
- // found specified via template.Attributes.
- specifiedExtensions := make(map[string]bool)
-
- for _, atvs := range atvSet.Value {
- for _, atv := range atvs {
- specifiedExtensions[atv.Type.String()] = true
- }
- }
-
- newValue := make([]pkix.AttributeTypeAndValue, 0, len(atvSet.Value[0])+len(extensions))
- newValue = append(newValue, atvSet.Value[0]...)
-
- for _, e := range extensions {
- if specifiedExtensions[e.Id.String()] {
- // Attributes already contained a value for
- // this extension and it takes priority.
- continue
- }
-
- newValue = append(newValue, pkix.AttributeTypeAndValue{
- // There is no place for the critical
- // flag in an AttributeTypeAndValue.
- Type: e.Id,
- Value: e.Value,
- })
- }
-
- atvSet.Value[0] = newValue
- extensionsAppended = true
- break
- }
- }
-
- rawAttributes, err := newRawAttributes(attributes)
- if err != nil {
- return
- }
-
- // If not included in attributes, add a new attribute for the
- // extensions.
- if len(extensions) > 0 && !extensionsAppended {
- attr := struct {
- Type asn1.ObjectIdentifier
- Value [][]pkix.Extension `asn1:"set"`
- }{
- Type: oidExtensionRequest,
- Value: [][]pkix.Extension{extensions},
- }
-
- b, err := asn1.Marshal(attr)
- if err != nil {
- return nil, errors.New("x509: failed to serialise extensions attribute: " + err.Error())
- }
-
- var rawValue asn1.RawValue
- if _, err := asn1.Unmarshal(b, &rawValue); err != nil {
- return nil, err
- }
-
- rawAttributes = append(rawAttributes, rawValue)
- }
-
- asn1Subject := template.RawSubject
- if len(asn1Subject) == 0 {
- asn1Subject, err = asn1.Marshal(template.Subject.ToRDNSequence())
- if err != nil {
- return nil, err
- }
- }
-
- tbsCSR := tbsCertificateRequest{
- Version: 0, // PKCS #10, RFC 2986
- Subject: asn1.RawValue{FullBytes: asn1Subject},
- PublicKey: publicKeyInfo{
- Algorithm: publicKeyAlgorithm,
- PublicKey: asn1.BitString{
- Bytes: publicKeyBytes,
- BitLength: len(publicKeyBytes) * 8,
- },
- },
- RawAttributes: rawAttributes,
- }
-
- tbsCSRContents, err := asn1.Marshal(tbsCSR)
- if err != nil {
- return
- }
- tbsCSR.Raw = tbsCSRContents
-
- signed := tbsCSRContents
- if hashFunc != 0 {
- h := hashFunc.New()
- h.Write(signed)
- signed = h.Sum(nil)
- }
-
- var signature []byte
- signature, err = key.Sign(rand, signed, hashFunc)
- if err != nil {
- return
- }
-
- return asn1.Marshal(certificateRequest{
- TBSCSR: tbsCSR,
- SignatureAlgorithm: sigAlgo,
- SignatureValue: asn1.BitString{
- Bytes: signature,
- BitLength: len(signature) * 8,
- },
- })
-}
-
-// ParseCertificateRequest parses a single certificate request from the
-// given ASN.1 DER data.
-func ParseCertificateRequest(asn1Data []byte) (*CertificateRequest, error) {
- var csr certificateRequest
-
- rest, err := asn1.Unmarshal(asn1Data, &csr)
- if err != nil {
- return nil, err
- } else if len(rest) != 0 {
- return nil, asn1.SyntaxError{Msg: "trailing data"}
- }
-
- return parseCertificateRequest(&csr)
-}
-
-func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error) {
- out := &CertificateRequest{
- Raw: in.Raw,
- RawTBSCertificateRequest: in.TBSCSR.Raw,
- RawSubjectPublicKeyInfo: in.TBSCSR.PublicKey.Raw,
- RawSubject: in.TBSCSR.Subject.FullBytes,
-
- Signature: in.SignatureValue.RightAlign(),
- SignatureAlgorithm: getSignatureAlgorithmFromAI(in.SignatureAlgorithm),
-
- PublicKeyAlgorithm: getPublicKeyAlgorithmFromOID(in.TBSCSR.PublicKey.Algorithm.Algorithm),
-
- Version: in.TBSCSR.Version,
- Attributes: parseRawAttributes(in.TBSCSR.RawAttributes),
- }
-
- var err error
- if out.PublicKeyAlgorithm != UnknownPublicKeyAlgorithm {
- out.PublicKey, err = parsePublicKey(&in.TBSCSR.PublicKey)
- if err != nil {
- return nil, err
- }
- }
-
- var subject pkix.RDNSequence
- if rest, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil {
- return nil, err
- } else if len(rest) != 0 {
- return nil, errors.New("x509: trailing data after X.509 Subject")
- }
-
- out.Subject.FillFromRDNSequence(&subject)
-
- if out.Extensions, err = parseCSRExtensions(in.TBSCSR.RawAttributes); err != nil {
- return nil, err
- }
-
- for _, extension := range out.Extensions {
- switch {
- case extension.Id.Equal(oidExtensionSubjectAltName):
- out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(extension.Value)
- if err != nil {
- return nil, err
- }
- }
- }
-
- return out, nil
-}
-
-// CheckSignature reports whether the signature on c is valid.
-func (c *CertificateRequest) CheckSignature() error {
- return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificateRequest, c.Signature, c.PublicKey, true)
-}
-
-// RevocationList contains the fields used to create an X.509 v2 Certificate
-// Revocation list with CreateRevocationList.
-type RevocationList struct {
- // Raw contains the complete ASN.1 DER content of the CRL (tbsCertList,
- // signatureAlgorithm, and signatureValue.)
- Raw []byte
- // RawTBSRevocationList contains just the tbsCertList portion of the ASN.1
- // DER.
- RawTBSRevocationList []byte
- // RawIssuer contains the DER encoded Issuer.
- RawIssuer []byte
-
- // Issuer contains the DN of the issuing certificate.
- Issuer pkix.Name
- // AuthorityKeyId is used to identify the public key associated with the
- // issuing certificate. It is populated from the authorityKeyIdentifier
- // extension when parsing a CRL. It is ignored when creating a CRL; the
- // extension is populated from the issuing certificate itself.
- AuthorityKeyId []byte
-
- Signature []byte
- // SignatureAlgorithm is used to determine the signature algorithm to be
- // used when signing the CRL. If 0 the default algorithm for the signing
- // key will be used.
- SignatureAlgorithm SignatureAlgorithm
-
- // RevokedCertificates is used to populate the revokedCertificates
- // sequence in the CRL, it may be empty. RevokedCertificates may be nil,
- // in which case an empty CRL will be created.
- RevokedCertificates []pkix.RevokedCertificate
-
- // Number is used to populate the X.509 v2 cRLNumber extension in the CRL,
- // which should be a monotonically increasing sequence number for a given
- // CRL scope and CRL issuer. It is also populated from the cRLNumber
- // extension when parsing a CRL.
- Number *big.Int
-
- // ThisUpdate is used to populate the thisUpdate field in the CRL, which
- // indicates the issuance date of the CRL.
- ThisUpdate time.Time
- // NextUpdate is used to populate the nextUpdate field in the CRL, which
- // indicates the date by which the next CRL will be issued. NextUpdate
- // must be greater than ThisUpdate.
- NextUpdate time.Time
-
- // Extensions contains raw X.509 extensions. When creating a CRL,
- // the Extensions field is ignored, see ExtraExtensions.
- Extensions []pkix.Extension
-
- // ExtraExtensions contains any additional extensions to add directly to
- // the CRL.
- ExtraExtensions []pkix.Extension
-}
-
-// These structures reflect the ASN.1 structure of X.509 CRLs better than
-// the existing crypto/x509/pkix variants do. These mirror the existing
-// certificate structs in this file.
-//
-// Notably, we include issuer as an asn1.RawValue, mirroring the behavior of
-// tbsCertificate and allowing raw (unparsed) subjects to be passed cleanly.
-type certificateList struct {
- TBSCertList tbsCertificateList
- SignatureAlgorithm pkix.AlgorithmIdentifier
- SignatureValue asn1.BitString
-}
-
-type tbsCertificateList struct {
- Raw asn1.RawContent
- Version int `asn1:"optional,default:0"`
- Signature pkix.AlgorithmIdentifier
- Issuer asn1.RawValue
- ThisUpdate time.Time
- NextUpdate time.Time `asn1:"optional"`
- RevokedCertificates []pkix.RevokedCertificate `asn1:"optional"`
- Extensions []pkix.Extension `asn1:"tag:0,optional,explicit"`
-}
-
-// CreateRevocationList creates a new X.509 v2 Certificate Revocation List,
-// according to RFC 5280, based on template.
-//
-// The CRL is signed by priv which should be the private key associated with
-// the public key in the issuer certificate.
-//
-// The issuer may not be nil, and the crlSign bit must be set in KeyUsage in
-// order to use it as a CRL issuer.
-//
-// The issuer distinguished name CRL field and authority key identifier
-// extension are populated using the issuer certificate. issuer must have
-// SubjectKeyId set.
-func CreateRevocationList(rand io.Reader, template *RevocationList, issuer *Certificate, priv crypto.Signer) ([]byte, error) {
- if template == nil {
- return nil, errors.New("x509: template can not be nil")
- }
- if issuer == nil {
- return nil, errors.New("x509: issuer can not be nil")
- }
- if (issuer.KeyUsage & KeyUsageCRLSign) == 0 {
- return nil, errors.New("x509: issuer must have the crlSign key usage bit set")
- }
- if len(issuer.SubjectKeyId) == 0 {
- return nil, errors.New("x509: issuer certificate doesn't contain a subject key identifier")
- }
- if template.NextUpdate.Before(template.ThisUpdate) {
- return nil, errors.New("x509: template.ThisUpdate is after template.NextUpdate")
- }
- if template.Number == nil {
- return nil, errors.New("x509: template contains nil Number field")
- }
-
- hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm)
- if err != nil {
- return nil, err
- }
-
- // Force revocation times to UTC per RFC 5280.
- revokedCertsUTC := make([]pkix.RevokedCertificate, len(template.RevokedCertificates))
- for i, rc := range template.RevokedCertificates {
- rc.RevocationTime = rc.RevocationTime.UTC()
- revokedCertsUTC[i] = rc
- }
-
- aki, err := asn1.Marshal(authKeyId{Id: issuer.SubjectKeyId})
- if err != nil {
- return nil, err
- }
-
- if numBytes := template.Number.Bytes(); len(numBytes) > 20 || (len(numBytes) == 20 && numBytes[0]&0x80 != 0) {
- return nil, errors.New("x509: CRL number exceeds 20 octets")
- }
- crlNum, err := asn1.Marshal(template.Number)
- if err != nil {
- return nil, err
- }
-
- // Correctly use the issuer's subject sequence if one is specified.
- issuerSubject, err := subjectBytes(issuer)
- if err != nil {
- return nil, err
- }
-
- tbsCertList := tbsCertificateList{
- Version: 1, // v2
- Signature: signatureAlgorithm,
- Issuer: asn1.RawValue{FullBytes: issuerSubject},
- ThisUpdate: template.ThisUpdate.UTC(),
- NextUpdate: template.NextUpdate.UTC(),
- Extensions: []pkix.Extension{
- {
- Id: oidExtensionAuthorityKeyId,
- Value: aki,
- },
- {
- Id: oidExtensionCRLNumber,
- Value: crlNum,
- },
- },
- }
- if len(revokedCertsUTC) > 0 {
- tbsCertList.RevokedCertificates = revokedCertsUTC
- }
-
- if len(template.ExtraExtensions) > 0 {
- tbsCertList.Extensions = append(tbsCertList.Extensions, template.ExtraExtensions...)
- }
-
- tbsCertListContents, err := asn1.Marshal(tbsCertList)
- if err != nil {
- return nil, err
- }
-
- // Optimization to only marshal this struct once, when signing and
- // then embedding in certificateList below.
- tbsCertList.Raw = tbsCertListContents
-
- input := tbsCertListContents
- if hashFunc != 0 {
- h := hashFunc.New()
- h.Write(tbsCertListContents)
- input = h.Sum(nil)
- }
- var signerOpts crypto.SignerOpts = hashFunc
- if template.SignatureAlgorithm.isRSAPSS() {
- signerOpts = &rsa.PSSOptions{
- SaltLength: rsa.PSSSaltLengthEqualsHash,
- Hash: hashFunc,
- }
- }
-
- signature, err := priv.Sign(rand, input, signerOpts)
- if err != nil {
- return nil, err
- }
-
- return asn1.Marshal(certificateList{
- TBSCertList: tbsCertList,
- SignatureAlgorithm: signatureAlgorithm,
- SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
- })
-}
-
-// CheckSignatureFrom verifies that the signature on rl is a valid signature
-// from issuer.
-func (rl *RevocationList) CheckSignatureFrom(parent *Certificate) error {
- if parent.Version == 3 && !parent.BasicConstraintsValid ||
- parent.BasicConstraintsValid && !parent.IsCA {
- return ConstraintViolationError{}
- }
-
- if parent.KeyUsage != 0 && parent.KeyUsage&KeyUsageCRLSign == 0 {
- return ConstraintViolationError{}
- }
-
- if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
- return ErrUnsupportedAlgorithm
- }
-
- return parent.CheckSignature(rl.SignatureAlgorithm, rl.RawTBSRevocationList, rl.Signature)
-}
diff --git a/contrib/go/_std_1.20/src/crypto/x509/ya.make b/contrib/go/_std_1.20/src/crypto/x509/ya.make
deleted file mode 100644
index 99e443c067..0000000000
--- a/contrib/go/_std_1.20/src/crypto/x509/ya.make
+++ /dev/null
@@ -1,40 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- cert_pool.go
- notboring.go
- parser.go
- pem_decrypt.go
- pkcs1.go
- pkcs8.go
- root.go
- sec1.go
- verify.go
- x509.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- root_darwin.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- root_linux.go
- root_unix.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- root_windows.go
- )
-ENDIF()
-
-END()
-
-RECURSE(
- internal
- pkix
-)
diff --git a/contrib/go/_std_1.20/src/crypto/ya.make b/contrib/go/_std_1.20/src/crypto/ya.make
deleted file mode 100644
index 2610933bb9..0000000000
--- a/contrib/go/_std_1.20/src/crypto/ya.make
+++ /dev/null
@@ -1,30 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- crypto.go
-)
-
-END()
-
-RECURSE(
- aes
- cipher
- des
- dsa
- ecdh
- ecdsa
- ed25519
- elliptic
- hmac
- internal
- md5
- rand
- rc4
- rsa
- sha1
- sha256
- sha512
- subtle
- tls
- x509
-)
diff --git a/contrib/go/_std_1.20/src/database/sql/convert.go b/contrib/go/_std_1.20/src/database/sql/convert.go
deleted file mode 100644
index 32941cb4c2..0000000000
--- a/contrib/go/_std_1.20/src/database/sql/convert.go
+++ /dev/null
@@ -1,591 +0,0 @@
-// Copyright 2011 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.
-
-// Type conversions for Scan.
-
-package sql
-
-import (
- "bytes"
- "database/sql/driver"
- "errors"
- "fmt"
- "reflect"
- "strconv"
- "time"
- "unicode"
- "unicode/utf8"
-)
-
-var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
-
-func describeNamedValue(nv *driver.NamedValue) string {
- if len(nv.Name) == 0 {
- return fmt.Sprintf("$%d", nv.Ordinal)
- }
- return fmt.Sprintf("with name %q", nv.Name)
-}
-
-func validateNamedValueName(name string) error {
- if len(name) == 0 {
- return nil
- }
- r, _ := utf8.DecodeRuneInString(name)
- if unicode.IsLetter(r) {
- return nil
- }
- return fmt.Errorf("name %q does not begin with a letter", name)
-}
-
-// ccChecker wraps the driver.ColumnConverter and allows it to be used
-// as if it were a NamedValueChecker. If the driver ColumnConverter
-// is not present then the NamedValueChecker will return driver.ErrSkip.
-type ccChecker struct {
- cci driver.ColumnConverter
- want int
-}
-
-func (c ccChecker) CheckNamedValue(nv *driver.NamedValue) error {
- if c.cci == nil {
- return driver.ErrSkip
- }
- // The column converter shouldn't be called on any index
- // it isn't expecting. The final error will be thrown
- // in the argument converter loop.
- index := nv.Ordinal - 1
- if c.want <= index {
- return nil
- }
-
- // First, see if the value itself knows how to convert
- // itself to a driver type. For example, a NullString
- // struct changing into a string or nil.
- if vr, ok := nv.Value.(driver.Valuer); ok {
- sv, err := callValuerValue(vr)
- if err != nil {
- return err
- }
- if !driver.IsValue(sv) {
- return fmt.Errorf("non-subset type %T returned from Value", sv)
- }
- nv.Value = sv
- }
-
- // Second, ask the column to sanity check itself. For
- // example, drivers might use this to make sure that
- // an int64 values being inserted into a 16-bit
- // integer field is in range (before getting
- // truncated), or that a nil can't go into a NOT NULL
- // column before going across the network to get the
- // same error.
- var err error
- arg := nv.Value
- nv.Value, err = c.cci.ColumnConverter(index).ConvertValue(arg)
- if err != nil {
- return err
- }
- if !driver.IsValue(nv.Value) {
- return fmt.Errorf("driver ColumnConverter error converted %T to unsupported type %T", arg, nv.Value)
- }
- return nil
-}
-
-// defaultCheckNamedValue wraps the default ColumnConverter to have the same
-// function signature as the CheckNamedValue in the driver.NamedValueChecker
-// interface.
-func defaultCheckNamedValue(nv *driver.NamedValue) (err error) {
- nv.Value, err = driver.DefaultParameterConverter.ConvertValue(nv.Value)
- return err
-}
-
-// driverArgsConnLocked converts arguments from callers of Stmt.Exec and
-// Stmt.Query into driver Values.
-//
-// The statement ds may be nil, if no statement is available.
-//
-// ci must be locked.
-func driverArgsConnLocked(ci driver.Conn, ds *driverStmt, args []any) ([]driver.NamedValue, error) {
- nvargs := make([]driver.NamedValue, len(args))
-
- // -1 means the driver doesn't know how to count the number of
- // placeholders, so we won't sanity check input here and instead let the
- // driver deal with errors.
- want := -1
-
- var si driver.Stmt
- var cc ccChecker
- if ds != nil {
- si = ds.si
- want = ds.si.NumInput()
- cc.want = want
- }
-
- // Check all types of interfaces from the start.
- // Drivers may opt to use the NamedValueChecker for special
- // argument types, then return driver.ErrSkip to pass it along
- // to the column converter.
- nvc, ok := si.(driver.NamedValueChecker)
- if !ok {
- nvc, ok = ci.(driver.NamedValueChecker)
- }
- cci, ok := si.(driver.ColumnConverter)
- if ok {
- cc.cci = cci
- }
-
- // Loop through all the arguments, checking each one.
- // If no error is returned simply increment the index
- // and continue. However if driver.ErrRemoveArgument
- // is returned the argument is not included in the query
- // argument list.
- var err error
- var n int
- for _, arg := range args {
- nv := &nvargs[n]
- if np, ok := arg.(NamedArg); ok {
- if err = validateNamedValueName(np.Name); err != nil {
- return nil, err
- }
- arg = np.Value
- nv.Name = np.Name
- }
- nv.Ordinal = n + 1
- nv.Value = arg
-
- // Checking sequence has four routes:
- // A: 1. Default
- // B: 1. NamedValueChecker 2. Column Converter 3. Default
- // C: 1. NamedValueChecker 3. Default
- // D: 1. Column Converter 2. Default
- //
- // The only time a Column Converter is called is first
- // or after NamedValueConverter. If first it is handled before
- // the nextCheck label. Thus for repeats tries only when the
- // NamedValueConverter is selected should the Column Converter
- // be used in the retry.
- checker := defaultCheckNamedValue
- nextCC := false
- switch {
- case nvc != nil:
- nextCC = cci != nil
- checker = nvc.CheckNamedValue
- case cci != nil:
- checker = cc.CheckNamedValue
- }
-
- nextCheck:
- err = checker(nv)
- switch err {
- case nil:
- n++
- continue
- case driver.ErrRemoveArgument:
- nvargs = nvargs[:len(nvargs)-1]
- continue
- case driver.ErrSkip:
- if nextCC {
- nextCC = false
- checker = cc.CheckNamedValue
- } else {
- checker = defaultCheckNamedValue
- }
- goto nextCheck
- default:
- return nil, fmt.Errorf("sql: converting argument %s type: %v", describeNamedValue(nv), err)
- }
- }
-
- // Check the length of arguments after conversion to allow for omitted
- // arguments.
- if want != -1 && len(nvargs) != want {
- return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(nvargs))
- }
-
- return nvargs, nil
-
-}
-
-// convertAssign is the same as convertAssignRows, but without the optional
-// rows argument.
-func convertAssign(dest, src any) error {
- return convertAssignRows(dest, src, nil)
-}
-
-// convertAssignRows copies to dest the value in src, converting it if possible.
-// An error is returned if the copy would result in loss of information.
-// dest should be a pointer type. If rows is passed in, the rows will
-// be used as the parent for any cursor values converted from a
-// driver.Rows to a *Rows.
-func convertAssignRows(dest, src any, rows *Rows) error {
- // Common cases, without reflect.
- switch s := src.(type) {
- case string:
- switch d := dest.(type) {
- case *string:
- if d == nil {
- return errNilPtr
- }
- *d = s
- return nil
- case *[]byte:
- if d == nil {
- return errNilPtr
- }
- *d = []byte(s)
- return nil
- case *RawBytes:
- if d == nil {
- return errNilPtr
- }
- *d = append((*d)[:0], s...)
- return nil
- }
- case []byte:
- switch d := dest.(type) {
- case *string:
- if d == nil {
- return errNilPtr
- }
- *d = string(s)
- return nil
- case *any:
- if d == nil {
- return errNilPtr
- }
- *d = bytes.Clone(s)
- return nil
- case *[]byte:
- if d == nil {
- return errNilPtr
- }
- *d = bytes.Clone(s)
- return nil
- case *RawBytes:
- if d == nil {
- return errNilPtr
- }
- *d = s
- return nil
- }
- case time.Time:
- switch d := dest.(type) {
- case *time.Time:
- *d = s
- return nil
- case *string:
- *d = s.Format(time.RFC3339Nano)
- return nil
- case *[]byte:
- if d == nil {
- return errNilPtr
- }
- *d = []byte(s.Format(time.RFC3339Nano))
- return nil
- case *RawBytes:
- if d == nil {
- return errNilPtr
- }
- *d = s.AppendFormat((*d)[:0], time.RFC3339Nano)
- return nil
- }
- case decimalDecompose:
- switch d := dest.(type) {
- case decimalCompose:
- return d.Compose(s.Decompose(nil))
- }
- case nil:
- switch d := dest.(type) {
- case *any:
- if d == nil {
- return errNilPtr
- }
- *d = nil
- return nil
- case *[]byte:
- if d == nil {
- return errNilPtr
- }
- *d = nil
- return nil
- case *RawBytes:
- if d == nil {
- return errNilPtr
- }
- *d = nil
- return nil
- }
- // The driver is returning a cursor the client may iterate over.
- case driver.Rows:
- switch d := dest.(type) {
- case *Rows:
- if d == nil {
- return errNilPtr
- }
- if rows == nil {
- return errors.New("invalid context to convert cursor rows, missing parent *Rows")
- }
- rows.closemu.Lock()
- *d = Rows{
- dc: rows.dc,
- releaseConn: func(error) {},
- rowsi: s,
- }
- // Chain the cancel function.
- parentCancel := rows.cancel
- rows.cancel = func() {
- // When Rows.cancel is called, the closemu will be locked as well.
- // So we can access rs.lasterr.
- d.close(rows.lasterr)
- if parentCancel != nil {
- parentCancel()
- }
- }
- rows.closemu.Unlock()
- return nil
- }
- }
-
- var sv reflect.Value
-
- switch d := dest.(type) {
- case *string:
- sv = reflect.ValueOf(src)
- switch sv.Kind() {
- case reflect.Bool,
- reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
- reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
- reflect.Float32, reflect.Float64:
- *d = asString(src)
- return nil
- }
- case *[]byte:
- sv = reflect.ValueOf(src)
- if b, ok := asBytes(nil, sv); ok {
- *d = b
- return nil
- }
- case *RawBytes:
- sv = reflect.ValueOf(src)
- if b, ok := asBytes([]byte(*d)[:0], sv); ok {
- *d = RawBytes(b)
- return nil
- }
- case *bool:
- bv, err := driver.Bool.ConvertValue(src)
- if err == nil {
- *d = bv.(bool)
- }
- return err
- case *any:
- *d = src
- return nil
- }
-
- if scanner, ok := dest.(Scanner); ok {
- return scanner.Scan(src)
- }
-
- dpv := reflect.ValueOf(dest)
- if dpv.Kind() != reflect.Pointer {
- return errors.New("destination not a pointer")
- }
- if dpv.IsNil() {
- return errNilPtr
- }
-
- if !sv.IsValid() {
- sv = reflect.ValueOf(src)
- }
-
- dv := reflect.Indirect(dpv)
- if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) {
- switch b := src.(type) {
- case []byte:
- dv.Set(reflect.ValueOf(bytes.Clone(b)))
- default:
- dv.Set(sv)
- }
- return nil
- }
-
- if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) {
- dv.Set(sv.Convert(dv.Type()))
- return nil
- }
-
- // The following conversions use a string value as an intermediate representation
- // to convert between various numeric types.
- //
- // This also allows scanning into user defined types such as "type Int int64".
- // For symmetry, also check for string destination types.
- switch dv.Kind() {
- case reflect.Pointer:
- if src == nil {
- dv.Set(reflect.Zero(dv.Type()))
- return nil
- }
- dv.Set(reflect.New(dv.Type().Elem()))
- return convertAssignRows(dv.Interface(), src, rows)
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- if src == nil {
- return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
- }
- s := asString(src)
- i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
- if err != nil {
- err = strconvErr(err)
- return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
- }
- dv.SetInt(i64)
- return nil
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- if src == nil {
- return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
- }
- s := asString(src)
- u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
- if err != nil {
- err = strconvErr(err)
- return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
- }
- dv.SetUint(u64)
- return nil
- case reflect.Float32, reflect.Float64:
- if src == nil {
- return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
- }
- s := asString(src)
- f64, err := strconv.ParseFloat(s, dv.Type().Bits())
- if err != nil {
- err = strconvErr(err)
- return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
- }
- dv.SetFloat(f64)
- return nil
- case reflect.String:
- if src == nil {
- return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
- }
- switch v := src.(type) {
- case string:
- dv.SetString(v)
- return nil
- case []byte:
- dv.SetString(string(v))
- return nil
- }
- }
-
- return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest)
-}
-
-func strconvErr(err error) error {
- if ne, ok := err.(*strconv.NumError); ok {
- return ne.Err
- }
- return err
-}
-
-func asString(src any) string {
- switch v := src.(type) {
- case string:
- return v
- case []byte:
- return string(v)
- }
- rv := reflect.ValueOf(src)
- switch rv.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return strconv.FormatInt(rv.Int(), 10)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return strconv.FormatUint(rv.Uint(), 10)
- case reflect.Float64:
- return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
- case reflect.Float32:
- return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
- case reflect.Bool:
- return strconv.FormatBool(rv.Bool())
- }
- return fmt.Sprintf("%v", src)
-}
-
-func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) {
- switch rv.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return strconv.AppendInt(buf, rv.Int(), 10), true
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return strconv.AppendUint(buf, rv.Uint(), 10), true
- case reflect.Float32:
- return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true
- case reflect.Float64:
- return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true
- case reflect.Bool:
- return strconv.AppendBool(buf, rv.Bool()), true
- case reflect.String:
- s := rv.String()
- return append(buf, s...), true
- }
- return
-}
-
-var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
-
-// callValuerValue returns vr.Value(), with one exception:
-// If vr.Value is an auto-generated method on a pointer type and the
-// pointer is nil, it would panic at runtime in the panicwrap
-// method. Treat it like nil instead.
-// Issue 8415.
-//
-// This is so people can implement driver.Value on value types and
-// still use nil pointers to those types to mean nil/NULL, just like
-// string/*string.
-//
-// This function is mirrored in the database/sql/driver package.
-func callValuerValue(vr driver.Valuer) (v driver.Value, err error) {
- if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Pointer &&
- rv.IsNil() &&
- rv.Type().Elem().Implements(valuerReflectType) {
- return nil, nil
- }
- return vr.Value()
-}
-
-// decimal composes or decomposes a decimal value to and from individual parts.
-// There are four parts: a boolean negative flag, a form byte with three possible states
-// (finite=0, infinite=1, NaN=2), a base-2 big-endian integer
-// coefficient (also known as a significand) as a []byte, and an int32 exponent.
-// These are composed into a final value as "decimal = (neg) (form=finite) coefficient * 10 ^ exponent".
-// A zero length coefficient is a zero value.
-// The big-endian integer coefficient stores the most significant byte first (at coefficient[0]).
-// If the form is not finite the coefficient and exponent should be ignored.
-// The negative parameter may be set to true for any form, although implementations are not required
-// to respect the negative parameter in the non-finite form.
-//
-// Implementations may choose to set the negative parameter to true on a zero or NaN value,
-// but implementations that do not differentiate between negative and positive
-// zero or NaN values should ignore the negative parameter without error.
-// If an implementation does not support Infinity it may be converted into a NaN without error.
-// If a value is set that is larger than what is supported by an implementation,
-// an error must be returned.
-// Implementations must return an error if a NaN or Infinity is attempted to be set while neither
-// are supported.
-//
-// NOTE(kardianos): This is an experimental interface. See https://golang.org/issue/30870
-type decimal interface {
- decimalDecompose
- decimalCompose
-}
-
-type decimalDecompose interface {
- // Decompose returns the internal decimal state in parts.
- // If the provided buf has sufficient capacity, buf may be returned as the coefficient with
- // the value set and length set as appropriate.
- Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32)
-}
-
-type decimalCompose interface {
- // Compose sets the internal decimal value from parts. If the value cannot be
- // represented then an error should be returned.
- Compose(form byte, negative bool, coefficient []byte, exponent int32) error
-}
diff --git a/contrib/go/_std_1.20/src/database/sql/driver/ya.make b/contrib/go/_std_1.20/src/database/sql/driver/ya.make
deleted file mode 100644
index 0ff07398f6..0000000000
--- a/contrib/go/_std_1.20/src/database/sql/driver/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- driver.go
- types.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/database/sql/sql.go b/contrib/go/_std_1.20/src/database/sql/sql.go
deleted file mode 100644
index ad17eb3da2..0000000000
--- a/contrib/go/_std_1.20/src/database/sql/sql.go
+++ /dev/null
@@ -1,3406 +0,0 @@
-// Copyright 2011 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 sql provides a generic interface around SQL (or SQL-like)
-// databases.
-//
-// The sql package must be used in conjunction with a database driver.
-// See https://golang.org/s/sqldrivers for a list of drivers.
-//
-// Drivers that do not support context cancellation will not return until
-// after the query is completed.
-//
-// For usage examples, see the wiki page at
-// https://golang.org/s/sqlwiki.
-package sql
-
-import (
- "context"
- "database/sql/driver"
- "errors"
- "fmt"
- "io"
- "reflect"
- "runtime"
- "sort"
- "strconv"
- "sync"
- "sync/atomic"
- "time"
-)
-
-var (
- driversMu sync.RWMutex
- drivers = make(map[string]driver.Driver)
-)
-
-// nowFunc returns the current time; it's overridden in tests.
-var nowFunc = time.Now
-
-// Register makes a database driver available by the provided name.
-// If Register is called twice with the same name or if driver is nil,
-// it panics.
-func Register(name string, driver driver.Driver) {
- driversMu.Lock()
- defer driversMu.Unlock()
- if driver == nil {
- panic("sql: Register driver is nil")
- }
- if _, dup := drivers[name]; dup {
- panic("sql: Register called twice for driver " + name)
- }
- drivers[name] = driver
-}
-
-func unregisterAllDrivers() {
- driversMu.Lock()
- defer driversMu.Unlock()
- // For tests.
- drivers = make(map[string]driver.Driver)
-}
-
-// Drivers returns a sorted list of the names of the registered drivers.
-func Drivers() []string {
- driversMu.RLock()
- defer driversMu.RUnlock()
- list := make([]string, 0, len(drivers))
- for name := range drivers {
- list = append(list, name)
- }
- sort.Strings(list)
- return list
-}
-
-// A NamedArg is a named argument. NamedArg values may be used as
-// arguments to Query or Exec and bind to the corresponding named
-// parameter in the SQL statement.
-//
-// For a more concise way to create NamedArg values, see
-// the Named function.
-type NamedArg struct {
- _NamedFieldsRequired struct{}
-
- // Name is the name of the parameter placeholder.
- //
- // If empty, the ordinal position in the argument list will be
- // used.
- //
- // Name must omit any symbol prefix.
- Name string
-
- // Value is the value of the parameter.
- // It may be assigned the same value types as the query
- // arguments.
- Value any
-}
-
-// Named provides a more concise way to create NamedArg values.
-//
-// Example usage:
-//
-// db.ExecContext(ctx, `
-// delete from Invoice
-// where
-// TimeCreated < @end
-// and TimeCreated >= @start;`,
-// sql.Named("start", startTime),
-// sql.Named("end", endTime),
-// )
-func Named(name string, value any) NamedArg {
- // This method exists because the go1compat promise
- // doesn't guarantee that structs don't grow more fields,
- // so unkeyed struct literals are a vet error. Thus, we don't
- // want to allow sql.NamedArg{name, value}.
- return NamedArg{Name: name, Value: value}
-}
-
-// IsolationLevel is the transaction isolation level used in TxOptions.
-type IsolationLevel int
-
-// Various isolation levels that drivers may support in BeginTx.
-// If a driver does not support a given isolation level an error may be returned.
-//
-// See https://en.wikipedia.org/wiki/Isolation_(database_systems)#Isolation_levels.
-const (
- LevelDefault IsolationLevel = iota
- LevelReadUncommitted
- LevelReadCommitted
- LevelWriteCommitted
- LevelRepeatableRead
- LevelSnapshot
- LevelSerializable
- LevelLinearizable
-)
-
-// String returns the name of the transaction isolation level.
-func (i IsolationLevel) String() string {
- switch i {
- case LevelDefault:
- return "Default"
- case LevelReadUncommitted:
- return "Read Uncommitted"
- case LevelReadCommitted:
- return "Read Committed"
- case LevelWriteCommitted:
- return "Write Committed"
- case LevelRepeatableRead:
- return "Repeatable Read"
- case LevelSnapshot:
- return "Snapshot"
- case LevelSerializable:
- return "Serializable"
- case LevelLinearizable:
- return "Linearizable"
- default:
- return "IsolationLevel(" + strconv.Itoa(int(i)) + ")"
- }
-}
-
-var _ fmt.Stringer = LevelDefault
-
-// TxOptions holds the transaction options to be used in DB.BeginTx.
-type TxOptions struct {
- // Isolation is the transaction isolation level.
- // If zero, the driver or database's default level is used.
- Isolation IsolationLevel
- ReadOnly bool
-}
-
-// RawBytes is a byte slice that holds a reference to memory owned by
-// the database itself. After a Scan into a RawBytes, the slice is only
-// valid until the next call to Next, Scan, or Close.
-type RawBytes []byte
-
-// NullString represents a string that may be null.
-// NullString implements the Scanner interface so
-// it can be used as a scan destination:
-//
-// var s NullString
-// err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s)
-// ...
-// if s.Valid {
-// // use s.String
-// } else {
-// // NULL value
-// }
-type NullString struct {
- String string
- Valid bool // Valid is true if String is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (ns *NullString) Scan(value any) error {
- if value == nil {
- ns.String, ns.Valid = "", false
- return nil
- }
- ns.Valid = true
- return convertAssign(&ns.String, value)
-}
-
-// Value implements the driver Valuer interface.
-func (ns NullString) Value() (driver.Value, error) {
- if !ns.Valid {
- return nil, nil
- }
- return ns.String, nil
-}
-
-// NullInt64 represents an int64 that may be null.
-// NullInt64 implements the Scanner interface so
-// it can be used as a scan destination, similar to NullString.
-type NullInt64 struct {
- Int64 int64
- Valid bool // Valid is true if Int64 is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (n *NullInt64) Scan(value any) error {
- if value == nil {
- n.Int64, n.Valid = 0, false
- return nil
- }
- n.Valid = true
- return convertAssign(&n.Int64, value)
-}
-
-// Value implements the driver Valuer interface.
-func (n NullInt64) Value() (driver.Value, error) {
- if !n.Valid {
- return nil, nil
- }
- return n.Int64, nil
-}
-
-// NullInt32 represents an int32 that may be null.
-// NullInt32 implements the Scanner interface so
-// it can be used as a scan destination, similar to NullString.
-type NullInt32 struct {
- Int32 int32
- Valid bool // Valid is true if Int32 is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (n *NullInt32) Scan(value any) error {
- if value == nil {
- n.Int32, n.Valid = 0, false
- return nil
- }
- n.Valid = true
- return convertAssign(&n.Int32, value)
-}
-
-// Value implements the driver Valuer interface.
-func (n NullInt32) Value() (driver.Value, error) {
- if !n.Valid {
- return nil, nil
- }
- return int64(n.Int32), nil
-}
-
-// NullInt16 represents an int16 that may be null.
-// NullInt16 implements the Scanner interface so
-// it can be used as a scan destination, similar to NullString.
-type NullInt16 struct {
- Int16 int16
- Valid bool // Valid is true if Int16 is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (n *NullInt16) Scan(value any) error {
- if value == nil {
- n.Int16, n.Valid = 0, false
- return nil
- }
- err := convertAssign(&n.Int16, value)
- n.Valid = err == nil
- return err
-}
-
-// Value implements the driver Valuer interface.
-func (n NullInt16) Value() (driver.Value, error) {
- if !n.Valid {
- return nil, nil
- }
- return int64(n.Int16), nil
-}
-
-// NullByte represents a byte that may be null.
-// NullByte implements the Scanner interface so
-// it can be used as a scan destination, similar to NullString.
-type NullByte struct {
- Byte byte
- Valid bool // Valid is true if Byte is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (n *NullByte) Scan(value any) error {
- if value == nil {
- n.Byte, n.Valid = 0, false
- return nil
- }
- err := convertAssign(&n.Byte, value)
- n.Valid = err == nil
- return err
-}
-
-// Value implements the driver Valuer interface.
-func (n NullByte) Value() (driver.Value, error) {
- if !n.Valid {
- return nil, nil
- }
- return int64(n.Byte), nil
-}
-
-// NullFloat64 represents a float64 that may be null.
-// NullFloat64 implements the Scanner interface so
-// it can be used as a scan destination, similar to NullString.
-type NullFloat64 struct {
- Float64 float64
- Valid bool // Valid is true if Float64 is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (n *NullFloat64) Scan(value any) error {
- if value == nil {
- n.Float64, n.Valid = 0, false
- return nil
- }
- n.Valid = true
- return convertAssign(&n.Float64, value)
-}
-
-// Value implements the driver Valuer interface.
-func (n NullFloat64) Value() (driver.Value, error) {
- if !n.Valid {
- return nil, nil
- }
- return n.Float64, nil
-}
-
-// NullBool represents a bool that may be null.
-// NullBool implements the Scanner interface so
-// it can be used as a scan destination, similar to NullString.
-type NullBool struct {
- Bool bool
- Valid bool // Valid is true if Bool is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (n *NullBool) Scan(value any) error {
- if value == nil {
- n.Bool, n.Valid = false, false
- return nil
- }
- n.Valid = true
- return convertAssign(&n.Bool, value)
-}
-
-// Value implements the driver Valuer interface.
-func (n NullBool) Value() (driver.Value, error) {
- if !n.Valid {
- return nil, nil
- }
- return n.Bool, nil
-}
-
-// NullTime represents a time.Time that may be null.
-// NullTime implements the Scanner interface so
-// it can be used as a scan destination, similar to NullString.
-type NullTime struct {
- Time time.Time
- Valid bool // Valid is true if Time is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (n *NullTime) Scan(value any) error {
- if value == nil {
- n.Time, n.Valid = time.Time{}, false
- return nil
- }
- n.Valid = true
- return convertAssign(&n.Time, value)
-}
-
-// Value implements the driver Valuer interface.
-func (n NullTime) Value() (driver.Value, error) {
- if !n.Valid {
- return nil, nil
- }
- return n.Time, nil
-}
-
-// Scanner is an interface used by Scan.
-type Scanner interface {
- // Scan assigns a value from a database driver.
- //
- // The src value will be of one of the following types:
- //
- // int64
- // float64
- // bool
- // []byte
- // string
- // time.Time
- // nil - for NULL values
- //
- // An error should be returned if the value cannot be stored
- // without loss of information.
- //
- // Reference types such as []byte are only valid until the next call to Scan
- // and should not be retained. Their underlying memory is owned by the driver.
- // If retention is necessary, copy their values before the next call to Scan.
- Scan(src any) error
-}
-
-// Out may be used to retrieve OUTPUT value parameters from stored procedures.
-//
-// Not all drivers and databases support OUTPUT value parameters.
-//
-// Example usage:
-//
-// var outArg string
-// _, err := db.ExecContext(ctx, "ProcName", sql.Named("Arg1", sql.Out{Dest: &outArg}))
-type Out struct {
- _NamedFieldsRequired struct{}
-
- // Dest is a pointer to the value that will be set to the result of the
- // stored procedure's OUTPUT parameter.
- Dest any
-
- // In is whether the parameter is an INOUT parameter. If so, the input value to the stored
- // procedure is the dereferenced value of Dest's pointer, which is then replaced with
- // the output value.
- In bool
-}
-
-// ErrNoRows is returned by Scan when QueryRow doesn't return a
-// row. In such a case, QueryRow returns a placeholder *Row value that
-// defers this error until a Scan.
-var ErrNoRows = errors.New("sql: no rows in result set")
-
-// DB is a database handle representing a pool of zero or more
-// underlying connections. It's safe for concurrent use by multiple
-// goroutines.
-//
-// The sql package creates and frees connections automatically; it
-// also maintains a free pool of idle connections. If the database has
-// a concept of per-connection state, such state can be reliably observed
-// within a transaction (Tx) or connection (Conn). Once DB.Begin is called, the
-// returned Tx is bound to a single connection. Once Commit or
-// Rollback is called on the transaction, that transaction's
-// connection is returned to DB's idle connection pool. The pool size
-// can be controlled with SetMaxIdleConns.
-type DB struct {
- // Total time waited for new connections.
- waitDuration atomic.Int64
-
- connector driver.Connector
- // numClosed is an atomic counter which represents a total number of
- // closed connections. Stmt.openStmt checks it before cleaning closed
- // connections in Stmt.css.
- numClosed atomic.Uint64
-
- mu sync.Mutex // protects following fields
- freeConn []*driverConn // free connections ordered by returnedAt oldest to newest
- connRequests map[uint64]chan connRequest
- nextRequest uint64 // Next key to use in connRequests.
- numOpen int // number of opened and pending open connections
- // Used to signal the need for new connections
- // a goroutine running connectionOpener() reads on this chan and
- // maybeOpenNewConnections sends on the chan (one send per needed connection)
- // It is closed during db.Close(). The close tells the connectionOpener
- // goroutine to exit.
- openerCh chan struct{}
- closed bool
- dep map[finalCloser]depSet
- lastPut map[*driverConn]string // stacktrace of last conn's put; debug only
- maxIdleCount int // zero means defaultMaxIdleConns; negative means 0
- maxOpen int // <= 0 means unlimited
- maxLifetime time.Duration // maximum amount of time a connection may be reused
- maxIdleTime time.Duration // maximum amount of time a connection may be idle before being closed
- cleanerCh chan struct{}
- waitCount int64 // Total number of connections waited for.
- maxIdleClosed int64 // Total number of connections closed due to idle count.
- maxIdleTimeClosed int64 // Total number of connections closed due to idle time.
- maxLifetimeClosed int64 // Total number of connections closed due to max connection lifetime limit.
-
- stop func() // stop cancels the connection opener.
-}
-
-// connReuseStrategy determines how (*DB).conn returns database connections.
-type connReuseStrategy uint8
-
-const (
- // alwaysNewConn forces a new connection to the database.
- alwaysNewConn connReuseStrategy = iota
- // cachedOrNewConn returns a cached connection, if available, else waits
- // for one to become available (if MaxOpenConns has been reached) or
- // creates a new database connection.
- cachedOrNewConn
-)
-
-// driverConn wraps a driver.Conn with a mutex, to
-// be held during all calls into the Conn. (including any calls onto
-// interfaces returned via that Conn, such as calls on Tx, Stmt,
-// Result, Rows)
-type driverConn struct {
- db *DB
- createdAt time.Time
-
- sync.Mutex // guards following
- ci driver.Conn
- needReset bool // The connection session should be reset before use if true.
- closed bool
- finalClosed bool // ci.Close has been called
- openStmt map[*driverStmt]bool
-
- // guarded by db.mu
- inUse bool
- returnedAt time.Time // Time the connection was created or returned.
- onPut []func() // code (with db.mu held) run when conn is next returned
- dbmuClosed bool // same as closed, but guarded by db.mu, for removeClosedStmtLocked
-}
-
-func (dc *driverConn) releaseConn(err error) {
- dc.db.putConn(dc, err, true)
-}
-
-func (dc *driverConn) removeOpenStmt(ds *driverStmt) {
- dc.Lock()
- defer dc.Unlock()
- delete(dc.openStmt, ds)
-}
-
-func (dc *driverConn) expired(timeout time.Duration) bool {
- if timeout <= 0 {
- return false
- }
- return dc.createdAt.Add(timeout).Before(nowFunc())
-}
-
-// resetSession checks if the driver connection needs the
-// session to be reset and if required, resets it.
-func (dc *driverConn) resetSession(ctx context.Context) error {
- dc.Lock()
- defer dc.Unlock()
-
- if !dc.needReset {
- return nil
- }
- if cr, ok := dc.ci.(driver.SessionResetter); ok {
- return cr.ResetSession(ctx)
- }
- return nil
-}
-
-// validateConnection checks if the connection is valid and can
-// still be used. It also marks the session for reset if required.
-func (dc *driverConn) validateConnection(needsReset bool) bool {
- dc.Lock()
- defer dc.Unlock()
-
- if needsReset {
- dc.needReset = true
- }
- if cv, ok := dc.ci.(driver.Validator); ok {
- return cv.IsValid()
- }
- return true
-}
-
-// prepareLocked prepares the query on dc. When cg == nil the dc must keep track of
-// the prepared statements in a pool.
-func (dc *driverConn) prepareLocked(ctx context.Context, cg stmtConnGrabber, query string) (*driverStmt, error) {
- si, err := ctxDriverPrepare(ctx, dc.ci, query)
- if err != nil {
- return nil, err
- }
- ds := &driverStmt{Locker: dc, si: si}
-
- // No need to manage open statements if there is a single connection grabber.
- if cg != nil {
- return ds, nil
- }
-
- // Track each driverConn's open statements, so we can close them
- // before closing the conn.
- //
- // Wrap all driver.Stmt is *driverStmt to ensure they are only closed once.
- if dc.openStmt == nil {
- dc.openStmt = make(map[*driverStmt]bool)
- }
- dc.openStmt[ds] = true
- return ds, nil
-}
-
-// the dc.db's Mutex is held.
-func (dc *driverConn) closeDBLocked() func() error {
- dc.Lock()
- defer dc.Unlock()
- if dc.closed {
- return func() error { return errors.New("sql: duplicate driverConn close") }
- }
- dc.closed = true
- return dc.db.removeDepLocked(dc, dc)
-}
-
-func (dc *driverConn) Close() error {
- dc.Lock()
- if dc.closed {
- dc.Unlock()
- return errors.New("sql: duplicate driverConn close")
- }
- dc.closed = true
- dc.Unlock() // not defer; removeDep finalClose calls may need to lock
-
- // And now updates that require holding dc.mu.Lock.
- dc.db.mu.Lock()
- dc.dbmuClosed = true
- fn := dc.db.removeDepLocked(dc, dc)
- dc.db.mu.Unlock()
- return fn()
-}
-
-func (dc *driverConn) finalClose() error {
- var err error
-
- // Each *driverStmt has a lock to the dc. Copy the list out of the dc
- // before calling close on each stmt.
- var openStmt []*driverStmt
- withLock(dc, func() {
- openStmt = make([]*driverStmt, 0, len(dc.openStmt))
- for ds := range dc.openStmt {
- openStmt = append(openStmt, ds)
- }
- dc.openStmt = nil
- })
- for _, ds := range openStmt {
- ds.Close()
- }
- withLock(dc, func() {
- dc.finalClosed = true
- err = dc.ci.Close()
- dc.ci = nil
- })
-
- dc.db.mu.Lock()
- dc.db.numOpen--
- dc.db.maybeOpenNewConnections()
- dc.db.mu.Unlock()
-
- dc.db.numClosed.Add(1)
- return err
-}
-
-// driverStmt associates a driver.Stmt with the
-// *driverConn from which it came, so the driverConn's lock can be
-// held during calls.
-type driverStmt struct {
- sync.Locker // the *driverConn
- si driver.Stmt
- closed bool
- closeErr error // return value of previous Close call
-}
-
-// Close ensures driver.Stmt is only closed once and always returns the same
-// result.
-func (ds *driverStmt) Close() error {
- ds.Lock()
- defer ds.Unlock()
- if ds.closed {
- return ds.closeErr
- }
- ds.closed = true
- ds.closeErr = ds.si.Close()
- return ds.closeErr
-}
-
-// depSet is a finalCloser's outstanding dependencies
-type depSet map[any]bool // set of true bools
-
-// The finalCloser interface is used by (*DB).addDep and related
-// dependency reference counting.
-type finalCloser interface {
- // finalClose is called when the reference count of an object
- // goes to zero. (*DB).mu is not held while calling it.
- finalClose() error
-}
-
-// addDep notes that x now depends on dep, and x's finalClose won't be
-// called until all of x's dependencies are removed with removeDep.
-func (db *DB) addDep(x finalCloser, dep any) {
- db.mu.Lock()
- defer db.mu.Unlock()
- db.addDepLocked(x, dep)
-}
-
-func (db *DB) addDepLocked(x finalCloser, dep any) {
- if db.dep == nil {
- db.dep = make(map[finalCloser]depSet)
- }
- xdep := db.dep[x]
- if xdep == nil {
- xdep = make(depSet)
- db.dep[x] = xdep
- }
- xdep[dep] = true
-}
-
-// removeDep notes that x no longer depends on dep.
-// If x still has dependencies, nil is returned.
-// If x no longer has any dependencies, its finalClose method will be
-// called and its error value will be returned.
-func (db *DB) removeDep(x finalCloser, dep any) error {
- db.mu.Lock()
- fn := db.removeDepLocked(x, dep)
- db.mu.Unlock()
- return fn()
-}
-
-func (db *DB) removeDepLocked(x finalCloser, dep any) func() error {
- xdep, ok := db.dep[x]
- if !ok {
- panic(fmt.Sprintf("unpaired removeDep: no deps for %T", x))
- }
-
- l0 := len(xdep)
- delete(xdep, dep)
-
- switch len(xdep) {
- case l0:
- // Nothing removed. Shouldn't happen.
- panic(fmt.Sprintf("unpaired removeDep: no %T dep on %T", dep, x))
- case 0:
- // No more dependencies.
- delete(db.dep, x)
- return x.finalClose
- default:
- // Dependencies remain.
- return func() error { return nil }
- }
-}
-
-// This is the size of the connectionOpener request chan (DB.openerCh).
-// This value should be larger than the maximum typical value
-// used for db.maxOpen. If maxOpen is significantly larger than
-// connectionRequestQueueSize then it is possible for ALL calls into the *DB
-// to block until the connectionOpener can satisfy the backlog of requests.
-var connectionRequestQueueSize = 1000000
-
-type dsnConnector struct {
- dsn string
- driver driver.Driver
-}
-
-func (t dsnConnector) Connect(_ context.Context) (driver.Conn, error) {
- return t.driver.Open(t.dsn)
-}
-
-func (t dsnConnector) Driver() driver.Driver {
- return t.driver
-}
-
-// OpenDB opens a database using a Connector, allowing drivers to
-// bypass a string based data source name.
-//
-// Most users will open a database via a driver-specific connection
-// helper function that returns a *DB. No database drivers are included
-// in the Go standard library. See https://golang.org/s/sqldrivers for
-// a list of third-party drivers.
-//
-// OpenDB may just validate its arguments without creating a connection
-// to the database. To verify that the data source name is valid, call
-// Ping.
-//
-// The returned DB is safe for concurrent use by multiple goroutines
-// and maintains its own pool of idle connections. Thus, the OpenDB
-// function should be called just once. It is rarely necessary to
-// close a DB.
-func OpenDB(c driver.Connector) *DB {
- ctx, cancel := context.WithCancel(context.Background())
- db := &DB{
- connector: c,
- openerCh: make(chan struct{}, connectionRequestQueueSize),
- lastPut: make(map[*driverConn]string),
- connRequests: make(map[uint64]chan connRequest),
- stop: cancel,
- }
-
- go db.connectionOpener(ctx)
-
- return db
-}
-
-// Open opens a database specified by its database driver name and a
-// driver-specific data source name, usually consisting of at least a
-// database name and connection information.
-//
-// Most users will open a database via a driver-specific connection
-// helper function that returns a *DB. No database drivers are included
-// in the Go standard library. See https://golang.org/s/sqldrivers for
-// a list of third-party drivers.
-//
-// Open may just validate its arguments without creating a connection
-// to the database. To verify that the data source name is valid, call
-// Ping.
-//
-// The returned DB is safe for concurrent use by multiple goroutines
-// and maintains its own pool of idle connections. Thus, the Open
-// function should be called just once. It is rarely necessary to
-// close a DB.
-func Open(driverName, dataSourceName string) (*DB, error) {
- driversMu.RLock()
- driveri, ok := drivers[driverName]
- driversMu.RUnlock()
- if !ok {
- return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
- }
-
- if driverCtx, ok := driveri.(driver.DriverContext); ok {
- connector, err := driverCtx.OpenConnector(dataSourceName)
- if err != nil {
- return nil, err
- }
- return OpenDB(connector), nil
- }
-
- return OpenDB(dsnConnector{dsn: dataSourceName, driver: driveri}), nil
-}
-
-func (db *DB) pingDC(ctx context.Context, dc *driverConn, release func(error)) error {
- var err error
- if pinger, ok := dc.ci.(driver.Pinger); ok {
- withLock(dc, func() {
- err = pinger.Ping(ctx)
- })
- }
- release(err)
- return err
-}
-
-// PingContext verifies a connection to the database is still alive,
-// establishing a connection if necessary.
-func (db *DB) PingContext(ctx context.Context) error {
- var dc *driverConn
- var err error
-
- err = db.retry(func(strategy connReuseStrategy) error {
- dc, err = db.conn(ctx, strategy)
- return err
- })
-
- if err != nil {
- return err
- }
-
- return db.pingDC(ctx, dc, dc.releaseConn)
-}
-
-// Ping verifies a connection to the database is still alive,
-// establishing a connection if necessary.
-//
-// Ping uses context.Background internally; to specify the context, use
-// PingContext.
-func (db *DB) Ping() error {
- return db.PingContext(context.Background())
-}
-
-// Close closes the database and prevents new queries from starting.
-// Close then waits for all queries that have started processing on the server
-// to finish.
-//
-// It is rare to Close a DB, as the DB handle is meant to be
-// long-lived and shared between many goroutines.
-func (db *DB) Close() error {
- db.mu.Lock()
- if db.closed { // Make DB.Close idempotent
- db.mu.Unlock()
- return nil
- }
- if db.cleanerCh != nil {
- close(db.cleanerCh)
- }
- var err error
- fns := make([]func() error, 0, len(db.freeConn))
- for _, dc := range db.freeConn {
- fns = append(fns, dc.closeDBLocked())
- }
- db.freeConn = nil
- db.closed = true
- for _, req := range db.connRequests {
- close(req)
- }
- db.mu.Unlock()
- for _, fn := range fns {
- err1 := fn()
- if err1 != nil {
- err = err1
- }
- }
- db.stop()
- if c, ok := db.connector.(io.Closer); ok {
- err1 := c.Close()
- if err1 != nil {
- err = err1
- }
- }
- return err
-}
-
-const defaultMaxIdleConns = 2
-
-func (db *DB) maxIdleConnsLocked() int {
- n := db.maxIdleCount
- switch {
- case n == 0:
- // TODO(bradfitz): ask driver, if supported, for its default preference
- return defaultMaxIdleConns
- case n < 0:
- return 0
- default:
- return n
- }
-}
-
-func (db *DB) shortestIdleTimeLocked() time.Duration {
- if db.maxIdleTime <= 0 {
- return db.maxLifetime
- }
- if db.maxLifetime <= 0 {
- return db.maxIdleTime
- }
-
- min := db.maxIdleTime
- if min > db.maxLifetime {
- min = db.maxLifetime
- }
- return min
-}
-
-// SetMaxIdleConns sets the maximum number of connections in the idle
-// connection pool.
-//
-// If MaxOpenConns is greater than 0 but less than the new MaxIdleConns,
-// then the new MaxIdleConns will be reduced to match the MaxOpenConns limit.
-//
-// If n <= 0, no idle connections are retained.
-//
-// The default max idle connections is currently 2. This may change in
-// a future release.
-func (db *DB) SetMaxIdleConns(n int) {
- db.mu.Lock()
- if n > 0 {
- db.maxIdleCount = n
- } else {
- // No idle connections.
- db.maxIdleCount = -1
- }
- // Make sure maxIdle doesn't exceed maxOpen
- if db.maxOpen > 0 && db.maxIdleConnsLocked() > db.maxOpen {
- db.maxIdleCount = db.maxOpen
- }
- var closing []*driverConn
- idleCount := len(db.freeConn)
- maxIdle := db.maxIdleConnsLocked()
- if idleCount > maxIdle {
- closing = db.freeConn[maxIdle:]
- db.freeConn = db.freeConn[:maxIdle]
- }
- db.maxIdleClosed += int64(len(closing))
- db.mu.Unlock()
- for _, c := range closing {
- c.Close()
- }
-}
-
-// SetMaxOpenConns sets the maximum number of open connections to the database.
-//
-// If MaxIdleConns is greater than 0 and the new MaxOpenConns is less than
-// MaxIdleConns, then MaxIdleConns will be reduced to match the new
-// MaxOpenConns limit.
-//
-// If n <= 0, then there is no limit on the number of open connections.
-// The default is 0 (unlimited).
-func (db *DB) SetMaxOpenConns(n int) {
- db.mu.Lock()
- db.maxOpen = n
- if n < 0 {
- db.maxOpen = 0
- }
- syncMaxIdle := db.maxOpen > 0 && db.maxIdleConnsLocked() > db.maxOpen
- db.mu.Unlock()
- if syncMaxIdle {
- db.SetMaxIdleConns(n)
- }
-}
-
-// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
-//
-// Expired connections may be closed lazily before reuse.
-//
-// If d <= 0, connections are not closed due to a connection's age.
-func (db *DB) SetConnMaxLifetime(d time.Duration) {
- if d < 0 {
- d = 0
- }
- db.mu.Lock()
- // Wake cleaner up when lifetime is shortened.
- if d > 0 && d < db.maxLifetime && db.cleanerCh != nil {
- select {
- case db.cleanerCh <- struct{}{}:
- default:
- }
- }
- db.maxLifetime = d
- db.startCleanerLocked()
- db.mu.Unlock()
-}
-
-// SetConnMaxIdleTime sets the maximum amount of time a connection may be idle.
-//
-// Expired connections may be closed lazily before reuse.
-//
-// If d <= 0, connections are not closed due to a connection's idle time.
-func (db *DB) SetConnMaxIdleTime(d time.Duration) {
- if d < 0 {
- d = 0
- }
- db.mu.Lock()
- defer db.mu.Unlock()
-
- // Wake cleaner up when idle time is shortened.
- if d > 0 && d < db.maxIdleTime && db.cleanerCh != nil {
- select {
- case db.cleanerCh <- struct{}{}:
- default:
- }
- }
- db.maxIdleTime = d
- db.startCleanerLocked()
-}
-
-// startCleanerLocked starts connectionCleaner if needed.
-func (db *DB) startCleanerLocked() {
- if (db.maxLifetime > 0 || db.maxIdleTime > 0) && db.numOpen > 0 && db.cleanerCh == nil {
- db.cleanerCh = make(chan struct{}, 1)
- go db.connectionCleaner(db.shortestIdleTimeLocked())
- }
-}
-
-func (db *DB) connectionCleaner(d time.Duration) {
- const minInterval = time.Second
-
- if d < minInterval {
- d = minInterval
- }
- t := time.NewTimer(d)
-
- for {
- select {
- case <-t.C:
- case <-db.cleanerCh: // maxLifetime was changed or db was closed.
- }
-
- db.mu.Lock()
-
- d = db.shortestIdleTimeLocked()
- if db.closed || db.numOpen == 0 || d <= 0 {
- db.cleanerCh = nil
- db.mu.Unlock()
- return
- }
-
- d, closing := db.connectionCleanerRunLocked(d)
- db.mu.Unlock()
- for _, c := range closing {
- c.Close()
- }
-
- if d < minInterval {
- d = minInterval
- }
-
- if !t.Stop() {
- select {
- case <-t.C:
- default:
- }
- }
- t.Reset(d)
- }
-}
-
-// connectionCleanerRunLocked removes connections that should be closed from
-// freeConn and returns them along side an updated duration to the next check
-// if a quicker check is required to ensure connections are checked appropriately.
-func (db *DB) connectionCleanerRunLocked(d time.Duration) (time.Duration, []*driverConn) {
- var idleClosing int64
- var closing []*driverConn
- if db.maxIdleTime > 0 {
- // As freeConn is ordered by returnedAt process
- // in reverse order to minimise the work needed.
- idleSince := nowFunc().Add(-db.maxIdleTime)
- last := len(db.freeConn) - 1
- for i := last; i >= 0; i-- {
- c := db.freeConn[i]
- if c.returnedAt.Before(idleSince) {
- i++
- closing = db.freeConn[:i:i]
- db.freeConn = db.freeConn[i:]
- idleClosing = int64(len(closing))
- db.maxIdleTimeClosed += idleClosing
- break
- }
- }
-
- if len(db.freeConn) > 0 {
- c := db.freeConn[0]
- if d2 := c.returnedAt.Sub(idleSince); d2 < d {
- // Ensure idle connections are cleaned up as soon as
- // possible.
- d = d2
- }
- }
- }
-
- if db.maxLifetime > 0 {
- expiredSince := nowFunc().Add(-db.maxLifetime)
- for i := 0; i < len(db.freeConn); i++ {
- c := db.freeConn[i]
- if c.createdAt.Before(expiredSince) {
- closing = append(closing, c)
-
- last := len(db.freeConn) - 1
- // Use slow delete as order is required to ensure
- // connections are reused least idle time first.
- copy(db.freeConn[i:], db.freeConn[i+1:])
- db.freeConn[last] = nil
- db.freeConn = db.freeConn[:last]
- i--
- } else if d2 := c.createdAt.Sub(expiredSince); d2 < d {
- // Prevent connections sitting the freeConn when they
- // have expired by updating our next deadline d.
- d = d2
- }
- }
- db.maxLifetimeClosed += int64(len(closing)) - idleClosing
- }
-
- return d, closing
-}
-
-// DBStats contains database statistics.
-type DBStats struct {
- MaxOpenConnections int // Maximum number of open connections to the database.
-
- // Pool Status
- OpenConnections int // The number of established connections both in use and idle.
- InUse int // The number of connections currently in use.
- Idle int // The number of idle connections.
-
- // Counters
- WaitCount int64 // The total number of connections waited for.
- WaitDuration time.Duration // The total time blocked waiting for a new connection.
- MaxIdleClosed int64 // The total number of connections closed due to SetMaxIdleConns.
- MaxIdleTimeClosed int64 // The total number of connections closed due to SetConnMaxIdleTime.
- MaxLifetimeClosed int64 // The total number of connections closed due to SetConnMaxLifetime.
-}
-
-// Stats returns database statistics.
-func (db *DB) Stats() DBStats {
- wait := db.waitDuration.Load()
-
- db.mu.Lock()
- defer db.mu.Unlock()
-
- stats := DBStats{
- MaxOpenConnections: db.maxOpen,
-
- Idle: len(db.freeConn),
- OpenConnections: db.numOpen,
- InUse: db.numOpen - len(db.freeConn),
-
- WaitCount: db.waitCount,
- WaitDuration: time.Duration(wait),
- MaxIdleClosed: db.maxIdleClosed,
- MaxIdleTimeClosed: db.maxIdleTimeClosed,
- MaxLifetimeClosed: db.maxLifetimeClosed,
- }
- return stats
-}
-
-// Assumes db.mu is locked.
-// If there are connRequests and the connection limit hasn't been reached,
-// then tell the connectionOpener to open new connections.
-func (db *DB) maybeOpenNewConnections() {
- numRequests := len(db.connRequests)
- if db.maxOpen > 0 {
- numCanOpen := db.maxOpen - db.numOpen
- if numRequests > numCanOpen {
- numRequests = numCanOpen
- }
- }
- for numRequests > 0 {
- db.numOpen++ // optimistically
- numRequests--
- if db.closed {
- return
- }
- db.openerCh <- struct{}{}
- }
-}
-
-// Runs in a separate goroutine, opens new connections when requested.
-func (db *DB) connectionOpener(ctx context.Context) {
- for {
- select {
- case <-ctx.Done():
- return
- case <-db.openerCh:
- db.openNewConnection(ctx)
- }
- }
-}
-
-// Open one new connection
-func (db *DB) openNewConnection(ctx context.Context) {
- // maybeOpenNewConnections has already executed db.numOpen++ before it sent
- // on db.openerCh. This function must execute db.numOpen-- if the
- // connection fails or is closed before returning.
- ci, err := db.connector.Connect(ctx)
- db.mu.Lock()
- defer db.mu.Unlock()
- if db.closed {
- if err == nil {
- ci.Close()
- }
- db.numOpen--
- return
- }
- if err != nil {
- db.numOpen--
- db.putConnDBLocked(nil, err)
- db.maybeOpenNewConnections()
- return
- }
- dc := &driverConn{
- db: db,
- createdAt: nowFunc(),
- returnedAt: nowFunc(),
- ci: ci,
- }
- if db.putConnDBLocked(dc, err) {
- db.addDepLocked(dc, dc)
- } else {
- db.numOpen--
- ci.Close()
- }
-}
-
-// connRequest represents one request for a new connection
-// When there are no idle connections available, DB.conn will create
-// a new connRequest and put it on the db.connRequests list.
-type connRequest struct {
- conn *driverConn
- err error
-}
-
-var errDBClosed = errors.New("sql: database is closed")
-
-// nextRequestKeyLocked returns the next connection request key.
-// It is assumed that nextRequest will not overflow.
-func (db *DB) nextRequestKeyLocked() uint64 {
- next := db.nextRequest
- db.nextRequest++
- return next
-}
-
-// conn returns a newly-opened or cached *driverConn.
-func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn, error) {
- db.mu.Lock()
- if db.closed {
- db.mu.Unlock()
- return nil, errDBClosed
- }
- // Check if the context is expired.
- select {
- default:
- case <-ctx.Done():
- db.mu.Unlock()
- return nil, ctx.Err()
- }
- lifetime := db.maxLifetime
-
- // Prefer a free connection, if possible.
- last := len(db.freeConn) - 1
- if strategy == cachedOrNewConn && last >= 0 {
- // Reuse the lowest idle time connection so we can close
- // connections which remain idle as soon as possible.
- conn := db.freeConn[last]
- db.freeConn = db.freeConn[:last]
- conn.inUse = true
- if conn.expired(lifetime) {
- db.maxLifetimeClosed++
- db.mu.Unlock()
- conn.Close()
- return nil, driver.ErrBadConn
- }
- db.mu.Unlock()
-
- // Reset the session if required.
- if err := conn.resetSession(ctx); errors.Is(err, driver.ErrBadConn) {
- conn.Close()
- return nil, err
- }
-
- return conn, nil
- }
-
- // Out of free connections or we were asked not to use one. If we're not
- // allowed to open any more connections, make a request and wait.
- if db.maxOpen > 0 && db.numOpen >= db.maxOpen {
- // Make the connRequest channel. It's buffered so that the
- // connectionOpener doesn't block while waiting for the req to be read.
- req := make(chan connRequest, 1)
- reqKey := db.nextRequestKeyLocked()
- db.connRequests[reqKey] = req
- db.waitCount++
- db.mu.Unlock()
-
- waitStart := nowFunc()
-
- // Timeout the connection request with the context.
- select {
- case <-ctx.Done():
- // Remove the connection request and ensure no value has been sent
- // on it after removing.
- db.mu.Lock()
- delete(db.connRequests, reqKey)
- db.mu.Unlock()
-
- db.waitDuration.Add(int64(time.Since(waitStart)))
-
- select {
- default:
- case ret, ok := <-req:
- if ok && ret.conn != nil {
- db.putConn(ret.conn, ret.err, false)
- }
- }
- return nil, ctx.Err()
- case ret, ok := <-req:
- db.waitDuration.Add(int64(time.Since(waitStart)))
-
- if !ok {
- return nil, errDBClosed
- }
- // Only check if the connection is expired if the strategy is cachedOrNewConns.
- // If we require a new connection, just re-use the connection without looking
- // at the expiry time. If it is expired, it will be checked when it is placed
- // back into the connection pool.
- // This prioritizes giving a valid connection to a client over the exact connection
- // lifetime, which could expire exactly after this point anyway.
- if strategy == cachedOrNewConn && ret.err == nil && ret.conn.expired(lifetime) {
- db.mu.Lock()
- db.maxLifetimeClosed++
- db.mu.Unlock()
- ret.conn.Close()
- return nil, driver.ErrBadConn
- }
- if ret.conn == nil {
- return nil, ret.err
- }
-
- // Reset the session if required.
- if err := ret.conn.resetSession(ctx); errors.Is(err, driver.ErrBadConn) {
- ret.conn.Close()
- return nil, err
- }
- return ret.conn, ret.err
- }
- }
-
- db.numOpen++ // optimistically
- db.mu.Unlock()
- ci, err := db.connector.Connect(ctx)
- if err != nil {
- db.mu.Lock()
- db.numOpen-- // correct for earlier optimism
- db.maybeOpenNewConnections()
- db.mu.Unlock()
- return nil, err
- }
- db.mu.Lock()
- dc := &driverConn{
- db: db,
- createdAt: nowFunc(),
- returnedAt: nowFunc(),
- ci: ci,
- inUse: true,
- }
- db.addDepLocked(dc, dc)
- db.mu.Unlock()
- return dc, nil
-}
-
-// putConnHook is a hook for testing.
-var putConnHook func(*DB, *driverConn)
-
-// noteUnusedDriverStatement notes that ds is no longer used and should
-// be closed whenever possible (when c is next not in use), unless c is
-// already closed.
-func (db *DB) noteUnusedDriverStatement(c *driverConn, ds *driverStmt) {
- db.mu.Lock()
- defer db.mu.Unlock()
- if c.inUse {
- c.onPut = append(c.onPut, func() {
- ds.Close()
- })
- } else {
- c.Lock()
- fc := c.finalClosed
- c.Unlock()
- if !fc {
- ds.Close()
- }
- }
-}
-
-// debugGetPut determines whether getConn & putConn calls' stack traces
-// are returned for more verbose crashes.
-const debugGetPut = false
-
-// putConn adds a connection to the db's free pool.
-// err is optionally the last error that occurred on this connection.
-func (db *DB) putConn(dc *driverConn, err error, resetSession bool) {
- if !errors.Is(err, driver.ErrBadConn) {
- if !dc.validateConnection(resetSession) {
- err = driver.ErrBadConn
- }
- }
- db.mu.Lock()
- if !dc.inUse {
- db.mu.Unlock()
- if debugGetPut {
- fmt.Printf("putConn(%v) DUPLICATE was: %s\n\nPREVIOUS was: %s", dc, stack(), db.lastPut[dc])
- }
- panic("sql: connection returned that was never out")
- }
-
- if !errors.Is(err, driver.ErrBadConn) && dc.expired(db.maxLifetime) {
- db.maxLifetimeClosed++
- err = driver.ErrBadConn
- }
- if debugGetPut {
- db.lastPut[dc] = stack()
- }
- dc.inUse = false
- dc.returnedAt = nowFunc()
-
- for _, fn := range dc.onPut {
- fn()
- }
- dc.onPut = nil
-
- if errors.Is(err, driver.ErrBadConn) {
- // Don't reuse bad connections.
- // Since the conn is considered bad and is being discarded, treat it
- // as closed. Don't decrement the open count here, finalClose will
- // take care of that.
- db.maybeOpenNewConnections()
- db.mu.Unlock()
- dc.Close()
- return
- }
- if putConnHook != nil {
- putConnHook(db, dc)
- }
- added := db.putConnDBLocked(dc, nil)
- db.mu.Unlock()
-
- if !added {
- dc.Close()
- return
- }
-}
-
-// Satisfy a connRequest or put the driverConn in the idle pool and return true
-// or return false.
-// putConnDBLocked will satisfy a connRequest if there is one, or it will
-// return the *driverConn to the freeConn list if err == nil and the idle
-// connection limit will not be exceeded.
-// If err != nil, the value of dc is ignored.
-// If err == nil, then dc must not equal nil.
-// If a connRequest was fulfilled or the *driverConn was placed in the
-// freeConn list, then true is returned, otherwise false is returned.
-func (db *DB) putConnDBLocked(dc *driverConn, err error) bool {
- if db.closed {
- return false
- }
- if db.maxOpen > 0 && db.numOpen > db.maxOpen {
- return false
- }
- if c := len(db.connRequests); c > 0 {
- var req chan connRequest
- var reqKey uint64
- for reqKey, req = range db.connRequests {
- break
- }
- delete(db.connRequests, reqKey) // Remove from pending requests.
- if err == nil {
- dc.inUse = true
- }
- req <- connRequest{
- conn: dc,
- err: err,
- }
- return true
- } else if err == nil && !db.closed {
- if db.maxIdleConnsLocked() > len(db.freeConn) {
- db.freeConn = append(db.freeConn, dc)
- db.startCleanerLocked()
- return true
- }
- db.maxIdleClosed++
- }
- return false
-}
-
-// maxBadConnRetries is the number of maximum retries if the driver returns
-// driver.ErrBadConn to signal a broken connection before forcing a new
-// connection to be opened.
-const maxBadConnRetries = 2
-
-func (db *DB) retry(fn func(strategy connReuseStrategy) error) error {
- for i := int64(0); i < maxBadConnRetries; i++ {
- err := fn(cachedOrNewConn)
- // retry if err is driver.ErrBadConn
- if err == nil || !errors.Is(err, driver.ErrBadConn) {
- return err
- }
- }
-
- return fn(alwaysNewConn)
-}
-
-// PrepareContext creates a prepared statement for later queries or executions.
-// Multiple queries or executions may be run concurrently from the
-// returned statement.
-// The caller must call the statement's Close method
-// when the statement is no longer needed.
-//
-// The provided context is used for the preparation of the statement, not for the
-// execution of the statement.
-func (db *DB) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
- var stmt *Stmt
- var err error
-
- err = db.retry(func(strategy connReuseStrategy) error {
- stmt, err = db.prepare(ctx, query, strategy)
- return err
- })
-
- return stmt, err
-}
-
-// Prepare creates a prepared statement for later queries or executions.
-// Multiple queries or executions may be run concurrently from the
-// returned statement.
-// The caller must call the statement's Close method
-// when the statement is no longer needed.
-//
-// Prepare uses context.Background internally; to specify the context, use
-// PrepareContext.
-func (db *DB) Prepare(query string) (*Stmt, error) {
- return db.PrepareContext(context.Background(), query)
-}
-
-func (db *DB) prepare(ctx context.Context, query string, strategy connReuseStrategy) (*Stmt, error) {
- // TODO: check if db.driver supports an optional
- // driver.Preparer interface and call that instead, if so,
- // otherwise we make a prepared statement that's bound
- // to a connection, and to execute this prepared statement
- // we either need to use this connection (if it's free), else
- // get a new connection + re-prepare + execute on that one.
- dc, err := db.conn(ctx, strategy)
- if err != nil {
- return nil, err
- }
- return db.prepareDC(ctx, dc, dc.releaseConn, nil, query)
-}
-
-// prepareDC prepares a query on the driverConn and calls release before
-// returning. When cg == nil it implies that a connection pool is used, and
-// when cg != nil only a single driver connection is used.
-func (db *DB) prepareDC(ctx context.Context, dc *driverConn, release func(error), cg stmtConnGrabber, query string) (*Stmt, error) {
- var ds *driverStmt
- var err error
- defer func() {
- release(err)
- }()
- withLock(dc, func() {
- ds, err = dc.prepareLocked(ctx, cg, query)
- })
- if err != nil {
- return nil, err
- }
- stmt := &Stmt{
- db: db,
- query: query,
- cg: cg,
- cgds: ds,
- }
-
- // When cg == nil this statement will need to keep track of various
- // connections they are prepared on and record the stmt dependency on
- // the DB.
- if cg == nil {
- stmt.css = []connStmt{{dc, ds}}
- stmt.lastNumClosed = db.numClosed.Load()
- db.addDep(stmt, stmt)
- }
- return stmt, nil
-}
-
-// ExecContext executes a query without returning any rows.
-// The args are for any placeholder parameters in the query.
-func (db *DB) ExecContext(ctx context.Context, query string, args ...any) (Result, error) {
- var res Result
- var err error
-
- err = db.retry(func(strategy connReuseStrategy) error {
- res, err = db.exec(ctx, query, args, strategy)
- return err
- })
-
- return res, err
-}
-
-// Exec executes a query without returning any rows.
-// The args are for any placeholder parameters in the query.
-//
-// Exec uses context.Background internally; to specify the context, use
-// ExecContext.
-func (db *DB) Exec(query string, args ...any) (Result, error) {
- return db.ExecContext(context.Background(), query, args...)
-}
-
-func (db *DB) exec(ctx context.Context, query string, args []any, strategy connReuseStrategy) (Result, error) {
- dc, err := db.conn(ctx, strategy)
- if err != nil {
- return nil, err
- }
- return db.execDC(ctx, dc, dc.releaseConn, query, args)
-}
-
-func (db *DB) execDC(ctx context.Context, dc *driverConn, release func(error), query string, args []any) (res Result, err error) {
- defer func() {
- release(err)
- }()
- execerCtx, ok := dc.ci.(driver.ExecerContext)
- var execer driver.Execer
- if !ok {
- execer, ok = dc.ci.(driver.Execer)
- }
- if ok {
- var nvdargs []driver.NamedValue
- var resi driver.Result
- withLock(dc, func() {
- nvdargs, err = driverArgsConnLocked(dc.ci, nil, args)
- if err != nil {
- return
- }
- resi, err = ctxDriverExec(ctx, execerCtx, execer, query, nvdargs)
- })
- if err != driver.ErrSkip {
- if err != nil {
- return nil, err
- }
- return driverResult{dc, resi}, nil
- }
- }
-
- var si driver.Stmt
- withLock(dc, func() {
- si, err = ctxDriverPrepare(ctx, dc.ci, query)
- })
- if err != nil {
- return nil, err
- }
- ds := &driverStmt{Locker: dc, si: si}
- defer ds.Close()
- return resultFromStatement(ctx, dc.ci, ds, args...)
-}
-
-// QueryContext executes a query that returns rows, typically a SELECT.
-// The args are for any placeholder parameters in the query.
-func (db *DB) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error) {
- var rows *Rows
- var err error
-
- err = db.retry(func(strategy connReuseStrategy) error {
- rows, err = db.query(ctx, query, args, strategy)
- return err
- })
-
- return rows, err
-}
-
-// Query executes a query that returns rows, typically a SELECT.
-// The args are for any placeholder parameters in the query.
-//
-// Query uses context.Background internally; to specify the context, use
-// QueryContext.
-func (db *DB) Query(query string, args ...any) (*Rows, error) {
- return db.QueryContext(context.Background(), query, args...)
-}
-
-func (db *DB) query(ctx context.Context, query string, args []any, strategy connReuseStrategy) (*Rows, error) {
- dc, err := db.conn(ctx, strategy)
- if err != nil {
- return nil, err
- }
-
- return db.queryDC(ctx, nil, dc, dc.releaseConn, query, args)
-}
-
-// queryDC executes a query on the given connection.
-// The connection gets released by the releaseConn function.
-// The ctx context is from a query method and the txctx context is from an
-// optional transaction context.
-func (db *DB) queryDC(ctx, txctx context.Context, dc *driverConn, releaseConn func(error), query string, args []any) (*Rows, error) {
- queryerCtx, ok := dc.ci.(driver.QueryerContext)
- var queryer driver.Queryer
- if !ok {
- queryer, ok = dc.ci.(driver.Queryer)
- }
- if ok {
- var nvdargs []driver.NamedValue
- var rowsi driver.Rows
- var err error
- withLock(dc, func() {
- nvdargs, err = driverArgsConnLocked(dc.ci, nil, args)
- if err != nil {
- return
- }
- rowsi, err = ctxDriverQuery(ctx, queryerCtx, queryer, query, nvdargs)
- })
- if err != driver.ErrSkip {
- if err != nil {
- releaseConn(err)
- return nil, err
- }
- // Note: ownership of dc passes to the *Rows, to be freed
- // with releaseConn.
- rows := &Rows{
- dc: dc,
- releaseConn: releaseConn,
- rowsi: rowsi,
- }
- rows.initContextClose(ctx, txctx)
- return rows, nil
- }
- }
-
- var si driver.Stmt
- var err error
- withLock(dc, func() {
- si, err = ctxDriverPrepare(ctx, dc.ci, query)
- })
- if err != nil {
- releaseConn(err)
- return nil, err
- }
-
- ds := &driverStmt{Locker: dc, si: si}
- rowsi, err := rowsiFromStatement(ctx, dc.ci, ds, args...)
- if err != nil {
- ds.Close()
- releaseConn(err)
- return nil, err
- }
-
- // Note: ownership of ci passes to the *Rows, to be freed
- // with releaseConn.
- rows := &Rows{
- dc: dc,
- releaseConn: releaseConn,
- rowsi: rowsi,
- closeStmt: ds,
- }
- rows.initContextClose(ctx, txctx)
- return rows, nil
-}
-
-// QueryRowContext executes a query that is expected to return at most one row.
-// QueryRowContext always returns a non-nil value. Errors are deferred until
-// Row's Scan method is called.
-// If the query selects no rows, the *Row's Scan will return ErrNoRows.
-// Otherwise, the *Row's Scan scans the first selected row and discards
-// the rest.
-func (db *DB) QueryRowContext(ctx context.Context, query string, args ...any) *Row {
- rows, err := db.QueryContext(ctx, query, args...)
- return &Row{rows: rows, err: err}
-}
-
-// QueryRow executes a query that is expected to return at most one row.
-// QueryRow always returns a non-nil value. Errors are deferred until
-// Row's Scan method is called.
-// If the query selects no rows, the *Row's Scan will return ErrNoRows.
-// Otherwise, the *Row's Scan scans the first selected row and discards
-// the rest.
-//
-// QueryRow uses context.Background internally; to specify the context, use
-// QueryRowContext.
-func (db *DB) QueryRow(query string, args ...any) *Row {
- return db.QueryRowContext(context.Background(), query, args...)
-}
-
-// BeginTx starts a transaction.
-//
-// The provided context is used until the transaction is committed or rolled back.
-// If the context is canceled, the sql package will roll back
-// the transaction. Tx.Commit will return an error if the context provided to
-// BeginTx is canceled.
-//
-// The provided TxOptions is optional and may be nil if defaults should be used.
-// If a non-default isolation level is used that the driver doesn't support,
-// an error will be returned.
-func (db *DB) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error) {
- var tx *Tx
- var err error
-
- err = db.retry(func(strategy connReuseStrategy) error {
- tx, err = db.begin(ctx, opts, strategy)
- return err
- })
-
- return tx, err
-}
-
-// Begin starts a transaction. The default isolation level is dependent on
-// the driver.
-//
-// Begin uses context.Background internally; to specify the context, use
-// BeginTx.
-func (db *DB) Begin() (*Tx, error) {
- return db.BeginTx(context.Background(), nil)
-}
-
-func (db *DB) begin(ctx context.Context, opts *TxOptions, strategy connReuseStrategy) (tx *Tx, err error) {
- dc, err := db.conn(ctx, strategy)
- if err != nil {
- return nil, err
- }
- return db.beginDC(ctx, dc, dc.releaseConn, opts)
-}
-
-// beginDC starts a transaction. The provided dc must be valid and ready to use.
-func (db *DB) beginDC(ctx context.Context, dc *driverConn, release func(error), opts *TxOptions) (tx *Tx, err error) {
- var txi driver.Tx
- keepConnOnRollback := false
- withLock(dc, func() {
- _, hasSessionResetter := dc.ci.(driver.SessionResetter)
- _, hasConnectionValidator := dc.ci.(driver.Validator)
- keepConnOnRollback = hasSessionResetter && hasConnectionValidator
- txi, err = ctxDriverBegin(ctx, opts, dc.ci)
- })
- if err != nil {
- release(err)
- return nil, err
- }
-
- // Schedule the transaction to rollback when the context is canceled.
- // The cancel function in Tx will be called after done is set to true.
- ctx, cancel := context.WithCancel(ctx)
- tx = &Tx{
- db: db,
- dc: dc,
- releaseConn: release,
- txi: txi,
- cancel: cancel,
- keepConnOnRollback: keepConnOnRollback,
- ctx: ctx,
- }
- go tx.awaitDone()
- return tx, nil
-}
-
-// Driver returns the database's underlying driver.
-func (db *DB) Driver() driver.Driver {
- return db.connector.Driver()
-}
-
-// ErrConnDone is returned by any operation that is performed on a connection
-// that has already been returned to the connection pool.
-var ErrConnDone = errors.New("sql: connection is already closed")
-
-// Conn returns a single connection by either opening a new connection
-// or returning an existing connection from the connection pool. Conn will
-// block until either a connection is returned or ctx is canceled.
-// Queries run on the same Conn will be run in the same database session.
-//
-// Every Conn must be returned to the database pool after use by
-// calling Conn.Close.
-func (db *DB) Conn(ctx context.Context) (*Conn, error) {
- var dc *driverConn
- var err error
-
- err = db.retry(func(strategy connReuseStrategy) error {
- dc, err = db.conn(ctx, strategy)
- return err
- })
-
- if err != nil {
- return nil, err
- }
-
- conn := &Conn{
- db: db,
- dc: dc,
- }
- return conn, nil
-}
-
-type releaseConn func(error)
-
-// Conn represents a single database connection rather than a pool of database
-// connections. Prefer running queries from DB unless there is a specific
-// need for a continuous single database connection.
-//
-// A Conn must call Close to return the connection to the database pool
-// and may do so concurrently with a running query.
-//
-// After a call to Close, all operations on the
-// connection fail with ErrConnDone.
-type Conn struct {
- db *DB
-
- // closemu prevents the connection from closing while there
- // is an active query. It is held for read during queries
- // and exclusively during close.
- closemu sync.RWMutex
-
- // dc is owned until close, at which point
- // it's returned to the connection pool.
- dc *driverConn
-
- // done transitions from 0 to 1 exactly once, on close.
- // Once done, all operations fail with ErrConnDone.
- // Use atomic operations on value when checking value.
- done int32
-}
-
-// grabConn takes a context to implement stmtConnGrabber
-// but the context is not used.
-func (c *Conn) grabConn(context.Context) (*driverConn, releaseConn, error) {
- if atomic.LoadInt32(&c.done) != 0 {
- return nil, nil, ErrConnDone
- }
- c.closemu.RLock()
- return c.dc, c.closemuRUnlockCondReleaseConn, nil
-}
-
-// PingContext verifies the connection to the database is still alive.
-func (c *Conn) PingContext(ctx context.Context) error {
- dc, release, err := c.grabConn(ctx)
- if err != nil {
- return err
- }
- return c.db.pingDC(ctx, dc, release)
-}
-
-// ExecContext executes a query without returning any rows.
-// The args are for any placeholder parameters in the query.
-func (c *Conn) ExecContext(ctx context.Context, query string, args ...any) (Result, error) {
- dc, release, err := c.grabConn(ctx)
- if err != nil {
- return nil, err
- }
- return c.db.execDC(ctx, dc, release, query, args)
-}
-
-// QueryContext executes a query that returns rows, typically a SELECT.
-// The args are for any placeholder parameters in the query.
-func (c *Conn) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error) {
- dc, release, err := c.grabConn(ctx)
- if err != nil {
- return nil, err
- }
- return c.db.queryDC(ctx, nil, dc, release, query, args)
-}
-
-// QueryRowContext executes a query that is expected to return at most one row.
-// QueryRowContext always returns a non-nil value. Errors are deferred until
-// Row's Scan method is called.
-// If the query selects no rows, the *Row's Scan will return ErrNoRows.
-// Otherwise, the *Row's Scan scans the first selected row and discards
-// the rest.
-func (c *Conn) QueryRowContext(ctx context.Context, query string, args ...any) *Row {
- rows, err := c.QueryContext(ctx, query, args...)
- return &Row{rows: rows, err: err}
-}
-
-// PrepareContext creates a prepared statement for later queries or executions.
-// Multiple queries or executions may be run concurrently from the
-// returned statement.
-// The caller must call the statement's Close method
-// when the statement is no longer needed.
-//
-// The provided context is used for the preparation of the statement, not for the
-// execution of the statement.
-func (c *Conn) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
- dc, release, err := c.grabConn(ctx)
- if err != nil {
- return nil, err
- }
- return c.db.prepareDC(ctx, dc, release, c, query)
-}
-
-// Raw executes f exposing the underlying driver connection for the
-// duration of f. The driverConn must not be used outside of f.
-//
-// Once f returns and err is not driver.ErrBadConn, the Conn will continue to be usable
-// until Conn.Close is called.
-func (c *Conn) Raw(f func(driverConn any) error) (err error) {
- var dc *driverConn
- var release releaseConn
-
- // grabConn takes a context to implement stmtConnGrabber, but the context is not used.
- dc, release, err = c.grabConn(nil)
- if err != nil {
- return
- }
- fPanic := true
- dc.Mutex.Lock()
- defer func() {
- dc.Mutex.Unlock()
-
- // If f panics fPanic will remain true.
- // Ensure an error is passed to release so the connection
- // may be discarded.
- if fPanic {
- err = driver.ErrBadConn
- }
- release(err)
- }()
- err = f(dc.ci)
- fPanic = false
-
- return
-}
-
-// BeginTx starts a transaction.
-//
-// The provided context is used until the transaction is committed or rolled back.
-// If the context is canceled, the sql package will roll back
-// the transaction. Tx.Commit will return an error if the context provided to
-// BeginTx is canceled.
-//
-// The provided TxOptions is optional and may be nil if defaults should be used.
-// If a non-default isolation level is used that the driver doesn't support,
-// an error will be returned.
-func (c *Conn) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error) {
- dc, release, err := c.grabConn(ctx)
- if err != nil {
- return nil, err
- }
- return c.db.beginDC(ctx, dc, release, opts)
-}
-
-// closemuRUnlockCondReleaseConn read unlocks closemu
-// as the sql operation is done with the dc.
-func (c *Conn) closemuRUnlockCondReleaseConn(err error) {
- c.closemu.RUnlock()
- if errors.Is(err, driver.ErrBadConn) {
- c.close(err)
- }
-}
-
-func (c *Conn) txCtx() context.Context {
- return nil
-}
-
-func (c *Conn) close(err error) error {
- if !atomic.CompareAndSwapInt32(&c.done, 0, 1) {
- return ErrConnDone
- }
-
- // Lock around releasing the driver connection
- // to ensure all queries have been stopped before doing so.
- c.closemu.Lock()
- defer c.closemu.Unlock()
-
- c.dc.releaseConn(err)
- c.dc = nil
- c.db = nil
- return err
-}
-
-// Close returns the connection to the connection pool.
-// All operations after a Close will return with ErrConnDone.
-// Close is safe to call concurrently with other operations and will
-// block until all other operations finish. It may be useful to first
-// cancel any used context and then call close directly after.
-func (c *Conn) Close() error {
- return c.close(nil)
-}
-
-// Tx is an in-progress database transaction.
-//
-// A transaction must end with a call to Commit or Rollback.
-//
-// After a call to Commit or Rollback, all operations on the
-// transaction fail with ErrTxDone.
-//
-// The statements prepared for a transaction by calling
-// the transaction's Prepare or Stmt methods are closed
-// by the call to Commit or Rollback.
-type Tx struct {
- db *DB
-
- // closemu prevents the transaction from closing while there
- // is an active query. It is held for read during queries
- // and exclusively during close.
- closemu sync.RWMutex
-
- // dc is owned exclusively until Commit or Rollback, at which point
- // it's returned with putConn.
- dc *driverConn
- txi driver.Tx
-
- // releaseConn is called once the Tx is closed to release
- // any held driverConn back to the pool.
- releaseConn func(error)
-
- // done transitions from false to true exactly once, on Commit
- // or Rollback. once done, all operations fail with
- // ErrTxDone.
- done atomic.Bool
-
- // keepConnOnRollback is true if the driver knows
- // how to reset the connection's session and if need be discard
- // the connection.
- keepConnOnRollback bool
-
- // All Stmts prepared for this transaction. These will be closed after the
- // transaction has been committed or rolled back.
- stmts struct {
- sync.Mutex
- v []*Stmt
- }
-
- // cancel is called after done transitions from 0 to 1.
- cancel func()
-
- // ctx lives for the life of the transaction.
- ctx context.Context
-}
-
-// awaitDone blocks until the context in Tx is canceled and rolls back
-// the transaction if it's not already done.
-func (tx *Tx) awaitDone() {
- // Wait for either the transaction to be committed or rolled
- // back, or for the associated context to be closed.
- <-tx.ctx.Done()
-
- // Discard and close the connection used to ensure the
- // transaction is closed and the resources are released. This
- // rollback does nothing if the transaction has already been
- // committed or rolled back.
- // Do not discard the connection if the connection knows
- // how to reset the session.
- discardConnection := !tx.keepConnOnRollback
- tx.rollback(discardConnection)
-}
-
-func (tx *Tx) isDone() bool {
- return tx.done.Load()
-}
-
-// ErrTxDone is returned by any operation that is performed on a transaction
-// that has already been committed or rolled back.
-var ErrTxDone = errors.New("sql: transaction has already been committed or rolled back")
-
-// close returns the connection to the pool and
-// must only be called by Tx.rollback or Tx.Commit while
-// 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
-}
-
-// hookTxGrabConn specifies an optional hook to be called on
-// a successful call to (*Tx).grabConn. For tests.
-var hookTxGrabConn func()
-
-func (tx *Tx) grabConn(ctx context.Context) (*driverConn, releaseConn, error) {
- select {
- default:
- case <-ctx.Done():
- return nil, nil, ctx.Err()
- }
-
- // closemu.RLock must come before the check for isDone to prevent the Tx from
- // closing while a query is executing.
- tx.closemu.RLock()
- if tx.isDone() {
- tx.closemu.RUnlock()
- return nil, nil, ErrTxDone
- }
- if hookTxGrabConn != nil { // test hook
- hookTxGrabConn()
- }
- return tx.dc, tx.closemuRUnlockRelease, nil
-}
-
-func (tx *Tx) txCtx() context.Context {
- return tx.ctx
-}
-
-// closemuRUnlockRelease is used as a func(error) method value in
-// ExecContext and QueryContext. Unlocking in the releaseConn keeps
-// the driver conn from being returned to the connection pool until
-// the Rows has been closed.
-func (tx *Tx) closemuRUnlockRelease(error) {
- tx.closemu.RUnlock()
-}
-
-// Closes all Stmts prepared for this transaction.
-func (tx *Tx) closePrepared() {
- tx.stmts.Lock()
- defer tx.stmts.Unlock()
- for _, stmt := range tx.stmts.v {
- stmt.Close()
- }
-}
-
-// Commit commits the transaction.
-func (tx *Tx) Commit() error {
- // Check context first to avoid transaction leak.
- // If put it behind tx.done CompareAndSwap statement, we can't ensure
- // the consistency between tx.done and the real COMMIT operation.
- select {
- default:
- case <-tx.ctx.Done():
- if tx.done.Load() {
- return ErrTxDone
- }
- return tx.ctx.Err()
- }
- if !tx.done.CompareAndSwap(false, true) {
- return ErrTxDone
- }
-
- // Cancel the Tx to release any active R-closemu locks.
- // This is safe to do because tx.done has already transitioned
- // from 0 to 1. Hold the W-closemu lock prior to rollback
- // to ensure no other connection has an active query.
- tx.cancel()
- tx.closemu.Lock()
- tx.closemu.Unlock()
-
- var err error
- withLock(tx.dc, func() {
- err = tx.txi.Commit()
- })
- if !errors.Is(err, driver.ErrBadConn) {
- tx.closePrepared()
- }
- tx.close(err)
- return err
-}
-
-var rollbackHook func()
-
-// rollback aborts the transaction and optionally forces the pool to discard
-// the connection.
-func (tx *Tx) rollback(discardConn bool) error {
- if !tx.done.CompareAndSwap(false, true) {
- return ErrTxDone
- }
-
- if rollbackHook != nil {
- rollbackHook()
- }
-
- // Cancel the Tx to release any active R-closemu locks.
- // This is safe to do because tx.done has already transitioned
- // from 0 to 1. Hold the W-closemu lock prior to rollback
- // to ensure no other connection has an active query.
- tx.cancel()
- tx.closemu.Lock()
- tx.closemu.Unlock()
-
- var err error
- withLock(tx.dc, func() {
- err = tx.txi.Rollback()
- })
- if !errors.Is(err, driver.ErrBadConn) {
- tx.closePrepared()
- }
- if discardConn {
- err = driver.ErrBadConn
- }
- tx.close(err)
- return err
-}
-
-// Rollback aborts the transaction.
-func (tx *Tx) Rollback() error {
- return tx.rollback(false)
-}
-
-// PrepareContext creates a prepared statement for use within a transaction.
-//
-// The returned statement operates within the transaction and will be closed
-// when the transaction has been committed or rolled back.
-//
-// To use an existing prepared statement on this transaction, see Tx.Stmt.
-//
-// The provided context will be used for the preparation of the context, not
-// for the execution of the returned statement. The returned statement
-// will run in the transaction context.
-func (tx *Tx) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
- dc, release, err := tx.grabConn(ctx)
- if err != nil {
- return nil, err
- }
-
- stmt, err := tx.db.prepareDC(ctx, dc, release, tx, query)
- if err != nil {
- return nil, err
- }
- tx.stmts.Lock()
- tx.stmts.v = append(tx.stmts.v, stmt)
- tx.stmts.Unlock()
- return stmt, nil
-}
-
-// Prepare creates a prepared statement for use within a transaction.
-//
-// The returned statement operates within the transaction and will be closed
-// when the transaction has been committed or rolled back.
-//
-// To use an existing prepared statement on this transaction, see Tx.Stmt.
-//
-// Prepare uses context.Background internally; to specify the context, use
-// PrepareContext.
-func (tx *Tx) Prepare(query string) (*Stmt, error) {
- return tx.PrepareContext(context.Background(), query)
-}
-
-// StmtContext returns a transaction-specific prepared statement from
-// an existing statement.
-//
-// Example:
-//
-// updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?")
-// ...
-// tx, err := db.Begin()
-// ...
-// res, err := tx.StmtContext(ctx, updateMoney).Exec(123.45, 98293203)
-//
-// The provided context is used for the preparation of the statement, not for the
-// execution of the statement.
-//
-// The returned statement operates within the transaction and will be closed
-// when the transaction has been committed or rolled back.
-func (tx *Tx) StmtContext(ctx context.Context, stmt *Stmt) *Stmt {
- dc, release, err := tx.grabConn(ctx)
- if err != nil {
- return &Stmt{stickyErr: err}
- }
- defer release(nil)
-
- if tx.db != stmt.db {
- return &Stmt{stickyErr: errors.New("sql: Tx.Stmt: statement from different database used")}
- }
- var si driver.Stmt
- var parentStmt *Stmt
- stmt.mu.Lock()
- if stmt.closed || stmt.cg != nil {
- // If the statement has been closed or already belongs to a
- // transaction, we can't reuse it in this connection.
- // Since tx.StmtContext should never need to be called with a
- // Stmt already belonging to tx, we ignore this edge case and
- // re-prepare the statement in this case. No need to add
- // code-complexity for this.
- stmt.mu.Unlock()
- withLock(dc, func() {
- si, err = ctxDriverPrepare(ctx, dc.ci, stmt.query)
- })
- if err != nil {
- return &Stmt{stickyErr: err}
- }
- } else {
- stmt.removeClosedStmtLocked()
- // See if the statement has already been prepared on this connection,
- // and reuse it if possible.
- for _, v := range stmt.css {
- if v.dc == dc {
- si = v.ds.si
- break
- }
- }
-
- stmt.mu.Unlock()
-
- if si == nil {
- var ds *driverStmt
- withLock(dc, func() {
- ds, err = stmt.prepareOnConnLocked(ctx, dc)
- })
- if err != nil {
- return &Stmt{stickyErr: err}
- }
- si = ds.si
- }
- parentStmt = stmt
- }
-
- txs := &Stmt{
- db: tx.db,
- cg: tx,
- cgds: &driverStmt{
- Locker: dc,
- si: si,
- },
- parentStmt: parentStmt,
- query: stmt.query,
- }
- if parentStmt != nil {
- tx.db.addDep(parentStmt, txs)
- }
- tx.stmts.Lock()
- tx.stmts.v = append(tx.stmts.v, txs)
- tx.stmts.Unlock()
- return txs
-}
-
-// Stmt returns a transaction-specific prepared statement from
-// an existing statement.
-//
-// Example:
-//
-// updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?")
-// ...
-// tx, err := db.Begin()
-// ...
-// res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203)
-//
-// The returned statement operates within the transaction and will be closed
-// when the transaction has been committed or rolled back.
-//
-// Stmt uses context.Background internally; to specify the context, use
-// StmtContext.
-func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
- return tx.StmtContext(context.Background(), stmt)
-}
-
-// ExecContext executes a query that doesn't return rows.
-// For example: an INSERT and UPDATE.
-func (tx *Tx) ExecContext(ctx context.Context, query string, args ...any) (Result, error) {
- dc, release, err := tx.grabConn(ctx)
- if err != nil {
- return nil, err
- }
- return tx.db.execDC(ctx, dc, release, query, args)
-}
-
-// Exec executes a query that doesn't return rows.
-// For example: an INSERT and UPDATE.
-//
-// Exec uses context.Background internally; to specify the context, use
-// ExecContext.
-func (tx *Tx) Exec(query string, args ...any) (Result, error) {
- return tx.ExecContext(context.Background(), query, args...)
-}
-
-// QueryContext executes a query that returns rows, typically a SELECT.
-func (tx *Tx) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error) {
- dc, release, err := tx.grabConn(ctx)
- if err != nil {
- return nil, err
- }
-
- return tx.db.queryDC(ctx, tx.ctx, dc, release, query, args)
-}
-
-// Query executes a query that returns rows, typically a SELECT.
-//
-// Query uses context.Background internally; to specify the context, use
-// QueryContext.
-func (tx *Tx) Query(query string, args ...any) (*Rows, error) {
- return tx.QueryContext(context.Background(), query, args...)
-}
-
-// QueryRowContext executes a query that is expected to return at most one row.
-// QueryRowContext always returns a non-nil value. Errors are deferred until
-// Row's Scan method is called.
-// If the query selects no rows, the *Row's Scan will return ErrNoRows.
-// Otherwise, the *Row's Scan scans the first selected row and discards
-// the rest.
-func (tx *Tx) QueryRowContext(ctx context.Context, query string, args ...any) *Row {
- rows, err := tx.QueryContext(ctx, query, args...)
- return &Row{rows: rows, err: err}
-}
-
-// QueryRow executes a query that is expected to return at most one row.
-// QueryRow always returns a non-nil value. Errors are deferred until
-// Row's Scan method is called.
-// If the query selects no rows, the *Row's Scan will return ErrNoRows.
-// Otherwise, the *Row's Scan scans the first selected row and discards
-// the rest.
-//
-// QueryRow uses context.Background internally; to specify the context, use
-// QueryRowContext.
-func (tx *Tx) QueryRow(query string, args ...any) *Row {
- return tx.QueryRowContext(context.Background(), query, args...)
-}
-
-// connStmt is a prepared statement on a particular connection.
-type connStmt struct {
- dc *driverConn
- ds *driverStmt
-}
-
-// stmtConnGrabber represents a Tx or Conn that will return the underlying
-// driverConn and release function.
-type stmtConnGrabber interface {
- // grabConn returns the driverConn and the associated release function
- // that must be called when the operation completes.
- grabConn(context.Context) (*driverConn, releaseConn, error)
-
- // txCtx returns the transaction context if available.
- // The returned context should be selected on along with
- // any query context when awaiting a cancel.
- txCtx() context.Context
-}
-
-var (
- _ stmtConnGrabber = &Tx{}
- _ stmtConnGrabber = &Conn{}
-)
-
-// Stmt is a prepared statement.
-// A Stmt is safe for concurrent use by multiple goroutines.
-//
-// If a Stmt is prepared on a Tx or Conn, it will be bound to a single
-// underlying connection forever. If the Tx or Conn closes, the Stmt will
-// become unusable and all operations will return an error.
-// If a Stmt is prepared on a DB, it will remain usable for the lifetime of the
-// DB. When the Stmt needs to execute on a new underlying connection, it will
-// prepare itself on the new connection automatically.
-type Stmt struct {
- // Immutable:
- db *DB // where we came from
- query string // that created the Stmt
- stickyErr error // if non-nil, this error is returned for all operations
-
- closemu sync.RWMutex // held exclusively during close, for read otherwise.
-
- // If Stmt is prepared on a Tx or Conn then cg is present and will
- // only ever grab a connection from cg.
- // If cg is nil then the Stmt must grab an arbitrary connection
- // from db and determine if it must prepare the stmt again by
- // inspecting css.
- cg stmtConnGrabber
- cgds *driverStmt
-
- // parentStmt is set when a transaction-specific statement
- // is requested from an identical statement prepared on the same
- // conn. parentStmt is used to track the dependency of this statement
- // on its originating ("parent") statement so that parentStmt may
- // be closed by the user without them having to know whether or not
- // any transactions are still using it.
- parentStmt *Stmt
-
- mu sync.Mutex // protects the rest of the fields
- closed bool
-
- // css is a list of underlying driver statement interfaces
- // that are valid on particular connections. This is only
- // used if cg == nil and one is found that has idle
- // connections. If cg != nil, cgds is always used.
- css []connStmt
-
- // lastNumClosed is copied from db.numClosed when Stmt is created
- // without tx and closed connections in css are removed.
- lastNumClosed uint64
-}
-
-// ExecContext executes a prepared statement with the given arguments and
-// returns a Result summarizing the effect of the statement.
-func (s *Stmt) ExecContext(ctx context.Context, args ...any) (Result, error) {
- s.closemu.RLock()
- defer s.closemu.RUnlock()
-
- var res Result
- err := s.db.retry(func(strategy connReuseStrategy) error {
- dc, releaseConn, ds, err := s.connStmt(ctx, strategy)
- if err != nil {
- return err
- }
-
- res, err = resultFromStatement(ctx, dc.ci, ds, args...)
- releaseConn(err)
- return err
- })
-
- return res, err
-}
-
-// Exec executes a prepared statement with the given arguments and
-// returns a Result summarizing the effect of the statement.
-//
-// Exec uses context.Background internally; to specify the context, use
-// ExecContext.
-func (s *Stmt) Exec(args ...any) (Result, error) {
- return s.ExecContext(context.Background(), args...)
-}
-
-func resultFromStatement(ctx context.Context, ci driver.Conn, ds *driverStmt, args ...any) (Result, error) {
- ds.Lock()
- defer ds.Unlock()
-
- dargs, err := driverArgsConnLocked(ci, ds, args)
- if err != nil {
- return nil, err
- }
-
- resi, err := ctxDriverStmtExec(ctx, ds.si, dargs)
- if err != nil {
- return nil, err
- }
- return driverResult{ds.Locker, resi}, nil
-}
-
-// removeClosedStmtLocked removes closed conns in s.css.
-//
-// To avoid lock contention on DB.mu, we do it only when
-// s.db.numClosed - s.lastNum is large enough.
-func (s *Stmt) removeClosedStmtLocked() {
- t := len(s.css)/2 + 1
- if t > 10 {
- t = 10
- }
- dbClosed := s.db.numClosed.Load()
- if dbClosed-s.lastNumClosed < uint64(t) {
- return
- }
-
- s.db.mu.Lock()
- for i := 0; i < len(s.css); i++ {
- if s.css[i].dc.dbmuClosed {
- s.css[i] = s.css[len(s.css)-1]
- s.css = s.css[:len(s.css)-1]
- i--
- }
- }
- s.db.mu.Unlock()
- s.lastNumClosed = dbClosed
-}
-
-// connStmt returns a free driver connection on which to execute the
-// statement, a function to call to release the connection, and a
-// statement bound to that connection.
-func (s *Stmt) connStmt(ctx context.Context, strategy connReuseStrategy) (dc *driverConn, releaseConn func(error), ds *driverStmt, err error) {
- if err = s.stickyErr; err != nil {
- return
- }
- s.mu.Lock()
- if s.closed {
- s.mu.Unlock()
- err = errors.New("sql: statement is closed")
- return
- }
-
- // In a transaction or connection, we always use the connection that the
- // stmt was created on.
- if s.cg != nil {
- s.mu.Unlock()
- dc, releaseConn, err = s.cg.grabConn(ctx) // blocks, waiting for the connection.
- if err != nil {
- return
- }
- return dc, releaseConn, s.cgds, nil
- }
-
- s.removeClosedStmtLocked()
- s.mu.Unlock()
-
- dc, err = s.db.conn(ctx, strategy)
- if err != nil {
- return nil, nil, nil, err
- }
-
- s.mu.Lock()
- for _, v := range s.css {
- if v.dc == dc {
- s.mu.Unlock()
- return dc, dc.releaseConn, v.ds, nil
- }
- }
- s.mu.Unlock()
-
- // No luck; we need to prepare the statement on this connection
- withLock(dc, func() {
- ds, err = s.prepareOnConnLocked(ctx, dc)
- })
- if err != nil {
- dc.releaseConn(err)
- return nil, nil, nil, err
- }
-
- return dc, dc.releaseConn, ds, nil
-}
-
-// prepareOnConnLocked prepares the query in Stmt s on dc and adds it to the list of
-// open connStmt on the statement. It assumes the caller is holding the lock on dc.
-func (s *Stmt) prepareOnConnLocked(ctx context.Context, dc *driverConn) (*driverStmt, error) {
- si, err := dc.prepareLocked(ctx, s.cg, s.query)
- if err != nil {
- return nil, err
- }
- cs := connStmt{dc, si}
- s.mu.Lock()
- s.css = append(s.css, cs)
- s.mu.Unlock()
- return cs.ds, nil
-}
-
-// QueryContext executes a prepared query statement with the given arguments
-// and returns the query results as a *Rows.
-func (s *Stmt) QueryContext(ctx context.Context, args ...any) (*Rows, error) {
- s.closemu.RLock()
- defer s.closemu.RUnlock()
-
- var rowsi driver.Rows
- var rows *Rows
-
- err := s.db.retry(func(strategy connReuseStrategy) error {
- dc, releaseConn, ds, err := s.connStmt(ctx, strategy)
- if err != nil {
- return err
- }
-
- rowsi, err = rowsiFromStatement(ctx, dc.ci, ds, args...)
- if err == nil {
- // Note: ownership of ci passes to the *Rows, to be freed
- // with releaseConn.
- rows = &Rows{
- dc: dc,
- rowsi: rowsi,
- // releaseConn set below
- }
- // addDep must be added before initContextClose or it could attempt
- // to removeDep before it has been added.
- s.db.addDep(s, rows)
-
- // releaseConn must be set before initContextClose or it could
- // release the connection before it is set.
- rows.releaseConn = func(err error) {
- releaseConn(err)
- s.db.removeDep(s, rows)
- }
- var txctx context.Context
- if s.cg != nil {
- txctx = s.cg.txCtx()
- }
- rows.initContextClose(ctx, txctx)
- return nil
- }
-
- releaseConn(err)
- return err
- })
-
- return rows, err
-}
-
-// Query executes a prepared query statement with the given arguments
-// and returns the query results as a *Rows.
-//
-// Query uses context.Background internally; to specify the context, use
-// QueryContext.
-func (s *Stmt) Query(args ...any) (*Rows, error) {
- return s.QueryContext(context.Background(), args...)
-}
-
-func rowsiFromStatement(ctx context.Context, ci driver.Conn, ds *driverStmt, args ...any) (driver.Rows, error) {
- ds.Lock()
- defer ds.Unlock()
- dargs, err := driverArgsConnLocked(ci, ds, args)
- if err != nil {
- return nil, err
- }
- return ctxDriverStmtQuery(ctx, ds.si, dargs)
-}
-
-// QueryRowContext executes a prepared query statement with the given arguments.
-// If an error occurs during the execution of the statement, that error will
-// be returned by a call to Scan on the returned *Row, which is always non-nil.
-// If the query selects no rows, the *Row's Scan will return ErrNoRows.
-// Otherwise, the *Row's Scan scans the first selected row and discards
-// the rest.
-func (s *Stmt) QueryRowContext(ctx context.Context, args ...any) *Row {
- rows, err := s.QueryContext(ctx, args...)
- if err != nil {
- return &Row{err: err}
- }
- return &Row{rows: rows}
-}
-
-// QueryRow executes a prepared query statement with the given arguments.
-// If an error occurs during the execution of the statement, that error will
-// be returned by a call to Scan on the returned *Row, which is always non-nil.
-// If the query selects no rows, the *Row's Scan will return ErrNoRows.
-// Otherwise, the *Row's Scan scans the first selected row and discards
-// the rest.
-//
-// Example usage:
-//
-// var name string
-// err := nameByUseridStmt.QueryRow(id).Scan(&name)
-//
-// QueryRow uses context.Background internally; to specify the context, use
-// QueryRowContext.
-func (s *Stmt) QueryRow(args ...any) *Row {
- return s.QueryRowContext(context.Background(), args...)
-}
-
-// Close closes the statement.
-func (s *Stmt) Close() error {
- s.closemu.Lock()
- defer s.closemu.Unlock()
-
- if s.stickyErr != nil {
- return s.stickyErr
- }
- s.mu.Lock()
- if s.closed {
- s.mu.Unlock()
- return nil
- }
- s.closed = true
- txds := s.cgds
- s.cgds = nil
-
- s.mu.Unlock()
-
- if s.cg == nil {
- return s.db.removeDep(s, s)
- }
-
- if s.parentStmt != nil {
- // If parentStmt is set, we must not close s.txds since it's stored
- // in the css array of the parentStmt.
- return s.db.removeDep(s.parentStmt, s)
- }
- return txds.Close()
-}
-
-func (s *Stmt) finalClose() error {
- s.mu.Lock()
- defer s.mu.Unlock()
- if s.css != nil {
- for _, v := range s.css {
- s.db.noteUnusedDriverStatement(v.dc, v.ds)
- v.dc.removeOpenStmt(v.ds)
- }
- s.css = nil
- }
- return nil
-}
-
-// Rows is the result of a query. Its cursor starts before the first row
-// of the result set. Use Next to advance from row to row.
-type Rows struct {
- dc *driverConn // owned; must call releaseConn when closed to release
- releaseConn func(error)
- rowsi driver.Rows
- cancel func() // called when Rows is closed, may be nil.
- closeStmt *driverStmt // if non-nil, statement to Close on close
-
- // closemu prevents Rows from closing while there
- // is an active streaming result. It is held for read during non-close operations
- // and exclusively during close.
- //
- // closemu guards lasterr and closed.
- closemu sync.RWMutex
- closed bool
- lasterr error // non-nil only if closed is true
-
- // lastcols is only used in Scan, Next, and NextResultSet which are expected
- // not to be called concurrently.
- lastcols []driver.Value
-}
-
-// lasterrOrErrLocked returns either lasterr or the provided err.
-// rs.closemu must be read-locked.
-func (rs *Rows) lasterrOrErrLocked(err error) error {
- if rs.lasterr != nil && rs.lasterr != io.EOF {
- return rs.lasterr
- }
- return err
-}
-
-// bypassRowsAwaitDone is only used for testing.
-// If true, it will not close the Rows automatically from the context.
-var bypassRowsAwaitDone = false
-
-func (rs *Rows) initContextClose(ctx, txctx context.Context) {
- if ctx.Done() == nil && (txctx == nil || txctx.Done() == nil) {
- return
- }
- if bypassRowsAwaitDone {
- return
- }
- ctx, rs.cancel = context.WithCancel(ctx)
- go rs.awaitDone(ctx, txctx)
-}
-
-// awaitDone blocks until either ctx or txctx is canceled. The ctx is provided
-// from the query context and is canceled when the query Rows is closed.
-// If the query was issued in a transaction, the transaction's context
-// is also provided in txctx to ensure Rows is closed if the Tx is closed.
-func (rs *Rows) awaitDone(ctx, txctx context.Context) {
- var txctxDone <-chan struct{}
- if txctx != nil {
- txctxDone = txctx.Done()
- }
- select {
- case <-ctx.Done():
- case <-txctxDone:
- }
- rs.close(ctx.Err())
-}
-
-// Next prepares the next result row for reading with the Scan method. It
-// returns true on success, or false if there is no next result row or an error
-// happened while preparing it. Err should be consulted to distinguish between
-// the two cases.
-//
-// Every call to Scan, even the first one, must be preceded by a call to Next.
-func (rs *Rows) Next() bool {
- var doClose, ok bool
- withLock(rs.closemu.RLocker(), func() {
- doClose, ok = rs.nextLocked()
- })
- if doClose {
- rs.Close()
- }
- return ok
-}
-
-func (rs *Rows) nextLocked() (doClose, ok bool) {
- if rs.closed {
- return false, false
- }
-
- // Lock the driver connection before calling the driver interface
- // rowsi to prevent a Tx from rolling back the connection at the same time.
- rs.dc.Lock()
- defer rs.dc.Unlock()
-
- if rs.lastcols == nil {
- rs.lastcols = make([]driver.Value, len(rs.rowsi.Columns()))
- }
-
- rs.lasterr = rs.rowsi.Next(rs.lastcols)
- if rs.lasterr != nil {
- // Close the connection if there is a driver error.
- if rs.lasterr != io.EOF {
- return true, false
- }
- nextResultSet, ok := rs.rowsi.(driver.RowsNextResultSet)
- if !ok {
- return true, false
- }
- // The driver is at the end of the current result set.
- // Test to see if there is another result set after the current one.
- // Only close Rows if there is no further result sets to read.
- if !nextResultSet.HasNextResultSet() {
- doClose = true
- }
- return doClose, false
- }
- return false, true
-}
-
-// NextResultSet prepares the next result set for reading. It reports whether
-// there is further result sets, or false if there is no further result set
-// or if there is an error advancing to it. The Err method should be consulted
-// to distinguish between the two cases.
-//
-// After calling NextResultSet, the Next method should always be called before
-// scanning. If there are further result sets they may not have rows in the result
-// set.
-func (rs *Rows) NextResultSet() bool {
- var doClose bool
- defer func() {
- if doClose {
- rs.Close()
- }
- }()
- rs.closemu.RLock()
- defer rs.closemu.RUnlock()
-
- if rs.closed {
- return false
- }
-
- rs.lastcols = nil
- nextResultSet, ok := rs.rowsi.(driver.RowsNextResultSet)
- if !ok {
- doClose = true
- return false
- }
-
- // Lock the driver connection before calling the driver interface
- // rowsi to prevent a Tx from rolling back the connection at the same time.
- rs.dc.Lock()
- defer rs.dc.Unlock()
-
- rs.lasterr = nextResultSet.NextResultSet()
- if rs.lasterr != nil {
- doClose = true
- return false
- }
- return true
-}
-
-// Err returns the error, if any, that was encountered during iteration.
-// Err may be called after an explicit or implicit Close.
-func (rs *Rows) Err() error {
- rs.closemu.RLock()
- defer rs.closemu.RUnlock()
- return rs.lasterrOrErrLocked(nil)
-}
-
-var errRowsClosed = errors.New("sql: Rows are closed")
-var errNoRows = errors.New("sql: no Rows available")
-
-// Columns returns the column names.
-// Columns returns an error if the rows are closed.
-func (rs *Rows) Columns() ([]string, error) {
- rs.closemu.RLock()
- defer rs.closemu.RUnlock()
- if rs.closed {
- return nil, rs.lasterrOrErrLocked(errRowsClosed)
- }
- if rs.rowsi == nil {
- return nil, rs.lasterrOrErrLocked(errNoRows)
- }
- rs.dc.Lock()
- defer rs.dc.Unlock()
-
- return rs.rowsi.Columns(), nil
-}
-
-// ColumnTypes returns column information such as column type, length,
-// and nullable. Some information may not be available from some drivers.
-func (rs *Rows) ColumnTypes() ([]*ColumnType, error) {
- rs.closemu.RLock()
- defer rs.closemu.RUnlock()
- if rs.closed {
- return nil, rs.lasterrOrErrLocked(errRowsClosed)
- }
- if rs.rowsi == nil {
- return nil, rs.lasterrOrErrLocked(errNoRows)
- }
- rs.dc.Lock()
- defer rs.dc.Unlock()
-
- return rowsColumnInfoSetupConnLocked(rs.rowsi), nil
-}
-
-// ColumnType contains the name and type of a column.
-type ColumnType struct {
- name string
-
- hasNullable bool
- hasLength bool
- hasPrecisionScale bool
-
- nullable bool
- length int64
- databaseType string
- precision int64
- scale int64
- scanType reflect.Type
-}
-
-// Name returns the name or alias of the column.
-func (ci *ColumnType) Name() string {
- return ci.name
-}
-
-// Length returns the column type length for variable length column types such
-// as text and binary field types. If the type length is unbounded the value will
-// be math.MaxInt64 (any database limits will still apply).
-// If the column type is not variable length, such as an int, or if not supported
-// by the driver ok is false.
-func (ci *ColumnType) Length() (length int64, ok bool) {
- return ci.length, ci.hasLength
-}
-
-// DecimalSize returns the scale and precision of a decimal type.
-// If not applicable or if not supported ok is false.
-func (ci *ColumnType) DecimalSize() (precision, scale int64, ok bool) {
- return ci.precision, ci.scale, ci.hasPrecisionScale
-}
-
-// ScanType returns a Go type suitable for scanning into using Rows.Scan.
-// If a driver does not support this property ScanType will return
-// the type of an empty interface.
-func (ci *ColumnType) ScanType() reflect.Type {
- return ci.scanType
-}
-
-// Nullable reports whether the column may be null.
-// If a driver does not support this property ok will be false.
-func (ci *ColumnType) Nullable() (nullable, ok bool) {
- return ci.nullable, ci.hasNullable
-}
-
-// DatabaseTypeName returns the database system name of the column type. If an empty
-// string is returned, then the driver type name is not supported.
-// Consult your driver documentation for a list of driver data types. Length specifiers
-// are not included.
-// Common type names include "VARCHAR", "TEXT", "NVARCHAR", "DECIMAL", "BOOL",
-// "INT", and "BIGINT".
-func (ci *ColumnType) DatabaseTypeName() string {
- return ci.databaseType
-}
-
-func rowsColumnInfoSetupConnLocked(rowsi driver.Rows) []*ColumnType {
- names := rowsi.Columns()
-
- list := make([]*ColumnType, len(names))
- for i := range list {
- ci := &ColumnType{
- name: names[i],
- }
- list[i] = ci
-
- if prop, ok := rowsi.(driver.RowsColumnTypeScanType); ok {
- ci.scanType = prop.ColumnTypeScanType(i)
- } else {
- ci.scanType = reflect.TypeOf(new(any)).Elem()
- }
- if prop, ok := rowsi.(driver.RowsColumnTypeDatabaseTypeName); ok {
- ci.databaseType = prop.ColumnTypeDatabaseTypeName(i)
- }
- if prop, ok := rowsi.(driver.RowsColumnTypeLength); ok {
- ci.length, ci.hasLength = prop.ColumnTypeLength(i)
- }
- if prop, ok := rowsi.(driver.RowsColumnTypeNullable); ok {
- ci.nullable, ci.hasNullable = prop.ColumnTypeNullable(i)
- }
- if prop, ok := rowsi.(driver.RowsColumnTypePrecisionScale); ok {
- ci.precision, ci.scale, ci.hasPrecisionScale = prop.ColumnTypePrecisionScale(i)
- }
- }
- return list
-}
-
-// Scan copies the columns in the current row into the values pointed
-// at by dest. The number of values in dest must be the same as the
-// number of columns in Rows.
-//
-// Scan converts columns read from the database into the following
-// common Go types and special types provided by the sql package:
-//
-// *string
-// *[]byte
-// *int, *int8, *int16, *int32, *int64
-// *uint, *uint8, *uint16, *uint32, *uint64
-// *bool
-// *float32, *float64
-// *interface{}
-// *RawBytes
-// *Rows (cursor value)
-// any type implementing Scanner (see Scanner docs)
-//
-// In the most simple case, if the type of the value from the source
-// column is an integer, bool or string type T and dest is of type *T,
-// Scan simply assigns the value through the pointer.
-//
-// Scan also converts between string and numeric types, as long as no
-// information would be lost. While Scan stringifies all numbers
-// scanned from numeric database columns into *string, scans into
-// numeric types are checked for overflow. For example, a float64 with
-// value 300 or a string with value "300" can scan into a uint16, but
-// not into a uint8, though float64(255) or "255" can scan into a
-// uint8. One exception is that scans of some float64 numbers to
-// strings may lose information when stringifying. In general, scan
-// floating point columns into *float64.
-//
-// If a dest argument has type *[]byte, Scan saves in that argument a
-// copy of the corresponding data. The copy is owned by the caller and
-// can be modified and held indefinitely. The copy can be avoided by
-// using an argument of type *RawBytes instead; see the documentation
-// for RawBytes for restrictions on its use.
-//
-// If an argument has type *interface{}, Scan copies the value
-// provided by the underlying driver without conversion. When scanning
-// from a source value of type []byte to *interface{}, a copy of the
-// slice is made and the caller owns the result.
-//
-// Source values of type time.Time may be scanned into values of type
-// *time.Time, *interface{}, *string, or *[]byte. When converting to
-// the latter two, time.RFC3339Nano is used.
-//
-// Source values of type bool may be scanned into types *bool,
-// *interface{}, *string, *[]byte, or *RawBytes.
-//
-// For scanning into *bool, the source may be true, false, 1, 0, or
-// string inputs parseable by strconv.ParseBool.
-//
-// Scan can also convert a cursor returned from a query, such as
-// "select cursor(select * from my_table) from dual", into a
-// *Rows value that can itself be scanned from. The parent
-// select query will close any cursor *Rows if the parent *Rows is closed.
-//
-// If any of the first arguments implementing Scanner returns an error,
-// that error will be wrapped in the returned error.
-func (rs *Rows) Scan(dest ...any) error {
- rs.closemu.RLock()
-
- if rs.lasterr != nil && rs.lasterr != io.EOF {
- rs.closemu.RUnlock()
- return rs.lasterr
- }
- if rs.closed {
- err := rs.lasterrOrErrLocked(errRowsClosed)
- rs.closemu.RUnlock()
- return err
- }
- rs.closemu.RUnlock()
-
- if rs.lastcols == nil {
- return errors.New("sql: Scan called without calling Next")
- }
- if len(dest) != len(rs.lastcols) {
- return fmt.Errorf("sql: expected %d destination arguments in Scan, not %d", len(rs.lastcols), len(dest))
- }
- for i, sv := range rs.lastcols {
- err := convertAssignRows(dest[i], sv, rs)
- if err != nil {
- return fmt.Errorf(`sql: Scan error on column index %d, name %q: %w`, i, rs.rowsi.Columns()[i], err)
- }
- }
- return nil
-}
-
-// rowsCloseHook returns a function so tests may install the
-// hook through a test only mutex.
-var rowsCloseHook = func() func(*Rows, *error) { return nil }
-
-// Close closes the Rows, preventing further enumeration. If Next is called
-// and returns false and there are no further result sets,
-// the Rows are closed automatically and it will suffice to check the
-// result of Err. Close is idempotent and does not affect the result of Err.
-func (rs *Rows) Close() error {
- return rs.close(nil)
-}
-
-func (rs *Rows) close(err error) error {
- rs.closemu.Lock()
- defer rs.closemu.Unlock()
-
- if rs.closed {
- return nil
- }
- rs.closed = true
-
- if rs.lasterr == nil {
- rs.lasterr = err
- }
-
- withLock(rs.dc, func() {
- err = rs.rowsi.Close()
- })
- if fn := rowsCloseHook(); fn != nil {
- fn(rs, &err)
- }
- if rs.cancel != nil {
- rs.cancel()
- }
-
- if rs.closeStmt != nil {
- rs.closeStmt.Close()
- }
- rs.releaseConn(err)
-
- rs.lasterr = rs.lasterrOrErrLocked(err)
- return err
-}
-
-// Row is the result of calling QueryRow to select a single row.
-type Row struct {
- // One of these two will be non-nil:
- err error // deferred error for easy chaining
- rows *Rows
-}
-
-// Scan copies the columns from the matched row into the values
-// pointed at by dest. See the documentation on Rows.Scan for details.
-// If more than one row matches the query,
-// Scan uses the first row and discards the rest. If no row matches
-// the query, Scan returns ErrNoRows.
-func (r *Row) Scan(dest ...any) error {
- if r.err != nil {
- return r.err
- }
-
- // TODO(bradfitz): for now we need to defensively clone all
- // []byte that the driver returned (not permitting
- // *RawBytes in Rows.Scan), since we're about to close
- // the Rows in our defer, when we return from this function.
- // the contract with the driver.Next(...) interface is that it
- // can return slices into read-only temporary memory that's
- // only valid until the next Scan/Close. But the TODO is that
- // for a lot of drivers, this copy will be unnecessary. We
- // should provide an optional interface for drivers to
- // implement to say, "don't worry, the []bytes that I return
- // from Next will not be modified again." (for instance, if
- // they were obtained from the network anyway) But for now we
- // don't care.
- defer r.rows.Close()
- for _, dp := range dest {
- if _, ok := dp.(*RawBytes); ok {
- return errors.New("sql: RawBytes isn't allowed on Row.Scan")
- }
- }
-
- if !r.rows.Next() {
- if err := r.rows.Err(); err != nil {
- return err
- }
- return ErrNoRows
- }
- err := r.rows.Scan(dest...)
- if err != nil {
- return err
- }
- // Make sure the query can be processed to completion with no errors.
- return r.rows.Close()
-}
-
-// Err provides a way for wrapping packages to check for
-// query errors without calling Scan.
-// Err returns the error, if any, that was encountered while running the query.
-// If this error is not nil, this error will also be returned from Scan.
-func (r *Row) Err() error {
- return r.err
-}
-
-// A Result summarizes an executed SQL command.
-type Result interface {
- // LastInsertId returns the integer generated by the database
- // in response to a command. Typically this will be from an
- // "auto increment" column when inserting a new row. Not all
- // databases support this feature, and the syntax of such
- // statements varies.
- LastInsertId() (int64, error)
-
- // RowsAffected returns the number of rows affected by an
- // update, insert, or delete. Not every database or database
- // driver may support this.
- RowsAffected() (int64, error)
-}
-
-type driverResult struct {
- sync.Locker // the *driverConn
- resi driver.Result
-}
-
-func (dr driverResult) LastInsertId() (int64, error) {
- dr.Lock()
- defer dr.Unlock()
- return dr.resi.LastInsertId()
-}
-
-func (dr driverResult) RowsAffected() (int64, error) {
- dr.Lock()
- defer dr.Unlock()
- return dr.resi.RowsAffected()
-}
-
-func stack() string {
- var buf [2 << 10]byte
- return string(buf[:runtime.Stack(buf[:], false)])
-}
-
-// withLock runs while holding lk.
-func withLock(lk sync.Locker, fn func()) {
- lk.Lock()
- defer lk.Unlock() // in case fn panics
- fn()
-}
diff --git a/contrib/go/_std_1.20/src/database/sql/ya.make b/contrib/go/_std_1.20/src/database/sql/ya.make
deleted file mode 100644
index 426fed6a04..0000000000
--- a/contrib/go/_std_1.20/src/database/sql/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- convert.go
- ctxutil.go
- sql.go
-)
-
-END()
-
-RECURSE(
- driver
-)
diff --git a/contrib/go/_std_1.20/src/debug/dwarf/class_string.go b/contrib/go/_std_1.20/src/debug/dwarf/class_string.go
deleted file mode 100644
index 76de7cad31..0000000000
--- a/contrib/go/_std_1.20/src/debug/dwarf/class_string.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Code generated by "stringer -type=Class"; DO NOT EDIT.
-
-package dwarf
-
-import "strconv"
-
-func _() {
- // An "invalid array index" compiler error signifies that the constant values have changed.
- // Re-run the stringer command to generate them again.
- var x [1]struct{}
- _ = x[ClassUnknown-0]
- _ = x[ClassAddress-1]
- _ = x[ClassBlock-2]
- _ = x[ClassConstant-3]
- _ = x[ClassExprLoc-4]
- _ = x[ClassFlag-5]
- _ = x[ClassLinePtr-6]
- _ = x[ClassLocListPtr-7]
- _ = x[ClassMacPtr-8]
- _ = x[ClassRangeListPtr-9]
- _ = x[ClassReference-10]
- _ = x[ClassReferenceSig-11]
- _ = x[ClassString-12]
- _ = x[ClassReferenceAlt-13]
- _ = x[ClassStringAlt-14]
-}
-
-const _Class_name = "ClassUnknownClassAddressClassBlockClassConstantClassExprLocClassFlagClassLinePtrClassLocListPtrClassMacPtrClassRangeListPtrClassReferenceClassReferenceSigClassStringClassReferenceAltClassStringAlt"
-
-var _Class_index = [...]uint8{0, 12, 24, 34, 47, 59, 68, 80, 95, 106, 123, 137, 154, 165, 182, 196}
-
-func (i Class) String() string {
- if i < 0 || i >= Class(len(_Class_index)-1) {
- return "Class(" + strconv.FormatInt(int64(i), 10) + ")"
- }
- return _Class_name[_Class_index[i]:_Class_index[i+1]]
-}
diff --git a/contrib/go/_std_1.20/src/debug/dwarf/entry.go b/contrib/go/_std_1.20/src/debug/dwarf/entry.go
deleted file mode 100644
index 5bb4297b48..0000000000
--- a/contrib/go/_std_1.20/src/debug/dwarf/entry.go
+++ /dev/null
@@ -1,1218 +0,0 @@
-// Copyright 2009 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.
-
-// DWARF debug information entry parser.
-// An entry is a sequence of data items of a given format.
-// The first word in the entry is an index into what DWARF
-// calls the ``abbreviation table.'' An abbreviation is really
-// just a type descriptor: it's an array of attribute tag/value format pairs.
-
-package dwarf
-
-import (
- "encoding/binary"
- "errors"
- "fmt"
- "strconv"
-)
-
-// a single entry's description: a sequence of attributes
-type abbrev struct {
- tag Tag
- children bool
- field []afield
-}
-
-type afield struct {
- attr Attr
- fmt format
- class Class
- val int64 // for formImplicitConst
-}
-
-// a map from entry format ids to their descriptions
-type abbrevTable map[uint32]abbrev
-
-// parseAbbrev returns the abbreviation table that starts at byte off
-// in the .debug_abbrev section.
-func (d *Data) parseAbbrev(off uint64, vers int) (abbrevTable, error) {
- if m, ok := d.abbrevCache[off]; ok {
- return m, nil
- }
-
- data := d.abbrev
- if off > uint64(len(data)) {
- data = nil
- } else {
- data = data[off:]
- }
- b := makeBuf(d, unknownFormat{}, "abbrev", 0, data)
-
- // Error handling is simplified by the buf getters
- // returning an endless stream of 0s after an error.
- m := make(abbrevTable)
- for {
- // Table ends with id == 0.
- id := uint32(b.uint())
- if id == 0 {
- break
- }
-
- // Walk over attributes, counting.
- n := 0
- b1 := b // Read from copy of b.
- b1.uint()
- b1.uint8()
- for {
- tag := b1.uint()
- fmt := b1.uint()
- if tag == 0 && fmt == 0 {
- break
- }
- if format(fmt) == formImplicitConst {
- b1.int()
- }
- n++
- }
- if b1.err != nil {
- return nil, b1.err
- }
-
- // Walk over attributes again, this time writing them down.
- var a abbrev
- a.tag = Tag(b.uint())
- a.children = b.uint8() != 0
- a.field = make([]afield, n)
- for i := range a.field {
- a.field[i].attr = Attr(b.uint())
- a.field[i].fmt = format(b.uint())
- a.field[i].class = formToClass(a.field[i].fmt, a.field[i].attr, vers, &b)
- if a.field[i].fmt == formImplicitConst {
- a.field[i].val = b.int()
- }
- }
- b.uint()
- b.uint()
-
- m[id] = a
- }
- if b.err != nil {
- return nil, b.err
- }
- d.abbrevCache[off] = m
- return m, nil
-}
-
-// attrIsExprloc indicates attributes that allow exprloc values that
-// are encoded as block values in DWARF 2 and 3. See DWARF 4, Figure
-// 20.
-var attrIsExprloc = map[Attr]bool{
- AttrLocation: true,
- AttrByteSize: true,
- AttrBitOffset: true,
- AttrBitSize: true,
- AttrStringLength: true,
- AttrLowerBound: true,
- AttrReturnAddr: true,
- AttrStrideSize: true,
- AttrUpperBound: true,
- AttrCount: true,
- AttrDataMemberLoc: true,
- AttrFrameBase: true,
- AttrSegment: true,
- AttrStaticLink: true,
- AttrUseLocation: true,
- AttrVtableElemLoc: true,
- AttrAllocated: true,
- AttrAssociated: true,
- AttrDataLocation: true,
- AttrStride: true,
-}
-
-// attrPtrClass indicates the *ptr class of attributes that have
-// encoding formSecOffset in DWARF 4 or formData* in DWARF 2 and 3.
-var attrPtrClass = map[Attr]Class{
- AttrLocation: ClassLocListPtr,
- AttrStmtList: ClassLinePtr,
- AttrStringLength: ClassLocListPtr,
- AttrReturnAddr: ClassLocListPtr,
- AttrStartScope: ClassRangeListPtr,
- AttrDataMemberLoc: ClassLocListPtr,
- AttrFrameBase: ClassLocListPtr,
- AttrMacroInfo: ClassMacPtr,
- AttrSegment: ClassLocListPtr,
- AttrStaticLink: ClassLocListPtr,
- AttrUseLocation: ClassLocListPtr,
- AttrVtableElemLoc: ClassLocListPtr,
- AttrRanges: ClassRangeListPtr,
- // The following are new in DWARF 5.
- AttrStrOffsetsBase: ClassStrOffsetsPtr,
- AttrAddrBase: ClassAddrPtr,
- AttrRnglistsBase: ClassRngListsPtr,
- AttrLoclistsBase: ClassLocListPtr,
-}
-
-// formToClass returns the DWARF 4 Class for the given form. If the
-// DWARF version is less then 4, it will disambiguate some forms
-// depending on the attribute.
-func formToClass(form format, attr Attr, vers int, b *buf) Class {
- switch form {
- default:
- b.error("cannot determine class of unknown attribute form")
- return 0
-
- case formIndirect:
- return ClassUnknown
-
- case formAddr, formAddrx, formAddrx1, formAddrx2, formAddrx3, formAddrx4:
- return ClassAddress
-
- case formDwarfBlock1, formDwarfBlock2, formDwarfBlock4, formDwarfBlock:
- // In DWARF 2 and 3, ClassExprLoc was encoded as a
- // block. DWARF 4 distinguishes ClassBlock and
- // ClassExprLoc, but there are no attributes that can
- // be both, so we also promote ClassBlock values in
- // DWARF 4 that should be ClassExprLoc in case
- // producers get this wrong.
- if attrIsExprloc[attr] {
- return ClassExprLoc
- }
- return ClassBlock
-
- case formData1, formData2, formData4, formData8, formSdata, formUdata, formData16, formImplicitConst:
- // In DWARF 2 and 3, ClassPtr was encoded as a
- // constant. Unlike ClassExprLoc/ClassBlock, some
- // DWARF 4 attributes need to distinguish Class*Ptr
- // from ClassConstant, so we only do this promotion
- // for versions 2 and 3.
- if class, ok := attrPtrClass[attr]; vers < 4 && ok {
- return class
- }
- return ClassConstant
-
- case formFlag, formFlagPresent:
- return ClassFlag
-
- case formRefAddr, formRef1, formRef2, formRef4, formRef8, formRefUdata, formRefSup4, formRefSup8:
- return ClassReference
-
- case formRefSig8:
- return ClassReferenceSig
-
- case formString, formStrp, formStrx, formStrpSup, formLineStrp, formStrx1, formStrx2, formStrx3, formStrx4:
- return ClassString
-
- case formSecOffset:
- // DWARF 4 defines four *ptr classes, but doesn't
- // distinguish them in the encoding. Disambiguate
- // these classes using the attribute.
- if class, ok := attrPtrClass[attr]; ok {
- return class
- }
- return ClassUnknown
-
- case formExprloc:
- return ClassExprLoc
-
- case formGnuRefAlt:
- return ClassReferenceAlt
-
- case formGnuStrpAlt:
- return ClassStringAlt
-
- case formLoclistx:
- return ClassLocList
-
- case formRnglistx:
- return ClassRngList
- }
-}
-
-// An entry is a sequence of attribute/value pairs.
-type Entry struct {
- Offset Offset // offset of Entry in DWARF info
- Tag Tag // tag (kind of Entry)
- Children bool // whether Entry is followed by children
- Field []Field
-}
-
-// A Field is a single attribute/value pair in an Entry.
-//
-// A value can be one of several "attribute classes" defined by DWARF.
-// The Go types corresponding to each class are:
-//
-// DWARF class Go type Class
-// ----------- ------- -----
-// address uint64 ClassAddress
-// block []byte ClassBlock
-// constant int64 ClassConstant
-// flag bool ClassFlag
-// reference
-// to info dwarf.Offset ClassReference
-// to type unit uint64 ClassReferenceSig
-// string string ClassString
-// exprloc []byte ClassExprLoc
-// lineptr int64 ClassLinePtr
-// loclistptr int64 ClassLocListPtr
-// macptr int64 ClassMacPtr
-// rangelistptr int64 ClassRangeListPtr
-//
-// For unrecognized or vendor-defined attributes, Class may be
-// ClassUnknown.
-type Field struct {
- Attr Attr
- Val any
- Class Class
-}
-
-// A Class is the DWARF 4 class of an attribute value.
-//
-// In general, a given attribute's value may take on one of several
-// possible classes defined by DWARF, each of which leads to a
-// slightly different interpretation of the attribute.
-//
-// DWARF version 4 distinguishes attribute value classes more finely
-// than previous versions of DWARF. The reader will disambiguate
-// coarser classes from earlier versions of DWARF into the appropriate
-// DWARF 4 class. For example, DWARF 2 uses "constant" for constants
-// as well as all types of section offsets, but the reader will
-// canonicalize attributes in DWARF 2 files that refer to section
-// offsets to one of the Class*Ptr classes, even though these classes
-// were only defined in DWARF 3.
-type Class int
-
-const (
- // ClassUnknown represents values of unknown DWARF class.
- ClassUnknown Class = iota
-
- // ClassAddress represents values of type uint64 that are
- // addresses on the target machine.
- ClassAddress
-
- // ClassBlock represents values of type []byte whose
- // interpretation depends on the attribute.
- ClassBlock
-
- // ClassConstant represents values of type int64 that are
- // constants. The interpretation of this constant depends on
- // the attribute.
- ClassConstant
-
- // ClassExprLoc represents values of type []byte that contain
- // an encoded DWARF expression or location description.
- ClassExprLoc
-
- // ClassFlag represents values of type bool.
- ClassFlag
-
- // ClassLinePtr represents values that are an int64 offset
- // into the "line" section.
- ClassLinePtr
-
- // ClassLocListPtr represents values that are an int64 offset
- // into the "loclist" section.
- ClassLocListPtr
-
- // ClassMacPtr represents values that are an int64 offset into
- // the "mac" section.
- ClassMacPtr
-
- // ClassRangeListPtr represents values that are an int64 offset into
- // the "rangelist" section.
- ClassRangeListPtr
-
- // ClassReference represents values that are an Offset offset
- // of an Entry in the info section (for use with Reader.Seek).
- // The DWARF specification combines ClassReference and
- // ClassReferenceSig into class "reference".
- ClassReference
-
- // ClassReferenceSig represents values that are a uint64 type
- // signature referencing a type Entry.
- ClassReferenceSig
-
- // ClassString represents values that are strings. If the
- // compilation unit specifies the AttrUseUTF8 flag (strongly
- // recommended), the string value will be encoded in UTF-8.
- // Otherwise, the encoding is unspecified.
- ClassString
-
- // ClassReferenceAlt represents values of type int64 that are
- // an offset into the DWARF "info" section of an alternate
- // object file.
- ClassReferenceAlt
-
- // ClassStringAlt represents values of type int64 that are an
- // offset into the DWARF string section of an alternate object
- // file.
- ClassStringAlt
-
- // ClassAddrPtr represents values that are an int64 offset
- // into the "addr" section.
- ClassAddrPtr
-
- // ClassLocList represents values that are an int64 offset
- // into the "loclists" section.
- ClassLocList
-
- // ClassRngList represents values that are a uint64 offset
- // from the base of the "rnglists" section.
- ClassRngList
-
- // ClassRngListsPtr represents values that are an int64 offset
- // into the "rnglists" section. These are used as the base for
- // ClassRngList values.
- ClassRngListsPtr
-
- // ClassStrOffsetsPtr represents values that are an int64
- // offset into the "str_offsets" section.
- ClassStrOffsetsPtr
-)
-
-//go:generate stringer -type=Class
-
-func (i Class) GoString() string {
- return "dwarf." + i.String()
-}
-
-// Val returns the value associated with attribute Attr in Entry,
-// or nil if there is no such attribute.
-//
-// A common idiom is to merge the check for nil return with
-// the check that the value has the expected dynamic type, as in:
-//
-// v, ok := e.Val(AttrSibling).(int64)
-func (e *Entry) Val(a Attr) any {
- if f := e.AttrField(a); f != nil {
- return f.Val
- }
- return nil
-}
-
-// AttrField returns the Field associated with attribute Attr in
-// Entry, or nil if there is no such attribute.
-func (e *Entry) AttrField(a Attr) *Field {
- for i, f := range e.Field {
- if f.Attr == a {
- return &e.Field[i]
- }
- }
- return nil
-}
-
-// An Offset represents the location of an Entry within the DWARF info.
-// (See Reader.Seek.)
-type Offset uint32
-
-// Entry reads a single entry from buf, decoding
-// according to the given abbreviation table.
-func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry {
- off := b.off
- id := uint32(b.uint())
- if id == 0 {
- return &Entry{}
- }
- a, ok := atab[id]
- if !ok {
- b.error("unknown abbreviation table index")
- return nil
- }
- e := &Entry{
- Offset: off,
- Tag: a.tag,
- Children: a.children,
- Field: make([]Field, len(a.field)),
- }
-
- // If we are currently parsing the compilation unit,
- // we can't evaluate Addrx or Strx until we've seen the
- // relevant base entry.
- type delayed struct {
- idx int
- off uint64
- fmt format
- }
- var delay []delayed
-
- resolveStrx := func(strBase, off uint64) string {
- off += strBase
- if uint64(int(off)) != off {
- b.error("DW_FORM_strx offset out of range")
- }
-
- b1 := makeBuf(b.dwarf, b.format, "str_offsets", 0, b.dwarf.strOffsets)
- b1.skip(int(off))
- is64, _ := b.format.dwarf64()
- if is64 {
- off = b1.uint64()
- } else {
- off = uint64(b1.uint32())
- }
- if b1.err != nil {
- b.err = b1.err
- return ""
- }
- if uint64(int(off)) != off {
- b.error("DW_FORM_strx indirect offset out of range")
- }
- b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
- b1.skip(int(off))
- val := b1.string()
- if b1.err != nil {
- b.err = b1.err
- }
- return val
- }
-
- resolveRnglistx := func(rnglistsBase, off uint64) uint64 {
- is64, _ := b.format.dwarf64()
- if is64 {
- off *= 8
- } else {
- off *= 4
- }
- off += rnglistsBase
- if uint64(int(off)) != off {
- b.error("DW_FORM_rnglistx offset out of range")
- }
-
- b1 := makeBuf(b.dwarf, b.format, "rnglists", 0, b.dwarf.rngLists)
- b1.skip(int(off))
- if is64 {
- off = b1.uint64()
- } else {
- off = uint64(b1.uint32())
- }
- if b1.err != nil {
- b.err = b1.err
- return 0
- }
- if uint64(int(off)) != off {
- b.error("DW_FORM_rnglistx indirect offset out of range")
- }
- return rnglistsBase + off
- }
-
- for i := range e.Field {
- e.Field[i].Attr = a.field[i].attr
- e.Field[i].Class = a.field[i].class
- fmt := a.field[i].fmt
- if fmt == formIndirect {
- fmt = format(b.uint())
- e.Field[i].Class = formToClass(fmt, a.field[i].attr, vers, b)
- }
- var val any
- switch fmt {
- default:
- b.error("unknown entry attr format 0x" + strconv.FormatInt(int64(fmt), 16))
-
- // address
- case formAddr:
- val = b.addr()
- case formAddrx, formAddrx1, formAddrx2, formAddrx3, formAddrx4:
- var off uint64
- switch fmt {
- case formAddrx:
- off = b.uint()
- case formAddrx1:
- off = uint64(b.uint8())
- case formAddrx2:
- off = uint64(b.uint16())
- case formAddrx3:
- off = uint64(b.uint24())
- case formAddrx4:
- off = uint64(b.uint32())
- }
- if b.dwarf.addr == nil {
- b.error("DW_FORM_addrx with no .debug_addr section")
- }
- if b.err != nil {
- return nil
- }
-
- // We have to adjust by the offset of the
- // compilation unit. This won't work if the
- // program uses Reader.Seek to skip over the
- // unit. Not much we can do about that.
- var addrBase int64
- if cu != nil {
- addrBase, _ = cu.Val(AttrAddrBase).(int64)
- } else if a.tag == TagCompileUnit {
- delay = append(delay, delayed{i, off, formAddrx})
- break
- }
-
- var err error
- val, err = b.dwarf.debugAddr(b.format, uint64(addrBase), off)
- if err != nil {
- if b.err == nil {
- b.err = err
- }
- return nil
- }
-
- // block
- case formDwarfBlock1:
- val = b.bytes(int(b.uint8()))
- case formDwarfBlock2:
- val = b.bytes(int(b.uint16()))
- case formDwarfBlock4:
- val = b.bytes(int(b.uint32()))
- case formDwarfBlock:
- val = b.bytes(int(b.uint()))
-
- // constant
- case formData1:
- val = int64(b.uint8())
- case formData2:
- val = int64(b.uint16())
- case formData4:
- val = int64(b.uint32())
- case formData8:
- val = int64(b.uint64())
- case formData16:
- val = b.bytes(16)
- case formSdata:
- val = int64(b.int())
- case formUdata:
- val = int64(b.uint())
- case formImplicitConst:
- val = a.field[i].val
-
- // flag
- case formFlag:
- val = b.uint8() == 1
- // New in DWARF 4.
- case formFlagPresent:
- // The attribute is implicitly indicated as present, and no value is
- // encoded in the debugging information entry itself.
- val = true
-
- // reference to other entry
- case formRefAddr:
- vers := b.format.version()
- if vers == 0 {
- b.error("unknown version for DW_FORM_ref_addr")
- } else if vers == 2 {
- val = Offset(b.addr())
- } else {
- is64, known := b.format.dwarf64()
- if !known {
- b.error("unknown size for DW_FORM_ref_addr")
- } else if is64 {
- val = Offset(b.uint64())
- } else {
- val = Offset(b.uint32())
- }
- }
- case formRef1:
- val = Offset(b.uint8()) + ubase
- case formRef2:
- val = Offset(b.uint16()) + ubase
- case formRef4:
- val = Offset(b.uint32()) + ubase
- case formRef8:
- val = Offset(b.uint64()) + ubase
- case formRefUdata:
- val = Offset(b.uint()) + ubase
-
- // string
- case formString:
- val = b.string()
- case formStrp, formLineStrp:
- var off uint64 // offset into .debug_str
- is64, known := b.format.dwarf64()
- if !known {
- b.error("unknown size for DW_FORM_strp/line_strp")
- } else if is64 {
- off = b.uint64()
- } else {
- off = uint64(b.uint32())
- }
- if uint64(int(off)) != off {
- b.error("DW_FORM_strp/line_strp offset out of range")
- }
- if b.err != nil {
- return nil
- }
- var b1 buf
- if fmt == formStrp {
- b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
- } else {
- if len(b.dwarf.lineStr) == 0 {
- b.error("DW_FORM_line_strp with no .debug_line_str section")
- return nil
- }
- b1 = makeBuf(b.dwarf, b.format, "line_str", 0, b.dwarf.lineStr)
- }
- b1.skip(int(off))
- val = b1.string()
- if b1.err != nil {
- b.err = b1.err
- return nil
- }
- case formStrx, formStrx1, formStrx2, formStrx3, formStrx4:
- var off uint64
- switch fmt {
- case formStrx:
- off = b.uint()
- case formStrx1:
- off = uint64(b.uint8())
- case formStrx2:
- off = uint64(b.uint16())
- case formStrx3:
- off = uint64(b.uint24())
- case formStrx4:
- off = uint64(b.uint32())
- }
- if len(b.dwarf.strOffsets) == 0 {
- b.error("DW_FORM_strx with no .debug_str_offsets section")
- }
- is64, known := b.format.dwarf64()
- if !known {
- b.error("unknown offset size for DW_FORM_strx")
- }
- if b.err != nil {
- return nil
- }
- if is64 {
- off *= 8
- } else {
- off *= 4
- }
-
- // We have to adjust by the offset of the
- // compilation unit. This won't work if the
- // program uses Reader.Seek to skip over the
- // unit. Not much we can do about that.
- var strBase int64
- if cu != nil {
- strBase, _ = cu.Val(AttrStrOffsetsBase).(int64)
- } else if a.tag == TagCompileUnit {
- delay = append(delay, delayed{i, off, formStrx})
- break
- }
-
- val = resolveStrx(uint64(strBase), off)
-
- case formStrpSup:
- is64, known := b.format.dwarf64()
- if !known {
- b.error("unknown size for DW_FORM_strp_sup")
- } else if is64 {
- val = b.uint64()
- } else {
- val = b.uint32()
- }
-
- // lineptr, loclistptr, macptr, rangelistptr
- // New in DWARF 4, but clang can generate them with -gdwarf-2.
- // Section reference, replacing use of formData4 and formData8.
- case formSecOffset, formGnuRefAlt, formGnuStrpAlt:
- is64, known := b.format.dwarf64()
- if !known {
- b.error("unknown size for form 0x" + strconv.FormatInt(int64(fmt), 16))
- } else if is64 {
- val = int64(b.uint64())
- } else {
- val = int64(b.uint32())
- }
-
- // exprloc
- // New in DWARF 4.
- case formExprloc:
- val = b.bytes(int(b.uint()))
-
- // reference
- // New in DWARF 4.
- case formRefSig8:
- // 64-bit type signature.
- val = b.uint64()
- case formRefSup4:
- val = b.uint32()
- case formRefSup8:
- val = b.uint64()
-
- // loclist
- case formLoclistx:
- val = b.uint()
-
- // rnglist
- case formRnglistx:
- off := b.uint()
-
- // We have to adjust by the rnglists_base of
- // the compilation unit. This won't work if
- // the program uses Reader.Seek to skip over
- // the unit. Not much we can do about that.
- var rnglistsBase int64
- if cu != nil {
- rnglistsBase, _ = cu.Val(AttrRnglistsBase).(int64)
- } else if a.tag == TagCompileUnit {
- delay = append(delay, delayed{i, off, formRnglistx})
- break
- }
-
- val = resolveRnglistx(uint64(rnglistsBase), off)
- }
-
- e.Field[i].Val = val
- }
- if b.err != nil {
- return nil
- }
-
- for _, del := range delay {
- switch del.fmt {
- case formAddrx:
- addrBase, _ := e.Val(AttrAddrBase).(int64)
- val, err := b.dwarf.debugAddr(b.format, uint64(addrBase), del.off)
- if err != nil {
- b.err = err
- return nil
- }
- e.Field[del.idx].Val = val
- case formStrx:
- strBase, _ := e.Val(AttrStrOffsetsBase).(int64)
- e.Field[del.idx].Val = resolveStrx(uint64(strBase), del.off)
- if b.err != nil {
- return nil
- }
- case formRnglistx:
- rnglistsBase, _ := e.Val(AttrRnglistsBase).(int64)
- e.Field[del.idx].Val = resolveRnglistx(uint64(rnglistsBase), del.off)
- if b.err != nil {
- return nil
- }
- }
- }
-
- return e
-}
-
-// A Reader allows reading Entry structures from a DWARF “info” section.
-// The Entry structures are arranged in a tree. The Reader's Next function
-// return successive entries from a pre-order traversal of the tree.
-// If an entry has children, its Children field will be true, and the children
-// follow, terminated by an Entry with Tag 0.
-type Reader struct {
- b buf
- d *Data
- err error
- unit int
- lastUnit bool // set if last entry returned by Next is TagCompileUnit/TagPartialUnit
- lastChildren bool // .Children of last entry returned by Next
- lastSibling Offset // .Val(AttrSibling) of last entry returned by Next
- cu *Entry // current compilation unit
-}
-
-// Reader returns a new Reader for Data.
-// The reader is positioned at byte offset 0 in the DWARF “info” section.
-func (d *Data) Reader() *Reader {
- r := &Reader{d: d}
- r.Seek(0)
- return r
-}
-
-// AddressSize returns the size in bytes of addresses in the current compilation
-// unit.
-func (r *Reader) AddressSize() int {
- return r.d.unit[r.unit].asize
-}
-
-// ByteOrder returns the byte order in the current compilation unit.
-func (r *Reader) ByteOrder() binary.ByteOrder {
- return r.b.order
-}
-
-// Seek positions the Reader at offset off in the encoded entry stream.
-// Offset 0 can be used to denote the first entry.
-func (r *Reader) Seek(off Offset) {
- d := r.d
- r.err = nil
- r.lastChildren = false
- if off == 0 {
- if len(d.unit) == 0 {
- return
- }
- u := &d.unit[0]
- r.unit = 0
- r.b = makeBuf(r.d, u, "info", u.off, u.data)
- r.cu = nil
- return
- }
-
- i := d.offsetToUnit(off)
- if i == -1 {
- r.err = errors.New("offset out of range")
- return
- }
- if i != r.unit {
- r.cu = nil
- }
- u := &d.unit[i]
- r.unit = i
- r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:])
-}
-
-// maybeNextUnit advances to the next unit if this one is finished.
-func (r *Reader) maybeNextUnit() {
- for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) {
- r.nextUnit()
- }
-}
-
-// nextUnit advances to the next unit.
-func (r *Reader) nextUnit() {
- r.unit++
- u := &r.d.unit[r.unit]
- r.b = makeBuf(r.d, u, "info", u.off, u.data)
- r.cu = nil
-}
-
-// Next reads the next entry from the encoded entry stream.
-// It returns nil, nil when it reaches the end of the section.
-// It returns an error if the current offset is invalid or the data at the
-// offset cannot be decoded as a valid Entry.
-func (r *Reader) Next() (*Entry, error) {
- if r.err != nil {
- return nil, r.err
- }
- r.maybeNextUnit()
- if len(r.b.data) == 0 {
- return nil, nil
- }
- u := &r.d.unit[r.unit]
- e := r.b.entry(r.cu, u.atable, u.base, u.vers)
- if r.b.err != nil {
- r.err = r.b.err
- return nil, r.err
- }
- r.lastUnit = false
- if e != nil {
- r.lastChildren = e.Children
- if r.lastChildren {
- r.lastSibling, _ = e.Val(AttrSibling).(Offset)
- }
- if e.Tag == TagCompileUnit || e.Tag == TagPartialUnit {
- r.lastUnit = true
- r.cu = e
- }
- } else {
- r.lastChildren = false
- }
- return e, nil
-}
-
-// SkipChildren skips over the child entries associated with
-// the last Entry returned by Next. If that Entry did not have
-// children or Next has not been called, SkipChildren is a no-op.
-func (r *Reader) SkipChildren() {
- if r.err != nil || !r.lastChildren {
- return
- }
-
- // If the last entry had a sibling attribute,
- // that attribute gives the offset of the next
- // sibling, so we can avoid decoding the
- // child subtrees.
- if r.lastSibling >= r.b.off {
- r.Seek(r.lastSibling)
- return
- }
-
- if r.lastUnit && r.unit+1 < len(r.d.unit) {
- r.nextUnit()
- return
- }
-
- for {
- e, err := r.Next()
- if err != nil || e == nil || e.Tag == 0 {
- break
- }
- if e.Children {
- r.SkipChildren()
- }
- }
-}
-
-// clone returns a copy of the reader. This is used by the typeReader
-// interface.
-func (r *Reader) clone() typeReader {
- return r.d.Reader()
-}
-
-// offset returns the current buffer offset. This is used by the
-// typeReader interface.
-func (r *Reader) offset() Offset {
- return r.b.off
-}
-
-// SeekPC returns the Entry for the compilation unit that includes pc,
-// and positions the reader to read the children of that unit. If pc
-// is not covered by any unit, SeekPC returns ErrUnknownPC and the
-// position of the reader is undefined.
-//
-// Because compilation units can describe multiple regions of the
-// executable, in the worst case SeekPC must search through all the
-// ranges in all the compilation units. Each call to SeekPC starts the
-// search at the compilation unit of the last call, so in general
-// looking up a series of PCs will be faster if they are sorted. If
-// the caller wishes to do repeated fast PC lookups, it should build
-// an appropriate index using the Ranges method.
-func (r *Reader) SeekPC(pc uint64) (*Entry, error) {
- unit := r.unit
- for i := 0; i < len(r.d.unit); i++ {
- if unit >= len(r.d.unit) {
- unit = 0
- }
- r.err = nil
- r.lastChildren = false
- r.unit = unit
- r.cu = nil
- u := &r.d.unit[unit]
- r.b = makeBuf(r.d, u, "info", u.off, u.data)
- e, err := r.Next()
- if err != nil || e == nil || e.Tag == 0 {
- return nil, err
- }
- ranges, err := r.d.Ranges(e)
- if err != nil {
- return nil, err
- }
- for _, pcs := range ranges {
- if pcs[0] <= pc && pc < pcs[1] {
- return e, nil
- }
- }
- unit++
- }
- return nil, ErrUnknownPC
-}
-
-// Ranges returns the PC ranges covered by e, a slice of [low,high) pairs.
-// Only some entry types, such as TagCompileUnit or TagSubprogram, have PC
-// ranges; for others, this will return nil with no error.
-func (d *Data) Ranges(e *Entry) ([][2]uint64, error) {
- var ret [][2]uint64
-
- low, lowOK := e.Val(AttrLowpc).(uint64)
-
- var high uint64
- var highOK bool
- highField := e.AttrField(AttrHighpc)
- if highField != nil {
- switch highField.Class {
- case ClassAddress:
- high, highOK = highField.Val.(uint64)
- case ClassConstant:
- off, ok := highField.Val.(int64)
- if ok {
- high = low + uint64(off)
- highOK = true
- }
- }
- }
-
- if lowOK && highOK {
- ret = append(ret, [2]uint64{low, high})
- }
-
- var u *unit
- if uidx := d.offsetToUnit(e.Offset); uidx >= 0 && uidx < len(d.unit) {
- u = &d.unit[uidx]
- }
-
- if u != nil && u.vers >= 5 && d.rngLists != nil {
- // DWARF version 5 and later
- field := e.AttrField(AttrRanges)
- if field == nil {
- return ret, nil
- }
- switch field.Class {
- case ClassRangeListPtr:
- ranges, rangesOK := field.Val.(int64)
- if !rangesOK {
- return ret, nil
- }
- cu, base, err := d.baseAddressForEntry(e)
- if err != nil {
- return nil, err
- }
- return d.dwarf5Ranges(u, cu, base, ranges, ret)
-
- case ClassRngList:
- rnglist, ok := field.Val.(uint64)
- if !ok {
- return ret, nil
- }
- cu, base, err := d.baseAddressForEntry(e)
- if err != nil {
- return nil, err
- }
- return d.dwarf5Ranges(u, cu, base, int64(rnglist), ret)
-
- default:
- return ret, nil
- }
- }
-
- // DWARF version 2 through 4
- ranges, rangesOK := e.Val(AttrRanges).(int64)
- if rangesOK && d.ranges != nil {
- _, base, err := d.baseAddressForEntry(e)
- if err != nil {
- return nil, err
- }
- return d.dwarf2Ranges(u, base, ranges, ret)
- }
-
- return ret, nil
-}
-
-// baseAddressForEntry returns the initial base address to be used when
-// looking up the range list of entry e.
-// DWARF specifies that this should be the lowpc attribute of the enclosing
-// compilation unit, however comments in gdb/dwarf2read.c say that some
-// versions of GCC use the entrypc attribute, so we check that too.
-func (d *Data) baseAddressForEntry(e *Entry) (*Entry, uint64, error) {
- var cu *Entry
- if e.Tag == TagCompileUnit {
- cu = e
- } else {
- i := d.offsetToUnit(e.Offset)
- if i == -1 {
- return nil, 0, errors.New("no unit for entry")
- }
- u := &d.unit[i]
- b := makeBuf(d, u, "info", u.off, u.data)
- cu = b.entry(nil, u.atable, u.base, u.vers)
- if b.err != nil {
- return nil, 0, b.err
- }
- }
-
- if cuEntry, cuEntryOK := cu.Val(AttrEntrypc).(uint64); cuEntryOK {
- return cu, cuEntry, nil
- } else if cuLow, cuLowOK := cu.Val(AttrLowpc).(uint64); cuLowOK {
- return cu, cuLow, nil
- }
-
- return cu, 0, nil
-}
-
-func (d *Data) dwarf2Ranges(u *unit, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
- if ranges < 0 || ranges > int64(len(d.ranges)) {
- return nil, fmt.Errorf("invalid range offset %d (max %d)", ranges, len(d.ranges))
- }
- buf := makeBuf(d, u, "ranges", Offset(ranges), d.ranges[ranges:])
- for len(buf.data) > 0 {
- low := buf.addr()
- high := buf.addr()
-
- if low == 0 && high == 0 {
- break
- }
-
- if low == ^uint64(0)>>uint((8-u.addrsize())*8) {
- base = high
- } else {
- ret = append(ret, [2]uint64{base + low, base + high})
- }
- }
-
- return ret, nil
-}
-
-// dwarf5Ranges interprets a debug_rnglists sequence, see DWARFv5 section
-// 2.17.3 (page 53).
-func (d *Data) dwarf5Ranges(u *unit, cu *Entry, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
- if ranges < 0 || ranges > int64(len(d.rngLists)) {
- return nil, fmt.Errorf("invalid rnglist offset %d (max %d)", ranges, len(d.ranges))
- }
- var addrBase int64
- if cu != nil {
- addrBase, _ = cu.Val(AttrAddrBase).(int64)
- }
-
- buf := makeBuf(d, u, "rnglists", 0, d.rngLists)
- buf.skip(int(ranges))
- for {
- opcode := buf.uint8()
- switch opcode {
- case rleEndOfList:
- if buf.err != nil {
- return nil, buf.err
- }
- return ret, nil
-
- case rleBaseAddressx:
- baseIdx := buf.uint()
- var err error
- base, err = d.debugAddr(u, uint64(addrBase), baseIdx)
- if err != nil {
- return nil, err
- }
-
- case rleStartxEndx:
- startIdx := buf.uint()
- endIdx := buf.uint()
-
- start, err := d.debugAddr(u, uint64(addrBase), startIdx)
- if err != nil {
- return nil, err
- }
- end, err := d.debugAddr(u, uint64(addrBase), endIdx)
- if err != nil {
- return nil, err
- }
- ret = append(ret, [2]uint64{start, end})
-
- case rleStartxLength:
- startIdx := buf.uint()
- len := buf.uint()
- start, err := d.debugAddr(u, uint64(addrBase), startIdx)
- if err != nil {
- return nil, err
- }
- ret = append(ret, [2]uint64{start, start + len})
-
- case rleOffsetPair:
- off1 := buf.uint()
- off2 := buf.uint()
- ret = append(ret, [2]uint64{base + off1, base + off2})
-
- case rleBaseAddress:
- base = buf.addr()
-
- case rleStartEnd:
- start := buf.addr()
- end := buf.addr()
- ret = append(ret, [2]uint64{start, end})
-
- case rleStartLength:
- start := buf.addr()
- len := buf.uint()
- ret = append(ret, [2]uint64{start, start + len})
- }
- }
-}
-
-// debugAddr returns the address at idx in debug_addr
-func (d *Data) debugAddr(format dataFormat, addrBase, idx uint64) (uint64, error) {
- off := idx*uint64(format.addrsize()) + addrBase
-
- if uint64(int(off)) != off {
- return 0, errors.New("offset out of range")
- }
-
- b := makeBuf(d, format, "addr", 0, d.addr)
- b.skip(int(off))
- val := b.addr()
- if b.err != nil {
- return 0, b.err
- }
- return val, nil
-}
diff --git a/contrib/go/_std_1.20/src/debug/dwarf/ya.make b/contrib/go/_std_1.20/src/debug/dwarf/ya.make
deleted file mode 100644
index 4f4ea0bcea..0000000000
--- a/contrib/go/_std_1.20/src/debug/dwarf/ya.make
+++ /dev/null
@@ -1,17 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- attr_string.go
- buf.go
- class_string.go
- const.go
- entry.go
- line.go
- open.go
- tag_string.go
- type.go
- typeunit.go
- unit.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/debug/elf/elf.go b/contrib/go/_std_1.20/src/debug/elf/elf.go
deleted file mode 100644
index 02cda16510..0000000000
--- a/contrib/go/_std_1.20/src/debug/elf/elf.go
+++ /dev/null
@@ -1,3478 +0,0 @@
-/*
- * ELF constants and data structures
- *
- * Derived from:
- * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
- * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
- * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
- * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
- * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
- * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
- * "System V ABI" (http://www.sco.com/developers/gabi/latest/ch4.eheader.html)
- * "ELF for the ARM® 64-bit Architecture (AArch64)" (ARM IHI 0056B)
- * "RISC-V ELF psABI specification" (https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md)
- * llvm/BinaryFormat/ELF.h - ELF constants and structures
- *
- * Copyright (c) 1996-1998 John D. Polstra. All rights reserved.
- * Copyright (c) 2001 David E. O'Brien
- * Portions Copyright 2009 The Go Authors. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-package elf
-
-import "strconv"
-
-/*
- * Constants
- */
-
-// Indexes into the Header.Ident array.
-const (
- EI_CLASS = 4 /* Class of machine. */
- EI_DATA = 5 /* Data format. */
- EI_VERSION = 6 /* ELF format version. */
- EI_OSABI = 7 /* Operating system / ABI identification */
- EI_ABIVERSION = 8 /* ABI version */
- EI_PAD = 9 /* Start of padding (per SVR4 ABI). */
- EI_NIDENT = 16 /* Size of e_ident array. */
-)
-
-// Initial magic number for ELF files.
-const ELFMAG = "\177ELF"
-
-// Version is found in Header.Ident[EI_VERSION] and Header.Version.
-type Version byte
-
-const (
- EV_NONE Version = 0
- EV_CURRENT Version = 1
-)
-
-var versionStrings = []intName{
- {0, "EV_NONE"},
- {1, "EV_CURRENT"},
-}
-
-func (i Version) String() string { return stringName(uint32(i), versionStrings, false) }
-func (i Version) GoString() string { return stringName(uint32(i), versionStrings, true) }
-
-// Class is found in Header.Ident[EI_CLASS] and Header.Class.
-type Class byte
-
-const (
- ELFCLASSNONE Class = 0 /* Unknown class. */
- ELFCLASS32 Class = 1 /* 32-bit architecture. */
- ELFCLASS64 Class = 2 /* 64-bit architecture. */
-)
-
-var classStrings = []intName{
- {0, "ELFCLASSNONE"},
- {1, "ELFCLASS32"},
- {2, "ELFCLASS64"},
-}
-
-func (i Class) String() string { return stringName(uint32(i), classStrings, false) }
-func (i Class) GoString() string { return stringName(uint32(i), classStrings, true) }
-
-// Data is found in Header.Ident[EI_DATA] and Header.Data.
-type Data byte
-
-const (
- ELFDATANONE Data = 0 /* Unknown data format. */
- ELFDATA2LSB Data = 1 /* 2's complement little-endian. */
- ELFDATA2MSB Data = 2 /* 2's complement big-endian. */
-)
-
-var dataStrings = []intName{
- {0, "ELFDATANONE"},
- {1, "ELFDATA2LSB"},
- {2, "ELFDATA2MSB"},
-}
-
-func (i Data) String() string { return stringName(uint32(i), dataStrings, false) }
-func (i Data) GoString() string { return stringName(uint32(i), dataStrings, true) }
-
-// OSABI is found in Header.Ident[EI_OSABI] and Header.OSABI.
-type OSABI byte
-
-const (
- ELFOSABI_NONE OSABI = 0 /* UNIX System V ABI */
- ELFOSABI_HPUX OSABI = 1 /* HP-UX operating system */
- ELFOSABI_NETBSD OSABI = 2 /* NetBSD */
- ELFOSABI_LINUX OSABI = 3 /* Linux */
- ELFOSABI_HURD OSABI = 4 /* Hurd */
- ELFOSABI_86OPEN OSABI = 5 /* 86Open common IA32 ABI */
- ELFOSABI_SOLARIS OSABI = 6 /* Solaris */
- ELFOSABI_AIX OSABI = 7 /* AIX */
- ELFOSABI_IRIX OSABI = 8 /* IRIX */
- ELFOSABI_FREEBSD OSABI = 9 /* FreeBSD */
- ELFOSABI_TRU64 OSABI = 10 /* TRU64 UNIX */
- ELFOSABI_MODESTO OSABI = 11 /* Novell Modesto */
- ELFOSABI_OPENBSD OSABI = 12 /* OpenBSD */
- ELFOSABI_OPENVMS OSABI = 13 /* Open VMS */
- ELFOSABI_NSK OSABI = 14 /* HP Non-Stop Kernel */
- ELFOSABI_AROS OSABI = 15 /* Amiga Research OS */
- ELFOSABI_FENIXOS OSABI = 16 /* The FenixOS highly scalable multi-core OS */
- ELFOSABI_CLOUDABI OSABI = 17 /* Nuxi CloudABI */
- ELFOSABI_ARM OSABI = 97 /* ARM */
- ELFOSABI_STANDALONE OSABI = 255 /* Standalone (embedded) application */
-)
-
-var osabiStrings = []intName{
- {0, "ELFOSABI_NONE"},
- {1, "ELFOSABI_HPUX"},
- {2, "ELFOSABI_NETBSD"},
- {3, "ELFOSABI_LINUX"},
- {4, "ELFOSABI_HURD"},
- {5, "ELFOSABI_86OPEN"},
- {6, "ELFOSABI_SOLARIS"},
- {7, "ELFOSABI_AIX"},
- {8, "ELFOSABI_IRIX"},
- {9, "ELFOSABI_FREEBSD"},
- {10, "ELFOSABI_TRU64"},
- {11, "ELFOSABI_MODESTO"},
- {12, "ELFOSABI_OPENBSD"},
- {13, "ELFOSABI_OPENVMS"},
- {14, "ELFOSABI_NSK"},
- {15, "ELFOSABI_AROS"},
- {16, "ELFOSABI_FENIXOS"},
- {17, "ELFOSABI_CLOUDABI"},
- {97, "ELFOSABI_ARM"},
- {255, "ELFOSABI_STANDALONE"},
-}
-
-func (i OSABI) String() string { return stringName(uint32(i), osabiStrings, false) }
-func (i OSABI) GoString() string { return stringName(uint32(i), osabiStrings, true) }
-
-// Type is found in Header.Type.
-type Type uint16
-
-const (
- ET_NONE Type = 0 /* Unknown type. */
- ET_REL Type = 1 /* Relocatable. */
- ET_EXEC Type = 2 /* Executable. */
- ET_DYN Type = 3 /* Shared object. */
- ET_CORE Type = 4 /* Core file. */
- ET_LOOS Type = 0xfe00 /* First operating system specific. */
- ET_HIOS Type = 0xfeff /* Last operating system-specific. */
- ET_LOPROC Type = 0xff00 /* First processor-specific. */
- ET_HIPROC Type = 0xffff /* Last processor-specific. */
-)
-
-var typeStrings = []intName{
- {0, "ET_NONE"},
- {1, "ET_REL"},
- {2, "ET_EXEC"},
- {3, "ET_DYN"},
- {4, "ET_CORE"},
- {0xfe00, "ET_LOOS"},
- {0xfeff, "ET_HIOS"},
- {0xff00, "ET_LOPROC"},
- {0xffff, "ET_HIPROC"},
-}
-
-func (i Type) String() string { return stringName(uint32(i), typeStrings, false) }
-func (i Type) GoString() string { return stringName(uint32(i), typeStrings, true) }
-
-// Machine is found in Header.Machine.
-type Machine uint16
-
-const (
- EM_NONE Machine = 0 /* Unknown machine. */
- EM_M32 Machine = 1 /* AT&T WE32100. */
- EM_SPARC Machine = 2 /* Sun SPARC. */
- EM_386 Machine = 3 /* Intel i386. */
- EM_68K Machine = 4 /* Motorola 68000. */
- EM_88K Machine = 5 /* Motorola 88000. */
- EM_860 Machine = 7 /* Intel i860. */
- EM_MIPS Machine = 8 /* MIPS R3000 Big-Endian only. */
- EM_S370 Machine = 9 /* IBM System/370. */
- EM_MIPS_RS3_LE Machine = 10 /* MIPS R3000 Little-Endian. */
- EM_PARISC Machine = 15 /* HP PA-RISC. */
- EM_VPP500 Machine = 17 /* Fujitsu VPP500. */
- EM_SPARC32PLUS Machine = 18 /* SPARC v8plus. */
- EM_960 Machine = 19 /* Intel 80960. */
- EM_PPC Machine = 20 /* PowerPC 32-bit. */
- EM_PPC64 Machine = 21 /* PowerPC 64-bit. */
- EM_S390 Machine = 22 /* IBM System/390. */
- EM_V800 Machine = 36 /* NEC V800. */
- EM_FR20 Machine = 37 /* Fujitsu FR20. */
- EM_RH32 Machine = 38 /* TRW RH-32. */
- EM_RCE Machine = 39 /* Motorola RCE. */
- EM_ARM Machine = 40 /* ARM. */
- EM_SH Machine = 42 /* Hitachi SH. */
- EM_SPARCV9 Machine = 43 /* SPARC v9 64-bit. */
- EM_TRICORE Machine = 44 /* Siemens TriCore embedded processor. */
- EM_ARC Machine = 45 /* Argonaut RISC Core. */
- EM_H8_300 Machine = 46 /* Hitachi H8/300. */
- EM_H8_300H Machine = 47 /* Hitachi H8/300H. */
- EM_H8S Machine = 48 /* Hitachi H8S. */
- EM_H8_500 Machine = 49 /* Hitachi H8/500. */
- EM_IA_64 Machine = 50 /* Intel IA-64 Processor. */
- EM_MIPS_X Machine = 51 /* Stanford MIPS-X. */
- EM_COLDFIRE Machine = 52 /* Motorola ColdFire. */
- EM_68HC12 Machine = 53 /* Motorola M68HC12. */
- EM_MMA Machine = 54 /* Fujitsu MMA. */
- EM_PCP Machine = 55 /* Siemens PCP. */
- EM_NCPU Machine = 56 /* Sony nCPU. */
- EM_NDR1 Machine = 57 /* Denso NDR1 microprocessor. */
- EM_STARCORE Machine = 58 /* Motorola Star*Core processor. */
- EM_ME16 Machine = 59 /* Toyota ME16 processor. */
- EM_ST100 Machine = 60 /* STMicroelectronics ST100 processor. */
- EM_TINYJ Machine = 61 /* Advanced Logic Corp. TinyJ processor. */
- EM_X86_64 Machine = 62 /* Advanced Micro Devices x86-64 */
- EM_PDSP Machine = 63 /* Sony DSP Processor */
- EM_PDP10 Machine = 64 /* Digital Equipment Corp. PDP-10 */
- EM_PDP11 Machine = 65 /* Digital Equipment Corp. PDP-11 */
- EM_FX66 Machine = 66 /* Siemens FX66 microcontroller */
- EM_ST9PLUS Machine = 67 /* STMicroelectronics ST9+ 8/16 bit microcontroller */
- EM_ST7 Machine = 68 /* STMicroelectronics ST7 8-bit microcontroller */
- EM_68HC16 Machine = 69 /* Motorola MC68HC16 Microcontroller */
- EM_68HC11 Machine = 70 /* Motorola MC68HC11 Microcontroller */
- EM_68HC08 Machine = 71 /* Motorola MC68HC08 Microcontroller */
- EM_68HC05 Machine = 72 /* Motorola MC68HC05 Microcontroller */
- EM_SVX Machine = 73 /* Silicon Graphics SVx */
- EM_ST19 Machine = 74 /* STMicroelectronics ST19 8-bit microcontroller */
- EM_VAX Machine = 75 /* Digital VAX */
- EM_CRIS Machine = 76 /* Axis Communications 32-bit embedded processor */
- EM_JAVELIN Machine = 77 /* Infineon Technologies 32-bit embedded processor */
- EM_FIREPATH Machine = 78 /* Element 14 64-bit DSP Processor */
- EM_ZSP Machine = 79 /* LSI Logic 16-bit DSP Processor */
- EM_MMIX Machine = 80 /* Donald Knuth's educational 64-bit processor */
- EM_HUANY Machine = 81 /* Harvard University machine-independent object files */
- EM_PRISM Machine = 82 /* SiTera Prism */
- EM_AVR Machine = 83 /* Atmel AVR 8-bit microcontroller */
- EM_FR30 Machine = 84 /* Fujitsu FR30 */
- EM_D10V Machine = 85 /* Mitsubishi D10V */
- EM_D30V Machine = 86 /* Mitsubishi D30V */
- EM_V850 Machine = 87 /* NEC v850 */
- EM_M32R Machine = 88 /* Mitsubishi M32R */
- EM_MN10300 Machine = 89 /* Matsushita MN10300 */
- EM_MN10200 Machine = 90 /* Matsushita MN10200 */
- EM_PJ Machine = 91 /* picoJava */
- EM_OPENRISC Machine = 92 /* OpenRISC 32-bit embedded processor */
- EM_ARC_COMPACT Machine = 93 /* ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5) */
- EM_XTENSA Machine = 94 /* Tensilica Xtensa Architecture */
- EM_VIDEOCORE Machine = 95 /* Alphamosaic VideoCore processor */
- EM_TMM_GPP Machine = 96 /* Thompson Multimedia General Purpose Processor */
- EM_NS32K Machine = 97 /* National Semiconductor 32000 series */
- EM_TPC Machine = 98 /* Tenor Network TPC processor */
- EM_SNP1K Machine = 99 /* Trebia SNP 1000 processor */
- EM_ST200 Machine = 100 /* STMicroelectronics (www.st.com) ST200 microcontroller */
- EM_IP2K Machine = 101 /* Ubicom IP2xxx microcontroller family */
- EM_MAX Machine = 102 /* MAX Processor */
- EM_CR Machine = 103 /* National Semiconductor CompactRISC microprocessor */
- EM_F2MC16 Machine = 104 /* Fujitsu F2MC16 */
- EM_MSP430 Machine = 105 /* Texas Instruments embedded microcontroller msp430 */
- EM_BLACKFIN Machine = 106 /* Analog Devices Blackfin (DSP) processor */
- EM_SE_C33 Machine = 107 /* S1C33 Family of Seiko Epson processors */
- EM_SEP Machine = 108 /* Sharp embedded microprocessor */
- EM_ARCA Machine = 109 /* Arca RISC Microprocessor */
- EM_UNICORE Machine = 110 /* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University */
- EM_EXCESS Machine = 111 /* eXcess: 16/32/64-bit configurable embedded CPU */
- EM_DXP Machine = 112 /* Icera Semiconductor Inc. Deep Execution Processor */
- EM_ALTERA_NIOS2 Machine = 113 /* Altera Nios II soft-core processor */
- EM_CRX Machine = 114 /* National Semiconductor CompactRISC CRX microprocessor */
- EM_XGATE Machine = 115 /* Motorola XGATE embedded processor */
- EM_C166 Machine = 116 /* Infineon C16x/XC16x processor */
- EM_M16C Machine = 117 /* Renesas M16C series microprocessors */
- EM_DSPIC30F Machine = 118 /* Microchip Technology dsPIC30F Digital Signal Controller */
- EM_CE Machine = 119 /* Freescale Communication Engine RISC core */
- EM_M32C Machine = 120 /* Renesas M32C series microprocessors */
- EM_TSK3000 Machine = 131 /* Altium TSK3000 core */
- EM_RS08 Machine = 132 /* Freescale RS08 embedded processor */
- EM_SHARC Machine = 133 /* Analog Devices SHARC family of 32-bit DSP processors */
- EM_ECOG2 Machine = 134 /* Cyan Technology eCOG2 microprocessor */
- EM_SCORE7 Machine = 135 /* Sunplus S+core7 RISC processor */
- EM_DSP24 Machine = 136 /* New Japan Radio (NJR) 24-bit DSP Processor */
- EM_VIDEOCORE3 Machine = 137 /* Broadcom VideoCore III processor */
- EM_LATTICEMICO32 Machine = 138 /* RISC processor for Lattice FPGA architecture */
- EM_SE_C17 Machine = 139 /* Seiko Epson C17 family */
- EM_TI_C6000 Machine = 140 /* The Texas Instruments TMS320C6000 DSP family */
- EM_TI_C2000 Machine = 141 /* The Texas Instruments TMS320C2000 DSP family */
- EM_TI_C5500 Machine = 142 /* The Texas Instruments TMS320C55x DSP family */
- EM_TI_ARP32 Machine = 143 /* Texas Instruments Application Specific RISC Processor, 32bit fetch */
- EM_TI_PRU Machine = 144 /* Texas Instruments Programmable Realtime Unit */
- EM_MMDSP_PLUS Machine = 160 /* STMicroelectronics 64bit VLIW Data Signal Processor */
- EM_CYPRESS_M8C Machine = 161 /* Cypress M8C microprocessor */
- EM_R32C Machine = 162 /* Renesas R32C series microprocessors */
- EM_TRIMEDIA Machine = 163 /* NXP Semiconductors TriMedia architecture family */
- EM_QDSP6 Machine = 164 /* QUALCOMM DSP6 Processor */
- EM_8051 Machine = 165 /* Intel 8051 and variants */
- EM_STXP7X Machine = 166 /* STMicroelectronics STxP7x family of configurable and extensible RISC processors */
- EM_NDS32 Machine = 167 /* Andes Technology compact code size embedded RISC processor family */
- EM_ECOG1 Machine = 168 /* Cyan Technology eCOG1X family */
- EM_ECOG1X Machine = 168 /* Cyan Technology eCOG1X family */
- EM_MAXQ30 Machine = 169 /* Dallas Semiconductor MAXQ30 Core Micro-controllers */
- EM_XIMO16 Machine = 170 /* New Japan Radio (NJR) 16-bit DSP Processor */
- EM_MANIK Machine = 171 /* M2000 Reconfigurable RISC Microprocessor */
- EM_CRAYNV2 Machine = 172 /* Cray Inc. NV2 vector architecture */
- EM_RX Machine = 173 /* Renesas RX family */
- EM_METAG Machine = 174 /* Imagination Technologies META processor architecture */
- EM_MCST_ELBRUS Machine = 175 /* MCST Elbrus general purpose hardware architecture */
- EM_ECOG16 Machine = 176 /* Cyan Technology eCOG16 family */
- EM_CR16 Machine = 177 /* National Semiconductor CompactRISC CR16 16-bit microprocessor */
- EM_ETPU Machine = 178 /* Freescale Extended Time Processing Unit */
- EM_SLE9X Machine = 179 /* Infineon Technologies SLE9X core */
- EM_L10M Machine = 180 /* Intel L10M */
- EM_K10M Machine = 181 /* Intel K10M */
- EM_AARCH64 Machine = 183 /* ARM 64-bit Architecture (AArch64) */
- EM_AVR32 Machine = 185 /* Atmel Corporation 32-bit microprocessor family */
- EM_STM8 Machine = 186 /* STMicroeletronics STM8 8-bit microcontroller */
- EM_TILE64 Machine = 187 /* Tilera TILE64 multicore architecture family */
- EM_TILEPRO Machine = 188 /* Tilera TILEPro multicore architecture family */
- EM_MICROBLAZE Machine = 189 /* Xilinx MicroBlaze 32-bit RISC soft processor core */
- EM_CUDA Machine = 190 /* NVIDIA CUDA architecture */
- EM_TILEGX Machine = 191 /* Tilera TILE-Gx multicore architecture family */
- EM_CLOUDSHIELD Machine = 192 /* CloudShield architecture family */
- EM_COREA_1ST Machine = 193 /* KIPO-KAIST Core-A 1st generation processor family */
- EM_COREA_2ND Machine = 194 /* KIPO-KAIST Core-A 2nd generation processor family */
- EM_ARC_COMPACT2 Machine = 195 /* Synopsys ARCompact V2 */
- EM_OPEN8 Machine = 196 /* Open8 8-bit RISC soft processor core */
- EM_RL78 Machine = 197 /* Renesas RL78 family */
- EM_VIDEOCORE5 Machine = 198 /* Broadcom VideoCore V processor */
- EM_78KOR Machine = 199 /* Renesas 78KOR family */
- EM_56800EX Machine = 200 /* Freescale 56800EX Digital Signal Controller (DSC) */
- EM_BA1 Machine = 201 /* Beyond BA1 CPU architecture */
- EM_BA2 Machine = 202 /* Beyond BA2 CPU architecture */
- EM_XCORE Machine = 203 /* XMOS xCORE processor family */
- EM_MCHP_PIC Machine = 204 /* Microchip 8-bit PIC(r) family */
- EM_INTEL205 Machine = 205 /* Reserved by Intel */
- EM_INTEL206 Machine = 206 /* Reserved by Intel */
- EM_INTEL207 Machine = 207 /* Reserved by Intel */
- EM_INTEL208 Machine = 208 /* Reserved by Intel */
- EM_INTEL209 Machine = 209 /* Reserved by Intel */
- EM_KM32 Machine = 210 /* KM211 KM32 32-bit processor */
- EM_KMX32 Machine = 211 /* KM211 KMX32 32-bit processor */
- EM_KMX16 Machine = 212 /* KM211 KMX16 16-bit processor */
- EM_KMX8 Machine = 213 /* KM211 KMX8 8-bit processor */
- EM_KVARC Machine = 214 /* KM211 KVARC processor */
- EM_CDP Machine = 215 /* Paneve CDP architecture family */
- EM_COGE Machine = 216 /* Cognitive Smart Memory Processor */
- EM_COOL Machine = 217 /* Bluechip Systems CoolEngine */
- EM_NORC Machine = 218 /* Nanoradio Optimized RISC */
- EM_CSR_KALIMBA Machine = 219 /* CSR Kalimba architecture family */
- EM_Z80 Machine = 220 /* Zilog Z80 */
- EM_VISIUM Machine = 221 /* Controls and Data Services VISIUMcore processor */
- EM_FT32 Machine = 222 /* FTDI Chip FT32 high performance 32-bit RISC architecture */
- EM_MOXIE Machine = 223 /* Moxie processor family */
- EM_AMDGPU Machine = 224 /* AMD GPU architecture */
- EM_RISCV Machine = 243 /* RISC-V */
- EM_LANAI Machine = 244 /* Lanai 32-bit processor */
- EM_BPF Machine = 247 /* Linux BPF – in-kernel virtual machine */
- EM_LOONGARCH Machine = 258 /* LoongArch */
-
- /* Non-standard or deprecated. */
- EM_486 Machine = 6 /* Intel i486. */
- EM_MIPS_RS4_BE Machine = 10 /* MIPS R4000 Big-Endian */
- EM_ALPHA_STD Machine = 41 /* Digital Alpha (standard value). */
- EM_ALPHA Machine = 0x9026 /* Alpha (written in the absence of an ABI) */
-)
-
-var machineStrings = []intName{
- {0, "EM_NONE"},
- {1, "EM_M32"},
- {2, "EM_SPARC"},
- {3, "EM_386"},
- {4, "EM_68K"},
- {5, "EM_88K"},
- {7, "EM_860"},
- {8, "EM_MIPS"},
- {9, "EM_S370"},
- {10, "EM_MIPS_RS3_LE"},
- {15, "EM_PARISC"},
- {17, "EM_VPP500"},
- {18, "EM_SPARC32PLUS"},
- {19, "EM_960"},
- {20, "EM_PPC"},
- {21, "EM_PPC64"},
- {22, "EM_S390"},
- {36, "EM_V800"},
- {37, "EM_FR20"},
- {38, "EM_RH32"},
- {39, "EM_RCE"},
- {40, "EM_ARM"},
- {42, "EM_SH"},
- {43, "EM_SPARCV9"},
- {44, "EM_TRICORE"},
- {45, "EM_ARC"},
- {46, "EM_H8_300"},
- {47, "EM_H8_300H"},
- {48, "EM_H8S"},
- {49, "EM_H8_500"},
- {50, "EM_IA_64"},
- {51, "EM_MIPS_X"},
- {52, "EM_COLDFIRE"},
- {53, "EM_68HC12"},
- {54, "EM_MMA"},
- {55, "EM_PCP"},
- {56, "EM_NCPU"},
- {57, "EM_NDR1"},
- {58, "EM_STARCORE"},
- {59, "EM_ME16"},
- {60, "EM_ST100"},
- {61, "EM_TINYJ"},
- {62, "EM_X86_64"},
- {63, "EM_PDSP"},
- {64, "EM_PDP10"},
- {65, "EM_PDP11"},
- {66, "EM_FX66"},
- {67, "EM_ST9PLUS"},
- {68, "EM_ST7"},
- {69, "EM_68HC16"},
- {70, "EM_68HC11"},
- {71, "EM_68HC08"},
- {72, "EM_68HC05"},
- {73, "EM_SVX"},
- {74, "EM_ST19"},
- {75, "EM_VAX"},
- {76, "EM_CRIS"},
- {77, "EM_JAVELIN"},
- {78, "EM_FIREPATH"},
- {79, "EM_ZSP"},
- {80, "EM_MMIX"},
- {81, "EM_HUANY"},
- {82, "EM_PRISM"},
- {83, "EM_AVR"},
- {84, "EM_FR30"},
- {85, "EM_D10V"},
- {86, "EM_D30V"},
- {87, "EM_V850"},
- {88, "EM_M32R"},
- {89, "EM_MN10300"},
- {90, "EM_MN10200"},
- {91, "EM_PJ"},
- {92, "EM_OPENRISC"},
- {93, "EM_ARC_COMPACT"},
- {94, "EM_XTENSA"},
- {95, "EM_VIDEOCORE"},
- {96, "EM_TMM_GPP"},
- {97, "EM_NS32K"},
- {98, "EM_TPC"},
- {99, "EM_SNP1K"},
- {100, "EM_ST200"},
- {101, "EM_IP2K"},
- {102, "EM_MAX"},
- {103, "EM_CR"},
- {104, "EM_F2MC16"},
- {105, "EM_MSP430"},
- {106, "EM_BLACKFIN"},
- {107, "EM_SE_C33"},
- {108, "EM_SEP"},
- {109, "EM_ARCA"},
- {110, "EM_UNICORE"},
- {111, "EM_EXCESS"},
- {112, "EM_DXP"},
- {113, "EM_ALTERA_NIOS2"},
- {114, "EM_CRX"},
- {115, "EM_XGATE"},
- {116, "EM_C166"},
- {117, "EM_M16C"},
- {118, "EM_DSPIC30F"},
- {119, "EM_CE"},
- {120, "EM_M32C"},
- {131, "EM_TSK3000"},
- {132, "EM_RS08"},
- {133, "EM_SHARC"},
- {134, "EM_ECOG2"},
- {135, "EM_SCORE7"},
- {136, "EM_DSP24"},
- {137, "EM_VIDEOCORE3"},
- {138, "EM_LATTICEMICO32"},
- {139, "EM_SE_C17"},
- {140, "EM_TI_C6000"},
- {141, "EM_TI_C2000"},
- {142, "EM_TI_C5500"},
- {143, "EM_TI_ARP32"},
- {144, "EM_TI_PRU"},
- {160, "EM_MMDSP_PLUS"},
- {161, "EM_CYPRESS_M8C"},
- {162, "EM_R32C"},
- {163, "EM_TRIMEDIA"},
- {164, "EM_QDSP6"},
- {165, "EM_8051"},
- {166, "EM_STXP7X"},
- {167, "EM_NDS32"},
- {168, "EM_ECOG1"},
- {168, "EM_ECOG1X"},
- {169, "EM_MAXQ30"},
- {170, "EM_XIMO16"},
- {171, "EM_MANIK"},
- {172, "EM_CRAYNV2"},
- {173, "EM_RX"},
- {174, "EM_METAG"},
- {175, "EM_MCST_ELBRUS"},
- {176, "EM_ECOG16"},
- {177, "EM_CR16"},
- {178, "EM_ETPU"},
- {179, "EM_SLE9X"},
- {180, "EM_L10M"},
- {181, "EM_K10M"},
- {183, "EM_AARCH64"},
- {185, "EM_AVR32"},
- {186, "EM_STM8"},
- {187, "EM_TILE64"},
- {188, "EM_TILEPRO"},
- {189, "EM_MICROBLAZE"},
- {190, "EM_CUDA"},
- {191, "EM_TILEGX"},
- {192, "EM_CLOUDSHIELD"},
- {193, "EM_COREA_1ST"},
- {194, "EM_COREA_2ND"},
- {195, "EM_ARC_COMPACT2"},
- {196, "EM_OPEN8"},
- {197, "EM_RL78"},
- {198, "EM_VIDEOCORE5"},
- {199, "EM_78KOR"},
- {200, "EM_56800EX"},
- {201, "EM_BA1"},
- {202, "EM_BA2"},
- {203, "EM_XCORE"},
- {204, "EM_MCHP_PIC"},
- {205, "EM_INTEL205"},
- {206, "EM_INTEL206"},
- {207, "EM_INTEL207"},
- {208, "EM_INTEL208"},
- {209, "EM_INTEL209"},
- {210, "EM_KM32"},
- {211, "EM_KMX32"},
- {212, "EM_KMX16"},
- {213, "EM_KMX8"},
- {214, "EM_KVARC"},
- {215, "EM_CDP"},
- {216, "EM_COGE"},
- {217, "EM_COOL"},
- {218, "EM_NORC"},
- {219, "EM_CSR_KALIMBA "},
- {220, "EM_Z80 "},
- {221, "EM_VISIUM "},
- {222, "EM_FT32 "},
- {223, "EM_MOXIE"},
- {224, "EM_AMDGPU"},
- {243, "EM_RISCV"},
- {244, "EM_LANAI"},
- {247, "EM_BPF"},
- {258, "EM_LOONGARCH"},
-
- /* Non-standard or deprecated. */
- {6, "EM_486"},
- {10, "EM_MIPS_RS4_BE"},
- {41, "EM_ALPHA_STD"},
- {0x9026, "EM_ALPHA"},
-}
-
-func (i Machine) String() string { return stringName(uint32(i), machineStrings, false) }
-func (i Machine) GoString() string { return stringName(uint32(i), machineStrings, true) }
-
-// Special section indices.
-type SectionIndex int
-
-const (
- SHN_UNDEF SectionIndex = 0 /* Undefined, missing, irrelevant. */
- SHN_LORESERVE SectionIndex = 0xff00 /* First of reserved range. */
- SHN_LOPROC SectionIndex = 0xff00 /* First processor-specific. */
- SHN_HIPROC SectionIndex = 0xff1f /* Last processor-specific. */
- SHN_LOOS SectionIndex = 0xff20 /* First operating system-specific. */
- SHN_HIOS SectionIndex = 0xff3f /* Last operating system-specific. */
- SHN_ABS SectionIndex = 0xfff1 /* Absolute values. */
- SHN_COMMON SectionIndex = 0xfff2 /* Common data. */
- SHN_XINDEX SectionIndex = 0xffff /* Escape; index stored elsewhere. */
- SHN_HIRESERVE SectionIndex = 0xffff /* Last of reserved range. */
-)
-
-var shnStrings = []intName{
- {0, "SHN_UNDEF"},
- {0xff00, "SHN_LOPROC"},
- {0xff20, "SHN_LOOS"},
- {0xfff1, "SHN_ABS"},
- {0xfff2, "SHN_COMMON"},
- {0xffff, "SHN_XINDEX"},
-}
-
-func (i SectionIndex) String() string { return stringName(uint32(i), shnStrings, false) }
-func (i SectionIndex) GoString() string { return stringName(uint32(i), shnStrings, true) }
-
-// Section type.
-type SectionType uint32
-
-const (
- SHT_NULL SectionType = 0 /* inactive */
- SHT_PROGBITS SectionType = 1 /* program defined information */
- SHT_SYMTAB SectionType = 2 /* symbol table section */
- SHT_STRTAB SectionType = 3 /* string table section */
- SHT_RELA SectionType = 4 /* relocation section with addends */
- SHT_HASH SectionType = 5 /* symbol hash table section */
- SHT_DYNAMIC SectionType = 6 /* dynamic section */
- SHT_NOTE SectionType = 7 /* note section */
- SHT_NOBITS SectionType = 8 /* no space section */
- SHT_REL SectionType = 9 /* relocation section - no addends */
- SHT_SHLIB SectionType = 10 /* reserved - purpose unknown */
- SHT_DYNSYM SectionType = 11 /* dynamic symbol table section */
- SHT_INIT_ARRAY SectionType = 14 /* Initialization function pointers. */
- SHT_FINI_ARRAY SectionType = 15 /* Termination function pointers. */
- SHT_PREINIT_ARRAY SectionType = 16 /* Pre-initialization function ptrs. */
- SHT_GROUP SectionType = 17 /* Section group. */
- SHT_SYMTAB_SHNDX SectionType = 18 /* Section indexes (see SHN_XINDEX). */
- SHT_LOOS SectionType = 0x60000000 /* First of OS specific semantics */
- SHT_GNU_ATTRIBUTES SectionType = 0x6ffffff5 /* GNU object attributes */
- SHT_GNU_HASH SectionType = 0x6ffffff6 /* GNU hash table */
- SHT_GNU_LIBLIST SectionType = 0x6ffffff7 /* GNU prelink library list */
- SHT_GNU_VERDEF SectionType = 0x6ffffffd /* GNU version definition section */
- SHT_GNU_VERNEED SectionType = 0x6ffffffe /* GNU version needs section */
- SHT_GNU_VERSYM SectionType = 0x6fffffff /* GNU version symbol table */
- SHT_HIOS SectionType = 0x6fffffff /* Last of OS specific semantics */
- SHT_LOPROC SectionType = 0x70000000 /* reserved range for processor */
- SHT_MIPS_ABIFLAGS SectionType = 0x7000002a /* .MIPS.abiflags */
- SHT_HIPROC SectionType = 0x7fffffff /* specific section header types */
- SHT_LOUSER SectionType = 0x80000000 /* reserved range for application */
- SHT_HIUSER SectionType = 0xffffffff /* specific indexes */
-)
-
-var shtStrings = []intName{
- {0, "SHT_NULL"},
- {1, "SHT_PROGBITS"},
- {2, "SHT_SYMTAB"},
- {3, "SHT_STRTAB"},
- {4, "SHT_RELA"},
- {5, "SHT_HASH"},
- {6, "SHT_DYNAMIC"},
- {7, "SHT_NOTE"},
- {8, "SHT_NOBITS"},
- {9, "SHT_REL"},
- {10, "SHT_SHLIB"},
- {11, "SHT_DYNSYM"},
- {14, "SHT_INIT_ARRAY"},
- {15, "SHT_FINI_ARRAY"},
- {16, "SHT_PREINIT_ARRAY"},
- {17, "SHT_GROUP"},
- {18, "SHT_SYMTAB_SHNDX"},
- {0x60000000, "SHT_LOOS"},
- {0x6ffffff5, "SHT_GNU_ATTRIBUTES"},
- {0x6ffffff6, "SHT_GNU_HASH"},
- {0x6ffffff7, "SHT_GNU_LIBLIST"},
- {0x6ffffffd, "SHT_GNU_VERDEF"},
- {0x6ffffffe, "SHT_GNU_VERNEED"},
- {0x6fffffff, "SHT_GNU_VERSYM"},
- {0x70000000, "SHT_LOPROC"},
- {0x7000002a, "SHT_MIPS_ABIFLAGS"},
- {0x7fffffff, "SHT_HIPROC"},
- {0x80000000, "SHT_LOUSER"},
- {0xffffffff, "SHT_HIUSER"},
-}
-
-func (i SectionType) String() string { return stringName(uint32(i), shtStrings, false) }
-func (i SectionType) GoString() string { return stringName(uint32(i), shtStrings, true) }
-
-// Section flags.
-type SectionFlag uint32
-
-const (
- SHF_WRITE SectionFlag = 0x1 /* Section contains writable data. */
- SHF_ALLOC SectionFlag = 0x2 /* Section occupies memory. */
- SHF_EXECINSTR SectionFlag = 0x4 /* Section contains instructions. */
- SHF_MERGE SectionFlag = 0x10 /* Section may be merged. */
- SHF_STRINGS SectionFlag = 0x20 /* Section contains strings. */
- SHF_INFO_LINK SectionFlag = 0x40 /* sh_info holds section index. */
- SHF_LINK_ORDER SectionFlag = 0x80 /* Special ordering requirements. */
- SHF_OS_NONCONFORMING SectionFlag = 0x100 /* OS-specific processing required. */
- SHF_GROUP SectionFlag = 0x200 /* Member of section group. */
- SHF_TLS SectionFlag = 0x400 /* Section contains TLS data. */
- SHF_COMPRESSED SectionFlag = 0x800 /* Section is compressed. */
- SHF_MASKOS SectionFlag = 0x0ff00000 /* OS-specific semantics. */
- SHF_MASKPROC SectionFlag = 0xf0000000 /* Processor-specific semantics. */
-)
-
-var shfStrings = []intName{
- {0x1, "SHF_WRITE"},
- {0x2, "SHF_ALLOC"},
- {0x4, "SHF_EXECINSTR"},
- {0x10, "SHF_MERGE"},
- {0x20, "SHF_STRINGS"},
- {0x40, "SHF_INFO_LINK"},
- {0x80, "SHF_LINK_ORDER"},
- {0x100, "SHF_OS_NONCONFORMING"},
- {0x200, "SHF_GROUP"},
- {0x400, "SHF_TLS"},
- {0x800, "SHF_COMPRESSED"},
-}
-
-func (i SectionFlag) String() string { return flagName(uint32(i), shfStrings, false) }
-func (i SectionFlag) GoString() string { return flagName(uint32(i), shfStrings, true) }
-
-// Section compression type.
-type CompressionType int
-
-const (
- COMPRESS_ZLIB CompressionType = 1 /* ZLIB compression. */
- COMPRESS_LOOS CompressionType = 0x60000000 /* First OS-specific. */
- COMPRESS_HIOS CompressionType = 0x6fffffff /* Last OS-specific. */
- COMPRESS_LOPROC CompressionType = 0x70000000 /* First processor-specific type. */
- COMPRESS_HIPROC CompressionType = 0x7fffffff /* Last processor-specific type. */
-)
-
-var compressionStrings = []intName{
- {1, "COMPRESS_ZLIB"},
- {0x60000000, "COMPRESS_LOOS"},
- {0x6fffffff, "COMPRESS_HIOS"},
- {0x70000000, "COMPRESS_LOPROC"},
- {0x7fffffff, "COMPRESS_HIPROC"},
-}
-
-func (i CompressionType) String() string { return stringName(uint32(i), compressionStrings, false) }
-func (i CompressionType) GoString() string { return stringName(uint32(i), compressionStrings, true) }
-
-// Prog.Type
-type ProgType int
-
-const (
- PT_NULL ProgType = 0 /* Unused entry. */
- PT_LOAD ProgType = 1 /* Loadable segment. */
- PT_DYNAMIC ProgType = 2 /* Dynamic linking information segment. */
- PT_INTERP ProgType = 3 /* Pathname of interpreter. */
- PT_NOTE ProgType = 4 /* Auxiliary information. */
- PT_SHLIB ProgType = 5 /* Reserved (not used). */
- PT_PHDR ProgType = 6 /* Location of program header itself. */
- PT_TLS ProgType = 7 /* Thread local storage segment */
-
- PT_LOOS ProgType = 0x60000000 /* First OS-specific. */
-
- PT_GNU_EH_FRAME ProgType = 0x6474e550 /* Frame unwind information */
- PT_GNU_STACK ProgType = 0x6474e551 /* Stack flags */
- PT_GNU_RELRO ProgType = 0x6474e552 /* Read only after relocs */
- PT_GNU_PROPERTY ProgType = 0x6474e553 /* GNU property */
- PT_GNU_MBIND_LO ProgType = 0x6474e555 /* Mbind segments start */
- PT_GNU_MBIND_HI ProgType = 0x6474f554 /* Mbind segments finish */
-
- PT_PAX_FLAGS ProgType = 0x65041580 /* PAX flags */
-
- PT_OPENBSD_RANDOMIZE ProgType = 0x65a3dbe6 /* Random data */
- PT_OPENBSD_WXNEEDED ProgType = 0x65a3dbe7 /* W^X violations */
- PT_OPENBSD_BOOTDATA ProgType = 0x65a41be6 /* Boot arguments */
-
- PT_SUNW_EH_FRAME ProgType = 0x6474e550 /* Frame unwind information */
- PT_SUNWSTACK ProgType = 0x6ffffffb /* Stack segment */
-
- PT_HIOS ProgType = 0x6fffffff /* Last OS-specific. */
-
- PT_LOPROC ProgType = 0x70000000 /* First processor-specific type. */
-
- PT_ARM_ARCHEXT ProgType = 0x70000000 /* Architecture compatibility */
- PT_ARM_EXIDX ProgType = 0x70000001 /* Exception unwind tables */
-
- PT_AARCH64_ARCHEXT ProgType = 0x70000000 /* Architecture compatibility */
- PT_AARCH64_UNWIND ProgType = 0x70000001 /* Exception unwind tables */
-
- PT_MIPS_REGINFO ProgType = 0x70000000 /* Register usage */
- PT_MIPS_RTPROC ProgType = 0x70000001 /* Runtime procedures */
- PT_MIPS_OPTIONS ProgType = 0x70000002 /* Options */
- PT_MIPS_ABIFLAGS ProgType = 0x70000003 /* ABI flags */
-
- PT_S390_PGSTE ProgType = 0x70000000 /* 4k page table size */
-
- PT_HIPROC ProgType = 0x7fffffff /* Last processor-specific type. */
-)
-
-var ptStrings = []intName{
- {0, "PT_NULL"},
- {1, "PT_LOAD"},
- {2, "PT_DYNAMIC"},
- {3, "PT_INTERP"},
- {4, "PT_NOTE"},
- {5, "PT_SHLIB"},
- {6, "PT_PHDR"},
- {7, "PT_TLS"},
- {0x60000000, "PT_LOOS"},
- {0x6474e550, "PT_GNU_EH_FRAME"},
- {0x6474e551, "PT_GNU_STACK"},
- {0x6474e552, "PT_GNU_RELRO"},
- {0x6474e553, "PT_GNU_PROPERTY"},
- {0x65041580, "PT_PAX_FLAGS"},
- {0x65a3dbe6, "PT_OPENBSD_RANDOMIZE"},
- {0x65a3dbe7, "PT_OPENBSD_WXNEEDED"},
- {0x65a41be6, "PT_OPENBSD_BOOTDATA"},
- {0x6ffffffb, "PT_SUNWSTACK"},
- {0x6fffffff, "PT_HIOS"},
- {0x70000000, "PT_LOPROC"},
- // We don't list the processor-dependent ProgTypes,
- // as the values overlap.
- {0x7fffffff, "PT_HIPROC"},
-}
-
-func (i ProgType) String() string { return stringName(uint32(i), ptStrings, false) }
-func (i ProgType) GoString() string { return stringName(uint32(i), ptStrings, true) }
-
-// Prog.Flag
-type ProgFlag uint32
-
-const (
- PF_X ProgFlag = 0x1 /* Executable. */
- PF_W ProgFlag = 0x2 /* Writable. */
- PF_R ProgFlag = 0x4 /* Readable. */
- PF_MASKOS ProgFlag = 0x0ff00000 /* Operating system-specific. */
- PF_MASKPROC ProgFlag = 0xf0000000 /* Processor-specific. */
-)
-
-var pfStrings = []intName{
- {0x1, "PF_X"},
- {0x2, "PF_W"},
- {0x4, "PF_R"},
-}
-
-func (i ProgFlag) String() string { return flagName(uint32(i), pfStrings, false) }
-func (i ProgFlag) GoString() string { return flagName(uint32(i), pfStrings, true) }
-
-// Dyn.Tag
-type DynTag int
-
-const (
- DT_NULL DynTag = 0 /* Terminating entry. */
- DT_NEEDED DynTag = 1 /* String table offset of a needed shared library. */
- DT_PLTRELSZ DynTag = 2 /* Total size in bytes of PLT relocations. */
- DT_PLTGOT DynTag = 3 /* Processor-dependent address. */
- DT_HASH DynTag = 4 /* Address of symbol hash table. */
- DT_STRTAB DynTag = 5 /* Address of string table. */
- DT_SYMTAB DynTag = 6 /* Address of symbol table. */
- DT_RELA DynTag = 7 /* Address of ElfNN_Rela relocations. */
- DT_RELASZ DynTag = 8 /* Total size of ElfNN_Rela relocations. */
- DT_RELAENT DynTag = 9 /* Size of each ElfNN_Rela relocation entry. */
- DT_STRSZ DynTag = 10 /* Size of string table. */
- DT_SYMENT DynTag = 11 /* Size of each symbol table entry. */
- DT_INIT DynTag = 12 /* Address of initialization function. */
- DT_FINI DynTag = 13 /* Address of finalization function. */
- DT_SONAME DynTag = 14 /* String table offset of shared object name. */
- DT_RPATH DynTag = 15 /* String table offset of library path. [sup] */
- DT_SYMBOLIC DynTag = 16 /* Indicates "symbolic" linking. [sup] */
- DT_REL DynTag = 17 /* Address of ElfNN_Rel relocations. */
- DT_RELSZ DynTag = 18 /* Total size of ElfNN_Rel relocations. */
- DT_RELENT DynTag = 19 /* Size of each ElfNN_Rel relocation. */
- DT_PLTREL DynTag = 20 /* Type of relocation used for PLT. */
- DT_DEBUG DynTag = 21 /* Reserved (not used). */
- DT_TEXTREL DynTag = 22 /* Indicates there may be relocations in non-writable segments. [sup] */
- DT_JMPREL DynTag = 23 /* Address of PLT relocations. */
- DT_BIND_NOW DynTag = 24 /* [sup] */
- DT_INIT_ARRAY DynTag = 25 /* Address of the array of pointers to initialization functions */
- DT_FINI_ARRAY DynTag = 26 /* Address of the array of pointers to termination functions */
- DT_INIT_ARRAYSZ DynTag = 27 /* Size in bytes of the array of initialization functions. */
- DT_FINI_ARRAYSZ DynTag = 28 /* Size in bytes of the array of termination functions. */
- DT_RUNPATH DynTag = 29 /* String table offset of a null-terminated library search path string. */
- DT_FLAGS DynTag = 30 /* Object specific flag values. */
- DT_ENCODING DynTag = 32 /* Values greater than or equal to DT_ENCODING
- and less than DT_LOOS follow the rules for
- the interpretation of the d_un union
- as follows: even == 'd_ptr', even == 'd_val'
- or none */
- DT_PREINIT_ARRAY DynTag = 32 /* Address of the array of pointers to pre-initialization functions. */
- DT_PREINIT_ARRAYSZ DynTag = 33 /* Size in bytes of the array of pre-initialization functions. */
- DT_SYMTAB_SHNDX DynTag = 34 /* Address of SHT_SYMTAB_SHNDX section. */
-
- DT_LOOS DynTag = 0x6000000d /* First OS-specific */
- DT_HIOS DynTag = 0x6ffff000 /* Last OS-specific */
-
- DT_VALRNGLO DynTag = 0x6ffffd00
- DT_GNU_PRELINKED DynTag = 0x6ffffdf5
- DT_GNU_CONFLICTSZ DynTag = 0x6ffffdf6
- DT_GNU_LIBLISTSZ DynTag = 0x6ffffdf7
- DT_CHECKSUM DynTag = 0x6ffffdf8
- DT_PLTPADSZ DynTag = 0x6ffffdf9
- DT_MOVEENT DynTag = 0x6ffffdfa
- DT_MOVESZ DynTag = 0x6ffffdfb
- DT_FEATURE DynTag = 0x6ffffdfc
- DT_POSFLAG_1 DynTag = 0x6ffffdfd
- DT_SYMINSZ DynTag = 0x6ffffdfe
- DT_SYMINENT DynTag = 0x6ffffdff
- DT_VALRNGHI DynTag = 0x6ffffdff
-
- DT_ADDRRNGLO DynTag = 0x6ffffe00
- DT_GNU_HASH DynTag = 0x6ffffef5
- DT_TLSDESC_PLT DynTag = 0x6ffffef6
- DT_TLSDESC_GOT DynTag = 0x6ffffef7
- DT_GNU_CONFLICT DynTag = 0x6ffffef8
- DT_GNU_LIBLIST DynTag = 0x6ffffef9
- DT_CONFIG DynTag = 0x6ffffefa
- DT_DEPAUDIT DynTag = 0x6ffffefb
- DT_AUDIT DynTag = 0x6ffffefc
- DT_PLTPAD DynTag = 0x6ffffefd
- DT_MOVETAB DynTag = 0x6ffffefe
- DT_SYMINFO DynTag = 0x6ffffeff
- DT_ADDRRNGHI DynTag = 0x6ffffeff
-
- DT_VERSYM DynTag = 0x6ffffff0
- DT_RELACOUNT DynTag = 0x6ffffff9
- DT_RELCOUNT DynTag = 0x6ffffffa
- DT_FLAGS_1 DynTag = 0x6ffffffb
- DT_VERDEF DynTag = 0x6ffffffc
- DT_VERDEFNUM DynTag = 0x6ffffffd
- DT_VERNEED DynTag = 0x6ffffffe
- DT_VERNEEDNUM DynTag = 0x6fffffff
-
- DT_LOPROC DynTag = 0x70000000 /* First processor-specific type. */
-
- DT_MIPS_RLD_VERSION DynTag = 0x70000001
- DT_MIPS_TIME_STAMP DynTag = 0x70000002
- DT_MIPS_ICHECKSUM DynTag = 0x70000003
- DT_MIPS_IVERSION DynTag = 0x70000004
- DT_MIPS_FLAGS DynTag = 0x70000005
- DT_MIPS_BASE_ADDRESS DynTag = 0x70000006
- DT_MIPS_MSYM DynTag = 0x70000007
- DT_MIPS_CONFLICT DynTag = 0x70000008
- DT_MIPS_LIBLIST DynTag = 0x70000009
- DT_MIPS_LOCAL_GOTNO DynTag = 0x7000000a
- DT_MIPS_CONFLICTNO DynTag = 0x7000000b
- DT_MIPS_LIBLISTNO DynTag = 0x70000010
- DT_MIPS_SYMTABNO DynTag = 0x70000011
- DT_MIPS_UNREFEXTNO DynTag = 0x70000012
- DT_MIPS_GOTSYM DynTag = 0x70000013
- DT_MIPS_HIPAGENO DynTag = 0x70000014
- DT_MIPS_RLD_MAP DynTag = 0x70000016
- DT_MIPS_DELTA_CLASS DynTag = 0x70000017
- DT_MIPS_DELTA_CLASS_NO DynTag = 0x70000018
- DT_MIPS_DELTA_INSTANCE DynTag = 0x70000019
- DT_MIPS_DELTA_INSTANCE_NO DynTag = 0x7000001a
- DT_MIPS_DELTA_RELOC DynTag = 0x7000001b
- DT_MIPS_DELTA_RELOC_NO DynTag = 0x7000001c
- DT_MIPS_DELTA_SYM DynTag = 0x7000001d
- DT_MIPS_DELTA_SYM_NO DynTag = 0x7000001e
- DT_MIPS_DELTA_CLASSSYM DynTag = 0x70000020
- DT_MIPS_DELTA_CLASSSYM_NO DynTag = 0x70000021
- DT_MIPS_CXX_FLAGS DynTag = 0x70000022
- DT_MIPS_PIXIE_INIT DynTag = 0x70000023
- DT_MIPS_SYMBOL_LIB DynTag = 0x70000024
- DT_MIPS_LOCALPAGE_GOTIDX DynTag = 0x70000025
- DT_MIPS_LOCAL_GOTIDX DynTag = 0x70000026
- DT_MIPS_HIDDEN_GOTIDX DynTag = 0x70000027
- DT_MIPS_PROTECTED_GOTIDX DynTag = 0x70000028
- DT_MIPS_OPTIONS DynTag = 0x70000029
- DT_MIPS_INTERFACE DynTag = 0x7000002a
- DT_MIPS_DYNSTR_ALIGN DynTag = 0x7000002b
- DT_MIPS_INTERFACE_SIZE DynTag = 0x7000002c
- DT_MIPS_RLD_TEXT_RESOLVE_ADDR DynTag = 0x7000002d
- DT_MIPS_PERF_SUFFIX DynTag = 0x7000002e
- DT_MIPS_COMPACT_SIZE DynTag = 0x7000002f
- DT_MIPS_GP_VALUE DynTag = 0x70000030
- DT_MIPS_AUX_DYNAMIC DynTag = 0x70000031
- DT_MIPS_PLTGOT DynTag = 0x70000032
- DT_MIPS_RWPLT DynTag = 0x70000034
- DT_MIPS_RLD_MAP_REL DynTag = 0x70000035
-
- DT_PPC_GOT DynTag = 0x70000000
- DT_PPC_OPT DynTag = 0x70000001
-
- DT_PPC64_GLINK DynTag = 0x70000000
- DT_PPC64_OPD DynTag = 0x70000001
- DT_PPC64_OPDSZ DynTag = 0x70000002
- DT_PPC64_OPT DynTag = 0x70000003
-
- DT_SPARC_REGISTER DynTag = 0x70000001
-
- DT_AUXILIARY DynTag = 0x7ffffffd
- DT_USED DynTag = 0x7ffffffe
- DT_FILTER DynTag = 0x7fffffff
-
- DT_HIPROC DynTag = 0x7fffffff /* Last processor-specific type. */
-)
-
-var dtStrings = []intName{
- {0, "DT_NULL"},
- {1, "DT_NEEDED"},
- {2, "DT_PLTRELSZ"},
- {3, "DT_PLTGOT"},
- {4, "DT_HASH"},
- {5, "DT_STRTAB"},
- {6, "DT_SYMTAB"},
- {7, "DT_RELA"},
- {8, "DT_RELASZ"},
- {9, "DT_RELAENT"},
- {10, "DT_STRSZ"},
- {11, "DT_SYMENT"},
- {12, "DT_INIT"},
- {13, "DT_FINI"},
- {14, "DT_SONAME"},
- {15, "DT_RPATH"},
- {16, "DT_SYMBOLIC"},
- {17, "DT_REL"},
- {18, "DT_RELSZ"},
- {19, "DT_RELENT"},
- {20, "DT_PLTREL"},
- {21, "DT_DEBUG"},
- {22, "DT_TEXTREL"},
- {23, "DT_JMPREL"},
- {24, "DT_BIND_NOW"},
- {25, "DT_INIT_ARRAY"},
- {26, "DT_FINI_ARRAY"},
- {27, "DT_INIT_ARRAYSZ"},
- {28, "DT_FINI_ARRAYSZ"},
- {29, "DT_RUNPATH"},
- {30, "DT_FLAGS"},
- {32, "DT_ENCODING"},
- {32, "DT_PREINIT_ARRAY"},
- {33, "DT_PREINIT_ARRAYSZ"},
- {34, "DT_SYMTAB_SHNDX"},
- {0x6000000d, "DT_LOOS"},
- {0x6ffff000, "DT_HIOS"},
- {0x6ffffd00, "DT_VALRNGLO"},
- {0x6ffffdf5, "DT_GNU_PRELINKED"},
- {0x6ffffdf6, "DT_GNU_CONFLICTSZ"},
- {0x6ffffdf7, "DT_GNU_LIBLISTSZ"},
- {0x6ffffdf8, "DT_CHECKSUM"},
- {0x6ffffdf9, "DT_PLTPADSZ"},
- {0x6ffffdfa, "DT_MOVEENT"},
- {0x6ffffdfb, "DT_MOVESZ"},
- {0x6ffffdfc, "DT_FEATURE"},
- {0x6ffffdfd, "DT_POSFLAG_1"},
- {0x6ffffdfe, "DT_SYMINSZ"},
- {0x6ffffdff, "DT_SYMINENT"},
- {0x6ffffdff, "DT_VALRNGHI"},
- {0x6ffffe00, "DT_ADDRRNGLO"},
- {0x6ffffef5, "DT_GNU_HASH"},
- {0x6ffffef6, "DT_TLSDESC_PLT"},
- {0x6ffffef7, "DT_TLSDESC_GOT"},
- {0x6ffffef8, "DT_GNU_CONFLICT"},
- {0x6ffffef9, "DT_GNU_LIBLIST"},
- {0x6ffffefa, "DT_CONFIG"},
- {0x6ffffefb, "DT_DEPAUDIT"},
- {0x6ffffefc, "DT_AUDIT"},
- {0x6ffffefd, "DT_PLTPAD"},
- {0x6ffffefe, "DT_MOVETAB"},
- {0x6ffffeff, "DT_SYMINFO"},
- {0x6ffffeff, "DT_ADDRRNGHI"},
- {0x6ffffff0, "DT_VERSYM"},
- {0x6ffffff9, "DT_RELACOUNT"},
- {0x6ffffffa, "DT_RELCOUNT"},
- {0x6ffffffb, "DT_FLAGS_1"},
- {0x6ffffffc, "DT_VERDEF"},
- {0x6ffffffd, "DT_VERDEFNUM"},
- {0x6ffffffe, "DT_VERNEED"},
- {0x6fffffff, "DT_VERNEEDNUM"},
- {0x70000000, "DT_LOPROC"},
- // We don't list the processor-dependent DynTags,
- // as the values overlap.
- {0x7ffffffd, "DT_AUXILIARY"},
- {0x7ffffffe, "DT_USED"},
- {0x7fffffff, "DT_FILTER"},
-}
-
-func (i DynTag) String() string { return stringName(uint32(i), dtStrings, false) }
-func (i DynTag) GoString() string { return stringName(uint32(i), dtStrings, true) }
-
-// DT_FLAGS values.
-type DynFlag int
-
-const (
- DF_ORIGIN DynFlag = 0x0001 /* Indicates that the object being loaded may
- make reference to the
- $ORIGIN substitution string */
- DF_SYMBOLIC DynFlag = 0x0002 /* Indicates "symbolic" linking. */
- DF_TEXTREL DynFlag = 0x0004 /* Indicates there may be relocations in non-writable segments. */
- DF_BIND_NOW DynFlag = 0x0008 /* Indicates that the dynamic linker should
- process all relocations for the object
- containing this entry before transferring
- control to the program. */
- DF_STATIC_TLS DynFlag = 0x0010 /* Indicates that the shared object or
- executable contains code using a static
- thread-local storage scheme. */
-)
-
-var dflagStrings = []intName{
- {0x0001, "DF_ORIGIN"},
- {0x0002, "DF_SYMBOLIC"},
- {0x0004, "DF_TEXTREL"},
- {0x0008, "DF_BIND_NOW"},
- {0x0010, "DF_STATIC_TLS"},
-}
-
-func (i DynFlag) String() string { return flagName(uint32(i), dflagStrings, false) }
-func (i DynFlag) GoString() string { return flagName(uint32(i), dflagStrings, true) }
-
-// NType values; used in core files.
-type NType int
-
-const (
- NT_PRSTATUS NType = 1 /* Process status. */
- NT_FPREGSET NType = 2 /* Floating point registers. */
- NT_PRPSINFO NType = 3 /* Process state info. */
-)
-
-var ntypeStrings = []intName{
- {1, "NT_PRSTATUS"},
- {2, "NT_FPREGSET"},
- {3, "NT_PRPSINFO"},
-}
-
-func (i NType) String() string { return stringName(uint32(i), ntypeStrings, false) }
-func (i NType) GoString() string { return stringName(uint32(i), ntypeStrings, true) }
-
-/* Symbol Binding - ELFNN_ST_BIND - st_info */
-type SymBind int
-
-const (
- STB_LOCAL SymBind = 0 /* Local symbol */
- STB_GLOBAL SymBind = 1 /* Global symbol */
- STB_WEAK SymBind = 2 /* like global - lower precedence */
- STB_LOOS SymBind = 10 /* Reserved range for operating system */
- STB_HIOS SymBind = 12 /* specific semantics. */
- STB_LOPROC SymBind = 13 /* reserved range for processor */
- STB_HIPROC SymBind = 15 /* specific semantics. */
-)
-
-var stbStrings = []intName{
- {0, "STB_LOCAL"},
- {1, "STB_GLOBAL"},
- {2, "STB_WEAK"},
- {10, "STB_LOOS"},
- {12, "STB_HIOS"},
- {13, "STB_LOPROC"},
- {15, "STB_HIPROC"},
-}
-
-func (i SymBind) String() string { return stringName(uint32(i), stbStrings, false) }
-func (i SymBind) GoString() string { return stringName(uint32(i), stbStrings, true) }
-
-/* Symbol type - ELFNN_ST_TYPE - st_info */
-type SymType int
-
-const (
- STT_NOTYPE SymType = 0 /* Unspecified type. */
- STT_OBJECT SymType = 1 /* Data object. */
- STT_FUNC SymType = 2 /* Function. */
- STT_SECTION SymType = 3 /* Section. */
- STT_FILE SymType = 4 /* Source file. */
- STT_COMMON SymType = 5 /* Uninitialized common block. */
- STT_TLS SymType = 6 /* TLS object. */
- STT_LOOS SymType = 10 /* Reserved range for operating system */
- STT_HIOS SymType = 12 /* specific semantics. */
- STT_LOPROC SymType = 13 /* reserved range for processor */
- STT_HIPROC SymType = 15 /* specific semantics. */
-)
-
-var sttStrings = []intName{
- {0, "STT_NOTYPE"},
- {1, "STT_OBJECT"},
- {2, "STT_FUNC"},
- {3, "STT_SECTION"},
- {4, "STT_FILE"},
- {5, "STT_COMMON"},
- {6, "STT_TLS"},
- {10, "STT_LOOS"},
- {12, "STT_HIOS"},
- {13, "STT_LOPROC"},
- {15, "STT_HIPROC"},
-}
-
-func (i SymType) String() string { return stringName(uint32(i), sttStrings, false) }
-func (i SymType) GoString() string { return stringName(uint32(i), sttStrings, true) }
-
-/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
-type SymVis int
-
-const (
- STV_DEFAULT SymVis = 0x0 /* Default visibility (see binding). */
- STV_INTERNAL SymVis = 0x1 /* Special meaning in relocatable objects. */
- STV_HIDDEN SymVis = 0x2 /* Not visible. */
- STV_PROTECTED SymVis = 0x3 /* Visible but not preemptible. */
-)
-
-var stvStrings = []intName{
- {0x0, "STV_DEFAULT"},
- {0x1, "STV_INTERNAL"},
- {0x2, "STV_HIDDEN"},
- {0x3, "STV_PROTECTED"},
-}
-
-func (i SymVis) String() string { return stringName(uint32(i), stvStrings, false) }
-func (i SymVis) GoString() string { return stringName(uint32(i), stvStrings, true) }
-
-/*
- * Relocation types.
- */
-
-// Relocation types for x86-64.
-type R_X86_64 int
-
-const (
- R_X86_64_NONE R_X86_64 = 0 /* No relocation. */
- R_X86_64_64 R_X86_64 = 1 /* Add 64 bit symbol value. */
- R_X86_64_PC32 R_X86_64 = 2 /* PC-relative 32 bit signed sym value. */
- R_X86_64_GOT32 R_X86_64 = 3 /* PC-relative 32 bit GOT offset. */
- R_X86_64_PLT32 R_X86_64 = 4 /* PC-relative 32 bit PLT offset. */
- R_X86_64_COPY R_X86_64 = 5 /* Copy data from shared object. */
- R_X86_64_GLOB_DAT R_X86_64 = 6 /* Set GOT entry to data address. */
- R_X86_64_JMP_SLOT R_X86_64 = 7 /* Set GOT entry to code address. */
- R_X86_64_RELATIVE R_X86_64 = 8 /* Add load address of shared object. */
- R_X86_64_GOTPCREL R_X86_64 = 9 /* Add 32 bit signed pcrel offset to GOT. */
- R_X86_64_32 R_X86_64 = 10 /* Add 32 bit zero extended symbol value */
- R_X86_64_32S R_X86_64 = 11 /* Add 32 bit sign extended symbol value */
- R_X86_64_16 R_X86_64 = 12 /* Add 16 bit zero extended symbol value */
- R_X86_64_PC16 R_X86_64 = 13 /* Add 16 bit signed extended pc relative symbol value */
- R_X86_64_8 R_X86_64 = 14 /* Add 8 bit zero extended symbol value */
- R_X86_64_PC8 R_X86_64 = 15 /* Add 8 bit signed extended pc relative symbol value */
- R_X86_64_DTPMOD64 R_X86_64 = 16 /* ID of module containing symbol */
- R_X86_64_DTPOFF64 R_X86_64 = 17 /* Offset in TLS block */
- R_X86_64_TPOFF64 R_X86_64 = 18 /* Offset in static TLS block */
- R_X86_64_TLSGD R_X86_64 = 19 /* PC relative offset to GD GOT entry */
- R_X86_64_TLSLD R_X86_64 = 20 /* PC relative offset to LD GOT entry */
- R_X86_64_DTPOFF32 R_X86_64 = 21 /* Offset in TLS block */
- R_X86_64_GOTTPOFF R_X86_64 = 22 /* PC relative offset to IE GOT entry */
- R_X86_64_TPOFF32 R_X86_64 = 23 /* Offset in static TLS block */
- R_X86_64_PC64 R_X86_64 = 24 /* PC relative 64-bit sign extended symbol value. */
- R_X86_64_GOTOFF64 R_X86_64 = 25
- R_X86_64_GOTPC32 R_X86_64 = 26
- R_X86_64_GOT64 R_X86_64 = 27
- R_X86_64_GOTPCREL64 R_X86_64 = 28
- R_X86_64_GOTPC64 R_X86_64 = 29
- R_X86_64_GOTPLT64 R_X86_64 = 30
- R_X86_64_PLTOFF64 R_X86_64 = 31
- R_X86_64_SIZE32 R_X86_64 = 32
- R_X86_64_SIZE64 R_X86_64 = 33
- R_X86_64_GOTPC32_TLSDESC R_X86_64 = 34
- R_X86_64_TLSDESC_CALL R_X86_64 = 35
- R_X86_64_TLSDESC R_X86_64 = 36
- R_X86_64_IRELATIVE R_X86_64 = 37
- R_X86_64_RELATIVE64 R_X86_64 = 38
- R_X86_64_PC32_BND R_X86_64 = 39
- R_X86_64_PLT32_BND R_X86_64 = 40
- R_X86_64_GOTPCRELX R_X86_64 = 41
- R_X86_64_REX_GOTPCRELX R_X86_64 = 42
-)
-
-var rx86_64Strings = []intName{
- {0, "R_X86_64_NONE"},
- {1, "R_X86_64_64"},
- {2, "R_X86_64_PC32"},
- {3, "R_X86_64_GOT32"},
- {4, "R_X86_64_PLT32"},
- {5, "R_X86_64_COPY"},
- {6, "R_X86_64_GLOB_DAT"},
- {7, "R_X86_64_JMP_SLOT"},
- {8, "R_X86_64_RELATIVE"},
- {9, "R_X86_64_GOTPCREL"},
- {10, "R_X86_64_32"},
- {11, "R_X86_64_32S"},
- {12, "R_X86_64_16"},
- {13, "R_X86_64_PC16"},
- {14, "R_X86_64_8"},
- {15, "R_X86_64_PC8"},
- {16, "R_X86_64_DTPMOD64"},
- {17, "R_X86_64_DTPOFF64"},
- {18, "R_X86_64_TPOFF64"},
- {19, "R_X86_64_TLSGD"},
- {20, "R_X86_64_TLSLD"},
- {21, "R_X86_64_DTPOFF32"},
- {22, "R_X86_64_GOTTPOFF"},
- {23, "R_X86_64_TPOFF32"},
- {24, "R_X86_64_PC64"},
- {25, "R_X86_64_GOTOFF64"},
- {26, "R_X86_64_GOTPC32"},
- {27, "R_X86_64_GOT64"},
- {28, "R_X86_64_GOTPCREL64"},
- {29, "R_X86_64_GOTPC64"},
- {30, "R_X86_64_GOTPLT64"},
- {31, "R_X86_64_PLTOFF64"},
- {32, "R_X86_64_SIZE32"},
- {33, "R_X86_64_SIZE64"},
- {34, "R_X86_64_GOTPC32_TLSDESC"},
- {35, "R_X86_64_TLSDESC_CALL"},
- {36, "R_X86_64_TLSDESC"},
- {37, "R_X86_64_IRELATIVE"},
- {38, "R_X86_64_RELATIVE64"},
- {39, "R_X86_64_PC32_BND"},
- {40, "R_X86_64_PLT32_BND"},
- {41, "R_X86_64_GOTPCRELX"},
- {42, "R_X86_64_REX_GOTPCRELX"},
-}
-
-func (i R_X86_64) String() string { return stringName(uint32(i), rx86_64Strings, false) }
-func (i R_X86_64) GoString() string { return stringName(uint32(i), rx86_64Strings, true) }
-
-// Relocation types for AArch64 (aka arm64)
-type R_AARCH64 int
-
-const (
- R_AARCH64_NONE R_AARCH64 = 0
- R_AARCH64_P32_ABS32 R_AARCH64 = 1
- R_AARCH64_P32_ABS16 R_AARCH64 = 2
- R_AARCH64_P32_PREL32 R_AARCH64 = 3
- R_AARCH64_P32_PREL16 R_AARCH64 = 4
- R_AARCH64_P32_MOVW_UABS_G0 R_AARCH64 = 5
- R_AARCH64_P32_MOVW_UABS_G0_NC R_AARCH64 = 6
- R_AARCH64_P32_MOVW_UABS_G1 R_AARCH64 = 7
- R_AARCH64_P32_MOVW_SABS_G0 R_AARCH64 = 8
- R_AARCH64_P32_LD_PREL_LO19 R_AARCH64 = 9
- R_AARCH64_P32_ADR_PREL_LO21 R_AARCH64 = 10
- R_AARCH64_P32_ADR_PREL_PG_HI21 R_AARCH64 = 11
- R_AARCH64_P32_ADD_ABS_LO12_NC R_AARCH64 = 12
- R_AARCH64_P32_LDST8_ABS_LO12_NC R_AARCH64 = 13
- R_AARCH64_P32_LDST16_ABS_LO12_NC R_AARCH64 = 14
- R_AARCH64_P32_LDST32_ABS_LO12_NC R_AARCH64 = 15
- R_AARCH64_P32_LDST64_ABS_LO12_NC R_AARCH64 = 16
- R_AARCH64_P32_LDST128_ABS_LO12_NC R_AARCH64 = 17
- R_AARCH64_P32_TSTBR14 R_AARCH64 = 18
- R_AARCH64_P32_CONDBR19 R_AARCH64 = 19
- R_AARCH64_P32_JUMP26 R_AARCH64 = 20
- R_AARCH64_P32_CALL26 R_AARCH64 = 21
- R_AARCH64_P32_GOT_LD_PREL19 R_AARCH64 = 25
- R_AARCH64_P32_ADR_GOT_PAGE R_AARCH64 = 26
- R_AARCH64_P32_LD32_GOT_LO12_NC R_AARCH64 = 27
- R_AARCH64_P32_TLSGD_ADR_PAGE21 R_AARCH64 = 81
- R_AARCH64_P32_TLSGD_ADD_LO12_NC R_AARCH64 = 82
- R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21 R_AARCH64 = 103
- R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC R_AARCH64 = 104
- R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19 R_AARCH64 = 105
- R_AARCH64_P32_TLSLE_MOVW_TPREL_G1 R_AARCH64 = 106
- R_AARCH64_P32_TLSLE_MOVW_TPREL_G0 R_AARCH64 = 107
- R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC R_AARCH64 = 108
- R_AARCH64_P32_TLSLE_ADD_TPREL_HI12 R_AARCH64 = 109
- R_AARCH64_P32_TLSLE_ADD_TPREL_LO12 R_AARCH64 = 110
- R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC R_AARCH64 = 111
- R_AARCH64_P32_TLSDESC_LD_PREL19 R_AARCH64 = 122
- R_AARCH64_P32_TLSDESC_ADR_PREL21 R_AARCH64 = 123
- R_AARCH64_P32_TLSDESC_ADR_PAGE21 R_AARCH64 = 124
- R_AARCH64_P32_TLSDESC_LD32_LO12_NC R_AARCH64 = 125
- R_AARCH64_P32_TLSDESC_ADD_LO12_NC R_AARCH64 = 126
- R_AARCH64_P32_TLSDESC_CALL R_AARCH64 = 127
- R_AARCH64_P32_COPY R_AARCH64 = 180
- R_AARCH64_P32_GLOB_DAT R_AARCH64 = 181
- R_AARCH64_P32_JUMP_SLOT R_AARCH64 = 182
- R_AARCH64_P32_RELATIVE R_AARCH64 = 183
- R_AARCH64_P32_TLS_DTPMOD R_AARCH64 = 184
- R_AARCH64_P32_TLS_DTPREL R_AARCH64 = 185
- R_AARCH64_P32_TLS_TPREL R_AARCH64 = 186
- R_AARCH64_P32_TLSDESC R_AARCH64 = 187
- R_AARCH64_P32_IRELATIVE R_AARCH64 = 188
- R_AARCH64_NULL R_AARCH64 = 256
- R_AARCH64_ABS64 R_AARCH64 = 257
- R_AARCH64_ABS32 R_AARCH64 = 258
- R_AARCH64_ABS16 R_AARCH64 = 259
- R_AARCH64_PREL64 R_AARCH64 = 260
- R_AARCH64_PREL32 R_AARCH64 = 261
- R_AARCH64_PREL16 R_AARCH64 = 262
- R_AARCH64_MOVW_UABS_G0 R_AARCH64 = 263
- R_AARCH64_MOVW_UABS_G0_NC R_AARCH64 = 264
- R_AARCH64_MOVW_UABS_G1 R_AARCH64 = 265
- R_AARCH64_MOVW_UABS_G1_NC R_AARCH64 = 266
- R_AARCH64_MOVW_UABS_G2 R_AARCH64 = 267
- R_AARCH64_MOVW_UABS_G2_NC R_AARCH64 = 268
- R_AARCH64_MOVW_UABS_G3 R_AARCH64 = 269
- R_AARCH64_MOVW_SABS_G0 R_AARCH64 = 270
- R_AARCH64_MOVW_SABS_G1 R_AARCH64 = 271
- R_AARCH64_MOVW_SABS_G2 R_AARCH64 = 272
- R_AARCH64_LD_PREL_LO19 R_AARCH64 = 273
- R_AARCH64_ADR_PREL_LO21 R_AARCH64 = 274
- R_AARCH64_ADR_PREL_PG_HI21 R_AARCH64 = 275
- R_AARCH64_ADR_PREL_PG_HI21_NC R_AARCH64 = 276
- R_AARCH64_ADD_ABS_LO12_NC R_AARCH64 = 277
- R_AARCH64_LDST8_ABS_LO12_NC R_AARCH64 = 278
- R_AARCH64_TSTBR14 R_AARCH64 = 279
- R_AARCH64_CONDBR19 R_AARCH64 = 280
- R_AARCH64_JUMP26 R_AARCH64 = 282
- R_AARCH64_CALL26 R_AARCH64 = 283
- R_AARCH64_LDST16_ABS_LO12_NC R_AARCH64 = 284
- R_AARCH64_LDST32_ABS_LO12_NC R_AARCH64 = 285
- R_AARCH64_LDST64_ABS_LO12_NC R_AARCH64 = 286
- R_AARCH64_LDST128_ABS_LO12_NC R_AARCH64 = 299
- R_AARCH64_GOT_LD_PREL19 R_AARCH64 = 309
- R_AARCH64_LD64_GOTOFF_LO15 R_AARCH64 = 310
- R_AARCH64_ADR_GOT_PAGE R_AARCH64 = 311
- R_AARCH64_LD64_GOT_LO12_NC R_AARCH64 = 312
- R_AARCH64_LD64_GOTPAGE_LO15 R_AARCH64 = 313
- R_AARCH64_TLSGD_ADR_PREL21 R_AARCH64 = 512
- R_AARCH64_TLSGD_ADR_PAGE21 R_AARCH64 = 513
- R_AARCH64_TLSGD_ADD_LO12_NC R_AARCH64 = 514
- R_AARCH64_TLSGD_MOVW_G1 R_AARCH64 = 515
- R_AARCH64_TLSGD_MOVW_G0_NC R_AARCH64 = 516
- R_AARCH64_TLSLD_ADR_PREL21 R_AARCH64 = 517
- R_AARCH64_TLSLD_ADR_PAGE21 R_AARCH64 = 518
- R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 R_AARCH64 = 539
- R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC R_AARCH64 = 540
- R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 R_AARCH64 = 541
- R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC R_AARCH64 = 542
- R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 R_AARCH64 = 543
- R_AARCH64_TLSLE_MOVW_TPREL_G2 R_AARCH64 = 544
- R_AARCH64_TLSLE_MOVW_TPREL_G1 R_AARCH64 = 545
- R_AARCH64_TLSLE_MOVW_TPREL_G1_NC R_AARCH64 = 546
- R_AARCH64_TLSLE_MOVW_TPREL_G0 R_AARCH64 = 547
- R_AARCH64_TLSLE_MOVW_TPREL_G0_NC R_AARCH64 = 548
- R_AARCH64_TLSLE_ADD_TPREL_HI12 R_AARCH64 = 549
- R_AARCH64_TLSLE_ADD_TPREL_LO12 R_AARCH64 = 550
- R_AARCH64_TLSLE_ADD_TPREL_LO12_NC R_AARCH64 = 551
- R_AARCH64_TLSDESC_LD_PREL19 R_AARCH64 = 560
- R_AARCH64_TLSDESC_ADR_PREL21 R_AARCH64 = 561
- R_AARCH64_TLSDESC_ADR_PAGE21 R_AARCH64 = 562
- R_AARCH64_TLSDESC_LD64_LO12_NC R_AARCH64 = 563
- R_AARCH64_TLSDESC_ADD_LO12_NC R_AARCH64 = 564
- R_AARCH64_TLSDESC_OFF_G1 R_AARCH64 = 565
- R_AARCH64_TLSDESC_OFF_G0_NC R_AARCH64 = 566
- R_AARCH64_TLSDESC_LDR R_AARCH64 = 567
- R_AARCH64_TLSDESC_ADD R_AARCH64 = 568
- R_AARCH64_TLSDESC_CALL R_AARCH64 = 569
- R_AARCH64_TLSLE_LDST128_TPREL_LO12 R_AARCH64 = 570
- R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC R_AARCH64 = 571
- R_AARCH64_TLSLD_LDST128_DTPREL_LO12 R_AARCH64 = 572
- R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC R_AARCH64 = 573
- R_AARCH64_COPY R_AARCH64 = 1024
- R_AARCH64_GLOB_DAT R_AARCH64 = 1025
- R_AARCH64_JUMP_SLOT R_AARCH64 = 1026
- R_AARCH64_RELATIVE R_AARCH64 = 1027
- R_AARCH64_TLS_DTPMOD64 R_AARCH64 = 1028
- R_AARCH64_TLS_DTPREL64 R_AARCH64 = 1029
- R_AARCH64_TLS_TPREL64 R_AARCH64 = 1030
- R_AARCH64_TLSDESC R_AARCH64 = 1031
- R_AARCH64_IRELATIVE R_AARCH64 = 1032
-)
-
-var raarch64Strings = []intName{
- {0, "R_AARCH64_NONE"},
- {1, "R_AARCH64_P32_ABS32"},
- {2, "R_AARCH64_P32_ABS16"},
- {3, "R_AARCH64_P32_PREL32"},
- {4, "R_AARCH64_P32_PREL16"},
- {5, "R_AARCH64_P32_MOVW_UABS_G0"},
- {6, "R_AARCH64_P32_MOVW_UABS_G0_NC"},
- {7, "R_AARCH64_P32_MOVW_UABS_G1"},
- {8, "R_AARCH64_P32_MOVW_SABS_G0"},
- {9, "R_AARCH64_P32_LD_PREL_LO19"},
- {10, "R_AARCH64_P32_ADR_PREL_LO21"},
- {11, "R_AARCH64_P32_ADR_PREL_PG_HI21"},
- {12, "R_AARCH64_P32_ADD_ABS_LO12_NC"},
- {13, "R_AARCH64_P32_LDST8_ABS_LO12_NC"},
- {14, "R_AARCH64_P32_LDST16_ABS_LO12_NC"},
- {15, "R_AARCH64_P32_LDST32_ABS_LO12_NC"},
- {16, "R_AARCH64_P32_LDST64_ABS_LO12_NC"},
- {17, "R_AARCH64_P32_LDST128_ABS_LO12_NC"},
- {18, "R_AARCH64_P32_TSTBR14"},
- {19, "R_AARCH64_P32_CONDBR19"},
- {20, "R_AARCH64_P32_JUMP26"},
- {21, "R_AARCH64_P32_CALL26"},
- {25, "R_AARCH64_P32_GOT_LD_PREL19"},
- {26, "R_AARCH64_P32_ADR_GOT_PAGE"},
- {27, "R_AARCH64_P32_LD32_GOT_LO12_NC"},
- {81, "R_AARCH64_P32_TLSGD_ADR_PAGE21"},
- {82, "R_AARCH64_P32_TLSGD_ADD_LO12_NC"},
- {103, "R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21"},
- {104, "R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC"},
- {105, "R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19"},
- {106, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G1"},
- {107, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G0"},
- {108, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC"},
- {109, "R_AARCH64_P32_TLSLE_ADD_TPREL_HI12"},
- {110, "R_AARCH64_P32_TLSLE_ADD_TPREL_LO12"},
- {111, "R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC"},
- {122, "R_AARCH64_P32_TLSDESC_LD_PREL19"},
- {123, "R_AARCH64_P32_TLSDESC_ADR_PREL21"},
- {124, "R_AARCH64_P32_TLSDESC_ADR_PAGE21"},
- {125, "R_AARCH64_P32_TLSDESC_LD32_LO12_NC"},
- {126, "R_AARCH64_P32_TLSDESC_ADD_LO12_NC"},
- {127, "R_AARCH64_P32_TLSDESC_CALL"},
- {180, "R_AARCH64_P32_COPY"},
- {181, "R_AARCH64_P32_GLOB_DAT"},
- {182, "R_AARCH64_P32_JUMP_SLOT"},
- {183, "R_AARCH64_P32_RELATIVE"},
- {184, "R_AARCH64_P32_TLS_DTPMOD"},
- {185, "R_AARCH64_P32_TLS_DTPREL"},
- {186, "R_AARCH64_P32_TLS_TPREL"},
- {187, "R_AARCH64_P32_TLSDESC"},
- {188, "R_AARCH64_P32_IRELATIVE"},
- {256, "R_AARCH64_NULL"},
- {257, "R_AARCH64_ABS64"},
- {258, "R_AARCH64_ABS32"},
- {259, "R_AARCH64_ABS16"},
- {260, "R_AARCH64_PREL64"},
- {261, "R_AARCH64_PREL32"},
- {262, "R_AARCH64_PREL16"},
- {263, "R_AARCH64_MOVW_UABS_G0"},
- {264, "R_AARCH64_MOVW_UABS_G0_NC"},
- {265, "R_AARCH64_MOVW_UABS_G1"},
- {266, "R_AARCH64_MOVW_UABS_G1_NC"},
- {267, "R_AARCH64_MOVW_UABS_G2"},
- {268, "R_AARCH64_MOVW_UABS_G2_NC"},
- {269, "R_AARCH64_MOVW_UABS_G3"},
- {270, "R_AARCH64_MOVW_SABS_G0"},
- {271, "R_AARCH64_MOVW_SABS_G1"},
- {272, "R_AARCH64_MOVW_SABS_G2"},
- {273, "R_AARCH64_LD_PREL_LO19"},
- {274, "R_AARCH64_ADR_PREL_LO21"},
- {275, "R_AARCH64_ADR_PREL_PG_HI21"},
- {276, "R_AARCH64_ADR_PREL_PG_HI21_NC"},
- {277, "R_AARCH64_ADD_ABS_LO12_NC"},
- {278, "R_AARCH64_LDST8_ABS_LO12_NC"},
- {279, "R_AARCH64_TSTBR14"},
- {280, "R_AARCH64_CONDBR19"},
- {282, "R_AARCH64_JUMP26"},
- {283, "R_AARCH64_CALL26"},
- {284, "R_AARCH64_LDST16_ABS_LO12_NC"},
- {285, "R_AARCH64_LDST32_ABS_LO12_NC"},
- {286, "R_AARCH64_LDST64_ABS_LO12_NC"},
- {299, "R_AARCH64_LDST128_ABS_LO12_NC"},
- {309, "R_AARCH64_GOT_LD_PREL19"},
- {310, "R_AARCH64_LD64_GOTOFF_LO15"},
- {311, "R_AARCH64_ADR_GOT_PAGE"},
- {312, "R_AARCH64_LD64_GOT_LO12_NC"},
- {313, "R_AARCH64_LD64_GOTPAGE_LO15"},
- {512, "R_AARCH64_TLSGD_ADR_PREL21"},
- {513, "R_AARCH64_TLSGD_ADR_PAGE21"},
- {514, "R_AARCH64_TLSGD_ADD_LO12_NC"},
- {515, "R_AARCH64_TLSGD_MOVW_G1"},
- {516, "R_AARCH64_TLSGD_MOVW_G0_NC"},
- {517, "R_AARCH64_TLSLD_ADR_PREL21"},
- {518, "R_AARCH64_TLSLD_ADR_PAGE21"},
- {539, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G1"},
- {540, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC"},
- {541, "R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21"},
- {542, "R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC"},
- {543, "R_AARCH64_TLSIE_LD_GOTTPREL_PREL19"},
- {544, "R_AARCH64_TLSLE_MOVW_TPREL_G2"},
- {545, "R_AARCH64_TLSLE_MOVW_TPREL_G1"},
- {546, "R_AARCH64_TLSLE_MOVW_TPREL_G1_NC"},
- {547, "R_AARCH64_TLSLE_MOVW_TPREL_G0"},
- {548, "R_AARCH64_TLSLE_MOVW_TPREL_G0_NC"},
- {549, "R_AARCH64_TLSLE_ADD_TPREL_HI12"},
- {550, "R_AARCH64_TLSLE_ADD_TPREL_LO12"},
- {551, "R_AARCH64_TLSLE_ADD_TPREL_LO12_NC"},
- {560, "R_AARCH64_TLSDESC_LD_PREL19"},
- {561, "R_AARCH64_TLSDESC_ADR_PREL21"},
- {562, "R_AARCH64_TLSDESC_ADR_PAGE21"},
- {563, "R_AARCH64_TLSDESC_LD64_LO12_NC"},
- {564, "R_AARCH64_TLSDESC_ADD_LO12_NC"},
- {565, "R_AARCH64_TLSDESC_OFF_G1"},
- {566, "R_AARCH64_TLSDESC_OFF_G0_NC"},
- {567, "R_AARCH64_TLSDESC_LDR"},
- {568, "R_AARCH64_TLSDESC_ADD"},
- {569, "R_AARCH64_TLSDESC_CALL"},
- {570, "R_AARCH64_TLSLE_LDST128_TPREL_LO12"},
- {571, "R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC"},
- {572, "R_AARCH64_TLSLD_LDST128_DTPREL_LO12"},
- {573, "R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC"},
- {1024, "R_AARCH64_COPY"},
- {1025, "R_AARCH64_GLOB_DAT"},
- {1026, "R_AARCH64_JUMP_SLOT"},
- {1027, "R_AARCH64_RELATIVE"},
- {1028, "R_AARCH64_TLS_DTPMOD64"},
- {1029, "R_AARCH64_TLS_DTPREL64"},
- {1030, "R_AARCH64_TLS_TPREL64"},
- {1031, "R_AARCH64_TLSDESC"},
- {1032, "R_AARCH64_IRELATIVE"},
-}
-
-func (i R_AARCH64) String() string { return stringName(uint32(i), raarch64Strings, false) }
-func (i R_AARCH64) GoString() string { return stringName(uint32(i), raarch64Strings, true) }
-
-// Relocation types for Alpha.
-type R_ALPHA int
-
-const (
- R_ALPHA_NONE R_ALPHA = 0 /* No reloc */
- R_ALPHA_REFLONG R_ALPHA = 1 /* Direct 32 bit */
- R_ALPHA_REFQUAD R_ALPHA = 2 /* Direct 64 bit */
- R_ALPHA_GPREL32 R_ALPHA = 3 /* GP relative 32 bit */
- R_ALPHA_LITERAL R_ALPHA = 4 /* GP relative 16 bit w/optimization */
- R_ALPHA_LITUSE R_ALPHA = 5 /* Optimization hint for LITERAL */
- R_ALPHA_GPDISP R_ALPHA = 6 /* Add displacement to GP */
- R_ALPHA_BRADDR R_ALPHA = 7 /* PC+4 relative 23 bit shifted */
- R_ALPHA_HINT R_ALPHA = 8 /* PC+4 relative 16 bit shifted */
- R_ALPHA_SREL16 R_ALPHA = 9 /* PC relative 16 bit */
- R_ALPHA_SREL32 R_ALPHA = 10 /* PC relative 32 bit */
- R_ALPHA_SREL64 R_ALPHA = 11 /* PC relative 64 bit */
- R_ALPHA_OP_PUSH R_ALPHA = 12 /* OP stack push */
- R_ALPHA_OP_STORE R_ALPHA = 13 /* OP stack pop and store */
- R_ALPHA_OP_PSUB R_ALPHA = 14 /* OP stack subtract */
- R_ALPHA_OP_PRSHIFT R_ALPHA = 15 /* OP stack right shift */
- R_ALPHA_GPVALUE R_ALPHA = 16
- R_ALPHA_GPRELHIGH R_ALPHA = 17
- R_ALPHA_GPRELLOW R_ALPHA = 18
- R_ALPHA_IMMED_GP_16 R_ALPHA = 19
- R_ALPHA_IMMED_GP_HI32 R_ALPHA = 20
- R_ALPHA_IMMED_SCN_HI32 R_ALPHA = 21
- R_ALPHA_IMMED_BR_HI32 R_ALPHA = 22
- R_ALPHA_IMMED_LO32 R_ALPHA = 23
- R_ALPHA_COPY R_ALPHA = 24 /* Copy symbol at runtime */
- R_ALPHA_GLOB_DAT R_ALPHA = 25 /* Create GOT entry */
- R_ALPHA_JMP_SLOT R_ALPHA = 26 /* Create PLT entry */
- R_ALPHA_RELATIVE R_ALPHA = 27 /* Adjust by program base */
-)
-
-var ralphaStrings = []intName{
- {0, "R_ALPHA_NONE"},
- {1, "R_ALPHA_REFLONG"},
- {2, "R_ALPHA_REFQUAD"},
- {3, "R_ALPHA_GPREL32"},
- {4, "R_ALPHA_LITERAL"},
- {5, "R_ALPHA_LITUSE"},
- {6, "R_ALPHA_GPDISP"},
- {7, "R_ALPHA_BRADDR"},
- {8, "R_ALPHA_HINT"},
- {9, "R_ALPHA_SREL16"},
- {10, "R_ALPHA_SREL32"},
- {11, "R_ALPHA_SREL64"},
- {12, "R_ALPHA_OP_PUSH"},
- {13, "R_ALPHA_OP_STORE"},
- {14, "R_ALPHA_OP_PSUB"},
- {15, "R_ALPHA_OP_PRSHIFT"},
- {16, "R_ALPHA_GPVALUE"},
- {17, "R_ALPHA_GPRELHIGH"},
- {18, "R_ALPHA_GPRELLOW"},
- {19, "R_ALPHA_IMMED_GP_16"},
- {20, "R_ALPHA_IMMED_GP_HI32"},
- {21, "R_ALPHA_IMMED_SCN_HI32"},
- {22, "R_ALPHA_IMMED_BR_HI32"},
- {23, "R_ALPHA_IMMED_LO32"},
- {24, "R_ALPHA_COPY"},
- {25, "R_ALPHA_GLOB_DAT"},
- {26, "R_ALPHA_JMP_SLOT"},
- {27, "R_ALPHA_RELATIVE"},
-}
-
-func (i R_ALPHA) String() string { return stringName(uint32(i), ralphaStrings, false) }
-func (i R_ALPHA) GoString() string { return stringName(uint32(i), ralphaStrings, true) }
-
-// Relocation types for ARM.
-type R_ARM int
-
-const (
- R_ARM_NONE R_ARM = 0 /* No relocation. */
- R_ARM_PC24 R_ARM = 1
- R_ARM_ABS32 R_ARM = 2
- R_ARM_REL32 R_ARM = 3
- R_ARM_PC13 R_ARM = 4
- R_ARM_ABS16 R_ARM = 5
- R_ARM_ABS12 R_ARM = 6
- R_ARM_THM_ABS5 R_ARM = 7
- R_ARM_ABS8 R_ARM = 8
- R_ARM_SBREL32 R_ARM = 9
- R_ARM_THM_PC22 R_ARM = 10
- R_ARM_THM_PC8 R_ARM = 11
- R_ARM_AMP_VCALL9 R_ARM = 12
- R_ARM_SWI24 R_ARM = 13
- R_ARM_THM_SWI8 R_ARM = 14
- R_ARM_XPC25 R_ARM = 15
- R_ARM_THM_XPC22 R_ARM = 16
- R_ARM_TLS_DTPMOD32 R_ARM = 17
- R_ARM_TLS_DTPOFF32 R_ARM = 18
- R_ARM_TLS_TPOFF32 R_ARM = 19
- R_ARM_COPY R_ARM = 20 /* Copy data from shared object. */
- R_ARM_GLOB_DAT R_ARM = 21 /* Set GOT entry to data address. */
- R_ARM_JUMP_SLOT R_ARM = 22 /* Set GOT entry to code address. */
- R_ARM_RELATIVE R_ARM = 23 /* Add load address of shared object. */
- R_ARM_GOTOFF R_ARM = 24 /* Add GOT-relative symbol address. */
- R_ARM_GOTPC R_ARM = 25 /* Add PC-relative GOT table address. */
- R_ARM_GOT32 R_ARM = 26 /* Add PC-relative GOT offset. */
- R_ARM_PLT32 R_ARM = 27 /* Add PC-relative PLT offset. */
- R_ARM_CALL R_ARM = 28
- R_ARM_JUMP24 R_ARM = 29
- R_ARM_THM_JUMP24 R_ARM = 30
- R_ARM_BASE_ABS R_ARM = 31
- R_ARM_ALU_PCREL_7_0 R_ARM = 32
- R_ARM_ALU_PCREL_15_8 R_ARM = 33
- R_ARM_ALU_PCREL_23_15 R_ARM = 34
- R_ARM_LDR_SBREL_11_10_NC R_ARM = 35
- R_ARM_ALU_SBREL_19_12_NC R_ARM = 36
- R_ARM_ALU_SBREL_27_20_CK R_ARM = 37
- R_ARM_TARGET1 R_ARM = 38
- R_ARM_SBREL31 R_ARM = 39
- R_ARM_V4BX R_ARM = 40
- R_ARM_TARGET2 R_ARM = 41
- R_ARM_PREL31 R_ARM = 42
- R_ARM_MOVW_ABS_NC R_ARM = 43
- R_ARM_MOVT_ABS R_ARM = 44
- R_ARM_MOVW_PREL_NC R_ARM = 45
- R_ARM_MOVT_PREL R_ARM = 46
- R_ARM_THM_MOVW_ABS_NC R_ARM = 47
- R_ARM_THM_MOVT_ABS R_ARM = 48
- R_ARM_THM_MOVW_PREL_NC R_ARM = 49
- R_ARM_THM_MOVT_PREL R_ARM = 50
- R_ARM_THM_JUMP19 R_ARM = 51
- R_ARM_THM_JUMP6 R_ARM = 52
- R_ARM_THM_ALU_PREL_11_0 R_ARM = 53
- R_ARM_THM_PC12 R_ARM = 54
- R_ARM_ABS32_NOI R_ARM = 55
- R_ARM_REL32_NOI R_ARM = 56
- R_ARM_ALU_PC_G0_NC R_ARM = 57
- R_ARM_ALU_PC_G0 R_ARM = 58
- R_ARM_ALU_PC_G1_NC R_ARM = 59
- R_ARM_ALU_PC_G1 R_ARM = 60
- R_ARM_ALU_PC_G2 R_ARM = 61
- R_ARM_LDR_PC_G1 R_ARM = 62
- R_ARM_LDR_PC_G2 R_ARM = 63
- R_ARM_LDRS_PC_G0 R_ARM = 64
- R_ARM_LDRS_PC_G1 R_ARM = 65
- R_ARM_LDRS_PC_G2 R_ARM = 66
- R_ARM_LDC_PC_G0 R_ARM = 67
- R_ARM_LDC_PC_G1 R_ARM = 68
- R_ARM_LDC_PC_G2 R_ARM = 69
- R_ARM_ALU_SB_G0_NC R_ARM = 70
- R_ARM_ALU_SB_G0 R_ARM = 71
- R_ARM_ALU_SB_G1_NC R_ARM = 72
- R_ARM_ALU_SB_G1 R_ARM = 73
- R_ARM_ALU_SB_G2 R_ARM = 74
- R_ARM_LDR_SB_G0 R_ARM = 75
- R_ARM_LDR_SB_G1 R_ARM = 76
- R_ARM_LDR_SB_G2 R_ARM = 77
- R_ARM_LDRS_SB_G0 R_ARM = 78
- R_ARM_LDRS_SB_G1 R_ARM = 79
- R_ARM_LDRS_SB_G2 R_ARM = 80
- R_ARM_LDC_SB_G0 R_ARM = 81
- R_ARM_LDC_SB_G1 R_ARM = 82
- R_ARM_LDC_SB_G2 R_ARM = 83
- R_ARM_MOVW_BREL_NC R_ARM = 84
- R_ARM_MOVT_BREL R_ARM = 85
- R_ARM_MOVW_BREL R_ARM = 86
- R_ARM_THM_MOVW_BREL_NC R_ARM = 87
- R_ARM_THM_MOVT_BREL R_ARM = 88
- R_ARM_THM_MOVW_BREL R_ARM = 89
- R_ARM_TLS_GOTDESC R_ARM = 90
- R_ARM_TLS_CALL R_ARM = 91
- R_ARM_TLS_DESCSEQ R_ARM = 92
- R_ARM_THM_TLS_CALL R_ARM = 93
- R_ARM_PLT32_ABS R_ARM = 94
- R_ARM_GOT_ABS R_ARM = 95
- R_ARM_GOT_PREL R_ARM = 96
- R_ARM_GOT_BREL12 R_ARM = 97
- R_ARM_GOTOFF12 R_ARM = 98
- R_ARM_GOTRELAX R_ARM = 99
- R_ARM_GNU_VTENTRY R_ARM = 100
- R_ARM_GNU_VTINHERIT R_ARM = 101
- R_ARM_THM_JUMP11 R_ARM = 102
- R_ARM_THM_JUMP8 R_ARM = 103
- R_ARM_TLS_GD32 R_ARM = 104
- R_ARM_TLS_LDM32 R_ARM = 105
- R_ARM_TLS_LDO32 R_ARM = 106
- R_ARM_TLS_IE32 R_ARM = 107
- R_ARM_TLS_LE32 R_ARM = 108
- R_ARM_TLS_LDO12 R_ARM = 109
- R_ARM_TLS_LE12 R_ARM = 110
- R_ARM_TLS_IE12GP R_ARM = 111
- R_ARM_PRIVATE_0 R_ARM = 112
- R_ARM_PRIVATE_1 R_ARM = 113
- R_ARM_PRIVATE_2 R_ARM = 114
- R_ARM_PRIVATE_3 R_ARM = 115
- R_ARM_PRIVATE_4 R_ARM = 116
- R_ARM_PRIVATE_5 R_ARM = 117
- R_ARM_PRIVATE_6 R_ARM = 118
- R_ARM_PRIVATE_7 R_ARM = 119
- R_ARM_PRIVATE_8 R_ARM = 120
- R_ARM_PRIVATE_9 R_ARM = 121
- R_ARM_PRIVATE_10 R_ARM = 122
- R_ARM_PRIVATE_11 R_ARM = 123
- R_ARM_PRIVATE_12 R_ARM = 124
- R_ARM_PRIVATE_13 R_ARM = 125
- R_ARM_PRIVATE_14 R_ARM = 126
- R_ARM_PRIVATE_15 R_ARM = 127
- R_ARM_ME_TOO R_ARM = 128
- R_ARM_THM_TLS_DESCSEQ16 R_ARM = 129
- R_ARM_THM_TLS_DESCSEQ32 R_ARM = 130
- R_ARM_THM_GOT_BREL12 R_ARM = 131
- R_ARM_THM_ALU_ABS_G0_NC R_ARM = 132
- R_ARM_THM_ALU_ABS_G1_NC R_ARM = 133
- R_ARM_THM_ALU_ABS_G2_NC R_ARM = 134
- R_ARM_THM_ALU_ABS_G3 R_ARM = 135
- R_ARM_IRELATIVE R_ARM = 160
- R_ARM_RXPC25 R_ARM = 249
- R_ARM_RSBREL32 R_ARM = 250
- R_ARM_THM_RPC22 R_ARM = 251
- R_ARM_RREL32 R_ARM = 252
- R_ARM_RABS32 R_ARM = 253
- R_ARM_RPC24 R_ARM = 254
- R_ARM_RBASE R_ARM = 255
-)
-
-var rarmStrings = []intName{
- {0, "R_ARM_NONE"},
- {1, "R_ARM_PC24"},
- {2, "R_ARM_ABS32"},
- {3, "R_ARM_REL32"},
- {4, "R_ARM_PC13"},
- {5, "R_ARM_ABS16"},
- {6, "R_ARM_ABS12"},
- {7, "R_ARM_THM_ABS5"},
- {8, "R_ARM_ABS8"},
- {9, "R_ARM_SBREL32"},
- {10, "R_ARM_THM_PC22"},
- {11, "R_ARM_THM_PC8"},
- {12, "R_ARM_AMP_VCALL9"},
- {13, "R_ARM_SWI24"},
- {14, "R_ARM_THM_SWI8"},
- {15, "R_ARM_XPC25"},
- {16, "R_ARM_THM_XPC22"},
- {17, "R_ARM_TLS_DTPMOD32"},
- {18, "R_ARM_TLS_DTPOFF32"},
- {19, "R_ARM_TLS_TPOFF32"},
- {20, "R_ARM_COPY"},
- {21, "R_ARM_GLOB_DAT"},
- {22, "R_ARM_JUMP_SLOT"},
- {23, "R_ARM_RELATIVE"},
- {24, "R_ARM_GOTOFF"},
- {25, "R_ARM_GOTPC"},
- {26, "R_ARM_GOT32"},
- {27, "R_ARM_PLT32"},
- {28, "R_ARM_CALL"},
- {29, "R_ARM_JUMP24"},
- {30, "R_ARM_THM_JUMP24"},
- {31, "R_ARM_BASE_ABS"},
- {32, "R_ARM_ALU_PCREL_7_0"},
- {33, "R_ARM_ALU_PCREL_15_8"},
- {34, "R_ARM_ALU_PCREL_23_15"},
- {35, "R_ARM_LDR_SBREL_11_10_NC"},
- {36, "R_ARM_ALU_SBREL_19_12_NC"},
- {37, "R_ARM_ALU_SBREL_27_20_CK"},
- {38, "R_ARM_TARGET1"},
- {39, "R_ARM_SBREL31"},
- {40, "R_ARM_V4BX"},
- {41, "R_ARM_TARGET2"},
- {42, "R_ARM_PREL31"},
- {43, "R_ARM_MOVW_ABS_NC"},
- {44, "R_ARM_MOVT_ABS"},
- {45, "R_ARM_MOVW_PREL_NC"},
- {46, "R_ARM_MOVT_PREL"},
- {47, "R_ARM_THM_MOVW_ABS_NC"},
- {48, "R_ARM_THM_MOVT_ABS"},
- {49, "R_ARM_THM_MOVW_PREL_NC"},
- {50, "R_ARM_THM_MOVT_PREL"},
- {51, "R_ARM_THM_JUMP19"},
- {52, "R_ARM_THM_JUMP6"},
- {53, "R_ARM_THM_ALU_PREL_11_0"},
- {54, "R_ARM_THM_PC12"},
- {55, "R_ARM_ABS32_NOI"},
- {56, "R_ARM_REL32_NOI"},
- {57, "R_ARM_ALU_PC_G0_NC"},
- {58, "R_ARM_ALU_PC_G0"},
- {59, "R_ARM_ALU_PC_G1_NC"},
- {60, "R_ARM_ALU_PC_G1"},
- {61, "R_ARM_ALU_PC_G2"},
- {62, "R_ARM_LDR_PC_G1"},
- {63, "R_ARM_LDR_PC_G2"},
- {64, "R_ARM_LDRS_PC_G0"},
- {65, "R_ARM_LDRS_PC_G1"},
- {66, "R_ARM_LDRS_PC_G2"},
- {67, "R_ARM_LDC_PC_G0"},
- {68, "R_ARM_LDC_PC_G1"},
- {69, "R_ARM_LDC_PC_G2"},
- {70, "R_ARM_ALU_SB_G0_NC"},
- {71, "R_ARM_ALU_SB_G0"},
- {72, "R_ARM_ALU_SB_G1_NC"},
- {73, "R_ARM_ALU_SB_G1"},
- {74, "R_ARM_ALU_SB_G2"},
- {75, "R_ARM_LDR_SB_G0"},
- {76, "R_ARM_LDR_SB_G1"},
- {77, "R_ARM_LDR_SB_G2"},
- {78, "R_ARM_LDRS_SB_G0"},
- {79, "R_ARM_LDRS_SB_G1"},
- {80, "R_ARM_LDRS_SB_G2"},
- {81, "R_ARM_LDC_SB_G0"},
- {82, "R_ARM_LDC_SB_G1"},
- {83, "R_ARM_LDC_SB_G2"},
- {84, "R_ARM_MOVW_BREL_NC"},
- {85, "R_ARM_MOVT_BREL"},
- {86, "R_ARM_MOVW_BREL"},
- {87, "R_ARM_THM_MOVW_BREL_NC"},
- {88, "R_ARM_THM_MOVT_BREL"},
- {89, "R_ARM_THM_MOVW_BREL"},
- {90, "R_ARM_TLS_GOTDESC"},
- {91, "R_ARM_TLS_CALL"},
- {92, "R_ARM_TLS_DESCSEQ"},
- {93, "R_ARM_THM_TLS_CALL"},
- {94, "R_ARM_PLT32_ABS"},
- {95, "R_ARM_GOT_ABS"},
- {96, "R_ARM_GOT_PREL"},
- {97, "R_ARM_GOT_BREL12"},
- {98, "R_ARM_GOTOFF12"},
- {99, "R_ARM_GOTRELAX"},
- {100, "R_ARM_GNU_VTENTRY"},
- {101, "R_ARM_GNU_VTINHERIT"},
- {102, "R_ARM_THM_JUMP11"},
- {103, "R_ARM_THM_JUMP8"},
- {104, "R_ARM_TLS_GD32"},
- {105, "R_ARM_TLS_LDM32"},
- {106, "R_ARM_TLS_LDO32"},
- {107, "R_ARM_TLS_IE32"},
- {108, "R_ARM_TLS_LE32"},
- {109, "R_ARM_TLS_LDO12"},
- {110, "R_ARM_TLS_LE12"},
- {111, "R_ARM_TLS_IE12GP"},
- {112, "R_ARM_PRIVATE_0"},
- {113, "R_ARM_PRIVATE_1"},
- {114, "R_ARM_PRIVATE_2"},
- {115, "R_ARM_PRIVATE_3"},
- {116, "R_ARM_PRIVATE_4"},
- {117, "R_ARM_PRIVATE_5"},
- {118, "R_ARM_PRIVATE_6"},
- {119, "R_ARM_PRIVATE_7"},
- {120, "R_ARM_PRIVATE_8"},
- {121, "R_ARM_PRIVATE_9"},
- {122, "R_ARM_PRIVATE_10"},
- {123, "R_ARM_PRIVATE_11"},
- {124, "R_ARM_PRIVATE_12"},
- {125, "R_ARM_PRIVATE_13"},
- {126, "R_ARM_PRIVATE_14"},
- {127, "R_ARM_PRIVATE_15"},
- {128, "R_ARM_ME_TOO"},
- {129, "R_ARM_THM_TLS_DESCSEQ16"},
- {130, "R_ARM_THM_TLS_DESCSEQ32"},
- {131, "R_ARM_THM_GOT_BREL12"},
- {132, "R_ARM_THM_ALU_ABS_G0_NC"},
- {133, "R_ARM_THM_ALU_ABS_G1_NC"},
- {134, "R_ARM_THM_ALU_ABS_G2_NC"},
- {135, "R_ARM_THM_ALU_ABS_G3"},
- {160, "R_ARM_IRELATIVE"},
- {249, "R_ARM_RXPC25"},
- {250, "R_ARM_RSBREL32"},
- {251, "R_ARM_THM_RPC22"},
- {252, "R_ARM_RREL32"},
- {253, "R_ARM_RABS32"},
- {254, "R_ARM_RPC24"},
- {255, "R_ARM_RBASE"},
-}
-
-func (i R_ARM) String() string { return stringName(uint32(i), rarmStrings, false) }
-func (i R_ARM) GoString() string { return stringName(uint32(i), rarmStrings, true) }
-
-// Relocation types for 386.
-type R_386 int
-
-const (
- R_386_NONE R_386 = 0 /* No relocation. */
- R_386_32 R_386 = 1 /* Add symbol value. */
- R_386_PC32 R_386 = 2 /* Add PC-relative symbol value. */
- R_386_GOT32 R_386 = 3 /* Add PC-relative GOT offset. */
- R_386_PLT32 R_386 = 4 /* Add PC-relative PLT offset. */
- R_386_COPY R_386 = 5 /* Copy data from shared object. */
- R_386_GLOB_DAT R_386 = 6 /* Set GOT entry to data address. */
- R_386_JMP_SLOT R_386 = 7 /* Set GOT entry to code address. */
- R_386_RELATIVE R_386 = 8 /* Add load address of shared object. */
- R_386_GOTOFF R_386 = 9 /* Add GOT-relative symbol address. */
- R_386_GOTPC R_386 = 10 /* Add PC-relative GOT table address. */
- R_386_32PLT R_386 = 11
- R_386_TLS_TPOFF R_386 = 14 /* Negative offset in static TLS block */
- R_386_TLS_IE R_386 = 15 /* Absolute address of GOT for -ve static TLS */
- R_386_TLS_GOTIE R_386 = 16 /* GOT entry for negative static TLS block */
- R_386_TLS_LE R_386 = 17 /* Negative offset relative to static TLS */
- R_386_TLS_GD R_386 = 18 /* 32 bit offset to GOT (index,off) pair */
- R_386_TLS_LDM R_386 = 19 /* 32 bit offset to GOT (index,zero) pair */
- R_386_16 R_386 = 20
- R_386_PC16 R_386 = 21
- R_386_8 R_386 = 22
- R_386_PC8 R_386 = 23
- R_386_TLS_GD_32 R_386 = 24 /* 32 bit offset to GOT (index,off) pair */
- R_386_TLS_GD_PUSH R_386 = 25 /* pushl instruction for Sun ABI GD sequence */
- R_386_TLS_GD_CALL R_386 = 26 /* call instruction for Sun ABI GD sequence */
- R_386_TLS_GD_POP R_386 = 27 /* popl instruction for Sun ABI GD sequence */
- R_386_TLS_LDM_32 R_386 = 28 /* 32 bit offset to GOT (index,zero) pair */
- R_386_TLS_LDM_PUSH R_386 = 29 /* pushl instruction for Sun ABI LD sequence */
- R_386_TLS_LDM_CALL R_386 = 30 /* call instruction for Sun ABI LD sequence */
- R_386_TLS_LDM_POP R_386 = 31 /* popl instruction for Sun ABI LD sequence */
- R_386_TLS_LDO_32 R_386 = 32 /* 32 bit offset from start of TLS block */
- R_386_TLS_IE_32 R_386 = 33 /* 32 bit offset to GOT static TLS offset entry */
- R_386_TLS_LE_32 R_386 = 34 /* 32 bit offset within static TLS block */
- R_386_TLS_DTPMOD32 R_386 = 35 /* GOT entry containing TLS index */
- R_386_TLS_DTPOFF32 R_386 = 36 /* GOT entry containing TLS offset */
- R_386_TLS_TPOFF32 R_386 = 37 /* GOT entry of -ve static TLS offset */
- R_386_SIZE32 R_386 = 38
- R_386_TLS_GOTDESC R_386 = 39
- R_386_TLS_DESC_CALL R_386 = 40
- R_386_TLS_DESC R_386 = 41
- R_386_IRELATIVE R_386 = 42
- R_386_GOT32X R_386 = 43
-)
-
-var r386Strings = []intName{
- {0, "R_386_NONE"},
- {1, "R_386_32"},
- {2, "R_386_PC32"},
- {3, "R_386_GOT32"},
- {4, "R_386_PLT32"},
- {5, "R_386_COPY"},
- {6, "R_386_GLOB_DAT"},
- {7, "R_386_JMP_SLOT"},
- {8, "R_386_RELATIVE"},
- {9, "R_386_GOTOFF"},
- {10, "R_386_GOTPC"},
- {11, "R_386_32PLT"},
- {14, "R_386_TLS_TPOFF"},
- {15, "R_386_TLS_IE"},
- {16, "R_386_TLS_GOTIE"},
- {17, "R_386_TLS_LE"},
- {18, "R_386_TLS_GD"},
- {19, "R_386_TLS_LDM"},
- {20, "R_386_16"},
- {21, "R_386_PC16"},
- {22, "R_386_8"},
- {23, "R_386_PC8"},
- {24, "R_386_TLS_GD_32"},
- {25, "R_386_TLS_GD_PUSH"},
- {26, "R_386_TLS_GD_CALL"},
- {27, "R_386_TLS_GD_POP"},
- {28, "R_386_TLS_LDM_32"},
- {29, "R_386_TLS_LDM_PUSH"},
- {30, "R_386_TLS_LDM_CALL"},
- {31, "R_386_TLS_LDM_POP"},
- {32, "R_386_TLS_LDO_32"},
- {33, "R_386_TLS_IE_32"},
- {34, "R_386_TLS_LE_32"},
- {35, "R_386_TLS_DTPMOD32"},
- {36, "R_386_TLS_DTPOFF32"},
- {37, "R_386_TLS_TPOFF32"},
- {38, "R_386_SIZE32"},
- {39, "R_386_TLS_GOTDESC"},
- {40, "R_386_TLS_DESC_CALL"},
- {41, "R_386_TLS_DESC"},
- {42, "R_386_IRELATIVE"},
- {43, "R_386_GOT32X"},
-}
-
-func (i R_386) String() string { return stringName(uint32(i), r386Strings, false) }
-func (i R_386) GoString() string { return stringName(uint32(i), r386Strings, true) }
-
-// Relocation types for MIPS.
-type R_MIPS int
-
-const (
- R_MIPS_NONE R_MIPS = 0
- R_MIPS_16 R_MIPS = 1
- R_MIPS_32 R_MIPS = 2
- R_MIPS_REL32 R_MIPS = 3
- R_MIPS_26 R_MIPS = 4
- R_MIPS_HI16 R_MIPS = 5 /* high 16 bits of symbol value */
- R_MIPS_LO16 R_MIPS = 6 /* low 16 bits of symbol value */
- R_MIPS_GPREL16 R_MIPS = 7 /* GP-relative reference */
- R_MIPS_LITERAL R_MIPS = 8 /* Reference to literal section */
- R_MIPS_GOT16 R_MIPS = 9 /* Reference to global offset table */
- R_MIPS_PC16 R_MIPS = 10 /* 16 bit PC relative reference */
- R_MIPS_CALL16 R_MIPS = 11 /* 16 bit call through glbl offset tbl */
- R_MIPS_GPREL32 R_MIPS = 12
- R_MIPS_SHIFT5 R_MIPS = 16
- R_MIPS_SHIFT6 R_MIPS = 17
- R_MIPS_64 R_MIPS = 18
- R_MIPS_GOT_DISP R_MIPS = 19
- R_MIPS_GOT_PAGE R_MIPS = 20
- R_MIPS_GOT_OFST R_MIPS = 21
- R_MIPS_GOT_HI16 R_MIPS = 22
- R_MIPS_GOT_LO16 R_MIPS = 23
- R_MIPS_SUB R_MIPS = 24
- R_MIPS_INSERT_A R_MIPS = 25
- R_MIPS_INSERT_B R_MIPS = 26
- R_MIPS_DELETE R_MIPS = 27
- R_MIPS_HIGHER R_MIPS = 28
- R_MIPS_HIGHEST R_MIPS = 29
- R_MIPS_CALL_HI16 R_MIPS = 30
- R_MIPS_CALL_LO16 R_MIPS = 31
- R_MIPS_SCN_DISP R_MIPS = 32
- R_MIPS_REL16 R_MIPS = 33
- R_MIPS_ADD_IMMEDIATE R_MIPS = 34
- R_MIPS_PJUMP R_MIPS = 35
- R_MIPS_RELGOT R_MIPS = 36
- R_MIPS_JALR R_MIPS = 37
-
- R_MIPS_TLS_DTPMOD32 R_MIPS = 38 /* Module number 32 bit */
- R_MIPS_TLS_DTPREL32 R_MIPS = 39 /* Module-relative offset 32 bit */
- R_MIPS_TLS_DTPMOD64 R_MIPS = 40 /* Module number 64 bit */
- R_MIPS_TLS_DTPREL64 R_MIPS = 41 /* Module-relative offset 64 bit */
- R_MIPS_TLS_GD R_MIPS = 42 /* 16 bit GOT offset for GD */
- R_MIPS_TLS_LDM R_MIPS = 43 /* 16 bit GOT offset for LDM */
- R_MIPS_TLS_DTPREL_HI16 R_MIPS = 44 /* Module-relative offset, high 16 bits */
- R_MIPS_TLS_DTPREL_LO16 R_MIPS = 45 /* Module-relative offset, low 16 bits */
- R_MIPS_TLS_GOTTPREL R_MIPS = 46 /* 16 bit GOT offset for IE */
- R_MIPS_TLS_TPREL32 R_MIPS = 47 /* TP-relative offset, 32 bit */
- R_MIPS_TLS_TPREL64 R_MIPS = 48 /* TP-relative offset, 64 bit */
- R_MIPS_TLS_TPREL_HI16 R_MIPS = 49 /* TP-relative offset, high 16 bits */
- R_MIPS_TLS_TPREL_LO16 R_MIPS = 50 /* TP-relative offset, low 16 bits */
-)
-
-var rmipsStrings = []intName{
- {0, "R_MIPS_NONE"},
- {1, "R_MIPS_16"},
- {2, "R_MIPS_32"},
- {3, "R_MIPS_REL32"},
- {4, "R_MIPS_26"},
- {5, "R_MIPS_HI16"},
- {6, "R_MIPS_LO16"},
- {7, "R_MIPS_GPREL16"},
- {8, "R_MIPS_LITERAL"},
- {9, "R_MIPS_GOT16"},
- {10, "R_MIPS_PC16"},
- {11, "R_MIPS_CALL16"},
- {12, "R_MIPS_GPREL32"},
- {16, "R_MIPS_SHIFT5"},
- {17, "R_MIPS_SHIFT6"},
- {18, "R_MIPS_64"},
- {19, "R_MIPS_GOT_DISP"},
- {20, "R_MIPS_GOT_PAGE"},
- {21, "R_MIPS_GOT_OFST"},
- {22, "R_MIPS_GOT_HI16"},
- {23, "R_MIPS_GOT_LO16"},
- {24, "R_MIPS_SUB"},
- {25, "R_MIPS_INSERT_A"},
- {26, "R_MIPS_INSERT_B"},
- {27, "R_MIPS_DELETE"},
- {28, "R_MIPS_HIGHER"},
- {29, "R_MIPS_HIGHEST"},
- {30, "R_MIPS_CALL_HI16"},
- {31, "R_MIPS_CALL_LO16"},
- {32, "R_MIPS_SCN_DISP"},
- {33, "R_MIPS_REL16"},
- {34, "R_MIPS_ADD_IMMEDIATE"},
- {35, "R_MIPS_PJUMP"},
- {36, "R_MIPS_RELGOT"},
- {37, "R_MIPS_JALR"},
- {38, "R_MIPS_TLS_DTPMOD32"},
- {39, "R_MIPS_TLS_DTPREL32"},
- {40, "R_MIPS_TLS_DTPMOD64"},
- {41, "R_MIPS_TLS_DTPREL64"},
- {42, "R_MIPS_TLS_GD"},
- {43, "R_MIPS_TLS_LDM"},
- {44, "R_MIPS_TLS_DTPREL_HI16"},
- {45, "R_MIPS_TLS_DTPREL_LO16"},
- {46, "R_MIPS_TLS_GOTTPREL"},
- {47, "R_MIPS_TLS_TPREL32"},
- {48, "R_MIPS_TLS_TPREL64"},
- {49, "R_MIPS_TLS_TPREL_HI16"},
- {50, "R_MIPS_TLS_TPREL_LO16"},
-}
-
-func (i R_MIPS) String() string { return stringName(uint32(i), rmipsStrings, false) }
-func (i R_MIPS) GoString() string { return stringName(uint32(i), rmipsStrings, true) }
-
-// Relocation types for LoongArch.
-type R_LARCH int
-
-const (
- R_LARCH_NONE R_LARCH = 0
- R_LARCH_32 R_LARCH = 1
- R_LARCH_64 R_LARCH = 2
- R_LARCH_RELATIVE R_LARCH = 3
- R_LARCH_COPY R_LARCH = 4
- R_LARCH_JUMP_SLOT R_LARCH = 5
- R_LARCH_TLS_DTPMOD32 R_LARCH = 6
- R_LARCH_TLS_DTPMOD64 R_LARCH = 7
- R_LARCH_TLS_DTPREL32 R_LARCH = 8
- R_LARCH_TLS_DTPREL64 R_LARCH = 9
- R_LARCH_TLS_TPREL32 R_LARCH = 10
- R_LARCH_TLS_TPREL64 R_LARCH = 11
- R_LARCH_IRELATIVE R_LARCH = 12
- R_LARCH_MARK_LA R_LARCH = 20
- R_LARCH_MARK_PCREL R_LARCH = 21
- R_LARCH_SOP_PUSH_PCREL R_LARCH = 22
- R_LARCH_SOP_PUSH_ABSOLUTE R_LARCH = 23
- R_LARCH_SOP_PUSH_DUP R_LARCH = 24
- R_LARCH_SOP_PUSH_GPREL R_LARCH = 25
- R_LARCH_SOP_PUSH_TLS_TPREL R_LARCH = 26
- R_LARCH_SOP_PUSH_TLS_GOT R_LARCH = 27
- R_LARCH_SOP_PUSH_TLS_GD R_LARCH = 28
- R_LARCH_SOP_PUSH_PLT_PCREL R_LARCH = 29
- R_LARCH_SOP_ASSERT R_LARCH = 30
- R_LARCH_SOP_NOT R_LARCH = 31
- R_LARCH_SOP_SUB R_LARCH = 32
- R_LARCH_SOP_SL R_LARCH = 33
- R_LARCH_SOP_SR R_LARCH = 34
- R_LARCH_SOP_ADD R_LARCH = 35
- R_LARCH_SOP_AND R_LARCH = 36
- R_LARCH_SOP_IF_ELSE R_LARCH = 37
- R_LARCH_SOP_POP_32_S_10_5 R_LARCH = 38
- R_LARCH_SOP_POP_32_U_10_12 R_LARCH = 39
- R_LARCH_SOP_POP_32_S_10_12 R_LARCH = 40
- R_LARCH_SOP_POP_32_S_10_16 R_LARCH = 41
- R_LARCH_SOP_POP_32_S_10_16_S2 R_LARCH = 42
- R_LARCH_SOP_POP_32_S_5_20 R_LARCH = 43
- R_LARCH_SOP_POP_32_S_0_5_10_16_S2 R_LARCH = 44
- R_LARCH_SOP_POP_32_S_0_10_10_16_S2 R_LARCH = 45
- R_LARCH_SOP_POP_32_U R_LARCH = 46
- R_LARCH_ADD8 R_LARCH = 47
- R_LARCH_ADD16 R_LARCH = 48
- R_LARCH_ADD24 R_LARCH = 49
- R_LARCH_ADD32 R_LARCH = 50
- R_LARCH_ADD64 R_LARCH = 51
- R_LARCH_SUB8 R_LARCH = 52
- R_LARCH_SUB16 R_LARCH = 53
- R_LARCH_SUB24 R_LARCH = 54
- R_LARCH_SUB32 R_LARCH = 55
- R_LARCH_SUB64 R_LARCH = 56
- R_LARCH_GNU_VTINHERIT R_LARCH = 57
- R_LARCH_GNU_VTENTRY R_LARCH = 58
- R_LARCH_B16 R_LARCH = 64
- R_LARCH_B21 R_LARCH = 65
- R_LARCH_B26 R_LARCH = 66
- R_LARCH_ABS_HI20 R_LARCH = 67
- R_LARCH_ABS_LO12 R_LARCH = 68
- R_LARCH_ABS64_LO20 R_LARCH = 69
- R_LARCH_ABS64_HI12 R_LARCH = 70
- R_LARCH_PCALA_HI20 R_LARCH = 71
- R_LARCH_PCALA_LO12 R_LARCH = 72
- R_LARCH_PCALA64_LO20 R_LARCH = 73
- R_LARCH_PCALA64_HI12 R_LARCH = 74
- R_LARCH_GOT_PC_HI20 R_LARCH = 75
- R_LARCH_GOT_PC_LO12 R_LARCH = 76
- R_LARCH_GOT64_PC_LO20 R_LARCH = 77
- R_LARCH_GOT64_PC_HI12 R_LARCH = 78
- R_LARCH_GOT_HI20 R_LARCH = 79
- R_LARCH_GOT_LO12 R_LARCH = 80
- R_LARCH_GOT64_LO20 R_LARCH = 81
- R_LARCH_GOT64_HI12 R_LARCH = 82
- R_LARCH_TLS_LE_HI20 R_LARCH = 83
- R_LARCH_TLS_LE_LO12 R_LARCH = 84
- R_LARCH_TLS_LE64_LO20 R_LARCH = 85
- R_LARCH_TLS_LE64_HI12 R_LARCH = 86
- R_LARCH_TLS_IE_PC_HI20 R_LARCH = 87
- R_LARCH_TLS_IE_PC_LO12 R_LARCH = 88
- R_LARCH_TLS_IE64_PC_LO20 R_LARCH = 89
- R_LARCH_TLS_IE64_PC_HI12 R_LARCH = 90
- R_LARCH_TLS_IE_HI20 R_LARCH = 91
- R_LARCH_TLS_IE_LO12 R_LARCH = 92
- R_LARCH_TLS_IE64_LO20 R_LARCH = 93
- R_LARCH_TLS_IE64_HI12 R_LARCH = 94
- R_LARCH_TLS_LD_PC_HI20 R_LARCH = 95
- R_LARCH_TLS_LD_HI20 R_LARCH = 96
- R_LARCH_TLS_GD_PC_HI20 R_LARCH = 97
- R_LARCH_TLS_GD_HI20 R_LARCH = 98
- R_LARCH_32_PCREL R_LARCH = 99
- R_LARCH_RELAX R_LARCH = 100
-)
-
-var rlarchStrings = []intName{
- {0, "R_LARCH_NONE"},
- {1, "R_LARCH_32"},
- {2, "R_LARCH_64"},
- {3, "R_LARCH_RELATIVE"},
- {4, "R_LARCH_COPY"},
- {5, "R_LARCH_JUMP_SLOT"},
- {6, "R_LARCH_TLS_DTPMOD32"},
- {7, "R_LARCH_TLS_DTPMOD64"},
- {8, "R_LARCH_TLS_DTPREL32"},
- {9, "R_LARCH_TLS_DTPREL64"},
- {10, "R_LARCH_TLS_TPREL32"},
- {11, "R_LARCH_TLS_TPREL64"},
- {12, "R_LARCH_IRELATIVE"},
- {20, "R_LARCH_MARK_LA"},
- {21, "R_LARCH_MARK_PCREL"},
- {22, "R_LARCH_SOP_PUSH_PCREL"},
- {23, "R_LARCH_SOP_PUSH_ABSOLUTE"},
- {24, "R_LARCH_SOP_PUSH_DUP"},
- {25, "R_LARCH_SOP_PUSH_GPREL"},
- {26, "R_LARCH_SOP_PUSH_TLS_TPREL"},
- {27, "R_LARCH_SOP_PUSH_TLS_GOT"},
- {28, "R_LARCH_SOP_PUSH_TLS_GD"},
- {29, "R_LARCH_SOP_PUSH_PLT_PCREL"},
- {30, "R_LARCH_SOP_ASSERT"},
- {31, "R_LARCH_SOP_NOT"},
- {32, "R_LARCH_SOP_SUB"},
- {33, "R_LARCH_SOP_SL"},
- {34, "R_LARCH_SOP_SR"},
- {35, "R_LARCH_SOP_ADD"},
- {36, "R_LARCH_SOP_AND"},
- {37, "R_LARCH_SOP_IF_ELSE"},
- {38, "R_LARCH_SOP_POP_32_S_10_5"},
- {39, "R_LARCH_SOP_POP_32_U_10_12"},
- {40, "R_LARCH_SOP_POP_32_S_10_12"},
- {41, "R_LARCH_SOP_POP_32_S_10_16"},
- {42, "R_LARCH_SOP_POP_32_S_10_16_S2"},
- {43, "R_LARCH_SOP_POP_32_S_5_20"},
- {44, "R_LARCH_SOP_POP_32_S_0_5_10_16_S2"},
- {45, "R_LARCH_SOP_POP_32_S_0_10_10_16_S2"},
- {46, "R_LARCH_SOP_POP_32_U"},
- {47, "R_LARCH_ADD8"},
- {48, "R_LARCH_ADD16"},
- {49, "R_LARCH_ADD24"},
- {50, "R_LARCH_ADD32"},
- {51, "R_LARCH_ADD64"},
- {52, "R_LARCH_SUB8"},
- {53, "R_LARCH_SUB16"},
- {54, "R_LARCH_SUB24"},
- {55, "R_LARCH_SUB32"},
- {56, "R_LARCH_SUB64"},
- {57, "R_LARCH_GNU_VTINHERIT"},
- {58, "R_LARCH_GNU_VTENTRY"},
- {64, "R_LARCH_B16"},
- {65, "R_LARCH_B21"},
- {66, "R_LARCH_B26"},
- {67, "R_LARCH_ABS_HI20"},
- {68, "R_LARCH_ABS_LO12"},
- {69, "R_LARCH_ABS64_LO20"},
- {70, "R_LARCH_ABS64_HI12"},
- {71, "R_LARCH_PCALA_HI20"},
- {72, "R_LARCH_PCALA_LO12"},
- {73, "R_LARCH_PCALA64_LO20"},
- {74, "R_LARCH_PCALA64_HI12"},
- {75, "R_LARCH_GOT_PC_HI20"},
- {76, "R_LARCH_GOT_PC_LO12"},
- {77, "R_LARCH_GOT64_PC_LO20"},
- {78, "R_LARCH_GOT64_PC_HI12"},
- {79, "R_LARCH_GOT_HI20"},
- {80, "R_LARCH_GOT_LO12"},
- {81, "R_LARCH_GOT64_LO20"},
- {82, "R_LARCH_GOT64_HI12"},
- {83, "R_LARCH_TLS_LE_HI20"},
- {84, "R_LARCH_TLS_LE_LO12"},
- {85, "R_LARCH_TLS_LE64_LO20"},
- {86, "R_LARCH_TLS_LE64_HI12"},
- {87, "R_LARCH_TLS_IE_PC_HI20"},
- {88, "R_LARCH_TLS_IE_PC_LO12"},
- {89, "R_LARCH_TLS_IE64_PC_LO20"},
- {90, "R_LARCH_TLS_IE64_PC_HI12"},
- {91, "R_LARCH_TLS_IE_HI20"},
- {92, "R_LARCH_TLS_IE_LO12"},
- {93, "R_LARCH_TLS_IE64_LO20"},
- {94, "R_LARCH_TLS_IE64_HI12"},
- {95, "R_LARCH_TLS_LD_PC_HI20"},
- {96, "R_LARCH_TLS_LD_HI20"},
- {97, "R_LARCH_TLS_GD_PC_HI20"},
- {98, "R_LARCH_TLS_GD_HI20"},
- {99, "R_LARCH_32_PCREL"},
- {100, "R_LARCH_RELAX"},
-}
-
-func (i R_LARCH) String() string { return stringName(uint32(i), rlarchStrings, false) }
-func (i R_LARCH) GoString() string { return stringName(uint32(i), rlarchStrings, true) }
-
-// Relocation types for PowerPC.
-//
-// Values that are shared by both R_PPC and R_PPC64 are prefixed with
-// R_POWERPC_ in the ELF standard. For the R_PPC type, the relevant
-// shared relocations have been renamed with the prefix R_PPC_.
-// The original name follows the value in a comment.
-type R_PPC int
-
-const (
- R_PPC_NONE R_PPC = 0 // R_POWERPC_NONE
- R_PPC_ADDR32 R_PPC = 1 // R_POWERPC_ADDR32
- R_PPC_ADDR24 R_PPC = 2 // R_POWERPC_ADDR24
- R_PPC_ADDR16 R_PPC = 3 // R_POWERPC_ADDR16
- R_PPC_ADDR16_LO R_PPC = 4 // R_POWERPC_ADDR16_LO
- R_PPC_ADDR16_HI R_PPC = 5 // R_POWERPC_ADDR16_HI
- R_PPC_ADDR16_HA R_PPC = 6 // R_POWERPC_ADDR16_HA
- R_PPC_ADDR14 R_PPC = 7 // R_POWERPC_ADDR14
- R_PPC_ADDR14_BRTAKEN R_PPC = 8 // R_POWERPC_ADDR14_BRTAKEN
- R_PPC_ADDR14_BRNTAKEN R_PPC = 9 // R_POWERPC_ADDR14_BRNTAKEN
- R_PPC_REL24 R_PPC = 10 // R_POWERPC_REL24
- R_PPC_REL14 R_PPC = 11 // R_POWERPC_REL14
- R_PPC_REL14_BRTAKEN R_PPC = 12 // R_POWERPC_REL14_BRTAKEN
- R_PPC_REL14_BRNTAKEN R_PPC = 13 // R_POWERPC_REL14_BRNTAKEN
- R_PPC_GOT16 R_PPC = 14 // R_POWERPC_GOT16
- R_PPC_GOT16_LO R_PPC = 15 // R_POWERPC_GOT16_LO
- R_PPC_GOT16_HI R_PPC = 16 // R_POWERPC_GOT16_HI
- R_PPC_GOT16_HA R_PPC = 17 // R_POWERPC_GOT16_HA
- R_PPC_PLTREL24 R_PPC = 18
- R_PPC_COPY R_PPC = 19 // R_POWERPC_COPY
- R_PPC_GLOB_DAT R_PPC = 20 // R_POWERPC_GLOB_DAT
- R_PPC_JMP_SLOT R_PPC = 21 // R_POWERPC_JMP_SLOT
- R_PPC_RELATIVE R_PPC = 22 // R_POWERPC_RELATIVE
- R_PPC_LOCAL24PC R_PPC = 23
- R_PPC_UADDR32 R_PPC = 24 // R_POWERPC_UADDR32
- R_PPC_UADDR16 R_PPC = 25 // R_POWERPC_UADDR16
- R_PPC_REL32 R_PPC = 26 // R_POWERPC_REL32
- R_PPC_PLT32 R_PPC = 27 // R_POWERPC_PLT32
- R_PPC_PLTREL32 R_PPC = 28 // R_POWERPC_PLTREL32
- R_PPC_PLT16_LO R_PPC = 29 // R_POWERPC_PLT16_LO
- R_PPC_PLT16_HI R_PPC = 30 // R_POWERPC_PLT16_HI
- R_PPC_PLT16_HA R_PPC = 31 // R_POWERPC_PLT16_HA
- R_PPC_SDAREL16 R_PPC = 32
- R_PPC_SECTOFF R_PPC = 33 // R_POWERPC_SECTOFF
- R_PPC_SECTOFF_LO R_PPC = 34 // R_POWERPC_SECTOFF_LO
- R_PPC_SECTOFF_HI R_PPC = 35 // R_POWERPC_SECTOFF_HI
- R_PPC_SECTOFF_HA R_PPC = 36 // R_POWERPC_SECTOFF_HA
- R_PPC_TLS R_PPC = 67 // R_POWERPC_TLS
- R_PPC_DTPMOD32 R_PPC = 68 // R_POWERPC_DTPMOD32
- R_PPC_TPREL16 R_PPC = 69 // R_POWERPC_TPREL16
- R_PPC_TPREL16_LO R_PPC = 70 // R_POWERPC_TPREL16_LO
- R_PPC_TPREL16_HI R_PPC = 71 // R_POWERPC_TPREL16_HI
- R_PPC_TPREL16_HA R_PPC = 72 // R_POWERPC_TPREL16_HA
- R_PPC_TPREL32 R_PPC = 73 // R_POWERPC_TPREL32
- R_PPC_DTPREL16 R_PPC = 74 // R_POWERPC_DTPREL16
- R_PPC_DTPREL16_LO R_PPC = 75 // R_POWERPC_DTPREL16_LO
- R_PPC_DTPREL16_HI R_PPC = 76 // R_POWERPC_DTPREL16_HI
- R_PPC_DTPREL16_HA R_PPC = 77 // R_POWERPC_DTPREL16_HA
- R_PPC_DTPREL32 R_PPC = 78 // R_POWERPC_DTPREL32
- R_PPC_GOT_TLSGD16 R_PPC = 79 // R_POWERPC_GOT_TLSGD16
- R_PPC_GOT_TLSGD16_LO R_PPC = 80 // R_POWERPC_GOT_TLSGD16_LO
- R_PPC_GOT_TLSGD16_HI R_PPC = 81 // R_POWERPC_GOT_TLSGD16_HI
- R_PPC_GOT_TLSGD16_HA R_PPC = 82 // R_POWERPC_GOT_TLSGD16_HA
- R_PPC_GOT_TLSLD16 R_PPC = 83 // R_POWERPC_GOT_TLSLD16
- R_PPC_GOT_TLSLD16_LO R_PPC = 84 // R_POWERPC_GOT_TLSLD16_LO
- R_PPC_GOT_TLSLD16_HI R_PPC = 85 // R_POWERPC_GOT_TLSLD16_HI
- R_PPC_GOT_TLSLD16_HA R_PPC = 86 // R_POWERPC_GOT_TLSLD16_HA
- R_PPC_GOT_TPREL16 R_PPC = 87 // R_POWERPC_GOT_TPREL16
- R_PPC_GOT_TPREL16_LO R_PPC = 88 // R_POWERPC_GOT_TPREL16_LO
- R_PPC_GOT_TPREL16_HI R_PPC = 89 // R_POWERPC_GOT_TPREL16_HI
- R_PPC_GOT_TPREL16_HA R_PPC = 90 // R_POWERPC_GOT_TPREL16_HA
- R_PPC_EMB_NADDR32 R_PPC = 101
- R_PPC_EMB_NADDR16 R_PPC = 102
- R_PPC_EMB_NADDR16_LO R_PPC = 103
- R_PPC_EMB_NADDR16_HI R_PPC = 104
- R_PPC_EMB_NADDR16_HA R_PPC = 105
- R_PPC_EMB_SDAI16 R_PPC = 106
- R_PPC_EMB_SDA2I16 R_PPC = 107
- R_PPC_EMB_SDA2REL R_PPC = 108
- R_PPC_EMB_SDA21 R_PPC = 109
- R_PPC_EMB_MRKREF R_PPC = 110
- R_PPC_EMB_RELSEC16 R_PPC = 111
- R_PPC_EMB_RELST_LO R_PPC = 112
- R_PPC_EMB_RELST_HI R_PPC = 113
- R_PPC_EMB_RELST_HA R_PPC = 114
- R_PPC_EMB_BIT_FLD R_PPC = 115
- R_PPC_EMB_RELSDA R_PPC = 116
-)
-
-var rppcStrings = []intName{
- {0, "R_PPC_NONE"},
- {1, "R_PPC_ADDR32"},
- {2, "R_PPC_ADDR24"},
- {3, "R_PPC_ADDR16"},
- {4, "R_PPC_ADDR16_LO"},
- {5, "R_PPC_ADDR16_HI"},
- {6, "R_PPC_ADDR16_HA"},
- {7, "R_PPC_ADDR14"},
- {8, "R_PPC_ADDR14_BRTAKEN"},
- {9, "R_PPC_ADDR14_BRNTAKEN"},
- {10, "R_PPC_REL24"},
- {11, "R_PPC_REL14"},
- {12, "R_PPC_REL14_BRTAKEN"},
- {13, "R_PPC_REL14_BRNTAKEN"},
- {14, "R_PPC_GOT16"},
- {15, "R_PPC_GOT16_LO"},
- {16, "R_PPC_GOT16_HI"},
- {17, "R_PPC_GOT16_HA"},
- {18, "R_PPC_PLTREL24"},
- {19, "R_PPC_COPY"},
- {20, "R_PPC_GLOB_DAT"},
- {21, "R_PPC_JMP_SLOT"},
- {22, "R_PPC_RELATIVE"},
- {23, "R_PPC_LOCAL24PC"},
- {24, "R_PPC_UADDR32"},
- {25, "R_PPC_UADDR16"},
- {26, "R_PPC_REL32"},
- {27, "R_PPC_PLT32"},
- {28, "R_PPC_PLTREL32"},
- {29, "R_PPC_PLT16_LO"},
- {30, "R_PPC_PLT16_HI"},
- {31, "R_PPC_PLT16_HA"},
- {32, "R_PPC_SDAREL16"},
- {33, "R_PPC_SECTOFF"},
- {34, "R_PPC_SECTOFF_LO"},
- {35, "R_PPC_SECTOFF_HI"},
- {36, "R_PPC_SECTOFF_HA"},
- {67, "R_PPC_TLS"},
- {68, "R_PPC_DTPMOD32"},
- {69, "R_PPC_TPREL16"},
- {70, "R_PPC_TPREL16_LO"},
- {71, "R_PPC_TPREL16_HI"},
- {72, "R_PPC_TPREL16_HA"},
- {73, "R_PPC_TPREL32"},
- {74, "R_PPC_DTPREL16"},
- {75, "R_PPC_DTPREL16_LO"},
- {76, "R_PPC_DTPREL16_HI"},
- {77, "R_PPC_DTPREL16_HA"},
- {78, "R_PPC_DTPREL32"},
- {79, "R_PPC_GOT_TLSGD16"},
- {80, "R_PPC_GOT_TLSGD16_LO"},
- {81, "R_PPC_GOT_TLSGD16_HI"},
- {82, "R_PPC_GOT_TLSGD16_HA"},
- {83, "R_PPC_GOT_TLSLD16"},
- {84, "R_PPC_GOT_TLSLD16_LO"},
- {85, "R_PPC_GOT_TLSLD16_HI"},
- {86, "R_PPC_GOT_TLSLD16_HA"},
- {87, "R_PPC_GOT_TPREL16"},
- {88, "R_PPC_GOT_TPREL16_LO"},
- {89, "R_PPC_GOT_TPREL16_HI"},
- {90, "R_PPC_GOT_TPREL16_HA"},
- {101, "R_PPC_EMB_NADDR32"},
- {102, "R_PPC_EMB_NADDR16"},
- {103, "R_PPC_EMB_NADDR16_LO"},
- {104, "R_PPC_EMB_NADDR16_HI"},
- {105, "R_PPC_EMB_NADDR16_HA"},
- {106, "R_PPC_EMB_SDAI16"},
- {107, "R_PPC_EMB_SDA2I16"},
- {108, "R_PPC_EMB_SDA2REL"},
- {109, "R_PPC_EMB_SDA21"},
- {110, "R_PPC_EMB_MRKREF"},
- {111, "R_PPC_EMB_RELSEC16"},
- {112, "R_PPC_EMB_RELST_LO"},
- {113, "R_PPC_EMB_RELST_HI"},
- {114, "R_PPC_EMB_RELST_HA"},
- {115, "R_PPC_EMB_BIT_FLD"},
- {116, "R_PPC_EMB_RELSDA"},
-}
-
-func (i R_PPC) String() string { return stringName(uint32(i), rppcStrings, false) }
-func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) }
-
-// Relocation types for 64-bit PowerPC or Power Architecture processors.
-//
-// Values that are shared by both R_PPC and R_PPC64 are prefixed with
-// R_POWERPC_ in the ELF standard. For the R_PPC64 type, the relevant
-// shared relocations have been renamed with the prefix R_PPC64_.
-// The original name follows the value in a comment.
-type R_PPC64 int
-
-const (
- R_PPC64_NONE R_PPC64 = 0 // R_POWERPC_NONE
- R_PPC64_ADDR32 R_PPC64 = 1 // R_POWERPC_ADDR32
- R_PPC64_ADDR24 R_PPC64 = 2 // R_POWERPC_ADDR24
- R_PPC64_ADDR16 R_PPC64 = 3 // R_POWERPC_ADDR16
- R_PPC64_ADDR16_LO R_PPC64 = 4 // R_POWERPC_ADDR16_LO
- R_PPC64_ADDR16_HI R_PPC64 = 5 // R_POWERPC_ADDR16_HI
- R_PPC64_ADDR16_HA R_PPC64 = 6 // R_POWERPC_ADDR16_HA
- R_PPC64_ADDR14 R_PPC64 = 7 // R_POWERPC_ADDR14
- R_PPC64_ADDR14_BRTAKEN R_PPC64 = 8 // R_POWERPC_ADDR14_BRTAKEN
- R_PPC64_ADDR14_BRNTAKEN R_PPC64 = 9 // R_POWERPC_ADDR14_BRNTAKEN
- R_PPC64_REL24 R_PPC64 = 10 // R_POWERPC_REL24
- R_PPC64_REL14 R_PPC64 = 11 // R_POWERPC_REL14
- R_PPC64_REL14_BRTAKEN R_PPC64 = 12 // R_POWERPC_REL14_BRTAKEN
- R_PPC64_REL14_BRNTAKEN R_PPC64 = 13 // R_POWERPC_REL14_BRNTAKEN
- R_PPC64_GOT16 R_PPC64 = 14 // R_POWERPC_GOT16
- R_PPC64_GOT16_LO R_PPC64 = 15 // R_POWERPC_GOT16_LO
- R_PPC64_GOT16_HI R_PPC64 = 16 // R_POWERPC_GOT16_HI
- R_PPC64_GOT16_HA R_PPC64 = 17 // R_POWERPC_GOT16_HA
- R_PPC64_COPY R_PPC64 = 19 // R_POWERPC_COPY
- R_PPC64_GLOB_DAT R_PPC64 = 20 // R_POWERPC_GLOB_DAT
- R_PPC64_JMP_SLOT R_PPC64 = 21 // R_POWERPC_JMP_SLOT
- R_PPC64_RELATIVE R_PPC64 = 22 // R_POWERPC_RELATIVE
- R_PPC64_UADDR32 R_PPC64 = 24 // R_POWERPC_UADDR32
- R_PPC64_UADDR16 R_PPC64 = 25 // R_POWERPC_UADDR16
- R_PPC64_REL32 R_PPC64 = 26 // R_POWERPC_REL32
- R_PPC64_PLT32 R_PPC64 = 27 // R_POWERPC_PLT32
- R_PPC64_PLTREL32 R_PPC64 = 28 // R_POWERPC_PLTREL32
- R_PPC64_PLT16_LO R_PPC64 = 29 // R_POWERPC_PLT16_LO
- R_PPC64_PLT16_HI R_PPC64 = 30 // R_POWERPC_PLT16_HI
- R_PPC64_PLT16_HA R_PPC64 = 31 // R_POWERPC_PLT16_HA
- R_PPC64_SECTOFF R_PPC64 = 33 // R_POWERPC_SECTOFF
- R_PPC64_SECTOFF_LO R_PPC64 = 34 // R_POWERPC_SECTOFF_LO
- R_PPC64_SECTOFF_HI R_PPC64 = 35 // R_POWERPC_SECTOFF_HI
- R_PPC64_SECTOFF_HA R_PPC64 = 36 // R_POWERPC_SECTOFF_HA
- R_PPC64_REL30 R_PPC64 = 37 // R_POWERPC_ADDR30
- R_PPC64_ADDR64 R_PPC64 = 38
- R_PPC64_ADDR16_HIGHER R_PPC64 = 39
- R_PPC64_ADDR16_HIGHERA R_PPC64 = 40
- R_PPC64_ADDR16_HIGHEST R_PPC64 = 41
- R_PPC64_ADDR16_HIGHESTA R_PPC64 = 42
- R_PPC64_UADDR64 R_PPC64 = 43
- R_PPC64_REL64 R_PPC64 = 44
- R_PPC64_PLT64 R_PPC64 = 45
- R_PPC64_PLTREL64 R_PPC64 = 46
- R_PPC64_TOC16 R_PPC64 = 47
- R_PPC64_TOC16_LO R_PPC64 = 48
- R_PPC64_TOC16_HI R_PPC64 = 49
- R_PPC64_TOC16_HA R_PPC64 = 50
- R_PPC64_TOC R_PPC64 = 51
- R_PPC64_PLTGOT16 R_PPC64 = 52
- R_PPC64_PLTGOT16_LO R_PPC64 = 53
- R_PPC64_PLTGOT16_HI R_PPC64 = 54
- R_PPC64_PLTGOT16_HA R_PPC64 = 55
- R_PPC64_ADDR16_DS R_PPC64 = 56
- R_PPC64_ADDR16_LO_DS R_PPC64 = 57
- R_PPC64_GOT16_DS R_PPC64 = 58
- R_PPC64_GOT16_LO_DS R_PPC64 = 59
- R_PPC64_PLT16_LO_DS R_PPC64 = 60
- R_PPC64_SECTOFF_DS R_PPC64 = 61
- R_PPC64_SECTOFF_LO_DS R_PPC64 = 62
- R_PPC64_TOC16_DS R_PPC64 = 63
- R_PPC64_TOC16_LO_DS R_PPC64 = 64
- R_PPC64_PLTGOT16_DS R_PPC64 = 65
- R_PPC64_PLTGOT_LO_DS R_PPC64 = 66
- R_PPC64_TLS R_PPC64 = 67 // R_POWERPC_TLS
- R_PPC64_DTPMOD64 R_PPC64 = 68 // R_POWERPC_DTPMOD64
- R_PPC64_TPREL16 R_PPC64 = 69 // R_POWERPC_TPREL16
- R_PPC64_TPREL16_LO R_PPC64 = 70 // R_POWERPC_TPREL16_LO
- R_PPC64_TPREL16_HI R_PPC64 = 71 // R_POWERPC_TPREL16_HI
- R_PPC64_TPREL16_HA R_PPC64 = 72 // R_POWERPC_TPREL16_HA
- R_PPC64_TPREL64 R_PPC64 = 73 // R_POWERPC_TPREL64
- R_PPC64_DTPREL16 R_PPC64 = 74 // R_POWERPC_DTPREL16
- R_PPC64_DTPREL16_LO R_PPC64 = 75 // R_POWERPC_DTPREL16_LO
- R_PPC64_DTPREL16_HI R_PPC64 = 76 // R_POWERPC_DTPREL16_HI
- R_PPC64_DTPREL16_HA R_PPC64 = 77 // R_POWERPC_DTPREL16_HA
- R_PPC64_DTPREL64 R_PPC64 = 78 // R_POWERPC_DTPREL64
- R_PPC64_GOT_TLSGD16 R_PPC64 = 79 // R_POWERPC_GOT_TLSGD16
- R_PPC64_GOT_TLSGD16_LO R_PPC64 = 80 // R_POWERPC_GOT_TLSGD16_LO
- R_PPC64_GOT_TLSGD16_HI R_PPC64 = 81 // R_POWERPC_GOT_TLSGD16_HI
- R_PPC64_GOT_TLSGD16_HA R_PPC64 = 82 // R_POWERPC_GOT_TLSGD16_HA
- R_PPC64_GOT_TLSLD16 R_PPC64 = 83 // R_POWERPC_GOT_TLSLD16
- R_PPC64_GOT_TLSLD16_LO R_PPC64 = 84 // R_POWERPC_GOT_TLSLD16_LO
- R_PPC64_GOT_TLSLD16_HI R_PPC64 = 85 // R_POWERPC_GOT_TLSLD16_HI
- R_PPC64_GOT_TLSLD16_HA R_PPC64 = 86 // R_POWERPC_GOT_TLSLD16_HA
- R_PPC64_GOT_TPREL16_DS R_PPC64 = 87 // R_POWERPC_GOT_TPREL16_DS
- R_PPC64_GOT_TPREL16_LO_DS R_PPC64 = 88 // R_POWERPC_GOT_TPREL16_LO_DS
- R_PPC64_GOT_TPREL16_HI R_PPC64 = 89 // R_POWERPC_GOT_TPREL16_HI
- R_PPC64_GOT_TPREL16_HA R_PPC64 = 90 // R_POWERPC_GOT_TPREL16_HA
- R_PPC64_GOT_DTPREL16_DS R_PPC64 = 91 // R_POWERPC_GOT_DTPREL16_DS
- R_PPC64_GOT_DTPREL16_LO_DS R_PPC64 = 92 // R_POWERPC_GOT_DTPREL16_LO_DS
- R_PPC64_GOT_DTPREL16_HI R_PPC64 = 93 // R_POWERPC_GOT_DTPREL16_HI
- R_PPC64_GOT_DTPREL16_HA R_PPC64 = 94 // R_POWERPC_GOT_DTPREL16_HA
- R_PPC64_TPREL16_DS R_PPC64 = 95
- R_PPC64_TPREL16_LO_DS R_PPC64 = 96
- R_PPC64_TPREL16_HIGHER R_PPC64 = 97
- R_PPC64_TPREL16_HIGHERA R_PPC64 = 98
- R_PPC64_TPREL16_HIGHEST R_PPC64 = 99
- R_PPC64_TPREL16_HIGHESTA R_PPC64 = 100
- R_PPC64_DTPREL16_DS R_PPC64 = 101
- R_PPC64_DTPREL16_LO_DS R_PPC64 = 102
- R_PPC64_DTPREL16_HIGHER R_PPC64 = 103
- R_PPC64_DTPREL16_HIGHERA R_PPC64 = 104
- R_PPC64_DTPREL16_HIGHEST R_PPC64 = 105
- R_PPC64_DTPREL16_HIGHESTA R_PPC64 = 106
- R_PPC64_TLSGD R_PPC64 = 107
- R_PPC64_TLSLD R_PPC64 = 108
- R_PPC64_TOCSAVE R_PPC64 = 109
- R_PPC64_ADDR16_HIGH R_PPC64 = 110
- R_PPC64_ADDR16_HIGHA R_PPC64 = 111
- R_PPC64_TPREL16_HIGH R_PPC64 = 112
- R_PPC64_TPREL16_HIGHA R_PPC64 = 113
- R_PPC64_DTPREL16_HIGH R_PPC64 = 114
- R_PPC64_DTPREL16_HIGHA R_PPC64 = 115
- R_PPC64_REL24_NOTOC R_PPC64 = 116
- R_PPC64_ADDR64_LOCAL R_PPC64 = 117
- R_PPC64_ENTRY R_PPC64 = 118
- R_PPC64_PLTSEQ R_PPC64 = 119
- R_PPC64_PLTCALL R_PPC64 = 120
- R_PPC64_PLTSEQ_NOTOC R_PPC64 = 121
- R_PPC64_PLTCALL_NOTOC R_PPC64 = 122
- R_PPC64_PCREL_OPT R_PPC64 = 123
- R_PPC64_D34 R_PPC64 = 128
- R_PPC64_D34_LO R_PPC64 = 129
- R_PPC64_D34_HI30 R_PPC64 = 130
- R_PPC64_D34_HA30 R_PPC64 = 131
- R_PPC64_PCREL34 R_PPC64 = 132
- R_PPC64_GOT_PCREL34 R_PPC64 = 133
- R_PPC64_PLT_PCREL34 R_PPC64 = 134
- R_PPC64_PLT_PCREL34_NOTOC R_PPC64 = 135
- R_PPC64_ADDR16_HIGHER34 R_PPC64 = 136
- R_PPC64_ADDR16_HIGHERA34 R_PPC64 = 137
- R_PPC64_ADDR16_HIGHEST34 R_PPC64 = 138
- R_PPC64_ADDR16_HIGHESTA34 R_PPC64 = 139
- R_PPC64_REL16_HIGHER34 R_PPC64 = 140
- R_PPC64_REL16_HIGHERA34 R_PPC64 = 141
- R_PPC64_REL16_HIGHEST34 R_PPC64 = 142
- R_PPC64_REL16_HIGHESTA34 R_PPC64 = 143
- R_PPC64_D28 R_PPC64 = 144
- R_PPC64_PCREL28 R_PPC64 = 145
- R_PPC64_TPREL34 R_PPC64 = 146
- R_PPC64_DTPREL34 R_PPC64 = 147
- R_PPC64_GOT_TLSGD_PCREL34 R_PPC64 = 148
- R_PPC64_GOT_TLSLD_PCREL34 R_PPC64 = 149
- R_PPC64_GOT_TPREL_PCREL34 R_PPC64 = 150
- R_PPC64_GOT_DTPREL_PCREL34 R_PPC64 = 151
- R_PPC64_REL16_HIGH R_PPC64 = 240
- R_PPC64_REL16_HIGHA R_PPC64 = 241
- R_PPC64_REL16_HIGHER R_PPC64 = 242
- R_PPC64_REL16_HIGHERA R_PPC64 = 243
- R_PPC64_REL16_HIGHEST R_PPC64 = 244
- R_PPC64_REL16_HIGHESTA R_PPC64 = 245
- R_PPC64_REL16DX_HA R_PPC64 = 246 // R_POWERPC_REL16DX_HA
- R_PPC64_JMP_IREL R_PPC64 = 247
- R_PPC64_IRELATIVE R_PPC64 = 248 // R_POWERPC_IRELATIVE
- R_PPC64_REL16 R_PPC64 = 249 // R_POWERPC_REL16
- R_PPC64_REL16_LO R_PPC64 = 250 // R_POWERPC_REL16_LO
- R_PPC64_REL16_HI R_PPC64 = 251 // R_POWERPC_REL16_HI
- R_PPC64_REL16_HA R_PPC64 = 252 // R_POWERPC_REL16_HA
- R_PPC64_GNU_VTINHERIT R_PPC64 = 253
- R_PPC64_GNU_VTENTRY R_PPC64 = 254
-)
-
-var rppc64Strings = []intName{
- {0, "R_PPC64_NONE"},
- {1, "R_PPC64_ADDR32"},
- {2, "R_PPC64_ADDR24"},
- {3, "R_PPC64_ADDR16"},
- {4, "R_PPC64_ADDR16_LO"},
- {5, "R_PPC64_ADDR16_HI"},
- {6, "R_PPC64_ADDR16_HA"},
- {7, "R_PPC64_ADDR14"},
- {8, "R_PPC64_ADDR14_BRTAKEN"},
- {9, "R_PPC64_ADDR14_BRNTAKEN"},
- {10, "R_PPC64_REL24"},
- {11, "R_PPC64_REL14"},
- {12, "R_PPC64_REL14_BRTAKEN"},
- {13, "R_PPC64_REL14_BRNTAKEN"},
- {14, "R_PPC64_GOT16"},
- {15, "R_PPC64_GOT16_LO"},
- {16, "R_PPC64_GOT16_HI"},
- {17, "R_PPC64_GOT16_HA"},
- {19, "R_PPC64_COPY"},
- {20, "R_PPC64_GLOB_DAT"},
- {21, "R_PPC64_JMP_SLOT"},
- {22, "R_PPC64_RELATIVE"},
- {24, "R_PPC64_UADDR32"},
- {25, "R_PPC64_UADDR16"},
- {26, "R_PPC64_REL32"},
- {27, "R_PPC64_PLT32"},
- {28, "R_PPC64_PLTREL32"},
- {29, "R_PPC64_PLT16_LO"},
- {30, "R_PPC64_PLT16_HI"},
- {31, "R_PPC64_PLT16_HA"},
- {33, "R_PPC64_SECTOFF"},
- {34, "R_PPC64_SECTOFF_LO"},
- {35, "R_PPC64_SECTOFF_HI"},
- {36, "R_PPC64_SECTOFF_HA"},
- {37, "R_PPC64_REL30"},
- {38, "R_PPC64_ADDR64"},
- {39, "R_PPC64_ADDR16_HIGHER"},
- {40, "R_PPC64_ADDR16_HIGHERA"},
- {41, "R_PPC64_ADDR16_HIGHEST"},
- {42, "R_PPC64_ADDR16_HIGHESTA"},
- {43, "R_PPC64_UADDR64"},
- {44, "R_PPC64_REL64"},
- {45, "R_PPC64_PLT64"},
- {46, "R_PPC64_PLTREL64"},
- {47, "R_PPC64_TOC16"},
- {48, "R_PPC64_TOC16_LO"},
- {49, "R_PPC64_TOC16_HI"},
- {50, "R_PPC64_TOC16_HA"},
- {51, "R_PPC64_TOC"},
- {52, "R_PPC64_PLTGOT16"},
- {53, "R_PPC64_PLTGOT16_LO"},
- {54, "R_PPC64_PLTGOT16_HI"},
- {55, "R_PPC64_PLTGOT16_HA"},
- {56, "R_PPC64_ADDR16_DS"},
- {57, "R_PPC64_ADDR16_LO_DS"},
- {58, "R_PPC64_GOT16_DS"},
- {59, "R_PPC64_GOT16_LO_DS"},
- {60, "R_PPC64_PLT16_LO_DS"},
- {61, "R_PPC64_SECTOFF_DS"},
- {62, "R_PPC64_SECTOFF_LO_DS"},
- {63, "R_PPC64_TOC16_DS"},
- {64, "R_PPC64_TOC16_LO_DS"},
- {65, "R_PPC64_PLTGOT16_DS"},
- {66, "R_PPC64_PLTGOT_LO_DS"},
- {67, "R_PPC64_TLS"},
- {68, "R_PPC64_DTPMOD64"},
- {69, "R_PPC64_TPREL16"},
- {70, "R_PPC64_TPREL16_LO"},
- {71, "R_PPC64_TPREL16_HI"},
- {72, "R_PPC64_TPREL16_HA"},
- {73, "R_PPC64_TPREL64"},
- {74, "R_PPC64_DTPREL16"},
- {75, "R_PPC64_DTPREL16_LO"},
- {76, "R_PPC64_DTPREL16_HI"},
- {77, "R_PPC64_DTPREL16_HA"},
- {78, "R_PPC64_DTPREL64"},
- {79, "R_PPC64_GOT_TLSGD16"},
- {80, "R_PPC64_GOT_TLSGD16_LO"},
- {81, "R_PPC64_GOT_TLSGD16_HI"},
- {82, "R_PPC64_GOT_TLSGD16_HA"},
- {83, "R_PPC64_GOT_TLSLD16"},
- {84, "R_PPC64_GOT_TLSLD16_LO"},
- {85, "R_PPC64_GOT_TLSLD16_HI"},
- {86, "R_PPC64_GOT_TLSLD16_HA"},
- {87, "R_PPC64_GOT_TPREL16_DS"},
- {88, "R_PPC64_GOT_TPREL16_LO_DS"},
- {89, "R_PPC64_GOT_TPREL16_HI"},
- {90, "R_PPC64_GOT_TPREL16_HA"},
- {91, "R_PPC64_GOT_DTPREL16_DS"},
- {92, "R_PPC64_GOT_DTPREL16_LO_DS"},
- {93, "R_PPC64_GOT_DTPREL16_HI"},
- {94, "R_PPC64_GOT_DTPREL16_HA"},
- {95, "R_PPC64_TPREL16_DS"},
- {96, "R_PPC64_TPREL16_LO_DS"},
- {97, "R_PPC64_TPREL16_HIGHER"},
- {98, "R_PPC64_TPREL16_HIGHERA"},
- {99, "R_PPC64_TPREL16_HIGHEST"},
- {100, "R_PPC64_TPREL16_HIGHESTA"},
- {101, "R_PPC64_DTPREL16_DS"},
- {102, "R_PPC64_DTPREL16_LO_DS"},
- {103, "R_PPC64_DTPREL16_HIGHER"},
- {104, "R_PPC64_DTPREL16_HIGHERA"},
- {105, "R_PPC64_DTPREL16_HIGHEST"},
- {106, "R_PPC64_DTPREL16_HIGHESTA"},
- {107, "R_PPC64_TLSGD"},
- {108, "R_PPC64_TLSLD"},
- {109, "R_PPC64_TOCSAVE"},
- {110, "R_PPC64_ADDR16_HIGH"},
- {111, "R_PPC64_ADDR16_HIGHA"},
- {112, "R_PPC64_TPREL16_HIGH"},
- {113, "R_PPC64_TPREL16_HIGHA"},
- {114, "R_PPC64_DTPREL16_HIGH"},
- {115, "R_PPC64_DTPREL16_HIGHA"},
- {116, "R_PPC64_REL24_NOTOC"},
- {117, "R_PPC64_ADDR64_LOCAL"},
- {118, "R_PPC64_ENTRY"},
- {119, "R_PPC64_PLTSEQ"},
- {120, "R_PPC64_PLTCALL"},
- {121, "R_PPC64_PLTSEQ_NOTOC"},
- {122, "R_PPC64_PLTCALL_NOTOC"},
- {123, "R_PPC64_PCREL_OPT"},
- {128, "R_PPC64_D34"},
- {129, "R_PPC64_D34_LO"},
- {130, "R_PPC64_D34_HI30"},
- {131, "R_PPC64_D34_HA30"},
- {132, "R_PPC64_PCREL34"},
- {133, "R_PPC64_GOT_PCREL34"},
- {134, "R_PPC64_PLT_PCREL34"},
- {135, "R_PPC64_PLT_PCREL34_NOTOC"},
- {136, "R_PPC64_ADDR16_HIGHER34"},
- {137, "R_PPC64_ADDR16_HIGHERA34"},
- {138, "R_PPC64_ADDR16_HIGHEST34"},
- {139, "R_PPC64_ADDR16_HIGHESTA34"},
- {140, "R_PPC64_REL16_HIGHER34"},
- {141, "R_PPC64_REL16_HIGHERA34"},
- {142, "R_PPC64_REL16_HIGHEST34"},
- {143, "R_PPC64_REL16_HIGHESTA34"},
- {144, "R_PPC64_D28"},
- {145, "R_PPC64_PCREL28"},
- {146, "R_PPC64_TPREL34"},
- {147, "R_PPC64_DTPREL34"},
- {148, "R_PPC64_GOT_TLSGD_PCREL34"},
- {149, "R_PPC64_GOT_TLSLD_PCREL34"},
- {150, "R_PPC64_GOT_TPREL_PCREL34"},
- {151, "R_PPC64_GOT_DTPREL_PCREL34"},
- {240, "R_PPC64_REL16_HIGH"},
- {241, "R_PPC64_REL16_HIGHA"},
- {242, "R_PPC64_REL16_HIGHER"},
- {243, "R_PPC64_REL16_HIGHERA"},
- {244, "R_PPC64_REL16_HIGHEST"},
- {245, "R_PPC64_REL16_HIGHESTA"},
- {246, "R_PPC64_REL16DX_HA"},
- {247, "R_PPC64_JMP_IREL"},
- {248, "R_PPC64_IRELATIVE"},
- {249, "R_PPC64_REL16"},
- {250, "R_PPC64_REL16_LO"},
- {251, "R_PPC64_REL16_HI"},
- {252, "R_PPC64_REL16_HA"},
- {253, "R_PPC64_GNU_VTINHERIT"},
- {254, "R_PPC64_GNU_VTENTRY"},
-}
-
-func (i R_PPC64) String() string { return stringName(uint32(i), rppc64Strings, false) }
-func (i R_PPC64) GoString() string { return stringName(uint32(i), rppc64Strings, true) }
-
-// Relocation types for RISC-V processors.
-type R_RISCV int
-
-const (
- R_RISCV_NONE R_RISCV = 0 /* No relocation. */
- R_RISCV_32 R_RISCV = 1 /* Add 32 bit zero extended symbol value */
- R_RISCV_64 R_RISCV = 2 /* Add 64 bit symbol value. */
- R_RISCV_RELATIVE R_RISCV = 3 /* Add load address of shared object. */
- R_RISCV_COPY R_RISCV = 4 /* Copy data from shared object. */
- R_RISCV_JUMP_SLOT R_RISCV = 5 /* Set GOT entry to code address. */
- R_RISCV_TLS_DTPMOD32 R_RISCV = 6 /* 32 bit ID of module containing symbol */
- R_RISCV_TLS_DTPMOD64 R_RISCV = 7 /* ID of module containing symbol */
- R_RISCV_TLS_DTPREL32 R_RISCV = 8 /* 32 bit relative offset in TLS block */
- R_RISCV_TLS_DTPREL64 R_RISCV = 9 /* Relative offset in TLS block */
- R_RISCV_TLS_TPREL32 R_RISCV = 10 /* 32 bit relative offset in static TLS block */
- R_RISCV_TLS_TPREL64 R_RISCV = 11 /* Relative offset in static TLS block */
- R_RISCV_BRANCH R_RISCV = 16 /* PC-relative branch */
- R_RISCV_JAL R_RISCV = 17 /* PC-relative jump */
- R_RISCV_CALL R_RISCV = 18 /* PC-relative call */
- R_RISCV_CALL_PLT R_RISCV = 19 /* PC-relative call (PLT) */
- R_RISCV_GOT_HI20 R_RISCV = 20 /* PC-relative GOT reference */
- R_RISCV_TLS_GOT_HI20 R_RISCV = 21 /* PC-relative TLS IE GOT offset */
- R_RISCV_TLS_GD_HI20 R_RISCV = 22 /* PC-relative TLS GD reference */
- R_RISCV_PCREL_HI20 R_RISCV = 23 /* PC-relative reference */
- R_RISCV_PCREL_LO12_I R_RISCV = 24 /* PC-relative reference */
- R_RISCV_PCREL_LO12_S R_RISCV = 25 /* PC-relative reference */
- R_RISCV_HI20 R_RISCV = 26 /* Absolute address */
- R_RISCV_LO12_I R_RISCV = 27 /* Absolute address */
- R_RISCV_LO12_S R_RISCV = 28 /* Absolute address */
- R_RISCV_TPREL_HI20 R_RISCV = 29 /* TLS LE thread offset */
- R_RISCV_TPREL_LO12_I R_RISCV = 30 /* TLS LE thread offset */
- R_RISCV_TPREL_LO12_S R_RISCV = 31 /* TLS LE thread offset */
- R_RISCV_TPREL_ADD R_RISCV = 32 /* TLS LE thread usage */
- R_RISCV_ADD8 R_RISCV = 33 /* 8-bit label addition */
- R_RISCV_ADD16 R_RISCV = 34 /* 16-bit label addition */
- R_RISCV_ADD32 R_RISCV = 35 /* 32-bit label addition */
- R_RISCV_ADD64 R_RISCV = 36 /* 64-bit label addition */
- R_RISCV_SUB8 R_RISCV = 37 /* 8-bit label subtraction */
- R_RISCV_SUB16 R_RISCV = 38 /* 16-bit label subtraction */
- R_RISCV_SUB32 R_RISCV = 39 /* 32-bit label subtraction */
- R_RISCV_SUB64 R_RISCV = 40 /* 64-bit label subtraction */
- R_RISCV_GNU_VTINHERIT R_RISCV = 41 /* GNU C++ vtable hierarchy */
- R_RISCV_GNU_VTENTRY R_RISCV = 42 /* GNU C++ vtable member usage */
- R_RISCV_ALIGN R_RISCV = 43 /* Alignment statement */
- R_RISCV_RVC_BRANCH R_RISCV = 44 /* PC-relative branch offset */
- R_RISCV_RVC_JUMP R_RISCV = 45 /* PC-relative jump offset */
- R_RISCV_RVC_LUI R_RISCV = 46 /* Absolute address */
- R_RISCV_GPREL_I R_RISCV = 47 /* GP-relative reference */
- R_RISCV_GPREL_S R_RISCV = 48 /* GP-relative reference */
- R_RISCV_TPREL_I R_RISCV = 49 /* TP-relative TLS LE load */
- R_RISCV_TPREL_S R_RISCV = 50 /* TP-relative TLS LE store */
- R_RISCV_RELAX R_RISCV = 51 /* Instruction pair can be relaxed */
- R_RISCV_SUB6 R_RISCV = 52 /* Local label subtraction */
- R_RISCV_SET6 R_RISCV = 53 /* Local label subtraction */
- R_RISCV_SET8 R_RISCV = 54 /* Local label subtraction */
- R_RISCV_SET16 R_RISCV = 55 /* Local label subtraction */
- R_RISCV_SET32 R_RISCV = 56 /* Local label subtraction */
- R_RISCV_32_PCREL R_RISCV = 57 /* 32-bit PC relative */
-)
-
-var rriscvStrings = []intName{
- {0, "R_RISCV_NONE"},
- {1, "R_RISCV_32"},
- {2, "R_RISCV_64"},
- {3, "R_RISCV_RELATIVE"},
- {4, "R_RISCV_COPY"},
- {5, "R_RISCV_JUMP_SLOT"},
- {6, "R_RISCV_TLS_DTPMOD32"},
- {7, "R_RISCV_TLS_DTPMOD64"},
- {8, "R_RISCV_TLS_DTPREL32"},
- {9, "R_RISCV_TLS_DTPREL64"},
- {10, "R_RISCV_TLS_TPREL32"},
- {11, "R_RISCV_TLS_TPREL64"},
- {16, "R_RISCV_BRANCH"},
- {17, "R_RISCV_JAL"},
- {18, "R_RISCV_CALL"},
- {19, "R_RISCV_CALL_PLT"},
- {20, "R_RISCV_GOT_HI20"},
- {21, "R_RISCV_TLS_GOT_HI20"},
- {22, "R_RISCV_TLS_GD_HI20"},
- {23, "R_RISCV_PCREL_HI20"},
- {24, "R_RISCV_PCREL_LO12_I"},
- {25, "R_RISCV_PCREL_LO12_S"},
- {26, "R_RISCV_HI20"},
- {27, "R_RISCV_LO12_I"},
- {28, "R_RISCV_LO12_S"},
- {29, "R_RISCV_TPREL_HI20"},
- {30, "R_RISCV_TPREL_LO12_I"},
- {31, "R_RISCV_TPREL_LO12_S"},
- {32, "R_RISCV_TPREL_ADD"},
- {33, "R_RISCV_ADD8"},
- {34, "R_RISCV_ADD16"},
- {35, "R_RISCV_ADD32"},
- {36, "R_RISCV_ADD64"},
- {37, "R_RISCV_SUB8"},
- {38, "R_RISCV_SUB16"},
- {39, "R_RISCV_SUB32"},
- {40, "R_RISCV_SUB64"},
- {41, "R_RISCV_GNU_VTINHERIT"},
- {42, "R_RISCV_GNU_VTENTRY"},
- {43, "R_RISCV_ALIGN"},
- {44, "R_RISCV_RVC_BRANCH"},
- {45, "R_RISCV_RVC_JUMP"},
- {46, "R_RISCV_RVC_LUI"},
- {47, "R_RISCV_GPREL_I"},
- {48, "R_RISCV_GPREL_S"},
- {49, "R_RISCV_TPREL_I"},
- {50, "R_RISCV_TPREL_S"},
- {51, "R_RISCV_RELAX"},
- {52, "R_RISCV_SUB6"},
- {53, "R_RISCV_SET6"},
- {54, "R_RISCV_SET8"},
- {55, "R_RISCV_SET16"},
- {56, "R_RISCV_SET32"},
- {57, "R_RISCV_32_PCREL"},
-}
-
-func (i R_RISCV) String() string { return stringName(uint32(i), rriscvStrings, false) }
-func (i R_RISCV) GoString() string { return stringName(uint32(i), rriscvStrings, true) }
-
-// Relocation types for s390x processors.
-type R_390 int
-
-const (
- R_390_NONE R_390 = 0
- R_390_8 R_390 = 1
- R_390_12 R_390 = 2
- R_390_16 R_390 = 3
- R_390_32 R_390 = 4
- R_390_PC32 R_390 = 5
- R_390_GOT12 R_390 = 6
- R_390_GOT32 R_390 = 7
- R_390_PLT32 R_390 = 8
- R_390_COPY R_390 = 9
- R_390_GLOB_DAT R_390 = 10
- R_390_JMP_SLOT R_390 = 11
- R_390_RELATIVE R_390 = 12
- R_390_GOTOFF R_390 = 13
- R_390_GOTPC R_390 = 14
- R_390_GOT16 R_390 = 15
- R_390_PC16 R_390 = 16
- R_390_PC16DBL R_390 = 17
- R_390_PLT16DBL R_390 = 18
- R_390_PC32DBL R_390 = 19
- R_390_PLT32DBL R_390 = 20
- R_390_GOTPCDBL R_390 = 21
- R_390_64 R_390 = 22
- R_390_PC64 R_390 = 23
- R_390_GOT64 R_390 = 24
- R_390_PLT64 R_390 = 25
- R_390_GOTENT R_390 = 26
- R_390_GOTOFF16 R_390 = 27
- R_390_GOTOFF64 R_390 = 28
- R_390_GOTPLT12 R_390 = 29
- R_390_GOTPLT16 R_390 = 30
- R_390_GOTPLT32 R_390 = 31
- R_390_GOTPLT64 R_390 = 32
- R_390_GOTPLTENT R_390 = 33
- R_390_GOTPLTOFF16 R_390 = 34
- R_390_GOTPLTOFF32 R_390 = 35
- R_390_GOTPLTOFF64 R_390 = 36
- R_390_TLS_LOAD R_390 = 37
- R_390_TLS_GDCALL R_390 = 38
- R_390_TLS_LDCALL R_390 = 39
- R_390_TLS_GD32 R_390 = 40
- R_390_TLS_GD64 R_390 = 41
- R_390_TLS_GOTIE12 R_390 = 42
- R_390_TLS_GOTIE32 R_390 = 43
- R_390_TLS_GOTIE64 R_390 = 44
- R_390_TLS_LDM32 R_390 = 45
- R_390_TLS_LDM64 R_390 = 46
- R_390_TLS_IE32 R_390 = 47
- R_390_TLS_IE64 R_390 = 48
- R_390_TLS_IEENT R_390 = 49
- R_390_TLS_LE32 R_390 = 50
- R_390_TLS_LE64 R_390 = 51
- R_390_TLS_LDO32 R_390 = 52
- R_390_TLS_LDO64 R_390 = 53
- R_390_TLS_DTPMOD R_390 = 54
- R_390_TLS_DTPOFF R_390 = 55
- R_390_TLS_TPOFF R_390 = 56
- R_390_20 R_390 = 57
- R_390_GOT20 R_390 = 58
- R_390_GOTPLT20 R_390 = 59
- R_390_TLS_GOTIE20 R_390 = 60
-)
-
-var r390Strings = []intName{
- {0, "R_390_NONE"},
- {1, "R_390_8"},
- {2, "R_390_12"},
- {3, "R_390_16"},
- {4, "R_390_32"},
- {5, "R_390_PC32"},
- {6, "R_390_GOT12"},
- {7, "R_390_GOT32"},
- {8, "R_390_PLT32"},
- {9, "R_390_COPY"},
- {10, "R_390_GLOB_DAT"},
- {11, "R_390_JMP_SLOT"},
- {12, "R_390_RELATIVE"},
- {13, "R_390_GOTOFF"},
- {14, "R_390_GOTPC"},
- {15, "R_390_GOT16"},
- {16, "R_390_PC16"},
- {17, "R_390_PC16DBL"},
- {18, "R_390_PLT16DBL"},
- {19, "R_390_PC32DBL"},
- {20, "R_390_PLT32DBL"},
- {21, "R_390_GOTPCDBL"},
- {22, "R_390_64"},
- {23, "R_390_PC64"},
- {24, "R_390_GOT64"},
- {25, "R_390_PLT64"},
- {26, "R_390_GOTENT"},
- {27, "R_390_GOTOFF16"},
- {28, "R_390_GOTOFF64"},
- {29, "R_390_GOTPLT12"},
- {30, "R_390_GOTPLT16"},
- {31, "R_390_GOTPLT32"},
- {32, "R_390_GOTPLT64"},
- {33, "R_390_GOTPLTENT"},
- {34, "R_390_GOTPLTOFF16"},
- {35, "R_390_GOTPLTOFF32"},
- {36, "R_390_GOTPLTOFF64"},
- {37, "R_390_TLS_LOAD"},
- {38, "R_390_TLS_GDCALL"},
- {39, "R_390_TLS_LDCALL"},
- {40, "R_390_TLS_GD32"},
- {41, "R_390_TLS_GD64"},
- {42, "R_390_TLS_GOTIE12"},
- {43, "R_390_TLS_GOTIE32"},
- {44, "R_390_TLS_GOTIE64"},
- {45, "R_390_TLS_LDM32"},
- {46, "R_390_TLS_LDM64"},
- {47, "R_390_TLS_IE32"},
- {48, "R_390_TLS_IE64"},
- {49, "R_390_TLS_IEENT"},
- {50, "R_390_TLS_LE32"},
- {51, "R_390_TLS_LE64"},
- {52, "R_390_TLS_LDO32"},
- {53, "R_390_TLS_LDO64"},
- {54, "R_390_TLS_DTPMOD"},
- {55, "R_390_TLS_DTPOFF"},
- {56, "R_390_TLS_TPOFF"},
- {57, "R_390_20"},
- {58, "R_390_GOT20"},
- {59, "R_390_GOTPLT20"},
- {60, "R_390_TLS_GOTIE20"},
-}
-
-func (i R_390) String() string { return stringName(uint32(i), r390Strings, false) }
-func (i R_390) GoString() string { return stringName(uint32(i), r390Strings, true) }
-
-// Relocation types for SPARC.
-type R_SPARC int
-
-const (
- R_SPARC_NONE R_SPARC = 0
- R_SPARC_8 R_SPARC = 1
- R_SPARC_16 R_SPARC = 2
- R_SPARC_32 R_SPARC = 3
- R_SPARC_DISP8 R_SPARC = 4
- R_SPARC_DISP16 R_SPARC = 5
- R_SPARC_DISP32 R_SPARC = 6
- R_SPARC_WDISP30 R_SPARC = 7
- R_SPARC_WDISP22 R_SPARC = 8
- R_SPARC_HI22 R_SPARC = 9
- R_SPARC_22 R_SPARC = 10
- R_SPARC_13 R_SPARC = 11
- R_SPARC_LO10 R_SPARC = 12
- R_SPARC_GOT10 R_SPARC = 13
- R_SPARC_GOT13 R_SPARC = 14
- R_SPARC_GOT22 R_SPARC = 15
- R_SPARC_PC10 R_SPARC = 16
- R_SPARC_PC22 R_SPARC = 17
- R_SPARC_WPLT30 R_SPARC = 18
- R_SPARC_COPY R_SPARC = 19
- R_SPARC_GLOB_DAT R_SPARC = 20
- R_SPARC_JMP_SLOT R_SPARC = 21
- R_SPARC_RELATIVE R_SPARC = 22
- R_SPARC_UA32 R_SPARC = 23
- R_SPARC_PLT32 R_SPARC = 24
- R_SPARC_HIPLT22 R_SPARC = 25
- R_SPARC_LOPLT10 R_SPARC = 26
- R_SPARC_PCPLT32 R_SPARC = 27
- R_SPARC_PCPLT22 R_SPARC = 28
- R_SPARC_PCPLT10 R_SPARC = 29
- R_SPARC_10 R_SPARC = 30
- R_SPARC_11 R_SPARC = 31
- R_SPARC_64 R_SPARC = 32
- R_SPARC_OLO10 R_SPARC = 33
- R_SPARC_HH22 R_SPARC = 34
- R_SPARC_HM10 R_SPARC = 35
- R_SPARC_LM22 R_SPARC = 36
- R_SPARC_PC_HH22 R_SPARC = 37
- R_SPARC_PC_HM10 R_SPARC = 38
- R_SPARC_PC_LM22 R_SPARC = 39
- R_SPARC_WDISP16 R_SPARC = 40
- R_SPARC_WDISP19 R_SPARC = 41
- R_SPARC_GLOB_JMP R_SPARC = 42
- R_SPARC_7 R_SPARC = 43
- R_SPARC_5 R_SPARC = 44
- R_SPARC_6 R_SPARC = 45
- R_SPARC_DISP64 R_SPARC = 46
- R_SPARC_PLT64 R_SPARC = 47
- R_SPARC_HIX22 R_SPARC = 48
- R_SPARC_LOX10 R_SPARC = 49
- R_SPARC_H44 R_SPARC = 50
- R_SPARC_M44 R_SPARC = 51
- R_SPARC_L44 R_SPARC = 52
- R_SPARC_REGISTER R_SPARC = 53
- R_SPARC_UA64 R_SPARC = 54
- R_SPARC_UA16 R_SPARC = 55
-)
-
-var rsparcStrings = []intName{
- {0, "R_SPARC_NONE"},
- {1, "R_SPARC_8"},
- {2, "R_SPARC_16"},
- {3, "R_SPARC_32"},
- {4, "R_SPARC_DISP8"},
- {5, "R_SPARC_DISP16"},
- {6, "R_SPARC_DISP32"},
- {7, "R_SPARC_WDISP30"},
- {8, "R_SPARC_WDISP22"},
- {9, "R_SPARC_HI22"},
- {10, "R_SPARC_22"},
- {11, "R_SPARC_13"},
- {12, "R_SPARC_LO10"},
- {13, "R_SPARC_GOT10"},
- {14, "R_SPARC_GOT13"},
- {15, "R_SPARC_GOT22"},
- {16, "R_SPARC_PC10"},
- {17, "R_SPARC_PC22"},
- {18, "R_SPARC_WPLT30"},
- {19, "R_SPARC_COPY"},
- {20, "R_SPARC_GLOB_DAT"},
- {21, "R_SPARC_JMP_SLOT"},
- {22, "R_SPARC_RELATIVE"},
- {23, "R_SPARC_UA32"},
- {24, "R_SPARC_PLT32"},
- {25, "R_SPARC_HIPLT22"},
- {26, "R_SPARC_LOPLT10"},
- {27, "R_SPARC_PCPLT32"},
- {28, "R_SPARC_PCPLT22"},
- {29, "R_SPARC_PCPLT10"},
- {30, "R_SPARC_10"},
- {31, "R_SPARC_11"},
- {32, "R_SPARC_64"},
- {33, "R_SPARC_OLO10"},
- {34, "R_SPARC_HH22"},
- {35, "R_SPARC_HM10"},
- {36, "R_SPARC_LM22"},
- {37, "R_SPARC_PC_HH22"},
- {38, "R_SPARC_PC_HM10"},
- {39, "R_SPARC_PC_LM22"},
- {40, "R_SPARC_WDISP16"},
- {41, "R_SPARC_WDISP19"},
- {42, "R_SPARC_GLOB_JMP"},
- {43, "R_SPARC_7"},
- {44, "R_SPARC_5"},
- {45, "R_SPARC_6"},
- {46, "R_SPARC_DISP64"},
- {47, "R_SPARC_PLT64"},
- {48, "R_SPARC_HIX22"},
- {49, "R_SPARC_LOX10"},
- {50, "R_SPARC_H44"},
- {51, "R_SPARC_M44"},
- {52, "R_SPARC_L44"},
- {53, "R_SPARC_REGISTER"},
- {54, "R_SPARC_UA64"},
- {55, "R_SPARC_UA16"},
-}
-
-func (i R_SPARC) String() string { return stringName(uint32(i), rsparcStrings, false) }
-func (i R_SPARC) GoString() string { return stringName(uint32(i), rsparcStrings, true) }
-
-// Magic number for the elf trampoline, chosen wisely to be an immediate value.
-const ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
-
-// ELF32 File header.
-type Header32 struct {
- Ident [EI_NIDENT]byte /* File identification. */
- Type uint16 /* File type. */
- Machine uint16 /* Machine architecture. */
- Version uint32 /* ELF format version. */
- Entry uint32 /* Entry point. */
- Phoff uint32 /* Program header file offset. */
- Shoff uint32 /* Section header file offset. */
- Flags uint32 /* Architecture-specific flags. */
- Ehsize uint16 /* Size of ELF header in bytes. */
- Phentsize uint16 /* Size of program header entry. */
- Phnum uint16 /* Number of program header entries. */
- Shentsize uint16 /* Size of section header entry. */
- Shnum uint16 /* Number of section header entries. */
- Shstrndx uint16 /* Section name strings section. */
-}
-
-// ELF32 Section header.
-type Section32 struct {
- Name uint32 /* Section name (index into the section header string table). */
- Type uint32 /* Section type. */
- Flags uint32 /* Section flags. */
- Addr uint32 /* Address in memory image. */
- Off uint32 /* Offset in file. */
- Size uint32 /* Size in bytes. */
- Link uint32 /* Index of a related section. */
- Info uint32 /* Depends on section type. */
- Addralign uint32 /* Alignment in bytes. */
- Entsize uint32 /* Size of each entry in section. */
-}
-
-// ELF32 Program header.
-type Prog32 struct {
- Type uint32 /* Entry type. */
- Off uint32 /* File offset of contents. */
- Vaddr uint32 /* Virtual address in memory image. */
- Paddr uint32 /* Physical address (not used). */
- Filesz uint32 /* Size of contents in file. */
- Memsz uint32 /* Size of contents in memory. */
- Flags uint32 /* Access permission flags. */
- Align uint32 /* Alignment in memory and file. */
-}
-
-// ELF32 Dynamic structure. The ".dynamic" section contains an array of them.
-type Dyn32 struct {
- Tag int32 /* Entry type. */
- Val uint32 /* Integer/Address value. */
-}
-
-// ELF32 Compression header.
-type Chdr32 struct {
- Type uint32
- Size uint32
- Addralign uint32
-}
-
-/*
- * Relocation entries.
- */
-
-// ELF32 Relocations that don't need an addend field.
-type Rel32 struct {
- Off uint32 /* Location to be relocated. */
- Info uint32 /* Relocation type and symbol index. */
-}
-
-// ELF32 Relocations that need an addend field.
-type Rela32 struct {
- Off uint32 /* Location to be relocated. */
- Info uint32 /* Relocation type and symbol index. */
- Addend int32 /* Addend. */
-}
-
-func R_SYM32(info uint32) uint32 { return info >> 8 }
-func R_TYPE32(info uint32) uint32 { return info & 0xff }
-func R_INFO32(sym, typ uint32) uint32 { return sym<<8 | typ }
-
-// ELF32 Symbol.
-type Sym32 struct {
- Name uint32
- Value uint32
- Size uint32
- Info uint8
- Other uint8
- Shndx uint16
-}
-
-const Sym32Size = 16
-
-func ST_BIND(info uint8) SymBind { return SymBind(info >> 4) }
-func ST_TYPE(info uint8) SymType { return SymType(info & 0xF) }
-func ST_INFO(bind SymBind, typ SymType) uint8 {
- return uint8(bind)<<4 | uint8(typ)&0xf
-}
-func ST_VISIBILITY(other uint8) SymVis { return SymVis(other & 3) }
-
-/*
- * ELF64
- */
-
-// ELF64 file header.
-type Header64 struct {
- Ident [EI_NIDENT]byte /* File identification. */
- Type uint16 /* File type. */
- Machine uint16 /* Machine architecture. */
- Version uint32 /* ELF format version. */
- Entry uint64 /* Entry point. */
- Phoff uint64 /* Program header file offset. */
- Shoff uint64 /* Section header file offset. */
- Flags uint32 /* Architecture-specific flags. */
- Ehsize uint16 /* Size of ELF header in bytes. */
- Phentsize uint16 /* Size of program header entry. */
- Phnum uint16 /* Number of program header entries. */
- Shentsize uint16 /* Size of section header entry. */
- Shnum uint16 /* Number of section header entries. */
- Shstrndx uint16 /* Section name strings section. */
-}
-
-// ELF64 Section header.
-type Section64 struct {
- Name uint32 /* Section name (index into the section header string table). */
- Type uint32 /* Section type. */
- Flags uint64 /* Section flags. */
- Addr uint64 /* Address in memory image. */
- Off uint64 /* Offset in file. */
- Size uint64 /* Size in bytes. */
- Link uint32 /* Index of a related section. */
- Info uint32 /* Depends on section type. */
- Addralign uint64 /* Alignment in bytes. */
- Entsize uint64 /* Size of each entry in section. */
-}
-
-// ELF64 Program header.
-type Prog64 struct {
- Type uint32 /* Entry type. */
- Flags uint32 /* Access permission flags. */
- Off uint64 /* File offset of contents. */
- Vaddr uint64 /* Virtual address in memory image. */
- Paddr uint64 /* Physical address (not used). */
- Filesz uint64 /* Size of contents in file. */
- Memsz uint64 /* Size of contents in memory. */
- Align uint64 /* Alignment in memory and file. */
-}
-
-// ELF64 Dynamic structure. The ".dynamic" section contains an array of them.
-type Dyn64 struct {
- Tag int64 /* Entry type. */
- Val uint64 /* Integer/address value */
-}
-
-// ELF64 Compression header.
-type Chdr64 struct {
- Type uint32
- _ uint32 /* Reserved. */
- Size uint64
- Addralign uint64
-}
-
-/*
- * Relocation entries.
- */
-
-/* ELF64 relocations that don't need an addend field. */
-type Rel64 struct {
- Off uint64 /* Location to be relocated. */
- Info uint64 /* Relocation type and symbol index. */
-}
-
-/* ELF64 relocations that need an addend field. */
-type Rela64 struct {
- Off uint64 /* Location to be relocated. */
- Info uint64 /* Relocation type and symbol index. */
- Addend int64 /* Addend. */
-}
-
-func R_SYM64(info uint64) uint32 { return uint32(info >> 32) }
-func R_TYPE64(info uint64) uint32 { return uint32(info) }
-func R_INFO(sym, typ uint32) uint64 { return uint64(sym)<<32 | uint64(typ) }
-
-// ELF64 symbol table entries.
-type Sym64 struct {
- Name uint32 /* String table index of name. */
- Info uint8 /* Type and binding information. */
- Other uint8 /* Reserved (not used). */
- Shndx uint16 /* Section index of symbol. */
- Value uint64 /* Symbol value. */
- Size uint64 /* Size of associated object. */
-}
-
-const Sym64Size = 24
-
-type intName struct {
- i uint32
- s string
-}
-
-func stringName(i uint32, names []intName, goSyntax bool) string {
- for _, n := range names {
- if n.i == i {
- if goSyntax {
- return "elf." + n.s
- }
- return n.s
- }
- }
-
- // second pass - look for smaller to add with.
- // assume sorted already
- for j := len(names) - 1; j >= 0; j-- {
- n := names[j]
- if n.i < i {
- s := n.s
- if goSyntax {
- s = "elf." + s
- }
- return s + "+" + strconv.FormatUint(uint64(i-n.i), 10)
- }
- }
-
- return strconv.FormatUint(uint64(i), 10)
-}
-
-func flagName(i uint32, names []intName, goSyntax bool) string {
- s := ""
- for _, n := range names {
- if n.i&i == n.i {
- if len(s) > 0 {
- s += "+"
- }
- if goSyntax {
- s += "elf."
- }
- s += n.s
- i -= n.i
- }
- }
- if len(s) == 0 {
- return "0x" + strconv.FormatUint(uint64(i), 16)
- }
- if i != 0 {
- s += "+0x" + strconv.FormatUint(uint64(i), 16)
- }
- return s
-}
diff --git a/contrib/go/_std_1.20/src/debug/elf/file.go b/contrib/go/_std_1.20/src/debug/elf/file.go
deleted file mode 100644
index 88b957657b..0000000000
--- a/contrib/go/_std_1.20/src/debug/elf/file.go
+++ /dev/null
@@ -1,1649 +0,0 @@
-// Copyright 2009 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 elf implements access to ELF object files.
-
-# Security
-
-This package is not designed to be hardened against adversarial inputs, and is
-outside the scope of https://go.dev/security/policy. In particular, only basic
-validation is done when parsing object files. As such, care should be taken when
-parsing untrusted inputs, as parsing malformed files may consume significant
-resources, or cause panics.
-*/
-package elf
-
-import (
- "bytes"
- "compress/zlib"
- "debug/dwarf"
- "encoding/binary"
- "errors"
- "fmt"
- "internal/saferio"
- "io"
- "os"
- "strings"
-)
-
-// seekStart, seekCurrent, seekEnd are copies of
-// io.SeekStart, io.SeekCurrent, and io.SeekEnd.
-// We can't use the ones from package io because
-// we want this code to build with Go 1.4 during
-// cmd/dist bootstrap.
-const (
- seekStart int = 0
- seekCurrent int = 1
- seekEnd int = 2
-)
-
-// TODO: error reporting detail
-
-/*
- * Internal ELF representation
- */
-
-// A FileHeader represents an ELF file header.
-type FileHeader struct {
- Class Class
- Data Data
- Version Version
- OSABI OSABI
- ABIVersion uint8
- ByteOrder binary.ByteOrder
- Type Type
- Machine Machine
- Entry uint64
-}
-
-// A File represents an open ELF file.
-type File struct {
- FileHeader
- Sections []*Section
- Progs []*Prog
- closer io.Closer
- gnuNeed []verneed
- gnuVersym []byte
-}
-
-// A SectionHeader represents a single ELF section header.
-type SectionHeader struct {
- Name string
- Type SectionType
- Flags SectionFlag
- Addr uint64
- Offset uint64
- Size uint64
- Link uint32
- Info uint32
- Addralign uint64
- Entsize uint64
-
- // FileSize is the size of this section in the file in bytes.
- // If a section is compressed, FileSize is the size of the
- // compressed data, while Size (above) is the size of the
- // uncompressed data.
- FileSize uint64
-}
-
-// A Section represents a single section in an ELF file.
-type Section struct {
- SectionHeader
-
- // Embed ReaderAt for ReadAt method.
- // Do not embed SectionReader directly
- // to avoid having Read and Seek.
- // If a client wants Read and Seek it must use
- // Open() to avoid fighting over the seek offset
- // with other clients.
- //
- // ReaderAt may be nil if the section is not easily available
- // in a random-access form. For example, a compressed section
- // may have a nil ReaderAt.
- io.ReaderAt
- sr *io.SectionReader
-
- compressionType CompressionType
- compressionOffset int64
-}
-
-// Data reads and returns the contents of the ELF section.
-// Even if the section is stored compressed in the ELF file,
-// Data returns uncompressed data.
-//
-// For an SHT_NOBITS section, Data always returns a non-nil error.
-func (s *Section) Data() ([]byte, error) {
- return saferio.ReadData(s.Open(), s.Size)
-}
-
-// stringTable reads and returns the string table given by the
-// specified link value.
-func (f *File) stringTable(link uint32) ([]byte, error) {
- if link <= 0 || link >= uint32(len(f.Sections)) {
- return nil, errors.New("section has invalid string table link")
- }
- return f.Sections[link].Data()
-}
-
-// Open returns a new ReadSeeker reading the ELF section.
-// Even if the section is stored compressed in the ELF file,
-// the ReadSeeker reads uncompressed data.
-//
-// For an SHT_NOBITS section, all calls to the opened reader
-// will return a non-nil error.
-func (s *Section) Open() io.ReadSeeker {
- if s.Type == SHT_NOBITS {
- return io.NewSectionReader(&nobitsSectionReader{}, 0, int64(s.Size))
- }
- if s.Flags&SHF_COMPRESSED == 0 {
- return io.NewSectionReader(s.sr, 0, 1<<63-1)
- }
- if s.compressionType == COMPRESS_ZLIB {
- return &readSeekerFromReader{
- reset: func() (io.Reader, error) {
- fr := io.NewSectionReader(s.sr, s.compressionOffset, int64(s.FileSize)-s.compressionOffset)
- return zlib.NewReader(fr)
- },
- size: int64(s.Size),
- }
- }
- err := &FormatError{int64(s.Offset), "unknown compression type", s.compressionType}
- return errorReader{err}
-}
-
-// A ProgHeader represents a single ELF program header.
-type ProgHeader struct {
- Type ProgType
- Flags ProgFlag
- Off uint64
- Vaddr uint64
- Paddr uint64
- Filesz uint64
- Memsz uint64
- Align uint64
-}
-
-// A Prog represents a single ELF program header in an ELF binary.
-type Prog struct {
- ProgHeader
-
- // Embed ReaderAt for ReadAt method.
- // Do not embed SectionReader directly
- // to avoid having Read and Seek.
- // If a client wants Read and Seek it must use
- // Open() to avoid fighting over the seek offset
- // with other clients.
- io.ReaderAt
- sr *io.SectionReader
-}
-
-// Open returns a new ReadSeeker reading the ELF program body.
-func (p *Prog) Open() io.ReadSeeker { return io.NewSectionReader(p.sr, 0, 1<<63-1) }
-
-// A Symbol represents an entry in an ELF symbol table section.
-type Symbol struct {
- Name string
- Info, Other byte
- Section SectionIndex
- Value, Size uint64
-
- // Version and Library are present only for the dynamic symbol
- // table.
- Version string
- Library string
-}
-
-/*
- * ELF reader
- */
-
-type FormatError struct {
- off int64
- msg string
- val any
-}
-
-func (e *FormatError) Error() string {
- msg := e.msg
- if e.val != nil {
- msg += fmt.Sprintf(" '%v' ", e.val)
- }
- msg += fmt.Sprintf("in record at byte %#x", e.off)
- return msg
-}
-
-// Open opens the named file using os.Open and prepares it for use as an ELF binary.
-func Open(name string) (*File, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- ff, err := NewFile(f)
- if err != nil {
- f.Close()
- return nil, err
- }
- ff.closer = f
- return ff, nil
-}
-
-// Close closes the File.
-// If the File was created using NewFile directly instead of Open,
-// Close has no effect.
-func (f *File) Close() error {
- var err error
- if f.closer != nil {
- err = f.closer.Close()
- f.closer = nil
- }
- return err
-}
-
-// SectionByType returns the first section in f with the
-// given type, or nil if there is no such section.
-func (f *File) SectionByType(typ SectionType) *Section {
- for _, s := range f.Sections {
- if s.Type == typ {
- return s
- }
- }
- return nil
-}
-
-// NewFile creates a new File for accessing an ELF binary in an underlying reader.
-// The ELF binary is expected to start at position 0 in the ReaderAt.
-func NewFile(r io.ReaderAt) (*File, error) {
- sr := io.NewSectionReader(r, 0, 1<<63-1)
- // Read and decode ELF identifier
- var ident [16]uint8
- if _, err := r.ReadAt(ident[0:], 0); err != nil {
- return nil, err
- }
- if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' {
- return nil, &FormatError{0, "bad magic number", ident[0:4]}
- }
-
- f := new(File)
- f.Class = Class(ident[EI_CLASS])
- switch f.Class {
- case ELFCLASS32:
- case ELFCLASS64:
- // ok
- default:
- return nil, &FormatError{0, "unknown ELF class", f.Class}
- }
-
- f.Data = Data(ident[EI_DATA])
- switch f.Data {
- case ELFDATA2LSB:
- f.ByteOrder = binary.LittleEndian
- case ELFDATA2MSB:
- f.ByteOrder = binary.BigEndian
- default:
- return nil, &FormatError{0, "unknown ELF data encoding", f.Data}
- }
-
- f.Version = Version(ident[EI_VERSION])
- if f.Version != EV_CURRENT {
- return nil, &FormatError{0, "unknown ELF version", f.Version}
- }
-
- f.OSABI = OSABI(ident[EI_OSABI])
- f.ABIVersion = ident[EI_ABIVERSION]
-
- // Read ELF file header
- var phoff int64
- var phentsize, phnum int
- var shoff int64
- var shentsize, shnum, shstrndx int
- switch f.Class {
- case ELFCLASS32:
- hdr := new(Header32)
- sr.Seek(0, seekStart)
- if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
- return nil, err
- }
- f.Type = Type(hdr.Type)
- f.Machine = Machine(hdr.Machine)
- f.Entry = uint64(hdr.Entry)
- if v := Version(hdr.Version); v != f.Version {
- return nil, &FormatError{0, "mismatched ELF version", v}
- }
- phoff = int64(hdr.Phoff)
- phentsize = int(hdr.Phentsize)
- phnum = int(hdr.Phnum)
- shoff = int64(hdr.Shoff)
- shentsize = int(hdr.Shentsize)
- shnum = int(hdr.Shnum)
- shstrndx = int(hdr.Shstrndx)
- case ELFCLASS64:
- hdr := new(Header64)
- sr.Seek(0, seekStart)
- if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
- return nil, err
- }
- f.Type = Type(hdr.Type)
- f.Machine = Machine(hdr.Machine)
- f.Entry = hdr.Entry
- if v := Version(hdr.Version); v != f.Version {
- return nil, &FormatError{0, "mismatched ELF version", v}
- }
- phoff = int64(hdr.Phoff)
- phentsize = int(hdr.Phentsize)
- phnum = int(hdr.Phnum)
- shoff = int64(hdr.Shoff)
- shentsize = int(hdr.Shentsize)
- shnum = int(hdr.Shnum)
- shstrndx = int(hdr.Shstrndx)
- }
-
- if shoff < 0 {
- return nil, &FormatError{0, "invalid shoff", shoff}
- }
- if phoff < 0 {
- return nil, &FormatError{0, "invalid phoff", phoff}
- }
-
- if shoff == 0 && shnum != 0 {
- return nil, &FormatError{0, "invalid ELF shnum for shoff=0", shnum}
- }
-
- if shnum > 0 && shstrndx >= shnum {
- return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx}
- }
-
- var wantPhentsize, wantShentsize int
- switch f.Class {
- case ELFCLASS32:
- wantPhentsize = 8 * 4
- wantShentsize = 10 * 4
- case ELFCLASS64:
- wantPhentsize = 2*4 + 6*8
- wantShentsize = 4*4 + 6*8
- }
- if phnum > 0 && phentsize < wantPhentsize {
- return nil, &FormatError{0, "invalid ELF phentsize", phentsize}
- }
-
- // Read program headers
- f.Progs = make([]*Prog, phnum)
- for i := 0; i < phnum; i++ {
- off := phoff + int64(i)*int64(phentsize)
- sr.Seek(off, seekStart)
- p := new(Prog)
- switch f.Class {
- case ELFCLASS32:
- ph := new(Prog32)
- if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
- return nil, err
- }
- p.ProgHeader = ProgHeader{
- Type: ProgType(ph.Type),
- Flags: ProgFlag(ph.Flags),
- Off: uint64(ph.Off),
- Vaddr: uint64(ph.Vaddr),
- Paddr: uint64(ph.Paddr),
- Filesz: uint64(ph.Filesz),
- Memsz: uint64(ph.Memsz),
- Align: uint64(ph.Align),
- }
- case ELFCLASS64:
- ph := new(Prog64)
- if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
- return nil, err
- }
- p.ProgHeader = ProgHeader{
- Type: ProgType(ph.Type),
- Flags: ProgFlag(ph.Flags),
- Off: ph.Off,
- Vaddr: ph.Vaddr,
- Paddr: ph.Paddr,
- Filesz: ph.Filesz,
- Memsz: ph.Memsz,
- Align: ph.Align,
- }
- }
- if int64(p.Off) < 0 {
- return nil, &FormatError{off, "invalid program header offset", p.Off}
- }
- if int64(p.Filesz) < 0 {
- return nil, &FormatError{off, "invalid program header file size", p.Filesz}
- }
- p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz))
- p.ReaderAt = p.sr
- f.Progs[i] = p
- }
-
- // If the number of sections is greater than or equal to SHN_LORESERVE
- // (0xff00), shnum has the value zero and the actual number of section
- // header table entries is contained in the sh_size field of the section
- // header at index 0.
- if shoff > 0 && shnum == 0 {
- var typ, link uint32
- sr.Seek(shoff, seekStart)
- switch f.Class {
- case ELFCLASS32:
- sh := new(Section32)
- if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
- return nil, err
- }
- shnum = int(sh.Size)
- typ = sh.Type
- link = sh.Link
- case ELFCLASS64:
- sh := new(Section64)
- if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
- return nil, err
- }
- shnum = int(sh.Size)
- typ = sh.Type
- link = sh.Link
- }
- if SectionType(typ) != SHT_NULL {
- return nil, &FormatError{shoff, "invalid type of the initial section", SectionType(typ)}
- }
-
- if shnum < int(SHN_LORESERVE) {
- return nil, &FormatError{shoff, "invalid ELF shnum contained in sh_size", shnum}
- }
-
- // If the section name string table section index is greater than or
- // equal to SHN_LORESERVE (0xff00), this member has the value
- // SHN_XINDEX (0xffff) and the actual index of the section name
- // string table section is contained in the sh_link field of the
- // section header at index 0.
- if shstrndx == int(SHN_XINDEX) {
- shstrndx = int(link)
- if shstrndx < int(SHN_LORESERVE) {
- return nil, &FormatError{shoff, "invalid ELF shstrndx contained in sh_link", shstrndx}
- }
- }
- }
-
- if shnum > 0 && shentsize < wantShentsize {
- return nil, &FormatError{0, "invalid ELF shentsize", shentsize}
- }
-
- // Read section headers
- c := saferio.SliceCap((*Section)(nil), uint64(shnum))
- if c < 0 {
- return nil, &FormatError{0, "too many sections", shnum}
- }
- f.Sections = make([]*Section, 0, c)
- names := make([]uint32, 0, c)
- for i := 0; i < shnum; i++ {
- off := shoff + int64(i)*int64(shentsize)
- sr.Seek(off, seekStart)
- s := new(Section)
- switch f.Class {
- case ELFCLASS32:
- sh := new(Section32)
- if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
- return nil, err
- }
- names = append(names, sh.Name)
- s.SectionHeader = SectionHeader{
- Type: SectionType(sh.Type),
- Flags: SectionFlag(sh.Flags),
- Addr: uint64(sh.Addr),
- Offset: uint64(sh.Off),
- FileSize: uint64(sh.Size),
- Link: sh.Link,
- Info: sh.Info,
- Addralign: uint64(sh.Addralign),
- Entsize: uint64(sh.Entsize),
- }
- case ELFCLASS64:
- sh := new(Section64)
- if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
- return nil, err
- }
- names = append(names, sh.Name)
- s.SectionHeader = SectionHeader{
- Type: SectionType(sh.Type),
- Flags: SectionFlag(sh.Flags),
- Offset: sh.Off,
- FileSize: sh.Size,
- Addr: sh.Addr,
- Link: sh.Link,
- Info: sh.Info,
- Addralign: sh.Addralign,
- Entsize: sh.Entsize,
- }
- }
- if int64(s.Offset) < 0 {
- return nil, &FormatError{off, "invalid section offset", int64(s.Offset)}
- }
- if int64(s.FileSize) < 0 {
- return nil, &FormatError{off, "invalid section size", int64(s.FileSize)}
- }
- s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.FileSize))
-
- if s.Flags&SHF_COMPRESSED == 0 {
- s.ReaderAt = s.sr
- s.Size = s.FileSize
- } else {
- // Read the compression header.
- switch f.Class {
- case ELFCLASS32:
- ch := new(Chdr32)
- if err := binary.Read(s.sr, f.ByteOrder, ch); err != nil {
- return nil, err
- }
- s.compressionType = CompressionType(ch.Type)
- s.Size = uint64(ch.Size)
- s.Addralign = uint64(ch.Addralign)
- s.compressionOffset = int64(binary.Size(ch))
- case ELFCLASS64:
- ch := new(Chdr64)
- if err := binary.Read(s.sr, f.ByteOrder, ch); err != nil {
- return nil, err
- }
- s.compressionType = CompressionType(ch.Type)
- s.Size = ch.Size
- s.Addralign = ch.Addralign
- s.compressionOffset = int64(binary.Size(ch))
- }
- }
-
- f.Sections = append(f.Sections, s)
- }
-
- if len(f.Sections) == 0 {
- return f, nil
- }
-
- // Load section header string table.
- if shstrndx == 0 {
- // If the file has no section name string table,
- // shstrndx holds the value SHN_UNDEF (0).
- return f, nil
- }
- shstr := f.Sections[shstrndx]
- if shstr.Type != SHT_STRTAB {
- return nil, &FormatError{shoff + int64(shstrndx*shentsize), "invalid ELF section name string table type", shstr.Type}
- }
- shstrtab, err := shstr.Data()
- if err != nil {
- return nil, err
- }
- for i, s := range f.Sections {
- var ok bool
- s.Name, ok = getString(shstrtab, int(names[i]))
- if !ok {
- return nil, &FormatError{shoff + int64(i*shentsize), "bad section name index", names[i]}
- }
- }
-
- return f, nil
-}
-
-// getSymbols returns a slice of Symbols from parsing the symbol table
-// with the given type, along with the associated string table.
-func (f *File) getSymbols(typ SectionType) ([]Symbol, []byte, error) {
- switch f.Class {
- case ELFCLASS64:
- return f.getSymbols64(typ)
-
- case ELFCLASS32:
- return f.getSymbols32(typ)
- }
-
- return nil, nil, errors.New("not implemented")
-}
-
-// ErrNoSymbols is returned by File.Symbols and File.DynamicSymbols
-// if there is no such section in the File.
-var ErrNoSymbols = errors.New("no symbol section")
-
-func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) {
- symtabSection := f.SectionByType(typ)
- if symtabSection == nil {
- return nil, nil, ErrNoSymbols
- }
-
- data, err := symtabSection.Data()
- if err != nil {
- return nil, nil, fmt.Errorf("cannot load symbol section: %w", err)
- }
- symtab := bytes.NewReader(data)
- if symtab.Len()%Sym32Size != 0 {
- return nil, nil, errors.New("length of symbol section is not a multiple of SymSize")
- }
-
- strdata, err := f.stringTable(symtabSection.Link)
- if err != nil {
- return nil, nil, fmt.Errorf("cannot load string table section: %w", err)
- }
-
- // The first entry is all zeros.
- var skip [Sym32Size]byte
- symtab.Read(skip[:])
-
- symbols := make([]Symbol, symtab.Len()/Sym32Size)
-
- i := 0
- var sym Sym32
- for symtab.Len() > 0 {
- binary.Read(symtab, f.ByteOrder, &sym)
- str, _ := getString(strdata, int(sym.Name))
- symbols[i].Name = str
- symbols[i].Info = sym.Info
- symbols[i].Other = sym.Other
- symbols[i].Section = SectionIndex(sym.Shndx)
- symbols[i].Value = uint64(sym.Value)
- symbols[i].Size = uint64(sym.Size)
- i++
- }
-
- return symbols, strdata, nil
-}
-
-func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) {
- symtabSection := f.SectionByType(typ)
- if symtabSection == nil {
- return nil, nil, ErrNoSymbols
- }
-
- data, err := symtabSection.Data()
- if err != nil {
- return nil, nil, fmt.Errorf("cannot load symbol section: %w", err)
- }
- symtab := bytes.NewReader(data)
- if symtab.Len()%Sym64Size != 0 {
- return nil, nil, errors.New("length of symbol section is not a multiple of Sym64Size")
- }
-
- strdata, err := f.stringTable(symtabSection.Link)
- if err != nil {
- return nil, nil, fmt.Errorf("cannot load string table section: %w", err)
- }
-
- // The first entry is all zeros.
- var skip [Sym64Size]byte
- symtab.Read(skip[:])
-
- symbols := make([]Symbol, symtab.Len()/Sym64Size)
-
- i := 0
- var sym Sym64
- for symtab.Len() > 0 {
- binary.Read(symtab, f.ByteOrder, &sym)
- str, _ := getString(strdata, int(sym.Name))
- symbols[i].Name = str
- symbols[i].Info = sym.Info
- symbols[i].Other = sym.Other
- symbols[i].Section = SectionIndex(sym.Shndx)
- symbols[i].Value = sym.Value
- symbols[i].Size = sym.Size
- i++
- }
-
- return symbols, strdata, nil
-}
-
-// getString extracts a string from an ELF string table.
-func getString(section []byte, start int) (string, bool) {
- if start < 0 || start >= len(section) {
- return "", false
- }
-
- for end := start; end < len(section); end++ {
- if section[end] == 0 {
- return string(section[start:end]), true
- }
- }
- return "", false
-}
-
-// Section returns a section with the given name, or nil if no such
-// section exists.
-func (f *File) Section(name string) *Section {
- for _, s := range f.Sections {
- if s.Name == name {
- return s
- }
- }
- return nil
-}
-
-// applyRelocations applies relocations to dst. rels is a relocations section
-// in REL or RELA format.
-func (f *File) applyRelocations(dst []byte, rels []byte) error {
- switch {
- case f.Class == ELFCLASS64 && f.Machine == EM_X86_64:
- return f.applyRelocationsAMD64(dst, rels)
- case f.Class == ELFCLASS32 && f.Machine == EM_386:
- return f.applyRelocations386(dst, rels)
- case f.Class == ELFCLASS32 && f.Machine == EM_ARM:
- return f.applyRelocationsARM(dst, rels)
- case f.Class == ELFCLASS64 && f.Machine == EM_AARCH64:
- return f.applyRelocationsARM64(dst, rels)
- case f.Class == ELFCLASS32 && f.Machine == EM_PPC:
- return f.applyRelocationsPPC(dst, rels)
- case f.Class == ELFCLASS64 && f.Machine == EM_PPC64:
- return f.applyRelocationsPPC64(dst, rels)
- case f.Class == ELFCLASS32 && f.Machine == EM_MIPS:
- return f.applyRelocationsMIPS(dst, rels)
- case f.Class == ELFCLASS64 && f.Machine == EM_MIPS:
- return f.applyRelocationsMIPS64(dst, rels)
- case f.Class == ELFCLASS64 && f.Machine == EM_LOONGARCH:
- return f.applyRelocationsLOONG64(dst, rels)
- case f.Class == ELFCLASS64 && f.Machine == EM_RISCV:
- return f.applyRelocationsRISCV64(dst, rels)
- case f.Class == ELFCLASS64 && f.Machine == EM_S390:
- return f.applyRelocationss390x(dst, rels)
- case f.Class == ELFCLASS64 && f.Machine == EM_SPARCV9:
- return f.applyRelocationsSPARC64(dst, rels)
- default:
- return errors.New("applyRelocations: not implemented")
- }
-}
-
-// canApplyRelocation reports whether we should try to apply a
-// relocation to a DWARF data section, given a pointer to the symbol
-// targeted by the relocation.
-// Most relocations in DWARF data tend to be section-relative, but
-// some target non-section symbols (for example, low_PC attrs on
-// subprogram or compilation unit DIEs that target function symbols).
-func canApplyRelocation(sym *Symbol) bool {
- return sym.Section != SHN_UNDEF && sym.Section < SHN_LORESERVE
-}
-
-func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
- // 24 is the size of Rela64.
- if len(rels)%24 != 0 {
- return errors.New("length of relocation section is not a multiple of 24")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rela Rela64
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rela)
- symNo := rela.Info >> 32
- t := R_X86_64(rela.Info & 0xffff)
-
- if symNo == 0 || symNo > uint64(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
- if !canApplyRelocation(sym) {
- continue
- }
-
- // There are relocations, so this must be a normal
- // object file. The code below handles only basic relocations
- // of the form S + A (symbol plus addend).
-
- switch t {
- case R_X86_64_64:
- if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val64 := sym.Value + uint64(rela.Addend)
- f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
- case R_X86_64_32:
- if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val32 := uint32(sym.Value) + uint32(rela.Addend)
- f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
- }
- }
-
- return nil
-}
-
-func (f *File) applyRelocations386(dst []byte, rels []byte) error {
- // 8 is the size of Rel32.
- if len(rels)%8 != 0 {
- return errors.New("length of relocation section is not a multiple of 8")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rel Rel32
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rel)
- symNo := rel.Info >> 8
- t := R_386(rel.Info & 0xff)
-
- if symNo == 0 || symNo > uint32(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
-
- if t == R_386_32 {
- if rel.Off+4 >= uint32(len(dst)) {
- continue
- }
- val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
- val += uint32(sym.Value)
- f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
- }
- }
-
- return nil
-}
-
-func (f *File) applyRelocationsARM(dst []byte, rels []byte) error {
- // 8 is the size of Rel32.
- if len(rels)%8 != 0 {
- return errors.New("length of relocation section is not a multiple of 8")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rel Rel32
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rel)
- symNo := rel.Info >> 8
- t := R_ARM(rel.Info & 0xff)
-
- if symNo == 0 || symNo > uint32(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
-
- switch t {
- case R_ARM_ABS32:
- if rel.Off+4 >= uint32(len(dst)) {
- continue
- }
- val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
- val += uint32(sym.Value)
- f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
- }
- }
-
- return nil
-}
-
-func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
- // 24 is the size of Rela64.
- if len(rels)%24 != 0 {
- return errors.New("length of relocation section is not a multiple of 24")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rela Rela64
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rela)
- symNo := rela.Info >> 32
- t := R_AARCH64(rela.Info & 0xffff)
-
- if symNo == 0 || symNo > uint64(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
- if !canApplyRelocation(sym) {
- continue
- }
-
- // There are relocations, so this must be a normal
- // object file. The code below handles only basic relocations
- // of the form S + A (symbol plus addend).
-
- switch t {
- case R_AARCH64_ABS64:
- if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val64 := sym.Value + uint64(rela.Addend)
- f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
- case R_AARCH64_ABS32:
- if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val32 := uint32(sym.Value) + uint32(rela.Addend)
- f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
- }
- }
-
- return nil
-}
-
-func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error {
- // 12 is the size of Rela32.
- if len(rels)%12 != 0 {
- return errors.New("length of relocation section is not a multiple of 12")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rela Rela32
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rela)
- symNo := rela.Info >> 8
- t := R_PPC(rela.Info & 0xff)
-
- if symNo == 0 || symNo > uint32(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
- if !canApplyRelocation(sym) {
- continue
- }
-
- switch t {
- case R_PPC_ADDR32:
- if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 {
- continue
- }
- val32 := uint32(sym.Value) + uint32(rela.Addend)
- f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
- }
- }
-
- return nil
-}
-
-func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error {
- // 24 is the size of Rela64.
- if len(rels)%24 != 0 {
- return errors.New("length of relocation section is not a multiple of 24")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rela Rela64
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rela)
- symNo := rela.Info >> 32
- t := R_PPC64(rela.Info & 0xffff)
-
- if symNo == 0 || symNo > uint64(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
- if !canApplyRelocation(sym) {
- continue
- }
-
- switch t {
- case R_PPC64_ADDR64:
- if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val64 := sym.Value + uint64(rela.Addend)
- f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
- case R_PPC64_ADDR32:
- if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val32 := uint32(sym.Value) + uint32(rela.Addend)
- f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
- }
- }
-
- return nil
-}
-
-func (f *File) applyRelocationsMIPS(dst []byte, rels []byte) error {
- // 8 is the size of Rel32.
- if len(rels)%8 != 0 {
- return errors.New("length of relocation section is not a multiple of 8")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rel Rel32
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rel)
- symNo := rel.Info >> 8
- t := R_MIPS(rel.Info & 0xff)
-
- if symNo == 0 || symNo > uint32(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
-
- switch t {
- case R_MIPS_32:
- if rel.Off+4 >= uint32(len(dst)) {
- continue
- }
- val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
- val += uint32(sym.Value)
- f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
- }
- }
-
- return nil
-}
-
-func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error {
- // 24 is the size of Rela64.
- if len(rels)%24 != 0 {
- return errors.New("length of relocation section is not a multiple of 24")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rela Rela64
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rela)
- var symNo uint64
- var t R_MIPS
- if f.ByteOrder == binary.BigEndian {
- symNo = rela.Info >> 32
- t = R_MIPS(rela.Info & 0xff)
- } else {
- symNo = rela.Info & 0xffffffff
- t = R_MIPS(rela.Info >> 56)
- }
-
- if symNo == 0 || symNo > uint64(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
- if !canApplyRelocation(sym) {
- continue
- }
-
- switch t {
- case R_MIPS_64:
- if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val64 := sym.Value + uint64(rela.Addend)
- f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
- case R_MIPS_32:
- if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val32 := uint32(sym.Value) + uint32(rela.Addend)
- f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
- }
- }
-
- return nil
-}
-
-func (f *File) applyRelocationsLOONG64(dst []byte, rels []byte) error {
- // 24 is the size of Rela64.
- if len(rels)%24 != 0 {
- return errors.New("length of relocation section is not a multiple of 24")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rela Rela64
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rela)
- var symNo uint64
- var t R_LARCH
- symNo = rela.Info >> 32
- t = R_LARCH(rela.Info & 0xffff)
-
- if symNo == 0 || symNo > uint64(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
- if !canApplyRelocation(sym) {
- continue
- }
-
- switch t {
- case R_LARCH_64:
- if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val64 := sym.Value + uint64(rela.Addend)
- f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
- case R_LARCH_32:
- if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val32 := uint32(sym.Value) + uint32(rela.Addend)
- f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
- }
- }
-
- return nil
-}
-
-func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error {
- // 24 is the size of Rela64.
- if len(rels)%24 != 0 {
- return errors.New("length of relocation section is not a multiple of 24")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rela Rela64
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rela)
- symNo := rela.Info >> 32
- t := R_RISCV(rela.Info & 0xffff)
-
- if symNo == 0 || symNo > uint64(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
- if !canApplyRelocation(sym) {
- continue
- }
-
- switch t {
- case R_RISCV_64:
- if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val64 := sym.Value + uint64(rela.Addend)
- f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
- case R_RISCV_32:
- if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val32 := uint32(sym.Value) + uint32(rela.Addend)
- f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
- }
- }
-
- return nil
-}
-
-func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
- // 24 is the size of Rela64.
- if len(rels)%24 != 0 {
- return errors.New("length of relocation section is not a multiple of 24")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rela Rela64
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rela)
- symNo := rela.Info >> 32
- t := R_390(rela.Info & 0xffff)
-
- if symNo == 0 || symNo > uint64(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
- if !canApplyRelocation(sym) {
- continue
- }
-
- switch t {
- case R_390_64:
- if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val64 := sym.Value + uint64(rela.Addend)
- f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
- case R_390_32:
- if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val32 := uint32(sym.Value) + uint32(rela.Addend)
- f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
- }
- }
-
- return nil
-}
-
-func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
- // 24 is the size of Rela64.
- if len(rels)%24 != 0 {
- return errors.New("length of relocation section is not a multiple of 24")
- }
-
- symbols, _, err := f.getSymbols(SHT_SYMTAB)
- if err != nil {
- return err
- }
-
- b := bytes.NewReader(rels)
- var rela Rela64
-
- for b.Len() > 0 {
- binary.Read(b, f.ByteOrder, &rela)
- symNo := rela.Info >> 32
- t := R_SPARC(rela.Info & 0xff)
-
- if symNo == 0 || symNo > uint64(len(symbols)) {
- continue
- }
- sym := &symbols[symNo-1]
- if !canApplyRelocation(sym) {
- continue
- }
-
- switch t {
- case R_SPARC_64, R_SPARC_UA64:
- if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val64 := sym.Value + uint64(rela.Addend)
- f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
- case R_SPARC_32, R_SPARC_UA32:
- if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
- continue
- }
- val32 := uint32(sym.Value) + uint32(rela.Addend)
- f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
- }
- }
-
- return nil
-}
-
-func (f *File) DWARF() (*dwarf.Data, error) {
- dwarfSuffix := func(s *Section) string {
- switch {
- case strings.HasPrefix(s.Name, ".debug_"):
- return s.Name[7:]
- case strings.HasPrefix(s.Name, ".zdebug_"):
- return s.Name[8:]
- default:
- return ""
- }
-
- }
- // sectionData gets the data for s, checks its size, and
- // applies any applicable relations.
- sectionData := func(i int, s *Section) ([]byte, error) {
- b, err := s.Data()
- if err != nil && uint64(len(b)) < s.Size {
- return nil, err
- }
- var dlen uint64
- if len(b) >= 12 && string(b[:4]) == "ZLIB" {
- dlen = binary.BigEndian.Uint64(b[4:12])
- s.compressionOffset = 12
- }
- if dlen == 0 && len(b) >= 12 && s.Flags&SHF_COMPRESSED != 0 &&
- s.Flags&SHF_ALLOC == 0 &&
- f.FileHeader.ByteOrder.Uint32(b[:]) == uint32(COMPRESS_ZLIB) {
- s.compressionType = COMPRESS_ZLIB
- switch f.FileHeader.Class {
- case ELFCLASS32:
- // Chdr32.Size offset
- dlen = uint64(f.FileHeader.ByteOrder.Uint32(b[4:]))
- s.compressionOffset = 12
- case ELFCLASS64:
- if len(b) < 24 {
- return nil, errors.New("invalid compress header 64")
- }
- // Chdr64.Size offset
- dlen = f.FileHeader.ByteOrder.Uint64(b[8:])
- s.compressionOffset = 24
- default:
- return nil, fmt.Errorf("unsupported compress header:%s", f.FileHeader.Class)
- }
- }
- if dlen > 0 {
- r, err := zlib.NewReader(bytes.NewBuffer(b[s.compressionOffset:]))
- if err != nil {
- return nil, err
- }
- b, err = saferio.ReadData(r, dlen)
- if err != nil {
- return nil, err
- }
- if err := r.Close(); err != nil {
- return nil, err
- }
- }
-
- if f.Type == ET_EXEC {
- // Do not apply relocations to DWARF sections for ET_EXEC binaries.
- // Relocations should already be applied, and .rela sections may
- // contain incorrect data.
- return b, nil
- }
-
- for _, r := range f.Sections {
- if r.Type != SHT_RELA && r.Type != SHT_REL {
- continue
- }
- if int(r.Info) != i {
- continue
- }
- rd, err := r.Data()
- if err != nil {
- return nil, err
- }
- err = f.applyRelocations(b, rd)
- if err != nil {
- return nil, err
- }
- }
- return b, nil
- }
-
- // There are many DWARf sections, but these are the ones
- // the debug/dwarf package started with.
- var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil, "ranges": nil}
- for i, s := range f.Sections {
- suffix := dwarfSuffix(s)
- if suffix == "" {
- continue
- }
- if _, ok := dat[suffix]; !ok {
- continue
- }
- b, err := sectionData(i, s)
- if err != nil {
- return nil, err
- }
- dat[suffix] = b
- }
-
- d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], dat["line"], nil, dat["ranges"], dat["str"])
- if err != nil {
- return nil, err
- }
-
- // Look for DWARF4 .debug_types sections and DWARF5 sections.
- for i, s := range f.Sections {
- suffix := dwarfSuffix(s)
- if suffix == "" {
- continue
- }
- if _, ok := dat[suffix]; ok {
- // Already handled.
- continue
- }
-
- b, err := sectionData(i, s)
- if err != nil {
- return nil, err
- }
-
- if suffix == "types" {
- if err := d.AddTypes(fmt.Sprintf("types-%d", i), b); err != nil {
- return nil, err
- }
- } else {
- if err := d.AddSection(".debug_"+suffix, b); err != nil {
- return nil, err
- }
- }
- }
-
- return d, nil
-}
-
-// Symbols returns the symbol table for f. The symbols will be listed in the order
-// they appear in f.
-//
-// For compatibility with Go 1.0, Symbols omits the null symbol at index 0.
-// After retrieving the symbols as symtab, an externally supplied index x
-// corresponds to symtab[x-1], not symtab[x].
-func (f *File) Symbols() ([]Symbol, error) {
- sym, _, err := f.getSymbols(SHT_SYMTAB)
- return sym, err
-}
-
-// DynamicSymbols returns the dynamic symbol table for f. The symbols
-// will be listed in the order they appear in f.
-//
-// If f has a symbol version table, the returned Symbols will have
-// initialized Version and Library fields.
-//
-// For compatibility with Symbols, DynamicSymbols omits the null symbol at index 0.
-// After retrieving the symbols as symtab, an externally supplied index x
-// corresponds to symtab[x-1], not symtab[x].
-func (f *File) DynamicSymbols() ([]Symbol, error) {
- sym, str, err := f.getSymbols(SHT_DYNSYM)
- if err != nil {
- return nil, err
- }
- if f.gnuVersionInit(str) {
- for i := range sym {
- sym[i].Library, sym[i].Version = f.gnuVersion(i)
- }
- }
- return sym, nil
-}
-
-type ImportedSymbol struct {
- Name string
- Version string
- Library string
-}
-
-// ImportedSymbols returns the names of all symbols
-// referred to by the binary f that are expected to be
-// satisfied by other libraries at dynamic load time.
-// It does not return weak symbols.
-func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
- sym, str, err := f.getSymbols(SHT_DYNSYM)
- if err != nil {
- return nil, err
- }
- f.gnuVersionInit(str)
- var all []ImportedSymbol
- for i, s := range sym {
- if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF {
- all = append(all, ImportedSymbol{Name: s.Name})
- sym := &all[len(all)-1]
- sym.Library, sym.Version = f.gnuVersion(i)
- }
- }
- return all, nil
-}
-
-type verneed struct {
- File string
- Name string
-}
-
-// gnuVersionInit parses the GNU version tables
-// for use by calls to gnuVersion.
-func (f *File) gnuVersionInit(str []byte) bool {
- if f.gnuNeed != nil {
- // Already initialized
- return true
- }
-
- // Accumulate verneed information.
- vn := f.SectionByType(SHT_GNU_VERNEED)
- if vn == nil {
- return false
- }
- d, _ := vn.Data()
-
- var need []verneed
- i := 0
- for {
- if i+16 > len(d) {
- break
- }
- vers := f.ByteOrder.Uint16(d[i : i+2])
- if vers != 1 {
- break
- }
- cnt := f.ByteOrder.Uint16(d[i+2 : i+4])
- fileoff := f.ByteOrder.Uint32(d[i+4 : i+8])
- aux := f.ByteOrder.Uint32(d[i+8 : i+12])
- next := f.ByteOrder.Uint32(d[i+12 : i+16])
- file, _ := getString(str, int(fileoff))
-
- var name string
- j := i + int(aux)
- for c := 0; c < int(cnt); c++ {
- if j+16 > len(d) {
- break
- }
- // hash := f.ByteOrder.Uint32(d[j:j+4])
- // flags := f.ByteOrder.Uint16(d[j+4:j+6])
- other := f.ByteOrder.Uint16(d[j+6 : j+8])
- nameoff := f.ByteOrder.Uint32(d[j+8 : j+12])
- next := f.ByteOrder.Uint32(d[j+12 : j+16])
- name, _ = getString(str, int(nameoff))
- ndx := int(other)
- if ndx >= len(need) {
- a := make([]verneed, 2*(ndx+1))
- copy(a, need)
- need = a
- }
-
- need[ndx] = verneed{file, name}
- if next == 0 {
- break
- }
- j += int(next)
- }
-
- if next == 0 {
- break
- }
- i += int(next)
- }
-
- // Versym parallels symbol table, indexing into verneed.
- vs := f.SectionByType(SHT_GNU_VERSYM)
- if vs == nil {
- return false
- }
- d, _ = vs.Data()
-
- f.gnuNeed = need
- f.gnuVersym = d
- return true
-}
-
-// gnuVersion adds Library and Version information to sym,
-// which came from offset i of the symbol table.
-func (f *File) gnuVersion(i int) (library string, version string) {
- // Each entry is two bytes; skip undef entry at beginning.
- i = (i + 1) * 2
- if i >= len(f.gnuVersym) {
- return
- }
- s := f.gnuVersym[i:]
- if len(s) < 2 {
- return
- }
- j := int(f.ByteOrder.Uint16(s))
- if j < 2 || j >= len(f.gnuNeed) {
- return
- }
- n := &f.gnuNeed[j]
- return n.File, n.Name
-}
-
-// ImportedLibraries returns the names of all libraries
-// referred to by the binary f that are expected to be
-// linked with the binary at dynamic link time.
-func (f *File) ImportedLibraries() ([]string, error) {
- return f.DynString(DT_NEEDED)
-}
-
-// DynString returns the strings listed for the given tag in the file's dynamic
-// section.
-//
-// The tag must be one that takes string values: DT_NEEDED, DT_SONAME, DT_RPATH, or
-// DT_RUNPATH.
-func (f *File) DynString(tag DynTag) ([]string, error) {
- switch tag {
- case DT_NEEDED, DT_SONAME, DT_RPATH, DT_RUNPATH:
- default:
- return nil, fmt.Errorf("non-string-valued tag %v", tag)
- }
- ds := f.SectionByType(SHT_DYNAMIC)
- if ds == nil {
- // not dynamic, so no libraries
- return nil, nil
- }
- d, err := ds.Data()
- if err != nil {
- return nil, err
- }
- str, err := f.stringTable(ds.Link)
- if err != nil {
- return nil, err
- }
- var all []string
- for len(d) > 0 {
- var t DynTag
- var v uint64
- switch f.Class {
- case ELFCLASS32:
- t = DynTag(f.ByteOrder.Uint32(d[0:4]))
- v = uint64(f.ByteOrder.Uint32(d[4:8]))
- d = d[8:]
- case ELFCLASS64:
- t = DynTag(f.ByteOrder.Uint64(d[0:8]))
- v = f.ByteOrder.Uint64(d[8:16])
- d = d[16:]
- }
- if t == tag {
- s, ok := getString(str, int(v))
- if ok {
- all = append(all, s)
- }
- }
- }
- return all, nil
-}
-
-type nobitsSectionReader struct{}
-
-func (*nobitsSectionReader) ReadAt(p []byte, off int64) (n int, err error) {
- return 0, errors.New("unexpected read from SHT_NOBITS section")
-}
diff --git a/contrib/go/_std_1.20/src/debug/elf/ya.make b/contrib/go/_std_1.20/src/debug/elf/ya.make
deleted file mode 100644
index 7c948a579a..0000000000
--- a/contrib/go/_std_1.20/src/debug/elf/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- elf.go
- file.go
- reader.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/embed/embed.go b/contrib/go/_std_1.20/src/embed/embed.go
deleted file mode 100644
index c54b961d15..0000000000
--- a/contrib/go/_std_1.20/src/embed/embed.go
+++ /dev/null
@@ -1,432 +0,0 @@
-// 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 embed provides access to files embedded in the running Go program.
-//
-// Go source files that import "embed" can use the //go:embed directive
-// to initialize a variable of type string, []byte, or FS with the contents of
-// files read from the package directory or subdirectories at compile time.
-//
-// For example, here are three ways to embed a file named hello.txt
-// and then print its contents at run time.
-//
-// Embedding one file into a string:
-//
-// import _ "embed"
-//
-// //go:embed hello.txt
-// var s string
-// print(s)
-//
-// Embedding one file into a slice of bytes:
-//
-// import _ "embed"
-//
-// //go:embed hello.txt
-// var b []byte
-// print(string(b))
-//
-// Embedded one or more files into a file system:
-//
-// import "embed"
-//
-// //go:embed hello.txt
-// var f embed.FS
-// data, _ := f.ReadFile("hello.txt")
-// print(string(data))
-//
-// # Directives
-//
-// A //go:embed directive above a variable declaration specifies which files to embed,
-// using one or more path.Match patterns.
-//
-// The directive must immediately precede a line containing the declaration of a single variable.
-// Only blank lines and ‘//’ line comments are permitted between the directive and the declaration.
-//
-// The type of the variable must be a string type, or a slice of a byte type,
-// or FS (or an alias of FS).
-//
-// For example:
-//
-// package server
-//
-// import "embed"
-//
-// // content holds our static web server content.
-// //go:embed image/* template/*
-// //go:embed html/index.html
-// var content embed.FS
-//
-// The Go build system will recognize the directives and arrange for the declared variable
-// (in the example above, content) to be populated with the matching files from the file system.
-//
-// The //go:embed directive accepts multiple space-separated patterns for
-// brevity, but it can also be repeated, to avoid very long lines when there are
-// many patterns. The patterns are interpreted relative to the package directory
-// containing the source file. The path separator is a forward slash, even on
-// Windows systems. Patterns may not contain ‘.’ or ‘..’ or empty path elements,
-// nor may they begin or end with a slash. To match everything in the current
-// directory, use ‘*’ instead of ‘.’. To allow for naming files with spaces in
-// their names, patterns can be written as Go double-quoted or back-quoted
-// string literals.
-//
-// If a pattern names a directory, all files in the subtree rooted at that directory are
-// embedded (recursively), except that files with names beginning with ‘.’ or ‘_’
-// are excluded. So the variable in the above example is almost equivalent to:
-//
-// // content is our static web server content.
-// //go:embed image template html/index.html
-// var content embed.FS
-//
-// The difference is that ‘image/*’ embeds ‘image/.tempfile’ while ‘image’ does not.
-// Neither embeds ‘image/dir/.tempfile’.
-//
-// If a pattern begins with the prefix ‘all:’, then the rule for walking directories is changed
-// to include those files beginning with ‘.’ or ‘_’. For example, ‘all:image’ embeds
-// both ‘image/.tempfile’ and ‘image/dir/.tempfile’.
-//
-// The //go:embed directive can be used with both exported and unexported variables,
-// depending on whether the package wants to make the data available to other packages.
-// It can only be used with variables at package scope, not with local variables.
-//
-// Patterns must not match files outside the package's module, such as ‘.git/*’ or symbolic links.
-// Patterns must not match files whose names include the special punctuation characters " * < > ? ` ' | / \ and :.
-// Matches for empty directories are ignored. After that, each pattern in a //go:embed line
-// must match at least one file or non-empty directory.
-//
-// If any patterns are invalid or have invalid matches, the build will fail.
-//
-// # Strings and Bytes
-//
-// The //go:embed line for a variable of type string or []byte can have only a single pattern,
-// and that pattern can match only a single file. The string or []byte is initialized with
-// the contents of that file.
-//
-// The //go:embed directive requires importing "embed", even when using a string or []byte.
-// In source files that don't refer to embed.FS, use a blank import (import _ "embed").
-//
-// # File Systems
-//
-// For embedding a single file, a variable of type string or []byte is often best.
-// The FS type enables embedding a tree of files, such as a directory of static
-// web server content, as in the example above.
-//
-// FS implements the io/fs package's FS interface, so it can be used with any package that
-// understands file systems, including net/http, text/template, and html/template.
-//
-// For example, given the content variable in the example above, we can write:
-//
-// http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(content))))
-//
-// template.ParseFS(content, "*.tmpl")
-//
-// # Tools
-//
-// To support tools that analyze Go packages, the patterns found in //go:embed lines
-// are available in “go list” output. See the EmbedPatterns, TestEmbedPatterns,
-// and XTestEmbedPatterns fields in the “go help list” output.
-package embed
-
-import (
- "errors"
- "io"
- "io/fs"
- "time"
-)
-
-// An FS is a read-only collection of files, usually initialized with a //go:embed directive.
-// When declared without a //go:embed directive, an FS is an empty file system.
-//
-// An FS is a read-only value, so it is safe to use from multiple goroutines
-// simultaneously and also safe to assign values of type FS to each other.
-//
-// FS implements fs.FS, so it can be used with any package that understands
-// file system interfaces, including net/http, text/template, and html/template.
-//
-// See the package documentation for more details about initializing an FS.
-type FS struct {
- // The compiler knows the layout of this struct.
- // See cmd/compile/internal/staticdata's WriteEmbed.
- //
- // The files list is sorted by name but not by simple string comparison.
- // Instead, each file's name takes the form "dir/elem" or "dir/elem/".
- // The optional trailing slash indicates that the file is itself a directory.
- // The files list is sorted first by dir (if dir is missing, it is taken to be ".")
- // and then by base, so this list of files:
- //
- // p
- // q/
- // q/r
- // q/s/
- // q/s/t
- // q/s/u
- // q/v
- // w
- //
- // is actually sorted as:
- //
- // p # dir=. elem=p
- // q/ # dir=. elem=q
- // w/ # dir=. elem=w
- // q/r # dir=q elem=r
- // q/s/ # dir=q elem=s
- // q/v # dir=q elem=v
- // q/s/t # dir=q/s elem=t
- // q/s/u # dir=q/s elem=u
- //
- // This order brings directory contents together in contiguous sections
- // of the list, allowing a directory read to use binary search to find
- // the relevant sequence of entries.
- files *[]file
-}
-
-// split splits the name into dir and elem as described in the
-// comment in the FS struct above. isDir reports whether the
-// final trailing slash was present, indicating that name is a directory.
-func split(name string) (dir, elem string, isDir bool) {
- if name[len(name)-1] == '/' {
- isDir = true
- name = name[:len(name)-1]
- }
- i := len(name) - 1
- for i >= 0 && name[i] != '/' {
- i--
- }
- if i < 0 {
- return ".", name, isDir
- }
- return name[:i], name[i+1:], isDir
-}
-
-// trimSlash trims a trailing slash from name, if present,
-// returning the possibly shortened name.
-func trimSlash(name string) string {
- if len(name) > 0 && name[len(name)-1] == '/' {
- return name[:len(name)-1]
- }
- return name
-}
-
-var (
- _ fs.ReadDirFS = FS{}
- _ fs.ReadFileFS = FS{}
-)
-
-// A file is a single file in the FS.
-// It implements fs.FileInfo and fs.DirEntry.
-type file struct {
- // The compiler knows the layout of this struct.
- // See cmd/compile/internal/staticdata's WriteEmbed.
- name string
- data string
- hash [16]byte // truncated SHA256 hash
-}
-
-var (
- _ fs.FileInfo = (*file)(nil)
- _ fs.DirEntry = (*file)(nil)
-)
-
-func (f *file) Name() string { _, elem, _ := split(f.name); return elem }
-func (f *file) Size() int64 { return int64(len(f.data)) }
-func (f *file) ModTime() time.Time { return time.Time{} }
-func (f *file) IsDir() bool { _, _, isDir := split(f.name); return isDir }
-func (f *file) Sys() any { return nil }
-func (f *file) Type() fs.FileMode { return f.Mode().Type() }
-func (f *file) Info() (fs.FileInfo, error) { return f, nil }
-
-func (f *file) Mode() fs.FileMode {
- if f.IsDir() {
- return fs.ModeDir | 0555
- }
- return 0444
-}
-
-// dotFile is a file for the root directory,
-// which is omitted from the files list in a FS.
-var dotFile = &file{name: "./"}
-
-// lookup returns the named file, or nil if it is not present.
-func (f FS) lookup(name string) *file {
- if !fs.ValidPath(name) {
- // The compiler should never emit a file with an invalid name,
- // so this check is not strictly necessary (if name is invalid,
- // we shouldn't find a match below), but it's a good backstop anyway.
- return nil
- }
- if name == "." {
- return dotFile
- }
- if f.files == nil {
- return nil
- }
-
- // Binary search to find where name would be in the list,
- // and then check if name is at that position.
- dir, elem, _ := split(name)
- files := *f.files
- i := sortSearch(len(files), func(i int) bool {
- idir, ielem, _ := split(files[i].name)
- return idir > dir || idir == dir && ielem >= elem
- })
- if i < len(files) && trimSlash(files[i].name) == name {
- return &files[i]
- }
- return nil
-}
-
-// readDir returns the list of files corresponding to the directory dir.
-func (f FS) readDir(dir string) []file {
- if f.files == nil {
- return nil
- }
- // Binary search to find where dir starts and ends in the list
- // and then return that slice of the list.
- files := *f.files
- i := sortSearch(len(files), func(i int) bool {
- idir, _, _ := split(files[i].name)
- return idir >= dir
- })
- j := sortSearch(len(files), func(j int) bool {
- jdir, _, _ := split(files[j].name)
- return jdir > dir
- })
- return files[i:j]
-}
-
-// Open opens the named file for reading and returns it as an fs.File.
-//
-// The returned file implements io.Seeker when the file is not a directory.
-func (f FS) Open(name string) (fs.File, error) {
- file := f.lookup(name)
- if file == nil {
- return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
- }
- if file.IsDir() {
- return &openDir{file, f.readDir(name), 0}, nil
- }
- return &openFile{file, 0}, nil
-}
-
-// ReadDir reads and returns the entire named directory.
-func (f FS) ReadDir(name string) ([]fs.DirEntry, error) {
- file, err := f.Open(name)
- if err != nil {
- return nil, err
- }
- dir, ok := file.(*openDir)
- if !ok {
- return nil, &fs.PathError{Op: "read", Path: name, Err: errors.New("not a directory")}
- }
- list := make([]fs.DirEntry, len(dir.files))
- for i := range list {
- list[i] = &dir.files[i]
- }
- return list, nil
-}
-
-// ReadFile reads and returns the content of the named file.
-func (f FS) ReadFile(name string) ([]byte, error) {
- file, err := f.Open(name)
- if err != nil {
- return nil, err
- }
- ofile, ok := file.(*openFile)
- if !ok {
- return nil, &fs.PathError{Op: "read", Path: name, Err: errors.New("is a directory")}
- }
- return []byte(ofile.f.data), nil
-}
-
-// An openFile is a regular file open for reading.
-type openFile struct {
- f *file // the file itself
- offset int64 // current read offset
-}
-
-var (
- _ io.Seeker = (*openFile)(nil)
-)
-
-func (f *openFile) Close() error { return nil }
-func (f *openFile) Stat() (fs.FileInfo, error) { return f.f, nil }
-
-func (f *openFile) Read(b []byte) (int, error) {
- if f.offset >= int64(len(f.f.data)) {
- return 0, io.EOF
- }
- if f.offset < 0 {
- return 0, &fs.PathError{Op: "read", Path: f.f.name, Err: fs.ErrInvalid}
- }
- n := copy(b, f.f.data[f.offset:])
- f.offset += int64(n)
- return n, nil
-}
-
-func (f *openFile) Seek(offset int64, whence int) (int64, error) {
- switch whence {
- case 0:
- // offset += 0
- case 1:
- offset += f.offset
- case 2:
- offset += int64(len(f.f.data))
- }
- if offset < 0 || offset > int64(len(f.f.data)) {
- return 0, &fs.PathError{Op: "seek", Path: f.f.name, Err: fs.ErrInvalid}
- }
- f.offset = offset
- return offset, nil
-}
-
-// An openDir is a directory open for reading.
-type openDir struct {
- f *file // the directory file itself
- files []file // the directory contents
- offset int // the read offset, an index into the files slice
-}
-
-func (d *openDir) Close() error { return nil }
-func (d *openDir) Stat() (fs.FileInfo, error) { return d.f, nil }
-
-func (d *openDir) Read([]byte) (int, error) {
- return 0, &fs.PathError{Op: "read", Path: d.f.name, Err: errors.New("is a directory")}
-}
-
-func (d *openDir) ReadDir(count int) ([]fs.DirEntry, error) {
- n := len(d.files) - d.offset
- if n == 0 {
- if count <= 0 {
- return nil, nil
- }
- return nil, io.EOF
- }
- if count > 0 && n > count {
- n = count
- }
- list := make([]fs.DirEntry, n)
- for i := range list {
- list[i] = &d.files[d.offset+i]
- }
- d.offset += n
- return list, nil
-}
-
-// sortSearch is like sort.Search, avoiding an import.
-func sortSearch(n int, f func(int) bool) int {
- // Define f(-1) == false and f(n) == true.
- // Invariant: f(i-1) == false, f(j) == true.
- i, j := 0, n
- for i < j {
- h := int(uint(i+j) >> 1) // avoid overflow when computing h
- // i ≤ h < j
- if !f(h) {
- i = h + 1 // preserves f(i-1) == false
- } else {
- j = h // preserves f(j) == true
- }
- }
- // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i.
- return i
-}
diff --git a/contrib/go/_std_1.20/src/embed/ya.make b/contrib/go/_std_1.20/src/embed/ya.make
deleted file mode 100644
index 558b4347a9..0000000000
--- a/contrib/go/_std_1.20/src/embed/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- embed.go
-)
-
-END()
-
-RECURSE(
- # internal
-)
diff --git a/contrib/go/_std_1.20/src/encoding/ascii85/ya.make b/contrib/go/_std_1.20/src/encoding/ascii85/ya.make
deleted file mode 100644
index 06c44bd7bb..0000000000
--- a/contrib/go/_std_1.20/src/encoding/ascii85/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- ascii85.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/encoding/asn1/asn1.go b/contrib/go/_std_1.20/src/encoding/asn1/asn1.go
deleted file mode 100644
index 2e320897e3..0000000000
--- a/contrib/go/_std_1.20/src/encoding/asn1/asn1.go
+++ /dev/null
@@ -1,1122 +0,0 @@
-// Copyright 2009 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 asn1 implements parsing of DER-encoded ASN.1 data structures,
-// as defined in ITU-T Rec X.690.
-//
-// See also “A Layman's Guide to a Subset of ASN.1, BER, and DER,”
-// http://luca.ntop.org/Teaching/Appunti/asn1.html.
-package asn1
-
-// ASN.1 is a syntax for specifying abstract objects and BER, DER, PER, XER etc
-// are different encoding formats for those objects. Here, we'll be dealing
-// with DER, the Distinguished Encoding Rules. DER is used in X.509 because
-// it's fast to parse and, unlike BER, has a unique encoding for every object.
-// When calculating hashes over objects, it's important that the resulting
-// bytes be the same at both ends and DER removes this margin of error.
-//
-// ASN.1 is very complex and this package doesn't attempt to implement
-// everything by any means.
-
-import (
- "errors"
- "fmt"
- "math"
- "math/big"
- "reflect"
- "strconv"
- "time"
- "unicode/utf16"
- "unicode/utf8"
-)
-
-// A StructuralError suggests that the ASN.1 data is valid, but the Go type
-// which is receiving it doesn't match.
-type StructuralError struct {
- Msg string
-}
-
-func (e StructuralError) Error() string { return "asn1: structure error: " + e.Msg }
-
-// A SyntaxError suggests that the ASN.1 data is invalid.
-type SyntaxError struct {
- Msg string
-}
-
-func (e SyntaxError) Error() string { return "asn1: syntax error: " + e.Msg }
-
-// We start by dealing with each of the primitive types in turn.
-
-// BOOLEAN
-
-func parseBool(bytes []byte) (ret bool, err error) {
- if len(bytes) != 1 {
- err = SyntaxError{"invalid boolean"}
- return
- }
-
- // DER demands that "If the encoding represents the boolean value TRUE,
- // its single contents octet shall have all eight bits set to one."
- // Thus only 0 and 255 are valid encoded values.
- switch bytes[0] {
- case 0:
- ret = false
- case 0xff:
- ret = true
- default:
- err = SyntaxError{"invalid boolean"}
- }
-
- return
-}
-
-// INTEGER
-
-// checkInteger returns nil if the given bytes are a valid DER-encoded
-// INTEGER and an error otherwise.
-func checkInteger(bytes []byte) error {
- if len(bytes) == 0 {
- return StructuralError{"empty integer"}
- }
- if len(bytes) == 1 {
- return nil
- }
- if (bytes[0] == 0 && bytes[1]&0x80 == 0) || (bytes[0] == 0xff && bytes[1]&0x80 == 0x80) {
- return StructuralError{"integer not minimally-encoded"}
- }
- return nil
-}
-
-// parseInt64 treats the given bytes as a big-endian, signed integer and
-// returns the result.
-func parseInt64(bytes []byte) (ret int64, err error) {
- err = checkInteger(bytes)
- if err != nil {
- return
- }
- if len(bytes) > 8 {
- // We'll overflow an int64 in this case.
- err = StructuralError{"integer too large"}
- return
- }
- for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
- ret <<= 8
- ret |= int64(bytes[bytesRead])
- }
-
- // Shift up and down in order to sign extend the result.
- ret <<= 64 - uint8(len(bytes))*8
- ret >>= 64 - uint8(len(bytes))*8
- return
-}
-
-// parseInt32 treats the given bytes as a big-endian, signed integer and returns
-// the result.
-func parseInt32(bytes []byte) (int32, error) {
- if err := checkInteger(bytes); err != nil {
- return 0, err
- }
- ret64, err := parseInt64(bytes)
- if err != nil {
- return 0, err
- }
- if ret64 != int64(int32(ret64)) {
- return 0, StructuralError{"integer too large"}
- }
- return int32(ret64), nil
-}
-
-var bigOne = big.NewInt(1)
-
-// parseBigInt treats the given bytes as a big-endian, signed integer and returns
-// the result.
-func parseBigInt(bytes []byte) (*big.Int, error) {
- if err := checkInteger(bytes); err != nil {
- return nil, err
- }
- ret := new(big.Int)
- if len(bytes) > 0 && bytes[0]&0x80 == 0x80 {
- // This is a negative number.
- notBytes := make([]byte, len(bytes))
- for i := range notBytes {
- notBytes[i] = ^bytes[i]
- }
- ret.SetBytes(notBytes)
- ret.Add(ret, bigOne)
- ret.Neg(ret)
- return ret, nil
- }
- ret.SetBytes(bytes)
- return ret, nil
-}
-
-// BIT STRING
-
-// BitString is the structure to use when you want an ASN.1 BIT STRING type. A
-// bit string is padded up to the nearest byte in memory and the number of
-// valid bits is recorded. Padding bits will be zero.
-type BitString struct {
- Bytes []byte // bits packed into bytes.
- BitLength int // length in bits.
-}
-
-// At returns the bit at the given index. If the index is out of range it
-// returns 0.
-func (b BitString) At(i int) int {
- if i < 0 || i >= b.BitLength {
- return 0
- }
- x := i / 8
- y := 7 - uint(i%8)
- return int(b.Bytes[x]>>y) & 1
-}
-
-// RightAlign returns a slice where the padding bits are at the beginning. The
-// slice may share memory with the BitString.
-func (b BitString) RightAlign() []byte {
- shift := uint(8 - (b.BitLength % 8))
- if shift == 8 || len(b.Bytes) == 0 {
- return b.Bytes
- }
-
- a := make([]byte, len(b.Bytes))
- a[0] = b.Bytes[0] >> shift
- for i := 1; i < len(b.Bytes); i++ {
- a[i] = b.Bytes[i-1] << (8 - shift)
- a[i] |= b.Bytes[i] >> shift
- }
-
- return a
-}
-
-// parseBitString parses an ASN.1 bit string from the given byte slice and returns it.
-func parseBitString(bytes []byte) (ret BitString, err error) {
- if len(bytes) == 0 {
- err = SyntaxError{"zero length BIT STRING"}
- return
- }
- paddingBits := int(bytes[0])
- if paddingBits > 7 ||
- len(bytes) == 1 && paddingBits > 0 ||
- bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {
- err = SyntaxError{"invalid padding bits in BIT STRING"}
- return
- }
- ret.BitLength = (len(bytes)-1)*8 - paddingBits
- ret.Bytes = bytes[1:]
- return
-}
-
-// NULL
-
-// NullRawValue is a RawValue with its Tag set to the ASN.1 NULL type tag (5).
-var NullRawValue = RawValue{Tag: TagNull}
-
-// NullBytes contains bytes representing the DER-encoded ASN.1 NULL type.
-var NullBytes = []byte{TagNull, 0}
-
-// OBJECT IDENTIFIER
-
-// An ObjectIdentifier represents an ASN.1 OBJECT IDENTIFIER.
-type ObjectIdentifier []int
-
-// Equal reports whether oi and other represent the same identifier.
-func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
- if len(oi) != len(other) {
- return false
- }
- for i := 0; i < len(oi); i++ {
- if oi[i] != other[i] {
- return false
- }
- }
-
- return true
-}
-
-func (oi ObjectIdentifier) String() string {
- var s string
-
- for i, v := range oi {
- if i > 0 {
- s += "."
- }
- s += strconv.Itoa(v)
- }
-
- return s
-}
-
-// parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and
-// returns it. An object identifier is a sequence of variable length integers
-// that are assigned in a hierarchy.
-func parseObjectIdentifier(bytes []byte) (s ObjectIdentifier, err error) {
- if len(bytes) == 0 {
- err = SyntaxError{"zero length OBJECT IDENTIFIER"}
- return
- }
-
- // In the worst case, we get two elements from the first byte (which is
- // encoded differently) and then every varint is a single byte long.
- s = make([]int, len(bytes)+1)
-
- // The first varint is 40*value1 + value2:
- // According to this packing, value1 can take the values 0, 1 and 2 only.
- // When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2,
- // then there are no restrictions on value2.
- v, offset, err := parseBase128Int(bytes, 0)
- if err != nil {
- return
- }
- if v < 80 {
- s[0] = v / 40
- s[1] = v % 40
- } else {
- s[0] = 2
- s[1] = v - 80
- }
-
- i := 2
- for ; offset < len(bytes); i++ {
- v, offset, err = parseBase128Int(bytes, offset)
- if err != nil {
- return
- }
- s[i] = v
- }
- s = s[0:i]
- return
-}
-
-// ENUMERATED
-
-// An Enumerated is represented as a plain int.
-type Enumerated int
-
-// FLAG
-
-// A Flag accepts any data and is set to true if present.
-type Flag bool
-
-// parseBase128Int parses a base-128 encoded int from the given offset in the
-// given byte slice. It returns the value and the new offset.
-func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error) {
- offset = initOffset
- var ret64 int64
- for shifted := 0; offset < len(bytes); shifted++ {
- // 5 * 7 bits per byte == 35 bits of data
- // Thus the representation is either non-minimal or too large for an int32
- if shifted == 5 {
- err = StructuralError{"base 128 integer too large"}
- return
- }
- ret64 <<= 7
- b := bytes[offset]
- // integers should be minimally encoded, so the leading octet should
- // never be 0x80
- if shifted == 0 && b == 0x80 {
- err = SyntaxError{"integer is not minimally encoded"}
- return
- }
- ret64 |= int64(b & 0x7f)
- offset++
- if b&0x80 == 0 {
- ret = int(ret64)
- // Ensure that the returned value fits in an int on all platforms
- if ret64 > math.MaxInt32 {
- err = StructuralError{"base 128 integer too large"}
- }
- return
- }
- }
- err = SyntaxError{"truncated base 128 integer"}
- return
-}
-
-// UTCTime
-
-func parseUTCTime(bytes []byte) (ret time.Time, err error) {
- s := string(bytes)
-
- formatStr := "0601021504Z0700"
- ret, err = time.Parse(formatStr, s)
- if err != nil {
- formatStr = "060102150405Z0700"
- ret, err = time.Parse(formatStr, s)
- }
- if err != nil {
- return
- }
-
- if serialized := ret.Format(formatStr); serialized != s {
- err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
- return
- }
-
- if ret.Year() >= 2050 {
- // UTCTime only encodes times prior to 2050. See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
- ret = ret.AddDate(-100, 0, 0)
- }
-
- return
-}
-
-// parseGeneralizedTime parses the GeneralizedTime from the given byte slice
-// and returns the resulting time.
-func parseGeneralizedTime(bytes []byte) (ret time.Time, err error) {
- const formatStr = "20060102150405Z0700"
- s := string(bytes)
-
- if ret, err = time.Parse(formatStr, s); err != nil {
- return
- }
-
- if serialized := ret.Format(formatStr); serialized != s {
- err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
- }
-
- return
-}
-
-// NumericString
-
-// parseNumericString parses an ASN.1 NumericString from the given byte array
-// and returns it.
-func parseNumericString(bytes []byte) (ret string, err error) {
- for _, b := range bytes {
- if !isNumeric(b) {
- return "", SyntaxError{"NumericString contains invalid character"}
- }
- }
- return string(bytes), nil
-}
-
-// isNumeric reports whether the given b is in the ASN.1 NumericString set.
-func isNumeric(b byte) bool {
- return '0' <= b && b <= '9' ||
- b == ' '
-}
-
-// PrintableString
-
-// parsePrintableString parses an ASN.1 PrintableString from the given byte
-// array and returns it.
-func parsePrintableString(bytes []byte) (ret string, err error) {
- for _, b := range bytes {
- if !isPrintable(b, allowAsterisk, allowAmpersand) {
- err = SyntaxError{"PrintableString contains invalid character"}
- return
- }
- }
- ret = string(bytes)
- return
-}
-
-type asteriskFlag bool
-type ampersandFlag bool
-
-const (
- allowAsterisk asteriskFlag = true
- rejectAsterisk asteriskFlag = false
-
- allowAmpersand ampersandFlag = true
- rejectAmpersand ampersandFlag = false
-)
-
-// isPrintable reports whether the given b is in the ASN.1 PrintableString set.
-// If asterisk is allowAsterisk then '*' is also allowed, reflecting existing
-// practice. If ampersand is allowAmpersand then '&' is allowed as well.
-func isPrintable(b byte, asterisk asteriskFlag, ampersand ampersandFlag) bool {
- return 'a' <= b && b <= 'z' ||
- 'A' <= b && b <= 'Z' ||
- '0' <= b && b <= '9' ||
- '\'' <= b && b <= ')' ||
- '+' <= b && b <= '/' ||
- b == ' ' ||
- b == ':' ||
- b == '=' ||
- b == '?' ||
- // This is technically not allowed in a PrintableString.
- // However, x509 certificates with wildcard strings don't
- // always use the correct string type so we permit it.
- (bool(asterisk) && b == '*') ||
- // This is not technically allowed either. However, not
- // only is it relatively common, but there are also a
- // handful of CA certificates that contain it. At least
- // one of which will not expire until 2027.
- (bool(ampersand) && b == '&')
-}
-
-// IA5String
-
-// parseIA5String parses an ASN.1 IA5String (ASCII string) from the given
-// byte slice and returns it.
-func parseIA5String(bytes []byte) (ret string, err error) {
- for _, b := range bytes {
- if b >= utf8.RuneSelf {
- err = SyntaxError{"IA5String contains invalid character"}
- return
- }
- }
- ret = string(bytes)
- return
-}
-
-// T61String
-
-// parseT61String parses an ASN.1 T61String (8-bit clean string) from the given
-// byte slice and returns it.
-func parseT61String(bytes []byte) (ret string, err error) {
- return string(bytes), nil
-}
-
-// UTF8String
-
-// parseUTF8String parses an ASN.1 UTF8String (raw UTF-8) from the given byte
-// array and returns it.
-func parseUTF8String(bytes []byte) (ret string, err error) {
- if !utf8.Valid(bytes) {
- return "", errors.New("asn1: invalid UTF-8 string")
- }
- return string(bytes), nil
-}
-
-// BMPString
-
-// parseBMPString parses an ASN.1 BMPString (Basic Multilingual Plane of
-// ISO/IEC/ITU 10646-1) from the given byte slice and returns it.
-func parseBMPString(bmpString []byte) (string, error) {
- if len(bmpString)%2 != 0 {
- return "", errors.New("pkcs12: odd-length BMP string")
- }
-
- // Strip terminator if present.
- if l := len(bmpString); l >= 2 && bmpString[l-1] == 0 && bmpString[l-2] == 0 {
- bmpString = bmpString[:l-2]
- }
-
- s := make([]uint16, 0, len(bmpString)/2)
- for len(bmpString) > 0 {
- s = append(s, uint16(bmpString[0])<<8+uint16(bmpString[1]))
- bmpString = bmpString[2:]
- }
-
- return string(utf16.Decode(s)), nil
-}
-
-// A RawValue represents an undecoded ASN.1 object.
-type RawValue struct {
- Class, Tag int
- IsCompound bool
- Bytes []byte
- FullBytes []byte // includes the tag and length
-}
-
-// RawContent is used to signal that the undecoded, DER data needs to be
-// preserved for a struct. To use it, the first field of the struct must have
-// this type. It's an error for any of the other fields to have this type.
-type RawContent []byte
-
-// Tagging
-
-// parseTagAndLength parses an ASN.1 tag and length pair from the given offset
-// into a byte slice. It returns the parsed data and the new offset. SET and
-// SET OF (tag 17) are mapped to SEQUENCE and SEQUENCE OF (tag 16) since we
-// don't distinguish between ordered and unordered objects in this code.
-func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err error) {
- offset = initOffset
- // parseTagAndLength should not be called without at least a single
- // byte to read. Thus this check is for robustness:
- if offset >= len(bytes) {
- err = errors.New("asn1: internal error in parseTagAndLength")
- return
- }
- b := bytes[offset]
- offset++
- ret.class = int(b >> 6)
- ret.isCompound = b&0x20 == 0x20
- ret.tag = int(b & 0x1f)
-
- // If the bottom five bits are set, then the tag number is actually base 128
- // encoded afterwards
- if ret.tag == 0x1f {
- ret.tag, offset, err = parseBase128Int(bytes, offset)
- if err != nil {
- return
- }
- // Tags should be encoded in minimal form.
- if ret.tag < 0x1f {
- err = SyntaxError{"non-minimal tag"}
- return
- }
- }
- if offset >= len(bytes) {
- err = SyntaxError{"truncated tag or length"}
- return
- }
- b = bytes[offset]
- offset++
- if b&0x80 == 0 {
- // The length is encoded in the bottom 7 bits.
- ret.length = int(b & 0x7f)
- } else {
- // Bottom 7 bits give the number of length bytes to follow.
- numBytes := int(b & 0x7f)
- if numBytes == 0 {
- err = SyntaxError{"indefinite length found (not DER)"}
- return
- }
- ret.length = 0
- for i := 0; i < numBytes; i++ {
- if offset >= len(bytes) {
- err = SyntaxError{"truncated tag or length"}
- return
- }
- b = bytes[offset]
- offset++
- if ret.length >= 1<<23 {
- // We can't shift ret.length up without
- // overflowing.
- err = StructuralError{"length too large"}
- return
- }
- ret.length <<= 8
- ret.length |= int(b)
- if ret.length == 0 {
- // DER requires that lengths be minimal.
- err = StructuralError{"superfluous leading zeros in length"}
- return
- }
- }
- // Short lengths must be encoded in short form.
- if ret.length < 0x80 {
- err = StructuralError{"non-minimal length"}
- return
- }
- }
-
- return
-}
-
-// parseSequenceOf is used for SEQUENCE OF and SET OF values. It tries to parse
-// a number of ASN.1 values from the given byte slice and returns them as a
-// slice of Go values of the given type.
-func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err error) {
- matchAny, expectedTag, compoundType, ok := getUniversalType(elemType)
- if !ok {
- err = StructuralError{"unknown Go type for slice"}
- return
- }
-
- // First we iterate over the input and count the number of elements,
- // checking that the types are correct in each case.
- numElements := 0
- for offset := 0; offset < len(bytes); {
- var t tagAndLength
- t, offset, err = parseTagAndLength(bytes, offset)
- if err != nil {
- return
- }
- switch t.tag {
- case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString, TagBMPString:
- // We pretend that various other string types are
- // PRINTABLE STRINGs so that a sequence of them can be
- // parsed into a []string.
- t.tag = TagPrintableString
- case TagGeneralizedTime, TagUTCTime:
- // Likewise, both time types are treated the same.
- t.tag = TagUTCTime
- }
-
- if !matchAny && (t.class != ClassUniversal || t.isCompound != compoundType || t.tag != expectedTag) {
- err = StructuralError{"sequence tag mismatch"}
- return
- }
- if invalidLength(offset, t.length, len(bytes)) {
- err = SyntaxError{"truncated sequence"}
- return
- }
- offset += t.length
- numElements++
- }
- ret = reflect.MakeSlice(sliceType, numElements, numElements)
- params := fieldParameters{}
- offset := 0
- for i := 0; i < numElements; i++ {
- offset, err = parseField(ret.Index(i), bytes, offset, params)
- if err != nil {
- return
- }
- }
- return
-}
-
-var (
- bitStringType = reflect.TypeOf(BitString{})
- objectIdentifierType = reflect.TypeOf(ObjectIdentifier{})
- enumeratedType = reflect.TypeOf(Enumerated(0))
- flagType = reflect.TypeOf(Flag(false))
- timeType = reflect.TypeOf(time.Time{})
- rawValueType = reflect.TypeOf(RawValue{})
- rawContentsType = reflect.TypeOf(RawContent(nil))
- bigIntType = reflect.TypeOf((*big.Int)(nil))
-)
-
-// invalidLength reports whether offset + length > sliceLength, or if the
-// addition would overflow.
-func invalidLength(offset, length, sliceLength int) bool {
- return offset+length < offset || offset+length > sliceLength
-}
-
-// parseField is the main parsing function. Given a byte slice and an offset
-// into the array, it will try to parse a suitable ASN.1 value out and store it
-// in the given Value.
-func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParameters) (offset int, err error) {
- offset = initOffset
- fieldType := v.Type()
-
- // If we have run out of data, it may be that there are optional elements at the end.
- if offset == len(bytes) {
- if !setDefaultValue(v, params) {
- err = SyntaxError{"sequence truncated"}
- }
- return
- }
-
- // Deal with the ANY type.
- if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 {
- var t tagAndLength
- t, offset, err = parseTagAndLength(bytes, offset)
- if err != nil {
- return
- }
- if invalidLength(offset, t.length, len(bytes)) {
- err = SyntaxError{"data truncated"}
- return
- }
- var result any
- if !t.isCompound && t.class == ClassUniversal {
- innerBytes := bytes[offset : offset+t.length]
- switch t.tag {
- case TagPrintableString:
- result, err = parsePrintableString(innerBytes)
- case TagNumericString:
- result, err = parseNumericString(innerBytes)
- case TagIA5String:
- result, err = parseIA5String(innerBytes)
- case TagT61String:
- result, err = parseT61String(innerBytes)
- case TagUTF8String:
- result, err = parseUTF8String(innerBytes)
- case TagInteger:
- result, err = parseInt64(innerBytes)
- case TagBitString:
- result, err = parseBitString(innerBytes)
- case TagOID:
- result, err = parseObjectIdentifier(innerBytes)
- case TagUTCTime:
- result, err = parseUTCTime(innerBytes)
- case TagGeneralizedTime:
- result, err = parseGeneralizedTime(innerBytes)
- case TagOctetString:
- result = innerBytes
- case TagBMPString:
- result, err = parseBMPString(innerBytes)
- default:
- // If we don't know how to handle the type, we just leave Value as nil.
- }
- }
- offset += t.length
- if err != nil {
- return
- }
- if result != nil {
- v.Set(reflect.ValueOf(result))
- }
- return
- }
-
- t, offset, err := parseTagAndLength(bytes, offset)
- if err != nil {
- return
- }
- if params.explicit {
- expectedClass := ClassContextSpecific
- if params.application {
- expectedClass = ClassApplication
- }
- if offset == len(bytes) {
- err = StructuralError{"explicit tag has no child"}
- return
- }
- if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
- if fieldType == rawValueType {
- // The inner element should not be parsed for RawValues.
- } else if t.length > 0 {
- t, offset, err = parseTagAndLength(bytes, offset)
- if err != nil {
- return
- }
- } else {
- if fieldType != flagType {
- err = StructuralError{"zero length explicit tag was not an asn1.Flag"}
- return
- }
- v.SetBool(true)
- return
- }
- } else {
- // The tags didn't match, it might be an optional element.
- ok := setDefaultValue(v, params)
- if ok {
- offset = initOffset
- } else {
- err = StructuralError{"explicitly tagged member didn't match"}
- }
- return
- }
- }
-
- matchAny, universalTag, compoundType, ok1 := getUniversalType(fieldType)
- if !ok1 {
- err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)}
- return
- }
-
- // Special case for strings: all the ASN.1 string types map to the Go
- // type string. getUniversalType returns the tag for PrintableString
- // when it sees a string, so if we see a different string type on the
- // wire, we change the universal type to match.
- if universalTag == TagPrintableString {
- if t.class == ClassUniversal {
- switch t.tag {
- case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString, TagBMPString:
- universalTag = t.tag
- }
- } else if params.stringType != 0 {
- universalTag = params.stringType
- }
- }
-
- // Special case for time: UTCTime and GeneralizedTime both map to the
- // Go type time.Time.
- if universalTag == TagUTCTime && t.tag == TagGeneralizedTime && t.class == ClassUniversal {
- universalTag = TagGeneralizedTime
- }
-
- if params.set {
- universalTag = TagSet
- }
-
- matchAnyClassAndTag := matchAny
- expectedClass := ClassUniversal
- expectedTag := universalTag
-
- if !params.explicit && params.tag != nil {
- expectedClass = ClassContextSpecific
- expectedTag = *params.tag
- matchAnyClassAndTag = false
- }
-
- if !params.explicit && params.application && params.tag != nil {
- expectedClass = ClassApplication
- expectedTag = *params.tag
- matchAnyClassAndTag = false
- }
-
- if !params.explicit && params.private && params.tag != nil {
- expectedClass = ClassPrivate
- expectedTag = *params.tag
- matchAnyClassAndTag = false
- }
-
- // We have unwrapped any explicit tagging at this point.
- if !matchAnyClassAndTag && (t.class != expectedClass || t.tag != expectedTag) ||
- (!matchAny && t.isCompound != compoundType) {
- // Tags don't match. Again, it could be an optional element.
- ok := setDefaultValue(v, params)
- if ok {
- offset = initOffset
- } else {
- err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)}
- }
- return
- }
- if invalidLength(offset, t.length, len(bytes)) {
- err = SyntaxError{"data truncated"}
- return
- }
- innerBytes := bytes[offset : offset+t.length]
- offset += t.length
-
- // We deal with the structures defined in this package first.
- switch v := v.Addr().Interface().(type) {
- case *RawValue:
- *v = RawValue{t.class, t.tag, t.isCompound, innerBytes, bytes[initOffset:offset]}
- return
- case *ObjectIdentifier:
- *v, err = parseObjectIdentifier(innerBytes)
- return
- case *BitString:
- *v, err = parseBitString(innerBytes)
- return
- case *time.Time:
- if universalTag == TagUTCTime {
- *v, err = parseUTCTime(innerBytes)
- return
- }
- *v, err = parseGeneralizedTime(innerBytes)
- return
- case *Enumerated:
- parsedInt, err1 := parseInt32(innerBytes)
- if err1 == nil {
- *v = Enumerated(parsedInt)
- }
- err = err1
- return
- case *Flag:
- *v = true
- return
- case **big.Int:
- parsedInt, err1 := parseBigInt(innerBytes)
- if err1 == nil {
- *v = parsedInt
- }
- err = err1
- return
- }
- switch val := v; val.Kind() {
- case reflect.Bool:
- parsedBool, err1 := parseBool(innerBytes)
- if err1 == nil {
- val.SetBool(parsedBool)
- }
- err = err1
- return
- case reflect.Int, reflect.Int32, reflect.Int64:
- if val.Type().Size() == 4 {
- parsedInt, err1 := parseInt32(innerBytes)
- if err1 == nil {
- val.SetInt(int64(parsedInt))
- }
- err = err1
- } else {
- parsedInt, err1 := parseInt64(innerBytes)
- if err1 == nil {
- val.SetInt(parsedInt)
- }
- err = err1
- }
- return
- // TODO(dfc) Add support for the remaining integer types
- case reflect.Struct:
- structType := fieldType
-
- for i := 0; i < structType.NumField(); i++ {
- if !structType.Field(i).IsExported() {
- err = StructuralError{"struct contains unexported fields"}
- return
- }
- }
-
- if structType.NumField() > 0 &&
- structType.Field(0).Type == rawContentsType {
- bytes := bytes[initOffset:offset]
- val.Field(0).Set(reflect.ValueOf(RawContent(bytes)))
- }
-
- innerOffset := 0
- for i := 0; i < structType.NumField(); i++ {
- field := structType.Field(i)
- if i == 0 && field.Type == rawContentsType {
- continue
- }
- innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag.Get("asn1")))
- if err != nil {
- return
- }
- }
- // We allow extra bytes at the end of the SEQUENCE because
- // adding elements to the end has been used in X.509 as the
- // version numbers have increased.
- return
- case reflect.Slice:
- sliceType := fieldType
- if sliceType.Elem().Kind() == reflect.Uint8 {
- val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes)))
- reflect.Copy(val, reflect.ValueOf(innerBytes))
- return
- }
- newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem())
- if err1 == nil {
- val.Set(newSlice)
- }
- err = err1
- return
- case reflect.String:
- var v string
- switch universalTag {
- case TagPrintableString:
- v, err = parsePrintableString(innerBytes)
- case TagNumericString:
- v, err = parseNumericString(innerBytes)
- case TagIA5String:
- v, err = parseIA5String(innerBytes)
- case TagT61String:
- v, err = parseT61String(innerBytes)
- case TagUTF8String:
- v, err = parseUTF8String(innerBytes)
- case TagGeneralString:
- // GeneralString is specified in ISO-2022/ECMA-35,
- // A brief review suggests that it includes structures
- // that allow the encoding to change midstring and
- // such. We give up and pass it as an 8-bit string.
- v, err = parseT61String(innerBytes)
- case TagBMPString:
- v, err = parseBMPString(innerBytes)
-
- default:
- err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)}
- }
- if err == nil {
- val.SetString(v)
- }
- return
- }
- err = StructuralError{"unsupported: " + v.Type().String()}
- return
-}
-
-// canHaveDefaultValue reports whether k is a Kind that we will set a default
-// value for. (A signed integer, essentially.)
-func canHaveDefaultValue(k reflect.Kind) bool {
- switch k {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return true
- }
-
- return false
-}
-
-// setDefaultValue is used to install a default value, from a tag string, into
-// a Value. It is successful if the field was optional, even if a default value
-// wasn't provided or it failed to install it into the Value.
-func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
- if !params.optional {
- return
- }
- ok = true
- if params.defaultValue == nil {
- return
- }
- if canHaveDefaultValue(v.Kind()) {
- v.SetInt(*params.defaultValue)
- }
- return
-}
-
-// Unmarshal parses the DER-encoded ASN.1 data structure b
-// and uses the reflect package to fill in an arbitrary value pointed at by val.
-// Because Unmarshal uses the reflect package, the structs
-// being written to must use upper case field names. If val
-// is nil or not a pointer, Unmarshal returns an error.
-//
-// After parsing b, any bytes that were leftover and not used to fill
-// val will be returned in rest. When parsing a SEQUENCE into a struct,
-// any trailing elements of the SEQUENCE that do not have matching
-// fields in val will not be included in rest, as these are considered
-// valid elements of the SEQUENCE and not trailing data.
-//
-// An ASN.1 INTEGER can be written to an int, int32, int64,
-// or *big.Int (from the math/big package).
-// If the encoded value does not fit in the Go type,
-// Unmarshal returns a parse error.
-//
-// An ASN.1 BIT STRING can be written to a BitString.
-//
-// An ASN.1 OCTET STRING can be written to a []byte.
-//
-// An ASN.1 OBJECT IDENTIFIER can be written to an
-// ObjectIdentifier.
-//
-// An ASN.1 ENUMERATED can be written to an Enumerated.
-//
-// An ASN.1 UTCTIME or GENERALIZEDTIME can be written to a time.Time.
-//
-// An ASN.1 PrintableString, IA5String, or NumericString can be written to a string.
-//
-// Any of the above ASN.1 values can be written to an interface{}.
-// The value stored in the interface has the corresponding Go type.
-// For integers, that type is int64.
-//
-// An ASN.1 SEQUENCE OF x or SET OF x can be written
-// to a slice if an x can be written to the slice's element type.
-//
-// An ASN.1 SEQUENCE or SET can be written to a struct
-// if each of the elements in the sequence can be
-// written to the corresponding element in the struct.
-//
-// The following tags on struct fields have special meaning to Unmarshal:
-//
-// application specifies that an APPLICATION tag is used
-// private specifies that a PRIVATE tag is used
-// default:x sets the default value for optional integer fields (only used if optional is also present)
-// explicit specifies that an additional, explicit tag wraps the implicit one
-// optional marks the field as ASN.1 OPTIONAL
-// set causes a SET, rather than a SEQUENCE type to be expected
-// tag:x specifies the ASN.1 tag number; implies ASN.1 CONTEXT SPECIFIC
-//
-// When decoding an ASN.1 value with an IMPLICIT tag into a string field,
-// Unmarshal will default to a PrintableString, which doesn't support
-// characters such as '@' and '&'. To force other encodings, use the following
-// tags:
-//
-// ia5 causes strings to be unmarshaled as ASN.1 IA5String values
-// numeric causes strings to be unmarshaled as ASN.1 NumericString values
-// utf8 causes strings to be unmarshaled as ASN.1 UTF8String values
-//
-// If the type of the first field of a structure is RawContent then the raw
-// ASN1 contents of the struct will be stored in it.
-//
-// If the name of a slice type ends with "SET" then it's treated as if
-// the "set" tag was set on it. This results in interpreting the type as a
-// SET OF x rather than a SEQUENCE OF x. This can be used with nested slices
-// where a struct tag cannot be given.
-//
-// Other ASN.1 types are not supported; if it encounters them,
-// Unmarshal returns a parse error.
-func Unmarshal(b []byte, val any) (rest []byte, err error) {
- return UnmarshalWithParams(b, val, "")
-}
-
-// An invalidUnmarshalError describes an invalid argument passed to Unmarshal.
-// (The argument to Unmarshal must be a non-nil pointer.)
-type invalidUnmarshalError struct {
- Type reflect.Type
-}
-
-func (e *invalidUnmarshalError) Error() string {
- if e.Type == nil {
- return "asn1: Unmarshal recipient value is nil"
- }
-
- if e.Type.Kind() != reflect.Pointer {
- return "asn1: Unmarshal recipient value is non-pointer " + e.Type.String()
- }
- return "asn1: Unmarshal recipient value is nil " + e.Type.String()
-}
-
-// UnmarshalWithParams allows field parameters to be specified for the
-// top-level element. The form of the params is the same as the field tags.
-func UnmarshalWithParams(b []byte, val any, params string) (rest []byte, err error) {
- v := reflect.ValueOf(val)
- if v.Kind() != reflect.Pointer || v.IsNil() {
- return nil, &invalidUnmarshalError{reflect.TypeOf(val)}
- }
- offset, err := parseField(v.Elem(), b, 0, parseFieldParameters(params))
- if err != nil {
- return nil, err
- }
- return b[offset:], nil
-}
diff --git a/contrib/go/_std_1.20/src/encoding/asn1/ya.make b/contrib/go/_std_1.20/src/encoding/asn1/ya.make
deleted file mode 100644
index abd9fd9c4b..0000000000
--- a/contrib/go/_std_1.20/src/encoding/asn1/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- asn1.go
- common.go
- marshal.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/encoding/base32/base32.go b/contrib/go/_std_1.20/src/encoding/base32/base32.go
deleted file mode 100644
index 41d343aaac..0000000000
--- a/contrib/go/_std_1.20/src/encoding/base32/base32.go
+++ /dev/null
@@ -1,549 +0,0 @@
-// Copyright 2011 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 base32 implements base32 encoding as specified by RFC 4648.
-package base32
-
-import (
- "io"
- "strconv"
-)
-
-/*
- * Encodings
- */
-
-// An Encoding is a radix 32 encoding/decoding scheme, defined by a
-// 32-character alphabet. The most common is the "base32" encoding
-// introduced for SASL GSSAPI and standardized in RFC 4648.
-// The alternate "base32hex" encoding is used in DNSSEC.
-type Encoding struct {
- encode [32]byte
- decodeMap [256]byte
- padChar rune
-}
-
-const (
- StdPadding rune = '=' // Standard padding character
- NoPadding rune = -1 // No padding
- decodeMapInitialize = "" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
-)
-
-const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
-const encodeHex = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
-
-// NewEncoding returns a new Encoding defined by the given alphabet,
-// which must be a 32-byte string.
-func NewEncoding(encoder string) *Encoding {
- if len(encoder) != 32 {
- panic("encoding alphabet is not 32-bytes long")
- }
-
- e := new(Encoding)
- e.padChar = StdPadding
- copy(e.encode[:], encoder)
- copy(e.decodeMap[:], decodeMapInitialize)
-
- for i := 0; i < len(encoder); i++ {
- e.decodeMap[encoder[i]] = byte(i)
- }
- return e
-}
-
-// StdEncoding is the standard base32 encoding, as defined in
-// RFC 4648.
-var StdEncoding = NewEncoding(encodeStd)
-
-// HexEncoding is the “Extended Hex Alphabet” defined in RFC 4648.
-// It is typically used in DNS.
-var HexEncoding = NewEncoding(encodeHex)
-
-// WithPadding creates a new encoding identical to enc except
-// with a specified padding character, or NoPadding to disable padding.
-// The padding character must not be '\r' or '\n', must not
-// be contained in the encoding's alphabet and must be a rune equal or
-// below '\xff'.
-func (enc Encoding) WithPadding(padding rune) *Encoding {
- if padding == '\r' || padding == '\n' || padding > 0xff {
- panic("invalid padding")
- }
-
- for i := 0; i < len(enc.encode); i++ {
- if rune(enc.encode[i]) == padding {
- panic("padding contained in alphabet")
- }
- }
-
- enc.padChar = padding
- return &enc
-}
-
-/*
- * Encoder
- */
-
-// Encode encodes src using the encoding enc, writing
-// EncodedLen(len(src)) bytes to dst.
-//
-// The encoding pads the output to a multiple of 8 bytes,
-// so Encode is not appropriate for use on individual blocks
-// of a large data stream. Use NewEncoder() instead.
-func (enc *Encoding) Encode(dst, src []byte) {
- for len(src) > 0 {
- var b [8]byte
-
- // Unpack 8x 5-bit source blocks into a 5 byte
- // destination quantum
- switch len(src) {
- default:
- b[7] = src[4] & 0x1F
- b[6] = src[4] >> 5
- fallthrough
- case 4:
- b[6] |= (src[3] << 3) & 0x1F
- b[5] = (src[3] >> 2) & 0x1F
- b[4] = src[3] >> 7
- fallthrough
- case 3:
- b[4] |= (src[2] << 1) & 0x1F
- b[3] = (src[2] >> 4) & 0x1F
- fallthrough
- case 2:
- b[3] |= (src[1] << 4) & 0x1F
- b[2] = (src[1] >> 1) & 0x1F
- b[1] = (src[1] >> 6) & 0x1F
- fallthrough
- case 1:
- b[1] |= (src[0] << 2) & 0x1F
- b[0] = src[0] >> 3
- }
-
- // Encode 5-bit blocks using the base32 alphabet
- size := len(dst)
- if size >= 8 {
- // Common case, unrolled for extra performance
- dst[0] = enc.encode[b[0]&31]
- dst[1] = enc.encode[b[1]&31]
- dst[2] = enc.encode[b[2]&31]
- dst[3] = enc.encode[b[3]&31]
- dst[4] = enc.encode[b[4]&31]
- dst[5] = enc.encode[b[5]&31]
- dst[6] = enc.encode[b[6]&31]
- dst[7] = enc.encode[b[7]&31]
- } else {
- for i := 0; i < size; i++ {
- dst[i] = enc.encode[b[i]&31]
- }
- }
-
- // Pad the final quantum
- if len(src) < 5 {
- if enc.padChar == NoPadding {
- break
- }
-
- dst[7] = byte(enc.padChar)
- if len(src) < 4 {
- dst[6] = byte(enc.padChar)
- dst[5] = byte(enc.padChar)
- if len(src) < 3 {
- dst[4] = byte(enc.padChar)
- if len(src) < 2 {
- dst[3] = byte(enc.padChar)
- dst[2] = byte(enc.padChar)
- }
- }
- }
-
- break
- }
-
- src = src[5:]
- dst = dst[8:]
- }
-}
-
-// EncodeToString returns the base32 encoding of src.
-func (enc *Encoding) EncodeToString(src []byte) string {
- buf := make([]byte, enc.EncodedLen(len(src)))
- enc.Encode(buf, src)
- return string(buf)
-}
-
-type encoder struct {
- err error
- enc *Encoding
- w io.Writer
- buf [5]byte // buffered data waiting to be encoded
- nbuf int // number of bytes in buf
- out [1024]byte // output buffer
-}
-
-func (e *encoder) Write(p []byte) (n int, err error) {
- if e.err != nil {
- return 0, e.err
- }
-
- // Leading fringe.
- if e.nbuf > 0 {
- var i int
- for i = 0; i < len(p) && e.nbuf < 5; i++ {
- e.buf[e.nbuf] = p[i]
- e.nbuf++
- }
- n += i
- p = p[i:]
- if e.nbuf < 5 {
- return
- }
- e.enc.Encode(e.out[0:], e.buf[0:])
- if _, e.err = e.w.Write(e.out[0:8]); e.err != nil {
- return n, e.err
- }
- e.nbuf = 0
- }
-
- // Large interior chunks.
- for len(p) >= 5 {
- nn := len(e.out) / 8 * 5
- if nn > len(p) {
- nn = len(p)
- nn -= nn % 5
- }
- e.enc.Encode(e.out[0:], p[0:nn])
- if _, e.err = e.w.Write(e.out[0 : nn/5*8]); e.err != nil {
- return n, e.err
- }
- n += nn
- p = p[nn:]
- }
-
- // Trailing fringe.
- copy(e.buf[:], p)
- e.nbuf = len(p)
- n += len(p)
- return
-}
-
-// Close flushes any pending output from the encoder.
-// It is an error to call Write after calling Close.
-func (e *encoder) Close() error {
- // If there's anything left in the buffer, flush it out
- if e.err == nil && e.nbuf > 0 {
- e.enc.Encode(e.out[0:], e.buf[0:e.nbuf])
- encodedLen := e.enc.EncodedLen(e.nbuf)
- e.nbuf = 0
- _, e.err = e.w.Write(e.out[0:encodedLen])
- }
- return e.err
-}
-
-// NewEncoder returns a new base32 stream encoder. Data written to
-// the returned writer will be encoded using enc and then written to w.
-// Base32 encodings operate in 5-byte blocks; when finished
-// writing, the caller must Close the returned encoder to flush any
-// partially written blocks.
-func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
- return &encoder{enc: enc, w: w}
-}
-
-// EncodedLen returns the length in bytes of the base32 encoding
-// of an input buffer of length n.
-func (enc *Encoding) EncodedLen(n int) int {
- if enc.padChar == NoPadding {
- return (n*8 + 4) / 5
- }
- return (n + 4) / 5 * 8
-}
-
-/*
- * Decoder
- */
-
-type CorruptInputError int64
-
-func (e CorruptInputError) Error() string {
- return "illegal base32 data at input byte " + strconv.FormatInt(int64(e), 10)
-}
-
-// decode is like Decode but returns an additional 'end' value, which
-// indicates if end-of-message padding was encountered and thus any
-// additional data is an error. This method assumes that src has been
-// stripped of all supported whitespace ('\r' and '\n').
-func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
- // Lift the nil check outside of the loop.
- _ = enc.decodeMap
-
- dsti := 0
- olen := len(src)
-
- for len(src) > 0 && !end {
- // Decode quantum using the base32 alphabet
- var dbuf [8]byte
- dlen := 8
-
- for j := 0; j < 8; {
-
- if len(src) == 0 {
- if enc.padChar != NoPadding {
- // We have reached the end and are missing padding
- return n, false, CorruptInputError(olen - len(src) - j)
- }
- // We have reached the end and are not expecting any padding
- dlen, end = j, true
- break
- }
- in := src[0]
- src = src[1:]
- if in == byte(enc.padChar) && j >= 2 && len(src) < 8 {
- // We've reached the end and there's padding
- if len(src)+j < 8-1 {
- // not enough padding
- return n, false, CorruptInputError(olen)
- }
- for k := 0; k < 8-1-j; k++ {
- if len(src) > k && src[k] != byte(enc.padChar) {
- // incorrect padding
- return n, false, CorruptInputError(olen - len(src) + k - 1)
- }
- }
- dlen, end = j, true
- // 7, 5 and 2 are not valid padding lengths, and so 1, 3 and 6 are not
- // valid dlen values. See RFC 4648 Section 6 "Base 32 Encoding" listing
- // the five valid padding lengths, and Section 9 "Illustrations and
- // Examples" for an illustration for how the 1st, 3rd and 6th base32
- // src bytes do not yield enough information to decode a dst byte.
- if dlen == 1 || dlen == 3 || dlen == 6 {
- return n, false, CorruptInputError(olen - len(src) - 1)
- }
- break
- }
- dbuf[j] = enc.decodeMap[in]
- if dbuf[j] == 0xFF {
- return n, false, CorruptInputError(olen - len(src) - 1)
- }
- j++
- }
-
- // Pack 8x 5-bit source blocks into 5 byte destination
- // quantum
- switch dlen {
- case 8:
- dst[dsti+4] = dbuf[6]<<5 | dbuf[7]
- n++
- fallthrough
- case 7:
- dst[dsti+3] = dbuf[4]<<7 | dbuf[5]<<2 | dbuf[6]>>3
- n++
- fallthrough
- case 5:
- dst[dsti+2] = dbuf[3]<<4 | dbuf[4]>>1
- n++
- fallthrough
- case 4:
- dst[dsti+1] = dbuf[1]<<6 | dbuf[2]<<1 | dbuf[3]>>4
- n++
- fallthrough
- case 2:
- dst[dsti+0] = dbuf[0]<<3 | dbuf[1]>>2
- n++
- }
- dsti += 5
- }
- return n, end, nil
-}
-
-// Decode decodes src using the encoding enc. It writes at most
-// DecodedLen(len(src)) bytes to dst and returns the number of bytes
-// written. If src contains invalid base32 data, it will return the
-// number of bytes successfully written and CorruptInputError.
-// New line characters (\r and \n) are ignored.
-func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
- buf := make([]byte, len(src))
- l := stripNewlines(buf, src)
- n, _, err = enc.decode(dst, buf[:l])
- return
-}
-
-// DecodeString returns the bytes represented by the base32 string s.
-func (enc *Encoding) DecodeString(s string) ([]byte, error) {
- buf := []byte(s)
- l := stripNewlines(buf, buf)
- n, _, err := enc.decode(buf, buf[:l])
- return buf[:n], err
-}
-
-type decoder struct {
- err error
- enc *Encoding
- r io.Reader
- end bool // saw end of message
- buf [1024]byte // leftover input
- nbuf int
- out []byte // leftover decoded output
- outbuf [1024 / 8 * 5]byte
-}
-
-func readEncodedData(r io.Reader, buf []byte, min int, expectsPadding bool) (n int, err error) {
- for n < min && err == nil {
- var nn int
- nn, err = r.Read(buf[n:])
- n += nn
- }
- // data was read, less than min bytes could be read
- if n < min && n > 0 && err == io.EOF {
- err = io.ErrUnexpectedEOF
- }
- // no data was read, the buffer already contains some data
- // when padding is disabled this is not an error, as the message can be of
- // any length
- if expectsPadding && min < 8 && n == 0 && err == io.EOF {
- err = io.ErrUnexpectedEOF
- }
- return
-}
-
-func (d *decoder) Read(p []byte) (n int, err error) {
- // Use leftover decoded output from last read.
- if len(d.out) > 0 {
- n = copy(p, d.out)
- d.out = d.out[n:]
- if len(d.out) == 0 {
- return n, d.err
- }
- return n, nil
- }
-
- if d.err != nil {
- return 0, d.err
- }
-
- // Read a chunk.
- nn := len(p) / 5 * 8
- if nn < 8 {
- nn = 8
- }
- if nn > len(d.buf) {
- nn = len(d.buf)
- }
-
- // Minimum amount of bytes that needs to be read each cycle
- var min int
- var expectsPadding bool
- if d.enc.padChar == NoPadding {
- min = 1
- expectsPadding = false
- } else {
- min = 8 - d.nbuf
- expectsPadding = true
- }
-
- nn, d.err = readEncodedData(d.r, d.buf[d.nbuf:nn], min, expectsPadding)
- d.nbuf += nn
- if d.nbuf < min {
- return 0, d.err
- }
- if nn > 0 && d.end {
- return 0, CorruptInputError(0)
- }
-
- // Decode chunk into p, or d.out and then p if p is too small.
- var nr int
- if d.enc.padChar == NoPadding {
- nr = d.nbuf
- } else {
- nr = d.nbuf / 8 * 8
- }
- nw := d.enc.DecodedLen(d.nbuf)
-
- if nw > len(p) {
- nw, d.end, err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
- d.out = d.outbuf[0:nw]
- n = copy(p, d.out)
- d.out = d.out[n:]
- } else {
- n, d.end, err = d.enc.decode(p, d.buf[0:nr])
- }
- d.nbuf -= nr
- for i := 0; i < d.nbuf; i++ {
- d.buf[i] = d.buf[i+nr]
- }
-
- if err != nil && (d.err == nil || d.err == io.EOF) {
- d.err = err
- }
-
- if len(d.out) > 0 {
- // We cannot return all the decoded bytes to the caller in this
- // invocation of Read, so we return a nil error to ensure that Read
- // will be called again. The error stored in d.err, if any, will be
- // returned with the last set of decoded bytes.
- return n, nil
- }
-
- return n, d.err
-}
-
-type newlineFilteringReader struct {
- wrapped io.Reader
-}
-
-// stripNewlines removes newline characters and returns the number
-// of non-newline characters copied to dst.
-func stripNewlines(dst, src []byte) int {
- offset := 0
- for _, b := range src {
- if b == '\r' || b == '\n' {
- continue
- }
- dst[offset] = b
- offset++
- }
- return offset
-}
-
-func (r *newlineFilteringReader) Read(p []byte) (int, error) {
- n, err := r.wrapped.Read(p)
- for n > 0 {
- s := p[0:n]
- offset := stripNewlines(s, s)
- if err != nil || offset > 0 {
- return offset, err
- }
- // Previous buffer entirely whitespace, read again
- n, err = r.wrapped.Read(p)
- }
- return n, err
-}
-
-// NewDecoder constructs a new base32 stream decoder.
-func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
- return &decoder{enc: enc, r: &newlineFilteringReader{r}}
-}
-
-// DecodedLen returns the maximum length in bytes of the decoded data
-// corresponding to n bytes of base32-encoded data.
-func (enc *Encoding) DecodedLen(n int) int {
- if enc.padChar == NoPadding {
- return n * 5 / 8
- }
-
- return n / 8 * 5
-}
diff --git a/contrib/go/_std_1.20/src/encoding/base32/ya.make b/contrib/go/_std_1.20/src/encoding/base32/ya.make
deleted file mode 100644
index ce1ac0d99f..0000000000
--- a/contrib/go/_std_1.20/src/encoding/base32/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- base32.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/encoding/base64/base64.go b/contrib/go/_std_1.20/src/encoding/base64/base64.go
deleted file mode 100644
index 0e12d90d29..0000000000
--- a/contrib/go/_std_1.20/src/encoding/base64/base64.go
+++ /dev/null
@@ -1,627 +0,0 @@
-// Copyright 2009 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 base64 implements base64 encoding as specified by RFC 4648.
-package base64
-
-import (
- "encoding/binary"
- "io"
- "strconv"
-)
-
-/*
- * Encodings
- */
-
-// An Encoding is a radix 64 encoding/decoding scheme, defined by a
-// 64-character alphabet. The most common encoding is the "base64"
-// encoding defined in RFC 4648 and used in MIME (RFC 2045) and PEM
-// (RFC 1421). RFC 4648 also defines an alternate encoding, which is
-// the standard encoding with - and _ substituted for + and /.
-type Encoding struct {
- encode [64]byte
- decodeMap [256]byte
- padChar rune
- strict bool
-}
-
-const (
- StdPadding rune = '=' // Standard padding character
- NoPadding rune = -1 // No padding
- decodeMapInitialize = "" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
- "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
-)
-
-const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
-const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
-
-// NewEncoding returns a new padded Encoding defined by the given alphabet,
-// which must be a 64-byte string that does not contain the padding character
-// or CR / LF ('\r', '\n').
-// The resulting Encoding uses the default padding character ('='),
-// which may be changed or disabled via WithPadding.
-func NewEncoding(encoder string) *Encoding {
- if len(encoder) != 64 {
- panic("encoding alphabet is not 64-bytes long")
- }
- for i := 0; i < len(encoder); i++ {
- if encoder[i] == '\n' || encoder[i] == '\r' {
- panic("encoding alphabet contains newline character")
- }
- }
-
- e := new(Encoding)
- e.padChar = StdPadding
- copy(e.encode[:], encoder)
- copy(e.decodeMap[:], decodeMapInitialize)
-
- for i := 0; i < len(encoder); i++ {
- e.decodeMap[encoder[i]] = byte(i)
- }
- return e
-}
-
-// WithPadding creates a new encoding identical to enc except
-// with a specified padding character, or NoPadding to disable padding.
-// The padding character must not be '\r' or '\n', must not
-// be contained in the encoding's alphabet and must be a rune equal or
-// below '\xff'.
-func (enc Encoding) WithPadding(padding rune) *Encoding {
- if padding == '\r' || padding == '\n' || padding > 0xff {
- panic("invalid padding")
- }
-
- for i := 0; i < len(enc.encode); i++ {
- if rune(enc.encode[i]) == padding {
- panic("padding contained in alphabet")
- }
- }
-
- enc.padChar = padding
- return &enc
-}
-
-// Strict creates a new encoding identical to enc except with
-// strict decoding enabled. In this mode, the decoder requires that
-// trailing padding bits are zero, as described in RFC 4648 section 3.5.
-//
-// Note that the input is still malleable, as new line characters
-// (CR and LF) are still ignored.
-func (enc Encoding) Strict() *Encoding {
- enc.strict = true
- return &enc
-}
-
-// StdEncoding is the standard base64 encoding, as defined in
-// RFC 4648.
-var StdEncoding = NewEncoding(encodeStd)
-
-// URLEncoding is the alternate base64 encoding defined in RFC 4648.
-// It is typically used in URLs and file names.
-var URLEncoding = NewEncoding(encodeURL)
-
-// RawStdEncoding is the standard raw, unpadded base64 encoding,
-// as defined in RFC 4648 section 3.2.
-// This is the same as StdEncoding but omits padding characters.
-var RawStdEncoding = StdEncoding.WithPadding(NoPadding)
-
-// RawURLEncoding is the unpadded alternate base64 encoding defined in RFC 4648.
-// It is typically used in URLs and file names.
-// This is the same as URLEncoding but omits padding characters.
-var RawURLEncoding = URLEncoding.WithPadding(NoPadding)
-
-/*
- * Encoder
- */
-
-// Encode encodes src using the encoding enc, writing
-// EncodedLen(len(src)) bytes to dst.
-//
-// The encoding pads the output to a multiple of 4 bytes,
-// so Encode is not appropriate for use on individual blocks
-// of a large data stream. Use NewEncoder() instead.
-func (enc *Encoding) Encode(dst, src []byte) {
- if len(src) == 0 {
- return
- }
- // enc is a pointer receiver, so the use of enc.encode within the hot
- // loop below means a nil check at every operation. Lift that nil check
- // outside of the loop to speed up the encoder.
- _ = enc.encode
-
- di, si := 0, 0
- n := (len(src) / 3) * 3
- for si < n {
- // Convert 3x 8bit source bytes into 4 bytes
- val := uint(src[si+0])<<16 | uint(src[si+1])<<8 | uint(src[si+2])
-
- dst[di+0] = enc.encode[val>>18&0x3F]
- dst[di+1] = enc.encode[val>>12&0x3F]
- dst[di+2] = enc.encode[val>>6&0x3F]
- dst[di+3] = enc.encode[val&0x3F]
-
- si += 3
- di += 4
- }
-
- remain := len(src) - si
- if remain == 0 {
- return
- }
- // Add the remaining small block
- val := uint(src[si+0]) << 16
- if remain == 2 {
- val |= uint(src[si+1]) << 8
- }
-
- dst[di+0] = enc.encode[val>>18&0x3F]
- dst[di+1] = enc.encode[val>>12&0x3F]
-
- switch remain {
- case 2:
- dst[di+2] = enc.encode[val>>6&0x3F]
- if enc.padChar != NoPadding {
- dst[di+3] = byte(enc.padChar)
- }
- case 1:
- if enc.padChar != NoPadding {
- dst[di+2] = byte(enc.padChar)
- dst[di+3] = byte(enc.padChar)
- }
- }
-}
-
-// EncodeToString returns the base64 encoding of src.
-func (enc *Encoding) EncodeToString(src []byte) string {
- buf := make([]byte, enc.EncodedLen(len(src)))
- enc.Encode(buf, src)
- return string(buf)
-}
-
-type encoder struct {
- err error
- enc *Encoding
- w io.Writer
- buf [3]byte // buffered data waiting to be encoded
- nbuf int // number of bytes in buf
- out [1024]byte // output buffer
-}
-
-func (e *encoder) Write(p []byte) (n int, err error) {
- if e.err != nil {
- return 0, e.err
- }
-
- // Leading fringe.
- if e.nbuf > 0 {
- var i int
- for i = 0; i < len(p) && e.nbuf < 3; i++ {
- e.buf[e.nbuf] = p[i]
- e.nbuf++
- }
- n += i
- p = p[i:]
- if e.nbuf < 3 {
- return
- }
- e.enc.Encode(e.out[:], e.buf[:])
- if _, e.err = e.w.Write(e.out[:4]); e.err != nil {
- return n, e.err
- }
- e.nbuf = 0
- }
-
- // Large interior chunks.
- for len(p) >= 3 {
- nn := len(e.out) / 4 * 3
- if nn > len(p) {
- nn = len(p)
- nn -= nn % 3
- }
- e.enc.Encode(e.out[:], p[:nn])
- if _, e.err = e.w.Write(e.out[0 : nn/3*4]); e.err != nil {
- return n, e.err
- }
- n += nn
- p = p[nn:]
- }
-
- // Trailing fringe.
- copy(e.buf[:], p)
- e.nbuf = len(p)
- n += len(p)
- return
-}
-
-// Close flushes any pending output from the encoder.
-// It is an error to call Write after calling Close.
-func (e *encoder) Close() error {
- // If there's anything left in the buffer, flush it out
- if e.err == nil && e.nbuf > 0 {
- e.enc.Encode(e.out[:], e.buf[:e.nbuf])
- _, e.err = e.w.Write(e.out[:e.enc.EncodedLen(e.nbuf)])
- e.nbuf = 0
- }
- return e.err
-}
-
-// NewEncoder returns a new base64 stream encoder. Data written to
-// the returned writer will be encoded using enc and then written to w.
-// Base64 encodings operate in 4-byte blocks; when finished
-// writing, the caller must Close the returned encoder to flush any
-// partially written blocks.
-func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
- return &encoder{enc: enc, w: w}
-}
-
-// EncodedLen returns the length in bytes of the base64 encoding
-// of an input buffer of length n.
-func (enc *Encoding) EncodedLen(n int) int {
- if enc.padChar == NoPadding {
- return (n*8 + 5) / 6 // minimum # chars at 6 bits per char
- }
- return (n + 2) / 3 * 4 // minimum # 4-char quanta, 3 bytes each
-}
-
-/*
- * Decoder
- */
-
-type CorruptInputError int64
-
-func (e CorruptInputError) Error() string {
- return "illegal base64 data at input byte " + strconv.FormatInt(int64(e), 10)
-}
-
-// decodeQuantum decodes up to 4 base64 bytes. The received parameters are
-// the destination buffer dst, the source buffer src and an index in the
-// source buffer si.
-// It returns the number of bytes read from src, the number of bytes written
-// to dst, and an error, if any.
-func (enc *Encoding) decodeQuantum(dst, src []byte, si int) (nsi, n int, err error) {
- // Decode quantum using the base64 alphabet
- var dbuf [4]byte
- dlen := 4
-
- // Lift the nil check outside of the loop.
- _ = enc.decodeMap
-
- for j := 0; j < len(dbuf); j++ {
- if len(src) == si {
- switch {
- case j == 0:
- return si, 0, nil
- case j == 1, enc.padChar != NoPadding:
- return si, 0, CorruptInputError(si - j)
- }
- dlen = j
- break
- }
- in := src[si]
- si++
-
- out := enc.decodeMap[in]
- if out != 0xff {
- dbuf[j] = out
- continue
- }
-
- if in == '\n' || in == '\r' {
- j--
- continue
- }
-
- if rune(in) != enc.padChar {
- return si, 0, CorruptInputError(si - 1)
- }
-
- // We've reached the end and there's padding
- switch j {
- case 0, 1:
- // incorrect padding
- return si, 0, CorruptInputError(si - 1)
- case 2:
- // "==" is expected, the first "=" is already consumed.
- // skip over newlines
- for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
- si++
- }
- if si == len(src) {
- // not enough padding
- return si, 0, CorruptInputError(len(src))
- }
- if rune(src[si]) != enc.padChar {
- // incorrect padding
- return si, 0, CorruptInputError(si - 1)
- }
-
- si++
- }
-
- // skip over newlines
- for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
- si++
- }
- if si < len(src) {
- // trailing garbage
- err = CorruptInputError(si)
- }
- dlen = j
- break
- }
-
- // Convert 4x 6bit source bytes into 3 bytes
- val := uint(dbuf[0])<<18 | uint(dbuf[1])<<12 | uint(dbuf[2])<<6 | uint(dbuf[3])
- dbuf[2], dbuf[1], dbuf[0] = byte(val>>0), byte(val>>8), byte(val>>16)
- switch dlen {
- case 4:
- dst[2] = dbuf[2]
- dbuf[2] = 0
- fallthrough
- case 3:
- dst[1] = dbuf[1]
- if enc.strict && dbuf[2] != 0 {
- return si, 0, CorruptInputError(si - 1)
- }
- dbuf[1] = 0
- fallthrough
- case 2:
- dst[0] = dbuf[0]
- if enc.strict && (dbuf[1] != 0 || dbuf[2] != 0) {
- return si, 0, CorruptInputError(si - 2)
- }
- }
-
- return si, dlen - 1, err
-}
-
-// DecodeString returns the bytes represented by the base64 string s.
-func (enc *Encoding) DecodeString(s string) ([]byte, error) {
- dbuf := make([]byte, enc.DecodedLen(len(s)))
- n, err := enc.Decode(dbuf, []byte(s))
- return dbuf[:n], err
-}
-
-type decoder struct {
- err error
- readErr error // error from r.Read
- enc *Encoding
- r io.Reader
- buf [1024]byte // leftover input
- nbuf int
- out []byte // leftover decoded output
- outbuf [1024 / 4 * 3]byte
-}
-
-func (d *decoder) Read(p []byte) (n int, err error) {
- // Use leftover decoded output from last read.
- if len(d.out) > 0 {
- n = copy(p, d.out)
- d.out = d.out[n:]
- return n, nil
- }
-
- if d.err != nil {
- return 0, d.err
- }
-
- // This code assumes that d.r strips supported whitespace ('\r' and '\n').
-
- // Refill buffer.
- for d.nbuf < 4 && d.readErr == nil {
- nn := len(p) / 3 * 4
- if nn < 4 {
- nn = 4
- }
- if nn > len(d.buf) {
- nn = len(d.buf)
- }
- nn, d.readErr = d.r.Read(d.buf[d.nbuf:nn])
- d.nbuf += nn
- }
-
- if d.nbuf < 4 {
- if d.enc.padChar == NoPadding && d.nbuf > 0 {
- // Decode final fragment, without padding.
- var nw int
- nw, d.err = d.enc.Decode(d.outbuf[:], d.buf[:d.nbuf])
- d.nbuf = 0
- d.out = d.outbuf[:nw]
- n = copy(p, d.out)
- d.out = d.out[n:]
- if n > 0 || len(p) == 0 && len(d.out) > 0 {
- return n, nil
- }
- if d.err != nil {
- return 0, d.err
- }
- }
- d.err = d.readErr
- if d.err == io.EOF && d.nbuf > 0 {
- d.err = io.ErrUnexpectedEOF
- }
- return 0, d.err
- }
-
- // Decode chunk into p, or d.out and then p if p is too small.
- nr := d.nbuf / 4 * 4
- nw := d.nbuf / 4 * 3
- if nw > len(p) {
- nw, d.err = d.enc.Decode(d.outbuf[:], d.buf[:nr])
- d.out = d.outbuf[:nw]
- n = copy(p, d.out)
- d.out = d.out[n:]
- } else {
- n, d.err = d.enc.Decode(p, d.buf[:nr])
- }
- d.nbuf -= nr
- copy(d.buf[:d.nbuf], d.buf[nr:])
- return n, d.err
-}
-
-// Decode decodes src using the encoding enc. It writes at most
-// DecodedLen(len(src)) bytes to dst and returns the number of bytes
-// written. If src contains invalid base64 data, it will return the
-// number of bytes successfully written and CorruptInputError.
-// New line characters (\r and \n) are ignored.
-func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
- if len(src) == 0 {
- return 0, nil
- }
-
- // Lift the nil check outside of the loop. enc.decodeMap is directly
- // used later in this function, to let the compiler know that the
- // receiver can't be nil.
- _ = enc.decodeMap
-
- si := 0
- for strconv.IntSize >= 64 && len(src)-si >= 8 && len(dst)-n >= 8 {
- src2 := src[si : si+8]
- if dn, ok := assemble64(
- enc.decodeMap[src2[0]],
- enc.decodeMap[src2[1]],
- enc.decodeMap[src2[2]],
- enc.decodeMap[src2[3]],
- enc.decodeMap[src2[4]],
- enc.decodeMap[src2[5]],
- enc.decodeMap[src2[6]],
- enc.decodeMap[src2[7]],
- ); ok {
- binary.BigEndian.PutUint64(dst[n:], dn)
- n += 6
- si += 8
- } else {
- var ninc int
- si, ninc, err = enc.decodeQuantum(dst[n:], src, si)
- n += ninc
- if err != nil {
- return n, err
- }
- }
- }
-
- for len(src)-si >= 4 && len(dst)-n >= 4 {
- src2 := src[si : si+4]
- if dn, ok := assemble32(
- enc.decodeMap[src2[0]],
- enc.decodeMap[src2[1]],
- enc.decodeMap[src2[2]],
- enc.decodeMap[src2[3]],
- ); ok {
- binary.BigEndian.PutUint32(dst[n:], dn)
- n += 3
- si += 4
- } else {
- var ninc int
- si, ninc, err = enc.decodeQuantum(dst[n:], src, si)
- n += ninc
- if err != nil {
- return n, err
- }
- }
- }
-
- for si < len(src) {
- var ninc int
- si, ninc, err = enc.decodeQuantum(dst[n:], src, si)
- n += ninc
- if err != nil {
- return n, err
- }
- }
- return n, err
-}
-
-// assemble32 assembles 4 base64 digits into 3 bytes.
-// Each digit comes from the decode map, and will be 0xff
-// if it came from an invalid character.
-func assemble32(n1, n2, n3, n4 byte) (dn uint32, ok bool) {
- // Check that all the digits are valid. If any of them was 0xff, their
- // bitwise OR will be 0xff.
- if n1|n2|n3|n4 == 0xff {
- return 0, false
- }
- return uint32(n1)<<26 |
- uint32(n2)<<20 |
- uint32(n3)<<14 |
- uint32(n4)<<8,
- true
-}
-
-// assemble64 assembles 8 base64 digits into 6 bytes.
-// Each digit comes from the decode map, and will be 0xff
-// if it came from an invalid character.
-func assemble64(n1, n2, n3, n4, n5, n6, n7, n8 byte) (dn uint64, ok bool) {
- // Check that all the digits are valid. If any of them was 0xff, their
- // bitwise OR will be 0xff.
- if n1|n2|n3|n4|n5|n6|n7|n8 == 0xff {
- return 0, false
- }
- return uint64(n1)<<58 |
- uint64(n2)<<52 |
- uint64(n3)<<46 |
- uint64(n4)<<40 |
- uint64(n5)<<34 |
- uint64(n6)<<28 |
- uint64(n7)<<22 |
- uint64(n8)<<16,
- true
-}
-
-type newlineFilteringReader struct {
- wrapped io.Reader
-}
-
-func (r *newlineFilteringReader) Read(p []byte) (int, error) {
- n, err := r.wrapped.Read(p)
- for n > 0 {
- offset := 0
- for i, b := range p[:n] {
- if b != '\r' && b != '\n' {
- if i != offset {
- p[offset] = b
- }
- offset++
- }
- }
- if offset > 0 {
- return offset, err
- }
- // Previous buffer entirely whitespace, read again
- n, err = r.wrapped.Read(p)
- }
- return n, err
-}
-
-// NewDecoder constructs a new base64 stream decoder.
-func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
- return &decoder{enc: enc, r: &newlineFilteringReader{r}}
-}
-
-// DecodedLen returns the maximum length in bytes of the decoded data
-// corresponding to n bytes of base64-encoded data.
-func (enc *Encoding) DecodedLen(n int) int {
- if enc.padChar == NoPadding {
- // Unpadded data may end with partial block of 2-3 characters.
- return n * 6 / 8
- }
- // Padded base64 should always be a multiple of 4 characters in length.
- return n / 4 * 3
-}
diff --git a/contrib/go/_std_1.20/src/encoding/base64/ya.make b/contrib/go/_std_1.20/src/encoding/base64/ya.make
deleted file mode 100644
index 86e693fa64..0000000000
--- a/contrib/go/_std_1.20/src/encoding/base64/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- base64.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/encoding/binary/binary.go b/contrib/go/_std_1.20/src/encoding/binary/binary.go
deleted file mode 100644
index 0681511fbb..0000000000
--- a/contrib/go/_std_1.20/src/encoding/binary/binary.go
+++ /dev/null
@@ -1,804 +0,0 @@
-// Copyright 2009 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 binary implements simple translation between numbers and byte
-// sequences and encoding and decoding of varints.
-//
-// Numbers are translated by reading and writing fixed-size values.
-// A fixed-size value is either a fixed-size arithmetic
-// type (bool, int8, uint8, int16, float32, complex64, ...)
-// or an array or struct containing only fixed-size values.
-//
-// The varint functions encode and decode single integer values using
-// a variable-length encoding; smaller values require fewer bytes.
-// For a specification, see
-// https://developers.google.com/protocol-buffers/docs/encoding.
-//
-// This package favors simplicity over efficiency. Clients that require
-// high-performance serialization, especially for large data structures,
-// should look at more advanced solutions such as the encoding/gob
-// package or protocol buffers.
-package binary
-
-import (
- "errors"
- "io"
- "math"
- "reflect"
- "sync"
-)
-
-// A ByteOrder specifies how to convert byte slices into
-// 16-, 32-, or 64-bit unsigned integers.
-type ByteOrder interface {
- Uint16([]byte) uint16
- Uint32([]byte) uint32
- Uint64([]byte) uint64
- PutUint16([]byte, uint16)
- PutUint32([]byte, uint32)
- PutUint64([]byte, uint64)
- String() string
-}
-
-// AppendByteOrder specifies how to append 16-, 32-, or 64-bit unsigned integers
-// into a byte slice.
-type AppendByteOrder interface {
- AppendUint16([]byte, uint16) []byte
- AppendUint32([]byte, uint32) []byte
- AppendUint64([]byte, uint64) []byte
- String() string
-}
-
-// LittleEndian is the little-endian implementation of ByteOrder and AppendByteOrder.
-var LittleEndian littleEndian
-
-// BigEndian is the big-endian implementation of ByteOrder and AppendByteOrder.
-var BigEndian bigEndian
-
-type littleEndian struct{}
-
-func (littleEndian) Uint16(b []byte) uint16 {
- _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
- return uint16(b[0]) | uint16(b[1])<<8
-}
-
-func (littleEndian) PutUint16(b []byte, v uint16) {
- _ = b[1] // early bounds check to guarantee safety of writes below
- b[0] = byte(v)
- b[1] = byte(v >> 8)
-}
-
-func (littleEndian) AppendUint16(b []byte, v uint16) []byte {
- return append(b,
- byte(v),
- byte(v>>8),
- )
-}
-
-func (littleEndian) Uint32(b []byte) uint32 {
- _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
- return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
-}
-
-func (littleEndian) PutUint32(b []byte, v uint32) {
- _ = b[3] // early bounds check to guarantee safety of writes below
- b[0] = byte(v)
- b[1] = byte(v >> 8)
- b[2] = byte(v >> 16)
- b[3] = byte(v >> 24)
-}
-
-func (littleEndian) AppendUint32(b []byte, v uint32) []byte {
- return append(b,
- byte(v),
- byte(v>>8),
- byte(v>>16),
- byte(v>>24),
- )
-}
-
-func (littleEndian) Uint64(b []byte) uint64 {
- _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
- uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
-}
-
-func (littleEndian) PutUint64(b []byte, v uint64) {
- _ = b[7] // early bounds check to guarantee safety of writes below
- b[0] = byte(v)
- b[1] = byte(v >> 8)
- b[2] = byte(v >> 16)
- b[3] = byte(v >> 24)
- b[4] = byte(v >> 32)
- b[5] = byte(v >> 40)
- b[6] = byte(v >> 48)
- b[7] = byte(v >> 56)
-}
-
-func (littleEndian) AppendUint64(b []byte, v uint64) []byte {
- return append(b,
- byte(v),
- byte(v>>8),
- byte(v>>16),
- byte(v>>24),
- byte(v>>32),
- byte(v>>40),
- byte(v>>48),
- byte(v>>56),
- )
-}
-
-func (littleEndian) String() string { return "LittleEndian" }
-
-func (littleEndian) GoString() string { return "binary.LittleEndian" }
-
-type bigEndian struct{}
-
-func (bigEndian) Uint16(b []byte) uint16 {
- _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
- return uint16(b[1]) | uint16(b[0])<<8
-}
-
-func (bigEndian) PutUint16(b []byte, v uint16) {
- _ = b[1] // early bounds check to guarantee safety of writes below
- b[0] = byte(v >> 8)
- b[1] = byte(v)
-}
-
-func (bigEndian) AppendUint16(b []byte, v uint16) []byte {
- return append(b,
- byte(v>>8),
- byte(v),
- )
-}
-
-func (bigEndian) Uint32(b []byte) uint32 {
- _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
- return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
-}
-
-func (bigEndian) PutUint32(b []byte, v uint32) {
- _ = b[3] // early bounds check to guarantee safety of writes below
- b[0] = byte(v >> 24)
- b[1] = byte(v >> 16)
- b[2] = byte(v >> 8)
- b[3] = byte(v)
-}
-
-func (bigEndian) AppendUint32(b []byte, v uint32) []byte {
- return append(b,
- byte(v>>24),
- byte(v>>16),
- byte(v>>8),
- byte(v),
- )
-}
-
-func (bigEndian) Uint64(b []byte) uint64 {
- _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
- uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
-}
-
-func (bigEndian) PutUint64(b []byte, v uint64) {
- _ = b[7] // early bounds check to guarantee safety of writes below
- b[0] = byte(v >> 56)
- b[1] = byte(v >> 48)
- b[2] = byte(v >> 40)
- b[3] = byte(v >> 32)
- b[4] = byte(v >> 24)
- b[5] = byte(v >> 16)
- b[6] = byte(v >> 8)
- b[7] = byte(v)
-}
-
-func (bigEndian) AppendUint64(b []byte, v uint64) []byte {
- return append(b,
- byte(v>>56),
- byte(v>>48),
- byte(v>>40),
- byte(v>>32),
- byte(v>>24),
- byte(v>>16),
- byte(v>>8),
- byte(v),
- )
-}
-
-func (bigEndian) String() string { return "BigEndian" }
-
-func (bigEndian) GoString() string { return "binary.BigEndian" }
-
-// Read reads structured binary data from r into data.
-// Data must be a pointer to a fixed-size value or a slice
-// of fixed-size values.
-// Bytes read from r are decoded using the specified byte order
-// and written to successive fields of the data.
-// When decoding boolean values, a zero byte is decoded as false, and
-// any other non-zero byte is decoded as true.
-// When reading into structs, the field data for fields with
-// blank (_) field names is skipped; i.e., blank field names
-// may be used for padding.
-// When reading into a struct, all non-blank fields must be exported
-// or Read may panic.
-//
-// The error is EOF only if no bytes were read.
-// If an EOF happens after reading some but not all the bytes,
-// Read returns ErrUnexpectedEOF.
-func Read(r io.Reader, order ByteOrder, data any) error {
- // Fast path for basic types and slices.
- if n := intDataSize(data); n != 0 {
- bs := make([]byte, n)
- if _, err := io.ReadFull(r, bs); err != nil {
- return err
- }
- switch data := data.(type) {
- case *bool:
- *data = bs[0] != 0
- case *int8:
- *data = int8(bs[0])
- case *uint8:
- *data = bs[0]
- case *int16:
- *data = int16(order.Uint16(bs))
- case *uint16:
- *data = order.Uint16(bs)
- case *int32:
- *data = int32(order.Uint32(bs))
- case *uint32:
- *data = order.Uint32(bs)
- case *int64:
- *data = int64(order.Uint64(bs))
- case *uint64:
- *data = order.Uint64(bs)
- case *float32:
- *data = math.Float32frombits(order.Uint32(bs))
- case *float64:
- *data = math.Float64frombits(order.Uint64(bs))
- case []bool:
- for i, x := range bs { // Easier to loop over the input for 8-bit values.
- data[i] = x != 0
- }
- case []int8:
- for i, x := range bs {
- data[i] = int8(x)
- }
- case []uint8:
- copy(data, bs)
- case []int16:
- for i := range data {
- data[i] = int16(order.Uint16(bs[2*i:]))
- }
- case []uint16:
- for i := range data {
- data[i] = order.Uint16(bs[2*i:])
- }
- case []int32:
- for i := range data {
- data[i] = int32(order.Uint32(bs[4*i:]))
- }
- case []uint32:
- for i := range data {
- data[i] = order.Uint32(bs[4*i:])
- }
- case []int64:
- for i := range data {
- data[i] = int64(order.Uint64(bs[8*i:]))
- }
- case []uint64:
- for i := range data {
- data[i] = order.Uint64(bs[8*i:])
- }
- case []float32:
- for i := range data {
- data[i] = math.Float32frombits(order.Uint32(bs[4*i:]))
- }
- case []float64:
- for i := range data {
- data[i] = math.Float64frombits(order.Uint64(bs[8*i:]))
- }
- default:
- n = 0 // fast path doesn't apply
- }
- if n != 0 {
- return nil
- }
- }
-
- // Fallback to reflect-based decoding.
- v := reflect.ValueOf(data)
- size := -1
- switch v.Kind() {
- case reflect.Pointer:
- v = v.Elem()
- size = dataSize(v)
- case reflect.Slice:
- size = dataSize(v)
- }
- if size < 0 {
- return errors.New("binary.Read: invalid type " + reflect.TypeOf(data).String())
- }
- d := &decoder{order: order, buf: make([]byte, size)}
- if _, err := io.ReadFull(r, d.buf); err != nil {
- return err
- }
- d.value(v)
- return nil
-}
-
-// Write writes the binary representation of data into w.
-// Data must be a fixed-size value or a slice of fixed-size
-// values, or a pointer to such data.
-// Boolean values encode as one byte: 1 for true, and 0 for false.
-// Bytes written to w are encoded using the specified byte order
-// and read from successive fields of the data.
-// When writing structs, zero values are written for fields
-// with blank (_) field names.
-func Write(w io.Writer, order ByteOrder, data any) error {
- // Fast path for basic types and slices.
- if n := intDataSize(data); n != 0 {
- bs := make([]byte, n)
- switch v := data.(type) {
- case *bool:
- if *v {
- bs[0] = 1
- } else {
- bs[0] = 0
- }
- case bool:
- if v {
- bs[0] = 1
- } else {
- bs[0] = 0
- }
- case []bool:
- for i, x := range v {
- if x {
- bs[i] = 1
- } else {
- bs[i] = 0
- }
- }
- case *int8:
- bs[0] = byte(*v)
- case int8:
- bs[0] = byte(v)
- case []int8:
- for i, x := range v {
- bs[i] = byte(x)
- }
- case *uint8:
- bs[0] = *v
- case uint8:
- bs[0] = v
- case []uint8:
- bs = v
- case *int16:
- order.PutUint16(bs, uint16(*v))
- case int16:
- order.PutUint16(bs, uint16(v))
- case []int16:
- for i, x := range v {
- order.PutUint16(bs[2*i:], uint16(x))
- }
- case *uint16:
- order.PutUint16(bs, *v)
- case uint16:
- order.PutUint16(bs, v)
- case []uint16:
- for i, x := range v {
- order.PutUint16(bs[2*i:], x)
- }
- case *int32:
- order.PutUint32(bs, uint32(*v))
- case int32:
- order.PutUint32(bs, uint32(v))
- case []int32:
- for i, x := range v {
- order.PutUint32(bs[4*i:], uint32(x))
- }
- case *uint32:
- order.PutUint32(bs, *v)
- case uint32:
- order.PutUint32(bs, v)
- case []uint32:
- for i, x := range v {
- order.PutUint32(bs[4*i:], x)
- }
- case *int64:
- order.PutUint64(bs, uint64(*v))
- case int64:
- order.PutUint64(bs, uint64(v))
- case []int64:
- for i, x := range v {
- order.PutUint64(bs[8*i:], uint64(x))
- }
- case *uint64:
- order.PutUint64(bs, *v)
- case uint64:
- order.PutUint64(bs, v)
- case []uint64:
- for i, x := range v {
- order.PutUint64(bs[8*i:], x)
- }
- case *float32:
- order.PutUint32(bs, math.Float32bits(*v))
- case float32:
- order.PutUint32(bs, math.Float32bits(v))
- case []float32:
- for i, x := range v {
- order.PutUint32(bs[4*i:], math.Float32bits(x))
- }
- case *float64:
- order.PutUint64(bs, math.Float64bits(*v))
- case float64:
- order.PutUint64(bs, math.Float64bits(v))
- case []float64:
- for i, x := range v {
- order.PutUint64(bs[8*i:], math.Float64bits(x))
- }
- }
- _, err := w.Write(bs)
- return err
- }
-
- // Fallback to reflect-based encoding.
- v := reflect.Indirect(reflect.ValueOf(data))
- size := dataSize(v)
- if size < 0 {
- return errors.New("binary.Write: invalid type " + reflect.TypeOf(data).String())
- }
- buf := make([]byte, size)
- e := &encoder{order: order, buf: buf}
- e.value(v)
- _, err := w.Write(buf)
- return err
-}
-
-// Size returns how many bytes Write would generate to encode the value v, which
-// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.
-// If v is neither of these, Size returns -1.
-func Size(v any) int {
- return dataSize(reflect.Indirect(reflect.ValueOf(v)))
-}
-
-var structSize sync.Map // map[reflect.Type]int
-
-// dataSize returns the number of bytes the actual data represented by v occupies in memory.
-// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice
-// it returns the length of the slice times the element size and does not count the memory
-// occupied by the header. If the type of v is not acceptable, dataSize returns -1.
-func dataSize(v reflect.Value) int {
- switch v.Kind() {
- case reflect.Slice:
- if s := sizeof(v.Type().Elem()); s >= 0 {
- return s * v.Len()
- }
- return -1
-
- case reflect.Struct:
- t := v.Type()
- if size, ok := structSize.Load(t); ok {
- return size.(int)
- }
- size := sizeof(t)
- structSize.Store(t, size)
- return size
-
- default:
- return sizeof(v.Type())
- }
-}
-
-// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.
-func sizeof(t reflect.Type) int {
- switch t.Kind() {
- case reflect.Array:
- if s := sizeof(t.Elem()); s >= 0 {
- return s * t.Len()
- }
-
- case reflect.Struct:
- sum := 0
- for i, n := 0, t.NumField(); i < n; i++ {
- s := sizeof(t.Field(i).Type)
- if s < 0 {
- return -1
- }
- sum += s
- }
- return sum
-
- case reflect.Bool,
- reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
- reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
- reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
- return int(t.Size())
- }
-
- return -1
-}
-
-type coder struct {
- order ByteOrder
- buf []byte
- offset int
-}
-
-type decoder coder
-type encoder coder
-
-func (d *decoder) bool() bool {
- x := d.buf[d.offset]
- d.offset++
- return x != 0
-}
-
-func (e *encoder) bool(x bool) {
- if x {
- e.buf[e.offset] = 1
- } else {
- e.buf[e.offset] = 0
- }
- e.offset++
-}
-
-func (d *decoder) uint8() uint8 {
- x := d.buf[d.offset]
- d.offset++
- return x
-}
-
-func (e *encoder) uint8(x uint8) {
- e.buf[e.offset] = x
- e.offset++
-}
-
-func (d *decoder) uint16() uint16 {
- x := d.order.Uint16(d.buf[d.offset : d.offset+2])
- d.offset += 2
- return x
-}
-
-func (e *encoder) uint16(x uint16) {
- e.order.PutUint16(e.buf[e.offset:e.offset+2], x)
- e.offset += 2
-}
-
-func (d *decoder) uint32() uint32 {
- x := d.order.Uint32(d.buf[d.offset : d.offset+4])
- d.offset += 4
- return x
-}
-
-func (e *encoder) uint32(x uint32) {
- e.order.PutUint32(e.buf[e.offset:e.offset+4], x)
- e.offset += 4
-}
-
-func (d *decoder) uint64() uint64 {
- x := d.order.Uint64(d.buf[d.offset : d.offset+8])
- d.offset += 8
- return x
-}
-
-func (e *encoder) uint64(x uint64) {
- e.order.PutUint64(e.buf[e.offset:e.offset+8], x)
- e.offset += 8
-}
-
-func (d *decoder) int8() int8 { return int8(d.uint8()) }
-
-func (e *encoder) int8(x int8) { e.uint8(uint8(x)) }
-
-func (d *decoder) int16() int16 { return int16(d.uint16()) }
-
-func (e *encoder) int16(x int16) { e.uint16(uint16(x)) }
-
-func (d *decoder) int32() int32 { return int32(d.uint32()) }
-
-func (e *encoder) int32(x int32) { e.uint32(uint32(x)) }
-
-func (d *decoder) int64() int64 { return int64(d.uint64()) }
-
-func (e *encoder) int64(x int64) { e.uint64(uint64(x)) }
-
-func (d *decoder) value(v reflect.Value) {
- switch v.Kind() {
- case reflect.Array:
- l := v.Len()
- for i := 0; i < l; i++ {
- d.value(v.Index(i))
- }
-
- case reflect.Struct:
- t := v.Type()
- l := v.NumField()
- for i := 0; i < l; i++ {
- // Note: Calling v.CanSet() below is an optimization.
- // It would be sufficient to check the field name,
- // but creating the StructField info for each field is
- // costly (run "go test -bench=ReadStruct" and compare
- // results when making changes to this code).
- if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
- d.value(v)
- } else {
- d.skip(v)
- }
- }
-
- case reflect.Slice:
- l := v.Len()
- for i := 0; i < l; i++ {
- d.value(v.Index(i))
- }
-
- case reflect.Bool:
- v.SetBool(d.bool())
-
- case reflect.Int8:
- v.SetInt(int64(d.int8()))
- case reflect.Int16:
- v.SetInt(int64(d.int16()))
- case reflect.Int32:
- v.SetInt(int64(d.int32()))
- case reflect.Int64:
- v.SetInt(d.int64())
-
- case reflect.Uint8:
- v.SetUint(uint64(d.uint8()))
- case reflect.Uint16:
- v.SetUint(uint64(d.uint16()))
- case reflect.Uint32:
- v.SetUint(uint64(d.uint32()))
- case reflect.Uint64:
- v.SetUint(d.uint64())
-
- case reflect.Float32:
- v.SetFloat(float64(math.Float32frombits(d.uint32())))
- case reflect.Float64:
- v.SetFloat(math.Float64frombits(d.uint64()))
-
- case reflect.Complex64:
- v.SetComplex(complex(
- float64(math.Float32frombits(d.uint32())),
- float64(math.Float32frombits(d.uint32())),
- ))
- case reflect.Complex128:
- v.SetComplex(complex(
- math.Float64frombits(d.uint64()),
- math.Float64frombits(d.uint64()),
- ))
- }
-}
-
-func (e *encoder) value(v reflect.Value) {
- switch v.Kind() {
- case reflect.Array:
- l := v.Len()
- for i := 0; i < l; i++ {
- e.value(v.Index(i))
- }
-
- case reflect.Struct:
- t := v.Type()
- l := v.NumField()
- for i := 0; i < l; i++ {
- // see comment for corresponding code in decoder.value()
- if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
- e.value(v)
- } else {
- e.skip(v)
- }
- }
-
- case reflect.Slice:
- l := v.Len()
- for i := 0; i < l; i++ {
- e.value(v.Index(i))
- }
-
- case reflect.Bool:
- e.bool(v.Bool())
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- switch v.Type().Kind() {
- case reflect.Int8:
- e.int8(int8(v.Int()))
- case reflect.Int16:
- e.int16(int16(v.Int()))
- case reflect.Int32:
- e.int32(int32(v.Int()))
- case reflect.Int64:
- e.int64(v.Int())
- }
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- switch v.Type().Kind() {
- case reflect.Uint8:
- e.uint8(uint8(v.Uint()))
- case reflect.Uint16:
- e.uint16(uint16(v.Uint()))
- case reflect.Uint32:
- e.uint32(uint32(v.Uint()))
- case reflect.Uint64:
- e.uint64(v.Uint())
- }
-
- case reflect.Float32, reflect.Float64:
- switch v.Type().Kind() {
- case reflect.Float32:
- e.uint32(math.Float32bits(float32(v.Float())))
- case reflect.Float64:
- e.uint64(math.Float64bits(v.Float()))
- }
-
- case reflect.Complex64, reflect.Complex128:
- switch v.Type().Kind() {
- case reflect.Complex64:
- x := v.Complex()
- e.uint32(math.Float32bits(float32(real(x))))
- e.uint32(math.Float32bits(float32(imag(x))))
- case reflect.Complex128:
- x := v.Complex()
- e.uint64(math.Float64bits(real(x)))
- e.uint64(math.Float64bits(imag(x)))
- }
- }
-}
-
-func (d *decoder) skip(v reflect.Value) {
- d.offset += dataSize(v)
-}
-
-func (e *encoder) skip(v reflect.Value) {
- n := dataSize(v)
- zero := e.buf[e.offset : e.offset+n]
- for i := range zero {
- zero[i] = 0
- }
- e.offset += n
-}
-
-// intDataSize returns the size of the data required to represent the data when encoded.
-// It returns zero if the type cannot be implemented by the fast path in Read or Write.
-func intDataSize(data any) int {
- switch data := data.(type) {
- case bool, int8, uint8, *bool, *int8, *uint8:
- return 1
- case []bool:
- return len(data)
- case []int8:
- return len(data)
- case []uint8:
- return len(data)
- case int16, uint16, *int16, *uint16:
- return 2
- case []int16:
- return 2 * len(data)
- case []uint16:
- return 2 * len(data)
- case int32, uint32, *int32, *uint32:
- return 4
- case []int32:
- return 4 * len(data)
- case []uint32:
- return 4 * len(data)
- case int64, uint64, *int64, *uint64:
- return 8
- case []int64:
- return 8 * len(data)
- case []uint64:
- return 8 * len(data)
- case float32, *float32:
- return 4
- case float64, *float64:
- return 8
- case []float32:
- return 4 * len(data)
- case []float64:
- return 8 * len(data)
- }
- return 0
-}
diff --git a/contrib/go/_std_1.20/src/encoding/binary/varint.go b/contrib/go/_std_1.20/src/encoding/binary/varint.go
deleted file mode 100644
index 18e1ff1511..0000000000
--- a/contrib/go/_std_1.20/src/encoding/binary/varint.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2011 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 binary
-
-// This file implements "varint" encoding of 64-bit integers.
-// The encoding is:
-// - unsigned integers are serialized 7 bits at a time, starting with the
-// least significant bits
-// - the most significant bit (msb) in each output byte indicates if there
-// is a continuation byte (msb = 1)
-// - signed integers are mapped to unsigned integers using "zig-zag"
-// encoding: Positive values x are written as 2*x + 0, negative values
-// are written as 2*(^x) + 1; that is, negative numbers are complemented
-// and whether to complement is encoded in bit 0.
-//
-// Design note:
-// At most 10 bytes are needed for 64-bit values. The encoding could
-// be more dense: a full 64-bit value needs an extra byte just to hold bit 63.
-// Instead, the msb of the previous byte could be used to hold bit 63 since we
-// know there can't be more than 64 bits. This is a trivial improvement and
-// would reduce the maximum encoding length to 9 bytes. However, it breaks the
-// invariant that the msb is always the "continuation bit" and thus makes the
-// format incompatible with a varint encoding for larger numbers (say 128-bit).
-
-import (
- "errors"
- "io"
-)
-
-// MaxVarintLenN is the maximum length of a varint-encoded N-bit integer.
-const (
- MaxVarintLen16 = 3
- MaxVarintLen32 = 5
- MaxVarintLen64 = 10
-)
-
-// AppendUvarint appends the varint-encoded form of x,
-// as generated by PutUvarint, to buf and returns the extended buffer.
-func AppendUvarint(buf []byte, x uint64) []byte {
- for x >= 0x80 {
- buf = append(buf, byte(x)|0x80)
- x >>= 7
- }
- return append(buf, byte(x))
-}
-
-// PutUvarint encodes a uint64 into buf and returns the number of bytes written.
-// If the buffer is too small, PutUvarint will panic.
-func PutUvarint(buf []byte, x uint64) int {
- i := 0
- for x >= 0x80 {
- buf[i] = byte(x) | 0x80
- x >>= 7
- i++
- }
- buf[i] = byte(x)
- return i + 1
-}
-
-// Uvarint decodes a uint64 from buf and returns that value and the
-// number of bytes read (> 0). If an error occurred, the value is 0
-// and the number of bytes n is <= 0 meaning:
-//
-// n == 0: buf too small
-// n < 0: value larger than 64 bits (overflow)
-// and -n is the number of bytes read
-func Uvarint(buf []byte) (uint64, int) {
- var x uint64
- var s uint
- for i, b := range buf {
- if i == MaxVarintLen64 {
- // Catch byte reads past MaxVarintLen64.
- // See issue https://golang.org/issues/41185
- return 0, -(i + 1) // overflow
- }
- if b < 0x80 {
- if i == MaxVarintLen64-1 && b > 1 {
- return 0, -(i + 1) // overflow
- }
- return x | uint64(b)<<s, i + 1
- }
- x |= uint64(b&0x7f) << s
- s += 7
- }
- return 0, 0
-}
-
-// AppendVarint appends the varint-encoded form of x,
-// as generated by PutVarint, to buf and returns the extended buffer.
-func AppendVarint(buf []byte, x int64) []byte {
- ux := uint64(x) << 1
- if x < 0 {
- ux = ^ux
- }
- return AppendUvarint(buf, ux)
-}
-
-// PutVarint encodes an int64 into buf and returns the number of bytes written.
-// If the buffer is too small, PutVarint will panic.
-func PutVarint(buf []byte, x int64) int {
- ux := uint64(x) << 1
- if x < 0 {
- ux = ^ux
- }
- return PutUvarint(buf, ux)
-}
-
-// Varint decodes an int64 from buf and returns that value and the
-// number of bytes read (> 0). If an error occurred, the value is 0
-// and the number of bytes n is <= 0 with the following meaning:
-//
-// n == 0: buf too small
-// n < 0: value larger than 64 bits (overflow)
-// and -n is the number of bytes read
-func Varint(buf []byte) (int64, int) {
- ux, n := Uvarint(buf) // ok to continue in presence of error
- x := int64(ux >> 1)
- if ux&1 != 0 {
- x = ^x
- }
- return x, n
-}
-
-var overflow = errors.New("binary: varint overflows a 64-bit integer")
-
-// ReadUvarint reads an encoded unsigned integer from r and returns it as a uint64.
-// The error is EOF only if no bytes were read.
-// If an EOF happens after reading some but not all the bytes,
-// ReadUvarint returns io.ErrUnexpectedEOF.
-func ReadUvarint(r io.ByteReader) (uint64, error) {
- var x uint64
- var s uint
- for i := 0; i < MaxVarintLen64; i++ {
- b, err := r.ReadByte()
- if err != nil {
- if i > 0 && err == io.EOF {
- err = io.ErrUnexpectedEOF
- }
- return x, err
- }
- if b < 0x80 {
- if i == MaxVarintLen64-1 && b > 1 {
- return x, overflow
- }
- return x | uint64(b)<<s, nil
- }
- x |= uint64(b&0x7f) << s
- s += 7
- }
- return x, overflow
-}
-
-// ReadVarint reads an encoded signed integer from r and returns it as an int64.
-// The error is EOF only if no bytes were read.
-// If an EOF happens after reading some but not all the bytes,
-// ReadVarint returns io.ErrUnexpectedEOF.
-func ReadVarint(r io.ByteReader) (int64, error) {
- ux, err := ReadUvarint(r) // ok to continue in presence of error
- x := int64(ux >> 1)
- if ux&1 != 0 {
- x = ^x
- }
- return x, err
-}
diff --git a/contrib/go/_std_1.20/src/encoding/binary/ya.make b/contrib/go/_std_1.20/src/encoding/binary/ya.make
deleted file mode 100644
index 6ce3254ed9..0000000000
--- a/contrib/go/_std_1.20/src/encoding/binary/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- binary.go
- varint.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/encoding/csv/reader.go b/contrib/go/_std_1.20/src/encoding/csv/reader.go
deleted file mode 100644
index b83208eb3a..0000000000
--- a/contrib/go/_std_1.20/src/encoding/csv/reader.go
+++ /dev/null
@@ -1,465 +0,0 @@
-// Copyright 2011 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 csv reads and writes comma-separated values (CSV) files.
-// There are many kinds of CSV files; this package supports the format
-// described in RFC 4180.
-//
-// A csv file contains zero or more records of one or more fields per record.
-// Each record is separated by the newline character. The final record may
-// optionally be followed by a newline character.
-//
-// field1,field2,field3
-//
-// White space is considered part of a field.
-//
-// Carriage returns before newline characters are silently removed.
-//
-// Blank lines are ignored. A line with only whitespace characters (excluding
-// the ending newline character) is not considered a blank line.
-//
-// Fields which start and stop with the quote character " are called
-// quoted-fields. The beginning and ending quote are not part of the
-// field.
-//
-// The source:
-//
-// normal string,"quoted-field"
-//
-// results in the fields
-//
-// {`normal string`, `quoted-field`}
-//
-// Within a quoted-field a quote character followed by a second quote
-// character is considered a single quote.
-//
-// "the ""word"" is true","a ""quoted-field"""
-//
-// results in
-//
-// {`the "word" is true`, `a "quoted-field"`}
-//
-// Newlines and commas may be included in a quoted-field
-//
-// "Multi-line
-// field","comma is ,"
-//
-// results in
-//
-// {`Multi-line
-// field`, `comma is ,`}
-package csv
-
-import (
- "bufio"
- "bytes"
- "errors"
- "fmt"
- "io"
- "unicode"
- "unicode/utf8"
-)
-
-// A ParseError is returned for parsing errors.
-// Line numbers are 1-indexed and columns are 0-indexed.
-type ParseError struct {
- StartLine int // Line where the record starts
- Line int // Line where the error occurred
- Column int // Column (1-based byte index) where the error occurred
- Err error // The actual error
-}
-
-func (e *ParseError) Error() string {
- if e.Err == ErrFieldCount {
- return fmt.Sprintf("record on line %d: %v", e.Line, e.Err)
- }
- if e.StartLine != e.Line {
- return fmt.Sprintf("record on line %d; parse error on line %d, column %d: %v", e.StartLine, e.Line, e.Column, e.Err)
- }
- return fmt.Sprintf("parse error on line %d, column %d: %v", e.Line, e.Column, e.Err)
-}
-
-func (e *ParseError) Unwrap() error { return e.Err }
-
-// These are the errors that can be returned in ParseError.Err.
-var (
- ErrBareQuote = errors.New("bare \" in non-quoted-field")
- ErrQuote = errors.New("extraneous or missing \" in quoted-field")
- ErrFieldCount = errors.New("wrong number of fields")
-
- // Deprecated: ErrTrailingComma is no longer used.
- ErrTrailingComma = errors.New("extra delimiter at end of line")
-)
-
-var errInvalidDelim = errors.New("csv: invalid field or comment delimiter")
-
-func validDelim(r rune) bool {
- return r != 0 && r != '"' && r != '\r' && r != '\n' && utf8.ValidRune(r) && r != utf8.RuneError
-}
-
-// A Reader reads records from a CSV-encoded file.
-//
-// As returned by NewReader, a Reader expects input conforming to RFC 4180.
-// The exported fields can be changed to customize the details before the
-// first call to Read or ReadAll.
-//
-// The Reader converts all \r\n sequences in its input to plain \n,
-// including in multiline field values, so that the returned data does
-// not depend on which line-ending convention an input file uses.
-type Reader struct {
- // Comma is the field delimiter.
- // It is set to comma (',') by NewReader.
- // Comma must be a valid rune and must not be \r, \n,
- // or the Unicode replacement character (0xFFFD).
- Comma rune
-
- // Comment, if not 0, is the comment character. Lines beginning with the
- // Comment character without preceding whitespace are ignored.
- // With leading whitespace the Comment character becomes part of the
- // field, even if TrimLeadingSpace is true.
- // Comment must be a valid rune and must not be \r, \n,
- // or the Unicode replacement character (0xFFFD).
- // It must also not be equal to Comma.
- Comment rune
-
- // FieldsPerRecord is the number of expected fields per record.
- // If FieldsPerRecord is positive, Read requires each record to
- // have the given number of fields. If FieldsPerRecord is 0, Read sets it to
- // the number of fields in the first record, so that future records must
- // have the same field count. If FieldsPerRecord is negative, no check is
- // made and records may have a variable number of fields.
- FieldsPerRecord int
-
- // If LazyQuotes is true, a quote may appear in an unquoted field and a
- // non-doubled quote may appear in a quoted field.
- LazyQuotes bool
-
- // If TrimLeadingSpace is true, leading white space in a field is ignored.
- // This is done even if the field delimiter, Comma, is white space.
- TrimLeadingSpace bool
-
- // ReuseRecord controls whether calls to Read may return a slice sharing
- // the backing array of the previous call's returned slice for performance.
- // By default, each call to Read returns newly allocated memory owned by the caller.
- ReuseRecord bool
-
- // Deprecated: TrailingComma is no longer used.
- TrailingComma bool
-
- r *bufio.Reader
-
- // numLine is the current line being read in the CSV file.
- numLine int
-
- // offset is the input stream byte offset of the current reader position.
- offset int64
-
- // rawBuffer is a line buffer only used by the readLine method.
- rawBuffer []byte
-
- // recordBuffer holds the unescaped fields, one after another.
- // The fields can be accessed by using the indexes in fieldIndexes.
- // E.g., For the row `a,"b","c""d",e`, recordBuffer will contain `abc"de`
- // and fieldIndexes will contain the indexes [1, 2, 5, 6].
- recordBuffer []byte
-
- // fieldIndexes is an index of fields inside recordBuffer.
- // The i'th field ends at offset fieldIndexes[i] in recordBuffer.
- fieldIndexes []int
-
- // fieldPositions is an index of field positions for the
- // last record returned by Read.
- fieldPositions []position
-
- // lastRecord is a record cache and only used when ReuseRecord == true.
- lastRecord []string
-}
-
-// NewReader returns a new Reader that reads from r.
-func NewReader(r io.Reader) *Reader {
- return &Reader{
- Comma: ',',
- r: bufio.NewReader(r),
- }
-}
-
-// Read reads one record (a slice of fields) from r.
-// If the record has an unexpected number of fields,
-// Read returns the record along with the error ErrFieldCount.
-// Except for that case, Read always returns either a non-nil
-// record or a non-nil error, but not both.
-// If there is no data left to be read, Read returns nil, io.EOF.
-// If ReuseRecord is true, the returned slice may be shared
-// between multiple calls to Read.
-func (r *Reader) Read() (record []string, err error) {
- if r.ReuseRecord {
- record, err = r.readRecord(r.lastRecord)
- r.lastRecord = record
- } else {
- record, err = r.readRecord(nil)
- }
- return record, err
-}
-
-// FieldPos returns the line and column corresponding to
-// the start of the field with the given index in the slice most recently
-// returned by Read. Numbering of lines and columns starts at 1;
-// columns are counted in bytes, not runes.
-//
-// If this is called with an out-of-bounds index, it panics.
-func (r *Reader) FieldPos(field int) (line, column int) {
- if field < 0 || field >= len(r.fieldPositions) {
- panic("out of range index passed to FieldPos")
- }
- p := &r.fieldPositions[field]
- return p.line, p.col
-}
-
-// InputOffset returns the input stream byte offset of the current reader
-// position. The offset gives the location of the end of the most recently
-// read row and the beginning of the next row.
-func (r *Reader) InputOffset() int64 {
- return r.offset
-}
-
-// pos holds the position of a field in the current line.
-type position struct {
- line, col int
-}
-
-// ReadAll reads all the remaining records from r.
-// Each record is a slice of fields.
-// A successful call returns err == nil, not err == io.EOF. Because ReadAll is
-// defined to read until EOF, it does not treat end of file as an error to be
-// reported.
-func (r *Reader) ReadAll() (records [][]string, err error) {
- for {
- record, err := r.readRecord(nil)
- if err == io.EOF {
- return records, nil
- }
- if err != nil {
- return nil, err
- }
- records = append(records, record)
- }
-}
-
-// readLine reads the next line (with the trailing endline).
-// If EOF is hit without a trailing endline, it will be omitted.
-// If some bytes were read, then the error is never io.EOF.
-// The result is only valid until the next call to readLine.
-func (r *Reader) readLine() ([]byte, error) {
- line, err := r.r.ReadSlice('\n')
- if err == bufio.ErrBufferFull {
- r.rawBuffer = append(r.rawBuffer[:0], line...)
- for err == bufio.ErrBufferFull {
- line, err = r.r.ReadSlice('\n')
- r.rawBuffer = append(r.rawBuffer, line...)
- }
- line = r.rawBuffer
- }
- readSize := len(line)
- if readSize > 0 && err == io.EOF {
- err = nil
- // For backwards compatibility, drop trailing \r before EOF.
- if line[readSize-1] == '\r' {
- line = line[:readSize-1]
- }
- }
- r.numLine++
- r.offset += int64(readSize)
- // Normalize \r\n to \n on all input lines.
- if n := len(line); n >= 2 && line[n-2] == '\r' && line[n-1] == '\n' {
- line[n-2] = '\n'
- line = line[:n-1]
- }
- return line, err
-}
-
-// lengthNL reports the number of bytes for the trailing \n.
-func lengthNL(b []byte) int {
- if len(b) > 0 && b[len(b)-1] == '\n' {
- return 1
- }
- return 0
-}
-
-// nextRune returns the next rune in b or utf8.RuneError.
-func nextRune(b []byte) rune {
- r, _ := utf8.DecodeRune(b)
- return r
-}
-
-func (r *Reader) readRecord(dst []string) ([]string, error) {
- if r.Comma == r.Comment || !validDelim(r.Comma) || (r.Comment != 0 && !validDelim(r.Comment)) {
- return nil, errInvalidDelim
- }
-
- // Read line (automatically skipping past empty lines and any comments).
- var line []byte
- var errRead error
- for errRead == nil {
- line, errRead = r.readLine()
- if r.Comment != 0 && nextRune(line) == r.Comment {
- line = nil
- continue // Skip comment lines
- }
- if errRead == nil && len(line) == lengthNL(line) {
- line = nil
- continue // Skip empty lines
- }
- break
- }
- if errRead == io.EOF {
- return nil, errRead
- }
-
- // Parse each field in the record.
- var err error
- const quoteLen = len(`"`)
- commaLen := utf8.RuneLen(r.Comma)
- recLine := r.numLine // Starting line for record
- r.recordBuffer = r.recordBuffer[:0]
- r.fieldIndexes = r.fieldIndexes[:0]
- r.fieldPositions = r.fieldPositions[:0]
- pos := position{line: r.numLine, col: 1}
-parseField:
- for {
- if r.TrimLeadingSpace {
- i := bytes.IndexFunc(line, func(r rune) bool {
- return !unicode.IsSpace(r)
- })
- if i < 0 {
- i = len(line)
- pos.col -= lengthNL(line)
- }
- line = line[i:]
- pos.col += i
- }
- if len(line) == 0 || line[0] != '"' {
- // Non-quoted string field
- i := bytes.IndexRune(line, r.Comma)
- field := line
- if i >= 0 {
- field = field[:i]
- } else {
- field = field[:len(field)-lengthNL(field)]
- }
- // Check to make sure a quote does not appear in field.
- if !r.LazyQuotes {
- if j := bytes.IndexByte(field, '"'); j >= 0 {
- col := pos.col + j
- err = &ParseError{StartLine: recLine, Line: r.numLine, Column: col, Err: ErrBareQuote}
- break parseField
- }
- }
- r.recordBuffer = append(r.recordBuffer, field...)
- r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
- r.fieldPositions = append(r.fieldPositions, pos)
- if i >= 0 {
- line = line[i+commaLen:]
- pos.col += i + commaLen
- continue parseField
- }
- break parseField
- } else {
- // Quoted string field
- fieldPos := pos
- line = line[quoteLen:]
- pos.col += quoteLen
- for {
- i := bytes.IndexByte(line, '"')
- if i >= 0 {
- // Hit next quote.
- r.recordBuffer = append(r.recordBuffer, line[:i]...)
- line = line[i+quoteLen:]
- pos.col += i + quoteLen
- switch rn := nextRune(line); {
- case rn == '"':
- // `""` sequence (append quote).
- r.recordBuffer = append(r.recordBuffer, '"')
- line = line[quoteLen:]
- pos.col += quoteLen
- case rn == r.Comma:
- // `",` sequence (end of field).
- line = line[commaLen:]
- pos.col += commaLen
- r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
- r.fieldPositions = append(r.fieldPositions, fieldPos)
- continue parseField
- case lengthNL(line) == len(line):
- // `"\n` sequence (end of line).
- r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
- r.fieldPositions = append(r.fieldPositions, fieldPos)
- break parseField
- case r.LazyQuotes:
- // `"` sequence (bare quote).
- r.recordBuffer = append(r.recordBuffer, '"')
- default:
- // `"*` sequence (invalid non-escaped quote).
- err = &ParseError{StartLine: recLine, Line: r.numLine, Column: pos.col - quoteLen, Err: ErrQuote}
- break parseField
- }
- } else if len(line) > 0 {
- // Hit end of line (copy all data so far).
- r.recordBuffer = append(r.recordBuffer, line...)
- if errRead != nil {
- break parseField
- }
- pos.col += len(line)
- line, errRead = r.readLine()
- if len(line) > 0 {
- pos.line++
- pos.col = 1
- }
- if errRead == io.EOF {
- errRead = nil
- }
- } else {
- // Abrupt end of file (EOF or error).
- if !r.LazyQuotes && errRead == nil {
- err = &ParseError{StartLine: recLine, Line: pos.line, Column: pos.col, Err: ErrQuote}
- break parseField
- }
- r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
- r.fieldPositions = append(r.fieldPositions, fieldPos)
- break parseField
- }
- }
- }
- }
- if err == nil {
- err = errRead
- }
-
- // Create a single string and create slices out of it.
- // This pins the memory of the fields together, but allocates once.
- str := string(r.recordBuffer) // Convert to string once to batch allocations
- dst = dst[:0]
- if cap(dst) < len(r.fieldIndexes) {
- dst = make([]string, len(r.fieldIndexes))
- }
- dst = dst[:len(r.fieldIndexes)]
- var preIdx int
- for i, idx := range r.fieldIndexes {
- dst[i] = str[preIdx:idx]
- preIdx = idx
- }
-
- // Check or update the expected fields per record.
- if r.FieldsPerRecord > 0 {
- if len(dst) != r.FieldsPerRecord && err == nil {
- err = &ParseError{
- StartLine: recLine,
- Line: recLine,
- Column: 1,
- Err: ErrFieldCount,
- }
- }
- } else if r.FieldsPerRecord == 0 {
- r.FieldsPerRecord = len(dst)
- }
- return dst, err
-}
diff --git a/contrib/go/_std_1.20/src/encoding/csv/ya.make b/contrib/go/_std_1.20/src/encoding/csv/ya.make
deleted file mode 100644
index 262cbbb45f..0000000000
--- a/contrib/go/_std_1.20/src/encoding/csv/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- reader.go
- writer.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/encoding/encoding.go b/contrib/go/_std_1.20/src/encoding/encoding.go
deleted file mode 100644
index cc5a536996..0000000000
--- a/contrib/go/_std_1.20/src/encoding/encoding.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2013 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 encoding defines interfaces shared by other packages that
-// convert data to and from byte-level and textual representations.
-// Packages that check for these interfaces include encoding/gob,
-// encoding/json, and encoding/xml. As a result, implementing an
-// interface once can make a type useful in multiple encodings.
-// Standard types that implement these interfaces include time.Time and net.IP.
-// The interfaces come in pairs that produce and consume encoded data.
-package encoding
-
-// BinaryMarshaler is the interface implemented by an object that can
-// marshal itself into a binary form.
-//
-// MarshalBinary encodes the receiver into a binary form and returns the result.
-type BinaryMarshaler interface {
- MarshalBinary() (data []byte, err error)
-}
-
-// BinaryUnmarshaler is the interface implemented by an object that can
-// unmarshal a binary representation of itself.
-//
-// UnmarshalBinary must be able to decode the form generated by MarshalBinary.
-// UnmarshalBinary must copy the data if it wishes to retain the data
-// after returning.
-type BinaryUnmarshaler interface {
- UnmarshalBinary(data []byte) error
-}
-
-// TextMarshaler is the interface implemented by an object that can
-// marshal itself into a textual form.
-//
-// MarshalText encodes the receiver into UTF-8-encoded text and returns the result.
-type TextMarshaler interface {
- MarshalText() (text []byte, err error)
-}
-
-// TextUnmarshaler is the interface implemented by an object that can
-// unmarshal a textual representation of itself.
-//
-// UnmarshalText must be able to decode the form generated by MarshalText.
-// UnmarshalText must copy the text if it wishes to retain the text
-// after returning.
-type TextUnmarshaler interface {
- UnmarshalText(text []byte) error
-}
diff --git a/contrib/go/_std_1.20/src/encoding/gob/dec_helpers.go b/contrib/go/_std_1.20/src/encoding/gob/dec_helpers.go
deleted file mode 100644
index a09ac8fc1a..0000000000
--- a/contrib/go/_std_1.20/src/encoding/gob/dec_helpers.go
+++ /dev/null
@@ -1,544 +0,0 @@
-// Code generated by go run decgen.go -output dec_helpers.go; DO NOT EDIT.
-
-// Copyright 2014 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 gob
-
-import (
- "math"
- "reflect"
-)
-
-var decArrayHelper = map[reflect.Kind]decHelper{
- reflect.Bool: decBoolArray,
- reflect.Complex64: decComplex64Array,
- reflect.Complex128: decComplex128Array,
- reflect.Float32: decFloat32Array,
- reflect.Float64: decFloat64Array,
- reflect.Int: decIntArray,
- reflect.Int16: decInt16Array,
- reflect.Int32: decInt32Array,
- reflect.Int64: decInt64Array,
- reflect.Int8: decInt8Array,
- reflect.String: decStringArray,
- reflect.Uint: decUintArray,
- reflect.Uint16: decUint16Array,
- reflect.Uint32: decUint32Array,
- reflect.Uint64: decUint64Array,
- reflect.Uintptr: decUintptrArray,
-}
-
-var decSliceHelper = map[reflect.Kind]decHelper{
- reflect.Bool: decBoolSlice,
- reflect.Complex64: decComplex64Slice,
- reflect.Complex128: decComplex128Slice,
- reflect.Float32: decFloat32Slice,
- reflect.Float64: decFloat64Slice,
- reflect.Int: decIntSlice,
- reflect.Int16: decInt16Slice,
- reflect.Int32: decInt32Slice,
- reflect.Int64: decInt64Slice,
- reflect.Int8: decInt8Slice,
- reflect.String: decStringSlice,
- reflect.Uint: decUintSlice,
- reflect.Uint16: decUint16Slice,
- reflect.Uint32: decUint32Slice,
- reflect.Uint64: decUint64Slice,
- reflect.Uintptr: decUintptrSlice,
-}
-
-func decBoolArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decBoolSlice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decBoolSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]bool)
- if !ok {
- // It is kind bool but not type bool. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding bool array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- slice[i] = state.decodeUint() != 0
- }
- return true
-}
-
-func decComplex64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decComplex64Slice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decComplex64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]complex64)
- if !ok {
- // It is kind complex64 but not type complex64. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding complex64 array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- real := float32FromBits(state.decodeUint(), ovfl)
- imag := float32FromBits(state.decodeUint(), ovfl)
- slice[i] = complex(float32(real), float32(imag))
- }
- return true
-}
-
-func decComplex128Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decComplex128Slice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decComplex128Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]complex128)
- if !ok {
- // It is kind complex128 but not type complex128. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding complex128 array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- real := float64FromBits(state.decodeUint())
- imag := float64FromBits(state.decodeUint())
- slice[i] = complex(real, imag)
- }
- return true
-}
-
-func decFloat32Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decFloat32Slice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decFloat32Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]float32)
- if !ok {
- // It is kind float32 but not type float32. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding float32 array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- slice[i] = float32(float32FromBits(state.decodeUint(), ovfl))
- }
- return true
-}
-
-func decFloat64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decFloat64Slice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decFloat64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]float64)
- if !ok {
- // It is kind float64 but not type float64. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding float64 array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- slice[i] = float64FromBits(state.decodeUint())
- }
- return true
-}
-
-func decIntArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decIntSlice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decIntSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]int)
- if !ok {
- // It is kind int but not type int. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding int array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- x := state.decodeInt()
- // MinInt and MaxInt
- if x < ^int64(^uint(0)>>1) || int64(^uint(0)>>1) < x {
- error_(ovfl)
- }
- slice[i] = int(x)
- }
- return true
-}
-
-func decInt16Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decInt16Slice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decInt16Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]int16)
- if !ok {
- // It is kind int16 but not type int16. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding int16 array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- x := state.decodeInt()
- if x < math.MinInt16 || math.MaxInt16 < x {
- error_(ovfl)
- }
- slice[i] = int16(x)
- }
- return true
-}
-
-func decInt32Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decInt32Slice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decInt32Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]int32)
- if !ok {
- // It is kind int32 but not type int32. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding int32 array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- x := state.decodeInt()
- if x < math.MinInt32 || math.MaxInt32 < x {
- error_(ovfl)
- }
- slice[i] = int32(x)
- }
- return true
-}
-
-func decInt64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decInt64Slice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decInt64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]int64)
- if !ok {
- // It is kind int64 but not type int64. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding int64 array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- slice[i] = state.decodeInt()
- }
- return true
-}
-
-func decInt8Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decInt8Slice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decInt8Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]int8)
- if !ok {
- // It is kind int8 but not type int8. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding int8 array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- x := state.decodeInt()
- if x < math.MinInt8 || math.MaxInt8 < x {
- error_(ovfl)
- }
- slice[i] = int8(x)
- }
- return true
-}
-
-func decStringArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decStringSlice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decStringSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]string)
- if !ok {
- // It is kind string but not type string. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding string array or slice: length exceeds input size (%d elements)", length)
- }
- u := state.decodeUint()
- n := int(u)
- if n < 0 || uint64(n) != u || n > state.b.Len() {
- errorf("length of string exceeds input size (%d bytes)", u)
- }
- if n > state.b.Len() {
- errorf("string data too long for buffer: %d", n)
- }
- // Read the data.
- data := state.b.Bytes()
- if len(data) < n {
- errorf("invalid string length %d: exceeds input size %d", n, len(data))
- }
- slice[i] = string(data[:n])
- state.b.Drop(n)
- }
- return true
-}
-
-func decUintArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decUintSlice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decUintSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]uint)
- if !ok {
- // It is kind uint but not type uint. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding uint array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- x := state.decodeUint()
- /*TODO if math.MaxUint32 < x {
- error_(ovfl)
- }*/
- slice[i] = uint(x)
- }
- return true
-}
-
-func decUint16Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decUint16Slice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decUint16Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]uint16)
- if !ok {
- // It is kind uint16 but not type uint16. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding uint16 array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- x := state.decodeUint()
- if math.MaxUint16 < x {
- error_(ovfl)
- }
- slice[i] = uint16(x)
- }
- return true
-}
-
-func decUint32Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decUint32Slice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decUint32Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]uint32)
- if !ok {
- // It is kind uint32 but not type uint32. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding uint32 array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- x := state.decodeUint()
- if math.MaxUint32 < x {
- error_(ovfl)
- }
- slice[i] = uint32(x)
- }
- return true
-}
-
-func decUint64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decUint64Slice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decUint64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]uint64)
- if !ok {
- // It is kind uint64 but not type uint64. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding uint64 array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- slice[i] = state.decodeUint()
- }
- return true
-}
-
-func decUintptrArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- // Can only slice if it is addressable.
- if !v.CanAddr() {
- return false
- }
- return decUintptrSlice(state, v.Slice(0, v.Len()), length, ovfl)
-}
-
-func decUintptrSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
- slice, ok := v.Interface().([]uintptr)
- if !ok {
- // It is kind uintptr but not type uintptr. TODO: We can handle this unsafely.
- return false
- }
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding uintptr array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= len(slice) {
- // This is a slice that we only partially allocated.
- growSlice(v, &slice, length)
- }
- x := state.decodeUint()
- if uint64(^uintptr(0)) < x {
- error_(ovfl)
- }
- slice[i] = uintptr(x)
- }
- return true
-}
-
-// growSlice is called for a slice that we only partially allocated,
-// to grow it up to length.
-func growSlice[E any](v reflect.Value, ps *[]E, length int) {
- var zero E
- s := *ps
- s = append(s, zero)
- cp := cap(s)
- if cp > length {
- cp = length
- }
- s = s[:cp]
- v.Set(reflect.ValueOf(s))
- *ps = s
-}
diff --git a/contrib/go/_std_1.20/src/encoding/gob/decode.go b/contrib/go/_std_1.20/src/encoding/gob/decode.go
deleted file mode 100644
index f46a3916b5..0000000000
--- a/contrib/go/_std_1.20/src/encoding/gob/decode.go
+++ /dev/null
@@ -1,1308 +0,0 @@
-// Copyright 2009 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.
-
-//go:generate go run decgen.go -output dec_helpers.go
-
-package gob
-
-import (
- "encoding"
- "errors"
- "internal/saferio"
- "io"
- "math"
- "math/bits"
- "reflect"
-)
-
-var (
- errBadUint = errors.New("gob: encoded unsigned integer out of range")
- errBadType = errors.New("gob: unknown type id or corrupted data")
- errRange = errors.New("gob: bad data: field numbers out of bounds")
-)
-
-type decHelper func(state *decoderState, v reflect.Value, length int, ovfl error) bool
-
-// decoderState is the execution state of an instance of the decoder. A new state
-// is created for nested objects.
-type decoderState struct {
- dec *Decoder
- // The buffer is stored with an extra indirection because it may be replaced
- // if we load a type during decode (when reading an interface value).
- b *decBuffer
- fieldnum int // the last field number read.
- next *decoderState // for free list
-}
-
-// decBuffer is an extremely simple, fast implementation of a read-only byte buffer.
-// It is initialized by calling Size and then copying the data into the slice returned by Bytes().
-type decBuffer struct {
- data []byte
- offset int // Read offset.
-}
-
-func (d *decBuffer) Read(p []byte) (int, error) {
- n := copy(p, d.data[d.offset:])
- if n == 0 && len(p) != 0 {
- return 0, io.EOF
- }
- d.offset += n
- return n, nil
-}
-
-func (d *decBuffer) Drop(n int) {
- if n > d.Len() {
- panic("drop")
- }
- d.offset += n
-}
-
-func (d *decBuffer) ReadByte() (byte, error) {
- if d.offset >= len(d.data) {
- return 0, io.EOF
- }
- c := d.data[d.offset]
- d.offset++
- return c, nil
-}
-
-func (d *decBuffer) Len() int {
- return len(d.data) - d.offset
-}
-
-func (d *decBuffer) Bytes() []byte {
- return d.data[d.offset:]
-}
-
-// SetBytes sets the buffer to the bytes, discarding any existing data.
-func (d *decBuffer) SetBytes(data []byte) {
- d.data = data
- d.offset = 0
-}
-
-func (d *decBuffer) Reset() {
- d.data = d.data[0:0]
- d.offset = 0
-}
-
-// We pass the bytes.Buffer separately for easier testing of the infrastructure
-// without requiring a full Decoder.
-func (dec *Decoder) newDecoderState(buf *decBuffer) *decoderState {
- d := dec.freeList
- if d == nil {
- d = new(decoderState)
- d.dec = dec
- } else {
- dec.freeList = d.next
- }
- d.b = buf
- return d
-}
-
-func (dec *Decoder) freeDecoderState(d *decoderState) {
- d.next = dec.freeList
- dec.freeList = d
-}
-
-func overflow(name string) error {
- return errors.New(`value for "` + name + `" out of range`)
-}
-
-// decodeUintReader reads an encoded unsigned integer from an io.Reader.
-// Used only by the Decoder to read the message length.
-func decodeUintReader(r io.Reader, buf []byte) (x uint64, width int, err error) {
- width = 1
- n, err := io.ReadFull(r, buf[0:width])
- if n == 0 {
- return
- }
- b := buf[0]
- if b <= 0x7f {
- return uint64(b), width, nil
- }
- n = -int(int8(b))
- if n > uint64Size {
- err = errBadUint
- return
- }
- width, err = io.ReadFull(r, buf[0:n])
- if err != nil {
- if err == io.EOF {
- err = io.ErrUnexpectedEOF
- }
- return
- }
- // Could check that the high byte is zero but it's not worth it.
- for _, b := range buf[0:width] {
- x = x<<8 | uint64(b)
- }
- width++ // +1 for length byte
- return
-}
-
-// decodeUint reads an encoded unsigned integer from state.r.
-// Does not check for overflow.
-func (state *decoderState) decodeUint() (x uint64) {
- b, err := state.b.ReadByte()
- if err != nil {
- error_(err)
- }
- if b <= 0x7f {
- return uint64(b)
- }
- n := -int(int8(b))
- if n > uint64Size {
- error_(errBadUint)
- }
- buf := state.b.Bytes()
- if len(buf) < n {
- errorf("invalid uint data length %d: exceeds input size %d", n, len(buf))
- }
- // Don't need to check error; it's safe to loop regardless.
- // Could check that the high byte is zero but it's not worth it.
- for _, b := range buf[0:n] {
- x = x<<8 | uint64(b)
- }
- state.b.Drop(n)
- return x
-}
-
-// decodeInt reads an encoded signed integer from state.r.
-// Does not check for overflow.
-func (state *decoderState) decodeInt() int64 {
- x := state.decodeUint()
- if x&1 != 0 {
- return ^int64(x >> 1)
- }
- return int64(x >> 1)
-}
-
-// getLength decodes the next uint and makes sure it is a possible
-// size for a data item that follows, which means it must fit in a
-// non-negative int and fit in the buffer.
-func (state *decoderState) getLength() (int, bool) {
- n := int(state.decodeUint())
- if n < 0 || state.b.Len() < n || tooBig <= n {
- return 0, false
- }
- return n, true
-}
-
-// decOp is the signature of a decoding operator for a given type.
-type decOp func(i *decInstr, state *decoderState, v reflect.Value)
-
-// The 'instructions' of the decoding machine
-type decInstr struct {
- op decOp
- field int // field number of the wire type
- index []int // field access indices for destination type
- ovfl error // error message for overflow/underflow (for arrays, of the elements)
-}
-
-// ignoreUint discards a uint value with no destination.
-func ignoreUint(i *decInstr, state *decoderState, v reflect.Value) {
- state.decodeUint()
-}
-
-// ignoreTwoUints discards a uint value with no destination. It's used to skip
-// complex values.
-func ignoreTwoUints(i *decInstr, state *decoderState, v reflect.Value) {
- state.decodeUint()
- state.decodeUint()
-}
-
-// Since the encoder writes no zeros, if we arrive at a decoder we have
-// a value to extract and store. The field number has already been read
-// (it's how we knew to call this decoder).
-// Each decoder is responsible for handling any indirections associated
-// with the data structure. If any pointer so reached is nil, allocation must
-// be done.
-
-// decAlloc takes a value and returns a settable value that can
-// be assigned to. If the value is a pointer, decAlloc guarantees it points to storage.
-// The callers to the individual decoders are expected to have used decAlloc.
-// The individual decoders don't need to it.
-func decAlloc(v reflect.Value) reflect.Value {
- for v.Kind() == reflect.Pointer {
- if v.IsNil() {
- v.Set(reflect.New(v.Type().Elem()))
- }
- v = v.Elem()
- }
- return v
-}
-
-// decBool decodes a uint and stores it as a boolean in value.
-func decBool(i *decInstr, state *decoderState, value reflect.Value) {
- value.SetBool(state.decodeUint() != 0)
-}
-
-// decInt8 decodes an integer and stores it as an int8 in value.
-func decInt8(i *decInstr, state *decoderState, value reflect.Value) {
- v := state.decodeInt()
- if v < math.MinInt8 || math.MaxInt8 < v {
- error_(i.ovfl)
- }
- value.SetInt(v)
-}
-
-// decUint8 decodes an unsigned integer and stores it as a uint8 in value.
-func decUint8(i *decInstr, state *decoderState, value reflect.Value) {
- v := state.decodeUint()
- if math.MaxUint8 < v {
- error_(i.ovfl)
- }
- value.SetUint(v)
-}
-
-// decInt16 decodes an integer and stores it as an int16 in value.
-func decInt16(i *decInstr, state *decoderState, value reflect.Value) {
- v := state.decodeInt()
- if v < math.MinInt16 || math.MaxInt16 < v {
- error_(i.ovfl)
- }
- value.SetInt(v)
-}
-
-// decUint16 decodes an unsigned integer and stores it as a uint16 in value.
-func decUint16(i *decInstr, state *decoderState, value reflect.Value) {
- v := state.decodeUint()
- if math.MaxUint16 < v {
- error_(i.ovfl)
- }
- value.SetUint(v)
-}
-
-// decInt32 decodes an integer and stores it as an int32 in value.
-func decInt32(i *decInstr, state *decoderState, value reflect.Value) {
- v := state.decodeInt()
- if v < math.MinInt32 || math.MaxInt32 < v {
- error_(i.ovfl)
- }
- value.SetInt(v)
-}
-
-// decUint32 decodes an unsigned integer and stores it as a uint32 in value.
-func decUint32(i *decInstr, state *decoderState, value reflect.Value) {
- v := state.decodeUint()
- if math.MaxUint32 < v {
- error_(i.ovfl)
- }
- value.SetUint(v)
-}
-
-// decInt64 decodes an integer and stores it as an int64 in value.
-func decInt64(i *decInstr, state *decoderState, value reflect.Value) {
- v := state.decodeInt()
- value.SetInt(v)
-}
-
-// decUint64 decodes an unsigned integer and stores it as a uint64 in value.
-func decUint64(i *decInstr, state *decoderState, value reflect.Value) {
- v := state.decodeUint()
- value.SetUint(v)
-}
-
-// Floating-point numbers are transmitted as uint64s holding the bits
-// of the underlying representation. They are sent byte-reversed, with
-// the exponent end coming out first, so integer floating point numbers
-// (for example) transmit more compactly. This routine does the
-// unswizzling.
-func float64FromBits(u uint64) float64 {
- v := bits.ReverseBytes64(u)
- return math.Float64frombits(v)
-}
-
-// float32FromBits decodes an unsigned integer, treats it as a 32-bit floating-point
-// number, and returns it. It's a helper function for float32 and complex64.
-// It returns a float64 because that's what reflection needs, but its return
-// value is known to be accurately representable in a float32.
-func float32FromBits(u uint64, ovfl error) float64 {
- v := float64FromBits(u)
- av := v
- if av < 0 {
- av = -av
- }
- // +Inf is OK in both 32- and 64-bit floats. Underflow is always OK.
- if math.MaxFloat32 < av && av <= math.MaxFloat64 {
- error_(ovfl)
- }
- return v
-}
-
-// decFloat32 decodes an unsigned integer, treats it as a 32-bit floating-point
-// number, and stores it in value.
-func decFloat32(i *decInstr, state *decoderState, value reflect.Value) {
- value.SetFloat(float32FromBits(state.decodeUint(), i.ovfl))
-}
-
-// decFloat64 decodes an unsigned integer, treats it as a 64-bit floating-point
-// number, and stores it in value.
-func decFloat64(i *decInstr, state *decoderState, value reflect.Value) {
- value.SetFloat(float64FromBits(state.decodeUint()))
-}
-
-// decComplex64 decodes a pair of unsigned integers, treats them as a
-// pair of floating point numbers, and stores them as a complex64 in value.
-// The real part comes first.
-func decComplex64(i *decInstr, state *decoderState, value reflect.Value) {
- real := float32FromBits(state.decodeUint(), i.ovfl)
- imag := float32FromBits(state.decodeUint(), i.ovfl)
- value.SetComplex(complex(real, imag))
-}
-
-// decComplex128 decodes a pair of unsigned integers, treats them as a
-// pair of floating point numbers, and stores them as a complex128 in value.
-// The real part comes first.
-func decComplex128(i *decInstr, state *decoderState, value reflect.Value) {
- real := float64FromBits(state.decodeUint())
- imag := float64FromBits(state.decodeUint())
- value.SetComplex(complex(real, imag))
-}
-
-// decUint8Slice decodes a byte slice and stores in value a slice header
-// describing the data.
-// uint8 slices are encoded as an unsigned count followed by the raw bytes.
-func decUint8Slice(i *decInstr, state *decoderState, value reflect.Value) {
- n, ok := state.getLength()
- if !ok {
- errorf("bad %s slice length: %d", value.Type(), n)
- }
- if value.Cap() < n {
- safe := saferio.SliceCap((*byte)(nil), uint64(n))
- if safe < 0 {
- errorf("%s slice too big: %d elements", value.Type(), n)
- }
- value.Set(reflect.MakeSlice(value.Type(), safe, safe))
- ln := safe
- i := 0
- for i < n {
- if i >= ln {
- // We didn't allocate the entire slice,
- // due to using saferio.SliceCap.
- // Append a value to grow the slice.
- // The slice is full, so this should
- // bump up the capacity.
- value.Set(reflect.Append(value, reflect.Zero(value.Type().Elem())))
- }
- // Copy into s up to the capacity or n,
- // whichever is less.
- ln = value.Cap()
- if ln > n {
- ln = n
- }
- value.SetLen(ln)
- sub := value.Slice(i, ln)
- if _, err := state.b.Read(sub.Bytes()); err != nil {
- errorf("error decoding []byte at %d: %s", err, i)
- }
- i = ln
- }
- } else {
- value.SetLen(n)
- if _, err := state.b.Read(value.Bytes()); err != nil {
- errorf("error decoding []byte: %s", err)
- }
- }
-}
-
-// decString decodes byte array and stores in value a string header
-// describing the data.
-// Strings are encoded as an unsigned count followed by the raw bytes.
-func decString(i *decInstr, state *decoderState, value reflect.Value) {
- n, ok := state.getLength()
- if !ok {
- errorf("bad %s slice length: %d", value.Type(), n)
- }
- // Read the data.
- data := state.b.Bytes()
- if len(data) < n {
- errorf("invalid string length %d: exceeds input size %d", n, len(data))
- }
- s := string(data[:n])
- state.b.Drop(n)
- value.SetString(s)
-}
-
-// ignoreUint8Array skips over the data for a byte slice value with no destination.
-func ignoreUint8Array(i *decInstr, state *decoderState, value reflect.Value) {
- n, ok := state.getLength()
- if !ok {
- errorf("slice length too large")
- }
- bn := state.b.Len()
- if bn < n {
- errorf("invalid slice length %d: exceeds input size %d", n, bn)
- }
- state.b.Drop(n)
-}
-
-// Execution engine
-
-// The encoder engine is an array of instructions indexed by field number of the incoming
-// decoder. It is executed with random access according to field number.
-type decEngine struct {
- instr []decInstr
- numInstr int // the number of active instructions
-}
-
-// decodeSingle decodes a top-level value that is not a struct and stores it in value.
-// Such values are preceded by a zero, making them have the memory layout of a
-// struct field (although with an illegal field number).
-func (dec *Decoder) decodeSingle(engine *decEngine, value reflect.Value) {
- state := dec.newDecoderState(&dec.buf)
- defer dec.freeDecoderState(state)
- state.fieldnum = singletonField
- if state.decodeUint() != 0 {
- errorf("decode: corrupted data: non-zero delta for singleton")
- }
- instr := &engine.instr[singletonField]
- instr.op(instr, state, value)
-}
-
-// decodeStruct decodes a top-level struct and stores it in value.
-// Indir is for the value, not the type. At the time of the call it may
-// differ from ut.indir, which was computed when the engine was built.
-// This state cannot arise for decodeSingle, which is called directly
-// from the user's value, not from the innards of an engine.
-func (dec *Decoder) decodeStruct(engine *decEngine, value reflect.Value) {
- state := dec.newDecoderState(&dec.buf)
- defer dec.freeDecoderState(state)
- state.fieldnum = -1
- for state.b.Len() > 0 {
- delta := int(state.decodeUint())
- if delta < 0 {
- errorf("decode: corrupted data: negative delta")
- }
- if delta == 0 { // struct terminator is zero delta fieldnum
- break
- }
- if state.fieldnum >= len(engine.instr)-delta { // subtract to compare without overflow
- error_(errRange)
- }
- fieldnum := state.fieldnum + delta
- instr := &engine.instr[fieldnum]
- var field reflect.Value
- if instr.index != nil {
- // Otherwise the field is unknown to us and instr.op is an ignore op.
- field = value.FieldByIndex(instr.index)
- if field.Kind() == reflect.Pointer {
- field = decAlloc(field)
- }
- }
- instr.op(instr, state, field)
- state.fieldnum = fieldnum
- }
-}
-
-var noValue reflect.Value
-
-// ignoreStruct discards the data for a struct with no destination.
-func (dec *Decoder) ignoreStruct(engine *decEngine) {
- state := dec.newDecoderState(&dec.buf)
- defer dec.freeDecoderState(state)
- state.fieldnum = -1
- for state.b.Len() > 0 {
- delta := int(state.decodeUint())
- if delta < 0 {
- errorf("ignore decode: corrupted data: negative delta")
- }
- if delta == 0 { // struct terminator is zero delta fieldnum
- break
- }
- fieldnum := state.fieldnum + delta
- if fieldnum >= len(engine.instr) {
- error_(errRange)
- }
- instr := &engine.instr[fieldnum]
- instr.op(instr, state, noValue)
- state.fieldnum = fieldnum
- }
-}
-
-// ignoreSingle discards the data for a top-level non-struct value with no
-// destination. It's used when calling Decode with a nil value.
-func (dec *Decoder) ignoreSingle(engine *decEngine) {
- state := dec.newDecoderState(&dec.buf)
- defer dec.freeDecoderState(state)
- state.fieldnum = singletonField
- delta := int(state.decodeUint())
- if delta != 0 {
- errorf("decode: corrupted data: non-zero delta for singleton")
- }
- instr := &engine.instr[singletonField]
- instr.op(instr, state, noValue)
-}
-
-// decodeArrayHelper does the work for decoding arrays and slices.
-func (dec *Decoder) decodeArrayHelper(state *decoderState, value reflect.Value, elemOp decOp, length int, ovfl error, helper decHelper) {
- if helper != nil && helper(state, value, length, ovfl) {
- return
- }
- instr := &decInstr{elemOp, 0, nil, ovfl}
- isPtr := value.Type().Elem().Kind() == reflect.Pointer
- ln := value.Len()
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding array or slice: length exceeds input size (%d elements)", length)
- }
- if i >= ln {
- // This is a slice that we only partially allocated.
- // Grow it using append, up to length.
- value.Set(reflect.Append(value, reflect.Zero(value.Type().Elem())))
- cp := value.Cap()
- if cp > length {
- cp = length
- }
- value.SetLen(cp)
- ln = cp
- }
- v := value.Index(i)
- if isPtr {
- v = decAlloc(v)
- }
- elemOp(instr, state, v)
- }
-}
-
-// decodeArray decodes an array and stores it in value.
-// The length is an unsigned integer preceding the elements. Even though the length is redundant
-// (it's part of the type), it's a useful check and is included in the encoding.
-func (dec *Decoder) decodeArray(state *decoderState, value reflect.Value, elemOp decOp, length int, ovfl error, helper decHelper) {
- if n := state.decodeUint(); n != uint64(length) {
- errorf("length mismatch in decodeArray")
- }
- dec.decodeArrayHelper(state, value, elemOp, length, ovfl, helper)
-}
-
-// decodeIntoValue is a helper for map decoding.
-func decodeIntoValue(state *decoderState, op decOp, isPtr bool, value reflect.Value, instr *decInstr) reflect.Value {
- v := value
- if isPtr {
- v = decAlloc(value)
- }
-
- op(instr, state, v)
- return value
-}
-
-// decodeMap decodes a map and stores it in value.
-// Maps are encoded as a length followed by key:value pairs.
-// Because the internals of maps are not visible to us, we must
-// use reflection rather than pointer magic.
-func (dec *Decoder) decodeMap(mtyp reflect.Type, state *decoderState, value reflect.Value, keyOp, elemOp decOp, ovfl error) {
- n := int(state.decodeUint())
- if value.IsNil() {
- value.Set(reflect.MakeMapWithSize(mtyp, n))
- }
- keyIsPtr := mtyp.Key().Kind() == reflect.Pointer
- elemIsPtr := mtyp.Elem().Kind() == reflect.Pointer
- keyInstr := &decInstr{keyOp, 0, nil, ovfl}
- elemInstr := &decInstr{elemOp, 0, nil, ovfl}
- keyP := reflect.New(mtyp.Key())
- keyZ := reflect.Zero(mtyp.Key())
- elemP := reflect.New(mtyp.Elem())
- elemZ := reflect.Zero(mtyp.Elem())
- for i := 0; i < n; i++ {
- key := decodeIntoValue(state, keyOp, keyIsPtr, keyP.Elem(), keyInstr)
- elem := decodeIntoValue(state, elemOp, elemIsPtr, elemP.Elem(), elemInstr)
- value.SetMapIndex(key, elem)
- keyP.Elem().Set(keyZ)
- elemP.Elem().Set(elemZ)
- }
-}
-
-// ignoreArrayHelper does the work for discarding arrays and slices.
-func (dec *Decoder) ignoreArrayHelper(state *decoderState, elemOp decOp, length int) {
- instr := &decInstr{elemOp, 0, nil, errors.New("no error")}
- for i := 0; i < length; i++ {
- if state.b.Len() == 0 {
- errorf("decoding array or slice: length exceeds input size (%d elements)", length)
- }
- elemOp(instr, state, noValue)
- }
-}
-
-// ignoreArray discards the data for an array value with no destination.
-func (dec *Decoder) ignoreArray(state *decoderState, elemOp decOp, length int) {
- if n := state.decodeUint(); n != uint64(length) {
- errorf("length mismatch in ignoreArray")
- }
- dec.ignoreArrayHelper(state, elemOp, length)
-}
-
-// ignoreMap discards the data for a map value with no destination.
-func (dec *Decoder) ignoreMap(state *decoderState, keyOp, elemOp decOp) {
- n := int(state.decodeUint())
- keyInstr := &decInstr{keyOp, 0, nil, errors.New("no error")}
- elemInstr := &decInstr{elemOp, 0, nil, errors.New("no error")}
- for i := 0; i < n; i++ {
- keyOp(keyInstr, state, noValue)
- elemOp(elemInstr, state, noValue)
- }
-}
-
-// decodeSlice decodes a slice and stores it in value.
-// Slices are encoded as an unsigned length followed by the elements.
-func (dec *Decoder) decodeSlice(state *decoderState, value reflect.Value, elemOp decOp, ovfl error, helper decHelper) {
- u := state.decodeUint()
- typ := value.Type()
- size := uint64(typ.Elem().Size())
- nBytes := u * size
- n := int(u)
- // Take care with overflow in this calculation.
- if n < 0 || uint64(n) != u || nBytes > tooBig || (size > 0 && nBytes/size != u) {
- // We don't check n against buffer length here because if it's a slice
- // of interfaces, there will be buffer reloads.
- errorf("%s slice too big: %d elements of %d bytes", typ.Elem(), u, size)
- }
- if value.Cap() < n {
- safe := saferio.SliceCap(reflect.Zero(reflect.PtrTo(typ.Elem())).Interface(), uint64(n))
- if safe < 0 {
- errorf("%s slice too big: %d elements of %d bytes", typ.Elem(), u, size)
- }
- value.Set(reflect.MakeSlice(typ, safe, safe))
- } else {
- value.SetLen(n)
- }
- dec.decodeArrayHelper(state, value, elemOp, n, ovfl, helper)
-}
-
-// ignoreSlice skips over the data for a slice value with no destination.
-func (dec *Decoder) ignoreSlice(state *decoderState, elemOp decOp) {
- dec.ignoreArrayHelper(state, elemOp, int(state.decodeUint()))
-}
-
-// decodeInterface decodes an interface value and stores it in value.
-// Interfaces are encoded as the name of a concrete type followed by a value.
-// If the name is empty, the value is nil and no value is sent.
-func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, value reflect.Value) {
- // Read the name of the concrete type.
- nr := state.decodeUint()
- if nr > 1<<31 { // zero is permissible for anonymous types
- errorf("invalid type name length %d", nr)
- }
- if nr > uint64(state.b.Len()) {
- errorf("invalid type name length %d: exceeds input size", nr)
- }
- n := int(nr)
- name := state.b.Bytes()[:n]
- state.b.Drop(n)
- // Allocate the destination interface value.
- if len(name) == 0 {
- // Copy the nil interface value to the target.
- value.Set(reflect.Zero(value.Type()))
- return
- }
- if len(name) > 1024 {
- errorf("name too long (%d bytes): %.20q...", len(name), name)
- }
- // The concrete type must be registered.
- typi, ok := nameToConcreteType.Load(string(name))
- if !ok {
- errorf("name not registered for interface: %q", name)
- }
- typ := typi.(reflect.Type)
-
- // Read the type id of the concrete value.
- concreteId := dec.decodeTypeSequence(true)
- if concreteId < 0 {
- error_(dec.err)
- }
- // Byte count of value is next; we don't care what it is (it's there
- // in case we want to ignore the value by skipping it completely).
- state.decodeUint()
- // Read the concrete value.
- v := allocValue(typ)
- dec.decodeValue(concreteId, v)
- if dec.err != nil {
- error_(dec.err)
- }
- // Assign the concrete value to the interface.
- // Tread carefully; it might not satisfy the interface.
- if !typ.AssignableTo(ityp) {
- errorf("%s is not assignable to type %s", typ, ityp)
- }
- // Copy the interface value to the target.
- value.Set(v)
-}
-
-// ignoreInterface discards the data for an interface value with no destination.
-func (dec *Decoder) ignoreInterface(state *decoderState) {
- // Read the name of the concrete type.
- n, ok := state.getLength()
- if !ok {
- errorf("bad interface encoding: name too large for buffer")
- }
- bn := state.b.Len()
- if bn < n {
- errorf("invalid interface value length %d: exceeds input size %d", n, bn)
- }
- state.b.Drop(n)
- id := dec.decodeTypeSequence(true)
- if id < 0 {
- error_(dec.err)
- }
- // At this point, the decoder buffer contains a delimited value. Just toss it.
- n, ok = state.getLength()
- if !ok {
- errorf("bad interface encoding: data length too large for buffer")
- }
- state.b.Drop(n)
-}
-
-// decodeGobDecoder decodes something implementing the GobDecoder interface.
-// The data is encoded as a byte slice.
-func (dec *Decoder) decodeGobDecoder(ut *userTypeInfo, state *decoderState, value reflect.Value) {
- // Read the bytes for the value.
- n, ok := state.getLength()
- if !ok {
- errorf("GobDecoder: length too large for buffer")
- }
- b := state.b.Bytes()
- if len(b) < n {
- errorf("GobDecoder: invalid data length %d: exceeds input size %d", n, len(b))
- }
- b = b[:n]
- state.b.Drop(n)
- var err error
- // We know it's one of these.
- switch ut.externalDec {
- case xGob:
- err = value.Interface().(GobDecoder).GobDecode(b)
- case xBinary:
- err = value.Interface().(encoding.BinaryUnmarshaler).UnmarshalBinary(b)
- case xText:
- err = value.Interface().(encoding.TextUnmarshaler).UnmarshalText(b)
- }
- if err != nil {
- error_(err)
- }
-}
-
-// ignoreGobDecoder discards the data for a GobDecoder value with no destination.
-func (dec *Decoder) ignoreGobDecoder(state *decoderState) {
- // Read the bytes for the value.
- n, ok := state.getLength()
- if !ok {
- errorf("GobDecoder: length too large for buffer")
- }
- bn := state.b.Len()
- if bn < n {
- errorf("GobDecoder: invalid data length %d: exceeds input size %d", n, bn)
- }
- state.b.Drop(n)
-}
-
-// Index by Go types.
-var decOpTable = [...]decOp{
- reflect.Bool: decBool,
- reflect.Int8: decInt8,
- reflect.Int16: decInt16,
- reflect.Int32: decInt32,
- reflect.Int64: decInt64,
- reflect.Uint8: decUint8,
- reflect.Uint16: decUint16,
- reflect.Uint32: decUint32,
- reflect.Uint64: decUint64,
- reflect.Float32: decFloat32,
- reflect.Float64: decFloat64,
- reflect.Complex64: decComplex64,
- reflect.Complex128: decComplex128,
- reflect.String: decString,
-}
-
-// Indexed by gob types. tComplex will be added during type.init().
-var decIgnoreOpMap = map[typeId]decOp{
- tBool: ignoreUint,
- tInt: ignoreUint,
- tUint: ignoreUint,
- tFloat: ignoreUint,
- tBytes: ignoreUint8Array,
- tString: ignoreUint8Array,
- tComplex: ignoreTwoUints,
-}
-
-// decOpFor returns the decoding op for the base type under rt and
-// the indirection count to reach it.
-func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProgress map[reflect.Type]*decOp) *decOp {
- ut := userType(rt)
- // If the type implements GobEncoder, we handle it without further processing.
- if ut.externalDec != 0 {
- return dec.gobDecodeOpFor(ut)
- }
-
- // If this type is already in progress, it's a recursive type (e.g. map[string]*T).
- // Return the pointer to the op we're already building.
- if opPtr := inProgress[rt]; opPtr != nil {
- return opPtr
- }
- typ := ut.base
- var op decOp
- k := typ.Kind()
- if int(k) < len(decOpTable) {
- op = decOpTable[k]
- }
- if op == nil {
- inProgress[rt] = &op
- // Special cases
- switch t := typ; t.Kind() {
- case reflect.Array:
- name = "element of " + name
- elemId := dec.wireType[wireId].ArrayT.Elem
- elemOp := dec.decOpFor(elemId, t.Elem(), name, inProgress)
- ovfl := overflow(name)
- helper := decArrayHelper[t.Elem().Kind()]
- op = func(i *decInstr, state *decoderState, value reflect.Value) {
- state.dec.decodeArray(state, value, *elemOp, t.Len(), ovfl, helper)
- }
-
- case reflect.Map:
- keyId := dec.wireType[wireId].MapT.Key
- elemId := dec.wireType[wireId].MapT.Elem
- keyOp := dec.decOpFor(keyId, t.Key(), "key of "+name, inProgress)
- elemOp := dec.decOpFor(elemId, t.Elem(), "element of "+name, inProgress)
- ovfl := overflow(name)
- op = func(i *decInstr, state *decoderState, value reflect.Value) {
- state.dec.decodeMap(t, state, value, *keyOp, *elemOp, ovfl)
- }
-
- case reflect.Slice:
- name = "element of " + name
- if t.Elem().Kind() == reflect.Uint8 {
- op = decUint8Slice
- break
- }
- var elemId typeId
- if tt, ok := builtinIdToType[wireId]; ok {
- elemId = tt.(*sliceType).Elem
- } else {
- elemId = dec.wireType[wireId].SliceT.Elem
- }
- elemOp := dec.decOpFor(elemId, t.Elem(), name, inProgress)
- ovfl := overflow(name)
- helper := decSliceHelper[t.Elem().Kind()]
- op = func(i *decInstr, state *decoderState, value reflect.Value) {
- state.dec.decodeSlice(state, value, *elemOp, ovfl, helper)
- }
-
- case reflect.Struct:
- // Generate a closure that calls out to the engine for the nested type.
- ut := userType(typ)
- enginePtr, err := dec.getDecEnginePtr(wireId, ut)
- if err != nil {
- error_(err)
- }
- op = func(i *decInstr, state *decoderState, value reflect.Value) {
- // indirect through enginePtr to delay evaluation for recursive structs.
- dec.decodeStruct(*enginePtr, value)
- }
- case reflect.Interface:
- op = func(i *decInstr, state *decoderState, value reflect.Value) {
- state.dec.decodeInterface(t, state, value)
- }
- }
- }
- if op == nil {
- errorf("decode can't handle type %s", rt)
- }
- return &op
-}
-
-var maxIgnoreNestingDepth = 10000
-
-// decIgnoreOpFor returns the decoding op for a field that has no destination.
-func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp, depth int) *decOp {
- if depth > maxIgnoreNestingDepth {
- error_(errors.New("invalid nesting depth"))
- }
- // If this type is already in progress, it's a recursive type (e.g. map[string]*T).
- // Return the pointer to the op we're already building.
- if opPtr := inProgress[wireId]; opPtr != nil {
- return opPtr
- }
- op, ok := decIgnoreOpMap[wireId]
- if !ok {
- inProgress[wireId] = &op
- if wireId == tInterface {
- // Special case because it's a method: the ignored item might
- // define types and we need to record their state in the decoder.
- op = func(i *decInstr, state *decoderState, value reflect.Value) {
- state.dec.ignoreInterface(state)
- }
- return &op
- }
- // Special cases
- wire := dec.wireType[wireId]
- switch {
- case wire == nil:
- errorf("bad data: undefined type %s", wireId.string())
- case wire.ArrayT != nil:
- elemId := wire.ArrayT.Elem
- elemOp := dec.decIgnoreOpFor(elemId, inProgress, depth+1)
- op = func(i *decInstr, state *decoderState, value reflect.Value) {
- state.dec.ignoreArray(state, *elemOp, wire.ArrayT.Len)
- }
-
- case wire.MapT != nil:
- keyId := dec.wireType[wireId].MapT.Key
- elemId := dec.wireType[wireId].MapT.Elem
- keyOp := dec.decIgnoreOpFor(keyId, inProgress, depth+1)
- elemOp := dec.decIgnoreOpFor(elemId, inProgress, depth+1)
- op = func(i *decInstr, state *decoderState, value reflect.Value) {
- state.dec.ignoreMap(state, *keyOp, *elemOp)
- }
-
- case wire.SliceT != nil:
- elemId := wire.SliceT.Elem
- elemOp := dec.decIgnoreOpFor(elemId, inProgress, depth+1)
- op = func(i *decInstr, state *decoderState, value reflect.Value) {
- state.dec.ignoreSlice(state, *elemOp)
- }
-
- case wire.StructT != nil:
- // Generate a closure that calls out to the engine for the nested type.
- enginePtr, err := dec.getIgnoreEnginePtr(wireId)
- if err != nil {
- error_(err)
- }
- op = func(i *decInstr, state *decoderState, value reflect.Value) {
- // indirect through enginePtr to delay evaluation for recursive structs
- state.dec.ignoreStruct(*enginePtr)
- }
-
- case wire.GobEncoderT != nil, wire.BinaryMarshalerT != nil, wire.TextMarshalerT != nil:
- op = func(i *decInstr, state *decoderState, value reflect.Value) {
- state.dec.ignoreGobDecoder(state)
- }
- }
- }
- if op == nil {
- errorf("bad data: ignore can't handle type %s", wireId.string())
- }
- return &op
-}
-
-// gobDecodeOpFor returns the op for a type that is known to implement
-// GobDecoder.
-func (dec *Decoder) gobDecodeOpFor(ut *userTypeInfo) *decOp {
- rcvrType := ut.user
- if ut.decIndir == -1 {
- rcvrType = reflect.PointerTo(rcvrType)
- } else if ut.decIndir > 0 {
- for i := int8(0); i < ut.decIndir; i++ {
- rcvrType = rcvrType.Elem()
- }
- }
- var op decOp
- op = func(i *decInstr, state *decoderState, value reflect.Value) {
- // We now have the base type. We need its address if the receiver is a pointer.
- if value.Kind() != reflect.Pointer && rcvrType.Kind() == reflect.Pointer {
- value = value.Addr()
- }
- state.dec.decodeGobDecoder(ut, state, value)
- }
- return &op
-}
-
-// compatibleType asks: Are these two gob Types compatible?
-// Answers the question for basic types, arrays, maps and slices, plus
-// GobEncoder/Decoder pairs.
-// Structs are considered ok; fields will be checked later.
-func (dec *Decoder) compatibleType(fr reflect.Type, fw typeId, inProgress map[reflect.Type]typeId) bool {
- if rhs, ok := inProgress[fr]; ok {
- return rhs == fw
- }
- inProgress[fr] = fw
- ut := userType(fr)
- wire, ok := dec.wireType[fw]
- // If wire was encoded with an encoding method, fr must have that method.
- // And if not, it must not.
- // At most one of the booleans in ut is set.
- // We could possibly relax this constraint in the future in order to
- // choose the decoding method using the data in the wireType.
- // The parentheses look odd but are correct.
- if (ut.externalDec == xGob) != (ok && wire.GobEncoderT != nil) ||
- (ut.externalDec == xBinary) != (ok && wire.BinaryMarshalerT != nil) ||
- (ut.externalDec == xText) != (ok && wire.TextMarshalerT != nil) {
- return false
- }
- if ut.externalDec != 0 { // This test trumps all others.
- return true
- }
- switch t := ut.base; t.Kind() {
- default:
- // chan, etc: cannot handle.
- return false
- case reflect.Bool:
- return fw == tBool
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return fw == tInt
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return fw == tUint
- case reflect.Float32, reflect.Float64:
- return fw == tFloat
- case reflect.Complex64, reflect.Complex128:
- return fw == tComplex
- case reflect.String:
- return fw == tString
- case reflect.Interface:
- return fw == tInterface
- case reflect.Array:
- if !ok || wire.ArrayT == nil {
- return false
- }
- array := wire.ArrayT
- return t.Len() == array.Len && dec.compatibleType(t.Elem(), array.Elem, inProgress)
- case reflect.Map:
- if !ok || wire.MapT == nil {
- return false
- }
- MapType := wire.MapT
- return dec.compatibleType(t.Key(), MapType.Key, inProgress) && dec.compatibleType(t.Elem(), MapType.Elem, inProgress)
- case reflect.Slice:
- // Is it an array of bytes?
- if t.Elem().Kind() == reflect.Uint8 {
- return fw == tBytes
- }
- // Extract and compare element types.
- var sw *sliceType
- if tt, ok := builtinIdToType[fw]; ok {
- sw, _ = tt.(*sliceType)
- } else if wire != nil {
- sw = wire.SliceT
- }
- elem := userType(t.Elem()).base
- return sw != nil && dec.compatibleType(elem, sw.Elem, inProgress)
- case reflect.Struct:
- return true
- }
-}
-
-// typeString returns a human-readable description of the type identified by remoteId.
-func (dec *Decoder) typeString(remoteId typeId) string {
- typeLock.Lock()
- defer typeLock.Unlock()
- if t := idToType[remoteId]; t != nil {
- // globally known type.
- return t.string()
- }
- return dec.wireType[remoteId].string()
-}
-
-// compileSingle compiles the decoder engine for a non-struct top-level value, including
-// GobDecoders.
-func (dec *Decoder) compileSingle(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) {
- rt := ut.user
- engine = new(decEngine)
- engine.instr = make([]decInstr, 1) // one item
- name := rt.String() // best we can do
- if !dec.compatibleType(rt, remoteId, make(map[reflect.Type]typeId)) {
- remoteType := dec.typeString(remoteId)
- // Common confusing case: local interface type, remote concrete type.
- if ut.base.Kind() == reflect.Interface && remoteId != tInterface {
- return nil, errors.New("gob: local interface type " + name + " can only be decoded from remote interface type; received concrete type " + remoteType)
- }
- return nil, errors.New("gob: decoding into local type " + name + ", received remote type " + remoteType)
- }
- op := dec.decOpFor(remoteId, rt, name, make(map[reflect.Type]*decOp))
- ovfl := errors.New(`value for "` + name + `" out of range`)
- engine.instr[singletonField] = decInstr{*op, singletonField, nil, ovfl}
- engine.numInstr = 1
- return
-}
-
-// compileIgnoreSingle compiles the decoder engine for a non-struct top-level value that will be discarded.
-func (dec *Decoder) compileIgnoreSingle(remoteId typeId) *decEngine {
- engine := new(decEngine)
- engine.instr = make([]decInstr, 1) // one item
- op := dec.decIgnoreOpFor(remoteId, make(map[typeId]*decOp), 0)
- ovfl := overflow(dec.typeString(remoteId))
- engine.instr[0] = decInstr{*op, 0, nil, ovfl}
- engine.numInstr = 1
- return engine
-}
-
-// compileDec compiles the decoder engine for a value. If the value is not a struct,
-// it calls out to compileSingle.
-func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) {
- defer catchError(&err)
- rt := ut.base
- srt := rt
- if srt.Kind() != reflect.Struct || ut.externalDec != 0 {
- return dec.compileSingle(remoteId, ut)
- }
- var wireStruct *structType
- // Builtin types can come from global pool; the rest must be defined by the decoder.
- // Also we know we're decoding a struct now, so the client must have sent one.
- if t, ok := builtinIdToType[remoteId]; ok {
- wireStruct, _ = t.(*structType)
- } else {
- wire := dec.wireType[remoteId]
- if wire == nil {
- error_(errBadType)
- }
- wireStruct = wire.StructT
- }
- if wireStruct == nil {
- errorf("type mismatch in decoder: want struct type %s; got non-struct", rt)
- }
- engine = new(decEngine)
- engine.instr = make([]decInstr, len(wireStruct.Field))
- seen := make(map[reflect.Type]*decOp)
- // Loop over the fields of the wire type.
- for fieldnum := 0; fieldnum < len(wireStruct.Field); fieldnum++ {
- wireField := wireStruct.Field[fieldnum]
- if wireField.Name == "" {
- errorf("empty name for remote field of type %s", wireStruct.Name)
- }
- ovfl := overflow(wireField.Name)
- // Find the field of the local type with the same name.
- localField, present := srt.FieldByName(wireField.Name)
- // TODO(r): anonymous names
- if !present || !isExported(wireField.Name) {
- op := dec.decIgnoreOpFor(wireField.Id, make(map[typeId]*decOp), 0)
- engine.instr[fieldnum] = decInstr{*op, fieldnum, nil, ovfl}
- continue
- }
- if !dec.compatibleType(localField.Type, wireField.Id, make(map[reflect.Type]typeId)) {
- errorf("wrong type (%s) for received field %s.%s", localField.Type, wireStruct.Name, wireField.Name)
- }
- op := dec.decOpFor(wireField.Id, localField.Type, localField.Name, seen)
- engine.instr[fieldnum] = decInstr{*op, fieldnum, localField.Index, ovfl}
- engine.numInstr++
- }
- return
-}
-
-// getDecEnginePtr returns the engine for the specified type.
-func (dec *Decoder) getDecEnginePtr(remoteId typeId, ut *userTypeInfo) (enginePtr **decEngine, err error) {
- rt := ut.user
- decoderMap, ok := dec.decoderCache[rt]
- if !ok {
- decoderMap = make(map[typeId]**decEngine)
- dec.decoderCache[rt] = decoderMap
- }
- if enginePtr, ok = decoderMap[remoteId]; !ok {
- // To handle recursive types, mark this engine as underway before compiling.
- enginePtr = new(*decEngine)
- decoderMap[remoteId] = enginePtr
- *enginePtr, err = dec.compileDec(remoteId, ut)
- if err != nil {
- delete(decoderMap, remoteId)
- }
- }
- return
-}
-
-// emptyStruct is the type we compile into when ignoring a struct value.
-type emptyStruct struct{}
-
-var emptyStructType = reflect.TypeOf(emptyStruct{})
-
-// getIgnoreEnginePtr returns the engine for the specified type when the value is to be discarded.
-func (dec *Decoder) getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err error) {
- var ok bool
- if enginePtr, ok = dec.ignorerCache[wireId]; !ok {
- // To handle recursive types, mark this engine as underway before compiling.
- enginePtr = new(*decEngine)
- dec.ignorerCache[wireId] = enginePtr
- wire := dec.wireType[wireId]
- if wire != nil && wire.StructT != nil {
- *enginePtr, err = dec.compileDec(wireId, userType(emptyStructType))
- } else {
- *enginePtr = dec.compileIgnoreSingle(wireId)
- }
- if err != nil {
- delete(dec.ignorerCache, wireId)
- }
- }
- return
-}
-
-// decodeValue decodes the data stream representing a value and stores it in value.
-func (dec *Decoder) decodeValue(wireId typeId, value reflect.Value) {
- defer catchError(&dec.err)
- // If the value is nil, it means we should just ignore this item.
- if !value.IsValid() {
- dec.decodeIgnoredValue(wireId)
- return
- }
- // Dereference down to the underlying type.
- ut := userType(value.Type())
- base := ut.base
- var enginePtr **decEngine
- enginePtr, dec.err = dec.getDecEnginePtr(wireId, ut)
- if dec.err != nil {
- return
- }
- value = decAlloc(value)
- engine := *enginePtr
- if st := base; st.Kind() == reflect.Struct && ut.externalDec == 0 {
- wt := dec.wireType[wireId]
- if engine.numInstr == 0 && st.NumField() > 0 &&
- wt != nil && len(wt.StructT.Field) > 0 {
- name := base.Name()
- errorf("type mismatch: no fields matched compiling decoder for %s", name)
- }
- dec.decodeStruct(engine, value)
- } else {
- dec.decodeSingle(engine, value)
- }
-}
-
-// decodeIgnoredValue decodes the data stream representing a value of the specified type and discards it.
-func (dec *Decoder) decodeIgnoredValue(wireId typeId) {
- var enginePtr **decEngine
- enginePtr, dec.err = dec.getIgnoreEnginePtr(wireId)
- if dec.err != nil {
- return
- }
- wire := dec.wireType[wireId]
- if wire != nil && wire.StructT != nil {
- dec.ignoreStruct(*enginePtr)
- } else {
- dec.ignoreSingle(*enginePtr)
- }
-}
-
-const (
- intBits = 32 << (^uint(0) >> 63)
- uintptrBits = 32 << (^uintptr(0) >> 63)
-)
-
-func init() {
- var iop, uop decOp
- switch intBits {
- case 32:
- iop = decInt32
- uop = decUint32
- case 64:
- iop = decInt64
- uop = decUint64
- default:
- panic("gob: unknown size of int/uint")
- }
- decOpTable[reflect.Int] = iop
- decOpTable[reflect.Uint] = uop
-
- // Finally uintptr
- switch uintptrBits {
- case 32:
- uop = decUint32
- case 64:
- uop = decUint64
- default:
- panic("gob: unknown size of uintptr")
- }
- decOpTable[reflect.Uintptr] = uop
-}
-
-// Gob depends on being able to take the address
-// of zeroed Values it creates, so use this wrapper instead
-// of the standard reflect.Zero.
-// Each call allocates once.
-func allocValue(t reflect.Type) reflect.Value {
- return reflect.New(t).Elem()
-}
diff --git a/contrib/go/_std_1.20/src/encoding/gob/doc.go b/contrib/go/_std_1.20/src/encoding/gob/doc.go
deleted file mode 100644
index 15473f18b2..0000000000
--- a/contrib/go/_std_1.20/src/encoding/gob/doc.go
+++ /dev/null
@@ -1,423 +0,0 @@
-// Copyright 2009 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 gob manages streams of gobs - binary values exchanged between an
-Encoder (transmitter) and a Decoder (receiver). A typical use is transporting
-arguments and results of remote procedure calls (RPCs) such as those provided by
-package "net/rpc".
-
-The implementation compiles a custom codec for each data type in the stream and
-is most efficient when a single Encoder is used to transmit a stream of values,
-amortizing the cost of compilation.
-
-# Basics
-
-A stream of gobs is self-describing. Each data item in the stream is preceded by
-a specification of its type, expressed in terms of a small set of predefined
-types. Pointers are not transmitted, but the things they point to are
-transmitted; that is, the values are flattened. Nil pointers are not permitted,
-as they have no value. Recursive types work fine, but
-recursive values (data with cycles) are problematic. This may change.
-
-To use gobs, create an Encoder and present it with a series of data items as
-values or addresses that can be dereferenced to values. The Encoder makes sure
-all type information is sent before it is needed. At the receive side, a
-Decoder retrieves values from the encoded stream and unpacks them into local
-variables.
-
-# Types and Values
-
-The source and destination values/types need not correspond exactly. For structs,
-fields (identified by name) that are in the source but absent from the receiving
-variable will be ignored. Fields that are in the receiving variable but missing
-from the transmitted type or value will be ignored in the destination. If a field
-with the same name is present in both, their types must be compatible. Both the
-receiver and transmitter will do all necessary indirection and dereferencing to
-convert between gobs and actual Go values. For instance, a gob type that is
-schematically,
-
- struct { A, B int }
-
-can be sent from or received into any of these Go types:
-
- struct { A, B int } // the same
- *struct { A, B int } // extra indirection of the struct
- struct { *A, **B int } // extra indirection of the fields
- struct { A, B int64 } // different concrete value type; see below
-
-It may also be received into any of these:
-
- struct { A, B int } // the same
- struct { B, A int } // ordering doesn't matter; matching is by name
- struct { A, B, C int } // extra field (C) ignored
- struct { B int } // missing field (A) ignored; data will be dropped
- struct { B, C int } // missing field (A) ignored; extra field (C) ignored.
-
-Attempting to receive into these types will draw a decode error:
-
- struct { A int; B uint } // change of signedness for B
- struct { A int; B float } // change of type for B
- struct { } // no field names in common
- struct { C, D int } // no field names in common
-
-Integers are transmitted two ways: arbitrary precision signed integers or
-arbitrary precision unsigned integers. There is no int8, int16 etc.
-discrimination in the gob format; there are only signed and unsigned integers. As
-described below, the transmitter sends the value in a variable-length encoding;
-the receiver accepts the value and stores it in the destination variable.
-Floating-point numbers are always sent using IEEE-754 64-bit precision (see
-below).
-
-Signed integers may be received into any signed integer variable: int, int16, etc.;
-unsigned integers may be received into any unsigned integer variable; and floating
-point values may be received into any floating point variable. However,
-the destination variable must be able to represent the value or the decode
-operation will fail.
-
-Structs, arrays and slices are also supported. Structs encode and decode only
-exported fields. Strings and arrays of bytes are supported with a special,
-efficient representation (see below). When a slice is decoded, if the existing
-slice has capacity the slice will be extended in place; if not, a new array is
-allocated. Regardless, the length of the resulting slice reports the number of
-elements decoded.
-
-In general, if allocation is required, the decoder will allocate memory. If not,
-it will update the destination variables with values read from the stream. It does
-not initialize them first, so if the destination is a compound value such as a
-map, struct, or slice, the decoded values will be merged elementwise into the
-existing variables.
-
-Functions and channels will not be sent in a gob. Attempting to encode such a value
-at the top level will fail. A struct field of chan or func type is treated exactly
-like an unexported field and is ignored.
-
-Gob can encode a value of any type implementing the GobEncoder or
-encoding.BinaryMarshaler interfaces by calling the corresponding method,
-in that order of preference.
-
-Gob can decode a value of any type implementing the GobDecoder or
-encoding.BinaryUnmarshaler interfaces by calling the corresponding method,
-again in that order of preference.
-
-# Encoding Details
-
-This section documents the encoding, details that are not important for most
-users. Details are presented bottom-up.
-
-An unsigned integer is sent one of two ways. If it is less than 128, it is sent
-as a byte with that value. Otherwise it is sent as a minimal-length big-endian
-(high byte first) byte stream holding the value, preceded by one byte holding the
-byte count, negated. Thus 0 is transmitted as (00), 7 is transmitted as (07) and
-256 is transmitted as (FE 01 00).
-
-A boolean is encoded within an unsigned integer: 0 for false, 1 for true.
-
-A signed integer, i, is encoded within an unsigned integer, u. Within u, bits 1
-upward contain the value; bit 0 says whether they should be complemented upon
-receipt. The encode algorithm looks like this:
-
- var u uint
- if i < 0 {
- u = (^uint(i) << 1) | 1 // complement i, bit 0 is 1
- } else {
- u = (uint(i) << 1) // do not complement i, bit 0 is 0
- }
- encodeUnsigned(u)
-
-The low bit is therefore analogous to a sign bit, but making it the complement bit
-instead guarantees that the largest negative integer is not a special case. For
-example, -129=^128=(^256>>1) encodes as (FE 01 01).
-
-Floating-point numbers are always sent as a representation of a float64 value.
-That value is converted to a uint64 using math.Float64bits. The uint64 is then
-byte-reversed and sent as a regular unsigned integer. The byte-reversal means the
-exponent and high-precision part of the mantissa go first. Since the low bits are
-often zero, this can save encoding bytes. For instance, 17.0 is encoded in only
-three bytes (FE 31 40).
-
-Strings and slices of bytes are sent as an unsigned count followed by that many
-uninterpreted bytes of the value.
-
-All other slices and arrays are sent as an unsigned count followed by that many
-elements using the standard gob encoding for their type, recursively.
-
-Maps are sent as an unsigned count followed by that many key, element
-pairs. Empty but non-nil maps are sent, so if the receiver has not allocated
-one already, one will always be allocated on receipt unless the transmitted map
-is nil and not at the top level.
-
-In slices and arrays, as well as maps, all elements, even zero-valued elements,
-are transmitted, even if all the elements are zero.
-
-Structs are sent as a sequence of (field number, field value) pairs. The field
-value is sent using the standard gob encoding for its type, recursively. If a
-field has the zero value for its type (except for arrays; see above), it is omitted
-from the transmission. The field number is defined by the type of the encoded
-struct: the first field of the encoded type is field 0, the second is field 1,
-etc. When encoding a value, the field numbers are delta encoded for efficiency
-and the fields are always sent in order of increasing field number; the deltas are
-therefore unsigned. The initialization for the delta encoding sets the field
-number to -1, so an unsigned integer field 0 with value 7 is transmitted as unsigned
-delta = 1, unsigned value = 7 or (01 07). Finally, after all the fields have been
-sent a terminating mark denotes the end of the struct. That mark is a delta=0
-value, which has representation (00).
-
-Interface types are not checked for compatibility; all interface types are
-treated, for transmission, as members of a single "interface" type, analogous to
-int or []byte - in effect they're all treated as interface{}. Interface values
-are transmitted as a string identifying the concrete type being sent (a name
-that must be pre-defined by calling Register), followed by a byte count of the
-length of the following data (so the value can be skipped if it cannot be
-stored), followed by the usual encoding of concrete (dynamic) value stored in
-the interface value. (A nil interface value is identified by the empty string
-and transmits no value.) Upon receipt, the decoder verifies that the unpacked
-concrete item satisfies the interface of the receiving variable.
-
-If a value is passed to Encode and the type is not a struct (or pointer to struct,
-etc.), for simplicity of processing it is represented as a struct of one field.
-The only visible effect of this is to encode a zero byte after the value, just as
-after the last field of an encoded struct, so that the decode algorithm knows when
-the top-level value is complete.
-
-The representation of types is described below. When a type is defined on a given
-connection between an Encoder and Decoder, it is assigned a signed integer type
-id. When Encoder.Encode(v) is called, it makes sure there is an id assigned for
-the type of v and all its elements and then it sends the pair (typeid, encoded-v)
-where typeid is the type id of the encoded type of v and encoded-v is the gob
-encoding of the value v.
-
-To define a type, the encoder chooses an unused, positive type id and sends the
-pair (-type id, encoded-type) where encoded-type is the gob encoding of a wireType
-description, constructed from these types:
-
- type wireType struct {
- ArrayT *ArrayType
- SliceT *SliceType
- StructT *StructType
- MapT *MapType
- GobEncoderT *gobEncoderType
- BinaryMarshalerT *gobEncoderType
- TextMarshalerT *gobEncoderType
-
- }
- type arrayType struct {
- CommonType
- Elem typeId
- Len int
- }
- type CommonType struct {
- Name string // the name of the struct type
- Id int // the id of the type, repeated so it's inside the type
- }
- type sliceType struct {
- CommonType
- Elem typeId
- }
- type structType struct {
- CommonType
- Field []*fieldType // the fields of the struct.
- }
- type fieldType struct {
- Name string // the name of the field.
- Id int // the type id of the field, which must be already defined
- }
- type mapType struct {
- CommonType
- Key typeId
- Elem typeId
- }
- type gobEncoderType struct {
- CommonType
- }
-
-If there are nested type ids, the types for all inner type ids must be defined
-before the top-level type id is used to describe an encoded-v.
-
-For simplicity in setup, the connection is defined to understand these types a
-priori, as well as the basic gob types int, uint, etc. Their ids are:
-
- bool 1
- int 2
- uint 3
- float 4
- []byte 5
- string 6
- complex 7
- interface 8
- // gap for reserved ids.
- WireType 16
- ArrayType 17
- CommonType 18
- SliceType 19
- StructType 20
- FieldType 21
- // 22 is slice of fieldType.
- MapType 23
-
-Finally, each message created by a call to Encode is preceded by an encoded
-unsigned integer count of the number of bytes remaining in the message. After
-the initial type name, interface values are wrapped the same way; in effect, the
-interface value acts like a recursive invocation of Encode.
-
-In summary, a gob stream looks like
-
- (byteCount (-type id, encoding of a wireType)* (type id, encoding of a value))*
-
-where * signifies zero or more repetitions and the type id of a value must
-be predefined or be defined before the value in the stream.
-
-Compatibility: Any future changes to the package will endeavor to maintain
-compatibility with streams encoded using previous versions. That is, any released
-version of this package should be able to decode data written with any previously
-released version, subject to issues such as security fixes. See the Go compatibility
-document for background: https://golang.org/doc/go1compat
-
-See "Gobs of data" for a design discussion of the gob wire format:
-https://blog.golang.org/gobs-of-data
-
-# Security
-
-This package is not designed to be hardened against adversarial inputs, and is
-outside the scope of https://go.dev/security/policy. In particular, the Decoder
-does only basic sanity checking on decoded input sizes, and its limits are not
-configurable. Care should be taken when decoding gob data from untrusted
-sources, which may consume significant resources.
-*/
-package gob
-
-/*
-Grammar:
-
-Tokens starting with a lower case letter are terminals; int(n)
-and uint(n) represent the signed/unsigned encodings of the value n.
-
-GobStream:
- DelimitedMessage*
-DelimitedMessage:
- uint(lengthOfMessage) Message
-Message:
- TypeSequence TypedValue
-TypeSequence
- (TypeDefinition DelimitedTypeDefinition*)?
-DelimitedTypeDefinition:
- uint(lengthOfTypeDefinition) TypeDefinition
-TypedValue:
- int(typeId) Value
-TypeDefinition:
- int(-typeId) encodingOfWireType
-Value:
- SingletonValue | StructValue
-SingletonValue:
- uint(0) FieldValue
-FieldValue:
- builtinValue | ArrayValue | MapValue | SliceValue | StructValue | InterfaceValue
-InterfaceValue:
- NilInterfaceValue | NonNilInterfaceValue
-NilInterfaceValue:
- uint(0)
-NonNilInterfaceValue:
- ConcreteTypeName TypeSequence InterfaceContents
-ConcreteTypeName:
- uint(lengthOfName) [already read=n] name
-InterfaceContents:
- int(concreteTypeId) DelimitedValue
-DelimitedValue:
- uint(length) Value
-ArrayValue:
- uint(n) FieldValue*n [n elements]
-MapValue:
- uint(n) (FieldValue FieldValue)*n [n (key, value) pairs]
-SliceValue:
- uint(n) FieldValue*n [n elements]
-StructValue:
- (uint(fieldDelta) FieldValue)*
-*/
-
-/*
-For implementers and the curious, here is an encoded example. Given
- type Point struct {X, Y int}
-and the value
- p := Point{22, 33}
-the bytes transmitted that encode p will be:
- 1f ff 81 03 01 01 05 50 6f 69 6e 74 01 ff 82 00
- 01 02 01 01 58 01 04 00 01 01 59 01 04 00 00 00
- 07 ff 82 01 2c 01 42 00
-They are determined as follows.
-
-Since this is the first transmission of type Point, the type descriptor
-for Point itself must be sent before the value. This is the first type
-we've sent on this Encoder, so it has type id 65 (0 through 64 are
-reserved).
-
- 1f // This item (a type descriptor) is 31 bytes long.
- ff 81 // The negative of the id for the type we're defining, -65.
- // This is one byte (indicated by FF = -1) followed by
- // ^-65<<1 | 1. The low 1 bit signals to complement the
- // rest upon receipt.
-
- // Now we send a type descriptor, which is itself a struct (wireType).
- // The type of wireType itself is known (it's built in, as is the type of
- // all its components), so we just need to send a *value* of type wireType
- // that represents type "Point".
- // Here starts the encoding of that value.
- // Set the field number implicitly to -1; this is done at the beginning
- // of every struct, including nested structs.
- 03 // Add 3 to field number; now 2 (wireType.structType; this is a struct).
- // structType starts with an embedded CommonType, which appears
- // as a regular structure here too.
- 01 // add 1 to field number (now 0); start of embedded CommonType.
- 01 // add 1 to field number (now 0, the name of the type)
- 05 // string is (unsigned) 5 bytes long
- 50 6f 69 6e 74 // wireType.structType.CommonType.name = "Point"
- 01 // add 1 to field number (now 1, the id of the type)
- ff 82 // wireType.structType.CommonType._id = 65
- 00 // end of embedded wiretype.structType.CommonType struct
- 01 // add 1 to field number (now 1, the field array in wireType.structType)
- 02 // There are two fields in the type (len(structType.field))
- 01 // Start of first field structure; add 1 to get field number 0: field[0].name
- 01 // 1 byte
- 58 // structType.field[0].name = "X"
- 01 // Add 1 to get field number 1: field[0].id
- 04 // structType.field[0].typeId is 2 (signed int).
- 00 // End of structType.field[0]; start structType.field[1]; set field number to -1.
- 01 // Add 1 to get field number 0: field[1].name
- 01 // 1 byte
- 59 // structType.field[1].name = "Y"
- 01 // Add 1 to get field number 1: field[1].id
- 04 // struct.Type.field[1].typeId is 2 (signed int).
- 00 // End of structType.field[1]; end of structType.field.
- 00 // end of wireType.structType structure
- 00 // end of wireType structure
-
-Now we can send the Point value. Again the field number resets to -1:
-
- 07 // this value is 7 bytes long
- ff 82 // the type number, 65 (1 byte (-FF) followed by 65<<1)
- 01 // add one to field number, yielding field 0
- 2c // encoding of signed "22" (0x2c = 44 = 22<<1); Point.x = 22
- 01 // add one to field number, yielding field 1
- 42 // encoding of signed "33" (0x42 = 66 = 33<<1); Point.y = 33
- 00 // end of structure
-
-The type encoding is long and fairly intricate but we send it only once.
-If p is transmitted a second time, the type is already known so the
-output will be just:
-
- 07 ff 82 01 2c 01 42 00
-
-A single non-struct value at top level is transmitted like a field with
-delta tag 0. For instance, a signed integer with value 3 presented as
-the argument to Encode will emit:
-
- 03 04 00 06
-
-Which represents:
-
- 03 // this value is 3 bytes long
- 04 // the type number, 2, represents an integer
- 00 // tag delta 0
- 06 // value 3
-
-*/
diff --git a/contrib/go/_std_1.20/src/encoding/gob/encode.go b/contrib/go/_std_1.20/src/encoding/gob/encode.go
deleted file mode 100644
index 38430342b6..0000000000
--- a/contrib/go/_std_1.20/src/encoding/gob/encode.go
+++ /dev/null
@@ -1,705 +0,0 @@
-// Copyright 2009 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.
-
-//go:generate go run encgen.go -output enc_helpers.go
-
-package gob
-
-import (
- "encoding"
- "encoding/binary"
- "math"
- "math/bits"
- "reflect"
- "sync"
-)
-
-const uint64Size = 8
-
-type encHelper func(state *encoderState, v reflect.Value) bool
-
-// encoderState is the global execution state of an instance of the encoder.
-// Field numbers are delta encoded and always increase. The field
-// number is initialized to -1 so 0 comes out as delta(1). A delta of
-// 0 terminates the structure.
-type encoderState struct {
- enc *Encoder
- b *encBuffer
- sendZero bool // encoding an array element or map key/value pair; send zero values
- fieldnum int // the last field number written.
- buf [1 + uint64Size]byte // buffer used by the encoder; here to avoid allocation.
- next *encoderState // for free list
-}
-
-// encBuffer is an extremely simple, fast implementation of a write-only byte buffer.
-// It never returns a non-nil error, but Write returns an error value so it matches io.Writer.
-type encBuffer struct {
- data []byte
- scratch [64]byte
-}
-
-var encBufferPool = sync.Pool{
- New: func() any {
- e := new(encBuffer)
- e.data = e.scratch[0:0]
- return e
- },
-}
-
-func (e *encBuffer) writeByte(c byte) {
- e.data = append(e.data, c)
-}
-
-func (e *encBuffer) Write(p []byte) (int, error) {
- e.data = append(e.data, p...)
- return len(p), nil
-}
-
-func (e *encBuffer) WriteString(s string) {
- e.data = append(e.data, s...)
-}
-
-func (e *encBuffer) Len() int {
- return len(e.data)
-}
-
-func (e *encBuffer) Bytes() []byte {
- return e.data
-}
-
-func (e *encBuffer) Reset() {
- if len(e.data) >= tooBig {
- e.data = e.scratch[0:0]
- } else {
- e.data = e.data[0:0]
- }
-}
-
-func (enc *Encoder) newEncoderState(b *encBuffer) *encoderState {
- e := enc.freeList
- if e == nil {
- e = new(encoderState)
- e.enc = enc
- } else {
- enc.freeList = e.next
- }
- e.sendZero = false
- e.fieldnum = 0
- e.b = b
- if len(b.data) == 0 {
- b.data = b.scratch[0:0]
- }
- return e
-}
-
-func (enc *Encoder) freeEncoderState(e *encoderState) {
- e.next = enc.freeList
- enc.freeList = e
-}
-
-// Unsigned integers have a two-state encoding. If the number is less
-// than 128 (0 through 0x7F), its value is written directly.
-// Otherwise the value is written in big-endian byte order preceded
-// by the byte length, negated.
-
-// encodeUint writes an encoded unsigned integer to state.b.
-func (state *encoderState) encodeUint(x uint64) {
- if x <= 0x7F {
- state.b.writeByte(uint8(x))
- return
- }
-
- binary.BigEndian.PutUint64(state.buf[1:], x)
- bc := bits.LeadingZeros64(x) >> 3 // 8 - bytelen(x)
- state.buf[bc] = uint8(bc - uint64Size) // and then we subtract 8 to get -bytelen(x)
-
- state.b.Write(state.buf[bc : uint64Size+1])
-}
-
-// encodeInt writes an encoded signed integer to state.w.
-// The low bit of the encoding says whether to bit complement the (other bits of the)
-// uint to recover the int.
-func (state *encoderState) encodeInt(i int64) {
- var x uint64
- if i < 0 {
- x = uint64(^i<<1) | 1
- } else {
- x = uint64(i << 1)
- }
- state.encodeUint(x)
-}
-
-// encOp is the signature of an encoding operator for a given type.
-type encOp func(i *encInstr, state *encoderState, v reflect.Value)
-
-// The 'instructions' of the encoding machine
-type encInstr struct {
- op encOp
- field int // field number in input
- index []int // struct index
- indir int // how many pointer indirections to reach the value in the struct
-}
-
-// update emits a field number and updates the state to record its value for delta encoding.
-// If the instruction pointer is nil, it does nothing
-func (state *encoderState) update(instr *encInstr) {
- if instr != nil {
- state.encodeUint(uint64(instr.field - state.fieldnum))
- state.fieldnum = instr.field
- }
-}
-
-// Each encoder for a composite is responsible for handling any
-// indirections associated with the elements of the data structure.
-// If any pointer so reached is nil, no bytes are written. If the
-// data item is zero, no bytes are written. Single values - ints,
-// strings etc. - are indirected before calling their encoders.
-// Otherwise, the output (for a scalar) is the field number, as an
-// encoded integer, followed by the field data in its appropriate
-// format.
-
-// encIndirect dereferences pv indir times and returns the result.
-func encIndirect(pv reflect.Value, indir int) reflect.Value {
- for ; indir > 0; indir-- {
- if pv.IsNil() {
- break
- }
- pv = pv.Elem()
- }
- return pv
-}
-
-// encBool encodes the bool referenced by v as an unsigned 0 or 1.
-func encBool(i *encInstr, state *encoderState, v reflect.Value) {
- b := v.Bool()
- if b || state.sendZero {
- state.update(i)
- if b {
- state.encodeUint(1)
- } else {
- state.encodeUint(0)
- }
- }
-}
-
-// encInt encodes the signed integer (int int8 int16 int32 int64) referenced by v.
-func encInt(i *encInstr, state *encoderState, v reflect.Value) {
- value := v.Int()
- if value != 0 || state.sendZero {
- state.update(i)
- state.encodeInt(value)
- }
-}
-
-// encUint encodes the unsigned integer (uint uint8 uint16 uint32 uint64 uintptr) referenced by v.
-func encUint(i *encInstr, state *encoderState, v reflect.Value) {
- value := v.Uint()
- if value != 0 || state.sendZero {
- state.update(i)
- state.encodeUint(value)
- }
-}
-
-// floatBits returns a uint64 holding the bits of a floating-point number.
-// Floating-point numbers are transmitted as uint64s holding the bits
-// of the underlying representation. They are sent byte-reversed, with
-// the exponent end coming out first, so integer floating point numbers
-// (for example) transmit more compactly. This routine does the
-// swizzling.
-func floatBits(f float64) uint64 {
- u := math.Float64bits(f)
- return bits.ReverseBytes64(u)
-}
-
-// encFloat encodes the floating point value (float32 float64) referenced by v.
-func encFloat(i *encInstr, state *encoderState, v reflect.Value) {
- f := v.Float()
- if f != 0 || state.sendZero {
- bits := floatBits(f)
- state.update(i)
- state.encodeUint(bits)
- }
-}
-
-// encComplex encodes the complex value (complex64 complex128) referenced by v.
-// Complex numbers are just a pair of floating-point numbers, real part first.
-func encComplex(i *encInstr, state *encoderState, v reflect.Value) {
- c := v.Complex()
- if c != 0+0i || state.sendZero {
- rpart := floatBits(real(c))
- ipart := floatBits(imag(c))
- state.update(i)
- state.encodeUint(rpart)
- state.encodeUint(ipart)
- }
-}
-
-// encUint8Array encodes the byte array referenced by v.
-// Byte arrays are encoded as an unsigned count followed by the raw bytes.
-func encUint8Array(i *encInstr, state *encoderState, v reflect.Value) {
- b := v.Bytes()
- if len(b) > 0 || state.sendZero {
- state.update(i)
- state.encodeUint(uint64(len(b)))
- state.b.Write(b)
- }
-}
-
-// encString encodes the string referenced by v.
-// Strings are encoded as an unsigned count followed by the raw bytes.
-func encString(i *encInstr, state *encoderState, v reflect.Value) {
- s := v.String()
- if len(s) > 0 || state.sendZero {
- state.update(i)
- state.encodeUint(uint64(len(s)))
- state.b.WriteString(s)
- }
-}
-
-// encStructTerminator encodes the end of an encoded struct
-// as delta field number of 0.
-func encStructTerminator(i *encInstr, state *encoderState, v reflect.Value) {
- state.encodeUint(0)
-}
-
-// Execution engine
-
-// encEngine an array of instructions indexed by field number of the encoding
-// data, typically a struct. It is executed top to bottom, walking the struct.
-type encEngine struct {
- instr []encInstr
-}
-
-const singletonField = 0
-
-// valid reports whether the value is valid and a non-nil pointer.
-// (Slices, maps, and chans take care of themselves.)
-func valid(v reflect.Value) bool {
- switch v.Kind() {
- case reflect.Invalid:
- return false
- case reflect.Pointer:
- return !v.IsNil()
- }
- return true
-}
-
-// encodeSingle encodes a single top-level non-struct value.
-func (enc *Encoder) encodeSingle(b *encBuffer, engine *encEngine, value reflect.Value) {
- state := enc.newEncoderState(b)
- defer enc.freeEncoderState(state)
- state.fieldnum = singletonField
- // There is no surrounding struct to frame the transmission, so we must
- // generate data even if the item is zero. To do this, set sendZero.
- state.sendZero = true
- instr := &engine.instr[singletonField]
- if instr.indir > 0 {
- value = encIndirect(value, instr.indir)
- }
- if valid(value) {
- instr.op(instr, state, value)
- }
-}
-
-// encodeStruct encodes a single struct value.
-func (enc *Encoder) encodeStruct(b *encBuffer, engine *encEngine, value reflect.Value) {
- if !valid(value) {
- return
- }
- state := enc.newEncoderState(b)
- defer enc.freeEncoderState(state)
- state.fieldnum = -1
- for i := 0; i < len(engine.instr); i++ {
- instr := &engine.instr[i]
- if i >= value.NumField() {
- // encStructTerminator
- instr.op(instr, state, reflect.Value{})
- break
- }
- field := value.FieldByIndex(instr.index)
- if instr.indir > 0 {
- field = encIndirect(field, instr.indir)
- // TODO: Is field guaranteed valid? If so we could avoid this check.
- if !valid(field) {
- continue
- }
- }
- instr.op(instr, state, field)
- }
-}
-
-// encodeArray encodes an array.
-func (enc *Encoder) encodeArray(b *encBuffer, value reflect.Value, op encOp, elemIndir int, length int, helper encHelper) {
- state := enc.newEncoderState(b)
- defer enc.freeEncoderState(state)
- state.fieldnum = -1
- state.sendZero = true
- state.encodeUint(uint64(length))
- if helper != nil && helper(state, value) {
- return
- }
- for i := 0; i < length; i++ {
- elem := value.Index(i)
- if elemIndir > 0 {
- elem = encIndirect(elem, elemIndir)
- // TODO: Is elem guaranteed valid? If so we could avoid this check.
- if !valid(elem) {
- errorf("encodeArray: nil element")
- }
- }
- op(nil, state, elem)
- }
-}
-
-// encodeReflectValue is a helper for maps. It encodes the value v.
-func encodeReflectValue(state *encoderState, v reflect.Value, op encOp, indir int) {
- for i := 0; i < indir && v.IsValid(); i++ {
- v = reflect.Indirect(v)
- }
- if !v.IsValid() {
- errorf("encodeReflectValue: nil element")
- }
- op(nil, state, v)
-}
-
-// encodeMap encodes a map as unsigned count followed by key:value pairs.
-func (enc *Encoder) encodeMap(b *encBuffer, mv reflect.Value, keyOp, elemOp encOp, keyIndir, elemIndir int) {
- state := enc.newEncoderState(b)
- state.fieldnum = -1
- state.sendZero = true
- state.encodeUint(uint64(mv.Len()))
- mi := mv.MapRange()
- for mi.Next() {
- encodeReflectValue(state, mi.Key(), keyOp, keyIndir)
- encodeReflectValue(state, mi.Value(), elemOp, elemIndir)
- }
- enc.freeEncoderState(state)
-}
-
-// encodeInterface encodes the interface value iv.
-// To send an interface, we send a string identifying the concrete type, followed
-// by the type identifier (which might require defining that type right now), followed
-// by the concrete value. A nil value gets sent as the empty string for the name,
-// followed by no value.
-func (enc *Encoder) encodeInterface(b *encBuffer, iv reflect.Value) {
- // Gobs can encode nil interface values but not typed interface
- // values holding nil pointers, since nil pointers point to no value.
- elem := iv.Elem()
- if elem.Kind() == reflect.Pointer && elem.IsNil() {
- errorf("gob: cannot encode nil pointer of type %s inside interface", iv.Elem().Type())
- }
- state := enc.newEncoderState(b)
- state.fieldnum = -1
- state.sendZero = true
- if iv.IsNil() {
- state.encodeUint(0)
- return
- }
-
- ut := userType(iv.Elem().Type())
- namei, ok := concreteTypeToName.Load(ut.base)
- if !ok {
- errorf("type not registered for interface: %s", ut.base)
- }
- name := namei.(string)
-
- // Send the name.
- state.encodeUint(uint64(len(name)))
- state.b.WriteString(name)
- // Define the type id if necessary.
- enc.sendTypeDescriptor(enc.writer(), state, ut)
- // Send the type id.
- enc.sendTypeId(state, ut)
- // Encode the value into a new buffer. Any nested type definitions
- // should be written to b, before the encoded value.
- enc.pushWriter(b)
- data := encBufferPool.Get().(*encBuffer)
- data.Write(spaceForLength)
- enc.encode(data, elem, ut)
- if enc.err != nil {
- error_(enc.err)
- }
- enc.popWriter()
- enc.writeMessage(b, data)
- data.Reset()
- encBufferPool.Put(data)
- if enc.err != nil {
- error_(enc.err)
- }
- enc.freeEncoderState(state)
-}
-
-// isZero reports whether the value is the zero of its type.
-func isZero(val reflect.Value) bool {
- switch val.Kind() {
- case reflect.Array:
- for i := 0; i < val.Len(); i++ {
- if !isZero(val.Index(i)) {
- return false
- }
- }
- return true
- case reflect.Map, reflect.Slice, reflect.String:
- return val.Len() == 0
- case reflect.Bool:
- return !val.Bool()
- case reflect.Complex64, reflect.Complex128:
- return val.Complex() == 0
- case reflect.Chan, reflect.Func, reflect.Interface, reflect.Pointer:
- return val.IsNil()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return val.Int() == 0
- case reflect.Float32, reflect.Float64:
- return val.Float() == 0
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return val.Uint() == 0
- case reflect.Struct:
- for i := 0; i < val.NumField(); i++ {
- if !isZero(val.Field(i)) {
- return false
- }
- }
- return true
- }
- panic("unknown type in isZero " + val.Type().String())
-}
-
-// encGobEncoder encodes a value that implements the GobEncoder interface.
-// The data is sent as a byte array.
-func (enc *Encoder) encodeGobEncoder(b *encBuffer, ut *userTypeInfo, v reflect.Value) {
- // TODO: should we catch panics from the called method?
-
- var data []byte
- var err error
- // We know it's one of these.
- switch ut.externalEnc {
- case xGob:
- data, err = v.Interface().(GobEncoder).GobEncode()
- case xBinary:
- data, err = v.Interface().(encoding.BinaryMarshaler).MarshalBinary()
- case xText:
- data, err = v.Interface().(encoding.TextMarshaler).MarshalText()
- }
- if err != nil {
- error_(err)
- }
- state := enc.newEncoderState(b)
- state.fieldnum = -1
- state.encodeUint(uint64(len(data)))
- state.b.Write(data)
- enc.freeEncoderState(state)
-}
-
-var encOpTable = [...]encOp{
- reflect.Bool: encBool,
- reflect.Int: encInt,
- reflect.Int8: encInt,
- reflect.Int16: encInt,
- reflect.Int32: encInt,
- reflect.Int64: encInt,
- reflect.Uint: encUint,
- reflect.Uint8: encUint,
- reflect.Uint16: encUint,
- reflect.Uint32: encUint,
- reflect.Uint64: encUint,
- reflect.Uintptr: encUint,
- reflect.Float32: encFloat,
- reflect.Float64: encFloat,
- reflect.Complex64: encComplex,
- reflect.Complex128: encComplex,
- reflect.String: encString,
-}
-
-// encOpFor returns (a pointer to) the encoding op for the base type under rt and
-// the indirection count to reach it.
-func encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp, building map[*typeInfo]bool) (*encOp, int) {
- ut := userType(rt)
- // If the type implements GobEncoder, we handle it without further processing.
- if ut.externalEnc != 0 {
- return gobEncodeOpFor(ut)
- }
- // If this type is already in progress, it's a recursive type (e.g. map[string]*T).
- // Return the pointer to the op we're already building.
- if opPtr := inProgress[rt]; opPtr != nil {
- return opPtr, ut.indir
- }
- typ := ut.base
- indir := ut.indir
- k := typ.Kind()
- var op encOp
- if int(k) < len(encOpTable) {
- op = encOpTable[k]
- }
- if op == nil {
- inProgress[rt] = &op
- // Special cases
- switch t := typ; t.Kind() {
- case reflect.Slice:
- if t.Elem().Kind() == reflect.Uint8 {
- op = encUint8Array
- break
- }
- // Slices have a header; we decode it to find the underlying array.
- elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
- helper := encSliceHelper[t.Elem().Kind()]
- op = func(i *encInstr, state *encoderState, slice reflect.Value) {
- if !state.sendZero && slice.Len() == 0 {
- return
- }
- state.update(i)
- state.enc.encodeArray(state.b, slice, *elemOp, elemIndir, slice.Len(), helper)
- }
- case reflect.Array:
- // True arrays have size in the type.
- elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
- helper := encArrayHelper[t.Elem().Kind()]
- op = func(i *encInstr, state *encoderState, array reflect.Value) {
- state.update(i)
- state.enc.encodeArray(state.b, array, *elemOp, elemIndir, array.Len(), helper)
- }
- case reflect.Map:
- keyOp, keyIndir := encOpFor(t.Key(), inProgress, building)
- elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
- op = func(i *encInstr, state *encoderState, mv reflect.Value) {
- // We send zero-length (but non-nil) maps because the
- // receiver might want to use the map. (Maps don't use append.)
- if !state.sendZero && mv.IsNil() {
- return
- }
- state.update(i)
- state.enc.encodeMap(state.b, mv, *keyOp, *elemOp, keyIndir, elemIndir)
- }
- case reflect.Struct:
- // Generate a closure that calls out to the engine for the nested type.
- getEncEngine(userType(typ), building)
- info := mustGetTypeInfo(typ)
- op = func(i *encInstr, state *encoderState, sv reflect.Value) {
- state.update(i)
- // indirect through info to delay evaluation for recursive structs
- enc := info.encoder.Load()
- state.enc.encodeStruct(state.b, enc, sv)
- }
- case reflect.Interface:
- op = func(i *encInstr, state *encoderState, iv reflect.Value) {
- if !state.sendZero && (!iv.IsValid() || iv.IsNil()) {
- return
- }
- state.update(i)
- state.enc.encodeInterface(state.b, iv)
- }
- }
- }
- if op == nil {
- errorf("can't happen: encode type %s", rt)
- }
- return &op, indir
-}
-
-// gobEncodeOpFor returns the op for a type that is known to implement GobEncoder.
-func gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) {
- rt := ut.user
- if ut.encIndir == -1 {
- rt = reflect.PointerTo(rt)
- } else if ut.encIndir > 0 {
- for i := int8(0); i < ut.encIndir; i++ {
- rt = rt.Elem()
- }
- }
- var op encOp
- op = func(i *encInstr, state *encoderState, v reflect.Value) {
- if ut.encIndir == -1 {
- // Need to climb up one level to turn value into pointer.
- if !v.CanAddr() {
- errorf("unaddressable value of type %s", rt)
- }
- v = v.Addr()
- }
- if !state.sendZero && isZero(v) {
- return
- }
- state.update(i)
- state.enc.encodeGobEncoder(state.b, ut, v)
- }
- return &op, int(ut.encIndir) // encIndir: op will get called with p == address of receiver.
-}
-
-// compileEnc returns the engine to compile the type.
-func compileEnc(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
- srt := ut.base
- engine := new(encEngine)
- seen := make(map[reflect.Type]*encOp)
- rt := ut.base
- if ut.externalEnc != 0 {
- rt = ut.user
- }
- if ut.externalEnc == 0 && srt.Kind() == reflect.Struct {
- for fieldNum, wireFieldNum := 0, 0; fieldNum < srt.NumField(); fieldNum++ {
- f := srt.Field(fieldNum)
- if !isSent(&f) {
- continue
- }
- op, indir := encOpFor(f.Type, seen, building)
- engine.instr = append(engine.instr, encInstr{*op, wireFieldNum, f.Index, indir})
- wireFieldNum++
- }
- if srt.NumField() > 0 && len(engine.instr) == 0 {
- errorf("type %s has no exported fields", rt)
- }
- engine.instr = append(engine.instr, encInstr{encStructTerminator, 0, nil, 0})
- } else {
- engine.instr = make([]encInstr, 1)
- op, indir := encOpFor(rt, seen, building)
- engine.instr[0] = encInstr{*op, singletonField, nil, indir}
- }
- return engine
-}
-
-// getEncEngine returns the engine to compile the type.
-func getEncEngine(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
- info, err := getTypeInfo(ut)
- if err != nil {
- error_(err)
- }
- enc := info.encoder.Load()
- if enc == nil {
- enc = buildEncEngine(info, ut, building)
- }
- return enc
-}
-
-func buildEncEngine(info *typeInfo, ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
- // Check for recursive types.
- if building != nil && building[info] {
- return nil
- }
- info.encInit.Lock()
- defer info.encInit.Unlock()
- enc := info.encoder.Load()
- if enc == nil {
- if building == nil {
- building = make(map[*typeInfo]bool)
- }
- building[info] = true
- enc = compileEnc(ut, building)
- info.encoder.Store(enc)
- }
- return enc
-}
-
-func (enc *Encoder) encode(b *encBuffer, value reflect.Value, ut *userTypeInfo) {
- defer catchError(&enc.err)
- engine := getEncEngine(ut, nil)
- indir := ut.indir
- if ut.externalEnc != 0 {
- indir = int(ut.encIndir)
- }
- for i := 0; i < indir; i++ {
- value = reflect.Indirect(value)
- }
- if ut.externalEnc == 0 && value.Type().Kind() == reflect.Struct {
- enc.encodeStruct(b, engine, value)
- } else {
- enc.encodeSingle(b, engine, value)
- }
-}
diff --git a/contrib/go/_std_1.20/src/encoding/gob/encoder.go b/contrib/go/_std_1.20/src/encoding/gob/encoder.go
deleted file mode 100644
index 5a80e6c3e8..0000000000
--- a/contrib/go/_std_1.20/src/encoding/gob/encoder.go
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright 2009 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 gob
-
-import (
- "errors"
- "io"
- "reflect"
- "sync"
-)
-
-// An Encoder manages the transmission of type and data information to the
-// other side of a connection. It is safe for concurrent use by multiple
-// goroutines.
-type Encoder struct {
- mutex sync.Mutex // each item must be sent atomically
- w []io.Writer // where to send the data
- sent map[reflect.Type]typeId // which types we've already sent
- countState *encoderState // stage for writing counts
- freeList *encoderState // list of free encoderStates; avoids reallocation
- byteBuf encBuffer // buffer for top-level encoderState
- err error
-}
-
-// Before we encode a message, we reserve space at the head of the
-// buffer in which to encode its length. This means we can use the
-// buffer to assemble the message without another allocation.
-const maxLength = 9 // Maximum size of an encoded length.
-var spaceForLength = make([]byte, maxLength)
-
-// NewEncoder returns a new encoder that will transmit on the io.Writer.
-func NewEncoder(w io.Writer) *Encoder {
- enc := new(Encoder)
- enc.w = []io.Writer{w}
- enc.sent = make(map[reflect.Type]typeId)
- enc.countState = enc.newEncoderState(new(encBuffer))
- return enc
-}
-
-// writer() returns the innermost writer the encoder is using
-func (enc *Encoder) writer() io.Writer {
- return enc.w[len(enc.w)-1]
-}
-
-// pushWriter adds a writer to the encoder.
-func (enc *Encoder) pushWriter(w io.Writer) {
- enc.w = append(enc.w, w)
-}
-
-// popWriter pops the innermost writer.
-func (enc *Encoder) popWriter() {
- enc.w = enc.w[0 : len(enc.w)-1]
-}
-
-func (enc *Encoder) setError(err error) {
- if enc.err == nil { // remember the first.
- enc.err = err
- }
-}
-
-// writeMessage sends the data item preceded by a unsigned count of its length.
-func (enc *Encoder) writeMessage(w io.Writer, b *encBuffer) {
- // Space has been reserved for the length at the head of the message.
- // This is a little dirty: we grab the slice from the bytes.Buffer and massage
- // it by hand.
- message := b.Bytes()
- messageLen := len(message) - maxLength
- // Length cannot be bigger than the decoder can handle.
- if messageLen >= tooBig {
- enc.setError(errors.New("gob: encoder: message too big"))
- return
- }
- // Encode the length.
- enc.countState.b.Reset()
- enc.countState.encodeUint(uint64(messageLen))
- // Copy the length to be a prefix of the message.
- offset := maxLength - enc.countState.b.Len()
- copy(message[offset:], enc.countState.b.Bytes())
- // Write the data.
- _, err := w.Write(message[offset:])
- // Drain the buffer and restore the space at the front for the count of the next message.
- b.Reset()
- b.Write(spaceForLength)
- if err != nil {
- enc.setError(err)
- }
-}
-
-// sendActualType sends the requested type, without further investigation, unless
-// it's been sent before.
-func (enc *Encoder) sendActualType(w io.Writer, state *encoderState, ut *userTypeInfo, actual reflect.Type) (sent bool) {
- if _, alreadySent := enc.sent[actual]; alreadySent {
- return false
- }
- info, err := getTypeInfo(ut)
- if err != nil {
- enc.setError(err)
- return
- }
- // Send the pair (-id, type)
- // Id:
- state.encodeInt(-int64(info.id))
- // Type:
- enc.encode(state.b, reflect.ValueOf(info.wire), wireTypeUserInfo)
- enc.writeMessage(w, state.b)
- if enc.err != nil {
- return
- }
-
- // Remember we've sent this type, both what the user gave us and the base type.
- enc.sent[ut.base] = info.id
- if ut.user != ut.base {
- enc.sent[ut.user] = info.id
- }
- // Now send the inner types
- switch st := actual; st.Kind() {
- case reflect.Struct:
- for i := 0; i < st.NumField(); i++ {
- if isExported(st.Field(i).Name) {
- enc.sendType(w, state, st.Field(i).Type)
- }
- }
- case reflect.Array, reflect.Slice:
- enc.sendType(w, state, st.Elem())
- case reflect.Map:
- enc.sendType(w, state, st.Key())
- enc.sendType(w, state, st.Elem())
- }
- return true
-}
-
-// sendType sends the type info to the other side, if necessary.
-func (enc *Encoder) sendType(w io.Writer, state *encoderState, origt reflect.Type) (sent bool) {
- ut := userType(origt)
- if ut.externalEnc != 0 {
- // The rules are different: regardless of the underlying type's representation,
- // we need to tell the other side that the base type is a GobEncoder.
- return enc.sendActualType(w, state, ut, ut.base)
- }
-
- // It's a concrete value, so drill down to the base type.
- switch rt := ut.base; rt.Kind() {
- default:
- // Basic types and interfaces do not need to be described.
- return
- case reflect.Slice:
- // If it's []uint8, don't send; it's considered basic.
- if rt.Elem().Kind() == reflect.Uint8 {
- return
- }
- // Otherwise we do send.
- break
- case reflect.Array:
- // arrays must be sent so we know their lengths and element types.
- break
- case reflect.Map:
- // maps must be sent so we know their lengths and key/value types.
- break
- case reflect.Struct:
- // structs must be sent so we know their fields.
- break
- case reflect.Chan, reflect.Func:
- // If we get here, it's a field of a struct; ignore it.
- return
- }
-
- return enc.sendActualType(w, state, ut, ut.base)
-}
-
-// Encode transmits the data item represented by the empty interface value,
-// guaranteeing that all necessary type information has been transmitted first.
-// Passing a nil pointer to Encoder will panic, as they cannot be transmitted by gob.
-func (enc *Encoder) Encode(e any) error {
- return enc.EncodeValue(reflect.ValueOf(e))
-}
-
-// sendTypeDescriptor makes sure the remote side knows about this type.
-// It will send a descriptor if this is the first time the type has been
-// sent.
-func (enc *Encoder) sendTypeDescriptor(w io.Writer, state *encoderState, ut *userTypeInfo) {
- // Make sure the type is known to the other side.
- // First, have we already sent this type?
- rt := ut.base
- if ut.externalEnc != 0 {
- rt = ut.user
- }
- if _, alreadySent := enc.sent[rt]; !alreadySent {
- // No, so send it.
- sent := enc.sendType(w, state, rt)
- if enc.err != nil {
- return
- }
- // If the type info has still not been transmitted, it means we have
- // a singleton basic type (int, []byte etc.) at top level. We don't
- // need to send the type info but we do need to update enc.sent.
- if !sent {
- info, err := getTypeInfo(ut)
- if err != nil {
- enc.setError(err)
- return
- }
- enc.sent[rt] = info.id
- }
- }
-}
-
-// sendTypeId sends the id, which must have already been defined.
-func (enc *Encoder) sendTypeId(state *encoderState, ut *userTypeInfo) {
- // Identify the type of this top-level value.
- state.encodeInt(int64(enc.sent[ut.base]))
-}
-
-// EncodeValue transmits the data item represented by the reflection value,
-// guaranteeing that all necessary type information has been transmitted first.
-// Passing a nil pointer to EncodeValue will panic, as they cannot be transmitted by gob.
-func (enc *Encoder) EncodeValue(value reflect.Value) error {
- if value.Kind() == reflect.Invalid {
- return errors.New("gob: cannot encode nil value")
- }
- if value.Kind() == reflect.Pointer && value.IsNil() {
- panic("gob: cannot encode nil pointer of type " + value.Type().String())
- }
-
- // Make sure we're single-threaded through here, so multiple
- // goroutines can share an encoder.
- enc.mutex.Lock()
- defer enc.mutex.Unlock()
-
- // Remove any nested writers remaining due to previous errors.
- enc.w = enc.w[0:1]
-
- ut, err := validUserType(value.Type())
- if err != nil {
- return err
- }
-
- enc.err = nil
- enc.byteBuf.Reset()
- enc.byteBuf.Write(spaceForLength)
- state := enc.newEncoderState(&enc.byteBuf)
-
- enc.sendTypeDescriptor(enc.writer(), state, ut)
- enc.sendTypeId(state, ut)
- if enc.err != nil {
- return enc.err
- }
-
- // Encode the object.
- enc.encode(state.b, value, ut)
- if enc.err == nil {
- enc.writeMessage(enc.writer(), state.b)
- }
-
- enc.freeEncoderState(state)
- return enc.err
-}
diff --git a/contrib/go/_std_1.20/src/encoding/gob/type.go b/contrib/go/_std_1.20/src/encoding/gob/type.go
deleted file mode 100644
index 3114cb0f98..0000000000
--- a/contrib/go/_std_1.20/src/encoding/gob/type.go
+++ /dev/null
@@ -1,913 +0,0 @@
-// Copyright 2009 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 gob
-
-import (
- "encoding"
- "errors"
- "fmt"
- "os"
- "reflect"
- "sync"
- "sync/atomic"
- "unicode"
- "unicode/utf8"
-)
-
-// userTypeInfo stores the information associated with a type the user has handed
-// to the package. It's computed once and stored in a map keyed by reflection
-// type.
-type userTypeInfo struct {
- user reflect.Type // the type the user handed us
- base reflect.Type // the base type after all indirections
- indir int // number of indirections to reach the base type
- externalEnc int // xGob, xBinary, or xText
- externalDec int // xGob, xBinary or xText
- encIndir int8 // number of indirections to reach the receiver type; may be negative
- decIndir int8 // number of indirections to reach the receiver type; may be negative
-}
-
-// externalEncoding bits
-const (
- xGob = 1 + iota // GobEncoder or GobDecoder
- xBinary // encoding.BinaryMarshaler or encoding.BinaryUnmarshaler
- xText // encoding.TextMarshaler or encoding.TextUnmarshaler
-)
-
-var userTypeCache sync.Map // map[reflect.Type]*userTypeInfo
-
-// validUserType returns, and saves, the information associated with user-provided type rt.
-// If the user type is not valid, err will be non-nil. To be used when the error handler
-// is not set up.
-func validUserType(rt reflect.Type) (*userTypeInfo, error) {
- if ui, ok := userTypeCache.Load(rt); ok {
- return ui.(*userTypeInfo), nil
- }
-
- // Construct a new userTypeInfo and atomically add it to the userTypeCache.
- // If we lose the race, we'll waste a little CPU and create a little garbage
- // but return the existing value anyway.
-
- ut := new(userTypeInfo)
- ut.base = rt
- ut.user = rt
- // A type that is just a cycle of pointers (such as type T *T) cannot
- // be represented in gobs, which need some concrete data. We use a
- // cycle detection algorithm from Knuth, Vol 2, Section 3.1, Ex 6,
- // pp 539-540. As we step through indirections, run another type at
- // half speed. If they meet up, there's a cycle.
- slowpoke := ut.base // walks half as fast as ut.base
- for {
- pt := ut.base
- if pt.Kind() != reflect.Pointer {
- break
- }
- ut.base = pt.Elem()
- if ut.base == slowpoke { // ut.base lapped slowpoke
- // recursive pointer type.
- return nil, errors.New("can't represent recursive pointer type " + ut.base.String())
- }
- if ut.indir%2 == 0 {
- slowpoke = slowpoke.Elem()
- }
- ut.indir++
- }
-
- if ok, indir := implementsInterface(ut.user, gobEncoderInterfaceType); ok {
- ut.externalEnc, ut.encIndir = xGob, indir
- } else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok {
- ut.externalEnc, ut.encIndir = xBinary, indir
- }
-
- // NOTE(rsc): Would like to allow MarshalText here, but results in incompatibility
- // with older encodings for net.IP. See golang.org/issue/6760.
- // } else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
- // ut.externalEnc, ut.encIndir = xText, indir
- // }
-
- if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok {
- ut.externalDec, ut.decIndir = xGob, indir
- } else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok {
- ut.externalDec, ut.decIndir = xBinary, indir
- }
-
- // See note above.
- // } else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
- // ut.externalDec, ut.decIndir = xText, indir
- // }
-
- ui, _ := userTypeCache.LoadOrStore(rt, ut)
- return ui.(*userTypeInfo), nil
-}
-
-var (
- gobEncoderInterfaceType = reflect.TypeOf((*GobEncoder)(nil)).Elem()
- gobDecoderInterfaceType = reflect.TypeOf((*GobDecoder)(nil)).Elem()
- binaryMarshalerInterfaceType = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem()
- binaryUnmarshalerInterfaceType = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem()
- textMarshalerInterfaceType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
- textUnmarshalerInterfaceType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
-)
-
-// implementsInterface reports whether the type implements the
-// gobEncoder/gobDecoder interface.
-// It also returns the number of indirections required to get to the
-// implementation.
-func implementsInterface(typ, gobEncDecType reflect.Type) (success bool, indir int8) {
- if typ == nil {
- return
- }
- rt := typ
- // The type might be a pointer and we need to keep
- // dereferencing to the base type until we find an implementation.
- for {
- if rt.Implements(gobEncDecType) {
- return true, indir
- }
- if p := rt; p.Kind() == reflect.Pointer {
- indir++
- if indir > 100 { // insane number of indirections
- return false, 0
- }
- rt = p.Elem()
- continue
- }
- break
- }
- // No luck yet, but if this is a base type (non-pointer), the pointer might satisfy.
- if typ.Kind() != reflect.Pointer {
- // Not a pointer, but does the pointer work?
- if reflect.PointerTo(typ).Implements(gobEncDecType) {
- return true, -1
- }
- }
- return false, 0
-}
-
-// userType returns, and saves, the information associated with user-provided type rt.
-// If the user type is not valid, it calls error.
-func userType(rt reflect.Type) *userTypeInfo {
- ut, err := validUserType(rt)
- if err != nil {
- error_(err)
- }
- return ut
-}
-
-// A typeId represents a gob Type as an integer that can be passed on the wire.
-// Internally, typeIds are used as keys to a map to recover the underlying type info.
-type typeId int32
-
-var nextId typeId // incremented for each new type we build
-var typeLock sync.Mutex // set while building a type
-const firstUserId = 64 // lowest id number granted to user
-
-type gobType interface {
- id() typeId
- setId(id typeId)
- name() string
- string() string // not public; only for debugging
- safeString(seen map[typeId]bool) string
-}
-
-var types = make(map[reflect.Type]gobType)
-var idToType = make(map[typeId]gobType)
-var builtinIdToType map[typeId]gobType // set in init() after builtins are established
-
-func setTypeId(typ gobType) {
- // When building recursive types, someone may get there before us.
- if typ.id() != 0 {
- return
- }
- nextId++
- typ.setId(nextId)
- idToType[nextId] = typ
-}
-
-func (t typeId) gobType() gobType {
- if t == 0 {
- return nil
- }
- return idToType[t]
-}
-
-// string returns the string representation of the type associated with the typeId.
-func (t typeId) string() string {
- if t.gobType() == nil {
- return "<nil>"
- }
- return t.gobType().string()
-}
-
-// Name returns the name of the type associated with the typeId.
-func (t typeId) name() string {
- if t.gobType() == nil {
- return "<nil>"
- }
- return t.gobType().name()
-}
-
-// CommonType holds elements of all types.
-// It is a historical artifact, kept for binary compatibility and exported
-// only for the benefit of the package's encoding of type descriptors. It is
-// not intended for direct use by clients.
-type CommonType struct {
- Name string
- Id typeId
-}
-
-func (t *CommonType) id() typeId { return t.Id }
-
-func (t *CommonType) setId(id typeId) { t.Id = id }
-
-func (t *CommonType) string() string { return t.Name }
-
-func (t *CommonType) safeString(seen map[typeId]bool) string {
- return t.Name
-}
-
-func (t *CommonType) name() string { return t.Name }
-
-// Create and check predefined types
-// The string for tBytes is "bytes" not "[]byte" to signify its specialness.
-
-var (
- // Primordial types, needed during initialization.
- // Always passed as pointers so the interface{} type
- // goes through without losing its interfaceness.
- tBool = bootstrapType("bool", (*bool)(nil), 1)
- tInt = bootstrapType("int", (*int)(nil), 2)
- tUint = bootstrapType("uint", (*uint)(nil), 3)
- tFloat = bootstrapType("float", (*float64)(nil), 4)
- tBytes = bootstrapType("bytes", (*[]byte)(nil), 5)
- tString = bootstrapType("string", (*string)(nil), 6)
- tComplex = bootstrapType("complex", (*complex128)(nil), 7)
- tInterface = bootstrapType("interface", (*any)(nil), 8)
- // Reserve some Ids for compatible expansion
- tReserved7 = bootstrapType("_reserved1", (*struct{ r7 int })(nil), 9)
- tReserved6 = bootstrapType("_reserved1", (*struct{ r6 int })(nil), 10)
- tReserved5 = bootstrapType("_reserved1", (*struct{ r5 int })(nil), 11)
- tReserved4 = bootstrapType("_reserved1", (*struct{ r4 int })(nil), 12)
- tReserved3 = bootstrapType("_reserved1", (*struct{ r3 int })(nil), 13)
- tReserved2 = bootstrapType("_reserved1", (*struct{ r2 int })(nil), 14)
- tReserved1 = bootstrapType("_reserved1", (*struct{ r1 int })(nil), 15)
-)
-
-// Predefined because it's needed by the Decoder
-var tWireType = mustGetTypeInfo(reflect.TypeOf(wireType{})).id
-var wireTypeUserInfo *userTypeInfo // userTypeInfo of (*wireType)
-
-func init() {
- // Some magic numbers to make sure there are no surprises.
- checkId(16, tWireType)
- checkId(17, mustGetTypeInfo(reflect.TypeOf(arrayType{})).id)
- checkId(18, mustGetTypeInfo(reflect.TypeOf(CommonType{})).id)
- checkId(19, mustGetTypeInfo(reflect.TypeOf(sliceType{})).id)
- checkId(20, mustGetTypeInfo(reflect.TypeOf(structType{})).id)
- checkId(21, mustGetTypeInfo(reflect.TypeOf(fieldType{})).id)
- checkId(23, mustGetTypeInfo(reflect.TypeOf(mapType{})).id)
-
- builtinIdToType = make(map[typeId]gobType)
- for k, v := range idToType {
- builtinIdToType[k] = v
- }
-
- // Move the id space upwards to allow for growth in the predefined world
- // without breaking existing files.
- if nextId > firstUserId {
- panic(fmt.Sprintln("nextId too large:", nextId))
- }
- nextId = firstUserId
- registerBasics()
- wireTypeUserInfo = userType(reflect.TypeOf((*wireType)(nil)))
-}
-
-// Array type
-type arrayType struct {
- CommonType
- Elem typeId
- Len int
-}
-
-func newArrayType(name string) *arrayType {
- a := &arrayType{CommonType{Name: name}, 0, 0}
- return a
-}
-
-func (a *arrayType) init(elem gobType, len int) {
- // Set our type id before evaluating the element's, in case it's our own.
- setTypeId(a)
- a.Elem = elem.id()
- a.Len = len
-}
-
-func (a *arrayType) safeString(seen map[typeId]bool) string {
- if seen[a.Id] {
- return a.Name
- }
- seen[a.Id] = true
- return fmt.Sprintf("[%d]%s", a.Len, a.Elem.gobType().safeString(seen))
-}
-
-func (a *arrayType) string() string { return a.safeString(make(map[typeId]bool)) }
-
-// GobEncoder type (something that implements the GobEncoder interface)
-type gobEncoderType struct {
- CommonType
-}
-
-func newGobEncoderType(name string) *gobEncoderType {
- g := &gobEncoderType{CommonType{Name: name}}
- setTypeId(g)
- return g
-}
-
-func (g *gobEncoderType) safeString(seen map[typeId]bool) string {
- return g.Name
-}
-
-func (g *gobEncoderType) string() string { return g.Name }
-
-// Map type
-type mapType struct {
- CommonType
- Key typeId
- Elem typeId
-}
-
-func newMapType(name string) *mapType {
- m := &mapType{CommonType{Name: name}, 0, 0}
- return m
-}
-
-func (m *mapType) init(key, elem gobType) {
- // Set our type id before evaluating the element's, in case it's our own.
- setTypeId(m)
- m.Key = key.id()
- m.Elem = elem.id()
-}
-
-func (m *mapType) safeString(seen map[typeId]bool) string {
- if seen[m.Id] {
- return m.Name
- }
- seen[m.Id] = true
- key := m.Key.gobType().safeString(seen)
- elem := m.Elem.gobType().safeString(seen)
- return fmt.Sprintf("map[%s]%s", key, elem)
-}
-
-func (m *mapType) string() string { return m.safeString(make(map[typeId]bool)) }
-
-// Slice type
-type sliceType struct {
- CommonType
- Elem typeId
-}
-
-func newSliceType(name string) *sliceType {
- s := &sliceType{CommonType{Name: name}, 0}
- return s
-}
-
-func (s *sliceType) init(elem gobType) {
- // Set our type id before evaluating the element's, in case it's our own.
- setTypeId(s)
- // See the comments about ids in newTypeObject. Only slices and
- // structs have mutual recursion.
- if elem.id() == 0 {
- setTypeId(elem)
- }
- s.Elem = elem.id()
-}
-
-func (s *sliceType) safeString(seen map[typeId]bool) string {
- if seen[s.Id] {
- return s.Name
- }
- seen[s.Id] = true
- return fmt.Sprintf("[]%s", s.Elem.gobType().safeString(seen))
-}
-
-func (s *sliceType) string() string { return s.safeString(make(map[typeId]bool)) }
-
-// Struct type
-type fieldType struct {
- Name string
- Id typeId
-}
-
-type structType struct {
- CommonType
- Field []*fieldType
-}
-
-func (s *structType) safeString(seen map[typeId]bool) string {
- if s == nil {
- return "<nil>"
- }
- if _, ok := seen[s.Id]; ok {
- return s.Name
- }
- seen[s.Id] = true
- str := s.Name + " = struct { "
- for _, f := range s.Field {
- str += fmt.Sprintf("%s %s; ", f.Name, f.Id.gobType().safeString(seen))
- }
- str += "}"
- return str
-}
-
-func (s *structType) string() string { return s.safeString(make(map[typeId]bool)) }
-
-func newStructType(name string) *structType {
- s := &structType{CommonType{Name: name}, nil}
- // For historical reasons we set the id here rather than init.
- // See the comment in newTypeObject for details.
- setTypeId(s)
- return s
-}
-
-// newTypeObject allocates a gobType for the reflection type rt.
-// Unless ut represents a GobEncoder, rt should be the base type
-// of ut.
-// This is only called from the encoding side. The decoding side
-// works through typeIds and userTypeInfos alone.
-func newTypeObject(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
- // Does this type implement GobEncoder?
- if ut.externalEnc != 0 {
- return newGobEncoderType(name), nil
- }
- var err error
- var type0, type1 gobType
- defer func() {
- if err != nil {
- delete(types, rt)
- }
- }()
- // Install the top-level type before the subtypes (e.g. struct before
- // fields) so recursive types can be constructed safely.
- switch t := rt; t.Kind() {
- // All basic types are easy: they are predefined.
- case reflect.Bool:
- return tBool.gobType(), nil
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return tInt.gobType(), nil
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return tUint.gobType(), nil
-
- case reflect.Float32, reflect.Float64:
- return tFloat.gobType(), nil
-
- case reflect.Complex64, reflect.Complex128:
- return tComplex.gobType(), nil
-
- case reflect.String:
- return tString.gobType(), nil
-
- case reflect.Interface:
- return tInterface.gobType(), nil
-
- case reflect.Array:
- at := newArrayType(name)
- types[rt] = at
- type0, err = getBaseType("", t.Elem())
- if err != nil {
- return nil, err
- }
- // Historical aside:
- // For arrays, maps, and slices, we set the type id after the elements
- // are constructed. This is to retain the order of type id allocation after
- // a fix made to handle recursive types, which changed the order in
- // which types are built. Delaying the setting in this way preserves
- // type ids while allowing recursive types to be described. Structs,
- // done below, were already handling recursion correctly so they
- // assign the top-level id before those of the field.
- at.init(type0, t.Len())
- return at, nil
-
- case reflect.Map:
- mt := newMapType(name)
- types[rt] = mt
- type0, err = getBaseType("", t.Key())
- if err != nil {
- return nil, err
- }
- type1, err = getBaseType("", t.Elem())
- if err != nil {
- return nil, err
- }
- mt.init(type0, type1)
- return mt, nil
-
- case reflect.Slice:
- // []byte == []uint8 is a special case
- if t.Elem().Kind() == reflect.Uint8 {
- return tBytes.gobType(), nil
- }
- st := newSliceType(name)
- types[rt] = st
- type0, err = getBaseType(t.Elem().Name(), t.Elem())
- if err != nil {
- return nil, err
- }
- st.init(type0)
- return st, nil
-
- case reflect.Struct:
- st := newStructType(name)
- types[rt] = st
- idToType[st.id()] = st
- for i := 0; i < t.NumField(); i++ {
- f := t.Field(i)
- if !isSent(&f) {
- continue
- }
- typ := userType(f.Type).base
- tname := typ.Name()
- if tname == "" {
- t := userType(f.Type).base
- tname = t.String()
- }
- gt, err := getBaseType(tname, f.Type)
- if err != nil {
- return nil, err
- }
- // Some mutually recursive types can cause us to be here while
- // still defining the element. Fix the element type id here.
- // We could do this more neatly by setting the id at the start of
- // building every type, but that would break binary compatibility.
- if gt.id() == 0 {
- setTypeId(gt)
- }
- st.Field = append(st.Field, &fieldType{f.Name, gt.id()})
- }
- return st, nil
-
- default:
- return nil, errors.New("gob NewTypeObject can't handle type: " + rt.String())
- }
-}
-
-// isExported reports whether this is an exported - upper case - name.
-func isExported(name string) bool {
- rune, _ := utf8.DecodeRuneInString(name)
- return unicode.IsUpper(rune)
-}
-
-// isSent reports whether this struct field is to be transmitted.
-// It will be transmitted only if it is exported and not a chan or func field
-// or pointer to chan or func.
-func isSent(field *reflect.StructField) bool {
- if !isExported(field.Name) {
- return false
- }
- // If the field is a chan or func or pointer thereto, don't send it.
- // That is, treat it like an unexported field.
- typ := field.Type
- for typ.Kind() == reflect.Pointer {
- typ = typ.Elem()
- }
- if typ.Kind() == reflect.Chan || typ.Kind() == reflect.Func {
- return false
- }
- return true
-}
-
-// getBaseType returns the Gob type describing the given reflect.Type's base type.
-// typeLock must be held.
-func getBaseType(name string, rt reflect.Type) (gobType, error) {
- ut := userType(rt)
- return getType(name, ut, ut.base)
-}
-
-// getType returns the Gob type describing the given reflect.Type.
-// Should be called only when handling GobEncoders/Decoders,
-// which may be pointers. All other types are handled through the
-// base type, never a pointer.
-// typeLock must be held.
-func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
- typ, present := types[rt]
- if present {
- return typ, nil
- }
- typ, err := newTypeObject(name, ut, rt)
- if err == nil {
- types[rt] = typ
- }
- return typ, err
-}
-
-func checkId(want, got typeId) {
- if want != got {
- fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(got), int(want))
- panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string())
- }
-}
-
-// used for building the basic types; called only from init(). the incoming
-// interface always refers to a pointer.
-func bootstrapType(name string, e any, expect typeId) typeId {
- rt := reflect.TypeOf(e).Elem()
- _, present := types[rt]
- if present {
- panic("bootstrap type already present: " + name + ", " + rt.String())
- }
- typ := &CommonType{Name: name}
- types[rt] = typ
- setTypeId(typ)
- checkId(expect, nextId)
- userType(rt) // might as well cache it now
- return nextId
-}
-
-// Representation of the information we send and receive about this type.
-// Each value we send is preceded by its type definition: an encoded int.
-// However, the very first time we send the value, we first send the pair
-// (-id, wireType).
-// For bootstrapping purposes, we assume that the recipient knows how
-// to decode a wireType; it is exactly the wireType struct here, interpreted
-// using the gob rules for sending a structure, except that we assume the
-// ids for wireType and structType etc. are known. The relevant pieces
-// are built in encode.go's init() function.
-// To maintain binary compatibility, if you extend this type, always put
-// the new fields last.
-type wireType struct {
- ArrayT *arrayType
- SliceT *sliceType
- StructT *structType
- MapT *mapType
- GobEncoderT *gobEncoderType
- BinaryMarshalerT *gobEncoderType
- TextMarshalerT *gobEncoderType
-}
-
-func (w *wireType) string() string {
- const unknown = "unknown type"
- if w == nil {
- return unknown
- }
- switch {
- case w.ArrayT != nil:
- return w.ArrayT.Name
- case w.SliceT != nil:
- return w.SliceT.Name
- case w.StructT != nil:
- return w.StructT.Name
- case w.MapT != nil:
- return w.MapT.Name
- case w.GobEncoderT != nil:
- return w.GobEncoderT.Name
- case w.BinaryMarshalerT != nil:
- return w.BinaryMarshalerT.Name
- case w.TextMarshalerT != nil:
- return w.TextMarshalerT.Name
- }
- return unknown
-}
-
-type typeInfo struct {
- id typeId
- encInit sync.Mutex // protects creation of encoder
- encoder atomic.Pointer[encEngine]
- wire *wireType
-}
-
-// typeInfoMap is an atomic pointer to map[reflect.Type]*typeInfo.
-// It's updated copy-on-write. Readers just do an atomic load
-// to get the current version of the map. Writers make a full copy of
-// the map and atomically update the pointer to point to the new map.
-// Under heavy read contention, this is significantly faster than a map
-// protected by a mutex.
-var typeInfoMap atomic.Value
-
-func lookupTypeInfo(rt reflect.Type) *typeInfo {
- m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
- return m[rt]
-}
-
-func getTypeInfo(ut *userTypeInfo) (*typeInfo, error) {
- rt := ut.base
- if ut.externalEnc != 0 {
- // We want the user type, not the base type.
- rt = ut.user
- }
- if info := lookupTypeInfo(rt); info != nil {
- return info, nil
- }
- return buildTypeInfo(ut, rt)
-}
-
-// buildTypeInfo constructs the type information for the type
-// and stores it in the type info map.
-func buildTypeInfo(ut *userTypeInfo, rt reflect.Type) (*typeInfo, error) {
- typeLock.Lock()
- defer typeLock.Unlock()
-
- if info := lookupTypeInfo(rt); info != nil {
- return info, nil
- }
-
- gt, err := getBaseType(rt.Name(), rt)
- if err != nil {
- return nil, err
- }
- info := &typeInfo{id: gt.id()}
-
- if ut.externalEnc != 0 {
- userType, err := getType(rt.Name(), ut, rt)
- if err != nil {
- return nil, err
- }
- gt := userType.id().gobType().(*gobEncoderType)
- switch ut.externalEnc {
- case xGob:
- info.wire = &wireType{GobEncoderT: gt}
- case xBinary:
- info.wire = &wireType{BinaryMarshalerT: gt}
- case xText:
- info.wire = &wireType{TextMarshalerT: gt}
- }
- rt = ut.user
- } else {
- t := info.id.gobType()
- switch typ := rt; typ.Kind() {
- case reflect.Array:
- info.wire = &wireType{ArrayT: t.(*arrayType)}
- case reflect.Map:
- info.wire = &wireType{MapT: t.(*mapType)}
- case reflect.Slice:
- // []byte == []uint8 is a special case handled separately
- if typ.Elem().Kind() != reflect.Uint8 {
- info.wire = &wireType{SliceT: t.(*sliceType)}
- }
- case reflect.Struct:
- info.wire = &wireType{StructT: t.(*structType)}
- }
- }
-
- // Create new map with old contents plus new entry.
- newm := make(map[reflect.Type]*typeInfo)
- m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
- for k, v := range m {
- newm[k] = v
- }
- newm[rt] = info
- typeInfoMap.Store(newm)
- return info, nil
-}
-
-// Called only when a panic is acceptable and unexpected.
-func mustGetTypeInfo(rt reflect.Type) *typeInfo {
- t, err := getTypeInfo(userType(rt))
- if err != nil {
- panic("getTypeInfo: " + err.Error())
- }
- return t
-}
-
-// GobEncoder is the interface describing data that provides its own
-// representation for encoding values for transmission to a GobDecoder.
-// A type that implements GobEncoder and GobDecoder has complete
-// control over the representation of its data and may therefore
-// contain things such as private fields, channels, and functions,
-// which are not usually transmissible in gob streams.
-//
-// Note: Since gobs can be stored permanently, it is good design
-// to guarantee the encoding used by a GobEncoder is stable as the
-// software evolves. For instance, it might make sense for GobEncode
-// to include a version number in the encoding.
-type GobEncoder interface {
- // GobEncode returns a byte slice representing the encoding of the
- // receiver for transmission to a GobDecoder, usually of the same
- // concrete type.
- GobEncode() ([]byte, error)
-}
-
-// GobDecoder is the interface describing data that provides its own
-// routine for decoding transmitted values sent by a GobEncoder.
-type GobDecoder interface {
- // GobDecode overwrites the receiver, which must be a pointer,
- // with the value represented by the byte slice, which was written
- // by GobEncode, usually for the same concrete type.
- GobDecode([]byte) error
-}
-
-var (
- nameToConcreteType sync.Map // map[string]reflect.Type
- concreteTypeToName sync.Map // map[reflect.Type]string
-)
-
-// RegisterName is like Register but uses the provided name rather than the
-// type's default.
-func RegisterName(name string, value any) {
- if name == "" {
- // reserved for nil
- panic("attempt to register empty name")
- }
-
- ut := userType(reflect.TypeOf(value))
-
- // Check for incompatible duplicates. The name must refer to the
- // same user type, and vice versa.
-
- // Store the name and type provided by the user....
- if t, dup := nameToConcreteType.LoadOrStore(name, reflect.TypeOf(value)); dup && t != ut.user {
- panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", name, t, ut.user))
- }
-
- // but the flattened type in the type table, since that's what decode needs.
- if n, dup := concreteTypeToName.LoadOrStore(ut.base, name); dup && n != name {
- nameToConcreteType.Delete(name)
- panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", ut.user, n, name))
- }
-}
-
-// Register records a type, identified by a value for that type, under its
-// internal type name. That name will identify the concrete type of a value
-// sent or received as an interface variable. Only types that will be
-// transferred as implementations of interface values need to be registered.
-// Expecting to be used only during initialization, it panics if the mapping
-// between types and names is not a bijection.
-func Register(value any) {
- // Default to printed representation for unnamed types
- rt := reflect.TypeOf(value)
- name := rt.String()
-
- // But for named types (or pointers to them), qualify with import path (but see inner comment).
- // Dereference one pointer looking for a named type.
- star := ""
- if rt.Name() == "" {
- if pt := rt; pt.Kind() == reflect.Pointer {
- star = "*"
- // NOTE: The following line should be rt = pt.Elem() to implement
- // what the comment above claims, but fixing it would break compatibility
- // with existing gobs.
- //
- // Given package p imported as "full/p" with these definitions:
- // package p
- // type T1 struct { ... }
- // this table shows the intended and actual strings used by gob to
- // name the types:
- //
- // Type Correct string Actual string
- //
- // T1 full/p.T1 full/p.T1
- // *T1 *full/p.T1 *p.T1
- //
- // The missing full path cannot be fixed without breaking existing gob decoders.
- rt = pt
- }
- }
- if rt.Name() != "" {
- if rt.PkgPath() == "" {
- name = star + rt.Name()
- } else {
- name = star + rt.PkgPath() + "." + rt.Name()
- }
- }
-
- RegisterName(name, value)
-}
-
-func registerBasics() {
- Register(int(0))
- Register(int8(0))
- Register(int16(0))
- Register(int32(0))
- Register(int64(0))
- Register(uint(0))
- Register(uint8(0))
- Register(uint16(0))
- Register(uint32(0))
- Register(uint64(0))
- Register(float32(0))
- Register(float64(0))
- Register(complex64(0i))
- Register(complex128(0i))
- Register(uintptr(0))
- Register(false)
- Register("")
- Register([]byte(nil))
- Register([]int(nil))
- Register([]int8(nil))
- Register([]int16(nil))
- Register([]int32(nil))
- Register([]int64(nil))
- Register([]uint(nil))
- Register([]uint8(nil))
- Register([]uint16(nil))
- Register([]uint32(nil))
- Register([]uint64(nil))
- Register([]float32(nil))
- Register([]float64(nil))
- Register([]complex64(nil))
- Register([]complex128(nil))
- Register([]uintptr(nil))
- Register([]bool(nil))
- Register([]string(nil))
-}
diff --git a/contrib/go/_std_1.20/src/encoding/gob/ya.make b/contrib/go/_std_1.20/src/encoding/gob/ya.make
deleted file mode 100644
index c972749012..0000000000
--- a/contrib/go/_std_1.20/src/encoding/gob/ya.make
+++ /dev/null
@@ -1,15 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- dec_helpers.go
- decode.go
- decoder.go
- doc.go
- enc_helpers.go
- encode.go
- encoder.go
- error.go
- type.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/encoding/hex/ya.make b/contrib/go/_std_1.20/src/encoding/hex/ya.make
deleted file mode 100644
index 0c896c6aa6..0000000000
--- a/contrib/go/_std_1.20/src/encoding/hex/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- hex.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/encoding/json/decode.go b/contrib/go/_std_1.20/src/encoding/json/decode.go
deleted file mode 100644
index 01af489b56..0000000000
--- a/contrib/go/_std_1.20/src/encoding/json/decode.go
+++ /dev/null
@@ -1,1311 +0,0 @@
-// Copyright 2010 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.
-
-// Represents JSON data structure using native Go types: booleans, floats,
-// strings, arrays, and maps.
-
-package json
-
-import (
- "encoding"
- "encoding/base64"
- "fmt"
- "reflect"
- "strconv"
- "strings"
- "unicode"
- "unicode/utf16"
- "unicode/utf8"
-)
-
-// Unmarshal parses the JSON-encoded data and stores the result
-// in the value pointed to by v. If v is nil or not a pointer,
-// Unmarshal returns an InvalidUnmarshalError.
-//
-// Unmarshal uses the inverse of the encodings that
-// Marshal uses, allocating maps, slices, and pointers as necessary,
-// with the following additional rules:
-//
-// To unmarshal JSON into a pointer, Unmarshal first handles the case of
-// the JSON being the JSON literal null. In that case, Unmarshal sets
-// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into
-// the value pointed at by the pointer. If the pointer is nil, Unmarshal
-// allocates a new value for it to point to.
-//
-// To unmarshal JSON into a value implementing the Unmarshaler interface,
-// Unmarshal calls that value's UnmarshalJSON method, including
-// when the input is a JSON null.
-// Otherwise, if the value implements encoding.TextUnmarshaler
-// and the input is a JSON quoted string, Unmarshal calls that value's
-// UnmarshalText method with the unquoted form of the string.
-//
-// To unmarshal JSON into a struct, Unmarshal matches incoming object
-// keys to the keys used by Marshal (either the struct field name or its tag),
-// preferring an exact match but also accepting a case-insensitive match. By
-// default, object keys which don't have a corresponding struct field are
-// ignored (see Decoder.DisallowUnknownFields for an alternative).
-//
-// To unmarshal JSON into an interface value,
-// Unmarshal stores one of these in the interface value:
-//
-// bool, for JSON booleans
-// float64, for JSON numbers
-// string, for JSON strings
-// []interface{}, for JSON arrays
-// map[string]interface{}, for JSON objects
-// nil for JSON null
-//
-// To unmarshal a JSON array into a slice, Unmarshal resets the slice length
-// to zero and then appends each element to the slice.
-// As a special case, to unmarshal an empty JSON array into a slice,
-// Unmarshal replaces the slice with a new empty slice.
-//
-// To unmarshal a JSON array into a Go array, Unmarshal decodes
-// JSON array elements into corresponding Go array elements.
-// If the Go array is smaller than the JSON array,
-// the additional JSON array elements are discarded.
-// If the JSON array is smaller than the Go array,
-// the additional Go array elements are set to zero values.
-//
-// To unmarshal a JSON object into a map, Unmarshal first establishes a map to
-// use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal
-// reuses the existing map, keeping existing entries. Unmarshal then stores
-// key-value pairs from the JSON object into the map. The map's key type must
-// either be any string type, an integer, implement json.Unmarshaler, or
-// implement encoding.TextUnmarshaler.
-//
-// If the JSON-encoded data contain a syntax error, Unmarshal returns a SyntaxError.
-//
-// If a JSON value is not appropriate for a given target type,
-// or if a JSON number overflows the target type, Unmarshal
-// skips that field and completes the unmarshaling as best it can.
-// If no more serious errors are encountered, Unmarshal returns
-// an UnmarshalTypeError describing the earliest such error. In any
-// case, it's not guaranteed that all the remaining fields following
-// the problematic one will be unmarshaled into the target object.
-//
-// The JSON null value unmarshals into an interface, map, pointer, or slice
-// by setting that Go value to nil. Because null is often used in JSON to mean
-// “not present,” unmarshaling a JSON null into any other Go type has no effect
-// on the value and produces no error.
-//
-// When unmarshaling quoted strings, invalid UTF-8 or
-// invalid UTF-16 surrogate pairs are not treated as an error.
-// Instead, they are replaced by the Unicode replacement
-// character U+FFFD.
-func Unmarshal(data []byte, v any) error {
- // Check for well-formedness.
- // Avoids filling out half a data structure
- // before discovering a JSON syntax error.
- var d decodeState
- err := checkValid(data, &d.scan)
- if err != nil {
- return err
- }
-
- d.init(data)
- return d.unmarshal(v)
-}
-
-// Unmarshaler is the interface implemented by types
-// that can unmarshal a JSON description of themselves.
-// The input can be assumed to be a valid encoding of
-// a JSON value. UnmarshalJSON must copy the JSON data
-// if it wishes to retain the data after returning.
-//
-// By convention, to approximate the behavior of Unmarshal itself,
-// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.
-type Unmarshaler interface {
- UnmarshalJSON([]byte) error
-}
-
-// An UnmarshalTypeError describes a JSON value that was
-// not appropriate for a value of a specific Go type.
-type UnmarshalTypeError struct {
- Value string // description of JSON value - "bool", "array", "number -5"
- Type reflect.Type // type of Go value it could not be assigned to
- Offset int64 // error occurred after reading Offset bytes
- Struct string // name of the struct type containing the field
- Field string // the full path from root node to the field
-}
-
-func (e *UnmarshalTypeError) Error() string {
- if e.Struct != "" || e.Field != "" {
- return "json: cannot unmarshal " + e.Value + " into Go struct field " + e.Struct + "." + e.Field + " of type " + e.Type.String()
- }
- return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String()
-}
-
-// An UnmarshalFieldError describes a JSON object key that
-// led to an unexported (and therefore unwritable) struct field.
-//
-// Deprecated: No longer used; kept for compatibility.
-type UnmarshalFieldError struct {
- Key string
- Type reflect.Type
- Field reflect.StructField
-}
-
-func (e *UnmarshalFieldError) Error() string {
- return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String()
-}
-
-// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
-// (The argument to Unmarshal must be a non-nil pointer.)
-type InvalidUnmarshalError struct {
- Type reflect.Type
-}
-
-func (e *InvalidUnmarshalError) Error() string {
- if e.Type == nil {
- return "json: Unmarshal(nil)"
- }
-
- if e.Type.Kind() != reflect.Pointer {
- return "json: Unmarshal(non-pointer " + e.Type.String() + ")"
- }
- return "json: Unmarshal(nil " + e.Type.String() + ")"
-}
-
-func (d *decodeState) unmarshal(v any) error {
- rv := reflect.ValueOf(v)
- if rv.Kind() != reflect.Pointer || rv.IsNil() {
- return &InvalidUnmarshalError{reflect.TypeOf(v)}
- }
-
- d.scan.reset()
- d.scanWhile(scanSkipSpace)
- // We decode rv not rv.Elem because the Unmarshaler interface
- // test must be applied at the top level of the value.
- err := d.value(rv)
- if err != nil {
- return d.addErrorContext(err)
- }
- return d.savedError
-}
-
-// A Number represents a JSON number literal.
-type Number string
-
-// String returns the literal text of the number.
-func (n Number) String() string { return string(n) }
-
-// Float64 returns the number as a float64.
-func (n Number) Float64() (float64, error) {
- return strconv.ParseFloat(string(n), 64)
-}
-
-// Int64 returns the number as an int64.
-func (n Number) Int64() (int64, error) {
- return strconv.ParseInt(string(n), 10, 64)
-}
-
-// An errorContext provides context for type errors during decoding.
-type errorContext struct {
- Struct reflect.Type
- FieldStack []string
-}
-
-// decodeState represents the state while decoding a JSON value.
-type decodeState struct {
- data []byte
- off int // next read offset in data
- opcode int // last read result
- scan scanner
- errorContext *errorContext
- savedError error
- useNumber bool
- disallowUnknownFields bool
-}
-
-// readIndex returns the position of the last byte read.
-func (d *decodeState) readIndex() int {
- return d.off - 1
-}
-
-// phasePanicMsg is used as a panic message when we end up with something that
-// shouldn't happen. It can indicate a bug in the JSON decoder, or that
-// something is editing the data slice while the decoder executes.
-const phasePanicMsg = "JSON decoder out of sync - data changing underfoot?"
-
-func (d *decodeState) init(data []byte) *decodeState {
- d.data = data
- d.off = 0
- d.savedError = nil
- if d.errorContext != nil {
- d.errorContext.Struct = nil
- // Reuse the allocated space for the FieldStack slice.
- d.errorContext.FieldStack = d.errorContext.FieldStack[:0]
- }
- return d
-}
-
-// saveError saves the first err it is called with,
-// for reporting at the end of the unmarshal.
-func (d *decodeState) saveError(err error) {
- if d.savedError == nil {
- d.savedError = d.addErrorContext(err)
- }
-}
-
-// addErrorContext returns a new error enhanced with information from d.errorContext
-func (d *decodeState) addErrorContext(err error) error {
- if d.errorContext != nil && (d.errorContext.Struct != nil || len(d.errorContext.FieldStack) > 0) {
- switch err := err.(type) {
- case *UnmarshalTypeError:
- err.Struct = d.errorContext.Struct.Name()
- err.Field = strings.Join(d.errorContext.FieldStack, ".")
- }
- }
- return err
-}
-
-// skip scans to the end of what was started.
-func (d *decodeState) skip() {
- s, data, i := &d.scan, d.data, d.off
- depth := len(s.parseState)
- for {
- op := s.step(s, data[i])
- i++
- if len(s.parseState) < depth {
- d.off = i
- d.opcode = op
- return
- }
- }
-}
-
-// scanNext processes the byte at d.data[d.off].
-func (d *decodeState) scanNext() {
- if d.off < len(d.data) {
- d.opcode = d.scan.step(&d.scan, d.data[d.off])
- d.off++
- } else {
- d.opcode = d.scan.eof()
- d.off = len(d.data) + 1 // mark processed EOF with len+1
- }
-}
-
-// scanWhile processes bytes in d.data[d.off:] until it
-// receives a scan code not equal to op.
-func (d *decodeState) scanWhile(op int) {
- s, data, i := &d.scan, d.data, d.off
- for i < len(data) {
- newOp := s.step(s, data[i])
- i++
- if newOp != op {
- d.opcode = newOp
- d.off = i
- return
- }
- }
-
- d.off = len(data) + 1 // mark processed EOF with len+1
- d.opcode = d.scan.eof()
-}
-
-// rescanLiteral is similar to scanWhile(scanContinue), but it specialises the
-// common case where we're decoding a literal. The decoder scans the input
-// twice, once for syntax errors and to check the length of the value, and the
-// second to perform the decoding.
-//
-// Only in the second step do we use decodeState to tokenize literals, so we
-// know there aren't any syntax errors. We can take advantage of that knowledge,
-// and scan a literal's bytes much more quickly.
-func (d *decodeState) rescanLiteral() {
- data, i := d.data, d.off
-Switch:
- switch data[i-1] {
- case '"': // string
- for ; i < len(data); i++ {
- switch data[i] {
- case '\\':
- i++ // escaped char
- case '"':
- i++ // tokenize the closing quote too
- break Switch
- }
- }
- case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': // number
- for ; i < len(data); i++ {
- switch data[i] {
- case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- '.', 'e', 'E', '+', '-':
- default:
- break Switch
- }
- }
- case 't': // true
- i += len("rue")
- case 'f': // false
- i += len("alse")
- case 'n': // null
- i += len("ull")
- }
- if i < len(data) {
- d.opcode = stateEndValue(&d.scan, data[i])
- } else {
- d.opcode = scanEnd
- }
- d.off = i + 1
-}
-
-// value consumes a JSON value from d.data[d.off-1:], decoding into v, and
-// reads the following byte ahead. If v is invalid, the value is discarded.
-// The first byte of the value has been read already.
-func (d *decodeState) value(v reflect.Value) error {
- switch d.opcode {
- default:
- panic(phasePanicMsg)
-
- case scanBeginArray:
- if v.IsValid() {
- if err := d.array(v); err != nil {
- return err
- }
- } else {
- d.skip()
- }
- d.scanNext()
-
- case scanBeginObject:
- if v.IsValid() {
- if err := d.object(v); err != nil {
- return err
- }
- } else {
- d.skip()
- }
- d.scanNext()
-
- case scanBeginLiteral:
- // All bytes inside literal return scanContinue op code.
- start := d.readIndex()
- d.rescanLiteral()
-
- if v.IsValid() {
- if err := d.literalStore(d.data[start:d.readIndex()], v, false); err != nil {
- return err
- }
- }
- }
- return nil
-}
-
-type unquotedValue struct{}
-
-// valueQuoted is like value but decodes a
-// quoted string literal or literal null into an interface value.
-// If it finds anything other than a quoted string literal or null,
-// valueQuoted returns unquotedValue{}.
-func (d *decodeState) valueQuoted() any {
- switch d.opcode {
- default:
- panic(phasePanicMsg)
-
- case scanBeginArray, scanBeginObject:
- d.skip()
- d.scanNext()
-
- case scanBeginLiteral:
- v := d.literalInterface()
- switch v.(type) {
- case nil, string:
- return v
- }
- }
- return unquotedValue{}
-}
-
-// indirect walks down v allocating pointers as needed,
-// until it gets to a non-pointer.
-// If it encounters an Unmarshaler, indirect stops and returns that.
-// If decodingNull is true, indirect stops at the first settable pointer so it
-// can be set to nil.
-func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
- // Issue #24153 indicates that it is generally not a guaranteed property
- // that you may round-trip a reflect.Value by calling Value.Addr().Elem()
- // and expect the value to still be settable for values derived from
- // unexported embedded struct fields.
- //
- // The logic below effectively does this when it first addresses the value
- // (to satisfy possible pointer methods) and continues to dereference
- // subsequent pointers as necessary.
- //
- // After the first round-trip, we set v back to the original value to
- // preserve the original RW flags contained in reflect.Value.
- v0 := v
- haveAddr := false
-
- // If v is a named type and is addressable,
- // start with its address, so that if the type has pointer methods,
- // we find them.
- if v.Kind() != reflect.Pointer && v.Type().Name() != "" && v.CanAddr() {
- haveAddr = true
- v = v.Addr()
- }
- for {
- // Load value from interface, but only if the result will be
- // usefully addressable.
- if v.Kind() == reflect.Interface && !v.IsNil() {
- e := v.Elem()
- if e.Kind() == reflect.Pointer && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Pointer) {
- haveAddr = false
- v = e
- continue
- }
- }
-
- if v.Kind() != reflect.Pointer {
- break
- }
-
- if decodingNull && v.CanSet() {
- break
- }
-
- // Prevent infinite loop if v is an interface pointing to its own address:
- // var v interface{}
- // v = &v
- if v.Elem().Kind() == reflect.Interface && v.Elem().Elem() == v {
- v = v.Elem()
- break
- }
- if v.IsNil() {
- v.Set(reflect.New(v.Type().Elem()))
- }
- if v.Type().NumMethod() > 0 && v.CanInterface() {
- if u, ok := v.Interface().(Unmarshaler); ok {
- return u, nil, reflect.Value{}
- }
- if !decodingNull {
- if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
- return nil, u, reflect.Value{}
- }
- }
- }
-
- if haveAddr {
- v = v0 // restore original value after round-trip Value.Addr().Elem()
- haveAddr = false
- } else {
- v = v.Elem()
- }
- }
- return nil, nil, v
-}
-
-// array consumes an array from d.data[d.off-1:], decoding into v.
-// The first byte of the array ('[') has been read already.
-func (d *decodeState) array(v reflect.Value) error {
- // Check for unmarshaler.
- u, ut, pv := indirect(v, false)
- if u != nil {
- start := d.readIndex()
- d.skip()
- return u.UnmarshalJSON(d.data[start:d.off])
- }
- if ut != nil {
- d.saveError(&UnmarshalTypeError{Value: "array", Type: v.Type(), Offset: int64(d.off)})
- d.skip()
- return nil
- }
- v = pv
-
- // Check type of target.
- switch v.Kind() {
- case reflect.Interface:
- if v.NumMethod() == 0 {
- // Decoding into nil interface? Switch to non-reflect code.
- ai := d.arrayInterface()
- v.Set(reflect.ValueOf(ai))
- return nil
- }
- // Otherwise it's invalid.
- fallthrough
- default:
- d.saveError(&UnmarshalTypeError{Value: "array", Type: v.Type(), Offset: int64(d.off)})
- d.skip()
- return nil
- case reflect.Array, reflect.Slice:
- break
- }
-
- i := 0
- for {
- // Look ahead for ] - can only happen on first iteration.
- d.scanWhile(scanSkipSpace)
- if d.opcode == scanEndArray {
- break
- }
-
- // Get element of array, growing if necessary.
- if v.Kind() == reflect.Slice {
- // Grow slice if necessary
- if i >= v.Cap() {
- newcap := v.Cap() + v.Cap()/2
- if newcap < 4 {
- newcap = 4
- }
- newv := reflect.MakeSlice(v.Type(), v.Len(), newcap)
- reflect.Copy(newv, v)
- v.Set(newv)
- }
- if i >= v.Len() {
- v.SetLen(i + 1)
- }
- }
-
- if i < v.Len() {
- // Decode into element.
- if err := d.value(v.Index(i)); err != nil {
- return err
- }
- } else {
- // Ran out of fixed array: skip.
- if err := d.value(reflect.Value{}); err != nil {
- return err
- }
- }
- i++
-
- // Next token must be , or ].
- if d.opcode == scanSkipSpace {
- d.scanWhile(scanSkipSpace)
- }
- if d.opcode == scanEndArray {
- break
- }
- if d.opcode != scanArrayValue {
- panic(phasePanicMsg)
- }
- }
-
- if i < v.Len() {
- if v.Kind() == reflect.Array {
- // Array. Zero the rest.
- z := reflect.Zero(v.Type().Elem())
- for ; i < v.Len(); i++ {
- v.Index(i).Set(z)
- }
- } else {
- v.SetLen(i)
- }
- }
- if i == 0 && v.Kind() == reflect.Slice {
- v.Set(reflect.MakeSlice(v.Type(), 0, 0))
- }
- return nil
-}
-
-var nullLiteral = []byte("null")
-var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
-
-// object consumes an object from d.data[d.off-1:], decoding into v.
-// The first byte ('{') of the object has been read already.
-func (d *decodeState) object(v reflect.Value) error {
- // Check for unmarshaler.
- u, ut, pv := indirect(v, false)
- if u != nil {
- start := d.readIndex()
- d.skip()
- return u.UnmarshalJSON(d.data[start:d.off])
- }
- if ut != nil {
- d.saveError(&UnmarshalTypeError{Value: "object", Type: v.Type(), Offset: int64(d.off)})
- d.skip()
- return nil
- }
- v = pv
- t := v.Type()
-
- // Decoding into nil interface? Switch to non-reflect code.
- if v.Kind() == reflect.Interface && v.NumMethod() == 0 {
- oi := d.objectInterface()
- v.Set(reflect.ValueOf(oi))
- return nil
- }
-
- var fields structFields
-
- // Check type of target:
- // struct or
- // map[T1]T2 where T1 is string, an integer type,
- // or an encoding.TextUnmarshaler
- switch v.Kind() {
- case reflect.Map:
- // Map key must either have string kind, have an integer kind,
- // or be an encoding.TextUnmarshaler.
- switch t.Key().Kind() {
- case reflect.String,
- reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
- reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- default:
- if !reflect.PointerTo(t.Key()).Implements(textUnmarshalerType) {
- d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)})
- d.skip()
- return nil
- }
- }
- if v.IsNil() {
- v.Set(reflect.MakeMap(t))
- }
- case reflect.Struct:
- fields = cachedTypeFields(t)
- // ok
- default:
- d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)})
- d.skip()
- return nil
- }
-
- var mapElem reflect.Value
- var origErrorContext errorContext
- if d.errorContext != nil {
- origErrorContext = *d.errorContext
- }
-
- for {
- // Read opening " of string key or closing }.
- d.scanWhile(scanSkipSpace)
- if d.opcode == scanEndObject {
- // closing } - can only happen on first iteration.
- break
- }
- if d.opcode != scanBeginLiteral {
- panic(phasePanicMsg)
- }
-
- // Read key.
- start := d.readIndex()
- d.rescanLiteral()
- item := d.data[start:d.readIndex()]
- key, ok := unquoteBytes(item)
- if !ok {
- panic(phasePanicMsg)
- }
-
- // Figure out field corresponding to key.
- var subv reflect.Value
- destring := false // whether the value is wrapped in a string to be decoded first
-
- if v.Kind() == reflect.Map {
- elemType := t.Elem()
- if !mapElem.IsValid() {
- mapElem = reflect.New(elemType).Elem()
- } else {
- mapElem.Set(reflect.Zero(elemType))
- }
- subv = mapElem
- } else {
- var f *field
- if i, ok := fields.nameIndex[string(key)]; ok {
- // Found an exact name match.
- f = &fields.list[i]
- } else {
- // Fall back to the expensive case-insensitive
- // linear search.
- for i := range fields.list {
- ff := &fields.list[i]
- if ff.equalFold(ff.nameBytes, key) {
- f = ff
- break
- }
- }
- }
- if f != nil {
- subv = v
- destring = f.quoted
- for _, i := range f.index {
- if subv.Kind() == reflect.Pointer {
- if subv.IsNil() {
- // If a struct embeds a pointer to an unexported type,
- // it is not possible to set a newly allocated value
- // since the field is unexported.
- //
- // See https://golang.org/issue/21357
- if !subv.CanSet() {
- d.saveError(fmt.Errorf("json: cannot set embedded pointer to unexported struct: %v", subv.Type().Elem()))
- // Invalidate subv to ensure d.value(subv) skips over
- // the JSON value without assigning it to subv.
- subv = reflect.Value{}
- destring = false
- break
- }
- subv.Set(reflect.New(subv.Type().Elem()))
- }
- subv = subv.Elem()
- }
- subv = subv.Field(i)
- }
- if d.errorContext == nil {
- d.errorContext = new(errorContext)
- }
- d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name)
- d.errorContext.Struct = t
- } else if d.disallowUnknownFields {
- d.saveError(fmt.Errorf("json: unknown field %q", key))
- }
- }
-
- // Read : before value.
- if d.opcode == scanSkipSpace {
- d.scanWhile(scanSkipSpace)
- }
- if d.opcode != scanObjectKey {
- panic(phasePanicMsg)
- }
- d.scanWhile(scanSkipSpace)
-
- if destring {
- switch qv := d.valueQuoted().(type) {
- case nil:
- if err := d.literalStore(nullLiteral, subv, false); err != nil {
- return err
- }
- case string:
- if err := d.literalStore([]byte(qv), subv, true); err != nil {
- return err
- }
- default:
- d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type()))
- }
- } else {
- if err := d.value(subv); err != nil {
- return err
- }
- }
-
- // Write value back to map;
- // if using struct, subv points into struct already.
- if v.Kind() == reflect.Map {
- kt := t.Key()
- var kv reflect.Value
- switch {
- case reflect.PointerTo(kt).Implements(textUnmarshalerType):
- kv = reflect.New(kt)
- if err := d.literalStore(item, kv, true); err != nil {
- return err
- }
- kv = kv.Elem()
- case kt.Kind() == reflect.String:
- kv = reflect.ValueOf(key).Convert(kt)
- default:
- switch kt.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- s := string(key)
- n, err := strconv.ParseInt(s, 10, 64)
- if err != nil || reflect.Zero(kt).OverflowInt(n) {
- d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)})
- break
- }
- kv = reflect.ValueOf(n).Convert(kt)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- s := string(key)
- n, err := strconv.ParseUint(s, 10, 64)
- if err != nil || reflect.Zero(kt).OverflowUint(n) {
- d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)})
- break
- }
- kv = reflect.ValueOf(n).Convert(kt)
- default:
- panic("json: Unexpected key type") // should never occur
- }
- }
- if kv.IsValid() {
- v.SetMapIndex(kv, subv)
- }
- }
-
- // Next token must be , or }.
- if d.opcode == scanSkipSpace {
- d.scanWhile(scanSkipSpace)
- }
- if d.errorContext != nil {
- // Reset errorContext to its original state.
- // Keep the same underlying array for FieldStack, to reuse the
- // space and avoid unnecessary allocs.
- d.errorContext.FieldStack = d.errorContext.FieldStack[:len(origErrorContext.FieldStack)]
- d.errorContext.Struct = origErrorContext.Struct
- }
- if d.opcode == scanEndObject {
- break
- }
- if d.opcode != scanObjectValue {
- panic(phasePanicMsg)
- }
- }
- return nil
-}
-
-// convertNumber converts the number literal s to a float64 or a Number
-// depending on the setting of d.useNumber.
-func (d *decodeState) convertNumber(s string) (any, error) {
- if d.useNumber {
- return Number(s), nil
- }
- f, err := strconv.ParseFloat(s, 64)
- if err != nil {
- return nil, &UnmarshalTypeError{Value: "number " + s, Type: reflect.TypeOf(0.0), Offset: int64(d.off)}
- }
- return f, nil
-}
-
-var numberType = reflect.TypeOf(Number(""))
-
-// literalStore decodes a literal stored in item into v.
-//
-// fromQuoted indicates whether this literal came from unwrapping a
-// string from the ",string" struct tag option. this is used only to
-// produce more helpful error messages.
-func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) error {
- // Check for unmarshaler.
- if len(item) == 0 {
- //Empty string given
- d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
- return nil
- }
- isNull := item[0] == 'n' // null
- u, ut, pv := indirect(v, isNull)
- if u != nil {
- return u.UnmarshalJSON(item)
- }
- if ut != nil {
- if item[0] != '"' {
- if fromQuoted {
- d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
- return nil
- }
- val := "number"
- switch item[0] {
- case 'n':
- val = "null"
- case 't', 'f':
- val = "bool"
- }
- d.saveError(&UnmarshalTypeError{Value: val, Type: v.Type(), Offset: int64(d.readIndex())})
- return nil
- }
- s, ok := unquoteBytes(item)
- if !ok {
- if fromQuoted {
- return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
- }
- panic(phasePanicMsg)
- }
- return ut.UnmarshalText(s)
- }
-
- v = pv
-
- switch c := item[0]; c {
- case 'n': // null
- // The main parser checks that only true and false can reach here,
- // but if this was a quoted string input, it could be anything.
- if fromQuoted && string(item) != "null" {
- d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
- break
- }
- switch v.Kind() {
- case reflect.Interface, reflect.Pointer, reflect.Map, reflect.Slice:
- v.Set(reflect.Zero(v.Type()))
- // otherwise, ignore null for primitives/string
- }
- case 't', 'f': // true, false
- value := item[0] == 't'
- // The main parser checks that only true and false can reach here,
- // but if this was a quoted string input, it could be anything.
- if fromQuoted && string(item) != "true" && string(item) != "false" {
- d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
- break
- }
- switch v.Kind() {
- default:
- if fromQuoted {
- d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
- } else {
- d.saveError(&UnmarshalTypeError{Value: "bool", Type: v.Type(), Offset: int64(d.readIndex())})
- }
- case reflect.Bool:
- v.SetBool(value)
- case reflect.Interface:
- if v.NumMethod() == 0 {
- v.Set(reflect.ValueOf(value))
- } else {
- d.saveError(&UnmarshalTypeError{Value: "bool", Type: v.Type(), Offset: int64(d.readIndex())})
- }
- }
-
- case '"': // string
- s, ok := unquoteBytes(item)
- if !ok {
- if fromQuoted {
- return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
- }
- panic(phasePanicMsg)
- }
- switch v.Kind() {
- default:
- d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())})
- case reflect.Slice:
- if v.Type().Elem().Kind() != reflect.Uint8 {
- d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())})
- break
- }
- b := make([]byte, base64.StdEncoding.DecodedLen(len(s)))
- n, err := base64.StdEncoding.Decode(b, s)
- if err != nil {
- d.saveError(err)
- break
- }
- v.SetBytes(b[:n])
- case reflect.String:
- if v.Type() == numberType && !isValidNumber(string(s)) {
- return fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item)
- }
- v.SetString(string(s))
- case reflect.Interface:
- if v.NumMethod() == 0 {
- v.Set(reflect.ValueOf(string(s)))
- } else {
- d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())})
- }
- }
-
- default: // number
- if c != '-' && (c < '0' || c > '9') {
- if fromQuoted {
- return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
- }
- panic(phasePanicMsg)
- }
- s := string(item)
- switch v.Kind() {
- default:
- if v.Kind() == reflect.String && v.Type() == numberType {
- // s must be a valid number, because it's
- // already been tokenized.
- v.SetString(s)
- break
- }
- if fromQuoted {
- return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
- }
- d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())})
- case reflect.Interface:
- n, err := d.convertNumber(s)
- if err != nil {
- d.saveError(err)
- break
- }
- if v.NumMethod() != 0 {
- d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())})
- break
- }
- v.Set(reflect.ValueOf(n))
-
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- n, err := strconv.ParseInt(s, 10, 64)
- if err != nil || v.OverflowInt(n) {
- d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())})
- break
- }
- v.SetInt(n)
-
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- n, err := strconv.ParseUint(s, 10, 64)
- if err != nil || v.OverflowUint(n) {
- d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())})
- break
- }
- v.SetUint(n)
-
- case reflect.Float32, reflect.Float64:
- n, err := strconv.ParseFloat(s, v.Type().Bits())
- if err != nil || v.OverflowFloat(n) {
- d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())})
- break
- }
- v.SetFloat(n)
- }
- }
- return nil
-}
-
-// The xxxInterface routines build up a value to be stored
-// in an empty interface. They are not strictly necessary,
-// but they avoid the weight of reflection in this common case.
-
-// valueInterface is like value but returns interface{}
-func (d *decodeState) valueInterface() (val any) {
- switch d.opcode {
- default:
- panic(phasePanicMsg)
- case scanBeginArray:
- val = d.arrayInterface()
- d.scanNext()
- case scanBeginObject:
- val = d.objectInterface()
- d.scanNext()
- case scanBeginLiteral:
- val = d.literalInterface()
- }
- return
-}
-
-// arrayInterface is like array but returns []interface{}.
-func (d *decodeState) arrayInterface() []any {
- var v = make([]any, 0)
- for {
- // Look ahead for ] - can only happen on first iteration.
- d.scanWhile(scanSkipSpace)
- if d.opcode == scanEndArray {
- break
- }
-
- v = append(v, d.valueInterface())
-
- // Next token must be , or ].
- if d.opcode == scanSkipSpace {
- d.scanWhile(scanSkipSpace)
- }
- if d.opcode == scanEndArray {
- break
- }
- if d.opcode != scanArrayValue {
- panic(phasePanicMsg)
- }
- }
- return v
-}
-
-// objectInterface is like object but returns map[string]interface{}.
-func (d *decodeState) objectInterface() map[string]any {
- m := make(map[string]any)
- for {
- // Read opening " of string key or closing }.
- d.scanWhile(scanSkipSpace)
- if d.opcode == scanEndObject {
- // closing } - can only happen on first iteration.
- break
- }
- if d.opcode != scanBeginLiteral {
- panic(phasePanicMsg)
- }
-
- // Read string key.
- start := d.readIndex()
- d.rescanLiteral()
- item := d.data[start:d.readIndex()]
- key, ok := unquote(item)
- if !ok {
- panic(phasePanicMsg)
- }
-
- // Read : before value.
- if d.opcode == scanSkipSpace {
- d.scanWhile(scanSkipSpace)
- }
- if d.opcode != scanObjectKey {
- panic(phasePanicMsg)
- }
- d.scanWhile(scanSkipSpace)
-
- // Read value.
- m[key] = d.valueInterface()
-
- // Next token must be , or }.
- if d.opcode == scanSkipSpace {
- d.scanWhile(scanSkipSpace)
- }
- if d.opcode == scanEndObject {
- break
- }
- if d.opcode != scanObjectValue {
- panic(phasePanicMsg)
- }
- }
- return m
-}
-
-// literalInterface consumes and returns a literal from d.data[d.off-1:] and
-// it reads the following byte ahead. The first byte of the literal has been
-// read already (that's how the caller knows it's a literal).
-func (d *decodeState) literalInterface() any {
- // All bytes inside literal return scanContinue op code.
- start := d.readIndex()
- d.rescanLiteral()
-
- item := d.data[start:d.readIndex()]
-
- switch c := item[0]; c {
- case 'n': // null
- return nil
-
- case 't', 'f': // true, false
- return c == 't'
-
- case '"': // string
- s, ok := unquote(item)
- if !ok {
- panic(phasePanicMsg)
- }
- return s
-
- default: // number
- if c != '-' && (c < '0' || c > '9') {
- panic(phasePanicMsg)
- }
- n, err := d.convertNumber(string(item))
- if err != nil {
- d.saveError(err)
- }
- return n
- }
-}
-
-// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
-// or it returns -1.
-func getu4(s []byte) rune {
- if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
- return -1
- }
- var r rune
- for _, c := range s[2:6] {
- switch {
- case '0' <= c && c <= '9':
- c = c - '0'
- case 'a' <= c && c <= 'f':
- c = c - 'a' + 10
- case 'A' <= c && c <= 'F':
- c = c - 'A' + 10
- default:
- return -1
- }
- r = r*16 + rune(c)
- }
- return r
-}
-
-// unquote converts a quoted JSON string literal s into an actual string t.
-// The rules are different than for Go, so cannot use strconv.Unquote.
-func unquote(s []byte) (t string, ok bool) {
- s, ok = unquoteBytes(s)
- t = string(s)
- return
-}
-
-func unquoteBytes(s []byte) (t []byte, ok bool) {
- if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
- return
- }
- s = s[1 : len(s)-1]
-
- // Check for unusual characters. If there are none,
- // then no unquoting is needed, so return a slice of the
- // original bytes.
- r := 0
- for r < len(s) {
- c := s[r]
- if c == '\\' || c == '"' || c < ' ' {
- break
- }
- if c < utf8.RuneSelf {
- r++
- continue
- }
- rr, size := utf8.DecodeRune(s[r:])
- if rr == utf8.RuneError && size == 1 {
- break
- }
- r += size
- }
- if r == len(s) {
- return s, true
- }
-
- b := make([]byte, len(s)+2*utf8.UTFMax)
- w := copy(b, s[0:r])
- for r < len(s) {
- // Out of room? Can only happen if s is full of
- // malformed UTF-8 and we're replacing each
- // byte with RuneError.
- if w >= len(b)-2*utf8.UTFMax {
- nb := make([]byte, (len(b)+utf8.UTFMax)*2)
- copy(nb, b[0:w])
- b = nb
- }
- switch c := s[r]; {
- case c == '\\':
- r++
- if r >= len(s) {
- return
- }
- switch s[r] {
- default:
- return
- case '"', '\\', '/', '\'':
- b[w] = s[r]
- r++
- w++
- case 'b':
- b[w] = '\b'
- r++
- w++
- case 'f':
- b[w] = '\f'
- r++
- w++
- case 'n':
- b[w] = '\n'
- r++
- w++
- case 'r':
- b[w] = '\r'
- r++
- w++
- case 't':
- b[w] = '\t'
- r++
- w++
- case 'u':
- r--
- rr := getu4(s[r:])
- if rr < 0 {
- return
- }
- r += 6
- if utf16.IsSurrogate(rr) {
- rr1 := getu4(s[r:])
- if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {
- // A valid pair; consume.
- r += 6
- w += utf8.EncodeRune(b[w:], dec)
- break
- }
- // Invalid surrogate; fall back to replacement rune.
- rr = unicode.ReplacementChar
- }
- w += utf8.EncodeRune(b[w:], rr)
- }
-
- // Quote, control characters are invalid.
- case c == '"', c < ' ':
- return
-
- // ASCII
- case c < utf8.RuneSelf:
- b[w] = c
- r++
- w++
-
- // Coerce to well-formed UTF-8.
- default:
- rr, size := utf8.DecodeRune(s[r:])
- r += size
- w += utf8.EncodeRune(b[w:], rr)
- }
- }
- return b[0:w], true
-}
diff --git a/contrib/go/_std_1.20/src/encoding/json/encode.go b/contrib/go/_std_1.20/src/encoding/json/encode.go
deleted file mode 100644
index 9d59b0ff2b..0000000000
--- a/contrib/go/_std_1.20/src/encoding/json/encode.go
+++ /dev/null
@@ -1,1417 +0,0 @@
-// Copyright 2010 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 json implements encoding and decoding of JSON as defined in
-// RFC 7159. The mapping between JSON and Go values is described
-// in the documentation for the Marshal and Unmarshal functions.
-//
-// See "JSON and Go" for an introduction to this package:
-// https://golang.org/doc/articles/json_and_go.html
-package json
-
-import (
- "bytes"
- "encoding"
- "encoding/base64"
- "fmt"
- "math"
- "reflect"
- "sort"
- "strconv"
- "strings"
- "sync"
- "unicode"
- "unicode/utf8"
-)
-
-// Marshal returns the JSON encoding of v.
-//
-// Marshal traverses the value v recursively.
-// If an encountered value implements the Marshaler interface
-// and is not a nil pointer, Marshal calls its MarshalJSON method
-// to produce JSON. If no MarshalJSON method is present but the
-// value implements encoding.TextMarshaler instead, Marshal calls
-// its MarshalText method and encodes the result as a JSON string.
-// The nil pointer exception is not strictly necessary
-// but mimics a similar, necessary exception in the behavior of
-// UnmarshalJSON.
-//
-// Otherwise, Marshal uses the following type-dependent default encodings:
-//
-// Boolean values encode as JSON booleans.
-//
-// Floating point, integer, and Number values encode as JSON numbers.
-//
-// String values encode as JSON strings coerced to valid UTF-8,
-// replacing invalid bytes with the Unicode replacement rune.
-// So that the JSON will be safe to embed inside HTML <script> tags,
-// the string is encoded using HTMLEscape,
-// which replaces "<", ">", "&", U+2028, and U+2029 are escaped
-// to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029".
-// This replacement can be disabled when using an Encoder,
-// by calling SetEscapeHTML(false).
-//
-// Array and slice values encode as JSON arrays, except that
-// []byte encodes as a base64-encoded string, and a nil slice
-// encodes as the null JSON value.
-//
-// Struct values encode as JSON objects.
-// Each exported struct field becomes a member of the object, using the
-// field name as the object key, unless the field is omitted for one of the
-// reasons given below.
-//
-// The encoding of each struct field can be customized by the format string
-// stored under the "json" key in the struct field's tag.
-// The format string gives the name of the field, possibly followed by a
-// comma-separated list of options. The name may be empty in order to
-// specify options without overriding the default field name.
-//
-// The "omitempty" option specifies that the field should be omitted
-// from the encoding if the field has an empty value, defined as
-// false, 0, a nil pointer, a nil interface value, and any empty array,
-// slice, map, or string.
-//
-// As a special case, if the field tag is "-", the field is always omitted.
-// Note that a field with name "-" can still be generated using the tag "-,".
-//
-// Examples of struct field tags and their meanings:
-//
-// // Field appears in JSON as key "myName".
-// Field int `json:"myName"`
-//
-// // Field appears in JSON as key "myName" and
-// // the field is omitted from the object if its value is empty,
-// // as defined above.
-// Field int `json:"myName,omitempty"`
-//
-// // Field appears in JSON as key "Field" (the default), but
-// // the field is skipped if empty.
-// // Note the leading comma.
-// Field int `json:",omitempty"`
-//
-// // Field is ignored by this package.
-// Field int `json:"-"`
-//
-// // Field appears in JSON as key "-".
-// Field int `json:"-,"`
-//
-// The "string" option signals that a field is stored as JSON inside a
-// JSON-encoded string. It applies only to fields of string, floating point,
-// integer, or boolean types. This extra level of encoding is sometimes used
-// when communicating with JavaScript programs:
-//
-// Int64String int64 `json:",string"`
-//
-// The key name will be used if it's a non-empty string consisting of
-// only Unicode letters, digits, and ASCII punctuation except quotation
-// marks, backslash, and comma.
-//
-// Anonymous struct fields are usually marshaled as if their inner exported fields
-// were fields in the outer struct, subject to the usual Go visibility rules amended
-// as described in the next paragraph.
-// An anonymous struct field with a name given in its JSON tag is treated as
-// having that name, rather than being anonymous.
-// An anonymous struct field of interface type is treated the same as having
-// that type as its name, rather than being anonymous.
-//
-// The Go visibility rules for struct fields are amended for JSON when
-// deciding which field to marshal or unmarshal. If there are
-// multiple fields at the same level, and that level is the least
-// nested (and would therefore be the nesting level selected by the
-// usual Go rules), the following extra rules apply:
-//
-// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,
-// even if there are multiple untagged fields that would otherwise conflict.
-//
-// 2) If there is exactly one field (tagged or not according to the first rule), that is selected.
-//
-// 3) Otherwise there are multiple fields, and all are ignored; no error occurs.
-//
-// Handling of anonymous struct fields is new in Go 1.1.
-// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of
-// an anonymous struct field in both current and earlier versions, give the field
-// a JSON tag of "-".
-//
-// Map values encode as JSON objects. The map's key type must either be a
-// string, an integer type, or implement encoding.TextMarshaler. The map keys
-// are sorted and used as JSON object keys by applying the following rules,
-// subject to the UTF-8 coercion described for string values above:
-// - keys of any string type are used directly
-// - encoding.TextMarshalers are marshaled
-// - integer keys are converted to strings
-//
-// Pointer values encode as the value pointed to.
-// A nil pointer encodes as the null JSON value.
-//
-// Interface values encode as the value contained in the interface.
-// A nil interface value encodes as the null JSON value.
-//
-// Channel, complex, and function values cannot be encoded in JSON.
-// Attempting to encode such a value causes Marshal to return
-// an UnsupportedTypeError.
-//
-// JSON cannot represent cyclic data structures and Marshal does not
-// handle them. Passing cyclic structures to Marshal will result in
-// an error.
-func Marshal(v any) ([]byte, error) {
- e := newEncodeState()
- defer encodeStatePool.Put(e)
-
- err := e.marshal(v, encOpts{escapeHTML: true})
- if err != nil {
- return nil, err
- }
- buf := append([]byte(nil), e.Bytes()...)
-
- return buf, nil
-}
-
-// MarshalIndent is like Marshal but applies Indent to format the output.
-// Each JSON element in the output will begin on a new line beginning with prefix
-// followed by one or more copies of indent according to the indentation nesting.
-func MarshalIndent(v any, prefix, indent string) ([]byte, error) {
- b, err := Marshal(v)
- if err != nil {
- return nil, err
- }
- var buf bytes.Buffer
- err = Indent(&buf, b, prefix, indent)
- if err != nil {
- return nil, err
- }
- return buf.Bytes(), nil
-}
-
-// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
-// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
-// so that the JSON will be safe to embed inside HTML <script> tags.
-// For historical reasons, web browsers don't honor standard HTML
-// escaping within <script> tags, so an alternative JSON encoding must
-// be used.
-func HTMLEscape(dst *bytes.Buffer, src []byte) {
- // The characters can only appear in string literals,
- // so just scan the string one byte at a time.
- start := 0
- for i, c := range src {
- if c == '<' || c == '>' || c == '&' {
- if start < i {
- dst.Write(src[start:i])
- }
- dst.WriteString(`\u00`)
- dst.WriteByte(hex[c>>4])
- dst.WriteByte(hex[c&0xF])
- start = i + 1
- }
- // Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
- if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
- if start < i {
- dst.Write(src[start:i])
- }
- dst.WriteString(`\u202`)
- dst.WriteByte(hex[src[i+2]&0xF])
- start = i + 3
- }
- }
- if start < len(src) {
- dst.Write(src[start:])
- }
-}
-
-// Marshaler is the interface implemented by types that
-// can marshal themselves into valid JSON.
-type Marshaler interface {
- MarshalJSON() ([]byte, error)
-}
-
-// An UnsupportedTypeError is returned by Marshal when attempting
-// to encode an unsupported value type.
-type UnsupportedTypeError struct {
- Type reflect.Type
-}
-
-func (e *UnsupportedTypeError) Error() string {
- return "json: unsupported type: " + e.Type.String()
-}
-
-// An UnsupportedValueError is returned by Marshal when attempting
-// to encode an unsupported value.
-type UnsupportedValueError struct {
- Value reflect.Value
- Str string
-}
-
-func (e *UnsupportedValueError) Error() string {
- return "json: unsupported value: " + e.Str
-}
-
-// Before Go 1.2, an InvalidUTF8Error was returned by Marshal when
-// attempting to encode a string value with invalid UTF-8 sequences.
-// As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by
-// replacing invalid bytes with the Unicode replacement rune U+FFFD.
-//
-// Deprecated: No longer used; kept for compatibility.
-type InvalidUTF8Error struct {
- S string // the whole string value that caused the error
-}
-
-func (e *InvalidUTF8Error) Error() string {
- return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
-}
-
-// A MarshalerError represents an error from calling a MarshalJSON or MarshalText method.
-type MarshalerError struct {
- Type reflect.Type
- Err error
- sourceFunc string
-}
-
-func (e *MarshalerError) Error() string {
- srcFunc := e.sourceFunc
- if srcFunc == "" {
- srcFunc = "MarshalJSON"
- }
- return "json: error calling " + srcFunc +
- " for type " + e.Type.String() +
- ": " + e.Err.Error()
-}
-
-// Unwrap returns the underlying error.
-func (e *MarshalerError) Unwrap() error { return e.Err }
-
-var hex = "0123456789abcdef"
-
-// An encodeState encodes JSON into a bytes.Buffer.
-type encodeState struct {
- bytes.Buffer // accumulated output
- scratch [64]byte
-
- // Keep track of what pointers we've seen in the current recursive call
- // path, to avoid cycles that could lead to a stack overflow. Only do
- // the relatively expensive map operations if ptrLevel is larger than
- // startDetectingCyclesAfter, so that we skip the work if we're within a
- // reasonable amount of nested pointers deep.
- ptrLevel uint
- ptrSeen map[any]struct{}
-}
-
-const startDetectingCyclesAfter = 1000
-
-var encodeStatePool sync.Pool
-
-func newEncodeState() *encodeState {
- if v := encodeStatePool.Get(); v != nil {
- e := v.(*encodeState)
- e.Reset()
- if len(e.ptrSeen) > 0 {
- panic("ptrEncoder.encode should have emptied ptrSeen via defers")
- }
- e.ptrLevel = 0
- return e
- }
- return &encodeState{ptrSeen: make(map[any]struct{})}
-}
-
-// jsonError is an error wrapper type for internal use only.
-// Panics with errors are wrapped in jsonError so that the top-level recover
-// can distinguish intentional panics from this package.
-type jsonError struct{ error }
-
-func (e *encodeState) marshal(v any, opts encOpts) (err error) {
- defer func() {
- if r := recover(); r != nil {
- if je, ok := r.(jsonError); ok {
- err = je.error
- } else {
- panic(r)
- }
- }
- }()
- e.reflectValue(reflect.ValueOf(v), opts)
- return nil
-}
-
-// error aborts the encoding by panicking with err wrapped in jsonError.
-func (e *encodeState) error(err error) {
- panic(jsonError{err})
-}
-
-func isEmptyValue(v reflect.Value) bool {
- switch v.Kind() {
- case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
- return v.Len() == 0
- case reflect.Bool:
- return !v.Bool()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return v.Int() == 0
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return v.Uint() == 0
- case reflect.Float32, reflect.Float64:
- return v.Float() == 0
- case reflect.Interface, reflect.Pointer:
- return v.IsNil()
- }
- return false
-}
-
-func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) {
- valueEncoder(v)(e, v, opts)
-}
-
-type encOpts struct {
- // quoted causes primitive fields to be encoded inside JSON strings.
- quoted bool
- // escapeHTML causes '<', '>', and '&' to be escaped in JSON strings.
- escapeHTML bool
-}
-
-type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts)
-
-var encoderCache sync.Map // map[reflect.Type]encoderFunc
-
-func valueEncoder(v reflect.Value) encoderFunc {
- if !v.IsValid() {
- return invalidValueEncoder
- }
- return typeEncoder(v.Type())
-}
-
-func typeEncoder(t reflect.Type) encoderFunc {
- if fi, ok := encoderCache.Load(t); ok {
- return fi.(encoderFunc)
- }
-
- // To deal with recursive types, populate the map with an
- // indirect func before we build it. This type waits on the
- // real func (f) to be ready and then calls it. This indirect
- // func is only used for recursive types.
- var (
- wg sync.WaitGroup
- f encoderFunc
- )
- wg.Add(1)
- fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value, opts encOpts) {
- wg.Wait()
- f(e, v, opts)
- }))
- if loaded {
- return fi.(encoderFunc)
- }
-
- // Compute the real encoder and replace the indirect func with it.
- f = newTypeEncoder(t, true)
- wg.Done()
- encoderCache.Store(t, f)
- return f
-}
-
-var (
- marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
- textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
-)
-
-// newTypeEncoder constructs an encoderFunc for a type.
-// The returned encoder only checks CanAddr when allowAddr is true.
-func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
- // If we have a non-pointer value whose type implements
- // Marshaler with a value receiver, then we're better off taking
- // the address of the value - otherwise we end up with an
- // allocation as we cast the value to an interface.
- if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(marshalerType) {
- return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))
- }
- if t.Implements(marshalerType) {
- return marshalerEncoder
- }
- if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(textMarshalerType) {
- return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))
- }
- if t.Implements(textMarshalerType) {
- return textMarshalerEncoder
- }
-
- switch t.Kind() {
- case reflect.Bool:
- return boolEncoder
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return intEncoder
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return uintEncoder
- case reflect.Float32:
- return float32Encoder
- case reflect.Float64:
- return float64Encoder
- case reflect.String:
- return stringEncoder
- case reflect.Interface:
- return interfaceEncoder
- case reflect.Struct:
- return newStructEncoder(t)
- case reflect.Map:
- return newMapEncoder(t)
- case reflect.Slice:
- return newSliceEncoder(t)
- case reflect.Array:
- return newArrayEncoder(t)
- case reflect.Pointer:
- return newPtrEncoder(t)
- default:
- return unsupportedTypeEncoder
- }
-}
-
-func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) {
- e.WriteString("null")
-}
-
-func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
- if v.Kind() == reflect.Pointer && v.IsNil() {
- e.WriteString("null")
- return
- }
- m, ok := v.Interface().(Marshaler)
- if !ok {
- e.WriteString("null")
- return
- }
- b, err := m.MarshalJSON()
- if err == nil {
- // copy JSON into buffer, checking validity.
- err = compact(&e.Buffer, b, opts.escapeHTML)
- }
- if err != nil {
- e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
- }
-}
-
-func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
- va := v.Addr()
- if va.IsNil() {
- e.WriteString("null")
- return
- }
- m := va.Interface().(Marshaler)
- b, err := m.MarshalJSON()
- if err == nil {
- // copy JSON into buffer, checking validity.
- err = compact(&e.Buffer, b, opts.escapeHTML)
- }
- if err != nil {
- e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
- }
-}
-
-func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
- if v.Kind() == reflect.Pointer && v.IsNil() {
- e.WriteString("null")
- return
- }
- m, ok := v.Interface().(encoding.TextMarshaler)
- if !ok {
- e.WriteString("null")
- return
- }
- b, err := m.MarshalText()
- if err != nil {
- e.error(&MarshalerError{v.Type(), err, "MarshalText"})
- }
- e.stringBytes(b, opts.escapeHTML)
-}
-
-func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
- va := v.Addr()
- if va.IsNil() {
- e.WriteString("null")
- return
- }
- m := va.Interface().(encoding.TextMarshaler)
- b, err := m.MarshalText()
- if err != nil {
- e.error(&MarshalerError{v.Type(), err, "MarshalText"})
- }
- e.stringBytes(b, opts.escapeHTML)
-}
-
-func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) {
- if opts.quoted {
- e.WriteByte('"')
- }
- if v.Bool() {
- e.WriteString("true")
- } else {
- e.WriteString("false")
- }
- if opts.quoted {
- e.WriteByte('"')
- }
-}
-
-func intEncoder(e *encodeState, v reflect.Value, opts encOpts) {
- b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
- if opts.quoted {
- e.WriteByte('"')
- }
- e.Write(b)
- if opts.quoted {
- e.WriteByte('"')
- }
-}
-
-func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) {
- b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
- if opts.quoted {
- e.WriteByte('"')
- }
- e.Write(b)
- if opts.quoted {
- e.WriteByte('"')
- }
-}
-
-type floatEncoder int // number of bits
-
-func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
- f := v.Float()
- if math.IsInf(f, 0) || math.IsNaN(f) {
- e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))})
- }
-
- // Convert as if by ES6 number to string conversion.
- // This matches most other JSON generators.
- // See golang.org/issue/6384 and golang.org/issue/14135.
- // Like fmt %g, but the exponent cutoffs are different
- // and exponents themselves are not padded to two digits.
- b := e.scratch[:0]
- abs := math.Abs(f)
- fmt := byte('f')
- // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
- if abs != 0 {
- if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
- fmt = 'e'
- }
- }
- b = strconv.AppendFloat(b, f, fmt, -1, int(bits))
- if fmt == 'e' {
- // clean up e-09 to e-9
- n := len(b)
- if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
- b[n-2] = b[n-1]
- b = b[:n-1]
- }
- }
-
- if opts.quoted {
- e.WriteByte('"')
- }
- e.Write(b)
- if opts.quoted {
- e.WriteByte('"')
- }
-}
-
-var (
- float32Encoder = (floatEncoder(32)).encode
- float64Encoder = (floatEncoder(64)).encode
-)
-
-func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) {
- if v.Type() == numberType {
- numStr := v.String()
- // In Go1.5 the empty string encodes to "0", while this is not a valid number literal
- // we keep compatibility so check validity after this.
- if numStr == "" {
- numStr = "0" // Number's zero-val
- }
- if !isValidNumber(numStr) {
- e.error(fmt.Errorf("json: invalid number literal %q", numStr))
- }
- if opts.quoted {
- e.WriteByte('"')
- }
- e.WriteString(numStr)
- if opts.quoted {
- e.WriteByte('"')
- }
- return
- }
- if opts.quoted {
- e2 := newEncodeState()
- // Since we encode the string twice, we only need to escape HTML
- // the first time.
- e2.string(v.String(), opts.escapeHTML)
- e.stringBytes(e2.Bytes(), false)
- encodeStatePool.Put(e2)
- } else {
- e.string(v.String(), opts.escapeHTML)
- }
-}
-
-// isValidNumber reports whether s is a valid JSON number literal.
-func isValidNumber(s string) bool {
- // This function implements the JSON numbers grammar.
- // See https://tools.ietf.org/html/rfc7159#section-6
- // and https://www.json.org/img/number.png
-
- if s == "" {
- return false
- }
-
- // Optional -
- if s[0] == '-' {
- s = s[1:]
- if s == "" {
- return false
- }
- }
-
- // Digits
- switch {
- default:
- return false
-
- case s[0] == '0':
- s = s[1:]
-
- case '1' <= s[0] && s[0] <= '9':
- s = s[1:]
- for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
- s = s[1:]
- }
- }
-
- // . followed by 1 or more digits.
- if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
- s = s[2:]
- for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
- s = s[1:]
- }
- }
-
- // e or E followed by an optional - or + and
- // 1 or more digits.
- if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
- s = s[1:]
- if s[0] == '+' || s[0] == '-' {
- s = s[1:]
- if s == "" {
- return false
- }
- }
- for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
- s = s[1:]
- }
- }
-
- // Make sure we are at the end.
- return s == ""
-}
-
-func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) {
- if v.IsNil() {
- e.WriteString("null")
- return
- }
- e.reflectValue(v.Elem(), opts)
-}
-
-func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) {
- e.error(&UnsupportedTypeError{v.Type()})
-}
-
-type structEncoder struct {
- fields structFields
-}
-
-type structFields struct {
- list []field
- nameIndex map[string]int
-}
-
-func (se structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
- next := byte('{')
-FieldLoop:
- for i := range se.fields.list {
- f := &se.fields.list[i]
-
- // Find the nested struct field by following f.index.
- fv := v
- for _, i := range f.index {
- if fv.Kind() == reflect.Pointer {
- if fv.IsNil() {
- continue FieldLoop
- }
- fv = fv.Elem()
- }
- fv = fv.Field(i)
- }
-
- if f.omitEmpty && isEmptyValue(fv) {
- continue
- }
- e.WriteByte(next)
- next = ','
- if opts.escapeHTML {
- e.WriteString(f.nameEscHTML)
- } else {
- e.WriteString(f.nameNonEsc)
- }
- opts.quoted = f.quoted
- f.encoder(e, fv, opts)
- }
- if next == '{' {
- e.WriteString("{}")
- } else {
- e.WriteByte('}')
- }
-}
-
-func newStructEncoder(t reflect.Type) encoderFunc {
- se := structEncoder{fields: cachedTypeFields(t)}
- return se.encode
-}
-
-type mapEncoder struct {
- elemEnc encoderFunc
-}
-
-func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
- if v.IsNil() {
- e.WriteString("null")
- return
- }
- if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
- // We're a large number of nested ptrEncoder.encode calls deep;
- // start checking if we've run into a pointer cycle.
- ptr := v.UnsafePointer()
- if _, ok := e.ptrSeen[ptr]; ok {
- e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
- }
- e.ptrSeen[ptr] = struct{}{}
- defer delete(e.ptrSeen, ptr)
- }
- e.WriteByte('{')
-
- // Extract and sort the keys.
- sv := make([]reflectWithString, v.Len())
- mi := v.MapRange()
- for i := 0; mi.Next(); i++ {
- sv[i].k = mi.Key()
- sv[i].v = mi.Value()
- if err := sv[i].resolve(); err != nil {
- e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error()))
- }
- }
- sort.Slice(sv, func(i, j int) bool { return sv[i].ks < sv[j].ks })
-
- for i, kv := range sv {
- if i > 0 {
- e.WriteByte(',')
- }
- e.string(kv.ks, opts.escapeHTML)
- e.WriteByte(':')
- me.elemEnc(e, kv.v, opts)
- }
- e.WriteByte('}')
- e.ptrLevel--
-}
-
-func newMapEncoder(t reflect.Type) encoderFunc {
- switch t.Key().Kind() {
- case reflect.String,
- reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
- reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- default:
- if !t.Key().Implements(textMarshalerType) {
- return unsupportedTypeEncoder
- }
- }
- me := mapEncoder{typeEncoder(t.Elem())}
- return me.encode
-}
-
-func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) {
- if v.IsNil() {
- e.WriteString("null")
- return
- }
- s := v.Bytes()
- e.WriteByte('"')
- encodedLen := base64.StdEncoding.EncodedLen(len(s))
- if encodedLen <= len(e.scratch) {
- // If the encoded bytes fit in e.scratch, avoid an extra
- // allocation and use the cheaper Encoding.Encode.
- dst := e.scratch[:encodedLen]
- base64.StdEncoding.Encode(dst, s)
- e.Write(dst)
- } else if encodedLen <= 1024 {
- // The encoded bytes are short enough to allocate for, and
- // Encoding.Encode is still cheaper.
- dst := make([]byte, encodedLen)
- base64.StdEncoding.Encode(dst, s)
- e.Write(dst)
- } else {
- // The encoded bytes are too long to cheaply allocate, and
- // Encoding.Encode is no longer noticeably cheaper.
- enc := base64.NewEncoder(base64.StdEncoding, e)
- enc.Write(s)
- enc.Close()
- }
- e.WriteByte('"')
-}
-
-// sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil.
-type sliceEncoder struct {
- arrayEnc encoderFunc
-}
-
-func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
- if v.IsNil() {
- e.WriteString("null")
- return
- }
- if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
- // We're a large number of nested ptrEncoder.encode calls deep;
- // start checking if we've run into a pointer cycle.
- // Here we use a struct to memorize the pointer to the first element of the slice
- // and its length.
- ptr := struct {
- ptr interface{} // always an unsafe.Pointer, but avoids a dependency on package unsafe
- len int
- }{v.UnsafePointer(), v.Len()}
- if _, ok := e.ptrSeen[ptr]; ok {
- e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
- }
- e.ptrSeen[ptr] = struct{}{}
- defer delete(e.ptrSeen, ptr)
- }
- se.arrayEnc(e, v, opts)
- e.ptrLevel--
-}
-
-func newSliceEncoder(t reflect.Type) encoderFunc {
- // Byte slices get special treatment; arrays don't.
- if t.Elem().Kind() == reflect.Uint8 {
- p := reflect.PointerTo(t.Elem())
- if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) {
- return encodeByteSlice
- }
- }
- enc := sliceEncoder{newArrayEncoder(t)}
- return enc.encode
-}
-
-type arrayEncoder struct {
- elemEnc encoderFunc
-}
-
-func (ae arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
- e.WriteByte('[')
- n := v.Len()
- for i := 0; i < n; i++ {
- if i > 0 {
- e.WriteByte(',')
- }
- ae.elemEnc(e, v.Index(i), opts)
- }
- e.WriteByte(']')
-}
-
-func newArrayEncoder(t reflect.Type) encoderFunc {
- enc := arrayEncoder{typeEncoder(t.Elem())}
- return enc.encode
-}
-
-type ptrEncoder struct {
- elemEnc encoderFunc
-}
-
-func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
- if v.IsNil() {
- e.WriteString("null")
- return
- }
- if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
- // We're a large number of nested ptrEncoder.encode calls deep;
- // start checking if we've run into a pointer cycle.
- ptr := v.Interface()
- if _, ok := e.ptrSeen[ptr]; ok {
- e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
- }
- e.ptrSeen[ptr] = struct{}{}
- defer delete(e.ptrSeen, ptr)
- }
- pe.elemEnc(e, v.Elem(), opts)
- e.ptrLevel--
-}
-
-func newPtrEncoder(t reflect.Type) encoderFunc {
- enc := ptrEncoder{typeEncoder(t.Elem())}
- return enc.encode
-}
-
-type condAddrEncoder struct {
- canAddrEnc, elseEnc encoderFunc
-}
-
-func (ce condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
- if v.CanAddr() {
- ce.canAddrEnc(e, v, opts)
- } else {
- ce.elseEnc(e, v, opts)
- }
-}
-
-// newCondAddrEncoder returns an encoder that checks whether its value
-// CanAddr and delegates to canAddrEnc if so, else to elseEnc.
-func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc {
- enc := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}
- return enc.encode
-}
-
-func isValidTag(s string) bool {
- if s == "" {
- return false
- }
- for _, c := range s {
- switch {
- case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c):
- // Backslash and quote chars are reserved, but
- // otherwise any punctuation chars are allowed
- // in a tag name.
- case !unicode.IsLetter(c) && !unicode.IsDigit(c):
- return false
- }
- }
- return true
-}
-
-func typeByIndex(t reflect.Type, index []int) reflect.Type {
- for _, i := range index {
- if t.Kind() == reflect.Pointer {
- t = t.Elem()
- }
- t = t.Field(i).Type
- }
- return t
-}
-
-type reflectWithString struct {
- k reflect.Value
- v reflect.Value
- ks string
-}
-
-func (w *reflectWithString) resolve() error {
- if w.k.Kind() == reflect.String {
- w.ks = w.k.String()
- return nil
- }
- if tm, ok := w.k.Interface().(encoding.TextMarshaler); ok {
- if w.k.Kind() == reflect.Pointer && w.k.IsNil() {
- return nil
- }
- buf, err := tm.MarshalText()
- w.ks = string(buf)
- return err
- }
- switch w.k.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- w.ks = strconv.FormatInt(w.k.Int(), 10)
- return nil
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- w.ks = strconv.FormatUint(w.k.Uint(), 10)
- return nil
- }
- panic("unexpected map key type")
-}
-
-// NOTE: keep in sync with stringBytes below.
-func (e *encodeState) string(s string, escapeHTML bool) {
- e.WriteByte('"')
- start := 0
- for i := 0; i < len(s); {
- if b := s[i]; b < utf8.RuneSelf {
- if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
- i++
- continue
- }
- if start < i {
- e.WriteString(s[start:i])
- }
- e.WriteByte('\\')
- switch b {
- case '\\', '"':
- e.WriteByte(b)
- case '\n':
- e.WriteByte('n')
- case '\r':
- e.WriteByte('r')
- case '\t':
- e.WriteByte('t')
- default:
- // This encodes bytes < 0x20 except for \t, \n and \r.
- // If escapeHTML is set, it also escapes <, >, and &
- // because they can lead to security holes when
- // user-controlled strings are rendered into JSON
- // and served to some browsers.
- e.WriteString(`u00`)
- e.WriteByte(hex[b>>4])
- e.WriteByte(hex[b&0xF])
- }
- i++
- start = i
- continue
- }
- c, size := utf8.DecodeRuneInString(s[i:])
- if c == utf8.RuneError && size == 1 {
- if start < i {
- e.WriteString(s[start:i])
- }
- e.WriteString(`\ufffd`)
- i += size
- start = i
- continue
- }
- // U+2028 is LINE SEPARATOR.
- // U+2029 is PARAGRAPH SEPARATOR.
- // They are both technically valid characters in JSON strings,
- // but don't work in JSONP, which has to be evaluated as JavaScript,
- // and can lead to security holes there. It is valid JSON to
- // escape them, so we do so unconditionally.
- // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
- if c == '\u2028' || c == '\u2029' {
- if start < i {
- e.WriteString(s[start:i])
- }
- e.WriteString(`\u202`)
- e.WriteByte(hex[c&0xF])
- i += size
- start = i
- continue
- }
- i += size
- }
- if start < len(s) {
- e.WriteString(s[start:])
- }
- e.WriteByte('"')
-}
-
-// NOTE: keep in sync with string above.
-func (e *encodeState) stringBytes(s []byte, escapeHTML bool) {
- e.WriteByte('"')
- start := 0
- for i := 0; i < len(s); {
- if b := s[i]; b < utf8.RuneSelf {
- if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
- i++
- continue
- }
- if start < i {
- e.Write(s[start:i])
- }
- e.WriteByte('\\')
- switch b {
- case '\\', '"':
- e.WriteByte(b)
- case '\n':
- e.WriteByte('n')
- case '\r':
- e.WriteByte('r')
- case '\t':
- e.WriteByte('t')
- default:
- // This encodes bytes < 0x20 except for \t, \n and \r.
- // If escapeHTML is set, it also escapes <, >, and &
- // because they can lead to security holes when
- // user-controlled strings are rendered into JSON
- // and served to some browsers.
- e.WriteString(`u00`)
- e.WriteByte(hex[b>>4])
- e.WriteByte(hex[b&0xF])
- }
- i++
- start = i
- continue
- }
- c, size := utf8.DecodeRune(s[i:])
- if c == utf8.RuneError && size == 1 {
- if start < i {
- e.Write(s[start:i])
- }
- e.WriteString(`\ufffd`)
- i += size
- start = i
- continue
- }
- // U+2028 is LINE SEPARATOR.
- // U+2029 is PARAGRAPH SEPARATOR.
- // They are both technically valid characters in JSON strings,
- // but don't work in JSONP, which has to be evaluated as JavaScript,
- // and can lead to security holes there. It is valid JSON to
- // escape them, so we do so unconditionally.
- // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
- if c == '\u2028' || c == '\u2029' {
- if start < i {
- e.Write(s[start:i])
- }
- e.WriteString(`\u202`)
- e.WriteByte(hex[c&0xF])
- i += size
- start = i
- continue
- }
- i += size
- }
- if start < len(s) {
- e.Write(s[start:])
- }
- e.WriteByte('"')
-}
-
-// A field represents a single field found in a struct.
-type field struct {
- name string
- nameBytes []byte // []byte(name)
- equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent
-
- nameNonEsc string // `"` + name + `":`
- nameEscHTML string // `"` + HTMLEscape(name) + `":`
-
- tag bool
- index []int
- typ reflect.Type
- omitEmpty bool
- quoted bool
-
- encoder encoderFunc
-}
-
-// byIndex sorts field by index sequence.
-type byIndex []field
-
-func (x byIndex) Len() int { return len(x) }
-
-func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-func (x byIndex) Less(i, j int) bool {
- for k, xik := range x[i].index {
- if k >= len(x[j].index) {
- return false
- }
- if xik != x[j].index[k] {
- return xik < x[j].index[k]
- }
- }
- return len(x[i].index) < len(x[j].index)
-}
-
-// typeFields returns a list of fields that JSON should recognize for the given type.
-// The algorithm is breadth-first search over the set of structs to include - the top struct
-// and then any reachable anonymous structs.
-func typeFields(t reflect.Type) structFields {
- // Anonymous fields to explore at the current level and the next.
- current := []field{}
- next := []field{{typ: t}}
-
- // Count of queued names for current level and the next.
- var count, nextCount map[reflect.Type]int
-
- // Types already visited at an earlier level.
- visited := map[reflect.Type]bool{}
-
- // Fields found.
- var fields []field
-
- // Buffer to run HTMLEscape on field names.
- var nameEscBuf bytes.Buffer
-
- for len(next) > 0 {
- current, next = next, current[:0]
- count, nextCount = nextCount, map[reflect.Type]int{}
-
- for _, f := range current {
- if visited[f.typ] {
- continue
- }
- visited[f.typ] = true
-
- // Scan f.typ for fields to include.
- for i := 0; i < f.typ.NumField(); i++ {
- sf := f.typ.Field(i)
- if sf.Anonymous {
- t := sf.Type
- if t.Kind() == reflect.Pointer {
- t = t.Elem()
- }
- if !sf.IsExported() && t.Kind() != reflect.Struct {
- // Ignore embedded fields of unexported non-struct types.
- continue
- }
- // Do not ignore embedded fields of unexported struct types
- // since they may have exported fields.
- } else if !sf.IsExported() {
- // Ignore unexported non-embedded fields.
- continue
- }
- tag := sf.Tag.Get("json")
- if tag == "-" {
- continue
- }
- name, opts := parseTag(tag)
- if !isValidTag(name) {
- name = ""
- }
- index := make([]int, len(f.index)+1)
- copy(index, f.index)
- index[len(f.index)] = i
-
- ft := sf.Type
- if ft.Name() == "" && ft.Kind() == reflect.Pointer {
- // Follow pointer.
- ft = ft.Elem()
- }
-
- // Only strings, floats, integers, and booleans can be quoted.
- quoted := false
- if opts.Contains("string") {
- switch ft.Kind() {
- case reflect.Bool,
- reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
- reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
- reflect.Float32, reflect.Float64,
- reflect.String:
- quoted = true
- }
- }
-
- // Record found field and index sequence.
- if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
- tagged := name != ""
- if name == "" {
- name = sf.Name
- }
- field := field{
- name: name,
- tag: tagged,
- index: index,
- typ: ft,
- omitEmpty: opts.Contains("omitempty"),
- quoted: quoted,
- }
- field.nameBytes = []byte(field.name)
- field.equalFold = foldFunc(field.nameBytes)
-
- // Build nameEscHTML and nameNonEsc ahead of time.
- nameEscBuf.Reset()
- nameEscBuf.WriteString(`"`)
- HTMLEscape(&nameEscBuf, field.nameBytes)
- nameEscBuf.WriteString(`":`)
- field.nameEscHTML = nameEscBuf.String()
- field.nameNonEsc = `"` + field.name + `":`
-
- fields = append(fields, field)
- if count[f.typ] > 1 {
- // If there were multiple instances, add a second,
- // so that the annihilation code will see a duplicate.
- // It only cares about the distinction between 1 or 2,
- // so don't bother generating any more copies.
- fields = append(fields, fields[len(fields)-1])
- }
- continue
- }
-
- // Record new anonymous struct to explore in next round.
- nextCount[ft]++
- if nextCount[ft] == 1 {
- next = append(next, field{name: ft.Name(), index: index, typ: ft})
- }
- }
- }
- }
-
- sort.Slice(fields, func(i, j int) bool {
- x := fields
- // sort field by name, breaking ties with depth, then
- // breaking ties with "name came from json tag", then
- // breaking ties with index sequence.
- if x[i].name != x[j].name {
- return x[i].name < x[j].name
- }
- if len(x[i].index) != len(x[j].index) {
- return len(x[i].index) < len(x[j].index)
- }
- if x[i].tag != x[j].tag {
- return x[i].tag
- }
- return byIndex(x).Less(i, j)
- })
-
- // Delete all fields that are hidden by the Go rules for embedded fields,
- // except that fields with JSON tags are promoted.
-
- // The fields are sorted in primary order of name, secondary order
- // of field index length. Loop over names; for each name, delete
- // hidden fields by choosing the one dominant field that survives.
- out := fields[:0]
- for advance, i := 0, 0; i < len(fields); i += advance {
- // One iteration per name.
- // Find the sequence of fields with the name of this first field.
- fi := fields[i]
- name := fi.name
- for advance = 1; i+advance < len(fields); advance++ {
- fj := fields[i+advance]
- if fj.name != name {
- break
- }
- }
- if advance == 1 { // Only one field with this name
- out = append(out, fi)
- continue
- }
- dominant, ok := dominantField(fields[i : i+advance])
- if ok {
- out = append(out, dominant)
- }
- }
-
- fields = out
- sort.Sort(byIndex(fields))
-
- for i := range fields {
- f := &fields[i]
- f.encoder = typeEncoder(typeByIndex(t, f.index))
- }
- nameIndex := make(map[string]int, len(fields))
- for i, field := range fields {
- nameIndex[field.name] = i
- }
- return structFields{fields, nameIndex}
-}
-
-// dominantField looks through the fields, all of which are known to
-// have the same name, to find the single field that dominates the
-// others using Go's embedding rules, modified by the presence of
-// JSON tags. If there are multiple top-level fields, the boolean
-// will be false: This condition is an error in Go and we skip all
-// the fields.
-func dominantField(fields []field) (field, bool) {
- // The fields are sorted in increasing index-length order, then by presence of tag.
- // That means that the first field is the dominant one. We need only check
- // for error cases: two fields at top level, either both tagged or neither tagged.
- if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag {
- return field{}, false
- }
- return fields[0], true
-}
-
-var fieldCache sync.Map // map[reflect.Type]structFields
-
-// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
-func cachedTypeFields(t reflect.Type) structFields {
- if f, ok := fieldCache.Load(t); ok {
- return f.(structFields)
- }
- f, _ := fieldCache.LoadOrStore(t, typeFields(t))
- return f.(structFields)
-}
diff --git a/contrib/go/_std_1.20/src/encoding/json/fold.go b/contrib/go/_std_1.20/src/encoding/json/fold.go
deleted file mode 100644
index 0f9b09d712..0000000000
--- a/contrib/go/_std_1.20/src/encoding/json/fold.go
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2013 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 json
-
-import (
- "bytes"
- "unicode/utf8"
-)
-
-const (
- caseMask = ^byte(0x20) // Mask to ignore case in ASCII.
- kelvin = '\u212a'
- smallLongEss = '\u017f'
-)
-
-// foldFunc returns one of four different case folding equivalence
-// functions, from most general (and slow) to fastest:
-//
-// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8
-// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S')
-// 3) asciiEqualFold, no special, but includes non-letters (including _)
-// 4) simpleLetterEqualFold, no specials, no non-letters.
-//
-// The letters S and K are special because they map to 3 runes, not just 2:
-// - S maps to s and to U+017F 'ſ' Latin small letter long s
-// - k maps to K and to U+212A 'K' Kelvin sign
-//
-// See https://play.golang.org/p/tTxjOc0OGo
-//
-// The returned function is specialized for matching against s and
-// should only be given s. It's not curried for performance reasons.
-func foldFunc(s []byte) func(s, t []byte) bool {
- nonLetter := false
- special := false // special letter
- for _, b := range s {
- if b >= utf8.RuneSelf {
- return bytes.EqualFold
- }
- upper := b & caseMask
- if upper < 'A' || upper > 'Z' {
- nonLetter = true
- } else if upper == 'K' || upper == 'S' {
- // See above for why these letters are special.
- special = true
- }
- }
- if special {
- return equalFoldRight
- }
- if nonLetter {
- return asciiEqualFold
- }
- return simpleLetterEqualFold
-}
-
-// equalFoldRight is a specialization of bytes.EqualFold when s is
-// known to be all ASCII (including punctuation), but contains an 's',
-// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.
-// See comments on foldFunc.
-func equalFoldRight(s, t []byte) bool {
- for _, sb := range s {
- if len(t) == 0 {
- return false
- }
- tb := t[0]
- if tb < utf8.RuneSelf {
- if sb != tb {
- sbUpper := sb & caseMask
- if 'A' <= sbUpper && sbUpper <= 'Z' {
- if sbUpper != tb&caseMask {
- return false
- }
- } else {
- return false
- }
- }
- t = t[1:]
- continue
- }
- // sb is ASCII and t is not. t must be either kelvin
- // sign or long s; sb must be s, S, k, or K.
- tr, size := utf8.DecodeRune(t)
- switch sb {
- case 's', 'S':
- if tr != smallLongEss {
- return false
- }
- case 'k', 'K':
- if tr != kelvin {
- return false
- }
- default:
- return false
- }
- t = t[size:]
-
- }
- return len(t) == 0
-}
-
-// asciiEqualFold is a specialization of bytes.EqualFold for use when
-// s is all ASCII (but may contain non-letters) and contains no
-// special-folding letters.
-// See comments on foldFunc.
-func asciiEqualFold(s, t []byte) bool {
- if len(s) != len(t) {
- return false
- }
- for i, sb := range s {
- tb := t[i]
- if sb == tb {
- continue
- }
- if ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {
- if sb&caseMask != tb&caseMask {
- return false
- }
- } else {
- return false
- }
- }
- return true
-}
-
-// simpleLetterEqualFold is a specialization of bytes.EqualFold for
-// use when s is all ASCII letters (no underscores, etc) and also
-// doesn't contain 'k', 'K', 's', or 'S'.
-// See comments on foldFunc.
-func simpleLetterEqualFold(s, t []byte) bool {
- if len(s) != len(t) {
- return false
- }
- for i, b := range s {
- if b&caseMask != t[i]&caseMask {
- return false
- }
- }
- return true
-}
diff --git a/contrib/go/_std_1.20/src/encoding/json/indent.go b/contrib/go/_std_1.20/src/encoding/json/indent.go
deleted file mode 100644
index 2924d3b49b..0000000000
--- a/contrib/go/_std_1.20/src/encoding/json/indent.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2010 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 json
-
-import (
- "bytes"
-)
-
-// Compact appends to dst the JSON-encoded src with
-// insignificant space characters elided.
-func Compact(dst *bytes.Buffer, src []byte) error {
- return compact(dst, src, false)
-}
-
-func compact(dst *bytes.Buffer, src []byte, escape bool) error {
- origLen := dst.Len()
- scan := newScanner()
- defer freeScanner(scan)
- start := 0
- for i, c := range src {
- if escape && (c == '<' || c == '>' || c == '&') {
- if start < i {
- dst.Write(src[start:i])
- }
- dst.WriteString(`\u00`)
- dst.WriteByte(hex[c>>4])
- dst.WriteByte(hex[c&0xF])
- start = i + 1
- }
- // Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
- if escape && c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
- if start < i {
- dst.Write(src[start:i])
- }
- dst.WriteString(`\u202`)
- dst.WriteByte(hex[src[i+2]&0xF])
- start = i + 3
- }
- v := scan.step(scan, c)
- if v >= scanSkipSpace {
- if v == scanError {
- break
- }
- if start < i {
- dst.Write(src[start:i])
- }
- start = i + 1
- }
- }
- if scan.eof() == scanError {
- dst.Truncate(origLen)
- return scan.err
- }
- if start < len(src) {
- dst.Write(src[start:])
- }
- return nil
-}
-
-func newline(dst *bytes.Buffer, prefix, indent string, depth int) {
- dst.WriteByte('\n')
- dst.WriteString(prefix)
- for i := 0; i < depth; i++ {
- dst.WriteString(indent)
- }
-}
-
-// Indent appends to dst an indented form of the JSON-encoded src.
-// Each element in a JSON object or array begins on a new,
-// indented line beginning with prefix followed by one or more
-// copies of indent according to the indentation nesting.
-// The data appended to dst does not begin with the prefix nor
-// any indentation, to make it easier to embed inside other formatted JSON data.
-// Although leading space characters (space, tab, carriage return, newline)
-// at the beginning of src are dropped, trailing space characters
-// at the end of src are preserved and copied to dst.
-// For example, if src has no trailing spaces, neither will dst;
-// if src ends in a trailing newline, so will dst.
-func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
- origLen := dst.Len()
- scan := newScanner()
- defer freeScanner(scan)
- needIndent := false
- depth := 0
- for _, c := range src {
- scan.bytes++
- v := scan.step(scan, c)
- if v == scanSkipSpace {
- continue
- }
- if v == scanError {
- break
- }
- if needIndent && v != scanEndObject && v != scanEndArray {
- needIndent = false
- depth++
- newline(dst, prefix, indent, depth)
- }
-
- // Emit semantically uninteresting bytes
- // (in particular, punctuation in strings) unmodified.
- if v == scanContinue {
- dst.WriteByte(c)
- continue
- }
-
- // Add spacing around real punctuation.
- switch c {
- case '{', '[':
- // delay indent so that empty object and array are formatted as {} and [].
- needIndent = true
- dst.WriteByte(c)
-
- case ',':
- dst.WriteByte(c)
- newline(dst, prefix, indent, depth)
-
- case ':':
- dst.WriteByte(c)
- dst.WriteByte(' ')
-
- case '}', ']':
- if needIndent {
- // suppress indent in empty object/array
- needIndent = false
- } else {
- depth--
- newline(dst, prefix, indent, depth)
- }
- dst.WriteByte(c)
-
- default:
- dst.WriteByte(c)
- }
- }
- if scan.eof() == scanError {
- dst.Truncate(origLen)
- return scan.err
- }
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/encoding/json/stream.go b/contrib/go/_std_1.20/src/encoding/json/stream.go
deleted file mode 100644
index 1442ef29ef..0000000000
--- a/contrib/go/_std_1.20/src/encoding/json/stream.go
+++ /dev/null
@@ -1,515 +0,0 @@
-// Copyright 2010 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 json
-
-import (
- "bytes"
- "errors"
- "io"
-)
-
-// A Decoder reads and decodes JSON values from an input stream.
-type Decoder struct {
- r io.Reader
- buf []byte
- d decodeState
- scanp int // start of unread data in buf
- scanned int64 // amount of data already scanned
- scan scanner
- err error
-
- tokenState int
- tokenStack []int
-}
-
-// NewDecoder returns a new decoder that reads from r.
-//
-// The decoder introduces its own buffering and may
-// read data from r beyond the JSON values requested.
-func NewDecoder(r io.Reader) *Decoder {
- return &Decoder{r: r}
-}
-
-// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
-// Number instead of as a float64.
-func (dec *Decoder) UseNumber() { dec.d.useNumber = true }
-
-// DisallowUnknownFields causes the Decoder to return an error when the destination
-// is a struct and the input contains object keys which do not match any
-// non-ignored, exported fields in the destination.
-func (dec *Decoder) DisallowUnknownFields() { dec.d.disallowUnknownFields = true }
-
-// Decode reads the next JSON-encoded value from its
-// input and stores it in the value pointed to by v.
-//
-// See the documentation for Unmarshal for details about
-// the conversion of JSON into a Go value.
-func (dec *Decoder) Decode(v any) error {
- if dec.err != nil {
- return dec.err
- }
-
- if err := dec.tokenPrepareForDecode(); err != nil {
- return err
- }
-
- if !dec.tokenValueAllowed() {
- return &SyntaxError{msg: "not at beginning of value", Offset: dec.InputOffset()}
- }
-
- // Read whole value into buffer.
- n, err := dec.readValue()
- if err != nil {
- return err
- }
- dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
- dec.scanp += n
-
- // Don't save err from unmarshal into dec.err:
- // the connection is still usable since we read a complete JSON
- // object from it before the error happened.
- err = dec.d.unmarshal(v)
-
- // fixup token streaming state
- dec.tokenValueEnd()
-
- return err
-}
-
-// Buffered returns a reader of the data remaining in the Decoder's
-// buffer. The reader is valid until the next call to Decode.
-func (dec *Decoder) Buffered() io.Reader {
- return bytes.NewReader(dec.buf[dec.scanp:])
-}
-
-// readValue reads a JSON value into dec.buf.
-// It returns the length of the encoding.
-func (dec *Decoder) readValue() (int, error) {
- dec.scan.reset()
-
- scanp := dec.scanp
- var err error
-Input:
- // help the compiler see that scanp is never negative, so it can remove
- // some bounds checks below.
- for scanp >= 0 {
-
- // Look in the buffer for a new value.
- for ; scanp < len(dec.buf); scanp++ {
- c := dec.buf[scanp]
- dec.scan.bytes++
- switch dec.scan.step(&dec.scan, c) {
- case scanEnd:
- // scanEnd is delayed one byte so we decrement
- // the scanner bytes count by 1 to ensure that
- // this value is correct in the next call of Decode.
- dec.scan.bytes--
- break Input
- case scanEndObject, scanEndArray:
- // scanEnd is delayed one byte.
- // We might block trying to get that byte from src,
- // so instead invent a space byte.
- if stateEndValue(&dec.scan, ' ') == scanEnd {
- scanp++
- break Input
- }
- case scanError:
- dec.err = dec.scan.err
- return 0, dec.scan.err
- }
- }
-
- // Did the last read have an error?
- // Delayed until now to allow buffer scan.
- if err != nil {
- if err == io.EOF {
- if dec.scan.step(&dec.scan, ' ') == scanEnd {
- break Input
- }
- if nonSpace(dec.buf) {
- err = io.ErrUnexpectedEOF
- }
- }
- dec.err = err
- return 0, err
- }
-
- n := scanp - dec.scanp
- err = dec.refill()
- scanp = dec.scanp + n
- }
- return scanp - dec.scanp, nil
-}
-
-func (dec *Decoder) refill() error {
- // Make room to read more into the buffer.
- // First slide down data already consumed.
- if dec.scanp > 0 {
- dec.scanned += int64(dec.scanp)
- n := copy(dec.buf, dec.buf[dec.scanp:])
- dec.buf = dec.buf[:n]
- dec.scanp = 0
- }
-
- // Grow buffer if not large enough.
- const minRead = 512
- if cap(dec.buf)-len(dec.buf) < minRead {
- newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
- copy(newBuf, dec.buf)
- dec.buf = newBuf
- }
-
- // Read. Delay error for next iteration (after scan).
- n, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
- dec.buf = dec.buf[0 : len(dec.buf)+n]
-
- return err
-}
-
-func nonSpace(b []byte) bool {
- for _, c := range b {
- if !isSpace(c) {
- return true
- }
- }
- return false
-}
-
-// An Encoder writes JSON values to an output stream.
-type Encoder struct {
- w io.Writer
- err error
- escapeHTML bool
-
- indentBuf *bytes.Buffer
- indentPrefix string
- indentValue string
-}
-
-// NewEncoder returns a new encoder that writes to w.
-func NewEncoder(w io.Writer) *Encoder {
- return &Encoder{w: w, escapeHTML: true}
-}
-
-// Encode writes the JSON encoding of v to the stream,
-// followed by a newline character.
-//
-// See the documentation for Marshal for details about the
-// conversion of Go values to JSON.
-func (enc *Encoder) Encode(v any) error {
- if enc.err != nil {
- return enc.err
- }
-
- e := newEncodeState()
- defer encodeStatePool.Put(e)
-
- err := e.marshal(v, encOpts{escapeHTML: enc.escapeHTML})
- if err != nil {
- return err
- }
-
- // Terminate each value with a newline.
- // This makes the output look a little nicer
- // when debugging, and some kind of space
- // is required if the encoded value was a number,
- // so that the reader knows there aren't more
- // digits coming.
- e.WriteByte('\n')
-
- b := e.Bytes()
- if enc.indentPrefix != "" || enc.indentValue != "" {
- if enc.indentBuf == nil {
- enc.indentBuf = new(bytes.Buffer)
- }
- enc.indentBuf.Reset()
- err = Indent(enc.indentBuf, b, enc.indentPrefix, enc.indentValue)
- if err != nil {
- return err
- }
- b = enc.indentBuf.Bytes()
- }
- if _, err = enc.w.Write(b); err != nil {
- enc.err = err
- }
- return err
-}
-
-// SetIndent instructs the encoder to format each subsequent encoded
-// value as if indented by the package-level function Indent(dst, src, prefix, indent).
-// Calling SetIndent("", "") disables indentation.
-func (enc *Encoder) SetIndent(prefix, indent string) {
- enc.indentPrefix = prefix
- enc.indentValue = indent
-}
-
-// SetEscapeHTML specifies whether problematic HTML characters
-// should be escaped inside JSON quoted strings.
-// The default behavior is to escape &, <, and > to \u0026, \u003c, and \u003e
-// to avoid certain safety problems that can arise when embedding JSON in HTML.
-//
-// In non-HTML settings where the escaping interferes with the readability
-// of the output, SetEscapeHTML(false) disables this behavior.
-func (enc *Encoder) SetEscapeHTML(on bool) {
- enc.escapeHTML = on
-}
-
-// RawMessage is a raw encoded JSON value.
-// It implements Marshaler and Unmarshaler and can
-// be used to delay JSON decoding or precompute a JSON encoding.
-type RawMessage []byte
-
-// MarshalJSON returns m as the JSON encoding of m.
-func (m RawMessage) MarshalJSON() ([]byte, error) {
- if m == nil {
- return []byte("null"), nil
- }
- return m, nil
-}
-
-// UnmarshalJSON sets *m to a copy of data.
-func (m *RawMessage) UnmarshalJSON(data []byte) error {
- if m == nil {
- return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
- }
- *m = append((*m)[0:0], data...)
- return nil
-}
-
-var _ Marshaler = (*RawMessage)(nil)
-var _ Unmarshaler = (*RawMessage)(nil)
-
-// A Token holds a value of one of these types:
-//
-// Delim, for the four JSON delimiters [ ] { }
-// bool, for JSON booleans
-// float64, for JSON numbers
-// Number, for JSON numbers
-// string, for JSON string literals
-// nil, for JSON null
-type Token any
-
-const (
- tokenTopValue = iota
- tokenArrayStart
- tokenArrayValue
- tokenArrayComma
- tokenObjectStart
- tokenObjectKey
- tokenObjectColon
- tokenObjectValue
- tokenObjectComma
-)
-
-// advance tokenstate from a separator state to a value state
-func (dec *Decoder) tokenPrepareForDecode() error {
- // Note: Not calling peek before switch, to avoid
- // putting peek into the standard Decode path.
- // peek is only called when using the Token API.
- switch dec.tokenState {
- case tokenArrayComma:
- c, err := dec.peek()
- if err != nil {
- return err
- }
- if c != ',' {
- return &SyntaxError{"expected comma after array element", dec.InputOffset()}
- }
- dec.scanp++
- dec.tokenState = tokenArrayValue
- case tokenObjectColon:
- c, err := dec.peek()
- if err != nil {
- return err
- }
- if c != ':' {
- return &SyntaxError{"expected colon after object key", dec.InputOffset()}
- }
- dec.scanp++
- dec.tokenState = tokenObjectValue
- }
- return nil
-}
-
-func (dec *Decoder) tokenValueAllowed() bool {
- switch dec.tokenState {
- case tokenTopValue, tokenArrayStart, tokenArrayValue, tokenObjectValue:
- return true
- }
- return false
-}
-
-func (dec *Decoder) tokenValueEnd() {
- switch dec.tokenState {
- case tokenArrayStart, tokenArrayValue:
- dec.tokenState = tokenArrayComma
- case tokenObjectValue:
- dec.tokenState = tokenObjectComma
- }
-}
-
-// A Delim is a JSON array or object delimiter, one of [ ] { or }.
-type Delim rune
-
-func (d Delim) String() string {
- return string(d)
-}
-
-// Token returns the next JSON token in the input stream.
-// At the end of the input stream, Token returns nil, io.EOF.
-//
-// Token guarantees that the delimiters [ ] { } it returns are
-// properly nested and matched: if Token encounters an unexpected
-// delimiter in the input, it will return an error.
-//
-// The input stream consists of basic JSON values—bool, string,
-// number, and null—along with delimiters [ ] { } of type Delim
-// to mark the start and end of arrays and objects.
-// Commas and colons are elided.
-func (dec *Decoder) Token() (Token, error) {
- for {
- c, err := dec.peek()
- if err != nil {
- return nil, err
- }
- switch c {
- case '[':
- if !dec.tokenValueAllowed() {
- return dec.tokenError(c)
- }
- dec.scanp++
- dec.tokenStack = append(dec.tokenStack, dec.tokenState)
- dec.tokenState = tokenArrayStart
- return Delim('['), nil
-
- case ']':
- if dec.tokenState != tokenArrayStart && dec.tokenState != tokenArrayComma {
- return dec.tokenError(c)
- }
- dec.scanp++
- dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
- dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
- dec.tokenValueEnd()
- return Delim(']'), nil
-
- case '{':
- if !dec.tokenValueAllowed() {
- return dec.tokenError(c)
- }
- dec.scanp++
- dec.tokenStack = append(dec.tokenStack, dec.tokenState)
- dec.tokenState = tokenObjectStart
- return Delim('{'), nil
-
- case '}':
- if dec.tokenState != tokenObjectStart && dec.tokenState != tokenObjectComma {
- return dec.tokenError(c)
- }
- dec.scanp++
- dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
- dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
- dec.tokenValueEnd()
- return Delim('}'), nil
-
- case ':':
- if dec.tokenState != tokenObjectColon {
- return dec.tokenError(c)
- }
- dec.scanp++
- dec.tokenState = tokenObjectValue
- continue
-
- case ',':
- if dec.tokenState == tokenArrayComma {
- dec.scanp++
- dec.tokenState = tokenArrayValue
- continue
- }
- if dec.tokenState == tokenObjectComma {
- dec.scanp++
- dec.tokenState = tokenObjectKey
- continue
- }
- return dec.tokenError(c)
-
- case '"':
- if dec.tokenState == tokenObjectStart || dec.tokenState == tokenObjectKey {
- var x string
- old := dec.tokenState
- dec.tokenState = tokenTopValue
- err := dec.Decode(&x)
- dec.tokenState = old
- if err != nil {
- return nil, err
- }
- dec.tokenState = tokenObjectColon
- return x, nil
- }
- fallthrough
-
- default:
- if !dec.tokenValueAllowed() {
- return dec.tokenError(c)
- }
- var x any
- if err := dec.Decode(&x); err != nil {
- return nil, err
- }
- return x, nil
- }
- }
-}
-
-func (dec *Decoder) tokenError(c byte) (Token, error) {
- var context string
- switch dec.tokenState {
- case tokenTopValue:
- context = " looking for beginning of value"
- case tokenArrayStart, tokenArrayValue, tokenObjectValue:
- context = " looking for beginning of value"
- case tokenArrayComma:
- context = " after array element"
- case tokenObjectKey:
- context = " looking for beginning of object key string"
- case tokenObjectColon:
- context = " after object key"
- case tokenObjectComma:
- context = " after object key:value pair"
- }
- return nil, &SyntaxError{"invalid character " + quoteChar(c) + context, dec.InputOffset()}
-}
-
-// More reports whether there is another element in the
-// current array or object being parsed.
-func (dec *Decoder) More() bool {
- c, err := dec.peek()
- return err == nil && c != ']' && c != '}'
-}
-
-func (dec *Decoder) peek() (byte, error) {
- var err error
- for {
- for i := dec.scanp; i < len(dec.buf); i++ {
- c := dec.buf[i]
- if isSpace(c) {
- continue
- }
- dec.scanp = i
- return c, nil
- }
- // buffer has been scanned, now report any error
- if err != nil {
- return 0, err
- }
- err = dec.refill()
- }
-}
-
-// InputOffset returns the input stream byte offset of the current decoder position.
-// The offset gives the location of the end of the most recently returned token
-// and the beginning of the next token.
-func (dec *Decoder) InputOffset() int64 {
- return dec.scanned + int64(dec.scanp)
-}
diff --git a/contrib/go/_std_1.20/src/encoding/json/ya.make b/contrib/go/_std_1.20/src/encoding/json/ya.make
deleted file mode 100644
index cb8eb38232..0000000000
--- a/contrib/go/_std_1.20/src/encoding/json/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- decode.go
- encode.go
- fold.go
- indent.go
- scanner.go
- stream.go
- tables.go
- tags.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/encoding/pem/ya.make b/contrib/go/_std_1.20/src/encoding/pem/ya.make
deleted file mode 100644
index f15f1645d2..0000000000
--- a/contrib/go/_std_1.20/src/encoding/pem/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- pem.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/encoding/xml/marshal.go b/contrib/go/_std_1.20/src/encoding/xml/marshal.go
deleted file mode 100644
index 07b6042da8..0000000000
--- a/contrib/go/_std_1.20/src/encoding/xml/marshal.go
+++ /dev/null
@@ -1,1129 +0,0 @@
-// Copyright 2011 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 xml
-
-import (
- "bufio"
- "bytes"
- "encoding"
- "errors"
- "fmt"
- "io"
- "reflect"
- "strconv"
- "strings"
-)
-
-const (
- // Header is a generic XML header suitable for use with the output of Marshal.
- // This is not automatically added to any output of this package,
- // it is provided as a convenience.
- Header = `<?xml version="1.0" encoding="UTF-8"?>` + "\n"
-)
-
-// Marshal returns the XML encoding of v.
-//
-// Marshal handles an array or slice by marshaling each of the elements.
-// Marshal handles a pointer by marshaling the value it points at or, if the
-// pointer is nil, by writing nothing. Marshal handles an interface value by
-// marshaling the value it contains or, if the interface value is nil, by
-// writing nothing. Marshal handles all other data by writing one or more XML
-// elements containing the data.
-//
-// The name for the XML elements is taken from, in order of preference:
-// - the tag on the XMLName field, if the data is a struct
-// - the value of the XMLName field of type Name
-// - the tag of the struct field used to obtain the data
-// - the name of the struct field used to obtain the data
-// - the name of the marshaled type
-//
-// The XML element for a struct contains marshaled elements for each of the
-// exported fields of the struct, with these exceptions:
-// - the XMLName field, described above, is omitted.
-// - a field with tag "-" is omitted.
-// - a field with tag "name,attr" becomes an attribute with
-// the given name in the XML element.
-// - a field with tag ",attr" becomes an attribute with the
-// field name in the XML element.
-// - a field with tag ",chardata" is written as character data,
-// not as an XML element.
-// - a field with tag ",cdata" is written as character data
-// wrapped in one or more <![CDATA[ ... ]]> tags, not as an XML element.
-// - a field with tag ",innerxml" is written verbatim, not subject
-// to the usual marshaling procedure.
-// - a field with tag ",comment" is written as an XML comment, not
-// subject to the usual marshaling procedure. It must not contain
-// the "--" string within it.
-// - a field with a tag including the "omitempty" option is omitted
-// if the field value is empty. The empty values are false, 0, any
-// nil pointer or interface value, and any array, slice, map, or
-// string of length zero.
-// - an anonymous struct field is handled as if the fields of its
-// value were part of the outer struct.
-// - a field implementing Marshaler is written by calling its MarshalXML
-// method.
-// - a field implementing encoding.TextMarshaler is written by encoding the
-// result of its MarshalText method as text.
-//
-// If a field uses a tag "a>b>c", then the element c will be nested inside
-// parent elements a and b. Fields that appear next to each other that name
-// the same parent will be enclosed in one XML element.
-//
-// If the XML name for a struct field is defined by both the field tag and the
-// struct's XMLName field, the names must match.
-//
-// See MarshalIndent for an example.
-//
-// Marshal will return an error if asked to marshal a channel, function, or map.
-func Marshal(v any) ([]byte, error) {
- var b bytes.Buffer
- enc := NewEncoder(&b)
- if err := enc.Encode(v); err != nil {
- return nil, err
- }
- if err := enc.Close(); err != nil {
- return nil, err
- }
- return b.Bytes(), nil
-}
-
-// Marshaler is the interface implemented by objects that can marshal
-// themselves into valid XML elements.
-//
-// MarshalXML encodes the receiver as zero or more XML elements.
-// By convention, arrays or slices are typically encoded as a sequence
-// of elements, one per entry.
-// Using start as the element tag is not required, but doing so
-// will enable Unmarshal to match the XML elements to the correct
-// struct field.
-// One common implementation strategy is to construct a separate
-// value with a layout corresponding to the desired XML and then
-// to encode it using e.EncodeElement.
-// Another common strategy is to use repeated calls to e.EncodeToken
-// to generate the XML output one token at a time.
-// The sequence of encoded tokens must make up zero or more valid
-// XML elements.
-type Marshaler interface {
- MarshalXML(e *Encoder, start StartElement) error
-}
-
-// MarshalerAttr is the interface implemented by objects that can marshal
-// themselves into valid XML attributes.
-//
-// MarshalXMLAttr returns an XML attribute with the encoded value of the receiver.
-// Using name as the attribute name is not required, but doing so
-// will enable Unmarshal to match the attribute to the correct
-// struct field.
-// If MarshalXMLAttr returns the zero attribute Attr{}, no attribute
-// will be generated in the output.
-// MarshalXMLAttr is used only for struct fields with the
-// "attr" option in the field tag.
-type MarshalerAttr interface {
- MarshalXMLAttr(name Name) (Attr, error)
-}
-
-// MarshalIndent works like Marshal, but each XML element begins on a new
-// indented line that starts with prefix and is followed by one or more
-// copies of indent according to the nesting depth.
-func MarshalIndent(v any, prefix, indent string) ([]byte, error) {
- var b bytes.Buffer
- enc := NewEncoder(&b)
- enc.Indent(prefix, indent)
- if err := enc.Encode(v); err != nil {
- return nil, err
- }
- if err := enc.Close(); err != nil {
- return nil, err
- }
- return b.Bytes(), nil
-}
-
-// An Encoder writes XML data to an output stream.
-type Encoder struct {
- p printer
-}
-
-// NewEncoder returns a new encoder that writes to w.
-func NewEncoder(w io.Writer) *Encoder {
- e := &Encoder{printer{w: bufio.NewWriter(w)}}
- e.p.encoder = e
- return e
-}
-
-// Indent sets the encoder to generate XML in which each element
-// begins on a new indented line that starts with prefix and is followed by
-// one or more copies of indent according to the nesting depth.
-func (enc *Encoder) Indent(prefix, indent string) {
- enc.p.prefix = prefix
- enc.p.indent = indent
-}
-
-// Encode writes the XML encoding of v to the stream.
-//
-// See the documentation for Marshal for details about the conversion
-// of Go values to XML.
-//
-// Encode calls Flush before returning.
-func (enc *Encoder) Encode(v any) error {
- err := enc.p.marshalValue(reflect.ValueOf(v), nil, nil)
- if err != nil {
- return err
- }
- return enc.p.w.Flush()
-}
-
-// EncodeElement writes the XML encoding of v to the stream,
-// using start as the outermost tag in the encoding.
-//
-// See the documentation for Marshal for details about the conversion
-// of Go values to XML.
-//
-// EncodeElement calls Flush before returning.
-func (enc *Encoder) EncodeElement(v any, start StartElement) error {
- err := enc.p.marshalValue(reflect.ValueOf(v), nil, &start)
- if err != nil {
- return err
- }
- return enc.p.w.Flush()
-}
-
-var (
- begComment = []byte("<!--")
- endComment = []byte("-->")
- endProcInst = []byte("?>")
-)
-
-// EncodeToken writes the given XML token to the stream.
-// It returns an error if StartElement and EndElement tokens are not properly matched.
-//
-// EncodeToken does not call Flush, because usually it is part of a larger operation
-// such as Encode or EncodeElement (or a custom Marshaler's MarshalXML invoked
-// during those), and those will call Flush when finished.
-// Callers that create an Encoder and then invoke EncodeToken directly, without
-// using Encode or EncodeElement, need to call Flush when finished to ensure
-// that the XML is written to the underlying writer.
-//
-// EncodeToken allows writing a ProcInst with Target set to "xml" only as the first token
-// in the stream.
-func (enc *Encoder) EncodeToken(t Token) error {
-
- p := &enc.p
- switch t := t.(type) {
- case StartElement:
- if err := p.writeStart(&t); err != nil {
- return err
- }
- case EndElement:
- if err := p.writeEnd(t.Name); err != nil {
- return err
- }
- case CharData:
- escapeText(p, t, false)
- case Comment:
- if bytes.Contains(t, endComment) {
- return fmt.Errorf("xml: EncodeToken of Comment containing --> marker")
- }
- p.WriteString("<!--")
- p.Write(t)
- p.WriteString("-->")
- return p.cachedWriteError()
- case ProcInst:
- // First token to be encoded which is also a ProcInst with target of xml
- // is the xml declaration. The only ProcInst where target of xml is allowed.
- if t.Target == "xml" && p.w.Buffered() != 0 {
- return fmt.Errorf("xml: EncodeToken of ProcInst xml target only valid for xml declaration, first token encoded")
- }
- if !isNameString(t.Target) {
- return fmt.Errorf("xml: EncodeToken of ProcInst with invalid Target")
- }
- if bytes.Contains(t.Inst, endProcInst) {
- return fmt.Errorf("xml: EncodeToken of ProcInst containing ?> marker")
- }
- p.WriteString("<?")
- p.WriteString(t.Target)
- if len(t.Inst) > 0 {
- p.WriteByte(' ')
- p.Write(t.Inst)
- }
- p.WriteString("?>")
- case Directive:
- if !isValidDirective(t) {
- return fmt.Errorf("xml: EncodeToken of Directive containing wrong < or > markers")
- }
- p.WriteString("<!")
- p.Write(t)
- p.WriteString(">")
- default:
- return fmt.Errorf("xml: EncodeToken of invalid token type")
-
- }
- return p.cachedWriteError()
-}
-
-// isValidDirective reports whether dir is a valid directive text,
-// meaning angle brackets are matched, ignoring comments and strings.
-func isValidDirective(dir Directive) bool {
- var (
- depth int
- inquote uint8
- incomment bool
- )
- for i, c := range dir {
- switch {
- case incomment:
- if c == '>' {
- if n := 1 + i - len(endComment); n >= 0 && bytes.Equal(dir[n:i+1], endComment) {
- incomment = false
- }
- }
- // Just ignore anything in comment
- case inquote != 0:
- if c == inquote {
- inquote = 0
- }
- // Just ignore anything within quotes
- case c == '\'' || c == '"':
- inquote = c
- case c == '<':
- if i+len(begComment) < len(dir) && bytes.Equal(dir[i:i+len(begComment)], begComment) {
- incomment = true
- } else {
- depth++
- }
- case c == '>':
- if depth == 0 {
- return false
- }
- depth--
- }
- }
- return depth == 0 && inquote == 0 && !incomment
-}
-
-// Flush flushes any buffered XML to the underlying writer.
-// See the EncodeToken documentation for details about when it is necessary.
-func (enc *Encoder) Flush() error {
- return enc.p.w.Flush()
-}
-
-// Close the Encoder, indicating that no more data will be written. It flushes
-// any buffered XML to the underlying writer and returns an error if the
-// written XML is invalid (e.g. by containing unclosed elements).
-func (enc *Encoder) Close() error {
- return enc.p.Close()
-}
-
-type printer struct {
- w *bufio.Writer
- encoder *Encoder
- seq int
- indent string
- prefix string
- depth int
- indentedIn bool
- putNewline bool
- attrNS map[string]string // map prefix -> name space
- attrPrefix map[string]string // map name space -> prefix
- prefixes []string
- tags []Name
- closed bool
- err error
-}
-
-// createAttrPrefix finds the name space prefix attribute to use for the given name space,
-// defining a new prefix if necessary. It returns the prefix.
-func (p *printer) createAttrPrefix(url string) string {
- if prefix := p.attrPrefix[url]; prefix != "" {
- return prefix
- }
-
- // The "http://www.w3.org/XML/1998/namespace" name space is predefined as "xml"
- // and must be referred to that way.
- // (The "http://www.w3.org/2000/xmlns/" name space is also predefined as "xmlns",
- // but users should not be trying to use that one directly - that's our job.)
- if url == xmlURL {
- return xmlPrefix
- }
-
- // Need to define a new name space.
- if p.attrPrefix == nil {
- p.attrPrefix = make(map[string]string)
- p.attrNS = make(map[string]string)
- }
-
- // Pick a name. We try to use the final element of the path
- // but fall back to _.
- prefix := strings.TrimRight(url, "/")
- if i := strings.LastIndex(prefix, "/"); i >= 0 {
- prefix = prefix[i+1:]
- }
- if prefix == "" || !isName([]byte(prefix)) || strings.Contains(prefix, ":") {
- prefix = "_"
- }
- // xmlanything is reserved and any variant of it regardless of
- // case should be matched, so:
- // (('X'|'x') ('M'|'m') ('L'|'l'))
- // See Section 2.3 of https://www.w3.org/TR/REC-xml/
- if len(prefix) >= 3 && strings.EqualFold(prefix[:3], "xml") {
- prefix = "_" + prefix
- }
- if p.attrNS[prefix] != "" {
- // Name is taken. Find a better one.
- for p.seq++; ; p.seq++ {
- if id := prefix + "_" + strconv.Itoa(p.seq); p.attrNS[id] == "" {
- prefix = id
- break
- }
- }
- }
-
- p.attrPrefix[url] = prefix
- p.attrNS[prefix] = url
-
- p.WriteString(`xmlns:`)
- p.WriteString(prefix)
- p.WriteString(`="`)
- EscapeText(p, []byte(url))
- p.WriteString(`" `)
-
- p.prefixes = append(p.prefixes, prefix)
-
- return prefix
-}
-
-// deleteAttrPrefix removes an attribute name space prefix.
-func (p *printer) deleteAttrPrefix(prefix string) {
- delete(p.attrPrefix, p.attrNS[prefix])
- delete(p.attrNS, prefix)
-}
-
-func (p *printer) markPrefix() {
- p.prefixes = append(p.prefixes, "")
-}
-
-func (p *printer) popPrefix() {
- for len(p.prefixes) > 0 {
- prefix := p.prefixes[len(p.prefixes)-1]
- p.prefixes = p.prefixes[:len(p.prefixes)-1]
- if prefix == "" {
- break
- }
- p.deleteAttrPrefix(prefix)
- }
-}
-
-var (
- marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
- marshalerAttrType = reflect.TypeOf((*MarshalerAttr)(nil)).Elem()
- textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
-)
-
-// marshalValue writes one or more XML elements representing val.
-// If val was obtained from a struct field, finfo must have its details.
-func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplate *StartElement) error {
- if startTemplate != nil && startTemplate.Name.Local == "" {
- return fmt.Errorf("xml: EncodeElement of StartElement with missing name")
- }
-
- if !val.IsValid() {
- return nil
- }
- if finfo != nil && finfo.flags&fOmitEmpty != 0 && isEmptyValue(val) {
- return nil
- }
-
- // Drill into interfaces and pointers.
- // This can turn into an infinite loop given a cyclic chain,
- // but it matches the Go 1 behavior.
- for val.Kind() == reflect.Interface || val.Kind() == reflect.Pointer {
- if val.IsNil() {
- return nil
- }
- val = val.Elem()
- }
-
- kind := val.Kind()
- typ := val.Type()
-
- // Check for marshaler.
- if val.CanInterface() && typ.Implements(marshalerType) {
- return p.marshalInterface(val.Interface().(Marshaler), defaultStart(typ, finfo, startTemplate))
- }
- if val.CanAddr() {
- pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(marshalerType) {
- return p.marshalInterface(pv.Interface().(Marshaler), defaultStart(pv.Type(), finfo, startTemplate))
- }
- }
-
- // Check for text marshaler.
- if val.CanInterface() && typ.Implements(textMarshalerType) {
- return p.marshalTextInterface(val.Interface().(encoding.TextMarshaler), defaultStart(typ, finfo, startTemplate))
- }
- if val.CanAddr() {
- pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
- return p.marshalTextInterface(pv.Interface().(encoding.TextMarshaler), defaultStart(pv.Type(), finfo, startTemplate))
- }
- }
-
- // Slices and arrays iterate over the elements. They do not have an enclosing tag.
- if (kind == reflect.Slice || kind == reflect.Array) && typ.Elem().Kind() != reflect.Uint8 {
- for i, n := 0, val.Len(); i < n; i++ {
- if err := p.marshalValue(val.Index(i), finfo, startTemplate); err != nil {
- return err
- }
- }
- return nil
- }
-
- tinfo, err := getTypeInfo(typ)
- if err != nil {
- return err
- }
-
- // Create start element.
- // Precedence for the XML element name is:
- // 0. startTemplate
- // 1. XMLName field in underlying struct;
- // 2. field name/tag in the struct field; and
- // 3. type name
- var start StartElement
-
- if startTemplate != nil {
- start.Name = startTemplate.Name
- start.Attr = append(start.Attr, startTemplate.Attr...)
- } else if tinfo.xmlname != nil {
- xmlname := tinfo.xmlname
- if xmlname.name != "" {
- start.Name.Space, start.Name.Local = xmlname.xmlns, xmlname.name
- } else {
- fv := xmlname.value(val, dontInitNilPointers)
- if v, ok := fv.Interface().(Name); ok && v.Local != "" {
- start.Name = v
- }
- }
- }
- if start.Name.Local == "" && finfo != nil {
- start.Name.Space, start.Name.Local = finfo.xmlns, finfo.name
- }
- if start.Name.Local == "" {
- name := typ.Name()
- if i := strings.IndexByte(name, '['); i >= 0 {
- // Truncate generic instantiation name. See issue 48318.
- name = name[:i]
- }
- if name == "" {
- return &UnsupportedTypeError{typ}
- }
- start.Name.Local = name
- }
-
- // Attributes
- for i := range tinfo.fields {
- finfo := &tinfo.fields[i]
- if finfo.flags&fAttr == 0 {
- continue
- }
- fv := finfo.value(val, dontInitNilPointers)
-
- if finfo.flags&fOmitEmpty != 0 && (!fv.IsValid() || isEmptyValue(fv)) {
- continue
- }
-
- if fv.Kind() == reflect.Interface && fv.IsNil() {
- continue
- }
-
- name := Name{Space: finfo.xmlns, Local: finfo.name}
- if err := p.marshalAttr(&start, name, fv); err != nil {
- return err
- }
- }
-
- if err := p.writeStart(&start); err != nil {
- return err
- }
-
- if val.Kind() == reflect.Struct {
- err = p.marshalStruct(tinfo, val)
- } else {
- s, b, err1 := p.marshalSimple(typ, val)
- if err1 != nil {
- err = err1
- } else if b != nil {
- EscapeText(p, b)
- } else {
- p.EscapeString(s)
- }
- }
- if err != nil {
- return err
- }
-
- if err := p.writeEnd(start.Name); err != nil {
- return err
- }
-
- return p.cachedWriteError()
-}
-
-// marshalAttr marshals an attribute with the given name and value, adding to start.Attr.
-func (p *printer) marshalAttr(start *StartElement, name Name, val reflect.Value) error {
- if val.CanInterface() && val.Type().Implements(marshalerAttrType) {
- attr, err := val.Interface().(MarshalerAttr).MarshalXMLAttr(name)
- if err != nil {
- return err
- }
- if attr.Name.Local != "" {
- start.Attr = append(start.Attr, attr)
- }
- return nil
- }
-
- if val.CanAddr() {
- pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) {
- attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
- if err != nil {
- return err
- }
- if attr.Name.Local != "" {
- start.Attr = append(start.Attr, attr)
- }
- return nil
- }
- }
-
- if val.CanInterface() && val.Type().Implements(textMarshalerType) {
- text, err := val.Interface().(encoding.TextMarshaler).MarshalText()
- if err != nil {
- return err
- }
- start.Attr = append(start.Attr, Attr{name, string(text)})
- return nil
- }
-
- if val.CanAddr() {
- pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
- text, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
- if err != nil {
- return err
- }
- start.Attr = append(start.Attr, Attr{name, string(text)})
- return nil
- }
- }
-
- // Dereference or skip nil pointer, interface values.
- switch val.Kind() {
- case reflect.Pointer, reflect.Interface:
- if val.IsNil() {
- return nil
- }
- val = val.Elem()
- }
-
- // Walk slices.
- if val.Kind() == reflect.Slice && val.Type().Elem().Kind() != reflect.Uint8 {
- n := val.Len()
- for i := 0; i < n; i++ {
- if err := p.marshalAttr(start, name, val.Index(i)); err != nil {
- return err
- }
- }
- return nil
- }
-
- if val.Type() == attrType {
- start.Attr = append(start.Attr, val.Interface().(Attr))
- return nil
- }
-
- s, b, err := p.marshalSimple(val.Type(), val)
- if err != nil {
- return err
- }
- if b != nil {
- s = string(b)
- }
- start.Attr = append(start.Attr, Attr{name, s})
- return nil
-}
-
-// defaultStart returns the default start element to use,
-// given the reflect type, field info, and start template.
-func defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement {
- var start StartElement
- // Precedence for the XML element name is as above,
- // except that we do not look inside structs for the first field.
- if startTemplate != nil {
- start.Name = startTemplate.Name
- start.Attr = append(start.Attr, startTemplate.Attr...)
- } else if finfo != nil && finfo.name != "" {
- start.Name.Local = finfo.name
- start.Name.Space = finfo.xmlns
- } else if typ.Name() != "" {
- start.Name.Local = typ.Name()
- } else {
- // Must be a pointer to a named type,
- // since it has the Marshaler methods.
- start.Name.Local = typ.Elem().Name()
- }
- return start
-}
-
-// marshalInterface marshals a Marshaler interface value.
-func (p *printer) marshalInterface(val Marshaler, start StartElement) error {
- // Push a marker onto the tag stack so that MarshalXML
- // cannot close the XML tags that it did not open.
- p.tags = append(p.tags, Name{})
- n := len(p.tags)
-
- err := val.MarshalXML(p.encoder, start)
- if err != nil {
- return err
- }
-
- // Make sure MarshalXML closed all its tags. p.tags[n-1] is the mark.
- if len(p.tags) > n {
- return fmt.Errorf("xml: %s.MarshalXML wrote invalid XML: <%s> not closed", receiverType(val), p.tags[len(p.tags)-1].Local)
- }
- p.tags = p.tags[:n-1]
- return nil
-}
-
-// marshalTextInterface marshals a TextMarshaler interface value.
-func (p *printer) marshalTextInterface(val encoding.TextMarshaler, start StartElement) error {
- if err := p.writeStart(&start); err != nil {
- return err
- }
- text, err := val.MarshalText()
- if err != nil {
- return err
- }
- EscapeText(p, text)
- return p.writeEnd(start.Name)
-}
-
-// writeStart writes the given start element.
-func (p *printer) writeStart(start *StartElement) error {
- if start.Name.Local == "" {
- return fmt.Errorf("xml: start tag with no name")
- }
-
- p.tags = append(p.tags, start.Name)
- p.markPrefix()
-
- p.writeIndent(1)
- p.WriteByte('<')
- p.WriteString(start.Name.Local)
-
- if start.Name.Space != "" {
- p.WriteString(` xmlns="`)
- p.EscapeString(start.Name.Space)
- p.WriteByte('"')
- }
-
- // Attributes
- for _, attr := range start.Attr {
- name := attr.Name
- if name.Local == "" {
- continue
- }
- p.WriteByte(' ')
- if name.Space != "" {
- p.WriteString(p.createAttrPrefix(name.Space))
- p.WriteByte(':')
- }
- p.WriteString(name.Local)
- p.WriteString(`="`)
- p.EscapeString(attr.Value)
- p.WriteByte('"')
- }
- p.WriteByte('>')
- return nil
-}
-
-func (p *printer) writeEnd(name Name) error {
- if name.Local == "" {
- return fmt.Errorf("xml: end tag with no name")
- }
- if len(p.tags) == 0 || p.tags[len(p.tags)-1].Local == "" {
- return fmt.Errorf("xml: end tag </%s> without start tag", name.Local)
- }
- if top := p.tags[len(p.tags)-1]; top != name {
- if top.Local != name.Local {
- return fmt.Errorf("xml: end tag </%s> does not match start tag <%s>", name.Local, top.Local)
- }
- return fmt.Errorf("xml: end tag </%s> in namespace %s does not match start tag <%s> in namespace %s", name.Local, name.Space, top.Local, top.Space)
- }
- p.tags = p.tags[:len(p.tags)-1]
-
- p.writeIndent(-1)
- p.WriteByte('<')
- p.WriteByte('/')
- p.WriteString(name.Local)
- p.WriteByte('>')
- p.popPrefix()
- return nil
-}
-
-func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []byte, error) {
- switch val.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return strconv.FormatInt(val.Int(), 10), nil, nil
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return strconv.FormatUint(val.Uint(), 10), nil, nil
- case reflect.Float32, reflect.Float64:
- return strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits()), nil, nil
- case reflect.String:
- return val.String(), nil, nil
- case reflect.Bool:
- return strconv.FormatBool(val.Bool()), nil, nil
- case reflect.Array:
- if typ.Elem().Kind() != reflect.Uint8 {
- break
- }
- // [...]byte
- var bytes []byte
- if val.CanAddr() {
- bytes = val.Slice(0, val.Len()).Bytes()
- } else {
- bytes = make([]byte, val.Len())
- reflect.Copy(reflect.ValueOf(bytes), val)
- }
- return "", bytes, nil
- case reflect.Slice:
- if typ.Elem().Kind() != reflect.Uint8 {
- break
- }
- // []byte
- return "", val.Bytes(), nil
- }
- return "", nil, &UnsupportedTypeError{typ}
-}
-
-var ddBytes = []byte("--")
-
-// indirect drills into interfaces and pointers, returning the pointed-at value.
-// If it encounters a nil interface or pointer, indirect returns that nil value.
-// This can turn into an infinite loop given a cyclic chain,
-// but it matches the Go 1 behavior.
-func indirect(vf reflect.Value) reflect.Value {
- for vf.Kind() == reflect.Interface || vf.Kind() == reflect.Pointer {
- if vf.IsNil() {
- return vf
- }
- vf = vf.Elem()
- }
- return vf
-}
-
-func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
- s := parentStack{p: p}
- for i := range tinfo.fields {
- finfo := &tinfo.fields[i]
- if finfo.flags&fAttr != 0 {
- continue
- }
- vf := finfo.value(val, dontInitNilPointers)
- if !vf.IsValid() {
- // The field is behind an anonymous struct field that's
- // nil. Skip it.
- continue
- }
-
- switch finfo.flags & fMode {
- case fCDATA, fCharData:
- emit := EscapeText
- if finfo.flags&fMode == fCDATA {
- emit = emitCDATA
- }
- if err := s.trim(finfo.parents); err != nil {
- return err
- }
- if vf.CanInterface() && vf.Type().Implements(textMarshalerType) {
- data, err := vf.Interface().(encoding.TextMarshaler).MarshalText()
- if err != nil {
- return err
- }
- if err := emit(p, data); err != nil {
- return err
- }
- continue
- }
- if vf.CanAddr() {
- pv := vf.Addr()
- if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
- data, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
- if err != nil {
- return err
- }
- if err := emit(p, data); err != nil {
- return err
- }
- continue
- }
- }
-
- var scratch [64]byte
- vf = indirect(vf)
- switch vf.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- if err := emit(p, strconv.AppendInt(scratch[:0], vf.Int(), 10)); err != nil {
- return err
- }
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- if err := emit(p, strconv.AppendUint(scratch[:0], vf.Uint(), 10)); err != nil {
- return err
- }
- case reflect.Float32, reflect.Float64:
- if err := emit(p, strconv.AppendFloat(scratch[:0], vf.Float(), 'g', -1, vf.Type().Bits())); err != nil {
- return err
- }
- case reflect.Bool:
- if err := emit(p, strconv.AppendBool(scratch[:0], vf.Bool())); err != nil {
- return err
- }
- case reflect.String:
- if err := emit(p, []byte(vf.String())); err != nil {
- return err
- }
- case reflect.Slice:
- if elem, ok := vf.Interface().([]byte); ok {
- if err := emit(p, elem); err != nil {
- return err
- }
- }
- }
- continue
-
- case fComment:
- if err := s.trim(finfo.parents); err != nil {
- return err
- }
- vf = indirect(vf)
- k := vf.Kind()
- if !(k == reflect.String || k == reflect.Slice && vf.Type().Elem().Kind() == reflect.Uint8) {
- return fmt.Errorf("xml: bad type for comment field of %s", val.Type())
- }
- if vf.Len() == 0 {
- continue
- }
- p.writeIndent(0)
- p.WriteString("<!--")
- dashDash := false
- dashLast := false
- switch k {
- case reflect.String:
- s := vf.String()
- dashDash = strings.Contains(s, "--")
- dashLast = s[len(s)-1] == '-'
- if !dashDash {
- p.WriteString(s)
- }
- case reflect.Slice:
- b := vf.Bytes()
- dashDash = bytes.Contains(b, ddBytes)
- dashLast = b[len(b)-1] == '-'
- if !dashDash {
- p.Write(b)
- }
- default:
- panic("can't happen")
- }
- if dashDash {
- return fmt.Errorf(`xml: comments must not contain "--"`)
- }
- if dashLast {
- // "--->" is invalid grammar. Make it "- -->"
- p.WriteByte(' ')
- }
- p.WriteString("-->")
- continue
-
- case fInnerXML:
- vf = indirect(vf)
- iface := vf.Interface()
- switch raw := iface.(type) {
- case []byte:
- p.Write(raw)
- continue
- case string:
- p.WriteString(raw)
- continue
- }
-
- case fElement, fElement | fAny:
- if err := s.trim(finfo.parents); err != nil {
- return err
- }
- if len(finfo.parents) > len(s.stack) {
- if vf.Kind() != reflect.Pointer && vf.Kind() != reflect.Interface || !vf.IsNil() {
- if err := s.push(finfo.parents[len(s.stack):]); err != nil {
- return err
- }
- }
- }
- }
- if err := p.marshalValue(vf, finfo, nil); err != nil {
- return err
- }
- }
- s.trim(nil)
- return p.cachedWriteError()
-}
-
-// Write implements io.Writer
-func (p *printer) Write(b []byte) (n int, err error) {
- if p.closed && p.err == nil {
- p.err = errors.New("use of closed Encoder")
- }
- if p.err == nil {
- n, p.err = p.w.Write(b)
- }
- return n, p.err
-}
-
-// WriteString implements io.StringWriter
-func (p *printer) WriteString(s string) (n int, err error) {
- if p.closed && p.err == nil {
- p.err = errors.New("use of closed Encoder")
- }
- if p.err == nil {
- n, p.err = p.w.WriteString(s)
- }
- return n, p.err
-}
-
-// WriteByte implements io.ByteWriter
-func (p *printer) WriteByte(c byte) error {
- if p.closed && p.err == nil {
- p.err = errors.New("use of closed Encoder")
- }
- if p.err == nil {
- p.err = p.w.WriteByte(c)
- }
- return p.err
-}
-
-// Close the Encoder, indicating that no more data will be written. It flushes
-// any buffered XML to the underlying writer and returns an error if the
-// written XML is invalid (e.g. by containing unclosed elements).
-func (p *printer) Close() error {
- if p.closed {
- return nil
- }
- p.closed = true
- if err := p.w.Flush(); err != nil {
- return err
- }
- if len(p.tags) > 0 {
- return fmt.Errorf("unclosed tag <%s>", p.tags[len(p.tags)-1].Local)
- }
- return nil
-}
-
-// return the bufio Writer's cached write error
-func (p *printer) cachedWriteError() error {
- _, err := p.Write(nil)
- return err
-}
-
-func (p *printer) writeIndent(depthDelta int) {
- if len(p.prefix) == 0 && len(p.indent) == 0 {
- return
- }
- if depthDelta < 0 {
- p.depth--
- if p.indentedIn {
- p.indentedIn = false
- return
- }
- p.indentedIn = false
- }
- if p.putNewline {
- p.WriteByte('\n')
- } else {
- p.putNewline = true
- }
- if len(p.prefix) > 0 {
- p.WriteString(p.prefix)
- }
- if len(p.indent) > 0 {
- for i := 0; i < p.depth; i++ {
- p.WriteString(p.indent)
- }
- }
- if depthDelta > 0 {
- p.depth++
- p.indentedIn = true
- }
-}
-
-type parentStack struct {
- p *printer
- stack []string
-}
-
-// trim updates the XML context to match the longest common prefix of the stack
-// and the given parents. A closing tag will be written for every parent
-// popped. Passing a zero slice or nil will close all the elements.
-func (s *parentStack) trim(parents []string) error {
- split := 0
- for ; split < len(parents) && split < len(s.stack); split++ {
- if parents[split] != s.stack[split] {
- break
- }
- }
- for i := len(s.stack) - 1; i >= split; i-- {
- if err := s.p.writeEnd(Name{Local: s.stack[i]}); err != nil {
- return err
- }
- }
- s.stack = s.stack[:split]
- return nil
-}
-
-// push adds parent elements to the stack and writes open tags.
-func (s *parentStack) push(parents []string) error {
- for i := 0; i < len(parents); i++ {
- if err := s.p.writeStart(&StartElement{Name: Name{Local: parents[i]}}); err != nil {
- return err
- }
- }
- s.stack = append(s.stack, parents...)
- return nil
-}
-
-// UnsupportedTypeError is returned when Marshal encounters a type
-// that cannot be converted into XML.
-type UnsupportedTypeError struct {
- Type reflect.Type
-}
-
-func (e *UnsupportedTypeError) Error() string {
- return "xml: unsupported type: " + e.Type.String()
-}
-
-func isEmptyValue(v reflect.Value) bool {
- switch v.Kind() {
- case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
- return v.Len() == 0
- case reflect.Bool:
- return !v.Bool()
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return v.Int() == 0
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return v.Uint() == 0
- case reflect.Float32, reflect.Float64:
- return v.Float() == 0
- case reflect.Interface, reflect.Pointer:
- return v.IsNil()
- }
- return false
-}
diff --git a/contrib/go/_std_1.20/src/encoding/xml/read.go b/contrib/go/_std_1.20/src/encoding/xml/read.go
deleted file mode 100644
index 43be08eeef..0000000000
--- a/contrib/go/_std_1.20/src/encoding/xml/read.go
+++ /dev/null
@@ -1,775 +0,0 @@
-// Copyright 2009 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 xml
-
-import (
- "bytes"
- "encoding"
- "errors"
- "fmt"
- "reflect"
- "runtime"
- "strconv"
- "strings"
-)
-
-// BUG(rsc): Mapping between XML elements and data structures is inherently flawed:
-// an XML element is an order-dependent collection of anonymous
-// values, while a data structure is an order-independent collection
-// of named values.
-// See package json for a textual representation more suitable
-// to data structures.
-
-// Unmarshal parses the XML-encoded data and stores the result in
-// the value pointed to by v, which must be an arbitrary struct,
-// slice, or string. Well-formed data that does not fit into v is
-// discarded.
-//
-// Because Unmarshal uses the reflect package, it can only assign
-// to exported (upper case) fields. Unmarshal uses a case-sensitive
-// comparison to match XML element names to tag values and struct
-// field names.
-//
-// Unmarshal maps an XML element to a struct using the following rules.
-// In the rules, the tag of a field refers to the value associated with the
-// key 'xml' in the struct field's tag (see the example above).
-//
-// - If the struct has a field of type []byte or string with tag
-// ",innerxml", Unmarshal accumulates the raw XML nested inside the
-// element in that field. The rest of the rules still apply.
-//
-// - If the struct has a field named XMLName of type Name,
-// Unmarshal records the element name in that field.
-//
-// - If the XMLName field has an associated tag of the form
-// "name" or "namespace-URL name", the XML element must have
-// the given name (and, optionally, name space) or else Unmarshal
-// returns an error.
-//
-// - If the XML element has an attribute whose name matches a
-// struct field name with an associated tag containing ",attr" or
-// the explicit name in a struct field tag of the form "name,attr",
-// Unmarshal records the attribute value in that field.
-//
-// - If the XML element has an attribute not handled by the previous
-// rule and the struct has a field with an associated tag containing
-// ",any,attr", Unmarshal records the attribute value in the first
-// such field.
-//
-// - If the XML element contains character data, that data is
-// accumulated in the first struct field that has tag ",chardata".
-// The struct field may have type []byte or string.
-// If there is no such field, the character data is discarded.
-//
-// - If the XML element contains comments, they are accumulated in
-// the first struct field that has tag ",comment". The struct
-// field may have type []byte or string. If there is no such
-// field, the comments are discarded.
-//
-// - If the XML element contains a sub-element whose name matches
-// the prefix of a tag formatted as "a" or "a>b>c", unmarshal
-// will descend into the XML structure looking for elements with the
-// given names, and will map the innermost elements to that struct
-// field. A tag starting with ">" is equivalent to one starting
-// with the field name followed by ">".
-//
-// - If the XML element contains a sub-element whose name matches
-// a struct field's XMLName tag and the struct field has no
-// explicit name tag as per the previous rule, unmarshal maps
-// the sub-element to that struct field.
-//
-// - If the XML element contains a sub-element whose name matches a
-// field without any mode flags (",attr", ",chardata", etc), Unmarshal
-// maps the sub-element to that struct field.
-//
-// - If the XML element contains a sub-element that hasn't matched any
-// of the above rules and the struct has a field with tag ",any",
-// unmarshal maps the sub-element to that struct field.
-//
-// - An anonymous struct field is handled as if the fields of its
-// value were part of the outer struct.
-//
-// - A struct field with tag "-" is never unmarshaled into.
-//
-// If Unmarshal encounters a field type that implements the Unmarshaler
-// interface, Unmarshal calls its UnmarshalXML method to produce the value from
-// the XML element. Otherwise, if the value implements
-// encoding.TextUnmarshaler, Unmarshal calls that value's UnmarshalText method.
-//
-// Unmarshal maps an XML element to a string or []byte by saving the
-// concatenation of that element's character data in the string or
-// []byte. The saved []byte is never nil.
-//
-// Unmarshal maps an attribute value to a string or []byte by saving
-// the value in the string or slice.
-//
-// Unmarshal maps an attribute value to an Attr by saving the attribute,
-// including its name, in the Attr.
-//
-// Unmarshal maps an XML element or attribute value to a slice by
-// extending the length of the slice and mapping the element or attribute
-// to the newly created value.
-//
-// Unmarshal maps an XML element or attribute value to a bool by
-// setting it to the boolean value represented by the string. Whitespace
-// is trimmed and ignored.
-//
-// Unmarshal maps an XML element or attribute value to an integer or
-// floating-point field by setting the field to the result of
-// interpreting the string value in decimal. There is no check for
-// overflow. Whitespace is trimmed and ignored.
-//
-// Unmarshal maps an XML element to a Name by recording the element
-// name.
-//
-// Unmarshal maps an XML element to a pointer by setting the pointer
-// to a freshly allocated value and then mapping the element to that value.
-//
-// A missing element or empty attribute value will be unmarshaled as a zero value.
-// If the field is a slice, a zero value will be appended to the field. Otherwise, the
-// field will be set to its zero value.
-func Unmarshal(data []byte, v any) error {
- return NewDecoder(bytes.NewReader(data)).Decode(v)
-}
-
-// Decode works like Unmarshal, except it reads the decoder
-// stream to find the start element.
-func (d *Decoder) Decode(v any) error {
- return d.DecodeElement(v, nil)
-}
-
-// DecodeElement works like Unmarshal except that it takes
-// a pointer to the start XML element to decode into v.
-// It is useful when a client reads some raw XML tokens itself
-// but also wants to defer to Unmarshal for some elements.
-func (d *Decoder) DecodeElement(v any, start *StartElement) error {
- val := reflect.ValueOf(v)
- if val.Kind() != reflect.Pointer {
- return errors.New("non-pointer passed to Unmarshal")
- }
-
- if val.IsNil() {
- return errors.New("nil pointer passed to Unmarshal")
- }
- return d.unmarshal(val.Elem(), start, 0)
-}
-
-// An UnmarshalError represents an error in the unmarshaling process.
-type UnmarshalError string
-
-func (e UnmarshalError) Error() string { return string(e) }
-
-// Unmarshaler is the interface implemented by objects that can unmarshal
-// an XML element description of themselves.
-//
-// UnmarshalXML decodes a single XML element
-// beginning with the given start element.
-// If it returns an error, the outer call to Unmarshal stops and
-// returns that error.
-// UnmarshalXML must consume exactly one XML element.
-// One common implementation strategy is to unmarshal into
-// a separate value with a layout matching the expected XML
-// using d.DecodeElement, and then to copy the data from
-// that value into the receiver.
-// Another common strategy is to use d.Token to process the
-// XML object one token at a time.
-// UnmarshalXML may not use d.RawToken.
-type Unmarshaler interface {
- UnmarshalXML(d *Decoder, start StartElement) error
-}
-
-// UnmarshalerAttr is the interface implemented by objects that can unmarshal
-// an XML attribute description of themselves.
-//
-// UnmarshalXMLAttr decodes a single XML attribute.
-// If it returns an error, the outer call to Unmarshal stops and
-// returns that error.
-// UnmarshalXMLAttr is used only for struct fields with the
-// "attr" option in the field tag.
-type UnmarshalerAttr interface {
- UnmarshalXMLAttr(attr Attr) error
-}
-
-// receiverType returns the receiver type to use in an expression like "%s.MethodName".
-func receiverType(val any) string {
- t := reflect.TypeOf(val)
- if t.Name() != "" {
- return t.String()
- }
- return "(" + t.String() + ")"
-}
-
-// unmarshalInterface unmarshals a single XML element into val.
-// start is the opening tag of the element.
-func (d *Decoder) unmarshalInterface(val Unmarshaler, start *StartElement) error {
- // Record that decoder must stop at end tag corresponding to start.
- d.pushEOF()
-
- d.unmarshalDepth++
- err := val.UnmarshalXML(d, *start)
- d.unmarshalDepth--
- if err != nil {
- d.popEOF()
- return err
- }
-
- if !d.popEOF() {
- return fmt.Errorf("xml: %s.UnmarshalXML did not consume entire <%s> element", receiverType(val), start.Name.Local)
- }
-
- return nil
-}
-
-// unmarshalTextInterface unmarshals a single XML element into val.
-// The chardata contained in the element (but not its children)
-// is passed to the text unmarshaler.
-func (d *Decoder) unmarshalTextInterface(val encoding.TextUnmarshaler) error {
- var buf []byte
- depth := 1
- for depth > 0 {
- t, err := d.Token()
- if err != nil {
- return err
- }
- switch t := t.(type) {
- case CharData:
- if depth == 1 {
- buf = append(buf, t...)
- }
- case StartElement:
- depth++
- case EndElement:
- depth--
- }
- }
- return val.UnmarshalText(buf)
-}
-
-// unmarshalAttr unmarshals a single XML attribute into val.
-func (d *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
- if val.Kind() == reflect.Pointer {
- if val.IsNil() {
- val.Set(reflect.New(val.Type().Elem()))
- }
- val = val.Elem()
- }
- if val.CanInterface() && val.Type().Implements(unmarshalerAttrType) {
- // This is an unmarshaler with a non-pointer receiver,
- // so it's likely to be incorrect, but we do what we're told.
- return val.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr)
- }
- if val.CanAddr() {
- pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(unmarshalerAttrType) {
- return pv.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr)
- }
- }
-
- // Not an UnmarshalerAttr; try encoding.TextUnmarshaler.
- if val.CanInterface() && val.Type().Implements(textUnmarshalerType) {
- // This is an unmarshaler with a non-pointer receiver,
- // so it's likely to be incorrect, but we do what we're told.
- return val.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value))
- }
- if val.CanAddr() {
- pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
- return pv.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value))
- }
- }
-
- if val.Type().Kind() == reflect.Slice && val.Type().Elem().Kind() != reflect.Uint8 {
- // Slice of element values.
- // Grow slice.
- n := val.Len()
- val.Set(reflect.Append(val, reflect.Zero(val.Type().Elem())))
-
- // Recur to read element into slice.
- if err := d.unmarshalAttr(val.Index(n), attr); err != nil {
- val.SetLen(n)
- return err
- }
- return nil
- }
-
- if val.Type() == attrType {
- val.Set(reflect.ValueOf(attr))
- return nil
- }
-
- return copyValue(val, []byte(attr.Value))
-}
-
-var (
- attrType = reflect.TypeOf(Attr{})
- unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
- unmarshalerAttrType = reflect.TypeOf((*UnmarshalerAttr)(nil)).Elem()
- textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
-)
-
-const (
- maxUnmarshalDepth = 10000
- maxUnmarshalDepthWasm = 5000 // go.dev/issue/56498
-)
-
-var errUnmarshalDepth = errors.New("exceeded max depth")
-
-// Unmarshal a single XML element into val.
-func (d *Decoder) unmarshal(val reflect.Value, start *StartElement, depth int) error {
- if depth >= maxUnmarshalDepth || runtime.GOARCH == "wasm" && depth >= maxUnmarshalDepthWasm {
- return errUnmarshalDepth
- }
- // Find start element if we need it.
- if start == nil {
- for {
- tok, err := d.Token()
- if err != nil {
- return err
- }
- if t, ok := tok.(StartElement); ok {
- start = &t
- break
- }
- }
- }
-
- // Load value from interface, but only if the result will be
- // usefully addressable.
- if val.Kind() == reflect.Interface && !val.IsNil() {
- e := val.Elem()
- if e.Kind() == reflect.Pointer && !e.IsNil() {
- val = e
- }
- }
-
- if val.Kind() == reflect.Pointer {
- if val.IsNil() {
- val.Set(reflect.New(val.Type().Elem()))
- }
- val = val.Elem()
- }
-
- if val.CanInterface() && val.Type().Implements(unmarshalerType) {
- // This is an unmarshaler with a non-pointer receiver,
- // so it's likely to be incorrect, but we do what we're told.
- return d.unmarshalInterface(val.Interface().(Unmarshaler), start)
- }
-
- if val.CanAddr() {
- pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(unmarshalerType) {
- return d.unmarshalInterface(pv.Interface().(Unmarshaler), start)
- }
- }
-
- if val.CanInterface() && val.Type().Implements(textUnmarshalerType) {
- return d.unmarshalTextInterface(val.Interface().(encoding.TextUnmarshaler))
- }
-
- if val.CanAddr() {
- pv := val.Addr()
- if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
- return d.unmarshalTextInterface(pv.Interface().(encoding.TextUnmarshaler))
- }
- }
-
- var (
- data []byte
- saveData reflect.Value
- comment []byte
- saveComment reflect.Value
- saveXML reflect.Value
- saveXMLIndex int
- saveXMLData []byte
- saveAny reflect.Value
- sv reflect.Value
- tinfo *typeInfo
- err error
- )
-
- switch v := val; v.Kind() {
- default:
- return errors.New("unknown type " + v.Type().String())
-
- case reflect.Interface:
- // TODO: For now, simply ignore the field. In the near
- // future we may choose to unmarshal the start
- // element on it, if not nil.
- return d.Skip()
-
- case reflect.Slice:
- typ := v.Type()
- if typ.Elem().Kind() == reflect.Uint8 {
- // []byte
- saveData = v
- break
- }
-
- // Slice of element values.
- // Grow slice.
- n := v.Len()
- v.Set(reflect.Append(val, reflect.Zero(v.Type().Elem())))
-
- // Recur to read element into slice.
- if err := d.unmarshal(v.Index(n), start, depth+1); err != nil {
- v.SetLen(n)
- return err
- }
- return nil
-
- case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.String:
- saveData = v
-
- case reflect.Struct:
- typ := v.Type()
- if typ == nameType {
- v.Set(reflect.ValueOf(start.Name))
- break
- }
-
- sv = v
- tinfo, err = getTypeInfo(typ)
- if err != nil {
- return err
- }
-
- // Validate and assign element name.
- if tinfo.xmlname != nil {
- finfo := tinfo.xmlname
- if finfo.name != "" && finfo.name != start.Name.Local {
- return UnmarshalError("expected element type <" + finfo.name + "> but have <" + start.Name.Local + ">")
- }
- if finfo.xmlns != "" && finfo.xmlns != start.Name.Space {
- e := "expected element <" + finfo.name + "> in name space " + finfo.xmlns + " but have "
- if start.Name.Space == "" {
- e += "no name space"
- } else {
- e += start.Name.Space
- }
- return UnmarshalError(e)
- }
- fv := finfo.value(sv, initNilPointers)
- if _, ok := fv.Interface().(Name); ok {
- fv.Set(reflect.ValueOf(start.Name))
- }
- }
-
- // Assign attributes.
- for _, a := range start.Attr {
- handled := false
- any := -1
- for i := range tinfo.fields {
- finfo := &tinfo.fields[i]
- switch finfo.flags & fMode {
- case fAttr:
- strv := finfo.value(sv, initNilPointers)
- if a.Name.Local == finfo.name && (finfo.xmlns == "" || finfo.xmlns == a.Name.Space) {
- if err := d.unmarshalAttr(strv, a); err != nil {
- return err
- }
- handled = true
- }
-
- case fAny | fAttr:
- if any == -1 {
- any = i
- }
- }
- }
- if !handled && any >= 0 {
- finfo := &tinfo.fields[any]
- strv := finfo.value(sv, initNilPointers)
- if err := d.unmarshalAttr(strv, a); err != nil {
- return err
- }
- }
- }
-
- // Determine whether we need to save character data or comments.
- for i := range tinfo.fields {
- finfo := &tinfo.fields[i]
- switch finfo.flags & fMode {
- case fCDATA, fCharData:
- if !saveData.IsValid() {
- saveData = finfo.value(sv, initNilPointers)
- }
-
- case fComment:
- if !saveComment.IsValid() {
- saveComment = finfo.value(sv, initNilPointers)
- }
-
- case fAny, fAny | fElement:
- if !saveAny.IsValid() {
- saveAny = finfo.value(sv, initNilPointers)
- }
-
- case fInnerXML:
- if !saveXML.IsValid() {
- saveXML = finfo.value(sv, initNilPointers)
- if d.saved == nil {
- saveXMLIndex = 0
- d.saved = new(bytes.Buffer)
- } else {
- saveXMLIndex = d.savedOffset()
- }
- }
- }
- }
- }
-
- // Find end element.
- // Process sub-elements along the way.
-Loop:
- for {
- var savedOffset int
- if saveXML.IsValid() {
- savedOffset = d.savedOffset()
- }
- tok, err := d.Token()
- if err != nil {
- return err
- }
- switch t := tok.(type) {
- case StartElement:
- consumed := false
- if sv.IsValid() {
- // unmarshalPath can call unmarshal, so we need to pass the depth through so that
- // we can continue to enforce the maximum recursion limit.
- consumed, err = d.unmarshalPath(tinfo, sv, nil, &t, depth)
- if err != nil {
- return err
- }
- if !consumed && saveAny.IsValid() {
- consumed = true
- if err := d.unmarshal(saveAny, &t, depth+1); err != nil {
- return err
- }
- }
- }
- if !consumed {
- if err := d.Skip(); err != nil {
- return err
- }
- }
-
- case EndElement:
- if saveXML.IsValid() {
- saveXMLData = d.saved.Bytes()[saveXMLIndex:savedOffset]
- if saveXMLIndex == 0 {
- d.saved = nil
- }
- }
- break Loop
-
- case CharData:
- if saveData.IsValid() {
- data = append(data, t...)
- }
-
- case Comment:
- if saveComment.IsValid() {
- comment = append(comment, t...)
- }
- }
- }
-
- if saveData.IsValid() && saveData.CanInterface() && saveData.Type().Implements(textUnmarshalerType) {
- if err := saveData.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil {
- return err
- }
- saveData = reflect.Value{}
- }
-
- if saveData.IsValid() && saveData.CanAddr() {
- pv := saveData.Addr()
- if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
- if err := pv.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil {
- return err
- }
- saveData = reflect.Value{}
- }
- }
-
- if err := copyValue(saveData, data); err != nil {
- return err
- }
-
- switch t := saveComment; t.Kind() {
- case reflect.String:
- t.SetString(string(comment))
- case reflect.Slice:
- t.Set(reflect.ValueOf(comment))
- }
-
- switch t := saveXML; t.Kind() {
- case reflect.String:
- t.SetString(string(saveXMLData))
- case reflect.Slice:
- if t.Type().Elem().Kind() == reflect.Uint8 {
- t.Set(reflect.ValueOf(saveXMLData))
- }
- }
-
- return nil
-}
-
-func copyValue(dst reflect.Value, src []byte) (err error) {
- dst0 := dst
-
- if dst.Kind() == reflect.Pointer {
- if dst.IsNil() {
- dst.Set(reflect.New(dst.Type().Elem()))
- }
- dst = dst.Elem()
- }
-
- // Save accumulated data.
- switch dst.Kind() {
- case reflect.Invalid:
- // Probably a comment.
- default:
- return errors.New("cannot unmarshal into " + dst0.Type().String())
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- if len(src) == 0 {
- dst.SetInt(0)
- return nil
- }
- itmp, err := strconv.ParseInt(strings.TrimSpace(string(src)), 10, dst.Type().Bits())
- if err != nil {
- return err
- }
- dst.SetInt(itmp)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- if len(src) == 0 {
- dst.SetUint(0)
- return nil
- }
- utmp, err := strconv.ParseUint(strings.TrimSpace(string(src)), 10, dst.Type().Bits())
- if err != nil {
- return err
- }
- dst.SetUint(utmp)
- case reflect.Float32, reflect.Float64:
- if len(src) == 0 {
- dst.SetFloat(0)
- return nil
- }
- ftmp, err := strconv.ParseFloat(strings.TrimSpace(string(src)), dst.Type().Bits())
- if err != nil {
- return err
- }
- dst.SetFloat(ftmp)
- case reflect.Bool:
- if len(src) == 0 {
- dst.SetBool(false)
- return nil
- }
- value, err := strconv.ParseBool(strings.TrimSpace(string(src)))
- if err != nil {
- return err
- }
- dst.SetBool(value)
- case reflect.String:
- dst.SetString(string(src))
- case reflect.Slice:
- if len(src) == 0 {
- // non-nil to flag presence
- src = []byte{}
- }
- dst.SetBytes(src)
- }
- return nil
-}
-
-// unmarshalPath walks down an XML structure looking for wanted
-// paths, and calls unmarshal on them.
-// The consumed result tells whether XML elements have been consumed
-// from the Decoder until start's matching end element, or if it's
-// still untouched because start is uninteresting for sv's fields.
-func (d *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []string, start *StartElement, depth int) (consumed bool, err error) {
- recurse := false
-Loop:
- for i := range tinfo.fields {
- finfo := &tinfo.fields[i]
- if finfo.flags&fElement == 0 || len(finfo.parents) < len(parents) || finfo.xmlns != "" && finfo.xmlns != start.Name.Space {
- continue
- }
- for j := range parents {
- if parents[j] != finfo.parents[j] {
- continue Loop
- }
- }
- if len(finfo.parents) == len(parents) && finfo.name == start.Name.Local {
- // It's a perfect match, unmarshal the field.
- return true, d.unmarshal(finfo.value(sv, initNilPointers), start, depth+1)
- }
- if len(finfo.parents) > len(parents) && finfo.parents[len(parents)] == start.Name.Local {
- // It's a prefix for the field. Break and recurse
- // since it's not ok for one field path to be itself
- // the prefix for another field path.
- recurse = true
-
- // We can reuse the same slice as long as we
- // don't try to append to it.
- parents = finfo.parents[:len(parents)+1]
- break
- }
- }
- if !recurse {
- // We have no business with this element.
- return false, nil
- }
- // The element is not a perfect match for any field, but one
- // or more fields have the path to this element as a parent
- // prefix. Recurse and attempt to match these.
- for {
- var tok Token
- tok, err = d.Token()
- if err != nil {
- return true, err
- }
- switch t := tok.(type) {
- case StartElement:
- // the recursion depth of unmarshalPath is limited to the path length specified
- // by the struct field tag, so we don't increment the depth here.
- consumed2, err := d.unmarshalPath(tinfo, sv, parents, &t, depth)
- if err != nil {
- return true, err
- }
- if !consumed2 {
- if err := d.Skip(); err != nil {
- return true, err
- }
- }
- case EndElement:
- return true, nil
- }
- }
-}
-
-// Skip reads tokens until it has consumed the end element
-// matching the most recent start element already consumed,
-// skipping nested structures.
-// It returns nil if it finds an end element matching the start
-// element; otherwise it returns an error describing the problem.
-func (d *Decoder) Skip() error {
- var depth int64
- for {
- tok, err := d.Token()
- if err != nil {
- return err
- }
- switch tok.(type) {
- case StartElement:
- depth++
- case EndElement:
- if depth == 0 {
- return nil
- }
- depth--
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/encoding/xml/xml.go b/contrib/go/_std_1.20/src/encoding/xml/xml.go
deleted file mode 100644
index 1f3084e5ca..0000000000
--- a/contrib/go/_std_1.20/src/encoding/xml/xml.go
+++ /dev/null
@@ -1,2057 +0,0 @@
-// Copyright 2009 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 xml implements a simple XML 1.0 parser that
-// understands XML name spaces.
-package xml
-
-// References:
-// Annotated XML spec: https://www.xml.com/axml/testaxml.htm
-// XML name spaces: https://www.w3.org/TR/REC-xml-names/
-
-import (
- "bufio"
- "bytes"
- "errors"
- "fmt"
- "io"
- "strconv"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-// A SyntaxError represents a syntax error in the XML input stream.
-type SyntaxError struct {
- Msg string
- Line int
-}
-
-func (e *SyntaxError) Error() string {
- return "XML syntax error on line " + strconv.Itoa(e.Line) + ": " + e.Msg
-}
-
-// A Name represents an XML name (Local) annotated
-// with a name space identifier (Space).
-// In tokens returned by Decoder.Token, the Space identifier
-// is given as a canonical URL, not the short prefix used
-// in the document being parsed.
-type Name struct {
- Space, Local string
-}
-
-// An Attr represents an attribute in an XML element (Name=Value).
-type Attr struct {
- Name Name
- Value string
-}
-
-// A Token is an interface holding one of the token types:
-// StartElement, EndElement, CharData, Comment, ProcInst, or Directive.
-type Token any
-
-// A StartElement represents an XML start element.
-type StartElement struct {
- Name Name
- Attr []Attr
-}
-
-// Copy creates a new copy of StartElement.
-func (e StartElement) Copy() StartElement {
- attrs := make([]Attr, len(e.Attr))
- copy(attrs, e.Attr)
- e.Attr = attrs
- return e
-}
-
-// End returns the corresponding XML end element.
-func (e StartElement) End() EndElement {
- return EndElement{e.Name}
-}
-
-// An EndElement represents an XML end element.
-type EndElement struct {
- Name Name
-}
-
-// A CharData represents XML character data (raw text),
-// in which XML escape sequences have been replaced by
-// the characters they represent.
-type CharData []byte
-
-// Copy creates a new copy of CharData.
-func (c CharData) Copy() CharData { return CharData(bytes.Clone(c)) }
-
-// A Comment represents an XML comment of the form <!--comment-->.
-// The bytes do not include the <!-- and --> comment markers.
-type Comment []byte
-
-// Copy creates a new copy of Comment.
-func (c Comment) Copy() Comment { return Comment(bytes.Clone(c)) }
-
-// A ProcInst represents an XML processing instruction of the form <?target inst?>
-type ProcInst struct {
- Target string
- Inst []byte
-}
-
-// Copy creates a new copy of ProcInst.
-func (p ProcInst) Copy() ProcInst {
- p.Inst = bytes.Clone(p.Inst)
- return p
-}
-
-// A Directive represents an XML directive of the form <!text>.
-// The bytes do not include the <! and > markers.
-type Directive []byte
-
-// Copy creates a new copy of Directive.
-func (d Directive) Copy() Directive { return Directive(bytes.Clone(d)) }
-
-// CopyToken returns a copy of a Token.
-func CopyToken(t Token) Token {
- switch v := t.(type) {
- case CharData:
- return v.Copy()
- case Comment:
- return v.Copy()
- case Directive:
- return v.Copy()
- case ProcInst:
- return v.Copy()
- case StartElement:
- return v.Copy()
- }
- return t
-}
-
-// A TokenReader is anything that can decode a stream of XML tokens, including a
-// Decoder.
-//
-// When Token encounters an error or end-of-file condition after successfully
-// reading a token, it returns the token. It may return the (non-nil) error from
-// the same call or return the error (and a nil token) from a subsequent call.
-// An instance of this general case is that a TokenReader returning a non-nil
-// token at the end of the token stream may return either io.EOF or a nil error.
-// The next Read should return nil, io.EOF.
-//
-// Implementations of Token are discouraged from returning a nil token with a
-// nil error. Callers should treat a return of nil, nil as indicating that
-// nothing happened; in particular it does not indicate EOF.
-type TokenReader interface {
- Token() (Token, error)
-}
-
-// A Decoder represents an XML parser reading a particular input stream.
-// The parser assumes that its input is encoded in UTF-8.
-type Decoder struct {
- // Strict defaults to true, enforcing the requirements
- // of the XML specification.
- // If set to false, the parser allows input containing common
- // mistakes:
- // * If an element is missing an end tag, the parser invents
- // end tags as necessary to keep the return values from Token
- // properly balanced.
- // * In attribute values and character data, unknown or malformed
- // character entities (sequences beginning with &) are left alone.
- //
- // Setting:
- //
- // d.Strict = false
- // d.AutoClose = xml.HTMLAutoClose
- // d.Entity = xml.HTMLEntity
- //
- // creates a parser that can handle typical HTML.
- //
- // Strict mode does not enforce the requirements of the XML name spaces TR.
- // In particular it does not reject name space tags using undefined prefixes.
- // Such tags are recorded with the unknown prefix as the name space URL.
- Strict bool
-
- // When Strict == false, AutoClose indicates a set of elements to
- // consider closed immediately after they are opened, regardless
- // of whether an end element is present.
- AutoClose []string
-
- // Entity can be used to map non-standard entity names to string replacements.
- // The parser behaves as if these standard mappings are present in the map,
- // regardless of the actual map content:
- //
- // "lt": "<",
- // "gt": ">",
- // "amp": "&",
- // "apos": "'",
- // "quot": `"`,
- Entity map[string]string
-
- // CharsetReader, if non-nil, defines a function to generate
- // charset-conversion readers, converting from the provided
- // non-UTF-8 charset into UTF-8. If CharsetReader is nil or
- // returns an error, parsing stops with an error. One of the
- // CharsetReader's result values must be non-nil.
- CharsetReader func(charset string, input io.Reader) (io.Reader, error)
-
- // DefaultSpace sets the default name space used for unadorned tags,
- // as if the entire XML stream were wrapped in an element containing
- // the attribute xmlns="DefaultSpace".
- DefaultSpace string
-
- r io.ByteReader
- t TokenReader
- buf bytes.Buffer
- saved *bytes.Buffer
- stk *stack
- free *stack
- needClose bool
- toClose Name
- nextToken Token
- nextByte int
- ns map[string]string
- err error
- line int
- linestart int64
- offset int64
- unmarshalDepth int
-}
-
-// NewDecoder creates a new XML parser reading from r.
-// If r does not implement io.ByteReader, NewDecoder will
-// do its own buffering.
-func NewDecoder(r io.Reader) *Decoder {
- d := &Decoder{
- ns: make(map[string]string),
- nextByte: -1,
- line: 1,
- Strict: true,
- }
- d.switchToReader(r)
- return d
-}
-
-// NewTokenDecoder creates a new XML parser using an underlying token stream.
-func NewTokenDecoder(t TokenReader) *Decoder {
- // Is it already a Decoder?
- if d, ok := t.(*Decoder); ok {
- return d
- }
- d := &Decoder{
- ns: make(map[string]string),
- t: t,
- nextByte: -1,
- line: 1,
- Strict: true,
- }
- return d
-}
-
-// Token returns the next XML token in the input stream.
-// At the end of the input stream, Token returns nil, io.EOF.
-//
-// Slices of bytes in the returned token data refer to the
-// parser's internal buffer and remain valid only until the next
-// call to Token. To acquire a copy of the bytes, call CopyToken
-// or the token's Copy method.
-//
-// Token expands self-closing elements such as <br>
-// into separate start and end elements returned by successive calls.
-//
-// Token guarantees that the StartElement and EndElement
-// tokens it returns are properly nested and matched:
-// if Token encounters an unexpected end element
-// or EOF before all expected end elements,
-// it will return an error.
-//
-// Token implements XML name spaces as described by
-// https://www.w3.org/TR/REC-xml-names/. Each of the
-// Name structures contained in the Token has the Space
-// set to the URL identifying its name space when known.
-// If Token encounters an unrecognized name space prefix,
-// it uses the prefix as the Space rather than report an error.
-func (d *Decoder) Token() (Token, error) {
- var t Token
- var err error
- if d.stk != nil && d.stk.kind == stkEOF {
- return nil, io.EOF
- }
- if d.nextToken != nil {
- t = d.nextToken
- d.nextToken = nil
- } else {
- if t, err = d.rawToken(); t == nil && err != nil {
- if err == io.EOF && d.stk != nil && d.stk.kind != stkEOF {
- err = d.syntaxError("unexpected EOF")
- }
- return nil, err
- }
- // We still have a token to process, so clear any
- // errors (e.g. EOF) and proceed.
- err = nil
- }
- if !d.Strict {
- if t1, ok := d.autoClose(t); ok {
- d.nextToken = t
- t = t1
- }
- }
- switch t1 := t.(type) {
- case StartElement:
- // In XML name spaces, the translations listed in the
- // attributes apply to the element name and
- // to the other attribute names, so process
- // the translations first.
- for _, a := range t1.Attr {
- if a.Name.Space == xmlnsPrefix {
- v, ok := d.ns[a.Name.Local]
- d.pushNs(a.Name.Local, v, ok)
- d.ns[a.Name.Local] = a.Value
- }
- if a.Name.Space == "" && a.Name.Local == xmlnsPrefix {
- // Default space for untagged names
- v, ok := d.ns[""]
- d.pushNs("", v, ok)
- d.ns[""] = a.Value
- }
- }
-
- d.pushElement(t1.Name)
- d.translate(&t1.Name, true)
- for i := range t1.Attr {
- d.translate(&t1.Attr[i].Name, false)
- }
- t = t1
-
- case EndElement:
- if !d.popElement(&t1) {
- return nil, d.err
- }
- t = t1
- }
- return t, err
-}
-
-const (
- xmlURL = "http://www.w3.org/XML/1998/namespace"
- xmlnsPrefix = "xmlns"
- xmlPrefix = "xml"
-)
-
-// Apply name space translation to name n.
-// The default name space (for Space=="")
-// applies only to element names, not to attribute names.
-func (d *Decoder) translate(n *Name, isElementName bool) {
- switch {
- case n.Space == xmlnsPrefix:
- return
- case n.Space == "" && !isElementName:
- return
- case n.Space == xmlPrefix:
- n.Space = xmlURL
- case n.Space == "" && n.Local == xmlnsPrefix:
- return
- }
- if v, ok := d.ns[n.Space]; ok {
- n.Space = v
- } else if n.Space == "" {
- n.Space = d.DefaultSpace
- }
-}
-
-func (d *Decoder) switchToReader(r io.Reader) {
- // Get efficient byte at a time reader.
- // Assume that if reader has its own
- // ReadByte, it's efficient enough.
- // Otherwise, use bufio.
- if rb, ok := r.(io.ByteReader); ok {
- d.r = rb
- } else {
- d.r = bufio.NewReader(r)
- }
-}
-
-// Parsing state - stack holds old name space translations
-// and the current set of open elements. The translations to pop when
-// ending a given tag are *below* it on the stack, which is
-// more work but forced on us by XML.
-type stack struct {
- next *stack
- kind int
- name Name
- ok bool
-}
-
-const (
- stkStart = iota
- stkNs
- stkEOF
-)
-
-func (d *Decoder) push(kind int) *stack {
- s := d.free
- if s != nil {
- d.free = s.next
- } else {
- s = new(stack)
- }
- s.next = d.stk
- s.kind = kind
- d.stk = s
- return s
-}
-
-func (d *Decoder) pop() *stack {
- s := d.stk
- if s != nil {
- d.stk = s.next
- s.next = d.free
- d.free = s
- }
- return s
-}
-
-// Record that after the current element is finished
-// (that element is already pushed on the stack)
-// Token should return EOF until popEOF is called.
-func (d *Decoder) pushEOF() {
- // Walk down stack to find Start.
- // It might not be the top, because there might be stkNs
- // entries above it.
- start := d.stk
- for start.kind != stkStart {
- start = start.next
- }
- // The stkNs entries below a start are associated with that
- // element too; skip over them.
- for start.next != nil && start.next.kind == stkNs {
- start = start.next
- }
- s := d.free
- if s != nil {
- d.free = s.next
- } else {
- s = new(stack)
- }
- s.kind = stkEOF
- s.next = start.next
- start.next = s
-}
-
-// Undo a pushEOF.
-// The element must have been finished, so the EOF should be at the top of the stack.
-func (d *Decoder) popEOF() bool {
- if d.stk == nil || d.stk.kind != stkEOF {
- return false
- }
- d.pop()
- return true
-}
-
-// Record that we are starting an element with the given name.
-func (d *Decoder) pushElement(name Name) {
- s := d.push(stkStart)
- s.name = name
-}
-
-// Record that we are changing the value of ns[local].
-// The old value is url, ok.
-func (d *Decoder) pushNs(local string, url string, ok bool) {
- s := d.push(stkNs)
- s.name.Local = local
- s.name.Space = url
- s.ok = ok
-}
-
-// Creates a SyntaxError with the current line number.
-func (d *Decoder) syntaxError(msg string) error {
- return &SyntaxError{Msg: msg, Line: d.line}
-}
-
-// Record that we are ending an element with the given name.
-// The name must match the record at the top of the stack,
-// which must be a pushElement record.
-// After popping the element, apply any undo records from
-// the stack to restore the name translations that existed
-// before we saw this element.
-func (d *Decoder) popElement(t *EndElement) bool {
- s := d.pop()
- name := t.Name
- switch {
- case s == nil || s.kind != stkStart:
- d.err = d.syntaxError("unexpected end element </" + name.Local + ">")
- return false
- case s.name.Local != name.Local:
- if !d.Strict {
- d.needClose = true
- d.toClose = t.Name
- t.Name = s.name
- return true
- }
- d.err = d.syntaxError("element <" + s.name.Local + "> closed by </" + name.Local + ">")
- return false
- case s.name.Space != name.Space:
- d.err = d.syntaxError("element <" + s.name.Local + "> in space " + s.name.Space +
- " closed by </" + name.Local + "> in space " + name.Space)
- return false
- }
-
- d.translate(&t.Name, true)
-
- // Pop stack until a Start or EOF is on the top, undoing the
- // translations that were associated with the element we just closed.
- for d.stk != nil && d.stk.kind != stkStart && d.stk.kind != stkEOF {
- s := d.pop()
- if s.ok {
- d.ns[s.name.Local] = s.name.Space
- } else {
- delete(d.ns, s.name.Local)
- }
- }
-
- return true
-}
-
-// If the top element on the stack is autoclosing and
-// t is not the end tag, invent the end tag.
-func (d *Decoder) autoClose(t Token) (Token, bool) {
- if d.stk == nil || d.stk.kind != stkStart {
- return nil, false
- }
- for _, s := range d.AutoClose {
- if strings.EqualFold(s, d.stk.name.Local) {
- // This one should be auto closed if t doesn't close it.
- et, ok := t.(EndElement)
- if !ok || !strings.EqualFold(et.Name.Local, d.stk.name.Local) {
- return EndElement{d.stk.name}, true
- }
- break
- }
- }
- return nil, false
-}
-
-var errRawToken = errors.New("xml: cannot use RawToken from UnmarshalXML method")
-
-// RawToken is like Token but does not verify that
-// start and end elements match and does not translate
-// name space prefixes to their corresponding URLs.
-func (d *Decoder) RawToken() (Token, error) {
- if d.unmarshalDepth > 0 {
- return nil, errRawToken
- }
- return d.rawToken()
-}
-
-func (d *Decoder) rawToken() (Token, error) {
- if d.t != nil {
- return d.t.Token()
- }
- if d.err != nil {
- return nil, d.err
- }
- if d.needClose {
- // The last element we read was self-closing and
- // we returned just the StartElement half.
- // Return the EndElement half now.
- d.needClose = false
- return EndElement{d.toClose}, nil
- }
-
- b, ok := d.getc()
- if !ok {
- return nil, d.err
- }
-
- if b != '<' {
- // Text section.
- d.ungetc(b)
- data := d.text(-1, false)
- if data == nil {
- return nil, d.err
- }
- return CharData(data), nil
- }
-
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- switch b {
- case '/':
- // </: End element
- var name Name
- if name, ok = d.nsname(); !ok {
- if d.err == nil {
- d.err = d.syntaxError("expected element name after </")
- }
- return nil, d.err
- }
- d.space()
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- if b != '>' {
- d.err = d.syntaxError("invalid characters between </" + name.Local + " and >")
- return nil, d.err
- }
- return EndElement{name}, nil
-
- case '?':
- // <?: Processing instruction.
- var target string
- if target, ok = d.name(); !ok {
- if d.err == nil {
- d.err = d.syntaxError("expected target name after <?")
- }
- return nil, d.err
- }
- d.space()
- d.buf.Reset()
- var b0 byte
- for {
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- d.buf.WriteByte(b)
- if b0 == '?' && b == '>' {
- break
- }
- b0 = b
- }
- data := d.buf.Bytes()
- data = data[0 : len(data)-2] // chop ?>
-
- if target == "xml" {
- content := string(data)
- ver := procInst("version", content)
- if ver != "" && ver != "1.0" {
- d.err = fmt.Errorf("xml: unsupported version %q; only version 1.0 is supported", ver)
- return nil, d.err
- }
- enc := procInst("encoding", content)
- if enc != "" && enc != "utf-8" && enc != "UTF-8" && !strings.EqualFold(enc, "utf-8") {
- if d.CharsetReader == nil {
- d.err = fmt.Errorf("xml: encoding %q declared but Decoder.CharsetReader is nil", enc)
- return nil, d.err
- }
- newr, err := d.CharsetReader(enc, d.r.(io.Reader))
- if err != nil {
- d.err = fmt.Errorf("xml: opening charset %q: %v", enc, err)
- return nil, d.err
- }
- if newr == nil {
- panic("CharsetReader returned a nil Reader for charset " + enc)
- }
- d.switchToReader(newr)
- }
- }
- return ProcInst{target, data}, nil
-
- case '!':
- // <!: Maybe comment, maybe CDATA.
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- switch b {
- case '-': // <!-
- // Probably <!-- for a comment.
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- if b != '-' {
- d.err = d.syntaxError("invalid sequence <!- not part of <!--")
- return nil, d.err
- }
- // Look for terminator.
- d.buf.Reset()
- var b0, b1 byte
- for {
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- d.buf.WriteByte(b)
- if b0 == '-' && b1 == '-' {
- if b != '>' {
- d.err = d.syntaxError(
- `invalid sequence "--" not allowed in comments`)
- return nil, d.err
- }
- break
- }
- b0, b1 = b1, b
- }
- data := d.buf.Bytes()
- data = data[0 : len(data)-3] // chop -->
- return Comment(data), nil
-
- case '[': // <![
- // Probably <![CDATA[.
- for i := 0; i < 6; i++ {
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- if b != "CDATA["[i] {
- d.err = d.syntaxError("invalid <![ sequence")
- return nil, d.err
- }
- }
- // Have <![CDATA[. Read text until ]]>.
- data := d.text(-1, true)
- if data == nil {
- return nil, d.err
- }
- return CharData(data), nil
- }
-
- // Probably a directive: <!DOCTYPE ...>, <!ENTITY ...>, etc.
- // We don't care, but accumulate for caller. Quoted angle
- // brackets do not count for nesting.
- d.buf.Reset()
- d.buf.WriteByte(b)
- inquote := uint8(0)
- depth := 0
- for {
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- if inquote == 0 && b == '>' && depth == 0 {
- break
- }
- HandleB:
- d.buf.WriteByte(b)
- switch {
- case b == inquote:
- inquote = 0
-
- case inquote != 0:
- // in quotes, no special action
-
- case b == '\'' || b == '"':
- inquote = b
-
- case b == '>' && inquote == 0:
- depth--
-
- case b == '<' && inquote == 0:
- // Look for <!-- to begin comment.
- s := "!--"
- for i := 0; i < len(s); i++ {
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- if b != s[i] {
- for j := 0; j < i; j++ {
- d.buf.WriteByte(s[j])
- }
- depth++
- goto HandleB
- }
- }
-
- // Remove < that was written above.
- d.buf.Truncate(d.buf.Len() - 1)
-
- // Look for terminator.
- var b0, b1 byte
- for {
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- if b0 == '-' && b1 == '-' && b == '>' {
- break
- }
- b0, b1 = b1, b
- }
-
- // Replace the comment with a space in the returned Directive
- // body, so that markup parts that were separated by the comment
- // (like a "<" and a "!") don't get joined when re-encoding the
- // Directive, taking new semantic meaning.
- d.buf.WriteByte(' ')
- }
- }
- return Directive(d.buf.Bytes()), nil
- }
-
- // Must be an open element like <a href="foo">
- d.ungetc(b)
-
- var (
- name Name
- empty bool
- attr []Attr
- )
- if name, ok = d.nsname(); !ok {
- if d.err == nil {
- d.err = d.syntaxError("expected element name after <")
- }
- return nil, d.err
- }
-
- attr = []Attr{}
- for {
- d.space()
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- if b == '/' {
- empty = true
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- if b != '>' {
- d.err = d.syntaxError("expected /> in element")
- return nil, d.err
- }
- break
- }
- if b == '>' {
- break
- }
- d.ungetc(b)
-
- a := Attr{}
- if a.Name, ok = d.nsname(); !ok {
- if d.err == nil {
- d.err = d.syntaxError("expected attribute name in element")
- }
- return nil, d.err
- }
- d.space()
- if b, ok = d.mustgetc(); !ok {
- return nil, d.err
- }
- if b != '=' {
- if d.Strict {
- d.err = d.syntaxError("attribute name without = in element")
- return nil, d.err
- }
- d.ungetc(b)
- a.Value = a.Name.Local
- } else {
- d.space()
- data := d.attrval()
- if data == nil {
- return nil, d.err
- }
- a.Value = string(data)
- }
- attr = append(attr, a)
- }
- if empty {
- d.needClose = true
- d.toClose = name
- }
- return StartElement{name, attr}, nil
-}
-
-func (d *Decoder) attrval() []byte {
- b, ok := d.mustgetc()
- if !ok {
- return nil
- }
- // Handle quoted attribute values
- if b == '"' || b == '\'' {
- return d.text(int(b), false)
- }
- // Handle unquoted attribute values for strict parsers
- if d.Strict {
- d.err = d.syntaxError("unquoted or missing attribute value in element")
- return nil
- }
- // Handle unquoted attribute values for unstrict parsers
- d.ungetc(b)
- d.buf.Reset()
- for {
- b, ok = d.mustgetc()
- if !ok {
- return nil
- }
- // https://www.w3.org/TR/REC-html40/intro/sgmltut.html#h-3.2.2
- if 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z' ||
- '0' <= b && b <= '9' || b == '_' || b == ':' || b == '-' {
- d.buf.WriteByte(b)
- } else {
- d.ungetc(b)
- break
- }
- }
- return d.buf.Bytes()
-}
-
-// Skip spaces if any
-func (d *Decoder) space() {
- for {
- b, ok := d.getc()
- if !ok {
- return
- }
- switch b {
- case ' ', '\r', '\n', '\t':
- default:
- d.ungetc(b)
- return
- }
- }
-}
-
-// Read a single byte.
-// If there is no byte to read, return ok==false
-// and leave the error in d.err.
-// Maintain line number.
-func (d *Decoder) getc() (b byte, ok bool) {
- if d.err != nil {
- return 0, false
- }
- if d.nextByte >= 0 {
- b = byte(d.nextByte)
- d.nextByte = -1
- } else {
- b, d.err = d.r.ReadByte()
- if d.err != nil {
- return 0, false
- }
- if d.saved != nil {
- d.saved.WriteByte(b)
- }
- }
- if b == '\n' {
- d.line++
- d.linestart = d.offset + 1
- }
- d.offset++
- return b, true
-}
-
-// InputOffset returns the input stream byte offset of the current decoder position.
-// The offset gives the location of the end of the most recently returned token
-// and the beginning of the next token.
-func (d *Decoder) InputOffset() int64 {
- return d.offset
-}
-
-// InputPos returns the line of the current decoder position and the 1 based
-// input position of the line. The position gives the location of the end of the
-// most recently returned token.
-func (d *Decoder) InputPos() (line, column int) {
- return d.line, int(d.offset-d.linestart) + 1
-}
-
-// Return saved offset.
-// If we did ungetc (nextByte >= 0), have to back up one.
-func (d *Decoder) savedOffset() int {
- n := d.saved.Len()
- if d.nextByte >= 0 {
- n--
- }
- return n
-}
-
-// Must read a single byte.
-// If there is no byte to read,
-// set d.err to SyntaxError("unexpected EOF")
-// and return ok==false
-func (d *Decoder) mustgetc() (b byte, ok bool) {
- if b, ok = d.getc(); !ok {
- if d.err == io.EOF {
- d.err = d.syntaxError("unexpected EOF")
- }
- }
- return
-}
-
-// Unread a single byte.
-func (d *Decoder) ungetc(b byte) {
- if b == '\n' {
- d.line--
- }
- d.nextByte = int(b)
- d.offset--
-}
-
-var entity = map[string]rune{
- "lt": '<',
- "gt": '>',
- "amp": '&',
- "apos": '\'',
- "quot": '"',
-}
-
-// Read plain text section (XML calls it character data).
-// If quote >= 0, we are in a quoted string and need to find the matching quote.
-// If cdata == true, we are in a <![CDATA[ section and need to find ]]>.
-// On failure return nil and leave the error in d.err.
-func (d *Decoder) text(quote int, cdata bool) []byte {
- var b0, b1 byte
- var trunc int
- d.buf.Reset()
-Input:
- for {
- b, ok := d.getc()
- if !ok {
- if cdata {
- if d.err == io.EOF {
- d.err = d.syntaxError("unexpected EOF in CDATA section")
- }
- return nil
- }
- break Input
- }
-
- // <![CDATA[ section ends with ]]>.
- // It is an error for ]]> to appear in ordinary text.
- if b0 == ']' && b1 == ']' && b == '>' {
- if cdata {
- trunc = 2
- break Input
- }
- d.err = d.syntaxError("unescaped ]]> not in CDATA section")
- return nil
- }
-
- // Stop reading text if we see a <.
- if b == '<' && !cdata {
- if quote >= 0 {
- d.err = d.syntaxError("unescaped < inside quoted string")
- return nil
- }
- d.ungetc('<')
- break Input
- }
- if quote >= 0 && b == byte(quote) {
- break Input
- }
- if b == '&' && !cdata {
- // Read escaped character expression up to semicolon.
- // XML in all its glory allows a document to define and use
- // its own character names with <!ENTITY ...> directives.
- // Parsers are required to recognize lt, gt, amp, apos, and quot
- // even if they have not been declared.
- before := d.buf.Len()
- d.buf.WriteByte('&')
- var ok bool
- var text string
- var haveText bool
- if b, ok = d.mustgetc(); !ok {
- return nil
- }
- if b == '#' {
- d.buf.WriteByte(b)
- if b, ok = d.mustgetc(); !ok {
- return nil
- }
- base := 10
- if b == 'x' {
- base = 16
- d.buf.WriteByte(b)
- if b, ok = d.mustgetc(); !ok {
- return nil
- }
- }
- start := d.buf.Len()
- for '0' <= b && b <= '9' ||
- base == 16 && 'a' <= b && b <= 'f' ||
- base == 16 && 'A' <= b && b <= 'F' {
- d.buf.WriteByte(b)
- if b, ok = d.mustgetc(); !ok {
- return nil
- }
- }
- if b != ';' {
- d.ungetc(b)
- } else {
- s := string(d.buf.Bytes()[start:])
- d.buf.WriteByte(';')
- n, err := strconv.ParseUint(s, base, 64)
- if err == nil && n <= unicode.MaxRune {
- text = string(rune(n))
- haveText = true
- }
- }
- } else {
- d.ungetc(b)
- if !d.readName() {
- if d.err != nil {
- return nil
- }
- }
- if b, ok = d.mustgetc(); !ok {
- return nil
- }
- if b != ';' {
- d.ungetc(b)
- } else {
- name := d.buf.Bytes()[before+1:]
- d.buf.WriteByte(';')
- if isName(name) {
- s := string(name)
- if r, ok := entity[s]; ok {
- text = string(r)
- haveText = true
- } else if d.Entity != nil {
- text, haveText = d.Entity[s]
- }
- }
- }
- }
-
- if haveText {
- d.buf.Truncate(before)
- d.buf.WriteString(text)
- b0, b1 = 0, 0
- continue Input
- }
- if !d.Strict {
- b0, b1 = 0, 0
- continue Input
- }
- ent := string(d.buf.Bytes()[before:])
- if ent[len(ent)-1] != ';' {
- ent += " (no semicolon)"
- }
- d.err = d.syntaxError("invalid character entity " + ent)
- return nil
- }
-
- // We must rewrite unescaped \r and \r\n into \n.
- if b == '\r' {
- d.buf.WriteByte('\n')
- } else if b1 == '\r' && b == '\n' {
- // Skip \r\n--we already wrote \n.
- } else {
- d.buf.WriteByte(b)
- }
-
- b0, b1 = b1, b
- }
- data := d.buf.Bytes()
- data = data[0 : len(data)-trunc]
-
- // Inspect each rune for being a disallowed character.
- buf := data
- for len(buf) > 0 {
- r, size := utf8.DecodeRune(buf)
- if r == utf8.RuneError && size == 1 {
- d.err = d.syntaxError("invalid UTF-8")
- return nil
- }
- buf = buf[size:]
- if !isInCharacterRange(r) {
- d.err = d.syntaxError(fmt.Sprintf("illegal character code %U", r))
- return nil
- }
- }
-
- return data
-}
-
-// Decide whether the given rune is in the XML Character Range, per
-// the Char production of https://www.xml.com/axml/testaxml.htm,
-// Section 2.2 Characters.
-func isInCharacterRange(r rune) (inrange bool) {
- return r == 0x09 ||
- r == 0x0A ||
- r == 0x0D ||
- r >= 0x20 && r <= 0xD7FF ||
- r >= 0xE000 && r <= 0xFFFD ||
- r >= 0x10000 && r <= 0x10FFFF
-}
-
-// Get name space name: name with a : stuck in the middle.
-// The part before the : is the name space identifier.
-func (d *Decoder) nsname() (name Name, ok bool) {
- s, ok := d.name()
- if !ok {
- return
- }
- if strings.Count(s, ":") > 1 {
- return name, false
- } else if space, local, ok := strings.Cut(s, ":"); !ok || space == "" || local == "" {
- name.Local = s
- } else {
- name.Space = space
- name.Local = local
- }
- return name, true
-}
-
-// Get name: /first(first|second)*/
-// Do not set d.err if the name is missing (unless unexpected EOF is received):
-// let the caller provide better context.
-func (d *Decoder) name() (s string, ok bool) {
- d.buf.Reset()
- if !d.readName() {
- return "", false
- }
-
- // Now we check the characters.
- b := d.buf.Bytes()
- if !isName(b) {
- d.err = d.syntaxError("invalid XML name: " + string(b))
- return "", false
- }
- return string(b), true
-}
-
-// Read a name and append its bytes to d.buf.
-// The name is delimited by any single-byte character not valid in names.
-// All multi-byte characters are accepted; the caller must check their validity.
-func (d *Decoder) readName() (ok bool) {
- var b byte
- if b, ok = d.mustgetc(); !ok {
- return
- }
- if b < utf8.RuneSelf && !isNameByte(b) {
- d.ungetc(b)
- return false
- }
- d.buf.WriteByte(b)
-
- for {
- if b, ok = d.mustgetc(); !ok {
- return
- }
- if b < utf8.RuneSelf && !isNameByte(b) {
- d.ungetc(b)
- break
- }
- d.buf.WriteByte(b)
- }
- return true
-}
-
-func isNameByte(c byte) bool {
- return 'A' <= c && c <= 'Z' ||
- 'a' <= c && c <= 'z' ||
- '0' <= c && c <= '9' ||
- c == '_' || c == ':' || c == '.' || c == '-'
-}
-
-func isName(s []byte) bool {
- if len(s) == 0 {
- return false
- }
- c, n := utf8.DecodeRune(s)
- if c == utf8.RuneError && n == 1 {
- return false
- }
- if !unicode.Is(first, c) {
- return false
- }
- for n < len(s) {
- s = s[n:]
- c, n = utf8.DecodeRune(s)
- if c == utf8.RuneError && n == 1 {
- return false
- }
- if !unicode.Is(first, c) && !unicode.Is(second, c) {
- return false
- }
- }
- return true
-}
-
-func isNameString(s string) bool {
- if len(s) == 0 {
- return false
- }
- c, n := utf8.DecodeRuneInString(s)
- if c == utf8.RuneError && n == 1 {
- return false
- }
- if !unicode.Is(first, c) {
- return false
- }
- for n < len(s) {
- s = s[n:]
- c, n = utf8.DecodeRuneInString(s)
- if c == utf8.RuneError && n == 1 {
- return false
- }
- if !unicode.Is(first, c) && !unicode.Is(second, c) {
- return false
- }
- }
- return true
-}
-
-// These tables were generated by cut and paste from Appendix B of
-// the XML spec at https://www.xml.com/axml/testaxml.htm
-// and then reformatting. First corresponds to (Letter | '_' | ':')
-// and second corresponds to NameChar.
-
-var first = &unicode.RangeTable{
- R16: []unicode.Range16{
- {0x003A, 0x003A, 1},
- {0x0041, 0x005A, 1},
- {0x005F, 0x005F, 1},
- {0x0061, 0x007A, 1},
- {0x00C0, 0x00D6, 1},
- {0x00D8, 0x00F6, 1},
- {0x00F8, 0x00FF, 1},
- {0x0100, 0x0131, 1},
- {0x0134, 0x013E, 1},
- {0x0141, 0x0148, 1},
- {0x014A, 0x017E, 1},
- {0x0180, 0x01C3, 1},
- {0x01CD, 0x01F0, 1},
- {0x01F4, 0x01F5, 1},
- {0x01FA, 0x0217, 1},
- {0x0250, 0x02A8, 1},
- {0x02BB, 0x02C1, 1},
- {0x0386, 0x0386, 1},
- {0x0388, 0x038A, 1},
- {0x038C, 0x038C, 1},
- {0x038E, 0x03A1, 1},
- {0x03A3, 0x03CE, 1},
- {0x03D0, 0x03D6, 1},
- {0x03DA, 0x03E0, 2},
- {0x03E2, 0x03F3, 1},
- {0x0401, 0x040C, 1},
- {0x040E, 0x044F, 1},
- {0x0451, 0x045C, 1},
- {0x045E, 0x0481, 1},
- {0x0490, 0x04C4, 1},
- {0x04C7, 0x04C8, 1},
- {0x04CB, 0x04CC, 1},
- {0x04D0, 0x04EB, 1},
- {0x04EE, 0x04F5, 1},
- {0x04F8, 0x04F9, 1},
- {0x0531, 0x0556, 1},
- {0x0559, 0x0559, 1},
- {0x0561, 0x0586, 1},
- {0x05D0, 0x05EA, 1},
- {0x05F0, 0x05F2, 1},
- {0x0621, 0x063A, 1},
- {0x0641, 0x064A, 1},
- {0x0671, 0x06B7, 1},
- {0x06BA, 0x06BE, 1},
- {0x06C0, 0x06CE, 1},
- {0x06D0, 0x06D3, 1},
- {0x06D5, 0x06D5, 1},
- {0x06E5, 0x06E6, 1},
- {0x0905, 0x0939, 1},
- {0x093D, 0x093D, 1},
- {0x0958, 0x0961, 1},
- {0x0985, 0x098C, 1},
- {0x098F, 0x0990, 1},
- {0x0993, 0x09A8, 1},
- {0x09AA, 0x09B0, 1},
- {0x09B2, 0x09B2, 1},
- {0x09B6, 0x09B9, 1},
- {0x09DC, 0x09DD, 1},
- {0x09DF, 0x09E1, 1},
- {0x09F0, 0x09F1, 1},
- {0x0A05, 0x0A0A, 1},
- {0x0A0F, 0x0A10, 1},
- {0x0A13, 0x0A28, 1},
- {0x0A2A, 0x0A30, 1},
- {0x0A32, 0x0A33, 1},
- {0x0A35, 0x0A36, 1},
- {0x0A38, 0x0A39, 1},
- {0x0A59, 0x0A5C, 1},
- {0x0A5E, 0x0A5E, 1},
- {0x0A72, 0x0A74, 1},
- {0x0A85, 0x0A8B, 1},
- {0x0A8D, 0x0A8D, 1},
- {0x0A8F, 0x0A91, 1},
- {0x0A93, 0x0AA8, 1},
- {0x0AAA, 0x0AB0, 1},
- {0x0AB2, 0x0AB3, 1},
- {0x0AB5, 0x0AB9, 1},
- {0x0ABD, 0x0AE0, 0x23},
- {0x0B05, 0x0B0C, 1},
- {0x0B0F, 0x0B10, 1},
- {0x0B13, 0x0B28, 1},
- {0x0B2A, 0x0B30, 1},
- {0x0B32, 0x0B33, 1},
- {0x0B36, 0x0B39, 1},
- {0x0B3D, 0x0B3D, 1},
- {0x0B5C, 0x0B5D, 1},
- {0x0B5F, 0x0B61, 1},
- {0x0B85, 0x0B8A, 1},
- {0x0B8E, 0x0B90, 1},
- {0x0B92, 0x0B95, 1},
- {0x0B99, 0x0B9A, 1},
- {0x0B9C, 0x0B9C, 1},
- {0x0B9E, 0x0B9F, 1},
- {0x0BA3, 0x0BA4, 1},
- {0x0BA8, 0x0BAA, 1},
- {0x0BAE, 0x0BB5, 1},
- {0x0BB7, 0x0BB9, 1},
- {0x0C05, 0x0C0C, 1},
- {0x0C0E, 0x0C10, 1},
- {0x0C12, 0x0C28, 1},
- {0x0C2A, 0x0C33, 1},
- {0x0C35, 0x0C39, 1},
- {0x0C60, 0x0C61, 1},
- {0x0C85, 0x0C8C, 1},
- {0x0C8E, 0x0C90, 1},
- {0x0C92, 0x0CA8, 1},
- {0x0CAA, 0x0CB3, 1},
- {0x0CB5, 0x0CB9, 1},
- {0x0CDE, 0x0CDE, 1},
- {0x0CE0, 0x0CE1, 1},
- {0x0D05, 0x0D0C, 1},
- {0x0D0E, 0x0D10, 1},
- {0x0D12, 0x0D28, 1},
- {0x0D2A, 0x0D39, 1},
- {0x0D60, 0x0D61, 1},
- {0x0E01, 0x0E2E, 1},
- {0x0E30, 0x0E30, 1},
- {0x0E32, 0x0E33, 1},
- {0x0E40, 0x0E45, 1},
- {0x0E81, 0x0E82, 1},
- {0x0E84, 0x0E84, 1},
- {0x0E87, 0x0E88, 1},
- {0x0E8A, 0x0E8D, 3},
- {0x0E94, 0x0E97, 1},
- {0x0E99, 0x0E9F, 1},
- {0x0EA1, 0x0EA3, 1},
- {0x0EA5, 0x0EA7, 2},
- {0x0EAA, 0x0EAB, 1},
- {0x0EAD, 0x0EAE, 1},
- {0x0EB0, 0x0EB0, 1},
- {0x0EB2, 0x0EB3, 1},
- {0x0EBD, 0x0EBD, 1},
- {0x0EC0, 0x0EC4, 1},
- {0x0F40, 0x0F47, 1},
- {0x0F49, 0x0F69, 1},
- {0x10A0, 0x10C5, 1},
- {0x10D0, 0x10F6, 1},
- {0x1100, 0x1100, 1},
- {0x1102, 0x1103, 1},
- {0x1105, 0x1107, 1},
- {0x1109, 0x1109, 1},
- {0x110B, 0x110C, 1},
- {0x110E, 0x1112, 1},
- {0x113C, 0x1140, 2},
- {0x114C, 0x1150, 2},
- {0x1154, 0x1155, 1},
- {0x1159, 0x1159, 1},
- {0x115F, 0x1161, 1},
- {0x1163, 0x1169, 2},
- {0x116D, 0x116E, 1},
- {0x1172, 0x1173, 1},
- {0x1175, 0x119E, 0x119E - 0x1175},
- {0x11A8, 0x11AB, 0x11AB - 0x11A8},
- {0x11AE, 0x11AF, 1},
- {0x11B7, 0x11B8, 1},
- {0x11BA, 0x11BA, 1},
- {0x11BC, 0x11C2, 1},
- {0x11EB, 0x11F0, 0x11F0 - 0x11EB},
- {0x11F9, 0x11F9, 1},
- {0x1E00, 0x1E9B, 1},
- {0x1EA0, 0x1EF9, 1},
- {0x1F00, 0x1F15, 1},
- {0x1F18, 0x1F1D, 1},
- {0x1F20, 0x1F45, 1},
- {0x1F48, 0x1F4D, 1},
- {0x1F50, 0x1F57, 1},
- {0x1F59, 0x1F5B, 0x1F5B - 0x1F59},
- {0x1F5D, 0x1F5D, 1},
- {0x1F5F, 0x1F7D, 1},
- {0x1F80, 0x1FB4, 1},
- {0x1FB6, 0x1FBC, 1},
- {0x1FBE, 0x1FBE, 1},
- {0x1FC2, 0x1FC4, 1},
- {0x1FC6, 0x1FCC, 1},
- {0x1FD0, 0x1FD3, 1},
- {0x1FD6, 0x1FDB, 1},
- {0x1FE0, 0x1FEC, 1},
- {0x1FF2, 0x1FF4, 1},
- {0x1FF6, 0x1FFC, 1},
- {0x2126, 0x2126, 1},
- {0x212A, 0x212B, 1},
- {0x212E, 0x212E, 1},
- {0x2180, 0x2182, 1},
- {0x3007, 0x3007, 1},
- {0x3021, 0x3029, 1},
- {0x3041, 0x3094, 1},
- {0x30A1, 0x30FA, 1},
- {0x3105, 0x312C, 1},
- {0x4E00, 0x9FA5, 1},
- {0xAC00, 0xD7A3, 1},
- },
-}
-
-var second = &unicode.RangeTable{
- R16: []unicode.Range16{
- {0x002D, 0x002E, 1},
- {0x0030, 0x0039, 1},
- {0x00B7, 0x00B7, 1},
- {0x02D0, 0x02D1, 1},
- {0x0300, 0x0345, 1},
- {0x0360, 0x0361, 1},
- {0x0387, 0x0387, 1},
- {0x0483, 0x0486, 1},
- {0x0591, 0x05A1, 1},
- {0x05A3, 0x05B9, 1},
- {0x05BB, 0x05BD, 1},
- {0x05BF, 0x05BF, 1},
- {0x05C1, 0x05C2, 1},
- {0x05C4, 0x0640, 0x0640 - 0x05C4},
- {0x064B, 0x0652, 1},
- {0x0660, 0x0669, 1},
- {0x0670, 0x0670, 1},
- {0x06D6, 0x06DC, 1},
- {0x06DD, 0x06DF, 1},
- {0x06E0, 0x06E4, 1},
- {0x06E7, 0x06E8, 1},
- {0x06EA, 0x06ED, 1},
- {0x06F0, 0x06F9, 1},
- {0x0901, 0x0903, 1},
- {0x093C, 0x093C, 1},
- {0x093E, 0x094C, 1},
- {0x094D, 0x094D, 1},
- {0x0951, 0x0954, 1},
- {0x0962, 0x0963, 1},
- {0x0966, 0x096F, 1},
- {0x0981, 0x0983, 1},
- {0x09BC, 0x09BC, 1},
- {0x09BE, 0x09BF, 1},
- {0x09C0, 0x09C4, 1},
- {0x09C7, 0x09C8, 1},
- {0x09CB, 0x09CD, 1},
- {0x09D7, 0x09D7, 1},
- {0x09E2, 0x09E3, 1},
- {0x09E6, 0x09EF, 1},
- {0x0A02, 0x0A3C, 0x3A},
- {0x0A3E, 0x0A3F, 1},
- {0x0A40, 0x0A42, 1},
- {0x0A47, 0x0A48, 1},
- {0x0A4B, 0x0A4D, 1},
- {0x0A66, 0x0A6F, 1},
- {0x0A70, 0x0A71, 1},
- {0x0A81, 0x0A83, 1},
- {0x0ABC, 0x0ABC, 1},
- {0x0ABE, 0x0AC5, 1},
- {0x0AC7, 0x0AC9, 1},
- {0x0ACB, 0x0ACD, 1},
- {0x0AE6, 0x0AEF, 1},
- {0x0B01, 0x0B03, 1},
- {0x0B3C, 0x0B3C, 1},
- {0x0B3E, 0x0B43, 1},
- {0x0B47, 0x0B48, 1},
- {0x0B4B, 0x0B4D, 1},
- {0x0B56, 0x0B57, 1},
- {0x0B66, 0x0B6F, 1},
- {0x0B82, 0x0B83, 1},
- {0x0BBE, 0x0BC2, 1},
- {0x0BC6, 0x0BC8, 1},
- {0x0BCA, 0x0BCD, 1},
- {0x0BD7, 0x0BD7, 1},
- {0x0BE7, 0x0BEF, 1},
- {0x0C01, 0x0C03, 1},
- {0x0C3E, 0x0C44, 1},
- {0x0C46, 0x0C48, 1},
- {0x0C4A, 0x0C4D, 1},
- {0x0C55, 0x0C56, 1},
- {0x0C66, 0x0C6F, 1},
- {0x0C82, 0x0C83, 1},
- {0x0CBE, 0x0CC4, 1},
- {0x0CC6, 0x0CC8, 1},
- {0x0CCA, 0x0CCD, 1},
- {0x0CD5, 0x0CD6, 1},
- {0x0CE6, 0x0CEF, 1},
- {0x0D02, 0x0D03, 1},
- {0x0D3E, 0x0D43, 1},
- {0x0D46, 0x0D48, 1},
- {0x0D4A, 0x0D4D, 1},
- {0x0D57, 0x0D57, 1},
- {0x0D66, 0x0D6F, 1},
- {0x0E31, 0x0E31, 1},
- {0x0E34, 0x0E3A, 1},
- {0x0E46, 0x0E46, 1},
- {0x0E47, 0x0E4E, 1},
- {0x0E50, 0x0E59, 1},
- {0x0EB1, 0x0EB1, 1},
- {0x0EB4, 0x0EB9, 1},
- {0x0EBB, 0x0EBC, 1},
- {0x0EC6, 0x0EC6, 1},
- {0x0EC8, 0x0ECD, 1},
- {0x0ED0, 0x0ED9, 1},
- {0x0F18, 0x0F19, 1},
- {0x0F20, 0x0F29, 1},
- {0x0F35, 0x0F39, 2},
- {0x0F3E, 0x0F3F, 1},
- {0x0F71, 0x0F84, 1},
- {0x0F86, 0x0F8B, 1},
- {0x0F90, 0x0F95, 1},
- {0x0F97, 0x0F97, 1},
- {0x0F99, 0x0FAD, 1},
- {0x0FB1, 0x0FB7, 1},
- {0x0FB9, 0x0FB9, 1},
- {0x20D0, 0x20DC, 1},
- {0x20E1, 0x3005, 0x3005 - 0x20E1},
- {0x302A, 0x302F, 1},
- {0x3031, 0x3035, 1},
- {0x3099, 0x309A, 1},
- {0x309D, 0x309E, 1},
- {0x30FC, 0x30FE, 1},
- },
-}
-
-// HTMLEntity is an entity map containing translations for the
-// standard HTML entity characters.
-//
-// See the Decoder.Strict and Decoder.Entity fields' documentation.
-var HTMLEntity map[string]string = htmlEntity
-
-var htmlEntity = map[string]string{
- /*
- hget http://www.w3.org/TR/html4/sgml/entities.html |
- ssam '
- ,y /\&gt;/ x/\&lt;(.|\n)+/ s/\n/ /g
- ,x v/^\&lt;!ENTITY/d
- ,s/\&lt;!ENTITY ([^ ]+) .*U\+([0-9A-F][0-9A-F][0-9A-F][0-9A-F]) .+/ "\1": "\\u\2",/g
- '
- */
- "nbsp": "\u00A0",
- "iexcl": "\u00A1",
- "cent": "\u00A2",
- "pound": "\u00A3",
- "curren": "\u00A4",
- "yen": "\u00A5",
- "brvbar": "\u00A6",
- "sect": "\u00A7",
- "uml": "\u00A8",
- "copy": "\u00A9",
- "ordf": "\u00AA",
- "laquo": "\u00AB",
- "not": "\u00AC",
- "shy": "\u00AD",
- "reg": "\u00AE",
- "macr": "\u00AF",
- "deg": "\u00B0",
- "plusmn": "\u00B1",
- "sup2": "\u00B2",
- "sup3": "\u00B3",
- "acute": "\u00B4",
- "micro": "\u00B5",
- "para": "\u00B6",
- "middot": "\u00B7",
- "cedil": "\u00B8",
- "sup1": "\u00B9",
- "ordm": "\u00BA",
- "raquo": "\u00BB",
- "frac14": "\u00BC",
- "frac12": "\u00BD",
- "frac34": "\u00BE",
- "iquest": "\u00BF",
- "Agrave": "\u00C0",
- "Aacute": "\u00C1",
- "Acirc": "\u00C2",
- "Atilde": "\u00C3",
- "Auml": "\u00C4",
- "Aring": "\u00C5",
- "AElig": "\u00C6",
- "Ccedil": "\u00C7",
- "Egrave": "\u00C8",
- "Eacute": "\u00C9",
- "Ecirc": "\u00CA",
- "Euml": "\u00CB",
- "Igrave": "\u00CC",
- "Iacute": "\u00CD",
- "Icirc": "\u00CE",
- "Iuml": "\u00CF",
- "ETH": "\u00D0",
- "Ntilde": "\u00D1",
- "Ograve": "\u00D2",
- "Oacute": "\u00D3",
- "Ocirc": "\u00D4",
- "Otilde": "\u00D5",
- "Ouml": "\u00D6",
- "times": "\u00D7",
- "Oslash": "\u00D8",
- "Ugrave": "\u00D9",
- "Uacute": "\u00DA",
- "Ucirc": "\u00DB",
- "Uuml": "\u00DC",
- "Yacute": "\u00DD",
- "THORN": "\u00DE",
- "szlig": "\u00DF",
- "agrave": "\u00E0",
- "aacute": "\u00E1",
- "acirc": "\u00E2",
- "atilde": "\u00E3",
- "auml": "\u00E4",
- "aring": "\u00E5",
- "aelig": "\u00E6",
- "ccedil": "\u00E7",
- "egrave": "\u00E8",
- "eacute": "\u00E9",
- "ecirc": "\u00EA",
- "euml": "\u00EB",
- "igrave": "\u00EC",
- "iacute": "\u00ED",
- "icirc": "\u00EE",
- "iuml": "\u00EF",
- "eth": "\u00F0",
- "ntilde": "\u00F1",
- "ograve": "\u00F2",
- "oacute": "\u00F3",
- "ocirc": "\u00F4",
- "otilde": "\u00F5",
- "ouml": "\u00F6",
- "divide": "\u00F7",
- "oslash": "\u00F8",
- "ugrave": "\u00F9",
- "uacute": "\u00FA",
- "ucirc": "\u00FB",
- "uuml": "\u00FC",
- "yacute": "\u00FD",
- "thorn": "\u00FE",
- "yuml": "\u00FF",
- "fnof": "\u0192",
- "Alpha": "\u0391",
- "Beta": "\u0392",
- "Gamma": "\u0393",
- "Delta": "\u0394",
- "Epsilon": "\u0395",
- "Zeta": "\u0396",
- "Eta": "\u0397",
- "Theta": "\u0398",
- "Iota": "\u0399",
- "Kappa": "\u039A",
- "Lambda": "\u039B",
- "Mu": "\u039C",
- "Nu": "\u039D",
- "Xi": "\u039E",
- "Omicron": "\u039F",
- "Pi": "\u03A0",
- "Rho": "\u03A1",
- "Sigma": "\u03A3",
- "Tau": "\u03A4",
- "Upsilon": "\u03A5",
- "Phi": "\u03A6",
- "Chi": "\u03A7",
- "Psi": "\u03A8",
- "Omega": "\u03A9",
- "alpha": "\u03B1",
- "beta": "\u03B2",
- "gamma": "\u03B3",
- "delta": "\u03B4",
- "epsilon": "\u03B5",
- "zeta": "\u03B6",
- "eta": "\u03B7",
- "theta": "\u03B8",
- "iota": "\u03B9",
- "kappa": "\u03BA",
- "lambda": "\u03BB",
- "mu": "\u03BC",
- "nu": "\u03BD",
- "xi": "\u03BE",
- "omicron": "\u03BF",
- "pi": "\u03C0",
- "rho": "\u03C1",
- "sigmaf": "\u03C2",
- "sigma": "\u03C3",
- "tau": "\u03C4",
- "upsilon": "\u03C5",
- "phi": "\u03C6",
- "chi": "\u03C7",
- "psi": "\u03C8",
- "omega": "\u03C9",
- "thetasym": "\u03D1",
- "upsih": "\u03D2",
- "piv": "\u03D6",
- "bull": "\u2022",
- "hellip": "\u2026",
- "prime": "\u2032",
- "Prime": "\u2033",
- "oline": "\u203E",
- "frasl": "\u2044",
- "weierp": "\u2118",
- "image": "\u2111",
- "real": "\u211C",
- "trade": "\u2122",
- "alefsym": "\u2135",
- "larr": "\u2190",
- "uarr": "\u2191",
- "rarr": "\u2192",
- "darr": "\u2193",
- "harr": "\u2194",
- "crarr": "\u21B5",
- "lArr": "\u21D0",
- "uArr": "\u21D1",
- "rArr": "\u21D2",
- "dArr": "\u21D3",
- "hArr": "\u21D4",
- "forall": "\u2200",
- "part": "\u2202",
- "exist": "\u2203",
- "empty": "\u2205",
- "nabla": "\u2207",
- "isin": "\u2208",
- "notin": "\u2209",
- "ni": "\u220B",
- "prod": "\u220F",
- "sum": "\u2211",
- "minus": "\u2212",
- "lowast": "\u2217",
- "radic": "\u221A",
- "prop": "\u221D",
- "infin": "\u221E",
- "ang": "\u2220",
- "and": "\u2227",
- "or": "\u2228",
- "cap": "\u2229",
- "cup": "\u222A",
- "int": "\u222B",
- "there4": "\u2234",
- "sim": "\u223C",
- "cong": "\u2245",
- "asymp": "\u2248",
- "ne": "\u2260",
- "equiv": "\u2261",
- "le": "\u2264",
- "ge": "\u2265",
- "sub": "\u2282",
- "sup": "\u2283",
- "nsub": "\u2284",
- "sube": "\u2286",
- "supe": "\u2287",
- "oplus": "\u2295",
- "otimes": "\u2297",
- "perp": "\u22A5",
- "sdot": "\u22C5",
- "lceil": "\u2308",
- "rceil": "\u2309",
- "lfloor": "\u230A",
- "rfloor": "\u230B",
- "lang": "\u2329",
- "rang": "\u232A",
- "loz": "\u25CA",
- "spades": "\u2660",
- "clubs": "\u2663",
- "hearts": "\u2665",
- "diams": "\u2666",
- "quot": "\u0022",
- "amp": "\u0026",
- "lt": "\u003C",
- "gt": "\u003E",
- "OElig": "\u0152",
- "oelig": "\u0153",
- "Scaron": "\u0160",
- "scaron": "\u0161",
- "Yuml": "\u0178",
- "circ": "\u02C6",
- "tilde": "\u02DC",
- "ensp": "\u2002",
- "emsp": "\u2003",
- "thinsp": "\u2009",
- "zwnj": "\u200C",
- "zwj": "\u200D",
- "lrm": "\u200E",
- "rlm": "\u200F",
- "ndash": "\u2013",
- "mdash": "\u2014",
- "lsquo": "\u2018",
- "rsquo": "\u2019",
- "sbquo": "\u201A",
- "ldquo": "\u201C",
- "rdquo": "\u201D",
- "bdquo": "\u201E",
- "dagger": "\u2020",
- "Dagger": "\u2021",
- "permil": "\u2030",
- "lsaquo": "\u2039",
- "rsaquo": "\u203A",
- "euro": "\u20AC",
-}
-
-// HTMLAutoClose is the set of HTML elements that
-// should be considered to close automatically.
-//
-// See the Decoder.Strict and Decoder.Entity fields' documentation.
-var HTMLAutoClose []string = htmlAutoClose
-
-var htmlAutoClose = []string{
- /*
- hget http://www.w3.org/TR/html4/loose.dtd |
- 9 sed -n 's/<!ELEMENT ([^ ]*) +- O EMPTY.+/ "\1",/p' | tr A-Z a-z
- */
- "basefont",
- "br",
- "area",
- "link",
- "img",
- "param",
- "hr",
- "input",
- "col",
- "frame",
- "isindex",
- "base",
- "meta",
-}
-
-var (
- escQuot = []byte("&#34;") // shorter than "&quot;"
- escApos = []byte("&#39;") // shorter than "&apos;"
- escAmp = []byte("&amp;")
- escLT = []byte("&lt;")
- escGT = []byte("&gt;")
- escTab = []byte("&#x9;")
- escNL = []byte("&#xA;")
- escCR = []byte("&#xD;")
- escFFFD = []byte("\uFFFD") // Unicode replacement character
-)
-
-// EscapeText writes to w the properly escaped XML equivalent
-// of the plain text data s.
-func EscapeText(w io.Writer, s []byte) error {
- return escapeText(w, s, true)
-}
-
-// escapeText writes to w the properly escaped XML equivalent
-// of the plain text data s. If escapeNewline is true, newline
-// characters will be escaped.
-func escapeText(w io.Writer, s []byte, escapeNewline bool) error {
- var esc []byte
- last := 0
- for i := 0; i < len(s); {
- r, width := utf8.DecodeRune(s[i:])
- i += width
- switch r {
- case '"':
- esc = escQuot
- case '\'':
- esc = escApos
- case '&':
- esc = escAmp
- case '<':
- esc = escLT
- case '>':
- esc = escGT
- case '\t':
- esc = escTab
- case '\n':
- if !escapeNewline {
- continue
- }
- esc = escNL
- case '\r':
- esc = escCR
- default:
- if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
- esc = escFFFD
- break
- }
- continue
- }
- if _, err := w.Write(s[last : i-width]); err != nil {
- return err
- }
- if _, err := w.Write(esc); err != nil {
- return err
- }
- last = i
- }
- _, err := w.Write(s[last:])
- return err
-}
-
-// EscapeString writes to p the properly escaped XML equivalent
-// of the plain text data s.
-func (p *printer) EscapeString(s string) {
- var esc []byte
- last := 0
- for i := 0; i < len(s); {
- r, width := utf8.DecodeRuneInString(s[i:])
- i += width
- switch r {
- case '"':
- esc = escQuot
- case '\'':
- esc = escApos
- case '&':
- esc = escAmp
- case '<':
- esc = escLT
- case '>':
- esc = escGT
- case '\t':
- esc = escTab
- case '\n':
- esc = escNL
- case '\r':
- esc = escCR
- default:
- if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
- esc = escFFFD
- break
- }
- continue
- }
- p.WriteString(s[last : i-width])
- p.Write(esc)
- last = i
- }
- p.WriteString(s[last:])
-}
-
-// Escape is like EscapeText but omits the error return value.
-// It is provided for backwards compatibility with Go 1.0.
-// Code targeting Go 1.1 or later should use EscapeText.
-func Escape(w io.Writer, s []byte) {
- EscapeText(w, s)
-}
-
-var (
- cdataStart = []byte("<![CDATA[")
- cdataEnd = []byte("]]>")
- cdataEscape = []byte("]]]]><![CDATA[>")
-)
-
-// emitCDATA writes to w the CDATA-wrapped plain text data s.
-// It escapes CDATA directives nested in s.
-func emitCDATA(w io.Writer, s []byte) error {
- if len(s) == 0 {
- return nil
- }
- if _, err := w.Write(cdataStart); err != nil {
- return err
- }
-
- for {
- before, after, ok := bytes.Cut(s, cdataEnd)
- if !ok {
- break
- }
- // Found a nested CDATA directive end.
- if _, err := w.Write(before); err != nil {
- return err
- }
- if _, err := w.Write(cdataEscape); err != nil {
- return err
- }
- s = after
- }
-
- if _, err := w.Write(s); err != nil {
- return err
- }
-
- _, err := w.Write(cdataEnd)
- return err
-}
-
-// procInst parses the `param="..."` or `param='...'`
-// value out of the provided string, returning "" if not found.
-func procInst(param, s string) string {
- // TODO: this parsing is somewhat lame and not exact.
- // It works for all actual cases, though.
- param = param + "="
- _, v, _ := strings.Cut(s, param)
- if v == "" {
- return ""
- }
- if v[0] != '\'' && v[0] != '"' {
- return ""
- }
- unquote, _, ok := strings.Cut(v[1:], v[:1])
- if !ok {
- return ""
- }
- return unquote
-}
diff --git a/contrib/go/_std_1.20/src/encoding/xml/ya.make b/contrib/go/_std_1.20/src/encoding/xml/ya.make
deleted file mode 100644
index 7a3003c071..0000000000
--- a/contrib/go/_std_1.20/src/encoding/xml/ya.make
+++ /dev/null
@@ -1,10 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- marshal.go
- read.go
- typeinfo.go
- xml.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/errors/errors.go b/contrib/go/_std_1.20/src/errors/errors.go
deleted file mode 100644
index 8436f812a6..0000000000
--- a/contrib/go/_std_1.20/src/errors/errors.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2011 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 errors implements functions to manipulate errors.
-//
-// The New function creates errors whose only content is a text message.
-//
-// An error e wraps another error if e's type has one of the methods
-//
-// Unwrap() error
-// Unwrap() []error
-//
-// If e.Unwrap() returns a non-nil error w or a slice containing w,
-// then we say that e wraps w. A nil error returned from e.Unwrap()
-// indicates that e does not wrap any error. It is invalid for an
-// Unwrap method to return an []error containing a nil error value.
-//
-// An easy way to create wrapped errors is to call fmt.Errorf and apply
-// the %w verb to the error argument:
-//
-// wrapsErr := fmt.Errorf("... %w ...", ..., err, ...)
-//
-// Successive unwrapping of an error creates a tree. The Is and As
-// functions inspect an error's tree by examining first the error
-// itself followed by the tree of each of its children in turn
-// (pre-order, depth-first traversal).
-//
-// Is examines the tree of its first argument looking for an error that
-// matches the second. It reports whether it finds a match. It should be
-// used in preference to simple equality checks:
-//
-// if errors.Is(err, fs.ErrExist)
-//
-// is preferable to
-//
-// if err == fs.ErrExist
-//
-// because the former will succeed if err wraps fs.ErrExist.
-//
-// As examines the tree of its first argument looking for an error that can be
-// assigned to its second argument, which must be a pointer. If it succeeds, it
-// performs the assignment and returns true. Otherwise, it returns false. The form
-//
-// var perr *fs.PathError
-// if errors.As(err, &perr) {
-// fmt.Println(perr.Path)
-// }
-//
-// is preferable to
-//
-// if perr, ok := err.(*fs.PathError); ok {
-// fmt.Println(perr.Path)
-// }
-//
-// because the former will succeed if err wraps an *fs.PathError.
-package errors
-
-// New returns an error that formats as the given text.
-// Each call to New returns a distinct error value even if the text is identical.
-func New(text string) error {
- return &errorString{text}
-}
-
-// errorString is a trivial implementation of error.
-type errorString struct {
- s string
-}
-
-func (e *errorString) Error() string {
- return e.s
-}
diff --git a/contrib/go/_std_1.20/src/errors/join.go b/contrib/go/_std_1.20/src/errors/join.go
deleted file mode 100644
index dc5a716aa6..0000000000
--- a/contrib/go/_std_1.20/src/errors/join.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2022 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 errors
-
-// Join returns an error that wraps the given errors.
-// Any nil error values are discarded.
-// Join returns nil if errs contains no non-nil values.
-// The error formats as the concatenation of the strings obtained
-// by calling the Error method of each element of errs, with a newline
-// between each string.
-func Join(errs ...error) error {
- n := 0
- for _, err := range errs {
- if err != nil {
- n++
- }
- }
- if n == 0 {
- return nil
- }
- e := &joinError{
- errs: make([]error, 0, n),
- }
- for _, err := range errs {
- if err != nil {
- e.errs = append(e.errs, err)
- }
- }
- return e
-}
-
-type joinError struct {
- errs []error
-}
-
-func (e *joinError) Error() string {
- var b []byte
- for i, err := range e.errs {
- if i > 0 {
- b = append(b, '\n')
- }
- b = append(b, err.Error()...)
- }
- return string(b)
-}
-
-func (e *joinError) Unwrap() []error {
- return e.errs
-}
diff --git a/contrib/go/_std_1.20/src/errors/wrap.go b/contrib/go/_std_1.20/src/errors/wrap.go
deleted file mode 100644
index a719655b10..0000000000
--- a/contrib/go/_std_1.20/src/errors/wrap.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2018 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 errors
-
-import (
- "internal/reflectlite"
-)
-
-// Unwrap returns the result of calling the Unwrap method on err, if err's
-// type contains an Unwrap method returning error.
-// Otherwise, Unwrap returns nil.
-//
-// Unwrap returns nil if the Unwrap method returns []error.
-func Unwrap(err error) error {
- u, ok := err.(interface {
- Unwrap() error
- })
- if !ok {
- return nil
- }
- return u.Unwrap()
-}
-
-// Is reports whether any error in err's tree matches target.
-//
-// The tree consists of err itself, followed by the errors obtained by repeatedly
-// calling Unwrap. When err wraps multiple errors, Is examines err followed by a
-// depth-first traversal of its children.
-//
-// An error is considered to match a target if it is equal to that target or if
-// it implements a method Is(error) bool such that Is(target) returns true.
-//
-// An error type might provide an Is method so it can be treated as equivalent
-// to an existing error. For example, if MyError defines
-//
-// func (m MyError) Is(target error) bool { return target == fs.ErrExist }
-//
-// then Is(MyError{}, fs.ErrExist) returns true. See syscall.Errno.Is for
-// an example in the standard library. An Is method should only shallowly
-// compare err and the target and not call Unwrap on either.
-func Is(err, target error) bool {
- if target == nil {
- return err == target
- }
-
- isComparable := reflectlite.TypeOf(target).Comparable()
- for {
- if isComparable && err == target {
- return true
- }
- if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
- return true
- }
- switch x := err.(type) {
- case interface{ Unwrap() error }:
- err = x.Unwrap()
- if err == nil {
- return false
- }
- case interface{ Unwrap() []error }:
- for _, err := range x.Unwrap() {
- if Is(err, target) {
- return true
- }
- }
- return false
- default:
- return false
- }
- }
-}
-
-// As finds the first error in err's tree that matches target, and if one is found, sets
-// target to that error value and returns true. Otherwise, it returns false.
-//
-// The tree consists of err itself, followed by the errors obtained by repeatedly
-// calling Unwrap. When err wraps multiple errors, As examines err followed by a
-// depth-first traversal of its children.
-//
-// An error matches target if the error's concrete value is assignable to the value
-// pointed to by target, or if the error has a method As(interface{}) bool such that
-// As(target) returns true. In the latter case, the As method is responsible for
-// setting target.
-//
-// An error type might provide an As method so it can be treated as if it were a
-// different error type.
-//
-// As panics if target is not a non-nil pointer to either a type that implements
-// error, or to any interface type.
-func As(err error, target any) bool {
- if err == nil {
- return false
- }
- if target == nil {
- panic("errors: target cannot be nil")
- }
- val := reflectlite.ValueOf(target)
- typ := val.Type()
- if typ.Kind() != reflectlite.Ptr || val.IsNil() {
- panic("errors: target must be a non-nil pointer")
- }
- targetType := typ.Elem()
- if targetType.Kind() != reflectlite.Interface && !targetType.Implements(errorType) {
- panic("errors: *target must be interface or implement error")
- }
- for {
- if reflectlite.TypeOf(err).AssignableTo(targetType) {
- val.Elem().Set(reflectlite.ValueOf(err))
- return true
- }
- if x, ok := err.(interface{ As(any) bool }); ok && x.As(target) {
- return true
- }
- switch x := err.(type) {
- case interface{ Unwrap() error }:
- err = x.Unwrap()
- if err == nil {
- return false
- }
- case interface{ Unwrap() []error }:
- for _, err := range x.Unwrap() {
- if As(err, target) {
- return true
- }
- }
- return false
- default:
- return false
- }
- }
-}
-
-var errorType = reflectlite.TypeOf((*error)(nil)).Elem()
diff --git a/contrib/go/_std_1.20/src/errors/ya.make b/contrib/go/_std_1.20/src/errors/ya.make
deleted file mode 100644
index 658dc0494c..0000000000
--- a/contrib/go/_std_1.20/src/errors/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- errors.go
- join.go
- wrap.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/expvar/ya.make b/contrib/go/_std_1.20/src/expvar/ya.make
deleted file mode 100644
index 72d16fac5f..0000000000
--- a/contrib/go/_std_1.20/src/expvar/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- expvar.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/flag/flag.go b/contrib/go/_std_1.20/src/flag/flag.go
deleted file mode 100644
index ef3cf29c0c..0000000000
--- a/contrib/go/_std_1.20/src/flag/flag.go
+++ /dev/null
@@ -1,1182 +0,0 @@
-// Copyright 2009 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 flag implements command-line flag parsing.
-
-# Usage
-
-Define flags using flag.String(), Bool(), Int(), etc.
-
-This declares an integer flag, -n, stored in the pointer nFlag, with type *int:
-
- import "flag"
- var nFlag = flag.Int("n", 1234, "help message for flag n")
-
-If you like, you can bind the flag to a variable using the Var() functions.
-
- var flagvar int
- func init() {
- flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
- }
-
-Or you can create custom flags that satisfy the Value interface (with
-pointer receivers) and couple them to flag parsing by
-
- flag.Var(&flagVal, "name", "help message for flagname")
-
-For such flags, the default value is just the initial value of the variable.
-
-After all flags are defined, call
-
- flag.Parse()
-
-to parse the command line into the defined flags.
-
-Flags may then be used directly. If you're using the flags themselves,
-they are all pointers; if you bind to variables, they're values.
-
- fmt.Println("ip has value ", *ip)
- fmt.Println("flagvar has value ", flagvar)
-
-After parsing, the arguments following the flags are available as the
-slice flag.Args() or individually as flag.Arg(i).
-The arguments are indexed from 0 through flag.NArg()-1.
-
-# Command line flag syntax
-
-The following forms are permitted:
-
- -flag
- --flag // double dashes are also permitted
- -flag=x
- -flag x // non-boolean flags only
-
-One or two dashes may be used; they are equivalent.
-The last form is not permitted for boolean flags because the
-meaning of the command
-
- cmd -x *
-
-where * is a Unix shell wildcard, will change if there is a file
-called 0, false, etc. You must use the -flag=false form to turn
-off a boolean flag.
-
-Flag parsing stops just before the first non-flag argument
-("-" is a non-flag argument) or after the terminator "--".
-
-Integer flags accept 1234, 0664, 0x1234 and may be negative.
-Boolean flags may be:
-
- 1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False
-
-Duration flags accept any input valid for time.ParseDuration.
-
-The default set of command-line flags is controlled by
-top-level functions. The FlagSet type allows one to define
-independent sets of flags, such as to implement subcommands
-in a command-line interface. The methods of FlagSet are
-analogous to the top-level functions for the command-line
-flag set.
-*/
-package flag
-
-import (
- "encoding"
- "errors"
- "fmt"
- "io"
- "os"
- "reflect"
- "sort"
- "strconv"
- "strings"
- "time"
-)
-
-// ErrHelp is the error returned if the -help or -h flag is invoked
-// but no such flag is defined.
-var ErrHelp = errors.New("flag: help requested")
-
-// errParse is returned by Set if a flag's value fails to parse, such as with an invalid integer for Int.
-// It then gets wrapped through failf to provide more information.
-var errParse = errors.New("parse error")
-
-// errRange is returned by Set if a flag's value is out of range.
-// It then gets wrapped through failf to provide more information.
-var errRange = errors.New("value out of range")
-
-func numError(err error) error {
- ne, ok := err.(*strconv.NumError)
- if !ok {
- return err
- }
- if ne.Err == strconv.ErrSyntax {
- return errParse
- }
- if ne.Err == strconv.ErrRange {
- return errRange
- }
- return err
-}
-
-// -- bool Value
-type boolValue bool
-
-func newBoolValue(val bool, p *bool) *boolValue {
- *p = val
- return (*boolValue)(p)
-}
-
-func (b *boolValue) Set(s string) error {
- v, err := strconv.ParseBool(s)
- if err != nil {
- err = errParse
- }
- *b = boolValue(v)
- return err
-}
-
-func (b *boolValue) Get() any { return bool(*b) }
-
-func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) }
-
-func (b *boolValue) IsBoolFlag() bool { return true }
-
-// optional interface to indicate boolean flags that can be
-// supplied without "=value" text
-type boolFlag interface {
- Value
- IsBoolFlag() bool
-}
-
-// -- int Value
-type intValue int
-
-func newIntValue(val int, p *int) *intValue {
- *p = val
- return (*intValue)(p)
-}
-
-func (i *intValue) Set(s string) error {
- v, err := strconv.ParseInt(s, 0, strconv.IntSize)
- if err != nil {
- err = numError(err)
- }
- *i = intValue(v)
- return err
-}
-
-func (i *intValue) Get() any { return int(*i) }
-
-func (i *intValue) String() string { return strconv.Itoa(int(*i)) }
-
-// -- int64 Value
-type int64Value int64
-
-func newInt64Value(val int64, p *int64) *int64Value {
- *p = val
- return (*int64Value)(p)
-}
-
-func (i *int64Value) Set(s string) error {
- v, err := strconv.ParseInt(s, 0, 64)
- if err != nil {
- err = numError(err)
- }
- *i = int64Value(v)
- return err
-}
-
-func (i *int64Value) Get() any { return int64(*i) }
-
-func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) }
-
-// -- uint Value
-type uintValue uint
-
-func newUintValue(val uint, p *uint) *uintValue {
- *p = val
- return (*uintValue)(p)
-}
-
-func (i *uintValue) Set(s string) error {
- v, err := strconv.ParseUint(s, 0, strconv.IntSize)
- if err != nil {
- err = numError(err)
- }
- *i = uintValue(v)
- return err
-}
-
-func (i *uintValue) Get() any { return uint(*i) }
-
-func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) }
-
-// -- uint64 Value
-type uint64Value uint64
-
-func newUint64Value(val uint64, p *uint64) *uint64Value {
- *p = val
- return (*uint64Value)(p)
-}
-
-func (i *uint64Value) Set(s string) error {
- v, err := strconv.ParseUint(s, 0, 64)
- if err != nil {
- err = numError(err)
- }
- *i = uint64Value(v)
- return err
-}
-
-func (i *uint64Value) Get() any { return uint64(*i) }
-
-func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
-
-// -- string Value
-type stringValue string
-
-func newStringValue(val string, p *string) *stringValue {
- *p = val
- return (*stringValue)(p)
-}
-
-func (s *stringValue) Set(val string) error {
- *s = stringValue(val)
- return nil
-}
-
-func (s *stringValue) Get() any { return string(*s) }
-
-func (s *stringValue) String() string { return string(*s) }
-
-// -- float64 Value
-type float64Value float64
-
-func newFloat64Value(val float64, p *float64) *float64Value {
- *p = val
- return (*float64Value)(p)
-}
-
-func (f *float64Value) Set(s string) error {
- v, err := strconv.ParseFloat(s, 64)
- if err != nil {
- err = numError(err)
- }
- *f = float64Value(v)
- return err
-}
-
-func (f *float64Value) Get() any { return float64(*f) }
-
-func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) }
-
-// -- time.Duration Value
-type durationValue time.Duration
-
-func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
- *p = val
- return (*durationValue)(p)
-}
-
-func (d *durationValue) Set(s string) error {
- v, err := time.ParseDuration(s)
- if err != nil {
- err = errParse
- }
- *d = durationValue(v)
- return err
-}
-
-func (d *durationValue) Get() any { return time.Duration(*d) }
-
-func (d *durationValue) String() string { return (*time.Duration)(d).String() }
-
-// -- encoding.TextUnmarshaler Value
-type textValue struct{ p encoding.TextUnmarshaler }
-
-func newTextValue(val encoding.TextMarshaler, p encoding.TextUnmarshaler) textValue {
- ptrVal := reflect.ValueOf(p)
- if ptrVal.Kind() != reflect.Ptr {
- panic("variable value type must be a pointer")
- }
- defVal := reflect.ValueOf(val)
- if defVal.Kind() == reflect.Ptr {
- defVal = defVal.Elem()
- }
- if defVal.Type() != ptrVal.Type().Elem() {
- panic(fmt.Sprintf("default type does not match variable type: %v != %v", defVal.Type(), ptrVal.Type().Elem()))
- }
- ptrVal.Elem().Set(defVal)
- return textValue{p}
-}
-
-func (v textValue) Set(s string) error {
- return v.p.UnmarshalText([]byte(s))
-}
-
-func (v textValue) Get() interface{} {
- return v.p
-}
-
-func (v textValue) String() string {
- if m, ok := v.p.(encoding.TextMarshaler); ok {
- if b, err := m.MarshalText(); err == nil {
- return string(b)
- }
- }
- return ""
-}
-
-// -- func Value
-type funcValue func(string) error
-
-func (f funcValue) Set(s string) error { return f(s) }
-
-func (f funcValue) String() string { return "" }
-
-// Value is the interface to the dynamic value stored in a flag.
-// (The default value is represented as a string.)
-//
-// If a Value has an IsBoolFlag() bool method returning true,
-// the command-line parser makes -name equivalent to -name=true
-// rather than using the next command-line argument.
-//
-// Set is called once, in command line order, for each flag present.
-// The flag package may call the String method with a zero-valued receiver,
-// such as a nil pointer.
-type Value interface {
- String() string
- Set(string) error
-}
-
-// Getter is an interface that allows the contents of a Value to be retrieved.
-// It wraps the Value interface, rather than being part of it, because it
-// appeared after Go 1 and its compatibility rules. All Value types provided
-// by this package satisfy the Getter interface, except the type used by Func.
-type Getter interface {
- Value
- Get() any
-}
-
-// ErrorHandling defines how FlagSet.Parse behaves if the parse fails.
-type ErrorHandling int
-
-// These constants cause FlagSet.Parse to behave as described if the parse fails.
-const (
- ContinueOnError ErrorHandling = iota // Return a descriptive error.
- ExitOnError // Call os.Exit(2) or for -h/-help Exit(0).
- PanicOnError // Call panic with a descriptive error.
-)
-
-// A FlagSet represents a set of defined flags. The zero value of a FlagSet
-// has no name and has ContinueOnError error handling.
-//
-// Flag names must be unique within a FlagSet. An attempt to define a flag whose
-// name is already in use will cause a panic.
-type FlagSet struct {
- // Usage is the function called when an error occurs while parsing flags.
- // The field is a function (not a method) that may be changed to point to
- // a custom error handler. What happens after Usage is called depends
- // on the ErrorHandling setting; for the command line, this defaults
- // to ExitOnError, which exits the program after calling Usage.
- Usage func()
-
- name string
- parsed bool
- actual map[string]*Flag
- formal map[string]*Flag
- args []string // arguments after flags
- errorHandling ErrorHandling
- output io.Writer // nil means stderr; use Output() accessor
-}
-
-// A Flag represents the state of a flag.
-type Flag struct {
- Name string // name as it appears on command line
- Usage string // help message
- Value Value // value as set
- DefValue string // default value (as text); for usage message
-}
-
-// sortFlags returns the flags as a slice in lexicographical sorted order.
-func sortFlags(flags map[string]*Flag) []*Flag {
- result := make([]*Flag, len(flags))
- i := 0
- for _, f := range flags {
- result[i] = f
- i++
- }
- sort.Slice(result, func(i, j int) bool {
- return result[i].Name < result[j].Name
- })
- return result
-}
-
-// Output returns the destination for usage and error messages. os.Stderr is returned if
-// output was not set or was set to nil.
-func (f *FlagSet) Output() io.Writer {
- if f.output == nil {
- return os.Stderr
- }
- return f.output
-}
-
-// Name returns the name of the flag set.
-func (f *FlagSet) Name() string {
- return f.name
-}
-
-// ErrorHandling returns the error handling behavior of the flag set.
-func (f *FlagSet) ErrorHandling() ErrorHandling {
- return f.errorHandling
-}
-
-// SetOutput sets the destination for usage and error messages.
-// If output is nil, os.Stderr is used.
-func (f *FlagSet) SetOutput(output io.Writer) {
- f.output = output
-}
-
-// VisitAll visits the flags in lexicographical order, calling fn for each.
-// It visits all flags, even those not set.
-func (f *FlagSet) VisitAll(fn func(*Flag)) {
- for _, flag := range sortFlags(f.formal) {
- fn(flag)
- }
-}
-
-// VisitAll visits the command-line flags in lexicographical order, calling
-// fn for each. It visits all flags, even those not set.
-func VisitAll(fn func(*Flag)) {
- CommandLine.VisitAll(fn)
-}
-
-// Visit visits the flags in lexicographical order, calling fn for each.
-// It visits only those flags that have been set.
-func (f *FlagSet) Visit(fn func(*Flag)) {
- for _, flag := range sortFlags(f.actual) {
- fn(flag)
- }
-}
-
-// Visit visits the command-line flags in lexicographical order, calling fn
-// for each. It visits only those flags that have been set.
-func Visit(fn func(*Flag)) {
- CommandLine.Visit(fn)
-}
-
-// Lookup returns the Flag structure of the named flag, returning nil if none exists.
-func (f *FlagSet) Lookup(name string) *Flag {
- return f.formal[name]
-}
-
-// Lookup returns the Flag structure of the named command-line flag,
-// returning nil if none exists.
-func Lookup(name string) *Flag {
- return CommandLine.formal[name]
-}
-
-// Set sets the value of the named flag.
-func (f *FlagSet) Set(name, value string) error {
- flag, ok := f.formal[name]
- if !ok {
- return fmt.Errorf("no such flag -%v", name)
- }
- err := flag.Value.Set(value)
- if err != nil {
- return err
- }
- if f.actual == nil {
- f.actual = make(map[string]*Flag)
- }
- f.actual[name] = flag
- return nil
-}
-
-// Set sets the value of the named command-line flag.
-func Set(name, value string) error {
- return CommandLine.Set(name, value)
-}
-
-// isZeroValue determines whether the string represents the zero
-// value for a flag.
-func isZeroValue(flag *Flag, value string) (ok bool, err error) {
- // Build a zero value of the flag's Value type, and see if the
- // result of calling its String method equals the value passed in.
- // This works unless the Value type is itself an interface type.
- typ := reflect.TypeOf(flag.Value)
- var z reflect.Value
- if typ.Kind() == reflect.Pointer {
- z = reflect.New(typ.Elem())
- } else {
- z = reflect.Zero(typ)
- }
- // Catch panics calling the String method, which shouldn't prevent the
- // usage message from being printed, but that we should report to the
- // user so that they know to fix their code.
- defer func() {
- if e := recover(); e != nil {
- if typ.Kind() == reflect.Pointer {
- typ = typ.Elem()
- }
- err = fmt.Errorf("panic calling String method on zero %v for flag %s: %v", typ, flag.Name, e)
- }
- }()
- return value == z.Interface().(Value).String(), nil
-}
-
-// UnquoteUsage extracts a back-quoted name from the usage
-// string for a flag and returns it and the un-quoted usage.
-// Given "a `name` to show" it returns ("name", "a name to show").
-// If there are no back quotes, the name is an educated guess of the
-// type of the flag's value, or the empty string if the flag is boolean.
-func UnquoteUsage(flag *Flag) (name string, usage string) {
- // Look for a back-quoted name, but avoid the strings package.
- usage = flag.Usage
- for i := 0; i < len(usage); i++ {
- if usage[i] == '`' {
- for j := i + 1; j < len(usage); j++ {
- if usage[j] == '`' {
- name = usage[i+1 : j]
- usage = usage[:i] + name + usage[j+1:]
- return name, usage
- }
- }
- break // Only one back quote; use type name.
- }
- }
- // No explicit name, so use type if we can find one.
- name = "value"
- switch fv := flag.Value.(type) {
- case boolFlag:
- if fv.IsBoolFlag() {
- name = ""
- }
- case *durationValue:
- name = "duration"
- case *float64Value:
- name = "float"
- case *intValue, *int64Value:
- name = "int"
- case *stringValue:
- name = "string"
- case *uintValue, *uint64Value:
- name = "uint"
- }
- return
-}
-
-// PrintDefaults prints, to standard error unless configured otherwise, the
-// default values of all defined command-line flags in the set. See the
-// documentation for the global function PrintDefaults for more information.
-func (f *FlagSet) PrintDefaults() {
- var isZeroValueErrs []error
- f.VisitAll(func(flag *Flag) {
- var b strings.Builder
- fmt.Fprintf(&b, " -%s", flag.Name) // Two spaces before -; see next two comments.
- name, usage := UnquoteUsage(flag)
- if len(name) > 0 {
- b.WriteString(" ")
- b.WriteString(name)
- }
- // Boolean flags of one ASCII letter are so common we
- // treat them specially, putting their usage on the same line.
- if b.Len() <= 4 { // space, space, '-', 'x'.
- b.WriteString("\t")
- } else {
- // Four spaces before the tab triggers good alignment
- // for both 4- and 8-space tab stops.
- b.WriteString("\n \t")
- }
- b.WriteString(strings.ReplaceAll(usage, "\n", "\n \t"))
-
- // Print the default value only if it differs to the zero value
- // for this flag type.
- if isZero, err := isZeroValue(flag, flag.DefValue); err != nil {
- isZeroValueErrs = append(isZeroValueErrs, err)
- } else if !isZero {
- if _, ok := flag.Value.(*stringValue); ok {
- // put quotes on the value
- fmt.Fprintf(&b, " (default %q)", flag.DefValue)
- } else {
- fmt.Fprintf(&b, " (default %v)", flag.DefValue)
- }
- }
- fmt.Fprint(f.Output(), b.String(), "\n")
- })
- // If calling String on any zero flag.Values triggered a panic, print
- // the messages after the full set of defaults so that the programmer
- // knows to fix the panic.
- if errs := isZeroValueErrs; len(errs) > 0 {
- fmt.Fprintln(f.Output())
- for _, err := range errs {
- fmt.Fprintln(f.Output(), err)
- }
- }
-}
-
-// PrintDefaults prints, to standard error unless configured otherwise,
-// a usage message showing the default settings of all defined
-// command-line flags.
-// For an integer valued flag x, the default output has the form
-//
-// -x int
-// usage-message-for-x (default 7)
-//
-// The usage message will appear on a separate line for anything but
-// a bool flag with a one-byte name. For bool flags, the type is
-// omitted and if the flag name is one byte the usage message appears
-// on the same line. The parenthetical default is omitted if the
-// default is the zero value for the type. The listed type, here int,
-// can be changed by placing a back-quoted name in the flag's usage
-// string; the first such item in the message is taken to be a parameter
-// name to show in the message and the back quotes are stripped from
-// the message when displayed. For instance, given
-//
-// flag.String("I", "", "search `directory` for include files")
-//
-// the output will be
-//
-// -I directory
-// search directory for include files.
-//
-// To change the destination for flag messages, call CommandLine.SetOutput.
-func PrintDefaults() {
- CommandLine.PrintDefaults()
-}
-
-// defaultUsage is the default function to print a usage message.
-func (f *FlagSet) defaultUsage() {
- if f.name == "" {
- fmt.Fprintf(f.Output(), "Usage:\n")
- } else {
- fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)
- }
- f.PrintDefaults()
-}
-
-// NOTE: Usage is not just defaultUsage(CommandLine)
-// because it serves (via godoc flag Usage) as the example
-// for how to write your own usage function.
-
-// Usage prints a usage message documenting all defined command-line flags
-// to CommandLine's output, which by default is os.Stderr.
-// It is called when an error occurs while parsing flags.
-// The function is a variable that may be changed to point to a custom function.
-// By default it prints a simple header and calls PrintDefaults; for details about the
-// format of the output and how to control it, see the documentation for PrintDefaults.
-// Custom usage functions may choose to exit the program; by default exiting
-// happens anyway as the command line's error handling strategy is set to
-// ExitOnError.
-var Usage = func() {
- fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0])
- PrintDefaults()
-}
-
-// NFlag returns the number of flags that have been set.
-func (f *FlagSet) NFlag() int { return len(f.actual) }
-
-// NFlag returns the number of command-line flags that have been set.
-func NFlag() int { return len(CommandLine.actual) }
-
-// Arg returns the i'th argument. Arg(0) is the first remaining argument
-// after flags have been processed. Arg returns an empty string if the
-// requested element does not exist.
-func (f *FlagSet) Arg(i int) string {
- if i < 0 || i >= len(f.args) {
- return ""
- }
- return f.args[i]
-}
-
-// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
-// after flags have been processed. Arg returns an empty string if the
-// requested element does not exist.
-func Arg(i int) string {
- return CommandLine.Arg(i)
-}
-
-// NArg is the number of arguments remaining after flags have been processed.
-func (f *FlagSet) NArg() int { return len(f.args) }
-
-// NArg is the number of arguments remaining after flags have been processed.
-func NArg() int { return len(CommandLine.args) }
-
-// Args returns the non-flag arguments.
-func (f *FlagSet) Args() []string { return f.args }
-
-// Args returns the non-flag command-line arguments.
-func Args() []string { return CommandLine.args }
-
-// BoolVar defines a bool flag with specified name, default value, and usage string.
-// The argument p points to a bool variable in which to store the value of the flag.
-func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
- f.Var(newBoolValue(value, p), name, usage)
-}
-
-// BoolVar defines a bool flag with specified name, default value, and usage string.
-// The argument p points to a bool variable in which to store the value of the flag.
-func BoolVar(p *bool, name string, value bool, usage string) {
- CommandLine.Var(newBoolValue(value, p), name, usage)
-}
-
-// Bool defines a bool flag with specified name, default value, and usage string.
-// The return value is the address of a bool variable that stores the value of the flag.
-func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
- p := new(bool)
- f.BoolVar(p, name, value, usage)
- return p
-}
-
-// Bool defines a bool flag with specified name, default value, and usage string.
-// The return value is the address of a bool variable that stores the value of the flag.
-func Bool(name string, value bool, usage string) *bool {
- return CommandLine.Bool(name, value, usage)
-}
-
-// IntVar defines an int flag with specified name, default value, and usage string.
-// The argument p points to an int variable in which to store the value of the flag.
-func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
- f.Var(newIntValue(value, p), name, usage)
-}
-
-// IntVar defines an int flag with specified name, default value, and usage string.
-// The argument p points to an int variable in which to store the value of the flag.
-func IntVar(p *int, name string, value int, usage string) {
- CommandLine.Var(newIntValue(value, p), name, usage)
-}
-
-// Int defines an int flag with specified name, default value, and usage string.
-// The return value is the address of an int variable that stores the value of the flag.
-func (f *FlagSet) Int(name string, value int, usage string) *int {
- p := new(int)
- f.IntVar(p, name, value, usage)
- return p
-}
-
-// Int defines an int flag with specified name, default value, and usage string.
-// The return value is the address of an int variable that stores the value of the flag.
-func Int(name string, value int, usage string) *int {
- return CommandLine.Int(name, value, usage)
-}
-
-// Int64Var defines an int64 flag with specified name, default value, and usage string.
-// The argument p points to an int64 variable in which to store the value of the flag.
-func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
- f.Var(newInt64Value(value, p), name, usage)
-}
-
-// Int64Var defines an int64 flag with specified name, default value, and usage string.
-// The argument p points to an int64 variable in which to store the value of the flag.
-func Int64Var(p *int64, name string, value int64, usage string) {
- CommandLine.Var(newInt64Value(value, p), name, usage)
-}
-
-// Int64 defines an int64 flag with specified name, default value, and usage string.
-// The return value is the address of an int64 variable that stores the value of the flag.
-func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
- p := new(int64)
- f.Int64Var(p, name, value, usage)
- return p
-}
-
-// Int64 defines an int64 flag with specified name, default value, and usage string.
-// The return value is the address of an int64 variable that stores the value of the flag.
-func Int64(name string, value int64, usage string) *int64 {
- return CommandLine.Int64(name, value, usage)
-}
-
-// UintVar defines a uint flag with specified name, default value, and usage string.
-// The argument p points to a uint variable in which to store the value of the flag.
-func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
- f.Var(newUintValue(value, p), name, usage)
-}
-
-// UintVar defines a uint flag with specified name, default value, and usage string.
-// The argument p points to a uint variable in which to store the value of the flag.
-func UintVar(p *uint, name string, value uint, usage string) {
- CommandLine.Var(newUintValue(value, p), name, usage)
-}
-
-// Uint defines a uint flag with specified name, default value, and usage string.
-// The return value is the address of a uint variable that stores the value of the flag.
-func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
- p := new(uint)
- f.UintVar(p, name, value, usage)
- return p
-}
-
-// Uint defines a uint flag with specified name, default value, and usage string.
-// The return value is the address of a uint variable that stores the value of the flag.
-func Uint(name string, value uint, usage string) *uint {
- return CommandLine.Uint(name, value, usage)
-}
-
-// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
-// The argument p points to a uint64 variable in which to store the value of the flag.
-func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
- f.Var(newUint64Value(value, p), name, usage)
-}
-
-// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
-// The argument p points to a uint64 variable in which to store the value of the flag.
-func Uint64Var(p *uint64, name string, value uint64, usage string) {
- CommandLine.Var(newUint64Value(value, p), name, usage)
-}
-
-// Uint64 defines a uint64 flag with specified name, default value, and usage string.
-// The return value is the address of a uint64 variable that stores the value of the flag.
-func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
- p := new(uint64)
- f.Uint64Var(p, name, value, usage)
- return p
-}
-
-// Uint64 defines a uint64 flag with specified name, default value, and usage string.
-// The return value is the address of a uint64 variable that stores the value of the flag.
-func Uint64(name string, value uint64, usage string) *uint64 {
- return CommandLine.Uint64(name, value, usage)
-}
-
-// StringVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a string variable in which to store the value of the flag.
-func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
- f.Var(newStringValue(value, p), name, usage)
-}
-
-// StringVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a string variable in which to store the value of the flag.
-func StringVar(p *string, name string, value string, usage string) {
- CommandLine.Var(newStringValue(value, p), name, usage)
-}
-
-// String defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a string variable that stores the value of the flag.
-func (f *FlagSet) String(name string, value string, usage string) *string {
- p := new(string)
- f.StringVar(p, name, value, usage)
- return p
-}
-
-// String defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a string variable that stores the value of the flag.
-func String(name string, value string, usage string) *string {
- return CommandLine.String(name, value, usage)
-}
-
-// Float64Var defines a float64 flag with specified name, default value, and usage string.
-// The argument p points to a float64 variable in which to store the value of the flag.
-func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
- f.Var(newFloat64Value(value, p), name, usage)
-}
-
-// Float64Var defines a float64 flag with specified name, default value, and usage string.
-// The argument p points to a float64 variable in which to store the value of the flag.
-func Float64Var(p *float64, name string, value float64, usage string) {
- CommandLine.Var(newFloat64Value(value, p), name, usage)
-}
-
-// Float64 defines a float64 flag with specified name, default value, and usage string.
-// The return value is the address of a float64 variable that stores the value of the flag.
-func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
- p := new(float64)
- f.Float64Var(p, name, value, usage)
- return p
-}
-
-// Float64 defines a float64 flag with specified name, default value, and usage string.
-// The return value is the address of a float64 variable that stores the value of the flag.
-func Float64(name string, value float64, usage string) *float64 {
- return CommandLine.Float64(name, value, usage)
-}
-
-// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
-// The argument p points to a time.Duration variable in which to store the value of the flag.
-// The flag accepts a value acceptable to time.ParseDuration.
-func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
- f.Var(newDurationValue(value, p), name, usage)
-}
-
-// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
-// The argument p points to a time.Duration variable in which to store the value of the flag.
-// The flag accepts a value acceptable to time.ParseDuration.
-func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
- CommandLine.Var(newDurationValue(value, p), name, usage)
-}
-
-// Duration defines a time.Duration flag with specified name, default value, and usage string.
-// The return value is the address of a time.Duration variable that stores the value of the flag.
-// The flag accepts a value acceptable to time.ParseDuration.
-func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
- p := new(time.Duration)
- f.DurationVar(p, name, value, usage)
- return p
-}
-
-// Duration defines a time.Duration flag with specified name, default value, and usage string.
-// The return value is the address of a time.Duration variable that stores the value of the flag.
-// The flag accepts a value acceptable to time.ParseDuration.
-func Duration(name string, value time.Duration, usage string) *time.Duration {
- return CommandLine.Duration(name, value, usage)
-}
-
-// TextVar defines a flag with a specified name, default value, and usage string.
-// The argument p must be a pointer to a variable that will hold the value
-// of the flag, and p must implement encoding.TextUnmarshaler.
-// If the flag is used, the flag value will be passed to p's UnmarshalText method.
-// The type of the default value must be the same as the type of p.
-func (f *FlagSet) TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) {
- f.Var(newTextValue(value, p), name, usage)
-}
-
-// TextVar defines a flag with a specified name, default value, and usage string.
-// The argument p must be a pointer to a variable that will hold the value
-// of the flag, and p must implement encoding.TextUnmarshaler.
-// If the flag is used, the flag value will be passed to p's UnmarshalText method.
-// The type of the default value must be the same as the type of p.
-func TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) {
- CommandLine.Var(newTextValue(value, p), name, usage)
-}
-
-// Func defines a flag with the specified name and usage string.
-// Each time the flag is seen, fn is called with the value of the flag.
-// If fn returns a non-nil error, it will be treated as a flag value parsing error.
-func (f *FlagSet) Func(name, usage string, fn func(string) error) {
- f.Var(funcValue(fn), name, usage)
-}
-
-// Func defines a flag with the specified name and usage string.
-// Each time the flag is seen, fn is called with the value of the flag.
-// If fn returns a non-nil error, it will be treated as a flag value parsing error.
-func Func(name, usage string, fn func(string) error) {
- CommandLine.Func(name, usage, fn)
-}
-
-// Var defines a flag with the specified name and usage string. The type and
-// value of the flag are represented by the first argument, of type Value, which
-// typically holds a user-defined implementation of Value. For instance, the
-// caller could create a flag that turns a comma-separated string into a slice
-// of strings by giving the slice the methods of Value; in particular, Set would
-// decompose the comma-separated string into the slice.
-func (f *FlagSet) Var(value Value, name string, usage string) {
- // Flag must not begin "-" or contain "=".
- if strings.HasPrefix(name, "-") {
- panic(f.sprintf("flag %q begins with -", name))
- } else if strings.Contains(name, "=") {
- panic(f.sprintf("flag %q contains =", name))
- }
-
- // Remember the default value as a string; it won't change.
- flag := &Flag{name, usage, value, value.String()}
- _, alreadythere := f.formal[name]
- if alreadythere {
- var msg string
- if f.name == "" {
- msg = f.sprintf("flag redefined: %s", name)
- } else {
- msg = f.sprintf("%s flag redefined: %s", f.name, name)
- }
- panic(msg) // Happens only if flags are declared with identical names
- }
- if f.formal == nil {
- f.formal = make(map[string]*Flag)
- }
- f.formal[name] = flag
-}
-
-// Var defines a flag with the specified name and usage string. The type and
-// value of the flag are represented by the first argument, of type Value, which
-// typically holds a user-defined implementation of Value. For instance, the
-// caller could create a flag that turns a comma-separated string into a slice
-// of strings by giving the slice the methods of Value; in particular, Set would
-// decompose the comma-separated string into the slice.
-func Var(value Value, name string, usage string) {
- CommandLine.Var(value, name, usage)
-}
-
-// sprintf formats the message, prints it to output, and returns it.
-func (f *FlagSet) sprintf(format string, a ...any) string {
- msg := fmt.Sprintf(format, a...)
- fmt.Fprintln(f.Output(), msg)
- return msg
-}
-
-// failf prints to standard error a formatted error and usage message and
-// returns the error.
-func (f *FlagSet) failf(format string, a ...any) error {
- msg := f.sprintf(format, a...)
- f.usage()
- return errors.New(msg)
-}
-
-// usage calls the Usage method for the flag set if one is specified,
-// or the appropriate default usage function otherwise.
-func (f *FlagSet) usage() {
- if f.Usage == nil {
- f.defaultUsage()
- } else {
- f.Usage()
- }
-}
-
-// parseOne parses one flag. It reports whether a flag was seen.
-func (f *FlagSet) parseOne() (bool, error) {
- if len(f.args) == 0 {
- return false, nil
- }
- s := f.args[0]
- if len(s) < 2 || s[0] != '-' {
- return false, nil
- }
- numMinuses := 1
- if s[1] == '-' {
- numMinuses++
- if len(s) == 2 { // "--" terminates the flags
- f.args = f.args[1:]
- return false, nil
- }
- }
- name := s[numMinuses:]
- if len(name) == 0 || name[0] == '-' || name[0] == '=' {
- return false, f.failf("bad flag syntax: %s", s)
- }
-
- // it's a flag. does it have an argument?
- f.args = f.args[1:]
- hasValue := false
- value := ""
- for i := 1; i < len(name); i++ { // equals cannot be first
- if name[i] == '=' {
- value = name[i+1:]
- hasValue = true
- name = name[0:i]
- break
- }
- }
-
- flag, ok := f.formal[name]
- if !ok {
- if name == "help" || name == "h" { // special case for nice help message.
- f.usage()
- return false, ErrHelp
- }
- return false, f.failf("flag provided but not defined: -%s", name)
- }
-
- if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
- if hasValue {
- if err := fv.Set(value); err != nil {
- return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
- }
- } else {
- if err := fv.Set("true"); err != nil {
- return false, f.failf("invalid boolean flag %s: %v", name, err)
- }
- }
- } else {
- // It must have a value, which might be the next argument.
- if !hasValue && len(f.args) > 0 {
- // value is the next arg
- hasValue = true
- value, f.args = f.args[0], f.args[1:]
- }
- if !hasValue {
- return false, f.failf("flag needs an argument: -%s", name)
- }
- if err := flag.Value.Set(value); err != nil {
- return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
- }
- }
- if f.actual == nil {
- f.actual = make(map[string]*Flag)
- }
- f.actual[name] = flag
- return true, nil
-}
-
-// Parse parses flag definitions from the argument list, which should not
-// include the command name. Must be called after all flags in the FlagSet
-// are defined and before flags are accessed by the program.
-// The return value will be ErrHelp if -help or -h were set but not defined.
-func (f *FlagSet) Parse(arguments []string) error {
- f.parsed = true
- f.args = arguments
- for {
- seen, err := f.parseOne()
- if seen {
- continue
- }
- if err == nil {
- break
- }
- switch f.errorHandling {
- case ContinueOnError:
- return err
- case ExitOnError:
- if err == ErrHelp {
- os.Exit(0)
- }
- os.Exit(2)
- case PanicOnError:
- panic(err)
- }
- }
- return nil
-}
-
-// Parsed reports whether f.Parse has been called.
-func (f *FlagSet) Parsed() bool {
- return f.parsed
-}
-
-// Parse parses the command-line flags from os.Args[1:]. Must be called
-// after all flags are defined and before flags are accessed by the program.
-func Parse() {
- // Ignore errors; CommandLine is set for ExitOnError.
- CommandLine.Parse(os.Args[1:])
-}
-
-// Parsed reports whether the command-line flags have been parsed.
-func Parsed() bool {
- return CommandLine.Parsed()
-}
-
-// CommandLine is the default set of command-line flags, parsed from os.Args.
-// The top-level functions such as BoolVar, Arg, and so on are wrappers for the
-// methods of CommandLine.
-var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
-
-func init() {
- // Override generic FlagSet default Usage with call to global Usage.
- // Note: This is not CommandLine.Usage = Usage,
- // because we want any eventual call to use any updated value of Usage,
- // not the value it has when this line is run.
- CommandLine.Usage = commandLineUsage
-}
-
-func commandLineUsage() {
- Usage()
-}
-
-// NewFlagSet returns a new, empty flag set with the specified name and
-// error handling property. If the name is not empty, it will be printed
-// in the default usage message and in error messages.
-func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
- f := &FlagSet{
- name: name,
- errorHandling: errorHandling,
- }
- f.Usage = f.defaultUsage
- return f
-}
-
-// Init sets the name and error handling property for a flag set.
-// By default, the zero FlagSet uses an empty name and the
-// ContinueOnError error handling policy.
-func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
- f.name = name
- f.errorHandling = errorHandling
-}
diff --git a/contrib/go/_std_1.20/src/flag/ya.make b/contrib/go/_std_1.20/src/flag/ya.make
deleted file mode 100644
index 89b54d2c4e..0000000000
--- a/contrib/go/_std_1.20/src/flag/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- flag.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/fmt/print.go b/contrib/go/_std_1.20/src/fmt/print.go
deleted file mode 100644
index b3dd43ce04..0000000000
--- a/contrib/go/_std_1.20/src/fmt/print.go
+++ /dev/null
@@ -1,1226 +0,0 @@
-// Copyright 2009 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 fmt
-
-import (
- "internal/fmtsort"
- "io"
- "os"
- "reflect"
- "strconv"
- "sync"
- "unicode/utf8"
-)
-
-// Strings for use with buffer.WriteString.
-// This is less overhead than using buffer.Write with byte arrays.
-const (
- commaSpaceString = ", "
- nilAngleString = "<nil>"
- nilParenString = "(nil)"
- nilString = "nil"
- mapString = "map["
- percentBangString = "%!"
- missingString = "(MISSING)"
- badIndexString = "(BADINDEX)"
- panicString = "(PANIC="
- extraString = "%!(EXTRA "
- badWidthString = "%!(BADWIDTH)"
- badPrecString = "%!(BADPREC)"
- noVerbString = "%!(NOVERB)"
- invReflectString = "<invalid reflect.Value>"
-)
-
-// State represents the printer state passed to custom formatters.
-// It provides access to the io.Writer interface plus information about
-// the flags and options for the operand's format specifier.
-type State interface {
- // Write is the function to call to emit formatted output to be printed.
- Write(b []byte) (n int, err error)
- // Width returns the value of the width option and whether it has been set.
- Width() (wid int, ok bool)
- // Precision returns the value of the precision option and whether it has been set.
- Precision() (prec int, ok bool)
-
- // Flag reports whether the flag c, a character, has been set.
- Flag(c int) bool
-}
-
-// Formatter is implemented by any value that has a Format method.
-// The implementation controls how State and rune are interpreted,
-// and may call Sprint(f) or Fprint(f) etc. to generate its output.
-type Formatter interface {
- Format(f State, verb rune)
-}
-
-// Stringer is implemented by any value that has a String method,
-// which defines the “native” format for that value.
-// The String method is used to print values passed as an operand
-// to any format that accepts a string or to an unformatted printer
-// such as Print.
-type Stringer interface {
- String() string
-}
-
-// GoStringer is implemented by any value that has a GoString method,
-// which defines the Go syntax for that value.
-// The GoString method is used to print values passed as an operand
-// to a %#v format.
-type GoStringer interface {
- GoString() string
-}
-
-// FormatString returns a string representing the fully qualified formatting
-// directive captured by the State, followed by the argument verb. (State does not
-// itself contain the verb.) The result has a leading percent sign followed by any
-// flags, the width, and the precision. Missing flags, width, and precision are
-// omitted. This function allows a Formatter to reconstruct the original
-// directive triggering the call to Format.
-func FormatString(state State, verb rune) string {
- var tmp [16]byte // Use a local buffer.
- b := append(tmp[:0], '%')
- for _, c := range " +-#0" { // All known flags
- if state.Flag(int(c)) { // The argument is an int for historical reasons.
- b = append(b, byte(c))
- }
- }
- if w, ok := state.Width(); ok {
- b = strconv.AppendInt(b, int64(w), 10)
- }
- if p, ok := state.Precision(); ok {
- b = append(b, '.')
- b = strconv.AppendInt(b, int64(p), 10)
- }
- b = utf8.AppendRune(b, verb)
- return string(b)
-}
-
-// Use simple []byte instead of bytes.Buffer to avoid large dependency.
-type buffer []byte
-
-func (b *buffer) write(p []byte) {
- *b = append(*b, p...)
-}
-
-func (b *buffer) writeString(s string) {
- *b = append(*b, s...)
-}
-
-func (b *buffer) writeByte(c byte) {
- *b = append(*b, c)
-}
-
-func (bp *buffer) writeRune(r rune) {
- *bp = utf8.AppendRune(*bp, r)
-}
-
-// pp is used to store a printer's state and is reused with sync.Pool to avoid allocations.
-type pp struct {
- buf buffer
-
- // arg holds the current item, as an interface{}.
- arg any
-
- // value is used instead of arg for reflect values.
- value reflect.Value
-
- // fmt is used to format basic items such as integers or strings.
- fmt fmt
-
- // reordered records whether the format string used argument reordering.
- reordered bool
- // goodArgNum records whether the most recent reordering directive was valid.
- goodArgNum bool
- // panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion.
- panicking bool
- // erroring is set when printing an error string to guard against calling handleMethods.
- erroring bool
- // wrapErrs is set when the format string may contain a %w verb.
- wrapErrs bool
- // wrappedErrs records the targets of the %w verb.
- wrappedErrs []int
-}
-
-var ppFree = sync.Pool{
- New: func() any { return new(pp) },
-}
-
-// newPrinter allocates a new pp struct or grabs a cached one.
-func newPrinter() *pp {
- p := ppFree.Get().(*pp)
- p.panicking = false
- p.erroring = false
- p.wrapErrs = false
- p.fmt.init(&p.buf)
- return p
-}
-
-// free saves used pp structs in ppFree; avoids an allocation per invocation.
-func (p *pp) free() {
- // Proper usage of a sync.Pool requires each entry to have approximately
- // the same memory cost. To obtain this property when the stored type
- // contains a variably-sized buffer, we add a hard limit on the maximum
- // buffer to place back in the pool. If the buffer is larger than the
- // limit, we drop the buffer and recycle just the printer.
- //
- // See https://golang.org/issue/23199.
- if cap(p.buf) > 64*1024 {
- p.buf = nil
- } else {
- p.buf = p.buf[:0]
- }
- if cap(p.wrappedErrs) > 8 {
- p.wrappedErrs = nil
- }
-
- p.arg = nil
- p.value = reflect.Value{}
- p.wrappedErrs = p.wrappedErrs[:0]
- ppFree.Put(p)
-}
-
-func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
-
-func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
-
-func (p *pp) Flag(b int) bool {
- switch b {
- case '-':
- return p.fmt.minus
- case '+':
- return p.fmt.plus || p.fmt.plusV
- case '#':
- return p.fmt.sharp || p.fmt.sharpV
- case ' ':
- return p.fmt.space
- case '0':
- return p.fmt.zero
- }
- return false
-}
-
-// Implement Write so we can call Fprintf on a pp (through State), for
-// recursive use in custom verbs.
-func (p *pp) Write(b []byte) (ret int, err error) {
- p.buf.write(b)
- return len(b), nil
-}
-
-// Implement WriteString so that we can call io.WriteString
-// on a pp (through state), for efficiency.
-func (p *pp) WriteString(s string) (ret int, err error) {
- p.buf.writeString(s)
- return len(s), nil
-}
-
-// These routines end in 'f' and take a format string.
-
-// Fprintf formats according to a format specifier and writes to w.
-// It returns the number of bytes written and any write error encountered.
-func Fprintf(w io.Writer, format string, a ...any) (n int, err error) {
- p := newPrinter()
- p.doPrintf(format, a)
- n, err = w.Write(p.buf)
- p.free()
- return
-}
-
-// Printf formats according to a format specifier and writes to standard output.
-// It returns the number of bytes written and any write error encountered.
-func Printf(format string, a ...any) (n int, err error) {
- return Fprintf(os.Stdout, format, a...)
-}
-
-// Sprintf formats according to a format specifier and returns the resulting string.
-func Sprintf(format string, a ...any) string {
- p := newPrinter()
- p.doPrintf(format, a)
- s := string(p.buf)
- p.free()
- return s
-}
-
-// Appendf formats according to a format specifier, appends the result to the byte
-// slice, and returns the updated slice.
-func Appendf(b []byte, format string, a ...any) []byte {
- p := newPrinter()
- p.doPrintf(format, a)
- b = append(b, p.buf...)
- p.free()
- return b
-}
-
-// These routines do not take a format string
-
-// Fprint formats using the default formats for its operands and writes to w.
-// Spaces are added between operands when neither is a string.
-// It returns the number of bytes written and any write error encountered.
-func Fprint(w io.Writer, a ...any) (n int, err error) {
- p := newPrinter()
- p.doPrint(a)
- n, err = w.Write(p.buf)
- p.free()
- return
-}
-
-// Print formats using the default formats for its operands and writes to standard output.
-// Spaces are added between operands when neither is a string.
-// It returns the number of bytes written and any write error encountered.
-func Print(a ...any) (n int, err error) {
- return Fprint(os.Stdout, a...)
-}
-
-// Sprint formats using the default formats for its operands and returns the resulting string.
-// Spaces are added between operands when neither is a string.
-func Sprint(a ...any) string {
- p := newPrinter()
- p.doPrint(a)
- s := string(p.buf)
- p.free()
- return s
-}
-
-// Append formats using the default formats for its operands, appends the result to
-// the byte slice, and returns the updated slice.
-func Append(b []byte, a ...any) []byte {
- p := newPrinter()
- p.doPrint(a)
- b = append(b, p.buf...)
- p.free()
- return b
-}
-
-// These routines end in 'ln', do not take a format string,
-// always add spaces between operands, and add a newline
-// after the last operand.
-
-// Fprintln formats using the default formats for its operands and writes to w.
-// Spaces are always added between operands and a newline is appended.
-// It returns the number of bytes written and any write error encountered.
-func Fprintln(w io.Writer, a ...any) (n int, err error) {
- p := newPrinter()
- p.doPrintln(a)
- n, err = w.Write(p.buf)
- p.free()
- return
-}
-
-// Println formats using the default formats for its operands and writes to standard output.
-// Spaces are always added between operands and a newline is appended.
-// It returns the number of bytes written and any write error encountered.
-func Println(a ...any) (n int, err error) {
- return Fprintln(os.Stdout, a...)
-}
-
-// Sprintln formats using the default formats for its operands and returns the resulting string.
-// Spaces are always added between operands and a newline is appended.
-func Sprintln(a ...any) string {
- p := newPrinter()
- p.doPrintln(a)
- s := string(p.buf)
- p.free()
- return s
-}
-
-// Appendln formats using the default formats for its operands, appends the result
-// to the byte slice, and returns the updated slice. Spaces are always added
-// between operands and a newline is appended.
-func Appendln(b []byte, a ...any) []byte {
- p := newPrinter()
- p.doPrintln(a)
- b = append(b, p.buf...)
- p.free()
- return b
-}
-
-// getField gets the i'th field of the struct value.
-// If the field is itself is an interface, return a value for
-// the thing inside the interface, not the interface itself.
-func getField(v reflect.Value, i int) reflect.Value {
- val := v.Field(i)
- if val.Kind() == reflect.Interface && !val.IsNil() {
- val = val.Elem()
- }
- return val
-}
-
-// tooLarge reports whether the magnitude of the integer is
-// too large to be used as a formatting width or precision.
-func tooLarge(x int) bool {
- const max int = 1e6
- return x > max || x < -max
-}
-
-// parsenum converts ASCII to integer. num is 0 (and isnum is false) if no number present.
-func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
- if start >= end {
- return 0, false, end
- }
- for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
- if tooLarge(num) {
- return 0, false, end // Overflow; crazy long number most likely.
- }
- num = num*10 + int(s[newi]-'0')
- isnum = true
- }
- return
-}
-
-func (p *pp) unknownType(v reflect.Value) {
- if !v.IsValid() {
- p.buf.writeString(nilAngleString)
- return
- }
- p.buf.writeByte('?')
- p.buf.writeString(v.Type().String())
- p.buf.writeByte('?')
-}
-
-func (p *pp) badVerb(verb rune) {
- p.erroring = true
- p.buf.writeString(percentBangString)
- p.buf.writeRune(verb)
- p.buf.writeByte('(')
- switch {
- case p.arg != nil:
- p.buf.writeString(reflect.TypeOf(p.arg).String())
- p.buf.writeByte('=')
- p.printArg(p.arg, 'v')
- case p.value.IsValid():
- p.buf.writeString(p.value.Type().String())
- p.buf.writeByte('=')
- p.printValue(p.value, 'v', 0)
- default:
- p.buf.writeString(nilAngleString)
- }
- p.buf.writeByte(')')
- p.erroring = false
-}
-
-func (p *pp) fmtBool(v bool, verb rune) {
- switch verb {
- case 't', 'v':
- p.fmt.fmtBoolean(v)
- default:
- p.badVerb(verb)
- }
-}
-
-// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
-// not, as requested, by temporarily setting the sharp flag.
-func (p *pp) fmt0x64(v uint64, leading0x bool) {
- sharp := p.fmt.sharp
- p.fmt.sharp = leading0x
- p.fmt.fmtInteger(v, 16, unsigned, 'v', ldigits)
- p.fmt.sharp = sharp
-}
-
-// fmtInteger formats a signed or unsigned integer.
-func (p *pp) fmtInteger(v uint64, isSigned bool, verb rune) {
- switch verb {
- case 'v':
- if p.fmt.sharpV && !isSigned {
- p.fmt0x64(v, true)
- } else {
- p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
- }
- case 'd':
- p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
- case 'b':
- p.fmt.fmtInteger(v, 2, isSigned, verb, ldigits)
- case 'o', 'O':
- p.fmt.fmtInteger(v, 8, isSigned, verb, ldigits)
- case 'x':
- p.fmt.fmtInteger(v, 16, isSigned, verb, ldigits)
- case 'X':
- p.fmt.fmtInteger(v, 16, isSigned, verb, udigits)
- case 'c':
- p.fmt.fmtC(v)
- case 'q':
- p.fmt.fmtQc(v)
- case 'U':
- p.fmt.fmtUnicode(v)
- default:
- p.badVerb(verb)
- }
-}
-
-// fmtFloat formats a float. The default precision for each verb
-// is specified as last argument in the call to fmt_float.
-func (p *pp) fmtFloat(v float64, size int, verb rune) {
- switch verb {
- case 'v':
- p.fmt.fmtFloat(v, size, 'g', -1)
- case 'b', 'g', 'G', 'x', 'X':
- p.fmt.fmtFloat(v, size, verb, -1)
- case 'f', 'e', 'E':
- p.fmt.fmtFloat(v, size, verb, 6)
- case 'F':
- p.fmt.fmtFloat(v, size, 'f', 6)
- default:
- p.badVerb(verb)
- }
-}
-
-// fmtComplex formats a complex number v with
-// r = real(v) and j = imag(v) as (r+ji) using
-// fmtFloat for r and j formatting.
-func (p *pp) fmtComplex(v complex128, size int, verb rune) {
- // Make sure any unsupported verbs are found before the
- // calls to fmtFloat to not generate an incorrect error string.
- switch verb {
- case 'v', 'b', 'g', 'G', 'x', 'X', 'f', 'F', 'e', 'E':
- oldPlus := p.fmt.plus
- p.buf.writeByte('(')
- p.fmtFloat(real(v), size/2, verb)
- // Imaginary part always has a sign.
- p.fmt.plus = true
- p.fmtFloat(imag(v), size/2, verb)
- p.buf.writeString("i)")
- p.fmt.plus = oldPlus
- default:
- p.badVerb(verb)
- }
-}
-
-func (p *pp) fmtString(v string, verb rune) {
- switch verb {
- case 'v':
- if p.fmt.sharpV {
- p.fmt.fmtQ(v)
- } else {
- p.fmt.fmtS(v)
- }
- case 's':
- p.fmt.fmtS(v)
- case 'x':
- p.fmt.fmtSx(v, ldigits)
- case 'X':
- p.fmt.fmtSx(v, udigits)
- case 'q':
- p.fmt.fmtQ(v)
- default:
- p.badVerb(verb)
- }
-}
-
-func (p *pp) fmtBytes(v []byte, verb rune, typeString string) {
- switch verb {
- case 'v', 'd':
- if p.fmt.sharpV {
- p.buf.writeString(typeString)
- if v == nil {
- p.buf.writeString(nilParenString)
- return
- }
- p.buf.writeByte('{')
- for i, c := range v {
- if i > 0 {
- p.buf.writeString(commaSpaceString)
- }
- p.fmt0x64(uint64(c), true)
- }
- p.buf.writeByte('}')
- } else {
- p.buf.writeByte('[')
- for i, c := range v {
- if i > 0 {
- p.buf.writeByte(' ')
- }
- p.fmt.fmtInteger(uint64(c), 10, unsigned, verb, ldigits)
- }
- p.buf.writeByte(']')
- }
- case 's':
- p.fmt.fmtBs(v)
- case 'x':
- p.fmt.fmtBx(v, ldigits)
- case 'X':
- p.fmt.fmtBx(v, udigits)
- case 'q':
- p.fmt.fmtQ(string(v))
- default:
- p.printValue(reflect.ValueOf(v), verb, 0)
- }
-}
-
-func (p *pp) fmtPointer(value reflect.Value, verb rune) {
- var u uintptr
- switch value.Kind() {
- case reflect.Chan, reflect.Func, reflect.Map, reflect.Pointer, reflect.Slice, reflect.UnsafePointer:
- u = value.Pointer()
- default:
- p.badVerb(verb)
- return
- }
-
- switch verb {
- case 'v':
- if p.fmt.sharpV {
- p.buf.writeByte('(')
- p.buf.writeString(value.Type().String())
- p.buf.writeString(")(")
- if u == 0 {
- p.buf.writeString(nilString)
- } else {
- p.fmt0x64(uint64(u), true)
- }
- p.buf.writeByte(')')
- } else {
- if u == 0 {
- p.fmt.padString(nilAngleString)
- } else {
- p.fmt0x64(uint64(u), !p.fmt.sharp)
- }
- }
- case 'p':
- p.fmt0x64(uint64(u), !p.fmt.sharp)
- case 'b', 'o', 'd', 'x', 'X':
- p.fmtInteger(uint64(u), unsigned, verb)
- default:
- p.badVerb(verb)
- }
-}
-
-func (p *pp) catchPanic(arg any, verb rune, method string) {
- if err := recover(); err != nil {
- // If it's a nil pointer, just say "<nil>". The likeliest causes are a
- // Stringer that fails to guard against nil or a nil pointer for a
- // value receiver, and in either case, "<nil>" is a nice result.
- if v := reflect.ValueOf(arg); v.Kind() == reflect.Pointer && v.IsNil() {
- p.buf.writeString(nilAngleString)
- return
- }
- // Otherwise print a concise panic message. Most of the time the panic
- // value will print itself nicely.
- if p.panicking {
- // Nested panics; the recursion in printArg cannot succeed.
- panic(err)
- }
-
- oldFlags := p.fmt.fmtFlags
- // For this output we want default behavior.
- p.fmt.clearflags()
-
- p.buf.writeString(percentBangString)
- p.buf.writeRune(verb)
- p.buf.writeString(panicString)
- p.buf.writeString(method)
- p.buf.writeString(" method: ")
- p.panicking = true
- p.printArg(err, 'v')
- p.panicking = false
- p.buf.writeByte(')')
-
- p.fmt.fmtFlags = oldFlags
- }
-}
-
-func (p *pp) handleMethods(verb rune) (handled bool) {
- if p.erroring {
- return
- }
- if verb == 'w' {
- // It is invalid to use %w other than with Errorf or with a non-error arg.
- _, ok := p.arg.(error)
- if !ok || !p.wrapErrs {
- p.badVerb(verb)
- return true
- }
- // If the arg is a Formatter, pass 'v' as the verb to it.
- verb = 'v'
- }
-
- // Is it a Formatter?
- if formatter, ok := p.arg.(Formatter); ok {
- handled = true
- defer p.catchPanic(p.arg, verb, "Format")
- formatter.Format(p, verb)
- return
- }
-
- // If we're doing Go syntax and the argument knows how to supply it, take care of it now.
- if p.fmt.sharpV {
- if stringer, ok := p.arg.(GoStringer); ok {
- handled = true
- defer p.catchPanic(p.arg, verb, "GoString")
- // Print the result of GoString unadorned.
- p.fmt.fmtS(stringer.GoString())
- return
- }
- } else {
- // If a string is acceptable according to the format, see if
- // the value satisfies one of the string-valued interfaces.
- // Println etc. set verb to %v, which is "stringable".
- switch verb {
- case 'v', 's', 'x', 'X', 'q':
- // Is it an error or Stringer?
- // The duplication in the bodies is necessary:
- // setting handled and deferring catchPanic
- // must happen before calling the method.
- switch v := p.arg.(type) {
- case error:
- handled = true
- defer p.catchPanic(p.arg, verb, "Error")
- p.fmtString(v.Error(), verb)
- return
-
- case Stringer:
- handled = true
- defer p.catchPanic(p.arg, verb, "String")
- p.fmtString(v.String(), verb)
- return
- }
- }
- }
- return false
-}
-
-func (p *pp) printArg(arg any, verb rune) {
- p.arg = arg
- p.value = reflect.Value{}
-
- if arg == nil {
- switch verb {
- case 'T', 'v':
- p.fmt.padString(nilAngleString)
- default:
- p.badVerb(verb)
- }
- return
- }
-
- // Special processing considerations.
- // %T (the value's type) and %p (its address) are special; we always do them first.
- switch verb {
- case 'T':
- p.fmt.fmtS(reflect.TypeOf(arg).String())
- return
- case 'p':
- p.fmtPointer(reflect.ValueOf(arg), 'p')
- return
- }
-
- // Some types can be done without reflection.
- switch f := arg.(type) {
- case bool:
- p.fmtBool(f, verb)
- case float32:
- p.fmtFloat(float64(f), 32, verb)
- case float64:
- p.fmtFloat(f, 64, verb)
- case complex64:
- p.fmtComplex(complex128(f), 64, verb)
- case complex128:
- p.fmtComplex(f, 128, verb)
- case int:
- p.fmtInteger(uint64(f), signed, verb)
- case int8:
- p.fmtInteger(uint64(f), signed, verb)
- case int16:
- p.fmtInteger(uint64(f), signed, verb)
- case int32:
- p.fmtInteger(uint64(f), signed, verb)
- case int64:
- p.fmtInteger(uint64(f), signed, verb)
- case uint:
- p.fmtInteger(uint64(f), unsigned, verb)
- case uint8:
- p.fmtInteger(uint64(f), unsigned, verb)
- case uint16:
- p.fmtInteger(uint64(f), unsigned, verb)
- case uint32:
- p.fmtInteger(uint64(f), unsigned, verb)
- case uint64:
- p.fmtInteger(f, unsigned, verb)
- case uintptr:
- p.fmtInteger(uint64(f), unsigned, verb)
- case string:
- p.fmtString(f, verb)
- case []byte:
- p.fmtBytes(f, verb, "[]byte")
- case reflect.Value:
- // Handle extractable values with special methods
- // since printValue does not handle them at depth 0.
- if f.IsValid() && f.CanInterface() {
- p.arg = f.Interface()
- if p.handleMethods(verb) {
- return
- }
- }
- p.printValue(f, verb, 0)
- default:
- // If the type is not simple, it might have methods.
- if !p.handleMethods(verb) {
- // Need to use reflection, since the type had no
- // interface methods that could be used for formatting.
- p.printValue(reflect.ValueOf(f), verb, 0)
- }
- }
-}
-
-// printValue is similar to printArg but starts with a reflect value, not an interface{} value.
-// It does not handle 'p' and 'T' verbs because these should have been already handled by printArg.
-func (p *pp) printValue(value reflect.Value, verb rune, depth int) {
- // Handle values with special methods if not already handled by printArg (depth == 0).
- if depth > 0 && value.IsValid() && value.CanInterface() {
- p.arg = value.Interface()
- if p.handleMethods(verb) {
- return
- }
- }
- p.arg = nil
- p.value = value
-
- switch f := value; value.Kind() {
- case reflect.Invalid:
- if depth == 0 {
- p.buf.writeString(invReflectString)
- } else {
- switch verb {
- case 'v':
- p.buf.writeString(nilAngleString)
- default:
- p.badVerb(verb)
- }
- }
- case reflect.Bool:
- p.fmtBool(f.Bool(), verb)
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- p.fmtInteger(uint64(f.Int()), signed, verb)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- p.fmtInteger(f.Uint(), unsigned, verb)
- case reflect.Float32:
- p.fmtFloat(f.Float(), 32, verb)
- case reflect.Float64:
- p.fmtFloat(f.Float(), 64, verb)
- case reflect.Complex64:
- p.fmtComplex(f.Complex(), 64, verb)
- case reflect.Complex128:
- p.fmtComplex(f.Complex(), 128, verb)
- case reflect.String:
- p.fmtString(f.String(), verb)
- case reflect.Map:
- if p.fmt.sharpV {
- p.buf.writeString(f.Type().String())
- if f.IsNil() {
- p.buf.writeString(nilParenString)
- return
- }
- p.buf.writeByte('{')
- } else {
- p.buf.writeString(mapString)
- }
- sorted := fmtsort.Sort(f)
- for i, key := range sorted.Key {
- if i > 0 {
- if p.fmt.sharpV {
- p.buf.writeString(commaSpaceString)
- } else {
- p.buf.writeByte(' ')
- }
- }
- p.printValue(key, verb, depth+1)
- p.buf.writeByte(':')
- p.printValue(sorted.Value[i], verb, depth+1)
- }
- if p.fmt.sharpV {
- p.buf.writeByte('}')
- } else {
- p.buf.writeByte(']')
- }
- case reflect.Struct:
- if p.fmt.sharpV {
- p.buf.writeString(f.Type().String())
- }
- p.buf.writeByte('{')
- for i := 0; i < f.NumField(); i++ {
- if i > 0 {
- if p.fmt.sharpV {
- p.buf.writeString(commaSpaceString)
- } else {
- p.buf.writeByte(' ')
- }
- }
- if p.fmt.plusV || p.fmt.sharpV {
- if name := f.Type().Field(i).Name; name != "" {
- p.buf.writeString(name)
- p.buf.writeByte(':')
- }
- }
- p.printValue(getField(f, i), verb, depth+1)
- }
- p.buf.writeByte('}')
- case reflect.Interface:
- value := f.Elem()
- if !value.IsValid() {
- if p.fmt.sharpV {
- p.buf.writeString(f.Type().String())
- p.buf.writeString(nilParenString)
- } else {
- p.buf.writeString(nilAngleString)
- }
- } else {
- p.printValue(value, verb, depth+1)
- }
- case reflect.Array, reflect.Slice:
- switch verb {
- case 's', 'q', 'x', 'X':
- // Handle byte and uint8 slices and arrays special for the above verbs.
- t := f.Type()
- if t.Elem().Kind() == reflect.Uint8 {
- var bytes []byte
- if f.Kind() == reflect.Slice {
- bytes = f.Bytes()
- } else if f.CanAddr() {
- bytes = f.Slice(0, f.Len()).Bytes()
- } else {
- // We have an array, but we cannot Slice() a non-addressable array,
- // so we build a slice by hand. This is a rare case but it would be nice
- // if reflection could help a little more.
- bytes = make([]byte, f.Len())
- for i := range bytes {
- bytes[i] = byte(f.Index(i).Uint())
- }
- }
- p.fmtBytes(bytes, verb, t.String())
- return
- }
- }
- if p.fmt.sharpV {
- p.buf.writeString(f.Type().String())
- if f.Kind() == reflect.Slice && f.IsNil() {
- p.buf.writeString(nilParenString)
- return
- }
- p.buf.writeByte('{')
- for i := 0; i < f.Len(); i++ {
- if i > 0 {
- p.buf.writeString(commaSpaceString)
- }
- p.printValue(f.Index(i), verb, depth+1)
- }
- p.buf.writeByte('}')
- } else {
- p.buf.writeByte('[')
- for i := 0; i < f.Len(); i++ {
- if i > 0 {
- p.buf.writeByte(' ')
- }
- p.printValue(f.Index(i), verb, depth+1)
- }
- p.buf.writeByte(']')
- }
- case reflect.Pointer:
- // pointer to array or slice or struct? ok at top level
- // but not embedded (avoid loops)
- if depth == 0 && f.Pointer() != 0 {
- switch a := f.Elem(); a.Kind() {
- case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map:
- p.buf.writeByte('&')
- p.printValue(a, verb, depth+1)
- return
- }
- }
- fallthrough
- case reflect.Chan, reflect.Func, reflect.UnsafePointer:
- p.fmtPointer(f, verb)
- default:
- p.unknownType(f)
- }
-}
-
-// intFromArg gets the argNumth element of a. On return, isInt reports whether the argument has integer type.
-func intFromArg(a []any, argNum int) (num int, isInt bool, newArgNum int) {
- newArgNum = argNum
- if argNum < len(a) {
- num, isInt = a[argNum].(int) // Almost always OK.
- if !isInt {
- // Work harder.
- switch v := reflect.ValueOf(a[argNum]); v.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- n := v.Int()
- if int64(int(n)) == n {
- num = int(n)
- isInt = true
- }
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- n := v.Uint()
- if int64(n) >= 0 && uint64(int(n)) == n {
- num = int(n)
- isInt = true
- }
- default:
- // Already 0, false.
- }
- }
- newArgNum = argNum + 1
- if tooLarge(num) {
- num = 0
- isInt = false
- }
- }
- return
-}
-
-// parseArgNumber returns the value of the bracketed number, minus 1
-// (explicit argument numbers are one-indexed but we want zero-indexed).
-// The opening bracket is known to be present at format[0].
-// The returned values are the index, the number of bytes to consume
-// up to the closing paren, if present, and whether the number parsed
-// ok. The bytes to consume will be 1 if no closing paren is present.
-func parseArgNumber(format string) (index int, wid int, ok bool) {
- // There must be at least 3 bytes: [n].
- if len(format) < 3 {
- return 0, 1, false
- }
-
- // Find closing bracket.
- for i := 1; i < len(format); i++ {
- if format[i] == ']' {
- width, ok, newi := parsenum(format, 1, i)
- if !ok || newi != i {
- return 0, i + 1, false
- }
- return width - 1, i + 1, true // arg numbers are one-indexed and skip paren.
- }
- }
- return 0, 1, false
-}
-
-// argNumber returns the next argument to evaluate, which is either the value of the passed-in
-// argNum or the value of the bracketed integer that begins format[i:]. It also returns
-// the new value of i, that is, the index of the next byte of the format to process.
-func (p *pp) argNumber(argNum int, format string, i int, numArgs int) (newArgNum, newi int, found bool) {
- if len(format) <= i || format[i] != '[' {
- return argNum, i, false
- }
- p.reordered = true
- index, wid, ok := parseArgNumber(format[i:])
- if ok && 0 <= index && index < numArgs {
- return index, i + wid, true
- }
- p.goodArgNum = false
- return argNum, i + wid, ok
-}
-
-func (p *pp) badArgNum(verb rune) {
- p.buf.writeString(percentBangString)
- p.buf.writeRune(verb)
- p.buf.writeString(badIndexString)
-}
-
-func (p *pp) missingArg(verb rune) {
- p.buf.writeString(percentBangString)
- p.buf.writeRune(verb)
- p.buf.writeString(missingString)
-}
-
-func (p *pp) doPrintf(format string, a []any) {
- end := len(format)
- argNum := 0 // we process one argument per non-trivial format
- afterIndex := false // previous item in format was an index like [3].
- p.reordered = false
-formatLoop:
- for i := 0; i < end; {
- p.goodArgNum = true
- lasti := i
- for i < end && format[i] != '%' {
- i++
- }
- if i > lasti {
- p.buf.writeString(format[lasti:i])
- }
- if i >= end {
- // done processing format string
- break
- }
-
- // Process one verb
- i++
-
- // Do we have flags?
- p.fmt.clearflags()
- simpleFormat:
- for ; i < end; i++ {
- c := format[i]
- switch c {
- case '#':
- p.fmt.sharp = true
- case '0':
- p.fmt.zero = !p.fmt.minus // Only allow zero padding to the left.
- case '+':
- p.fmt.plus = true
- case '-':
- p.fmt.minus = true
- p.fmt.zero = false // Do not pad with zeros to the right.
- case ' ':
- p.fmt.space = true
- default:
- // Fast path for common case of ascii lower case simple verbs
- // without precision or width or argument indices.
- if 'a' <= c && c <= 'z' && argNum < len(a) {
- switch c {
- case 'w':
- p.wrappedErrs = append(p.wrappedErrs, argNum)
- fallthrough
- case 'v':
- // Go syntax
- p.fmt.sharpV = p.fmt.sharp
- p.fmt.sharp = false
- // Struct-field syntax
- p.fmt.plusV = p.fmt.plus
- p.fmt.plus = false
- }
- p.printArg(a[argNum], rune(c))
- argNum++
- i++
- continue formatLoop
- }
- // Format is more complex than simple flags and a verb or is malformed.
- break simpleFormat
- }
- }
-
- // Do we have an explicit argument index?
- argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
-
- // Do we have width?
- if i < end && format[i] == '*' {
- i++
- p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum)
-
- if !p.fmt.widPresent {
- p.buf.writeString(badWidthString)
- }
-
- // We have a negative width, so take its value and ensure
- // that the minus flag is set
- if p.fmt.wid < 0 {
- p.fmt.wid = -p.fmt.wid
- p.fmt.minus = true
- p.fmt.zero = false // Do not pad with zeros to the right.
- }
- afterIndex = false
- } else {
- p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
- if afterIndex && p.fmt.widPresent { // "%[3]2d"
- p.goodArgNum = false
- }
- }
-
- // Do we have precision?
- if i+1 < end && format[i] == '.' {
- i++
- if afterIndex { // "%[3].2d"
- p.goodArgNum = false
- }
- argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
- if i < end && format[i] == '*' {
- i++
- p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum)
- // Negative precision arguments don't make sense
- if p.fmt.prec < 0 {
- p.fmt.prec = 0
- p.fmt.precPresent = false
- }
- if !p.fmt.precPresent {
- p.buf.writeString(badPrecString)
- }
- afterIndex = false
- } else {
- p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i, end)
- if !p.fmt.precPresent {
- p.fmt.prec = 0
- p.fmt.precPresent = true
- }
- }
- }
-
- if !afterIndex {
- argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
- }
-
- if i >= end {
- p.buf.writeString(noVerbString)
- break
- }
-
- verb, size := rune(format[i]), 1
- if verb >= utf8.RuneSelf {
- verb, size = utf8.DecodeRuneInString(format[i:])
- }
- i += size
-
- switch {
- case verb == '%': // Percent does not absorb operands and ignores f.wid and f.prec.
- p.buf.writeByte('%')
- case !p.goodArgNum:
- p.badArgNum(verb)
- case argNum >= len(a): // No argument left over to print for the current verb.
- p.missingArg(verb)
- case verb == 'w':
- p.wrappedErrs = append(p.wrappedErrs, argNum)
- fallthrough
- case verb == 'v':
- // Go syntax
- p.fmt.sharpV = p.fmt.sharp
- p.fmt.sharp = false
- // Struct-field syntax
- p.fmt.plusV = p.fmt.plus
- p.fmt.plus = false
- fallthrough
- default:
- p.printArg(a[argNum], verb)
- argNum++
- }
- }
-
- // Check for extra arguments unless the call accessed the arguments
- // out of order, in which case it's too expensive to detect if they've all
- // been used and arguably OK if they're not.
- if !p.reordered && argNum < len(a) {
- p.fmt.clearflags()
- p.buf.writeString(extraString)
- for i, arg := range a[argNum:] {
- if i > 0 {
- p.buf.writeString(commaSpaceString)
- }
- if arg == nil {
- p.buf.writeString(nilAngleString)
- } else {
- p.buf.writeString(reflect.TypeOf(arg).String())
- p.buf.writeByte('=')
- p.printArg(arg, 'v')
- }
- }
- p.buf.writeByte(')')
- }
-}
-
-func (p *pp) doPrint(a []any) {
- prevString := false
- for argNum, arg := range a {
- isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
- // Add a space between two non-string arguments.
- if argNum > 0 && !isString && !prevString {
- p.buf.writeByte(' ')
- }
- p.printArg(arg, 'v')
- prevString = isString
- }
-}
-
-// doPrintln is like doPrint but always adds a space between arguments
-// and a newline after the last argument.
-func (p *pp) doPrintln(a []any) {
- for argNum, arg := range a {
- if argNum > 0 {
- p.buf.writeByte(' ')
- }
- p.printArg(arg, 'v')
- }
- p.buf.writeByte('\n')
-}
diff --git a/contrib/go/_std_1.20/src/fmt/scan.go b/contrib/go/_std_1.20/src/fmt/scan.go
deleted file mode 100644
index d38610df35..0000000000
--- a/contrib/go/_std_1.20/src/fmt/scan.go
+++ /dev/null
@@ -1,1238 +0,0 @@
-// Copyright 2010 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 fmt
-
-import (
- "errors"
- "io"
- "math"
- "os"
- "reflect"
- "strconv"
- "sync"
- "unicode/utf8"
-)
-
-// ScanState represents the scanner state passed to custom scanners.
-// Scanners may do rune-at-a-time scanning or ask the ScanState
-// to discover the next space-delimited token.
-type ScanState interface {
- // ReadRune reads the next rune (Unicode code point) from the input.
- // If invoked during Scanln, Fscanln, or Sscanln, ReadRune() will
- // return EOF after returning the first '\n' or when reading beyond
- // the specified width.
- ReadRune() (r rune, size int, err error)
- // UnreadRune causes the next call to ReadRune to return the same rune.
- UnreadRune() error
- // SkipSpace skips space in the input. Newlines are treated appropriately
- // for the operation being performed; see the package documentation
- // for more information.
- SkipSpace()
- // Token skips space in the input if skipSpace is true, then returns the
- // run of Unicode code points c satisfying f(c). If f is nil,
- // !unicode.IsSpace(c) is used; that is, the token will hold non-space
- // characters. Newlines are treated appropriately for the operation being
- // performed; see the package documentation for more information.
- // The returned slice points to shared data that may be overwritten
- // by the next call to Token, a call to a Scan function using the ScanState
- // as input, or when the calling Scan method returns.
- Token(skipSpace bool, f func(rune) bool) (token []byte, err error)
- // Width returns the value of the width option and whether it has been set.
- // The unit is Unicode code points.
- Width() (wid int, ok bool)
- // Because ReadRune is implemented by the interface, Read should never be
- // called by the scanning routines and a valid implementation of
- // ScanState may choose always to return an error from Read.
- Read(buf []byte) (n int, err error)
-}
-
-// Scanner is implemented by any value that has a Scan method, which scans
-// the input for the representation of a value and stores the result in the
-// receiver, which must be a pointer to be useful. The Scan method is called
-// for any argument to Scan, Scanf, or Scanln that implements it.
-type Scanner interface {
- Scan(state ScanState, verb rune) error
-}
-
-// Scan scans text read from standard input, storing successive
-// space-separated values into successive arguments. Newlines count
-// as space. It returns the number of items successfully scanned.
-// If that is less than the number of arguments, err will report why.
-func Scan(a ...any) (n int, err error) {
- return Fscan(os.Stdin, a...)
-}
-
-// Scanln is similar to Scan, but stops scanning at a newline and
-// after the final item there must be a newline or EOF.
-func Scanln(a ...any) (n int, err error) {
- return Fscanln(os.Stdin, a...)
-}
-
-// Scanf scans text read from standard input, storing successive
-// space-separated values into successive arguments as determined by
-// the format. It returns the number of items successfully scanned.
-// If that is less than the number of arguments, err will report why.
-// Newlines in the input must match newlines in the format.
-// The one exception: the verb %c always scans the next rune in the
-// input, even if it is a space (or tab etc.) or newline.
-func Scanf(format string, a ...any) (n int, err error) {
- return Fscanf(os.Stdin, format, a...)
-}
-
-type stringReader string
-
-func (r *stringReader) Read(b []byte) (n int, err error) {
- n = copy(b, *r)
- *r = (*r)[n:]
- if n == 0 {
- err = io.EOF
- }
- return
-}
-
-// Sscan scans the argument string, storing successive space-separated
-// values into successive arguments. Newlines count as space. It
-// returns the number of items successfully scanned. If that is less
-// than the number of arguments, err will report why.
-func Sscan(str string, a ...any) (n int, err error) {
- return Fscan((*stringReader)(&str), a...)
-}
-
-// Sscanln is similar to Sscan, but stops scanning at a newline and
-// after the final item there must be a newline or EOF.
-func Sscanln(str string, a ...any) (n int, err error) {
- return Fscanln((*stringReader)(&str), a...)
-}
-
-// Sscanf scans the argument string, storing successive space-separated
-// values into successive arguments as determined by the format. It
-// returns the number of items successfully parsed.
-// Newlines in the input must match newlines in the format.
-func Sscanf(str string, format string, a ...any) (n int, err error) {
- return Fscanf((*stringReader)(&str), format, a...)
-}
-
-// Fscan scans text read from r, storing successive space-separated
-// values into successive arguments. Newlines count as space. It
-// returns the number of items successfully scanned. If that is less
-// than the number of arguments, err will report why.
-func Fscan(r io.Reader, a ...any) (n int, err error) {
- s, old := newScanState(r, true, false)
- n, err = s.doScan(a)
- s.free(old)
- return
-}
-
-// Fscanln is similar to Fscan, but stops scanning at a newline and
-// after the final item there must be a newline or EOF.
-func Fscanln(r io.Reader, a ...any) (n int, err error) {
- s, old := newScanState(r, false, true)
- n, err = s.doScan(a)
- s.free(old)
- return
-}
-
-// Fscanf scans text read from r, storing successive space-separated
-// values into successive arguments as determined by the format. It
-// returns the number of items successfully parsed.
-// Newlines in the input must match newlines in the format.
-func Fscanf(r io.Reader, format string, a ...any) (n int, err error) {
- s, old := newScanState(r, false, false)
- n, err = s.doScanf(format, a)
- s.free(old)
- return
-}
-
-// scanError represents an error generated by the scanning software.
-// It's used as a unique signature to identify such errors when recovering.
-type scanError struct {
- err error
-}
-
-const eof = -1
-
-// ss is the internal implementation of ScanState.
-type ss struct {
- rs io.RuneScanner // where to read input
- buf buffer // token accumulator
- count int // runes consumed so far.
- atEOF bool // already read EOF
- ssave
-}
-
-// ssave holds the parts of ss that need to be
-// saved and restored on recursive scans.
-type ssave struct {
- validSave bool // is or was a part of an actual ss.
- nlIsEnd bool // whether newline terminates scan
- nlIsSpace bool // whether newline counts as white space
- argLimit int // max value of ss.count for this arg; argLimit <= limit
- limit int // max value of ss.count.
- maxWid int // width of this arg.
-}
-
-// The Read method is only in ScanState so that ScanState
-// satisfies io.Reader. It will never be called when used as
-// intended, so there is no need to make it actually work.
-func (s *ss) Read(buf []byte) (n int, err error) {
- return 0, errors.New("ScanState's Read should not be called. Use ReadRune")
-}
-
-func (s *ss) ReadRune() (r rune, size int, err error) {
- if s.atEOF || s.count >= s.argLimit {
- err = io.EOF
- return
- }
-
- r, size, err = s.rs.ReadRune()
- if err == nil {
- s.count++
- if s.nlIsEnd && r == '\n' {
- s.atEOF = true
- }
- } else if err == io.EOF {
- s.atEOF = true
- }
- return
-}
-
-func (s *ss) Width() (wid int, ok bool) {
- if s.maxWid == hugeWid {
- return 0, false
- }
- return s.maxWid, true
-}
-
-// The public method returns an error; this private one panics.
-// If getRune reaches EOF, the return value is EOF (-1).
-func (s *ss) getRune() (r rune) {
- r, _, err := s.ReadRune()
- if err != nil {
- if err == io.EOF {
- return eof
- }
- s.error(err)
- }
- return
-}
-
-// mustReadRune turns io.EOF into a panic(io.ErrUnexpectedEOF).
-// It is called in cases such as string scanning where an EOF is a
-// syntax error.
-func (s *ss) mustReadRune() (r rune) {
- r = s.getRune()
- if r == eof {
- s.error(io.ErrUnexpectedEOF)
- }
- return
-}
-
-func (s *ss) UnreadRune() error {
- s.rs.UnreadRune()
- s.atEOF = false
- s.count--
- return nil
-}
-
-func (s *ss) error(err error) {
- panic(scanError{err})
-}
-
-func (s *ss) errorString(err string) {
- panic(scanError{errors.New(err)})
-}
-
-func (s *ss) Token(skipSpace bool, f func(rune) bool) (tok []byte, err error) {
- defer func() {
- if e := recover(); e != nil {
- if se, ok := e.(scanError); ok {
- err = se.err
- } else {
- panic(e)
- }
- }
- }()
- if f == nil {
- f = notSpace
- }
- s.buf = s.buf[:0]
- tok = s.token(skipSpace, f)
- return
-}
-
-// space is a copy of the unicode.White_Space ranges,
-// to avoid depending on package unicode.
-var space = [][2]uint16{
- {0x0009, 0x000d},
- {0x0020, 0x0020},
- {0x0085, 0x0085},
- {0x00a0, 0x00a0},
- {0x1680, 0x1680},
- {0x2000, 0x200a},
- {0x2028, 0x2029},
- {0x202f, 0x202f},
- {0x205f, 0x205f},
- {0x3000, 0x3000},
-}
-
-func isSpace(r rune) bool {
- if r >= 1<<16 {
- return false
- }
- rx := uint16(r)
- for _, rng := range space {
- if rx < rng[0] {
- return false
- }
- if rx <= rng[1] {
- return true
- }
- }
- return false
-}
-
-// notSpace is the default scanning function used in Token.
-func notSpace(r rune) bool {
- return !isSpace(r)
-}
-
-// readRune is a structure to enable reading UTF-8 encoded code points
-// from an io.Reader. It is used if the Reader given to the scanner does
-// not already implement io.RuneScanner.
-type readRune struct {
- reader io.Reader
- buf [utf8.UTFMax]byte // used only inside ReadRune
- pending int // number of bytes in pendBuf; only >0 for bad UTF-8
- pendBuf [utf8.UTFMax]byte // bytes left over
- peekRune rune // if >=0 next rune; when <0 is ^(previous Rune)
-}
-
-// readByte returns the next byte from the input, which may be
-// left over from a previous read if the UTF-8 was ill-formed.
-func (r *readRune) readByte() (b byte, err error) {
- if r.pending > 0 {
- b = r.pendBuf[0]
- copy(r.pendBuf[0:], r.pendBuf[1:])
- r.pending--
- return
- }
- n, err := io.ReadFull(r.reader, r.pendBuf[:1])
- if n != 1 {
- return 0, err
- }
- return r.pendBuf[0], err
-}
-
-// ReadRune returns the next UTF-8 encoded code point from the
-// io.Reader inside r.
-func (r *readRune) ReadRune() (rr rune, size int, err error) {
- if r.peekRune >= 0 {
- rr = r.peekRune
- r.peekRune = ^r.peekRune
- size = utf8.RuneLen(rr)
- return
- }
- r.buf[0], err = r.readByte()
- if err != nil {
- return
- }
- if r.buf[0] < utf8.RuneSelf { // fast check for common ASCII case
- rr = rune(r.buf[0])
- size = 1 // Known to be 1.
- // Flip the bits of the rune so it's available to UnreadRune.
- r.peekRune = ^rr
- return
- }
- var n int
- for n = 1; !utf8.FullRune(r.buf[:n]); n++ {
- r.buf[n], err = r.readByte()
- if err != nil {
- if err == io.EOF {
- err = nil
- break
- }
- return
- }
- }
- rr, size = utf8.DecodeRune(r.buf[:n])
- if size < n { // an error, save the bytes for the next read
- copy(r.pendBuf[r.pending:], r.buf[size:n])
- r.pending += n - size
- }
- // Flip the bits of the rune so it's available to UnreadRune.
- r.peekRune = ^rr
- return
-}
-
-func (r *readRune) UnreadRune() error {
- if r.peekRune >= 0 {
- return errors.New("fmt: scanning called UnreadRune with no rune available")
- }
- // Reverse bit flip of previously read rune to obtain valid >=0 state.
- r.peekRune = ^r.peekRune
- return nil
-}
-
-var ssFree = sync.Pool{
- New: func() any { return new(ss) },
-}
-
-// newScanState allocates a new ss struct or grab a cached one.
-func newScanState(r io.Reader, nlIsSpace, nlIsEnd bool) (s *ss, old ssave) {
- s = ssFree.Get().(*ss)
- if rs, ok := r.(io.RuneScanner); ok {
- s.rs = rs
- } else {
- s.rs = &readRune{reader: r, peekRune: -1}
- }
- s.nlIsSpace = nlIsSpace
- s.nlIsEnd = nlIsEnd
- s.atEOF = false
- s.limit = hugeWid
- s.argLimit = hugeWid
- s.maxWid = hugeWid
- s.validSave = true
- s.count = 0
- return
-}
-
-// free saves used ss structs in ssFree; avoid an allocation per invocation.
-func (s *ss) free(old ssave) {
- // If it was used recursively, just restore the old state.
- if old.validSave {
- s.ssave = old
- return
- }
- // Don't hold on to ss structs with large buffers.
- if cap(s.buf) > 1024 {
- return
- }
- s.buf = s.buf[:0]
- s.rs = nil
- ssFree.Put(s)
-}
-
-// SkipSpace provides Scan methods the ability to skip space and newline
-// characters in keeping with the current scanning mode set by format strings
-// and Scan/Scanln.
-func (s *ss) SkipSpace() {
- for {
- r := s.getRune()
- if r == eof {
- return
- }
- if r == '\r' && s.peek("\n") {
- continue
- }
- if r == '\n' {
- if s.nlIsSpace {
- continue
- }
- s.errorString("unexpected newline")
- return
- }
- if !isSpace(r) {
- s.UnreadRune()
- break
- }
- }
-}
-
-// token returns the next space-delimited string from the input. It
-// skips white space. For Scanln, it stops at newlines. For Scan,
-// newlines are treated as spaces.
-func (s *ss) token(skipSpace bool, f func(rune) bool) []byte {
- if skipSpace {
- s.SkipSpace()
- }
- // read until white space or newline
- for {
- r := s.getRune()
- if r == eof {
- break
- }
- if !f(r) {
- s.UnreadRune()
- break
- }
- s.buf.writeRune(r)
- }
- return s.buf
-}
-
-var complexError = errors.New("syntax error scanning complex number")
-var boolError = errors.New("syntax error scanning boolean")
-
-func indexRune(s string, r rune) int {
- for i, c := range s {
- if c == r {
- return i
- }
- }
- return -1
-}
-
-// consume reads the next rune in the input and reports whether it is in the ok string.
-// If accept is true, it puts the character into the input token.
-func (s *ss) consume(ok string, accept bool) bool {
- r := s.getRune()
- if r == eof {
- return false
- }
- if indexRune(ok, r) >= 0 {
- if accept {
- s.buf.writeRune(r)
- }
- return true
- }
- if r != eof && accept {
- s.UnreadRune()
- }
- return false
-}
-
-// peek reports whether the next character is in the ok string, without consuming it.
-func (s *ss) peek(ok string) bool {
- r := s.getRune()
- if r != eof {
- s.UnreadRune()
- }
- return indexRune(ok, r) >= 0
-}
-
-func (s *ss) notEOF() {
- // Guarantee there is data to be read.
- if r := s.getRune(); r == eof {
- panic(io.EOF)
- }
- s.UnreadRune()
-}
-
-// accept checks the next rune in the input. If it's a byte (sic) in the string, it puts it in the
-// buffer and returns true. Otherwise it return false.
-func (s *ss) accept(ok string) bool {
- return s.consume(ok, true)
-}
-
-// okVerb verifies that the verb is present in the list, setting s.err appropriately if not.
-func (s *ss) okVerb(verb rune, okVerbs, typ string) bool {
- for _, v := range okVerbs {
- if v == verb {
- return true
- }
- }
- s.errorString("bad verb '%" + string(verb) + "' for " + typ)
- return false
-}
-
-// scanBool returns the value of the boolean represented by the next token.
-func (s *ss) scanBool(verb rune) bool {
- s.SkipSpace()
- s.notEOF()
- if !s.okVerb(verb, "tv", "boolean") {
- return false
- }
- // Syntax-checking a boolean is annoying. We're not fastidious about case.
- switch s.getRune() {
- case '0':
- return false
- case '1':
- return true
- case 't', 'T':
- if s.accept("rR") && (!s.accept("uU") || !s.accept("eE")) {
- s.error(boolError)
- }
- return true
- case 'f', 'F':
- if s.accept("aA") && (!s.accept("lL") || !s.accept("sS") || !s.accept("eE")) {
- s.error(boolError)
- }
- return false
- }
- return false
-}
-
-// Numerical elements
-const (
- binaryDigits = "01"
- octalDigits = "01234567"
- decimalDigits = "0123456789"
- hexadecimalDigits = "0123456789aAbBcCdDeEfF"
- sign = "+-"
- period = "."
- exponent = "eEpP"
-)
-
-// getBase returns the numeric base represented by the verb and its digit string.
-func (s *ss) getBase(verb rune) (base int, digits string) {
- s.okVerb(verb, "bdoUxXv", "integer") // sets s.err
- base = 10
- digits = decimalDigits
- switch verb {
- case 'b':
- base = 2
- digits = binaryDigits
- case 'o':
- base = 8
- digits = octalDigits
- case 'x', 'X', 'U':
- base = 16
- digits = hexadecimalDigits
- }
- return
-}
-
-// scanNumber returns the numerical string with specified digits starting here.
-func (s *ss) scanNumber(digits string, haveDigits bool) string {
- if !haveDigits {
- s.notEOF()
- if !s.accept(digits) {
- s.errorString("expected integer")
- }
- }
- for s.accept(digits) {
- }
- return string(s.buf)
-}
-
-// scanRune returns the next rune value in the input.
-func (s *ss) scanRune(bitSize int) int64 {
- s.notEOF()
- r := s.getRune()
- n := uint(bitSize)
- x := (int64(r) << (64 - n)) >> (64 - n)
- if x != int64(r) {
- s.errorString("overflow on character value " + string(r))
- }
- return int64(r)
-}
-
-// scanBasePrefix reports whether the integer begins with a base prefix
-// and returns the base, digit string, and whether a zero was found.
-// It is called only if the verb is %v.
-func (s *ss) scanBasePrefix() (base int, digits string, zeroFound bool) {
- if !s.peek("0") {
- return 0, decimalDigits + "_", false
- }
- s.accept("0")
- // Special cases for 0, 0b, 0o, 0x.
- switch {
- case s.peek("bB"):
- s.consume("bB", true)
- return 0, binaryDigits + "_", true
- case s.peek("oO"):
- s.consume("oO", true)
- return 0, octalDigits + "_", true
- case s.peek("xX"):
- s.consume("xX", true)
- return 0, hexadecimalDigits + "_", true
- default:
- return 0, octalDigits + "_", true
- }
-}
-
-// scanInt returns the value of the integer represented by the next
-// token, checking for overflow. Any error is stored in s.err.
-func (s *ss) scanInt(verb rune, bitSize int) int64 {
- if verb == 'c' {
- return s.scanRune(bitSize)
- }
- s.SkipSpace()
- s.notEOF()
- base, digits := s.getBase(verb)
- haveDigits := false
- if verb == 'U' {
- if !s.consume("U", false) || !s.consume("+", false) {
- s.errorString("bad unicode format ")
- }
- } else {
- s.accept(sign) // If there's a sign, it will be left in the token buffer.
- if verb == 'v' {
- base, digits, haveDigits = s.scanBasePrefix()
- }
- }
- tok := s.scanNumber(digits, haveDigits)
- i, err := strconv.ParseInt(tok, base, 64)
- if err != nil {
- s.error(err)
- }
- n := uint(bitSize)
- x := (i << (64 - n)) >> (64 - n)
- if x != i {
- s.errorString("integer overflow on token " + tok)
- }
- return i
-}
-
-// scanUint returns the value of the unsigned integer represented
-// by the next token, checking for overflow. Any error is stored in s.err.
-func (s *ss) scanUint(verb rune, bitSize int) uint64 {
- if verb == 'c' {
- return uint64(s.scanRune(bitSize))
- }
- s.SkipSpace()
- s.notEOF()
- base, digits := s.getBase(verb)
- haveDigits := false
- if verb == 'U' {
- if !s.consume("U", false) || !s.consume("+", false) {
- s.errorString("bad unicode format ")
- }
- } else if verb == 'v' {
- base, digits, haveDigits = s.scanBasePrefix()
- }
- tok := s.scanNumber(digits, haveDigits)
- i, err := strconv.ParseUint(tok, base, 64)
- if err != nil {
- s.error(err)
- }
- n := uint(bitSize)
- x := (i << (64 - n)) >> (64 - n)
- if x != i {
- s.errorString("unsigned integer overflow on token " + tok)
- }
- return i
-}
-
-// floatToken returns the floating-point number starting here, no longer than swid
-// if the width is specified. It's not rigorous about syntax because it doesn't check that
-// we have at least some digits, but Atof will do that.
-func (s *ss) floatToken() string {
- s.buf = s.buf[:0]
- // NaN?
- if s.accept("nN") && s.accept("aA") && s.accept("nN") {
- return string(s.buf)
- }
- // leading sign?
- s.accept(sign)
- // Inf?
- if s.accept("iI") && s.accept("nN") && s.accept("fF") {
- return string(s.buf)
- }
- digits := decimalDigits + "_"
- exp := exponent
- if s.accept("0") && s.accept("xX") {
- digits = hexadecimalDigits + "_"
- exp = "pP"
- }
- // digits?
- for s.accept(digits) {
- }
- // decimal point?
- if s.accept(period) {
- // fraction?
- for s.accept(digits) {
- }
- }
- // exponent?
- if s.accept(exp) {
- // leading sign?
- s.accept(sign)
- // digits?
- for s.accept(decimalDigits + "_") {
- }
- }
- return string(s.buf)
-}
-
-// complexTokens returns the real and imaginary parts of the complex number starting here.
-// The number might be parenthesized and has the format (N+Ni) where N is a floating-point
-// number and there are no spaces within.
-func (s *ss) complexTokens() (real, imag string) {
- // TODO: accept N and Ni independently?
- parens := s.accept("(")
- real = s.floatToken()
- s.buf = s.buf[:0]
- // Must now have a sign.
- if !s.accept("+-") {
- s.error(complexError)
- }
- // Sign is now in buffer
- imagSign := string(s.buf)
- imag = s.floatToken()
- if !s.accept("i") {
- s.error(complexError)
- }
- if parens && !s.accept(")") {
- s.error(complexError)
- }
- return real, imagSign + imag
-}
-
-func hasX(s string) bool {
- for i := 0; i < len(s); i++ {
- if s[i] == 'x' || s[i] == 'X' {
- return true
- }
- }
- return false
-}
-
-// convertFloat converts the string to a float64value.
-func (s *ss) convertFloat(str string, n int) float64 {
- // strconv.ParseFloat will handle "+0x1.fp+2",
- // but we have to implement our non-standard
- // decimal+binary exponent mix (1.2p4) ourselves.
- if p := indexRune(str, 'p'); p >= 0 && !hasX(str) {
- // Atof doesn't handle power-of-2 exponents,
- // but they're easy to evaluate.
- f, err := strconv.ParseFloat(str[:p], n)
- if err != nil {
- // Put full string into error.
- if e, ok := err.(*strconv.NumError); ok {
- e.Num = str
- }
- s.error(err)
- }
- m, err := strconv.Atoi(str[p+1:])
- if err != nil {
- // Put full string into error.
- if e, ok := err.(*strconv.NumError); ok {
- e.Num = str
- }
- s.error(err)
- }
- return math.Ldexp(f, m)
- }
- f, err := strconv.ParseFloat(str, n)
- if err != nil {
- s.error(err)
- }
- return f
-}
-
-// convertComplex converts the next token to a complex128 value.
-// The atof argument is a type-specific reader for the underlying type.
-// If we're reading complex64, atof will parse float32s and convert them
-// to float64's to avoid reproducing this code for each complex type.
-func (s *ss) scanComplex(verb rune, n int) complex128 {
- if !s.okVerb(verb, floatVerbs, "complex") {
- return 0
- }
- s.SkipSpace()
- s.notEOF()
- sreal, simag := s.complexTokens()
- real := s.convertFloat(sreal, n/2)
- imag := s.convertFloat(simag, n/2)
- return complex(real, imag)
-}
-
-// convertString returns the string represented by the next input characters.
-// The format of the input is determined by the verb.
-func (s *ss) convertString(verb rune) (str string) {
- if !s.okVerb(verb, "svqxX", "string") {
- return ""
- }
- s.SkipSpace()
- s.notEOF()
- switch verb {
- case 'q':
- str = s.quotedString()
- case 'x', 'X':
- str = s.hexString()
- default:
- str = string(s.token(true, notSpace)) // %s and %v just return the next word
- }
- return
-}
-
-// quotedString returns the double- or back-quoted string represented by the next input characters.
-func (s *ss) quotedString() string {
- s.notEOF()
- quote := s.getRune()
- switch quote {
- case '`':
- // Back-quoted: Anything goes until EOF or back quote.
- for {
- r := s.mustReadRune()
- if r == quote {
- break
- }
- s.buf.writeRune(r)
- }
- return string(s.buf)
- case '"':
- // Double-quoted: Include the quotes and let strconv.Unquote do the backslash escapes.
- s.buf.writeByte('"')
- for {
- r := s.mustReadRune()
- s.buf.writeRune(r)
- if r == '\\' {
- // In a legal backslash escape, no matter how long, only the character
- // immediately after the escape can itself be a backslash or quote.
- // Thus we only need to protect the first character after the backslash.
- s.buf.writeRune(s.mustReadRune())
- } else if r == '"' {
- break
- }
- }
- result, err := strconv.Unquote(string(s.buf))
- if err != nil {
- s.error(err)
- }
- return result
- default:
- s.errorString("expected quoted string")
- }
- return ""
-}
-
-// hexDigit returns the value of the hexadecimal digit.
-func hexDigit(d rune) (int, bool) {
- digit := int(d)
- switch digit {
- case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
- return digit - '0', true
- case 'a', 'b', 'c', 'd', 'e', 'f':
- return 10 + digit - 'a', true
- case 'A', 'B', 'C', 'D', 'E', 'F':
- return 10 + digit - 'A', true
- }
- return -1, false
-}
-
-// hexByte returns the next hex-encoded (two-character) byte from the input.
-// It returns ok==false if the next bytes in the input do not encode a hex byte.
-// If the first byte is hex and the second is not, processing stops.
-func (s *ss) hexByte() (b byte, ok bool) {
- rune1 := s.getRune()
- if rune1 == eof {
- return
- }
- value1, ok := hexDigit(rune1)
- if !ok {
- s.UnreadRune()
- return
- }
- value2, ok := hexDigit(s.mustReadRune())
- if !ok {
- s.errorString("illegal hex digit")
- return
- }
- return byte(value1<<4 | value2), true
-}
-
-// hexString returns the space-delimited hexpair-encoded string.
-func (s *ss) hexString() string {
- s.notEOF()
- for {
- b, ok := s.hexByte()
- if !ok {
- break
- }
- s.buf.writeByte(b)
- }
- if len(s.buf) == 0 {
- s.errorString("no hex data for %x string")
- return ""
- }
- return string(s.buf)
-}
-
-const (
- floatVerbs = "beEfFgGv"
-
- hugeWid = 1 << 30
-
- intBits = 32 << (^uint(0) >> 63)
- uintptrBits = 32 << (^uintptr(0) >> 63)
-)
-
-// scanPercent scans a literal percent character.
-func (s *ss) scanPercent() {
- s.SkipSpace()
- s.notEOF()
- if !s.accept("%") {
- s.errorString("missing literal %")
- }
-}
-
-// scanOne scans a single value, deriving the scanner from the type of the argument.
-func (s *ss) scanOne(verb rune, arg any) {
- s.buf = s.buf[:0]
- var err error
- // If the parameter has its own Scan method, use that.
- if v, ok := arg.(Scanner); ok {
- err = v.Scan(s, verb)
- if err != nil {
- if err == io.EOF {
- err = io.ErrUnexpectedEOF
- }
- s.error(err)
- }
- return
- }
-
- switch v := arg.(type) {
- case *bool:
- *v = s.scanBool(verb)
- case *complex64:
- *v = complex64(s.scanComplex(verb, 64))
- case *complex128:
- *v = s.scanComplex(verb, 128)
- case *int:
- *v = int(s.scanInt(verb, intBits))
- case *int8:
- *v = int8(s.scanInt(verb, 8))
- case *int16:
- *v = int16(s.scanInt(verb, 16))
- case *int32:
- *v = int32(s.scanInt(verb, 32))
- case *int64:
- *v = s.scanInt(verb, 64)
- case *uint:
- *v = uint(s.scanUint(verb, intBits))
- case *uint8:
- *v = uint8(s.scanUint(verb, 8))
- case *uint16:
- *v = uint16(s.scanUint(verb, 16))
- case *uint32:
- *v = uint32(s.scanUint(verb, 32))
- case *uint64:
- *v = s.scanUint(verb, 64)
- case *uintptr:
- *v = uintptr(s.scanUint(verb, uintptrBits))
- // Floats are tricky because you want to scan in the precision of the result, not
- // scan in high precision and convert, in order to preserve the correct error condition.
- case *float32:
- if s.okVerb(verb, floatVerbs, "float32") {
- s.SkipSpace()
- s.notEOF()
- *v = float32(s.convertFloat(s.floatToken(), 32))
- }
- case *float64:
- if s.okVerb(verb, floatVerbs, "float64") {
- s.SkipSpace()
- s.notEOF()
- *v = s.convertFloat(s.floatToken(), 64)
- }
- case *string:
- *v = s.convertString(verb)
- case *[]byte:
- // We scan to string and convert so we get a copy of the data.
- // If we scanned to bytes, the slice would point at the buffer.
- *v = []byte(s.convertString(verb))
- default:
- val := reflect.ValueOf(v)
- ptr := val
- if ptr.Kind() != reflect.Pointer {
- s.errorString("type not a pointer: " + val.Type().String())
- return
- }
- switch v := ptr.Elem(); v.Kind() {
- case reflect.Bool:
- v.SetBool(s.scanBool(verb))
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- v.SetInt(s.scanInt(verb, v.Type().Bits()))
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- v.SetUint(s.scanUint(verb, v.Type().Bits()))
- case reflect.String:
- v.SetString(s.convertString(verb))
- case reflect.Slice:
- // For now, can only handle (renamed) []byte.
- typ := v.Type()
- if typ.Elem().Kind() != reflect.Uint8 {
- s.errorString("can't scan type: " + val.Type().String())
- }
- str := s.convertString(verb)
- v.Set(reflect.MakeSlice(typ, len(str), len(str)))
- for i := 0; i < len(str); i++ {
- v.Index(i).SetUint(uint64(str[i]))
- }
- case reflect.Float32, reflect.Float64:
- s.SkipSpace()
- s.notEOF()
- v.SetFloat(s.convertFloat(s.floatToken(), v.Type().Bits()))
- case reflect.Complex64, reflect.Complex128:
- v.SetComplex(s.scanComplex(verb, v.Type().Bits()))
- default:
- s.errorString("can't scan type: " + val.Type().String())
- }
- }
-}
-
-// errorHandler turns local panics into error returns.
-func errorHandler(errp *error) {
- if e := recover(); e != nil {
- if se, ok := e.(scanError); ok { // catch local error
- *errp = se.err
- } else if eof, ok := e.(error); ok && eof == io.EOF { // out of input
- *errp = eof
- } else {
- panic(e)
- }
- }
-}
-
-// doScan does the real work for scanning without a format string.
-func (s *ss) doScan(a []any) (numProcessed int, err error) {
- defer errorHandler(&err)
- for _, arg := range a {
- s.scanOne('v', arg)
- numProcessed++
- }
- // Check for newline (or EOF) if required (Scanln etc.).
- if s.nlIsEnd {
- for {
- r := s.getRune()
- if r == '\n' || r == eof {
- break
- }
- if !isSpace(r) {
- s.errorString("expected newline")
- break
- }
- }
- }
- return
-}
-
-// advance determines whether the next characters in the input match
-// those of the format. It returns the number of bytes (sic) consumed
-// in the format. All runs of space characters in either input or
-// format behave as a single space. Newlines are special, though:
-// newlines in the format must match those in the input and vice versa.
-// This routine also handles the %% case. If the return value is zero,
-// either format starts with a % (with no following %) or the input
-// is empty. If it is negative, the input did not match the string.
-func (s *ss) advance(format string) (i int) {
- for i < len(format) {
- fmtc, w := utf8.DecodeRuneInString(format[i:])
-
- // Space processing.
- // In the rest of this comment "space" means spaces other than newline.
- // Newline in the format matches input of zero or more spaces and then newline or end-of-input.
- // Spaces in the format before the newline are collapsed into the newline.
- // Spaces in the format after the newline match zero or more spaces after the corresponding input newline.
- // Other spaces in the format match input of one or more spaces or end-of-input.
- if isSpace(fmtc) {
- newlines := 0
- trailingSpace := false
- for isSpace(fmtc) && i < len(format) {
- if fmtc == '\n' {
- newlines++
- trailingSpace = false
- } else {
- trailingSpace = true
- }
- i += w
- fmtc, w = utf8.DecodeRuneInString(format[i:])
- }
- for j := 0; j < newlines; j++ {
- inputc := s.getRune()
- for isSpace(inputc) && inputc != '\n' {
- inputc = s.getRune()
- }
- if inputc != '\n' && inputc != eof {
- s.errorString("newline in format does not match input")
- }
- }
- if trailingSpace {
- inputc := s.getRune()
- if newlines == 0 {
- // If the trailing space stood alone (did not follow a newline),
- // it must find at least one space to consume.
- if !isSpace(inputc) && inputc != eof {
- s.errorString("expected space in input to match format")
- }
- if inputc == '\n' {
- s.errorString("newline in input does not match format")
- }
- }
- for isSpace(inputc) && inputc != '\n' {
- inputc = s.getRune()
- }
- if inputc != eof {
- s.UnreadRune()
- }
- }
- continue
- }
-
- // Verbs.
- if fmtc == '%' {
- // % at end of string is an error.
- if i+w == len(format) {
- s.errorString("missing verb: % at end of format string")
- }
- // %% acts like a real percent
- nextc, _ := utf8.DecodeRuneInString(format[i+w:]) // will not match % if string is empty
- if nextc != '%' {
- return
- }
- i += w // skip the first %
- }
-
- // Literals.
- inputc := s.mustReadRune()
- if fmtc != inputc {
- s.UnreadRune()
- return -1
- }
- i += w
- }
- return
-}
-
-// doScanf does the real work when scanning with a format string.
-// At the moment, it handles only pointers to basic types.
-func (s *ss) doScanf(format string, a []any) (numProcessed int, err error) {
- defer errorHandler(&err)
- end := len(format) - 1
- // We process one item per non-trivial format
- for i := 0; i <= end; {
- w := s.advance(format[i:])
- if w > 0 {
- i += w
- continue
- }
- // Either we failed to advance, we have a percent character, or we ran out of input.
- if format[i] != '%' {
- // Can't advance format. Why not?
- if w < 0 {
- s.errorString("input does not match format")
- }
- // Otherwise at EOF; "too many operands" error handled below
- break
- }
- i++ // % is one byte
-
- // do we have 20 (width)?
- var widPresent bool
- s.maxWid, widPresent, i = parsenum(format, i, end)
- if !widPresent {
- s.maxWid = hugeWid
- }
-
- c, w := utf8.DecodeRuneInString(format[i:])
- i += w
-
- if c != 'c' {
- s.SkipSpace()
- }
- if c == '%' {
- s.scanPercent()
- continue // Do not consume an argument.
- }
- s.argLimit = s.limit
- if f := s.count + s.maxWid; f < s.argLimit {
- s.argLimit = f
- }
-
- if numProcessed >= len(a) { // out of operands
- s.errorString("too few operands for format '%" + format[i-w:] + "'")
- break
- }
- arg := a[numProcessed]
-
- s.scanOne(c, arg)
- numProcessed++
- s.argLimit = s.limit
- }
- if numProcessed < len(a) {
- s.errorString("too many operands")
- }
- return
-}
diff --git a/contrib/go/_std_1.20/src/fmt/ya.make b/contrib/go/_std_1.20/src/fmt/ya.make
deleted file mode 100644
index 75846fcba8..0000000000
--- a/contrib/go/_std_1.20/src/fmt/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- doc.go
- errors.go
- format.go
- print.go
- scan.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/ast/ast.go b/contrib/go/_std_1.20/src/go/ast/ast.go
deleted file mode 100644
index 9baf72f40f..0000000000
--- a/contrib/go/_std_1.20/src/go/ast/ast.go
+++ /dev/null
@@ -1,1074 +0,0 @@
-// Copyright 2009 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 ast declares the types used to represent syntax trees for Go
-// packages.
-package ast
-
-import (
- "go/token"
- "strings"
-)
-
-// ----------------------------------------------------------------------------
-// Interfaces
-//
-// There are 3 main classes of nodes: Expressions and type nodes,
-// statement nodes, and declaration nodes. The node names usually
-// match the corresponding Go spec production names to which they
-// correspond. The node fields correspond to the individual parts
-// of the respective productions.
-//
-// All nodes contain position information marking the beginning of
-// the corresponding source text segment; it is accessible via the
-// Pos accessor method. Nodes may contain additional position info
-// for language constructs where comments may be found between parts
-// of the construct (typically any larger, parenthesized subpart).
-// That position information is needed to properly position comments
-// when printing the construct.
-
-// All node types implement the Node interface.
-type Node interface {
- Pos() token.Pos // position of first character belonging to the node
- End() token.Pos // position of first character immediately after the node
-}
-
-// All expression nodes implement the Expr interface.
-type Expr interface {
- Node
- exprNode()
-}
-
-// All statement nodes implement the Stmt interface.
-type Stmt interface {
- Node
- stmtNode()
-}
-
-// All declaration nodes implement the Decl interface.
-type Decl interface {
- Node
- declNode()
-}
-
-// ----------------------------------------------------------------------------
-// Comments
-
-// A Comment node represents a single //-style or /*-style comment.
-//
-// The Text field contains the comment text without carriage returns (\r) that
-// may have been present in the source. Because a comment's end position is
-// computed using len(Text), the position reported by End() does not match the
-// true source end position for comments containing carriage returns.
-type Comment struct {
- Slash token.Pos // position of "/" starting the comment
- Text string // comment text (excluding '\n' for //-style comments)
-}
-
-func (c *Comment) Pos() token.Pos { return c.Slash }
-func (c *Comment) End() token.Pos { return token.Pos(int(c.Slash) + len(c.Text)) }
-
-// A CommentGroup represents a sequence of comments
-// with no other tokens and no empty lines between.
-type CommentGroup struct {
- List []*Comment // len(List) > 0
-}
-
-func (g *CommentGroup) Pos() token.Pos { return g.List[0].Pos() }
-func (g *CommentGroup) End() token.Pos { return g.List[len(g.List)-1].End() }
-
-func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' }
-
-func stripTrailingWhitespace(s string) string {
- i := len(s)
- for i > 0 && isWhitespace(s[i-1]) {
- i--
- }
- return s[0:i]
-}
-
-// Text returns the text of the comment.
-// Comment markers (//, /*, and */), the first space of a line comment, and
-// leading and trailing empty lines are removed.
-// Comment directives like "//line" and "//go:noinline" are also removed.
-// Multiple empty lines are reduced to one, and trailing space on lines is trimmed.
-// Unless the result is empty, it is newline-terminated.
-func (g *CommentGroup) Text() string {
- if g == nil {
- return ""
- }
- comments := make([]string, len(g.List))
- for i, c := range g.List {
- comments[i] = c.Text
- }
-
- lines := make([]string, 0, 10) // most comments are less than 10 lines
- for _, c := range comments {
- // Remove comment markers.
- // The parser has given us exactly the comment text.
- switch c[1] {
- case '/':
- //-style comment (no newline at the end)
- c = c[2:]
- if len(c) == 0 {
- // empty line
- break
- }
- if c[0] == ' ' {
- // strip first space - required for Example tests
- c = c[1:]
- break
- }
- if isDirective(c) {
- // Ignore //go:noinline, //line, and so on.
- continue
- }
- case '*':
- /*-style comment */
- c = c[2 : len(c)-2]
- }
-
- // Split on newlines.
- cl := strings.Split(c, "\n")
-
- // Walk lines, stripping trailing white space and adding to list.
- for _, l := range cl {
- lines = append(lines, stripTrailingWhitespace(l))
- }
- }
-
- // Remove leading blank lines; convert runs of
- // interior blank lines to a single blank line.
- n := 0
- for _, line := range lines {
- if line != "" || n > 0 && lines[n-1] != "" {
- lines[n] = line
- n++
- }
- }
- lines = lines[0:n]
-
- // Add final "" entry to get trailing newline from Join.
- if n > 0 && lines[n-1] != "" {
- lines = append(lines, "")
- }
-
- return strings.Join(lines, "\n")
-}
-
-// isDirective reports whether c is a comment directive.
-// This code is also in go/printer.
-func isDirective(c string) bool {
- // "//line " is a line directive.
- // "//extern " is for gccgo.
- // "//export " is for cgo.
- // (The // has been removed.)
- if strings.HasPrefix(c, "line ") || strings.HasPrefix(c, "extern ") || strings.HasPrefix(c, "export ") {
- return true
- }
-
- // "//[a-z0-9]+:[a-z0-9]"
- // (The // has been removed.)
- colon := strings.Index(c, ":")
- if colon <= 0 || colon+1 >= len(c) {
- return false
- }
- for i := 0; i <= colon+1; i++ {
- if i == colon {
- continue
- }
- b := c[i]
- if !('a' <= b && b <= 'z' || '0' <= b && b <= '9') {
- return false
- }
- }
- return true
-}
-
-// ----------------------------------------------------------------------------
-// Expressions and types
-
-// A Field represents a Field declaration list in a struct type,
-// a method list in an interface type, or a parameter/result declaration
-// in a signature.
-// Field.Names is nil for unnamed parameters (parameter lists which only contain types)
-// and embedded struct fields. In the latter case, the field name is the type name.
-type Field struct {
- Doc *CommentGroup // associated documentation; or nil
- Names []*Ident // field/method/(type) parameter names; or nil
- Type Expr // field/method/parameter type; or nil
- Tag *BasicLit // field tag; or nil
- Comment *CommentGroup // line comments; or nil
-}
-
-func (f *Field) Pos() token.Pos {
- if len(f.Names) > 0 {
- return f.Names[0].Pos()
- }
- if f.Type != nil {
- return f.Type.Pos()
- }
- return token.NoPos
-}
-
-func (f *Field) End() token.Pos {
- if f.Tag != nil {
- return f.Tag.End()
- }
- if f.Type != nil {
- return f.Type.End()
- }
- if len(f.Names) > 0 {
- return f.Names[len(f.Names)-1].End()
- }
- return token.NoPos
-}
-
-// A FieldList represents a list of Fields, enclosed by parentheses,
-// curly braces, or square brackets.
-type FieldList struct {
- Opening token.Pos // position of opening parenthesis/brace/bracket, if any
- List []*Field // field list; or nil
- Closing token.Pos // position of closing parenthesis/brace/bracket, if any
-}
-
-func (f *FieldList) Pos() token.Pos {
- if f.Opening.IsValid() {
- return f.Opening
- }
- // the list should not be empty in this case;
- // be conservative and guard against bad ASTs
- if len(f.List) > 0 {
- return f.List[0].Pos()
- }
- return token.NoPos
-}
-
-func (f *FieldList) End() token.Pos {
- if f.Closing.IsValid() {
- return f.Closing + 1
- }
- // the list should not be empty in this case;
- // be conservative and guard against bad ASTs
- if n := len(f.List); n > 0 {
- return f.List[n-1].End()
- }
- return token.NoPos
-}
-
-// NumFields returns the number of parameters or struct fields represented by a FieldList.
-func (f *FieldList) NumFields() int {
- n := 0
- if f != nil {
- for _, g := range f.List {
- m := len(g.Names)
- if m == 0 {
- m = 1
- }
- n += m
- }
- }
- return n
-}
-
-// An expression is represented by a tree consisting of one
-// or more of the following concrete expression nodes.
-type (
- // A BadExpr node is a placeholder for an expression containing
- // syntax errors for which a correct expression node cannot be
- // created.
- //
- BadExpr struct {
- From, To token.Pos // position range of bad expression
- }
-
- // An Ident node represents an identifier.
- Ident struct {
- NamePos token.Pos // identifier position
- Name string // identifier name
- Obj *Object // denoted object; or nil
- }
-
- // An Ellipsis node stands for the "..." type in a
- // parameter list or the "..." length in an array type.
- //
- Ellipsis struct {
- Ellipsis token.Pos // position of "..."
- Elt Expr // ellipsis element type (parameter lists only); or nil
- }
-
- // A BasicLit node represents a literal of basic type.
- BasicLit struct {
- ValuePos token.Pos // literal position
- Kind token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING
- Value string // literal string; e.g. 42, 0x7f, 3.14, 1e-9, 2.4i, 'a', '\x7f', "foo" or `\m\n\o`
- }
-
- // A FuncLit node represents a function literal.
- FuncLit struct {
- Type *FuncType // function type
- Body *BlockStmt // function body
- }
-
- // A CompositeLit node represents a composite literal.
- CompositeLit struct {
- Type Expr // literal type; or nil
- Lbrace token.Pos // position of "{"
- Elts []Expr // list of composite elements; or nil
- Rbrace token.Pos // position of "}"
- Incomplete bool // true if (source) expressions are missing in the Elts list
- }
-
- // A ParenExpr node represents a parenthesized expression.
- ParenExpr struct {
- Lparen token.Pos // position of "("
- X Expr // parenthesized expression
- Rparen token.Pos // position of ")"
- }
-
- // A SelectorExpr node represents an expression followed by a selector.
- SelectorExpr struct {
- X Expr // expression
- Sel *Ident // field selector
- }
-
- // An IndexExpr node represents an expression followed by an index.
- IndexExpr struct {
- X Expr // expression
- Lbrack token.Pos // position of "["
- Index Expr // index expression
- Rbrack token.Pos // position of "]"
- }
-
- // An IndexListExpr node represents an expression followed by multiple
- // indices.
- IndexListExpr struct {
- X Expr // expression
- Lbrack token.Pos // position of "["
- Indices []Expr // index expressions
- Rbrack token.Pos // position of "]"
- }
-
- // A SliceExpr node represents an expression followed by slice indices.
- SliceExpr struct {
- X Expr // expression
- Lbrack token.Pos // position of "["
- Low Expr // begin of slice range; or nil
- High Expr // end of slice range; or nil
- Max Expr // maximum capacity of slice; or nil
- Slice3 bool // true if 3-index slice (2 colons present)
- Rbrack token.Pos // position of "]"
- }
-
- // A TypeAssertExpr node represents an expression followed by a
- // type assertion.
- //
- TypeAssertExpr struct {
- X Expr // expression
- Lparen token.Pos // position of "("
- Type Expr // asserted type; nil means type switch X.(type)
- Rparen token.Pos // position of ")"
- }
-
- // A CallExpr node represents an expression followed by an argument list.
- CallExpr struct {
- Fun Expr // function expression
- Lparen token.Pos // position of "("
- Args []Expr // function arguments; or nil
- Ellipsis token.Pos // position of "..." (token.NoPos if there is no "...")
- Rparen token.Pos // position of ")"
- }
-
- // A StarExpr node represents an expression of the form "*" Expression.
- // Semantically it could be a unary "*" expression, or a pointer type.
- //
- StarExpr struct {
- Star token.Pos // position of "*"
- X Expr // operand
- }
-
- // A UnaryExpr node represents a unary expression.
- // Unary "*" expressions are represented via StarExpr nodes.
- //
- UnaryExpr struct {
- OpPos token.Pos // position of Op
- Op token.Token // operator
- X Expr // operand
- }
-
- // A BinaryExpr node represents a binary expression.
- BinaryExpr struct {
- X Expr // left operand
- OpPos token.Pos // position of Op
- Op token.Token // operator
- Y Expr // right operand
- }
-
- // A KeyValueExpr node represents (key : value) pairs
- // in composite literals.
- //
- KeyValueExpr struct {
- Key Expr
- Colon token.Pos // position of ":"
- Value Expr
- }
-)
-
-// The direction of a channel type is indicated by a bit
-// mask including one or both of the following constants.
-type ChanDir int
-
-const (
- SEND ChanDir = 1 << iota
- RECV
-)
-
-// A type is represented by a tree consisting of one
-// or more of the following type-specific expression
-// nodes.
-type (
- // An ArrayType node represents an array or slice type.
- ArrayType struct {
- Lbrack token.Pos // position of "["
- Len Expr // Ellipsis node for [...]T array types, nil for slice types
- Elt Expr // element type
- }
-
- // A StructType node represents a struct type.
- StructType struct {
- Struct token.Pos // position of "struct" keyword
- Fields *FieldList // list of field declarations
- Incomplete bool // true if (source) fields are missing in the Fields list
- }
-
- // Pointer types are represented via StarExpr nodes.
-
- // A FuncType node represents a function type.
- FuncType struct {
- Func token.Pos // position of "func" keyword (token.NoPos if there is no "func")
- TypeParams *FieldList // type parameters; or nil
- Params *FieldList // (incoming) parameters; non-nil
- Results *FieldList // (outgoing) results; or nil
- }
-
- // An InterfaceType node represents an interface type.
- InterfaceType struct {
- Interface token.Pos // position of "interface" keyword
- Methods *FieldList // list of embedded interfaces, methods, or types
- Incomplete bool // true if (source) methods or types are missing in the Methods list
- }
-
- // A MapType node represents a map type.
- MapType struct {
- Map token.Pos // position of "map" keyword
- Key Expr
- Value Expr
- }
-
- // A ChanType node represents a channel type.
- ChanType struct {
- Begin token.Pos // position of "chan" keyword or "<-" (whichever comes first)
- Arrow token.Pos // position of "<-" (token.NoPos if there is no "<-")
- Dir ChanDir // channel direction
- Value Expr // value type
- }
-)
-
-// Pos and End implementations for expression/type nodes.
-
-func (x *BadExpr) Pos() token.Pos { return x.From }
-func (x *Ident) Pos() token.Pos { return x.NamePos }
-func (x *Ellipsis) Pos() token.Pos { return x.Ellipsis }
-func (x *BasicLit) Pos() token.Pos { return x.ValuePos }
-func (x *FuncLit) Pos() token.Pos { return x.Type.Pos() }
-func (x *CompositeLit) Pos() token.Pos {
- if x.Type != nil {
- return x.Type.Pos()
- }
- return x.Lbrace
-}
-func (x *ParenExpr) Pos() token.Pos { return x.Lparen }
-func (x *SelectorExpr) Pos() token.Pos { return x.X.Pos() }
-func (x *IndexExpr) Pos() token.Pos { return x.X.Pos() }
-func (x *IndexListExpr) Pos() token.Pos { return x.X.Pos() }
-func (x *SliceExpr) Pos() token.Pos { return x.X.Pos() }
-func (x *TypeAssertExpr) Pos() token.Pos { return x.X.Pos() }
-func (x *CallExpr) Pos() token.Pos { return x.Fun.Pos() }
-func (x *StarExpr) Pos() token.Pos { return x.Star }
-func (x *UnaryExpr) Pos() token.Pos { return x.OpPos }
-func (x *BinaryExpr) Pos() token.Pos { return x.X.Pos() }
-func (x *KeyValueExpr) Pos() token.Pos { return x.Key.Pos() }
-func (x *ArrayType) Pos() token.Pos { return x.Lbrack }
-func (x *StructType) Pos() token.Pos { return x.Struct }
-func (x *FuncType) Pos() token.Pos {
- if x.Func.IsValid() || x.Params == nil { // see issue 3870
- return x.Func
- }
- return x.Params.Pos() // interface method declarations have no "func" keyword
-}
-func (x *InterfaceType) Pos() token.Pos { return x.Interface }
-func (x *MapType) Pos() token.Pos { return x.Map }
-func (x *ChanType) Pos() token.Pos { return x.Begin }
-
-func (x *BadExpr) End() token.Pos { return x.To }
-func (x *Ident) End() token.Pos { return token.Pos(int(x.NamePos) + len(x.Name)) }
-func (x *Ellipsis) End() token.Pos {
- if x.Elt != nil {
- return x.Elt.End()
- }
- return x.Ellipsis + 3 // len("...")
-}
-func (x *BasicLit) End() token.Pos { return token.Pos(int(x.ValuePos) + len(x.Value)) }
-func (x *FuncLit) End() token.Pos { return x.Body.End() }
-func (x *CompositeLit) End() token.Pos { return x.Rbrace + 1 }
-func (x *ParenExpr) End() token.Pos { return x.Rparen + 1 }
-func (x *SelectorExpr) End() token.Pos { return x.Sel.End() }
-func (x *IndexExpr) End() token.Pos { return x.Rbrack + 1 }
-func (x *IndexListExpr) End() token.Pos { return x.Rbrack + 1 }
-func (x *SliceExpr) End() token.Pos { return x.Rbrack + 1 }
-func (x *TypeAssertExpr) End() token.Pos { return x.Rparen + 1 }
-func (x *CallExpr) End() token.Pos { return x.Rparen + 1 }
-func (x *StarExpr) End() token.Pos { return x.X.End() }
-func (x *UnaryExpr) End() token.Pos { return x.X.End() }
-func (x *BinaryExpr) End() token.Pos { return x.Y.End() }
-func (x *KeyValueExpr) End() token.Pos { return x.Value.End() }
-func (x *ArrayType) End() token.Pos { return x.Elt.End() }
-func (x *StructType) End() token.Pos { return x.Fields.End() }
-func (x *FuncType) End() token.Pos {
- if x.Results != nil {
- return x.Results.End()
- }
- return x.Params.End()
-}
-func (x *InterfaceType) End() token.Pos { return x.Methods.End() }
-func (x *MapType) End() token.Pos { return x.Value.End() }
-func (x *ChanType) End() token.Pos { return x.Value.End() }
-
-// exprNode() ensures that only expression/type nodes can be
-// assigned to an Expr.
-func (*BadExpr) exprNode() {}
-func (*Ident) exprNode() {}
-func (*Ellipsis) exprNode() {}
-func (*BasicLit) exprNode() {}
-func (*FuncLit) exprNode() {}
-func (*CompositeLit) exprNode() {}
-func (*ParenExpr) exprNode() {}
-func (*SelectorExpr) exprNode() {}
-func (*IndexExpr) exprNode() {}
-func (*IndexListExpr) exprNode() {}
-func (*SliceExpr) exprNode() {}
-func (*TypeAssertExpr) exprNode() {}
-func (*CallExpr) exprNode() {}
-func (*StarExpr) exprNode() {}
-func (*UnaryExpr) exprNode() {}
-func (*BinaryExpr) exprNode() {}
-func (*KeyValueExpr) exprNode() {}
-
-func (*ArrayType) exprNode() {}
-func (*StructType) exprNode() {}
-func (*FuncType) exprNode() {}
-func (*InterfaceType) exprNode() {}
-func (*MapType) exprNode() {}
-func (*ChanType) exprNode() {}
-
-// ----------------------------------------------------------------------------
-// Convenience functions for Idents
-
-// NewIdent creates a new Ident without position.
-// Useful for ASTs generated by code other than the Go parser.
-func NewIdent(name string) *Ident { return &Ident{token.NoPos, name, nil} }
-
-// IsExported reports whether name starts with an upper-case letter.
-func IsExported(name string) bool { return token.IsExported(name) }
-
-// IsExported reports whether id starts with an upper-case letter.
-func (id *Ident) IsExported() bool { return token.IsExported(id.Name) }
-
-func (id *Ident) String() string {
- if id != nil {
- return id.Name
- }
- return "<nil>"
-}
-
-// ----------------------------------------------------------------------------
-// Statements
-
-// A statement is represented by a tree consisting of one
-// or more of the following concrete statement nodes.
-type (
- // A BadStmt node is a placeholder for statements containing
- // syntax errors for which no correct statement nodes can be
- // created.
- //
- BadStmt struct {
- From, To token.Pos // position range of bad statement
- }
-
- // A DeclStmt node represents a declaration in a statement list.
- DeclStmt struct {
- Decl Decl // *GenDecl with CONST, TYPE, or VAR token
- }
-
- // An EmptyStmt node represents an empty statement.
- // The "position" of the empty statement is the position
- // of the immediately following (explicit or implicit) semicolon.
- //
- EmptyStmt struct {
- Semicolon token.Pos // position of following ";"
- Implicit bool // if set, ";" was omitted in the source
- }
-
- // A LabeledStmt node represents a labeled statement.
- LabeledStmt struct {
- Label *Ident
- Colon token.Pos // position of ":"
- Stmt Stmt
- }
-
- // An ExprStmt node represents a (stand-alone) expression
- // in a statement list.
- //
- ExprStmt struct {
- X Expr // expression
- }
-
- // A SendStmt node represents a send statement.
- SendStmt struct {
- Chan Expr
- Arrow token.Pos // position of "<-"
- Value Expr
- }
-
- // An IncDecStmt node represents an increment or decrement statement.
- IncDecStmt struct {
- X Expr
- TokPos token.Pos // position of Tok
- Tok token.Token // INC or DEC
- }
-
- // An AssignStmt node represents an assignment or
- // a short variable declaration.
- //
- AssignStmt struct {
- Lhs []Expr
- TokPos token.Pos // position of Tok
- Tok token.Token // assignment token, DEFINE
- Rhs []Expr
- }
-
- // A GoStmt node represents a go statement.
- GoStmt struct {
- Go token.Pos // position of "go" keyword
- Call *CallExpr
- }
-
- // A DeferStmt node represents a defer statement.
- DeferStmt struct {
- Defer token.Pos // position of "defer" keyword
- Call *CallExpr
- }
-
- // A ReturnStmt node represents a return statement.
- ReturnStmt struct {
- Return token.Pos // position of "return" keyword
- Results []Expr // result expressions; or nil
- }
-
- // A BranchStmt node represents a break, continue, goto,
- // or fallthrough statement.
- //
- BranchStmt struct {
- TokPos token.Pos // position of Tok
- Tok token.Token // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
- Label *Ident // label name; or nil
- }
-
- // A BlockStmt node represents a braced statement list.
- BlockStmt struct {
- Lbrace token.Pos // position of "{"
- List []Stmt
- Rbrace token.Pos // position of "}", if any (may be absent due to syntax error)
- }
-
- // An IfStmt node represents an if statement.
- IfStmt struct {
- If token.Pos // position of "if" keyword
- Init Stmt // initialization statement; or nil
- Cond Expr // condition
- Body *BlockStmt
- Else Stmt // else branch; or nil
- }
-
- // A CaseClause represents a case of an expression or type switch statement.
- CaseClause struct {
- Case token.Pos // position of "case" or "default" keyword
- List []Expr // list of expressions or types; nil means default case
- Colon token.Pos // position of ":"
- Body []Stmt // statement list; or nil
- }
-
- // A SwitchStmt node represents an expression switch statement.
- SwitchStmt struct {
- Switch token.Pos // position of "switch" keyword
- Init Stmt // initialization statement; or nil
- Tag Expr // tag expression; or nil
- Body *BlockStmt // CaseClauses only
- }
-
- // A TypeSwitchStmt node represents a type switch statement.
- TypeSwitchStmt struct {
- Switch token.Pos // position of "switch" keyword
- Init Stmt // initialization statement; or nil
- Assign Stmt // x := y.(type) or y.(type)
- Body *BlockStmt // CaseClauses only
- }
-
- // A CommClause node represents a case of a select statement.
- CommClause struct {
- Case token.Pos // position of "case" or "default" keyword
- Comm Stmt // send or receive statement; nil means default case
- Colon token.Pos // position of ":"
- Body []Stmt // statement list; or nil
- }
-
- // A SelectStmt node represents a select statement.
- SelectStmt struct {
- Select token.Pos // position of "select" keyword
- Body *BlockStmt // CommClauses only
- }
-
- // A ForStmt represents a for statement.
- ForStmt struct {
- For token.Pos // position of "for" keyword
- Init Stmt // initialization statement; or nil
- Cond Expr // condition; or nil
- Post Stmt // post iteration statement; or nil
- Body *BlockStmt
- }
-
- // A RangeStmt represents a for statement with a range clause.
- RangeStmt struct {
- For token.Pos // position of "for" keyword
- Key, Value Expr // Key, Value may be nil
- TokPos token.Pos // position of Tok; invalid if Key == nil
- Tok token.Token // ILLEGAL if Key == nil, ASSIGN, DEFINE
- Range token.Pos // position of "range" keyword
- X Expr // value to range over
- Body *BlockStmt
- }
-)
-
-// Pos and End implementations for statement nodes.
-
-func (s *BadStmt) Pos() token.Pos { return s.From }
-func (s *DeclStmt) Pos() token.Pos { return s.Decl.Pos() }
-func (s *EmptyStmt) Pos() token.Pos { return s.Semicolon }
-func (s *LabeledStmt) Pos() token.Pos { return s.Label.Pos() }
-func (s *ExprStmt) Pos() token.Pos { return s.X.Pos() }
-func (s *SendStmt) Pos() token.Pos { return s.Chan.Pos() }
-func (s *IncDecStmt) Pos() token.Pos { return s.X.Pos() }
-func (s *AssignStmt) Pos() token.Pos { return s.Lhs[0].Pos() }
-func (s *GoStmt) Pos() token.Pos { return s.Go }
-func (s *DeferStmt) Pos() token.Pos { return s.Defer }
-func (s *ReturnStmt) Pos() token.Pos { return s.Return }
-func (s *BranchStmt) Pos() token.Pos { return s.TokPos }
-func (s *BlockStmt) Pos() token.Pos { return s.Lbrace }
-func (s *IfStmt) Pos() token.Pos { return s.If }
-func (s *CaseClause) Pos() token.Pos { return s.Case }
-func (s *SwitchStmt) Pos() token.Pos { return s.Switch }
-func (s *TypeSwitchStmt) Pos() token.Pos { return s.Switch }
-func (s *CommClause) Pos() token.Pos { return s.Case }
-func (s *SelectStmt) Pos() token.Pos { return s.Select }
-func (s *ForStmt) Pos() token.Pos { return s.For }
-func (s *RangeStmt) Pos() token.Pos { return s.For }
-
-func (s *BadStmt) End() token.Pos { return s.To }
-func (s *DeclStmt) End() token.Pos { return s.Decl.End() }
-func (s *EmptyStmt) End() token.Pos {
- if s.Implicit {
- return s.Semicolon
- }
- return s.Semicolon + 1 /* len(";") */
-}
-func (s *LabeledStmt) End() token.Pos { return s.Stmt.End() }
-func (s *ExprStmt) End() token.Pos { return s.X.End() }
-func (s *SendStmt) End() token.Pos { return s.Value.End() }
-func (s *IncDecStmt) End() token.Pos {
- return s.TokPos + 2 /* len("++") */
-}
-func (s *AssignStmt) End() token.Pos { return s.Rhs[len(s.Rhs)-1].End() }
-func (s *GoStmt) End() token.Pos { return s.Call.End() }
-func (s *DeferStmt) End() token.Pos { return s.Call.End() }
-func (s *ReturnStmt) End() token.Pos {
- if n := len(s.Results); n > 0 {
- return s.Results[n-1].End()
- }
- return s.Return + 6 // len("return")
-}
-func (s *BranchStmt) End() token.Pos {
- if s.Label != nil {
- return s.Label.End()
- }
- return token.Pos(int(s.TokPos) + len(s.Tok.String()))
-}
-func (s *BlockStmt) End() token.Pos {
- if s.Rbrace.IsValid() {
- return s.Rbrace + 1
- }
- if n := len(s.List); n > 0 {
- return s.List[n-1].End()
- }
- return s.Lbrace + 1
-}
-func (s *IfStmt) End() token.Pos {
- if s.Else != nil {
- return s.Else.End()
- }
- return s.Body.End()
-}
-func (s *CaseClause) End() token.Pos {
- if n := len(s.Body); n > 0 {
- return s.Body[n-1].End()
- }
- return s.Colon + 1
-}
-func (s *SwitchStmt) End() token.Pos { return s.Body.End() }
-func (s *TypeSwitchStmt) End() token.Pos { return s.Body.End() }
-func (s *CommClause) End() token.Pos {
- if n := len(s.Body); n > 0 {
- return s.Body[n-1].End()
- }
- return s.Colon + 1
-}
-func (s *SelectStmt) End() token.Pos { return s.Body.End() }
-func (s *ForStmt) End() token.Pos { return s.Body.End() }
-func (s *RangeStmt) End() token.Pos { return s.Body.End() }
-
-// stmtNode() ensures that only statement nodes can be
-// assigned to a Stmt.
-func (*BadStmt) stmtNode() {}
-func (*DeclStmt) stmtNode() {}
-func (*EmptyStmt) stmtNode() {}
-func (*LabeledStmt) stmtNode() {}
-func (*ExprStmt) stmtNode() {}
-func (*SendStmt) stmtNode() {}
-func (*IncDecStmt) stmtNode() {}
-func (*AssignStmt) stmtNode() {}
-func (*GoStmt) stmtNode() {}
-func (*DeferStmt) stmtNode() {}
-func (*ReturnStmt) stmtNode() {}
-func (*BranchStmt) stmtNode() {}
-func (*BlockStmt) stmtNode() {}
-func (*IfStmt) stmtNode() {}
-func (*CaseClause) stmtNode() {}
-func (*SwitchStmt) stmtNode() {}
-func (*TypeSwitchStmt) stmtNode() {}
-func (*CommClause) stmtNode() {}
-func (*SelectStmt) stmtNode() {}
-func (*ForStmt) stmtNode() {}
-func (*RangeStmt) stmtNode() {}
-
-// ----------------------------------------------------------------------------
-// Declarations
-
-// A Spec node represents a single (non-parenthesized) import,
-// constant, type, or variable declaration.
-type (
- // The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec.
- Spec interface {
- Node
- specNode()
- }
-
- // An ImportSpec node represents a single package import.
- ImportSpec struct {
- Doc *CommentGroup // associated documentation; or nil
- Name *Ident // local package name (including "."); or nil
- Path *BasicLit // import path
- Comment *CommentGroup // line comments; or nil
- EndPos token.Pos // end of spec (overrides Path.Pos if nonzero)
- }
-
- // A ValueSpec node represents a constant or variable declaration
- // (ConstSpec or VarSpec production).
- //
- ValueSpec struct {
- Doc *CommentGroup // associated documentation; or nil
- Names []*Ident // value names (len(Names) > 0)
- Type Expr // value type; or nil
- Values []Expr // initial values; or nil
- Comment *CommentGroup // line comments; or nil
- }
-
- // A TypeSpec node represents a type declaration (TypeSpec production).
- TypeSpec struct {
- Doc *CommentGroup // associated documentation; or nil
- Name *Ident // type name
- TypeParams *FieldList // type parameters; or nil
- Assign token.Pos // position of '=', if any
- Type Expr // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes
- Comment *CommentGroup // line comments; or nil
- }
-)
-
-// Pos and End implementations for spec nodes.
-
-func (s *ImportSpec) Pos() token.Pos {
- if s.Name != nil {
- return s.Name.Pos()
- }
- return s.Path.Pos()
-}
-func (s *ValueSpec) Pos() token.Pos { return s.Names[0].Pos() }
-func (s *TypeSpec) Pos() token.Pos { return s.Name.Pos() }
-
-func (s *ImportSpec) End() token.Pos {
- if s.EndPos != 0 {
- return s.EndPos
- }
- return s.Path.End()
-}
-
-func (s *ValueSpec) End() token.Pos {
- if n := len(s.Values); n > 0 {
- return s.Values[n-1].End()
- }
- if s.Type != nil {
- return s.Type.End()
- }
- return s.Names[len(s.Names)-1].End()
-}
-func (s *TypeSpec) End() token.Pos { return s.Type.End() }
-
-// specNode() ensures that only spec nodes can be
-// assigned to a Spec.
-func (*ImportSpec) specNode() {}
-func (*ValueSpec) specNode() {}
-func (*TypeSpec) specNode() {}
-
-// A declaration is represented by one of the following declaration nodes.
-type (
- // A BadDecl node is a placeholder for a declaration containing
- // syntax errors for which a correct declaration node cannot be
- // created.
- //
- BadDecl struct {
- From, To token.Pos // position range of bad declaration
- }
-
- // A GenDecl node (generic declaration node) represents an import,
- // constant, type or variable declaration. A valid Lparen position
- // (Lparen.IsValid()) indicates a parenthesized declaration.
- //
- // Relationship between Tok value and Specs element type:
- //
- // token.IMPORT *ImportSpec
- // token.CONST *ValueSpec
- // token.TYPE *TypeSpec
- // token.VAR *ValueSpec
- //
- GenDecl struct {
- Doc *CommentGroup // associated documentation; or nil
- TokPos token.Pos // position of Tok
- Tok token.Token // IMPORT, CONST, TYPE, or VAR
- Lparen token.Pos // position of '(', if any
- Specs []Spec
- Rparen token.Pos // position of ')', if any
- }
-
- // A FuncDecl node represents a function declaration.
- FuncDecl struct {
- Doc *CommentGroup // associated documentation; or nil
- Recv *FieldList // receiver (methods); or nil (functions)
- Name *Ident // function/method name
- Type *FuncType // function signature: type and value parameters, results, and position of "func" keyword
- Body *BlockStmt // function body; or nil for external (non-Go) function
- }
-)
-
-// Pos and End implementations for declaration nodes.
-
-func (d *BadDecl) Pos() token.Pos { return d.From }
-func (d *GenDecl) Pos() token.Pos { return d.TokPos }
-func (d *FuncDecl) Pos() token.Pos { return d.Type.Pos() }
-
-func (d *BadDecl) End() token.Pos { return d.To }
-func (d *GenDecl) End() token.Pos {
- if d.Rparen.IsValid() {
- return d.Rparen + 1
- }
- return d.Specs[0].End()
-}
-func (d *FuncDecl) End() token.Pos {
- if d.Body != nil {
- return d.Body.End()
- }
- return d.Type.End()
-}
-
-// declNode() ensures that only declaration nodes can be
-// assigned to a Decl.
-func (*BadDecl) declNode() {}
-func (*GenDecl) declNode() {}
-func (*FuncDecl) declNode() {}
-
-// ----------------------------------------------------------------------------
-// Files and packages
-
-// A File node represents a Go source file.
-//
-// The Comments list contains all comments in the source file in order of
-// appearance, including the comments that are pointed to from other nodes
-// via Doc and Comment fields.
-//
-// For correct printing of source code containing comments (using packages
-// go/format and go/printer), special care must be taken to update comments
-// when a File's syntax tree is modified: For printing, comments are interspersed
-// between tokens based on their position. If syntax tree nodes are
-// removed or moved, relevant comments in their vicinity must also be removed
-// (from the File.Comments list) or moved accordingly (by updating their
-// positions). A CommentMap may be used to facilitate some of these operations.
-//
-// Whether and how a comment is associated with a node depends on the
-// interpretation of the syntax tree by the manipulating program: Except for Doc
-// and Comment comments directly associated with nodes, the remaining comments
-// are "free-floating" (see also issues #18593, #20744).
-type File struct {
- Doc *CommentGroup // associated documentation; or nil
- Package token.Pos // position of "package" keyword
- Name *Ident // package name
- Decls []Decl // top-level declarations; or nil
-
- FileStart, FileEnd token.Pos // start and end of entire file
- Scope *Scope // package scope (this file only)
- Imports []*ImportSpec // imports in this file
- Unresolved []*Ident // unresolved identifiers in this file
- Comments []*CommentGroup // list of all comments in the source file
-}
-
-// Pos returns the position of the package declaration.
-// (Use FileStart for the start of the entire file.)
-func (f *File) Pos() token.Pos { return f.Package }
-
-// End returns the end of the last declaration in the file.
-// (Use FileEnd for the end of the entire file.)
-func (f *File) End() token.Pos {
- if n := len(f.Decls); n > 0 {
- return f.Decls[n-1].End()
- }
- return f.Name.End()
-}
-
-// A Package node represents a set of source files
-// collectively building a Go package.
-type Package struct {
- Name string // package name
- Scope *Scope // package scope across all files
- Imports map[string]*Object // map of package id -> package object
- Files map[string]*File // Go source files by filename
-}
-
-func (p *Package) Pos() token.Pos { return token.NoPos }
-func (p *Package) End() token.Pos { return token.NoPos }
diff --git a/contrib/go/_std_1.20/src/go/ast/filter.go b/contrib/go/_std_1.20/src/go/ast/filter.go
deleted file mode 100644
index 7d2a11e475..0000000000
--- a/contrib/go/_std_1.20/src/go/ast/filter.go
+++ /dev/null
@@ -1,495 +0,0 @@
-// Copyright 2009 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 ast
-
-import (
- "go/token"
- "sort"
-)
-
-// ----------------------------------------------------------------------------
-// Export filtering
-
-// exportFilter is a special filter function to extract exported nodes.
-func exportFilter(name string) bool {
- return IsExported(name)
-}
-
-// FileExports trims the AST for a Go source file in place such that
-// only exported nodes remain: all top-level identifiers which are not exported
-// and their associated information (such as type, initial value, or function
-// body) are removed. Non-exported fields and methods of exported types are
-// stripped. The File.Comments list is not changed.
-//
-// FileExports reports whether there are exported declarations.
-func FileExports(src *File) bool {
- return filterFile(src, exportFilter, true)
-}
-
-// PackageExports trims the AST for a Go package in place such that
-// only exported nodes remain. The pkg.Files list is not changed, so that
-// file names and top-level package comments don't get lost.
-//
-// PackageExports reports whether there are exported declarations;
-// it returns false otherwise.
-func PackageExports(pkg *Package) bool {
- return filterPackage(pkg, exportFilter, true)
-}
-
-// ----------------------------------------------------------------------------
-// General filtering
-
-type Filter func(string) bool
-
-func filterIdentList(list []*Ident, f Filter) []*Ident {
- j := 0
- for _, x := range list {
- if f(x.Name) {
- list[j] = x
- j++
- }
- }
- return list[0:j]
-}
-
-// fieldName assumes that x is the type of an anonymous field and
-// returns the corresponding field name. If x is not an acceptable
-// anonymous field, the result is nil.
-func fieldName(x Expr) *Ident {
- switch t := x.(type) {
- case *Ident:
- return t
- case *SelectorExpr:
- if _, ok := t.X.(*Ident); ok {
- return t.Sel
- }
- case *StarExpr:
- return fieldName(t.X)
- }
- return nil
-}
-
-func filterFieldList(fields *FieldList, filter Filter, export bool) (removedFields bool) {
- if fields == nil {
- return false
- }
- list := fields.List
- j := 0
- for _, f := range list {
- keepField := false
- if len(f.Names) == 0 {
- // anonymous field
- name := fieldName(f.Type)
- keepField = name != nil && filter(name.Name)
- } else {
- n := len(f.Names)
- f.Names = filterIdentList(f.Names, filter)
- if len(f.Names) < n {
- removedFields = true
- }
- keepField = len(f.Names) > 0
- }
- if keepField {
- if export {
- filterType(f.Type, filter, export)
- }
- list[j] = f
- j++
- }
- }
- if j < len(list) {
- removedFields = true
- }
- fields.List = list[0:j]
- return
-}
-
-func filterCompositeLit(lit *CompositeLit, filter Filter, export bool) {
- n := len(lit.Elts)
- lit.Elts = filterExprList(lit.Elts, filter, export)
- if len(lit.Elts) < n {
- lit.Incomplete = true
- }
-}
-
-func filterExprList(list []Expr, filter Filter, export bool) []Expr {
- j := 0
- for _, exp := range list {
- switch x := exp.(type) {
- case *CompositeLit:
- filterCompositeLit(x, filter, export)
- case *KeyValueExpr:
- if x, ok := x.Key.(*Ident); ok && !filter(x.Name) {
- continue
- }
- if x, ok := x.Value.(*CompositeLit); ok {
- filterCompositeLit(x, filter, export)
- }
- }
- list[j] = exp
- j++
- }
- return list[0:j]
-}
-
-func filterParamList(fields *FieldList, filter Filter, export bool) bool {
- if fields == nil {
- return false
- }
- var b bool
- for _, f := range fields.List {
- if filterType(f.Type, filter, export) {
- b = true
- }
- }
- return b
-}
-
-func filterType(typ Expr, f Filter, export bool) bool {
- switch t := typ.(type) {
- case *Ident:
- return f(t.Name)
- case *ParenExpr:
- return filterType(t.X, f, export)
- case *ArrayType:
- return filterType(t.Elt, f, export)
- case *StructType:
- if filterFieldList(t.Fields, f, export) {
- t.Incomplete = true
- }
- return len(t.Fields.List) > 0
- case *FuncType:
- b1 := filterParamList(t.Params, f, export)
- b2 := filterParamList(t.Results, f, export)
- return b1 || b2
- case *InterfaceType:
- if filterFieldList(t.Methods, f, export) {
- t.Incomplete = true
- }
- return len(t.Methods.List) > 0
- case *MapType:
- b1 := filterType(t.Key, f, export)
- b2 := filterType(t.Value, f, export)
- return b1 || b2
- case *ChanType:
- return filterType(t.Value, f, export)
- }
- return false
-}
-
-func filterSpec(spec Spec, f Filter, export bool) bool {
- switch s := spec.(type) {
- case *ValueSpec:
- s.Names = filterIdentList(s.Names, f)
- s.Values = filterExprList(s.Values, f, export)
- if len(s.Names) > 0 {
- if export {
- filterType(s.Type, f, export)
- }
- return true
- }
- case *TypeSpec:
- if f(s.Name.Name) {
- if export {
- filterType(s.Type, f, export)
- }
- return true
- }
- if !export {
- // For general filtering (not just exports),
- // filter type even if name is not filtered
- // out.
- // If the type contains filtered elements,
- // keep the declaration.
- return filterType(s.Type, f, export)
- }
- }
- return false
-}
-
-func filterSpecList(list []Spec, f Filter, export bool) []Spec {
- j := 0
- for _, s := range list {
- if filterSpec(s, f, export) {
- list[j] = s
- j++
- }
- }
- return list[0:j]
-}
-
-// FilterDecl trims the AST for a Go declaration in place by removing
-// all names (including struct field and interface method names, but
-// not from parameter lists) that don't pass through the filter f.
-//
-// FilterDecl reports whether there are any declared names left after
-// filtering.
-func FilterDecl(decl Decl, f Filter) bool {
- return filterDecl(decl, f, false)
-}
-
-func filterDecl(decl Decl, f Filter, export bool) bool {
- switch d := decl.(type) {
- case *GenDecl:
- d.Specs = filterSpecList(d.Specs, f, export)
- return len(d.Specs) > 0
- case *FuncDecl:
- return f(d.Name.Name)
- }
- return false
-}
-
-// FilterFile trims the AST for a Go file in place by removing all
-// names from top-level declarations (including struct field and
-// interface method names, but not from parameter lists) that don't
-// pass through the filter f. If the declaration is empty afterwards,
-// the declaration is removed from the AST. Import declarations are
-// always removed. The File.Comments list is not changed.
-//
-// FilterFile reports whether there are any top-level declarations
-// left after filtering.
-func FilterFile(src *File, f Filter) bool {
- return filterFile(src, f, false)
-}
-
-func filterFile(src *File, f Filter, export bool) bool {
- j := 0
- for _, d := range src.Decls {
- if filterDecl(d, f, export) {
- src.Decls[j] = d
- j++
- }
- }
- src.Decls = src.Decls[0:j]
- return j > 0
-}
-
-// FilterPackage trims the AST for a Go package in place by removing
-// all names from top-level declarations (including struct field and
-// interface method names, but not from parameter lists) that don't
-// pass through the filter f. If the declaration is empty afterwards,
-// the declaration is removed from the AST. The pkg.Files list is not
-// changed, so that file names and top-level package comments don't get
-// lost.
-//
-// FilterPackage reports whether there are any top-level declarations
-// left after filtering.
-func FilterPackage(pkg *Package, f Filter) bool {
- return filterPackage(pkg, f, false)
-}
-
-func filterPackage(pkg *Package, f Filter, export bool) bool {
- hasDecls := false
- for _, src := range pkg.Files {
- if filterFile(src, f, export) {
- hasDecls = true
- }
- }
- return hasDecls
-}
-
-// ----------------------------------------------------------------------------
-// Merging of package files
-
-// The MergeMode flags control the behavior of MergePackageFiles.
-type MergeMode uint
-
-const (
- // If set, duplicate function declarations are excluded.
- FilterFuncDuplicates MergeMode = 1 << iota
- // If set, comments that are not associated with a specific
- // AST node (as Doc or Comment) are excluded.
- FilterUnassociatedComments
- // If set, duplicate import declarations are excluded.
- FilterImportDuplicates
-)
-
-// nameOf returns the function (foo) or method name (foo.bar) for
-// the given function declaration. If the AST is incorrect for the
-// receiver, it assumes a function instead.
-func nameOf(f *FuncDecl) string {
- if r := f.Recv; r != nil && len(r.List) == 1 {
- // looks like a correct receiver declaration
- t := r.List[0].Type
- // dereference pointer receiver types
- if p, _ := t.(*StarExpr); p != nil {
- t = p.X
- }
- // the receiver type must be a type name
- if p, _ := t.(*Ident); p != nil {
- return p.Name + "." + f.Name.Name
- }
- // otherwise assume a function instead
- }
- return f.Name.Name
-}
-
-// separator is an empty //-style comment that is interspersed between
-// different comment groups when they are concatenated into a single group
-var separator = &Comment{token.NoPos, "//"}
-
-// MergePackageFiles creates a file AST by merging the ASTs of the
-// files belonging to a package. The mode flags control merging behavior.
-func MergePackageFiles(pkg *Package, mode MergeMode) *File {
- // Count the number of package docs, comments and declarations across
- // all package files. Also, compute sorted list of filenames, so that
- // subsequent iterations can always iterate in the same order.
- ndocs := 0
- ncomments := 0
- ndecls := 0
- filenames := make([]string, len(pkg.Files))
- var minPos, maxPos token.Pos
- i := 0
- for filename, f := range pkg.Files {
- filenames[i] = filename
- i++
- if f.Doc != nil {
- ndocs += len(f.Doc.List) + 1 // +1 for separator
- }
- ncomments += len(f.Comments)
- ndecls += len(f.Decls)
- if i == 0 || f.FileStart < minPos {
- minPos = f.FileStart
- }
- if i == 0 || f.FileEnd > maxPos {
- maxPos = f.FileEnd
- }
- }
- sort.Strings(filenames)
-
- // Collect package comments from all package files into a single
- // CommentGroup - the collected package documentation. In general
- // there should be only one file with a package comment; but it's
- // better to collect extra comments than drop them on the floor.
- var doc *CommentGroup
- var pos token.Pos
- if ndocs > 0 {
- list := make([]*Comment, ndocs-1) // -1: no separator before first group
- i := 0
- for _, filename := range filenames {
- f := pkg.Files[filename]
- if f.Doc != nil {
- if i > 0 {
- // not the first group - add separator
- list[i] = separator
- i++
- }
- for _, c := range f.Doc.List {
- list[i] = c
- i++
- }
- if f.Package > pos {
- // Keep the maximum package clause position as
- // position for the package clause of the merged
- // files.
- pos = f.Package
- }
- }
- }
- doc = &CommentGroup{list}
- }
-
- // Collect declarations from all package files.
- var decls []Decl
- if ndecls > 0 {
- decls = make([]Decl, ndecls)
- funcs := make(map[string]int) // map of func name -> decls index
- i := 0 // current index
- n := 0 // number of filtered entries
- for _, filename := range filenames {
- f := pkg.Files[filename]
- for _, d := range f.Decls {
- if mode&FilterFuncDuplicates != 0 {
- // A language entity may be declared multiple
- // times in different package files; only at
- // build time declarations must be unique.
- // For now, exclude multiple declarations of
- // functions - keep the one with documentation.
- //
- // TODO(gri): Expand this filtering to other
- // entities (const, type, vars) if
- // multiple declarations are common.
- if f, isFun := d.(*FuncDecl); isFun {
- name := nameOf(f)
- if j, exists := funcs[name]; exists {
- // function declared already
- if decls[j] != nil && decls[j].(*FuncDecl).Doc == nil {
- // existing declaration has no documentation;
- // ignore the existing declaration
- decls[j] = nil
- } else {
- // ignore the new declaration
- d = nil
- }
- n++ // filtered an entry
- } else {
- funcs[name] = i
- }
- }
- }
- decls[i] = d
- i++
- }
- }
-
- // Eliminate nil entries from the decls list if entries were
- // filtered. We do this using a 2nd pass in order to not disturb
- // the original declaration order in the source (otherwise, this
- // would also invalidate the monotonically increasing position
- // info within a single file).
- if n > 0 {
- i = 0
- for _, d := range decls {
- if d != nil {
- decls[i] = d
- i++
- }
- }
- decls = decls[0:i]
- }
- }
-
- // Collect import specs from all package files.
- var imports []*ImportSpec
- if mode&FilterImportDuplicates != 0 {
- seen := make(map[string]bool)
- for _, filename := range filenames {
- f := pkg.Files[filename]
- for _, imp := range f.Imports {
- if path := imp.Path.Value; !seen[path] {
- // TODO: consider handling cases where:
- // - 2 imports exist with the same import path but
- // have different local names (one should probably
- // keep both of them)
- // - 2 imports exist but only one has a comment
- // - 2 imports exist and they both have (possibly
- // different) comments
- imports = append(imports, imp)
- seen[path] = true
- }
- }
- }
- } else {
- // Iterate over filenames for deterministic order.
- for _, filename := range filenames {
- f := pkg.Files[filename]
- imports = append(imports, f.Imports...)
- }
- }
-
- // Collect comments from all package files.
- var comments []*CommentGroup
- if mode&FilterUnassociatedComments == 0 {
- comments = make([]*CommentGroup, ncomments)
- i := 0
- for _, filename := range filenames {
- f := pkg.Files[filename]
- i += copy(comments[i:], f.Comments)
- }
- }
-
- // TODO(gri) need to compute unresolved identifiers!
- return &File{doc, pos, NewIdent(pkg.Name), decls, minPos, maxPos, pkg.Scope, imports, nil, comments}
-}
diff --git a/contrib/go/_std_1.20/src/go/ast/ya.make b/contrib/go/_std_1.20/src/go/ast/ya.make
deleted file mode 100644
index c4a35eb4de..0000000000
--- a/contrib/go/_std_1.20/src/go/ast/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- ast.go
- commentmap.go
- filter.go
- import.go
- print.go
- resolve.go
- scope.go
- walk.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/build/build.go b/contrib/go/_std_1.20/src/go/build/build.go
deleted file mode 100644
index 420873c256..0000000000
--- a/contrib/go/_std_1.20/src/go/build/build.go
+++ /dev/null
@@ -1,2012 +0,0 @@
-// Copyright 2011 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 build
-
-import (
- "bytes"
- "errors"
- "fmt"
- "go/ast"
- "go/build/constraint"
- "go/doc"
- "go/token"
- "internal/buildcfg"
- "internal/godebug"
- "internal/goroot"
- "internal/goversion"
- "io"
- "io/fs"
- "os"
- "os/exec"
- pathpkg "path"
- "path/filepath"
- "runtime"
- "sort"
- "strconv"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-// A Context specifies the supporting context for a build.
-type Context struct {
- GOARCH string // target architecture
- GOOS string // target operating system
- GOROOT string // Go root
- GOPATH string // Go paths
-
- // Dir is the caller's working directory, or the empty string to use
- // the current directory of the running process. In module mode, this is used
- // to locate the main module.
- //
- // If Dir is non-empty, directories passed to Import and ImportDir must
- // be absolute.
- Dir string
-
- CgoEnabled bool // whether cgo files are included
- UseAllFiles bool // use files regardless of go:build lines, file names
- Compiler string // compiler to assume when computing target paths
-
- // The build, tool, and release tags specify build constraints
- // that should be considered satisfied when processing go:build lines.
- // Clients creating a new context may customize BuildTags, which
- // defaults to empty, but it is usually an error to customize ToolTags or ReleaseTags.
- // ToolTags defaults to build tags appropriate to the current Go toolchain configuration.
- // ReleaseTags defaults to the list of Go releases the current release is compatible with.
- // BuildTags is not set for the Default build Context.
- // In addition to the BuildTags, ToolTags, and ReleaseTags, build constraints
- // consider the values of GOARCH and GOOS as satisfied tags.
- // The last element in ReleaseTags is assumed to be the current release.
- BuildTags []string
- ToolTags []string
- ReleaseTags []string
-
- // The install suffix specifies a suffix to use in the name of the installation
- // directory. By default it is empty, but custom builds that need to keep
- // their outputs separate can set InstallSuffix to do so. For example, when
- // using the race detector, the go command uses InstallSuffix = "race", so
- // that on a Linux/386 system, packages are written to a directory named
- // "linux_386_race" instead of the usual "linux_386".
- InstallSuffix string
-
- // By default, Import uses the operating system's file system calls
- // to read directories and files. To read from other sources,
- // callers can set the following functions. They all have default
- // behaviors that use the local file system, so clients need only set
- // the functions whose behaviors they wish to change.
-
- // JoinPath joins the sequence of path fragments into a single path.
- // If JoinPath is nil, Import uses filepath.Join.
- JoinPath func(elem ...string) string
-
- // SplitPathList splits the path list into a slice of individual paths.
- // If SplitPathList is nil, Import uses filepath.SplitList.
- SplitPathList func(list string) []string
-
- // IsAbsPath reports whether path is an absolute path.
- // If IsAbsPath is nil, Import uses filepath.IsAbs.
- IsAbsPath func(path string) bool
-
- // IsDir reports whether the path names a directory.
- // If IsDir is nil, Import calls os.Stat and uses the result's IsDir method.
- IsDir func(path string) bool
-
- // HasSubdir reports whether dir is lexically a subdirectory of
- // root, perhaps multiple levels below. It does not try to check
- // whether dir exists.
- // If so, HasSubdir sets rel to a slash-separated path that
- // can be joined to root to produce a path equivalent to dir.
- // If HasSubdir is nil, Import uses an implementation built on
- // filepath.EvalSymlinks.
- HasSubdir func(root, dir string) (rel string, ok bool)
-
- // ReadDir returns a slice of fs.FileInfo, sorted by Name,
- // describing the content of the named directory.
- // If ReadDir is nil, Import uses os.ReadDir.
- ReadDir func(dir string) ([]fs.FileInfo, error)
-
- // OpenFile opens a file (not a directory) for reading.
- // If OpenFile is nil, Import uses os.Open.
- OpenFile func(path string) (io.ReadCloser, error)
-}
-
-// joinPath calls ctxt.JoinPath (if not nil) or else filepath.Join.
-func (ctxt *Context) joinPath(elem ...string) string {
- if f := ctxt.JoinPath; f != nil {
- return f(elem...)
- }
- return filepath.Join(elem...)
-}
-
-// splitPathList calls ctxt.SplitPathList (if not nil) or else filepath.SplitList.
-func (ctxt *Context) splitPathList(s string) []string {
- if f := ctxt.SplitPathList; f != nil {
- return f(s)
- }
- return filepath.SplitList(s)
-}
-
-// isAbsPath calls ctxt.IsAbsPath (if not nil) or else filepath.IsAbs.
-func (ctxt *Context) isAbsPath(path string) bool {
- if f := ctxt.IsAbsPath; f != nil {
- return f(path)
- }
- return filepath.IsAbs(path)
-}
-
-// isDir calls ctxt.IsDir (if not nil) or else uses os.Stat.
-func (ctxt *Context) isDir(path string) bool {
- if f := ctxt.IsDir; f != nil {
- return f(path)
- }
- fi, err := os.Stat(path)
- return err == nil && fi.IsDir()
-}
-
-// hasSubdir calls ctxt.HasSubdir (if not nil) or else uses
-// the local file system to answer the question.
-func (ctxt *Context) hasSubdir(root, dir string) (rel string, ok bool) {
- if f := ctxt.HasSubdir; f != nil {
- return f(root, dir)
- }
-
- // Try using paths we received.
- if rel, ok = hasSubdir(root, dir); ok {
- return
- }
-
- // Try expanding symlinks and comparing
- // expanded against unexpanded and
- // expanded against expanded.
- rootSym, _ := filepath.EvalSymlinks(root)
- dirSym, _ := filepath.EvalSymlinks(dir)
-
- if rel, ok = hasSubdir(rootSym, dir); ok {
- return
- }
- if rel, ok = hasSubdir(root, dirSym); ok {
- return
- }
- return hasSubdir(rootSym, dirSym)
-}
-
-// hasSubdir reports if dir is within root by performing lexical analysis only.
-func hasSubdir(root, dir string) (rel string, ok bool) {
- const sep = string(filepath.Separator)
- root = filepath.Clean(root)
- if !strings.HasSuffix(root, sep) {
- root += sep
- }
- dir = filepath.Clean(dir)
- after, found := strings.CutPrefix(dir, root)
- if !found {
- return "", false
- }
- return filepath.ToSlash(after), true
-}
-
-// readDir calls ctxt.ReadDir (if not nil) or else os.ReadDir.
-func (ctxt *Context) readDir(path string) ([]fs.DirEntry, error) {
- // TODO: add a fs.DirEntry version of Context.ReadDir
- if f := ctxt.ReadDir; f != nil {
- fis, err := f(path)
- if err != nil {
- return nil, err
- }
- des := make([]fs.DirEntry, len(fis))
- for i, fi := range fis {
- des[i] = fs.FileInfoToDirEntry(fi)
- }
- return des, nil
- }
- return os.ReadDir(path)
-}
-
-// openFile calls ctxt.OpenFile (if not nil) or else os.Open.
-func (ctxt *Context) openFile(path string) (io.ReadCloser, error) {
- if fn := ctxt.OpenFile; fn != nil {
- return fn(path)
- }
-
- f, err := os.Open(path)
- if err != nil {
- return nil, err // nil interface
- }
- return f, nil
-}
-
-// isFile determines whether path is a file by trying to open it.
-// It reuses openFile instead of adding another function to the
-// list in Context.
-func (ctxt *Context) isFile(path string) bool {
- f, err := ctxt.openFile(path)
- if err != nil {
- return false
- }
- f.Close()
- return true
-}
-
-// gopath returns the list of Go path directories.
-func (ctxt *Context) gopath() []string {
- var all []string
- for _, p := range ctxt.splitPathList(ctxt.GOPATH) {
- if p == "" || p == ctxt.GOROOT {
- // Empty paths are uninteresting.
- // If the path is the GOROOT, ignore it.
- // People sometimes set GOPATH=$GOROOT.
- // Do not get confused by this common mistake.
- continue
- }
- if strings.HasPrefix(p, "~") {
- // Path segments starting with ~ on Unix are almost always
- // users who have incorrectly quoted ~ while setting GOPATH,
- // preventing it from expanding to $HOME.
- // The situation is made more confusing by the fact that
- // bash allows quoted ~ in $PATH (most shells do not).
- // Do not get confused by this, and do not try to use the path.
- // It does not exist, and printing errors about it confuses
- // those users even more, because they think "sure ~ exists!".
- // The go command diagnoses this situation and prints a
- // useful error.
- // On Windows, ~ is used in short names, such as c:\progra~1
- // for c:\program files.
- continue
- }
- all = append(all, p)
- }
- return all
-}
-
-// SrcDirs returns a list of package source root directories.
-// It draws from the current Go root and Go path but omits directories
-// that do not exist.
-func (ctxt *Context) SrcDirs() []string {
- var all []string
- if ctxt.GOROOT != "" && ctxt.Compiler != "gccgo" {
- dir := ctxt.joinPath(ctxt.GOROOT, "src")
- if ctxt.isDir(dir) {
- all = append(all, dir)
- }
- }
- for _, p := range ctxt.gopath() {
- dir := ctxt.joinPath(p, "src")
- if ctxt.isDir(dir) {
- all = append(all, dir)
- }
- }
- return all
-}
-
-// Default is the default Context for builds.
-// It uses the GOARCH, GOOS, GOROOT, and GOPATH environment variables
-// if set, or else the compiled code's GOARCH, GOOS, and GOROOT.
-var Default Context = defaultContext()
-
-func defaultGOPATH() string {
- env := "HOME"
- if runtime.GOOS == "windows" {
- env = "USERPROFILE"
- } else if runtime.GOOS == "plan9" {
- env = "home"
- }
- if home := os.Getenv(env); home != "" {
- def := filepath.Join(home, "go")
- if filepath.Clean(def) == filepath.Clean(runtime.GOROOT()) {
- // Don't set the default GOPATH to GOROOT,
- // as that will trigger warnings from the go tool.
- return ""
- }
- return def
- }
- return ""
-}
-
-var defaultToolTags, defaultReleaseTags []string
-
-func defaultContext() Context {
- var c Context
-
- c.GOARCH = buildcfg.GOARCH
- c.GOOS = buildcfg.GOOS
- if goroot := runtime.GOROOT(); goroot != "" {
- c.GOROOT = filepath.Clean(goroot)
- }
- c.GOPATH = envOr("GOPATH", defaultGOPATH())
- c.Compiler = runtime.Compiler
- c.ToolTags = append(c.ToolTags, buildcfg.ToolTags...)
-
- defaultToolTags = append([]string{}, c.ToolTags...) // our own private copy
-
- // Each major Go release in the Go 1.x series adds a new
- // "go1.x" release tag. That is, the go1.x tag is present in
- // all releases >= Go 1.x. Code that requires Go 1.x or later
- // should say "go:build go1.x", and code that should only be
- // built before Go 1.x (perhaps it is the stub to use in that
- // case) should say "go:build !go1.x".
- // The last element in ReleaseTags is the current release.
- for i := 1; i <= goversion.Version; i++ {
- c.ReleaseTags = append(c.ReleaseTags, "go1."+strconv.Itoa(i))
- }
-
- defaultReleaseTags = append([]string{}, c.ReleaseTags...) // our own private copy
-
- env := os.Getenv("CGO_ENABLED")
- if env == "" {
- env = defaultCGO_ENABLED
- }
- switch env {
- case "1":
- c.CgoEnabled = true
- case "0":
- c.CgoEnabled = false
- default:
- // cgo must be explicitly enabled for cross compilation builds
- if runtime.GOARCH == c.GOARCH && runtime.GOOS == c.GOOS {
- c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH]
- break
- }
- c.CgoEnabled = false
- }
-
- return c
-}
-
-func envOr(name, def string) string {
- s := os.Getenv(name)
- if s == "" {
- return def
- }
- return s
-}
-
-// An ImportMode controls the behavior of the Import method.
-type ImportMode uint
-
-const (
- // If FindOnly is set, Import stops after locating the directory
- // that should contain the sources for a package. It does not
- // read any files in the directory.
- FindOnly ImportMode = 1 << iota
-
- // If AllowBinary is set, Import can be satisfied by a compiled
- // package object without corresponding sources.
- //
- // Deprecated:
- // The supported way to create a compiled-only package is to
- // write source code containing a //go:binary-only-package comment at
- // the top of the file. Such a package will be recognized
- // regardless of this flag setting (because it has source code)
- // and will have BinaryOnly set to true in the returned Package.
- AllowBinary
-
- // If ImportComment is set, parse import comments on package statements.
- // Import returns an error if it finds a comment it cannot understand
- // or finds conflicting comments in multiple source files.
- // See golang.org/s/go14customimport for more information.
- ImportComment
-
- // By default, Import searches vendor directories
- // that apply in the given source directory before searching
- // the GOROOT and GOPATH roots.
- // If an Import finds and returns a package using a vendor
- // directory, the resulting ImportPath is the complete path
- // to the package, including the path elements leading up
- // to and including "vendor".
- // For example, if Import("y", "x/subdir", 0) finds
- // "x/vendor/y", the returned package's ImportPath is "x/vendor/y",
- // not plain "y".
- // See golang.org/s/go15vendor for more information.
- //
- // Setting IgnoreVendor ignores vendor directories.
- //
- // In contrast to the package's ImportPath,
- // the returned package's Imports, TestImports, and XTestImports
- // are always the exact import paths from the source files:
- // Import makes no attempt to resolve or check those paths.
- IgnoreVendor
-)
-
-// A Package describes the Go package found in a directory.
-type Package struct {
- Dir string // directory containing package sources
- Name string // package name
- ImportComment string // path in import comment on package statement
- Doc string // documentation synopsis
- ImportPath string // import path of package ("" if unknown)
- Root string // root of Go tree where this package lives
- SrcRoot string // package source root directory ("" if unknown)
- PkgRoot string // package install root directory ("" if unknown)
- PkgTargetRoot string // architecture dependent install root directory ("" if unknown)
- BinDir string // command install directory ("" if unknown)
- Goroot bool // package found in Go root
- PkgObj string // installed .a file
- AllTags []string // tags that can influence file selection in this directory
- ConflictDir string // this directory shadows Dir in $GOPATH
- BinaryOnly bool // cannot be rebuilt from source (has //go:binary-only-package comment)
-
- // Source files
- GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
- CgoFiles []string // .go source files that import "C"
- IgnoredGoFiles []string // .go source files ignored for this build (including ignored _test.go files)
- InvalidGoFiles []string // .go source files with detected problems (parse error, wrong package name, and so on)
- IgnoredOtherFiles []string // non-.go source files ignored for this build
- CFiles []string // .c source files
- CXXFiles []string // .cc, .cpp and .cxx source files
- MFiles []string // .m (Objective-C) source files
- HFiles []string // .h, .hh, .hpp and .hxx source files
- FFiles []string // .f, .F, .for and .f90 Fortran source files
- SFiles []string // .s source files
- SwigFiles []string // .swig files
- SwigCXXFiles []string // .swigcxx files
- SysoFiles []string // .syso system object files to add to archive
-
- // Cgo directives
- CgoCFLAGS []string // Cgo CFLAGS directives
- CgoCPPFLAGS []string // Cgo CPPFLAGS directives
- CgoCXXFLAGS []string // Cgo CXXFLAGS directives
- CgoFFLAGS []string // Cgo FFLAGS directives
- CgoLDFLAGS []string // Cgo LDFLAGS directives
- CgoPkgConfig []string // Cgo pkg-config directives
-
- // Test information
- TestGoFiles []string // _test.go files in package
- XTestGoFiles []string // _test.go files outside package
-
- // Dependency information
- Imports []string // import paths from GoFiles, CgoFiles
- ImportPos map[string][]token.Position // line information for Imports
- TestImports []string // import paths from TestGoFiles
- TestImportPos map[string][]token.Position // line information for TestImports
- XTestImports []string // import paths from XTestGoFiles
- XTestImportPos map[string][]token.Position // line information for XTestImports
-
- // //go:embed patterns found in Go source files
- // For example, if a source file says
- // //go:embed a* b.c
- // then the list will contain those two strings as separate entries.
- // (See package embed for more details about //go:embed.)
- EmbedPatterns []string // patterns from GoFiles, CgoFiles
- EmbedPatternPos map[string][]token.Position // line information for EmbedPatterns
- TestEmbedPatterns []string // patterns from TestGoFiles
- TestEmbedPatternPos map[string][]token.Position // line information for TestEmbedPatterns
- XTestEmbedPatterns []string // patterns from XTestGoFiles
- XTestEmbedPatternPos map[string][]token.Position // line information for XTestEmbedPatternPos
-}
-
-// IsCommand reports whether the package is considered a
-// command to be installed (not just a library).
-// Packages named "main" are treated as commands.
-func (p *Package) IsCommand() bool {
- return p.Name == "main"
-}
-
-// ImportDir is like Import but processes the Go package found in
-// the named directory.
-func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error) {
- return ctxt.Import(".", dir, mode)
-}
-
-// NoGoError is the error used by Import to describe a directory
-// containing no buildable Go source files. (It may still contain
-// test files, files hidden by build tags, and so on.)
-type NoGoError struct {
- Dir string
-}
-
-func (e *NoGoError) Error() string {
- return "no buildable Go source files in " + e.Dir
-}
-
-// MultiplePackageError describes a directory containing
-// multiple buildable Go source files for multiple packages.
-type MultiplePackageError struct {
- Dir string // directory containing files
- Packages []string // package names found
- Files []string // corresponding files: Files[i] declares package Packages[i]
-}
-
-func (e *MultiplePackageError) Error() string {
- // Error string limited to two entries for compatibility.
- return fmt.Sprintf("found packages %s (%s) and %s (%s) in %s", e.Packages[0], e.Files[0], e.Packages[1], e.Files[1], e.Dir)
-}
-
-func nameExt(name string) string {
- i := strings.LastIndex(name, ".")
- if i < 0 {
- return ""
- }
- return name[i:]
-}
-
-var installgoroot = godebug.New("installgoroot")
-
-// Import returns details about the Go package named by the import path,
-// interpreting local import paths relative to the srcDir directory.
-// If the path is a local import path naming a package that can be imported
-// using a standard import path, the returned package will set p.ImportPath
-// to that path.
-//
-// In the directory containing the package, .go, .c, .h, and .s files are
-// considered part of the package except for:
-//
-// - .go files in package documentation
-// - files starting with _ or . (likely editor temporary files)
-// - files with build constraints not satisfied by the context
-//
-// If an error occurs, Import returns a non-nil error and a non-nil
-// *Package containing partial information.
-func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error) {
- p := &Package{
- ImportPath: path,
- }
- if path == "" {
- return p, fmt.Errorf("import %q: invalid import path", path)
- }
-
- var pkgtargetroot string
- var pkga string
- var pkgerr error
- suffix := ""
- if ctxt.InstallSuffix != "" {
- suffix = "_" + ctxt.InstallSuffix
- }
- switch ctxt.Compiler {
- case "gccgo":
- pkgtargetroot = "pkg/gccgo_" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
- case "gc":
- pkgtargetroot = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
- default:
- // Save error for end of function.
- pkgerr = fmt.Errorf("import %q: unknown compiler %q", path, ctxt.Compiler)
- }
- setPkga := func() {
- switch ctxt.Compiler {
- case "gccgo":
- dir, elem := pathpkg.Split(p.ImportPath)
- pkga = pkgtargetroot + "/" + dir + "lib" + elem + ".a"
- case "gc":
- pkga = pkgtargetroot + "/" + p.ImportPath + ".a"
- }
- }
- setPkga()
-
- binaryOnly := false
- if IsLocalImport(path) {
- pkga = "" // local imports have no installed path
- if srcDir == "" {
- return p, fmt.Errorf("import %q: import relative to unknown directory", path)
- }
- if !ctxt.isAbsPath(path) {
- p.Dir = ctxt.joinPath(srcDir, path)
- }
- // p.Dir directory may or may not exist. Gather partial information first, check if it exists later.
- // Determine canonical import path, if any.
- // Exclude results where the import path would include /testdata/.
- inTestdata := func(sub string) bool {
- return strings.Contains(sub, "/testdata/") || strings.HasSuffix(sub, "/testdata") || strings.HasPrefix(sub, "testdata/") || sub == "testdata"
- }
- if ctxt.GOROOT != "" {
- root := ctxt.joinPath(ctxt.GOROOT, "src")
- if sub, ok := ctxt.hasSubdir(root, p.Dir); ok && !inTestdata(sub) {
- p.Goroot = true
- p.ImportPath = sub
- p.Root = ctxt.GOROOT
- setPkga() // p.ImportPath changed
- goto Found
- }
- }
- all := ctxt.gopath()
- for i, root := range all {
- rootsrc := ctxt.joinPath(root, "src")
- if sub, ok := ctxt.hasSubdir(rootsrc, p.Dir); ok && !inTestdata(sub) {
- // We found a potential import path for dir,
- // but check that using it wouldn't find something
- // else first.
- if ctxt.GOROOT != "" && ctxt.Compiler != "gccgo" {
- if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) {
- p.ConflictDir = dir
- goto Found
- }
- }
- for _, earlyRoot := range all[:i] {
- if dir := ctxt.joinPath(earlyRoot, "src", sub); ctxt.isDir(dir) {
- p.ConflictDir = dir
- goto Found
- }
- }
-
- // sub would not name some other directory instead of this one.
- // Record it.
- p.ImportPath = sub
- p.Root = root
- setPkga() // p.ImportPath changed
- goto Found
- }
- }
- // It's okay that we didn't find a root containing dir.
- // Keep going with the information we have.
- } else {
- if strings.HasPrefix(path, "/") {
- return p, fmt.Errorf("import %q: cannot import absolute path", path)
- }
-
- if err := ctxt.importGo(p, path, srcDir, mode); err == nil {
- goto Found
- } else if err != errNoModules {
- return p, err
- }
-
- gopath := ctxt.gopath() // needed twice below; avoid computing many times
-
- // tried records the location of unsuccessful package lookups
- var tried struct {
- vendor []string
- goroot string
- gopath []string
- }
-
- // Vendor directories get first chance to satisfy import.
- if mode&IgnoreVendor == 0 && srcDir != "" {
- searchVendor := func(root string, isGoroot bool) bool {
- sub, ok := ctxt.hasSubdir(root, srcDir)
- if !ok || !strings.HasPrefix(sub, "src/") || strings.Contains(sub, "/testdata/") {
- return false
- }
- for {
- vendor := ctxt.joinPath(root, sub, "vendor")
- if ctxt.isDir(vendor) {
- dir := ctxt.joinPath(vendor, path)
- if ctxt.isDir(dir) && hasGoFiles(ctxt, dir) {
- p.Dir = dir
- p.ImportPath = strings.TrimPrefix(pathpkg.Join(sub, "vendor", path), "src/")
- p.Goroot = isGoroot
- p.Root = root
- setPkga() // p.ImportPath changed
- return true
- }
- tried.vendor = append(tried.vendor, dir)
- }
- i := strings.LastIndex(sub, "/")
- if i < 0 {
- break
- }
- sub = sub[:i]
- }
- return false
- }
- if ctxt.Compiler != "gccgo" && ctxt.GOROOT != "" && searchVendor(ctxt.GOROOT, true) {
- goto Found
- }
- for _, root := range gopath {
- if searchVendor(root, false) {
- goto Found
- }
- }
- }
-
- // Determine directory from import path.
- if ctxt.GOROOT != "" {
- // If the package path starts with "vendor/", only search GOROOT before
- // GOPATH if the importer is also within GOROOT. That way, if the user has
- // vendored in a package that is subsequently included in the standard
- // distribution, they'll continue to pick up their own vendored copy.
- gorootFirst := srcDir == "" || !strings.HasPrefix(path, "vendor/")
- if !gorootFirst {
- _, gorootFirst = ctxt.hasSubdir(ctxt.GOROOT, srcDir)
- }
- if gorootFirst {
- dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
- if ctxt.Compiler != "gccgo" {
- isDir := ctxt.isDir(dir)
- binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
- if isDir || binaryOnly {
- p.Dir = dir
- p.Goroot = true
- p.Root = ctxt.GOROOT
- goto Found
- }
- }
- tried.goroot = dir
- }
- if ctxt.Compiler == "gccgo" && goroot.IsStandardPackage(ctxt.GOROOT, ctxt.Compiler, path) {
- // TODO(bcmills): Setting p.Dir here is misleading, because gccgo
- // doesn't actually load its standard-library packages from this
- // directory. See if we can leave it unset.
- p.Dir = ctxt.joinPath(ctxt.GOROOT, "src", path)
- p.Goroot = true
- p.Root = ctxt.GOROOT
- goto Found
- }
- }
- for _, root := range gopath {
- dir := ctxt.joinPath(root, "src", path)
- isDir := ctxt.isDir(dir)
- binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(root, pkga))
- if isDir || binaryOnly {
- p.Dir = dir
- p.Root = root
- goto Found
- }
- tried.gopath = append(tried.gopath, dir)
- }
-
- // If we tried GOPATH first due to a "vendor/" prefix, fall back to GOPATH.
- // That way, the user can still get useful results from 'go list' for
- // standard-vendored paths passed on the command line.
- if ctxt.GOROOT != "" && tried.goroot == "" {
- dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
- if ctxt.Compiler != "gccgo" {
- isDir := ctxt.isDir(dir)
- binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
- if isDir || binaryOnly {
- p.Dir = dir
- p.Goroot = true
- p.Root = ctxt.GOROOT
- goto Found
- }
- }
- tried.goroot = dir
- }
-
- // package was not found
- var paths []string
- format := "\t%s (vendor tree)"
- for _, dir := range tried.vendor {
- paths = append(paths, fmt.Sprintf(format, dir))
- format = "\t%s"
- }
- if tried.goroot != "" {
- paths = append(paths, fmt.Sprintf("\t%s (from $GOROOT)", tried.goroot))
- } else {
- paths = append(paths, "\t($GOROOT not set)")
- }
- format = "\t%s (from $GOPATH)"
- for _, dir := range tried.gopath {
- paths = append(paths, fmt.Sprintf(format, dir))
- format = "\t%s"
- }
- if len(tried.gopath) == 0 {
- paths = append(paths, "\t($GOPATH not set. For more details see: 'go help gopath')")
- }
- return p, fmt.Errorf("cannot find package %q in any of:\n%s", path, strings.Join(paths, "\n"))
- }
-
-Found:
- if p.Root != "" {
- p.SrcRoot = ctxt.joinPath(p.Root, "src")
- p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
- p.BinDir = ctxt.joinPath(p.Root, "bin")
- if pkga != "" {
- // Always set PkgTargetRoot. It might be used when building in shared
- // mode.
- p.PkgTargetRoot = ctxt.joinPath(p.Root, pkgtargetroot)
-
- // Set the install target if applicable.
- if !p.Goroot || (installgoroot.Value() == "all" && p.ImportPath != "unsafe" && p.ImportPath != "builtin") {
- p.PkgObj = ctxt.joinPath(p.Root, pkga)
- }
- }
- }
-
- // If it's a local import path, by the time we get here, we still haven't checked
- // that p.Dir directory exists. This is the right time to do that check.
- // We can't do it earlier, because we want to gather partial information for the
- // non-nil *Package returned when an error occurs.
- // We need to do this before we return early on FindOnly flag.
- if IsLocalImport(path) && !ctxt.isDir(p.Dir) {
- if ctxt.Compiler == "gccgo" && p.Goroot {
- // gccgo has no sources for GOROOT packages.
- return p, nil
- }
-
- // package was not found
- return p, fmt.Errorf("cannot find package %q in:\n\t%s", p.ImportPath, p.Dir)
- }
-
- if mode&FindOnly != 0 {
- return p, pkgerr
- }
- if binaryOnly && (mode&AllowBinary) != 0 {
- return p, pkgerr
- }
-
- if ctxt.Compiler == "gccgo" && p.Goroot {
- // gccgo has no sources for GOROOT packages.
- return p, nil
- }
-
- dirs, err := ctxt.readDir(p.Dir)
- if err != nil {
- return p, err
- }
-
- var badGoError error
- badGoFiles := make(map[string]bool)
- badGoFile := func(name string, err error) {
- if badGoError == nil {
- badGoError = err
- }
- if !badGoFiles[name] {
- p.InvalidGoFiles = append(p.InvalidGoFiles, name)
- badGoFiles[name] = true
- }
- }
-
- var Sfiles []string // files with ".S"(capital S)/.sx(capital s equivalent for case insensitive filesystems)
- var firstFile, firstCommentFile string
- embedPos := make(map[string][]token.Position)
- testEmbedPos := make(map[string][]token.Position)
- xTestEmbedPos := make(map[string][]token.Position)
- importPos := make(map[string][]token.Position)
- testImportPos := make(map[string][]token.Position)
- xTestImportPos := make(map[string][]token.Position)
- allTags := make(map[string]bool)
- fset := token.NewFileSet()
- for _, d := range dirs {
- if d.IsDir() {
- continue
- }
- if d.Type() == fs.ModeSymlink {
- if ctxt.isDir(ctxt.joinPath(p.Dir, d.Name())) {
- // Symlinks to directories are not source files.
- continue
- }
- }
-
- name := d.Name()
- ext := nameExt(name)
-
- info, err := ctxt.matchFile(p.Dir, name, allTags, &p.BinaryOnly, fset)
- if err != nil && strings.HasSuffix(name, ".go") {
- badGoFile(name, err)
- continue
- }
- if info == nil {
- if strings.HasPrefix(name, "_") || strings.HasPrefix(name, ".") {
- // not due to build constraints - don't report
- } else if ext == ".go" {
- p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
- } else if fileListForExt(p, ext) != nil {
- p.IgnoredOtherFiles = append(p.IgnoredOtherFiles, name)
- }
- continue
- }
-
- // Going to save the file. For non-Go files, can stop here.
- switch ext {
- case ".go":
- // keep going
- case ".S", ".sx":
- // special case for cgo, handled at end
- Sfiles = append(Sfiles, name)
- continue
- default:
- if list := fileListForExt(p, ext); list != nil {
- *list = append(*list, name)
- }
- continue
- }
-
- data, filename := info.header, info.name
-
- if info.parseErr != nil {
- badGoFile(name, info.parseErr)
- // Fall through: we might still have a partial AST in info.parsed,
- // and we want to list files with parse errors anyway.
- }
-
- var pkg string
- if info.parsed != nil {
- pkg = info.parsed.Name.Name
- if pkg == "documentation" {
- p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
- continue
- }
- }
-
- isTest := strings.HasSuffix(name, "_test.go")
- isXTest := false
- if isTest && strings.HasSuffix(pkg, "_test") && p.Name != pkg {
- isXTest = true
- pkg = pkg[:len(pkg)-len("_test")]
- }
-
- if p.Name == "" {
- p.Name = pkg
- firstFile = name
- } else if pkg != p.Name {
- // TODO(#45999): The choice of p.Name is arbitrary based on file iteration
- // order. Instead of resolving p.Name arbitrarily, we should clear out the
- // existing name and mark the existing files as also invalid.
- badGoFile(name, &MultiplePackageError{
- Dir: p.Dir,
- Packages: []string{p.Name, pkg},
- Files: []string{firstFile, name},
- })
- }
- // Grab the first package comment as docs, provided it is not from a test file.
- if info.parsed != nil && info.parsed.Doc != nil && p.Doc == "" && !isTest && !isXTest {
- p.Doc = doc.Synopsis(info.parsed.Doc.Text())
- }
-
- if mode&ImportComment != 0 {
- qcom, line := findImportComment(data)
- if line != 0 {
- com, err := strconv.Unquote(qcom)
- if err != nil {
- badGoFile(name, fmt.Errorf("%s:%d: cannot parse import comment", filename, line))
- } else if p.ImportComment == "" {
- p.ImportComment = com
- firstCommentFile = name
- } else if p.ImportComment != com {
- badGoFile(name, fmt.Errorf("found import comments %q (%s) and %q (%s) in %s", p.ImportComment, firstCommentFile, com, name, p.Dir))
- }
- }
- }
-
- // Record imports and information about cgo.
- isCgo := false
- for _, imp := range info.imports {
- if imp.path == "C" {
- if isTest {
- badGoFile(name, fmt.Errorf("use of cgo in test %s not supported", filename))
- continue
- }
- isCgo = true
- if imp.doc != nil {
- if err := ctxt.saveCgo(filename, p, imp.doc); err != nil {
- badGoFile(name, err)
- }
- }
- }
- }
-
- var fileList *[]string
- var importMap, embedMap map[string][]token.Position
- switch {
- case isCgo:
- allTags["cgo"] = true
- if ctxt.CgoEnabled {
- fileList = &p.CgoFiles
- importMap = importPos
- embedMap = embedPos
- } else {
- // Ignore imports and embeds from cgo files if cgo is disabled.
- fileList = &p.IgnoredGoFiles
- }
- case isXTest:
- fileList = &p.XTestGoFiles
- importMap = xTestImportPos
- embedMap = xTestEmbedPos
- case isTest:
- fileList = &p.TestGoFiles
- importMap = testImportPos
- embedMap = testEmbedPos
- default:
- fileList = &p.GoFiles
- importMap = importPos
- embedMap = embedPos
- }
- *fileList = append(*fileList, name)
- if importMap != nil {
- for _, imp := range info.imports {
- importMap[imp.path] = append(importMap[imp.path], fset.Position(imp.pos))
- }
- }
- if embedMap != nil {
- for _, emb := range info.embeds {
- embedMap[emb.pattern] = append(embedMap[emb.pattern], emb.pos)
- }
- }
- }
-
- for tag := range allTags {
- p.AllTags = append(p.AllTags, tag)
- }
- sort.Strings(p.AllTags)
-
- p.EmbedPatterns, p.EmbedPatternPos = cleanDecls(embedPos)
- p.TestEmbedPatterns, p.TestEmbedPatternPos = cleanDecls(testEmbedPos)
- p.XTestEmbedPatterns, p.XTestEmbedPatternPos = cleanDecls(xTestEmbedPos)
-
- p.Imports, p.ImportPos = cleanDecls(importPos)
- p.TestImports, p.TestImportPos = cleanDecls(testImportPos)
- p.XTestImports, p.XTestImportPos = cleanDecls(xTestImportPos)
-
- // add the .S/.sx files only if we are using cgo
- // (which means gcc will compile them).
- // The standard assemblers expect .s files.
- if len(p.CgoFiles) > 0 {
- p.SFiles = append(p.SFiles, Sfiles...)
- sort.Strings(p.SFiles)
- } else {
- p.IgnoredOtherFiles = append(p.IgnoredOtherFiles, Sfiles...)
- sort.Strings(p.IgnoredOtherFiles)
- }
-
- if badGoError != nil {
- return p, badGoError
- }
- if len(p.GoFiles)+len(p.CgoFiles)+len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
- return p, &NoGoError{p.Dir}
- }
- return p, pkgerr
-}
-
-func fileListForExt(p *Package, ext string) *[]string {
- switch ext {
- case ".c":
- return &p.CFiles
- case ".cc", ".cpp", ".cxx":
- return &p.CXXFiles
- case ".m":
- return &p.MFiles
- case ".h", ".hh", ".hpp", ".hxx":
- return &p.HFiles
- case ".f", ".F", ".for", ".f90":
- return &p.FFiles
- case ".s", ".S", ".sx":
- return &p.SFiles
- case ".swig":
- return &p.SwigFiles
- case ".swigcxx":
- return &p.SwigCXXFiles
- case ".syso":
- return &p.SysoFiles
- }
- return nil
-}
-
-func uniq(list []string) []string {
- if list == nil {
- return nil
- }
- out := make([]string, len(list))
- copy(out, list)
- sort.Strings(out)
- uniq := out[:0]
- for _, x := range out {
- if len(uniq) == 0 || uniq[len(uniq)-1] != x {
- uniq = append(uniq, x)
- }
- }
- return uniq
-}
-
-var errNoModules = errors.New("not using modules")
-
-// importGo checks whether it can use the go command to find the directory for path.
-// If using the go command is not appropriate, importGo returns errNoModules.
-// Otherwise, importGo tries using the go command and reports whether that succeeded.
-// Using the go command lets build.Import and build.Context.Import find code
-// in Go modules. In the long term we want tools to use go/packages (currently golang.org/x/tools/go/packages),
-// which will also use the go command.
-// Invoking the go command here is not very efficient in that it computes information
-// about the requested package and all dependencies and then only reports about the requested package.
-// Then we reinvoke it for every dependency. But this is still better than not working at all.
-// See golang.org/issue/26504.
-func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode) error {
- // To invoke the go command,
- // we must not being doing special things like AllowBinary or IgnoreVendor,
- // and all the file system callbacks must be nil (we're meant to use the local file system).
- if mode&AllowBinary != 0 || mode&IgnoreVendor != 0 ||
- ctxt.JoinPath != nil || ctxt.SplitPathList != nil || ctxt.IsAbsPath != nil || ctxt.IsDir != nil || ctxt.HasSubdir != nil || ctxt.ReadDir != nil || ctxt.OpenFile != nil || !equal(ctxt.ToolTags, defaultToolTags) || !equal(ctxt.ReleaseTags, defaultReleaseTags) {
- return errNoModules
- }
-
- // If ctxt.GOROOT is not set, we don't know which go command to invoke,
- // and even if we did we might return packages in GOROOT that we wouldn't otherwise find
- // (because we don't know to search in 'go env GOROOT' otherwise).
- if ctxt.GOROOT == "" {
- return errNoModules
- }
-
- // Predict whether module aware mode is enabled by checking the value of
- // GO111MODULE and looking for a go.mod file in the source directory or
- // one of its parents. Running 'go env GOMOD' in the source directory would
- // give a canonical answer, but we'd prefer not to execute another command.
- go111Module := os.Getenv("GO111MODULE")
- switch go111Module {
- case "off":
- return errNoModules
- default: // "", "on", "auto", anything else
- // Maybe use modules.
- }
-
- if srcDir != "" {
- var absSrcDir string
- if filepath.IsAbs(srcDir) {
- absSrcDir = srcDir
- } else if ctxt.Dir != "" {
- return fmt.Errorf("go/build: Dir is non-empty, so relative srcDir is not allowed: %v", srcDir)
- } else {
- // Find the absolute source directory. hasSubdir does not handle
- // relative paths (and can't because the callbacks don't support this).
- var err error
- absSrcDir, err = filepath.Abs(srcDir)
- if err != nil {
- return errNoModules
- }
- }
-
- // If the source directory is in GOROOT, then the in-process code works fine
- // and we should keep using it. Moreover, the 'go list' approach below doesn't
- // take standard-library vendoring into account and will fail.
- if _, ok := ctxt.hasSubdir(filepath.Join(ctxt.GOROOT, "src"), absSrcDir); ok {
- return errNoModules
- }
- }
-
- // For efficiency, if path is a standard library package, let the usual lookup code handle it.
- if dir := ctxt.joinPath(ctxt.GOROOT, "src", path); ctxt.isDir(dir) {
- return errNoModules
- }
-
- // If GO111MODULE=auto, look to see if there is a go.mod.
- // Since go1.13, it doesn't matter if we're inside GOPATH.
- if go111Module == "auto" {
- var (
- parent string
- err error
- )
- if ctxt.Dir == "" {
- parent, err = os.Getwd()
- if err != nil {
- // A nonexistent working directory can't be in a module.
- return errNoModules
- }
- } else {
- parent, err = filepath.Abs(ctxt.Dir)
- if err != nil {
- // If the caller passed a bogus Dir explicitly, that's materially
- // different from not having modules enabled.
- return err
- }
- }
- for {
- if f, err := ctxt.openFile(ctxt.joinPath(parent, "go.mod")); err == nil {
- buf := make([]byte, 100)
- _, err := f.Read(buf)
- f.Close()
- if err == nil || err == io.EOF {
- // go.mod exists and is readable (is a file, not a directory).
- break
- }
- }
- d := filepath.Dir(parent)
- if len(d) >= len(parent) {
- return errNoModules // reached top of file system, no go.mod
- }
- parent = d
- }
- }
-
- goCmd := filepath.Join(ctxt.GOROOT, "bin", "go")
- cmd := exec.Command(goCmd, "list", "-e", "-compiler="+ctxt.Compiler, "-tags="+strings.Join(ctxt.BuildTags, ","), "-installsuffix="+ctxt.InstallSuffix, "-f={{.Dir}}\n{{.ImportPath}}\n{{.Root}}\n{{.Goroot}}\n{{if .Error}}{{.Error}}{{end}}\n", "--", path)
-
- if ctxt.Dir != "" {
- cmd.Dir = ctxt.Dir
- }
-
- var stdout, stderr strings.Builder
- cmd.Stdout = &stdout
- cmd.Stderr = &stderr
-
- cgo := "0"
- if ctxt.CgoEnabled {
- cgo = "1"
- }
- cmd.Env = append(cmd.Environ(),
- "GOOS="+ctxt.GOOS,
- "GOARCH="+ctxt.GOARCH,
- "GOROOT="+ctxt.GOROOT,
- "GOPATH="+ctxt.GOPATH,
- "CGO_ENABLED="+cgo,
- )
-
- if err := cmd.Run(); err != nil {
- return fmt.Errorf("go/build: go list %s: %v\n%s\n", path, err, stderr.String())
- }
-
- f := strings.SplitN(stdout.String(), "\n", 5)
- if len(f) != 5 {
- return fmt.Errorf("go/build: importGo %s: unexpected output:\n%s\n", path, stdout.String())
- }
- dir := f[0]
- errStr := strings.TrimSpace(f[4])
- if errStr != "" && dir == "" {
- // If 'go list' could not locate the package (dir is empty),
- // return the same error that 'go list' reported.
- return errors.New(errStr)
- }
-
- // If 'go list' did locate the package, ignore the error.
- // It was probably related to loading source files, and we'll
- // encounter it ourselves shortly if the FindOnly flag isn't set.
- p.Dir = dir
- p.ImportPath = f[1]
- p.Root = f[2]
- p.Goroot = f[3] == "true"
- return nil
-}
-
-func equal(x, y []string) bool {
- if len(x) != len(y) {
- return false
- }
- for i, xi := range x {
- if xi != y[i] {
- return false
- }
- }
- return true
-}
-
-// hasGoFiles reports whether dir contains any files with names ending in .go.
-// For a vendor check we must exclude directories that contain no .go files.
-// Otherwise it is not possible to vendor just a/b/c and still import the
-// non-vendored a/b. See golang.org/issue/13832.
-func hasGoFiles(ctxt *Context, dir string) bool {
- ents, _ := ctxt.readDir(dir)
- for _, ent := range ents {
- if !ent.IsDir() && strings.HasSuffix(ent.Name(), ".go") {
- return true
- }
- }
- return false
-}
-
-func findImportComment(data []byte) (s string, line int) {
- // expect keyword package
- word, data := parseWord(data)
- if string(word) != "package" {
- return "", 0
- }
-
- // expect package name
- _, data = parseWord(data)
-
- // now ready for import comment, a // or /* */ comment
- // beginning and ending on the current line.
- for len(data) > 0 && (data[0] == ' ' || data[0] == '\t' || data[0] == '\r') {
- data = data[1:]
- }
-
- var comment []byte
- switch {
- case bytes.HasPrefix(data, slashSlash):
- comment, _, _ = bytes.Cut(data[2:], newline)
- case bytes.HasPrefix(data, slashStar):
- var ok bool
- comment, _, ok = bytes.Cut(data[2:], starSlash)
- if !ok {
- // malformed comment
- return "", 0
- }
- if bytes.Contains(comment, newline) {
- return "", 0
- }
- }
- comment = bytes.TrimSpace(comment)
-
- // split comment into `import`, `"pkg"`
- word, arg := parseWord(comment)
- if string(word) != "import" {
- return "", 0
- }
-
- line = 1 + bytes.Count(data[:cap(data)-cap(arg)], newline)
- return strings.TrimSpace(string(arg)), line
-}
-
-var (
- slashSlash = []byte("//")
- slashStar = []byte("/*")
- starSlash = []byte("*/")
- newline = []byte("\n")
-)
-
-// skipSpaceOrComment returns data with any leading spaces or comments removed.
-func skipSpaceOrComment(data []byte) []byte {
- for len(data) > 0 {
- switch data[0] {
- case ' ', '\t', '\r', '\n':
- data = data[1:]
- continue
- case '/':
- if bytes.HasPrefix(data, slashSlash) {
- i := bytes.Index(data, newline)
- if i < 0 {
- return nil
- }
- data = data[i+1:]
- continue
- }
- if bytes.HasPrefix(data, slashStar) {
- data = data[2:]
- i := bytes.Index(data, starSlash)
- if i < 0 {
- return nil
- }
- data = data[i+2:]
- continue
- }
- }
- break
- }
- return data
-}
-
-// parseWord skips any leading spaces or comments in data
-// and then parses the beginning of data as an identifier or keyword,
-// returning that word and what remains after the word.
-func parseWord(data []byte) (word, rest []byte) {
- data = skipSpaceOrComment(data)
-
- // Parse past leading word characters.
- rest = data
- for {
- r, size := utf8.DecodeRune(rest)
- if unicode.IsLetter(r) || '0' <= r && r <= '9' || r == '_' {
- rest = rest[size:]
- continue
- }
- break
- }
-
- word = data[:len(data)-len(rest)]
- if len(word) == 0 {
- return nil, nil
- }
-
- return word, rest
-}
-
-// MatchFile reports whether the file with the given name in the given directory
-// matches the context and would be included in a Package created by ImportDir
-// of that directory.
-//
-// MatchFile considers the name of the file and may use ctxt.OpenFile to
-// read some or all of the file's content.
-func (ctxt *Context) MatchFile(dir, name string) (match bool, err error) {
- info, err := ctxt.matchFile(dir, name, nil, nil, nil)
- return info != nil, err
-}
-
-var dummyPkg Package
-
-// fileInfo records information learned about a file included in a build.
-type fileInfo struct {
- name string // full name including dir
- header []byte
- fset *token.FileSet
- parsed *ast.File
- parseErr error
- imports []fileImport
- embeds []fileEmbed
-}
-
-type fileImport struct {
- path string
- pos token.Pos
- doc *ast.CommentGroup
-}
-
-type fileEmbed struct {
- pattern string
- pos token.Position
-}
-
-// matchFile determines whether the file with the given name in the given directory
-// should be included in the package being constructed.
-// If the file should be included, matchFile returns a non-nil *fileInfo (and a nil error).
-// Non-nil errors are reserved for unexpected problems.
-//
-// If name denotes a Go program, matchFile reads until the end of the
-// imports and returns that section of the file in the fileInfo's header field,
-// even though it only considers text until the first non-comment
-// for go:build lines.
-//
-// If allTags is non-nil, matchFile records any encountered build tag
-// by setting allTags[tag] = true.
-func (ctxt *Context) matchFile(dir, name string, allTags map[string]bool, binaryOnly *bool, fset *token.FileSet) (*fileInfo, error) {
- if strings.HasPrefix(name, "_") ||
- strings.HasPrefix(name, ".") {
- return nil, nil
- }
-
- i := strings.LastIndex(name, ".")
- if i < 0 {
- i = len(name)
- }
- ext := name[i:]
-
- if ext != ".go" && fileListForExt(&dummyPkg, ext) == nil {
- // skip
- return nil, nil
- }
-
- if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles {
- return nil, nil
- }
-
- info := &fileInfo{name: ctxt.joinPath(dir, name), fset: fset}
- if ext == ".syso" {
- // binary, no reading
- return info, nil
- }
-
- f, err := ctxt.openFile(info.name)
- if err != nil {
- return nil, err
- }
-
- if strings.HasSuffix(name, ".go") {
- err = readGoInfo(f, info)
- if strings.HasSuffix(name, "_test.go") {
- binaryOnly = nil // ignore //go:binary-only-package comments in _test.go files
- }
- } else {
- binaryOnly = nil // ignore //go:binary-only-package comments in non-Go sources
- info.header, err = readComments(f)
- }
- f.Close()
- if err != nil {
- return info, fmt.Errorf("read %s: %v", info.name, err)
- }
-
- // Look for go:build comments to accept or reject the file.
- ok, sawBinaryOnly, err := ctxt.shouldBuild(info.header, allTags)
- if err != nil {
- return nil, fmt.Errorf("%s: %v", name, err)
- }
- if !ok && !ctxt.UseAllFiles {
- return nil, nil
- }
-
- if binaryOnly != nil && sawBinaryOnly {
- *binaryOnly = true
- }
-
- return info, nil
-}
-
-func cleanDecls(m map[string][]token.Position) ([]string, map[string][]token.Position) {
- all := make([]string, 0, len(m))
- for path := range m {
- all = append(all, path)
- }
- sort.Strings(all)
- return all, m
-}
-
-// Import is shorthand for Default.Import.
-func Import(path, srcDir string, mode ImportMode) (*Package, error) {
- return Default.Import(path, srcDir, mode)
-}
-
-// ImportDir is shorthand for Default.ImportDir.
-func ImportDir(dir string, mode ImportMode) (*Package, error) {
- return Default.ImportDir(dir, mode)
-}
-
-var (
- plusBuild = []byte("+build")
-
- goBuildComment = []byte("//go:build")
-
- errMultipleGoBuild = errors.New("multiple //go:build comments")
-)
-
-func isGoBuildComment(line []byte) bool {
- if !bytes.HasPrefix(line, goBuildComment) {
- return false
- }
- line = bytes.TrimSpace(line)
- rest := line[len(goBuildComment):]
- return len(rest) == 0 || len(bytes.TrimSpace(rest)) < len(rest)
-}
-
-// Special comment denoting a binary-only package.
-// See https://golang.org/design/2775-binary-only-packages
-// for more about the design of binary-only packages.
-var binaryOnlyComment = []byte("//go:binary-only-package")
-
-// shouldBuild reports whether it is okay to use this file,
-// The rule is that in the file's leading run of // comments
-// and blank lines, which must be followed by a blank line
-// (to avoid including a Go package clause doc comment),
-// lines beginning with '//go:build' are taken as build directives.
-//
-// The file is accepted only if each such line lists something
-// matching the file. For example:
-//
-// //go:build windows linux
-//
-// marks the file as applicable only on Windows and Linux.
-//
-// For each build tag it consults, shouldBuild sets allTags[tag] = true.
-//
-// shouldBuild reports whether the file should be built
-// and whether a //go:binary-only-package comment was found.
-func (ctxt *Context) shouldBuild(content []byte, allTags map[string]bool) (shouldBuild, binaryOnly bool, err error) {
- // Identify leading run of // comments and blank lines,
- // which must be followed by a blank line.
- // Also identify any //go:build comments.
- content, goBuild, sawBinaryOnly, err := parseFileHeader(content)
- if err != nil {
- return false, false, err
- }
-
- // If //go:build line is present, it controls.
- // Otherwise fall back to +build processing.
- switch {
- case goBuild != nil:
- x, err := constraint.Parse(string(goBuild))
- if err != nil {
- return false, false, fmt.Errorf("parsing //go:build line: %v", err)
- }
- shouldBuild = ctxt.eval(x, allTags)
-
- default:
- shouldBuild = true
- p := content
- for len(p) > 0 {
- line := p
- if i := bytes.IndexByte(line, '\n'); i >= 0 {
- line, p = line[:i], p[i+1:]
- } else {
- p = p[len(p):]
- }
- line = bytes.TrimSpace(line)
- if !bytes.HasPrefix(line, slashSlash) || !bytes.Contains(line, plusBuild) {
- continue
- }
- text := string(line)
- if !constraint.IsPlusBuild(text) {
- continue
- }
- if x, err := constraint.Parse(text); err == nil {
- if !ctxt.eval(x, allTags) {
- shouldBuild = false
- }
- }
- }
- }
-
- return shouldBuild, sawBinaryOnly, nil
-}
-
-func parseFileHeader(content []byte) (trimmed, goBuild []byte, sawBinaryOnly bool, err error) {
- end := 0
- p := content
- ended := false // found non-blank, non-// line, so stopped accepting //go:build lines
- inSlashStar := false // in /* */ comment
-
-Lines:
- for len(p) > 0 {
- line := p
- if i := bytes.IndexByte(line, '\n'); i >= 0 {
- line, p = line[:i], p[i+1:]
- } else {
- p = p[len(p):]
- }
- line = bytes.TrimSpace(line)
- if len(line) == 0 && !ended { // Blank line
- // Remember position of most recent blank line.
- // When we find the first non-blank, non-// line,
- // this "end" position marks the latest file position
- // where a //go:build line can appear.
- // (It must appear _before_ a blank line before the non-blank, non-// line.
- // Yes, that's confusing, which is part of why we moved to //go:build lines.)
- // Note that ended==false here means that inSlashStar==false,
- // since seeing a /* would have set ended==true.
- end = len(content) - len(p)
- continue Lines
- }
- if !bytes.HasPrefix(line, slashSlash) { // Not comment line
- ended = true
- }
-
- if !inSlashStar && isGoBuildComment(line) {
- if goBuild != nil {
- return nil, nil, false, errMultipleGoBuild
- }
- goBuild = line
- }
- if !inSlashStar && bytes.Equal(line, binaryOnlyComment) {
- sawBinaryOnly = true
- }
-
- Comments:
- for len(line) > 0 {
- if inSlashStar {
- if i := bytes.Index(line, starSlash); i >= 0 {
- inSlashStar = false
- line = bytes.TrimSpace(line[i+len(starSlash):])
- continue Comments
- }
- continue Lines
- }
- if bytes.HasPrefix(line, slashSlash) {
- continue Lines
- }
- if bytes.HasPrefix(line, slashStar) {
- inSlashStar = true
- line = bytes.TrimSpace(line[len(slashStar):])
- continue Comments
- }
- // Found non-comment text.
- break Lines
- }
- }
-
- return content[:end], goBuild, sawBinaryOnly, nil
-}
-
-// saveCgo saves the information from the #cgo lines in the import "C" comment.
-// These lines set CFLAGS, CPPFLAGS, CXXFLAGS and LDFLAGS and pkg-config directives
-// that affect the way cgo's C code is built.
-func (ctxt *Context) saveCgo(filename string, di *Package, cg *ast.CommentGroup) error {
- text := cg.Text()
- for _, line := range strings.Split(text, "\n") {
- orig := line
-
- // Line is
- // #cgo [GOOS/GOARCH...] LDFLAGS: stuff
- //
- line = strings.TrimSpace(line)
- if len(line) < 5 || line[:4] != "#cgo" || (line[4] != ' ' && line[4] != '\t') {
- continue
- }
-
- // Split at colon.
- line, argstr, ok := strings.Cut(strings.TrimSpace(line[4:]), ":")
- if !ok {
- return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
- }
-
- // Parse GOOS/GOARCH stuff.
- f := strings.Fields(line)
- if len(f) < 1 {
- return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
- }
-
- cond, verb := f[:len(f)-1], f[len(f)-1]
- if len(cond) > 0 {
- ok := false
- for _, c := range cond {
- if ctxt.matchAuto(c, nil) {
- ok = true
- break
- }
- }
- if !ok {
- continue
- }
- }
-
- args, err := splitQuoted(argstr)
- if err != nil {
- return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
- }
- for i, arg := range args {
- if arg, ok = expandSrcDir(arg, di.Dir); !ok {
- return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg)
- }
- args[i] = arg
- }
-
- switch verb {
- case "CFLAGS", "CPPFLAGS", "CXXFLAGS", "FFLAGS", "LDFLAGS":
- // Change relative paths to absolute.
- ctxt.makePathsAbsolute(args, di.Dir)
- }
-
- switch verb {
- case "CFLAGS":
- di.CgoCFLAGS = append(di.CgoCFLAGS, args...)
- case "CPPFLAGS":
- di.CgoCPPFLAGS = append(di.CgoCPPFLAGS, args...)
- case "CXXFLAGS":
- di.CgoCXXFLAGS = append(di.CgoCXXFLAGS, args...)
- case "FFLAGS":
- di.CgoFFLAGS = append(di.CgoFFLAGS, args...)
- case "LDFLAGS":
- di.CgoLDFLAGS = append(di.CgoLDFLAGS, args...)
- case "pkg-config":
- di.CgoPkgConfig = append(di.CgoPkgConfig, args...)
- default:
- return fmt.Errorf("%s: invalid #cgo verb: %s", filename, orig)
- }
- }
- return nil
-}
-
-// expandSrcDir expands any occurrence of ${SRCDIR}, making sure
-// the result is safe for the shell.
-func expandSrcDir(str string, srcdir string) (string, bool) {
- // "\" delimited paths cause safeCgoName to fail
- // so convert native paths with a different delimiter
- // to "/" before starting (eg: on windows).
- srcdir = filepath.ToSlash(srcdir)
-
- chunks := strings.Split(str, "${SRCDIR}")
- if len(chunks) < 2 {
- return str, safeCgoName(str)
- }
- ok := true
- for _, chunk := range chunks {
- ok = ok && (chunk == "" || safeCgoName(chunk))
- }
- ok = ok && (srcdir == "" || safeCgoName(srcdir))
- res := strings.Join(chunks, srcdir)
- return res, ok && res != ""
-}
-
-// makePathsAbsolute looks for compiler options that take paths and
-// makes them absolute. We do this because through the 1.8 release we
-// ran the compiler in the package directory, so any relative -I or -L
-// options would be relative to that directory. In 1.9 we changed to
-// running the compiler in the build directory, to get consistent
-// build results (issue #19964). To keep builds working, we change any
-// relative -I or -L options to be absolute.
-//
-// Using filepath.IsAbs and filepath.Join here means the results will be
-// different on different systems, but that's OK: -I and -L options are
-// inherently system-dependent.
-func (ctxt *Context) makePathsAbsolute(args []string, srcDir string) {
- nextPath := false
- for i, arg := range args {
- if nextPath {
- if !filepath.IsAbs(arg) {
- args[i] = filepath.Join(srcDir, arg)
- }
- nextPath = false
- } else if strings.HasPrefix(arg, "-I") || strings.HasPrefix(arg, "-L") {
- if len(arg) == 2 {
- nextPath = true
- } else {
- if !filepath.IsAbs(arg[2:]) {
- args[i] = arg[:2] + filepath.Join(srcDir, arg[2:])
- }
- }
- }
- }
-}
-
-// NOTE: $ is not safe for the shell, but it is allowed here because of linker options like -Wl,$ORIGIN.
-// We never pass these arguments to a shell (just to programs we construct argv for), so this should be okay.
-// See golang.org/issue/6038.
-// The @ is for OS X. See golang.org/issue/13720.
-// The % is for Jenkins. See golang.org/issue/16959.
-// The ! is because module paths may use them. See golang.org/issue/26716.
-// The ~ and ^ are for sr.ht. See golang.org/issue/32260.
-const safeString = "+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$@%! ~^"
-
-func safeCgoName(s string) bool {
- if s == "" {
- return false
- }
- for i := 0; i < len(s); i++ {
- if c := s[i]; c < utf8.RuneSelf && strings.IndexByte(safeString, c) < 0 {
- return false
- }
- }
- return true
-}
-
-// splitQuoted splits the string s around each instance of one or more consecutive
-// white space characters while taking into account quotes and escaping, and
-// returns an array of substrings of s or an empty list if s contains only white space.
-// Single quotes and double quotes are recognized to prevent splitting within the
-// quoted region, and are removed from the resulting substrings. If a quote in s
-// isn't closed err will be set and r will have the unclosed argument as the
-// last element. The backslash is used for escaping.
-//
-// For example, the following string:
-//
-// a b:"c d" 'e''f' "g\""
-//
-// Would be parsed as:
-//
-// []string{"a", "b:c d", "ef", `g"`}
-func splitQuoted(s string) (r []string, err error) {
- var args []string
- arg := make([]rune, len(s))
- escaped := false
- quoted := false
- quote := '\x00'
- i := 0
- for _, rune := range s {
- switch {
- case escaped:
- escaped = false
- case rune == '\\':
- escaped = true
- continue
- case quote != '\x00':
- if rune == quote {
- quote = '\x00'
- continue
- }
- case rune == '"' || rune == '\'':
- quoted = true
- quote = rune
- continue
- case unicode.IsSpace(rune):
- if quoted || i > 0 {
- quoted = false
- args = append(args, string(arg[:i]))
- i = 0
- }
- continue
- }
- arg[i] = rune
- i++
- }
- if quoted || i > 0 {
- args = append(args, string(arg[:i]))
- }
- if quote != 0 {
- err = errors.New("unclosed quote")
- } else if escaped {
- err = errors.New("unfinished escaping")
- }
- return args, err
-}
-
-// matchAuto interprets text as either a +build or //go:build expression (whichever works),
-// reporting whether the expression matches the build context.
-//
-// matchAuto is only used for testing of tag evaluation
-// and in #cgo lines, which accept either syntax.
-func (ctxt *Context) matchAuto(text string, allTags map[string]bool) bool {
- if strings.ContainsAny(text, "&|()") {
- text = "//go:build " + text
- } else {
- text = "// +build " + text
- }
- x, err := constraint.Parse(text)
- if err != nil {
- return false
- }
- return ctxt.eval(x, allTags)
-}
-
-func (ctxt *Context) eval(x constraint.Expr, allTags map[string]bool) bool {
- return x.Eval(func(tag string) bool { return ctxt.matchTag(tag, allTags) })
-}
-
-// matchTag reports whether the name is one of:
-//
-// cgo (if cgo is enabled)
-// $GOOS
-// $GOARCH
-// ctxt.Compiler
-// linux (if GOOS = android)
-// solaris (if GOOS = illumos)
-// darwin (if GOOS = ios)
-// unix (if this is a Unix GOOS)
-// boringcrypto (if GOEXPERIMENT=boringcrypto is enabled)
-// tag (if tag is listed in ctxt.BuildTags, ctxt.ToolTags, or ctxt.ReleaseTags)
-//
-// It records all consulted tags in allTags.
-func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool {
- if allTags != nil {
- allTags[name] = true
- }
-
- // special tags
- if ctxt.CgoEnabled && name == "cgo" {
- return true
- }
- if name == ctxt.GOOS || name == ctxt.GOARCH || name == ctxt.Compiler {
- return true
- }
- if ctxt.GOOS == "android" && name == "linux" {
- return true
- }
- if ctxt.GOOS == "illumos" && name == "solaris" {
- return true
- }
- if ctxt.GOOS == "ios" && name == "darwin" {
- return true
- }
- if name == "unix" && unixOS[ctxt.GOOS] {
- return true
- }
- if name == "boringcrypto" {
- name = "goexperiment.boringcrypto" // boringcrypto is an old name for goexperiment.boringcrypto
- }
-
- // other tags
- for _, tag := range ctxt.BuildTags {
- if tag == name {
- return true
- }
- }
- for _, tag := range ctxt.ToolTags {
- if tag == name {
- return true
- }
- }
- for _, tag := range ctxt.ReleaseTags {
- if tag == name {
- return true
- }
- }
-
- return false
-}
-
-// goodOSArchFile returns false if the name contains a $GOOS or $GOARCH
-// suffix which does not match the current system.
-// The recognized name formats are:
-//
-// name_$(GOOS).*
-// name_$(GOARCH).*
-// name_$(GOOS)_$(GOARCH).*
-// name_$(GOOS)_test.*
-// name_$(GOARCH)_test.*
-// name_$(GOOS)_$(GOARCH)_test.*
-//
-// Exceptions:
-// if GOOS=android, then files with GOOS=linux are also matched.
-// if GOOS=illumos, then files with GOOS=solaris are also matched.
-// if GOOS=ios, then files with GOOS=darwin are also matched.
-func (ctxt *Context) goodOSArchFile(name string, allTags map[string]bool) bool {
- name, _, _ = strings.Cut(name, ".")
-
- // Before Go 1.4, a file called "linux.go" would be equivalent to having a
- // build tag "linux" in that file. For Go 1.4 and beyond, we require this
- // auto-tagging to apply only to files with a non-empty prefix, so
- // "foo_linux.go" is tagged but "linux.go" is not. This allows new operating
- // systems, such as android, to arrive without breaking existing code with
- // innocuous source code in "android.go". The easiest fix: cut everything
- // in the name before the initial _.
- i := strings.Index(name, "_")
- if i < 0 {
- return true
- }
- name = name[i:] // ignore everything before first _
-
- l := strings.Split(name, "_")
- if n := len(l); n > 0 && l[n-1] == "test" {
- l = l[:n-1]
- }
- n := len(l)
- if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] {
- if allTags != nil {
- // In case we short-circuit on l[n-1].
- allTags[l[n-2]] = true
- }
- return ctxt.matchTag(l[n-1], allTags) && ctxt.matchTag(l[n-2], allTags)
- }
- if n >= 1 && (knownOS[l[n-1]] || knownArch[l[n-1]]) {
- return ctxt.matchTag(l[n-1], allTags)
- }
- return true
-}
-
-// ToolDir is the directory containing build tools.
-var ToolDir = getToolDir()
-
-// IsLocalImport reports whether the import path is
-// a local import path, like ".", "..", "./foo", or "../foo".
-func IsLocalImport(path string) bool {
- return path == "." || path == ".." ||
- strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../")
-}
-
-// ArchChar returns "?" and an error.
-// In earlier versions of Go, the returned string was used to derive
-// the compiler and linker tool names, the default object file suffix,
-// and the default linker output name. As of Go 1.5, those strings
-// no longer vary by architecture; they are compile, link, .o, and a.out, respectively.
-func ArchChar(goarch string) (string, error) {
- return "?", errors.New("architecture letter no longer used")
-}
diff --git a/contrib/go/_std_1.20/src/go/build/constraint/ya.make b/contrib/go/_std_1.20/src/go/build/constraint/ya.make
deleted file mode 100644
index 052b73bf82..0000000000
--- a/contrib/go/_std_1.20/src/go/build/constraint/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- expr.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/build/read.go b/contrib/go/_std_1.20/src/go/build/read.go
deleted file mode 100644
index adcf82f3f0..0000000000
--- a/contrib/go/_std_1.20/src/go/build/read.go
+++ /dev/null
@@ -1,600 +0,0 @@
-// Copyright 2012 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 build
-
-import (
- "bufio"
- "bytes"
- "errors"
- "fmt"
- "go/ast"
- "go/parser"
- "go/scanner"
- "go/token"
- "io"
- "strconv"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-type importReader struct {
- b *bufio.Reader
- buf []byte
- peek byte
- err error
- eof bool
- nerr int
- pos token.Position
-}
-
-var bom = []byte{0xef, 0xbb, 0xbf}
-
-func newImportReader(name string, r io.Reader) *importReader {
- b := bufio.NewReader(r)
- // Remove leading UTF-8 BOM.
- // Per https://golang.org/ref/spec#Source_code_representation:
- // a compiler may ignore a UTF-8-encoded byte order mark (U+FEFF)
- // if it is the first Unicode code point in the source text.
- if leadingBytes, err := b.Peek(3); err == nil && bytes.Equal(leadingBytes, bom) {
- b.Discard(3)
- }
- return &importReader{
- b: b,
- pos: token.Position{
- Filename: name,
- Line: 1,
- Column: 1,
- },
- }
-}
-
-func isIdent(c byte) bool {
- return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c >= utf8.RuneSelf
-}
-
-var (
- errSyntax = errors.New("syntax error")
- errNUL = errors.New("unexpected NUL in input")
-)
-
-// syntaxError records a syntax error, but only if an I/O error has not already been recorded.
-func (r *importReader) syntaxError() {
- if r.err == nil {
- r.err = errSyntax
- }
-}
-
-// readByte reads the next byte from the input, saves it in buf, and returns it.
-// If an error occurs, readByte records the error in r.err and returns 0.
-func (r *importReader) readByte() byte {
- c, err := r.b.ReadByte()
- if err == nil {
- r.buf = append(r.buf, c)
- if c == 0 {
- err = errNUL
- }
- }
- if err != nil {
- if err == io.EOF {
- r.eof = true
- } else if r.err == nil {
- r.err = err
- }
- c = 0
- }
- return c
-}
-
-// readByteNoBuf is like readByte but doesn't buffer the byte.
-// It exhausts r.buf before reading from r.b.
-func (r *importReader) readByteNoBuf() byte {
- var c byte
- var err error
- if len(r.buf) > 0 {
- c = r.buf[0]
- r.buf = r.buf[1:]
- } else {
- c, err = r.b.ReadByte()
- if err == nil && c == 0 {
- err = errNUL
- }
- }
-
- if err != nil {
- if err == io.EOF {
- r.eof = true
- } else if r.err == nil {
- r.err = err
- }
- return 0
- }
- r.pos.Offset++
- if c == '\n' {
- r.pos.Line++
- r.pos.Column = 1
- } else {
- r.pos.Column++
- }
- return c
-}
-
-// peekByte returns the next byte from the input reader but does not advance beyond it.
-// If skipSpace is set, peekByte skips leading spaces and comments.
-func (r *importReader) peekByte(skipSpace bool) byte {
- if r.err != nil {
- if r.nerr++; r.nerr > 10000 {
- panic("go/build: import reader looping")
- }
- return 0
- }
-
- // Use r.peek as first input byte.
- // Don't just return r.peek here: it might have been left by peekByte(false)
- // and this might be peekByte(true).
- c := r.peek
- if c == 0 {
- c = r.readByte()
- }
- for r.err == nil && !r.eof {
- if skipSpace {
- // For the purposes of this reader, semicolons are never necessary to
- // understand the input and are treated as spaces.
- switch c {
- case ' ', '\f', '\t', '\r', '\n', ';':
- c = r.readByte()
- continue
-
- case '/':
- c = r.readByte()
- if c == '/' {
- for c != '\n' && r.err == nil && !r.eof {
- c = r.readByte()
- }
- } else if c == '*' {
- var c1 byte
- for (c != '*' || c1 != '/') && r.err == nil {
- if r.eof {
- r.syntaxError()
- }
- c, c1 = c1, r.readByte()
- }
- } else {
- r.syntaxError()
- }
- c = r.readByte()
- continue
- }
- }
- break
- }
- r.peek = c
- return r.peek
-}
-
-// nextByte is like peekByte but advances beyond the returned byte.
-func (r *importReader) nextByte(skipSpace bool) byte {
- c := r.peekByte(skipSpace)
- r.peek = 0
- return c
-}
-
-var goEmbed = []byte("go:embed")
-
-// findEmbed advances the input reader to the next //go:embed comment.
-// It reports whether it found a comment.
-// (Otherwise it found an error or EOF.)
-func (r *importReader) findEmbed(first bool) bool {
- // The import block scan stopped after a non-space character,
- // so the reader is not at the start of a line on the first call.
- // After that, each //go:embed extraction leaves the reader
- // at the end of a line.
- startLine := !first
- var c byte
- for r.err == nil && !r.eof {
- c = r.readByteNoBuf()
- Reswitch:
- switch c {
- default:
- startLine = false
-
- case '\n':
- startLine = true
-
- case ' ', '\t':
- // leave startLine alone
-
- case '"':
- startLine = false
- for r.err == nil {
- if r.eof {
- r.syntaxError()
- }
- c = r.readByteNoBuf()
- if c == '\\' {
- r.readByteNoBuf()
- if r.err != nil {
- r.syntaxError()
- return false
- }
- continue
- }
- if c == '"' {
- c = r.readByteNoBuf()
- goto Reswitch
- }
- }
- goto Reswitch
-
- case '`':
- startLine = false
- for r.err == nil {
- if r.eof {
- r.syntaxError()
- }
- c = r.readByteNoBuf()
- if c == '`' {
- c = r.readByteNoBuf()
- goto Reswitch
- }
- }
-
- case '\'':
- startLine = false
- for r.err == nil {
- if r.eof {
- r.syntaxError()
- }
- c = r.readByteNoBuf()
- if c == '\\' {
- r.readByteNoBuf()
- if r.err != nil {
- r.syntaxError()
- return false
- }
- continue
- }
- if c == '\'' {
- c = r.readByteNoBuf()
- goto Reswitch
- }
- }
-
- case '/':
- c = r.readByteNoBuf()
- switch c {
- default:
- startLine = false
- goto Reswitch
-
- case '*':
- var c1 byte
- for (c != '*' || c1 != '/') && r.err == nil {
- if r.eof {
- r.syntaxError()
- }
- c, c1 = c1, r.readByteNoBuf()
- }
- startLine = false
-
- case '/':
- if startLine {
- // Try to read this as a //go:embed comment.
- for i := range goEmbed {
- c = r.readByteNoBuf()
- if c != goEmbed[i] {
- goto SkipSlashSlash
- }
- }
- c = r.readByteNoBuf()
- if c == ' ' || c == '\t' {
- // Found one!
- return true
- }
- }
- SkipSlashSlash:
- for c != '\n' && r.err == nil && !r.eof {
- c = r.readByteNoBuf()
- }
- startLine = true
- }
- }
- }
- return false
-}
-
-// readKeyword reads the given keyword from the input.
-// If the keyword is not present, readKeyword records a syntax error.
-func (r *importReader) readKeyword(kw string) {
- r.peekByte(true)
- for i := 0; i < len(kw); i++ {
- if r.nextByte(false) != kw[i] {
- r.syntaxError()
- return
- }
- }
- if isIdent(r.peekByte(false)) {
- r.syntaxError()
- }
-}
-
-// readIdent reads an identifier from the input.
-// If an identifier is not present, readIdent records a syntax error.
-func (r *importReader) readIdent() {
- c := r.peekByte(true)
- if !isIdent(c) {
- r.syntaxError()
- return
- }
- for isIdent(r.peekByte(false)) {
- r.peek = 0
- }
-}
-
-// readString reads a quoted string literal from the input.
-// If an identifier is not present, readString records a syntax error.
-func (r *importReader) readString() {
- switch r.nextByte(true) {
- case '`':
- for r.err == nil {
- if r.nextByte(false) == '`' {
- break
- }
- if r.eof {
- r.syntaxError()
- }
- }
- case '"':
- for r.err == nil {
- c := r.nextByte(false)
- if c == '"' {
- break
- }
- if r.eof || c == '\n' {
- r.syntaxError()
- }
- if c == '\\' {
- r.nextByte(false)
- }
- }
- default:
- r.syntaxError()
- }
-}
-
-// readImport reads an import clause - optional identifier followed by quoted string -
-// from the input.
-func (r *importReader) readImport() {
- c := r.peekByte(true)
- if c == '.' {
- r.peek = 0
- } else if isIdent(c) {
- r.readIdent()
- }
- r.readString()
-}
-
-// readComments is like io.ReadAll, except that it only reads the leading
-// block of comments in the file.
-func readComments(f io.Reader) ([]byte, error) {
- r := newImportReader("", f)
- r.peekByte(true)
- if r.err == nil && !r.eof {
- // Didn't reach EOF, so must have found a non-space byte. Remove it.
- r.buf = r.buf[:len(r.buf)-1]
- }
- return r.buf, r.err
-}
-
-// readGoInfo expects a Go file as input and reads the file up to and including the import section.
-// It records what it learned in *info.
-// If info.fset is non-nil, readGoInfo parses the file and sets info.parsed, info.parseErr,
-// info.imports and info.embeds.
-//
-// It only returns an error if there are problems reading the file,
-// not for syntax errors in the file itself.
-func readGoInfo(f io.Reader, info *fileInfo) error {
- r := newImportReader(info.name, f)
-
- r.readKeyword("package")
- r.readIdent()
- for r.peekByte(true) == 'i' {
- r.readKeyword("import")
- if r.peekByte(true) == '(' {
- r.nextByte(false)
- for r.peekByte(true) != ')' && r.err == nil {
- r.readImport()
- }
- r.nextByte(false)
- } else {
- r.readImport()
- }
- }
-
- info.header = r.buf
-
- // If we stopped successfully before EOF, we read a byte that told us we were done.
- // Return all but that last byte, which would cause a syntax error if we let it through.
- if r.err == nil && !r.eof {
- info.header = r.buf[:len(r.buf)-1]
- }
-
- // If we stopped for a syntax error, consume the whole file so that
- // we are sure we don't change the errors that go/parser returns.
- if r.err == errSyntax {
- r.err = nil
- for r.err == nil && !r.eof {
- r.readByte()
- }
- info.header = r.buf
- }
- if r.err != nil {
- return r.err
- }
-
- if info.fset == nil {
- return nil
- }
-
- // Parse file header & record imports.
- info.parsed, info.parseErr = parser.ParseFile(info.fset, info.name, info.header, parser.ImportsOnly|parser.ParseComments)
- if info.parseErr != nil {
- return nil
- }
-
- hasEmbed := false
- for _, decl := range info.parsed.Decls {
- d, ok := decl.(*ast.GenDecl)
- if !ok {
- continue
- }
- for _, dspec := range d.Specs {
- spec, ok := dspec.(*ast.ImportSpec)
- if !ok {
- continue
- }
- quoted := spec.Path.Value
- path, err := strconv.Unquote(quoted)
- if err != nil {
- return fmt.Errorf("parser returned invalid quoted string: <%s>", quoted)
- }
- if !isValidImport(path) {
- // The parser used to return a parse error for invalid import paths, but
- // no longer does, so check for and create the error here instead.
- info.parseErr = scanner.Error{Pos: info.fset.Position(spec.Pos()), Msg: "invalid import path: " + path}
- info.imports = nil
- return nil
- }
- if path == "embed" {
- hasEmbed = true
- }
-
- doc := spec.Doc
- if doc == nil && len(d.Specs) == 1 {
- doc = d.Doc
- }
- info.imports = append(info.imports, fileImport{path, spec.Pos(), doc})
- }
- }
-
- // If the file imports "embed",
- // we have to look for //go:embed comments
- // in the remainder of the file.
- // The compiler will enforce the mapping of comments to
- // declared variables. We just need to know the patterns.
- // If there were //go:embed comments earlier in the file
- // (near the package statement or imports), the compiler
- // will reject them. They can be (and have already been) ignored.
- if hasEmbed {
- var line []byte
- for first := true; r.findEmbed(first); first = false {
- line = line[:0]
- pos := r.pos
- for {
- c := r.readByteNoBuf()
- if c == '\n' || r.err != nil || r.eof {
- break
- }
- line = append(line, c)
- }
- // Add args if line is well-formed.
- // Ignore badly-formed lines - the compiler will report them when it finds them,
- // and we can pretend they are not there to help go list succeed with what it knows.
- embs, err := parseGoEmbed(string(line), pos)
- if err == nil {
- info.embeds = append(info.embeds, embs...)
- }
- }
- }
-
- return nil
-}
-
-// isValidImport checks if the import is a valid import using the more strict
-// checks allowed by the implementation restriction in https://go.dev/ref/spec#Import_declarations.
-// It was ported from the function of the same name that was removed from the
-// parser in CL 424855, when the parser stopped doing these checks.
-func isValidImport(s string) bool {
- const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
- for _, r := range s {
- if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
- return false
- }
- }
- return s != ""
-}
-
-// parseGoEmbed parses the text following "//go:embed" to extract the glob patterns.
-// It accepts unquoted space-separated patterns as well as double-quoted and back-quoted Go strings.
-// This is based on a similar function in cmd/compile/internal/gc/noder.go;
-// this version calculates position information as well.
-func parseGoEmbed(args string, pos token.Position) ([]fileEmbed, error) {
- trimBytes := func(n int) {
- pos.Offset += n
- pos.Column += utf8.RuneCountInString(args[:n])
- args = args[n:]
- }
- trimSpace := func() {
- trim := strings.TrimLeftFunc(args, unicode.IsSpace)
- trimBytes(len(args) - len(trim))
- }
-
- var list []fileEmbed
- for trimSpace(); args != ""; trimSpace() {
- var path string
- pathPos := pos
- Switch:
- switch args[0] {
- default:
- i := len(args)
- for j, c := range args {
- if unicode.IsSpace(c) {
- i = j
- break
- }
- }
- path = args[:i]
- trimBytes(i)
-
- case '`':
- var ok bool
- path, _, ok = strings.Cut(args[1:], "`")
- if !ok {
- return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
- }
- trimBytes(1 + len(path) + 1)
-
- case '"':
- i := 1
- for ; i < len(args); i++ {
- if args[i] == '\\' {
- i++
- continue
- }
- if args[i] == '"' {
- q, err := strconv.Unquote(args[:i+1])
- if err != nil {
- return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args[:i+1])
- }
- path = q
- trimBytes(i + 1)
- break Switch
- }
- }
- if i >= len(args) {
- return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
- }
- }
-
- if args != "" {
- r, _ := utf8.DecodeRuneInString(args)
- if !unicode.IsSpace(r) {
- return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
- }
- }
- list = append(list, fileEmbed{path, pathPos})
- }
- return list, nil
-}
diff --git a/contrib/go/_std_1.20/src/go/build/syslist.go b/contrib/go/_std_1.20/src/go/build/syslist.go
deleted file mode 100644
index 78ca565ce2..0000000000
--- a/contrib/go/_std_1.20/src/go/build/syslist.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2011 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 build
-
-// Note that this file is read by internal/goarch/gengoarch.go and by
-// internal/goos/gengoos.go. If you change this file, look at those
-// files as well.
-
-// knownOS is the list of past, present, and future known GOOS values.
-// Do not remove from this list, as it is used for filename matching.
-// If you add an entry to this list, look at unixOS, below.
-var knownOS = map[string]bool{
- "aix": true,
- "android": true,
- "darwin": true,
- "dragonfly": true,
- "freebsd": true,
- "hurd": true,
- "illumos": true,
- "ios": true,
- "js": true,
- "linux": true,
- "nacl": true,
- "netbsd": true,
- "openbsd": true,
- "plan9": true,
- "solaris": true,
- "windows": true,
- "zos": true,
-}
-
-// unixOS is the set of GOOS values matched by the "unix" build tag.
-// This is not used for filename matching.
-// This list also appears in cmd/dist/build.go and
-// cmd/go/internal/imports/build.go.
-var unixOS = map[string]bool{
- "aix": true,
- "android": true,
- "darwin": true,
- "dragonfly": true,
- "freebsd": true,
- "hurd": true,
- "illumos": true,
- "ios": true,
- "linux": true,
- "netbsd": true,
- "openbsd": true,
- "solaris": true,
-}
-
-// knownArch is the list of past, present, and future known GOARCH values.
-// Do not remove from this list, as it is used for filename matching.
-var knownArch = map[string]bool{
- "386": true,
- "amd64": true,
- "amd64p32": true,
- "arm": true,
- "armbe": true,
- "arm64": true,
- "arm64be": true,
- "loong64": true,
- "mips": true,
- "mipsle": true,
- "mips64": true,
- "mips64le": true,
- "mips64p32": true,
- "mips64p32le": true,
- "ppc": true,
- "ppc64": true,
- "ppc64le": true,
- "riscv": true,
- "riscv64": true,
- "s390": true,
- "s390x": true,
- "sparc": true,
- "sparc64": true,
- "wasm": true,
-}
diff --git a/contrib/go/_std_1.20/src/go/build/ya.make b/contrib/go/_std_1.20/src/go/build/ya.make
deleted file mode 100644
index d4b185eea8..0000000000
--- a/contrib/go/_std_1.20/src/go/build/ya.make
+++ /dev/null
@@ -1,16 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- build.go
- doc.go
- gc.go
- read.go
- syslist.go
- zcgo.go
-)
-
-END()
-
-RECURSE(
- constraint
-)
diff --git a/contrib/go/_std_1.20/src/go/build/zcgo.go b/contrib/go/_std_1.20/src/go/build/zcgo.go
deleted file mode 100644
index 3240671e38..0000000000
--- a/contrib/go/_std_1.20/src/go/build/zcgo.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Code generated by go tool dist; DO NOT EDIT.
-
-package build
-
-const defaultCGO_ENABLED = ""
-
-var cgoEnabled = map[string]bool{
- "aix/ppc64": true,
- "android/386": true,
- "android/amd64": true,
- "android/arm": true,
- "android/arm64": true,
- "darwin/amd64": true,
- "darwin/arm64": true,
- "dragonfly/amd64": true,
- "freebsd/386": true,
- "freebsd/amd64": true,
- "freebsd/arm": true,
- "freebsd/arm64": true,
- "freebsd/riscv64": true,
- "illumos/amd64": true,
- "ios/amd64": true,
- "ios/arm64": true,
- "linux/386": true,
- "linux/amd64": true,
- "linux/arm": true,
- "linux/arm64": true,
- "linux/loong64": true,
- "linux/mips": true,
- "linux/mips64": true,
- "linux/mips64le": true,
- "linux/mipsle": true,
- "linux/ppc64le": true,
- "linux/riscv64": true,
- "linux/s390x": true,
- "linux/sparc64": true,
- "netbsd/386": true,
- "netbsd/amd64": true,
- "netbsd/arm": true,
- "netbsd/arm64": true,
- "openbsd/386": true,
- "openbsd/amd64": true,
- "openbsd/arm": true,
- "openbsd/arm64": true,
- "openbsd/mips64": true,
- "solaris/amd64": true,
- "windows/386": true,
- "windows/amd64": true,
- "windows/arm64": true,
-}
diff --git a/contrib/go/_std_1.20/src/go/constant/ya.make b/contrib/go/_std_1.20/src/go/constant/ya.make
deleted file mode 100644
index cb1687450e..0000000000
--- a/contrib/go/_std_1.20/src/go/constant/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- kind_string.go
- value.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/doc/comment/print.go b/contrib/go/_std_1.20/src/go/doc/comment/print.go
deleted file mode 100644
index 4e9da3d1e8..0000000000
--- a/contrib/go/_std_1.20/src/go/doc/comment/print.go
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright 2022 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 comment
-
-import (
- "bytes"
- "fmt"
- "strings"
-)
-
-// A Printer is a doc comment printer.
-// The fields in the struct can be filled in before calling
-// any of the printing methods
-// in order to customize the details of the printing process.
-type Printer struct {
- // HeadingLevel is the nesting level used for
- // HTML and Markdown headings.
- // If HeadingLevel is zero, it defaults to level 3,
- // meaning to use <h3> and ###.
- HeadingLevel int
-
- // HeadingID is a function that computes the heading ID
- // (anchor tag) to use for the heading h when generating
- // HTML and Markdown. If HeadingID returns an empty string,
- // then the heading ID is omitted.
- // If HeadingID is nil, h.DefaultID is used.
- HeadingID func(h *Heading) string
-
- // DocLinkURL is a function that computes the URL for the given DocLink.
- // If DocLinkURL is nil, then link.DefaultURL(p.DocLinkBaseURL) is used.
- DocLinkURL func(link *DocLink) string
-
- // DocLinkBaseURL is used when DocLinkURL is nil,
- // passed to [DocLink.DefaultURL] to construct a DocLink's URL.
- // See that method's documentation for details.
- DocLinkBaseURL string
-
- // TextPrefix is a prefix to print at the start of every line
- // when generating text output using the Text method.
- TextPrefix string
-
- // TextCodePrefix is the prefix to print at the start of each
- // preformatted (code block) line when generating text output,
- // instead of (not in addition to) TextPrefix.
- // If TextCodePrefix is the empty string, it defaults to TextPrefix+"\t".
- TextCodePrefix string
-
- // TextWidth is the maximum width text line to generate,
- // measured in Unicode code points,
- // excluding TextPrefix and the newline character.
- // If TextWidth is zero, it defaults to 80 minus the number of code points in TextPrefix.
- // If TextWidth is negative, there is no limit.
- TextWidth int
-}
-
-func (p *Printer) headingLevel() int {
- if p.HeadingLevel <= 0 {
- return 3
- }
- return p.HeadingLevel
-}
-
-func (p *Printer) headingID(h *Heading) string {
- if p.HeadingID == nil {
- return h.DefaultID()
- }
- return p.HeadingID(h)
-}
-
-func (p *Printer) docLinkURL(link *DocLink) string {
- if p.DocLinkURL != nil {
- return p.DocLinkURL(link)
- }
- return link.DefaultURL(p.DocLinkBaseURL)
-}
-
-// DefaultURL constructs and returns the documentation URL for l,
-// using baseURL as a prefix for links to other packages.
-//
-// The possible forms returned by DefaultURL are:
-// - baseURL/ImportPath, for a link to another package
-// - baseURL/ImportPath#Name, for a link to a const, func, type, or var in another package
-// - baseURL/ImportPath#Recv.Name, for a link to a method in another package
-// - #Name, for a link to a const, func, type, or var in this package
-// - #Recv.Name, for a link to a method in this package
-//
-// If baseURL ends in a trailing slash, then DefaultURL inserts
-// a slash between ImportPath and # in the anchored forms.
-// For example, here are some baseURL values and URLs they can generate:
-//
-// "/pkg/" → "/pkg/math/#Sqrt"
-// "/pkg" → "/pkg/math#Sqrt"
-// "/" → "/math/#Sqrt"
-// "" → "/math#Sqrt"
-func (l *DocLink) DefaultURL(baseURL string) string {
- if l.ImportPath != "" {
- slash := ""
- if strings.HasSuffix(baseURL, "/") {
- slash = "/"
- } else {
- baseURL += "/"
- }
- switch {
- case l.Name == "":
- return baseURL + l.ImportPath + slash
- case l.Recv != "":
- return baseURL + l.ImportPath + slash + "#" + l.Recv + "." + l.Name
- default:
- return baseURL + l.ImportPath + slash + "#" + l.Name
- }
- }
- if l.Recv != "" {
- return "#" + l.Recv + "." + l.Name
- }
- return "#" + l.Name
-}
-
-// DefaultID returns the default anchor ID for the heading h.
-//
-// The default anchor ID is constructed by converting every
-// rune that is not alphanumeric ASCII to an underscore
-// and then adding the prefix “hdr-”.
-// For example, if the heading text is “Go Doc Comments”,
-// the default ID is “hdr-Go_Doc_Comments”.
-func (h *Heading) DefaultID() string {
- // Note: The “hdr-” prefix is important to avoid DOM clobbering attacks.
- // See https://pkg.go.dev/github.com/google/safehtml#Identifier.
- var out strings.Builder
- var p textPrinter
- p.oneLongLine(&out, h.Text)
- s := strings.TrimSpace(out.String())
- if s == "" {
- return ""
- }
- out.Reset()
- out.WriteString("hdr-")
- for _, r := range s {
- if r < 0x80 && isIdentASCII(byte(r)) {
- out.WriteByte(byte(r))
- } else {
- out.WriteByte('_')
- }
- }
- return out.String()
-}
-
-type commentPrinter struct {
- *Printer
- headingPrefix string
- needDoc map[string]bool
-}
-
-// Comment returns the standard Go formatting of the Doc,
-// without any comment markers.
-func (p *Printer) Comment(d *Doc) []byte {
- cp := &commentPrinter{Printer: p}
- var out bytes.Buffer
- for i, x := range d.Content {
- if i > 0 && blankBefore(x) {
- out.WriteString("\n")
- }
- cp.block(&out, x)
- }
-
- // Print one block containing all the link definitions that were used,
- // and then a second block containing all the unused ones.
- // This makes it easy to clean up the unused ones: gofmt and
- // delete the final block. And it's a nice visual signal without
- // affecting the way the comment formats for users.
- for i := 0; i < 2; i++ {
- used := i == 0
- first := true
- for _, def := range d.Links {
- if def.Used == used {
- if first {
- out.WriteString("\n")
- first = false
- }
- out.WriteString("[")
- out.WriteString(def.Text)
- out.WriteString("]: ")
- out.WriteString(def.URL)
- out.WriteString("\n")
- }
- }
- }
-
- return out.Bytes()
-}
-
-// blankBefore reports whether the block x requires a blank line before it.
-// All blocks do, except for Lists that return false from x.BlankBefore().
-func blankBefore(x Block) bool {
- if x, ok := x.(*List); ok {
- return x.BlankBefore()
- }
- return true
-}
-
-// block prints the block x to out.
-func (p *commentPrinter) block(out *bytes.Buffer, x Block) {
- switch x := x.(type) {
- default:
- fmt.Fprintf(out, "?%T", x)
-
- case *Paragraph:
- p.text(out, "", x.Text)
- out.WriteString("\n")
-
- case *Heading:
- out.WriteString("# ")
- p.text(out, "", x.Text)
- out.WriteString("\n")
-
- case *Code:
- md := x.Text
- for md != "" {
- var line string
- line, md, _ = strings.Cut(md, "\n")
- if line != "" {
- out.WriteString("\t")
- out.WriteString(line)
- }
- out.WriteString("\n")
- }
-
- case *List:
- loose := x.BlankBetween()
- for i, item := range x.Items {
- if i > 0 && loose {
- out.WriteString("\n")
- }
- out.WriteString(" ")
- if item.Number == "" {
- out.WriteString(" - ")
- } else {
- out.WriteString(item.Number)
- out.WriteString(". ")
- }
- for i, blk := range item.Content {
- const fourSpace = " "
- if i > 0 {
- out.WriteString("\n" + fourSpace)
- }
- p.text(out, fourSpace, blk.(*Paragraph).Text)
- out.WriteString("\n")
- }
- }
- }
-}
-
-// text prints the text sequence x to out.
-func (p *commentPrinter) text(out *bytes.Buffer, indent string, x []Text) {
- for _, t := range x {
- switch t := t.(type) {
- case Plain:
- p.indent(out, indent, string(t))
- case Italic:
- p.indent(out, indent, string(t))
- case *Link:
- if t.Auto {
- p.text(out, indent, t.Text)
- } else {
- out.WriteString("[")
- p.text(out, indent, t.Text)
- out.WriteString("]")
- }
- case *DocLink:
- out.WriteString("[")
- p.text(out, indent, t.Text)
- out.WriteString("]")
- }
- }
-}
-
-// indent prints s to out, indenting with the indent string
-// after each newline in s.
-func (p *commentPrinter) indent(out *bytes.Buffer, indent, s string) {
- for s != "" {
- line, rest, ok := strings.Cut(s, "\n")
- out.WriteString(line)
- if ok {
- out.WriteString("\n")
- out.WriteString(indent)
- }
- s = rest
- }
-}
diff --git a/contrib/go/_std_1.20/src/go/doc/comment/std.go b/contrib/go/_std_1.20/src/go/doc/comment/std.go
deleted file mode 100644
index 71f15f47b1..0000000000
--- a/contrib/go/_std_1.20/src/go/doc/comment/std.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2022 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.
-
-// Code generated by 'go generate' DO NOT EDIT.
-//go:generate ./mkstd.sh
-
-package comment
-
-var stdPkgs = []string{
- "bufio",
- "bytes",
- "context",
- "crypto",
- "embed",
- "encoding",
- "errors",
- "expvar",
- "flag",
- "fmt",
- "hash",
- "html",
- "image",
- "io",
- "log",
- "math",
- "mime",
- "net",
- "os",
- "path",
- "plugin",
- "reflect",
- "regexp",
- "runtime",
- "sort",
- "strconv",
- "strings",
- "sync",
- "syscall",
- "testing",
- "time",
- "unicode",
- "unsafe",
-}
diff --git a/contrib/go/_std_1.20/src/go/doc/comment/ya.make b/contrib/go/_std_1.20/src/go/doc/comment/ya.make
deleted file mode 100644
index 2b775bb1a8..0000000000
--- a/contrib/go/_std_1.20/src/go/doc/comment/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- doc.go
- html.go
- markdown.go
- parse.go
- print.go
- std.go
- text.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/doc/ya.make b/contrib/go/_std_1.20/src/go/doc/ya.make
deleted file mode 100644
index b232c8f954..0000000000
--- a/contrib/go/_std_1.20/src/go/doc/ya.make
+++ /dev/null
@@ -1,17 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- comment.go
- doc.go
- example.go
- exports.go
- filter.go
- reader.go
- synopsis.go
-)
-
-END()
-
-RECURSE(
- comment
-)
diff --git a/contrib/go/_std_1.20/src/go/format/ya.make b/contrib/go/_std_1.20/src/go/format/ya.make
deleted file mode 100644
index f7f26ce7e6..0000000000
--- a/contrib/go/_std_1.20/src/go/format/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- format.go
- internal.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/importer/ya.make b/contrib/go/_std_1.20/src/go/importer/ya.make
deleted file mode 100644
index e08c6bb115..0000000000
--- a/contrib/go/_std_1.20/src/go/importer/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- importer.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/internal/gccgoimporter/ya.make b/contrib/go/_std_1.20/src/go/internal/gccgoimporter/ya.make
deleted file mode 100644
index 003ff5a8f2..0000000000
--- a/contrib/go/_std_1.20/src/go/internal/gccgoimporter/ya.make
+++ /dev/null
@@ -1,10 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- ar.go
- gccgoinstallation.go
- importer.go
- parser.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/internal/gcimporter/gcimporter.go b/contrib/go/_std_1.20/src/go/internal/gcimporter/gcimporter.go
deleted file mode 100644
index 284389aae7..0000000000
--- a/contrib/go/_std_1.20/src/go/internal/gcimporter/gcimporter.go
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2011 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 gcimporter implements Import for gc-generated object files.
-package gcimporter // import "go/internal/gcimporter"
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "go/build"
- "go/token"
- "go/types"
- "internal/pkgbits"
- "io"
- "os"
- "os/exec"
- "path/filepath"
- "strings"
- "sync"
-)
-
-// debugging/development support
-const debug = false
-
-var exportMap sync.Map // package dir → func() (string, bool)
-
-// lookupGorootExport returns the location of the export data
-// (normally found in the build cache, but located in GOROOT/pkg
-// in prior Go releases) for the package located in pkgDir.
-//
-// (We use the package's directory instead of its import path
-// mainly to simplify handling of the packages in src/vendor
-// and cmd/vendor.)
-func lookupGorootExport(pkgDir string) (string, bool) {
- f, ok := exportMap.Load(pkgDir)
- if !ok {
- var (
- listOnce sync.Once
- exportPath string
- )
- f, _ = exportMap.LoadOrStore(pkgDir, func() (string, bool) {
- listOnce.Do(func() {
- cmd := exec.Command(filepath.Join(build.Default.GOROOT, "bin", "go"), "list", "-export", "-f", "{{.Export}}", pkgDir)
- cmd.Dir = build.Default.GOROOT
- cmd.Env = append(cmd.Environ(), "GOROOT="+build.Default.GOROOT)
- var output []byte
- output, err := cmd.Output()
- if err != nil {
- return
- }
-
- exports := strings.Split(string(bytes.TrimSpace(output)), "\n")
- if len(exports) != 1 {
- return
- }
-
- exportPath = exports[0]
- })
-
- return exportPath, exportPath != ""
- })
- }
-
- return f.(func() (string, bool))()
-}
-
-var pkgExts = [...]string{".a", ".o"} // a file from the build cache will have no extension
-
-// FindPkg returns the filename and unique package id for an import
-// path based on package information provided by build.Import (using
-// the build.Default build.Context). A relative srcDir is interpreted
-// relative to the current working directory.
-// If no file was found, an empty filename is returned.
-func FindPkg(path, srcDir string) (filename, id string) {
- if path == "" {
- return
- }
-
- var noext string
- switch {
- default:
- // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
- // Don't require the source files to be present.
- if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
- srcDir = abs
- }
- bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
- if bp.PkgObj == "" {
- var ok bool
- if bp.Goroot && bp.Dir != "" {
- filename, ok = lookupGorootExport(bp.Dir)
- }
- if !ok {
- id = path // make sure we have an id to print in error message
- return
- }
- } else {
- noext = strings.TrimSuffix(bp.PkgObj, ".a")
- }
- id = bp.ImportPath
-
- case build.IsLocalImport(path):
- // "./x" -> "/this/directory/x.ext", "/this/directory/x"
- noext = filepath.Join(srcDir, path)
- id = noext
-
- case filepath.IsAbs(path):
- // for completeness only - go/build.Import
- // does not support absolute imports
- // "/x" -> "/x.ext", "/x"
- noext = path
- id = path
- }
-
- if false { // for debugging
- if path != id {
- fmt.Printf("%s -> %s\n", path, id)
- }
- }
-
- if filename != "" {
- if f, err := os.Stat(filename); err == nil && !f.IsDir() {
- return
- }
- }
- // try extensions
- for _, ext := range pkgExts {
- filename = noext + ext
- if f, err := os.Stat(filename); err == nil && !f.IsDir() {
- return
- }
- }
-
- filename = "" // not found
- return
-}
-
-// Import imports a gc-generated package given its import path and srcDir, adds
-// the corresponding package object to the packages map, and returns the object.
-// The packages map must contain all packages already imported.
-func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
- var rc io.ReadCloser
- var id string
- if lookup != nil {
- // With custom lookup specified, assume that caller has
- // converted path to a canonical import path for use in the map.
- if path == "unsafe" {
- return types.Unsafe, nil
- }
- id = path
-
- // No need to re-import if the package was imported completely before.
- if pkg = packages[id]; pkg != nil && pkg.Complete() {
- return
- }
- f, err := lookup(path)
- if err != nil {
- return nil, err
- }
- rc = f
- } else {
- var filename string
- filename, id = FindPkg(path, srcDir)
- if filename == "" {
- if path == "unsafe" {
- return types.Unsafe, nil
- }
- return nil, fmt.Errorf("can't find import: %q", id)
- }
-
- // no need to re-import if the package was imported completely before
- if pkg = packages[id]; pkg != nil && pkg.Complete() {
- return
- }
-
- // open file
- f, err := os.Open(filename)
- if err != nil {
- return nil, err
- }
- defer func() {
- if err != nil {
- // add file name to error
- err = fmt.Errorf("%s: %v", filename, err)
- }
- }()
- rc = f
- }
- defer rc.Close()
-
- buf := bufio.NewReader(rc)
- hdr, size, err := FindExportData(buf)
- if err != nil {
- return
- }
-
- switch hdr {
- case "$$\n":
- err = fmt.Errorf("import %q: old textual export format no longer supported (recompile library)", path)
-
- case "$$B\n":
- var exportFormat byte
- if exportFormat, err = buf.ReadByte(); err != nil {
- return
- }
-
- // The unified export format starts with a 'u'; the indexed export
- // format starts with an 'i'; and the older binary export format
- // starts with a 'c', 'd', or 'v' (from "version"). Select
- // appropriate importer.
- switch exportFormat {
- case 'u':
- var data []byte
- var r io.Reader = buf
- if size >= 0 {
- r = io.LimitReader(r, int64(size))
- }
- if data, err = io.ReadAll(r); err != nil {
- return
- }
- s := string(data)
- s = s[:strings.LastIndex(s, "\n$$\n")]
-
- input := pkgbits.NewPkgDecoder(id, s)
- pkg = readUnifiedPackage(fset, nil, packages, input)
- case 'i':
- pkg, err = iImportData(fset, packages, buf, id)
- default:
- err = fmt.Errorf("import %q: old binary export format no longer supported (recompile library)", path)
- }
-
- default:
- err = fmt.Errorf("import %q: unknown export data header: %q", path, hdr)
- }
-
- return
-}
-
-type byPath []*types.Package
-
-func (a byPath) Len() int { return len(a) }
-func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
diff --git a/contrib/go/_std_1.20/src/go/internal/gcimporter/ureader.go b/contrib/go/_std_1.20/src/go/internal/gcimporter/ureader.go
deleted file mode 100644
index ffd8402202..0000000000
--- a/contrib/go/_std_1.20/src/go/internal/gcimporter/ureader.go
+++ /dev/null
@@ -1,682 +0,0 @@
-// 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 gcimporter
-
-import (
- "go/token"
- "go/types"
- "internal/pkgbits"
-)
-
-// A pkgReader holds the shared state for reading a unified IR package
-// description.
-type pkgReader struct {
- pkgbits.PkgDecoder
-
- fake fakeFileSet
-
- ctxt *types.Context
- imports map[string]*types.Package // previously imported packages, indexed by path
-
- // lazily initialized arrays corresponding to the unified IR
- // PosBase, Pkg, and Type sections, respectively.
- posBases []string // position bases (i.e., file names)
- pkgs []*types.Package
- typs []types.Type
-
- // laterFns holds functions that need to be invoked at the end of
- // import reading.
- laterFns []func()
-
- // ifaces holds a list of constructed Interfaces, which need to have
- // Complete called after importing is done.
- ifaces []*types.Interface
-}
-
-// later adds a function to be invoked at the end of import reading.
-func (pr *pkgReader) later(fn func()) {
- pr.laterFns = append(pr.laterFns, fn)
-}
-
-// readUnifiedPackage reads a package description from the given
-// unified IR export data decoder.
-func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package {
- pr := pkgReader{
- PkgDecoder: input,
-
- fake: fakeFileSet{
- fset: fset,
- files: make(map[string]*fileInfo),
- },
-
- ctxt: ctxt,
- imports: imports,
-
- posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)),
- pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)),
- typs: make([]types.Type, input.NumElems(pkgbits.RelocType)),
- }
- defer pr.fake.setLines()
-
- r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
- pkg := r.pkg()
- r.Bool() // TODO(mdempsky): Remove; was "has init"
-
- for i, n := 0, r.Len(); i < n; i++ {
- // As if r.obj(), but avoiding the Scope.Lookup call,
- // to avoid eager loading of imports.
- r.Sync(pkgbits.SyncObject)
- assert(!r.Bool())
- r.p.objIdx(r.Reloc(pkgbits.RelocObj))
- assert(r.Len() == 0)
- }
-
- r.Sync(pkgbits.SyncEOF)
-
- for _, fn := range pr.laterFns {
- fn()
- }
-
- for _, iface := range pr.ifaces {
- iface.Complete()
- }
-
- pkg.MarkComplete()
- return pkg
-}
-
-// A reader holds the state for reading a single unified IR element
-// within a package.
-type reader struct {
- pkgbits.Decoder
-
- p *pkgReader
-
- dict *readerDict
-}
-
-// A readerDict holds the state for type parameters that parameterize
-// the current unified IR element.
-type readerDict struct {
- // bounds is a slice of typeInfos corresponding to the underlying
- // bounds of the element's type parameters.
- bounds []typeInfo
-
- // tparams is a slice of the constructed TypeParams for the element.
- tparams []*types.TypeParam
-
- // devived is a slice of types derived from tparams, which may be
- // instantiated while reading the current element.
- derived []derivedInfo
- derivedTypes []types.Type // lazily instantiated from derived
-}
-
-func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
- return &reader{
- Decoder: pr.NewDecoder(k, idx, marker),
- p: pr,
- }
-}
-
-func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
- return &reader{
- Decoder: pr.TempDecoder(k, idx, marker),
- p: pr,
- }
-}
-
-func (pr *pkgReader) retireReader(r *reader) {
- pr.RetireDecoder(&r.Decoder)
-}
-
-// @@@ Positions
-
-func (r *reader) pos() token.Pos {
- r.Sync(pkgbits.SyncPos)
- if !r.Bool() {
- return token.NoPos
- }
-
- // TODO(mdempsky): Delta encoding.
- posBase := r.posBase()
- line := r.Uint()
- col := r.Uint()
- return r.p.fake.pos(posBase, int(line), int(col))
-}
-
-func (r *reader) posBase() string {
- return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase))
-}
-
-func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string {
- if b := pr.posBases[idx]; b != "" {
- return b
- }
-
- var filename string
- {
- r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
-
- // Within types2, position bases have a lot more details (e.g.,
- // keeping track of where //line directives appeared exactly).
- //
- // For go/types, we just track the file name.
-
- filename = r.String()
-
- if r.Bool() { // file base
- // Was: "b = token.NewTrimmedFileBase(filename, true)"
- } else { // line base
- pos := r.pos()
- line := r.Uint()
- col := r.Uint()
-
- // Was: "b = token.NewLineBase(pos, filename, true, line, col)"
- _, _, _ = pos, line, col
- }
- pr.retireReader(r)
- }
- b := filename
- pr.posBases[idx] = b
- return b
-}
-
-// @@@ Packages
-
-func (r *reader) pkg() *types.Package {
- r.Sync(pkgbits.SyncPkg)
- return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
-}
-
-func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package {
- // TODO(mdempsky): Consider using some non-nil pointer to indicate
- // the universe scope, so we don't need to keep re-reading it.
- if pkg := pr.pkgs[idx]; pkg != nil {
- return pkg
- }
-
- pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg()
- pr.pkgs[idx] = pkg
- return pkg
-}
-
-func (r *reader) doPkg() *types.Package {
- path := r.String()
- switch path {
- case "":
- path = r.p.PkgPath()
- case "builtin":
- return nil // universe
- case "unsafe":
- return types.Unsafe
- }
-
- if pkg := r.p.imports[path]; pkg != nil {
- return pkg
- }
-
- name := r.String()
-
- pkg := types.NewPackage(path, name)
- r.p.imports[path] = pkg
-
- imports := make([]*types.Package, r.Len())
- for i := range imports {
- imports[i] = r.pkg()
- }
-
- // The documentation for (*types.Package).Imports requires
- // flattening the import graph when reading from export data, as
- // obviously incorrect as that is.
- //
- // TODO(mdempsky): Remove this if go.dev/issue/54096 is accepted.
- pkg.SetImports(flattenImports(imports))
-
- return pkg
-}
-
-// flattenImports returns the transitive closure of all imported
-// packages rooted from pkgs.
-func flattenImports(pkgs []*types.Package) []*types.Package {
- var res []*types.Package
- seen := make(map[*types.Package]struct{})
- for _, pkg := range pkgs {
- if _, ok := seen[pkg]; ok {
- continue
- }
- seen[pkg] = struct{}{}
- res = append(res, pkg)
-
- // pkg.Imports() is already flattened.
- for _, pkg := range pkg.Imports() {
- if _, ok := seen[pkg]; ok {
- continue
- }
- seen[pkg] = struct{}{}
- res = append(res, pkg)
- }
- }
- return res
-}
-
-// @@@ Types
-
-func (r *reader) typ() types.Type {
- return r.p.typIdx(r.typInfo(), r.dict)
-}
-
-func (r *reader) typInfo() typeInfo {
- r.Sync(pkgbits.SyncType)
- if r.Bool() {
- return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
- }
- return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
-}
-
-func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type {
- idx := info.idx
- var where *types.Type
- if info.derived {
- where = &dict.derivedTypes[idx]
- idx = dict.derived[idx].idx
- } else {
- where = &pr.typs[idx]
- }
-
- if typ := *where; typ != nil {
- return typ
- }
-
- var typ types.Type
- {
- r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
- r.dict = dict
-
- typ = r.doTyp()
- assert(typ != nil)
- pr.retireReader(r)
- }
- // See comment in pkgReader.typIdx explaining how this happens.
- if prev := *where; prev != nil {
- return prev
- }
-
- *where = typ
- return typ
-}
-
-func (r *reader) doTyp() (res types.Type) {
- switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
- default:
- errorf("unhandled type tag: %v", tag)
- panic("unreachable")
-
- case pkgbits.TypeBasic:
- return types.Typ[r.Len()]
-
- case pkgbits.TypeNamed:
- obj, targs := r.obj()
- name := obj.(*types.TypeName)
- if len(targs) != 0 {
- t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false)
- return t
- }
- return name.Type()
-
- case pkgbits.TypeTypeParam:
- return r.dict.tparams[r.Len()]
-
- case pkgbits.TypeArray:
- len := int64(r.Uint64())
- return types.NewArray(r.typ(), len)
- case pkgbits.TypeChan:
- dir := types.ChanDir(r.Len())
- return types.NewChan(dir, r.typ())
- case pkgbits.TypeMap:
- return types.NewMap(r.typ(), r.typ())
- case pkgbits.TypePointer:
- return types.NewPointer(r.typ())
- case pkgbits.TypeSignature:
- return r.signature(nil, nil, nil)
- case pkgbits.TypeSlice:
- return types.NewSlice(r.typ())
- case pkgbits.TypeStruct:
- return r.structType()
- case pkgbits.TypeInterface:
- return r.interfaceType()
- case pkgbits.TypeUnion:
- return r.unionType()
- }
-}
-
-func (r *reader) structType() *types.Struct {
- fields := make([]*types.Var, r.Len())
- var tags []string
- for i := range fields {
- pos := r.pos()
- pkg, name := r.selector()
- ftyp := r.typ()
- tag := r.String()
- embedded := r.Bool()
-
- fields[i] = types.NewField(pos, pkg, name, ftyp, embedded)
- if tag != "" {
- for len(tags) < i {
- tags = append(tags, "")
- }
- tags = append(tags, tag)
- }
- }
- return types.NewStruct(fields, tags)
-}
-
-func (r *reader) unionType() *types.Union {
- terms := make([]*types.Term, r.Len())
- for i := range terms {
- terms[i] = types.NewTerm(r.Bool(), r.typ())
- }
- return types.NewUnion(terms)
-}
-
-func (r *reader) interfaceType() *types.Interface {
- methods := make([]*types.Func, r.Len())
- embeddeds := make([]types.Type, r.Len())
- implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool()
-
- for i := range methods {
- pos := r.pos()
- pkg, name := r.selector()
- mtyp := r.signature(nil, nil, nil)
- methods[i] = types.NewFunc(pos, pkg, name, mtyp)
- }
-
- for i := range embeddeds {
- embeddeds[i] = r.typ()
- }
-
- iface := types.NewInterfaceType(methods, embeddeds)
- if implicit {
- iface.MarkImplicit()
- }
-
- // We need to call iface.Complete(), but if there are any embedded
- // defined types, then we may not have set their underlying
- // interface type yet. So we need to defer calling Complete until
- // after we've called SetUnderlying everywhere.
- //
- // TODO(mdempsky): After CL 424876 lands, it should be safe to call
- // iface.Complete() immediately.
- r.p.ifaces = append(r.p.ifaces, iface)
-
- return iface
-}
-
-func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature {
- r.Sync(pkgbits.SyncSignature)
-
- params := r.params()
- results := r.params()
- variadic := r.Bool()
-
- return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic)
-}
-
-func (r *reader) params() *types.Tuple {
- r.Sync(pkgbits.SyncParams)
-
- params := make([]*types.Var, r.Len())
- for i := range params {
- params[i] = r.param()
- }
-
- return types.NewTuple(params...)
-}
-
-func (r *reader) param() *types.Var {
- r.Sync(pkgbits.SyncParam)
-
- pos := r.pos()
- pkg, name := r.localIdent()
- typ := r.typ()
-
- return types.NewParam(pos, pkg, name, typ)
-}
-
-// @@@ Objects
-
-func (r *reader) obj() (types.Object, []types.Type) {
- r.Sync(pkgbits.SyncObject)
-
- assert(!r.Bool())
-
- pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj))
- obj := pkgScope(pkg).Lookup(name)
-
- targs := make([]types.Type, r.Len())
- for i := range targs {
- targs[i] = r.typ()
- }
-
- return obj, targs
-}
-
-func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
-
- var objPkg *types.Package
- var objName string
- var tag pkgbits.CodeObj
- {
- rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
-
- objPkg, objName = rname.qualifiedIdent()
- assert(objName != "")
-
- tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
- pr.retireReader(rname)
- }
-
- if tag == pkgbits.ObjStub {
- assert(objPkg == nil || objPkg == types.Unsafe)
- return objPkg, objName
- }
-
- // Ignore local types promoted to global scope (#55110).
- if _, suffix := splitVargenSuffix(objName); suffix != "" {
- return objPkg, objName
- }
-
- if objPkg.Scope().Lookup(objName) == nil {
- dict := pr.objDictIdx(idx)
-
- r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1)
- r.dict = dict
-
- declare := func(obj types.Object) {
- objPkg.Scope().Insert(obj)
- }
-
- switch tag {
- default:
- panic("weird")
-
- case pkgbits.ObjAlias:
- pos := r.pos()
- typ := r.typ()
- declare(types.NewTypeName(pos, objPkg, objName, typ))
-
- case pkgbits.ObjConst:
- pos := r.pos()
- typ := r.typ()
- val := r.Value()
- declare(types.NewConst(pos, objPkg, objName, typ, val))
-
- case pkgbits.ObjFunc:
- pos := r.pos()
- tparams := r.typeParamNames()
- sig := r.signature(nil, nil, tparams)
- declare(types.NewFunc(pos, objPkg, objName, sig))
-
- case pkgbits.ObjType:
- pos := r.pos()
-
- obj := types.NewTypeName(pos, objPkg, objName, nil)
- named := types.NewNamed(obj, nil, nil)
- declare(obj)
-
- named.SetTypeParams(r.typeParamNames())
-
- underlying := r.typ().Underlying()
-
- // If the underlying type is an interface, we need to
- // duplicate its methods so we can replace the receiver
- // parameter's type (#49906).
- if iface, ok := underlying.(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
- methods := make([]*types.Func, iface.NumExplicitMethods())
- for i := range methods {
- fn := iface.ExplicitMethod(i)
- sig := fn.Type().(*types.Signature)
-
- recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named)
- methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic()))
- }
-
- embeds := make([]types.Type, iface.NumEmbeddeds())
- for i := range embeds {
- embeds[i] = iface.EmbeddedType(i)
- }
-
- newIface := types.NewInterfaceType(methods, embeds)
- r.p.ifaces = append(r.p.ifaces, newIface)
- underlying = newIface
- }
-
- named.SetUnderlying(underlying)
-
- for i, n := 0, r.Len(); i < n; i++ {
- named.AddMethod(r.method())
- }
-
- case pkgbits.ObjVar:
- pos := r.pos()
- typ := r.typ()
- declare(types.NewVar(pos, objPkg, objName, typ))
- }
- }
-
- return objPkg, objName
-}
-
-func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
-
- var dict readerDict
-
- {
- r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
- if implicits := r.Len(); implicits != 0 {
- errorf("unexpected object with %v implicit type parameter(s)", implicits)
- }
-
- dict.bounds = make([]typeInfo, r.Len())
- for i := range dict.bounds {
- dict.bounds[i] = r.typInfo()
- }
-
- dict.derived = make([]derivedInfo, r.Len())
- dict.derivedTypes = make([]types.Type, len(dict.derived))
- for i := range dict.derived {
- dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
- }
-
- pr.retireReader(r)
- }
- // function references follow, but reader doesn't need those
-
- return &dict
-}
-
-func (r *reader) typeParamNames() []*types.TypeParam {
- r.Sync(pkgbits.SyncTypeParamNames)
-
- // Note: This code assumes it only processes objects without
- // implement type parameters. This is currently fine, because
- // reader is only used to read in exported declarations, which are
- // always package scoped.
-
- if len(r.dict.bounds) == 0 {
- return nil
- }
-
- // Careful: Type parameter lists may have cycles. To allow for this,
- // we construct the type parameter list in two passes: first we
- // create all the TypeNames and TypeParams, then we construct and
- // set the bound type.
-
- r.dict.tparams = make([]*types.TypeParam, len(r.dict.bounds))
- for i := range r.dict.bounds {
- pos := r.pos()
- pkg, name := r.localIdent()
-
- tname := types.NewTypeName(pos, pkg, name, nil)
- r.dict.tparams[i] = types.NewTypeParam(tname, nil)
- }
-
- typs := make([]types.Type, len(r.dict.bounds))
- for i, bound := range r.dict.bounds {
- typs[i] = r.p.typIdx(bound, r.dict)
- }
-
- // TODO(mdempsky): This is subtle, elaborate further.
- //
- // We have to save tparams outside of the closure, because
- // typeParamNames() can be called multiple times with the same
- // dictionary instance.
- //
- // Also, this needs to happen later to make sure SetUnderlying has
- // been called.
- //
- // TODO(mdempsky): Is it safe to have a single "later" slice or do
- // we need to have multiple passes? See comments on CL 386002 and
- // go.dev/issue/52104.
- tparams := r.dict.tparams
- r.p.later(func() {
- for i, typ := range typs {
- tparams[i].SetConstraint(typ)
- }
- })
-
- return r.dict.tparams
-}
-
-func (r *reader) method() *types.Func {
- r.Sync(pkgbits.SyncMethod)
- pos := r.pos()
- pkg, name := r.selector()
-
- rparams := r.typeParamNames()
- sig := r.signature(r.param(), rparams, nil)
-
- _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go.
- return types.NewFunc(pos, pkg, name, sig)
-}
-
-func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) }
-func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) }
-func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) }
-
-func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) {
- r.Sync(marker)
- return r.pkg(), r.String()
-}
-
-// pkgScope returns pkg.Scope().
-// If pkg is nil, it returns types.Universe instead.
-//
-// TODO(mdempsky): Remove after x/tools can depend on Go 1.19.
-func pkgScope(pkg *types.Package) *types.Scope {
- if pkg != nil {
- return pkg.Scope()
- }
- return types.Universe
-}
diff --git a/contrib/go/_std_1.20/src/go/internal/gcimporter/ya.make b/contrib/go/_std_1.20/src/go/internal/gcimporter/ya.make
deleted file mode 100644
index dd2dfb21d4..0000000000
--- a/contrib/go/_std_1.20/src/go/internal/gcimporter/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- exportdata.go
- gcimporter.go
- iimport.go
- support.go
- ureader.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/internal/srcimporter/ya.make b/contrib/go/_std_1.20/src/go/internal/srcimporter/ya.make
deleted file mode 100644
index 4248d120b1..0000000000
--- a/contrib/go/_std_1.20/src/go/internal/srcimporter/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- srcimporter.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/parser/parser.go b/contrib/go/_std_1.20/src/go/parser/parser.go
deleted file mode 100644
index fac24dfa05..0000000000
--- a/contrib/go/_std_1.20/src/go/parser/parser.go
+++ /dev/null
@@ -1,2864 +0,0 @@
-// Copyright 2009 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 parser implements a parser for Go source files. Input may be
-// provided in a variety of forms (see the various Parse* functions); the
-// output is an abstract syntax tree (AST) representing the Go source. The
-// parser is invoked through one of the Parse* functions.
-//
-// The parser accepts a larger language than is syntactically permitted by
-// the Go spec, for simplicity, and for improved robustness in the presence
-// of syntax errors. For instance, in method declarations, the receiver is
-// treated like an ordinary parameter list and thus may contain multiple
-// entries where the spec permits exactly one. Consequently, the corresponding
-// field in the AST (ast.FuncDecl.Recv) field is not restricted to one entry.
-package parser
-
-import (
- "fmt"
- "go/ast"
- "go/internal/typeparams"
- "go/scanner"
- "go/token"
-)
-
-// The parser structure holds the parser's internal state.
-type parser struct {
- file *token.File
- errors scanner.ErrorList
- scanner scanner.Scanner
-
- // Tracing/debugging
- mode Mode // parsing mode
- trace bool // == (mode&Trace != 0)
- indent int // indentation used for tracing output
-
- // Comments
- comments []*ast.CommentGroup
- leadComment *ast.CommentGroup // last lead comment
- lineComment *ast.CommentGroup // last line comment
-
- // Next token
- pos token.Pos // token position
- tok token.Token // one token look-ahead
- lit string // token literal
-
- // Error recovery
- // (used to limit the number of calls to parser.advance
- // w/o making scanning progress - avoids potential endless
- // loops across multiple parser functions during error recovery)
- syncPos token.Pos // last synchronization position
- syncCnt int // number of parser.advance calls without progress
-
- // Non-syntactic parser control
- exprLev int // < 0: in control clause, >= 0: in expression
- inRhs bool // if set, the parser is parsing a rhs expression
-
- imports []*ast.ImportSpec // list of imports
-
- // nestLev is used to track and limit the recursion depth
- // during parsing.
- nestLev int
-}
-
-func (p *parser) init(fset *token.FileSet, filename string, src []byte, mode Mode) {
- p.file = fset.AddFile(filename, -1, len(src))
- var m scanner.Mode
- if mode&ParseComments != 0 {
- m = scanner.ScanComments
- }
- eh := func(pos token.Position, msg string) { p.errors.Add(pos, msg) }
- p.scanner.Init(p.file, src, eh, m)
-
- p.mode = mode
- p.trace = mode&Trace != 0 // for convenience (p.trace is used frequently)
- p.next()
-}
-
-// ----------------------------------------------------------------------------
-// Parsing support
-
-func (p *parser) printTrace(a ...any) {
- const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
- const n = len(dots)
- pos := p.file.Position(p.pos)
- fmt.Printf("%5d:%3d: ", pos.Line, pos.Column)
- i := 2 * p.indent
- for i > n {
- fmt.Print(dots)
- i -= n
- }
- // i <= n
- fmt.Print(dots[0:i])
- fmt.Println(a...)
-}
-
-func trace(p *parser, msg string) *parser {
- p.printTrace(msg, "(")
- p.indent++
- return p
-}
-
-// Usage pattern: defer un(trace(p, "..."))
-func un(p *parser) {
- p.indent--
- p.printTrace(")")
-}
-
-// maxNestLev is the deepest we're willing to recurse during parsing
-const maxNestLev int = 1e5
-
-func incNestLev(p *parser) *parser {
- p.nestLev++
- if p.nestLev > maxNestLev {
- p.error(p.pos, "exceeded max nesting depth")
- panic(bailout{})
- }
- return p
-}
-
-// decNestLev is used to track nesting depth during parsing to prevent stack exhaustion.
-// It is used along with incNestLev in a similar fashion to how un and trace are used.
-func decNestLev(p *parser) {
- p.nestLev--
-}
-
-// Advance to the next token.
-func (p *parser) next0() {
- // Because of one-token look-ahead, print the previous token
- // when tracing as it provides a more readable output. The
- // very first token (!p.pos.IsValid()) is not initialized
- // (it is token.ILLEGAL), so don't print it.
- if p.trace && p.pos.IsValid() {
- s := p.tok.String()
- switch {
- case p.tok.IsLiteral():
- p.printTrace(s, p.lit)
- case p.tok.IsOperator(), p.tok.IsKeyword():
- p.printTrace("\"" + s + "\"")
- default:
- p.printTrace(s)
- }
- }
-
- p.pos, p.tok, p.lit = p.scanner.Scan()
-}
-
-// Consume a comment and return it and the line on which it ends.
-func (p *parser) consumeComment() (comment *ast.Comment, endline int) {
- // /*-style comments may end on a different line than where they start.
- // Scan the comment for '\n' chars and adjust endline accordingly.
- endline = p.file.Line(p.pos)
- if p.lit[1] == '*' {
- // don't use range here - no need to decode Unicode code points
- for i := 0; i < len(p.lit); i++ {
- if p.lit[i] == '\n' {
- endline++
- }
- }
- }
-
- comment = &ast.Comment{Slash: p.pos, Text: p.lit}
- p.next0()
-
- return
-}
-
-// Consume a group of adjacent comments, add it to the parser's
-// comments list, and return it together with the line at which
-// the last comment in the group ends. A non-comment token or n
-// empty lines terminate a comment group.
-func (p *parser) consumeCommentGroup(n int) (comments *ast.CommentGroup, endline int) {
- var list []*ast.Comment
- endline = p.file.Line(p.pos)
- for p.tok == token.COMMENT && p.file.Line(p.pos) <= endline+n {
- var comment *ast.Comment
- comment, endline = p.consumeComment()
- list = append(list, comment)
- }
-
- // add comment group to the comments list
- comments = &ast.CommentGroup{List: list}
- p.comments = append(p.comments, comments)
-
- return
-}
-
-// Advance to the next non-comment token. In the process, collect
-// any comment groups encountered, and remember the last lead and
-// line comments.
-//
-// A lead comment is a comment group that starts and ends in a
-// line without any other tokens and that is followed by a non-comment
-// token on the line immediately after the comment group.
-//
-// A line comment is a comment group that follows a non-comment
-// token on the same line, and that has no tokens after it on the line
-// where it ends.
-//
-// Lead and line comments may be considered documentation that is
-// stored in the AST.
-func (p *parser) next() {
- p.leadComment = nil
- p.lineComment = nil
- prev := p.pos
- p.next0()
-
- if p.tok == token.COMMENT {
- var comment *ast.CommentGroup
- var endline int
-
- if p.file.Line(p.pos) == p.file.Line(prev) {
- // The comment is on same line as the previous token; it
- // cannot be a lead comment but may be a line comment.
- comment, endline = p.consumeCommentGroup(0)
- if p.file.Line(p.pos) != endline || p.tok == token.SEMICOLON || p.tok == token.EOF {
- // The next token is on a different line, thus
- // the last comment group is a line comment.
- p.lineComment = comment
- }
- }
-
- // consume successor comments, if any
- endline = -1
- for p.tok == token.COMMENT {
- comment, endline = p.consumeCommentGroup(1)
- }
-
- if endline+1 == p.file.Line(p.pos) {
- // The next token is following on the line immediately after the
- // comment group, thus the last comment group is a lead comment.
- p.leadComment = comment
- }
- }
-}
-
-// A bailout panic is raised to indicate early termination. pos and msg are
-// only populated when bailing out of object resolution.
-type bailout struct {
- pos token.Pos
- msg string
-}
-
-func (p *parser) error(pos token.Pos, msg string) {
- if p.trace {
- defer un(trace(p, "error: "+msg))
- }
-
- epos := p.file.Position(pos)
-
- // If AllErrors is not set, discard errors reported on the same line
- // as the last recorded error and stop parsing if there are more than
- // 10 errors.
- if p.mode&AllErrors == 0 {
- n := len(p.errors)
- if n > 0 && p.errors[n-1].Pos.Line == epos.Line {
- return // discard - likely a spurious error
- }
- if n > 10 {
- panic(bailout{})
- }
- }
-
- p.errors.Add(epos, msg)
-}
-
-func (p *parser) errorExpected(pos token.Pos, msg string) {
- msg = "expected " + msg
- if pos == p.pos {
- // the error happened at the current position;
- // make the error message more specific
- switch {
- case p.tok == token.SEMICOLON && p.lit == "\n":
- msg += ", found newline"
- case p.tok.IsLiteral():
- // print 123 rather than 'INT', etc.
- msg += ", found " + p.lit
- default:
- msg += ", found '" + p.tok.String() + "'"
- }
- }
- p.error(pos, msg)
-}
-
-func (p *parser) expect(tok token.Token) token.Pos {
- pos := p.pos
- if p.tok != tok {
- p.errorExpected(pos, "'"+tok.String()+"'")
- }
- p.next() // make progress
- return pos
-}
-
-// expect2 is like expect, but it returns an invalid position
-// if the expected token is not found.
-func (p *parser) expect2(tok token.Token) (pos token.Pos) {
- if p.tok == tok {
- pos = p.pos
- } else {
- p.errorExpected(p.pos, "'"+tok.String()+"'")
- }
- p.next() // make progress
- return
-}
-
-// expectClosing is like expect but provides a better error message
-// for the common case of a missing comma before a newline.
-func (p *parser) expectClosing(tok token.Token, context string) token.Pos {
- if p.tok != tok && p.tok == token.SEMICOLON && p.lit == "\n" {
- p.error(p.pos, "missing ',' before newline in "+context)
- p.next()
- }
- return p.expect(tok)
-}
-
-// expectSemi consumes a semicolon and returns the applicable line comment.
-func (p *parser) expectSemi() (comment *ast.CommentGroup) {
- // semicolon is optional before a closing ')' or '}'
- if p.tok != token.RPAREN && p.tok != token.RBRACE {
- switch p.tok {
- case token.COMMA:
- // permit a ',' instead of a ';' but complain
- p.errorExpected(p.pos, "';'")
- fallthrough
- case token.SEMICOLON:
- if p.lit == ";" {
- // explicit semicolon
- p.next()
- comment = p.lineComment // use following comments
- } else {
- // artificial semicolon
- comment = p.lineComment // use preceding comments
- p.next()
- }
- return comment
- default:
- p.errorExpected(p.pos, "';'")
- p.advance(stmtStart)
- }
- }
- return nil
-}
-
-func (p *parser) atComma(context string, follow token.Token) bool {
- if p.tok == token.COMMA {
- return true
- }
- if p.tok != follow {
- msg := "missing ','"
- if p.tok == token.SEMICOLON && p.lit == "\n" {
- msg += " before newline"
- }
- p.error(p.pos, msg+" in "+context)
- return true // "insert" comma and continue
- }
- return false
-}
-
-func assert(cond bool, msg string) {
- if !cond {
- panic("go/parser internal error: " + msg)
- }
-}
-
-// advance consumes tokens until the current token p.tok
-// is in the 'to' set, or token.EOF. For error recovery.
-func (p *parser) advance(to map[token.Token]bool) {
- for ; p.tok != token.EOF; p.next() {
- if to[p.tok] {
- // Return only if parser made some progress since last
- // sync or if it has not reached 10 advance calls without
- // progress. Otherwise consume at least one token to
- // avoid an endless parser loop (it is possible that
- // both parseOperand and parseStmt call advance and
- // correctly do not advance, thus the need for the
- // invocation limit p.syncCnt).
- if p.pos == p.syncPos && p.syncCnt < 10 {
- p.syncCnt++
- return
- }
- if p.pos > p.syncPos {
- p.syncPos = p.pos
- p.syncCnt = 0
- return
- }
- // Reaching here indicates a parser bug, likely an
- // incorrect token list in this function, but it only
- // leads to skipping of possibly correct code if a
- // previous error is present, and thus is preferred
- // over a non-terminating parse.
- }
- }
-}
-
-var stmtStart = map[token.Token]bool{
- token.BREAK: true,
- token.CONST: true,
- token.CONTINUE: true,
- token.DEFER: true,
- token.FALLTHROUGH: true,
- token.FOR: true,
- token.GO: true,
- token.GOTO: true,
- token.IF: true,
- token.RETURN: true,
- token.SELECT: true,
- token.SWITCH: true,
- token.TYPE: true,
- token.VAR: true,
-}
-
-var declStart = map[token.Token]bool{
- token.IMPORT: true,
- token.CONST: true,
- token.TYPE: true,
- token.VAR: true,
-}
-
-var exprEnd = map[token.Token]bool{
- token.COMMA: true,
- token.COLON: true,
- token.SEMICOLON: true,
- token.RPAREN: true,
- token.RBRACK: true,
- token.RBRACE: true,
-}
-
-// safePos returns a valid file position for a given position: If pos
-// is valid to begin with, safePos returns pos. If pos is out-of-range,
-// safePos returns the EOF position.
-//
-// This is hack to work around "artificial" end positions in the AST which
-// are computed by adding 1 to (presumably valid) token positions. If the
-// token positions are invalid due to parse errors, the resulting end position
-// may be past the file's EOF position, which would lead to panics if used
-// later on.
-func (p *parser) safePos(pos token.Pos) (res token.Pos) {
- defer func() {
- if recover() != nil {
- res = token.Pos(p.file.Base() + p.file.Size()) // EOF position
- }
- }()
- _ = p.file.Offset(pos) // trigger a panic if position is out-of-range
- return pos
-}
-
-// ----------------------------------------------------------------------------
-// Identifiers
-
-func (p *parser) parseIdent() *ast.Ident {
- pos := p.pos
- name := "_"
- if p.tok == token.IDENT {
- name = p.lit
- p.next()
- } else {
- p.expect(token.IDENT) // use expect() error handling
- }
- return &ast.Ident{NamePos: pos, Name: name}
-}
-
-func (p *parser) parseIdentList() (list []*ast.Ident) {
- if p.trace {
- defer un(trace(p, "IdentList"))
- }
-
- list = append(list, p.parseIdent())
- for p.tok == token.COMMA {
- p.next()
- list = append(list, p.parseIdent())
- }
-
- return
-}
-
-// ----------------------------------------------------------------------------
-// Common productions
-
-// If lhs is set, result list elements which are identifiers are not resolved.
-func (p *parser) parseExprList() (list []ast.Expr) {
- if p.trace {
- defer un(trace(p, "ExpressionList"))
- }
-
- list = append(list, p.parseExpr())
- for p.tok == token.COMMA {
- p.next()
- list = append(list, p.parseExpr())
- }
-
- return
-}
-
-func (p *parser) parseList(inRhs bool) []ast.Expr {
- old := p.inRhs
- p.inRhs = inRhs
- list := p.parseExprList()
- p.inRhs = old
- return list
-}
-
-// ----------------------------------------------------------------------------
-// Types
-
-func (p *parser) parseType() ast.Expr {
- if p.trace {
- defer un(trace(p, "Type"))
- }
-
- typ := p.tryIdentOrType()
-
- if typ == nil {
- pos := p.pos
- p.errorExpected(pos, "type")
- p.advance(exprEnd)
- return &ast.BadExpr{From: pos, To: p.pos}
- }
-
- return typ
-}
-
-func (p *parser) parseQualifiedIdent(ident *ast.Ident) ast.Expr {
- if p.trace {
- defer un(trace(p, "QualifiedIdent"))
- }
-
- typ := p.parseTypeName(ident)
- if p.tok == token.LBRACK {
- typ = p.parseTypeInstance(typ)
- }
-
- return typ
-}
-
-// If the result is an identifier, it is not resolved.
-func (p *parser) parseTypeName(ident *ast.Ident) ast.Expr {
- if p.trace {
- defer un(trace(p, "TypeName"))
- }
-
- if ident == nil {
- ident = p.parseIdent()
- }
-
- if p.tok == token.PERIOD {
- // ident is a package name
- p.next()
- sel := p.parseIdent()
- return &ast.SelectorExpr{X: ident, Sel: sel}
- }
-
- return ident
-}
-
-// "[" has already been consumed, and lbrack is its position.
-// If len != nil it is the already consumed array length.
-func (p *parser) parseArrayType(lbrack token.Pos, len ast.Expr) *ast.ArrayType {
- if p.trace {
- defer un(trace(p, "ArrayType"))
- }
-
- if len == nil {
- p.exprLev++
- // always permit ellipsis for more fault-tolerant parsing
- if p.tok == token.ELLIPSIS {
- len = &ast.Ellipsis{Ellipsis: p.pos}
- p.next()
- } else if p.tok != token.RBRACK {
- len = p.parseRhs()
- }
- p.exprLev--
- }
- if p.tok == token.COMMA {
- // Trailing commas are accepted in type parameter
- // lists but not in array type declarations.
- // Accept for better error handling but complain.
- p.error(p.pos, "unexpected comma; expecting ]")
- p.next()
- }
- p.expect(token.RBRACK)
- elt := p.parseType()
- return &ast.ArrayType{Lbrack: lbrack, Len: len, Elt: elt}
-}
-
-func (p *parser) parseArrayFieldOrTypeInstance(x *ast.Ident) (*ast.Ident, ast.Expr) {
- if p.trace {
- defer un(trace(p, "ArrayFieldOrTypeInstance"))
- }
-
- lbrack := p.expect(token.LBRACK)
- trailingComma := token.NoPos // if valid, the position of a trailing comma preceding the ']'
- var args []ast.Expr
- if p.tok != token.RBRACK {
- p.exprLev++
- args = append(args, p.parseRhs())
- for p.tok == token.COMMA {
- comma := p.pos
- p.next()
- if p.tok == token.RBRACK {
- trailingComma = comma
- break
- }
- args = append(args, p.parseRhs())
- }
- p.exprLev--
- }
- rbrack := p.expect(token.RBRACK)
-
- if len(args) == 0 {
- // x []E
- elt := p.parseType()
- return x, &ast.ArrayType{Lbrack: lbrack, Elt: elt}
- }
-
- // x [P]E or x[P]
- if len(args) == 1 {
- elt := p.tryIdentOrType()
- if elt != nil {
- // x [P]E
- if trailingComma.IsValid() {
- // Trailing commas are invalid in array type fields.
- p.error(trailingComma, "unexpected comma; expecting ]")
- }
- return x, &ast.ArrayType{Lbrack: lbrack, Len: args[0], Elt: elt}
- }
- }
-
- // x[P], x[P1, P2], ...
- return nil, typeparams.PackIndexExpr(x, lbrack, args, rbrack)
-}
-
-func (p *parser) parseFieldDecl() *ast.Field {
- if p.trace {
- defer un(trace(p, "FieldDecl"))
- }
-
- doc := p.leadComment
-
- var names []*ast.Ident
- var typ ast.Expr
- switch p.tok {
- case token.IDENT:
- name := p.parseIdent()
- if p.tok == token.PERIOD || p.tok == token.STRING || p.tok == token.SEMICOLON || p.tok == token.RBRACE {
- // embedded type
- typ = name
- if p.tok == token.PERIOD {
- typ = p.parseQualifiedIdent(name)
- }
- } else {
- // name1, name2, ... T
- names = []*ast.Ident{name}
- for p.tok == token.COMMA {
- p.next()
- names = append(names, p.parseIdent())
- }
- // Careful dance: We don't know if we have an embedded instantiated
- // type T[P1, P2, ...] or a field T of array type []E or [P]E.
- if len(names) == 1 && p.tok == token.LBRACK {
- name, typ = p.parseArrayFieldOrTypeInstance(name)
- if name == nil {
- names = nil
- }
- } else {
- // T P
- typ = p.parseType()
- }
- }
- case token.MUL:
- star := p.pos
- p.next()
- if p.tok == token.LPAREN {
- // *(T)
- p.error(p.pos, "cannot parenthesize embedded type")
- p.next()
- typ = p.parseQualifiedIdent(nil)
- // expect closing ')' but no need to complain if missing
- if p.tok == token.RPAREN {
- p.next()
- }
- } else {
- // *T
- typ = p.parseQualifiedIdent(nil)
- }
- typ = &ast.StarExpr{Star: star, X: typ}
-
- case token.LPAREN:
- p.error(p.pos, "cannot parenthesize embedded type")
- p.next()
- if p.tok == token.MUL {
- // (*T)
- star := p.pos
- p.next()
- typ = &ast.StarExpr{Star: star, X: p.parseQualifiedIdent(nil)}
- } else {
- // (T)
- typ = p.parseQualifiedIdent(nil)
- }
- // expect closing ')' but no need to complain if missing
- if p.tok == token.RPAREN {
- p.next()
- }
-
- default:
- pos := p.pos
- p.errorExpected(pos, "field name or embedded type")
- p.advance(exprEnd)
- typ = &ast.BadExpr{From: pos, To: p.pos}
- }
-
- var tag *ast.BasicLit
- if p.tok == token.STRING {
- tag = &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit}
- p.next()
- }
-
- comment := p.expectSemi()
-
- field := &ast.Field{Doc: doc, Names: names, Type: typ, Tag: tag, Comment: comment}
- return field
-}
-
-func (p *parser) parseStructType() *ast.StructType {
- if p.trace {
- defer un(trace(p, "StructType"))
- }
-
- pos := p.expect(token.STRUCT)
- lbrace := p.expect(token.LBRACE)
- var list []*ast.Field
- for p.tok == token.IDENT || p.tok == token.MUL || p.tok == token.LPAREN {
- // a field declaration cannot start with a '(' but we accept
- // it here for more robust parsing and better error messages
- // (parseFieldDecl will check and complain if necessary)
- list = append(list, p.parseFieldDecl())
- }
- rbrace := p.expect(token.RBRACE)
-
- return &ast.StructType{
- Struct: pos,
- Fields: &ast.FieldList{
- Opening: lbrace,
- List: list,
- Closing: rbrace,
- },
- }
-}
-
-func (p *parser) parsePointerType() *ast.StarExpr {
- if p.trace {
- defer un(trace(p, "PointerType"))
- }
-
- star := p.expect(token.MUL)
- base := p.parseType()
-
- return &ast.StarExpr{Star: star, X: base}
-}
-
-func (p *parser) parseDotsType() *ast.Ellipsis {
- if p.trace {
- defer un(trace(p, "DotsType"))
- }
-
- pos := p.expect(token.ELLIPSIS)
- elt := p.parseType()
-
- return &ast.Ellipsis{Ellipsis: pos, Elt: elt}
-}
-
-type field struct {
- name *ast.Ident
- typ ast.Expr
-}
-
-func (p *parser) parseParamDecl(name *ast.Ident, typeSetsOK bool) (f field) {
- // TODO(rFindley) refactor to be more similar to paramDeclOrNil in the syntax
- // package
- if p.trace {
- defer un(trace(p, "ParamDeclOrNil"))
- }
-
- ptok := p.tok
- if name != nil {
- p.tok = token.IDENT // force token.IDENT case in switch below
- } else if typeSetsOK && p.tok == token.TILDE {
- // "~" ...
- return field{nil, p.embeddedElem(nil)}
- }
-
- switch p.tok {
- case token.IDENT:
- // name
- if name != nil {
- f.name = name
- p.tok = ptok
- } else {
- f.name = p.parseIdent()
- }
- switch p.tok {
- case token.IDENT, token.MUL, token.ARROW, token.FUNC, token.CHAN, token.MAP, token.STRUCT, token.INTERFACE, token.LPAREN:
- // name type
- f.typ = p.parseType()
-
- case token.LBRACK:
- // name "[" type1, ..., typeN "]" or name "[" n "]" type
- f.name, f.typ = p.parseArrayFieldOrTypeInstance(f.name)
-
- case token.ELLIPSIS:
- // name "..." type
- f.typ = p.parseDotsType()
- return // don't allow ...type "|" ...
-
- case token.PERIOD:
- // name "." ...
- f.typ = p.parseQualifiedIdent(f.name)
- f.name = nil
-
- case token.TILDE:
- if typeSetsOK {
- f.typ = p.embeddedElem(nil)
- return
- }
-
- case token.OR:
- if typeSetsOK {
- // name "|" typeset
- f.typ = p.embeddedElem(f.name)
- f.name = nil
- return
- }
- }
-
- case token.MUL, token.ARROW, token.FUNC, token.LBRACK, token.CHAN, token.MAP, token.STRUCT, token.INTERFACE, token.LPAREN:
- // type
- f.typ = p.parseType()
-
- case token.ELLIPSIS:
- // "..." type
- // (always accepted)
- f.typ = p.parseDotsType()
- return // don't allow ...type "|" ...
-
- default:
- // TODO(rfindley): this is incorrect in the case of type parameter lists
- // (should be "']'" in that case)
- p.errorExpected(p.pos, "')'")
- p.advance(exprEnd)
- }
-
- // [name] type "|"
- if typeSetsOK && p.tok == token.OR && f.typ != nil {
- f.typ = p.embeddedElem(f.typ)
- }
-
- return
-}
-
-func (p *parser) parseParameterList(name0 *ast.Ident, typ0 ast.Expr, closing token.Token) (params []*ast.Field) {
- if p.trace {
- defer un(trace(p, "ParameterList"))
- }
-
- // Type parameters are the only parameter list closed by ']'.
- tparams := closing == token.RBRACK
- // Type set notation is ok in type parameter lists.
- typeSetsOK := tparams
-
- pos := p.pos
- if name0 != nil {
- pos = name0.Pos()
- }
-
- var list []field
- var named int // number of parameters that have an explicit name and type
-
- for name0 != nil || p.tok != closing && p.tok != token.EOF {
- var par field
- if typ0 != nil {
- if typeSetsOK {
- typ0 = p.embeddedElem(typ0)
- }
- par = field{name0, typ0}
- } else {
- par = p.parseParamDecl(name0, typeSetsOK)
- }
- name0 = nil // 1st name was consumed if present
- typ0 = nil // 1st typ was consumed if present
- if par.name != nil || par.typ != nil {
- list = append(list, par)
- if par.name != nil && par.typ != nil {
- named++
- }
- }
- if !p.atComma("parameter list", closing) {
- break
- }
- p.next()
- }
-
- if len(list) == 0 {
- return // not uncommon
- }
-
- // TODO(gri) parameter distribution and conversion to []*ast.Field
- // can be combined and made more efficient
-
- // distribute parameter types
- if named == 0 {
- // all unnamed => found names are type names
- for i := 0; i < len(list); i++ {
- par := &list[i]
- if typ := par.name; typ != nil {
- par.typ = typ
- par.name = nil
- }
- }
- if tparams {
- p.error(pos, "type parameters must be named")
- }
- } else if named != len(list) {
- // some named => all must be named
- ok := true
- var typ ast.Expr
- missingName := pos
- for i := len(list) - 1; i >= 0; i-- {
- if par := &list[i]; par.typ != nil {
- typ = par.typ
- if par.name == nil {
- ok = false
- missingName = par.typ.Pos()
- n := ast.NewIdent("_")
- n.NamePos = typ.Pos() // correct position
- par.name = n
- }
- } else if typ != nil {
- par.typ = typ
- } else {
- // par.typ == nil && typ == nil => we only have a par.name
- ok = false
- missingName = par.name.Pos()
- par.typ = &ast.BadExpr{From: par.name.Pos(), To: p.pos}
- }
- }
- if !ok {
- if tparams {
- p.error(missingName, "type parameters must be named")
- } else {
- p.error(pos, "mixed named and unnamed parameters")
- }
- }
- }
-
- // convert list []*ast.Field
- if named == 0 {
- // parameter list consists of types only
- for _, par := range list {
- assert(par.typ != nil, "nil type in unnamed parameter list")
- params = append(params, &ast.Field{Type: par.typ})
- }
- return
- }
-
- // parameter list consists of named parameters with types
- var names []*ast.Ident
- var typ ast.Expr
- addParams := func() {
- assert(typ != nil, "nil type in named parameter list")
- field := &ast.Field{Names: names, Type: typ}
- params = append(params, field)
- names = nil
- }
- for _, par := range list {
- if par.typ != typ {
- if len(names) > 0 {
- addParams()
- }
- typ = par.typ
- }
- names = append(names, par.name)
- }
- if len(names) > 0 {
- addParams()
- }
- return
-}
-
-func (p *parser) parseParameters(acceptTParams bool) (tparams, params *ast.FieldList) {
- if p.trace {
- defer un(trace(p, "Parameters"))
- }
-
- if acceptTParams && p.tok == token.LBRACK {
- opening := p.pos
- p.next()
- // [T any](params) syntax
- list := p.parseParameterList(nil, nil, token.RBRACK)
- rbrack := p.expect(token.RBRACK)
- tparams = &ast.FieldList{Opening: opening, List: list, Closing: rbrack}
- // Type parameter lists must not be empty.
- if tparams.NumFields() == 0 {
- p.error(tparams.Closing, "empty type parameter list")
- tparams = nil // avoid follow-on errors
- }
- }
-
- opening := p.expect(token.LPAREN)
-
- var fields []*ast.Field
- if p.tok != token.RPAREN {
- fields = p.parseParameterList(nil, nil, token.RPAREN)
- }
-
- rparen := p.expect(token.RPAREN)
- params = &ast.FieldList{Opening: opening, List: fields, Closing: rparen}
-
- return
-}
-
-func (p *parser) parseResult() *ast.FieldList {
- if p.trace {
- defer un(trace(p, "Result"))
- }
-
- if p.tok == token.LPAREN {
- _, results := p.parseParameters(false)
- return results
- }
-
- typ := p.tryIdentOrType()
- if typ != nil {
- list := make([]*ast.Field, 1)
- list[0] = &ast.Field{Type: typ}
- return &ast.FieldList{List: list}
- }
-
- return nil
-}
-
-func (p *parser) parseFuncType() *ast.FuncType {
- if p.trace {
- defer un(trace(p, "FuncType"))
- }
-
- pos := p.expect(token.FUNC)
- tparams, params := p.parseParameters(true)
- if tparams != nil {
- p.error(tparams.Pos(), "function type must have no type parameters")
- }
- results := p.parseResult()
-
- return &ast.FuncType{Func: pos, Params: params, Results: results}
-}
-
-func (p *parser) parseMethodSpec() *ast.Field {
- if p.trace {
- defer un(trace(p, "MethodSpec"))
- }
-
- doc := p.leadComment
- var idents []*ast.Ident
- var typ ast.Expr
- x := p.parseTypeName(nil)
- if ident, _ := x.(*ast.Ident); ident != nil {
- switch {
- case p.tok == token.LBRACK:
- // generic method or embedded instantiated type
- lbrack := p.pos
- p.next()
- p.exprLev++
- x := p.parseExpr()
- p.exprLev--
- if name0, _ := x.(*ast.Ident); name0 != nil && p.tok != token.COMMA && p.tok != token.RBRACK {
- // generic method m[T any]
- //
- // Interface methods do not have type parameters. We parse them for a
- // better error message and improved error recovery.
- _ = p.parseParameterList(name0, nil, token.RBRACK)
- _ = p.expect(token.RBRACK)
- p.error(lbrack, "interface method must have no type parameters")
-
- // TODO(rfindley) refactor to share code with parseFuncType.
- _, params := p.parseParameters(false)
- results := p.parseResult()
- idents = []*ast.Ident{ident}
- typ = &ast.FuncType{
- Func: token.NoPos,
- Params: params,
- Results: results,
- }
- } else {
- // embedded instantiated type
- // TODO(rfindley) should resolve all identifiers in x.
- list := []ast.Expr{x}
- if p.atComma("type argument list", token.RBRACK) {
- p.exprLev++
- p.next()
- for p.tok != token.RBRACK && p.tok != token.EOF {
- list = append(list, p.parseType())
- if !p.atComma("type argument list", token.RBRACK) {
- break
- }
- p.next()
- }
- p.exprLev--
- }
- rbrack := p.expectClosing(token.RBRACK, "type argument list")
- typ = typeparams.PackIndexExpr(ident, lbrack, list, rbrack)
- }
- case p.tok == token.LPAREN:
- // ordinary method
- // TODO(rfindley) refactor to share code with parseFuncType.
- _, params := p.parseParameters(false)
- results := p.parseResult()
- idents = []*ast.Ident{ident}
- typ = &ast.FuncType{Func: token.NoPos, Params: params, Results: results}
- default:
- // embedded type
- typ = x
- }
- } else {
- // embedded, possibly instantiated type
- typ = x
- if p.tok == token.LBRACK {
- // embedded instantiated interface
- typ = p.parseTypeInstance(typ)
- }
- }
-
- // Comment is added at the callsite: the field below may joined with
- // additional type specs using '|'.
- // TODO(rfindley) this should be refactored.
- // TODO(rfindley) add more tests for comment handling.
- return &ast.Field{Doc: doc, Names: idents, Type: typ}
-}
-
-func (p *parser) embeddedElem(x ast.Expr) ast.Expr {
- if p.trace {
- defer un(trace(p, "EmbeddedElem"))
- }
- if x == nil {
- x = p.embeddedTerm()
- }
- for p.tok == token.OR {
- t := new(ast.BinaryExpr)
- t.OpPos = p.pos
- t.Op = token.OR
- p.next()
- t.X = x
- t.Y = p.embeddedTerm()
- x = t
- }
- return x
-}
-
-func (p *parser) embeddedTerm() ast.Expr {
- if p.trace {
- defer un(trace(p, "EmbeddedTerm"))
- }
- if p.tok == token.TILDE {
- t := new(ast.UnaryExpr)
- t.OpPos = p.pos
- t.Op = token.TILDE
- p.next()
- t.X = p.parseType()
- return t
- }
-
- t := p.tryIdentOrType()
- if t == nil {
- pos := p.pos
- p.errorExpected(pos, "~ term or type")
- p.advance(exprEnd)
- return &ast.BadExpr{From: pos, To: p.pos}
- }
-
- return t
-}
-
-func (p *parser) parseInterfaceType() *ast.InterfaceType {
- if p.trace {
- defer un(trace(p, "InterfaceType"))
- }
-
- pos := p.expect(token.INTERFACE)
- lbrace := p.expect(token.LBRACE)
-
- var list []*ast.Field
-
-parseElements:
- for {
- switch {
- case p.tok == token.IDENT:
- f := p.parseMethodSpec()
- if f.Names == nil {
- f.Type = p.embeddedElem(f.Type)
- }
- f.Comment = p.expectSemi()
- list = append(list, f)
- case p.tok == token.TILDE:
- typ := p.embeddedElem(nil)
- comment := p.expectSemi()
- list = append(list, &ast.Field{Type: typ, Comment: comment})
- default:
- if t := p.tryIdentOrType(); t != nil {
- typ := p.embeddedElem(t)
- comment := p.expectSemi()
- list = append(list, &ast.Field{Type: typ, Comment: comment})
- } else {
- break parseElements
- }
- }
- }
-
- // TODO(rfindley): the error produced here could be improved, since we could
- // accept a identifier, 'type', or a '}' at this point.
- rbrace := p.expect(token.RBRACE)
-
- return &ast.InterfaceType{
- Interface: pos,
- Methods: &ast.FieldList{
- Opening: lbrace,
- List: list,
- Closing: rbrace,
- },
- }
-}
-
-func (p *parser) parseMapType() *ast.MapType {
- if p.trace {
- defer un(trace(p, "MapType"))
- }
-
- pos := p.expect(token.MAP)
- p.expect(token.LBRACK)
- key := p.parseType()
- p.expect(token.RBRACK)
- value := p.parseType()
-
- return &ast.MapType{Map: pos, Key: key, Value: value}
-}
-
-func (p *parser) parseChanType() *ast.ChanType {
- if p.trace {
- defer un(trace(p, "ChanType"))
- }
-
- pos := p.pos
- dir := ast.SEND | ast.RECV
- var arrow token.Pos
- if p.tok == token.CHAN {
- p.next()
- if p.tok == token.ARROW {
- arrow = p.pos
- p.next()
- dir = ast.SEND
- }
- } else {
- arrow = p.expect(token.ARROW)
- p.expect(token.CHAN)
- dir = ast.RECV
- }
- value := p.parseType()
-
- return &ast.ChanType{Begin: pos, Arrow: arrow, Dir: dir, Value: value}
-}
-
-func (p *parser) parseTypeInstance(typ ast.Expr) ast.Expr {
- if p.trace {
- defer un(trace(p, "TypeInstance"))
- }
-
- opening := p.expect(token.LBRACK)
- p.exprLev++
- var list []ast.Expr
- for p.tok != token.RBRACK && p.tok != token.EOF {
- list = append(list, p.parseType())
- if !p.atComma("type argument list", token.RBRACK) {
- break
- }
- p.next()
- }
- p.exprLev--
-
- closing := p.expectClosing(token.RBRACK, "type argument list")
-
- if len(list) == 0 {
- p.errorExpected(closing, "type argument list")
- return &ast.IndexExpr{
- X: typ,
- Lbrack: opening,
- Index: &ast.BadExpr{From: opening + 1, To: closing},
- Rbrack: closing,
- }
- }
-
- return typeparams.PackIndexExpr(typ, opening, list, closing)
-}
-
-func (p *parser) tryIdentOrType() ast.Expr {
- defer decNestLev(incNestLev(p))
-
- switch p.tok {
- case token.IDENT:
- typ := p.parseTypeName(nil)
- if p.tok == token.LBRACK {
- typ = p.parseTypeInstance(typ)
- }
- return typ
- case token.LBRACK:
- lbrack := p.expect(token.LBRACK)
- return p.parseArrayType(lbrack, nil)
- case token.STRUCT:
- return p.parseStructType()
- case token.MUL:
- return p.parsePointerType()
- case token.FUNC:
- return p.parseFuncType()
- case token.INTERFACE:
- return p.parseInterfaceType()
- case token.MAP:
- return p.parseMapType()
- case token.CHAN, token.ARROW:
- return p.parseChanType()
- case token.LPAREN:
- lparen := p.pos
- p.next()
- typ := p.parseType()
- rparen := p.expect(token.RPAREN)
- return &ast.ParenExpr{Lparen: lparen, X: typ, Rparen: rparen}
- }
-
- // no type found
- return nil
-}
-
-// ----------------------------------------------------------------------------
-// Blocks
-
-func (p *parser) parseStmtList() (list []ast.Stmt) {
- if p.trace {
- defer un(trace(p, "StatementList"))
- }
-
- for p.tok != token.CASE && p.tok != token.DEFAULT && p.tok != token.RBRACE && p.tok != token.EOF {
- list = append(list, p.parseStmt())
- }
-
- return
-}
-
-func (p *parser) parseBody() *ast.BlockStmt {
- if p.trace {
- defer un(trace(p, "Body"))
- }
-
- lbrace := p.expect(token.LBRACE)
- list := p.parseStmtList()
- rbrace := p.expect2(token.RBRACE)
-
- return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
-}
-
-func (p *parser) parseBlockStmt() *ast.BlockStmt {
- if p.trace {
- defer un(trace(p, "BlockStmt"))
- }
-
- lbrace := p.expect(token.LBRACE)
- list := p.parseStmtList()
- rbrace := p.expect2(token.RBRACE)
-
- return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
-}
-
-// ----------------------------------------------------------------------------
-// Expressions
-
-func (p *parser) parseFuncTypeOrLit() ast.Expr {
- if p.trace {
- defer un(trace(p, "FuncTypeOrLit"))
- }
-
- typ := p.parseFuncType()
- if p.tok != token.LBRACE {
- // function type only
- return typ
- }
-
- p.exprLev++
- body := p.parseBody()
- p.exprLev--
-
- return &ast.FuncLit{Type: typ, Body: body}
-}
-
-// parseOperand may return an expression or a raw type (incl. array
-// types of the form [...]T). Callers must verify the result.
-func (p *parser) parseOperand() ast.Expr {
- if p.trace {
- defer un(trace(p, "Operand"))
- }
-
- switch p.tok {
- case token.IDENT:
- x := p.parseIdent()
- return x
-
- case token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING:
- x := &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit}
- p.next()
- return x
-
- case token.LPAREN:
- lparen := p.pos
- p.next()
- p.exprLev++
- x := p.parseRhs() // types may be parenthesized: (some type)
- p.exprLev--
- rparen := p.expect(token.RPAREN)
- return &ast.ParenExpr{Lparen: lparen, X: x, Rparen: rparen}
-
- case token.FUNC:
- return p.parseFuncTypeOrLit()
- }
-
- if typ := p.tryIdentOrType(); typ != nil { // do not consume trailing type parameters
- // could be type for composite literal or conversion
- _, isIdent := typ.(*ast.Ident)
- assert(!isIdent, "type cannot be identifier")
- return typ
- }
-
- // we have an error
- pos := p.pos
- p.errorExpected(pos, "operand")
- p.advance(stmtStart)
- return &ast.BadExpr{From: pos, To: p.pos}
-}
-
-func (p *parser) parseSelector(x ast.Expr) ast.Expr {
- if p.trace {
- defer un(trace(p, "Selector"))
- }
-
- sel := p.parseIdent()
-
- return &ast.SelectorExpr{X: x, Sel: sel}
-}
-
-func (p *parser) parseTypeAssertion(x ast.Expr) ast.Expr {
- if p.trace {
- defer un(trace(p, "TypeAssertion"))
- }
-
- lparen := p.expect(token.LPAREN)
- var typ ast.Expr
- if p.tok == token.TYPE {
- // type switch: typ == nil
- p.next()
- } else {
- typ = p.parseType()
- }
- rparen := p.expect(token.RPAREN)
-
- return &ast.TypeAssertExpr{X: x, Type: typ, Lparen: lparen, Rparen: rparen}
-}
-
-func (p *parser) parseIndexOrSliceOrInstance(x ast.Expr) ast.Expr {
- if p.trace {
- defer un(trace(p, "parseIndexOrSliceOrInstance"))
- }
-
- lbrack := p.expect(token.LBRACK)
- if p.tok == token.RBRACK {
- // empty index, slice or index expressions are not permitted;
- // accept them for parsing tolerance, but complain
- p.errorExpected(p.pos, "operand")
- rbrack := p.pos
- p.next()
- return &ast.IndexExpr{
- X: x,
- Lbrack: lbrack,
- Index: &ast.BadExpr{From: rbrack, To: rbrack},
- Rbrack: rbrack,
- }
- }
- p.exprLev++
-
- const N = 3 // change the 3 to 2 to disable 3-index slices
- var args []ast.Expr
- var index [N]ast.Expr
- var colons [N - 1]token.Pos
- if p.tok != token.COLON {
- // We can't know if we have an index expression or a type instantiation;
- // so even if we see a (named) type we are not going to be in type context.
- index[0] = p.parseRhs()
- }
- ncolons := 0
- switch p.tok {
- case token.COLON:
- // slice expression
- for p.tok == token.COLON && ncolons < len(colons) {
- colons[ncolons] = p.pos
- ncolons++
- p.next()
- if p.tok != token.COLON && p.tok != token.RBRACK && p.tok != token.EOF {
- index[ncolons] = p.parseRhs()
- }
- }
- case token.COMMA:
- // instance expression
- args = append(args, index[0])
- for p.tok == token.COMMA {
- p.next()
- if p.tok != token.RBRACK && p.tok != token.EOF {
- args = append(args, p.parseType())
- }
- }
- }
-
- p.exprLev--
- rbrack := p.expect(token.RBRACK)
-
- if ncolons > 0 {
- // slice expression
- slice3 := false
- if ncolons == 2 {
- slice3 = true
- // Check presence of middle and final index here rather than during type-checking
- // to prevent erroneous programs from passing through gofmt (was issue 7305).
- if index[1] == nil {
- p.error(colons[0], "middle index required in 3-index slice")
- index[1] = &ast.BadExpr{From: colons[0] + 1, To: colons[1]}
- }
- if index[2] == nil {
- p.error(colons[1], "final index required in 3-index slice")
- index[2] = &ast.BadExpr{From: colons[1] + 1, To: rbrack}
- }
- }
- return &ast.SliceExpr{X: x, Lbrack: lbrack, Low: index[0], High: index[1], Max: index[2], Slice3: slice3, Rbrack: rbrack}
- }
-
- if len(args) == 0 {
- // index expression
- return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: index[0], Rbrack: rbrack}
- }
-
- // instance expression
- return typeparams.PackIndexExpr(x, lbrack, args, rbrack)
-}
-
-func (p *parser) parseCallOrConversion(fun ast.Expr) *ast.CallExpr {
- if p.trace {
- defer un(trace(p, "CallOrConversion"))
- }
-
- lparen := p.expect(token.LPAREN)
- p.exprLev++
- var list []ast.Expr
- var ellipsis token.Pos
- for p.tok != token.RPAREN && p.tok != token.EOF && !ellipsis.IsValid() {
- list = append(list, p.parseRhs()) // builtins may expect a type: make(some type, ...)
- if p.tok == token.ELLIPSIS {
- ellipsis = p.pos
- p.next()
- }
- if !p.atComma("argument list", token.RPAREN) {
- break
- }
- p.next()
- }
- p.exprLev--
- rparen := p.expectClosing(token.RPAREN, "argument list")
-
- return &ast.CallExpr{Fun: fun, Lparen: lparen, Args: list, Ellipsis: ellipsis, Rparen: rparen}
-}
-
-func (p *parser) parseValue() ast.Expr {
- if p.trace {
- defer un(trace(p, "Element"))
- }
-
- if p.tok == token.LBRACE {
- return p.parseLiteralValue(nil)
- }
-
- x := p.parseExpr()
-
- return x
-}
-
-func (p *parser) parseElement() ast.Expr {
- if p.trace {
- defer un(trace(p, "Element"))
- }
-
- x := p.parseValue()
- if p.tok == token.COLON {
- colon := p.pos
- p.next()
- x = &ast.KeyValueExpr{Key: x, Colon: colon, Value: p.parseValue()}
- }
-
- return x
-}
-
-func (p *parser) parseElementList() (list []ast.Expr) {
- if p.trace {
- defer un(trace(p, "ElementList"))
- }
-
- for p.tok != token.RBRACE && p.tok != token.EOF {
- list = append(list, p.parseElement())
- if !p.atComma("composite literal", token.RBRACE) {
- break
- }
- p.next()
- }
-
- return
-}
-
-func (p *parser) parseLiteralValue(typ ast.Expr) ast.Expr {
- if p.trace {
- defer un(trace(p, "LiteralValue"))
- }
-
- lbrace := p.expect(token.LBRACE)
- var elts []ast.Expr
- p.exprLev++
- if p.tok != token.RBRACE {
- elts = p.parseElementList()
- }
- p.exprLev--
- rbrace := p.expectClosing(token.RBRACE, "composite literal")
- return &ast.CompositeLit{Type: typ, Lbrace: lbrace, Elts: elts, Rbrace: rbrace}
-}
-
-// If x is of the form (T), unparen returns unparen(T), otherwise it returns x.
-func unparen(x ast.Expr) ast.Expr {
- if p, isParen := x.(*ast.ParenExpr); isParen {
- x = unparen(p.X)
- }
- return x
-}
-
-func (p *parser) parsePrimaryExpr(x ast.Expr) ast.Expr {
- if p.trace {
- defer un(trace(p, "PrimaryExpr"))
- }
-
- if x == nil {
- x = p.parseOperand()
- }
- // We track the nesting here rather than at the entry for the function,
- // since it can iteratively produce a nested output, and we want to
- // limit how deep a structure we generate.
- var n int
- defer func() { p.nestLev -= n }()
- for n = 1; ; n++ {
- incNestLev(p)
- switch p.tok {
- case token.PERIOD:
- p.next()
- switch p.tok {
- case token.IDENT:
- x = p.parseSelector(x)
- case token.LPAREN:
- x = p.parseTypeAssertion(x)
- default:
- pos := p.pos
- p.errorExpected(pos, "selector or type assertion")
- // TODO(rFindley) The check for token.RBRACE below is a targeted fix
- // to error recovery sufficient to make the x/tools tests to
- // pass with the new parsing logic introduced for type
- // parameters. Remove this once error recovery has been
- // more generally reconsidered.
- if p.tok != token.RBRACE {
- p.next() // make progress
- }
- sel := &ast.Ident{NamePos: pos, Name: "_"}
- x = &ast.SelectorExpr{X: x, Sel: sel}
- }
- case token.LBRACK:
- x = p.parseIndexOrSliceOrInstance(x)
- case token.LPAREN:
- x = p.parseCallOrConversion(x)
- case token.LBRACE:
- // operand may have returned a parenthesized complit
- // type; accept it but complain if we have a complit
- t := unparen(x)
- // determine if '{' belongs to a composite literal or a block statement
- switch t.(type) {
- case *ast.BadExpr, *ast.Ident, *ast.SelectorExpr:
- if p.exprLev < 0 {
- return x
- }
- // x is possibly a composite literal type
- case *ast.IndexExpr, *ast.IndexListExpr:
- if p.exprLev < 0 {
- return x
- }
- // x is possibly a composite literal type
- case *ast.ArrayType, *ast.StructType, *ast.MapType:
- // x is a composite literal type
- default:
- return x
- }
- if t != x {
- p.error(t.Pos(), "cannot parenthesize type in composite literal")
- // already progressed, no need to advance
- }
- x = p.parseLiteralValue(x)
- default:
- return x
- }
- }
-}
-
-func (p *parser) parseUnaryExpr() ast.Expr {
- defer decNestLev(incNestLev(p))
-
- if p.trace {
- defer un(trace(p, "UnaryExpr"))
- }
-
- switch p.tok {
- case token.ADD, token.SUB, token.NOT, token.XOR, token.AND, token.TILDE:
- pos, op := p.pos, p.tok
- p.next()
- x := p.parseUnaryExpr()
- return &ast.UnaryExpr{OpPos: pos, Op: op, X: x}
-
- case token.ARROW:
- // channel type or receive expression
- arrow := p.pos
- p.next()
-
- // If the next token is token.CHAN we still don't know if it
- // is a channel type or a receive operation - we only know
- // once we have found the end of the unary expression. There
- // are two cases:
- //
- // <- type => (<-type) must be channel type
- // <- expr => <-(expr) is a receive from an expression
- //
- // In the first case, the arrow must be re-associated with
- // the channel type parsed already:
- //
- // <- (chan type) => (<-chan type)
- // <- (chan<- type) => (<-chan (<-type))
-
- x := p.parseUnaryExpr()
-
- // determine which case we have
- if typ, ok := x.(*ast.ChanType); ok {
- // (<-type)
-
- // re-associate position info and <-
- dir := ast.SEND
- for ok && dir == ast.SEND {
- if typ.Dir == ast.RECV {
- // error: (<-type) is (<-(<-chan T))
- p.errorExpected(typ.Arrow, "'chan'")
- }
- arrow, typ.Begin, typ.Arrow = typ.Arrow, arrow, arrow
- dir, typ.Dir = typ.Dir, ast.RECV
- typ, ok = typ.Value.(*ast.ChanType)
- }
- if dir == ast.SEND {
- p.errorExpected(arrow, "channel type")
- }
-
- return x
- }
-
- // <-(expr)
- return &ast.UnaryExpr{OpPos: arrow, Op: token.ARROW, X: x}
-
- case token.MUL:
- // pointer type or unary "*" expression
- pos := p.pos
- p.next()
- x := p.parseUnaryExpr()
- return &ast.StarExpr{Star: pos, X: x}
- }
-
- return p.parsePrimaryExpr(nil)
-}
-
-func (p *parser) tokPrec() (token.Token, int) {
- tok := p.tok
- if p.inRhs && tok == token.ASSIGN {
- tok = token.EQL
- }
- return tok, tok.Precedence()
-}
-
-// parseBinaryExpr parses a (possibly) binary expression.
-// If x is non-nil, it is used as the left operand.
-//
-// TODO(rfindley): parseBinaryExpr has become overloaded. Consider refactoring.
-func (p *parser) parseBinaryExpr(x ast.Expr, prec1 int) ast.Expr {
- if p.trace {
- defer un(trace(p, "BinaryExpr"))
- }
-
- if x == nil {
- x = p.parseUnaryExpr()
- }
- // We track the nesting here rather than at the entry for the function,
- // since it can iteratively produce a nested output, and we want to
- // limit how deep a structure we generate.
- var n int
- defer func() { p.nestLev -= n }()
- for n = 1; ; n++ {
- incNestLev(p)
- op, oprec := p.tokPrec()
- if oprec < prec1 {
- return x
- }
- pos := p.expect(op)
- y := p.parseBinaryExpr(nil, oprec+1)
- x = &ast.BinaryExpr{X: x, OpPos: pos, Op: op, Y: y}
- }
-}
-
-// The result may be a type or even a raw type ([...]int).
-func (p *parser) parseExpr() ast.Expr {
- if p.trace {
- defer un(trace(p, "Expression"))
- }
-
- return p.parseBinaryExpr(nil, token.LowestPrec+1)
-}
-
-func (p *parser) parseRhs() ast.Expr {
- old := p.inRhs
- p.inRhs = true
- x := p.parseExpr()
- p.inRhs = old
- return x
-}
-
-// ----------------------------------------------------------------------------
-// Statements
-
-// Parsing modes for parseSimpleStmt.
-const (
- basic = iota
- labelOk
- rangeOk
-)
-
-// parseSimpleStmt returns true as 2nd result if it parsed the assignment
-// of a range clause (with mode == rangeOk). The returned statement is an
-// assignment with a right-hand side that is a single unary expression of
-// the form "range x". No guarantees are given for the left-hand side.
-func (p *parser) parseSimpleStmt(mode int) (ast.Stmt, bool) {
- if p.trace {
- defer un(trace(p, "SimpleStmt"))
- }
-
- x := p.parseList(false)
-
- switch p.tok {
- case
- token.DEFINE, token.ASSIGN, token.ADD_ASSIGN,
- token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
- token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN,
- token.XOR_ASSIGN, token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN:
- // assignment statement, possibly part of a range clause
- pos, tok := p.pos, p.tok
- p.next()
- var y []ast.Expr
- isRange := false
- if mode == rangeOk && p.tok == token.RANGE && (tok == token.DEFINE || tok == token.ASSIGN) {
- pos := p.pos
- p.next()
- y = []ast.Expr{&ast.UnaryExpr{OpPos: pos, Op: token.RANGE, X: p.parseRhs()}}
- isRange = true
- } else {
- y = p.parseList(true)
- }
- return &ast.AssignStmt{Lhs: x, TokPos: pos, Tok: tok, Rhs: y}, isRange
- }
-
- if len(x) > 1 {
- p.errorExpected(x[0].Pos(), "1 expression")
- // continue with first expression
- }
-
- switch p.tok {
- case token.COLON:
- // labeled statement
- colon := p.pos
- p.next()
- if label, isIdent := x[0].(*ast.Ident); mode == labelOk && isIdent {
- // Go spec: The scope of a label is the body of the function
- // in which it is declared and excludes the body of any nested
- // function.
- stmt := &ast.LabeledStmt{Label: label, Colon: colon, Stmt: p.parseStmt()}
- return stmt, false
- }
- // The label declaration typically starts at x[0].Pos(), but the label
- // declaration may be erroneous due to a token after that position (and
- // before the ':'). If SpuriousErrors is not set, the (only) error
- // reported for the line is the illegal label error instead of the token
- // before the ':' that caused the problem. Thus, use the (latest) colon
- // position for error reporting.
- p.error(colon, "illegal label declaration")
- return &ast.BadStmt{From: x[0].Pos(), To: colon + 1}, false
-
- case token.ARROW:
- // send statement
- arrow := p.pos
- p.next()
- y := p.parseRhs()
- return &ast.SendStmt{Chan: x[0], Arrow: arrow, Value: y}, false
-
- case token.INC, token.DEC:
- // increment or decrement
- s := &ast.IncDecStmt{X: x[0], TokPos: p.pos, Tok: p.tok}
- p.next()
- return s, false
- }
-
- // expression
- return &ast.ExprStmt{X: x[0]}, false
-}
-
-func (p *parser) parseCallExpr(callType string) *ast.CallExpr {
- x := p.parseRhs() // could be a conversion: (some type)(x)
- if t := unparen(x); t != x {
- p.error(x.Pos(), fmt.Sprintf("expression in %s must not be parenthesized", callType))
- x = t
- }
- if call, isCall := x.(*ast.CallExpr); isCall {
- return call
- }
- if _, isBad := x.(*ast.BadExpr); !isBad {
- // only report error if it's a new one
- p.error(p.safePos(x.End()), fmt.Sprintf("expression in %s must be function call", callType))
- }
- return nil
-}
-
-func (p *parser) parseGoStmt() ast.Stmt {
- if p.trace {
- defer un(trace(p, "GoStmt"))
- }
-
- pos := p.expect(token.GO)
- call := p.parseCallExpr("go")
- p.expectSemi()
- if call == nil {
- return &ast.BadStmt{From: pos, To: pos + 2} // len("go")
- }
-
- return &ast.GoStmt{Go: pos, Call: call}
-}
-
-func (p *parser) parseDeferStmt() ast.Stmt {
- if p.trace {
- defer un(trace(p, "DeferStmt"))
- }
-
- pos := p.expect(token.DEFER)
- call := p.parseCallExpr("defer")
- p.expectSemi()
- if call == nil {
- return &ast.BadStmt{From: pos, To: pos + 5} // len("defer")
- }
-
- return &ast.DeferStmt{Defer: pos, Call: call}
-}
-
-func (p *parser) parseReturnStmt() *ast.ReturnStmt {
- if p.trace {
- defer un(trace(p, "ReturnStmt"))
- }
-
- pos := p.pos
- p.expect(token.RETURN)
- var x []ast.Expr
- if p.tok != token.SEMICOLON && p.tok != token.RBRACE {
- x = p.parseList(true)
- }
- p.expectSemi()
-
- return &ast.ReturnStmt{Return: pos, Results: x}
-}
-
-func (p *parser) parseBranchStmt(tok token.Token) *ast.BranchStmt {
- if p.trace {
- defer un(trace(p, "BranchStmt"))
- }
-
- pos := p.expect(tok)
- var label *ast.Ident
- if tok != token.FALLTHROUGH && p.tok == token.IDENT {
- label = p.parseIdent()
- }
- p.expectSemi()
-
- return &ast.BranchStmt{TokPos: pos, Tok: tok, Label: label}
-}
-
-func (p *parser) makeExpr(s ast.Stmt, want string) ast.Expr {
- if s == nil {
- return nil
- }
- if es, isExpr := s.(*ast.ExprStmt); isExpr {
- return es.X
- }
- found := "simple statement"
- if _, isAss := s.(*ast.AssignStmt); isAss {
- found = "assignment"
- }
- p.error(s.Pos(), fmt.Sprintf("expected %s, found %s (missing parentheses around composite literal?)", want, found))
- return &ast.BadExpr{From: s.Pos(), To: p.safePos(s.End())}
-}
-
-// parseIfHeader is an adjusted version of parser.header
-// in cmd/compile/internal/syntax/parser.go, which has
-// been tuned for better error handling.
-func (p *parser) parseIfHeader() (init ast.Stmt, cond ast.Expr) {
- if p.tok == token.LBRACE {
- p.error(p.pos, "missing condition in if statement")
- cond = &ast.BadExpr{From: p.pos, To: p.pos}
- return
- }
- // p.tok != token.LBRACE
-
- prevLev := p.exprLev
- p.exprLev = -1
-
- if p.tok != token.SEMICOLON {
- // accept potential variable declaration but complain
- if p.tok == token.VAR {
- p.next()
- p.error(p.pos, "var declaration not allowed in if initializer")
- }
- init, _ = p.parseSimpleStmt(basic)
- }
-
- var condStmt ast.Stmt
- var semi struct {
- pos token.Pos
- lit string // ";" or "\n"; valid if pos.IsValid()
- }
- if p.tok != token.LBRACE {
- if p.tok == token.SEMICOLON {
- semi.pos = p.pos
- semi.lit = p.lit
- p.next()
- } else {
- p.expect(token.SEMICOLON)
- }
- if p.tok != token.LBRACE {
- condStmt, _ = p.parseSimpleStmt(basic)
- }
- } else {
- condStmt = init
- init = nil
- }
-
- if condStmt != nil {
- cond = p.makeExpr(condStmt, "boolean expression")
- } else if semi.pos.IsValid() {
- if semi.lit == "\n" {
- p.error(semi.pos, "unexpected newline, expecting { after if clause")
- } else {
- p.error(semi.pos, "missing condition in if statement")
- }
- }
-
- // make sure we have a valid AST
- if cond == nil {
- cond = &ast.BadExpr{From: p.pos, To: p.pos}
- }
-
- p.exprLev = prevLev
- return
-}
-
-func (p *parser) parseIfStmt() *ast.IfStmt {
- defer decNestLev(incNestLev(p))
-
- if p.trace {
- defer un(trace(p, "IfStmt"))
- }
-
- pos := p.expect(token.IF)
-
- init, cond := p.parseIfHeader()
- body := p.parseBlockStmt()
-
- var else_ ast.Stmt
- if p.tok == token.ELSE {
- p.next()
- switch p.tok {
- case token.IF:
- else_ = p.parseIfStmt()
- case token.LBRACE:
- else_ = p.parseBlockStmt()
- p.expectSemi()
- default:
- p.errorExpected(p.pos, "if statement or block")
- else_ = &ast.BadStmt{From: p.pos, To: p.pos}
- }
- } else {
- p.expectSemi()
- }
-
- return &ast.IfStmt{If: pos, Init: init, Cond: cond, Body: body, Else: else_}
-}
-
-func (p *parser) parseCaseClause() *ast.CaseClause {
- if p.trace {
- defer un(trace(p, "CaseClause"))
- }
-
- pos := p.pos
- var list []ast.Expr
- if p.tok == token.CASE {
- p.next()
- list = p.parseList(true)
- } else {
- p.expect(token.DEFAULT)
- }
-
- colon := p.expect(token.COLON)
- body := p.parseStmtList()
-
- return &ast.CaseClause{Case: pos, List: list, Colon: colon, Body: body}
-}
-
-func isTypeSwitchAssert(x ast.Expr) bool {
- a, ok := x.(*ast.TypeAssertExpr)
- return ok && a.Type == nil
-}
-
-func (p *parser) isTypeSwitchGuard(s ast.Stmt) bool {
- switch t := s.(type) {
- case *ast.ExprStmt:
- // x.(type)
- return isTypeSwitchAssert(t.X)
- case *ast.AssignStmt:
- // v := x.(type)
- if len(t.Lhs) == 1 && len(t.Rhs) == 1 && isTypeSwitchAssert(t.Rhs[0]) {
- switch t.Tok {
- case token.ASSIGN:
- // permit v = x.(type) but complain
- p.error(t.TokPos, "expected ':=', found '='")
- fallthrough
- case token.DEFINE:
- return true
- }
- }
- }
- return false
-}
-
-func (p *parser) parseSwitchStmt() ast.Stmt {
- if p.trace {
- defer un(trace(p, "SwitchStmt"))
- }
-
- pos := p.expect(token.SWITCH)
-
- var s1, s2 ast.Stmt
- if p.tok != token.LBRACE {
- prevLev := p.exprLev
- p.exprLev = -1
- if p.tok != token.SEMICOLON {
- s2, _ = p.parseSimpleStmt(basic)
- }
- if p.tok == token.SEMICOLON {
- p.next()
- s1 = s2
- s2 = nil
- if p.tok != token.LBRACE {
- // A TypeSwitchGuard may declare a variable in addition
- // to the variable declared in the initial SimpleStmt.
- // Introduce extra scope to avoid redeclaration errors:
- //
- // switch t := 0; t := x.(T) { ... }
- //
- // (this code is not valid Go because the first t
- // cannot be accessed and thus is never used, the extra
- // scope is needed for the correct error message).
- //
- // If we don't have a type switch, s2 must be an expression.
- // Having the extra nested but empty scope won't affect it.
- s2, _ = p.parseSimpleStmt(basic)
- }
- }
- p.exprLev = prevLev
- }
-
- typeSwitch := p.isTypeSwitchGuard(s2)
- lbrace := p.expect(token.LBRACE)
- var list []ast.Stmt
- for p.tok == token.CASE || p.tok == token.DEFAULT {
- list = append(list, p.parseCaseClause())
- }
- rbrace := p.expect(token.RBRACE)
- p.expectSemi()
- body := &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
-
- if typeSwitch {
- return &ast.TypeSwitchStmt{Switch: pos, Init: s1, Assign: s2, Body: body}
- }
-
- return &ast.SwitchStmt{Switch: pos, Init: s1, Tag: p.makeExpr(s2, "switch expression"), Body: body}
-}
-
-func (p *parser) parseCommClause() *ast.CommClause {
- if p.trace {
- defer un(trace(p, "CommClause"))
- }
-
- pos := p.pos
- var comm ast.Stmt
- if p.tok == token.CASE {
- p.next()
- lhs := p.parseList(false)
- if p.tok == token.ARROW {
- // SendStmt
- if len(lhs) > 1 {
- p.errorExpected(lhs[0].Pos(), "1 expression")
- // continue with first expression
- }
- arrow := p.pos
- p.next()
- rhs := p.parseRhs()
- comm = &ast.SendStmt{Chan: lhs[0], Arrow: arrow, Value: rhs}
- } else {
- // RecvStmt
- if tok := p.tok; tok == token.ASSIGN || tok == token.DEFINE {
- // RecvStmt with assignment
- if len(lhs) > 2 {
- p.errorExpected(lhs[0].Pos(), "1 or 2 expressions")
- // continue with first two expressions
- lhs = lhs[0:2]
- }
- pos := p.pos
- p.next()
- rhs := p.parseRhs()
- comm = &ast.AssignStmt{Lhs: lhs, TokPos: pos, Tok: tok, Rhs: []ast.Expr{rhs}}
- } else {
- // lhs must be single receive operation
- if len(lhs) > 1 {
- p.errorExpected(lhs[0].Pos(), "1 expression")
- // continue with first expression
- }
- comm = &ast.ExprStmt{X: lhs[0]}
- }
- }
- } else {
- p.expect(token.DEFAULT)
- }
-
- colon := p.expect(token.COLON)
- body := p.parseStmtList()
-
- return &ast.CommClause{Case: pos, Comm: comm, Colon: colon, Body: body}
-}
-
-func (p *parser) parseSelectStmt() *ast.SelectStmt {
- if p.trace {
- defer un(trace(p, "SelectStmt"))
- }
-
- pos := p.expect(token.SELECT)
- lbrace := p.expect(token.LBRACE)
- var list []ast.Stmt
- for p.tok == token.CASE || p.tok == token.DEFAULT {
- list = append(list, p.parseCommClause())
- }
- rbrace := p.expect(token.RBRACE)
- p.expectSemi()
- body := &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
-
- return &ast.SelectStmt{Select: pos, Body: body}
-}
-
-func (p *parser) parseForStmt() ast.Stmt {
- if p.trace {
- defer un(trace(p, "ForStmt"))
- }
-
- pos := p.expect(token.FOR)
-
- var s1, s2, s3 ast.Stmt
- var isRange bool
- if p.tok != token.LBRACE {
- prevLev := p.exprLev
- p.exprLev = -1
- if p.tok != token.SEMICOLON {
- if p.tok == token.RANGE {
- // "for range x" (nil lhs in assignment)
- pos := p.pos
- p.next()
- y := []ast.Expr{&ast.UnaryExpr{OpPos: pos, Op: token.RANGE, X: p.parseRhs()}}
- s2 = &ast.AssignStmt{Rhs: y}
- isRange = true
- } else {
- s2, isRange = p.parseSimpleStmt(rangeOk)
- }
- }
- if !isRange && p.tok == token.SEMICOLON {
- p.next()
- s1 = s2
- s2 = nil
- if p.tok != token.SEMICOLON {
- s2, _ = p.parseSimpleStmt(basic)
- }
- p.expectSemi()
- if p.tok != token.LBRACE {
- s3, _ = p.parseSimpleStmt(basic)
- }
- }
- p.exprLev = prevLev
- }
-
- body := p.parseBlockStmt()
- p.expectSemi()
-
- if isRange {
- as := s2.(*ast.AssignStmt)
- // check lhs
- var key, value ast.Expr
- switch len(as.Lhs) {
- case 0:
- // nothing to do
- case 1:
- key = as.Lhs[0]
- case 2:
- key, value = as.Lhs[0], as.Lhs[1]
- default:
- p.errorExpected(as.Lhs[len(as.Lhs)-1].Pos(), "at most 2 expressions")
- return &ast.BadStmt{From: pos, To: p.safePos(body.End())}
- }
- // parseSimpleStmt returned a right-hand side that
- // is a single unary expression of the form "range x"
- x := as.Rhs[0].(*ast.UnaryExpr).X
- return &ast.RangeStmt{
- For: pos,
- Key: key,
- Value: value,
- TokPos: as.TokPos,
- Tok: as.Tok,
- Range: as.Rhs[0].Pos(),
- X: x,
- Body: body,
- }
- }
-
- // regular for statement
- return &ast.ForStmt{
- For: pos,
- Init: s1,
- Cond: p.makeExpr(s2, "boolean or range expression"),
- Post: s3,
- Body: body,
- }
-}
-
-func (p *parser) parseStmt() (s ast.Stmt) {
- defer decNestLev(incNestLev(p))
-
- if p.trace {
- defer un(trace(p, "Statement"))
- }
-
- switch p.tok {
- case token.CONST, token.TYPE, token.VAR:
- s = &ast.DeclStmt{Decl: p.parseDecl(stmtStart)}
- case
- // tokens that may start an expression
- token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING, token.FUNC, token.LPAREN, // operands
- token.LBRACK, token.STRUCT, token.MAP, token.CHAN, token.INTERFACE, // composite types
- token.ADD, token.SUB, token.MUL, token.AND, token.XOR, token.ARROW, token.NOT: // unary operators
- s, _ = p.parseSimpleStmt(labelOk)
- // because of the required look-ahead, labeled statements are
- // parsed by parseSimpleStmt - don't expect a semicolon after
- // them
- if _, isLabeledStmt := s.(*ast.LabeledStmt); !isLabeledStmt {
- p.expectSemi()
- }
- case token.GO:
- s = p.parseGoStmt()
- case token.DEFER:
- s = p.parseDeferStmt()
- case token.RETURN:
- s = p.parseReturnStmt()
- case token.BREAK, token.CONTINUE, token.GOTO, token.FALLTHROUGH:
- s = p.parseBranchStmt(p.tok)
- case token.LBRACE:
- s = p.parseBlockStmt()
- p.expectSemi()
- case token.IF:
- s = p.parseIfStmt()
- case token.SWITCH:
- s = p.parseSwitchStmt()
- case token.SELECT:
- s = p.parseSelectStmt()
- case token.FOR:
- s = p.parseForStmt()
- case token.SEMICOLON:
- // Is it ever possible to have an implicit semicolon
- // producing an empty statement in a valid program?
- // (handle correctly anyway)
- s = &ast.EmptyStmt{Semicolon: p.pos, Implicit: p.lit == "\n"}
- p.next()
- case token.RBRACE:
- // a semicolon may be omitted before a closing "}"
- s = &ast.EmptyStmt{Semicolon: p.pos, Implicit: true}
- default:
- // no statement found
- pos := p.pos
- p.errorExpected(pos, "statement")
- p.advance(stmtStart)
- s = &ast.BadStmt{From: pos, To: p.pos}
- }
-
- return
-}
-
-// ----------------------------------------------------------------------------
-// Declarations
-
-type parseSpecFunction func(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec
-
-func (p *parser) parseImportSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.Spec {
- if p.trace {
- defer un(trace(p, "ImportSpec"))
- }
-
- var ident *ast.Ident
- switch p.tok {
- case token.IDENT:
- ident = p.parseIdent()
- case token.PERIOD:
- ident = &ast.Ident{NamePos: p.pos, Name: "."}
- p.next()
- }
-
- pos := p.pos
- var path string
- if p.tok == token.STRING {
- path = p.lit
- p.next()
- } else if p.tok.IsLiteral() {
- p.error(pos, "import path must be a string")
- p.next()
- } else {
- p.error(pos, "missing import path")
- p.advance(exprEnd)
- }
- comment := p.expectSemi()
-
- // collect imports
- spec := &ast.ImportSpec{
- Doc: doc,
- Name: ident,
- Path: &ast.BasicLit{ValuePos: pos, Kind: token.STRING, Value: path},
- Comment: comment,
- }
- p.imports = append(p.imports, spec)
-
- return spec
-}
-
-func (p *parser) parseValueSpec(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec {
- if p.trace {
- defer un(trace(p, keyword.String()+"Spec"))
- }
-
- idents := p.parseIdentList()
- var typ ast.Expr
- var values []ast.Expr
- switch keyword {
- case token.CONST:
- // always permit optional type and initialization for more tolerant parsing
- if p.tok != token.EOF && p.tok != token.SEMICOLON && p.tok != token.RPAREN {
- typ = p.tryIdentOrType()
- if p.tok == token.ASSIGN {
- p.next()
- values = p.parseList(true)
- }
- }
- case token.VAR:
- if p.tok != token.ASSIGN {
- typ = p.parseType()
- }
- if p.tok == token.ASSIGN {
- p.next()
- values = p.parseList(true)
- }
- default:
- panic("unreachable")
- }
- comment := p.expectSemi()
-
- spec := &ast.ValueSpec{
- Doc: doc,
- Names: idents,
- Type: typ,
- Values: values,
- Comment: comment,
- }
- return spec
-}
-
-func (p *parser) parseGenericType(spec *ast.TypeSpec, openPos token.Pos, name0 *ast.Ident, typ0 ast.Expr) {
- if p.trace {
- defer un(trace(p, "parseGenericType"))
- }
-
- list := p.parseParameterList(name0, typ0, token.RBRACK)
- closePos := p.expect(token.RBRACK)
- spec.TypeParams = &ast.FieldList{Opening: openPos, List: list, Closing: closePos}
- // Let the type checker decide whether to accept type parameters on aliases:
- // see issue #46477.
- if p.tok == token.ASSIGN {
- // type alias
- spec.Assign = p.pos
- p.next()
- }
- spec.Type = p.parseType()
-}
-
-func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.Spec {
- if p.trace {
- defer un(trace(p, "TypeSpec"))
- }
-
- name := p.parseIdent()
- spec := &ast.TypeSpec{Doc: doc, Name: name}
-
- if p.tok == token.LBRACK {
- // spec.Name "[" ...
- // array/slice type or type parameter list
- lbrack := p.pos
- p.next()
- if p.tok == token.IDENT {
- // We may have an array type or a type parameter list.
- // In either case we expect an expression x (which may
- // just be a name, or a more complex expression) which
- // we can analyze further.
- //
- // A type parameter list may have a type bound starting
- // with a "[" as in: P []E. In that case, simply parsing
- // an expression would lead to an error: P[] is invalid.
- // But since index or slice expressions are never constant
- // and thus invalid array length expressions, if the name
- // is followed by "[" it must be the start of an array or
- // slice constraint. Only if we don't see a "[" do we
- // need to parse a full expression. Notably, name <- x
- // is not a concern because name <- x is a statement and
- // not an expression.
- var x ast.Expr = p.parseIdent()
- if p.tok != token.LBRACK {
- // To parse the expression starting with name, expand
- // the call sequence we would get by passing in name
- // to parser.expr, and pass in name to parsePrimaryExpr.
- p.exprLev++
- lhs := p.parsePrimaryExpr(x)
- x = p.parseBinaryExpr(lhs, token.LowestPrec+1)
- p.exprLev--
- }
- // Analyze expression x. If we can split x into a type parameter
- // name, possibly followed by a type parameter type, we consider
- // this the start of a type parameter list, with some caveats:
- // a single name followed by "]" tilts the decision towards an
- // array declaration; a type parameter type that could also be
- // an ordinary expression but which is followed by a comma tilts
- // the decision towards a type parameter list.
- if pname, ptype := extractName(x, p.tok == token.COMMA); pname != nil && (ptype != nil || p.tok != token.RBRACK) {
- // spec.Name "[" pname ...
- // spec.Name "[" pname ptype ...
- // spec.Name "[" pname ptype "," ...
- p.parseGenericType(spec, lbrack, pname, ptype) // ptype may be nil
- } else {
- // spec.Name "[" pname "]" ...
- // spec.Name "[" x ...
- spec.Type = p.parseArrayType(lbrack, x)
- }
- } else {
- // array type
- spec.Type = p.parseArrayType(lbrack, nil)
- }
- } else {
- // no type parameters
- if p.tok == token.ASSIGN {
- // type alias
- spec.Assign = p.pos
- p.next()
- }
- spec.Type = p.parseType()
- }
-
- spec.Comment = p.expectSemi()
-
- return spec
-}
-
-// extractName splits the expression x into (name, expr) if syntactically
-// x can be written as name expr. The split only happens if expr is a type
-// element (per the isTypeElem predicate) or if force is set.
-// If x is just a name, the result is (name, nil). If the split succeeds,
-// the result is (name, expr). Otherwise the result is (nil, x).
-// Examples:
-//
-// x force name expr
-// ------------------------------------
-// P*[]int T/F P *[]int
-// P*E T P *E
-// P*E F nil P*E
-// P([]int) T/F P []int
-// P(E) T P E
-// P(E) F nil P(E)
-// P*E|F|~G T/F P *E|F|~G
-// P*E|F|G T P *E|F|G
-// P*E|F|G F nil P*E|F|G
-func extractName(x ast.Expr, force bool) (*ast.Ident, ast.Expr) {
- switch x := x.(type) {
- case *ast.Ident:
- return x, nil
- case *ast.BinaryExpr:
- switch x.Op {
- case token.MUL:
- if name, _ := x.X.(*ast.Ident); name != nil && (force || isTypeElem(x.Y)) {
- // x = name *x.Y
- return name, &ast.StarExpr{Star: x.OpPos, X: x.Y}
- }
- case token.OR:
- if name, lhs := extractName(x.X, force || isTypeElem(x.Y)); name != nil && lhs != nil {
- // x = name lhs|x.Y
- op := *x
- op.X = lhs
- return name, &op
- }
- }
- case *ast.CallExpr:
- if name, _ := x.Fun.(*ast.Ident); name != nil {
- if len(x.Args) == 1 && x.Ellipsis == token.NoPos && (force || isTypeElem(x.Args[0])) {
- // x = name "(" x.ArgList[0] ")"
- return name, x.Args[0]
- }
- }
- }
- return nil, x
-}
-
-// isTypeElem reports whether x is a (possibly parenthesized) type element expression.
-// The result is false if x could be a type element OR an ordinary (value) expression.
-func isTypeElem(x ast.Expr) bool {
- switch x := x.(type) {
- case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
- return true
- case *ast.BinaryExpr:
- return isTypeElem(x.X) || isTypeElem(x.Y)
- case *ast.UnaryExpr:
- return x.Op == token.TILDE
- case *ast.ParenExpr:
- return isTypeElem(x.X)
- }
- return false
-}
-
-func (p *parser) parseGenDecl(keyword token.Token, f parseSpecFunction) *ast.GenDecl {
- if p.trace {
- defer un(trace(p, "GenDecl("+keyword.String()+")"))
- }
-
- doc := p.leadComment
- pos := p.expect(keyword)
- var lparen, rparen token.Pos
- var list []ast.Spec
- if p.tok == token.LPAREN {
- lparen = p.pos
- p.next()
- for iota := 0; p.tok != token.RPAREN && p.tok != token.EOF; iota++ {
- list = append(list, f(p.leadComment, keyword, iota))
- }
- rparen = p.expect(token.RPAREN)
- p.expectSemi()
- } else {
- list = append(list, f(nil, keyword, 0))
- }
-
- return &ast.GenDecl{
- Doc: doc,
- TokPos: pos,
- Tok: keyword,
- Lparen: lparen,
- Specs: list,
- Rparen: rparen,
- }
-}
-
-func (p *parser) parseFuncDecl() *ast.FuncDecl {
- if p.trace {
- defer un(trace(p, "FunctionDecl"))
- }
-
- doc := p.leadComment
- pos := p.expect(token.FUNC)
-
- var recv *ast.FieldList
- if p.tok == token.LPAREN {
- _, recv = p.parseParameters(false)
- }
-
- ident := p.parseIdent()
-
- tparams, params := p.parseParameters(true)
- if recv != nil && tparams != nil {
- // Method declarations do not have type parameters. We parse them for a
- // better error message and improved error recovery.
- p.error(tparams.Opening, "method must have no type parameters")
- tparams = nil
- }
- results := p.parseResult()
-
- var body *ast.BlockStmt
- switch p.tok {
- case token.LBRACE:
- body = p.parseBody()
- p.expectSemi()
- case token.SEMICOLON:
- p.next()
- if p.tok == token.LBRACE {
- // opening { of function declaration on next line
- p.error(p.pos, "unexpected semicolon or newline before {")
- body = p.parseBody()
- p.expectSemi()
- }
- default:
- p.expectSemi()
- }
-
- decl := &ast.FuncDecl{
- Doc: doc,
- Recv: recv,
- Name: ident,
- Type: &ast.FuncType{
- Func: pos,
- TypeParams: tparams,
- Params: params,
- Results: results,
- },
- Body: body,
- }
- return decl
-}
-
-func (p *parser) parseDecl(sync map[token.Token]bool) ast.Decl {
- if p.trace {
- defer un(trace(p, "Declaration"))
- }
-
- var f parseSpecFunction
- switch p.tok {
- case token.IMPORT:
- f = p.parseImportSpec
-
- case token.CONST, token.VAR:
- f = p.parseValueSpec
-
- case token.TYPE:
- f = p.parseTypeSpec
-
- case token.FUNC:
- return p.parseFuncDecl()
-
- default:
- pos := p.pos
- p.errorExpected(pos, "declaration")
- p.advance(sync)
- return &ast.BadDecl{From: pos, To: p.pos}
- }
-
- return p.parseGenDecl(p.tok, f)
-}
-
-// ----------------------------------------------------------------------------
-// Source files
-
-func (p *parser) parseFile() *ast.File {
- if p.trace {
- defer un(trace(p, "File"))
- }
-
- // Don't bother parsing the rest if we had errors scanning the first token.
- // Likely not a Go source file at all.
- if p.errors.Len() != 0 {
- return nil
- }
-
- // package clause
- doc := p.leadComment
- pos := p.expect(token.PACKAGE)
- // Go spec: The package clause is not a declaration;
- // the package name does not appear in any scope.
- ident := p.parseIdent()
- if ident.Name == "_" && p.mode&DeclarationErrors != 0 {
- p.error(p.pos, "invalid package name _")
- }
- p.expectSemi()
-
- // Don't bother parsing the rest if we had errors parsing the package clause.
- // Likely not a Go source file at all.
- if p.errors.Len() != 0 {
- return nil
- }
-
- var decls []ast.Decl
- if p.mode&PackageClauseOnly == 0 {
- // import decls
- for p.tok == token.IMPORT {
- decls = append(decls, p.parseGenDecl(token.IMPORT, p.parseImportSpec))
- }
-
- if p.mode&ImportsOnly == 0 {
- // rest of package body
- prev := token.IMPORT
- for p.tok != token.EOF {
- // Continue to accept import declarations for error tolerance, but complain.
- if p.tok == token.IMPORT && prev != token.IMPORT {
- p.error(p.pos, "imports must appear before other declarations")
- }
- prev = p.tok
-
- decls = append(decls, p.parseDecl(declStart))
- }
- }
- }
-
- f := &ast.File{
- Doc: doc,
- Package: pos,
- Name: ident,
- Decls: decls,
- FileStart: token.Pos(p.file.Base()),
- FileEnd: token.Pos(p.file.Base() + p.file.Size()),
- Imports: p.imports,
- Comments: p.comments,
- }
- var declErr func(token.Pos, string)
- if p.mode&DeclarationErrors != 0 {
- declErr = p.error
- }
- if p.mode&SkipObjectResolution == 0 {
- resolveFile(f, p.file, declErr)
- }
-
- return f
-}
diff --git a/contrib/go/_std_1.20/src/go/parser/ya.make b/contrib/go/_std_1.20/src/go/parser/ya.make
deleted file mode 100644
index 797b3ebab6..0000000000
--- a/contrib/go/_std_1.20/src/go/parser/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- interface.go
- parser.go
- resolver.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/printer/printer.go b/contrib/go/_std_1.20/src/go/printer/printer.go
deleted file mode 100644
index 46131c6697..0000000000
--- a/contrib/go/_std_1.20/src/go/printer/printer.go
+++ /dev/null
@@ -1,1436 +0,0 @@
-// Copyright 2009 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 printer implements printing of AST nodes.
-package printer
-
-import (
- "fmt"
- "go/ast"
- "go/build/constraint"
- "go/token"
- "io"
- "os"
- "strings"
- "sync"
- "text/tabwriter"
- "unicode"
-)
-
-const (
- maxNewlines = 2 // max. number of newlines between source text
- debug = false // enable for debugging
- infinity = 1 << 30
-)
-
-type whiteSpace byte
-
-const (
- ignore = whiteSpace(0)
- blank = whiteSpace(' ')
- vtab = whiteSpace('\v')
- newline = whiteSpace('\n')
- formfeed = whiteSpace('\f')
- indent = whiteSpace('>')
- unindent = whiteSpace('<')
-)
-
-// A pmode value represents the current printer mode.
-type pmode int
-
-const (
- noExtraBlank pmode = 1 << iota // disables extra blank after /*-style comment
- noExtraLinebreak // disables extra line break after /*-style comment
-)
-
-type commentInfo struct {
- cindex int // current comment index
- comment *ast.CommentGroup // = printer.comments[cindex]; or nil
- commentOffset int // = printer.posFor(printer.comments[cindex].List[0].Pos()).Offset; or infinity
- commentNewline bool // true if the comment group contains newlines
-}
-
-type printer struct {
- // Configuration (does not change after initialization)
- Config
- fset *token.FileSet
-
- // Current state
- output []byte // raw printer result
- indent int // current indentation
- level int // level == 0: outside composite literal; level > 0: inside composite literal
- mode pmode // current printer mode
- endAlignment bool // if set, terminate alignment immediately
- impliedSemi bool // if set, a linebreak implies a semicolon
- lastTok token.Token // last token printed (token.ILLEGAL if it's whitespace)
- prevOpen token.Token // previous non-brace "open" token (, [, or token.ILLEGAL
- wsbuf []whiteSpace // delayed white space
- goBuild []int // start index of all //go:build comments in output
- plusBuild []int // start index of all // +build comments in output
-
- // Positions
- // The out position differs from the pos position when the result
- // formatting differs from the source formatting (in the amount of
- // white space). If there's a difference and SourcePos is set in
- // ConfigMode, //line directives are used in the output to restore
- // original source positions for a reader.
- pos token.Position // current position in AST (source) space
- out token.Position // current position in output space
- last token.Position // value of pos after calling writeString
- linePtr *int // if set, record out.Line for the next token in *linePtr
- sourcePosErr error // if non-nil, the first error emitting a //line directive
-
- // The list of all source comments, in order of appearance.
- comments []*ast.CommentGroup // may be nil
- useNodeComments bool // if not set, ignore lead and line comments of nodes
-
- // Information about p.comments[p.cindex]; set up by nextComment.
- commentInfo
-
- // Cache of already computed node sizes.
- nodeSizes map[ast.Node]int
-
- // Cache of most recently computed line position.
- cachedPos token.Pos
- cachedLine int // line corresponding to cachedPos
-}
-
-func (p *printer) internalError(msg ...any) {
- if debug {
- fmt.Print(p.pos.String() + ": ")
- fmt.Println(msg...)
- panic("go/printer")
- }
-}
-
-// commentsHaveNewline reports whether a list of comments belonging to
-// an *ast.CommentGroup contains newlines. Because the position information
-// may only be partially correct, we also have to read the comment text.
-func (p *printer) commentsHaveNewline(list []*ast.Comment) bool {
- // len(list) > 0
- line := p.lineFor(list[0].Pos())
- for i, c := range list {
- if i > 0 && p.lineFor(list[i].Pos()) != line {
- // not all comments on the same line
- return true
- }
- if t := c.Text; len(t) >= 2 && (t[1] == '/' || strings.Contains(t, "\n")) {
- return true
- }
- }
- _ = line
- return false
-}
-
-func (p *printer) nextComment() {
- for p.cindex < len(p.comments) {
- c := p.comments[p.cindex]
- p.cindex++
- if list := c.List; len(list) > 0 {
- p.comment = c
- p.commentOffset = p.posFor(list[0].Pos()).Offset
- p.commentNewline = p.commentsHaveNewline(list)
- return
- }
- // we should not reach here (correct ASTs don't have empty
- // ast.CommentGroup nodes), but be conservative and try again
- }
- // no more comments
- p.commentOffset = infinity
-}
-
-// commentBefore reports whether the current comment group occurs
-// before the next position in the source code and printing it does
-// not introduce implicit semicolons.
-func (p *printer) commentBefore(next token.Position) bool {
- return p.commentOffset < next.Offset && (!p.impliedSemi || !p.commentNewline)
-}
-
-// commentSizeBefore returns the estimated size of the
-// comments on the same line before the next position.
-func (p *printer) commentSizeBefore(next token.Position) int {
- // save/restore current p.commentInfo (p.nextComment() modifies it)
- defer func(info commentInfo) {
- p.commentInfo = info
- }(p.commentInfo)
-
- size := 0
- for p.commentBefore(next) {
- for _, c := range p.comment.List {
- size += len(c.Text)
- }
- p.nextComment()
- }
- return size
-}
-
-// recordLine records the output line number for the next non-whitespace
-// token in *linePtr. It is used to compute an accurate line number for a
-// formatted construct, independent of pending (not yet emitted) whitespace
-// or comments.
-func (p *printer) recordLine(linePtr *int) {
- p.linePtr = linePtr
-}
-
-// linesFrom returns the number of output lines between the current
-// output line and the line argument, ignoring any pending (not yet
-// emitted) whitespace or comments. It is used to compute an accurate
-// size (in number of lines) for a formatted construct.
-func (p *printer) linesFrom(line int) int {
- return p.out.Line - line
-}
-
-func (p *printer) posFor(pos token.Pos) token.Position {
- // not used frequently enough to cache entire token.Position
- return p.fset.PositionFor(pos, false /* absolute position */)
-}
-
-func (p *printer) lineFor(pos token.Pos) int {
- if pos != p.cachedPos {
- p.cachedPos = pos
- p.cachedLine = p.fset.PositionFor(pos, false /* absolute position */).Line
- }
- return p.cachedLine
-}
-
-// writeLineDirective writes a //line directive if necessary.
-func (p *printer) writeLineDirective(pos token.Position) {
- if pos.IsValid() && (p.out.Line != pos.Line || p.out.Filename != pos.Filename) {
- if strings.ContainsAny(pos.Filename, "\r\n") {
- if p.sourcePosErr == nil {
- p.sourcePosErr = fmt.Errorf("go/printer: source filename contains unexpected newline character: %q", pos.Filename)
- }
- return
- }
-
- p.output = append(p.output, tabwriter.Escape) // protect '\n' in //line from tabwriter interpretation
- p.output = append(p.output, fmt.Sprintf("//line %s:%d\n", pos.Filename, pos.Line)...)
- p.output = append(p.output, tabwriter.Escape)
- // p.out must match the //line directive
- p.out.Filename = pos.Filename
- p.out.Line = pos.Line
- }
-}
-
-// writeIndent writes indentation.
-func (p *printer) writeIndent() {
- // use "hard" htabs - indentation columns
- // must not be discarded by the tabwriter
- n := p.Config.Indent + p.indent // include base indentation
- for i := 0; i < n; i++ {
- p.output = append(p.output, '\t')
- }
-
- // update positions
- p.pos.Offset += n
- p.pos.Column += n
- p.out.Column += n
-}
-
-// writeByte writes ch n times to p.output and updates p.pos.
-// Only used to write formatting (white space) characters.
-func (p *printer) writeByte(ch byte, n int) {
- if p.endAlignment {
- // Ignore any alignment control character;
- // and at the end of the line, break with
- // a formfeed to indicate termination of
- // existing columns.
- switch ch {
- case '\t', '\v':
- ch = ' '
- case '\n', '\f':
- ch = '\f'
- p.endAlignment = false
- }
- }
-
- if p.out.Column == 1 {
- // no need to write line directives before white space
- p.writeIndent()
- }
-
- for i := 0; i < n; i++ {
- p.output = append(p.output, ch)
- }
-
- // update positions
- p.pos.Offset += n
- if ch == '\n' || ch == '\f' {
- p.pos.Line += n
- p.out.Line += n
- p.pos.Column = 1
- p.out.Column = 1
- return
- }
- p.pos.Column += n
- p.out.Column += n
-}
-
-// writeString writes the string s to p.output and updates p.pos, p.out,
-// and p.last. If isLit is set, s is escaped w/ tabwriter.Escape characters
-// to protect s from being interpreted by the tabwriter.
-//
-// Note: writeString is only used to write Go tokens, literals, and
-// comments, all of which must be written literally. Thus, it is correct
-// to always set isLit = true. However, setting it explicitly only when
-// needed (i.e., when we don't know that s contains no tabs or line breaks)
-// avoids processing extra escape characters and reduces run time of the
-// printer benchmark by up to 10%.
-func (p *printer) writeString(pos token.Position, s string, isLit bool) {
- if p.out.Column == 1 {
- if p.Config.Mode&SourcePos != 0 {
- p.writeLineDirective(pos)
- }
- p.writeIndent()
- }
-
- if pos.IsValid() {
- // update p.pos (if pos is invalid, continue with existing p.pos)
- // Note: Must do this after handling line beginnings because
- // writeIndent updates p.pos if there's indentation, but p.pos
- // is the position of s.
- p.pos = pos
- }
-
- if isLit {
- // Protect s such that is passes through the tabwriter
- // unchanged. Note that valid Go programs cannot contain
- // tabwriter.Escape bytes since they do not appear in legal
- // UTF-8 sequences.
- p.output = append(p.output, tabwriter.Escape)
- }
-
- if debug {
- p.output = append(p.output, fmt.Sprintf("/*%s*/", pos)...) // do not update p.pos!
- }
- p.output = append(p.output, s...)
-
- // update positions
- nlines := 0
- var li int // index of last newline; valid if nlines > 0
- for i := 0; i < len(s); i++ {
- // Raw string literals may contain any character except back quote (`).
- if ch := s[i]; ch == '\n' || ch == '\f' {
- // account for line break
- nlines++
- li = i
- // A line break inside a literal will break whatever column
- // formatting is in place; ignore any further alignment through
- // the end of the line.
- p.endAlignment = true
- }
- }
- p.pos.Offset += len(s)
- if nlines > 0 {
- p.pos.Line += nlines
- p.out.Line += nlines
- c := len(s) - li
- p.pos.Column = c
- p.out.Column = c
- } else {
- p.pos.Column += len(s)
- p.out.Column += len(s)
- }
-
- if isLit {
- p.output = append(p.output, tabwriter.Escape)
- }
-
- p.last = p.pos
-}
-
-// writeCommentPrefix writes the whitespace before a comment.
-// If there is any pending whitespace, it consumes as much of
-// it as is likely to help position the comment nicely.
-// pos is the comment position, next the position of the item
-// after all pending comments, prev is the previous comment in
-// a group of comments (or nil), and tok is the next token.
-func (p *printer) writeCommentPrefix(pos, next token.Position, prev *ast.Comment, tok token.Token) {
- if len(p.output) == 0 {
- // the comment is the first item to be printed - don't write any whitespace
- return
- }
-
- if pos.IsValid() && pos.Filename != p.last.Filename {
- // comment in a different file - separate with newlines
- p.writeByte('\f', maxNewlines)
- return
- }
-
- if pos.Line == p.last.Line && (prev == nil || prev.Text[1] != '/') {
- // comment on the same line as last item:
- // separate with at least one separator
- hasSep := false
- if prev == nil {
- // first comment of a comment group
- j := 0
- for i, ch := range p.wsbuf {
- switch ch {
- case blank:
- // ignore any blanks before a comment
- p.wsbuf[i] = ignore
- continue
- case vtab:
- // respect existing tabs - important
- // for proper formatting of commented structs
- hasSep = true
- continue
- case indent:
- // apply pending indentation
- continue
- }
- j = i
- break
- }
- p.writeWhitespace(j)
- }
- // make sure there is at least one separator
- if !hasSep {
- sep := byte('\t')
- if pos.Line == next.Line {
- // next item is on the same line as the comment
- // (which must be a /*-style comment): separate
- // with a blank instead of a tab
- sep = ' '
- }
- p.writeByte(sep, 1)
- }
-
- } else {
- // comment on a different line:
- // separate with at least one line break
- droppedLinebreak := false
- j := 0
- for i, ch := range p.wsbuf {
- switch ch {
- case blank, vtab:
- // ignore any horizontal whitespace before line breaks
- p.wsbuf[i] = ignore
- continue
- case indent:
- // apply pending indentation
- continue
- case unindent:
- // if this is not the last unindent, apply it
- // as it is (likely) belonging to the last
- // construct (e.g., a multi-line expression list)
- // and is not part of closing a block
- if i+1 < len(p.wsbuf) && p.wsbuf[i+1] == unindent {
- continue
- }
- // if the next token is not a closing }, apply the unindent
- // if it appears that the comment is aligned with the
- // token; otherwise assume the unindent is part of a
- // closing block and stop (this scenario appears with
- // comments before a case label where the comments
- // apply to the next case instead of the current one)
- if tok != token.RBRACE && pos.Column == next.Column {
- continue
- }
- case newline, formfeed:
- p.wsbuf[i] = ignore
- droppedLinebreak = prev == nil // record only if first comment of a group
- }
- j = i
- break
- }
- p.writeWhitespace(j)
-
- // determine number of linebreaks before the comment
- n := 0
- if pos.IsValid() && p.last.IsValid() {
- n = pos.Line - p.last.Line
- if n < 0 { // should never happen
- n = 0
- }
- }
-
- // at the package scope level only (p.indent == 0),
- // add an extra newline if we dropped one before:
- // this preserves a blank line before documentation
- // comments at the package scope level (issue 2570)
- if p.indent == 0 && droppedLinebreak {
- n++
- }
-
- // make sure there is at least one line break
- // if the previous comment was a line comment
- if n == 0 && prev != nil && prev.Text[1] == '/' {
- n = 1
- }
-
- if n > 0 {
- // use formfeeds to break columns before a comment;
- // this is analogous to using formfeeds to separate
- // individual lines of /*-style comments
- p.writeByte('\f', nlimit(n))
- }
- }
-}
-
-// Returns true if s contains only white space
-// (only tabs and blanks can appear in the printer's context).
-func isBlank(s string) bool {
- for i := 0; i < len(s); i++ {
- if s[i] > ' ' {
- return false
- }
- }
- return true
-}
-
-// commonPrefix returns the common prefix of a and b.
-func commonPrefix(a, b string) string {
- i := 0
- for i < len(a) && i < len(b) && a[i] == b[i] && (a[i] <= ' ' || a[i] == '*') {
- i++
- }
- return a[0:i]
-}
-
-// trimRight returns s with trailing whitespace removed.
-func trimRight(s string) string {
- return strings.TrimRightFunc(s, unicode.IsSpace)
-}
-
-// stripCommonPrefix removes a common prefix from /*-style comment lines (unless no
-// comment line is indented, all but the first line have some form of space prefix).
-// The prefix is computed using heuristics such that is likely that the comment
-// contents are nicely laid out after re-printing each line using the printer's
-// current indentation.
-func stripCommonPrefix(lines []string) {
- if len(lines) <= 1 {
- return // at most one line - nothing to do
- }
- // len(lines) > 1
-
- // The heuristic in this function tries to handle a few
- // common patterns of /*-style comments: Comments where
- // the opening /* and closing */ are aligned and the
- // rest of the comment text is aligned and indented with
- // blanks or tabs, cases with a vertical "line of stars"
- // on the left, and cases where the closing */ is on the
- // same line as the last comment text.
-
- // Compute maximum common white prefix of all but the first,
- // last, and blank lines, and replace blank lines with empty
- // lines (the first line starts with /* and has no prefix).
- // In cases where only the first and last lines are not blank,
- // such as two-line comments, or comments where all inner lines
- // are blank, consider the last line for the prefix computation
- // since otherwise the prefix would be empty.
- //
- // Note that the first and last line are never empty (they
- // contain the opening /* and closing */ respectively) and
- // thus they can be ignored by the blank line check.
- prefix := ""
- prefixSet := false
- if len(lines) > 2 {
- for i, line := range lines[1 : len(lines)-1] {
- if isBlank(line) {
- lines[1+i] = "" // range starts with lines[1]
- } else {
- if !prefixSet {
- prefix = line
- prefixSet = true
- }
- prefix = commonPrefix(prefix, line)
- }
-
- }
- }
- // If we don't have a prefix yet, consider the last line.
- if !prefixSet {
- line := lines[len(lines)-1]
- prefix = commonPrefix(line, line)
- }
-
- /*
- * Check for vertical "line of stars" and correct prefix accordingly.
- */
- lineOfStars := false
- if p, _, ok := strings.Cut(prefix, "*"); ok {
- // remove trailing blank from prefix so stars remain aligned
- prefix = strings.TrimSuffix(p, " ")
- lineOfStars = true
- } else {
- // No line of stars present.
- // Determine the white space on the first line after the /*
- // and before the beginning of the comment text, assume two
- // blanks instead of the /* unless the first character after
- // the /* is a tab. If the first comment line is empty but
- // for the opening /*, assume up to 3 blanks or a tab. This
- // whitespace may be found as suffix in the common prefix.
- first := lines[0]
- if isBlank(first[2:]) {
- // no comment text on the first line:
- // reduce prefix by up to 3 blanks or a tab
- // if present - this keeps comment text indented
- // relative to the /* and */'s if it was indented
- // in the first place
- i := len(prefix)
- for n := 0; n < 3 && i > 0 && prefix[i-1] == ' '; n++ {
- i--
- }
- if i == len(prefix) && i > 0 && prefix[i-1] == '\t' {
- i--
- }
- prefix = prefix[0:i]
- } else {
- // comment text on the first line
- suffix := make([]byte, len(first))
- n := 2 // start after opening /*
- for n < len(first) && first[n] <= ' ' {
- suffix[n] = first[n]
- n++
- }
- if n > 2 && suffix[2] == '\t' {
- // assume the '\t' compensates for the /*
- suffix = suffix[2:n]
- } else {
- // otherwise assume two blanks
- suffix[0], suffix[1] = ' ', ' '
- suffix = suffix[0:n]
- }
- // Shorten the computed common prefix by the length of
- // suffix, if it is found as suffix of the prefix.
- prefix = strings.TrimSuffix(prefix, string(suffix))
- }
- }
-
- // Handle last line: If it only contains a closing */, align it
- // with the opening /*, otherwise align the text with the other
- // lines.
- last := lines[len(lines)-1]
- closing := "*/"
- before, _, _ := strings.Cut(last, closing) // closing always present
- if isBlank(before) {
- // last line only contains closing */
- if lineOfStars {
- closing = " */" // add blank to align final star
- }
- lines[len(lines)-1] = prefix + closing
- } else {
- // last line contains more comment text - assume
- // it is aligned like the other lines and include
- // in prefix computation
- prefix = commonPrefix(prefix, last)
- }
-
- // Remove the common prefix from all but the first and empty lines.
- for i, line := range lines {
- if i > 0 && line != "" {
- lines[i] = line[len(prefix):]
- }
- }
-}
-
-func (p *printer) writeComment(comment *ast.Comment) {
- text := comment.Text
- pos := p.posFor(comment.Pos())
-
- const linePrefix = "//line "
- if strings.HasPrefix(text, linePrefix) && (!pos.IsValid() || pos.Column == 1) {
- // Possibly a //-style line directive.
- // Suspend indentation temporarily to keep line directive valid.
- defer func(indent int) { p.indent = indent }(p.indent)
- p.indent = 0
- }
-
- // shortcut common case of //-style comments
- if text[1] == '/' {
- if constraint.IsGoBuild(text) {
- p.goBuild = append(p.goBuild, len(p.output))
- } else if constraint.IsPlusBuild(text) {
- p.plusBuild = append(p.plusBuild, len(p.output))
- }
- p.writeString(pos, trimRight(text), true)
- return
- }
-
- // for /*-style comments, print line by line and let the
- // write function take care of the proper indentation
- lines := strings.Split(text, "\n")
-
- // The comment started in the first column but is going
- // to be indented. For an idempotent result, add indentation
- // to all lines such that they look like they were indented
- // before - this will make sure the common prefix computation
- // is the same independent of how many times formatting is
- // applied (was issue 1835).
- if pos.IsValid() && pos.Column == 1 && p.indent > 0 {
- for i, line := range lines[1:] {
- lines[1+i] = " " + line
- }
- }
-
- stripCommonPrefix(lines)
-
- // write comment lines, separated by formfeed,
- // without a line break after the last line
- for i, line := range lines {
- if i > 0 {
- p.writeByte('\f', 1)
- pos = p.pos
- }
- if len(line) > 0 {
- p.writeString(pos, trimRight(line), true)
- }
- }
-}
-
-// writeCommentSuffix writes a line break after a comment if indicated
-// and processes any leftover indentation information. If a line break
-// is needed, the kind of break (newline vs formfeed) depends on the
-// pending whitespace. The writeCommentSuffix result indicates if a
-// newline was written or if a formfeed was dropped from the whitespace
-// buffer.
-func (p *printer) writeCommentSuffix(needsLinebreak bool) (wroteNewline, droppedFF bool) {
- for i, ch := range p.wsbuf {
- switch ch {
- case blank, vtab:
- // ignore trailing whitespace
- p.wsbuf[i] = ignore
- case indent, unindent:
- // don't lose indentation information
- case newline, formfeed:
- // if we need a line break, keep exactly one
- // but remember if we dropped any formfeeds
- if needsLinebreak {
- needsLinebreak = false
- wroteNewline = true
- } else {
- if ch == formfeed {
- droppedFF = true
- }
- p.wsbuf[i] = ignore
- }
- }
- }
- p.writeWhitespace(len(p.wsbuf))
-
- // make sure we have a line break
- if needsLinebreak {
- p.writeByte('\n', 1)
- wroteNewline = true
- }
-
- return
-}
-
-// containsLinebreak reports whether the whitespace buffer contains any line breaks.
-func (p *printer) containsLinebreak() bool {
- for _, ch := range p.wsbuf {
- if ch == newline || ch == formfeed {
- return true
- }
- }
- return false
-}
-
-// intersperseComments consumes all comments that appear before the next token
-// tok and prints it together with the buffered whitespace (i.e., the whitespace
-// that needs to be written before the next token). A heuristic is used to mix
-// the comments and whitespace. The intersperseComments result indicates if a
-// newline was written or if a formfeed was dropped from the whitespace buffer.
-func (p *printer) intersperseComments(next token.Position, tok token.Token) (wroteNewline, droppedFF bool) {
- var last *ast.Comment
- for p.commentBefore(next) {
- list := p.comment.List
- changed := false
- if p.lastTok != token.IMPORT && // do not rewrite cgo's import "C" comments
- p.posFor(p.comment.Pos()).Column == 1 &&
- p.posFor(p.comment.End()+1) == next {
- // Unindented comment abutting next token position:
- // a top-level doc comment.
- list = formatDocComment(list)
- changed = true
-
- if len(p.comment.List) > 0 && len(list) == 0 {
- // The doc comment was removed entirely.
- // Keep preceding whitespace.
- p.writeCommentPrefix(p.posFor(p.comment.Pos()), next, last, tok)
- // Change print state to continue at next.
- p.pos = next
- p.last = next
- // There can't be any more comments.
- p.nextComment()
- return p.writeCommentSuffix(false)
- }
- }
- for _, c := range list {
- p.writeCommentPrefix(p.posFor(c.Pos()), next, last, tok)
- p.writeComment(c)
- last = c
- }
- // In case list was rewritten, change print state to where
- // the original list would have ended.
- if len(p.comment.List) > 0 && changed {
- last = p.comment.List[len(p.comment.List)-1]
- p.pos = p.posFor(last.End())
- p.last = p.pos
- }
- p.nextComment()
- }
-
- if last != nil {
- // If the last comment is a /*-style comment and the next item
- // follows on the same line but is not a comma, and not a "closing"
- // token immediately following its corresponding "opening" token,
- // add an extra separator unless explicitly disabled. Use a blank
- // as separator unless we have pending linebreaks, they are not
- // disabled, and we are outside a composite literal, in which case
- // we want a linebreak (issue 15137).
- // TODO(gri) This has become overly complicated. We should be able
- // to track whether we're inside an expression or statement and
- // use that information to decide more directly.
- needsLinebreak := false
- if p.mode&noExtraBlank == 0 &&
- last.Text[1] == '*' && p.lineFor(last.Pos()) == next.Line &&
- tok != token.COMMA &&
- (tok != token.RPAREN || p.prevOpen == token.LPAREN) &&
- (tok != token.RBRACK || p.prevOpen == token.LBRACK) {
- if p.containsLinebreak() && p.mode&noExtraLinebreak == 0 && p.level == 0 {
- needsLinebreak = true
- } else {
- p.writeByte(' ', 1)
- }
- }
- // Ensure that there is a line break after a //-style comment,
- // before EOF, and before a closing '}' unless explicitly disabled.
- if last.Text[1] == '/' ||
- tok == token.EOF ||
- tok == token.RBRACE && p.mode&noExtraLinebreak == 0 {
- needsLinebreak = true
- }
- return p.writeCommentSuffix(needsLinebreak)
- }
-
- // no comment was written - we should never reach here since
- // intersperseComments should not be called in that case
- p.internalError("intersperseComments called without pending comments")
- return
-}
-
-// whiteWhitespace writes the first n whitespace entries.
-func (p *printer) writeWhitespace(n int) {
- // write entries
- for i := 0; i < n; i++ {
- switch ch := p.wsbuf[i]; ch {
- case ignore:
- // ignore!
- case indent:
- p.indent++
- case unindent:
- p.indent--
- if p.indent < 0 {
- p.internalError("negative indentation:", p.indent)
- p.indent = 0
- }
- case newline, formfeed:
- // A line break immediately followed by a "correcting"
- // unindent is swapped with the unindent - this permits
- // proper label positioning. If a comment is between
- // the line break and the label, the unindent is not
- // part of the comment whitespace prefix and the comment
- // will be positioned correctly indented.
- if i+1 < n && p.wsbuf[i+1] == unindent {
- // Use a formfeed to terminate the current section.
- // Otherwise, a long label name on the next line leading
- // to a wide column may increase the indentation column
- // of lines before the label; effectively leading to wrong
- // indentation.
- p.wsbuf[i], p.wsbuf[i+1] = unindent, formfeed
- i-- // do it again
- continue
- }
- fallthrough
- default:
- p.writeByte(byte(ch), 1)
- }
- }
-
- // shift remaining entries down
- l := copy(p.wsbuf, p.wsbuf[n:])
- p.wsbuf = p.wsbuf[:l]
-}
-
-// ----------------------------------------------------------------------------
-// Printing interface
-
-// nlimit limits n to maxNewlines.
-func nlimit(n int) int {
- if n > maxNewlines {
- n = maxNewlines
- }
- return n
-}
-
-func mayCombine(prev token.Token, next byte) (b bool) {
- switch prev {
- case token.INT:
- b = next == '.' // 1.
- case token.ADD:
- b = next == '+' // ++
- case token.SUB:
- b = next == '-' // --
- case token.QUO:
- b = next == '*' // /*
- case token.LSS:
- b = next == '-' || next == '<' // <- or <<
- case token.AND:
- b = next == '&' || next == '^' // && or &^
- }
- return
-}
-
-func (p *printer) setPos(pos token.Pos) {
- if pos.IsValid() {
- p.pos = p.posFor(pos) // accurate position of next item
- }
-}
-
-// print prints a list of "items" (roughly corresponding to syntactic
-// tokens, but also including whitespace and formatting information).
-// It is the only print function that should be called directly from
-// any of the AST printing functions in nodes.go.
-//
-// Whitespace is accumulated until a non-whitespace token appears. Any
-// comments that need to appear before that token are printed first,
-// taking into account the amount and structure of any pending white-
-// space for best comment placement. Then, any leftover whitespace is
-// printed, followed by the actual token.
-func (p *printer) print(args ...any) {
- for _, arg := range args {
- // information about the current arg
- var data string
- var isLit bool
- var impliedSemi bool // value for p.impliedSemi after this arg
-
- // record previous opening token, if any
- switch p.lastTok {
- case token.ILLEGAL:
- // ignore (white space)
- case token.LPAREN, token.LBRACK:
- p.prevOpen = p.lastTok
- default:
- // other tokens followed any opening token
- p.prevOpen = token.ILLEGAL
- }
-
- switch x := arg.(type) {
- case pmode:
- // toggle printer mode
- p.mode ^= x
- continue
-
- case whiteSpace:
- if x == ignore {
- // don't add ignore's to the buffer; they
- // may screw up "correcting" unindents (see
- // LabeledStmt)
- continue
- }
- i := len(p.wsbuf)
- if i == cap(p.wsbuf) {
- // Whitespace sequences are very short so this should
- // never happen. Handle gracefully (but possibly with
- // bad comment placement) if it does happen.
- p.writeWhitespace(i)
- i = 0
- }
- p.wsbuf = p.wsbuf[0 : i+1]
- p.wsbuf[i] = x
- if x == newline || x == formfeed {
- // newlines affect the current state (p.impliedSemi)
- // and not the state after printing arg (impliedSemi)
- // because comments can be interspersed before the arg
- // in this case
- p.impliedSemi = false
- }
- p.lastTok = token.ILLEGAL
- continue
-
- case *ast.Ident:
- data = x.Name
- impliedSemi = true
- p.lastTok = token.IDENT
-
- case *ast.BasicLit:
- data = x.Value
- isLit = true
- impliedSemi = true
- p.lastTok = x.Kind
-
- case token.Token:
- s := x.String()
- if mayCombine(p.lastTok, s[0]) {
- // the previous and the current token must be
- // separated by a blank otherwise they combine
- // into a different incorrect token sequence
- // (except for token.INT followed by a '.' this
- // should never happen because it is taken care
- // of via binary expression formatting)
- if len(p.wsbuf) != 0 {
- p.internalError("whitespace buffer not empty")
- }
- p.wsbuf = p.wsbuf[0:1]
- p.wsbuf[0] = ' '
- }
- data = s
- // some keywords followed by a newline imply a semicolon
- switch x {
- case token.BREAK, token.CONTINUE, token.FALLTHROUGH, token.RETURN,
- token.INC, token.DEC, token.RPAREN, token.RBRACK, token.RBRACE:
- impliedSemi = true
- }
- p.lastTok = x
-
- case string:
- // incorrect AST - print error message
- data = x
- isLit = true
- impliedSemi = true
- p.lastTok = token.STRING
-
- default:
- fmt.Fprintf(os.Stderr, "print: unsupported argument %v (%T)\n", arg, arg)
- panic("go/printer type")
- }
- // data != ""
-
- next := p.pos // estimated/accurate position of next item
- wroteNewline, droppedFF := p.flush(next, p.lastTok)
-
- // intersperse extra newlines if present in the source and
- // if they don't cause extra semicolons (don't do this in
- // flush as it will cause extra newlines at the end of a file)
- if !p.impliedSemi {
- n := nlimit(next.Line - p.pos.Line)
- // don't exceed maxNewlines if we already wrote one
- if wroteNewline && n == maxNewlines {
- n = maxNewlines - 1
- }
- if n > 0 {
- ch := byte('\n')
- if droppedFF {
- ch = '\f' // use formfeed since we dropped one before
- }
- p.writeByte(ch, n)
- impliedSemi = false
- }
- }
-
- // the next token starts now - record its line number if requested
- if p.linePtr != nil {
- *p.linePtr = p.out.Line
- p.linePtr = nil
- }
-
- p.writeString(next, data, isLit)
- p.impliedSemi = impliedSemi
- }
-}
-
-// flush prints any pending comments and whitespace occurring textually
-// before the position of the next token tok. The flush result indicates
-// if a newline was written or if a formfeed was dropped from the whitespace
-// buffer.
-func (p *printer) flush(next token.Position, tok token.Token) (wroteNewline, droppedFF bool) {
- if p.commentBefore(next) {
- // if there are comments before the next item, intersperse them
- wroteNewline, droppedFF = p.intersperseComments(next, tok)
- } else {
- // otherwise, write any leftover whitespace
- p.writeWhitespace(len(p.wsbuf))
- }
- return
-}
-
-// getDoc returns the ast.CommentGroup associated with n, if any.
-func getDoc(n ast.Node) *ast.CommentGroup {
- switch n := n.(type) {
- case *ast.Field:
- return n.Doc
- case *ast.ImportSpec:
- return n.Doc
- case *ast.ValueSpec:
- return n.Doc
- case *ast.TypeSpec:
- return n.Doc
- case *ast.GenDecl:
- return n.Doc
- case *ast.FuncDecl:
- return n.Doc
- case *ast.File:
- return n.Doc
- }
- return nil
-}
-
-func getLastComment(n ast.Node) *ast.CommentGroup {
- switch n := n.(type) {
- case *ast.Field:
- return n.Comment
- case *ast.ImportSpec:
- return n.Comment
- case *ast.ValueSpec:
- return n.Comment
- case *ast.TypeSpec:
- return n.Comment
- case *ast.GenDecl:
- if len(n.Specs) > 0 {
- return getLastComment(n.Specs[len(n.Specs)-1])
- }
- case *ast.File:
- if len(n.Comments) > 0 {
- return n.Comments[len(n.Comments)-1]
- }
- }
- return nil
-}
-
-func (p *printer) printNode(node any) error {
- // unpack *CommentedNode, if any
- var comments []*ast.CommentGroup
- if cnode, ok := node.(*CommentedNode); ok {
- node = cnode.Node
- comments = cnode.Comments
- }
-
- if comments != nil {
- // commented node - restrict comment list to relevant range
- n, ok := node.(ast.Node)
- if !ok {
- goto unsupported
- }
- beg := n.Pos()
- end := n.End()
- // if the node has associated documentation,
- // include that commentgroup in the range
- // (the comment list is sorted in the order
- // of the comment appearance in the source code)
- if doc := getDoc(n); doc != nil {
- beg = doc.Pos()
- }
- if com := getLastComment(n); com != nil {
- if e := com.End(); e > end {
- end = e
- }
- }
- // token.Pos values are global offsets, we can
- // compare them directly
- i := 0
- for i < len(comments) && comments[i].End() < beg {
- i++
- }
- j := i
- for j < len(comments) && comments[j].Pos() < end {
- j++
- }
- if i < j {
- p.comments = comments[i:j]
- }
- } else if n, ok := node.(*ast.File); ok {
- // use ast.File comments, if any
- p.comments = n.Comments
- }
-
- // if there are no comments, use node comments
- p.useNodeComments = p.comments == nil
-
- // get comments ready for use
- p.nextComment()
-
- p.print(pmode(0))
-
- // format node
- switch n := node.(type) {
- case ast.Expr:
- p.expr(n)
- case ast.Stmt:
- // A labeled statement will un-indent to position the label.
- // Set p.indent to 1 so we don't get indent "underflow".
- if _, ok := n.(*ast.LabeledStmt); ok {
- p.indent = 1
- }
- p.stmt(n, false)
- case ast.Decl:
- p.decl(n)
- case ast.Spec:
- p.spec(n, 1, false)
- case []ast.Stmt:
- // A labeled statement will un-indent to position the label.
- // Set p.indent to 1 so we don't get indent "underflow".
- for _, s := range n {
- if _, ok := s.(*ast.LabeledStmt); ok {
- p.indent = 1
- }
- }
- p.stmtList(n, 0, false)
- case []ast.Decl:
- p.declList(n)
- case *ast.File:
- p.file(n)
- default:
- goto unsupported
- }
-
- return p.sourcePosErr
-
-unsupported:
- return fmt.Errorf("go/printer: unsupported node type %T", node)
-}
-
-// ----------------------------------------------------------------------------
-// Trimmer
-
-// A trimmer is an io.Writer filter for stripping tabwriter.Escape
-// characters, trailing blanks and tabs, and for converting formfeed
-// and vtab characters into newlines and htabs (in case no tabwriter
-// is used). Text bracketed by tabwriter.Escape characters is passed
-// through unchanged.
-type trimmer struct {
- output io.Writer
- state int
- space []byte
-}
-
-// trimmer is implemented as a state machine.
-// It can be in one of the following states:
-const (
- inSpace = iota // inside space
- inEscape // inside text bracketed by tabwriter.Escapes
- inText // inside text
-)
-
-func (p *trimmer) resetSpace() {
- p.state = inSpace
- p.space = p.space[0:0]
-}
-
-// Design note: It is tempting to eliminate extra blanks occurring in
-// whitespace in this function as it could simplify some
-// of the blanks logic in the node printing functions.
-// However, this would mess up any formatting done by
-// the tabwriter.
-
-var aNewline = []byte("\n")
-
-func (p *trimmer) Write(data []byte) (n int, err error) {
- // invariants:
- // p.state == inSpace:
- // p.space is unwritten
- // p.state == inEscape, inText:
- // data[m:n] is unwritten
- m := 0
- var b byte
- for n, b = range data {
- if b == '\v' {
- b = '\t' // convert to htab
- }
- switch p.state {
- case inSpace:
- switch b {
- case '\t', ' ':
- p.space = append(p.space, b)
- case '\n', '\f':
- p.resetSpace() // discard trailing space
- _, err = p.output.Write(aNewline)
- case tabwriter.Escape:
- _, err = p.output.Write(p.space)
- p.state = inEscape
- m = n + 1 // +1: skip tabwriter.Escape
- default:
- _, err = p.output.Write(p.space)
- p.state = inText
- m = n
- }
- case inEscape:
- if b == tabwriter.Escape {
- _, err = p.output.Write(data[m:n])
- p.resetSpace()
- }
- case inText:
- switch b {
- case '\t', ' ':
- _, err = p.output.Write(data[m:n])
- p.resetSpace()
- p.space = append(p.space, b)
- case '\n', '\f':
- _, err = p.output.Write(data[m:n])
- p.resetSpace()
- if err == nil {
- _, err = p.output.Write(aNewline)
- }
- case tabwriter.Escape:
- _, err = p.output.Write(data[m:n])
- p.state = inEscape
- m = n + 1 // +1: skip tabwriter.Escape
- }
- default:
- panic("unreachable")
- }
- if err != nil {
- return
- }
- }
- n = len(data)
-
- switch p.state {
- case inEscape, inText:
- _, err = p.output.Write(data[m:n])
- p.resetSpace()
- }
-
- return
-}
-
-// ----------------------------------------------------------------------------
-// Public interface
-
-// A Mode value is a set of flags (or 0). They control printing.
-type Mode uint
-
-const (
- RawFormat Mode = 1 << iota // do not use a tabwriter; if set, UseSpaces is ignored
- TabIndent // use tabs for indentation independent of UseSpaces
- UseSpaces // use spaces instead of tabs for alignment
- SourcePos // emit //line directives to preserve original source positions
-)
-
-// The mode below is not included in printer's public API because
-// editing code text is deemed out of scope. Because this mode is
-// unexported, it's also possible to modify or remove it based on
-// the evolving needs of go/format and cmd/gofmt without breaking
-// users. See discussion in CL 240683.
-const (
- // normalizeNumbers means to canonicalize number
- // literal prefixes and exponents while printing.
- //
- // This value is known in and used by go/format and cmd/gofmt.
- // It is currently more convenient and performant for those
- // packages to apply number normalization during printing,
- // rather than by modifying the AST in advance.
- normalizeNumbers Mode = 1 << 30
-)
-
-// A Config node controls the output of Fprint.
-type Config struct {
- Mode Mode // default: 0
- Tabwidth int // default: 8
- Indent int // default: 0 (all code is indented at least by this much)
-}
-
-var printerPool = sync.Pool{
- New: func() any {
- return &printer{
- // Whitespace sequences are short.
- wsbuf: make([]whiteSpace, 0, 16),
- // We start the printer with a 16K output buffer, which is currently
- // larger than about 80% of Go files in the standard library.
- output: make([]byte, 0, 16<<10),
- }
- },
-}
-
-func newPrinter(cfg *Config, fset *token.FileSet, nodeSizes map[ast.Node]int) *printer {
- p := printerPool.Get().(*printer)
- *p = printer{
- Config: *cfg,
- fset: fset,
- pos: token.Position{Line: 1, Column: 1},
- out: token.Position{Line: 1, Column: 1},
- wsbuf: p.wsbuf[:0],
- nodeSizes: nodeSizes,
- cachedPos: -1,
- output: p.output[:0],
- }
- return p
-}
-
-func (p *printer) free() {
- // Hard limit on buffer size; see https://golang.org/issue/23199.
- if cap(p.output) > 64<<10 {
- return
- }
-
- printerPool.Put(p)
-}
-
-// fprint implements Fprint and takes a nodesSizes map for setting up the printer state.
-func (cfg *Config) fprint(output io.Writer, fset *token.FileSet, node any, nodeSizes map[ast.Node]int) (err error) {
- // print node
- p := newPrinter(cfg, fset, nodeSizes)
- defer p.free()
- if err = p.printNode(node); err != nil {
- return
- }
- // print outstanding comments
- p.impliedSemi = false // EOF acts like a newline
- p.flush(token.Position{Offset: infinity, Line: infinity}, token.EOF)
-
- // output is buffered in p.output now.
- // fix //go:build and // +build comments if needed.
- p.fixGoBuildLines()
-
- // redirect output through a trimmer to eliminate trailing whitespace
- // (Input to a tabwriter must be untrimmed since trailing tabs provide
- // formatting information. The tabwriter could provide trimming
- // functionality but no tabwriter is used when RawFormat is set.)
- output = &trimmer{output: output}
-
- // redirect output through a tabwriter if necessary
- if cfg.Mode&RawFormat == 0 {
- minwidth := cfg.Tabwidth
-
- padchar := byte('\t')
- if cfg.Mode&UseSpaces != 0 {
- padchar = ' '
- }
-
- twmode := tabwriter.DiscardEmptyColumns
- if cfg.Mode&TabIndent != 0 {
- minwidth = 0
- twmode |= tabwriter.TabIndent
- }
-
- output = tabwriter.NewWriter(output, minwidth, cfg.Tabwidth, 1, padchar, twmode)
- }
-
- // write printer result via tabwriter/trimmer to output
- if _, err = output.Write(p.output); err != nil {
- return
- }
-
- // flush tabwriter, if any
- if tw, _ := output.(*tabwriter.Writer); tw != nil {
- err = tw.Flush()
- }
-
- return
-}
-
-// A CommentedNode bundles an AST node and corresponding comments.
-// It may be provided as argument to any of the Fprint functions.
-type CommentedNode struct {
- Node any // *ast.File, or ast.Expr, ast.Decl, ast.Spec, or ast.Stmt
- Comments []*ast.CommentGroup
-}
-
-// Fprint "pretty-prints" an AST node to output for a given configuration cfg.
-// Position information is interpreted relative to the file set fset.
-// The node type must be *ast.File, *CommentedNode, []ast.Decl, []ast.Stmt,
-// or assignment-compatible to ast.Expr, ast.Decl, ast.Spec, or ast.Stmt.
-func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node any) error {
- return cfg.fprint(output, fset, node, make(map[ast.Node]int))
-}
-
-// Fprint "pretty-prints" an AST node to output.
-// It calls Config.Fprint with default settings.
-// Note that gofmt uses tabs for indentation but spaces for alignment;
-// use format.Node (package go/format) for output that matches gofmt.
-func Fprint(output io.Writer, fset *token.FileSet, node any) error {
- return (&Config{Tabwidth: 8}).Fprint(output, fset, node)
-}
diff --git a/contrib/go/_std_1.20/src/go/printer/ya.make b/contrib/go/_std_1.20/src/go/printer/ya.make
deleted file mode 100644
index 34e2f065ad..0000000000
--- a/contrib/go/_std_1.20/src/go/printer/ya.make
+++ /dev/null
@@ -1,10 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- comment.go
- gobuild.go
- nodes.go
- printer.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/scanner/scanner.go b/contrib/go/_std_1.20/src/go/scanner/scanner.go
deleted file mode 100644
index 0cd9f5901d..0000000000
--- a/contrib/go/_std_1.20/src/go/scanner/scanner.go
+++ /dev/null
@@ -1,957 +0,0 @@
-// Copyright 2009 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 scanner implements a scanner for Go source text.
-// It takes a []byte as source which can then be tokenized
-// through repeated calls to the Scan method.
-package scanner
-
-import (
- "bytes"
- "fmt"
- "go/token"
- "path/filepath"
- "strconv"
- "unicode"
- "unicode/utf8"
-)
-
-// An ErrorHandler may be provided to Scanner.Init. If a syntax error is
-// encountered and a handler was installed, the handler is called with a
-// position and an error message. The position points to the beginning of
-// the offending token.
-type ErrorHandler func(pos token.Position, msg string)
-
-// A Scanner holds the scanner's internal state while processing
-// a given text. It can be allocated as part of another data
-// structure but must be initialized via Init before use.
-type Scanner struct {
- // immutable state
- file *token.File // source file handle
- dir string // directory portion of file.Name()
- src []byte // source
- err ErrorHandler // error reporting; or nil
- mode Mode // scanning mode
-
- // scanning state
- ch rune // current character
- offset int // character offset
- rdOffset int // reading offset (position after current character)
- lineOffset int // current line offset
- insertSemi bool // insert a semicolon before next newline
- nlPos token.Pos // position of newline in preceding comment
-
- // public state - ok to modify
- ErrorCount int // number of errors encountered
-}
-
-const (
- bom = 0xFEFF // byte order mark, only permitted as very first character
- eof = -1 // end of file
-)
-
-// Read the next Unicode char into s.ch.
-// s.ch < 0 means end-of-file.
-//
-// For optimization, there is some overlap between this method and
-// s.scanIdentifier.
-func (s *Scanner) next() {
- if s.rdOffset < len(s.src) {
- s.offset = s.rdOffset
- if s.ch == '\n' {
- s.lineOffset = s.offset
- s.file.AddLine(s.offset)
- }
- r, w := rune(s.src[s.rdOffset]), 1
- switch {
- case r == 0:
- s.error(s.offset, "illegal character NUL")
- case r >= utf8.RuneSelf:
- // not ASCII
- r, w = utf8.DecodeRune(s.src[s.rdOffset:])
- if r == utf8.RuneError && w == 1 {
- s.error(s.offset, "illegal UTF-8 encoding")
- } else if r == bom && s.offset > 0 {
- s.error(s.offset, "illegal byte order mark")
- }
- }
- s.rdOffset += w
- s.ch = r
- } else {
- s.offset = len(s.src)
- if s.ch == '\n' {
- s.lineOffset = s.offset
- s.file.AddLine(s.offset)
- }
- s.ch = eof
- }
-}
-
-// peek returns the byte following the most recently read character without
-// advancing the scanner. If the scanner is at EOF, peek returns 0.
-func (s *Scanner) peek() byte {
- if s.rdOffset < len(s.src) {
- return s.src[s.rdOffset]
- }
- return 0
-}
-
-// A mode value is a set of flags (or 0).
-// They control scanner behavior.
-type Mode uint
-
-const (
- ScanComments Mode = 1 << iota // return comments as COMMENT tokens
- dontInsertSemis // do not automatically insert semicolons - for testing only
-)
-
-// Init prepares the scanner s to tokenize the text src by setting the
-// scanner at the beginning of src. The scanner uses the file set file
-// for position information and it adds line information for each line.
-// It is ok to re-use the same file when re-scanning the same file as
-// line information which is already present is ignored. Init causes a
-// panic if the file size does not match the src size.
-//
-// Calls to Scan will invoke the error handler err if they encounter a
-// syntax error and err is not nil. Also, for each error encountered,
-// the Scanner field ErrorCount is incremented by one. The mode parameter
-// determines how comments are handled.
-//
-// Note that Init may call err if there is an error in the first character
-// of the file.
-func (s *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode Mode) {
- // Explicitly initialize all fields since a scanner may be reused.
- if file.Size() != len(src) {
- panic(fmt.Sprintf("file size (%d) does not match src len (%d)", file.Size(), len(src)))
- }
- s.file = file
- s.dir, _ = filepath.Split(file.Name())
- s.src = src
- s.err = err
- s.mode = mode
-
- s.ch = ' '
- s.offset = 0
- s.rdOffset = 0
- s.lineOffset = 0
- s.insertSemi = false
- s.ErrorCount = 0
-
- s.next()
- if s.ch == bom {
- s.next() // ignore BOM at file beginning
- }
-}
-
-func (s *Scanner) error(offs int, msg string) {
- if s.err != nil {
- s.err(s.file.Position(s.file.Pos(offs)), msg)
- }
- s.ErrorCount++
-}
-
-func (s *Scanner) errorf(offs int, format string, args ...any) {
- s.error(offs, fmt.Sprintf(format, args...))
-}
-
-// scanComment returns the text of the comment and (if nonzero)
-// the offset of the first newline within it, which implies a
-// /*...*/ comment.
-func (s *Scanner) scanComment() (string, int) {
- // initial '/' already consumed; s.ch == '/' || s.ch == '*'
- offs := s.offset - 1 // position of initial '/'
- next := -1 // position immediately following the comment; < 0 means invalid comment
- numCR := 0
- nlOffset := 0 // offset of first newline within /*...*/ comment
-
- if s.ch == '/' {
- //-style comment
- // (the final '\n' is not considered part of the comment)
- s.next()
- for s.ch != '\n' && s.ch >= 0 {
- if s.ch == '\r' {
- numCR++
- }
- s.next()
- }
- // if we are at '\n', the position following the comment is afterwards
- next = s.offset
- if s.ch == '\n' {
- next++
- }
- goto exit
- }
-
- /*-style comment */
- s.next()
- for s.ch >= 0 {
- ch := s.ch
- if ch == '\r' {
- numCR++
- } else if ch == '\n' && nlOffset == 0 {
- nlOffset = s.offset
- }
- s.next()
- if ch == '*' && s.ch == '/' {
- s.next()
- next = s.offset
- goto exit
- }
- }
-
- s.error(offs, "comment not terminated")
-
-exit:
- lit := s.src[offs:s.offset]
-
- // On Windows, a (//-comment) line may end in "\r\n".
- // Remove the final '\r' before analyzing the text for
- // line directives (matching the compiler). Remove any
- // other '\r' afterwards (matching the pre-existing be-
- // havior of the scanner).
- if numCR > 0 && len(lit) >= 2 && lit[1] == '/' && lit[len(lit)-1] == '\r' {
- lit = lit[:len(lit)-1]
- numCR--
- }
-
- // interpret line directives
- // (//line directives must start at the beginning of the current line)
- if next >= 0 /* implies valid comment */ && (lit[1] == '*' || offs == s.lineOffset) && bytes.HasPrefix(lit[2:], prefix) {
- s.updateLineInfo(next, offs, lit)
- }
-
- if numCR > 0 {
- lit = stripCR(lit, lit[1] == '*')
- }
-
- return string(lit), nlOffset
-}
-
-var prefix = []byte("line ")
-
-// updateLineInfo parses the incoming comment text at offset offs
-// as a line directive. If successful, it updates the line info table
-// for the position next per the line directive.
-func (s *Scanner) updateLineInfo(next, offs int, text []byte) {
- // extract comment text
- if text[1] == '*' {
- text = text[:len(text)-2] // lop off trailing "*/"
- }
- text = text[7:] // lop off leading "//line " or "/*line "
- offs += 7
-
- i, n, ok := trailingDigits(text)
- if i == 0 {
- return // ignore (not a line directive)
- }
- // i > 0
-
- if !ok {
- // text has a suffix :xxx but xxx is not a number
- s.error(offs+i, "invalid line number: "+string(text[i:]))
- return
- }
-
- // Put a cap on the maximum size of line and column numbers.
- // 30 bits allows for some additional space before wrapping an int32.
- const maxLineCol = 1<<30 - 1
- var line, col int
- i2, n2, ok2 := trailingDigits(text[:i-1])
- if ok2 {
- //line filename:line:col
- i, i2 = i2, i
- line, col = n2, n
- if col == 0 || col > maxLineCol {
- s.error(offs+i2, "invalid column number: "+string(text[i2:]))
- return
- }
- text = text[:i2-1] // lop off ":col"
- } else {
- //line filename:line
- line = n
- }
-
- if line == 0 || line > maxLineCol {
- s.error(offs+i, "invalid line number: "+string(text[i:]))
- return
- }
-
- // If we have a column (//line filename:line:col form),
- // an empty filename means to use the previous filename.
- filename := string(text[:i-1]) // lop off ":line", and trim white space
- if filename == "" && ok2 {
- filename = s.file.Position(s.file.Pos(offs)).Filename
- } else if filename != "" {
- // Put a relative filename in the current directory.
- // This is for compatibility with earlier releases.
- // See issue 26671.
- filename = filepath.Clean(filename)
- if !filepath.IsAbs(filename) {
- filename = filepath.Join(s.dir, filename)
- }
- }
-
- s.file.AddLineColumnInfo(next, filename, line, col)
-}
-
-func trailingDigits(text []byte) (int, int, bool) {
- i := bytes.LastIndexByte(text, ':') // look from right (Windows filenames may contain ':')
- if i < 0 {
- return 0, 0, false // no ":"
- }
- // i >= 0
- n, err := strconv.ParseUint(string(text[i+1:]), 10, 0)
- return i + 1, int(n), err == nil
-}
-
-func isLetter(ch rune) bool {
- return 'a' <= lower(ch) && lower(ch) <= 'z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch)
-}
-
-func isDigit(ch rune) bool {
- return isDecimal(ch) || ch >= utf8.RuneSelf && unicode.IsDigit(ch)
-}
-
-// scanIdentifier reads the string of valid identifier characters at s.offset.
-// It must only be called when s.ch is known to be a valid letter.
-//
-// Be careful when making changes to this function: it is optimized and affects
-// scanning performance significantly.
-func (s *Scanner) scanIdentifier() string {
- offs := s.offset
-
- // Optimize for the common case of an ASCII identifier.
- //
- // Ranging over s.src[s.rdOffset:] lets us avoid some bounds checks, and
- // avoids conversions to runes.
- //
- // In case we encounter a non-ASCII character, fall back on the slower path
- // of calling into s.next().
- for rdOffset, b := range s.src[s.rdOffset:] {
- if 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z' || b == '_' || '0' <= b && b <= '9' {
- // Avoid assigning a rune for the common case of an ascii character.
- continue
- }
- s.rdOffset += rdOffset
- if 0 < b && b < utf8.RuneSelf {
- // Optimization: we've encountered an ASCII character that's not a letter
- // or number. Avoid the call into s.next() and corresponding set up.
- //
- // Note that s.next() does some line accounting if s.ch is '\n', so this
- // shortcut is only possible because we know that the preceding character
- // is not '\n'.
- s.ch = rune(b)
- s.offset = s.rdOffset
- s.rdOffset++
- goto exit
- }
- // We know that the preceding character is valid for an identifier because
- // scanIdentifier is only called when s.ch is a letter, so calling s.next()
- // at s.rdOffset resets the scanner state.
- s.next()
- for isLetter(s.ch) || isDigit(s.ch) {
- s.next()
- }
- goto exit
- }
- s.offset = len(s.src)
- s.rdOffset = len(s.src)
- s.ch = eof
-
-exit:
- return string(s.src[offs:s.offset])
-}
-
-func digitVal(ch rune) int {
- switch {
- case '0' <= ch && ch <= '9':
- return int(ch - '0')
- case 'a' <= lower(ch) && lower(ch) <= 'f':
- return int(lower(ch) - 'a' + 10)
- }
- return 16 // larger than any legal digit val
-}
-
-func lower(ch rune) rune { return ('a' - 'A') | ch } // returns lower-case ch iff ch is ASCII letter
-func isDecimal(ch rune) bool { return '0' <= ch && ch <= '9' }
-func isHex(ch rune) bool { return '0' <= ch && ch <= '9' || 'a' <= lower(ch) && lower(ch) <= 'f' }
-
-// digits accepts the sequence { digit | '_' }.
-// If base <= 10, digits accepts any decimal digit but records
-// the offset (relative to the source start) of a digit >= base
-// in *invalid, if *invalid < 0.
-// digits returns a bitset describing whether the sequence contained
-// digits (bit 0 is set), or separators '_' (bit 1 is set).
-func (s *Scanner) digits(base int, invalid *int) (digsep int) {
- if base <= 10 {
- max := rune('0' + base)
- for isDecimal(s.ch) || s.ch == '_' {
- ds := 1
- if s.ch == '_' {
- ds = 2
- } else if s.ch >= max && *invalid < 0 {
- *invalid = s.offset // record invalid rune offset
- }
- digsep |= ds
- s.next()
- }
- } else {
- for isHex(s.ch) || s.ch == '_' {
- ds := 1
- if s.ch == '_' {
- ds = 2
- }
- digsep |= ds
- s.next()
- }
- }
- return
-}
-
-func (s *Scanner) scanNumber() (token.Token, string) {
- offs := s.offset
- tok := token.ILLEGAL
-
- base := 10 // number base
- prefix := rune(0) // one of 0 (decimal), '0' (0-octal), 'x', 'o', or 'b'
- digsep := 0 // bit 0: digit present, bit 1: '_' present
- invalid := -1 // index of invalid digit in literal, or < 0
-
- // integer part
- if s.ch != '.' {
- tok = token.INT
- if s.ch == '0' {
- s.next()
- switch lower(s.ch) {
- case 'x':
- s.next()
- base, prefix = 16, 'x'
- case 'o':
- s.next()
- base, prefix = 8, 'o'
- case 'b':
- s.next()
- base, prefix = 2, 'b'
- default:
- base, prefix = 8, '0'
- digsep = 1 // leading 0
- }
- }
- digsep |= s.digits(base, &invalid)
- }
-
- // fractional part
- if s.ch == '.' {
- tok = token.FLOAT
- if prefix == 'o' || prefix == 'b' {
- s.error(s.offset, "invalid radix point in "+litname(prefix))
- }
- s.next()
- digsep |= s.digits(base, &invalid)
- }
-
- if digsep&1 == 0 {
- s.error(s.offset, litname(prefix)+" has no digits")
- }
-
- // exponent
- if e := lower(s.ch); e == 'e' || e == 'p' {
- switch {
- case e == 'e' && prefix != 0 && prefix != '0':
- s.errorf(s.offset, "%q exponent requires decimal mantissa", s.ch)
- case e == 'p' && prefix != 'x':
- s.errorf(s.offset, "%q exponent requires hexadecimal mantissa", s.ch)
- }
- s.next()
- tok = token.FLOAT
- if s.ch == '+' || s.ch == '-' {
- s.next()
- }
- ds := s.digits(10, nil)
- digsep |= ds
- if ds&1 == 0 {
- s.error(s.offset, "exponent has no digits")
- }
- } else if prefix == 'x' && tok == token.FLOAT {
- s.error(s.offset, "hexadecimal mantissa requires a 'p' exponent")
- }
-
- // suffix 'i'
- if s.ch == 'i' {
- tok = token.IMAG
- s.next()
- }
-
- lit := string(s.src[offs:s.offset])
- if tok == token.INT && invalid >= 0 {
- s.errorf(invalid, "invalid digit %q in %s", lit[invalid-offs], litname(prefix))
- }
- if digsep&2 != 0 {
- if i := invalidSep(lit); i >= 0 {
- s.error(offs+i, "'_' must separate successive digits")
- }
- }
-
- return tok, lit
-}
-
-func litname(prefix rune) string {
- switch prefix {
- case 'x':
- return "hexadecimal literal"
- case 'o', '0':
- return "octal literal"
- case 'b':
- return "binary literal"
- }
- return "decimal literal"
-}
-
-// invalidSep returns the index of the first invalid separator in x, or -1.
-func invalidSep(x string) int {
- x1 := ' ' // prefix char, we only care if it's 'x'
- d := '.' // digit, one of '_', '0' (a digit), or '.' (anything else)
- i := 0
-
- // a prefix counts as a digit
- if len(x) >= 2 && x[0] == '0' {
- x1 = lower(rune(x[1]))
- if x1 == 'x' || x1 == 'o' || x1 == 'b' {
- d = '0'
- i = 2
- }
- }
-
- // mantissa and exponent
- for ; i < len(x); i++ {
- p := d // previous digit
- d = rune(x[i])
- switch {
- case d == '_':
- if p != '0' {
- return i
- }
- case isDecimal(d) || x1 == 'x' && isHex(d):
- d = '0'
- default:
- if p == '_' {
- return i - 1
- }
- d = '.'
- }
- }
- if d == '_' {
- return len(x) - 1
- }
-
- return -1
-}
-
-// scanEscape parses an escape sequence where rune is the accepted
-// escaped quote. In case of a syntax error, it stops at the offending
-// character (without consuming it) and returns false. Otherwise
-// it returns true.
-func (s *Scanner) scanEscape(quote rune) bool {
- offs := s.offset
-
- var n int
- var base, max uint32
- switch s.ch {
- case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
- s.next()
- return true
- case '0', '1', '2', '3', '4', '5', '6', '7':
- n, base, max = 3, 8, 255
- case 'x':
- s.next()
- n, base, max = 2, 16, 255
- case 'u':
- s.next()
- n, base, max = 4, 16, unicode.MaxRune
- case 'U':
- s.next()
- n, base, max = 8, 16, unicode.MaxRune
- default:
- msg := "unknown escape sequence"
- if s.ch < 0 {
- msg = "escape sequence not terminated"
- }
- s.error(offs, msg)
- return false
- }
-
- var x uint32
- for n > 0 {
- d := uint32(digitVal(s.ch))
- if d >= base {
- msg := fmt.Sprintf("illegal character %#U in escape sequence", s.ch)
- if s.ch < 0 {
- msg = "escape sequence not terminated"
- }
- s.error(s.offset, msg)
- return false
- }
- x = x*base + d
- s.next()
- n--
- }
-
- if x > max || 0xD800 <= x && x < 0xE000 {
- s.error(offs, "escape sequence is invalid Unicode code point")
- return false
- }
-
- return true
-}
-
-func (s *Scanner) scanRune() string {
- // '\'' opening already consumed
- offs := s.offset - 1
-
- valid := true
- n := 0
- for {
- ch := s.ch
- if ch == '\n' || ch < 0 {
- // only report error if we don't have one already
- if valid {
- s.error(offs, "rune literal not terminated")
- valid = false
- }
- break
- }
- s.next()
- if ch == '\'' {
- break
- }
- n++
- if ch == '\\' {
- if !s.scanEscape('\'') {
- valid = false
- }
- // continue to read to closing quote
- }
- }
-
- if valid && n != 1 {
- s.error(offs, "illegal rune literal")
- }
-
- return string(s.src[offs:s.offset])
-}
-
-func (s *Scanner) scanString() string {
- // '"' opening already consumed
- offs := s.offset - 1
-
- for {
- ch := s.ch
- if ch == '\n' || ch < 0 {
- s.error(offs, "string literal not terminated")
- break
- }
- s.next()
- if ch == '"' {
- break
- }
- if ch == '\\' {
- s.scanEscape('"')
- }
- }
-
- return string(s.src[offs:s.offset])
-}
-
-func stripCR(b []byte, comment bool) []byte {
- c := make([]byte, len(b))
- i := 0
- for j, ch := range b {
- // In a /*-style comment, don't strip \r from *\r/ (incl.
- // sequences of \r from *\r\r...\r/) since the resulting
- // */ would terminate the comment too early unless the \r
- // is immediately following the opening /* in which case
- // it's ok because /*/ is not closed yet (issue #11151).
- if ch != '\r' || comment && i > len("/*") && c[i-1] == '*' && j+1 < len(b) && b[j+1] == '/' {
- c[i] = ch
- i++
- }
- }
- return c[:i]
-}
-
-func (s *Scanner) scanRawString() string {
- // '`' opening already consumed
- offs := s.offset - 1
-
- hasCR := false
- for {
- ch := s.ch
- if ch < 0 {
- s.error(offs, "raw string literal not terminated")
- break
- }
- s.next()
- if ch == '`' {
- break
- }
- if ch == '\r' {
- hasCR = true
- }
- }
-
- lit := s.src[offs:s.offset]
- if hasCR {
- lit = stripCR(lit, false)
- }
-
- return string(lit)
-}
-
-func (s *Scanner) skipWhitespace() {
- for s.ch == ' ' || s.ch == '\t' || s.ch == '\n' && !s.insertSemi || s.ch == '\r' {
- s.next()
- }
-}
-
-// Helper functions for scanning multi-byte tokens such as >> += >>= .
-// Different routines recognize different length tok_i based on matches
-// of ch_i. If a token ends in '=', the result is tok1 or tok3
-// respectively. Otherwise, the result is tok0 if there was no other
-// matching character, or tok2 if the matching character was ch2.
-
-func (s *Scanner) switch2(tok0, tok1 token.Token) token.Token {
- if s.ch == '=' {
- s.next()
- return tok1
- }
- return tok0
-}
-
-func (s *Scanner) switch3(tok0, tok1 token.Token, ch2 rune, tok2 token.Token) token.Token {
- if s.ch == '=' {
- s.next()
- return tok1
- }
- if s.ch == ch2 {
- s.next()
- return tok2
- }
- return tok0
-}
-
-func (s *Scanner) switch4(tok0, tok1 token.Token, ch2 rune, tok2, tok3 token.Token) token.Token {
- if s.ch == '=' {
- s.next()
- return tok1
- }
- if s.ch == ch2 {
- s.next()
- if s.ch == '=' {
- s.next()
- return tok3
- }
- return tok2
- }
- return tok0
-}
-
-// Scan scans the next token and returns the token position, the token,
-// and its literal string if applicable. The source end is indicated by
-// token.EOF.
-//
-// If the returned token is a literal (token.IDENT, token.INT, token.FLOAT,
-// token.IMAG, token.CHAR, token.STRING) or token.COMMENT, the literal string
-// has the corresponding value.
-//
-// If the returned token is a keyword, the literal string is the keyword.
-//
-// If the returned token is token.SEMICOLON, the corresponding
-// literal string is ";" if the semicolon was present in the source,
-// and "\n" if the semicolon was inserted because of a newline or
-// at EOF.
-//
-// If the returned token is token.ILLEGAL, the literal string is the
-// offending character.
-//
-// In all other cases, Scan returns an empty literal string.
-//
-// For more tolerant parsing, Scan will return a valid token if
-// possible even if a syntax error was encountered. Thus, even
-// if the resulting token sequence contains no illegal tokens,
-// a client may not assume that no error occurred. Instead it
-// must check the scanner's ErrorCount or the number of calls
-// of the error handler, if there was one installed.
-//
-// Scan adds line information to the file added to the file
-// set with Init. Token positions are relative to that file
-// and thus relative to the file set.
-func (s *Scanner) Scan() (pos token.Pos, tok token.Token, lit string) {
-scanAgain:
- if s.nlPos.IsValid() {
- // Return artificial ';' token after /*...*/ comment
- // containing newline, at position of first newline.
- pos, tok, lit = s.nlPos, token.SEMICOLON, "\n"
- s.nlPos = token.NoPos
- return
- }
-
- s.skipWhitespace()
-
- // current token start
- pos = s.file.Pos(s.offset)
-
- // determine token value
- insertSemi := false
- switch ch := s.ch; {
- case isLetter(ch):
- lit = s.scanIdentifier()
- if len(lit) > 1 {
- // keywords are longer than one letter - avoid lookup otherwise
- tok = token.Lookup(lit)
- switch tok {
- case token.IDENT, token.BREAK, token.CONTINUE, token.FALLTHROUGH, token.RETURN:
- insertSemi = true
- }
- } else {
- insertSemi = true
- tok = token.IDENT
- }
- case isDecimal(ch) || ch == '.' && isDecimal(rune(s.peek())):
- insertSemi = true
- tok, lit = s.scanNumber()
- default:
- s.next() // always make progress
- switch ch {
- case eof:
- if s.insertSemi {
- s.insertSemi = false // EOF consumed
- return pos, token.SEMICOLON, "\n"
- }
- tok = token.EOF
- case '\n':
- // we only reach here if s.insertSemi was
- // set in the first place and exited early
- // from s.skipWhitespace()
- s.insertSemi = false // newline consumed
- return pos, token.SEMICOLON, "\n"
- case '"':
- insertSemi = true
- tok = token.STRING
- lit = s.scanString()
- case '\'':
- insertSemi = true
- tok = token.CHAR
- lit = s.scanRune()
- case '`':
- insertSemi = true
- tok = token.STRING
- lit = s.scanRawString()
- case ':':
- tok = s.switch2(token.COLON, token.DEFINE)
- case '.':
- // fractions starting with a '.' are handled by outer switch
- tok = token.PERIOD
- if s.ch == '.' && s.peek() == '.' {
- s.next()
- s.next() // consume last '.'
- tok = token.ELLIPSIS
- }
- case ',':
- tok = token.COMMA
- case ';':
- tok = token.SEMICOLON
- lit = ";"
- case '(':
- tok = token.LPAREN
- case ')':
- insertSemi = true
- tok = token.RPAREN
- case '[':
- tok = token.LBRACK
- case ']':
- insertSemi = true
- tok = token.RBRACK
- case '{':
- tok = token.LBRACE
- case '}':
- insertSemi = true
- tok = token.RBRACE
- case '+':
- tok = s.switch3(token.ADD, token.ADD_ASSIGN, '+', token.INC)
- if tok == token.INC {
- insertSemi = true
- }
- case '-':
- tok = s.switch3(token.SUB, token.SUB_ASSIGN, '-', token.DEC)
- if tok == token.DEC {
- insertSemi = true
- }
- case '*':
- tok = s.switch2(token.MUL, token.MUL_ASSIGN)
- case '/':
- if s.ch == '/' || s.ch == '*' {
- // comment
- comment, nlOffset := s.scanComment()
- if s.insertSemi && nlOffset != 0 {
- // For /*...*/ containing \n, return
- // COMMENT then artificial SEMICOLON.
- s.nlPos = s.file.Pos(nlOffset)
- s.insertSemi = false
- } else {
- insertSemi = s.insertSemi // preserve insertSemi info
- }
- if s.mode&ScanComments == 0 {
- // skip comment
- goto scanAgain
- }
- tok = token.COMMENT
- lit = comment
- } else {
- // division
- tok = s.switch2(token.QUO, token.QUO_ASSIGN)
- }
- case '%':
- tok = s.switch2(token.REM, token.REM_ASSIGN)
- case '^':
- tok = s.switch2(token.XOR, token.XOR_ASSIGN)
- case '<':
- if s.ch == '-' {
- s.next()
- tok = token.ARROW
- } else {
- tok = s.switch4(token.LSS, token.LEQ, '<', token.SHL, token.SHL_ASSIGN)
- }
- case '>':
- tok = s.switch4(token.GTR, token.GEQ, '>', token.SHR, token.SHR_ASSIGN)
- case '=':
- tok = s.switch2(token.ASSIGN, token.EQL)
- case '!':
- tok = s.switch2(token.NOT, token.NEQ)
- case '&':
- if s.ch == '^' {
- s.next()
- tok = s.switch2(token.AND_NOT, token.AND_NOT_ASSIGN)
- } else {
- tok = s.switch3(token.AND, token.AND_ASSIGN, '&', token.LAND)
- }
- case '|':
- tok = s.switch3(token.OR, token.OR_ASSIGN, '|', token.LOR)
- case '~':
- tok = token.TILDE
- default:
- // next reports unexpected BOMs - don't repeat
- if ch != bom {
- s.errorf(s.file.Offset(pos), "illegal character %#U", ch)
- }
- insertSemi = s.insertSemi // preserve insertSemi info
- tok = token.ILLEGAL
- lit = string(ch)
- }
- }
- if s.mode&dontInsertSemis == 0 {
- s.insertSemi = insertSemi
- }
-
- return
-}
diff --git a/contrib/go/_std_1.20/src/go/scanner/ya.make b/contrib/go/_std_1.20/src/go/scanner/ya.make
deleted file mode 100644
index 42dcaff208..0000000000
--- a/contrib/go/_std_1.20/src/go/scanner/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- errors.go
- scanner.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/token/position.go b/contrib/go/_std_1.20/src/go/token/position.go
deleted file mode 100644
index cbc2ddb5eb..0000000000
--- a/contrib/go/_std_1.20/src/go/token/position.go
+++ /dev/null
@@ -1,556 +0,0 @@
-// Copyright 2010 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 token
-
-import (
- "fmt"
- "sort"
- "sync"
- "sync/atomic"
-)
-
-// -----------------------------------------------------------------------------
-// Positions
-
-// Position describes an arbitrary source position
-// including the file, line, and column location.
-// A Position is valid if the line number is > 0.
-type Position struct {
- Filename string // filename, if any
- Offset int // offset, starting at 0
- Line int // line number, starting at 1
- Column int // column number, starting at 1 (byte count)
-}
-
-// IsValid reports whether the position is valid.
-func (pos *Position) IsValid() bool { return pos.Line > 0 }
-
-// String returns a string in one of several forms:
-//
-// file:line:column valid position with file name
-// file:line valid position with file name but no column (column == 0)
-// line:column valid position without file name
-// line valid position without file name and no column (column == 0)
-// file invalid position with file name
-// - invalid position without file name
-func (pos Position) String() string {
- s := pos.Filename
- if pos.IsValid() {
- if s != "" {
- s += ":"
- }
- s += fmt.Sprintf("%d", pos.Line)
- if pos.Column != 0 {
- s += fmt.Sprintf(":%d", pos.Column)
- }
- }
- if s == "" {
- s = "-"
- }
- return s
-}
-
-// Pos is a compact encoding of a source position within a file set.
-// It can be converted into a Position for a more convenient, but much
-// larger, representation.
-//
-// The Pos value for a given file is a number in the range [base, base+size],
-// where base and size are specified when a file is added to the file set.
-// The difference between a Pos value and the corresponding file base
-// corresponds to the byte offset of that position (represented by the Pos value)
-// from the beginning of the file. Thus, the file base offset is the Pos value
-// representing the first byte in the file.
-//
-// To create the Pos value for a specific source offset (measured in bytes),
-// first add the respective file to the current file set using FileSet.AddFile
-// and then call File.Pos(offset) for that file. Given a Pos value p
-// for a specific file set fset, the corresponding Position value is
-// obtained by calling fset.Position(p).
-//
-// Pos values can be compared directly with the usual comparison operators:
-// If two Pos values p and q are in the same file, comparing p and q is
-// equivalent to comparing the respective source file offsets. If p and q
-// are in different files, p < q is true if the file implied by p was added
-// to the respective file set before the file implied by q.
-type Pos int
-
-// The zero value for Pos is NoPos; there is no file and line information
-// associated with it, and NoPos.IsValid() is false. NoPos is always
-// smaller than any other Pos value. The corresponding Position value
-// for NoPos is the zero value for Position.
-const NoPos Pos = 0
-
-// IsValid reports whether the position is valid.
-func (p Pos) IsValid() bool {
- return p != NoPos
-}
-
-// -----------------------------------------------------------------------------
-// File
-
-// A File is a handle for a file belonging to a FileSet.
-// A File has a name, size, and line offset table.
-type File struct {
- name string // file name as provided to AddFile
- base int // Pos value range for this file is [base...base+size]
- size int // file size as provided to AddFile
-
- // lines and infos are protected by mutex
- mutex sync.Mutex
- lines []int // lines contains the offset of the first character for each line (the first entry is always 0)
- infos []lineInfo
-}
-
-// Name returns the file name of file f as registered with AddFile.
-func (f *File) Name() string {
- return f.name
-}
-
-// Base returns the base offset of file f as registered with AddFile.
-func (f *File) Base() int {
- return f.base
-}
-
-// Size returns the size of file f as registered with AddFile.
-func (f *File) Size() int {
- return f.size
-}
-
-// LineCount returns the number of lines in file f.
-func (f *File) LineCount() int {
- f.mutex.Lock()
- n := len(f.lines)
- f.mutex.Unlock()
- return n
-}
-
-// AddLine adds the line offset for a new line.
-// The line offset must be larger than the offset for the previous line
-// and smaller than the file size; otherwise the line offset is ignored.
-func (f *File) AddLine(offset int) {
- f.mutex.Lock()
- if i := len(f.lines); (i == 0 || f.lines[i-1] < offset) && offset < f.size {
- f.lines = append(f.lines, offset)
- }
- f.mutex.Unlock()
-}
-
-// MergeLine merges a line with the following line. It is akin to replacing
-// the newline character at the end of the line with a space (to not change the
-// remaining offsets). To obtain the line number, consult e.g. Position.Line.
-// MergeLine will panic if given an invalid line number.
-func (f *File) MergeLine(line int) {
- if line < 1 {
- panic(fmt.Sprintf("invalid line number %d (should be >= 1)", line))
- }
- f.mutex.Lock()
- defer f.mutex.Unlock()
- if line >= len(f.lines) {
- panic(fmt.Sprintf("invalid line number %d (should be < %d)", line, len(f.lines)))
- }
- // To merge the line numbered <line> with the line numbered <line+1>,
- // we need to remove the entry in lines corresponding to the line
- // numbered <line+1>. The entry in lines corresponding to the line
- // numbered <line+1> is located at index <line>, since indices in lines
- // are 0-based and line numbers are 1-based.
- copy(f.lines[line:], f.lines[line+1:])
- f.lines = f.lines[:len(f.lines)-1]
-}
-
-// SetLines sets the line offsets for a file and reports whether it succeeded.
-// The line offsets are the offsets of the first character of each line;
-// for instance for the content "ab\nc\n" the line offsets are {0, 3}.
-// An empty file has an empty line offset table.
-// Each line offset must be larger than the offset for the previous line
-// and smaller than the file size; otherwise SetLines fails and returns
-// false.
-// Callers must not mutate the provided slice after SetLines returns.
-func (f *File) SetLines(lines []int) bool {
- // verify validity of lines table
- size := f.size
- for i, offset := range lines {
- if i > 0 && offset <= lines[i-1] || size <= offset {
- return false
- }
- }
-
- // set lines table
- f.mutex.Lock()
- f.lines = lines
- f.mutex.Unlock()
- return true
-}
-
-// SetLinesForContent sets the line offsets for the given file content.
-// It ignores position-altering //line comments.
-func (f *File) SetLinesForContent(content []byte) {
- var lines []int
- line := 0
- for offset, b := range content {
- if line >= 0 {
- lines = append(lines, line)
- }
- line = -1
- if b == '\n' {
- line = offset + 1
- }
- }
-
- // set lines table
- f.mutex.Lock()
- f.lines = lines
- f.mutex.Unlock()
-}
-
-// LineStart returns the Pos value of the start of the specified line.
-// It ignores any alternative positions set using AddLineColumnInfo.
-// LineStart panics if the 1-based line number is invalid.
-func (f *File) LineStart(line int) Pos {
- if line < 1 {
- panic(fmt.Sprintf("invalid line number %d (should be >= 1)", line))
- }
- f.mutex.Lock()
- defer f.mutex.Unlock()
- if line > len(f.lines) {
- panic(fmt.Sprintf("invalid line number %d (should be < %d)", line, len(f.lines)))
- }
- return Pos(f.base + f.lines[line-1])
-}
-
-// A lineInfo object describes alternative file, line, and column
-// number information (such as provided via a //line directive)
-// for a given file offset.
-type lineInfo struct {
- // fields are exported to make them accessible to gob
- Offset int
- Filename string
- Line, Column int
-}
-
-// AddLineInfo is like AddLineColumnInfo with a column = 1 argument.
-// It is here for backward-compatibility for code prior to Go 1.11.
-func (f *File) AddLineInfo(offset int, filename string, line int) {
- f.AddLineColumnInfo(offset, filename, line, 1)
-}
-
-// AddLineColumnInfo adds alternative file, line, and column number
-// information for a given file offset. The offset must be larger
-// than the offset for the previously added alternative line info
-// and smaller than the file size; otherwise the information is
-// ignored.
-//
-// AddLineColumnInfo is typically used to register alternative position
-// information for line directives such as //line filename:line:column.
-func (f *File) AddLineColumnInfo(offset int, filename string, line, column int) {
- f.mutex.Lock()
- if i := len(f.infos); (i == 0 || f.infos[i-1].Offset < offset) && offset < f.size {
- f.infos = append(f.infos, lineInfo{offset, filename, line, column})
- }
- f.mutex.Unlock()
-}
-
-// Pos returns the Pos value for the given file offset;
-// the offset must be <= f.Size().
-// f.Pos(f.Offset(p)) == p.
-func (f *File) Pos(offset int) Pos {
- if offset > f.size {
- panic(fmt.Sprintf("invalid file offset %d (should be <= %d)", offset, f.size))
- }
- return Pos(f.base + offset)
-}
-
-// Offset returns the offset for the given file position p;
-// p must be a valid Pos value in that file.
-// f.Offset(f.Pos(offset)) == offset.
-func (f *File) Offset(p Pos) int {
- if int(p) < f.base || int(p) > f.base+f.size {
- panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d])", p, f.base, f.base+f.size))
- }
- return int(p) - f.base
-}
-
-// Line returns the line number for the given file position p;
-// p must be a Pos value in that file or NoPos.
-func (f *File) Line(p Pos) int {
- return f.Position(p).Line
-}
-
-func searchLineInfos(a []lineInfo, x int) int {
- return sort.Search(len(a), func(i int) bool { return a[i].Offset > x }) - 1
-}
-
-// unpack returns the filename and line and column number for a file offset.
-// If adjusted is set, unpack will return the filename and line information
-// possibly adjusted by //line comments; otherwise those comments are ignored.
-func (f *File) unpack(offset int, adjusted bool) (filename string, line, column int) {
- f.mutex.Lock()
- filename = f.name
- if i := searchInts(f.lines, offset); i >= 0 {
- line, column = i+1, offset-f.lines[i]+1
- }
- if adjusted && len(f.infos) > 0 {
- // few files have extra line infos
- if i := searchLineInfos(f.infos, offset); i >= 0 {
- alt := &f.infos[i]
- filename = alt.Filename
- if i := searchInts(f.lines, alt.Offset); i >= 0 {
- // i+1 is the line at which the alternative position was recorded
- d := line - (i + 1) // line distance from alternative position base
- line = alt.Line + d
- if alt.Column == 0 {
- // alternative column is unknown => relative column is unknown
- // (the current specification for line directives requires
- // this to apply until the next PosBase/line directive,
- // not just until the new newline)
- column = 0
- } else if d == 0 {
- // the alternative position base is on the current line
- // => column is relative to alternative column
- column = alt.Column + (offset - alt.Offset)
- }
- }
- }
- }
- // TODO(mvdan): move Unlock back under Lock with a defer statement once
- // https://go.dev/issue/38471 is fixed to remove the performance penalty.
- f.mutex.Unlock()
- return
-}
-
-func (f *File) position(p Pos, adjusted bool) (pos Position) {
- offset := int(p) - f.base
- pos.Offset = offset
- pos.Filename, pos.Line, pos.Column = f.unpack(offset, adjusted)
- return
-}
-
-// PositionFor returns the Position value for the given file position p.
-// If adjusted is set, the position may be adjusted by position-altering
-// //line comments; otherwise those comments are ignored.
-// p must be a Pos value in f or NoPos.
-func (f *File) PositionFor(p Pos, adjusted bool) (pos Position) {
- if p != NoPos {
- if int(p) < f.base || int(p) > f.base+f.size {
- panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d])", p, f.base, f.base+f.size))
- }
- pos = f.position(p, adjusted)
- }
- return
-}
-
-// Position returns the Position value for the given file position p.
-// Calling f.Position(p) is equivalent to calling f.PositionFor(p, true).
-func (f *File) Position(p Pos) (pos Position) {
- return f.PositionFor(p, true)
-}
-
-// -----------------------------------------------------------------------------
-// FileSet
-
-// A FileSet represents a set of source files.
-// Methods of file sets are synchronized; multiple goroutines
-// may invoke them concurrently.
-//
-// The byte offsets for each file in a file set are mapped into
-// distinct (integer) intervals, one interval [base, base+size]
-// per file. Base represents the first byte in the file, and size
-// is the corresponding file size. A Pos value is a value in such
-// an interval. By determining the interval a Pos value belongs
-// to, the file, its file base, and thus the byte offset (position)
-// the Pos value is representing can be computed.
-//
-// When adding a new file, a file base must be provided. That can
-// be any integer value that is past the end of any interval of any
-// file already in the file set. For convenience, FileSet.Base provides
-// such a value, which is simply the end of the Pos interval of the most
-// recently added file, plus one. Unless there is a need to extend an
-// interval later, using the FileSet.Base should be used as argument
-// for FileSet.AddFile.
-//
-// A File may be removed from a FileSet when it is no longer needed.
-// This may reduce memory usage in a long-running application.
-type FileSet struct {
- mutex sync.RWMutex // protects the file set
- base int // base offset for the next file
- files []*File // list of files in the order added to the set
- last atomic.Pointer[File] // cache of last file looked up
-}
-
-// NewFileSet creates a new file set.
-func NewFileSet() *FileSet {
- return &FileSet{
- base: 1, // 0 == NoPos
- }
-}
-
-// Base returns the minimum base offset that must be provided to
-// AddFile when adding the next file.
-func (s *FileSet) Base() int {
- s.mutex.RLock()
- b := s.base
- s.mutex.RUnlock()
- return b
-
-}
-
-// AddFile adds a new file with a given filename, base offset, and file size
-// to the file set s and returns the file. Multiple files may have the same
-// name. The base offset must not be smaller than the FileSet's Base(), and
-// size must not be negative. As a special case, if a negative base is provided,
-// the current value of the FileSet's Base() is used instead.
-//
-// Adding the file will set the file set's Base() value to base + size + 1
-// as the minimum base value for the next file. The following relationship
-// exists between a Pos value p for a given file offset offs:
-//
-// int(p) = base + offs
-//
-// with offs in the range [0, size] and thus p in the range [base, base+size].
-// For convenience, File.Pos may be used to create file-specific position
-// values from a file offset.
-func (s *FileSet) AddFile(filename string, base, size int) *File {
- // Allocate f outside the critical section.
- f := &File{name: filename, size: size, lines: []int{0}}
-
- s.mutex.Lock()
- defer s.mutex.Unlock()
- if base < 0 {
- base = s.base
- }
- if base < s.base {
- panic(fmt.Sprintf("invalid base %d (should be >= %d)", base, s.base))
- }
- f.base = base
- if size < 0 {
- panic(fmt.Sprintf("invalid size %d (should be >= 0)", size))
- }
- // base >= s.base && size >= 0
- base += size + 1 // +1 because EOF also has a position
- if base < 0 {
- panic("token.Pos offset overflow (> 2G of source code in file set)")
- }
- // add the file to the file set
- s.base = base
- s.files = append(s.files, f)
- s.last.Store(f)
- return f
-}
-
-// RemoveFile removes a file from the FileSet so that subsequent
-// queries for its Pos interval yield a negative result.
-// This reduces the memory usage of a long-lived FileSet that
-// encounters an unbounded stream of files.
-//
-// Removing a file that does not belong to the set has no effect.
-func (s *FileSet) RemoveFile(file *File) {
- s.last.CompareAndSwap(file, nil) // clear last file cache
-
- s.mutex.Lock()
- defer s.mutex.Unlock()
-
- if i := searchFiles(s.files, file.base); i >= 0 && s.files[i] == file {
- last := &s.files[len(s.files)-1]
- s.files = append(s.files[:i], s.files[i+1:]...)
- *last = nil // don't prolong lifetime when popping last element
- }
-}
-
-// Iterate calls f for the files in the file set in the order they were added
-// until f returns false.
-func (s *FileSet) Iterate(f func(*File) bool) {
- for i := 0; ; i++ {
- var file *File
- s.mutex.RLock()
- if i < len(s.files) {
- file = s.files[i]
- }
- s.mutex.RUnlock()
- if file == nil || !f(file) {
- break
- }
- }
-}
-
-func searchFiles(a []*File, x int) int {
- return sort.Search(len(a), func(i int) bool { return a[i].base > x }) - 1
-}
-
-func (s *FileSet) file(p Pos) *File {
- // common case: p is in last file.
- if f := s.last.Load(); f != nil && f.base <= int(p) && int(p) <= f.base+f.size {
- return f
- }
-
- s.mutex.RLock()
- defer s.mutex.RUnlock()
-
- // p is not in last file - search all files
- if i := searchFiles(s.files, int(p)); i >= 0 {
- f := s.files[i]
- // f.base <= int(p) by definition of searchFiles
- if int(p) <= f.base+f.size {
- // Update cache of last file. A race is ok,
- // but an exclusive lock causes heavy contention.
- s.last.Store(f)
- return f
- }
- }
- return nil
-}
-
-// File returns the file that contains the position p.
-// If no such file is found (for instance for p == NoPos),
-// the result is nil.
-func (s *FileSet) File(p Pos) (f *File) {
- if p != NoPos {
- f = s.file(p)
- }
- return
-}
-
-// PositionFor converts a Pos p in the fileset into a Position value.
-// If adjusted is set, the position may be adjusted by position-altering
-// //line comments; otherwise those comments are ignored.
-// p must be a Pos value in s or NoPos.
-func (s *FileSet) PositionFor(p Pos, adjusted bool) (pos Position) {
- if p != NoPos {
- if f := s.file(p); f != nil {
- return f.position(p, adjusted)
- }
- }
- return
-}
-
-// Position converts a Pos p in the fileset into a Position value.
-// Calling s.Position(p) is equivalent to calling s.PositionFor(p, true).
-func (s *FileSet) Position(p Pos) (pos Position) {
- return s.PositionFor(p, true)
-}
-
-// -----------------------------------------------------------------------------
-// Helper functions
-
-func searchInts(a []int, x int) int {
- // This function body is a manually inlined version of:
- //
- // return sort.Search(len(a), func(i int) bool { return a[i] > x }) - 1
- //
- // With better compiler optimizations, this may not be needed in the
- // future, but at the moment this change improves the go/printer
- // benchmark performance by ~30%. This has a direct impact on the
- // speed of gofmt and thus seems worthwhile (2011-04-29).
- // TODO(gri): Remove this when compilers have caught up.
- i, j := 0, len(a)
- for i < j {
- h := int(uint(i+j) >> 1) // avoid overflow when computing h
- // i ≤ h < j
- if a[h] <= x {
- i = h + 1
- } else {
- j = h
- }
- }
- return i - 1
-}
diff --git a/contrib/go/_std_1.20/src/go/token/ya.make b/contrib/go/_std_1.20/src/go/token/ya.make
deleted file mode 100644
index b2e712f56e..0000000000
--- a/contrib/go/_std_1.20/src/go/token/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- position.go
- serialize.go
- token.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/go/types/api.go b/contrib/go/_std_1.20/src/go/types/api.go
deleted file mode 100644
index eda41b366a..0000000000
--- a/contrib/go/_std_1.20/src/go/types/api.go
+++ /dev/null
@@ -1,492 +0,0 @@
-// Copyright 2012 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 types declares the data types and implements
-// the algorithms for type-checking of Go packages. Use
-// Config.Check to invoke the type checker for a package.
-// Alternatively, create a new type checker with NewChecker
-// and invoke it incrementally by calling Checker.Files.
-//
-// Type-checking consists of several interdependent phases:
-//
-// Name resolution maps each identifier (ast.Ident) in the program to the
-// language object (Object) it denotes.
-// Use Info.{Defs,Uses,Implicits} for the results of name resolution.
-//
-// Constant folding computes the exact constant value (constant.Value)
-// for every expression (ast.Expr) that is a compile-time constant.
-// Use Info.Types[expr].Value for the results of constant folding.
-//
-// Type inference computes the type (Type) of every expression (ast.Expr)
-// and checks for compliance with the language specification.
-// Use Info.Types[expr].Type for the results of type inference.
-//
-// For a tutorial, see https://golang.org/s/types-tutorial.
-package types
-
-import (
- "bytes"
- "fmt"
- "go/ast"
- "go/constant"
- "go/token"
- . "internal/types/errors"
-)
-
-// An Error describes a type-checking error; it implements the error interface.
-// A "soft" error is an error that still permits a valid interpretation of a
-// package (such as "unused variable"); "hard" errors may lead to unpredictable
-// behavior if ignored.
-type Error struct {
- Fset *token.FileSet // file set for interpretation of Pos
- Pos token.Pos // error position
- Msg string // error message
- Soft bool // if set, error is "soft"
-
- // go116code is a future API, unexported as the set of error codes is large
- // and likely to change significantly during experimentation. Tools wishing
- // to preview this feature may read go116code using reflection (see
- // errorcodes_test.go), but beware that there is no guarantee of future
- // compatibility.
- go116code Code
- go116start token.Pos
- go116end token.Pos
-}
-
-// Error returns an error string formatted as follows:
-// filename:line:column: message
-func (err Error) Error() string {
- return fmt.Sprintf("%s: %s", err.Fset.Position(err.Pos), err.Msg)
-}
-
-// An ArgumentError holds an error associated with an argument index.
-type ArgumentError struct {
- Index int
- Err error
-}
-
-func (e *ArgumentError) Error() string { return e.Err.Error() }
-func (e *ArgumentError) Unwrap() error { return e.Err }
-
-// An Importer resolves import paths to Packages.
-//
-// CAUTION: This interface does not support the import of locally
-// vendored packages. See https://golang.org/s/go15vendor.
-// If possible, external implementations should implement ImporterFrom.
-type Importer interface {
- // Import returns the imported package for the given import path.
- // The semantics is like for ImporterFrom.ImportFrom except that
- // dir and mode are ignored (since they are not present).
- Import(path string) (*Package, error)
-}
-
-// ImportMode is reserved for future use.
-type ImportMode int
-
-// An ImporterFrom resolves import paths to packages; it
-// supports vendoring per https://golang.org/s/go15vendor.
-// Use go/importer to obtain an ImporterFrom implementation.
-type ImporterFrom interface {
- // Importer is present for backward-compatibility. Calling
- // Import(path) is the same as calling ImportFrom(path, "", 0);
- // i.e., locally vendored packages may not be found.
- // The types package does not call Import if an ImporterFrom
- // is present.
- Importer
-
- // ImportFrom returns the imported package for the given import
- // path when imported by a package file located in dir.
- // If the import failed, besides returning an error, ImportFrom
- // is encouraged to cache and return a package anyway, if one
- // was created. This will reduce package inconsistencies and
- // follow-on type checker errors due to the missing package.
- // The mode value must be 0; it is reserved for future use.
- // Two calls to ImportFrom with the same path and dir must
- // return the same package.
- ImportFrom(path, dir string, mode ImportMode) (*Package, error)
-}
-
-// A Config specifies the configuration for type checking.
-// The zero value for Config is a ready-to-use default configuration.
-type Config struct {
- // Context is the context used for resolving global identifiers. If nil, the
- // type checker will initialize this field with a newly created context.
- Context *Context
-
- // GoVersion describes the accepted Go language version. The string
- // must follow the format "go%d.%d" (e.g. "go1.12") or it must be
- // empty; an empty string indicates the latest language version.
- // If the format is invalid, invoking the type checker will cause a
- // panic.
- GoVersion string
-
- // If IgnoreFuncBodies is set, function bodies are not
- // type-checked.
- IgnoreFuncBodies bool
-
- // If FakeImportC is set, `import "C"` (for packages requiring Cgo)
- // declares an empty "C" package and errors are omitted for qualified
- // identifiers referring to package C (which won't find an object).
- // This feature is intended for the standard library cmd/api tool.
- //
- // Caution: Effects may be unpredictable due to follow-on errors.
- // Do not use casually!
- FakeImportC bool
-
- // If go115UsesCgo is set, the type checker expects the
- // _cgo_gotypes.go file generated by running cmd/cgo to be
- // provided as a package source file. Qualified identifiers
- // referring to package C will be resolved to cgo-provided
- // declarations within _cgo_gotypes.go.
- //
- // It is an error to set both FakeImportC and go115UsesCgo.
- go115UsesCgo bool
-
- // If Error != nil, it is called with each error found
- // during type checking; err has dynamic type Error.
- // Secondary errors (for instance, to enumerate all types
- // involved in an invalid recursive type declaration) have
- // error strings that start with a '\t' character.
- // If Error == nil, type-checking stops with the first
- // error found.
- Error func(err error)
-
- // An importer is used to import packages referred to from
- // import declarations.
- // If the installed importer implements ImporterFrom, the type
- // checker calls ImportFrom instead of Import.
- // The type checker reports an error if an importer is needed
- // but none was installed.
- Importer Importer
-
- // If Sizes != nil, it provides the sizing functions for package unsafe.
- // Otherwise SizesFor("gc", "amd64") is used instead.
- Sizes Sizes
-
- // If DisableUnusedImportCheck is set, packages are not checked
- // for unused imports.
- DisableUnusedImportCheck bool
-
- // If oldComparableSemantics is set, ordinary (non-type parameter)
- // interfaces do not satisfy the comparable constraint.
- // TODO(gri) remove this flag for Go 1.21
- oldComparableSemantics bool
-}
-
-func srcimporter_setUsesCgo(conf *Config) {
- conf.go115UsesCgo = true
-}
-
-// Info holds result type information for a type-checked package.
-// Only the information for which a map is provided is collected.
-// If the package has type errors, the collected information may
-// be incomplete.
-type Info struct {
- // Types maps expressions to their types, and for constant
- // expressions, also their values. Invalid expressions are
- // omitted.
- //
- // For (possibly parenthesized) identifiers denoting built-in
- // functions, the recorded signatures are call-site specific:
- // if the call result is not a constant, the recorded type is
- // an argument-specific signature. Otherwise, the recorded type
- // is invalid.
- //
- // The Types map does not record the type of every identifier,
- // only those that appear where an arbitrary expression is
- // permitted. For instance, the identifier f in a selector
- // expression x.f is found only in the Selections map, the
- // identifier z in a variable declaration 'var z int' is found
- // only in the Defs map, and identifiers denoting packages in
- // qualified identifiers are collected in the Uses map.
- Types map[ast.Expr]TypeAndValue
-
- // Instances maps identifiers denoting generic types or functions to their
- // type arguments and instantiated type.
- //
- // For example, Instances will map the identifier for 'T' in the type
- // instantiation T[int, string] to the type arguments [int, string] and
- // resulting instantiated *Named type. Given a generic function
- // func F[A any](A), Instances will map the identifier for 'F' in the call
- // expression F(int(1)) to the inferred type arguments [int], and resulting
- // instantiated *Signature.
- //
- // Invariant: Instantiating Uses[id].Type() with Instances[id].TypeArgs
- // results in an equivalent of Instances[id].Type.
- Instances map[*ast.Ident]Instance
-
- // Defs maps identifiers to the objects they define (including
- // package names, dots "." of dot-imports, and blank "_" identifiers).
- // For identifiers that do not denote objects (e.g., the package name
- // in package clauses, or symbolic variables t in t := x.(type) of
- // type switch headers), the corresponding objects are nil.
- //
- // For an embedded field, Defs returns the field *Var it defines.
- //
- // Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos()
- Defs map[*ast.Ident]Object
-
- // Uses maps identifiers to the objects they denote.
- //
- // For an embedded field, Uses returns the *TypeName it denotes.
- //
- // Invariant: Uses[id].Pos() != id.Pos()
- Uses map[*ast.Ident]Object
-
- // Implicits maps nodes to their implicitly declared objects, if any.
- // The following node and object types may appear:
- //
- // node declared object
- //
- // *ast.ImportSpec *PkgName for imports without renames
- // *ast.CaseClause type-specific *Var for each type switch case clause (incl. default)
- // *ast.Field anonymous parameter *Var (incl. unnamed results)
- //
- Implicits map[ast.Node]Object
-
- // Selections maps selector expressions (excluding qualified identifiers)
- // to their corresponding selections.
- Selections map[*ast.SelectorExpr]*Selection
-
- // Scopes maps ast.Nodes to the scopes they define. Package scopes are not
- // associated with a specific node but with all files belonging to a package.
- // Thus, the package scope can be found in the type-checked Package object.
- // Scopes nest, with the Universe scope being the outermost scope, enclosing
- // the package scope, which contains (one or more) files scopes, which enclose
- // function scopes which in turn enclose statement and function literal scopes.
- // Note that even though package-level functions are declared in the package
- // scope, the function scopes are embedded in the file scope of the file
- // containing the function declaration.
- //
- // The following node types may appear in Scopes:
- //
- // *ast.File
- // *ast.FuncType
- // *ast.TypeSpec
- // *ast.BlockStmt
- // *ast.IfStmt
- // *ast.SwitchStmt
- // *ast.TypeSwitchStmt
- // *ast.CaseClause
- // *ast.CommClause
- // *ast.ForStmt
- // *ast.RangeStmt
- //
- Scopes map[ast.Node]*Scope
-
- // InitOrder is the list of package-level initializers in the order in which
- // they must be executed. Initializers referring to variables related by an
- // initialization dependency appear in topological order, the others appear
- // in source order. Variables without an initialization expression do not
- // appear in this list.
- InitOrder []*Initializer
-}
-
-// TypeOf returns the type of expression e, or nil if not found.
-// Precondition: the Types, Uses and Defs maps are populated.
-func (info *Info) TypeOf(e ast.Expr) Type {
- if t, ok := info.Types[e]; ok {
- return t.Type
- }
- if id, _ := e.(*ast.Ident); id != nil {
- if obj := info.ObjectOf(id); obj != nil {
- return obj.Type()
- }
- }
- return nil
-}
-
-// ObjectOf returns the object denoted by the specified id,
-// or nil if not found.
-//
-// If id is an embedded struct field, ObjectOf returns the field (*Var)
-// it defines, not the type (*TypeName) it uses.
-//
-// Precondition: the Uses and Defs maps are populated.
-func (info *Info) ObjectOf(id *ast.Ident) Object {
- if obj := info.Defs[id]; obj != nil {
- return obj
- }
- return info.Uses[id]
-}
-
-// TypeAndValue reports the type and value (for constants)
-// of the corresponding expression.
-type TypeAndValue struct {
- mode operandMode
- Type Type
- Value constant.Value
-}
-
-// IsVoid reports whether the corresponding expression
-// is a function call without results.
-func (tv TypeAndValue) IsVoid() bool {
- return tv.mode == novalue
-}
-
-// IsType reports whether the corresponding expression specifies a type.
-func (tv TypeAndValue) IsType() bool {
- return tv.mode == typexpr
-}
-
-// IsBuiltin reports whether the corresponding expression denotes
-// a (possibly parenthesized) built-in function.
-func (tv TypeAndValue) IsBuiltin() bool {
- return tv.mode == builtin
-}
-
-// IsValue reports whether the corresponding expression is a value.
-// Builtins are not considered values. Constant values have a non-
-// nil Value.
-func (tv TypeAndValue) IsValue() bool {
- switch tv.mode {
- case constant_, variable, mapindex, value, commaok, commaerr:
- return true
- }
- return false
-}
-
-// IsNil reports whether the corresponding expression denotes the
-// predeclared value nil.
-func (tv TypeAndValue) IsNil() bool {
- return tv.mode == value && tv.Type == Typ[UntypedNil]
-}
-
-// Addressable reports whether the corresponding expression
-// is addressable (https://golang.org/ref/spec#Address_operators).
-func (tv TypeAndValue) Addressable() bool {
- return tv.mode == variable
-}
-
-// Assignable reports whether the corresponding expression
-// is assignable to (provided a value of the right type).
-func (tv TypeAndValue) Assignable() bool {
- return tv.mode == variable || tv.mode == mapindex
-}
-
-// HasOk reports whether the corresponding expression may be
-// used on the rhs of a comma-ok assignment.
-func (tv TypeAndValue) HasOk() bool {
- return tv.mode == commaok || tv.mode == mapindex
-}
-
-// Instance reports the type arguments and instantiated type for type and
-// function instantiations. For type instantiations, Type will be of dynamic
-// type *Named. For function instantiations, Type will be of dynamic type
-// *Signature.
-type Instance struct {
- TypeArgs *TypeList
- Type Type
-}
-
-// An Initializer describes a package-level variable, or a list of variables in case
-// of a multi-valued initialization expression, and the corresponding initialization
-// expression.
-type Initializer struct {
- Lhs []*Var // var Lhs = Rhs
- Rhs ast.Expr
-}
-
-func (init *Initializer) String() string {
- var buf bytes.Buffer
- for i, lhs := range init.Lhs {
- if i > 0 {
- buf.WriteString(", ")
- }
- buf.WriteString(lhs.Name())
- }
- buf.WriteString(" = ")
- WriteExpr(&buf, init.Rhs)
- return buf.String()
-}
-
-// Check type-checks a package and returns the resulting package object and
-// the first error if any. Additionally, if info != nil, Check populates each
-// of the non-nil maps in the Info struct.
-//
-// The package is marked as complete if no errors occurred, otherwise it is
-// incomplete. See Config.Error for controlling behavior in the presence of
-// errors.
-//
-// The package is specified by a list of *ast.Files and corresponding
-// file set, and the package path the package is identified with.
-// The clean path must not be empty or dot (".").
-func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, info *Info) (*Package, error) {
- pkg := NewPackage(path, "")
- return pkg, NewChecker(conf, fset, pkg, info).Files(files)
-}
-
-// AssertableTo reports whether a value of type V can be asserted to have type T.
-//
-// The behavior of AssertableTo is unspecified in three cases:
-// - if T is Typ[Invalid]
-// - if V is a generalized interface; i.e., an interface that may only be used
-// as a type constraint in Go code
-// - if T is an uninstantiated generic type
-func AssertableTo(V *Interface, T Type) bool {
- // Checker.newAssertableTo suppresses errors for invalid types, so we need special
- // handling here.
- if T.Underlying() == Typ[Invalid] {
- return false
- }
- return (*Checker)(nil).newAssertableTo(V, T)
-}
-
-// AssignableTo reports whether a value of type V is assignable to a variable
-// of type T.
-//
-// The behavior of AssignableTo is unspecified if V or T is Typ[Invalid] or an
-// uninstantiated generic type.
-func AssignableTo(V, T Type) bool {
- x := operand{mode: value, typ: V}
- ok, _ := x.assignableTo(nil, T, nil) // check not needed for non-constant x
- return ok
-}
-
-// ConvertibleTo reports whether a value of type V is convertible to a value of
-// type T.
-//
-// The behavior of ConvertibleTo is unspecified if V or T is Typ[Invalid] or an
-// uninstantiated generic type.
-func ConvertibleTo(V, T Type) bool {
- x := operand{mode: value, typ: V}
- return x.convertibleTo(nil, T, nil) // check not needed for non-constant x
-}
-
-// Implements reports whether type V implements interface T.
-//
-// The behavior of Implements is unspecified if V is Typ[Invalid] or an uninstantiated
-// generic type.
-func Implements(V Type, T *Interface) bool {
- if T.Empty() {
- // All types (even Typ[Invalid]) implement the empty interface.
- return true
- }
- // Checker.implements suppresses errors for invalid types, so we need special
- // handling here.
- if V.Underlying() == Typ[Invalid] {
- return false
- }
- return (*Checker)(nil).implements(V, T, false, nil)
-}
-
-// Satisfies reports whether type V satisfies the constraint T.
-//
-// The behavior of Satisfies is unspecified if V is Typ[Invalid] or an uninstantiated
-// generic type.
-func Satisfies(V Type, T *Interface) bool {
- return (*Checker)(nil).implements(V, T, true, nil)
-}
-
-// Identical reports whether x and y are identical types.
-// Receivers of Signature types are ignored.
-func Identical(x, y Type) bool {
- return identical(x, y, true, nil)
-}
-
-// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored.
-// Receivers of Signature types are ignored.
-func IdenticalIgnoreTags(x, y Type) bool {
- return identical(x, y, false, nil)
-}
diff --git a/contrib/go/_std_1.20/src/go/types/array.go b/contrib/go/_std_1.20/src/go/types/array.go
deleted file mode 100644
index 5b28474bb3..0000000000
--- a/contrib/go/_std_1.20/src/go/types/array.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2011 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 types
-
-// An Array represents an array type.
-type Array struct {
- len int64
- elem Type
-}
-
-// NewArray returns a new array type for the given element type and length.
-// A negative length indicates an unknown length.
-func NewArray(elem Type, len int64) *Array { return &Array{len: len, elem: elem} }
-
-// Len returns the length of array a.
-// A negative result indicates an unknown length.
-func (a *Array) Len() int64 { return a.len }
-
-// Elem returns element type of array a.
-func (a *Array) Elem() Type { return a.elem }
-
-func (t *Array) Underlying() Type { return t }
-func (t *Array) String() string { return TypeString(t, nil) }
diff --git a/contrib/go/_std_1.20/src/go/types/assignments.go b/contrib/go/_std_1.20/src/go/types/assignments.go
deleted file mode 100644
index 4d5acb1052..0000000000
--- a/contrib/go/_std_1.20/src/go/types/assignments.go
+++ /dev/null
@@ -1,475 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements initialization and assignment checks.
-
-package types
-
-import (
- "fmt"
- "go/ast"
- "go/token"
- . "internal/types/errors"
- "strings"
-)
-
-// assignment reports whether x can be assigned to a variable of type T,
-// if necessary by attempting to convert untyped values to the appropriate
-// type. context describes the context in which the assignment takes place.
-// Use T == nil to indicate assignment to an untyped blank identifier.
-// x.mode is set to invalid if the assignment failed.
-func (check *Checker) assignment(x *operand, T Type, context string) {
- check.singleValue(x)
-
- switch x.mode {
- case invalid:
- return // error reported before
- case constant_, variable, mapindex, value, commaok, commaerr:
- // ok
- default:
- // we may get here because of other problems (issue #39634, crash 12)
- // TODO(gri) do we need a new "generic" error code here?
- check.errorf(x, IncompatibleAssign, "cannot assign %s to %s in %s", x, T, context)
- return
- }
-
- if isUntyped(x.typ) {
- target := T
- // spec: "If an untyped constant is assigned to a variable of interface
- // type or the blank identifier, the constant is first converted to type
- // bool, rune, int, float64, complex128 or string respectively, depending
- // on whether the value is a boolean, rune, integer, floating-point,
- // complex, or string constant."
- if T == nil || isNonTypeParamInterface(T) {
- if T == nil && x.typ == Typ[UntypedNil] {
- check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
- x.mode = invalid
- return
- }
- target = Default(x.typ)
- }
- newType, val, code := check.implicitTypeAndValue(x, target)
- if code != 0 {
- msg := check.sprintf("cannot use %s as %s value in %s", x, target, context)
- switch code {
- case TruncatedFloat:
- msg += " (truncated)"
- case NumericOverflow:
- msg += " (overflows)"
- default:
- code = IncompatibleAssign
- }
- check.error(x, code, msg)
- x.mode = invalid
- return
- }
- if val != nil {
- x.val = val
- check.updateExprVal(x.expr, val)
- }
- if newType != x.typ {
- x.typ = newType
- check.updateExprType(x.expr, newType, false)
- }
- }
-
- // A generic (non-instantiated) function value cannot be assigned to a variable.
- if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
- check.errorf(x, WrongTypeArgCount, "cannot use generic function %s without instantiation in %s", x, context)
- }
-
- // spec: "If a left-hand side is the blank identifier, any typed or
- // non-constant value except for the predeclared identifier nil may
- // be assigned to it."
- if T == nil {
- return
- }
-
- cause := ""
- if ok, code := x.assignableTo(check, T, &cause); !ok {
- if cause != "" {
- check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, cause)
- } else {
- check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
- }
- x.mode = invalid
- }
-}
-
-func (check *Checker) initConst(lhs *Const, x *operand) {
- if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
- if lhs.typ == nil {
- lhs.typ = Typ[Invalid]
- }
- return
- }
-
- // rhs must be a constant
- if x.mode != constant_ {
- check.errorf(x, InvalidConstInit, "%s is not constant", x)
- if lhs.typ == nil {
- lhs.typ = Typ[Invalid]
- }
- return
- }
- assert(isConstType(x.typ))
-
- // If the lhs doesn't have a type yet, use the type of x.
- if lhs.typ == nil {
- lhs.typ = x.typ
- }
-
- check.assignment(x, lhs.typ, "constant declaration")
- if x.mode == invalid {
- return
- }
-
- lhs.val = x.val
-}
-
-func (check *Checker) initVar(lhs *Var, x *operand, context string) Type {
- if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
- if lhs.typ == nil {
- lhs.typ = Typ[Invalid]
- }
- return nil
- }
-
- // If the lhs doesn't have a type yet, use the type of x.
- if lhs.typ == nil {
- typ := x.typ
- if isUntyped(typ) {
- // convert untyped types to default types
- if typ == Typ[UntypedNil] {
- check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
- lhs.typ = Typ[Invalid]
- return nil
- }
- typ = Default(typ)
- }
- lhs.typ = typ
- }
-
- check.assignment(x, lhs.typ, context)
- if x.mode == invalid {
- return nil
- }
-
- return x.typ
-}
-
-func (check *Checker) assignVar(lhs ast.Expr, x *operand) Type {
- if x.mode == invalid || x.typ == Typ[Invalid] {
- check.useLHS(lhs)
- return nil
- }
-
- // Determine if the lhs is a (possibly parenthesized) identifier.
- ident, _ := unparen(lhs).(*ast.Ident)
-
- // Don't evaluate lhs if it is the blank identifier.
- if ident != nil && ident.Name == "_" {
- check.recordDef(ident, nil)
- check.assignment(x, nil, "assignment to _ identifier")
- if x.mode == invalid {
- return nil
- }
- return x.typ
- }
-
- // If the lhs is an identifier denoting a variable v, this assignment
- // is not a 'use' of v. Remember current value of v.used and restore
- // after evaluating the lhs via check.expr.
- var v *Var
- var v_used bool
- if ident != nil {
- if obj := check.lookup(ident.Name); obj != nil {
- // It's ok to mark non-local variables, but ignore variables
- // from other packages to avoid potential race conditions with
- // dot-imported variables.
- if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
- v = w
- v_used = v.used
- }
- }
- }
-
- var z operand
- check.expr(&z, lhs)
- if v != nil {
- v.used = v_used // restore v.used
- }
-
- if z.mode == invalid || z.typ == Typ[Invalid] {
- return nil
- }
-
- // spec: "Each left-hand side operand must be addressable, a map index
- // expression, or the blank identifier. Operands may be parenthesized."
- switch z.mode {
- case invalid:
- return nil
- case variable, mapindex:
- // ok
- default:
- if sel, ok := z.expr.(*ast.SelectorExpr); ok {
- var op operand
- check.expr(&op, sel.X)
- if op.mode == mapindex {
- check.errorf(&z, UnaddressableFieldAssign, "cannot assign to struct field %s in map", ExprString(z.expr))
- return nil
- }
- }
- check.errorf(&z, UnassignableOperand, "cannot assign to %s", &z)
- return nil
- }
-
- check.assignment(x, z.typ, "assignment")
- if x.mode == invalid {
- return nil
- }
-
- return x.typ
-}
-
-// operandTypes returns the list of types for the given operands.
-func operandTypes(list []*operand) (res []Type) {
- for _, x := range list {
- res = append(res, x.typ)
- }
- return res
-}
-
-// varTypes returns the list of types for the given variables.
-func varTypes(list []*Var) (res []Type) {
- for _, x := range list {
- res = append(res, x.typ)
- }
- return res
-}
-
-// typesSummary returns a string of the form "(t1, t2, ...)" where the
-// ti's are user-friendly string representations for the given types.
-// If variadic is set and the last type is a slice, its string is of
-// the form "...E" where E is the slice's element type.
-func (check *Checker) typesSummary(list []Type, variadic bool) string {
- var res []string
- for i, t := range list {
- var s string
- switch {
- case t == nil:
- fallthrough // should not happen but be cautious
- case t == Typ[Invalid]:
- s = "<T>"
- case isUntyped(t):
- if isNumeric(t) {
- // Do not imply a specific type requirement:
- // "have number, want float64" is better than
- // "have untyped int, want float64" or
- // "have int, want float64".
- s = "number"
- } else {
- // If we don't have a number, omit the "untyped" qualifier
- // for compactness.
- s = strings.Replace(t.(*Basic).name, "untyped ", "", -1)
- }
- case variadic && i == len(list)-1:
- s = check.sprintf("...%s", t.(*Slice).elem)
- }
- if s == "" {
- s = check.sprintf("%s", t)
- }
- res = append(res, s)
- }
- return "(" + strings.Join(res, ", ") + ")"
-}
-
-func measure(x int, unit string) string {
- if x != 1 {
- unit += "s"
- }
- return fmt.Sprintf("%d %s", x, unit)
-}
-
-func (check *Checker) assignError(rhs []ast.Expr, nvars, nvals int) {
- vars := measure(nvars, "variable")
- vals := measure(nvals, "value")
- rhs0 := rhs[0]
-
- if len(rhs) == 1 {
- if call, _ := unparen(rhs0).(*ast.CallExpr); call != nil {
- check.errorf(rhs0, WrongAssignCount, "assignment mismatch: %s but %s returns %s", vars, call.Fun, vals)
- return
- }
- }
- check.errorf(rhs0, WrongAssignCount, "assignment mismatch: %s but %s", vars, vals)
-}
-
-// If returnStmt != nil, initVars is called to type-check the assignment
-// of return expressions, and returnStmt is the return statement.
-func (check *Checker) initVars(lhs []*Var, origRHS []ast.Expr, returnStmt ast.Stmt) {
- rhs, commaOk := check.exprList(origRHS, len(lhs) == 2 && returnStmt == nil)
-
- if len(lhs) != len(rhs) {
- // invalidate lhs
- for _, obj := range lhs {
- obj.used = true // avoid declared and not used errors
- if obj.typ == nil {
- obj.typ = Typ[Invalid]
- }
- }
- // don't report an error if we already reported one
- for _, x := range rhs {
- if x.mode == invalid {
- return
- }
- }
- if returnStmt != nil {
- var at positioner = returnStmt
- qualifier := "not enough"
- if len(rhs) > len(lhs) {
- at = rhs[len(lhs)].expr // report at first extra value
- qualifier = "too many"
- } else if len(rhs) > 0 {
- at = rhs[len(rhs)-1].expr // report at last value
- }
- err := newErrorf(at, WrongResultCount, "%s return values", qualifier)
- err.errorf(token.NoPos, "have %s", check.typesSummary(operandTypes(rhs), false))
- err.errorf(token.NoPos, "want %s", check.typesSummary(varTypes(lhs), false))
- check.report(err)
- return
- }
- check.assignError(origRHS, len(lhs), len(rhs))
- return
- }
-
- context := "assignment"
- if returnStmt != nil {
- context = "return statement"
- }
-
- if commaOk {
- var a [2]Type
- for i := range a {
- a[i] = check.initVar(lhs[i], rhs[i], context)
- }
- check.recordCommaOkTypes(origRHS[0], a)
- return
- }
-
- for i, lhs := range lhs {
- check.initVar(lhs, rhs[i], context)
- }
-}
-
-func (check *Checker) assignVars(lhs, origRHS []ast.Expr) {
- rhs, commaOk := check.exprList(origRHS, len(lhs) == 2)
-
- if len(lhs) != len(rhs) {
- check.useLHS(lhs...)
- // don't report an error if we already reported one
- for _, x := range rhs {
- if x.mode == invalid {
- return
- }
- }
- check.assignError(origRHS, len(lhs), len(rhs))
- return
- }
-
- if commaOk {
- var a [2]Type
- for i := range a {
- a[i] = check.assignVar(lhs[i], rhs[i])
- }
- check.recordCommaOkTypes(origRHS[0], a)
- return
- }
-
- for i, lhs := range lhs {
- check.assignVar(lhs, rhs[i])
- }
-}
-
-func (check *Checker) shortVarDecl(pos positioner, lhs, rhs []ast.Expr) {
- top := len(check.delayed)
- scope := check.scope
-
- // collect lhs variables
- seen := make(map[string]bool, len(lhs))
- lhsVars := make([]*Var, len(lhs))
- newVars := make([]*Var, 0, len(lhs))
- hasErr := false
- for i, lhs := range lhs {
- ident, _ := lhs.(*ast.Ident)
- if ident == nil {
- check.useLHS(lhs)
- // TODO(rFindley) this is redundant with a parser error. Consider omitting?
- check.errorf(lhs, BadDecl, "non-name %s on left side of :=", lhs)
- hasErr = true
- continue
- }
-
- name := ident.Name
- if name != "_" {
- if seen[name] {
- check.errorf(lhs, RepeatedDecl, "%s repeated on left side of :=", lhs)
- hasErr = true
- continue
- }
- seen[name] = true
- }
-
- // Use the correct obj if the ident is redeclared. The
- // variable's scope starts after the declaration; so we
- // must use Scope.Lookup here and call Scope.Insert
- // (via check.declare) later.
- if alt := scope.Lookup(name); alt != nil {
- check.recordUse(ident, alt)
- // redeclared object must be a variable
- if obj, _ := alt.(*Var); obj != nil {
- lhsVars[i] = obj
- } else {
- check.errorf(lhs, UnassignableOperand, "cannot assign to %s", lhs)
- hasErr = true
- }
- continue
- }
-
- // declare new variable
- obj := NewVar(ident.Pos(), check.pkg, name, nil)
- lhsVars[i] = obj
- if name != "_" {
- newVars = append(newVars, obj)
- }
- check.recordDef(ident, obj)
- }
-
- // create dummy variables where the lhs is invalid
- for i, obj := range lhsVars {
- if obj == nil {
- lhsVars[i] = NewVar(lhs[i].Pos(), check.pkg, "_", nil)
- }
- }
-
- check.initVars(lhsVars, rhs, nil)
-
- // process function literals in rhs expressions before scope changes
- check.processDelayed(top)
-
- if len(newVars) == 0 && !hasErr {
- check.softErrorf(pos, NoNewVar, "no new variables on left side of :=")
- return
- }
-
- // declare new variables
- // spec: "The scope of a constant or variable identifier declared inside
- // a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
- // for short variable declarations) and ends at the end of the innermost
- // containing block."
- scopePos := rhs[len(rhs)-1].End()
- for _, obj := range newVars {
- check.declare(scope, nil, obj, scopePos) // id = nil: recordDef already called
- }
-}
diff --git a/contrib/go/_std_1.20/src/go/types/basic.go b/contrib/go/_std_1.20/src/go/types/basic.go
deleted file mode 100644
index 215923f657..0000000000
--- a/contrib/go/_std_1.20/src/go/types/basic.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2011 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 types
-
-// BasicKind describes the kind of basic type.
-type BasicKind int
-
-const (
- Invalid BasicKind = iota // type is invalid
-
- // predeclared types
- Bool
- Int
- Int8
- Int16
- Int32
- Int64
- Uint
- Uint8
- Uint16
- Uint32
- Uint64
- Uintptr
- Float32
- Float64
- Complex64
- Complex128
- String
- UnsafePointer
-
- // types for untyped values
- UntypedBool
- UntypedInt
- UntypedRune
- UntypedFloat
- UntypedComplex
- UntypedString
- UntypedNil
-
- // aliases
- Byte = Uint8
- Rune = Int32
-)
-
-// BasicInfo is a set of flags describing properties of a basic type.
-type BasicInfo int
-
-// Properties of basic types.
-const (
- IsBoolean BasicInfo = 1 << iota
- IsInteger
- IsUnsigned
- IsFloat
- IsComplex
- IsString
- IsUntyped
-
- IsOrdered = IsInteger | IsFloat | IsString
- IsNumeric = IsInteger | IsFloat | IsComplex
- IsConstType = IsBoolean | IsNumeric | IsString
-)
-
-// A Basic represents a basic type.
-type Basic struct {
- kind BasicKind
- info BasicInfo
- name string
-}
-
-// Kind returns the kind of basic type b.
-func (b *Basic) Kind() BasicKind { return b.kind }
-
-// Info returns information about properties of basic type b.
-func (b *Basic) Info() BasicInfo { return b.info }
-
-// Name returns the name of basic type b.
-func (b *Basic) Name() string { return b.name }
-
-func (t *Basic) Underlying() Type { return t }
-func (t *Basic) String() string { return TypeString(t, nil) }
diff --git a/contrib/go/_std_1.20/src/go/types/builtins.go b/contrib/go/_std_1.20/src/go/types/builtins.go
deleted file mode 100644
index d3bca606b2..0000000000
--- a/contrib/go/_std_1.20/src/go/types/builtins.go
+++ /dev/null
@@ -1,1017 +0,0 @@
-// Copyright 2012 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.
-
-// This file implements typechecking of builtin function calls.
-
-package types
-
-import (
- "go/ast"
- "go/constant"
- "go/token"
- . "internal/types/errors"
-)
-
-// builtin type-checks a call to the built-in specified by id and
-// reports whether the call is valid, with *x holding the result;
-// but x.expr is not set. If the call is invalid, the result is
-// false, and *x is undefined.
-func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) {
- // append is the only built-in that permits the use of ... for the last argument
- bin := predeclaredFuncs[id]
- if call.Ellipsis.IsValid() && id != _Append {
- check.errorf(atPos(call.Ellipsis),
- InvalidDotDotDot,
- invalidOp+"invalid use of ... with built-in %s", bin.name)
- check.use(call.Args...)
- return
- }
-
- // For len(x) and cap(x) we need to know if x contains any function calls or
- // receive operations. Save/restore current setting and set hasCallOrRecv to
- // false for the evaluation of x so that we can check it afterwards.
- // Note: We must do this _before_ calling exprList because exprList evaluates
- // all arguments.
- if id == _Len || id == _Cap {
- defer func(b bool) {
- check.hasCallOrRecv = b
- }(check.hasCallOrRecv)
- check.hasCallOrRecv = false
- }
-
- // determine actual arguments
- var arg func(*operand, int) // TODO(gri) remove use of arg getter in favor of using xlist directly
- nargs := len(call.Args)
- switch id {
- default:
- // make argument getter
- xlist, _ := check.exprList(call.Args, false)
- arg = func(x *operand, i int) { *x = *xlist[i] }
- nargs = len(xlist)
- // evaluate first argument, if present
- if nargs > 0 {
- arg(x, 0)
- if x.mode == invalid {
- return
- }
- }
- case _Make, _New, _Offsetof, _Trace:
- // arguments require special handling
- }
-
- // check argument count
- {
- msg := ""
- if nargs < bin.nargs {
- msg = "not enough"
- } else if !bin.variadic && nargs > bin.nargs {
- msg = "too many"
- }
- if msg != "" {
- check.errorf(inNode(call, call.Rparen), WrongArgCount, invalidOp+"%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs)
- return
- }
- }
-
- switch id {
- case _Append:
- // append(s S, x ...T) S, where T is the element type of S
- // spec: "The variadic function append appends zero or more values x to s of type
- // S, which must be a slice type, and returns the resulting slice, also of type S.
- // The values x are passed to a parameter of type ...T where T is the element type
- // of S and the respective parameter passing rules apply."
- S := x.typ
- var T Type
- if s, _ := coreType(S).(*Slice); s != nil {
- T = s.elem
- } else {
- var cause string
- switch {
- case x.isNil():
- cause = "have untyped nil"
- case isTypeParam(S):
- if u := coreType(S); u != nil {
- cause = check.sprintf("%s has core type %s", x, u)
- } else {
- cause = check.sprintf("%s has no core type", x)
- }
- default:
- cause = check.sprintf("have %s", x)
- }
- // don't use Checker.invalidArg here as it would repeat "argument" in the error message
- check.errorf(x, InvalidAppend, "first argument to append must be a slice; %s", cause)
- return
- }
-
- // remember arguments that have been evaluated already
- alist := []operand{*x}
-
- // spec: "As a special case, append also accepts a first argument assignable
- // to type []byte with a second argument of string type followed by ... .
- // This form appends the bytes of the string.
- if nargs == 2 && call.Ellipsis.IsValid() {
- if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
- arg(x, 1)
- if x.mode == invalid {
- return
- }
- if t := coreString(x.typ); t != nil && isString(t) {
- if check.Types != nil {
- sig := makeSig(S, S, x.typ)
- sig.variadic = true
- check.recordBuiltinType(call.Fun, sig)
- }
- x.mode = value
- x.typ = S
- break
- }
- alist = append(alist, *x)
- // fallthrough
- }
- }
-
- // check general case by creating custom signature
- sig := makeSig(S, S, NewSlice(T)) // []T required for variadic signature
- sig.variadic = true
- var xlist []*operand
- // convert []operand to []*operand
- for i := range alist {
- xlist = append(xlist, &alist[i])
- }
- for i := len(alist); i < nargs; i++ {
- var x operand
- arg(&x, i)
- xlist = append(xlist, &x)
- }
- check.arguments(call, sig, nil, xlist, nil) // discard result (we know the result type)
- // ok to continue even if check.arguments reported errors
-
- x.mode = value
- x.typ = S
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, sig)
- }
-
- case _Cap, _Len:
- // cap(x)
- // len(x)
- mode := invalid
- var val constant.Value
- switch t := arrayPtrDeref(under(x.typ)).(type) {
- case *Basic:
- if isString(t) && id == _Len {
- if x.mode == constant_ {
- mode = constant_
- val = constant.MakeInt64(int64(len(constant.StringVal(x.val))))
- } else {
- mode = value
- }
- }
-
- case *Array:
- mode = value
- // spec: "The expressions len(s) and cap(s) are constants
- // if the type of s is an array or pointer to an array and
- // the expression s does not contain channel receives or
- // function calls; in this case s is not evaluated."
- if !check.hasCallOrRecv {
- mode = constant_
- if t.len >= 0 {
- val = constant.MakeInt64(t.len)
- } else {
- val = constant.MakeUnknown()
- }
- }
-
- case *Slice, *Chan:
- mode = value
-
- case *Map:
- if id == _Len {
- mode = value
- }
-
- case *Interface:
- if !isTypeParam(x.typ) {
- break
- }
- if t.typeSet().underIs(func(t Type) bool {
- switch t := arrayPtrDeref(t).(type) {
- case *Basic:
- if isString(t) && id == _Len {
- return true
- }
- case *Array, *Slice, *Chan:
- return true
- case *Map:
- if id == _Len {
- return true
- }
- }
- return false
- }) {
- mode = value
- }
- }
-
- if mode == invalid && under(x.typ) != Typ[Invalid] {
- code := InvalidCap
- if id == _Len {
- code = InvalidLen
- }
- check.errorf(x, code, invalidArg+"%s for %s", x, bin.name)
- return
- }
-
- // record the signature before changing x.typ
- if check.Types != nil && mode != constant_ {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ))
- }
-
- x.mode = mode
- x.typ = Typ[Int]
- x.val = val
-
- case _Clear:
- // clear(m)
- if !check.allowVersion(check.pkg, 1, 21) {
- check.error(call.Fun, UnsupportedFeature, "clear requires go1.21 or later")
- return
- }
-
- if !underIs(x.typ, func(u Type) bool {
- switch u := u.(type) {
- case *Map, *Slice:
- return true
- case *Pointer:
- if _, ok := under(u.base).(*Array); ok {
- return true
- }
- }
- check.errorf(x, InvalidClear, invalidArg+"cannot clear %s: argument must be (or constrained by) map, slice, or array pointer", x)
- return false
- }) {
- return
- }
-
- x.mode = novalue
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
- }
-
- case _Close:
- // close(c)
- if !underIs(x.typ, func(u Type) bool {
- uch, _ := u.(*Chan)
- if uch == nil {
- check.errorf(x, InvalidClose, invalidOp+"cannot close non-channel %s", x)
- return false
- }
- if uch.dir == RecvOnly {
- check.errorf(x, InvalidClose, invalidOp+"cannot close receive-only channel %s", x)
- return false
- }
- return true
- }) {
- return
- }
- x.mode = novalue
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
- }
-
- case _Complex:
- // complex(x, y floatT) complexT
- var y operand
- arg(&y, 1)
- if y.mode == invalid {
- return
- }
-
- // convert or check untyped arguments
- d := 0
- if isUntyped(x.typ) {
- d |= 1
- }
- if isUntyped(y.typ) {
- d |= 2
- }
- switch d {
- case 0:
- // x and y are typed => nothing to do
- case 1:
- // only x is untyped => convert to type of y
- check.convertUntyped(x, y.typ)
- case 2:
- // only y is untyped => convert to type of x
- check.convertUntyped(&y, x.typ)
- case 3:
- // x and y are untyped =>
- // 1) if both are constants, convert them to untyped
- // floating-point numbers if possible,
- // 2) if one of them is not constant (possible because
- // it contains a shift that is yet untyped), convert
- // both of them to float64 since they must have the
- // same type to succeed (this will result in an error
- // because shifts of floats are not permitted)
- if x.mode == constant_ && y.mode == constant_ {
- toFloat := func(x *operand) {
- if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
- x.typ = Typ[UntypedFloat]
- }
- }
- toFloat(x)
- toFloat(&y)
- } else {
- check.convertUntyped(x, Typ[Float64])
- check.convertUntyped(&y, Typ[Float64])
- // x and y should be invalid now, but be conservative
- // and check below
- }
- }
- if x.mode == invalid || y.mode == invalid {
- return
- }
-
- // both argument types must be identical
- if !Identical(x.typ, y.typ) {
- check.errorf(x, InvalidComplex, invalidArg+"mismatched types %s and %s", x.typ, y.typ)
- return
- }
-
- // the argument types must be of floating-point type
- // (applyTypeFunc never calls f with a type parameter)
- f := func(typ Type) Type {
- assert(!isTypeParam(typ))
- if t, _ := under(typ).(*Basic); t != nil {
- switch t.kind {
- case Float32:
- return Typ[Complex64]
- case Float64:
- return Typ[Complex128]
- case UntypedFloat:
- return Typ[UntypedComplex]
- }
- }
- return nil
- }
- resTyp := check.applyTypeFunc(f, x, id)
- if resTyp == nil {
- check.errorf(x, InvalidComplex, invalidArg+"arguments have type %s, expected floating-point", x.typ)
- return
- }
-
- // if both arguments are constants, the result is a constant
- if x.mode == constant_ && y.mode == constant_ {
- x.val = constant.BinaryOp(constant.ToFloat(x.val), token.ADD, constant.MakeImag(constant.ToFloat(y.val)))
- } else {
- x.mode = value
- }
-
- if check.Types != nil && x.mode != constant_ {
- check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
- }
-
- x.typ = resTyp
-
- case _Copy:
- // copy(x, y []T) int
- dst, _ := coreType(x.typ).(*Slice)
-
- var y operand
- arg(&y, 1)
- if y.mode == invalid {
- return
- }
- src0 := coreString(y.typ)
- if src0 != nil && isString(src0) {
- src0 = NewSlice(universeByte)
- }
- src, _ := src0.(*Slice)
-
- if dst == nil || src == nil {
- check.errorf(x, InvalidCopy, invalidArg+"copy expects slice arguments; found %s and %s", x, &y)
- return
- }
-
- if !Identical(dst.elem, src.elem) {
- check.errorf(x, InvalidCopy, "arguments to copy %s and %s have different element types %s and %s", x, &y, dst.elem, src.elem)
- return
- }
-
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
- }
- x.mode = value
- x.typ = Typ[Int]
-
- case _Delete:
- // delete(map_, key)
- // map_ must be a map type or a type parameter describing map types.
- // The key cannot be a type parameter for now.
- map_ := x.typ
- var key Type
- if !underIs(map_, func(u Type) bool {
- map_, _ := u.(*Map)
- if map_ == nil {
- check.errorf(x, InvalidDelete, invalidArg+"%s is not a map", x)
- return false
- }
- if key != nil && !Identical(map_.key, key) {
- check.errorf(x, InvalidDelete, invalidArg+"maps of %s must have identical key types", x)
- return false
- }
- key = map_.key
- return true
- }) {
- return
- }
-
- arg(x, 1) // k
- if x.mode == invalid {
- return
- }
-
- check.assignment(x, key, "argument to delete")
- if x.mode == invalid {
- return
- }
-
- x.mode = novalue
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(nil, map_, key))
- }
-
- case _Imag, _Real:
- // imag(complexT) floatT
- // real(complexT) floatT
-
- // convert or check untyped argument
- if isUntyped(x.typ) {
- if x.mode == constant_ {
- // an untyped constant number can always be considered
- // as a complex constant
- if isNumeric(x.typ) {
- x.typ = Typ[UntypedComplex]
- }
- } else {
- // an untyped non-constant argument may appear if
- // it contains a (yet untyped non-constant) shift
- // expression: convert it to complex128 which will
- // result in an error (shift of complex value)
- check.convertUntyped(x, Typ[Complex128])
- // x should be invalid now, but be conservative and check
- if x.mode == invalid {
- return
- }
- }
- }
-
- // the argument must be of complex type
- // (applyTypeFunc never calls f with a type parameter)
- f := func(typ Type) Type {
- assert(!isTypeParam(typ))
- if t, _ := under(typ).(*Basic); t != nil {
- switch t.kind {
- case Complex64:
- return Typ[Float32]
- case Complex128:
- return Typ[Float64]
- case UntypedComplex:
- return Typ[UntypedFloat]
- }
- }
- return nil
- }
- resTyp := check.applyTypeFunc(f, x, id)
- if resTyp == nil {
- code := InvalidImag
- if id == _Real {
- code = InvalidReal
- }
- check.errorf(x, code, invalidArg+"argument has type %s, expected complex type", x.typ)
- return
- }
-
- // if the argument is a constant, the result is a constant
- if x.mode == constant_ {
- if id == _Real {
- x.val = constant.Real(x.val)
- } else {
- x.val = constant.Imag(x.val)
- }
- } else {
- x.mode = value
- }
-
- if check.Types != nil && x.mode != constant_ {
- check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
- }
-
- x.typ = resTyp
-
- case _Make:
- // make(T, n)
- // make(T, n, m)
- // (no argument evaluated yet)
- arg0 := call.Args[0]
- T := check.varType(arg0)
- if T == Typ[Invalid] {
- return
- }
-
- var min int // minimum number of arguments
- switch coreType(T).(type) {
- case *Slice:
- min = 2
- case *Map, *Chan:
- min = 1
- case nil:
- check.errorf(arg0, InvalidMake, "cannot make %s: no core type", arg0)
- return
- default:
- check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
- return
- }
- if nargs < min || min+1 < nargs {
- check.errorf(call, WrongArgCount, invalidOp+"%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
- return
- }
-
- types := []Type{T}
- var sizes []int64 // constant integer arguments, if any
- for _, arg := range call.Args[1:] {
- typ, size := check.index(arg, -1) // ok to continue with typ == Typ[Invalid]
- types = append(types, typ)
- if size >= 0 {
- sizes = append(sizes, size)
- }
- }
- if len(sizes) == 2 && sizes[0] > sizes[1] {
- check.error(call.Args[1], SwappedMakeArgs, invalidArg+"length and capacity swapped")
- // safe to continue
- }
- x.mode = value
- x.typ = T
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
- }
-
- case _New:
- // new(T)
- // (no argument evaluated yet)
- T := check.varType(call.Args[0])
- if T == Typ[Invalid] {
- return
- }
-
- x.mode = value
- x.typ = &Pointer{base: T}
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
- }
-
- case _Panic:
- // panic(x)
- // record panic call if inside a function with result parameters
- // (for use in Checker.isTerminating)
- if check.sig != nil && check.sig.results.Len() > 0 {
- // function has result parameters
- p := check.isPanic
- if p == nil {
- // allocate lazily
- p = make(map[*ast.CallExpr]bool)
- check.isPanic = p
- }
- p[call] = true
- }
-
- check.assignment(x, &emptyInterface, "argument to panic")
- if x.mode == invalid {
- return
- }
-
- x.mode = novalue
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
- }
-
- case _Print, _Println:
- // print(x, y, ...)
- // println(x, y, ...)
- var params []Type
- if nargs > 0 {
- params = make([]Type, nargs)
- for i := 0; i < nargs; i++ {
- if i > 0 {
- arg(x, i) // first argument already evaluated
- }
- check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name)
- if x.mode == invalid {
- // TODO(gri) "use" all arguments?
- return
- }
- params[i] = x.typ
- }
- }
-
- x.mode = novalue
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(nil, params...))
- }
-
- case _Recover:
- // recover() interface{}
- x.mode = value
- x.typ = &emptyInterface
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(x.typ))
- }
-
- case _Add:
- // unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer
- if !check.allowVersion(check.pkg, 1, 17) {
- check.error(call.Fun, UnsupportedFeature, "unsafe.Add requires go1.17 or later")
- return
- }
-
- check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
- if x.mode == invalid {
- return
- }
-
- var y operand
- arg(&y, 1)
- if !check.isValidIndex(&y, InvalidUnsafeAdd, "length", true) {
- return
- }
-
- x.mode = value
- x.typ = Typ[UnsafePointer]
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(x.typ, x.typ, y.typ))
- }
-
- case _Alignof:
- // unsafe.Alignof(x T) uintptr
- check.assignment(x, nil, "argument to unsafe.Alignof")
- if x.mode == invalid {
- return
- }
-
- if hasVarSize(x.typ, nil) {
- x.mode = value
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
- }
- } else {
- x.mode = constant_
- x.val = constant.MakeInt64(check.conf.alignof(x.typ))
- // result is constant - no need to record signature
- }
- x.typ = Typ[Uintptr]
-
- case _Offsetof:
- // unsafe.Offsetof(x T) uintptr, where x must be a selector
- // (no argument evaluated yet)
- arg0 := call.Args[0]
- selx, _ := unparen(arg0).(*ast.SelectorExpr)
- if selx == nil {
- check.errorf(arg0, BadOffsetofSyntax, invalidArg+"%s is not a selector expression", arg0)
- check.use(arg0)
- return
- }
-
- check.expr(x, selx.X)
- if x.mode == invalid {
- return
- }
-
- base := derefStructPtr(x.typ)
- sel := selx.Sel.Name
- obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
- switch obj.(type) {
- case nil:
- check.errorf(x, MissingFieldOrMethod, invalidArg+"%s has no single field %s", base, sel)
- return
- case *Func:
- // TODO(gri) Using derefStructPtr may result in methods being found
- // that don't actually exist. An error either way, but the error
- // message is confusing. See: https://play.golang.org/p/al75v23kUy ,
- // but go/types reports: "invalid argument: x.m is a method value".
- check.errorf(arg0, InvalidOffsetof, invalidArg+"%s is a method value", arg0)
- return
- }
- if indirect {
- check.errorf(x, InvalidOffsetof, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
- return
- }
-
- // TODO(gri) Should we pass x.typ instead of base (and have indirect report if derefStructPtr indirected)?
- check.recordSelection(selx, FieldVal, base, obj, index, false)
-
- // record the selector expression (was bug - issue #47895)
- {
- mode := value
- if x.mode == variable || indirect {
- mode = variable
- }
- check.record(&operand{mode, selx, obj.Type(), nil, 0})
- }
-
- // The field offset is considered a variable even if the field is declared before
- // the part of the struct which is variable-sized. This makes both the rules
- // simpler and also permits (or at least doesn't prevent) a compiler from re-
- // arranging struct fields if it wanted to.
- if hasVarSize(base, nil) {
- x.mode = value
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], obj.Type()))
- }
- } else {
- x.mode = constant_
- x.val = constant.MakeInt64(check.conf.offsetof(base, index))
- // result is constant - no need to record signature
- }
- x.typ = Typ[Uintptr]
-
- case _Sizeof:
- // unsafe.Sizeof(x T) uintptr
- check.assignment(x, nil, "argument to unsafe.Sizeof")
- if x.mode == invalid {
- return
- }
-
- if hasVarSize(x.typ, nil) {
- x.mode = value
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
- }
- } else {
- x.mode = constant_
- x.val = constant.MakeInt64(check.conf.sizeof(x.typ))
- // result is constant - no need to record signature
- }
- x.typ = Typ[Uintptr]
-
- case _Slice:
- // unsafe.Slice(ptr *T, len IntegerType) []T
- if !check.allowVersion(check.pkg, 1, 17) {
- check.error(call.Fun, UnsupportedFeature, "unsafe.Slice requires go1.17 or later")
- return
- }
-
- ptr, _ := under(x.typ).(*Pointer) // TODO(gri) should this be coreType rather than under?
- if ptr == nil {
- check.errorf(x, InvalidUnsafeSlice, invalidArg+"%s is not a pointer", x)
- return
- }
-
- var y operand
- arg(&y, 1)
- if !check.isValidIndex(&y, InvalidUnsafeSlice, "length", false) {
- return
- }
-
- x.mode = value
- x.typ = NewSlice(ptr.base)
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(x.typ, ptr, y.typ))
- }
-
- case _SliceData:
- // unsafe.SliceData(slice []T) *T
- if !check.allowVersion(check.pkg, 1, 20) {
- check.error(call.Fun, UnsupportedFeature, "unsafe.SliceData requires go1.20 or later")
- return
- }
-
- slice, _ := under(x.typ).(*Slice) // TODO(gri) should this be coreType rather than under?
- if slice == nil {
- check.errorf(x, InvalidUnsafeSliceData, invalidArg+"%s is not a slice", x)
- return
- }
-
- x.mode = value
- x.typ = NewPointer(slice.elem)
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(x.typ, slice))
- }
-
- case _String:
- // unsafe.String(ptr *byte, len IntegerType) string
- if !check.allowVersion(check.pkg, 1, 20) {
- check.error(call.Fun, UnsupportedFeature, "unsafe.String requires go1.20 or later")
- return
- }
-
- check.assignment(x, NewPointer(universeByte), "argument to unsafe.String")
- if x.mode == invalid {
- return
- }
-
- var y operand
- arg(&y, 1)
- if !check.isValidIndex(&y, InvalidUnsafeString, "length", false) {
- return
- }
-
- x.mode = value
- x.typ = Typ[String]
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(x.typ, NewPointer(universeByte), y.typ))
- }
-
- case _StringData:
- // unsafe.StringData(str string) *byte
- if !check.allowVersion(check.pkg, 1, 20) {
- check.error(call.Fun, UnsupportedFeature, "unsafe.StringData requires go1.20 or later")
- return
- }
-
- check.assignment(x, Typ[String], "argument to unsafe.StringData")
- if x.mode == invalid {
- return
- }
-
- x.mode = value
- x.typ = NewPointer(universeByte)
- if check.Types != nil {
- check.recordBuiltinType(call.Fun, makeSig(x.typ, Typ[String]))
- }
-
- case _Assert:
- // assert(pred) causes a typechecker error if pred is false.
- // The result of assert is the value of pred if there is no error.
- // Note: assert is only available in self-test mode.
- if x.mode != constant_ || !isBoolean(x.typ) {
- check.errorf(x, Test, invalidArg+"%s is not a boolean constant", x)
- return
- }
- if x.val.Kind() != constant.Bool {
- check.errorf(x, Test, "internal error: value of %s should be a boolean constant", x)
- return
- }
- if !constant.BoolVal(x.val) {
- check.errorf(call, Test, "%v failed", call)
- // compile-time assertion failure - safe to continue
- }
- // result is constant - no need to record signature
-
- case _Trace:
- // trace(x, y, z, ...) dumps the positions, expressions, and
- // values of its arguments. The result of trace is the value
- // of the first argument.
- // Note: trace is only available in self-test mode.
- // (no argument evaluated yet)
- if nargs == 0 {
- check.dump("%v: trace() without arguments", call.Pos())
- x.mode = novalue
- break
- }
- var t operand
- x1 := x
- for _, arg := range call.Args {
- check.rawExpr(x1, arg, nil, false) // permit trace for types, e.g.: new(trace(T))
- check.dump("%v: %s", x1.Pos(), x1)
- x1 = &t // use incoming x only for first argument
- }
- // trace is only available in test mode - no need to record signature
-
- default:
- unreachable()
- }
-
- return true
-}
-
-// hasVarSize reports if the size of type t is variable due to type parameters
-// or if the type is infinitely-sized due to a cycle for which the type has not
-// yet been checked.
-func hasVarSize(t Type, seen map[*Named]bool) (varSized bool) {
- // Cycles are only possible through *Named types.
- // The seen map is used to detect cycles and track
- // the results of previously seen types.
- if named, _ := t.(*Named); named != nil {
- if v, ok := seen[named]; ok {
- return v
- }
- if seen == nil {
- seen = make(map[*Named]bool)
- }
- seen[named] = true // possibly cyclic until proven otherwise
- defer func() {
- seen[named] = varSized // record final determination for named
- }()
- }
-
- switch u := under(t).(type) {
- case *Array:
- return hasVarSize(u.elem, seen)
- case *Struct:
- for _, f := range u.fields {
- if hasVarSize(f.typ, seen) {
- return true
- }
- }
- case *Interface:
- return isTypeParam(t)
- case *Named, *Union:
- unreachable()
- }
- return false
-}
-
-// applyTypeFunc applies f to x. If x is a type parameter,
-// the result is a type parameter constrained by an new
-// interface bound. The type bounds for that interface
-// are computed by applying f to each of the type bounds
-// of x. If any of these applications of f return nil,
-// applyTypeFunc returns nil.
-// If x is not a type parameter, the result is f(x).
-func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId) Type {
- if tp, _ := x.typ.(*TypeParam); tp != nil {
- // Test if t satisfies the requirements for the argument
- // type and collect possible result types at the same time.
- var terms []*Term
- if !tp.is(func(t *term) bool {
- if t == nil {
- return false
- }
- if r := f(t.typ); r != nil {
- terms = append(terms, NewTerm(t.tilde, r))
- return true
- }
- return false
- }) {
- return nil
- }
-
- // We can type-check this fine but we're introducing a synthetic
- // type parameter for the result. It's not clear what the API
- // implications are here. Report an error for 1.18 (see #50912),
- // but continue type-checking.
- var code Code
- switch id {
- case _Real:
- code = InvalidReal
- case _Imag:
- code = InvalidImag
- case _Complex:
- code = InvalidComplex
- default:
- unreachable()
- }
- check.softErrorf(x, code, "%s not supported as argument to %s for go1.18 (see issue #50937)", x, predeclaredFuncs[id].name)
-
- // Construct a suitable new type parameter for the result type.
- // The type parameter is placed in the current package so export/import
- // works as expected.
- tpar := NewTypeName(token.NoPos, check.pkg, tp.obj.name, nil)
- ptyp := check.newTypeParam(tpar, NewInterfaceType(nil, []Type{NewUnion(terms)})) // assigns type to tpar as a side-effect
- ptyp.index = tp.index
-
- return ptyp
- }
-
- return f(x.typ)
-}
-
-// makeSig makes a signature for the given argument and result types.
-// Default types are used for untyped arguments, and res may be nil.
-func makeSig(res Type, args ...Type) *Signature {
- list := make([]*Var, len(args))
- for i, param := range args {
- list[i] = NewVar(token.NoPos, nil, "", Default(param))
- }
- params := NewTuple(list...)
- var result *Tuple
- if res != nil {
- assert(!isUntyped(res))
- result = NewTuple(NewVar(token.NoPos, nil, "", res))
- }
- return &Signature{params: params, results: result}
-}
-
-// arrayPtrDeref returns A if typ is of the form *A and A is an array;
-// otherwise it returns typ.
-func arrayPtrDeref(typ Type) Type {
- if p, ok := typ.(*Pointer); ok {
- if a, _ := under(p.base).(*Array); a != nil {
- return a
- }
- }
- return typ
-}
-
-// unparen returns e with any enclosing parentheses stripped.
-func unparen(e ast.Expr) ast.Expr {
- for {
- p, ok := e.(*ast.ParenExpr)
- if !ok {
- return e
- }
- e = p.X
- }
-}
diff --git a/contrib/go/_std_1.20/src/go/types/call.go b/contrib/go/_std_1.20/src/go/types/call.go
deleted file mode 100644
index db603b5260..0000000000
--- a/contrib/go/_std_1.20/src/go/types/call.go
+++ /dev/null
@@ -1,817 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements typechecking of call and selector expressions.
-
-package types
-
-import (
- "go/ast"
- "go/internal/typeparams"
- "go/token"
- . "internal/types/errors"
- "strings"
- "unicode"
-)
-
-// funcInst type-checks a function instantiation inst and returns the result in x.
-// The operand x must be the evaluation of inst.X and its type must be a signature.
-func (check *Checker) funcInst(x *operand, ix *typeparams.IndexExpr) {
- if !check.allowVersion(check.pkg, 1, 18) {
- check.softErrorf(inNode(ix.Orig, ix.Lbrack), UnsupportedFeature, "function instantiation requires go1.18 or later")
- }
-
- targs := check.typeList(ix.Indices)
- if targs == nil {
- x.mode = invalid
- x.expr = ix.Orig
- return
- }
- assert(len(targs) == len(ix.Indices))
-
- // check number of type arguments (got) vs number of type parameters (want)
- sig := x.typ.(*Signature)
- got, want := len(targs), sig.TypeParams().Len()
- if got > want {
- check.errorf(ix.Indices[got-1], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
- x.mode = invalid
- x.expr = ix.Orig
- return
- }
-
- if got < want {
- targs = check.infer(ix.Orig, sig.TypeParams().list(), targs, nil, nil)
- if targs == nil {
- // error was already reported
- x.mode = invalid
- x.expr = ix.Orig
- return
- }
- got = len(targs)
- }
- assert(got == want)
-
- // instantiate function signature
- sig = check.instantiateSignature(x.Pos(), sig, targs, ix.Indices)
- assert(sig.TypeParams().Len() == 0) // signature is not generic anymore
- check.recordInstance(ix.Orig, targs, sig)
- x.typ = sig
- x.mode = value
- x.expr = ix.Orig
-}
-
-func (check *Checker) instantiateSignature(pos token.Pos, typ *Signature, targs []Type, xlist []ast.Expr) (res *Signature) {
- assert(check != nil)
- assert(len(targs) == typ.TypeParams().Len())
-
- if trace {
- check.trace(pos, "-- instantiating signature %s with %s", typ, targs)
- check.indent++
- defer func() {
- check.indent--
- check.trace(pos, "=> %s (under = %s)", res, res.Underlying())
- }()
- }
-
- inst := check.instance(pos, typ, targs, nil, check.context()).(*Signature)
- assert(len(xlist) <= len(targs))
-
- // verify instantiation lazily (was issue #50450)
- check.later(func() {
- tparams := typ.TypeParams().list()
- if i, err := check.verify(pos, tparams, targs, check.context()); err != nil {
- // best position for error reporting
- pos := pos
- if i < len(xlist) {
- pos = xlist[i].Pos()
- }
- check.softErrorf(atPos(pos), InvalidTypeArg, "%s", err)
- } else {
- check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist)
- }
- }).describef(atPos(pos), "verify instantiation")
-
- return inst
-}
-
-func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
- ix := typeparams.UnpackIndexExpr(call.Fun)
- if ix != nil {
- if check.indexExpr(x, ix) {
- // Delay function instantiation to argument checking,
- // where we combine type and value arguments for type
- // inference.
- assert(x.mode == value)
- } else {
- ix = nil
- }
- x.expr = call.Fun
- check.record(x)
- } else {
- check.exprOrType(x, call.Fun, true)
- }
- // x.typ may be generic
-
- switch x.mode {
- case invalid:
- check.use(call.Args...)
- x.expr = call
- return statement
-
- case typexpr:
- // conversion
- check.nonGeneric(x)
- if x.mode == invalid {
- return conversion
- }
- T := x.typ
- x.mode = invalid
- switch n := len(call.Args); n {
- case 0:
- check.errorf(inNode(call, call.Rparen), WrongArgCount, "missing argument in conversion to %s", T)
- case 1:
- check.expr(x, call.Args[0])
- if x.mode != invalid {
- if call.Ellipsis.IsValid() {
- check.errorf(call.Args[0], BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
- break
- }
- if t, _ := under(T).(*Interface); t != nil && !isTypeParam(T) {
- if !t.IsMethodSet() {
- check.errorf(call, MisplacedConstraintIface, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
- break
- }
- }
- check.conversion(x, T)
- }
- default:
- check.use(call.Args...)
- check.errorf(call.Args[n-1], WrongArgCount, "too many arguments in conversion to %s", T)
- }
- x.expr = call
- return conversion
-
- case builtin:
- // no need to check for non-genericity here
- id := x.id
- if !check.builtin(x, call, id) {
- x.mode = invalid
- }
- x.expr = call
- // a non-constant result implies a function call
- if x.mode != invalid && x.mode != constant_ {
- check.hasCallOrRecv = true
- }
- return predeclaredFuncs[id].kind
- }
-
- // ordinary function/method call
- // signature may be generic
- cgocall := x.mode == cgofunc
-
- // a type parameter may be "called" if all types have the same signature
- sig, _ := coreType(x.typ).(*Signature)
- if sig == nil {
- check.errorf(x, InvalidCall, invalidOp+"cannot call non-function %s", x)
- x.mode = invalid
- x.expr = call
- return statement
- }
-
- // Capture wasGeneric before sig is potentially instantiated below.
- wasGeneric := sig.TypeParams().Len() > 0
-
- // evaluate type arguments, if any
- var xlist []ast.Expr
- var targs []Type
- if ix != nil {
- xlist = ix.Indices
- targs = check.typeList(xlist)
- if targs == nil {
- check.use(call.Args...)
- x.mode = invalid
- x.expr = call
- return statement
- }
- assert(len(targs) == len(xlist))
-
- // check number of type arguments (got) vs number of type parameters (want)
- got, want := len(targs), sig.TypeParams().Len()
- if got > want {
- check.errorf(xlist[want], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
- check.use(call.Args...)
- x.mode = invalid
- x.expr = call
- return statement
- }
-
- // If sig is generic and all type arguments are provided, preempt function
- // argument type inference by explicitly instantiating the signature. This
- // ensures that we record accurate type information for sig, even if there
- // is an error checking its arguments (for example, if an incorrect number
- // of arguments is supplied).
- if got == want && want > 0 {
- if !check.allowVersion(check.pkg, 1, 18) {
- check.softErrorf(inNode(call.Fun, ix.Lbrack), UnsupportedFeature, "function instantiation requires go1.18 or later")
- }
-
- sig = check.instantiateSignature(ix.Pos(), sig, targs, xlist)
- assert(sig.TypeParams().Len() == 0) // signature is not generic anymore
- check.recordInstance(ix.Orig, targs, sig)
-
- // targs have been consumed; proceed with checking arguments of the
- // non-generic signature.
- targs = nil
- xlist = nil
- }
- }
-
- // evaluate arguments
- args, _ := check.exprList(call.Args, false)
- sig = check.arguments(call, sig, targs, args, xlist)
-
- if wasGeneric && sig.TypeParams().Len() == 0 {
- // Update the recorded type of call.Fun to its instantiated type.
- check.recordTypeAndValue(call.Fun, value, sig, nil)
- }
-
- // determine result
- switch sig.results.Len() {
- case 0:
- x.mode = novalue
- case 1:
- if cgocall {
- x.mode = commaerr
- } else {
- x.mode = value
- }
- x.typ = sig.results.vars[0].typ // unpack tuple
- default:
- x.mode = value
- x.typ = sig.results
- }
- x.expr = call
- check.hasCallOrRecv = true
-
- // if type inference failed, a parametrized result must be invalidated
- // (operands cannot have a parametrized type)
- if x.mode == value && sig.TypeParams().Len() > 0 && isParameterized(sig.TypeParams().list(), x.typ) {
- x.mode = invalid
- }
-
- return statement
-}
-
-func (check *Checker) exprList(elist []ast.Expr, allowCommaOk bool) (xlist []*operand, commaOk bool) {
- switch len(elist) {
- case 0:
- // nothing to do
-
- case 1:
- // single (possibly comma-ok) value, or function returning multiple values
- e := elist[0]
- var x operand
- check.multiExpr(&x, e)
- if t, ok := x.typ.(*Tuple); ok && x.mode != invalid {
- // multiple values
- xlist = make([]*operand, t.Len())
- for i, v := range t.vars {
- xlist[i] = &operand{mode: value, expr: e, typ: v.typ}
- }
- break
- }
-
- // exactly one (possibly invalid or comma-ok) value
- xlist = []*operand{&x}
- if allowCommaOk && (x.mode == mapindex || x.mode == commaok || x.mode == commaerr) {
- x2 := &operand{mode: value, expr: e, typ: Typ[UntypedBool]}
- if x.mode == commaerr {
- x2.typ = universeError
- }
- xlist = append(xlist, x2)
- commaOk = true
- }
-
- default:
- // multiple (possibly invalid) values
- xlist = make([]*operand, len(elist))
- for i, e := range elist {
- var x operand
- check.expr(&x, e)
- xlist[i] = &x
- }
- }
-
- return
-}
-
-// xlist is the list of type argument expressions supplied in the source code.
-func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type, args []*operand, xlist []ast.Expr) (rsig *Signature) {
- rsig = sig
-
- // TODO(gri) try to eliminate this extra verification loop
- for _, a := range args {
- switch a.mode {
- case typexpr:
- check.errorf(a, NotAnExpr, "%s used as value", a)
- return
- case invalid:
- return
- }
- }
-
- // Function call argument/parameter count requirements
- //
- // | standard call | dotdotdot call |
- // --------------+------------------+----------------+
- // standard func | nargs == npars | invalid |
- // --------------+------------------+----------------+
- // variadic func | nargs >= npars-1 | nargs == npars |
- // --------------+------------------+----------------+
-
- nargs := len(args)
- npars := sig.params.Len()
- ddd := call.Ellipsis.IsValid()
-
- // set up parameters
- sigParams := sig.params // adjusted for variadic functions (may be nil for empty parameter lists!)
- adjusted := false // indicates if sigParams is different from t.params
- if sig.variadic {
- if ddd {
- // variadic_func(a, b, c...)
- if len(call.Args) == 1 && nargs > 1 {
- // f()... is not permitted if f() is multi-valued
- check.errorf(inNode(call, call.Ellipsis), InvalidDotDotDot, "cannot use ... with %d-valued %s", nargs, call.Args[0])
- return
- }
- } else {
- // variadic_func(a, b, c)
- if nargs >= npars-1 {
- // Create custom parameters for arguments: keep
- // the first npars-1 parameters and add one for
- // each argument mapping to the ... parameter.
- vars := make([]*Var, npars-1) // npars > 0 for variadic functions
- copy(vars, sig.params.vars)
- last := sig.params.vars[npars-1]
- typ := last.typ.(*Slice).elem
- for len(vars) < nargs {
- vars = append(vars, NewParam(last.pos, last.pkg, last.name, typ))
- }
- sigParams = NewTuple(vars...) // possibly nil!
- adjusted = true
- npars = nargs
- } else {
- // nargs < npars-1
- npars-- // for correct error message below
- }
- }
- } else {
- if ddd {
- // standard_func(a, b, c...)
- check.errorf(inNode(call, call.Ellipsis), NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
- return
- }
- // standard_func(a, b, c)
- }
-
- // check argument count
- if nargs != npars {
- var at positioner = call
- qualifier := "not enough"
- if nargs > npars {
- at = args[npars].expr // report at first extra argument
- qualifier = "too many"
- } else {
- at = atPos(call.Rparen) // report at closing )
- }
- // take care of empty parameter lists represented by nil tuples
- var params []*Var
- if sig.params != nil {
- params = sig.params.vars
- }
- err := newErrorf(at, WrongArgCount, "%s arguments in call to %s", qualifier, call.Fun)
- err.errorf(token.NoPos, "have %s", check.typesSummary(operandTypes(args), false))
- err.errorf(token.NoPos, "want %s", check.typesSummary(varTypes(params), sig.variadic))
- check.report(err)
- return
- }
-
- // infer type arguments and instantiate signature if necessary
- if sig.TypeParams().Len() > 0 {
- if !check.allowVersion(check.pkg, 1, 18) {
- switch call.Fun.(type) {
- case *ast.IndexExpr, *ast.IndexListExpr:
- ix := typeparams.UnpackIndexExpr(call.Fun)
- check.softErrorf(inNode(call.Fun, ix.Lbrack), UnsupportedFeature, "function instantiation requires go1.18 or later")
- default:
- check.softErrorf(inNode(call, call.Lparen), UnsupportedFeature, "implicit function instantiation requires go1.18 or later")
- }
- }
- targs := check.infer(call, sig.TypeParams().list(), targs, sigParams, args)
- if targs == nil {
- return // error already reported
- }
-
- // compute result signature
- rsig = check.instantiateSignature(call.Pos(), sig, targs, xlist)
- assert(rsig.TypeParams().Len() == 0) // signature is not generic anymore
- check.recordInstance(call.Fun, targs, rsig)
-
- // Optimization: Only if the parameter list was adjusted do we
- // need to compute it from the adjusted list; otherwise we can
- // simply use the result signature's parameter list.
- if adjusted {
- sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(sig.TypeParams().list(), targs), nil, check.context()).(*Tuple)
- } else {
- sigParams = rsig.params
- }
- }
-
- // check arguments
- if len(args) > 0 {
- context := check.sprintf("argument to %s", call.Fun)
- for i, a := range args {
- check.assignment(a, sigParams.vars[i].typ, context)
- }
- }
-
- return
-}
-
-var cgoPrefixes = [...]string{
- "_Ciconst_",
- "_Cfconst_",
- "_Csconst_",
- "_Ctype_",
- "_Cvar_", // actually a pointer to the var
- "_Cfpvar_fp_",
- "_Cfunc_",
- "_Cmacro_", // function to evaluate the expanded expression
-}
-
-func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *Named, wantType bool) {
- // these must be declared before the "goto Error" statements
- var (
- obj Object
- index []int
- indirect bool
- )
-
- sel := e.Sel.Name
- // If the identifier refers to a package, handle everything here
- // so we don't need a "package" mode for operands: package names
- // can only appear in qualified identifiers which are mapped to
- // selector expressions.
- if ident, ok := e.X.(*ast.Ident); ok {
- obj := check.lookup(ident.Name)
- if pname, _ := obj.(*PkgName); pname != nil {
- assert(pname.pkg == check.pkg)
- check.recordUse(ident, pname)
- pname.used = true
- pkg := pname.imported
-
- var exp Object
- funcMode := value
- if pkg.cgo {
- // cgo special cases C.malloc: it's
- // rewritten to _CMalloc and does not
- // support two-result calls.
- if sel == "malloc" {
- sel = "_CMalloc"
- } else {
- funcMode = cgofunc
- }
- for _, prefix := range cgoPrefixes {
- // cgo objects are part of the current package (in file
- // _cgo_gotypes.go). Use regular lookup.
- _, exp = check.scope.LookupParent(prefix+sel, check.pos)
- if exp != nil {
- break
- }
- }
- if exp == nil {
- check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", ast.Expr(e)) // cast to ast.Expr to silence vet
- goto Error
- }
- check.objDecl(exp, nil)
- } else {
- exp = pkg.scope.Lookup(sel)
- if exp == nil {
- if !pkg.fake {
- check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", ast.Expr(e))
- }
- goto Error
- }
- if !exp.Exported() {
- check.errorf(e.Sel, UnexportedName, "%s not exported by package %s", sel, pkg.name)
- // ok to continue
- }
- }
- check.recordUse(e.Sel, exp)
-
- // Simplified version of the code for *ast.Idents:
- // - imported objects are always fully initialized
- switch exp := exp.(type) {
- case *Const:
- assert(exp.Val() != nil)
- x.mode = constant_
- x.typ = exp.typ
- x.val = exp.val
- case *TypeName:
- x.mode = typexpr
- x.typ = exp.typ
- case *Var:
- x.mode = variable
- x.typ = exp.typ
- if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") {
- x.typ = x.typ.(*Pointer).base
- }
- case *Func:
- x.mode = funcMode
- x.typ = exp.typ
- if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") {
- x.mode = value
- x.typ = x.typ.(*Signature).results.vars[0].typ
- }
- case *Builtin:
- x.mode = builtin
- x.typ = exp.typ
- x.id = exp.id
- default:
- check.dump("%v: unexpected object %v", e.Sel.Pos(), exp)
- unreachable()
- }
- x.expr = e
- return
- }
- }
-
- check.exprOrType(x, e.X, false)
- switch x.mode {
- case typexpr:
- // don't crash for "type T T.x" (was issue #51509)
- if def != nil && x.typ == def {
- check.cycleError([]Object{def.obj})
- goto Error
- }
- case builtin:
- // types2 uses the position of '.' for the error
- check.errorf(e.Sel, UncalledBuiltin, "cannot select on %s", x)
- goto Error
- case invalid:
- goto Error
- }
-
- // Avoid crashing when checking an invalid selector in a method declaration
- // (i.e., where def is not set):
- //
- // type S[T any] struct{}
- // type V = S[any]
- // func (fs *S[T]) M(x V.M) {}
- //
- // All codepaths below return a non-type expression. If we get here while
- // expecting a type expression, it is an error.
- //
- // See issue #57522 for more details.
- //
- // TODO(rfindley): We should do better by refusing to check selectors in all cases where
- // x.typ is incomplete.
- if wantType {
- check.errorf(e.Sel, NotAType, "%s is not a type", ast.Expr(e))
- goto Error
- }
-
- obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
- if obj == nil {
- // Don't report another error if the underlying type was invalid (issue #49541).
- if under(x.typ) == Typ[Invalid] {
- goto Error
- }
-
- if index != nil {
- // TODO(gri) should provide actual type where the conflict happens
- check.errorf(e.Sel, AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel)
- goto Error
- }
-
- if indirect {
- if x.mode == typexpr {
- check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ, sel, x.typ, sel)
- } else {
- check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
- }
- goto Error
- }
-
- var why string
- if isInterfacePtr(x.typ) {
- why = check.interfacePtrError(x.typ)
- } else {
- why = check.sprintf("type %s has no field or method %s", x.typ, sel)
- // Check if capitalization of sel matters and provide better error message in that case.
- // TODO(gri) This code only looks at the first character but LookupFieldOrMethod should
- // have an (internal) mechanism for case-insensitive lookup that we should use
- // instead (see types2).
- if len(sel) > 0 {
- var changeCase string
- if r := rune(sel[0]); unicode.IsUpper(r) {
- changeCase = string(unicode.ToLower(r)) + sel[1:]
- } else {
- changeCase = string(unicode.ToUpper(r)) + sel[1:]
- }
- if obj, _, _ = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, changeCase); obj != nil {
- why += ", but does have " + changeCase
- }
- }
- }
- check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
- goto Error
- }
-
- // methods may not have a fully set up signature yet
- if m, _ := obj.(*Func); m != nil {
- check.objDecl(m, nil)
- }
-
- if x.mode == typexpr {
- // method expression
- m, _ := obj.(*Func)
- if m == nil {
- // TODO(gri) should check if capitalization of sel matters and provide better error message in that case
- check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
- goto Error
- }
-
- check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
-
- sig := m.typ.(*Signature)
- if sig.recv == nil {
- check.error(e, InvalidDeclCycle, "illegal cycle in method declaration")
- goto Error
- }
-
- // the receiver type becomes the type of the first function
- // argument of the method expression's function type
- var params []*Var
- if sig.params != nil {
- params = sig.params.vars
- }
- // Be consistent about named/unnamed parameters. This is not needed
- // for type-checking, but the newly constructed signature may appear
- // in an error message and then have mixed named/unnamed parameters.
- // (An alternative would be to not print parameter names in errors,
- // but it's useful to see them; this is cheap and method expressions
- // are rare.)
- name := ""
- if len(params) > 0 && params[0].name != "" {
- // name needed
- name = sig.recv.name
- if name == "" {
- name = "_"
- }
- }
- params = append([]*Var{NewVar(sig.recv.pos, sig.recv.pkg, name, x.typ)}, params...)
- x.mode = value
- x.typ = &Signature{
- tparams: sig.tparams,
- params: NewTuple(params...),
- results: sig.results,
- variadic: sig.variadic,
- }
-
- check.addDeclDep(m)
-
- } else {
- // regular selector
- switch obj := obj.(type) {
- case *Var:
- check.recordSelection(e, FieldVal, x.typ, obj, index, indirect)
- if x.mode == variable || indirect {
- x.mode = variable
- } else {
- x.mode = value
- }
- x.typ = obj.typ
-
- case *Func:
- // TODO(gri) If we needed to take into account the receiver's
- // addressability, should we report the type &(x.typ) instead?
- check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
-
- // TODO(gri) The verification pass below is disabled for now because
- // method sets don't match method lookup in some cases.
- // For instance, if we made a copy above when creating a
- // custom method for a parameterized received type, the
- // method set method doesn't match (no copy there). There
- /// may be other situations.
- disabled := true
- if !disabled && debug {
- // Verify that LookupFieldOrMethod and MethodSet.Lookup agree.
- // TODO(gri) This only works because we call LookupFieldOrMethod
- // _before_ calling NewMethodSet: LookupFieldOrMethod completes
- // any incomplete interfaces so they are available to NewMethodSet
- // (which assumes that interfaces have been completed already).
- typ := x.typ
- if x.mode == variable {
- // If typ is not an (unnamed) pointer or an interface,
- // use *typ instead, because the method set of *typ
- // includes the methods of typ.
- // Variables are addressable, so we can always take their
- // address.
- if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) {
- typ = &Pointer{base: typ}
- }
- }
- // If we created a synthetic pointer type above, we will throw
- // away the method set computed here after use.
- // TODO(gri) Method set computation should probably always compute
- // both, the value and the pointer receiver method set and represent
- // them in a single structure.
- // TODO(gri) Consider also using a method set cache for the lifetime
- // of checker once we rely on MethodSet lookup instead of individual
- // lookup.
- mset := NewMethodSet(typ)
- if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj {
- check.dump("%v: (%s).%v -> %s", e.Pos(), typ, obj.name, m)
- check.dump("%s\n", mset)
- // Caution: MethodSets are supposed to be used externally
- // only (after all interface types were completed). It's
- // now possible that we get here incorrectly. Not urgent
- // to fix since we only run this code in debug mode.
- // TODO(gri) fix this eventually.
- panic("method sets and lookup don't agree")
- }
- }
-
- x.mode = value
-
- // remove receiver
- sig := *obj.typ.(*Signature)
- sig.recv = nil
- x.typ = &sig
-
- check.addDeclDep(obj)
-
- default:
- unreachable()
- }
- }
-
- // everything went well
- x.expr = e
- return
-
-Error:
- x.mode = invalid
- x.expr = e
-}
-
-// use type-checks each argument.
-// Useful to make sure expressions are evaluated
-// (and variables are "used") in the presence of other errors.
-// The arguments may be nil.
-func (check *Checker) use(arg ...ast.Expr) {
- var x operand
- for _, e := range arg {
- // The nil check below is necessary since certain AST fields
- // may legally be nil (e.g., the ast.SliceExpr.High field).
- if e != nil {
- check.rawExpr(&x, e, nil, false)
- }
- }
-}
-
-// useLHS is like use, but doesn't "use" top-level identifiers.
-// It should be called instead of use if the arguments are
-// expressions on the lhs of an assignment.
-// The arguments must not be nil.
-func (check *Checker) useLHS(arg ...ast.Expr) {
- var x operand
- for _, e := range arg {
- // If the lhs is an identifier denoting a variable v, this assignment
- // is not a 'use' of v. Remember current value of v.used and restore
- // after evaluating the lhs via check.rawExpr.
- var v *Var
- var v_used bool
- if ident, _ := unparen(e).(*ast.Ident); ident != nil {
- // never type-check the blank name on the lhs
- if ident.Name == "_" {
- continue
- }
- if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil {
- // It's ok to mark non-local variables, but ignore variables
- // from other packages to avoid potential race conditions with
- // dot-imported variables.
- if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
- v = w
- v_used = v.used
- }
- }
- }
- check.rawExpr(&x, e, nil, false)
- if v != nil {
- v.used = v_used // restore v.used
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/go/types/chan.go b/contrib/go/_std_1.20/src/go/types/chan.go
deleted file mode 100644
index 1f7b72be30..0000000000
--- a/contrib/go/_std_1.20/src/go/types/chan.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2011 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 types
-
-// A Chan represents a channel type.
-type Chan struct {
- dir ChanDir
- elem Type
-}
-
-// A ChanDir value indicates a channel direction.
-type ChanDir int
-
-// The direction of a channel is indicated by one of these constants.
-const (
- SendRecv ChanDir = iota
- SendOnly
- RecvOnly
-)
-
-// NewChan returns a new channel type for the given direction and element type.
-func NewChan(dir ChanDir, elem Type) *Chan {
- return &Chan{dir: dir, elem: elem}
-}
-
-// Dir returns the direction of channel c.
-func (c *Chan) Dir() ChanDir { return c.dir }
-
-// Elem returns the element type of channel c.
-func (c *Chan) Elem() Type { return c.elem }
-
-func (t *Chan) Underlying() Type { return t }
-func (t *Chan) String() string { return TypeString(t, nil) }
diff --git a/contrib/go/_std_1.20/src/go/types/check.go b/contrib/go/_std_1.20/src/go/types/check.go
deleted file mode 100644
index 50d8afe4e3..0000000000
--- a/contrib/go/_std_1.20/src/go/types/check.go
+++ /dev/null
@@ -1,578 +0,0 @@
-// Copyright 2011 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.
-
-// This file implements the Check function, which drives type-checking.
-
-package types
-
-import (
- "errors"
- "fmt"
- "go/ast"
- "go/constant"
- "go/token"
- . "internal/types/errors"
-)
-
-// debugging/development support
-const (
- debug = false // leave on during development
- trace = false // turn on for detailed type resolution traces
-)
-
-// exprInfo stores information about an untyped expression.
-type exprInfo struct {
- isLhs bool // expression is lhs operand of a shift with delayed type-check
- mode operandMode
- typ *Basic
- val constant.Value // constant value; or nil (if not a constant)
-}
-
-// An environment represents the environment within which an object is
-// type-checked.
-type environment struct {
- decl *declInfo // package-level declaration whose init expression/function body is checked
- scope *Scope // top-most scope for lookups
- pos token.Pos // if valid, identifiers are looked up as if at position pos (used by Eval)
- iota constant.Value // value of iota in a constant declaration; nil otherwise
- errpos positioner // if set, identifier position of a constant with inherited initializer
- inTParamList bool // set if inside a type parameter list
- sig *Signature // function signature if inside a function; nil otherwise
- isPanic map[*ast.CallExpr]bool // set of panic call expressions (used for termination check)
- hasLabel bool // set if a function makes use of labels (only ~1% of functions); unused outside functions
- hasCallOrRecv bool // set if an expression contains a function call or channel receive operation
-}
-
-// lookup looks up name in the current environment and returns the matching object, or nil.
-func (env *environment) lookup(name string) Object {
- _, obj := env.scope.LookupParent(name, env.pos)
- return obj
-}
-
-// An importKey identifies an imported package by import path and source directory
-// (directory containing the file containing the import). In practice, the directory
-// may always be the same, or may not matter. Given an (import path, directory), an
-// importer must always return the same package (but given two different import paths,
-// an importer may still return the same package by mapping them to the same package
-// paths).
-type importKey struct {
- path, dir string
-}
-
-// A dotImportKey describes a dot-imported object in the given scope.
-type dotImportKey struct {
- scope *Scope
- name string
-}
-
-// An action describes a (delayed) action.
-type action struct {
- f func() // action to be executed
- desc *actionDesc // action description; may be nil, requires debug to be set
-}
-
-// If debug is set, describef sets a printf-formatted description for action a.
-// Otherwise, it is a no-op.
-func (a *action) describef(pos positioner, format string, args ...any) {
- if debug {
- a.desc = &actionDesc{pos, format, args}
- }
-}
-
-// An actionDesc provides information on an action.
-// For debugging only.
-type actionDesc struct {
- pos positioner
- format string
- args []any
-}
-
-// A Checker maintains the state of the type checker.
-// It must be created with NewChecker.
-type Checker struct {
- // package information
- // (initialized by NewChecker, valid for the life-time of checker)
- conf *Config
- ctxt *Context // context for de-duplicating instances
- fset *token.FileSet
- pkg *Package
- *Info
- version version // accepted language version
- nextID uint64 // unique Id for type parameters (first valid Id is 1)
- objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info
- impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package
- valids instanceLookup // valid *Named (incl. instantiated) types per the validType check
-
- // pkgPathMap maps package names to the set of distinct import paths we've
- // seen for that name, anywhere in the import graph. It is used for
- // disambiguating package names in error messages.
- //
- // pkgPathMap is allocated lazily, so that we don't pay the price of building
- // it on the happy path. seenPkgMap tracks the packages that we've already
- // walked.
- pkgPathMap map[string]map[string]bool
- seenPkgMap map[*Package]bool
-
- // information collected during type-checking of a set of package files
- // (initialized by Files, valid only for the duration of check.Files;
- // maps and lists are allocated on demand)
- files []*ast.File // package files
- imports []*PkgName // list of imported packages
- dotImportMap map[dotImportKey]*PkgName // maps dot-imported objects to the package they were dot-imported through
- recvTParamMap map[*ast.Ident]*TypeParam // maps blank receiver type parameters to their type
- brokenAliases map[*TypeName]bool // set of aliases with broken (not yet determined) types
- unionTypeSets map[*Union]*_TypeSet // computed type sets for union types
- mono monoGraph // graph for detecting non-monomorphizable instantiation loops
-
- firstErr error // first error encountered
- methods map[*TypeName][]*Func // maps package scope type names to associated non-blank (non-interface) methods
- untyped map[ast.Expr]exprInfo // map of expressions without final type
- delayed []action // stack of delayed action segments; segments are processed in FIFO order
- objPath []Object // path of object dependencies during type inference (for cycle reporting)
- cleaners []cleaner // list of types that may need a final cleanup at the end of type-checking
-
- // environment within which the current object is type-checked (valid only
- // for the duration of type-checking a specific object)
- environment
-
- // debugging
- indent int // indentation for tracing
-}
-
-// addDeclDep adds the dependency edge (check.decl -> to) if check.decl exists
-func (check *Checker) addDeclDep(to Object) {
- from := check.decl
- if from == nil {
- return // not in a package-level init expression
- }
- if _, found := check.objMap[to]; !found {
- return // to is not a package-level object
- }
- from.addDep(to)
-}
-
-// brokenAlias records that alias doesn't have a determined type yet.
-// It also sets alias.typ to Typ[Invalid].
-func (check *Checker) brokenAlias(alias *TypeName) {
- if check.brokenAliases == nil {
- check.brokenAliases = make(map[*TypeName]bool)
- }
- check.brokenAliases[alias] = true
- alias.typ = Typ[Invalid]
-}
-
-// validAlias records that alias has the valid type typ (possibly Typ[Invalid]).
-func (check *Checker) validAlias(alias *TypeName, typ Type) {
- delete(check.brokenAliases, alias)
- alias.typ = typ
-}
-
-// isBrokenAlias reports whether alias doesn't have a determined type yet.
-func (check *Checker) isBrokenAlias(alias *TypeName) bool {
- return alias.typ == Typ[Invalid] && check.brokenAliases[alias]
-}
-
-func (check *Checker) rememberUntyped(e ast.Expr, lhs bool, mode operandMode, typ *Basic, val constant.Value) {
- m := check.untyped
- if m == nil {
- m = make(map[ast.Expr]exprInfo)
- check.untyped = m
- }
- m[e] = exprInfo{lhs, mode, typ, val}
-}
-
-// later pushes f on to the stack of actions that will be processed later;
-// either at the end of the current statement, or in case of a local constant
-// or variable declaration, before the constant or variable is in scope
-// (so that f still sees the scope before any new declarations).
-// later returns the pushed action so one can provide a description
-// via action.describef for debugging, if desired.
-func (check *Checker) later(f func()) *action {
- i := len(check.delayed)
- check.delayed = append(check.delayed, action{f: f})
- return &check.delayed[i]
-}
-
-// push pushes obj onto the object path and returns its index in the path.
-func (check *Checker) push(obj Object) int {
- check.objPath = append(check.objPath, obj)
- return len(check.objPath) - 1
-}
-
-// pop pops and returns the topmost object from the object path.
-func (check *Checker) pop() Object {
- i := len(check.objPath) - 1
- obj := check.objPath[i]
- check.objPath[i] = nil
- check.objPath = check.objPath[:i]
- return obj
-}
-
-type cleaner interface {
- cleanup()
-}
-
-// needsCleanup records objects/types that implement the cleanup method
-// which will be called at the end of type-checking.
-func (check *Checker) needsCleanup(c cleaner) {
- check.cleaners = append(check.cleaners, c)
-}
-
-// NewChecker returns a new Checker instance for a given package.
-// Package files may be added incrementally via checker.Files.
-func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Checker {
- // make sure we have a configuration
- if conf == nil {
- conf = new(Config)
- }
-
- // make sure we have an info struct
- if info == nil {
- info = new(Info)
- }
-
- version, err := parseGoVersion(conf.GoVersion)
- if err != nil {
- panic(fmt.Sprintf("invalid Go version %q (%v)", conf.GoVersion, err))
- }
-
- return &Checker{
- conf: conf,
- ctxt: conf.Context,
- fset: fset,
- pkg: pkg,
- Info: info,
- version: version,
- objMap: make(map[Object]*declInfo),
- impMap: make(map[importKey]*Package),
- }
-}
-
-// initFiles initializes the files-specific portion of checker.
-// The provided files must all belong to the same package.
-func (check *Checker) initFiles(files []*ast.File) {
- // start with a clean slate (check.Files may be called multiple times)
- check.files = nil
- check.imports = nil
- check.dotImportMap = nil
-
- check.firstErr = nil
- check.methods = nil
- check.untyped = nil
- check.delayed = nil
- check.objPath = nil
- check.cleaners = nil
-
- // determine package name and collect valid files
- pkg := check.pkg
- for _, file := range files {
- switch name := file.Name.Name; pkg.name {
- case "":
- if name != "_" {
- pkg.name = name
- } else {
- check.error(file.Name, BlankPkgName, "invalid package name _")
- }
- fallthrough
-
- case name:
- check.files = append(check.files, file)
-
- default:
- check.errorf(atPos(file.Package), MismatchedPkgName, "package %s; expected %s", name, pkg.name)
- // ignore this file
- }
- }
-}
-
-// A bailout panic is used for early termination.
-type bailout struct{}
-
-func (check *Checker) handleBailout(err *error) {
- switch p := recover().(type) {
- case nil, bailout:
- // normal return or early exit
- *err = check.firstErr
- default:
- // re-panic
- panic(p)
- }
-}
-
-// Files checks the provided files as part of the checker's package.
-func (check *Checker) Files(files []*ast.File) error { return check.checkFiles(files) }
-
-var errBadCgo = errors.New("cannot use FakeImportC and go115UsesCgo together")
-
-func (check *Checker) checkFiles(files []*ast.File) (err error) {
- if check.conf.FakeImportC && check.conf.go115UsesCgo {
- return errBadCgo
- }
-
- defer check.handleBailout(&err)
-
- print := func(msg string) {
- if trace {
- fmt.Println()
- fmt.Println(msg)
- }
- }
-
- print("== initFiles ==")
- check.initFiles(files)
-
- print("== collectObjects ==")
- check.collectObjects()
-
- print("== packageObjects ==")
- check.packageObjects()
-
- print("== processDelayed ==")
- check.processDelayed(0) // incl. all functions
-
- print("== cleanup ==")
- check.cleanup()
-
- print("== initOrder ==")
- check.initOrder()
-
- if !check.conf.DisableUnusedImportCheck {
- print("== unusedImports ==")
- check.unusedImports()
- }
-
- print("== recordUntyped ==")
- check.recordUntyped()
-
- if check.firstErr == nil {
- // TODO(mdempsky): Ensure monomorph is safe when errors exist.
- check.monomorph()
- }
-
- check.pkg.complete = true
-
- // no longer needed - release memory
- check.imports = nil
- check.dotImportMap = nil
- check.pkgPathMap = nil
- check.seenPkgMap = nil
- check.recvTParamMap = nil
- check.brokenAliases = nil
- check.unionTypeSets = nil
- check.ctxt = nil
-
- // TODO(rFindley) There's more memory we should release at this point.
-
- return
-}
-
-// processDelayed processes all delayed actions pushed after top.
-func (check *Checker) processDelayed(top int) {
- // If each delayed action pushes a new action, the
- // stack will continue to grow during this loop.
- // However, it is only processing functions (which
- // are processed in a delayed fashion) that may
- // add more actions (such as nested functions), so
- // this is a sufficiently bounded process.
- for i := top; i < len(check.delayed); i++ {
- a := &check.delayed[i]
- if trace {
- if a.desc != nil {
- check.trace(a.desc.pos.Pos(), "-- "+a.desc.format, a.desc.args...)
- } else {
- check.trace(token.NoPos, "-- delayed %p", a.f)
- }
- }
- a.f() // may append to check.delayed
- if trace {
- fmt.Println()
- }
- }
- assert(top <= len(check.delayed)) // stack must not have shrunk
- check.delayed = check.delayed[:top]
-}
-
-// cleanup runs cleanup for all collected cleaners.
-func (check *Checker) cleanup() {
- // Don't use a range clause since Named.cleanup may add more cleaners.
- for i := 0; i < len(check.cleaners); i++ {
- check.cleaners[i].cleanup()
- }
- check.cleaners = nil
-}
-
-func (check *Checker) record(x *operand) {
- // convert x into a user-friendly set of values
- // TODO(gri) this code can be simplified
- var typ Type
- var val constant.Value
- switch x.mode {
- case invalid:
- typ = Typ[Invalid]
- case novalue:
- typ = (*Tuple)(nil)
- case constant_:
- typ = x.typ
- val = x.val
- default:
- typ = x.typ
- }
- assert(x.expr != nil && typ != nil)
-
- if isUntyped(typ) {
- // delay type and value recording until we know the type
- // or until the end of type checking
- check.rememberUntyped(x.expr, false, x.mode, typ.(*Basic), val)
- } else {
- check.recordTypeAndValue(x.expr, x.mode, typ, val)
- }
-}
-
-func (check *Checker) recordUntyped() {
- if !debug && check.Types == nil {
- return // nothing to do
- }
-
- for x, info := range check.untyped {
- if debug && isTyped(info.typ) {
- check.dump("%v: %s (type %s) is typed", x.Pos(), x, info.typ)
- unreachable()
- }
- check.recordTypeAndValue(x, info.mode, info.typ, info.val)
- }
-}
-
-func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type, val constant.Value) {
- assert(x != nil)
- assert(typ != nil)
- if mode == invalid {
- return // omit
- }
- if mode == constant_ {
- assert(val != nil)
- // We check allBasic(typ, IsConstType) here as constant expressions may be
- // recorded as type parameters.
- assert(typ == Typ[Invalid] || allBasic(typ, IsConstType))
- }
- if m := check.Types; m != nil {
- m[x] = TypeAndValue{mode, typ, val}
- }
-}
-
-func (check *Checker) recordBuiltinType(f ast.Expr, sig *Signature) {
- // f must be a (possibly parenthesized, possibly qualified)
- // identifier denoting a built-in (including unsafe's non-constant
- // functions Add and Slice): record the signature for f and possible
- // children.
- for {
- check.recordTypeAndValue(f, builtin, sig, nil)
- switch p := f.(type) {
- case *ast.Ident, *ast.SelectorExpr:
- return // we're done
- case *ast.ParenExpr:
- f = p.X
- default:
- unreachable()
- }
- }
-}
-
-func (check *Checker) recordCommaOkTypes(x ast.Expr, a [2]Type) {
- assert(x != nil)
- if a[0] == nil || a[1] == nil {
- return
- }
- assert(isTyped(a[0]) && isTyped(a[1]) && (isBoolean(a[1]) || a[1] == universeError))
- if m := check.Types; m != nil {
- for {
- tv := m[x]
- assert(tv.Type != nil) // should have been recorded already
- pos := x.Pos()
- tv.Type = NewTuple(
- NewVar(pos, check.pkg, "", a[0]),
- NewVar(pos, check.pkg, "", a[1]),
- )
- m[x] = tv
- // if x is a parenthesized expression (p.X), update p.X
- p, _ := x.(*ast.ParenExpr)
- if p == nil {
- break
- }
- x = p.X
- }
- }
-}
-
-// recordInstance records instantiation information into check.Info, if the
-// Instances map is non-nil. The given expr must be an ident, selector, or
-// index (list) expr with ident or selector operand.
-//
-// TODO(rfindley): the expr parameter is fragile. See if we can access the
-// instantiated identifier in some other way.
-func (check *Checker) recordInstance(expr ast.Expr, targs []Type, typ Type) {
- ident := instantiatedIdent(expr)
- assert(ident != nil)
- assert(typ != nil)
- if m := check.Instances; m != nil {
- m[ident] = Instance{newTypeList(targs), typ}
- }
-}
-
-func instantiatedIdent(expr ast.Expr) *ast.Ident {
- var selOrIdent ast.Expr
- switch e := expr.(type) {
- case *ast.IndexExpr:
- selOrIdent = e.X
- case *ast.IndexListExpr:
- selOrIdent = e.X
- case *ast.SelectorExpr, *ast.Ident:
- selOrIdent = e
- }
- switch x := selOrIdent.(type) {
- case *ast.Ident:
- return x
- case *ast.SelectorExpr:
- return x.Sel
- }
- panic("instantiated ident not found")
-}
-
-func (check *Checker) recordDef(id *ast.Ident, obj Object) {
- assert(id != nil)
- if m := check.Defs; m != nil {
- m[id] = obj
- }
-}
-
-func (check *Checker) recordUse(id *ast.Ident, obj Object) {
- assert(id != nil)
- assert(obj != nil)
- if m := check.Uses; m != nil {
- m[id] = obj
- }
-}
-
-func (check *Checker) recordImplicit(node ast.Node, obj Object) {
- assert(node != nil)
- assert(obj != nil)
- if m := check.Implicits; m != nil {
- m[node] = obj
- }
-}
-
-func (check *Checker) recordSelection(x *ast.SelectorExpr, kind SelectionKind, recv Type, obj Object, index []int, indirect bool) {
- assert(obj != nil && (recv == nil || len(index) > 0))
- check.recordUse(x.Sel, obj)
- if m := check.Selections; m != nil {
- m[x] = &Selection{kind, recv, obj, index, indirect}
- }
-}
-
-func (check *Checker) recordScope(node ast.Node, scope *Scope) {
- assert(node != nil)
- assert(scope != nil)
- if m := check.Scopes; m != nil {
- m[node] = scope
- }
-}
diff --git a/contrib/go/_std_1.20/src/go/types/context.go b/contrib/go/_std_1.20/src/go/types/context.go
deleted file mode 100644
index 15756b062d..0000000000
--- a/contrib/go/_std_1.20/src/go/types/context.go
+++ /dev/null
@@ -1,144 +0,0 @@
-// 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 types
-
-import (
- "bytes"
- "fmt"
- "strconv"
- "strings"
- "sync"
-)
-
-// This file contains a definition of the type-checking context; an opaque type
-// that may be supplied by users during instantiation.
-//
-// Contexts serve two purposes:
-// - reduce the duplication of identical instances
-// - short-circuit instantiation cycles
-//
-// For the latter purpose, we must always have a context during instantiation,
-// whether or not it is supplied by the user. For both purposes, it must be the
-// case that hashing a pointer-identical type produces consistent results
-// (somewhat obviously).
-//
-// However, neither of these purposes require that our hash is perfect, and so
-// this was not an explicit design goal of the context type. In fact, due to
-// concurrent use it is convenient not to guarantee de-duplication.
-//
-// Nevertheless, in the future it could be helpful to allow users to leverage
-// contexts to canonicalize instances, and it would probably be possible to
-// achieve such a guarantee.
-
-// A Context is an opaque type checking context. It may be used to share
-// identical type instances across type-checked packages or calls to
-// Instantiate. Contexts are safe for concurrent use.
-//
-// The use of a shared context does not guarantee that identical instances are
-// deduplicated in all cases.
-type Context struct {
- mu sync.Mutex
- typeMap map[string][]ctxtEntry // type hash -> instances entries
- nextID int // next unique ID
- originIDs map[Type]int // origin type -> unique ID
-}
-
-type ctxtEntry struct {
- orig Type
- targs []Type
- instance Type // = orig[targs]
-}
-
-// NewContext creates a new Context.
-func NewContext() *Context {
- return &Context{
- typeMap: make(map[string][]ctxtEntry),
- originIDs: make(map[Type]int),
- }
-}
-
-// instanceHash returns a string representation of typ instantiated with targs.
-// The hash should be a perfect hash, though out of caution the type checker
-// does not assume this. The result is guaranteed to not contain blanks.
-func (ctxt *Context) instanceHash(orig Type, targs []Type) string {
- assert(ctxt != nil)
- assert(orig != nil)
- var buf bytes.Buffer
-
- h := newTypeHasher(&buf, ctxt)
- h.string(strconv.Itoa(ctxt.getID(orig)))
- // Because we've already written the unique origin ID this call to h.typ is
- // unnecessary, but we leave it for hash readability. It can be removed later
- // if performance is an issue.
- h.typ(orig)
- if len(targs) > 0 {
- // TODO(rfindley): consider asserting on isGeneric(typ) here, if and when
- // isGeneric handles *Signature types.
- h.typeList(targs)
- }
-
- return strings.Replace(buf.String(), " ", "#", -1) // ReplaceAll is not available in Go1.4
-}
-
-// lookup returns an existing instantiation of orig with targs, if it exists.
-// Otherwise, it returns nil.
-func (ctxt *Context) lookup(h string, orig Type, targs []Type) Type {
- ctxt.mu.Lock()
- defer ctxt.mu.Unlock()
-
- for _, e := range ctxt.typeMap[h] {
- if identicalInstance(orig, targs, e.orig, e.targs) {
- return e.instance
- }
- if debug {
- // Panic during development to surface any imperfections in our hash.
- panic(fmt.Sprintf("non-identical instances: (orig: %s, targs: %v) and %s", orig, targs, e.instance))
- }
- }
-
- return nil
-}
-
-// update de-duplicates n against previously seen types with the hash h. If an
-// identical type is found with the type hash h, the previously seen type is
-// returned. Otherwise, n is returned, and recorded in the Context for the hash
-// h.
-func (ctxt *Context) update(h string, orig Type, targs []Type, inst Type) Type {
- assert(inst != nil)
-
- ctxt.mu.Lock()
- defer ctxt.mu.Unlock()
-
- for _, e := range ctxt.typeMap[h] {
- if inst == nil || Identical(inst, e.instance) {
- return e.instance
- }
- if debug {
- // Panic during development to surface any imperfections in our hash.
- panic(fmt.Sprintf("%s and %s are not identical", inst, e.instance))
- }
- }
-
- ctxt.typeMap[h] = append(ctxt.typeMap[h], ctxtEntry{
- orig: orig,
- targs: targs,
- instance: inst,
- })
-
- return inst
-}
-
-// getID returns a unique ID for the type t.
-func (ctxt *Context) getID(t Type) int {
- ctxt.mu.Lock()
- defer ctxt.mu.Unlock()
- id, ok := ctxt.originIDs[t]
- if !ok {
- id = ctxt.nextID
- ctxt.originIDs[t] = id
- ctxt.nextID++
- }
- return id
-}
diff --git a/contrib/go/_std_1.20/src/go/types/conversions.go b/contrib/go/_std_1.20/src/go/types/conversions.go
deleted file mode 100644
index 3cdbedb8bc..0000000000
--- a/contrib/go/_std_1.20/src/go/types/conversions.go
+++ /dev/null
@@ -1,296 +0,0 @@
-// Copyright 2012 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.
-
-// This file implements typechecking of conversions.
-
-package types
-
-import (
- "go/constant"
- . "internal/types/errors"
- "unicode"
-)
-
-// Conversion type-checks the conversion T(x).
-// The result is in x.
-func (check *Checker) conversion(x *operand, T Type) {
- constArg := x.mode == constant_
-
- constConvertibleTo := func(T Type, val *constant.Value) bool {
- switch t, _ := under(T).(*Basic); {
- case t == nil:
- // nothing to do
- case representableConst(x.val, check, t, val):
- return true
- case isInteger(x.typ) && isString(t):
- codepoint := unicode.ReplacementChar
- if i, ok := constant.Uint64Val(x.val); ok && i <= unicode.MaxRune {
- codepoint = rune(i)
- }
- if val != nil {
- *val = constant.MakeString(string(codepoint))
- }
- return true
- }
- return false
- }
-
- var ok bool
- var cause string
- switch {
- case constArg && isConstType(T):
- // constant conversion
- ok = constConvertibleTo(T, &x.val)
- case constArg && isTypeParam(T):
- // x is convertible to T if it is convertible
- // to each specific type in the type set of T.
- // If T's type set is empty, or if it doesn't
- // have specific types, constant x cannot be
- // converted.
- ok = T.(*TypeParam).underIs(func(u Type) bool {
- // u is nil if there are no specific type terms
- if u == nil {
- cause = check.sprintf("%s does not contain specific types", T)
- return false
- }
- if isString(x.typ) && isBytesOrRunes(u) {
- return true
- }
- if !constConvertibleTo(u, nil) {
- cause = check.sprintf("cannot convert %s to type %s (in %s)", x, u, T)
- return false
- }
- return true
- })
- x.mode = value // type parameters are not constants
- case x.convertibleTo(check, T, &cause):
- // non-constant conversion
- ok = true
- x.mode = value
- }
-
- if !ok {
- if cause != "" {
- check.errorf(x, InvalidConversion, "cannot convert %s to type %s: %s", x, T, cause)
- } else {
- check.errorf(x, InvalidConversion, "cannot convert %s to type %s", x, T)
- }
- x.mode = invalid
- return
- }
-
- // The conversion argument types are final. For untyped values the
- // conversion provides the type, per the spec: "A constant may be
- // given a type explicitly by a constant declaration or conversion,...".
- if isUntyped(x.typ) {
- final := T
- // - For conversions to interfaces, use the argument's default type.
- // - For conversions of untyped constants to non-constant types, also
- // use the default type (e.g., []byte("foo") should report string
- // not []byte as type for the constant "foo").
- // - Keep untyped nil for untyped nil arguments.
- // - For constant integer to string conversions, keep the argument type.
- // (See also the TODO below.)
- if isNonTypeParamInterface(T) || constArg && !isConstType(T) || x.isNil() {
- final = Default(x.typ) // default type of untyped nil is untyped nil
- } else if x.mode == constant_ && isInteger(x.typ) && allString(T) {
- final = x.typ
- }
- check.updateExprType(x.expr, final, true)
- }
-
- x.typ = T
-}
-
-// TODO(gri) convertibleTo checks if T(x) is valid. It assumes that the type
-// of x is fully known, but that's not the case for say string(1<<s + 1.0):
-// Here, the type of 1<<s + 1.0 will be UntypedFloat which will lead to the
-// (correct!) refusal of the conversion. But the reported error is essentially
-// "cannot convert untyped float value to string", yet the correct error (per
-// the spec) is that we cannot shift a floating-point value: 1 in 1<<s should
-// be converted to UntypedFloat because of the addition of 1.0. Fixing this
-// is tricky because we'd have to run updateExprType on the argument first.
-// (Issue #21982.)
-
-// convertibleTo reports whether T(x) is valid. In the failure case, *cause
-// may be set to the cause for the failure.
-// The check parameter may be nil if convertibleTo is invoked through an
-// exported API call, i.e., when all methods have been type-checked.
-func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
- // "x is assignable to T"
- if ok, _ := x.assignableTo(check, T, cause); ok {
- return true
- }
-
- // "V and T have identical underlying types if tags are ignored
- // and V and T are not type parameters"
- V := x.typ
- Vu := under(V)
- Tu := under(T)
- Vp, _ := V.(*TypeParam)
- Tp, _ := T.(*TypeParam)
- if IdenticalIgnoreTags(Vu, Tu) && Vp == nil && Tp == nil {
- return true
- }
-
- // "V and T are unnamed pointer types and their pointer base types
- // have identical underlying types if tags are ignored
- // and their pointer base types are not type parameters"
- if V, ok := V.(*Pointer); ok {
- if T, ok := T.(*Pointer); ok {
- if IdenticalIgnoreTags(under(V.base), under(T.base)) && !isTypeParam(V.base) && !isTypeParam(T.base) {
- return true
- }
- }
- }
-
- // "V and T are both integer or floating point types"
- if isIntegerOrFloat(Vu) && isIntegerOrFloat(Tu) {
- return true
- }
-
- // "V and T are both complex types"
- if isComplex(Vu) && isComplex(Tu) {
- return true
- }
-
- // "V is an integer or a slice of bytes or runes and T is a string type"
- if (isInteger(Vu) || isBytesOrRunes(Vu)) && isString(Tu) {
- return true
- }
-
- // "V is a string and T is a slice of bytes or runes"
- if isString(Vu) && isBytesOrRunes(Tu) {
- return true
- }
-
- // package unsafe:
- // "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
- if (isPointer(Vu) || isUintptr(Vu)) && isUnsafePointer(Tu) {
- return true
- }
- // "and vice versa"
- if isUnsafePointer(Vu) && (isPointer(Tu) || isUintptr(Tu)) {
- return true
- }
-
- // "V is a slice, T is an array or pointer-to-array type,
- // and the slice and array types have identical element types."
- if s, _ := Vu.(*Slice); s != nil {
- switch a := Tu.(type) {
- case *Array:
- if Identical(s.Elem(), a.Elem()) {
- if check == nil || check.allowVersion(check.pkg, 1, 20) {
- return true
- }
- // check != nil
- if cause != nil {
- // TODO(gri) consider restructuring versionErrorf so we can use it here and below
- *cause = "conversion of slices to arrays requires go1.20 or later"
- }
- return false
- }
- case *Pointer:
- if a, _ := under(a.Elem()).(*Array); a != nil {
- if Identical(s.Elem(), a.Elem()) {
- if check == nil || check.allowVersion(check.pkg, 1, 17) {
- return true
- }
- // check != nil
- if cause != nil {
- *cause = "conversion of slices to array pointers requires go1.17 or later"
- }
- return false
- }
- }
- }
- }
-
- // optimization: if we don't have type parameters, we're done
- if Vp == nil && Tp == nil {
- return false
- }
-
- errorf := func(format string, args ...any) {
- if check != nil && cause != nil {
- msg := check.sprintf(format, args...)
- if *cause != "" {
- msg += "\n\t" + *cause
- }
- *cause = msg
- }
- }
-
- // generic cases with specific type terms
- // (generic operands cannot be constants, so we can ignore x.val)
- switch {
- case Vp != nil && Tp != nil:
- x := *x // don't clobber outer x
- return Vp.is(func(V *term) bool {
- if V == nil {
- return false // no specific types
- }
- x.typ = V.typ
- return Tp.is(func(T *term) bool {
- if T == nil {
- return false // no specific types
- }
- if !x.convertibleTo(check, T.typ, cause) {
- errorf("cannot convert %s (in %s) to type %s (in %s)", V.typ, Vp, T.typ, Tp)
- return false
- }
- return true
- })
- })
- case Vp != nil:
- x := *x // don't clobber outer x
- return Vp.is(func(V *term) bool {
- if V == nil {
- return false // no specific types
- }
- x.typ = V.typ
- if !x.convertibleTo(check, T, cause) {
- errorf("cannot convert %s (in %s) to type %s", V.typ, Vp, T)
- return false
- }
- return true
- })
- case Tp != nil:
- return Tp.is(func(T *term) bool {
- if T == nil {
- return false // no specific types
- }
- if !x.convertibleTo(check, T.typ, cause) {
- errorf("cannot convert %s to type %s (in %s)", x.typ, T.typ, Tp)
- return false
- }
- return true
- })
- }
-
- return false
-}
-
-func isUintptr(typ Type) bool {
- t, _ := under(typ).(*Basic)
- return t != nil && t.kind == Uintptr
-}
-
-func isUnsafePointer(typ Type) bool {
- t, _ := under(typ).(*Basic)
- return t != nil && t.kind == UnsafePointer
-}
-
-func isPointer(typ Type) bool {
- _, ok := under(typ).(*Pointer)
- return ok
-}
-
-func isBytesOrRunes(typ Type) bool {
- if s, _ := under(typ).(*Slice); s != nil {
- t, _ := under(s.elem).(*Basic)
- return t != nil && (t.kind == Byte || t.kind == Rune)
- }
- return false
-}
diff --git a/contrib/go/_std_1.20/src/go/types/decl.go b/contrib/go/_std_1.20/src/go/types/decl.go
deleted file mode 100644
index adc485c400..0000000000
--- a/contrib/go/_std_1.20/src/go/types/decl.go
+++ /dev/null
@@ -1,937 +0,0 @@
-// Copyright 2014 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 types
-
-import (
- "fmt"
- "go/ast"
- "go/constant"
- "go/token"
- . "internal/types/errors"
-)
-
-func (check *Checker) reportAltDecl(obj Object) {
- if pos := obj.Pos(); pos.IsValid() {
- // We use "other" rather than "previous" here because
- // the first declaration seen may not be textually
- // earlier in the source.
- check.errorf(obj, DuplicateDecl, "\tother declaration of %s", obj.Name()) // secondary error, \t indented
- }
-}
-
-func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) {
- // spec: "The blank identifier, represented by the underscore
- // character _, may be used in a declaration like any other
- // identifier but the declaration does not introduce a new
- // binding."
- if obj.Name() != "_" {
- if alt := scope.Insert(obj); alt != nil {
- check.errorf(obj, DuplicateDecl, "%s redeclared in this block", obj.Name())
- check.reportAltDecl(alt)
- return
- }
- obj.setScopePos(pos)
- }
- if id != nil {
- check.recordDef(id, obj)
- }
-}
-
-// pathString returns a string of the form a->b-> ... ->g for a path [a, b, ... g].
-func pathString(path []Object) string {
- var s string
- for i, p := range path {
- if i > 0 {
- s += "->"
- }
- s += p.Name()
- }
- return s
-}
-
-// objDecl type-checks the declaration of obj in its respective (file) environment.
-// For the meaning of def, see Checker.definedType, in typexpr.go.
-func (check *Checker) objDecl(obj Object, def *Named) {
- if trace && obj.Type() == nil {
- if check.indent == 0 {
- fmt.Println() // empty line between top-level objects for readability
- }
- check.trace(obj.Pos(), "-- checking %s (%s, objPath = %s)", obj, obj.color(), pathString(check.objPath))
- check.indent++
- defer func() {
- check.indent--
- check.trace(obj.Pos(), "=> %s (%s)", obj, obj.color())
- }()
- }
-
- // Checking the declaration of obj means inferring its type
- // (and possibly its value, for constants).
- // An object's type (and thus the object) may be in one of
- // three states which are expressed by colors:
- //
- // - an object whose type is not yet known is painted white (initial color)
- // - an object whose type is in the process of being inferred is painted grey
- // - an object whose type is fully inferred is painted black
- //
- // During type inference, an object's color changes from white to grey
- // to black (pre-declared objects are painted black from the start).
- // A black object (i.e., its type) can only depend on (refer to) other black
- // ones. White and grey objects may depend on white and black objects.
- // A dependency on a grey object indicates a cycle which may or may not be
- // valid.
- //
- // When objects turn grey, they are pushed on the object path (a stack);
- // they are popped again when they turn black. Thus, if a grey object (a
- // cycle) is encountered, it is on the object path, and all the objects
- // it depends on are the remaining objects on that path. Color encoding
- // is such that the color value of a grey object indicates the index of
- // that object in the object path.
-
- // During type-checking, white objects may be assigned a type without
- // traversing through objDecl; e.g., when initializing constants and
- // variables. Update the colors of those objects here (rather than
- // everywhere where we set the type) to satisfy the color invariants.
- if obj.color() == white && obj.Type() != nil {
- obj.setColor(black)
- return
- }
-
- switch obj.color() {
- case white:
- assert(obj.Type() == nil)
- // All color values other than white and black are considered grey.
- // Because black and white are < grey, all values >= grey are grey.
- // Use those values to encode the object's index into the object path.
- obj.setColor(grey + color(check.push(obj)))
- defer func() {
- check.pop().setColor(black)
- }()
-
- case black:
- assert(obj.Type() != nil)
- return
-
- default:
- // Color values other than white or black are considered grey.
- fallthrough
-
- case grey:
- // We have a (possibly invalid) cycle.
- // In the existing code, this is marked by a non-nil type
- // for the object except for constants and variables whose
- // type may be non-nil (known), or nil if it depends on the
- // not-yet known initialization value.
- // In the former case, set the type to Typ[Invalid] because
- // we have an initialization cycle. The cycle error will be
- // reported later, when determining initialization order.
- // TODO(gri) Report cycle here and simplify initialization
- // order code.
- switch obj := obj.(type) {
- case *Const:
- if !check.validCycle(obj) || obj.typ == nil {
- obj.typ = Typ[Invalid]
- }
-
- case *Var:
- if !check.validCycle(obj) || obj.typ == nil {
- obj.typ = Typ[Invalid]
- }
-
- case *TypeName:
- if !check.validCycle(obj) {
- // break cycle
- // (without this, calling underlying()
- // below may lead to an endless loop
- // if we have a cycle for a defined
- // (*Named) type)
- obj.typ = Typ[Invalid]
- }
-
- case *Func:
- if !check.validCycle(obj) {
- // Don't set obj.typ to Typ[Invalid] here
- // because plenty of code type-asserts that
- // functions have a *Signature type. Grey
- // functions have their type set to an empty
- // signature which makes it impossible to
- // initialize a variable with the function.
- }
-
- default:
- unreachable()
- }
- assert(obj.Type() != nil)
- return
- }
-
- d := check.objMap[obj]
- if d == nil {
- check.dump("%v: %s should have been declared", obj.Pos(), obj)
- unreachable()
- }
-
- // save/restore current environment and set up object environment
- defer func(env environment) {
- check.environment = env
- }(check.environment)
- check.environment = environment{
- scope: d.file,
- }
-
- // Const and var declarations must not have initialization
- // cycles. We track them by remembering the current declaration
- // in check.decl. Initialization expressions depending on other
- // consts, vars, or functions, add dependencies to the current
- // check.decl.
- switch obj := obj.(type) {
- case *Const:
- check.decl = d // new package-level const decl
- check.constDecl(obj, d.vtyp, d.init, d.inherited)
- case *Var:
- check.decl = d // new package-level var decl
- check.varDecl(obj, d.lhs, d.vtyp, d.init)
- case *TypeName:
- // invalid recursive types are detected via path
- check.typeDecl(obj, d.tdecl, def)
- check.collectMethods(obj) // methods can only be added to top-level types
- case *Func:
- // functions may be recursive - no need to track dependencies
- check.funcDecl(obj, d)
- default:
- unreachable()
- }
-}
-
-// validCycle checks if the cycle starting with obj is valid and
-// reports an error if it is not.
-func (check *Checker) validCycle(obj Object) (valid bool) {
- // The object map contains the package scope objects and the non-interface methods.
- if debug {
- info := check.objMap[obj]
- inObjMap := info != nil && (info.fdecl == nil || info.fdecl.Recv == nil) // exclude methods
- isPkgObj := obj.Parent() == check.pkg.scope
- if isPkgObj != inObjMap {
- check.dump("%v: inconsistent object map for %s (isPkgObj = %v, inObjMap = %v)", obj.Pos(), obj, isPkgObj, inObjMap)
- unreachable()
- }
- }
-
- // Count cycle objects.
- assert(obj.color() >= grey)
- start := obj.color() - grey // index of obj in objPath
- cycle := check.objPath[start:]
- tparCycle := false // if set, the cycle is through a type parameter list
- nval := 0 // number of (constant or variable) values in the cycle; valid if !generic
- ndef := 0 // number of type definitions in the cycle; valid if !generic
-loop:
- for _, obj := range cycle {
- switch obj := obj.(type) {
- case *Const, *Var:
- nval++
- case *TypeName:
- // If we reach a generic type that is part of a cycle
- // and we are in a type parameter list, we have a cycle
- // through a type parameter list, which is invalid.
- if check.inTParamList && isGeneric(obj.typ) {
- tparCycle = true
- break loop
- }
-
- // Determine if the type name is an alias or not. For
- // package-level objects, use the object map which
- // provides syntactic information (which doesn't rely
- // on the order in which the objects are set up). For
- // local objects, we can rely on the order, so use
- // the object's predicate.
- // TODO(gri) It would be less fragile to always access
- // the syntactic information. We should consider storing
- // this information explicitly in the object.
- var alias bool
- if d := check.objMap[obj]; d != nil {
- alias = d.tdecl.Assign.IsValid() // package-level object
- } else {
- alias = obj.IsAlias() // function local object
- }
- if !alias {
- ndef++
- }
- case *Func:
- // ignored for now
- default:
- unreachable()
- }
- }
-
- if trace {
- check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", pathString(cycle), obj.Name(), len(cycle))
- if tparCycle {
- check.trace(obj.Pos(), "## cycle contains: generic type in a type parameter list")
- } else {
- check.trace(obj.Pos(), "## cycle contains: %d values, %d type definitions", nval, ndef)
- }
- defer func() {
- if valid {
- check.trace(obj.Pos(), "=> cycle is valid")
- } else {
- check.trace(obj.Pos(), "=> error: cycle is invalid")
- }
- }()
- }
-
- if !tparCycle {
- // A cycle involving only constants and variables is invalid but we
- // ignore them here because they are reported via the initialization
- // cycle check.
- if nval == len(cycle) {
- return true
- }
-
- // A cycle involving only types (and possibly functions) must have at least
- // one type definition to be permitted: If there is no type definition, we
- // have a sequence of alias type names which will expand ad infinitum.
- if nval == 0 && ndef > 0 {
- return true
- }
- }
-
- check.cycleError(cycle)
- return false
-}
-
-// cycleError reports a declaration cycle starting with
-// the object in cycle that is "first" in the source.
-func (check *Checker) cycleError(cycle []Object) {
- // name returns the (possibly qualified) object name.
- // This is needed because with generic types, cycles
- // may refer to imported types. See issue #50788.
- // TODO(gri) Thus functionality is used elsewhere. Factor it out.
- name := func(obj Object) string {
- return packagePrefix(obj.Pkg(), check.qualifier) + obj.Name()
- }
-
- // TODO(gri) Should we start with the last (rather than the first) object in the cycle
- // since that is the earliest point in the source where we start seeing the
- // cycle? That would be more consistent with other error messages.
- i := firstInSrc(cycle)
- obj := cycle[i]
- objName := name(obj)
- // If obj is a type alias, mark it as valid (not broken) in order to avoid follow-on errors.
- tname, _ := obj.(*TypeName)
- if tname != nil && tname.IsAlias() {
- check.validAlias(tname, Typ[Invalid])
- }
-
- // report a more concise error for self references
- if len(cycle) == 1 {
- if tname != nil {
- check.errorf(obj, InvalidDeclCycle, "invalid recursive type: %s refers to itself", objName)
- } else {
- check.errorf(obj, InvalidDeclCycle, "invalid cycle in declaration: %s refers to itself", objName)
- }
- return
- }
-
- if tname != nil {
- check.errorf(obj, InvalidDeclCycle, "invalid recursive type %s", objName)
- } else {
- check.errorf(obj, InvalidDeclCycle, "invalid cycle in declaration of %s", objName)
- }
- for range cycle {
- check.errorf(obj, InvalidDeclCycle, "\t%s refers to", objName) // secondary error, \t indented
- i++
- if i >= len(cycle) {
- i = 0
- }
- obj = cycle[i]
- objName = name(obj)
- }
- check.errorf(obj, InvalidDeclCycle, "\t%s", objName)
-}
-
-// firstInSrc reports the index of the object with the "smallest"
-// source position in path. path must not be empty.
-func firstInSrc(path []Object) int {
- fst, pos := 0, path[0].Pos()
- for i, t := range path[1:] {
- if t.Pos() < pos {
- fst, pos = i+1, t.Pos()
- }
- }
- return fst
-}
-
-type (
- decl interface {
- node() ast.Node
- }
-
- importDecl struct{ spec *ast.ImportSpec }
- constDecl struct {
- spec *ast.ValueSpec
- iota int
- typ ast.Expr
- init []ast.Expr
- inherited bool
- }
- varDecl struct{ spec *ast.ValueSpec }
- typeDecl struct{ spec *ast.TypeSpec }
- funcDecl struct{ decl *ast.FuncDecl }
-)
-
-func (d importDecl) node() ast.Node { return d.spec }
-func (d constDecl) node() ast.Node { return d.spec }
-func (d varDecl) node() ast.Node { return d.spec }
-func (d typeDecl) node() ast.Node { return d.spec }
-func (d funcDecl) node() ast.Node { return d.decl }
-
-func (check *Checker) walkDecls(decls []ast.Decl, f func(decl)) {
- for _, d := range decls {
- check.walkDecl(d, f)
- }
-}
-
-func (check *Checker) walkDecl(d ast.Decl, f func(decl)) {
- switch d := d.(type) {
- case *ast.BadDecl:
- // ignore
- case *ast.GenDecl:
- var last *ast.ValueSpec // last ValueSpec with type or init exprs seen
- for iota, s := range d.Specs {
- switch s := s.(type) {
- case *ast.ImportSpec:
- f(importDecl{s})
- case *ast.ValueSpec:
- switch d.Tok {
- case token.CONST:
- // determine which initialization expressions to use
- inherited := true
- switch {
- case s.Type != nil || len(s.Values) > 0:
- last = s
- inherited = false
- case last == nil:
- last = new(ast.ValueSpec) // make sure last exists
- inherited = false
- }
- check.arityMatch(s, last)
- f(constDecl{spec: s, iota: iota, typ: last.Type, init: last.Values, inherited: inherited})
- case token.VAR:
- check.arityMatch(s, nil)
- f(varDecl{s})
- default:
- check.errorf(s, InvalidSyntaxTree, "invalid token %s", d.Tok)
- }
- case *ast.TypeSpec:
- f(typeDecl{s})
- default:
- check.errorf(s, InvalidSyntaxTree, "unknown ast.Spec node %T", s)
- }
- }
- case *ast.FuncDecl:
- f(funcDecl{d})
- default:
- check.errorf(d, InvalidSyntaxTree, "unknown ast.Decl node %T", d)
- }
-}
-
-func (check *Checker) constDecl(obj *Const, typ, init ast.Expr, inherited bool) {
- assert(obj.typ == nil)
-
- // use the correct value of iota
- defer func(iota constant.Value, errpos positioner) {
- check.iota = iota
- check.errpos = errpos
- }(check.iota, check.errpos)
- check.iota = obj.val
- check.errpos = nil
-
- // provide valid constant value under all circumstances
- obj.val = constant.MakeUnknown()
-
- // determine type, if any
- if typ != nil {
- t := check.typ(typ)
- if !isConstType(t) {
- // don't report an error if the type is an invalid C (defined) type
- // (issue #22090)
- if under(t) != Typ[Invalid] {
- check.errorf(typ, InvalidConstType, "invalid constant type %s", t)
- }
- obj.typ = Typ[Invalid]
- return
- }
- obj.typ = t
- }
-
- // check initialization
- var x operand
- if init != nil {
- if inherited {
- // The initialization expression is inherited from a previous
- // constant declaration, and (error) positions refer to that
- // expression and not the current constant declaration. Use
- // the constant identifier position for any errors during
- // init expression evaluation since that is all we have
- // (see issues #42991, #42992).
- check.errpos = atPos(obj.pos)
- }
- check.expr(&x, init)
- }
- check.initConst(obj, &x)
-}
-
-func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
- assert(obj.typ == nil)
-
- // determine type, if any
- if typ != nil {
- obj.typ = check.varType(typ)
- // We cannot spread the type to all lhs variables if there
- // are more than one since that would mark them as checked
- // (see Checker.objDecl) and the assignment of init exprs,
- // if any, would not be checked.
- //
- // TODO(gri) If we have no init expr, we should distribute
- // a given type otherwise we need to re-evalate the type
- // expr for each lhs variable, leading to duplicate work.
- }
-
- // check initialization
- if init == nil {
- if typ == nil {
- // error reported before by arityMatch
- obj.typ = Typ[Invalid]
- }
- return
- }
-
- if lhs == nil || len(lhs) == 1 {
- assert(lhs == nil || lhs[0] == obj)
- var x operand
- check.expr(&x, init)
- check.initVar(obj, &x, "variable declaration")
- return
- }
-
- if debug {
- // obj must be one of lhs
- found := false
- for _, lhs := range lhs {
- if obj == lhs {
- found = true
- break
- }
- }
- if !found {
- panic("inconsistent lhs")
- }
- }
-
- // We have multiple variables on the lhs and one init expr.
- // Make sure all variables have been given the same type if
- // one was specified, otherwise they assume the type of the
- // init expression values (was issue #15755).
- if typ != nil {
- for _, lhs := range lhs {
- lhs.typ = obj.typ
- }
- }
-
- check.initVars(lhs, []ast.Expr{init}, nil)
-}
-
-// isImportedConstraint reports whether typ is an imported type constraint.
-func (check *Checker) isImportedConstraint(typ Type) bool {
- named, _ := typ.(*Named)
- if named == nil || named.obj.pkg == check.pkg || named.obj.pkg == nil {
- return false
- }
- u, _ := named.under().(*Interface)
- return u != nil && !u.IsMethodSet()
-}
-
-func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
- assert(obj.typ == nil)
-
- var rhs Type
- check.later(func() {
- if t, _ := obj.typ.(*Named); t != nil { // type may be invalid
- check.validType(t)
- }
- // If typ is local, an error was already reported where typ is specified/defined.
- if check.isImportedConstraint(rhs) && !check.allowVersion(check.pkg, 1, 18) {
- check.errorf(tdecl.Type, UnsupportedFeature, "using type constraint %s requires go1.18 or later", rhs)
- }
- }).describef(obj, "validType(%s)", obj.Name())
-
- alias := tdecl.Assign.IsValid()
- if alias && tdecl.TypeParams.NumFields() != 0 {
- // The parser will ensure this but we may still get an invalid AST.
- // Complain and continue as regular type definition.
- check.error(atPos(tdecl.Assign), BadDecl, "generic type cannot be alias")
- alias = false
- }
-
- // alias declaration
- if alias {
- if !check.allowVersion(check.pkg, 1, 9) {
- check.error(atPos(tdecl.Assign), UnsupportedFeature, "type aliases requires go1.9 or later")
- }
-
- check.brokenAlias(obj)
- rhs = check.typ(tdecl.Type)
- check.validAlias(obj, rhs)
- return
- }
-
- // type definition or generic type declaration
- named := check.newNamed(obj, nil, nil)
- def.setUnderlying(named)
-
- if tdecl.TypeParams != nil {
- check.openScope(tdecl, "type parameters")
- defer check.closeScope()
- check.collectTypeParams(&named.tparams, tdecl.TypeParams)
- }
-
- // determine underlying type of named
- rhs = check.definedType(tdecl.Type, named)
- assert(rhs != nil)
- named.fromRHS = rhs
-
- // If the underlying type was not set while type-checking the right-hand
- // side, it is invalid and an error should have been reported elsewhere.
- if named.underlying == nil {
- named.underlying = Typ[Invalid]
- }
-
- // Disallow a lone type parameter as the RHS of a type declaration (issue #45639).
- // We don't need this restriction anymore if we make the underlying type of a type
- // parameter its constraint interface: if the RHS is a lone type parameter, we will
- // use its underlying type (like we do for any RHS in a type declaration), and its
- // underlying type is an interface and the type declaration is well defined.
- if isTypeParam(rhs) {
- check.error(tdecl.Type, MisplacedTypeParam, "cannot use a type parameter as RHS in type declaration")
- named.underlying = Typ[Invalid]
- }
-}
-
-func (check *Checker) collectTypeParams(dst **TypeParamList, list *ast.FieldList) {
- var tparams []*TypeParam
- // Declare type parameters up-front, with empty interface as type bound.
- // The scope of type parameters starts at the beginning of the type parameter
- // list (so we can have mutually recursive parameterized interfaces).
- for _, f := range list.List {
- tparams = check.declareTypeParams(tparams, f.Names)
- }
-
- // Set the type parameters before collecting the type constraints because
- // the parameterized type may be used by the constraints (issue #47887).
- // Example: type T[P T[P]] interface{}
- *dst = bindTParams(tparams)
-
- // Signal to cycle detection that we are in a type parameter list.
- // We can only be inside one type parameter list at any given time:
- // function closures may appear inside a type parameter list but they
- // cannot be generic, and their bodies are processed in delayed and
- // sequential fashion. Note that with each new declaration, we save
- // the existing environment and restore it when done; thus inTPList is
- // true exactly only when we are in a specific type parameter list.
- assert(!check.inTParamList)
- check.inTParamList = true
- defer func() {
- check.inTParamList = false
- }()
-
- index := 0
- for _, f := range list.List {
- var bound Type
- // NOTE: we may be able to assert that f.Type != nil here, but this is not
- // an invariant of the AST, so we are cautious.
- if f.Type != nil {
- bound = check.bound(f.Type)
- if isTypeParam(bound) {
- // We may be able to allow this since it is now well-defined what
- // the underlying type and thus type set of a type parameter is.
- // But we may need some additional form of cycle detection within
- // type parameter lists.
- check.error(f.Type, MisplacedTypeParam, "cannot use a type parameter as constraint")
- bound = Typ[Invalid]
- }
- } else {
- bound = Typ[Invalid]
- }
- for i := range f.Names {
- tparams[index+i].bound = bound
- }
- index += len(f.Names)
- }
-}
-
-func (check *Checker) bound(x ast.Expr) Type {
- // A type set literal of the form ~T and A|B may only appear as constraint;
- // embed it in an implicit interface so that only interface type-checking
- // needs to take care of such type expressions.
- wrap := false
- switch op := x.(type) {
- case *ast.UnaryExpr:
- wrap = op.Op == token.TILDE
- case *ast.BinaryExpr:
- wrap = op.Op == token.OR
- }
- if wrap {
- x = &ast.InterfaceType{Methods: &ast.FieldList{List: []*ast.Field{{Type: x}}}}
- t := check.typ(x)
- // mark t as implicit interface if all went well
- if t, _ := t.(*Interface); t != nil {
- t.implicit = true
- }
- return t
- }
- return check.typ(x)
-}
-
-func (check *Checker) declareTypeParams(tparams []*TypeParam, names []*ast.Ident) []*TypeParam {
- // Use Typ[Invalid] for the type constraint to ensure that a type
- // is present even if the actual constraint has not been assigned
- // yet.
- // TODO(gri) Need to systematically review all uses of type parameter
- // constraints to make sure we don't rely on them if they
- // are not properly set yet.
- for _, name := range names {
- tname := NewTypeName(name.Pos(), check.pkg, name.Name, nil)
- tpar := check.newTypeParam(tname, Typ[Invalid]) // assigns type to tpar as a side-effect
- check.declare(check.scope, name, tname, check.scope.pos) // TODO(gri) check scope position
- tparams = append(tparams, tpar)
- }
-
- if trace && len(names) > 0 {
- check.trace(names[0].Pos(), "type params = %v", tparams[len(tparams)-len(names):])
- }
-
- return tparams
-}
-
-func (check *Checker) collectMethods(obj *TypeName) {
- // get associated methods
- // (Checker.collectObjects only collects methods with non-blank names;
- // Checker.resolveBaseTypeName ensures that obj is not an alias name
- // if it has attached methods.)
- methods := check.methods[obj]
- if methods == nil {
- return
- }
- delete(check.methods, obj)
- assert(!check.objMap[obj].tdecl.Assign.IsValid()) // don't use TypeName.IsAlias (requires fully set up object)
-
- // use an objset to check for name conflicts
- var mset objset
-
- // spec: "If the base type is a struct type, the non-blank method
- // and field names must be distinct."
- base, _ := obj.typ.(*Named) // shouldn't fail but be conservative
- if base != nil {
- assert(base.TypeArgs().Len() == 0) // collectMethods should not be called on an instantiated type
-
- // See issue #52529: we must delay the expansion of underlying here, as
- // base may not be fully set-up.
- check.later(func() {
- check.checkFieldUniqueness(base)
- }).describef(obj, "verifying field uniqueness for %v", base)
-
- // Checker.Files may be called multiple times; additional package files
- // may add methods to already type-checked types. Add pre-existing methods
- // so that we can detect redeclarations.
- for i := 0; i < base.NumMethods(); i++ {
- m := base.Method(i)
- assert(m.name != "_")
- assert(mset.insert(m) == nil)
- }
- }
-
- // add valid methods
- for _, m := range methods {
- // spec: "For a base type, the non-blank names of methods bound
- // to it must be unique."
- assert(m.name != "_")
- if alt := mset.insert(m); alt != nil {
- if alt.Pos().IsValid() {
- check.errorf(m, DuplicateMethod, "method %s.%s already declared at %s", obj.Name(), m.name, alt.Pos())
- } else {
- check.errorf(m, DuplicateMethod, "method %s.%s already declared", obj.Name(), m.name)
- }
- continue
- }
-
- if base != nil {
- base.AddMethod(m)
- }
- }
-}
-
-func (check *Checker) checkFieldUniqueness(base *Named) {
- if t, _ := base.under().(*Struct); t != nil {
- var mset objset
- for i := 0; i < base.NumMethods(); i++ {
- m := base.Method(i)
- assert(m.name != "_")
- assert(mset.insert(m) == nil)
- }
-
- // Check that any non-blank field names of base are distinct from its
- // method names.
- for _, fld := range t.fields {
- if fld.name != "_" {
- if alt := mset.insert(fld); alt != nil {
- // Struct fields should already be unique, so we should only
- // encounter an alternate via collision with a method name.
- _ = alt.(*Func)
-
- // For historical consistency, we report the primary error on the
- // method, and the alt decl on the field.
- check.errorf(alt, DuplicateFieldAndMethod, "field and method with the same name %s", fld.name)
- check.reportAltDecl(fld)
- }
- }
- }
- }
-}
-
-func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
- assert(obj.typ == nil)
-
- // func declarations cannot use iota
- assert(check.iota == nil)
-
- sig := new(Signature)
- obj.typ = sig // guard against cycles
-
- // Avoid cycle error when referring to method while type-checking the signature.
- // This avoids a nuisance in the best case (non-parameterized receiver type) and
- // since the method is not a type, we get an error. If we have a parameterized
- // receiver type, instantiating the receiver type leads to the instantiation of
- // its methods, and we don't want a cycle error in that case.
- // TODO(gri) review if this is correct and/or whether we still need this?
- saved := obj.color_
- obj.color_ = black
- fdecl := decl.fdecl
- check.funcType(sig, fdecl.Recv, fdecl.Type)
- obj.color_ = saved
-
- if fdecl.Type.TypeParams.NumFields() > 0 && fdecl.Body == nil {
- check.softErrorf(fdecl.Name, BadDecl, "generic function is missing function body")
- }
-
- // function body must be type-checked after global declarations
- // (functions implemented elsewhere have no body)
- if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
- check.later(func() {
- check.funcBody(decl, obj.name, sig, fdecl.Body, nil)
- }).describef(obj, "func %s", obj.name)
- }
-}
-
-func (check *Checker) declStmt(d ast.Decl) {
- pkg := check.pkg
-
- check.walkDecl(d, func(d decl) {
- switch d := d.(type) {
- case constDecl:
- top := len(check.delayed)
-
- // declare all constants
- lhs := make([]*Const, len(d.spec.Names))
- for i, name := range d.spec.Names {
- obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(d.iota)))
- lhs[i] = obj
-
- var init ast.Expr
- if i < len(d.init) {
- init = d.init[i]
- }
-
- check.constDecl(obj, d.typ, init, d.inherited)
- }
-
- // process function literals in init expressions before scope changes
- check.processDelayed(top)
-
- // spec: "The scope of a constant or variable identifier declared
- // inside a function begins at the end of the ConstSpec or VarSpec
- // (ShortVarDecl for short variable declarations) and ends at the
- // end of the innermost containing block."
- scopePos := d.spec.End()
- for i, name := range d.spec.Names {
- check.declare(check.scope, name, lhs[i], scopePos)
- }
-
- case varDecl:
- top := len(check.delayed)
-
- lhs0 := make([]*Var, len(d.spec.Names))
- for i, name := range d.spec.Names {
- lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil)
- }
-
- // initialize all variables
- for i, obj := range lhs0 {
- var lhs []*Var
- var init ast.Expr
- switch len(d.spec.Values) {
- case len(d.spec.Names):
- // lhs and rhs match
- init = d.spec.Values[i]
- case 1:
- // rhs is expected to be a multi-valued expression
- lhs = lhs0
- init = d.spec.Values[0]
- default:
- if i < len(d.spec.Values) {
- init = d.spec.Values[i]
- }
- }
- check.varDecl(obj, lhs, d.spec.Type, init)
- if len(d.spec.Values) == 1 {
- // If we have a single lhs variable we are done either way.
- // If we have a single rhs expression, it must be a multi-
- // valued expression, in which case handling the first lhs
- // variable will cause all lhs variables to have a type
- // assigned, and we are done as well.
- if debug {
- for _, obj := range lhs0 {
- assert(obj.typ != nil)
- }
- }
- break
- }
- }
-
- // process function literals in init expressions before scope changes
- check.processDelayed(top)
-
- // declare all variables
- // (only at this point are the variable scopes (parents) set)
- scopePos := d.spec.End() // see constant declarations
- for i, name := range d.spec.Names {
- // see constant declarations
- check.declare(check.scope, name, lhs0[i], scopePos)
- }
-
- case typeDecl:
- obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil)
- // spec: "The scope of a type identifier declared inside a function
- // begins at the identifier in the TypeSpec and ends at the end of
- // the innermost containing block."
- scopePos := d.spec.Name.Pos()
- check.declare(check.scope, d.spec.Name, obj, scopePos)
- // mark and unmark type before calling typeDecl; its type is still nil (see Checker.objDecl)
- obj.setColor(grey + color(check.push(obj)))
- check.typeDecl(obj, d.spec, nil)
- check.pop().setColor(black)
- default:
- check.errorf(d.node(), InvalidSyntaxTree, "unknown ast.Decl node %T", d.node())
- }
- })
-}
diff --git a/contrib/go/_std_1.20/src/go/types/errors.go b/contrib/go/_std_1.20/src/go/types/errors.go
deleted file mode 100644
index b52019ddf5..0000000000
--- a/contrib/go/_std_1.20/src/go/types/errors.go
+++ /dev/null
@@ -1,390 +0,0 @@
-// Copyright 2012 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.
-
-// This file implements various error reporters.
-
-package types
-
-import (
- "bytes"
- "fmt"
- "go/ast"
- "go/token"
- . "internal/types/errors"
- "runtime"
- "strconv"
- "strings"
-)
-
-func assert(p bool) {
- if !p {
- msg := "assertion failed"
- // Include information about the assertion location. Due to panic recovery,
- // this location is otherwise buried in the middle of the panicking stack.
- if _, file, line, ok := runtime.Caller(1); ok {
- msg = fmt.Sprintf("%s:%d: %s", file, line, msg)
- }
- panic(msg)
- }
-}
-
-func unreachable() {
- panic("unreachable")
-}
-
-// An error_ represents a type-checking error.
-// To report an error_, call Checker.report.
-type error_ struct {
- desc []errorDesc
- code Code
- soft bool // TODO(gri) eventually determine this from an error code
-}
-
-// An errorDesc describes part of a type-checking error.
-type errorDesc struct {
- posn positioner
- format string
- args []interface{}
-}
-
-func (err *error_) empty() bool {
- return err.desc == nil
-}
-
-func (err *error_) pos() token.Pos {
- if err.empty() {
- return token.NoPos
- }
- return err.desc[0].posn.Pos()
-}
-
-func (err *error_) msg(fset *token.FileSet, qf Qualifier) string {
- if err.empty() {
- return "no error"
- }
- var buf strings.Builder
- for i := range err.desc {
- p := &err.desc[i]
- if i > 0 {
- fmt.Fprint(&buf, "\n\t")
- if p.posn.Pos().IsValid() {
- fmt.Fprintf(&buf, "%s: ", fset.Position(p.posn.Pos()))
- }
- }
- buf.WriteString(sprintf(fset, qf, false, p.format, p.args...))
- }
- return buf.String()
-}
-
-// String is for testing.
-func (err *error_) String() string {
- if err.empty() {
- return "no error"
- }
- return fmt.Sprintf("%d: %s", err.pos(), err.msg(nil, nil))
-}
-
-// errorf adds formatted error information to err.
-// It may be called multiple times to provide additional information.
-func (err *error_) errorf(at token.Pos, format string, args ...interface{}) {
- err.desc = append(err.desc, errorDesc{atPos(at), format, args})
-}
-
-func (check *Checker) qualifier(pkg *Package) string {
- // Qualify the package unless it's the package being type-checked.
- if pkg != check.pkg {
- if check.pkgPathMap == nil {
- check.pkgPathMap = make(map[string]map[string]bool)
- check.seenPkgMap = make(map[*Package]bool)
- check.markImports(check.pkg)
- }
- // If the same package name was used by multiple packages, display the full path.
- if len(check.pkgPathMap[pkg.name]) > 1 {
- return strconv.Quote(pkg.path)
- }
- return pkg.name
- }
- return ""
-}
-
-// markImports recursively walks pkg and its imports, to record unique import
-// paths in pkgPathMap.
-func (check *Checker) markImports(pkg *Package) {
- if check.seenPkgMap[pkg] {
- return
- }
- check.seenPkgMap[pkg] = true
-
- forName, ok := check.pkgPathMap[pkg.name]
- if !ok {
- forName = make(map[string]bool)
- check.pkgPathMap[pkg.name] = forName
- }
- forName[pkg.path] = true
-
- for _, imp := range pkg.imports {
- check.markImports(imp)
- }
-}
-
-// check may be nil.
-func (check *Checker) sprintf(format string, args ...any) string {
- var fset *token.FileSet
- var qf Qualifier
- if check != nil {
- fset = check.fset
- qf = check.qualifier
- }
- return sprintf(fset, qf, false, format, args...)
-}
-
-func sprintf(fset *token.FileSet, qf Qualifier, tpSubscripts bool, format string, args ...any) string {
- for i, arg := range args {
- switch a := arg.(type) {
- case nil:
- arg = "<nil>"
- case operand:
- panic("got operand instead of *operand")
- case *operand:
- arg = operandString(a, qf)
- case token.Pos:
- if fset != nil {
- arg = fset.Position(a).String()
- }
- case ast.Expr:
- arg = ExprString(a)
- case []ast.Expr:
- var buf bytes.Buffer
- buf.WriteByte('[')
- writeExprList(&buf, a)
- buf.WriteByte(']')
- arg = buf.String()
- case Object:
- arg = ObjectString(a, qf)
- case Type:
- var buf bytes.Buffer
- w := newTypeWriter(&buf, qf)
- w.tpSubscripts = tpSubscripts
- w.typ(a)
- arg = buf.String()
- case []Type:
- var buf bytes.Buffer
- w := newTypeWriter(&buf, qf)
- w.tpSubscripts = tpSubscripts
- buf.WriteByte('[')
- for i, x := range a {
- if i > 0 {
- buf.WriteString(", ")
- }
- w.typ(x)
- }
- buf.WriteByte(']')
- arg = buf.String()
- case []*TypeParam:
- var buf bytes.Buffer
- w := newTypeWriter(&buf, qf)
- w.tpSubscripts = tpSubscripts
- buf.WriteByte('[')
- for i, x := range a {
- if i > 0 {
- buf.WriteString(", ")
- }
- w.typ(x)
- }
- buf.WriteByte(']')
- arg = buf.String()
- }
- args[i] = arg
- }
- return fmt.Sprintf(format, args...)
-}
-
-func (check *Checker) trace(pos token.Pos, format string, args ...any) {
- fmt.Printf("%s:\t%s%s\n",
- check.fset.Position(pos),
- strings.Repeat(". ", check.indent),
- sprintf(check.fset, check.qualifier, true, format, args...),
- )
-}
-
-// dump is only needed for debugging
-func (check *Checker) dump(format string, args ...any) {
- fmt.Println(sprintf(check.fset, check.qualifier, true, format, args...))
-}
-
-// Report records the error pointed to by errp, setting check.firstError if
-// necessary.
-func (check *Checker) report(errp *error_) {
- if errp.empty() {
- panic("empty error details")
- }
-
- msg := errp.msg(check.fset, check.qualifier)
- switch errp.code {
- case InvalidSyntaxTree:
- msg = "invalid AST: " + msg
- case 0:
- panic("no error code provided")
- }
-
- span := spanOf(errp.desc[0].posn)
- e := Error{
- Fset: check.fset,
- Pos: span.pos,
- Msg: msg,
- Soft: errp.soft,
- go116code: errp.code,
- go116start: span.start,
- go116end: span.end,
- }
-
- // Cheap trick: Don't report errors with messages containing
- // "invalid operand" or "invalid type" as those tend to be
- // follow-on errors which don't add useful information. Only
- // exclude them if these strings are not at the beginning,
- // and only if we have at least one error already reported.
- isInvalidErr := strings.Index(e.Msg, "invalid operand") > 0 || strings.Index(e.Msg, "invalid type") > 0
- if check.firstErr != nil && isInvalidErr {
- return
- }
-
- e.Msg = stripAnnotations(e.Msg)
- if check.errpos != nil {
- // If we have an internal error and the errpos override is set, use it to
- // augment our error positioning.
- // TODO(rFindley) we may also want to augment the error message and refer
- // to the position (pos) in the original expression.
- span := spanOf(check.errpos)
- e.Pos = span.pos
- e.go116start = span.start
- e.go116end = span.end
- }
- err := e
-
- if check.firstErr == nil {
- check.firstErr = err
- }
-
- if trace {
- pos := e.Pos
- msg := e.Msg
- check.trace(pos, "ERROR: %s", msg)
- }
-
- f := check.conf.Error
- if f == nil {
- panic(bailout{}) // report only first error
- }
- f(err)
-}
-
-const (
- invalidArg = "invalid argument: "
- invalidOp = "invalid operation: "
-)
-
-// newErrorf creates a new error_ for later reporting with check.report.
-func newErrorf(at positioner, code Code, format string, args ...any) *error_ {
- return &error_{
- desc: []errorDesc{{at, format, args}},
- code: code,
- }
-}
-
-func (check *Checker) error(at positioner, code Code, msg string) {
- check.report(newErrorf(at, code, msg))
-}
-
-func (check *Checker) errorf(at positioner, code Code, format string, args ...any) {
- check.report(newErrorf(at, code, format, args...))
-}
-
-func (check *Checker) softErrorf(at positioner, code Code, format string, args ...any) {
- err := newErrorf(at, code, format, args...)
- err.soft = true
- check.report(err)
-}
-
-func (check *Checker) versionErrorf(at positioner, goVersion string, format string, args ...interface{}) {
- msg := check.sprintf(format, args...)
- var err *error_
- err = newErrorf(at, UnsupportedFeature, "%s requires %s or later", msg, goVersion)
- check.report(err)
-}
-
-// The positioner interface is used to extract the position of type-checker
-// errors.
-type positioner interface {
- Pos() token.Pos
-}
-
-// posSpan holds a position range along with a highlighted position within that
-// range. This is used for positioning errors, with pos by convention being the
-// first position in the source where the error is known to exist, and start
-// and end defining the full span of syntax being considered when the error was
-// detected. Invariant: start <= pos < end || start == pos == end.
-type posSpan struct {
- start, pos, end token.Pos
-}
-
-func (e posSpan) Pos() token.Pos {
- return e.pos
-}
-
-// inNode creates a posSpan for the given node.
-// Invariant: node.Pos() <= pos < node.End() (node.End() is the position of the
-// first byte after node within the source).
-func inNode(node ast.Node, pos token.Pos) posSpan {
- start, end := node.Pos(), node.End()
- if debug {
- assert(start <= pos && pos < end)
- }
- return posSpan{start, pos, end}
-}
-
-// atPos wraps a token.Pos to implement the positioner interface.
-type atPos token.Pos
-
-func (s atPos) Pos() token.Pos {
- return token.Pos(s)
-}
-
-// spanOf extracts an error span from the given positioner. By default this is
-// the trivial span starting and ending at pos, but this span is expanded when
-// the argument naturally corresponds to a span of source code.
-func spanOf(at positioner) posSpan {
- switch x := at.(type) {
- case nil:
- panic("nil positioner")
- case posSpan:
- return x
- case ast.Node:
- pos := x.Pos()
- return posSpan{pos, pos, x.End()}
- case *operand:
- if x.expr != nil {
- pos := x.Pos()
- return posSpan{pos, pos, x.expr.End()}
- }
- return posSpan{token.NoPos, token.NoPos, token.NoPos}
- default:
- pos := at.Pos()
- return posSpan{pos, pos, pos}
- }
-}
-
-// stripAnnotations removes internal (type) annotations from s.
-func stripAnnotations(s string) string {
- var buf strings.Builder
- for _, r := range s {
- // strip #'s and subscript digits
- if r < '₀' || '₀'+10 <= r { // '₀' == U+2080
- buf.WriteRune(r)
- }
- }
- if buf.Len() < len(s) {
- return buf.String()
- }
- return s
-}
diff --git a/contrib/go/_std_1.20/src/go/types/eval.go b/contrib/go/_std_1.20/src/go/types/eval.go
deleted file mode 100644
index 084f746fe6..0000000000
--- a/contrib/go/_std_1.20/src/go/types/eval.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2013 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 types
-
-import (
- "fmt"
- "go/ast"
- "go/parser"
- "go/token"
-)
-
-// Eval returns the type and, if constant, the value for the
-// expression expr, evaluated at position pos of package pkg,
-// which must have been derived from type-checking an AST with
-// complete position information relative to the provided file
-// set.
-//
-// The meaning of the parameters fset, pkg, and pos is the
-// same as in CheckExpr. An error is returned if expr cannot
-// be parsed successfully, or the resulting expr AST cannot be
-// type-checked.
-func Eval(fset *token.FileSet, pkg *Package, pos token.Pos, expr string) (_ TypeAndValue, err error) {
- // parse expressions
- node, err := parser.ParseExprFrom(fset, "eval", expr, 0)
- if err != nil {
- return TypeAndValue{}, err
- }
-
- info := &Info{
- Types: make(map[ast.Expr]TypeAndValue),
- }
- err = CheckExpr(fset, pkg, pos, node, info)
- return info.Types[node], err
-}
-
-// CheckExpr type checks the expression expr as if it had appeared at position
-// pos of package pkg. Type information about the expression is recorded in
-// info. The expression may be an identifier denoting an uninstantiated generic
-// function or type.
-//
-// If pkg == nil, the Universe scope is used and the provided
-// position pos is ignored. If pkg != nil, and pos is invalid,
-// the package scope is used. Otherwise, pos must belong to the
-// package.
-//
-// An error is returned if pos is not within the package or
-// if the node cannot be type-checked.
-//
-// Note: Eval and CheckExpr should not be used instead of running Check
-// to compute types and values, but in addition to Check, as these
-// functions ignore the context in which an expression is used (e.g., an
-// assignment). Thus, top-level untyped constants will return an
-// untyped type rather then the respective context-specific type.
-func CheckExpr(fset *token.FileSet, pkg *Package, pos token.Pos, expr ast.Expr, info *Info) (err error) {
- // determine scope
- var scope *Scope
- if pkg == nil {
- scope = Universe
- pos = token.NoPos
- } else if !pos.IsValid() {
- scope = pkg.scope
- } else {
- // The package scope extent (position information) may be
- // incorrect (files spread across a wide range of fset
- // positions) - ignore it and just consider its children
- // (file scopes).
- for _, fscope := range pkg.scope.children {
- if scope = fscope.Innermost(pos); scope != nil {
- break
- }
- }
- if scope == nil || debug {
- s := scope
- for s != nil && s != pkg.scope {
- s = s.parent
- }
- // s == nil || s == pkg.scope
- if s == nil {
- return fmt.Errorf("no position %s found in package %s", fset.Position(pos), pkg.name)
- }
- }
- }
-
- // initialize checker
- check := NewChecker(nil, fset, pkg, info)
- check.scope = scope
- check.pos = pos
- defer check.handleBailout(&err)
-
- // evaluate node
- var x operand
- check.rawExpr(&x, expr, nil, true) // allow generic expressions
- check.processDelayed(0) // incl. all functions
- check.recordUntyped()
-
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/go/types/expr.go b/contrib/go/_std_1.20/src/go/types/expr.go
deleted file mode 100644
index aa90145b36..0000000000
--- a/contrib/go/_std_1.20/src/go/types/expr.go
+++ /dev/null
@@ -1,1826 +0,0 @@
-// Copyright 2012 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.
-
-// This file implements typechecking of expressions.
-
-package types
-
-import (
- "fmt"
- "go/ast"
- "go/constant"
- "go/internal/typeparams"
- "go/token"
- . "internal/types/errors"
- "math"
-)
-
-/*
-Basic algorithm:
-
-Expressions are checked recursively, top down. Expression checker functions
-are generally of the form:
-
- func f(x *operand, e *ast.Expr, ...)
-
-where e is the expression to be checked, and x is the result of the check.
-The check performed by f may fail in which case x.mode == invalid, and
-related error messages will have been issued by f.
-
-If a hint argument is present, it is the composite literal element type
-of an outer composite literal; it is used to type-check composite literal
-elements that have no explicit type specification in the source
-(e.g.: []T{{...}, {...}}, the hint is the type T in this case).
-
-All expressions are checked via rawExpr, which dispatches according
-to expression kind. Upon returning, rawExpr is recording the types and
-constant values for all expressions that have an untyped type (those types
-may change on the way up in the expression tree). Usually these are constants,
-but the results of comparisons or non-constant shifts of untyped constants
-may also be untyped, but not constant.
-
-Untyped expressions may eventually become fully typed (i.e., not untyped),
-typically when the value is assigned to a variable, or is used otherwise.
-The updateExprType method is used to record this final type and update
-the recorded types: the type-checked expression tree is again traversed down,
-and the new type is propagated as needed. Untyped constant expression values
-that become fully typed must now be representable by the full type (constant
-sub-expression trees are left alone except for their roots). This mechanism
-ensures that a client sees the actual (run-time) type an untyped value would
-have. It also permits type-checking of lhs shift operands "as if the shift
-were not present": when updateExprType visits an untyped lhs shift operand
-and assigns it it's final type, that type must be an integer type, and a
-constant lhs must be representable as an integer.
-
-When an expression gets its final type, either on the way out from rawExpr,
-on the way down in updateExprType, or at the end of the type checker run,
-the type (and constant value, if any) is recorded via Info.Types, if present.
-*/
-
-type opPredicates map[token.Token]func(Type) bool
-
-var unaryOpPredicates opPredicates
-
-func init() {
- // Setting unaryOpPredicates in init avoids declaration cycles.
- unaryOpPredicates = opPredicates{
- token.ADD: allNumeric,
- token.SUB: allNumeric,
- token.XOR: allInteger,
- token.NOT: allBoolean,
- }
-}
-
-func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool {
- if pred := m[op]; pred != nil {
- if !pred(x.typ) {
- check.errorf(x, UndefinedOp, invalidOp+"operator %s not defined on %s", op, x)
- return false
- }
- } else {
- check.errorf(x, InvalidSyntaxTree, "unknown operator %s", op)
- return false
- }
- return true
-}
-
-// overflow checks that the constant x is representable by its type.
-// For untyped constants, it checks that the value doesn't become
-// arbitrarily large.
-func (check *Checker) overflow(x *operand, opPos token.Pos) {
- assert(x.mode == constant_)
-
- if x.val.Kind() == constant.Unknown {
- // TODO(gri) We should report exactly what went wrong. At the
- // moment we don't have the (go/constant) API for that.
- // See also TODO in go/constant/value.go.
- check.error(atPos(opPos), InvalidConstVal, "constant result is not representable")
- return
- }
-
- // Typed constants must be representable in
- // their type after each constant operation.
- // x.typ cannot be a type parameter (type
- // parameters cannot be constant types).
- if isTyped(x.typ) {
- check.representable(x, under(x.typ).(*Basic))
- return
- }
-
- // Untyped integer values must not grow arbitrarily.
- const prec = 512 // 512 is the constant precision
- if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
- op := opName(x.expr)
- if op != "" {
- op += " "
- }
- check.errorf(atPos(opPos), InvalidConstVal, "constant %soverflow", op)
- x.val = constant.MakeUnknown()
- }
-}
-
-// opName returns the name of the operation if x is an operation
-// that might overflow; otherwise it returns the empty string.
-func opName(e ast.Expr) string {
- switch e := e.(type) {
- case *ast.BinaryExpr:
- if int(e.Op) < len(op2str2) {
- return op2str2[e.Op]
- }
- case *ast.UnaryExpr:
- if int(e.Op) < len(op2str1) {
- return op2str1[e.Op]
- }
- }
- return ""
-}
-
-var op2str1 = [...]string{
- token.XOR: "bitwise complement",
-}
-
-// This is only used for operations that may cause overflow.
-var op2str2 = [...]string{
- token.ADD: "addition",
- token.SUB: "subtraction",
- token.XOR: "bitwise XOR",
- token.MUL: "multiplication",
- token.SHL: "shift",
-}
-
-// If typ is a type parameter, underIs returns the result of typ.underIs(f).
-// Otherwise, underIs returns the result of f(under(typ)).
-func underIs(typ Type, f func(Type) bool) bool {
- if tpar, _ := typ.(*TypeParam); tpar != nil {
- return tpar.underIs(f)
- }
- return f(under(typ))
-}
-
-// The unary expression e may be nil. It's passed in for better error messages only.
-func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
- check.expr(x, e.X)
- if x.mode == invalid {
- return
- }
- switch e.Op {
- case token.AND:
- // spec: "As an exception to the addressability
- // requirement x may also be a composite literal."
- if _, ok := unparen(e.X).(*ast.CompositeLit); !ok && x.mode != variable {
- check.errorf(x, UnaddressableOperand, invalidOp+"cannot take address of %s", x)
- x.mode = invalid
- return
- }
- x.mode = value
- x.typ = &Pointer{base: x.typ}
- return
-
- case token.ARROW:
- u := coreType(x.typ)
- if u == nil {
- check.errorf(x, InvalidReceive, invalidOp+"cannot receive from %s (no core type)", x)
- x.mode = invalid
- return
- }
- ch, _ := u.(*Chan)
- if ch == nil {
- check.errorf(x, InvalidReceive, invalidOp+"cannot receive from non-channel %s", x)
- x.mode = invalid
- return
- }
- if ch.dir == SendOnly {
- check.errorf(x, InvalidReceive, invalidOp+"cannot receive from send-only channel %s", x)
- x.mode = invalid
- return
- }
-
- x.mode = commaok
- x.typ = ch.elem
- check.hasCallOrRecv = true
- return
-
- case token.TILDE:
- // Provide a better error position and message than what check.op below could do.
- check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint")
- x.mode = invalid
- return
- }
-
- if !check.op(unaryOpPredicates, x, e.Op) {
- x.mode = invalid
- return
- }
-
- if x.mode == constant_ {
- if x.val.Kind() == constant.Unknown {
- // nothing to do (and don't cause an error below in the overflow check)
- return
- }
- var prec uint
- if isUnsigned(x.typ) {
- prec = uint(check.conf.sizeof(x.typ) * 8)
- }
- x.val = constant.UnaryOp(e.Op, x.val, prec)
- x.expr = e
- check.overflow(x, x.Pos())
- return
- }
-
- x.mode = value
- // x.typ remains unchanged
-}
-
-func isShift(op token.Token) bool {
- return op == token.SHL || op == token.SHR
-}
-
-func isComparison(op token.Token) bool {
- // Note: tokens are not ordered well to make this much easier
- switch op {
- case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ:
- return true
- }
- return false
-}
-
-func fitsFloat32(x constant.Value) bool {
- f32, _ := constant.Float32Val(x)
- f := float64(f32)
- return !math.IsInf(f, 0)
-}
-
-func roundFloat32(x constant.Value) constant.Value {
- f32, _ := constant.Float32Val(x)
- f := float64(f32)
- if !math.IsInf(f, 0) {
- return constant.MakeFloat64(f)
- }
- return nil
-}
-
-func fitsFloat64(x constant.Value) bool {
- f, _ := constant.Float64Val(x)
- return !math.IsInf(f, 0)
-}
-
-func roundFloat64(x constant.Value) constant.Value {
- f, _ := constant.Float64Val(x)
- if !math.IsInf(f, 0) {
- return constant.MakeFloat64(f)
- }
- return nil
-}
-
-// representableConst reports whether x can be represented as
-// value of the given basic type and for the configuration
-// provided (only needed for int/uint sizes).
-//
-// If rounded != nil, *rounded is set to the rounded value of x for
-// representable floating-point and complex values, and to an Int
-// value for integer values; it is left alone otherwise.
-// It is ok to provide the addressof the first argument for rounded.
-//
-// The check parameter may be nil if representableConst is invoked
-// (indirectly) through an exported API call (AssignableTo, ConvertibleTo)
-// because we don't need the Checker's config for those calls.
-func representableConst(x constant.Value, check *Checker, typ *Basic, rounded *constant.Value) bool {
- if x.Kind() == constant.Unknown {
- return true // avoid follow-up errors
- }
-
- var conf *Config
- if check != nil {
- conf = check.conf
- }
-
- switch {
- case isInteger(typ):
- x := constant.ToInt(x)
- if x.Kind() != constant.Int {
- return false
- }
- if rounded != nil {
- *rounded = x
- }
- if x, ok := constant.Int64Val(x); ok {
- switch typ.kind {
- case Int:
- var s = uint(conf.sizeof(typ)) * 8
- return int64(-1)<<(s-1) <= x && x <= int64(1)<<(s-1)-1
- case Int8:
- const s = 8
- return -1<<(s-1) <= x && x <= 1<<(s-1)-1
- case Int16:
- const s = 16
- return -1<<(s-1) <= x && x <= 1<<(s-1)-1
- case Int32:
- const s = 32
- return -1<<(s-1) <= x && x <= 1<<(s-1)-1
- case Int64, UntypedInt:
- return true
- case Uint, Uintptr:
- if s := uint(conf.sizeof(typ)) * 8; s < 64 {
- return 0 <= x && x <= int64(1)<<s-1
- }
- return 0 <= x
- case Uint8:
- const s = 8
- return 0 <= x && x <= 1<<s-1
- case Uint16:
- const s = 16
- return 0 <= x && x <= 1<<s-1
- case Uint32:
- const s = 32
- return 0 <= x && x <= 1<<s-1
- case Uint64:
- return 0 <= x
- default:
- unreachable()
- }
- }
- // x does not fit into int64
- switch n := constant.BitLen(x); typ.kind {
- case Uint, Uintptr:
- var s = uint(conf.sizeof(typ)) * 8
- return constant.Sign(x) >= 0 && n <= int(s)
- case Uint64:
- return constant.Sign(x) >= 0 && n <= 64
- case UntypedInt:
- return true
- }
-
- case isFloat(typ):
- x := constant.ToFloat(x)
- if x.Kind() != constant.Float {
- return false
- }
- switch typ.kind {
- case Float32:
- if rounded == nil {
- return fitsFloat32(x)
- }
- r := roundFloat32(x)
- if r != nil {
- *rounded = r
- return true
- }
- case Float64:
- if rounded == nil {
- return fitsFloat64(x)
- }
- r := roundFloat64(x)
- if r != nil {
- *rounded = r
- return true
- }
- case UntypedFloat:
- return true
- default:
- unreachable()
- }
-
- case isComplex(typ):
- x := constant.ToComplex(x)
- if x.Kind() != constant.Complex {
- return false
- }
- switch typ.kind {
- case Complex64:
- if rounded == nil {
- return fitsFloat32(constant.Real(x)) && fitsFloat32(constant.Imag(x))
- }
- re := roundFloat32(constant.Real(x))
- im := roundFloat32(constant.Imag(x))
- if re != nil && im != nil {
- *rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
- return true
- }
- case Complex128:
- if rounded == nil {
- return fitsFloat64(constant.Real(x)) && fitsFloat64(constant.Imag(x))
- }
- re := roundFloat64(constant.Real(x))
- im := roundFloat64(constant.Imag(x))
- if re != nil && im != nil {
- *rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
- return true
- }
- case UntypedComplex:
- return true
- default:
- unreachable()
- }
-
- case isString(typ):
- return x.Kind() == constant.String
-
- case isBoolean(typ):
- return x.Kind() == constant.Bool
- }
-
- return false
-}
-
-// representable checks that a constant operand is representable in the given
-// basic type.
-func (check *Checker) representable(x *operand, typ *Basic) {
- v, code := check.representation(x, typ)
- if code != 0 {
- check.invalidConversion(code, x, typ)
- x.mode = invalid
- return
- }
- assert(v != nil)
- x.val = v
-}
-
-// representation returns the representation of the constant operand x as the
-// basic type typ.
-//
-// If no such representation is possible, it returns a non-zero error code.
-func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, Code) {
- assert(x.mode == constant_)
- v := x.val
- if !representableConst(x.val, check, typ, &v) {
- if isNumeric(x.typ) && isNumeric(typ) {
- // numeric conversion : error msg
- //
- // integer -> integer : overflows
- // integer -> float : overflows (actually not possible)
- // float -> integer : truncated
- // float -> float : overflows
- //
- if !isInteger(x.typ) && isInteger(typ) {
- return nil, TruncatedFloat
- } else {
- return nil, NumericOverflow
- }
- }
- return nil, InvalidConstVal
- }
- return v, 0
-}
-
-func (check *Checker) invalidConversion(code Code, x *operand, target Type) {
- msg := "cannot convert %s to type %s"
- switch code {
- case TruncatedFloat:
- msg = "%s truncated to %s"
- case NumericOverflow:
- msg = "%s overflows %s"
- }
- check.errorf(x, code, msg, x, target)
-}
-
-// updateExprType updates the type of x to typ and invokes itself
-// recursively for the operands of x, depending on expression kind.
-// If typ is still an untyped and not the final type, updateExprType
-// only updates the recorded untyped type for x and possibly its
-// operands. Otherwise (i.e., typ is not an untyped type anymore,
-// or it is the final type for x), the type and value are recorded.
-// Also, if x is a constant, it must be representable as a value of typ,
-// and if x is the (formerly untyped) lhs operand of a non-constant
-// shift, it must be an integer value.
-func (check *Checker) updateExprType(x ast.Expr, typ Type, final bool) {
- check.updateExprType0(nil, x, typ, final)
-}
-
-func (check *Checker) updateExprType0(parent, x ast.Expr, typ Type, final bool) {
- old, found := check.untyped[x]
- if !found {
- return // nothing to do
- }
-
- // update operands of x if necessary
- switch x := x.(type) {
- case *ast.BadExpr,
- *ast.FuncLit,
- *ast.CompositeLit,
- *ast.IndexExpr,
- *ast.SliceExpr,
- *ast.TypeAssertExpr,
- *ast.StarExpr,
- *ast.KeyValueExpr,
- *ast.ArrayType,
- *ast.StructType,
- *ast.FuncType,
- *ast.InterfaceType,
- *ast.MapType,
- *ast.ChanType:
- // These expression are never untyped - nothing to do.
- // The respective sub-expressions got their final types
- // upon assignment or use.
- if debug {
- check.dump("%v: found old type(%s): %s (new: %s)", x.Pos(), x, old.typ, typ)
- unreachable()
- }
- return
-
- case *ast.CallExpr:
- // Resulting in an untyped constant (e.g., built-in complex).
- // The respective calls take care of calling updateExprType
- // for the arguments if necessary.
-
- case *ast.Ident, *ast.BasicLit, *ast.SelectorExpr:
- // An identifier denoting a constant, a constant literal,
- // or a qualified identifier (imported untyped constant).
- // No operands to take care of.
-
- case *ast.ParenExpr:
- check.updateExprType0(x, x.X, typ, final)
-
- case *ast.UnaryExpr:
- // If x is a constant, the operands were constants.
- // The operands don't need to be updated since they
- // never get "materialized" into a typed value. If
- // left in the untyped map, they will be processed
- // at the end of the type check.
- if old.val != nil {
- break
- }
- check.updateExprType0(x, x.X, typ, final)
-
- case *ast.BinaryExpr:
- if old.val != nil {
- break // see comment for unary expressions
- }
- if isComparison(x.Op) {
- // The result type is independent of operand types
- // and the operand types must have final types.
- } else if isShift(x.Op) {
- // The result type depends only on lhs operand.
- // The rhs type was updated when checking the shift.
- check.updateExprType0(x, x.X, typ, final)
- } else {
- // The operand types match the result type.
- check.updateExprType0(x, x.X, typ, final)
- check.updateExprType0(x, x.Y, typ, final)
- }
-
- default:
- unreachable()
- }
-
- // If the new type is not final and still untyped, just
- // update the recorded type.
- if !final && isUntyped(typ) {
- old.typ = under(typ).(*Basic)
- check.untyped[x] = old
- return
- }
-
- // Otherwise we have the final (typed or untyped type).
- // Remove it from the map of yet untyped expressions.
- delete(check.untyped, x)
-
- if old.isLhs {
- // If x is the lhs of a shift, its final type must be integer.
- // We already know from the shift check that it is representable
- // as an integer if it is a constant.
- if !allInteger(typ) {
- check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
- return
- }
- // Even if we have an integer, if the value is a constant we
- // still must check that it is representable as the specific
- // int type requested (was issue #22969). Fall through here.
- }
- if old.val != nil {
- // If x is a constant, it must be representable as a value of typ.
- c := operand{old.mode, x, old.typ, old.val, 0}
- check.convertUntyped(&c, typ)
- if c.mode == invalid {
- return
- }
- }
-
- // Everything's fine, record final type and value for x.
- check.recordTypeAndValue(x, old.mode, typ, old.val)
-}
-
-// updateExprVal updates the value of x to val.
-func (check *Checker) updateExprVal(x ast.Expr, val constant.Value) {
- if info, ok := check.untyped[x]; ok {
- info.val = val
- check.untyped[x] = info
- }
-}
-
-// convertUntyped attempts to set the type of an untyped value to the target type.
-func (check *Checker) convertUntyped(x *operand, target Type) {
- newType, val, code := check.implicitTypeAndValue(x, target)
- if code != 0 {
- t := target
- if !isTypeParam(target) {
- t = safeUnderlying(target)
- }
- check.invalidConversion(code, x, t)
- x.mode = invalid
- return
- }
- if val != nil {
- x.val = val
- check.updateExprVal(x.expr, val)
- }
- if newType != x.typ {
- x.typ = newType
- check.updateExprType(x.expr, newType, false)
- }
-}
-
-// implicitTypeAndValue returns the implicit type of x when used in a context
-// where the target type is expected. If no such implicit conversion is
-// possible, it returns a nil Type and non-zero error code.
-//
-// If x is a constant operand, the returned constant.Value will be the
-// representation of x in this context.
-func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, Code) {
- if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
- return x.typ, nil, 0
- }
-
- if isUntyped(target) {
- // both x and target are untyped
- xkind := x.typ.(*Basic).kind
- tkind := target.(*Basic).kind
- if isNumeric(x.typ) && isNumeric(target) {
- if xkind < tkind {
- return target, nil, 0
- }
- } else if xkind != tkind {
- return nil, nil, InvalidUntypedConversion
- }
- return x.typ, nil, 0
- }
-
- switch u := under(target).(type) {
- case *Basic:
- if x.mode == constant_ {
- v, code := check.representation(x, u)
- if code != 0 {
- return nil, nil, code
- }
- return target, v, code
- }
- // Non-constant untyped values may appear as the
- // result of comparisons (untyped bool), intermediate
- // (delayed-checked) rhs operands of shifts, and as
- // the value nil.
- switch x.typ.(*Basic).kind {
- case UntypedBool:
- if !isBoolean(target) {
- return nil, nil, InvalidUntypedConversion
- }
- case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
- if !isNumeric(target) {
- return nil, nil, InvalidUntypedConversion
- }
- case UntypedString:
- // Non-constant untyped string values are not permitted by the spec and
- // should not occur during normal typechecking passes, but this path is
- // reachable via the AssignableTo API.
- if !isString(target) {
- return nil, nil, InvalidUntypedConversion
- }
- case UntypedNil:
- // Unsafe.Pointer is a basic type that includes nil.
- if !hasNil(target) {
- return nil, nil, InvalidUntypedConversion
- }
- // Preserve the type of nil as UntypedNil: see #13061.
- return Typ[UntypedNil], nil, 0
- default:
- return nil, nil, InvalidUntypedConversion
- }
- case *Interface:
- if isTypeParam(target) {
- if !u.typeSet().underIs(func(u Type) bool {
- if u == nil {
- return false
- }
- t, _, _ := check.implicitTypeAndValue(x, u)
- return t != nil
- }) {
- return nil, nil, InvalidUntypedConversion
- }
- // keep nil untyped (was bug #39755)
- if x.isNil() {
- return Typ[UntypedNil], nil, 0
- }
- break
- }
- // Values must have concrete dynamic types. If the value is nil,
- // keep it untyped (this is important for tools such as go vet which
- // need the dynamic type for argument checking of say, print
- // functions)
- if x.isNil() {
- return Typ[UntypedNil], nil, 0
- }
- // cannot assign untyped values to non-empty interfaces
- if !u.Empty() {
- return nil, nil, InvalidUntypedConversion
- }
- return Default(x.typ), nil, 0
- case *Pointer, *Signature, *Slice, *Map, *Chan:
- if !x.isNil() {
- return nil, nil, InvalidUntypedConversion
- }
- // Keep nil untyped - see comment for interfaces, above.
- return Typ[UntypedNil], nil, 0
- default:
- return nil, nil, InvalidUntypedConversion
- }
- return target, nil, 0
-}
-
-// If switchCase is true, the operator op is ignored.
-func (check *Checker) comparison(x, y *operand, op token.Token, switchCase bool) {
- // Avoid spurious errors if any of the operands has an invalid type (issue #54405).
- if x.typ == Typ[Invalid] || y.typ == Typ[Invalid] {
- x.mode = invalid
- return
- }
-
- if switchCase {
- op = token.EQL
- }
-
- errOp := x // operand for which error is reported, if any
- cause := "" // specific error cause, if any
-
- // spec: "In any comparison, the first operand must be assignable
- // to the type of the second operand, or vice versa."
- code := MismatchedTypes
- ok, _ := x.assignableTo(check, y.typ, nil)
- if !ok {
- ok, _ = y.assignableTo(check, x.typ, nil)
- }
- if !ok {
- // Report the error on the 2nd operand since we only
- // know after seeing the 2nd operand whether we have
- // a type mismatch.
- errOp = y
- cause = check.sprintf("mismatched types %s and %s", x.typ, y.typ)
- goto Error
- }
-
- // check if comparison is defined for operands
- code = UndefinedOp
- switch op {
- case token.EQL, token.NEQ:
- // spec: "The equality operators == and != apply to operands that are comparable."
- switch {
- case x.isNil() || y.isNil():
- // Comparison against nil requires that the other operand type has nil.
- typ := x.typ
- if x.isNil() {
- typ = y.typ
- }
- if !hasNil(typ) {
- // This case should only be possible for "nil == nil".
- // Report the error on the 2nd operand since we only
- // know after seeing the 2nd operand whether we have
- // an invalid comparison.
- errOp = y
- goto Error
- }
-
- case !Comparable(x.typ):
- errOp = x
- cause = check.incomparableCause(x.typ)
- goto Error
-
- case !Comparable(y.typ):
- errOp = y
- cause = check.incomparableCause(y.typ)
- goto Error
- }
-
- case token.LSS, token.LEQ, token.GTR, token.GEQ:
- // spec: The ordering operators <, <=, >, and >= apply to operands that are ordered."
- switch {
- case !allOrdered(x.typ):
- errOp = x
- goto Error
- case !allOrdered(y.typ):
- errOp = y
- goto Error
- }
-
- default:
- unreachable()
- }
-
- // comparison is ok
- if x.mode == constant_ && y.mode == constant_ {
- x.val = constant.MakeBool(constant.Compare(x.val, op, y.val))
- // The operands are never materialized; no need to update
- // their types.
- } else {
- x.mode = value
- // The operands have now their final types, which at run-
- // time will be materialized. Update the expression trees.
- // If the current types are untyped, the materialized type
- // is the respective default type.
- check.updateExprType(x.expr, Default(x.typ), true)
- check.updateExprType(y.expr, Default(y.typ), true)
- }
-
- // spec: "Comparison operators compare two operands and yield
- // an untyped boolean value."
- x.typ = Typ[UntypedBool]
- return
-
-Error:
- // We have an offending operand errOp and possibly an error cause.
- if cause == "" {
- if isTypeParam(x.typ) || isTypeParam(y.typ) {
- // TODO(gri) should report the specific type causing the problem, if any
- if !isTypeParam(x.typ) {
- errOp = y
- }
- cause = check.sprintf("type parameter %s is not comparable with %s", errOp.typ, op)
- } else {
- cause = check.sprintf("operator %s not defined on %s", op, check.kindString(errOp.typ)) // catch-all
- }
- }
- if switchCase {
- check.errorf(x, code, "invalid case %s in switch on %s (%s)", x.expr, y.expr, cause) // error position always at 1st operand
- } else {
- check.errorf(errOp, code, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
- }
- x.mode = invalid
-}
-
-// incomparableCause returns a more specific cause why typ is not comparable.
-// If there is no more specific cause, the result is "".
-func (check *Checker) incomparableCause(typ Type) string {
- switch under(typ).(type) {
- case *Slice, *Signature, *Map:
- return check.kindString(typ) + " can only be compared to nil"
- }
- // see if we can extract a more specific error
- var cause string
- comparable(typ, true, nil, func(format string, args ...interface{}) {
- cause = check.sprintf(format, args...)
- })
- return cause
-}
-
-// kindString returns the type kind as a string.
-func (check *Checker) kindString(typ Type) string {
- switch under(typ).(type) {
- case *Array:
- return "array"
- case *Slice:
- return "slice"
- case *Struct:
- return "struct"
- case *Pointer:
- return "pointer"
- case *Signature:
- return "func"
- case *Interface:
- if isTypeParam(typ) {
- return check.sprintf("type parameter %s", typ)
- }
- return "interface"
- case *Map:
- return "map"
- case *Chan:
- return "chan"
- default:
- return check.sprintf("%s", typ) // catch-all
- }
-}
-
-// If e != nil, it must be the shift expression; it may be nil for non-constant shifts.
-func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
- // TODO(gri) This function seems overly complex. Revisit.
-
- var xval constant.Value
- if x.mode == constant_ {
- xval = constant.ToInt(x.val)
- }
-
- if allInteger(x.typ) || isUntyped(x.typ) && xval != nil && xval.Kind() == constant.Int {
- // The lhs is of integer type or an untyped constant representable
- // as an integer. Nothing to do.
- } else {
- // shift has no chance
- check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
- x.mode = invalid
- return
- }
-
- // spec: "The right operand in a shift expression must have integer type
- // or be an untyped constant representable by a value of type uint."
-
- // Check that constants are representable by uint, but do not convert them
- // (see also issue #47243).
- var yval constant.Value
- if y.mode == constant_ {
- // Provide a good error message for negative shift counts.
- yval = constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
- if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
- check.errorf(y, InvalidShiftCount, invalidOp+"negative shift count %s", y)
- x.mode = invalid
- return
- }
-
- if isUntyped(y.typ) {
- // Caution: Check for representability here, rather than in the switch
- // below, because isInteger includes untyped integers (was bug #43697).
- check.representable(y, Typ[Uint])
- if y.mode == invalid {
- x.mode = invalid
- return
- }
- }
- } else {
- // Check that RHS is otherwise at least of integer type.
- switch {
- case allInteger(y.typ):
- if !allUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
- check.errorf(y, UnsupportedFeature, invalidOp+"signed shift count %s requires go1.13 or later", y)
- x.mode = invalid
- return
- }
- case isUntyped(y.typ):
- // This is incorrect, but preserves pre-existing behavior.
- // See also bug #47410.
- check.convertUntyped(y, Typ[Uint])
- if y.mode == invalid {
- x.mode = invalid
- return
- }
- default:
- check.errorf(y, InvalidShiftCount, invalidOp+"shift count %s must be integer", y)
- x.mode = invalid
- return
- }
- }
-
- if x.mode == constant_ {
- if y.mode == constant_ {
- // if either x or y has an unknown value, the result is unknown
- if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
- x.val = constant.MakeUnknown()
- // ensure the correct type - see comment below
- if !isInteger(x.typ) {
- x.typ = Typ[UntypedInt]
- }
- return
- }
- // rhs must be within reasonable bounds in constant shifts
- const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 (see issue #44057)
- s, ok := constant.Uint64Val(yval)
- if !ok || s > shiftBound {
- check.errorf(y, InvalidShiftCount, invalidOp+"invalid shift count %s", y)
- x.mode = invalid
- return
- }
- // The lhs is representable as an integer but may not be an integer
- // (e.g., 2.0, an untyped float) - this can only happen for untyped
- // non-integer numeric constants. Correct the type so that the shift
- // result is of integer type.
- if !isInteger(x.typ) {
- x.typ = Typ[UntypedInt]
- }
- // x is a constant so xval != nil and it must be of Int kind.
- x.val = constant.Shift(xval, op, uint(s))
- x.expr = e
- opPos := x.Pos()
- if b, _ := e.(*ast.BinaryExpr); b != nil {
- opPos = b.OpPos
- }
- check.overflow(x, opPos)
- return
- }
-
- // non-constant shift with constant lhs
- if isUntyped(x.typ) {
- // spec: "If the left operand of a non-constant shift
- // expression is an untyped constant, the type of the
- // constant is what it would be if the shift expression
- // were replaced by its left operand alone.".
- //
- // Delay operand checking until we know the final type
- // by marking the lhs expression as lhs shift operand.
- //
- // Usually (in correct programs), the lhs expression
- // is in the untyped map. However, it is possible to
- // create incorrect programs where the same expression
- // is evaluated twice (via a declaration cycle) such
- // that the lhs expression type is determined in the
- // first round and thus deleted from the map, and then
- // not found in the second round (double insertion of
- // the same expr node still just leads to one entry for
- // that node, and it can only be deleted once).
- // Be cautious and check for presence of entry.
- // Example: var e, f = int(1<<""[f]) // issue 11347
- if info, found := check.untyped[x.expr]; found {
- info.isLhs = true
- check.untyped[x.expr] = info
- }
- // keep x's type
- x.mode = value
- return
- }
- }
-
- // non-constant shift - lhs must be an integer
- if !allInteger(x.typ) {
- check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
- x.mode = invalid
- return
- }
-
- x.mode = value
-}
-
-var binaryOpPredicates opPredicates
-
-func init() {
- // Setting binaryOpPredicates in init avoids declaration cycles.
- binaryOpPredicates = opPredicates{
- token.ADD: allNumericOrString,
- token.SUB: allNumeric,
- token.MUL: allNumeric,
- token.QUO: allNumeric,
- token.REM: allInteger,
-
- token.AND: allInteger,
- token.OR: allInteger,
- token.XOR: allInteger,
- token.AND_NOT: allInteger,
-
- token.LAND: allBoolean,
- token.LOR: allBoolean,
- }
-}
-
-// If e != nil, it must be the binary expression; it may be nil for non-constant expressions
-// (when invoked for an assignment operation where the binary expression is implicit).
-func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token.Token, opPos token.Pos) {
- var y operand
-
- check.expr(x, lhs)
- check.expr(&y, rhs)
-
- if x.mode == invalid {
- return
- }
- if y.mode == invalid {
- x.mode = invalid
- x.expr = y.expr
- return
- }
-
- if isShift(op) {
- check.shift(x, &y, e, op)
- return
- }
-
- // mayConvert reports whether the operands x and y may
- // possibly have matching types after converting one
- // untyped operand to the type of the other.
- // If mayConvert returns true, we try to convert the
- // operands to each other's types, and if that fails
- // we report a conversion failure.
- // If mayConvert returns false, we continue without an
- // attempt at conversion, and if the operand types are
- // not compatible, we report a type mismatch error.
- mayConvert := func(x, y *operand) bool {
- // If both operands are typed, there's no need for an implicit conversion.
- if isTyped(x.typ) && isTyped(y.typ) {
- return false
- }
- // An untyped operand may convert to its default type when paired with an empty interface
- // TODO(gri) This should only matter for comparisons (the only binary operation that is
- // valid with interfaces), but in that case the assignability check should take
- // care of the conversion. Verify and possibly eliminate this extra test.
- if isNonTypeParamInterface(x.typ) || isNonTypeParamInterface(y.typ) {
- return true
- }
- // A boolean type can only convert to another boolean type.
- if allBoolean(x.typ) != allBoolean(y.typ) {
- return false
- }
- // A string type can only convert to another string type.
- if allString(x.typ) != allString(y.typ) {
- return false
- }
- // Untyped nil can only convert to a type that has a nil.
- if x.isNil() {
- return hasNil(y.typ)
- }
- if y.isNil() {
- return hasNil(x.typ)
- }
- // An untyped operand cannot convert to a pointer.
- // TODO(gri) generalize to type parameters
- if isPointer(x.typ) || isPointer(y.typ) {
- return false
- }
- return true
- }
- if mayConvert(x, &y) {
- check.convertUntyped(x, y.typ)
- if x.mode == invalid {
- return
- }
- check.convertUntyped(&y, x.typ)
- if y.mode == invalid {
- x.mode = invalid
- return
- }
- }
-
- if isComparison(op) {
- check.comparison(x, &y, op, false)
- return
- }
-
- if !Identical(x.typ, y.typ) {
- // only report an error if we have valid types
- // (otherwise we had an error reported elsewhere already)
- if x.typ != Typ[Invalid] && y.typ != Typ[Invalid] {
- var posn positioner = x
- if e != nil {
- posn = e
- }
- if e != nil {
- check.errorf(posn, MismatchedTypes, invalidOp+"%s (mismatched types %s and %s)", e, x.typ, y.typ)
- } else {
- check.errorf(posn, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ, y.typ)
- }
- }
- x.mode = invalid
- return
- }
-
- if !check.op(binaryOpPredicates, x, op) {
- x.mode = invalid
- return
- }
-
- if op == token.QUO || op == token.REM {
- // check for zero divisor
- if (x.mode == constant_ || allInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 {
- check.error(&y, DivByZero, invalidOp+"division by zero")
- x.mode = invalid
- return
- }
-
- // check for divisor underflow in complex division (see issue 20227)
- if x.mode == constant_ && y.mode == constant_ && isComplex(x.typ) {
- re, im := constant.Real(y.val), constant.Imag(y.val)
- re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
- if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
- check.error(&y, DivByZero, invalidOp+"division by zero")
- x.mode = invalid
- return
- }
- }
- }
-
- if x.mode == constant_ && y.mode == constant_ {
- // if either x or y has an unknown value, the result is unknown
- if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
- x.val = constant.MakeUnknown()
- // x.typ is unchanged
- return
- }
- // force integer division of integer operands
- if op == token.QUO && isInteger(x.typ) {
- op = token.QUO_ASSIGN
- }
- x.val = constant.BinaryOp(x.val, op, y.val)
- x.expr = e
- check.overflow(x, opPos)
- return
- }
-
- x.mode = value
- // x.typ is unchanged
-}
-
-// exprKind describes the kind of an expression; the kind
-// determines if an expression is valid in 'statement context'.
-type exprKind int
-
-const (
- conversion exprKind = iota
- expression
- statement
-)
-
-// rawExpr typechecks expression e and initializes x with the expression
-// value or type. If an error occurred, x.mode is set to invalid.
-// If hint != nil, it is the type of a composite literal element.
-// If allowGeneric is set, the operand type may be an uninstantiated
-// parameterized type or function value.
-func (check *Checker) rawExpr(x *operand, e ast.Expr, hint Type, allowGeneric bool) exprKind {
- if trace {
- check.trace(e.Pos(), "-- expr %s", e)
- check.indent++
- defer func() {
- check.indent--
- check.trace(e.Pos(), "=> %s", x)
- }()
- }
-
- kind := check.exprInternal(x, e, hint)
-
- if !allowGeneric {
- check.nonGeneric(x)
- }
-
- check.record(x)
-
- return kind
-}
-
-// If x is a generic function or type, nonGeneric reports an error and invalidates x.mode and x.typ.
-// Otherwise it leaves x alone.
-func (check *Checker) nonGeneric(x *operand) {
- if x.mode == invalid || x.mode == novalue {
- return
- }
- var what string
- switch t := x.typ.(type) {
- case *Named:
- if isGeneric(t) {
- what = "type"
- }
- case *Signature:
- if t.tparams != nil {
- what = "function"
- }
- }
- if what != "" {
- check.errorf(x.expr, WrongTypeArgCount, "cannot use generic %s %s without instantiation", what, x.expr)
- x.mode = invalid
- x.typ = Typ[Invalid]
- }
-}
-
-// exprInternal contains the core of type checking of expressions.
-// Must only be called by rawExpr.
-func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
- // make sure x has a valid state in case of bailout
- // (was issue 5770)
- x.mode = invalid
- x.typ = Typ[Invalid]
-
- switch e := e.(type) {
- case *ast.BadExpr:
- goto Error // error was reported before
-
- case *ast.Ident:
- check.ident(x, e, nil, false)
-
- case *ast.Ellipsis:
- // ellipses are handled explicitly where they are legal
- // (array composite literals and parameter lists)
- check.error(e, BadDotDotDotSyntax, "invalid use of '...'")
- goto Error
-
- case *ast.BasicLit:
- switch e.Kind {
- case token.INT, token.FLOAT, token.IMAG:
- check.langCompat(e)
- // The max. mantissa precision for untyped numeric values
- // is 512 bits, or 4048 bits for each of the two integer
- // parts of a fraction for floating-point numbers that are
- // represented accurately in the go/constant package.
- // Constant literals that are longer than this many bits
- // are not meaningful; and excessively long constants may
- // consume a lot of space and time for a useless conversion.
- // Cap constant length with a generous upper limit that also
- // allows for separators between all digits.
- const limit = 10000
- if len(e.Value) > limit {
- check.errorf(e, InvalidConstVal, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
- goto Error
- }
- }
- x.setConst(e.Kind, e.Value)
- if x.mode == invalid {
- // The parser already establishes syntactic correctness.
- // If we reach here it's because of number under-/overflow.
- // TODO(gri) setConst (and in turn the go/constant package)
- // should return an error describing the issue.
- check.errorf(e, InvalidConstVal, "malformed constant: %s", e.Value)
- goto Error
- }
- // Ensure that integer values don't overflow (issue #54280).
- check.overflow(x, e.Pos())
-
- case *ast.FuncLit:
- if sig, ok := check.typ(e.Type).(*Signature); ok {
- if !check.conf.IgnoreFuncBodies && e.Body != nil {
- // Anonymous functions are considered part of the
- // init expression/func declaration which contains
- // them: use existing package-level declaration info.
- decl := check.decl // capture for use in closure below
- iota := check.iota // capture for use in closure below (#22345)
- // Don't type-check right away because the function may
- // be part of a type definition to which the function
- // body refers. Instead, type-check as soon as possible,
- // but before the enclosing scope contents changes (#22992).
- check.later(func() {
- check.funcBody(decl, "<function literal>", sig, e.Body, iota)
- }).describef(e, "func literal")
- }
- x.mode = value
- x.typ = sig
- } else {
- check.errorf(e, InvalidSyntaxTree, "invalid function literal %s", e)
- goto Error
- }
-
- case *ast.CompositeLit:
- var typ, base Type
-
- switch {
- case e.Type != nil:
- // composite literal type present - use it
- // [...]T array types may only appear with composite literals.
- // Check for them here so we don't have to handle ... in general.
- if atyp, _ := e.Type.(*ast.ArrayType); atyp != nil && atyp.Len != nil {
- if ellip, _ := atyp.Len.(*ast.Ellipsis); ellip != nil && ellip.Elt == nil {
- // We have an "open" [...]T array type.
- // Create a new ArrayType with unknown length (-1)
- // and finish setting it up after analyzing the literal.
- typ = &Array{len: -1, elem: check.varType(atyp.Elt)}
- base = typ
- break
- }
- }
- typ = check.typ(e.Type)
- base = typ
-
- case hint != nil:
- // no composite literal type present - use hint (element type of enclosing type)
- typ = hint
- base, _ = deref(coreType(typ)) // *T implies &T{}
- if base == nil {
- check.errorf(e, InvalidLit, "invalid composite literal element type %s (no core type)", typ)
- goto Error
- }
-
- default:
- // TODO(gri) provide better error messages depending on context
- check.error(e, UntypedLit, "missing type in composite literal")
- goto Error
- }
-
- switch utyp := coreType(base).(type) {
- case *Struct:
- // Prevent crash if the struct referred to is not yet set up.
- // See analogous comment for *Array.
- if utyp.fields == nil {
- check.error(e, InvalidTypeCycle, "invalid recursive type")
- goto Error
- }
- if len(e.Elts) == 0 {
- break
- }
- // Convention for error messages on invalid struct literals:
- // we mention the struct type only if it clarifies the error
- // (e.g., a duplicate field error doesn't need the struct type).
- fields := utyp.fields
- if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok {
- // all elements must have keys
- visited := make([]bool, len(fields))
- for _, e := range e.Elts {
- kv, _ := e.(*ast.KeyValueExpr)
- if kv == nil {
- check.error(e, MixedStructLit, "mixture of field:value and value elements in struct literal")
- continue
- }
- key, _ := kv.Key.(*ast.Ident)
- // do all possible checks early (before exiting due to errors)
- // so we don't drop information on the floor
- check.expr(x, kv.Value)
- if key == nil {
- check.errorf(kv, InvalidLitField, "invalid field name %s in struct literal", kv.Key)
- continue
- }
- i := fieldIndex(utyp.fields, check.pkg, key.Name)
- if i < 0 {
- check.errorf(kv, MissingLitField, "unknown field %s in struct literal of type %s", key.Name, base)
- continue
- }
- fld := fields[i]
- check.recordUse(key, fld)
- etyp := fld.typ
- check.assignment(x, etyp, "struct literal")
- // 0 <= i < len(fields)
- if visited[i] {
- check.errorf(kv, DuplicateLitField, "duplicate field name %s in struct literal", key.Name)
- continue
- }
- visited[i] = true
- }
- } else {
- // no element must have a key
- for i, e := range e.Elts {
- if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
- check.error(kv, MixedStructLit, "mixture of field:value and value elements in struct literal")
- continue
- }
- check.expr(x, e)
- if i >= len(fields) {
- check.errorf(x, InvalidStructLit, "too many values in struct literal of type %s", base)
- break // cannot continue
- }
- // i < len(fields)
- fld := fields[i]
- if !fld.Exported() && fld.pkg != check.pkg {
- check.errorf(x,
- UnexportedLitField,
- "implicit assignment to unexported field %s in struct literal of type %s", fld.name, base)
- continue
- }
- etyp := fld.typ
- check.assignment(x, etyp, "struct literal")
- }
- if len(e.Elts) < len(fields) {
- check.errorf(inNode(e, e.Rbrace), InvalidStructLit, "too few values in struct literal of type %s", base)
- // ok to continue
- }
- }
-
- case *Array:
- // Prevent crash if the array referred to is not yet set up. Was issue #18643.
- // This is a stop-gap solution. Should use Checker.objPath to report entire
- // path starting with earliest declaration in the source. TODO(gri) fix this.
- if utyp.elem == nil {
- check.error(e, InvalidTypeCycle, "invalid recursive type")
- goto Error
- }
- n := check.indexedElts(e.Elts, utyp.elem, utyp.len)
- // If we have an array of unknown length (usually [...]T arrays, but also
- // arrays [n]T where n is invalid) set the length now that we know it and
- // record the type for the array (usually done by check.typ which is not
- // called for [...]T). We handle [...]T arrays and arrays with invalid
- // length the same here because it makes sense to "guess" the length for
- // the latter if we have a composite literal; e.g. for [n]int{1, 2, 3}
- // where n is invalid for some reason, it seems fair to assume it should
- // be 3 (see also Checked.arrayLength and issue #27346).
- if utyp.len < 0 {
- utyp.len = n
- // e.Type is missing if we have a composite literal element
- // that is itself a composite literal with omitted type. In
- // that case there is nothing to record (there is no type in
- // the source at that point).
- if e.Type != nil {
- check.recordTypeAndValue(e.Type, typexpr, utyp, nil)
- }
- }
-
- case *Slice:
- // Prevent crash if the slice referred to is not yet set up.
- // See analogous comment for *Array.
- if utyp.elem == nil {
- check.error(e, InvalidTypeCycle, "invalid recursive type")
- goto Error
- }
- check.indexedElts(e.Elts, utyp.elem, -1)
-
- case *Map:
- // Prevent crash if the map referred to is not yet set up.
- // See analogous comment for *Array.
- if utyp.key == nil || utyp.elem == nil {
- check.error(e, InvalidTypeCycle, "invalid recursive type")
- goto Error
- }
- // If the map key type is an interface (but not a type parameter),
- // the type of a constant key must be considered when checking for
- // duplicates.
- keyIsInterface := isNonTypeParamInterface(utyp.key)
- visited := make(map[any][]Type, len(e.Elts))
- for _, e := range e.Elts {
- kv, _ := e.(*ast.KeyValueExpr)
- if kv == nil {
- check.error(e, MissingLitKey, "missing key in map literal")
- continue
- }
- check.exprWithHint(x, kv.Key, utyp.key)
- check.assignment(x, utyp.key, "map literal")
- if x.mode == invalid {
- continue
- }
- if x.mode == constant_ {
- duplicate := false
- xkey := keyVal(x.val)
- if keyIsInterface {
- for _, vtyp := range visited[xkey] {
- if Identical(vtyp, x.typ) {
- duplicate = true
- break
- }
- }
- visited[xkey] = append(visited[xkey], x.typ)
- } else {
- _, duplicate = visited[xkey]
- visited[xkey] = nil
- }
- if duplicate {
- check.errorf(x, DuplicateLitKey, "duplicate key %s in map literal", x.val)
- continue
- }
- }
- check.exprWithHint(x, kv.Value, utyp.elem)
- check.assignment(x, utyp.elem, "map literal")
- }
-
- default:
- // when "using" all elements unpack KeyValueExpr
- // explicitly because check.use doesn't accept them
- for _, e := range e.Elts {
- if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
- // Ideally, we should also "use" kv.Key but we can't know
- // if it's an externally defined struct key or not. Going
- // forward anyway can lead to other errors. Give up instead.
- e = kv.Value
- }
- check.use(e)
- }
- // if utyp is invalid, an error was reported before
- if utyp != Typ[Invalid] {
- check.errorf(e, InvalidLit, "invalid composite literal type %s", typ)
- goto Error
- }
- }
-
- x.mode = value
- x.typ = typ
-
- case *ast.ParenExpr:
- kind := check.rawExpr(x, e.X, nil, false)
- x.expr = e
- return kind
-
- case *ast.SelectorExpr:
- check.selector(x, e, nil, false)
-
- case *ast.IndexExpr, *ast.IndexListExpr:
- ix := typeparams.UnpackIndexExpr(e)
- if check.indexExpr(x, ix) {
- check.funcInst(x, ix)
- }
- if x.mode == invalid {
- goto Error
- }
-
- case *ast.SliceExpr:
- check.sliceExpr(x, e)
- if x.mode == invalid {
- goto Error
- }
-
- case *ast.TypeAssertExpr:
- check.expr(x, e.X)
- if x.mode == invalid {
- goto Error
- }
- // TODO(gri) we may want to permit type assertions on type parameter values at some point
- if isTypeParam(x.typ) {
- check.errorf(x, InvalidAssert, invalidOp+"cannot use type assertion on type parameter value %s", x)
- goto Error
- }
- if _, ok := under(x.typ).(*Interface); !ok {
- check.errorf(x, InvalidAssert, invalidOp+"%s is not an interface", x)
- goto Error
- }
- // x.(type) expressions are handled explicitly in type switches
- if e.Type == nil {
- // Don't use invalidAST because this can occur in the AST produced by
- // go/parser.
- check.error(e, BadTypeKeyword, "use of .(type) outside type switch")
- goto Error
- }
- T := check.varType(e.Type)
- if T == Typ[Invalid] {
- goto Error
- }
- check.typeAssertion(e, x, T, false)
- x.mode = commaok
- x.typ = T
-
- case *ast.CallExpr:
- return check.callExpr(x, e)
-
- case *ast.StarExpr:
- check.exprOrType(x, e.X, false)
- switch x.mode {
- case invalid:
- goto Error
- case typexpr:
- check.validVarType(e.X, x.typ)
- x.typ = &Pointer{base: x.typ}
- default:
- var base Type
- if !underIs(x.typ, func(u Type) bool {
- p, _ := u.(*Pointer)
- if p == nil {
- check.errorf(x, InvalidIndirection, invalidOp+"cannot indirect %s", x)
- return false
- }
- if base != nil && !Identical(p.base, base) {
- check.errorf(x, InvalidIndirection, invalidOp+"pointers of %s must have identical base types", x)
- return false
- }
- base = p.base
- return true
- }) {
- goto Error
- }
- x.mode = variable
- x.typ = base
- }
-
- case *ast.UnaryExpr:
- check.unary(x, e)
- if x.mode == invalid {
- goto Error
- }
- if e.Op == token.ARROW {
- x.expr = e
- return statement // receive operations may appear in statement context
- }
-
- case *ast.BinaryExpr:
- check.binary(x, e, e.X, e.Y, e.Op, e.OpPos)
- if x.mode == invalid {
- goto Error
- }
-
- case *ast.KeyValueExpr:
- // key:value expressions are handled in composite literals
- check.error(e, InvalidSyntaxTree, "no key:value expected")
- goto Error
-
- case *ast.ArrayType, *ast.StructType, *ast.FuncType,
- *ast.InterfaceType, *ast.MapType, *ast.ChanType:
- x.mode = typexpr
- x.typ = check.typ(e)
- // Note: rawExpr (caller of exprInternal) will call check.recordTypeAndValue
- // even though check.typ has already called it. This is fine as both
- // times the same expression and type are recorded. It is also not a
- // performance issue because we only reach here for composite literal
- // types, which are comparatively rare.
-
- default:
- panic(fmt.Sprintf("%s: unknown expression type %T", check.fset.Position(e.Pos()), e))
- }
-
- // everything went well
- x.expr = e
- return expression
-
-Error:
- x.mode = invalid
- x.expr = e
- return statement // avoid follow-up errors
-}
-
-// keyVal maps a complex, float, integer, string or boolean constant value
-// to the corresponding complex128, float64, int64, uint64, string, or bool
-// Go value if possible; otherwise it returns x.
-// A complex constant that can be represented as a float (such as 1.2 + 0i)
-// is returned as a floating point value; if a floating point value can be
-// represented as an integer (such as 1.0) it is returned as an integer value.
-// This ensures that constants of different kind but equal value (such as
-// 1.0 + 0i, 1.0, 1) result in the same value.
-func keyVal(x constant.Value) interface{} {
- switch x.Kind() {
- case constant.Complex:
- f := constant.ToFloat(x)
- if f.Kind() != constant.Float {
- r, _ := constant.Float64Val(constant.Real(x))
- i, _ := constant.Float64Val(constant.Imag(x))
- return complex(r, i)
- }
- x = f
- fallthrough
- case constant.Float:
- i := constant.ToInt(x)
- if i.Kind() != constant.Int {
- v, _ := constant.Float64Val(x)
- return v
- }
- x = i
- fallthrough
- case constant.Int:
- if v, ok := constant.Int64Val(x); ok {
- return v
- }
- if v, ok := constant.Uint64Val(x); ok {
- return v
- }
- case constant.String:
- return constant.StringVal(x)
- case constant.Bool:
- return constant.BoolVal(x)
- }
- return x
-}
-
-// typeAssertion checks x.(T). The type of x must be an interface.
-func (check *Checker) typeAssertion(e ast.Expr, x *operand, T Type, typeSwitch bool) {
- method, alt := check.assertableTo(under(x.typ).(*Interface), T)
- if method == nil {
- return // success
- }
-
- cause := check.missingMethodCause(T, x.typ, method, alt)
-
- if typeSwitch {
- check.errorf(e, ImpossibleAssert, "impossible type switch case: %s\n\t%s cannot have dynamic type %s %s", e, x, T, cause)
- return
- }
-
- check.errorf(e, ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ, cause)
-}
-
-// expr typechecks expression e and initializes x with the expression value.
-// The result must be a single value.
-// If an error occurred, x.mode is set to invalid.
-func (check *Checker) expr(x *operand, e ast.Expr) {
- check.rawExpr(x, e, nil, false)
- check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
- check.singleValue(x)
-}
-
-// multiExpr is like expr but the result may also be a multi-value.
-func (check *Checker) multiExpr(x *operand, e ast.Expr) {
- check.rawExpr(x, e, nil, false)
- check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
-}
-
-// exprWithHint typechecks expression e and initializes x with the expression value;
-// hint is the type of a composite literal element.
-// If an error occurred, x.mode is set to invalid.
-func (check *Checker) exprWithHint(x *operand, e ast.Expr, hint Type) {
- assert(hint != nil)
- check.rawExpr(x, e, hint, false)
- check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
- check.singleValue(x)
-}
-
-// exprOrType typechecks expression or type e and initializes x with the expression value or type.
-// If allowGeneric is set, the operand type may be an uninstantiated parameterized type or function
-// value.
-// If an error occurred, x.mode is set to invalid.
-func (check *Checker) exprOrType(x *operand, e ast.Expr, allowGeneric bool) {
- check.rawExpr(x, e, nil, allowGeneric)
- check.exclude(x, 1<<novalue)
- check.singleValue(x)
-}
-
-// exclude reports an error if x.mode is in modeset and sets x.mode to invalid.
-// The modeset may contain any of 1<<novalue, 1<<builtin, 1<<typexpr.
-func (check *Checker) exclude(x *operand, modeset uint) {
- if modeset&(1<<x.mode) != 0 {
- var msg string
- var code Code
- switch x.mode {
- case novalue:
- if modeset&(1<<typexpr) != 0 {
- msg = "%s used as value"
- } else {
- msg = "%s used as value or type"
- }
- code = TooManyValues
- case builtin:
- msg = "%s must be called"
- code = UncalledBuiltin
- case typexpr:
- msg = "%s is not an expression"
- code = NotAnExpr
- default:
- unreachable()
- }
- check.errorf(x, code, msg, x)
- x.mode = invalid
- }
-}
-
-// singleValue reports an error if x describes a tuple and sets x.mode to invalid.
-func (check *Checker) singleValue(x *operand) {
- if x.mode == value {
- // tuple types are never named - no need for underlying type below
- if t, ok := x.typ.(*Tuple); ok {
- assert(t.Len() != 1)
- check.errorf(x, TooManyValues, "multiple-value %s in single-value context", x)
- x.mode = invalid
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/go/types/gccgosizes.go b/contrib/go/_std_1.20/src/go/types/gccgosizes.go
deleted file mode 100644
index 9d077cc5a6..0000000000
--- a/contrib/go/_std_1.20/src/go/types/gccgosizes.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This is a copy of the file generated during the gccgo build process.
-// Last update 2019-01-22.
-
-package types
-
-var gccgoArchSizes = map[string]*StdSizes{
- "386": {4, 4},
- "alpha": {8, 8},
- "amd64": {8, 8},
- "amd64p32": {4, 8},
- "arm": {4, 8},
- "armbe": {4, 8},
- "arm64": {8, 8},
- "arm64be": {8, 8},
- "ia64": {8, 8},
- "loong64": {8, 8},
- "m68k": {4, 2},
- "mips": {4, 8},
- "mipsle": {4, 8},
- "mips64": {8, 8},
- "mips64le": {8, 8},
- "mips64p32": {4, 8},
- "mips64p32le": {4, 8},
- "nios2": {4, 8},
- "ppc": {4, 8},
- "ppc64": {8, 8},
- "ppc64le": {8, 8},
- "riscv": {4, 8},
- "riscv64": {8, 8},
- "s390": {4, 8},
- "s390x": {8, 8},
- "sh": {4, 8},
- "shbe": {4, 8},
- "sparc": {4, 8},
- "sparc64": {8, 8},
- "wasm": {8, 8},
-}
diff --git a/contrib/go/_std_1.20/src/go/types/index.go b/contrib/go/_std_1.20/src/go/types/index.go
deleted file mode 100644
index 45d591e31c..0000000000
--- a/contrib/go/_std_1.20/src/go/types/index.go
+++ /dev/null
@@ -1,456 +0,0 @@
-// 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.
-
-// This file implements typechecking of index/slice expressions.
-
-package types
-
-import (
- "go/ast"
- "go/constant"
- "go/internal/typeparams"
- . "internal/types/errors"
-)
-
-// If e is a valid function instantiation, indexExpr returns true.
-// In that case x represents the uninstantiated function value and
-// it is the caller's responsibility to instantiate the function.
-func (check *Checker) indexExpr(x *operand, e *typeparams.IndexExpr) (isFuncInst bool) {
- check.exprOrType(x, e.X, true)
- // x may be generic
-
- switch x.mode {
- case invalid:
- check.use(e.Indices...)
- return false
-
- case typexpr:
- // type instantiation
- x.mode = invalid
- // TODO(gri) here we re-evaluate e.X - try to avoid this
- x.typ = check.varType(e.Orig)
- if x.typ != Typ[Invalid] {
- x.mode = typexpr
- }
- return false
-
- case value:
- if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
- // function instantiation
- return true
- }
- }
-
- // x should not be generic at this point, but be safe and check
- check.nonGeneric(x)
- if x.mode == invalid {
- return false
- }
-
- // ordinary index expression
- valid := false
- length := int64(-1) // valid if >= 0
- switch typ := under(x.typ).(type) {
- case *Basic:
- if isString(typ) {
- valid = true
- if x.mode == constant_ {
- length = int64(len(constant.StringVal(x.val)))
- }
- // an indexed string always yields a byte value
- // (not a constant) even if the string and the
- // index are constant
- x.mode = value
- x.typ = universeByte // use 'byte' name
- }
-
- case *Array:
- valid = true
- length = typ.len
- if x.mode != variable {
- x.mode = value
- }
- x.typ = typ.elem
-
- case *Pointer:
- if typ, _ := under(typ.base).(*Array); typ != nil {
- valid = true
- length = typ.len
- x.mode = variable
- x.typ = typ.elem
- }
-
- case *Slice:
- valid = true
- x.mode = variable
- x.typ = typ.elem
-
- case *Map:
- index := check.singleIndex(e)
- if index == nil {
- x.mode = invalid
- return false
- }
- var key operand
- check.expr(&key, index)
- check.assignment(&key, typ.key, "map index")
- // ok to continue even if indexing failed - map element type is known
- x.mode = mapindex
- x.typ = typ.elem
- x.expr = e.Orig
- return false
-
- case *Interface:
- if !isTypeParam(x.typ) {
- break
- }
- // TODO(gri) report detailed failure cause for better error messages
- var key, elem Type // key != nil: we must have all maps
- mode := variable // non-maps result mode
- // TODO(gri) factor out closure and use it for non-typeparam cases as well
- if typ.typeSet().underIs(func(u Type) bool {
- l := int64(-1) // valid if >= 0
- var k, e Type // k is only set for maps
- switch t := u.(type) {
- case *Basic:
- if isString(t) {
- e = universeByte
- mode = value
- }
- case *Array:
- l = t.len
- e = t.elem
- if x.mode != variable {
- mode = value
- }
- case *Pointer:
- if t, _ := under(t.base).(*Array); t != nil {
- l = t.len
- e = t.elem
- }
- case *Slice:
- e = t.elem
- case *Map:
- k = t.key
- e = t.elem
- }
- if e == nil {
- return false
- }
- if elem == nil {
- // first type
- length = l
- key, elem = k, e
- return true
- }
- // all map keys must be identical (incl. all nil)
- // (that is, we cannot mix maps with other types)
- if !Identical(key, k) {
- return false
- }
- // all element types must be identical
- if !Identical(elem, e) {
- return false
- }
- // track the minimal length for arrays, if any
- if l >= 0 && l < length {
- length = l
- }
- return true
- }) {
- // For maps, the index expression must be assignable to the map key type.
- if key != nil {
- index := check.singleIndex(e)
- if index == nil {
- x.mode = invalid
- return false
- }
- var k operand
- check.expr(&k, index)
- check.assignment(&k, key, "map index")
- // ok to continue even if indexing failed - map element type is known
- x.mode = mapindex
- x.typ = elem
- x.expr = e
- return false
- }
-
- // no maps
- valid = true
- x.mode = mode
- x.typ = elem
- }
- }
-
- if !valid {
- // types2 uses the position of '[' for the error
- check.errorf(x, NonIndexableOperand, invalidOp+"cannot index %s", x)
- x.mode = invalid
- return false
- }
-
- index := check.singleIndex(e)
- if index == nil {
- x.mode = invalid
- return false
- }
-
- // In pathological (invalid) cases (e.g.: type T1 [][[]T1{}[0][0]]T0)
- // the element type may be accessed before it's set. Make sure we have
- // a valid type.
- if x.typ == nil {
- x.typ = Typ[Invalid]
- }
-
- check.index(index, length)
- return false
-}
-
-func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
- check.expr(x, e.X)
- if x.mode == invalid {
- check.use(e.Low, e.High, e.Max)
- return
- }
-
- valid := false
- length := int64(-1) // valid if >= 0
- switch u := coreString(x.typ).(type) {
- case nil:
- check.errorf(x, NonSliceableOperand, invalidOp+"cannot slice %s: %s has no core type", x, x.typ)
- x.mode = invalid
- return
-
- case *Basic:
- if isString(u) {
- if e.Slice3 {
- at := e.Max
- if at == nil {
- at = e // e.Index[2] should be present but be careful
- }
- check.error(at, InvalidSliceExpr, invalidOp+"3-index slice of string")
- x.mode = invalid
- return
- }
- valid = true
- if x.mode == constant_ {
- length = int64(len(constant.StringVal(x.val)))
- }
- // spec: "For untyped string operands the result
- // is a non-constant value of type string."
- if isUntyped(x.typ) {
- x.typ = Typ[String]
- }
- }
-
- case *Array:
- valid = true
- length = u.len
- if x.mode != variable {
- check.errorf(x, NonSliceableOperand, invalidOp+"cannot slice %s (value not addressable)", x)
- x.mode = invalid
- return
- }
- x.typ = &Slice{elem: u.elem}
-
- case *Pointer:
- if u, _ := under(u.base).(*Array); u != nil {
- valid = true
- length = u.len
- x.typ = &Slice{elem: u.elem}
- }
-
- case *Slice:
- valid = true
- // x.typ doesn't change
- }
-
- if !valid {
- check.errorf(x, NonSliceableOperand, invalidOp+"cannot slice %s", x)
- x.mode = invalid
- return
- }
-
- x.mode = value
-
- // spec: "Only the first index may be omitted; it defaults to 0."
- if e.Slice3 && (e.High == nil || e.Max == nil) {
- check.error(inNode(e, e.Rbrack), InvalidSyntaxTree, "2nd and 3rd index required in 3-index slice")
- x.mode = invalid
- return
- }
-
- // check indices
- var ind [3]int64
- for i, expr := range []ast.Expr{e.Low, e.High, e.Max} {
- x := int64(-1)
- switch {
- case expr != nil:
- // The "capacity" is only known statically for strings, arrays,
- // and pointers to arrays, and it is the same as the length for
- // those types.
- max := int64(-1)
- if length >= 0 {
- max = length + 1
- }
- if _, v := check.index(expr, max); v >= 0 {
- x = v
- }
- case i == 0:
- // default is 0 for the first index
- x = 0
- case length >= 0:
- // default is length (== capacity) otherwise
- x = length
- }
- ind[i] = x
- }
-
- // constant indices must be in range
- // (check.index already checks that existing indices >= 0)
-L:
- for i, x := range ind[:len(ind)-1] {
- if x > 0 {
- for j, y := range ind[i+1:] {
- if y >= 0 && y < x {
- // The value y corresponds to the expression e.Index[i+1+j].
- // Because y >= 0, it must have been set from the expression
- // when checking indices and thus e.Index[i+1+j] is not nil.
- at := []ast.Expr{e.Low, e.High, e.Max}[i+1+j]
- check.errorf(at, SwappedSliceIndices, "invalid slice indices: %d < %d", y, x)
- break L // only report one error, ok to continue
- }
- }
- }
- }
-}
-
-// singleIndex returns the (single) index from the index expression e.
-// If the index is missing, or if there are multiple indices, an error
-// is reported and the result is nil.
-func (check *Checker) singleIndex(expr *typeparams.IndexExpr) ast.Expr {
- if len(expr.Indices) == 0 {
- check.errorf(expr.Orig, InvalidSyntaxTree, "index expression %v with 0 indices", expr)
- return nil
- }
- if len(expr.Indices) > 1 {
- // TODO(rFindley) should this get a distinct error code?
- check.error(expr.Indices[1], InvalidIndex, invalidOp+"more than one index")
- }
- return expr.Indices[0]
-}
-
-// index checks an index expression for validity.
-// If max >= 0, it is the upper bound for index.
-// If the result typ is != Typ[Invalid], index is valid and typ is its (possibly named) integer type.
-// If the result val >= 0, index is valid and val is its constant int value.
-func (check *Checker) index(index ast.Expr, max int64) (typ Type, val int64) {
- typ = Typ[Invalid]
- val = -1
-
- var x operand
- check.expr(&x, index)
- if !check.isValidIndex(&x, InvalidIndex, "index", false) {
- return
- }
-
- if x.mode != constant_ {
- return x.typ, -1
- }
-
- if x.val.Kind() == constant.Unknown {
- return
- }
-
- v, ok := constant.Int64Val(x.val)
- assert(ok)
- if max >= 0 && v >= max {
- check.errorf(&x, InvalidIndex, invalidArg+"index %s out of bounds [0:%d]", x.val.String(), max)
- return
- }
-
- // 0 <= v [ && v < max ]
- return x.typ, v
-}
-
-func (check *Checker) isValidIndex(x *operand, code Code, what string, allowNegative bool) bool {
- if x.mode == invalid {
- return false
- }
-
- // spec: "a constant index that is untyped is given type int"
- check.convertUntyped(x, Typ[Int])
- if x.mode == invalid {
- return false
- }
-
- // spec: "the index x must be of integer type or an untyped constant"
- if !allInteger(x.typ) {
- check.errorf(x, code, invalidArg+"%s %s must be integer", what, x)
- return false
- }
-
- if x.mode == constant_ {
- // spec: "a constant index must be non-negative ..."
- if !allowNegative && constant.Sign(x.val) < 0 {
- check.errorf(x, code, invalidArg+"%s %s must not be negative", what, x)
- return false
- }
-
- // spec: "... and representable by a value of type int"
- if !representableConst(x.val, check, Typ[Int], &x.val) {
- check.errorf(x, code, invalidArg+"%s %s overflows int", what, x)
- return false
- }
- }
-
- return true
-}
-
-// indexElts checks the elements (elts) of an array or slice composite literal
-// against the literal's element type (typ), and the element indices against
-// the literal length if known (length >= 0). It returns the length of the
-// literal (maximum index value + 1).
-func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 {
- visited := make(map[int64]bool, len(elts))
- var index, max int64
- for _, e := range elts {
- // determine and check index
- validIndex := false
- eval := e
- if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
- if typ, i := check.index(kv.Key, length); typ != Typ[Invalid] {
- if i >= 0 {
- index = i
- validIndex = true
- } else {
- check.errorf(e, InvalidLitIndex, "index %s must be integer constant", kv.Key)
- }
- }
- eval = kv.Value
- } else if length >= 0 && index >= length {
- check.errorf(e, OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
- } else {
- validIndex = true
- }
-
- // if we have a valid index, check for duplicate entries
- if validIndex {
- if visited[index] {
- check.errorf(e, DuplicateLitKey, "duplicate index %d in array or slice literal", index)
- }
- visited[index] = true
- }
- index++
- if index > max {
- max = index
- }
-
- // check element against composite literal element type
- var x operand
- check.exprWithHint(&x, eval, typ)
- check.assignment(&x, typ, "array or slice literal")
- }
- return max
-}
diff --git a/contrib/go/_std_1.20/src/go/types/infer.go b/contrib/go/_std_1.20/src/go/types/infer.go
deleted file mode 100644
index dc87902c4c..0000000000
--- a/contrib/go/_std_1.20/src/go/types/infer.go
+++ /dev/null
@@ -1,773 +0,0 @@
-// Copyright 2018 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.
-
-// This file implements type parameter inference given
-// a list of concrete arguments and a parameter list.
-
-package types
-
-import (
- "fmt"
- "go/token"
- . "internal/types/errors"
- "strings"
-)
-
-// infer attempts to infer the complete set of type arguments for generic function instantiation/call
-// based on the given type parameters tparams, type arguments targs, function parameters params, and
-// function arguments args, if any. There must be at least one type parameter, no more type arguments
-// than type parameters, and params and args must match in number (incl. zero).
-// If successful, infer returns the complete list of type arguments, one for each type parameter.
-// Otherwise the result is nil and appropriate errors will be reported.
-//
-// Inference proceeds as follows:
-//
-// Starting with given type arguments
-// 1) apply FTI (function type inference) with typed arguments,
-// 2) apply CTI (constraint type inference),
-// 3) apply FTI with untyped function arguments,
-// 4) apply CTI.
-//
-// The process stops as soon as all type arguments are known or an error occurs.
-func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type, params *Tuple, args []*operand) (result []Type) {
- if debug {
- defer func() {
- assert(result == nil || len(result) == len(tparams))
- for _, targ := range result {
- assert(targ != nil)
- }
- //check.dump("### inferred targs = %s", result)
- }()
- }
-
- if traceInference {
- check.dump("-- inferA %s%s ➞ %s", tparams, params, targs)
- defer func() {
- check.dump("=> inferA %s ➞ %s", tparams, result)
- }()
- }
-
- // There must be at least one type parameter, and no more type arguments than type parameters.
- n := len(tparams)
- assert(n > 0 && len(targs) <= n)
-
- // Function parameters and arguments must match in number.
- assert(params.Len() == len(args))
-
- // If we already have all type arguments, we're done.
- if len(targs) == n {
- return targs
- }
- // len(targs) < n
-
- const enableTparamRenaming = true
- if enableTparamRenaming {
- // For the purpose of type inference we must differentiate type parameters
- // occurring in explicit type or value function arguments from the type
- // parameters we are solving for via unification, because they may be the
- // same in self-recursive calls. For example:
- //
- // func f[P *Q, Q any](p P, q Q) {
- // f(p)
- // }
- //
- // In this example, the fact that the P used in the instantation f[P] has
- // the same pointer identity as the P we are trying to solve for via
- // unification is coincidental: there is nothing special about recursive
- // calls that should cause them to conflate the identity of type arguments
- // with type parameters. To put it another way: any such self-recursive
- // call is equivalent to a mutually recursive call, which does not run into
- // any problems of type parameter identity. For example, the following code
- // is equivalent to the code above.
- //
- // func f[P interface{*Q}, Q any](p P, q Q) {
- // f2(p)
- // }
- //
- // func f2[P interface{*Q}, Q any](p P, q Q) {
- // f(p)
- // }
- //
- // We turn the first example into the second example by renaming type
- // parameters in the original signature to give them a new identity.
- tparams2 := make([]*TypeParam, len(tparams))
- for i, tparam := range tparams {
- tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
- tparams2[i] = NewTypeParam(tname, nil)
- tparams2[i].index = tparam.index // == i
- }
-
- renameMap := makeRenameMap(tparams, tparams2)
- for i, tparam := range tparams {
- tparams2[i].bound = check.subst(posn.Pos(), tparam.bound, renameMap, nil, check.context())
- }
-
- tparams = tparams2
- params = check.subst(posn.Pos(), params, renameMap, nil, check.context()).(*Tuple)
- }
-
- // If we have more than 2 arguments, we may have arguments with named and unnamed types.
- // If that is the case, permutate params and args such that the arguments with named
- // types are first in the list. This doesn't affect type inference if all types are taken
- // as is. But when we have inexact unification enabled (as is the case for function type
- // inference), when a named type is unified with an unnamed type, unification proceeds
- // with the underlying type of the named type because otherwise unification would fail
- // right away. This leads to an asymmetry in type inference: in cases where arguments of
- // named and unnamed types are passed to parameters with identical type, different types
- // (named vs underlying) may be inferred depending on the order of the arguments.
- // By ensuring that named types are seen first, order dependence is avoided and unification
- // succeeds where it can (issue #43056).
- const enableArgSorting = true
- if m := len(args); m >= 2 && enableArgSorting {
- // Determine indices of arguments with named and unnamed types.
- var named, unnamed []int
- for i, arg := range args {
- if hasName(arg.typ) {
- named = append(named, i)
- } else {
- unnamed = append(unnamed, i)
- }
- }
-
- // If we have named and unnamed types, move the arguments with
- // named types first. Update the parameter list accordingly.
- // Make copies so as not to clobber the incoming slices.
- if len(named) != 0 && len(unnamed) != 0 {
- params2 := make([]*Var, m)
- args2 := make([]*operand, m)
- i := 0
- for _, j := range named {
- params2[i] = params.At(j)
- args2[i] = args[j]
- i++
- }
- for _, j := range unnamed {
- params2[i] = params.At(j)
- args2[i] = args[j]
- i++
- }
- params = NewTuple(params2...)
- args = args2
- }
- }
-
- // --- 1 ---
- // Continue with the type arguments we have. Avoid matching generic
- // parameters that already have type arguments against function arguments:
- // It may fail because matching uses type identity while parameter passing
- // uses assignment rules. Instantiate the parameter list with the type
- // arguments we have, and continue with that parameter list.
-
- // First, make sure we have a "full" list of type arguments, some of which
- // may be nil (unknown). Make a copy so as to not clobber the incoming slice.
- if len(targs) < n {
- targs2 := make([]Type, n)
- copy(targs2, targs)
- targs = targs2
- }
- // len(targs) == n
-
- // Substitute type arguments for their respective type parameters in params,
- // if any. Note that nil targs entries are ignored by check.subst.
- // TODO(gri) Can we avoid this (we're setting known type arguments below,
- // but that doesn't impact the isParameterized check for now).
- if params.Len() > 0 {
- smap := makeSubstMap(tparams, targs)
- params = check.subst(token.NoPos, params, smap, nil, check.context()).(*Tuple)
- }
-
- // Unify parameter and argument types for generic parameters with typed arguments
- // and collect the indices of generic parameters with untyped arguments.
- // Terminology: generic parameter = function parameter with a type-parameterized type
- u := newUnifier(false)
- u.x.init(tparams)
-
- // Set the type arguments which we know already.
- for i, targ := range targs {
- if targ != nil {
- u.x.set(i, targ)
- }
- }
-
- errorf := func(kind string, tpar, targ Type, arg *operand) {
- // provide a better error message if we can
- targs, index := u.x.types()
- if index == 0 {
- // The first type parameter couldn't be inferred.
- // If none of them could be inferred, don't try
- // to provide the inferred type in the error msg.
- allFailed := true
- for _, targ := range targs {
- if targ != nil {
- allFailed = false
- break
- }
- }
- if allFailed {
- check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match %s (cannot infer %s)", kind, targ, arg.expr, tpar, typeParamsString(tparams))
- return
- }
- }
- smap := makeSubstMap(tparams, targs)
- // TODO(rFindley): pass a positioner here, rather than arg.Pos().
- inferred := check.subst(arg.Pos(), tpar, smap, nil, check.context())
- // _CannotInferTypeArgs indicates a failure of inference, though the actual
- // error may be better attributed to a user-provided type argument (hence
- // _InvalidTypeArg). We can't differentiate these cases, so fall back on
- // the more general _CannotInferTypeArgs.
- if inferred != tpar {
- check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match inferred type %s for %s", kind, targ, arg.expr, inferred, tpar)
- } else {
- check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match %s", kind, targ, arg.expr, tpar)
- }
- }
-
- // indices of the generic parameters with untyped arguments - save for later
- var indices []int
- for i, arg := range args {
- par := params.At(i)
- // If we permit bidirectional unification, this conditional code needs to be
- // executed even if par.typ is not parameterized since the argument may be a
- // generic function (for which we want to infer its type arguments).
- if isParameterized(tparams, par.typ) {
- if arg.mode == invalid {
- // An error was reported earlier. Ignore this targ
- // and continue, we may still be able to infer all
- // targs resulting in fewer follow-on errors.
- continue
- }
- if targ := arg.typ; isTyped(targ) {
- // If we permit bidirectional unification, and targ is
- // a generic function, we need to initialize u.y with
- // the respective type parameters of targ.
- if !u.unify(par.typ, targ) {
- errorf("type", par.typ, targ, arg)
- return nil
- }
- } else if _, ok := par.typ.(*TypeParam); ok {
- // Since default types are all basic (i.e., non-composite) types, an
- // untyped argument will never match a composite parameter type; the
- // only parameter type it can possibly match against is a *TypeParam.
- // Thus, for untyped arguments we only need to look at parameter types
- // that are single type parameters.
- indices = append(indices, i)
- }
- }
- }
-
- // If we've got all type arguments, we're done.
- var index int
- targs, index = u.x.types()
- if index < 0 {
- return targs
- }
-
- // --- 2 ---
- // See how far we get with constraint type inference.
- // Note that even if we don't have any type arguments, constraint type inference
- // may produce results for constraints that explicitly specify a type.
- targs, index = check.inferB(posn, tparams, targs)
- if targs == nil || index < 0 {
- return targs
- }
-
- // --- 3 ---
- // Use any untyped arguments to infer additional type arguments.
- // Some generic parameters with untyped arguments may have been given
- // a type by now, we can ignore them.
- for _, i := range indices {
- tpar := params.At(i).typ.(*TypeParam) // is type parameter by construction of indices
- // Only consider untyped arguments for which the corresponding type
- // parameter doesn't have an inferred type yet.
- if targs[tpar.index] == nil {
- arg := args[i]
- targ := Default(arg.typ)
- // The default type for an untyped nil is untyped nil. We must not
- // infer an untyped nil type as type parameter type. Ignore untyped
- // nil by making sure all default argument types are typed.
- if isTyped(targ) && !u.unify(tpar, targ) {
- errorf("default type", tpar, targ, arg)
- return nil
- }
- }
- }
-
- // If we've got all type arguments, we're done.
- targs, index = u.x.types()
- if index < 0 {
- return targs
- }
-
- // --- 4 ---
- // Again, follow up with constraint type inference.
- targs, index = check.inferB(posn, tparams, targs)
- if targs == nil || index < 0 {
- return targs
- }
-
- // At least one type argument couldn't be inferred.
- assert(index >= 0 && targs[index] == nil)
- tpar := tparams[index]
- check.errorf(posn, CannotInferTypeArgs, "cannot infer %s (%v)", tpar.obj.name, tpar.obj.pos)
- return nil
-}
-
-// typeParamsString produces a string containing all the type parameter names
-// in list suitable for human consumption.
-func typeParamsString(list []*TypeParam) string {
- // common cases
- n := len(list)
- switch n {
- case 0:
- return ""
- case 1:
- return list[0].obj.name
- case 2:
- return list[0].obj.name + " and " + list[1].obj.name
- }
-
- // general case (n > 2)
- var buf strings.Builder
- for i, tname := range list[:n-1] {
- if i > 0 {
- buf.WriteString(", ")
- }
- buf.WriteString(tname.obj.name)
- }
- buf.WriteString(", and ")
- buf.WriteString(list[n-1].obj.name)
- return buf.String()
-}
-
-// isParameterized reports whether typ contains any of the type parameters of tparams.
-func isParameterized(tparams []*TypeParam, typ Type) bool {
- w := tpWalker{
- seen: make(map[Type]bool),
- tparams: tparams,
- }
- return w.isParameterized(typ)
-}
-
-type tpWalker struct {
- seen map[Type]bool
- tparams []*TypeParam
-}
-
-func (w *tpWalker) isParameterized(typ Type) (res bool) {
- // detect cycles
- if x, ok := w.seen[typ]; ok {
- return x
- }
- w.seen[typ] = false
- defer func() {
- w.seen[typ] = res
- }()
-
- switch t := typ.(type) {
- case nil, *Basic: // TODO(gri) should nil be handled here?
- break
-
- case *Array:
- return w.isParameterized(t.elem)
-
- case *Slice:
- return w.isParameterized(t.elem)
-
- case *Struct:
- for _, fld := range t.fields {
- if w.isParameterized(fld.typ) {
- return true
- }
- }
-
- case *Pointer:
- return w.isParameterized(t.base)
-
- case *Tuple:
- n := t.Len()
- for i := 0; i < n; i++ {
- if w.isParameterized(t.At(i).typ) {
- return true
- }
- }
-
- case *Signature:
- // t.tparams may not be nil if we are looking at a signature
- // of a generic function type (or an interface method) that is
- // part of the type we're testing. We don't care about these type
- // parameters.
- // Similarly, the receiver of a method may declare (rather then
- // use) type parameters, we don't care about those either.
- // Thus, we only need to look at the input and result parameters.
- return w.isParameterized(t.params) || w.isParameterized(t.results)
-
- case *Interface:
- tset := t.typeSet()
- for _, m := range tset.methods {
- if w.isParameterized(m.typ) {
- return true
- }
- }
- return tset.is(func(t *term) bool {
- return t != nil && w.isParameterized(t.typ)
- })
-
- case *Map:
- return w.isParameterized(t.key) || w.isParameterized(t.elem)
-
- case *Chan:
- return w.isParameterized(t.elem)
-
- case *Named:
- return w.isParameterizedTypeList(t.TypeArgs().list())
-
- case *TypeParam:
- // t must be one of w.tparams
- return tparamIndex(w.tparams, t) >= 0
-
- default:
- unreachable()
- }
-
- return false
-}
-
-func (w *tpWalker) isParameterizedTypeList(list []Type) bool {
- for _, t := range list {
- if w.isParameterized(t) {
- return true
- }
- }
- return false
-}
-
-// inferB returns the list of actual type arguments inferred from the type parameters'
-// bounds and an initial set of type arguments. If type inference is impossible because
-// unification fails, an error is reported if report is set to true, the resulting types
-// list is nil, and index is 0.
-// Otherwise, types is the list of inferred type arguments, and index is the index of the
-// first type argument in that list that couldn't be inferred (and thus is nil). If all
-// type arguments were inferred successfully, index is < 0. The number of type arguments
-// provided may be less than the number of type parameters, but there must be at least one.
-func (check *Checker) inferB(posn positioner, tparams []*TypeParam, targs []Type) (types []Type, index int) {
- assert(len(tparams) >= len(targs) && len(targs) > 0)
-
- if traceInference {
- check.dump("-- inferB %s ➞ %s", tparams, targs)
- defer func() {
- check.dump("=> inferB %s ➞ %s", tparams, types)
- }()
- }
-
- // Setup bidirectional unification between constraints
- // and the corresponding type arguments (which may be nil!).
- u := newUnifier(false)
- u.x.init(tparams)
- u.y = u.x // type parameters between LHS and RHS of unification are identical
-
- // Set the type arguments which we know already.
- for i, targ := range targs {
- if targ != nil {
- u.x.set(i, targ)
- }
- }
-
- // Repeatedly apply constraint type inference as long as
- // there are still unknown type arguments and progress is
- // being made.
- //
- // This is an O(n^2) algorithm where n is the number of
- // type parameters: if there is progress (and iteration
- // continues), at least one type argument is inferred
- // per iteration and we have a doubly nested loop.
- // In practice this is not a problem because the number
- // of type parameters tends to be very small (< 5 or so).
- // (It should be possible for unification to efficiently
- // signal newly inferred type arguments; then the loops
- // here could handle the respective type parameters only,
- // but that will come at a cost of extra complexity which
- // may not be worth it.)
- for n := u.x.unknowns(); n > 0; {
- nn := n
-
- for i, tpar := range tparams {
- // If there is a core term (i.e., a core type with tilde information)
- // unify the type parameter with the core type.
- if core, single := coreTerm(tpar); core != nil {
- // A type parameter can be unified with its core type in two cases.
- tx := u.x.at(i)
- switch {
- case tx != nil:
- // The corresponding type argument tx is known.
- // In this case, if the core type has a tilde, the type argument's underlying
- // type must match the core type, otherwise the type argument and the core type
- // must match.
- // If tx is an external type parameter, don't consider its underlying type
- // (which is an interface). Core type unification will attempt to unify against
- // core.typ.
- // Note also that even with inexact unification we cannot leave away the under
- // call here because it's possible that both tx and core.typ are named types,
- // with under(tx) being a (named) basic type matching core.typ. Such cases do
- // not match with inexact unification.
- if core.tilde && !isTypeParam(tx) {
- tx = under(tx)
- }
- if !u.unify(tx, core.typ) {
- // TODO(gri) improve error message by providing the type arguments
- // which we know already
- // Don't use term.String() as it always qualifies types, even if they
- // are in the current package.
- tilde := ""
- if core.tilde {
- tilde = "~"
- }
- check.errorf(posn, InvalidTypeArg, "%s does not match %s%s", tx, tilde, core.typ)
- return nil, 0
- }
-
- case single && !core.tilde:
- // The corresponding type argument tx is unknown and there's a single
- // specific type and no tilde.
- // In this case the type argument must be that single type; set it.
- u.x.set(i, core.typ)
-
- default:
- // Unification is not possible and no progress was made.
- continue
- }
-
- // The number of known type arguments may have changed.
- nn = u.x.unknowns()
- if nn == 0 {
- break // all type arguments are known
- }
- }
- }
-
- assert(nn <= n)
- if nn == n {
- break // no progress
- }
- n = nn
- }
-
- // u.x.types() now contains the incoming type arguments plus any additional type
- // arguments which were inferred from core terms. The newly inferred non-nil
- // entries may still contain references to other type parameters.
- // For instance, for [A any, B interface{ []C }, C interface{ *A }], if A == int
- // was given, unification produced the type list [int, []C, *A]. We eliminate the
- // remaining type parameters by substituting the type parameters in this type list
- // until nothing changes anymore.
- types, _ = u.x.types()
- if debug {
- for i, targ := range targs {
- assert(targ == nil || types[i] == targ)
- }
- }
-
- // The data structure of each (provided or inferred) type represents a graph, where
- // each node corresponds to a type and each (directed) vertex points to a component
- // type. The substitution process described above repeatedly replaces type parameter
- // nodes in these graphs with the graphs of the types the type parameters stand for,
- // which creates a new (possibly bigger) graph for each type.
- // The substitution process will not stop if the replacement graph for a type parameter
- // also contains that type parameter.
- // For instance, for [A interface{ *A }], without any type argument provided for A,
- // unification produces the type list [*A]. Substituting A in *A with the value for
- // A will lead to infinite expansion by producing [**A], [****A], [********A], etc.,
- // because the graph A -> *A has a cycle through A.
- // Generally, cycles may occur across multiple type parameters and inferred types
- // (for instance, consider [P interface{ *Q }, Q interface{ func(P) }]).
- // We eliminate cycles by walking the graphs for all type parameters. If a cycle
- // through a type parameter is detected, cycleFinder nils out the respective type
- // which kills the cycle; this also means that the respective type could not be
- // inferred.
- //
- // TODO(gri) If useful, we could report the respective cycle as an error. We don't
- // do this now because type inference will fail anyway, and furthermore,
- // constraints with cycles of this kind cannot currently be satisfied by
- // any user-supplied type. But should that change, reporting an error
- // would be wrong.
- w := cycleFinder{tparams, types, make(map[Type]bool)}
- for _, t := range tparams {
- w.typ(t) // t != nil
- }
-
- // dirty tracks the indices of all types that may still contain type parameters.
- // We know that nil type entries and entries corresponding to provided (non-nil)
- // type arguments are clean, so exclude them from the start.
- var dirty []int
- for i, typ := range types {
- if typ != nil && (i >= len(targs) || targs[i] == nil) {
- dirty = append(dirty, i)
- }
- }
-
- for len(dirty) > 0 {
- // TODO(gri) Instead of creating a new substMap for each iteration,
- // provide an update operation for substMaps and only change when
- // needed. Optimization.
- smap := makeSubstMap(tparams, types)
- n := 0
- for _, index := range dirty {
- t0 := types[index]
- if t1 := check.subst(token.NoPos, t0, smap, nil, check.context()); t1 != t0 {
- types[index] = t1
- dirty[n] = index
- n++
- }
- }
- dirty = dirty[:n]
- }
-
- // Once nothing changes anymore, we may still have type parameters left;
- // e.g., a constraint with core type *P may match a type parameter Q but
- // we don't have any type arguments to fill in for *P or Q (issue #45548).
- // Don't let such inferences escape, instead nil them out.
- for i, typ := range types {
- if typ != nil && isParameterized(tparams, typ) {
- types[i] = nil
- }
- }
-
- // update index
- index = -1
- for i, typ := range types {
- if typ == nil {
- index = i
- break
- }
- }
-
- return
-}
-
-// If the type parameter has a single specific type S, coreTerm returns (S, true).
-// Otherwise, if tpar has a core type T, it returns a term corresponding to that
-// core type and false. In that case, if any term of tpar has a tilde, the core
-// term has a tilde. In all other cases coreTerm returns (nil, false).
-func coreTerm(tpar *TypeParam) (*term, bool) {
- n := 0
- var single *term // valid if n == 1
- var tilde bool
- tpar.is(func(t *term) bool {
- if t == nil {
- assert(n == 0)
- return false // no terms
- }
- n++
- single = t
- if t.tilde {
- tilde = true
- }
- return true
- })
- if n == 1 {
- if debug {
- assert(debug && under(single.typ) == coreType(tpar))
- }
- return single, true
- }
- if typ := coreType(tpar); typ != nil {
- // A core type is always an underlying type.
- // If any term of tpar has a tilde, we don't
- // have a precise core type and we must return
- // a tilde as well.
- return &term{tilde, typ}, false
- }
- return nil, false
-}
-
-type cycleFinder struct {
- tparams []*TypeParam
- types []Type
- seen map[Type]bool
-}
-
-func (w *cycleFinder) typ(typ Type) {
- if w.seen[typ] {
- // We have seen typ before. If it is one of the type parameters
- // in tparams, iterative substitution will lead to infinite expansion.
- // Nil out the corresponding type which effectively kills the cycle.
- if tpar, _ := typ.(*TypeParam); tpar != nil {
- if i := tparamIndex(w.tparams, tpar); i >= 0 {
- // cycle through tpar
- w.types[i] = nil
- }
- }
- // If we don't have one of our type parameters, the cycle is due
- // to an ordinary recursive type and we can just stop walking it.
- return
- }
- w.seen[typ] = true
- defer delete(w.seen, typ)
-
- switch t := typ.(type) {
- case *Basic:
- // nothing to do
-
- case *Array:
- w.typ(t.elem)
-
- case *Slice:
- w.typ(t.elem)
-
- case *Struct:
- w.varList(t.fields)
-
- case *Pointer:
- w.typ(t.base)
-
- // case *Tuple:
- // This case should not occur because tuples only appear
- // in signatures where they are handled explicitly.
-
- case *Signature:
- if t.params != nil {
- w.varList(t.params.vars)
- }
- if t.results != nil {
- w.varList(t.results.vars)
- }
-
- case *Union:
- for _, t := range t.terms {
- w.typ(t.typ)
- }
-
- case *Interface:
- for _, m := range t.methods {
- w.typ(m.typ)
- }
- for _, t := range t.embeddeds {
- w.typ(t)
- }
-
- case *Map:
- w.typ(t.key)
- w.typ(t.elem)
-
- case *Chan:
- w.typ(t.elem)
-
- case *Named:
- for _, tpar := range t.TypeArgs().list() {
- w.typ(tpar)
- }
-
- case *TypeParam:
- if i := tparamIndex(w.tparams, t); i >= 0 && w.types[i] != nil {
- w.typ(w.types[i])
- }
-
- default:
- panic(fmt.Sprintf("unexpected %T", typ))
- }
-}
-
-func (w *cycleFinder) varList(list []*Var) {
- for _, v := range list {
- w.typ(v.typ)
- }
-}
diff --git a/contrib/go/_std_1.20/src/go/types/instantiate.go b/contrib/go/_std_1.20/src/go/types/instantiate.go
deleted file mode 100644
index 2cf48c17d2..0000000000
--- a/contrib/go/_std_1.20/src/go/types/instantiate.go
+++ /dev/null
@@ -1,366 +0,0 @@
-// 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.
-
-// This file implements instantiation of generic types
-// through substitution of type parameters by type arguments.
-
-package types
-
-import (
- "errors"
- "fmt"
- "go/token"
- . "internal/types/errors"
-)
-
-// Instantiate instantiates the type orig with the given type arguments targs.
-// orig must be a *Named or a *Signature type. If there is no error, the
-// resulting Type is an instantiated type of the same kind (either a *Named or
-// a *Signature). Methods attached to a *Named type are also instantiated, and
-// associated with a new *Func that has the same position as the original
-// method, but nil function scope.
-//
-// If ctxt is non-nil, it may be used to de-duplicate the instance against
-// previous instances with the same identity. As a special case, generic
-// *Signature origin types are only considered identical if they are pointer
-// equivalent, so that instantiating distinct (but possibly identical)
-// signatures will yield different instances. The use of a shared context does
-// not guarantee that identical instances are deduplicated in all cases.
-//
-// If validate is set, Instantiate verifies that the number of type arguments
-// and parameters match, and that the type arguments satisfy their
-// corresponding type constraints. If verification fails, the resulting error
-// may wrap an *ArgumentError indicating which type argument did not satisfy
-// its corresponding type parameter constraint, and why.
-//
-// If validate is not set, Instantiate does not verify the type argument count
-// or whether the type arguments satisfy their constraints. Instantiate is
-// guaranteed to not return an error, but may panic. Specifically, for
-// *Signature types, Instantiate will panic immediately if the type argument
-// count is incorrect; for *Named types, a panic may occur later inside the
-// *Named API.
-func Instantiate(ctxt *Context, orig Type, targs []Type, validate bool) (Type, error) {
- if ctxt == nil {
- ctxt = NewContext()
- }
- if validate {
- var tparams []*TypeParam
- switch t := orig.(type) {
- case *Named:
- tparams = t.TypeParams().list()
- case *Signature:
- tparams = t.TypeParams().list()
- }
- if len(targs) != len(tparams) {
- return nil, fmt.Errorf("got %d type arguments but %s has %d type parameters", len(targs), orig, len(tparams))
- }
- if i, err := (*Checker)(nil).verify(token.NoPos, tparams, targs, ctxt); err != nil {
- return nil, &ArgumentError{i, err}
- }
- }
-
- inst := (*Checker)(nil).instance(token.NoPos, orig, targs, nil, ctxt)
- return inst, nil
-}
-
-// instance instantiates the given original (generic) function or type with the
-// provided type arguments and returns the resulting instance. If an identical
-// instance exists already in the given contexts, it returns that instance,
-// otherwise it creates a new one.
-//
-// If expanding is non-nil, it is the Named instance type currently being
-// expanded. If ctxt is non-nil, it is the context associated with the current
-// type-checking pass or call to Instantiate. At least one of expanding or ctxt
-// must be non-nil.
-//
-// For Named types the resulting instance may be unexpanded.
-func (check *Checker) instance(pos token.Pos, orig Type, targs []Type, expanding *Named, ctxt *Context) (res Type) {
- // The order of the contexts below matters: we always prefer instances in the
- // expanding instance context in order to preserve reference cycles.
- //
- // Invariant: if expanding != nil, the returned instance will be the instance
- // recorded in expanding.inst.ctxt.
- var ctxts []*Context
- if expanding != nil {
- ctxts = append(ctxts, expanding.inst.ctxt)
- }
- if ctxt != nil {
- ctxts = append(ctxts, ctxt)
- }
- assert(len(ctxts) > 0)
-
- // Compute all hashes; hashes may differ across contexts due to different
- // unique IDs for Named types within the hasher.
- hashes := make([]string, len(ctxts))
- for i, ctxt := range ctxts {
- hashes[i] = ctxt.instanceHash(orig, targs)
- }
-
- // If local is non-nil, updateContexts return the type recorded in
- // local.
- updateContexts := func(res Type) Type {
- for i := len(ctxts) - 1; i >= 0; i-- {
- res = ctxts[i].update(hashes[i], orig, targs, res)
- }
- return res
- }
-
- // typ may already have been instantiated with identical type arguments. In
- // that case, re-use the existing instance.
- for i, ctxt := range ctxts {
- if inst := ctxt.lookup(hashes[i], orig, targs); inst != nil {
- return updateContexts(inst)
- }
- }
-
- switch orig := orig.(type) {
- case *Named:
- res = check.newNamedInstance(pos, orig, targs, expanding) // substituted lazily
-
- case *Signature:
- assert(expanding == nil) // function instances cannot be reached from Named types
-
- tparams := orig.TypeParams()
- if !check.validateTArgLen(pos, tparams.Len(), len(targs)) {
- return Typ[Invalid]
- }
- if tparams.Len() == 0 {
- return orig // nothing to do (minor optimization)
- }
- sig := check.subst(pos, orig, makeSubstMap(tparams.list(), targs), nil, ctxt).(*Signature)
- // If the signature doesn't use its type parameters, subst
- // will not make a copy. In that case, make a copy now (so
- // we can set tparams to nil w/o causing side-effects).
- if sig == orig {
- copy := *sig
- sig = &copy
- }
- // After instantiating a generic signature, it is not generic
- // anymore; we need to set tparams to nil.
- sig.tparams = nil
- res = sig
-
- default:
- // only types and functions can be generic
- panic(fmt.Sprintf("%v: cannot instantiate %v", pos, orig))
- }
-
- // Update all contexts; it's possible that we've lost a race.
- return updateContexts(res)
-}
-
-// validateTArgLen verifies that the length of targs and tparams matches,
-// reporting an error if not. If validation fails and check is nil,
-// validateTArgLen panics.
-func (check *Checker) validateTArgLen(pos token.Pos, ntparams, ntargs int) bool {
- if ntargs != ntparams {
- // TODO(gri) provide better error message
- if check != nil {
- check.errorf(atPos(pos), WrongTypeArgCount, "got %d arguments but %d type parameters", ntargs, ntparams)
- return false
- }
- panic(fmt.Sprintf("%v: got %d arguments but %d type parameters", pos, ntargs, ntparams))
- }
- return true
-}
-
-func (check *Checker) verify(pos token.Pos, tparams []*TypeParam, targs []Type, ctxt *Context) (int, error) {
- smap := makeSubstMap(tparams, targs)
- for i, tpar := range tparams {
- // Ensure that we have a (possibly implicit) interface as type bound (issue #51048).
- tpar.iface()
- // The type parameter bound is parameterized with the same type parameters
- // as the instantiated type; before we can use it for bounds checking we
- // need to instantiate it with the type arguments with which we instantiated
- // the parameterized type.
- bound := check.subst(pos, tpar.bound, smap, nil, ctxt)
- var cause string
- if !check.implements(targs[i], bound, true, &cause) {
- return i, errors.New(cause)
- }
- }
- return -1, nil
-}
-
-// implements checks if V implements T. The receiver may be nil if implements
-// is called through an exported API call such as AssignableTo. If constraint
-// is set, T is a type constraint.
-//
-// If the provided cause is non-nil, it may be set to an error string
-// explaining why V does not implement (or satisfy, for constraints) T.
-func (check *Checker) implements(V, T Type, constraint bool, cause *string) bool {
- Vu := under(V)
- Tu := under(T)
- if Vu == Typ[Invalid] || Tu == Typ[Invalid] {
- return true // avoid follow-on errors
- }
- if p, _ := Vu.(*Pointer); p != nil && under(p.base) == Typ[Invalid] {
- return true // avoid follow-on errors (see issue #49541 for an example)
- }
-
- verb := "implement"
- if constraint {
- verb = "satisfy"
- }
-
- Ti, _ := Tu.(*Interface)
- if Ti == nil {
- if cause != nil {
- var detail string
- if isInterfacePtr(Tu) {
- detail = check.sprintf("type %s is pointer to interface, not interface", T)
- } else {
- detail = check.sprintf("%s is not an interface", T)
- }
- *cause = check.sprintf("%s does not %s %s (%s)", V, verb, T, detail)
- }
- return false
- }
-
- // Every type satisfies the empty interface.
- if Ti.Empty() {
- return true
- }
- // T is not the empty interface (i.e., the type set of T is restricted)
-
- // An interface V with an empty type set satisfies any interface.
- // (The empty set is a subset of any set.)
- Vi, _ := Vu.(*Interface)
- if Vi != nil && Vi.typeSet().IsEmpty() {
- return true
- }
- // type set of V is not empty
-
- // No type with non-empty type set satisfies the empty type set.
- if Ti.typeSet().IsEmpty() {
- if cause != nil {
- *cause = check.sprintf("cannot %s %s (empty type set)", verb, T)
- }
- return false
- }
-
- // V must implement T's methods, if any.
- if m, wrong := check.missingMethod(V, Ti, true); m != nil /* !Implements(V, Ti) */ {
- if cause != nil {
- *cause = check.sprintf("%s does not %s %s %s", V, verb, T, check.missingMethodCause(V, T, m, wrong))
- }
- return false
- }
-
- // Only check comparability if we don't have a more specific error.
- checkComparability := func() bool {
- if !Ti.IsComparable() {
- return true
- }
- // If T is comparable, V must be comparable.
- // If V is strictly comparable, we're done.
- if comparable(V, false /* strict comparability */, nil, nil) {
- return true
- }
- // If check.conf.OldComparableSemantics is set (by the compiler or
- // a test), we only consider strict comparability and we're done.
- // TODO(gri) remove this check for Go 1.21
- if check != nil && check.conf.oldComparableSemantics {
- if cause != nil {
- *cause = check.sprintf("%s does not %s comparable", V, verb)
- }
- return false
- }
- // For constraint satisfaction, use dynamic (spec) comparability
- // so that ordinary, non-type parameter interfaces implement comparable.
- if constraint && comparable(V, true /* spec comparability */, nil, nil) {
- // V is comparable if we are at Go 1.20 or higher.
- if check == nil || check.allowVersion(check.pkg, 1, 20) {
- return true
- }
- if cause != nil {
- *cause = check.sprintf("%s to %s comparable requires go1.20 or later", V, verb)
- }
- return false
- }
- if cause != nil {
- *cause = check.sprintf("%s does not %s comparable", V, verb)
- }
- return false
- }
-
- // V must also be in the set of types of T, if any.
- // Constraints with empty type sets were already excluded above.
- if !Ti.typeSet().hasTerms() {
- return checkComparability() // nothing to do
- }
-
- // If V is itself an interface, each of its possible types must be in the set
- // of T types (i.e., the V type set must be a subset of the T type set).
- // Interfaces V with empty type sets were already excluded above.
- if Vi != nil {
- if !Vi.typeSet().subsetOf(Ti.typeSet()) {
- // TODO(gri) report which type is missing
- if cause != nil {
- *cause = check.sprintf("%s does not %s %s", V, verb, T)
- }
- return false
- }
- return checkComparability()
- }
-
- // Otherwise, V's type must be included in the iface type set.
- var alt Type
- if Ti.typeSet().is(func(t *term) bool {
- if !t.includes(V) {
- // If V ∉ t.typ but V ∈ ~t.typ then remember this type
- // so we can suggest it as an alternative in the error
- // message.
- if alt == nil && !t.tilde && Identical(t.typ, under(t.typ)) {
- tt := *t
- tt.tilde = true
- if tt.includes(V) {
- alt = t.typ
- }
- }
- return true
- }
- return false
- }) {
- if cause != nil {
- var detail string
- switch {
- case alt != nil:
- detail = check.sprintf("possibly missing ~ for %s in %s", alt, T)
- case mentions(Ti, V):
- detail = check.sprintf("%s mentions %s, but %s is not in the type set of %s", T, V, V, T)
- default:
- detail = check.sprintf("%s missing in %s", V, Ti.typeSet().terms)
- }
- *cause = check.sprintf("%s does not %s %s (%s)", V, verb, T, detail)
- }
- return false
- }
-
- return checkComparability()
-}
-
-// mentions reports whether type T "mentions" typ in an (embedded) element or term
-// of T (whether typ is in the type set of T or not). For better error messages.
-func mentions(T, typ Type) bool {
- switch T := T.(type) {
- case *Interface:
- for _, e := range T.embeddeds {
- if mentions(e, typ) {
- return true
- }
- }
- case *Union:
- for _, t := range T.terms {
- if mentions(t.typ, typ) {
- return true
- }
- }
- default:
- if Identical(T, typ) {
- return true
- }
- }
- return false
-}
diff --git a/contrib/go/_std_1.20/src/go/types/interface.go b/contrib/go/_std_1.20/src/go/types/interface.go
deleted file mode 100644
index 83538d2885..0000000000
--- a/contrib/go/_std_1.20/src/go/types/interface.go
+++ /dev/null
@@ -1,233 +0,0 @@
-// 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 types
-
-import (
- "go/ast"
- "go/token"
- . "internal/types/errors"
-)
-
-// ----------------------------------------------------------------------------
-// API
-
-// An Interface represents an interface type.
-type Interface struct {
- check *Checker // for error reporting; nil once type set is computed
- methods []*Func // ordered list of explicitly declared methods
- embeddeds []Type // ordered list of explicitly embedded elements
- embedPos *[]token.Pos // positions of embedded elements; or nil (for error messages) - use pointer to save space
- implicit bool // interface is wrapper for type set literal (non-interface T, ~T, or A|B)
- complete bool // indicates that obj, methods, and embeddeds are set and type set can be computed
-
- tset *_TypeSet // type set described by this interface, computed lazily
-}
-
-// typeSet returns the type set for interface t.
-func (t *Interface) typeSet() *_TypeSet { return computeInterfaceTypeSet(t.check, token.NoPos, t) }
-
-// emptyInterface represents the empty (completed) interface
-var emptyInterface = Interface{complete: true, tset: &topTypeSet}
-
-// NewInterface returns a new interface for the given methods and embedded types.
-// NewInterface takes ownership of the provided methods and may modify their types
-// by setting missing receivers.
-//
-// Deprecated: Use NewInterfaceType instead which allows arbitrary embedded types.
-func NewInterface(methods []*Func, embeddeds []*Named) *Interface {
- tnames := make([]Type, len(embeddeds))
- for i, t := range embeddeds {
- tnames[i] = t
- }
- return NewInterfaceType(methods, tnames)
-}
-
-// NewInterfaceType returns a new interface for the given methods and embedded
-// types. NewInterfaceType takes ownership of the provided methods and may
-// modify their types by setting missing receivers.
-//
-// To avoid race conditions, the interface's type set should be computed before
-// concurrent use of the interface, by explicitly calling Complete.
-func NewInterfaceType(methods []*Func, embeddeds []Type) *Interface {
- if len(methods) == 0 && len(embeddeds) == 0 {
- return &emptyInterface
- }
-
- // set method receivers if necessary
- typ := (*Checker)(nil).newInterface()
- for _, m := range methods {
- if sig := m.typ.(*Signature); sig.recv == nil {
- sig.recv = NewVar(m.pos, m.pkg, "", typ)
- }
- }
-
- // sort for API stability
- sortMethods(methods)
-
- typ.methods = methods
- typ.embeddeds = embeddeds
- typ.complete = true
-
- return typ
-}
-
-// check may be nil
-func (check *Checker) newInterface() *Interface {
- typ := &Interface{check: check}
- if check != nil {
- check.needsCleanup(typ)
- }
- return typ
-}
-
-// MarkImplicit marks the interface t as implicit, meaning this interface
-// corresponds to a constraint literal such as ~T or A|B without explicit
-// interface embedding. MarkImplicit should be called before any concurrent use
-// of implicit interfaces.
-func (t *Interface) MarkImplicit() {
- t.implicit = true
-}
-
-// NumExplicitMethods returns the number of explicitly declared methods of interface t.
-func (t *Interface) NumExplicitMethods() int { return len(t.methods) }
-
-// ExplicitMethod returns the i'th explicitly declared method of interface t for 0 <= i < t.NumExplicitMethods().
-// The methods are ordered by their unique Id.
-func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] }
-
-// NumEmbeddeds returns the number of embedded types in interface t.
-func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) }
-
-// Embedded returns the i'th embedded defined (*Named) type of interface t for 0 <= i < t.NumEmbeddeds().
-// The result is nil if the i'th embedded type is not a defined type.
-//
-// Deprecated: Use EmbeddedType which is not restricted to defined (*Named) types.
-func (t *Interface) Embedded(i int) *Named { tname, _ := t.embeddeds[i].(*Named); return tname }
-
-// EmbeddedType returns the i'th embedded type of interface t for 0 <= i < t.NumEmbeddeds().
-func (t *Interface) EmbeddedType(i int) Type { return t.embeddeds[i] }
-
-// NumMethods returns the total number of methods of interface t.
-func (t *Interface) NumMethods() int { return t.typeSet().NumMethods() }
-
-// Method returns the i'th method of interface t for 0 <= i < t.NumMethods().
-// The methods are ordered by their unique Id.
-func (t *Interface) Method(i int) *Func { return t.typeSet().Method(i) }
-
-// Empty reports whether t is the empty interface.
-func (t *Interface) Empty() bool { return t.typeSet().IsAll() }
-
-// IsComparable reports whether each type in interface t's type set is comparable.
-func (t *Interface) IsComparable() bool { return t.typeSet().IsComparable(nil) }
-
-// IsMethodSet reports whether the interface t is fully described by its method
-// set.
-func (t *Interface) IsMethodSet() bool { return t.typeSet().IsMethodSet() }
-
-// IsImplicit reports whether the interface t is a wrapper for a type set literal.
-func (t *Interface) IsImplicit() bool { return t.implicit }
-
-// Complete computes the interface's type set. It must be called by users of
-// NewInterfaceType and NewInterface after the interface's embedded types are
-// fully defined and before using the interface type in any way other than to
-// form other types. The interface must not contain duplicate methods or a
-// panic occurs. Complete returns the receiver.
-//
-// Interface types that have been completed are safe for concurrent use.
-func (t *Interface) Complete() *Interface {
- if !t.complete {
- t.complete = true
- }
- t.typeSet() // checks if t.tset is already set
- return t
-}
-
-func (t *Interface) Underlying() Type { return t }
-func (t *Interface) String() string { return TypeString(t, nil) }
-
-// ----------------------------------------------------------------------------
-// Implementation
-
-func (t *Interface) cleanup() {
- t.check = nil
- t.embedPos = nil
-}
-
-func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named) {
- addEmbedded := func(pos token.Pos, typ Type) {
- ityp.embeddeds = append(ityp.embeddeds, typ)
- if ityp.embedPos == nil {
- ityp.embedPos = new([]token.Pos)
- }
- *ityp.embedPos = append(*ityp.embedPos, pos)
- }
-
- for _, f := range iface.Methods.List {
- if len(f.Names) == 0 {
- addEmbedded(f.Type.Pos(), parseUnion(check, f.Type))
- continue
- }
- // f.Name != nil
-
- // We have a method with name f.Names[0].
- name := f.Names[0]
- if name.Name == "_" {
- check.error(name, BlankIfaceMethod, "methods must have a unique non-blank name")
- continue // ignore
- }
-
- typ := check.typ(f.Type)
- sig, _ := typ.(*Signature)
- if sig == nil {
- if typ != Typ[Invalid] {
- check.errorf(f.Type, InvalidSyntaxTree, "%s is not a method signature", typ)
- }
- continue // ignore
- }
-
- // Always type-check method type parameters but complain if they are not enabled.
- // (This extra check is needed here because interface method signatures don't have
- // a receiver specification.)
- if sig.tparams != nil {
- var at positioner = f.Type
- if ftyp, _ := f.Type.(*ast.FuncType); ftyp != nil && ftyp.TypeParams != nil {
- at = ftyp.TypeParams
- }
- check.error(at, InvalidMethodTypeParams, "methods cannot have type parameters")
- }
-
- // use named receiver type if available (for better error messages)
- var recvTyp Type = ityp
- if def != nil {
- recvTyp = def
- }
- sig.recv = NewVar(name.Pos(), check.pkg, "", recvTyp)
-
- m := NewFunc(name.Pos(), check.pkg, name.Name, sig)
- check.recordDef(name, m)
- ityp.methods = append(ityp.methods, m)
- }
-
- // All methods and embedded elements for this interface are collected;
- // i.e., this interface may be used in a type set computation.
- ityp.complete = true
-
- if len(ityp.methods) == 0 && len(ityp.embeddeds) == 0 {
- // empty interface
- ityp.tset = &topTypeSet
- return
- }
-
- // sort for API stability
- sortMethods(ityp.methods)
- // (don't sort embeddeds: they must correspond to *embedPos entries)
-
- // Compute type set as soon as possible to report any errors.
- // Subsequent uses of type sets will use this computed type
- // set and won't need to pass in a *Checker.
- check.later(func() {
- computeInterfaceTypeSet(check, iface.Pos(), ityp)
- }).describef(iface, "compute type set for %s", ityp)
-}
diff --git a/contrib/go/_std_1.20/src/go/types/lookup.go b/contrib/go/_std_1.20/src/go/types/lookup.go
deleted file mode 100644
index 4eedcc23a1..0000000000
--- a/contrib/go/_std_1.20/src/go/types/lookup.go
+++ /dev/null
@@ -1,543 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements various field and method lookup functions.
-
-package types
-
-import (
- "bytes"
- "strings"
-)
-
-// Internal use of LookupFieldOrMethod: If the obj result is a method
-// associated with a concrete (non-interface) type, the method's signature
-// may not be fully set up. Call Checker.objDecl(obj, nil) before accessing
-// the method's type.
-
-// LookupFieldOrMethod looks up a field or method with given package and name
-// in T and returns the corresponding *Var or *Func, an index sequence, and a
-// bool indicating if there were any pointer indirections on the path to the
-// field or method. If addressable is set, T is the type of an addressable
-// variable (only matters for method lookups). T must not be nil.
-//
-// The last index entry is the field or method index in the (possibly embedded)
-// type where the entry was found, either:
-//
-// 1. the list of declared methods of a named type; or
-// 2. the list of all methods (method set) of an interface type; or
-// 3. the list of fields of a struct type.
-//
-// The earlier index entries are the indices of the embedded struct fields
-// traversed to get to the found entry, starting at depth 0.
-//
-// If no entry is found, a nil object is returned. In this case, the returned
-// index and indirect values have the following meaning:
-//
-// - If index != nil, the index sequence points to an ambiguous entry
-// (the same name appeared more than once at the same embedding level).
-//
-// - If indirect is set, a method with a pointer receiver type was found
-// but there was no pointer on the path from the actual receiver type to
-// the method's formal receiver base type, nor was the receiver addressable.
-func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
- if T == nil {
- panic("LookupFieldOrMethod on nil type")
- }
-
- // Methods cannot be associated to a named pointer type.
- // (spec: "The type denoted by T is called the receiver base type;
- // it must not be a pointer or interface type and it must be declared
- // in the same package as the method.").
- // Thus, if we have a named pointer type, proceed with the underlying
- // pointer type but discard the result if it is a method since we would
- // not have found it for T (see also issue 8590).
- if t, _ := T.(*Named); t != nil {
- if p, _ := t.Underlying().(*Pointer); p != nil {
- obj, index, indirect = lookupFieldOrMethod(p, false, pkg, name, false)
- if _, ok := obj.(*Func); ok {
- return nil, nil, false
- }
- return
- }
- }
-
- obj, index, indirect = lookupFieldOrMethod(T, addressable, pkg, name, false)
-
- // If we didn't find anything and if we have a type parameter with a core type,
- // see if there is a matching field (but not a method, those need to be declared
- // explicitly in the constraint). If the constraint is a named pointer type (see
- // above), we are ok here because only fields are accepted as results.
- const enableTParamFieldLookup = false // see issue #51576
- if enableTParamFieldLookup && obj == nil && isTypeParam(T) {
- if t := coreType(T); t != nil {
- obj, index, indirect = lookupFieldOrMethod(t, addressable, pkg, name, false)
- if _, ok := obj.(*Var); !ok {
- obj, index, indirect = nil, nil, false // accept fields (variables) only
- }
- }
- }
- return
-}
-
-// lookupFieldOrMethod should only be called by LookupFieldOrMethod and missingMethod.
-// If foldCase is true, the lookup for methods will include looking for any method
-// which case-folds to the same as 'name' (used for giving helpful error messages).
-//
-// The resulting object may not be fully type-checked.
-func lookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string, foldCase bool) (obj Object, index []int, indirect bool) {
- // WARNING: The code in this function is extremely subtle - do not modify casually!
-
- if name == "_" {
- return // blank fields/methods are never found
- }
-
- typ, isPtr := deref(T)
-
- // *typ where typ is an interface (incl. a type parameter) has no methods.
- if isPtr {
- if _, ok := under(typ).(*Interface); ok {
- return
- }
- }
-
- // Start with typ as single entry at shallowest depth.
- current := []embeddedType{{typ, nil, isPtr, false}}
-
- // seen tracks named types that we have seen already, allocated lazily.
- // Used to avoid endless searches in case of recursive types.
- //
- // We must use a lookup on identity rather than a simple map[*Named]bool as
- // instantiated types may be identical but not equal.
- var seen instanceLookup
-
- // search current depth
- for len(current) > 0 {
- var next []embeddedType // embedded types found at current depth
-
- // look for (pkg, name) in all types at current depth
- for _, e := range current {
- typ := e.typ
-
- // If we have a named type, we may have associated methods.
- // Look for those first.
- if named, _ := typ.(*Named); named != nil {
- if alt := seen.lookup(named); alt != nil {
- // We have seen this type before, at a more shallow depth
- // (note that multiples of this type at the current depth
- // were consolidated before). The type at that depth shadows
- // this same type at the current depth, so we can ignore
- // this one.
- continue
- }
- seen.add(named)
-
- // look for a matching attached method
- if i, m := named.lookupMethod(pkg, name, foldCase); m != nil {
- // potential match
- // caution: method may not have a proper signature yet
- index = concat(e.index, i)
- if obj != nil || e.multiples {
- return nil, index, false // collision
- }
- obj = m
- indirect = e.indirect
- continue // we can't have a matching field or interface method
- }
- }
-
- switch t := under(typ).(type) {
- case *Struct:
- // look for a matching field and collect embedded types
- for i, f := range t.fields {
- if f.sameId(pkg, name) {
- assert(f.typ != nil)
- index = concat(e.index, i)
- if obj != nil || e.multiples {
- return nil, index, false // collision
- }
- obj = f
- indirect = e.indirect
- continue // we can't have a matching interface method
- }
- // Collect embedded struct fields for searching the next
- // lower depth, but only if we have not seen a match yet
- // (if we have a match it is either the desired field or
- // we have a name collision on the same depth; in either
- // case we don't need to look further).
- // Embedded fields are always of the form T or *T where
- // T is a type name. If e.typ appeared multiple times at
- // this depth, f.typ appears multiple times at the next
- // depth.
- if obj == nil && f.embedded {
- typ, isPtr := deref(f.typ)
- // TODO(gri) optimization: ignore types that can't
- // have fields or methods (only Named, Struct, and
- // Interface types need to be considered).
- next = append(next, embeddedType{typ, concat(e.index, i), e.indirect || isPtr, e.multiples})
- }
- }
-
- case *Interface:
- // look for a matching method (interface may be a type parameter)
- if i, m := t.typeSet().LookupMethod(pkg, name, foldCase); m != nil {
- assert(m.typ != nil)
- index = concat(e.index, i)
- if obj != nil || e.multiples {
- return nil, index, false // collision
- }
- obj = m
- indirect = e.indirect
- }
- }
- }
-
- if obj != nil {
- // found a potential match
- // spec: "A method call x.m() is valid if the method set of (the type of) x
- // contains m and the argument list can be assigned to the parameter
- // list of m. If x is addressable and &x's method set contains m, x.m()
- // is shorthand for (&x).m()".
- if f, _ := obj.(*Func); f != nil {
- // determine if method has a pointer receiver
- if f.hasPtrRecv() && !indirect && !addressable {
- return nil, nil, true // pointer/addressable receiver required
- }
- }
- return
- }
-
- current = consolidateMultiples(next)
- }
-
- return nil, nil, false // not found
-}
-
-// embeddedType represents an embedded type
-type embeddedType struct {
- typ Type
- index []int // embedded field indices, starting with index at depth 0
- indirect bool // if set, there was a pointer indirection on the path to this field
- multiples bool // if set, typ appears multiple times at this depth
-}
-
-// consolidateMultiples collects multiple list entries with the same type
-// into a single entry marked as containing multiples. The result is the
-// consolidated list.
-func consolidateMultiples(list []embeddedType) []embeddedType {
- if len(list) <= 1 {
- return list // at most one entry - nothing to do
- }
-
- n := 0 // number of entries w/ unique type
- prev := make(map[Type]int) // index at which type was previously seen
- for _, e := range list {
- if i, found := lookupType(prev, e.typ); found {
- list[i].multiples = true
- // ignore this entry
- } else {
- prev[e.typ] = n
- list[n] = e
- n++
- }
- }
- return list[:n]
-}
-
-func lookupType(m map[Type]int, typ Type) (int, bool) {
- // fast path: maybe the types are equal
- if i, found := m[typ]; found {
- return i, true
- }
-
- for t, i := range m {
- if Identical(t, typ) {
- return i, true
- }
- }
-
- return 0, false
-}
-
-type instanceLookup struct {
- // buf is used to avoid allocating the map m in the common case of a small
- // number of instances.
- buf [3]*Named
- m map[*Named][]*Named
-}
-
-func (l *instanceLookup) lookup(inst *Named) *Named {
- for _, t := range l.buf {
- if t != nil && Identical(inst, t) {
- return t
- }
- }
- for _, t := range l.m[inst.Origin()] {
- if Identical(inst, t) {
- return t
- }
- }
- return nil
-}
-
-func (l *instanceLookup) add(inst *Named) {
- for i, t := range l.buf {
- if t == nil {
- l.buf[i] = inst
- return
- }
- }
- if l.m == nil {
- l.m = make(map[*Named][]*Named)
- }
- insts := l.m[inst.Origin()]
- l.m[inst.Origin()] = append(insts, inst)
-}
-
-// MissingMethod returns (nil, false) if V implements T, otherwise it
-// returns a missing method required by T and whether it is missing or
-// just has the wrong type.
-//
-// For non-interface types V, or if static is set, V implements T if all
-// methods of T are present in V. Otherwise (V is an interface and static
-// is not set), MissingMethod only checks that methods of T which are also
-// present in V have matching types (e.g., for a type assertion x.(T) where
-// x is of interface type V).
-func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) {
- m, alt := (*Checker)(nil).missingMethod(V, T, static)
- // Only report a wrong type if the alternative method has the same name as m.
- return m, alt != nil && alt.name == m.name // alt != nil implies m != nil
-}
-
-// missingMethod is like MissingMethod but accepts a *Checker as receiver.
-// The receiver may be nil if missingMethod is invoked through an exported
-// API call (such as MissingMethod), i.e., when all methods have been type-
-// checked.
-//
-// If a method is missing on T but is found on *T, or if a method is found
-// on T when looked up with case-folding, this alternative method is returned
-// as the second result.
-func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method, alt *Func) {
- if T.NumMethods() == 0 {
- return
- }
-
- // V is an interface
- if u, _ := under(V).(*Interface); u != nil {
- tset := u.typeSet()
- for _, m := range T.typeSet().methods {
- _, f := tset.LookupMethod(m.pkg, m.name, false)
-
- if f == nil {
- if !static {
- continue
- }
- return m, nil
- }
-
- if !Identical(f.typ, m.typ) {
- return m, f
- }
- }
-
- return
- }
-
- // V is not an interface
- for _, m := range T.typeSet().methods {
- // TODO(gri) should this be calling LookupFieldOrMethod instead (and why not)?
- obj, _, _ := lookupFieldOrMethod(V, false, m.pkg, m.name, false)
-
- // check if m is on *V, or on V with case-folding
- found := obj != nil
- if !found {
- // TODO(gri) Instead of NewPointer(V) below, can we just set the "addressable" argument?
- obj, _, _ = lookupFieldOrMethod(NewPointer(V), false, m.pkg, m.name, false)
- if obj == nil {
- obj, _, _ = lookupFieldOrMethod(V, false, m.pkg, m.name, true /* fold case */)
- }
- }
-
- // we must have a method (not a struct field)
- f, _ := obj.(*Func)
- if f == nil {
- return m, nil
- }
-
- // methods may not have a fully set up signature yet
- if check != nil {
- check.objDecl(f, nil)
- }
-
- if !found || !Identical(f.typ, m.typ) {
- return m, f
- }
- }
-
- return
-}
-
-// missingMethodCause returns a string giving the detailed cause for a missing method m,
-// where m is missing from V, but required by T. It puts the cause in parentheses,
-// and may include more have/want info after that. If non-nil, alt is a relevant
-// method that matches in some way. It may have the correct name, but wrong type, or
-// it may have a pointer receiver, or it may have the correct name except wrong case.
-// check may be nil.
-func (check *Checker) missingMethodCause(V, T Type, m, alt *Func) string {
- mname := "method " + m.Name()
-
- if alt != nil {
- if m.Name() != alt.Name() {
- return check.sprintf("(missing %s)\n\t\thave %s\n\t\twant %s",
- mname, check.funcString(alt, false), check.funcString(m, false))
- }
-
- if Identical(m.typ, alt.typ) {
- return check.sprintf("(%s has pointer receiver)", mname)
- }
-
- altS, mS := check.funcString(alt, false), check.funcString(m, false)
- if altS == mS {
- // Would tell the user that Foo isn't a Foo, add package information to disambiguate. See #54258.
- altS, mS = check.funcString(alt, true), check.funcString(m, true)
- }
-
- return check.sprintf("(wrong type for %s)\n\t\thave %s\n\t\twant %s",
- mname, altS, mS)
- }
-
- if isInterfacePtr(V) {
- return "(" + check.interfacePtrError(V) + ")"
- }
-
- if isInterfacePtr(T) {
- return "(" + check.interfacePtrError(T) + ")"
- }
-
- obj, _, _ := lookupFieldOrMethod(V, true /* auto-deref */, m.pkg, m.name, false)
- if fld, _ := obj.(*Var); fld != nil {
- return check.sprintf("(%s.%s is a field, not a method)", V, fld.Name())
- }
-
- return check.sprintf("(missing %s)", mname)
-}
-
-func isInterfacePtr(T Type) bool {
- p, _ := under(T).(*Pointer)
- return p != nil && IsInterface(p.base)
-}
-
-// check may be nil.
-func (check *Checker) interfacePtrError(T Type) string {
- assert(isInterfacePtr(T))
- if p, _ := under(T).(*Pointer); isTypeParam(p.base) {
- return check.sprintf("type %s is pointer to type parameter, not type parameter", T)
- }
- return check.sprintf("type %s is pointer to interface, not interface", T)
-}
-
-// funcString returns a string of the form name + signature for f.
-// check may be nil.
-func (check *Checker) funcString(f *Func, pkgInfo bool) string {
- buf := bytes.NewBufferString(f.name)
- var qf Qualifier
- if check != nil && !pkgInfo {
- qf = check.qualifier
- }
- w := newTypeWriter(buf, qf)
- w.pkgInfo = pkgInfo
- w.paramNames = false
- w.signature(f.typ.(*Signature))
- return buf.String()
-}
-
-// assertableTo reports whether a value of type V can be asserted to have type T.
-// It returns (nil, false) as affirmative answer. Otherwise it returns a missing
-// method required by V and whether it is missing or just has the wrong type.
-// The receiver may be nil if assertableTo is invoked through an exported API call
-// (such as AssertableTo), i.e., when all methods have been type-checked.
-// TODO(gri) replace calls to this function with calls to newAssertableTo.
-func (check *Checker) assertableTo(V *Interface, T Type) (method, wrongType *Func) {
- // no static check is required if T is an interface
- // spec: "If T is an interface type, x.(T) asserts that the
- // dynamic type of x implements the interface T."
- if IsInterface(T) {
- return
- }
- // TODO(gri) fix this for generalized interfaces
- return check.missingMethod(T, V, false)
-}
-
-// newAssertableTo reports whether a value of type V can be asserted to have type T.
-// It also implements behavior for interfaces that currently are only permitted
-// in constraint position (we have not yet defined that behavior in the spec).
-func (check *Checker) newAssertableTo(V *Interface, T Type) bool {
- // no static check is required if T is an interface
- // spec: "If T is an interface type, x.(T) asserts that the
- // dynamic type of x implements the interface T."
- if IsInterface(T) {
- return true
- }
- return check.implements(T, V, false, nil)
-}
-
-// deref dereferences typ if it is a *Pointer and returns its base and true.
-// Otherwise it returns (typ, false).
-func deref(typ Type) (Type, bool) {
- if p, _ := typ.(*Pointer); p != nil {
- // p.base should never be nil, but be conservative
- if p.base == nil {
- if debug {
- panic("pointer with nil base type (possibly due to an invalid cyclic declaration)")
- }
- return Typ[Invalid], true
- }
- return p.base, true
- }
- return typ, false
-}
-
-// derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a
-// (named or unnamed) struct and returns its base. Otherwise it returns typ.
-func derefStructPtr(typ Type) Type {
- if p, _ := under(typ).(*Pointer); p != nil {
- if _, ok := under(p.base).(*Struct); ok {
- return p.base
- }
- }
- return typ
-}
-
-// concat returns the result of concatenating list and i.
-// The result does not share its underlying array with list.
-func concat(list []int, i int) []int {
- var t []int
- t = append(t, list...)
- return append(t, i)
-}
-
-// fieldIndex returns the index for the field with matching package and name, or a value < 0.
-func fieldIndex(fields []*Var, pkg *Package, name string) int {
- if name != "_" {
- for i, f := range fields {
- if f.sameId(pkg, name) {
- return i
- }
- }
- }
- return -1
-}
-
-// lookupMethod returns the index of and method with matching package and name, or (-1, nil).
-// If foldCase is true, method names are considered equal if they are equal with case folding.
-func lookupMethod(methods []*Func, pkg *Package, name string, foldCase bool) (int, *Func) {
- if name != "_" {
- for i, m := range methods {
- if (m.name == name || foldCase && strings.EqualFold(m.name, name)) && m.sameId(pkg, m.name) {
- return i, m
- }
- }
- }
- return -1, nil
-}
diff --git a/contrib/go/_std_1.20/src/go/types/map.go b/contrib/go/_std_1.20/src/go/types/map.go
deleted file mode 100644
index 01e13b214e..0000000000
--- a/contrib/go/_std_1.20/src/go/types/map.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2011 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 types
-
-// A Map represents a map type.
-type Map struct {
- key, elem Type
-}
-
-// NewMap returns a new map for the given key and element types.
-func NewMap(key, elem Type) *Map {
- return &Map{key: key, elem: elem}
-}
-
-// Key returns the key type of map m.
-func (m *Map) Key() Type { return m.key }
-
-// Elem returns the element type of map m.
-func (m *Map) Elem() Type { return m.elem }
-
-func (t *Map) Underlying() Type { return t }
-func (t *Map) String() string { return TypeString(t, nil) }
diff --git a/contrib/go/_std_1.20/src/go/types/methodset.go b/contrib/go/_std_1.20/src/go/types/methodset.go
deleted file mode 100644
index 2bf3028615..0000000000
--- a/contrib/go/_std_1.20/src/go/types/methodset.go
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements method sets.
-
-package types
-
-import (
- "fmt"
- "sort"
- "strings"
-)
-
-// A MethodSet is an ordered set of concrete or abstract (interface) methods;
-// a method is a MethodVal selection, and they are ordered by ascending m.Obj().Id().
-// The zero value for a MethodSet is a ready-to-use empty method set.
-type MethodSet struct {
- list []*Selection
-}
-
-func (s *MethodSet) String() string {
- if s.Len() == 0 {
- return "MethodSet {}"
- }
-
- var buf strings.Builder
- fmt.Fprintln(&buf, "MethodSet {")
- for _, f := range s.list {
- fmt.Fprintf(&buf, "\t%s\n", f)
- }
- fmt.Fprintln(&buf, "}")
- return buf.String()
-}
-
-// Len returns the number of methods in s.
-func (s *MethodSet) Len() int { return len(s.list) }
-
-// At returns the i'th method in s for 0 <= i < s.Len().
-func (s *MethodSet) At(i int) *Selection { return s.list[i] }
-
-// Lookup returns the method with matching package and name, or nil if not found.
-func (s *MethodSet) Lookup(pkg *Package, name string) *Selection {
- if s.Len() == 0 {
- return nil
- }
-
- key := Id(pkg, name)
- i := sort.Search(len(s.list), func(i int) bool {
- m := s.list[i]
- return m.obj.Id() >= key
- })
- if i < len(s.list) {
- m := s.list[i]
- if m.obj.Id() == key {
- return m
- }
- }
- return nil
-}
-
-// Shared empty method set.
-var emptyMethodSet MethodSet
-
-// Note: NewMethodSet is intended for external use only as it
-// requires interfaces to be complete. It may be used
-// internally if LookupFieldOrMethod completed the same
-// interfaces beforehand.
-
-// NewMethodSet returns the method set for the given type T.
-// It always returns a non-nil method set, even if it is empty.
-func NewMethodSet(T Type) *MethodSet {
- // WARNING: The code in this function is extremely subtle - do not modify casually!
- // This function and lookupFieldOrMethod should be kept in sync.
-
- // TODO(rfindley) confirm that this code is in sync with lookupFieldOrMethod
- // with respect to type params.
-
- // method set up to the current depth, allocated lazily
- var base methodSet
-
- typ, isPtr := deref(T)
-
- // *typ where typ is an interface has no methods.
- if isPtr && IsInterface(typ) {
- return &emptyMethodSet
- }
-
- // Start with typ as single entry at shallowest depth.
- current := []embeddedType{{typ, nil, isPtr, false}}
-
- // seen tracks named types that we have seen already, allocated lazily.
- // Used to avoid endless searches in case of recursive types.
- //
- // We must use a lookup on identity rather than a simple map[*Named]bool as
- // instantiated types may be identical but not equal.
- var seen instanceLookup
-
- // collect methods at current depth
- for len(current) > 0 {
- var next []embeddedType // embedded types found at current depth
-
- // field and method sets at current depth, indexed by names (Id's), and allocated lazily
- var fset map[string]bool // we only care about the field names
- var mset methodSet
-
- for _, e := range current {
- typ := e.typ
-
- // If we have a named type, we may have associated methods.
- // Look for those first.
- if named, _ := typ.(*Named); named != nil {
- if alt := seen.lookup(named); alt != nil {
- // We have seen this type before, at a more shallow depth
- // (note that multiples of this type at the current depth
- // were consolidated before). The type at that depth shadows
- // this same type at the current depth, so we can ignore
- // this one.
- continue
- }
- seen.add(named)
-
- for i := 0; i < named.NumMethods(); i++ {
- mset = mset.addOne(named.Method(i), concat(e.index, i), e.indirect, e.multiples)
- }
- }
-
- switch t := under(typ).(type) {
- case *Struct:
- for i, f := range t.fields {
- if fset == nil {
- fset = make(map[string]bool)
- }
- fset[f.Id()] = true
-
- // Embedded fields are always of the form T or *T where
- // T is a type name. If typ appeared multiple times at
- // this depth, f.Type appears multiple times at the next
- // depth.
- if f.embedded {
- typ, isPtr := deref(f.typ)
- // TODO(gri) optimization: ignore types that can't
- // have fields or methods (only Named, Struct, and
- // Interface types need to be considered).
- next = append(next, embeddedType{typ, concat(e.index, i), e.indirect || isPtr, e.multiples})
- }
- }
-
- case *Interface:
- mset = mset.add(t.typeSet().methods, e.index, true, e.multiples)
- }
- }
-
- // Add methods and collisions at this depth to base if no entries with matching
- // names exist already.
- for k, m := range mset {
- if _, found := base[k]; !found {
- // Fields collide with methods of the same name at this depth.
- if fset[k] {
- m = nil // collision
- }
- if base == nil {
- base = make(methodSet)
- }
- base[k] = m
- }
- }
-
- // Add all (remaining) fields at this depth as collisions (since they will
- // hide any method further down) if no entries with matching names exist already.
- for k := range fset {
- if _, found := base[k]; !found {
- if base == nil {
- base = make(methodSet)
- }
- base[k] = nil // collision
- }
- }
-
- current = consolidateMultiples(next)
- }
-
- if len(base) == 0 {
- return &emptyMethodSet
- }
-
- // collect methods
- var list []*Selection
- for _, m := range base {
- if m != nil {
- m.recv = T
- list = append(list, m)
- }
- }
- // sort by unique name
- sort.Slice(list, func(i, j int) bool {
- return list[i].obj.Id() < list[j].obj.Id()
- })
- return &MethodSet{list}
-}
-
-// A methodSet is a set of methods and name collisions.
-// A collision indicates that multiple methods with the
-// same unique id, or a field with that id appeared.
-type methodSet map[string]*Selection // a nil entry indicates a name collision
-
-// Add adds all functions in list to the method set s.
-// If multiples is set, every function in list appears multiple times
-// and is treated as a collision.
-func (s methodSet) add(list []*Func, index []int, indirect bool, multiples bool) methodSet {
- if len(list) == 0 {
- return s
- }
- for i, f := range list {
- s = s.addOne(f, concat(index, i), indirect, multiples)
- }
- return s
-}
-
-func (s methodSet) addOne(f *Func, index []int, indirect bool, multiples bool) methodSet {
- if s == nil {
- s = make(methodSet)
- }
- key := f.Id()
- // if f is not in the set, add it
- if !multiples {
- // TODO(gri) A found method may not be added because it's not in the method set
- // (!indirect && f.hasPtrRecv()). A 2nd method on the same level may be in the method
- // set and may not collide with the first one, thus leading to a false positive.
- // Is that possible? Investigate.
- if _, found := s[key]; !found && (indirect || !f.hasPtrRecv()) {
- s[key] = &Selection{MethodVal, nil, f, index, indirect}
- return s
- }
- }
- s[key] = nil // collision
- return s
-}
diff --git a/contrib/go/_std_1.20/src/go/types/mono.go b/contrib/go/_std_1.20/src/go/types/mono.go
deleted file mode 100644
index cf3f5a8bdc..0000000000
--- a/contrib/go/_std_1.20/src/go/types/mono.go
+++ /dev/null
@@ -1,337 +0,0 @@
-// 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 types
-
-import (
- "go/ast"
- "go/token"
- . "internal/types/errors"
-)
-
-// This file implements a check to validate that a Go package doesn't
-// have unbounded recursive instantiation, which is not compatible
-// with compilers using static instantiation (such as
-// monomorphization).
-//
-// It implements a sort of "type flow" analysis by detecting which
-// type parameters are instantiated with other type parameters (or
-// types derived thereof). A package cannot be statically instantiated
-// if the graph has any cycles involving at least one derived type.
-//
-// Concretely, we construct a directed, weighted graph. Vertices are
-// used to represent type parameters as well as some defined
-// types. Edges are used to represent how types depend on each other:
-//
-// * Everywhere a type-parameterized function or type is instantiated,
-// we add edges to each type parameter from the vertices (if any)
-// representing each type parameter or defined type referenced by
-// the type argument. If the type argument is just the referenced
-// type itself, then the edge has weight 0, otherwise 1.
-//
-// * For every defined type declared within a type-parameterized
-// function or method, we add an edge of weight 1 to the defined
-// type from each ambient type parameter.
-//
-// For example, given:
-//
-// func f[A, B any]() {
-// type T int
-// f[T, map[A]B]()
-// }
-//
-// we construct vertices representing types A, B, and T. Because of
-// declaration "type T int", we construct edges T<-A and T<-B with
-// weight 1; and because of instantiation "f[T, map[A]B]" we construct
-// edges A<-T with weight 0, and B<-A and B<-B with weight 1.
-//
-// Finally, we look for any positive-weight cycles. Zero-weight cycles
-// are allowed because static instantiation will reach a fixed point.
-
-type monoGraph struct {
- vertices []monoVertex
- edges []monoEdge
-
- // canon maps method receiver type parameters to their respective
- // receiver type's type parameters.
- canon map[*TypeParam]*TypeParam
-
- // nameIdx maps a defined type or (canonical) type parameter to its
- // vertex index.
- nameIdx map[*TypeName]int
-}
-
-type monoVertex struct {
- weight int // weight of heaviest known path to this vertex
- pre int // previous edge (if any) in the above path
- len int // length of the above path
-
- // obj is the defined type or type parameter represented by this
- // vertex.
- obj *TypeName
-}
-
-type monoEdge struct {
- dst, src int
- weight int
-
- pos token.Pos
- typ Type
-}
-
-func (check *Checker) monomorph() {
- // We detect unbounded instantiation cycles using a variant of
- // Bellman-Ford's algorithm. Namely, instead of always running |V|
- // iterations, we run until we either reach a fixed point or we've
- // found a path of length |V|. This allows us to terminate earlier
- // when there are no cycles, which should be the common case.
-
- again := true
- for again {
- again = false
-
- for i, edge := range check.mono.edges {
- src := &check.mono.vertices[edge.src]
- dst := &check.mono.vertices[edge.dst]
-
- // N.B., we're looking for the greatest weight paths, unlike
- // typical Bellman-Ford.
- w := src.weight + edge.weight
- if w <= dst.weight {
- continue
- }
-
- dst.pre = i
- dst.len = src.len + 1
- if dst.len == len(check.mono.vertices) {
- check.reportInstanceLoop(edge.dst)
- return
- }
-
- dst.weight = w
- again = true
- }
- }
-}
-
-func (check *Checker) reportInstanceLoop(v int) {
- var stack []int
- seen := make([]bool, len(check.mono.vertices))
-
- // We have a path that contains a cycle and ends at v, but v may
- // only be reachable from the cycle, not on the cycle itself. We
- // start by walking backwards along the path until we find a vertex
- // that appears twice.
- for !seen[v] {
- stack = append(stack, v)
- seen[v] = true
- v = check.mono.edges[check.mono.vertices[v].pre].src
- }
-
- // Trim any vertices we visited before visiting v the first
- // time. Since v is the first vertex we found within the cycle, any
- // vertices we visited earlier cannot be part of the cycle.
- for stack[0] != v {
- stack = stack[1:]
- }
-
- // TODO(mdempsky): Pivot stack so we report the cycle from the top?
-
- obj0 := check.mono.vertices[v].obj
- check.error(obj0, InvalidInstanceCycle, "instantiation cycle:")
-
- qf := RelativeTo(check.pkg)
- for _, v := range stack {
- edge := check.mono.edges[check.mono.vertices[v].pre]
- obj := check.mono.vertices[edge.dst].obj
-
- switch obj.Type().(type) {
- default:
- panic("unexpected type")
- case *Named:
- check.errorf(atPos(edge.pos), InvalidInstanceCycle, "\t%s implicitly parameterized by %s", obj.Name(), TypeString(edge.typ, qf)) // secondary error, \t indented
- case *TypeParam:
- check.errorf(atPos(edge.pos), InvalidInstanceCycle, "\t%s instantiated as %s", obj.Name(), TypeString(edge.typ, qf)) // secondary error, \t indented
- }
- }
-}
-
-// recordCanon records that tpar is the canonical type parameter
-// corresponding to method type parameter mpar.
-func (w *monoGraph) recordCanon(mpar, tpar *TypeParam) {
- if w.canon == nil {
- w.canon = make(map[*TypeParam]*TypeParam)
- }
- w.canon[mpar] = tpar
-}
-
-// recordInstance records that the given type parameters were
-// instantiated with the corresponding type arguments.
-func (w *monoGraph) recordInstance(pkg *Package, pos token.Pos, tparams []*TypeParam, targs []Type, xlist []ast.Expr) {
- for i, tpar := range tparams {
- pos := pos
- if i < len(xlist) {
- pos = xlist[i].Pos()
- }
- w.assign(pkg, pos, tpar, targs[i])
- }
-}
-
-// assign records that tpar was instantiated as targ at pos.
-func (w *monoGraph) assign(pkg *Package, pos token.Pos, tpar *TypeParam, targ Type) {
- // Go generics do not have an analog to C++`s template-templates,
- // where a template parameter can itself be an instantiable
- // template. So any instantiation cycles must occur within a single
- // package. Accordingly, we can ignore instantiations of imported
- // type parameters.
- //
- // TODO(mdempsky): Push this check up into recordInstance? All type
- // parameters in a list will appear in the same package.
- if tpar.Obj().Pkg() != pkg {
- return
- }
-
- // flow adds an edge from vertex src representing that typ flows to tpar.
- flow := func(src int, typ Type) {
- weight := 1
- if typ == targ {
- weight = 0
- }
-
- w.addEdge(w.typeParamVertex(tpar), src, weight, pos, targ)
- }
-
- // Recursively walk the type argument to find any defined types or
- // type parameters.
- var do func(typ Type)
- do = func(typ Type) {
- switch typ := typ.(type) {
- default:
- panic("unexpected type")
-
- case *TypeParam:
- assert(typ.Obj().Pkg() == pkg)
- flow(w.typeParamVertex(typ), typ)
-
- case *Named:
- if src := w.localNamedVertex(pkg, typ.Origin()); src >= 0 {
- flow(src, typ)
- }
-
- targs := typ.TypeArgs()
- for i := 0; i < targs.Len(); i++ {
- do(targs.At(i))
- }
-
- case *Array:
- do(typ.Elem())
- case *Basic:
- // ok
- case *Chan:
- do(typ.Elem())
- case *Map:
- do(typ.Key())
- do(typ.Elem())
- case *Pointer:
- do(typ.Elem())
- case *Slice:
- do(typ.Elem())
-
- case *Interface:
- for i := 0; i < typ.NumMethods(); i++ {
- do(typ.Method(i).Type())
- }
- case *Signature:
- tuple := func(tup *Tuple) {
- for i := 0; i < tup.Len(); i++ {
- do(tup.At(i).Type())
- }
- }
- tuple(typ.Params())
- tuple(typ.Results())
- case *Struct:
- for i := 0; i < typ.NumFields(); i++ {
- do(typ.Field(i).Type())
- }
- }
- }
- do(targ)
-}
-
-// localNamedVertex returns the index of the vertex representing
-// named, or -1 if named doesn't need representation.
-func (w *monoGraph) localNamedVertex(pkg *Package, named *Named) int {
- obj := named.Obj()
- if obj.Pkg() != pkg {
- return -1 // imported type
- }
-
- root := pkg.Scope()
- if obj.Parent() == root {
- return -1 // package scope, no ambient type parameters
- }
-
- if idx, ok := w.nameIdx[obj]; ok {
- return idx
- }
-
- idx := -1
-
- // Walk the type definition's scope to find any ambient type
- // parameters that it's implicitly parameterized by.
- for scope := obj.Parent(); scope != root; scope = scope.Parent() {
- for _, elem := range scope.elems {
- if elem, ok := elem.(*TypeName); ok && !elem.IsAlias() && elem.Pos() < obj.Pos() {
- if tpar, ok := elem.Type().(*TypeParam); ok {
- if idx < 0 {
- idx = len(w.vertices)
- w.vertices = append(w.vertices, monoVertex{obj: obj})
- }
-
- w.addEdge(idx, w.typeParamVertex(tpar), 1, obj.Pos(), tpar)
- }
- }
- }
- }
-
- if w.nameIdx == nil {
- w.nameIdx = make(map[*TypeName]int)
- }
- w.nameIdx[obj] = idx
- return idx
-}
-
-// typeParamVertex returns the index of the vertex representing tpar.
-func (w *monoGraph) typeParamVertex(tpar *TypeParam) int {
- if x, ok := w.canon[tpar]; ok {
- tpar = x
- }
-
- obj := tpar.Obj()
-
- if idx, ok := w.nameIdx[obj]; ok {
- return idx
- }
-
- if w.nameIdx == nil {
- w.nameIdx = make(map[*TypeName]int)
- }
-
- idx := len(w.vertices)
- w.vertices = append(w.vertices, monoVertex{obj: obj})
- w.nameIdx[obj] = idx
- return idx
-}
-
-func (w *monoGraph) addEdge(dst, src, weight int, pos token.Pos, typ Type) {
- // TODO(mdempsky): Deduplicate redundant edges?
- w.edges = append(w.edges, monoEdge{
- dst: dst,
- src: src,
- weight: weight,
-
- pos: pos,
- typ: typ,
- })
-}
diff --git a/contrib/go/_std_1.20/src/go/types/named.go b/contrib/go/_std_1.20/src/go/types/named.go
deleted file mode 100644
index c08997aa77..0000000000
--- a/contrib/go/_std_1.20/src/go/types/named.go
+++ /dev/null
@@ -1,656 +0,0 @@
-// Copyright 2011 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 types
-
-import (
- "go/token"
- "sync"
- "sync/atomic"
-)
-
-// Type-checking Named types is subtle, because they may be recursively
-// defined, and because their full details may be spread across multiple
-// declarations (via methods). For this reason they are type-checked lazily,
-// to avoid information being accessed before it is complete.
-//
-// Conceptually, it is helpful to think of named types as having two distinct
-// sets of information:
-// - "LHS" information, defining their identity: Obj() and TypeArgs()
-// - "RHS" information, defining their details: TypeParams(), Underlying(),
-// and methods.
-//
-// In this taxonomy, LHS information is available immediately, but RHS
-// information is lazy. Specifically, a named type N may be constructed in any
-// of the following ways:
-// 1. type-checked from the source
-// 2. loaded eagerly from export data
-// 3. loaded lazily from export data (when using unified IR)
-// 4. instantiated from a generic type
-//
-// In cases 1, 3, and 4, it is possible that the underlying type or methods of
-// N may not be immediately available.
-// - During type-checking, we allocate N before type-checking its underlying
-// type or methods, so that we may resolve recursive references.
-// - When loading from export data, we may load its methods and underlying
-// type lazily using a provided load function.
-// - After instantiating, we lazily expand the underlying type and methods
-// (note that instances may be created while still in the process of
-// type-checking the original type declaration).
-//
-// In cases 3 and 4 this lazy construction may also occur concurrently, due to
-// concurrent use of the type checker API (after type checking or importing has
-// finished). It is critical that we keep track of state, so that Named types
-// are constructed exactly once and so that we do not access their details too
-// soon.
-//
-// We achieve this by tracking state with an atomic state variable, and
-// guarding potentially concurrent calculations with a mutex. At any point in
-// time this state variable determines which data on N may be accessed. As
-// state monotonically progresses, any data available at state M may be
-// accessed without acquiring the mutex at state N, provided N >= M.
-//
-// GLOSSARY: Here are a few terms used in this file to describe Named types:
-// - We say that a Named type is "instantiated" if it has been constructed by
-// instantiating a generic named type with type arguments.
-// - We say that a Named type is "declared" if it corresponds to a type
-// declaration in the source. Instantiated named types correspond to a type
-// instantiation in the source, not a declaration. But their Origin type is
-// a declared type.
-// - We say that a Named type is "resolved" if its RHS information has been
-// loaded or fully type-checked. For Named types constructed from export
-// data, this may involve invoking a loader function to extract information
-// from export data. For instantiated named types this involves reading
-// information from their origin.
-// - We say that a Named type is "expanded" if it is an instantiated type and
-// type parameters in its underlying type and methods have been substituted
-// with the type arguments from the instantiation. A type may be partially
-// expanded if some but not all of these details have been substituted.
-// Similarly, we refer to these individual details (underlying type or
-// method) as being "expanded".
-// - When all information is known for a named type, we say it is "complete".
-//
-// Some invariants to keep in mind: each declared Named type has a single
-// corresponding object, and that object's type is the (possibly generic) Named
-// type. Declared Named types are identical if and only if their pointers are
-// identical. On the other hand, multiple instantiated Named types may be
-// identical even though their pointers are not identical. One has to use
-// Identical to compare them. For instantiated named types, their obj is a
-// synthetic placeholder that records their position of the corresponding
-// instantiation in the source (if they were constructed during type checking).
-//
-// To prevent infinite expansion of named instances that are created outside of
-// type-checking, instances share a Context with other instances created during
-// their expansion. Via the pidgeonhole principle, this guarantees that in the
-// presence of a cycle of named types, expansion will eventually find an
-// existing instance in the Context and short-circuit the expansion.
-//
-// Once an instance is complete, we can nil out this shared Context to unpin
-// memory, though this Context may still be held by other incomplete instances
-// in its "lineage".
-
-// A Named represents a named (defined) type.
-type Named struct {
- check *Checker // non-nil during type-checking; nil otherwise
- obj *TypeName // corresponding declared object for declared types; see above for instantiated types
-
- // fromRHS holds the type (on RHS of declaration) this *Named type is derived
- // from (for cycle reporting). Only used by validType, and therefore does not
- // require synchronization.
- fromRHS Type
-
- // information for instantiated types; nil otherwise
- inst *instance
-
- mu sync.Mutex // guards all fields below
- state_ uint32 // the current state of this type; must only be accessed atomically
- underlying Type // possibly a *Named during setup; never a *Named once set up completely
- tparams *TypeParamList // type parameters, or nil
-
- // methods declared for this type (not the method set of this type)
- // Signatures are type-checked lazily.
- // For non-instantiated types, this is a fully populated list of methods. For
- // instantiated types, methods are individually expanded when they are first
- // accessed.
- methods []*Func
-
- // loader may be provided to lazily load type parameters, underlying type, and methods.
- loader func(*Named) (tparams []*TypeParam, underlying Type, methods []*Func)
-}
-
-// instance holds information that is only necessary for instantiated named
-// types.
-type instance struct {
- orig *Named // original, uninstantiated type
- targs *TypeList // type arguments
- expandedMethods int // number of expanded methods; expandedMethods <= len(orig.methods)
- ctxt *Context // local Context; set to nil after full expansion
-}
-
-// namedState represents the possible states that a named type may assume.
-type namedState uint32
-
-const (
- unresolved namedState = iota // tparams, underlying type and methods might be unavailable
- resolved // resolve has run; methods might be incomplete (for instances)
- complete // all data is known
-)
-
-// NewNamed returns a new named type for the given type name, underlying type, and associated methods.
-// If the given type name obj doesn't have a type yet, its type is set to the returned named type.
-// The underlying type must not be a *Named.
-func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
- if _, ok := underlying.(*Named); ok {
- panic("underlying type must not be *Named")
- }
- return (*Checker)(nil).newNamed(obj, underlying, methods)
-}
-
-// resolve resolves the type parameters, methods, and underlying type of n.
-// This information may be loaded from a provided loader function, or computed
-// from an origin type (in the case of instances).
-//
-// After resolution, the type parameters, methods, and underlying type of n are
-// accessible; but if n is an instantiated type, its methods may still be
-// unexpanded.
-func (n *Named) resolve() *Named {
- if n.state() >= resolved { // avoid locking below
- return n
- }
-
- // TODO(rfindley): if n.check is non-nil we can avoid locking here, since
- // type-checking is not concurrent. Evaluate if this is worth doing.
- n.mu.Lock()
- defer n.mu.Unlock()
-
- if n.state() >= resolved {
- return n
- }
-
- if n.inst != nil {
- assert(n.underlying == nil) // n is an unresolved instance
- assert(n.loader == nil) // instances are created by instantiation, in which case n.loader is nil
-
- orig := n.inst.orig
- orig.resolve()
- underlying := n.expandUnderlying()
-
- n.tparams = orig.tparams
- n.underlying = underlying
- n.fromRHS = orig.fromRHS // for cycle detection
-
- if len(orig.methods) == 0 {
- n.setState(complete) // nothing further to do
- n.inst.ctxt = nil
- } else {
- n.setState(resolved)
- }
- return n
- }
-
- // TODO(mdempsky): Since we're passing n to the loader anyway
- // (necessary because types2 expects the receiver type for methods
- // on defined interface types to be the Named rather than the
- // underlying Interface), maybe it should just handle calling
- // SetTypeParams, SetUnderlying, and AddMethod instead? Those
- // methods would need to support reentrant calls though. It would
- // also make the API more future-proof towards further extensions.
- if n.loader != nil {
- assert(n.underlying == nil)
- assert(n.TypeArgs().Len() == 0) // instances are created by instantiation, in which case n.loader is nil
-
- tparams, underlying, methods := n.loader(n)
-
- n.tparams = bindTParams(tparams)
- n.underlying = underlying
- n.fromRHS = underlying // for cycle detection
- n.methods = methods
- n.loader = nil
- }
-
- n.setState(complete)
- return n
-}
-
-// state atomically accesses the current state of the receiver.
-func (n *Named) state() namedState {
- return namedState(atomic.LoadUint32(&n.state_))
-}
-
-// setState atomically stores the given state for n.
-// Must only be called while holding n.mu.
-func (n *Named) setState(state namedState) {
- atomic.StoreUint32(&n.state_, uint32(state))
-}
-
-// newNamed is like NewNamed but with a *Checker receiver and additional orig argument.
-func (check *Checker) newNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
- typ := &Named{check: check, obj: obj, fromRHS: underlying, underlying: underlying, methods: methods}
- if obj.typ == nil {
- obj.typ = typ
- }
- // Ensure that typ is always sanity-checked.
- if check != nil {
- check.needsCleanup(typ)
- }
- return typ
-}
-
-// newNamedInstance creates a new named instance for the given origin and type
-// arguments, recording pos as the position of its synthetic object (for error
-// reporting).
-//
-// If set, expanding is the named type instance currently being expanded, that
-// led to the creation of this instance.
-func (check *Checker) newNamedInstance(pos token.Pos, orig *Named, targs []Type, expanding *Named) *Named {
- assert(len(targs) > 0)
-
- obj := NewTypeName(pos, orig.obj.pkg, orig.obj.name, nil)
- inst := &instance{orig: orig, targs: newTypeList(targs)}
-
- // Only pass the expanding context to the new instance if their packages
- // match. Since type reference cycles are only possible within a single
- // package, this is sufficient for the purposes of short-circuiting cycles.
- // Avoiding passing the context in other cases prevents unnecessary coupling
- // of types across packages.
- if expanding != nil && expanding.Obj().pkg == obj.pkg {
- inst.ctxt = expanding.inst.ctxt
- }
- typ := &Named{check: check, obj: obj, inst: inst}
- obj.typ = typ
- // Ensure that typ is always sanity-checked.
- if check != nil {
- check.needsCleanup(typ)
- }
- return typ
-}
-
-func (t *Named) cleanup() {
- assert(t.inst == nil || t.inst.orig.inst == nil)
- // Ensure that every defined type created in the course of type-checking has
- // either non-*Named underlying type, or is unexpanded.
- //
- // This guarantees that we don't leak any types whose underlying type is
- // *Named, because any unexpanded instances will lazily compute their
- // underlying type by substituting in the underlying type of their origin.
- // The origin must have either been imported or type-checked and expanded
- // here, and in either case its underlying type will be fully expanded.
- switch t.underlying.(type) {
- case nil:
- if t.TypeArgs().Len() == 0 {
- panic("nil underlying")
- }
- case *Named:
- t.under() // t.under may add entries to check.cleaners
- }
- t.check = nil
-}
-
-// Obj returns the type name for the declaration defining the named type t. For
-// instantiated types, this is same as the type name of the origin type.
-func (t *Named) Obj() *TypeName {
- if t.inst == nil {
- return t.obj
- }
- return t.inst.orig.obj
-}
-
-// Origin returns the generic type from which the named type t is
-// instantiated. If t is not an instantiated type, the result is t.
-func (t *Named) Origin() *Named {
- if t.inst == nil {
- return t
- }
- return t.inst.orig
-}
-
-// TypeParams returns the type parameters of the named type t, or nil.
-// The result is non-nil for an (originally) generic type even if it is instantiated.
-func (t *Named) TypeParams() *TypeParamList { return t.resolve().tparams }
-
-// SetTypeParams sets the type parameters of the named type t.
-// t must not have type arguments.
-func (t *Named) SetTypeParams(tparams []*TypeParam) {
- assert(t.inst == nil)
- t.resolve().tparams = bindTParams(tparams)
-}
-
-// TypeArgs returns the type arguments used to instantiate the named type t.
-func (t *Named) TypeArgs() *TypeList {
- if t.inst == nil {
- return nil
- }
- return t.inst.targs
-}
-
-// NumMethods returns the number of explicit methods defined for t.
-func (t *Named) NumMethods() int {
- return len(t.Origin().resolve().methods)
-}
-
-// Method returns the i'th method of named type t for 0 <= i < t.NumMethods().
-//
-// For an ordinary or instantiated type t, the receiver base type of this
-// method is the named type t. For an uninstantiated generic type t, each
-// method receiver is instantiated with its receiver type parameters.
-func (t *Named) Method(i int) *Func {
- t.resolve()
-
- if t.state() >= complete {
- return t.methods[i]
- }
-
- assert(t.inst != nil) // only instances should have incomplete methods
- orig := t.inst.orig
-
- t.mu.Lock()
- defer t.mu.Unlock()
-
- if len(t.methods) != len(orig.methods) {
- assert(len(t.methods) == 0)
- t.methods = make([]*Func, len(orig.methods))
- }
-
- if t.methods[i] == nil {
- assert(t.inst.ctxt != nil) // we should still have a context remaining from the resolution phase
- t.methods[i] = t.expandMethod(i)
- t.inst.expandedMethods++
-
- // Check if we've created all methods at this point. If we have, mark the
- // type as fully expanded.
- if t.inst.expandedMethods == len(orig.methods) {
- t.setState(complete)
- t.inst.ctxt = nil // no need for a context anymore
- }
- }
-
- return t.methods[i]
-}
-
-// expandMethod substitutes type arguments in the i'th method for an
-// instantiated receiver.
-func (t *Named) expandMethod(i int) *Func {
- // t.orig.methods is not lazy. origm is the method instantiated with its
- // receiver type parameters (the "origin" method).
- origm := t.inst.orig.Method(i)
- assert(origm != nil)
-
- check := t.check
- // Ensure that the original method is type-checked.
- if check != nil {
- check.objDecl(origm, nil)
- }
-
- origSig := origm.typ.(*Signature)
- rbase, _ := deref(origSig.Recv().Type())
-
- // If rbase is t, then origm is already the instantiated method we're looking
- // for. In this case, we return origm to preserve the invariant that
- // traversing Method->Receiver Type->Method should get back to the same
- // method.
- //
- // This occurs if t is instantiated with the receiver type parameters, as in
- // the use of m in func (r T[_]) m() { r.m() }.
- if rbase == t {
- return origm
- }
-
- sig := origSig
- // We can only substitute if we have a correspondence between type arguments
- // and type parameters. This check is necessary in the presence of invalid
- // code.
- if origSig.RecvTypeParams().Len() == t.inst.targs.Len() {
- smap := makeSubstMap(origSig.RecvTypeParams().list(), t.inst.targs.list())
- var ctxt *Context
- if check != nil {
- ctxt = check.context()
- }
- sig = check.subst(origm.pos, origSig, smap, t, ctxt).(*Signature)
- }
-
- if sig == origSig {
- // No substitution occurred, but we still need to create a new signature to
- // hold the instantiated receiver.
- copy := *origSig
- sig = &copy
- }
-
- var rtyp Type
- if origm.hasPtrRecv() {
- rtyp = NewPointer(t)
- } else {
- rtyp = t
- }
-
- sig.recv = substVar(origSig.recv, rtyp)
- return substFunc(origm, sig)
-}
-
-// SetUnderlying sets the underlying type and marks t as complete.
-// t must not have type arguments.
-func (t *Named) SetUnderlying(underlying Type) {
- assert(t.inst == nil)
- if underlying == nil {
- panic("underlying type must not be nil")
- }
- if _, ok := underlying.(*Named); ok {
- panic("underlying type must not be *Named")
- }
- t.resolve().underlying = underlying
- if t.fromRHS == nil {
- t.fromRHS = underlying // for cycle detection
- }
-}
-
-// AddMethod adds method m unless it is already in the method list.
-// t must not have type arguments.
-func (t *Named) AddMethod(m *Func) {
- assert(t.inst == nil)
- t.resolve()
- if i, _ := lookupMethod(t.methods, m.pkg, m.name, false); i < 0 {
- t.methods = append(t.methods, m)
- }
-}
-
-func (t *Named) Underlying() Type { return t.resolve().underlying }
-func (t *Named) String() string { return TypeString(t, nil) }
-
-// ----------------------------------------------------------------------------
-// Implementation
-//
-// TODO(rfindley): reorganize the loading and expansion methods under this
-// heading.
-
-// under returns the expanded underlying type of n0; possibly by following
-// forward chains of named types. If an underlying type is found, resolve
-// the chain by setting the underlying type for each defined type in the
-// chain before returning it. If no underlying type is found or a cycle
-// is detected, the result is Typ[Invalid]. If a cycle is detected and
-// n0.check != nil, the cycle is reported.
-//
-// This is necessary because the underlying type of named may be itself a
-// named type that is incomplete:
-//
-// type (
-// A B
-// B *C
-// C A
-// )
-//
-// The type of C is the (named) type of A which is incomplete,
-// and which has as its underlying type the named type B.
-func (n0 *Named) under() Type {
- u := n0.Underlying()
-
- // If the underlying type of a defined type is not a defined
- // (incl. instance) type, then that is the desired underlying
- // type.
- var n1 *Named
- switch u1 := u.(type) {
- case nil:
- // After expansion via Underlying(), we should never encounter a nil
- // underlying.
- panic("nil underlying")
- default:
- // common case
- return u
- case *Named:
- // handled below
- n1 = u1
- }
-
- if n0.check == nil {
- panic("Named.check == nil but type is incomplete")
- }
-
- // Invariant: after this point n0 as well as any named types in its
- // underlying chain should be set up when this function exits.
- check := n0.check
- n := n0
-
- seen := make(map[*Named]int) // types that need their underlying type resolved
- var path []Object // objects encountered, for cycle reporting
-
-loop:
- for {
- seen[n] = len(seen)
- path = append(path, n.obj)
- n = n1
- if i, ok := seen[n]; ok {
- // cycle
- check.cycleError(path[i:])
- u = Typ[Invalid]
- break
- }
- u = n.Underlying()
- switch u1 := u.(type) {
- case nil:
- u = Typ[Invalid]
- break loop
- default:
- break loop
- case *Named:
- // Continue collecting *Named types in the chain.
- n1 = u1
- }
- }
-
- for n := range seen {
- // We should never have to update the underlying type of an imported type;
- // those underlying types should have been resolved during the import.
- // Also, doing so would lead to a race condition (was issue #31749).
- // Do this check always, not just in debug mode (it's cheap).
- if n.obj.pkg != check.pkg {
- panic("imported type with unresolved underlying type")
- }
- n.underlying = u
- }
-
- return u
-}
-
-func (n *Named) setUnderlying(typ Type) {
- if n != nil {
- n.underlying = typ
- }
-}
-
-func (n *Named) lookupMethod(pkg *Package, name string, foldCase bool) (int, *Func) {
- n.resolve()
- // If n is an instance, we may not have yet instantiated all of its methods.
- // Look up the method index in orig, and only instantiate method at the
- // matching index (if any).
- i, _ := lookupMethod(n.Origin().methods, pkg, name, foldCase)
- if i < 0 {
- return -1, nil
- }
- // For instances, m.Method(i) will be different from the orig method.
- return i, n.Method(i)
-}
-
-// context returns the type-checker context.
-func (check *Checker) context() *Context {
- if check.ctxt == nil {
- check.ctxt = NewContext()
- }
- return check.ctxt
-}
-
-// expandUnderlying substitutes type arguments in the underlying type n.orig,
-// returning the result. Returns Typ[Invalid] if there was an error.
-func (n *Named) expandUnderlying() Type {
- check := n.check
- if check != nil && trace {
- check.trace(n.obj.pos, "-- Named.expandUnderlying %s", n)
- check.indent++
- defer func() {
- check.indent--
- check.trace(n.obj.pos, "=> %s (tparams = %s, under = %s)", n, n.tparams.list(), n.underlying)
- }()
- }
-
- assert(n.inst.orig.underlying != nil)
- if n.inst.ctxt == nil {
- n.inst.ctxt = NewContext()
- }
-
- orig := n.inst.orig
- targs := n.inst.targs
-
- if _, unexpanded := orig.underlying.(*Named); unexpanded {
- // We should only get a Named underlying type here during type checking
- // (for example, in recursive type declarations).
- assert(check != nil)
- }
-
- if orig.tparams.Len() != targs.Len() {
- // Mismatching arg and tparam length may be checked elsewhere.
- return Typ[Invalid]
- }
-
- // Ensure that an instance is recorded before substituting, so that we
- // resolve n for any recursive references.
- h := n.inst.ctxt.instanceHash(orig, targs.list())
- n2 := n.inst.ctxt.update(h, orig, n.TypeArgs().list(), n)
- assert(n == n2)
-
- smap := makeSubstMap(orig.tparams.list(), targs.list())
- var ctxt *Context
- if check != nil {
- ctxt = check.context()
- }
- underlying := n.check.subst(n.obj.pos, orig.underlying, smap, n, ctxt)
- // If the underlying type of n is an interface, we need to set the receiver of
- // its methods accurately -- we set the receiver of interface methods on
- // the RHS of a type declaration to the defined type.
- if iface, _ := underlying.(*Interface); iface != nil {
- if methods, copied := replaceRecvType(iface.methods, orig, n); copied {
- // If the underlying type doesn't actually use type parameters, it's
- // possible that it wasn't substituted. In this case we need to create
- // a new *Interface before modifying receivers.
- if iface == orig.underlying {
- old := iface
- iface = check.newInterface()
- iface.embeddeds = old.embeddeds
- iface.complete = old.complete
- iface.implicit = old.implicit // should be false but be conservative
- underlying = iface
- }
- iface.methods = methods
- }
- }
-
- return underlying
-}
-
-// safeUnderlying returns the underlying type of typ without expanding
-// instances, to avoid infinite recursion.
-//
-// TODO(rfindley): eliminate this function or give it a better name.
-func safeUnderlying(typ Type) Type {
- if t, _ := typ.(*Named); t != nil {
- return t.underlying
- }
- return typ.Underlying()
-}
diff --git a/contrib/go/_std_1.20/src/go/types/object.go b/contrib/go/_std_1.20/src/go/types/object.go
deleted file mode 100644
index 6e63948680..0000000000
--- a/contrib/go/_std_1.20/src/go/types/object.go
+++ /dev/null
@@ -1,568 +0,0 @@
-// Copyright 2013 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 types
-
-import (
- "bytes"
- "fmt"
- "go/constant"
- "go/token"
-)
-
-// An Object describes a named language entity such as a package,
-// constant, type, variable, function (incl. methods), or label.
-// All objects implement the Object interface.
-type Object interface {
- Parent() *Scope // scope in which this object is declared; nil for methods and struct fields
- Pos() token.Pos // position of object identifier in declaration
- Pkg() *Package // package to which this object belongs; nil for labels and objects in the Universe scope
- Name() string // package local object name
- Type() Type // object type
- Exported() bool // reports whether the name starts with a capital letter
- Id() string // object name if exported, qualified name if not exported (see func Id)
-
- // String returns a human-readable string of the object.
- String() string
-
- // order reflects a package-level object's source order: if object
- // a is before object b in the source, then a.order() < b.order().
- // order returns a value > 0 for package-level objects; it returns
- // 0 for all other objects (including objects in file scopes).
- order() uint32
-
- // color returns the object's color.
- color() color
-
- // setType sets the type of the object.
- setType(Type)
-
- // setOrder sets the order number of the object. It must be > 0.
- setOrder(uint32)
-
- // setColor sets the object's color. It must not be white.
- setColor(color color)
-
- // setParent sets the parent scope of the object.
- setParent(*Scope)
-
- // sameId reports whether obj.Id() and Id(pkg, name) are the same.
- sameId(pkg *Package, name string) bool
-
- // scopePos returns the start position of the scope of this Object
- scopePos() token.Pos
-
- // setScopePos sets the start position of the scope for this Object.
- setScopePos(pos token.Pos)
-}
-
-// Id returns name if it is exported, otherwise it
-// returns the name qualified with the package path.
-func Id(pkg *Package, name string) string {
- if token.IsExported(name) {
- return name
- }
- // unexported names need the package path for differentiation
- // (if there's no package, make sure we don't start with '.'
- // as that may change the order of methods between a setup
- // inside a package and outside a package - which breaks some
- // tests)
- path := "_"
- // pkg is nil for objects in Universe scope and possibly types
- // introduced via Eval (see also comment in object.sameId)
- if pkg != nil && pkg.path != "" {
- path = pkg.path
- }
- return path + "." + name
-}
-
-// An object implements the common parts of an Object.
-type object struct {
- parent *Scope
- pos token.Pos
- pkg *Package
- name string
- typ Type
- order_ uint32
- color_ color
- scopePos_ token.Pos
-}
-
-// color encodes the color of an object (see Checker.objDecl for details).
-type color uint32
-
-// An object may be painted in one of three colors.
-// Color values other than white or black are considered grey.
-const (
- white color = iota
- black
- grey // must be > white and black
-)
-
-func (c color) String() string {
- switch c {
- case white:
- return "white"
- case black:
- return "black"
- default:
- return "grey"
- }
-}
-
-// colorFor returns the (initial) color for an object depending on
-// whether its type t is known or not.
-func colorFor(t Type) color {
- if t != nil {
- return black
- }
- return white
-}
-
-// Parent returns the scope in which the object is declared.
-// The result is nil for methods and struct fields.
-func (obj *object) Parent() *Scope { return obj.parent }
-
-// Pos returns the declaration position of the object's identifier.
-func (obj *object) Pos() token.Pos { return obj.pos }
-
-// Pkg returns the package to which the object belongs.
-// The result is nil for labels and objects in the Universe scope.
-func (obj *object) Pkg() *Package { return obj.pkg }
-
-// Name returns the object's (package-local, unqualified) name.
-func (obj *object) Name() string { return obj.name }
-
-// Type returns the object's type.
-func (obj *object) Type() Type { return obj.typ }
-
-// Exported reports whether the object is exported (starts with a capital letter).
-// It doesn't take into account whether the object is in a local (function) scope
-// or not.
-func (obj *object) Exported() bool { return token.IsExported(obj.name) }
-
-// Id is a wrapper for Id(obj.Pkg(), obj.Name()).
-func (obj *object) Id() string { return Id(obj.pkg, obj.name) }
-
-func (obj *object) String() string { panic("abstract") }
-func (obj *object) order() uint32 { return obj.order_ }
-func (obj *object) color() color { return obj.color_ }
-func (obj *object) scopePos() token.Pos { return obj.scopePos_ }
-
-func (obj *object) setParent(parent *Scope) { obj.parent = parent }
-func (obj *object) setType(typ Type) { obj.typ = typ }
-func (obj *object) setOrder(order uint32) { assert(order > 0); obj.order_ = order }
-func (obj *object) setColor(color color) { assert(color != white); obj.color_ = color }
-func (obj *object) setScopePos(pos token.Pos) { obj.scopePos_ = pos }
-
-func (obj *object) sameId(pkg *Package, name string) bool {
- // spec:
- // "Two identifiers are different if they are spelled differently,
- // or if they appear in different packages and are not exported.
- // Otherwise, they are the same."
- if name != obj.name {
- return false
- }
- // obj.Name == name
- if obj.Exported() {
- return true
- }
- // not exported, so packages must be the same (pkg == nil for
- // fields in Universe scope; this can only happen for types
- // introduced via Eval)
- if pkg == nil || obj.pkg == nil {
- return pkg == obj.pkg
- }
- // pkg != nil && obj.pkg != nil
- return pkg.path == obj.pkg.path
-}
-
-// A PkgName represents an imported Go package.
-// PkgNames don't have a type.
-type PkgName struct {
- object
- imported *Package
- used bool // set if the package was used
-}
-
-// NewPkgName returns a new PkgName object representing an imported package.
-// The remaining arguments set the attributes found with all Objects.
-func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName {
- return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, token.NoPos}, imported, false}
-}
-
-// Imported returns the package that was imported.
-// It is distinct from Pkg(), which is the package containing the import statement.
-func (obj *PkgName) Imported() *Package { return obj.imported }
-
-// A Const represents a declared constant.
-type Const struct {
- object
- val constant.Value
-}
-
-// NewConst returns a new constant with value val.
-// The remaining arguments set the attributes found with all Objects.
-func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
- return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, val}
-}
-
-// Val returns the constant's value.
-func (obj *Const) Val() constant.Value { return obj.val }
-
-func (*Const) isDependency() {} // a constant may be a dependency of an initialization expression
-
-// A TypeName represents a name for a (defined or alias) type.
-type TypeName struct {
- object
-}
-
-// NewTypeName returns a new type name denoting the given typ.
-// The remaining arguments set the attributes found with all Objects.
-//
-// The typ argument may be a defined (Named) type or an alias type.
-// It may also be nil such that the returned TypeName can be used as
-// argument for NewNamed, which will set the TypeName's type as a side-
-// effect.
-func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName {
- return &TypeName{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}}
-}
-
-// _NewTypeNameLazy returns a new defined type like NewTypeName, but it
-// lazily calls resolve to finish constructing the Named object.
-func _NewTypeNameLazy(pos token.Pos, pkg *Package, name string, load func(named *Named) (tparams []*TypeParam, underlying Type, methods []*Func)) *TypeName {
- obj := NewTypeName(pos, pkg, name, nil)
- NewNamed(obj, nil, nil).loader = load
- return obj
-}
-
-// IsAlias reports whether obj is an alias name for a type.
-func (obj *TypeName) IsAlias() bool {
- switch t := obj.typ.(type) {
- case nil:
- return false
- case *Basic:
- // unsafe.Pointer is not an alias.
- if obj.pkg == Unsafe {
- return false
- }
- // Any user-defined type name for a basic type is an alias for a
- // basic type (because basic types are pre-declared in the Universe
- // scope, outside any package scope), and so is any type name with
- // a different name than the name of the basic type it refers to.
- // Additionally, we need to look for "byte" and "rune" because they
- // are aliases but have the same names (for better error messages).
- return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune
- case *Named:
- return obj != t.obj
- case *TypeParam:
- return obj != t.obj
- default:
- return true
- }
-}
-
-// A Variable represents a declared variable (including function parameters and results, and struct fields).
-type Var struct {
- object
- embedded bool // if set, the variable is an embedded struct field, and name is the type name
- isField bool // var is struct field
- used bool // set if the variable was used
- origin *Var // if non-nil, the Var from which this one was instantiated
-}
-
-// NewVar returns a new variable.
-// The arguments set the attributes found with all Objects.
-func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var {
- return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}}
-}
-
-// NewParam returns a new variable representing a function parameter.
-func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var {
- return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, used: true} // parameters are always 'used'
-}
-
-// NewField returns a new variable representing a struct field.
-// For embedded fields, the name is the unqualified type name
-// under which the field is accessible.
-func NewField(pos token.Pos, pkg *Package, name string, typ Type, embedded bool) *Var {
- return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, embedded: embedded, isField: true}
-}
-
-// Anonymous reports whether the variable is an embedded field.
-// Same as Embedded; only present for backward-compatibility.
-func (obj *Var) Anonymous() bool { return obj.embedded }
-
-// Embedded reports whether the variable is an embedded field.
-func (obj *Var) Embedded() bool { return obj.embedded }
-
-// IsField reports whether the variable is a struct field.
-func (obj *Var) IsField() bool { return obj.isField }
-
-// Origin returns the canonical Var for its receiver, i.e. the Var object
-// recorded in Info.Defs.
-//
-// For synthetic Vars created during instantiation (such as struct fields or
-// function parameters that depend on type arguments), this will be the
-// corresponding Var on the generic (uninstantiated) type. For all other Vars
-// Origin returns the receiver.
-func (obj *Var) Origin() *Var {
- if obj.origin != nil {
- return obj.origin
- }
- return obj
-}
-
-func (*Var) isDependency() {} // a variable may be a dependency of an initialization expression
-
-// A Func represents a declared function, concrete method, or abstract
-// (interface) method. Its Type() is always a *Signature.
-// An abstract method may belong to many interfaces due to embedding.
-type Func struct {
- object
- hasPtrRecv_ bool // only valid for methods that don't have a type yet; use hasPtrRecv() to read
- origin *Func // if non-nil, the Func from which this one was instantiated
-}
-
-// NewFunc returns a new function with the given signature, representing
-// the function's type.
-func NewFunc(pos token.Pos, pkg *Package, name string, sig *Signature) *Func {
- // don't store a (typed) nil signature
- var typ Type
- if sig != nil {
- typ = sig
- }
- return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, false, nil}
-}
-
-// FullName returns the package- or receiver-type-qualified name of
-// function or method obj.
-func (obj *Func) FullName() string {
- var buf bytes.Buffer
- writeFuncName(&buf, obj, nil)
- return buf.String()
-}
-
-// Scope returns the scope of the function's body block.
-// The result is nil for imported or instantiated functions and methods
-// (but there is also no mechanism to get to an instantiated function).
-func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
-
-// Origin returns the canonical Func for its receiver, i.e. the Func object
-// recorded in Info.Defs.
-//
-// For synthetic functions created during instantiation (such as methods on an
-// instantiated Named type or interface methods that depend on type arguments),
-// this will be the corresponding Func on the generic (uninstantiated) type.
-// For all other Funcs Origin returns the receiver.
-func (obj *Func) Origin() *Func {
- if obj.origin != nil {
- return obj.origin
- }
- return obj
-}
-
-// hasPtrRecv reports whether the receiver is of the form *T for the given method obj.
-func (obj *Func) hasPtrRecv() bool {
- // If a method's receiver type is set, use that as the source of truth for the receiver.
- // Caution: Checker.funcDecl (decl.go) marks a function by setting its type to an empty
- // signature. We may reach here before the signature is fully set up: we must explicitly
- // check if the receiver is set (we cannot just look for non-nil obj.typ).
- if sig, _ := obj.typ.(*Signature); sig != nil && sig.recv != nil {
- _, isPtr := deref(sig.recv.typ)
- return isPtr
- }
-
- // If a method's type is not set it may be a method/function that is:
- // 1) client-supplied (via NewFunc with no signature), or
- // 2) internally created but not yet type-checked.
- // For case 1) we can't do anything; the client must know what they are doing.
- // For case 2) we can use the information gathered by the resolver.
- return obj.hasPtrRecv_
-}
-
-func (*Func) isDependency() {} // a function may be a dependency of an initialization expression
-
-// A Label represents a declared label.
-// Labels don't have a type.
-type Label struct {
- object
- used bool // set if the label was used
-}
-
-// NewLabel returns a new label.
-func NewLabel(pos token.Pos, pkg *Package, name string) *Label {
- return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid], color_: black}, false}
-}
-
-// A Builtin represents a built-in function.
-// Builtins don't have a valid type.
-type Builtin struct {
- object
- id builtinId
-}
-
-func newBuiltin(id builtinId) *Builtin {
- return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid], color_: black}, id}
-}
-
-// Nil represents the predeclared value nil.
-type Nil struct {
- object
-}
-
-func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
- var tname *TypeName
- typ := obj.Type()
-
- switch obj := obj.(type) {
- case *PkgName:
- fmt.Fprintf(buf, "package %s", obj.Name())
- if path := obj.imported.path; path != "" && path != obj.name {
- fmt.Fprintf(buf, " (%q)", path)
- }
- return
-
- case *Const:
- buf.WriteString("const")
-
- case *TypeName:
- tname = obj
- buf.WriteString("type")
- if isTypeParam(typ) {
- buf.WriteString(" parameter")
- }
-
- case *Var:
- if obj.isField {
- buf.WriteString("field")
- } else {
- buf.WriteString("var")
- }
-
- case *Func:
- buf.WriteString("func ")
- writeFuncName(buf, obj, qf)
- if typ != nil {
- WriteSignature(buf, typ.(*Signature), qf)
- }
- return
-
- case *Label:
- buf.WriteString("label")
- typ = nil
-
- case *Builtin:
- buf.WriteString("builtin")
- typ = nil
-
- case *Nil:
- buf.WriteString("nil")
- return
-
- default:
- panic(fmt.Sprintf("writeObject(%T)", obj))
- }
-
- buf.WriteByte(' ')
-
- // For package-level objects, qualify the name.
- if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
- buf.WriteString(packagePrefix(obj.Pkg(), qf))
- }
- buf.WriteString(obj.Name())
-
- if typ == nil {
- return
- }
-
- if tname != nil {
- switch t := typ.(type) {
- case *Basic:
- // Don't print anything more for basic types since there's
- // no more information.
- return
- case *Named:
- if t.TypeParams().Len() > 0 {
- newTypeWriter(buf, qf).tParamList(t.TypeParams().list())
- }
- }
- if tname.IsAlias() {
- buf.WriteString(" =")
- } else if t, _ := typ.(*TypeParam); t != nil {
- typ = t.bound
- } else {
- // TODO(gri) should this be fromRHS for *Named?
- typ = under(typ)
- }
- }
-
- // Special handling for any: because WriteType will format 'any' as 'any',
- // resulting in the object string `type any = any` rather than `type any =
- // interface{}`. To avoid this, swap in a different empty interface.
- if obj == universeAny {
- assert(Identical(typ, &emptyInterface))
- typ = &emptyInterface
- }
-
- buf.WriteByte(' ')
- WriteType(buf, typ, qf)
-}
-
-func packagePrefix(pkg *Package, qf Qualifier) string {
- if pkg == nil {
- return ""
- }
- var s string
- if qf != nil {
- s = qf(pkg)
- } else {
- s = pkg.Path()
- }
- if s != "" {
- s += "."
- }
- return s
-}
-
-// ObjectString returns the string form of obj.
-// The Qualifier controls the printing of
-// package-level objects, and may be nil.
-func ObjectString(obj Object, qf Qualifier) string {
- var buf bytes.Buffer
- writeObject(&buf, obj, qf)
- return buf.String()
-}
-
-func (obj *PkgName) String() string { return ObjectString(obj, nil) }
-func (obj *Const) String() string { return ObjectString(obj, nil) }
-func (obj *TypeName) String() string { return ObjectString(obj, nil) }
-func (obj *Var) String() string { return ObjectString(obj, nil) }
-func (obj *Func) String() string { return ObjectString(obj, nil) }
-func (obj *Label) String() string { return ObjectString(obj, nil) }
-func (obj *Builtin) String() string { return ObjectString(obj, nil) }
-func (obj *Nil) String() string { return ObjectString(obj, nil) }
-
-func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
- if f.typ != nil {
- sig := f.typ.(*Signature)
- if recv := sig.Recv(); recv != nil {
- buf.WriteByte('(')
- if _, ok := recv.Type().(*Interface); ok {
- // gcimporter creates abstract methods of
- // named interfaces using the interface type
- // (not the named type) as the receiver.
- // Don't print it in full.
- buf.WriteString("interface")
- } else {
- WriteType(buf, recv.Type(), qf)
- }
- buf.WriteByte(')')
- buf.WriteByte('.')
- } else if f.pkg != nil {
- buf.WriteString(packagePrefix(f.pkg, qf))
- }
- }
- buf.WriteString(f.name)
-}
diff --git a/contrib/go/_std_1.20/src/go/types/objset.go b/contrib/go/_std_1.20/src/go/types/objset.go
deleted file mode 100644
index 55eb74addb..0000000000
--- a/contrib/go/_std_1.20/src/go/types/objset.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements objsets.
-//
-// An objset is similar to a Scope but objset elements
-// are identified by their unique id, instead of their
-// object name.
-
-package types
-
-// An objset is a set of objects identified by their unique id.
-// The zero value for objset is a ready-to-use empty objset.
-type objset map[string]Object // initialized lazily
-
-// insert attempts to insert an object obj into objset s.
-// If s already contains an alternative object alt with
-// the same name, insert leaves s unchanged and returns alt.
-// Otherwise it inserts obj and returns nil.
-func (s *objset) insert(obj Object) Object {
- id := obj.Id()
- if alt := (*s)[id]; alt != nil {
- return alt
- }
- if *s == nil {
- *s = make(map[string]Object)
- }
- (*s)[id] = obj
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/go/types/operand.go b/contrib/go/_std_1.20/src/go/types/operand.go
deleted file mode 100644
index 819c99e684..0000000000
--- a/contrib/go/_std_1.20/src/go/types/operand.go
+++ /dev/null
@@ -1,368 +0,0 @@
-// Copyright 2012 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.
-
-// This file defines operands and associated operations.
-
-package types
-
-import (
- "bytes"
- "go/ast"
- "go/constant"
- "go/token"
- . "internal/types/errors"
-)
-
-// An operandMode specifies the (addressing) mode of an operand.
-type operandMode byte
-
-const (
- invalid operandMode = iota // operand is invalid
- novalue // operand represents no value (result of a function call w/o result)
- builtin // operand is a built-in function
- typexpr // operand is a type
- constant_ // operand is a constant; the operand's typ is a Basic type
- variable // operand is an addressable variable
- mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
- value // operand is a computed value
- commaok // like value, but operand may be used in a comma,ok expression
- commaerr // like commaok, but second value is error, not boolean
- cgofunc // operand is a cgo function
-)
-
-var operandModeString = [...]string{
- invalid: "invalid operand",
- novalue: "no value",
- builtin: "built-in",
- typexpr: "type",
- constant_: "constant",
- variable: "variable",
- mapindex: "map index expression",
- value: "value",
- commaok: "comma, ok expression",
- commaerr: "comma, error expression",
- cgofunc: "cgo function",
-}
-
-// An operand represents an intermediate value during type checking.
-// Operands have an (addressing) mode, the expression evaluating to
-// the operand, the operand's type, a value for constants, and an id
-// for built-in functions.
-// The zero value of operand is a ready to use invalid operand.
-type operand struct {
- mode operandMode
- expr ast.Expr
- typ Type
- val constant.Value
- id builtinId
-}
-
-// Pos returns the position of the expression corresponding to x.
-// If x is invalid the position is token.NoPos.
-func (x *operand) Pos() token.Pos {
- // x.expr may not be set if x is invalid
- if x.expr == nil {
- return token.NoPos
- }
- return x.expr.Pos()
-}
-
-// Operand string formats
-// (not all "untyped" cases can appear due to the type system,
-// but they fall out naturally here)
-//
-// mode format
-//
-// invalid <expr> ( <mode> )
-// novalue <expr> ( <mode> )
-// builtin <expr> ( <mode> )
-// typexpr <expr> ( <mode> )
-//
-// constant <expr> (<untyped kind> <mode> )
-// constant <expr> ( <mode> of type <typ>)
-// constant <expr> (<untyped kind> <mode> <val> )
-// constant <expr> ( <mode> <val> of type <typ>)
-//
-// variable <expr> (<untyped kind> <mode> )
-// variable <expr> ( <mode> of type <typ>)
-//
-// mapindex <expr> (<untyped kind> <mode> )
-// mapindex <expr> ( <mode> of type <typ>)
-//
-// value <expr> (<untyped kind> <mode> )
-// value <expr> ( <mode> of type <typ>)
-//
-// commaok <expr> (<untyped kind> <mode> )
-// commaok <expr> ( <mode> of type <typ>)
-//
-// commaerr <expr> (<untyped kind> <mode> )
-// commaerr <expr> ( <mode> of type <typ>)
-//
-// cgofunc <expr> (<untyped kind> <mode> )
-// cgofunc <expr> ( <mode> of type <typ>)
-func operandString(x *operand, qf Qualifier) string {
- // special-case nil
- if x.mode == value && x.typ == Typ[UntypedNil] {
- return "nil"
- }
-
- var buf bytes.Buffer
-
- var expr string
- if x.expr != nil {
- expr = ExprString(x.expr)
- } else {
- switch x.mode {
- case builtin:
- expr = predeclaredFuncs[x.id].name
- case typexpr:
- expr = TypeString(x.typ, qf)
- case constant_:
- expr = x.val.String()
- }
- }
-
- // <expr> (
- if expr != "" {
- buf.WriteString(expr)
- buf.WriteString(" (")
- }
-
- // <untyped kind>
- hasType := false
- switch x.mode {
- case invalid, novalue, builtin, typexpr:
- // no type
- default:
- // should have a type, but be cautious (don't crash during printing)
- if x.typ != nil {
- if isUntyped(x.typ) {
- buf.WriteString(x.typ.(*Basic).name)
- buf.WriteByte(' ')
- break
- }
- hasType = true
- }
- }
-
- // <mode>
- buf.WriteString(operandModeString[x.mode])
-
- // <val>
- if x.mode == constant_ {
- if s := x.val.String(); s != expr {
- buf.WriteByte(' ')
- buf.WriteString(s)
- }
- }
-
- // <typ>
- if hasType {
- if x.typ != Typ[Invalid] {
- var intro string
- if isGeneric(x.typ) {
- intro = " of generic type "
- } else {
- intro = " of type "
- }
- buf.WriteString(intro)
- WriteType(&buf, x.typ, qf)
- if tpar, _ := x.typ.(*TypeParam); tpar != nil {
- buf.WriteString(" constrained by ")
- WriteType(&buf, tpar.bound, qf) // do not compute interface type sets here
- // If we have the type set and it's empty, say so for better error messages.
- if hasEmptyTypeset(tpar) {
- buf.WriteString(" with empty type set")
- }
- }
- } else {
- buf.WriteString(" with invalid type")
- }
- }
-
- // )
- if expr != "" {
- buf.WriteByte(')')
- }
-
- return buf.String()
-}
-
-func (x *operand) String() string {
- return operandString(x, nil)
-}
-
-// setConst sets x to the untyped constant for literal lit.
-func (x *operand) setConst(tok token.Token, lit string) {
- var kind BasicKind
- switch tok {
- case token.INT:
- kind = UntypedInt
- case token.FLOAT:
- kind = UntypedFloat
- case token.IMAG:
- kind = UntypedComplex
- case token.CHAR:
- kind = UntypedRune
- case token.STRING:
- kind = UntypedString
- default:
- unreachable()
- }
-
- val := constant.MakeFromLiteral(lit, tok, 0)
- if val.Kind() == constant.Unknown {
- x.mode = invalid
- x.typ = Typ[Invalid]
- return
- }
- x.mode = constant_
- x.typ = Typ[kind]
- x.val = val
-}
-
-// isNil reports whether x is the nil value.
-func (x *operand) isNil() bool {
- return x.mode == value && x.typ == Typ[UntypedNil]
-}
-
-// assignableTo reports whether x is assignable to a variable of type T. If the
-// result is false and a non-nil cause is provided, it may be set to a more
-// detailed explanation of the failure (result != ""). The returned error code
-// is only valid if the (first) result is false. The check parameter may be nil
-// if assignableTo is invoked through an exported API call, i.e., when all
-// methods have been type-checked.
-func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Code) {
- if x.mode == invalid || T == Typ[Invalid] {
- return true, 0 // avoid spurious errors
- }
-
- V := x.typ
-
- // x's type is identical to T
- if Identical(V, T) {
- return true, 0
- }
-
- Vu := under(V)
- Tu := under(T)
- Vp, _ := V.(*TypeParam)
- Tp, _ := T.(*TypeParam)
-
- // x is an untyped value representable by a value of type T.
- if isUntyped(Vu) {
- assert(Vp == nil)
- if Tp != nil {
- // T is a type parameter: x is assignable to T if it is
- // representable by each specific type in the type set of T.
- return Tp.is(func(t *term) bool {
- if t == nil {
- return false
- }
- // A term may be a tilde term but the underlying
- // type of an untyped value doesn't change so we
- // don't need to do anything special.
- newType, _, _ := check.implicitTypeAndValue(x, t.typ)
- return newType != nil
- }), IncompatibleAssign
- }
- newType, _, _ := check.implicitTypeAndValue(x, T)
- return newType != nil, IncompatibleAssign
- }
- // Vu is typed
-
- // x's type V and T have identical underlying types
- // and at least one of V or T is not a named type
- // and neither V nor T is a type parameter.
- if Identical(Vu, Tu) && (!hasName(V) || !hasName(T)) && Vp == nil && Tp == nil {
- return true, 0
- }
-
- // T is an interface type and x implements T and T is not a type parameter.
- // Also handle the case where T is a pointer to an interface.
- if _, ok := Tu.(*Interface); ok && Tp == nil || isInterfacePtr(Tu) {
- if !check.implements(V, T, false, cause) {
- return false, InvalidIfaceAssign
- }
- return true, 0
- }
-
- // If V is an interface, check if a missing type assertion is the problem.
- if Vi, _ := Vu.(*Interface); Vi != nil && Vp == nil {
- if check.implements(T, V, false, nil) {
- // T implements V, so give hint about type assertion.
- if cause != nil {
- *cause = "need type assertion"
- }
- return false, IncompatibleAssign
- }
- }
-
- // x is a bidirectional channel value, T is a channel
- // type, x's type V and T have identical element types,
- // and at least one of V or T is not a named type.
- if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv {
- if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) {
- return !hasName(V) || !hasName(T), InvalidChanAssign
- }
- }
-
- // optimization: if we don't have type parameters, we're done
- if Vp == nil && Tp == nil {
- return false, IncompatibleAssign
- }
-
- errorf := func(format string, args ...any) {
- if check != nil && cause != nil {
- msg := check.sprintf(format, args...)
- if *cause != "" {
- msg += "\n\t" + *cause
- }
- *cause = msg
- }
- }
-
- // x's type V is not a named type and T is a type parameter, and
- // x is assignable to each specific type in T's type set.
- if !hasName(V) && Tp != nil {
- ok := false
- code := IncompatibleAssign
- Tp.is(func(T *term) bool {
- if T == nil {
- return false // no specific types
- }
- ok, code = x.assignableTo(check, T.typ, cause)
- if !ok {
- errorf("cannot assign %s to %s (in %s)", x.typ, T.typ, Tp)
- return false
- }
- return true
- })
- return ok, code
- }
-
- // x's type V is a type parameter and T is not a named type,
- // and values x' of each specific type in V's type set are
- // assignable to T.
- if Vp != nil && !hasName(T) {
- x := *x // don't clobber outer x
- ok := false
- code := IncompatibleAssign
- Vp.is(func(V *term) bool {
- if V == nil {
- return false // no specific types
- }
- x.typ = V.typ
- ok, code = x.assignableTo(check, T, cause)
- if !ok {
- errorf("cannot assign %s (in %s) to %s", V.typ, Vp, T)
- return false
- }
- return true
- })
- return ok, code
- }
-
- return false, IncompatibleAssign
-}
diff --git a/contrib/go/_std_1.20/src/go/types/package.go b/contrib/go/_std_1.20/src/go/types/package.go
deleted file mode 100644
index 2b72ff1509..0000000000
--- a/contrib/go/_std_1.20/src/go/types/package.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2013 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 types
-
-import (
- "fmt"
- "go/token"
-)
-
-// A Package describes a Go package.
-type Package struct {
- path string
- name string
- scope *Scope
- complete bool
- imports []*Package
- fake bool // scope lookup errors are silently dropped if package is fake (internal use only)
- cgo bool // uses of this package will be rewritten into uses of declarations from _cgo_gotypes.go
-}
-
-// NewPackage returns a new Package for the given package path and name.
-// The package is not complete and contains no explicit imports.
-func NewPackage(path, name string) *Package {
- scope := NewScope(Universe, token.NoPos, token.NoPos, fmt.Sprintf("package %q", path))
- return &Package{path: path, name: name, scope: scope}
-}
-
-// Path returns the package path.
-func (pkg *Package) Path() string { return pkg.path }
-
-// Name returns the package name.
-func (pkg *Package) Name() string { return pkg.name }
-
-// SetName sets the package name.
-func (pkg *Package) SetName(name string) { pkg.name = name }
-
-// Scope returns the (complete or incomplete) package scope
-// holding the objects declared at package level (TypeNames,
-// Consts, Vars, and Funcs).
-// For a nil pkg receiver, Scope returns the Universe scope.
-func (pkg *Package) Scope() *Scope {
- if pkg != nil {
- return pkg.scope
- }
- return Universe
-}
-
-// A package is complete if its scope contains (at least) all
-// exported objects; otherwise it is incomplete.
-func (pkg *Package) Complete() bool { return pkg.complete }
-
-// MarkComplete marks a package as complete.
-func (pkg *Package) MarkComplete() { pkg.complete = true }
-
-// Imports returns the list of packages directly imported by
-// pkg; the list is in source order.
-//
-// If pkg was loaded from export data, Imports includes packages that
-// provide package-level objects referenced by pkg. This may be more or
-// less than the set of packages directly imported by pkg's source code.
-//
-// If pkg uses cgo and the FakeImportC configuration option
-// was enabled, the imports list may contain a fake "C" package.
-func (pkg *Package) Imports() []*Package { return pkg.imports }
-
-// SetImports sets the list of explicitly imported packages to list.
-// It is the caller's responsibility to make sure list elements are unique.
-func (pkg *Package) SetImports(list []*Package) { pkg.imports = list }
-
-func (pkg *Package) String() string {
- return fmt.Sprintf("package %s (%q)", pkg.name, pkg.path)
-}
diff --git a/contrib/go/_std_1.20/src/go/types/pointer.go b/contrib/go/_std_1.20/src/go/types/pointer.go
deleted file mode 100644
index 6352ee57e2..0000000000
--- a/contrib/go/_std_1.20/src/go/types/pointer.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2011 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 types
-
-// A Pointer represents a pointer type.
-type Pointer struct {
- base Type // element type
-}
-
-// NewPointer returns a new pointer type for the given element (base) type.
-func NewPointer(elem Type) *Pointer { return &Pointer{base: elem} }
-
-// Elem returns the element type for the given pointer p.
-func (p *Pointer) Elem() Type { return p.base }
-
-func (t *Pointer) Underlying() Type { return t }
-func (t *Pointer) String() string { return TypeString(t, nil) }
diff --git a/contrib/go/_std_1.20/src/go/types/predicates.go b/contrib/go/_std_1.20/src/go/types/predicates.go
deleted file mode 100644
index e9a0e438d8..0000000000
--- a/contrib/go/_std_1.20/src/go/types/predicates.go
+++ /dev/null
@@ -1,497 +0,0 @@
-// Copyright 2012 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.
-
-// This file implements commonly used type predicates.
-
-package types
-
-import "go/token"
-
-// The isX predicates below report whether t is an X.
-// If t is a type parameter the result is false; i.e.,
-// these predicates don't look inside a type parameter.
-
-func isBoolean(t Type) bool { return isBasic(t, IsBoolean) }
-func isInteger(t Type) bool { return isBasic(t, IsInteger) }
-func isUnsigned(t Type) bool { return isBasic(t, IsUnsigned) }
-func isFloat(t Type) bool { return isBasic(t, IsFloat) }
-func isComplex(t Type) bool { return isBasic(t, IsComplex) }
-func isNumeric(t Type) bool { return isBasic(t, IsNumeric) }
-func isString(t Type) bool { return isBasic(t, IsString) }
-func isIntegerOrFloat(t Type) bool { return isBasic(t, IsInteger|IsFloat) }
-func isConstType(t Type) bool { return isBasic(t, IsConstType) }
-
-// isBasic reports whether under(t) is a basic type with the specified info.
-// If t is a type parameter the result is false; i.e.,
-// isBasic does not look inside a type parameter.
-func isBasic(t Type, info BasicInfo) bool {
- u, _ := under(t).(*Basic)
- return u != nil && u.info&info != 0
-}
-
-// The allX predicates below report whether t is an X.
-// If t is a type parameter the result is true if isX is true
-// for all specified types of the type parameter's type set.
-// allX is an optimized version of isX(coreType(t)) (which
-// is the same as underIs(t, isX)).
-
-func allBoolean(typ Type) bool { return allBasic(typ, IsBoolean) }
-func allInteger(typ Type) bool { return allBasic(typ, IsInteger) }
-func allUnsigned(typ Type) bool { return allBasic(typ, IsUnsigned) }
-func allNumeric(typ Type) bool { return allBasic(typ, IsNumeric) }
-func allString(typ Type) bool { return allBasic(typ, IsString) }
-func allOrdered(typ Type) bool { return allBasic(typ, IsOrdered) }
-func allNumericOrString(typ Type) bool { return allBasic(typ, IsNumeric|IsString) }
-
-// allBasic reports whether under(t) is a basic type with the specified info.
-// If t is a type parameter, the result is true if isBasic(t, info) is true
-// for all specific types of the type parameter's type set.
-// allBasic(t, info) is an optimized version of isBasic(coreType(t), info).
-func allBasic(t Type, info BasicInfo) bool {
- if tpar, _ := t.(*TypeParam); tpar != nil {
- return tpar.is(func(t *term) bool { return t != nil && isBasic(t.typ, info) })
- }
- return isBasic(t, info)
-}
-
-// hasName reports whether t has a name. This includes
-// predeclared types, defined types, and type parameters.
-// hasName may be called with types that are not fully set up.
-func hasName(t Type) bool {
- switch t.(type) {
- case *Basic, *Named, *TypeParam:
- return true
- }
- return false
-}
-
-// isTyped reports whether t is typed; i.e., not an untyped
-// constant or boolean. isTyped may be called with types that
-// are not fully set up.
-func isTyped(t Type) bool {
- // isTyped is called with types that are not fully
- // set up. Must not call under()!
- b, _ := t.(*Basic)
- return b == nil || b.info&IsUntyped == 0
-}
-
-// isUntyped(t) is the same as !isTyped(t).
-func isUntyped(t Type) bool {
- return !isTyped(t)
-}
-
-// IsInterface reports whether t is an interface type.
-func IsInterface(t Type) bool {
- _, ok := under(t).(*Interface)
- return ok
-}
-
-// isNonTypeParamInterface reports whether t is an interface type but not a type parameter.
-func isNonTypeParamInterface(t Type) bool {
- return !isTypeParam(t) && IsInterface(t)
-}
-
-// isTypeParam reports whether t is a type parameter.
-func isTypeParam(t Type) bool {
- _, ok := t.(*TypeParam)
- return ok
-}
-
-// hasEmptyTypeset reports whether t is a type parameter with an empty type set.
-// The function does not force the computation of the type set and so is safe to
-// use anywhere, but it may report a false negative if the type set has not been
-// computed yet.
-func hasEmptyTypeset(t Type) bool {
- if tpar, _ := t.(*TypeParam); tpar != nil && tpar.bound != nil {
- iface, _ := safeUnderlying(tpar.bound).(*Interface)
- return iface != nil && iface.tset != nil && iface.tset.IsEmpty()
- }
- return false
-}
-
-// isGeneric reports whether a type is a generic, uninstantiated type
-// (generic signatures are not included).
-// TODO(gri) should we include signatures or assert that they are not present?
-func isGeneric(t Type) bool {
- // A parameterized type is only generic if it doesn't have an instantiation already.
- named, _ := t.(*Named)
- return named != nil && named.obj != nil && named.inst == nil && named.TypeParams().Len() > 0
-}
-
-// Comparable reports whether values of type T are comparable.
-func Comparable(T Type) bool {
- return comparable(T, true, nil, nil)
-}
-
-// If dynamic is set, non-type parameter interfaces are always comparable.
-// If reportf != nil, it may be used to report why T is not comparable.
-func comparable(T Type, dynamic bool, seen map[Type]bool, reportf func(string, ...interface{})) bool {
- if seen[T] {
- return true
- }
- if seen == nil {
- seen = make(map[Type]bool)
- }
- seen[T] = true
-
- switch t := under(T).(type) {
- case *Basic:
- // assume invalid types to be comparable
- // to avoid follow-up errors
- return t.kind != UntypedNil
- case *Pointer, *Chan:
- return true
- case *Struct:
- for _, f := range t.fields {
- if !comparable(f.typ, dynamic, seen, nil) {
- if reportf != nil {
- reportf("struct containing %s cannot be compared", f.typ)
- }
- return false
- }
- }
- return true
- case *Array:
- if !comparable(t.elem, dynamic, seen, nil) {
- if reportf != nil {
- reportf("%s cannot be compared", t)
- }
- return false
- }
- return true
- case *Interface:
- if dynamic && !isTypeParam(T) || t.typeSet().IsComparable(seen) {
- return true
- }
- if reportf != nil {
- if t.typeSet().IsEmpty() {
- reportf("empty type set")
- } else {
- reportf("incomparable types in type set")
- }
- }
- // fallthrough
- }
- return false
-}
-
-// hasNil reports whether type t includes the nil value.
-func hasNil(t Type) bool {
- switch u := under(t).(type) {
- case *Basic:
- return u.kind == UnsafePointer
- case *Slice, *Pointer, *Signature, *Map, *Chan:
- return true
- case *Interface:
- return !isTypeParam(t) || u.typeSet().underIs(func(u Type) bool {
- return u != nil && hasNil(u)
- })
- }
- return false
-}
-
-// An ifacePair is a node in a stack of interface type pairs compared for identity.
-type ifacePair struct {
- x, y *Interface
- prev *ifacePair
-}
-
-func (p *ifacePair) identical(q *ifacePair) bool {
- return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
-}
-
-// For changes to this code the corresponding changes should be made to unifier.nify.
-func identical(x, y Type, cmpTags bool, p *ifacePair) bool {
- if x == y {
- return true
- }
-
- switch x := x.(type) {
- case *Basic:
- // Basic types are singletons except for the rune and byte
- // aliases, thus we cannot solely rely on the x == y check
- // above. See also comment in TypeName.IsAlias.
- if y, ok := y.(*Basic); ok {
- return x.kind == y.kind
- }
-
- case *Array:
- // Two array types are identical if they have identical element types
- // and the same array length.
- if y, ok := y.(*Array); ok {
- // If one or both array lengths are unknown (< 0) due to some error,
- // assume they are the same to avoid spurious follow-on errors.
- return (x.len < 0 || y.len < 0 || x.len == y.len) && identical(x.elem, y.elem, cmpTags, p)
- }
-
- case *Slice:
- // Two slice types are identical if they have identical element types.
- if y, ok := y.(*Slice); ok {
- return identical(x.elem, y.elem, cmpTags, p)
- }
-
- case *Struct:
- // Two struct types are identical if they have the same sequence of fields,
- // and if corresponding fields have the same names, and identical types,
- // and identical tags. Two embedded fields are considered to have the same
- // name. Lower-case field names from different packages are always different.
- if y, ok := y.(*Struct); ok {
- if x.NumFields() == y.NumFields() {
- for i, f := range x.fields {
- g := y.fields[i]
- if f.embedded != g.embedded ||
- cmpTags && x.Tag(i) != y.Tag(i) ||
- !f.sameId(g.pkg, g.name) ||
- !identical(f.typ, g.typ, cmpTags, p) {
- return false
- }
- }
- return true
- }
- }
-
- case *Pointer:
- // Two pointer types are identical if they have identical base types.
- if y, ok := y.(*Pointer); ok {
- return identical(x.base, y.base, cmpTags, p)
- }
-
- case *Tuple:
- // Two tuples types are identical if they have the same number of elements
- // and corresponding elements have identical types.
- if y, ok := y.(*Tuple); ok {
- if x.Len() == y.Len() {
- if x != nil {
- for i, v := range x.vars {
- w := y.vars[i]
- if !identical(v.typ, w.typ, cmpTags, p) {
- return false
- }
- }
- }
- return true
- }
- }
-
- case *Signature:
- y, _ := y.(*Signature)
- if y == nil {
- return false
- }
-
- // Two function types are identical if they have the same number of
- // parameters and result values, corresponding parameter and result types
- // are identical, and either both functions are variadic or neither is.
- // Parameter and result names are not required to match, and type
- // parameters are considered identical modulo renaming.
-
- if x.TypeParams().Len() != y.TypeParams().Len() {
- return false
- }
-
- // In the case of generic signatures, we will substitute in yparams and
- // yresults.
- yparams := y.params
- yresults := y.results
-
- if x.TypeParams().Len() > 0 {
- // We must ignore type parameter names when comparing x and y. The
- // easiest way to do this is to substitute x's type parameters for y's.
- xtparams := x.TypeParams().list()
- ytparams := y.TypeParams().list()
-
- var targs []Type
- for i := range xtparams {
- targs = append(targs, x.TypeParams().At(i))
- }
- smap := makeSubstMap(ytparams, targs)
-
- var check *Checker // ok to call subst on a nil *Checker
- ctxt := NewContext() // need a non-nil Context for the substitution below
-
- // Constraints must be pair-wise identical, after substitution.
- for i, xtparam := range xtparams {
- ybound := check.subst(token.NoPos, ytparams[i].bound, smap, nil, ctxt)
- if !identical(xtparam.bound, ybound, cmpTags, p) {
- return false
- }
- }
-
- yparams = check.subst(token.NoPos, y.params, smap, nil, ctxt).(*Tuple)
- yresults = check.subst(token.NoPos, y.results, smap, nil, ctxt).(*Tuple)
- }
-
- return x.variadic == y.variadic &&
- identical(x.params, yparams, cmpTags, p) &&
- identical(x.results, yresults, cmpTags, p)
-
- case *Union:
- if y, _ := y.(*Union); y != nil {
- // TODO(rfindley): can this be reached during type checking? If so,
- // consider passing a type set map.
- unionSets := make(map[*Union]*_TypeSet)
- xset := computeUnionTypeSet(nil, unionSets, token.NoPos, x)
- yset := computeUnionTypeSet(nil, unionSets, token.NoPos, y)
- return xset.terms.equal(yset.terms)
- }
-
- case *Interface:
- // Two interface types are identical if they describe the same type sets.
- // With the existing implementation restriction, this simplifies to:
- //
- // Two interface types are identical if they have the same set of methods with
- // the same names and identical function types, and if any type restrictions
- // are the same. Lower-case method names from different packages are always
- // different. The order of the methods is irrelevant.
- if y, ok := y.(*Interface); ok {
- xset := x.typeSet()
- yset := y.typeSet()
- if xset.comparable != yset.comparable {
- return false
- }
- if !xset.terms.equal(yset.terms) {
- return false
- }
- a := xset.methods
- b := yset.methods
- if len(a) == len(b) {
- // Interface types are the only types where cycles can occur
- // that are not "terminated" via named types; and such cycles
- // can only be created via method parameter types that are
- // anonymous interfaces (directly or indirectly) embedding
- // the current interface. Example:
- //
- // type T interface {
- // m() interface{T}
- // }
- //
- // If two such (differently named) interfaces are compared,
- // endless recursion occurs if the cycle is not detected.
- //
- // If x and y were compared before, they must be equal
- // (if they were not, the recursion would have stopped);
- // search the ifacePair stack for the same pair.
- //
- // This is a quadratic algorithm, but in practice these stacks
- // are extremely short (bounded by the nesting depth of interface
- // type declarations that recur via parameter types, an extremely
- // rare occurrence). An alternative implementation might use a
- // "visited" map, but that is probably less efficient overall.
- q := &ifacePair{x, y, p}
- for p != nil {
- if p.identical(q) {
- return true // same pair was compared before
- }
- p = p.prev
- }
- if debug {
- assertSortedMethods(a)
- assertSortedMethods(b)
- }
- for i, f := range a {
- g := b[i]
- if f.Id() != g.Id() || !identical(f.typ, g.typ, cmpTags, q) {
- return false
- }
- }
- return true
- }
- }
-
- case *Map:
- // Two map types are identical if they have identical key and value types.
- if y, ok := y.(*Map); ok {
- return identical(x.key, y.key, cmpTags, p) && identical(x.elem, y.elem, cmpTags, p)
- }
-
- case *Chan:
- // Two channel types are identical if they have identical value types
- // and the same direction.
- if y, ok := y.(*Chan); ok {
- return x.dir == y.dir && identical(x.elem, y.elem, cmpTags, p)
- }
-
- case *Named:
- // Two named types are identical if their type names originate
- // in the same type declaration.
- if y, ok := y.(*Named); ok {
- xargs := x.TypeArgs().list()
- yargs := y.TypeArgs().list()
-
- if len(xargs) != len(yargs) {
- return false
- }
-
- if len(xargs) > 0 {
- // Instances are identical if their original type and type arguments
- // are identical.
- if !Identical(x.Origin(), y.Origin()) {
- return false
- }
- for i, xa := range xargs {
- if !Identical(xa, yargs[i]) {
- return false
- }
- }
- return true
- }
-
- // TODO(gri) Why is x == y not sufficient? And if it is,
- // we can just return false here because x == y
- // is caught in the very beginning of this function.
- return x.obj == y.obj
- }
-
- case *TypeParam:
- // nothing to do (x and y being equal is caught in the very beginning of this function)
-
- case nil:
- // avoid a crash in case of nil type
-
- default:
- unreachable()
- }
-
- return false
-}
-
-// identicalInstance reports if two type instantiations are identical.
-// Instantiations are identical if their origin and type arguments are
-// identical.
-func identicalInstance(xorig Type, xargs []Type, yorig Type, yargs []Type) bool {
- if len(xargs) != len(yargs) {
- return false
- }
-
- for i, xa := range xargs {
- if !Identical(xa, yargs[i]) {
- return false
- }
- }
-
- return Identical(xorig, yorig)
-}
-
-// Default returns the default "typed" type for an "untyped" type;
-// it returns the incoming type for all other types. The default type
-// for untyped nil is untyped nil.
-func Default(t Type) Type {
- if t, ok := t.(*Basic); ok {
- switch t.kind {
- case UntypedBool:
- return Typ[Bool]
- case UntypedInt:
- return Typ[Int]
- case UntypedRune:
- return universeRune // use 'rune' name
- case UntypedFloat:
- return Typ[Float64]
- case UntypedComplex:
- return Typ[Complex128]
- case UntypedString:
- return Typ[String]
- }
- }
- return t
-}
diff --git a/contrib/go/_std_1.20/src/go/types/resolver.go b/contrib/go/_std_1.20/src/go/types/resolver.go
deleted file mode 100644
index 075bd91261..0000000000
--- a/contrib/go/_std_1.20/src/go/types/resolver.go
+++ /dev/null
@@ -1,726 +0,0 @@
-// Copyright 2013 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 types
-
-import (
- "fmt"
- "go/ast"
- "go/constant"
- "go/internal/typeparams"
- "go/token"
- . "internal/types/errors"
- "sort"
- "strconv"
- "strings"
- "unicode"
-)
-
-// A declInfo describes a package-level const, type, var, or func declaration.
-type declInfo struct {
- file *Scope // scope of file containing this declaration
- lhs []*Var // lhs of n:1 variable declarations, or nil
- vtyp ast.Expr // type, or nil (for const and var declarations only)
- init ast.Expr // init/orig expression, or nil (for const and var declarations only)
- inherited bool // if set, the init expression is inherited from a previous constant declaration
- tdecl *ast.TypeSpec // type declaration, or nil
- fdecl *ast.FuncDecl // func declaration, or nil
-
- // The deps field tracks initialization expression dependencies.
- deps map[Object]bool // lazily initialized
-}
-
-// hasInitializer reports whether the declared object has an initialization
-// expression or function body.
-func (d *declInfo) hasInitializer() bool {
- return d.init != nil || d.fdecl != nil && d.fdecl.Body != nil
-}
-
-// addDep adds obj to the set of objects d's init expression depends on.
-func (d *declInfo) addDep(obj Object) {
- m := d.deps
- if m == nil {
- m = make(map[Object]bool)
- d.deps = m
- }
- m[obj] = true
-}
-
-// arityMatch checks that the lhs and rhs of a const or var decl
-// have the appropriate number of names and init exprs. For const
-// decls, init is the value spec providing the init exprs; for
-// var decls, init is nil (the init exprs are in s in this case).
-func (check *Checker) arityMatch(s, init *ast.ValueSpec) {
- l := len(s.Names)
- r := len(s.Values)
- if init != nil {
- r = len(init.Values)
- }
-
- const code = WrongAssignCount
- switch {
- case init == nil && r == 0:
- // var decl w/o init expr
- if s.Type == nil {
- check.error(s, code, "missing type or init expr")
- }
- case l < r:
- if l < len(s.Values) {
- // init exprs from s
- n := s.Values[l]
- check.errorf(n, code, "extra init expr %s", n)
- // TODO(gri) avoid declared and not used error here
- } else {
- // init exprs "inherited"
- check.errorf(s, code, "extra init expr at %s", check.fset.Position(init.Pos()))
- // TODO(gri) avoid declared and not used error here
- }
- case l > r && (init != nil || r != 1):
- n := s.Names[r]
- check.errorf(n, code, "missing init expr for %s", n)
- }
-}
-
-func validatedImportPath(path string) (string, error) {
- s, err := strconv.Unquote(path)
- if err != nil {
- return "", err
- }
- if s == "" {
- return "", fmt.Errorf("empty string")
- }
- const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
- for _, r := range s {
- if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
- return s, fmt.Errorf("invalid character %#U", r)
- }
- }
- return s, nil
-}
-
-// declarePkgObj declares obj in the package scope, records its ident -> obj mapping,
-// and updates check.objMap. The object must not be a function or method.
-func (check *Checker) declarePkgObj(ident *ast.Ident, obj Object, d *declInfo) {
- assert(ident.Name == obj.Name())
-
- // spec: "A package-scope or file-scope identifier with name init
- // may only be declared to be a function with this (func()) signature."
- if ident.Name == "init" {
- check.error(ident, InvalidInitDecl, "cannot declare init - must be func")
- return
- }
-
- // spec: "The main package must have package name main and declare
- // a function main that takes no arguments and returns no value."
- if ident.Name == "main" && check.pkg.name == "main" {
- check.error(ident, InvalidMainDecl, "cannot declare main - must be func")
- return
- }
-
- check.declare(check.pkg.scope, ident, obj, token.NoPos)
- check.objMap[obj] = d
- obj.setOrder(uint32(len(check.objMap)))
-}
-
-// filename returns a filename suitable for debugging output.
-func (check *Checker) filename(fileNo int) string {
- file := check.files[fileNo]
- if pos := file.Pos(); pos.IsValid() {
- return check.fset.File(pos).Name()
- }
- return fmt.Sprintf("file[%d]", fileNo)
-}
-
-func (check *Checker) importPackage(at positioner, path, dir string) *Package {
- // If we already have a package for the given (path, dir)
- // pair, use it instead of doing a full import.
- // Checker.impMap only caches packages that are marked Complete
- // or fake (dummy packages for failed imports). Incomplete but
- // non-fake packages do require an import to complete them.
- key := importKey{path, dir}
- imp := check.impMap[key]
- if imp != nil {
- return imp
- }
-
- // no package yet => import it
- if path == "C" && (check.conf.FakeImportC || check.conf.go115UsesCgo) {
- imp = NewPackage("C", "C")
- imp.fake = true // package scope is not populated
- imp.cgo = check.conf.go115UsesCgo
- } else {
- // ordinary import
- var err error
- if importer := check.conf.Importer; importer == nil {
- err = fmt.Errorf("Config.Importer not installed")
- } else if importerFrom, ok := importer.(ImporterFrom); ok {
- imp, err = importerFrom.ImportFrom(path, dir, 0)
- if imp == nil && err == nil {
- err = fmt.Errorf("Config.Importer.ImportFrom(%s, %s, 0) returned nil but no error", path, dir)
- }
- } else {
- imp, err = importer.Import(path)
- if imp == nil && err == nil {
- err = fmt.Errorf("Config.Importer.Import(%s) returned nil but no error", path)
- }
- }
- // make sure we have a valid package name
- // (errors here can only happen through manipulation of packages after creation)
- if err == nil && imp != nil && (imp.name == "_" || imp.name == "") {
- err = fmt.Errorf("invalid package name: %q", imp.name)
- imp = nil // create fake package below
- }
- if err != nil {
- check.errorf(at, BrokenImport, "could not import %s (%s)", path, err)
- if imp == nil {
- // create a new fake package
- // come up with a sensible package name (heuristic)
- name := path
- if i := len(name); i > 0 && name[i-1] == '/' {
- name = name[:i-1]
- }
- if i := strings.LastIndex(name, "/"); i >= 0 {
- name = name[i+1:]
- }
- imp = NewPackage(path, name)
- }
- // continue to use the package as best as we can
- imp.fake = true // avoid follow-up lookup failures
- }
- }
-
- // package should be complete or marked fake, but be cautious
- if imp.complete || imp.fake {
- check.impMap[key] = imp
- // Once we've formatted an error message, keep the pkgPathMap
- // up-to-date on subsequent imports. It is used for package
- // qualification in error messages.
- if check.pkgPathMap != nil {
- check.markImports(imp)
- }
- return imp
- }
-
- // something went wrong (importer may have returned incomplete package without error)
- return nil
-}
-
-// collectObjects collects all file and package objects and inserts them
-// into their respective scopes. It also performs imports and associates
-// methods with receiver base type names.
-func (check *Checker) collectObjects() {
- pkg := check.pkg
-
- // pkgImports is the set of packages already imported by any package file seen
- // so far. Used to avoid duplicate entries in pkg.imports. Allocate and populate
- // it (pkg.imports may not be empty if we are checking test files incrementally).
- // Note that pkgImports is keyed by package (and thus package path), not by an
- // importKey value. Two different importKey values may map to the same package
- // which is why we cannot use the check.impMap here.
- var pkgImports = make(map[*Package]bool)
- for _, imp := range pkg.imports {
- pkgImports[imp] = true
- }
-
- type methodInfo struct {
- obj *Func // method
- ptr bool // true if pointer receiver
- recv *ast.Ident // receiver type name
- }
- var methods []methodInfo // collected methods with valid receivers and non-blank _ names
- var fileScopes []*Scope
- for fileNo, file := range check.files {
- // The package identifier denotes the current package,
- // but there is no corresponding package object.
- check.recordDef(file.Name, nil)
-
- // Use the actual source file extent rather than *ast.File extent since the
- // latter doesn't include comments which appear at the start or end of the file.
- // Be conservative and use the *ast.File extent if we don't have a *token.File.
- pos, end := file.Pos(), file.End()
- if f := check.fset.File(file.Pos()); f != nil {
- pos, end = token.Pos(f.Base()), token.Pos(f.Base()+f.Size())
- }
- fileScope := NewScope(check.pkg.scope, pos, end, check.filename(fileNo))
- fileScopes = append(fileScopes, fileScope)
- check.recordScope(file, fileScope)
-
- // determine file directory, necessary to resolve imports
- // FileName may be "" (typically for tests) in which case
- // we get "." as the directory which is what we would want.
- fileDir := dir(check.fset.Position(file.Name.Pos()).Filename)
-
- check.walkDecls(file.Decls, func(d decl) {
- switch d := d.(type) {
- case importDecl:
- // import package
- if d.spec.Path.Value == "" {
- return // error reported by parser
- }
- path, err := validatedImportPath(d.spec.Path.Value)
- if err != nil {
- check.errorf(d.spec.Path, BadImportPath, "invalid import path (%s)", err)
- return
- }
-
- imp := check.importPackage(d.spec.Path, path, fileDir)
- if imp == nil {
- return
- }
-
- // local name overrides imported package name
- name := imp.name
- if d.spec.Name != nil {
- name = d.spec.Name.Name
- if path == "C" {
- // match 1.17 cmd/compile (not prescribed by spec)
- check.error(d.spec.Name, ImportCRenamed, `cannot rename import "C"`)
- return
- }
- }
-
- if name == "init" {
- check.error(d.spec, InvalidInitDecl, "cannot import package as init - init must be a func")
- return
- }
-
- // add package to list of explicit imports
- // (this functionality is provided as a convenience
- // for clients; it is not needed for type-checking)
- if !pkgImports[imp] {
- pkgImports[imp] = true
- pkg.imports = append(pkg.imports, imp)
- }
-
- pkgName := NewPkgName(d.spec.Pos(), pkg, name, imp)
- if d.spec.Name != nil {
- // in a dot-import, the dot represents the package
- check.recordDef(d.spec.Name, pkgName)
- } else {
- check.recordImplicit(d.spec, pkgName)
- }
-
- if imp.fake {
- // match 1.17 cmd/compile (not prescribed by spec)
- pkgName.used = true
- }
-
- // add import to file scope
- check.imports = append(check.imports, pkgName)
- if name == "." {
- // dot-import
- if check.dotImportMap == nil {
- check.dotImportMap = make(map[dotImportKey]*PkgName)
- }
- // merge imported scope with file scope
- for name, obj := range imp.scope.elems {
- // Note: Avoid eager resolve(name, obj) here, so we only
- // resolve dot-imported objects as needed.
-
- // A package scope may contain non-exported objects,
- // do not import them!
- if token.IsExported(name) {
- // declare dot-imported object
- // (Do not use check.declare because it modifies the object
- // via Object.setScopePos, which leads to a race condition;
- // the object may be imported into more than one file scope
- // concurrently. See issue #32154.)
- if alt := fileScope.Lookup(name); alt != nil {
- check.errorf(d.spec.Name, DuplicateDecl, "%s redeclared in this block", alt.Name())
- check.reportAltDecl(alt)
- } else {
- fileScope.insert(name, obj)
- check.dotImportMap[dotImportKey{fileScope, name}] = pkgName
- }
- }
- }
- } else {
- // declare imported package object in file scope
- // (no need to provide s.Name since we called check.recordDef earlier)
- check.declare(fileScope, nil, pkgName, token.NoPos)
- }
- case constDecl:
- // declare all constants
- for i, name := range d.spec.Names {
- obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(d.iota)))
-
- var init ast.Expr
- if i < len(d.init) {
- init = d.init[i]
- }
-
- d := &declInfo{file: fileScope, vtyp: d.typ, init: init, inherited: d.inherited}
- check.declarePkgObj(name, obj, d)
- }
-
- case varDecl:
- lhs := make([]*Var, len(d.spec.Names))
- // If there's exactly one rhs initializer, use
- // the same declInfo d1 for all lhs variables
- // so that each lhs variable depends on the same
- // rhs initializer (n:1 var declaration).
- var d1 *declInfo
- if len(d.spec.Values) == 1 {
- // The lhs elements are only set up after the for loop below,
- // but that's ok because declareVar only collects the declInfo
- // for a later phase.
- d1 = &declInfo{file: fileScope, lhs: lhs, vtyp: d.spec.Type, init: d.spec.Values[0]}
- }
-
- // declare all variables
- for i, name := range d.spec.Names {
- obj := NewVar(name.Pos(), pkg, name.Name, nil)
- lhs[i] = obj
-
- di := d1
- if di == nil {
- // individual assignments
- var init ast.Expr
- if i < len(d.spec.Values) {
- init = d.spec.Values[i]
- }
- di = &declInfo{file: fileScope, vtyp: d.spec.Type, init: init}
- }
-
- check.declarePkgObj(name, obj, di)
- }
- case typeDecl:
- if d.spec.TypeParams.NumFields() != 0 && !check.allowVersion(pkg, 1, 18) {
- check.softErrorf(d.spec.TypeParams.List[0], UnsupportedFeature, "type parameter requires go1.18 or later")
- }
- obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil)
- check.declarePkgObj(d.spec.Name, obj, &declInfo{file: fileScope, tdecl: d.spec})
- case funcDecl:
- name := d.decl.Name.Name
- obj := NewFunc(d.decl.Name.Pos(), pkg, name, nil)
- hasTParamError := false // avoid duplicate type parameter errors
- if d.decl.Recv.NumFields() == 0 {
- // regular function
- if d.decl.Recv != nil {
- check.error(d.decl.Recv, BadRecv, "method has no receiver")
- // treat as function
- }
- if name == "init" || (name == "main" && check.pkg.name == "main") {
- code := InvalidInitDecl
- if name == "main" {
- code = InvalidMainDecl
- }
- if d.decl.Type.TypeParams.NumFields() != 0 {
- check.softErrorf(d.decl.Type.TypeParams.List[0], code, "func %s must have no type parameters", name)
- hasTParamError = true
- }
- if t := d.decl.Type; t.Params.NumFields() != 0 || t.Results != nil {
- // TODO(rFindley) Should this be a hard error?
- check.softErrorf(d.decl.Name, code, "func %s must have no arguments and no return values", name)
- }
- }
- if name == "init" {
- // don't declare init functions in the package scope - they are invisible
- obj.parent = pkg.scope
- check.recordDef(d.decl.Name, obj)
- // init functions must have a body
- if d.decl.Body == nil {
- // TODO(gri) make this error message consistent with the others above
- check.softErrorf(obj, MissingInitBody, "missing function body")
- }
- } else {
- check.declare(pkg.scope, d.decl.Name, obj, token.NoPos)
- }
- } else {
- // method
-
- // TODO(rFindley) earlier versions of this code checked that methods
- // have no type parameters, but this is checked later
- // when type checking the function type. Confirm that
- // we don't need to check tparams here.
-
- ptr, recv, _ := check.unpackRecv(d.decl.Recv.List[0].Type, false)
- // (Methods with invalid receiver cannot be associated to a type, and
- // methods with blank _ names are never found; no need to collect any
- // of them. They will still be type-checked with all the other functions.)
- if recv != nil && name != "_" {
- methods = append(methods, methodInfo{obj, ptr, recv})
- }
- check.recordDef(d.decl.Name, obj)
- }
- if d.decl.Type.TypeParams.NumFields() != 0 && !check.allowVersion(pkg, 1, 18) && !hasTParamError {
- check.softErrorf(d.decl.Type.TypeParams.List[0], UnsupportedFeature, "type parameter requires go1.18 or later")
- }
- info := &declInfo{file: fileScope, fdecl: d.decl}
- // Methods are not package-level objects but we still track them in the
- // object map so that we can handle them like regular functions (if the
- // receiver is invalid); also we need their fdecl info when associating
- // them with their receiver base type, below.
- check.objMap[obj] = info
- obj.setOrder(uint32(len(check.objMap)))
- }
- })
- }
-
- // verify that objects in package and file scopes have different names
- for _, scope := range fileScopes {
- for name, obj := range scope.elems {
- if alt := pkg.scope.Lookup(name); alt != nil {
- obj = resolve(name, obj)
- if pkg, ok := obj.(*PkgName); ok {
- check.errorf(alt, DuplicateDecl, "%s already declared through import of %s", alt.Name(), pkg.Imported())
- check.reportAltDecl(pkg)
- } else {
- check.errorf(alt, DuplicateDecl, "%s already declared through dot-import of %s", alt.Name(), obj.Pkg())
- // TODO(gri) dot-imported objects don't have a position; reportAltDecl won't print anything
- check.reportAltDecl(obj)
- }
- }
- }
- }
-
- // Now that we have all package scope objects and all methods,
- // associate methods with receiver base type name where possible.
- // Ignore methods that have an invalid receiver. They will be
- // type-checked later, with regular functions.
- if methods == nil {
- return // nothing to do
- }
- check.methods = make(map[*TypeName][]*Func)
- for i := range methods {
- m := &methods[i]
- // Determine the receiver base type and associate m with it.
- ptr, base := check.resolveBaseTypeName(m.ptr, m.recv)
- if base != nil {
- m.obj.hasPtrRecv_ = ptr
- check.methods[base] = append(check.methods[base], m.obj)
- }
- }
-}
-
-// unpackRecv unpacks a receiver type and returns its components: ptr indicates whether
-// rtyp is a pointer receiver, rname is the receiver type name, and tparams are its
-// type parameters, if any. The type parameters are only unpacked if unpackParams is
-// set. If rname is nil, the receiver is unusable (i.e., the source has a bug which we
-// cannot easily work around).
-func (check *Checker) unpackRecv(rtyp ast.Expr, unpackParams bool) (ptr bool, rname *ast.Ident, tparams []*ast.Ident) {
-L: // unpack receiver type
- // This accepts invalid receivers such as ***T and does not
- // work for other invalid receivers, but we don't care. The
- // validity of receiver expressions is checked elsewhere.
- for {
- switch t := rtyp.(type) {
- case *ast.ParenExpr:
- rtyp = t.X
- case *ast.StarExpr:
- ptr = true
- rtyp = t.X
- default:
- break L
- }
- }
-
- // unpack type parameters, if any
- switch rtyp.(type) {
- case *ast.IndexExpr, *ast.IndexListExpr:
- ix := typeparams.UnpackIndexExpr(rtyp)
- rtyp = ix.X
- if unpackParams {
- for _, arg := range ix.Indices {
- var par *ast.Ident
- switch arg := arg.(type) {
- case *ast.Ident:
- par = arg
- case *ast.BadExpr:
- // ignore - error already reported by parser
- case nil:
- check.error(ix.Orig, InvalidSyntaxTree, "parameterized receiver contains nil parameters")
- default:
- check.errorf(arg, BadDecl, "receiver type parameter %s must be an identifier", arg)
- }
- if par == nil {
- par = &ast.Ident{NamePos: arg.Pos(), Name: "_"}
- }
- tparams = append(tparams, par)
- }
- }
- }
-
- // unpack receiver name
- if name, _ := rtyp.(*ast.Ident); name != nil {
- rname = name
- }
-
- return
-}
-
-// resolveBaseTypeName returns the non-alias base type name for typ, and whether
-// there was a pointer indirection to get to it. The base type name must be declared
-// in package scope, and there can be at most one pointer indirection. If no such type
-// name exists, the returned base is nil.
-func (check *Checker) resolveBaseTypeName(seenPtr bool, name *ast.Ident) (ptr bool, base *TypeName) {
- // Algorithm: Starting from a type expression, which may be a name,
- // we follow that type through alias declarations until we reach a
- // non-alias type name. If we encounter anything but pointer types or
- // parentheses we're done. If we encounter more than one pointer type
- // we're done.
- ptr = seenPtr
- var seen map[*TypeName]bool
- var typ ast.Expr = name
- for {
- typ = unparen(typ)
-
- // check if we have a pointer type
- if pexpr, _ := typ.(*ast.StarExpr); pexpr != nil {
- // if we've already seen a pointer, we're done
- if ptr {
- return false, nil
- }
- ptr = true
- typ = unparen(pexpr.X) // continue with pointer base type
- }
-
- // typ must be a name
- name, _ := typ.(*ast.Ident)
- if name == nil {
- return false, nil
- }
-
- // name must denote an object found in the current package scope
- // (note that dot-imported objects are not in the package scope!)
- obj := check.pkg.scope.Lookup(name.Name)
- if obj == nil {
- return false, nil
- }
-
- // the object must be a type name...
- tname, _ := obj.(*TypeName)
- if tname == nil {
- return false, nil
- }
-
- // ... which we have not seen before
- if seen[tname] {
- return false, nil
- }
-
- // we're done if tdecl defined tname as a new type
- // (rather than an alias)
- tdecl := check.objMap[tname].tdecl // must exist for objects in package scope
- if !tdecl.Assign.IsValid() {
- return ptr, tname
- }
-
- // otherwise, continue resolving
- typ = tdecl.Type
- if seen == nil {
- seen = make(map[*TypeName]bool)
- }
- seen[tname] = true
- }
-}
-
-// packageObjects typechecks all package objects, but not function bodies.
-func (check *Checker) packageObjects() {
- // process package objects in source order for reproducible results
- objList := make([]Object, len(check.objMap))
- i := 0
- for obj := range check.objMap {
- objList[i] = obj
- i++
- }
- sort.Sort(inSourceOrder(objList))
-
- // add new methods to already type-checked types (from a prior Checker.Files call)
- for _, obj := range objList {
- if obj, _ := obj.(*TypeName); obj != nil && obj.typ != nil {
- check.collectMethods(obj)
- }
- }
-
- // We process non-alias type declarations first, followed by alias declarations,
- // and then everything else. This appears to avoid most situations where the type
- // of an alias is needed before it is available.
- // There may still be cases where this is not good enough (see also issue #25838).
- // In those cases Checker.ident will report an error ("invalid use of type alias").
- var aliasList []*TypeName
- var othersList []Object // everything that's not a type
- // phase 1: non-alias type declarations
- for _, obj := range objList {
- if tname, _ := obj.(*TypeName); tname != nil {
- if check.objMap[tname].tdecl.Assign.IsValid() {
- aliasList = append(aliasList, tname)
- } else {
- check.objDecl(obj, nil)
- }
- } else {
- othersList = append(othersList, obj)
- }
- }
- // phase 2: alias type declarations
- for _, obj := range aliasList {
- check.objDecl(obj, nil)
- }
- // phase 3: all other declarations
- for _, obj := range othersList {
- check.objDecl(obj, nil)
- }
-
- // At this point we may have a non-empty check.methods map; this means that not all
- // entries were deleted at the end of typeDecl because the respective receiver base
- // types were not found. In that case, an error was reported when declaring those
- // methods. We can now safely discard this map.
- check.methods = nil
-}
-
-// inSourceOrder implements the sort.Sort interface.
-type inSourceOrder []Object
-
-func (a inSourceOrder) Len() int { return len(a) }
-func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() }
-func (a inSourceOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-
-// unusedImports checks for unused imports.
-func (check *Checker) unusedImports() {
- // If function bodies are not checked, packages' uses are likely missing - don't check.
- if check.conf.IgnoreFuncBodies {
- return
- }
-
- // spec: "It is illegal (...) to directly import a package without referring to
- // any of its exported identifiers. To import a package solely for its side-effects
- // (initialization), use the blank identifier as explicit package name."
-
- for _, obj := range check.imports {
- if !obj.used && obj.name != "_" {
- check.errorUnusedPkg(obj)
- }
- }
-}
-
-func (check *Checker) errorUnusedPkg(obj *PkgName) {
- // If the package was imported with a name other than the final
- // import path element, show it explicitly in the error message.
- // Note that this handles both renamed imports and imports of
- // packages containing unconventional package declarations.
- // Note that this uses / always, even on Windows, because Go import
- // paths always use forward slashes.
- path := obj.imported.path
- elem := path
- if i := strings.LastIndex(elem, "/"); i >= 0 {
- elem = elem[i+1:]
- }
- if obj.name == "" || obj.name == "." || obj.name == elem {
- check.softErrorf(obj, UnusedImport, "%q imported and not used", path)
- } else {
- check.softErrorf(obj, UnusedImport, "%q imported as %s and not used", path, obj.name)
- }
-}
-
-// dir makes a good-faith attempt to return the directory
-// portion of path. If path is empty, the result is ".".
-// (Per the go/build package dependency tests, we cannot import
-// path/filepath and simply use filepath.Dir.)
-func dir(path string) string {
- if i := strings.LastIndexAny(path, `/\`); i > 0 {
- return path[:i]
- }
- // i <= 0
- return "."
-}
diff --git a/contrib/go/_std_1.20/src/go/types/scope.go b/contrib/go/_std_1.20/src/go/types/scope.go
deleted file mode 100644
index fc42ce6524..0000000000
--- a/contrib/go/_std_1.20/src/go/types/scope.go
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements Scopes.
-
-package types
-
-import (
- "fmt"
- "go/token"
- "io"
- "sort"
- "strings"
- "sync"
-)
-
-// A Scope maintains a set of objects and links to its containing
-// (parent) and contained (children) scopes. Objects may be inserted
-// and looked up by name. The zero value for Scope is a ready-to-use
-// empty scope.
-type Scope struct {
- parent *Scope
- children []*Scope
- number int // parent.children[number-1] is this scope; 0 if there is no parent
- elems map[string]Object // lazily allocated
- pos, end token.Pos // scope extent; may be invalid
- comment string // for debugging only
- isFunc bool // set if this is a function scope (internal use only)
-}
-
-// NewScope returns a new, empty scope contained in the given parent
-// scope, if any. The comment is for debugging only.
-func NewScope(parent *Scope, pos, end token.Pos, comment string) *Scope {
- s := &Scope{parent, nil, 0, nil, pos, end, comment, false}
- // don't add children to Universe scope!
- if parent != nil && parent != Universe {
- parent.children = append(parent.children, s)
- s.number = len(parent.children)
- }
- return s
-}
-
-// Parent returns the scope's containing (parent) scope.
-func (s *Scope) Parent() *Scope { return s.parent }
-
-// Len returns the number of scope elements.
-func (s *Scope) Len() int { return len(s.elems) }
-
-// Names returns the scope's element names in sorted order.
-func (s *Scope) Names() []string {
- names := make([]string, len(s.elems))
- i := 0
- for name := range s.elems {
- names[i] = name
- i++
- }
- sort.Strings(names)
- return names
-}
-
-// NumChildren returns the number of scopes nested in s.
-func (s *Scope) NumChildren() int { return len(s.children) }
-
-// Child returns the i'th child scope for 0 <= i < NumChildren().
-func (s *Scope) Child(i int) *Scope { return s.children[i] }
-
-// Lookup returns the object in scope s with the given name if such an
-// object exists; otherwise the result is nil.
-func (s *Scope) Lookup(name string) Object {
- return resolve(name, s.elems[name])
-}
-
-// LookupParent follows the parent chain of scopes starting with s until
-// it finds a scope where Lookup(name) returns a non-nil object, and then
-// returns that scope and object. If a valid position pos is provided,
-// only objects that were declared at or before pos are considered.
-// If no such scope and object exists, the result is (nil, nil).
-//
-// Note that obj.Parent() may be different from the returned scope if the
-// object was inserted into the scope and already had a parent at that
-// time (see Insert). This can only happen for dot-imported objects
-// whose scope is the scope of the package that exported them.
-func (s *Scope) LookupParent(name string, pos token.Pos) (*Scope, Object) {
- for ; s != nil; s = s.parent {
- if obj := s.Lookup(name); obj != nil && (!pos.IsValid() || obj.scopePos() <= pos) {
- return s, obj
- }
- }
- return nil, nil
-}
-
-// Insert attempts to insert an object obj into scope s.
-// If s already contains an alternative object alt with
-// the same name, Insert leaves s unchanged and returns alt.
-// Otherwise it inserts obj, sets the object's parent scope
-// if not already set, and returns nil.
-func (s *Scope) Insert(obj Object) Object {
- name := obj.Name()
- if alt := s.Lookup(name); alt != nil {
- return alt
- }
- s.insert(name, obj)
- if obj.Parent() == nil {
- obj.setParent(s)
- }
- return nil
-}
-
-// _InsertLazy is like Insert, but allows deferring construction of the
-// inserted object until it's accessed with Lookup. The Object
-// returned by resolve must have the same name as given to _InsertLazy.
-// If s already contains an alternative object with the same name,
-// _InsertLazy leaves s unchanged and returns false. Otherwise it
-// records the binding and returns true. The object's parent scope
-// will be set to s after resolve is called.
-func (s *Scope) _InsertLazy(name string, resolve func() Object) bool {
- if s.elems[name] != nil {
- return false
- }
- s.insert(name, &lazyObject{parent: s, resolve: resolve})
- return true
-}
-
-func (s *Scope) insert(name string, obj Object) {
- if s.elems == nil {
- s.elems = make(map[string]Object)
- }
- s.elems[name] = obj
-}
-
-// squash merges s with its parent scope p by adding all
-// objects of s to p, adding all children of s to the
-// children of p, and removing s from p's children.
-// The function f is called for each object obj in s which
-// has an object alt in p. s should be discarded after
-// having been squashed.
-func (s *Scope) squash(err func(obj, alt Object)) {
- p := s.parent
- assert(p != nil)
- for name, obj := range s.elems {
- obj = resolve(name, obj)
- obj.setParent(nil)
- if alt := p.Insert(obj); alt != nil {
- err(obj, alt)
- }
- }
-
- j := -1 // index of s in p.children
- for i, ch := range p.children {
- if ch == s {
- j = i
- break
- }
- }
- assert(j >= 0)
- k := len(p.children) - 1
- p.children[j] = p.children[k]
- p.children = p.children[:k]
-
- p.children = append(p.children, s.children...)
-
- s.children = nil
- s.elems = nil
-}
-
-// Pos and End describe the scope's source code extent [pos, end).
-// The results are guaranteed to be valid only if the type-checked
-// AST has complete position information. The extent is undefined
-// for Universe and package scopes.
-func (s *Scope) Pos() token.Pos { return s.pos }
-func (s *Scope) End() token.Pos { return s.end }
-
-// Contains reports whether pos is within the scope's extent.
-// The result is guaranteed to be valid only if the type-checked
-// AST has complete position information.
-func (s *Scope) Contains(pos token.Pos) bool {
- return s.pos <= pos && pos < s.end
-}
-
-// Innermost returns the innermost (child) scope containing
-// pos. If pos is not within any scope, the result is nil.
-// The result is also nil for the Universe scope.
-// The result is guaranteed to be valid only if the type-checked
-// AST has complete position information.
-func (s *Scope) Innermost(pos token.Pos) *Scope {
- // Package scopes do not have extents since they may be
- // discontiguous, so iterate over the package's files.
- if s.parent == Universe {
- for _, s := range s.children {
- if inner := s.Innermost(pos); inner != nil {
- return inner
- }
- }
- }
-
- if s.Contains(pos) {
- for _, s := range s.children {
- if s.Contains(pos) {
- return s.Innermost(pos)
- }
- }
- return s
- }
- return nil
-}
-
-// WriteTo writes a string representation of the scope to w,
-// with the scope elements sorted by name.
-// The level of indentation is controlled by n >= 0, with
-// n == 0 for no indentation.
-// If recurse is set, it also writes nested (children) scopes.
-func (s *Scope) WriteTo(w io.Writer, n int, recurse bool) {
- const ind = ". "
- indn := strings.Repeat(ind, n)
-
- fmt.Fprintf(w, "%s%s scope %p {\n", indn, s.comment, s)
-
- indn1 := indn + ind
- for _, name := range s.Names() {
- fmt.Fprintf(w, "%s%s\n", indn1, s.Lookup(name))
- }
-
- if recurse {
- for _, s := range s.children {
- s.WriteTo(w, n+1, recurse)
- }
- }
-
- fmt.Fprintf(w, "%s}\n", indn)
-}
-
-// String returns a string representation of the scope, for debugging.
-func (s *Scope) String() string {
- var buf strings.Builder
- s.WriteTo(&buf, 0, false)
- return buf.String()
-}
-
-// A lazyObject represents an imported Object that has not been fully
-// resolved yet by its importer.
-type lazyObject struct {
- parent *Scope
- resolve func() Object
- obj Object
- once sync.Once
-}
-
-// resolve returns the Object represented by obj, resolving lazy
-// objects as appropriate.
-func resolve(name string, obj Object) Object {
- if lazy, ok := obj.(*lazyObject); ok {
- lazy.once.Do(func() {
- obj := lazy.resolve()
-
- if _, ok := obj.(*lazyObject); ok {
- panic("recursive lazy object")
- }
- if obj.Name() != name {
- panic("lazy object has unexpected name")
- }
-
- if obj.Parent() == nil {
- obj.setParent(lazy.parent)
- }
- lazy.obj = obj
- })
-
- obj = lazy.obj
- }
- return obj
-}
-
-// stub implementations so *lazyObject implements Object and we can
-// store them directly into Scope.elems.
-func (*lazyObject) Parent() *Scope { panic("unreachable") }
-func (*lazyObject) Pos() token.Pos { panic("unreachable") }
-func (*lazyObject) Pkg() *Package { panic("unreachable") }
-func (*lazyObject) Name() string { panic("unreachable") }
-func (*lazyObject) Type() Type { panic("unreachable") }
-func (*lazyObject) Exported() bool { panic("unreachable") }
-func (*lazyObject) Id() string { panic("unreachable") }
-func (*lazyObject) String() string { panic("unreachable") }
-func (*lazyObject) order() uint32 { panic("unreachable") }
-func (*lazyObject) color() color { panic("unreachable") }
-func (*lazyObject) setType(Type) { panic("unreachable") }
-func (*lazyObject) setOrder(uint32) { panic("unreachable") }
-func (*lazyObject) setColor(color color) { panic("unreachable") }
-func (*lazyObject) setParent(*Scope) { panic("unreachable") }
-func (*lazyObject) sameId(pkg *Package, name string) bool { panic("unreachable") }
-func (*lazyObject) scopePos() token.Pos { panic("unreachable") }
-func (*lazyObject) setScopePos(pos token.Pos) { panic("unreachable") }
diff --git a/contrib/go/_std_1.20/src/go/types/selection.go b/contrib/go/_std_1.20/src/go/types/selection.go
deleted file mode 100644
index 09c304d378..0000000000
--- a/contrib/go/_std_1.20/src/go/types/selection.go
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements Selections.
-
-package types
-
-import (
- "bytes"
- "fmt"
-)
-
-// SelectionKind describes the kind of a selector expression x.f
-// (excluding qualified identifiers).
-type SelectionKind int
-
-const (
- FieldVal SelectionKind = iota // x.f is a struct field selector
- MethodVal // x.f is a method selector
- MethodExpr // x.f is a method expression
-)
-
-// A Selection describes a selector expression x.f.
-// For the declarations:
-//
-// type T struct{ x int; E }
-// type E struct{}
-// func (e E) m() {}
-// var p *T
-//
-// the following relations exist:
-//
-// Selector Kind Recv Obj Type Index Indirect
-//
-// p.x FieldVal T x int {0} true
-// p.m MethodVal *T m func() {1, 0} true
-// T.m MethodExpr T m func(T) {1, 0} false
-type Selection struct {
- kind SelectionKind
- recv Type // type of x
- obj Object // object denoted by x.f
- index []int // path from x to x.f
- indirect bool // set if there was any pointer indirection on the path
-}
-
-// Kind returns the selection kind.
-func (s *Selection) Kind() SelectionKind { return s.kind }
-
-// Recv returns the type of x in x.f.
-func (s *Selection) Recv() Type { return s.recv }
-
-// Obj returns the object denoted by x.f; a *Var for
-// a field selection, and a *Func in all other cases.
-func (s *Selection) Obj() Object { return s.obj }
-
-// Type returns the type of x.f, which may be different from the type of f.
-// See Selection for more information.
-func (s *Selection) Type() Type {
- switch s.kind {
- case MethodVal:
- // The type of x.f is a method with its receiver type set
- // to the type of x.
- sig := *s.obj.(*Func).typ.(*Signature)
- recv := *sig.recv
- recv.typ = s.recv
- sig.recv = &recv
- return &sig
-
- case MethodExpr:
- // The type of x.f is a function (without receiver)
- // and an additional first argument with the same type as x.
- // TODO(gri) Similar code is already in call.go - factor!
- // TODO(gri) Compute this eagerly to avoid allocations.
- sig := *s.obj.(*Func).typ.(*Signature)
- arg0 := *sig.recv
- sig.recv = nil
- arg0.typ = s.recv
- var params []*Var
- if sig.params != nil {
- params = sig.params.vars
- }
- sig.params = NewTuple(append([]*Var{&arg0}, params...)...)
- return &sig
- }
-
- // In all other cases, the type of x.f is the type of x.
- return s.obj.Type()
-}
-
-// Index describes the path from x to f in x.f.
-// The last index entry is the field or method index of the type declaring f;
-// either:
-//
-// 1. the list of declared methods of a named type; or
-// 2. the list of methods of an interface type; or
-// 3. the list of fields of a struct type.
-//
-// The earlier index entries are the indices of the embedded fields implicitly
-// traversed to get from (the type of) x to f, starting at embedding depth 0.
-func (s *Selection) Index() []int { return s.index }
-
-// Indirect reports whether any pointer indirection was required to get from
-// x to f in x.f.
-func (s *Selection) Indirect() bool { return s.indirect }
-
-func (s *Selection) String() string { return SelectionString(s, nil) }
-
-// SelectionString returns the string form of s.
-// The Qualifier controls the printing of
-// package-level objects, and may be nil.
-//
-// Examples:
-//
-// "field (T) f int"
-// "method (T) f(X) Y"
-// "method expr (T) f(X) Y"
-func SelectionString(s *Selection, qf Qualifier) string {
- var k string
- switch s.kind {
- case FieldVal:
- k = "field "
- case MethodVal:
- k = "method "
- case MethodExpr:
- k = "method expr "
- default:
- unreachable()
- }
- var buf bytes.Buffer
- buf.WriteString(k)
- buf.WriteByte('(')
- WriteType(&buf, s.Recv(), qf)
- fmt.Fprintf(&buf, ") %s", s.obj.Name())
- if T := s.Type(); s.kind == FieldVal {
- buf.WriteByte(' ')
- WriteType(&buf, T, qf)
- } else {
- WriteSignature(&buf, T.(*Signature), qf)
- }
- return buf.String()
-}
diff --git a/contrib/go/_std_1.20/src/go/types/signature.go b/contrib/go/_std_1.20/src/go/types/signature.go
deleted file mode 100644
index 83460eaf1f..0000000000
--- a/contrib/go/_std_1.20/src/go/types/signature.go
+++ /dev/null
@@ -1,321 +0,0 @@
-// 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 types
-
-import (
- "fmt"
- "go/ast"
- "go/token"
- . "internal/types/errors"
-)
-
-// ----------------------------------------------------------------------------
-// API
-
-// A Signature represents a (non-builtin) function or method type.
-// The receiver is ignored when comparing signatures for identity.
-type Signature struct {
- // We need to keep the scope in Signature (rather than passing it around
- // and store it in the Func Object) because when type-checking a function
- // literal we call the general type checker which returns a general Type.
- // We then unpack the *Signature and use the scope for the literal body.
- rparams *TypeParamList // receiver type parameters from left to right, or nil
- tparams *TypeParamList // type parameters from left to right, or nil
- scope *Scope // function scope for package-local and non-instantiated signatures; nil otherwise
- recv *Var // nil if not a method
- params *Tuple // (incoming) parameters from left to right; or nil
- results *Tuple // (outgoing) results from left to right; or nil
- variadic bool // true if the last parameter's type is of the form ...T (or string, for append built-in only)
-}
-
-// NewSignature returns a new function type for the given receiver, parameters,
-// and results, either of which may be nil. If variadic is set, the function
-// is variadic, it must have at least one parameter, and the last parameter
-// must be of unnamed slice type.
-//
-// Deprecated: Use NewSignatureType instead which allows for type parameters.
-func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature {
- return NewSignatureType(recv, nil, nil, params, results, variadic)
-}
-
-// NewSignatureType creates a new function type for the given receiver,
-// receiver type parameters, type parameters, parameters, and results. If
-// variadic is set, params must hold at least one parameter and the last
-// parameter's core type must be of unnamed slice or bytestring type.
-// If recv is non-nil, typeParams must be empty. If recvTypeParams is
-// non-empty, recv must be non-nil.
-func NewSignatureType(recv *Var, recvTypeParams, typeParams []*TypeParam, params, results *Tuple, variadic bool) *Signature {
- if variadic {
- n := params.Len()
- if n == 0 {
- panic("variadic function must have at least one parameter")
- }
- core := coreString(params.At(n - 1).typ)
- if _, ok := core.(*Slice); !ok && !isString(core) {
- panic(fmt.Sprintf("got %s, want variadic parameter with unnamed slice type or string as core type", core.String()))
- }
- }
- sig := &Signature{recv: recv, params: params, results: results, variadic: variadic}
- if len(recvTypeParams) != 0 {
- if recv == nil {
- panic("function with receiver type parameters must have a receiver")
- }
- sig.rparams = bindTParams(recvTypeParams)
- }
- if len(typeParams) != 0 {
- if recv != nil {
- panic("function with type parameters cannot have a receiver")
- }
- sig.tparams = bindTParams(typeParams)
- }
- return sig
-}
-
-// Recv returns the receiver of signature s (if a method), or nil if a
-// function. It is ignored when comparing signatures for identity.
-//
-// For an abstract method, Recv returns the enclosing interface either
-// as a *Named or an *Interface. Due to embedding, an interface may
-// contain methods whose receiver type is a different interface.
-func (s *Signature) Recv() *Var { return s.recv }
-
-// TypeParams returns the type parameters of signature s, or nil.
-func (s *Signature) TypeParams() *TypeParamList { return s.tparams }
-
-// RecvTypeParams returns the receiver type parameters of signature s, or nil.
-func (s *Signature) RecvTypeParams() *TypeParamList { return s.rparams }
-
-// Params returns the parameters of signature s, or nil.
-func (s *Signature) Params() *Tuple { return s.params }
-
-// Results returns the results of signature s, or nil.
-func (s *Signature) Results() *Tuple { return s.results }
-
-// Variadic reports whether the signature s is variadic.
-func (s *Signature) Variadic() bool { return s.variadic }
-
-func (t *Signature) Underlying() Type { return t }
-func (t *Signature) String() string { return TypeString(t, nil) }
-
-// ----------------------------------------------------------------------------
-// Implementation
-
-// funcType type-checks a function or method type.
-func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) {
- check.openScope(ftyp, "function")
- check.scope.isFunc = true
- check.recordScope(ftyp, check.scope)
- sig.scope = check.scope
- defer check.closeScope()
-
- if recvPar != nil && len(recvPar.List) > 0 {
- // collect generic receiver type parameters, if any
- // - a receiver type parameter is like any other type parameter, except that it is declared implicitly
- // - the receiver specification acts as local declaration for its type parameters, which may be blank
- _, rname, rparams := check.unpackRecv(recvPar.List[0].Type, true)
- if len(rparams) > 0 {
- tparams := check.declareTypeParams(nil, rparams)
- sig.rparams = bindTParams(tparams)
- // Blank identifiers don't get declared, so naive type-checking of the
- // receiver type expression would fail in Checker.collectParams below,
- // when Checker.ident cannot resolve the _ to a type.
- //
- // Checker.recvTParamMap maps these blank identifiers to their type parameter
- // types, so that they may be resolved in Checker.ident when they fail
- // lookup in the scope.
- for i, p := range rparams {
- if p.Name == "_" {
- if check.recvTParamMap == nil {
- check.recvTParamMap = make(map[*ast.Ident]*TypeParam)
- }
- check.recvTParamMap[p] = tparams[i]
- }
- }
- // determine receiver type to get its type parameters
- // and the respective type parameter bounds
- var recvTParams []*TypeParam
- if rname != nil {
- // recv should be a Named type (otherwise an error is reported elsewhere)
- // Also: Don't report an error via genericType since it will be reported
- // again when we type-check the signature.
- // TODO(gri) maybe the receiver should be marked as invalid instead?
- if recv, _ := check.genericType(rname, nil).(*Named); recv != nil {
- recvTParams = recv.TypeParams().list()
- }
- }
- // provide type parameter bounds
- if len(tparams) == len(recvTParams) {
- smap := makeRenameMap(recvTParams, tparams)
- for i, tpar := range tparams {
- recvTPar := recvTParams[i]
- check.mono.recordCanon(tpar, recvTPar)
- // recvTPar.bound is (possibly) parameterized in the context of the
- // receiver type declaration. Substitute parameters for the current
- // context.
- tpar.bound = check.subst(tpar.obj.pos, recvTPar.bound, smap, nil, check.context())
- }
- } else if len(tparams) < len(recvTParams) {
- // Reporting an error here is a stop-gap measure to avoid crashes in the
- // compiler when a type parameter/argument cannot be inferred later. It
- // may lead to follow-on errors (see issues #51339, #51343).
- // TODO(gri) find a better solution
- got := measure(len(tparams), "type parameter")
- check.errorf(recvPar, BadRecv, "got %s, but receiver base type declares %d", got, len(recvTParams))
- }
- }
- }
-
- if ftyp.TypeParams != nil {
- check.collectTypeParams(&sig.tparams, ftyp.TypeParams)
- // Always type-check method type parameters but complain that they are not allowed.
- // (A separate check is needed when type-checking interface method signatures because
- // they don't have a receiver specification.)
- if recvPar != nil {
- check.error(ftyp.TypeParams, InvalidMethodTypeParams, "methods cannot have type parameters")
- }
- }
-
- // Value (non-type) parameters' scope starts in the function body. Use a temporary scope for their
- // declarations and then squash that scope into the parent scope (and report any redeclarations at
- // that time).
- scope := NewScope(check.scope, token.NoPos, token.NoPos, "function body (temp. scope)")
- recvList, _ := check.collectParams(scope, recvPar, false)
- params, variadic := check.collectParams(scope, ftyp.Params, true)
- results, _ := check.collectParams(scope, ftyp.Results, false)
- scope.squash(func(obj, alt Object) {
- check.errorf(obj, DuplicateDecl, "%s redeclared in this block", obj.Name())
- check.reportAltDecl(alt)
- })
-
- if recvPar != nil {
- // recv parameter list present (may be empty)
- // spec: "The receiver is specified via an extra parameter section preceding the
- // method name. That parameter section must declare a single parameter, the receiver."
- var recv *Var
- switch len(recvList) {
- case 0:
- // error reported by resolver
- recv = NewParam(token.NoPos, nil, "", Typ[Invalid]) // ignore recv below
- default:
- // more than one receiver
- check.error(recvList[len(recvList)-1], InvalidRecv, "method has multiple receivers")
- fallthrough // continue with first receiver
- case 1:
- recv = recvList[0]
- }
- sig.recv = recv
-
- // Delay validation of receiver type as it may cause premature expansion
- // of types the receiver type is dependent on (see issues #51232, #51233).
- check.later(func() {
- // spec: "The receiver type must be of the form T or *T where T is a type name."
- rtyp, _ := deref(recv.typ)
- if rtyp == Typ[Invalid] {
- return // error was reported before
- }
- // spec: "The type denoted by T is called the receiver base type; it must not
- // be a pointer or interface type and it must be declared in the same package
- // as the method."
- switch T := rtyp.(type) {
- case *Named:
- // The receiver type may be an instantiated type referred to
- // by an alias (which cannot have receiver parameters for now).
- if T.TypeArgs() != nil && sig.RecvTypeParams() == nil {
- check.errorf(recv, InvalidRecv, "cannot define new methods on instantiated type %s", rtyp)
- break
- }
- if T.obj.pkg != check.pkg {
- check.errorf(recv, InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
- break
- }
- var cause string
- switch u := T.under().(type) {
- case *Basic:
- // unsafe.Pointer is treated like a regular pointer
- if u.kind == UnsafePointer {
- cause = "unsafe.Pointer"
- }
- case *Pointer, *Interface:
- cause = "pointer or interface type"
- case *TypeParam:
- // The underlying type of a receiver base type cannot be a
- // type parameter: "type T[P any] P" is not a valid declaration.
- unreachable()
- }
- if cause != "" {
- check.errorf(recv, InvalidRecv, "invalid receiver type %s (%s)", rtyp, cause)
- }
- case *Basic:
- check.errorf(recv, InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
- default:
- check.errorf(recv, InvalidRecv, "invalid receiver type %s", recv.typ)
- }
- }).describef(recv, "validate receiver %s", recv)
- }
-
- sig.params = NewTuple(params...)
- sig.results = NewTuple(results...)
- sig.variadic = variadic
-}
-
-// collectParams declares the parameters of list in scope and returns the corresponding
-// variable list.
-func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, variadic bool) {
- if list == nil {
- return
- }
-
- var named, anonymous bool
- for i, field := range list.List {
- ftype := field.Type
- if t, _ := ftype.(*ast.Ellipsis); t != nil {
- ftype = t.Elt
- if variadicOk && i == len(list.List)-1 && len(field.Names) <= 1 {
- variadic = true
- } else {
- check.softErrorf(t, MisplacedDotDotDot, "can only use ... with final parameter in list")
- // ignore ... and continue
- }
- }
- typ := check.varType(ftype)
- // The parser ensures that f.Tag is nil and we don't
- // care if a constructed AST contains a non-nil tag.
- if len(field.Names) > 0 {
- // named parameter
- for _, name := range field.Names {
- if name.Name == "" {
- check.error(name, InvalidSyntaxTree, "anonymous parameter")
- // ok to continue
- }
- par := NewParam(name.Pos(), check.pkg, name.Name, typ)
- check.declare(scope, name, par, scope.pos)
- params = append(params, par)
- }
- named = true
- } else {
- // anonymous parameter
- par := NewParam(ftype.Pos(), check.pkg, "", typ)
- check.recordImplicit(field, par)
- params = append(params, par)
- anonymous = true
- }
- }
-
- if named && anonymous {
- check.error(list, InvalidSyntaxTree, "list contains both named and anonymous parameters")
- // ok to continue
- }
-
- // For a variadic function, change the last parameter's type from T to []T.
- // Since we type-checked T rather than ...T, we also need to retro-actively
- // record the type for ...T.
- if variadic {
- last := params[len(params)-1]
- last.typ = &Slice{elem: last.typ}
- check.recordTypeAndValue(list.List[len(list.List)-1].Type, typexpr, last.typ, nil)
- }
-
- return
-}
diff --git a/contrib/go/_std_1.20/src/go/types/sizes.go b/contrib/go/_std_1.20/src/go/types/sizes.go
deleted file mode 100644
index cb5253b453..0000000000
--- a/contrib/go/_std_1.20/src/go/types/sizes.go
+++ /dev/null
@@ -1,296 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements Sizes.
-
-package types
-
-// Sizes defines the sizing functions for package unsafe.
-type Sizes interface {
- // Alignof returns the alignment of a variable of type T.
- // Alignof must implement the alignment guarantees required by the spec.
- Alignof(T Type) int64
-
- // Offsetsof returns the offsets of the given struct fields, in bytes.
- // Offsetsof must implement the offset guarantees required by the spec.
- Offsetsof(fields []*Var) []int64
-
- // Sizeof returns the size of a variable of type T.
- // Sizeof must implement the size guarantees required by the spec.
- Sizeof(T Type) int64
-}
-
-// StdSizes is a convenience type for creating commonly used Sizes.
-// It makes the following simplifying assumptions:
-//
-// - The size of explicitly sized basic types (int16, etc.) is the
-// specified size.
-// - The size of strings and interfaces is 2*WordSize.
-// - The size of slices is 3*WordSize.
-// - The size of an array of n elements corresponds to the size of
-// a struct of n consecutive fields of the array's element type.
-// - The size of a struct is the offset of the last field plus that
-// field's size. As with all element types, if the struct is used
-// in an array its size must first be aligned to a multiple of the
-// struct's alignment.
-// - All other types have size WordSize.
-// - Arrays and structs are aligned per spec definition; all other
-// types are naturally aligned with a maximum alignment MaxAlign.
-//
-// *StdSizes implements Sizes.
-type StdSizes struct {
- WordSize int64 // word size in bytes - must be >= 4 (32bits)
- MaxAlign int64 // maximum alignment in bytes - must be >= 1
-}
-
-func (s *StdSizes) Alignof(T Type) int64 {
- // For arrays and structs, alignment is defined in terms
- // of alignment of the elements and fields, respectively.
- switch t := under(T).(type) {
- case *Array:
- // spec: "For a variable x of array type: unsafe.Alignof(x)
- // is the same as unsafe.Alignof(x[0]), but at least 1."
- return s.Alignof(t.elem)
- case *Struct:
- if len(t.fields) == 0 && isSyncAtomicAlign64(T) {
- // Special case: sync/atomic.align64 is an
- // empty struct we recognize as a signal that
- // the struct it contains must be
- // 64-bit-aligned.
- //
- // This logic is equivalent to the logic in
- // cmd/compile/internal/types/size.go:calcStructOffset
- return 8
- }
-
- // spec: "For a variable x of struct type: unsafe.Alignof(x)
- // is the largest of the values unsafe.Alignof(x.f) for each
- // field f of x, but at least 1."
- max := int64(1)
- for _, f := range t.fields {
- if a := s.Alignof(f.typ); a > max {
- max = a
- }
- }
- return max
- case *Slice, *Interface:
- // Multiword data structures are effectively structs
- // in which each element has size WordSize.
- // Type parameters lead to variable sizes/alignments;
- // StdSizes.Alignof won't be called for them.
- assert(!isTypeParam(T))
- return s.WordSize
- case *Basic:
- // Strings are like slices and interfaces.
- if t.Info()&IsString != 0 {
- return s.WordSize
- }
- case *TypeParam, *Union:
- unreachable()
- }
- a := s.Sizeof(T) // may be 0
- // spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
- if a < 1 {
- return 1
- }
- // complex{64,128} are aligned like [2]float{32,64}.
- if isComplex(T) {
- a /= 2
- }
- if a > s.MaxAlign {
- return s.MaxAlign
- }
- return a
-}
-
-func isSyncAtomicAlign64(T Type) bool {
- named, ok := T.(*Named)
- if !ok {
- return false
- }
- obj := named.Obj()
- return obj.Name() == "align64" &&
- obj.Pkg() != nil &&
- (obj.Pkg().Path() == "sync/atomic" ||
- obj.Pkg().Path() == "runtime/internal/atomic")
-}
-
-func (s *StdSizes) Offsetsof(fields []*Var) []int64 {
- offsets := make([]int64, len(fields))
- var o int64
- for i, f := range fields {
- a := s.Alignof(f.typ)
- o = align(o, a)
- offsets[i] = o
- o += s.Sizeof(f.typ)
- }
- return offsets
-}
-
-var basicSizes = [...]byte{
- Bool: 1,
- Int8: 1,
- Int16: 2,
- Int32: 4,
- Int64: 8,
- Uint8: 1,
- Uint16: 2,
- Uint32: 4,
- Uint64: 8,
- Float32: 4,
- Float64: 8,
- Complex64: 8,
- Complex128: 16,
-}
-
-func (s *StdSizes) Sizeof(T Type) int64 {
- switch t := under(T).(type) {
- case *Basic:
- assert(isTyped(T))
- k := t.kind
- if int(k) < len(basicSizes) {
- if s := basicSizes[k]; s > 0 {
- return int64(s)
- }
- }
- if k == String {
- return s.WordSize * 2
- }
- case *Array:
- n := t.len
- if n <= 0 {
- return 0
- }
- // n > 0
- a := s.Alignof(t.elem)
- z := s.Sizeof(t.elem)
- return align(z, a)*(n-1) + z
- case *Slice:
- return s.WordSize * 3
- case *Struct:
- n := t.NumFields()
- if n == 0 {
- return 0
- }
- offsets := s.Offsetsof(t.fields)
- return offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
- case *Interface:
- // Type parameters lead to variable sizes/alignments;
- // StdSizes.Sizeof won't be called for them.
- assert(!isTypeParam(T))
- return s.WordSize * 2
- case *TypeParam, *Union:
- unreachable()
- }
- return s.WordSize // catch-all
-}
-
-// common architecture word sizes and alignments
-var gcArchSizes = map[string]*StdSizes{
- "386": {4, 4},
- "amd64": {8, 8},
- "amd64p32": {4, 8},
- "arm": {4, 4},
- "arm64": {8, 8},
- "loong64": {8, 8},
- "mips": {4, 4},
- "mipsle": {4, 4},
- "mips64": {8, 8},
- "mips64le": {8, 8},
- "ppc64": {8, 8},
- "ppc64le": {8, 8},
- "riscv64": {8, 8},
- "s390x": {8, 8},
- "sparc64": {8, 8},
- "wasm": {8, 8},
- // When adding more architectures here,
- // update the doc string of SizesFor below.
-}
-
-// SizesFor returns the Sizes used by a compiler for an architecture.
-// The result is nil if a compiler/architecture pair is not known.
-//
-// Supported architectures for compiler "gc":
-// "386", "amd64", "amd64p32", "arm", "arm64", "loong64", "mips", "mipsle",
-// "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x", "sparc64", "wasm".
-func SizesFor(compiler, arch string) Sizes {
- var m map[string]*StdSizes
- switch compiler {
- case "gc":
- m = gcArchSizes
- case "gccgo":
- m = gccgoArchSizes
- default:
- return nil
- }
- s, ok := m[arch]
- if !ok {
- return nil
- }
- return s
-}
-
-// stdSizes is used if Config.Sizes == nil.
-var stdSizes = SizesFor("gc", "amd64")
-
-func (conf *Config) alignof(T Type) int64 {
- if s := conf.Sizes; s != nil {
- if a := s.Alignof(T); a >= 1 {
- return a
- }
- panic("Config.Sizes.Alignof returned an alignment < 1")
- }
- return stdSizes.Alignof(T)
-}
-
-func (conf *Config) offsetsof(T *Struct) []int64 {
- var offsets []int64
- if T.NumFields() > 0 {
- // compute offsets on demand
- if s := conf.Sizes; s != nil {
- offsets = s.Offsetsof(T.fields)
- // sanity checks
- if len(offsets) != T.NumFields() {
- panic("Config.Sizes.Offsetsof returned the wrong number of offsets")
- }
- for _, o := range offsets {
- if o < 0 {
- panic("Config.Sizes.Offsetsof returned an offset < 0")
- }
- }
- } else {
- offsets = stdSizes.Offsetsof(T.fields)
- }
- }
- return offsets
-}
-
-// offsetof returns the offset of the field specified via
-// the index sequence relative to typ. All embedded fields
-// must be structs (rather than pointer to structs).
-func (conf *Config) offsetof(typ Type, index []int) int64 {
- var o int64
- for _, i := range index {
- s := under(typ).(*Struct)
- o += conf.offsetsof(s)[i]
- typ = s.fields[i].typ
- }
- return o
-}
-
-func (conf *Config) sizeof(T Type) int64 {
- if s := conf.Sizes; s != nil {
- if z := s.Sizeof(T); z >= 0 {
- return z
- }
- panic("Config.Sizes.Sizeof returned a size < 0")
- }
- return stdSizes.Sizeof(T)
-}
-
-// align returns the smallest y >= x such that y % a == 0.
-func align(x, a int64) int64 {
- y := x + a - 1
- return y - y%a
-}
diff --git a/contrib/go/_std_1.20/src/go/types/slice.go b/contrib/go/_std_1.20/src/go/types/slice.go
deleted file mode 100644
index debdd81586..0000000000
--- a/contrib/go/_std_1.20/src/go/types/slice.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2011 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 types
-
-// A Slice represents a slice type.
-type Slice struct {
- elem Type
-}
-
-// NewSlice returns a new slice type for the given element type.
-func NewSlice(elem Type) *Slice { return &Slice{elem: elem} }
-
-// Elem returns the element type of slice s.
-func (s *Slice) Elem() Type { return s.elem }
-
-func (t *Slice) Underlying() Type { return t }
-func (t *Slice) String() string { return TypeString(t, nil) }
diff --git a/contrib/go/_std_1.20/src/go/types/stmt.go b/contrib/go/_std_1.20/src/go/types/stmt.go
deleted file mode 100644
index ac6255d42a..0000000000
--- a/contrib/go/_std_1.20/src/go/types/stmt.go
+++ /dev/null
@@ -1,962 +0,0 @@
-// Copyright 2012 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.
-
-// This file implements typechecking of statements.
-
-package types
-
-import (
- "go/ast"
- "go/constant"
- "go/token"
- . "internal/types/errors"
- "sort"
-)
-
-func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body *ast.BlockStmt, iota constant.Value) {
- if check.conf.IgnoreFuncBodies {
- panic("function body not ignored")
- }
-
- if trace {
- check.trace(body.Pos(), "-- %s: %s", name, sig)
- }
-
- // set function scope extent
- sig.scope.pos = body.Pos()
- sig.scope.end = body.End()
-
- // save/restore current environment and set up function environment
- // (and use 0 indentation at function start)
- defer func(env environment, indent int) {
- check.environment = env
- check.indent = indent
- }(check.environment, check.indent)
- check.environment = environment{
- decl: decl,
- scope: sig.scope,
- iota: iota,
- sig: sig,
- }
- check.indent = 0
-
- check.stmtList(0, body.List)
-
- if check.hasLabel {
- check.labels(body)
- }
-
- if sig.results.Len() > 0 && !check.isTerminating(body, "") {
- check.error(atPos(body.Rbrace), MissingReturn, "missing return")
- }
-
- // spec: "Implementation restriction: A compiler may make it illegal to
- // declare a variable inside a function body if the variable is never used."
- check.usage(sig.scope)
-}
-
-func (check *Checker) usage(scope *Scope) {
- var unused []*Var
- for name, elem := range scope.elems {
- elem = resolve(name, elem)
- if v, _ := elem.(*Var); v != nil && !v.used {
- unused = append(unused, v)
- }
- }
- sort.Slice(unused, func(i, j int) bool {
- return unused[i].pos < unused[j].pos
- })
- for _, v := range unused {
- check.softErrorf(v, UnusedVar, "%s declared and not used", v.name)
- }
-
- for _, scope := range scope.children {
- // Don't go inside function literal scopes a second time;
- // they are handled explicitly by funcBody.
- if !scope.isFunc {
- check.usage(scope)
- }
- }
-}
-
-// stmtContext is a bitset describing which
-// control-flow statements are permissible,
-// and provides additional context information
-// for better error messages.
-type stmtContext uint
-
-const (
- // permissible control-flow statements
- breakOk stmtContext = 1 << iota
- continueOk
- fallthroughOk
-
- // additional context information
- finalSwitchCase
- inTypeSwitch
-)
-
-func (check *Checker) simpleStmt(s ast.Stmt) {
- if s != nil {
- check.stmt(0, s)
- }
-}
-
-func trimTrailingEmptyStmts(list []ast.Stmt) []ast.Stmt {
- for i := len(list); i > 0; i-- {
- if _, ok := list[i-1].(*ast.EmptyStmt); !ok {
- return list[:i]
- }
- }
- return nil
-}
-
-func (check *Checker) stmtList(ctxt stmtContext, list []ast.Stmt) {
- ok := ctxt&fallthroughOk != 0
- inner := ctxt &^ fallthroughOk
- list = trimTrailingEmptyStmts(list) // trailing empty statements are "invisible" to fallthrough analysis
- for i, s := range list {
- inner := inner
- if ok && i+1 == len(list) {
- inner |= fallthroughOk
- }
- check.stmt(inner, s)
- }
-}
-
-func (check *Checker) multipleDefaults(list []ast.Stmt) {
- var first ast.Stmt
- for _, s := range list {
- var d ast.Stmt
- switch c := s.(type) {
- case *ast.CaseClause:
- if len(c.List) == 0 {
- d = s
- }
- case *ast.CommClause:
- if c.Comm == nil {
- d = s
- }
- default:
- check.error(s, InvalidSyntaxTree, "case/communication clause expected")
- }
- if d != nil {
- if first != nil {
- check.errorf(d, DuplicateDefault, "multiple defaults (first at %s)", check.fset.Position(first.Pos()))
- } else {
- first = d
- }
- }
- }
-}
-
-func (check *Checker) openScope(node ast.Node, comment string) {
- scope := NewScope(check.scope, node.Pos(), node.End(), comment)
- check.recordScope(node, scope)
- check.scope = scope
-}
-
-func (check *Checker) closeScope() {
- check.scope = check.scope.Parent()
-}
-
-func assignOp(op token.Token) token.Token {
- // token_test.go verifies the token ordering this function relies on
- if token.ADD_ASSIGN <= op && op <= token.AND_NOT_ASSIGN {
- return op + (token.ADD - token.ADD_ASSIGN)
- }
- return token.ILLEGAL
-}
-
-func (check *Checker) suspendedCall(keyword string, call *ast.CallExpr) {
- var x operand
- var msg string
- var code Code
- switch check.rawExpr(&x, call, nil, false) {
- case conversion:
- msg = "requires function call, not conversion"
- code = InvalidDefer
- if keyword == "go" {
- code = InvalidGo
- }
- case expression:
- msg = "discards result of"
- code = UnusedResults
- case statement:
- return
- default:
- unreachable()
- }
- check.errorf(&x, code, "%s %s %s", keyword, msg, &x)
-}
-
-// goVal returns the Go value for val, or nil.
-func goVal(val constant.Value) any {
- // val should exist, but be conservative and check
- if val == nil {
- return nil
- }
- // Match implementation restriction of other compilers.
- // gc only checks duplicates for integer, floating-point
- // and string values, so only create Go values for these
- // types.
- switch val.Kind() {
- case constant.Int:
- if x, ok := constant.Int64Val(val); ok {
- return x
- }
- if x, ok := constant.Uint64Val(val); ok {
- return x
- }
- case constant.Float:
- if x, ok := constant.Float64Val(val); ok {
- return x
- }
- case constant.String:
- return constant.StringVal(val)
- }
- return nil
-}
-
-// A valueMap maps a case value (of a basic Go type) to a list of positions
-// where the same case value appeared, together with the corresponding case
-// types.
-// Since two case values may have the same "underlying" value but different
-// types we need to also check the value's types (e.g., byte(1) vs myByte(1))
-// when the switch expression is of interface type.
-type (
- valueMap map[any][]valueType // underlying Go value -> valueType
- valueType struct {
- pos token.Pos
- typ Type
- }
-)
-
-func (check *Checker) caseValues(x *operand, values []ast.Expr, seen valueMap) {
-L:
- for _, e := range values {
- var v operand
- check.expr(&v, e)
- if x.mode == invalid || v.mode == invalid {
- continue L
- }
- check.convertUntyped(&v, x.typ)
- if v.mode == invalid {
- continue L
- }
- // Order matters: By comparing v against x, error positions are at the case values.
- res := v // keep original v unchanged
- check.comparison(&res, x, token.EQL, true)
- if res.mode == invalid {
- continue L
- }
- if v.mode != constant_ {
- continue L // we're done
- }
- // look for duplicate values
- if val := goVal(v.val); val != nil {
- // look for duplicate types for a given value
- // (quadratic algorithm, but these lists tend to be very short)
- for _, vt := range seen[val] {
- if Identical(v.typ, vt.typ) {
- check.errorf(&v, DuplicateCase, "duplicate case %s in expression switch", &v)
- check.error(atPos(vt.pos), DuplicateCase, "\tprevious case") // secondary error, \t indented
- continue L
- }
- }
- seen[val] = append(seen[val], valueType{v.Pos(), v.typ})
- }
- }
-}
-
-// isNil reports whether the expression e denotes the predeclared value nil.
-func (check *Checker) isNil(e ast.Expr) bool {
- // The only way to express the nil value is by literally writing nil (possibly in parentheses).
- if name, _ := unparen(e).(*ast.Ident); name != nil {
- _, ok := check.lookup(name.Name).(*Nil)
- return ok
- }
- return false
-}
-
-// If the type switch expression is invalid, x is nil.
-func (check *Checker) caseTypes(x *operand, types []ast.Expr, seen map[Type]ast.Expr) (T Type) {
- var dummy operand
-L:
- for _, e := range types {
- // The spec allows the value nil instead of a type.
- if check.isNil(e) {
- T = nil
- check.expr(&dummy, e) // run e through expr so we get the usual Info recordings
- } else {
- T = check.varType(e)
- if T == Typ[Invalid] {
- continue L
- }
- }
- // look for duplicate types
- // (quadratic algorithm, but type switches tend to be reasonably small)
- for t, other := range seen {
- if T == nil && t == nil || T != nil && t != nil && Identical(T, t) {
- // talk about "case" rather than "type" because of nil case
- Ts := "nil"
- if T != nil {
- Ts = TypeString(T, check.qualifier)
- }
- check.errorf(e, DuplicateCase, "duplicate case %s in type switch", Ts)
- check.error(other, DuplicateCase, "\tprevious case") // secondary error, \t indented
- continue L
- }
- }
- seen[T] = e
- if x != nil && T != nil {
- check.typeAssertion(e, x, T, true)
- }
- }
- return
-}
-
-// TODO(gri) Once we are certain that typeHash is correct in all situations, use this version of caseTypes instead.
-// (Currently it may be possible that different types have identical names and import paths due to ImporterFrom.)
-//
-// func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []ast.Expr, seen map[string]ast.Expr) (T Type) {
-// var dummy operand
-// L:
-// for _, e := range types {
-// // The spec allows the value nil instead of a type.
-// var hash string
-// if check.isNil(e) {
-// check.expr(&dummy, e) // run e through expr so we get the usual Info recordings
-// T = nil
-// hash = "<nil>" // avoid collision with a type named nil
-// } else {
-// T = check.varType(e)
-// if T == Typ[Invalid] {
-// continue L
-// }
-// hash = typeHash(T, nil)
-// }
-// // look for duplicate types
-// if other := seen[hash]; other != nil {
-// // talk about "case" rather than "type" because of nil case
-// Ts := "nil"
-// if T != nil {
-// Ts = TypeString(T, check.qualifier)
-// }
-// var err error_
-// err.code = DuplicateCase
-// err.errorf(e, "duplicate case %s in type switch", Ts)
-// err.errorf(other, "previous case")
-// check.report(&err)
-// continue L
-// }
-// seen[hash] = e
-// if T != nil {
-// check.typeAssertion(e.Pos(), x, xtyp, T)
-// }
-// }
-// return
-// }
-
-// stmt typechecks statement s.
-func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
- // statements must end with the same top scope as they started with
- if debug {
- defer func(scope *Scope) {
- // don't check if code is panicking
- if p := recover(); p != nil {
- panic(p)
- }
- assert(scope == check.scope)
- }(check.scope)
- }
-
- // process collected function literals before scope changes
- defer check.processDelayed(len(check.delayed))
-
- // reset context for statements of inner blocks
- inner := ctxt &^ (fallthroughOk | finalSwitchCase | inTypeSwitch)
-
- switch s := s.(type) {
- case *ast.BadStmt, *ast.EmptyStmt:
- // ignore
-
- case *ast.DeclStmt:
- check.declStmt(s.Decl)
-
- case *ast.LabeledStmt:
- check.hasLabel = true
- check.stmt(ctxt, s.Stmt)
-
- case *ast.ExprStmt:
- // spec: "With the exception of specific built-in functions,
- // function and method calls and receive operations can appear
- // in statement context. Such statements may be parenthesized."
- var x operand
- kind := check.rawExpr(&x, s.X, nil, false)
- var msg string
- var code Code
- switch x.mode {
- default:
- if kind == statement {
- return
- }
- msg = "is not used"
- code = UnusedExpr
- case builtin:
- msg = "must be called"
- code = UncalledBuiltin
- case typexpr:
- msg = "is not an expression"
- code = NotAnExpr
- }
- check.errorf(&x, code, "%s %s", &x, msg)
-
- case *ast.SendStmt:
- var ch, val operand
- check.expr(&ch, s.Chan)
- check.expr(&val, s.Value)
- if ch.mode == invalid || val.mode == invalid {
- return
- }
- u := coreType(ch.typ)
- if u == nil {
- check.errorf(inNode(s, s.Arrow), InvalidSend, invalidOp+"cannot send to %s: no core type", &ch)
- return
- }
- uch, _ := u.(*Chan)
- if uch == nil {
- check.errorf(inNode(s, s.Arrow), InvalidSend, invalidOp+"cannot send to non-channel %s", &ch)
- return
- }
- if uch.dir == RecvOnly {
- check.errorf(inNode(s, s.Arrow), InvalidSend, invalidOp+"cannot send to receive-only channel %s", &ch)
- return
- }
- check.assignment(&val, uch.elem, "send")
-
- case *ast.IncDecStmt:
- var op token.Token
- switch s.Tok {
- case token.INC:
- op = token.ADD
- case token.DEC:
- op = token.SUB
- default:
- check.errorf(inNode(s, s.TokPos), InvalidSyntaxTree, "unknown inc/dec operation %s", s.Tok)
- return
- }
-
- var x operand
- check.expr(&x, s.X)
- if x.mode == invalid {
- return
- }
- if !allNumeric(x.typ) {
- check.errorf(s.X, NonNumericIncDec, invalidOp+"%s%s (non-numeric type %s)", s.X, s.Tok, x.typ)
- return
- }
-
- Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position
- check.binary(&x, nil, s.X, Y, op, s.TokPos)
- if x.mode == invalid {
- return
- }
- check.assignVar(s.X, &x)
-
- case *ast.AssignStmt:
- switch s.Tok {
- case token.ASSIGN, token.DEFINE:
- if len(s.Lhs) == 0 {
- check.error(s, InvalidSyntaxTree, "missing lhs in assignment")
- return
- }
- if s.Tok == token.DEFINE {
- check.shortVarDecl(inNode(s, s.TokPos), s.Lhs, s.Rhs)
- } else {
- // regular assignment
- check.assignVars(s.Lhs, s.Rhs)
- }
-
- default:
- // assignment operations
- if len(s.Lhs) != 1 || len(s.Rhs) != 1 {
- check.errorf(inNode(s, s.TokPos), MultiValAssignOp, "assignment operation %s requires single-valued expressions", s.Tok)
- return
- }
- op := assignOp(s.Tok)
- if op == token.ILLEGAL {
- check.errorf(atPos(s.TokPos), InvalidSyntaxTree, "unknown assignment operation %s", s.Tok)
- return
- }
- var x operand
- check.binary(&x, nil, s.Lhs[0], s.Rhs[0], op, s.TokPos)
- if x.mode == invalid {
- return
- }
- check.assignVar(s.Lhs[0], &x)
- }
-
- case *ast.GoStmt:
- check.suspendedCall("go", s.Call)
-
- case *ast.DeferStmt:
- check.suspendedCall("defer", s.Call)
-
- case *ast.ReturnStmt:
- res := check.sig.results
- // Return with implicit results allowed for function with named results.
- // (If one is named, all are named.)
- if len(s.Results) == 0 && res.Len() > 0 && res.vars[0].name != "" {
- // spec: "Implementation restriction: A compiler may disallow an empty expression
- // list in a "return" statement if a different entity (constant, type, or variable)
- // with the same name as a result parameter is in scope at the place of the return."
- for _, obj := range res.vars {
- if alt := check.lookup(obj.name); alt != nil && alt != obj {
- check.errorf(s, OutOfScopeResult, "result parameter %s not in scope at return", obj.name)
- check.errorf(alt, OutOfScopeResult, "\tinner declaration of %s", obj)
- // ok to continue
- }
- }
- } else {
- var lhs []*Var
- if res.Len() > 0 {
- lhs = res.vars
- }
- check.initVars(lhs, s.Results, s)
- }
-
- case *ast.BranchStmt:
- if s.Label != nil {
- check.hasLabel = true
- return // checked in 2nd pass (check.labels)
- }
- switch s.Tok {
- case token.BREAK:
- if ctxt&breakOk == 0 {
- check.error(s, MisplacedBreak, "break not in for, switch, or select statement")
- }
- case token.CONTINUE:
- if ctxt&continueOk == 0 {
- check.error(s, MisplacedContinue, "continue not in for statement")
- }
- case token.FALLTHROUGH:
- if ctxt&fallthroughOk == 0 {
- var msg string
- switch {
- case ctxt&finalSwitchCase != 0:
- msg = "cannot fallthrough final case in switch"
- case ctxt&inTypeSwitch != 0:
- msg = "cannot fallthrough in type switch"
- default:
- msg = "fallthrough statement out of place"
- }
- check.error(s, MisplacedFallthrough, msg)
- }
- default:
- check.errorf(s, InvalidSyntaxTree, "branch statement: %s", s.Tok)
- }
-
- case *ast.BlockStmt:
- check.openScope(s, "block")
- defer check.closeScope()
-
- check.stmtList(inner, s.List)
-
- case *ast.IfStmt:
- check.openScope(s, "if")
- defer check.closeScope()
-
- check.simpleStmt(s.Init)
- var x operand
- check.expr(&x, s.Cond)
- if x.mode != invalid && !allBoolean(x.typ) {
- check.error(s.Cond, InvalidCond, "non-boolean condition in if statement")
- }
- check.stmt(inner, s.Body)
- // The parser produces a correct AST but if it was modified
- // elsewhere the else branch may be invalid. Check again.
- switch s.Else.(type) {
- case nil, *ast.BadStmt:
- // valid or error already reported
- case *ast.IfStmt, *ast.BlockStmt:
- check.stmt(inner, s.Else)
- default:
- check.error(s.Else, InvalidSyntaxTree, "invalid else branch in if statement")
- }
-
- case *ast.SwitchStmt:
- inner |= breakOk
- check.openScope(s, "switch")
- defer check.closeScope()
-
- check.simpleStmt(s.Init)
- var x operand
- if s.Tag != nil {
- check.expr(&x, s.Tag)
- // By checking assignment of x to an invisible temporary
- // (as a compiler would), we get all the relevant checks.
- check.assignment(&x, nil, "switch expression")
- if x.mode != invalid && !Comparable(x.typ) && !hasNil(x.typ) {
- check.errorf(&x, InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ)
- x.mode = invalid
- }
- } else {
- // spec: "A missing switch expression is
- // equivalent to the boolean value true."
- x.mode = constant_
- x.typ = Typ[Bool]
- x.val = constant.MakeBool(true)
- x.expr = &ast.Ident{NamePos: s.Body.Lbrace, Name: "true"}
- }
-
- check.multipleDefaults(s.Body.List)
-
- seen := make(valueMap) // map of seen case values to positions and types
- for i, c := range s.Body.List {
- clause, _ := c.(*ast.CaseClause)
- if clause == nil {
- check.error(c, InvalidSyntaxTree, "incorrect expression switch case")
- continue
- }
- check.caseValues(&x, clause.List, seen)
- check.openScope(clause, "case")
- inner := inner
- if i+1 < len(s.Body.List) {
- inner |= fallthroughOk
- } else {
- inner |= finalSwitchCase
- }
- check.stmtList(inner, clause.Body)
- check.closeScope()
- }
-
- case *ast.TypeSwitchStmt:
- inner |= breakOk | inTypeSwitch
- check.openScope(s, "type switch")
- defer check.closeScope()
-
- check.simpleStmt(s.Init)
-
- // A type switch guard must be of the form:
- //
- // TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
- //
- // The parser is checking syntactic correctness;
- // remaining syntactic errors are considered AST errors here.
- // TODO(gri) better factoring of error handling (invalid ASTs)
- //
- var lhs *ast.Ident // lhs identifier or nil
- var rhs ast.Expr
- switch guard := s.Assign.(type) {
- case *ast.ExprStmt:
- rhs = guard.X
- case *ast.AssignStmt:
- if len(guard.Lhs) != 1 || guard.Tok != token.DEFINE || len(guard.Rhs) != 1 {
- check.error(s, InvalidSyntaxTree, "incorrect form of type switch guard")
- return
- }
-
- lhs, _ = guard.Lhs[0].(*ast.Ident)
- if lhs == nil {
- check.error(s, InvalidSyntaxTree, "incorrect form of type switch guard")
- return
- }
-
- if lhs.Name == "_" {
- // _ := x.(type) is an invalid short variable declaration
- check.softErrorf(lhs, NoNewVar, "no new variable on left side of :=")
- lhs = nil // avoid declared and not used error below
- } else {
- check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause
- }
-
- rhs = guard.Rhs[0]
-
- default:
- check.error(s, InvalidSyntaxTree, "incorrect form of type switch guard")
- return
- }
-
- // rhs must be of the form: expr.(type) and expr must be an ordinary interface
- expr, _ := rhs.(*ast.TypeAssertExpr)
- if expr == nil || expr.Type != nil {
- check.error(s, InvalidSyntaxTree, "incorrect form of type switch guard")
- return
- }
- var x operand
- check.expr(&x, expr.X)
- if x.mode == invalid {
- return
- }
- // TODO(gri) we may want to permit type switches on type parameter values at some point
- var sx *operand // switch expression against which cases are compared against; nil if invalid
- if isTypeParam(x.typ) {
- check.errorf(&x, InvalidTypeSwitch, "cannot use type switch on type parameter value %s", &x)
- } else {
- if _, ok := under(x.typ).(*Interface); ok {
- sx = &x
- } else {
- check.errorf(&x, InvalidTypeSwitch, "%s is not an interface", &x)
- }
- }
-
- check.multipleDefaults(s.Body.List)
-
- var lhsVars []*Var // list of implicitly declared lhs variables
- seen := make(map[Type]ast.Expr) // map of seen types to positions
- for _, s := range s.Body.List {
- clause, _ := s.(*ast.CaseClause)
- if clause == nil {
- check.error(s, InvalidSyntaxTree, "incorrect type switch case")
- continue
- }
- // Check each type in this type switch case.
- T := check.caseTypes(sx, clause.List, seen)
- check.openScope(clause, "case")
- // If lhs exists, declare a corresponding variable in the case-local scope.
- if lhs != nil {
- // spec: "The TypeSwitchGuard may include a short variable declaration.
- // When that form is used, the variable is declared at the beginning of
- // the implicit block in each clause. In clauses with a case listing
- // exactly one type, the variable has that type; otherwise, the variable
- // has the type of the expression in the TypeSwitchGuard."
- if len(clause.List) != 1 || T == nil {
- T = x.typ
- }
- obj := NewVar(lhs.Pos(), check.pkg, lhs.Name, T)
- scopePos := clause.Pos() + token.Pos(len("default")) // for default clause (len(List) == 0)
- if n := len(clause.List); n > 0 {
- scopePos = clause.List[n-1].End()
- }
- check.declare(check.scope, nil, obj, scopePos)
- check.recordImplicit(clause, obj)
- // For the "declared and not used" error, all lhs variables act as
- // one; i.e., if any one of them is 'used', all of them are 'used'.
- // Collect them for later analysis.
- lhsVars = append(lhsVars, obj)
- }
- check.stmtList(inner, clause.Body)
- check.closeScope()
- }
-
- // If lhs exists, we must have at least one lhs variable that was used.
- if lhs != nil {
- var used bool
- for _, v := range lhsVars {
- if v.used {
- used = true
- }
- v.used = true // avoid usage error when checking entire function
- }
- if !used {
- check.softErrorf(lhs, UnusedVar, "%s declared and not used", lhs.Name)
- }
- }
-
- case *ast.SelectStmt:
- inner |= breakOk
-
- check.multipleDefaults(s.Body.List)
-
- for _, s := range s.Body.List {
- clause, _ := s.(*ast.CommClause)
- if clause == nil {
- continue // error reported before
- }
-
- // clause.Comm must be a SendStmt, RecvStmt, or default case
- valid := false
- var rhs ast.Expr // rhs of RecvStmt, or nil
- switch s := clause.Comm.(type) {
- case nil, *ast.SendStmt:
- valid = true
- case *ast.AssignStmt:
- if len(s.Rhs) == 1 {
- rhs = s.Rhs[0]
- }
- case *ast.ExprStmt:
- rhs = s.X
- }
-
- // if present, rhs must be a receive operation
- if rhs != nil {
- if x, _ := unparen(rhs).(*ast.UnaryExpr); x != nil && x.Op == token.ARROW {
- valid = true
- }
- }
-
- if !valid {
- check.error(clause.Comm, InvalidSelectCase, "select case must be send or receive (possibly with assignment)")
- continue
- }
-
- check.openScope(s, "case")
- if clause.Comm != nil {
- check.stmt(inner, clause.Comm)
- }
- check.stmtList(inner, clause.Body)
- check.closeScope()
- }
-
- case *ast.ForStmt:
- inner |= breakOk | continueOk
- check.openScope(s, "for")
- defer check.closeScope()
-
- check.simpleStmt(s.Init)
- if s.Cond != nil {
- var x operand
- check.expr(&x, s.Cond)
- if x.mode != invalid && !allBoolean(x.typ) {
- check.error(s.Cond, InvalidCond, "non-boolean condition in for statement")
- }
- }
- check.simpleStmt(s.Post)
- // spec: "The init statement may be a short variable
- // declaration, but the post statement must not."
- if s, _ := s.Post.(*ast.AssignStmt); s != nil && s.Tok == token.DEFINE {
- check.softErrorf(s, InvalidPostDecl, "cannot declare in post statement")
- // Don't call useLHS here because we want to use the lhs in
- // this erroneous statement so that we don't get errors about
- // these lhs variables being declared and not used.
- check.use(s.Lhs...) // avoid follow-up errors
- }
- check.stmt(inner, s.Body)
-
- case *ast.RangeStmt:
- inner |= breakOk | continueOk
-
- // check expression to iterate over
- var x operand
- check.expr(&x, s.X)
-
- // determine key/value types
- var key, val Type
- if x.mode != invalid {
- // Ranging over a type parameter is permitted if it has a core type.
- var cause string
- u := coreType(x.typ)
- switch t := u.(type) {
- case nil:
- cause = check.sprintf("%s has no core type", x.typ)
- case *Chan:
- if s.Value != nil {
- check.softErrorf(s.Value, InvalidIterVar, "range over %s permits only one iteration variable", &x)
- // ok to continue
- }
- if t.dir == SendOnly {
- cause = "receive from send-only channel"
- }
- }
- key, val = rangeKeyVal(u)
- if key == nil || cause != "" {
- if cause == "" {
- check.softErrorf(&x, InvalidRangeExpr, "cannot range over %s", &x)
- } else {
- check.softErrorf(&x, InvalidRangeExpr, "cannot range over %s (%s)", &x, cause)
- }
- // ok to continue
- }
- }
-
- // Open the for-statement block scope now, after the range clause.
- // Iteration variables declared with := need to go in this scope (was issue #51437).
- check.openScope(s, "range")
- defer check.closeScope()
-
- // check assignment to/declaration of iteration variables
- // (irregular assignment, cannot easily map to existing assignment checks)
-
- // lhs expressions and initialization value (rhs) types
- lhs := [2]ast.Expr{s.Key, s.Value}
- rhs := [2]Type{key, val} // key, val may be nil
-
- if s.Tok == token.DEFINE {
- // short variable declaration
- var vars []*Var
- for i, lhs := range lhs {
- if lhs == nil {
- continue
- }
-
- // determine lhs variable
- var obj *Var
- if ident, _ := lhs.(*ast.Ident); ident != nil {
- // declare new variable
- name := ident.Name
- obj = NewVar(ident.Pos(), check.pkg, name, nil)
- check.recordDef(ident, obj)
- // _ variables don't count as new variables
- if name != "_" {
- vars = append(vars, obj)
- }
- } else {
- check.errorf(lhs, InvalidSyntaxTree, "cannot declare %s", lhs)
- obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
- }
-
- // initialize lhs variable
- if typ := rhs[i]; typ != nil {
- x.mode = value
- x.expr = lhs // we don't have a better rhs expression to use here
- x.typ = typ
- check.initVar(obj, &x, "range clause")
- } else {
- obj.typ = Typ[Invalid]
- obj.used = true // don't complain about unused variable
- }
- }
-
- // declare variables
- if len(vars) > 0 {
- scopePos := s.Body.Pos()
- for _, obj := range vars {
- check.declare(check.scope, nil /* recordDef already called */, obj, scopePos)
- }
- } else {
- check.error(inNode(s, s.TokPos), NoNewVar, "no new variables on left side of :=")
- }
- } else {
- // ordinary assignment
- for i, lhs := range lhs {
- if lhs == nil {
- continue
- }
- if typ := rhs[i]; typ != nil {
- x.mode = value
- x.expr = lhs // we don't have a better rhs expression to use here
- x.typ = typ
- check.assignVar(lhs, &x)
- }
- }
- }
-
- check.stmt(inner, s.Body)
-
- default:
- check.error(s, InvalidSyntaxTree, "invalid statement")
- }
-}
-
-// rangeKeyVal returns the key and value type produced by a range clause
-// over an expression of type typ. If the range clause is not permitted
-// the results are nil.
-func rangeKeyVal(typ Type) (key, val Type) {
- switch typ := arrayPtrDeref(typ).(type) {
- case *Basic:
- if isString(typ) {
- return Typ[Int], universeRune // use 'rune' name
- }
- case *Array:
- return Typ[Int], typ.elem
- case *Slice:
- return Typ[Int], typ.elem
- case *Map:
- return typ.key, typ.elem
- case *Chan:
- return typ.elem, Typ[Invalid]
- }
- return
-}
diff --git a/contrib/go/_std_1.20/src/go/types/struct.go b/contrib/go/_std_1.20/src/go/types/struct.go
deleted file mode 100644
index 2ed0e6d89a..0000000000
--- a/contrib/go/_std_1.20/src/go/types/struct.go
+++ /dev/null
@@ -1,218 +0,0 @@
-// 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 types
-
-import (
- "go/ast"
- "go/token"
- . "internal/types/errors"
- "strconv"
-)
-
-// ----------------------------------------------------------------------------
-// API
-
-// A Struct represents a struct type.
-type Struct struct {
- fields []*Var // fields != nil indicates the struct is set up (possibly with len(fields) == 0)
- tags []string // field tags; nil if there are no tags
-}
-
-// NewStruct returns a new struct with the given fields and corresponding field tags.
-// If a field with index i has a tag, tags[i] must be that tag, but len(tags) may be
-// only as long as required to hold the tag with the largest index i. Consequently,
-// if no field has a tag, tags may be nil.
-func NewStruct(fields []*Var, tags []string) *Struct {
- var fset objset
- for _, f := range fields {
- if f.name != "_" && fset.insert(f) != nil {
- panic("multiple fields with the same name")
- }
- }
- if len(tags) > len(fields) {
- panic("more tags than fields")
- }
- s := &Struct{fields: fields, tags: tags}
- s.markComplete()
- return s
-}
-
-// NumFields returns the number of fields in the struct (including blank and embedded fields).
-func (s *Struct) NumFields() int { return len(s.fields) }
-
-// Field returns the i'th field for 0 <= i < NumFields().
-func (s *Struct) Field(i int) *Var { return s.fields[i] }
-
-// Tag returns the i'th field tag for 0 <= i < NumFields().
-func (s *Struct) Tag(i int) string {
- if i < len(s.tags) {
- return s.tags[i]
- }
- return ""
-}
-
-func (t *Struct) Underlying() Type { return t }
-func (t *Struct) String() string { return TypeString(t, nil) }
-
-// ----------------------------------------------------------------------------
-// Implementation
-
-func (s *Struct) markComplete() {
- if s.fields == nil {
- s.fields = make([]*Var, 0)
- }
-}
-
-func (check *Checker) structType(styp *Struct, e *ast.StructType) {
- list := e.Fields
- if list == nil {
- styp.markComplete()
- return
- }
-
- // struct fields and tags
- var fields []*Var
- var tags []string
-
- // for double-declaration checks
- var fset objset
-
- // current field typ and tag
- var typ Type
- var tag string
- add := func(ident *ast.Ident, embedded bool, pos token.Pos) {
- if tag != "" && tags == nil {
- tags = make([]string, len(fields))
- }
- if tags != nil {
- tags = append(tags, tag)
- }
-
- name := ident.Name
- fld := NewField(pos, check.pkg, name, typ, embedded)
- // spec: "Within a struct, non-blank field names must be unique."
- if name == "_" || check.declareInSet(&fset, pos, fld) {
- fields = append(fields, fld)
- check.recordDef(ident, fld)
- }
- }
-
- // addInvalid adds an embedded field of invalid type to the struct for
- // fields with errors; this keeps the number of struct fields in sync
- // with the source as long as the fields are _ or have different names
- // (issue #25627).
- addInvalid := func(ident *ast.Ident, pos token.Pos) {
- typ = Typ[Invalid]
- tag = ""
- add(ident, true, pos)
- }
-
- for _, f := range list.List {
- typ = check.varType(f.Type)
- tag = check.tag(f.Tag)
- if len(f.Names) > 0 {
- // named fields
- for _, name := range f.Names {
- add(name, false, name.Pos())
- }
- } else {
- // embedded field
- // spec: "An embedded type must be specified as a type name T or as a
- // pointer to a non-interface type name *T, and T itself may not be a
- // pointer type."
- pos := f.Type.Pos()
- name := embeddedFieldIdent(f.Type)
- if name == nil {
- check.errorf(f.Type, InvalidSyntaxTree, "embedded field type %s has no name", f.Type)
- name = ast.NewIdent("_")
- name.NamePos = pos
- addInvalid(name, pos)
- continue
- }
- add(name, true, pos)
-
- // Because we have a name, typ must be of the form T or *T, where T is the name
- // of a (named or alias) type, and t (= deref(typ)) must be the type of T.
- // We must delay this check to the end because we don't want to instantiate
- // (via under(t)) a possibly incomplete type.
-
- // for use in the closure below
- embeddedTyp := typ
- embeddedPos := f.Type
-
- check.later(func() {
- t, isPtr := deref(embeddedTyp)
- switch u := under(t).(type) {
- case *Basic:
- if t == Typ[Invalid] {
- // error was reported before
- return
- }
- // unsafe.Pointer is treated like a regular pointer
- if u.kind == UnsafePointer {
- check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer")
- }
- case *Pointer:
- check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be a pointer")
- case *Interface:
- if isTypeParam(t) {
- // The error code here is inconsistent with other error codes for
- // invalid embedding, because this restriction may be relaxed in the
- // future, and so it did not warrant a new error code.
- check.error(embeddedPos, MisplacedTypeParam, "embedded field type cannot be a (pointer to a) type parameter")
- break
- }
- if isPtr {
- check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface")
- }
- }
- }).describef(embeddedPos, "check embedded type %s", embeddedTyp)
- }
- }
-
- styp.fields = fields
- styp.tags = tags
- styp.markComplete()
-}
-
-func embeddedFieldIdent(e ast.Expr) *ast.Ident {
- switch e := e.(type) {
- case *ast.Ident:
- return e
- case *ast.StarExpr:
- // *T is valid, but **T is not
- if _, ok := e.X.(*ast.StarExpr); !ok {
- return embeddedFieldIdent(e.X)
- }
- case *ast.SelectorExpr:
- return e.Sel
- case *ast.IndexExpr:
- return embeddedFieldIdent(e.X)
- case *ast.IndexListExpr:
- return embeddedFieldIdent(e.X)
- }
- return nil // invalid embedded field
-}
-
-func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool {
- if alt := oset.insert(obj); alt != nil {
- check.errorf(atPos(pos), DuplicateDecl, "%s redeclared", obj.Name())
- check.reportAltDecl(alt)
- return false
- }
- return true
-}
-
-func (check *Checker) tag(t *ast.BasicLit) string {
- if t != nil {
- if t.Kind == token.STRING {
- if val, err := strconv.Unquote(t.Value); err == nil {
- return val
- }
- }
- check.errorf(t, InvalidSyntaxTree, "incorrect tag syntax: %q", t.Value)
- }
- return ""
-}
diff --git a/contrib/go/_std_1.20/src/go/types/subst.go b/contrib/go/_std_1.20/src/go/types/subst.go
deleted file mode 100644
index 5a49c0447f..0000000000
--- a/contrib/go/_std_1.20/src/go/types/subst.go
+++ /dev/null
@@ -1,421 +0,0 @@
-// Copyright 2018 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.
-
-// This file implements type parameter substitution.
-
-package types
-
-import (
- "go/token"
-)
-
-type substMap map[*TypeParam]Type
-
-// makeSubstMap creates a new substitution map mapping tpars[i] to targs[i].
-// If targs[i] is nil, tpars[i] is not substituted.
-func makeSubstMap(tpars []*TypeParam, targs []Type) substMap {
- assert(len(tpars) == len(targs))
- proj := make(substMap, len(tpars))
- for i, tpar := range tpars {
- proj[tpar] = targs[i]
- }
- return proj
-}
-
-// makeRenameMap is like makeSubstMap, but creates a map used to rename type
-// parameters in from with the type parameters in to.
-func makeRenameMap(from, to []*TypeParam) substMap {
- assert(len(from) == len(to))
- proj := make(substMap, len(from))
- for i, tpar := range from {
- proj[tpar] = to[i]
- }
- return proj
-}
-
-func (m substMap) empty() bool {
- return len(m) == 0
-}
-
-func (m substMap) lookup(tpar *TypeParam) Type {
- if t := m[tpar]; t != nil {
- return t
- }
- return tpar
-}
-
-// subst returns the type typ with its type parameters tpars replaced by the
-// corresponding type arguments targs, recursively. subst is pure in the sense
-// that it doesn't modify the incoming type. If a substitution took place, the
-// result type is different from the incoming type.
-//
-// If expanding is non-nil, it is the instance type currently being expanded.
-// One of expanding or ctxt must be non-nil.
-func (check *Checker) subst(pos token.Pos, typ Type, smap substMap, expanding *Named, ctxt *Context) Type {
- assert(expanding != nil || ctxt != nil)
-
- if smap.empty() {
- return typ
- }
-
- // common cases
- switch t := typ.(type) {
- case *Basic:
- return typ // nothing to do
- case *TypeParam:
- return smap.lookup(t)
- }
-
- // general case
- subst := subster{
- pos: pos,
- smap: smap,
- check: check,
- expanding: expanding,
- ctxt: ctxt,
- }
- return subst.typ(typ)
-}
-
-type subster struct {
- pos token.Pos
- smap substMap
- check *Checker // nil if called via Instantiate
- expanding *Named // if non-nil, the instance that is being expanded
- ctxt *Context
-}
-
-func (subst *subster) typ(typ Type) Type {
- switch t := typ.(type) {
- case nil:
- // Call typOrNil if it's possible that typ is nil.
- panic("nil typ")
-
- case *Basic:
- // nothing to do
-
- case *Array:
- elem := subst.typOrNil(t.elem)
- if elem != t.elem {
- return &Array{len: t.len, elem: elem}
- }
-
- case *Slice:
- elem := subst.typOrNil(t.elem)
- if elem != t.elem {
- return &Slice{elem: elem}
- }
-
- case *Struct:
- if fields, copied := subst.varList(t.fields); copied {
- s := &Struct{fields: fields, tags: t.tags}
- s.markComplete()
- return s
- }
-
- case *Pointer:
- base := subst.typ(t.base)
- if base != t.base {
- return &Pointer{base: base}
- }
-
- case *Tuple:
- return subst.tuple(t)
-
- case *Signature:
- // Preserve the receiver: it is handled during *Interface and *Named type
- // substitution.
- //
- // Naively doing the substitution here can lead to an infinite recursion in
- // the case where the receiver is an interface. For example, consider the
- // following declaration:
- //
- // type T[A any] struct { f interface{ m() } }
- //
- // In this case, the type of f is an interface that is itself the receiver
- // type of all of its methods. Because we have no type name to break
- // cycles, substituting in the recv results in an infinite loop of
- // recv->interface->recv->interface->...
- recv := t.recv
-
- params := subst.tuple(t.params)
- results := subst.tuple(t.results)
- if params != t.params || results != t.results {
- return &Signature{
- rparams: t.rparams,
- // TODO(rFindley) why can't we nil out tparams here, rather than in instantiate?
- tparams: t.tparams,
- // instantiated signatures have a nil scope
- recv: recv,
- params: params,
- results: results,
- variadic: t.variadic,
- }
- }
-
- case *Union:
- terms, copied := subst.termlist(t.terms)
- if copied {
- // term list substitution may introduce duplicate terms (unlikely but possible).
- // This is ok; lazy type set computation will determine the actual type set
- // in normal form.
- return &Union{terms}
- }
-
- case *Interface:
- methods, mcopied := subst.funcList(t.methods)
- embeddeds, ecopied := subst.typeList(t.embeddeds)
- if mcopied || ecopied {
- iface := subst.check.newInterface()
- iface.embeddeds = embeddeds
- iface.implicit = t.implicit
- iface.complete = t.complete
- // If we've changed the interface type, we may need to replace its
- // receiver if the receiver type is the original interface. Receivers of
- // *Named type are replaced during named type expansion.
- //
- // Notably, it's possible to reach here and not create a new *Interface,
- // even though the receiver type may be parameterized. For example:
- //
- // type T[P any] interface{ m() }
- //
- // In this case the interface will not be substituted here, because its
- // method signatures do not depend on the type parameter P, but we still
- // need to create new interface methods to hold the instantiated
- // receiver. This is handled by Named.expandUnderlying.
- iface.methods, _ = replaceRecvType(methods, t, iface)
- return iface
- }
-
- case *Map:
- key := subst.typ(t.key)
- elem := subst.typ(t.elem)
- if key != t.key || elem != t.elem {
- return &Map{key: key, elem: elem}
- }
-
- case *Chan:
- elem := subst.typ(t.elem)
- if elem != t.elem {
- return &Chan{dir: t.dir, elem: elem}
- }
-
- case *Named:
- // dump is for debugging
- dump := func(string, ...any) {}
- if subst.check != nil && trace {
- subst.check.indent++
- defer func() {
- subst.check.indent--
- }()
- dump = func(format string, args ...any) {
- subst.check.trace(subst.pos, format, args...)
- }
- }
-
- // subst is called during expansion, so in this function we need to be
- // careful not to call any methods that would cause t to be expanded: doing
- // so would result in deadlock.
- //
- // So we call t.Origin().TypeParams() rather than t.TypeParams().
- orig := t.Origin()
- n := orig.TypeParams().Len()
- if n == 0 {
- dump(">>> %s is not parameterized", t)
- return t // type is not parameterized
- }
-
- var newTArgs []Type
- if t.TypeArgs().Len() != n {
- return Typ[Invalid] // error reported elsewhere
- }
-
- // already instantiated
- dump(">>> %s already instantiated", t)
- // For each (existing) type argument targ, determine if it needs
- // to be substituted; i.e., if it is or contains a type parameter
- // that has a type argument for it.
- for i, targ := range t.TypeArgs().list() {
- dump(">>> %d targ = %s", i, targ)
- new_targ := subst.typ(targ)
- if new_targ != targ {
- dump(">>> substituted %d targ %s => %s", i, targ, new_targ)
- if newTArgs == nil {
- newTArgs = make([]Type, n)
- copy(newTArgs, t.TypeArgs().list())
- }
- newTArgs[i] = new_targ
- }
- }
-
- if newTArgs == nil {
- dump(">>> nothing to substitute in %s", t)
- return t // nothing to substitute
- }
-
- // Create a new instance and populate the context to avoid endless
- // recursion. The position used here is irrelevant because validation only
- // occurs on t (we don't call validType on named), but we use subst.pos to
- // help with debugging.
- return subst.check.instance(subst.pos, orig, newTArgs, subst.expanding, subst.ctxt)
-
- case *TypeParam:
- return subst.smap.lookup(t)
-
- default:
- unreachable()
- }
-
- return typ
-}
-
-// typOrNil is like typ but if the argument is nil it is replaced with Typ[Invalid].
-// A nil type may appear in pathological cases such as type T[P any] []func(_ T([]_))
-// where an array/slice element is accessed before it is set up.
-func (subst *subster) typOrNil(typ Type) Type {
- if typ == nil {
- return Typ[Invalid]
- }
- return subst.typ(typ)
-}
-
-func (subst *subster) var_(v *Var) *Var {
- if v != nil {
- if typ := subst.typ(v.typ); typ != v.typ {
- return substVar(v, typ)
- }
- }
- return v
-}
-
-func substVar(v *Var, typ Type) *Var {
- copy := *v
- copy.typ = typ
- copy.origin = v.Origin()
- return &copy
-}
-
-func (subst *subster) tuple(t *Tuple) *Tuple {
- if t != nil {
- if vars, copied := subst.varList(t.vars); copied {
- return &Tuple{vars: vars}
- }
- }
- return t
-}
-
-func (subst *subster) varList(in []*Var) (out []*Var, copied bool) {
- out = in
- for i, v := range in {
- if w := subst.var_(v); w != v {
- if !copied {
- // first variable that got substituted => allocate new out slice
- // and copy all variables
- new := make([]*Var, len(in))
- copy(new, out)
- out = new
- copied = true
- }
- out[i] = w
- }
- }
- return
-}
-
-func (subst *subster) func_(f *Func) *Func {
- if f != nil {
- if typ := subst.typ(f.typ); typ != f.typ {
- return substFunc(f, typ)
- }
- }
- return f
-}
-
-func substFunc(f *Func, typ Type) *Func {
- copy := *f
- copy.typ = typ
- copy.origin = f.Origin()
- return &copy
-}
-
-func (subst *subster) funcList(in []*Func) (out []*Func, copied bool) {
- out = in
- for i, f := range in {
- if g := subst.func_(f); g != f {
- if !copied {
- // first function that got substituted => allocate new out slice
- // and copy all functions
- new := make([]*Func, len(in))
- copy(new, out)
- out = new
- copied = true
- }
- out[i] = g
- }
- }
- return
-}
-
-func (subst *subster) typeList(in []Type) (out []Type, copied bool) {
- out = in
- for i, t := range in {
- if u := subst.typ(t); u != t {
- if !copied {
- // first function that got substituted => allocate new out slice
- // and copy all functions
- new := make([]Type, len(in))
- copy(new, out)
- out = new
- copied = true
- }
- out[i] = u
- }
- }
- return
-}
-
-func (subst *subster) termlist(in []*Term) (out []*Term, copied bool) {
- out = in
- for i, t := range in {
- if u := subst.typ(t.typ); u != t.typ {
- if !copied {
- // first function that got substituted => allocate new out slice
- // and copy all functions
- new := make([]*Term, len(in))
- copy(new, out)
- out = new
- copied = true
- }
- out[i] = NewTerm(t.tilde, u)
- }
- }
- return
-}
-
-// replaceRecvType updates any function receivers that have type old to have
-// type new. It does not modify the input slice; if modifications are required,
-// the input slice and any affected signatures will be copied before mutating.
-//
-// The resulting out slice contains the updated functions, and copied reports
-// if anything was modified.
-func replaceRecvType(in []*Func, old, new Type) (out []*Func, copied bool) {
- out = in
- for i, method := range in {
- sig := method.Type().(*Signature)
- if sig.recv != nil && sig.recv.Type() == old {
- if !copied {
- // Allocate a new methods slice before mutating for the first time.
- // This is defensive, as we may share methods across instantiations of
- // a given interface type if they do not get substituted.
- out = make([]*Func, len(in))
- copy(out, in)
- copied = true
- }
- newsig := *sig
- newsig.recv = substVar(sig.recv, new)
- out[i] = substFunc(method, &newsig)
- }
- }
- return
-}
diff --git a/contrib/go/_std_1.20/src/go/types/termlist.go b/contrib/go/_std_1.20/src/go/types/termlist.go
deleted file mode 100644
index 83a02eefac..0000000000
--- a/contrib/go/_std_1.20/src/go/types/termlist.go
+++ /dev/null
@@ -1,161 +0,0 @@
-// 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 types
-
-import "strings"
-
-// A termlist represents the type set represented by the union
-// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn.
-// A termlist is in normal form if all terms are disjoint.
-// termlist operations don't require the operands to be in
-// normal form.
-type termlist []*term
-
-// allTermlist represents the set of all types.
-// It is in normal form.
-var allTermlist = termlist{new(term)}
-
-// termSep is the separator used between individual terms.
-const termSep = " | "
-
-// String prints the termlist exactly (without normalization).
-func (xl termlist) String() string {
- if len(xl) == 0 {
- return "∅"
- }
- var buf strings.Builder
- for i, x := range xl {
- if i > 0 {
- buf.WriteString(termSep)
- }
- buf.WriteString(x.String())
- }
- return buf.String()
-}
-
-// isEmpty reports whether the termlist xl represents the empty set of types.
-func (xl termlist) isEmpty() bool {
- // If there's a non-nil term, the entire list is not empty.
- // If the termlist is in normal form, this requires at most
- // one iteration.
- for _, x := range xl {
- if x != nil {
- return false
- }
- }
- return true
-}
-
-// isAll reports whether the termlist xl represents the set of all types.
-func (xl termlist) isAll() bool {
- // If there's a 𝓤 term, the entire list is 𝓤.
- // If the termlist is in normal form, this requires at most
- // one iteration.
- for _, x := range xl {
- if x != nil && x.typ == nil {
- return true
- }
- }
- return false
-}
-
-// norm returns the normal form of xl.
-func (xl termlist) norm() termlist {
- // Quadratic algorithm, but good enough for now.
- // TODO(gri) fix asymptotic performance
- used := make([]bool, len(xl))
- var rl termlist
- for i, xi := range xl {
- if xi == nil || used[i] {
- continue
- }
- for j := i + 1; j < len(xl); j++ {
- xj := xl[j]
- if xj == nil || used[j] {
- continue
- }
- if u1, u2 := xi.union(xj); u2 == nil {
- // If we encounter a 𝓤 term, the entire list is 𝓤.
- // Exit early.
- // (Note that this is not just an optimization;
- // if we continue, we may end up with a 𝓤 term
- // and other terms and the result would not be
- // in normal form.)
- if u1.typ == nil {
- return allTermlist
- }
- xi = u1
- used[j] = true // xj is now unioned into xi - ignore it in future iterations
- }
- }
- rl = append(rl, xi)
- }
- return rl
-}
-
-// union returns the union xl ∪ yl.
-func (xl termlist) union(yl termlist) termlist {
- return append(xl, yl...).norm()
-}
-
-// intersect returns the intersection xl ∩ yl.
-func (xl termlist) intersect(yl termlist) termlist {
- if xl.isEmpty() || yl.isEmpty() {
- return nil
- }
-
- // Quadratic algorithm, but good enough for now.
- // TODO(gri) fix asymptotic performance
- var rl termlist
- for _, x := range xl {
- for _, y := range yl {
- if r := x.intersect(y); r != nil {
- rl = append(rl, r)
- }
- }
- }
- return rl.norm()
-}
-
-// equal reports whether xl and yl represent the same type set.
-func (xl termlist) equal(yl termlist) bool {
- // TODO(gri) this should be more efficient
- return xl.subsetOf(yl) && yl.subsetOf(xl)
-}
-
-// includes reports whether t ∈ xl.
-func (xl termlist) includes(t Type) bool {
- for _, x := range xl {
- if x.includes(t) {
- return true
- }
- }
- return false
-}
-
-// supersetOf reports whether y ⊆ xl.
-func (xl termlist) supersetOf(y *term) bool {
- for _, x := range xl {
- if y.subsetOf(x) {
- return true
- }
- }
- return false
-}
-
-// subsetOf reports whether xl ⊆ yl.
-func (xl termlist) subsetOf(yl termlist) bool {
- if yl.isEmpty() {
- return xl.isEmpty()
- }
-
- // each term x of xl must be a subset of yl
- for _, x := range xl {
- if !yl.supersetOf(x) {
- return false // x is not a subset yl
- }
- }
- return true
-}
diff --git a/contrib/go/_std_1.20/src/go/types/tuple.go b/contrib/go/_std_1.20/src/go/types/tuple.go
deleted file mode 100644
index e85c5aa81b..0000000000
--- a/contrib/go/_std_1.20/src/go/types/tuple.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2011 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 types
-
-// A Tuple represents an ordered list of variables; a nil *Tuple is a valid (empty) tuple.
-// Tuples are used as components of signatures and to represent the type of multiple
-// assignments; they are not first class types of Go.
-type Tuple struct {
- vars []*Var
-}
-
-// NewTuple returns a new tuple for the given variables.
-func NewTuple(x ...*Var) *Tuple {
- if len(x) > 0 {
- return &Tuple{vars: x}
- }
- return nil
-}
-
-// Len returns the number variables of tuple t.
-func (t *Tuple) Len() int {
- if t != nil {
- return len(t.vars)
- }
- return 0
-}
-
-// At returns the i'th variable of tuple t.
-func (t *Tuple) At(i int) *Var { return t.vars[i] }
-
-func (t *Tuple) Underlying() Type { return t }
-func (t *Tuple) String() string { return TypeString(t, nil) }
diff --git a/contrib/go/_std_1.20/src/go/types/type.go b/contrib/go/_std_1.20/src/go/types/type.go
deleted file mode 100644
index 130637530b..0000000000
--- a/contrib/go/_std_1.20/src/go/types/type.go
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2011 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 types
-
-// A Type represents a type of Go.
-// All types implement the Type interface.
-type Type interface {
- // Underlying returns the underlying type of a type.
- Underlying() Type
-
- // String returns a string representation of a type.
- String() string
-}
-
-// under returns the true expanded underlying type.
-// If it doesn't exist, the result is Typ[Invalid].
-// under must only be called when a type is known
-// to be fully set up.
-func under(t Type) Type {
- if t, _ := t.(*Named); t != nil {
- return t.under()
- }
- return t.Underlying()
-}
-
-// If t is not a type parameter, coreType returns the underlying type.
-// If t is a type parameter, coreType returns the single underlying
-// type of all types in its type set if it exists, or nil otherwise. If the
-// type set contains only unrestricted and restricted channel types (with
-// identical element types), the single underlying type is the restricted
-// channel type if the restrictions are always the same, or nil otherwise.
-func coreType(t Type) Type {
- tpar, _ := t.(*TypeParam)
- if tpar == nil {
- return under(t)
- }
-
- var su Type
- if tpar.underIs(func(u Type) bool {
- if u == nil {
- return false
- }
- if su != nil {
- u = match(su, u)
- if u == nil {
- return false
- }
- }
- // su == nil || match(su, u) != nil
- su = u
- return true
- }) {
- return su
- }
- return nil
-}
-
-// coreString is like coreType but also considers []byte
-// and strings as identical. In this case, if successful and we saw
-// a string, the result is of type (possibly untyped) string.
-func coreString(t Type) Type {
- tpar, _ := t.(*TypeParam)
- if tpar == nil {
- return under(t) // string or untyped string
- }
-
- var su Type
- hasString := false
- if tpar.underIs(func(u Type) bool {
- if u == nil {
- return false
- }
- if isString(u) {
- u = NewSlice(universeByte)
- hasString = true
- }
- if su != nil {
- u = match(su, u)
- if u == nil {
- return false
- }
- }
- // su == nil || match(su, u) != nil
- su = u
- return true
- }) {
- if hasString {
- return Typ[String]
- }
- return su
- }
- return nil
-}
-
-// If x and y are identical, match returns x.
-// If x and y are identical channels but for their direction
-// and one of them is unrestricted, match returns the channel
-// with the restricted direction.
-// In all other cases, match returns nil.
-func match(x, y Type) Type {
- // Common case: we don't have channels.
- if Identical(x, y) {
- return x
- }
-
- // We may have channels that differ in direction only.
- if x, _ := x.(*Chan); x != nil {
- if y, _ := y.(*Chan); y != nil && Identical(x.elem, y.elem) {
- // We have channels that differ in direction only.
- // If there's an unrestricted channel, select the restricted one.
- switch {
- case x.dir == SendRecv:
- return y
- case y.dir == SendRecv:
- return x
- }
- }
- }
-
- // types are different
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/go/types/typelists.go b/contrib/go/_std_1.20/src/go/types/typelists.go
deleted file mode 100644
index 0f241356c3..0000000000
--- a/contrib/go/_std_1.20/src/go/types/typelists.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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 types
-
-// TypeParamList holds a list of type parameters.
-type TypeParamList struct{ tparams []*TypeParam }
-
-// Len returns the number of type parameters in the list.
-// It is safe to call on a nil receiver.
-func (l *TypeParamList) Len() int { return len(l.list()) }
-
-// At returns the i'th type parameter in the list.
-func (l *TypeParamList) At(i int) *TypeParam { return l.tparams[i] }
-
-// list is for internal use where we expect a []*TypeParam.
-// TODO(rfindley): list should probably be eliminated: we can pass around a
-// TypeParamList instead.
-func (l *TypeParamList) list() []*TypeParam {
- if l == nil {
- return nil
- }
- return l.tparams
-}
-
-// TypeList holds a list of types.
-type TypeList struct{ types []Type }
-
-// newTypeList returns a new TypeList with the types in list.
-func newTypeList(list []Type) *TypeList {
- if len(list) == 0 {
- return nil
- }
- return &TypeList{list}
-}
-
-// Len returns the number of types in the list.
-// It is safe to call on a nil receiver.
-func (l *TypeList) Len() int { return len(l.list()) }
-
-// At returns the i'th type in the list.
-func (l *TypeList) At(i int) Type { return l.types[i] }
-
-// list is for internal use where we expect a []Type.
-// TODO(rfindley): list should probably be eliminated: we can pass around a
-// TypeList instead.
-func (l *TypeList) list() []Type {
- if l == nil {
- return nil
- }
- return l.types
-}
-
-// ----------------------------------------------------------------------------
-// Implementation
-
-func bindTParams(list []*TypeParam) *TypeParamList {
- if len(list) == 0 {
- return nil
- }
- for i, typ := range list {
- if typ.index >= 0 {
- panic("type parameter bound more than once")
- }
- typ.index = i
- }
- return &TypeParamList{tparams: list}
-}
diff --git a/contrib/go/_std_1.20/src/go/types/typeparam.go b/contrib/go/_std_1.20/src/go/types/typeparam.go
deleted file mode 100644
index 40d96ac947..0000000000
--- a/contrib/go/_std_1.20/src/go/types/typeparam.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2011 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 types
-
-import (
- "sync/atomic"
-)
-
-// Note: This is a uint32 rather than a uint64 because the
-// respective 64 bit atomic instructions are not available
-// on all platforms.
-var lastID uint32
-
-// nextID returns a value increasing monotonically by 1 with
-// each call, starting with 1. It may be called concurrently.
-func nextID() uint64 { return uint64(atomic.AddUint32(&lastID, 1)) }
-
-// A TypeParam represents a type parameter type.
-type TypeParam struct {
- check *Checker // for lazy type bound completion
- id uint64 // unique id, for debugging only
- obj *TypeName // corresponding type name
- index int // type parameter index in source order, starting at 0
- bound Type // any type, but underlying is eventually *Interface for correct programs (see TypeParam.iface)
-}
-
-// NewTypeParam returns a new TypeParam. Type parameters may be set on a Named
-// or Signature type by calling SetTypeParams. Setting a type parameter on more
-// than one type will result in a panic.
-//
-// The constraint argument can be nil, and set later via SetConstraint. If the
-// constraint is non-nil, it must be fully defined.
-func NewTypeParam(obj *TypeName, constraint Type) *TypeParam {
- return (*Checker)(nil).newTypeParam(obj, constraint)
-}
-
-// check may be nil
-func (check *Checker) newTypeParam(obj *TypeName, constraint Type) *TypeParam {
- // Always increment lastID, even if it is not used.
- id := nextID()
- if check != nil {
- check.nextID++
- id = check.nextID
- }
- typ := &TypeParam{check: check, id: id, obj: obj, index: -1, bound: constraint}
- if obj.typ == nil {
- obj.typ = typ
- }
- // iface may mutate typ.bound, so we must ensure that iface() is called
- // at least once before the resulting TypeParam escapes.
- if check != nil {
- check.needsCleanup(typ)
- } else if constraint != nil {
- typ.iface()
- }
- return typ
-}
-
-// Index returns the index of the type param within its param list, or -1 if
-// the type parameter has not yet been bound to a type.
-func (t *TypeParam) Index() int {
- return t.index
-}
-
-// Obj returns the type name for t.
-func (t *TypeParam) Obj() *TypeName { return t.obj }
-
-// Constraint returns the type constraint specified for t.
-func (t *TypeParam) Constraint() Type {
- return t.bound
-}
-
-// SetConstraint sets the type constraint for t.
-//
-// It must be called by users of NewTypeParam after the bound's underlying is
-// fully defined, and before using the type parameter in any way other than to
-// form other types. Once SetConstraint returns the receiver, t is safe for
-// concurrent use.
-func (t *TypeParam) SetConstraint(bound Type) {
- if bound == nil {
- panic("nil constraint")
- }
- t.bound = bound
- // iface may mutate t.bound (if bound is not an interface), so ensure that
- // this is done before returning.
- t.iface()
-}
-
-func (t *TypeParam) Underlying() Type {
- return t.iface()
-}
-
-func (t *TypeParam) String() string { return TypeString(t, nil) }
-
-// ----------------------------------------------------------------------------
-// Implementation
-
-func (t *TypeParam) cleanup() {
- t.iface()
- t.check = nil
-}
-
-// iface returns the constraint interface of t.
-func (t *TypeParam) iface() *Interface {
- bound := t.bound
-
- // determine constraint interface
- var ityp *Interface
- switch u := under(bound).(type) {
- case *Basic:
- if u == Typ[Invalid] {
- // error is reported elsewhere
- return &emptyInterface
- }
- case *Interface:
- if isTypeParam(bound) {
- // error is reported in Checker.collectTypeParams
- return &emptyInterface
- }
- ityp = u
- }
-
- // If we don't have an interface, wrap constraint into an implicit interface.
- if ityp == nil {
- ityp = NewInterfaceType(nil, []Type{bound})
- ityp.implicit = true
- t.bound = ityp // update t.bound for next time (optimization)
- }
-
- // compute type set if necessary
- if ityp.tset == nil {
- // pos is used for tracing output; start with the type parameter position.
- pos := t.obj.pos
- // use the (original or possibly instantiated) type bound position if we have one
- if n, _ := bound.(*Named); n != nil {
- pos = n.obj.pos
- }
- computeInterfaceTypeSet(t.check, pos, ityp)
- }
-
- return ityp
-}
-
-// is calls f with the specific type terms of t's constraint and reports whether
-// all calls to f returned true. If there are no specific terms, is
-// returns the result of f(nil).
-func (t *TypeParam) is(f func(*term) bool) bool {
- return t.iface().typeSet().is(f)
-}
-
-// underIs calls f with the underlying types of the specific type terms
-// of t's constraint and reports whether all calls to f returned true.
-// If there are no specific terms, underIs returns the result of f(nil).
-func (t *TypeParam) underIs(f func(Type) bool) bool {
- return t.iface().typeSet().underIs(f)
-}
diff --git a/contrib/go/_std_1.20/src/go/types/typeset.go b/contrib/go/_std_1.20/src/go/types/typeset.go
deleted file mode 100644
index d68446df66..0000000000
--- a/contrib/go/_std_1.20/src/go/types/typeset.go
+++ /dev/null
@@ -1,434 +0,0 @@
-// 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 types
-
-import (
- "fmt"
- "go/token"
- . "internal/types/errors"
- "sort"
- "strings"
-)
-
-// ----------------------------------------------------------------------------
-// API
-
-// A _TypeSet represents the type set of an interface.
-// Because of existing language restrictions, methods can be "factored out"
-// from the terms. The actual type set is the intersection of the type set
-// implied by the methods and the type set described by the terms and the
-// comparable bit. To test whether a type is included in a type set
-// ("implements" relation), the type must implement all methods _and_ be
-// an element of the type set described by the terms and the comparable bit.
-// If the term list describes the set of all types and comparable is true,
-// only comparable types are meant; in all other cases comparable is false.
-type _TypeSet struct {
- methods []*Func // all methods of the interface; sorted by unique ID
- terms termlist // type terms of the type set
- comparable bool // invariant: !comparable || terms.isAll()
-}
-
-// IsEmpty reports whether type set s is the empty set.
-func (s *_TypeSet) IsEmpty() bool { return s.terms.isEmpty() }
-
-// IsAll reports whether type set s is the set of all types (corresponding to the empty interface).
-func (s *_TypeSet) IsAll() bool { return s.IsMethodSet() && len(s.methods) == 0 }
-
-// IsMethodSet reports whether the interface t is fully described by its method set.
-func (s *_TypeSet) IsMethodSet() bool { return !s.comparable && s.terms.isAll() }
-
-// IsComparable reports whether each type in the set is comparable.
-func (s *_TypeSet) IsComparable(seen map[Type]bool) bool {
- if s.terms.isAll() {
- return s.comparable
- }
- return s.is(func(t *term) bool {
- return t != nil && comparable(t.typ, false, seen, nil)
- })
-}
-
-// NumMethods returns the number of methods available.
-func (s *_TypeSet) NumMethods() int { return len(s.methods) }
-
-// Method returns the i'th method of type set s for 0 <= i < s.NumMethods().
-// The methods are ordered by their unique ID.
-func (s *_TypeSet) Method(i int) *Func { return s.methods[i] }
-
-// LookupMethod returns the index of and method with matching package and name, or (-1, nil).
-func (s *_TypeSet) LookupMethod(pkg *Package, name string, foldCase bool) (int, *Func) {
- return lookupMethod(s.methods, pkg, name, foldCase)
-}
-
-func (s *_TypeSet) String() string {
- switch {
- case s.IsEmpty():
- return "∅"
- case s.IsAll():
- return "𝓤"
- }
-
- hasMethods := len(s.methods) > 0
- hasTerms := s.hasTerms()
-
- var buf strings.Builder
- buf.WriteByte('{')
- if s.comparable {
- buf.WriteString("comparable")
- if hasMethods || hasTerms {
- buf.WriteString("; ")
- }
- }
- for i, m := range s.methods {
- if i > 0 {
- buf.WriteString("; ")
- }
- buf.WriteString(m.String())
- }
- if hasMethods && hasTerms {
- buf.WriteString("; ")
- }
- if hasTerms {
- buf.WriteString(s.terms.String())
- }
- buf.WriteString("}")
- return buf.String()
-}
-
-// ----------------------------------------------------------------------------
-// Implementation
-
-// hasTerms reports whether the type set has specific type terms.
-func (s *_TypeSet) hasTerms() bool { return !s.terms.isEmpty() && !s.terms.isAll() }
-
-// subsetOf reports whether s1 ⊆ s2.
-func (s1 *_TypeSet) subsetOf(s2 *_TypeSet) bool { return s1.terms.subsetOf(s2.terms) }
-
-// TODO(gri) TypeSet.is and TypeSet.underIs should probably also go into termlist.go
-
-// is calls f with the specific type terms of s and reports whether
-// all calls to f returned true. If there are no specific terms, is
-// returns the result of f(nil).
-func (s *_TypeSet) is(f func(*term) bool) bool {
- if !s.hasTerms() {
- return f(nil)
- }
- for _, t := range s.terms {
- assert(t.typ != nil)
- if !f(t) {
- return false
- }
- }
- return true
-}
-
-// underIs calls f with the underlying types of the specific type terms
-// of s and reports whether all calls to f returned true. If there are
-// no specific terms, underIs returns the result of f(nil).
-func (s *_TypeSet) underIs(f func(Type) bool) bool {
- if !s.hasTerms() {
- return f(nil)
- }
- for _, t := range s.terms {
- assert(t.typ != nil)
- // x == under(x) for ~x terms
- u := t.typ
- if !t.tilde {
- u = under(u)
- }
- if debug {
- assert(Identical(u, under(u)))
- }
- if !f(u) {
- return false
- }
- }
- return true
-}
-
-// topTypeSet may be used as type set for the empty interface.
-var topTypeSet = _TypeSet{terms: allTermlist}
-
-// computeInterfaceTypeSet may be called with check == nil.
-func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_TypeSet {
- if ityp.tset != nil {
- return ityp.tset
- }
-
- // If the interface is not fully set up yet, the type set will
- // not be complete, which may lead to errors when using the
- // type set (e.g. missing method). Don't compute a partial type
- // set (and don't store it!), so that we still compute the full
- // type set eventually. Instead, return the top type set and
- // let any follow-on errors play out.
- //
- // TODO(gri) Consider recording when this happens and reporting
- // it as an error (but only if there were no other errors so to
- // to not have unnecessary follow-on errors).
- if !ityp.complete {
- return &topTypeSet
- }
-
- if check != nil && trace {
- // Types don't generally have position information.
- // If we don't have a valid pos provided, try to use
- // one close enough.
- if !pos.IsValid() && len(ityp.methods) > 0 {
- pos = ityp.methods[0].pos
- }
-
- check.trace(pos, "-- type set for %s", ityp)
- check.indent++
- defer func() {
- check.indent--
- check.trace(pos, "=> %s ", ityp.typeSet())
- }()
- }
-
- // An infinitely expanding interface (due to a cycle) is detected
- // elsewhere (Checker.validType), so here we simply assume we only
- // have valid interfaces. Mark the interface as complete to avoid
- // infinite recursion if the validType check occurs later for some
- // reason.
- ityp.tset = &_TypeSet{terms: allTermlist} // TODO(gri) is this sufficient?
-
- var unionSets map[*Union]*_TypeSet
- if check != nil {
- if check.unionTypeSets == nil {
- check.unionTypeSets = make(map[*Union]*_TypeSet)
- }
- unionSets = check.unionTypeSets
- } else {
- unionSets = make(map[*Union]*_TypeSet)
- }
-
- // Methods of embedded interfaces are collected unchanged; i.e., the identity
- // of a method I.m's Func Object of an interface I is the same as that of
- // the method m in an interface that embeds interface I. On the other hand,
- // if a method is embedded via multiple overlapping embedded interfaces, we
- // don't provide a guarantee which "original m" got chosen for the embedding
- // interface. See also issue #34421.
- //
- // If we don't care to provide this identity guarantee anymore, instead of
- // reusing the original method in embeddings, we can clone the method's Func
- // Object and give it the position of a corresponding embedded interface. Then
- // we can get rid of the mpos map below and simply use the cloned method's
- // position.
-
- var todo []*Func
- var seen objset
- var allMethods []*Func
- mpos := make(map[*Func]token.Pos) // method specification or method embedding position, for good error messages
- addMethod := func(pos token.Pos, m *Func, explicit bool) {
- switch other := seen.insert(m); {
- case other == nil:
- allMethods = append(allMethods, m)
- mpos[m] = pos
- case explicit:
- if check == nil {
- panic(fmt.Sprintf("%v: duplicate method %s", m.pos, m.name))
- }
- // check != nil
- check.errorf(atPos(pos), DuplicateDecl, "duplicate method %s", m.name)
- check.errorf(atPos(mpos[other.(*Func)]), DuplicateDecl, "\tother declaration of %s", m.name) // secondary error, \t indented
- default:
- // We have a duplicate method name in an embedded (not explicitly declared) method.
- // Check method signatures after all types are computed (issue #33656).
- // If we're pre-go1.14 (overlapping embeddings are not permitted), report that
- // error here as well (even though we could do it eagerly) because it's the same
- // error message.
- if check == nil {
- // check method signatures after all locally embedded interfaces are computed
- todo = append(todo, m, other.(*Func))
- break
- }
- // check != nil
- check.later(func() {
- if !check.allowVersion(m.pkg, 1, 14) || !Identical(m.typ, other.Type()) {
- check.errorf(atPos(pos), DuplicateDecl, "duplicate method %s", m.name)
- check.errorf(atPos(mpos[other.(*Func)]), DuplicateDecl, "\tother declaration of %s", m.name) // secondary error, \t indented
- }
- }).describef(atPos(pos), "duplicate method check for %s", m.name)
- }
- }
-
- for _, m := range ityp.methods {
- addMethod(m.pos, m, true)
- }
-
- // collect embedded elements
- allTerms := allTermlist
- allComparable := false
- for i, typ := range ityp.embeddeds {
- // The embedding position is nil for imported interfaces
- // and also for interface copies after substitution (but
- // in that case we don't need to report errors again).
- var pos token.Pos // embedding position
- if ityp.embedPos != nil {
- pos = (*ityp.embedPos)[i]
- }
- var comparable bool
- var terms termlist
- switch u := under(typ).(type) {
- case *Interface:
- // For now we don't permit type parameters as constraints.
- assert(!isTypeParam(typ))
- tset := computeInterfaceTypeSet(check, pos, u)
- // If typ is local, an error was already reported where typ is specified/defined.
- if check != nil && check.isImportedConstraint(typ) && !check.allowVersion(check.pkg, 1, 18) {
- check.errorf(atPos(pos), UnsupportedFeature, "embedding constraint interface %s requires go1.18 or later", typ)
- continue
- }
- comparable = tset.comparable
- for _, m := range tset.methods {
- addMethod(pos, m, false) // use embedding position pos rather than m.pos
- }
- terms = tset.terms
- case *Union:
- if check != nil && !check.allowVersion(check.pkg, 1, 18) {
- check.errorf(atPos(pos), UnsupportedFeature, "embedding interface element %s requires go1.18 or later", u)
- continue
- }
- tset := computeUnionTypeSet(check, unionSets, pos, u)
- if tset == &invalidTypeSet {
- continue // ignore invalid unions
- }
- assert(!tset.comparable)
- assert(len(tset.methods) == 0)
- terms = tset.terms
- default:
- if u == Typ[Invalid] {
- continue
- }
- if check != nil && !check.allowVersion(check.pkg, 1, 18) {
- check.errorf(atPos(pos), UnsupportedFeature, "embedding non-interface type %s requires go1.18 or later", typ)
- continue
- }
- terms = termlist{{false, typ}}
- }
-
- // The type set of an interface is the intersection of the type sets of all its elements.
- // Due to language restrictions, only embedded interfaces can add methods, they are handled
- // separately. Here we only need to intersect the term lists and comparable bits.
- allTerms, allComparable = intersectTermLists(allTerms, allComparable, terms, comparable)
- }
- ityp.embedPos = nil // not needed anymore (errors have been reported)
-
- // process todo's (this only happens if check == nil)
- for i := 0; i < len(todo); i += 2 {
- m := todo[i]
- other := todo[i+1]
- if !Identical(m.typ, other.typ) {
- panic(fmt.Sprintf("%v: duplicate method %s", m.pos, m.name))
- }
- }
-
- ityp.tset.comparable = allComparable
- if len(allMethods) != 0 {
- sortMethods(allMethods)
- ityp.tset.methods = allMethods
- }
- ityp.tset.terms = allTerms
-
- return ityp.tset
-}
-
-// TODO(gri) The intersectTermLists function belongs to the termlist implementation.
-// The comparable type set may also be best represented as a term (using
-// a special type).
-
-// intersectTermLists computes the intersection of two term lists and respective comparable bits.
-// xcomp, ycomp are valid only if xterms.isAll() and yterms.isAll() respectively.
-func intersectTermLists(xterms termlist, xcomp bool, yterms termlist, ycomp bool) (termlist, bool) {
- terms := xterms.intersect(yterms)
- // If one of xterms or yterms is marked as comparable,
- // the result must only include comparable types.
- comp := xcomp || ycomp
- if comp && !terms.isAll() {
- // only keep comparable terms
- i := 0
- for _, t := range terms {
- assert(t.typ != nil)
- if comparable(t.typ, false /* strictly comparable */, nil, nil) {
- terms[i] = t
- i++
- }
- }
- terms = terms[:i]
- if !terms.isAll() {
- comp = false
- }
- }
- assert(!comp || terms.isAll()) // comparable invariant
- return terms, comp
-}
-
-func sortMethods(list []*Func) {
- sort.Sort(byUniqueMethodName(list))
-}
-
-func assertSortedMethods(list []*Func) {
- if !debug {
- panic("assertSortedMethods called outside debug mode")
- }
- if !sort.IsSorted(byUniqueMethodName(list)) {
- panic("methods not sorted")
- }
-}
-
-// byUniqueMethodName method lists can be sorted by their unique method names.
-type byUniqueMethodName []*Func
-
-func (a byUniqueMethodName) Len() int { return len(a) }
-func (a byUniqueMethodName) Less(i, j int) bool { return a[i].Id() < a[j].Id() }
-func (a byUniqueMethodName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-
-// invalidTypeSet is a singleton type set to signal an invalid type set
-// due to an error. It's also a valid empty type set, so consumers of
-// type sets may choose to ignore it.
-var invalidTypeSet _TypeSet
-
-// computeUnionTypeSet may be called with check == nil.
-// The result is &invalidTypeSet if the union overflows.
-func computeUnionTypeSet(check *Checker, unionSets map[*Union]*_TypeSet, pos token.Pos, utyp *Union) *_TypeSet {
- if tset, _ := unionSets[utyp]; tset != nil {
- return tset
- }
-
- // avoid infinite recursion (see also computeInterfaceTypeSet)
- unionSets[utyp] = new(_TypeSet)
-
- var allTerms termlist
- for _, t := range utyp.terms {
- var terms termlist
- u := under(t.typ)
- if ui, _ := u.(*Interface); ui != nil {
- // For now we don't permit type parameters as constraints.
- assert(!isTypeParam(t.typ))
- terms = computeInterfaceTypeSet(check, pos, ui).terms
- } else if u == Typ[Invalid] {
- continue
- } else {
- if t.tilde && !Identical(t.typ, u) {
- // There is no underlying type which is t.typ.
- // The corresponding type set is empty.
- t = nil // ∅ term
- }
- terms = termlist{(*term)(t)}
- }
- // The type set of a union expression is the union
- // of the type sets of each term.
- allTerms = allTerms.union(terms)
- if len(allTerms) > maxTermCount {
- if check != nil {
- check.errorf(atPos(pos), InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
- }
- unionSets[utyp] = &invalidTypeSet
- return unionSets[utyp]
- }
- }
- unionSets[utyp].terms = allTerms
-
- return unionSets[utyp]
-}
diff --git a/contrib/go/_std_1.20/src/go/types/typestring.go b/contrib/go/_std_1.20/src/go/types/typestring.go
deleted file mode 100644
index cfeb7eb404..0000000000
--- a/contrib/go/_std_1.20/src/go/types/typestring.go
+++ /dev/null
@@ -1,491 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements printing of types.
-
-package types
-
-import (
- "bytes"
- "fmt"
- "go/token"
- "sort"
- "strconv"
- "strings"
- "unicode/utf8"
-)
-
-// A Qualifier controls how named package-level objects are printed in
-// calls to TypeString, ObjectString, and SelectionString.
-//
-// These three formatting routines call the Qualifier for each
-// package-level object O, and if the Qualifier returns a non-empty
-// string p, the object is printed in the form p.O.
-// If it returns an empty string, only the object name O is printed.
-//
-// Using a nil Qualifier is equivalent to using (*Package).Path: the
-// object is qualified by the import path, e.g., "encoding/json.Marshal".
-type Qualifier func(*Package) string
-
-// RelativeTo returns a Qualifier that fully qualifies members of
-// all packages other than pkg.
-func RelativeTo(pkg *Package) Qualifier {
- if pkg == nil {
- return nil
- }
- return func(other *Package) string {
- if pkg == other {
- return "" // same package; unqualified
- }
- return other.Path()
- }
-}
-
-// TypeString returns the string representation of typ.
-// The Qualifier controls the printing of
-// package-level objects, and may be nil.
-func TypeString(typ Type, qf Qualifier) string {
- var buf bytes.Buffer
- WriteType(&buf, typ, qf)
- return buf.String()
-}
-
-// WriteType writes the string representation of typ to buf.
-// The Qualifier controls the printing of
-// package-level objects, and may be nil.
-func WriteType(buf *bytes.Buffer, typ Type, qf Qualifier) {
- newTypeWriter(buf, qf).typ(typ)
-}
-
-// WriteSignature writes the representation of the signature sig to buf,
-// without a leading "func" keyword. The Qualifier controls the printing
-// of package-level objects, and may be nil.
-func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
- newTypeWriter(buf, qf).signature(sig)
-}
-
-type typeWriter struct {
- buf *bytes.Buffer
- seen map[Type]bool
- qf Qualifier
- ctxt *Context // if non-nil, we are type hashing
- tparams *TypeParamList // local type parameters
- paramNames bool // if set, write function parameter names, otherwise, write types only
- tpSubscripts bool // if set, write type parameter indices as subscripts
- pkgInfo bool // package-annotate first unexported-type field to avoid confusing type description
-}
-
-func newTypeWriter(buf *bytes.Buffer, qf Qualifier) *typeWriter {
- return &typeWriter{buf, make(map[Type]bool), qf, nil, nil, true, false, false}
-}
-
-func newTypeHasher(buf *bytes.Buffer, ctxt *Context) *typeWriter {
- assert(ctxt != nil)
- return &typeWriter{buf, make(map[Type]bool), nil, ctxt, nil, false, false, false}
-}
-
-func (w *typeWriter) byte(b byte) {
- if w.ctxt != nil {
- if b == ' ' {
- b = '#'
- }
- w.buf.WriteByte(b)
- return
- }
- w.buf.WriteByte(b)
- if b == ',' || b == ';' {
- w.buf.WriteByte(' ')
- }
-}
-
-func (w *typeWriter) string(s string) {
- w.buf.WriteString(s)
-}
-
-func (w *typeWriter) error(msg string) {
- if w.ctxt != nil {
- panic(msg)
- }
- w.buf.WriteString("<" + msg + ">")
-}
-
-func (w *typeWriter) typ(typ Type) {
- if w.seen[typ] {
- w.error("cycle to " + goTypeName(typ))
- return
- }
- w.seen[typ] = true
- defer delete(w.seen, typ)
-
- switch t := typ.(type) {
- case nil:
- w.error("nil")
-
- case *Basic:
- // exported basic types go into package unsafe
- // (currently this is just unsafe.Pointer)
- if token.IsExported(t.name) {
- if obj, _ := Unsafe.scope.Lookup(t.name).(*TypeName); obj != nil {
- w.typeName(obj)
- break
- }
- }
- w.string(t.name)
-
- case *Array:
- w.byte('[')
- w.string(strconv.FormatInt(t.len, 10))
- w.byte(']')
- w.typ(t.elem)
-
- case *Slice:
- w.string("[]")
- w.typ(t.elem)
-
- case *Struct:
- w.string("struct{")
- for i, f := range t.fields {
- if i > 0 {
- w.byte(';')
- }
-
- // If disambiguating one struct for another, look for the first unexported field.
- // Do this first in case of nested structs; tag the first-outermost field.
- pkgAnnotate := false
- if w.qf == nil && w.pkgInfo && !token.IsExported(f.name) {
- // note for embedded types, type name is field name, and "string" etc are lower case hence unexported.
- pkgAnnotate = true
- w.pkgInfo = false // only tag once
- }
-
- // This doesn't do the right thing for embedded type
- // aliases where we should print the alias name, not
- // the aliased type (see issue #44410).
- if !f.embedded {
- w.string(f.name)
- w.byte(' ')
- }
- w.typ(f.typ)
- if pkgAnnotate {
- w.string(" /* package ")
- w.string(f.pkg.Path())
- w.string(" */ ")
- }
- if tag := t.Tag(i); tag != "" {
- w.byte(' ')
- // TODO(rfindley) If tag contains blanks, replacing them with '#'
- // in Context.TypeHash may produce another tag
- // accidentally.
- w.string(strconv.Quote(tag))
- }
- }
- w.byte('}')
-
- case *Pointer:
- w.byte('*')
- w.typ(t.base)
-
- case *Tuple:
- w.tuple(t, false)
-
- case *Signature:
- w.string("func")
- w.signature(t)
-
- case *Union:
- // Unions only appear as (syntactic) embedded elements
- // in interfaces and syntactically cannot be empty.
- if t.Len() == 0 {
- w.error("empty union")
- break
- }
- for i, t := range t.terms {
- if i > 0 {
- w.string(termSep)
- }
- if t.tilde {
- w.byte('~')
- }
- w.typ(t.typ)
- }
-
- case *Interface:
- if w.ctxt == nil {
- if t == universeAny.Type() {
- // When not hashing, we can try to improve type strings by writing "any"
- // for a type that is pointer-identical to universeAny. This logic should
- // be deprecated by more robust handling for aliases.
- w.string("any")
- break
- }
- if t == universeComparable.Type().(*Named).underlying {
- w.string("interface{comparable}")
- break
- }
- }
- if t.implicit {
- if len(t.methods) == 0 && len(t.embeddeds) == 1 {
- w.typ(t.embeddeds[0])
- break
- }
- // Something's wrong with the implicit interface.
- // Print it as such and continue.
- w.string("/* implicit */ ")
- }
- w.string("interface{")
- first := true
- if w.ctxt != nil {
- w.typeSet(t.typeSet())
- } else {
- for _, m := range t.methods {
- if !first {
- w.byte(';')
- }
- first = false
- w.string(m.name)
- w.signature(m.typ.(*Signature))
- }
- for _, typ := range t.embeddeds {
- if !first {
- w.byte(';')
- }
- first = false
- w.typ(typ)
- }
- }
- w.byte('}')
-
- case *Map:
- w.string("map[")
- w.typ(t.key)
- w.byte(']')
- w.typ(t.elem)
-
- case *Chan:
- var s string
- var parens bool
- switch t.dir {
- case SendRecv:
- s = "chan "
- // chan (<-chan T) requires parentheses
- if c, _ := t.elem.(*Chan); c != nil && c.dir == RecvOnly {
- parens = true
- }
- case SendOnly:
- s = "chan<- "
- case RecvOnly:
- s = "<-chan "
- default:
- w.error("unknown channel direction")
- }
- w.string(s)
- if parens {
- w.byte('(')
- }
- w.typ(t.elem)
- if parens {
- w.byte(')')
- }
-
- case *Named:
- // If hashing, write a unique prefix for t to represent its identity, since
- // named type identity is pointer identity.
- if w.ctxt != nil {
- w.string(strconv.Itoa(w.ctxt.getID(t)))
- }
- w.typeName(t.obj) // when hashing written for readability of the hash only
- if t.inst != nil {
- // instantiated type
- w.typeList(t.inst.targs.list())
- } else if w.ctxt == nil && t.TypeParams().Len() != 0 { // For type hashing, don't need to format the TypeParams
- // parameterized type
- w.tParamList(t.TypeParams().list())
- }
-
- case *TypeParam:
- if t.obj == nil {
- w.error("unnamed type parameter")
- break
- }
- if i := tparamIndex(w.tparams.list(), t); i >= 0 {
- // The names of type parameters that are declared by the type being
- // hashed are not part of the type identity. Replace them with a
- // placeholder indicating their index.
- w.string(fmt.Sprintf("$%d", i))
- } else {
- w.string(t.obj.name)
- if w.tpSubscripts || w.ctxt != nil {
- w.string(subscript(t.id))
- }
- }
-
- default:
- // For externally defined implementations of Type.
- // Note: In this case cycles won't be caught.
- w.string(t.String())
- }
-}
-
-// typeSet writes a canonical hash for an interface type set.
-func (w *typeWriter) typeSet(s *_TypeSet) {
- assert(w.ctxt != nil)
- first := true
- for _, m := range s.methods {
- if !first {
- w.byte(';')
- }
- first = false
- w.string(m.name)
- w.signature(m.typ.(*Signature))
- }
- switch {
- case s.terms.isAll():
- // nothing to do
- case s.terms.isEmpty():
- w.string(s.terms.String())
- default:
- var termHashes []string
- for _, term := range s.terms {
- // terms are not canonically sorted, so we sort their hashes instead.
- var buf bytes.Buffer
- if term.tilde {
- buf.WriteByte('~')
- }
- newTypeHasher(&buf, w.ctxt).typ(term.typ)
- termHashes = append(termHashes, buf.String())
- }
- sort.Strings(termHashes)
- if !first {
- w.byte(';')
- }
- w.string(strings.Join(termHashes, "|"))
- }
-}
-
-func (w *typeWriter) typeList(list []Type) {
- w.byte('[')
- for i, typ := range list {
- if i > 0 {
- w.byte(',')
- }
- w.typ(typ)
- }
- w.byte(']')
-}
-
-func (w *typeWriter) tParamList(list []*TypeParam) {
- w.byte('[')
- var prev Type
- for i, tpar := range list {
- // Determine the type parameter and its constraint.
- // list is expected to hold type parameter names,
- // but don't crash if that's not the case.
- if tpar == nil {
- w.error("nil type parameter")
- continue
- }
- if i > 0 {
- if tpar.bound != prev {
- // bound changed - write previous one before advancing
- w.byte(' ')
- w.typ(prev)
- }
- w.byte(',')
- }
- prev = tpar.bound
- w.typ(tpar)
- }
- if prev != nil {
- w.byte(' ')
- w.typ(prev)
- }
- w.byte(']')
-}
-
-func (w *typeWriter) typeName(obj *TypeName) {
- w.string(packagePrefix(obj.pkg, w.qf))
- w.string(obj.name)
-}
-
-func (w *typeWriter) tuple(tup *Tuple, variadic bool) {
- w.byte('(')
- if tup != nil {
- for i, v := range tup.vars {
- if i > 0 {
- w.byte(',')
- }
- // parameter names are ignored for type identity and thus type hashes
- if w.ctxt == nil && v.name != "" && w.paramNames {
- w.string(v.name)
- w.byte(' ')
- }
- typ := v.typ
- if variadic && i == len(tup.vars)-1 {
- if s, ok := typ.(*Slice); ok {
- w.string("...")
- typ = s.elem
- } else {
- // special case:
- // append(s, "foo"...) leads to signature func([]byte, string...)
- if t, _ := under(typ).(*Basic); t == nil || t.kind != String {
- w.error("expected string type")
- continue
- }
- w.typ(typ)
- w.string("...")
- continue
- }
- }
- w.typ(typ)
- }
- }
- w.byte(')')
-}
-
-func (w *typeWriter) signature(sig *Signature) {
- if sig.TypeParams().Len() != 0 {
- if w.ctxt != nil {
- assert(w.tparams == nil)
- w.tparams = sig.TypeParams()
- defer func() {
- w.tparams = nil
- }()
- }
- w.tParamList(sig.TypeParams().list())
- }
-
- w.tuple(sig.params, sig.variadic)
-
- n := sig.results.Len()
- if n == 0 {
- // no result
- return
- }
-
- w.byte(' ')
- if n == 1 && (w.ctxt != nil || sig.results.vars[0].name == "") {
- // single unnamed result (if type hashing, name must be ignored)
- w.typ(sig.results.vars[0].typ)
- return
- }
-
- // multiple or named result(s)
- w.tuple(sig.results, false)
-}
-
-// subscript returns the decimal (utf8) representation of x using subscript digits.
-func subscript(x uint64) string {
- const w = len("₀") // all digits 0...9 have the same utf8 width
- var buf [32 * w]byte
- i := len(buf)
- for {
- i -= w
- utf8.EncodeRune(buf[i:], '₀'+rune(x%10)) // '₀' == U+2080
- x /= 10
- if x == 0 {
- break
- }
- }
- return string(buf[i:])
-}
diff --git a/contrib/go/_std_1.20/src/go/types/typeterm.go b/contrib/go/_std_1.20/src/go/types/typeterm.go
deleted file mode 100644
index a7b8969627..0000000000
--- a/contrib/go/_std_1.20/src/go/types/typeterm.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// 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 types
-
-// A term describes elementary type sets:
-//
-// ∅: (*term)(nil) == ∅ // set of no types (empty set)
-// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse)
-// T: &term{false, T} == {T} // set of type T
-// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t
-type term struct {
- tilde bool // valid if typ != nil
- typ Type
-}
-
-func (x *term) String() string {
- switch {
- case x == nil:
- return "∅"
- case x.typ == nil:
- return "𝓤"
- case x.tilde:
- return "~" + x.typ.String()
- default:
- return x.typ.String()
- }
-}
-
-// equal reports whether x and y represent the same type set.
-func (x *term) equal(y *term) bool {
- // easy cases
- switch {
- case x == nil || y == nil:
- return x == y
- case x.typ == nil || y.typ == nil:
- return x.typ == y.typ
- }
- // ∅ ⊂ x, y ⊂ 𝓤
-
- return x.tilde == y.tilde && Identical(x.typ, y.typ)
-}
-
-// union returns the union x ∪ y: zero, one, or two non-nil terms.
-func (x *term) union(y *term) (_, _ *term) {
- // easy cases
- switch {
- case x == nil && y == nil:
- return nil, nil // ∅ ∪ ∅ == ∅
- case x == nil:
- return y, nil // ∅ ∪ y == y
- case y == nil:
- return x, nil // x ∪ ∅ == x
- case x.typ == nil:
- return x, nil // 𝓤 ∪ y == 𝓤
- case y.typ == nil:
- return y, nil // x ∪ 𝓤 == 𝓤
- }
- // ∅ ⊂ x, y ⊂ 𝓤
-
- if x.disjoint(y) {
- return x, y // x ∪ y == (x, y) if x ∩ y == ∅
- }
- // x.typ == y.typ
-
- // ~t ∪ ~t == ~t
- // ~t ∪ T == ~t
- // T ∪ ~t == ~t
- // T ∪ T == T
- if x.tilde || !y.tilde {
- return x, nil
- }
- return y, nil
-}
-
-// intersect returns the intersection x ∩ y.
-func (x *term) intersect(y *term) *term {
- // easy cases
- switch {
- case x == nil || y == nil:
- return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅
- case x.typ == nil:
- return y // 𝓤 ∩ y == y
- case y.typ == nil:
- return x // x ∩ 𝓤 == x
- }
- // ∅ ⊂ x, y ⊂ 𝓤
-
- if x.disjoint(y) {
- return nil // x ∩ y == ∅ if x ∩ y == ∅
- }
- // x.typ == y.typ
-
- // ~t ∩ ~t == ~t
- // ~t ∩ T == T
- // T ∩ ~t == T
- // T ∩ T == T
- if !x.tilde || y.tilde {
- return x
- }
- return y
-}
-
-// includes reports whether t ∈ x.
-func (x *term) includes(t Type) bool {
- // easy cases
- switch {
- case x == nil:
- return false // t ∈ ∅ == false
- case x.typ == nil:
- return true // t ∈ 𝓤 == true
- }
- // ∅ ⊂ x ⊂ 𝓤
-
- u := t
- if x.tilde {
- u = under(u)
- }
- return Identical(x.typ, u)
-}
-
-// subsetOf reports whether x ⊆ y.
-func (x *term) subsetOf(y *term) bool {
- // easy cases
- switch {
- case x == nil:
- return true // ∅ ⊆ y == true
- case y == nil:
- return false // x ⊆ ∅ == false since x != ∅
- case y.typ == nil:
- return true // x ⊆ 𝓤 == true
- case x.typ == nil:
- return false // 𝓤 ⊆ y == false since y != 𝓤
- }
- // ∅ ⊂ x, y ⊂ 𝓤
-
- if x.disjoint(y) {
- return false // x ⊆ y == false if x ∩ y == ∅
- }
- // x.typ == y.typ
-
- // ~t ⊆ ~t == true
- // ~t ⊆ T == false
- // T ⊆ ~t == true
- // T ⊆ T == true
- return !x.tilde || y.tilde
-}
-
-// disjoint reports whether x ∩ y == ∅.
-// x.typ and y.typ must not be nil.
-func (x *term) disjoint(y *term) bool {
- if debug && (x.typ == nil || y.typ == nil) {
- panic("invalid argument(s)")
- }
- ux := x.typ
- if y.tilde {
- ux = under(ux)
- }
- uy := y.typ
- if x.tilde {
- uy = under(uy)
- }
- return !Identical(ux, uy)
-}
diff --git a/contrib/go/_std_1.20/src/go/types/typexpr.go b/contrib/go/_std_1.20/src/go/types/typexpr.go
deleted file mode 100644
index 03817dded1..0000000000
--- a/contrib/go/_std_1.20/src/go/types/typexpr.go
+++ /dev/null
@@ -1,521 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements type-checking of identifiers and type expressions.
-
-package types
-
-import (
- "fmt"
- "go/ast"
- "go/constant"
- "go/internal/typeparams"
- . "internal/types/errors"
- "strings"
-)
-
-// ident type-checks identifier e and initializes x with the value or type of e.
-// If an error occurred, x.mode is set to invalid.
-// For the meaning of def, see Checker.definedType, below.
-// If wantType is set, the identifier e is expected to denote a type.
-func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, wantType bool) {
- x.mode = invalid
- x.expr = e
-
- // Note that we cannot use check.lookup here because the returned scope
- // may be different from obj.Parent(). See also Scope.LookupParent doc.
- scope, obj := check.scope.LookupParent(e.Name, check.pos)
- switch obj {
- case nil:
- if e.Name == "_" {
- // Blank identifiers are never declared, but the current identifier may
- // be a placeholder for a receiver type parameter. In this case we can
- // resolve its type and object from Checker.recvTParamMap.
- if tpar := check.recvTParamMap[e]; tpar != nil {
- x.mode = typexpr
- x.typ = tpar
- } else {
- check.error(e, InvalidBlank, "cannot use _ as value or type")
- }
- } else {
- check.errorf(e, UndeclaredName, "undefined: %s", e.Name)
- }
- return
- case universeAny, universeComparable:
- if !check.allowVersion(check.pkg, 1, 18) {
- check.versionErrorf(e, "go1.18", "predeclared %s", e.Name)
- return // avoid follow-on errors
- }
- }
- check.recordUse(e, obj)
-
- // Type-check the object.
- // Only call Checker.objDecl if the object doesn't have a type yet
- // (in which case we must actually determine it) or the object is a
- // TypeName and we also want a type (in which case we might detect
- // a cycle which needs to be reported). Otherwise we can skip the
- // call and avoid a possible cycle error in favor of the more
- // informative "not a type/value" error that this function's caller
- // will issue (see issue #25790).
- typ := obj.Type()
- if _, gotType := obj.(*TypeName); typ == nil || gotType && wantType {
- check.objDecl(obj, def)
- typ = obj.Type() // type must have been assigned by Checker.objDecl
- }
- assert(typ != nil)
-
- // The object may have been dot-imported.
- // If so, mark the respective package as used.
- // (This code is only needed for dot-imports. Without them,
- // we only have to mark variables, see *Var case below).
- if pkgName := check.dotImportMap[dotImportKey{scope, obj.Name()}]; pkgName != nil {
- pkgName.used = true
- }
-
- switch obj := obj.(type) {
- case *PkgName:
- check.errorf(e, InvalidPkgUse, "use of package %s not in selector", obj.name)
- return
-
- case *Const:
- check.addDeclDep(obj)
- if typ == Typ[Invalid] {
- return
- }
- if obj == universeIota {
- if check.iota == nil {
- check.error(e, InvalidIota, "cannot use iota outside constant declaration")
- return
- }
- x.val = check.iota
- } else {
- x.val = obj.val
- }
- assert(x.val != nil)
- x.mode = constant_
-
- case *TypeName:
- if check.isBrokenAlias(obj) {
- check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see issue #50729)", obj.name)
- return
- }
- x.mode = typexpr
-
- case *Var:
- // It's ok to mark non-local variables, but ignore variables
- // from other packages to avoid potential race conditions with
- // dot-imported variables.
- if obj.pkg == check.pkg {
- obj.used = true
- }
- check.addDeclDep(obj)
- if typ == Typ[Invalid] {
- return
- }
- x.mode = variable
-
- case *Func:
- check.addDeclDep(obj)
- x.mode = value
-
- case *Builtin:
- x.id = obj.id
- x.mode = builtin
-
- case *Nil:
- x.mode = value
-
- default:
- unreachable()
- }
-
- x.typ = typ
-}
-
-// typ type-checks the type expression e and returns its type, or Typ[Invalid].
-// The type must not be an (uninstantiated) generic type.
-func (check *Checker) typ(e ast.Expr) Type {
- return check.definedType(e, nil)
-}
-
-// varType type-checks the type expression e and returns its type, or Typ[Invalid].
-// The type must not be an (uninstantiated) generic type and it must not be a
-// constraint interface.
-func (check *Checker) varType(e ast.Expr) Type {
- typ := check.definedType(e, nil)
- check.validVarType(e, typ)
- return typ
-}
-
-// validVarType reports an error if typ is a constraint interface.
-// The expression e is used for error reporting, if any.
-func (check *Checker) validVarType(e ast.Expr, typ Type) {
- // If we have a type parameter there's nothing to do.
- if isTypeParam(typ) {
- return
- }
-
- // We don't want to call under() or complete interfaces while we are in
- // the middle of type-checking parameter declarations that might belong
- // to interface methods. Delay this check to the end of type-checking.
- check.later(func() {
- if t, _ := under(typ).(*Interface); t != nil {
- tset := computeInterfaceTypeSet(check, e.Pos(), t) // TODO(gri) is this the correct position?
- if !tset.IsMethodSet() {
- if tset.comparable {
- check.softErrorf(e, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface is (or embeds) comparable", typ)
- } else {
- check.softErrorf(e, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface contains type constraints", typ)
- }
- }
- }
- }).describef(e, "check var type %s", typ)
-}
-
-// definedType is like typ but also accepts a type name def.
-// If def != nil, e is the type specification for the defined type def, declared
-// in a type declaration, and def.underlying will be set to the type of e before
-// any components of e are type-checked.
-func (check *Checker) definedType(e ast.Expr, def *Named) Type {
- typ := check.typInternal(e, def)
- assert(isTyped(typ))
- if isGeneric(typ) {
- check.errorf(e, WrongTypeArgCount, "cannot use generic type %s without instantiation", typ)
- typ = Typ[Invalid]
- }
- check.recordTypeAndValue(e, typexpr, typ, nil)
- return typ
-}
-
-// genericType is like typ but the type must be an (uninstantiated) generic
-// type. If cause is non-nil and the type expression was a valid type but not
-// generic, cause will be populated with a message describing the error.
-func (check *Checker) genericType(e ast.Expr, cause *string) Type {
- typ := check.typInternal(e, nil)
- assert(isTyped(typ))
- if typ != Typ[Invalid] && !isGeneric(typ) {
- if cause != nil {
- *cause = check.sprintf("%s is not a generic type", typ)
- }
- typ = Typ[Invalid]
- }
- // TODO(gri) what is the correct call below?
- check.recordTypeAndValue(e, typexpr, typ, nil)
- return typ
-}
-
-// goTypeName returns the Go type name for typ and
-// removes any occurrences of "types." from that name.
-func goTypeName(typ Type) string {
- return strings.ReplaceAll(fmt.Sprintf("%T", typ), "types.", "")
-}
-
-// typInternal drives type checking of types.
-// Must only be called by definedType or genericType.
-func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
- if trace {
- check.trace(e0.Pos(), "-- type %s", e0)
- check.indent++
- defer func() {
- check.indent--
- var under Type
- if T != nil {
- // Calling under() here may lead to endless instantiations.
- // Test case: type T[P any] *T[P]
- under = safeUnderlying(T)
- }
- if T == under {
- check.trace(e0.Pos(), "=> %s // %s", T, goTypeName(T))
- } else {
- check.trace(e0.Pos(), "=> %s (under = %s) // %s", T, under, goTypeName(T))
- }
- }()
- }
-
- switch e := e0.(type) {
- case *ast.BadExpr:
- // ignore - error reported before
-
- case *ast.Ident:
- var x operand
- check.ident(&x, e, def, true)
-
- switch x.mode {
- case typexpr:
- typ := x.typ
- def.setUnderlying(typ)
- return typ
- case invalid:
- // ignore - error reported before
- case novalue:
- check.errorf(&x, NotAType, "%s used as type", &x)
- default:
- check.errorf(&x, NotAType, "%s is not a type", &x)
- }
-
- case *ast.SelectorExpr:
- var x operand
- check.selector(&x, e, def, true)
-
- switch x.mode {
- case typexpr:
- typ := x.typ
- def.setUnderlying(typ)
- return typ
- case invalid:
- // ignore - error reported before
- case novalue:
- check.errorf(&x, NotAType, "%s used as type", &x)
- default:
- check.errorf(&x, NotAType, "%s is not a type", &x)
- }
-
- case *ast.IndexExpr, *ast.IndexListExpr:
- ix := typeparams.UnpackIndexExpr(e)
- if !check.allowVersion(check.pkg, 1, 18) {
- check.softErrorf(inNode(e, ix.Lbrack), UnsupportedFeature, "type instantiation requires go1.18 or later")
- }
- return check.instantiatedType(ix, def)
-
- case *ast.ParenExpr:
- // Generic types must be instantiated before they can be used in any form.
- // Consequently, generic types cannot be parenthesized.
- return check.definedType(e.X, def)
-
- case *ast.ArrayType:
- if e.Len == nil {
- typ := new(Slice)
- def.setUnderlying(typ)
- typ.elem = check.varType(e.Elt)
- return typ
- }
-
- typ := new(Array)
- def.setUnderlying(typ)
- // Provide a more specific error when encountering a [...] array
- // rather than leaving it to the handling of the ... expression.
- if _, ok := e.Len.(*ast.Ellipsis); ok {
- check.error(e.Len, BadDotDotDotSyntax, "invalid use of [...] array (outside a composite literal)")
- typ.len = -1
- } else {
- typ.len = check.arrayLength(e.Len)
- }
- typ.elem = check.varType(e.Elt)
- if typ.len >= 0 {
- return typ
- }
- // report error if we encountered [...]
-
- case *ast.Ellipsis:
- // dots are handled explicitly where they are legal
- // (array composite literals and parameter lists)
- check.error(e, InvalidDotDotDot, "invalid use of '...'")
- check.use(e.Elt)
-
- case *ast.StructType:
- typ := new(Struct)
- def.setUnderlying(typ)
- check.structType(typ, e)
- return typ
-
- case *ast.StarExpr:
- typ := new(Pointer)
- typ.base = Typ[Invalid] // avoid nil base in invalid recursive type declaration
- def.setUnderlying(typ)
- typ.base = check.varType(e.X)
- return typ
-
- case *ast.FuncType:
- typ := new(Signature)
- def.setUnderlying(typ)
- check.funcType(typ, nil, e)
- return typ
-
- case *ast.InterfaceType:
- typ := check.newInterface()
- def.setUnderlying(typ)
- check.interfaceType(typ, e, def)
- return typ
-
- case *ast.MapType:
- typ := new(Map)
- def.setUnderlying(typ)
-
- typ.key = check.varType(e.Key)
- typ.elem = check.varType(e.Value)
-
- // spec: "The comparison operators == and != must be fully defined
- // for operands of the key type; thus the key type must not be a
- // function, map, or slice."
- //
- // Delay this check because it requires fully setup types;
- // it is safe to continue in any case (was issue 6667).
- check.later(func() {
- if !Comparable(typ.key) {
- var why string
- if isTypeParam(typ.key) {
- why = " (missing comparable constraint)"
- }
- check.errorf(e.Key, IncomparableMapKey, "invalid map key type %s%s", typ.key, why)
- }
- }).describef(e.Key, "check map key %s", typ.key)
-
- return typ
-
- case *ast.ChanType:
- typ := new(Chan)
- def.setUnderlying(typ)
-
- dir := SendRecv
- switch e.Dir {
- case ast.SEND | ast.RECV:
- // nothing to do
- case ast.SEND:
- dir = SendOnly
- case ast.RECV:
- dir = RecvOnly
- default:
- check.errorf(e, InvalidSyntaxTree, "unknown channel direction %d", e.Dir)
- // ok to continue
- }
-
- typ.dir = dir
- typ.elem = check.varType(e.Value)
- return typ
-
- default:
- check.errorf(e0, NotAType, "%s is not a type", e0)
- check.use(e0)
- }
-
- typ := Typ[Invalid]
- def.setUnderlying(typ)
- return typ
-}
-
-func (check *Checker) instantiatedType(ix *typeparams.IndexExpr, def *Named) (res Type) {
- if trace {
- check.trace(ix.Pos(), "-- instantiating type %s with %s", ix.X, ix.Indices)
- check.indent++
- defer func() {
- check.indent--
- // Don't format the underlying here. It will always be nil.
- check.trace(ix.Pos(), "=> %s", res)
- }()
- }
-
- var cause string
- gtyp := check.genericType(ix.X, &cause)
- if cause != "" {
- check.errorf(ix.Orig, NotAGenericType, invalidOp+"%s (%s)", ix.Orig, cause)
- }
- if gtyp == Typ[Invalid] {
- return gtyp // error already reported
- }
-
- orig, _ := gtyp.(*Named)
- if orig == nil {
- panic(fmt.Sprintf("%v: cannot instantiate %v", ix.Pos(), gtyp))
- }
-
- // evaluate arguments
- targs := check.typeList(ix.Indices)
- if targs == nil {
- def.setUnderlying(Typ[Invalid]) // avoid errors later due to lazy instantiation
- return Typ[Invalid]
- }
-
- // create the instance
- inst := check.instance(ix.Pos(), orig, targs, nil, check.context()).(*Named)
- def.setUnderlying(inst)
-
- // orig.tparams may not be set up, so we need to do expansion later.
- check.later(func() {
- // This is an instance from the source, not from recursive substitution,
- // and so it must be resolved during type-checking so that we can report
- // errors.
- check.recordInstance(ix.Orig, inst.TypeArgs().list(), inst)
-
- if check.validateTArgLen(ix.Pos(), inst.TypeParams().Len(), inst.TypeArgs().Len()) {
- if i, err := check.verify(ix.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), check.context()); err != nil {
- // best position for error reporting
- pos := ix.Pos()
- if i < len(ix.Indices) {
- pos = ix.Indices[i].Pos()
- }
- check.softErrorf(atPos(pos), InvalidTypeArg, err.Error())
- } else {
- check.mono.recordInstance(check.pkg, ix.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), ix.Indices)
- }
- }
-
- // TODO(rfindley): remove this call: we don't need to call validType here,
- // as cycles can only occur for types used inside a Named type declaration,
- // and so it suffices to call validType from declared types.
- check.validType(inst)
- }).describef(ix, "resolve instance %s", inst)
-
- return inst
-}
-
-// arrayLength type-checks the array length expression e
-// and returns the constant length >= 0, or a value < 0
-// to indicate an error (and thus an unknown length).
-func (check *Checker) arrayLength(e ast.Expr) int64 {
- // If e is an identifier, the array declaration might be an
- // attempt at a parameterized type declaration with missing
- // constraint. Provide an error message that mentions array
- // length.
- if name, _ := e.(*ast.Ident); name != nil {
- obj := check.lookup(name.Name)
- if obj == nil {
- check.errorf(name, InvalidArrayLen, "undefined array length %s or missing type constraint", name.Name)
- return -1
- }
- if _, ok := obj.(*Const); !ok {
- check.errorf(name, InvalidArrayLen, "invalid array length %s", name.Name)
- return -1
- }
- }
-
- var x operand
- check.expr(&x, e)
- if x.mode != constant_ {
- if x.mode != invalid {
- check.errorf(&x, InvalidArrayLen, "array length %s must be constant", &x)
- }
- return -1
- }
-
- if isUntyped(x.typ) || isInteger(x.typ) {
- if val := constant.ToInt(x.val); val.Kind() == constant.Int {
- if representableConst(val, check, Typ[Int], nil) {
- if n, ok := constant.Int64Val(val); ok && n >= 0 {
- return n
- }
- check.errorf(&x, InvalidArrayLen, "invalid array length %s", &x)
- return -1
- }
- }
- }
-
- check.errorf(&x, InvalidArrayLen, "array length %s must be integer", &x)
- return -1
-}
-
-// typeList provides the list of types corresponding to the incoming expression list.
-// If an error occurred, the result is nil, but all list elements were type-checked.
-func (check *Checker) typeList(list []ast.Expr) []Type {
- res := make([]Type, len(list)) // res != nil even if len(list) == 0
- for i, x := range list {
- t := check.varType(x)
- if t == Typ[Invalid] {
- res = nil
- }
- if res != nil {
- res[i] = t
- }
- }
- return res
-}
diff --git a/contrib/go/_std_1.20/src/go/types/unify.go b/contrib/go/_std_1.20/src/go/types/unify.go
deleted file mode 100644
index 602e304b4a..0000000000
--- a/contrib/go/_std_1.20/src/go/types/unify.go
+++ /dev/null
@@ -1,583 +0,0 @@
-// 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.
-
-// This file implements type unification.
-
-package types
-
-import (
- "bytes"
- "fmt"
- "strings"
-)
-
-// The unifier maintains two separate sets of type parameters x and y
-// which are used to resolve type parameters in the x and y arguments
-// provided to the unify call. For unidirectional unification, only
-// one of these sets (say x) is provided, and then type parameters are
-// only resolved for the x argument passed to unify, not the y argument
-// (even if that also contains possibly the same type parameters). This
-// is crucial to infer the type parameters of self-recursive calls:
-//
-// func f[P any](a P) { f(a) }
-//
-// For the call f(a) we want to infer that the type argument for P is P.
-// During unification, the parameter type P must be resolved to the type
-// parameter P ("x" side), but the argument type P must be left alone so
-// that unification resolves the type parameter P to P.
-//
-// For bidirectional unification, both sets are provided. This enables
-// unification to go from argument to parameter type and vice versa.
-// For constraint type inference, we use bidirectional unification
-// where both the x and y type parameters are identical. This is done
-// by setting up one of them (using init) and then assigning its value
-// to the other.
-
-const (
- // Upper limit for recursion depth. Used to catch infinite recursions
- // due to implementation issues (e.g., see issues #48619, #48656).
- unificationDepthLimit = 50
-
- // Whether to panic when unificationDepthLimit is reached.
- // If disabled, a recursion depth overflow results in a (quiet)
- // unification failure.
- panicAtUnificationDepthLimit = true
-
- // If enableCoreTypeUnification is set, unification will consider
- // the core types, if any, of non-local (unbound) type parameters.
- enableCoreTypeUnification = true
-
- // If traceInference is set, unification will print a trace of its operation.
- // Interpretation of trace:
- // x ≡ y attempt to unify types x and y
- // p ➞ y type parameter p is set to type y (p is inferred to be y)
- // p ⇄ q type parameters p and q match (p is inferred to be q and vice versa)
- // x ≢ y types x and y cannot be unified
- // [p, q, ...] ➞ [x, y, ...] mapping from type parameters to types
- traceInference = false
-)
-
-// A unifier maintains the current type parameters for x and y
-// and the respective types inferred for each type parameter.
-// A unifier is created by calling newUnifier.
-type unifier struct {
- exact bool
- x, y tparamsList // x and y must initialized via tparamsList.init
- types []Type // inferred types, shared by x and y
- depth int // recursion depth during unification
-}
-
-// newUnifier returns a new unifier.
-// If exact is set, unification requires unified types to match
-// exactly. If exact is not set, a named type's underlying type
-// is considered if unification would fail otherwise, and the
-// direction of channels is ignored.
-// TODO(gri) exact is not set anymore by a caller. Consider removing it.
-func newUnifier(exact bool) *unifier {
- u := &unifier{exact: exact}
- u.x.unifier = u
- u.y.unifier = u
- return u
-}
-
-// unify attempts to unify x and y and reports whether it succeeded.
-func (u *unifier) unify(x, y Type) bool {
- return u.nify(x, y, nil)
-}
-
-func (u *unifier) tracef(format string, args ...interface{}) {
- fmt.Println(strings.Repeat(". ", u.depth) + sprintf(nil, nil, true, format, args...))
-}
-
-// A tparamsList describes a list of type parameters and the types inferred for them.
-type tparamsList struct {
- unifier *unifier
- tparams []*TypeParam
- // For each tparams element, there is a corresponding type slot index in indices.
- // index < 0: unifier.types[-index-1] == nil
- // index == 0: no type slot allocated yet
- // index > 0: unifier.types[index-1] == typ
- // Joined tparams elements share the same type slot and thus have the same index.
- // By using a negative index for nil types we don't need to check unifier.types
- // to see if we have a type or not.
- indices []int // len(d.indices) == len(d.tparams)
-}
-
-// String returns a string representation for a tparamsList. For debugging.
-func (d *tparamsList) String() string {
- var buf bytes.Buffer
- w := newTypeWriter(&buf, nil)
- w.byte('[')
- for i, tpar := range d.tparams {
- if i > 0 {
- w.string(", ")
- }
- w.typ(tpar)
- w.string(": ")
- w.typ(d.at(i))
- }
- w.byte(']')
- return buf.String()
-}
-
-// init initializes d with the given type parameters.
-// The type parameters must be in the order in which they appear in their declaration
-// (this ensures that the tparams indices match the respective type parameter index).
-func (d *tparamsList) init(tparams []*TypeParam) {
- if len(tparams) == 0 {
- return
- }
- if debug {
- for i, tpar := range tparams {
- assert(i == tpar.index)
- }
- }
- d.tparams = tparams
- d.indices = make([]int, len(tparams))
-}
-
-// join unifies the i'th type parameter of x with the j'th type parameter of y.
-// If both type parameters already have a type associated with them and they are
-// not joined, join fails and returns false.
-func (u *unifier) join(i, j int) bool {
- if traceInference {
- u.tracef("%s ⇄ %s", u.x.tparams[i], u.y.tparams[j])
- }
- ti := u.x.indices[i]
- tj := u.y.indices[j]
- switch {
- case ti == 0 && tj == 0:
- // Neither type parameter has a type slot associated with them.
- // Allocate a new joined nil type slot (negative index).
- u.types = append(u.types, nil)
- u.x.indices[i] = -len(u.types)
- u.y.indices[j] = -len(u.types)
- case ti == 0:
- // The type parameter for x has no type slot yet. Use slot of y.
- u.x.indices[i] = tj
- case tj == 0:
- // The type parameter for y has no type slot yet. Use slot of x.
- u.y.indices[j] = ti
-
- // Both type parameters have a slot: ti != 0 && tj != 0.
- case ti == tj:
- // Both type parameters already share the same slot. Nothing to do.
- break
- case ti > 0 && tj > 0:
- // Both type parameters have (possibly different) inferred types. Cannot join.
- // TODO(gri) Should we check if types are identical? Investigate.
- return false
- case ti > 0:
- // Only the type parameter for x has an inferred type. Use x slot for y.
- u.y.setIndex(j, ti)
- // This case is handled like the default case.
- // case tj > 0:
- // // Only the type parameter for y has an inferred type. Use y slot for x.
- // u.x.setIndex(i, tj)
- default:
- // Neither type parameter has an inferred type. Use y slot for x
- // (or x slot for y, it doesn't matter).
- u.x.setIndex(i, tj)
- }
- return true
-}
-
-// If typ is a type parameter of d, index returns the type parameter index.
-// Otherwise, the result is < 0.
-func (d *tparamsList) index(typ Type) int {
- if tpar, ok := typ.(*TypeParam); ok {
- return tparamIndex(d.tparams, tpar)
- }
- return -1
-}
-
-// If tpar is a type parameter in list, tparamIndex returns the type parameter index.
-// Otherwise, the result is < 0. tpar must not be nil.
-func tparamIndex(list []*TypeParam, tpar *TypeParam) int {
- // Once a type parameter is bound its index is >= 0. However, there are some
- // code paths (namely tracing and type hashing) by which it is possible to
- // arrive here with a type parameter that has not been bound, hence the check
- // for 0 <= i below.
- // TODO(rfindley): investigate a better approach for guarding against using
- // unbound type parameters.
- if i := tpar.index; 0 <= i && i < len(list) && list[i] == tpar {
- return i
- }
- return -1
-}
-
-// setIndex sets the type slot index for the i'th type parameter
-// (and all its joined parameters) to tj. The type parameter
-// must have a (possibly nil) type slot associated with it.
-func (d *tparamsList) setIndex(i, tj int) {
- ti := d.indices[i]
- assert(ti != 0 && tj != 0)
- for k, tk := range d.indices {
- if tk == ti {
- d.indices[k] = tj
- }
- }
-}
-
-// at returns the type set for the i'th type parameter; or nil.
-func (d *tparamsList) at(i int) Type {
- if ti := d.indices[i]; ti > 0 {
- return d.unifier.types[ti-1]
- }
- return nil
-}
-
-// set sets the type typ for the i'th type parameter;
-// typ must not be nil and it must not have been set before.
-func (d *tparamsList) set(i int, typ Type) {
- assert(typ != nil)
- u := d.unifier
- if traceInference {
- u.tracef("%s ➞ %s", d.tparams[i], typ)
- }
- switch ti := d.indices[i]; {
- case ti < 0:
- u.types[-ti-1] = typ
- d.setIndex(i, -ti)
- case ti == 0:
- u.types = append(u.types, typ)
- d.indices[i] = len(u.types)
- default:
- panic("type already set")
- }
-}
-
-// unknowns returns the number of type parameters for which no type has been set yet.
-func (d *tparamsList) unknowns() int {
- n := 0
- for _, ti := range d.indices {
- if ti <= 0 {
- n++
- }
- }
- return n
-}
-
-// types returns the list of inferred types (via unification) for the type parameters
-// described by d, and an index. If all types were inferred, the returned index is < 0.
-// Otherwise, it is the index of the first type parameter which couldn't be inferred;
-// i.e., for which list[index] is nil.
-func (d *tparamsList) types() (list []Type, index int) {
- list = make([]Type, len(d.tparams))
- index = -1
- for i := range d.tparams {
- t := d.at(i)
- list[i] = t
- if index < 0 && t == nil {
- index = i
- }
- }
- return
-}
-
-func (u *unifier) nifyEq(x, y Type, p *ifacePair) bool {
- return x == y || u.nify(x, y, p)
-}
-
-// nify implements the core unification algorithm which is an
-// adapted version of Checker.identical. For changes to that
-// code the corresponding changes should be made here.
-// Must not be called directly from outside the unifier.
-func (u *unifier) nify(x, y Type, p *ifacePair) (result bool) {
- if traceInference {
- u.tracef("%s ≡ %s", x, y)
- }
-
- // Stop gap for cases where unification fails.
- if u.depth >= unificationDepthLimit {
- if traceInference {
- u.tracef("depth %d >= %d", u.depth, unificationDepthLimit)
- }
- if panicAtUnificationDepthLimit {
- panic("unification reached recursion depth limit")
- }
- return false
- }
- u.depth++
- defer func() {
- u.depth--
- if traceInference && !result {
- u.tracef("%s ≢ %s", x, y)
- }
- }()
-
- if !u.exact {
- // If exact unification is known to fail because we attempt to
- // match a type name against an unnamed type literal, consider
- // the underlying type of the named type.
- // (We use !hasName to exclude any type with a name, including
- // basic types and type parameters; the rest are unamed types.)
- if nx, _ := x.(*Named); nx != nil && !hasName(y) {
- if traceInference {
- u.tracef("under %s ≡ %s", nx, y)
- }
- return u.nify(nx.under(), y, p)
- } else if ny, _ := y.(*Named); ny != nil && !hasName(x) {
- if traceInference {
- u.tracef("%s ≡ under %s", x, ny)
- }
- return u.nify(x, ny.under(), p)
- }
- }
-
- // Cases where at least one of x or y is a type parameter.
- switch i, j := u.x.index(x), u.y.index(y); {
- case i >= 0 && j >= 0:
- // both x and y are type parameters
- if u.join(i, j) {
- return true
- }
- // both x and y have an inferred type - they must match
- return u.nifyEq(u.x.at(i), u.y.at(j), p)
-
- case i >= 0:
- // x is a type parameter, y is not
- if tx := u.x.at(i); tx != nil {
- return u.nifyEq(tx, y, p)
- }
- // otherwise, infer type from y
- u.x.set(i, y)
- return true
-
- case j >= 0:
- // y is a type parameter, x is not
- if ty := u.y.at(j); ty != nil {
- return u.nifyEq(x, ty, p)
- }
- // otherwise, infer type from x
- u.y.set(j, x)
- return true
- }
-
- // If we get here and x or y is a type parameter, they are type parameters
- // from outside our declaration list. Try to unify their core types, if any
- // (see issue #50755 for a test case).
- if enableCoreTypeUnification && !u.exact {
- if isTypeParam(x) && !hasName(y) {
- // When considering the type parameter for unification
- // we look at the adjusted core term (adjusted core type
- // with tilde information).
- // If the adjusted core type is a named type N; the
- // corresponding core type is under(N). Since !u.exact
- // and y doesn't have a name, unification will end up
- // comparing under(N) to y, so we can just use the core
- // type instead. And we can ignore the tilde because we
- // already look at the underlying types on both sides
- // and we have known types on both sides.
- // Optimization.
- if cx := coreType(x); cx != nil {
- if traceInference {
- u.tracef("core %s ≡ %s", x, y)
- }
- return u.nify(cx, y, p)
- }
- } else if isTypeParam(y) && !hasName(x) {
- // see comment above
- if cy := coreType(y); cy != nil {
- if traceInference {
- u.tracef("%s ≡ core %s", x, y)
- }
- return u.nify(x, cy, p)
- }
- }
- }
-
- // For type unification, do not shortcut (x == y) for identical
- // types. Instead keep comparing them element-wise to unify the
- // matching (and equal type parameter types). A simple test case
- // where this matters is: func f[P any](a P) { f(a) } .
-
- switch x := x.(type) {
- case *Basic:
- // Basic types are singletons except for the rune and byte
- // aliases, thus we cannot solely rely on the x == y check
- // above. See also comment in TypeName.IsAlias.
- if y, ok := y.(*Basic); ok {
- return x.kind == y.kind
- }
-
- case *Array:
- // Two array types are identical if they have identical element types
- // and the same array length.
- if y, ok := y.(*Array); ok {
- // If one or both array lengths are unknown (< 0) due to some error,
- // assume they are the same to avoid spurious follow-on errors.
- return (x.len < 0 || y.len < 0 || x.len == y.len) && u.nify(x.elem, y.elem, p)
- }
-
- case *Slice:
- // Two slice types are identical if they have identical element types.
- if y, ok := y.(*Slice); ok {
- return u.nify(x.elem, y.elem, p)
- }
-
- case *Struct:
- // Two struct types are identical if they have the same sequence of fields,
- // and if corresponding fields have the same names, and identical types,
- // and identical tags. Two embedded fields are considered to have the same
- // name. Lower-case field names from different packages are always different.
- if y, ok := y.(*Struct); ok {
- if x.NumFields() == y.NumFields() {
- for i, f := range x.fields {
- g := y.fields[i]
- if f.embedded != g.embedded ||
- x.Tag(i) != y.Tag(i) ||
- !f.sameId(g.pkg, g.name) ||
- !u.nify(f.typ, g.typ, p) {
- return false
- }
- }
- return true
- }
- }
-
- case *Pointer:
- // Two pointer types are identical if they have identical base types.
- if y, ok := y.(*Pointer); ok {
- return u.nify(x.base, y.base, p)
- }
-
- case *Tuple:
- // Two tuples types are identical if they have the same number of elements
- // and corresponding elements have identical types.
- if y, ok := y.(*Tuple); ok {
- if x.Len() == y.Len() {
- if x != nil {
- for i, v := range x.vars {
- w := y.vars[i]
- if !u.nify(v.typ, w.typ, p) {
- return false
- }
- }
- }
- return true
- }
- }
-
- case *Signature:
- // Two function types are identical if they have the same number of parameters
- // and result values, corresponding parameter and result types are identical,
- // and either both functions are variadic or neither is. Parameter and result
- // names are not required to match.
- // TODO(gri) handle type parameters or document why we can ignore them.
- if y, ok := y.(*Signature); ok {
- return x.variadic == y.variadic &&
- u.nify(x.params, y.params, p) &&
- u.nify(x.results, y.results, p)
- }
-
- case *Interface:
- // Two interface types are identical if they have the same set of methods with
- // the same names and identical function types. Lower-case method names from
- // different packages are always different. The order of the methods is irrelevant.
- if y, ok := y.(*Interface); ok {
- xset := x.typeSet()
- yset := y.typeSet()
- if xset.comparable != yset.comparable {
- return false
- }
- if !xset.terms.equal(yset.terms) {
- return false
- }
- a := xset.methods
- b := yset.methods
- if len(a) == len(b) {
- // Interface types are the only types where cycles can occur
- // that are not "terminated" via named types; and such cycles
- // can only be created via method parameter types that are
- // anonymous interfaces (directly or indirectly) embedding
- // the current interface. Example:
- //
- // type T interface {
- // m() interface{T}
- // }
- //
- // If two such (differently named) interfaces are compared,
- // endless recursion occurs if the cycle is not detected.
- //
- // If x and y were compared before, they must be equal
- // (if they were not, the recursion would have stopped);
- // search the ifacePair stack for the same pair.
- //
- // This is a quadratic algorithm, but in practice these stacks
- // are extremely short (bounded by the nesting depth of interface
- // type declarations that recur via parameter types, an extremely
- // rare occurrence). An alternative implementation might use a
- // "visited" map, but that is probably less efficient overall.
- q := &ifacePair{x, y, p}
- for p != nil {
- if p.identical(q) {
- return true // same pair was compared before
- }
- p = p.prev
- }
- if debug {
- assertSortedMethods(a)
- assertSortedMethods(b)
- }
- for i, f := range a {
- g := b[i]
- if f.Id() != g.Id() || !u.nify(f.typ, g.typ, q) {
- return false
- }
- }
- return true
- }
- }
-
- case *Map:
- // Two map types are identical if they have identical key and value types.
- if y, ok := y.(*Map); ok {
- return u.nify(x.key, y.key, p) && u.nify(x.elem, y.elem, p)
- }
-
- case *Chan:
- // Two channel types are identical if they have identical value types.
- if y, ok := y.(*Chan); ok {
- return (!u.exact || x.dir == y.dir) && u.nify(x.elem, y.elem, p)
- }
-
- case *Named:
- // TODO(gri) This code differs now from the parallel code in Checker.identical. Investigate.
- if y, ok := y.(*Named); ok {
- xargs := x.TypeArgs().list()
- yargs := y.TypeArgs().list()
-
- if len(xargs) != len(yargs) {
- return false
- }
-
- // TODO(gri) This is not always correct: two types may have the same names
- // in the same package if one of them is nested in a function.
- // Extremely unlikely but we need an always correct solution.
- if x.obj.pkg == y.obj.pkg && x.obj.name == y.obj.name {
- for i, x := range xargs {
- if !u.nify(x, yargs[i], p) {
- return false
- }
- }
- return true
- }
- }
-
- case *TypeParam:
- // Two type parameters (which are not part of the type parameters of the
- // enclosing type as those are handled in the beginning of this function)
- // are identical if they originate in the same declaration.
- return x == y
-
- case nil:
- // avoid a crash in case of nil type
-
- default:
- panic(sprintf(nil, nil, true, "u.nify(%s, %s), u.x.tparams = %s", x, y, u.x.tparams))
- }
-
- return false
-}
diff --git a/contrib/go/_std_1.20/src/go/types/union.go b/contrib/go/_std_1.20/src/go/types/union.go
deleted file mode 100644
index 9509afe7a4..0000000000
--- a/contrib/go/_std_1.20/src/go/types/union.go
+++ /dev/null
@@ -1,200 +0,0 @@
-// 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 types
-
-import (
- "go/ast"
- "go/token"
- . "internal/types/errors"
-)
-
-// ----------------------------------------------------------------------------
-// API
-
-// A Union represents a union of terms embedded in an interface.
-type Union struct {
- terms []*Term // list of syntactical terms (not a canonicalized termlist)
-}
-
-// NewUnion returns a new Union type with the given terms.
-// It is an error to create an empty union; they are syntactically not possible.
-func NewUnion(terms []*Term) *Union {
- if len(terms) == 0 {
- panic("empty union")
- }
- return &Union{terms}
-}
-
-func (u *Union) Len() int { return len(u.terms) }
-func (u *Union) Term(i int) *Term { return u.terms[i] }
-
-func (u *Union) Underlying() Type { return u }
-func (u *Union) String() string { return TypeString(u, nil) }
-
-// A Term represents a term in a Union.
-type Term term
-
-// NewTerm returns a new union term.
-func NewTerm(tilde bool, typ Type) *Term { return &Term{tilde, typ} }
-
-func (t *Term) Tilde() bool { return t.tilde }
-func (t *Term) Type() Type { return t.typ }
-func (t *Term) String() string { return (*term)(t).String() }
-
-// ----------------------------------------------------------------------------
-// Implementation
-
-// Avoid excessive type-checking times due to quadratic termlist operations.
-const maxTermCount = 100
-
-// parseUnion parses uexpr as a union of expressions.
-// The result is a Union type, or Typ[Invalid] for some errors.
-func parseUnion(check *Checker, uexpr ast.Expr) Type {
- blist, tlist := flattenUnion(nil, uexpr)
- assert(len(blist) == len(tlist)-1)
-
- var terms []*Term
-
- var u Type
- for i, x := range tlist {
- term := parseTilde(check, x)
- if len(tlist) == 1 && !term.tilde {
- // Single type. Ok to return early because all relevant
- // checks have been performed in parseTilde (no need to
- // run through term validity check below).
- return term.typ // typ already recorded through check.typ in parseTilde
- }
- if len(terms) >= maxTermCount {
- if u != Typ[Invalid] {
- check.errorf(x, InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
- u = Typ[Invalid]
- }
- } else {
- terms = append(terms, term)
- u = &Union{terms}
- }
-
- if i > 0 {
- check.recordTypeAndValue(blist[i-1], typexpr, u, nil)
- }
- }
-
- if u == Typ[Invalid] {
- return u
- }
-
- // Check validity of terms.
- // Do this check later because it requires types to be set up.
- // Note: This is a quadratic algorithm, but unions tend to be short.
- check.later(func() {
- for i, t := range terms {
- if t.typ == Typ[Invalid] {
- continue
- }
-
- u := under(t.typ)
- f, _ := u.(*Interface)
- if t.tilde {
- if f != nil {
- check.errorf(tlist[i], InvalidUnion, "invalid use of ~ (%s is an interface)", t.typ)
- continue // don't report another error for t
- }
-
- if !Identical(u, t.typ) {
- check.errorf(tlist[i], InvalidUnion, "invalid use of ~ (underlying type of %s is %s)", t.typ, u)
- continue
- }
- }
-
- // Stand-alone embedded interfaces are ok and are handled by the single-type case
- // in the beginning. Embedded interfaces with tilde are excluded above. If we reach
- // here, we must have at least two terms in the syntactic term list (but not necessarily
- // in the term list of the union's type set).
- if f != nil {
- tset := f.typeSet()
- switch {
- case tset.NumMethods() != 0:
- check.errorf(tlist[i], InvalidUnion, "cannot use %s in union (%s contains methods)", t, t)
- case t.typ == universeComparable.Type():
- check.error(tlist[i], InvalidUnion, "cannot use comparable in union")
- case tset.comparable:
- check.errorf(tlist[i], InvalidUnion, "cannot use %s in union (%s embeds comparable)", t, t)
- }
- continue // terms with interface types are not subject to the no-overlap rule
- }
-
- // Report overlapping (non-disjoint) terms such as
- // a|a, a|~a, ~a|~a, and ~a|A (where under(A) == a).
- if j := overlappingTerm(terms[:i], t); j >= 0 {
- check.softErrorf(tlist[i], InvalidUnion, "overlapping terms %s and %s", t, terms[j])
- }
- }
- }).describef(uexpr, "check term validity %s", uexpr)
-
- return u
-}
-
-func parseTilde(check *Checker, tx ast.Expr) *Term {
- x := tx
- var tilde bool
- if op, _ := x.(*ast.UnaryExpr); op != nil && op.Op == token.TILDE {
- x = op.X
- tilde = true
- }
- typ := check.typ(x)
- // Embedding stand-alone type parameters is not permitted (issue #47127).
- // We don't need this restriction anymore if we make the underlying type of a type
- // parameter its constraint interface: if we embed a lone type parameter, we will
- // simply use its underlying type (like we do for other named, embedded interfaces),
- // and since the underlying type is an interface the embedding is well defined.
- if isTypeParam(typ) {
- if tilde {
- check.errorf(x, MisplacedTypeParam, "type in term %s cannot be a type parameter", tx)
- } else {
- check.error(x, MisplacedTypeParam, "term cannot be a type parameter")
- }
- typ = Typ[Invalid]
- }
- term := NewTerm(tilde, typ)
- if tilde {
- check.recordTypeAndValue(tx, typexpr, &Union{[]*Term{term}}, nil)
- }
- return term
-}
-
-// overlappingTerm reports the index of the term x in terms which is
-// overlapping (not disjoint) from y. The result is < 0 if there is no
-// such term. The type of term y must not be an interface, and terms
-// with an interface type are ignored in the terms list.
-func overlappingTerm(terms []*Term, y *Term) int {
- assert(!IsInterface(y.typ))
- for i, x := range terms {
- if IsInterface(x.typ) {
- continue
- }
- // disjoint requires non-nil, non-top arguments,
- // and non-interface types as term types.
- if debug {
- if x == nil || x.typ == nil || y == nil || y.typ == nil {
- panic("empty or top union term")
- }
- }
- if !(*term)(x).disjoint((*term)(y)) {
- return i
- }
- }
- return -1
-}
-
-// flattenUnion walks a union type expression of the form A | B | C | ...,
-// extracting both the binary exprs (blist) and leaf types (tlist).
-func flattenUnion(list []ast.Expr, x ast.Expr) (blist, tlist []ast.Expr) {
- if o, _ := x.(*ast.BinaryExpr); o != nil && o.Op == token.OR {
- blist, tlist = flattenUnion(list, o.X)
- blist = append(blist, o)
- x = o.Y
- }
- return blist, append(tlist, x)
-}
diff --git a/contrib/go/_std_1.20/src/go/types/universe.go b/contrib/go/_std_1.20/src/go/types/universe.go
deleted file mode 100644
index 9103fca713..0000000000
--- a/contrib/go/_std_1.20/src/go/types/universe.go
+++ /dev/null
@@ -1,284 +0,0 @@
-// Copyright 2011 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.
-
-// This file sets up the universe scope and the unsafe package.
-
-package types
-
-import (
- "go/constant"
- "go/token"
- "strings"
-)
-
-// The Universe scope contains all predeclared objects of Go.
-// It is the outermost scope of any chain of nested scopes.
-var Universe *Scope
-
-// The Unsafe package is the package returned by an importer
-// for the import path "unsafe".
-var Unsafe *Package
-
-var (
- universeIota Object
- universeByte Type // uint8 alias, but has name "byte"
- universeRune Type // int32 alias, but has name "rune"
- universeAny Object
- universeError Type
- universeComparable Object
-)
-
-// Typ contains the predeclared *Basic types indexed by their
-// corresponding BasicKind.
-//
-// The *Basic type for Typ[Byte] will have the name "uint8".
-// Use Universe.Lookup("byte").Type() to obtain the specific
-// alias basic type named "byte" (and analogous for "rune").
-var Typ = []*Basic{
- Invalid: {Invalid, 0, "invalid type"},
-
- Bool: {Bool, IsBoolean, "bool"},
- Int: {Int, IsInteger, "int"},
- Int8: {Int8, IsInteger, "int8"},
- Int16: {Int16, IsInteger, "int16"},
- Int32: {Int32, IsInteger, "int32"},
- Int64: {Int64, IsInteger, "int64"},
- Uint: {Uint, IsInteger | IsUnsigned, "uint"},
- Uint8: {Uint8, IsInteger | IsUnsigned, "uint8"},
- Uint16: {Uint16, IsInteger | IsUnsigned, "uint16"},
- Uint32: {Uint32, IsInteger | IsUnsigned, "uint32"},
- Uint64: {Uint64, IsInteger | IsUnsigned, "uint64"},
- Uintptr: {Uintptr, IsInteger | IsUnsigned, "uintptr"},
- Float32: {Float32, IsFloat, "float32"},
- Float64: {Float64, IsFloat, "float64"},
- Complex64: {Complex64, IsComplex, "complex64"},
- Complex128: {Complex128, IsComplex, "complex128"},
- String: {String, IsString, "string"},
- UnsafePointer: {UnsafePointer, 0, "Pointer"},
-
- UntypedBool: {UntypedBool, IsBoolean | IsUntyped, "untyped bool"},
- UntypedInt: {UntypedInt, IsInteger | IsUntyped, "untyped int"},
- UntypedRune: {UntypedRune, IsInteger | IsUntyped, "untyped rune"},
- UntypedFloat: {UntypedFloat, IsFloat | IsUntyped, "untyped float"},
- UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"},
- UntypedString: {UntypedString, IsString | IsUntyped, "untyped string"},
- UntypedNil: {UntypedNil, IsUntyped, "untyped nil"},
-}
-
-var aliases = [...]*Basic{
- {Byte, IsInteger | IsUnsigned, "byte"},
- {Rune, IsInteger, "rune"},
-}
-
-func defPredeclaredTypes() {
- for _, t := range Typ {
- def(NewTypeName(token.NoPos, nil, t.name, t))
- }
- for _, t := range aliases {
- def(NewTypeName(token.NoPos, nil, t.name, t))
- }
-
- // type any = interface{}
- // Note: don't use &emptyInterface for the type of any. Using a unique
- // pointer allows us to detect any and format it as "any" rather than
- // interface{}, which clarifies user-facing error messages significantly.
- def(NewTypeName(token.NoPos, nil, "any", &Interface{complete: true, tset: &topTypeSet}))
-
- // type error interface{ Error() string }
- {
- obj := NewTypeName(token.NoPos, nil, "error", nil)
- obj.setColor(black)
- typ := NewNamed(obj, nil, nil)
-
- // error.Error() string
- recv := NewVar(token.NoPos, nil, "", typ)
- res := NewVar(token.NoPos, nil, "", Typ[String])
- sig := NewSignatureType(recv, nil, nil, nil, NewTuple(res), false)
- err := NewFunc(token.NoPos, nil, "Error", sig)
-
- // interface{ Error() string }
- ityp := &Interface{methods: []*Func{err}, complete: true}
- computeInterfaceTypeSet(nil, token.NoPos, ityp) // prevent races due to lazy computation of tset
-
- typ.SetUnderlying(ityp)
- def(obj)
- }
-
- // type comparable interface{} // marked as comparable
- {
- obj := NewTypeName(token.NoPos, nil, "comparable", nil)
- obj.setColor(black)
- typ := NewNamed(obj, nil, nil)
-
- // interface{} // marked as comparable
- ityp := &Interface{complete: true, tset: &_TypeSet{nil, allTermlist, true}}
-
- typ.SetUnderlying(ityp)
- def(obj)
- }
-}
-
-var predeclaredConsts = [...]struct {
- name string
- kind BasicKind
- val constant.Value
-}{
- {"true", UntypedBool, constant.MakeBool(true)},
- {"false", UntypedBool, constant.MakeBool(false)},
- {"iota", UntypedInt, constant.MakeInt64(0)},
-}
-
-func defPredeclaredConsts() {
- for _, c := range predeclaredConsts {
- def(NewConst(token.NoPos, nil, c.name, Typ[c.kind], c.val))
- }
-}
-
-func defPredeclaredNil() {
- def(&Nil{object{name: "nil", typ: Typ[UntypedNil], color_: black}})
-}
-
-// A builtinId is the id of a builtin function.
-type builtinId int
-
-const (
- // universe scope
- _Append builtinId = iota
- _Cap
- _Clear
- _Close
- _Complex
- _Copy
- _Delete
- _Imag
- _Len
- _Make
- _New
- _Panic
- _Print
- _Println
- _Real
- _Recover
-
- // package unsafe
- _Add
- _Alignof
- _Offsetof
- _Sizeof
- _Slice
- _SliceData
- _String
- _StringData
-
- // testing support
- _Assert
- _Trace
-)
-
-var predeclaredFuncs = [...]struct {
- name string
- nargs int
- variadic bool
- kind exprKind
-}{
- _Append: {"append", 1, true, expression},
- _Cap: {"cap", 1, false, expression},
- _Clear: {"clear", 1, false, statement},
- _Close: {"close", 1, false, statement},
- _Complex: {"complex", 2, false, expression},
- _Copy: {"copy", 2, false, statement},
- _Delete: {"delete", 2, false, statement},
- _Imag: {"imag", 1, false, expression},
- _Len: {"len", 1, false, expression},
- _Make: {"make", 1, true, expression},
- _New: {"new", 1, false, expression},
- _Panic: {"panic", 1, false, statement},
- _Print: {"print", 0, true, statement},
- _Println: {"println", 0, true, statement},
- _Real: {"real", 1, false, expression},
- _Recover: {"recover", 0, false, statement},
-
- _Add: {"Add", 2, false, expression},
- _Alignof: {"Alignof", 1, false, expression},
- _Offsetof: {"Offsetof", 1, false, expression},
- _Sizeof: {"Sizeof", 1, false, expression},
- _Slice: {"Slice", 2, false, expression},
- _SliceData: {"SliceData", 1, false, expression},
- _String: {"String", 2, false, expression},
- _StringData: {"StringData", 1, false, expression},
-
- _Assert: {"assert", 1, false, statement},
- _Trace: {"trace", 0, true, statement},
-}
-
-func defPredeclaredFuncs() {
- for i := range predeclaredFuncs {
- id := builtinId(i)
- if id == _Assert || id == _Trace {
- continue // only define these in testing environment
- }
- def(newBuiltin(id))
- }
-}
-
-// DefPredeclaredTestFuncs defines the assert and trace built-ins.
-// These built-ins are intended for debugging and testing of this
-// package only.
-func DefPredeclaredTestFuncs() {
- if Universe.Lookup("assert") != nil {
- return // already defined
- }
- def(newBuiltin(_Assert))
- def(newBuiltin(_Trace))
-}
-
-func init() {
- Universe = NewScope(nil, token.NoPos, token.NoPos, "universe")
- Unsafe = NewPackage("unsafe", "unsafe")
- Unsafe.complete = true
-
- defPredeclaredTypes()
- defPredeclaredConsts()
- defPredeclaredNil()
- defPredeclaredFuncs()
-
- universeIota = Universe.Lookup("iota")
- universeByte = Universe.Lookup("byte").Type()
- universeRune = Universe.Lookup("rune").Type()
- universeAny = Universe.Lookup("any")
- universeError = Universe.Lookup("error").Type()
- universeComparable = Universe.Lookup("comparable")
-}
-
-// Objects with names containing blanks are internal and not entered into
-// a scope. Objects with exported names are inserted in the unsafe package
-// scope; other objects are inserted in the universe scope.
-func def(obj Object) {
- assert(obj.color() == black)
- name := obj.Name()
- if strings.Contains(name, " ") {
- return // nothing to do
- }
- // fix Obj link for named types
- if typ, _ := obj.Type().(*Named); typ != nil {
- typ.obj = obj.(*TypeName)
- }
- // exported identifiers go into package unsafe
- scope := Universe
- if obj.Exported() {
- scope = Unsafe.scope
- // set Pkg field
- switch obj := obj.(type) {
- case *TypeName:
- obj.pkg = Unsafe
- case *Builtin:
- obj.pkg = Unsafe
- default:
- unreachable()
- }
- }
- if scope.Insert(obj) != nil {
- panic("double declaration of predeclared identifier")
- }
-}
diff --git a/contrib/go/_std_1.20/src/go/types/validtype.go b/contrib/go/_std_1.20/src/go/types/validtype.go
deleted file mode 100644
index d62c3983f0..0000000000
--- a/contrib/go/_std_1.20/src/go/types/validtype.go
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2022 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 types
-
-// validType verifies that the given type does not "expand" indefinitely
-// producing a cycle in the type graph.
-// (Cycles involving alias types, as in "type A = [10]A" are detected
-// earlier, via the objDecl cycle detection mechanism.)
-func (check *Checker) validType(typ *Named) {
- check.validType0(typ, nil, nil)
-}
-
-// validType0 checks if the given type is valid. If typ is a type parameter
-// its value is looked up in the type argument list of the instantiated
-// (enclosing) type, if it exists. Otherwise the type parameter must be from
-// an enclosing function and can be ignored.
-// The nest list describes the stack (the "nest in memory") of types which
-// contain (or embed in the case of interfaces) other types. For instance, a
-// struct named S which contains a field of named type F contains (the memory
-// of) F in S, leading to the nest S->F. If a type appears in its own nest
-// (say S->F->S) we have an invalid recursive type. The path list is the full
-// path of named types in a cycle, it is only needed for error reporting.
-func (check *Checker) validType0(typ Type, nest, path []*Named) bool {
- switch t := typ.(type) {
- case nil:
- // We should never see a nil type but be conservative and panic
- // only in debug mode.
- if debug {
- panic("validType0(nil)")
- }
-
- case *Array:
- return check.validType0(t.elem, nest, path)
-
- case *Struct:
- for _, f := range t.fields {
- if !check.validType0(f.typ, nest, path) {
- return false
- }
- }
-
- case *Union:
- for _, t := range t.terms {
- if !check.validType0(t.typ, nest, path) {
- return false
- }
- }
-
- case *Interface:
- for _, etyp := range t.embeddeds {
- if !check.validType0(etyp, nest, path) {
- return false
- }
- }
-
- case *Named:
- // Exit early if we already know t is valid.
- // This is purely an optimization but it prevents excessive computation
- // times in pathological cases such as testdata/fixedbugs/issue6977.go.
- // (Note: The valids map could also be allocated locally, once for each
- // validType call.)
- if check.valids.lookup(t) != nil {
- break
- }
-
- // Don't report a 2nd error if we already know the type is invalid
- // (e.g., if a cycle was detected earlier, via under).
- // Note: ensure that t.orig is fully resolved by calling Underlying().
- if t.Underlying() == Typ[Invalid] {
- return false
- }
-
- // If the current type t is also found in nest, (the memory of) t is
- // embedded in itself, indicating an invalid recursive type.
- for _, e := range nest {
- if Identical(e, t) {
- // We have a cycle. If t != t.Origin() then t is an instance of
- // the generic type t.Origin(). Because t is in the nest, t must
- // occur within the definition (RHS) of the generic type t.Origin(),
- // directly or indirectly, after expansion of the RHS.
- // Therefore t.Origin() must be invalid, no matter how it is
- // instantiated since the instantiation t of t.Origin() happens
- // inside t.Origin()'s RHS and thus is always the same and always
- // present.
- // Therefore we can mark the underlying of both t and t.Origin()
- // as invalid. If t is not an instance of a generic type, t and
- // t.Origin() are the same.
- // Furthermore, because we check all types in a package for validity
- // before type checking is complete, any exported type that is invalid
- // will have an invalid underlying type and we can't reach here with
- // such a type (invalid types are excluded above).
- // Thus, if we reach here with a type t, both t and t.Origin() (if
- // different in the first place) must be from the current package;
- // they cannot have been imported.
- // Therefore it is safe to change their underlying types; there is
- // no chance for a race condition (the types of the current package
- // are not yet available to other goroutines).
- assert(t.obj.pkg == check.pkg)
- assert(t.Origin().obj.pkg == check.pkg)
- t.underlying = Typ[Invalid]
- t.Origin().underlying = Typ[Invalid]
-
- // Find the starting point of the cycle and report it.
- // Because each type in nest must also appear in path (see invariant below),
- // type t must be in path since it was found in nest. But not every type in path
- // is in nest. Specifically t may appear in path with an earlier index than the
- // index of t in nest. Search again.
- for start, p := range path {
- if Identical(p, t) {
- check.cycleError(makeObjList(path[start:]))
- return false
- }
- }
- panic("cycle start not found")
- }
- }
-
- // No cycle was found. Check the RHS of t.
- // Every type added to nest is also added to path; thus every type that is in nest
- // must also be in path (invariant). But not every type in path is in nest, since
- // nest may be pruned (see below, *TypeParam case).
- if !check.validType0(t.Origin().fromRHS, append(nest, t), append(path, t)) {
- return false
- }
-
- check.valids.add(t) // t is valid
-
- case *TypeParam:
- // A type parameter stands for the type (argument) it was instantiated with.
- // Check the corresponding type argument for validity if we are in an
- // instantiated type.
- if len(nest) > 0 {
- inst := nest[len(nest)-1] // the type instance
- // Find the corresponding type argument for the type parameter
- // and proceed with checking that type argument.
- for i, tparam := range inst.TypeParams().list() {
- // The type parameter and type argument lists should
- // match in length but be careful in case of errors.
- if t == tparam && i < inst.TypeArgs().Len() {
- targ := inst.TypeArgs().At(i)
- // The type argument must be valid in the enclosing
- // type (where inst was instantiated), hence we must
- // check targ's validity in the type nest excluding
- // the current (instantiated) type (see the example
- // at the end of this file).
- // For error reporting we keep the full path.
- return check.validType0(targ, nest[:len(nest)-1], path)
- }
- }
- }
- }
-
- return true
-}
-
-// makeObjList returns the list of type name objects for the given
-// list of named types.
-func makeObjList(tlist []*Named) []Object {
- olist := make([]Object, len(tlist))
- for i, t := range tlist {
- olist[i] = t.obj
- }
- return olist
-}
-
-// Here is an example illustrating why we need to exclude the
-// instantiated type from nest when evaluating the validity of
-// a type parameter. Given the declarations
-//
-// var _ A[A[string]]
-//
-// type A[P any] struct { _ B[P] }
-// type B[P any] struct { _ P }
-//
-// we want to determine if the type A[A[string]] is valid.
-// We start evaluating A[A[string]] outside any type nest:
-//
-// A[A[string]]
-// nest =
-// path =
-//
-// The RHS of A is now evaluated in the A[A[string]] nest:
-//
-// struct{_ B[P₁]}
-// nest = A[A[string]]
-// path = A[A[string]]
-//
-// The struct has a single field of type B[P₁] with which
-// we continue:
-//
-// B[P₁]
-// nest = A[A[string]]
-// path = A[A[string]]
-//
-// struct{_ P₂}
-// nest = A[A[string]]->B[P]
-// path = A[A[string]]->B[P]
-//
-// Eventually we reach the type parameter P of type B (P₂):
-//
-// P₂
-// nest = A[A[string]]->B[P]
-// path = A[A[string]]->B[P]
-//
-// The type argument for P of B is the type parameter P of A (P₁).
-// It must be evaluated in the type nest that existed when B was
-// instantiated:
-//
-// P₁
-// nest = A[A[string]] <== type nest at B's instantiation time
-// path = A[A[string]]->B[P]
-//
-// If we'd use the current nest it would correspond to the path
-// which will be wrong as we will see shortly. P's type argument
-// is A[string], which again must be evaluated in the type nest
-// that existed when A was instantiated with A[string]. That type
-// nest is empty:
-//
-// A[string]
-// nest = <== type nest at A's instantiation time
-// path = A[A[string]]->B[P]
-//
-// Evaluation then proceeds as before for A[string]:
-//
-// struct{_ B[P₁]}
-// nest = A[string]
-// path = A[A[string]]->B[P]->A[string]
-//
-// Now we reach B[P] again. If we had not adjusted nest, it would
-// correspond to path, and we would find B[P] in nest, indicating
-// a cycle, which would clearly be wrong since there's no cycle in
-// A[string]:
-//
-// B[P₁]
-// nest = A[string]
-// path = A[A[string]]->B[P]->A[string] <== path contains B[P]!
-//
-// But because we use the correct type nest, evaluation proceeds without
-// errors and we get the evaluation sequence:
-//
-// struct{_ P₂}
-// nest = A[string]->B[P]
-// path = A[A[string]]->B[P]->A[string]->B[P]
-// P₂
-// nest = A[string]->B[P]
-// path = A[A[string]]->B[P]->A[string]->B[P]
-// P₁
-// nest = A[string]
-// path = A[A[string]]->B[P]->A[string]->B[P]
-// string
-// nest =
-// path = A[A[string]]->B[P]->A[string]->B[P]
-//
-// At this point we're done and A[A[string]] and is valid.
diff --git a/contrib/go/_std_1.20/src/go/types/version.go b/contrib/go/_std_1.20/src/go/types/version.go
deleted file mode 100644
index 3958ec922c..0000000000
--- a/contrib/go/_std_1.20/src/go/types/version.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// 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 types
-
-import (
- "fmt"
- "go/ast"
- "go/token"
- . "internal/types/errors"
- "regexp"
- "strconv"
- "strings"
-)
-
-// langCompat reports an error if the representation of a numeric
-// literal is not compatible with the current language version.
-func (check *Checker) langCompat(lit *ast.BasicLit) {
- s := lit.Value
- if len(s) <= 2 || check.allowVersion(check.pkg, 1, 13) {
- return
- }
- // len(s) > 2
- if strings.Contains(s, "_") {
- check.error(lit, UnsupportedFeature, "underscores in numeric literals requires go1.13 or later")
- return
- }
- if s[0] != '0' {
- return
- }
- radix := s[1]
- if radix == 'b' || radix == 'B' {
- check.error(lit, UnsupportedFeature, "binary literals requires go1.13 or later")
- return
- }
- if radix == 'o' || radix == 'O' {
- check.error(lit, UnsupportedFeature, "0o/0O-style octal literals requires go1.13 or later")
- return
- }
- if lit.Kind != token.INT && (radix == 'x' || radix == 'X') {
- check.error(lit, UnsupportedFeature, "hexadecimal floating-point literals requires go1.13 or later")
- }
-}
-
-// allowVersion reports whether the given package
-// is allowed to use version major.minor.
-func (check *Checker) allowVersion(pkg *Package, major, minor int) bool {
- // We assume that imported packages have all been checked,
- // so we only have to check for the local package.
- if pkg != check.pkg {
- return true
- }
- ma, mi := check.version.major, check.version.minor
- return ma == 0 && mi == 0 || ma > major || ma == major && mi >= minor
-}
-
-type version struct {
- major, minor int
-}
-
-// parseGoVersion parses a Go version string (such as "go1.12")
-// and returns the version, or an error. If s is the empty
-// string, the version is 0.0.
-func parseGoVersion(s string) (v version, err error) {
- if s == "" {
- return
- }
- matches := goVersionRx.FindStringSubmatch(s)
- if matches == nil {
- err = fmt.Errorf(`should be something like "go1.12"`)
- return
- }
- v.major, err = strconv.Atoi(matches[1])
- if err != nil {
- return
- }
- v.minor, err = strconv.Atoi(matches[2])
- return
-}
-
-// goVersionRx matches a Go version string, e.g. "go1.12".
-var goVersionRx = regexp.MustCompile(`^go([1-9]\d*)\.(0|[1-9]\d*)$`)
diff --git a/contrib/go/_std_1.20/src/go/types/ya.make b/contrib/go/_std_1.20/src/go/types/ya.make
deleted file mode 100644
index b26fa0770a..0000000000
--- a/contrib/go/_std_1.20/src/go/types/ya.make
+++ /dev/null
@@ -1,63 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- api.go
- array.go
- assignments.go
- basic.go
- builtins.go
- call.go
- chan.go
- check.go
- context.go
- conversions.go
- decl.go
- errors.go
- eval.go
- expr.go
- exprstring.go
- gccgosizes.go
- index.go
- infer.go
- initorder.go
- instantiate.go
- interface.go
- labels.go
- lookup.go
- map.go
- methodset.go
- mono.go
- named.go
- object.go
- objset.go
- operand.go
- package.go
- pointer.go
- predicates.go
- resolver.go
- return.go
- scope.go
- selection.go
- signature.go
- sizes.go
- slice.go
- stmt.go
- struct.go
- subst.go
- termlist.go
- tuple.go
- type.go
- typelists.go
- typeparam.go
- typeset.go
- typestring.go
- typeterm.go
- typexpr.go
- unify.go
- union.go
- universe.go
- validtype.go
- version.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/hash/adler32/ya.make b/contrib/go/_std_1.20/src/hash/adler32/ya.make
deleted file mode 100644
index 0533de83ae..0000000000
--- a/contrib/go/_std_1.20/src/hash/adler32/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- adler32.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/hash/crc32/ya.make b/contrib/go/_std_1.20/src/hash/crc32/ya.make
deleted file mode 100644
index 0d06b481d0..0000000000
--- a/contrib/go/_std_1.20/src/hash/crc32/ya.make
+++ /dev/null
@@ -1,22 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- crc32.go
- crc32_generic.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- crc32_arm64.go
- crc32_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- crc32_amd64.go
- crc32_amd64.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/hash/crc64/ya.make b/contrib/go/_std_1.20/src/hash/crc64/ya.make
deleted file mode 100644
index 1918694a61..0000000000
--- a/contrib/go/_std_1.20/src/hash/crc64/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- crc64.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/hash/fnv/ya.make b/contrib/go/_std_1.20/src/hash/fnv/ya.make
deleted file mode 100644
index 204d5cb9bc..0000000000
--- a/contrib/go/_std_1.20/src/hash/fnv/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- fnv.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/hash/maphash/maphash.go b/contrib/go/_std_1.20/src/hash/maphash/maphash.go
deleted file mode 100644
index 690068a70a..0000000000
--- a/contrib/go/_std_1.20/src/hash/maphash/maphash.go
+++ /dev/null
@@ -1,308 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package maphash provides hash functions on byte sequences.
-// These hash functions are intended to be used to implement hash tables or
-// other data structures that need to map arbitrary strings or byte
-// sequences to a uniform distribution on unsigned 64-bit integers.
-// Each different instance of a hash table or data structure should use its own Seed.
-//
-// The hash functions are not cryptographically secure.
-// (See crypto/sha256 and crypto/sha512 for cryptographic use.)
-package maphash
-
-import (
- "unsafe"
-)
-
-// A Seed is a random value that selects the specific hash function
-// computed by a Hash. If two Hashes use the same Seeds, they
-// will compute the same hash values for any given input.
-// If two Hashes use different Seeds, they are very likely to compute
-// distinct hash values for any given input.
-//
-// A Seed must be initialized by calling MakeSeed.
-// The zero seed is uninitialized and not valid for use with Hash's SetSeed method.
-//
-// Each Seed value is local to a single process and cannot be serialized
-// or otherwise recreated in a different process.
-type Seed struct {
- s uint64
-}
-
-// Bytes returns the hash of b with the given seed.
-//
-// Bytes is equivalent to, but more convenient and efficient than:
-//
-// var h Hash
-// h.SetSeed(seed)
-// h.Write(b)
-// return h.Sum64()
-func Bytes(seed Seed, b []byte) uint64 {
- state := seed.s
- if state == 0 {
- panic("maphash: use of uninitialized Seed")
- }
- if len(b) == 0 {
- return rthash(nil, 0, state) // avoid &b[0] index panic below
- }
- if len(b) > bufSize {
- b = b[:len(b):len(b)] // merge len and cap calculations when reslicing
- for len(b) > bufSize {
- state = rthash(&b[0], bufSize, state)
- b = b[bufSize:]
- }
- }
- return rthash(&b[0], len(b), state)
-}
-
-// String returns the hash of s with the given seed.
-//
-// String is equivalent to, but more convenient and efficient than:
-//
-// var h Hash
-// h.SetSeed(seed)
-// h.WriteString(s)
-// return h.Sum64()
-func String(seed Seed, s string) uint64 {
- state := seed.s
- if state == 0 {
- panic("maphash: use of uninitialized Seed")
- }
- for len(s) > bufSize {
- p := (*byte)(unsafe.StringData(s))
- state = rthash(p, bufSize, state)
- s = s[bufSize:]
- }
- p := (*byte)(unsafe.StringData(s))
- return rthash(p, len(s), state)
-}
-
-// A Hash computes a seeded hash of a byte sequence.
-//
-// The zero Hash is a valid Hash ready to use.
-// A zero Hash chooses a random seed for itself during
-// the first call to a Reset, Write, Seed, or Sum64 method.
-// For control over the seed, use SetSeed.
-//
-// The computed hash values depend only on the initial seed and
-// the sequence of bytes provided to the Hash object, not on the way
-// in which the bytes are provided. For example, the three sequences
-//
-// h.Write([]byte{'f','o','o'})
-// h.WriteByte('f'); h.WriteByte('o'); h.WriteByte('o')
-// h.WriteString("foo")
-//
-// all have the same effect.
-//
-// Hashes are intended to be collision-resistant, even for situations
-// where an adversary controls the byte sequences being hashed.
-//
-// A Hash is not safe for concurrent use by multiple goroutines, but a Seed is.
-// If multiple goroutines must compute the same seeded hash,
-// each can declare its own Hash and call SetSeed with a common Seed.
-type Hash struct {
- _ [0]func() // not comparable
- seed Seed // initial seed used for this hash
- state Seed // current hash of all flushed bytes
- buf [bufSize]byte // unflushed byte buffer
- n int // number of unflushed bytes
-}
-
-// bufSize is the size of the Hash write buffer.
-// The buffer ensures that writes depend only on the sequence of bytes,
-// not the sequence of WriteByte/Write/WriteString calls,
-// by always calling rthash with a full buffer (except for the tail).
-const bufSize = 128
-
-// initSeed seeds the hash if necessary.
-// initSeed is called lazily before any operation that actually uses h.seed/h.state.
-// Note that this does not include Write/WriteByte/WriteString in the case
-// where they only add to h.buf. (If they write too much, they call h.flush,
-// which does call h.initSeed.)
-func (h *Hash) initSeed() {
- if h.seed.s == 0 {
- seed := MakeSeed()
- h.seed = seed
- h.state = seed
- }
-}
-
-// WriteByte adds b to the sequence of bytes hashed by h.
-// It never fails; the error result is for implementing io.ByteWriter.
-func (h *Hash) WriteByte(b byte) error {
- if h.n == len(h.buf) {
- h.flush()
- }
- h.buf[h.n] = b
- h.n++
- return nil
-}
-
-// Write adds b to the sequence of bytes hashed by h.
-// It always writes all of b and never fails; the count and error result are for implementing io.Writer.
-func (h *Hash) Write(b []byte) (int, error) {
- size := len(b)
- // Deal with bytes left over in h.buf.
- // h.n <= bufSize is always true.
- // Checking it is ~free and it lets the compiler eliminate a bounds check.
- if h.n > 0 && h.n <= bufSize {
- k := copy(h.buf[h.n:], b)
- h.n += k
- if h.n < bufSize {
- // Copied the entirety of b to h.buf.
- return size, nil
- }
- b = b[k:]
- h.flush()
- // No need to set h.n = 0 here; it happens just before exit.
- }
- // Process as many full buffers as possible, without copying, and calling initSeed only once.
- if len(b) > bufSize {
- h.initSeed()
- for len(b) > bufSize {
- h.state.s = rthash(&b[0], bufSize, h.state.s)
- b = b[bufSize:]
- }
- }
- // Copy the tail.
- copy(h.buf[:], b)
- h.n = len(b)
- return size, nil
-}
-
-// WriteString adds the bytes of s to the sequence of bytes hashed by h.
-// It always writes all of s and never fails; the count and error result are for implementing io.StringWriter.
-func (h *Hash) WriteString(s string) (int, error) {
- // WriteString mirrors Write. See Write for comments.
- size := len(s)
- if h.n > 0 && h.n <= bufSize {
- k := copy(h.buf[h.n:], s)
- h.n += k
- if h.n < bufSize {
- return size, nil
- }
- s = s[k:]
- h.flush()
- }
- if len(s) > bufSize {
- h.initSeed()
- for len(s) > bufSize {
- ptr := (*byte)(unsafe.StringData(s))
- h.state.s = rthash(ptr, bufSize, h.state.s)
- s = s[bufSize:]
- }
- }
- copy(h.buf[:], s)
- h.n = len(s)
- return size, nil
-}
-
-// Seed returns h's seed value.
-func (h *Hash) Seed() Seed {
- h.initSeed()
- return h.seed
-}
-
-// SetSeed sets h to use seed, which must have been returned by MakeSeed
-// or by another Hash's Seed method.
-// Two Hash objects with the same seed behave identically.
-// Two Hash objects with different seeds will very likely behave differently.
-// Any bytes added to h before this call will be discarded.
-func (h *Hash) SetSeed(seed Seed) {
- if seed.s == 0 {
- panic("maphash: use of uninitialized Seed")
- }
- h.seed = seed
- h.state = seed
- h.n = 0
-}
-
-// Reset discards all bytes added to h.
-// (The seed remains the same.)
-func (h *Hash) Reset() {
- h.initSeed()
- h.state = h.seed
- h.n = 0
-}
-
-// precondition: buffer is full.
-func (h *Hash) flush() {
- if h.n != len(h.buf) {
- panic("maphash: flush of partially full buffer")
- }
- h.initSeed()
- h.state.s = rthash(&h.buf[0], h.n, h.state.s)
- h.n = 0
-}
-
-// Sum64 returns h's current 64-bit value, which depends on
-// h's seed and the sequence of bytes added to h since the
-// last call to Reset or SetSeed.
-//
-// All bits of the Sum64 result are close to uniformly and
-// independently distributed, so it can be safely reduced
-// by using bit masking, shifting, or modular arithmetic.
-func (h *Hash) Sum64() uint64 {
- h.initSeed()
- return rthash(&h.buf[0], h.n, h.state.s)
-}
-
-// MakeSeed returns a new random seed.
-func MakeSeed() Seed {
- var s uint64
- for {
- s = runtime_fastrand64()
- // We use seed 0 to indicate an uninitialized seed/hash,
- // so keep trying until we get a non-zero seed.
- if s != 0 {
- break
- }
- }
- return Seed{s: s}
-}
-
-//go:linkname runtime_fastrand64 runtime.fastrand64
-func runtime_fastrand64() uint64
-
-func rthash(ptr *byte, len int, seed uint64) uint64 {
- if len == 0 {
- return seed
- }
- // The runtime hasher only works on uintptr. For 64-bit
- // architectures, we use the hasher directly. Otherwise,
- // we use two parallel hashers on the lower and upper 32 bits.
- if unsafe.Sizeof(uintptr(0)) == 8 {
- return uint64(runtime_memhash(unsafe.Pointer(ptr), uintptr(seed), uintptr(len)))
- }
- lo := runtime_memhash(unsafe.Pointer(ptr), uintptr(seed), uintptr(len))
- hi := runtime_memhash(unsafe.Pointer(ptr), uintptr(seed>>32), uintptr(len))
- return uint64(hi)<<32 | uint64(lo)
-}
-
-//go:linkname runtime_memhash runtime.memhash
-//go:noescape
-func runtime_memhash(p unsafe.Pointer, seed, s uintptr) uintptr
-
-// Sum appends the hash's current 64-bit value to b.
-// It exists for implementing hash.Hash.
-// For direct calls, it is more efficient to use Sum64.
-func (h *Hash) Sum(b []byte) []byte {
- x := h.Sum64()
- return append(b,
- byte(x>>0),
- byte(x>>8),
- byte(x>>16),
- byte(x>>24),
- byte(x>>32),
- byte(x>>40),
- byte(x>>48),
- byte(x>>56))
-}
-
-// Size returns h's hash value size, 8 bytes.
-func (h *Hash) Size() int { return 8 }
-
-// BlockSize returns h's block size.
-func (h *Hash) BlockSize() int { return len(h.buf) }
diff --git a/contrib/go/_std_1.20/src/hash/maphash/ya.make b/contrib/go/_std_1.20/src/hash/maphash/ya.make
deleted file mode 100644
index 135ad498bd..0000000000
--- a/contrib/go/_std_1.20/src/hash/maphash/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- maphash.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/hash/ya.make b/contrib/go/_std_1.20/src/hash/ya.make
deleted file mode 100644
index ae2cdc426d..0000000000
--- a/contrib/go/_std_1.20/src/hash/ya.make
+++ /dev/null
@@ -1,15 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- hash.go
-)
-
-END()
-
-RECURSE(
- adler32
- crc32
- crc64
- fnv
- maphash
-)
diff --git a/contrib/go/_std_1.20/src/html/template/attr_string.go b/contrib/go/_std_1.20/src/html/template/attr_string.go
deleted file mode 100644
index babe70c08b..0000000000
--- a/contrib/go/_std_1.20/src/html/template/attr_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Code generated by "stringer -type attr"; DO NOT EDIT.
-
-package template
-
-import "strconv"
-
-const _attr_name = "attrNoneattrScriptattrScriptTypeattrStyleattrURLattrSrcset"
-
-var _attr_index = [...]uint8{0, 8, 18, 32, 41, 48, 58}
-
-func (i attr) String() string {
- if i >= attr(len(_attr_index)-1) {
- return "attr(" + strconv.FormatInt(int64(i), 10) + ")"
- }
- return _attr_name[_attr_index[i]:_attr_index[i+1]]
-}
diff --git a/contrib/go/_std_1.20/src/html/template/context.go b/contrib/go/_std_1.20/src/html/template/context.go
deleted file mode 100644
index c28fb0c5ea..0000000000
--- a/contrib/go/_std_1.20/src/html/template/context.go
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2011 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 template
-
-import (
- "fmt"
- "text/template/parse"
-)
-
-// context describes the state an HTML parser must be in when it reaches the
-// portion of HTML produced by evaluating a particular template node.
-//
-// The zero value of type context is the start context for a template that
-// produces an HTML fragment as defined at
-// https://www.w3.org/TR/html5/syntax.html#the-end
-// where the context element is null.
-type context struct {
- state state
- delim delim
- urlPart urlPart
- jsCtx jsCtx
- attr attr
- element element
- n parse.Node // for range break/continue
- err *Error
-}
-
-func (c context) String() string {
- var err error
- if c.err != nil {
- err = c.err
- }
- return fmt.Sprintf("{%v %v %v %v %v %v %v}", c.state, c.delim, c.urlPart, c.jsCtx, c.attr, c.element, err)
-}
-
-// eq reports whether two contexts are equal.
-func (c context) eq(d context) bool {
- return c.state == d.state &&
- c.delim == d.delim &&
- c.urlPart == d.urlPart &&
- c.jsCtx == d.jsCtx &&
- c.attr == d.attr &&
- c.element == d.element &&
- c.err == d.err
-}
-
-// mangle produces an identifier that includes a suffix that distinguishes it
-// from template names mangled with different contexts.
-func (c context) mangle(templateName string) string {
- // The mangled name for the default context is the input templateName.
- if c.state == stateText {
- return templateName
- }
- s := templateName + "$htmltemplate_" + c.state.String()
- if c.delim != delimNone {
- s += "_" + c.delim.String()
- }
- if c.urlPart != urlPartNone {
- s += "_" + c.urlPart.String()
- }
- if c.jsCtx != jsCtxRegexp {
- s += "_" + c.jsCtx.String()
- }
- if c.attr != attrNone {
- s += "_" + c.attr.String()
- }
- if c.element != elementNone {
- s += "_" + c.element.String()
- }
- return s
-}
-
-// state describes a high-level HTML parser state.
-//
-// It bounds the top of the element stack, and by extension the HTML insertion
-// mode, but also contains state that does not correspond to anything in the
-// HTML5 parsing algorithm because a single token production in the HTML
-// grammar may contain embedded actions in a template. For instance, the quoted
-// HTML attribute produced by
-//
-// <div title="Hello {{.World}}">
-//
-// is a single token in HTML's grammar but in a template spans several nodes.
-type state uint8
-
-//go:generate stringer -type state
-
-const (
- // stateText is parsed character data. An HTML parser is in
- // this state when its parse position is outside an HTML tag,
- // directive, comment, and special element body.
- stateText state = iota
- // stateTag occurs before an HTML attribute or the end of a tag.
- stateTag
- // stateAttrName occurs inside an attribute name.
- // It occurs between the ^'s in ` ^name^ = value`.
- stateAttrName
- // stateAfterName occurs after an attr name has ended but before any
- // equals sign. It occurs between the ^'s in ` name^ ^= value`.
- stateAfterName
- // stateBeforeValue occurs after the equals sign but before the value.
- // It occurs between the ^'s in ` name =^ ^value`.
- stateBeforeValue
- // stateHTMLCmt occurs inside an <!-- HTML comment -->.
- stateHTMLCmt
- // stateRCDATA occurs inside an RCDATA element (<textarea> or <title>)
- // as described at https://www.w3.org/TR/html5/syntax.html#elements-0
- stateRCDATA
- // stateAttr occurs inside an HTML attribute whose content is text.
- stateAttr
- // stateURL occurs inside an HTML attribute whose content is a URL.
- stateURL
- // stateSrcset occurs inside an HTML srcset attribute.
- stateSrcset
- // stateJS occurs inside an event handler or script element.
- stateJS
- // stateJSDqStr occurs inside a JavaScript double quoted string.
- stateJSDqStr
- // stateJSSqStr occurs inside a JavaScript single quoted string.
- stateJSSqStr
- // stateJSBqStr occurs inside a JavaScript back quoted string.
- stateJSBqStr
- // stateJSRegexp occurs inside a JavaScript regexp literal.
- stateJSRegexp
- // stateJSBlockCmt occurs inside a JavaScript /* block comment */.
- stateJSBlockCmt
- // stateJSLineCmt occurs inside a JavaScript // line comment.
- stateJSLineCmt
- // stateCSS occurs inside a <style> element or style attribute.
- stateCSS
- // stateCSSDqStr occurs inside a CSS double quoted string.
- stateCSSDqStr
- // stateCSSSqStr occurs inside a CSS single quoted string.
- stateCSSSqStr
- // stateCSSDqURL occurs inside a CSS double quoted url("...").
- stateCSSDqURL
- // stateCSSSqURL occurs inside a CSS single quoted url('...').
- stateCSSSqURL
- // stateCSSURL occurs inside a CSS unquoted url(...).
- stateCSSURL
- // stateCSSBlockCmt occurs inside a CSS /* block comment */.
- stateCSSBlockCmt
- // stateCSSLineCmt occurs inside a CSS // line comment.
- stateCSSLineCmt
- // stateError is an infectious error state outside any valid
- // HTML/CSS/JS construct.
- stateError
- // stateDead marks unreachable code after a {{break}} or {{continue}}.
- stateDead
-)
-
-// isComment is true for any state that contains content meant for template
-// authors & maintainers, not for end-users or machines.
-func isComment(s state) bool {
- switch s {
- case stateHTMLCmt, stateJSBlockCmt, stateJSLineCmt, stateCSSBlockCmt, stateCSSLineCmt:
- return true
- }
- return false
-}
-
-// isInTag return whether s occurs solely inside an HTML tag.
-func isInTag(s state) bool {
- switch s {
- case stateTag, stateAttrName, stateAfterName, stateBeforeValue, stateAttr:
- return true
- }
- return false
-}
-
-// delim is the delimiter that will end the current HTML attribute.
-type delim uint8
-
-//go:generate stringer -type delim
-
-const (
- // delimNone occurs outside any attribute.
- delimNone delim = iota
- // delimDoubleQuote occurs when a double quote (") closes the attribute.
- delimDoubleQuote
- // delimSingleQuote occurs when a single quote (') closes the attribute.
- delimSingleQuote
- // delimSpaceOrTagEnd occurs when a space or right angle bracket (>)
- // closes the attribute.
- delimSpaceOrTagEnd
-)
-
-// urlPart identifies a part in an RFC 3986 hierarchical URL to allow different
-// encoding strategies.
-type urlPart uint8
-
-//go:generate stringer -type urlPart
-
-const (
- // urlPartNone occurs when not in a URL, or possibly at the start:
- // ^ in "^http://auth/path?k=v#frag".
- urlPartNone urlPart = iota
- // urlPartPreQuery occurs in the scheme, authority, or path; between the
- // ^s in "h^ttp://auth/path^?k=v#frag".
- urlPartPreQuery
- // urlPartQueryOrFrag occurs in the query portion between the ^s in
- // "http://auth/path?^k=v#frag^".
- urlPartQueryOrFrag
- // urlPartUnknown occurs due to joining of contexts both before and
- // after the query separator.
- urlPartUnknown
-)
-
-// jsCtx determines whether a '/' starts a regular expression literal or a
-// division operator.
-type jsCtx uint8
-
-//go:generate stringer -type jsCtx
-
-const (
- // jsCtxRegexp occurs where a '/' would start a regexp literal.
- jsCtxRegexp jsCtx = iota
- // jsCtxDivOp occurs where a '/' would start a division operator.
- jsCtxDivOp
- // jsCtxUnknown occurs where a '/' is ambiguous due to context joining.
- jsCtxUnknown
-)
-
-// element identifies the HTML element when inside a start tag or special body.
-// Certain HTML element (for example <script> and <style>) have bodies that are
-// treated differently from stateText so the element type is necessary to
-// transition into the correct context at the end of a tag and to identify the
-// end delimiter for the body.
-type element uint8
-
-//go:generate stringer -type element
-
-const (
- // elementNone occurs outside a special tag or special element body.
- elementNone element = iota
- // elementScript corresponds to the raw text <script> element
- // with JS MIME type or no type attribute.
- elementScript
- // elementStyle corresponds to the raw text <style> element.
- elementStyle
- // elementTextarea corresponds to the RCDATA <textarea> element.
- elementTextarea
- // elementTitle corresponds to the RCDATA <title> element.
- elementTitle
-)
-
-//go:generate stringer -type attr
-
-// attr identifies the current HTML attribute when inside the attribute,
-// that is, starting from stateAttrName until stateTag/stateText (exclusive).
-type attr uint8
-
-const (
- // attrNone corresponds to a normal attribute or no attribute.
- attrNone attr = iota
- // attrScript corresponds to an event handler attribute.
- attrScript
- // attrScriptType corresponds to the type attribute in script HTML element
- attrScriptType
- // attrStyle corresponds to the style attribute whose value is CSS.
- attrStyle
- // attrURL corresponds to an attribute whose value is a URL.
- attrURL
- // attrSrcset corresponds to a srcset attribute.
- attrSrcset
-)
diff --git a/contrib/go/_std_1.20/src/html/template/delim_string.go b/contrib/go/_std_1.20/src/html/template/delim_string.go
deleted file mode 100644
index 6d80e09a44..0000000000
--- a/contrib/go/_std_1.20/src/html/template/delim_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Code generated by "stringer -type delim"; DO NOT EDIT.
-
-package template
-
-import "strconv"
-
-const _delim_name = "delimNonedelimDoubleQuotedelimSingleQuotedelimSpaceOrTagEnd"
-
-var _delim_index = [...]uint8{0, 9, 25, 41, 59}
-
-func (i delim) String() string {
- if i >= delim(len(_delim_index)-1) {
- return "delim(" + strconv.FormatInt(int64(i), 10) + ")"
- }
- return _delim_name[_delim_index[i]:_delim_index[i+1]]
-}
diff --git a/contrib/go/_std_1.20/src/html/template/doc.go b/contrib/go/_std_1.20/src/html/template/doc.go
deleted file mode 100644
index ce7b094d9a..0000000000
--- a/contrib/go/_std_1.20/src/html/template/doc.go
+++ /dev/null
@@ -1,242 +0,0 @@
-// Copyright 2011 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 template (html/template) implements data-driven templates for
-generating HTML output safe against code injection. It provides the
-same interface as package text/template and should be used instead of
-text/template whenever the output is HTML.
-
-The documentation here focuses on the security features of the package.
-For information about how to program the templates themselves, see the
-documentation for text/template.
-
-# Introduction
-
-This package wraps package text/template so you can share its template API
-to parse and execute HTML templates safely.
-
- tmpl, err := template.New("name").Parse(...)
- // Error checking elided
- err = tmpl.Execute(out, data)
-
-If successful, tmpl will now be injection-safe. Otherwise, err is an error
-defined in the docs for ErrorCode.
-
-HTML templates treat data values as plain text which should be encoded so they
-can be safely embedded in an HTML document. The escaping is contextual, so
-actions can appear within JavaScript, CSS, and URI contexts.
-
-The security model used by this package assumes that template authors are
-trusted, while Execute's data parameter is not. More details are
-provided below.
-
-Example
-
- import "text/template"
- ...
- t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
- err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")
-
-produces
-
- Hello, <script>alert('you have been pwned')</script>!
-
-but the contextual autoescaping in html/template
-
- import "html/template"
- ...
- t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
- err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")
-
-produces safe, escaped HTML output
-
- Hello, &lt;script&gt;alert(&#39;you have been pwned&#39;)&lt;/script&gt;!
-
-# Contexts
-
-This package understands HTML, CSS, JavaScript, and URIs. It adds sanitizing
-functions to each simple action pipeline, so given the excerpt
-
- <a href="/search?q={{.}}">{{.}}</a>
-
-At parse time each {{.}} is overwritten to add escaping functions as necessary.
-In this case it becomes
-
- <a href="/search?q={{. | urlescaper | attrescaper}}">{{. | htmlescaper}}</a>
-
-where urlescaper, attrescaper, and htmlescaper are aliases for internal escaping
-functions.
-
-For these internal escaping functions, if an action pipeline evaluates to
-a nil interface value, it is treated as though it were an empty string.
-
-# Namespaced and data- attributes
-
-Attributes with a namespace are treated as if they had no namespace.
-Given the excerpt
-
- <a my:href="{{.}}"></a>
-
-At parse time the attribute will be treated as if it were just "href".
-So at parse time the template becomes:
-
- <a my:href="{{. | urlescaper | attrescaper}}"></a>
-
-Similarly to attributes with namespaces, attributes with a "data-" prefix are
-treated as if they had no "data-" prefix. So given
-
- <a data-href="{{.}}"></a>
-
-At parse time this becomes
-
- <a data-href="{{. | urlescaper | attrescaper}}"></a>
-
-If an attribute has both a namespace and a "data-" prefix, only the namespace
-will be removed when determining the context. For example
-
- <a my:data-href="{{.}}"></a>
-
-This is handled as if "my:data-href" was just "data-href" and not "href" as
-it would be if the "data-" prefix were to be ignored too. Thus at parse
-time this becomes just
-
- <a my:data-href="{{. | attrescaper}}"></a>
-
-As a special case, attributes with the namespace "xmlns" are always treated
-as containing URLs. Given the excerpts
-
- <a xmlns:title="{{.}}"></a>
- <a xmlns:href="{{.}}"></a>
- <a xmlns:onclick="{{.}}"></a>
-
-At parse time they become:
-
- <a xmlns:title="{{. | urlescaper | attrescaper}}"></a>
- <a xmlns:href="{{. | urlescaper | attrescaper}}"></a>
- <a xmlns:onclick="{{. | urlescaper | attrescaper}}"></a>
-
-# Errors
-
-See the documentation of ErrorCode for details.
-
-# A fuller picture
-
-The rest of this package comment may be skipped on first reading; it includes
-details necessary to understand escaping contexts and error messages. Most users
-will not need to understand these details.
-
-# Contexts
-
-Assuming {{.}} is `O'Reilly: How are <i>you</i>?`, the table below shows
-how {{.}} appears when used in the context to the left.
-
- Context {{.}} After
- {{.}} O'Reilly: How are &lt;i&gt;you&lt;/i&gt;?
- <a title='{{.}}'> O&#39;Reilly: How are you?
- <a href="/{{.}}"> O&#39;Reilly: How are %3ci%3eyou%3c/i%3e?
- <a href="?q={{.}}"> O&#39;Reilly%3a%20How%20are%3ci%3e...%3f
- <a onx='f("{{.}}")'> O\x27Reilly: How are \x3ci\x3eyou...?
- <a onx='f({{.}})'> "O\x27Reilly: How are \x3ci\x3eyou...?"
- <a onx='pattern = /{{.}}/;'> O\x27Reilly: How are \x3ci\x3eyou...\x3f
-
-If used in an unsafe context, then the value might be filtered out:
-
- Context {{.}} After
- <a href="{{.}}"> #ZgotmplZ
-
-since "O'Reilly:" is not an allowed protocol like "http:".
-
-If {{.}} is the innocuous word, `left`, then it can appear more widely,
-
- Context {{.}} After
- {{.}} left
- <a title='{{.}}'> left
- <a href='{{.}}'> left
- <a href='/{{.}}'> left
- <a href='?dir={{.}}'> left
- <a style="border-{{.}}: 4px"> left
- <a style="align: {{.}}"> left
- <a style="background: '{{.}}'> left
- <a style="background: url('{{.}}')> left
- <style>p.{{.}} {color:red}</style> left
-
-Non-string values can be used in JavaScript contexts.
-If {{.}} is
-
- struct{A,B string}{ "foo", "bar" }
-
-in the escaped template
-
- <script>var pair = {{.}};</script>
-
-then the template output is
-
- <script>var pair = {"A": "foo", "B": "bar"};</script>
-
-See package json to understand how non-string content is marshaled for
-embedding in JavaScript contexts.
-
-# Typed Strings
-
-By default, this package assumes that all pipelines produce a plain text string.
-It adds escaping pipeline stages necessary to correctly and safely embed that
-plain text string in the appropriate context.
-
-When a data value is not plain text, you can make sure it is not over-escaped
-by marking it with its type.
-
-Types HTML, JS, URL, and others from content.go can carry safe content that is
-exempted from escaping.
-
-The template
-
- Hello, {{.}}!
-
-can be invoked with
-
- tmpl.Execute(out, template.HTML(`<b>World</b>`))
-
-to produce
-
- Hello, <b>World</b>!
-
-instead of the
-
- Hello, &lt;b&gt;World&lt;b&gt;!
-
-that would have been produced if {{.}} was a regular string.
-
-# Security Model
-
-https://rawgit.com/mikesamuel/sanitized-jquery-templates/trunk/safetemplate.html#problem_definition defines "safe" as used by this package.
-
-This package assumes that template authors are trusted, that Execute's data
-parameter is not, and seeks to preserve the properties below in the face
-of untrusted data:
-
-Structure Preservation Property:
-"... when a template author writes an HTML tag in a safe templating language,
-the browser will interpret the corresponding portion of the output as a tag
-regardless of the values of untrusted data, and similarly for other structures
-such as attribute boundaries and JS and CSS string boundaries."
-
-Code Effect Property:
-"... only code specified by the template author should run as a result of
-injecting the template output into a page and all code specified by the
-template author should run as a result of the same."
-
-Least Surprise Property:
-"A developer (or code reviewer) familiar with HTML, CSS, and JavaScript, who
-knows that contextual autoescaping happens should be able to look at a {{.}}
-and correctly infer what sanitization happens."
-
-As a consequence of the Least Surprise Property, template actions within an
-ECMAScript 6 template literal are disabled by default.
-Handling string interpolation within these literals is rather complex resulting
-in no clear safe way to support it.
-To re-enable template actions within ECMAScript 6 template literals, use the
-GODEBUG=jstmpllitinterp=1 environment variable.
-*/
-package template
diff --git a/contrib/go/_std_1.20/src/html/template/element_string.go b/contrib/go/_std_1.20/src/html/template/element_string.go
deleted file mode 100644
index 4573e0873e..0000000000
--- a/contrib/go/_std_1.20/src/html/template/element_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Code generated by "stringer -type element"; DO NOT EDIT.
-
-package template
-
-import "strconv"
-
-const _element_name = "elementNoneelementScriptelementStyleelementTextareaelementTitle"
-
-var _element_index = [...]uint8{0, 11, 24, 36, 51, 63}
-
-func (i element) String() string {
- if i >= element(len(_element_index)-1) {
- return "element(" + strconv.FormatInt(int64(i), 10) + ")"
- }
- return _element_name[_element_index[i]:_element_index[i+1]]
-}
diff --git a/contrib/go/_std_1.20/src/html/template/error.go b/contrib/go/_std_1.20/src/html/template/error.go
deleted file mode 100644
index d7d6f5b3ab..0000000000
--- a/contrib/go/_std_1.20/src/html/template/error.go
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright 2011 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 template
-
-import (
- "fmt"
- "text/template/parse"
-)
-
-// Error describes a problem encountered during template Escaping.
-type Error struct {
- // ErrorCode describes the kind of error.
- ErrorCode ErrorCode
- // Node is the node that caused the problem, if known.
- // If not nil, it overrides Name and Line.
- Node parse.Node
- // Name is the name of the template in which the error was encountered.
- Name string
- // Line is the line number of the error in the template source or 0.
- Line int
- // Description is a human-readable description of the problem.
- Description string
-}
-
-// ErrorCode is a code for a kind of error.
-type ErrorCode int
-
-// We define codes for each error that manifests while escaping templates, but
-// escaped templates may also fail at runtime.
-//
-// Output: "ZgotmplZ"
-// Example:
-//
-// <img src="{{.X}}">
-// where {{.X}} evaluates to `javascript:...`
-//
-// Discussion:
-//
-// "ZgotmplZ" is a special value that indicates that unsafe content reached a
-// CSS or URL context at runtime. The output of the example will be
-// <img src="#ZgotmplZ">
-// If the data comes from a trusted source, use content types to exempt it
-// from filtering: URL(`javascript:...`).
-const (
- // OK indicates the lack of an error.
- OK ErrorCode = iota
-
- // ErrAmbigContext: "... appears in an ambiguous context within a URL"
- // Example:
- // <a href="
- // {{if .C}}
- // /path/
- // {{else}}
- // /search?q=
- // {{end}}
- // {{.X}}
- // ">
- // Discussion:
- // {{.X}} is in an ambiguous URL context since, depending on {{.C}},
- // it may be either a URL suffix or a query parameter.
- // Moving {{.X}} into the condition removes the ambiguity:
- // <a href="{{if .C}}/path/{{.X}}{{else}}/search?q={{.X}}">
- ErrAmbigContext
-
- // ErrBadHTML: "expected space, attr name, or end of tag, but got ...",
- // "... in unquoted attr", "... in attribute name"
- // Example:
- // <a href = /search?q=foo>
- // <href=foo>
- // <form na<e=...>
- // <option selected<
- // Discussion:
- // This is often due to a typo in an HTML element, but some runes
- // are banned in tag names, attribute names, and unquoted attribute
- // values because they can tickle parser ambiguities.
- // Quoting all attributes is the best policy.
- ErrBadHTML
-
- // ErrBranchEnd: "{{if}} branches end in different contexts"
- // Example:
- // {{if .C}}<a href="{{end}}{{.X}}
- // Discussion:
- // Package html/template statically examines each path through an
- // {{if}}, {{range}}, or {{with}} to escape any following pipelines.
- // The example is ambiguous since {{.X}} might be an HTML text node,
- // or a URL prefix in an HTML attribute. The context of {{.X}} is
- // used to figure out how to escape it, but that context depends on
- // the run-time value of {{.C}} which is not statically known.
- //
- // The problem is usually something like missing quotes or angle
- // brackets, or can be avoided by refactoring to put the two contexts
- // into different branches of an if, range or with. If the problem
- // is in a {{range}} over a collection that should never be empty,
- // adding a dummy {{else}} can help.
- ErrBranchEnd
-
- // ErrEndContext: "... ends in a non-text context: ..."
- // Examples:
- // <div
- // <div title="no close quote>
- // <script>f()
- // Discussion:
- // Executed templates should produce a DocumentFragment of HTML.
- // Templates that end without closing tags will trigger this error.
- // Templates that should not be used in an HTML context or that
- // produce incomplete Fragments should not be executed directly.
- //
- // {{define "main"}} <script>{{template "helper"}}</script> {{end}}
- // {{define "helper"}} document.write(' <div title=" ') {{end}}
- //
- // "helper" does not produce a valid document fragment, so should
- // not be Executed directly.
- ErrEndContext
-
- // ErrNoSuchTemplate: "no such template ..."
- // Examples:
- // {{define "main"}}<div {{template "attrs"}}>{{end}}
- // {{define "attrs"}}href="{{.URL}}"{{end}}
- // Discussion:
- // Package html/template looks through template calls to compute the
- // context.
- // Here the {{.URL}} in "attrs" must be treated as a URL when called
- // from "main", but you will get this error if "attrs" is not defined
- // when "main" is parsed.
- ErrNoSuchTemplate
-
- // ErrOutputContext: "cannot compute output context for template ..."
- // Examples:
- // {{define "t"}}{{if .T}}{{template "t" .T}}{{end}}{{.H}}",{{end}}
- // Discussion:
- // A recursive template does not end in the same context in which it
- // starts, and a reliable output context cannot be computed.
- // Look for typos in the named template.
- // If the template should not be called in the named start context,
- // look for calls to that template in unexpected contexts.
- // Maybe refactor recursive templates to not be recursive.
- ErrOutputContext
-
- // ErrPartialCharset: "unfinished JS regexp charset in ..."
- // Example:
- // <script>var pattern = /foo[{{.Chars}}]/</script>
- // Discussion:
- // Package html/template does not support interpolation into regular
- // expression literal character sets.
- ErrPartialCharset
-
- // ErrPartialEscape: "unfinished escape sequence in ..."
- // Example:
- // <script>alert("\{{.X}}")</script>
- // Discussion:
- // Package html/template does not support actions following a
- // backslash.
- // This is usually an error and there are better solutions; for
- // example
- // <script>alert("{{.X}}")</script>
- // should work, and if {{.X}} is a partial escape sequence such as
- // "xA0", mark the whole sequence as safe content: JSStr(`\xA0`)
- ErrPartialEscape
-
- // ErrRangeLoopReentry: "on range loop re-entry: ..."
- // Example:
- // <script>var x = [{{range .}}'{{.}},{{end}}]</script>
- // Discussion:
- // If an iteration through a range would cause it to end in a
- // different context than an earlier pass, there is no single context.
- // In the example, there is missing a quote, so it is not clear
- // whether {{.}} is meant to be inside a JS string or in a JS value
- // context. The second iteration would produce something like
- //
- // <script>var x = ['firstValue,'secondValue]</script>
- ErrRangeLoopReentry
-
- // ErrSlashAmbig: '/' could start a division or regexp.
- // Example:
- // <script>
- // {{if .C}}var x = 1{{end}}
- // /-{{.N}}/i.test(x) ? doThis : doThat();
- // </script>
- // Discussion:
- // The example above could produce `var x = 1/-2/i.test(s)...`
- // in which the first '/' is a mathematical division operator or it
- // could produce `/-2/i.test(s)` in which the first '/' starts a
- // regexp literal.
- // Look for missing semicolons inside branches, and maybe add
- // parentheses to make it clear which interpretation you intend.
- ErrSlashAmbig
-
- // ErrPredefinedEscaper: "predefined escaper ... disallowed in template"
- // Example:
- // <div class={{. | html}}>Hello<div>
- // Discussion:
- // Package html/template already contextually escapes all pipelines to
- // produce HTML output safe against code injection. Manually escaping
- // pipeline output using the predefined escapers "html" or "urlquery" is
- // unnecessary, and may affect the correctness or safety of the escaped
- // pipeline output in Go 1.8 and earlier.
- //
- // In most cases, such as the given example, this error can be resolved by
- // simply removing the predefined escaper from the pipeline and letting the
- // contextual autoescaper handle the escaping of the pipeline. In other
- // instances, where the predefined escaper occurs in the middle of a
- // pipeline where subsequent commands expect escaped input, e.g.
- // {{.X | html | makeALink}}
- // where makeALink does
- // return `<a href="`+input+`">link</a>`
- // consider refactoring the surrounding template to make use of the
- // contextual autoescaper, i.e.
- // <a href="{{.X}}">link</a>
- //
- // To ease migration to Go 1.9 and beyond, "html" and "urlquery" will
- // continue to be allowed as the last command in a pipeline. However, if the
- // pipeline occurs in an unquoted attribute value context, "html" is
- // disallowed. Avoid using "html" and "urlquery" entirely in new templates.
- ErrPredefinedEscaper
-
- // errJSTmplLit: "... appears in a JS template literal"
- // Example:
- // <script>var tmpl = `{{.Interp}`</script>
- // Discussion:
- // Package html/template does not support actions inside of JS template
- // literals.
- //
- // TODO(rolandshoemaker): we cannot add this as an exported error in a minor
- // release, since it is backwards incompatible with the other minor
- // releases. As such we need to leave it unexported, and then we'll add it
- // in the next major release.
- errJSTmplLit
-)
-
-func (e *Error) Error() string {
- switch {
- case e.Node != nil:
- loc, _ := (*parse.Tree)(nil).ErrorContext(e.Node)
- return fmt.Sprintf("html/template:%s: %s", loc, e.Description)
- case e.Line != 0:
- return fmt.Sprintf("html/template:%s:%d: %s", e.Name, e.Line, e.Description)
- case e.Name != "":
- return fmt.Sprintf("html/template:%s: %s", e.Name, e.Description)
- }
- return "html/template: " + e.Description
-}
-
-// errorf creates an error given a format string f and args.
-// The template Name still needs to be supplied.
-func errorf(k ErrorCode, node parse.Node, line int, f string, args ...any) *Error {
- return &Error{k, node, "", line, fmt.Sprintf(f, args...)}
-}
diff --git a/contrib/go/_std_1.20/src/html/template/escape.go b/contrib/go/_std_1.20/src/html/template/escape.go
deleted file mode 100644
index c262d1698d..0000000000
--- a/contrib/go/_std_1.20/src/html/template/escape.go
+++ /dev/null
@@ -1,978 +0,0 @@
-// Copyright 2011 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 template
-
-import (
- "bytes"
- "fmt"
- "html"
- "internal/godebug"
- "io"
- "text/template"
- "text/template/parse"
-)
-
-// escapeTemplate rewrites the named template, which must be
-// associated with t, to guarantee that the output of any of the named
-// templates is properly escaped. If no error is returned, then the named templates have
-// been modified. Otherwise the named templates have been rendered
-// unusable.
-func escapeTemplate(tmpl *Template, node parse.Node, name string) error {
- c, _ := tmpl.esc.escapeTree(context{}, node, name, 0)
- var err error
- if c.err != nil {
- err, c.err.Name = c.err, name
- } else if c.state != stateText {
- err = &Error{ErrEndContext, nil, name, 0, fmt.Sprintf("ends in a non-text context: %v", c)}
- }
- if err != nil {
- // Prevent execution of unsafe templates.
- if t := tmpl.set[name]; t != nil {
- t.escapeErr = err
- t.text.Tree = nil
- t.Tree = nil
- }
- return err
- }
- tmpl.esc.commit()
- if t := tmpl.set[name]; t != nil {
- t.escapeErr = escapeOK
- t.Tree = t.text.Tree
- }
- return nil
-}
-
-// evalArgs formats the list of arguments into a string. It is equivalent to
-// fmt.Sprint(args...), except that it dereferences all pointers.
-func evalArgs(args ...any) string {
- // Optimization for simple common case of a single string argument.
- if len(args) == 1 {
- if s, ok := args[0].(string); ok {
- return s
- }
- }
- for i, arg := range args {
- args[i] = indirectToStringerOrError(arg)
- }
- return fmt.Sprint(args...)
-}
-
-// funcMap maps command names to functions that render their inputs safe.
-var funcMap = template.FuncMap{
- "_html_template_attrescaper": attrEscaper,
- "_html_template_commentescaper": commentEscaper,
- "_html_template_cssescaper": cssEscaper,
- "_html_template_cssvaluefilter": cssValueFilter,
- "_html_template_htmlnamefilter": htmlNameFilter,
- "_html_template_htmlescaper": htmlEscaper,
- "_html_template_jsregexpescaper": jsRegexpEscaper,
- "_html_template_jsstrescaper": jsStrEscaper,
- "_html_template_jsvalescaper": jsValEscaper,
- "_html_template_nospaceescaper": htmlNospaceEscaper,
- "_html_template_rcdataescaper": rcdataEscaper,
- "_html_template_srcsetescaper": srcsetFilterAndEscaper,
- "_html_template_urlescaper": urlEscaper,
- "_html_template_urlfilter": urlFilter,
- "_html_template_urlnormalizer": urlNormalizer,
- "_eval_args_": evalArgs,
-}
-
-// escaper collects type inferences about templates and changes needed to make
-// templates injection safe.
-type escaper struct {
- // ns is the nameSpace that this escaper is associated with.
- ns *nameSpace
- // output[templateName] is the output context for a templateName that
- // has been mangled to include its input context.
- output map[string]context
- // derived[c.mangle(name)] maps to a template derived from the template
- // named name templateName for the start context c.
- derived map[string]*template.Template
- // called[templateName] is a set of called mangled template names.
- called map[string]bool
- // xxxNodeEdits are the accumulated edits to apply during commit.
- // Such edits are not applied immediately in case a template set
- // executes a given template in different escaping contexts.
- actionNodeEdits map[*parse.ActionNode][]string
- templateNodeEdits map[*parse.TemplateNode]string
- textNodeEdits map[*parse.TextNode][]byte
- // rangeContext holds context about the current range loop.
- rangeContext *rangeContext
-}
-
-// rangeContext holds information about the current range loop.
-type rangeContext struct {
- outer *rangeContext // outer loop
- breaks []context // context at each break action
- continues []context // context at each continue action
-}
-
-// makeEscaper creates a blank escaper for the given set.
-func makeEscaper(n *nameSpace) escaper {
- return escaper{
- n,
- map[string]context{},
- map[string]*template.Template{},
- map[string]bool{},
- map[*parse.ActionNode][]string{},
- map[*parse.TemplateNode]string{},
- map[*parse.TextNode][]byte{},
- nil,
- }
-}
-
-// filterFailsafe is an innocuous word that is emitted in place of unsafe values
-// by sanitizer functions. It is not a keyword in any programming language,
-// contains no special characters, is not empty, and when it appears in output
-// it is distinct enough that a developer can find the source of the problem
-// via a search engine.
-const filterFailsafe = "ZgotmplZ"
-
-// escape escapes a template node.
-func (e *escaper) escape(c context, n parse.Node) context {
- switch n := n.(type) {
- case *parse.ActionNode:
- return e.escapeAction(c, n)
- case *parse.BreakNode:
- c.n = n
- e.rangeContext.breaks = append(e.rangeContext.breaks, c)
- return context{state: stateDead}
- case *parse.CommentNode:
- return c
- case *parse.ContinueNode:
- c.n = n
- e.rangeContext.continues = append(e.rangeContext.breaks, c)
- return context{state: stateDead}
- case *parse.IfNode:
- return e.escapeBranch(c, &n.BranchNode, "if")
- case *parse.ListNode:
- return e.escapeList(c, n)
- case *parse.RangeNode:
- return e.escapeBranch(c, &n.BranchNode, "range")
- case *parse.TemplateNode:
- return e.escapeTemplate(c, n)
- case *parse.TextNode:
- return e.escapeText(c, n)
- case *parse.WithNode:
- return e.escapeBranch(c, &n.BranchNode, "with")
- }
- panic("escaping " + n.String() + " is unimplemented")
-}
-
-var debugAllowActionJSTmpl = godebug.New("jstmpllitinterp")
-
-// escapeAction escapes an action template node.
-func (e *escaper) escapeAction(c context, n *parse.ActionNode) context {
- if len(n.Pipe.Decl) != 0 {
- // A local variable assignment, not an interpolation.
- return c
- }
- c = nudge(c)
- // Check for disallowed use of predefined escapers in the pipeline.
- for pos, idNode := range n.Pipe.Cmds {
- node, ok := idNode.Args[0].(*parse.IdentifierNode)
- if !ok {
- // A predefined escaper "esc" will never be found as an identifier in a
- // Chain or Field node, since:
- // - "esc.x ..." is invalid, since predefined escapers return strings, and
- // strings do not have methods, keys or fields.
- // - "... .esc" is invalid, since predefined escapers are global functions,
- // not methods or fields of any types.
- // Therefore, it is safe to ignore these two node types.
- continue
- }
- ident := node.Ident
- if _, ok := predefinedEscapers[ident]; ok {
- if pos < len(n.Pipe.Cmds)-1 ||
- c.state == stateAttr && c.delim == delimSpaceOrTagEnd && ident == "html" {
- return context{
- state: stateError,
- err: errorf(ErrPredefinedEscaper, n, n.Line, "predefined escaper %q disallowed in template", ident),
- }
- }
- }
- }
- s := make([]string, 0, 3)
- switch c.state {
- case stateError:
- return c
- case stateURL, stateCSSDqStr, stateCSSSqStr, stateCSSDqURL, stateCSSSqURL, stateCSSURL:
- switch c.urlPart {
- case urlPartNone:
- s = append(s, "_html_template_urlfilter")
- fallthrough
- case urlPartPreQuery:
- switch c.state {
- case stateCSSDqStr, stateCSSSqStr:
- s = append(s, "_html_template_cssescaper")
- default:
- s = append(s, "_html_template_urlnormalizer")
- }
- case urlPartQueryOrFrag:
- s = append(s, "_html_template_urlescaper")
- case urlPartUnknown:
- return context{
- state: stateError,
- err: errorf(ErrAmbigContext, n, n.Line, "%s appears in an ambiguous context within a URL", n),
- }
- default:
- panic(c.urlPart.String())
- }
- case stateJS:
- s = append(s, "_html_template_jsvalescaper")
- // A slash after a value starts a div operator.
- c.jsCtx = jsCtxDivOp
- case stateJSDqStr, stateJSSqStr:
- s = append(s, "_html_template_jsstrescaper")
- case stateJSBqStr:
- if debugAllowActionJSTmpl.Value() == "1" {
- s = append(s, "_html_template_jsstrescaper")
- } else {
- return context{
- state: stateError,
- err: errorf(errJSTmplLit, n, n.Line, "%s appears in a JS template literal", n),
- }
- }
- case stateJSRegexp:
- s = append(s, "_html_template_jsregexpescaper")
- case stateCSS:
- s = append(s, "_html_template_cssvaluefilter")
- case stateText:
- s = append(s, "_html_template_htmlescaper")
- case stateRCDATA:
- s = append(s, "_html_template_rcdataescaper")
- case stateAttr:
- // Handled below in delim check.
- case stateAttrName, stateTag:
- c.state = stateAttrName
- s = append(s, "_html_template_htmlnamefilter")
- case stateSrcset:
- s = append(s, "_html_template_srcsetescaper")
- default:
- if isComment(c.state) {
- s = append(s, "_html_template_commentescaper")
- } else {
- panic("unexpected state " + c.state.String())
- }
- }
- switch c.delim {
- case delimNone:
- // No extra-escaping needed for raw text content.
- case delimSpaceOrTagEnd:
- s = append(s, "_html_template_nospaceescaper")
- default:
- s = append(s, "_html_template_attrescaper")
- }
- e.editActionNode(n, s)
- return c
-}
-
-// ensurePipelineContains ensures that the pipeline ends with the commands with
-// the identifiers in s in order. If the pipeline ends with a predefined escaper
-// (i.e. "html" or "urlquery"), merge it with the identifiers in s.
-func ensurePipelineContains(p *parse.PipeNode, s []string) {
- if len(s) == 0 {
- // Do not rewrite pipeline if we have no escapers to insert.
- return
- }
- // Precondition: p.Cmds contains at most one predefined escaper and the
- // escaper will be present at p.Cmds[len(p.Cmds)-1]. This precondition is
- // always true because of the checks in escapeAction.
- pipelineLen := len(p.Cmds)
- if pipelineLen > 0 {
- lastCmd := p.Cmds[pipelineLen-1]
- if idNode, ok := lastCmd.Args[0].(*parse.IdentifierNode); ok {
- if esc := idNode.Ident; predefinedEscapers[esc] {
- // Pipeline ends with a predefined escaper.
- if len(p.Cmds) == 1 && len(lastCmd.Args) > 1 {
- // Special case: pipeline is of the form {{ esc arg1 arg2 ... argN }},
- // where esc is the predefined escaper, and arg1...argN are its arguments.
- // Convert this into the equivalent form
- // {{ _eval_args_ arg1 arg2 ... argN | esc }}, so that esc can be easily
- // merged with the escapers in s.
- lastCmd.Args[0] = parse.NewIdentifier("_eval_args_").SetTree(nil).SetPos(lastCmd.Args[0].Position())
- p.Cmds = appendCmd(p.Cmds, newIdentCmd(esc, p.Position()))
- pipelineLen++
- }
- // If any of the commands in s that we are about to insert is equivalent
- // to the predefined escaper, use the predefined escaper instead.
- dup := false
- for i, escaper := range s {
- if escFnsEq(esc, escaper) {
- s[i] = idNode.Ident
- dup = true
- }
- }
- if dup {
- // The predefined escaper will already be inserted along with the
- // escapers in s, so do not copy it to the rewritten pipeline.
- pipelineLen--
- }
- }
- }
- }
- // Rewrite the pipeline, creating the escapers in s at the end of the pipeline.
- newCmds := make([]*parse.CommandNode, pipelineLen, pipelineLen+len(s))
- insertedIdents := make(map[string]bool)
- for i := 0; i < pipelineLen; i++ {
- cmd := p.Cmds[i]
- newCmds[i] = cmd
- if idNode, ok := cmd.Args[0].(*parse.IdentifierNode); ok {
- insertedIdents[normalizeEscFn(idNode.Ident)] = true
- }
- }
- for _, name := range s {
- if !insertedIdents[normalizeEscFn(name)] {
- // When two templates share an underlying parse tree via the use of
- // AddParseTree and one template is executed after the other, this check
- // ensures that escapers that were already inserted into the pipeline on
- // the first escaping pass do not get inserted again.
- newCmds = appendCmd(newCmds, newIdentCmd(name, p.Position()))
- }
- }
- p.Cmds = newCmds
-}
-
-// predefinedEscapers contains template predefined escapers that are equivalent
-// to some contextual escapers. Keep in sync with equivEscapers.
-var predefinedEscapers = map[string]bool{
- "html": true,
- "urlquery": true,
-}
-
-// equivEscapers matches contextual escapers to equivalent predefined
-// template escapers.
-var equivEscapers = map[string]string{
- // The following pairs of HTML escapers provide equivalent security
- // guarantees, since they all escape '\000', '\'', '"', '&', '<', and '>'.
- "_html_template_attrescaper": "html",
- "_html_template_htmlescaper": "html",
- "_html_template_rcdataescaper": "html",
- // These two URL escapers produce URLs safe for embedding in a URL query by
- // percent-encoding all the reserved characters specified in RFC 3986 Section
- // 2.2
- "_html_template_urlescaper": "urlquery",
- // These two functions are not actually equivalent; urlquery is stricter as it
- // escapes reserved characters (e.g. '#'), while _html_template_urlnormalizer
- // does not. It is therefore only safe to replace _html_template_urlnormalizer
- // with urlquery (this happens in ensurePipelineContains), but not the otherI've
- // way around. We keep this entry around to preserve the behavior of templates
- // written before Go 1.9, which might depend on this substitution taking place.
- "_html_template_urlnormalizer": "urlquery",
-}
-
-// escFnsEq reports whether the two escaping functions are equivalent.
-func escFnsEq(a, b string) bool {
- return normalizeEscFn(a) == normalizeEscFn(b)
-}
-
-// normalizeEscFn(a) is equal to normalizeEscFn(b) for any pair of names of
-// escaper functions a and b that are equivalent.
-func normalizeEscFn(e string) string {
- if norm := equivEscapers[e]; norm != "" {
- return norm
- }
- return e
-}
-
-// redundantFuncs[a][b] implies that funcMap[b](funcMap[a](x)) == funcMap[a](x)
-// for all x.
-var redundantFuncs = map[string]map[string]bool{
- "_html_template_commentescaper": {
- "_html_template_attrescaper": true,
- "_html_template_htmlescaper": true,
- },
- "_html_template_cssescaper": {
- "_html_template_attrescaper": true,
- },
- "_html_template_jsregexpescaper": {
- "_html_template_attrescaper": true,
- },
- "_html_template_jsstrescaper": {
- "_html_template_attrescaper": true,
- },
- "_html_template_urlescaper": {
- "_html_template_urlnormalizer": true,
- },
-}
-
-// appendCmd appends the given command to the end of the command pipeline
-// unless it is redundant with the last command.
-func appendCmd(cmds []*parse.CommandNode, cmd *parse.CommandNode) []*parse.CommandNode {
- if n := len(cmds); n != 0 {
- last, okLast := cmds[n-1].Args[0].(*parse.IdentifierNode)
- next, okNext := cmd.Args[0].(*parse.IdentifierNode)
- if okLast && okNext && redundantFuncs[last.Ident][next.Ident] {
- return cmds
- }
- }
- return append(cmds, cmd)
-}
-
-// newIdentCmd produces a command containing a single identifier node.
-func newIdentCmd(identifier string, pos parse.Pos) *parse.CommandNode {
- return &parse.CommandNode{
- NodeType: parse.NodeCommand,
- Args: []parse.Node{parse.NewIdentifier(identifier).SetTree(nil).SetPos(pos)}, // TODO: SetTree.
- }
-}
-
-// nudge returns the context that would result from following empty string
-// transitions from the input context.
-// For example, parsing:
-//
-// `<a href=`
-//
-// will end in context{stateBeforeValue, attrURL}, but parsing one extra rune:
-//
-// `<a href=x`
-//
-// will end in context{stateURL, delimSpaceOrTagEnd, ...}.
-// There are two transitions that happen when the 'x' is seen:
-// (1) Transition from a before-value state to a start-of-value state without
-//
-// consuming any character.
-//
-// (2) Consume 'x' and transition past the first value character.
-// In this case, nudging produces the context after (1) happens.
-func nudge(c context) context {
- switch c.state {
- case stateTag:
- // In `<foo {{.}}`, the action should emit an attribute.
- c.state = stateAttrName
- case stateBeforeValue:
- // In `<foo bar={{.}}`, the action is an undelimited value.
- c.state, c.delim, c.attr = attrStartStates[c.attr], delimSpaceOrTagEnd, attrNone
- case stateAfterName:
- // In `<foo bar {{.}}`, the action is an attribute name.
- c.state, c.attr = stateAttrName, attrNone
- }
- return c
-}
-
-// join joins the two contexts of a branch template node. The result is an
-// error context if either of the input contexts are error contexts, or if the
-// input contexts differ.
-func join(a, b context, node parse.Node, nodeName string) context {
- if a.state == stateError {
- return a
- }
- if b.state == stateError {
- return b
- }
- if a.state == stateDead {
- return b
- }
- if b.state == stateDead {
- return a
- }
- if a.eq(b) {
- return a
- }
-
- c := a
- c.urlPart = b.urlPart
- if c.eq(b) {
- // The contexts differ only by urlPart.
- c.urlPart = urlPartUnknown
- return c
- }
-
- c = a
- c.jsCtx = b.jsCtx
- if c.eq(b) {
- // The contexts differ only by jsCtx.
- c.jsCtx = jsCtxUnknown
- return c
- }
-
- // Allow a nudged context to join with an unnudged one.
- // This means that
- // <p title={{if .C}}{{.}}{{end}}
- // ends in an unquoted value state even though the else branch
- // ends in stateBeforeValue.
- if c, d := nudge(a), nudge(b); !(c.eq(a) && d.eq(b)) {
- if e := join(c, d, node, nodeName); e.state != stateError {
- return e
- }
- }
-
- return context{
- state: stateError,
- err: errorf(ErrBranchEnd, node, 0, "{{%s}} branches end in different contexts: %v, %v", nodeName, a, b),
- }
-}
-
-// escapeBranch escapes a branch template node: "if", "range" and "with".
-func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName string) context {
- if nodeName == "range" {
- e.rangeContext = &rangeContext{outer: e.rangeContext}
- }
- c0 := e.escapeList(c, n.List)
- if nodeName == "range" {
- if c0.state != stateError {
- c0 = joinRange(c0, e.rangeContext)
- }
- e.rangeContext = e.rangeContext.outer
- if c0.state == stateError {
- return c0
- }
-
- // The "true" branch of a "range" node can execute multiple times.
- // We check that executing n.List once results in the same context
- // as executing n.List twice.
- e.rangeContext = &rangeContext{outer: e.rangeContext}
- c1, _ := e.escapeListConditionally(c0, n.List, nil)
- c0 = join(c0, c1, n, nodeName)
- if c0.state == stateError {
- e.rangeContext = e.rangeContext.outer
- // Make clear that this is a problem on loop re-entry
- // since developers tend to overlook that branch when
- // debugging templates.
- c0.err.Line = n.Line
- c0.err.Description = "on range loop re-entry: " + c0.err.Description
- return c0
- }
- c0 = joinRange(c0, e.rangeContext)
- e.rangeContext = e.rangeContext.outer
- if c0.state == stateError {
- return c0
- }
- }
- c1 := e.escapeList(c, n.ElseList)
- return join(c0, c1, n, nodeName)
-}
-
-func joinRange(c0 context, rc *rangeContext) context {
- // Merge contexts at break and continue statements into overall body context.
- // In theory we could treat breaks differently from continues, but for now it is
- // enough to treat them both as going back to the start of the loop (which may then stop).
- for _, c := range rc.breaks {
- c0 = join(c0, c, c.n, "range")
- if c0.state == stateError {
- c0.err.Line = c.n.(*parse.BreakNode).Line
- c0.err.Description = "at range loop break: " + c0.err.Description
- return c0
- }
- }
- for _, c := range rc.continues {
- c0 = join(c0, c, c.n, "range")
- if c0.state == stateError {
- c0.err.Line = c.n.(*parse.ContinueNode).Line
- c0.err.Description = "at range loop continue: " + c0.err.Description
- return c0
- }
- }
- return c0
-}
-
-// escapeList escapes a list template node.
-func (e *escaper) escapeList(c context, n *parse.ListNode) context {
- if n == nil {
- return c
- }
- for _, m := range n.Nodes {
- c = e.escape(c, m)
- if c.state == stateDead {
- break
- }
- }
- return c
-}
-
-// escapeListConditionally escapes a list node but only preserves edits and
-// inferences in e if the inferences and output context satisfy filter.
-// It returns the best guess at an output context, and the result of the filter
-// which is the same as whether e was updated.
-func (e *escaper) escapeListConditionally(c context, n *parse.ListNode, filter func(*escaper, context) bool) (context, bool) {
- e1 := makeEscaper(e.ns)
- e1.rangeContext = e.rangeContext
- // Make type inferences available to f.
- for k, v := range e.output {
- e1.output[k] = v
- }
- c = e1.escapeList(c, n)
- ok := filter != nil && filter(&e1, c)
- if ok {
- // Copy inferences and edits from e1 back into e.
- for k, v := range e1.output {
- e.output[k] = v
- }
- for k, v := range e1.derived {
- e.derived[k] = v
- }
- for k, v := range e1.called {
- e.called[k] = v
- }
- for k, v := range e1.actionNodeEdits {
- e.editActionNode(k, v)
- }
- for k, v := range e1.templateNodeEdits {
- e.editTemplateNode(k, v)
- }
- for k, v := range e1.textNodeEdits {
- e.editTextNode(k, v)
- }
- }
- return c, ok
-}
-
-// escapeTemplate escapes a {{template}} call node.
-func (e *escaper) escapeTemplate(c context, n *parse.TemplateNode) context {
- c, name := e.escapeTree(c, n, n.Name, n.Line)
- if name != n.Name {
- e.editTemplateNode(n, name)
- }
- return c
-}
-
-// escapeTree escapes the named template starting in the given context as
-// necessary and returns its output context.
-func (e *escaper) escapeTree(c context, node parse.Node, name string, line int) (context, string) {
- // Mangle the template name with the input context to produce a reliable
- // identifier.
- dname := c.mangle(name)
- e.called[dname] = true
- if out, ok := e.output[dname]; ok {
- // Already escaped.
- return out, dname
- }
- t := e.template(name)
- if t == nil {
- // Two cases: The template exists but is empty, or has never been mentioned at
- // all. Distinguish the cases in the error messages.
- if e.ns.set[name] != nil {
- return context{
- state: stateError,
- err: errorf(ErrNoSuchTemplate, node, line, "%q is an incomplete or empty template", name),
- }, dname
- }
- return context{
- state: stateError,
- err: errorf(ErrNoSuchTemplate, node, line, "no such template %q", name),
- }, dname
- }
- if dname != name {
- // Use any template derived during an earlier call to escapeTemplate
- // with different top level templates, or clone if necessary.
- dt := e.template(dname)
- if dt == nil {
- dt = template.New(dname)
- dt.Tree = &parse.Tree{Name: dname, Root: t.Root.CopyList()}
- e.derived[dname] = dt
- }
- t = dt
- }
- return e.computeOutCtx(c, t), dname
-}
-
-// computeOutCtx takes a template and its start context and computes the output
-// context while storing any inferences in e.
-func (e *escaper) computeOutCtx(c context, t *template.Template) context {
- // Propagate context over the body.
- c1, ok := e.escapeTemplateBody(c, t)
- if !ok {
- // Look for a fixed point by assuming c1 as the output context.
- if c2, ok2 := e.escapeTemplateBody(c1, t); ok2 {
- c1, ok = c2, true
- }
- // Use c1 as the error context if neither assumption worked.
- }
- if !ok && c1.state != stateError {
- return context{
- state: stateError,
- err: errorf(ErrOutputContext, t.Tree.Root, 0, "cannot compute output context for template %s", t.Name()),
- }
- }
- return c1
-}
-
-// escapeTemplateBody escapes the given template assuming the given output
-// context, and returns the best guess at the output context and whether the
-// assumption was correct.
-func (e *escaper) escapeTemplateBody(c context, t *template.Template) (context, bool) {
- filter := func(e1 *escaper, c1 context) bool {
- if c1.state == stateError {
- // Do not update the input escaper, e.
- return false
- }
- if !e1.called[t.Name()] {
- // If t is not recursively called, then c1 is an
- // accurate output context.
- return true
- }
- // c1 is accurate if it matches our assumed output context.
- return c.eq(c1)
- }
- // We need to assume an output context so that recursive template calls
- // take the fast path out of escapeTree instead of infinitely recurring.
- // Naively assuming that the input context is the same as the output
- // works >90% of the time.
- e.output[t.Name()] = c
- return e.escapeListConditionally(c, t.Tree.Root, filter)
-}
-
-// delimEnds maps each delim to a string of characters that terminate it.
-var delimEnds = [...]string{
- delimDoubleQuote: `"`,
- delimSingleQuote: "'",
- // Determined empirically by running the below in various browsers.
- // var div = document.createElement("DIV");
- // for (var i = 0; i < 0x10000; ++i) {
- // div.innerHTML = "<span title=x" + String.fromCharCode(i) + "-bar>";
- // if (div.getElementsByTagName("SPAN")[0].title.indexOf("bar") < 0)
- // document.write("<p>U+" + i.toString(16));
- // }
- delimSpaceOrTagEnd: " \t\n\f\r>",
-}
-
-var doctypeBytes = []byte("<!DOCTYPE")
-
-// escapeText escapes a text template node.
-func (e *escaper) escapeText(c context, n *parse.TextNode) context {
- s, written, i, b := n.Text, 0, 0, new(bytes.Buffer)
- for i != len(s) {
- c1, nread := contextAfterText(c, s[i:])
- i1 := i + nread
- if c.state == stateText || c.state == stateRCDATA {
- end := i1
- if c1.state != c.state {
- for j := end - 1; j >= i; j-- {
- if s[j] == '<' {
- end = j
- break
- }
- }
- }
- for j := i; j < end; j++ {
- if s[j] == '<' && !bytes.HasPrefix(bytes.ToUpper(s[j:]), doctypeBytes) {
- b.Write(s[written:j])
- b.WriteString("&lt;")
- written = j + 1
- }
- }
- } else if isComment(c.state) && c.delim == delimNone {
- switch c.state {
- case stateJSBlockCmt:
- // https://es5.github.com/#x7.4:
- // "Comments behave like white space and are
- // discarded except that, if a MultiLineComment
- // contains a line terminator character, then
- // the entire comment is considered to be a
- // LineTerminator for purposes of parsing by
- // the syntactic grammar."
- if bytes.ContainsAny(s[written:i1], "\n\r\u2028\u2029") {
- b.WriteByte('\n')
- } else {
- b.WriteByte(' ')
- }
- case stateCSSBlockCmt:
- b.WriteByte(' ')
- }
- written = i1
- }
- if c.state != c1.state && isComment(c1.state) && c1.delim == delimNone {
- // Preserve the portion between written and the comment start.
- cs := i1 - 2
- if c1.state == stateHTMLCmt {
- // "<!--" instead of "/*" or "//"
- cs -= 2
- }
- b.Write(s[written:cs])
- written = i1
- }
- if i == i1 && c.state == c1.state {
- panic(fmt.Sprintf("infinite loop from %v to %v on %q..%q", c, c1, s[:i], s[i:]))
- }
- c, i = c1, i1
- }
-
- if written != 0 && c.state != stateError {
- if !isComment(c.state) || c.delim != delimNone {
- b.Write(n.Text[written:])
- }
- e.editTextNode(n, b.Bytes())
- }
- return c
-}
-
-// contextAfterText starts in context c, consumes some tokens from the front of
-// s, then returns the context after those tokens and the unprocessed suffix.
-func contextAfterText(c context, s []byte) (context, int) {
- if c.delim == delimNone {
- c1, i := tSpecialTagEnd(c, s)
- if i == 0 {
- // A special end tag (`</script>`) has been seen and
- // all content preceding it has been consumed.
- return c1, 0
- }
- // Consider all content up to any end tag.
- return transitionFunc[c.state](c, s[:i])
- }
-
- // We are at the beginning of an attribute value.
-
- i := bytes.IndexAny(s, delimEnds[c.delim])
- if i == -1 {
- i = len(s)
- }
- if c.delim == delimSpaceOrTagEnd {
- // https://www.w3.org/TR/html5/syntax.html#attribute-value-(unquoted)-state
- // lists the runes below as error characters.
- // Error out because HTML parsers may differ on whether
- // "<a id= onclick=f(" ends inside id's or onclick's value,
- // "<a class=`foo " ends inside a value,
- // "<a style=font:'Arial'" needs open-quote fixup.
- // IE treats '`' as a quotation character.
- if j := bytes.IndexAny(s[:i], "\"'<=`"); j >= 0 {
- return context{
- state: stateError,
- err: errorf(ErrBadHTML, nil, 0, "%q in unquoted attr: %q", s[j:j+1], s[:i]),
- }, len(s)
- }
- }
- if i == len(s) {
- // Remain inside the attribute.
- // Decode the value so non-HTML rules can easily handle
- // <button onclick="alert(&quot;Hi!&quot;)">
- // without having to entity decode token boundaries.
- for u := []byte(html.UnescapeString(string(s))); len(u) != 0; {
- c1, i1 := transitionFunc[c.state](c, u)
- c, u = c1, u[i1:]
- }
- return c, len(s)
- }
-
- element := c.element
-
- // If this is a non-JS "type" attribute inside "script" tag, do not treat the contents as JS.
- if c.state == stateAttr && c.element == elementScript && c.attr == attrScriptType && !isJSType(string(s[:i])) {
- element = elementNone
- }
-
- if c.delim != delimSpaceOrTagEnd {
- // Consume any quote.
- i++
- }
- // On exiting an attribute, we discard all state information
- // except the state and element.
- return context{state: stateTag, element: element}, i
-}
-
-// editActionNode records a change to an action pipeline for later commit.
-func (e *escaper) editActionNode(n *parse.ActionNode, cmds []string) {
- if _, ok := e.actionNodeEdits[n]; ok {
- panic(fmt.Sprintf("node %s shared between templates", n))
- }
- e.actionNodeEdits[n] = cmds
-}
-
-// editTemplateNode records a change to a {{template}} callee for later commit.
-func (e *escaper) editTemplateNode(n *parse.TemplateNode, callee string) {
- if _, ok := e.templateNodeEdits[n]; ok {
- panic(fmt.Sprintf("node %s shared between templates", n))
- }
- e.templateNodeEdits[n] = callee
-}
-
-// editTextNode records a change to a text node for later commit.
-func (e *escaper) editTextNode(n *parse.TextNode, text []byte) {
- if _, ok := e.textNodeEdits[n]; ok {
- panic(fmt.Sprintf("node %s shared between templates", n))
- }
- e.textNodeEdits[n] = text
-}
-
-// commit applies changes to actions and template calls needed to contextually
-// autoescape content and adds any derived templates to the set.
-func (e *escaper) commit() {
- for name := range e.output {
- e.template(name).Funcs(funcMap)
- }
- // Any template from the name space associated with this escaper can be used
- // to add derived templates to the underlying text/template name space.
- tmpl := e.arbitraryTemplate()
- for _, t := range e.derived {
- if _, err := tmpl.text.AddParseTree(t.Name(), t.Tree); err != nil {
- panic("error adding derived template")
- }
- }
- for n, s := range e.actionNodeEdits {
- ensurePipelineContains(n.Pipe, s)
- }
- for n, name := range e.templateNodeEdits {
- n.Name = name
- }
- for n, s := range e.textNodeEdits {
- n.Text = s
- }
- // Reset state that is specific to this commit so that the same changes are
- // not re-applied to the template on subsequent calls to commit.
- e.called = make(map[string]bool)
- e.actionNodeEdits = make(map[*parse.ActionNode][]string)
- e.templateNodeEdits = make(map[*parse.TemplateNode]string)
- e.textNodeEdits = make(map[*parse.TextNode][]byte)
-}
-
-// template returns the named template given a mangled template name.
-func (e *escaper) template(name string) *template.Template {
- // Any template from the name space associated with this escaper can be used
- // to look up templates in the underlying text/template name space.
- t := e.arbitraryTemplate().text.Lookup(name)
- if t == nil {
- t = e.derived[name]
- }
- return t
-}
-
-// arbitraryTemplate returns an arbitrary template from the name space
-// associated with e and panics if no templates are found.
-func (e *escaper) arbitraryTemplate() *Template {
- for _, t := range e.ns.set {
- return t
- }
- panic("no templates in name space")
-}
-
-// Forwarding functions so that clients need only import this package
-// to reach the general escaping functions of text/template.
-
-// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
-func HTMLEscape(w io.Writer, b []byte) {
- template.HTMLEscape(w, b)
-}
-
-// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
-func HTMLEscapeString(s string) string {
- return template.HTMLEscapeString(s)
-}
-
-// HTMLEscaper returns the escaped HTML equivalent of the textual
-// representation of its arguments.
-func HTMLEscaper(args ...any) string {
- return template.HTMLEscaper(args...)
-}
-
-// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
-func JSEscape(w io.Writer, b []byte) {
- template.JSEscape(w, b)
-}
-
-// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
-func JSEscapeString(s string) string {
- return template.JSEscapeString(s)
-}
-
-// JSEscaper returns the escaped JavaScript equivalent of the textual
-// representation of its arguments.
-func JSEscaper(args ...any) string {
- return template.JSEscaper(args...)
-}
-
-// URLQueryEscaper returns the escaped value of the textual representation of
-// its arguments in a form suitable for embedding in a URL query.
-func URLQueryEscaper(args ...any) string {
- return template.URLQueryEscaper(args...)
-}
diff --git a/contrib/go/_std_1.20/src/html/template/state_string.go b/contrib/go/_std_1.20/src/html/template/state_string.go
deleted file mode 100644
index 6fb1a6eeb0..0000000000
--- a/contrib/go/_std_1.20/src/html/template/state_string.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Code generated by "stringer -type state"; DO NOT EDIT.
-
-package template
-
-import "strconv"
-
-func _() {
- // An "invalid array index" compiler error signifies that the constant values have changed.
- // Re-run the stringer command to generate them again.
- var x [1]struct{}
- _ = x[stateText-0]
- _ = x[stateTag-1]
- _ = x[stateAttrName-2]
- _ = x[stateAfterName-3]
- _ = x[stateBeforeValue-4]
- _ = x[stateHTMLCmt-5]
- _ = x[stateRCDATA-6]
- _ = x[stateAttr-7]
- _ = x[stateURL-8]
- _ = x[stateSrcset-9]
- _ = x[stateJS-10]
- _ = x[stateJSDqStr-11]
- _ = x[stateJSSqStr-12]
- _ = x[stateJSBqStr-13]
- _ = x[stateJSRegexp-14]
- _ = x[stateJSBlockCmt-15]
- _ = x[stateJSLineCmt-16]
- _ = x[stateCSS-17]
- _ = x[stateCSSDqStr-18]
- _ = x[stateCSSSqStr-19]
- _ = x[stateCSSDqURL-20]
- _ = x[stateCSSSqURL-21]
- _ = x[stateCSSURL-22]
- _ = x[stateCSSBlockCmt-23]
- _ = x[stateCSSLineCmt-24]
- _ = x[stateError-25]
- _ = x[stateDead-26]
-}
-
-const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead"
-
-var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 154, 167, 182, 196, 204, 217, 230, 243, 256, 267, 283, 298, 308, 317}
-
-func (i state) String() string {
- if i >= state(len(_state_index)-1) {
- return "state(" + strconv.FormatInt(int64(i), 10) + ")"
- }
- return _state_name[_state_index[i]:_state_index[i+1]]
-}
diff --git a/contrib/go/_std_1.20/src/html/template/transition.go b/contrib/go/_std_1.20/src/html/template/transition.go
deleted file mode 100644
index 92eb351906..0000000000
--- a/contrib/go/_std_1.20/src/html/template/transition.go
+++ /dev/null
@@ -1,597 +0,0 @@
-// Copyright 2011 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 template
-
-import (
- "bytes"
- "strings"
-)
-
-// transitionFunc is the array of context transition functions for text nodes.
-// A transition function takes a context and template text input, and returns
-// the updated context and the number of bytes consumed from the front of the
-// input.
-var transitionFunc = [...]func(context, []byte) (context, int){
- stateText: tText,
- stateTag: tTag,
- stateAttrName: tAttrName,
- stateAfterName: tAfterName,
- stateBeforeValue: tBeforeValue,
- stateHTMLCmt: tHTMLCmt,
- stateRCDATA: tSpecialTagEnd,
- stateAttr: tAttr,
- stateURL: tURL,
- stateSrcset: tURL,
- stateJS: tJS,
- stateJSDqStr: tJSDelimited,
- stateJSSqStr: tJSDelimited,
- stateJSBqStr: tJSDelimited,
- stateJSRegexp: tJSDelimited,
- stateJSBlockCmt: tBlockCmt,
- stateJSLineCmt: tLineCmt,
- stateCSS: tCSS,
- stateCSSDqStr: tCSSStr,
- stateCSSSqStr: tCSSStr,
- stateCSSDqURL: tCSSStr,
- stateCSSSqURL: tCSSStr,
- stateCSSURL: tCSSStr,
- stateCSSBlockCmt: tBlockCmt,
- stateCSSLineCmt: tLineCmt,
- stateError: tError,
-}
-
-var commentStart = []byte("<!--")
-var commentEnd = []byte("-->")
-
-// tText is the context transition function for the text state.
-func tText(c context, s []byte) (context, int) {
- k := 0
- for {
- i := k + bytes.IndexByte(s[k:], '<')
- if i < k || i+1 == len(s) {
- return c, len(s)
- } else if i+4 <= len(s) && bytes.Equal(commentStart, s[i:i+4]) {
- return context{state: stateHTMLCmt}, i + 4
- }
- i++
- end := false
- if s[i] == '/' {
- if i+1 == len(s) {
- return c, len(s)
- }
- end, i = true, i+1
- }
- j, e := eatTagName(s, i)
- if j != i {
- if end {
- e = elementNone
- }
- // We've found an HTML tag.
- return context{state: stateTag, element: e}, j
- }
- k = j
- }
-}
-
-var elementContentType = [...]state{
- elementNone: stateText,
- elementScript: stateJS,
- elementStyle: stateCSS,
- elementTextarea: stateRCDATA,
- elementTitle: stateRCDATA,
-}
-
-// tTag is the context transition function for the tag state.
-func tTag(c context, s []byte) (context, int) {
- // Find the attribute name.
- i := eatWhiteSpace(s, 0)
- if i == len(s) {
- return c, len(s)
- }
- if s[i] == '>' {
- return context{
- state: elementContentType[c.element],
- element: c.element,
- }, i + 1
- }
- j, err := eatAttrName(s, i)
- if err != nil {
- return context{state: stateError, err: err}, len(s)
- }
- state, attr := stateTag, attrNone
- if i == j {
- return context{
- state: stateError,
- err: errorf(ErrBadHTML, nil, 0, "expected space, attr name, or end of tag, but got %q", s[i:]),
- }, len(s)
- }
-
- attrName := strings.ToLower(string(s[i:j]))
- if c.element == elementScript && attrName == "type" {
- attr = attrScriptType
- } else {
- switch attrType(attrName) {
- case contentTypeURL:
- attr = attrURL
- case contentTypeCSS:
- attr = attrStyle
- case contentTypeJS:
- attr = attrScript
- case contentTypeSrcset:
- attr = attrSrcset
- }
- }
-
- if j == len(s) {
- state = stateAttrName
- } else {
- state = stateAfterName
- }
- return context{state: state, element: c.element, attr: attr}, j
-}
-
-// tAttrName is the context transition function for stateAttrName.
-func tAttrName(c context, s []byte) (context, int) {
- i, err := eatAttrName(s, 0)
- if err != nil {
- return context{state: stateError, err: err}, len(s)
- } else if i != len(s) {
- c.state = stateAfterName
- }
- return c, i
-}
-
-// tAfterName is the context transition function for stateAfterName.
-func tAfterName(c context, s []byte) (context, int) {
- // Look for the start of the value.
- i := eatWhiteSpace(s, 0)
- if i == len(s) {
- return c, len(s)
- } else if s[i] != '=' {
- // Occurs due to tag ending '>', and valueless attribute.
- c.state = stateTag
- return c, i
- }
- c.state = stateBeforeValue
- // Consume the "=".
- return c, i + 1
-}
-
-var attrStartStates = [...]state{
- attrNone: stateAttr,
- attrScript: stateJS,
- attrScriptType: stateAttr,
- attrStyle: stateCSS,
- attrURL: stateURL,
- attrSrcset: stateSrcset,
-}
-
-// tBeforeValue is the context transition function for stateBeforeValue.
-func tBeforeValue(c context, s []byte) (context, int) {
- i := eatWhiteSpace(s, 0)
- if i == len(s) {
- return c, len(s)
- }
- // Find the attribute delimiter.
- delim := delimSpaceOrTagEnd
- switch s[i] {
- case '\'':
- delim, i = delimSingleQuote, i+1
- case '"':
- delim, i = delimDoubleQuote, i+1
- }
- c.state, c.delim = attrStartStates[c.attr], delim
- return c, i
-}
-
-// tHTMLCmt is the context transition function for stateHTMLCmt.
-func tHTMLCmt(c context, s []byte) (context, int) {
- if i := bytes.Index(s, commentEnd); i != -1 {
- return context{}, i + 3
- }
- return c, len(s)
-}
-
-// specialTagEndMarkers maps element types to the character sequence that
-// case-insensitively signals the end of the special tag body.
-var specialTagEndMarkers = [...][]byte{
- elementScript: []byte("script"),
- elementStyle: []byte("style"),
- elementTextarea: []byte("textarea"),
- elementTitle: []byte("title"),
-}
-
-var (
- specialTagEndPrefix = []byte("</")
- tagEndSeparators = []byte("> \t\n\f/")
-)
-
-// tSpecialTagEnd is the context transition function for raw text and RCDATA
-// element states.
-func tSpecialTagEnd(c context, s []byte) (context, int) {
- if c.element != elementNone {
- if i := indexTagEnd(s, specialTagEndMarkers[c.element]); i != -1 {
- return context{}, i
- }
- }
- return c, len(s)
-}
-
-// indexTagEnd finds the index of a special tag end in a case insensitive way, or returns -1
-func indexTagEnd(s []byte, tag []byte) int {
- res := 0
- plen := len(specialTagEndPrefix)
- for len(s) > 0 {
- // Try to find the tag end prefix first
- i := bytes.Index(s, specialTagEndPrefix)
- if i == -1 {
- return i
- }
- s = s[i+plen:]
- // Try to match the actual tag if there is still space for it
- if len(tag) <= len(s) && bytes.EqualFold(tag, s[:len(tag)]) {
- s = s[len(tag):]
- // Check the tag is followed by a proper separator
- if len(s) > 0 && bytes.IndexByte(tagEndSeparators, s[0]) != -1 {
- return res + i
- }
- res += len(tag)
- }
- res += i + plen
- }
- return -1
-}
-
-// tAttr is the context transition function for the attribute state.
-func tAttr(c context, s []byte) (context, int) {
- return c, len(s)
-}
-
-// tURL is the context transition function for the URL state.
-func tURL(c context, s []byte) (context, int) {
- if bytes.ContainsAny(s, "#?") {
- c.urlPart = urlPartQueryOrFrag
- } else if len(s) != eatWhiteSpace(s, 0) && c.urlPart == urlPartNone {
- // HTML5 uses "Valid URL potentially surrounded by spaces" for
- // attrs: https://www.w3.org/TR/html5/index.html#attributes-1
- c.urlPart = urlPartPreQuery
- }
- return c, len(s)
-}
-
-// tJS is the context transition function for the JS state.
-func tJS(c context, s []byte) (context, int) {
- i := bytes.IndexAny(s, "\"`'/")
- if i == -1 {
- // Entire input is non string, comment, regexp tokens.
- c.jsCtx = nextJSCtx(s, c.jsCtx)
- return c, len(s)
- }
- c.jsCtx = nextJSCtx(s[:i], c.jsCtx)
- switch s[i] {
- case '"':
- c.state, c.jsCtx = stateJSDqStr, jsCtxRegexp
- case '\'':
- c.state, c.jsCtx = stateJSSqStr, jsCtxRegexp
- case '`':
- c.state, c.jsCtx = stateJSBqStr, jsCtxRegexp
- case '/':
- switch {
- case i+1 < len(s) && s[i+1] == '/':
- c.state, i = stateJSLineCmt, i+1
- case i+1 < len(s) && s[i+1] == '*':
- c.state, i = stateJSBlockCmt, i+1
- case c.jsCtx == jsCtxRegexp:
- c.state = stateJSRegexp
- case c.jsCtx == jsCtxDivOp:
- c.jsCtx = jsCtxRegexp
- default:
- return context{
- state: stateError,
- err: errorf(ErrSlashAmbig, nil, 0, "'/' could start a division or regexp: %.32q", s[i:]),
- }, len(s)
- }
- default:
- panic("unreachable")
- }
- return c, i + 1
-}
-
-// tJSDelimited is the context transition function for the JS string and regexp
-// states.
-func tJSDelimited(c context, s []byte) (context, int) {
- specials := `\"`
- switch c.state {
- case stateJSSqStr:
- specials = `\'`
- case stateJSBqStr:
- specials = "`\\"
- case stateJSRegexp:
- specials = `\/[]`
- }
-
- k, inCharset := 0, false
- for {
- i := k + bytes.IndexAny(s[k:], specials)
- if i < k {
- break
- }
- switch s[i] {
- case '\\':
- i++
- if i == len(s) {
- return context{
- state: stateError,
- err: errorf(ErrPartialEscape, nil, 0, "unfinished escape sequence in JS string: %q", s),
- }, len(s)
- }
- case '[':
- inCharset = true
- case ']':
- inCharset = false
- default:
- // end delimiter
- if !inCharset {
- c.state, c.jsCtx = stateJS, jsCtxDivOp
- return c, i + 1
- }
- }
- k = i + 1
- }
-
- if inCharset {
- // This can be fixed by making context richer if interpolation
- // into charsets is desired.
- return context{
- state: stateError,
- err: errorf(ErrPartialCharset, nil, 0, "unfinished JS regexp charset: %q", s),
- }, len(s)
- }
-
- return c, len(s)
-}
-
-var blockCommentEnd = []byte("*/")
-
-// tBlockCmt is the context transition function for /*comment*/ states.
-func tBlockCmt(c context, s []byte) (context, int) {
- i := bytes.Index(s, blockCommentEnd)
- if i == -1 {
- return c, len(s)
- }
- switch c.state {
- case stateJSBlockCmt:
- c.state = stateJS
- case stateCSSBlockCmt:
- c.state = stateCSS
- default:
- panic(c.state.String())
- }
- return c, i + 2
-}
-
-// tLineCmt is the context transition function for //comment states.
-func tLineCmt(c context, s []byte) (context, int) {
- var lineTerminators string
- var endState state
- switch c.state {
- case stateJSLineCmt:
- lineTerminators, endState = "\n\r\u2028\u2029", stateJS
- case stateCSSLineCmt:
- lineTerminators, endState = "\n\f\r", stateCSS
- // Line comments are not part of any published CSS standard but
- // are supported by the 4 major browsers.
- // This defines line comments as
- // LINECOMMENT ::= "//" [^\n\f\d]*
- // since https://www.w3.org/TR/css3-syntax/#SUBTOK-nl defines
- // newlines:
- // nl ::= #xA | #xD #xA | #xD | #xC
- default:
- panic(c.state.String())
- }
-
- i := bytes.IndexAny(s, lineTerminators)
- if i == -1 {
- return c, len(s)
- }
- c.state = endState
- // Per section 7.4 of EcmaScript 5 : https://es5.github.com/#x7.4
- // "However, the LineTerminator at the end of the line is not
- // considered to be part of the single-line comment; it is
- // recognized separately by the lexical grammar and becomes part
- // of the stream of input elements for the syntactic grammar."
- return c, i
-}
-
-// tCSS is the context transition function for the CSS state.
-func tCSS(c context, s []byte) (context, int) {
- // CSS quoted strings are almost never used except for:
- // (1) URLs as in background: "/foo.png"
- // (2) Multiword font-names as in font-family: "Times New Roman"
- // (3) List separators in content values as in inline-lists:
- // <style>
- // ul.inlineList { list-style: none; padding:0 }
- // ul.inlineList > li { display: inline }
- // ul.inlineList > li:before { content: ", " }
- // ul.inlineList > li:first-child:before { content: "" }
- // </style>
- // <ul class=inlineList><li>One<li>Two<li>Three</ul>
- // (4) Attribute value selectors as in a[href="http://example.com/"]
- //
- // We conservatively treat all strings as URLs, but make some
- // allowances to avoid confusion.
- //
- // In (1), our conservative assumption is justified.
- // In (2), valid font names do not contain ':', '?', or '#', so our
- // conservative assumption is fine since we will never transition past
- // urlPartPreQuery.
- // In (3), our protocol heuristic should not be tripped, and there
- // should not be non-space content after a '?' or '#', so as long as
- // we only %-encode RFC 3986 reserved characters we are ok.
- // In (4), we should URL escape for URL attributes, and for others we
- // have the attribute name available if our conservative assumption
- // proves problematic for real code.
-
- k := 0
- for {
- i := k + bytes.IndexAny(s[k:], `("'/`)
- if i < k {
- return c, len(s)
- }
- switch s[i] {
- case '(':
- // Look for url to the left.
- p := bytes.TrimRight(s[:i], "\t\n\f\r ")
- if endsWithCSSKeyword(p, "url") {
- j := len(s) - len(bytes.TrimLeft(s[i+1:], "\t\n\f\r "))
- switch {
- case j != len(s) && s[j] == '"':
- c.state, j = stateCSSDqURL, j+1
- case j != len(s) && s[j] == '\'':
- c.state, j = stateCSSSqURL, j+1
- default:
- c.state = stateCSSURL
- }
- return c, j
- }
- case '/':
- if i+1 < len(s) {
- switch s[i+1] {
- case '/':
- c.state = stateCSSLineCmt
- return c, i + 2
- case '*':
- c.state = stateCSSBlockCmt
- return c, i + 2
- }
- }
- case '"':
- c.state = stateCSSDqStr
- return c, i + 1
- case '\'':
- c.state = stateCSSSqStr
- return c, i + 1
- }
- k = i + 1
- }
-}
-
-// tCSSStr is the context transition function for the CSS string and URL states.
-func tCSSStr(c context, s []byte) (context, int) {
- var endAndEsc string
- switch c.state {
- case stateCSSDqStr, stateCSSDqURL:
- endAndEsc = `\"`
- case stateCSSSqStr, stateCSSSqURL:
- endAndEsc = `\'`
- case stateCSSURL:
- // Unquoted URLs end with a newline or close parenthesis.
- // The below includes the wc (whitespace character) and nl.
- endAndEsc = "\\\t\n\f\r )"
- default:
- panic(c.state.String())
- }
-
- k := 0
- for {
- i := k + bytes.IndexAny(s[k:], endAndEsc)
- if i < k {
- c, nread := tURL(c, decodeCSS(s[k:]))
- return c, k + nread
- }
- if s[i] == '\\' {
- i++
- if i == len(s) {
- return context{
- state: stateError,
- err: errorf(ErrPartialEscape, nil, 0, "unfinished escape sequence in CSS string: %q", s),
- }, len(s)
- }
- } else {
- c.state = stateCSS
- return c, i + 1
- }
- c, _ = tURL(c, decodeCSS(s[:i+1]))
- k = i + 1
- }
-}
-
-// tError is the context transition function for the error state.
-func tError(c context, s []byte) (context, int) {
- return c, len(s)
-}
-
-// eatAttrName returns the largest j such that s[i:j] is an attribute name.
-// It returns an error if s[i:] does not look like it begins with an
-// attribute name, such as encountering a quote mark without a preceding
-// equals sign.
-func eatAttrName(s []byte, i int) (int, *Error) {
- for j := i; j < len(s); j++ {
- switch s[j] {
- case ' ', '\t', '\n', '\f', '\r', '=', '>':
- return j, nil
- case '\'', '"', '<':
- // These result in a parse warning in HTML5 and are
- // indicative of serious problems if seen in an attr
- // name in a template.
- return -1, errorf(ErrBadHTML, nil, 0, "%q in attribute name: %.32q", s[j:j+1], s)
- default:
- // No-op.
- }
- }
- return len(s), nil
-}
-
-var elementNameMap = map[string]element{
- "script": elementScript,
- "style": elementStyle,
- "textarea": elementTextarea,
- "title": elementTitle,
-}
-
-// asciiAlpha reports whether c is an ASCII letter.
-func asciiAlpha(c byte) bool {
- return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
-}
-
-// asciiAlphaNum reports whether c is an ASCII letter or digit.
-func asciiAlphaNum(c byte) bool {
- return asciiAlpha(c) || '0' <= c && c <= '9'
-}
-
-// eatTagName returns the largest j such that s[i:j] is a tag name and the tag type.
-func eatTagName(s []byte, i int) (int, element) {
- if i == len(s) || !asciiAlpha(s[i]) {
- return i, elementNone
- }
- j := i + 1
- for j < len(s) {
- x := s[j]
- if asciiAlphaNum(x) {
- j++
- continue
- }
- // Allow "x-y" or "x:y" but not "x-", "-y", or "x--y".
- if (x == ':' || x == '-') && j+1 < len(s) && asciiAlphaNum(s[j+1]) {
- j += 2
- continue
- }
- break
- }
- return j, elementNameMap[strings.ToLower(string(s[i:j]))]
-}
-
-// eatWhiteSpace returns the largest j such that s[i:j] is white space.
-func eatWhiteSpace(s []byte, i int) int {
- for j := i; j < len(s); j++ {
- switch s[j] {
- case ' ', '\t', '\n', '\f', '\r':
- // No-op.
- default:
- return j
- }
- }
- return len(s)
-}
diff --git a/contrib/go/_std_1.20/src/html/template/urlpart_string.go b/contrib/go/_std_1.20/src/html/template/urlpart_string.go
deleted file mode 100644
index 813eea9e44..0000000000
--- a/contrib/go/_std_1.20/src/html/template/urlpart_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Code generated by "stringer -type urlPart"; DO NOT EDIT.
-
-package template
-
-import "strconv"
-
-const _urlPart_name = "urlPartNoneurlPartPreQueryurlPartQueryOrFragurlPartUnknown"
-
-var _urlPart_index = [...]uint8{0, 11, 26, 44, 58}
-
-func (i urlPart) String() string {
- if i >= urlPart(len(_urlPart_index)-1) {
- return "urlPart(" + strconv.FormatInt(int64(i), 10) + ")"
- }
- return _urlPart_name[_urlPart_index[i]:_urlPart_index[i+1]]
-}
diff --git a/contrib/go/_std_1.20/src/html/template/ya.make b/contrib/go/_std_1.20/src/html/template/ya.make
deleted file mode 100644
index d05924f283..0000000000
--- a/contrib/go/_std_1.20/src/html/template/ya.make
+++ /dev/null
@@ -1,24 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- attr.go
- attr_string.go
- content.go
- context.go
- css.go
- delim_string.go
- doc.go
- element_string.go
- error.go
- escape.go
- html.go
- js.go
- jsctx_string.go
- state_string.go
- template.go
- transition.go
- url.go
- urlpart_string.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/html/ya.make b/contrib/go/_std_1.20/src/html/ya.make
deleted file mode 100644
index 99892066f0..0000000000
--- a/contrib/go/_std_1.20/src/html/ya.make
+++ /dev/null
@@ -1,12 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- entity.go
- escape.go
-)
-
-END()
-
-RECURSE(
- template
-)
diff --git a/contrib/go/_std_1.20/src/image/color/ya.make b/contrib/go/_std_1.20/src/image/color/ya.make
deleted file mode 100644
index 14392ffdda..0000000000
--- a/contrib/go/_std_1.20/src/image/color/ya.make
+++ /dev/null
@@ -1,12 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- color.go
- ycbcr.go
-)
-
-END()
-
-RECURSE(
- palette
-)
diff --git a/contrib/go/_std_1.20/src/image/ya.make b/contrib/go/_std_1.20/src/image/ya.make
deleted file mode 100644
index 290d91bf77..0000000000
--- a/contrib/go/_std_1.20/src/image/ya.make
+++ /dev/null
@@ -1,20 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- format.go
- geom.go
- image.go
- names.go
- ycbcr.go
-)
-
-END()
-
-RECURSE(
- color
- draw
- gif
- internal
- jpeg
- png
-)
diff --git a/contrib/go/_std_1.20/src/internal/abi/abi.go b/contrib/go/_std_1.20/src/internal/abi/abi.go
deleted file mode 100644
index 11acac346f..0000000000
--- a/contrib/go/_std_1.20/src/internal/abi/abi.go
+++ /dev/null
@@ -1,126 +0,0 @@
-// 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 abi
-
-import (
- "internal/goarch"
- "unsafe"
-)
-
-// RegArgs is a struct that has space for each argument
-// and return value register on the current architecture.
-//
-// Assembly code knows the layout of the first two fields
-// of RegArgs.
-//
-// RegArgs also contains additional space to hold pointers
-// when it may not be safe to keep them only in the integer
-// register space otherwise.
-type RegArgs struct {
- // Values in these slots should be precisely the bit-by-bit
- // representation of how they would appear in a register.
- //
- // This means that on big endian arches, integer values should
- // be in the top bits of the slot. Floats are usually just
- // directly represented, but some architectures treat narrow
- // width floating point values specially (e.g. they're promoted
- // first, or they need to be NaN-boxed).
- Ints [IntArgRegs]uintptr // untyped integer registers
- Floats [FloatArgRegs]uint64 // untyped float registers
-
- // Fields above this point are known to assembly.
-
- // Ptrs is a space that duplicates Ints but with pointer type,
- // used to make pointers passed or returned in registers
- // visible to the GC by making the type unsafe.Pointer.
- Ptrs [IntArgRegs]unsafe.Pointer
-
- // ReturnIsPtr is a bitmap that indicates which registers
- // contain or will contain pointers on the return path from
- // a reflectcall. The i'th bit indicates whether the i'th
- // register contains or will contain a valid Go pointer.
- ReturnIsPtr IntArgRegBitmap
-}
-
-func (r *RegArgs) Dump() {
- print("Ints:")
- for _, x := range r.Ints {
- print(" ", x)
- }
- println()
- print("Floats:")
- for _, x := range r.Floats {
- print(" ", x)
- }
- println()
- print("Ptrs:")
- for _, x := range r.Ptrs {
- print(" ", x)
- }
- println()
-}
-
-// IntRegArgAddr returns a pointer inside of r.Ints[reg] that is appropriately
-// offset for an argument of size argSize.
-//
-// argSize must be non-zero, fit in a register, and a power-of-two.
-//
-// This method is a helper for dealing with the endianness of different CPU
-// architectures, since sub-word-sized arguments in big endian architectures
-// need to be "aligned" to the upper edge of the register to be interpreted
-// by the CPU correctly.
-func (r *RegArgs) IntRegArgAddr(reg int, argSize uintptr) unsafe.Pointer {
- if argSize > goarch.PtrSize || argSize == 0 || argSize&(argSize-1) != 0 {
- panic("invalid argSize")
- }
- offset := uintptr(0)
- if goarch.BigEndian {
- offset = goarch.PtrSize - argSize
- }
- return unsafe.Pointer(uintptr(unsafe.Pointer(&r.Ints[reg])) + offset)
-}
-
-// IntArgRegBitmap is a bitmap large enough to hold one bit per
-// integer argument/return register.
-type IntArgRegBitmap [(IntArgRegs + 7) / 8]uint8
-
-// Set sets the i'th bit of the bitmap to 1.
-func (b *IntArgRegBitmap) Set(i int) {
- b[i/8] |= uint8(1) << (i % 8)
-}
-
-// Get returns whether the i'th bit of the bitmap is set.
-//
-// nosplit because it's called in extremely sensitive contexts, like
-// on the reflectcall return path.
-//
-//go:nosplit
-func (b *IntArgRegBitmap) Get(i int) bool {
- return b[i/8]&(uint8(1)<<(i%8)) != 0
-}
-
-// FuncPC* intrinsics.
-//
-// CAREFUL: In programs with plugins, FuncPC* can return different values
-// for the same function (because there are actually multiple copies of
-// the same function in the address space). To be safe, don't use the
-// results of this function in any == expression. It is only safe to
-// use the result as an address at which to start executing code.
-
-// FuncPCABI0 returns the entry PC of the function f, which must be a
-// direct reference of a function defined as ABI0. Otherwise it is a
-// compile-time error.
-//
-// Implemented as a compile intrinsic.
-func FuncPCABI0(f any) uintptr
-
-// FuncPCABIInternal returns the entry PC of the function f. If f is a
-// direct reference of a function, it must be defined as ABIInternal.
-// Otherwise it is a compile-time error. If f is not a direct reference
-// of a defined function, it assumes that f is a func value. Otherwise
-// the behavior is undefined.
-//
-// Implemented as a compile intrinsic.
-func FuncPCABIInternal(f any) uintptr
diff --git a/contrib/go/_std_1.20/src/internal/abi/ya.make b/contrib/go/_std_1.20/src/internal/abi/ya.make
deleted file mode 100644
index 640da81aac..0000000000
--- a/contrib/go/_std_1.20/src/internal/abi/ya.make
+++ /dev/null
@@ -1,20 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- abi.go
- abi_test.s
-)
-
-IF (ARCH_ARM64)
- SRCS(
- abi_arm64.go
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- abi_amd64.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/buildcfg/cfg.go b/contrib/go/_std_1.20/src/internal/buildcfg/cfg.go
deleted file mode 100644
index a0736aaf74..0000000000
--- a/contrib/go/_std_1.20/src/internal/buildcfg/cfg.go
+++ /dev/null
@@ -1,234 +0,0 @@
-// 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 buildcfg provides access to the build configuration
-// described by the current environment. It is for use by build tools
-// such as cmd/go or cmd/compile and for setting up go/build's Default context.
-//
-// Note that it does NOT provide access to the build configuration used to
-// build the currently-running binary. For that, use runtime.GOOS etc
-// as well as internal/goexperiment.
-package buildcfg
-
-import (
- "fmt"
- "os"
- "path/filepath"
- "runtime"
- "strings"
-)
-
-var (
- GOROOT = runtime.GOROOT() // cached for efficiency
- GOARCH = envOr("GOARCH", defaultGOARCH)
- GOOS = envOr("GOOS", defaultGOOS)
- GO386 = envOr("GO386", defaultGO386)
- GOAMD64 = goamd64()
- GOARM = goarm()
- GOMIPS = gomips()
- GOMIPS64 = gomips64()
- GOPPC64 = goppc64()
- GOWASM = gowasm()
- ToolTags = toolTags()
- GO_LDSO = defaultGO_LDSO
- Version = version
-)
-
-// Error is one of the errors found (if any) in the build configuration.
-var Error error
-
-// Check exits the program with a fatal error if Error is non-nil.
-func Check() {
- if Error != nil {
- fmt.Fprintf(os.Stderr, "%s: %v\n", filepath.Base(os.Args[0]), Error)
- os.Exit(2)
- }
-}
-
-func envOr(key, value string) string {
- if x := os.Getenv(key); x != "" {
- return x
- }
- return value
-}
-
-func goamd64() int {
- switch v := envOr("GOAMD64", defaultGOAMD64); v {
- case "v1":
- return 1
- case "v2":
- return 2
- case "v3":
- return 3
- case "v4":
- return 4
- }
- Error = fmt.Errorf("invalid GOAMD64: must be v1, v2, v3, v4")
- return int(defaultGOAMD64[len("v")] - '0')
-}
-
-func goarm() int {
- def := defaultGOARM
- if GOOS == "android" && GOARCH == "arm" {
- // Android arm devices always support GOARM=7.
- def = "7"
- }
- switch v := envOr("GOARM", def); v {
- case "5":
- return 5
- case "6":
- return 6
- case "7":
- return 7
- }
- Error = fmt.Errorf("invalid GOARM: must be 5, 6, 7")
- return int(def[0] - '0')
-}
-
-func gomips() string {
- switch v := envOr("GOMIPS", defaultGOMIPS); v {
- case "hardfloat", "softfloat":
- return v
- }
- Error = fmt.Errorf("invalid GOMIPS: must be hardfloat, softfloat")
- return defaultGOMIPS
-}
-
-func gomips64() string {
- switch v := envOr("GOMIPS64", defaultGOMIPS64); v {
- case "hardfloat", "softfloat":
- return v
- }
- Error = fmt.Errorf("invalid GOMIPS64: must be hardfloat, softfloat")
- return defaultGOMIPS64
-}
-
-func goppc64() int {
- switch v := envOr("GOPPC64", defaultGOPPC64); v {
- case "power8":
- return 8
- case "power9":
- return 9
- case "power10":
- return 10
- }
- Error = fmt.Errorf("invalid GOPPC64: must be power8, power9, power10")
- return int(defaultGOPPC64[len("power")] - '0')
-}
-
-type gowasmFeatures struct {
- SatConv bool
- SignExt bool
-}
-
-func (f gowasmFeatures) String() string {
- var flags []string
- if f.SatConv {
- flags = append(flags, "satconv")
- }
- if f.SignExt {
- flags = append(flags, "signext")
- }
- return strings.Join(flags, ",")
-}
-
-func gowasm() (f gowasmFeatures) {
- for _, opt := range strings.Split(envOr("GOWASM", ""), ",") {
- switch opt {
- case "satconv":
- f.SatConv = true
- case "signext":
- f.SignExt = true
- case "":
- // ignore
- default:
- Error = fmt.Errorf("invalid GOWASM: no such feature %q", opt)
- }
- }
- return
-}
-
-func Getgoextlinkenabled() string {
- return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
-}
-
-func toolTags() []string {
- tags := experimentTags()
- tags = append(tags, gogoarchTags()...)
- return tags
-}
-
-func experimentTags() []string {
- var list []string
- // For each experiment that has been enabled in the toolchain, define a
- // build tag with the same name but prefixed by "goexperiment." which can be
- // used for compiling alternative files for the experiment. This allows
- // changes for the experiment, like extra struct fields in the runtime,
- // without affecting the base non-experiment code at all.
- for _, exp := range Experiment.Enabled() {
- list = append(list, "goexperiment."+exp)
- }
- return list
-}
-
-// GOGOARCH returns the name and value of the GO$GOARCH setting.
-// For example, if GOARCH is "amd64" it might return "GOAMD64", "v2".
-func GOGOARCH() (name, value string) {
- switch GOARCH {
- case "386":
- return "GO386", GO386
- case "amd64":
- return "GOAMD64", fmt.Sprintf("v%d", GOAMD64)
- case "arm":
- return "GOARM", fmt.Sprintf("%d", GOARM)
- case "mips", "mipsle":
- return "GOMIPS", GOMIPS
- case "mips64", "mips64le":
- return "GOMIPS64", GOMIPS64
- case "ppc64", "ppc64le":
- return "GOPPC64", fmt.Sprintf("power%d", GOPPC64)
- case "wasm":
- return "GOWASM", GOWASM.String()
- }
- return "", ""
-}
-
-func gogoarchTags() []string {
- switch GOARCH {
- case "386":
- return []string{GOARCH + "." + GO386}
- case "amd64":
- var list []string
- for i := 1; i <= GOAMD64; i++ {
- list = append(list, fmt.Sprintf("%s.v%d", GOARCH, i))
- }
- return list
- case "arm":
- var list []string
- for i := 5; i <= GOARM; i++ {
- list = append(list, fmt.Sprintf("%s.%d", GOARCH, i))
- }
- return list
- case "mips", "mipsle":
- return []string{GOARCH + "." + GOMIPS}
- case "mips64", "mips64le":
- return []string{GOARCH + "." + GOMIPS64}
- case "ppc64", "ppc64le":
- var list []string
- for i := 8; i <= GOPPC64; i++ {
- list = append(list, fmt.Sprintf("%s.power%d", GOARCH, i))
- }
- return list
- case "wasm":
- var list []string
- if GOWASM.SatConv {
- list = append(list, GOARCH+".satconv")
- }
- if GOWASM.SignExt {
- list = append(list, GOARCH+".signext")
- }
- return list
- }
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/buildcfg/exp.go b/contrib/go/_std_1.20/src/internal/buildcfg/exp.go
deleted file mode 100644
index 546a68d335..0000000000
--- a/contrib/go/_std_1.20/src/internal/buildcfg/exp.go
+++ /dev/null
@@ -1,190 +0,0 @@
-// 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 buildcfg
-
-import (
- "fmt"
- "internal/goexperiment"
- "reflect"
- "strings"
-)
-
-// ExperimentFlags represents a set of GOEXPERIMENT flags relative to a baseline
-// (platform-default) experiment configuration.
-type ExperimentFlags struct {
- goexperiment.Flags
- baseline goexperiment.Flags
-}
-
-// Experiment contains the toolchain experiments enabled for the
-// current build.
-//
-// (This is not necessarily the set of experiments the compiler itself
-// was built with.)
-//
-// experimentBaseline specifies the experiment flags that are enabled by
-// default in the current toolchain. This is, in effect, the "control"
-// configuration and any variation from this is an experiment.
-var Experiment ExperimentFlags = func() ExperimentFlags {
- flags, err := ParseGOEXPERIMENT(GOOS, GOARCH, envOr("GOEXPERIMENT", defaultGOEXPERIMENT))
- if err != nil {
- Error = err
- return ExperimentFlags{}
- }
- return *flags
-}()
-
-// DefaultGOEXPERIMENT is the embedded default GOEXPERIMENT string.
-// It is not guaranteed to be canonical.
-const DefaultGOEXPERIMENT = defaultGOEXPERIMENT
-
-// FramePointerEnabled enables the use of platform conventions for
-// saving frame pointers.
-//
-// This used to be an experiment, but now it's always enabled on
-// platforms that support it.
-//
-// Note: must agree with runtime.framepointer_enabled.
-var FramePointerEnabled = GOARCH == "amd64" || GOARCH == "arm64"
-
-// ParseGOEXPERIMENT parses a (GOOS, GOARCH, GOEXPERIMENT)
-// configuration tuple and returns the enabled and baseline experiment
-// flag sets.
-//
-// TODO(mdempsky): Move to internal/goexperiment.
-func ParseGOEXPERIMENT(goos, goarch, goexp string) (*ExperimentFlags, error) {
- // regabiSupported is set to true on platforms where register ABI is
- // supported and enabled by default.
- // regabiAlwaysOn is set to true on platforms where register ABI is
- // always on.
- var regabiSupported, regabiAlwaysOn bool
- switch goarch {
- case "amd64", "arm64", "ppc64le", "ppc64", "riscv64":
- regabiAlwaysOn = true
- regabiSupported = true
- }
-
- baseline := goexperiment.Flags{
- RegabiWrappers: regabiSupported,
- RegabiArgs: regabiSupported,
- Unified: true,
- CoverageRedesign: true,
- }
-
- // Start with the statically enabled set of experiments.
- flags := &ExperimentFlags{
- Flags: baseline,
- baseline: baseline,
- }
-
- // Pick up any changes to the baseline configuration from the
- // GOEXPERIMENT environment. This can be set at make.bash time
- // and overridden at build time.
- if goexp != "" {
- // Create a map of known experiment names.
- names := make(map[string]func(bool))
- rv := reflect.ValueOf(&flags.Flags).Elem()
- rt := rv.Type()
- for i := 0; i < rt.NumField(); i++ {
- field := rv.Field(i)
- names[strings.ToLower(rt.Field(i).Name)] = field.SetBool
- }
-
- // "regabi" is an alias for all working regabi
- // subexperiments, and not an experiment itself. Doing
- // this as an alias make both "regabi" and "noregabi"
- // do the right thing.
- names["regabi"] = func(v bool) {
- flags.RegabiWrappers = v
- flags.RegabiArgs = v
- }
-
- // Parse names.
- for _, f := range strings.Split(goexp, ",") {
- if f == "" {
- continue
- }
- if f == "none" {
- // GOEXPERIMENT=none disables all experiment flags.
- // This is used by cmd/dist, which doesn't know how
- // to build with any experiment flags.
- flags.Flags = goexperiment.Flags{}
- continue
- }
- val := true
- if strings.HasPrefix(f, "no") {
- f, val = f[2:], false
- }
- set, ok := names[f]
- if !ok {
- return nil, fmt.Errorf("unknown GOEXPERIMENT %s", f)
- }
- set(val)
- }
- }
-
- if regabiAlwaysOn {
- flags.RegabiWrappers = true
- flags.RegabiArgs = true
- }
- // regabi is only supported on amd64, arm64, riscv64, ppc64 and ppc64le.
- if !regabiSupported {
- flags.RegabiWrappers = false
- flags.RegabiArgs = false
- }
- // Check regabi dependencies.
- if flags.RegabiArgs && !flags.RegabiWrappers {
- return nil, fmt.Errorf("GOEXPERIMENT regabiargs requires regabiwrappers")
- }
- return flags, nil
-}
-
-// String returns the canonical GOEXPERIMENT string to enable this experiment
-// configuration. (Experiments in the same state as in the baseline are elided.)
-func (exp *ExperimentFlags) String() string {
- return strings.Join(expList(&exp.Flags, &exp.baseline, false), ",")
-}
-
-// expList returns the list of lower-cased experiment names for
-// experiments that differ from base. base may be nil to indicate no
-// experiments. If all is true, then include all experiment flags,
-// regardless of base.
-func expList(exp, base *goexperiment.Flags, all bool) []string {
- var list []string
- rv := reflect.ValueOf(exp).Elem()
- var rBase reflect.Value
- if base != nil {
- rBase = reflect.ValueOf(base).Elem()
- }
- rt := rv.Type()
- for i := 0; i < rt.NumField(); i++ {
- name := strings.ToLower(rt.Field(i).Name)
- val := rv.Field(i).Bool()
- baseVal := false
- if base != nil {
- baseVal = rBase.Field(i).Bool()
- }
- if all || val != baseVal {
- if val {
- list = append(list, name)
- } else {
- list = append(list, "no"+name)
- }
- }
- }
- return list
-}
-
-// Enabled returns a list of enabled experiments, as
-// lower-cased experiment names.
-func (exp *ExperimentFlags) Enabled() []string {
- return expList(&exp.Flags, nil, false)
-}
-
-// All returns a list of all experiment settings.
-// Disabled experiments appear in the list prefixed by "no".
-func (exp *ExperimentFlags) All() []string {
- return expList(&exp.Flags, nil, true)
-}
diff --git a/contrib/go/_std_1.20/src/internal/buildcfg/ya.make b/contrib/go/_std_1.20/src/internal/buildcfg/ya.make
deleted file mode 100644
index 616e2ae44d..0000000000
--- a/contrib/go/_std_1.20/src/internal/buildcfg/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- cfg.go
- exp.go
- zbootstrap.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/buildcfg/zbootstrap.go b/contrib/go/_std_1.20/src/internal/buildcfg/zbootstrap.go
deleted file mode 100644
index 2035d68b60..0000000000
--- a/contrib/go/_std_1.20/src/internal/buildcfg/zbootstrap.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Code generated by go tool dist; DO NOT EDIT.
-
-package buildcfg
-
-import "runtime"
-
-const defaultGO386 = `sse2`
-const defaultGOAMD64 = `v1`
-const defaultGOARM = `5`
-const defaultGOMIPS = `hardfloat`
-const defaultGOMIPS64 = `hardfloat`
-const defaultGOPPC64 = `power8`
-const defaultGOEXPERIMENT = ``
-const defaultGO_EXTLINK_ENABLED = ``
-const defaultGO_LDSO = ``
-const version = `go1.20.4`
-const defaultGOOS = runtime.GOOS
-const defaultGOARCH = runtime.GOARCH
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/bytealg.go b/contrib/go/_std_1.20/src/internal/bytealg/bytealg.go
deleted file mode 100644
index ebebce75fe..0000000000
--- a/contrib/go/_std_1.20/src/internal/bytealg/bytealg.go
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2018 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 bytealg
-
-import (
- "internal/cpu"
- "unsafe"
-)
-
-// Offsets into internal/cpu records for use in assembly.
-const (
- offsetX86HasSSE42 = unsafe.Offsetof(cpu.X86.HasSSE42)
- offsetX86HasAVX2 = unsafe.Offsetof(cpu.X86.HasAVX2)
- offsetX86HasPOPCNT = unsafe.Offsetof(cpu.X86.HasPOPCNT)
-
- offsetS390xHasVX = unsafe.Offsetof(cpu.S390X.HasVX)
-
- offsetPPC64HasPOWER9 = unsafe.Offsetof(cpu.PPC64.IsPOWER9)
-)
-
-// MaxLen is the maximum length of the string to be searched for (argument b) in Index.
-// If MaxLen is not 0, make sure MaxLen >= 4.
-var MaxLen int
-
-// FIXME: the logic of HashStrBytes, HashStrRevBytes, IndexRabinKarpBytes and HashStr, HashStrRev,
-// IndexRabinKarp are exactly the same, except that the types are different. Can we eliminate
-// three of them without causing allocation?
-
-// PrimeRK is the prime base used in Rabin-Karp algorithm.
-const PrimeRK = 16777619
-
-// HashStrBytes returns the hash and the appropriate multiplicative
-// factor for use in Rabin-Karp algorithm.
-func HashStrBytes(sep []byte) (uint32, uint32) {
- hash := uint32(0)
- for i := 0; i < len(sep); i++ {
- hash = hash*PrimeRK + uint32(sep[i])
- }
- var pow, sq uint32 = 1, PrimeRK
- for i := len(sep); i > 0; i >>= 1 {
- if i&1 != 0 {
- pow *= sq
- }
- sq *= sq
- }
- return hash, pow
-}
-
-// HashStr returns the hash and the appropriate multiplicative
-// factor for use in Rabin-Karp algorithm.
-func HashStr(sep string) (uint32, uint32) {
- hash := uint32(0)
- for i := 0; i < len(sep); i++ {
- hash = hash*PrimeRK + uint32(sep[i])
- }
- var pow, sq uint32 = 1, PrimeRK
- for i := len(sep); i > 0; i >>= 1 {
- if i&1 != 0 {
- pow *= sq
- }
- sq *= sq
- }
- return hash, pow
-}
-
-// HashStrRevBytes returns the hash of the reverse of sep and the
-// appropriate multiplicative factor for use in Rabin-Karp algorithm.
-func HashStrRevBytes(sep []byte) (uint32, uint32) {
- hash := uint32(0)
- for i := len(sep) - 1; i >= 0; i-- {
- hash = hash*PrimeRK + uint32(sep[i])
- }
- var pow, sq uint32 = 1, PrimeRK
- for i := len(sep); i > 0; i >>= 1 {
- if i&1 != 0 {
- pow *= sq
- }
- sq *= sq
- }
- return hash, pow
-}
-
-// HashStrRev returns the hash of the reverse of sep and the
-// appropriate multiplicative factor for use in Rabin-Karp algorithm.
-func HashStrRev(sep string) (uint32, uint32) {
- hash := uint32(0)
- for i := len(sep) - 1; i >= 0; i-- {
- hash = hash*PrimeRK + uint32(sep[i])
- }
- var pow, sq uint32 = 1, PrimeRK
- for i := len(sep); i > 0; i >>= 1 {
- if i&1 != 0 {
- pow *= sq
- }
- sq *= sq
- }
- return hash, pow
-}
-
-// IndexRabinKarpBytes uses the Rabin-Karp search algorithm to return the index of the
-// first occurrence of substr in s, or -1 if not present.
-func IndexRabinKarpBytes(s, sep []byte) int {
- // Rabin-Karp search
- hashsep, pow := HashStrBytes(sep)
- n := len(sep)
- var h uint32
- for i := 0; i < n; i++ {
- h = h*PrimeRK + uint32(s[i])
- }
- if h == hashsep && Equal(s[:n], sep) {
- return 0
- }
- for i := n; i < len(s); {
- h *= PrimeRK
- h += uint32(s[i])
- h -= pow * uint32(s[i-n])
- i++
- if h == hashsep && Equal(s[i-n:i], sep) {
- return i - n
- }
- }
- return -1
-}
-
-// IndexRabinKarp uses the Rabin-Karp search algorithm to return the index of the
-// first occurrence of substr in s, or -1 if not present.
-func IndexRabinKarp(s, substr string) int {
- // Rabin-Karp search
- hashss, pow := HashStr(substr)
- n := len(substr)
- var h uint32
- for i := 0; i < n; i++ {
- h = h*PrimeRK + uint32(s[i])
- }
- if h == hashss && s[:n] == substr {
- return 0
- }
- for i := n; i < len(s); {
- h *= PrimeRK
- h += uint32(s[i])
- h -= pow * uint32(s[i-n])
- i++
- if h == hashss && s[i-n:i] == substr {
- return i - n
- }
- }
- return -1
-}
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/index_native.go b/contrib/go/_std_1.20/src/internal/bytealg/index_native.go
deleted file mode 100644
index 6e4a2f39e4..0000000000
--- a/contrib/go/_std_1.20/src/internal/bytealg/index_native.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2018 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.
-
-//go:build amd64 || arm64 || s390x || ppc64le || ppc64
-
-package bytealg
-
-//go:noescape
-
-// Index returns the index of the first instance of b in a, or -1 if b is not present in a.
-// Requires 2 <= len(b) <= MaxLen.
-func Index(a, b []byte) int
-
-//go:noescape
-
-// IndexString returns the index of the first instance of b in a, or -1 if b is not present in a.
-// Requires 2 <= len(b) <= MaxLen.
-func IndexString(a, b string) int
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/ya.make b/contrib/go/_std_1.20/src/internal/bytealg/ya.make
deleted file mode 100644
index 16cb4d0eea..0000000000
--- a/contrib/go/_std_1.20/src/internal/bytealg/ya.make
+++ /dev/null
@@ -1,35 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- bytealg.go
- compare_native.go
- count_native.go
- equal_generic.go
- equal_native.go
- index_native.go
- indexbyte_native.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- compare_arm64.s
- count_arm64.s
- equal_arm64.s
- index_arm64.go
- index_arm64.s
- indexbyte_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- compare_amd64.s
- count_amd64.s
- equal_amd64.s
- index_amd64.go
- index_amd64.s
- indexbyte_amd64.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/coverage/cformat/format.go b/contrib/go/_std_1.20/src/internal/coverage/cformat/format.go
deleted file mode 100644
index a8276ff124..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/cformat/format.go
+++ /dev/null
@@ -1,340 +0,0 @@
-// Copyright 2022 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 cformat
-
-// This package provides apis for producing human-readable summaries
-// of coverage data (e.g. a coverage percentage for a given package or
-// set of packages) and for writing data in the legacy test format
-// emitted by "go test -coverprofile=<outfile>".
-//
-// The model for using these apis is to create a Formatter object,
-// then make a series of calls to SetPackage and AddUnit passing in
-// data read from coverage meta-data and counter-data files. E.g.
-//
-// myformatter := cformat.NewFormatter()
-// ...
-// for each package P in meta-data file: {
-// myformatter.SetPackage(P)
-// for each function F in P: {
-// for each coverable unit U in F: {
-// myformatter.AddUnit(U)
-// }
-// }
-// }
-// myformatter.EmitPercent(os.Stdout, "")
-// myformatter.EmitTextual(somefile)
-//
-// These apis are linked into tests that are built with "-cover", and
-// called at the end of test execution to produce text output or
-// emit coverage percentages.
-
-import (
- "fmt"
- "internal/coverage"
- "internal/coverage/cmerge"
- "io"
- "sort"
- "text/tabwriter"
-)
-
-type Formatter struct {
- // Maps import path to package state.
- pm map[string]*pstate
- // Records current package being visited.
- pkg string
- // Pointer to current package state.
- p *pstate
- // Counter mode.
- cm coverage.CounterMode
-}
-
-// pstate records package-level coverage data state:
-// - a table of functions (file/fname/literal)
-// - a map recording the index/ID of each func encountered so far
-// - a table storing execution count for the coverable units in each func
-type pstate struct {
- // slice of unique functions
- funcs []fnfile
- // maps function to index in slice above (index acts as function ID)
- funcTable map[fnfile]uint32
-
- // A table storing coverage counts for each coverable unit.
- unitTable map[extcu]uint32
-}
-
-// extcu encapsulates a coverable unit within some function.
-type extcu struct {
- fnfid uint32 // index into p.funcs slice
- coverage.CoverableUnit
-}
-
-// fnfile is a function-name/file-name tuple.
-type fnfile struct {
- file string
- fname string
- lit bool
-}
-
-func NewFormatter(cm coverage.CounterMode) *Formatter {
- return &Formatter{
- pm: make(map[string]*pstate),
- cm: cm,
- }
-}
-
-// SetPackage tells the formatter that we're about to visit the
-// coverage data for the package with the specified import path.
-// Note that it's OK to call SetPackage more than once with the
-// same import path; counter data values will be accumulated.
-func (fm *Formatter) SetPackage(importpath string) {
- if importpath == fm.pkg {
- return
- }
- fm.pkg = importpath
- ps, ok := fm.pm[importpath]
- if !ok {
- ps = new(pstate)
- fm.pm[importpath] = ps
- ps.unitTable = make(map[extcu]uint32)
- ps.funcTable = make(map[fnfile]uint32)
- }
- fm.p = ps
-}
-
-// AddUnit passes info on a single coverable unit (file, funcname,
-// literal flag, range of lines, and counter value) to the formatter.
-// Counter values will be accumulated where appropriate.
-func (fm *Formatter) AddUnit(file string, fname string, isfnlit bool, unit coverage.CoverableUnit, count uint32) {
- if fm.p == nil {
- panic("AddUnit invoked before SetPackage")
- }
- fkey := fnfile{file: file, fname: fname, lit: isfnlit}
- idx, ok := fm.p.funcTable[fkey]
- if !ok {
- idx = uint32(len(fm.p.funcs))
- fm.p.funcs = append(fm.p.funcs, fkey)
- fm.p.funcTable[fkey] = idx
- }
- ukey := extcu{fnfid: idx, CoverableUnit: unit}
- pcount := fm.p.unitTable[ukey]
- var result uint32
- if fm.cm == coverage.CtrModeSet {
- if count != 0 || pcount != 0 {
- result = 1
- }
- } else {
- // Use saturating arithmetic.
- result, _ = cmerge.SaturatingAdd(pcount, count)
- }
- fm.p.unitTable[ukey] = result
-}
-
-// sortUnits sorts a slice of extcu objects in a package according to
-// source position information (e.g. file and line). Note that we don't
-// include function name as part of the sorting criteria, the thinking
-// being that is better to provide things in the original source order.
-func (p *pstate) sortUnits(units []extcu) {
- sort.Slice(units, func(i, j int) bool {
- ui := units[i]
- uj := units[j]
- ifile := p.funcs[ui.fnfid].file
- jfile := p.funcs[uj.fnfid].file
- if ifile != jfile {
- return ifile < jfile
- }
- // NB: not taking function literal flag into account here (no
- // need, since other fields are guaranteed to be distinct).
- if units[i].StLine != units[j].StLine {
- return units[i].StLine < units[j].StLine
- }
- if units[i].EnLine != units[j].EnLine {
- return units[i].EnLine < units[j].EnLine
- }
- if units[i].StCol != units[j].StCol {
- return units[i].StCol < units[j].StCol
- }
- if units[i].EnCol != units[j].EnCol {
- return units[i].EnCol < units[j].EnCol
- }
- return units[i].NxStmts < units[j].NxStmts
- })
-}
-
-// EmitTextual writes the accumulated coverage data in the legacy
-// cmd/cover text format to the writer 'w'. We sort the data items by
-// importpath, source file, and line number before emitting (this sorting
-// is not explicitly mandated by the format, but seems like a good idea
-// for repeatable/deterministic dumps).
-func (fm *Formatter) EmitTextual(w io.Writer) error {
- if fm.cm == coverage.CtrModeInvalid {
- panic("internal error, counter mode unset")
- }
- if _, err := fmt.Fprintf(w, "mode: %s\n", fm.cm.String()); err != nil {
- return err
- }
- pkgs := make([]string, 0, len(fm.pm))
- for importpath := range fm.pm {
- pkgs = append(pkgs, importpath)
- }
- sort.Strings(pkgs)
- for _, importpath := range pkgs {
- p := fm.pm[importpath]
- units := make([]extcu, 0, len(p.unitTable))
- for u := range p.unitTable {
- units = append(units, u)
- }
- p.sortUnits(units)
- for _, u := range units {
- count := p.unitTable[u]
- file := p.funcs[u.fnfid].file
- if _, err := fmt.Fprintf(w, "%s:%d.%d,%d.%d %d %d\n",
- file, u.StLine, u.StCol,
- u.EnLine, u.EnCol, u.NxStmts, count); err != nil {
- return err
- }
- }
- }
- return nil
-}
-
-// EmitPercent writes out a "percentage covered" string to the writer 'w'.
-func (fm *Formatter) EmitPercent(w io.Writer, covpkgs string, noteEmpty bool) error {
- pkgs := make([]string, 0, len(fm.pm))
- for importpath := range fm.pm {
- pkgs = append(pkgs, importpath)
- }
- sort.Strings(pkgs)
- seenPkg := false
- for _, importpath := range pkgs {
- seenPkg = true
- p := fm.pm[importpath]
- var totalStmts, coveredStmts uint64
- for unit, count := range p.unitTable {
- nx := uint64(unit.NxStmts)
- totalStmts += nx
- if count != 0 {
- coveredStmts += nx
- }
- }
- if _, err := fmt.Fprintf(w, "\t%s\t", importpath); err != nil {
- return err
- }
- if totalStmts == 0 {
- if _, err := fmt.Fprintf(w, "coverage: [no statements]\n"); err != nil {
- return err
- }
- } else {
- if _, err := fmt.Fprintf(w, "coverage: %.1f%% of statements%s\n", 100*float64(coveredStmts)/float64(totalStmts), covpkgs); err != nil {
- return err
- }
- }
- }
- if noteEmpty && !seenPkg {
- if _, err := fmt.Fprintf(w, "coverage: [no statements]\n"); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// EmitFuncs writes out a function-level summary to the writer 'w'. A
-// note on handling function literals: although we collect coverage
-// data for unnamed literals, it probably does not make sense to
-// include them in the function summary since there isn't any good way
-// to name them (this is also consistent with the legacy cmd/cover
-// implementation). We do want to include their counts in the overall
-// summary however.
-func (fm *Formatter) EmitFuncs(w io.Writer) error {
- if fm.cm == coverage.CtrModeInvalid {
- panic("internal error, counter mode unset")
- }
- perc := func(covered, total uint64) float64 {
- if total == 0 {
- total = 1
- }
- return 100.0 * float64(covered) / float64(total)
- }
- tabber := tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
- defer tabber.Flush()
- allStmts := uint64(0)
- covStmts := uint64(0)
-
- pkgs := make([]string, 0, len(fm.pm))
- for importpath := range fm.pm {
- pkgs = append(pkgs, importpath)
- }
- sort.Strings(pkgs)
-
- // Emit functions for each package, sorted by import path.
- for _, importpath := range pkgs {
- p := fm.pm[importpath]
- if len(p.unitTable) == 0 {
- continue
- }
- units := make([]extcu, 0, len(p.unitTable))
- for u := range p.unitTable {
- units = append(units, u)
- }
-
- // Within a package, sort the units, then walk through the
- // sorted array. Each time we hit a new function, emit the
- // summary entry for the previous function, then make one last
- // emit call at the end of the loop.
- p.sortUnits(units)
- fname := ""
- ffile := ""
- flit := false
- var fline uint32
- var cstmts, tstmts uint64
- captureFuncStart := func(u extcu) {
- fname = p.funcs[u.fnfid].fname
- ffile = p.funcs[u.fnfid].file
- flit = p.funcs[u.fnfid].lit
- fline = u.StLine
- }
- emitFunc := func(u extcu) error {
- // Don't emit entries for function literals (see discussion
- // in function header comment above).
- if !flit {
- if _, err := fmt.Fprintf(tabber, "%s:%d:\t%s\t%.1f%%\n",
- ffile, fline, fname, perc(cstmts, tstmts)); err != nil {
- return err
- }
- }
- captureFuncStart(u)
- allStmts += tstmts
- covStmts += cstmts
- tstmts = 0
- cstmts = 0
- return nil
- }
- for k, u := range units {
- if k == 0 {
- captureFuncStart(u)
- } else {
- if fname != p.funcs[u.fnfid].fname {
- // New function; emit entry for previous one.
- if err := emitFunc(u); err != nil {
- return err
- }
- }
- }
- tstmts += uint64(u.NxStmts)
- count := p.unitTable[u]
- if count != 0 {
- cstmts += uint64(u.NxStmts)
- }
- }
- if err := emitFunc(extcu{}); err != nil {
- return err
- }
- }
- if _, err := fmt.Fprintf(tabber, "%s\t%s\t%.1f%%\n",
- "total", "(statements)", perc(covStmts, allStmts)); err != nil {
- return err
- }
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/coverage/cformat/ya.make b/contrib/go/_std_1.20/src/internal/coverage/cformat/ya.make
deleted file mode 100644
index 2f71b28c69..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/cformat/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- format.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/coverage/cmddefs.go b/contrib/go/_std_1.20/src/internal/coverage/cmddefs.go
deleted file mode 100644
index b30c37a08f..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/cmddefs.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2022 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 coverage
-
-// CoverPkgConfig is a bundle of information passed from the Go
-// command to the cover command during "go build -cover" runs. The
-// Go command creates and fills in a struct as below, then passes
-// file containing the encoded JSON for the struct to the "cover"
-// tool when instrumenting the source files in a Go package.
-type CoverPkgConfig struct {
- // File into which cmd/cover should emit summary info
- // when instrumentation is complete.
- OutConfig string
-
- // Import path for the package being instrumented.
- PkgPath string
-
- // Package name.
- PkgName string
-
- // Instrumentation granularity: one of "perfunc" or "perblock" (default)
- Granularity string
-
- // Module path for this package (empty if no go.mod in use)
- ModulePath string
-
- // Local mode indicates we're doing a coverage build or test of a
- // package selected via local import path, e.g. "./..." or
- // "./foo/bar" as opposed to a non-relative import path. See the
- // corresponding field in cmd/go's PackageInternal struct for more
- // info.
- Local bool
-}
-
-// CoverFixupConfig contains annotations/notes generated by the
-// cmd/cover tool (during instrumentation) to be passed on to the
-// compiler when the instrumented code is compiled. The cmd/cover tool
-// creates a struct of this type, JSON-encodes it, and emits the
-// result to a file, which the Go command then passes to the compiler
-// when the instrumented package is built.
-type CoverFixupConfig struct {
- // Name of the variable (created by cmd/cover) containing the
- // encoded meta-data for the package.
- MetaVar string
-
- // Length of the meta-data.
- MetaLen int
-
- // Hash computed by cmd/cover of the meta-data.
- MetaHash string
-
- // Instrumentation strategy. For now this is always set to
- // "normal", but in the future we may add new values (for example,
- // if panic paths are instrumented, or if the instrumenter
- // eliminates redundant counters).
- Strategy string
-
- // Prefix assigned to the names of counter variables generated
- // during instrumentation by cmd/cover.
- CounterPrefix string
-
- // Name chosen for the package ID variable generated during
- // instrumentation.
- PkgIdVar string
-
- // Counter mode (e.g. set/count/atomic)
- CounterMode string
-
- // Counter granularity (perblock or perfunc).
- CounterGranularity string
-}
diff --git a/contrib/go/_std_1.20/src/internal/coverage/cmerge/merge.go b/contrib/go/_std_1.20/src/internal/coverage/cmerge/merge.go
deleted file mode 100644
index c482b8bfa8..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/cmerge/merge.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2022 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 cmerge
-
-// package cmerge provides a few small utility APIs for helping
-// with merging of counter data for a given function.
-
-import (
- "fmt"
- "internal/coverage"
- "math"
-)
-
-// Merger provides state and methods to help manage the process of
-// merging together coverage counter data for a given function, for
-// tools that need to implicitly merge counter as they read multiple
-// coverage counter data files.
-type Merger struct {
- cmode coverage.CounterMode
- cgran coverage.CounterGranularity
- overflow bool
-}
-
-// MergeCounters takes the counter values in 'src' and merges them
-// into 'dst' according to the correct counter mode.
-func (m *Merger) MergeCounters(dst, src []uint32) (error, bool) {
- if len(src) != len(dst) {
- return fmt.Errorf("merging counters: len(dst)=%d len(src)=%d", len(dst), len(src)), false
- }
- if m.cmode == coverage.CtrModeSet {
- for i := 0; i < len(src); i++ {
- if src[i] != 0 {
- dst[i] = 1
- }
- }
- } else {
- for i := 0; i < len(src); i++ {
- dst[i] = m.SaturatingAdd(dst[i], src[i])
- }
- }
- ovf := m.overflow
- m.overflow = false
- return nil, ovf
-}
-
-// Saturating add does a saturating addition of 'dst' and 'src',
-// returning added value or math.MaxUint32 if there is an overflow.
-// Overflows are recorded in case the client needs to track them.
-func (m *Merger) SaturatingAdd(dst, src uint32) uint32 {
- result, overflow := SaturatingAdd(dst, src)
- if overflow {
- m.overflow = true
- }
- return result
-}
-
-// Saturating add does a saturing addition of 'dst' and 'src',
-// returning added value or math.MaxUint32 plus an overflow flag.
-func SaturatingAdd(dst, src uint32) (uint32, bool) {
- d, s := uint64(dst), uint64(src)
- sum := d + s
- overflow := false
- if uint64(uint32(sum)) != sum {
- overflow = true
- sum = math.MaxUint32
- }
- return uint32(sum), overflow
-}
-
-// SetModeAndGranularity records the counter mode and granularity for
-// the current merge. In the specific case of merging across coverage
-// data files from different binaries, where we're combining data from
-// more than one meta-data file, we need to check for mode/granularity
-// clashes.
-func (cm *Merger) SetModeAndGranularity(mdf string, cmode coverage.CounterMode, cgran coverage.CounterGranularity) error {
- // Collect counter mode and granularity so as to detect clashes.
- if cm.cmode != coverage.CtrModeInvalid {
- if cm.cmode != cmode {
- return fmt.Errorf("counter mode clash while reading meta-data file %s: previous file had %s, new file has %s", mdf, cm.cmode.String(), cmode.String())
- }
- if cm.cgran != cgran {
- return fmt.Errorf("counter granularity clash while reading meta-data file %s: previous file had %s, new file has %s", mdf, cm.cgran.String(), cgran.String())
- }
- }
- cm.cmode = cmode
- cm.cgran = cgran
- return nil
-}
-
-func (cm *Merger) ResetModeAndGranularity() {
- cm.cmode = coverage.CtrModeInvalid
- cm.cgran = coverage.CtrGranularityInvalid
- cm.overflow = false
-}
-
-func (cm *Merger) Mode() coverage.CounterMode {
- return cm.cmode
-}
-
-func (cm *Merger) Granularity() coverage.CounterGranularity {
- return cm.cgran
-}
diff --git a/contrib/go/_std_1.20/src/internal/coverage/cmerge/ya.make b/contrib/go/_std_1.20/src/internal/coverage/cmerge/ya.make
deleted file mode 100644
index 3014b57456..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/cmerge/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- merge.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/coverage/decodecounter/decodecounterfile.go b/contrib/go/_std_1.20/src/internal/coverage/decodecounter/decodecounterfile.go
deleted file mode 100644
index fce060aaba..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/decodecounter/decodecounterfile.go
+++ /dev/null
@@ -1,373 +0,0 @@
-// 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 decodecounter
-
-import (
- "encoding/binary"
- "fmt"
- "internal/coverage"
- "internal/coverage/slicereader"
- "internal/coverage/stringtab"
- "io"
- "os"
- "strconv"
- "unsafe"
-)
-
-// This file contains helpers for reading counter data files created
-// during the executions of a coverage-instrumented binary.
-
-type CounterDataReader struct {
- stab *stringtab.Reader
- args map[string]string
- osargs []string
- goarch string // GOARCH setting from run that produced counter data
- goos string // GOOS setting from run that produced counter data
- mr io.ReadSeeker
- hdr coverage.CounterFileHeader
- ftr coverage.CounterFileFooter
- shdr coverage.CounterSegmentHeader
- u32b []byte
- u8b []byte
- fcnCount uint32
- segCount uint32
- debug bool
-}
-
-func NewCounterDataReader(fn string, rs io.ReadSeeker) (*CounterDataReader, error) {
- cdr := &CounterDataReader{
- mr: rs,
- u32b: make([]byte, 4),
- u8b: make([]byte, 1),
- }
- // Read header
- if err := binary.Read(rs, binary.LittleEndian, &cdr.hdr); err != nil {
- return nil, err
- }
- if cdr.debug {
- fmt.Fprintf(os.Stderr, "=-= counter file header: %+v\n", cdr.hdr)
- }
- if !checkMagic(cdr.hdr.Magic) {
- return nil, fmt.Errorf("invalid magic string: not a counter data file")
- }
- if cdr.hdr.Version > coverage.CounterFileVersion {
- return nil, fmt.Errorf("version data incompatibility: reader is %d data is %d", coverage.CounterFileVersion, cdr.hdr.Version)
- }
-
- // Read footer.
- if err := cdr.readFooter(); err != nil {
- return nil, err
- }
- // Seek back to just past the file header.
- hsz := int64(unsafe.Sizeof(cdr.hdr))
- if _, err := cdr.mr.Seek(hsz, io.SeekStart); err != nil {
- return nil, err
- }
- // Read preamble for first segment.
- if err := cdr.readSegmentPreamble(); err != nil {
- return nil, err
- }
- return cdr, nil
-}
-
-func checkMagic(v [4]byte) bool {
- g := coverage.CovCounterMagic
- return v[0] == g[0] && v[1] == g[1] && v[2] == g[2] && v[3] == g[3]
-}
-
-func (cdr *CounterDataReader) readFooter() error {
- ftrSize := int64(unsafe.Sizeof(cdr.ftr))
- if _, err := cdr.mr.Seek(-ftrSize, io.SeekEnd); err != nil {
- return err
- }
- if err := binary.Read(cdr.mr, binary.LittleEndian, &cdr.ftr); err != nil {
- return err
- }
- if !checkMagic(cdr.ftr.Magic) {
- return fmt.Errorf("invalid magic string (not a counter data file)")
- }
- if cdr.ftr.NumSegments == 0 {
- return fmt.Errorf("invalid counter data file (no segments)")
- }
- return nil
-}
-
-// readSegmentPreamble reads and consumes the segment header, segment string
-// table, and segment args table.
-func (cdr *CounterDataReader) readSegmentPreamble() error {
- // Read segment header.
- if err := binary.Read(cdr.mr, binary.LittleEndian, &cdr.shdr); err != nil {
- return err
- }
- if cdr.debug {
- fmt.Fprintf(os.Stderr, "=-= read counter segment header: %+v", cdr.shdr)
- fmt.Fprintf(os.Stderr, " FcnEntries=0x%x StrTabLen=0x%x ArgsLen=0x%x\n",
- cdr.shdr.FcnEntries, cdr.shdr.StrTabLen, cdr.shdr.ArgsLen)
- }
-
- // Read string table and args.
- if err := cdr.readStringTable(); err != nil {
- return err
- }
- if err := cdr.readArgs(); err != nil {
- return err
- }
- // Seek past any padding to bring us up to a 4-byte boundary.
- if of, err := cdr.mr.Seek(0, io.SeekCurrent); err != nil {
- return err
- } else {
- rem := of % 4
- if rem != 0 {
- pad := 4 - rem
- if _, err := cdr.mr.Seek(pad, io.SeekCurrent); err != nil {
- return err
- }
- }
- }
- return nil
-}
-
-func (cdr *CounterDataReader) readStringTable() error {
- b := make([]byte, cdr.shdr.StrTabLen)
- nr, err := cdr.mr.Read(b)
- if err != nil {
- return err
- }
- if nr != int(cdr.shdr.StrTabLen) {
- return fmt.Errorf("error: short read on string table")
- }
- slr := slicereader.NewReader(b, false /* not readonly */)
- cdr.stab = stringtab.NewReader(slr)
- cdr.stab.Read()
- return nil
-}
-
-func (cdr *CounterDataReader) readArgs() error {
- b := make([]byte, cdr.shdr.ArgsLen)
- nr, err := cdr.mr.Read(b)
- if err != nil {
- return err
- }
- if nr != int(cdr.shdr.ArgsLen) {
- return fmt.Errorf("error: short read on args table")
- }
- slr := slicereader.NewReader(b, false /* not readonly */)
- sget := func() (string, error) {
- kidx := slr.ReadULEB128()
- if int(kidx) >= cdr.stab.Entries() {
- return "", fmt.Errorf("malformed string table ref")
- }
- return cdr.stab.Get(uint32(kidx)), nil
- }
- nents := slr.ReadULEB128()
- cdr.args = make(map[string]string, int(nents))
- for i := uint64(0); i < nents; i++ {
- k, errk := sget()
- if errk != nil {
- return errk
- }
- v, errv := sget()
- if errv != nil {
- return errv
- }
- if _, ok := cdr.args[k]; ok {
- return fmt.Errorf("malformed args table")
- }
- cdr.args[k] = v
- }
- if argcs, ok := cdr.args["argc"]; ok {
- argc, err := strconv.Atoi(argcs)
- if err != nil {
- return fmt.Errorf("malformed argc in counter data file args section")
- }
- cdr.osargs = make([]string, 0, argc)
- for i := 0; i < argc; i++ {
- arg := cdr.args[fmt.Sprintf("argv%d", i)]
- cdr.osargs = append(cdr.osargs, arg)
- }
- }
- if goos, ok := cdr.args["GOOS"]; ok {
- cdr.goos = goos
- }
- if goarch, ok := cdr.args["GOARCH"]; ok {
- cdr.goarch = goarch
- }
- return nil
-}
-
-// OsArgs returns the program arguments (saved from os.Args during
-// the run of the instrumented binary) read from the counter
-// data file. Not all coverage data files will have os.Args values;
-// for example, if a data file is produced by merging coverage
-// data from two distinct runs, no os args will be available (an
-// empty list is returned).
-func (cdr *CounterDataReader) OsArgs() []string {
- return cdr.osargs
-}
-
-// Goos returns the GOOS setting in effect for the "-cover" binary
-// that produced this counter data file. The GOOS value may be
-// empty in the case where the counter data file was produced
-// from a merge in which more than one GOOS value was present.
-func (cdr *CounterDataReader) Goos() string {
- return cdr.goos
-}
-
-// Goarch returns the GOARCH setting in effect for the "-cover" binary
-// that produced this counter data file. The GOARCH value may be
-// empty in the case where the counter data file was produced
-// from a merge in which more than one GOARCH value was present.
-func (cdr *CounterDataReader) Goarch() string {
- return cdr.goarch
-}
-
-// FuncPayload encapsulates the counter data payload for a single
-// function as read from a counter data file.
-type FuncPayload struct {
- PkgIdx uint32
- FuncIdx uint32
- Counters []uint32
-}
-
-// NumSegments returns the number of execution segments in the file.
-func (cdr *CounterDataReader) NumSegments() uint32 {
- return cdr.ftr.NumSegments
-}
-
-// BeginNextSegment sets up the the reader to read the next segment,
-// returning TRUE if we do have another segment to read, or FALSE
-// if we're done with all the segments (also an error if
-// something went wrong).
-func (cdr *CounterDataReader) BeginNextSegment() (bool, error) {
- if cdr.segCount >= cdr.ftr.NumSegments {
- return false, nil
- }
- cdr.segCount++
- cdr.fcnCount = 0
- // Seek past footer from last segment.
- ftrSize := int64(unsafe.Sizeof(cdr.ftr))
- if _, err := cdr.mr.Seek(ftrSize, io.SeekCurrent); err != nil {
- return false, err
- }
- // Read preamble for this segment.
- if err := cdr.readSegmentPreamble(); err != nil {
- return false, err
- }
- return true, nil
-}
-
-// NumFunctionsInSegment returns the number of live functions
-// in the currently selected segment.
-func (cdr *CounterDataReader) NumFunctionsInSegment() uint32 {
- return uint32(cdr.shdr.FcnEntries)
-}
-
-const supportDeadFunctionsInCounterData = false
-
-// NextFunc reads data for the next function in this current segment
-// into "p", returning TRUE if the read was successful or FALSE
-// if we've read all the functions already (also an error if
-// something went wrong with the read or we hit a premature
-// EOF).
-func (cdr *CounterDataReader) NextFunc(p *FuncPayload) (bool, error) {
- if cdr.fcnCount >= uint32(cdr.shdr.FcnEntries) {
- return false, nil
- }
- cdr.fcnCount++
- var rdu32 func() (uint32, error)
- if cdr.hdr.CFlavor == coverage.CtrULeb128 {
- rdu32 = func() (uint32, error) {
- var shift uint
- var value uint64
- for {
- _, err := cdr.mr.Read(cdr.u8b)
- if err != nil {
- return 0, err
- }
- b := cdr.u8b[0]
- value |= (uint64(b&0x7F) << shift)
- if b&0x80 == 0 {
- break
- }
- shift += 7
- }
- return uint32(value), nil
- }
- } else if cdr.hdr.CFlavor == coverage.CtrRaw {
- if cdr.hdr.BigEndian {
- rdu32 = func() (uint32, error) {
- n, err := cdr.mr.Read(cdr.u32b)
- if err != nil {
- return 0, err
- }
- if n != 4 {
- return 0, io.EOF
- }
- return binary.BigEndian.Uint32(cdr.u32b), nil
- }
- } else {
- rdu32 = func() (uint32, error) {
- n, err := cdr.mr.Read(cdr.u32b)
- if err != nil {
- return 0, err
- }
- if n != 4 {
- return 0, io.EOF
- }
- return binary.LittleEndian.Uint32(cdr.u32b), nil
- }
- }
- } else {
- panic("internal error: unknown counter flavor")
- }
-
- // Alternative/experimental path: one way we could handling writing
- // out counter data would be to just memcpy the counter segment
- // out to a file, meaning that a region in the counter memory
- // corresponding to a dead (never-executed) function would just be
- // zeroes. The code path below handles this case.
- var nc uint32
- var err error
- if supportDeadFunctionsInCounterData {
- for {
- nc, err = rdu32()
- if err == io.EOF {
- return false, io.EOF
- } else if err != nil {
- break
- }
- if nc != 0 {
- break
- }
- }
- } else {
- nc, err = rdu32()
- }
- if err != nil {
- return false, err
- }
-
- // Read package and func indices.
- p.PkgIdx, err = rdu32()
- if err != nil {
- return false, err
- }
- p.FuncIdx, err = rdu32()
- if err != nil {
- return false, err
- }
- if cap(p.Counters) < 1024 {
- p.Counters = make([]uint32, 0, 1024)
- }
- p.Counters = p.Counters[:0]
- for i := uint32(0); i < nc; i++ {
- v, err := rdu32()
- if err != nil {
- return false, err
- }
- p.Counters = append(p.Counters, v)
- }
- return true, nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/coverage/decodemeta/decode.go b/contrib/go/_std_1.20/src/internal/coverage/decodemeta/decode.go
deleted file mode 100644
index 71f1c567ab..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/decodemeta/decode.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// 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 decodemeta
-
-// This package contains APIs and helpers for decoding a single package's
-// meta data "blob" emitted by the compiler when coverage instrumentation
-// is turned on.
-
-import (
- "encoding/binary"
- "fmt"
- "internal/coverage"
- "internal/coverage/slicereader"
- "internal/coverage/stringtab"
- "os"
-)
-
-// See comments in the encodecovmeta package for details on the format.
-
-type CoverageMetaDataDecoder struct {
- r *slicereader.Reader
- hdr coverage.MetaSymbolHeader
- strtab *stringtab.Reader
- tmp []byte
- debug bool
-}
-
-func NewCoverageMetaDataDecoder(b []byte, readonly bool) (*CoverageMetaDataDecoder, error) {
- slr := slicereader.NewReader(b, readonly)
- x := &CoverageMetaDataDecoder{
- r: slr,
- tmp: make([]byte, 0, 256),
- }
- if err := x.readHeader(); err != nil {
- return nil, err
- }
- if err := x.readStringTable(); err != nil {
- return nil, err
- }
- return x, nil
-}
-
-func (d *CoverageMetaDataDecoder) readHeader() error {
- if err := binary.Read(d.r, binary.LittleEndian, &d.hdr); err != nil {
- return err
- }
- if d.debug {
- fmt.Fprintf(os.Stderr, "=-= after readHeader: %+v\n", d.hdr)
- }
- return nil
-}
-
-func (d *CoverageMetaDataDecoder) readStringTable() error {
- // Seek to the correct location to read the string table.
- stringTableLocation := int64(coverage.CovMetaHeaderSize + 4*d.hdr.NumFuncs)
- d.r.SeekTo(stringTableLocation)
-
- // Read the table itself.
- d.strtab = stringtab.NewReader(d.r)
- d.strtab.Read()
- return nil
-}
-
-func (d *CoverageMetaDataDecoder) PackagePath() string {
- return d.strtab.Get(d.hdr.PkgPath)
-}
-
-func (d *CoverageMetaDataDecoder) PackageName() string {
- return d.strtab.Get(d.hdr.PkgName)
-}
-
-func (d *CoverageMetaDataDecoder) ModulePath() string {
- return d.strtab.Get(d.hdr.ModulePath)
-}
-
-func (d *CoverageMetaDataDecoder) NumFuncs() uint32 {
- return d.hdr.NumFuncs
-}
-
-// ReadFunc reads the coverage meta-data for the function with index
-// 'findex', filling it into the FuncDesc pointed to by 'f'.
-func (d *CoverageMetaDataDecoder) ReadFunc(fidx uint32, f *coverage.FuncDesc) error {
- if fidx >= d.hdr.NumFuncs {
- return fmt.Errorf("illegal function index")
- }
-
- // Seek to the correct location to read the function offset and read it.
- funcOffsetLocation := int64(coverage.CovMetaHeaderSize + 4*fidx)
- d.r.SeekTo(funcOffsetLocation)
- foff := d.r.ReadUint32()
-
- // Check assumptions
- if foff < uint32(funcOffsetLocation) || foff > d.hdr.Length {
- return fmt.Errorf("malformed func offset %d", foff)
- }
-
- // Seek to the correct location to read the function.
- d.r.SeekTo(int64(foff))
-
- // Preamble containing number of units, file, and function.
- numUnits := uint32(d.r.ReadULEB128())
- fnameidx := uint32(d.r.ReadULEB128())
- fileidx := uint32(d.r.ReadULEB128())
-
- f.Srcfile = d.strtab.Get(fileidx)
- f.Funcname = d.strtab.Get(fnameidx)
-
- // Now the units
- f.Units = f.Units[:0]
- if cap(f.Units) < int(numUnits) {
- f.Units = make([]coverage.CoverableUnit, 0, numUnits)
- }
- for k := uint32(0); k < numUnits; k++ {
- f.Units = append(f.Units,
- coverage.CoverableUnit{
- StLine: uint32(d.r.ReadULEB128()),
- StCol: uint32(d.r.ReadULEB128()),
- EnLine: uint32(d.r.ReadULEB128()),
- EnCol: uint32(d.r.ReadULEB128()),
- NxStmts: uint32(d.r.ReadULEB128()),
- })
- }
- lit := d.r.ReadULEB128()
- f.Lit = lit != 0
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/coverage/defs.go b/contrib/go/_std_1.20/src/internal/coverage/defs.go
deleted file mode 100644
index 4a41f57efd..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/defs.go
+++ /dev/null
@@ -1,374 +0,0 @@
-// Copyright 2022 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 coverage
-
-// Types and constants related to the output files files written
-// by code coverage tooling. When a coverage-instrumented binary
-// is run, it emits two output files: a meta-data output file, and
-// a counter data output file.
-
-//.....................................................................
-//
-// Meta-data definitions:
-//
-// The meta-data file is composed of a file header, a series of
-// meta-data blobs/sections (one per instrumented package), and an offsets
-// area storing the offsets of each section. Format of the meta-data
-// file looks like:
-//
-// --header----------
-// | magic: [4]byte magic string
-// | version
-// | total length of meta-data file in bytes
-// | numPkgs: number of package entries in file
-// | hash: [16]byte hash of entire meta-data payload
-// | offset to string table section
-// | length of string table
-// | number of entries in string table
-// | counter mode
-// | counter granularity
-// --package offsets table------
-// <offset to pkg 0>
-// <offset to pkg 1>
-// ...
-// --package lengths table------
-// <length of pkg 0>
-// <length of pkg 1>
-// ...
-// --string table------
-// <uleb128 len> 8
-// <data> "somestring"
-// ...
-// --package payloads------
-// <meta-symbol for pkg 0>
-// <meta-symbol for pkg 1>
-// ...
-//
-// Each package payload is a stand-alone blob emitted by the compiler,
-// and does not depend on anything else in the meta-data file. In
-// particular, each blob has it's own string table. Note that the
-// file-level string table is expected to be very short (most strings
-// will be in the meta-data blobs themselves).
-
-// CovMetaMagic holds the magic string for a meta-data file.
-var CovMetaMagic = [4]byte{'\x00', '\x63', '\x76', '\x6d'}
-
-// MetaFilePref is a prefix used when emitting meta-data files; these
-// files are of the form "covmeta.<hash>", where hash is a hash
-// computed from the hashes of all the package meta-data symbols in
-// the program.
-const MetaFilePref = "covmeta"
-
-// MetaFileVersion contains the current (most recent) meta-data file version.
-const MetaFileVersion = 1
-
-// MetaFileHeader stores file header information for a meta-data file.
-type MetaFileHeader struct {
- Magic [4]byte
- Version uint32
- TotalLength uint64
- Entries uint64
- MetaFileHash [16]byte
- StrTabOffset uint32
- StrTabLength uint32
- CMode CounterMode
- CGranularity CounterGranularity
- _ [6]byte // padding
-}
-
-// MetaSymbolHeader stores header information for a single
-// meta-data blob, e.g. the coverage meta-data payload
-// computed for a given Go package.
-type MetaSymbolHeader struct {
- Length uint32 // size of meta-symbol payload in bytes
- PkgName uint32 // string table index
- PkgPath uint32 // string table index
- ModulePath uint32 // string table index
- MetaHash [16]byte
- _ byte // currently unused
- _ [3]byte // padding
- NumFiles uint32
- NumFuncs uint32
-}
-
-const CovMetaHeaderSize = 16 + 4 + 4 + 4 + 4 + 4 + 4 + 4 // keep in sync with above
-
-// As an example, consider the following Go package:
-//
-// 01: package p
-// 02:
-// 03: var v, w, z int
-// 04:
-// 05: func small(x, y int) int {
-// 06: v++
-// 07: // comment
-// 08: if y == 0 {
-// 09: return x
-// 10: }
-// 11: return (x << 1) ^ (9 / y)
-// 12: }
-// 13:
-// 14: func Medium(q, r int) int {
-// 15: s1 := small(q, r)
-// 16: z += s1
-// 17: s2 := small(r, q)
-// 18: w -= s2
-// 19: return w + z
-// 20: }
-//
-// The meta-data blob for the single package above might look like the
-// following:
-//
-// -- MetaSymbolHeader header----------
-// | size: size of this blob in bytes
-// | packagepath: <path to p>
-// | modulepath: <modpath for p>
-// | nfiles: 1
-// | nfunctions: 2
-// --func offsets table------
-// <offset to func 0>
-// <offset to func 1>
-// --string table (contains all files and functions)------
-// | <uleb128 len> 4
-// | <data> "p.go"
-// | <uleb128 len> 5
-// | <data> "small"
-// | <uleb128 len> 6
-// | <data> "Medium"
-// --func 0------
-// | <uleb128> num units: 3
-// | <uleb128> func name: S1 (index into string table)
-// | <uleb128> file: S0 (index into string table)
-// | <unit 0>: S0 L6 L8 2
-// | <unit 1>: S0 L9 L9 1
-// | <unit 2>: S0 L11 L11 1
-// --func 1------
-// | <uleb128> num units: 1
-// | <uleb128> func name: S2 (index into string table)
-// | <uleb128> file: S0 (index into string table)
-// | <unit 0>: S0 L15 L19 5
-// ---end-----------
-
-// The following types and constants used by the meta-data encoder/decoder.
-
-// FuncDesc encapsulates the meta-data definitions for a single Go function.
-// This version assumes that we're looking at a function before inlining;
-// if we want to capture a post-inlining view of the world, the
-// representations of source positions would need to be a good deal more
-// complicated.
-type FuncDesc struct {
- Funcname string
- Srcfile string
- Units []CoverableUnit
- Lit bool // true if this is a function literal
-}
-
-// CoverableUnit describes the source characteristics of a single
-// program unit for which we want to gather coverage info. Coverable
-// units are either "simple" or "intraline"; a "simple" coverable unit
-// corresponds to a basic block (region of straight-line code with no
-// jumps or control transfers). An "intraline" unit corresponds to a
-// logical clause nested within some other simple unit. A simple unit
-// will have a zero Parent value; for an intraline unit NxStmts will
-// be zero and and Parent will be set to 1 plus the index of the
-// containing simple statement. Example:
-//
-// L7: q := 1
-// L8: x := (y == 101 || launch() == false)
-// L9: r := x * 2
-//
-// For the code above we would have three simple units (one for each
-// line), then an intraline unit describing the "launch() == false"
-// clause in line 8, with Parent pointing to the index of the line 8
-// unit in the units array.
-//
-// Note: in the initial version of the coverage revamp, only simple
-// units will be in use.
-type CoverableUnit struct {
- StLine, StCol uint32
- EnLine, EnCol uint32
- NxStmts uint32
- Parent uint32
-}
-
-// CounterMode tracks the "flavor" of the coverage counters being
-// used in a given coverage-instrumented program.
-type CounterMode uint8
-
-const (
- CtrModeInvalid CounterMode = iota
- CtrModeSet // "set" mode
- CtrModeCount // "count" mode
- CtrModeAtomic // "atomic" mode
- CtrModeRegOnly // registration-only pseudo-mode
- CtrModeTestMain // testmain pseudo-mode
-)
-
-func (cm CounterMode) String() string {
- switch cm {
- case CtrModeSet:
- return "set"
- case CtrModeCount:
- return "count"
- case CtrModeAtomic:
- return "atomic"
- case CtrModeRegOnly:
- return "regonly"
- case CtrModeTestMain:
- return "testmain"
- }
- return "<invalid>"
-}
-
-func ParseCounterMode(mode string) CounterMode {
- var cm CounterMode
- switch mode {
- case "set":
- cm = CtrModeSet
- case "count":
- cm = CtrModeCount
- case "atomic":
- cm = CtrModeAtomic
- case "regonly":
- cm = CtrModeRegOnly
- case "testmain":
- cm = CtrModeTestMain
- default:
- cm = CtrModeInvalid
- }
- return cm
-}
-
-// CounterGranularity tracks the granularity of the coverage counters being
-// used in a given coverage-instrumented program.
-type CounterGranularity uint8
-
-const (
- CtrGranularityInvalid CounterGranularity = iota
- CtrGranularityPerBlock
- CtrGranularityPerFunc
-)
-
-func (cm CounterGranularity) String() string {
- switch cm {
- case CtrGranularityPerBlock:
- return "perblock"
- case CtrGranularityPerFunc:
- return "perfunc"
- }
- return "<invalid>"
-}
-
-//.....................................................................
-//
-// Counter data definitions:
-//
-
-// A counter data file is composed of a file header followed by one or
-// more "segments" (each segment representing a given run or partial
-// run of a give binary) followed by a footer.
-
-// CovCounterMagic holds the magic string for a coverage counter-data file.
-var CovCounterMagic = [4]byte{'\x00', '\x63', '\x77', '\x6d'}
-
-// CounterFileVersion stores the most recent counter data file version.
-const CounterFileVersion = 1
-
-// CounterFileHeader stores files header information for a counter-data file.
-type CounterFileHeader struct {
- Magic [4]byte
- Version uint32
- MetaHash [16]byte
- CFlavor CounterFlavor
- BigEndian bool
- _ [6]byte // padding
-}
-
-// CounterSegmentHeader encapsulates information about a specific
-// segment in a counter data file, which at the moment contains
-// counters data from a single execution of a coverage-instrumented
-// program. Following the segment header will be the string table and
-// args table, and then (possibly) padding bytes to bring the byte
-// size of the preamble up to a multiple of 4. Immediately following
-// that will be the counter payloads.
-//
-// The "args" section of a segment is used to store annotations
-// describing where the counter data came from; this section is
-// basically a series of key-value pairs (can be thought of as an
-// encoded 'map[string]string'). At the moment we only write os.Args()
-// data to this section, using pairs of the form "argc=<integer>",
-// "argv0=<os.Args[0]>", "argv1=<os.Args[1]>", and so on. In the
-// future the args table may also include things like GOOS/GOARCH
-// values, and/or tags indicating which tests were run to generate the
-// counter data.
-type CounterSegmentHeader struct {
- FcnEntries uint64
- StrTabLen uint32
- ArgsLen uint32
-}
-
-// CounterFileFooter appears at the tail end of a counter data file,
-// and stores the number of segments it contains.
-type CounterFileFooter struct {
- Magic [4]byte
- _ [4]byte // padding
- NumSegments uint32
- _ [4]byte // padding
-}
-
-// CounterFilePref is the file prefix used when emitting coverage data
-// output files. CounterFileTemplate describes the format of the file
-// name: prefix followed by meta-file hash followed by process ID
-// followed by emit UnixNanoTime.
-const CounterFilePref = "covcounters"
-const CounterFileTempl = "%s.%x.%d.%d"
-const CounterFileRegexp = `^%s\.(\S+)\.(\d+)\.(\d+)+$`
-
-// CounterFlavor describes how function and counters are
-// stored/represented in the counter section of the file.
-type CounterFlavor uint8
-
-const (
- // "Raw" representation: all values (pkg ID, func ID, num counters,
- // and counters themselves) are stored as uint32's.
- CtrRaw CounterFlavor = iota + 1
-
- // "ULeb" representation: all values (pkg ID, func ID, num counters,
- // and counters themselves) are stored with ULEB128 encoding.
- CtrULeb128
-)
-
-func Round4(x int) int {
- return (x + 3) &^ 3
-}
-
-//.....................................................................
-//
-// Runtime counter data definitions.
-//
-
-// At runtime within a coverage-instrumented program, the "counters"
-// object we associated with instrumented function can be thought of
-// as a struct of the following form:
-//
-// struct {
-// numCtrs uint32
-// pkgid uint32
-// funcid uint32
-// counterArray [numBlocks]uint32
-// }
-//
-// where "numCtrs" is the number of blocks / coverable units within the
-// function, "pkgid" is the unique index assigned to this package by
-// the runtime, "funcid" is the index of this function within its containing
-// package, and "counterArray" stores the actual counters.
-//
-// The counter variable itself is created not as a struct but as a flat
-// array of uint32's; we then use the offsets below to index into it.
-
-const NumCtrsOffset = 0
-const PkgIdOffset = 1
-const FuncIdOffset = 2
-const FirstCtrOffset = 3
diff --git a/contrib/go/_std_1.20/src/internal/coverage/encodecounter/encode.go b/contrib/go/_std_1.20/src/internal/coverage/encodecounter/encode.go
deleted file mode 100644
index 8db4f514e8..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/encodecounter/encode.go
+++ /dev/null
@@ -1,284 +0,0 @@
-// 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 encodecounter
-
-import (
- "bufio"
- "encoding/binary"
- "fmt"
- "internal/coverage"
- "internal/coverage/slicewriter"
- "internal/coverage/stringtab"
- "internal/coverage/uleb128"
- "io"
- "os"
- "sort"
-)
-
-// This package contains APIs and helpers for encoding initial portions
-// of the counter data files emitted at runtime when coverage instrumentation
-// is enabled. Counter data files may contain multiple segments; the file
-// header and first segment are written via the "Write" method below, and
-// additional segments can then be added using "AddSegment".
-
-type CoverageDataWriter struct {
- stab *stringtab.Writer
- w *bufio.Writer
- tmp []byte
- cflavor coverage.CounterFlavor
- segs uint32
- debug bool
-}
-
-func NewCoverageDataWriter(w io.Writer, flav coverage.CounterFlavor) *CoverageDataWriter {
- r := &CoverageDataWriter{
- stab: &stringtab.Writer{},
- w: bufio.NewWriter(w),
-
- tmp: make([]byte, 64),
- cflavor: flav,
- }
- r.stab.InitWriter()
- r.stab.Lookup("")
- return r
-}
-
-// CounterVisitor describes a helper object used during counter file
-// writing; when writing counter data files, clients pass a
-// CounterVisitor to the write/emit routines. The writers will then
-// first invoke the visitor's NumFuncs() method to find out how many
-// function's worth of data to write, then it will invoke VisitFuncs.
-// The expectation is that the VisitFuncs method will then invoke the
-// callback "f" with data for each function to emit to the file.
-type CounterVisitor interface {
- NumFuncs() (int, error)
- VisitFuncs(f CounterVisitorFn) error
-}
-
-// CounterVisitorFn describes a callback function invoked when writing
-// coverage counter data.
-type CounterVisitorFn func(pkid uint32, funcid uint32, counters []uint32) error
-
-// Write writes the contents of the count-data file to the writer
-// previously supplied to NewCoverageDataWriter. Returns an error
-// if something went wrong somewhere with the write.
-func (cfw *CoverageDataWriter) Write(metaFileHash [16]byte, args map[string]string, visitor CounterVisitor) error {
- if err := cfw.writeHeader(metaFileHash); err != nil {
- return err
- }
- return cfw.AppendSegment(args, visitor)
-}
-
-func padToFourByteBoundary(ws *slicewriter.WriteSeeker) error {
- sz := len(ws.BytesWritten())
- zeros := []byte{0, 0, 0, 0}
- rem := uint32(sz) % 4
- if rem != 0 {
- pad := zeros[:(4 - rem)]
- if nw, err := ws.Write(pad); err != nil {
- return err
- } else if nw != len(pad) {
- return fmt.Errorf("error: short write")
- }
- }
- return nil
-}
-
-func (cfw *CoverageDataWriter) writeSegmentPreamble(args map[string]string, visitor CounterVisitor) error {
- var csh coverage.CounterSegmentHeader
- if nf, err := visitor.NumFuncs(); err != nil {
- return err
- } else {
- csh.FcnEntries = uint64(nf)
- }
-
- // Write string table and args to a byte slice (since we need
- // to capture offsets at various points), then emit the slice
- // once we are done.
- cfw.stab.Freeze()
- ws := &slicewriter.WriteSeeker{}
- if err := cfw.stab.Write(ws); err != nil {
- return err
- }
- csh.StrTabLen = uint32(len(ws.BytesWritten()))
-
- akeys := make([]string, 0, len(args))
- for k := range args {
- akeys = append(akeys, k)
- }
- sort.Strings(akeys)
-
- wrULEB128 := func(v uint) error {
- cfw.tmp = cfw.tmp[:0]
- cfw.tmp = uleb128.AppendUleb128(cfw.tmp, v)
- if _, err := ws.Write(cfw.tmp); err != nil {
- return err
- }
- return nil
- }
-
- // Count of arg pairs.
- if err := wrULEB128(uint(len(args))); err != nil {
- return err
- }
- // Arg pairs themselves.
- for _, k := range akeys {
- ki := uint(cfw.stab.Lookup(k))
- if err := wrULEB128(ki); err != nil {
- return err
- }
- v := args[k]
- vi := uint(cfw.stab.Lookup(v))
- if err := wrULEB128(vi); err != nil {
- return err
- }
- }
- if err := padToFourByteBoundary(ws); err != nil {
- return err
- }
- csh.ArgsLen = uint32(len(ws.BytesWritten())) - csh.StrTabLen
-
- if cfw.debug {
- fmt.Fprintf(os.Stderr, "=-= counter segment header: %+v", csh)
- fmt.Fprintf(os.Stderr, " FcnEntries=0x%x StrTabLen=0x%x ArgsLen=0x%x\n",
- csh.FcnEntries, csh.StrTabLen, csh.ArgsLen)
- }
-
- // At this point we can now do the actual write.
- if err := binary.Write(cfw.w, binary.LittleEndian, csh); err != nil {
- return err
- }
- if err := cfw.writeBytes(ws.BytesWritten()); err != nil {
- return err
- }
- return nil
-}
-
-// AppendSegment appends a new segment to a counter data, with a new
-// args section followed by a payload of counter data clauses.
-func (cfw *CoverageDataWriter) AppendSegment(args map[string]string, visitor CounterVisitor) error {
- cfw.stab = &stringtab.Writer{}
- cfw.stab.InitWriter()
- cfw.stab.Lookup("")
-
- var err error
- for k, v := range args {
- cfw.stab.Lookup(k)
- cfw.stab.Lookup(v)
- }
-
- if err = cfw.writeSegmentPreamble(args, visitor); err != nil {
- return err
- }
- if err = cfw.writeCounters(visitor); err != nil {
- return err
- }
- if err = cfw.writeFooter(); err != nil {
- return err
- }
- if err := cfw.w.Flush(); err != nil {
- return fmt.Errorf("write error: %v", err)
- }
- cfw.stab = nil
- return nil
-}
-
-func (cfw *CoverageDataWriter) writeHeader(metaFileHash [16]byte) error {
- // Emit file header.
- ch := coverage.CounterFileHeader{
- Magic: coverage.CovCounterMagic,
- Version: coverage.CounterFileVersion,
- MetaHash: metaFileHash,
- CFlavor: cfw.cflavor,
- BigEndian: false,
- }
- if err := binary.Write(cfw.w, binary.LittleEndian, ch); err != nil {
- return err
- }
- return nil
-}
-
-func (cfw *CoverageDataWriter) writeBytes(b []byte) error {
- if len(b) == 0 {
- return nil
- }
- nw, err := cfw.w.Write(b)
- if err != nil {
- return fmt.Errorf("error writing counter data: %v", err)
- }
- if len(b) != nw {
- return fmt.Errorf("error writing counter data: short write")
- }
- return nil
-}
-
-func (cfw *CoverageDataWriter) writeCounters(visitor CounterVisitor) error {
- // Notes:
- // - this version writes everything little-endian, which means
- // a call is needed to encode every value (expensive)
- // - we may want to move to a model in which we just blast out
- // all counters, or possibly mmap the file and do the write
- // implicitly.
- ctrb := make([]byte, 4)
- wrval := func(val uint32) error {
- var buf []byte
- var towr int
- if cfw.cflavor == coverage.CtrRaw {
- binary.LittleEndian.PutUint32(ctrb, val)
- buf = ctrb
- towr = 4
- } else if cfw.cflavor == coverage.CtrULeb128 {
- cfw.tmp = cfw.tmp[:0]
- cfw.tmp = uleb128.AppendUleb128(cfw.tmp, uint(val))
- buf = cfw.tmp
- towr = len(buf)
- } else {
- panic("internal error: bad counter flavor")
- }
- if sz, err := cfw.w.Write(buf); err != nil {
- return err
- } else if sz != towr {
- return fmt.Errorf("writing counters: short write")
- }
- return nil
- }
-
- // Write out entries for each live function.
- emitter := func(pkid uint32, funcid uint32, counters []uint32) error {
- if err := wrval(uint32(len(counters))); err != nil {
- return err
- }
-
- if err := wrval(pkid); err != nil {
- return err
- }
-
- if err := wrval(funcid); err != nil {
- return err
- }
- for _, val := range counters {
- if err := wrval(val); err != nil {
- return err
- }
- }
- return nil
- }
- if err := visitor.VisitFuncs(emitter); err != nil {
- return err
- }
- return nil
-}
-
-func (cfw *CoverageDataWriter) writeFooter() error {
- cfw.segs++
- cf := coverage.CounterFileFooter{
- Magic: coverage.CovCounterMagic,
- NumSegments: cfw.segs,
- }
- if err := binary.Write(cfw.w, binary.LittleEndian, cf); err != nil {
- return err
- }
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/coverage/pods/pods.go b/contrib/go/_std_1.20/src/internal/coverage/pods/pods.go
deleted file mode 100644
index 432c7b6bd6..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/pods/pods.go
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2022 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 pods
-
-import (
- "fmt"
- "internal/coverage"
- "os"
- "path/filepath"
- "regexp"
- "sort"
- "strconv"
-)
-
-// Pod encapsulates a set of files emitted during the executions of a
-// coverage-instrumented binary. Each pod contains a single meta-data
-// file, and then 0 or more counter data files that refer to that
-// meta-data file. Pods are intended to simplify processing of
-// coverage output files in the case where we have several coverage
-// output directories containing output files derived from more
-// than one instrumented executable. In the case where the files that
-// make up a pod are spread out across multiple directories, each
-// element of the "Origins" field below will be populated with the
-// index of the originating directory for the corresponding counter
-// data file (within the slice of input dirs handed to CollectPods).
-// The ProcessIDs field will be populated with the process ID of each
-// data file in the CounterDataFiles slice.
-type Pod struct {
- MetaFile string
- CounterDataFiles []string
- Origins []int
- ProcessIDs []int
-}
-
-// CollectPods visits the files contained within the directories in
-// the list 'dirs', collects any coverage-related files, partitions
-// them into pods, and returns a list of the pods to the caller, along
-// with an error if something went wrong during directory/file
-// reading.
-//
-// CollectPods skips over any file that is not related to coverage
-// (e.g. avoids looking at things that are not meta-data files or
-// counter-data files). CollectPods also skips over 'orphaned' counter
-// data files (e.g. counter data files for which we can't find the
-// corresponding meta-data file). If "warn" is true, CollectPods will
-// issue warnings to stderr when it encounters non-fatal problems (for
-// orphans or a directory with no meta-data files).
-func CollectPods(dirs []string, warn bool) ([]Pod, error) {
- files := []string{}
- dirIndices := []int{}
- for k, dir := range dirs {
- dents, err := os.ReadDir(dir)
- if err != nil {
- return nil, err
- }
- for _, e := range dents {
- if e.IsDir() {
- continue
- }
- files = append(files, filepath.Join(dir, e.Name()))
- dirIndices = append(dirIndices, k)
- }
- }
- return collectPodsImpl(files, dirIndices, warn), nil
-}
-
-// CollectPodsFromFiles functions the same as "CollectPods" but
-// operates on an explicit list of files instead of a directory.
-func CollectPodsFromFiles(files []string, warn bool) []Pod {
- return collectPodsImpl(files, nil, warn)
-}
-
-type fileWithAnnotations struct {
- file string
- origin int
- pid int
-}
-
-type protoPod struct {
- mf string
- elements []fileWithAnnotations
-}
-
-// collectPodsImpl examines the specified list of files and picks out
-// subsets that correspond to coverage pods. The first stage in this
-// process is collecting a set { M1, M2, ... MN } where each M_k is a
-// distinct coverage meta-data file. We then create a single pod for
-// each meta-data file M_k, then find all of the counter data files
-// that refer to that meta-data file (recall that the counter data
-// file name incorporates the meta-data hash), and add the counter
-// data file to the appropriate pod.
-//
-// This process is complicated by the fact that we need to keep track
-// of directory indices for counter data files. Here is an example to
-// motivate:
-//
-// directory 1:
-//
-// M1 covmeta.9bbf1777f47b3fcacb05c38b035512d6
-// C1 covcounters.9bbf1777f47b3fcacb05c38b035512d6.1677673.1662138360208416486
-// C2 covcounters.9bbf1777f47b3fcacb05c38b035512d6.1677637.1662138359974441782
-//
-// directory 2:
-//
-// M2 covmeta.9bbf1777f47b3fcacb05c38b035512d6
-// C3 covcounters.9bbf1777f47b3fcacb05c38b035512d6.1677445.1662138360208416480
-// C4 covcounters.9bbf1777f47b3fcacb05c38b035512d6.1677677.1662138359974441781
-// M3 covmeta.a723844208cea2ae80c63482c78b2245
-// C5 covcounters.a723844208cea2ae80c63482c78b2245.3677445.1662138360208416480
-// C6 covcounters.a723844208cea2ae80c63482c78b2245.1877677.1662138359974441781
-//
-// In these two directories we have three meta-data files, but only
-// two are distinct, meaning that we'll wind up with two pods. The
-// first pod (with meta-file M1) will have four counter data files
-// (C1, C2, C3, C4) and the second pod will have two counter data files
-// (C5, C6).
-func collectPodsImpl(files []string, dirIndices []int, warn bool) []Pod {
- metaRE := regexp.MustCompile(fmt.Sprintf(`^%s\.(\S+)$`, coverage.MetaFilePref))
- mm := make(map[string]protoPod)
- for _, f := range files {
- base := filepath.Base(f)
- if m := metaRE.FindStringSubmatch(base); m != nil {
- tag := m[1]
- // We need to allow for the possibility of duplicate
- // meta-data files. If we hit this case, use the
- // first encountered as the canonical version.
- if _, ok := mm[tag]; !ok {
- mm[tag] = protoPod{mf: f}
- }
- // FIXME: should probably check file length and hash here for
- // the duplicate.
- }
- }
- counterRE := regexp.MustCompile(fmt.Sprintf(coverage.CounterFileRegexp, coverage.CounterFilePref))
- for k, f := range files {
- base := filepath.Base(f)
- if m := counterRE.FindStringSubmatch(base); m != nil {
- tag := m[1] // meta hash
- pid, err := strconv.Atoi(m[2])
- if err != nil {
- continue
- }
- if v, ok := mm[tag]; ok {
- idx := -1
- if dirIndices != nil {
- idx = dirIndices[k]
- }
- fo := fileWithAnnotations{file: f, origin: idx, pid: pid}
- v.elements = append(v.elements, fo)
- mm[tag] = v
- } else {
- if warn {
- warning("skipping orphaned counter file: %s", f)
- }
- }
- }
- }
- if len(mm) == 0 {
- if warn {
- warning("no coverage data files found")
- }
- return nil
- }
- pods := make([]Pod, 0, len(mm))
- for _, p := range mm {
- sort.Slice(p.elements, func(i, j int) bool {
- return p.elements[i].file < p.elements[j].file
- })
- pod := Pod{
- MetaFile: p.mf,
- CounterDataFiles: make([]string, 0, len(p.elements)),
- Origins: make([]int, 0, len(p.elements)),
- ProcessIDs: make([]int, 0, len(p.elements)),
- }
- for _, e := range p.elements {
- pod.CounterDataFiles = append(pod.CounterDataFiles, e.file)
- pod.Origins = append(pod.Origins, e.origin)
- pod.ProcessIDs = append(pod.ProcessIDs, e.pid)
- }
- pods = append(pods, pod)
- }
- sort.Slice(pods, func(i, j int) bool {
- return pods[i].MetaFile < pods[j].MetaFile
- })
- return pods
-}
-
-func warning(s string, a ...interface{}) {
- fmt.Fprintf(os.Stderr, "warning: ")
- fmt.Fprintf(os.Stderr, s, a...)
- fmt.Fprintf(os.Stderr, "\n")
-}
diff --git a/contrib/go/_std_1.20/src/internal/coverage/pods/ya.make b/contrib/go/_std_1.20/src/internal/coverage/pods/ya.make
deleted file mode 100644
index 2a226abc34..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/pods/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- pods.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/coverage/slicereader/slicereader.go b/contrib/go/_std_1.20/src/internal/coverage/slicereader/slicereader.go
deleted file mode 100644
index 3d117bae37..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/slicereader/slicereader.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// 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 slicereader
-
-import (
- "encoding/binary"
- "unsafe"
-)
-
-// This file contains the helper "SliceReader", a utility for
-// reading values from a byte slice that may or may not be backed
-// by a read-only mmap'd region.
-
-type Reader struct {
- b []byte
- readonly bool
- off int64
-}
-
-func NewReader(b []byte, readonly bool) *Reader {
- r := Reader{
- b: b,
- readonly: readonly,
- }
- return &r
-}
-
-func (r *Reader) Read(b []byte) (int, error) {
- amt := len(b)
- toread := r.b[r.off:]
- if len(toread) < amt {
- amt = len(toread)
- }
- copy(b, toread)
- r.off += int64(amt)
- return amt, nil
-}
-
-func (r *Reader) SeekTo(off int64) {
- r.off = off
-}
-
-func (r *Reader) Offset() int64 {
- return r.off
-}
-
-func (r *Reader) ReadUint8() uint8 {
- rv := uint8(r.b[int(r.off)])
- r.off += 1
- return rv
-}
-
-func (r *Reader) ReadUint32() uint32 {
- end := int(r.off) + 4
- rv := binary.LittleEndian.Uint32(r.b[int(r.off):end:end])
- r.off += 4
- return rv
-}
-
-func (r *Reader) ReadUint64() uint64 {
- end := int(r.off) + 8
- rv := binary.LittleEndian.Uint64(r.b[int(r.off):end:end])
- r.off += 8
- return rv
-}
-
-func (r *Reader) ReadULEB128() (value uint64) {
- var shift uint
-
- for {
- b := r.b[r.off]
- r.off++
- value |= (uint64(b&0x7F) << shift)
- if b&0x80 == 0 {
- break
- }
- shift += 7
- }
- return
-}
-
-func (r *Reader) ReadString(len int64) string {
- b := r.b[r.off : r.off+len]
- r.off += len
- if r.readonly {
- return toString(b) // backed by RO memory, ok to make unsafe string
- }
- return string(b)
-}
-
-func toString(b []byte) string {
- if len(b) == 0 {
- return ""
- }
- return unsafe.String(&b[0], len(b))
-}
diff --git a/contrib/go/_std_1.20/src/internal/coverage/slicereader/ya.make b/contrib/go/_std_1.20/src/internal/coverage/slicereader/ya.make
deleted file mode 100644
index 950964912a..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/slicereader/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- slicereader.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/coverage/slicewriter/slicewriter.go b/contrib/go/_std_1.20/src/internal/coverage/slicewriter/slicewriter.go
deleted file mode 100644
index 3522bf5770..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/slicewriter/slicewriter.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2022 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 slicewriter
-
-import (
- "fmt"
- "io"
-)
-
-// WriteSeeker is a helper object that implements the io.WriteSeeker
-// interface. Clients can create a WriteSeeker, make a series of Write
-// calls to add data to it (and possibly Seek calls to update
-// previously written portions), then finally invoke BytesWritten() to
-// get a pointer to the constructed byte slice.
-type WriteSeeker struct {
- payload []byte
- off int64
-}
-
-func (sws *WriteSeeker) Write(p []byte) (n int, err error) {
- amt := len(p)
- towrite := sws.payload[sws.off:]
- if len(towrite) < amt {
- sws.payload = append(sws.payload, make([]byte, amt-len(towrite))...)
- towrite = sws.payload[sws.off:]
- }
- copy(towrite, p)
- sws.off += int64(amt)
- return amt, nil
-}
-
-// Seek repositions the read/write position of the WriteSeeker within
-// its internally maintained slice. Note that it is not possible to
-// expand the size of the slice using SEEK_SET; trying to seek outside
-// the slice will result in an error.
-func (sws *WriteSeeker) Seek(offset int64, whence int) (int64, error) {
- switch whence {
- case io.SeekStart:
- if sws.off != offset && (offset < 0 || offset >= int64(len(sws.payload))) {
- return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", offset, len(sws.payload))
- }
- sws.off = offset
- return offset, nil
- case io.SeekCurrent:
- newoff := sws.off + offset
- if newoff != sws.off && (newoff < 0 || newoff >= int64(len(sws.payload))) {
- return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", newoff, len(sws.payload))
- }
- sws.off += offset
- return sws.off, nil
- case io.SeekEnd:
- newoff := int64(len(sws.payload)) + offset
- if newoff != sws.off && (newoff < 0 || newoff >= int64(len(sws.payload))) {
- return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", newoff, len(sws.payload))
- }
- sws.off = newoff
- return sws.off, nil
- }
- // other modes not supported
- return 0, fmt.Errorf("unsupported seek mode %d", whence)
-}
-
-// BytesWritten returns the underlying byte slice for the WriteSeeker,
-// containing the data written to it via Write/Seek calls.
-func (sws *WriteSeeker) BytesWritten() []byte {
- return sws.payload
-}
-
-func (sws *WriteSeeker) Read(p []byte) (n int, err error) {
- amt := len(p)
- toread := sws.payload[sws.off:]
- if len(toread) < amt {
- amt = len(toread)
- }
- copy(p, toread)
- sws.off += int64(amt)
- return amt, nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/coverage/slicewriter/ya.make b/contrib/go/_std_1.20/src/internal/coverage/slicewriter/ya.make
deleted file mode 100644
index e3169f3e1a..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/slicewriter/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- slicewriter.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/coverage/ya.make b/contrib/go/_std_1.20/src/internal/coverage/ya.make
deleted file mode 100644
index fba90aa775..0000000000
--- a/contrib/go/_std_1.20/src/internal/coverage/ya.make
+++ /dev/null
@@ -1,26 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- cmddefs.go
- defs.go
- pkid.go
-)
-
-END()
-
-RECURSE(
- calloc
- cformat
- cmerge
- decodecounter
- decodemeta
- encodecounter
- encodemeta
- pods
- rtcov
- slicereader
- slicewriter
- stringtab
- # test
- uleb128
-)
diff --git a/contrib/go/_std_1.20/src/internal/cpu/cpu.go b/contrib/go/_std_1.20/src/internal/cpu/cpu.go
deleted file mode 100644
index aef9fb3be7..0000000000
--- a/contrib/go/_std_1.20/src/internal/cpu/cpu.go
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright 2017 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 cpu implements processor feature detection
-// used by the Go standard library.
-package cpu
-
-// DebugOptions is set to true by the runtime if the OS supports reading
-// GODEBUG early in runtime startup.
-// This should not be changed after it is initialized.
-var DebugOptions bool
-
-// CacheLinePad is used to pad structs to avoid false sharing.
-type CacheLinePad struct{ _ [CacheLinePadSize]byte }
-
-// CacheLineSize is the CPU's assumed cache line size.
-// There is currently no runtime detection of the real cache line size
-// so we use the constant per GOARCH CacheLinePadSize as an approximation.
-var CacheLineSize uintptr = CacheLinePadSize
-
-// The booleans in X86 contain the correspondingly named cpuid feature bit.
-// HasAVX and HasAVX2 are only set if the OS does support XMM and YMM registers
-// in addition to the cpuid feature bit being set.
-// The struct is padded to avoid false sharing.
-var X86 struct {
- _ CacheLinePad
- HasAES bool
- HasADX bool
- HasAVX bool
- HasAVX2 bool
- HasBMI1 bool
- HasBMI2 bool
- HasERMS bool
- HasFMA bool
- HasOSXSAVE bool
- HasPCLMULQDQ bool
- HasPOPCNT bool
- HasRDTSCP bool
- HasSHA bool
- HasSSE3 bool
- HasSSSE3 bool
- HasSSE41 bool
- HasSSE42 bool
- _ CacheLinePad
-}
-
-// The booleans in ARM contain the correspondingly named cpu feature bit.
-// The struct is padded to avoid false sharing.
-var ARM struct {
- _ CacheLinePad
- HasVFPv4 bool
- HasIDIVA bool
- _ CacheLinePad
-}
-
-// The booleans in ARM64 contain the correspondingly named cpu feature bit.
-// The struct is padded to avoid false sharing.
-var ARM64 struct {
- _ CacheLinePad
- HasAES bool
- HasPMULL bool
- HasSHA1 bool
- HasSHA2 bool
- HasSHA512 bool
- HasCRC32 bool
- HasATOMICS bool
- HasCPUID bool
- IsNeoverseN1 bool
- IsNeoverseV1 bool
- _ CacheLinePad
-}
-
-var MIPS64X struct {
- _ CacheLinePad
- HasMSA bool // MIPS SIMD architecture
- _ CacheLinePad
-}
-
-// For ppc64(le), it is safe to check only for ISA level starting on ISA v3.00,
-// since there are no optional categories. There are some exceptions that also
-// require kernel support to work (darn, scv), so there are feature bits for
-// those as well. The minimum processor requirement is POWER8 (ISA 2.07).
-// The struct is padded to avoid false sharing.
-var PPC64 struct {
- _ CacheLinePad
- HasDARN bool // Hardware random number generator (requires kernel enablement)
- HasSCV bool // Syscall vectored (requires kernel enablement)
- IsPOWER8 bool // ISA v2.07 (POWER8)
- IsPOWER9 bool // ISA v3.00 (POWER9)
- IsPOWER10 bool // ISA v3.1 (POWER10)
- _ CacheLinePad
-}
-
-var S390X struct {
- _ CacheLinePad
- HasZARCH bool // z architecture mode is active [mandatory]
- HasSTFLE bool // store facility list extended [mandatory]
- HasLDISP bool // long (20-bit) displacements [mandatory]
- HasEIMM bool // 32-bit immediates [mandatory]
- HasDFP bool // decimal floating point
- HasETF3EH bool // ETF-3 enhanced
- HasMSA bool // message security assist (CPACF)
- HasAES bool // KM-AES{128,192,256} functions
- HasAESCBC bool // KMC-AES{128,192,256} functions
- HasAESCTR bool // KMCTR-AES{128,192,256} functions
- HasAESGCM bool // KMA-GCM-AES{128,192,256} functions
- HasGHASH bool // KIMD-GHASH function
- HasSHA1 bool // K{I,L}MD-SHA-1 functions
- HasSHA256 bool // K{I,L}MD-SHA-256 functions
- HasSHA512 bool // K{I,L}MD-SHA-512 functions
- HasSHA3 bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functions
- HasVX bool // vector facility. Note: the runtime sets this when it processes auxv records.
- HasVXE bool // vector-enhancements facility 1
- HasKDSA bool // elliptic curve functions
- HasECDSA bool // NIST curves
- HasEDDSA bool // Edwards curves
- _ CacheLinePad
-}
-
-// Initialize examines the processor and sets the relevant variables above.
-// This is called by the runtime package early in program initialization,
-// before normal init functions are run. env is set by runtime if the OS supports
-// cpu feature options in GODEBUG.
-func Initialize(env string) {
- doinit()
- processOptions(env)
-}
-
-// options contains the cpu debug options that can be used in GODEBUG.
-// Options are arch dependent and are added by the arch specific doinit functions.
-// Features that are mandatory for the specific GOARCH should not be added to options
-// (e.g. SSE2 on amd64).
-var options []option
-
-// Option names should be lower case. e.g. avx instead of AVX.
-type option struct {
- Name string
- Feature *bool
- Specified bool // whether feature value was specified in GODEBUG
- Enable bool // whether feature should be enabled
-}
-
-// processOptions enables or disables CPU feature values based on the parsed env string.
-// The env string is expected to be of the form cpu.feature1=value1,cpu.feature2=value2...
-// where feature names is one of the architecture specific list stored in the
-// cpu packages options variable and values are either 'on' or 'off'.
-// If env contains cpu.all=off then all cpu features referenced through the options
-// variable are disabled. Other feature names and values result in warning messages.
-func processOptions(env string) {
-field:
- for env != "" {
- field := ""
- i := indexByte(env, ',')
- if i < 0 {
- field, env = env, ""
- } else {
- field, env = env[:i], env[i+1:]
- }
- if len(field) < 4 || field[:4] != "cpu." {
- continue
- }
- i = indexByte(field, '=')
- if i < 0 {
- print("GODEBUG: no value specified for \"", field, "\"\n")
- continue
- }
- key, value := field[4:i], field[i+1:] // e.g. "SSE2", "on"
-
- var enable bool
- switch value {
- case "on":
- enable = true
- case "off":
- enable = false
- default:
- print("GODEBUG: value \"", value, "\" not supported for cpu option \"", key, "\"\n")
- continue field
- }
-
- if key == "all" {
- for i := range options {
- options[i].Specified = true
- options[i].Enable = enable
- }
- continue field
- }
-
- for i := range options {
- if options[i].Name == key {
- options[i].Specified = true
- options[i].Enable = enable
- continue field
- }
- }
-
- print("GODEBUG: unknown cpu feature \"", key, "\"\n")
- }
-
- for _, o := range options {
- if !o.Specified {
- continue
- }
-
- if o.Enable && !*o.Feature {
- print("GODEBUG: can not enable \"", o.Name, "\", missing CPU support\n")
- continue
- }
-
- *o.Feature = o.Enable
- }
-}
-
-// indexByte returns the index of the first instance of c in s,
-// or -1 if c is not present in s.
-func indexByte(s string, c byte) int {
- for i := 0; i < len(s); i++ {
- if s[i] == c {
- return i
- }
- }
- return -1
-}
diff --git a/contrib/go/_std_1.20/src/internal/cpu/cpu_arm64.go b/contrib/go/_std_1.20/src/internal/cpu/cpu_arm64.go
deleted file mode 100644
index 85210aa00c..0000000000
--- a/contrib/go/_std_1.20/src/internal/cpu/cpu_arm64.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2017 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 cpu
-
-// CacheLinePadSize is used to prevent false sharing of cache lines.
-// We choose 128 because Apple Silicon, a.k.a. M1, has 128-byte cache line size.
-// It doesn't cost much and is much more future-proof.
-const CacheLinePadSize = 128
-
-func doinit() {
- options = []option{
- {Name: "aes", Feature: &ARM64.HasAES},
- {Name: "pmull", Feature: &ARM64.HasPMULL},
- {Name: "sha1", Feature: &ARM64.HasSHA1},
- {Name: "sha2", Feature: &ARM64.HasSHA2},
- {Name: "sha512", Feature: &ARM64.HasSHA512},
- {Name: "crc32", Feature: &ARM64.HasCRC32},
- {Name: "atomics", Feature: &ARM64.HasATOMICS},
- {Name: "cpuid", Feature: &ARM64.HasCPUID},
- {Name: "isNeoverseN1", Feature: &ARM64.IsNeoverseN1},
- {Name: "isNeoverseV1", Feature: &ARM64.IsNeoverseV1},
- }
-
- // arm64 uses different ways to detect CPU features at runtime depending on the operating system.
- osInit()
-}
-
-func getisar0() uint64
-
-func getMIDR() uint64
-
-func extractBits(data uint64, start, end uint) uint {
- return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
-}
-
-func parseARM64SystemRegisters(isar0 uint64) {
- // ID_AA64ISAR0_EL1
- switch extractBits(isar0, 4, 7) {
- case 1:
- ARM64.HasAES = true
- case 2:
- ARM64.HasAES = true
- ARM64.HasPMULL = true
- }
-
- switch extractBits(isar0, 8, 11) {
- case 1:
- ARM64.HasSHA1 = true
- }
-
- switch extractBits(isar0, 12, 15) {
- case 1:
- ARM64.HasSHA2 = true
- case 2:
- ARM64.HasSHA2 = true
- ARM64.HasSHA512 = true
- }
-
- switch extractBits(isar0, 16, 19) {
- case 1:
- ARM64.HasCRC32 = true
- }
-
- switch extractBits(isar0, 20, 23) {
- case 2:
- ARM64.HasATOMICS = true
- }
-}
diff --git a/contrib/go/_std_1.20/src/internal/cpu/cpu_arm64_hwcap.go b/contrib/go/_std_1.20/src/internal/cpu/cpu_arm64_hwcap.go
deleted file mode 100644
index 0fb5fb505a..0000000000
--- a/contrib/go/_std_1.20/src/internal/cpu/cpu_arm64_hwcap.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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.
-
-//go:build arm64 && linux
-
-package cpu
-
-// HWCap may be initialized by archauxv and
-// should not be changed after it was initialized.
-var HWCap uint
-
-// HWCAP bits. These are exposed by Linux.
-const (
- hwcap_AES = 1 << 3
- hwcap_PMULL = 1 << 4
- hwcap_SHA1 = 1 << 5
- hwcap_SHA2 = 1 << 6
- hwcap_CRC32 = 1 << 7
- hwcap_ATOMICS = 1 << 8
- hwcap_CPUID = 1 << 11
-)
-
-func hwcapInit(os string) {
- // HWCap was populated by the runtime from the auxiliary vector.
- // Use HWCap information since reading aarch64 system registers
- // is not supported in user space on older linux kernels.
- ARM64.HasAES = isSet(HWCap, hwcap_AES)
- ARM64.HasPMULL = isSet(HWCap, hwcap_PMULL)
- ARM64.HasSHA1 = isSet(HWCap, hwcap_SHA1)
- ARM64.HasSHA2 = isSet(HWCap, hwcap_SHA2)
- ARM64.HasCRC32 = isSet(HWCap, hwcap_CRC32)
- ARM64.HasCPUID = isSet(HWCap, hwcap_CPUID)
-
- // The Samsung S9+ kernel reports support for atomics, but not all cores
- // actually support them, resulting in SIGILL. See issue #28431.
- // TODO(elias.naur): Only disable the optimization on bad chipsets on android.
- ARM64.HasATOMICS = isSet(HWCap, hwcap_ATOMICS) && os != "android"
-
- // Check to see if executing on a NeoverseN1 and in order to do that,
- // check the AUXV for the CPUID bit. The getMIDR function executes an
- // instruction which would normally be an illegal instruction, but it's
- // trapped by the kernel, the value sanitized and then returned. Without
- // the CPUID bit the kernel will not trap the instruction and the process
- // will be terminated with SIGILL.
- if ARM64.HasCPUID {
- midr := getMIDR()
- part_num := uint16((midr >> 4) & 0xfff)
- implementor := byte((midr >> 24) & 0xff)
-
- if implementor == 'A' && part_num == 0xd0c {
- ARM64.IsNeoverseN1 = true
- }
- if implementor == 'A' && part_num == 0xd40 {
- ARM64.IsNeoverseV1 = true
- }
- }
-}
-
-func isSet(hwc uint, value uint) bool {
- return hwc&value != 0
-}
diff --git a/contrib/go/_std_1.20/src/internal/cpu/ya.make b/contrib/go/_std_1.20/src/internal/cpu/ya.make
deleted file mode 100644
index fbaac454b3..0000000000
--- a/contrib/go/_std_1.20/src/internal/cpu/ya.make
+++ /dev/null
@@ -1,42 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- cpu.go
- cpu.s
-)
-
-IF (ARCH_ARM64)
- SRCS(
- cpu_arm64.go
- cpu_arm64.s
- cpu_no_name.go
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- cpu_x86.go
- cpu_x86.s
- )
-ENDIF()
-
-IF (OS_DARWIN AND ARCH_ARM64)
- SRCS(
- cpu_arm64_darwin.go
- )
-ENDIF()
-
-IF (OS_LINUX AND ARCH_ARM64)
- SRCS(
- cpu_arm64_hwcap.go
- cpu_arm64_linux.go
- )
-ENDIF()
-
-IF (OS_WINDOWS AND ARCH_ARM64)
- SRCS(
- cpu_arm64_other.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/fmtsort/ya.make b/contrib/go/_std_1.20/src/internal/fmtsort/ya.make
deleted file mode 100644
index cf99850591..0000000000
--- a/contrib/go/_std_1.20/src/internal/fmtsort/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- sort.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/fuzz.go b/contrib/go/_std_1.20/src/internal/fuzz/fuzz.go
deleted file mode 100644
index 7d4fe06198..0000000000
--- a/contrib/go/_std_1.20/src/internal/fuzz/fuzz.go
+++ /dev/null
@@ -1,1083 +0,0 @@
-// 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 fuzz provides common fuzzing functionality for tests built with
-// "go test" and for programs that use fuzzing functionality in the testing
-// package.
-package fuzz
-
-import (
- "bytes"
- "context"
- "crypto/sha256"
- "errors"
- "fmt"
- "internal/godebug"
- "io"
- "math/bits"
- "os"
- "path/filepath"
- "reflect"
- "runtime"
- "strings"
- "time"
-)
-
-// CoordinateFuzzingOpts is a set of arguments for CoordinateFuzzing.
-// The zero value is valid for each field unless specified otherwise.
-type CoordinateFuzzingOpts struct {
- // Log is a writer for logging progress messages and warnings.
- // If nil, io.Discard will be used instead.
- Log io.Writer
-
- // Timeout is the amount of wall clock time to spend fuzzing after the corpus
- // has loaded. If zero, there will be no time limit.
- Timeout time.Duration
-
- // Limit is the number of random values to generate and test. If zero,
- // there will be no limit on the number of generated values.
- Limit int64
-
- // MinimizeTimeout is the amount of wall clock time to spend minimizing
- // after discovering a crasher. If zero, there will be no time limit. If
- // MinimizeTimeout and MinimizeLimit are both zero, then minimization will
- // be disabled.
- MinimizeTimeout time.Duration
-
- // MinimizeLimit is the maximum number of calls to the fuzz function to be
- // made while minimizing after finding a crash. If zero, there will be no
- // limit. Calls to the fuzz function made when minimizing also count toward
- // Limit. If MinimizeTimeout and MinimizeLimit are both zero, then
- // minimization will be disabled.
- MinimizeLimit int64
-
- // parallel is the number of worker processes to run in parallel. If zero,
- // CoordinateFuzzing will run GOMAXPROCS workers.
- Parallel int
-
- // Seed is a list of seed values added by the fuzz target with testing.F.Add
- // and in testdata.
- Seed []CorpusEntry
-
- // Types is the list of types which make up a corpus entry.
- // Types must be set and must match values in Seed.
- Types []reflect.Type
-
- // CorpusDir is a directory where files containing values that crash the
- // code being tested may be written. CorpusDir must be set.
- CorpusDir string
-
- // CacheDir is a directory containing additional "interesting" values.
- // The fuzzer may derive new values from these, and may write new values here.
- CacheDir string
-}
-
-// CoordinateFuzzing creates several worker processes and communicates with
-// them to test random inputs that could trigger crashes and expose bugs.
-// The worker processes run the same binary in the same directory with the
-// same environment variables as the coordinator process. Workers also run
-// with the same arguments as the coordinator, except with the -test.fuzzworker
-// flag prepended to the argument list.
-//
-// If a crash occurs, the function will return an error containing information
-// about the crash, which can be reported to the user.
-func CoordinateFuzzing(ctx context.Context, opts CoordinateFuzzingOpts) (err error) {
- if err := ctx.Err(); err != nil {
- return err
- }
- if opts.Log == nil {
- opts.Log = io.Discard
- }
- if opts.Parallel == 0 {
- opts.Parallel = runtime.GOMAXPROCS(0)
- }
- if opts.Limit > 0 && int64(opts.Parallel) > opts.Limit {
- // Don't start more workers than we need.
- opts.Parallel = int(opts.Limit)
- }
-
- c, err := newCoordinator(opts)
- if err != nil {
- return err
- }
-
- if opts.Timeout > 0 {
- var cancel func()
- ctx, cancel = context.WithTimeout(ctx, opts.Timeout)
- defer cancel()
- }
-
- // fuzzCtx is used to stop workers, for example, after finding a crasher.
- fuzzCtx, cancelWorkers := context.WithCancel(ctx)
- defer cancelWorkers()
- doneC := ctx.Done()
-
- // stop is called when a worker encounters a fatal error.
- var fuzzErr error
- stopping := false
- stop := func(err error) {
- if err == fuzzCtx.Err() || isInterruptError(err) {
- // Suppress cancellation errors and terminations due to SIGINT.
- // The messages are not helpful since either the user triggered the error
- // (with ^C) or another more helpful message will be printed (a crasher).
- err = nil
- }
- if err != nil && (fuzzErr == nil || fuzzErr == ctx.Err()) {
- fuzzErr = err
- }
- if stopping {
- return
- }
- stopping = true
- cancelWorkers()
- doneC = nil
- }
-
- // Ensure that any crash we find is written to the corpus, even if an error
- // or interruption occurs while minimizing it.
- crashWritten := false
- defer func() {
- if c.crashMinimizing == nil || crashWritten {
- return
- }
- werr := writeToCorpus(&c.crashMinimizing.entry, opts.CorpusDir)
- if werr != nil {
- err = fmt.Errorf("%w\n%v", err, werr)
- return
- }
- if err == nil {
- err = &crashError{
- path: c.crashMinimizing.entry.Path,
- err: errors.New(c.crashMinimizing.crasherMsg),
- }
- }
- }()
-
- // Start workers.
- // TODO(jayconrod): do we want to support fuzzing different binaries?
- dir := "" // same as self
- binPath := os.Args[0]
- args := append([]string{"-test.fuzzworker"}, os.Args[1:]...)
- env := os.Environ() // same as self
-
- errC := make(chan error)
- workers := make([]*worker, opts.Parallel)
- for i := range workers {
- var err error
- workers[i], err = newWorker(c, dir, binPath, args, env)
- if err != nil {
- return err
- }
- }
- for i := range workers {
- w := workers[i]
- go func() {
- err := w.coordinate(fuzzCtx)
- if fuzzCtx.Err() != nil || isInterruptError(err) {
- err = nil
- }
- cleanErr := w.cleanup()
- if err == nil {
- err = cleanErr
- }
- errC <- err
- }()
- }
-
- // Main event loop.
- // Do not return until all workers have terminated. We avoid a deadlock by
- // receiving messages from workers even after ctx is cancelled.
- activeWorkers := len(workers)
- statTicker := time.NewTicker(3 * time.Second)
- defer statTicker.Stop()
- defer c.logStats()
-
- c.logStats()
- for {
- var inputC chan fuzzInput
- input, ok := c.peekInput()
- if ok && c.crashMinimizing == nil && !stopping {
- inputC = c.inputC
- }
-
- var minimizeC chan fuzzMinimizeInput
- minimizeInput, ok := c.peekMinimizeInput()
- if ok && !stopping {
- minimizeC = c.minimizeC
- }
-
- select {
- case <-doneC:
- // Interrupted, cancelled, or timed out.
- // stop sets doneC to nil so we don't busy wait here.
- stop(ctx.Err())
-
- case err := <-errC:
- // A worker terminated, possibly after encountering a fatal error.
- stop(err)
- activeWorkers--
- if activeWorkers == 0 {
- return fuzzErr
- }
-
- case result := <-c.resultC:
- // Received response from worker.
- if stopping {
- break
- }
- c.updateStats(result)
-
- if result.crasherMsg != "" {
- if c.warmupRun() && result.entry.IsSeed {
- target := filepath.Base(c.opts.CorpusDir)
- fmt.Fprintf(c.opts.Log, "failure while testing seed corpus entry: %s/%s\n", target, testName(result.entry.Parent))
- stop(errors.New(result.crasherMsg))
- break
- }
- if c.canMinimize() && result.canMinimize {
- if c.crashMinimizing != nil {
- // This crash is not minimized, and another crash is being minimized.
- // Ignore this one and wait for the other one to finish.
- break
- }
- // Found a crasher but haven't yet attempted to minimize it.
- // Send it back to a worker for minimization. Disable inputC so
- // other workers don't continue fuzzing.
- c.crashMinimizing = &result
- fmt.Fprintf(c.opts.Log, "fuzz: minimizing %d-byte failing input file\n", len(result.entry.Data))
- c.queueForMinimization(result, nil)
- } else if !crashWritten {
- // Found a crasher that's either minimized or not minimizable.
- // Write to corpus and stop.
- err := writeToCorpus(&result.entry, opts.CorpusDir)
- if err == nil {
- crashWritten = true
- err = &crashError{
- path: result.entry.Path,
- err: errors.New(result.crasherMsg),
- }
- }
- if shouldPrintDebugInfo() {
- fmt.Fprintf(
- c.opts.Log,
- "DEBUG new crasher, elapsed: %s, id: %s, parent: %s, gen: %d, size: %d, exec time: %s\n",
- c.elapsed(),
- result.entry.Path,
- result.entry.Parent,
- result.entry.Generation,
- len(result.entry.Data),
- result.entryDuration,
- )
- }
- stop(err)
- }
- } else if result.coverageData != nil {
- if c.warmupRun() {
- if shouldPrintDebugInfo() {
- fmt.Fprintf(
- c.opts.Log,
- "DEBUG processed an initial input, elapsed: %s, id: %s, new bits: %d, size: %d, exec time: %s\n",
- c.elapsed(),
- result.entry.Parent,
- countBits(diffCoverage(c.coverageMask, result.coverageData)),
- len(result.entry.Data),
- result.entryDuration,
- )
- }
- c.updateCoverage(result.coverageData)
- c.warmupInputLeft--
- if c.warmupInputLeft == 0 {
- fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, gathering baseline coverage: %d/%d completed, now fuzzing with %d workers\n", c.elapsed(), c.warmupInputCount, c.warmupInputCount, c.opts.Parallel)
- if shouldPrintDebugInfo() {
- fmt.Fprintf(
- c.opts.Log,
- "DEBUG finished processing input corpus, elapsed: %s, entries: %d, initial coverage bits: %d\n",
- c.elapsed(),
- len(c.corpus.entries),
- countBits(c.coverageMask),
- )
- }
- }
- } else if keepCoverage := diffCoverage(c.coverageMask, result.coverageData); keepCoverage != nil {
- // Found a value that expanded coverage.
- // It's not a crasher, but we may want to add it to the on-disk
- // corpus and prioritize it for future fuzzing.
- // TODO(jayconrod, katiehockman): Prioritize fuzzing these
- // values which expanded coverage, perhaps based on the
- // number of new edges that this result expanded.
- // TODO(jayconrod, katiehockman): Don't write a value that's already
- // in the corpus.
- if c.canMinimize() && result.canMinimize && c.crashMinimizing == nil {
- // Send back to workers to find a smaller value that preserves
- // at least one new coverage bit.
- c.queueForMinimization(result, keepCoverage)
- } else {
- // Update the coordinator's coverage mask and save the value.
- inputSize := len(result.entry.Data)
- entryNew, err := c.addCorpusEntries(true, result.entry)
- if err != nil {
- stop(err)
- break
- }
- if !entryNew {
- continue
- }
- c.updateCoverage(keepCoverage)
- c.inputQueue.enqueue(result.entry)
- c.interestingCount++
- if shouldPrintDebugInfo() {
- fmt.Fprintf(
- c.opts.Log,
- "DEBUG new interesting input, elapsed: %s, id: %s, parent: %s, gen: %d, new bits: %d, total bits: %d, size: %d, exec time: %s\n",
- c.elapsed(),
- result.entry.Path,
- result.entry.Parent,
- result.entry.Generation,
- countBits(keepCoverage),
- countBits(c.coverageMask),
- inputSize,
- result.entryDuration,
- )
- }
- }
- } else {
- if shouldPrintDebugInfo() {
- fmt.Fprintf(
- c.opts.Log,
- "DEBUG worker reported interesting input that doesn't expand coverage, elapsed: %s, id: %s, parent: %s, canMinimize: %t\n",
- c.elapsed(),
- result.entry.Path,
- result.entry.Parent,
- result.canMinimize,
- )
- }
- }
- } else if c.warmupRun() {
- // No error or coverage data was reported for this input during
- // warmup, so continue processing results.
- c.warmupInputLeft--
- if c.warmupInputLeft == 0 {
- fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, testing seed corpus: %d/%d completed, now fuzzing with %d workers\n", c.elapsed(), c.warmupInputCount, c.warmupInputCount, c.opts.Parallel)
- if shouldPrintDebugInfo() {
- fmt.Fprintf(
- c.opts.Log,
- "DEBUG finished testing-only phase, elapsed: %s, entries: %d\n",
- time.Since(c.startTime),
- len(c.corpus.entries),
- )
- }
- }
- }
-
- // Once the result has been processed, stop the worker if we
- // have reached the fuzzing limit.
- if c.opts.Limit > 0 && c.count >= c.opts.Limit {
- stop(nil)
- }
-
- case inputC <- input:
- // Sent the next input to a worker.
- c.sentInput(input)
-
- case minimizeC <- minimizeInput:
- // Sent the next input for minimization to a worker.
- c.sentMinimizeInput(minimizeInput)
-
- case <-statTicker.C:
- c.logStats()
- }
- }
-
- // TODO(jayconrod,katiehockman): if a crasher can't be written to the corpus,
- // write to the cache instead.
-}
-
-// crashError wraps a crasher written to the seed corpus. It saves the name
-// of the file where the input causing the crasher was saved. The testing
-// framework uses this to report a command to re-run that specific input.
-type crashError struct {
- path string
- err error
-}
-
-func (e *crashError) Error() string {
- return e.err.Error()
-}
-
-func (e *crashError) Unwrap() error {
- return e.err
-}
-
-func (e *crashError) CrashPath() string {
- return e.path
-}
-
-type corpus struct {
- entries []CorpusEntry
- hashes map[[sha256.Size]byte]bool
-}
-
-// addCorpusEntries adds entries to the corpus, and optionally writes the entries
-// to the cache directory. If an entry is already in the corpus it is skipped. If
-// all of the entries are unique, addCorpusEntries returns true and a nil error,
-// if at least one of the entries was a duplicate, it returns false and a nil error.
-func (c *coordinator) addCorpusEntries(addToCache bool, entries ...CorpusEntry) (bool, error) {
- noDupes := true
- for _, e := range entries {
- data, err := corpusEntryData(e)
- if err != nil {
- return false, err
- }
- h := sha256.Sum256(data)
- if c.corpus.hashes[h] {
- noDupes = false
- continue
- }
- if addToCache {
- if err := writeToCorpus(&e, c.opts.CacheDir); err != nil {
- return false, err
- }
- // For entries written to disk, we don't hold onto the bytes,
- // since the corpus would consume a significant amount of
- // memory.
- e.Data = nil
- }
- c.corpus.hashes[h] = true
- c.corpus.entries = append(c.corpus.entries, e)
- }
- return noDupes, nil
-}
-
-// CorpusEntry represents an individual input for fuzzing.
-//
-// We must use an equivalent type in the testing and testing/internal/testdeps
-// packages, but testing can't import this package directly, and we don't want
-// to export this type from testing. Instead, we use the same struct type and
-// use a type alias (not a defined type) for convenience.
-type CorpusEntry = struct {
- Parent string
-
- // Path is the path of the corpus file, if the entry was loaded from disk.
- // For other entries, including seed values provided by f.Add, Path is the
- // name of the test, e.g. seed#0 or its hash.
- Path string
-
- // Data is the raw input data. Data should only be populated for seed
- // values. For on-disk corpus files, Data will be nil, as it will be loaded
- // from disk using Path.
- Data []byte
-
- // Values is the unmarshaled values from a corpus file.
- Values []any
-
- Generation int
-
- // IsSeed indicates whether this entry is part of the seed corpus.
- IsSeed bool
-}
-
-// corpusEntryData returns the raw input bytes, either from the data struct
-// field, or from disk.
-func corpusEntryData(ce CorpusEntry) ([]byte, error) {
- if ce.Data != nil {
- return ce.Data, nil
- }
-
- return os.ReadFile(ce.Path)
-}
-
-type fuzzInput struct {
- // entry is the value to test initially. The worker will randomly mutate
- // values from this starting point.
- entry CorpusEntry
-
- // timeout is the time to spend fuzzing variations of this input,
- // not including starting or cleaning up.
- timeout time.Duration
-
- // limit is the maximum number of calls to the fuzz function the worker may
- // make. The worker may make fewer calls, for example, if it finds an
- // error early. If limit is zero, there is no limit on calls to the
- // fuzz function.
- limit int64
-
- // warmup indicates whether this is a warmup input before fuzzing begins. If
- // true, the input should not be fuzzed.
- warmup bool
-
- // coverageData reflects the coordinator's current coverageMask.
- coverageData []byte
-}
-
-type fuzzResult struct {
- // entry is an interesting value or a crasher.
- entry CorpusEntry
-
- // crasherMsg is an error message from a crash. It's "" if no crash was found.
- crasherMsg string
-
- // canMinimize is true if the worker should attempt to minimize this result.
- // It may be false because an attempt has already been made.
- canMinimize bool
-
- // coverageData is set if the worker found new coverage.
- coverageData []byte
-
- // limit is the number of values the coordinator asked the worker
- // to test. 0 if there was no limit.
- limit int64
-
- // count is the number of values the worker actually tested.
- count int64
-
- // totalDuration is the time the worker spent testing inputs.
- totalDuration time.Duration
-
- // entryDuration is the time the worker spent execution an interesting result
- entryDuration time.Duration
-}
-
-type fuzzMinimizeInput struct {
- // entry is an interesting value or crasher to minimize.
- entry CorpusEntry
-
- // crasherMsg is an error message from a crash. It's "" if no crash was found.
- // If set, the worker will attempt to find a smaller input that also produces
- // an error, though not necessarily the same error.
- crasherMsg string
-
- // limit is the maximum number of calls to the fuzz function the worker may
- // make. The worker may make fewer calls, for example, if it can't reproduce
- // an error. If limit is zero, there is no limit on calls to the fuzz function.
- limit int64
-
- // timeout is the time to spend minimizing this input.
- // A zero timeout means no limit.
- timeout time.Duration
-
- // keepCoverage is a set of coverage bits that entry found that were not in
- // the coordinator's combined set. When minimizing, the worker should find an
- // input that preserves at least one of these bits. keepCoverage is nil for
- // crashing inputs.
- keepCoverage []byte
-}
-
-// coordinator holds channels that workers can use to communicate with
-// the coordinator.
-type coordinator struct {
- opts CoordinateFuzzingOpts
-
- // startTime is the time we started the workers after loading the corpus.
- // Used for logging.
- startTime time.Time
-
- // inputC is sent values to fuzz by the coordinator. Any worker may receive
- // values from this channel. Workers send results to resultC.
- inputC chan fuzzInput
-
- // minimizeC is sent values to minimize by the coordinator. Any worker may
- // receive values from this channel. Workers send results to resultC.
- minimizeC chan fuzzMinimizeInput
-
- // resultC is sent results of fuzzing by workers. The coordinator
- // receives these. Multiple types of messages are allowed.
- resultC chan fuzzResult
-
- // count is the number of values fuzzed so far.
- count int64
-
- // countLastLog is the number of values fuzzed when the output was last
- // logged.
- countLastLog int64
-
- // timeLastLog is the time at which the output was last logged.
- timeLastLog time.Time
-
- // interestingCount is the number of unique interesting values which have
- // been found this execution.
- interestingCount int
-
- // warmupInputCount is the count of all entries in the corpus which will
- // need to be received from workers to run once during warmup, but not fuzz.
- // This could be for coverage data, or only for the purposes of verifying
- // that the seed corpus doesn't have any crashers. See warmupRun.
- warmupInputCount int
-
- // warmupInputLeft is the number of entries in the corpus which still need
- // to be received from workers to run once during warmup, but not fuzz.
- // See warmupInputLeft.
- warmupInputLeft int
-
- // duration is the time spent fuzzing inside workers, not counting time
- // starting up or tearing down.
- duration time.Duration
-
- // countWaiting is the number of fuzzing executions the coordinator is
- // waiting on workers to complete.
- countWaiting int64
-
- // corpus is a set of interesting values, including the seed corpus and
- // generated values that workers reported as interesting.
- corpus corpus
-
- // minimizationAllowed is true if one or more of the types of fuzz
- // function's parameters can be minimized.
- minimizationAllowed bool
-
- // inputQueue is a queue of inputs that workers should try fuzzing. This is
- // initially populated from the seed corpus and cached inputs. More inputs
- // may be added as new coverage is discovered.
- inputQueue queue
-
- // minimizeQueue is a queue of inputs that caused errors or exposed new
- // coverage. Workers should attempt to find smaller inputs that do the
- // same thing.
- minimizeQueue queue
-
- // crashMinimizing is the crash that is currently being minimized.
- crashMinimizing *fuzzResult
-
- // coverageMask aggregates coverage that was found for all inputs in the
- // corpus. Each byte represents a single basic execution block. Each set bit
- // within the byte indicates that an input has triggered that block at least
- // 1 << n times, where n is the position of the bit in the byte. For example, a
- // value of 12 indicates that separate inputs have triggered this block
- // between 4-7 times and 8-15 times.
- coverageMask []byte
-}
-
-func newCoordinator(opts CoordinateFuzzingOpts) (*coordinator, error) {
- // Make sure all of the seed corpus has marshalled data.
- for i := range opts.Seed {
- if opts.Seed[i].Data == nil && opts.Seed[i].Values != nil {
- opts.Seed[i].Data = marshalCorpusFile(opts.Seed[i].Values...)
- }
- }
- c := &coordinator{
- opts: opts,
- startTime: time.Now(),
- inputC: make(chan fuzzInput),
- minimizeC: make(chan fuzzMinimizeInput),
- resultC: make(chan fuzzResult),
- timeLastLog: time.Now(),
- corpus: corpus{hashes: make(map[[sha256.Size]byte]bool)},
- }
- if err := c.readCache(); err != nil {
- return nil, err
- }
- if opts.MinimizeLimit > 0 || opts.MinimizeTimeout > 0 {
- for _, t := range opts.Types {
- if isMinimizable(t) {
- c.minimizationAllowed = true
- break
- }
- }
- }
-
- covSize := len(coverage())
- if covSize == 0 {
- fmt.Fprintf(c.opts.Log, "warning: the test binary was not built with coverage instrumentation, so fuzzing will run without coverage guidance and may be inefficient\n")
- // Even though a coverage-only run won't occur, we should still run all
- // of the seed corpus to make sure there are no existing failures before
- // we start fuzzing.
- c.warmupInputCount = len(c.opts.Seed)
- for _, e := range c.opts.Seed {
- c.inputQueue.enqueue(e)
- }
- } else {
- c.warmupInputCount = len(c.corpus.entries)
- for _, e := range c.corpus.entries {
- c.inputQueue.enqueue(e)
- }
- // Set c.coverageMask to a clean []byte full of zeros.
- c.coverageMask = make([]byte, covSize)
- }
- c.warmupInputLeft = c.warmupInputCount
-
- if len(c.corpus.entries) == 0 {
- fmt.Fprintf(c.opts.Log, "warning: starting with empty corpus\n")
- var vals []any
- for _, t := range opts.Types {
- vals = append(vals, zeroValue(t))
- }
- data := marshalCorpusFile(vals...)
- h := sha256.Sum256(data)
- name := fmt.Sprintf("%x", h[:4])
- c.addCorpusEntries(false, CorpusEntry{Path: name, Data: data})
- }
-
- return c, nil
-}
-
-func (c *coordinator) updateStats(result fuzzResult) {
- c.count += result.count
- c.countWaiting -= result.limit
- c.duration += result.totalDuration
-}
-
-func (c *coordinator) logStats() {
- now := time.Now()
- if c.warmupRun() {
- runSoFar := c.warmupInputCount - c.warmupInputLeft
- if coverageEnabled {
- fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, gathering baseline coverage: %d/%d completed\n", c.elapsed(), runSoFar, c.warmupInputCount)
- } else {
- fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, testing seed corpus: %d/%d completed\n", c.elapsed(), runSoFar, c.warmupInputCount)
- }
- } else if c.crashMinimizing != nil {
- fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, minimizing\n", c.elapsed())
- } else {
- rate := float64(c.count-c.countLastLog) / now.Sub(c.timeLastLog).Seconds()
- if coverageEnabled {
- total := c.warmupInputCount + c.interestingCount
- fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, execs: %d (%.0f/sec), new interesting: %d (total: %d)\n", c.elapsed(), c.count, rate, c.interestingCount, total)
- } else {
- fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, execs: %d (%.0f/sec)\n", c.elapsed(), c.count, rate)
- }
- }
- c.countLastLog = c.count
- c.timeLastLog = now
-}
-
-// peekInput returns the next value that should be sent to workers.
-// If the number of executions is limited, the returned value includes
-// a limit for one worker. If there are no executions left, peekInput returns
-// a zero value and false.
-//
-// peekInput doesn't actually remove the input from the queue. The caller
-// must call sentInput after sending the input.
-//
-// If the input queue is empty and the coverage/testing-only run has completed,
-// queue refills it from the corpus.
-func (c *coordinator) peekInput() (fuzzInput, bool) {
- if c.opts.Limit > 0 && c.count+c.countWaiting >= c.opts.Limit {
- // Already making the maximum number of calls to the fuzz function.
- // Don't send more inputs right now.
- return fuzzInput{}, false
- }
- if c.inputQueue.len == 0 {
- if c.warmupRun() {
- // Wait for coverage/testing-only run to finish before sending more
- // inputs.
- return fuzzInput{}, false
- }
- c.refillInputQueue()
- }
-
- entry, ok := c.inputQueue.peek()
- if !ok {
- panic("input queue empty after refill")
- }
- input := fuzzInput{
- entry: entry.(CorpusEntry),
- timeout: workerFuzzDuration,
- warmup: c.warmupRun(),
- }
- if c.coverageMask != nil {
- input.coverageData = bytes.Clone(c.coverageMask)
- }
- if input.warmup {
- // No fuzzing will occur, but it should count toward the limit set by
- // -fuzztime.
- input.limit = 1
- return input, true
- }
-
- if c.opts.Limit > 0 {
- input.limit = c.opts.Limit / int64(c.opts.Parallel)
- if c.opts.Limit%int64(c.opts.Parallel) > 0 {
- input.limit++
- }
- remaining := c.opts.Limit - c.count - c.countWaiting
- if input.limit > remaining {
- input.limit = remaining
- }
- }
- return input, true
-}
-
-// sentInput updates internal counters after an input is sent to c.inputC.
-func (c *coordinator) sentInput(input fuzzInput) {
- c.inputQueue.dequeue()
- c.countWaiting += input.limit
-}
-
-// refillInputQueue refills the input queue from the corpus after it becomes
-// empty.
-func (c *coordinator) refillInputQueue() {
- for _, e := range c.corpus.entries {
- c.inputQueue.enqueue(e)
- }
-}
-
-// queueForMinimization creates a fuzzMinimizeInput from result and adds it
-// to the minimization queue to be sent to workers.
-func (c *coordinator) queueForMinimization(result fuzzResult, keepCoverage []byte) {
- if result.crasherMsg != "" {
- c.minimizeQueue.clear()
- }
-
- input := fuzzMinimizeInput{
- entry: result.entry,
- crasherMsg: result.crasherMsg,
- keepCoverage: keepCoverage,
- }
- c.minimizeQueue.enqueue(input)
-}
-
-// peekMinimizeInput returns the next input that should be sent to workers for
-// minimization.
-func (c *coordinator) peekMinimizeInput() (fuzzMinimizeInput, bool) {
- if !c.canMinimize() {
- // Already making the maximum number of calls to the fuzz function.
- // Don't send more inputs right now.
- return fuzzMinimizeInput{}, false
- }
- v, ok := c.minimizeQueue.peek()
- if !ok {
- return fuzzMinimizeInput{}, false
- }
- input := v.(fuzzMinimizeInput)
-
- if c.opts.MinimizeTimeout > 0 {
- input.timeout = c.opts.MinimizeTimeout
- }
- if c.opts.MinimizeLimit > 0 {
- input.limit = c.opts.MinimizeLimit
- } else if c.opts.Limit > 0 {
- if input.crasherMsg != "" {
- input.limit = c.opts.Limit
- } else {
- input.limit = c.opts.Limit / int64(c.opts.Parallel)
- if c.opts.Limit%int64(c.opts.Parallel) > 0 {
- input.limit++
- }
- }
- }
- if c.opts.Limit > 0 {
- remaining := c.opts.Limit - c.count - c.countWaiting
- if input.limit > remaining {
- input.limit = remaining
- }
- }
- return input, true
-}
-
-// sentMinimizeInput removes an input from the minimization queue after it's
-// sent to minimizeC.
-func (c *coordinator) sentMinimizeInput(input fuzzMinimizeInput) {
- c.minimizeQueue.dequeue()
- c.countWaiting += input.limit
-}
-
-// warmupRun returns true while the coordinator is running inputs without
-// mutating them as a warmup before fuzzing. This could be to gather baseline
-// coverage data for entries in the corpus, or to test all of the seed corpus
-// for errors before fuzzing begins.
-//
-// The coordinator doesn't store coverage data in the cache with each input
-// because that data would be invalid when counter offsets in the test binary
-// change.
-//
-// When gathering coverage, the coordinator sends each entry to a worker to
-// gather coverage for that entry only, without fuzzing or minimizing. This
-// phase ends when all workers have finished, and the coordinator has a combined
-// coverage map.
-func (c *coordinator) warmupRun() bool {
- return c.warmupInputLeft > 0
-}
-
-// updateCoverage sets bits in c.coverageMask that are set in newCoverage.
-// updateCoverage returns the number of newly set bits. See the comment on
-// coverageMask for the format.
-func (c *coordinator) updateCoverage(newCoverage []byte) int {
- if len(newCoverage) != len(c.coverageMask) {
- panic(fmt.Sprintf("number of coverage counters changed at runtime: %d, expected %d", len(newCoverage), len(c.coverageMask)))
- }
- newBitCount := 0
- for i := range newCoverage {
- diff := newCoverage[i] &^ c.coverageMask[i]
- newBitCount += bits.OnesCount8(diff)
- c.coverageMask[i] |= newCoverage[i]
- }
- return newBitCount
-}
-
-// canMinimize returns whether the coordinator should attempt to find smaller
-// inputs that reproduce a crash or new coverage.
-func (c *coordinator) canMinimize() bool {
- return c.minimizationAllowed &&
- (c.opts.Limit == 0 || c.count+c.countWaiting < c.opts.Limit)
-}
-
-func (c *coordinator) elapsed() time.Duration {
- return time.Since(c.startTime).Round(1 * time.Second)
-}
-
-// readCache creates a combined corpus from seed values and values in the cache
-// (in GOCACHE/fuzz).
-//
-// TODO(fuzzing): need a mechanism that can remove values that
-// aren't useful anymore, for example, because they have the wrong type.
-func (c *coordinator) readCache() error {
- if _, err := c.addCorpusEntries(false, c.opts.Seed...); err != nil {
- return err
- }
- entries, err := ReadCorpus(c.opts.CacheDir, c.opts.Types)
- if err != nil {
- if _, ok := err.(*MalformedCorpusError); !ok {
- // It's okay if some files in the cache directory are malformed and
- // are not included in the corpus, but fail if it's an I/O error.
- return err
- }
- // TODO(jayconrod,katiehockman): consider printing some kind of warning
- // indicating the number of files which were skipped because they are
- // malformed.
- }
- if _, err := c.addCorpusEntries(false, entries...); err != nil {
- return err
- }
- return nil
-}
-
-// MalformedCorpusError is an error found while reading the corpus from the
-// filesystem. All of the errors are stored in the errs list. The testing
-// framework uses this to report malformed files in testdata.
-type MalformedCorpusError struct {
- errs []error
-}
-
-func (e *MalformedCorpusError) Error() string {
- var msgs []string
- for _, s := range e.errs {
- msgs = append(msgs, s.Error())
- }
- return strings.Join(msgs, "\n")
-}
-
-// ReadCorpus reads the corpus from the provided dir. The returned corpus
-// entries are guaranteed to match the given types. Any malformed files will
-// be saved in a MalformedCorpusError and returned, along with the most recent
-// error.
-func ReadCorpus(dir string, types []reflect.Type) ([]CorpusEntry, error) {
- files, err := os.ReadDir(dir)
- if os.IsNotExist(err) {
- return nil, nil // No corpus to read
- } else if err != nil {
- return nil, fmt.Errorf("reading seed corpus from testdata: %v", err)
- }
- var corpus []CorpusEntry
- var errs []error
- for _, file := range files {
- // TODO(jayconrod,katiehockman): determine when a file is a fuzzing input
- // based on its name. We should only read files created by writeToCorpus.
- // If we read ALL files, we won't be able to change the file format by
- // changing the extension. We also won't be able to add files like
- // README.txt explaining why the directory exists.
- if file.IsDir() {
- continue
- }
- filename := filepath.Join(dir, file.Name())
- data, err := os.ReadFile(filename)
- if err != nil {
- return nil, fmt.Errorf("failed to read corpus file: %v", err)
- }
- var vals []any
- vals, err = readCorpusData(data, types)
- if err != nil {
- errs = append(errs, fmt.Errorf("%q: %v", filename, err))
- continue
- }
- corpus = append(corpus, CorpusEntry{Path: filename, Values: vals})
- }
- if len(errs) > 0 {
- return corpus, &MalformedCorpusError{errs: errs}
- }
- return corpus, nil
-}
-
-func readCorpusData(data []byte, types []reflect.Type) ([]any, error) {
- vals, err := unmarshalCorpusFile(data)
- if err != nil {
- return nil, fmt.Errorf("unmarshal: %v", err)
- }
- if err = CheckCorpus(vals, types); err != nil {
- return nil, err
- }
- return vals, nil
-}
-
-// CheckCorpus verifies that the types in vals match the expected types
-// provided.
-func CheckCorpus(vals []any, types []reflect.Type) error {
- if len(vals) != len(types) {
- return fmt.Errorf("wrong number of values in corpus entry: %d, want %d", len(vals), len(types))
- }
- valsT := make([]reflect.Type, len(vals))
- for valsI, v := range vals {
- valsT[valsI] = reflect.TypeOf(v)
- }
- for i := range types {
- if valsT[i] != types[i] {
- return fmt.Errorf("mismatched types in corpus entry: %v, want %v", valsT, types)
- }
- }
- return nil
-}
-
-// writeToCorpus atomically writes the given bytes to a new file in testdata. If
-// the directory does not exist, it will create one. If the file already exists,
-// writeToCorpus will not rewrite it. writeToCorpus sets entry.Path to the new
-// file that was just written or an error if it failed.
-func writeToCorpus(entry *CorpusEntry, dir string) (err error) {
- sum := fmt.Sprintf("%x", sha256.Sum256(entry.Data))[:16]
- entry.Path = filepath.Join(dir, sum)
- if err := os.MkdirAll(dir, 0777); err != nil {
- return err
- }
- if err := os.WriteFile(entry.Path, entry.Data, 0666); err != nil {
- os.Remove(entry.Path) // remove partially written file
- return err
- }
- return nil
-}
-
-func testName(path string) string {
- return filepath.Base(path)
-}
-
-func zeroValue(t reflect.Type) any {
- for _, v := range zeroVals {
- if reflect.TypeOf(v) == t {
- return v
- }
- }
- panic(fmt.Sprintf("unsupported type: %v", t))
-}
-
-var zeroVals []any = []any{
- []byte(""),
- string(""),
- false,
- byte(0),
- rune(0),
- float32(0),
- float64(0),
- int(0),
- int8(0),
- int16(0),
- int32(0),
- int64(0),
- uint(0),
- uint8(0),
- uint16(0),
- uint32(0),
- uint64(0),
-}
-
-var debugInfo = godebug.New("fuzzdebug").Value() == "1"
-
-func shouldPrintDebugInfo() bool {
- return debugInfo
-}
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/worker.go b/contrib/go/_std_1.20/src/internal/fuzz/worker.go
deleted file mode 100644
index 467c39bdc9..0000000000
--- a/contrib/go/_std_1.20/src/internal/fuzz/worker.go
+++ /dev/null
@@ -1,1184 +0,0 @@
-// 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 fuzz
-
-import (
- "bytes"
- "context"
- "crypto/sha256"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "os"
- "os/exec"
- "reflect"
- "runtime"
- "sync"
- "time"
-)
-
-const (
- // workerFuzzDuration is the amount of time a worker can spend testing random
- // variations of an input given by the coordinator.
- workerFuzzDuration = 100 * time.Millisecond
-
- // workerTimeoutDuration is the amount of time a worker can go without
- // responding to the coordinator before being stopped.
- workerTimeoutDuration = 1 * time.Second
-
- // workerExitCode is used as an exit code by fuzz worker processes after an internal error.
- // This distinguishes internal errors from uncontrolled panics and other crashes.
- // Keep in sync with internal/fuzz.workerExitCode.
- workerExitCode = 70
-
- // workerSharedMemSize is the maximum size of the shared memory file used to
- // communicate with workers. This limits the size of fuzz inputs.
- workerSharedMemSize = 100 << 20 // 100 MB
-)
-
-// worker manages a worker process running a test binary. The worker object
-// exists only in the coordinator (the process started by 'go test -fuzz').
-// workerClient is used by the coordinator to send RPCs to the worker process,
-// which handles them with workerServer.
-type worker struct {
- dir string // working directory, same as package directory
- binPath string // path to test executable
- args []string // arguments for test executable
- env []string // environment for test executable
-
- coordinator *coordinator
-
- memMu chan *sharedMem // mutex guarding shared memory with worker; persists across processes.
-
- cmd *exec.Cmd // current worker process
- client *workerClient // used to communicate with worker process
- waitErr error // last error returned by wait, set before termC is closed.
- interrupted bool // true after stop interrupts a running worker.
- termC chan struct{} // closed by wait when worker process terminates
-}
-
-func newWorker(c *coordinator, dir, binPath string, args, env []string) (*worker, error) {
- mem, err := sharedMemTempFile(workerSharedMemSize)
- if err != nil {
- return nil, err
- }
- memMu := make(chan *sharedMem, 1)
- memMu <- mem
- return &worker{
- dir: dir,
- binPath: binPath,
- args: args,
- env: env[:len(env):len(env)], // copy on append to ensure workers don't overwrite each other.
- coordinator: c,
- memMu: memMu,
- }, nil
-}
-
-// cleanup releases persistent resources associated with the worker.
-func (w *worker) cleanup() error {
- mem := <-w.memMu
- if mem == nil {
- return nil
- }
- close(w.memMu)
- return mem.Close()
-}
-
-// coordinate runs the test binary to perform fuzzing.
-//
-// coordinate loops until ctx is cancelled or a fatal error is encountered.
-// If a test process terminates unexpectedly while fuzzing, coordinate will
-// attempt to restart and continue unless the termination can be attributed
-// to an interruption (from a timer or the user).
-//
-// While looping, coordinate receives inputs from the coordinator, passes
-// those inputs to the worker process, then passes the results back to
-// the coordinator.
-func (w *worker) coordinate(ctx context.Context) error {
- // Main event loop.
- for {
- // Start or restart the worker if it's not running.
- if !w.isRunning() {
- if err := w.startAndPing(ctx); err != nil {
- return err
- }
- }
-
- select {
- case <-ctx.Done():
- // Worker was told to stop.
- err := w.stop()
- if err != nil && !w.interrupted && !isInterruptError(err) {
- return err
- }
- return ctx.Err()
-
- case <-w.termC:
- // Worker process terminated unexpectedly while waiting for input.
- err := w.stop()
- if w.interrupted {
- panic("worker interrupted after unexpected termination")
- }
- if err == nil || isInterruptError(err) {
- // Worker stopped, either by exiting with status 0 or after being
- // interrupted with a signal that was not sent by the coordinator.
- //
- // When the user presses ^C, on POSIX platforms, SIGINT is delivered to
- // all processes in the group concurrently, and the worker may see it
- // before the coordinator. The worker should exit 0 gracefully (in
- // theory).
- //
- // This condition is probably intended by the user, so suppress
- // the error.
- return nil
- }
- if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == workerExitCode {
- // Worker exited with a code indicating F.Fuzz was not called correctly,
- // for example, F.Fail was called first.
- return fmt.Errorf("fuzzing process exited unexpectedly due to an internal failure: %w", err)
- }
- // Worker exited non-zero or was terminated by a non-interrupt
- // signal (for example, SIGSEGV) while fuzzing.
- return fmt.Errorf("fuzzing process hung or terminated unexpectedly: %w", err)
- // TODO(jayconrod,katiehockman): if -keepfuzzing, restart worker.
-
- case input := <-w.coordinator.inputC:
- // Received input from coordinator.
- args := fuzzArgs{
- Limit: input.limit,
- Timeout: input.timeout,
- Warmup: input.warmup,
- CoverageData: input.coverageData,
- }
- entry, resp, isInternalError, err := w.client.fuzz(ctx, input.entry, args)
- canMinimize := true
- if err != nil {
- // Error communicating with worker.
- w.stop()
- if ctx.Err() != nil {
- // Timeout or interruption.
- return ctx.Err()
- }
- if w.interrupted {
- // Communication error before we stopped the worker.
- // Report an error, but don't record a crasher.
- return fmt.Errorf("communicating with fuzzing process: %v", err)
- }
- if sig, ok := terminationSignal(w.waitErr); ok && !isCrashSignal(sig) {
- // Worker terminated by a signal that probably wasn't caused by a
- // specific input to the fuzz function. For example, on Linux,
- // the kernel (OOM killer) may send SIGKILL to a process using a lot
- // of memory. Or the shell might send SIGHUP when the terminal
- // is closed. Don't record a crasher.
- return fmt.Errorf("fuzzing process terminated by unexpected signal; no crash will be recorded: %v", w.waitErr)
- }
- if isInternalError {
- // An internal error occurred which shouldn't be considered
- // a crash.
- return err
- }
- // Unexpected termination. Set error message and fall through.
- // We'll restart the worker on the next iteration.
- // Don't attempt to minimize this since it crashed the worker.
- resp.Err = fmt.Sprintf("fuzzing process hung or terminated unexpectedly: %v", w.waitErr)
- canMinimize = false
- }
- result := fuzzResult{
- limit: input.limit,
- count: resp.Count,
- totalDuration: resp.TotalDuration,
- entryDuration: resp.InterestingDuration,
- entry: entry,
- crasherMsg: resp.Err,
- coverageData: resp.CoverageData,
- canMinimize: canMinimize,
- }
- w.coordinator.resultC <- result
-
- case input := <-w.coordinator.minimizeC:
- // Received input to minimize from coordinator.
- result, err := w.minimize(ctx, input)
- if err != nil {
- // Error minimizing. Send back the original input. If it didn't cause
- // an error before, report it as causing an error now.
- // TODO: double-check this is handled correctly when
- // implementing -keepfuzzing.
- result = fuzzResult{
- entry: input.entry,
- crasherMsg: input.crasherMsg,
- canMinimize: false,
- limit: input.limit,
- }
- if result.crasherMsg == "" {
- result.crasherMsg = err.Error()
- }
- }
- w.coordinator.resultC <- result
- }
- }
-}
-
-// minimize tells a worker process to attempt to find a smaller value that
-// either causes an error (if we started minimizing because we found an input
-// that causes an error) or preserves new coverage (if we started minimizing
-// because we found an input that expands coverage).
-func (w *worker) minimize(ctx context.Context, input fuzzMinimizeInput) (min fuzzResult, err error) {
- if w.coordinator.opts.MinimizeTimeout != 0 {
- var cancel func()
- ctx, cancel = context.WithTimeout(ctx, w.coordinator.opts.MinimizeTimeout)
- defer cancel()
- }
-
- args := minimizeArgs{
- Limit: input.limit,
- Timeout: input.timeout,
- KeepCoverage: input.keepCoverage,
- }
- entry, resp, err := w.client.minimize(ctx, input.entry, args)
- if err != nil {
- // Error communicating with worker.
- w.stop()
- if ctx.Err() != nil || w.interrupted || isInterruptError(w.waitErr) {
- // Worker was interrupted, possibly by the user pressing ^C.
- // Normally, workers can handle interrupts and timeouts gracefully and
- // will return without error. An error here indicates the worker
- // may not have been in a good state, but the error won't be meaningful
- // to the user. Just return the original crasher without logging anything.
- return fuzzResult{
- entry: input.entry,
- crasherMsg: input.crasherMsg,
- coverageData: input.keepCoverage,
- canMinimize: false,
- limit: input.limit,
- }, nil
- }
- return fuzzResult{
- entry: entry,
- crasherMsg: fmt.Sprintf("fuzzing process hung or terminated unexpectedly while minimizing: %v", err),
- canMinimize: false,
- limit: input.limit,
- count: resp.Count,
- totalDuration: resp.Duration,
- }, nil
- }
-
- if input.crasherMsg != "" && resp.Err == "" {
- return fuzzResult{}, fmt.Errorf("attempted to minimize a crash but could not reproduce")
- }
-
- return fuzzResult{
- entry: entry,
- crasherMsg: resp.Err,
- coverageData: resp.CoverageData,
- canMinimize: false,
- limit: input.limit,
- count: resp.Count,
- totalDuration: resp.Duration,
- }, nil
-}
-
-func (w *worker) isRunning() bool {
- return w.cmd != nil
-}
-
-// startAndPing starts the worker process and sends it a message to make sure it
-// can communicate.
-//
-// startAndPing returns an error if any part of this didn't work, including if
-// the context is expired or the worker process was interrupted before it
-// responded. Errors that happen after start but before the ping response
-// likely indicate that the worker did not call F.Fuzz or called F.Fail first.
-// We don't record crashers for these errors.
-func (w *worker) startAndPing(ctx context.Context) error {
- if ctx.Err() != nil {
- return ctx.Err()
- }
- if err := w.start(); err != nil {
- return err
- }
- if err := w.client.ping(ctx); err != nil {
- w.stop()
- if ctx.Err() != nil {
- return ctx.Err()
- }
- if isInterruptError(err) {
- // User may have pressed ^C before worker responded.
- return err
- }
- // TODO: record and return stderr.
- return fmt.Errorf("fuzzing process terminated without fuzzing: %w", err)
- }
- return nil
-}
-
-// start runs a new worker process.
-//
-// If the process couldn't be started, start returns an error. Start won't
-// return later termination errors from the process if they occur.
-//
-// If the process starts successfully, start returns nil. stop must be called
-// once later to clean up, even if the process terminates on its own.
-//
-// When the process terminates, w.waitErr is set to the error (if any), and
-// w.termC is closed.
-func (w *worker) start() (err error) {
- if w.isRunning() {
- panic("worker already started")
- }
- w.waitErr = nil
- w.interrupted = false
- w.termC = nil
-
- cmd := exec.Command(w.binPath, w.args...)
- cmd.Dir = w.dir
- cmd.Env = w.env[:len(w.env):len(w.env)] // copy on append to ensure workers don't overwrite each other.
-
- // Create the "fuzz_in" and "fuzz_out" pipes so we can communicate with
- // the worker. We don't use stdin and stdout, since the test binary may
- // do something else with those.
- //
- // Each pipe has a reader and a writer. The coordinator writes to fuzzInW
- // and reads from fuzzOutR. The worker inherits fuzzInR and fuzzOutW.
- // The coordinator closes fuzzInR and fuzzOutW after starting the worker,
- // since we have no further need of them.
- fuzzInR, fuzzInW, err := os.Pipe()
- if err != nil {
- return err
- }
- defer fuzzInR.Close()
- fuzzOutR, fuzzOutW, err := os.Pipe()
- if err != nil {
- fuzzInW.Close()
- return err
- }
- defer fuzzOutW.Close()
- setWorkerComm(cmd, workerComm{fuzzIn: fuzzInR, fuzzOut: fuzzOutW, memMu: w.memMu})
-
- // Start the worker process.
- if err := cmd.Start(); err != nil {
- fuzzInW.Close()
- fuzzOutR.Close()
- return err
- }
-
- // Worker started successfully.
- // After this, w.client owns fuzzInW and fuzzOutR, so w.client.Close must be
- // called later by stop.
- w.cmd = cmd
- w.termC = make(chan struct{})
- comm := workerComm{fuzzIn: fuzzInW, fuzzOut: fuzzOutR, memMu: w.memMu}
- m := newMutator()
- w.client = newWorkerClient(comm, m)
-
- go func() {
- w.waitErr = w.cmd.Wait()
- close(w.termC)
- }()
-
- return nil
-}
-
-// stop tells the worker process to exit by closing w.client, then blocks until
-// it terminates. If the worker doesn't terminate after a short time, stop
-// signals it with os.Interrupt (where supported), then os.Kill.
-//
-// stop returns the error the process terminated with, if any (same as
-// w.waitErr).
-//
-// stop must be called at least once after start returns successfully, even if
-// the worker process terminates unexpectedly.
-func (w *worker) stop() error {
- if w.termC == nil {
- panic("worker was not started successfully")
- }
- select {
- case <-w.termC:
- // Worker already terminated.
- if w.client == nil {
- // stop already called.
- return w.waitErr
- }
- // Possible unexpected termination.
- w.client.Close()
- w.cmd = nil
- w.client = nil
- return w.waitErr
- default:
- // Worker still running.
- }
-
- // Tell the worker to stop by closing fuzz_in. It won't actually stop until it
- // finishes with earlier calls.
- closeC := make(chan struct{})
- go func() {
- w.client.Close()
- close(closeC)
- }()
-
- sig := os.Interrupt
- if runtime.GOOS == "windows" {
- // Per https://golang.org/pkg/os/#Signal, “Interrupt is not implemented on
- // Windows; using it with os.Process.Signal will return an error.”
- // Fall back to Kill instead.
- sig = os.Kill
- }
-
- t := time.NewTimer(workerTimeoutDuration)
- for {
- select {
- case <-w.termC:
- // Worker terminated.
- t.Stop()
- <-closeC
- w.cmd = nil
- w.client = nil
- return w.waitErr
-
- case <-t.C:
- // Timer fired before worker terminated.
- w.interrupted = true
- switch sig {
- case os.Interrupt:
- // Try to stop the worker with SIGINT and wait a little longer.
- w.cmd.Process.Signal(sig)
- sig = os.Kill
- t.Reset(workerTimeoutDuration)
-
- case os.Kill:
- // Try to stop the worker with SIGKILL and keep waiting.
- w.cmd.Process.Signal(sig)
- sig = nil
- t.Reset(workerTimeoutDuration)
-
- case nil:
- // Still waiting. Print a message to let the user know why.
- fmt.Fprintf(w.coordinator.opts.Log, "waiting for fuzzing process to terminate...\n")
- }
- }
- }
-}
-
-// RunFuzzWorker is called in a worker process to communicate with the
-// coordinator process in order to fuzz random inputs. RunFuzzWorker loops
-// until the coordinator tells it to stop.
-//
-// fn is a wrapper on the fuzz function. It may return an error to indicate
-// a given input "crashed". The coordinator will also record a crasher if
-// the function times out or terminates the process.
-//
-// RunFuzzWorker returns an error if it could not communicate with the
-// coordinator process.
-func RunFuzzWorker(ctx context.Context, fn func(CorpusEntry) error) error {
- comm, err := getWorkerComm()
- if err != nil {
- return err
- }
- srv := &workerServer{
- workerComm: comm,
- fuzzFn: func(e CorpusEntry) (time.Duration, error) {
- timer := time.AfterFunc(10*time.Second, func() {
- panic("deadlocked!") // this error message won't be printed
- })
- defer timer.Stop()
- start := time.Now()
- err := fn(e)
- return time.Since(start), err
- },
- m: newMutator(),
- }
- return srv.serve(ctx)
-}
-
-// call is serialized and sent from the coordinator on fuzz_in. It acts as
-// a minimalist RPC mechanism. Exactly one of its fields must be set to indicate
-// which method to call.
-type call struct {
- Ping *pingArgs
- Fuzz *fuzzArgs
- Minimize *minimizeArgs
-}
-
-// minimizeArgs contains arguments to workerServer.minimize. The value to
-// minimize is already in shared memory.
-type minimizeArgs struct {
- // Timeout is the time to spend minimizing. This may include time to start up,
- // especially if the input causes the worker process to terminated, requiring
- // repeated restarts.
- Timeout time.Duration
-
- // Limit is the maximum number of values to test, without spending more time
- // than Duration. 0 indicates no limit.
- Limit int64
-
- // KeepCoverage is a set of coverage counters the worker should attempt to
- // keep in minimized values. When provided, the worker will reject inputs that
- // don't cause at least one of these bits to be set.
- KeepCoverage []byte
-
- // Index is the index of the fuzz target parameter to be minimized.
- Index int
-}
-
-// minimizeResponse contains results from workerServer.minimize.
-type minimizeResponse struct {
- // WroteToMem is true if the worker found a smaller input and wrote it to
- // shared memory. If minimizeArgs.KeepCoverage was set, the minimized input
- // preserved at least one coverage bit and did not cause an error.
- // Otherwise, the minimized input caused some error, recorded in Err.
- WroteToMem bool
-
- // Err is the error string caused by the value in shared memory, if any.
- Err string
-
- // CoverageData is the set of coverage bits activated by the minimized value
- // in shared memory. When set, it contains at least one bit from KeepCoverage.
- // CoverageData will be nil if Err is set or if minimization failed.
- CoverageData []byte
-
- // Duration is the time spent minimizing, not including starting or cleaning up.
- Duration time.Duration
-
- // Count is the number of values tested.
- Count int64
-}
-
-// fuzzArgs contains arguments to workerServer.fuzz. The value to fuzz is
-// passed in shared memory.
-type fuzzArgs struct {
- // Timeout is the time to spend fuzzing, not including starting or
- // cleaning up.
- Timeout time.Duration
-
- // Limit is the maximum number of values to test, without spending more time
- // than Duration. 0 indicates no limit.
- Limit int64
-
- // Warmup indicates whether this is part of a warmup run, meaning that
- // fuzzing should not occur. If coverageEnabled is true, then coverage data
- // should be reported.
- Warmup bool
-
- // CoverageData is the coverage data. If set, the worker should update its
- // local coverage data prior to fuzzing.
- CoverageData []byte
-}
-
-// fuzzResponse contains results from workerServer.fuzz.
-type fuzzResponse struct {
- // Duration is the time spent fuzzing, not including starting or cleaning up.
- TotalDuration time.Duration
- InterestingDuration time.Duration
-
- // Count is the number of values tested.
- Count int64
-
- // CoverageData is set if the value in shared memory expands coverage
- // and therefore may be interesting to the coordinator.
- CoverageData []byte
-
- // Err is the error string caused by the value in shared memory, which is
- // non-empty if the value in shared memory caused a crash.
- Err string
-
- // InternalErr is the error string caused by an internal error in the
- // worker. This shouldn't be considered a crasher.
- InternalErr string
-}
-
-// pingArgs contains arguments to workerServer.ping.
-type pingArgs struct{}
-
-// pingResponse contains results from workerServer.ping.
-type pingResponse struct{}
-
-// workerComm holds pipes and shared memory used for communication
-// between the coordinator process (client) and a worker process (server).
-// These values are unique to each worker; they are shared only with the
-// coordinator, not with other workers.
-//
-// Access to shared memory is synchronized implicitly over the RPC protocol
-// implemented in workerServer and workerClient. During a call, the client
-// (worker) has exclusive access to shared memory; at other times, the server
-// (coordinator) has exclusive access.
-type workerComm struct {
- fuzzIn, fuzzOut *os.File
- memMu chan *sharedMem // mutex guarding shared memory
-}
-
-// workerServer is a minimalist RPC server, run by fuzz worker processes.
-// It allows the coordinator process (using workerClient) to call methods in a
-// worker process. This system allows the coordinator to run multiple worker
-// processes in parallel and to collect inputs that caused crashes from shared
-// memory after a worker process terminates unexpectedly.
-type workerServer struct {
- workerComm
- m *mutator
-
- // coverageMask is the local coverage data for the worker. It is
- // periodically updated to reflect the data in the coordinator when new
- // coverage is found.
- coverageMask []byte
-
- // fuzzFn runs the worker's fuzz target on the given input and returns an
- // error if it finds a crasher (the process may also exit or crash), and the
- // time it took to run the input. It sets a deadline of 10 seconds, at which
- // point it will panic with the assumption that the process is hanging or
- // deadlocked.
- fuzzFn func(CorpusEntry) (time.Duration, error)
-}
-
-// serve reads serialized RPC messages on fuzzIn. When serve receives a message,
-// it calls the corresponding method, then sends the serialized result back
-// on fuzzOut.
-//
-// serve handles RPC calls synchronously; it will not attempt to read a message
-// until the previous call has finished.
-//
-// serve returns errors that occurred when communicating over pipes. serve
-// does not return errors from method calls; those are passed through serialized
-// responses.
-func (ws *workerServer) serve(ctx context.Context) error {
- enc := json.NewEncoder(ws.fuzzOut)
- dec := json.NewDecoder(&contextReader{ctx: ctx, r: ws.fuzzIn})
- for {
- var c call
- if err := dec.Decode(&c); err != nil {
- if err == io.EOF || err == ctx.Err() {
- return nil
- } else {
- return err
- }
- }
-
- var resp any
- switch {
- case c.Fuzz != nil:
- resp = ws.fuzz(ctx, *c.Fuzz)
- case c.Minimize != nil:
- resp = ws.minimize(ctx, *c.Minimize)
- case c.Ping != nil:
- resp = ws.ping(ctx, *c.Ping)
- default:
- return errors.New("no arguments provided for any call")
- }
-
- if err := enc.Encode(resp); err != nil {
- return err
- }
- }
-}
-
-// chainedMutations is how many mutations are applied before the worker
-// resets the input to it's original state.
-// NOTE: this number was picked without much thought. It is low enough that
-// it seems to create a significant diversity in mutated inputs. We may want
-// to consider looking into this more closely once we have a proper performance
-// testing framework. Another option is to randomly pick the number of chained
-// mutations on each invocation of the workerServer.fuzz method (this appears to
-// be what libFuzzer does, although there seems to be no documentation which
-// explains why this choice was made.)
-const chainedMutations = 5
-
-// fuzz runs the test function on random variations of the input value in shared
-// memory for a limited duration or number of iterations.
-//
-// fuzz returns early if it finds an input that crashes the fuzz function (with
-// fuzzResponse.Err set) or an input that expands coverage (with
-// fuzzResponse.InterestingDuration set).
-//
-// fuzz does not modify the input in shared memory. Instead, it saves the
-// initial PRNG state in shared memory and increments a counter in shared
-// memory before each call to the test function. The caller may reconstruct
-// the crashing input with this information, since the PRNG is deterministic.
-func (ws *workerServer) fuzz(ctx context.Context, args fuzzArgs) (resp fuzzResponse) {
- if args.CoverageData != nil {
- if ws.coverageMask != nil && len(args.CoverageData) != len(ws.coverageMask) {
- resp.InternalErr = fmt.Sprintf("unexpected size for CoverageData: got %d, expected %d", len(args.CoverageData), len(ws.coverageMask))
- return resp
- }
- ws.coverageMask = args.CoverageData
- }
- start := time.Now()
- defer func() { resp.TotalDuration = time.Since(start) }()
-
- if args.Timeout != 0 {
- var cancel func()
- ctx, cancel = context.WithTimeout(ctx, args.Timeout)
- defer cancel()
- }
- mem := <-ws.memMu
- ws.m.r.save(&mem.header().randState, &mem.header().randInc)
- defer func() {
- resp.Count = mem.header().count
- ws.memMu <- mem
- }()
- if args.Limit > 0 && mem.header().count >= args.Limit {
- resp.InternalErr = fmt.Sprintf("mem.header().count %d already exceeds args.Limit %d", mem.header().count, args.Limit)
- return resp
- }
-
- originalVals, err := unmarshalCorpusFile(mem.valueCopy())
- if err != nil {
- resp.InternalErr = err.Error()
- return resp
- }
- vals := make([]any, len(originalVals))
- copy(vals, originalVals)
-
- shouldStop := func() bool {
- return args.Limit > 0 && mem.header().count >= args.Limit
- }
- fuzzOnce := func(entry CorpusEntry) (dur time.Duration, cov []byte, errMsg string) {
- mem.header().count++
- var err error
- dur, err = ws.fuzzFn(entry)
- if err != nil {
- errMsg = err.Error()
- if errMsg == "" {
- errMsg = "fuzz function failed with no input"
- }
- return dur, nil, errMsg
- }
- if ws.coverageMask != nil && countNewCoverageBits(ws.coverageMask, coverageSnapshot) > 0 {
- return dur, coverageSnapshot, ""
- }
- return dur, nil, ""
- }
-
- if args.Warmup {
- dur, _, errMsg := fuzzOnce(CorpusEntry{Values: vals})
- if errMsg != "" {
- resp.Err = errMsg
- return resp
- }
- resp.InterestingDuration = dur
- if coverageEnabled {
- resp.CoverageData = coverageSnapshot
- }
- return resp
- }
-
- for {
- select {
- case <-ctx.Done():
- return resp
- default:
- if mem.header().count%chainedMutations == 0 {
- copy(vals, originalVals)
- ws.m.r.save(&mem.header().randState, &mem.header().randInc)
- }
- ws.m.mutate(vals, cap(mem.valueRef()))
-
- entry := CorpusEntry{Values: vals}
- dur, cov, errMsg := fuzzOnce(entry)
- if errMsg != "" {
- resp.Err = errMsg
- return resp
- }
- if cov != nil {
- resp.CoverageData = cov
- resp.InterestingDuration = dur
- return resp
- }
- if shouldStop() {
- return resp
- }
- }
- }
-}
-
-func (ws *workerServer) minimize(ctx context.Context, args minimizeArgs) (resp minimizeResponse) {
- start := time.Now()
- defer func() { resp.Duration = time.Since(start) }()
- mem := <-ws.memMu
- defer func() { ws.memMu <- mem }()
- vals, err := unmarshalCorpusFile(mem.valueCopy())
- if err != nil {
- panic(err)
- }
- inpHash := sha256.Sum256(mem.valueCopy())
- if args.Timeout != 0 {
- var cancel func()
- ctx, cancel = context.WithTimeout(ctx, args.Timeout)
- defer cancel()
- }
-
- // Minimize the values in vals, then write to shared memory. We only write
- // to shared memory after completing minimization.
- success, err := ws.minimizeInput(ctx, vals, mem, args)
- if success {
- writeToMem(vals, mem)
- outHash := sha256.Sum256(mem.valueCopy())
- mem.header().rawInMem = false
- resp.WroteToMem = true
- if err != nil {
- resp.Err = err.Error()
- } else {
- // If the values didn't change during minimization then coverageSnapshot is likely
- // a dirty snapshot which represents the very last step of minimization, not the
- // coverage for the initial input. In that case just return the coverage we were
- // given initially, since it more accurately represents the coverage map for the
- // input we are returning.
- if outHash != inpHash {
- resp.CoverageData = coverageSnapshot
- } else {
- resp.CoverageData = args.KeepCoverage
- }
- }
- }
- return resp
-}
-
-// minimizeInput applies a series of minimizing transformations on the provided
-// vals, ensuring that each minimization still causes an error, or keeps
-// coverage, in fuzzFn. It uses the context to determine how long to run,
-// stopping once closed. It returns a bool indicating whether minimization was
-// successful and an error if one was found.
-func (ws *workerServer) minimizeInput(ctx context.Context, vals []any, mem *sharedMem, args minimizeArgs) (success bool, retErr error) {
- keepCoverage := args.KeepCoverage
- memBytes := mem.valueRef()
- bPtr := &memBytes
- count := &mem.header().count
- shouldStop := func() bool {
- return ctx.Err() != nil ||
- (args.Limit > 0 && *count >= args.Limit)
- }
- if shouldStop() {
- return false, nil
- }
-
- // Check that the original value preserves coverage or causes an error.
- // If not, then whatever caused us to think the value was interesting may
- // have been a flake, and we can't minimize it.
- *count++
- _, retErr = ws.fuzzFn(CorpusEntry{Values: vals})
- if keepCoverage != nil {
- if !hasCoverageBit(keepCoverage, coverageSnapshot) || retErr != nil {
- return false, nil
- }
- } else if retErr == nil {
- return false, nil
- }
- mem.header().rawInMem = true
-
- // tryMinimized runs the fuzz function with candidate replacing the value
- // at index valI. tryMinimized returns whether the input with candidate is
- // interesting for the same reason as the original input: it returns
- // an error if one was expected, or it preserves coverage.
- tryMinimized := func(candidate []byte) bool {
- prev := vals[args.Index]
- switch prev.(type) {
- case []byte:
- vals[args.Index] = candidate
- case string:
- vals[args.Index] = string(candidate)
- default:
- panic("impossible")
- }
- copy(*bPtr, candidate)
- *bPtr = (*bPtr)[:len(candidate)]
- mem.setValueLen(len(candidate))
- *count++
- _, err := ws.fuzzFn(CorpusEntry{Values: vals})
- if err != nil {
- retErr = err
- if keepCoverage != nil {
- // Now that we've found a crash, that's more important than any
- // minimization of interesting inputs that was being done. Clear out
- // keepCoverage to only minimize the crash going forward.
- keepCoverage = nil
- }
- return true
- }
- // Minimization should preserve coverage bits.
- if keepCoverage != nil && isCoverageSubset(keepCoverage, coverageSnapshot) {
- return true
- }
- vals[args.Index] = prev
- return false
- }
- switch v := vals[args.Index].(type) {
- case string:
- minimizeBytes([]byte(v), tryMinimized, shouldStop)
- case []byte:
- minimizeBytes(v, tryMinimized, shouldStop)
- default:
- panic("impossible")
- }
- return true, retErr
-}
-
-func writeToMem(vals []any, mem *sharedMem) {
- b := marshalCorpusFile(vals...)
- mem.setValue(b)
-}
-
-// ping does nothing. The coordinator calls this method to ensure the worker
-// has called F.Fuzz and can communicate.
-func (ws *workerServer) ping(ctx context.Context, args pingArgs) pingResponse {
- return pingResponse{}
-}
-
-// workerClient is a minimalist RPC client. The coordinator process uses a
-// workerClient to call methods in each worker process (handled by
-// workerServer).
-type workerClient struct {
- workerComm
- m *mutator
-
- // mu is the mutex protecting the workerComm.fuzzIn pipe. This must be
- // locked before making calls to the workerServer. It prevents
- // workerClient.Close from closing fuzzIn while workerClient methods are
- // writing to it concurrently, and prevents multiple callers from writing to
- // fuzzIn concurrently.
- mu sync.Mutex
-}
-
-func newWorkerClient(comm workerComm, m *mutator) *workerClient {
- return &workerClient{workerComm: comm, m: m}
-}
-
-// Close shuts down the connection to the RPC server (the worker process) by
-// closing fuzz_in. Close drains fuzz_out (avoiding a SIGPIPE in the worker),
-// and closes it after the worker process closes the other end.
-func (wc *workerClient) Close() error {
- wc.mu.Lock()
- defer wc.mu.Unlock()
-
- // Close fuzzIn. This signals to the server that there are no more calls,
- // and it should exit.
- if err := wc.fuzzIn.Close(); err != nil {
- wc.fuzzOut.Close()
- return err
- }
-
- // Drain fuzzOut and close it. When the server exits, the kernel will close
- // its end of fuzzOut, and we'll get EOF.
- if _, err := io.Copy(io.Discard, wc.fuzzOut); err != nil {
- wc.fuzzOut.Close()
- return err
- }
- return wc.fuzzOut.Close()
-}
-
-// errSharedMemClosed is returned by workerClient methods that cannot access
-// shared memory because it was closed and unmapped by another goroutine. That
-// can happen when worker.cleanup is called in the worker goroutine while a
-// workerClient.fuzz call runs concurrently.
-//
-// This error should not be reported. It indicates the operation was
-// interrupted.
-var errSharedMemClosed = errors.New("internal error: shared memory was closed and unmapped")
-
-// minimize tells the worker to call the minimize method. See
-// workerServer.minimize.
-func (wc *workerClient) minimize(ctx context.Context, entryIn CorpusEntry, args minimizeArgs) (entryOut CorpusEntry, resp minimizeResponse, retErr error) {
- wc.mu.Lock()
- defer wc.mu.Unlock()
-
- mem, ok := <-wc.memMu
- if !ok {
- return CorpusEntry{}, minimizeResponse{}, errSharedMemClosed
- }
- mem.header().count = 0
- inp, err := corpusEntryData(entryIn)
- if err != nil {
- return CorpusEntry{}, minimizeResponse{}, err
- }
- mem.setValue(inp)
- defer func() { wc.memMu <- mem }()
- entryOut = entryIn
- entryOut.Values, err = unmarshalCorpusFile(inp)
- if err != nil {
- return CorpusEntry{}, minimizeResponse{}, fmt.Errorf("workerClient.minimize unmarshaling provided value: %v", err)
- }
- for i, v := range entryOut.Values {
- if !isMinimizable(reflect.TypeOf(v)) {
- continue
- }
-
- wc.memMu <- mem
- args.Index = i
- c := call{Minimize: &args}
- callErr := wc.callLocked(ctx, c, &resp)
- mem, ok = <-wc.memMu
- if !ok {
- return CorpusEntry{}, minimizeResponse{}, errSharedMemClosed
- }
-
- if callErr != nil {
- retErr = callErr
- if !mem.header().rawInMem {
- // An unrecoverable error occurred before minimization began.
- return entryIn, minimizeResponse{}, retErr
- }
- // An unrecoverable error occurred during minimization. mem now
- // holds the raw, unmarshalled bytes of entryIn.Values[i] that
- // caused the error.
- switch entryOut.Values[i].(type) {
- case string:
- entryOut.Values[i] = string(mem.valueCopy())
- case []byte:
- entryOut.Values[i] = mem.valueCopy()
- default:
- panic("impossible")
- }
- entryOut.Data = marshalCorpusFile(entryOut.Values...)
- // Stop minimizing; another unrecoverable error is likely to occur.
- break
- }
-
- if resp.WroteToMem {
- // Minimization succeeded, and mem holds the marshaled data.
- entryOut.Data = mem.valueCopy()
- entryOut.Values, err = unmarshalCorpusFile(entryOut.Data)
- if err != nil {
- return CorpusEntry{}, minimizeResponse{}, fmt.Errorf("workerClient.minimize unmarshaling minimized value: %v", err)
- }
- }
-
- // Prepare for next iteration of the loop.
- if args.Timeout != 0 {
- args.Timeout -= resp.Duration
- if args.Timeout <= 0 {
- break
- }
- }
- if args.Limit != 0 {
- args.Limit -= mem.header().count
- if args.Limit <= 0 {
- break
- }
- }
- }
- resp.Count = mem.header().count
- h := sha256.Sum256(entryOut.Data)
- entryOut.Path = fmt.Sprintf("%x", h[:4])
- return entryOut, resp, retErr
-}
-
-// fuzz tells the worker to call the fuzz method. See workerServer.fuzz.
-func (wc *workerClient) fuzz(ctx context.Context, entryIn CorpusEntry, args fuzzArgs) (entryOut CorpusEntry, resp fuzzResponse, isInternalError bool, err error) {
- wc.mu.Lock()
- defer wc.mu.Unlock()
-
- mem, ok := <-wc.memMu
- if !ok {
- return CorpusEntry{}, fuzzResponse{}, true, errSharedMemClosed
- }
- mem.header().count = 0
- inp, err := corpusEntryData(entryIn)
- if err != nil {
- return CorpusEntry{}, fuzzResponse{}, true, err
- }
- mem.setValue(inp)
- wc.memMu <- mem
-
- c := call{Fuzz: &args}
- callErr := wc.callLocked(ctx, c, &resp)
- if resp.InternalErr != "" {
- return CorpusEntry{}, fuzzResponse{}, true, errors.New(resp.InternalErr)
- }
- mem, ok = <-wc.memMu
- if !ok {
- return CorpusEntry{}, fuzzResponse{}, true, errSharedMemClosed
- }
- defer func() { wc.memMu <- mem }()
- resp.Count = mem.header().count
-
- if !bytes.Equal(inp, mem.valueRef()) {
- return CorpusEntry{}, fuzzResponse{}, true, errors.New("workerServer.fuzz modified input")
- }
- needEntryOut := callErr != nil || resp.Err != "" ||
- (!args.Warmup && resp.CoverageData != nil)
- if needEntryOut {
- valuesOut, err := unmarshalCorpusFile(inp)
- if err != nil {
- return CorpusEntry{}, fuzzResponse{}, true, fmt.Errorf("unmarshaling fuzz input value after call: %v", err)
- }
- wc.m.r.restore(mem.header().randState, mem.header().randInc)
- if !args.Warmup {
- // Only mutate the valuesOut if fuzzing actually occurred.
- numMutations := ((resp.Count - 1) % chainedMutations) + 1
- for i := int64(0); i < numMutations; i++ {
- wc.m.mutate(valuesOut, cap(mem.valueRef()))
- }
- }
- dataOut := marshalCorpusFile(valuesOut...)
-
- h := sha256.Sum256(dataOut)
- name := fmt.Sprintf("%x", h[:4])
- entryOut = CorpusEntry{
- Parent: entryIn.Path,
- Path: name,
- Data: dataOut,
- Generation: entryIn.Generation + 1,
- }
- if args.Warmup {
- // The bytes weren't mutated, so if entryIn was a seed corpus value,
- // then entryOut is too.
- entryOut.IsSeed = entryIn.IsSeed
- }
- }
-
- return entryOut, resp, false, callErr
-}
-
-// ping tells the worker to call the ping method. See workerServer.ping.
-func (wc *workerClient) ping(ctx context.Context) error {
- wc.mu.Lock()
- defer wc.mu.Unlock()
- c := call{Ping: &pingArgs{}}
- var resp pingResponse
- return wc.callLocked(ctx, c, &resp)
-}
-
-// callLocked sends an RPC from the coordinator to the worker process and waits
-// for the response. The callLocked may be cancelled with ctx.
-func (wc *workerClient) callLocked(ctx context.Context, c call, resp any) (err error) {
- enc := json.NewEncoder(wc.fuzzIn)
- dec := json.NewDecoder(&contextReader{ctx: ctx, r: wc.fuzzOut})
- if err := enc.Encode(c); err != nil {
- return err
- }
- return dec.Decode(resp)
-}
-
-// contextReader wraps a Reader with a Context. If the context is cancelled
-// while the underlying reader is blocked, Read returns immediately.
-//
-// This is useful for reading from a pipe. Closing a pipe file descriptor does
-// not unblock pending Reads on that file descriptor. All copies of the pipe's
-// other file descriptor (the write end) must be closed in all processes that
-// inherit it. This is difficult to do correctly in the situation we care about
-// (process group termination).
-type contextReader struct {
- ctx context.Context
- r io.Reader
-}
-
-func (cr *contextReader) Read(b []byte) (int, error) {
- if ctxErr := cr.ctx.Err(); ctxErr != nil {
- return 0, ctxErr
- }
- done := make(chan struct{})
-
- // This goroutine may stay blocked after Read returns because the underlying
- // read is blocked.
- var n int
- var err error
- go func() {
- n, err = cr.r.Read(b)
- close(done)
- }()
-
- select {
- case <-cr.ctx.Done():
- return 0, cr.ctx.Err()
- case <-done:
- return n, err
- }
-}
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/ya.make b/contrib/go/_std_1.20/src/internal/fuzz/ya.make
deleted file mode 100644
index 6643d232bb..0000000000
--- a/contrib/go/_std_1.20/src/internal/fuzz/ya.make
+++ /dev/null
@@ -1,36 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- counters_supported.go
- coverage.go
- encoding.go
- fuzz.go
- mem.go
- minimize.go
- mutator.go
- mutators_byteslice.go
- pcg.go
- queue.go
- trace.go
- worker.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- sys_posix.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- sys_posix.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- sys_windows.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/goarch/ya.make b/contrib/go/_std_1.20/src/internal/goarch/ya.make
deleted file mode 100644
index 8483e0734e..0000000000
--- a/contrib/go/_std_1.20/src/internal/goarch/ya.make
+++ /dev/null
@@ -1,21 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- goarch.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- goarch_arm64.go
- zgoarch_arm64.go
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- goarch_amd64.go
- zgoarch_amd64.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/godebug/godebug.go b/contrib/go/_std_1.20/src/internal/godebug/godebug.go
deleted file mode 100644
index 26f360c73c..0000000000
--- a/contrib/go/_std_1.20/src/internal/godebug/godebug.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// 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 godebug makes the settings in the $GODEBUG environment variable
-// available to other packages. These settings are often used for compatibility
-// tweaks, when we need to change a default behavior but want to let users
-// opt back in to the original. For example GODEBUG=http2server=0 disables
-// HTTP/2 support in the net/http server.
-//
-// In typical usage, code should declare a Setting as a global
-// and then call Value each time the current setting value is needed:
-//
-// var http2server = godebug.New("http2server")
-//
-// func ServeConn(c net.Conn) {
-// if http2server.Value() == "0" {
-// disallow HTTP/2
-// ...
-// }
-// ...
-// }
-package godebug
-
-import (
- "sync"
- "sync/atomic"
- _ "unsafe" // go:linkname
-
-)
-
-// A Setting is a single setting in the $GODEBUG environment variable.
-type Setting struct {
- name string
- once sync.Once
- value *atomic.Pointer[string]
-}
-
-// New returns a new Setting for the $GODEBUG setting with the given name.
-func New(name string) *Setting {
- return &Setting{name: name}
-}
-
-// Name returns the name of the setting.
-func (s *Setting) Name() string {
- return s.name
-}
-
-// String returns a printable form for the setting: name=value.
-func (s *Setting) String() string {
- return s.name + "=" + s.Value()
-}
-
-// cache is a cache of all the GODEBUG settings,
-// a locked map[string]*atomic.Pointer[string].
-//
-// All Settings with the same name share a single
-// *atomic.Pointer[string], so that when GODEBUG
-// changes only that single atomic string pointer
-// needs to be updated.
-//
-// A name appears in the values map either if it is the
-// name of a Setting for which Value has been called
-// at least once, or if the name has ever appeared in
-// a name=value pair in the $GODEBUG environment variable.
-// Once entered into the map, the name is never removed.
-var cache sync.Map // name string -> value *atomic.Pointer[string]
-
-var empty string
-
-// Value returns the current value for the GODEBUG setting s.
-//
-// Value maintains an internal cache that is synchronized
-// with changes to the $GODEBUG environment variable,
-// making Value efficient to call as frequently as needed.
-// Clients should therefore typically not attempt their own
-// caching of Value's result.
-func (s *Setting) Value() string {
- s.once.Do(func() {
- v, ok := cache.Load(s.name)
- if !ok {
- p := new(atomic.Pointer[string])
- p.Store(&empty)
- v, _ = cache.LoadOrStore(s.name, p)
- }
- s.value = v.(*atomic.Pointer[string])
- })
- return *s.value.Load()
-}
-
-// setUpdate is provided by package runtime.
-// It calls update(def, env), where def is the default GODEBUG setting
-// and env is the current value of the $GODEBUG environment variable.
-// After that first call, the runtime calls update(def, env)
-// again each time the environment variable changes
-// (due to use of os.Setenv, for example).
-//
-//go:linkname setUpdate
-func setUpdate(update func(string, string))
-
-func init() {
- setUpdate(update)
-}
-
-var updateMu sync.Mutex
-
-// update records an updated GODEBUG setting.
-// def is the default GODEBUG setting for the running binary,
-// and env is the current value of the $GODEBUG environment variable.
-func update(def, env string) {
- updateMu.Lock()
- defer updateMu.Unlock()
-
- // Update all the cached values, creating new ones as needed.
- // We parse the environment variable first, so that any settings it has
- // are already locked in place (did[name] = true) before we consider
- // the defaults.
- did := make(map[string]bool)
- parse(did, env)
- parse(did, def)
-
- // Clear any cached values that are no longer present.
- cache.Range(func(name, v any) bool {
- if !did[name.(string)] {
- v.(*atomic.Pointer[string]).Store(&empty)
- }
- return true
- })
-}
-
-// parse parses the GODEBUG setting string s,
-// which has the form k=v,k2=v2,k3=v3.
-// Later settings override earlier ones.
-// Parse only updates settings k=v for which did[k] = false.
-// It also sets did[k] = true for settings that it updates.
-func parse(did map[string]bool, s string) {
- // Scan the string backward so that later settings are used
- // and earlier settings are ignored.
- // Note that a forward scan would cause cached values
- // to temporarily use the ignored value before being
- // updated to the "correct" one.
- end := len(s)
- eq := -1
- for i := end - 1; i >= -1; i-- {
- if i == -1 || s[i] == ',' {
- if eq >= 0 {
- name, value := s[i+1:eq], s[eq+1:end]
- if !did[name] {
- did[name] = true
- v, ok := cache.Load(name)
- if !ok {
- p := new(atomic.Pointer[string])
- p.Store(&empty)
- v, _ = cache.LoadOrStore(name, p)
- }
- v.(*atomic.Pointer[string]).Store(&value)
- }
- }
- eq = -1
- end = i
- } else if s[i] == '=' {
- eq = i
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/internal/godebug/ya.make b/contrib/go/_std_1.20/src/internal/godebug/ya.make
deleted file mode 100644
index aeb5fa5afc..0000000000
--- a/contrib/go/_std_1.20/src/internal/godebug/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- godebug.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/exp_coverageredesign_off.go b/contrib/go/_std_1.20/src/internal/goexperiment/exp_coverageredesign_off.go
deleted file mode 100644
index 95d3a6c4ae..0000000000
--- a/contrib/go/_std_1.20/src/internal/goexperiment/exp_coverageredesign_off.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Code generated by mkconsts.go. DO NOT EDIT.
-
-//go:build !goexperiment.coverageredesign
-// +build !goexperiment.coverageredesign
-
-package goexperiment
-
-const CoverageRedesign = false
-const CoverageRedesignInt = 0
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/exp_unified_off.go b/contrib/go/_std_1.20/src/internal/goexperiment/exp_unified_off.go
deleted file mode 100644
index 4c16fd8562..0000000000
--- a/contrib/go/_std_1.20/src/internal/goexperiment/exp_unified_off.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Code generated by mkconsts.go. DO NOT EDIT.
-
-//go:build !goexperiment.unified
-// +build !goexperiment.unified
-
-package goexperiment
-
-const Unified = false
-const UnifiedInt = 0
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/flags.go b/contrib/go/_std_1.20/src/internal/goexperiment/flags.go
deleted file mode 100644
index 02e744362c..0000000000
--- a/contrib/go/_std_1.20/src/internal/goexperiment/flags.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// 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 goexperiment implements support for toolchain experiments.
-//
-// Toolchain experiments are controlled by the GOEXPERIMENT
-// environment variable. GOEXPERIMENT is a comma-separated list of
-// experiment names. GOEXPERIMENT can be set at make.bash time, which
-// sets the default experiments for binaries built with the tool
-// chain; or it can be set at build time. GOEXPERIMENT can also be set
-// to "none", which disables any experiments that were enabled at
-// make.bash time.
-//
-// Experiments are exposed to the build in the following ways:
-//
-// - Build tag goexperiment.x is set if experiment x (lower case) is
-// enabled.
-//
-// - For each experiment x (in camel case), this package contains a
-// boolean constant x and an integer constant xInt.
-//
-// - In runtime assembly, the macro GOEXPERIMENT_x is defined if
-// experiment x (lower case) is enabled.
-//
-// In the toolchain, the set of experiments enabled for the current
-// build should be accessed via objabi.Experiment.
-//
-// The set of experiments is included in the output of runtime.Version()
-// and "go version <binary>" if it differs from the default experiments.
-//
-// For the set of experiments supported by the current toolchain, see
-// "go doc goexperiment.Flags".
-//
-// Note that this package defines the set of experiments (in Flags)
-// and records the experiments that were enabled when the package
-// was compiled (as boolean and integer constants).
-//
-// Note especially that this package does not itself change behavior
-// at run time based on the GOEXPERIMENT variable.
-// The code used in builds to interpret the GOEXPERIMENT variable
-// is in the separate package internal/buildcfg.
-package goexperiment
-
-//go:generate go run mkconsts.go
-
-// Flags is the set of experiments that can be enabled or disabled in
-// the current toolchain.
-//
-// When specified in the GOEXPERIMENT environment variable or as build
-// tags, experiments use the strings.ToLower of their field name.
-//
-// For the baseline experimental configuration, see
-// objabi.experimentBaseline.
-//
-// If you change this struct definition, run "go generate".
-type Flags struct {
- FieldTrack bool
- PreemptibleLoops bool
- StaticLockRanking bool
- BoringCrypto bool
-
- // Unified enables the compiler's unified IR construction
- // experiment.
- Unified bool
-
- // Regabi is split into several sub-experiments that can be
- // enabled individually. Not all combinations work.
- // The "regabi" GOEXPERIMENT is an alias for all "working"
- // subexperiments.
-
- // RegabiWrappers enables ABI wrappers for calling between
- // ABI0 and ABIInternal functions. Without this, the ABIs are
- // assumed to be identical so cross-ABI calls are direct.
- RegabiWrappers bool
- // RegabiArgs enables register arguments/results in all
- // compiled Go functions.
- //
- // Requires wrappers (to do ABI translation), and reflect (so
- // reflection calls use registers).
- RegabiArgs bool
-
- // HeapMinimum512KiB reduces the minimum heap size to 512 KiB.
- //
- // This was originally reduced as part of PacerRedesign, but
- // has been broken out to its own experiment that is disabled
- // by default.
- HeapMinimum512KiB bool
-
- // CoverageRedesign enables the new compiler-based code coverage
- // tooling.
- CoverageRedesign bool
-
- // Arenas causes the "arena" standard library package to be visible
- // to the outside world.
- Arenas bool
-
- // PageTrace enables GODEBUG=pagetrace=/path/to/result. This feature
- // is a GOEXPERIMENT due to a security risk with setuid binaries:
- // this compels the Go runtime to write to some arbitrary file, which
- // may be exploited.
- PageTrace bool
-}
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/ya.make b/contrib/go/_std_1.20/src/internal/goexperiment/ya.make
deleted file mode 100644
index 32c0113b21..0000000000
--- a/contrib/go/_std_1.20/src/internal/goexperiment/ya.make
+++ /dev/null
@@ -1,18 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- exp_arenas_off.go
- exp_boringcrypto_off.go
- exp_coverageredesign_off.go
- exp_fieldtrack_off.go
- exp_heapminimum512kib_off.go
- exp_pagetrace_off.go
- exp_preemptibleloops_off.go
- exp_regabiargs_on.go
- exp_regabiwrappers_on.go
- exp_staticlockranking_off.go
- exp_unified_off.go
- flags.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/goos/ya.make b/contrib/go/_std_1.20/src/internal/goos/ya.make
deleted file mode 100644
index 904eeb29f1..0000000000
--- a/contrib/go/_std_1.20/src/internal/goos/ya.make
+++ /dev/null
@@ -1,28 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- goos.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- unix.go
- zgoos_darwin.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- unix.go
- zgoos_linux.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- nonunix.go
- zgoos_windows.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/goos/zgoos_darwin.go b/contrib/go/_std_1.20/src/internal/goos/zgoos_darwin.go
deleted file mode 100644
index decdd49642..0000000000
--- a/contrib/go/_std_1.20/src/internal/goos/zgoos_darwin.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
-
-//go:build !ios && darwin
-
-package goos
-
-const GOOS = `darwin`
-
-const IsAix = 0
-const IsAndroid = 0
-const IsDarwin = 1
-const IsDragonfly = 0
-const IsFreebsd = 0
-const IsHurd = 0
-const IsIllumos = 0
-const IsIos = 0
-const IsJs = 0
-const IsLinux = 0
-const IsNacl = 0
-const IsNetbsd = 0
-const IsOpenbsd = 0
-const IsPlan9 = 0
-const IsSolaris = 0
-const IsWindows = 0
-const IsZos = 0
diff --git a/contrib/go/_std_1.20/src/internal/goos/zgoos_linux.go b/contrib/go/_std_1.20/src/internal/goos/zgoos_linux.go
deleted file mode 100644
index cb9d6e8afa..0000000000
--- a/contrib/go/_std_1.20/src/internal/goos/zgoos_linux.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
-
-//go:build !android && linux
-
-package goos
-
-const GOOS = `linux`
-
-const IsAix = 0
-const IsAndroid = 0
-const IsDarwin = 0
-const IsDragonfly = 0
-const IsFreebsd = 0
-const IsHurd = 0
-const IsIllumos = 0
-const IsIos = 0
-const IsJs = 0
-const IsLinux = 1
-const IsNacl = 0
-const IsNetbsd = 0
-const IsOpenbsd = 0
-const IsPlan9 = 0
-const IsSolaris = 0
-const IsWindows = 0
-const IsZos = 0
diff --git a/contrib/go/_std_1.20/src/internal/goos/zgoos_windows.go b/contrib/go/_std_1.20/src/internal/goos/zgoos_windows.go
deleted file mode 100644
index 16158be78b..0000000000
--- a/contrib/go/_std_1.20/src/internal/goos/zgoos_windows.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
-
-//go:build windows
-
-package goos
-
-const GOOS = `windows`
-
-const IsAix = 0
-const IsAndroid = 0
-const IsDarwin = 0
-const IsDragonfly = 0
-const IsFreebsd = 0
-const IsHurd = 0
-const IsIllumos = 0
-const IsIos = 0
-const IsJs = 0
-const IsLinux = 0
-const IsNacl = 0
-const IsNetbsd = 0
-const IsOpenbsd = 0
-const IsPlan9 = 0
-const IsSolaris = 0
-const IsWindows = 1
-const IsZos = 0
diff --git a/contrib/go/_std_1.20/src/internal/goroot/gc.go b/contrib/go/_std_1.20/src/internal/goroot/gc.go
deleted file mode 100644
index 79403d29fc..0000000000
--- a/contrib/go/_std_1.20/src/internal/goroot/gc.go
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2018 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.
-
-//go:build gc
-
-package goroot
-
-import (
- "os"
- "os/exec"
- "path/filepath"
- "strings"
- "sync"
-)
-
-// IsStandardPackage reports whether path is a standard package,
-// given goroot and compiler.
-func IsStandardPackage(goroot, compiler, path string) bool {
- switch compiler {
- case "gc":
- dir := filepath.Join(goroot, "src", path)
- _, err := os.Stat(dir)
- return err == nil
- case "gccgo":
- return gccgoSearch.isStandard(path)
- default:
- panic("unknown compiler " + compiler)
- }
-}
-
-// gccgoSearch holds the gccgo search directories.
-type gccgoDirs struct {
- once sync.Once
- dirs []string
-}
-
-// gccgoSearch is used to check whether a gccgo package exists in the
-// standard library.
-var gccgoSearch gccgoDirs
-
-// init finds the gccgo search directories. If this fails it leaves dirs == nil.
-func (gd *gccgoDirs) init() {
- gccgo := os.Getenv("GCCGO")
- if gccgo == "" {
- gccgo = "gccgo"
- }
- bin, err := exec.LookPath(gccgo)
- if err != nil {
- return
- }
-
- allDirs, err := exec.Command(bin, "-print-search-dirs").Output()
- if err != nil {
- return
- }
- versionB, err := exec.Command(bin, "-dumpversion").Output()
- if err != nil {
- return
- }
- version := strings.TrimSpace(string(versionB))
- machineB, err := exec.Command(bin, "-dumpmachine").Output()
- if err != nil {
- return
- }
- machine := strings.TrimSpace(string(machineB))
-
- dirsEntries := strings.Split(string(allDirs), "\n")
- const prefix = "libraries: ="
- var dirs []string
- for _, dirEntry := range dirsEntries {
- if strings.HasPrefix(dirEntry, prefix) {
- dirs = filepath.SplitList(strings.TrimPrefix(dirEntry, prefix))
- break
- }
- }
- if len(dirs) == 0 {
- return
- }
-
- var lastDirs []string
- for _, dir := range dirs {
- goDir := filepath.Join(dir, "go", version)
- if fi, err := os.Stat(goDir); err == nil && fi.IsDir() {
- gd.dirs = append(gd.dirs, goDir)
- goDir = filepath.Join(goDir, machine)
- if fi, err = os.Stat(goDir); err == nil && fi.IsDir() {
- gd.dirs = append(gd.dirs, goDir)
- }
- }
- if fi, err := os.Stat(dir); err == nil && fi.IsDir() {
- lastDirs = append(lastDirs, dir)
- }
- }
- gd.dirs = append(gd.dirs, lastDirs...)
-}
-
-// isStandard reports whether path is a standard library for gccgo.
-func (gd *gccgoDirs) isStandard(path string) bool {
- // Quick check: if the first path component has a '.', it's not
- // in the standard library. This skips most GOPATH directories.
- i := strings.Index(path, "/")
- if i < 0 {
- i = len(path)
- }
- if strings.Contains(path[:i], ".") {
- return false
- }
-
- if path == "unsafe" {
- // Special case.
- return true
- }
-
- gd.once.Do(gd.init)
- if gd.dirs == nil {
- // We couldn't find the gccgo search directories.
- // Best guess, since the first component did not contain
- // '.', is that this is a standard library package.
- return true
- }
-
- for _, dir := range gd.dirs {
- full := filepath.Join(dir, path) + ".gox"
- if fi, err := os.Stat(full); err == nil && !fi.IsDir() {
- return true
- }
- }
-
- return false
-}
diff --git a/contrib/go/_std_1.20/src/internal/goroot/importcfg.go b/contrib/go/_std_1.20/src/internal/goroot/importcfg.go
deleted file mode 100644
index e324073746..0000000000
--- a/contrib/go/_std_1.20/src/internal/goroot/importcfg.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2022 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 goroot
-
-import (
- "bytes"
- "fmt"
- "os/exec"
- "strings"
- "sync"
-)
-
-// Importcfg returns an importcfg file to be passed to the
-// Go compiler that contains the cached paths for the .a files for the
-// standard library.
-func Importcfg() (string, error) {
- var icfg bytes.Buffer
-
- m, err := PkgfileMap()
- if err != nil {
- return "", err
- }
- fmt.Fprintf(&icfg, "# import config")
- for importPath, export := range m {
- fmt.Fprintf(&icfg, "\npackagefile %s=%s", importPath, export)
- }
- s := icfg.String()
- return s, nil
-}
-
-var (
- stdlibPkgfileMap map[string]string
- stdlibPkgfileErr error
- once sync.Once
-)
-
-// PkgfileMap returns a map of package paths to the location on disk
-// of the .a file for the package.
-// The caller must not modify the map.
-func PkgfileMap() (map[string]string, error) {
- once.Do(func() {
- m := make(map[string]string)
- output, err := exec.Command("go", "list", "-export", "-e", "-f", "{{.ImportPath}} {{.Export}}", "std", "cmd").Output()
- if err != nil {
- stdlibPkgfileErr = err
- }
- for _, line := range strings.Split(string(output), "\n") {
- if line == "" {
- continue
- }
- sp := strings.SplitN(line, " ", 2)
- if len(sp) != 2 {
- stdlibPkgfileErr = fmt.Errorf("determining pkgfile map: invalid line in go list output: %q", line)
- return
- }
- importPath, export := sp[0], sp[1]
- if export != "" {
- m[importPath] = export
- }
- }
- stdlibPkgfileMap = m
- })
- return stdlibPkgfileMap, stdlibPkgfileErr
-}
diff --git a/contrib/go/_std_1.20/src/internal/goroot/ya.make b/contrib/go/_std_1.20/src/internal/goroot/ya.make
deleted file mode 100644
index 6dd7a3c141..0000000000
--- a/contrib/go/_std_1.20/src/internal/goroot/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- gc.go
- importcfg.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/goversion/goversion.go b/contrib/go/_std_1.20/src/internal/goversion/goversion.go
deleted file mode 100644
index e9ecf8e643..0000000000
--- a/contrib/go/_std_1.20/src/internal/goversion/goversion.go
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package goversion
-
-// Version is the Go 1.x version which is currently
-// in development and will eventually get released.
-//
-// It should be updated at the start of each development cycle to be
-// the version of the next Go 1.x release. See golang.org/issue/40705.
-const Version = 20
diff --git a/contrib/go/_std_1.20/src/internal/intern/intern.go b/contrib/go/_std_1.20/src/internal/intern/intern.go
deleted file mode 100644
index 0e6852f729..0000000000
--- a/contrib/go/_std_1.20/src/internal/intern/intern.go
+++ /dev/null
@@ -1,181 +0,0 @@
-// 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 intern lets you make smaller comparable values by boxing
-// a larger comparable value (such as a 16 byte string header) down
-// into a globally unique 8 byte pointer.
-//
-// The globally unique pointers are garbage collected with weak
-// references and finalizers. This package hides that.
-package intern
-
-import (
- "internal/godebug"
- "runtime"
- "sync"
- "unsafe"
-)
-
-// A Value pointer is the handle to an underlying comparable value.
-// See func Get for how Value pointers may be used.
-type Value struct {
- _ [0]func() // prevent people from accidentally using value type as comparable
- cmpVal any
- // resurrected is guarded by mu (for all instances of Value).
- // It is set true whenever v is synthesized from a uintptr.
- resurrected bool
-}
-
-// Get returns the comparable value passed to the Get func
-// that returned v.
-func (v *Value) Get() any { return v.cmpVal }
-
-// key is a key in our global value map.
-// It contains type-specialized fields to avoid allocations
-// when converting common types to empty interfaces.
-type key struct {
- s string
- cmpVal any
- // isString reports whether key contains a string.
- // Without it, the zero value of key is ambiguous.
- isString bool
-}
-
-// keyFor returns a key to use with cmpVal.
-func keyFor(cmpVal any) key {
- if s, ok := cmpVal.(string); ok {
- return key{s: s, isString: true}
- }
- return key{cmpVal: cmpVal}
-}
-
-// Value returns a *Value built from k.
-func (k key) Value() *Value {
- if k.isString {
- return &Value{cmpVal: k.s}
- }
- return &Value{cmpVal: k.cmpVal}
-}
-
-var (
- // mu guards valMap, a weakref map of *Value by underlying value.
- // It also guards the resurrected field of all *Values.
- mu sync.Mutex
- valMap = map[key]uintptr{} // to uintptr(*Value)
- valSafe = safeMap() // non-nil in safe+leaky mode
-)
-
-var intern = godebug.New("intern")
-
-// safeMap returns a non-nil map if we're in safe-but-leaky mode,
-// as controlled by GODEBUG=intern=leaky
-func safeMap() map[key]*Value {
- if intern.Value() == "leaky" {
- return map[key]*Value{}
- }
- return nil
-}
-
-// Get returns a pointer representing the comparable value cmpVal.
-//
-// The returned pointer will be the same for Get(v) and Get(v2)
-// if and only if v == v2, and can be used as a map key.
-func Get(cmpVal any) *Value {
- return get(keyFor(cmpVal))
-}
-
-// GetByString is identical to Get, except that it is specialized for strings.
-// This avoids an allocation from putting a string into an interface{}
-// to pass as an argument to Get.
-func GetByString(s string) *Value {
- return get(key{s: s, isString: true})
-}
-
-// We play unsafe games that violate Go's rules (and assume a non-moving
-// collector). So we quiet Go here.
-// See the comment below Get for more implementation details.
-//
-//go:nocheckptr
-func get(k key) *Value {
- mu.Lock()
- defer mu.Unlock()
-
- var v *Value
- if valSafe != nil {
- v = valSafe[k]
- } else if addr, ok := valMap[k]; ok {
- v = (*Value)(unsafe.Pointer(addr))
- v.resurrected = true
- }
- if v != nil {
- return v
- }
- v = k.Value()
- if valSafe != nil {
- valSafe[k] = v
- } else {
- // SetFinalizer before uintptr conversion (theoretical concern;
- // see https://github.com/go4org/intern/issues/13)
- runtime.SetFinalizer(v, finalize)
- valMap[k] = uintptr(unsafe.Pointer(v))
- }
- return v
-}
-
-func finalize(v *Value) {
- mu.Lock()
- defer mu.Unlock()
- if v.resurrected {
- // We lost the race. Somebody resurrected it while we
- // were about to finalize it. Try again next round.
- v.resurrected = false
- runtime.SetFinalizer(v, finalize)
- return
- }
- delete(valMap, keyFor(v.cmpVal))
-}
-
-// Interning is simple if you don't require that unused values be
-// garbage collectable. But we do require that; we don't want to be
-// DOS vector. We do this by using a uintptr to hide the pointer from
-// the garbage collector, and using a finalizer to eliminate the
-// pointer when no other code is using it.
-//
-// The obvious implementation of this is to use a
-// map[interface{}]uintptr-of-*interface{}, and set up a finalizer to
-// delete from the map. Unfortunately, this is racy. Because pointers
-// are being created in violation of Go's unsafety rules, it's
-// possible to create a pointer to a value concurrently with the GC
-// concluding that the value can be collected. There are other races
-// that break the equality invariant as well, but the use-after-free
-// will cause a runtime crash.
-//
-// To make this work, the finalizer needs to know that no references
-// have been unsafely created since the finalizer was set up. To do
-// this, values carry a "resurrected" sentinel, which gets set
-// whenever a pointer is unsafely created. If the finalizer encounters
-// the sentinel, it clears the sentinel and delays collection for one
-// additional GC cycle, by re-installing itself as finalizer. This
-// ensures that the unsafely created pointer is visible to the GC, and
-// will correctly prevent collection.
-//
-// This technique does mean that interned values that get reused take
-// at least 3 GC cycles to fully collect (1 to clear the sentinel, 1
-// to clean up the unsafe map, 1 to be actually deleted).
-//
-// @ianlancetaylor commented in
-// https://github.com/golang/go/issues/41303#issuecomment-717401656
-// that it is possible to implement weak references in terms of
-// finalizers without unsafe. Unfortunately, the approach he outlined
-// does not work here, for two reasons. First, there is no way to
-// construct a strong pointer out of a weak pointer; our map stores
-// weak pointers, but we must return strong pointers to callers.
-// Second, and more fundamentally, we must return not just _a_ strong
-// pointer to callers, but _the same_ strong pointer to callers. In
-// order to return _the same_ strong pointer to callers, we must track
-// it, which is exactly what we cannot do with strong pointers.
-//
-// See https://github.com/inetaf/netaddr/issues/53 for more
-// discussion, and https://github.com/go4org/intern/issues/2 for an
-// illustration of the subtleties at play.
diff --git a/contrib/go/_std_1.20/src/internal/intern/ya.make b/contrib/go/_std_1.20/src/internal/intern/ya.make
deleted file mode 100644
index 25a446724a..0000000000
--- a/contrib/go/_std_1.20/src/internal/intern/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- intern.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/itoa/ya.make b/contrib/go/_std_1.20/src/internal/itoa/ya.make
deleted file mode 100644
index f49dc1108e..0000000000
--- a/contrib/go/_std_1.20/src/internal/itoa/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- itoa.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/pkgbits/syncmarker_string.go b/contrib/go/_std_1.20/src/internal/pkgbits/syncmarker_string.go
deleted file mode 100644
index 4a5b0ca5f2..0000000000
--- a/contrib/go/_std_1.20/src/internal/pkgbits/syncmarker_string.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT.
-
-package pkgbits
-
-import "strconv"
-
-func _() {
- // An "invalid array index" compiler error signifies that the constant values have changed.
- // Re-run the stringer command to generate them again.
- var x [1]struct{}
- _ = x[SyncEOF-1]
- _ = x[SyncBool-2]
- _ = x[SyncInt64-3]
- _ = x[SyncUint64-4]
- _ = x[SyncString-5]
- _ = x[SyncValue-6]
- _ = x[SyncVal-7]
- _ = x[SyncRelocs-8]
- _ = x[SyncReloc-9]
- _ = x[SyncUseReloc-10]
- _ = x[SyncPublic-11]
- _ = x[SyncPos-12]
- _ = x[SyncPosBase-13]
- _ = x[SyncObject-14]
- _ = x[SyncObject1-15]
- _ = x[SyncPkg-16]
- _ = x[SyncPkgDef-17]
- _ = x[SyncMethod-18]
- _ = x[SyncType-19]
- _ = x[SyncTypeIdx-20]
- _ = x[SyncTypeParamNames-21]
- _ = x[SyncSignature-22]
- _ = x[SyncParams-23]
- _ = x[SyncParam-24]
- _ = x[SyncCodeObj-25]
- _ = x[SyncSym-26]
- _ = x[SyncLocalIdent-27]
- _ = x[SyncSelector-28]
- _ = x[SyncPrivate-29]
- _ = x[SyncFuncExt-30]
- _ = x[SyncVarExt-31]
- _ = x[SyncTypeExt-32]
- _ = x[SyncPragma-33]
- _ = x[SyncExprList-34]
- _ = x[SyncExprs-35]
- _ = x[SyncExpr-36]
- _ = x[SyncExprType-37]
- _ = x[SyncAssign-38]
- _ = x[SyncOp-39]
- _ = x[SyncFuncLit-40]
- _ = x[SyncCompLit-41]
- _ = x[SyncDecl-42]
- _ = x[SyncFuncBody-43]
- _ = x[SyncOpenScope-44]
- _ = x[SyncCloseScope-45]
- _ = x[SyncCloseAnotherScope-46]
- _ = x[SyncDeclNames-47]
- _ = x[SyncDeclName-48]
- _ = x[SyncStmts-49]
- _ = x[SyncBlockStmt-50]
- _ = x[SyncIfStmt-51]
- _ = x[SyncForStmt-52]
- _ = x[SyncSwitchStmt-53]
- _ = x[SyncRangeStmt-54]
- _ = x[SyncCaseClause-55]
- _ = x[SyncCommClause-56]
- _ = x[SyncSelectStmt-57]
- _ = x[SyncDecls-58]
- _ = x[SyncLabeledStmt-59]
- _ = x[SyncUseObjLocal-60]
- _ = x[SyncAddLocal-61]
- _ = x[SyncLinkname-62]
- _ = x[SyncStmt1-63]
- _ = x[SyncStmtsEnd-64]
- _ = x[SyncLabel-65]
- _ = x[SyncOptLabel-66]
-}
-
-const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel"
-
-var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458}
-
-func (i SyncMarker) String() string {
- i -= 1
- if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) {
- return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")"
- }
- return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]]
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/errno_unix.go b/contrib/go/_std_1.20/src/internal/poll/errno_unix.go
deleted file mode 100644
index 8eed93a31c..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/errno_unix.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build unix
-
-package poll
-
-import "syscall"
-
-// Do the interface allocations only once for common
-// Errno values.
-var (
- errEAGAIN error = syscall.EAGAIN
- errEINVAL error = syscall.EINVAL
- errENOENT error = syscall.ENOENT
-)
-
-// errnoErr returns common boxed Errno values, to prevent
-// allocations at runtime.
-func errnoErr(e syscall.Errno) error {
- switch e {
- case 0:
- return nil
- case syscall.EAGAIN:
- return errEAGAIN
- case syscall.EINVAL:
- return errEINVAL
- case syscall.ENOENT:
- return errENOENT
- }
- return e
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/fcntl_libc.go b/contrib/go/_std_1.20/src/internal/poll/fcntl_libc.go
deleted file mode 100644
index 3f0b6d1bad..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/fcntl_libc.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build aix || darwin || (openbsd && !mips64) || solaris
-
-package poll
-
-import _ "unsafe"
-// for go:linkname
-
-// Implemented in the syscall package.
-//
-//go:linkname fcntl syscall.fcntl
-func fcntl(fd int, cmd int, arg int) (int, error)
diff --git a/contrib/go/_std_1.20/src/internal/poll/fcntl_syscall.go b/contrib/go/_std_1.20/src/internal/poll/fcntl_syscall.go
deleted file mode 100644
index bbfc8a8be5..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/fcntl_syscall.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build dragonfly || freebsd || linux || netbsd || (openbsd && mips64)
-
-package poll
-
-import (
- "internal/syscall/unix"
- "syscall"
-)
-
-func fcntl(fd int, cmd int, arg int) (int, error) {
- r, _, e := syscall.Syscall(unix.FcntlSyscall, uintptr(fd), uintptr(cmd), uintptr(arg))
- if e != 0 {
- return int(r), syscall.Errno(e)
- }
- return int(r), nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/fd_fsync_darwin.go b/contrib/go/_std_1.20/src/internal/poll/fd_fsync_darwin.go
deleted file mode 100644
index 48e7596922..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/fd_fsync_darwin.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 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 poll
-
-import "syscall"
-
-// Fsync invokes SYS_FCNTL with SYS_FULLFSYNC because
-// on OS X, SYS_FSYNC doesn't fully flush contents to disk.
-// See Issue #26650 as well as the man page for fsync on OS X.
-func (fd *FD) Fsync() error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return ignoringEINTR(func() error {
- _, err := fcntl(fd.Sysfd, syscall.F_FULLFSYNC, 0)
- return err
- })
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/fd_fsync_posix.go b/contrib/go/_std_1.20/src/internal/poll/fd_fsync_posix.go
deleted file mode 100644
index 6f17019e73..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/fd_fsync_posix.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2018 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.
-
-//go:build aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
-
-package poll
-
-import "syscall"
-
-// Fsync wraps syscall.Fsync.
-func (fd *FD) Fsync() error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return ignoringEINTR(func() error {
- return syscall.Fsync(fd.Sysfd)
- })
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/fd_poll_runtime.go b/contrib/go/_std_1.20/src/internal/poll/fd_poll_runtime.go
deleted file mode 100644
index 6fc627db32..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/fd_poll_runtime.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2013 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.
-
-//go:build unix || windows
-
-package poll
-
-import (
- "errors"
- "sync"
- "syscall"
- "time"
- _ "unsafe" // for go:linkname
-
-)
-
-// runtimeNano returns the current value of the runtime clock in nanoseconds.
-//
-//go:linkname runtimeNano runtime.nanotime
-func runtimeNano() int64
-
-func runtime_pollServerInit()
-func runtime_pollOpen(fd uintptr) (uintptr, int)
-func runtime_pollClose(ctx uintptr)
-func runtime_pollWait(ctx uintptr, mode int) int
-func runtime_pollWaitCanceled(ctx uintptr, mode int)
-func runtime_pollReset(ctx uintptr, mode int) int
-func runtime_pollSetDeadline(ctx uintptr, d int64, mode int)
-func runtime_pollUnblock(ctx uintptr)
-func runtime_isPollServerDescriptor(fd uintptr) bool
-
-type pollDesc struct {
- runtimeCtx uintptr
-}
-
-var serverInit sync.Once
-
-func (pd *pollDesc) init(fd *FD) error {
- serverInit.Do(runtime_pollServerInit)
- ctx, errno := runtime_pollOpen(uintptr(fd.Sysfd))
- if errno != 0 {
- return errnoErr(syscall.Errno(errno))
- }
- pd.runtimeCtx = ctx
- return nil
-}
-
-func (pd *pollDesc) close() {
- if pd.runtimeCtx == 0 {
- return
- }
- runtime_pollClose(pd.runtimeCtx)
- pd.runtimeCtx = 0
-}
-
-// Evict evicts fd from the pending list, unblocking any I/O running on fd.
-func (pd *pollDesc) evict() {
- if pd.runtimeCtx == 0 {
- return
- }
- runtime_pollUnblock(pd.runtimeCtx)
-}
-
-func (pd *pollDesc) prepare(mode int, isFile bool) error {
- if pd.runtimeCtx == 0 {
- return nil
- }
- res := runtime_pollReset(pd.runtimeCtx, mode)
- return convertErr(res, isFile)
-}
-
-func (pd *pollDesc) prepareRead(isFile bool) error {
- return pd.prepare('r', isFile)
-}
-
-func (pd *pollDesc) prepareWrite(isFile bool) error {
- return pd.prepare('w', isFile)
-}
-
-func (pd *pollDesc) wait(mode int, isFile bool) error {
- if pd.runtimeCtx == 0 {
- return errors.New("waiting for unsupported file type")
- }
- res := runtime_pollWait(pd.runtimeCtx, mode)
- return convertErr(res, isFile)
-}
-
-func (pd *pollDesc) waitRead(isFile bool) error {
- return pd.wait('r', isFile)
-}
-
-func (pd *pollDesc) waitWrite(isFile bool) error {
- return pd.wait('w', isFile)
-}
-
-func (pd *pollDesc) waitCanceled(mode int) {
- if pd.runtimeCtx == 0 {
- return
- }
- runtime_pollWaitCanceled(pd.runtimeCtx, mode)
-}
-
-func (pd *pollDesc) pollable() bool {
- return pd.runtimeCtx != 0
-}
-
-// Error values returned by runtime_pollReset and runtime_pollWait.
-// These must match the values in runtime/netpoll.go.
-const (
- pollNoError = 0
- pollErrClosing = 1
- pollErrTimeout = 2
- pollErrNotPollable = 3
-)
-
-func convertErr(res int, isFile bool) error {
- switch res {
- case pollNoError:
- return nil
- case pollErrClosing:
- return errClosing(isFile)
- case pollErrTimeout:
- return ErrDeadlineExceeded
- case pollErrNotPollable:
- return ErrNotPollable
- }
- println("unreachable: ", res)
- panic("unreachable")
-}
-
-// SetDeadline sets the read and write deadlines associated with fd.
-func (fd *FD) SetDeadline(t time.Time) error {
- return setDeadlineImpl(fd, t, 'r'+'w')
-}
-
-// SetReadDeadline sets the read deadline associated with fd.
-func (fd *FD) SetReadDeadline(t time.Time) error {
- return setDeadlineImpl(fd, t, 'r')
-}
-
-// SetWriteDeadline sets the write deadline associated with fd.
-func (fd *FD) SetWriteDeadline(t time.Time) error {
- return setDeadlineImpl(fd, t, 'w')
-}
-
-func setDeadlineImpl(fd *FD, t time.Time, mode int) error {
- var d int64
- if !t.IsZero() {
- d = int64(time.Until(t))
- if d == 0 {
- d = -1 // don't confuse deadline right now with no deadline
- }
- }
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- if fd.pd.runtimeCtx == 0 {
- return ErrNoDeadline
- }
- runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode)
- return nil
-}
-
-// IsPollDescriptor reports whether fd is the descriptor being used by the poller.
-// This is only used for testing.
-func IsPollDescriptor(fd uintptr) bool {
- return runtime_isPollServerDescriptor(fd)
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/fd_posix.go b/contrib/go/_std_1.20/src/internal/poll/fd_posix.go
deleted file mode 100644
index 778fe1e5c1..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/fd_posix.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix || (js && wasm) || windows
-
-package poll
-
-import (
- "io"
- "syscall"
-)
-
-// eofError returns io.EOF when fd is available for reading end of
-// file.
-func (fd *FD) eofError(n int, err error) error {
- if n == 0 && err == nil && fd.ZeroReadIsEOF {
- return io.EOF
- }
- return err
-}
-
-// Shutdown wraps syscall.Shutdown.
-func (fd *FD) Shutdown(how int) error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return syscall.Shutdown(fd.Sysfd, how)
-}
-
-// Fchown wraps syscall.Fchown.
-func (fd *FD) Fchown(uid, gid int) error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return ignoringEINTR(func() error {
- return syscall.Fchown(fd.Sysfd, uid, gid)
- })
-}
-
-// Ftruncate wraps syscall.Ftruncate.
-func (fd *FD) Ftruncate(size int64) error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return ignoringEINTR(func() error {
- return syscall.Ftruncate(fd.Sysfd, size)
- })
-}
-
-// RawControl invokes the user-defined function f for a non-IO
-// operation.
-func (fd *FD) RawControl(f func(uintptr)) error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- f(uintptr(fd.Sysfd))
- return nil
-}
-
-// ignoringEINTR makes a function call and repeats it if it returns
-// an EINTR error. This appears to be required even though we install all
-// signal handlers with SA_RESTART: see #22838, #38033, #38836, #40846.
-// Also #20400 and #36644 are issues in which a signal handler is
-// installed without setting SA_RESTART. None of these are the common case,
-// but there are enough of them that it seems that we can't avoid
-// an EINTR loop.
-func ignoringEINTR(fn func() error) error {
- for {
- err := fn()
- if err != syscall.EINTR {
- return err
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/fd_unix.go b/contrib/go/_std_1.20/src/internal/poll/fd_unix.go
deleted file mode 100644
index 2786064d9f..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/fd_unix.go
+++ /dev/null
@@ -1,799 +0,0 @@
-// Copyright 2017 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.
-
-//go:build unix || (js && wasm)
-
-package poll
-
-import (
- "internal/syscall/unix"
- "io"
- "sync/atomic"
- "syscall"
-)
-
-// FD is a file descriptor. The net and os packages use this type as a
-// field of a larger type representing a network connection or OS file.
-type FD struct {
- // Lock sysfd and serialize access to Read and Write methods.
- fdmu fdMutex
-
- // System file descriptor. Immutable until Close.
- Sysfd int
-
- // I/O poller.
- pd pollDesc
-
- // Writev cache.
- iovecs *[]syscall.Iovec
-
- // Semaphore signaled when file is closed.
- csema uint32
-
- // Non-zero if this file has been set to blocking mode.
- isBlocking uint32
-
- // Whether this is a streaming descriptor, as opposed to a
- // packet-based descriptor like a UDP socket. Immutable.
- IsStream bool
-
- // Whether a zero byte read indicates EOF. This is false for a
- // message based socket connection.
- ZeroReadIsEOF bool
-
- // Whether this is a file rather than a network socket.
- isFile bool
-}
-
-// Init initializes the FD. The Sysfd field should already be set.
-// This can be called multiple times on a single FD.
-// The net argument is a network name from the net package (e.g., "tcp"),
-// or "file".
-// Set pollable to true if fd should be managed by runtime netpoll.
-func (fd *FD) Init(net string, pollable bool) error {
- // We don't actually care about the various network types.
- if net == "file" {
- fd.isFile = true
- }
- if !pollable {
- fd.isBlocking = 1
- return nil
- }
- err := fd.pd.init(fd)
- if err != nil {
- // If we could not initialize the runtime poller,
- // assume we are using blocking mode.
- fd.isBlocking = 1
- }
- return err
-}
-
-// Destroy closes the file descriptor. This is called when there are
-// no remaining references.
-func (fd *FD) destroy() error {
- // Poller may want to unregister fd in readiness notification mechanism,
- // so this must be executed before CloseFunc.
- fd.pd.close()
-
- // We don't use ignoringEINTR here because POSIX does not define
- // whether the descriptor is closed if close returns EINTR.
- // If the descriptor is indeed closed, using a loop would race
- // with some other goroutine opening a new descriptor.
- // (The Linux kernel guarantees that it is closed on an EINTR error.)
- err := CloseFunc(fd.Sysfd)
-
- fd.Sysfd = -1
- runtime_Semrelease(&fd.csema)
- return err
-}
-
-// Close closes the FD. The underlying file descriptor is closed by the
-// destroy method when there are no remaining references.
-func (fd *FD) Close() error {
- if !fd.fdmu.increfAndClose() {
- return errClosing(fd.isFile)
- }
-
- // Unblock any I/O. Once it all unblocks and returns,
- // so that it cannot be referring to fd.sysfd anymore,
- // the final decref will close fd.sysfd. This should happen
- // fairly quickly, since all the I/O is non-blocking, and any
- // attempts to block in the pollDesc will return errClosing(fd.isFile).
- fd.pd.evict()
-
- // The call to decref will call destroy if there are no other
- // references.
- err := fd.decref()
-
- // Wait until the descriptor is closed. If this was the only
- // reference, it is already closed. Only wait if the file has
- // not been set to blocking mode, as otherwise any current I/O
- // may be blocking, and that would block the Close.
- // No need for an atomic read of isBlocking, increfAndClose means
- // we have exclusive access to fd.
- if fd.isBlocking == 0 {
- runtime_Semacquire(&fd.csema)
- }
-
- return err
-}
-
-// SetBlocking puts the file into blocking mode.
-func (fd *FD) SetBlocking() error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- // Atomic store so that concurrent calls to SetBlocking
- // do not cause a race condition. isBlocking only ever goes
- // from 0 to 1 so there is no real race here.
- atomic.StoreUint32(&fd.isBlocking, 1)
- return syscall.SetNonblock(fd.Sysfd, false)
-}
-
-// Darwin and FreeBSD can't read or write 2GB+ files at a time,
-// even on 64-bit systems.
-// The same is true of socket implementations on many systems.
-// See golang.org/issue/7812 and golang.org/issue/16266.
-// Use 1GB instead of, say, 2GB-1, to keep subsequent reads aligned.
-const maxRW = 1 << 30
-
-// Read implements io.Reader.
-func (fd *FD) Read(p []byte) (int, error) {
- if err := fd.readLock(); err != nil {
- return 0, err
- }
- defer fd.readUnlock()
- if len(p) == 0 {
- // If the caller wanted a zero byte read, return immediately
- // without trying (but after acquiring the readLock).
- // Otherwise syscall.Read returns 0, nil which looks like
- // io.EOF.
- // TODO(bradfitz): make it wait for readability? (Issue 15735)
- return 0, nil
- }
- if err := fd.pd.prepareRead(fd.isFile); err != nil {
- return 0, err
- }
- if fd.IsStream && len(p) > maxRW {
- p = p[:maxRW]
- }
- for {
- n, err := ignoringEINTRIO(syscall.Read, fd.Sysfd, p)
- if err != nil {
- n = 0
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitRead(fd.isFile); err == nil {
- continue
- }
- }
- }
- err = fd.eofError(n, err)
- return n, err
- }
-}
-
-// Pread wraps the pread system call.
-func (fd *FD) Pread(p []byte, off int64) (int, error) {
- // Call incref, not readLock, because since pread specifies the
- // offset it is independent from other reads.
- // Similarly, using the poller doesn't make sense for pread.
- if err := fd.incref(); err != nil {
- return 0, err
- }
- if fd.IsStream && len(p) > maxRW {
- p = p[:maxRW]
- }
- var (
- n int
- err error
- )
- for {
- n, err = syscall.Pread(fd.Sysfd, p, off)
- if err != syscall.EINTR {
- break
- }
- }
- if err != nil {
- n = 0
- }
- fd.decref()
- err = fd.eofError(n, err)
- return n, err
-}
-
-// ReadFrom wraps the recvfrom network call.
-func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) {
- if err := fd.readLock(); err != nil {
- return 0, nil, err
- }
- defer fd.readUnlock()
- if err := fd.pd.prepareRead(fd.isFile); err != nil {
- return 0, nil, err
- }
- for {
- n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0)
- if err != nil {
- if err == syscall.EINTR {
- continue
- }
- n = 0
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitRead(fd.isFile); err == nil {
- continue
- }
- }
- }
- err = fd.eofError(n, err)
- return n, sa, err
- }
-}
-
-// ReadFromInet4 wraps the recvfrom network call for IPv4.
-func (fd *FD) ReadFromInet4(p []byte, from *syscall.SockaddrInet4) (int, error) {
- if err := fd.readLock(); err != nil {
- return 0, err
- }
- defer fd.readUnlock()
- if err := fd.pd.prepareRead(fd.isFile); err != nil {
- return 0, err
- }
- for {
- n, err := unix.RecvfromInet4(fd.Sysfd, p, 0, from)
- if err != nil {
- if err == syscall.EINTR {
- continue
- }
- n = 0
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitRead(fd.isFile); err == nil {
- continue
- }
- }
- }
- err = fd.eofError(n, err)
- return n, err
- }
-}
-
-// ReadFromInet6 wraps the recvfrom network call for IPv6.
-func (fd *FD) ReadFromInet6(p []byte, from *syscall.SockaddrInet6) (int, error) {
- if err := fd.readLock(); err != nil {
- return 0, err
- }
- defer fd.readUnlock()
- if err := fd.pd.prepareRead(fd.isFile); err != nil {
- return 0, err
- }
- for {
- n, err := unix.RecvfromInet6(fd.Sysfd, p, 0, from)
- if err != nil {
- if err == syscall.EINTR {
- continue
- }
- n = 0
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitRead(fd.isFile); err == nil {
- continue
- }
- }
- }
- err = fd.eofError(n, err)
- return n, err
- }
-}
-
-// ReadMsg wraps the recvmsg network call.
-func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) {
- if err := fd.readLock(); err != nil {
- return 0, 0, 0, nil, err
- }
- defer fd.readUnlock()
- if err := fd.pd.prepareRead(fd.isFile); err != nil {
- return 0, 0, 0, nil, err
- }
- for {
- n, oobn, sysflags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, flags)
- if err != nil {
- if err == syscall.EINTR {
- continue
- }
- // TODO(dfc) should n and oobn be set to 0
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitRead(fd.isFile); err == nil {
- continue
- }
- }
- }
- err = fd.eofError(n, err)
- return n, oobn, sysflags, sa, err
- }
-}
-
-// ReadMsgInet4 is ReadMsg, but specialized for syscall.SockaddrInet4.
-func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) {
- if err := fd.readLock(); err != nil {
- return 0, 0, 0, err
- }
- defer fd.readUnlock()
- if err := fd.pd.prepareRead(fd.isFile); err != nil {
- return 0, 0, 0, err
- }
- for {
- n, oobn, sysflags, err := unix.RecvmsgInet4(fd.Sysfd, p, oob, flags, sa4)
- if err != nil {
- if err == syscall.EINTR {
- continue
- }
- // TODO(dfc) should n and oobn be set to 0
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitRead(fd.isFile); err == nil {
- continue
- }
- }
- }
- err = fd.eofError(n, err)
- return n, oobn, sysflags, err
- }
-}
-
-// ReadMsgInet6 is ReadMsg, but specialized for syscall.SockaddrInet6.
-func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) {
- if err := fd.readLock(); err != nil {
- return 0, 0, 0, err
- }
- defer fd.readUnlock()
- if err := fd.pd.prepareRead(fd.isFile); err != nil {
- return 0, 0, 0, err
- }
- for {
- n, oobn, sysflags, err := unix.RecvmsgInet6(fd.Sysfd, p, oob, flags, sa6)
- if err != nil {
- if err == syscall.EINTR {
- continue
- }
- // TODO(dfc) should n and oobn be set to 0
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitRead(fd.isFile); err == nil {
- continue
- }
- }
- }
- err = fd.eofError(n, err)
- return n, oobn, sysflags, err
- }
-}
-
-// Write implements io.Writer.
-func (fd *FD) Write(p []byte) (int, error) {
- if err := fd.writeLock(); err != nil {
- return 0, err
- }
- defer fd.writeUnlock()
- if err := fd.pd.prepareWrite(fd.isFile); err != nil {
- return 0, err
- }
- var nn int
- for {
- max := len(p)
- if fd.IsStream && max-nn > maxRW {
- max = nn + maxRW
- }
- n, err := ignoringEINTRIO(syscall.Write, fd.Sysfd, p[nn:max])
- if n > 0 {
- nn += n
- }
- if nn == len(p) {
- return nn, err
- }
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitWrite(fd.isFile); err == nil {
- continue
- }
- }
- if err != nil {
- return nn, err
- }
- if n == 0 {
- return nn, io.ErrUnexpectedEOF
- }
- }
-}
-
-// Pwrite wraps the pwrite system call.
-func (fd *FD) Pwrite(p []byte, off int64) (int, error) {
- // Call incref, not writeLock, because since pwrite specifies the
- // offset it is independent from other writes.
- // Similarly, using the poller doesn't make sense for pwrite.
- if err := fd.incref(); err != nil {
- return 0, err
- }
- defer fd.decref()
- var nn int
- for {
- max := len(p)
- if fd.IsStream && max-nn > maxRW {
- max = nn + maxRW
- }
- n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn))
- if err == syscall.EINTR {
- continue
- }
- if n > 0 {
- nn += n
- }
- if nn == len(p) {
- return nn, err
- }
- if err != nil {
- return nn, err
- }
- if n == 0 {
- return nn, io.ErrUnexpectedEOF
- }
- }
-}
-
-// WriteToInet4 wraps the sendto network call for IPv4 addresses.
-func (fd *FD) WriteToInet4(p []byte, sa *syscall.SockaddrInet4) (int, error) {
- if err := fd.writeLock(); err != nil {
- return 0, err
- }
- defer fd.writeUnlock()
- if err := fd.pd.prepareWrite(fd.isFile); err != nil {
- return 0, err
- }
- for {
- err := unix.SendtoInet4(fd.Sysfd, p, 0, sa)
- if err == syscall.EINTR {
- continue
- }
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitWrite(fd.isFile); err == nil {
- continue
- }
- }
- if err != nil {
- return 0, err
- }
- return len(p), nil
- }
-}
-
-// WriteToInet6 wraps the sendto network call for IPv6 addresses.
-func (fd *FD) WriteToInet6(p []byte, sa *syscall.SockaddrInet6) (int, error) {
- if err := fd.writeLock(); err != nil {
- return 0, err
- }
- defer fd.writeUnlock()
- if err := fd.pd.prepareWrite(fd.isFile); err != nil {
- return 0, err
- }
- for {
- err := unix.SendtoInet6(fd.Sysfd, p, 0, sa)
- if err == syscall.EINTR {
- continue
- }
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitWrite(fd.isFile); err == nil {
- continue
- }
- }
- if err != nil {
- return 0, err
- }
- return len(p), nil
- }
-}
-
-// WriteTo wraps the sendto network call.
-func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) {
- if err := fd.writeLock(); err != nil {
- return 0, err
- }
- defer fd.writeUnlock()
- if err := fd.pd.prepareWrite(fd.isFile); err != nil {
- return 0, err
- }
- for {
- err := syscall.Sendto(fd.Sysfd, p, 0, sa)
- if err == syscall.EINTR {
- continue
- }
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitWrite(fd.isFile); err == nil {
- continue
- }
- }
- if err != nil {
- return 0, err
- }
- return len(p), nil
- }
-}
-
-// WriteMsg wraps the sendmsg network call.
-func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
- if err := fd.writeLock(); err != nil {
- return 0, 0, err
- }
- defer fd.writeUnlock()
- if err := fd.pd.prepareWrite(fd.isFile); err != nil {
- return 0, 0, err
- }
- for {
- n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0)
- if err == syscall.EINTR {
- continue
- }
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitWrite(fd.isFile); err == nil {
- continue
- }
- }
- if err != nil {
- return n, 0, err
- }
- return n, len(oob), err
- }
-}
-
-// WriteMsgInet4 is WriteMsg specialized for syscall.SockaddrInet4.
-func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (int, int, error) {
- if err := fd.writeLock(); err != nil {
- return 0, 0, err
- }
- defer fd.writeUnlock()
- if err := fd.pd.prepareWrite(fd.isFile); err != nil {
- return 0, 0, err
- }
- for {
- n, err := unix.SendmsgNInet4(fd.Sysfd, p, oob, sa, 0)
- if err == syscall.EINTR {
- continue
- }
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitWrite(fd.isFile); err == nil {
- continue
- }
- }
- if err != nil {
- return n, 0, err
- }
- return n, len(oob), err
- }
-}
-
-// WriteMsgInet6 is WriteMsg specialized for syscall.SockaddrInet6.
-func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (int, int, error) {
- if err := fd.writeLock(); err != nil {
- return 0, 0, err
- }
- defer fd.writeUnlock()
- if err := fd.pd.prepareWrite(fd.isFile); err != nil {
- return 0, 0, err
- }
- for {
- n, err := unix.SendmsgNInet6(fd.Sysfd, p, oob, sa, 0)
- if err == syscall.EINTR {
- continue
- }
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitWrite(fd.isFile); err == nil {
- continue
- }
- }
- if err != nil {
- return n, 0, err
- }
- return n, len(oob), err
- }
-}
-
-// Accept wraps the accept network call.
-func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) {
- if err := fd.readLock(); err != nil {
- return -1, nil, "", err
- }
- defer fd.readUnlock()
-
- if err := fd.pd.prepareRead(fd.isFile); err != nil {
- return -1, nil, "", err
- }
- for {
- s, rsa, errcall, err := accept(fd.Sysfd)
- if err == nil {
- return s, rsa, "", err
- }
- switch err {
- case syscall.EINTR:
- continue
- case syscall.EAGAIN:
- if fd.pd.pollable() {
- if err = fd.pd.waitRead(fd.isFile); err == nil {
- continue
- }
- }
- case syscall.ECONNABORTED:
- // This means that a socket on the listen
- // queue was closed before we Accept()ed it;
- // it's a silly error, so try again.
- continue
- }
- return -1, nil, errcall, err
- }
-}
-
-// Seek wraps syscall.Seek.
-func (fd *FD) Seek(offset int64, whence int) (int64, error) {
- if err := fd.incref(); err != nil {
- return 0, err
- }
- defer fd.decref()
- return syscall.Seek(fd.Sysfd, offset, whence)
-}
-
-// ReadDirent wraps syscall.ReadDirent.
-// We treat this like an ordinary system call rather than a call
-// that tries to fill the buffer.
-func (fd *FD) ReadDirent(buf []byte) (int, error) {
- if err := fd.incref(); err != nil {
- return 0, err
- }
- defer fd.decref()
- for {
- n, err := ignoringEINTRIO(syscall.ReadDirent, fd.Sysfd, buf)
- if err != nil {
- n = 0
- if err == syscall.EAGAIN && fd.pd.pollable() {
- if err = fd.pd.waitRead(fd.isFile); err == nil {
- continue
- }
- }
- }
- // Do not call eofError; caller does not expect to see io.EOF.
- return n, err
- }
-}
-
-// Fchmod wraps syscall.Fchmod.
-func (fd *FD) Fchmod(mode uint32) error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return ignoringEINTR(func() error {
- return syscall.Fchmod(fd.Sysfd, mode)
- })
-}
-
-// Fchdir wraps syscall.Fchdir.
-func (fd *FD) Fchdir() error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return syscall.Fchdir(fd.Sysfd)
-}
-
-// Fstat wraps syscall.Fstat
-func (fd *FD) Fstat(s *syscall.Stat_t) error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return ignoringEINTR(func() error {
- return syscall.Fstat(fd.Sysfd, s)
- })
-}
-
-// tryDupCloexec indicates whether F_DUPFD_CLOEXEC should be used.
-// If the kernel doesn't support it, this is set to 0.
-var tryDupCloexec = int32(1)
-
-// DupCloseOnExec dups fd and marks it close-on-exec.
-func DupCloseOnExec(fd int) (int, string, error) {
- if syscall.F_DUPFD_CLOEXEC != 0 && atomic.LoadInt32(&tryDupCloexec) == 1 {
- r0, e1 := fcntl(fd, syscall.F_DUPFD_CLOEXEC, 0)
- if e1 == nil {
- return r0, "", nil
- }
- switch e1.(syscall.Errno) {
- case syscall.EINVAL, syscall.ENOSYS:
- // Old kernel, or js/wasm (which returns
- // ENOSYS). Fall back to the portable way from
- // now on.
- atomic.StoreInt32(&tryDupCloexec, 0)
- default:
- return -1, "fcntl", e1
- }
- }
- return dupCloseOnExecOld(fd)
-}
-
-// dupCloseOnExecOld is the traditional way to dup an fd and
-// set its O_CLOEXEC bit, using two system calls.
-func dupCloseOnExecOld(fd int) (int, string, error) {
- syscall.ForkLock.RLock()
- defer syscall.ForkLock.RUnlock()
- newfd, err := syscall.Dup(fd)
- if err != nil {
- return -1, "dup", err
- }
- syscall.CloseOnExec(newfd)
- return newfd, "", nil
-}
-
-// Dup duplicates the file descriptor.
-func (fd *FD) Dup() (int, string, error) {
- if err := fd.incref(); err != nil {
- return -1, "", err
- }
- defer fd.decref()
- return DupCloseOnExec(fd.Sysfd)
-}
-
-// On Unix variants only, expose the IO event for the net code.
-
-// WaitWrite waits until data can be read from fd.
-func (fd *FD) WaitWrite() error {
- return fd.pd.waitWrite(fd.isFile)
-}
-
-// WriteOnce is for testing only. It makes a single write call.
-func (fd *FD) WriteOnce(p []byte) (int, error) {
- if err := fd.writeLock(); err != nil {
- return 0, err
- }
- defer fd.writeUnlock()
- return ignoringEINTRIO(syscall.Write, fd.Sysfd, p)
-}
-
-// RawRead invokes the user-defined function f for a read operation.
-func (fd *FD) RawRead(f func(uintptr) bool) error {
- if err := fd.readLock(); err != nil {
- return err
- }
- defer fd.readUnlock()
- if err := fd.pd.prepareRead(fd.isFile); err != nil {
- return err
- }
- for {
- if f(uintptr(fd.Sysfd)) {
- return nil
- }
- if err := fd.pd.waitRead(fd.isFile); err != nil {
- return err
- }
- }
-}
-
-// RawWrite invokes the user-defined function f for a write operation.
-func (fd *FD) RawWrite(f func(uintptr) bool) error {
- if err := fd.writeLock(); err != nil {
- return err
- }
- defer fd.writeUnlock()
- if err := fd.pd.prepareWrite(fd.isFile); err != nil {
- return err
- }
- for {
- if f(uintptr(fd.Sysfd)) {
- return nil
- }
- if err := fd.pd.waitWrite(fd.isFile); err != nil {
- return err
- }
- }
-}
-
-// ignoringEINTRIO is like ignoringEINTR, but just for IO calls.
-func ignoringEINTRIO(fn func(fd int, p []byte) (int, error), fd int, p []byte) (int, error) {
- for {
- n, err := fn(fd, p)
- if err != syscall.EINTR {
- return n, err
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/fd_windows.go b/contrib/go/_std_1.20/src/internal/poll/fd_windows.go
deleted file mode 100644
index 3a4a74f2ae..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/fd_windows.go
+++ /dev/null
@@ -1,1321 +0,0 @@
-// Copyright 2017 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 poll
-
-import (
- "errors"
- "internal/race"
- "internal/syscall/windows"
- "io"
- "sync"
- "syscall"
- "unicode/utf16"
- "unicode/utf8"
- "unsafe"
-)
-
-var (
- initErr error
- ioSync uint64
-)
-
-// This package uses the SetFileCompletionNotificationModes Windows
-// API to skip calling GetQueuedCompletionStatus if an IO operation
-// completes synchronously. There is a known bug where
-// SetFileCompletionNotificationModes crashes on some systems (see
-// https://support.microsoft.com/kb/2568167 for details).
-
-var useSetFileCompletionNotificationModes bool // determines is SetFileCompletionNotificationModes is present and safe to use
-
-// checkSetFileCompletionNotificationModes verifies that
-// SetFileCompletionNotificationModes Windows API is present
-// on the system and is safe to use.
-// See https://support.microsoft.com/kb/2568167 for details.
-func checkSetFileCompletionNotificationModes() {
- err := syscall.LoadSetFileCompletionNotificationModes()
- if err != nil {
- return
- }
- protos := [2]int32{syscall.IPPROTO_TCP, 0}
- var buf [32]syscall.WSAProtocolInfo
- len := uint32(unsafe.Sizeof(buf))
- n, err := syscall.WSAEnumProtocols(&protos[0], &buf[0], &len)
- if err != nil {
- return
- }
- for i := int32(0); i < n; i++ {
- if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 {
- return
- }
- }
- useSetFileCompletionNotificationModes = true
-}
-
-func init() {
- var d syscall.WSAData
- e := syscall.WSAStartup(uint32(0x202), &d)
- if e != nil {
- initErr = e
- }
- checkSetFileCompletionNotificationModes()
-}
-
-// operation contains superset of data necessary to perform all async IO.
-type operation struct {
- // Used by IOCP interface, it must be first field
- // of the struct, as our code rely on it.
- o syscall.Overlapped
-
- // fields used by runtime.netpoll
- runtimeCtx uintptr
- mode int32
- errno int32
- qty uint32
-
- // fields used only by net package
- fd *FD
- buf syscall.WSABuf
- msg windows.WSAMsg
- sa syscall.Sockaddr
- rsa *syscall.RawSockaddrAny
- rsan int32
- handle syscall.Handle
- flags uint32
- bufs []syscall.WSABuf
-}
-
-func (o *operation) InitBuf(buf []byte) {
- o.buf.Len = uint32(len(buf))
- o.buf.Buf = nil
- if len(buf) != 0 {
- o.buf.Buf = &buf[0]
- }
-}
-
-func (o *operation) InitBufs(buf *[][]byte) {
- if o.bufs == nil {
- o.bufs = make([]syscall.WSABuf, 0, len(*buf))
- } else {
- o.bufs = o.bufs[:0]
- }
- for _, b := range *buf {
- if len(b) == 0 {
- o.bufs = append(o.bufs, syscall.WSABuf{})
- continue
- }
- for len(b) > maxRW {
- o.bufs = append(o.bufs, syscall.WSABuf{Len: maxRW, Buf: &b[0]})
- b = b[maxRW:]
- }
- if len(b) > 0 {
- o.bufs = append(o.bufs, syscall.WSABuf{Len: uint32(len(b)), Buf: &b[0]})
- }
- }
-}
-
-// ClearBufs clears all pointers to Buffers parameter captured
-// by InitBufs, so it can be released by garbage collector.
-func (o *operation) ClearBufs() {
- for i := range o.bufs {
- o.bufs[i].Buf = nil
- }
- o.bufs = o.bufs[:0]
-}
-
-func (o *operation) InitMsg(p []byte, oob []byte) {
- o.InitBuf(p)
- o.msg.Buffers = &o.buf
- o.msg.BufferCount = 1
-
- o.msg.Name = nil
- o.msg.Namelen = 0
-
- o.msg.Flags = 0
- o.msg.Control.Len = uint32(len(oob))
- o.msg.Control.Buf = nil
- if len(oob) != 0 {
- o.msg.Control.Buf = &oob[0]
- }
-}
-
-// execIO executes a single IO operation o. It submits and cancels
-// IO in the current thread for systems where Windows CancelIoEx API
-// is available. Alternatively, it passes the request onto
-// runtime netpoll and waits for completion or cancels request.
-func execIO(o *operation, submit func(o *operation) error) (int, error) {
- if o.fd.pd.runtimeCtx == 0 {
- return 0, errors.New("internal error: polling on unsupported descriptor type")
- }
-
- fd := o.fd
- // Notify runtime netpoll about starting IO.
- err := fd.pd.prepare(int(o.mode), fd.isFile)
- if err != nil {
- return 0, err
- }
- // Start IO.
- err = submit(o)
- switch err {
- case nil:
- // IO completed immediately
- if o.fd.skipSyncNotif {
- // No completion message will follow, so return immediately.
- return int(o.qty), nil
- }
- // Need to get our completion message anyway.
- case syscall.ERROR_IO_PENDING:
- // IO started, and we have to wait for its completion.
- err = nil
- default:
- return 0, err
- }
- // Wait for our request to complete.
- err = fd.pd.wait(int(o.mode), fd.isFile)
- if err == nil {
- // All is good. Extract our IO results and return.
- if o.errno != 0 {
- err = syscall.Errno(o.errno)
- // More data available. Return back the size of received data.
- if err == syscall.ERROR_MORE_DATA || err == windows.WSAEMSGSIZE {
- return int(o.qty), err
- }
- return 0, err
- }
- return int(o.qty), nil
- }
- // IO is interrupted by "close" or "timeout"
- netpollErr := err
- switch netpollErr {
- case ErrNetClosing, ErrFileClosing, ErrDeadlineExceeded:
- // will deal with those.
- default:
- panic("unexpected runtime.netpoll error: " + netpollErr.Error())
- }
- // Cancel our request.
- err = syscall.CancelIoEx(fd.Sysfd, &o.o)
- // Assuming ERROR_NOT_FOUND is returned, if IO is completed.
- if err != nil && err != syscall.ERROR_NOT_FOUND {
- // TODO(brainman): maybe do something else, but panic.
- panic(err)
- }
- // Wait for cancellation to complete.
- fd.pd.waitCanceled(int(o.mode))
- if o.errno != 0 {
- err = syscall.Errno(o.errno)
- if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled
- err = netpollErr
- }
- return 0, err
- }
- // We issued a cancellation request. But, it seems, IO operation succeeded
- // before the cancellation request run. We need to treat the IO operation as
- // succeeded (the bytes are actually sent/recv from network).
- return int(o.qty), nil
-}
-
-// FD is a file descriptor. The net and os packages embed this type in
-// a larger type representing a network connection or OS file.
-type FD struct {
- // Lock sysfd and serialize access to Read and Write methods.
- fdmu fdMutex
-
- // System file descriptor. Immutable until Close.
- Sysfd syscall.Handle
-
- // Read operation.
- rop operation
- // Write operation.
- wop operation
-
- // I/O poller.
- pd pollDesc
-
- // Used to implement pread/pwrite.
- l sync.Mutex
-
- // For console I/O.
- lastbits []byte // first few bytes of the last incomplete rune in last write
- readuint16 []uint16 // buffer to hold uint16s obtained with ReadConsole
- readbyte []byte // buffer to hold decoding of readuint16 from utf16 to utf8
- readbyteOffset int // readbyte[readOffset:] is yet to be consumed with file.Read
-
- // Semaphore signaled when file is closed.
- csema uint32
-
- skipSyncNotif bool
-
- // Whether this is a streaming descriptor, as opposed to a
- // packet-based descriptor like a UDP socket.
- IsStream bool
-
- // Whether a zero byte read indicates EOF. This is false for a
- // message based socket connection.
- ZeroReadIsEOF bool
-
- // Whether this is a file rather than a network socket.
- isFile bool
-
- // The kind of this file.
- kind fileKind
-}
-
-// fileKind describes the kind of file.
-type fileKind byte
-
-const (
- kindNet fileKind = iota
- kindFile
- kindConsole
- kindPipe
-)
-
-// logInitFD is set by tests to enable file descriptor initialization logging.
-var logInitFD func(net string, fd *FD, err error)
-
-// Init initializes the FD. The Sysfd field should already be set.
-// This can be called multiple times on a single FD.
-// The net argument is a network name from the net package (e.g., "tcp"),
-// or "file" or "console" or "dir".
-// Set pollable to true if fd should be managed by runtime netpoll.
-func (fd *FD) Init(net string, pollable bool) (string, error) {
- if initErr != nil {
- return "", initErr
- }
-
- switch net {
- case "file", "dir":
- fd.kind = kindFile
- case "console":
- fd.kind = kindConsole
- case "pipe":
- fd.kind = kindPipe
- case "tcp", "tcp4", "tcp6",
- "udp", "udp4", "udp6",
- "ip", "ip4", "ip6",
- "unix", "unixgram", "unixpacket":
- fd.kind = kindNet
- default:
- return "", errors.New("internal error: unknown network type " + net)
- }
- fd.isFile = fd.kind != kindNet
-
- var err error
- if pollable {
- // Only call init for a network socket.
- // This means that we don't add files to the runtime poller.
- // Adding files to the runtime poller can confuse matters
- // if the user is doing their own overlapped I/O.
- // See issue #21172.
- //
- // In general the code below avoids calling the execIO
- // function for non-network sockets. If some method does
- // somehow call execIO, then execIO, and therefore the
- // calling method, will return an error, because
- // fd.pd.runtimeCtx will be 0.
- err = fd.pd.init(fd)
- }
- if logInitFD != nil {
- logInitFD(net, fd, err)
- }
- if err != nil {
- return "", err
- }
- if pollable && useSetFileCompletionNotificationModes {
- // We do not use events, so we can skip them always.
- flags := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE)
- // It's not safe to skip completion notifications for UDP:
- // https://docs.microsoft.com/en-us/archive/blogs/winserverperformance/designing-applications-for-high-performance-part-iii
- if net == "tcp" {
- flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
- }
- err := syscall.SetFileCompletionNotificationModes(fd.Sysfd, flags)
- if err == nil && flags&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 {
- fd.skipSyncNotif = true
- }
- }
- // Disable SIO_UDP_CONNRESET behavior.
- // http://support.microsoft.com/kb/263823
- switch net {
- case "udp", "udp4", "udp6":
- ret := uint32(0)
- flag := uint32(0)
- size := uint32(unsafe.Sizeof(flag))
- err := syscall.WSAIoctl(fd.Sysfd, syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0)
- if err != nil {
- return "wsaioctl", err
- }
- }
- fd.rop.mode = 'r'
- fd.wop.mode = 'w'
- fd.rop.fd = fd
- fd.wop.fd = fd
- fd.rop.runtimeCtx = fd.pd.runtimeCtx
- fd.wop.runtimeCtx = fd.pd.runtimeCtx
- return "", nil
-}
-
-func (fd *FD) destroy() error {
- if fd.Sysfd == syscall.InvalidHandle {
- return syscall.EINVAL
- }
- // Poller may want to unregister fd in readiness notification mechanism,
- // so this must be executed before fd.CloseFunc.
- fd.pd.close()
- var err error
- switch fd.kind {
- case kindNet:
- // The net package uses the CloseFunc variable for testing.
- err = CloseFunc(fd.Sysfd)
- default:
- err = syscall.CloseHandle(fd.Sysfd)
- }
- fd.Sysfd = syscall.InvalidHandle
- runtime_Semrelease(&fd.csema)
- return err
-}
-
-// Close closes the FD. The underlying file descriptor is closed by
-// the destroy method when there are no remaining references.
-func (fd *FD) Close() error {
- if !fd.fdmu.increfAndClose() {
- return errClosing(fd.isFile)
- }
- if fd.kind == kindPipe {
- syscall.CancelIoEx(fd.Sysfd, nil)
- }
- // unblock pending reader and writer
- fd.pd.evict()
- err := fd.decref()
- // Wait until the descriptor is closed. If this was the only
- // reference, it is already closed.
- runtime_Semacquire(&fd.csema)
- return err
-}
-
-// Windows ReadFile and WSARecv use DWORD (uint32) parameter to pass buffer length.
-// This prevents us reading blocks larger than 4GB.
-// See golang.org/issue/26923.
-const maxRW = 1 << 30 // 1GB is large enough and keeps subsequent reads aligned
-
-// Read implements io.Reader.
-func (fd *FD) Read(buf []byte) (int, error) {
- if err := fd.readLock(); err != nil {
- return 0, err
- }
- defer fd.readUnlock()
-
- if len(buf) > maxRW {
- buf = buf[:maxRW]
- }
-
- var n int
- var err error
- if fd.isFile {
- fd.l.Lock()
- defer fd.l.Unlock()
- switch fd.kind {
- case kindConsole:
- n, err = fd.readConsole(buf)
- default:
- n, err = syscall.Read(fd.Sysfd, buf)
- if fd.kind == kindPipe && err == syscall.ERROR_OPERATION_ABORTED {
- // Close uses CancelIoEx to interrupt concurrent I/O for pipes.
- // If the fd is a pipe and the Read was interrupted by CancelIoEx,
- // we assume it is interrupted by Close.
- err = ErrFileClosing
- }
- }
- if err != nil {
- n = 0
- }
- } else {
- o := &fd.rop
- o.InitBuf(buf)
- n, err = execIO(o, func(o *operation) error {
- return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
- })
- if race.Enabled {
- race.Acquire(unsafe.Pointer(&ioSync))
- }
- }
- if len(buf) != 0 {
- err = fd.eofError(n, err)
- }
- return n, err
-}
-
-var ReadConsole = syscall.ReadConsole // changed for testing
-
-// readConsole reads utf16 characters from console File,
-// encodes them into utf8 and stores them in buffer b.
-// It returns the number of utf8 bytes read and an error, if any.
-func (fd *FD) readConsole(b []byte) (int, error) {
- if len(b) == 0 {
- return 0, nil
- }
-
- if fd.readuint16 == nil {
- // Note: syscall.ReadConsole fails for very large buffers.
- // The limit is somewhere around (but not exactly) 16384.
- // Stay well below.
- fd.readuint16 = make([]uint16, 0, 10000)
- fd.readbyte = make([]byte, 0, 4*cap(fd.readuint16))
- }
-
- for fd.readbyteOffset >= len(fd.readbyte) {
- n := cap(fd.readuint16) - len(fd.readuint16)
- if n > len(b) {
- n = len(b)
- }
- var nw uint32
- err := ReadConsole(fd.Sysfd, &fd.readuint16[:len(fd.readuint16)+1][len(fd.readuint16)], uint32(n), &nw, nil)
- if err != nil {
- return 0, err
- }
- uint16s := fd.readuint16[:len(fd.readuint16)+int(nw)]
- fd.readuint16 = fd.readuint16[:0]
- buf := fd.readbyte[:0]
- for i := 0; i < len(uint16s); i++ {
- r := rune(uint16s[i])
- if utf16.IsSurrogate(r) {
- if i+1 == len(uint16s) {
- if nw > 0 {
- // Save half surrogate pair for next time.
- fd.readuint16 = fd.readuint16[:1]
- fd.readuint16[0] = uint16(r)
- break
- }
- r = utf8.RuneError
- } else {
- r = utf16.DecodeRune(r, rune(uint16s[i+1]))
- if r != utf8.RuneError {
- i++
- }
- }
- }
- buf = utf8.AppendRune(buf, r)
- }
- fd.readbyte = buf
- fd.readbyteOffset = 0
- if nw == 0 {
- break
- }
- }
-
- src := fd.readbyte[fd.readbyteOffset:]
- var i int
- for i = 0; i < len(src) && i < len(b); i++ {
- x := src[i]
- if x == 0x1A { // Ctrl-Z
- if i == 0 {
- fd.readbyteOffset++
- }
- break
- }
- b[i] = x
- }
- fd.readbyteOffset += i
- return i, nil
-}
-
-// Pread emulates the Unix pread system call.
-func (fd *FD) Pread(b []byte, off int64) (int, error) {
- // Call incref, not readLock, because since pread specifies the
- // offset it is independent from other reads.
- if err := fd.incref(); err != nil {
- return 0, err
- }
- defer fd.decref()
-
- if len(b) > maxRW {
- b = b[:maxRW]
- }
-
- fd.l.Lock()
- defer fd.l.Unlock()
- curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent)
- if e != nil {
- return 0, e
- }
- defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart)
- o := syscall.Overlapped{
- OffsetHigh: uint32(off >> 32),
- Offset: uint32(off),
- }
- var done uint32
- e = syscall.ReadFile(fd.Sysfd, b, &done, &o)
- if e != nil {
- done = 0
- if e == syscall.ERROR_HANDLE_EOF {
- e = io.EOF
- }
- }
- if len(b) != 0 {
- e = fd.eofError(int(done), e)
- }
- return int(done), e
-}
-
-// ReadFrom wraps the recvfrom network call.
-func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) {
- if len(buf) == 0 {
- return 0, nil, nil
- }
- if len(buf) > maxRW {
- buf = buf[:maxRW]
- }
- if err := fd.readLock(); err != nil {
- return 0, nil, err
- }
- defer fd.readUnlock()
- o := &fd.rop
- o.InitBuf(buf)
- n, err := execIO(o, func(o *operation) error {
- if o.rsa == nil {
- o.rsa = new(syscall.RawSockaddrAny)
- }
- o.rsan = int32(unsafe.Sizeof(*o.rsa))
- return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
- })
- err = fd.eofError(n, err)
- if err != nil {
- return n, nil, err
- }
- sa, _ := o.rsa.Sockaddr()
- return n, sa, nil
-}
-
-// ReadFromInet4 wraps the recvfrom network call for IPv4.
-func (fd *FD) ReadFromInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) {
- if len(buf) == 0 {
- return 0, nil
- }
- if len(buf) > maxRW {
- buf = buf[:maxRW]
- }
- if err := fd.readLock(); err != nil {
- return 0, err
- }
- defer fd.readUnlock()
- o := &fd.rop
- o.InitBuf(buf)
- n, err := execIO(o, func(o *operation) error {
- if o.rsa == nil {
- o.rsa = new(syscall.RawSockaddrAny)
- }
- o.rsan = int32(unsafe.Sizeof(*o.rsa))
- return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
- })
- err = fd.eofError(n, err)
- if err != nil {
- return n, err
- }
- rawToSockaddrInet4(o.rsa, sa4)
- return n, err
-}
-
-// ReadFromInet6 wraps the recvfrom network call for IPv6.
-func (fd *FD) ReadFromInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) {
- if len(buf) == 0 {
- return 0, nil
- }
- if len(buf) > maxRW {
- buf = buf[:maxRW]
- }
- if err := fd.readLock(); err != nil {
- return 0, err
- }
- defer fd.readUnlock()
- o := &fd.rop
- o.InitBuf(buf)
- n, err := execIO(o, func(o *operation) error {
- if o.rsa == nil {
- o.rsa = new(syscall.RawSockaddrAny)
- }
- o.rsan = int32(unsafe.Sizeof(*o.rsa))
- return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
- })
- err = fd.eofError(n, err)
- if err != nil {
- return n, err
- }
- rawToSockaddrInet6(o.rsa, sa6)
- return n, err
-}
-
-// Write implements io.Writer.
-func (fd *FD) Write(buf []byte) (int, error) {
- if err := fd.writeLock(); err != nil {
- return 0, err
- }
- defer fd.writeUnlock()
- if fd.isFile {
- fd.l.Lock()
- defer fd.l.Unlock()
- }
-
- ntotal := 0
- for len(buf) > 0 {
- b := buf
- if len(b) > maxRW {
- b = b[:maxRW]
- }
- var n int
- var err error
- if fd.isFile {
- switch fd.kind {
- case kindConsole:
- n, err = fd.writeConsole(b)
- default:
- n, err = syscall.Write(fd.Sysfd, b)
- if fd.kind == kindPipe && err == syscall.ERROR_OPERATION_ABORTED {
- // Close uses CancelIoEx to interrupt concurrent I/O for pipes.
- // If the fd is a pipe and the Write was interrupted by CancelIoEx,
- // we assume it is interrupted by Close.
- err = ErrFileClosing
- }
- }
- if err != nil {
- n = 0
- }
- } else {
- if race.Enabled {
- race.ReleaseMerge(unsafe.Pointer(&ioSync))
- }
- o := &fd.wop
- o.InitBuf(b)
- n, err = execIO(o, func(o *operation) error {
- return syscall.WSASend(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil)
- })
- }
- ntotal += n
- if err != nil {
- return ntotal, err
- }
- buf = buf[n:]
- }
- return ntotal, nil
-}
-
-// writeConsole writes len(b) bytes to the console File.
-// It returns the number of bytes written and an error, if any.
-func (fd *FD) writeConsole(b []byte) (int, error) {
- n := len(b)
- runes := make([]rune, 0, 256)
- if len(fd.lastbits) > 0 {
- b = append(fd.lastbits, b...)
- fd.lastbits = nil
-
- }
- for len(b) >= utf8.UTFMax || utf8.FullRune(b) {
- r, l := utf8.DecodeRune(b)
- runes = append(runes, r)
- b = b[l:]
- }
- if len(b) > 0 {
- fd.lastbits = make([]byte, len(b))
- copy(fd.lastbits, b)
- }
- // syscall.WriteConsole seems to fail, if given large buffer.
- // So limit the buffer to 16000 characters. This number was
- // discovered by experimenting with syscall.WriteConsole.
- const maxWrite = 16000
- for len(runes) > 0 {
- m := len(runes)
- if m > maxWrite {
- m = maxWrite
- }
- chunk := runes[:m]
- runes = runes[m:]
- uint16s := utf16.Encode(chunk)
- for len(uint16s) > 0 {
- var written uint32
- err := syscall.WriteConsole(fd.Sysfd, &uint16s[0], uint32(len(uint16s)), &written, nil)
- if err != nil {
- return 0, err
- }
- uint16s = uint16s[written:]
- }
- }
- return n, nil
-}
-
-// Pwrite emulates the Unix pwrite system call.
-func (fd *FD) Pwrite(buf []byte, off int64) (int, error) {
- // Call incref, not writeLock, because since pwrite specifies the
- // offset it is independent from other writes.
- if err := fd.incref(); err != nil {
- return 0, err
- }
- defer fd.decref()
-
- fd.l.Lock()
- defer fd.l.Unlock()
- curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent)
- if e != nil {
- return 0, e
- }
- defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart)
-
- ntotal := 0
- for len(buf) > 0 {
- b := buf
- if len(b) > maxRW {
- b = b[:maxRW]
- }
- var n uint32
- o := syscall.Overlapped{
- OffsetHigh: uint32(off >> 32),
- Offset: uint32(off),
- }
- e = syscall.WriteFile(fd.Sysfd, b, &n, &o)
- ntotal += int(n)
- if e != nil {
- return ntotal, e
- }
- buf = buf[n:]
- off += int64(n)
- }
- return ntotal, nil
-}
-
-// Writev emulates the Unix writev system call.
-func (fd *FD) Writev(buf *[][]byte) (int64, error) {
- if len(*buf) == 0 {
- return 0, nil
- }
- if err := fd.writeLock(); err != nil {
- return 0, err
- }
- defer fd.writeUnlock()
- if race.Enabled {
- race.ReleaseMerge(unsafe.Pointer(&ioSync))
- }
- o := &fd.wop
- o.InitBufs(buf)
- n, err := execIO(o, func(o *operation) error {
- return syscall.WSASend(o.fd.Sysfd, &o.bufs[0], uint32(len(o.bufs)), &o.qty, 0, &o.o, nil)
- })
- o.ClearBufs()
- TestHookDidWritev(n)
- consume(buf, int64(n))
- return int64(n), err
-}
-
-// WriteTo wraps the sendto network call.
-func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) {
- if err := fd.writeLock(); err != nil {
- return 0, err
- }
- defer fd.writeUnlock()
-
- if len(buf) == 0 {
- // handle zero-byte payload
- o := &fd.wop
- o.InitBuf(buf)
- o.sa = sa
- n, err := execIO(o, func(o *operation) error {
- return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
- })
- return n, err
- }
-
- ntotal := 0
- for len(buf) > 0 {
- b := buf
- if len(b) > maxRW {
- b = b[:maxRW]
- }
- o := &fd.wop
- o.InitBuf(b)
- o.sa = sa
- n, err := execIO(o, func(o *operation) error {
- return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
- })
- ntotal += int(n)
- if err != nil {
- return ntotal, err
- }
- buf = buf[n:]
- }
- return ntotal, nil
-}
-
-// WriteToInet4 is WriteTo, specialized for syscall.SockaddrInet4.
-func (fd *FD) WriteToInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) {
- if err := fd.writeLock(); err != nil {
- return 0, err
- }
- defer fd.writeUnlock()
-
- if len(buf) == 0 {
- // handle zero-byte payload
- o := &fd.wop
- o.InitBuf(buf)
- n, err := execIO(o, func(o *operation) error {
- return windows.WSASendtoInet4(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa4, &o.o, nil)
- })
- return n, err
- }
-
- ntotal := 0
- for len(buf) > 0 {
- b := buf
- if len(b) > maxRW {
- b = b[:maxRW]
- }
- o := &fd.wop
- o.InitBuf(b)
- n, err := execIO(o, func(o *operation) error {
- return windows.WSASendtoInet4(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa4, &o.o, nil)
- })
- ntotal += int(n)
- if err != nil {
- return ntotal, err
- }
- buf = buf[n:]
- }
- return ntotal, nil
-}
-
-// WriteToInet6 is WriteTo, specialized for syscall.SockaddrInet6.
-func (fd *FD) WriteToInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) {
- if err := fd.writeLock(); err != nil {
- return 0, err
- }
- defer fd.writeUnlock()
-
- if len(buf) == 0 {
- // handle zero-byte payload
- o := &fd.wop
- o.InitBuf(buf)
- n, err := execIO(o, func(o *operation) error {
- return windows.WSASendtoInet6(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa6, &o.o, nil)
- })
- return n, err
- }
-
- ntotal := 0
- for len(buf) > 0 {
- b := buf
- if len(b) > maxRW {
- b = b[:maxRW]
- }
- o := &fd.wop
- o.InitBuf(b)
- n, err := execIO(o, func(o *operation) error {
- return windows.WSASendtoInet6(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa6, &o.o, nil)
- })
- ntotal += int(n)
- if err != nil {
- return ntotal, err
- }
- buf = buf[n:]
- }
- return ntotal, nil
-}
-
-// Call ConnectEx. This doesn't need any locking, since it is only
-// called when the descriptor is first created. This is here rather
-// than in the net package so that it can use fd.wop.
-func (fd *FD) ConnectEx(ra syscall.Sockaddr) error {
- o := &fd.wop
- o.sa = ra
- _, err := execIO(o, func(o *operation) error {
- return ConnectExFunc(o.fd.Sysfd, o.sa, nil, 0, nil, &o.o)
- })
- return err
-}
-
-func (fd *FD) acceptOne(s syscall.Handle, rawsa []syscall.RawSockaddrAny, o *operation) (string, error) {
- // Submit accept request.
- o.handle = s
- o.rsan = int32(unsafe.Sizeof(rawsa[0]))
- _, err := execIO(o, func(o *operation) error {
- return AcceptFunc(o.fd.Sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
- })
- if err != nil {
- CloseFunc(s)
- return "acceptex", err
- }
-
- // Inherit properties of the listening socket.
- err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.Sysfd)), int32(unsafe.Sizeof(fd.Sysfd)))
- if err != nil {
- CloseFunc(s)
- return "setsockopt", err
- }
-
- return "", nil
-}
-
-// Accept handles accepting a socket. The sysSocket parameter is used
-// to allocate the net socket.
-func (fd *FD) Accept(sysSocket func() (syscall.Handle, error)) (syscall.Handle, []syscall.RawSockaddrAny, uint32, string, error) {
- if err := fd.readLock(); err != nil {
- return syscall.InvalidHandle, nil, 0, "", err
- }
- defer fd.readUnlock()
-
- o := &fd.rop
- var rawsa [2]syscall.RawSockaddrAny
- for {
- s, err := sysSocket()
- if err != nil {
- return syscall.InvalidHandle, nil, 0, "", err
- }
-
- errcall, err := fd.acceptOne(s, rawsa[:], o)
- if err == nil {
- return s, rawsa[:], uint32(o.rsan), "", nil
- }
-
- // Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is
- // returned here. These happen if connection reset is received
- // before AcceptEx could complete. These errors relate to new
- // connection, not to AcceptEx, so ignore broken connection and
- // try AcceptEx again for more connections.
- errno, ok := err.(syscall.Errno)
- if !ok {
- return syscall.InvalidHandle, nil, 0, errcall, err
- }
- switch errno {
- case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET:
- // ignore these and try again
- default:
- return syscall.InvalidHandle, nil, 0, errcall, err
- }
- }
-}
-
-// Seek wraps syscall.Seek.
-func (fd *FD) Seek(offset int64, whence int) (int64, error) {
- if err := fd.incref(); err != nil {
- return 0, err
- }
- defer fd.decref()
-
- fd.l.Lock()
- defer fd.l.Unlock()
-
- return syscall.Seek(fd.Sysfd, offset, whence)
-}
-
-// Fchmod updates syscall.ByHandleFileInformation.Fileattributes when needed.
-func (fd *FD) Fchmod(mode uint32) error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
-
- var d syscall.ByHandleFileInformation
- if err := syscall.GetFileInformationByHandle(fd.Sysfd, &d); err != nil {
- return err
- }
- attrs := d.FileAttributes
- if mode&syscall.S_IWRITE != 0 {
- attrs &^= syscall.FILE_ATTRIBUTE_READONLY
- } else {
- attrs |= syscall.FILE_ATTRIBUTE_READONLY
- }
- if attrs == d.FileAttributes {
- return nil
- }
-
- var du windows.FILE_BASIC_INFO
- du.FileAttributes = attrs
- l := uint32(unsafe.Sizeof(d))
- return windows.SetFileInformationByHandle(fd.Sysfd, windows.FileBasicInfo, uintptr(unsafe.Pointer(&du)), l)
-}
-
-// Fchdir wraps syscall.Fchdir.
-func (fd *FD) Fchdir() error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return syscall.Fchdir(fd.Sysfd)
-}
-
-// GetFileType wraps syscall.GetFileType.
-func (fd *FD) GetFileType() (uint32, error) {
- if err := fd.incref(); err != nil {
- return 0, err
- }
- defer fd.decref()
- return syscall.GetFileType(fd.Sysfd)
-}
-
-// GetFileInformationByHandle wraps GetFileInformationByHandle.
-func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return syscall.GetFileInformationByHandle(fd.Sysfd, data)
-}
-
-// RawRead invokes the user-defined function f for a read operation.
-func (fd *FD) RawRead(f func(uintptr) bool) error {
- if err := fd.readLock(); err != nil {
- return err
- }
- defer fd.readUnlock()
- for {
- if f(uintptr(fd.Sysfd)) {
- return nil
- }
-
- // Use a zero-byte read as a way to get notified when this
- // socket is readable. h/t https://stackoverflow.com/a/42019668/332798
- o := &fd.rop
- o.InitBuf(nil)
- if !fd.IsStream {
- o.flags |= windows.MSG_PEEK
- }
- _, err := execIO(o, func(o *operation) error {
- return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
- })
- if err == windows.WSAEMSGSIZE {
- // expected with a 0-byte peek, ignore.
- } else if err != nil {
- return err
- }
- }
-}
-
-// RawWrite invokes the user-defined function f for a write operation.
-func (fd *FD) RawWrite(f func(uintptr) bool) error {
- if err := fd.writeLock(); err != nil {
- return err
- }
- defer fd.writeUnlock()
-
- if f(uintptr(fd.Sysfd)) {
- return nil
- }
-
- // TODO(tmm1): find a way to detect socket writability
- return syscall.EWINDOWS
-}
-
-func sockaddrInet4ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) int32 {
- *rsa = syscall.RawSockaddrAny{}
- raw := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
- raw.Family = syscall.AF_INET
- p := (*[2]byte)(unsafe.Pointer(&raw.Port))
- p[0] = byte(sa.Port >> 8)
- p[1] = byte(sa.Port)
- raw.Addr = sa.Addr
- return int32(unsafe.Sizeof(*raw))
-}
-
-func sockaddrInet6ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) int32 {
- *rsa = syscall.RawSockaddrAny{}
- raw := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
- raw.Family = syscall.AF_INET6
- p := (*[2]byte)(unsafe.Pointer(&raw.Port))
- p[0] = byte(sa.Port >> 8)
- p[1] = byte(sa.Port)
- raw.Scope_id = sa.ZoneId
- raw.Addr = sa.Addr
- return int32(unsafe.Sizeof(*raw))
-}
-
-func rawToSockaddrInet4(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) {
- pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
- p := (*[2]byte)(unsafe.Pointer(&pp.Port))
- sa.Port = int(p[0])<<8 + int(p[1])
- sa.Addr = pp.Addr
-}
-
-func rawToSockaddrInet6(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) {
- pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
- p := (*[2]byte)(unsafe.Pointer(&pp.Port))
- sa.Port = int(p[0])<<8 + int(p[1])
- sa.ZoneId = pp.Scope_id
- sa.Addr = pp.Addr
-}
-
-func sockaddrToRaw(rsa *syscall.RawSockaddrAny, sa syscall.Sockaddr) (int32, error) {
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- sz := sockaddrInet4ToRaw(rsa, sa)
- return sz, nil
- case *syscall.SockaddrInet6:
- sz := sockaddrInet6ToRaw(rsa, sa)
- return sz, nil
- default:
- return 0, syscall.EWINDOWS
- }
-}
-
-// ReadMsg wraps the WSARecvMsg network call.
-func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) {
- if err := fd.readLock(); err != nil {
- return 0, 0, 0, nil, err
- }
- defer fd.readUnlock()
-
- if len(p) > maxRW {
- p = p[:maxRW]
- }
-
- o := &fd.rop
- o.InitMsg(p, oob)
- if o.rsa == nil {
- o.rsa = new(syscall.RawSockaddrAny)
- }
- o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
- o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
- o.msg.Flags = uint32(flags)
- n, err := execIO(o, func(o *operation) error {
- return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
- })
- err = fd.eofError(n, err)
- var sa syscall.Sockaddr
- if err == nil {
- sa, err = o.rsa.Sockaddr()
- }
- return n, int(o.msg.Control.Len), int(o.msg.Flags), sa, err
-}
-
-// ReadMsgInet4 is ReadMsg, but specialized to return a syscall.SockaddrInet4.
-func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) {
- if err := fd.readLock(); err != nil {
- return 0, 0, 0, err
- }
- defer fd.readUnlock()
-
- if len(p) > maxRW {
- p = p[:maxRW]
- }
-
- o := &fd.rop
- o.InitMsg(p, oob)
- if o.rsa == nil {
- o.rsa = new(syscall.RawSockaddrAny)
- }
- o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
- o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
- o.msg.Flags = uint32(flags)
- n, err := execIO(o, func(o *operation) error {
- return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
- })
- err = fd.eofError(n, err)
- if err == nil {
- rawToSockaddrInet4(o.rsa, sa4)
- }
- return n, int(o.msg.Control.Len), int(o.msg.Flags), err
-}
-
-// ReadMsgInet6 is ReadMsg, but specialized to return a syscall.SockaddrInet6.
-func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) {
- if err := fd.readLock(); err != nil {
- return 0, 0, 0, err
- }
- defer fd.readUnlock()
-
- if len(p) > maxRW {
- p = p[:maxRW]
- }
-
- o := &fd.rop
- o.InitMsg(p, oob)
- if o.rsa == nil {
- o.rsa = new(syscall.RawSockaddrAny)
- }
- o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
- o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
- o.msg.Flags = uint32(flags)
- n, err := execIO(o, func(o *operation) error {
- return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
- })
- err = fd.eofError(n, err)
- if err == nil {
- rawToSockaddrInet6(o.rsa, sa6)
- }
- return n, int(o.msg.Control.Len), int(o.msg.Flags), err
-}
-
-// WriteMsg wraps the WSASendMsg network call.
-func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
- if len(p) > maxRW {
- return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
- }
-
- if err := fd.writeLock(); err != nil {
- return 0, 0, err
- }
- defer fd.writeUnlock()
-
- o := &fd.wop
- o.InitMsg(p, oob)
- if sa != nil {
- if o.rsa == nil {
- o.rsa = new(syscall.RawSockaddrAny)
- }
- len, err := sockaddrToRaw(o.rsa, sa)
- if err != nil {
- return 0, 0, err
- }
- o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
- o.msg.Namelen = len
- }
- n, err := execIO(o, func(o *operation) error {
- return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
- })
- return n, int(o.msg.Control.Len), err
-}
-
-// WriteMsgInet4 is WriteMsg specialized for syscall.SockaddrInet4.
-func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (int, int, error) {
- if len(p) > maxRW {
- return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
- }
-
- if err := fd.writeLock(); err != nil {
- return 0, 0, err
- }
- defer fd.writeUnlock()
-
- o := &fd.wop
- o.InitMsg(p, oob)
- if o.rsa == nil {
- o.rsa = new(syscall.RawSockaddrAny)
- }
- len := sockaddrInet4ToRaw(o.rsa, sa)
- o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
- o.msg.Namelen = len
- n, err := execIO(o, func(o *operation) error {
- return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
- })
- return n, int(o.msg.Control.Len), err
-}
-
-// WriteMsgInet6 is WriteMsg specialized for syscall.SockaddrInet6.
-func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (int, int, error) {
- if len(p) > maxRW {
- return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
- }
-
- if err := fd.writeLock(); err != nil {
- return 0, 0, err
- }
- defer fd.writeUnlock()
-
- o := &fd.wop
- o.InitMsg(p, oob)
- if o.rsa == nil {
- o.rsa = new(syscall.RawSockaddrAny)
- }
- len := sockaddrInet6ToRaw(o.rsa, sa)
- o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
- o.msg.Namelen = len
- n, err := execIO(o, func(o *operation) error {
- return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
- })
- return n, int(o.msg.Control.Len), err
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/hook_unix.go b/contrib/go/_std_1.20/src/internal/poll/hook_unix.go
deleted file mode 100644
index 1a5035675d..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/hook_unix.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2017 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.
-
-//go:build unix || (js && wasm)
-
-package poll
-
-import "syscall"
-
-// CloseFunc is used to hook the close call.
-var CloseFunc func(int) error = syscall.Close
-
-// AcceptFunc is used to hook the accept call.
-var AcceptFunc func(int) (int, syscall.Sockaddr, error) = syscall.Accept
diff --git a/contrib/go/_std_1.20/src/internal/poll/sendfile_windows.go b/contrib/go/_std_1.20/src/internal/poll/sendfile_windows.go
deleted file mode 100644
index 50c3ee86c0..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/sendfile_windows.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2011 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 poll
-
-import (
- "io"
- "syscall"
-)
-
-// SendFile wraps the TransmitFile call.
-func SendFile(fd *FD, src syscall.Handle, n int64) (written int64, err error) {
- if fd.kind == kindPipe {
- // TransmitFile does not work with pipes
- return 0, syscall.ESPIPE
- }
-
- if err := fd.writeLock(); err != nil {
- return 0, err
- }
- defer fd.writeUnlock()
-
- o := &fd.wop
- o.handle = src
-
- // TODO(brainman): skip calling syscall.Seek if OS allows it
- curpos, err := syscall.Seek(o.handle, 0, io.SeekCurrent)
- if err != nil {
- return 0, err
- }
-
- if n <= 0 { // We don't know the size of the file so infer it.
- // Find the number of bytes offset from curpos until the end of the file.
- n, err = syscall.Seek(o.handle, -curpos, io.SeekEnd)
- if err != nil {
- return
- }
- // Now seek back to the original position.
- if _, err = syscall.Seek(o.handle, curpos, io.SeekStart); err != nil {
- return
- }
- }
-
- // TransmitFile can be invoked in one call with at most
- // 2,147,483,646 bytes: the maximum value for a 32-bit integer minus 1.
- // See https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-transmitfile
- const maxChunkSizePerCall = int64(0x7fffffff - 1)
-
- for n > 0 {
- chunkSize := maxChunkSizePerCall
- if chunkSize > n {
- chunkSize = n
- }
-
- o.qty = uint32(chunkSize)
- o.o.Offset = uint32(curpos)
- o.o.OffsetHigh = uint32(curpos >> 32)
-
- nw, err := execIO(o, func(o *operation) error {
- return syscall.TransmitFile(o.fd.Sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
- })
- if err != nil {
- return written, err
- }
-
- curpos += int64(nw)
-
- // Some versions of Windows (Windows 10 1803) do not set
- // file position after TransmitFile completes.
- // So just use Seek to set file position.
- if _, err = syscall.Seek(o.handle, curpos, io.SeekStart); err != nil {
- return written, err
- }
-
- n -= int64(nw)
- written += int64(nw)
- }
-
- return
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/sock_cloexec.go b/contrib/go/_std_1.20/src/internal/poll/sock_cloexec.go
deleted file mode 100644
index f5be2aa5f2..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/sock_cloexec.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements accept for platforms that provide a fast path for
-// setting SetNonblock and CloseOnExec.
-
-//go:build dragonfly || freebsd || (linux && !arm) || netbsd || openbsd || solaris
-
-package poll
-
-import "syscall"
-
-// Wrapper around the accept system call that marks the returned file
-// descriptor as nonblocking and close-on-exec.
-func accept(s int) (int, syscall.Sockaddr, string, error) {
- ns, sa, err := Accept4Func(s, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC)
- if err != nil {
- return -1, sa, "accept4", err
- }
- return ns, sa, "", nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/sockopt.go b/contrib/go/_std_1.20/src/internal/poll/sockopt.go
deleted file mode 100644
index a7c9d115b4..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/sockopt.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix || windows
-
-package poll
-
-import "syscall"
-
-// SetsockoptInt wraps the setsockopt network call with an int argument.
-func (fd *FD) SetsockoptInt(level, name, arg int) error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return syscall.SetsockoptInt(fd.Sysfd, level, name, arg)
-}
-
-// SetsockoptInet4Addr wraps the setsockopt network call with an IPv4 address.
-func (fd *FD) SetsockoptInet4Addr(level, name int, arg [4]byte) error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return syscall.SetsockoptInet4Addr(fd.Sysfd, level, name, arg)
-}
-
-// SetsockoptLinger wraps the setsockopt network call with a Linger argument.
-func (fd *FD) SetsockoptLinger(level, name int, l *syscall.Linger) error {
- if err := fd.incref(); err != nil {
- return err
- }
- defer fd.decref()
- return syscall.SetsockoptLinger(fd.Sysfd, level, name, l)
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/splice_linux.go b/contrib/go/_std_1.20/src/internal/poll/splice_linux.go
deleted file mode 100644
index 96cbe4a312..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/splice_linux.go
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2018 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 poll
-
-import (
- "runtime"
- "sync"
- "syscall"
- "unsafe"
-)
-
-const (
- // spliceNonblock makes calls to splice(2) non-blocking.
- spliceNonblock = 0x2
-
- // maxSpliceSize is the maximum amount of data Splice asks
- // the kernel to move in a single call to splice(2).
- // We use 1MB as Splice writes data through a pipe, and 1MB is the default maximum pipe buffer size,
- // which is determined by /proc/sys/fs/pipe-max-size.
- maxSpliceSize = 1 << 20
-)
-
-// Splice transfers at most remain bytes of data from src to dst, using the
-// splice system call to minimize copies of data from and to userspace.
-//
-// Splice gets a pipe buffer from the pool or creates a new one if needed, to serve as a buffer for the data transfer.
-// src and dst must both be stream-oriented sockets.
-//
-// If err != nil, sc is the system call which caused the error.
-func Splice(dst, src *FD, remain int64) (written int64, handled bool, sc string, err error) {
- p, sc, err := getPipe()
- if err != nil {
- return 0, false, sc, err
- }
- defer putPipe(p)
- var inPipe, n int
- for err == nil && remain > 0 {
- max := maxSpliceSize
- if int64(max) > remain {
- max = int(remain)
- }
- inPipe, err = spliceDrain(p.wfd, src, max)
- // The operation is considered handled if splice returns no
- // error, or an error other than EINVAL. An EINVAL means the
- // kernel does not support splice for the socket type of src.
- // The failed syscall does not consume any data so it is safe
- // to fall back to a generic copy.
- //
- // spliceDrain should never return EAGAIN, so if err != nil,
- // Splice cannot continue.
- //
- // If inPipe == 0 && err == nil, src is at EOF, and the
- // transfer is complete.
- handled = handled || (err != syscall.EINVAL)
- if err != nil || inPipe == 0 {
- break
- }
- p.data += inPipe
-
- n, err = splicePump(dst, p.rfd, inPipe)
- if n > 0 {
- written += int64(n)
- remain -= int64(n)
- p.data -= n
- }
- }
- if err != nil {
- return written, handled, "splice", err
- }
- return written, true, "", nil
-}
-
-// spliceDrain moves data from a socket to a pipe.
-//
-// Invariant: when entering spliceDrain, the pipe is empty. It is either in its
-// initial state, or splicePump has emptied it previously.
-//
-// Given this, spliceDrain can reasonably assume that the pipe is ready for
-// writing, so if splice returns EAGAIN, it must be because the socket is not
-// ready for reading.
-//
-// If spliceDrain returns (0, nil), src is at EOF.
-func spliceDrain(pipefd int, sock *FD, max int) (int, error) {
- if err := sock.readLock(); err != nil {
- return 0, err
- }
- defer sock.readUnlock()
- if err := sock.pd.prepareRead(sock.isFile); err != nil {
- return 0, err
- }
- for {
- n, err := splice(pipefd, sock.Sysfd, max, spliceNonblock)
- if err == syscall.EINTR {
- continue
- }
- if err != syscall.EAGAIN {
- return n, err
- }
- if err := sock.pd.waitRead(sock.isFile); err != nil {
- return n, err
- }
- }
-}
-
-// splicePump moves all the buffered data from a pipe to a socket.
-//
-// Invariant: when entering splicePump, there are exactly inPipe
-// bytes of data in the pipe, from a previous call to spliceDrain.
-//
-// By analogy to the condition from spliceDrain, splicePump
-// only needs to poll the socket for readiness, if splice returns
-// EAGAIN.
-//
-// If splicePump cannot move all the data in a single call to
-// splice(2), it loops over the buffered data until it has written
-// all of it to the socket. This behavior is similar to the Write
-// step of an io.Copy in userspace.
-func splicePump(sock *FD, pipefd int, inPipe int) (int, error) {
- if err := sock.writeLock(); err != nil {
- return 0, err
- }
- defer sock.writeUnlock()
- if err := sock.pd.prepareWrite(sock.isFile); err != nil {
- return 0, err
- }
- written := 0
- for inPipe > 0 {
- n, err := splice(sock.Sysfd, pipefd, inPipe, spliceNonblock)
- // Here, the condition n == 0 && err == nil should never be
- // observed, since Splice controls the write side of the pipe.
- if n > 0 {
- inPipe -= n
- written += n
- continue
- }
- if err != syscall.EAGAIN {
- return written, err
- }
- if err := sock.pd.waitWrite(sock.isFile); err != nil {
- return written, err
- }
- }
- return written, nil
-}
-
-// splice wraps the splice system call. Since the current implementation
-// only uses splice on sockets and pipes, the offset arguments are unused.
-// splice returns int instead of int64, because callers never ask it to
-// move more data in a single call than can fit in an int32.
-func splice(out int, in int, max int, flags int) (int, error) {
- n, err := syscall.Splice(in, nil, out, nil, max, flags)
- return int(n), err
-}
-
-type splicePipeFields struct {
- rfd int
- wfd int
- data int
-}
-
-type splicePipe struct {
- splicePipeFields
-
- // We want to use a finalizer, so ensure that the size is
- // large enough to not use the tiny allocator.
- _ [24 - unsafe.Sizeof(splicePipeFields{})%24]byte
-}
-
-// splicePipePool caches pipes to avoid high-frequency construction and destruction of pipe buffers.
-// The garbage collector will free all pipes in the sync.Pool periodically, thus we need to set up
-// a finalizer for each pipe to close its file descriptors before the actual GC.
-var splicePipePool = sync.Pool{New: newPoolPipe}
-
-func newPoolPipe() any {
- // Discard the error which occurred during the creation of pipe buffer,
- // redirecting the data transmission to the conventional way utilizing read() + write() as a fallback.
- p := newPipe()
- if p == nil {
- return nil
- }
- runtime.SetFinalizer(p, destroyPipe)
- return p
-}
-
-// getPipe tries to acquire a pipe buffer from the pool or create a new one with newPipe() if it gets nil from the cache.
-//
-// Note that it may fail to create a new pipe buffer by newPipe(), in which case getPipe() will return a generic error
-// and system call name splice in a string as the indication.
-func getPipe() (*splicePipe, string, error) {
- v := splicePipePool.Get()
- if v == nil {
- return nil, "splice", syscall.EINVAL
- }
- return v.(*splicePipe), "", nil
-}
-
-func putPipe(p *splicePipe) {
- // If there is still data left in the pipe,
- // then close and discard it instead of putting it back into the pool.
- if p.data != 0 {
- runtime.SetFinalizer(p, nil)
- destroyPipe(p)
- return
- }
- splicePipePool.Put(p)
-}
-
-// newPipe sets up a pipe for a splice operation.
-func newPipe() *splicePipe {
- var fds [2]int
- if err := syscall.Pipe2(fds[:], syscall.O_CLOEXEC|syscall.O_NONBLOCK); err != nil {
- return nil
- }
-
- // Splice will loop writing maxSpliceSize bytes from the source to the pipe,
- // and then write those bytes from the pipe to the destination.
- // Set the pipe buffer size to maxSpliceSize to optimize that.
- // Ignore errors here, as a smaller buffer size will work,
- // although it will require more system calls.
- fcntl(fds[0], syscall.F_SETPIPE_SZ, maxSpliceSize)
-
- return &splicePipe{splicePipeFields: splicePipeFields{rfd: fds[0], wfd: fds[1]}}
-}
-
-// destroyPipe destroys a pipe.
-func destroyPipe(p *splicePipe) {
- CloseFunc(p.rfd)
- CloseFunc(p.wfd)
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/sys_cloexec.go b/contrib/go/_std_1.20/src/internal/poll/sys_cloexec.go
deleted file mode 100644
index 7cd80019f4..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/sys_cloexec.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements accept for platforms that do not provide a fast path for
-// setting SetNonblock and CloseOnExec.
-
-//go:build aix || darwin || (js && wasm)
-
-package poll
-
-import (
- "syscall"
-)
-
-// Wrapper around the accept system call that marks the returned file
-// descriptor as nonblocking and close-on-exec.
-func accept(s int) (int, syscall.Sockaddr, string, error) {
- // See ../syscall/exec_unix.go for description of ForkLock.
- // It is probably okay to hold the lock across syscall.Accept
- // because we have put fd.sysfd into non-blocking mode.
- // However, a call to the File method will put it back into
- // blocking mode. We can't take that risk, so no use of ForkLock here.
- ns, sa, err := AcceptFunc(s)
- if err == nil {
- syscall.CloseOnExec(ns)
- }
- if err != nil {
- return -1, nil, "accept", err
- }
- if err = syscall.SetNonblock(ns, true); err != nil {
- CloseFunc(ns)
- return -1, nil, "setnonblock", err
- }
- return ns, sa, "", nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/poll/ya.make b/contrib/go/_std_1.20/src/internal/poll/ya.make
deleted file mode 100644
index bc94f38a4a..0000000000
--- a/contrib/go/_std_1.20/src/internal/poll/ya.make
+++ /dev/null
@@ -1,60 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- fd.go
- fd_mutex.go
- fd_poll_runtime.go
- fd_posix.go
- sockopt.go
- sockoptip.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- errno_unix.go
- fcntl_libc.go
- fd_fsync_darwin.go
- fd_opendir_darwin.go
- fd_unix.go
- fd_writev_libc.go
- hook_unix.go
- iovec_unix.go
- sendfile_bsd.go
- sockopt_unix.go
- sys_cloexec.go
- writev.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- copy_file_range_linux.go
- errno_unix.go
- fcntl_syscall.go
- fd_fsync_posix.go
- fd_unix.go
- fd_writev_unix.go
- hook_cloexec.go
- hook_unix.go
- iovec_unix.go
- sendfile_linux.go
- sock_cloexec.go
- sockopt_linux.go
- sockopt_unix.go
- splice_linux.go
- writev.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- errno_windows.go
- fd_fsync_windows.go
- fd_windows.go
- hook_windows.go
- sendfile_windows.go
- sockopt_windows.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/profile/legacy_profile.go b/contrib/go/_std_1.20/src/internal/profile/legacy_profile.go
deleted file mode 100644
index b102c95904..0000000000
--- a/contrib/go/_std_1.20/src/internal/profile/legacy_profile.go
+++ /dev/null
@@ -1,1268 +0,0 @@
-// Copyright 2014 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.
-
-// This file implements parsers to convert legacy profiles into the
-// profile.proto format.
-
-package profile
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "io"
- "math"
- "regexp"
- "strconv"
- "strings"
-)
-
-var (
- countStartRE = regexp.MustCompile(`\A(\w+) profile: total \d+\n\z`)
- countRE = regexp.MustCompile(`\A(\d+) @(( 0x[0-9a-f]+)+)\n\z`)
-
- heapHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] *@ *(heap[_a-z0-9]*)/?(\d*)`)
- heapSampleRE = regexp.MustCompile(`(-?\d+): *(-?\d+) *\[ *(\d+): *(\d+) *] @([ x0-9a-f]*)`)
-
- contentionSampleRE = regexp.MustCompile(`(\d+) *(\d+) @([ x0-9a-f]*)`)
-
- hexNumberRE = regexp.MustCompile(`0x[0-9a-f]+`)
-
- growthHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ growthz`)
-
- fragmentationHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ fragmentationz`)
-
- threadzStartRE = regexp.MustCompile(`--- threadz \d+ ---`)
- threadStartRE = regexp.MustCompile(`--- Thread ([[:xdigit:]]+) \(name: (.*)/(\d+)\) stack: ---`)
-
- procMapsRE = regexp.MustCompile(`([[:xdigit:]]+)-([[:xdigit:]]+)\s+([-rwxp]+)\s+([[:xdigit:]]+)\s+([[:xdigit:]]+):([[:xdigit:]]+)\s+([[:digit:]]+)\s*(\S+)?`)
-
- briefMapsRE = regexp.MustCompile(`\s*([[:xdigit:]]+)-([[:xdigit:]]+):\s*(\S+)(\s.*@)?([[:xdigit:]]+)?`)
-
- // LegacyHeapAllocated instructs the heapz parsers to use the
- // allocated memory stats instead of the default in-use memory. Note
- // that tcmalloc doesn't provide all allocated memory, only in-use
- // stats.
- LegacyHeapAllocated bool
-)
-
-func isSpaceOrComment(line string) bool {
- trimmed := strings.TrimSpace(line)
- return len(trimmed) == 0 || trimmed[0] == '#'
-}
-
-// parseGoCount parses a Go count profile (e.g., threadcreate or
-// goroutine) and returns a new Profile.
-func parseGoCount(b []byte) (*Profile, error) {
- r := bytes.NewBuffer(b)
-
- var line string
- var err error
- for {
- // Skip past comments and empty lines seeking a real header.
- line, err = r.ReadString('\n')
- if err != nil {
- return nil, err
- }
- if !isSpaceOrComment(line) {
- break
- }
- }
-
- m := countStartRE.FindStringSubmatch(line)
- if m == nil {
- return nil, errUnrecognized
- }
- profileType := m[1]
- p := &Profile{
- PeriodType: &ValueType{Type: profileType, Unit: "count"},
- Period: 1,
- SampleType: []*ValueType{{Type: profileType, Unit: "count"}},
- }
- locations := make(map[uint64]*Location)
- for {
- line, err = r.ReadString('\n')
- if err != nil {
- if err == io.EOF {
- break
- }
- return nil, err
- }
- if isSpaceOrComment(line) {
- continue
- }
- if strings.HasPrefix(line, "---") {
- break
- }
- m := countRE.FindStringSubmatch(line)
- if m == nil {
- return nil, errMalformed
- }
- n, err := strconv.ParseInt(m[1], 0, 64)
- if err != nil {
- return nil, errMalformed
- }
- fields := strings.Fields(m[2])
- locs := make([]*Location, 0, len(fields))
- for _, stk := range fields {
- addr, err := strconv.ParseUint(stk, 0, 64)
- if err != nil {
- return nil, errMalformed
- }
- // Adjust all frames by -1 to land on the call instruction.
- addr--
- loc := locations[addr]
- if loc == nil {
- loc = &Location{
- Address: addr,
- }
- locations[addr] = loc
- p.Location = append(p.Location, loc)
- }
- locs = append(locs, loc)
- }
- p.Sample = append(p.Sample, &Sample{
- Location: locs,
- Value: []int64{n},
- })
- }
-
- if err = parseAdditionalSections(strings.TrimSpace(line), r, p); err != nil {
- return nil, err
- }
- return p, nil
-}
-
-// remapLocationIDs ensures there is a location for each address
-// referenced by a sample, and remaps the samples to point to the new
-// location ids.
-func (p *Profile) remapLocationIDs() {
- seen := make(map[*Location]bool, len(p.Location))
- var locs []*Location
-
- for _, s := range p.Sample {
- for _, l := range s.Location {
- if seen[l] {
- continue
- }
- l.ID = uint64(len(locs) + 1)
- locs = append(locs, l)
- seen[l] = true
- }
- }
- p.Location = locs
-}
-
-func (p *Profile) remapFunctionIDs() {
- seen := make(map[*Function]bool, len(p.Function))
- var fns []*Function
-
- for _, l := range p.Location {
- for _, ln := range l.Line {
- fn := ln.Function
- if fn == nil || seen[fn] {
- continue
- }
- fn.ID = uint64(len(fns) + 1)
- fns = append(fns, fn)
- seen[fn] = true
- }
- }
- p.Function = fns
-}
-
-// remapMappingIDs matches location addresses with existing mappings
-// and updates them appropriately. This is O(N*M), if this ever shows
-// up as a bottleneck, evaluate sorting the mappings and doing a
-// binary search, which would make it O(N*log(M)).
-func (p *Profile) remapMappingIDs() {
- if len(p.Mapping) == 0 {
- return
- }
-
- // Some profile handlers will incorrectly set regions for the main
- // executable if its section is remapped. Fix them through heuristics.
-
- // Remove the initial mapping if named '/anon_hugepage' and has a
- // consecutive adjacent mapping.
- if m := p.Mapping[0]; strings.HasPrefix(m.File, "/anon_hugepage") {
- if len(p.Mapping) > 1 && m.Limit == p.Mapping[1].Start {
- p.Mapping = p.Mapping[1:]
- }
- }
-
- for _, l := range p.Location {
- if a := l.Address; a != 0 {
- for _, m := range p.Mapping {
- if m.Start <= a && a < m.Limit {
- l.Mapping = m
- break
- }
- }
- }
- }
-
- // Reset all mapping IDs.
- for i, m := range p.Mapping {
- m.ID = uint64(i + 1)
- }
-}
-
-var cpuInts = []func([]byte) (uint64, []byte){
- get32l,
- get32b,
- get64l,
- get64b,
-}
-
-func get32l(b []byte) (uint64, []byte) {
- if len(b) < 4 {
- return 0, nil
- }
- return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24, b[4:]
-}
-
-func get32b(b []byte) (uint64, []byte) {
- if len(b) < 4 {
- return 0, nil
- }
- return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24, b[4:]
-}
-
-func get64l(b []byte) (uint64, []byte) {
- if len(b) < 8 {
- return 0, nil
- }
- return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56, b[8:]
-}
-
-func get64b(b []byte) (uint64, []byte) {
- if len(b) < 8 {
- return 0, nil
- }
- return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56, b[8:]
-}
-
-// ParseTracebacks parses a set of tracebacks and returns a newly
-// populated profile. It will accept any text file and generate a
-// Profile out of it with any hex addresses it can identify, including
-// a process map if it can recognize one. Each sample will include a
-// tag "source" with the addresses recognized in string format.
-func ParseTracebacks(b []byte) (*Profile, error) {
- r := bytes.NewBuffer(b)
-
- p := &Profile{
- PeriodType: &ValueType{Type: "trace", Unit: "count"},
- Period: 1,
- SampleType: []*ValueType{
- {Type: "trace", Unit: "count"},
- },
- }
-
- var sources []string
- var sloc []*Location
-
- locs := make(map[uint64]*Location)
- for {
- l, err := r.ReadString('\n')
- if err != nil {
- if err != io.EOF {
- return nil, err
- }
- if l == "" {
- break
- }
- }
- if sectionTrigger(l) == memoryMapSection {
- break
- }
- if s, addrs := extractHexAddresses(l); len(s) > 0 {
- for _, addr := range addrs {
- // Addresses from stack traces point to the next instruction after
- // each call. Adjust by -1 to land somewhere on the actual call.
- addr--
- loc := locs[addr]
- if locs[addr] == nil {
- loc = &Location{
- Address: addr,
- }
- p.Location = append(p.Location, loc)
- locs[addr] = loc
- }
- sloc = append(sloc, loc)
- }
-
- sources = append(sources, s...)
- } else {
- if len(sources) > 0 || len(sloc) > 0 {
- addTracebackSample(sloc, sources, p)
- sloc, sources = nil, nil
- }
- }
- }
-
- // Add final sample to save any leftover data.
- if len(sources) > 0 || len(sloc) > 0 {
- addTracebackSample(sloc, sources, p)
- }
-
- if err := p.ParseMemoryMap(r); err != nil {
- return nil, err
- }
- return p, nil
-}
-
-func addTracebackSample(l []*Location, s []string, p *Profile) {
- p.Sample = append(p.Sample,
- &Sample{
- Value: []int64{1},
- Location: l,
- Label: map[string][]string{"source": s},
- })
-}
-
-// parseCPU parses a profilez legacy profile and returns a newly
-// populated Profile.
-//
-// The general format for profilez samples is a sequence of words in
-// binary format. The first words are a header with the following data:
-//
-// 1st word -- 0
-// 2nd word -- 3
-// 3rd word -- 0 if a c++ application, 1 if a java application.
-// 4th word -- Sampling period (in microseconds).
-// 5th word -- Padding.
-func parseCPU(b []byte) (*Profile, error) {
- var parse func([]byte) (uint64, []byte)
- var n1, n2, n3, n4, n5 uint64
- for _, parse = range cpuInts {
- var tmp []byte
- n1, tmp = parse(b)
- n2, tmp = parse(tmp)
- n3, tmp = parse(tmp)
- n4, tmp = parse(tmp)
- n5, tmp = parse(tmp)
-
- if tmp != nil && n1 == 0 && n2 == 3 && n3 == 0 && n4 > 0 && n5 == 0 {
- b = tmp
- return cpuProfile(b, int64(n4), parse)
- }
- }
- return nil, errUnrecognized
-}
-
-// cpuProfile returns a new Profile from C++ profilez data.
-// b is the profile bytes after the header, period is the profiling
-// period, and parse is a function to parse 8-byte chunks from the
-// profile in its native endianness.
-func cpuProfile(b []byte, period int64, parse func(b []byte) (uint64, []byte)) (*Profile, error) {
- p := &Profile{
- Period: period * 1000,
- PeriodType: &ValueType{Type: "cpu", Unit: "nanoseconds"},
- SampleType: []*ValueType{
- {Type: "samples", Unit: "count"},
- {Type: "cpu", Unit: "nanoseconds"},
- },
- }
- var err error
- if b, _, err = parseCPUSamples(b, parse, true, p); err != nil {
- return nil, err
- }
-
- // If all samples have the same second-to-the-bottom frame, it
- // strongly suggests that it is an uninteresting artifact of
- // measurement -- a stack frame pushed by the signal handler. The
- // bottom frame is always correct as it is picked up from the signal
- // structure, not the stack. Check if this is the case and if so,
- // remove.
- if len(p.Sample) > 1 && len(p.Sample[0].Location) > 1 {
- allSame := true
- id1 := p.Sample[0].Location[1].Address
- for _, s := range p.Sample {
- if len(s.Location) < 2 || id1 != s.Location[1].Address {
- allSame = false
- break
- }
- }
- if allSame {
- for _, s := range p.Sample {
- s.Location = append(s.Location[:1], s.Location[2:]...)
- }
- }
- }
-
- if err := p.ParseMemoryMap(bytes.NewBuffer(b)); err != nil {
- return nil, err
- }
- return p, nil
-}
-
-// parseCPUSamples parses a collection of profilez samples from a
-// profile.
-//
-// profilez samples are a repeated sequence of stack frames of the
-// form:
-//
-// 1st word -- The number of times this stack was encountered.
-// 2nd word -- The size of the stack (StackSize).
-// 3rd word -- The first address on the stack.
-// ...
-// StackSize + 2 -- The last address on the stack
-//
-// The last stack trace is of the form:
-//
-// 1st word -- 0
-// 2nd word -- 1
-// 3rd word -- 0
-//
-// Addresses from stack traces may point to the next instruction after
-// each call. Optionally adjust by -1 to land somewhere on the actual
-// call (except for the leaf, which is not a call).
-func parseCPUSamples(b []byte, parse func(b []byte) (uint64, []byte), adjust bool, p *Profile) ([]byte, map[uint64]*Location, error) {
- locs := make(map[uint64]*Location)
- for len(b) > 0 {
- var count, nstk uint64
- count, b = parse(b)
- nstk, b = parse(b)
- if b == nil || nstk > uint64(len(b)/4) {
- return nil, nil, errUnrecognized
- }
- var sloc []*Location
- addrs := make([]uint64, nstk)
- for i := 0; i < int(nstk); i++ {
- addrs[i], b = parse(b)
- }
-
- if count == 0 && nstk == 1 && addrs[0] == 0 {
- // End of data marker
- break
- }
- for i, addr := range addrs {
- if adjust && i > 0 {
- addr--
- }
- loc := locs[addr]
- if loc == nil {
- loc = &Location{
- Address: addr,
- }
- locs[addr] = loc
- p.Location = append(p.Location, loc)
- }
- sloc = append(sloc, loc)
- }
- p.Sample = append(p.Sample,
- &Sample{
- Value: []int64{int64(count), int64(count) * p.Period},
- Location: sloc,
- })
- }
- // Reached the end without finding the EOD marker.
- return b, locs, nil
-}
-
-// parseHeap parses a heapz legacy or a growthz profile and
-// returns a newly populated Profile.
-func parseHeap(b []byte) (p *Profile, err error) {
- r := bytes.NewBuffer(b)
- l, err := r.ReadString('\n')
- if err != nil {
- return nil, errUnrecognized
- }
-
- sampling := ""
-
- if header := heapHeaderRE.FindStringSubmatch(l); header != nil {
- p = &Profile{
- SampleType: []*ValueType{
- {Type: "objects", Unit: "count"},
- {Type: "space", Unit: "bytes"},
- },
- PeriodType: &ValueType{Type: "objects", Unit: "bytes"},
- }
-
- var period int64
- if len(header[6]) > 0 {
- if period, err = strconv.ParseInt(header[6], 10, 64); err != nil {
- return nil, errUnrecognized
- }
- }
-
- switch header[5] {
- case "heapz_v2", "heap_v2":
- sampling, p.Period = "v2", period
- case "heapprofile":
- sampling, p.Period = "", 1
- case "heap":
- sampling, p.Period = "v2", period/2
- default:
- return nil, errUnrecognized
- }
- } else if header = growthHeaderRE.FindStringSubmatch(l); header != nil {
- p = &Profile{
- SampleType: []*ValueType{
- {Type: "objects", Unit: "count"},
- {Type: "space", Unit: "bytes"},
- },
- PeriodType: &ValueType{Type: "heapgrowth", Unit: "count"},
- Period: 1,
- }
- } else if header = fragmentationHeaderRE.FindStringSubmatch(l); header != nil {
- p = &Profile{
- SampleType: []*ValueType{
- {Type: "objects", Unit: "count"},
- {Type: "space", Unit: "bytes"},
- },
- PeriodType: &ValueType{Type: "allocations", Unit: "count"},
- Period: 1,
- }
- } else {
- return nil, errUnrecognized
- }
-
- if LegacyHeapAllocated {
- for _, st := range p.SampleType {
- st.Type = "alloc_" + st.Type
- }
- } else {
- for _, st := range p.SampleType {
- st.Type = "inuse_" + st.Type
- }
- }
-
- locs := make(map[uint64]*Location)
- for {
- l, err = r.ReadString('\n')
- if err != nil {
- if err != io.EOF {
- return nil, err
- }
-
- if l == "" {
- break
- }
- }
-
- if isSpaceOrComment(l) {
- continue
- }
- l = strings.TrimSpace(l)
-
- if sectionTrigger(l) != unrecognizedSection {
- break
- }
-
- value, blocksize, addrs, err := parseHeapSample(l, p.Period, sampling)
- if err != nil {
- return nil, err
- }
- var sloc []*Location
- for _, addr := range addrs {
- // Addresses from stack traces point to the next instruction after
- // each call. Adjust by -1 to land somewhere on the actual call.
- addr--
- loc := locs[addr]
- if locs[addr] == nil {
- loc = &Location{
- Address: addr,
- }
- p.Location = append(p.Location, loc)
- locs[addr] = loc
- }
- sloc = append(sloc, loc)
- }
-
- p.Sample = append(p.Sample, &Sample{
- Value: value,
- Location: sloc,
- NumLabel: map[string][]int64{"bytes": {blocksize}},
- })
- }
-
- if err = parseAdditionalSections(l, r, p); err != nil {
- return nil, err
- }
- return p, nil
-}
-
-// parseHeapSample parses a single row from a heap profile into a new Sample.
-func parseHeapSample(line string, rate int64, sampling string) (value []int64, blocksize int64, addrs []uint64, err error) {
- sampleData := heapSampleRE.FindStringSubmatch(line)
- if len(sampleData) != 6 {
- return value, blocksize, addrs, fmt.Errorf("unexpected number of sample values: got %d, want 6", len(sampleData))
- }
-
- // Use first two values by default; tcmalloc sampling generates the
- // same value for both, only the older heap-profile collect separate
- // stats for in-use and allocated objects.
- valueIndex := 1
- if LegacyHeapAllocated {
- valueIndex = 3
- }
-
- var v1, v2 int64
- if v1, err = strconv.ParseInt(sampleData[valueIndex], 10, 64); err != nil {
- return value, blocksize, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
- }
- if v2, err = strconv.ParseInt(sampleData[valueIndex+1], 10, 64); err != nil {
- return value, blocksize, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
- }
-
- if v1 == 0 {
- if v2 != 0 {
- return value, blocksize, addrs, fmt.Errorf("allocation count was 0 but allocation bytes was %d", v2)
- }
- } else {
- blocksize = v2 / v1
- if sampling == "v2" {
- v1, v2 = scaleHeapSample(v1, v2, rate)
- }
- }
-
- value = []int64{v1, v2}
- addrs = parseHexAddresses(sampleData[5])
-
- return value, blocksize, addrs, nil
-}
-
-// extractHexAddresses extracts hex numbers from a string and returns
-// them, together with their numeric value, in a slice.
-func extractHexAddresses(s string) ([]string, []uint64) {
- hexStrings := hexNumberRE.FindAllString(s, -1)
- var ids []uint64
- for _, s := range hexStrings {
- if id, err := strconv.ParseUint(s, 0, 64); err == nil {
- ids = append(ids, id)
- } else {
- // Do not expect any parsing failures due to the regexp matching.
- panic("failed to parse hex value:" + s)
- }
- }
- return hexStrings, ids
-}
-
-// parseHexAddresses parses hex numbers from a string and returns them
-// in a slice.
-func parseHexAddresses(s string) []uint64 {
- _, ids := extractHexAddresses(s)
- return ids
-}
-
-// scaleHeapSample adjusts the data from a heapz Sample to
-// account for its probability of appearing in the collected
-// data. heapz profiles are a sampling of the memory allocations
-// requests in a program. We estimate the unsampled value by dividing
-// each collected sample by its probability of appearing in the
-// profile. heapz v2 profiles rely on a poisson process to determine
-// which samples to collect, based on the desired average collection
-// rate R. The probability of a sample of size S to appear in that
-// profile is 1-exp(-S/R).
-func scaleHeapSample(count, size, rate int64) (int64, int64) {
- if count == 0 || size == 0 {
- return 0, 0
- }
-
- if rate <= 1 {
- // if rate==1 all samples were collected so no adjustment is needed.
- // if rate<1 treat as unknown and skip scaling.
- return count, size
- }
-
- avgSize := float64(size) / float64(count)
- scale := 1 / (1 - math.Exp(-avgSize/float64(rate)))
-
- return int64(float64(count) * scale), int64(float64(size) * scale)
-}
-
-// parseContention parses a mutex or contention profile. There are 2 cases:
-// "--- contentionz " for legacy C++ profiles (and backwards compatibility)
-// "--- mutex:" or "--- contention:" for profiles generated by the Go runtime.
-// This code converts the text output from runtime into a *Profile. (In the future
-// the runtime might write a serialized Profile directly making this unnecessary.)
-func parseContention(b []byte) (*Profile, error) {
- r := bytes.NewBuffer(b)
- var l string
- var err error
- for {
- // Skip past comments and empty lines seeking a real header.
- l, err = r.ReadString('\n')
- if err != nil {
- return nil, err
- }
- if !isSpaceOrComment(l) {
- break
- }
- }
-
- if strings.HasPrefix(l, "--- contentionz ") {
- return parseCppContention(r)
- } else if strings.HasPrefix(l, "--- mutex:") {
- return parseCppContention(r)
- } else if strings.HasPrefix(l, "--- contention:") {
- return parseCppContention(r)
- }
- return nil, errUnrecognized
-}
-
-// parseCppContention parses the output from synchronization_profiling.cc
-// for backward compatibility, and the compatible (non-debug) block profile
-// output from the Go runtime.
-func parseCppContention(r *bytes.Buffer) (*Profile, error) {
- p := &Profile{
- PeriodType: &ValueType{Type: "contentions", Unit: "count"},
- Period: 1,
- SampleType: []*ValueType{
- {Type: "contentions", Unit: "count"},
- {Type: "delay", Unit: "nanoseconds"},
- },
- }
-
- var cpuHz int64
- var l string
- var err error
- // Parse text of the form "attribute = value" before the samples.
- const delimiter = '='
- for {
- l, err = r.ReadString('\n')
- if err != nil {
- if err != io.EOF {
- return nil, err
- }
-
- if l == "" {
- break
- }
- }
- if isSpaceOrComment(l) {
- continue
- }
-
- if l = strings.TrimSpace(l); l == "" {
- continue
- }
-
- if strings.HasPrefix(l, "---") {
- break
- }
-
- index := strings.IndexByte(l, delimiter)
- if index < 0 {
- break
- }
- key := l[:index]
- val := l[index+1:]
-
- key, val = strings.TrimSpace(key), strings.TrimSpace(val)
- var err error
- switch key {
- case "cycles/second":
- if cpuHz, err = strconv.ParseInt(val, 0, 64); err != nil {
- return nil, errUnrecognized
- }
- case "sampling period":
- if p.Period, err = strconv.ParseInt(val, 0, 64); err != nil {
- return nil, errUnrecognized
- }
- case "ms since reset":
- ms, err := strconv.ParseInt(val, 0, 64)
- if err != nil {
- return nil, errUnrecognized
- }
- p.DurationNanos = ms * 1000 * 1000
- case "format":
- // CPP contentionz profiles don't have format.
- return nil, errUnrecognized
- case "resolution":
- // CPP contentionz profiles don't have resolution.
- return nil, errUnrecognized
- case "discarded samples":
- default:
- return nil, errUnrecognized
- }
- }
-
- locs := make(map[uint64]*Location)
- for {
- if !isSpaceOrComment(l) {
- if l = strings.TrimSpace(l); strings.HasPrefix(l, "---") {
- break
- }
- value, addrs, err := parseContentionSample(l, p.Period, cpuHz)
- if err != nil {
- return nil, err
- }
- var sloc []*Location
- for _, addr := range addrs {
- // Addresses from stack traces point to the next instruction after
- // each call. Adjust by -1 to land somewhere on the actual call.
- addr--
- loc := locs[addr]
- if locs[addr] == nil {
- loc = &Location{
- Address: addr,
- }
- p.Location = append(p.Location, loc)
- locs[addr] = loc
- }
- sloc = append(sloc, loc)
- }
- p.Sample = append(p.Sample, &Sample{
- Value: value,
- Location: sloc,
- })
- }
-
- if l, err = r.ReadString('\n'); err != nil {
- if err != io.EOF {
- return nil, err
- }
- if l == "" {
- break
- }
- }
- }
-
- if err = parseAdditionalSections(l, r, p); err != nil {
- return nil, err
- }
-
- return p, nil
-}
-
-// parseContentionSample parses a single row from a contention profile
-// into a new Sample.
-func parseContentionSample(line string, period, cpuHz int64) (value []int64, addrs []uint64, err error) {
- sampleData := contentionSampleRE.FindStringSubmatch(line)
- if sampleData == nil {
- return value, addrs, errUnrecognized
- }
-
- v1, err := strconv.ParseInt(sampleData[1], 10, 64)
- if err != nil {
- return value, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
- }
- v2, err := strconv.ParseInt(sampleData[2], 10, 64)
- if err != nil {
- return value, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
- }
-
- // Unsample values if period and cpuHz are available.
- // - Delays are scaled to cycles and then to nanoseconds.
- // - Contentions are scaled to cycles.
- if period > 0 {
- if cpuHz > 0 {
- cpuGHz := float64(cpuHz) / 1e9
- v1 = int64(float64(v1) * float64(period) / cpuGHz)
- }
- v2 = v2 * period
- }
-
- value = []int64{v2, v1}
- addrs = parseHexAddresses(sampleData[3])
-
- return value, addrs, nil
-}
-
-// parseThread parses a Threadz profile and returns a new Profile.
-func parseThread(b []byte) (*Profile, error) {
- r := bytes.NewBuffer(b)
-
- var line string
- var err error
- for {
- // Skip past comments and empty lines seeking a real header.
- line, err = r.ReadString('\n')
- if err != nil {
- return nil, err
- }
- if !isSpaceOrComment(line) {
- break
- }
- }
-
- if m := threadzStartRE.FindStringSubmatch(line); m != nil {
- // Advance over initial comments until first stack trace.
- for {
- line, err = r.ReadString('\n')
- if err != nil {
- if err != io.EOF {
- return nil, err
- }
-
- if line == "" {
- break
- }
- }
- if sectionTrigger(line) != unrecognizedSection || line[0] == '-' {
- break
- }
- }
- } else if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 {
- return nil, errUnrecognized
- }
-
- p := &Profile{
- SampleType: []*ValueType{{Type: "thread", Unit: "count"}},
- PeriodType: &ValueType{Type: "thread", Unit: "count"},
- Period: 1,
- }
-
- locs := make(map[uint64]*Location)
- // Recognize each thread and populate profile samples.
- for sectionTrigger(line) == unrecognizedSection {
- if strings.HasPrefix(line, "---- no stack trace for") {
- line = ""
- break
- }
- if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 {
- return nil, errUnrecognized
- }
-
- var addrs []uint64
- line, addrs, err = parseThreadSample(r)
- if err != nil {
- return nil, errUnrecognized
- }
- if len(addrs) == 0 {
- // We got a --same as previous threads--. Bump counters.
- if len(p.Sample) > 0 {
- s := p.Sample[len(p.Sample)-1]
- s.Value[0]++
- }
- continue
- }
-
- var sloc []*Location
- for _, addr := range addrs {
- // Addresses from stack traces point to the next instruction after
- // each call. Adjust by -1 to land somewhere on the actual call.
- addr--
- loc := locs[addr]
- if locs[addr] == nil {
- loc = &Location{
- Address: addr,
- }
- p.Location = append(p.Location, loc)
- locs[addr] = loc
- }
- sloc = append(sloc, loc)
- }
-
- p.Sample = append(p.Sample, &Sample{
- Value: []int64{1},
- Location: sloc,
- })
- }
-
- if err = parseAdditionalSections(line, r, p); err != nil {
- return nil, err
- }
-
- return p, nil
-}
-
-// parseThreadSample parses a symbolized or unsymbolized stack trace.
-// Returns the first line after the traceback, the sample (or nil if
-// it hits a 'same-as-previous' marker) and an error.
-func parseThreadSample(b *bytes.Buffer) (nextl string, addrs []uint64, err error) {
- var l string
- sameAsPrevious := false
- for {
- if l, err = b.ReadString('\n'); err != nil {
- if err != io.EOF {
- return "", nil, err
- }
- if l == "" {
- break
- }
- }
- if l = strings.TrimSpace(l); l == "" {
- continue
- }
-
- if strings.HasPrefix(l, "---") {
- break
- }
- if strings.Contains(l, "same as previous thread") {
- sameAsPrevious = true
- continue
- }
-
- addrs = append(addrs, parseHexAddresses(l)...)
- }
-
- if sameAsPrevious {
- return l, nil, nil
- }
- return l, addrs, nil
-}
-
-// parseAdditionalSections parses any additional sections in the
-// profile, ignoring any unrecognized sections.
-func parseAdditionalSections(l string, b *bytes.Buffer, p *Profile) (err error) {
- for {
- if sectionTrigger(l) == memoryMapSection {
- break
- }
- // Ignore any unrecognized sections.
- if l, err := b.ReadString('\n'); err != nil {
- if err != io.EOF {
- return err
- }
- if l == "" {
- break
- }
- }
- }
- return p.ParseMemoryMap(b)
-}
-
-// ParseMemoryMap parses a memory map in the format of
-// /proc/self/maps, and overrides the mappings in the current profile.
-// It renumbers the samples and locations in the profile correspondingly.
-func (p *Profile) ParseMemoryMap(rd io.Reader) error {
- b := bufio.NewReader(rd)
-
- var attrs []string
- var r *strings.Replacer
- const delimiter = '='
- for {
- l, err := b.ReadString('\n')
- if err != nil {
- if err != io.EOF {
- return err
- }
- if l == "" {
- break
- }
- }
- if l = strings.TrimSpace(l); l == "" {
- continue
- }
-
- if r != nil {
- l = r.Replace(l)
- }
- m, err := parseMappingEntry(l)
- if err != nil {
- if err == errUnrecognized {
- // Recognize assignments of the form: attr=value, and replace
- // $attr with value on subsequent mappings.
- idx := strings.IndexByte(l, delimiter)
- if idx >= 0 {
- attr := l[:idx]
- value := l[idx+1:]
- attrs = append(attrs, "$"+strings.TrimSpace(attr), strings.TrimSpace(value))
- r = strings.NewReplacer(attrs...)
- }
- // Ignore any unrecognized entries
- continue
- }
- return err
- }
- if m == nil || (m.File == "" && len(p.Mapping) != 0) {
- // In some cases the first entry may include the address range
- // but not the name of the file. It should be followed by
- // another entry with the name.
- continue
- }
- if len(p.Mapping) == 1 && p.Mapping[0].File == "" {
- // Update the name if this is the entry following that empty one.
- p.Mapping[0].File = m.File
- continue
- }
- p.Mapping = append(p.Mapping, m)
- }
- p.remapLocationIDs()
- p.remapFunctionIDs()
- p.remapMappingIDs()
- return nil
-}
-
-func parseMappingEntry(l string) (*Mapping, error) {
- mapping := &Mapping{}
- var err error
- if me := procMapsRE.FindStringSubmatch(l); len(me) == 9 {
- if !strings.Contains(me[3], "x") {
- // Skip non-executable entries.
- return nil, nil
- }
- if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil {
- return nil, errUnrecognized
- }
- if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil {
- return nil, errUnrecognized
- }
- if me[4] != "" {
- if mapping.Offset, err = strconv.ParseUint(me[4], 16, 64); err != nil {
- return nil, errUnrecognized
- }
- }
- mapping.File = me[8]
- return mapping, nil
- }
-
- if me := briefMapsRE.FindStringSubmatch(l); len(me) == 6 {
- if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil {
- return nil, errUnrecognized
- }
- if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil {
- return nil, errUnrecognized
- }
- mapping.File = me[3]
- if me[5] != "" {
- if mapping.Offset, err = strconv.ParseUint(me[5], 16, 64); err != nil {
- return nil, errUnrecognized
- }
- }
- return mapping, nil
- }
-
- return nil, errUnrecognized
-}
-
-type sectionType int
-
-const (
- unrecognizedSection sectionType = iota
- memoryMapSection
-)
-
-var memoryMapTriggers = []string{
- "--- Memory map: ---",
- "MAPPED_LIBRARIES:",
-}
-
-func sectionTrigger(line string) sectionType {
- for _, trigger := range memoryMapTriggers {
- if strings.Contains(line, trigger) {
- return memoryMapSection
- }
- }
- return unrecognizedSection
-}
-
-func (p *Profile) addLegacyFrameInfo() {
- switch {
- case isProfileType(p, heapzSampleTypes) ||
- isProfileType(p, heapzInUseSampleTypes) ||
- isProfileType(p, heapzAllocSampleTypes):
- p.DropFrames, p.KeepFrames = allocRxStr, allocSkipRxStr
- case isProfileType(p, contentionzSampleTypes):
- p.DropFrames, p.KeepFrames = lockRxStr, ""
- default:
- p.DropFrames, p.KeepFrames = cpuProfilerRxStr, ""
- }
-}
-
-var heapzSampleTypes = []string{"allocations", "size"} // early Go pprof profiles
-var heapzInUseSampleTypes = []string{"inuse_objects", "inuse_space"}
-var heapzAllocSampleTypes = []string{"alloc_objects", "alloc_space"}
-var contentionzSampleTypes = []string{"contentions", "delay"}
-
-func isProfileType(p *Profile, t []string) bool {
- st := p.SampleType
- if len(st) != len(t) {
- return false
- }
-
- for i := range st {
- if st[i].Type != t[i] {
- return false
- }
- }
- return true
-}
-
-var allocRxStr = strings.Join([]string{
- // POSIX entry points.
- `calloc`,
- `cfree`,
- `malloc`,
- `free`,
- `memalign`,
- `do_memalign`,
- `(__)?posix_memalign`,
- `pvalloc`,
- `valloc`,
- `realloc`,
-
- // TC malloc.
- `tcmalloc::.*`,
- `tc_calloc`,
- `tc_cfree`,
- `tc_malloc`,
- `tc_free`,
- `tc_memalign`,
- `tc_posix_memalign`,
- `tc_pvalloc`,
- `tc_valloc`,
- `tc_realloc`,
- `tc_new`,
- `tc_delete`,
- `tc_newarray`,
- `tc_deletearray`,
- `tc_new_nothrow`,
- `tc_newarray_nothrow`,
-
- // Memory-allocation routines on OS X.
- `malloc_zone_malloc`,
- `malloc_zone_calloc`,
- `malloc_zone_valloc`,
- `malloc_zone_realloc`,
- `malloc_zone_memalign`,
- `malloc_zone_free`,
-
- // Go runtime
- `runtime\..*`,
-
- // Other misc. memory allocation routines
- `BaseArena::.*`,
- `(::)?do_malloc_no_errno`,
- `(::)?do_malloc_pages`,
- `(::)?do_malloc`,
- `DoSampledAllocation`,
- `MallocedMemBlock::MallocedMemBlock`,
- `_M_allocate`,
- `__builtin_(vec_)?delete`,
- `__builtin_(vec_)?new`,
- `__gnu_cxx::new_allocator::allocate`,
- `__libc_malloc`,
- `__malloc_alloc_template::allocate`,
- `allocate`,
- `cpp_alloc`,
- `operator new(\[\])?`,
- `simple_alloc::allocate`,
-}, `|`)
-
-var allocSkipRxStr = strings.Join([]string{
- // Preserve Go runtime frames that appear in the middle/bottom of
- // the stack.
- `runtime\.panic`,
- `runtime\.reflectcall`,
- `runtime\.call[0-9]*`,
-}, `|`)
-
-var cpuProfilerRxStr = strings.Join([]string{
- `ProfileData::Add`,
- `ProfileData::prof_handler`,
- `CpuProfiler::prof_handler`,
- `__pthread_sighandler`,
- `__restore`,
-}, `|`)
-
-var lockRxStr = strings.Join([]string{
- `RecordLockProfileData`,
- `(base::)?RecordLockProfileData.*`,
- `(base::)?SubmitMutexProfileData.*`,
- `(base::)?SubmitSpinLockProfileData.*`,
- `(Mutex::)?AwaitCommon.*`,
- `(Mutex::)?Unlock.*`,
- `(Mutex::)?UnlockSlow.*`,
- `(Mutex::)?ReaderUnlock.*`,
- `(MutexLock::)?~MutexLock.*`,
- `(SpinLock::)?Unlock.*`,
- `(SpinLock::)?SlowUnlock.*`,
- `(SpinLockHolder::)?~SpinLockHolder.*`,
-}, `|`)
diff --git a/contrib/go/_std_1.20/src/internal/profile/profile.go b/contrib/go/_std_1.20/src/internal/profile/profile.go
deleted file mode 100644
index 29568aa4b5..0000000000
--- a/contrib/go/_std_1.20/src/internal/profile/profile.go
+++ /dev/null
@@ -1,613 +0,0 @@
-// Copyright 2014 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 profile provides a representation of
-// github.com/google/pprof/proto/profile.proto and
-// methods to encode/decode/merge profiles in this format.
-package profile
-
-import (
- "bytes"
- "compress/gzip"
- "fmt"
- "io"
- "regexp"
- "strings"
- "time"
-)
-
-// Profile is an in-memory representation of profile.proto.
-type Profile struct {
- SampleType []*ValueType
- DefaultSampleType string
- Sample []*Sample
- Mapping []*Mapping
- Location []*Location
- Function []*Function
- Comments []string
-
- DropFrames string
- KeepFrames string
-
- TimeNanos int64
- DurationNanos int64
- PeriodType *ValueType
- Period int64
-
- commentX []int64
- dropFramesX int64
- keepFramesX int64
- stringTable []string
- defaultSampleTypeX int64
-}
-
-// ValueType corresponds to Profile.ValueType
-type ValueType struct {
- Type string // cpu, wall, inuse_space, etc
- Unit string // seconds, nanoseconds, bytes, etc
-
- typeX int64
- unitX int64
-}
-
-// Sample corresponds to Profile.Sample
-type Sample struct {
- Location []*Location
- Value []int64
- Label map[string][]string
- NumLabel map[string][]int64
- NumUnit map[string][]string
-
- locationIDX []uint64
- labelX []Label
-}
-
-// Label corresponds to Profile.Label
-type Label struct {
- keyX int64
- // Exactly one of the two following values must be set
- strX int64
- numX int64 // Integer value for this label
-}
-
-// Mapping corresponds to Profile.Mapping
-type Mapping struct {
- ID uint64
- Start uint64
- Limit uint64
- Offset uint64
- File string
- BuildID string
- HasFunctions bool
- HasFilenames bool
- HasLineNumbers bool
- HasInlineFrames bool
-
- fileX int64
- buildIDX int64
-}
-
-// Location corresponds to Profile.Location
-type Location struct {
- ID uint64
- Mapping *Mapping
- Address uint64
- Line []Line
- IsFolded bool
-
- mappingIDX uint64
-}
-
-// Line corresponds to Profile.Line
-type Line struct {
- Function *Function
- Line int64
-
- functionIDX uint64
-}
-
-// Function corresponds to Profile.Function
-type Function struct {
- ID uint64
- Name string
- SystemName string
- Filename string
- StartLine int64
-
- nameX int64
- systemNameX int64
- filenameX int64
-}
-
-// Parse parses a profile and checks for its validity. The input
-// may be a gzip-compressed encoded protobuf or one of many legacy
-// profile formats which may be unsupported in the future.
-func Parse(r io.Reader) (*Profile, error) {
- orig, err := io.ReadAll(r)
- if err != nil {
- return nil, err
- }
-
- var p *Profile
- if len(orig) >= 2 && orig[0] == 0x1f && orig[1] == 0x8b {
- gz, err := gzip.NewReader(bytes.NewBuffer(orig))
- if err != nil {
- return nil, fmt.Errorf("decompressing profile: %v", err)
- }
- data, err := io.ReadAll(gz)
- if err != nil {
- return nil, fmt.Errorf("decompressing profile: %v", err)
- }
- orig = data
- }
- if p, err = parseUncompressed(orig); err != nil {
- if p, err = parseLegacy(orig); err != nil {
- return nil, fmt.Errorf("parsing profile: %v", err)
- }
- }
-
- if err := p.CheckValid(); err != nil {
- return nil, fmt.Errorf("malformed profile: %v", err)
- }
- return p, nil
-}
-
-var errUnrecognized = fmt.Errorf("unrecognized profile format")
-var errMalformed = fmt.Errorf("malformed profile format")
-
-func parseLegacy(data []byte) (*Profile, error) {
- parsers := []func([]byte) (*Profile, error){
- parseCPU,
- parseHeap,
- parseGoCount, // goroutine, threadcreate
- parseThread,
- parseContention,
- }
-
- for _, parser := range parsers {
- p, err := parser(data)
- if err == nil {
- p.setMain()
- p.addLegacyFrameInfo()
- return p, nil
- }
- if err != errUnrecognized {
- return nil, err
- }
- }
- return nil, errUnrecognized
-}
-
-func parseUncompressed(data []byte) (*Profile, error) {
- p := &Profile{}
- if err := unmarshal(data, p); err != nil {
- return nil, err
- }
-
- if err := p.postDecode(); err != nil {
- return nil, err
- }
-
- return p, nil
-}
-
-var libRx = regexp.MustCompile(`([.]so$|[.]so[._][0-9]+)`)
-
-// setMain scans Mapping entries and guesses which entry is main
-// because legacy profiles don't obey the convention of putting main
-// first.
-func (p *Profile) setMain() {
- for i := 0; i < len(p.Mapping); i++ {
- file := strings.TrimSpace(strings.ReplaceAll(p.Mapping[i].File, "(deleted)", ""))
- if len(file) == 0 {
- continue
- }
- if len(libRx.FindStringSubmatch(file)) > 0 {
- continue
- }
- if strings.HasPrefix(file, "[") {
- continue
- }
- // Swap what we guess is main to position 0.
- p.Mapping[i], p.Mapping[0] = p.Mapping[0], p.Mapping[i]
- break
- }
-}
-
-// Write writes the profile as a gzip-compressed marshaled protobuf.
-func (p *Profile) Write(w io.Writer) error {
- p.preEncode()
- b := marshal(p)
- zw := gzip.NewWriter(w)
- defer zw.Close()
- _, err := zw.Write(b)
- return err
-}
-
-// CheckValid tests whether the profile is valid. Checks include, but are
-// not limited to:
-// - len(Profile.Sample[n].value) == len(Profile.value_unit)
-// - Sample.id has a corresponding Profile.Location
-func (p *Profile) CheckValid() error {
- // Check that sample values are consistent
- sampleLen := len(p.SampleType)
- if sampleLen == 0 && len(p.Sample) != 0 {
- return fmt.Errorf("missing sample type information")
- }
- for _, s := range p.Sample {
- if len(s.Value) != sampleLen {
- return fmt.Errorf("mismatch: sample has: %d values vs. %d types", len(s.Value), len(p.SampleType))
- }
- }
-
- // Check that all mappings/locations/functions are in the tables
- // Check that there are no duplicate ids
- mappings := make(map[uint64]*Mapping, len(p.Mapping))
- for _, m := range p.Mapping {
- if m.ID == 0 {
- return fmt.Errorf("found mapping with reserved ID=0")
- }
- if mappings[m.ID] != nil {
- return fmt.Errorf("multiple mappings with same id: %d", m.ID)
- }
- mappings[m.ID] = m
- }
- functions := make(map[uint64]*Function, len(p.Function))
- for _, f := range p.Function {
- if f.ID == 0 {
- return fmt.Errorf("found function with reserved ID=0")
- }
- if functions[f.ID] != nil {
- return fmt.Errorf("multiple functions with same id: %d", f.ID)
- }
- functions[f.ID] = f
- }
- locations := make(map[uint64]*Location, len(p.Location))
- for _, l := range p.Location {
- if l.ID == 0 {
- return fmt.Errorf("found location with reserved id=0")
- }
- if locations[l.ID] != nil {
- return fmt.Errorf("multiple locations with same id: %d", l.ID)
- }
- locations[l.ID] = l
- if m := l.Mapping; m != nil {
- if m.ID == 0 || mappings[m.ID] != m {
- return fmt.Errorf("inconsistent mapping %p: %d", m, m.ID)
- }
- }
- for _, ln := range l.Line {
- if f := ln.Function; f != nil {
- if f.ID == 0 || functions[f.ID] != f {
- return fmt.Errorf("inconsistent function %p: %d", f, f.ID)
- }
- }
- }
- }
- return nil
-}
-
-// Aggregate merges the locations in the profile into equivalence
-// classes preserving the request attributes. It also updates the
-// samples to point to the merged locations.
-func (p *Profile) Aggregate(inlineFrame, function, filename, linenumber, address bool) error {
- for _, m := range p.Mapping {
- m.HasInlineFrames = m.HasInlineFrames && inlineFrame
- m.HasFunctions = m.HasFunctions && function
- m.HasFilenames = m.HasFilenames && filename
- m.HasLineNumbers = m.HasLineNumbers && linenumber
- }
-
- // Aggregate functions
- if !function || !filename {
- for _, f := range p.Function {
- if !function {
- f.Name = ""
- f.SystemName = ""
- }
- if !filename {
- f.Filename = ""
- }
- }
- }
-
- // Aggregate locations
- if !inlineFrame || !address || !linenumber {
- for _, l := range p.Location {
- if !inlineFrame && len(l.Line) > 1 {
- l.Line = l.Line[len(l.Line)-1:]
- }
- if !linenumber {
- for i := range l.Line {
- l.Line[i].Line = 0
- }
- }
- if !address {
- l.Address = 0
- }
- }
- }
-
- return p.CheckValid()
-}
-
-// Print dumps a text representation of a profile. Intended mainly
-// for debugging purposes.
-func (p *Profile) String() string {
-
- ss := make([]string, 0, len(p.Sample)+len(p.Mapping)+len(p.Location))
- if pt := p.PeriodType; pt != nil {
- ss = append(ss, fmt.Sprintf("PeriodType: %s %s", pt.Type, pt.Unit))
- }
- ss = append(ss, fmt.Sprintf("Period: %d", p.Period))
- if p.TimeNanos != 0 {
- ss = append(ss, fmt.Sprintf("Time: %v", time.Unix(0, p.TimeNanos)))
- }
- if p.DurationNanos != 0 {
- ss = append(ss, fmt.Sprintf("Duration: %v", time.Duration(p.DurationNanos)))
- }
-
- ss = append(ss, "Samples:")
- var sh1 string
- for _, s := range p.SampleType {
- sh1 = sh1 + fmt.Sprintf("%s/%s ", s.Type, s.Unit)
- }
- ss = append(ss, strings.TrimSpace(sh1))
- for _, s := range p.Sample {
- var sv string
- for _, v := range s.Value {
- sv = fmt.Sprintf("%s %10d", sv, v)
- }
- sv = sv + ": "
- for _, l := range s.Location {
- sv = sv + fmt.Sprintf("%d ", l.ID)
- }
- ss = append(ss, sv)
- const labelHeader = " "
- if len(s.Label) > 0 {
- ls := labelHeader
- for k, v := range s.Label {
- ls = ls + fmt.Sprintf("%s:%v ", k, v)
- }
- ss = append(ss, ls)
- }
- if len(s.NumLabel) > 0 {
- ls := labelHeader
- for k, v := range s.NumLabel {
- ls = ls + fmt.Sprintf("%s:%v ", k, v)
- }
- ss = append(ss, ls)
- }
- }
-
- ss = append(ss, "Locations")
- for _, l := range p.Location {
- locStr := fmt.Sprintf("%6d: %#x ", l.ID, l.Address)
- if m := l.Mapping; m != nil {
- locStr = locStr + fmt.Sprintf("M=%d ", m.ID)
- }
- if len(l.Line) == 0 {
- ss = append(ss, locStr)
- }
- for li := range l.Line {
- lnStr := "??"
- if fn := l.Line[li].Function; fn != nil {
- lnStr = fmt.Sprintf("%s %s:%d s=%d",
- fn.Name,
- fn.Filename,
- l.Line[li].Line,
- fn.StartLine)
- if fn.Name != fn.SystemName {
- lnStr = lnStr + "(" + fn.SystemName + ")"
- }
- }
- ss = append(ss, locStr+lnStr)
- // Do not print location details past the first line
- locStr = " "
- }
- }
-
- ss = append(ss, "Mappings")
- for _, m := range p.Mapping {
- bits := ""
- if m.HasFunctions {
- bits += "[FN]"
- }
- if m.HasFilenames {
- bits += "[FL]"
- }
- if m.HasLineNumbers {
- bits += "[LN]"
- }
- if m.HasInlineFrames {
- bits += "[IN]"
- }
- ss = append(ss, fmt.Sprintf("%d: %#x/%#x/%#x %s %s %s",
- m.ID,
- m.Start, m.Limit, m.Offset,
- m.File,
- m.BuildID,
- bits))
- }
-
- return strings.Join(ss, "\n") + "\n"
-}
-
-// Merge adds profile p adjusted by ratio r into profile p. Profiles
-// must be compatible (same Type and SampleType).
-// TODO(rsilvera): consider normalizing the profiles based on the
-// total samples collected.
-func (p *Profile) Merge(pb *Profile, r float64) error {
- if err := p.Compatible(pb); err != nil {
- return err
- }
-
- pb = pb.Copy()
-
- // Keep the largest of the two periods.
- if pb.Period > p.Period {
- p.Period = pb.Period
- }
-
- p.DurationNanos += pb.DurationNanos
-
- p.Mapping = append(p.Mapping, pb.Mapping...)
- for i, m := range p.Mapping {
- m.ID = uint64(i + 1)
- }
- p.Location = append(p.Location, pb.Location...)
- for i, l := range p.Location {
- l.ID = uint64(i + 1)
- }
- p.Function = append(p.Function, pb.Function...)
- for i, f := range p.Function {
- f.ID = uint64(i + 1)
- }
-
- if r != 1.0 {
- for _, s := range pb.Sample {
- for i, v := range s.Value {
- s.Value[i] = int64((float64(v) * r))
- }
- }
- }
- p.Sample = append(p.Sample, pb.Sample...)
- return p.CheckValid()
-}
-
-// Compatible determines if two profiles can be compared/merged.
-// returns nil if the profiles are compatible; otherwise an error with
-// details on the incompatibility.
-func (p *Profile) Compatible(pb *Profile) error {
- if !compatibleValueTypes(p.PeriodType, pb.PeriodType) {
- return fmt.Errorf("incompatible period types %v and %v", p.PeriodType, pb.PeriodType)
- }
-
- if len(p.SampleType) != len(pb.SampleType) {
- return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType)
- }
-
- for i := range p.SampleType {
- if !compatibleValueTypes(p.SampleType[i], pb.SampleType[i]) {
- return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType)
- }
- }
-
- return nil
-}
-
-// HasFunctions determines if all locations in this profile have
-// symbolized function information.
-func (p *Profile) HasFunctions() bool {
- for _, l := range p.Location {
- if l.Mapping == nil || !l.Mapping.HasFunctions {
- return false
- }
- }
- return true
-}
-
-// HasFileLines determines if all locations in this profile have
-// symbolized file and line number information.
-func (p *Profile) HasFileLines() bool {
- for _, l := range p.Location {
- if l.Mapping == nil || (!l.Mapping.HasFilenames || !l.Mapping.HasLineNumbers) {
- return false
- }
- }
- return true
-}
-
-func compatibleValueTypes(v1, v2 *ValueType) bool {
- if v1 == nil || v2 == nil {
- return true // No grounds to disqualify.
- }
- return v1.Type == v2.Type && v1.Unit == v2.Unit
-}
-
-// Copy makes a fully independent copy of a profile.
-func (p *Profile) Copy() *Profile {
- p.preEncode()
- b := marshal(p)
-
- pp := &Profile{}
- if err := unmarshal(b, pp); err != nil {
- panic(err)
- }
- if err := pp.postDecode(); err != nil {
- panic(err)
- }
-
- return pp
-}
-
-// Demangler maps symbol names to a human-readable form. This may
-// include C++ demangling and additional simplification. Names that
-// are not demangled may be missing from the resulting map.
-type Demangler func(name []string) (map[string]string, error)
-
-// Demangle attempts to demangle and optionally simplify any function
-// names referenced in the profile. It works on a best-effort basis:
-// it will silently preserve the original names in case of any errors.
-func (p *Profile) Demangle(d Demangler) error {
- // Collect names to demangle.
- var names []string
- for _, fn := range p.Function {
- names = append(names, fn.SystemName)
- }
-
- // Update profile with demangled names.
- demangled, err := d(names)
- if err != nil {
- return err
- }
- for _, fn := range p.Function {
- if dd, ok := demangled[fn.SystemName]; ok {
- fn.Name = dd
- }
- }
- return nil
-}
-
-// Empty reports whether the profile contains no samples.
-func (p *Profile) Empty() bool {
- return len(p.Sample) == 0
-}
-
-// Scale multiplies all sample values in a profile by a constant.
-func (p *Profile) Scale(ratio float64) {
- if ratio == 1 {
- return
- }
- ratios := make([]float64, len(p.SampleType))
- for i := range p.SampleType {
- ratios[i] = ratio
- }
- p.ScaleN(ratios)
-}
-
-// ScaleN multiplies each sample values in a sample by a different amount.
-func (p *Profile) ScaleN(ratios []float64) error {
- if len(p.SampleType) != len(ratios) {
- return fmt.Errorf("mismatched scale ratios, got %d, want %d", len(ratios), len(p.SampleType))
- }
- allOnes := true
- for _, r := range ratios {
- if r != 1 {
- allOnes = false
- break
- }
- }
- if allOnes {
- return nil
- }
- for _, s := range p.Sample {
- for i, v := range s.Value {
- if ratios[i] != 1 {
- s.Value[i] = int64(float64(v) * ratios[i])
- }
- }
- }
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/profile/ya.make b/contrib/go/_std_1.20/src/internal/profile/ya.make
deleted file mode 100644
index 3074ea06c3..0000000000
--- a/contrib/go/_std_1.20/src/internal/profile/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- encode.go
- filter.go
- legacy_profile.go
- merge.go
- profile.go
- proto.go
- prune.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/race/ya.make b/contrib/go/_std_1.20/src/internal/race/ya.make
deleted file mode 100644
index e7b39e2415..0000000000
--- a/contrib/go/_std_1.20/src/internal/race/ya.make
+++ /dev/null
@@ -1,23 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- doc.go
-)
-
-IF (RACE)
- IF (CGO_ENABLED OR OS_DARWIN)
- SRCS(
- race.go
- )
- ELSE()
- SRCS(
- norace.go
- )
- ENDIF()
-ELSE()
- SRCS(
- norace.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/reflectlite/swapper.go b/contrib/go/_std_1.20/src/internal/reflectlite/swapper.go
deleted file mode 100644
index fc402bb38a..0000000000
--- a/contrib/go/_std_1.20/src/internal/reflectlite/swapper.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2016 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 reflectlite
-
-import (
- "internal/goarch"
- "internal/unsafeheader"
- "unsafe"
-)
-
-// Swapper returns a function that swaps the elements in the provided
-// slice.
-//
-// Swapper panics if the provided interface is not a slice.
-func Swapper(slice any) func(i, j int) {
- v := ValueOf(slice)
- if v.Kind() != Slice {
- panic(&ValueError{Method: "Swapper", Kind: v.Kind()})
- }
- // Fast path for slices of size 0 and 1. Nothing to swap.
- switch v.Len() {
- case 0:
- return func(i, j int) { panic("reflect: slice index out of range") }
- case 1:
- return func(i, j int) {
- if i != 0 || j != 0 {
- panic("reflect: slice index out of range")
- }
- }
- }
-
- typ := v.Type().Elem().(*rtype)
- size := typ.Size()
- hasPtr := typ.ptrdata != 0
-
- // Some common & small cases, without using memmove:
- if hasPtr {
- if size == goarch.PtrSize {
- ps := *(*[]unsafe.Pointer)(v.ptr)
- return func(i, j int) { ps[i], ps[j] = ps[j], ps[i] }
- }
- if typ.Kind() == String {
- ss := *(*[]string)(v.ptr)
- return func(i, j int) { ss[i], ss[j] = ss[j], ss[i] }
- }
- } else {
- switch size {
- case 8:
- is := *(*[]int64)(v.ptr)
- return func(i, j int) { is[i], is[j] = is[j], is[i] }
- case 4:
- is := *(*[]int32)(v.ptr)
- return func(i, j int) { is[i], is[j] = is[j], is[i] }
- case 2:
- is := *(*[]int16)(v.ptr)
- return func(i, j int) { is[i], is[j] = is[j], is[i] }
- case 1:
- is := *(*[]int8)(v.ptr)
- return func(i, j int) { is[i], is[j] = is[j], is[i] }
- }
- }
-
- s := (*unsafeheader.Slice)(v.ptr)
- tmp := unsafe_New(typ) // swap scratch space
-
- return func(i, j int) {
- if uint(i) >= uint(s.Len) || uint(j) >= uint(s.Len) {
- panic("reflect: slice index out of range")
- }
- val1 := arrayAt(s.Data, i, size, "i < s.Len")
- val2 := arrayAt(s.Data, j, size, "j < s.Len")
- typedmemmove(typ, tmp, val1)
- typedmemmove(typ, val1, val2)
- typedmemmove(typ, val2, tmp)
- }
-}
diff --git a/contrib/go/_std_1.20/src/internal/reflectlite/type.go b/contrib/go/_std_1.20/src/internal/reflectlite/type.go
deleted file mode 100644
index 43440b1126..0000000000
--- a/contrib/go/_std_1.20/src/internal/reflectlite/type.go
+++ /dev/null
@@ -1,974 +0,0 @@
-// Copyright 2009 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 reflectlite implements lightweight version of reflect, not using
-// any package except for "runtime" and "unsafe".
-package reflectlite
-
-import "unsafe"
-
-// Type is the representation of a Go type.
-//
-// Not all methods apply to all kinds of types. Restrictions,
-// if any, are noted in the documentation for each method.
-// Use the Kind method to find out the kind of type before
-// calling kind-specific methods. Calling a method
-// inappropriate to the kind of type causes a run-time panic.
-//
-// Type values are comparable, such as with the == operator,
-// so they can be used as map keys.
-// Two Type values are equal if they represent identical types.
-type Type interface {
- // Methods applicable to all types.
-
- // Name returns the type's name within its package for a defined type.
- // For other (non-defined) types it returns the empty string.
- Name() string
-
- // PkgPath returns a defined type's package path, that is, the import path
- // that uniquely identifies the package, such as "encoding/base64".
- // If the type was predeclared (string, error) or not defined (*T, struct{},
- // []int, or A where A is an alias for a non-defined type), the package path
- // will be the empty string.
- PkgPath() string
-
- // Size returns the number of bytes needed to store
- // a value of the given type; it is analogous to unsafe.Sizeof.
- Size() uintptr
-
- // Kind returns the specific kind of this type.
- Kind() Kind
-
- // Implements reports whether the type implements the interface type u.
- Implements(u Type) bool
-
- // AssignableTo reports whether a value of the type is assignable to type u.
- AssignableTo(u Type) bool
-
- // Comparable reports whether values of this type are comparable.
- Comparable() bool
-
- // String returns a string representation of the type.
- // The string representation may use shortened package names
- // (e.g., base64 instead of "encoding/base64") and is not
- // guaranteed to be unique among types. To test for type identity,
- // compare the Types directly.
- String() string
-
- // Elem returns a type's element type.
- // It panics if the type's Kind is not Ptr.
- Elem() Type
-
- common() *rtype
- uncommon() *uncommonType
-}
-
-/*
- * These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go).
- * A few are known to ../runtime/type.go to convey to debuggers.
- * They are also known to ../runtime/type.go.
- */
-
-// A Kind represents the specific kind of type that a Type represents.
-// The zero Kind is not a valid kind.
-type Kind uint
-
-const (
- Invalid Kind = iota
- Bool
- Int
- Int8
- Int16
- Int32
- Int64
- Uint
- Uint8
- Uint16
- Uint32
- Uint64
- Uintptr
- Float32
- Float64
- Complex64
- Complex128
- Array
- Chan
- Func
- Interface
- Map
- Pointer
- Slice
- String
- Struct
- UnsafePointer
-)
-
-const Ptr = Pointer
-
-// tflag is used by an rtype to signal what extra type information is
-// available in the memory directly following the rtype value.
-//
-// tflag values must be kept in sync with copies in:
-//
-// cmd/compile/internal/reflectdata/reflect.go
-// cmd/link/internal/ld/decodesym.go
-// runtime/type.go
-type tflag uint8
-
-const (
- // tflagUncommon means that there is a pointer, *uncommonType,
- // just beyond the outer type structure.
- //
- // For example, if t.Kind() == Struct and t.tflag&tflagUncommon != 0,
- // then t has uncommonType data and it can be accessed as:
- //
- // type tUncommon struct {
- // structType
- // u uncommonType
- // }
- // u := &(*tUncommon)(unsafe.Pointer(t)).u
- tflagUncommon tflag = 1 << 0
-
- // tflagExtraStar means the name in the str field has an
- // extraneous '*' prefix. This is because for most types T in
- // a program, the type *T also exists and reusing the str data
- // saves binary size.
- tflagExtraStar tflag = 1 << 1
-
- // tflagNamed means the type has a name.
- tflagNamed tflag = 1 << 2
-
- // tflagRegularMemory means that equal and hash functions can treat
- // this type as a single region of t.size bytes.
- tflagRegularMemory tflag = 1 << 3
-)
-
-// rtype is the common implementation of most values.
-// It is embedded in other struct types.
-//
-// rtype must be kept in sync with ../runtime/type.go:/^type._type.
-type rtype struct {
- size uintptr
- ptrdata uintptr // number of bytes in the type that can contain pointers
- hash uint32 // hash of type; avoids computation in hash tables
- tflag tflag // extra type information flags
- align uint8 // alignment of variable with this type
- fieldAlign uint8 // alignment of struct field with this type
- kind uint8 // enumeration for C
- // function for comparing objects of this type
- // (ptr to object A, ptr to object B) -> ==?
- equal func(unsafe.Pointer, unsafe.Pointer) bool
- gcdata *byte // garbage collection data
- str nameOff // string form
- ptrToThis typeOff // type for pointer to this type, may be zero
-}
-
-// Method on non-interface type
-type method struct {
- name nameOff // name of method
- mtyp typeOff // method type (without receiver)
- ifn textOff // fn used in interface call (one-word receiver)
- tfn textOff // fn used for normal method call
-}
-
-// uncommonType is present only for defined types or types with methods
-// (if T is a defined type, the uncommonTypes for T and *T have methods).
-// Using a pointer to this struct reduces the overall size required
-// to describe a non-defined type with no methods.
-type uncommonType struct {
- pkgPath nameOff // import path; empty for built-in types like int, string
- mcount uint16 // number of methods
- xcount uint16 // number of exported methods
- moff uint32 // offset from this uncommontype to [mcount]method
- _ uint32 // unused
-}
-
-// chanDir represents a channel type's direction.
-type chanDir int
-
-const (
- recvDir chanDir = 1 << iota // <-chan
- sendDir // chan<-
- bothDir = recvDir | sendDir // chan
-)
-
-// arrayType represents a fixed array type.
-type arrayType struct {
- rtype
- elem *rtype // array element type
- slice *rtype // slice type
- len uintptr
-}
-
-// chanType represents a channel type.
-type chanType struct {
- rtype
- elem *rtype // channel element type
- dir uintptr // channel direction (chanDir)
-}
-
-// funcType represents a function type.
-//
-// A *rtype for each in and out parameter is stored in an array that
-// directly follows the funcType (and possibly its uncommonType). So
-// a function type with one method, one input, and one output is:
-//
-// struct {
-// funcType
-// uncommonType
-// [2]*rtype // [0] is in, [1] is out
-// }
-type funcType struct {
- rtype
- inCount uint16
- outCount uint16 // top bit is set if last input parameter is ...
-}
-
-// imethod represents a method on an interface type
-type imethod struct {
- name nameOff // name of method
- typ typeOff // .(*FuncType) underneath
-}
-
-// interfaceType represents an interface type.
-type interfaceType struct {
- rtype
- pkgPath name // import path
- methods []imethod // sorted by hash
-}
-
-// mapType represents a map type.
-type mapType struct {
- rtype
- key *rtype // map key type
- elem *rtype // map element (value) type
- bucket *rtype // internal bucket structure
- // function for hashing keys (ptr to key, seed) -> hash
- hasher func(unsafe.Pointer, uintptr) uintptr
- keysize uint8 // size of key slot
- valuesize uint8 // size of value slot
- bucketsize uint16 // size of bucket
- flags uint32
-}
-
-// ptrType represents a pointer type.
-type ptrType struct {
- rtype
- elem *rtype // pointer element (pointed at) type
-}
-
-// sliceType represents a slice type.
-type sliceType struct {
- rtype
- elem *rtype // slice element type
-}
-
-// Struct field
-type structField struct {
- name name // name is always non-empty
- typ *rtype // type of field
- offset uintptr // byte offset of field
-}
-
-func (f *structField) embedded() bool {
- return f.name.embedded()
-}
-
-// structType represents a struct type.
-type structType struct {
- rtype
- pkgPath name
- fields []structField // sorted by offset
-}
-
-// name is an encoded type name with optional extra data.
-//
-// The first byte is a bit field containing:
-//
-// 1<<0 the name is exported
-// 1<<1 tag data follows the name
-// 1<<2 pkgPath nameOff follows the name and tag
-//
-// The next two bytes are the data length:
-//
-// l := uint16(data[1])<<8 | uint16(data[2])
-//
-// Bytes [3:3+l] are the string data.
-//
-// If tag data follows then bytes 3+l and 3+l+1 are the tag length,
-// with the data following.
-//
-// If the import path follows, then 4 bytes at the end of
-// the data form a nameOff. The import path is only set for concrete
-// methods that are defined in a different package than their type.
-//
-// If a name starts with "*", then the exported bit represents
-// whether the pointed to type is exported.
-type name struct {
- bytes *byte
-}
-
-func (n name) data(off int, whySafe string) *byte {
- return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe))
-}
-
-func (n name) isExported() bool {
- return (*n.bytes)&(1<<0) != 0
-}
-
-func (n name) hasTag() bool {
- return (*n.bytes)&(1<<1) != 0
-}
-
-func (n name) embedded() bool {
- return (*n.bytes)&(1<<3) != 0
-}
-
-// readVarint parses a varint as encoded by encoding/binary.
-// It returns the number of encoded bytes and the encoded value.
-func (n name) readVarint(off int) (int, int) {
- v := 0
- for i := 0; ; i++ {
- x := *n.data(off+i, "read varint")
- v += int(x&0x7f) << (7 * i)
- if x&0x80 == 0 {
- return i + 1, v
- }
- }
-}
-
-func (n name) name() string {
- if n.bytes == nil {
- return ""
- }
- i, l := n.readVarint(1)
- return unsafe.String(n.data(1+i, "non-empty string"), l)
-}
-
-func (n name) tag() string {
- if !n.hasTag() {
- return ""
- }
- i, l := n.readVarint(1)
- i2, l2 := n.readVarint(1 + i + l)
- return unsafe.String(n.data(1+i+l+i2, "non-empty string"), l2)
-}
-
-func (n name) pkgPath() string {
- if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 {
- return ""
- }
- i, l := n.readVarint(1)
- off := 1 + i + l
- if n.hasTag() {
- i2, l2 := n.readVarint(off)
- off += i2 + l2
- }
- var nameOff int32
- // Note that this field may not be aligned in memory,
- // so we cannot use a direct int32 assignment here.
- copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:])
- pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))}
- return pkgPathName.name()
-}
-
-/*
- * The compiler knows the exact layout of all the data structures above.
- * The compiler does not know about the data structures and methods below.
- */
-
-const (
- kindDirectIface = 1 << 5
- kindGCProg = 1 << 6 // Type.gc points to GC program
- kindMask = (1 << 5) - 1
-)
-
-// String returns the name of k.
-func (k Kind) String() string {
- if int(k) < len(kindNames) {
- return kindNames[k]
- }
- return kindNames[0]
-}
-
-var kindNames = []string{
- Invalid: "invalid",
- Bool: "bool",
- Int: "int",
- Int8: "int8",
- Int16: "int16",
- Int32: "int32",
- Int64: "int64",
- Uint: "uint",
- Uint8: "uint8",
- Uint16: "uint16",
- Uint32: "uint32",
- Uint64: "uint64",
- Uintptr: "uintptr",
- Float32: "float32",
- Float64: "float64",
- Complex64: "complex64",
- Complex128: "complex128",
- Array: "array",
- Chan: "chan",
- Func: "func",
- Interface: "interface",
- Map: "map",
- Ptr: "ptr",
- Slice: "slice",
- String: "string",
- Struct: "struct",
- UnsafePointer: "unsafe.Pointer",
-}
-
-func (t *uncommonType) methods() []method {
- if t.mcount == 0 {
- return nil
- }
- return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount]
-}
-
-func (t *uncommonType) exportedMethods() []method {
- if t.xcount == 0 {
- return nil
- }
- return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount]
-}
-
-// resolveNameOff resolves a name offset from a base pointer.
-// The (*rtype).nameOff method is a convenience wrapper for this function.
-// Implemented in the runtime package.
-func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
-
-// resolveTypeOff resolves an *rtype offset from a base type.
-// The (*rtype).typeOff method is a convenience wrapper for this function.
-// Implemented in the runtime package.
-func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
-
-type nameOff int32 // offset to a name
-type typeOff int32 // offset to an *rtype
-type textOff int32 // offset from top of text section
-
-func (t *rtype) nameOff(off nameOff) name {
- return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
-}
-
-func (t *rtype) typeOff(off typeOff) *rtype {
- return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off)))
-}
-
-func (t *rtype) uncommon() *uncommonType {
- if t.tflag&tflagUncommon == 0 {
- return nil
- }
- switch t.Kind() {
- case Struct:
- return &(*structTypeUncommon)(unsafe.Pointer(t)).u
- case Ptr:
- type u struct {
- ptrType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- case Func:
- type u struct {
- funcType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- case Slice:
- type u struct {
- sliceType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- case Array:
- type u struct {
- arrayType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- case Chan:
- type u struct {
- chanType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- case Map:
- type u struct {
- mapType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- case Interface:
- type u struct {
- interfaceType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- default:
- type u struct {
- rtype
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- }
-}
-
-func (t *rtype) String() string {
- s := t.nameOff(t.str).name()
- if t.tflag&tflagExtraStar != 0 {
- return s[1:]
- }
- return s
-}
-
-func (t *rtype) Size() uintptr { return t.size }
-
-func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
-
-func (t *rtype) pointers() bool { return t.ptrdata != 0 }
-
-func (t *rtype) common() *rtype { return t }
-
-func (t *rtype) exportedMethods() []method {
- ut := t.uncommon()
- if ut == nil {
- return nil
- }
- return ut.exportedMethods()
-}
-
-func (t *rtype) NumMethod() int {
- if t.Kind() == Interface {
- tt := (*interfaceType)(unsafe.Pointer(t))
- return tt.NumMethod()
- }
- return len(t.exportedMethods())
-}
-
-func (t *rtype) PkgPath() string {
- if t.tflag&tflagNamed == 0 {
- return ""
- }
- ut := t.uncommon()
- if ut == nil {
- return ""
- }
- return t.nameOff(ut.pkgPath).name()
-}
-
-func (t *rtype) hasName() bool {
- return t.tflag&tflagNamed != 0
-}
-
-func (t *rtype) Name() string {
- if !t.hasName() {
- return ""
- }
- s := t.String()
- i := len(s) - 1
- sqBrackets := 0
- for i >= 0 && (s[i] != '.' || sqBrackets != 0) {
- switch s[i] {
- case ']':
- sqBrackets++
- case '[':
- sqBrackets--
- }
- i--
- }
- return s[i+1:]
-}
-
-func (t *rtype) chanDir() chanDir {
- if t.Kind() != Chan {
- panic("reflect: chanDir of non-chan type")
- }
- tt := (*chanType)(unsafe.Pointer(t))
- return chanDir(tt.dir)
-}
-
-func (t *rtype) Elem() Type {
- switch t.Kind() {
- case Array:
- tt := (*arrayType)(unsafe.Pointer(t))
- return toType(tt.elem)
- case Chan:
- tt := (*chanType)(unsafe.Pointer(t))
- return toType(tt.elem)
- case Map:
- tt := (*mapType)(unsafe.Pointer(t))
- return toType(tt.elem)
- case Ptr:
- tt := (*ptrType)(unsafe.Pointer(t))
- return toType(tt.elem)
- case Slice:
- tt := (*sliceType)(unsafe.Pointer(t))
- return toType(tt.elem)
- }
- panic("reflect: Elem of invalid type")
-}
-
-func (t *rtype) In(i int) Type {
- if t.Kind() != Func {
- panic("reflect: In of non-func type")
- }
- tt := (*funcType)(unsafe.Pointer(t))
- return toType(tt.in()[i])
-}
-
-func (t *rtype) Key() Type {
- if t.Kind() != Map {
- panic("reflect: Key of non-map type")
- }
- tt := (*mapType)(unsafe.Pointer(t))
- return toType(tt.key)
-}
-
-func (t *rtype) Len() int {
- if t.Kind() != Array {
- panic("reflect: Len of non-array type")
- }
- tt := (*arrayType)(unsafe.Pointer(t))
- return int(tt.len)
-}
-
-func (t *rtype) NumField() int {
- if t.Kind() != Struct {
- panic("reflect: NumField of non-struct type")
- }
- tt := (*structType)(unsafe.Pointer(t))
- return len(tt.fields)
-}
-
-func (t *rtype) NumIn() int {
- if t.Kind() != Func {
- panic("reflect: NumIn of non-func type")
- }
- tt := (*funcType)(unsafe.Pointer(t))
- return int(tt.inCount)
-}
-
-func (t *rtype) NumOut() int {
- if t.Kind() != Func {
- panic("reflect: NumOut of non-func type")
- }
- tt := (*funcType)(unsafe.Pointer(t))
- return len(tt.out())
-}
-
-func (t *rtype) Out(i int) Type {
- if t.Kind() != Func {
- panic("reflect: Out of non-func type")
- }
- tt := (*funcType)(unsafe.Pointer(t))
- return toType(tt.out()[i])
-}
-
-func (t *funcType) in() []*rtype {
- uadd := unsafe.Sizeof(*t)
- if t.tflag&tflagUncommon != 0 {
- uadd += unsafe.Sizeof(uncommonType{})
- }
- if t.inCount == 0 {
- return nil
- }
- return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount]
-}
-
-func (t *funcType) out() []*rtype {
- uadd := unsafe.Sizeof(*t)
- if t.tflag&tflagUncommon != 0 {
- uadd += unsafe.Sizeof(uncommonType{})
- }
- outCount := t.outCount & (1<<15 - 1)
- if outCount == 0 {
- return nil
- }
- return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount]
-}
-
-// add returns p+x.
-//
-// The whySafe string is ignored, so that the function still inlines
-// as efficiently as p+x, but all call sites should use the string to
-// record why the addition is safe, which is to say why the addition
-// does not cause x to advance to the very end of p's allocation
-// and therefore point incorrectly at the next block in memory.
-func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
- return unsafe.Pointer(uintptr(p) + x)
-}
-
-// NumMethod returns the number of interface methods in the type's method set.
-func (t *interfaceType) NumMethod() int { return len(t.methods) }
-
-// TypeOf returns the reflection Type that represents the dynamic type of i.
-// If i is a nil interface value, TypeOf returns nil.
-func TypeOf(i any) Type {
- eface := *(*emptyInterface)(unsafe.Pointer(&i))
- return toType(eface.typ)
-}
-
-func (t *rtype) Implements(u Type) bool {
- if u == nil {
- panic("reflect: nil type passed to Type.Implements")
- }
- if u.Kind() != Interface {
- panic("reflect: non-interface type passed to Type.Implements")
- }
- return implements(u.(*rtype), t)
-}
-
-func (t *rtype) AssignableTo(u Type) bool {
- if u == nil {
- panic("reflect: nil type passed to Type.AssignableTo")
- }
- uu := u.(*rtype)
- return directlyAssignable(uu, t) || implements(uu, t)
-}
-
-func (t *rtype) Comparable() bool {
- return t.equal != nil
-}
-
-// implements reports whether the type V implements the interface type T.
-func implements(T, V *rtype) bool {
- if T.Kind() != Interface {
- return false
- }
- t := (*interfaceType)(unsafe.Pointer(T))
- if len(t.methods) == 0 {
- return true
- }
-
- // The same algorithm applies in both cases, but the
- // method tables for an interface type and a concrete type
- // are different, so the code is duplicated.
- // In both cases the algorithm is a linear scan over the two
- // lists - T's methods and V's methods - simultaneously.
- // Since method tables are stored in a unique sorted order
- // (alphabetical, with no duplicate method names), the scan
- // through V's methods must hit a match for each of T's
- // methods along the way, or else V does not implement T.
- // This lets us run the scan in overall linear time instead of
- // the quadratic time a naive search would require.
- // See also ../runtime/iface.go.
- if V.Kind() == Interface {
- v := (*interfaceType)(unsafe.Pointer(V))
- i := 0
- for j := 0; j < len(v.methods); j++ {
- tm := &t.methods[i]
- tmName := t.nameOff(tm.name)
- vm := &v.methods[j]
- vmName := V.nameOff(vm.name)
- if vmName.name() == tmName.name() && V.typeOff(vm.typ) == t.typeOff(tm.typ) {
- if !tmName.isExported() {
- tmPkgPath := tmName.pkgPath()
- if tmPkgPath == "" {
- tmPkgPath = t.pkgPath.name()
- }
- vmPkgPath := vmName.pkgPath()
- if vmPkgPath == "" {
- vmPkgPath = v.pkgPath.name()
- }
- if tmPkgPath != vmPkgPath {
- continue
- }
- }
- if i++; i >= len(t.methods) {
- return true
- }
- }
- }
- return false
- }
-
- v := V.uncommon()
- if v == nil {
- return false
- }
- i := 0
- vmethods := v.methods()
- for j := 0; j < int(v.mcount); j++ {
- tm := &t.methods[i]
- tmName := t.nameOff(tm.name)
- vm := vmethods[j]
- vmName := V.nameOff(vm.name)
- if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) {
- if !tmName.isExported() {
- tmPkgPath := tmName.pkgPath()
- if tmPkgPath == "" {
- tmPkgPath = t.pkgPath.name()
- }
- vmPkgPath := vmName.pkgPath()
- if vmPkgPath == "" {
- vmPkgPath = V.nameOff(v.pkgPath).name()
- }
- if tmPkgPath != vmPkgPath {
- continue
- }
- }
- if i++; i >= len(t.methods) {
- return true
- }
- }
- }
- return false
-}
-
-// directlyAssignable reports whether a value x of type V can be directly
-// assigned (using memmove) to a value of type T.
-// https://golang.org/doc/go_spec.html#Assignability
-// Ignoring the interface rules (implemented elsewhere)
-// and the ideal constant rules (no ideal constants at run time).
-func directlyAssignable(T, V *rtype) bool {
- // x's type V is identical to T?
- if T == V {
- return true
- }
-
- // Otherwise at least one of T and V must not be defined
- // and they must have the same kind.
- if T.hasName() && V.hasName() || T.Kind() != V.Kind() {
- return false
- }
-
- // x's type T and V must have identical underlying types.
- return haveIdenticalUnderlyingType(T, V, true)
-}
-
-func haveIdenticalType(T, V Type, cmpTags bool) bool {
- if cmpTags {
- return T == V
- }
-
- if T.Name() != V.Name() || T.Kind() != V.Kind() {
- return false
- }
-
- return haveIdenticalUnderlyingType(T.common(), V.common(), false)
-}
-
-func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
- if T == V {
- return true
- }
-
- kind := T.Kind()
- if kind != V.Kind() {
- return false
- }
-
- // Non-composite types of equal kind have same underlying type
- // (the predefined instance of the type).
- if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
- return true
- }
-
- // Composite types.
- switch kind {
- case Array:
- return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
-
- case Chan:
- // Special case:
- // x is a bidirectional channel value, T is a channel type,
- // and x's type V and T have identical element types.
- if V.chanDir() == bothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) {
- return true
- }
-
- // Otherwise continue test for identical underlying type.
- return V.chanDir() == T.chanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
-
- case Func:
- t := (*funcType)(unsafe.Pointer(T))
- v := (*funcType)(unsafe.Pointer(V))
- if t.outCount != v.outCount || t.inCount != v.inCount {
- return false
- }
- for i := 0; i < t.NumIn(); i++ {
- if !haveIdenticalType(t.In(i), v.In(i), cmpTags) {
- return false
- }
- }
- for i := 0; i < t.NumOut(); i++ {
- if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) {
- return false
- }
- }
- return true
-
- case Interface:
- t := (*interfaceType)(unsafe.Pointer(T))
- v := (*interfaceType)(unsafe.Pointer(V))
- if len(t.methods) == 0 && len(v.methods) == 0 {
- return true
- }
- // Might have the same methods but still
- // need a run time conversion.
- return false
-
- case Map:
- return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
-
- case Ptr, Slice:
- return haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
-
- case Struct:
- t := (*structType)(unsafe.Pointer(T))
- v := (*structType)(unsafe.Pointer(V))
- if len(t.fields) != len(v.fields) {
- return false
- }
- if t.pkgPath.name() != v.pkgPath.name() {
- return false
- }
- for i := range t.fields {
- tf := &t.fields[i]
- vf := &v.fields[i]
- if tf.name.name() != vf.name.name() {
- return false
- }
- if !haveIdenticalType(tf.typ, vf.typ, cmpTags) {
- return false
- }
- if cmpTags && tf.name.tag() != vf.name.tag() {
- return false
- }
- if tf.offset != vf.offset {
- return false
- }
- if tf.embedded() != vf.embedded() {
- return false
- }
- }
- return true
- }
-
- return false
-}
-
-type structTypeUncommon struct {
- structType
- u uncommonType
-}
-
-// toType converts from a *rtype to a Type that can be returned
-// to the client of package reflect. In gc, the only concern is that
-// a nil *rtype must be replaced by a nil Type, but in gccgo this
-// function takes care of ensuring that multiple *rtype for the same
-// type are coalesced into a single Type.
-func toType(t *rtype) Type {
- if t == nil {
- return nil
- }
- return t
-}
-
-// ifaceIndir reports whether t is stored indirectly in an interface value.
-func ifaceIndir(t *rtype) bool {
- return t.kind&kindDirectIface == 0
-}
diff --git a/contrib/go/_std_1.20/src/internal/reflectlite/value.go b/contrib/go/_std_1.20/src/internal/reflectlite/value.go
deleted file mode 100644
index b9bca3ab44..0000000000
--- a/contrib/go/_std_1.20/src/internal/reflectlite/value.go
+++ /dev/null
@@ -1,477 +0,0 @@
-// Copyright 2009 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 reflectlite
-
-import (
- "internal/goarch"
- "internal/unsafeheader"
- "runtime"
- "unsafe"
-)
-
-// Value is the reflection interface to a Go value.
-//
-// Not all methods apply to all kinds of values. Restrictions,
-// if any, are noted in the documentation for each method.
-// Use the Kind method to find out the kind of value before
-// calling kind-specific methods. Calling a method
-// inappropriate to the kind of type causes a run time panic.
-//
-// The zero Value represents no value.
-// Its IsValid method returns false, its Kind method returns Invalid,
-// its String method returns "<invalid Value>", and all other methods panic.
-// Most functions and methods never return an invalid value.
-// If one does, its documentation states the conditions explicitly.
-//
-// A Value can be used concurrently by multiple goroutines provided that
-// the underlying Go value can be used concurrently for the equivalent
-// direct operations.
-//
-// To compare two Values, compare the results of the Interface method.
-// Using == on two Values does not compare the underlying values
-// they represent.
-type Value struct {
- // typ holds the type of the value represented by a Value.
- typ *rtype
-
- // Pointer-valued data or, if flagIndir is set, pointer to data.
- // Valid when either flagIndir is set or typ.pointers() is true.
- ptr unsafe.Pointer
-
- // flag holds metadata about the value.
- // The lowest bits are flag bits:
- // - flagStickyRO: obtained via unexported not embedded field, so read-only
- // - flagEmbedRO: obtained via unexported embedded field, so read-only
- // - flagIndir: val holds a pointer to the data
- // - flagAddr: v.CanAddr is true (implies flagIndir)
- // Value cannot represent method values.
- // The next five bits give the Kind of the value.
- // This repeats typ.Kind() except for method values.
- // The remaining 23+ bits give a method number for method values.
- // If flag.kind() != Func, code can assume that flagMethod is unset.
- // If ifaceIndir(typ), code can assume that flagIndir is set.
- flag
-
- // A method value represents a curried method invocation
- // like r.Read for some receiver r. The typ+val+flag bits describe
- // the receiver r, but the flag's Kind bits say Func (methods are
- // functions), and the top bits of the flag give the method number
- // in r's type's method table.
-}
-
-type flag uintptr
-
-const (
- flagKindWidth = 5 // there are 27 kinds
- flagKindMask flag = 1<<flagKindWidth - 1
- flagStickyRO flag = 1 << 5
- flagEmbedRO flag = 1 << 6
- flagIndir flag = 1 << 7
- flagAddr flag = 1 << 8
- flagMethod flag = 1 << 9
- flagMethodShift = 10
- flagRO flag = flagStickyRO | flagEmbedRO
-)
-
-func (f flag) kind() Kind {
- return Kind(f & flagKindMask)
-}
-
-func (f flag) ro() flag {
- if f&flagRO != 0 {
- return flagStickyRO
- }
- return 0
-}
-
-// pointer returns the underlying pointer represented by v.
-// v.Kind() must be Pointer, Map, Chan, Func, or UnsafePointer
-func (v Value) pointer() unsafe.Pointer {
- if v.typ.size != goarch.PtrSize || !v.typ.pointers() {
- panic("can't call pointer on a non-pointer Value")
- }
- if v.flag&flagIndir != 0 {
- return *(*unsafe.Pointer)(v.ptr)
- }
- return v.ptr
-}
-
-// packEface converts v to the empty interface.
-func packEface(v Value) any {
- t := v.typ
- var i any
- e := (*emptyInterface)(unsafe.Pointer(&i))
- // First, fill in the data portion of the interface.
- switch {
- case ifaceIndir(t):
- if v.flag&flagIndir == 0 {
- panic("bad indir")
- }
- // Value is indirect, and so is the interface we're making.
- ptr := v.ptr
- if v.flag&flagAddr != 0 {
- // TODO: pass safe boolean from valueInterface so
- // we don't need to copy if safe==true?
- c := unsafe_New(t)
- typedmemmove(t, c, ptr)
- ptr = c
- }
- e.word = ptr
- case v.flag&flagIndir != 0:
- // Value is indirect, but interface is direct. We need
- // to load the data at v.ptr into the interface data word.
- e.word = *(*unsafe.Pointer)(v.ptr)
- default:
- // Value is direct, and so is the interface.
- e.word = v.ptr
- }
- // Now, fill in the type portion. We're very careful here not
- // to have any operation between the e.word and e.typ assignments
- // that would let the garbage collector observe the partially-built
- // interface value.
- e.typ = t
- return i
-}
-
-// unpackEface converts the empty interface i to a Value.
-func unpackEface(i any) Value {
- e := (*emptyInterface)(unsafe.Pointer(&i))
- // NOTE: don't read e.word until we know whether it is really a pointer or not.
- t := e.typ
- if t == nil {
- return Value{}
- }
- f := flag(t.Kind())
- if ifaceIndir(t) {
- f |= flagIndir
- }
- return Value{t, e.word, f}
-}
-
-// A ValueError occurs when a Value method is invoked on
-// a Value that does not support it. Such cases are documented
-// in the description of each method.
-type ValueError struct {
- Method string
- Kind Kind
-}
-
-func (e *ValueError) Error() string {
- if e.Kind == 0 {
- return "reflect: call of " + e.Method + " on zero Value"
- }
- return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
-}
-
-// methodName returns the name of the calling method,
-// assumed to be two stack frames above.
-func methodName() string {
- pc, _, _, _ := runtime.Caller(2)
- f := runtime.FuncForPC(pc)
- if f == nil {
- return "unknown method"
- }
- return f.Name()
-}
-
-// emptyInterface is the header for an interface{} value.
-type emptyInterface struct {
- typ *rtype
- word unsafe.Pointer
-}
-
-// mustBeExported panics if f records that the value was obtained using
-// an unexported field.
-func (f flag) mustBeExported() {
- if f == 0 {
- panic(&ValueError{methodName(), 0})
- }
- if f&flagRO != 0 {
- panic("reflect: " + methodName() + " using value obtained using unexported field")
- }
-}
-
-// mustBeAssignable panics if f records that the value is not assignable,
-// which is to say that either it was obtained using an unexported field
-// or it is not addressable.
-func (f flag) mustBeAssignable() {
- if f == 0 {
- panic(&ValueError{methodName(), Invalid})
- }
- // Assignable if addressable and not read-only.
- if f&flagRO != 0 {
- panic("reflect: " + methodName() + " using value obtained using unexported field")
- }
- if f&flagAddr == 0 {
- panic("reflect: " + methodName() + " using unaddressable value")
- }
-}
-
-// CanSet reports whether the value of v can be changed.
-// A Value can be changed only if it is addressable and was not
-// obtained by the use of unexported struct fields.
-// If CanSet returns false, calling Set or any type-specific
-// setter (e.g., SetBool, SetInt) will panic.
-func (v Value) CanSet() bool {
- return v.flag&(flagAddr|flagRO) == flagAddr
-}
-
-// Elem returns the value that the interface v contains
-// or that the pointer v points to.
-// It panics if v's Kind is not Interface or Pointer.
-// It returns the zero Value if v is nil.
-func (v Value) Elem() Value {
- k := v.kind()
- switch k {
- case Interface:
- var eface any
- if v.typ.NumMethod() == 0 {
- eface = *(*any)(v.ptr)
- } else {
- eface = (any)(*(*interface {
- M()
- })(v.ptr))
- }
- x := unpackEface(eface)
- if x.flag != 0 {
- x.flag |= v.flag.ro()
- }
- return x
- case Pointer:
- ptr := v.ptr
- if v.flag&flagIndir != 0 {
- ptr = *(*unsafe.Pointer)(ptr)
- }
- // The returned value's address is v's value.
- if ptr == nil {
- return Value{}
- }
- tt := (*ptrType)(unsafe.Pointer(v.typ))
- typ := tt.elem
- fl := v.flag&flagRO | flagIndir | flagAddr
- fl |= flag(typ.Kind())
- return Value{typ, ptr, fl}
- }
- panic(&ValueError{"reflectlite.Value.Elem", v.kind()})
-}
-
-func valueInterface(v Value) any {
- if v.flag == 0 {
- panic(&ValueError{"reflectlite.Value.Interface", 0})
- }
-
- if v.kind() == Interface {
- // Special case: return the element inside the interface.
- // Empty interface has one layout, all interfaces with
- // methods have a second layout.
- if v.numMethod() == 0 {
- return *(*any)(v.ptr)
- }
- return *(*interface {
- M()
- })(v.ptr)
- }
-
- // TODO: pass safe to packEface so we don't need to copy if safe==true?
- return packEface(v)
-}
-
-// IsNil reports whether its argument v is nil. The argument must be
-// a chan, func, interface, map, pointer, or slice value; if it is
-// not, IsNil panics. Note that IsNil is not always equivalent to a
-// regular comparison with nil in Go. For example, if v was created
-// by calling ValueOf with an uninitialized interface variable i,
-// i==nil will be true but v.IsNil will panic as v will be the zero
-// Value.
-func (v Value) IsNil() bool {
- k := v.kind()
- switch k {
- case Chan, Func, Map, Pointer, UnsafePointer:
- // if v.flag&flagMethod != 0 {
- // return false
- // }
- ptr := v.ptr
- if v.flag&flagIndir != 0 {
- ptr = *(*unsafe.Pointer)(ptr)
- }
- return ptr == nil
- case Interface, Slice:
- // Both interface and slice are nil if first word is 0.
- // Both are always bigger than a word; assume flagIndir.
- return *(*unsafe.Pointer)(v.ptr) == nil
- }
- panic(&ValueError{"reflectlite.Value.IsNil", v.kind()})
-}
-
-// IsValid reports whether v represents a value.
-// It returns false if v is the zero Value.
-// If IsValid returns false, all other methods except String panic.
-// Most functions and methods never return an invalid Value.
-// If one does, its documentation states the conditions explicitly.
-func (v Value) IsValid() bool {
- return v.flag != 0
-}
-
-// Kind returns v's Kind.
-// If v is the zero Value (IsValid returns false), Kind returns Invalid.
-func (v Value) Kind() Kind {
- return v.kind()
-}
-
-// implemented in runtime:
-func chanlen(unsafe.Pointer) int
-func maplen(unsafe.Pointer) int
-
-// Len returns v's length.
-// It panics if v's Kind is not Array, Chan, Map, Slice, or String.
-func (v Value) Len() int {
- k := v.kind()
- switch k {
- case Array:
- tt := (*arrayType)(unsafe.Pointer(v.typ))
- return int(tt.len)
- case Chan:
- return chanlen(v.pointer())
- case Map:
- return maplen(v.pointer())
- case Slice:
- // Slice is bigger than a word; assume flagIndir.
- return (*unsafeheader.Slice)(v.ptr).Len
- case String:
- // String is bigger than a word; assume flagIndir.
- return (*unsafeheader.String)(v.ptr).Len
- }
- panic(&ValueError{"reflect.Value.Len", v.kind()})
-}
-
-// NumMethod returns the number of exported methods in the value's method set.
-func (v Value) numMethod() int {
- if v.typ == nil {
- panic(&ValueError{"reflectlite.Value.NumMethod", Invalid})
- }
- return v.typ.NumMethod()
-}
-
-// Set assigns x to the value v.
-// It panics if CanSet returns false.
-// As in Go, x's value must be assignable to v's type.
-func (v Value) Set(x Value) {
- v.mustBeAssignable()
- x.mustBeExported() // do not let unexported x leak
- var target unsafe.Pointer
- if v.kind() == Interface {
- target = v.ptr
- }
- x = x.assignTo("reflectlite.Set", v.typ, target)
- if x.flag&flagIndir != 0 {
- typedmemmove(v.typ, v.ptr, x.ptr)
- } else {
- *(*unsafe.Pointer)(v.ptr) = x.ptr
- }
-}
-
-// Type returns v's type.
-func (v Value) Type() Type {
- f := v.flag
- if f == 0 {
- panic(&ValueError{"reflectlite.Value.Type", Invalid})
- }
- // Method values not supported.
- return v.typ
-}
-
-/*
- * constructors
- */
-
-// implemented in package runtime
-func unsafe_New(*rtype) unsafe.Pointer
-
-// ValueOf returns a new Value initialized to the concrete value
-// stored in the interface i. ValueOf(nil) returns the zero Value.
-func ValueOf(i any) Value {
- if i == nil {
- return Value{}
- }
-
- // TODO: Maybe allow contents of a Value to live on the stack.
- // For now we make the contents always escape to the heap. It
- // makes life easier in a few places (see chanrecv/mapassign
- // comment below).
- escapes(i)
-
- return unpackEface(i)
-}
-
-// assignTo returns a value v that can be assigned directly to typ.
-// It panics if v is not assignable to typ.
-// For a conversion to an interface type, target is a suggested scratch space to use.
-func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value {
- // if v.flag&flagMethod != 0 {
- // v = makeMethodValue(context, v)
- // }
-
- switch {
- case directlyAssignable(dst, v.typ):
- // Overwrite type so that they match.
- // Same memory layout, so no harm done.
- fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
- fl |= flag(dst.Kind())
- return Value{dst, v.ptr, fl}
-
- case implements(dst, v.typ):
- if target == nil {
- target = unsafe_New(dst)
- }
- if v.Kind() == Interface && v.IsNil() {
- // A nil ReadWriter passed to nil Reader is OK,
- // but using ifaceE2I below will panic.
- // Avoid the panic by returning a nil dst (e.g., Reader) explicitly.
- return Value{dst, nil, flag(Interface)}
- }
- x := valueInterface(v)
- if dst.NumMethod() == 0 {
- *(*any)(target) = x
- } else {
- ifaceE2I(dst, x, target)
- }
- return Value{dst, target, flagIndir | flag(Interface)}
- }
-
- // Failed.
- panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
-}
-
-// arrayAt returns the i-th element of p,
-// an array whose elements are eltSize bytes wide.
-// The array pointed at by p must have at least i+1 elements:
-// it is invalid (but impossible to check here) to pass i >= len,
-// because then the result will point outside the array.
-// whySafe must explain why i < len. (Passing "i < len" is fine;
-// the benefit is to surface this assumption at the call site.)
-func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
- return add(p, uintptr(i)*eltSize, "i < len")
-}
-
-func ifaceE2I(t *rtype, src any, dst unsafe.Pointer)
-
-// typedmemmove copies a value of type t to dst from src.
-//
-//go:noescape
-func typedmemmove(t *rtype, dst, src unsafe.Pointer)
-
-// Dummy annotation marking that the value x escapes,
-// for use in cases where the reflect code is so clever that
-// the compiler cannot follow.
-func escapes(x any) {
- if dummy.b {
- dummy.x = x
- }
-}
-
-var dummy struct {
- b bool
- x any
-}
diff --git a/contrib/go/_std_1.20/src/internal/reflectlite/ya.make b/contrib/go/_std_1.20/src/internal/reflectlite/ya.make
deleted file mode 100644
index 3747308e12..0000000000
--- a/contrib/go/_std_1.20/src/internal/reflectlite/ya.make
+++ /dev/null
@@ -1,10 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- asm.s
- swapper.go
- type.go
- value.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/safefilepath/ya.make b/contrib/go/_std_1.20/src/internal/safefilepath/ya.make
deleted file mode 100644
index db2dcfda27..0000000000
--- a/contrib/go/_std_1.20/src/internal/safefilepath/ya.make
+++ /dev/null
@@ -1,25 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- path.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- path_other.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- path_other.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- path_windows.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/saferio/ya.make b/contrib/go/_std_1.20/src/internal/saferio/ya.make
deleted file mode 100644
index 1773a7384e..0000000000
--- a/contrib/go/_std_1.20/src/internal/saferio/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- io.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/singleflight/ya.make b/contrib/go/_std_1.20/src/internal/singleflight/ya.make
deleted file mode 100644
index b44ecbcd79..0000000000
--- a/contrib/go/_std_1.20/src/internal/singleflight/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- singleflight.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/syscall/execenv/execenv_windows.go b/contrib/go/_std_1.20/src/internal/syscall/execenv/execenv_windows.go
deleted file mode 100644
index a8aa1a644e..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/execenv/execenv_windows.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// 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.
-
-//go:build windows
-
-package execenv
-
-import (
- "internal/syscall/windows"
- "syscall"
- "unicode/utf16"
- "unsafe"
-)
-
-// Default will return the default environment
-// variables based on the process attributes
-// provided.
-//
-// If the process attributes contain a token, then
-// the environment variables will be sourced from
-// the defaults for that user token, otherwise they
-// will be sourced from syscall.Environ().
-func Default(sys *syscall.SysProcAttr) (env []string, err error) {
- if sys == nil || sys.Token == 0 {
- return syscall.Environ(), nil
- }
- var block *uint16
- err = windows.CreateEnvironmentBlock(&block, sys.Token, false)
- if err != nil {
- return nil, err
- }
- defer windows.DestroyEnvironmentBlock(block)
- blockp := uintptr(unsafe.Pointer(block))
- for {
-
- // find NUL terminator
- end := unsafe.Pointer(blockp)
- for *(*uint16)(end) != 0 {
- end = unsafe.Pointer(uintptr(end) + 2)
- }
-
- n := (uintptr(end) - uintptr(unsafe.Pointer(blockp))) / 2
- if n == 0 {
- // environment block ends with empty string
- break
- }
-
- entry := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(blockp))[:n:n]
- env = append(env, string(utf16.Decode(entry)))
- blockp += 2 * (uintptr(len(entry)) + 1)
- }
- return
-}
diff --git a/contrib/go/_std_1.20/src/internal/syscall/execenv/ya.make b/contrib/go/_std_1.20/src/internal/syscall/execenv/ya.make
deleted file mode 100644
index 6e4227b8ca..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/execenv/ya.make
+++ /dev/null
@@ -1,21 +0,0 @@
-GO_LIBRARY()
-
-IF (OS_DARWIN)
- SRCS(
- execenv_default.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- execenv_default.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- execenv_windows.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_darwin.go b/contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_darwin.go
deleted file mode 100644
index aaaaa4751c..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_darwin.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2018 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 unix
-
-const AT_REMOVEDIR = 0x80
-const AT_SYMLINK_NOFOLLOW = 0x0020
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_linux.go b/contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_linux.go
deleted file mode 100644
index b9b8495e32..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_linux.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2018 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 unix
-
-import "syscall"
-
-const unlinkatTrap uintptr = syscall.SYS_UNLINKAT
-const openatTrap uintptr = syscall.SYS_OPENAT
-
-const (
- AT_EACCESS = 0x200
- AT_FDCWD = -0x64
- AT_REMOVEDIR = 0x200
- AT_SYMLINK_NOFOLLOW = 0x100
-)
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/getrandom.go b/contrib/go/_std_1.20/src/internal/syscall/unix/getrandom.go
deleted file mode 100644
index a6659331e4..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/getrandom.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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.
-
-//go:build dragonfly || freebsd || linux
-
-package unix
-
-import (
- "sync/atomic"
- "syscall"
- "unsafe"
-)
-
-var getrandomUnsupported int32 // atomic
-
-// GetRandomFlag is a flag supported by the getrandom system call.
-type GetRandomFlag uintptr
-
-// GetRandom calls the getrandom system call.
-func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) {
- if len(p) == 0 {
- return 0, nil
- }
- if atomic.LoadInt32(&getrandomUnsupported) != 0 {
- return 0, syscall.ENOSYS
- }
- r1, _, errno := syscall.Syscall(getrandomTrap,
- uintptr(unsafe.Pointer(&p[0])),
- uintptr(len(p)),
- uintptr(flags))
- if errno != 0 {
- if errno == syscall.ENOSYS {
- atomic.StoreInt32(&getrandomUnsupported, 1)
- }
- return 0, errno
- }
- return int(r1), nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/net_darwin.go b/contrib/go/_std_1.20/src/internal/syscall/unix/net_darwin.go
deleted file mode 100644
index b9da4f1dc7..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/net_darwin.go
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2022 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 unix
-
-import (
- "internal/abi"
- "syscall"
- "unsafe"
-)
-
-const (
- AI_CANONNAME = 0x2
- AI_ALL = 0x100
- AI_V4MAPPED = 0x800
- AI_MASK = 0x1407
-
- EAI_AGAIN = 2
- EAI_NONAME = 8
- EAI_SYSTEM = 11
- EAI_OVERFLOW = 14
-
- NI_NAMEREQD = 4
-)
-
-type Addrinfo struct {
- Flags int32
- Family int32
- Socktype int32
- Protocol int32
- Addrlen uint32
- Canonname *byte
- Addr *syscall.RawSockaddr
- Next *Addrinfo
-}
-
-//go:cgo_ldflag "-lresolv"
-
-//go:cgo_import_dynamic libc_getaddrinfo getaddrinfo "/usr/lib/libSystem.B.dylib"
-func libc_getaddrinfo_trampoline()
-
-func Getaddrinfo(hostname, servname *byte, hints *Addrinfo, res **Addrinfo) (int, error) {
- gerrno, _, errno := syscall_syscall6(abi.FuncPCABI0(libc_getaddrinfo_trampoline),
- uintptr(unsafe.Pointer(hostname)),
- uintptr(unsafe.Pointer(servname)),
- uintptr(unsafe.Pointer(hints)),
- uintptr(unsafe.Pointer(res)),
- 0,
- 0)
- var err error
- if errno != 0 {
- err = errno
- }
- return int(gerrno), err
-}
-
-//go:cgo_import_dynamic libc_freeaddrinfo freeaddrinfo "/usr/lib/libSystem.B.dylib"
-func libc_freeaddrinfo_trampoline()
-
-func Freeaddrinfo(ai *Addrinfo) {
- syscall_syscall6(abi.FuncPCABI0(libc_freeaddrinfo_trampoline),
- uintptr(unsafe.Pointer(ai)),
- 0, 0, 0, 0, 0)
-}
-
-//go:cgo_import_dynamic libc_getnameinfo getnameinfo "/usr/lib/libSystem.B.dylib"
-func libc_getnameinfo_trampoline()
-
-func Getnameinfo(sa *syscall.RawSockaddr, salen int, host *byte, hostlen int, serv *byte, servlen int, flags int) (int, error) {
- gerrno, _, errno := syscall_syscall9(abi.FuncPCABI0(libc_getnameinfo_trampoline),
- uintptr(unsafe.Pointer(sa)),
- uintptr(salen),
- uintptr(unsafe.Pointer(host)),
- uintptr(hostlen),
- uintptr(unsafe.Pointer(serv)),
- uintptr(servlen),
- uintptr(flags),
- 0,
- 0)
- var err error
- if errno != 0 {
- err = errno
- }
- return int(gerrno), err
-}
-
-//go:cgo_import_dynamic libc_gai_strerror gai_strerror "/usr/lib/libSystem.B.dylib"
-func libc_gai_strerror_trampoline()
-
-func GaiStrerror(ecode int) string {
- r1, _, _ := syscall_syscall(abi.FuncPCABI0(libc_gai_strerror_trampoline),
- uintptr(ecode),
- 0, 0)
- return GoString((*byte)(unsafe.Pointer(r1)))
-}
-
-// Implemented in the runtime package.
-func gostring(*byte) string
-
-func GoString(p *byte) string {
- return gostring(p)
-}
-
-//go:linkname syscall_syscall syscall.syscall
-func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
-
-//go:linkname syscall_syscallPtr syscall.syscallPtr
-func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
-
-//go:linkname syscall_syscall6 syscall.syscall6
-func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
-
-//go:linkname syscall_syscall6X syscall.syscall6X
-func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
-
-//go:linkname syscall_syscall9 syscall.syscall9
-func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
-
-type ResState struct {
- unexported [70]uintptr
-}
-
-//go:cgo_import_dynamic libresolv_res_9_ninit res_9_ninit "/usr/lib/libresolv.9.dylib"
-func libresolv_res_9_ninit_trampoline()
-
-func ResNinit(state *ResState) error {
- _, _, errno := syscall_syscall(abi.FuncPCABI0(libresolv_res_9_ninit_trampoline),
- uintptr(unsafe.Pointer(state)),
- 0, 0)
- if errno != 0 {
- return errno
- }
- return nil
-}
-
-//go:cgo_import_dynamic libresolv_res_9_nclose res_9_nclose "/usr/lib/libresolv.9.dylib"
-func libresolv_res_9_nclose_trampoline()
-
-func ResNclose(state *ResState) {
- syscall_syscall(abi.FuncPCABI0(libresolv_res_9_nclose_trampoline),
- uintptr(unsafe.Pointer(state)),
- 0, 0)
-}
-
-//go:cgo_import_dynamic libresolv_res_9_nsearch res_9_nsearch "/usr/lib/libresolv.9.dylib"
-func libresolv_res_9_nsearch_trampoline()
-
-func ResNsearch(state *ResState, dname *byte, class, typ int, ans *byte, anslen int) (int, error) {
- r1, _, errno := syscall_syscall6(abi.FuncPCABI0(libresolv_res_9_nsearch_trampoline),
- uintptr(unsafe.Pointer(state)),
- uintptr(unsafe.Pointer(dname)),
- uintptr(class),
- uintptr(typ),
- uintptr(unsafe.Pointer(ans)),
- uintptr(anslen))
- if errno != 0 {
- return 0, errno
- }
- return int(int32(r1)), nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/nonblocking.go b/contrib/go/_std_1.20/src/internal/syscall/unix/nonblocking.go
deleted file mode 100644
index 6c6f0674d6..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/nonblocking.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2018 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.
-
-//go:build dragonfly || freebsd || linux || netbsd || (openbsd && mips64)
-
-package unix
-
-import "syscall"
-
-// FcntlSyscall is the number for the fcntl system call. This is
-// usually SYS_FCNTL, but can be overridden to SYS_FCNTL64.
-var FcntlSyscall uintptr = syscall.SYS_FCNTL
-
-func IsNonblock(fd int) (nonblocking bool, err error) {
- flag, _, e1 := syscall.Syscall(FcntlSyscall, uintptr(fd), uintptr(syscall.F_GETFL), 0)
- if e1 != 0 {
- return false, e1
- }
- return flag&syscall.O_NONBLOCK != 0, nil
-}
-
-func HasNonblockFlag(flag int) bool {
- return flag&syscall.O_NONBLOCK != 0
-}
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/nonblocking_libc.go b/contrib/go/_std_1.20/src/internal/syscall/unix/nonblocking_libc.go
deleted file mode 100644
index 56cac5b5cd..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/nonblocking_libc.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018 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.
-
-//go:build aix || darwin || (openbsd && !mips64) || solaris
-
-package unix
-
-import (
- "syscall"
- _ "unsafe" // for go:linkname
-
-)
-
-func IsNonblock(fd int) (nonblocking bool, err error) {
- flag, e1 := fcntl(fd, syscall.F_GETFL, 0)
- if e1 != nil {
- return false, e1
- }
- return flag&syscall.O_NONBLOCK != 0, nil
-}
-
-func HasNonblockFlag(flag int) bool {
- return flag&syscall.O_NONBLOCK != 0
-}
-
-// Implemented in the syscall package.
-//
-//go:linkname fcntl syscall.fcntl
-func fcntl(fd int, cmd int, arg int) (int, error)
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/ya.make b/contrib/go/_std_1.20/src/internal/syscall/unix/ya.make
deleted file mode 100644
index d7d1a71aab..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/ya.make
+++ /dev/null
@@ -1,62 +0,0 @@
-GO_LIBRARY()
-
-BUILD_ONLY_IF(WARNING OS_DARWIN OR OS_LINUX)
-
-IF (OS_DARWIN)
- CGO_LDFLAGS(
- -lresolv
- )
-
- SRCS(
- asm_darwin.s
- at_libc2.go
- at_sysnum_darwin.go
- constants.go
- eaccess_other.go
- getentropy_darwin.go
- kernel_version_other.go
- net.go
- net_darwin.go
- nonblocking_libc.go
- pty_darwin.go
- user_darwin.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- at.go
- at_fstatat.go
- at_sysnum_linux.go
- constants.go
- copy_file_range_linux.go
- eaccess_linux.go
- getrandom.go
- getrandom_linux.go
- kernel_version_linux.go
- net.go
- nonblocking.go
- )
-
- IF (ARCH_ARM64)
- SRCS(
- at_sysnum_fstatat_linux.go
- sysnum_linux_generic.go
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- at_sysnum_newfstatat_linux.go
- sysnum_linux_amd64.go
- )
- ENDIF()
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- kernel_version_other.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/net_windows.go b/contrib/go/_std_1.20/src/internal/syscall/windows/net_windows.go
deleted file mode 100644
index 3d3df7161c..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/net_windows.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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 windows
-
-import (
- "syscall"
- _ "unsafe"
-)
-
-//go:linkname WSASendtoInet4 syscall.wsaSendtoInet4
-//go:noescape
-func WSASendtoInet4(s syscall.Handle, bufs *syscall.WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *syscall.SockaddrInet4, overlapped *syscall.Overlapped, croutine *byte) (err error)
-
-//go:linkname WSASendtoInet6 syscall.wsaSendtoInet6
-//go:noescape
-func WSASendtoInet6(s syscall.Handle, bufs *syscall.WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *syscall.SockaddrInet6, overlapped *syscall.Overlapped, croutine *byte) (err error)
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/registry/value.go b/contrib/go/_std_1.20/src/internal/syscall/windows/registry/value.go
deleted file mode 100644
index 025574015f..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/registry/value.go
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright 2015 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.
-
-//go:build windows
-
-package registry
-
-import (
- "errors"
- "syscall"
- "unicode/utf16"
- "unsafe"
-)
-
-const (
- // Registry value types.
- NONE = 0
- SZ = 1
- EXPAND_SZ = 2
- BINARY = 3
- DWORD = 4
- DWORD_BIG_ENDIAN = 5
- LINK = 6
- MULTI_SZ = 7
- RESOURCE_LIST = 8
- FULL_RESOURCE_DESCRIPTOR = 9
- RESOURCE_REQUIREMENTS_LIST = 10
- QWORD = 11
-)
-
-var (
- // ErrShortBuffer is returned when the buffer was too short for the operation.
- ErrShortBuffer = syscall.ERROR_MORE_DATA
-
- // ErrNotExist is returned when a registry key or value does not exist.
- ErrNotExist = syscall.ERROR_FILE_NOT_FOUND
-
- // ErrUnexpectedType is returned by Get*Value when the value's type was unexpected.
- ErrUnexpectedType = errors.New("unexpected key value type")
-)
-
-// GetValue retrieves the type and data for the specified value associated
-// with an open key k. It fills up buffer buf and returns the retrieved
-// byte count n. If buf is too small to fit the stored value it returns
-// ErrShortBuffer error along with the required buffer size n.
-// If no buffer is provided, it returns true and actual buffer size n.
-// If no buffer is provided, GetValue returns the value's type only.
-// If the value does not exist, the error returned is ErrNotExist.
-//
-// GetValue is a low level function. If value's type is known, use the appropriate
-// Get*Value function instead.
-func (k Key) GetValue(name string, buf []byte) (n int, valtype uint32, err error) {
- pname, err := syscall.UTF16PtrFromString(name)
- if err != nil {
- return 0, 0, err
- }
- var pbuf *byte
- if len(buf) > 0 {
- pbuf = (*byte)(unsafe.Pointer(&buf[0]))
- }
- l := uint32(len(buf))
- err = syscall.RegQueryValueEx(syscall.Handle(k), pname, nil, &valtype, pbuf, &l)
- if err != nil {
- return int(l), valtype, err
- }
- return int(l), valtype, nil
-}
-
-func (k Key) getValue(name string, buf []byte) (date []byte, valtype uint32, err error) {
- p, err := syscall.UTF16PtrFromString(name)
- if err != nil {
- return nil, 0, err
- }
- var t uint32
- n := uint32(len(buf))
- for {
- err = syscall.RegQueryValueEx(syscall.Handle(k), p, nil, &t, (*byte)(unsafe.Pointer(&buf[0])), &n)
- if err == nil {
- return buf[:n], t, nil
- }
- if err != syscall.ERROR_MORE_DATA {
- return nil, 0, err
- }
- if n <= uint32(len(buf)) {
- return nil, 0, err
- }
- buf = make([]byte, n)
- }
-}
-
-// GetStringValue retrieves the string value for the specified
-// value name associated with an open key k. It also returns the value's type.
-// If value does not exist, GetStringValue returns ErrNotExist.
-// If value is not SZ or EXPAND_SZ, it will return the correct value
-// type and ErrUnexpectedType.
-func (k Key) GetStringValue(name string) (val string, valtype uint32, err error) {
- data, typ, err2 := k.getValue(name, make([]byte, 64))
- if err2 != nil {
- return "", typ, err2
- }
- switch typ {
- case SZ, EXPAND_SZ:
- default:
- return "", typ, ErrUnexpectedType
- }
- if len(data) == 0 {
- return "", typ, nil
- }
- u := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[: len(data)/2 : len(data)/2]
- return syscall.UTF16ToString(u), typ, nil
-}
-
-// GetMUIStringValue retrieves the localized string value for
-// the specified value name associated with an open key k.
-// If the value name doesn't exist or the localized string value
-// can't be resolved, GetMUIStringValue returns ErrNotExist.
-// GetMUIStringValue panics if the system doesn't support
-// regLoadMUIString; use LoadRegLoadMUIString to check if
-// regLoadMUIString is supported before calling this function.
-func (k Key) GetMUIStringValue(name string) (string, error) {
- pname, err := syscall.UTF16PtrFromString(name)
- if err != nil {
- return "", err
- }
-
- buf := make([]uint16, 1024)
- var buflen uint32
- var pdir *uint16
-
- err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
- if err == syscall.ERROR_FILE_NOT_FOUND { // Try fallback path
-
- // Try to resolve the string value using the system directory as
- // a DLL search path; this assumes the string value is of the form
- // @[path]\dllname,-strID but with no path given, e.g. @tzres.dll,-320.
-
- // This approach works with tzres.dll but may have to be revised
- // in the future to allow callers to provide custom search paths.
-
- var s string
- s, err = ExpandString("%SystemRoot%\\system32\\")
- if err != nil {
- return "", err
- }
- pdir, err = syscall.UTF16PtrFromString(s)
- if err != nil {
- return "", err
- }
-
- err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
- }
-
- for err == syscall.ERROR_MORE_DATA { // Grow buffer if needed
- if buflen <= uint32(len(buf)) {
- break // Buffer not growing, assume race; break
- }
- buf = make([]uint16, buflen)
- err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
- }
-
- if err != nil {
- return "", err
- }
-
- return syscall.UTF16ToString(buf), nil
-}
-
-// ExpandString expands environment-variable strings and replaces
-// them with the values defined for the current user.
-// Use ExpandString to expand EXPAND_SZ strings.
-func ExpandString(value string) (string, error) {
- if value == "" {
- return "", nil
- }
- p, err := syscall.UTF16PtrFromString(value)
- if err != nil {
- return "", err
- }
- r := make([]uint16, 100)
- for {
- n, err := expandEnvironmentStrings(p, &r[0], uint32(len(r)))
- if err != nil {
- return "", err
- }
- if n <= uint32(len(r)) {
- return syscall.UTF16ToString(r[:n]), nil
- }
- r = make([]uint16, n)
- }
-}
-
-// GetStringsValue retrieves the []string value for the specified
-// value name associated with an open key k. It also returns the value's type.
-// If value does not exist, GetStringsValue returns ErrNotExist.
-// If value is not MULTI_SZ, it will return the correct value
-// type and ErrUnexpectedType.
-func (k Key) GetStringsValue(name string) (val []string, valtype uint32, err error) {
- data, typ, err2 := k.getValue(name, make([]byte, 64))
- if err2 != nil {
- return nil, typ, err2
- }
- if typ != MULTI_SZ {
- return nil, typ, ErrUnexpectedType
- }
- if len(data) == 0 {
- return nil, typ, nil
- }
- p := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[: len(data)/2 : len(data)/2]
- if len(p) == 0 {
- return nil, typ, nil
- }
- if p[len(p)-1] == 0 {
- p = p[:len(p)-1] // remove terminating null
- }
- val = make([]string, 0, 5)
- from := 0
- for i, c := range p {
- if c == 0 {
- val = append(val, string(utf16.Decode(p[from:i])))
- from = i + 1
- }
- }
- return val, typ, nil
-}
-
-// GetIntegerValue retrieves the integer value for the specified
-// value name associated with an open key k. It also returns the value's type.
-// If value does not exist, GetIntegerValue returns ErrNotExist.
-// If value is not DWORD or QWORD, it will return the correct value
-// type and ErrUnexpectedType.
-func (k Key) GetIntegerValue(name string) (val uint64, valtype uint32, err error) {
- data, typ, err2 := k.getValue(name, make([]byte, 8))
- if err2 != nil {
- return 0, typ, err2
- }
- switch typ {
- case DWORD:
- if len(data) != 4 {
- return 0, typ, errors.New("DWORD value is not 4 bytes long")
- }
- return uint64(*(*uint32)(unsafe.Pointer(&data[0]))), DWORD, nil
- case QWORD:
- if len(data) != 8 {
- return 0, typ, errors.New("QWORD value is not 8 bytes long")
- }
- return uint64(*(*uint64)(unsafe.Pointer(&data[0]))), QWORD, nil
- default:
- return 0, typ, ErrUnexpectedType
- }
-}
-
-// GetBinaryValue retrieves the binary value for the specified
-// value name associated with an open key k. It also returns the value's type.
-// If value does not exist, GetBinaryValue returns ErrNotExist.
-// If value is not BINARY, it will return the correct value
-// type and ErrUnexpectedType.
-func (k Key) GetBinaryValue(name string) (val []byte, valtype uint32, err error) {
- data, typ, err2 := k.getValue(name, make([]byte, 64))
- if err2 != nil {
- return nil, typ, err2
- }
- if typ != BINARY {
- return nil, typ, ErrUnexpectedType
- }
- return data, typ, nil
-}
-
-func (k Key) setValue(name string, valtype uint32, data []byte) error {
- p, err := syscall.UTF16PtrFromString(name)
- if err != nil {
- return err
- }
- if len(data) == 0 {
- return regSetValueEx(syscall.Handle(k), p, 0, valtype, nil, 0)
- }
- return regSetValueEx(syscall.Handle(k), p, 0, valtype, &data[0], uint32(len(data)))
-}
-
-// SetDWordValue sets the data and type of a name value
-// under key k to value and DWORD.
-func (k Key) SetDWordValue(name string, value uint32) error {
- return k.setValue(name, DWORD, (*[4]byte)(unsafe.Pointer(&value))[:])
-}
-
-// SetQWordValue sets the data and type of a name value
-// under key k to value and QWORD.
-func (k Key) SetQWordValue(name string, value uint64) error {
- return k.setValue(name, QWORD, (*[8]byte)(unsafe.Pointer(&value))[:])
-}
-
-func (k Key) setStringValue(name string, valtype uint32, value string) error {
- v, err := syscall.UTF16FromString(value)
- if err != nil {
- return err
- }
- buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[: len(v)*2 : len(v)*2]
- return k.setValue(name, valtype, buf)
-}
-
-// SetStringValue sets the data and type of a name value
-// under key k to value and SZ. The value must not contain a zero byte.
-func (k Key) SetStringValue(name, value string) error {
- return k.setStringValue(name, SZ, value)
-}
-
-// SetExpandStringValue sets the data and type of a name value
-// under key k to value and EXPAND_SZ. The value must not contain a zero byte.
-func (k Key) SetExpandStringValue(name, value string) error {
- return k.setStringValue(name, EXPAND_SZ, value)
-}
-
-// SetStringsValue sets the data and type of a name value
-// under key k to value and MULTI_SZ. The value strings
-// must not contain a zero byte.
-func (k Key) SetStringsValue(name string, value []string) error {
- ss := ""
- for _, s := range value {
- for i := 0; i < len(s); i++ {
- if s[i] == 0 {
- return errors.New("string cannot have 0 inside")
- }
- }
- ss += s + "\x00"
- }
- v := utf16.Encode([]rune(ss + "\x00"))
- buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[: len(v)*2 : len(v)*2]
- return k.setValue(name, MULTI_SZ, buf)
-}
-
-// SetBinaryValue sets the data and type of a name value
-// under key k to value and BINARY.
-func (k Key) SetBinaryValue(name string, value []byte) error {
- return k.setValue(name, BINARY, value)
-}
-
-// DeleteValue removes a named value from the key k.
-func (k Key) DeleteValue(name string) error {
- return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name))
-}
-
-// ReadValueNames returns the value names of key k.
-func (k Key) ReadValueNames() ([]string, error) {
- ki, err := k.Stat()
- if err != nil {
- return nil, err
- }
- names := make([]string, 0, ki.ValueCount)
- buf := make([]uint16, ki.MaxValueNameLen+1) // extra room for terminating null character
-loopItems:
- for i := uint32(0); ; i++ {
- l := uint32(len(buf))
- for {
- err := regEnumValue(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
- if err == nil {
- break
- }
- if err == syscall.ERROR_MORE_DATA {
- // Double buffer size and try again.
- l = uint32(2 * len(buf))
- buf = make([]uint16, l)
- continue
- }
- if err == _ERROR_NO_MORE_ITEMS {
- break loopItems
- }
- return names, err
- }
- names = append(names, syscall.UTF16ToString(buf[:l]))
- }
- return names, nil
-}
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/registry/ya.make b/contrib/go/_std_1.20/src/internal/syscall/windows/registry/ya.make
deleted file mode 100644
index a883ca985a..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/registry/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-GO_LIBRARY()
-
-BUILD_ONLY_IF(WARNING OS_WINDOWS)
-
-IF (OS_WINDOWS)
- SRCS(
- key.go
- syscall.go
- value.go
- zsyscall_windows.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/syscall_windows.go b/contrib/go/_std_1.20/src/internal/syscall/windows/syscall_windows.go
deleted file mode 100644
index 8ace2a27e7..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/syscall_windows.go
+++ /dev/null
@@ -1,369 +0,0 @@
-// Copyright 2014 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 windows
-
-import (
- "sync"
- "syscall"
- "unicode/utf16"
- "unsafe"
-)
-
-// UTF16PtrToString is like UTF16ToString, but takes *uint16
-// as a parameter instead of []uint16.
-func UTF16PtrToString(p *uint16) string {
- if p == nil {
- return ""
- }
- // Find NUL terminator.
- end := unsafe.Pointer(p)
- n := 0
- for *(*uint16)(end) != 0 {
- end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p))
- n++
- }
- // Turn *uint16 into []uint16.
- s := unsafe.Slice(p, n)
- // Decode []uint16 into string.
- return string(utf16.Decode(s))
-}
-
-const (
- ERROR_BAD_LENGTH syscall.Errno = 24
- ERROR_SHARING_VIOLATION syscall.Errno = 32
- ERROR_LOCK_VIOLATION syscall.Errno = 33
- ERROR_NOT_SUPPORTED syscall.Errno = 50
- ERROR_CALL_NOT_IMPLEMENTED syscall.Errno = 120
- ERROR_INVALID_NAME syscall.Errno = 123
- ERROR_LOCK_FAILED syscall.Errno = 167
- ERROR_NO_UNICODE_TRANSLATION syscall.Errno = 1113
-)
-
-const GAA_FLAG_INCLUDE_PREFIX = 0x00000010
-
-const (
- IF_TYPE_OTHER = 1
- IF_TYPE_ETHERNET_CSMACD = 6
- IF_TYPE_ISO88025_TOKENRING = 9
- IF_TYPE_PPP = 23
- IF_TYPE_SOFTWARE_LOOPBACK = 24
- IF_TYPE_ATM = 37
- IF_TYPE_IEEE80211 = 71
- IF_TYPE_TUNNEL = 131
- IF_TYPE_IEEE1394 = 144
-)
-
-type SocketAddress struct {
- Sockaddr *syscall.RawSockaddrAny
- SockaddrLength int32
-}
-
-type IpAdapterUnicastAddress struct {
- Length uint32
- Flags uint32
- Next *IpAdapterUnicastAddress
- Address SocketAddress
- PrefixOrigin int32
- SuffixOrigin int32
- DadState int32
- ValidLifetime uint32
- PreferredLifetime uint32
- LeaseLifetime uint32
- OnLinkPrefixLength uint8
-}
-
-type IpAdapterAnycastAddress struct {
- Length uint32
- Flags uint32
- Next *IpAdapterAnycastAddress
- Address SocketAddress
-}
-
-type IpAdapterMulticastAddress struct {
- Length uint32
- Flags uint32
- Next *IpAdapterMulticastAddress
- Address SocketAddress
-}
-
-type IpAdapterDnsServerAdapter struct {
- Length uint32
- Reserved uint32
- Next *IpAdapterDnsServerAdapter
- Address SocketAddress
-}
-
-type IpAdapterPrefix struct {
- Length uint32
- Flags uint32
- Next *IpAdapterPrefix
- Address SocketAddress
- PrefixLength uint32
-}
-
-type IpAdapterAddresses struct {
- Length uint32
- IfIndex uint32
- Next *IpAdapterAddresses
- AdapterName *byte
- FirstUnicastAddress *IpAdapterUnicastAddress
- FirstAnycastAddress *IpAdapterAnycastAddress
- FirstMulticastAddress *IpAdapterMulticastAddress
- FirstDnsServerAddress *IpAdapterDnsServerAdapter
- DnsSuffix *uint16
- Description *uint16
- FriendlyName *uint16
- PhysicalAddress [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
- PhysicalAddressLength uint32
- Flags uint32
- Mtu uint32
- IfType uint32
- OperStatus uint32
- Ipv6IfIndex uint32
- ZoneIndices [16]uint32
- FirstPrefix *IpAdapterPrefix
- /* more fields might be present here. */
-}
-
-type FILE_BASIC_INFO struct {
- CreationTime syscall.Filetime
- LastAccessTime syscall.Filetime
- LastWriteTime syscall.Filetime
- ChangedTime syscall.Filetime
- FileAttributes uint32
-}
-
-const (
- IfOperStatusUp = 1
- IfOperStatusDown = 2
- IfOperStatusTesting = 3
- IfOperStatusUnknown = 4
- IfOperStatusDormant = 5
- IfOperStatusNotPresent = 6
- IfOperStatusLowerLayerDown = 7
-)
-
-//sys GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses
-//sys GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
-//sys MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW
-//sys GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
-//sys SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf uintptr, bufsize uint32) (err error) = kernel32.SetFileInformationByHandle
-//sys VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) = kernel32.VirtualQuery
-
-const (
- // flags for CreateToolhelp32Snapshot
- TH32CS_SNAPMODULE = 0x08
- TH32CS_SNAPMODULE32 = 0x10
-)
-
-const MAX_MODULE_NAME32 = 255
-
-type ModuleEntry32 struct {
- Size uint32
- ModuleID uint32
- ProcessID uint32
- GlblcntUsage uint32
- ProccntUsage uint32
- ModBaseAddr uintptr
- ModBaseSize uint32
- ModuleHandle syscall.Handle
- Module [MAX_MODULE_NAME32 + 1]uint16
- ExePath [syscall.MAX_PATH]uint16
-}
-
-const SizeofModuleEntry32 = unsafe.Sizeof(ModuleEntry32{})
-
-//sys Module32First(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW
-//sys Module32Next(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32NextW
-
-const (
- WSA_FLAG_OVERLAPPED = 0x01
- WSA_FLAG_NO_HANDLE_INHERIT = 0x80
-
- WSAEMSGSIZE syscall.Errno = 10040
-
- MSG_PEEK = 0x2
- MSG_TRUNC = 0x0100
- MSG_CTRUNC = 0x0200
-
- socket_error = uintptr(^uint32(0))
-)
-
-var WSAID_WSASENDMSG = syscall.GUID{
- Data1: 0xa441e712,
- Data2: 0x754f,
- Data3: 0x43ca,
- Data4: [8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d},
-}
-
-var WSAID_WSARECVMSG = syscall.GUID{
- Data1: 0xf689d7c8,
- Data2: 0x6f1f,
- Data3: 0x436b,
- Data4: [8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22},
-}
-
-var sendRecvMsgFunc struct {
- once sync.Once
- sendAddr uintptr
- recvAddr uintptr
- err error
-}
-
-type WSAMsg struct {
- Name syscall.Pointer
- Namelen int32
- Buffers *syscall.WSABuf
- BufferCount uint32
- Control syscall.WSABuf
- Flags uint32
-}
-
-//sys WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = ws2_32.WSASocketW
-
-func loadWSASendRecvMsg() error {
- sendRecvMsgFunc.once.Do(func() {
- var s syscall.Handle
- s, sendRecvMsgFunc.err = syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
- if sendRecvMsgFunc.err != nil {
- return
- }
- defer syscall.CloseHandle(s)
- var n uint32
- sendRecvMsgFunc.err = syscall.WSAIoctl(s,
- syscall.SIO_GET_EXTENSION_FUNCTION_POINTER,
- (*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)),
- uint32(unsafe.Sizeof(WSAID_WSARECVMSG)),
- (*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)),
- uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)),
- &n, nil, 0)
- if sendRecvMsgFunc.err != nil {
- return
- }
- sendRecvMsgFunc.err = syscall.WSAIoctl(s,
- syscall.SIO_GET_EXTENSION_FUNCTION_POINTER,
- (*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)),
- uint32(unsafe.Sizeof(WSAID_WSASENDMSG)),
- (*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)),
- uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)),
- &n, nil, 0)
- })
- return sendRecvMsgFunc.err
-}
-
-func WSASendMsg(fd syscall.Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *syscall.Overlapped, croutine *byte) error {
- err := loadWSASendRecvMsg()
- if err != nil {
- return err
- }
- r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
- if r1 == socket_error {
- if e1 != 0 {
- err = errnoErr(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return err
-}
-
-func WSARecvMsg(fd syscall.Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *syscall.Overlapped, croutine *byte) error {
- err := loadWSASendRecvMsg()
- if err != nil {
- return err
- }
- r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0)
- if r1 == socket_error {
- if e1 != 0 {
- err = errnoErr(e1)
- } else {
- err = syscall.EINVAL
- }
- }
- return err
-}
-
-const (
- ComputerNameNetBIOS = 0
- ComputerNameDnsHostname = 1
- ComputerNameDnsDomain = 2
- ComputerNameDnsFullyQualified = 3
- ComputerNamePhysicalNetBIOS = 4
- ComputerNamePhysicalDnsHostname = 5
- ComputerNamePhysicalDnsDomain = 6
- ComputerNamePhysicalDnsFullyQualified = 7
- ComputerNameMax = 8
-
- MOVEFILE_REPLACE_EXISTING = 0x1
- MOVEFILE_COPY_ALLOWED = 0x2
- MOVEFILE_DELAY_UNTIL_REBOOT = 0x4
- MOVEFILE_WRITE_THROUGH = 0x8
- MOVEFILE_CREATE_HARDLINK = 0x10
- MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
-)
-
-func Rename(oldpath, newpath string) error {
- from, err := syscall.UTF16PtrFromString(oldpath)
- if err != nil {
- return err
- }
- to, err := syscall.UTF16PtrFromString(newpath)
- if err != nil {
- return err
- }
- return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING)
-}
-
-//sys LockFileEx(file syscall.Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.LockFileEx
-//sys UnlockFileEx(file syscall.Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.UnlockFileEx
-
-const (
- LOCKFILE_FAIL_IMMEDIATELY = 0x00000001
- LOCKFILE_EXCLUSIVE_LOCK = 0x00000002
-)
-
-const MB_ERR_INVALID_CHARS = 8
-
-//sys GetACP() (acp uint32) = kernel32.GetACP
-//sys GetConsoleCP() (ccp uint32) = kernel32.GetConsoleCP
-//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
-//sys GetCurrentThread() (pseudoHandle syscall.Handle, err error) = kernel32.GetCurrentThread
-
-const STYPE_DISKTREE = 0x00
-
-type SHARE_INFO_2 struct {
- Netname *uint16
- Type uint32
- Remark *uint16
- Permissions uint32
- MaxUses uint32
- CurrentUses uint32
- Path *uint16
- Passwd *uint16
-}
-
-//sys NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) = netapi32.NetShareAdd
-//sys NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) = netapi32.NetShareDel
-
-const (
- FILE_NAME_NORMALIZED = 0x0
- FILE_NAME_OPENED = 0x8
-
- VOLUME_NAME_DOS = 0x0
- VOLUME_NAME_GUID = 0x1
- VOLUME_NAME_NONE = 0x4
- VOLUME_NAME_NT = 0x2
-)
-
-//sys GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) = kernel32.GetFinalPathNameByHandleW
-
-func LoadGetFinalPathNameByHandle() error {
- return procGetFinalPathNameByHandleW.Find()
-}
-
-//sys CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock
-//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
-
-//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/sysdll/ya.make b/contrib/go/_std_1.20/src/internal/syscall/windows/sysdll/ya.make
deleted file mode 100644
index 7f2cd0fe71..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/sysdll/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-GO_LIBRARY()
-
-BUILD_ONLY_IF(WARNING OS_WINDOWS)
-
-IF (OS_WINDOWS)
- SRCS(
- sysdll.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/ya.make b/contrib/go/_std_1.20/src/internal/syscall/windows/ya.make
deleted file mode 100644
index 34b9e2d231..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/ya.make
+++ /dev/null
@@ -1,25 +0,0 @@
-GO_LIBRARY()
-
-BUILD_ONLY_IF(WARNING OS_WINDOWS)
-
-IF (OS_WINDOWS)
- SRCS(
- memory_windows.go
- net_windows.go
- psapi_windows.go
- reparse_windows.go
- security_windows.go
- symlink_windows.go
- syscall_windows.go
- zsyscall_windows.go
- )
-ENDIF()
-
-END()
-
-IF (OS_WINDOWS)
- RECURSE(
- registry
- sysdll
- )
-ENDIF()
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/zsyscall_windows.go b/contrib/go/_std_1.20/src/internal/syscall/windows/zsyscall_windows.go
deleted file mode 100644
index afd64e318e..0000000000
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/zsyscall_windows.go
+++ /dev/null
@@ -1,354 +0,0 @@
-// Code generated by 'go generate'; DO NOT EDIT.
-
-package windows
-
-import (
- "internal/syscall/windows/sysdll"
- "syscall"
- "unsafe"
-)
-
-var _ unsafe.Pointer
-
-// Do the interface allocations only once for common
-// Errno values.
-const (
- errnoERROR_IO_PENDING = 997
-)
-
-var (
- errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
- errERROR_EINVAL error = syscall.EINVAL
-)
-
-// errnoErr returns common boxed Errno values, to prevent
-// allocations at runtime.
-func errnoErr(e syscall.Errno) error {
- switch e {
- case 0:
- return errERROR_EINVAL
- case errnoERROR_IO_PENDING:
- return errERROR_IO_PENDING
- }
- // TODO: add more here, after collecting data on the common
- // error values see on Windows. (perhaps when running
- // all.bat?)
- return e
-}
-
-var (
- modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll"))
- modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll"))
- modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll"))
- modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll"))
- modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll"))
- moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll"))
- modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll"))
-
- procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
- procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx")
- procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
- procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
- procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
- procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
- procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation")
- procSystemFunction036 = modadvapi32.NewProc("SystemFunction036")
- procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
- procGetACP = modkernel32.NewProc("GetACP")
- procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW")
- procGetConsoleCP = modkernel32.NewProc("GetConsoleCP")
- procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
- procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
- procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW")
- procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW")
- procLockFileEx = modkernel32.NewProc("LockFileEx")
- procModule32FirstW = modkernel32.NewProc("Module32FirstW")
- procModule32NextW = modkernel32.NewProc("Module32NextW")
- procMoveFileExW = modkernel32.NewProc("MoveFileExW")
- procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar")
- procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle")
- procUnlockFileEx = modkernel32.NewProc("UnlockFileEx")
- procVirtualQuery = modkernel32.NewProc("VirtualQuery")
- procNetShareAdd = modnetapi32.NewProc("NetShareAdd")
- procNetShareDel = modnetapi32.NewProc("NetShareDel")
- procNetUserGetLocalGroups = modnetapi32.NewProc("NetUserGetLocalGroups")
- procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
- procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
- procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
- procGetProfilesDirectoryW = moduserenv.NewProc("GetProfilesDirectoryW")
- procWSASocketW = modws2_32.NewProc("WSASocketW")
-)
-
-func adjustTokenPrivileges(token syscall.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) (ret uint32, err error) {
- var _p0 uint32
- if disableAllPrivileges {
- _p0 = 1
- }
- r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen)))
- ret = uint32(r0)
- if true {
- err = errnoErr(e1)
- }
- return
-}
-
-func DuplicateTokenEx(hExistingToken syscall.Token, dwDesiredAccess uint32, lpTokenAttributes *syscall.SecurityAttributes, impersonationLevel uint32, tokenType TokenType, phNewToken *syscall.Token) (err error) {
- r1, _, e1 := syscall.Syscall6(procDuplicateTokenEx.Addr(), 6, uintptr(hExistingToken), uintptr(dwDesiredAccess), uintptr(unsafe.Pointer(lpTokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(phNewToken)))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func ImpersonateSelf(impersonationlevel uint32) (err error) {
- r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(impersonationlevel), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) {
- r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemname)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func OpenThreadToken(h syscall.Handle, access uint32, openasself bool, token *syscall.Token) (err error) {
- var _p0 uint32
- if openasself {
- _p0 = 1
- }
- r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(h), uintptr(access), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func RevertToSelf() (err error) {
- r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32, tokenInformation uintptr, tokenInformationLength uint32) (err error) {
- r1, _, e1 := syscall.Syscall6(procSetTokenInformation.Addr(), 4, uintptr(tokenHandle), uintptr(tokenInformationClass), uintptr(tokenInformation), uintptr(tokenInformationLength), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func RtlGenRandom(buf []byte) (err error) {
- var _p0 *byte
- if len(buf) > 0 {
- _p0 = &buf[0]
- }
- r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
- r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0)
- if r0 != 0 {
- errcode = syscall.Errno(r0)
- }
- return
-}
-
-func GetACP() (acp uint32) {
- r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0)
- acp = uint32(r0)
- return
-}
-
-func GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) {
- r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nameformat), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetConsoleCP() (ccp uint32) {
- r0, _, _ := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0)
- ccp = uint32(r0)
- return
-}
-
-func GetCurrentThread() (pseudoHandle syscall.Handle, err error) {
- r0, _, e1 := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
- pseudoHandle = syscall.Handle(r0)
- if pseudoHandle == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetFileInformationByHandleEx(handle syscall.Handle, class uint32, info *byte, bufsize uint32) (err error) {
- r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(info)), uintptr(bufsize), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) {
- r0, _, e1 := syscall.Syscall6(procGetFinalPathNameByHandleW.Addr(), 4, uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags), 0, 0)
- n = uint32(r0)
- if n == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) {
- r0, _, e1 := syscall.Syscall(procGetModuleFileNameW.Addr(), 3, uintptr(module), uintptr(unsafe.Pointer(fn)), uintptr(len))
- n = uint32(r0)
- if n == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func LockFileEx(file syscall.Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) {
- r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(file), uintptr(flags), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped)))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func Module32First(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) {
- r1, _, e1 := syscall.Syscall(procModule32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func Module32Next(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) {
- r1, _, e1 := syscall.Syscall(procModule32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) {
- r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) {
- r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar))
- nwrite = int32(r0)
- if nwrite == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf uintptr, bufsize uint32) (err error) {
- r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(handle), uintptr(fileInformationClass), uintptr(buf), uintptr(bufsize), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func UnlockFileEx(file syscall.Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) {
- r1, _, e1 := syscall.Syscall6(procUnlockFileEx.Addr(), 5, uintptr(file), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) {
- r1, _, e1 := syscall.Syscall(procVirtualQuery.Addr(), 3, uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) {
- r0, _, _ := syscall.Syscall6(procNetShareAdd.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(parmErr)), 0, 0)
- if r0 != 0 {
- neterr = syscall.Errno(r0)
- }
- return
-}
-
-func NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) {
- r0, _, _ := syscall.Syscall(procNetShareDel.Addr(), 3, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(netName)), uintptr(reserved))
- if r0 != 0 {
- neterr = syscall.Errno(r0)
- }
- return
-}
-
-func NetUserGetLocalGroups(serverName *uint16, userName *uint16, level uint32, flags uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32) (neterr error) {
- r0, _, _ := syscall.Syscall9(procNetUserGetLocalGroups.Addr(), 8, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(flags), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), 0)
- if r0 != 0 {
- neterr = syscall.Errno(r0)
- }
- return
-}
-
-func GetProcessMemoryInfo(handle syscall.Handle, memCounters *PROCESS_MEMORY_COUNTERS, cb uint32) (err error) {
- r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(memCounters)), uintptr(cb))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) {
- var _p0 uint32
- if inheritExisting {
- _p0 = 1
- }
- r1, _, e1 := syscall.Syscall(procCreateEnvironmentBlock.Addr(), 3, uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func DestroyEnvironmentBlock(block *uint16) (err error) {
- r1, _, e1 := syscall.Syscall(procDestroyEnvironmentBlock.Addr(), 1, uintptr(unsafe.Pointer(block)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetProfilesDirectory(dir *uint16, dirLen *uint32) (err error) {
- r1, _, e1 := syscall.Syscall(procGetProfilesDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) {
- r0, _, e1 := syscall.Syscall6(procWSASocketW.Addr(), 6, uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protinfo)), uintptr(group), uintptr(flags))
- handle = syscall.Handle(r0)
- if handle == syscall.InvalidHandle {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/contrib/go/_std_1.20/src/internal/types/errors/codes.go b/contrib/go/_std_1.20/src/internal/types/errors/codes.go
deleted file mode 100644
index acddcbb9c5..0000000000
--- a/contrib/go/_std_1.20/src/internal/types/errors/codes.go
+++ /dev/null
@@ -1,1442 +0,0 @@
-// 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 errors
-
-type Code int
-
-// This file defines the error codes that can be produced during type-checking.
-// Collectively, these codes provide an identifier that may be used to
-// implement special handling for certain types of errors.
-//
-// Error code values should not be changed: add new codes at the end.
-//
-// Error codes should be fine-grained enough that the exact nature of the error
-// can be easily determined, but coarse enough that they are not an
-// implementation detail of the type checking algorithm. As a rule-of-thumb,
-// errors should be considered equivalent if there is a theoretical refactoring
-// of the type checker in which they are emitted in exactly one place. For
-// example, the type checker emits different error messages for "too many
-// arguments" and "too few arguments", but one can imagine an alternative type
-// checker where this check instead just emits a single "wrong number of
-// arguments", so these errors should have the same code.
-//
-// Error code names should be as brief as possible while retaining accuracy and
-// distinctiveness. In most cases names should start with an adjective
-// describing the nature of the error (e.g. "invalid", "unused", "misplaced"),
-// and end with a noun identifying the relevant language object. For example,
-// "_DuplicateDecl" or "_InvalidSliceExpr". For brevity, naming follows the
-// convention that "bad" implies a problem with syntax, and "invalid" implies a
-// problem with types.
-
-const (
- // InvalidSyntaxTree occurs if an invalid syntax tree is provided
- // to the type checker. It should never happen.
- InvalidSyntaxTree Code = -1
-)
-
-const (
- // The zero Code value indicates an unset (invalid) error code.
- _ Code = iota
-
- // Test is reserved for errors that only apply while in self-test mode.
- Test
-
- // BlankPkgName occurs when a package name is the blank identifier "_".
- //
- // Per the spec:
- // "The PackageName must not be the blank identifier."
- //
- // Example:
- // package _
- BlankPkgName
-
- // MismatchedPkgName occurs when a file's package name doesn't match the
- // package name already established by other files.
- MismatchedPkgName
-
- // InvalidPkgUse occurs when a package identifier is used outside of a
- // selector expression.
- //
- // Example:
- // import "fmt"
- //
- // var _ = fmt
- InvalidPkgUse
-
- // BadImportPath occurs when an import path is not valid.
- BadImportPath
-
- // BrokenImport occurs when importing a package fails.
- //
- // Example:
- // import "amissingpackage"
- BrokenImport
-
- // ImportCRenamed occurs when the special import "C" is renamed. "C" is a
- // pseudo-package, and must not be renamed.
- //
- // Example:
- // import _ "C"
- ImportCRenamed
-
- // UnusedImport occurs when an import is unused.
- //
- // Example:
- // import "fmt"
- //
- // func main() {}
- UnusedImport
-
- // InvalidInitCycle occurs when an invalid cycle is detected within the
- // initialization graph.
- //
- // Example:
- // var x int = f()
- //
- // func f() int { return x }
- InvalidInitCycle
-
- // DuplicateDecl occurs when an identifier is declared multiple times.
- //
- // Example:
- // var x = 1
- // var x = 2
- DuplicateDecl
-
- // InvalidDeclCycle occurs when a declaration cycle is not valid.
- //
- // Example:
- // type S struct {
- // S
- // }
- //
- InvalidDeclCycle
-
- // InvalidTypeCycle occurs when a cycle in type definitions results in a
- // type that is not well-defined.
- //
- // Example:
- // import "unsafe"
- //
- // type T [unsafe.Sizeof(T{})]int
- InvalidTypeCycle
-
- // InvalidConstInit occurs when a const declaration has a non-constant
- // initializer.
- //
- // Example:
- // var x int
- // const _ = x
- InvalidConstInit
-
- // InvalidConstVal occurs when a const value cannot be converted to its
- // target type.
- //
- // TODO(findleyr): this error code and example are not very clear. Consider
- // removing it.
- //
- // Example:
- // const _ = 1 << "hello"
- InvalidConstVal
-
- // InvalidConstType occurs when the underlying type in a const declaration
- // is not a valid constant type.
- //
- // Example:
- // const c *int = 4
- InvalidConstType
-
- // UntypedNilUse occurs when the predeclared (untyped) value nil is used to
- // initialize a variable declared without an explicit type.
- //
- // Example:
- // var x = nil
- UntypedNilUse
-
- // WrongAssignCount occurs when the number of values on the right-hand side
- // of an assignment or initialization expression does not match the number
- // of variables on the left-hand side.
- //
- // Example:
- // var x = 1, 2
- WrongAssignCount
-
- // UnassignableOperand occurs when the left-hand side of an assignment is
- // not assignable.
- //
- // Example:
- // func f() {
- // const c = 1
- // c = 2
- // }
- UnassignableOperand
-
- // NoNewVar occurs when a short variable declaration (':=') does not declare
- // new variables.
- //
- // Example:
- // func f() {
- // x := 1
- // x := 2
- // }
- NoNewVar
-
- // MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does
- // not have single-valued left-hand or right-hand side.
- //
- // Per the spec:
- // "In assignment operations, both the left- and right-hand expression lists
- // must contain exactly one single-valued expression"
- //
- // Example:
- // func f() int {
- // x, y := 1, 2
- // x, y += 1
- // return x + y
- // }
- MultiValAssignOp
-
- // InvalidIfaceAssign occurs when a value of type T is used as an
- // interface, but T does not implement a method of the expected interface.
- //
- // Example:
- // type I interface {
- // f()
- // }
- //
- // type T int
- //
- // var x I = T(1)
- InvalidIfaceAssign
-
- // InvalidChanAssign occurs when a chan assignment is invalid.
- //
- // Per the spec, a value x is assignable to a channel type T if:
- // "x is a bidirectional channel value, T is a channel type, x's type V and
- // T have identical element types, and at least one of V or T is not a
- // defined type."
- //
- // Example:
- // type T1 chan int
- // type T2 chan int
- //
- // var x T1
- // // Invalid assignment because both types are named
- // var _ T2 = x
- InvalidChanAssign
-
- // IncompatibleAssign occurs when the type of the right-hand side expression
- // in an assignment cannot be assigned to the type of the variable being
- // assigned.
- //
- // Example:
- // var x []int
- // var _ int = x
- IncompatibleAssign
-
- // UnaddressableFieldAssign occurs when trying to assign to a struct field
- // in a map value.
- //
- // Example:
- // func f() {
- // m := make(map[string]struct{i int})
- // m["foo"].i = 42
- // }
- UnaddressableFieldAssign
-
- // NotAType occurs when the identifier used as the underlying type in a type
- // declaration or the right-hand side of a type alias does not denote a type.
- //
- // Example:
- // var S = 2
- //
- // type T S
- NotAType
-
- // InvalidArrayLen occurs when an array length is not a constant value.
- //
- // Example:
- // var n = 3
- // var _ = [n]int{}
- InvalidArrayLen
-
- // BlankIfaceMethod occurs when a method name is '_'.
- //
- // Per the spec:
- // "The name of each explicitly specified method must be unique and not
- // blank."
- //
- // Example:
- // type T interface {
- // _(int)
- // }
- BlankIfaceMethod
-
- // IncomparableMapKey occurs when a map key type does not support the == and
- // != operators.
- //
- // Per the spec:
- // "The comparison operators == and != must be fully defined for operands of
- // the key type; thus the key type must not be a function, map, or slice."
- //
- // Example:
- // var x map[T]int
- //
- // type T []int
- IncomparableMapKey
-
- // InvalidIfaceEmbed occurs when a non-interface type is embedded in an
- // interface (for go 1.17 or earlier).
- _ // not used anymore
-
- // InvalidPtrEmbed occurs when an embedded field is of the pointer form *T,
- // and T itself is itself a pointer, an unsafe.Pointer, or an interface.
- //
- // Per the spec:
- // "An embedded field must be specified as a type name T or as a pointer to
- // a non-interface type name *T, and T itself may not be a pointer type."
- //
- // Example:
- // type T *int
- //
- // type S struct {
- // *T
- // }
- InvalidPtrEmbed
-
- // BadRecv occurs when a method declaration does not have exactly one
- // receiver parameter.
- //
- // Example:
- // func () _() {}
- BadRecv
-
- // InvalidRecv occurs when a receiver type expression is not of the form T
- // or *T, or T is a pointer type.
- //
- // Example:
- // type T struct {}
- //
- // func (**T) m() {}
- InvalidRecv
-
- // DuplicateFieldAndMethod occurs when an identifier appears as both a field
- // and method name.
- //
- // Example:
- // type T struct {
- // m int
- // }
- //
- // func (T) m() {}
- DuplicateFieldAndMethod
-
- // DuplicateMethod occurs when two methods on the same receiver type have
- // the same name.
- //
- // Example:
- // type T struct {}
- // func (T) m() {}
- // func (T) m(i int) int { return i }
- DuplicateMethod
-
- // InvalidBlank occurs when a blank identifier is used as a value or type.
- //
- // Per the spec:
- // "The blank identifier may appear as an operand only on the left-hand side
- // of an assignment."
- //
- // Example:
- // var x = _
- InvalidBlank
-
- // InvalidIota occurs when the predeclared identifier iota is used outside
- // of a constant declaration.
- //
- // Example:
- // var x = iota
- InvalidIota
-
- // MissingInitBody occurs when an init function is missing its body.
- //
- // Example:
- // func init()
- MissingInitBody
-
- // InvalidInitSig occurs when an init function declares parameters or
- // results.
- //
- // Deprecated: no longer emitted by the type checker. _InvalidInitDecl is
- // used instead.
- InvalidInitSig
-
- // InvalidInitDecl occurs when init is declared as anything other than a
- // function.
- //
- // Example:
- // var init = 1
- //
- // Example:
- // func init() int { return 1 }
- InvalidInitDecl
-
- // InvalidMainDecl occurs when main is declared as anything other than a
- // function, in a main package.
- InvalidMainDecl
-
- // TooManyValues occurs when a function returns too many values for the
- // expression context in which it is used.
- //
- // Example:
- // func ReturnTwo() (int, int) {
- // return 1, 2
- // }
- //
- // var x = ReturnTwo()
- TooManyValues
-
- // NotAnExpr occurs when a type expression is used where a value expression
- // is expected.
- //
- // Example:
- // type T struct {}
- //
- // func f() {
- // T
- // }
- NotAnExpr
-
- // TruncatedFloat occurs when a float constant is truncated to an integer
- // value.
- //
- // Example:
- // var _ int = 98.6
- TruncatedFloat
-
- // NumericOverflow occurs when a numeric constant overflows its target type.
- //
- // Example:
- // var x int8 = 1000
- NumericOverflow
-
- // UndefinedOp occurs when an operator is not defined for the type(s) used
- // in an operation.
- //
- // Example:
- // var c = "a" - "b"
- UndefinedOp
-
- // MismatchedTypes occurs when operand types are incompatible in a binary
- // operation.
- //
- // Example:
- // var a = "hello"
- // var b = 1
- // var c = a - b
- MismatchedTypes
-
- // DivByZero occurs when a division operation is provable at compile
- // time to be a division by zero.
- //
- // Example:
- // const divisor = 0
- // var x int = 1/divisor
- DivByZero
-
- // NonNumericIncDec occurs when an increment or decrement operator is
- // applied to a non-numeric value.
- //
- // Example:
- // func f() {
- // var c = "c"
- // c++
- // }
- NonNumericIncDec
-
- // UnaddressableOperand occurs when the & operator is applied to an
- // unaddressable expression.
- //
- // Example:
- // var x = &1
- UnaddressableOperand
-
- // InvalidIndirection occurs when a non-pointer value is indirected via the
- // '*' operator.
- //
- // Example:
- // var x int
- // var y = *x
- InvalidIndirection
-
- // NonIndexableOperand occurs when an index operation is applied to a value
- // that cannot be indexed.
- //
- // Example:
- // var x = 1
- // var y = x[1]
- NonIndexableOperand
-
- // InvalidIndex occurs when an index argument is not of integer type,
- // negative, or out-of-bounds.
- //
- // Example:
- // var s = [...]int{1,2,3}
- // var x = s[5]
- //
- // Example:
- // var s = []int{1,2,3}
- // var _ = s[-1]
- //
- // Example:
- // var s = []int{1,2,3}
- // var i string
- // var _ = s[i]
- InvalidIndex
-
- // SwappedSliceIndices occurs when constant indices in a slice expression
- // are decreasing in value.
- //
- // Example:
- // var _ = []int{1,2,3}[2:1]
- SwappedSliceIndices
-
- // NonSliceableOperand occurs when a slice operation is applied to a value
- // whose type is not sliceable, or is unaddressable.
- //
- // Example:
- // var x = [...]int{1, 2, 3}[:1]
- //
- // Example:
- // var x = 1
- // var y = 1[:1]
- NonSliceableOperand
-
- // InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is
- // applied to a string.
- //
- // Example:
- // var s = "hello"
- // var x = s[1:2:3]
- InvalidSliceExpr
-
- // InvalidShiftCount occurs when the right-hand side of a shift operation is
- // either non-integer, negative, or too large.
- //
- // Example:
- // var (
- // x string
- // y int = 1 << x
- // )
- InvalidShiftCount
-
- // InvalidShiftOperand occurs when the shifted operand is not an integer.
- //
- // Example:
- // var s = "hello"
- // var x = s << 2
- InvalidShiftOperand
-
- // InvalidReceive occurs when there is a channel receive from a value that
- // is either not a channel, or is a send-only channel.
- //
- // Example:
- // func f() {
- // var x = 1
- // <-x
- // }
- InvalidReceive
-
- // InvalidSend occurs when there is a channel send to a value that is not a
- // channel, or is a receive-only channel.
- //
- // Example:
- // func f() {
- // var x = 1
- // x <- "hello!"
- // }
- InvalidSend
-
- // DuplicateLitKey occurs when an index is duplicated in a slice, array, or
- // map literal.
- //
- // Example:
- // var _ = []int{0:1, 0:2}
- //
- // Example:
- // var _ = map[string]int{"a": 1, "a": 2}
- DuplicateLitKey
-
- // MissingLitKey occurs when a map literal is missing a key expression.
- //
- // Example:
- // var _ = map[string]int{1}
- MissingLitKey
-
- // InvalidLitIndex occurs when the key in a key-value element of a slice or
- // array literal is not an integer constant.
- //
- // Example:
- // var i = 0
- // var x = []string{i: "world"}
- InvalidLitIndex
-
- // OversizeArrayLit occurs when an array literal exceeds its length.
- //
- // Example:
- // var _ = [2]int{1,2,3}
- OversizeArrayLit
-
- // MixedStructLit occurs when a struct literal contains a mix of positional
- // and named elements.
- //
- // Example:
- // var _ = struct{i, j int}{i: 1, 2}
- MixedStructLit
-
- // InvalidStructLit occurs when a positional struct literal has an incorrect
- // number of values.
- //
- // Example:
- // var _ = struct{i, j int}{1,2,3}
- InvalidStructLit
-
- // MissingLitField occurs when a struct literal refers to a field that does
- // not exist on the struct type.
- //
- // Example:
- // var _ = struct{i int}{j: 2}
- MissingLitField
-
- // DuplicateLitField occurs when a struct literal contains duplicated
- // fields.
- //
- // Example:
- // var _ = struct{i int}{i: 1, i: 2}
- DuplicateLitField
-
- // UnexportedLitField occurs when a positional struct literal implicitly
- // assigns an unexported field of an imported type.
- UnexportedLitField
-
- // InvalidLitField occurs when a field name is not a valid identifier.
- //
- // Example:
- // var _ = struct{i int}{1: 1}
- InvalidLitField
-
- // UntypedLit occurs when a composite literal omits a required type
- // identifier.
- //
- // Example:
- // type outer struct{
- // inner struct { i int }
- // }
- //
- // var _ = outer{inner: {1}}
- UntypedLit
-
- // InvalidLit occurs when a composite literal expression does not match its
- // type.
- //
- // Example:
- // type P *struct{
- // x int
- // }
- // var _ = P {}
- InvalidLit
-
- // AmbiguousSelector occurs when a selector is ambiguous.
- //
- // Example:
- // type E1 struct { i int }
- // type E2 struct { i int }
- // type T struct { E1; E2 }
- //
- // var x T
- // var _ = x.i
- AmbiguousSelector
-
- // UndeclaredImportedName occurs when a package-qualified identifier is
- // undeclared by the imported package.
- //
- // Example:
- // import "go/types"
- //
- // var _ = types.NotAnActualIdentifier
- UndeclaredImportedName
-
- // UnexportedName occurs when a selector refers to an unexported identifier
- // of an imported package.
- //
- // Example:
- // import "reflect"
- //
- // type _ reflect.flag
- UnexportedName
-
- // UndeclaredName occurs when an identifier is not declared in the current
- // scope.
- //
- // Example:
- // var x T
- UndeclaredName
-
- // MissingFieldOrMethod occurs when a selector references a field or method
- // that does not exist.
- //
- // Example:
- // type T struct {}
- //
- // var x = T{}.f
- MissingFieldOrMethod
-
- // BadDotDotDotSyntax occurs when a "..." occurs in a context where it is
- // not valid.
- //
- // Example:
- // var _ = map[int][...]int{0: {}}
- BadDotDotDotSyntax
-
- // NonVariadicDotDotDot occurs when a "..." is used on the final argument to
- // a non-variadic function.
- //
- // Example:
- // func printArgs(s []string) {
- // for _, a := range s {
- // println(a)
- // }
- // }
- //
- // func f() {
- // s := []string{"a", "b", "c"}
- // printArgs(s...)
- // }
- NonVariadicDotDotDot
-
- // MisplacedDotDotDot occurs when a "..." is used somewhere other than the
- // final argument in a function declaration.
- //
- // Example:
- // func f(...int, int)
- MisplacedDotDotDot
-
- _ // InvalidDotDotDotOperand was removed.
-
- // InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in
- // function.
- //
- // Example:
- // var s = []int{1, 2, 3}
- // var l = len(s...)
- InvalidDotDotDot
-
- // UncalledBuiltin occurs when a built-in function is used as a
- // function-valued expression, instead of being called.
- //
- // Per the spec:
- // "The built-in functions do not have standard Go types, so they can only
- // appear in call expressions; they cannot be used as function values."
- //
- // Example:
- // var _ = copy
- UncalledBuiltin
-
- // InvalidAppend occurs when append is called with a first argument that is
- // not a slice.
- //
- // Example:
- // var _ = append(1, 2)
- InvalidAppend
-
- // InvalidCap occurs when an argument to the cap built-in function is not of
- // supported type.
- //
- // See https://golang.org/ref/spec#Length_and_capacity for information on
- // which underlying types are supported as arguments to cap and len.
- //
- // Example:
- // var s = 2
- // var x = cap(s)
- InvalidCap
-
- // InvalidClose occurs when close(...) is called with an argument that is
- // not of channel type, or that is a receive-only channel.
- //
- // Example:
- // func f() {
- // var x int
- // close(x)
- // }
- InvalidClose
-
- // InvalidCopy occurs when the arguments are not of slice type or do not
- // have compatible type.
- //
- // See https://golang.org/ref/spec#Appending_and_copying_slices for more
- // information on the type requirements for the copy built-in.
- //
- // Example:
- // func f() {
- // var x []int
- // y := []int64{1,2,3}
- // copy(x, y)
- // }
- InvalidCopy
-
- // InvalidComplex occurs when the complex built-in function is called with
- // arguments with incompatible types.
- //
- // Example:
- // var _ = complex(float32(1), float64(2))
- InvalidComplex
-
- // InvalidDelete occurs when the delete built-in function is called with a
- // first argument that is not a map.
- //
- // Example:
- // func f() {
- // m := "hello"
- // delete(m, "e")
- // }
- InvalidDelete
-
- // InvalidImag occurs when the imag built-in function is called with an
- // argument that does not have complex type.
- //
- // Example:
- // var _ = imag(int(1))
- InvalidImag
-
- // InvalidLen occurs when an argument to the len built-in function is not of
- // supported type.
- //
- // See https://golang.org/ref/spec#Length_and_capacity for information on
- // which underlying types are supported as arguments to cap and len.
- //
- // Example:
- // var s = 2
- // var x = len(s)
- InvalidLen
-
- // SwappedMakeArgs occurs when make is called with three arguments, and its
- // length argument is larger than its capacity argument.
- //
- // Example:
- // var x = make([]int, 3, 2)
- SwappedMakeArgs
-
- // InvalidMake occurs when make is called with an unsupported type argument.
- //
- // See https://golang.org/ref/spec#Making_slices_maps_and_channels for
- // information on the types that may be created using make.
- //
- // Example:
- // var x = make(int)
- InvalidMake
-
- // InvalidReal occurs when the real built-in function is called with an
- // argument that does not have complex type.
- //
- // Example:
- // var _ = real(int(1))
- InvalidReal
-
- // InvalidAssert occurs when a type assertion is applied to a
- // value that is not of interface type.
- //
- // Example:
- // var x = 1
- // var _ = x.(float64)
- InvalidAssert
-
- // ImpossibleAssert occurs for a type assertion x.(T) when the value x of
- // interface cannot have dynamic type T, due to a missing or mismatching
- // method on T.
- //
- // Example:
- // type T int
- //
- // func (t *T) m() int { return int(*t) }
- //
- // type I interface { m() int }
- //
- // var x I
- // var _ = x.(T)
- ImpossibleAssert
-
- // InvalidConversion occurs when the argument type cannot be converted to the
- // target.
- //
- // See https://golang.org/ref/spec#Conversions for the rules of
- // convertibility.
- //
- // Example:
- // var x float64
- // var _ = string(x)
- InvalidConversion
-
- // InvalidUntypedConversion occurs when there is no valid implicit
- // conversion from an untyped value satisfying the type constraints of the
- // context in which it is used.
- //
- // Example:
- // var _ = 1 + []int{}
- InvalidUntypedConversion
-
- // BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument
- // that is not a selector expression.
- //
- // Example:
- // import "unsafe"
- //
- // var x int
- // var _ = unsafe.Offsetof(x)
- BadOffsetofSyntax
-
- // InvalidOffsetof occurs when unsafe.Offsetof is called with a method
- // selector, rather than a field selector, or when the field is embedded via
- // a pointer.
- //
- // Per the spec:
- //
- // "If f is an embedded field, it must be reachable without pointer
- // indirections through fields of the struct. "
- //
- // Example:
- // import "unsafe"
- //
- // type T struct { f int }
- // type S struct { *T }
- // var s S
- // var _ = unsafe.Offsetof(s.f)
- //
- // Example:
- // import "unsafe"
- //
- // type S struct{}
- //
- // func (S) m() {}
- //
- // var s S
- // var _ = unsafe.Offsetof(s.m)
- InvalidOffsetof
-
- // UnusedExpr occurs when a side-effect free expression is used as a
- // statement. Such a statement has no effect.
- //
- // Example:
- // func f(i int) {
- // i*i
- // }
- UnusedExpr
-
- // UnusedVar occurs when a variable is declared but unused.
- //
- // Example:
- // func f() {
- // x := 1
- // }
- UnusedVar
-
- // MissingReturn occurs when a function with results is missing a return
- // statement.
- //
- // Example:
- // func f() int {}
- MissingReturn
-
- // WrongResultCount occurs when a return statement returns an incorrect
- // number of values.
- //
- // Example:
- // func ReturnOne() int {
- // return 1, 2
- // }
- WrongResultCount
-
- // OutOfScopeResult occurs when the name of a value implicitly returned by
- // an empty return statement is shadowed in a nested scope.
- //
- // Example:
- // func factor(n int) (i int) {
- // for i := 2; i < n; i++ {
- // if n%i == 0 {
- // return
- // }
- // }
- // return 0
- // }
- OutOfScopeResult
-
- // InvalidCond occurs when an if condition is not a boolean expression.
- //
- // Example:
- // func checkReturn(i int) {
- // if i {
- // panic("non-zero return")
- // }
- // }
- InvalidCond
-
- // InvalidPostDecl occurs when there is a declaration in a for-loop post
- // statement.
- //
- // Example:
- // func f() {
- // for i := 0; i < 10; j := 0 {}
- // }
- InvalidPostDecl
-
- _ // InvalidChanRange was removed.
-
- // InvalidIterVar occurs when two iteration variables are used while ranging
- // over a channel.
- //
- // Example:
- // func f(c chan int) {
- // for k, v := range c {
- // println(k, v)
- // }
- // }
- InvalidIterVar
-
- // InvalidRangeExpr occurs when the type of a range expression is not array,
- // slice, string, map, or channel.
- //
- // Example:
- // func f(i int) {
- // for j := range i {
- // println(j)
- // }
- // }
- InvalidRangeExpr
-
- // MisplacedBreak occurs when a break statement is not within a for, switch,
- // or select statement of the innermost function definition.
- //
- // Example:
- // func f() {
- // break
- // }
- MisplacedBreak
-
- // MisplacedContinue occurs when a continue statement is not within a for
- // loop of the innermost function definition.
- //
- // Example:
- // func sumeven(n int) int {
- // proceed := func() {
- // continue
- // }
- // sum := 0
- // for i := 1; i <= n; i++ {
- // if i % 2 != 0 {
- // proceed()
- // }
- // sum += i
- // }
- // return sum
- // }
- MisplacedContinue
-
- // MisplacedFallthrough occurs when a fallthrough statement is not within an
- // expression switch.
- //
- // Example:
- // func typename(i interface{}) string {
- // switch i.(type) {
- // case int64:
- // fallthrough
- // case int:
- // return "int"
- // }
- // return "unsupported"
- // }
- MisplacedFallthrough
-
- // DuplicateCase occurs when a type or expression switch has duplicate
- // cases.
- //
- // Example:
- // func printInt(i int) {
- // switch i {
- // case 1:
- // println("one")
- // case 1:
- // println("One")
- // }
- // }
- DuplicateCase
-
- // DuplicateDefault occurs when a type or expression switch has multiple
- // default clauses.
- //
- // Example:
- // func printInt(i int) {
- // switch i {
- // case 1:
- // println("one")
- // default:
- // println("One")
- // default:
- // println("1")
- // }
- // }
- DuplicateDefault
-
- // BadTypeKeyword occurs when a .(type) expression is used anywhere other
- // than a type switch.
- //
- // Example:
- // type I interface {
- // m()
- // }
- // var t I
- // var _ = t.(type)
- BadTypeKeyword
-
- // InvalidTypeSwitch occurs when .(type) is used on an expression that is
- // not of interface type.
- //
- // Example:
- // func f(i int) {
- // switch x := i.(type) {}
- // }
- InvalidTypeSwitch
-
- // InvalidExprSwitch occurs when a switch expression is not comparable.
- //
- // Example:
- // func _() {
- // var a struct{ _ func() }
- // switch a /* ERROR cannot switch on a */ {
- // }
- // }
- InvalidExprSwitch
-
- // InvalidSelectCase occurs when a select case is not a channel send or
- // receive.
- //
- // Example:
- // func checkChan(c <-chan int) bool {
- // select {
- // case c:
- // return true
- // default:
- // return false
- // }
- // }
- InvalidSelectCase
-
- // UndeclaredLabel occurs when an undeclared label is jumped to.
- //
- // Example:
- // func f() {
- // goto L
- // }
- UndeclaredLabel
-
- // DuplicateLabel occurs when a label is declared more than once.
- //
- // Example:
- // func f() int {
- // L:
- // L:
- // return 1
- // }
- DuplicateLabel
-
- // MisplacedLabel occurs when a break or continue label is not on a for,
- // switch, or select statement.
- //
- // Example:
- // func f() {
- // L:
- // a := []int{1,2,3}
- // for _, e := range a {
- // if e > 10 {
- // break L
- // }
- // println(a)
- // }
- // }
- MisplacedLabel
-
- // UnusedLabel occurs when a label is declared and not used.
- //
- // Example:
- // func f() {
- // L:
- // }
- UnusedLabel
-
- // JumpOverDecl occurs when a label jumps over a variable declaration.
- //
- // Example:
- // func f() int {
- // goto L
- // x := 2
- // L:
- // x++
- // return x
- // }
- JumpOverDecl
-
- // JumpIntoBlock occurs when a forward jump goes to a label inside a nested
- // block.
- //
- // Example:
- // func f(x int) {
- // goto L
- // if x > 0 {
- // L:
- // print("inside block")
- // }
- // }
- JumpIntoBlock
-
- // InvalidMethodExpr occurs when a pointer method is called but the argument
- // is not addressable.
- //
- // Example:
- // type T struct {}
- //
- // func (*T) m() int { return 1 }
- //
- // var _ = T.m(T{})
- InvalidMethodExpr
-
- // WrongArgCount occurs when too few or too many arguments are passed by a
- // function call.
- //
- // Example:
- // func f(i int) {}
- // var x = f()
- WrongArgCount
-
- // InvalidCall occurs when an expression is called that is not of function
- // type.
- //
- // Example:
- // var x = "x"
- // var y = x()
- InvalidCall
-
- // UnusedResults occurs when a restricted expression-only built-in function
- // is suspended via go or defer. Such a suspension discards the results of
- // these side-effect free built-in functions, and therefore is ineffectual.
- //
- // Example:
- // func f(a []int) int {
- // defer len(a)
- // return i
- // }
- UnusedResults
-
- // InvalidDefer occurs when a deferred expression is not a function call,
- // for example if the expression is a type conversion.
- //
- // Example:
- // func f(i int) int {
- // defer int32(i)
- // return i
- // }
- InvalidDefer
-
- // InvalidGo occurs when a go expression is not a function call, for example
- // if the expression is a type conversion.
- //
- // Example:
- // func f(i int) int {
- // go int32(i)
- // return i
- // }
- InvalidGo
-
- // All codes below were added in Go 1.17.
-
- // BadDecl occurs when a declaration has invalid syntax.
- BadDecl
-
- // RepeatedDecl occurs when an identifier occurs more than once on the left
- // hand side of a short variable declaration.
- //
- // Example:
- // func _() {
- // x, y, y := 1, 2, 3
- // }
- RepeatedDecl
-
- // InvalidUnsafeAdd occurs when unsafe.Add is called with a
- // length argument that is not of integer type.
- // It also occurs if it is used in a package compiled for a
- // language version before go1.17.
- //
- // Example:
- // import "unsafe"
- //
- // var p unsafe.Pointer
- // var _ = unsafe.Add(p, float64(1))
- InvalidUnsafeAdd
-
- // InvalidUnsafeSlice occurs when unsafe.Slice is called with a
- // pointer argument that is not of pointer type or a length argument
- // that is not of integer type, negative, or out of bounds.
- // It also occurs if it is used in a package compiled for a language
- // version before go1.17.
- //
- // Example:
- // import "unsafe"
- //
- // var x int
- // var _ = unsafe.Slice(x, 1)
- //
- // Example:
- // import "unsafe"
- //
- // var x int
- // var _ = unsafe.Slice(&x, float64(1))
- //
- // Example:
- // import "unsafe"
- //
- // var x int
- // var _ = unsafe.Slice(&x, -1)
- //
- // Example:
- // import "unsafe"
- //
- // var x int
- // var _ = unsafe.Slice(&x, uint64(1) << 63)
- InvalidUnsafeSlice
-
- // All codes below were added in Go 1.18.
-
- // UnsupportedFeature occurs when a language feature is used that is not
- // supported at this Go version.
- UnsupportedFeature
-
- // NotAGenericType occurs when a non-generic type is used where a generic
- // type is expected: in type or function instantiation.
- //
- // Example:
- // type T int
- //
- // var _ T[int]
- NotAGenericType
-
- // WrongTypeArgCount occurs when a type or function is instantiated with an
- // incorrent number of type arguments, including when a generic type or
- // function is used without instantiation.
- //
- // Errors inolving failed type inference are assigned other error codes.
- //
- // Example:
- // type T[p any] int
- //
- // var _ T[int, string]
- //
- // Example:
- // func f[T any]() {}
- //
- // var x = f
- WrongTypeArgCount
-
- // CannotInferTypeArgs occurs when type or function type argument inference
- // fails to infer all type arguments.
- //
- // Example:
- // func f[T any]() {}
- //
- // func _() {
- // f()
- // }
- CannotInferTypeArgs
-
- // InvalidTypeArg occurs when a type argument does not satisfy its
- // corresponding type parameter constraints.
- //
- // Example:
- // type T[P ~int] struct{}
- //
- // var _ T[string]
- InvalidTypeArg // arguments? InferenceFailed
-
- // InvalidInstanceCycle occurs when an invalid cycle is detected
- // within the instantiation graph.
- //
- // Example:
- // func f[T any]() { f[*T]() }
- InvalidInstanceCycle
-
- // InvalidUnion occurs when an embedded union or approximation element is
- // not valid.
- //
- // Example:
- // type _ interface {
- // ~int | interface{ m() }
- // }
- InvalidUnion
-
- // MisplacedConstraintIface occurs when a constraint-type interface is used
- // outside of constraint position.
- //
- // Example:
- // type I interface { ~int }
- //
- // var _ I
- MisplacedConstraintIface
-
- // InvalidMethodTypeParams occurs when methods have type parameters.
- //
- // It cannot be encountered with an AST parsed using go/parser.
- InvalidMethodTypeParams
-
- // MisplacedTypeParam occurs when a type parameter is used in a place where
- // it is not permitted.
- //
- // Example:
- // type T[P any] P
- //
- // Example:
- // type T[P any] struct{ *P }
- MisplacedTypeParam
-
- // InvalidUnsafeSliceData occurs when unsafe.SliceData is called with
- // an argument that is not of slice type. It also occurs if it is used
- // in a package compiled for a language version before go1.20.
- //
- // Example:
- // import "unsafe"
- //
- // var x int
- // var _ = unsafe.SliceData(x)
- InvalidUnsafeSliceData
-
- // InvalidUnsafeString occurs when unsafe.String is called with
- // a length argument that is not of integer type, negative, or
- // out of bounds. It also occurs if it is used in a package
- // compiled for a language version before go1.20.
- //
- // Example:
- // import "unsafe"
- //
- // var b [10]byte
- // var _ = unsafe.String(&b[0], -1)
- InvalidUnsafeString
-
- // InvalidUnsafeStringData occurs if it is used in a package
- // compiled for a language version before go1.20.
- _ // not used anymore
-
- // InvalidClear occurs when clear is called with an argument
- // that is not of map, slice, or pointer-to-array type.
- //
- // Example:
- // func _(x int) {
- // clear(x)
- // }
- InvalidClear
-)
diff --git a/contrib/go/_std_1.20/src/internal/types/errors/ya.make b/contrib/go/_std_1.20/src/internal/types/errors/ya.make
deleted file mode 100644
index 3fee0fa26e..0000000000
--- a/contrib/go/_std_1.20/src/internal/types/errors/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- codes.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/unsafeheader/ya.make b/contrib/go/_std_1.20/src/internal/unsafeheader/ya.make
deleted file mode 100644
index d1319b628f..0000000000
--- a/contrib/go/_std_1.20/src/internal/unsafeheader/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- unsafeheader.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/internal/xcoff/ar.go b/contrib/go/_std_1.20/src/internal/xcoff/ar.go
deleted file mode 100644
index 2b432d5e10..0000000000
--- a/contrib/go/_std_1.20/src/internal/xcoff/ar.go
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright 2018 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 xcoff
-
-import (
- "encoding/binary"
- "fmt"
- "io"
- "os"
- "strconv"
- "strings"
-)
-
-const (
- SAIAMAG = 0x8
- AIAFMAG = "`\n"
- AIAMAG = "<aiaff>\n"
- AIAMAGBIG = "<bigaf>\n"
-
- // Sizeof
- FL_HSZ_BIG = 0x80
- AR_HSZ_BIG = 0x70
-)
-
-type bigarFileHeader struct {
- Flmagic [SAIAMAG]byte // Archive magic string
- Flmemoff [20]byte // Member table offset
- Flgstoff [20]byte // 32-bits global symtab offset
- Flgst64off [20]byte // 64-bits global symtab offset
- Flfstmoff [20]byte // First member offset
- Fllstmoff [20]byte // Last member offset
- Flfreeoff [20]byte // First member on free list offset
-}
-
-type bigarMemberHeader struct {
- Arsize [20]byte // File member size
- Arnxtmem [20]byte // Next member pointer
- Arprvmem [20]byte // Previous member pointer
- Ardate [12]byte // File member date
- Aruid [12]byte // File member uid
- Argid [12]byte // File member gid
- Armode [12]byte // File member mode (octal)
- Arnamlen [4]byte // File member name length
- // _ar_nam is removed because it's easier to get name without it.
-}
-
-// Archive represents an open AIX big archive.
-type Archive struct {
- ArchiveHeader
- Members []*Member
-
- closer io.Closer
-}
-
-// MemberHeader holds information about a big archive file header
-type ArchiveHeader struct {
- magic string
-}
-
-// Member represents a member of an AIX big archive.
-type Member struct {
- MemberHeader
- sr *io.SectionReader
-}
-
-// MemberHeader holds information about a big archive member
-type MemberHeader struct {
- Name string
- Size uint64
-}
-
-// OpenArchive opens the named archive using os.Open and prepares it for use
-// as an AIX big archive.
-func OpenArchive(name string) (*Archive, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- arch, err := NewArchive(f)
- if err != nil {
- f.Close()
- return nil, err
- }
- arch.closer = f
- return arch, nil
-}
-
-// Close closes the Archive.
-// If the Archive was created using NewArchive directly instead of OpenArchive,
-// Close has no effect.
-func (a *Archive) Close() error {
- var err error
- if a.closer != nil {
- err = a.closer.Close()
- a.closer = nil
- }
- return err
-}
-
-// NewArchive creates a new Archive for accessing an AIX big archive in an underlying reader.
-func NewArchive(r io.ReaderAt) (*Archive, error) {
- parseDecimalBytes := func(b []byte) (int64, error) {
- return strconv.ParseInt(strings.TrimSpace(string(b)), 10, 64)
- }
- sr := io.NewSectionReader(r, 0, 1<<63-1)
-
- // Read File Header
- var magic [SAIAMAG]byte
- if _, err := sr.ReadAt(magic[:], 0); err != nil {
- return nil, err
- }
-
- arch := new(Archive)
- switch string(magic[:]) {
- case AIAMAGBIG:
- arch.magic = string(magic[:])
- case AIAMAG:
- return nil, fmt.Errorf("small AIX archive not supported")
- default:
- return nil, fmt.Errorf("unrecognised archive magic: 0x%x", magic)
- }
-
- var fhdr bigarFileHeader
- if _, err := sr.Seek(0, io.SeekStart); err != nil {
- return nil, err
- }
- if err := binary.Read(sr, binary.BigEndian, &fhdr); err != nil {
- return nil, err
- }
-
- off, err := parseDecimalBytes(fhdr.Flfstmoff[:])
- if err != nil {
- return nil, fmt.Errorf("error parsing offset of first member in archive header(%q); %v", fhdr, err)
- }
-
- if off == 0 {
- // Occurs if the archive is empty.
- return arch, nil
- }
-
- lastoff, err := parseDecimalBytes(fhdr.Fllstmoff[:])
- if err != nil {
- return nil, fmt.Errorf("error parsing offset of first member in archive header(%q); %v", fhdr, err)
- }
-
- // Read members
- for {
- // Read Member Header
- // The member header is normally 2 bytes larger. But it's easier
- // to read the name if the header is read without _ar_nam.
- // However, AIAFMAG must be read afterward.
- if _, err := sr.Seek(off, io.SeekStart); err != nil {
- return nil, err
- }
-
- var mhdr bigarMemberHeader
- if err := binary.Read(sr, binary.BigEndian, &mhdr); err != nil {
- return nil, err
- }
-
- member := new(Member)
- arch.Members = append(arch.Members, member)
-
- size, err := parseDecimalBytes(mhdr.Arsize[:])
- if err != nil {
- return nil, fmt.Errorf("error parsing size in member header(%q); %v", mhdr, err)
- }
- member.Size = uint64(size)
-
- // Read name
- namlen, err := parseDecimalBytes(mhdr.Arnamlen[:])
- if err != nil {
- return nil, fmt.Errorf("error parsing name length in member header(%q); %v", mhdr, err)
- }
- name := make([]byte, namlen)
- if err := binary.Read(sr, binary.BigEndian, name); err != nil {
- return nil, err
- }
- member.Name = string(name)
-
- fileoff := off + AR_HSZ_BIG + namlen
- if fileoff&1 != 0 {
- fileoff++
- if _, err := sr.Seek(1, io.SeekCurrent); err != nil {
- return nil, err
- }
- }
-
- // Read AIAFMAG string
- var fmag [2]byte
- if err := binary.Read(sr, binary.BigEndian, &fmag); err != nil {
- return nil, err
- }
- if string(fmag[:]) != AIAFMAG {
- return nil, fmt.Errorf("AIAFMAG not found after member header")
- }
-
- fileoff += 2 // Add the two bytes of AIAFMAG
- member.sr = io.NewSectionReader(sr, fileoff, size)
-
- if off == lastoff {
- break
- }
- off, err = parseDecimalBytes(mhdr.Arnxtmem[:])
- if err != nil {
- return nil, fmt.Errorf("error parsing offset of first member in archive header(%q); %v", fhdr, err)
- }
-
- }
-
- return arch, nil
-
-}
-
-// GetFile returns the XCOFF file defined by member name.
-// FIXME: This doesn't work if an archive has two members with the same
-// name which can occur if a archive has both 32-bits and 64-bits files.
-func (arch *Archive) GetFile(name string) (*File, error) {
- for _, mem := range arch.Members {
- if mem.Name == name {
- return NewFile(mem.sr)
- }
- }
- return nil, fmt.Errorf("unknown member %s in archive", name)
-
-}
diff --git a/contrib/go/_std_1.20/src/internal/xcoff/file.go b/contrib/go/_std_1.20/src/internal/xcoff/file.go
deleted file mode 100644
index e859de932a..0000000000
--- a/contrib/go/_std_1.20/src/internal/xcoff/file.go
+++ /dev/null
@@ -1,692 +0,0 @@
-// Copyright 2018 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 xcoff implements access to XCOFF (Extended Common Object File Format) files.
-package xcoff
-
-import (
- "debug/dwarf"
- "encoding/binary"
- "fmt"
- "internal/saferio"
- "io"
- "os"
- "strings"
-)
-
-// SectionHeader holds information about an XCOFF section header.
-type SectionHeader struct {
- Name string
- VirtualAddress uint64
- Size uint64
- Type uint32
- Relptr uint64
- Nreloc uint32
-}
-
-type Section struct {
- SectionHeader
- Relocs []Reloc
- io.ReaderAt
- sr *io.SectionReader
-}
-
-// AuxiliaryCSect holds information about an XCOFF symbol in an AUX_CSECT entry.
-type AuxiliaryCSect struct {
- Length int64
- StorageMappingClass int
- SymbolType int
-}
-
-// AuxiliaryFcn holds information about an XCOFF symbol in an AUX_FCN entry.
-type AuxiliaryFcn struct {
- Size int64
-}
-
-type Symbol struct {
- Name string
- Value uint64
- SectionNumber int
- StorageClass int
- AuxFcn AuxiliaryFcn
- AuxCSect AuxiliaryCSect
-}
-
-type Reloc struct {
- VirtualAddress uint64
- Symbol *Symbol
- Signed bool
- InstructionFixed bool
- Length uint8
- Type uint8
-}
-
-// ImportedSymbol holds information about an imported XCOFF symbol.
-type ImportedSymbol struct {
- Name string
- Library string
-}
-
-// FileHeader holds information about an XCOFF file header.
-type FileHeader struct {
- TargetMachine uint16
-}
-
-// A File represents an open XCOFF file.
-type File struct {
- FileHeader
- Sections []*Section
- Symbols []*Symbol
- StringTable []byte
- LibraryPaths []string
-
- closer io.Closer
-}
-
-// Open opens the named file using os.Open and prepares it for use as an XCOFF binary.
-func Open(name string) (*File, error) {
- f, err := os.Open(name)
- if err != nil {
- return nil, err
- }
- ff, err := NewFile(f)
- if err != nil {
- f.Close()
- return nil, err
- }
- ff.closer = f
- return ff, nil
-}
-
-// Close closes the File.
-// If the File was created using NewFile directly instead of Open,
-// Close has no effect.
-func (f *File) Close() error {
- var err error
- if f.closer != nil {
- err = f.closer.Close()
- f.closer = nil
- }
- return err
-}
-
-// Section returns the first section with the given name, or nil if no such
-// section exists.
-// Xcoff have section's name limited to 8 bytes. Some sections like .gosymtab
-// can be trunked but this method will still find them.
-func (f *File) Section(name string) *Section {
- for _, s := range f.Sections {
- if s.Name == name || (len(name) > 8 && s.Name == name[:8]) {
- return s
- }
- }
- return nil
-}
-
-// SectionByType returns the first section in f with the
-// given type, or nil if there is no such section.
-func (f *File) SectionByType(typ uint32) *Section {
- for _, s := range f.Sections {
- if s.Type == typ {
- return s
- }
- }
- return nil
-}
-
-// cstring converts ASCII byte sequence b to string.
-// It stops once it finds 0 or reaches end of b.
-func cstring(b []byte) string {
- var i int
- for i = 0; i < len(b) && b[i] != 0; i++ {
- }
- return string(b[:i])
-}
-
-// getString extracts a string from an XCOFF string table.
-func getString(st []byte, offset uint32) (string, bool) {
- if offset < 4 || int(offset) >= len(st) {
- return "", false
- }
- return cstring(st[offset:]), true
-}
-
-// NewFile creates a new File for accessing an XCOFF binary in an underlying reader.
-func NewFile(r io.ReaderAt) (*File, error) {
- sr := io.NewSectionReader(r, 0, 1<<63-1)
- // Read XCOFF target machine
- var magic uint16
- if err := binary.Read(sr, binary.BigEndian, &magic); err != nil {
- return nil, err
- }
- if magic != U802TOCMAGIC && magic != U64_TOCMAGIC {
- return nil, fmt.Errorf("unrecognised XCOFF magic: 0x%x", magic)
- }
-
- f := new(File)
- f.TargetMachine = magic
-
- // Read XCOFF file header
- if _, err := sr.Seek(0, io.SeekStart); err != nil {
- return nil, err
- }
- var nscns uint16
- var symptr uint64
- var nsyms int32
- var opthdr uint16
- var hdrsz int
- switch f.TargetMachine {
- case U802TOCMAGIC:
- fhdr := new(FileHeader32)
- if err := binary.Read(sr, binary.BigEndian, fhdr); err != nil {
- return nil, err
- }
- nscns = fhdr.Fnscns
- symptr = uint64(fhdr.Fsymptr)
- nsyms = fhdr.Fnsyms
- opthdr = fhdr.Fopthdr
- hdrsz = FILHSZ_32
- case U64_TOCMAGIC:
- fhdr := new(FileHeader64)
- if err := binary.Read(sr, binary.BigEndian, fhdr); err != nil {
- return nil, err
- }
- nscns = fhdr.Fnscns
- symptr = fhdr.Fsymptr
- nsyms = fhdr.Fnsyms
- opthdr = fhdr.Fopthdr
- hdrsz = FILHSZ_64
- }
-
- if symptr == 0 || nsyms <= 0 {
- return nil, fmt.Errorf("no symbol table")
- }
-
- // Read string table (located right after symbol table).
- offset := symptr + uint64(nsyms)*SYMESZ
- if _, err := sr.Seek(int64(offset), io.SeekStart); err != nil {
- return nil, err
- }
- // The first 4 bytes contain the length (in bytes).
- var l uint32
- if err := binary.Read(sr, binary.BigEndian, &l); err != nil {
- return nil, err
- }
- if l > 4 {
- st, err := saferio.ReadDataAt(sr, uint64(l), int64(offset))
- if err != nil {
- return nil, err
- }
- f.StringTable = st
- }
-
- // Read section headers
- if _, err := sr.Seek(int64(hdrsz)+int64(opthdr), io.SeekStart); err != nil {
- return nil, err
- }
- f.Sections = make([]*Section, nscns)
- for i := 0; i < int(nscns); i++ {
- var scnptr uint64
- s := new(Section)
- switch f.TargetMachine {
- case U802TOCMAGIC:
- shdr := new(SectionHeader32)
- if err := binary.Read(sr, binary.BigEndian, shdr); err != nil {
- return nil, err
- }
- s.Name = cstring(shdr.Sname[:])
- s.VirtualAddress = uint64(shdr.Svaddr)
- s.Size = uint64(shdr.Ssize)
- scnptr = uint64(shdr.Sscnptr)
- s.Type = shdr.Sflags
- s.Relptr = uint64(shdr.Srelptr)
- s.Nreloc = uint32(shdr.Snreloc)
- case U64_TOCMAGIC:
- shdr := new(SectionHeader64)
- if err := binary.Read(sr, binary.BigEndian, shdr); err != nil {
- return nil, err
- }
- s.Name = cstring(shdr.Sname[:])
- s.VirtualAddress = shdr.Svaddr
- s.Size = shdr.Ssize
- scnptr = shdr.Sscnptr
- s.Type = shdr.Sflags
- s.Relptr = shdr.Srelptr
- s.Nreloc = shdr.Snreloc
- }
- r2 := r
- if scnptr == 0 { // .bss must have all 0s
- r2 = zeroReaderAt{}
- }
- s.sr = io.NewSectionReader(r2, int64(scnptr), int64(s.Size))
- s.ReaderAt = s.sr
- f.Sections[i] = s
- }
-
- // Symbol map needed by relocation
- var idxToSym = make(map[int]*Symbol)
-
- // Read symbol table
- if _, err := sr.Seek(int64(symptr), io.SeekStart); err != nil {
- return nil, err
- }
- f.Symbols = make([]*Symbol, 0)
- for i := 0; i < int(nsyms); i++ {
- var numaux int
- var ok, needAuxFcn bool
- sym := new(Symbol)
- switch f.TargetMachine {
- case U802TOCMAGIC:
- se := new(SymEnt32)
- if err := binary.Read(sr, binary.BigEndian, se); err != nil {
- return nil, err
- }
- numaux = int(se.Nnumaux)
- if numaux < 0 {
- return nil, fmt.Errorf("malformed symbol table, invalid number of aux symbols")
- }
- sym.SectionNumber = int(se.Nscnum)
- sym.StorageClass = int(se.Nsclass)
- sym.Value = uint64(se.Nvalue)
- needAuxFcn = se.Ntype&SYM_TYPE_FUNC != 0 && numaux > 1
- zeroes := binary.BigEndian.Uint32(se.Nname[:4])
- if zeroes != 0 {
- sym.Name = cstring(se.Nname[:])
- } else {
- offset := binary.BigEndian.Uint32(se.Nname[4:])
- sym.Name, ok = getString(f.StringTable, offset)
- if !ok {
- goto skip
- }
- }
- case U64_TOCMAGIC:
- se := new(SymEnt64)
- if err := binary.Read(sr, binary.BigEndian, se); err != nil {
- return nil, err
- }
- numaux = int(se.Nnumaux)
- if numaux < 0 {
- return nil, fmt.Errorf("malformed symbol table, invalid number of aux symbols")
- }
- sym.SectionNumber = int(se.Nscnum)
- sym.StorageClass = int(se.Nsclass)
- sym.Value = se.Nvalue
- needAuxFcn = se.Ntype&SYM_TYPE_FUNC != 0 && numaux > 1
- sym.Name, ok = getString(f.StringTable, se.Noffset)
- if !ok {
- goto skip
- }
- }
- if sym.StorageClass != C_EXT && sym.StorageClass != C_WEAKEXT && sym.StorageClass != C_HIDEXT {
- goto skip
- }
- // Must have at least one csect auxiliary entry.
- if numaux < 1 || i+numaux >= int(nsyms) {
- goto skip
- }
-
- if sym.SectionNumber > int(nscns) {
- goto skip
- }
- if sym.SectionNumber == 0 {
- sym.Value = 0
- } else {
- sym.Value -= f.Sections[sym.SectionNumber-1].VirtualAddress
- }
-
- idxToSym[i] = sym
-
- // If this symbol is a function, it must retrieve its size from
- // its AUX_FCN entry.
- // It can happen that a function symbol doesn't have any AUX_FCN.
- // In this case, needAuxFcn is false and their size will be set to 0.
- if needAuxFcn {
- switch f.TargetMachine {
- case U802TOCMAGIC:
- aux := new(AuxFcn32)
- if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
- return nil, err
- }
- sym.AuxFcn.Size = int64(aux.Xfsize)
- case U64_TOCMAGIC:
- aux := new(AuxFcn64)
- if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
- return nil, err
- }
- sym.AuxFcn.Size = int64(aux.Xfsize)
- }
- }
-
- // Read csect auxiliary entry (by convention, it is the last).
- if !needAuxFcn {
- if _, err := sr.Seek(int64(numaux-1)*SYMESZ, io.SeekCurrent); err != nil {
- return nil, err
- }
- }
- i += numaux
- numaux = 0
- switch f.TargetMachine {
- case U802TOCMAGIC:
- aux := new(AuxCSect32)
- if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
- return nil, err
- }
- sym.AuxCSect.SymbolType = int(aux.Xsmtyp & 0x7)
- sym.AuxCSect.StorageMappingClass = int(aux.Xsmclas)
- sym.AuxCSect.Length = int64(aux.Xscnlen)
- case U64_TOCMAGIC:
- aux := new(AuxCSect64)
- if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
- return nil, err
- }
- sym.AuxCSect.SymbolType = int(aux.Xsmtyp & 0x7)
- sym.AuxCSect.StorageMappingClass = int(aux.Xsmclas)
- sym.AuxCSect.Length = int64(aux.Xscnlenhi)<<32 | int64(aux.Xscnlenlo)
- }
- f.Symbols = append(f.Symbols, sym)
- skip:
- i += numaux // Skip auxiliary entries
- if _, err := sr.Seek(int64(numaux)*SYMESZ, io.SeekCurrent); err != nil {
- return nil, err
- }
- }
-
- // Read relocations
- // Only for .data or .text section
- for _, sect := range f.Sections {
- if sect.Type != STYP_TEXT && sect.Type != STYP_DATA {
- continue
- }
- sect.Relocs = make([]Reloc, sect.Nreloc)
- if sect.Relptr == 0 {
- continue
- }
- if _, err := sr.Seek(int64(sect.Relptr), io.SeekStart); err != nil {
- return nil, err
- }
- for i := uint32(0); i < sect.Nreloc; i++ {
- switch f.TargetMachine {
- case U802TOCMAGIC:
- rel := new(Reloc32)
- if err := binary.Read(sr, binary.BigEndian, rel); err != nil {
- return nil, err
- }
- sect.Relocs[i].VirtualAddress = uint64(rel.Rvaddr)
- sect.Relocs[i].Symbol = idxToSym[int(rel.Rsymndx)]
- sect.Relocs[i].Type = rel.Rtype
- sect.Relocs[i].Length = rel.Rsize&0x3F + 1
-
- if rel.Rsize&0x80 != 0 {
- sect.Relocs[i].Signed = true
- }
- if rel.Rsize&0x40 != 0 {
- sect.Relocs[i].InstructionFixed = true
- }
-
- case U64_TOCMAGIC:
- rel := new(Reloc64)
- if err := binary.Read(sr, binary.BigEndian, rel); err != nil {
- return nil, err
- }
- sect.Relocs[i].VirtualAddress = rel.Rvaddr
- sect.Relocs[i].Symbol = idxToSym[int(rel.Rsymndx)]
- sect.Relocs[i].Type = rel.Rtype
- sect.Relocs[i].Length = rel.Rsize&0x3F + 1
- if rel.Rsize&0x80 != 0 {
- sect.Relocs[i].Signed = true
- }
- if rel.Rsize&0x40 != 0 {
- sect.Relocs[i].InstructionFixed = true
- }
- }
- }
- }
-
- return f, nil
-}
-
-// zeroReaderAt is ReaderAt that reads 0s.
-type zeroReaderAt struct{}
-
-// ReadAt writes len(p) 0s into p.
-func (w zeroReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
- for i := range p {
- p[i] = 0
- }
- return len(p), nil
-}
-
-// Data reads and returns the contents of the XCOFF section s.
-func (s *Section) Data() ([]byte, error) {
- dat := make([]byte, s.sr.Size())
- n, err := s.sr.ReadAt(dat, 0)
- if n == len(dat) {
- err = nil
- }
- return dat[:n], err
-}
-
-// CSect reads and returns the contents of a csect.
-func (f *File) CSect(name string) []byte {
- for _, sym := range f.Symbols {
- if sym.Name == name && sym.AuxCSect.SymbolType == XTY_SD {
- if i := sym.SectionNumber - 1; 0 <= i && i < len(f.Sections) {
- s := f.Sections[i]
- if sym.Value+uint64(sym.AuxCSect.Length) <= s.Size {
- dat := make([]byte, sym.AuxCSect.Length)
- _, err := s.sr.ReadAt(dat, int64(sym.Value))
- if err != nil {
- return nil
- }
- return dat
- }
- }
- break
- }
- }
- return nil
-}
-
-func (f *File) DWARF() (*dwarf.Data, error) {
- // There are many other DWARF sections, but these
- // are the ones the debug/dwarf package uses.
- // Don't bother loading others.
- var subtypes = [...]uint32{SSUBTYP_DWABREV, SSUBTYP_DWINFO, SSUBTYP_DWLINE, SSUBTYP_DWRNGES, SSUBTYP_DWSTR}
- var dat [len(subtypes)][]byte
- for i, subtype := range subtypes {
- s := f.SectionByType(STYP_DWARF | subtype)
- if s != nil {
- b, err := s.Data()
- if err != nil && uint64(len(b)) < s.Size {
- return nil, err
- }
- dat[i] = b
- }
- }
-
- abbrev, info, line, ranges, str := dat[0], dat[1], dat[2], dat[3], dat[4]
- return dwarf.New(abbrev, nil, nil, info, line, nil, ranges, str)
-}
-
-// readImportID returns the import file IDs stored inside the .loader section.
-// Library name pattern is either path/base/member or base/member
-func (f *File) readImportIDs(s *Section) ([]string, error) {
- // Read loader header
- if _, err := s.sr.Seek(0, io.SeekStart); err != nil {
- return nil, err
- }
- var istlen uint32
- var nimpid int32
- var impoff uint64
- switch f.TargetMachine {
- case U802TOCMAGIC:
- lhdr := new(LoaderHeader32)
- if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
- return nil, err
- }
- istlen = lhdr.Listlen
- nimpid = lhdr.Lnimpid
- impoff = uint64(lhdr.Limpoff)
- case U64_TOCMAGIC:
- lhdr := new(LoaderHeader64)
- if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
- return nil, err
- }
- istlen = lhdr.Listlen
- nimpid = lhdr.Lnimpid
- impoff = lhdr.Limpoff
- }
-
- // Read loader import file ID table
- if _, err := s.sr.Seek(int64(impoff), io.SeekStart); err != nil {
- return nil, err
- }
- table := make([]byte, istlen)
- if _, err := io.ReadFull(s.sr, table); err != nil {
- return nil, err
- }
-
- offset := 0
- // First import file ID is the default LIBPATH value
- libpath := cstring(table[offset:])
- f.LibraryPaths = strings.Split(libpath, ":")
- offset += len(libpath) + 3 // 3 null bytes
- all := make([]string, 0)
- for i := 1; i < int(nimpid); i++ {
- impidpath := cstring(table[offset:])
- offset += len(impidpath) + 1
- impidbase := cstring(table[offset:])
- offset += len(impidbase) + 1
- impidmem := cstring(table[offset:])
- offset += len(impidmem) + 1
- var path string
- if len(impidpath) > 0 {
- path = impidpath + "/" + impidbase + "/" + impidmem
- } else {
- path = impidbase + "/" + impidmem
- }
- all = append(all, path)
- }
-
- return all, nil
-}
-
-// ImportedSymbols returns the names of all symbols
-// referred to by the binary f that are expected to be
-// satisfied by other libraries at dynamic load time.
-// It does not return weak symbols.
-func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
- s := f.SectionByType(STYP_LOADER)
- if s == nil {
- return nil, nil
- }
- // Read loader header
- if _, err := s.sr.Seek(0, io.SeekStart); err != nil {
- return nil, err
- }
- var stlen uint32
- var stoff uint64
- var nsyms int32
- var symoff uint64
- switch f.TargetMachine {
- case U802TOCMAGIC:
- lhdr := new(LoaderHeader32)
- if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
- return nil, err
- }
- stlen = lhdr.Lstlen
- stoff = uint64(lhdr.Lstoff)
- nsyms = lhdr.Lnsyms
- symoff = LDHDRSZ_32
- case U64_TOCMAGIC:
- lhdr := new(LoaderHeader64)
- if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
- return nil, err
- }
- stlen = lhdr.Lstlen
- stoff = lhdr.Lstoff
- nsyms = lhdr.Lnsyms
- symoff = lhdr.Lsymoff
- }
-
- // Read loader section string table
- if _, err := s.sr.Seek(int64(stoff), io.SeekStart); err != nil {
- return nil, err
- }
- st := make([]byte, stlen)
- if _, err := io.ReadFull(s.sr, st); err != nil {
- return nil, err
- }
-
- // Read imported libraries
- libs, err := f.readImportIDs(s)
- if err != nil {
- return nil, err
- }
-
- // Read loader symbol table
- if _, err := s.sr.Seek(int64(symoff), io.SeekStart); err != nil {
- return nil, err
- }
- all := make([]ImportedSymbol, 0)
- for i := 0; i < int(nsyms); i++ {
- var name string
- var ifile int32
- var ok bool
- switch f.TargetMachine {
- case U802TOCMAGIC:
- ldsym := new(LoaderSymbol32)
- if err := binary.Read(s.sr, binary.BigEndian, ldsym); err != nil {
- return nil, err
- }
- if ldsym.Lsmtype&0x40 == 0 {
- continue // Imported symbols only
- }
- zeroes := binary.BigEndian.Uint32(ldsym.Lname[:4])
- if zeroes != 0 {
- name = cstring(ldsym.Lname[:])
- } else {
- offset := binary.BigEndian.Uint32(ldsym.Lname[4:])
- name, ok = getString(st, offset)
- if !ok {
- continue
- }
- }
- ifile = ldsym.Lifile
- case U64_TOCMAGIC:
- ldsym := new(LoaderSymbol64)
- if err := binary.Read(s.sr, binary.BigEndian, ldsym); err != nil {
- return nil, err
- }
- if ldsym.Lsmtype&0x40 == 0 {
- continue // Imported symbols only
- }
- name, ok = getString(st, ldsym.Loffset)
- if !ok {
- continue
- }
- ifile = ldsym.Lifile
- }
- var sym ImportedSymbol
- sym.Name = name
- if ifile >= 1 && int(ifile) <= len(libs) {
- sym.Library = libs[ifile-1]
- }
- all = append(all, sym)
- }
-
- return all, nil
-}
-
-// ImportedLibraries returns the names of all libraries
-// referred to by the binary f that are expected to be
-// linked with the binary at dynamic link time.
-func (f *File) ImportedLibraries() ([]string, error) {
- s := f.SectionByType(STYP_LOADER)
- if s == nil {
- return nil, nil
- }
- all, err := f.readImportIDs(s)
- return all, err
-}
diff --git a/contrib/go/_std_1.20/src/internal/xcoff/xcoff.go b/contrib/go/_std_1.20/src/internal/xcoff/xcoff.go
deleted file mode 100644
index f8465d7289..0000000000
--- a/contrib/go/_std_1.20/src/internal/xcoff/xcoff.go
+++ /dev/null
@@ -1,367 +0,0 @@
-// Copyright 2018 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 xcoff
-
-// File Header.
-type FileHeader32 struct {
- Fmagic uint16 // Target machine
- Fnscns uint16 // Number of sections
- Ftimedat int32 // Time and date of file creation
- Fsymptr uint32 // Byte offset to symbol table start
- Fnsyms int32 // Number of entries in symbol table
- Fopthdr uint16 // Number of bytes in optional header
- Fflags uint16 // Flags
-}
-
-type FileHeader64 struct {
- Fmagic uint16 // Target machine
- Fnscns uint16 // Number of sections
- Ftimedat int32 // Time and date of file creation
- Fsymptr uint64 // Byte offset to symbol table start
- Fopthdr uint16 // Number of bytes in optional header
- Fflags uint16 // Flags
- Fnsyms int32 // Number of entries in symbol table
-}
-
-const (
- FILHSZ_32 = 20
- FILHSZ_64 = 24
-)
-const (
- U802TOCMAGIC = 0737 // AIX 32-bit XCOFF
- U64_TOCMAGIC = 0767 // AIX 64-bit XCOFF
-)
-
-// Flags that describe the type of the object file.
-const (
- F_RELFLG = 0x0001
- F_EXEC = 0x0002
- F_LNNO = 0x0004
- F_FDPR_PROF = 0x0010
- F_FDPR_OPTI = 0x0020
- F_DSA = 0x0040
- F_VARPG = 0x0100
- F_DYNLOAD = 0x1000
- F_SHROBJ = 0x2000
- F_LOADONLY = 0x4000
-)
-
-// Section Header.
-type SectionHeader32 struct {
- Sname [8]byte // Section name
- Spaddr uint32 // Physical address
- Svaddr uint32 // Virtual address
- Ssize uint32 // Section size
- Sscnptr uint32 // Offset in file to raw data for section
- Srelptr uint32 // Offset in file to relocation entries for section
- Slnnoptr uint32 // Offset in file to line number entries for section
- Snreloc uint16 // Number of relocation entries
- Snlnno uint16 // Number of line number entries
- Sflags uint32 // Flags to define the section type
-}
-
-type SectionHeader64 struct {
- Sname [8]byte // Section name
- Spaddr uint64 // Physical address
- Svaddr uint64 // Virtual address
- Ssize uint64 // Section size
- Sscnptr uint64 // Offset in file to raw data for section
- Srelptr uint64 // Offset in file to relocation entries for section
- Slnnoptr uint64 // Offset in file to line number entries for section
- Snreloc uint32 // Number of relocation entries
- Snlnno uint32 // Number of line number entries
- Sflags uint32 // Flags to define the section type
- Spad uint32 // Needs to be 72 bytes long
-}
-
-// Flags defining the section type.
-const (
- STYP_DWARF = 0x0010
- STYP_TEXT = 0x0020
- STYP_DATA = 0x0040
- STYP_BSS = 0x0080
- STYP_EXCEPT = 0x0100
- STYP_INFO = 0x0200
- STYP_TDATA = 0x0400
- STYP_TBSS = 0x0800
- STYP_LOADER = 0x1000
- STYP_DEBUG = 0x2000
- STYP_TYPCHK = 0x4000
- STYP_OVRFLO = 0x8000
-)
-const (
- SSUBTYP_DWINFO = 0x10000 // DWARF info section
- SSUBTYP_DWLINE = 0x20000 // DWARF line-number section
- SSUBTYP_DWPBNMS = 0x30000 // DWARF public names section
- SSUBTYP_DWPBTYP = 0x40000 // DWARF public types section
- SSUBTYP_DWARNGE = 0x50000 // DWARF aranges section
- SSUBTYP_DWABREV = 0x60000 // DWARF abbreviation section
- SSUBTYP_DWSTR = 0x70000 // DWARF strings section
- SSUBTYP_DWRNGES = 0x80000 // DWARF ranges section
- SSUBTYP_DWLOC = 0x90000 // DWARF location lists section
- SSUBTYP_DWFRAME = 0xA0000 // DWARF frames section
- SSUBTYP_DWMAC = 0xB0000 // DWARF macros section
-)
-
-// Symbol Table Entry.
-type SymEnt32 struct {
- Nname [8]byte // Symbol name
- Nvalue uint32 // Symbol value
- Nscnum int16 // Section number of symbol
- Ntype uint16 // Basic and derived type specification
- Nsclass int8 // Storage class of symbol
- Nnumaux int8 // Number of auxiliary entries
-}
-
-type SymEnt64 struct {
- Nvalue uint64 // Symbol value
- Noffset uint32 // Offset of the name in string table or .debug section
- Nscnum int16 // Section number of symbol
- Ntype uint16 // Basic and derived type specification
- Nsclass int8 // Storage class of symbol
- Nnumaux int8 // Number of auxiliary entries
-}
-
-const SYMESZ = 18
-
-const (
- // Nscnum
- N_DEBUG = -2
- N_ABS = -1
- N_UNDEF = 0
-
- //Ntype
- SYM_V_INTERNAL = 0x1000
- SYM_V_HIDDEN = 0x2000
- SYM_V_PROTECTED = 0x3000
- SYM_V_EXPORTED = 0x4000
- SYM_TYPE_FUNC = 0x0020 // is function
-)
-
-// Storage Class.
-const (
- C_NULL = 0 // Symbol table entry marked for deletion
- C_EXT = 2 // External symbol
- C_STAT = 3 // Static symbol
- C_BLOCK = 100 // Beginning or end of inner block
- C_FCN = 101 // Beginning or end of function
- C_FILE = 103 // Source file name and compiler information
- C_HIDEXT = 107 // Unnamed external symbol
- C_BINCL = 108 // Beginning of include file
- C_EINCL = 109 // End of include file
- C_WEAKEXT = 111 // Weak external symbol
- C_DWARF = 112 // DWARF symbol
- C_GSYM = 128 // Global variable
- C_LSYM = 129 // Automatic variable allocated on stack
- C_PSYM = 130 // Argument to subroutine allocated on stack
- C_RSYM = 131 // Register variable
- C_RPSYM = 132 // Argument to function or procedure stored in register
- C_STSYM = 133 // Statically allocated symbol
- C_BCOMM = 135 // Beginning of common block
- C_ECOML = 136 // Local member of common block
- C_ECOMM = 137 // End of common block
- C_DECL = 140 // Declaration of object
- C_ENTRY = 141 // Alternate entry
- C_FUN = 142 // Function or procedure
- C_BSTAT = 143 // Beginning of static block
- C_ESTAT = 144 // End of static block
- C_GTLS = 145 // Global thread-local variable
- C_STTLS = 146 // Static thread-local variable
-)
-
-// File Auxiliary Entry
-type AuxFile64 struct {
- Xfname [8]byte // Name or offset inside string table
- Xftype uint8 // Source file string type
- Xauxtype uint8 // Type of auxiliary entry
-}
-
-// Function Auxiliary Entry
-type AuxFcn32 struct {
- Xexptr uint32 // File offset to exception table entry
- Xfsize uint32 // Size of function in bytes
- Xlnnoptr uint32 // File pointer to line number
- Xendndx uint32 // Symbol table index of next entry
- Xpad uint16 // Unused
-}
-type AuxFcn64 struct {
- Xlnnoptr uint64 // File pointer to line number
- Xfsize uint32 // Size of function in bytes
- Xendndx uint32 // Symbol table index of next entry
- Xpad uint8 // Unused
- Xauxtype uint8 // Type of auxiliary entry
-}
-
-type AuxSect64 struct {
- Xscnlen uint64 // section length
- Xnreloc uint64 // Num RLDs
- pad uint8
- Xauxtype uint8 // Type of auxiliary entry
-}
-
-// csect Auxiliary Entry.
-type AuxCSect32 struct {
- Xscnlen int32 // Length or symbol table index
- Xparmhash uint32 // Offset of parameter type-check string
- Xsnhash uint16 // .typchk section number
- Xsmtyp uint8 // Symbol alignment and type
- Xsmclas uint8 // Storage-mapping class
- Xstab uint32 // Reserved
- Xsnstab uint16 // Reserved
-}
-
-type AuxCSect64 struct {
- Xscnlenlo uint32 // Lower 4 bytes of length or symbol table index
- Xparmhash uint32 // Offset of parameter type-check string
- Xsnhash uint16 // .typchk section number
- Xsmtyp uint8 // Symbol alignment and type
- Xsmclas uint8 // Storage-mapping class
- Xscnlenhi int32 // Upper 4 bytes of length or symbol table index
- Xpad uint8 // Unused
- Xauxtype uint8 // Type of auxiliary entry
-}
-
-// Auxiliary type
-const (
- _AUX_EXCEPT = 255
- _AUX_FCN = 254
- _AUX_SYM = 253
- _AUX_FILE = 252
- _AUX_CSECT = 251
- _AUX_SECT = 250
-)
-
-// Symbol type field.
-const (
- XTY_ER = 0 // External reference
- XTY_SD = 1 // Section definition
- XTY_LD = 2 // Label definition
- XTY_CM = 3 // Common csect definition
-)
-
-// Defines for File auxiliary definitions: x_ftype field of x_file
-const (
- XFT_FN = 0 // Source File Name
- XFT_CT = 1 // Compile Time Stamp
- XFT_CV = 2 // Compiler Version Number
- XFT_CD = 128 // Compiler Defined Information
-)
-
-// Storage-mapping class.
-const (
- XMC_PR = 0 // Program code
- XMC_RO = 1 // Read-only constant
- XMC_DB = 2 // Debug dictionary table
- XMC_TC = 3 // TOC entry
- XMC_UA = 4 // Unclassified
- XMC_RW = 5 // Read/Write data
- XMC_GL = 6 // Global linkage
- XMC_XO = 7 // Extended operation
- XMC_SV = 8 // 32-bit supervisor call descriptor
- XMC_BS = 9 // BSS class
- XMC_DS = 10 // Function descriptor
- XMC_UC = 11 // Unnamed FORTRAN common
- XMC_TC0 = 15 // TOC anchor
- XMC_TD = 16 // Scalar data entry in the TOC
- XMC_SV64 = 17 // 64-bit supervisor call descriptor
- XMC_SV3264 = 18 // Supervisor call descriptor for both 32-bit and 64-bit
- XMC_TL = 20 // Read/Write thread-local data
- XMC_UL = 21 // Read/Write thread-local data (.tbss)
- XMC_TE = 22 // TOC entry
-)
-
-// Loader Header.
-type LoaderHeader32 struct {
- Lversion int32 // Loader section version number
- Lnsyms int32 // Number of symbol table entries
- Lnreloc int32 // Number of relocation table entries
- Listlen uint32 // Length of import file ID string table
- Lnimpid int32 // Number of import file IDs
- Limpoff uint32 // Offset to start of import file IDs
- Lstlen uint32 // Length of string table
- Lstoff uint32 // Offset to start of string table
-}
-
-type LoaderHeader64 struct {
- Lversion int32 // Loader section version number
- Lnsyms int32 // Number of symbol table entries
- Lnreloc int32 // Number of relocation table entries
- Listlen uint32 // Length of import file ID string table
- Lnimpid int32 // Number of import file IDs
- Lstlen uint32 // Length of string table
- Limpoff uint64 // Offset to start of import file IDs
- Lstoff uint64 // Offset to start of string table
- Lsymoff uint64 // Offset to start of symbol table
- Lrldoff uint64 // Offset to start of relocation entries
-}
-
-const (
- LDHDRSZ_32 = 32
- LDHDRSZ_64 = 56
-)
-
-// Loader Symbol.
-type LoaderSymbol32 struct {
- Lname [8]byte // Symbol name or byte offset into string table
- Lvalue uint32 // Address field
- Lscnum int16 // Section number containing symbol
- Lsmtype int8 // Symbol type, export, import flags
- Lsmclas int8 // Symbol storage class
- Lifile int32 // Import file ID; ordinal of import file IDs
- Lparm uint32 // Parameter type-check field
-}
-
-type LoaderSymbol64 struct {
- Lvalue uint64 // Address field
- Loffset uint32 // Byte offset into string table of symbol name
- Lscnum int16 // Section number containing symbol
- Lsmtype int8 // Symbol type, export, import flags
- Lsmclas int8 // Symbol storage class
- Lifile int32 // Import file ID; ordinal of import file IDs
- Lparm uint32 // Parameter type-check field
-}
-
-type Reloc32 struct {
- Rvaddr uint32 // (virtual) address of reference
- Rsymndx uint32 // Index into symbol table
- Rsize uint8 // Sign and reloc bit len
- Rtype uint8 // Toc relocation type
-}
-
-type Reloc64 struct {
- Rvaddr uint64 // (virtual) address of reference
- Rsymndx uint32 // Index into symbol table
- Rsize uint8 // Sign and reloc bit len
- Rtype uint8 // Toc relocation type
-}
-
-const (
- R_POS = 0x00 // A(sym) Positive Relocation
- R_NEG = 0x01 // -A(sym) Negative Relocation
- R_REL = 0x02 // A(sym-*) Relative to self
- R_TOC = 0x03 // A(sym-TOC) Relative to TOC
- R_TRL = 0x12 // A(sym-TOC) TOC Relative indirect load.
-
- R_TRLA = 0x13 // A(sym-TOC) TOC Rel load address. modifiable inst
- R_GL = 0x05 // A(external TOC of sym) Global Linkage
- R_TCL = 0x06 // A(local TOC of sym) Local object TOC address
- R_RL = 0x0C // A(sym) Pos indirect load. modifiable instruction
- R_RLA = 0x0D // A(sym) Pos Load Address. modifiable instruction
- R_REF = 0x0F // AL0(sym) Non relocating ref. No garbage collect
- R_BA = 0x08 // A(sym) Branch absolute. Cannot modify instruction
- R_RBA = 0x18 // A(sym) Branch absolute. modifiable instruction
- R_BR = 0x0A // A(sym-*) Branch rel to self. non modifiable
- R_RBR = 0x1A // A(sym-*) Branch rel to self. modifiable instr
-
- R_TLS = 0x20 // General-dynamic reference to TLS symbol
- R_TLS_IE = 0x21 // Initial-exec reference to TLS symbol
- R_TLS_LD = 0x22 // Local-dynamic reference to TLS symbol
- R_TLS_LE = 0x23 // Local-exec reference to TLS symbol
- R_TLSM = 0x24 // Module reference to TLS symbol
- R_TLSML = 0x25 // Module reference to local (own) module
-
- R_TOCU = 0x30 // Relative to TOC - high order bits
- R_TOCL = 0x31 // Relative to TOC - low order bits
-)
diff --git a/contrib/go/_std_1.20/src/internal/xcoff/ya.make b/contrib/go/_std_1.20/src/internal/xcoff/ya.make
deleted file mode 100644
index 32bfb9ac56..0000000000
--- a/contrib/go/_std_1.20/src/internal/xcoff/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- ar.go
- file.go
- xcoff.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/io/fs/readdir.go b/contrib/go/_std_1.20/src/io/fs/readdir.go
deleted file mode 100644
index 2b10ddb0a3..0000000000
--- a/contrib/go/_std_1.20/src/io/fs/readdir.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// 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 fs
-
-import (
- "errors"
- "sort"
-)
-
-// ReadDirFS is the interface implemented by a file system
-// that provides an optimized implementation of ReadDir.
-type ReadDirFS interface {
- FS
-
- // ReadDir reads the named directory
- // and returns a list of directory entries sorted by filename.
- ReadDir(name string) ([]DirEntry, error)
-}
-
-// ReadDir reads the named directory
-// and returns a list of directory entries sorted by filename.
-//
-// If fs implements ReadDirFS, ReadDir calls fs.ReadDir.
-// Otherwise ReadDir calls fs.Open and uses ReadDir and Close
-// on the returned file.
-func ReadDir(fsys FS, name string) ([]DirEntry, error) {
- if fsys, ok := fsys.(ReadDirFS); ok {
- return fsys.ReadDir(name)
- }
-
- file, err := fsys.Open(name)
- if err != nil {
- return nil, err
- }
- defer file.Close()
-
- dir, ok := file.(ReadDirFile)
- if !ok {
- return nil, &PathError{Op: "readdir", Path: name, Err: errors.New("not implemented")}
- }
-
- list, err := dir.ReadDir(-1)
- sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
- return list, err
-}
-
-// dirInfo is a DirEntry based on a FileInfo.
-type dirInfo struct {
- fileInfo FileInfo
-}
-
-func (di dirInfo) IsDir() bool {
- return di.fileInfo.IsDir()
-}
-
-func (di dirInfo) Type() FileMode {
- return di.fileInfo.Mode().Type()
-}
-
-func (di dirInfo) Info() (FileInfo, error) {
- return di.fileInfo, nil
-}
-
-func (di dirInfo) Name() string {
- return di.fileInfo.Name()
-}
-
-// FileInfoToDirEntry returns a DirEntry that returns information from info.
-// If info is nil, FileInfoToDirEntry returns nil.
-func FileInfoToDirEntry(info FileInfo) DirEntry {
- if info == nil {
- return nil
- }
- return dirInfo{fileInfo: info}
-}
diff --git a/contrib/go/_std_1.20/src/io/fs/walk.go b/contrib/go/_std_1.20/src/io/fs/walk.go
deleted file mode 100644
index cff26104f0..0000000000
--- a/contrib/go/_std_1.20/src/io/fs/walk.go
+++ /dev/null
@@ -1,137 +0,0 @@
-// 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 fs
-
-import (
- "errors"
- "path"
-)
-
-// SkipDir is used as a return value from WalkDirFuncs to indicate that
-// the directory named in the call is to be skipped. It is not returned
-// as an error by any function.
-var SkipDir = errors.New("skip this directory")
-
-// SkipAll is used as a return value from WalkDirFuncs to indicate that
-// all remaining files and directories are to be skipped. It is not returned
-// as an error by any function.
-var SkipAll = errors.New("skip everything and stop the walk")
-
-// WalkDirFunc is the type of the function called by WalkDir to visit
-// each file or directory.
-//
-// The path argument contains the argument to WalkDir as a prefix.
-// That is, if WalkDir is called with root argument "dir" and finds a file
-// named "a" in that directory, the walk function will be called with
-// argument "dir/a".
-//
-// The d argument is the fs.DirEntry for the named path.
-//
-// The error result returned by the function controls how WalkDir
-// continues. If the function returns the special value SkipDir, WalkDir
-// skips the current directory (path if d.IsDir() is true, otherwise
-// path's parent directory). If the function returns the special value
-// SkipAll, WalkDir skips all remaining files and directories. Otherwise,
-// if the function returns a non-nil error, WalkDir stops entirely and
-// returns that error.
-//
-// The err argument reports an error related to path, signaling that
-// WalkDir will not walk into that directory. The function can decide how
-// to handle that error; as described earlier, returning the error will
-// cause WalkDir to stop walking the entire tree.
-//
-// WalkDir calls the function with a non-nil err argument in two cases.
-//
-// First, if the initial fs.Stat on the root directory fails, WalkDir
-// calls the function with path set to root, d set to nil, and err set to
-// the error from fs.Stat.
-//
-// Second, if a directory's ReadDir method fails, WalkDir calls the
-// function with path set to the directory's path, d set to an
-// fs.DirEntry describing the directory, and err set to the error from
-// ReadDir. In this second case, the function is called twice with the
-// path of the directory: the first call is before the directory read is
-// attempted and has err set to nil, giving the function a chance to
-// return SkipDir or SkipAll and avoid the ReadDir entirely. The second call
-// is after a failed ReadDir and reports the error from ReadDir.
-// (If ReadDir succeeds, there is no second call.)
-//
-// The differences between WalkDirFunc compared to filepath.WalkFunc are:
-//
-// - The second argument has type fs.DirEntry instead of fs.FileInfo.
-// - The function is called before reading a directory, to allow SkipDir
-// or SkipAll to bypass the directory read entirely or skip all remaining
-// files and directories respectively.
-// - If a directory read fails, the function is called a second time
-// for that directory to report the error.
-type WalkDirFunc func(path string, d DirEntry, err error) error
-
-// walkDir recursively descends path, calling walkDirFn.
-func walkDir(fsys FS, name string, d DirEntry, walkDirFn WalkDirFunc) error {
- if err := walkDirFn(name, d, nil); err != nil || !d.IsDir() {
- if err == SkipDir && d.IsDir() {
- // Successfully skipped directory.
- err = nil
- }
- return err
- }
-
- dirs, err := ReadDir(fsys, name)
- if err != nil {
- // Second call, to report ReadDir error.
- err = walkDirFn(name, d, err)
- if err != nil {
- if err == SkipDir && d.IsDir() {
- err = nil
- }
- return err
- }
- }
-
- for _, d1 := range dirs {
- name1 := path.Join(name, d1.Name())
- if err := walkDir(fsys, name1, d1, walkDirFn); err != nil {
- if err == SkipDir {
- break
- }
- return err
- }
- }
- return nil
-}
-
-// WalkDir walks the file tree rooted at root, calling fn for each file or
-// directory in the tree, including root.
-//
-// All errors that arise visiting files and directories are filtered by fn:
-// see the fs.WalkDirFunc documentation for details.
-//
-// The files are walked in lexical order, which makes the output deterministic
-// but requires WalkDir to read an entire directory into memory before proceeding
-// to walk that directory.
-//
-// WalkDir does not follow symbolic links found in directories,
-// but if root itself is a symbolic link, its target will be walked.
-func WalkDir(fsys FS, root string, fn WalkDirFunc) error {
- info, err := Stat(fsys, root)
- if err != nil {
- err = fn(root, nil, err)
- } else {
- err = walkDir(fsys, root, &statDirEntry{info}, fn)
- }
- if err == SkipDir || err == SkipAll {
- return nil
- }
- return err
-}
-
-type statDirEntry struct {
- info FileInfo
-}
-
-func (d *statDirEntry) Name() string { return d.info.Name() }
-func (d *statDirEntry) IsDir() bool { return d.info.IsDir() }
-func (d *statDirEntry) Type() FileMode { return d.info.Mode().Type() }
-func (d *statDirEntry) Info() (FileInfo, error) { return d.info, nil }
diff --git a/contrib/go/_std_1.20/src/io/fs/ya.make b/contrib/go/_std_1.20/src/io/fs/ya.make
deleted file mode 100644
index 1f751e05e9..0000000000
--- a/contrib/go/_std_1.20/src/io/fs/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- fs.go
- glob.go
- readdir.go
- readfile.go
- stat.go
- sub.go
- walk.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/io/io.go b/contrib/go/_std_1.20/src/io/io.go
deleted file mode 100644
index 630ab73b56..0000000000
--- a/contrib/go/_std_1.20/src/io/io.go
+++ /dev/null
@@ -1,710 +0,0 @@
-// Copyright 2009 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 io provides basic interfaces to I/O primitives.
-// Its primary job is to wrap existing implementations of such primitives,
-// such as those in package os, into shared public interfaces that
-// abstract the functionality, plus some other related primitives.
-//
-// Because these interfaces and primitives wrap lower-level operations with
-// various implementations, unless otherwise informed clients should not
-// assume they are safe for parallel execution.
-package io
-
-import (
- "errors"
- "sync"
-)
-
-// Seek whence values.
-const (
- SeekStart = 0 // seek relative to the origin of the file
- SeekCurrent = 1 // seek relative to the current offset
- SeekEnd = 2 // seek relative to the end
-)
-
-// ErrShortWrite means that a write accepted fewer bytes than requested
-// but failed to return an explicit error.
-var ErrShortWrite = errors.New("short write")
-
-// errInvalidWrite means that a write returned an impossible count.
-var errInvalidWrite = errors.New("invalid write result")
-
-// ErrShortBuffer means that a read required a longer buffer than was provided.
-var ErrShortBuffer = errors.New("short buffer")
-
-// EOF is the error returned by Read when no more input is available.
-// (Read must return EOF itself, not an error wrapping EOF,
-// because callers will test for EOF using ==.)
-// Functions should return EOF only to signal a graceful end of input.
-// If the EOF occurs unexpectedly in a structured data stream,
-// the appropriate error is either ErrUnexpectedEOF or some other error
-// giving more detail.
-var EOF = errors.New("EOF")
-
-// ErrUnexpectedEOF means that EOF was encountered in the
-// middle of reading a fixed-size block or data structure.
-var ErrUnexpectedEOF = errors.New("unexpected EOF")
-
-// ErrNoProgress is returned by some clients of a Reader when
-// many calls to Read have failed to return any data or error,
-// usually the sign of a broken Reader implementation.
-var ErrNoProgress = errors.New("multiple Read calls return no data or error")
-
-// Reader is the interface that wraps the basic Read method.
-//
-// Read reads up to len(p) bytes into p. It returns the number of bytes
-// read (0 <= n <= len(p)) and any error encountered. Even if Read
-// returns n < len(p), it may use all of p as scratch space during the call.
-// If some data is available but not len(p) bytes, Read conventionally
-// returns what is available instead of waiting for more.
-//
-// When Read encounters an error or end-of-file condition after
-// successfully reading n > 0 bytes, it returns the number of
-// bytes read. It may return the (non-nil) error from the same call
-// or return the error (and n == 0) from a subsequent call.
-// An instance of this general case is that a Reader returning
-// a non-zero number of bytes at the end of the input stream may
-// return either err == EOF or err == nil. The next Read should
-// return 0, EOF.
-//
-// Callers should always process the n > 0 bytes returned before
-// considering the error err. Doing so correctly handles I/O errors
-// that happen after reading some bytes and also both of the
-// allowed EOF behaviors.
-//
-// Implementations of Read are discouraged from returning a
-// zero byte count with a nil error, except when len(p) == 0.
-// Callers should treat a return of 0 and nil as indicating that
-// nothing happened; in particular it does not indicate EOF.
-//
-// Implementations must not retain p.
-type Reader interface {
- Read(p []byte) (n int, err error)
-}
-
-// Writer is the interface that wraps the basic Write method.
-//
-// Write writes len(p) bytes from p to the underlying data stream.
-// It returns the number of bytes written from p (0 <= n <= len(p))
-// and any error encountered that caused the write to stop early.
-// Write must return a non-nil error if it returns n < len(p).
-// Write must not modify the slice data, even temporarily.
-//
-// Implementations must not retain p.
-type Writer interface {
- Write(p []byte) (n int, err error)
-}
-
-// Closer is the interface that wraps the basic Close method.
-//
-// The behavior of Close after the first call is undefined.
-// Specific implementations may document their own behavior.
-type Closer interface {
- Close() error
-}
-
-// Seeker is the interface that wraps the basic Seek method.
-//
-// Seek sets the offset for the next Read or Write to offset,
-// interpreted according to whence:
-// SeekStart means relative to the start of the file,
-// SeekCurrent means relative to the current offset, and
-// SeekEnd means relative to the end
-// (for example, offset = -2 specifies the penultimate byte of the file).
-// Seek returns the new offset relative to the start of the
-// file or an error, if any.
-//
-// Seeking to an offset before the start of the file is an error.
-// Seeking to any positive offset may be allowed, but if the new offset exceeds
-// the size of the underlying object the behavior of subsequent I/O operations
-// is implementation-dependent.
-type Seeker interface {
- Seek(offset int64, whence int) (int64, error)
-}
-
-// ReadWriter is the interface that groups the basic Read and Write methods.
-type ReadWriter interface {
- Reader
- Writer
-}
-
-// ReadCloser is the interface that groups the basic Read and Close methods.
-type ReadCloser interface {
- Reader
- Closer
-}
-
-// WriteCloser is the interface that groups the basic Write and Close methods.
-type WriteCloser interface {
- Writer
- Closer
-}
-
-// ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.
-type ReadWriteCloser interface {
- Reader
- Writer
- Closer
-}
-
-// ReadSeeker is the interface that groups the basic Read and Seek methods.
-type ReadSeeker interface {
- Reader
- Seeker
-}
-
-// ReadSeekCloser is the interface that groups the basic Read, Seek and Close
-// methods.
-type ReadSeekCloser interface {
- Reader
- Seeker
- Closer
-}
-
-// WriteSeeker is the interface that groups the basic Write and Seek methods.
-type WriteSeeker interface {
- Writer
- Seeker
-}
-
-// ReadWriteSeeker is the interface that groups the basic Read, Write and Seek methods.
-type ReadWriteSeeker interface {
- Reader
- Writer
- Seeker
-}
-
-// ReaderFrom is the interface that wraps the ReadFrom method.
-//
-// ReadFrom reads data from r until EOF or error.
-// The return value n is the number of bytes read.
-// Any error except EOF encountered during the read is also returned.
-//
-// The Copy function uses ReaderFrom if available.
-type ReaderFrom interface {
- ReadFrom(r Reader) (n int64, err error)
-}
-
-// WriterTo is the interface that wraps the WriteTo method.
-//
-// WriteTo writes data to w until there's no more data to write or
-// when an error occurs. The return value n is the number of bytes
-// written. Any error encountered during the write is also returned.
-//
-// The Copy function uses WriterTo if available.
-type WriterTo interface {
- WriteTo(w Writer) (n int64, err error)
-}
-
-// ReaderAt is the interface that wraps the basic ReadAt method.
-//
-// ReadAt reads len(p) bytes into p starting at offset off in the
-// underlying input source. It returns the number of bytes
-// read (0 <= n <= len(p)) and any error encountered.
-//
-// When ReadAt returns n < len(p), it returns a non-nil error
-// explaining why more bytes were not returned. In this respect,
-// ReadAt is stricter than Read.
-//
-// Even if ReadAt returns n < len(p), it may use all of p as scratch
-// space during the call. If some data is available but not len(p) bytes,
-// ReadAt blocks until either all the data is available or an error occurs.
-// In this respect ReadAt is different from Read.
-//
-// If the n = len(p) bytes returned by ReadAt are at the end of the
-// input source, ReadAt may return either err == EOF or err == nil.
-//
-// If ReadAt is reading from an input source with a seek offset,
-// ReadAt should not affect nor be affected by the underlying
-// seek offset.
-//
-// Clients of ReadAt can execute parallel ReadAt calls on the
-// same input source.
-//
-// Implementations must not retain p.
-type ReaderAt interface {
- ReadAt(p []byte, off int64) (n int, err error)
-}
-
-// WriterAt is the interface that wraps the basic WriteAt method.
-//
-// WriteAt writes len(p) bytes from p to the underlying data stream
-// at offset off. It returns the number of bytes written from p (0 <= n <= len(p))
-// and any error encountered that caused the write to stop early.
-// WriteAt must return a non-nil error if it returns n < len(p).
-//
-// If WriteAt is writing to a destination with a seek offset,
-// WriteAt should not affect nor be affected by the underlying
-// seek offset.
-//
-// Clients of WriteAt can execute parallel WriteAt calls on the same
-// destination if the ranges do not overlap.
-//
-// Implementations must not retain p.
-type WriterAt interface {
- WriteAt(p []byte, off int64) (n int, err error)
-}
-
-// ByteReader is the interface that wraps the ReadByte method.
-//
-// ReadByte reads and returns the next byte from the input or
-// any error encountered. If ReadByte returns an error, no input
-// byte was consumed, and the returned byte value is undefined.
-//
-// ReadByte provides an efficient interface for byte-at-time
-// processing. A Reader that does not implement ByteReader
-// can be wrapped using bufio.NewReader to add this method.
-type ByteReader interface {
- ReadByte() (byte, error)
-}
-
-// ByteScanner is the interface that adds the UnreadByte method to the
-// basic ReadByte method.
-//
-// UnreadByte causes the next call to ReadByte to return the last byte read.
-// If the last operation was not a successful call to ReadByte, UnreadByte may
-// return an error, unread the last byte read (or the byte prior to the
-// last-unread byte), or (in implementations that support the Seeker interface)
-// seek to one byte before the current offset.
-type ByteScanner interface {
- ByteReader
- UnreadByte() error
-}
-
-// ByteWriter is the interface that wraps the WriteByte method.
-type ByteWriter interface {
- WriteByte(c byte) error
-}
-
-// RuneReader is the interface that wraps the ReadRune method.
-//
-// ReadRune reads a single encoded Unicode character
-// and returns the rune and its size in bytes. If no character is
-// available, err will be set.
-type RuneReader interface {
- ReadRune() (r rune, size int, err error)
-}
-
-// RuneScanner is the interface that adds the UnreadRune method to the
-// basic ReadRune method.
-//
-// UnreadRune causes the next call to ReadRune to return the last rune read.
-// If the last operation was not a successful call to ReadRune, UnreadRune may
-// return an error, unread the last rune read (or the rune prior to the
-// last-unread rune), or (in implementations that support the Seeker interface)
-// seek to the start of the rune before the current offset.
-type RuneScanner interface {
- RuneReader
- UnreadRune() error
-}
-
-// StringWriter is the interface that wraps the WriteString method.
-type StringWriter interface {
- WriteString(s string) (n int, err error)
-}
-
-// WriteString writes the contents of the string s to w, which accepts a slice of bytes.
-// If w implements StringWriter, its WriteString method is invoked directly.
-// Otherwise, w.Write is called exactly once.
-func WriteString(w Writer, s string) (n int, err error) {
- if sw, ok := w.(StringWriter); ok {
- return sw.WriteString(s)
- }
- return w.Write([]byte(s))
-}
-
-// ReadAtLeast reads from r into buf until it has read at least min bytes.
-// It returns the number of bytes copied and an error if fewer bytes were read.
-// The error is EOF only if no bytes were read.
-// If an EOF happens after reading fewer than min bytes,
-// ReadAtLeast returns ErrUnexpectedEOF.
-// If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer.
-// On return, n >= min if and only if err == nil.
-// If r returns an error having read at least min bytes, the error is dropped.
-func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) {
- if len(buf) < min {
- return 0, ErrShortBuffer
- }
- for n < min && err == nil {
- var nn int
- nn, err = r.Read(buf[n:])
- n += nn
- }
- if n >= min {
- err = nil
- } else if n > 0 && err == EOF {
- err = ErrUnexpectedEOF
- }
- return
-}
-
-// ReadFull reads exactly len(buf) bytes from r into buf.
-// It returns the number of bytes copied and an error if fewer bytes were read.
-// The error is EOF only if no bytes were read.
-// If an EOF happens after reading some but not all the bytes,
-// ReadFull returns ErrUnexpectedEOF.
-// On return, n == len(buf) if and only if err == nil.
-// If r returns an error having read at least len(buf) bytes, the error is dropped.
-func ReadFull(r Reader, buf []byte) (n int, err error) {
- return ReadAtLeast(r, buf, len(buf))
-}
-
-// CopyN copies n bytes (or until an error) from src to dst.
-// It returns the number of bytes copied and the earliest
-// error encountered while copying.
-// On return, written == n if and only if err == nil.
-//
-// If dst implements the ReaderFrom interface,
-// the copy is implemented using it.
-func CopyN(dst Writer, src Reader, n int64) (written int64, err error) {
- written, err = Copy(dst, LimitReader(src, n))
- if written == n {
- return n, nil
- }
- if written < n && err == nil {
- // src stopped early; must have been EOF.
- err = EOF
- }
- return
-}
-
-// Copy copies from src to dst until either EOF is reached
-// on src or an error occurs. It returns the number of bytes
-// copied and the first error encountered while copying, if any.
-//
-// A successful Copy returns err == nil, not err == EOF.
-// Because Copy is defined to read from src until EOF, it does
-// not treat an EOF from Read as an error to be reported.
-//
-// If src implements the WriterTo interface,
-// the copy is implemented by calling src.WriteTo(dst).
-// Otherwise, if dst implements the ReaderFrom interface,
-// the copy is implemented by calling dst.ReadFrom(src).
-func Copy(dst Writer, src Reader) (written int64, err error) {
- return copyBuffer(dst, src, nil)
-}
-
-// CopyBuffer is identical to Copy except that it stages through the
-// provided buffer (if one is required) rather than allocating a
-// temporary one. If buf is nil, one is allocated; otherwise if it has
-// zero length, CopyBuffer panics.
-//
-// If either src implements WriterTo or dst implements ReaderFrom,
-// buf will not be used to perform the copy.
-func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
- if buf != nil && len(buf) == 0 {
- panic("empty buffer in CopyBuffer")
- }
- return copyBuffer(dst, src, buf)
-}
-
-// copyBuffer is the actual implementation of Copy and CopyBuffer.
-// if buf is nil, one is allocated.
-func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
- // If the reader has a WriteTo method, use it to do the copy.
- // Avoids an allocation and a copy.
- if wt, ok := src.(WriterTo); ok {
- return wt.WriteTo(dst)
- }
- // Similarly, if the writer has a ReadFrom method, use it to do the copy.
- if rt, ok := dst.(ReaderFrom); ok {
- return rt.ReadFrom(src)
- }
- if buf == nil {
- size := 32 * 1024
- if l, ok := src.(*LimitedReader); ok && int64(size) > l.N {
- if l.N < 1 {
- size = 1
- } else {
- size = int(l.N)
- }
- }
- buf = make([]byte, size)
- }
- for {
- nr, er := src.Read(buf)
- if nr > 0 {
- nw, ew := dst.Write(buf[0:nr])
- if nw < 0 || nr < nw {
- nw = 0
- if ew == nil {
- ew = errInvalidWrite
- }
- }
- written += int64(nw)
- if ew != nil {
- err = ew
- break
- }
- if nr != nw {
- err = ErrShortWrite
- break
- }
- }
- if er != nil {
- if er != EOF {
- err = er
- }
- break
- }
- }
- return written, err
-}
-
-// LimitReader returns a Reader that reads from r
-// but stops with EOF after n bytes.
-// The underlying implementation is a *LimitedReader.
-func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} }
-
-// A LimitedReader reads from R but limits the amount of
-// data returned to just N bytes. Each call to Read
-// updates N to reflect the new amount remaining.
-// Read returns EOF when N <= 0 or when the underlying R returns EOF.
-type LimitedReader struct {
- R Reader // underlying reader
- N int64 // max bytes remaining
-}
-
-func (l *LimitedReader) Read(p []byte) (n int, err error) {
- if l.N <= 0 {
- return 0, EOF
- }
- if int64(len(p)) > l.N {
- p = p[0:l.N]
- }
- n, err = l.R.Read(p)
- l.N -= int64(n)
- return
-}
-
-// NewSectionReader returns a SectionReader that reads from r
-// starting at offset off and stops with EOF after n bytes.
-func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader {
- var remaining int64
- const maxint64 = 1<<63 - 1
- if off <= maxint64-n {
- remaining = n + off
- } else {
- // Overflow, with no way to return error.
- // Assume we can read up to an offset of 1<<63 - 1.
- remaining = maxint64
- }
- return &SectionReader{r, off, off, remaining}
-}
-
-// SectionReader implements Read, Seek, and ReadAt on a section
-// of an underlying ReaderAt.
-type SectionReader struct {
- r ReaderAt
- base int64
- off int64
- limit int64
-}
-
-func (s *SectionReader) Read(p []byte) (n int, err error) {
- if s.off >= s.limit {
- return 0, EOF
- }
- if max := s.limit - s.off; int64(len(p)) > max {
- p = p[0:max]
- }
- n, err = s.r.ReadAt(p, s.off)
- s.off += int64(n)
- return
-}
-
-var errWhence = errors.New("Seek: invalid whence")
-var errOffset = errors.New("Seek: invalid offset")
-
-func (s *SectionReader) Seek(offset int64, whence int) (int64, error) {
- switch whence {
- default:
- return 0, errWhence
- case SeekStart:
- offset += s.base
- case SeekCurrent:
- offset += s.off
- case SeekEnd:
- offset += s.limit
- }
- if offset < s.base {
- return 0, errOffset
- }
- s.off = offset
- return offset - s.base, nil
-}
-
-func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error) {
- if off < 0 || off >= s.limit-s.base {
- return 0, EOF
- }
- off += s.base
- if max := s.limit - off; int64(len(p)) > max {
- p = p[0:max]
- n, err = s.r.ReadAt(p, off)
- if err == nil {
- err = EOF
- }
- return n, err
- }
- return s.r.ReadAt(p, off)
-}
-
-// Size returns the size of the section in bytes.
-func (s *SectionReader) Size() int64 { return s.limit - s.base }
-
-// An OffsetWriter maps writes at offset base to offset base+off in the underlying writer.
-type OffsetWriter struct {
- w WriterAt
- base int64 // the original offset
- off int64 // the current offset
-}
-
-// NewOffsetWriter returns an OffsetWriter that writes to w
-// starting at offset off.
-func NewOffsetWriter(w WriterAt, off int64) *OffsetWriter {
- return &OffsetWriter{w, off, off}
-}
-
-func (o *OffsetWriter) Write(p []byte) (n int, err error) {
- n, err = o.w.WriteAt(p, o.off)
- o.off += int64(n)
- return
-}
-
-func (o *OffsetWriter) WriteAt(p []byte, off int64) (n int, err error) {
- off += o.base
- return o.w.WriteAt(p, off)
-}
-
-func (o *OffsetWriter) Seek(offset int64, whence int) (int64, error) {
- switch whence {
- default:
- return 0, errWhence
- case SeekStart:
- offset += o.base
- case SeekCurrent:
- offset += o.off
- }
- if offset < o.base {
- return 0, errOffset
- }
- o.off = offset
- return offset - o.base, nil
-}
-
-// TeeReader returns a Reader that writes to w what it reads from r.
-// All reads from r performed through it are matched with
-// corresponding writes to w. There is no internal buffering -
-// the write must complete before the read completes.
-// Any error encountered while writing is reported as a read error.
-func TeeReader(r Reader, w Writer) Reader {
- return &teeReader{r, w}
-}
-
-type teeReader struct {
- r Reader
- w Writer
-}
-
-func (t *teeReader) Read(p []byte) (n int, err error) {
- n, err = t.r.Read(p)
- if n > 0 {
- if n, err := t.w.Write(p[:n]); err != nil {
- return n, err
- }
- }
- return
-}
-
-// Discard is a Writer on which all Write calls succeed
-// without doing anything.
-var Discard Writer = discard{}
-
-type discard struct{}
-
-// discard implements ReaderFrom as an optimization so Copy to
-// io.Discard can avoid doing unnecessary work.
-var _ ReaderFrom = discard{}
-
-func (discard) Write(p []byte) (int, error) {
- return len(p), nil
-}
-
-func (discard) WriteString(s string) (int, error) {
- return len(s), nil
-}
-
-var blackHolePool = sync.Pool{
- New: func() any {
- b := make([]byte, 8192)
- return &b
- },
-}
-
-func (discard) ReadFrom(r Reader) (n int64, err error) {
- bufp := blackHolePool.Get().(*[]byte)
- readSize := 0
- for {
- readSize, err = r.Read(*bufp)
- n += int64(readSize)
- if err != nil {
- blackHolePool.Put(bufp)
- if err == EOF {
- return n, nil
- }
- return
- }
- }
-}
-
-// NopCloser returns a ReadCloser with a no-op Close method wrapping
-// the provided Reader r.
-// If r implements WriterTo, the returned ReadCloser will implement WriterTo
-// by forwarding calls to r.
-func NopCloser(r Reader) ReadCloser {
- if _, ok := r.(WriterTo); ok {
- return nopCloserWriterTo{r}
- }
- return nopCloser{r}
-}
-
-type nopCloser struct {
- Reader
-}
-
-func (nopCloser) Close() error { return nil }
-
-type nopCloserWriterTo struct {
- Reader
-}
-
-func (nopCloserWriterTo) Close() error { return nil }
-
-func (c nopCloserWriterTo) WriteTo(w Writer) (n int64, err error) {
- return c.Reader.(WriterTo).WriteTo(w)
-}
-
-// ReadAll reads from r until an error or EOF and returns the data it read.
-// A successful call returns err == nil, not err == EOF. Because ReadAll is
-// defined to read from src until EOF, it does not treat an EOF from Read
-// as an error to be reported.
-func ReadAll(r Reader) ([]byte, error) {
- b := make([]byte, 0, 512)
- for {
- if len(b) == cap(b) {
- // Add more capacity (let append pick how much).
- b = append(b, 0)[:len(b)]
- }
- n, err := r.Read(b[len(b):cap(b)])
- b = b[:len(b)+n]
- if err != nil {
- if err == EOF {
- err = nil
- }
- return b, err
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/io/ioutil/ioutil.go b/contrib/go/_std_1.20/src/io/ioutil/ioutil.go
deleted file mode 100644
index 6a1d69172c..0000000000
--- a/contrib/go/_std_1.20/src/io/ioutil/ioutil.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2009 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 ioutil implements some I/O utility functions.
-//
-// Deprecated: As of Go 1.16, the same functionality is now provided
-// by package io or package os, and those implementations
-// should be preferred in new code.
-// See the specific function documentation for details.
-package ioutil
-
-import (
- "io"
- "io/fs"
- "os"
- "sort"
-)
-
-// ReadAll reads from r until an error or EOF and returns the data it read.
-// A successful call returns err == nil, not err == EOF. Because ReadAll is
-// defined to read from src until EOF, it does not treat an EOF from Read
-// as an error to be reported.
-//
-// Deprecated: As of Go 1.16, this function simply calls io.ReadAll.
-func ReadAll(r io.Reader) ([]byte, error) {
- return io.ReadAll(r)
-}
-
-// ReadFile reads the file named by filename and returns the contents.
-// A successful call returns err == nil, not err == EOF. Because ReadFile
-// reads the whole file, it does not treat an EOF from Read as an error
-// to be reported.
-//
-// Deprecated: As of Go 1.16, this function simply calls os.ReadFile.
-func ReadFile(filename string) ([]byte, error) {
- return os.ReadFile(filename)
-}
-
-// WriteFile writes data to a file named by filename.
-// If the file does not exist, WriteFile creates it with permissions perm
-// (before umask); otherwise WriteFile truncates it before writing, without changing permissions.
-//
-// Deprecated: As of Go 1.16, this function simply calls os.WriteFile.
-func WriteFile(filename string, data []byte, perm fs.FileMode) error {
- return os.WriteFile(filename, data, perm)
-}
-
-// ReadDir reads the directory named by dirname and returns
-// a list of fs.FileInfo for the directory's contents,
-// sorted by filename. If an error occurs reading the directory,
-// ReadDir returns no directory entries along with the error.
-//
-// Deprecated: As of Go 1.16, os.ReadDir is a more efficient and correct choice:
-// it returns a list of fs.DirEntry instead of fs.FileInfo,
-// and it returns partial results in the case of an error
-// midway through reading a directory.
-//
-// If you must continue obtaining a list of fs.FileInfo, you still can:
-//
-// entries, err := os.ReadDir(dirname)
-// if err != nil { ... }
-// infos := make([]fs.FileInfo, 0, len(entries))
-// for _, entry := range entries {
-// info, err := entry.Info()
-// if err != nil { ... }
-// infos = append(infos, info)
-// }
-func ReadDir(dirname string) ([]fs.FileInfo, error) {
- f, err := os.Open(dirname)
- if err != nil {
- return nil, err
- }
- list, err := f.Readdir(-1)
- f.Close()
- if err != nil {
- return nil, err
- }
- sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
- return list, nil
-}
-
-// NopCloser returns a ReadCloser with a no-op Close method wrapping
-// the provided Reader r.
-//
-// Deprecated: As of Go 1.16, this function simply calls io.NopCloser.
-func NopCloser(r io.Reader) io.ReadCloser {
- return io.NopCloser(r)
-}
-
-// Discard is an io.Writer on which all Write calls succeed
-// without doing anything.
-//
-// Deprecated: As of Go 1.16, this value is simply io.Discard.
-var Discard io.Writer = io.Discard
diff --git a/contrib/go/_std_1.20/src/io/ioutil/tempfile.go b/contrib/go/_std_1.20/src/io/ioutil/tempfile.go
deleted file mode 100644
index 0561ad5a27..0000000000
--- a/contrib/go/_std_1.20/src/io/ioutil/tempfile.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2010 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 ioutil
-
-import (
- "os"
-)
-
-// TempFile creates a new temporary file in the directory dir,
-// opens the file for reading and writing, and returns the resulting *os.File.
-// The filename is generated by taking pattern and adding a random
-// string to the end. If pattern includes a "*", the random string
-// replaces the last "*".
-// If dir is the empty string, TempFile uses the default directory
-// for temporary files (see os.TempDir).
-// Multiple programs calling TempFile simultaneously
-// will not choose the same file. The caller can use f.Name()
-// to find the pathname of the file. It is the caller's responsibility
-// to remove the file when no longer needed.
-//
-// Deprecated: As of Go 1.17, this function simply calls os.CreateTemp.
-func TempFile(dir, pattern string) (f *os.File, err error) {
- return os.CreateTemp(dir, pattern)
-}
-
-// TempDir creates a new temporary directory in the directory dir.
-// The directory name is generated by taking pattern and applying a
-// random string to the end. If pattern includes a "*", the random string
-// replaces the last "*". TempDir returns the name of the new directory.
-// If dir is the empty string, TempDir uses the
-// default directory for temporary files (see os.TempDir).
-// Multiple programs calling TempDir simultaneously
-// will not choose the same directory. It is the caller's responsibility
-// to remove the directory when no longer needed.
-//
-// Deprecated: As of Go 1.17, this function simply calls os.MkdirTemp.
-func TempDir(dir, pattern string) (name string, err error) {
- return os.MkdirTemp(dir, pattern)
-}
diff --git a/contrib/go/_std_1.20/src/io/ioutil/ya.make b/contrib/go/_std_1.20/src/io/ioutil/ya.make
deleted file mode 100644
index 8eecd98560..0000000000
--- a/contrib/go/_std_1.20/src/io/ioutil/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- ioutil.go
- tempfile.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/io/ya.make b/contrib/go/_std_1.20/src/io/ya.make
deleted file mode 100644
index 22ea080bbf..0000000000
--- a/contrib/go/_std_1.20/src/io/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- io.go
- multi.go
- pipe.go
-)
-
-END()
-
-RECURSE(
- fs
- ioutil
-)
diff --git a/contrib/go/_std_1.20/src/log/log.go b/contrib/go/_std_1.20/src/log/log.go
deleted file mode 100644
index 566535f25c..0000000000
--- a/contrib/go/_std_1.20/src/log/log.go
+++ /dev/null
@@ -1,410 +0,0 @@
-// Copyright 2009 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 log implements a simple logging package. It defines a type, Logger,
-// with methods for formatting output. It also has a predefined 'standard'
-// Logger accessible through helper functions Print[f|ln], Fatal[f|ln], and
-// Panic[f|ln], which are easier to use than creating a Logger manually.
-// That logger writes to standard error and prints the date and time
-// of each logged message.
-// Every log message is output on a separate line: if the message being
-// printed does not end in a newline, the logger will add one.
-// The Fatal functions call os.Exit(1) after writing the log message.
-// The Panic functions call panic after writing the log message.
-package log
-
-import (
- "fmt"
- "io"
- "os"
- "runtime"
- "sync"
- "sync/atomic"
- "time"
-)
-
-// These flags define which text to prefix to each log entry generated by the Logger.
-// Bits are or'ed together to control what's printed.
-// With the exception of the Lmsgprefix flag, there is no
-// control over the order they appear (the order listed here)
-// or the format they present (as described in the comments).
-// The prefix is followed by a colon only when Llongfile or Lshortfile
-// is specified.
-// For example, flags Ldate | Ltime (or LstdFlags) produce,
-//
-// 2009/01/23 01:23:23 message
-//
-// while flags Ldate | Ltime | Lmicroseconds | Llongfile produce,
-//
-// 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
-const (
- Ldate = 1 << iota // the date in the local time zone: 2009/01/23
- Ltime // the time in the local time zone: 01:23:23
- Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
- Llongfile // full file name and line number: /a/b/c/d.go:23
- Lshortfile // final file name element and line number: d.go:23. overrides Llongfile
- LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone
- Lmsgprefix // move the "prefix" from the beginning of the line to before the message
- LstdFlags = Ldate | Ltime // initial values for the standard logger
-)
-
-// A Logger represents an active logging object that generates lines of
-// output to an io.Writer. Each logging operation makes a single call to
-// the Writer's Write method. A Logger can be used simultaneously from
-// multiple goroutines; it guarantees to serialize access to the Writer.
-type Logger struct {
- mu sync.Mutex // ensures atomic writes; protects the following fields
- prefix string // prefix on each line to identify the logger (but see Lmsgprefix)
- flag int // properties
- out io.Writer // destination for output
- buf []byte // for accumulating text to write
- isDiscard atomic.Bool // whether out == io.Discard
-}
-
-// New creates a new Logger. The out variable sets the
-// destination to which log data will be written.
-// The prefix appears at the beginning of each generated log line, or
-// after the log header if the Lmsgprefix flag is provided.
-// The flag argument defines the logging properties.
-func New(out io.Writer, prefix string, flag int) *Logger {
- l := &Logger{out: out, prefix: prefix, flag: flag}
- if out == io.Discard {
- l.isDiscard.Store(true)
- }
- return l
-}
-
-// SetOutput sets the output destination for the logger.
-func (l *Logger) SetOutput(w io.Writer) {
- l.mu.Lock()
- defer l.mu.Unlock()
- l.out = w
- l.isDiscard.Store(w == io.Discard)
-}
-
-var std = New(os.Stderr, "", LstdFlags)
-
-// Default returns the standard logger used by the package-level output functions.
-func Default() *Logger { return std }
-
-// Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding.
-func itoa(buf *[]byte, i int, wid int) {
- // Assemble decimal in reverse order.
- var b [20]byte
- bp := len(b) - 1
- for i >= 10 || wid > 1 {
- wid--
- q := i / 10
- b[bp] = byte('0' + i - q*10)
- bp--
- i = q
- }
- // i < 10
- b[bp] = byte('0' + i)
- *buf = append(*buf, b[bp:]...)
-}
-
-// formatHeader writes log header to buf in following order:
-// - l.prefix (if it's not blank and Lmsgprefix is unset),
-// - date and/or time (if corresponding flags are provided),
-// - file and line number (if corresponding flags are provided),
-// - l.prefix (if it's not blank and Lmsgprefix is set).
-func (l *Logger) formatHeader(buf *[]byte, t time.Time, file string, line int) {
- if l.flag&Lmsgprefix == 0 {
- *buf = append(*buf, l.prefix...)
- }
- if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 {
- if l.flag&LUTC != 0 {
- t = t.UTC()
- }
- if l.flag&Ldate != 0 {
- year, month, day := t.Date()
- itoa(buf, year, 4)
- *buf = append(*buf, '/')
- itoa(buf, int(month), 2)
- *buf = append(*buf, '/')
- itoa(buf, day, 2)
- *buf = append(*buf, ' ')
- }
- if l.flag&(Ltime|Lmicroseconds) != 0 {
- hour, min, sec := t.Clock()
- itoa(buf, hour, 2)
- *buf = append(*buf, ':')
- itoa(buf, min, 2)
- *buf = append(*buf, ':')
- itoa(buf, sec, 2)
- if l.flag&Lmicroseconds != 0 {
- *buf = append(*buf, '.')
- itoa(buf, t.Nanosecond()/1e3, 6)
- }
- *buf = append(*buf, ' ')
- }
- }
- if l.flag&(Lshortfile|Llongfile) != 0 {
- if l.flag&Lshortfile != 0 {
- short := file
- for i := len(file) - 1; i > 0; i-- {
- if file[i] == '/' {
- short = file[i+1:]
- break
- }
- }
- file = short
- }
- *buf = append(*buf, file...)
- *buf = append(*buf, ':')
- itoa(buf, line, -1)
- *buf = append(*buf, ": "...)
- }
- if l.flag&Lmsgprefix != 0 {
- *buf = append(*buf, l.prefix...)
- }
-}
-
-// Output writes the output for a logging event. The string s contains
-// the text to print after the prefix specified by the flags of the
-// Logger. A newline is appended if the last character of s is not
-// already a newline. Calldepth is used to recover the PC and is
-// provided for generality, although at the moment on all pre-defined
-// paths it will be 2.
-func (l *Logger) Output(calldepth int, s string) error {
- now := time.Now() // get this early.
- var file string
- var line int
- l.mu.Lock()
- defer l.mu.Unlock()
- if l.flag&(Lshortfile|Llongfile) != 0 {
- // Release lock while getting caller info - it's expensive.
- l.mu.Unlock()
- var ok bool
- _, file, line, ok = runtime.Caller(calldepth)
- if !ok {
- file = "???"
- line = 0
- }
- l.mu.Lock()
- }
- l.buf = l.buf[:0]
- l.formatHeader(&l.buf, now, file, line)
- l.buf = append(l.buf, s...)
- if len(s) == 0 || s[len(s)-1] != '\n' {
- l.buf = append(l.buf, '\n')
- }
- _, err := l.out.Write(l.buf)
- return err
-}
-
-// Printf calls l.Output to print to the logger.
-// Arguments are handled in the manner of fmt.Printf.
-func (l *Logger) Printf(format string, v ...any) {
- if l.isDiscard.Load() {
- return
- }
- l.Output(2, fmt.Sprintf(format, v...))
-}
-
-// Print calls l.Output to print to the logger.
-// Arguments are handled in the manner of fmt.Print.
-func (l *Logger) Print(v ...any) {
- if l.isDiscard.Load() {
- return
- }
- l.Output(2, fmt.Sprint(v...))
-}
-
-// Println calls l.Output to print to the logger.
-// Arguments are handled in the manner of fmt.Println.
-func (l *Logger) Println(v ...any) {
- if l.isDiscard.Load() {
- return
- }
- l.Output(2, fmt.Sprintln(v...))
-}
-
-// Fatal is equivalent to l.Print() followed by a call to os.Exit(1).
-func (l *Logger) Fatal(v ...any) {
- l.Output(2, fmt.Sprint(v...))
- os.Exit(1)
-}
-
-// Fatalf is equivalent to l.Printf() followed by a call to os.Exit(1).
-func (l *Logger) Fatalf(format string, v ...any) {
- l.Output(2, fmt.Sprintf(format, v...))
- os.Exit(1)
-}
-
-// Fatalln is equivalent to l.Println() followed by a call to os.Exit(1).
-func (l *Logger) Fatalln(v ...any) {
- l.Output(2, fmt.Sprintln(v...))
- os.Exit(1)
-}
-
-// Panic is equivalent to l.Print() followed by a call to panic().
-func (l *Logger) Panic(v ...any) {
- s := fmt.Sprint(v...)
- l.Output(2, s)
- panic(s)
-}
-
-// Panicf is equivalent to l.Printf() followed by a call to panic().
-func (l *Logger) Panicf(format string, v ...any) {
- s := fmt.Sprintf(format, v...)
- l.Output(2, s)
- panic(s)
-}
-
-// Panicln is equivalent to l.Println() followed by a call to panic().
-func (l *Logger) Panicln(v ...any) {
- s := fmt.Sprintln(v...)
- l.Output(2, s)
- panic(s)
-}
-
-// Flags returns the output flags for the logger.
-// The flag bits are Ldate, Ltime, and so on.
-func (l *Logger) Flags() int {
- l.mu.Lock()
- defer l.mu.Unlock()
- return l.flag
-}
-
-// SetFlags sets the output flags for the logger.
-// The flag bits are Ldate, Ltime, and so on.
-func (l *Logger) SetFlags(flag int) {
- l.mu.Lock()
- defer l.mu.Unlock()
- l.flag = flag
-}
-
-// Prefix returns the output prefix for the logger.
-func (l *Logger) Prefix() string {
- l.mu.Lock()
- defer l.mu.Unlock()
- return l.prefix
-}
-
-// SetPrefix sets the output prefix for the logger.
-func (l *Logger) SetPrefix(prefix string) {
- l.mu.Lock()
- defer l.mu.Unlock()
- l.prefix = prefix
-}
-
-// Writer returns the output destination for the logger.
-func (l *Logger) Writer() io.Writer {
- l.mu.Lock()
- defer l.mu.Unlock()
- return l.out
-}
-
-// SetOutput sets the output destination for the standard logger.
-func SetOutput(w io.Writer) {
- std.SetOutput(w)
-}
-
-// Flags returns the output flags for the standard logger.
-// The flag bits are Ldate, Ltime, and so on.
-func Flags() int {
- return std.Flags()
-}
-
-// SetFlags sets the output flags for the standard logger.
-// The flag bits are Ldate, Ltime, and so on.
-func SetFlags(flag int) {
- std.SetFlags(flag)
-}
-
-// Prefix returns the output prefix for the standard logger.
-func Prefix() string {
- return std.Prefix()
-}
-
-// SetPrefix sets the output prefix for the standard logger.
-func SetPrefix(prefix string) {
- std.SetPrefix(prefix)
-}
-
-// Writer returns the output destination for the standard logger.
-func Writer() io.Writer {
- return std.Writer()
-}
-
-// These functions write to the standard logger.
-
-// Print calls Output to print to the standard logger.
-// Arguments are handled in the manner of fmt.Print.
-func Print(v ...any) {
- if std.isDiscard.Load() {
- return
- }
- std.Output(2, fmt.Sprint(v...))
-}
-
-// Printf calls Output to print to the standard logger.
-// Arguments are handled in the manner of fmt.Printf.
-func Printf(format string, v ...any) {
- if std.isDiscard.Load() {
- return
- }
- std.Output(2, fmt.Sprintf(format, v...))
-}
-
-// Println calls Output to print to the standard logger.
-// Arguments are handled in the manner of fmt.Println.
-func Println(v ...any) {
- if std.isDiscard.Load() {
- return
- }
- std.Output(2, fmt.Sprintln(v...))
-}
-
-// Fatal is equivalent to Print() followed by a call to os.Exit(1).
-func Fatal(v ...any) {
- std.Output(2, fmt.Sprint(v...))
- os.Exit(1)
-}
-
-// Fatalf is equivalent to Printf() followed by a call to os.Exit(1).
-func Fatalf(format string, v ...any) {
- std.Output(2, fmt.Sprintf(format, v...))
- os.Exit(1)
-}
-
-// Fatalln is equivalent to Println() followed by a call to os.Exit(1).
-func Fatalln(v ...any) {
- std.Output(2, fmt.Sprintln(v...))
- os.Exit(1)
-}
-
-// Panic is equivalent to Print() followed by a call to panic().
-func Panic(v ...any) {
- s := fmt.Sprint(v...)
- std.Output(2, s)
- panic(s)
-}
-
-// Panicf is equivalent to Printf() followed by a call to panic().
-func Panicf(format string, v ...any) {
- s := fmt.Sprintf(format, v...)
- std.Output(2, s)
- panic(s)
-}
-
-// Panicln is equivalent to Println() followed by a call to panic().
-func Panicln(v ...any) {
- s := fmt.Sprintln(v...)
- std.Output(2, s)
- panic(s)
-}
-
-// Output writes the output for a logging event. The string s contains
-// the text to print after the prefix specified by the flags of the
-// Logger. A newline is appended if the last character of s is not
-// already a newline. Calldepth is the count of the number of
-// frames to skip when computing the file name and line number
-// if Llongfile or Lshortfile is set; a value of 1 will print the details
-// for the caller of Output.
-func Output(calldepth int, s string) error {
- return std.Output(calldepth+1, s) // +1 for this frame.
-}
diff --git a/contrib/go/_std_1.20/src/log/syslog/ya.make b/contrib/go/_std_1.20/src/log/syslog/ya.make
deleted file mode 100644
index 3f500430f4..0000000000
--- a/contrib/go/_std_1.20/src/log/syslog/ya.make
+++ /dev/null
@@ -1,21 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- doc.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- syslog.go
- syslog_unix.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- syslog.go
- syslog_unix.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/log/ya.make b/contrib/go/_std_1.20/src/log/ya.make
deleted file mode 100644
index 46e29d28e2..0000000000
--- a/contrib/go/_std_1.20/src/log/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- log.go
-)
-
-END()
-
-RECURSE(
- syslog
-)
diff --git a/contrib/go/_std_1.20/src/math/asinh.go b/contrib/go/_std_1.20/src/math/asinh.go
deleted file mode 100644
index 6f6e9e4608..0000000000
--- a/contrib/go/_std_1.20/src/math/asinh.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2010 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 math
-
-// The original C code, the long comment, and the constants
-// below are from FreeBSD's /usr/src/lib/msun/src/s_asinh.c
-// and came with this notice. The go code is a simplified
-// version of the original C.
-//
-// ====================================================
-// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-//
-// Developed at SunPro, a Sun Microsystems, Inc. business.
-// Permission to use, copy, modify, and distribute this
-// software is freely granted, provided that this notice
-// is preserved.
-// ====================================================
-//
-//
-// asinh(x)
-// Method :
-// Based on
-// asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
-// we have
-// asinh(x) := x if 1+x*x=1,
-// := sign(x)*(log(x)+ln2)) for large |x|, else
-// := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
-// := sign(x)*log1p(|x| + x**2/(1 + sqrt(1+x**2)))
-//
-
-// Asinh returns the inverse hyperbolic sine of x.
-//
-// Special cases are:
-//
-// Asinh(±0) = ±0
-// Asinh(±Inf) = ±Inf
-// Asinh(NaN) = NaN
-func Asinh(x float64) float64 {
- if haveArchAsinh {
- return archAsinh(x)
- }
- return asinh(x)
-}
-
-func asinh(x float64) float64 {
- const (
- Ln2 = 6.93147180559945286227e-01 // 0x3FE62E42FEFA39EF
- NearZero = 1.0 / (1 << 28) // 2**-28
- Large = 1 << 28 // 2**28
- )
- // special cases
- if IsNaN(x) || IsInf(x, 0) {
- return x
- }
- sign := false
- if x < 0 {
- x = -x
- sign = true
- }
- var temp float64
- switch {
- case x > Large:
- temp = Log(x) + Ln2 // |x| > 2**28
- case x > 2:
- temp = Log(2*x + 1/(Sqrt(x*x+1)+x)) // 2**28 > |x| > 2.0
- case x < NearZero:
- temp = x // |x| < 2**-28
- default:
- temp = Log1p(x + x*x/(1+Sqrt(1+x*x))) // 2.0 > |x| > 2**-28
- }
- if sign {
- temp = -temp
- }
- return temp
-}
diff --git a/contrib/go/_std_1.20/src/math/big/accuracy_string.go b/contrib/go/_std_1.20/src/math/big/accuracy_string.go
deleted file mode 100644
index 1501ace00d..0000000000
--- a/contrib/go/_std_1.20/src/math/big/accuracy_string.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Code generated by "stringer -type=Accuracy"; DO NOT EDIT.
-
-package big
-
-import "strconv"
-
-const _Accuracy_name = "BelowExactAbove"
-
-var _Accuracy_index = [...]uint8{0, 5, 10, 15}
-
-func (i Accuracy) String() string {
- i -= -1
- if i < 0 || i >= Accuracy(len(_Accuracy_index)-1) {
- return "Accuracy(" + strconv.FormatInt(int64(i+-1), 10) + ")"
- }
- return _Accuracy_name[_Accuracy_index[i]:_Accuracy_index[i+1]]
-}
diff --git a/contrib/go/_std_1.20/src/math/big/doc.go b/contrib/go/_std_1.20/src/math/big/doc.go
deleted file mode 100644
index 65ed019b74..0000000000
--- a/contrib/go/_std_1.20/src/math/big/doc.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2009 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 big implements arbitrary-precision arithmetic (big numbers).
-The following numeric types are supported:
-
- Int signed integers
- Rat rational numbers
- Float floating-point numbers
-
-The zero value for an Int, Rat, or Float correspond to 0. Thus, new
-values can be declared in the usual ways and denote 0 without further
-initialization:
-
- var x Int // &x is an *Int of value 0
- var r = &Rat{} // r is a *Rat of value 0
- y := new(Float) // y is a *Float of value 0
-
-Alternatively, new values can be allocated and initialized with factory
-functions of the form:
-
- func NewT(v V) *T
-
-For instance, NewInt(x) returns an *Int set to the value of the int64
-argument x, NewRat(a, b) returns a *Rat set to the fraction a/b where
-a and b are int64 values, and NewFloat(f) returns a *Float initialized
-to the float64 argument f. More flexibility is provided with explicit
-setters, for instance:
-
- var z1 Int
- z1.SetUint64(123) // z1 := 123
- z2 := new(Rat).SetFloat64(1.25) // z2 := 5/4
- z3 := new(Float).SetInt(z1) // z3 := 123.0
-
-Setters, numeric operations and predicates are represented as methods of
-the form:
-
- func (z *T) SetV(v V) *T // z = v
- func (z *T) Unary(x *T) *T // z = unary x
- func (z *T) Binary(x, y *T) *T // z = x binary y
- func (x *T) Pred() P // p = pred(x)
-
-with T one of Int, Rat, or Float. For unary and binary operations, the
-result is the receiver (usually named z in that case; see below); if it
-is one of the operands x or y it may be safely overwritten (and its memory
-reused).
-
-Arithmetic expressions are typically written as a sequence of individual
-method calls, with each call corresponding to an operation. The receiver
-denotes the result and the method arguments are the operation's operands.
-For instance, given three *Int values a, b and c, the invocation
-
- c.Add(a, b)
-
-computes the sum a + b and stores the result in c, overwriting whatever
-value was held in c before. Unless specified otherwise, operations permit
-aliasing of parameters, so it is perfectly ok to write
-
- sum.Add(sum, x)
-
-to accumulate values x in a sum.
-
-(By always passing in a result value via the receiver, memory use can be
-much better controlled. Instead of having to allocate new memory for each
-result, an operation can reuse the space allocated for the result value,
-and overwrite that value with the new result in the process.)
-
-Notational convention: Incoming method parameters (including the receiver)
-are named consistently in the API to clarify their use. Incoming operands
-are usually named x, y, a, b, and so on, but never z. A parameter specifying
-the result is named z (typically the receiver).
-
-For instance, the arguments for (*Int).Add are named x and y, and because
-the receiver specifies the result destination, it is called z:
-
- func (z *Int) Add(x, y *Int) *Int
-
-Methods of this form typically return the incoming receiver as well, to
-enable simple call chaining.
-
-Methods which don't require a result value to be passed in (for instance,
-Int.Sign), simply return the result. In this case, the receiver is typically
-the first operand, named x:
-
- func (x *Int) Sign() int
-
-Various methods support conversions between strings and corresponding
-numeric values, and vice versa: *Int, *Rat, and *Float values implement
-the Stringer interface for a (default) string representation of the value,
-but also provide SetString methods to initialize a value from a string in
-a variety of supported formats (see the respective SetString documentation).
-
-Finally, *Int, *Rat, and *Float satisfy the fmt package's Scanner interface
-for scanning and (except for *Rat) the Formatter interface for formatted
-printing.
-*/
-package big
diff --git a/contrib/go/_std_1.20/src/math/big/float.go b/contrib/go/_std_1.20/src/math/big/float.go
deleted file mode 100644
index 84666d817b..0000000000
--- a/contrib/go/_std_1.20/src/math/big/float.go
+++ /dev/null
@@ -1,1729 +0,0 @@
-// Copyright 2014 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.
-
-// This file implements multi-precision floating-point numbers.
-// Like in the GNU MPFR library (https://www.mpfr.org/), operands
-// can be of mixed precision. Unlike MPFR, the rounding mode is
-// not specified with each operation, but with each operand. The
-// rounding mode of the result operand determines the rounding
-// mode of an operation. This is a from-scratch implementation.
-
-package big
-
-import (
- "fmt"
- "math"
- "math/bits"
-)
-
-const debugFloat = false // enable for debugging
-
-// A nonzero finite Float represents a multi-precision floating point number
-//
-// sign × mantissa × 2**exponent
-//
-// with 0.5 <= mantissa < 1.0, and MinExp <= exponent <= MaxExp.
-// A Float may also be zero (+0, -0) or infinite (+Inf, -Inf).
-// All Floats are ordered, and the ordering of two Floats x and y
-// is defined by x.Cmp(y).
-//
-// Each Float value also has a precision, rounding mode, and accuracy.
-// The precision is the maximum number of mantissa bits available to
-// represent the value. The rounding mode specifies how a result should
-// be rounded to fit into the mantissa bits, and accuracy describes the
-// rounding error with respect to the exact result.
-//
-// Unless specified otherwise, all operations (including setters) that
-// specify a *Float variable for the result (usually via the receiver
-// with the exception of MantExp), round the numeric result according
-// to the precision and rounding mode of the result variable.
-//
-// If the provided result precision is 0 (see below), it is set to the
-// precision of the argument with the largest precision value before any
-// rounding takes place, and the rounding mode remains unchanged. Thus,
-// uninitialized Floats provided as result arguments will have their
-// precision set to a reasonable value determined by the operands, and
-// their mode is the zero value for RoundingMode (ToNearestEven).
-//
-// By setting the desired precision to 24 or 53 and using matching rounding
-// mode (typically ToNearestEven), Float operations produce the same results
-// as the corresponding float32 or float64 IEEE-754 arithmetic for operands
-// that correspond to normal (i.e., not denormal) float32 or float64 numbers.
-// Exponent underflow and overflow lead to a 0 or an Infinity for different
-// values than IEEE-754 because Float exponents have a much larger range.
-//
-// The zero (uninitialized) value for a Float is ready to use and represents
-// the number +0.0 exactly, with precision 0 and rounding mode ToNearestEven.
-//
-// Operations always take pointer arguments (*Float) rather
-// than Float values, and each unique Float value requires
-// its own unique *Float pointer. To "copy" a Float value,
-// an existing (or newly allocated) Float must be set to
-// a new value using the Float.Set method; shallow copies
-// of Floats are not supported and may lead to errors.
-type Float struct {
- prec uint32
- mode RoundingMode
- acc Accuracy
- form form
- neg bool
- mant nat
- exp int32
-}
-
-// An ErrNaN panic is raised by a Float operation that would lead to
-// a NaN under IEEE-754 rules. An ErrNaN implements the error interface.
-type ErrNaN struct {
- msg string
-}
-
-func (err ErrNaN) Error() string {
- return err.msg
-}
-
-// NewFloat allocates and returns a new Float set to x,
-// with precision 53 and rounding mode ToNearestEven.
-// NewFloat panics with ErrNaN if x is a NaN.
-func NewFloat(x float64) *Float {
- if math.IsNaN(x) {
- panic(ErrNaN{"NewFloat(NaN)"})
- }
- return new(Float).SetFloat64(x)
-}
-
-// Exponent and precision limits.
-const (
- MaxExp = math.MaxInt32 // largest supported exponent
- MinExp = math.MinInt32 // smallest supported exponent
- MaxPrec = math.MaxUint32 // largest (theoretically) supported precision; likely memory-limited
-)
-
-// Internal representation: The mantissa bits x.mant of a nonzero finite
-// Float x are stored in a nat slice long enough to hold up to x.prec bits;
-// the slice may (but doesn't have to) be shorter if the mantissa contains
-// trailing 0 bits. x.mant is normalized if the msb of x.mant == 1 (i.e.,
-// the msb is shifted all the way "to the left"). Thus, if the mantissa has
-// trailing 0 bits or x.prec is not a multiple of the Word size _W,
-// x.mant[0] has trailing zero bits. The msb of the mantissa corresponds
-// to the value 0.5; the exponent x.exp shifts the binary point as needed.
-//
-// A zero or non-finite Float x ignores x.mant and x.exp.
-//
-// x form neg mant exp
-// ----------------------------------------------------------
-// ±0 zero sign - -
-// 0 < |x| < +Inf finite sign mantissa exponent
-// ±Inf inf sign - -
-
-// A form value describes the internal representation.
-type form byte
-
-// The form value order is relevant - do not change!
-const (
- zero form = iota
- finite
- inf
-)
-
-// RoundingMode determines how a Float value is rounded to the
-// desired precision. Rounding may change the Float value; the
-// rounding error is described by the Float's Accuracy.
-type RoundingMode byte
-
-// These constants define supported rounding modes.
-const (
- ToNearestEven RoundingMode = iota // == IEEE 754-2008 roundTiesToEven
- ToNearestAway // == IEEE 754-2008 roundTiesToAway
- ToZero // == IEEE 754-2008 roundTowardZero
- AwayFromZero // no IEEE 754-2008 equivalent
- ToNegativeInf // == IEEE 754-2008 roundTowardNegative
- ToPositiveInf // == IEEE 754-2008 roundTowardPositive
-)
-
-//go:generate stringer -type=RoundingMode
-
-// Accuracy describes the rounding error produced by the most recent
-// operation that generated a Float value, relative to the exact value.
-type Accuracy int8
-
-// Constants describing the Accuracy of a Float.
-const (
- Below Accuracy = -1
- Exact Accuracy = 0
- Above Accuracy = +1
-)
-
-//go:generate stringer -type=Accuracy
-
-// SetPrec sets z's precision to prec and returns the (possibly) rounded
-// value of z. Rounding occurs according to z's rounding mode if the mantissa
-// cannot be represented in prec bits without loss of precision.
-// SetPrec(0) maps all finite values to ±0; infinite values remain unchanged.
-// If prec > MaxPrec, it is set to MaxPrec.
-func (z *Float) SetPrec(prec uint) *Float {
- z.acc = Exact // optimistically assume no rounding is needed
-
- // special case
- if prec == 0 {
- z.prec = 0
- if z.form == finite {
- // truncate z to 0
- z.acc = makeAcc(z.neg)
- z.form = zero
- }
- return z
- }
-
- // general case
- if prec > MaxPrec {
- prec = MaxPrec
- }
- old := z.prec
- z.prec = uint32(prec)
- if z.prec < old {
- z.round(0)
- }
- return z
-}
-
-func makeAcc(above bool) Accuracy {
- if above {
- return Above
- }
- return Below
-}
-
-// SetMode sets z's rounding mode to mode and returns an exact z.
-// z remains unchanged otherwise.
-// z.SetMode(z.Mode()) is a cheap way to set z's accuracy to Exact.
-func (z *Float) SetMode(mode RoundingMode) *Float {
- z.mode = mode
- z.acc = Exact
- return z
-}
-
-// Prec returns the mantissa precision of x in bits.
-// The result may be 0 for |x| == 0 and |x| == Inf.
-func (x *Float) Prec() uint {
- return uint(x.prec)
-}
-
-// MinPrec returns the minimum precision required to represent x exactly
-// (i.e., the smallest prec before x.SetPrec(prec) would start rounding x).
-// The result is 0 for |x| == 0 and |x| == Inf.
-func (x *Float) MinPrec() uint {
- if x.form != finite {
- return 0
- }
- return uint(len(x.mant))*_W - x.mant.trailingZeroBits()
-}
-
-// Mode returns the rounding mode of x.
-func (x *Float) Mode() RoundingMode {
- return x.mode
-}
-
-// Acc returns the accuracy of x produced by the most recent
-// operation, unless explicitly documented otherwise by that
-// operation.
-func (x *Float) Acc() Accuracy {
- return x.acc
-}
-
-// Sign returns:
-//
-// -1 if x < 0
-// 0 if x is ±0
-// +1 if x > 0
-func (x *Float) Sign() int {
- if debugFloat {
- x.validate()
- }
- if x.form == zero {
- return 0
- }
- if x.neg {
- return -1
- }
- return 1
-}
-
-// MantExp breaks x into its mantissa and exponent components
-// and returns the exponent. If a non-nil mant argument is
-// provided its value is set to the mantissa of x, with the
-// same precision and rounding mode as x. The components
-// satisfy x == mant × 2**exp, with 0.5 <= |mant| < 1.0.
-// Calling MantExp with a nil argument is an efficient way to
-// get the exponent of the receiver.
-//
-// Special cases are:
-//
-// ( ±0).MantExp(mant) = 0, with mant set to ±0
-// (±Inf).MantExp(mant) = 0, with mant set to ±Inf
-//
-// x and mant may be the same in which case x is set to its
-// mantissa value.
-func (x *Float) MantExp(mant *Float) (exp int) {
- if debugFloat {
- x.validate()
- }
- if x.form == finite {
- exp = int(x.exp)
- }
- if mant != nil {
- mant.Copy(x)
- if mant.form == finite {
- mant.exp = 0
- }
- }
- return
-}
-
-func (z *Float) setExpAndRound(exp int64, sbit uint) {
- if exp < MinExp {
- // underflow
- z.acc = makeAcc(z.neg)
- z.form = zero
- return
- }
-
- if exp > MaxExp {
- // overflow
- z.acc = makeAcc(!z.neg)
- z.form = inf
- return
- }
-
- z.form = finite
- z.exp = int32(exp)
- z.round(sbit)
-}
-
-// SetMantExp sets z to mant × 2**exp and returns z.
-// The result z has the same precision and rounding mode
-// as mant. SetMantExp is an inverse of MantExp but does
-// not require 0.5 <= |mant| < 1.0. Specifically, for a
-// given x of type *Float, SetMantExp relates to MantExp
-// as follows:
-//
-// mant := new(Float)
-// new(Float).SetMantExp(mant, x.MantExp(mant)).Cmp(x) == 0
-//
-// Special cases are:
-//
-// z.SetMantExp( ±0, exp) = ±0
-// z.SetMantExp(±Inf, exp) = ±Inf
-//
-// z and mant may be the same in which case z's exponent
-// is set to exp.
-func (z *Float) SetMantExp(mant *Float, exp int) *Float {
- if debugFloat {
- z.validate()
- mant.validate()
- }
- z.Copy(mant)
-
- if z.form == finite {
- // 0 < |mant| < +Inf
- z.setExpAndRound(int64(z.exp)+int64(exp), 0)
- }
- return z
-}
-
-// Signbit reports whether x is negative or negative zero.
-func (x *Float) Signbit() bool {
- return x.neg
-}
-
-// IsInf reports whether x is +Inf or -Inf.
-func (x *Float) IsInf() bool {
- return x.form == inf
-}
-
-// IsInt reports whether x is an integer.
-// ±Inf values are not integers.
-func (x *Float) IsInt() bool {
- if debugFloat {
- x.validate()
- }
- // special cases
- if x.form != finite {
- return x.form == zero
- }
- // x.form == finite
- if x.exp <= 0 {
- return false
- }
- // x.exp > 0
- return x.prec <= uint32(x.exp) || x.MinPrec() <= uint(x.exp) // not enough bits for fractional mantissa
-}
-
-// debugging support
-func (x *Float) validate() {
- if !debugFloat {
- // avoid performance bugs
- panic("validate called but debugFloat is not set")
- }
- if x.form != finite {
- return
- }
- m := len(x.mant)
- if m == 0 {
- panic("nonzero finite number with empty mantissa")
- }
- const msb = 1 << (_W - 1)
- if x.mant[m-1]&msb == 0 {
- panic(fmt.Sprintf("msb not set in last word %#x of %s", x.mant[m-1], x.Text('p', 0)))
- }
- if x.prec == 0 {
- panic("zero precision finite number")
- }
-}
-
-// round rounds z according to z.mode to z.prec bits and sets z.acc accordingly.
-// sbit must be 0 or 1 and summarizes any "sticky bit" information one might
-// have before calling round. z's mantissa must be normalized (with the msb set)
-// or empty.
-//
-// CAUTION: The rounding modes ToNegativeInf, ToPositiveInf are affected by the
-// sign of z. For correct rounding, the sign of z must be set correctly before
-// calling round.
-func (z *Float) round(sbit uint) {
- if debugFloat {
- z.validate()
- }
-
- z.acc = Exact
- if z.form != finite {
- // ±0 or ±Inf => nothing left to do
- return
- }
- // z.form == finite && len(z.mant) > 0
- // m > 0 implies z.prec > 0 (checked by validate)
-
- m := uint32(len(z.mant)) // present mantissa length in words
- bits := m * _W // present mantissa bits; bits > 0
- if bits <= z.prec {
- // mantissa fits => nothing to do
- return
- }
- // bits > z.prec
-
- // Rounding is based on two bits: the rounding bit (rbit) and the
- // sticky bit (sbit). The rbit is the bit immediately before the
- // z.prec leading mantissa bits (the "0.5"). The sbit is set if any
- // of the bits before the rbit are set (the "0.25", "0.125", etc.):
- //
- // rbit sbit => "fractional part"
- //
- // 0 0 == 0
- // 0 1 > 0 , < 0.5
- // 1 0 == 0.5
- // 1 1 > 0.5, < 1.0
-
- // bits > z.prec: mantissa too large => round
- r := uint(bits - z.prec - 1) // rounding bit position; r >= 0
- rbit := z.mant.bit(r) & 1 // rounding bit; be safe and ensure it's a single bit
- // The sticky bit is only needed for rounding ToNearestEven
- // or when the rounding bit is zero. Avoid computation otherwise.
- if sbit == 0 && (rbit == 0 || z.mode == ToNearestEven) {
- sbit = z.mant.sticky(r)
- }
- sbit &= 1 // be safe and ensure it's a single bit
-
- // cut off extra words
- n := (z.prec + (_W - 1)) / _W // mantissa length in words for desired precision
- if m > n {
- copy(z.mant, z.mant[m-n:]) // move n last words to front
- z.mant = z.mant[:n]
- }
-
- // determine number of trailing zero bits (ntz) and compute lsb mask of mantissa's least-significant word
- ntz := n*_W - z.prec // 0 <= ntz < _W
- lsb := Word(1) << ntz
-
- // round if result is inexact
- if rbit|sbit != 0 {
- // Make rounding decision: The result mantissa is truncated ("rounded down")
- // by default. Decide if we need to increment, or "round up", the (unsigned)
- // mantissa.
- inc := false
- switch z.mode {
- case ToNegativeInf:
- inc = z.neg
- case ToZero:
- // nothing to do
- case ToNearestEven:
- inc = rbit != 0 && (sbit != 0 || z.mant[0]&lsb != 0)
- case ToNearestAway:
- inc = rbit != 0
- case AwayFromZero:
- inc = true
- case ToPositiveInf:
- inc = !z.neg
- default:
- panic("unreachable")
- }
-
- // A positive result (!z.neg) is Above the exact result if we increment,
- // and it's Below if we truncate (Exact results require no rounding).
- // For a negative result (z.neg) it is exactly the opposite.
- z.acc = makeAcc(inc != z.neg)
-
- if inc {
- // add 1 to mantissa
- if addVW(z.mant, z.mant, lsb) != 0 {
- // mantissa overflow => adjust exponent
- if z.exp >= MaxExp {
- // exponent overflow
- z.form = inf
- return
- }
- z.exp++
- // adjust mantissa: divide by 2 to compensate for exponent adjustment
- shrVU(z.mant, z.mant, 1)
- // set msb == carry == 1 from the mantissa overflow above
- const msb = 1 << (_W - 1)
- z.mant[n-1] |= msb
- }
- }
- }
-
- // zero out trailing bits in least-significant word
- z.mant[0] &^= lsb - 1
-
- if debugFloat {
- z.validate()
- }
-}
-
-func (z *Float) setBits64(neg bool, x uint64) *Float {
- if z.prec == 0 {
- z.prec = 64
- }
- z.acc = Exact
- z.neg = neg
- if x == 0 {
- z.form = zero
- return z
- }
- // x != 0
- z.form = finite
- s := bits.LeadingZeros64(x)
- z.mant = z.mant.setUint64(x << uint(s))
- z.exp = int32(64 - s) // always fits
- if z.prec < 64 {
- z.round(0)
- }
- return z
-}
-
-// SetUint64 sets z to the (possibly rounded) value of x and returns z.
-// If z's precision is 0, it is changed to 64 (and rounding will have
-// no effect).
-func (z *Float) SetUint64(x uint64) *Float {
- return z.setBits64(false, x)
-}
-
-// SetInt64 sets z to the (possibly rounded) value of x and returns z.
-// If z's precision is 0, it is changed to 64 (and rounding will have
-// no effect).
-func (z *Float) SetInt64(x int64) *Float {
- u := x
- if u < 0 {
- u = -u
- }
- // We cannot simply call z.SetUint64(uint64(u)) and change
- // the sign afterwards because the sign affects rounding.
- return z.setBits64(x < 0, uint64(u))
-}
-
-// SetFloat64 sets z to the (possibly rounded) value of x and returns z.
-// If z's precision is 0, it is changed to 53 (and rounding will have
-// no effect). SetFloat64 panics with ErrNaN if x is a NaN.
-func (z *Float) SetFloat64(x float64) *Float {
- if z.prec == 0 {
- z.prec = 53
- }
- if math.IsNaN(x) {
- panic(ErrNaN{"Float.SetFloat64(NaN)"})
- }
- z.acc = Exact
- z.neg = math.Signbit(x) // handle -0, -Inf correctly
- if x == 0 {
- z.form = zero
- return z
- }
- if math.IsInf(x, 0) {
- z.form = inf
- return z
- }
- // normalized x != 0
- z.form = finite
- fmant, exp := math.Frexp(x) // get normalized mantissa
- z.mant = z.mant.setUint64(1<<63 | math.Float64bits(fmant)<<11)
- z.exp = int32(exp) // always fits
- if z.prec < 53 {
- z.round(0)
- }
- return z
-}
-
-// fnorm normalizes mantissa m by shifting it to the left
-// such that the msb of the most-significant word (msw) is 1.
-// It returns the shift amount. It assumes that len(m) != 0.
-func fnorm(m nat) int64 {
- if debugFloat && (len(m) == 0 || m[len(m)-1] == 0) {
- panic("msw of mantissa is 0")
- }
- s := nlz(m[len(m)-1])
- if s > 0 {
- c := shlVU(m, m, s)
- if debugFloat && c != 0 {
- panic("nlz or shlVU incorrect")
- }
- }
- return int64(s)
-}
-
-// SetInt sets z to the (possibly rounded) value of x and returns z.
-// If z's precision is 0, it is changed to the larger of x.BitLen()
-// or 64 (and rounding will have no effect).
-func (z *Float) SetInt(x *Int) *Float {
- // TODO(gri) can be more efficient if z.prec > 0
- // but small compared to the size of x, or if there
- // are many trailing 0's.
- bits := uint32(x.BitLen())
- if z.prec == 0 {
- z.prec = umax32(bits, 64)
- }
- z.acc = Exact
- z.neg = x.neg
- if len(x.abs) == 0 {
- z.form = zero
- return z
- }
- // x != 0
- z.mant = z.mant.set(x.abs)
- fnorm(z.mant)
- z.setExpAndRound(int64(bits), 0)
- return z
-}
-
-// SetRat sets z to the (possibly rounded) value of x and returns z.
-// If z's precision is 0, it is changed to the largest of a.BitLen(),
-// b.BitLen(), or 64; with x = a/b.
-func (z *Float) SetRat(x *Rat) *Float {
- if x.IsInt() {
- return z.SetInt(x.Num())
- }
- var a, b Float
- a.SetInt(x.Num())
- b.SetInt(x.Denom())
- if z.prec == 0 {
- z.prec = umax32(a.prec, b.prec)
- }
- return z.Quo(&a, &b)
-}
-
-// SetInf sets z to the infinite Float -Inf if signbit is
-// set, or +Inf if signbit is not set, and returns z. The
-// precision of z is unchanged and the result is always
-// Exact.
-func (z *Float) SetInf(signbit bool) *Float {
- z.acc = Exact
- z.form = inf
- z.neg = signbit
- return z
-}
-
-// Set sets z to the (possibly rounded) value of x and returns z.
-// If z's precision is 0, it is changed to the precision of x
-// before setting z (and rounding will have no effect).
-// Rounding is performed according to z's precision and rounding
-// mode; and z's accuracy reports the result error relative to the
-// exact (not rounded) result.
-func (z *Float) Set(x *Float) *Float {
- if debugFloat {
- x.validate()
- }
- z.acc = Exact
- if z != x {
- z.form = x.form
- z.neg = x.neg
- if x.form == finite {
- z.exp = x.exp
- z.mant = z.mant.set(x.mant)
- }
- if z.prec == 0 {
- z.prec = x.prec
- } else if z.prec < x.prec {
- z.round(0)
- }
- }
- return z
-}
-
-// Copy sets z to x, with the same precision, rounding mode, and
-// accuracy as x, and returns z. x is not changed even if z and
-// x are the same.
-func (z *Float) Copy(x *Float) *Float {
- if debugFloat {
- x.validate()
- }
- if z != x {
- z.prec = x.prec
- z.mode = x.mode
- z.acc = x.acc
- z.form = x.form
- z.neg = x.neg
- if z.form == finite {
- z.mant = z.mant.set(x.mant)
- z.exp = x.exp
- }
- }
- return z
-}
-
-// msb32 returns the 32 most significant bits of x.
-func msb32(x nat) uint32 {
- i := len(x) - 1
- if i < 0 {
- return 0
- }
- if debugFloat && x[i]&(1<<(_W-1)) == 0 {
- panic("x not normalized")
- }
- switch _W {
- case 32:
- return uint32(x[i])
- case 64:
- return uint32(x[i] >> 32)
- }
- panic("unreachable")
-}
-
-// msb64 returns the 64 most significant bits of x.
-func msb64(x nat) uint64 {
- i := len(x) - 1
- if i < 0 {
- return 0
- }
- if debugFloat && x[i]&(1<<(_W-1)) == 0 {
- panic("x not normalized")
- }
- switch _W {
- case 32:
- v := uint64(x[i]) << 32
- if i > 0 {
- v |= uint64(x[i-1])
- }
- return v
- case 64:
- return uint64(x[i])
- }
- panic("unreachable")
-}
-
-// Uint64 returns the unsigned integer resulting from truncating x
-// towards zero. If 0 <= x <= math.MaxUint64, the result is Exact
-// if x is an integer and Below otherwise.
-// The result is (0, Above) for x < 0, and (math.MaxUint64, Below)
-// for x > math.MaxUint64.
-func (x *Float) Uint64() (uint64, Accuracy) {
- if debugFloat {
- x.validate()
- }
-
- switch x.form {
- case finite:
- if x.neg {
- return 0, Above
- }
- // 0 < x < +Inf
- if x.exp <= 0 {
- // 0 < x < 1
- return 0, Below
- }
- // 1 <= x < Inf
- if x.exp <= 64 {
- // u = trunc(x) fits into a uint64
- u := msb64(x.mant) >> (64 - uint32(x.exp))
- if x.MinPrec() <= 64 {
- return u, Exact
- }
- return u, Below // x truncated
- }
- // x too large
- return math.MaxUint64, Below
-
- case zero:
- return 0, Exact
-
- case inf:
- if x.neg {
- return 0, Above
- }
- return math.MaxUint64, Below
- }
-
- panic("unreachable")
-}
-
-// Int64 returns the integer resulting from truncating x towards zero.
-// If math.MinInt64 <= x <= math.MaxInt64, the result is Exact if x is
-// an integer, and Above (x < 0) or Below (x > 0) otherwise.
-// The result is (math.MinInt64, Above) for x < math.MinInt64,
-// and (math.MaxInt64, Below) for x > math.MaxInt64.
-func (x *Float) Int64() (int64, Accuracy) {
- if debugFloat {
- x.validate()
- }
-
- switch x.form {
- case finite:
- // 0 < |x| < +Inf
- acc := makeAcc(x.neg)
- if x.exp <= 0 {
- // 0 < |x| < 1
- return 0, acc
- }
- // x.exp > 0
-
- // 1 <= |x| < +Inf
- if x.exp <= 63 {
- // i = trunc(x) fits into an int64 (excluding math.MinInt64)
- i := int64(msb64(x.mant) >> (64 - uint32(x.exp)))
- if x.neg {
- i = -i
- }
- if x.MinPrec() <= uint(x.exp) {
- return i, Exact
- }
- return i, acc // x truncated
- }
- if x.neg {
- // check for special case x == math.MinInt64 (i.e., x == -(0.5 << 64))
- if x.exp == 64 && x.MinPrec() == 1 {
- acc = Exact
- }
- return math.MinInt64, acc
- }
- // x too large
- return math.MaxInt64, Below
-
- case zero:
- return 0, Exact
-
- case inf:
- if x.neg {
- return math.MinInt64, Above
- }
- return math.MaxInt64, Below
- }
-
- panic("unreachable")
-}
-
-// Float32 returns the float32 value nearest to x. If x is too small to be
-// represented by a float32 (|x| < math.SmallestNonzeroFloat32), the result
-// is (0, Below) or (-0, Above), respectively, depending on the sign of x.
-// If x is too large to be represented by a float32 (|x| > math.MaxFloat32),
-// the result is (+Inf, Above) or (-Inf, Below), depending on the sign of x.
-func (x *Float) Float32() (float32, Accuracy) {
- if debugFloat {
- x.validate()
- }
-
- switch x.form {
- case finite:
- // 0 < |x| < +Inf
-
- const (
- fbits = 32 // float size
- mbits = 23 // mantissa size (excluding implicit msb)
- ebits = fbits - mbits - 1 // 8 exponent size
- bias = 1<<(ebits-1) - 1 // 127 exponent bias
- dmin = 1 - bias - mbits // -149 smallest unbiased exponent (denormal)
- emin = 1 - bias // -126 smallest unbiased exponent (normal)
- emax = bias // 127 largest unbiased exponent (normal)
- )
-
- // Float mantissa m is 0.5 <= m < 1.0; compute exponent e for float32 mantissa.
- e := x.exp - 1 // exponent for normal mantissa m with 1.0 <= m < 2.0
-
- // Compute precision p for float32 mantissa.
- // If the exponent is too small, we have a denormal number before
- // rounding and fewer than p mantissa bits of precision available
- // (the exponent remains fixed but the mantissa gets shifted right).
- p := mbits + 1 // precision of normal float
- if e < emin {
- // recompute precision
- p = mbits + 1 - emin + int(e)
- // If p == 0, the mantissa of x is shifted so much to the right
- // that its msb falls immediately to the right of the float32
- // mantissa space. In other words, if the smallest denormal is
- // considered "1.0", for p == 0, the mantissa value m is >= 0.5.
- // If m > 0.5, it is rounded up to 1.0; i.e., the smallest denormal.
- // If m == 0.5, it is rounded down to even, i.e., 0.0.
- // If p < 0, the mantissa value m is <= "0.25" which is never rounded up.
- if p < 0 /* m <= 0.25 */ || p == 0 && x.mant.sticky(uint(len(x.mant))*_W-1) == 0 /* m == 0.5 */ {
- // underflow to ±0
- if x.neg {
- var z float32
- return -z, Above
- }
- return 0.0, Below
- }
- // otherwise, round up
- // We handle p == 0 explicitly because it's easy and because
- // Float.round doesn't support rounding to 0 bits of precision.
- if p == 0 {
- if x.neg {
- return -math.SmallestNonzeroFloat32, Below
- }
- return math.SmallestNonzeroFloat32, Above
- }
- }
- // p > 0
-
- // round
- var r Float
- r.prec = uint32(p)
- r.Set(x)
- e = r.exp - 1
-
- // Rounding may have caused r to overflow to ±Inf
- // (rounding never causes underflows to 0).
- // If the exponent is too large, also overflow to ±Inf.
- if r.form == inf || e > emax {
- // overflow
- if x.neg {
- return float32(math.Inf(-1)), Below
- }
- return float32(math.Inf(+1)), Above
- }
- // e <= emax
-
- // Determine sign, biased exponent, and mantissa.
- var sign, bexp, mant uint32
- if x.neg {
- sign = 1 << (fbits - 1)
- }
-
- // Rounding may have caused a denormal number to
- // become normal. Check again.
- if e < emin {
- // denormal number: recompute precision
- // Since rounding may have at best increased precision
- // and we have eliminated p <= 0 early, we know p > 0.
- // bexp == 0 for denormals
- p = mbits + 1 - emin + int(e)
- mant = msb32(r.mant) >> uint(fbits-p)
- } else {
- // normal number: emin <= e <= emax
- bexp = uint32(e+bias) << mbits
- mant = msb32(r.mant) >> ebits & (1<<mbits - 1) // cut off msb (implicit 1 bit)
- }
-
- return math.Float32frombits(sign | bexp | mant), r.acc
-
- case zero:
- if x.neg {
- var z float32
- return -z, Exact
- }
- return 0.0, Exact
-
- case inf:
- if x.neg {
- return float32(math.Inf(-1)), Exact
- }
- return float32(math.Inf(+1)), Exact
- }
-
- panic("unreachable")
-}
-
-// Float64 returns the float64 value nearest to x. If x is too small to be
-// represented by a float64 (|x| < math.SmallestNonzeroFloat64), the result
-// is (0, Below) or (-0, Above), respectively, depending on the sign of x.
-// If x is too large to be represented by a float64 (|x| > math.MaxFloat64),
-// the result is (+Inf, Above) or (-Inf, Below), depending on the sign of x.
-func (x *Float) Float64() (float64, Accuracy) {
- if debugFloat {
- x.validate()
- }
-
- switch x.form {
- case finite:
- // 0 < |x| < +Inf
-
- const (
- fbits = 64 // float size
- mbits = 52 // mantissa size (excluding implicit msb)
- ebits = fbits - mbits - 1 // 11 exponent size
- bias = 1<<(ebits-1) - 1 // 1023 exponent bias
- dmin = 1 - bias - mbits // -1074 smallest unbiased exponent (denormal)
- emin = 1 - bias // -1022 smallest unbiased exponent (normal)
- emax = bias // 1023 largest unbiased exponent (normal)
- )
-
- // Float mantissa m is 0.5 <= m < 1.0; compute exponent e for float64 mantissa.
- e := x.exp - 1 // exponent for normal mantissa m with 1.0 <= m < 2.0
-
- // Compute precision p for float64 mantissa.
- // If the exponent is too small, we have a denormal number before
- // rounding and fewer than p mantissa bits of precision available
- // (the exponent remains fixed but the mantissa gets shifted right).
- p := mbits + 1 // precision of normal float
- if e < emin {
- // recompute precision
- p = mbits + 1 - emin + int(e)
- // If p == 0, the mantissa of x is shifted so much to the right
- // that its msb falls immediately to the right of the float64
- // mantissa space. In other words, if the smallest denormal is
- // considered "1.0", for p == 0, the mantissa value m is >= 0.5.
- // If m > 0.5, it is rounded up to 1.0; i.e., the smallest denormal.
- // If m == 0.5, it is rounded down to even, i.e., 0.0.
- // If p < 0, the mantissa value m is <= "0.25" which is never rounded up.
- if p < 0 /* m <= 0.25 */ || p == 0 && x.mant.sticky(uint(len(x.mant))*_W-1) == 0 /* m == 0.5 */ {
- // underflow to ±0
- if x.neg {
- var z float64
- return -z, Above
- }
- return 0.0, Below
- }
- // otherwise, round up
- // We handle p == 0 explicitly because it's easy and because
- // Float.round doesn't support rounding to 0 bits of precision.
- if p == 0 {
- if x.neg {
- return -math.SmallestNonzeroFloat64, Below
- }
- return math.SmallestNonzeroFloat64, Above
- }
- }
- // p > 0
-
- // round
- var r Float
- r.prec = uint32(p)
- r.Set(x)
- e = r.exp - 1
-
- // Rounding may have caused r to overflow to ±Inf
- // (rounding never causes underflows to 0).
- // If the exponent is too large, also overflow to ±Inf.
- if r.form == inf || e > emax {
- // overflow
- if x.neg {
- return math.Inf(-1), Below
- }
- return math.Inf(+1), Above
- }
- // e <= emax
-
- // Determine sign, biased exponent, and mantissa.
- var sign, bexp, mant uint64
- if x.neg {
- sign = 1 << (fbits - 1)
- }
-
- // Rounding may have caused a denormal number to
- // become normal. Check again.
- if e < emin {
- // denormal number: recompute precision
- // Since rounding may have at best increased precision
- // and we have eliminated p <= 0 early, we know p > 0.
- // bexp == 0 for denormals
- p = mbits + 1 - emin + int(e)
- mant = msb64(r.mant) >> uint(fbits-p)
- } else {
- // normal number: emin <= e <= emax
- bexp = uint64(e+bias) << mbits
- mant = msb64(r.mant) >> ebits & (1<<mbits - 1) // cut off msb (implicit 1 bit)
- }
-
- return math.Float64frombits(sign | bexp | mant), r.acc
-
- case zero:
- if x.neg {
- var z float64
- return -z, Exact
- }
- return 0.0, Exact
-
- case inf:
- if x.neg {
- return math.Inf(-1), Exact
- }
- return math.Inf(+1), Exact
- }
-
- panic("unreachable")
-}
-
-// Int returns the result of truncating x towards zero;
-// or nil if x is an infinity.
-// The result is Exact if x.IsInt(); otherwise it is Below
-// for x > 0, and Above for x < 0.
-// If a non-nil *Int argument z is provided, Int stores
-// the result in z instead of allocating a new Int.
-func (x *Float) Int(z *Int) (*Int, Accuracy) {
- if debugFloat {
- x.validate()
- }
-
- if z == nil && x.form <= finite {
- z = new(Int)
- }
-
- switch x.form {
- case finite:
- // 0 < |x| < +Inf
- acc := makeAcc(x.neg)
- if x.exp <= 0 {
- // 0 < |x| < 1
- return z.SetInt64(0), acc
- }
- // x.exp > 0
-
- // 1 <= |x| < +Inf
- // determine minimum required precision for x
- allBits := uint(len(x.mant)) * _W
- exp := uint(x.exp)
- if x.MinPrec() <= exp {
- acc = Exact
- }
- // shift mantissa as needed
- if z == nil {
- z = new(Int)
- }
- z.neg = x.neg
- switch {
- case exp > allBits:
- z.abs = z.abs.shl(x.mant, exp-allBits)
- default:
- z.abs = z.abs.set(x.mant)
- case exp < allBits:
- z.abs = z.abs.shr(x.mant, allBits-exp)
- }
- return z, acc
-
- case zero:
- return z.SetInt64(0), Exact
-
- case inf:
- return nil, makeAcc(x.neg)
- }
-
- panic("unreachable")
-}
-
-// Rat returns the rational number corresponding to x;
-// or nil if x is an infinity.
-// The result is Exact if x is not an Inf.
-// If a non-nil *Rat argument z is provided, Rat stores
-// the result in z instead of allocating a new Rat.
-func (x *Float) Rat(z *Rat) (*Rat, Accuracy) {
- if debugFloat {
- x.validate()
- }
-
- if z == nil && x.form <= finite {
- z = new(Rat)
- }
-
- switch x.form {
- case finite:
- // 0 < |x| < +Inf
- allBits := int32(len(x.mant)) * _W
- // build up numerator and denominator
- z.a.neg = x.neg
- switch {
- case x.exp > allBits:
- z.a.abs = z.a.abs.shl(x.mant, uint(x.exp-allBits))
- z.b.abs = z.b.abs[:0] // == 1 (see Rat)
- // z already in normal form
- default:
- z.a.abs = z.a.abs.set(x.mant)
- z.b.abs = z.b.abs[:0] // == 1 (see Rat)
- // z already in normal form
- case x.exp < allBits:
- z.a.abs = z.a.abs.set(x.mant)
- t := z.b.abs.setUint64(1)
- z.b.abs = t.shl(t, uint(allBits-x.exp))
- z.norm()
- }
- return z, Exact
-
- case zero:
- return z.SetInt64(0), Exact
-
- case inf:
- return nil, makeAcc(x.neg)
- }
-
- panic("unreachable")
-}
-
-// Abs sets z to the (possibly rounded) value |x| (the absolute value of x)
-// and returns z.
-func (z *Float) Abs(x *Float) *Float {
- z.Set(x)
- z.neg = false
- return z
-}
-
-// Neg sets z to the (possibly rounded) value of x with its sign negated,
-// and returns z.
-func (z *Float) Neg(x *Float) *Float {
- z.Set(x)
- z.neg = !z.neg
- return z
-}
-
-func validateBinaryOperands(x, y *Float) {
- if !debugFloat {
- // avoid performance bugs
- panic("validateBinaryOperands called but debugFloat is not set")
- }
- if len(x.mant) == 0 {
- panic("empty mantissa for x")
- }
- if len(y.mant) == 0 {
- panic("empty mantissa for y")
- }
-}
-
-// z = x + y, ignoring signs of x and y for the addition
-// but using the sign of z for rounding the result.
-// x and y must have a non-empty mantissa and valid exponent.
-func (z *Float) uadd(x, y *Float) {
- // Note: This implementation requires 2 shifts most of the
- // time. It is also inefficient if exponents or precisions
- // differ by wide margins. The following article describes
- // an efficient (but much more complicated) implementation
- // compatible with the internal representation used here:
- //
- // Vincent Lefèvre: "The Generic Multiple-Precision Floating-
- // Point Addition With Exact Rounding (as in the MPFR Library)"
- // http://www.vinc17.net/research/papers/rnc6.pdf
-
- if debugFloat {
- validateBinaryOperands(x, y)
- }
-
- // compute exponents ex, ey for mantissa with "binary point"
- // on the right (mantissa.0) - use int64 to avoid overflow
- ex := int64(x.exp) - int64(len(x.mant))*_W
- ey := int64(y.exp) - int64(len(y.mant))*_W
-
- al := alias(z.mant, x.mant) || alias(z.mant, y.mant)
-
- // TODO(gri) having a combined add-and-shift primitive
- // could make this code significantly faster
- switch {
- case ex < ey:
- if al {
- t := nat(nil).shl(y.mant, uint(ey-ex))
- z.mant = z.mant.add(x.mant, t)
- } else {
- z.mant = z.mant.shl(y.mant, uint(ey-ex))
- z.mant = z.mant.add(x.mant, z.mant)
- }
- default:
- // ex == ey, no shift needed
- z.mant = z.mant.add(x.mant, y.mant)
- case ex > ey:
- if al {
- t := nat(nil).shl(x.mant, uint(ex-ey))
- z.mant = z.mant.add(t, y.mant)
- } else {
- z.mant = z.mant.shl(x.mant, uint(ex-ey))
- z.mant = z.mant.add(z.mant, y.mant)
- }
- ex = ey
- }
- // len(z.mant) > 0
-
- z.setExpAndRound(ex+int64(len(z.mant))*_W-fnorm(z.mant), 0)
-}
-
-// z = x - y for |x| > |y|, ignoring signs of x and y for the subtraction
-// but using the sign of z for rounding the result.
-// x and y must have a non-empty mantissa and valid exponent.
-func (z *Float) usub(x, y *Float) {
- // This code is symmetric to uadd.
- // We have not factored the common code out because
- // eventually uadd (and usub) should be optimized
- // by special-casing, and the code will diverge.
-
- if debugFloat {
- validateBinaryOperands(x, y)
- }
-
- ex := int64(x.exp) - int64(len(x.mant))*_W
- ey := int64(y.exp) - int64(len(y.mant))*_W
-
- al := alias(z.mant, x.mant) || alias(z.mant, y.mant)
-
- switch {
- case ex < ey:
- if al {
- t := nat(nil).shl(y.mant, uint(ey-ex))
- z.mant = t.sub(x.mant, t)
- } else {
- z.mant = z.mant.shl(y.mant, uint(ey-ex))
- z.mant = z.mant.sub(x.mant, z.mant)
- }
- default:
- // ex == ey, no shift needed
- z.mant = z.mant.sub(x.mant, y.mant)
- case ex > ey:
- if al {
- t := nat(nil).shl(x.mant, uint(ex-ey))
- z.mant = t.sub(t, y.mant)
- } else {
- z.mant = z.mant.shl(x.mant, uint(ex-ey))
- z.mant = z.mant.sub(z.mant, y.mant)
- }
- ex = ey
- }
-
- // operands may have canceled each other out
- if len(z.mant) == 0 {
- z.acc = Exact
- z.form = zero
- z.neg = false
- return
- }
- // len(z.mant) > 0
-
- z.setExpAndRound(ex+int64(len(z.mant))*_W-fnorm(z.mant), 0)
-}
-
-// z = x * y, ignoring signs of x and y for the multiplication
-// but using the sign of z for rounding the result.
-// x and y must have a non-empty mantissa and valid exponent.
-func (z *Float) umul(x, y *Float) {
- if debugFloat {
- validateBinaryOperands(x, y)
- }
-
- // Note: This is doing too much work if the precision
- // of z is less than the sum of the precisions of x
- // and y which is often the case (e.g., if all floats
- // have the same precision).
- // TODO(gri) Optimize this for the common case.
-
- e := int64(x.exp) + int64(y.exp)
- if x == y {
- z.mant = z.mant.sqr(x.mant)
- } else {
- z.mant = z.mant.mul(x.mant, y.mant)
- }
- z.setExpAndRound(e-fnorm(z.mant), 0)
-}
-
-// z = x / y, ignoring signs of x and y for the division
-// but using the sign of z for rounding the result.
-// x and y must have a non-empty mantissa and valid exponent.
-func (z *Float) uquo(x, y *Float) {
- if debugFloat {
- validateBinaryOperands(x, y)
- }
-
- // mantissa length in words for desired result precision + 1
- // (at least one extra bit so we get the rounding bit after
- // the division)
- n := int(z.prec/_W) + 1
-
- // compute adjusted x.mant such that we get enough result precision
- xadj := x.mant
- if d := n - len(x.mant) + len(y.mant); d > 0 {
- // d extra words needed => add d "0 digits" to x
- xadj = make(nat, len(x.mant)+d)
- copy(xadj[d:], x.mant)
- }
- // TODO(gri): If we have too many digits (d < 0), we should be able
- // to shorten x for faster division. But we must be extra careful
- // with rounding in that case.
-
- // Compute d before division since there may be aliasing of x.mant
- // (via xadj) or y.mant with z.mant.
- d := len(xadj) - len(y.mant)
-
- // divide
- var r nat
- z.mant, r = z.mant.div(nil, xadj, y.mant)
- e := int64(x.exp) - int64(y.exp) - int64(d-len(z.mant))*_W
-
- // The result is long enough to include (at least) the rounding bit.
- // If there's a non-zero remainder, the corresponding fractional part
- // (if it were computed), would have a non-zero sticky bit (if it were
- // zero, it couldn't have a non-zero remainder).
- var sbit uint
- if len(r) > 0 {
- sbit = 1
- }
-
- z.setExpAndRound(e-fnorm(z.mant), sbit)
-}
-
-// ucmp returns -1, 0, or +1, depending on whether
-// |x| < |y|, |x| == |y|, or |x| > |y|.
-// x and y must have a non-empty mantissa and valid exponent.
-func (x *Float) ucmp(y *Float) int {
- if debugFloat {
- validateBinaryOperands(x, y)
- }
-
- switch {
- case x.exp < y.exp:
- return -1
- case x.exp > y.exp:
- return +1
- }
- // x.exp == y.exp
-
- // compare mantissas
- i := len(x.mant)
- j := len(y.mant)
- for i > 0 || j > 0 {
- var xm, ym Word
- if i > 0 {
- i--
- xm = x.mant[i]
- }
- if j > 0 {
- j--
- ym = y.mant[j]
- }
- switch {
- case xm < ym:
- return -1
- case xm > ym:
- return +1
- }
- }
-
- return 0
-}
-
-// Handling of sign bit as defined by IEEE 754-2008, section 6.3:
-//
-// When neither the inputs nor result are NaN, the sign of a product or
-// quotient is the exclusive OR of the operands’ signs; the sign of a sum,
-// or of a difference x−y regarded as a sum x+(−y), differs from at most
-// one of the addends’ signs; and the sign of the result of conversions,
-// the quantize operation, the roundToIntegral operations, and the
-// roundToIntegralExact (see 5.3.1) is the sign of the first or only operand.
-// These rules shall apply even when operands or results are zero or infinite.
-//
-// When the sum of two operands with opposite signs (or the difference of
-// two operands with like signs) is exactly zero, the sign of that sum (or
-// difference) shall be +0 in all rounding-direction attributes except
-// roundTowardNegative; under that attribute, the sign of an exact zero
-// sum (or difference) shall be −0. However, x+x = x−(−x) retains the same
-// sign as x even when x is zero.
-//
-// See also: https://play.golang.org/p/RtH3UCt5IH
-
-// Add sets z to the rounded sum x+y and returns z. If z's precision is 0,
-// it is changed to the larger of x's or y's precision before the operation.
-// Rounding is performed according to z's precision and rounding mode; and
-// z's accuracy reports the result error relative to the exact (not rounded)
-// result. Add panics with ErrNaN if x and y are infinities with opposite
-// signs. The value of z is undefined in that case.
-func (z *Float) Add(x, y *Float) *Float {
- if debugFloat {
- x.validate()
- y.validate()
- }
-
- if z.prec == 0 {
- z.prec = umax32(x.prec, y.prec)
- }
-
- if x.form == finite && y.form == finite {
- // x + y (common case)
-
- // Below we set z.neg = x.neg, and when z aliases y this will
- // change the y operand's sign. This is fine, because if an
- // operand aliases the receiver it'll be overwritten, but we still
- // want the original x.neg and y.neg values when we evaluate
- // x.neg != y.neg, so we need to save y.neg before setting z.neg.
- yneg := y.neg
-
- z.neg = x.neg
- if x.neg == yneg {
- // x + y == x + y
- // (-x) + (-y) == -(x + y)
- z.uadd(x, y)
- } else {
- // x + (-y) == x - y == -(y - x)
- // (-x) + y == y - x == -(x - y)
- if x.ucmp(y) > 0 {
- z.usub(x, y)
- } else {
- z.neg = !z.neg
- z.usub(y, x)
- }
- }
- if z.form == zero && z.mode == ToNegativeInf && z.acc == Exact {
- z.neg = true
- }
- return z
- }
-
- if x.form == inf && y.form == inf && x.neg != y.neg {
- // +Inf + -Inf
- // -Inf + +Inf
- // value of z is undefined but make sure it's valid
- z.acc = Exact
- z.form = zero
- z.neg = false
- panic(ErrNaN{"addition of infinities with opposite signs"})
- }
-
- if x.form == zero && y.form == zero {
- // ±0 + ±0
- z.acc = Exact
- z.form = zero
- z.neg = x.neg && y.neg // -0 + -0 == -0
- return z
- }
-
- if x.form == inf || y.form == zero {
- // ±Inf + y
- // x + ±0
- return z.Set(x)
- }
-
- // ±0 + y
- // x + ±Inf
- return z.Set(y)
-}
-
-// Sub sets z to the rounded difference x-y and returns z.
-// Precision, rounding, and accuracy reporting are as for Add.
-// Sub panics with ErrNaN if x and y are infinities with equal
-// signs. The value of z is undefined in that case.
-func (z *Float) Sub(x, y *Float) *Float {
- if debugFloat {
- x.validate()
- y.validate()
- }
-
- if z.prec == 0 {
- z.prec = umax32(x.prec, y.prec)
- }
-
- if x.form == finite && y.form == finite {
- // x - y (common case)
- yneg := y.neg
- z.neg = x.neg
- if x.neg != yneg {
- // x - (-y) == x + y
- // (-x) - y == -(x + y)
- z.uadd(x, y)
- } else {
- // x - y == x - y == -(y - x)
- // (-x) - (-y) == y - x == -(x - y)
- if x.ucmp(y) > 0 {
- z.usub(x, y)
- } else {
- z.neg = !z.neg
- z.usub(y, x)
- }
- }
- if z.form == zero && z.mode == ToNegativeInf && z.acc == Exact {
- z.neg = true
- }
- return z
- }
-
- if x.form == inf && y.form == inf && x.neg == y.neg {
- // +Inf - +Inf
- // -Inf - -Inf
- // value of z is undefined but make sure it's valid
- z.acc = Exact
- z.form = zero
- z.neg = false
- panic(ErrNaN{"subtraction of infinities with equal signs"})
- }
-
- if x.form == zero && y.form == zero {
- // ±0 - ±0
- z.acc = Exact
- z.form = zero
- z.neg = x.neg && !y.neg // -0 - +0 == -0
- return z
- }
-
- if x.form == inf || y.form == zero {
- // ±Inf - y
- // x - ±0
- return z.Set(x)
- }
-
- // ±0 - y
- // x - ±Inf
- return z.Neg(y)
-}
-
-// Mul sets z to the rounded product x*y and returns z.
-// Precision, rounding, and accuracy reporting are as for Add.
-// Mul panics with ErrNaN if one operand is zero and the other
-// operand an infinity. The value of z is undefined in that case.
-func (z *Float) Mul(x, y *Float) *Float {
- if debugFloat {
- x.validate()
- y.validate()
- }
-
- if z.prec == 0 {
- z.prec = umax32(x.prec, y.prec)
- }
-
- z.neg = x.neg != y.neg
-
- if x.form == finite && y.form == finite {
- // x * y (common case)
- z.umul(x, y)
- return z
- }
-
- z.acc = Exact
- if x.form == zero && y.form == inf || x.form == inf && y.form == zero {
- // ±0 * ±Inf
- // ±Inf * ±0
- // value of z is undefined but make sure it's valid
- z.form = zero
- z.neg = false
- panic(ErrNaN{"multiplication of zero with infinity"})
- }
-
- if x.form == inf || y.form == inf {
- // ±Inf * y
- // x * ±Inf
- z.form = inf
- return z
- }
-
- // ±0 * y
- // x * ±0
- z.form = zero
- return z
-}
-
-// Quo sets z to the rounded quotient x/y and returns z.
-// Precision, rounding, and accuracy reporting are as for Add.
-// Quo panics with ErrNaN if both operands are zero or infinities.
-// The value of z is undefined in that case.
-func (z *Float) Quo(x, y *Float) *Float {
- if debugFloat {
- x.validate()
- y.validate()
- }
-
- if z.prec == 0 {
- z.prec = umax32(x.prec, y.prec)
- }
-
- z.neg = x.neg != y.neg
-
- if x.form == finite && y.form == finite {
- // x / y (common case)
- z.uquo(x, y)
- return z
- }
-
- z.acc = Exact
- if x.form == zero && y.form == zero || x.form == inf && y.form == inf {
- // ±0 / ±0
- // ±Inf / ±Inf
- // value of z is undefined but make sure it's valid
- z.form = zero
- z.neg = false
- panic(ErrNaN{"division of zero by zero or infinity by infinity"})
- }
-
- if x.form == zero || y.form == inf {
- // ±0 / y
- // x / ±Inf
- z.form = zero
- return z
- }
-
- // x / ±0
- // ±Inf / y
- z.form = inf
- return z
-}
-
-// Cmp compares x and y and returns:
-//
-// -1 if x < y
-// 0 if x == y (incl. -0 == 0, -Inf == -Inf, and +Inf == +Inf)
-// +1 if x > y
-func (x *Float) Cmp(y *Float) int {
- if debugFloat {
- x.validate()
- y.validate()
- }
-
- mx := x.ord()
- my := y.ord()
- switch {
- case mx < my:
- return -1
- case mx > my:
- return +1
- }
- // mx == my
-
- // only if |mx| == 1 we have to compare the mantissae
- switch mx {
- case -1:
- return y.ucmp(x)
- case +1:
- return x.ucmp(y)
- }
-
- return 0
-}
-
-// ord classifies x and returns:
-//
-// -2 if -Inf == x
-// -1 if -Inf < x < 0
-// 0 if x == 0 (signed or unsigned)
-// +1 if 0 < x < +Inf
-// +2 if x == +Inf
-func (x *Float) ord() int {
- var m int
- switch x.form {
- case finite:
- m = 1
- case zero:
- return 0
- case inf:
- m = 2
- }
- if x.neg {
- m = -m
- }
- return m
-}
-
-func umax32(x, y uint32) uint32 {
- if x > y {
- return x
- }
- return y
-}
diff --git a/contrib/go/_std_1.20/src/math/big/floatconv.go b/contrib/go/_std_1.20/src/math/big/floatconv.go
deleted file mode 100644
index 3bb51c7dea..0000000000
--- a/contrib/go/_std_1.20/src/math/big/floatconv.go
+++ /dev/null
@@ -1,302 +0,0 @@
-// Copyright 2015 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.
-
-// This file implements string-to-Float conversion functions.
-
-package big
-
-import (
- "fmt"
- "io"
- "strings"
-)
-
-var floatZero Float
-
-// SetString sets z to the value of s and returns z and a boolean indicating
-// success. s must be a floating-point number of the same format as accepted
-// by Parse, with base argument 0. The entire string (not just a prefix) must
-// be valid for success. If the operation failed, the value of z is undefined
-// but the returned value is nil.
-func (z *Float) SetString(s string) (*Float, bool) {
- if f, _, err := z.Parse(s, 0); err == nil {
- return f, true
- }
- return nil, false
-}
-
-// scan is like Parse but reads the longest possible prefix representing a valid
-// floating point number from an io.ByteScanner rather than a string. It serves
-// as the implementation of Parse. It does not recognize ±Inf and does not expect
-// EOF at the end.
-func (z *Float) scan(r io.ByteScanner, base int) (f *Float, b int, err error) {
- prec := z.prec
- if prec == 0 {
- prec = 64
- }
-
- // A reasonable value in case of an error.
- z.form = zero
-
- // sign
- z.neg, err = scanSign(r)
- if err != nil {
- return
- }
-
- // mantissa
- var fcount int // fractional digit count; valid if <= 0
- z.mant, b, fcount, err = z.mant.scan(r, base, true)
- if err != nil {
- return
- }
-
- // exponent
- var exp int64
- var ebase int
- exp, ebase, err = scanExponent(r, true, base == 0)
- if err != nil {
- return
- }
-
- // special-case 0
- if len(z.mant) == 0 {
- z.prec = prec
- z.acc = Exact
- z.form = zero
- f = z
- return
- }
- // len(z.mant) > 0
-
- // The mantissa may have a radix point (fcount <= 0) and there
- // may be a nonzero exponent exp. The radix point amounts to a
- // division by b**(-fcount). An exponent means multiplication by
- // ebase**exp. Finally, mantissa normalization (shift left) requires
- // a correcting multiplication by 2**(-shiftcount). Multiplications
- // are commutative, so we can apply them in any order as long as there
- // is no loss of precision. We only have powers of 2 and 10, and
- // we split powers of 10 into the product of the same powers of
- // 2 and 5. This reduces the size of the multiplication factor
- // needed for base-10 exponents.
-
- // normalize mantissa and determine initial exponent contributions
- exp2 := int64(len(z.mant))*_W - fnorm(z.mant)
- exp5 := int64(0)
-
- // determine binary or decimal exponent contribution of radix point
- if fcount < 0 {
- // The mantissa has a radix point ddd.dddd; and
- // -fcount is the number of digits to the right
- // of '.'. Adjust relevant exponent accordingly.
- d := int64(fcount)
- switch b {
- case 10:
- exp5 = d
- fallthrough // 10**e == 5**e * 2**e
- case 2:
- exp2 += d
- case 8:
- exp2 += d * 3 // octal digits are 3 bits each
- case 16:
- exp2 += d * 4 // hexadecimal digits are 4 bits each
- default:
- panic("unexpected mantissa base")
- }
- // fcount consumed - not needed anymore
- }
-
- // take actual exponent into account
- switch ebase {
- case 10:
- exp5 += exp
- fallthrough // see fallthrough above
- case 2:
- exp2 += exp
- default:
- panic("unexpected exponent base")
- }
- // exp consumed - not needed anymore
-
- // apply 2**exp2
- if MinExp <= exp2 && exp2 <= MaxExp {
- z.prec = prec
- z.form = finite
- z.exp = int32(exp2)
- f = z
- } else {
- err = fmt.Errorf("exponent overflow")
- return
- }
-
- if exp5 == 0 {
- // no decimal exponent contribution
- z.round(0)
- return
- }
- // exp5 != 0
-
- // apply 5**exp5
- p := new(Float).SetPrec(z.Prec() + 64) // use more bits for p -- TODO(gri) what is the right number?
- if exp5 < 0 {
- z.Quo(z, p.pow5(uint64(-exp5)))
- } else {
- z.Mul(z, p.pow5(uint64(exp5)))
- }
-
- return
-}
-
-// These powers of 5 fit into a uint64.
-//
-// for p, q := uint64(0), uint64(1); p < q; p, q = q, q*5 {
-// fmt.Println(q)
-// }
-var pow5tab = [...]uint64{
- 1,
- 5,
- 25,
- 125,
- 625,
- 3125,
- 15625,
- 78125,
- 390625,
- 1953125,
- 9765625,
- 48828125,
- 244140625,
- 1220703125,
- 6103515625,
- 30517578125,
- 152587890625,
- 762939453125,
- 3814697265625,
- 19073486328125,
- 95367431640625,
- 476837158203125,
- 2384185791015625,
- 11920928955078125,
- 59604644775390625,
- 298023223876953125,
- 1490116119384765625,
- 7450580596923828125,
-}
-
-// pow5 sets z to 5**n and returns z.
-// n must not be negative.
-func (z *Float) pow5(n uint64) *Float {
- const m = uint64(len(pow5tab) - 1)
- if n <= m {
- return z.SetUint64(pow5tab[n])
- }
- // n > m
-
- z.SetUint64(pow5tab[m])
- n -= m
-
- // use more bits for f than for z
- // TODO(gri) what is the right number?
- f := new(Float).SetPrec(z.Prec() + 64).SetUint64(5)
-
- for n > 0 {
- if n&1 != 0 {
- z.Mul(z, f)
- }
- f.Mul(f, f)
- n >>= 1
- }
-
- return z
-}
-
-// Parse parses s which must contain a text representation of a floating-
-// point number with a mantissa in the given conversion base (the exponent
-// is always a decimal number), or a string representing an infinite value.
-//
-// For base 0, an underscore character “_” may appear between a base
-// prefix and an adjacent digit, and between successive digits; such
-// underscores do not change the value of the number, or the returned
-// digit count. Incorrect placement of underscores is reported as an
-// error if there are no other errors. If base != 0, underscores are
-// not recognized and thus terminate scanning like any other character
-// that is not a valid radix point or digit.
-//
-// It sets z to the (possibly rounded) value of the corresponding floating-
-// point value, and returns z, the actual base b, and an error err, if any.
-// The entire string (not just a prefix) must be consumed for success.
-// If z's precision is 0, it is changed to 64 before rounding takes effect.
-// The number must be of the form:
-//
-// number = [ sign ] ( float | "inf" | "Inf" ) .
-// sign = "+" | "-" .
-// float = ( mantissa | prefix pmantissa ) [ exponent ] .
-// prefix = "0" [ "b" | "B" | "o" | "O" | "x" | "X" ] .
-// mantissa = digits "." [ digits ] | digits | "." digits .
-// pmantissa = [ "_" ] digits "." [ digits ] | [ "_" ] digits | "." digits .
-// exponent = ( "e" | "E" | "p" | "P" ) [ sign ] digits .
-// digits = digit { [ "_" ] digit } .
-// digit = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
-//
-// The base argument must be 0, 2, 8, 10, or 16. Providing an invalid base
-// argument will lead to a run-time panic.
-//
-// For base 0, the number prefix determines the actual base: A prefix of
-// “0b” or “0B” selects base 2, “0o” or “0O” selects base 8, and
-// “0x” or “0X” selects base 16. Otherwise, the actual base is 10 and
-// no prefix is accepted. The octal prefix "0" is not supported (a leading
-// "0" is simply considered a "0").
-//
-// A "p" or "P" exponent indicates a base 2 (rather then base 10) exponent;
-// for instance, "0x1.fffffffffffffp1023" (using base 0) represents the
-// maximum float64 value. For hexadecimal mantissae, the exponent character
-// must be one of 'p' or 'P', if present (an "e" or "E" exponent indicator
-// cannot be distinguished from a mantissa digit).
-//
-// The returned *Float f is nil and the value of z is valid but not
-// defined if an error is reported.
-func (z *Float) Parse(s string, base int) (f *Float, b int, err error) {
- // scan doesn't handle ±Inf
- if len(s) == 3 && (s == "Inf" || s == "inf") {
- f = z.SetInf(false)
- return
- }
- if len(s) == 4 && (s[0] == '+' || s[0] == '-') && (s[1:] == "Inf" || s[1:] == "inf") {
- f = z.SetInf(s[0] == '-')
- return
- }
-
- r := strings.NewReader(s)
- if f, b, err = z.scan(r, base); err != nil {
- return
- }
-
- // entire string must have been consumed
- if ch, err2 := r.ReadByte(); err2 == nil {
- err = fmt.Errorf("expected end of string, found %q", ch)
- } else if err2 != io.EOF {
- err = err2
- }
-
- return
-}
-
-// ParseFloat is like f.Parse(s, base) with f set to the given precision
-// and rounding mode.
-func ParseFloat(s string, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) {
- return new(Float).SetPrec(prec).SetMode(mode).Parse(s, base)
-}
-
-var _ fmt.Scanner = (*Float)(nil) // *Float must implement fmt.Scanner
-
-// Scan is a support routine for fmt.Scanner; it sets z to the value of
-// the scanned number. It accepts formats whose verbs are supported by
-// fmt.Scan for floating point values, which are:
-// 'b' (binary), 'e', 'E', 'f', 'F', 'g' and 'G'.
-// Scan doesn't handle ±Inf.
-func (z *Float) Scan(s fmt.ScanState, ch rune) error {
- s.SkipSpace()
- _, _, err := z.scan(byteReader{s}, 0)
- return err
-}
diff --git a/contrib/go/_std_1.20/src/math/big/floatmarsh.go b/contrib/go/_std_1.20/src/math/big/floatmarsh.go
deleted file mode 100644
index 990e085abe..0000000000
--- a/contrib/go/_std_1.20/src/math/big/floatmarsh.go
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2015 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.
-
-// This file implements encoding/decoding of Floats.
-
-package big
-
-import (
- "encoding/binary"
- "errors"
- "fmt"
-)
-
-// Gob codec version. Permits backward-compatible changes to the encoding.
-const floatGobVersion byte = 1
-
-// GobEncode implements the gob.GobEncoder interface.
-// The Float value and all its attributes (precision,
-// rounding mode, accuracy) are marshaled.
-func (x *Float) GobEncode() ([]byte, error) {
- if x == nil {
- return nil, nil
- }
-
- // determine max. space (bytes) required for encoding
- sz := 1 + 1 + 4 // version + mode|acc|form|neg (3+2+2+1bit) + prec
- n := 0 // number of mantissa words
- if x.form == finite {
- // add space for mantissa and exponent
- n = int((x.prec + (_W - 1)) / _W) // required mantissa length in words for given precision
- // actual mantissa slice could be shorter (trailing 0's) or longer (unused bits):
- // - if shorter, only encode the words present
- // - if longer, cut off unused words when encoding in bytes
- // (in practice, this should never happen since rounding
- // takes care of it, but be safe and do it always)
- if len(x.mant) < n {
- n = len(x.mant)
- }
- // len(x.mant) >= n
- sz += 4 + n*_S // exp + mant
- }
- buf := make([]byte, sz)
-
- buf[0] = floatGobVersion
- b := byte(x.mode&7)<<5 | byte((x.acc+1)&3)<<3 | byte(x.form&3)<<1
- if x.neg {
- b |= 1
- }
- buf[1] = b
- binary.BigEndian.PutUint32(buf[2:], x.prec)
-
- if x.form == finite {
- binary.BigEndian.PutUint32(buf[6:], uint32(x.exp))
- x.mant[len(x.mant)-n:].bytes(buf[10:]) // cut off unused trailing words
- }
-
- return buf, nil
-}
-
-// GobDecode implements the gob.GobDecoder interface.
-// The result is rounded per the precision and rounding mode of
-// z unless z's precision is 0, in which case z is set exactly
-// to the decoded value.
-func (z *Float) GobDecode(buf []byte) error {
- if len(buf) == 0 {
- // Other side sent a nil or default value.
- *z = Float{}
- return nil
- }
- if len(buf) < 6 {
- return errors.New("Float.GobDecode: buffer too small")
- }
-
- if buf[0] != floatGobVersion {
- return fmt.Errorf("Float.GobDecode: encoding version %d not supported", buf[0])
- }
-
- oldPrec := z.prec
- oldMode := z.mode
-
- b := buf[1]
- z.mode = RoundingMode((b >> 5) & 7)
- z.acc = Accuracy((b>>3)&3) - 1
- z.form = form((b >> 1) & 3)
- z.neg = b&1 != 0
- z.prec = binary.BigEndian.Uint32(buf[2:])
-
- if z.form == finite {
- if len(buf) < 10 {
- return errors.New("Float.GobDecode: buffer too small for finite form float")
- }
- z.exp = int32(binary.BigEndian.Uint32(buf[6:]))
- z.mant = z.mant.setBytes(buf[10:])
- }
-
- if oldPrec != 0 {
- z.mode = oldMode
- z.SetPrec(uint(oldPrec))
- }
-
- return nil
-}
-
-// MarshalText implements the encoding.TextMarshaler interface.
-// Only the Float value is marshaled (in full precision), other
-// attributes such as precision or accuracy are ignored.
-func (x *Float) MarshalText() (text []byte, err error) {
- if x == nil {
- return []byte("<nil>"), nil
- }
- var buf []byte
- return x.Append(buf, 'g', -1), nil
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler interface.
-// The result is rounded per the precision and rounding mode of z.
-// If z's precision is 0, it is changed to 64 before rounding takes
-// effect.
-func (z *Float) UnmarshalText(text []byte) error {
- // TODO(gri): get rid of the []byte/string conversion
- _, _, err := z.Parse(string(text), 0)
- if err != nil {
- err = fmt.Errorf("math/big: cannot unmarshal %q into a *big.Float (%v)", text, err)
- }
- return err
-}
diff --git a/contrib/go/_std_1.20/src/math/big/int.go b/contrib/go/_std_1.20/src/math/big/int.go
deleted file mode 100644
index 76d6eb9cae..0000000000
--- a/contrib/go/_std_1.20/src/math/big/int.go
+++ /dev/null
@@ -1,1293 +0,0 @@
-// Copyright 2009 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.
-
-// This file implements signed multi-precision integers.
-
-package big
-
-import (
- "fmt"
- "io"
- "math/rand"
- "strings"
-)
-
-// An Int represents a signed multi-precision integer.
-// The zero value for an Int represents the value 0.
-//
-// Operations always take pointer arguments (*Int) rather
-// than Int values, and each unique Int value requires
-// its own unique *Int pointer. To "copy" an Int value,
-// an existing (or newly allocated) Int must be set to
-// a new value using the Int.Set method; shallow copies
-// of Ints are not supported and may lead to errors.
-type Int struct {
- neg bool // sign
- abs nat // absolute value of the integer
-}
-
-var intOne = &Int{false, natOne}
-
-// Sign returns:
-//
-// -1 if x < 0
-// 0 if x == 0
-// +1 if x > 0
-func (x *Int) Sign() int {
- // This function is used in cryptographic operations. It must not leak
- // anything but the Int's sign and bit size through side-channels. Any
- // changes must be reviewed by a security expert.
- if len(x.abs) == 0 {
- return 0
- }
- if x.neg {
- return -1
- }
- return 1
-}
-
-// SetInt64 sets z to x and returns z.
-func (z *Int) SetInt64(x int64) *Int {
- neg := false
- if x < 0 {
- neg = true
- x = -x
- }
- z.abs = z.abs.setUint64(uint64(x))
- z.neg = neg
- return z
-}
-
-// SetUint64 sets z to x and returns z.
-func (z *Int) SetUint64(x uint64) *Int {
- z.abs = z.abs.setUint64(x)
- z.neg = false
- return z
-}
-
-// NewInt allocates and returns a new Int set to x.
-func NewInt(x int64) *Int {
- // This code is arranged to be inlineable and produce
- // zero allocations when inlined. See issue 29951.
- u := uint64(x)
- if x < 0 {
- u = -u
- }
- var abs []Word
- if x == 0 {
- } else if _W == 32 && u>>32 != 0 {
- abs = []Word{Word(u), Word(u >> 32)}
- } else {
- abs = []Word{Word(u)}
- }
- return &Int{neg: x < 0, abs: abs}
-}
-
-// Set sets z to x and returns z.
-func (z *Int) Set(x *Int) *Int {
- if z != x {
- z.abs = z.abs.set(x.abs)
- z.neg = x.neg
- }
- return z
-}
-
-// Bits provides raw (unchecked but fast) access to x by returning its
-// absolute value as a little-endian Word slice. The result and x share
-// the same underlying array.
-// Bits is intended to support implementation of missing low-level Int
-// functionality outside this package; it should be avoided otherwise.
-func (x *Int) Bits() []Word {
- // This function is used in cryptographic operations. It must not leak
- // anything but the Int's sign and bit size through side-channels. Any
- // changes must be reviewed by a security expert.
- return x.abs
-}
-
-// SetBits provides raw (unchecked but fast) access to z by setting its
-// value to abs, interpreted as a little-endian Word slice, and returning
-// z. The result and abs share the same underlying array.
-// SetBits is intended to support implementation of missing low-level Int
-// functionality outside this package; it should be avoided otherwise.
-func (z *Int) SetBits(abs []Word) *Int {
- z.abs = nat(abs).norm()
- z.neg = false
- return z
-}
-
-// Abs sets z to |x| (the absolute value of x) and returns z.
-func (z *Int) Abs(x *Int) *Int {
- z.Set(x)
- z.neg = false
- return z
-}
-
-// Neg sets z to -x and returns z.
-func (z *Int) Neg(x *Int) *Int {
- z.Set(x)
- z.neg = len(z.abs) > 0 && !z.neg // 0 has no sign
- return z
-}
-
-// Add sets z to the sum x+y and returns z.
-func (z *Int) Add(x, y *Int) *Int {
- neg := x.neg
- if x.neg == y.neg {
- // x + y == x + y
- // (-x) + (-y) == -(x + y)
- z.abs = z.abs.add(x.abs, y.abs)
- } else {
- // x + (-y) == x - y == -(y - x)
- // (-x) + y == y - x == -(x - y)
- if x.abs.cmp(y.abs) >= 0 {
- z.abs = z.abs.sub(x.abs, y.abs)
- } else {
- neg = !neg
- z.abs = z.abs.sub(y.abs, x.abs)
- }
- }
- z.neg = len(z.abs) > 0 && neg // 0 has no sign
- return z
-}
-
-// Sub sets z to the difference x-y and returns z.
-func (z *Int) Sub(x, y *Int) *Int {
- neg := x.neg
- if x.neg != y.neg {
- // x - (-y) == x + y
- // (-x) - y == -(x + y)
- z.abs = z.abs.add(x.abs, y.abs)
- } else {
- // x - y == x - y == -(y - x)
- // (-x) - (-y) == y - x == -(x - y)
- if x.abs.cmp(y.abs) >= 0 {
- z.abs = z.abs.sub(x.abs, y.abs)
- } else {
- neg = !neg
- z.abs = z.abs.sub(y.abs, x.abs)
- }
- }
- z.neg = len(z.abs) > 0 && neg // 0 has no sign
- return z
-}
-
-// Mul sets z to the product x*y and returns z.
-func (z *Int) Mul(x, y *Int) *Int {
- // x * y == x * y
- // x * (-y) == -(x * y)
- // (-x) * y == -(x * y)
- // (-x) * (-y) == x * y
- if x == y {
- z.abs = z.abs.sqr(x.abs)
- z.neg = false
- return z
- }
- z.abs = z.abs.mul(x.abs, y.abs)
- z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
- return z
-}
-
-// MulRange sets z to the product of all integers
-// in the range [a, b] inclusively and returns z.
-// If a > b (empty range), the result is 1.
-func (z *Int) MulRange(a, b int64) *Int {
- switch {
- case a > b:
- return z.SetInt64(1) // empty range
- case a <= 0 && b >= 0:
- return z.SetInt64(0) // range includes 0
- }
- // a <= b && (b < 0 || a > 0)
-
- neg := false
- if a < 0 {
- neg = (b-a)&1 == 0
- a, b = -b, -a
- }
-
- z.abs = z.abs.mulRange(uint64(a), uint64(b))
- z.neg = neg
- return z
-}
-
-// Binomial sets z to the binomial coefficient C(n, k) and returns z.
-func (z *Int) Binomial(n, k int64) *Int {
- if k > n {
- return z.SetInt64(0)
- }
- // reduce the number of multiplications by reducing k
- if k > n-k {
- k = n - k // C(n, k) == C(n, n-k)
- }
- // C(n, k) == n * (n-1) * ... * (n-k+1) / k * (k-1) * ... * 1
- // == n * (n-1) * ... * (n-k+1) / 1 * (1+1) * ... * k
- //
- // Using the multiplicative formula produces smaller values
- // at each step, requiring fewer allocations and computations:
- //
- // z = 1
- // for i := 0; i < k; i = i+1 {
- // z *= n-i
- // z /= i+1
- // }
- //
- // finally to avoid computing i+1 twice per loop:
- //
- // z = 1
- // i := 0
- // for i < k {
- // z *= n-i
- // i++
- // z /= i
- // }
- var N, K, i, t Int
- N.SetInt64(n)
- K.SetInt64(k)
- z.Set(intOne)
- for i.Cmp(&K) < 0 {
- z.Mul(z, t.Sub(&N, &i))
- i.Add(&i, intOne)
- z.Quo(z, &i)
- }
- return z
-}
-
-// Quo sets z to the quotient x/y for y != 0 and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-// Quo implements truncated division (like Go); see QuoRem for more details.
-func (z *Int) Quo(x, y *Int) *Int {
- z.abs, _ = z.abs.div(nil, x.abs, y.abs)
- z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
- return z
-}
-
-// Rem sets z to the remainder x%y for y != 0 and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-// Rem implements truncated modulus (like Go); see QuoRem for more details.
-func (z *Int) Rem(x, y *Int) *Int {
- _, z.abs = nat(nil).div(z.abs, x.abs, y.abs)
- z.neg = len(z.abs) > 0 && x.neg // 0 has no sign
- return z
-}
-
-// QuoRem sets z to the quotient x/y and r to the remainder x%y
-// and returns the pair (z, r) for y != 0.
-// If y == 0, a division-by-zero run-time panic occurs.
-//
-// QuoRem implements T-division and modulus (like Go):
-//
-// q = x/y with the result truncated to zero
-// r = x - y*q
-//
-// (See Daan Leijen, “Division and Modulus for Computer Scientists”.)
-// See DivMod for Euclidean division and modulus (unlike Go).
-func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int) {
- z.abs, r.abs = z.abs.div(r.abs, x.abs, y.abs)
- z.neg, r.neg = len(z.abs) > 0 && x.neg != y.neg, len(r.abs) > 0 && x.neg // 0 has no sign
- return z, r
-}
-
-// Div sets z to the quotient x/y for y != 0 and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-// Div implements Euclidean division (unlike Go); see DivMod for more details.
-func (z *Int) Div(x, y *Int) *Int {
- y_neg := y.neg // z may be an alias for y
- var r Int
- z.QuoRem(x, y, &r)
- if r.neg {
- if y_neg {
- z.Add(z, intOne)
- } else {
- z.Sub(z, intOne)
- }
- }
- return z
-}
-
-// Mod sets z to the modulus x%y for y != 0 and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-// Mod implements Euclidean modulus (unlike Go); see DivMod for more details.
-func (z *Int) Mod(x, y *Int) *Int {
- y0 := y // save y
- if z == y || alias(z.abs, y.abs) {
- y0 = new(Int).Set(y)
- }
- var q Int
- q.QuoRem(x, y, z)
- if z.neg {
- if y0.neg {
- z.Sub(z, y0)
- } else {
- z.Add(z, y0)
- }
- }
- return z
-}
-
-// DivMod sets z to the quotient x div y and m to the modulus x mod y
-// and returns the pair (z, m) for y != 0.
-// If y == 0, a division-by-zero run-time panic occurs.
-//
-// DivMod implements Euclidean division and modulus (unlike Go):
-//
-// q = x div y such that
-// m = x - y*q with 0 <= m < |y|
-//
-// (See Raymond T. Boute, “The Euclidean definition of the functions
-// div and mod”. ACM Transactions on Programming Languages and
-// Systems (TOPLAS), 14(2):127-144, New York, NY, USA, 4/1992.
-// ACM press.)
-// See QuoRem for T-division and modulus (like Go).
-func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) {
- y0 := y // save y
- if z == y || alias(z.abs, y.abs) {
- y0 = new(Int).Set(y)
- }
- z.QuoRem(x, y, m)
- if m.neg {
- if y0.neg {
- z.Add(z, intOne)
- m.Sub(m, y0)
- } else {
- z.Sub(z, intOne)
- m.Add(m, y0)
- }
- }
- return z, m
-}
-
-// Cmp compares x and y and returns:
-//
-// -1 if x < y
-// 0 if x == y
-// +1 if x > y
-func (x *Int) Cmp(y *Int) (r int) {
- // x cmp y == x cmp y
- // x cmp (-y) == x
- // (-x) cmp y == y
- // (-x) cmp (-y) == -(x cmp y)
- switch {
- case x == y:
- // nothing to do
- case x.neg == y.neg:
- r = x.abs.cmp(y.abs)
- if x.neg {
- r = -r
- }
- case x.neg:
- r = -1
- default:
- r = 1
- }
- return
-}
-
-// CmpAbs compares the absolute values of x and y and returns:
-//
-// -1 if |x| < |y|
-// 0 if |x| == |y|
-// +1 if |x| > |y|
-func (x *Int) CmpAbs(y *Int) int {
- return x.abs.cmp(y.abs)
-}
-
-// low32 returns the least significant 32 bits of x.
-func low32(x nat) uint32 {
- if len(x) == 0 {
- return 0
- }
- return uint32(x[0])
-}
-
-// low64 returns the least significant 64 bits of x.
-func low64(x nat) uint64 {
- if len(x) == 0 {
- return 0
- }
- v := uint64(x[0])
- if _W == 32 && len(x) > 1 {
- return uint64(x[1])<<32 | v
- }
- return v
-}
-
-// Int64 returns the int64 representation of x.
-// If x cannot be represented in an int64, the result is undefined.
-func (x *Int) Int64() int64 {
- v := int64(low64(x.abs))
- if x.neg {
- v = -v
- }
- return v
-}
-
-// Uint64 returns the uint64 representation of x.
-// If x cannot be represented in a uint64, the result is undefined.
-func (x *Int) Uint64() uint64 {
- return low64(x.abs)
-}
-
-// IsInt64 reports whether x can be represented as an int64.
-func (x *Int) IsInt64() bool {
- if len(x.abs) <= 64/_W {
- w := int64(low64(x.abs))
- return w >= 0 || x.neg && w == -w
- }
- return false
-}
-
-// IsUint64 reports whether x can be represented as a uint64.
-func (x *Int) IsUint64() bool {
- return !x.neg && len(x.abs) <= 64/_W
-}
-
-// SetString sets z to the value of s, interpreted in the given base,
-// and returns z and a boolean indicating success. The entire string
-// (not just a prefix) must be valid for success. If SetString fails,
-// the value of z is undefined but the returned value is nil.
-//
-// The base argument must be 0 or a value between 2 and MaxBase.
-// For base 0, the number prefix determines the actual base: A prefix of
-// “0b” or “0B” selects base 2, “0”, “0o” or “0O” selects base 8,
-// and “0x” or “0X” selects base 16. Otherwise, the selected base is 10
-// and no prefix is accepted.
-//
-// For bases <= 36, lower and upper case letters are considered the same:
-// The letters 'a' to 'z' and 'A' to 'Z' represent digit values 10 to 35.
-// For bases > 36, the upper case letters 'A' to 'Z' represent the digit
-// values 36 to 61.
-//
-// For base 0, an underscore character “_” may appear between a base
-// prefix and an adjacent digit, and between successive digits; such
-// underscores do not change the value of the number.
-// Incorrect placement of underscores is reported as an error if there
-// are no other errors. If base != 0, underscores are not recognized
-// and act like any other character that is not a valid digit.
-func (z *Int) SetString(s string, base int) (*Int, bool) {
- return z.setFromScanner(strings.NewReader(s), base)
-}
-
-// setFromScanner implements SetString given an io.ByteScanner.
-// For documentation see comments of SetString.
-func (z *Int) setFromScanner(r io.ByteScanner, base int) (*Int, bool) {
- if _, _, err := z.scan(r, base); err != nil {
- return nil, false
- }
- // entire content must have been consumed
- if _, err := r.ReadByte(); err != io.EOF {
- return nil, false
- }
- return z, true // err == io.EOF => scan consumed all content of r
-}
-
-// SetBytes interprets buf as the bytes of a big-endian unsigned
-// integer, sets z to that value, and returns z.
-func (z *Int) SetBytes(buf []byte) *Int {
- z.abs = z.abs.setBytes(buf)
- z.neg = false
- return z
-}
-
-// Bytes returns the absolute value of x as a big-endian byte slice.
-//
-// To use a fixed length slice, or a preallocated one, use FillBytes.
-func (x *Int) Bytes() []byte {
- // This function is used in cryptographic operations. It must not leak
- // anything but the Int's sign and bit size through side-channels. Any
- // changes must be reviewed by a security expert.
- buf := make([]byte, len(x.abs)*_S)
- return buf[x.abs.bytes(buf):]
-}
-
-// FillBytes sets buf to the absolute value of x, storing it as a zero-extended
-// big-endian byte slice, and returns buf.
-//
-// If the absolute value of x doesn't fit in buf, FillBytes will panic.
-func (x *Int) FillBytes(buf []byte) []byte {
- // Clear whole buffer. (This gets optimized into a memclr.)
- for i := range buf {
- buf[i] = 0
- }
- x.abs.bytes(buf)
- return buf
-}
-
-// BitLen returns the length of the absolute value of x in bits.
-// The bit length of 0 is 0.
-func (x *Int) BitLen() int {
- // This function is used in cryptographic operations. It must not leak
- // anything but the Int's sign and bit size through side-channels. Any
- // changes must be reviewed by a security expert.
- return x.abs.bitLen()
-}
-
-// TrailingZeroBits returns the number of consecutive least significant zero
-// bits of |x|.
-func (x *Int) TrailingZeroBits() uint {
- return x.abs.trailingZeroBits()
-}
-
-// Exp sets z = x**y mod |m| (i.e. the sign of m is ignored), and returns z.
-// If m == nil or m == 0, z = x**y unless y <= 0 then z = 1. If m != 0, y < 0,
-// and x and m are not relatively prime, z is unchanged and nil is returned.
-//
-// Modular exponentiation of inputs of a particular size is not a
-// cryptographically constant-time operation.
-func (z *Int) Exp(x, y, m *Int) *Int {
- return z.exp(x, y, m, false)
-}
-
-func (z *Int) expSlow(x, y, m *Int) *Int {
- return z.exp(x, y, m, true)
-}
-
-func (z *Int) exp(x, y, m *Int, slow bool) *Int {
- // See Knuth, volume 2, section 4.6.3.
- xWords := x.abs
- if y.neg {
- if m == nil || len(m.abs) == 0 {
- return z.SetInt64(1)
- }
- // for y < 0: x**y mod m == (x**(-1))**|y| mod m
- inverse := new(Int).ModInverse(x, m)
- if inverse == nil {
- return nil
- }
- xWords = inverse.abs
- }
- yWords := y.abs
-
- var mWords nat
- if m != nil {
- if z == m || alias(z.abs, m.abs) {
- m = new(Int).Set(m)
- }
- mWords = m.abs // m.abs may be nil for m == 0
- }
-
- z.abs = z.abs.expNN(xWords, yWords, mWords, slow)
- z.neg = len(z.abs) > 0 && x.neg && len(yWords) > 0 && yWords[0]&1 == 1 // 0 has no sign
- if z.neg && len(mWords) > 0 {
- // make modulus result positive
- z.abs = z.abs.sub(mWords, z.abs) // z == x**y mod |m| && 0 <= z < |m|
- z.neg = false
- }
-
- return z
-}
-
-// GCD sets z to the greatest common divisor of a and b and returns z.
-// If x or y are not nil, GCD sets their value such that z = a*x + b*y.
-//
-// a and b may be positive, zero or negative. (Before Go 1.14 both had
-// to be > 0.) Regardless of the signs of a and b, z is always >= 0.
-//
-// If a == b == 0, GCD sets z = x = y = 0.
-//
-// If a == 0 and b != 0, GCD sets z = |b|, x = 0, y = sign(b) * 1.
-//
-// If a != 0 and b == 0, GCD sets z = |a|, x = sign(a) * 1, y = 0.
-func (z *Int) GCD(x, y, a, b *Int) *Int {
- if len(a.abs) == 0 || len(b.abs) == 0 {
- lenA, lenB, negA, negB := len(a.abs), len(b.abs), a.neg, b.neg
- if lenA == 0 {
- z.Set(b)
- } else {
- z.Set(a)
- }
- z.neg = false
- if x != nil {
- if lenA == 0 {
- x.SetUint64(0)
- } else {
- x.SetUint64(1)
- x.neg = negA
- }
- }
- if y != nil {
- if lenB == 0 {
- y.SetUint64(0)
- } else {
- y.SetUint64(1)
- y.neg = negB
- }
- }
- return z
- }
-
- return z.lehmerGCD(x, y, a, b)
-}
-
-// lehmerSimulate attempts to simulate several Euclidean update steps
-// using the leading digits of A and B. It returns u0, u1, v0, v1
-// such that A and B can be updated as:
-//
-// A = u0*A + v0*B
-// B = u1*A + v1*B
-//
-// Requirements: A >= B and len(B.abs) >= 2
-// Since we are calculating with full words to avoid overflow,
-// we use 'even' to track the sign of the cosequences.
-// For even iterations: u0, v1 >= 0 && u1, v0 <= 0
-// For odd iterations: u0, v1 <= 0 && u1, v0 >= 0
-func lehmerSimulate(A, B *Int) (u0, u1, v0, v1 Word, even bool) {
- // initialize the digits
- var a1, a2, u2, v2 Word
-
- m := len(B.abs) // m >= 2
- n := len(A.abs) // n >= m >= 2
-
- // extract the top Word of bits from A and B
- h := nlz(A.abs[n-1])
- a1 = A.abs[n-1]<<h | A.abs[n-2]>>(_W-h)
- // B may have implicit zero words in the high bits if the lengths differ
- switch {
- case n == m:
- a2 = B.abs[n-1]<<h | B.abs[n-2]>>(_W-h)
- case n == m+1:
- a2 = B.abs[n-2] >> (_W - h)
- default:
- a2 = 0
- }
-
- // Since we are calculating with full words to avoid overflow,
- // we use 'even' to track the sign of the cosequences.
- // For even iterations: u0, v1 >= 0 && u1, v0 <= 0
- // For odd iterations: u0, v1 <= 0 && u1, v0 >= 0
- // The first iteration starts with k=1 (odd).
- even = false
- // variables to track the cosequences
- u0, u1, u2 = 0, 1, 0
- v0, v1, v2 = 0, 0, 1
-
- // Calculate the quotient and cosequences using Collins' stopping condition.
- // Note that overflow of a Word is not possible when computing the remainder
- // sequence and cosequences since the cosequence size is bounded by the input size.
- // See section 4.2 of Jebelean for details.
- for a2 >= v2 && a1-a2 >= v1+v2 {
- q, r := a1/a2, a1%a2
- a1, a2 = a2, r
- u0, u1, u2 = u1, u2, u1+q*u2
- v0, v1, v2 = v1, v2, v1+q*v2
- even = !even
- }
- return
-}
-
-// lehmerUpdate updates the inputs A and B such that:
-//
-// A = u0*A + v0*B
-// B = u1*A + v1*B
-//
-// where the signs of u0, u1, v0, v1 are given by even
-// For even == true: u0, v1 >= 0 && u1, v0 <= 0
-// For even == false: u0, v1 <= 0 && u1, v0 >= 0
-// q, r, s, t are temporary variables to avoid allocations in the multiplication.
-func lehmerUpdate(A, B, q, r, s, t *Int, u0, u1, v0, v1 Word, even bool) {
-
- t.abs = t.abs.setWord(u0)
- s.abs = s.abs.setWord(v0)
- t.neg = !even
- s.neg = even
-
- t.Mul(A, t)
- s.Mul(B, s)
-
- r.abs = r.abs.setWord(u1)
- q.abs = q.abs.setWord(v1)
- r.neg = even
- q.neg = !even
-
- r.Mul(A, r)
- q.Mul(B, q)
-
- A.Add(t, s)
- B.Add(r, q)
-}
-
-// euclidUpdate performs a single step of the Euclidean GCD algorithm
-// if extended is true, it also updates the cosequence Ua, Ub.
-func euclidUpdate(A, B, Ua, Ub, q, r, s, t *Int, extended bool) {
- q, r = q.QuoRem(A, B, r)
-
- *A, *B, *r = *B, *r, *A
-
- if extended {
- // Ua, Ub = Ub, Ua - q*Ub
- t.Set(Ub)
- s.Mul(Ub, q)
- Ub.Sub(Ua, s)
- Ua.Set(t)
- }
-}
-
-// lehmerGCD sets z to the greatest common divisor of a and b,
-// which both must be != 0, and returns z.
-// If x or y are not nil, their values are set such that z = a*x + b*y.
-// See Knuth, The Art of Computer Programming, Vol. 2, Section 4.5.2, Algorithm L.
-// This implementation uses the improved condition by Collins requiring only one
-// quotient and avoiding the possibility of single Word overflow.
-// See Jebelean, "Improving the multiprecision Euclidean algorithm",
-// Design and Implementation of Symbolic Computation Systems, pp 45-58.
-// The cosequences are updated according to Algorithm 10.45 from
-// Cohen et al. "Handbook of Elliptic and Hyperelliptic Curve Cryptography" pp 192.
-func (z *Int) lehmerGCD(x, y, a, b *Int) *Int {
- var A, B, Ua, Ub *Int
-
- A = new(Int).Abs(a)
- B = new(Int).Abs(b)
-
- extended := x != nil || y != nil
-
- if extended {
- // Ua (Ub) tracks how many times input a has been accumulated into A (B).
- Ua = new(Int).SetInt64(1)
- Ub = new(Int)
- }
-
- // temp variables for multiprecision update
- q := new(Int)
- r := new(Int)
- s := new(Int)
- t := new(Int)
-
- // ensure A >= B
- if A.abs.cmp(B.abs) < 0 {
- A, B = B, A
- Ub, Ua = Ua, Ub
- }
-
- // loop invariant A >= B
- for len(B.abs) > 1 {
- // Attempt to calculate in single-precision using leading words of A and B.
- u0, u1, v0, v1, even := lehmerSimulate(A, B)
-
- // multiprecision Step
- if v0 != 0 {
- // Simulate the effect of the single-precision steps using the cosequences.
- // A = u0*A + v0*B
- // B = u1*A + v1*B
- lehmerUpdate(A, B, q, r, s, t, u0, u1, v0, v1, even)
-
- if extended {
- // Ua = u0*Ua + v0*Ub
- // Ub = u1*Ua + v1*Ub
- lehmerUpdate(Ua, Ub, q, r, s, t, u0, u1, v0, v1, even)
- }
-
- } else {
- // Single-digit calculations failed to simulate any quotients.
- // Do a standard Euclidean step.
- euclidUpdate(A, B, Ua, Ub, q, r, s, t, extended)
- }
- }
-
- if len(B.abs) > 0 {
- // extended Euclidean algorithm base case if B is a single Word
- if len(A.abs) > 1 {
- // A is longer than a single Word, so one update is needed.
- euclidUpdate(A, B, Ua, Ub, q, r, s, t, extended)
- }
- if len(B.abs) > 0 {
- // A and B are both a single Word.
- aWord, bWord := A.abs[0], B.abs[0]
- if extended {
- var ua, ub, va, vb Word
- ua, ub = 1, 0
- va, vb = 0, 1
- even := true
- for bWord != 0 {
- q, r := aWord/bWord, aWord%bWord
- aWord, bWord = bWord, r
- ua, ub = ub, ua+q*ub
- va, vb = vb, va+q*vb
- even = !even
- }
-
- t.abs = t.abs.setWord(ua)
- s.abs = s.abs.setWord(va)
- t.neg = !even
- s.neg = even
-
- t.Mul(Ua, t)
- s.Mul(Ub, s)
-
- Ua.Add(t, s)
- } else {
- for bWord != 0 {
- aWord, bWord = bWord, aWord%bWord
- }
- }
- A.abs[0] = aWord
- }
- }
- negA := a.neg
- if y != nil {
- // avoid aliasing b needed in the division below
- if y == b {
- B.Set(b)
- } else {
- B = b
- }
- // y = (z - a*x)/b
- y.Mul(a, Ua) // y can safely alias a
- if negA {
- y.neg = !y.neg
- }
- y.Sub(A, y)
- y.Div(y, B)
- }
-
- if x != nil {
- *x = *Ua
- if negA {
- x.neg = !x.neg
- }
- }
-
- *z = *A
-
- return z
-}
-
-// Rand sets z to a pseudo-random number in [0, n) and returns z.
-//
-// As this uses the math/rand package, it must not be used for
-// security-sensitive work. Use crypto/rand.Int instead.
-func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int {
- // z.neg is not modified before the if check, because z and n might alias.
- if n.neg || len(n.abs) == 0 {
- z.neg = false
- z.abs = nil
- return z
- }
- z.neg = false
- z.abs = z.abs.random(rnd, n.abs, n.abs.bitLen())
- return z
-}
-
-// ModInverse sets z to the multiplicative inverse of g in the ring ℤ/nℤ
-// and returns z. If g and n are not relatively prime, g has no multiplicative
-// inverse in the ring ℤ/nℤ. In this case, z is unchanged and the return value
-// is nil. If n == 0, a division-by-zero run-time panic occurs.
-func (z *Int) ModInverse(g, n *Int) *Int {
- // GCD expects parameters a and b to be > 0.
- if n.neg {
- var n2 Int
- n = n2.Neg(n)
- }
- if g.neg {
- var g2 Int
- g = g2.Mod(g, n)
- }
- var d, x Int
- d.GCD(&x, nil, g, n)
-
- // if and only if d==1, g and n are relatively prime
- if d.Cmp(intOne) != 0 {
- return nil
- }
-
- // x and y are such that g*x + n*y = 1, therefore x is the inverse element,
- // but it may be negative, so convert to the range 0 <= z < |n|
- if x.neg {
- z.Add(&x, n)
- } else {
- z.Set(&x)
- }
- return z
-}
-
-func (z nat) modInverse(g, n nat) nat {
- // TODO(rsc): ModInverse should be implemented in terms of this function.
- return (&Int{abs: z}).ModInverse(&Int{abs: g}, &Int{abs: n}).abs
-}
-
-// Jacobi returns the Jacobi symbol (x/y), either +1, -1, or 0.
-// The y argument must be an odd integer.
-func Jacobi(x, y *Int) int {
- if len(y.abs) == 0 || y.abs[0]&1 == 0 {
- panic(fmt.Sprintf("big: invalid 2nd argument to Int.Jacobi: need odd integer but got %s", y.String()))
- }
-
- // We use the formulation described in chapter 2, section 2.4,
- // "The Yacas Book of Algorithms":
- // http://yacas.sourceforge.net/Algo.book.pdf
-
- var a, b, c Int
- a.Set(x)
- b.Set(y)
- j := 1
-
- if b.neg {
- if a.neg {
- j = -1
- }
- b.neg = false
- }
-
- for {
- if b.Cmp(intOne) == 0 {
- return j
- }
- if len(a.abs) == 0 {
- return 0
- }
- a.Mod(&a, &b)
- if len(a.abs) == 0 {
- return 0
- }
- // a > 0
-
- // handle factors of 2 in 'a'
- s := a.abs.trailingZeroBits()
- if s&1 != 0 {
- bmod8 := b.abs[0] & 7
- if bmod8 == 3 || bmod8 == 5 {
- j = -j
- }
- }
- c.Rsh(&a, s) // a = 2^s*c
-
- // swap numerator and denominator
- if b.abs[0]&3 == 3 && c.abs[0]&3 == 3 {
- j = -j
- }
- a.Set(&b)
- b.Set(&c)
- }
-}
-
-// modSqrt3Mod4 uses the identity
-//
-// (a^((p+1)/4))^2 mod p
-// == u^(p+1) mod p
-// == u^2 mod p
-//
-// to calculate the square root of any quadratic residue mod p quickly for 3
-// mod 4 primes.
-func (z *Int) modSqrt3Mod4Prime(x, p *Int) *Int {
- e := new(Int).Add(p, intOne) // e = p + 1
- e.Rsh(e, 2) // e = (p + 1) / 4
- z.Exp(x, e, p) // z = x^e mod p
- return z
-}
-
-// modSqrt5Mod8 uses Atkin's observation that 2 is not a square mod p
-//
-// alpha == (2*a)^((p-5)/8) mod p
-// beta == 2*a*alpha^2 mod p is a square root of -1
-// b == a*alpha*(beta-1) mod p is a square root of a
-//
-// to calculate the square root of any quadratic residue mod p quickly for 5
-// mod 8 primes.
-func (z *Int) modSqrt5Mod8Prime(x, p *Int) *Int {
- // p == 5 mod 8 implies p = e*8 + 5
- // e is the quotient and 5 the remainder on division by 8
- e := new(Int).Rsh(p, 3) // e = (p - 5) / 8
- tx := new(Int).Lsh(x, 1) // tx = 2*x
- alpha := new(Int).Exp(tx, e, p)
- beta := new(Int).Mul(alpha, alpha)
- beta.Mod(beta, p)
- beta.Mul(beta, tx)
- beta.Mod(beta, p)
- beta.Sub(beta, intOne)
- beta.Mul(beta, x)
- beta.Mod(beta, p)
- beta.Mul(beta, alpha)
- z.Mod(beta, p)
- return z
-}
-
-// modSqrtTonelliShanks uses the Tonelli-Shanks algorithm to find the square
-// root of a quadratic residue modulo any prime.
-func (z *Int) modSqrtTonelliShanks(x, p *Int) *Int {
- // Break p-1 into s*2^e such that s is odd.
- var s Int
- s.Sub(p, intOne)
- e := s.abs.trailingZeroBits()
- s.Rsh(&s, e)
-
- // find some non-square n
- var n Int
- n.SetInt64(2)
- for Jacobi(&n, p) != -1 {
- n.Add(&n, intOne)
- }
-
- // Core of the Tonelli-Shanks algorithm. Follows the description in
- // section 6 of "Square roots from 1; 24, 51, 10 to Dan Shanks" by Ezra
- // Brown:
- // https://www.maa.org/sites/default/files/pdf/upload_library/22/Polya/07468342.di020786.02p0470a.pdf
- var y, b, g, t Int
- y.Add(&s, intOne)
- y.Rsh(&y, 1)
- y.Exp(x, &y, p) // y = x^((s+1)/2)
- b.Exp(x, &s, p) // b = x^s
- g.Exp(&n, &s, p) // g = n^s
- r := e
- for {
- // find the least m such that ord_p(b) = 2^m
- var m uint
- t.Set(&b)
- for t.Cmp(intOne) != 0 {
- t.Mul(&t, &t).Mod(&t, p)
- m++
- }
-
- if m == 0 {
- return z.Set(&y)
- }
-
- t.SetInt64(0).SetBit(&t, int(r-m-1), 1).Exp(&g, &t, p)
- // t = g^(2^(r-m-1)) mod p
- g.Mul(&t, &t).Mod(&g, p) // g = g^(2^(r-m)) mod p
- y.Mul(&y, &t).Mod(&y, p)
- b.Mul(&b, &g).Mod(&b, p)
- r = m
- }
-}
-
-// ModSqrt sets z to a square root of x mod p if such a square root exists, and
-// returns z. The modulus p must be an odd prime. If x is not a square mod p,
-// ModSqrt leaves z unchanged and returns nil. This function panics if p is
-// not an odd integer, its behavior is undefined if p is odd but not prime.
-func (z *Int) ModSqrt(x, p *Int) *Int {
- switch Jacobi(x, p) {
- case -1:
- return nil // x is not a square mod p
- case 0:
- return z.SetInt64(0) // sqrt(0) mod p = 0
- case 1:
- break
- }
- if x.neg || x.Cmp(p) >= 0 { // ensure 0 <= x < p
- x = new(Int).Mod(x, p)
- }
-
- switch {
- case p.abs[0]%4 == 3:
- // Check whether p is 3 mod 4, and if so, use the faster algorithm.
- return z.modSqrt3Mod4Prime(x, p)
- case p.abs[0]%8 == 5:
- // Check whether p is 5 mod 8, use Atkin's algorithm.
- return z.modSqrt5Mod8Prime(x, p)
- default:
- // Otherwise, use Tonelli-Shanks.
- return z.modSqrtTonelliShanks(x, p)
- }
-}
-
-// Lsh sets z = x << n and returns z.
-func (z *Int) Lsh(x *Int, n uint) *Int {
- z.abs = z.abs.shl(x.abs, n)
- z.neg = x.neg
- return z
-}
-
-// Rsh sets z = x >> n and returns z.
-func (z *Int) Rsh(x *Int, n uint) *Int {
- if x.neg {
- // (-x) >> s == ^(x-1) >> s == ^((x-1) >> s) == -(((x-1) >> s) + 1)
- t := z.abs.sub(x.abs, natOne) // no underflow because |x| > 0
- t = t.shr(t, n)
- z.abs = t.add(t, natOne)
- z.neg = true // z cannot be zero if x is negative
- return z
- }
-
- z.abs = z.abs.shr(x.abs, n)
- z.neg = false
- return z
-}
-
-// Bit returns the value of the i'th bit of x. That is, it
-// returns (x>>i)&1. The bit index i must be >= 0.
-func (x *Int) Bit(i int) uint {
- if i == 0 {
- // optimization for common case: odd/even test of x
- if len(x.abs) > 0 {
- return uint(x.abs[0] & 1) // bit 0 is same for -x
- }
- return 0
- }
- if i < 0 {
- panic("negative bit index")
- }
- if x.neg {
- t := nat(nil).sub(x.abs, natOne)
- return t.bit(uint(i)) ^ 1
- }
-
- return x.abs.bit(uint(i))
-}
-
-// SetBit sets z to x, with x's i'th bit set to b (0 or 1).
-// That is, if b is 1 SetBit sets z = x | (1 << i);
-// if b is 0 SetBit sets z = x &^ (1 << i). If b is not 0 or 1,
-// SetBit will panic.
-func (z *Int) SetBit(x *Int, i int, b uint) *Int {
- if i < 0 {
- panic("negative bit index")
- }
- if x.neg {
- t := z.abs.sub(x.abs, natOne)
- t = t.setBit(t, uint(i), b^1)
- z.abs = t.add(t, natOne)
- z.neg = len(z.abs) > 0
- return z
- }
- z.abs = z.abs.setBit(x.abs, uint(i), b)
- z.neg = false
- return z
-}
-
-// And sets z = x & y and returns z.
-func (z *Int) And(x, y *Int) *Int {
- if x.neg == y.neg {
- if x.neg {
- // (-x) & (-y) == ^(x-1) & ^(y-1) == ^((x-1) | (y-1)) == -(((x-1) | (y-1)) + 1)
- x1 := nat(nil).sub(x.abs, natOne)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.add(z.abs.or(x1, y1), natOne)
- z.neg = true // z cannot be zero if x and y are negative
- return z
- }
-
- // x & y == x & y
- z.abs = z.abs.and(x.abs, y.abs)
- z.neg = false
- return z
- }
-
- // x.neg != y.neg
- if x.neg {
- x, y = y, x // & is symmetric
- }
-
- // x & (-y) == x & ^(y-1) == x &^ (y-1)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.andNot(x.abs, y1)
- z.neg = false
- return z
-}
-
-// AndNot sets z = x &^ y and returns z.
-func (z *Int) AndNot(x, y *Int) *Int {
- if x.neg == y.neg {
- if x.neg {
- // (-x) &^ (-y) == ^(x-1) &^ ^(y-1) == ^(x-1) & (y-1) == (y-1) &^ (x-1)
- x1 := nat(nil).sub(x.abs, natOne)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.andNot(y1, x1)
- z.neg = false
- return z
- }
-
- // x &^ y == x &^ y
- z.abs = z.abs.andNot(x.abs, y.abs)
- z.neg = false
- return z
- }
-
- if x.neg {
- // (-x) &^ y == ^(x-1) &^ y == ^(x-1) & ^y == ^((x-1) | y) == -(((x-1) | y) + 1)
- x1 := nat(nil).sub(x.abs, natOne)
- z.abs = z.abs.add(z.abs.or(x1, y.abs), natOne)
- z.neg = true // z cannot be zero if x is negative and y is positive
- return z
- }
-
- // x &^ (-y) == x &^ ^(y-1) == x & (y-1)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.and(x.abs, y1)
- z.neg = false
- return z
-}
-
-// Or sets z = x | y and returns z.
-func (z *Int) Or(x, y *Int) *Int {
- if x.neg == y.neg {
- if x.neg {
- // (-x) | (-y) == ^(x-1) | ^(y-1) == ^((x-1) & (y-1)) == -(((x-1) & (y-1)) + 1)
- x1 := nat(nil).sub(x.abs, natOne)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.add(z.abs.and(x1, y1), natOne)
- z.neg = true // z cannot be zero if x and y are negative
- return z
- }
-
- // x | y == x | y
- z.abs = z.abs.or(x.abs, y.abs)
- z.neg = false
- return z
- }
-
- // x.neg != y.neg
- if x.neg {
- x, y = y, x // | is symmetric
- }
-
- // x | (-y) == x | ^(y-1) == ^((y-1) &^ x) == -(^((y-1) &^ x) + 1)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.add(z.abs.andNot(y1, x.abs), natOne)
- z.neg = true // z cannot be zero if one of x or y is negative
- return z
-}
-
-// Xor sets z = x ^ y and returns z.
-func (z *Int) Xor(x, y *Int) *Int {
- if x.neg == y.neg {
- if x.neg {
- // (-x) ^ (-y) == ^(x-1) ^ ^(y-1) == (x-1) ^ (y-1)
- x1 := nat(nil).sub(x.abs, natOne)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.xor(x1, y1)
- z.neg = false
- return z
- }
-
- // x ^ y == x ^ y
- z.abs = z.abs.xor(x.abs, y.abs)
- z.neg = false
- return z
- }
-
- // x.neg != y.neg
- if x.neg {
- x, y = y, x // ^ is symmetric
- }
-
- // x ^ (-y) == x ^ ^(y-1) == ^(x ^ (y-1)) == -((x ^ (y-1)) + 1)
- y1 := nat(nil).sub(y.abs, natOne)
- z.abs = z.abs.add(z.abs.xor(x.abs, y1), natOne)
- z.neg = true // z cannot be zero if only one of x or y is negative
- return z
-}
-
-// Not sets z = ^x and returns z.
-func (z *Int) Not(x *Int) *Int {
- if x.neg {
- // ^(-x) == ^(^(x-1)) == x-1
- z.abs = z.abs.sub(x.abs, natOne)
- z.neg = false
- return z
- }
-
- // ^x == -x-1 == -(x+1)
- z.abs = z.abs.add(x.abs, natOne)
- z.neg = true // z cannot be zero if x is positive
- return z
-}
-
-// Sqrt sets z to ⌊√x⌋, the largest integer such that z² ≤ x, and returns z.
-// It panics if x is negative.
-func (z *Int) Sqrt(x *Int) *Int {
- if x.neg {
- panic("square root of negative number")
- }
- z.neg = false
- z.abs = z.abs.sqrt(x.abs)
- return z
-}
diff --git a/contrib/go/_std_1.20/src/math/big/roundingmode_string.go b/contrib/go/_std_1.20/src/math/big/roundingmode_string.go
deleted file mode 100644
index c7629eb98b..0000000000
--- a/contrib/go/_std_1.20/src/math/big/roundingmode_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Code generated by "stringer -type=RoundingMode"; DO NOT EDIT.
-
-package big
-
-import "strconv"
-
-const _RoundingMode_name = "ToNearestEvenToNearestAwayToZeroAwayFromZeroToNegativeInfToPositiveInf"
-
-var _RoundingMode_index = [...]uint8{0, 13, 26, 32, 44, 57, 70}
-
-func (i RoundingMode) String() string {
- if i >= RoundingMode(len(_RoundingMode_index)-1) {
- return "RoundingMode(" + strconv.FormatInt(int64(i), 10) + ")"
- }
- return _RoundingMode_name[_RoundingMode_index[i]:_RoundingMode_index[i+1]]
-}
diff --git a/contrib/go/_std_1.20/src/math/big/ya.make b/contrib/go/_std_1.20/src/math/big/ya.make
deleted file mode 100644
index e7d4942cd9..0000000000
--- a/contrib/go/_std_1.20/src/math/big/ya.make
+++ /dev/null
@@ -1,40 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- accuracy_string.go
- arith.go
- arith_decl.go
- decimal.go
- doc.go
- float.go
- floatconv.go
- floatmarsh.go
- ftoa.go
- int.go
- intconv.go
- intmarsh.go
- nat.go
- natconv.go
- natdiv.go
- prime.go
- rat.go
- ratconv.go
- ratmarsh.go
- roundingmode_string.go
- sqrt.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- arith_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- arith_amd64.go
- arith_amd64.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/math/bits/ya.make b/contrib/go/_std_1.20/src/math/bits/ya.make
deleted file mode 100644
index 574ffbc157..0000000000
--- a/contrib/go/_std_1.20/src/math/bits/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- bits.go
- bits_errors.go
- bits_tables.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/math/cmplx/ya.make b/contrib/go/_std_1.20/src/math/cmplx/ya.make
deleted file mode 100644
index 850af8e286..0000000000
--- a/contrib/go/_std_1.20/src/math/cmplx/ya.make
+++ /dev/null
@@ -1,20 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- abs.go
- asin.go
- conj.go
- exp.go
- isinf.go
- isnan.go
- log.go
- phase.go
- polar.go
- pow.go
- rect.go
- sin.go
- sqrt.go
- tan.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/math/dim.go b/contrib/go/_std_1.20/src/math/dim.go
deleted file mode 100644
index 6a286cdc75..0000000000
--- a/contrib/go/_std_1.20/src/math/dim.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2010 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 math
-
-// Dim returns the maximum of x-y or 0.
-//
-// Special cases are:
-//
-// Dim(+Inf, +Inf) = NaN
-// Dim(-Inf, -Inf) = NaN
-// Dim(x, NaN) = Dim(NaN, x) = NaN
-func Dim(x, y float64) float64 {
- // The special cases result in NaN after the subtraction:
- // +Inf - +Inf = NaN
- // -Inf - -Inf = NaN
- // NaN - y = NaN
- // x - NaN = NaN
- v := x - y
- if v <= 0 {
- // v is negative or 0
- return 0
- }
- // v is positive or NaN
- return v
-}
-
-// Max returns the larger of x or y.
-//
-// Special cases are:
-//
-// Max(x, +Inf) = Max(+Inf, x) = +Inf
-// Max(x, NaN) = Max(NaN, x) = NaN
-// Max(+0, ±0) = Max(±0, +0) = +0
-// Max(-0, -0) = -0
-func Max(x, y float64) float64 {
- if haveArchMax {
- return archMax(x, y)
- }
- return max(x, y)
-}
-
-func max(x, y float64) float64 {
- // special cases
- switch {
- case IsInf(x, 1) || IsInf(y, 1):
- return Inf(1)
- case IsNaN(x) || IsNaN(y):
- return NaN()
- case x == 0 && x == y:
- if Signbit(x) {
- return y
- }
- return x
- }
- if x > y {
- return x
- }
- return y
-}
-
-// Min returns the smaller of x or y.
-//
-// Special cases are:
-//
-// Min(x, -Inf) = Min(-Inf, x) = -Inf
-// Min(x, NaN) = Min(NaN, x) = NaN
-// Min(-0, ±0) = Min(±0, -0) = -0
-func Min(x, y float64) float64 {
- if haveArchMin {
- return archMin(x, y)
- }
- return min(x, y)
-}
-
-func min(x, y float64) float64 {
- // special cases
- switch {
- case IsInf(x, -1) || IsInf(y, -1):
- return Inf(-1)
- case IsNaN(x) || IsNaN(y):
- return NaN()
- case x == 0 && x == y:
- if Signbit(x) {
- return x
- }
- return y
- }
- if x < y {
- return x
- }
- return y
-}
diff --git a/contrib/go/_std_1.20/src/math/fma.go b/contrib/go/_std_1.20/src/math/fma.go
deleted file mode 100644
index ca0bf99f21..0000000000
--- a/contrib/go/_std_1.20/src/math/fma.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package math
-
-import "math/bits"
-
-func zero(x uint64) uint64 {
- if x == 0 {
- return 1
- }
- return 0
- // branchless:
- // return ((x>>1 | x&1) - 1) >> 63
-}
-
-func nonzero(x uint64) uint64 {
- if x != 0 {
- return 1
- }
- return 0
- // branchless:
- // return 1 - ((x>>1|x&1)-1)>>63
-}
-
-func shl(u1, u2 uint64, n uint) (r1, r2 uint64) {
- r1 = u1<<n | u2>>(64-n) | u2<<(n-64)
- r2 = u2 << n
- return
-}
-
-func shr(u1, u2 uint64, n uint) (r1, r2 uint64) {
- r2 = u2>>n | u1<<(64-n) | u1>>(n-64)
- r1 = u1 >> n
- return
-}
-
-// shrcompress compresses the bottom n+1 bits of the two-word
-// value into a single bit. the result is equal to the value
-// shifted to the right by n, except the result's 0th bit is
-// set to the bitwise OR of the bottom n+1 bits.
-func shrcompress(u1, u2 uint64, n uint) (r1, r2 uint64) {
- // TODO: Performance here is really sensitive to the
- // order/placement of these branches. n == 0 is common
- // enough to be in the fast path. Perhaps more measurement
- // needs to be done to find the optimal order/placement?
- switch {
- case n == 0:
- return u1, u2
- case n == 64:
- return 0, u1 | nonzero(u2)
- case n >= 128:
- return 0, nonzero(u1 | u2)
- case n < 64:
- r1, r2 = shr(u1, u2, n)
- r2 |= nonzero(u2 & (1<<n - 1))
- case n < 128:
- r1, r2 = shr(u1, u2, n)
- r2 |= nonzero(u1&(1<<(n-64)-1) | u2)
- }
- return
-}
-
-func lz(u1, u2 uint64) (l int32) {
- l = int32(bits.LeadingZeros64(u1))
- if l == 64 {
- l += int32(bits.LeadingZeros64(u2))
- }
- return l
-}
-
-// split splits b into sign, biased exponent, and mantissa.
-// It adds the implicit 1 bit to the mantissa for normal values,
-// and normalizes subnormal values.
-func split(b uint64) (sign uint32, exp int32, mantissa uint64) {
- sign = uint32(b >> 63)
- exp = int32(b>>52) & mask
- mantissa = b & fracMask
-
- if exp == 0 {
- // Normalize value if subnormal.
- shift := uint(bits.LeadingZeros64(mantissa) - 11)
- mantissa <<= shift
- exp = 1 - int32(shift)
- } else {
- // Add implicit 1 bit
- mantissa |= 1 << 52
- }
- return
-}
-
-// FMA returns x * y + z, computed with only one rounding.
-// (That is, FMA returns the fused multiply-add of x, y, and z.)
-func FMA(x, y, z float64) float64 {
- bx, by, bz := Float64bits(x), Float64bits(y), Float64bits(z)
-
- // Inf or NaN or zero involved. At most one rounding will occur.
- if x == 0.0 || y == 0.0 || z == 0.0 || bx&uvinf == uvinf || by&uvinf == uvinf {
- return x*y + z
- }
- // Handle non-finite z separately. Evaluating x*y+z where
- // x and y are finite, but z is infinite, should always result in z.
- if bz&uvinf == uvinf {
- return z
- }
-
- // Inputs are (sub)normal.
- // Split x, y, z into sign, exponent, mantissa.
- xs, xe, xm := split(bx)
- ys, ye, ym := split(by)
- zs, ze, zm := split(bz)
-
- // Compute product p = x*y as sign, exponent, two-word mantissa.
- // Start with exponent. "is normal" bit isn't subtracted yet.
- pe := xe + ye - bias + 1
-
- // pm1:pm2 is the double-word mantissa for the product p.
- // Shift left to leave top bit in product. Effectively
- // shifts the 106-bit product to the left by 21.
- pm1, pm2 := bits.Mul64(xm<<10, ym<<11)
- zm1, zm2 := zm<<10, uint64(0)
- ps := xs ^ ys // product sign
-
- // normalize to 62nd bit
- is62zero := uint((^pm1 >> 62) & 1)
- pm1, pm2 = shl(pm1, pm2, is62zero)
- pe -= int32(is62zero)
-
- // Swap addition operands so |p| >= |z|
- if pe < ze || pe == ze && pm1 < zm1 {
- ps, pe, pm1, pm2, zs, ze, zm1, zm2 = zs, ze, zm1, zm2, ps, pe, pm1, pm2
- }
-
- // Align significands
- zm1, zm2 = shrcompress(zm1, zm2, uint(pe-ze))
-
- // Compute resulting significands, normalizing if necessary.
- var m, c uint64
- if ps == zs {
- // Adding (pm1:pm2) + (zm1:zm2)
- pm2, c = bits.Add64(pm2, zm2, 0)
- pm1, _ = bits.Add64(pm1, zm1, c)
- pe -= int32(^pm1 >> 63)
- pm1, m = shrcompress(pm1, pm2, uint(64+pm1>>63))
- } else {
- // Subtracting (pm1:pm2) - (zm1:zm2)
- // TODO: should we special-case cancellation?
- pm2, c = bits.Sub64(pm2, zm2, 0)
- pm1, _ = bits.Sub64(pm1, zm1, c)
- nz := lz(pm1, pm2)
- pe -= nz
- m, pm2 = shl(pm1, pm2, uint(nz-1))
- m |= nonzero(pm2)
- }
-
- // Round and break ties to even
- if pe > 1022+bias || pe == 1022+bias && (m+1<<9)>>63 == 1 {
- // rounded value overflows exponent range
- return Float64frombits(uint64(ps)<<63 | uvinf)
- }
- if pe < 0 {
- n := uint(-pe)
- m = m>>n | nonzero(m&(1<<n-1))
- pe = 0
- }
- m = ((m + 1<<9) >> 10) & ^zero((m&(1<<10-1))^1<<9)
- pe &= -int32(nonzero(m))
- return Float64frombits(uint64(ps)<<63 + uint64(pe)<<52 + m)
-}
diff --git a/contrib/go/_std_1.20/src/math/log_amd64.s b/contrib/go/_std_1.20/src/math/log_amd64.s
deleted file mode 100644
index d84091f23a..0000000000
--- a/contrib/go/_std_1.20/src/math/log_amd64.s
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2010 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.
-
-#include "textflag.h"
-
-#define HSqrt2 7.07106781186547524401e-01 // sqrt(2)/2
-#define Ln2Hi 6.93147180369123816490e-01 // 0x3fe62e42fee00000
-#define Ln2Lo 1.90821492927058770002e-10 // 0x3dea39ef35793c76
-#define L1 6.666666666666735130e-01 // 0x3FE5555555555593
-#define L2 3.999999999940941908e-01 // 0x3FD999999997FA04
-#define L3 2.857142874366239149e-01 // 0x3FD2492494229359
-#define L4 2.222219843214978396e-01 // 0x3FCC71C51D8E78AF
-#define L5 1.818357216161805012e-01 // 0x3FC7466496CB03DE
-#define L6 1.531383769920937332e-01 // 0x3FC39A09D078C69F
-#define L7 1.479819860511658591e-01 // 0x3FC2F112DF3E5244
-#define NaN 0x7FF8000000000001
-#define NegInf 0xFFF0000000000000
-#define PosInf 0x7FF0000000000000
-
-// func Log(x float64) float64
-TEXT ·archLog(SB),NOSPLIT,$0
- // test bits for special cases
- MOVQ x+0(FP), BX
- MOVQ $~(1<<63), AX // sign bit mask
- ANDQ BX, AX
- JEQ isZero
- MOVQ $0, AX
- CMPQ AX, BX
- JGT isNegative
- MOVQ $PosInf, AX
- CMPQ AX, BX
- JLE isInfOrNaN
- // f1, ki := math.Frexp(x); k := float64(ki)
- MOVQ BX, X0
- MOVQ $0x000FFFFFFFFFFFFF, AX
- MOVQ AX, X2
- ANDPD X0, X2
- MOVSD $0.5, X0 // 0x3FE0000000000000
- ORPD X0, X2 // X2= f1
- SHRQ $52, BX
- ANDL $0x7FF, BX
- SUBL $0x3FE, BX
- XORPS X1, X1 // break dependency for CVTSL2SD
- CVTSL2SD BX, X1 // x1= k, x2= f1
- // if f1 < math.Sqrt2/2 { k -= 1; f1 *= 2 }
- MOVSD $HSqrt2, X0 // x0= 0.7071, x1= k, x2= f1
- CMPSD X2, X0, 5 // cmpnlt; x0= 0 or ^0, x1= k, x2 = f1
- MOVSD $1.0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 1
- ANDPD X0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1
- SUBSD X3, X1 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1
- MOVSD $1.0, X0 // x0= 1, x1= k, x2= f1, x3= 0 or 1
- ADDSD X0, X3 // x0= 1, x1= k, x2= f1, x3= 1 or 2
- MULSD X3, X2 // x0= 1, x1= k, x2= f1
- // f := f1 - 1
- SUBSD X0, X2 // x1= k, x2= f
- // s := f / (2 + f)
- MOVSD $2.0, X0
- ADDSD X2, X0
- MOVAPD X2, X3
- DIVSD X0, X3 // x1=k, x2= f, x3= s
- // s2 := s * s
- MOVAPD X3, X4 // x1= k, x2= f, x3= s
- MULSD X4, X4 // x1= k, x2= f, x3= s, x4= s2
- // s4 := s2 * s2
- MOVAPD X4, X5 // x1= k, x2= f, x3= s, x4= s2
- MULSD X5, X5 // x1= k, x2= f, x3= s, x4= s2, x5= s4
- // t1 := s2 * (L1 + s4*(L3+s4*(L5+s4*L7)))
- MOVSD $L7, X6
- MULSD X5, X6
- ADDSD $L5, X6
- MULSD X5, X6
- ADDSD $L3, X6
- MULSD X5, X6
- ADDSD $L1, X6
- MULSD X6, X4 // x1= k, x2= f, x3= s, x4= t1, x5= s4
- // t2 := s4 * (L2 + s4*(L4+s4*L6))
- MOVSD $L6, X6
- MULSD X5, X6
- ADDSD $L4, X6
- MULSD X5, X6
- ADDSD $L2, X6
- MULSD X6, X5 // x1= k, x2= f, x3= s, x4= t1, x5= t2
- // R := t1 + t2
- ADDSD X5, X4 // x1= k, x2= f, x3= s, x4= R
- // hfsq := 0.5 * f * f
- MOVSD $0.5, X0
- MULSD X2, X0
- MULSD X2, X0 // x0= hfsq, x1= k, x2= f, x3= s, x4= R
- // return k*Ln2Hi - ((hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f)
- ADDSD X0, X4 // x0= hfsq, x1= k, x2= f, x3= s, x4= hfsq+R
- MULSD X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)
- MOVSD $Ln2Lo, X4
- MULSD X1, X4 // x4= k*Ln2Lo
- ADDSD X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)+k*Ln2Lo
- SUBSD X3, X0 // x0= hfsq-(s*(hfsq+R)+k*Ln2Lo), x1= k, x2= f
- SUBSD X2, X0 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k
- MULSD $Ln2Hi, X1 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k*Ln2Hi
- SUBSD X0, X1 // x1= k*Ln2Hi-((hfsq-(s*(hfsq+R)+k*Ln2Lo))-f)
- MOVSD X1, ret+8(FP)
- RET
-isInfOrNaN:
- MOVQ BX, ret+8(FP) // +Inf or NaN, return x
- RET
-isNegative:
- MOVQ $NaN, AX
- MOVQ AX, ret+8(FP) // return NaN
- RET
-isZero:
- MOVQ $NegInf, AX
- MOVQ AX, ret+8(FP) // return -Inf
- RET
diff --git a/contrib/go/_std_1.20/src/math/pow.go b/contrib/go/_std_1.20/src/math/pow.go
deleted file mode 100644
index 3af8c8b649..0000000000
--- a/contrib/go/_std_1.20/src/math/pow.go
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2009 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 math
-
-func isOddInt(x float64) bool {
- xi, xf := Modf(x)
- return xf == 0 && int64(xi)&1 == 1
-}
-
-// Special cases taken from FreeBSD's /usr/src/lib/msun/src/e_pow.c
-// updated by IEEE Std. 754-2008 "Section 9.2.1 Special values".
-
-// Pow returns x**y, the base-x exponential of y.
-//
-// Special cases are (in order):
-//
-// Pow(x, ±0) = 1 for any x
-// Pow(1, y) = 1 for any y
-// Pow(x, 1) = x for any x
-// Pow(NaN, y) = NaN
-// Pow(x, NaN) = NaN
-// Pow(±0, y) = ±Inf for y an odd integer < 0
-// Pow(±0, -Inf) = +Inf
-// Pow(±0, +Inf) = +0
-// Pow(±0, y) = +Inf for finite y < 0 and not an odd integer
-// Pow(±0, y) = ±0 for y an odd integer > 0
-// Pow(±0, y) = +0 for finite y > 0 and not an odd integer
-// Pow(-1, ±Inf) = 1
-// Pow(x, +Inf) = +Inf for |x| > 1
-// Pow(x, -Inf) = +0 for |x| > 1
-// Pow(x, +Inf) = +0 for |x| < 1
-// Pow(x, -Inf) = +Inf for |x| < 1
-// Pow(+Inf, y) = +Inf for y > 0
-// Pow(+Inf, y) = +0 for y < 0
-// Pow(-Inf, y) = Pow(-0, -y)
-// Pow(x, y) = NaN for finite x < 0 and finite non-integer y
-func Pow(x, y float64) float64 {
- if haveArchPow {
- return archPow(x, y)
- }
- return pow(x, y)
-}
-
-func pow(x, y float64) float64 {
- switch {
- case y == 0 || x == 1:
- return 1
- case y == 1:
- return x
- case IsNaN(x) || IsNaN(y):
- return NaN()
- case x == 0:
- switch {
- case y < 0:
- if isOddInt(y) {
- return Copysign(Inf(1), x)
- }
- return Inf(1)
- case y > 0:
- if isOddInt(y) {
- return x
- }
- return 0
- }
- case IsInf(y, 0):
- switch {
- case x == -1:
- return 1
- case (Abs(x) < 1) == IsInf(y, 1):
- return 0
- default:
- return Inf(1)
- }
- case IsInf(x, 0):
- if IsInf(x, -1) {
- return Pow(1/x, -y) // Pow(-0, -y)
- }
- switch {
- case y < 0:
- return 0
- case y > 0:
- return Inf(1)
- }
- case y == 0.5:
- return Sqrt(x)
- case y == -0.5:
- return 1 / Sqrt(x)
- }
-
- yi, yf := Modf(Abs(y))
- if yf != 0 && x < 0 {
- return NaN()
- }
- if yi >= 1<<63 {
- // yi is a large even int that will lead to overflow (or underflow to 0)
- // for all x except -1 (x == 1 was handled earlier)
- switch {
- case x == -1:
- return 1
- case (Abs(x) < 1) == (y > 0):
- return 0
- default:
- return Inf(1)
- }
- }
-
- // ans = a1 * 2**ae (= 1 for now).
- a1 := 1.0
- ae := 0
-
- // ans *= x**yf
- if yf != 0 {
- if yf > 0.5 {
- yf--
- yi++
- }
- a1 = Exp(yf * Log(x))
- }
-
- // ans *= x**yi
- // by multiplying in successive squarings
- // of x according to bits of yi.
- // accumulate powers of two into exp.
- x1, xe := Frexp(x)
- for i := int64(yi); i != 0; i >>= 1 {
- if xe < -1<<12 || 1<<12 < xe {
- // catch xe before it overflows the left shift below
- // Since i !=0 it has at least one bit still set, so ae will accumulate xe
- // on at least one more iteration, ae += xe is a lower bound on ae
- // the lower bound on ae exceeds the size of a float64 exp
- // so the final call to Ldexp will produce under/overflow (0/Inf)
- ae += xe
- break
- }
- if i&1 == 1 {
- a1 *= x1
- ae += xe
- }
- x1 *= x1
- xe <<= 1
- if x1 < .5 {
- x1 += x1
- xe--
- }
- }
-
- // ans = a1*2**ae
- // if y < 0 { ans = 1 / ans }
- // but in the opposite order
- if y < 0 {
- a1 = 1 / a1
- ae = -ae
- }
- return Ldexp(a1, ae)
-}
diff --git a/contrib/go/_std_1.20/src/math/rand/rand.go b/contrib/go/_std_1.20/src/math/rand/rand.go
deleted file mode 100644
index b668da85d1..0000000000
--- a/contrib/go/_std_1.20/src/math/rand/rand.go
+++ /dev/null
@@ -1,473 +0,0 @@
-// Copyright 2009 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 rand implements pseudo-random number generators unsuitable for
-// security-sensitive work.
-//
-// Random numbers are generated by a [Source], usually wrapped in a [Rand].
-// Both types should be used by a single goroutine at a time: sharing among
-// multiple goroutines requires some kind of synchronization.
-//
-// Top-level functions, such as [Float64] and [Int],
-// are safe for concurrent use by multiple goroutines.
-//
-// This package's outputs might be easily predictable regardless of how it's
-// seeded. For random numbers suitable for security-sensitive work, see the
-// crypto/rand package.
-package rand
-
-import (
- "internal/godebug"
- "sync"
- _ "unsafe" // for go:linkname
-
-)
-
-// A Source represents a source of uniformly-distributed
-// pseudo-random int64 values in the range [0, 1<<63).
-//
-// A Source is not safe for concurrent use by multiple goroutines.
-type Source interface {
- Int63() int64
- Seed(seed int64)
-}
-
-// A Source64 is a Source that can also generate
-// uniformly-distributed pseudo-random uint64 values in
-// the range [0, 1<<64) directly.
-// If a Rand r's underlying Source s implements Source64,
-// then r.Uint64 returns the result of one call to s.Uint64
-// instead of making two calls to s.Int63.
-type Source64 interface {
- Source
- Uint64() uint64
-}
-
-// NewSource returns a new pseudo-random Source seeded with the given value.
-// Unlike the default Source used by top-level functions, this source is not
-// safe for concurrent use by multiple goroutines.
-// The returned Source implements Source64.
-func NewSource(seed int64) Source {
- return newSource(seed)
-}
-
-func newSource(seed int64) *rngSource {
- var rng rngSource
- rng.Seed(seed)
- return &rng
-}
-
-// A Rand is a source of random numbers.
-type Rand struct {
- src Source
- s64 Source64 // non-nil if src is source64
-
- // readVal contains remainder of 63-bit integer used for bytes
- // generation during most recent Read call.
- // It is saved so next Read call can start where the previous
- // one finished.
- readVal int64
- // readPos indicates the number of low-order bytes of readVal
- // that are still valid.
- readPos int8
-}
-
-// New returns a new Rand that uses random values from src
-// to generate other random values.
-func New(src Source) *Rand {
- s64, _ := src.(Source64)
- return &Rand{src: src, s64: s64}
-}
-
-// Seed uses the provided seed value to initialize the generator to a deterministic state.
-// Seed should not be called concurrently with any other Rand method.
-func (r *Rand) Seed(seed int64) {
- if lk, ok := r.src.(*lockedSource); ok {
- lk.seedPos(seed, &r.readPos)
- return
- }
-
- r.src.Seed(seed)
- r.readPos = 0
-}
-
-// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
-func (r *Rand) Int63() int64 { return r.src.Int63() }
-
-// Uint32 returns a pseudo-random 32-bit value as a uint32.
-func (r *Rand) Uint32() uint32 { return uint32(r.Int63() >> 31) }
-
-// Uint64 returns a pseudo-random 64-bit value as a uint64.
-func (r *Rand) Uint64() uint64 {
- if r.s64 != nil {
- return r.s64.Uint64()
- }
- return uint64(r.Int63())>>31 | uint64(r.Int63())<<32
-}
-
-// Int31 returns a non-negative pseudo-random 31-bit integer as an int32.
-func (r *Rand) Int31() int32 { return int32(r.Int63() >> 32) }
-
-// Int returns a non-negative pseudo-random int.
-func (r *Rand) Int() int {
- u := uint(r.Int63())
- return int(u << 1 >> 1) // clear sign bit if int == int32
-}
-
-// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n).
-// It panics if n <= 0.
-func (r *Rand) Int63n(n int64) int64 {
- if n <= 0 {
- panic("invalid argument to Int63n")
- }
- if n&(n-1) == 0 { // n is power of two, can mask
- return r.Int63() & (n - 1)
- }
- max := int64((1 << 63) - 1 - (1<<63)%uint64(n))
- v := r.Int63()
- for v > max {
- v = r.Int63()
- }
- return v % n
-}
-
-// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n).
-// It panics if n <= 0.
-func (r *Rand) Int31n(n int32) int32 {
- if n <= 0 {
- panic("invalid argument to Int31n")
- }
- if n&(n-1) == 0 { // n is power of two, can mask
- return r.Int31() & (n - 1)
- }
- max := int32((1 << 31) - 1 - (1<<31)%uint32(n))
- v := r.Int31()
- for v > max {
- v = r.Int31()
- }
- return v % n
-}
-
-// int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n).
-// n must be > 0, but int31n does not check this; the caller must ensure it.
-// int31n exists because Int31n is inefficient, but Go 1 compatibility
-// requires that the stream of values produced by math/rand remain unchanged.
-// int31n can thus only be used internally, by newly introduced APIs.
-//
-// For implementation details, see:
-// https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction
-// https://lemire.me/blog/2016/06/30/fast-random-shuffling
-func (r *Rand) int31n(n int32) int32 {
- v := r.Uint32()
- prod := uint64(v) * uint64(n)
- low := uint32(prod)
- if low < uint32(n) {
- thresh := uint32(-n) % uint32(n)
- for low < thresh {
- v = r.Uint32()
- prod = uint64(v) * uint64(n)
- low = uint32(prod)
- }
- }
- return int32(prod >> 32)
-}
-
-// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n).
-// It panics if n <= 0.
-func (r *Rand) Intn(n int) int {
- if n <= 0 {
- panic("invalid argument to Intn")
- }
- if n <= 1<<31-1 {
- return int(r.Int31n(int32(n)))
- }
- return int(r.Int63n(int64(n)))
-}
-
-// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0).
-func (r *Rand) Float64() float64 {
- // A clearer, simpler implementation would be:
- // return float64(r.Int63n(1<<53)) / (1<<53)
- // However, Go 1 shipped with
- // return float64(r.Int63()) / (1 << 63)
- // and we want to preserve that value stream.
- //
- // There is one bug in the value stream: r.Int63() may be so close
- // to 1<<63 that the division rounds up to 1.0, and we've guaranteed
- // that the result is always less than 1.0.
- //
- // We tried to fix this by mapping 1.0 back to 0.0, but since float64
- // values near 0 are much denser than near 1, mapping 1 to 0 caused
- // a theoretically significant overshoot in the probability of returning 0.
- // Instead of that, if we round up to 1, just try again.
- // Getting 1 only happens 1/2⁵³ of the time, so most clients
- // will not observe it anyway.
-again:
- f := float64(r.Int63()) / (1 << 63)
- if f == 1 {
- goto again // resample; this branch is taken O(never)
- }
- return f
-}
-
-// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0).
-func (r *Rand) Float32() float32 {
- // Same rationale as in Float64: we want to preserve the Go 1 value
- // stream except we want to fix it not to return 1.0
- // This only happens 1/2²⁴ of the time (plus the 1/2⁵³ of the time in Float64).
-again:
- f := float32(r.Float64())
- if f == 1 {
- goto again // resample; this branch is taken O(very rarely)
- }
- return f
-}
-
-// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers
-// in the half-open interval [0,n).
-func (r *Rand) Perm(n int) []int {
- m := make([]int, n)
- // In the following loop, the iteration when i=0 always swaps m[0] with m[0].
- // A change to remove this useless iteration is to assign 1 to i in the init
- // statement. But Perm also effects r. Making this change will affect
- // the final state of r. So this change can't be made for compatibility
- // reasons for Go 1.
- for i := 0; i < n; i++ {
- j := r.Intn(i + 1)
- m[i] = m[j]
- m[j] = i
- }
- return m
-}
-
-// Shuffle pseudo-randomizes the order of elements.
-// n is the number of elements. Shuffle panics if n < 0.
-// swap swaps the elements with indexes i and j.
-func (r *Rand) Shuffle(n int, swap func(i, j int)) {
- if n < 0 {
- panic("invalid argument to Shuffle")
- }
-
- // Fisher-Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
- // Shuffle really ought not be called with n that doesn't fit in 32 bits.
- // Not only will it take a very long time, but with 2³¹! possible permutations,
- // there's no way that any PRNG can have a big enough internal state to
- // generate even a minuscule percentage of the possible permutations.
- // Nevertheless, the right API signature accepts an int n, so handle it as best we can.
- i := n - 1
- for ; i > 1<<31-1-1; i-- {
- j := int(r.Int63n(int64(i + 1)))
- swap(i, j)
- }
- for ; i > 0; i-- {
- j := int(r.int31n(int32(i + 1)))
- swap(i, j)
- }
-}
-
-// Read generates len(p) random bytes and writes them into p. It
-// always returns len(p) and a nil error.
-// Read should not be called concurrently with any other Rand method.
-func (r *Rand) Read(p []byte) (n int, err error) {
- if lk, ok := r.src.(*lockedSource); ok {
- return lk.read(p, &r.readVal, &r.readPos)
- }
- return read(p, r.src, &r.readVal, &r.readPos)
-}
-
-func read(p []byte, src Source, readVal *int64, readPos *int8) (n int, err error) {
- pos := *readPos
- val := *readVal
- rng, _ := src.(*rngSource)
- for n = 0; n < len(p); n++ {
- if pos == 0 {
- if rng != nil {
- val = rng.Int63()
- } else {
- val = src.Int63()
- }
- pos = 7
- }
- p[n] = byte(val)
- val >>= 8
- pos--
- }
- *readPos = pos
- *readVal = val
- return
-}
-
-/*
- * Top-level convenience functions
- */
-
-var globalRand = New(new(lockedSource))
-
-// Seed uses the provided seed value to initialize the default Source to a
-// deterministic state. Seed values that have the same remainder when
-// divided by 2³¹-1 generate the same pseudo-random sequence.
-// Seed, unlike the Rand.Seed method, is safe for concurrent use.
-//
-// If Seed is not called, the generator is seeded randomly at program startup.
-//
-// Prior to Go 1.20, the generator was seeded like Seed(1) at program startup.
-// To force the old behavior, call Seed(1) at program startup.
-// Alternately, set GODEBUG=randautoseed=0 in the environment
-// before making any calls to functions in this package.
-//
-// Deprecated: Programs that call Seed and then expect a specific sequence
-// of results from the global random source (using functions such as Int)
-// can be broken when a dependency changes how much it consumes
-// from the global random source. To avoid such breakages, programs
-// that need a specific result sequence should use NewRand(NewSource(seed))
-// to obtain a random generator that other packages cannot access.
-func Seed(seed int64) { globalRand.Seed(seed) }
-
-// Int63 returns a non-negative pseudo-random 63-bit integer as an int64
-// from the default Source.
-func Int63() int64 { return globalRand.Int63() }
-
-// Uint32 returns a pseudo-random 32-bit value as a uint32
-// from the default Source.
-func Uint32() uint32 { return globalRand.Uint32() }
-
-// Uint64 returns a pseudo-random 64-bit value as a uint64
-// from the default Source.
-func Uint64() uint64 { return globalRand.Uint64() }
-
-// Int31 returns a non-negative pseudo-random 31-bit integer as an int32
-// from the default Source.
-func Int31() int32 { return globalRand.Int31() }
-
-// Int returns a non-negative pseudo-random int from the default Source.
-func Int() int { return globalRand.Int() }
-
-// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n)
-// from the default Source.
-// It panics if n <= 0.
-func Int63n(n int64) int64 { return globalRand.Int63n(n) }
-
-// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n)
-// from the default Source.
-// It panics if n <= 0.
-func Int31n(n int32) int32 { return globalRand.Int31n(n) }
-
-// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n)
-// from the default Source.
-// It panics if n <= 0.
-func Intn(n int) int { return globalRand.Intn(n) }
-
-// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0)
-// from the default Source.
-func Float64() float64 { return globalRand.Float64() }
-
-// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0)
-// from the default Source.
-func Float32() float32 { return globalRand.Float32() }
-
-// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers
-// in the half-open interval [0,n) from the default Source.
-func Perm(n int) []int { return globalRand.Perm(n) }
-
-// Shuffle pseudo-randomizes the order of elements using the default Source.
-// n is the number of elements. Shuffle panics if n < 0.
-// swap swaps the elements with indexes i and j.
-func Shuffle(n int, swap func(i, j int)) { globalRand.Shuffle(n, swap) }
-
-// Read generates len(p) random bytes from the default Source and
-// writes them into p. It always returns len(p) and a nil error.
-// Read, unlike the Rand.Read method, is safe for concurrent use.
-//
-// Deprecated: For almost all use cases, crypto/rand.Read is more appropriate.
-func Read(p []byte) (n int, err error) { return globalRand.Read(p) }
-
-// NormFloat64 returns a normally distributed float64 in the range
-// [-math.MaxFloat64, +math.MaxFloat64] with
-// standard normal distribution (mean = 0, stddev = 1)
-// from the default Source.
-// To produce a different normal distribution, callers can
-// adjust the output using:
-//
-// sample = NormFloat64() * desiredStdDev + desiredMean
-func NormFloat64() float64 { return globalRand.NormFloat64() }
-
-// ExpFloat64 returns an exponentially distributed float64 in the range
-// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter
-// (lambda) is 1 and whose mean is 1/lambda (1) from the default Source.
-// To produce a distribution with a different rate parameter,
-// callers can adjust the output using:
-//
-// sample = ExpFloat64() / desiredRateParameter
-func ExpFloat64() float64 { return globalRand.ExpFloat64() }
-
-type lockedSource struct {
- lk sync.Mutex
- s *rngSource // nil if not yet allocated
-}
-
-//go:linkname fastrand64
-func fastrand64() uint64
-
-var randautoseed = godebug.New("randautoseed")
-
-// source returns r.s, allocating and seeding it if needed.
-// The caller must have locked r.
-func (r *lockedSource) source() *rngSource {
- if r.s == nil {
- var seed int64
- if randautoseed.Value() == "0" {
- seed = 1
- } else {
- seed = int64(fastrand64())
- }
- r.s = newSource(seed)
- }
- return r.s
-}
-
-func (r *lockedSource) Int63() (n int64) {
- r.lk.Lock()
- n = r.source().Int63()
- r.lk.Unlock()
- return
-}
-
-func (r *lockedSource) Uint64() (n uint64) {
- r.lk.Lock()
- n = r.source().Uint64()
- r.lk.Unlock()
- return
-}
-
-func (r *lockedSource) Seed(seed int64) {
- r.lk.Lock()
- r.seed(seed)
- r.lk.Unlock()
-}
-
-// seedPos implements Seed for a lockedSource without a race condition.
-func (r *lockedSource) seedPos(seed int64, readPos *int8) {
- r.lk.Lock()
- r.seed(seed)
- *readPos = 0
- r.lk.Unlock()
-}
-
-// seed seeds the underlying source.
-// The caller must have locked r.lk.
-func (r *lockedSource) seed(seed int64) {
- if r.s == nil {
- r.s = newSource(seed)
- } else {
- r.s.Seed(seed)
- }
-}
-
-// read implements Read for a lockedSource without a race condition.
-func (r *lockedSource) read(p []byte, readVal *int64, readPos *int8) (n int, err error) {
- r.lk.Lock()
- n, err = read(p, r.source(), readVal, readPos)
- r.lk.Unlock()
- return
-}
diff --git a/contrib/go/_std_1.20/src/math/rand/rng.go b/contrib/go/_std_1.20/src/math/rand/rng.go
deleted file mode 100644
index f305df1a20..0000000000
--- a/contrib/go/_std_1.20/src/math/rand/rng.go
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2009 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 rand
-
-/*
- * Uniform distribution
- *
- * algorithm by
- * DP Mitchell and JA Reeds
- */
-
-const (
- rngLen = 607
- rngTap = 273
- rngMax = 1 << 63
- rngMask = rngMax - 1
- int32max = (1 << 31) - 1
-)
-
-var (
- // rngCooked used for seeding. See gen_cooked.go for details.
- rngCooked [rngLen]int64 = [...]int64{
- -4181792142133755926, -4576982950128230565, 1395769623340756751, 5333664234075297259,
- -6347679516498800754, 9033628115061424579, 7143218595135194537, 4812947590706362721,
- 7937252194349799378, 5307299880338848416, 8209348851763925077, -7107630437535961764,
- 4593015457530856296, 8140875735541888011, -5903942795589686782, -603556388664454774,
- -7496297993371156308, 113108499721038619, 4569519971459345583, -4160538177779461077,
- -6835753265595711384, -6507240692498089696, 6559392774825876886, 7650093201692370310,
- 7684323884043752161, -8965504200858744418, -2629915517445760644, 271327514973697897,
- -6433985589514657524, 1065192797246149621, 3344507881999356393, -4763574095074709175,
- 7465081662728599889, 1014950805555097187, -4773931307508785033, -5742262670416273165,
- 2418672789110888383, 5796562887576294778, 4484266064449540171, 3738982361971787048,
- -4699774852342421385, 10530508058128498, -589538253572429690, -6598062107225984180,
- 8660405965245884302, 10162832508971942, -2682657355892958417, 7031802312784620857,
- 6240911277345944669, 831864355460801054, -1218937899312622917, 2116287251661052151,
- 2202309800992166967, 9161020366945053561, 4069299552407763864, 4936383537992622449,
- 457351505131524928, -8881176990926596454, -6375600354038175299, -7155351920868399290,
- 4368649989588021065, 887231587095185257, -3659780529968199312, -2407146836602825512,
- 5616972787034086048, -751562733459939242, 1686575021641186857, -5177887698780513806,
- -4979215821652996885, -1375154703071198421, 5632136521049761902, -8390088894796940536,
- -193645528485698615, -5979788902190688516, -4907000935050298721, -285522056888777828,
- -2776431630044341707, 1679342092332374735, 6050638460742422078, -2229851317345194226,
- -1582494184340482199, 5881353426285907985, 812786550756860885, 4541845584483343330,
- -6497901820577766722, 4980675660146853729, -4012602956251539747, -329088717864244987,
- -2896929232104691526, 1495812843684243920, -2153620458055647789, 7370257291860230865,
- -2466442761497833547, 4706794511633873654, -1398851569026877145, 8549875090542453214,
- -9189721207376179652, -7894453601103453165, 7297902601803624459, 1011190183918857495,
- -6985347000036920864, 5147159997473910359, -8326859945294252826, 2659470849286379941,
- 6097729358393448602, -7491646050550022124, -5117116194870963097, -896216826133240300,
- -745860416168701406, 5803876044675762232, -787954255994554146, -3234519180203704564,
- -4507534739750823898, -1657200065590290694, 505808562678895611, -4153273856159712438,
- -8381261370078904295, 572156825025677802, 1791881013492340891, 3393267094866038768,
- -5444650186382539299, 2352769483186201278, -7930912453007408350, -325464993179687389,
- -3441562999710612272, -6489413242825283295, 5092019688680754699, -227247482082248967,
- 4234737173186232084, 5027558287275472836, 4635198586344772304, -536033143587636457,
- 5907508150730407386, -8438615781380831356, 972392927514829904, -3801314342046600696,
- -4064951393885491917, -174840358296132583, 2407211146698877100, -1640089820333676239,
- 3940796514530962282, -5882197405809569433, 3095313889586102949, -1818050141166537098,
- 5832080132947175283, 7890064875145919662, 8184139210799583195, -8073512175445549678,
- -7758774793014564506, -4581724029666783935, 3516491885471466898, -8267083515063118116,
- 6657089965014657519, 5220884358887979358, 1796677326474620641, 5340761970648932916,
- 1147977171614181568, 5066037465548252321, 2574765911837859848, 1085848279845204775,
- -5873264506986385449, 6116438694366558490, 2107701075971293812, -7420077970933506541,
- 2469478054175558874, -1855128755834809824, -5431463669011098282, -9038325065738319171,
- -6966276280341336160, 7217693971077460129, -8314322083775271549, 7196649268545224266,
- -3585711691453906209, -5267827091426810625, 8057528650917418961, -5084103596553648165,
- -2601445448341207749, -7850010900052094367, 6527366231383600011, 3507654575162700890,
- 9202058512774729859, 1954818376891585542, -2582991129724600103, 8299563319178235687,
- -5321504681635821435, 7046310742295574065, -2376176645520785576, -7650733936335907755,
- 8850422670118399721, 3631909142291992901, 5158881091950831288, -6340413719511654215,
- 4763258931815816403, 6280052734341785344, -4979582628649810958, 2043464728020827976,
- -2678071570832690343, 4562580375758598164, 5495451168795427352, -7485059175264624713,
- 553004618757816492, 6895160632757959823, -989748114590090637, 7139506338801360852,
- -672480814466784139, 5535668688139305547, 2430933853350256242, -3821430778991574732,
- -1063731997747047009, -3065878205254005442, 7632066283658143750, 6308328381617103346,
- 3681878764086140361, 3289686137190109749, 6587997200611086848, 244714774258135476,
- -5143583659437639708, 8090302575944624335, 2945117363431356361, -8359047641006034763,
- 3009039260312620700, -793344576772241777, 401084700045993341, -1968749590416080887,
- 4707864159563588614, -3583123505891281857, -3240864324164777915, -5908273794572565703,
- -3719524458082857382, -5281400669679581926, 8118566580304798074, 3839261274019871296,
- 7062410411742090847, -8481991033874568140, 6027994129690250817, -6725542042704711878,
- -2971981702428546974, -7854441788951256975, 8809096399316380241, 6492004350391900708,
- 2462145737463489636, -8818543617934476634, -5070345602623085213, -8961586321599299868,
- -3758656652254704451, -8630661632476012791, 6764129236657751224, -709716318315418359,
- -3403028373052861600, -8838073512170985897, -3999237033416576341, -2920240395515973663,
- -2073249475545404416, 368107899140673753, -6108185202296464250, -6307735683270494757,
- 4782583894627718279, 6718292300699989587, 8387085186914375220, 3387513132024756289,
- 4654329375432538231, -292704475491394206, -3848998599978456535, 7623042350483453954,
- 7725442901813263321, 9186225467561587250, -5132344747257272453, -6865740430362196008,
- 2530936820058611833, 1636551876240043639, -3658707362519810009, 1452244145334316253,
- -7161729655835084979, -7943791770359481772, 9108481583171221009, -3200093350120725999,
- 5007630032676973346, 2153168792952589781, 6720334534964750538, -3181825545719981703,
- 3433922409283786309, 2285479922797300912, 3110614940896576130, -2856812446131932915,
- -3804580617188639299, 7163298419643543757, 4891138053923696990, 580618510277907015,
- 1684034065251686769, 4429514767357295841, -8893025458299325803, -8103734041042601133,
- 7177515271653460134, 4589042248470800257, -1530083407795771245, 143607045258444228,
- 246994305896273627, -8356954712051676521, 6473547110565816071, 3092379936208876896,
- 2058427839513754051, -4089587328327907870, 8785882556301281247, -3074039370013608197,
- -637529855400303673, 6137678347805511274, -7152924852417805802, 5708223427705576541,
- -3223714144396531304, 4358391411789012426, 325123008708389849, 6837621693887290924,
- 4843721905315627004, -3212720814705499393, -3825019837890901156, 4602025990114250980,
- 1044646352569048800, 9106614159853161675, -8394115921626182539, -4304087667751778808,
- 2681532557646850893, 3681559472488511871, -3915372517896561773, -2889241648411946534,
- -6564663803938238204, -8060058171802589521, 581945337509520675, 3648778920718647903,
- -4799698790548231394, -7602572252857820065, 220828013409515943, -1072987336855386047,
- 4287360518296753003, -4633371852008891965, 5513660857261085186, -2258542936462001533,
- -8744380348503999773, 8746140185685648781, 228500091334420247, 1356187007457302238,
- 3019253992034194581, 3152601605678500003, -8793219284148773595, 5559581553696971176,
- 4916432985369275664, -8559797105120221417, -5802598197927043732, 2868348622579915573,
- -7224052902810357288, -5894682518218493085, 2587672709781371173, -7706116723325376475,
- 3092343956317362483, -5561119517847711700, 972445599196498113, -1558506600978816441,
- 1708913533482282562, -2305554874185907314, -6005743014309462908, -6653329009633068701,
- -483583197311151195, 2488075924621352812, -4529369641467339140, -4663743555056261452,
- 2997203966153298104, 1282559373026354493, 240113143146674385, 8665713329246516443,
- 628141331766346752, -4651421219668005332, -7750560848702540400, 7596648026010355826,
- -3132152619100351065, 7834161864828164065, 7103445518877254909, 4390861237357459201,
- -4780718172614204074, -319889632007444440, 622261699494173647, -3186110786557562560,
- -8718967088789066690, -1948156510637662747, -8212195255998774408, -7028621931231314745,
- 2623071828615234808, -4066058308780939700, -5484966924888173764, -6683604512778046238,
- -6756087640505506466, 5256026990536851868, 7841086888628396109, 6640857538655893162,
- -8021284697816458310, -7109857044414059830, -1689021141511844405, -4298087301956291063,
- -4077748265377282003, -998231156719803476, 2719520354384050532, 9132346697815513771,
- 4332154495710163773, -2085582442760428892, 6994721091344268833, -2556143461985726874,
- -8567931991128098309, 59934747298466858, -3098398008776739403, -265597256199410390,
- 2332206071942466437, -7522315324568406181, 3154897383618636503, -7585605855467168281,
- -6762850759087199275, 197309393502684135, -8579694182469508493, 2543179307861934850,
- 4350769010207485119, -4468719947444108136, -7207776534213261296, -1224312577878317200,
- 4287946071480840813, 8362686366770308971, 6486469209321732151, -5605644191012979782,
- -1669018511020473564, 4450022655153542367, -7618176296641240059, -3896357471549267421,
- -4596796223304447488, -6531150016257070659, -8982326463137525940, -4125325062227681798,
- -1306489741394045544, -8338554946557245229, 5329160409530630596, 7790979528857726136,
- 4955070238059373407, -4304834761432101506, -6215295852904371179, 3007769226071157901,
- -6753025801236972788, 8928702772696731736, 7856187920214445904, -4748497451462800923,
- 7900176660600710914, -7082800908938549136, -6797926979589575837, -6737316883512927978,
- 4186670094382025798, 1883939007446035042, -414705992779907823, 3734134241178479257,
- 4065968871360089196, 6953124200385847784, -7917685222115876751, -7585632937840318161,
- -5567246375906782599, -5256612402221608788, 3106378204088556331, -2894472214076325998,
- 4565385105440252958, 1979884289539493806, -6891578849933910383, 3783206694208922581,
- 8464961209802336085, 2843963751609577687, 3030678195484896323, -4429654462759003204,
- 4459239494808162889, 402587895800087237, 8057891408711167515, 4541888170938985079,
- 1042662272908816815, -3666068979732206850, 2647678726283249984, 2144477441549833761,
- -3417019821499388721, -2105601033380872185, 5916597177708541638, -8760774321402454447,
- 8833658097025758785, 5970273481425315300, 563813119381731307, -6455022486202078793,
- 1598828206250873866, -4016978389451217698, -2988328551145513985, -6071154634840136312,
- 8469693267274066490, 125672920241807416, -3912292412830714870, -2559617104544284221,
- -486523741806024092, -4735332261862713930, 5923302823487327109, -9082480245771672572,
- -1808429243461201518, 7990420780896957397, 4317817392807076702, 3625184369705367340,
- -6482649271566653105, -3480272027152017464, -3225473396345736649, -368878695502291645,
- -3981164001421868007, -8522033136963788610, 7609280429197514109, 3020985755112334161,
- -2572049329799262942, 2635195723621160615, 5144520864246028816, -8188285521126945980,
- 1567242097116389047, 8172389260191636581, -2885551685425483535, -7060359469858316883,
- -6480181133964513127, -7317004403633452381, 6011544915663598137, 5932255307352610768,
- 2241128460406315459, -8327867140638080220, 3094483003111372717, 4583857460292963101,
- 9079887171656594975, -384082854924064405, -3460631649611717935, 4225072055348026230,
- -7385151438465742745, 3801620336801580414, -399845416774701952, -7446754431269675473,
- 7899055018877642622, 5421679761463003041, 5521102963086275121, -4975092593295409910,
- 8735487530905098534, -7462844945281082830, -2080886987197029914, -1000715163927557685,
- -4253840471931071485, -5828896094657903328, 6424174453260338141, 359248545074932887,
- -5949720754023045210, -2426265837057637212, 3030918217665093212, -9077771202237461772,
- -3186796180789149575, 740416251634527158, -2142944401404840226, 6951781370868335478,
- 399922722363687927, -8928469722407522623, -1378421100515597285, -8343051178220066766,
- -3030716356046100229, -8811767350470065420, 9026808440365124461, 6440783557497587732,
- 4615674634722404292, 539897290441580544, 2096238225866883852, 8751955639408182687,
- -7316147128802486205, 7381039757301768559, 6157238513393239656, -1473377804940618233,
- 8629571604380892756, 5280433031239081479, 7101611890139813254, 2479018537985767835,
- 7169176924412769570, -1281305539061572506, -7865612307799218120, 2278447439451174845,
- 3625338785743880657, 6477479539006708521, 8976185375579272206, -3712000482142939688,
- 1326024180520890843, 7537449876596048829, 5464680203499696154, 3189671183162196045,
- 6346751753565857109, -8982212049534145501, -6127578587196093755, -245039190118465649,
- -6320577374581628592, 7208698530190629697, 7276901792339343736, -7490986807540332668,
- 4133292154170828382, 2918308698224194548, -7703910638917631350, -3929437324238184044,
- -4300543082831323144, -6344160503358350167, 5896236396443472108, -758328221503023383,
- -1894351639983151068, -307900319840287220, -6278469401177312761, -2171292963361310674,
- 8382142935188824023, 9103922860780351547, 4152330101494654406,
- }
-)
-
-type rngSource struct {
- tap int // index into vec
- feed int // index into vec
- vec [rngLen]int64 // current feedback register
-}
-
-// seed rng x[n+1] = 48271 * x[n] mod (2**31 - 1)
-func seedrand(x int32) int32 {
- const (
- A = 48271
- Q = 44488
- R = 3399
- )
-
- hi := x / Q
- lo := x % Q
- x = A*lo - R*hi
- if x < 0 {
- x += int32max
- }
- return x
-}
-
-// Seed uses the provided seed value to initialize the generator to a deterministic state.
-func (rng *rngSource) Seed(seed int64) {
- rng.tap = 0
- rng.feed = rngLen - rngTap
-
- seed = seed % int32max
- if seed < 0 {
- seed += int32max
- }
- if seed == 0 {
- seed = 89482311
- }
-
- x := int32(seed)
- for i := -20; i < rngLen; i++ {
- x = seedrand(x)
- if i >= 0 {
- var u int64
- u = int64(x) << 40
- x = seedrand(x)
- u ^= int64(x) << 20
- x = seedrand(x)
- u ^= int64(x)
- u ^= rngCooked[i]
- rng.vec[i] = u
- }
- }
-}
-
-// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
-func (rng *rngSource) Int63() int64 {
- return int64(rng.Uint64() & rngMask)
-}
-
-// Uint64 returns a non-negative pseudo-random 64-bit integer as an uint64.
-func (rng *rngSource) Uint64() uint64 {
- rng.tap--
- if rng.tap < 0 {
- rng.tap += rngLen
- }
-
- rng.feed--
- if rng.feed < 0 {
- rng.feed += rngLen
- }
-
- x := rng.vec[rng.feed] + rng.vec[rng.tap]
- rng.vec[rng.feed] = x
- return uint64(x)
-}
diff --git a/contrib/go/_std_1.20/src/math/rand/ya.make b/contrib/go/_std_1.20/src/math/rand/ya.make
deleted file mode 100644
index d0b0250cdc..0000000000
--- a/contrib/go/_std_1.20/src/math/rand/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- exp.go
- normal.go
- rand.go
- rng.go
- zipf.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/math/ya.make b/contrib/go/_std_1.20/src/math/ya.make
deleted file mode 100644
index a4e405aa16..0000000000
--- a/contrib/go/_std_1.20/src/math/ya.make
+++ /dev/null
@@ -1,90 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- abs.go
- acosh.go
- asin.go
- asinh.go
- atan.go
- atan2.go
- atanh.go
- bits.go
- cbrt.go
- const.go
- copysign.go
- dim.go
- dim_asm.go
- erf.go
- erfinv.go
- exp.go
- exp_asm.go
- expm1.go
- floor.go
- floor_asm.go
- fma.go
- frexp.go
- gamma.go
- hypot.go
- j0.go
- j1.go
- jn.go
- ldexp.go
- lgamma.go
- log.go
- log10.go
- log1p.go
- logb.go
- mod.go
- modf.go
- nextafter.go
- pow.go
- pow10.go
- remainder.go
- signbit.go
- sin.go
- sincos.go
- sinh.go
- sqrt.go
- stubs.go
- tan.go
- tanh.go
- trig_reduce.go
- unsafe.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- dim_arm64.s
- exp2_asm.go
- exp_arm64.s
- floor_arm64.s
- hypot_noasm.go
- log_stub.go
- modf_arm64.s
- modf_asm.go
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- dim_amd64.s
- exp2_noasm.go
- exp_amd64.go
- exp_amd64.s
- floor_amd64.s
- hypot_amd64.s
- hypot_asm.go
- log_amd64.s
- log_asm.go
- modf_noasm.go
- )
-ENDIF()
-
-END()
-
-RECURSE(
- big
- bits
- cmplx
- rand
-)
diff --git a/contrib/go/_std_1.20/src/mime/multipart/formdata.go b/contrib/go/_std_1.20/src/mime/multipart/formdata.go
deleted file mode 100644
index 267cfe84ca..0000000000
--- a/contrib/go/_std_1.20/src/mime/multipart/formdata.go
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright 2011 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 multipart
-
-import (
- "bytes"
- "errors"
- "internal/godebug"
- "io"
- "math"
- "net/textproto"
- "os"
- "strconv"
-)
-
-// ErrMessageTooLarge is returned by ReadForm if the message form
-// data is too large to be processed.
-var ErrMessageTooLarge = errors.New("multipart: message too large")
-
-// TODO(adg,bradfitz): find a way to unify the DoS-prevention strategy here
-// with that of the http package's ParseForm.
-
-// ReadForm parses an entire multipart message whose parts have
-// a Content-Disposition of "form-data".
-// It stores up to maxMemory bytes + 10MB (reserved for non-file parts)
-// in memory. File parts which can't be stored in memory will be stored on
-// disk in temporary files.
-// It returns ErrMessageTooLarge if all non-file parts can't be stored in
-// memory.
-func (r *Reader) ReadForm(maxMemory int64) (*Form, error) {
- return r.readForm(maxMemory)
-}
-
-var (
- multipartFiles = godebug.New("multipartfiles")
- multipartMaxParts = godebug.New("multipartmaxparts")
-)
-
-func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) {
- form := &Form{make(map[string][]string), make(map[string][]*FileHeader)}
- var (
- file *os.File
- fileOff int64
- )
- numDiskFiles := 0
- combineFiles := true
- if multipartFiles.Value() == "distinct" {
- combineFiles = false
- }
- maxParts := 1000
- if s := multipartMaxParts.Value(); s != "" {
- if v, err := strconv.Atoi(s); err == nil && v >= 0 {
- maxParts = v
- }
- }
- maxHeaders := maxMIMEHeaders()
-
- defer func() {
- if file != nil {
- if cerr := file.Close(); err == nil {
- err = cerr
- }
- }
- if combineFiles && numDiskFiles > 1 {
- for _, fhs := range form.File {
- for _, fh := range fhs {
- fh.tmpshared = true
- }
- }
- }
- if err != nil {
- form.RemoveAll()
- if file != nil {
- os.Remove(file.Name())
- }
- }
- }()
-
- // maxFileMemoryBytes is the maximum bytes of file data we will store in memory.
- // Data past this limit is written to disk.
- // This limit strictly applies to content, not metadata (filenames, MIME headers, etc.),
- // since metadata is always stored in memory, not disk.
- //
- // maxMemoryBytes is the maximum bytes we will store in memory, including file content,
- // non-file part values, metdata, and map entry overhead.
- //
- // We reserve an additional 10 MB in maxMemoryBytes for non-file data.
- //
- // The relationship between these parameters, as well as the overly-large and
- // unconfigurable 10 MB added on to maxMemory, is unfortunate but difficult to change
- // within the constraints of the API as documented.
- maxFileMemoryBytes := maxMemory
- maxMemoryBytes := maxMemory + int64(10<<20)
- if maxMemoryBytes <= 0 {
- if maxMemory < 0 {
- maxMemoryBytes = 0
- } else {
- maxMemoryBytes = math.MaxInt64
- }
- }
- var copyBuf []byte
- for {
- p, err := r.nextPart(false, maxMemoryBytes, maxHeaders)
- if err == io.EOF {
- break
- }
- if err != nil {
- return nil, err
- }
- if maxParts <= 0 {
- return nil, ErrMessageTooLarge
- }
- maxParts--
-
- name := p.FormName()
- if name == "" {
- continue
- }
- filename := p.FileName()
-
- // Multiple values for the same key (one map entry, longer slice) are cheaper
- // than the same number of values for different keys (many map entries), but
- // using a consistent per-value cost for overhead is simpler.
- const mapEntryOverhead = 200
- maxMemoryBytes -= int64(len(name))
- maxMemoryBytes -= mapEntryOverhead
- if maxMemoryBytes < 0 {
- // We can't actually take this path, since nextPart would already have
- // rejected the MIME headers for being too large. Check anyway.
- return nil, ErrMessageTooLarge
- }
-
- var b bytes.Buffer
-
- if filename == "" {
- // value, store as string in memory
- n, err := io.CopyN(&b, p, maxMemoryBytes+1)
- if err != nil && err != io.EOF {
- return nil, err
- }
- maxMemoryBytes -= n
- if maxMemoryBytes < 0 {
- return nil, ErrMessageTooLarge
- }
- form.Value[name] = append(form.Value[name], b.String())
- continue
- }
-
- // file, store in memory or on disk
- const fileHeaderSize = 100
- maxMemoryBytes -= mimeHeaderSize(p.Header)
- maxMemoryBytes -= mapEntryOverhead
- maxMemoryBytes -= fileHeaderSize
- if maxMemoryBytes < 0 {
- return nil, ErrMessageTooLarge
- }
- for _, v := range p.Header {
- maxHeaders -= int64(len(v))
- }
- fh := &FileHeader{
- Filename: filename,
- Header: p.Header,
- }
- n, err := io.CopyN(&b, p, maxFileMemoryBytes+1)
- if err != nil && err != io.EOF {
- return nil, err
- }
- if n > maxFileMemoryBytes {
- if file == nil {
- file, err = os.CreateTemp(r.tempDir, "multipart-")
- if err != nil {
- return nil, err
- }
- }
- numDiskFiles++
- if _, err := file.Write(b.Bytes()); err != nil {
- return nil, err
- }
- if copyBuf == nil {
- copyBuf = make([]byte, 32*1024) // same buffer size as io.Copy uses
- }
- // os.File.ReadFrom will allocate its own copy buffer if we let io.Copy use it.
- type writerOnly struct{ io.Writer }
- remainingSize, err := io.CopyBuffer(writerOnly{file}, p, copyBuf)
- if err != nil {
- return nil, err
- }
- fh.tmpfile = file.Name()
- fh.Size = int64(b.Len()) + remainingSize
- fh.tmpoff = fileOff
- fileOff += fh.Size
- if !combineFiles {
- if err := file.Close(); err != nil {
- return nil, err
- }
- file = nil
- }
- } else {
- fh.content = b.Bytes()
- fh.Size = int64(len(fh.content))
- maxFileMemoryBytes -= n
- maxMemoryBytes -= n
- }
- form.File[name] = append(form.File[name], fh)
- }
-
- return form, nil
-}
-
-func mimeHeaderSize(h textproto.MIMEHeader) (size int64) {
- size = 400
- for k, vs := range h {
- size += int64(len(k))
- size += 200 // map entry overhead
- for _, v := range vs {
- size += int64(len(v))
- }
- }
- return size
-}
-
-// Form is a parsed multipart form.
-// Its File parts are stored either in memory or on disk,
-// and are accessible via the *FileHeader's Open method.
-// Its Value parts are stored as strings.
-// Both are keyed by field name.
-type Form struct {
- Value map[string][]string
- File map[string][]*FileHeader
-}
-
-// RemoveAll removes any temporary files associated with a Form.
-func (f *Form) RemoveAll() error {
- var err error
- for _, fhs := range f.File {
- for _, fh := range fhs {
- if fh.tmpfile != "" {
- e := os.Remove(fh.tmpfile)
- if e != nil && !errors.Is(e, os.ErrNotExist) && err == nil {
- err = e
- }
- }
- }
- }
- return err
-}
-
-// A FileHeader describes a file part of a multipart request.
-type FileHeader struct {
- Filename string
- Header textproto.MIMEHeader
- Size int64
-
- content []byte
- tmpfile string
- tmpoff int64
- tmpshared bool
-}
-
-// Open opens and returns the FileHeader's associated File.
-func (fh *FileHeader) Open() (File, error) {
- if b := fh.content; b != nil {
- r := io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b)))
- return sectionReadCloser{r, nil}, nil
- }
- if fh.tmpshared {
- f, err := os.Open(fh.tmpfile)
- if err != nil {
- return nil, err
- }
- r := io.NewSectionReader(f, fh.tmpoff, fh.Size)
- return sectionReadCloser{r, f}, nil
- }
- return os.Open(fh.tmpfile)
-}
-
-// File is an interface to access the file part of a multipart message.
-// Its contents may be either stored in memory or on disk.
-// If stored on disk, the File's underlying concrete type will be an *os.File.
-type File interface {
- io.Reader
- io.ReaderAt
- io.Seeker
- io.Closer
-}
-
-// helper types to turn a []byte into a File
-
-type sectionReadCloser struct {
- *io.SectionReader
- io.Closer
-}
-
-func (rc sectionReadCloser) Close() error {
- if rc.Closer != nil {
- return rc.Closer.Close()
- }
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/mime/multipart/multipart.go b/contrib/go/_std_1.20/src/mime/multipart/multipart.go
deleted file mode 100644
index 066aa70286..0000000000
--- a/contrib/go/_std_1.20/src/mime/multipart/multipart.go
+++ /dev/null
@@ -1,487 +0,0 @@
-// Copyright 2010 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 multipart implements MIME multipart parsing, as defined in RFC
-2046.
-
-The implementation is sufficient for HTTP (RFC 2388) and the multipart
-bodies generated by popular browsers.
-
-# Limits
-
-To protect against malicious inputs, this package sets limits on the size
-of the MIME data it processes.
-
-Reader.NextPart and Reader.NextRawPart limit the number of headers in a
-part to 10000 and Reader.ReadForm limits the total number of headers in all
-FileHeaders to 10000.
-These limits may be adjusted with the GODEBUG=multipartmaxheaders=<values>
-setting.
-
-Reader.ReadForm further limits the number of parts in a form to 1000.
-This limit may be adjusted with the GODEBUG=multipartmaxparts=<value>
-setting.
-*/
-package multipart
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "internal/godebug"
- "io"
- "mime"
- "mime/quotedprintable"
- "net/textproto"
- "path/filepath"
- "strconv"
- "strings"
-)
-
-var emptyParams = make(map[string]string)
-
-// This constant needs to be at least 76 for this package to work correctly.
-// This is because \r\n--separator_of_len_70- would fill the buffer and it
-// wouldn't be safe to consume a single byte from it.
-const peekBufferSize = 4096
-
-// A Part represents a single part in a multipart body.
-type Part struct {
- // The headers of the body, if any, with the keys canonicalized
- // in the same fashion that the Go http.Request headers are.
- // For example, "foo-bar" changes case to "Foo-Bar"
- Header textproto.MIMEHeader
-
- mr *Reader
-
- disposition string
- dispositionParams map[string]string
-
- // r is either a reader directly reading from mr, or it's a
- // wrapper around such a reader, decoding the
- // Content-Transfer-Encoding
- r io.Reader
-
- n int // known data bytes waiting in mr.bufReader
- total int64 // total data bytes read already
- err error // error to return when n == 0
- readErr error // read error observed from mr.bufReader
-}
-
-// FormName returns the name parameter if p has a Content-Disposition
-// of type "form-data". Otherwise it returns the empty string.
-func (p *Part) FormName() string {
- // See https://tools.ietf.org/html/rfc2183 section 2 for EBNF
- // of Content-Disposition value format.
- if p.dispositionParams == nil {
- p.parseContentDisposition()
- }
- if p.disposition != "form-data" {
- return ""
- }
- return p.dispositionParams["name"]
-}
-
-// FileName returns the filename parameter of the Part's Content-Disposition
-// header. If not empty, the filename is passed through filepath.Base (which is
-// platform dependent) before being returned.
-func (p *Part) FileName() string {
- if p.dispositionParams == nil {
- p.parseContentDisposition()
- }
- filename := p.dispositionParams["filename"]
- if filename == "" {
- return ""
- }
- // RFC 7578, Section 4.2 requires that if a filename is provided, the
- // directory path information must not be used.
- return filepath.Base(filename)
-}
-
-func (p *Part) parseContentDisposition() {
- v := p.Header.Get("Content-Disposition")
- var err error
- p.disposition, p.dispositionParams, err = mime.ParseMediaType(v)
- if err != nil {
- p.dispositionParams = emptyParams
- }
-}
-
-// NewReader creates a new multipart Reader reading from r using the
-// given MIME boundary.
-//
-// The boundary is usually obtained from the "boundary" parameter of
-// the message's "Content-Type" header. Use mime.ParseMediaType to
-// parse such headers.
-func NewReader(r io.Reader, boundary string) *Reader {
- b := []byte("\r\n--" + boundary + "--")
- return &Reader{
- bufReader: bufio.NewReaderSize(&stickyErrorReader{r: r}, peekBufferSize),
- nl: b[:2],
- nlDashBoundary: b[:len(b)-2],
- dashBoundaryDash: b[2:],
- dashBoundary: b[2 : len(b)-2],
- }
-}
-
-// stickyErrorReader is an io.Reader which never calls Read on its
-// underlying Reader once an error has been seen. (the io.Reader
-// interface's contract promises nothing about the return values of
-// Read calls after an error, yet this package does do multiple Reads
-// after error)
-type stickyErrorReader struct {
- r io.Reader
- err error
-}
-
-func (r *stickyErrorReader) Read(p []byte) (n int, _ error) {
- if r.err != nil {
- return 0, r.err
- }
- n, r.err = r.r.Read(p)
- return n, r.err
-}
-
-func newPart(mr *Reader, rawPart bool, maxMIMEHeaderSize, maxMIMEHeaders int64) (*Part, error) {
- bp := &Part{
- Header: make(map[string][]string),
- mr: mr,
- }
- if err := bp.populateHeaders(maxMIMEHeaderSize, maxMIMEHeaders); err != nil {
- return nil, err
- }
- bp.r = partReader{bp}
-
- // rawPart is used to switch between Part.NextPart and Part.NextRawPart.
- if !rawPart {
- const cte = "Content-Transfer-Encoding"
- if strings.EqualFold(bp.Header.Get(cte), "quoted-printable") {
- bp.Header.Del(cte)
- bp.r = quotedprintable.NewReader(bp.r)
- }
- }
- return bp, nil
-}
-
-func (p *Part) populateHeaders(maxMIMEHeaderSize, maxMIMEHeaders int64) error {
- r := textproto.NewReader(p.mr.bufReader)
- header, err := readMIMEHeader(r, maxMIMEHeaderSize, maxMIMEHeaders)
- if err == nil {
- p.Header = header
- }
- // TODO: Add a distinguishable error to net/textproto.
- if err != nil && err.Error() == "message too large" {
- err = ErrMessageTooLarge
- }
- return err
-}
-
-// Read reads the body of a part, after its headers and before the
-// next part (if any) begins.
-func (p *Part) Read(d []byte) (n int, err error) {
- return p.r.Read(d)
-}
-
-// partReader implements io.Reader by reading raw bytes directly from the
-// wrapped *Part, without doing any Transfer-Encoding decoding.
-type partReader struct {
- p *Part
-}
-
-func (pr partReader) Read(d []byte) (int, error) {
- p := pr.p
- br := p.mr.bufReader
-
- // Read into buffer until we identify some data to return,
- // or we find a reason to stop (boundary or read error).
- for p.n == 0 && p.err == nil {
- peek, _ := br.Peek(br.Buffered())
- p.n, p.err = scanUntilBoundary(peek, p.mr.dashBoundary, p.mr.nlDashBoundary, p.total, p.readErr)
- if p.n == 0 && p.err == nil {
- // Force buffered I/O to read more into buffer.
- _, p.readErr = br.Peek(len(peek) + 1)
- if p.readErr == io.EOF {
- p.readErr = io.ErrUnexpectedEOF
- }
- }
- }
-
- // Read out from "data to return" part of buffer.
- if p.n == 0 {
- return 0, p.err
- }
- n := len(d)
- if n > p.n {
- n = p.n
- }
- n, _ = br.Read(d[:n])
- p.total += int64(n)
- p.n -= n
- if p.n == 0 {
- return n, p.err
- }
- return n, nil
-}
-
-// scanUntilBoundary scans buf to identify how much of it can be safely
-// returned as part of the Part body.
-// dashBoundary is "--boundary".
-// nlDashBoundary is "\r\n--boundary" or "\n--boundary", depending on what mode we are in.
-// The comments below (and the name) assume "\n--boundary", but either is accepted.
-// total is the number of bytes read out so far. If total == 0, then a leading "--boundary" is recognized.
-// readErr is the read error, if any, that followed reading the bytes in buf.
-// scanUntilBoundary returns the number of data bytes from buf that can be
-// returned as part of the Part body and also the error to return (if any)
-// once those data bytes are done.
-func scanUntilBoundary(buf, dashBoundary, nlDashBoundary []byte, total int64, readErr error) (int, error) {
- if total == 0 {
- // At beginning of body, allow dashBoundary.
- if bytes.HasPrefix(buf, dashBoundary) {
- switch matchAfterPrefix(buf, dashBoundary, readErr) {
- case -1:
- return len(dashBoundary), nil
- case 0:
- return 0, nil
- case +1:
- return 0, io.EOF
- }
- }
- if bytes.HasPrefix(dashBoundary, buf) {
- return 0, readErr
- }
- }
-
- // Search for "\n--boundary".
- if i := bytes.Index(buf, nlDashBoundary); i >= 0 {
- switch matchAfterPrefix(buf[i:], nlDashBoundary, readErr) {
- case -1:
- return i + len(nlDashBoundary), nil
- case 0:
- return i, nil
- case +1:
- return i, io.EOF
- }
- }
- if bytes.HasPrefix(nlDashBoundary, buf) {
- return 0, readErr
- }
-
- // Otherwise, anything up to the final \n is not part of the boundary
- // and so must be part of the body.
- // Also if the section from the final \n onward is not a prefix of the boundary,
- // it too must be part of the body.
- i := bytes.LastIndexByte(buf, nlDashBoundary[0])
- if i >= 0 && bytes.HasPrefix(nlDashBoundary, buf[i:]) {
- return i, nil
- }
- return len(buf), readErr
-}
-
-// matchAfterPrefix checks whether buf should be considered to match the boundary.
-// The prefix is "--boundary" or "\r\n--boundary" or "\n--boundary",
-// and the caller has verified already that bytes.HasPrefix(buf, prefix) is true.
-//
-// matchAfterPrefix returns +1 if the buffer does match the boundary,
-// meaning the prefix is followed by a double dash, space, tab, cr, nl,
-// or end of input.
-// It returns -1 if the buffer definitely does NOT match the boundary,
-// meaning the prefix is followed by some other character.
-// For example, "--foobar" does not match "--foo".
-// It returns 0 more input needs to be read to make the decision,
-// meaning that len(buf) == len(prefix) and readErr == nil.
-func matchAfterPrefix(buf, prefix []byte, readErr error) int {
- if len(buf) == len(prefix) {
- if readErr != nil {
- return +1
- }
- return 0
- }
- c := buf[len(prefix)]
-
- if c == ' ' || c == '\t' || c == '\r' || c == '\n' {
- return +1
- }
-
- // Try to detect boundaryDash
- if c == '-' {
- if len(buf) == len(prefix)+1 {
- if readErr != nil {
- // Prefix + "-" does not match
- return -1
- }
- return 0
- }
- if buf[len(prefix)+1] == '-' {
- return +1
- }
- }
-
- return -1
-}
-
-func (p *Part) Close() error {
- io.Copy(io.Discard, p)
- return nil
-}
-
-// Reader is an iterator over parts in a MIME multipart body.
-// Reader's underlying parser consumes its input as needed. Seeking
-// isn't supported.
-type Reader struct {
- bufReader *bufio.Reader
- tempDir string // used in tests
-
- currentPart *Part
- partsRead int
-
- nl []byte // "\r\n" or "\n" (set after seeing first boundary line)
- nlDashBoundary []byte // nl + "--boundary"
- dashBoundaryDash []byte // "--boundary--"
- dashBoundary []byte // "--boundary"
-}
-
-// maxMIMEHeaderSize is the maximum size of a MIME header we will parse,
-// including header keys, values, and map overhead.
-const maxMIMEHeaderSize = 10 << 20
-
-// multipartMaxHeaders is the maximum number of header entries NextPart will return,
-// as well as the maximum combined total of header entries Reader.ReadForm will return
-// in FileHeaders.
-var multipartMaxHeaders = godebug.New("multipartmaxheaders")
-
-func maxMIMEHeaders() int64 {
- if s := multipartMaxHeaders.Value(); s != "" {
- if v, err := strconv.ParseInt(s, 10, 64); err == nil && v >= 0 {
- return v
- }
- }
- return 10000
-}
-
-// NextPart returns the next part in the multipart or an error.
-// When there are no more parts, the error io.EOF is returned.
-//
-// As a special case, if the "Content-Transfer-Encoding" header
-// has a value of "quoted-printable", that header is instead
-// hidden and the body is transparently decoded during Read calls.
-func (r *Reader) NextPart() (*Part, error) {
- return r.nextPart(false, maxMIMEHeaderSize, maxMIMEHeaders())
-}
-
-// NextRawPart returns the next part in the multipart or an error.
-// When there are no more parts, the error io.EOF is returned.
-//
-// Unlike NextPart, it does not have special handling for
-// "Content-Transfer-Encoding: quoted-printable".
-func (r *Reader) NextRawPart() (*Part, error) {
- return r.nextPart(true, maxMIMEHeaderSize, maxMIMEHeaders())
-}
-
-func (r *Reader) nextPart(rawPart bool, maxMIMEHeaderSize, maxMIMEHeaders int64) (*Part, error) {
- if r.currentPart != nil {
- r.currentPart.Close()
- }
- if string(r.dashBoundary) == "--" {
- return nil, fmt.Errorf("multipart: boundary is empty")
- }
- expectNewPart := false
- for {
- line, err := r.bufReader.ReadSlice('\n')
-
- if err == io.EOF && r.isFinalBoundary(line) {
- // If the buffer ends in "--boundary--" without the
- // trailing "\r\n", ReadSlice will return an error
- // (since it's missing the '\n'), but this is a valid
- // multipart EOF so we need to return io.EOF instead of
- // a fmt-wrapped one.
- return nil, io.EOF
- }
- if err != nil {
- return nil, fmt.Errorf("multipart: NextPart: %w", err)
- }
-
- if r.isBoundaryDelimiterLine(line) {
- r.partsRead++
- bp, err := newPart(r, rawPart, maxMIMEHeaderSize, maxMIMEHeaders)
- if err != nil {
- return nil, err
- }
- r.currentPart = bp
- return bp, nil
- }
-
- if r.isFinalBoundary(line) {
- // Expected EOF
- return nil, io.EOF
- }
-
- if expectNewPart {
- return nil, fmt.Errorf("multipart: expecting a new Part; got line %q", string(line))
- }
-
- if r.partsRead == 0 {
- // skip line
- continue
- }
-
- // Consume the "\n" or "\r\n" separator between the
- // body of the previous part and the boundary line we
- // now expect will follow. (either a new part or the
- // end boundary)
- if bytes.Equal(line, r.nl) {
- expectNewPart = true
- continue
- }
-
- return nil, fmt.Errorf("multipart: unexpected line in Next(): %q", line)
- }
-}
-
-// isFinalBoundary reports whether line is the final boundary line
-// indicating that all parts are over.
-// It matches `^--boundary--[ \t]*(\r\n)?$`
-func (r *Reader) isFinalBoundary(line []byte) bool {
- if !bytes.HasPrefix(line, r.dashBoundaryDash) {
- return false
- }
- rest := line[len(r.dashBoundaryDash):]
- rest = skipLWSPChar(rest)
- return len(rest) == 0 || bytes.Equal(rest, r.nl)
-}
-
-func (r *Reader) isBoundaryDelimiterLine(line []byte) (ret bool) {
- // https://tools.ietf.org/html/rfc2046#section-5.1
- // The boundary delimiter line is then defined as a line
- // consisting entirely of two hyphen characters ("-",
- // decimal value 45) followed by the boundary parameter
- // value from the Content-Type header field, optional linear
- // whitespace, and a terminating CRLF.
- if !bytes.HasPrefix(line, r.dashBoundary) {
- return false
- }
- rest := line[len(r.dashBoundary):]
- rest = skipLWSPChar(rest)
-
- // On the first part, see our lines are ending in \n instead of \r\n
- // and switch into that mode if so. This is a violation of the spec,
- // but occurs in practice.
- if r.partsRead == 0 && len(rest) == 1 && rest[0] == '\n' {
- r.nl = r.nl[1:]
- r.nlDashBoundary = r.nlDashBoundary[1:]
- }
- return bytes.Equal(rest, r.nl)
-}
-
-// skipLWSPChar returns b with leading spaces and tabs removed.
-// RFC 822 defines:
-//
-// LWSP-char = SPACE / HTAB
-func skipLWSPChar(b []byte) []byte {
- for len(b) > 0 && (b[0] == ' ' || b[0] == '\t') {
- b = b[1:]
- }
- return b
-}
diff --git a/contrib/go/_std_1.20/src/mime/multipart/ya.make b/contrib/go/_std_1.20/src/mime/multipart/ya.make
deleted file mode 100644
index 6ddb61c0f0..0000000000
--- a/contrib/go/_std_1.20/src/mime/multipart/ya.make
+++ /dev/null
@@ -1,10 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- formdata.go
- multipart.go
- readmimeheader.go
- writer.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/mime/quotedprintable/ya.make b/contrib/go/_std_1.20/src/mime/quotedprintable/ya.make
deleted file mode 100644
index 262cbbb45f..0000000000
--- a/contrib/go/_std_1.20/src/mime/quotedprintable/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- reader.go
- writer.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/mime/type_unix.go b/contrib/go/_std_1.20/src/mime/type_unix.go
deleted file mode 100644
index 649d9001e3..0000000000
--- a/contrib/go/_std_1.20/src/mime/type_unix.go
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2010 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.
-
-//go:build unix || (js && wasm)
-
-package mime
-
-import (
- "bufio"
- "os"
- "strings"
-)
-
-func init() {
- osInitMime = initMimeUnix
-}
-
-// See https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-0.21.html
-// for the FreeDesktop Shared MIME-info Database specification.
-var mimeGlobs = []string{
- "/usr/local/share/mime/globs2",
- "/usr/share/mime/globs2",
-}
-
-// Common locations for mime.types files on unix.
-var typeFiles = []string{
- "/etc/mime.types",
- "/etc/apache2/mime.types",
- "/etc/apache/mime.types",
- "/etc/httpd/conf/mime.types",
-}
-
-func loadMimeGlobsFile(filename string) error {
- f, err := os.Open(filename)
- if err != nil {
- return err
- }
- defer f.Close()
-
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- // Each line should be of format: weight:mimetype:glob[:morefields...]
- fields := strings.Split(scanner.Text(), ":")
- if len(fields) < 3 || len(fields[0]) < 1 || len(fields[2]) < 3 {
- continue
- } else if fields[0][0] == '#' || fields[2][0] != '*' || fields[2][1] != '.' {
- continue
- }
-
- extension := fields[2][1:]
- if strings.ContainsAny(extension, "?*[") {
- // Not a bare extension, but a glob. Ignore for now:
- // - we do not have an implementation for this glob
- // syntax (translation to path/filepath.Match could
- // be possible)
- // - support for globs with weight ordering would have
- // performance impact to all lookups to support the
- // rarely seen glob entries
- // - trying to match glob metacharacters literally is
- // not useful
- continue
- }
- if _, ok := mimeTypes.Load(extension); ok {
- // We've already seen this extension.
- // The file is in weight order, so we keep
- // the first entry that we see.
- continue
- }
-
- setExtensionType(extension, fields[1])
- }
- if err := scanner.Err(); err != nil {
- panic(err)
- }
- return nil
-}
-
-func loadMimeFile(filename string) {
- f, err := os.Open(filename)
- if err != nil {
- return
- }
- defer f.Close()
-
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- fields := strings.Fields(scanner.Text())
- if len(fields) <= 1 || fields[0][0] == '#' {
- continue
- }
- mimeType := fields[0]
- for _, ext := range fields[1:] {
- if ext[0] == '#' {
- break
- }
- setExtensionType("."+ext, mimeType)
- }
- }
- if err := scanner.Err(); err != nil {
- panic(err)
- }
-}
-
-func initMimeUnix() {
- for _, filename := range mimeGlobs {
- if err := loadMimeGlobsFile(filename); err == nil {
- return // Stop checking more files if mimetype database is found.
- }
- }
-
- // Fallback if no system-generated mimetype database exists.
- for _, filename := range typeFiles {
- loadMimeFile(filename)
- }
-}
-
-func initMimeForTests() map[string]string {
- mimeGlobs = []string{""}
- typeFiles = []string{"testdata/test.types"}
- return map[string]string{
- ".T1": "application/test",
- ".t2": "text/test; charset=utf-8",
- ".png": "image/png",
- }
-}
diff --git a/contrib/go/_std_1.20/src/mime/ya.make b/contrib/go/_std_1.20/src/mime/ya.make
deleted file mode 100644
index f7d0c91778..0000000000
--- a/contrib/go/_std_1.20/src/mime/ya.make
+++ /dev/null
@@ -1,33 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- encodedword.go
- grammar.go
- mediatype.go
- type.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- type_unix.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- type_unix.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- type_windows.go
- )
-ENDIF()
-
-END()
-
-RECURSE(
- multipart
- quotedprintable
-)
diff --git a/contrib/go/_std_1.20/src/net/cgo_unix.go b/contrib/go/_std_1.20/src/net/cgo_unix.go
deleted file mode 100644
index 6a2c369c66..0000000000
--- a/contrib/go/_std_1.20/src/net/cgo_unix.go
+++ /dev/null
@@ -1,412 +0,0 @@
-// Copyright 2011 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.
-
-// This file is called cgo_unix.go, but to allow syscalls-to-libc-based
-// implementations to share the code, it does not use cgo directly.
-// Instead of C.foo it uses _C_foo, which is defined in either
-// cgo_unix_cgo.go or cgo_unix_syscall.go
-
-//go:build !netgo && ((cgo && unix) || darwin)
-
-package net
-
-import (
- "context"
- "errors"
- "syscall"
- "unsafe"
-
- "golang.org/x/net/dns/dnsmessage"
-)
-
-// An addrinfoErrno represents a getaddrinfo, getnameinfo-specific
-// error number. It's a signed number and a zero value is a non-error
-// by convention.
-type addrinfoErrno int
-
-func (eai addrinfoErrno) Error() string { return _C_gai_strerror(_C_int(eai)) }
-func (eai addrinfoErrno) Temporary() bool { return eai == _C_EAI_AGAIN }
-func (eai addrinfoErrno) Timeout() bool { return false }
-
-type portLookupResult struct {
- port int
- err error
-}
-
-type ipLookupResult struct {
- addrs []IPAddr
- cname string
- err error
-}
-
-type reverseLookupResult struct {
- names []string
- err error
-}
-
-func cgoLookupHost(ctx context.Context, name string) (hosts []string, err error, completed bool) {
- addrs, err, completed := cgoLookupIP(ctx, "ip", name)
- for _, addr := range addrs {
- hosts = append(hosts, addr.String())
- }
- return
-}
-
-func cgoLookupPort(ctx context.Context, network, service string) (port int, err error, completed bool) {
- var hints _C_struct_addrinfo
- switch network {
- case "": // no hints
- case "tcp", "tcp4", "tcp6":
- *_C_ai_socktype(&hints) = _C_SOCK_STREAM
- *_C_ai_protocol(&hints) = _C_IPPROTO_TCP
- case "udp", "udp4", "udp6":
- *_C_ai_socktype(&hints) = _C_SOCK_DGRAM
- *_C_ai_protocol(&hints) = _C_IPPROTO_UDP
- default:
- return 0, &DNSError{Err: "unknown network", Name: network + "/" + service}, true
- }
- switch ipVersion(network) {
- case '4':
- *_C_ai_family(&hints) = _C_AF_INET
- case '6':
- *_C_ai_family(&hints) = _C_AF_INET6
- }
- if ctx.Done() == nil {
- port, err := cgoLookupServicePort(&hints, network, service)
- return port, err, true
- }
- result := make(chan portLookupResult, 1)
- go cgoPortLookup(result, &hints, network, service)
- select {
- case r := <-result:
- return r.port, r.err, true
- case <-ctx.Done():
- // Since there isn't a portable way to cancel the lookup,
- // we just let it finish and write to the buffered channel.
- return 0, mapErr(ctx.Err()), false
- }
-}
-
-func cgoLookupServicePort(hints *_C_struct_addrinfo, network, service string) (port int, err error) {
- cservice := make([]byte, len(service)+1)
- copy(cservice, service)
- // Lowercase the C service name.
- for i, b := range cservice[:len(service)] {
- cservice[i] = lowerASCII(b)
- }
- var res *_C_struct_addrinfo
- gerrno, err := _C_getaddrinfo(nil, (*_C_char)(unsafe.Pointer(&cservice[0])), hints, &res)
- if gerrno != 0 {
- isTemporary := false
- switch gerrno {
- case _C_EAI_SYSTEM:
- if err == nil { // see golang.org/issue/6232
- err = syscall.EMFILE
- }
- default:
- err = addrinfoErrno(gerrno)
- isTemporary = addrinfoErrno(gerrno).Temporary()
- }
- return 0, &DNSError{Err: err.Error(), Name: network + "/" + service, IsTemporary: isTemporary}
- }
- defer _C_freeaddrinfo(res)
-
- for r := res; r != nil; r = *_C_ai_next(r) {
- switch *_C_ai_family(r) {
- case _C_AF_INET:
- sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(*_C_ai_addr(r)))
- p := (*[2]byte)(unsafe.Pointer(&sa.Port))
- return int(p[0])<<8 | int(p[1]), nil
- case _C_AF_INET6:
- sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(*_C_ai_addr(r)))
- p := (*[2]byte)(unsafe.Pointer(&sa.Port))
- return int(p[0])<<8 | int(p[1]), nil
- }
- }
- return 0, &DNSError{Err: "unknown port", Name: network + "/" + service}
-}
-
-func cgoPortLookup(result chan<- portLookupResult, hints *_C_struct_addrinfo, network, service string) {
- port, err := cgoLookupServicePort(hints, network, service)
- result <- portLookupResult{port, err}
-}
-
-func cgoLookupIPCNAME(network, name string) (addrs []IPAddr, cname string, err error) {
- acquireThread()
- defer releaseThread()
-
- var hints _C_struct_addrinfo
- *_C_ai_flags(&hints) = cgoAddrInfoFlags
- *_C_ai_socktype(&hints) = _C_SOCK_STREAM
- *_C_ai_family(&hints) = _C_AF_UNSPEC
- switch ipVersion(network) {
- case '4':
- *_C_ai_family(&hints) = _C_AF_INET
- case '6':
- *_C_ai_family(&hints) = _C_AF_INET6
- }
-
- h := make([]byte, len(name)+1)
- copy(h, name)
- var res *_C_struct_addrinfo
- gerrno, err := _C_getaddrinfo((*_C_char)(unsafe.Pointer(&h[0])), nil, &hints, &res)
- if gerrno != 0 {
- isErrorNoSuchHost := false
- isTemporary := false
- switch gerrno {
- case _C_EAI_SYSTEM:
- if err == nil {
- // err should not be nil, but sometimes getaddrinfo returns
- // gerrno == _C_EAI_SYSTEM with err == nil on Linux.
- // The report claims that it happens when we have too many
- // open files, so use syscall.EMFILE (too many open files in system).
- // Most system calls would return ENFILE (too many open files),
- // so at the least EMFILE should be easy to recognize if this
- // comes up again. golang.org/issue/6232.
- err = syscall.EMFILE
- }
- case _C_EAI_NONAME:
- err = errNoSuchHost
- isErrorNoSuchHost = true
- default:
- err = addrinfoErrno(gerrno)
- isTemporary = addrinfoErrno(gerrno).Temporary()
- }
-
- return nil, "", &DNSError{Err: err.Error(), Name: name, IsNotFound: isErrorNoSuchHost, IsTemporary: isTemporary}
- }
- defer _C_freeaddrinfo(res)
-
- if res != nil {
- cname = _C_GoString(*_C_ai_canonname(res))
- if cname == "" {
- cname = name
- }
- if len(cname) > 0 && cname[len(cname)-1] != '.' {
- cname += "."
- }
- }
- for r := res; r != nil; r = *_C_ai_next(r) {
- // We only asked for SOCK_STREAM, but check anyhow.
- if *_C_ai_socktype(r) != _C_SOCK_STREAM {
- continue
- }
- switch *_C_ai_family(r) {
- case _C_AF_INET:
- sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(*_C_ai_addr(r)))
- addr := IPAddr{IP: copyIP(sa.Addr[:])}
- addrs = append(addrs, addr)
- case _C_AF_INET6:
- sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(*_C_ai_addr(r)))
- addr := IPAddr{IP: copyIP(sa.Addr[:]), Zone: zoneCache.name(int(sa.Scope_id))}
- addrs = append(addrs, addr)
- }
- }
- return addrs, cname, nil
-}
-
-func cgoIPLookup(result chan<- ipLookupResult, network, name string) {
- addrs, cname, err := cgoLookupIPCNAME(network, name)
- result <- ipLookupResult{addrs, cname, err}
-}
-
-func cgoLookupIP(ctx context.Context, network, name string) (addrs []IPAddr, err error, completed bool) {
- if ctx.Done() == nil {
- addrs, _, err = cgoLookupIPCNAME(network, name)
- return addrs, err, true
- }
- result := make(chan ipLookupResult, 1)
- go cgoIPLookup(result, network, name)
- select {
- case r := <-result:
- return r.addrs, r.err, true
- case <-ctx.Done():
- return nil, mapErr(ctx.Err()), false
- }
-}
-
-// These are roughly enough for the following:
-//
-// Source Encoding Maximum length of single name entry
-// Unicast DNS ASCII or <=253 + a NUL terminator
-// Unicode in RFC 5892 252 * total number of labels + delimiters + a NUL terminator
-// Multicast DNS UTF-8 in RFC 5198 or <=253 + a NUL terminator
-// the same as unicast DNS ASCII <=253 + a NUL terminator
-// Local database various depends on implementation
-const (
- nameinfoLen = 64
- maxNameinfoLen = 4096
-)
-
-func cgoLookupPTR(ctx context.Context, addr string) (names []string, err error, completed bool) {
- var zone string
- ip := parseIPv4(addr)
- if ip == nil {
- ip, zone = parseIPv6Zone(addr)
- }
- if ip == nil {
- return nil, &DNSError{Err: "invalid address", Name: addr}, true
- }
- sa, salen := cgoSockaddr(ip, zone)
- if sa == nil {
- return nil, &DNSError{Err: "invalid address " + ip.String(), Name: addr}, true
- }
- if ctx.Done() == nil {
- names, err := cgoLookupAddrPTR(addr, sa, salen)
- return names, err, true
- }
- result := make(chan reverseLookupResult, 1)
- go cgoReverseLookup(result, addr, sa, salen)
- select {
- case r := <-result:
- return r.names, r.err, true
- case <-ctx.Done():
- return nil, mapErr(ctx.Err()), false
- }
-}
-
-func cgoLookupAddrPTR(addr string, sa *_C_struct_sockaddr, salen _C_socklen_t) (names []string, err error) {
- acquireThread()
- defer releaseThread()
-
- var gerrno int
- var b []byte
- for l := nameinfoLen; l <= maxNameinfoLen; l *= 2 {
- b = make([]byte, l)
- gerrno, err = cgoNameinfoPTR(b, sa, salen)
- if gerrno == 0 || gerrno != _C_EAI_OVERFLOW {
- break
- }
- }
- if gerrno != 0 {
- isTemporary := false
- switch gerrno {
- case _C_EAI_SYSTEM:
- if err == nil { // see golang.org/issue/6232
- err = syscall.EMFILE
- }
- default:
- err = addrinfoErrno(gerrno)
- isTemporary = addrinfoErrno(gerrno).Temporary()
- }
- return nil, &DNSError{Err: err.Error(), Name: addr, IsTemporary: isTemporary}
- }
- for i := 0; i < len(b); i++ {
- if b[i] == 0 {
- b = b[:i]
- break
- }
- }
- return []string{absDomainName(string(b))}, nil
-}
-
-func cgoReverseLookup(result chan<- reverseLookupResult, addr string, sa *_C_struct_sockaddr, salen _C_socklen_t) {
- names, err := cgoLookupAddrPTR(addr, sa, salen)
- result <- reverseLookupResult{names, err}
-}
-
-func cgoSockaddr(ip IP, zone string) (*_C_struct_sockaddr, _C_socklen_t) {
- if ip4 := ip.To4(); ip4 != nil {
- return cgoSockaddrInet4(ip4), _C_socklen_t(syscall.SizeofSockaddrInet4)
- }
- if ip6 := ip.To16(); ip6 != nil {
- return cgoSockaddrInet6(ip6, zoneCache.index(zone)), _C_socklen_t(syscall.SizeofSockaddrInet6)
- }
- return nil, 0
-}
-
-func cgoLookupCNAME(ctx context.Context, name string) (cname string, err error, completed bool) {
- resources, err := resSearch(ctx, name, int(dnsmessage.TypeCNAME), int(dnsmessage.ClassINET))
- if err != nil {
- return
- }
- cname, err = parseCNAMEFromResources(resources)
- if err != nil {
- return "", err, false
- }
- return cname, nil, true
-}
-
-// resSearch will make a call to the 'res_nsearch' routine in the C library
-// and parse the output as a slice of DNS resources.
-func resSearch(ctx context.Context, hostname string, rtype, class int) ([]dnsmessage.Resource, error) {
- if ctx.Done() == nil {
- return cgoResSearch(hostname, rtype, class)
- }
-
- type result struct {
- res []dnsmessage.Resource
- err error
- }
-
- res := make(chan result, 1)
- go func() {
- r, err := cgoResSearch(hostname, rtype, class)
- res <- result{
- res: r,
- err: err,
- }
- }()
-
- select {
- case res := <-res:
- return res.res, res.err
- case <-ctx.Done():
- return nil, mapErr(ctx.Err())
- }
-}
-
-func cgoResSearch(hostname string, rtype, class int) ([]dnsmessage.Resource, error) {
- acquireThread()
- defer releaseThread()
-
- state := (*_C_struct___res_state)(_C_malloc(unsafe.Sizeof(_C_struct___res_state{})))
- defer _C_free(unsafe.Pointer(state))
- if err := _C_res_ninit(state); err != nil {
- return nil, errors.New("res_ninit failure: " + err.Error())
- }
- defer _C_res_nclose(state)
-
- // Some res_nsearch implementations (like macOS) do not set errno.
- // They set h_errno, which is not per-thread and useless to us.
- // res_nsearch returns the size of the DNS response packet.
- // But if the DNS response packet contains failure-like response codes,
- // res_search returns -1 even though it has copied the packet into buf,
- // giving us no way to find out how big the packet is.
- // For now, we are willing to take res_search's word that there's nothing
- // useful in the response, even though there *is* a response.
- bufSize := maxDNSPacketSize
- buf := (*_C_uchar)(_C_malloc(uintptr(bufSize)))
- defer _C_free(unsafe.Pointer(buf))
-
- s := _C_CString(hostname)
- defer _C_FreeCString(s)
-
- var size int
- for {
- size, _ = _C_res_nsearch(state, s, class, rtype, buf, bufSize)
- if size <= 0 || size > 0xffff {
- return nil, errors.New("res_nsearch failure")
- }
- if size <= bufSize {
- break
- }
-
- // Allocate a bigger buffer to fit the entire msg.
- _C_free(unsafe.Pointer(buf))
- bufSize = size
- buf = (*_C_uchar)(_C_malloc(uintptr(bufSize)))
- }
-
- var p dnsmessage.Parser
- if _, err := p.Start(unsafe.Slice((*byte)(unsafe.Pointer(buf)), size)); err != nil {
- return nil, err
- }
- p.SkipAllQuestions()
- resources, err := p.AllAnswers()
- if err != nil {
- return nil, err
- }
- return resources, nil
-}
diff --git a/contrib/go/_std_1.20/src/net/cgo_unix_cgo.go b/contrib/go/_std_1.20/src/net/cgo_unix_cgo.go
deleted file mode 100644
index 97427e695d..0000000000
--- a/contrib/go/_std_1.20/src/net/cgo_unix_cgo.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2022 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.
-
-//go:build cgo && !netgo && unix && !darwin
-
-package net
-
-/*
-#cgo CFLAGS: -fno-stack-protector
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-
-// If nothing else defined EAI_OVERFLOW, make sure it has a value.
-#ifndef EAI_OVERFLOW
-#define EAI_OVERFLOW -12
-#endif
-*/
-import "C"
-import "unsafe"
-
-const (
- _C_AF_INET = C.AF_INET
- _C_AF_INET6 = C.AF_INET6
- _C_AF_UNSPEC = C.AF_UNSPEC
- _C_EAI_AGAIN = C.EAI_AGAIN
- _C_EAI_NONAME = C.EAI_NONAME
- _C_EAI_OVERFLOW = C.EAI_OVERFLOW
- _C_EAI_SYSTEM = C.EAI_SYSTEM
- _C_IPPROTO_TCP = C.IPPROTO_TCP
- _C_IPPROTO_UDP = C.IPPROTO_UDP
- _C_SOCK_DGRAM = C.SOCK_DGRAM
- _C_SOCK_STREAM = C.SOCK_STREAM
-)
-
-type (
- _C_char = C.char
- _C_uchar = C.uchar
- _C_int = C.int
- _C_uint = C.uint
- _C_socklen_t = C.socklen_t
- _C_struct_addrinfo = C.struct_addrinfo
- _C_struct_sockaddr = C.struct_sockaddr
-)
-
-func _C_GoString(p *_C_char) string { return C.GoString(p) }
-func _C_CString(s string) *_C_char { return C.CString(s) }
-func _C_FreeCString(p *_C_char) { C.free(unsafe.Pointer(p)) }
-func _C_malloc(n uintptr) unsafe.Pointer { return C.malloc(C.size_t(n)) }
-func _C_free(p unsafe.Pointer) { C.free(p) }
-
-func _C_ai_addr(ai *_C_struct_addrinfo) **_C_struct_sockaddr { return &ai.ai_addr }
-func _C_ai_canonname(ai *_C_struct_addrinfo) **_C_char { return &ai.ai_canonname }
-func _C_ai_family(ai *_C_struct_addrinfo) *_C_int { return &ai.ai_family }
-func _C_ai_flags(ai *_C_struct_addrinfo) *_C_int { return &ai.ai_flags }
-func _C_ai_next(ai *_C_struct_addrinfo) **_C_struct_addrinfo { return &ai.ai_next }
-func _C_ai_protocol(ai *_C_struct_addrinfo) *_C_int { return &ai.ai_protocol }
-func _C_ai_socktype(ai *_C_struct_addrinfo) *_C_int { return &ai.ai_socktype }
-
-func _C_freeaddrinfo(ai *_C_struct_addrinfo) {
- C.freeaddrinfo(ai)
-}
-
-func _C_gai_strerror(eai _C_int) string {
- return C.GoString(C.gai_strerror(eai))
-}
-
-func _C_getaddrinfo(hostname, servname *_C_char, hints *_C_struct_addrinfo, res **_C_struct_addrinfo) (int, error) {
- x, err := C.getaddrinfo(hostname, servname, hints, res)
- return int(x), err
-}
diff --git a/contrib/go/_std_1.20/src/net/cgo_unix_syscall.go b/contrib/go/_std_1.20/src/net/cgo_unix_syscall.go
deleted file mode 100644
index 0d20a52464..0000000000
--- a/contrib/go/_std_1.20/src/net/cgo_unix_syscall.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2022 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.
-
-//go:build !netgo && darwin
-
-package net
-
-import (
- "internal/syscall/unix"
- "runtime"
- "syscall"
- "unsafe"
-)
-
-const (
- _C_AF_INET = syscall.AF_INET
- _C_AF_INET6 = syscall.AF_INET6
- _C_AF_UNSPEC = syscall.AF_UNSPEC
- _C_EAI_AGAIN = unix.EAI_AGAIN
- _C_EAI_NONAME = unix.EAI_NONAME
- _C_EAI_OVERFLOW = unix.EAI_OVERFLOW
- _C_EAI_SYSTEM = unix.EAI_SYSTEM
- _C_IPPROTO_TCP = syscall.IPPROTO_TCP
- _C_IPPROTO_UDP = syscall.IPPROTO_UDP
- _C_SOCK_DGRAM = syscall.SOCK_DGRAM
- _C_SOCK_STREAM = syscall.SOCK_STREAM
-)
-
-type (
- _C_char = byte
- _C_int = int32
- _C_uchar = byte
- _C_uint = uint32
- _C_socklen_t = int
- _C_struct___res_state = unix.ResState
- _C_struct_addrinfo = unix.Addrinfo
- _C_struct_sockaddr = syscall.RawSockaddr
-)
-
-func _C_GoString(p *_C_char) string {
- return unix.GoString(p)
-}
-
-func _C_CString(s string) *_C_char {
- p := make([]byte, len(s)+1)
- copy(p, s)
- return &p[0]
-}
-
-func _C_FreeCString(p *_C_char) { _C_free(unsafe.Pointer(p)) }
-func _C_free(p unsafe.Pointer) { runtime.KeepAlive(p) }
-
-func _C_malloc(n uintptr) unsafe.Pointer {
- if n <= 0 {
- n = 1
- }
- return unsafe.Pointer(&make([]byte, n)[0])
-}
-
-func _C_ai_addr(ai *_C_struct_addrinfo) **_C_struct_sockaddr { return &ai.Addr }
-func _C_ai_canonname(ai *_C_struct_addrinfo) **_C_char { return &ai.Canonname }
-func _C_ai_family(ai *_C_struct_addrinfo) *_C_int { return &ai.Family }
-func _C_ai_flags(ai *_C_struct_addrinfo) *_C_int { return &ai.Flags }
-func _C_ai_next(ai *_C_struct_addrinfo) **_C_struct_addrinfo { return &ai.Next }
-func _C_ai_protocol(ai *_C_struct_addrinfo) *_C_int { return &ai.Protocol }
-func _C_ai_socktype(ai *_C_struct_addrinfo) *_C_int { return &ai.Socktype }
-
-func _C_freeaddrinfo(ai *_C_struct_addrinfo) {
- unix.Freeaddrinfo(ai)
-}
-
-func _C_gai_strerror(eai _C_int) string {
- return unix.GaiStrerror(int(eai))
-}
-
-func _C_getaddrinfo(hostname, servname *byte, hints *_C_struct_addrinfo, res **_C_struct_addrinfo) (int, error) {
- return unix.Getaddrinfo(hostname, servname, hints, res)
-}
-
-func _C_res_ninit(state *_C_struct___res_state) error {
- unix.ResNinit(state)
- return nil
-}
-
-func _C_res_nsearch(state *_C_struct___res_state, dname *_C_char, class, typ int, ans *_C_char, anslen int) (int, error) {
- return unix.ResNsearch(state, dname, class, typ, ans, anslen)
-}
-
-func _C_res_nclose(state *_C_struct___res_state) {
- unix.ResNclose(state)
-}
-
-func cgoNameinfoPTR(b []byte, sa *syscall.RawSockaddr, salen int) (int, error) {
- gerrno, err := unix.Getnameinfo(sa, salen, &b[0], len(b), nil, 0, unix.NI_NAMEREQD)
- return int(gerrno), err
-}
-
-func cgoSockaddrInet4(ip IP) *syscall.RawSockaddr {
- sa := syscall.RawSockaddrInet4{Len: syscall.SizeofSockaddrInet4, Family: syscall.AF_INET}
- copy(sa.Addr[:], ip)
- return (*syscall.RawSockaddr)(unsafe.Pointer(&sa))
-}
-
-func cgoSockaddrInet6(ip IP, zone int) *syscall.RawSockaddr {
- sa := syscall.RawSockaddrInet6{Len: syscall.SizeofSockaddrInet6, Family: syscall.AF_INET6, Scope_id: uint32(zone)}
- copy(sa.Addr[:], ip)
- return (*syscall.RawSockaddr)(unsafe.Pointer(&sa))
-}
diff --git a/contrib/go/_std_1.20/src/net/cgo_windows.go b/contrib/go/_std_1.20/src/net/cgo_windows.go
deleted file mode 100644
index 6bb6cbbb2f..0000000000
--- a/contrib/go/_std_1.20/src/net/cgo_windows.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2015 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.
-
-//go:build cgo && !netgo
-
-package net
-
-type addrinfoErrno int
-
-func (eai addrinfoErrno) Error() string { return "<nil>" }
-func (eai addrinfoErrno) Temporary() bool { return false }
-func (eai addrinfoErrno) Timeout() bool { return false }
diff --git a/contrib/go/_std_1.20/src/net/conf.go b/contrib/go/_std_1.20/src/net/conf.go
deleted file mode 100644
index 41196042bb..0000000000
--- a/contrib/go/_std_1.20/src/net/conf.go
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright 2015 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.
-
-//go:build !js
-
-package net
-
-import (
- "internal/bytealg"
- "internal/godebug"
- "os"
- "runtime"
- "sync"
- "syscall"
-)
-
-// conf represents a system's network configuration.
-type conf struct {
- // forceCgoLookupHost forces CGO to always be used, if available.
- forceCgoLookupHost bool
-
- netGo bool // go DNS resolution forced
- netCgo bool // non-go DNS resolution forced (cgo, or win32)
-
- // machine has an /etc/mdns.allow file
- hasMDNSAllow bool
-
- goos string // the runtime.GOOS, to ease testing
- dnsDebugLevel int
-}
-
-var (
- confOnce sync.Once // guards init of confVal via initConfVal
- confVal = &conf{goos: runtime.GOOS}
-)
-
-// systemConf returns the machine's network configuration.
-func systemConf() *conf {
- confOnce.Do(initConfVal)
- return confVal
-}
-
-func initConfVal() {
- dnsMode, debugLevel := goDebugNetDNS()
- confVal.dnsDebugLevel = debugLevel
- confVal.netGo = netGo || dnsMode == "go"
- confVal.netCgo = netCgo || dnsMode == "cgo"
- if !confVal.netGo && !confVal.netCgo && (runtime.GOOS == "windows" || runtime.GOOS == "plan9") {
- // Neither of these platforms actually use cgo.
- //
- // The meaning of "cgo" mode in the net package is
- // really "the native OS way", which for libc meant
- // cgo on the original platforms that motivated
- // PreferGo support before Windows and Plan9 got support,
- // at which time the GODEBUG=netdns=go and GODEBUG=netdns=cgo
- // names were already kinda locked in.
- confVal.netCgo = true
- }
-
- if confVal.dnsDebugLevel > 0 {
- defer func() {
- if confVal.dnsDebugLevel > 1 {
- println("go package net: confVal.netCgo =", confVal.netCgo, " netGo =", confVal.netGo)
- }
- switch {
- case confVal.netGo:
- if netGo {
- println("go package net: built with netgo build tag; using Go's DNS resolver")
- } else {
- println("go package net: GODEBUG setting forcing use of Go's resolver")
- }
- case confVal.forceCgoLookupHost:
- println("go package net: using cgo DNS resolver")
- default:
- println("go package net: dynamic selection of DNS resolver")
- }
- }()
- }
-
- // Darwin pops up annoying dialog boxes if programs try to do
- // their own DNS requests. So always use cgo instead, which
- // avoids that.
- if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
- confVal.forceCgoLookupHost = true
- return
- }
-
- if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
- return
- }
-
- // If any environment-specified resolver options are specified,
- // force cgo. Note that LOCALDOMAIN can change behavior merely
- // by being specified with the empty string.
- _, localDomainDefined := syscall.Getenv("LOCALDOMAIN")
- if os.Getenv("RES_OPTIONS") != "" ||
- os.Getenv("HOSTALIASES") != "" ||
- confVal.netCgo ||
- localDomainDefined {
- confVal.forceCgoLookupHost = true
- return
- }
-
- // OpenBSD apparently lets you override the location of resolv.conf
- // with ASR_CONFIG. If we notice that, defer to libc.
- if runtime.GOOS == "openbsd" && os.Getenv("ASR_CONFIG") != "" {
- confVal.forceCgoLookupHost = true
- return
- }
-
- if _, err := os.Stat("/etc/mdns.allow"); err == nil {
- confVal.hasMDNSAllow = true
- }
-}
-
-// canUseCgo reports whether calling cgo functions is allowed
-// for non-hostname lookups.
-func (c *conf) canUseCgo() bool {
- ret, _ := c.hostLookupOrder(nil, "")
- return ret == hostLookupCgo
-}
-
-// hostLookupOrder determines which strategy to use to resolve hostname.
-// The provided Resolver is optional. nil means to not consider its options.
-// It also returns dnsConfig when it was used to determine the lookup order.
-func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrder, dnsConfig *dnsConfig) {
- if c.dnsDebugLevel > 1 {
- defer func() {
- print("go package net: hostLookupOrder(", hostname, ") = ", ret.String(), "\n")
- }()
- }
- fallbackOrder := hostLookupCgo
- if c.netGo || r.preferGo() {
- switch c.goos {
- case "windows":
- // TODO(bradfitz): implement files-based
- // lookup on Windows too? I guess /etc/hosts
- // kinda exists on Windows. But for now, only
- // do DNS.
- fallbackOrder = hostLookupDNS
- default:
- fallbackOrder = hostLookupFilesDNS
- }
- }
- if c.forceCgoLookupHost || c.goos == "android" || c.goos == "windows" || c.goos == "plan9" {
- return fallbackOrder, nil
- }
- if bytealg.IndexByteString(hostname, '\\') != -1 || bytealg.IndexByteString(hostname, '%') != -1 {
- // Don't deal with special form hostnames with backslashes
- // or '%'.
- return fallbackOrder, nil
- }
-
- conf := getSystemDNSConfig()
- if conf.err != nil && !os.IsNotExist(conf.err) && !os.IsPermission(conf.err) {
- // If we can't read the resolv.conf file, assume it
- // had something important in it and defer to cgo.
- // libc's resolver might then fail too, but at least
- // it wasn't our fault.
- return fallbackOrder, conf
- }
-
- if conf.unknownOpt {
- return fallbackOrder, conf
- }
-
- // OpenBSD is unique and doesn't use nsswitch.conf.
- // It also doesn't support mDNS.
- if c.goos == "openbsd" {
- // OpenBSD's resolv.conf manpage says that a non-existent
- // resolv.conf means "lookup" defaults to only "files",
- // without DNS lookups.
- if os.IsNotExist(conf.err) {
- return hostLookupFiles, conf
- }
-
- lookup := conf.lookup
- if len(lookup) == 0 {
- // https://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/resolv.conf.5
- // "If the lookup keyword is not used in the
- // system's resolv.conf file then the assumed
- // order is 'bind file'"
- return hostLookupDNSFiles, conf
- }
- if len(lookup) < 1 || len(lookup) > 2 {
- return fallbackOrder, conf
- }
- switch lookup[0] {
- case "bind":
- if len(lookup) == 2 {
- if lookup[1] == "file" {
- return hostLookupDNSFiles, conf
- }
- return fallbackOrder, conf
- }
- return hostLookupDNS, conf
- case "file":
- if len(lookup) == 2 {
- if lookup[1] == "bind" {
- return hostLookupFilesDNS, conf
- }
- return fallbackOrder, conf
- }
- return hostLookupFiles, conf
- default:
- return fallbackOrder, conf
- }
- }
-
- // Canonicalize the hostname by removing any trailing dot.
- if stringsHasSuffix(hostname, ".") {
- hostname = hostname[:len(hostname)-1]
- }
- if stringsHasSuffixFold(hostname, ".local") {
- // Per RFC 6762, the ".local" TLD is special. And
- // because Go's native resolver doesn't do mDNS or
- // similar local resolution mechanisms, assume that
- // libc might (via Avahi, etc) and use cgo.
- return fallbackOrder, conf
- }
-
- nss := getSystemNSS()
- srcs := nss.sources["hosts"]
- // If /etc/nsswitch.conf doesn't exist or doesn't specify any
- // sources for "hosts", assume Go's DNS will work fine.
- if os.IsNotExist(nss.err) || (nss.err == nil && len(srcs) == 0) {
- if c.goos == "solaris" {
- // illumos defaults to "nis [NOTFOUND=return] files"
- return fallbackOrder, conf
- }
-
- return hostLookupFilesDNS, conf
- }
- if nss.err != nil {
- // We failed to parse or open nsswitch.conf, so
- // conservatively assume we should use cgo if it's
- // available.
- return fallbackOrder, conf
- }
-
- var mdnsSource, filesSource, dnsSource bool
- var first string
- for _, src := range srcs {
- if src.source == "myhostname" {
- if isLocalhost(hostname) || isGateway(hostname) || isOutbound(hostname) {
- return fallbackOrder, conf
- }
- hn, err := getHostname()
- if err != nil || stringsEqualFold(hostname, hn) {
- return fallbackOrder, conf
- }
- continue
- }
- if src.source == "files" || src.source == "dns" {
- if !src.standardCriteria() {
- return fallbackOrder, conf // non-standard; let libc deal with it.
- }
- if src.source == "files" {
- filesSource = true
- } else if src.source == "dns" {
- dnsSource = true
- }
- if first == "" {
- first = src.source
- }
- continue
- }
- if stringsHasPrefix(src.source, "mdns") {
- // e.g. "mdns4", "mdns4_minimal"
- // We already returned true before if it was *.local.
- // libc wouldn't have found a hit on this anyway.
- mdnsSource = true
- continue
- }
- // Some source we don't know how to deal with.
- return fallbackOrder, conf
- }
-
- // We don't parse mdns.allow files. They're rare. If one
- // exists, it might list other TLDs (besides .local) or even
- // '*', so just let libc deal with it.
- if mdnsSource && c.hasMDNSAllow {
- return fallbackOrder, conf
- }
-
- // Cases where Go can handle it without cgo and C thread
- // overhead.
- switch {
- case filesSource && dnsSource:
- if first == "files" {
- return hostLookupFilesDNS, conf
- } else {
- return hostLookupDNSFiles, conf
- }
- case filesSource:
- return hostLookupFiles, conf
- case dnsSource:
- return hostLookupDNS, conf
- }
-
- // Something weird. Let libc deal with it.
- return fallbackOrder, conf
-}
-
-var netdns = godebug.New("netdns")
-
-// goDebugNetDNS parses the value of the GODEBUG "netdns" value.
-// The netdns value can be of the form:
-//
-// 1 // debug level 1
-// 2 // debug level 2
-// cgo // use cgo for DNS lookups
-// go // use go for DNS lookups
-// cgo+1 // use cgo for DNS lookups + debug level 1
-// 1+cgo // same
-// cgo+2 // same, but debug level 2
-//
-// etc.
-func goDebugNetDNS() (dnsMode string, debugLevel int) {
- goDebug := netdns.Value()
- parsePart := func(s string) {
- if s == "" {
- return
- }
- if '0' <= s[0] && s[0] <= '9' {
- debugLevel, _, _ = dtoi(s)
- } else {
- dnsMode = s
- }
- }
- if i := bytealg.IndexByteString(goDebug, '+'); i != -1 {
- parsePart(goDebug[:i])
- parsePart(goDebug[i+1:])
- return
- }
- parsePart(goDebug)
- return
-}
-
-// isLocalhost reports whether h should be considered a "localhost"
-// name for the myhostname NSS module.
-func isLocalhost(h string) bool {
- return stringsEqualFold(h, "localhost") || stringsEqualFold(h, "localhost.localdomain") || stringsHasSuffixFold(h, ".localhost") || stringsHasSuffixFold(h, ".localhost.localdomain")
-}
-
-// isGateway reports whether h should be considered a "gateway"
-// name for the myhostname NSS module.
-func isGateway(h string) bool {
- return stringsEqualFold(h, "_gateway")
-}
-
-// isOutbound reports whether h should be considered a "outbound"
-// name for the myhostname NSS module.
-func isOutbound(h string) bool {
- return stringsEqualFold(h, "_outbound")
-}
diff --git a/contrib/go/_std_1.20/src/net/dial.go b/contrib/go/_std_1.20/src/net/dial.go
deleted file mode 100644
index 85ec557575..0000000000
--- a/contrib/go/_std_1.20/src/net/dial.go
+++ /dev/null
@@ -1,740 +0,0 @@
-// Copyright 2010 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 net
-
-import (
- "context"
- "internal/nettrace"
- "syscall"
- "time"
-)
-
-// defaultTCPKeepAlive is a default constant value for TCPKeepAlive times
-// See golang.org/issue/31510
-const (
- defaultTCPKeepAlive = 15 * time.Second
-)
-
-// A Dialer contains options for connecting to an address.
-//
-// The zero value for each field is equivalent to dialing
-// without that option. Dialing with the zero value of Dialer
-// is therefore equivalent to just calling the Dial function.
-//
-// It is safe to call Dialer's methods concurrently.
-type Dialer struct {
- // Timeout is the maximum amount of time a dial will wait for
- // a connect to complete. If Deadline is also set, it may fail
- // earlier.
- //
- // The default is no timeout.
- //
- // When using TCP and dialing a host name with multiple IP
- // addresses, the timeout may be divided between them.
- //
- // With or without a timeout, the operating system may impose
- // its own earlier timeout. For instance, TCP timeouts are
- // often around 3 minutes.
- Timeout time.Duration
-
- // Deadline is the absolute point in time after which dials
- // will fail. If Timeout is set, it may fail earlier.
- // Zero means no deadline, or dependent on the operating system
- // as with the Timeout option.
- Deadline time.Time
-
- // LocalAddr is the local address to use when dialing an
- // address. The address must be of a compatible type for the
- // network being dialed.
- // If nil, a local address is automatically chosen.
- LocalAddr Addr
-
- // DualStack previously enabled RFC 6555 Fast Fallback
- // support, also known as "Happy Eyeballs", in which IPv4 is
- // tried soon if IPv6 appears to be misconfigured and
- // hanging.
- //
- // Deprecated: Fast Fallback is enabled by default. To
- // disable, set FallbackDelay to a negative value.
- DualStack bool
-
- // FallbackDelay specifies the length of time to wait before
- // spawning a RFC 6555 Fast Fallback connection. That is, this
- // is the amount of time to wait for IPv6 to succeed before
- // assuming that IPv6 is misconfigured and falling back to
- // IPv4.
- //
- // If zero, a default delay of 300ms is used.
- // A negative value disables Fast Fallback support.
- FallbackDelay time.Duration
-
- // KeepAlive specifies the interval between keep-alive
- // probes for an active network connection.
- // If zero, keep-alive probes are sent with a default value
- // (currently 15 seconds), if supported by the protocol and operating
- // system. Network protocols or operating systems that do
- // not support keep-alives ignore this field.
- // If negative, keep-alive probes are disabled.
- KeepAlive time.Duration
-
- // Resolver optionally specifies an alternate resolver to use.
- Resolver *Resolver
-
- // Cancel is an optional channel whose closure indicates that
- // the dial should be canceled. Not all types of dials support
- // cancellation.
- //
- // Deprecated: Use DialContext instead.
- Cancel <-chan struct{}
-
- // If Control is not nil, it is called after creating the network
- // connection but before actually dialing.
- //
- // Network and address parameters passed to Control method are not
- // necessarily the ones passed to Dial. For example, passing "tcp" to Dial
- // will cause the Control function to be called with "tcp4" or "tcp6".
- //
- // Control is ignored if ControlContext is not nil.
- Control func(network, address string, c syscall.RawConn) error
-
- // If ControlContext is not nil, it is called after creating the network
- // connection but before actually dialing.
- //
- // Network and address parameters passed to Control method are not
- // necessarily the ones passed to Dial. For example, passing "tcp" to Dial
- // will cause the Control function to be called with "tcp4" or "tcp6".
- //
- // If ControlContext is not nil, Control is ignored.
- ControlContext func(ctx context.Context, network, address string, c syscall.RawConn) error
-}
-
-func (d *Dialer) dualStack() bool { return d.FallbackDelay >= 0 }
-
-func minNonzeroTime(a, b time.Time) time.Time {
- if a.IsZero() {
- return b
- }
- if b.IsZero() || a.Before(b) {
- return a
- }
- return b
-}
-
-// deadline returns the earliest of:
-// - now+Timeout
-// - d.Deadline
-// - the context's deadline
-//
-// Or zero, if none of Timeout, Deadline, or context's deadline is set.
-func (d *Dialer) deadline(ctx context.Context, now time.Time) (earliest time.Time) {
- if d.Timeout != 0 { // including negative, for historical reasons
- earliest = now.Add(d.Timeout)
- }
- if d, ok := ctx.Deadline(); ok {
- earliest = minNonzeroTime(earliest, d)
- }
- return minNonzeroTime(earliest, d.Deadline)
-}
-
-func (d *Dialer) resolver() *Resolver {
- if d.Resolver != nil {
- return d.Resolver
- }
- return DefaultResolver
-}
-
-// partialDeadline returns the deadline to use for a single address,
-// when multiple addresses are pending.
-func partialDeadline(now, deadline time.Time, addrsRemaining int) (time.Time, error) {
- if deadline.IsZero() {
- return deadline, nil
- }
- timeRemaining := deadline.Sub(now)
- if timeRemaining <= 0 {
- return time.Time{}, errTimeout
- }
- // Tentatively allocate equal time to each remaining address.
- timeout := timeRemaining / time.Duration(addrsRemaining)
- // If the time per address is too short, steal from the end of the list.
- const saneMinimum = 2 * time.Second
- if timeout < saneMinimum {
- if timeRemaining < saneMinimum {
- timeout = timeRemaining
- } else {
- timeout = saneMinimum
- }
- }
- return now.Add(timeout), nil
-}
-
-func (d *Dialer) fallbackDelay() time.Duration {
- if d.FallbackDelay > 0 {
- return d.FallbackDelay
- } else {
- return 300 * time.Millisecond
- }
-}
-
-func parseNetwork(ctx context.Context, network string, needsProto bool) (afnet string, proto int, err error) {
- i := last(network, ':')
- if i < 0 { // no colon
- switch network {
- case "tcp", "tcp4", "tcp6":
- case "udp", "udp4", "udp6":
- case "ip", "ip4", "ip6":
- if needsProto {
- return "", 0, UnknownNetworkError(network)
- }
- case "unix", "unixgram", "unixpacket":
- default:
- return "", 0, UnknownNetworkError(network)
- }
- return network, 0, nil
- }
- afnet = network[:i]
- switch afnet {
- case "ip", "ip4", "ip6":
- protostr := network[i+1:]
- proto, i, ok := dtoi(protostr)
- if !ok || i != len(protostr) {
- proto, err = lookupProtocol(ctx, protostr)
- if err != nil {
- return "", 0, err
- }
- }
- return afnet, proto, nil
- }
- return "", 0, UnknownNetworkError(network)
-}
-
-// resolveAddrList resolves addr using hint and returns a list of
-// addresses. The result contains at least one address when error is
-// nil.
-func (r *Resolver) resolveAddrList(ctx context.Context, op, network, addr string, hint Addr) (addrList, error) {
- afnet, _, err := parseNetwork(ctx, network, true)
- if err != nil {
- return nil, err
- }
- if op == "dial" && addr == "" {
- return nil, errMissingAddress
- }
- switch afnet {
- case "unix", "unixgram", "unixpacket":
- addr, err := ResolveUnixAddr(afnet, addr)
- if err != nil {
- return nil, err
- }
- if op == "dial" && hint != nil && addr.Network() != hint.Network() {
- return nil, &AddrError{Err: "mismatched local address type", Addr: hint.String()}
- }
- return addrList{addr}, nil
- }
- addrs, err := r.internetAddrList(ctx, afnet, addr)
- if err != nil || op != "dial" || hint == nil {
- return addrs, err
- }
- var (
- tcp *TCPAddr
- udp *UDPAddr
- ip *IPAddr
- wildcard bool
- )
- switch hint := hint.(type) {
- case *TCPAddr:
- tcp = hint
- wildcard = tcp.isWildcard()
- case *UDPAddr:
- udp = hint
- wildcard = udp.isWildcard()
- case *IPAddr:
- ip = hint
- wildcard = ip.isWildcard()
- }
- naddrs := addrs[:0]
- for _, addr := range addrs {
- if addr.Network() != hint.Network() {
- return nil, &AddrError{Err: "mismatched local address type", Addr: hint.String()}
- }
- switch addr := addr.(type) {
- case *TCPAddr:
- if !wildcard && !addr.isWildcard() && !addr.IP.matchAddrFamily(tcp.IP) {
- continue
- }
- naddrs = append(naddrs, addr)
- case *UDPAddr:
- if !wildcard && !addr.isWildcard() && !addr.IP.matchAddrFamily(udp.IP) {
- continue
- }
- naddrs = append(naddrs, addr)
- case *IPAddr:
- if !wildcard && !addr.isWildcard() && !addr.IP.matchAddrFamily(ip.IP) {
- continue
- }
- naddrs = append(naddrs, addr)
- }
- }
- if len(naddrs) == 0 {
- return nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: hint.String()}
- }
- return naddrs, nil
-}
-
-// Dial connects to the address on the named network.
-//
-// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
-// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
-// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
-// "unixpacket".
-//
-// For TCP and UDP networks, the address has the form "host:port".
-// The host must be a literal IP address, or a host name that can be
-// resolved to IP addresses.
-// The port must be a literal port number or a service name.
-// If the host is a literal IPv6 address it must be enclosed in square
-// brackets, as in "[2001:db8::1]:80" or "[fe80::1%zone]:80".
-// The zone specifies the scope of the literal IPv6 address as defined
-// in RFC 4007.
-// The functions JoinHostPort and SplitHostPort manipulate a pair of
-// host and port in this form.
-// When using TCP, and the host resolves to multiple IP addresses,
-// Dial will try each IP address in order until one succeeds.
-//
-// Examples:
-//
-// Dial("tcp", "golang.org:http")
-// Dial("tcp", "192.0.2.1:http")
-// Dial("tcp", "198.51.100.1:80")
-// Dial("udp", "[2001:db8::1]:domain")
-// Dial("udp", "[fe80::1%lo0]:53")
-// Dial("tcp", ":80")
-//
-// For IP networks, the network must be "ip", "ip4" or "ip6" followed
-// by a colon and a literal protocol number or a protocol name, and
-// the address has the form "host". The host must be a literal IP
-// address or a literal IPv6 address with zone.
-// It depends on each operating system how the operating system
-// behaves with a non-well known protocol number such as "0" or "255".
-//
-// Examples:
-//
-// Dial("ip4:1", "192.0.2.1")
-// Dial("ip6:ipv6-icmp", "2001:db8::1")
-// Dial("ip6:58", "fe80::1%lo0")
-//
-// For TCP, UDP and IP networks, if the host is empty or a literal
-// unspecified IP address, as in ":80", "0.0.0.0:80" or "[::]:80" for
-// TCP and UDP, "", "0.0.0.0" or "::" for IP, the local system is
-// assumed.
-//
-// For Unix networks, the address must be a file system path.
-func Dial(network, address string) (Conn, error) {
- var d Dialer
- return d.Dial(network, address)
-}
-
-// DialTimeout acts like Dial but takes a timeout.
-//
-// The timeout includes name resolution, if required.
-// When using TCP, and the host in the address parameter resolves to
-// multiple IP addresses, the timeout is spread over each consecutive
-// dial, such that each is given an appropriate fraction of the time
-// to connect.
-//
-// See func Dial for a description of the network and address
-// parameters.
-func DialTimeout(network, address string, timeout time.Duration) (Conn, error) {
- d := Dialer{Timeout: timeout}
- return d.Dial(network, address)
-}
-
-// sysDialer contains a Dial's parameters and configuration.
-type sysDialer struct {
- Dialer
- network, address string
- testHookDialTCP func(ctx context.Context, net string, laddr, raddr *TCPAddr) (*TCPConn, error)
-}
-
-// Dial connects to the address on the named network.
-//
-// See func Dial for a description of the network and address
-// parameters.
-//
-// Dial uses context.Background internally; to specify the context, use
-// DialContext.
-func (d *Dialer) Dial(network, address string) (Conn, error) {
- return d.DialContext(context.Background(), network, address)
-}
-
-// DialContext connects to the address on the named network using
-// the provided context.
-//
-// The provided Context must be non-nil. If the context expires before
-// the connection is complete, an error is returned. Once successfully
-// connected, any expiration of the context will not affect the
-// connection.
-//
-// When using TCP, and the host in the address parameter resolves to multiple
-// network addresses, any dial timeout (from d.Timeout or ctx) is spread
-// over each consecutive dial, such that each is given an appropriate
-// fraction of the time to connect.
-// For example, if a host has 4 IP addresses and the timeout is 1 minute,
-// the connect to each single address will be given 15 seconds to complete
-// before trying the next one.
-//
-// See func Dial for a description of the network and address
-// parameters.
-func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error) {
- if ctx == nil {
- panic("nil context")
- }
- deadline := d.deadline(ctx, time.Now())
- if !deadline.IsZero() {
- if d, ok := ctx.Deadline(); !ok || deadline.Before(d) {
- subCtx, cancel := context.WithDeadline(ctx, deadline)
- defer cancel()
- ctx = subCtx
- }
- }
- if oldCancel := d.Cancel; oldCancel != nil {
- subCtx, cancel := context.WithCancel(ctx)
- defer cancel()
- go func() {
- select {
- case <-oldCancel:
- cancel()
- case <-subCtx.Done():
- }
- }()
- ctx = subCtx
- }
-
- // Shadow the nettrace (if any) during resolve so Connect events don't fire for DNS lookups.
- resolveCtx := ctx
- if trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace); trace != nil {
- shadow := *trace
- shadow.ConnectStart = nil
- shadow.ConnectDone = nil
- resolveCtx = context.WithValue(resolveCtx, nettrace.TraceKey{}, &shadow)
- }
-
- addrs, err := d.resolver().resolveAddrList(resolveCtx, "dial", network, address, d.LocalAddr)
- if err != nil {
- return nil, &OpError{Op: "dial", Net: network, Source: nil, Addr: nil, Err: err}
- }
-
- sd := &sysDialer{
- Dialer: *d,
- network: network,
- address: address,
- }
-
- var primaries, fallbacks addrList
- if d.dualStack() && network == "tcp" {
- primaries, fallbacks = addrs.partition(isIPv4)
- } else {
- primaries = addrs
- }
-
- return sd.dialParallel(ctx, primaries, fallbacks)
-}
-
-// dialParallel races two copies of dialSerial, giving the first a
-// head start. It returns the first established connection and
-// closes the others. Otherwise it returns an error from the first
-// primary address.
-func (sd *sysDialer) dialParallel(ctx context.Context, primaries, fallbacks addrList) (Conn, error) {
- if len(fallbacks) == 0 {
- return sd.dialSerial(ctx, primaries)
- }
-
- returned := make(chan struct{})
- defer close(returned)
-
- type dialResult struct {
- Conn
- error
- primary bool
- done bool
- }
- results := make(chan dialResult) // unbuffered
-
- startRacer := func(ctx context.Context, primary bool) {
- ras := primaries
- if !primary {
- ras = fallbacks
- }
- c, err := sd.dialSerial(ctx, ras)
- select {
- case results <- dialResult{Conn: c, error: err, primary: primary, done: true}:
- case <-returned:
- if c != nil {
- c.Close()
- }
- }
- }
-
- var primary, fallback dialResult
-
- // Start the main racer.
- primaryCtx, primaryCancel := context.WithCancel(ctx)
- defer primaryCancel()
- go startRacer(primaryCtx, true)
-
- // Start the timer for the fallback racer.
- fallbackTimer := time.NewTimer(sd.fallbackDelay())
- defer fallbackTimer.Stop()
-
- for {
- select {
- case <-fallbackTimer.C:
- fallbackCtx, fallbackCancel := context.WithCancel(ctx)
- defer fallbackCancel()
- go startRacer(fallbackCtx, false)
-
- case res := <-results:
- if res.error == nil {
- return res.Conn, nil
- }
- if res.primary {
- primary = res
- } else {
- fallback = res
- }
- if primary.done && fallback.done {
- return nil, primary.error
- }
- if res.primary && fallbackTimer.Stop() {
- // If we were able to stop the timer, that means it
- // was running (hadn't yet started the fallback), but
- // we just got an error on the primary path, so start
- // the fallback immediately (in 0 nanoseconds).
- fallbackTimer.Reset(0)
- }
- }
- }
-}
-
-// dialSerial connects to a list of addresses in sequence, returning
-// either the first successful connection, or the first error.
-func (sd *sysDialer) dialSerial(ctx context.Context, ras addrList) (Conn, error) {
- var firstErr error // The error from the first address is most relevant.
-
- for i, ra := range ras {
- select {
- case <-ctx.Done():
- return nil, &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: mapErr(ctx.Err())}
- default:
- }
-
- dialCtx := ctx
- if deadline, hasDeadline := ctx.Deadline(); hasDeadline {
- partialDeadline, err := partialDeadline(time.Now(), deadline, len(ras)-i)
- if err != nil {
- // Ran out of time.
- if firstErr == nil {
- firstErr = &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: err}
- }
- break
- }
- if partialDeadline.Before(deadline) {
- var cancel context.CancelFunc
- dialCtx, cancel = context.WithDeadline(ctx, partialDeadline)
- defer cancel()
- }
- }
-
- c, err := sd.dialSingle(dialCtx, ra)
- if err == nil {
- return c, nil
- }
- if firstErr == nil {
- firstErr = err
- }
- }
-
- if firstErr == nil {
- firstErr = &OpError{Op: "dial", Net: sd.network, Source: nil, Addr: nil, Err: errMissingAddress}
- }
- return nil, firstErr
-}
-
-// dialSingle attempts to establish and returns a single connection to
-// the destination address.
-func (sd *sysDialer) dialSingle(ctx context.Context, ra Addr) (c Conn, err error) {
- trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace)
- if trace != nil {
- raStr := ra.String()
- if trace.ConnectStart != nil {
- trace.ConnectStart(sd.network, raStr)
- }
- if trace.ConnectDone != nil {
- defer func() { trace.ConnectDone(sd.network, raStr, err) }()
- }
- }
- la := sd.LocalAddr
- switch ra := ra.(type) {
- case *TCPAddr:
- la, _ := la.(*TCPAddr)
- c, err = sd.dialTCP(ctx, la, ra)
- case *UDPAddr:
- la, _ := la.(*UDPAddr)
- c, err = sd.dialUDP(ctx, la, ra)
- case *IPAddr:
- la, _ := la.(*IPAddr)
- c, err = sd.dialIP(ctx, la, ra)
- case *UnixAddr:
- la, _ := la.(*UnixAddr)
- c, err = sd.dialUnix(ctx, la, ra)
- default:
- return nil, &OpError{Op: "dial", Net: sd.network, Source: la, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: sd.address}}
- }
- if err != nil {
- return nil, &OpError{Op: "dial", Net: sd.network, Source: la, Addr: ra, Err: err} // c is non-nil interface containing nil pointer
- }
- return c, nil
-}
-
-// ListenConfig contains options for listening to an address.
-type ListenConfig struct {
- // If Control is not nil, it is called after creating the network
- // connection but before binding it to the operating system.
- //
- // Network and address parameters passed to Control method are not
- // necessarily the ones passed to Listen. For example, passing "tcp" to
- // Listen will cause the Control function to be called with "tcp4" or "tcp6".
- Control func(network, address string, c syscall.RawConn) error
-
- // KeepAlive specifies the keep-alive period for network
- // connections accepted by this listener.
- // If zero, keep-alives are enabled if supported by the protocol
- // and operating system. Network protocols or operating systems
- // that do not support keep-alives ignore this field.
- // If negative, keep-alives are disabled.
- KeepAlive time.Duration
-}
-
-// Listen announces on the local network address.
-//
-// See func Listen for a description of the network and address
-// parameters.
-func (lc *ListenConfig) Listen(ctx context.Context, network, address string) (Listener, error) {
- addrs, err := DefaultResolver.resolveAddrList(ctx, "listen", network, address, nil)
- if err != nil {
- return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: err}
- }
- sl := &sysListener{
- ListenConfig: *lc,
- network: network,
- address: address,
- }
- var l Listener
- la := addrs.first(isIPv4)
- switch la := la.(type) {
- case *TCPAddr:
- l, err = sl.listenTCP(ctx, la)
- case *UnixAddr:
- l, err = sl.listenUnix(ctx, la)
- default:
- return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: address}}
- }
- if err != nil {
- return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: err} // l is non-nil interface containing nil pointer
- }
- return l, nil
-}
-
-// ListenPacket announces on the local network address.
-//
-// See func ListenPacket for a description of the network and address
-// parameters.
-func (lc *ListenConfig) ListenPacket(ctx context.Context, network, address string) (PacketConn, error) {
- addrs, err := DefaultResolver.resolveAddrList(ctx, "listen", network, address, nil)
- if err != nil {
- return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: err}
- }
- sl := &sysListener{
- ListenConfig: *lc,
- network: network,
- address: address,
- }
- var c PacketConn
- la := addrs.first(isIPv4)
- switch la := la.(type) {
- case *UDPAddr:
- c, err = sl.listenUDP(ctx, la)
- case *IPAddr:
- c, err = sl.listenIP(ctx, la)
- case *UnixAddr:
- c, err = sl.listenUnixgram(ctx, la)
- default:
- return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: address}}
- }
- if err != nil {
- return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: err} // c is non-nil interface containing nil pointer
- }
- return c, nil
-}
-
-// sysListener contains a Listen's parameters and configuration.
-type sysListener struct {
- ListenConfig
- network, address string
-}
-
-// Listen announces on the local network address.
-//
-// The network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
-//
-// For TCP networks, if the host in the address parameter is empty or
-// a literal unspecified IP address, Listen listens on all available
-// unicast and anycast IP addresses of the local system.
-// To only use IPv4, use network "tcp4".
-// The address can use a host name, but this is not recommended,
-// because it will create a listener for at most one of the host's IP
-// addresses.
-// If the port in the address parameter is empty or "0", as in
-// "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
-// The Addr method of Listener can be used to discover the chosen
-// port.
-//
-// See func Dial for a description of the network and address
-// parameters.
-//
-// Listen uses context.Background internally; to specify the context, use
-// ListenConfig.Listen.
-func Listen(network, address string) (Listener, error) {
- var lc ListenConfig
- return lc.Listen(context.Background(), network, address)
-}
-
-// ListenPacket announces on the local network address.
-//
-// The network must be "udp", "udp4", "udp6", "unixgram", or an IP
-// transport. The IP transports are "ip", "ip4", or "ip6" followed by
-// a colon and a literal protocol number or a protocol name, as in
-// "ip:1" or "ip:icmp".
-//
-// For UDP and IP networks, if the host in the address parameter is
-// empty or a literal unspecified IP address, ListenPacket listens on
-// all available IP addresses of the local system except multicast IP
-// addresses.
-// To only use IPv4, use network "udp4" or "ip4:proto".
-// The address can use a host name, but this is not recommended,
-// because it will create a listener for at most one of the host's IP
-// addresses.
-// If the port in the address parameter is empty or "0", as in
-// "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
-// The LocalAddr method of PacketConn can be used to discover the
-// chosen port.
-//
-// See func Dial for a description of the network and address
-// parameters.
-//
-// ListenPacket uses context.Background internally; to specify the context, use
-// ListenConfig.ListenPacket.
-func ListenPacket(network, address string) (PacketConn, error) {
- var lc ListenConfig
- return lc.ListenPacket(context.Background(), network, address)
-}
diff --git a/contrib/go/_std_1.20/src/net/dnsclient_unix.go b/contrib/go/_std_1.20/src/net/dnsclient_unix.go
deleted file mode 100644
index 20da8f1970..0000000000
--- a/contrib/go/_std_1.20/src/net/dnsclient_unix.go
+++ /dev/null
@@ -1,866 +0,0 @@
-// Copyright 2009 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.
-
-//go:build !js
-
-// DNS client: see RFC 1035.
-// Has to be linked into package net for Dial.
-
-// TODO(rsc):
-// Could potentially handle many outstanding lookups faster.
-// Random UDP source port (net.Dial should do that for us).
-// Random request IDs.
-
-package net
-
-import (
- "context"
- "errors"
- "internal/itoa"
- "io"
- "os"
- "runtime"
- "sync"
- "sync/atomic"
- "time"
-
- "golang.org/x/net/dns/dnsmessage"
-)
-
-const (
- // to be used as a useTCP parameter to exchange
- useTCPOnly = true
- useUDPOrTCP = false
-
- // Maximum DNS packet size.
- // Value taken from https://dnsflagday.net/2020/.
- maxDNSPacketSize = 1232
-)
-
-var (
- errLameReferral = errors.New("lame referral")
- errCannotUnmarshalDNSMessage = errors.New("cannot unmarshal DNS message")
- errCannotMarshalDNSMessage = errors.New("cannot marshal DNS message")
- errServerMisbehaving = errors.New("server misbehaving")
- errInvalidDNSResponse = errors.New("invalid DNS response")
- errNoAnswerFromDNSServer = errors.New("no answer from DNS server")
-
- // errServerTemporarilyMisbehaving is like errServerMisbehaving, except
- // that when it gets translated to a DNSError, the IsTemporary field
- // gets set to true.
- errServerTemporarilyMisbehaving = errors.New("server misbehaving")
-)
-
-func newRequest(q dnsmessage.Question, ad bool) (id uint16, udpReq, tcpReq []byte, err error) {
- id = uint16(randInt())
- b := dnsmessage.NewBuilder(make([]byte, 2, 514), dnsmessage.Header{ID: id, RecursionDesired: true, AuthenticData: ad})
- if err := b.StartQuestions(); err != nil {
- return 0, nil, nil, err
- }
- if err := b.Question(q); err != nil {
- return 0, nil, nil, err
- }
-
- // Accept packets up to maxDNSPacketSize. RFC 6891.
- if err := b.StartAdditionals(); err != nil {
- return 0, nil, nil, err
- }
- var rh dnsmessage.ResourceHeader
- if err := rh.SetEDNS0(maxDNSPacketSize, dnsmessage.RCodeSuccess, false); err != nil {
- return 0, nil, nil, err
- }
- if err := b.OPTResource(rh, dnsmessage.OPTResource{}); err != nil {
- return 0, nil, nil, err
- }
-
- tcpReq, err = b.Finish()
- if err != nil {
- return 0, nil, nil, err
- }
- udpReq = tcpReq[2:]
- l := len(tcpReq) - 2
- tcpReq[0] = byte(l >> 8)
- tcpReq[1] = byte(l)
- return id, udpReq, tcpReq, nil
-}
-
-func checkResponse(reqID uint16, reqQues dnsmessage.Question, respHdr dnsmessage.Header, respQues dnsmessage.Question) bool {
- if !respHdr.Response {
- return false
- }
- if reqID != respHdr.ID {
- return false
- }
- if reqQues.Type != respQues.Type || reqQues.Class != respQues.Class || !equalASCIIName(reqQues.Name, respQues.Name) {
- return false
- }
- return true
-}
-
-func dnsPacketRoundTrip(c Conn, id uint16, query dnsmessage.Question, b []byte) (dnsmessage.Parser, dnsmessage.Header, error) {
- if _, err := c.Write(b); err != nil {
- return dnsmessage.Parser{}, dnsmessage.Header{}, err
- }
-
- b = make([]byte, maxDNSPacketSize)
- for {
- n, err := c.Read(b)
- if err != nil {
- return dnsmessage.Parser{}, dnsmessage.Header{}, err
- }
- var p dnsmessage.Parser
- // Ignore invalid responses as they may be malicious
- // forgery attempts. Instead continue waiting until
- // timeout. See golang.org/issue/13281.
- h, err := p.Start(b[:n])
- if err != nil {
- continue
- }
- q, err := p.Question()
- if err != nil || !checkResponse(id, query, h, q) {
- continue
- }
- return p, h, nil
- }
-}
-
-func dnsStreamRoundTrip(c Conn, id uint16, query dnsmessage.Question, b []byte) (dnsmessage.Parser, dnsmessage.Header, error) {
- if _, err := c.Write(b); err != nil {
- return dnsmessage.Parser{}, dnsmessage.Header{}, err
- }
-
- b = make([]byte, 1280) // 1280 is a reasonable initial size for IP over Ethernet, see RFC 4035
- if _, err := io.ReadFull(c, b[:2]); err != nil {
- return dnsmessage.Parser{}, dnsmessage.Header{}, err
- }
- l := int(b[0])<<8 | int(b[1])
- if l > len(b) {
- b = make([]byte, l)
- }
- n, err := io.ReadFull(c, b[:l])
- if err != nil {
- return dnsmessage.Parser{}, dnsmessage.Header{}, err
- }
- var p dnsmessage.Parser
- h, err := p.Start(b[:n])
- if err != nil {
- return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotUnmarshalDNSMessage
- }
- q, err := p.Question()
- if err != nil {
- return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotUnmarshalDNSMessage
- }
- if !checkResponse(id, query, h, q) {
- return dnsmessage.Parser{}, dnsmessage.Header{}, errInvalidDNSResponse
- }
- return p, h, nil
-}
-
-// exchange sends a query on the connection and hopes for a response.
-func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Question, timeout time.Duration, useTCP, ad bool) (dnsmessage.Parser, dnsmessage.Header, error) {
- q.Class = dnsmessage.ClassINET
- id, udpReq, tcpReq, err := newRequest(q, ad)
- if err != nil {
- return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotMarshalDNSMessage
- }
- var networks []string
- if useTCP {
- networks = []string{"tcp"}
- } else {
- networks = []string{"udp", "tcp"}
- }
- for _, network := range networks {
- ctx, cancel := context.WithDeadline(ctx, time.Now().Add(timeout))
- defer cancel()
-
- c, err := r.dial(ctx, network, server)
- if err != nil {
- return dnsmessage.Parser{}, dnsmessage.Header{}, err
- }
- if d, ok := ctx.Deadline(); ok && !d.IsZero() {
- c.SetDeadline(d)
- }
- var p dnsmessage.Parser
- var h dnsmessage.Header
- if _, ok := c.(PacketConn); ok {
- p, h, err = dnsPacketRoundTrip(c, id, q, udpReq)
- } else {
- p, h, err = dnsStreamRoundTrip(c, id, q, tcpReq)
- }
- c.Close()
- if err != nil {
- return dnsmessage.Parser{}, dnsmessage.Header{}, mapErr(err)
- }
- if err := p.SkipQuestion(); err != dnsmessage.ErrSectionDone {
- return dnsmessage.Parser{}, dnsmessage.Header{}, errInvalidDNSResponse
- }
- if h.Truncated { // see RFC 5966
- continue
- }
- return p, h, nil
- }
- return dnsmessage.Parser{}, dnsmessage.Header{}, errNoAnswerFromDNSServer
-}
-
-// checkHeader performs basic sanity checks on the header.
-func checkHeader(p *dnsmessage.Parser, h dnsmessage.Header) error {
- if h.RCode == dnsmessage.RCodeNameError {
- return errNoSuchHost
- }
-
- _, err := p.AnswerHeader()
- if err != nil && err != dnsmessage.ErrSectionDone {
- return errCannotUnmarshalDNSMessage
- }
-
- // libresolv continues to the next server when it receives
- // an invalid referral response. See golang.org/issue/15434.
- if h.RCode == dnsmessage.RCodeSuccess && !h.Authoritative && !h.RecursionAvailable && err == dnsmessage.ErrSectionDone {
- return errLameReferral
- }
-
- if h.RCode != dnsmessage.RCodeSuccess && h.RCode != dnsmessage.RCodeNameError {
- // None of the error codes make sense
- // for the query we sent. If we didn't get
- // a name error and we didn't get success,
- // the server is behaving incorrectly or
- // having temporary trouble.
- if h.RCode == dnsmessage.RCodeServerFailure {
- return errServerTemporarilyMisbehaving
- }
- return errServerMisbehaving
- }
-
- return nil
-}
-
-func skipToAnswer(p *dnsmessage.Parser, qtype dnsmessage.Type) error {
- for {
- h, err := p.AnswerHeader()
- if err == dnsmessage.ErrSectionDone {
- return errNoSuchHost
- }
- if err != nil {
- return errCannotUnmarshalDNSMessage
- }
- if h.Type == qtype {
- return nil
- }
- if err := p.SkipAnswer(); err != nil {
- return errCannotUnmarshalDNSMessage
- }
- }
-}
-
-// Do a lookup for a single name, which must be rooted
-// (otherwise answer will not find the answers).
-func (r *Resolver) tryOneName(ctx context.Context, cfg *dnsConfig, name string, qtype dnsmessage.Type) (dnsmessage.Parser, string, error) {
- var lastErr error
- serverOffset := cfg.serverOffset()
- sLen := uint32(len(cfg.servers))
-
- n, err := dnsmessage.NewName(name)
- if err != nil {
- return dnsmessage.Parser{}, "", errCannotMarshalDNSMessage
- }
- q := dnsmessage.Question{
- Name: n,
- Type: qtype,
- Class: dnsmessage.ClassINET,
- }
-
- for i := 0; i < cfg.attempts; i++ {
- for j := uint32(0); j < sLen; j++ {
- server := cfg.servers[(serverOffset+j)%sLen]
-
- p, h, err := r.exchange(ctx, server, q, cfg.timeout, cfg.useTCP, cfg.trustAD)
- if err != nil {
- dnsErr := &DNSError{
- Err: err.Error(),
- Name: name,
- Server: server,
- }
- if nerr, ok := err.(Error); ok && nerr.Timeout() {
- dnsErr.IsTimeout = true
- }
- // Set IsTemporary for socket-level errors. Note that this flag
- // may also be used to indicate a SERVFAIL response.
- if _, ok := err.(*OpError); ok {
- dnsErr.IsTemporary = true
- }
- lastErr = dnsErr
- continue
- }
-
- if err := checkHeader(&p, h); err != nil {
- dnsErr := &DNSError{
- Err: err.Error(),
- Name: name,
- Server: server,
- }
- if err == errServerTemporarilyMisbehaving {
- dnsErr.IsTemporary = true
- }
- if err == errNoSuchHost {
- // The name does not exist, so trying
- // another server won't help.
-
- dnsErr.IsNotFound = true
- return p, server, dnsErr
- }
- lastErr = dnsErr
- continue
- }
-
- err = skipToAnswer(&p, qtype)
- if err == nil {
- return p, server, nil
- }
- lastErr = &DNSError{
- Err: err.Error(),
- Name: name,
- Server: server,
- }
- if err == errNoSuchHost {
- // The name does not exist, so trying another
- // server won't help.
-
- lastErr.(*DNSError).IsNotFound = true
- return p, server, lastErr
- }
- }
- }
- return dnsmessage.Parser{}, "", lastErr
-}
-
-// A resolverConfig represents a DNS stub resolver configuration.
-type resolverConfig struct {
- initOnce sync.Once // guards init of resolverConfig
-
- // ch is used as a semaphore that only allows one lookup at a
- // time to recheck resolv.conf.
- ch chan struct{} // guards lastChecked and modTime
- lastChecked time.Time // last time resolv.conf was checked
-
- dnsConfig atomic.Pointer[dnsConfig] // parsed resolv.conf structure used in lookups
-}
-
-var resolvConf resolverConfig
-
-func getSystemDNSConfig() *dnsConfig {
- resolvConf.tryUpdate("/etc/resolv.conf")
- return resolvConf.dnsConfig.Load()
-}
-
-// init initializes conf and is only called via conf.initOnce.
-func (conf *resolverConfig) init() {
- // Set dnsConfig and lastChecked so we don't parse
- // resolv.conf twice the first time.
- conf.dnsConfig.Store(dnsReadConfig("/etc/resolv.conf"))
- conf.lastChecked = time.Now()
-
- // Prepare ch so that only one update of resolverConfig may
- // run at once.
- conf.ch = make(chan struct{}, 1)
-}
-
-// tryUpdate tries to update conf with the named resolv.conf file.
-// The name variable only exists for testing. It is otherwise always
-// "/etc/resolv.conf".
-func (conf *resolverConfig) tryUpdate(name string) {
- conf.initOnce.Do(conf.init)
-
- if conf.dnsConfig.Load().noReload {
- return
- }
-
- // Ensure only one update at a time checks resolv.conf.
- if !conf.tryAcquireSema() {
- return
- }
- defer conf.releaseSema()
-
- now := time.Now()
- if conf.lastChecked.After(now.Add(-5 * time.Second)) {
- return
- }
- conf.lastChecked = now
-
- switch runtime.GOOS {
- case "windows":
- // There's no file on disk, so don't bother checking
- // and failing.
- //
- // The Windows implementation of dnsReadConfig (called
- // below) ignores the name.
- default:
- var mtime time.Time
- if fi, err := os.Stat(name); err == nil {
- mtime = fi.ModTime()
- }
- if mtime.Equal(conf.dnsConfig.Load().mtime) {
- return
- }
- }
-
- dnsConf := dnsReadConfig(name)
- conf.dnsConfig.Store(dnsConf)
-}
-
-func (conf *resolverConfig) tryAcquireSema() bool {
- select {
- case conf.ch <- struct{}{}:
- return true
- default:
- return false
- }
-}
-
-func (conf *resolverConfig) releaseSema() {
- <-conf.ch
-}
-
-func (r *Resolver) lookup(ctx context.Context, name string, qtype dnsmessage.Type, conf *dnsConfig) (dnsmessage.Parser, string, error) {
- if !isDomainName(name) {
- // We used to use "invalid domain name" as the error,
- // but that is a detail of the specific lookup mechanism.
- // Other lookups might allow broader name syntax
- // (for example Multicast DNS allows UTF-8; see RFC 6762).
- // For consistency with libc resolvers, report no such host.
- return dnsmessage.Parser{}, "", &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
- }
-
- if conf == nil {
- conf = getSystemDNSConfig()
- }
-
- var (
- p dnsmessage.Parser
- server string
- err error
- )
- for _, fqdn := range conf.nameList(name) {
- p, server, err = r.tryOneName(ctx, conf, fqdn, qtype)
- if err == nil {
- break
- }
- if nerr, ok := err.(Error); ok && nerr.Temporary() && r.strictErrors() {
- // If we hit a temporary error with StrictErrors enabled,
- // stop immediately instead of trying more names.
- break
- }
- }
- if err == nil {
- return p, server, nil
- }
- if err, ok := err.(*DNSError); ok {
- // Show original name passed to lookup, not suffixed one.
- // In general we might have tried many suffixes; showing
- // just one is misleading. See also golang.org/issue/6324.
- err.Name = name
- }
- return dnsmessage.Parser{}, "", err
-}
-
-// avoidDNS reports whether this is a hostname for which we should not
-// use DNS. Currently this includes only .onion, per RFC 7686. See
-// golang.org/issue/13705. Does not cover .local names (RFC 6762),
-// see golang.org/issue/16739.
-func avoidDNS(name string) bool {
- if name == "" {
- return true
- }
- if name[len(name)-1] == '.' {
- name = name[:len(name)-1]
- }
- return stringsHasSuffixFold(name, ".onion")
-}
-
-// nameList returns a list of names for sequential DNS queries.
-func (conf *dnsConfig) nameList(name string) []string {
- if avoidDNS(name) {
- return nil
- }
-
- // Check name length (see isDomainName).
- l := len(name)
- rooted := l > 0 && name[l-1] == '.'
- if l > 254 || l == 254 && !rooted {
- return nil
- }
-
- // If name is rooted (trailing dot), try only that name.
- if rooted {
- return []string{name}
- }
-
- hasNdots := count(name, '.') >= conf.ndots
- name += "."
- l++
-
- // Build list of search choices.
- names := make([]string, 0, 1+len(conf.search))
- // If name has enough dots, try unsuffixed first.
- if hasNdots {
- names = append(names, name)
- }
- // Try suffixes that are not too long (see isDomainName).
- for _, suffix := range conf.search {
- if l+len(suffix) <= 254 {
- names = append(names, name+suffix)
- }
- }
- // Try unsuffixed, if not tried first above.
- if !hasNdots {
- names = append(names, name)
- }
- return names
-}
-
-// hostLookupOrder specifies the order of LookupHost lookup strategies.
-// It is basically a simplified representation of nsswitch.conf.
-// "files" means /etc/hosts.
-type hostLookupOrder int
-
-const (
- // hostLookupCgo means defer to cgo.
- hostLookupCgo hostLookupOrder = iota
- hostLookupFilesDNS // files first
- hostLookupDNSFiles // dns first
- hostLookupFiles // only files
- hostLookupDNS // only DNS
-)
-
-var lookupOrderName = map[hostLookupOrder]string{
- hostLookupCgo: "cgo",
- hostLookupFilesDNS: "files,dns",
- hostLookupDNSFiles: "dns,files",
- hostLookupFiles: "files",
- hostLookupDNS: "dns",
-}
-
-func (o hostLookupOrder) String() string {
- if s, ok := lookupOrderName[o]; ok {
- return s
- }
- return "hostLookupOrder=" + itoa.Itoa(int(o)) + "??"
-}
-
-func (r *Resolver) goLookupHostOrder(ctx context.Context, name string, order hostLookupOrder, conf *dnsConfig) (addrs []string, err error) {
- if order == hostLookupFilesDNS || order == hostLookupFiles {
- // Use entries from /etc/hosts if they match.
- addrs, _ = lookupStaticHost(name)
- if len(addrs) > 0 {
- return
- }
-
- if order == hostLookupFiles {
- return nil, &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
- }
- }
- ips, _, err := r.goLookupIPCNAMEOrder(ctx, "ip", name, order, conf)
- if err != nil {
- return
- }
- addrs = make([]string, 0, len(ips))
- for _, ip := range ips {
- addrs = append(addrs, ip.String())
- }
- return
-}
-
-// lookup entries from /etc/hosts
-func goLookupIPFiles(name string) (addrs []IPAddr, canonical string) {
- addr, canonical := lookupStaticHost(name)
- for _, haddr := range addr {
- haddr, zone := splitHostZone(haddr)
- if ip := ParseIP(haddr); ip != nil {
- addr := IPAddr{IP: ip, Zone: zone}
- addrs = append(addrs, addr)
- }
- }
- sortByRFC6724(addrs)
- return addrs, canonical
-}
-
-// goLookupIP is the native Go implementation of LookupIP.
-// The libc versions are in cgo_*.go.
-func (r *Resolver) goLookupIP(ctx context.Context, network, host string) (addrs []IPAddr, err error) {
- order, conf := systemConf().hostLookupOrder(r, host)
- addrs, _, err = r.goLookupIPCNAMEOrder(ctx, network, host, order, conf)
- return
-}
-
-func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name string, order hostLookupOrder, conf *dnsConfig) (addrs []IPAddr, cname dnsmessage.Name, err error) {
- if order == hostLookupFilesDNS || order == hostLookupFiles {
- var canonical string
- addrs, canonical = goLookupIPFiles(name)
-
- if len(addrs) > 0 {
- var err error
- cname, err = dnsmessage.NewName(canonical)
- if err != nil {
- return nil, dnsmessage.Name{}, err
- }
- return addrs, cname, nil
- }
-
- if order == hostLookupFiles {
- return nil, dnsmessage.Name{}, &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
- }
- }
-
- if !isDomainName(name) {
- // See comment in func lookup above about use of errNoSuchHost.
- return nil, dnsmessage.Name{}, &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
- }
- type result struct {
- p dnsmessage.Parser
- server string
- error
- }
-
- if conf == nil {
- conf = getSystemDNSConfig()
- }
-
- lane := make(chan result, 1)
- qtypes := []dnsmessage.Type{dnsmessage.TypeA, dnsmessage.TypeAAAA}
- if network == "CNAME" {
- qtypes = append(qtypes, dnsmessage.TypeCNAME)
- }
- switch ipVersion(network) {
- case '4':
- qtypes = []dnsmessage.Type{dnsmessage.TypeA}
- case '6':
- qtypes = []dnsmessage.Type{dnsmessage.TypeAAAA}
- }
- var queryFn func(fqdn string, qtype dnsmessage.Type)
- var responseFn func(fqdn string, qtype dnsmessage.Type) result
- if conf.singleRequest {
- queryFn = func(fqdn string, qtype dnsmessage.Type) {}
- responseFn = func(fqdn string, qtype dnsmessage.Type) result {
- dnsWaitGroup.Add(1)
- defer dnsWaitGroup.Done()
- p, server, err := r.tryOneName(ctx, conf, fqdn, qtype)
- return result{p, server, err}
- }
- } else {
- queryFn = func(fqdn string, qtype dnsmessage.Type) {
- dnsWaitGroup.Add(1)
- go func(qtype dnsmessage.Type) {
- p, server, err := r.tryOneName(ctx, conf, fqdn, qtype)
- lane <- result{p, server, err}
- dnsWaitGroup.Done()
- }(qtype)
- }
- responseFn = func(fqdn string, qtype dnsmessage.Type) result {
- return <-lane
- }
- }
- var lastErr error
- for _, fqdn := range conf.nameList(name) {
- for _, qtype := range qtypes {
- queryFn(fqdn, qtype)
- }
- hitStrictError := false
- for _, qtype := range qtypes {
- result := responseFn(fqdn, qtype)
- if result.error != nil {
- if nerr, ok := result.error.(Error); ok && nerr.Temporary() && r.strictErrors() {
- // This error will abort the nameList loop.
- hitStrictError = true
- lastErr = result.error
- } else if lastErr == nil || fqdn == name+"." {
- // Prefer error for original name.
- lastErr = result.error
- }
- continue
- }
-
- // Presotto says it's okay to assume that servers listed in
- // /etc/resolv.conf are recursive resolvers.
- //
- // We asked for recursion, so it should have included all the
- // answers we need in this one packet.
- //
- // Further, RFC 1034 section 4.3.1 says that "the recursive
- // response to a query will be... The answer to the query,
- // possibly preface by one or more CNAME RRs that specify
- // aliases encountered on the way to an answer."
- //
- // Therefore, we should be able to assume that we can ignore
- // CNAMEs and that the A and AAAA records we requested are
- // for the canonical name.
-
- loop:
- for {
- h, err := result.p.AnswerHeader()
- if err != nil && err != dnsmessage.ErrSectionDone {
- lastErr = &DNSError{
- Err: "cannot marshal DNS message",
- Name: name,
- Server: result.server,
- }
- }
- if err != nil {
- break
- }
- switch h.Type {
- case dnsmessage.TypeA:
- a, err := result.p.AResource()
- if err != nil {
- lastErr = &DNSError{
- Err: "cannot marshal DNS message",
- Name: name,
- Server: result.server,
- }
- break loop
- }
- addrs = append(addrs, IPAddr{IP: IP(a.A[:])})
- if cname.Length == 0 && h.Name.Length != 0 {
- cname = h.Name
- }
-
- case dnsmessage.TypeAAAA:
- aaaa, err := result.p.AAAAResource()
- if err != nil {
- lastErr = &DNSError{
- Err: "cannot marshal DNS message",
- Name: name,
- Server: result.server,
- }
- break loop
- }
- addrs = append(addrs, IPAddr{IP: IP(aaaa.AAAA[:])})
- if cname.Length == 0 && h.Name.Length != 0 {
- cname = h.Name
- }
-
- case dnsmessage.TypeCNAME:
- c, err := result.p.CNAMEResource()
- if err != nil {
- lastErr = &DNSError{
- Err: "cannot marshal DNS message",
- Name: name,
- Server: result.server,
- }
- break loop
- }
- if cname.Length == 0 && c.CNAME.Length > 0 {
- cname = c.CNAME
- }
-
- default:
- if err := result.p.SkipAnswer(); err != nil {
- lastErr = &DNSError{
- Err: "cannot marshal DNS message",
- Name: name,
- Server: result.server,
- }
- break loop
- }
- continue
- }
- }
- }
- if hitStrictError {
- // If either family hit an error with StrictErrors enabled,
- // discard all addresses. This ensures that network flakiness
- // cannot turn a dualstack hostname IPv4/IPv6-only.
- addrs = nil
- break
- }
- if len(addrs) > 0 || network == "CNAME" && cname.Length > 0 {
- break
- }
- }
- if lastErr, ok := lastErr.(*DNSError); ok {
- // Show original name passed to lookup, not suffixed one.
- // In general we might have tried many suffixes; showing
- // just one is misleading. See also golang.org/issue/6324.
- lastErr.Name = name
- }
- sortByRFC6724(addrs)
- if len(addrs) == 0 && !(network == "CNAME" && cname.Length > 0) {
- if order == hostLookupDNSFiles {
- var canonical string
- addrs, canonical = goLookupIPFiles(name)
- if len(addrs) > 0 {
- var err error
- cname, err = dnsmessage.NewName(canonical)
- if err != nil {
- return nil, dnsmessage.Name{}, err
- }
- return addrs, cname, nil
- }
- }
- if lastErr != nil {
- return nil, dnsmessage.Name{}, lastErr
- }
- }
- return addrs, cname, nil
-}
-
-// goLookupCNAME is the native Go (non-cgo) implementation of LookupCNAME.
-func (r *Resolver) goLookupCNAME(ctx context.Context, host string, order hostLookupOrder, conf *dnsConfig) (string, error) {
- _, cname, err := r.goLookupIPCNAMEOrder(ctx, "CNAME", host, order, conf)
- return cname.String(), err
-}
-
-// goLookupPTR is the native Go implementation of LookupAddr.
-// Used only if cgoLookupPTR refuses to handle the request (that is,
-// only if cgoLookupPTR is the stub in cgo_stub.go).
-// Normally we let cgo use the C library resolver instead of depending
-// on our lookup code, so that Go and C get the same answers.
-func (r *Resolver) goLookupPTR(ctx context.Context, addr string, conf *dnsConfig) ([]string, error) {
- names := lookupStaticAddr(addr)
- if len(names) > 0 {
- return names, nil
- }
- arpa, err := reverseaddr(addr)
- if err != nil {
- return nil, err
- }
- p, server, err := r.lookup(ctx, arpa, dnsmessage.TypePTR, conf)
- if err != nil {
- return nil, err
- }
- var ptrs []string
- for {
- h, err := p.AnswerHeader()
- if err == dnsmessage.ErrSectionDone {
- break
- }
- if err != nil {
- return nil, &DNSError{
- Err: "cannot marshal DNS message",
- Name: addr,
- Server: server,
- }
- }
- if h.Type != dnsmessage.TypePTR {
- err := p.SkipAnswer()
- if err != nil {
- return nil, &DNSError{
- Err: "cannot marshal DNS message",
- Name: addr,
- Server: server,
- }
- }
- continue
- }
- ptr, err := p.PTRResource()
- if err != nil {
- return nil, &DNSError{
- Err: "cannot marshal DNS message",
- Name: addr,
- Server: server,
- }
- }
- ptrs = append(ptrs, ptr.PTR.String())
-
- }
- return ptrs, nil
-}
diff --git a/contrib/go/_std_1.20/src/net/dnsconfig_unix.go b/contrib/go/_std_1.20/src/net/dnsconfig_unix.go
deleted file mode 100644
index 8f6ae34c1b..0000000000
--- a/contrib/go/_std_1.20/src/net/dnsconfig_unix.go
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2009 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.
-
-//go:build !js && !windows
-
-// Read system DNS config from /etc/resolv.conf
-
-package net
-
-import (
- "internal/bytealg"
- "time"
-)
-
-// See resolv.conf(5) on a Linux machine.
-func dnsReadConfig(filename string) *dnsConfig {
- conf := &dnsConfig{
- ndots: 1,
- timeout: 5 * time.Second,
- attempts: 2,
- }
- file, err := open(filename)
- if err != nil {
- conf.servers = defaultNS
- conf.search = dnsDefaultSearch()
- conf.err = err
- return conf
- }
- defer file.close()
- if fi, err := file.file.Stat(); err == nil {
- conf.mtime = fi.ModTime()
- } else {
- conf.servers = defaultNS
- conf.search = dnsDefaultSearch()
- conf.err = err
- return conf
- }
- for line, ok := file.readLine(); ok; line, ok = file.readLine() {
- if len(line) > 0 && (line[0] == ';' || line[0] == '#') {
- // comment.
- continue
- }
- f := getFields(line)
- if len(f) < 1 {
- continue
- }
- switch f[0] {
- case "nameserver": // add one name server
- if len(f) > 1 && len(conf.servers) < 3 { // small, but the standard limit
- // One more check: make sure server name is
- // just an IP address. Otherwise we need DNS
- // to look it up.
- if parseIPv4(f[1]) != nil {
- conf.servers = append(conf.servers, JoinHostPort(f[1], "53"))
- } else if ip, _ := parseIPv6Zone(f[1]); ip != nil {
- conf.servers = append(conf.servers, JoinHostPort(f[1], "53"))
- }
- }
-
- case "domain": // set search path to just this domain
- if len(f) > 1 {
- conf.search = []string{ensureRooted(f[1])}
- }
-
- case "search": // set search path to given servers
- conf.search = make([]string, 0, len(f)-1)
- for i := 1; i < len(f); i++ {
- name := ensureRooted(f[i])
- if name == "." {
- continue
- }
- conf.search = append(conf.search, name)
- }
-
- case "options": // magic options
- for _, s := range f[1:] {
- switch {
- case hasPrefix(s, "ndots:"):
- n, _, _ := dtoi(s[6:])
- if n < 0 {
- n = 0
- } else if n > 15 {
- n = 15
- }
- conf.ndots = n
- case hasPrefix(s, "timeout:"):
- n, _, _ := dtoi(s[8:])
- if n < 1 {
- n = 1
- }
- conf.timeout = time.Duration(n) * time.Second
- case hasPrefix(s, "attempts:"):
- n, _, _ := dtoi(s[9:])
- if n < 1 {
- n = 1
- }
- conf.attempts = n
- case s == "rotate":
- conf.rotate = true
- case s == "single-request" || s == "single-request-reopen":
- // Linux option:
- // http://man7.org/linux/man-pages/man5/resolv.conf.5.html
- // "By default, glibc performs IPv4 and IPv6 lookups in parallel [...]
- // This option disables the behavior and makes glibc
- // perform the IPv6 and IPv4 requests sequentially."
- conf.singleRequest = true
- case s == "use-vc" || s == "usevc" || s == "tcp":
- // Linux (use-vc), FreeBSD (usevc) and OpenBSD (tcp) option:
- // http://man7.org/linux/man-pages/man5/resolv.conf.5.html
- // "Sets RES_USEVC in _res.options.
- // This option forces the use of TCP for DNS resolutions."
- // https://www.freebsd.org/cgi/man.cgi?query=resolv.conf&sektion=5&manpath=freebsd-release-ports
- // https://man.openbsd.org/resolv.conf.5
- conf.useTCP = true
- case s == "trust-ad":
- conf.trustAD = true
- case s == "edns0":
- // We use EDNS by default.
- // Ignore this option.
- case s == "no-reload":
- conf.noReload = true
- default:
- conf.unknownOpt = true
- }
- }
-
- case "lookup":
- // OpenBSD option:
- // https://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/resolv.conf.5
- // "the legal space-separated values are: bind, file, yp"
- conf.lookup = f[1:]
-
- default:
- conf.unknownOpt = true
- }
- }
- if len(conf.servers) == 0 {
- conf.servers = defaultNS
- }
- if len(conf.search) == 0 {
- conf.search = dnsDefaultSearch()
- }
- return conf
-}
-
-func dnsDefaultSearch() []string {
- hn, err := getHostname()
- if err != nil {
- // best effort
- return nil
- }
- if i := bytealg.IndexByteString(hn, '.'); i >= 0 && i < len(hn)-1 {
- return []string{ensureRooted(hn[i+1:])}
- }
- return nil
-}
-
-func hasPrefix(s, prefix string) bool {
- return len(s) >= len(prefix) && s[:len(prefix)] == prefix
-}
-
-func ensureRooted(s string) string {
- if len(s) > 0 && s[len(s)-1] == '.' {
- return s
- }
- return s + "."
-}
diff --git a/contrib/go/_std_1.20/src/net/dnsconfig_windows.go b/contrib/go/_std_1.20/src/net/dnsconfig_windows.go
deleted file mode 100644
index 5d640da1d7..0000000000
--- a/contrib/go/_std_1.20/src/net/dnsconfig_windows.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2022 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 net
-
-import (
- "syscall"
- "time"
-)
-
-func dnsReadConfig(ignoredFilename string) (conf *dnsConfig) {
- conf = &dnsConfig{
- ndots: 1,
- timeout: 5 * time.Second,
- attempts: 2,
- }
- defer func() {
- if len(conf.servers) == 0 {
- conf.servers = defaultNS
- }
- }()
- aas, err := adapterAddresses()
- if err != nil {
- return
- }
- // TODO(bradfitz): this just collects all the DNS servers on all
- // the interfaces in some random order. It should order it by
- // default route, or only use the default route(s) instead.
- // In practice, however, it mostly works.
- for _, aa := range aas {
- for dns := aa.FirstDnsServerAddress; dns != nil; dns = dns.Next {
- sa, err := dns.Address.Sockaddr.Sockaddr()
- if err != nil {
- continue
- }
- var ip IP
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- ip = IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
- case *syscall.SockaddrInet6:
- ip = make(IP, IPv6len)
- copy(ip, sa.Addr[:])
- if ip[0] == 0xfe && ip[1] == 0xc0 {
- // Ignore these fec0/10 ones. Windows seems to
- // populate them as defaults on its misc rando
- // interfaces.
- continue
- }
- default:
- // Unexpected type.
- continue
- }
- conf.servers = append(conf.servers, JoinHostPort(ip.String(), "53"))
- }
- }
- return conf
-}
diff --git a/contrib/go/_std_1.20/src/net/error_posix.go b/contrib/go/_std_1.20/src/net/error_posix.go
deleted file mode 100644
index 8fc7d0bb73..0000000000
--- a/contrib/go/_std_1.20/src/net/error_posix.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2017 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.
-
-//go:build unix || (js && wasm) || windows
-
-package net
-
-import (
- "os"
- "syscall"
-)
-
-// wrapSyscallError takes an error and a syscall name. If the error is
-// a syscall.Errno, it wraps it in a os.SyscallError using the syscall name.
-func wrapSyscallError(name string, err error) error {
- if _, ok := err.(syscall.Errno); ok {
- err = os.NewSyscallError(name, err)
- }
- return err
-}
diff --git a/contrib/go/_std_1.20/src/net/error_unix.go b/contrib/go/_std_1.20/src/net/error_unix.go
deleted file mode 100644
index 1f9b6eb78c..0000000000
--- a/contrib/go/_std_1.20/src/net/error_unix.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2018 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.
-
-//go:build unix || js
-
-package net
-
-import "syscall"
-
-func isConnError(err error) bool {
- if se, ok := err.(syscall.Errno); ok {
- return se == syscall.ECONNRESET || se == syscall.ECONNABORTED
- }
- return false
-}
diff --git a/contrib/go/_std_1.20/src/net/fd_unix.go b/contrib/go/_std_1.20/src/net/fd_unix.go
deleted file mode 100644
index 198f606284..0000000000
--- a/contrib/go/_std_1.20/src/net/fd_unix.go
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix
-
-package net
-
-import (
- "context"
- "internal/poll"
- "os"
- "runtime"
- "syscall"
-)
-
-const (
- readSyscallName = "read"
- readFromSyscallName = "recvfrom"
- readMsgSyscallName = "recvmsg"
- writeSyscallName = "write"
- writeToSyscallName = "sendto"
- writeMsgSyscallName = "sendmsg"
-)
-
-func newFD(sysfd, family, sotype int, net string) (*netFD, error) {
- ret := &netFD{
- pfd: poll.FD{
- Sysfd: sysfd,
- IsStream: sotype == syscall.SOCK_STREAM,
- ZeroReadIsEOF: sotype != syscall.SOCK_DGRAM && sotype != syscall.SOCK_RAW,
- },
- family: family,
- sotype: sotype,
- net: net,
- }
- return ret, nil
-}
-
-func (fd *netFD) init() error {
- return fd.pfd.Init(fd.net, true)
-}
-
-func (fd *netFD) name() string {
- var ls, rs string
- if fd.laddr != nil {
- ls = fd.laddr.String()
- }
- if fd.raddr != nil {
- rs = fd.raddr.String()
- }
- return fd.net + ":" + ls + "->" + rs
-}
-
-func (fd *netFD) connect(ctx context.Context, la, ra syscall.Sockaddr) (rsa syscall.Sockaddr, ret error) {
- // Do not need to call fd.writeLock here,
- // because fd is not yet accessible to user,
- // so no concurrent operations are possible.
- switch err := connectFunc(fd.pfd.Sysfd, ra); err {
- case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
- case nil, syscall.EISCONN:
- select {
- case <-ctx.Done():
- return nil, mapErr(ctx.Err())
- default:
- }
- if err := fd.pfd.Init(fd.net, true); err != nil {
- return nil, err
- }
- runtime.KeepAlive(fd)
- return nil, nil
- case syscall.EINVAL:
- // On Solaris and illumos we can see EINVAL if the socket has
- // already been accepted and closed by the server. Treat this
- // as a successful connection--writes to the socket will see
- // EOF. For details and a test case in C see
- // https://golang.org/issue/6828.
- if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" {
- return nil, nil
- }
- fallthrough
- default:
- return nil, os.NewSyscallError("connect", err)
- }
- if err := fd.pfd.Init(fd.net, true); err != nil {
- return nil, err
- }
- if deadline, hasDeadline := ctx.Deadline(); hasDeadline {
- fd.pfd.SetWriteDeadline(deadline)
- defer fd.pfd.SetWriteDeadline(noDeadline)
- }
-
- // Start the "interrupter" goroutine, if this context might be canceled.
- //
- // The interrupter goroutine waits for the context to be done and
- // interrupts the dial (by altering the fd's write deadline, which
- // wakes up waitWrite).
- ctxDone := ctx.Done()
- if ctxDone != nil {
- // Wait for the interrupter goroutine to exit before returning
- // from connect.
- done := make(chan struct{})
- interruptRes := make(chan error)
- defer func() {
- close(done)
- if ctxErr := <-interruptRes; ctxErr != nil && ret == nil {
- // The interrupter goroutine called SetWriteDeadline,
- // but the connect code below had returned from
- // waitWrite already and did a successful connect (ret
- // == nil). Because we've now poisoned the connection
- // by making it unwritable, don't return a successful
- // dial. This was issue 16523.
- ret = mapErr(ctxErr)
- fd.Close() // prevent a leak
- }
- }()
- go func() {
- select {
- case <-ctxDone:
- // Force the runtime's poller to immediately give up
- // waiting for writability, unblocking waitWrite
- // below.
- fd.pfd.SetWriteDeadline(aLongTimeAgo)
- testHookCanceledDial()
- interruptRes <- ctx.Err()
- case <-done:
- interruptRes <- nil
- }
- }()
- }
-
- for {
- // Performing multiple connect system calls on a
- // non-blocking socket under Unix variants does not
- // necessarily result in earlier errors being
- // returned. Instead, once runtime-integrated network
- // poller tells us that the socket is ready, get the
- // SO_ERROR socket option to see if the connection
- // succeeded or failed. See issue 7474 for further
- // details.
- if err := fd.pfd.WaitWrite(); err != nil {
- select {
- case <-ctxDone:
- return nil, mapErr(ctx.Err())
- default:
- }
- return nil, err
- }
- nerr, err := getsockoptIntFunc(fd.pfd.Sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
- if err != nil {
- return nil, os.NewSyscallError("getsockopt", err)
- }
- switch err := syscall.Errno(nerr); err {
- case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
- case syscall.EISCONN:
- return nil, nil
- case syscall.Errno(0):
- // The runtime poller can wake us up spuriously;
- // see issues 14548 and 19289. Check that we are
- // really connected; if not, wait again.
- if rsa, err := syscall.Getpeername(fd.pfd.Sysfd); err == nil {
- return rsa, nil
- }
- default:
- return nil, os.NewSyscallError("connect", err)
- }
- runtime.KeepAlive(fd)
- }
-}
-
-func (fd *netFD) accept() (netfd *netFD, err error) {
- d, rsa, errcall, err := fd.pfd.Accept()
- if err != nil {
- if errcall != "" {
- err = wrapSyscallError(errcall, err)
- }
- return nil, err
- }
-
- if netfd, err = newFD(d, fd.family, fd.sotype, fd.net); err != nil {
- poll.CloseFunc(d)
- return nil, err
- }
- if err = netfd.init(); err != nil {
- netfd.Close()
- return nil, err
- }
- lsa, _ := syscall.Getsockname(netfd.pfd.Sysfd)
- netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa))
- return netfd, nil
-}
-
-// Defined in os package.
-func newUnixFile(fd uintptr, name string) *os.File
-
-func (fd *netFD) dup() (f *os.File, err error) {
- ns, call, err := fd.pfd.Dup()
- if err != nil {
- if call != "" {
- err = os.NewSyscallError(call, err)
- }
- return nil, err
- }
-
- return newUnixFile(uintptr(ns), fd.name()), nil
-}
diff --git a/contrib/go/_std_1.20/src/net/fd_windows.go b/contrib/go/_std_1.20/src/net/fd_windows.go
deleted file mode 100644
index 030b6a15fb..0000000000
--- a/contrib/go/_std_1.20/src/net/fd_windows.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2010 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 net
-
-import (
- "context"
- "internal/poll"
- "os"
- "runtime"
- "syscall"
- "unsafe"
-)
-
-const (
- readSyscallName = "wsarecv"
- readFromSyscallName = "wsarecvfrom"
- readMsgSyscallName = "wsarecvmsg"
- writeSyscallName = "wsasend"
- writeToSyscallName = "wsasendto"
- writeMsgSyscallName = "wsasendmsg"
-)
-
-// canUseConnectEx reports whether we can use the ConnectEx Windows API call
-// for the given network type.
-func canUseConnectEx(net string) bool {
- switch net {
- case "tcp", "tcp4", "tcp6":
- return true
- }
- // ConnectEx windows API does not support connectionless sockets.
- return false
-}
-
-func newFD(sysfd syscall.Handle, family, sotype int, net string) (*netFD, error) {
- ret := &netFD{
- pfd: poll.FD{
- Sysfd: sysfd,
- IsStream: sotype == syscall.SOCK_STREAM,
- ZeroReadIsEOF: sotype != syscall.SOCK_DGRAM && sotype != syscall.SOCK_RAW,
- },
- family: family,
- sotype: sotype,
- net: net,
- }
- return ret, nil
-}
-
-func (fd *netFD) init() error {
- errcall, err := fd.pfd.Init(fd.net, true)
- if errcall != "" {
- err = wrapSyscallError(errcall, err)
- }
- return err
-}
-
-// Always returns nil for connected peer address result.
-func (fd *netFD) connect(ctx context.Context, la, ra syscall.Sockaddr) (syscall.Sockaddr, error) {
- // Do not need to call fd.writeLock here,
- // because fd is not yet accessible to user,
- // so no concurrent operations are possible.
- if err := fd.init(); err != nil {
- return nil, err
- }
- if deadline, ok := ctx.Deadline(); ok && !deadline.IsZero() {
- fd.pfd.SetWriteDeadline(deadline)
- defer fd.pfd.SetWriteDeadline(noDeadline)
- }
- if !canUseConnectEx(fd.net) {
- err := connectFunc(fd.pfd.Sysfd, ra)
- return nil, os.NewSyscallError("connect", err)
- }
- // ConnectEx windows API requires an unconnected, previously bound socket.
- if la == nil {
- switch ra.(type) {
- case *syscall.SockaddrInet4:
- la = &syscall.SockaddrInet4{}
- case *syscall.SockaddrInet6:
- la = &syscall.SockaddrInet6{}
- default:
- panic("unexpected type in connect")
- }
- if err := syscall.Bind(fd.pfd.Sysfd, la); err != nil {
- return nil, os.NewSyscallError("bind", err)
- }
- }
-
- // Wait for the goroutine converting context.Done into a write timeout
- // to exist, otherwise our caller might cancel the context and
- // cause fd.setWriteDeadline(aLongTimeAgo) to cancel a successful dial.
- done := make(chan bool) // must be unbuffered
- defer func() { done <- true }()
- go func() {
- select {
- case <-ctx.Done():
- // Force the runtime's poller to immediately give
- // up waiting for writability.
- fd.pfd.SetWriteDeadline(aLongTimeAgo)
- <-done
- case <-done:
- }
- }()
-
- // Call ConnectEx API.
- if err := fd.pfd.ConnectEx(ra); err != nil {
- select {
- case <-ctx.Done():
- return nil, mapErr(ctx.Err())
- default:
- if _, ok := err.(syscall.Errno); ok {
- err = os.NewSyscallError("connectex", err)
- }
- return nil, err
- }
- }
- // Refresh socket properties.
- return nil, os.NewSyscallError("setsockopt", syscall.Setsockopt(fd.pfd.Sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.pfd.Sysfd)), int32(unsafe.Sizeof(fd.pfd.Sysfd))))
-}
-
-func (c *conn) writeBuffers(v *Buffers) (int64, error) {
- if !c.ok() {
- return 0, syscall.EINVAL
- }
- n, err := c.fd.writeBuffers(v)
- if err != nil {
- return n, &OpError{Op: "wsasend", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return n, nil
-}
-
-func (fd *netFD) writeBuffers(buf *Buffers) (int64, error) {
- n, err := fd.pfd.Writev((*[][]byte)(buf))
- runtime.KeepAlive(fd)
- return n, wrapSyscallError("wsasend", err)
-}
-
-func (fd *netFD) accept() (*netFD, error) {
- s, rawsa, rsan, errcall, err := fd.pfd.Accept(func() (syscall.Handle, error) {
- return sysSocket(fd.family, fd.sotype, 0)
- })
-
- if err != nil {
- if errcall != "" {
- err = wrapSyscallError(errcall, err)
- }
- return nil, err
- }
-
- // Associate our new socket with IOCP.
- netfd, err := newFD(s, fd.family, fd.sotype, fd.net)
- if err != nil {
- poll.CloseFunc(s)
- return nil, err
- }
- if err := netfd.init(); err != nil {
- fd.Close()
- return nil, err
- }
-
- // Get local and peer addr out of AcceptEx buffer.
- var lrsa, rrsa *syscall.RawSockaddrAny
- var llen, rlen int32
- syscall.GetAcceptExSockaddrs((*byte)(unsafe.Pointer(&rawsa[0])),
- 0, rsan, rsan, &lrsa, &llen, &rrsa, &rlen)
- lsa, _ := lrsa.Sockaddr()
- rsa, _ := rrsa.Sockaddr()
-
- netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa))
- return netfd, nil
-}
-
-// Unimplemented functions.
-
-func (fd *netFD) dup() (*os.File, error) {
- // TODO: Implement this
- return nil, syscall.EWINDOWS
-}
diff --git a/contrib/go/_std_1.20/src/net/hook_unix.go b/contrib/go/_std_1.20/src/net/hook_unix.go
deleted file mode 100644
index fa82c7e52b..0000000000
--- a/contrib/go/_std_1.20/src/net/hook_unix.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 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.
-
-//go:build unix || (js && wasm)
-
-package net
-
-import "syscall"
-
-var (
- testHookDialChannel = func() {} // for golang.org/issue/5349
- testHookCanceledDial = func() {} // for golang.org/issue/16523
-
- // Placeholders for socket system calls.
- socketFunc func(int, int, int) (int, error) = syscall.Socket
- connectFunc func(int, syscall.Sockaddr) error = syscall.Connect
- listenFunc func(int, int) error = syscall.Listen
- getsockoptIntFunc func(int, int, int) (int, error) = syscall.GetsockoptInt
-)
diff --git a/contrib/go/_std_1.20/src/net/hosts.go b/contrib/go/_std_1.20/src/net/hosts.go
deleted file mode 100644
index dbf8fea136..0000000000
--- a/contrib/go/_std_1.20/src/net/hosts.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2009 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 net
-
-import (
- "internal/bytealg"
- "sync"
- "time"
-)
-
-const cacheMaxAge = 5 * time.Second
-
-func parseLiteralIP(addr string) string {
- var ip IP
- var zone string
- ip = parseIPv4(addr)
- if ip == nil {
- ip, zone = parseIPv6Zone(addr)
- }
- if ip == nil {
- return ""
- }
- if zone == "" {
- return ip.String()
- }
- return ip.String() + "%" + zone
-}
-
-type byName struct {
- addrs []string
- canonicalName string
-}
-
-// hosts contains known host entries.
-var hosts struct {
- sync.Mutex
-
- // Key for the list of literal IP addresses must be a host
- // name. It would be part of DNS labels, a FQDN or an absolute
- // FQDN.
- // For now the key is converted to lower case for convenience.
- byName map[string]byName
-
- // Key for the list of host names must be a literal IP address
- // including IPv6 address with zone identifier.
- // We don't support old-classful IP address notation.
- byAddr map[string][]string
-
- expire time.Time
- path string
- mtime time.Time
- size int64
-}
-
-func readHosts() {
- now := time.Now()
- hp := testHookHostsPath
-
- if now.Before(hosts.expire) && hosts.path == hp && len(hosts.byName) > 0 {
- return
- }
- mtime, size, err := stat(hp)
- if err == nil && hosts.path == hp && hosts.mtime.Equal(mtime) && hosts.size == size {
- hosts.expire = now.Add(cacheMaxAge)
- return
- }
-
- hs := make(map[string]byName)
- is := make(map[string][]string)
-
- var file *file
- if file, _ = open(hp); file == nil {
- return
- }
- for line, ok := file.readLine(); ok; line, ok = file.readLine() {
- if i := bytealg.IndexByteString(line, '#'); i >= 0 {
- // Discard comments.
- line = line[0:i]
- }
- f := getFields(line)
- if len(f) < 2 {
- continue
- }
- addr := parseLiteralIP(f[0])
- if addr == "" {
- continue
- }
-
- var canonical string
- for i := 1; i < len(f); i++ {
- name := absDomainName(f[i])
- h := []byte(f[i])
- lowerASCIIBytes(h)
- key := absDomainName(string(h))
-
- if i == 1 {
- canonical = key
- }
-
- is[addr] = append(is[addr], name)
-
- if v, ok := hs[key]; ok {
- hs[key] = byName{
- addrs: append(v.addrs, addr),
- canonicalName: v.canonicalName,
- }
- continue
- }
-
- hs[key] = byName{
- addrs: []string{addr},
- canonicalName: canonical,
- }
- }
- }
- // Update the data cache.
- hosts.expire = now.Add(cacheMaxAge)
- hosts.path = hp
- hosts.byName = hs
- hosts.byAddr = is
- hosts.mtime = mtime
- hosts.size = size
- file.close()
-}
-
-// lookupStaticHost looks up the addresses and the canonical name for the given host from /etc/hosts.
-func lookupStaticHost(host string) ([]string, string) {
- hosts.Lock()
- defer hosts.Unlock()
- readHosts()
- if len(hosts.byName) != 0 {
- if hasUpperCase(host) {
- lowerHost := []byte(host)
- lowerASCIIBytes(lowerHost)
- host = string(lowerHost)
- }
- if byName, ok := hosts.byName[absDomainName(host)]; ok {
- ipsCp := make([]string, len(byName.addrs))
- copy(ipsCp, byName.addrs)
- return ipsCp, byName.canonicalName
- }
- }
- return nil, ""
-}
-
-// lookupStaticAddr looks up the hosts for the given address from /etc/hosts.
-func lookupStaticAddr(addr string) []string {
- hosts.Lock()
- defer hosts.Unlock()
- readHosts()
- addr = parseLiteralIP(addr)
- if addr == "" {
- return nil
- }
- if len(hosts.byAddr) != 0 {
- if hosts, ok := hosts.byAddr[addr]; ok {
- hostsCp := make([]string, len(hosts))
- copy(hostsCp, hosts)
- return hostsCp
- }
- }
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/net/http/cgi/host.go b/contrib/go/_std_1.20/src/net/http/cgi/host.go
deleted file mode 100644
index 349dda15ac..0000000000
--- a/contrib/go/_std_1.20/src/net/http/cgi/host.go
+++ /dev/null
@@ -1,413 +0,0 @@
-// Copyright 2011 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.
-
-// This file implements the host side of CGI (being the webserver
-// parent process).
-
-// Package cgi implements CGI (Common Gateway Interface) as specified
-// in RFC 3875.
-//
-// Note that using CGI means starting a new process to handle each
-// request, which is typically less efficient than using a
-// long-running server. This package is intended primarily for
-// compatibility with existing systems.
-package cgi
-
-import (
- "bufio"
- "fmt"
- "io"
- "log"
- "net"
- "net/http"
- "net/textproto"
- "os"
- "os/exec"
- "path/filepath"
- "regexp"
- "runtime"
- "strconv"
- "strings"
-
- "golang.org/x/net/http/httpguts"
-)
-
-var trailingPort = regexp.MustCompile(`:([0-9]+)$`)
-
-var osDefaultInheritEnv = func() []string {
- switch runtime.GOOS {
- case "darwin", "ios":
- return []string{"DYLD_LIBRARY_PATH"}
- case "linux", "freebsd", "netbsd", "openbsd":
- return []string{"LD_LIBRARY_PATH"}
- case "hpux":
- return []string{"LD_LIBRARY_PATH", "SHLIB_PATH"}
- case "irix":
- return []string{"LD_LIBRARY_PATH", "LD_LIBRARYN32_PATH", "LD_LIBRARY64_PATH"}
- case "illumos", "solaris":
- return []string{"LD_LIBRARY_PATH", "LD_LIBRARY_PATH_32", "LD_LIBRARY_PATH_64"}
- case "windows":
- return []string{"SystemRoot", "COMSPEC", "PATHEXT", "WINDIR"}
- }
- return nil
-}()
-
-// Handler runs an executable in a subprocess with a CGI environment.
-type Handler struct {
- Path string // path to the CGI executable
- Root string // root URI prefix of handler or empty for "/"
-
- // Dir specifies the CGI executable's working directory.
- // If Dir is empty, the base directory of Path is used.
- // If Path has no base directory, the current working
- // directory is used.
- Dir string
-
- Env []string // extra environment variables to set, if any, as "key=value"
- InheritEnv []string // environment variables to inherit from host, as "key"
- Logger *log.Logger // optional log for errors or nil to use log.Print
- Args []string // optional arguments to pass to child process
- Stderr io.Writer // optional stderr for the child process; nil means os.Stderr
-
- // PathLocationHandler specifies the root http Handler that
- // should handle internal redirects when the CGI process
- // returns a Location header value starting with a "/", as
- // specified in RFC 3875 § 6.3.2. This will likely be
- // http.DefaultServeMux.
- //
- // If nil, a CGI response with a local URI path is instead sent
- // back to the client and not redirected internally.
- PathLocationHandler http.Handler
-}
-
-func (h *Handler) stderr() io.Writer {
- if h.Stderr != nil {
- return h.Stderr
- }
- return os.Stderr
-}
-
-// removeLeadingDuplicates remove leading duplicate in environments.
-// It's possible to override environment like following.
-//
-// cgi.Handler{
-// ...
-// Env: []string{"SCRIPT_FILENAME=foo.php"},
-// }
-func removeLeadingDuplicates(env []string) (ret []string) {
- for i, e := range env {
- found := false
- if eq := strings.IndexByte(e, '='); eq != -1 {
- keq := e[:eq+1] // "key="
- for _, e2 := range env[i+1:] {
- if strings.HasPrefix(e2, keq) {
- found = true
- break
- }
- }
- }
- if !found {
- ret = append(ret, e)
- }
- }
- return
-}
-
-func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
- root := h.Root
- if root == "" {
- root = "/"
- }
-
- if len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked" {
- rw.WriteHeader(http.StatusBadRequest)
- rw.Write([]byte("Chunked request bodies are not supported by CGI."))
- return
- }
-
- pathInfo := req.URL.Path
- if root != "/" && strings.HasPrefix(pathInfo, root) {
- pathInfo = pathInfo[len(root):]
- }
-
- port := "80"
- if matches := trailingPort.FindStringSubmatch(req.Host); len(matches) != 0 {
- port = matches[1]
- }
-
- env := []string{
- "SERVER_SOFTWARE=go",
- "SERVER_PROTOCOL=HTTP/1.1",
- "HTTP_HOST=" + req.Host,
- "GATEWAY_INTERFACE=CGI/1.1",
- "REQUEST_METHOD=" + req.Method,
- "QUERY_STRING=" + req.URL.RawQuery,
- "REQUEST_URI=" + req.URL.RequestURI(),
- "PATH_INFO=" + pathInfo,
- "SCRIPT_NAME=" + root,
- "SCRIPT_FILENAME=" + h.Path,
- "SERVER_PORT=" + port,
- }
-
- if remoteIP, remotePort, err := net.SplitHostPort(req.RemoteAddr); err == nil {
- env = append(env, "REMOTE_ADDR="+remoteIP, "REMOTE_HOST="+remoteIP, "REMOTE_PORT="+remotePort)
- } else {
- // could not parse ip:port, let's use whole RemoteAddr and leave REMOTE_PORT undefined
- env = append(env, "REMOTE_ADDR="+req.RemoteAddr, "REMOTE_HOST="+req.RemoteAddr)
- }
-
- if hostDomain, _, err := net.SplitHostPort(req.Host); err == nil {
- env = append(env, "SERVER_NAME="+hostDomain)
- } else {
- env = append(env, "SERVER_NAME="+req.Host)
- }
-
- if req.TLS != nil {
- env = append(env, "HTTPS=on")
- }
-
- for k, v := range req.Header {
- k = strings.Map(upperCaseAndUnderscore, k)
- if k == "PROXY" {
- // See Issue 16405
- continue
- }
- joinStr := ", "
- if k == "COOKIE" {
- joinStr = "; "
- }
- env = append(env, "HTTP_"+k+"="+strings.Join(v, joinStr))
- }
-
- if req.ContentLength > 0 {
- env = append(env, fmt.Sprintf("CONTENT_LENGTH=%d", req.ContentLength))
- }
- if ctype := req.Header.Get("Content-Type"); ctype != "" {
- env = append(env, "CONTENT_TYPE="+ctype)
- }
-
- envPath := os.Getenv("PATH")
- if envPath == "" {
- envPath = "/bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin"
- }
- env = append(env, "PATH="+envPath)
-
- for _, e := range h.InheritEnv {
- if v := os.Getenv(e); v != "" {
- env = append(env, e+"="+v)
- }
- }
-
- for _, e := range osDefaultInheritEnv {
- if v := os.Getenv(e); v != "" {
- env = append(env, e+"="+v)
- }
- }
-
- if h.Env != nil {
- env = append(env, h.Env...)
- }
-
- env = removeLeadingDuplicates(env)
-
- var cwd, path string
- if h.Dir != "" {
- path = h.Path
- cwd = h.Dir
- } else {
- cwd, path = filepath.Split(h.Path)
- }
- if cwd == "" {
- cwd = "."
- }
-
- internalError := func(err error) {
- rw.WriteHeader(http.StatusInternalServerError)
- h.printf("CGI error: %v", err)
- }
-
- cmd := &exec.Cmd{
- Path: path,
- Args: append([]string{h.Path}, h.Args...),
- Dir: cwd,
- Env: env,
- Stderr: h.stderr(),
- }
- if req.ContentLength != 0 {
- cmd.Stdin = req.Body
- }
- stdoutRead, err := cmd.StdoutPipe()
- if err != nil {
- internalError(err)
- return
- }
-
- err = cmd.Start()
- if err != nil {
- internalError(err)
- return
- }
- if hook := testHookStartProcess; hook != nil {
- hook(cmd.Process)
- }
- defer cmd.Wait()
- defer stdoutRead.Close()
-
- linebody := bufio.NewReaderSize(stdoutRead, 1024)
- headers := make(http.Header)
- statusCode := 0
- headerLines := 0
- sawBlankLine := false
- for {
- line, isPrefix, err := linebody.ReadLine()
- if isPrefix {
- rw.WriteHeader(http.StatusInternalServerError)
- h.printf("cgi: long header line from subprocess.")
- return
- }
- if err == io.EOF {
- break
- }
- if err != nil {
- rw.WriteHeader(http.StatusInternalServerError)
- h.printf("cgi: error reading headers: %v", err)
- return
- }
- if len(line) == 0 {
- sawBlankLine = true
- break
- }
- headerLines++
- header, val, ok := strings.Cut(string(line), ":")
- if !ok {
- h.printf("cgi: bogus header line: %s", string(line))
- continue
- }
- if !httpguts.ValidHeaderFieldName(header) {
- h.printf("cgi: invalid header name: %q", header)
- continue
- }
- val = textproto.TrimString(val)
- switch {
- case header == "Status":
- if len(val) < 3 {
- h.printf("cgi: bogus status (short): %q", val)
- return
- }
- code, err := strconv.Atoi(val[0:3])
- if err != nil {
- h.printf("cgi: bogus status: %q", val)
- h.printf("cgi: line was %q", line)
- return
- }
- statusCode = code
- default:
- headers.Add(header, val)
- }
- }
- if headerLines == 0 || !sawBlankLine {
- rw.WriteHeader(http.StatusInternalServerError)
- h.printf("cgi: no headers")
- return
- }
-
- if loc := headers.Get("Location"); loc != "" {
- if strings.HasPrefix(loc, "/") && h.PathLocationHandler != nil {
- h.handleInternalRedirect(rw, req, loc)
- return
- }
- if statusCode == 0 {
- statusCode = http.StatusFound
- }
- }
-
- if statusCode == 0 && headers.Get("Content-Type") == "" {
- rw.WriteHeader(http.StatusInternalServerError)
- h.printf("cgi: missing required Content-Type in headers")
- return
- }
-
- if statusCode == 0 {
- statusCode = http.StatusOK
- }
-
- // Copy headers to rw's headers, after we've decided not to
- // go into handleInternalRedirect, which won't want its rw
- // headers to have been touched.
- for k, vv := range headers {
- for _, v := range vv {
- rw.Header().Add(k, v)
- }
- }
-
- rw.WriteHeader(statusCode)
-
- _, err = io.Copy(rw, linebody)
- if err != nil {
- h.printf("cgi: copy error: %v", err)
- // And kill the child CGI process so we don't hang on
- // the deferred cmd.Wait above if the error was just
- // the client (rw) going away. If it was a read error
- // (because the child died itself), then the extra
- // kill of an already-dead process is harmless (the PID
- // won't be reused until the Wait above).
- cmd.Process.Kill()
- }
-}
-
-func (h *Handler) printf(format string, v ...any) {
- if h.Logger != nil {
- h.Logger.Printf(format, v...)
- } else {
- log.Printf(format, v...)
- }
-}
-
-func (h *Handler) handleInternalRedirect(rw http.ResponseWriter, req *http.Request, path string) {
- url, err := req.URL.Parse(path)
- if err != nil {
- rw.WriteHeader(http.StatusInternalServerError)
- h.printf("cgi: error resolving local URI path %q: %v", path, err)
- return
- }
- // TODO: RFC 3875 isn't clear if only GET is supported, but it
- // suggests so: "Note that any message-body attached to the
- // request (such as for a POST request) may not be available
- // to the resource that is the target of the redirect." We
- // should do some tests against Apache to see how it handles
- // POST, HEAD, etc. Does the internal redirect get the same
- // method or just GET? What about incoming headers?
- // (e.g. Cookies) Which headers, if any, are copied into the
- // second request?
- newReq := &http.Request{
- Method: "GET",
- URL: url,
- Proto: "HTTP/1.1",
- ProtoMajor: 1,
- ProtoMinor: 1,
- Header: make(http.Header),
- Host: url.Host,
- RemoteAddr: req.RemoteAddr,
- TLS: req.TLS,
- }
- h.PathLocationHandler.ServeHTTP(rw, newReq)
-}
-
-func upperCaseAndUnderscore(r rune) rune {
- switch {
- case r >= 'a' && r <= 'z':
- return r - ('a' - 'A')
- case r == '-':
- return '_'
- case r == '=':
- // Maybe not part of the CGI 'spec' but would mess up
- // the environment in any case, as Go represents the
- // environment as a slice of "key=value" strings.
- return '_'
- }
- // TODO: other transformations in spec or practice?
- return r
-}
-
-var testHookStartProcess func(*os.Process) // nil except for some tests
diff --git a/contrib/go/_std_1.20/src/net/http/cgi/ya.make b/contrib/go/_std_1.20/src/net/http/cgi/ya.make
deleted file mode 100644
index 77667ec3af..0000000000
--- a/contrib/go/_std_1.20/src/net/http/cgi/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- child.go
- host.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/http/client.go b/contrib/go/_std_1.20/src/net/http/client.go
deleted file mode 100644
index 122e8d030d..0000000000
--- a/contrib/go/_std_1.20/src/net/http/client.go
+++ /dev/null
@@ -1,1024 +0,0 @@
-// Copyright 2009 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.
-
-// HTTP client. See RFC 7230 through 7235.
-//
-// This is the high-level Client interface.
-// The low-level implementation is in transport.go.
-
-package http
-
-import (
- "context"
- "crypto/tls"
- "encoding/base64"
- "errors"
- "fmt"
- "io"
- "log"
- "net/http/internal/ascii"
- "net/url"
- "reflect"
- "sort"
- "strings"
- "sync"
- "sync/atomic"
- "time"
-)
-
-// A Client is an HTTP client. Its zero value (DefaultClient) is a
-// usable client that uses DefaultTransport.
-//
-// The Client's Transport typically has internal state (cached TCP
-// connections), so Clients should be reused instead of created as
-// needed. Clients are safe for concurrent use by multiple goroutines.
-//
-// A Client is higher-level than a RoundTripper (such as Transport)
-// and additionally handles HTTP details such as cookies and
-// redirects.
-//
-// When following redirects, the Client will forward all headers set on the
-// initial Request except:
-//
-// • when forwarding sensitive headers like "Authorization",
-// "WWW-Authenticate", and "Cookie" to untrusted targets.
-// These headers will be ignored when following a redirect to a domain
-// that is not a subdomain match or exact match of the initial domain.
-// For example, a redirect from "foo.com" to either "foo.com" or "sub.foo.com"
-// will forward the sensitive headers, but a redirect to "bar.com" will not.
-//
-// • when forwarding the "Cookie" header with a non-nil cookie Jar.
-// Since each redirect may mutate the state of the cookie jar,
-// a redirect may possibly alter a cookie set in the initial request.
-// When forwarding the "Cookie" header, any mutated cookies will be omitted,
-// with the expectation that the Jar will insert those mutated cookies
-// with the updated values (assuming the origin matches).
-// If Jar is nil, the initial cookies are forwarded without change.
-type Client struct {
- // Transport specifies the mechanism by which individual
- // HTTP requests are made.
- // If nil, DefaultTransport is used.
- Transport RoundTripper
-
- // CheckRedirect specifies the policy for handling redirects.
- // If CheckRedirect is not nil, the client calls it before
- // following an HTTP redirect. The arguments req and via are
- // the upcoming request and the requests made already, oldest
- // first. If CheckRedirect returns an error, the Client's Get
- // method returns both the previous Response (with its Body
- // closed) and CheckRedirect's error (wrapped in a url.Error)
- // instead of issuing the Request req.
- // As a special case, if CheckRedirect returns ErrUseLastResponse,
- // then the most recent response is returned with its body
- // unclosed, along with a nil error.
- //
- // If CheckRedirect is nil, the Client uses its default policy,
- // which is to stop after 10 consecutive requests.
- CheckRedirect func(req *Request, via []*Request) error
-
- // Jar specifies the cookie jar.
- //
- // The Jar is used to insert relevant cookies into every
- // outbound Request and is updated with the cookie values
- // of every inbound Response. The Jar is consulted for every
- // redirect that the Client follows.
- //
- // If Jar is nil, cookies are only sent if they are explicitly
- // set on the Request.
- Jar CookieJar
-
- // Timeout specifies a time limit for requests made by this
- // Client. The timeout includes connection time, any
- // redirects, and reading the response body. The timer remains
- // running after Get, Head, Post, or Do return and will
- // interrupt reading of the Response.Body.
- //
- // A Timeout of zero means no timeout.
- //
- // The Client cancels requests to the underlying Transport
- // as if the Request's Context ended.
- //
- // For compatibility, the Client will also use the deprecated
- // CancelRequest method on Transport if found. New
- // RoundTripper implementations should use the Request's Context
- // for cancellation instead of implementing CancelRequest.
- Timeout time.Duration
-}
-
-// DefaultClient is the default Client and is used by Get, Head, and Post.
-var DefaultClient = &Client{}
-
-// RoundTripper is an interface representing the ability to execute a
-// single HTTP transaction, obtaining the Response for a given Request.
-//
-// A RoundTripper must be safe for concurrent use by multiple
-// goroutines.
-type RoundTripper interface {
- // RoundTrip executes a single HTTP transaction, returning
- // a Response for the provided Request.
- //
- // RoundTrip should not attempt to interpret the response. In
- // particular, RoundTrip must return err == nil if it obtained
- // a response, regardless of the response's HTTP status code.
- // A non-nil err should be reserved for failure to obtain a
- // response. Similarly, RoundTrip should not attempt to
- // handle higher-level protocol details such as redirects,
- // authentication, or cookies.
- //
- // RoundTrip should not modify the request, except for
- // consuming and closing the Request's Body. RoundTrip may
- // read fields of the request in a separate goroutine. Callers
- // should not mutate or reuse the request until the Response's
- // Body has been closed.
- //
- // RoundTrip must always close the body, including on errors,
- // but depending on the implementation may do so in a separate
- // goroutine even after RoundTrip returns. This means that
- // callers wanting to reuse the body for subsequent requests
- // must arrange to wait for the Close call before doing so.
- //
- // The Request's URL and Header fields must be initialized.
- RoundTrip(*Request) (*Response, error)
-}
-
-// refererForURL returns a referer without any authentication info or
-// an empty string if lastReq scheme is https and newReq scheme is http.
-func refererForURL(lastReq, newReq *url.URL) string {
- // https://tools.ietf.org/html/rfc7231#section-5.5.2
- // "Clients SHOULD NOT include a Referer header field in a
- // (non-secure) HTTP request if the referring page was
- // transferred with a secure protocol."
- if lastReq.Scheme == "https" && newReq.Scheme == "http" {
- return ""
- }
- referer := lastReq.String()
- if lastReq.User != nil {
- // This is not very efficient, but is the best we can
- // do without:
- // - introducing a new method on URL
- // - creating a race condition
- // - copying the URL struct manually, which would cause
- // maintenance problems down the line
- auth := lastReq.User.String() + "@"
- referer = strings.Replace(referer, auth, "", 1)
- }
- return referer
-}
-
-// didTimeout is non-nil only if err != nil.
-func (c *Client) send(req *Request, deadline time.Time) (resp *Response, didTimeout func() bool, err error) {
- if c.Jar != nil {
- for _, cookie := range c.Jar.Cookies(req.URL) {
- req.AddCookie(cookie)
- }
- }
- resp, didTimeout, err = send(req, c.transport(), deadline)
- if err != nil {
- return nil, didTimeout, err
- }
- if c.Jar != nil {
- if rc := resp.Cookies(); len(rc) > 0 {
- c.Jar.SetCookies(req.URL, rc)
- }
- }
- return resp, nil, nil
-}
-
-func (c *Client) deadline() time.Time {
- if c.Timeout > 0 {
- return time.Now().Add(c.Timeout)
- }
- return time.Time{}
-}
-
-func (c *Client) transport() RoundTripper {
- if c.Transport != nil {
- return c.Transport
- }
- return DefaultTransport
-}
-
-// send issues an HTTP request.
-// Caller should close resp.Body when done reading from it.
-func send(ireq *Request, rt RoundTripper, deadline time.Time) (resp *Response, didTimeout func() bool, err error) {
- req := ireq // req is either the original request, or a modified fork
-
- if rt == nil {
- req.closeBody()
- return nil, alwaysFalse, errors.New("http: no Client.Transport or DefaultTransport")
- }
-
- if req.URL == nil {
- req.closeBody()
- return nil, alwaysFalse, errors.New("http: nil Request.URL")
- }
-
- if req.RequestURI != "" {
- req.closeBody()
- return nil, alwaysFalse, errors.New("http: Request.RequestURI can't be set in client requests")
- }
-
- // forkReq forks req into a shallow clone of ireq the first
- // time it's called.
- forkReq := func() {
- if ireq == req {
- req = new(Request)
- *req = *ireq // shallow clone
- }
- }
-
- // Most the callers of send (Get, Post, et al) don't need
- // Headers, leaving it uninitialized. We guarantee to the
- // Transport that this has been initialized, though.
- if req.Header == nil {
- forkReq()
- req.Header = make(Header)
- }
-
- if u := req.URL.User; u != nil && req.Header.Get("Authorization") == "" {
- username := u.Username()
- password, _ := u.Password()
- forkReq()
- req.Header = cloneOrMakeHeader(ireq.Header)
- req.Header.Set("Authorization", "Basic "+basicAuth(username, password))
- }
-
- if !deadline.IsZero() {
- forkReq()
- }
- stopTimer, didTimeout := setRequestCancel(req, rt, deadline)
-
- resp, err = rt.RoundTrip(req)
- if err != nil {
- stopTimer()
- if resp != nil {
- log.Printf("RoundTripper returned a response & error; ignoring response")
- }
- if tlsErr, ok := err.(tls.RecordHeaderError); ok {
- // If we get a bad TLS record header, check to see if the
- // response looks like HTTP and give a more helpful error.
- // See golang.org/issue/11111.
- if string(tlsErr.RecordHeader[:]) == "HTTP/" {
- err = errors.New("http: server gave HTTP response to HTTPS client")
- }
- }
- return nil, didTimeout, err
- }
- if resp == nil {
- return nil, didTimeout, fmt.Errorf("http: RoundTripper implementation (%T) returned a nil *Response with a nil error", rt)
- }
- if resp.Body == nil {
- // The documentation on the Body field says “The http Client and Transport
- // guarantee that Body is always non-nil, even on responses without a body
- // or responses with a zero-length body.” Unfortunately, we didn't document
- // that same constraint for arbitrary RoundTripper implementations, and
- // RoundTripper implementations in the wild (mostly in tests) assume that
- // they can use a nil Body to mean an empty one (similar to Request.Body).
- // (See https://golang.org/issue/38095.)
- //
- // If the ContentLength allows the Body to be empty, fill in an empty one
- // here to ensure that it is non-nil.
- if resp.ContentLength > 0 && req.Method != "HEAD" {
- return nil, didTimeout, fmt.Errorf("http: RoundTripper implementation (%T) returned a *Response with content length %d but a nil Body", rt, resp.ContentLength)
- }
- resp.Body = io.NopCloser(strings.NewReader(""))
- }
- if !deadline.IsZero() {
- resp.Body = &cancelTimerBody{
- stop: stopTimer,
- rc: resp.Body,
- reqDidTimeout: didTimeout,
- }
- }
- return resp, nil, nil
-}
-
-// timeBeforeContextDeadline reports whether the non-zero Time t is
-// before ctx's deadline, if any. If ctx does not have a deadline, it
-// always reports true (the deadline is considered infinite).
-func timeBeforeContextDeadline(t time.Time, ctx context.Context) bool {
- d, ok := ctx.Deadline()
- if !ok {
- return true
- }
- return t.Before(d)
-}
-
-// knownRoundTripperImpl reports whether rt is a RoundTripper that's
-// maintained by the Go team and known to implement the latest
-// optional semantics (notably contexts). The Request is used
-// to check whether this particular request is using an alternate protocol,
-// in which case we need to check the RoundTripper for that protocol.
-func knownRoundTripperImpl(rt RoundTripper, req *Request) bool {
- switch t := rt.(type) {
- case *Transport:
- if altRT := t.alternateRoundTripper(req); altRT != nil {
- return knownRoundTripperImpl(altRT, req)
- }
- return true
- case *http2Transport, http2noDialH2RoundTripper:
- return true
- }
- // There's a very minor chance of a false positive with this.
- // Instead of detecting our golang.org/x/net/http2.Transport,
- // it might detect a Transport type in a different http2
- // package. But I know of none, and the only problem would be
- // some temporarily leaked goroutines if the transport didn't
- // support contexts. So this is a good enough heuristic:
- if reflect.TypeOf(rt).String() == "*http2.Transport" {
- return true
- }
- return false
-}
-
-// setRequestCancel sets req.Cancel and adds a deadline context to req
-// if deadline is non-zero. The RoundTripper's type is used to
-// determine whether the legacy CancelRequest behavior should be used.
-//
-// As background, there are three ways to cancel a request:
-// First was Transport.CancelRequest. (deprecated)
-// Second was Request.Cancel.
-// Third was Request.Context.
-// This function populates the second and third, and uses the first if it really needs to.
-func setRequestCancel(req *Request, rt RoundTripper, deadline time.Time) (stopTimer func(), didTimeout func() bool) {
- if deadline.IsZero() {
- return nop, alwaysFalse
- }
- knownTransport := knownRoundTripperImpl(rt, req)
- oldCtx := req.Context()
-
- if req.Cancel == nil && knownTransport {
- // If they already had a Request.Context that's
- // expiring sooner, do nothing:
- if !timeBeforeContextDeadline(deadline, oldCtx) {
- return nop, alwaysFalse
- }
-
- var cancelCtx func()
- req.ctx, cancelCtx = context.WithDeadline(oldCtx, deadline)
- return cancelCtx, func() bool { return time.Now().After(deadline) }
- }
- initialReqCancel := req.Cancel // the user's original Request.Cancel, if any
-
- var cancelCtx func()
- if timeBeforeContextDeadline(deadline, oldCtx) {
- req.ctx, cancelCtx = context.WithDeadline(oldCtx, deadline)
- }
-
- cancel := make(chan struct{})
- req.Cancel = cancel
-
- doCancel := func() {
- // The second way in the func comment above:
- close(cancel)
- // The first way, used only for RoundTripper
- // implementations written before Go 1.5 or Go 1.6.
- type canceler interface{ CancelRequest(*Request) }
- if v, ok := rt.(canceler); ok {
- v.CancelRequest(req)
- }
- }
-
- stopTimerCh := make(chan struct{})
- var once sync.Once
- stopTimer = func() {
- once.Do(func() {
- close(stopTimerCh)
- if cancelCtx != nil {
- cancelCtx()
- }
- })
- }
-
- timer := time.NewTimer(time.Until(deadline))
- var timedOut atomic.Bool
-
- go func() {
- select {
- case <-initialReqCancel:
- doCancel()
- timer.Stop()
- case <-timer.C:
- timedOut.Store(true)
- doCancel()
- case <-stopTimerCh:
- timer.Stop()
- }
- }()
-
- return stopTimer, timedOut.Load
-}
-
-// See 2 (end of page 4) https://www.ietf.org/rfc/rfc2617.txt
-// "To receive authorization, the client sends the userid and password,
-// separated by a single colon (":") character, within a base64
-// encoded string in the credentials."
-// It is not meant to be urlencoded.
-func basicAuth(username, password string) string {
- auth := username + ":" + password
- return base64.StdEncoding.EncodeToString([]byte(auth))
-}
-
-// Get issues a GET to the specified URL. If the response is one of
-// the following redirect codes, Get follows the redirect, up to a
-// maximum of 10 redirects:
-//
-// 301 (Moved Permanently)
-// 302 (Found)
-// 303 (See Other)
-// 307 (Temporary Redirect)
-// 308 (Permanent Redirect)
-//
-// An error is returned if there were too many redirects or if there
-// was an HTTP protocol error. A non-2xx response doesn't cause an
-// error. Any returned error will be of type *url.Error. The url.Error
-// value's Timeout method will report true if the request timed out.
-//
-// When err is nil, resp always contains a non-nil resp.Body.
-// Caller should close resp.Body when done reading from it.
-//
-// Get is a wrapper around DefaultClient.Get.
-//
-// To make a request with custom headers, use NewRequest and
-// DefaultClient.Do.
-//
-// To make a request with a specified context.Context, use NewRequestWithContext
-// and DefaultClient.Do.
-func Get(url string) (resp *Response, err error) {
- return DefaultClient.Get(url)
-}
-
-// Get issues a GET to the specified URL. If the response is one of the
-// following redirect codes, Get follows the redirect after calling the
-// Client's CheckRedirect function:
-//
-// 301 (Moved Permanently)
-// 302 (Found)
-// 303 (See Other)
-// 307 (Temporary Redirect)
-// 308 (Permanent Redirect)
-//
-// An error is returned if the Client's CheckRedirect function fails
-// or if there was an HTTP protocol error. A non-2xx response doesn't
-// cause an error. Any returned error will be of type *url.Error. The
-// url.Error value's Timeout method will report true if the request
-// timed out.
-//
-// When err is nil, resp always contains a non-nil resp.Body.
-// Caller should close resp.Body when done reading from it.
-//
-// To make a request with custom headers, use NewRequest and Client.Do.
-//
-// To make a request with a specified context.Context, use NewRequestWithContext
-// and Client.Do.
-func (c *Client) Get(url string) (resp *Response, err error) {
- req, err := NewRequest("GET", url, nil)
- if err != nil {
- return nil, err
- }
- return c.Do(req)
-}
-
-func alwaysFalse() bool { return false }
-
-// ErrUseLastResponse can be returned by Client.CheckRedirect hooks to
-// control how redirects are processed. If returned, the next request
-// is not sent and the most recent response is returned with its body
-// unclosed.
-var ErrUseLastResponse = errors.New("net/http: use last response")
-
-// checkRedirect calls either the user's configured CheckRedirect
-// function, or the default.
-func (c *Client) checkRedirect(req *Request, via []*Request) error {
- fn := c.CheckRedirect
- if fn == nil {
- fn = defaultCheckRedirect
- }
- return fn(req, via)
-}
-
-// redirectBehavior describes what should happen when the
-// client encounters a 3xx status code from the server.
-func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirectMethod string, shouldRedirect, includeBody bool) {
- switch resp.StatusCode {
- case 301, 302, 303:
- redirectMethod = reqMethod
- shouldRedirect = true
- includeBody = false
-
- // RFC 2616 allowed automatic redirection only with GET and
- // HEAD requests. RFC 7231 lifts this restriction, but we still
- // restrict other methods to GET to maintain compatibility.
- // See Issue 18570.
- if reqMethod != "GET" && reqMethod != "HEAD" {
- redirectMethod = "GET"
- }
- case 307, 308:
- redirectMethod = reqMethod
- shouldRedirect = true
- includeBody = true
-
- if ireq.GetBody == nil && ireq.outgoingLength() != 0 {
- // We had a request body, and 307/308 require
- // re-sending it, but GetBody is not defined. So just
- // return this response to the user instead of an
- // error, like we did in Go 1.7 and earlier.
- shouldRedirect = false
- }
- }
- return redirectMethod, shouldRedirect, includeBody
-}
-
-// urlErrorOp returns the (*url.Error).Op value to use for the
-// provided (*Request).Method value.
-func urlErrorOp(method string) string {
- if method == "" {
- return "Get"
- }
- if lowerMethod, ok := ascii.ToLower(method); ok {
- return method[:1] + lowerMethod[1:]
- }
- return method
-}
-
-// Do sends an HTTP request and returns an HTTP response, following
-// policy (such as redirects, cookies, auth) as configured on the
-// client.
-//
-// An error is returned if caused by client policy (such as
-// CheckRedirect), or failure to speak HTTP (such as a network
-// connectivity problem). A non-2xx status code doesn't cause an
-// error.
-//
-// If the returned error is nil, the Response will contain a non-nil
-// Body which the user is expected to close. If the Body is not both
-// read to EOF and closed, the Client's underlying RoundTripper
-// (typically Transport) may not be able to re-use a persistent TCP
-// connection to the server for a subsequent "keep-alive" request.
-//
-// The request Body, if non-nil, will be closed by the underlying
-// Transport, even on errors.
-//
-// On error, any Response can be ignored. A non-nil Response with a
-// non-nil error only occurs when CheckRedirect fails, and even then
-// the returned Response.Body is already closed.
-//
-// Generally Get, Post, or PostForm will be used instead of Do.
-//
-// If the server replies with a redirect, the Client first uses the
-// CheckRedirect function to determine whether the redirect should be
-// followed. If permitted, a 301, 302, or 303 redirect causes
-// subsequent requests to use HTTP method GET
-// (or HEAD if the original request was HEAD), with no body.
-// A 307 or 308 redirect preserves the original HTTP method and body,
-// provided that the Request.GetBody function is defined.
-// The NewRequest function automatically sets GetBody for common
-// standard library body types.
-//
-// Any returned error will be of type *url.Error. The url.Error
-// value's Timeout method will report true if the request timed out.
-func (c *Client) Do(req *Request) (*Response, error) {
- return c.do(req)
-}
-
-var testHookClientDoResult func(retres *Response, reterr error)
-
-func (c *Client) do(req *Request) (retres *Response, reterr error) {
- if testHookClientDoResult != nil {
- defer func() { testHookClientDoResult(retres, reterr) }()
- }
- if req.URL == nil {
- req.closeBody()
- return nil, &url.Error{
- Op: urlErrorOp(req.Method),
- Err: errors.New("http: nil Request.URL"),
- }
- }
-
- var (
- deadline = c.deadline()
- reqs []*Request
- resp *Response
- copyHeaders = c.makeHeadersCopier(req)
- reqBodyClosed = false // have we closed the current req.Body?
-
- // Redirect behavior:
- redirectMethod string
- includeBody bool
- )
- uerr := func(err error) error {
- // the body may have been closed already by c.send()
- if !reqBodyClosed {
- req.closeBody()
- }
- var urlStr string
- if resp != nil && resp.Request != nil {
- urlStr = stripPassword(resp.Request.URL)
- } else {
- urlStr = stripPassword(req.URL)
- }
- return &url.Error{
- Op: urlErrorOp(reqs[0].Method),
- URL: urlStr,
- Err: err,
- }
- }
- for {
- // For all but the first request, create the next
- // request hop and replace req.
- if len(reqs) > 0 {
- loc := resp.Header.Get("Location")
- if loc == "" {
- // While most 3xx responses include a Location, it is not
- // required and 3xx responses without a Location have been
- // observed in the wild. See issues #17773 and #49281.
- return resp, nil
- }
- u, err := req.URL.Parse(loc)
- if err != nil {
- resp.closeBody()
- return nil, uerr(fmt.Errorf("failed to parse Location header %q: %v", loc, err))
- }
- host := ""
- if req.Host != "" && req.Host != req.URL.Host {
- // If the caller specified a custom Host header and the
- // redirect location is relative, preserve the Host header
- // through the redirect. See issue #22233.
- if u, _ := url.Parse(loc); u != nil && !u.IsAbs() {
- host = req.Host
- }
- }
- ireq := reqs[0]
- req = &Request{
- Method: redirectMethod,
- Response: resp,
- URL: u,
- Header: make(Header),
- Host: host,
- Cancel: ireq.Cancel,
- ctx: ireq.ctx,
- }
- if includeBody && ireq.GetBody != nil {
- req.Body, err = ireq.GetBody()
- if err != nil {
- resp.closeBody()
- return nil, uerr(err)
- }
- req.ContentLength = ireq.ContentLength
- }
-
- // Copy original headers before setting the Referer,
- // in case the user set Referer on their first request.
- // If they really want to override, they can do it in
- // their CheckRedirect func.
- copyHeaders(req)
-
- // Add the Referer header from the most recent
- // request URL to the new one, if it's not https->http:
- if ref := refererForURL(reqs[len(reqs)-1].URL, req.URL); ref != "" {
- req.Header.Set("Referer", ref)
- }
- err = c.checkRedirect(req, reqs)
-
- // Sentinel error to let users select the
- // previous response, without closing its
- // body. See Issue 10069.
- if err == ErrUseLastResponse {
- return resp, nil
- }
-
- // Close the previous response's body. But
- // read at least some of the body so if it's
- // small the underlying TCP connection will be
- // re-used. No need to check for errors: if it
- // fails, the Transport won't reuse it anyway.
- const maxBodySlurpSize = 2 << 10
- if resp.ContentLength == -1 || resp.ContentLength <= maxBodySlurpSize {
- io.CopyN(io.Discard, resp.Body, maxBodySlurpSize)
- }
- resp.Body.Close()
-
- if err != nil {
- // Special case for Go 1 compatibility: return both the response
- // and an error if the CheckRedirect function failed.
- // See https://golang.org/issue/3795
- // The resp.Body has already been closed.
- ue := uerr(err)
- ue.(*url.Error).URL = loc
- return resp, ue
- }
- }
-
- reqs = append(reqs, req)
- var err error
- var didTimeout func() bool
- if resp, didTimeout, err = c.send(req, deadline); err != nil {
- // c.send() always closes req.Body
- reqBodyClosed = true
- if !deadline.IsZero() && didTimeout() {
- err = &httpError{
- err: err.Error() + " (Client.Timeout exceeded while awaiting headers)",
- timeout: true,
- }
- }
- return nil, uerr(err)
- }
-
- var shouldRedirect bool
- redirectMethod, shouldRedirect, includeBody = redirectBehavior(req.Method, resp, reqs[0])
- if !shouldRedirect {
- return resp, nil
- }
-
- req.closeBody()
- }
-}
-
-// makeHeadersCopier makes a function that copies headers from the
-// initial Request, ireq. For every redirect, this function must be called
-// so that it can copy headers into the upcoming Request.
-func (c *Client) makeHeadersCopier(ireq *Request) func(*Request) {
- // The headers to copy are from the very initial request.
- // We use a closured callback to keep a reference to these original headers.
- var (
- ireqhdr = cloneOrMakeHeader(ireq.Header)
- icookies map[string][]*Cookie
- )
- if c.Jar != nil && ireq.Header.Get("Cookie") != "" {
- icookies = make(map[string][]*Cookie)
- for _, c := range ireq.Cookies() {
- icookies[c.Name] = append(icookies[c.Name], c)
- }
- }
-
- preq := ireq // The previous request
- return func(req *Request) {
- // If Jar is present and there was some initial cookies provided
- // via the request header, then we may need to alter the initial
- // cookies as we follow redirects since each redirect may end up
- // modifying a pre-existing cookie.
- //
- // Since cookies already set in the request header do not contain
- // information about the original domain and path, the logic below
- // assumes any new set cookies override the original cookie
- // regardless of domain or path.
- //
- // See https://golang.org/issue/17494
- if c.Jar != nil && icookies != nil {
- var changed bool
- resp := req.Response // The response that caused the upcoming redirect
- for _, c := range resp.Cookies() {
- if _, ok := icookies[c.Name]; ok {
- delete(icookies, c.Name)
- changed = true
- }
- }
- if changed {
- ireqhdr.Del("Cookie")
- var ss []string
- for _, cs := range icookies {
- for _, c := range cs {
- ss = append(ss, c.Name+"="+c.Value)
- }
- }
- sort.Strings(ss) // Ensure deterministic headers
- ireqhdr.Set("Cookie", strings.Join(ss, "; "))
- }
- }
-
- // Copy the initial request's Header values
- // (at least the safe ones).
- for k, vv := range ireqhdr {
- if shouldCopyHeaderOnRedirect(k, preq.URL, req.URL) {
- req.Header[k] = vv
- }
- }
-
- preq = req // Update previous Request with the current request
- }
-}
-
-func defaultCheckRedirect(req *Request, via []*Request) error {
- if len(via) >= 10 {
- return errors.New("stopped after 10 redirects")
- }
- return nil
-}
-
-// Post issues a POST to the specified URL.
-//
-// Caller should close resp.Body when done reading from it.
-//
-// If the provided body is an io.Closer, it is closed after the
-// request.
-//
-// Post is a wrapper around DefaultClient.Post.
-//
-// To set custom headers, use NewRequest and DefaultClient.Do.
-//
-// See the Client.Do method documentation for details on how redirects
-// are handled.
-//
-// To make a request with a specified context.Context, use NewRequestWithContext
-// and DefaultClient.Do.
-func Post(url, contentType string, body io.Reader) (resp *Response, err error) {
- return DefaultClient.Post(url, contentType, body)
-}
-
-// Post issues a POST to the specified URL.
-//
-// Caller should close resp.Body when done reading from it.
-//
-// If the provided body is an io.Closer, it is closed after the
-// request.
-//
-// To set custom headers, use NewRequest and Client.Do.
-//
-// To make a request with a specified context.Context, use NewRequestWithContext
-// and Client.Do.
-//
-// See the Client.Do method documentation for details on how redirects
-// are handled.
-func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, err error) {
- req, err := NewRequest("POST", url, body)
- if err != nil {
- return nil, err
- }
- req.Header.Set("Content-Type", contentType)
- return c.Do(req)
-}
-
-// PostForm issues a POST to the specified URL, with data's keys and
-// values URL-encoded as the request body.
-//
-// The Content-Type header is set to application/x-www-form-urlencoded.
-// To set other headers, use NewRequest and DefaultClient.Do.
-//
-// When err is nil, resp always contains a non-nil resp.Body.
-// Caller should close resp.Body when done reading from it.
-//
-// PostForm is a wrapper around DefaultClient.PostForm.
-//
-// See the Client.Do method documentation for details on how redirects
-// are handled.
-//
-// To make a request with a specified context.Context, use NewRequestWithContext
-// and DefaultClient.Do.
-func PostForm(url string, data url.Values) (resp *Response, err error) {
- return DefaultClient.PostForm(url, data)
-}
-
-// PostForm issues a POST to the specified URL,
-// with data's keys and values URL-encoded as the request body.
-//
-// The Content-Type header is set to application/x-www-form-urlencoded.
-// To set other headers, use NewRequest and Client.Do.
-//
-// When err is nil, resp always contains a non-nil resp.Body.
-// Caller should close resp.Body when done reading from it.
-//
-// See the Client.Do method documentation for details on how redirects
-// are handled.
-//
-// To make a request with a specified context.Context, use NewRequestWithContext
-// and Client.Do.
-func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) {
- return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
-}
-
-// Head issues a HEAD to the specified URL. If the response is one of
-// the following redirect codes, Head follows the redirect, up to a
-// maximum of 10 redirects:
-//
-// 301 (Moved Permanently)
-// 302 (Found)
-// 303 (See Other)
-// 307 (Temporary Redirect)
-// 308 (Permanent Redirect)
-//
-// Head is a wrapper around DefaultClient.Head.
-//
-// To make a request with a specified context.Context, use NewRequestWithContext
-// and DefaultClient.Do.
-func Head(url string) (resp *Response, err error) {
- return DefaultClient.Head(url)
-}
-
-// Head issues a HEAD to the specified URL. If the response is one of the
-// following redirect codes, Head follows the redirect after calling the
-// Client's CheckRedirect function:
-//
-// 301 (Moved Permanently)
-// 302 (Found)
-// 303 (See Other)
-// 307 (Temporary Redirect)
-// 308 (Permanent Redirect)
-//
-// To make a request with a specified context.Context, use NewRequestWithContext
-// and Client.Do.
-func (c *Client) Head(url string) (resp *Response, err error) {
- req, err := NewRequest("HEAD", url, nil)
- if err != nil {
- return nil, err
- }
- return c.Do(req)
-}
-
-// CloseIdleConnections closes any connections on its Transport which
-// were previously connected from previous requests but are now
-// sitting idle in a "keep-alive" state. It does not interrupt any
-// connections currently in use.
-//
-// If the Client's Transport does not have a CloseIdleConnections method
-// then this method does nothing.
-func (c *Client) CloseIdleConnections() {
- type closeIdler interface {
- CloseIdleConnections()
- }
- if tr, ok := c.transport().(closeIdler); ok {
- tr.CloseIdleConnections()
- }
-}
-
-// cancelTimerBody is an io.ReadCloser that wraps rc with two features:
-// 1. On Read error or close, the stop func is called.
-// 2. On Read failure, if reqDidTimeout is true, the error is wrapped and
-// marked as net.Error that hit its timeout.
-type cancelTimerBody struct {
- stop func() // stops the time.Timer waiting to cancel the request
- rc io.ReadCloser
- reqDidTimeout func() bool
-}
-
-func (b *cancelTimerBody) Read(p []byte) (n int, err error) {
- n, err = b.rc.Read(p)
- if err == nil {
- return n, nil
- }
- if err == io.EOF {
- return n, err
- }
- if b.reqDidTimeout() {
- err = &httpError{
- err: err.Error() + " (Client.Timeout or context cancellation while reading body)",
- timeout: true,
- }
- }
- return n, err
-}
-
-func (b *cancelTimerBody) Close() error {
- err := b.rc.Close()
- b.stop()
- return err
-}
-
-func shouldCopyHeaderOnRedirect(headerKey string, initial, dest *url.URL) bool {
- switch CanonicalHeaderKey(headerKey) {
- case "Authorization", "Www-Authenticate", "Cookie", "Cookie2":
- // Permit sending auth/cookie headers from "foo.com"
- // to "sub.foo.com".
-
- // Note that we don't send all cookies to subdomains
- // automatically. This function is only used for
- // Cookies set explicitly on the initial outgoing
- // client request. Cookies automatically added via the
- // CookieJar mechanism continue to follow each
- // cookie's scope as set by Set-Cookie. But for
- // outgoing requests with the Cookie header set
- // directly, we don't know their scope, so we assume
- // it's for *.domain.com.
-
- ihost := canonicalAddr(initial)
- dhost := canonicalAddr(dest)
- return isDomainOrSubdomain(dhost, ihost)
- }
- // All other headers are copied:
- return true
-}
-
-// isDomainOrSubdomain reports whether sub is a subdomain (or exact
-// match) of the parent domain.
-//
-// Both domains must already be in canonical form.
-func isDomainOrSubdomain(sub, parent string) bool {
- if sub == parent {
- return true
- }
- // If sub is "foo.example.com" and parent is "example.com",
- // that means sub must end in "."+parent.
- // Do it without allocating.
- if !strings.HasSuffix(sub, parent) {
- return false
- }
- return sub[len(sub)-len(parent)-1] == '.'
-}
-
-func stripPassword(u *url.URL) string {
- _, passSet := u.User.Password()
- if passSet {
- return strings.Replace(u.String(), u.User.String()+"@", u.User.Username()+":***@", 1)
- }
- return u.String()
-}
diff --git a/contrib/go/_std_1.20/src/net/http/cookiejar/jar.go b/contrib/go/_std_1.20/src/net/http/cookiejar/jar.go
deleted file mode 100644
index 3d0ad19af0..0000000000
--- a/contrib/go/_std_1.20/src/net/http/cookiejar/jar.go
+++ /dev/null
@@ -1,540 +0,0 @@
-// Copyright 2012 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 cookiejar implements an in-memory RFC 6265-compliant http.CookieJar.
-package cookiejar
-
-import (
- "errors"
- "fmt"
- "net"
- "net/http"
- "net/http/internal/ascii"
- "net/url"
- "sort"
- "strings"
- "sync"
- "time"
-)
-
-// PublicSuffixList provides the public suffix of a domain. For example:
-// - the public suffix of "example.com" is "com",
-// - the public suffix of "foo1.foo2.foo3.co.uk" is "co.uk", and
-// - the public suffix of "bar.pvt.k12.ma.us" is "pvt.k12.ma.us".
-//
-// Implementations of PublicSuffixList must be safe for concurrent use by
-// multiple goroutines.
-//
-// An implementation that always returns "" is valid and may be useful for
-// testing but it is not secure: it means that the HTTP server for foo.com can
-// set a cookie for bar.com.
-//
-// A public suffix list implementation is in the package
-// golang.org/x/net/publicsuffix.
-type PublicSuffixList interface {
- // PublicSuffix returns the public suffix of domain.
- //
- // TODO: specify which of the caller and callee is responsible for IP
- // addresses, for leading and trailing dots, for case sensitivity, and
- // for IDN/Punycode.
- PublicSuffix(domain string) string
-
- // String returns a description of the source of this public suffix
- // list. The description will typically contain something like a time
- // stamp or version number.
- String() string
-}
-
-// Options are the options for creating a new Jar.
-type Options struct {
- // PublicSuffixList is the public suffix list that determines whether
- // an HTTP server can set a cookie for a domain.
- //
- // A nil value is valid and may be useful for testing but it is not
- // secure: it means that the HTTP server for foo.co.uk can set a cookie
- // for bar.co.uk.
- PublicSuffixList PublicSuffixList
-}
-
-// Jar implements the http.CookieJar interface from the net/http package.
-type Jar struct {
- psList PublicSuffixList
-
- // mu locks the remaining fields.
- mu sync.Mutex
-
- // entries is a set of entries, keyed by their eTLD+1 and subkeyed by
- // their name/domain/path.
- entries map[string]map[string]entry
-
- // nextSeqNum is the next sequence number assigned to a new cookie
- // created SetCookies.
- nextSeqNum uint64
-}
-
-// New returns a new cookie jar. A nil *Options is equivalent to a zero
-// Options.
-func New(o *Options) (*Jar, error) {
- jar := &Jar{
- entries: make(map[string]map[string]entry),
- }
- if o != nil {
- jar.psList = o.PublicSuffixList
- }
- return jar, nil
-}
-
-// entry is the internal representation of a cookie.
-//
-// This struct type is not used outside of this package per se, but the exported
-// fields are those of RFC 6265.
-type entry struct {
- Name string
- Value string
- Domain string
- Path string
- SameSite string
- Secure bool
- HttpOnly bool
- Persistent bool
- HostOnly bool
- Expires time.Time
- Creation time.Time
- LastAccess time.Time
-
- // seqNum is a sequence number so that Cookies returns cookies in a
- // deterministic order, even for cookies that have equal Path length and
- // equal Creation time. This simplifies testing.
- seqNum uint64
-}
-
-// id returns the domain;path;name triple of e as an id.
-func (e *entry) id() string {
- return fmt.Sprintf("%s;%s;%s", e.Domain, e.Path, e.Name)
-}
-
-// shouldSend determines whether e's cookie qualifies to be included in a
-// request to host/path. It is the caller's responsibility to check if the
-// cookie is expired.
-func (e *entry) shouldSend(https bool, host, path string) bool {
- return e.domainMatch(host) && e.pathMatch(path) && (https || !e.Secure)
-}
-
-// domainMatch checks whether e's Domain allows sending e back to host.
-// It differs from "domain-match" of RFC 6265 section 5.1.3 because we treat
-// a cookie with an IP address in the Domain always as a host cookie.
-func (e *entry) domainMatch(host string) bool {
- if e.Domain == host {
- return true
- }
- return !e.HostOnly && hasDotSuffix(host, e.Domain)
-}
-
-// pathMatch implements "path-match" according to RFC 6265 section 5.1.4.
-func (e *entry) pathMatch(requestPath string) bool {
- if requestPath == e.Path {
- return true
- }
- if strings.HasPrefix(requestPath, e.Path) {
- if e.Path[len(e.Path)-1] == '/' {
- return true // The "/any/" matches "/any/path" case.
- } else if requestPath[len(e.Path)] == '/' {
- return true // The "/any" matches "/any/path" case.
- }
- }
- return false
-}
-
-// hasDotSuffix reports whether s ends in "."+suffix.
-func hasDotSuffix(s, suffix string) bool {
- return len(s) > len(suffix) && s[len(s)-len(suffix)-1] == '.' && s[len(s)-len(suffix):] == suffix
-}
-
-// Cookies implements the Cookies method of the http.CookieJar interface.
-//
-// It returns an empty slice if the URL's scheme is not HTTP or HTTPS.
-func (j *Jar) Cookies(u *url.URL) (cookies []*http.Cookie) {
- return j.cookies(u, time.Now())
-}
-
-// cookies is like Cookies but takes the current time as a parameter.
-func (j *Jar) cookies(u *url.URL, now time.Time) (cookies []*http.Cookie) {
- if u.Scheme != "http" && u.Scheme != "https" {
- return cookies
- }
- host, err := canonicalHost(u.Host)
- if err != nil {
- return cookies
- }
- key := jarKey(host, j.psList)
-
- j.mu.Lock()
- defer j.mu.Unlock()
-
- submap := j.entries[key]
- if submap == nil {
- return cookies
- }
-
- https := u.Scheme == "https"
- path := u.Path
- if path == "" {
- path = "/"
- }
-
- modified := false
- var selected []entry
- for id, e := range submap {
- if e.Persistent && !e.Expires.After(now) {
- delete(submap, id)
- modified = true
- continue
- }
- if !e.shouldSend(https, host, path) {
- continue
- }
- e.LastAccess = now
- submap[id] = e
- selected = append(selected, e)
- modified = true
- }
- if modified {
- if len(submap) == 0 {
- delete(j.entries, key)
- } else {
- j.entries[key] = submap
- }
- }
-
- // sort according to RFC 6265 section 5.4 point 2: by longest
- // path and then by earliest creation time.
- sort.Slice(selected, func(i, j int) bool {
- s := selected
- if len(s[i].Path) != len(s[j].Path) {
- return len(s[i].Path) > len(s[j].Path)
- }
- if ret := s[i].Creation.Compare(s[j].Creation); ret != 0 {
- return ret < 0
- }
- return s[i].seqNum < s[j].seqNum
- })
- for _, e := range selected {
- cookies = append(cookies, &http.Cookie{Name: e.Name, Value: e.Value})
- }
-
- return cookies
-}
-
-// SetCookies implements the SetCookies method of the http.CookieJar interface.
-//
-// It does nothing if the URL's scheme is not HTTP or HTTPS.
-func (j *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) {
- j.setCookies(u, cookies, time.Now())
-}
-
-// setCookies is like SetCookies but takes the current time as parameter.
-func (j *Jar) setCookies(u *url.URL, cookies []*http.Cookie, now time.Time) {
- if len(cookies) == 0 {
- return
- }
- if u.Scheme != "http" && u.Scheme != "https" {
- return
- }
- host, err := canonicalHost(u.Host)
- if err != nil {
- return
- }
- key := jarKey(host, j.psList)
- defPath := defaultPath(u.Path)
-
- j.mu.Lock()
- defer j.mu.Unlock()
-
- submap := j.entries[key]
-
- modified := false
- for _, cookie := range cookies {
- e, remove, err := j.newEntry(cookie, now, defPath, host)
- if err != nil {
- continue
- }
- id := e.id()
- if remove {
- if submap != nil {
- if _, ok := submap[id]; ok {
- delete(submap, id)
- modified = true
- }
- }
- continue
- }
- if submap == nil {
- submap = make(map[string]entry)
- }
-
- if old, ok := submap[id]; ok {
- e.Creation = old.Creation
- e.seqNum = old.seqNum
- } else {
- e.Creation = now
- e.seqNum = j.nextSeqNum
- j.nextSeqNum++
- }
- e.LastAccess = now
- submap[id] = e
- modified = true
- }
-
- if modified {
- if len(submap) == 0 {
- delete(j.entries, key)
- } else {
- j.entries[key] = submap
- }
- }
-}
-
-// canonicalHost strips port from host if present and returns the canonicalized
-// host name.
-func canonicalHost(host string) (string, error) {
- var err error
- if hasPort(host) {
- host, _, err = net.SplitHostPort(host)
- if err != nil {
- return "", err
- }
- }
- // Strip trailing dot from fully qualified domain names.
- host = strings.TrimSuffix(host, ".")
- encoded, err := toASCII(host)
- if err != nil {
- return "", err
- }
- // We know this is ascii, no need to check.
- lower, _ := ascii.ToLower(encoded)
- return lower, nil
-}
-
-// hasPort reports whether host contains a port number. host may be a host
-// name, an IPv4 or an IPv6 address.
-func hasPort(host string) bool {
- colons := strings.Count(host, ":")
- if colons == 0 {
- return false
- }
- if colons == 1 {
- return true
- }
- return host[0] == '[' && strings.Contains(host, "]:")
-}
-
-// jarKey returns the key to use for a jar.
-func jarKey(host string, psl PublicSuffixList) string {
- if isIP(host) {
- return host
- }
-
- var i int
- if psl == nil {
- i = strings.LastIndex(host, ".")
- if i <= 0 {
- return host
- }
- } else {
- suffix := psl.PublicSuffix(host)
- if suffix == host {
- return host
- }
- i = len(host) - len(suffix)
- if i <= 0 || host[i-1] != '.' {
- // The provided public suffix list psl is broken.
- // Storing cookies under host is a safe stopgap.
- return host
- }
- // Only len(suffix) is used to determine the jar key from
- // here on, so it is okay if psl.PublicSuffix("www.buggy.psl")
- // returns "com" as the jar key is generated from host.
- }
- prevDot := strings.LastIndex(host[:i-1], ".")
- return host[prevDot+1:]
-}
-
-// isIP reports whether host is an IP address.
-func isIP(host string) bool {
- return net.ParseIP(host) != nil
-}
-
-// defaultPath returns the directory part of an URL's path according to
-// RFC 6265 section 5.1.4.
-func defaultPath(path string) string {
- if len(path) == 0 || path[0] != '/' {
- return "/" // Path is empty or malformed.
- }
-
- i := strings.LastIndex(path, "/") // Path starts with "/", so i != -1.
- if i == 0 {
- return "/" // Path has the form "/abc".
- }
- return path[:i] // Path is either of form "/abc/xyz" or "/abc/xyz/".
-}
-
-// newEntry creates an entry from a http.Cookie c. now is the current time and
-// is compared to c.Expires to determine deletion of c. defPath and host are the
-// default-path and the canonical host name of the URL c was received from.
-//
-// remove records whether the jar should delete this cookie, as it has already
-// expired with respect to now. In this case, e may be incomplete, but it will
-// be valid to call e.id (which depends on e's Name, Domain and Path).
-//
-// A malformed c.Domain will result in an error.
-func (j *Jar) newEntry(c *http.Cookie, now time.Time, defPath, host string) (e entry, remove bool, err error) {
- e.Name = c.Name
-
- if c.Path == "" || c.Path[0] != '/' {
- e.Path = defPath
- } else {
- e.Path = c.Path
- }
-
- e.Domain, e.HostOnly, err = j.domainAndType(host, c.Domain)
- if err != nil {
- return e, false, err
- }
-
- // MaxAge takes precedence over Expires.
- if c.MaxAge < 0 {
- return e, true, nil
- } else if c.MaxAge > 0 {
- e.Expires = now.Add(time.Duration(c.MaxAge) * time.Second)
- e.Persistent = true
- } else {
- if c.Expires.IsZero() {
- e.Expires = endOfTime
- e.Persistent = false
- } else {
- if !c.Expires.After(now) {
- return e, true, nil
- }
- e.Expires = c.Expires
- e.Persistent = true
- }
- }
-
- e.Value = c.Value
- e.Secure = c.Secure
- e.HttpOnly = c.HttpOnly
-
- switch c.SameSite {
- case http.SameSiteDefaultMode:
- e.SameSite = "SameSite"
- case http.SameSiteStrictMode:
- e.SameSite = "SameSite=Strict"
- case http.SameSiteLaxMode:
- e.SameSite = "SameSite=Lax"
- }
-
- return e, false, nil
-}
-
-var (
- errIllegalDomain = errors.New("cookiejar: illegal cookie domain attribute")
- errMalformedDomain = errors.New("cookiejar: malformed cookie domain attribute")
- errNoHostname = errors.New("cookiejar: no host name available (IP only)")
-)
-
-// endOfTime is the time when session (non-persistent) cookies expire.
-// This instant is representable in most date/time formats (not just
-// Go's time.Time) and should be far enough in the future.
-var endOfTime = time.Date(9999, 12, 31, 23, 59, 59, 0, time.UTC)
-
-// domainAndType determines the cookie's domain and hostOnly attribute.
-func (j *Jar) domainAndType(host, domain string) (string, bool, error) {
- if domain == "" {
- // No domain attribute in the SetCookie header indicates a
- // host cookie.
- return host, true, nil
- }
-
- if isIP(host) {
- // RFC 6265 is not super clear here, a sensible interpretation
- // is that cookies with an IP address in the domain-attribute
- // are allowed.
-
- // RFC 6265 section 5.2.3 mandates to strip an optional leading
- // dot in the domain-attribute before processing the cookie.
- //
- // Most browsers don't do that for IP addresses, only curl
- // version 7.54) and IE (version 11) do not reject a
- // Set-Cookie: a=1; domain=.127.0.0.1
- // This leading dot is optional and serves only as hint for
- // humans to indicate that a cookie with "domain=.bbc.co.uk"
- // would be sent to every subdomain of bbc.co.uk.
- // It just doesn't make sense on IP addresses.
- // The other processing and validation steps in RFC 6265 just
- // collaps to:
- if host != domain {
- return "", false, errIllegalDomain
- }
-
- // According to RFC 6265 such cookies should be treated as
- // domain cookies.
- // As there are no subdomains of an IP address the treatment
- // according to RFC 6265 would be exactly the same as that of
- // a host-only cookie. Contemporary browsers (and curl) do
- // allows such cookies but treat them as host-only cookies.
- // So do we as it just doesn't make sense to label them as
- // domain cookies when there is no domain; the whole notion of
- // domain cookies requires a domain name to be well defined.
- return host, true, nil
- }
-
- // From here on: If the cookie is valid, it is a domain cookie (with
- // the one exception of a public suffix below).
- // See RFC 6265 section 5.2.3.
- if domain[0] == '.' {
- domain = domain[1:]
- }
-
- if len(domain) == 0 || domain[0] == '.' {
- // Received either "Domain=." or "Domain=..some.thing",
- // both are illegal.
- return "", false, errMalformedDomain
- }
-
- domain, isASCII := ascii.ToLower(domain)
- if !isASCII {
- // Received non-ASCII domain, e.g. "perché.com" instead of "xn--perch-fsa.com"
- return "", false, errMalformedDomain
- }
-
- if domain[len(domain)-1] == '.' {
- // We received stuff like "Domain=www.example.com.".
- // Browsers do handle such stuff (actually differently) but
- // RFC 6265 seems to be clear here (e.g. section 4.1.2.3) in
- // requiring a reject. 4.1.2.3 is not normative, but
- // "Domain Matching" (5.1.3) and "Canonicalized Host Names"
- // (5.1.2) are.
- return "", false, errMalformedDomain
- }
-
- // See RFC 6265 section 5.3 #5.
- if j.psList != nil {
- if ps := j.psList.PublicSuffix(domain); ps != "" && !hasDotSuffix(domain, ps) {
- if host == domain {
- // This is the one exception in which a cookie
- // with a domain attribute is a host cookie.
- return host, true, nil
- }
- return "", false, errIllegalDomain
- }
- }
-
- // The domain must domain-match host: www.mycompany.com cannot
- // set cookies for .ourcompetitors.com.
- if host != domain && !hasDotSuffix(host, domain) {
- return "", false, errIllegalDomain
- }
-
- return domain, false, nil
-}
diff --git a/contrib/go/_std_1.20/src/net/http/cookiejar/ya.make b/contrib/go/_std_1.20/src/net/http/cookiejar/ya.make
deleted file mode 100644
index 322ce6d11a..0000000000
--- a/contrib/go/_std_1.20/src/net/http/cookiejar/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- jar.go
- punycode.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/http/doc.go b/contrib/go/_std_1.20/src/net/http/doc.go
deleted file mode 100644
index 67c4246c60..0000000000
--- a/contrib/go/_std_1.20/src/net/http/doc.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2011 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 http provides HTTP client and server implementations.
-
-Get, Head, Post, and PostForm make HTTP (or HTTPS) requests:
-
- resp, err := http.Get("http://example.com/")
- ...
- resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
- ...
- resp, err := http.PostForm("http://example.com/form",
- url.Values{"key": {"Value"}, "id": {"123"}})
-
-The client must close the response body when finished with it:
-
- resp, err := http.Get("http://example.com/")
- if err != nil {
- // handle error
- }
- defer resp.Body.Close()
- body, err := io.ReadAll(resp.Body)
- // ...
-
-For control over HTTP client headers, redirect policy, and other
-settings, create a Client:
-
- client := &http.Client{
- CheckRedirect: redirectPolicyFunc,
- }
-
- resp, err := client.Get("http://example.com")
- // ...
-
- req, err := http.NewRequest("GET", "http://example.com", nil)
- // ...
- req.Header.Add("If-None-Match", `W/"wyzzy"`)
- resp, err := client.Do(req)
- // ...
-
-For control over proxies, TLS configuration, keep-alives,
-compression, and other settings, create a Transport:
-
- tr := &http.Transport{
- MaxIdleConns: 10,
- IdleConnTimeout: 30 * time.Second,
- DisableCompression: true,
- }
- client := &http.Client{Transport: tr}
- resp, err := client.Get("https://example.com")
-
-Clients and Transports are safe for concurrent use by multiple
-goroutines and for efficiency should only be created once and re-used.
-
-ListenAndServe starts an HTTP server with a given address and handler.
-The handler is usually nil, which means to use DefaultServeMux.
-Handle and HandleFunc add handlers to DefaultServeMux:
-
- http.Handle("/foo", fooHandler)
-
- http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
- fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
- })
-
- log.Fatal(http.ListenAndServe(":8080", nil))
-
-More control over the server's behavior is available by creating a
-custom Server:
-
- s := &http.Server{
- Addr: ":8080",
- Handler: myHandler,
- ReadTimeout: 10 * time.Second,
- WriteTimeout: 10 * time.Second,
- MaxHeaderBytes: 1 << 20,
- }
- log.Fatal(s.ListenAndServe())
-
-Starting with Go 1.6, the http package has transparent support for the
-HTTP/2 protocol when using HTTPS. Programs that must disable HTTP/2
-can do so by setting Transport.TLSNextProto (for clients) or
-Server.TLSNextProto (for servers) to a non-nil, empty
-map. Alternatively, the following GODEBUG environment variables are
-currently supported:
-
- GODEBUG=http2client=0 # disable HTTP/2 client support
- GODEBUG=http2server=0 # disable HTTP/2 server support
- GODEBUG=http2debug=1 # enable verbose HTTP/2 debug logs
- GODEBUG=http2debug=2 # ... even more verbose, with frame dumps
-
-The GODEBUG variables are not covered by Go's API compatibility
-promise. Please report any issues before disabling HTTP/2
-support: https://golang.org/s/http2bug
-
-The http package's Transport and Server both automatically enable
-HTTP/2 support for simple configurations. To enable HTTP/2 for more
-complex configurations, to use lower-level HTTP/2 features, or to use
-a newer version of Go's http2 package, import "golang.org/x/net/http2"
-directly and use its ConfigureTransport and/or ConfigureServer
-functions. Manually configuring HTTP/2 via the golang.org/x/net/http2
-package takes precedence over the net/http package's built-in HTTP/2
-support.
-*/
-package http
diff --git a/contrib/go/_std_1.20/src/net/http/fcgi/fcgi.go b/contrib/go/_std_1.20/src/net/http/fcgi/fcgi.go
deleted file mode 100644
index fb822f8a6d..0000000000
--- a/contrib/go/_std_1.20/src/net/http/fcgi/fcgi.go
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2011 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 fcgi implements the FastCGI protocol.
-//
-// See https://fast-cgi.github.io/ for an unofficial mirror of the
-// original documentation.
-//
-// Currently only the responder role is supported.
-package fcgi
-
-// This file defines the raw protocol and some utilities used by the child and
-// the host.
-
-import (
- "bufio"
- "bytes"
- "encoding/binary"
- "errors"
- "io"
- "sync"
-)
-
-// recType is a record type, as defined by
-// https://web.archive.org/web/20150420080736/http://www.fastcgi.com/drupal/node/6?q=node/22#S8
-type recType uint8
-
-const (
- typeBeginRequest recType = 1
- typeAbortRequest recType = 2
- typeEndRequest recType = 3
- typeParams recType = 4
- typeStdin recType = 5
- typeStdout recType = 6
- typeStderr recType = 7
- typeData recType = 8
- typeGetValues recType = 9
- typeGetValuesResult recType = 10
- typeUnknownType recType = 11
-)
-
-// keep the connection between web-server and responder open after request
-const flagKeepConn = 1
-
-const (
- maxWrite = 65535 // maximum record body
- maxPad = 255
-)
-
-const (
- roleResponder = iota + 1 // only Responders are implemented.
- roleAuthorizer
- roleFilter
-)
-
-const (
- statusRequestComplete = iota
- statusCantMultiplex
- statusOverloaded
- statusUnknownRole
-)
-
-type header struct {
- Version uint8
- Type recType
- Id uint16
- ContentLength uint16
- PaddingLength uint8
- Reserved uint8
-}
-
-type beginRequest struct {
- role uint16
- flags uint8
- reserved [5]uint8
-}
-
-func (br *beginRequest) read(content []byte) error {
- if len(content) != 8 {
- return errors.New("fcgi: invalid begin request record")
- }
- br.role = binary.BigEndian.Uint16(content)
- br.flags = content[2]
- return nil
-}
-
-// for padding so we don't have to allocate all the time
-// not synchronized because we don't care what the contents are
-var pad [maxPad]byte
-
-func (h *header) init(recType recType, reqId uint16, contentLength int) {
- h.Version = 1
- h.Type = recType
- h.Id = reqId
- h.ContentLength = uint16(contentLength)
- h.PaddingLength = uint8(-contentLength & 7)
-}
-
-// conn sends records over rwc
-type conn struct {
- mutex sync.Mutex
- rwc io.ReadWriteCloser
-
- // to avoid allocations
- buf bytes.Buffer
- h header
-}
-
-func newConn(rwc io.ReadWriteCloser) *conn {
- return &conn{rwc: rwc}
-}
-
-func (c *conn) Close() error {
- c.mutex.Lock()
- defer c.mutex.Unlock()
- return c.rwc.Close()
-}
-
-type record struct {
- h header
- buf [maxWrite + maxPad]byte
-}
-
-func (rec *record) read(r io.Reader) (err error) {
- if err = binary.Read(r, binary.BigEndian, &rec.h); err != nil {
- return err
- }
- if rec.h.Version != 1 {
- return errors.New("fcgi: invalid header version")
- }
- n := int(rec.h.ContentLength) + int(rec.h.PaddingLength)
- if _, err = io.ReadFull(r, rec.buf[:n]); err != nil {
- return err
- }
- return nil
-}
-
-func (r *record) content() []byte {
- return r.buf[:r.h.ContentLength]
-}
-
-// writeRecord writes and sends a single record.
-func (c *conn) writeRecord(recType recType, reqId uint16, b []byte) error {
- c.mutex.Lock()
- defer c.mutex.Unlock()
- c.buf.Reset()
- c.h.init(recType, reqId, len(b))
- if err := binary.Write(&c.buf, binary.BigEndian, c.h); err != nil {
- return err
- }
- if _, err := c.buf.Write(b); err != nil {
- return err
- }
- if _, err := c.buf.Write(pad[:c.h.PaddingLength]); err != nil {
- return err
- }
- _, err := c.rwc.Write(c.buf.Bytes())
- return err
-}
-
-func (c *conn) writeEndRequest(reqId uint16, appStatus int, protocolStatus uint8) error {
- b := make([]byte, 8)
- binary.BigEndian.PutUint32(b, uint32(appStatus))
- b[4] = protocolStatus
- return c.writeRecord(typeEndRequest, reqId, b)
-}
-
-func (c *conn) writePairs(recType recType, reqId uint16, pairs map[string]string) error {
- w := newWriter(c, recType, reqId)
- b := make([]byte, 8)
- for k, v := range pairs {
- n := encodeSize(b, uint32(len(k)))
- n += encodeSize(b[n:], uint32(len(v)))
- if _, err := w.Write(b[:n]); err != nil {
- return err
- }
- if _, err := w.WriteString(k); err != nil {
- return err
- }
- if _, err := w.WriteString(v); err != nil {
- return err
- }
- }
- w.Close()
- return nil
-}
-
-func readSize(s []byte) (uint32, int) {
- if len(s) == 0 {
- return 0, 0
- }
- size, n := uint32(s[0]), 1
- if size&(1<<7) != 0 {
- if len(s) < 4 {
- return 0, 0
- }
- n = 4
- size = binary.BigEndian.Uint32(s)
- size &^= 1 << 31
- }
- return size, n
-}
-
-func readString(s []byte, size uint32) string {
- if size > uint32(len(s)) {
- return ""
- }
- return string(s[:size])
-}
-
-func encodeSize(b []byte, size uint32) int {
- if size > 127 {
- size |= 1 << 31
- binary.BigEndian.PutUint32(b, size)
- return 4
- }
- b[0] = byte(size)
- return 1
-}
-
-// bufWriter encapsulates bufio.Writer but also closes the underlying stream when
-// Closed.
-type bufWriter struct {
- closer io.Closer
- *bufio.Writer
-}
-
-func (w *bufWriter) Close() error {
- if err := w.Writer.Flush(); err != nil {
- w.closer.Close()
- return err
- }
- return w.closer.Close()
-}
-
-func newWriter(c *conn, recType recType, reqId uint16) *bufWriter {
- s := &streamWriter{c: c, recType: recType, reqId: reqId}
- w := bufio.NewWriterSize(s, maxWrite)
- return &bufWriter{s, w}
-}
-
-// streamWriter abstracts out the separation of a stream into discrete records.
-// It only writes maxWrite bytes at a time.
-type streamWriter struct {
- c *conn
- recType recType
- reqId uint16
-}
-
-func (w *streamWriter) Write(p []byte) (int, error) {
- nn := 0
- for len(p) > 0 {
- n := len(p)
- if n > maxWrite {
- n = maxWrite
- }
- if err := w.c.writeRecord(w.recType, w.reqId, p[:n]); err != nil {
- return nn, err
- }
- nn += n
- p = p[n:]
- }
- return nn, nil
-}
-
-func (w *streamWriter) Close() error {
- // send empty record to close the stream
- return w.c.writeRecord(w.recType, w.reqId, nil)
-}
diff --git a/contrib/go/_std_1.20/src/net/http/fcgi/ya.make b/contrib/go/_std_1.20/src/net/http/fcgi/ya.make
deleted file mode 100644
index 9ae9d18cd5..0000000000
--- a/contrib/go/_std_1.20/src/net/http/fcgi/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- child.go
- fcgi.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/http/h2_bundle.go b/contrib/go/_std_1.20/src/net/http/h2_bundle.go
deleted file mode 100644
index 1e0b83d493..0000000000
--- a/contrib/go/_std_1.20/src/net/http/h2_bundle.go
+++ /dev/null
@@ -1,11240 +0,0 @@
-//go:build !nethttpomithttp2
-// +build !nethttpomithttp2
-
-// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
-// $ bundle -o=h2_bundle.go -prefix=http2 -tags=!nethttpomithttp2 golang.org/x/net/http2
-
-// Package http2 implements the HTTP/2 protocol.
-//
-// This package is low-level and intended to be used directly by very
-// few people. Most users will use it indirectly through the automatic
-// use by the net/http package (from Go 1.6 and later).
-// For use in earlier Go versions see ConfigureServer. (Transport support
-// requires Go 1.6 or later)
-//
-// See https://http2.github.io/ for more information on HTTP/2.
-//
-// See https://http2.golang.org/ for a test server running this code.
-//
-
-package http
-
-import (
- "bufio"
- "bytes"
- "compress/gzip"
- "context"
- "crypto/rand"
- "crypto/tls"
- "encoding/binary"
- "errors"
- "fmt"
- "io"
- "io/fs"
- "log"
- "math"
- mathrand "math/rand"
- "net"
- "net/http/httptrace"
- "net/textproto"
- "net/url"
- "os"
- "reflect"
- "runtime"
- "sort"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
- "time"
-
- "golang.org/x/net/http/httpguts"
- "golang.org/x/net/http2/hpack"
- "golang.org/x/net/idna"
-)
-
-// The HTTP protocols are defined in terms of ASCII, not Unicode. This file
-// contains helper functions which may use Unicode-aware functions which would
-// otherwise be unsafe and could introduce vulnerabilities if used improperly.
-
-// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t
-// are equal, ASCII-case-insensitively.
-func http2asciiEqualFold(s, t string) bool {
- if len(s) != len(t) {
- return false
- }
- for i := 0; i < len(s); i++ {
- if http2lower(s[i]) != http2lower(t[i]) {
- return false
- }
- }
- return true
-}
-
-// lower returns the ASCII lowercase version of b.
-func http2lower(b byte) byte {
- if 'A' <= b && b <= 'Z' {
- return b + ('a' - 'A')
- }
- return b
-}
-
-// isASCIIPrint returns whether s is ASCII and printable according to
-// https://tools.ietf.org/html/rfc20#section-4.2.
-func http2isASCIIPrint(s string) bool {
- for i := 0; i < len(s); i++ {
- if s[i] < ' ' || s[i] > '~' {
- return false
- }
- }
- return true
-}
-
-// asciiToLower returns the lowercase version of s if s is ASCII and printable,
-// and whether or not it was.
-func http2asciiToLower(s string) (lower string, ok bool) {
- if !http2isASCIIPrint(s) {
- return "", false
- }
- return strings.ToLower(s), true
-}
-
-// A list of the possible cipher suite ids. Taken from
-// https://www.iana.org/assignments/tls-parameters/tls-parameters.txt
-
-const (
- http2cipher_TLS_NULL_WITH_NULL_NULL uint16 = 0x0000
- http2cipher_TLS_RSA_WITH_NULL_MD5 uint16 = 0x0001
- http2cipher_TLS_RSA_WITH_NULL_SHA uint16 = 0x0002
- http2cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0003
- http2cipher_TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004
- http2cipher_TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
- http2cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x0006
- http2cipher_TLS_RSA_WITH_IDEA_CBC_SHA uint16 = 0x0007
- http2cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0008
- http2cipher_TLS_RSA_WITH_DES_CBC_SHA uint16 = 0x0009
- http2cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000A
- http2cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000B
- http2cipher_TLS_DH_DSS_WITH_DES_CBC_SHA uint16 = 0x000C
- http2cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x000D
- http2cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000E
- http2cipher_TLS_DH_RSA_WITH_DES_CBC_SHA uint16 = 0x000F
- http2cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0010
- http2cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0011
- http2cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA uint16 = 0x0012
- http2cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x0013
- http2cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0014
- http2cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA uint16 = 0x0015
- http2cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0016
- http2cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0017
- http2cipher_TLS_DH_anon_WITH_RC4_128_MD5 uint16 = 0x0018
- http2cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0019
- http2cipher_TLS_DH_anon_WITH_DES_CBC_SHA uint16 = 0x001A
- http2cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0x001B
- // Reserved uint16 = 0x001C-1D
- http2cipher_TLS_KRB5_WITH_DES_CBC_SHA uint16 = 0x001E
- http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA uint16 = 0x001F
- http2cipher_TLS_KRB5_WITH_RC4_128_SHA uint16 = 0x0020
- http2cipher_TLS_KRB5_WITH_IDEA_CBC_SHA uint16 = 0x0021
- http2cipher_TLS_KRB5_WITH_DES_CBC_MD5 uint16 = 0x0022
- http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5 uint16 = 0x0023
- http2cipher_TLS_KRB5_WITH_RC4_128_MD5 uint16 = 0x0024
- http2cipher_TLS_KRB5_WITH_IDEA_CBC_MD5 uint16 = 0x0025
- http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA uint16 = 0x0026
- http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA uint16 = 0x0027
- http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA uint16 = 0x0028
- http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 uint16 = 0x0029
- http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x002A
- http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5 uint16 = 0x002B
- http2cipher_TLS_PSK_WITH_NULL_SHA uint16 = 0x002C
- http2cipher_TLS_DHE_PSK_WITH_NULL_SHA uint16 = 0x002D
- http2cipher_TLS_RSA_PSK_WITH_NULL_SHA uint16 = 0x002E
- http2cipher_TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002F
- http2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0030
- http2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0031
- http2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0032
- http2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0033
- http2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA uint16 = 0x0034
- http2cipher_TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
- http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0036
- http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0037
- http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0038
- http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0039
- http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA uint16 = 0x003A
- http2cipher_TLS_RSA_WITH_NULL_SHA256 uint16 = 0x003B
- http2cipher_TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003C
- http2cipher_TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003D
- http2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x003E
- http2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003F
- http2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x0040
- http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0041
- http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0042
- http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0043
- http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0044
- http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0045
- http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0046
- // Reserved uint16 = 0x0047-4F
- // Reserved uint16 = 0x0050-58
- // Reserved uint16 = 0x0059-5C
- // Unassigned uint16 = 0x005D-5F
- // Reserved uint16 = 0x0060-66
- http2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067
- http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x0068
- http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x0069
- http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x006A
- http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006B
- http2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256 uint16 = 0x006C
- http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256 uint16 = 0x006D
- // Unassigned uint16 = 0x006E-83
- http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0084
- http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0085
- http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0086
- http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0087
- http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0088
- http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0089
- http2cipher_TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008A
- http2cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008B
- http2cipher_TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008C
- http2cipher_TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008D
- http2cipher_TLS_DHE_PSK_WITH_RC4_128_SHA uint16 = 0x008E
- http2cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008F
- http2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0090
- http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0091
- http2cipher_TLS_RSA_PSK_WITH_RC4_128_SHA uint16 = 0x0092
- http2cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x0093
- http2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0094
- http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0095
- http2cipher_TLS_RSA_WITH_SEED_CBC_SHA uint16 = 0x0096
- http2cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA uint16 = 0x0097
- http2cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA uint16 = 0x0098
- http2cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA uint16 = 0x0099
- http2cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA uint16 = 0x009A
- http2cipher_TLS_DH_anon_WITH_SEED_CBC_SHA uint16 = 0x009B
- http2cipher_TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009C
- http2cipher_TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009D
- http2cipher_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009E
- http2cipher_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009F
- http2cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x00A0
- http2cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x00A1
- http2cipher_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A2
- http2cipher_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A3
- http2cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A4
- http2cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A5
- http2cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256 uint16 = 0x00A6
- http2cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384 uint16 = 0x00A7
- http2cipher_TLS_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00A8
- http2cipher_TLS_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00A9
- http2cipher_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AA
- http2cipher_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AB
- http2cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AC
- http2cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AD
- http2cipher_TLS_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00AE
- http2cipher_TLS_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00AF
- http2cipher_TLS_PSK_WITH_NULL_SHA256 uint16 = 0x00B0
- http2cipher_TLS_PSK_WITH_NULL_SHA384 uint16 = 0x00B1
- http2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B2
- http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B3
- http2cipher_TLS_DHE_PSK_WITH_NULL_SHA256 uint16 = 0x00B4
- http2cipher_TLS_DHE_PSK_WITH_NULL_SHA384 uint16 = 0x00B5
- http2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B6
- http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B7
- http2cipher_TLS_RSA_PSK_WITH_NULL_SHA256 uint16 = 0x00B8
- http2cipher_TLS_RSA_PSK_WITH_NULL_SHA384 uint16 = 0x00B9
- http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BA
- http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BB
- http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BC
- http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BD
- http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BE
- http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BF
- http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C0
- http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C1
- http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C2
- http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C3
- http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C4
- http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C5
- // Unassigned uint16 = 0x00C6-FE
- http2cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV uint16 = 0x00FF
- // Unassigned uint16 = 0x01-55,*
- http2cipher_TLS_FALLBACK_SCSV uint16 = 0x5600
- // Unassigned uint16 = 0x5601 - 0xC000
- http2cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA uint16 = 0xC001
- http2cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA uint16 = 0xC002
- http2cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC003
- http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC004
- http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC005
- http2cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA uint16 = 0xC006
- http2cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xC007
- http2cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC008
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC009
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC00A
- http2cipher_TLS_ECDH_RSA_WITH_NULL_SHA uint16 = 0xC00B
- http2cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA uint16 = 0xC00C
- http2cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC00D
- http2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC00E
- http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC00F
- http2cipher_TLS_ECDHE_RSA_WITH_NULL_SHA uint16 = 0xC010
- http2cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xC011
- http2cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC012
- http2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC013
- http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC014
- http2cipher_TLS_ECDH_anon_WITH_NULL_SHA uint16 = 0xC015
- http2cipher_TLS_ECDH_anon_WITH_RC4_128_SHA uint16 = 0xC016
- http2cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0xC017
- http2cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA uint16 = 0xC018
- http2cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA uint16 = 0xC019
- http2cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01A
- http2cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01B
- http2cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01C
- http2cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA uint16 = 0xC01D
- http2cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC01E
- http2cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA uint16 = 0xC01F
- http2cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA uint16 = 0xC020
- http2cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC021
- http2cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA uint16 = 0xC022
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC023
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC024
- http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC025
- http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC026
- http2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC027
- http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC028
- http2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC029
- http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC02A
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02B
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02C
- http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02D
- http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02E
- http2cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02F
- http2cipher_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC030
- http2cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC031
- http2cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC032
- http2cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA uint16 = 0xC033
- http2cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0xC034
- http2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xC035
- http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xC036
- http2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0xC037
- http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0xC038
- http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA uint16 = 0xC039
- http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256 uint16 = 0xC03A
- http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384 uint16 = 0xC03B
- http2cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03C
- http2cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03D
- http2cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03E
- http2cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03F
- http2cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC040
- http2cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC041
- http2cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC042
- http2cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC043
- http2cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC044
- http2cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC045
- http2cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC046
- http2cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC047
- http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC048
- http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC049
- http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04A
- http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04B
- http2cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04C
- http2cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04D
- http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04E
- http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04F
- http2cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC050
- http2cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC051
- http2cipher_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC052
- http2cipher_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC053
- http2cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC054
- http2cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC055
- http2cipher_TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC056
- http2cipher_TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC057
- http2cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC058
- http2cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC059
- http2cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05A
- http2cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05B
- http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05C
- http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05D
- http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05E
- http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05F
- http2cipher_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC060
- http2cipher_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC061
- http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC062
- http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC063
- http2cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC064
- http2cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC065
- http2cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC066
- http2cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC067
- http2cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC068
- http2cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC069
- http2cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06A
- http2cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06B
- http2cipher_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06C
- http2cipher_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06D
- http2cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06E
- http2cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06F
- http2cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC070
- http2cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC071
- http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC072
- http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC073
- http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC074
- http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC075
- http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC076
- http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC077
- http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC078
- http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC079
- http2cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07A
- http2cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07B
- http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07C
- http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07D
- http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07E
- http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07F
- http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC080
- http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC081
- http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC082
- http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC083
- http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC084
- http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC085
- http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC086
- http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC087
- http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC088
- http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC089
- http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08A
- http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08B
- http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08C
- http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08D
- http2cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08E
- http2cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08F
- http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC090
- http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC091
- http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC092
- http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC093
- http2cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC094
- http2cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC095
- http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC096
- http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC097
- http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC098
- http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC099
- http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC09A
- http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC09B
- http2cipher_TLS_RSA_WITH_AES_128_CCM uint16 = 0xC09C
- http2cipher_TLS_RSA_WITH_AES_256_CCM uint16 = 0xC09D
- http2cipher_TLS_DHE_RSA_WITH_AES_128_CCM uint16 = 0xC09E
- http2cipher_TLS_DHE_RSA_WITH_AES_256_CCM uint16 = 0xC09F
- http2cipher_TLS_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A0
- http2cipher_TLS_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A1
- http2cipher_TLS_DHE_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A2
- http2cipher_TLS_DHE_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A3
- http2cipher_TLS_PSK_WITH_AES_128_CCM uint16 = 0xC0A4
- http2cipher_TLS_PSK_WITH_AES_256_CCM uint16 = 0xC0A5
- http2cipher_TLS_DHE_PSK_WITH_AES_128_CCM uint16 = 0xC0A6
- http2cipher_TLS_DHE_PSK_WITH_AES_256_CCM uint16 = 0xC0A7
- http2cipher_TLS_PSK_WITH_AES_128_CCM_8 uint16 = 0xC0A8
- http2cipher_TLS_PSK_WITH_AES_256_CCM_8 uint16 = 0xC0A9
- http2cipher_TLS_PSK_DHE_WITH_AES_128_CCM_8 uint16 = 0xC0AA
- http2cipher_TLS_PSK_DHE_WITH_AES_256_CCM_8 uint16 = 0xC0AB
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM uint16 = 0xC0AC
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM uint16 = 0xC0AD
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 uint16 = 0xC0AE
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 uint16 = 0xC0AF
- // Unassigned uint16 = 0xC0B0-FF
- // Unassigned uint16 = 0xC1-CB,*
- // Unassigned uint16 = 0xCC00-A7
- http2cipher_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA8
- http2cipher_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA9
- http2cipher_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAA
- http2cipher_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAB
- http2cipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAC
- http2cipher_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAD
- http2cipher_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAE
-)
-
-// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec.
-// References:
-// https://tools.ietf.org/html/rfc7540#appendix-A
-// Reject cipher suites from Appendix A.
-// "This list includes those cipher suites that do not
-// offer an ephemeral key exchange and those that are
-// based on the TLS null, stream or block cipher type"
-func http2isBadCipher(cipher uint16) bool {
- switch cipher {
- case http2cipher_TLS_NULL_WITH_NULL_NULL,
- http2cipher_TLS_RSA_WITH_NULL_MD5,
- http2cipher_TLS_RSA_WITH_NULL_SHA,
- http2cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5,
- http2cipher_TLS_RSA_WITH_RC4_128_MD5,
- http2cipher_TLS_RSA_WITH_RC4_128_SHA,
- http2cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
- http2cipher_TLS_RSA_WITH_IDEA_CBC_SHA,
- http2cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
- http2cipher_TLS_RSA_WITH_DES_CBC_SHA,
- http2cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
- http2cipher_TLS_DH_DSS_WITH_DES_CBC_SHA,
- http2cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
- http2cipher_TLS_DH_RSA_WITH_DES_CBC_SHA,
- http2cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
- http2cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA,
- http2cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
- http2cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA,
- http2cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5,
- http2cipher_TLS_DH_anon_WITH_RC4_128_MD5,
- http2cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
- http2cipher_TLS_DH_anon_WITH_DES_CBC_SHA,
- http2cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_KRB5_WITH_DES_CBC_SHA,
- http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_KRB5_WITH_RC4_128_SHA,
- http2cipher_TLS_KRB5_WITH_IDEA_CBC_SHA,
- http2cipher_TLS_KRB5_WITH_DES_CBC_MD5,
- http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5,
- http2cipher_TLS_KRB5_WITH_RC4_128_MD5,
- http2cipher_TLS_KRB5_WITH_IDEA_CBC_MD5,
- http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA,
- http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA,
- http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA,
- http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5,
- http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5,
- http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5,
- http2cipher_TLS_PSK_WITH_NULL_SHA,
- http2cipher_TLS_DHE_PSK_WITH_NULL_SHA,
- http2cipher_TLS_RSA_PSK_WITH_NULL_SHA,
- http2cipher_TLS_RSA_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_RSA_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_RSA_WITH_NULL_SHA256,
- http2cipher_TLS_RSA_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_RSA_WITH_AES_256_CBC_SHA256,
- http2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
- http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
- http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
- http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
- http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
- http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,
- http2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256,
- http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256,
- http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
- http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
- http2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256,
- http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
- http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
- http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
- http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
- http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
- http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA,
- http2cipher_TLS_PSK_WITH_RC4_128_SHA,
- http2cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_PSK_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_PSK_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_DHE_PSK_WITH_RC4_128_SHA,
- http2cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_RSA_PSK_WITH_RC4_128_SHA,
- http2cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_RSA_WITH_SEED_CBC_SHA,
- http2cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA,
- http2cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA,
- http2cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA,
- http2cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA,
- http2cipher_TLS_DH_anon_WITH_SEED_CBC_SHA,
- http2cipher_TLS_RSA_WITH_AES_128_GCM_SHA256,
- http2cipher_TLS_RSA_WITH_AES_256_GCM_SHA384,
- http2cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
- http2cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384,
- http2cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256,
- http2cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384,
- http2cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256,
- http2cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384,
- http2cipher_TLS_PSK_WITH_AES_128_GCM_SHA256,
- http2cipher_TLS_PSK_WITH_AES_256_GCM_SHA384,
- http2cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
- http2cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
- http2cipher_TLS_PSK_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_PSK_WITH_AES_256_CBC_SHA384,
- http2cipher_TLS_PSK_WITH_NULL_SHA256,
- http2cipher_TLS_PSK_WITH_NULL_SHA384,
- http2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
- http2cipher_TLS_DHE_PSK_WITH_NULL_SHA256,
- http2cipher_TLS_DHE_PSK_WITH_NULL_SHA384,
- http2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
- http2cipher_TLS_RSA_PSK_WITH_NULL_SHA256,
- http2cipher_TLS_RSA_PSK_WITH_NULL_SHA384,
- http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
- http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256,
- http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256,
- http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,
- http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
- http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,
- http2cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
- http2cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA,
- http2cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
- http2cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA,
- http2cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
- http2cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_ECDH_RSA_WITH_NULL_SHA,
- http2cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA,
- http2cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_ECDHE_RSA_WITH_NULL_SHA,
- http2cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA,
- http2cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_ECDH_anon_WITH_NULL_SHA,
- http2cipher_TLS_ECDH_anon_WITH_RC4_128_SHA,
- http2cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
- http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
- http2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
- http2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
- http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
- http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
- http2cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
- http2cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
- http2cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA,
- http2cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
- http2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
- http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
- http2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
- http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
- http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA,
- http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256,
- http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384,
- http2cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
- http2cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
- http2cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256,
- http2cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384,
- http2cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256,
- http2cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384,
- http2cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256,
- http2cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384,
- http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
- http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
- http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
- http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
- http2cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
- http2cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
- http2cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
- http2cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
- http2cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
- http2cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
- http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
- http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
- http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
- http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,
- http2cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- http2cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256,
- http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384,
- http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256,
- http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384,
- http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
- http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
- http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
- http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
- http2cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
- http2cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
- http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
- http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
- http2cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
- http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
- http2cipher_TLS_RSA_WITH_AES_128_CCM,
- http2cipher_TLS_RSA_WITH_AES_256_CCM,
- http2cipher_TLS_RSA_WITH_AES_128_CCM_8,
- http2cipher_TLS_RSA_WITH_AES_256_CCM_8,
- http2cipher_TLS_PSK_WITH_AES_128_CCM,
- http2cipher_TLS_PSK_WITH_AES_256_CCM,
- http2cipher_TLS_PSK_WITH_AES_128_CCM_8,
- http2cipher_TLS_PSK_WITH_AES_256_CCM_8:
- return true
- default:
- return false
- }
-}
-
-// ClientConnPool manages a pool of HTTP/2 client connections.
-type http2ClientConnPool interface {
- // GetClientConn returns a specific HTTP/2 connection (usually
- // a TLS-TCP connection) to an HTTP/2 server. On success, the
- // returned ClientConn accounts for the upcoming RoundTrip
- // call, so the caller should not omit it. If the caller needs
- // to, ClientConn.RoundTrip can be called with a bogus
- // new(http.Request) to release the stream reservation.
- GetClientConn(req *Request, addr string) (*http2ClientConn, error)
- MarkDead(*http2ClientConn)
-}
-
-// clientConnPoolIdleCloser is the interface implemented by ClientConnPool
-// implementations which can close their idle connections.
-type http2clientConnPoolIdleCloser interface {
- http2ClientConnPool
- closeIdleConnections()
-}
-
-var (
- _ http2clientConnPoolIdleCloser = (*http2clientConnPool)(nil)
- _ http2clientConnPoolIdleCloser = http2noDialClientConnPool{}
-)
-
-// TODO: use singleflight for dialing and addConnCalls?
-type http2clientConnPool struct {
- t *http2Transport
-
- mu sync.Mutex // TODO: maybe switch to RWMutex
- // TODO: add support for sharing conns based on cert names
- // (e.g. share conn for googleapis.com and appspot.com)
- conns map[string][]*http2ClientConn // key is host:port
- dialing map[string]*http2dialCall // currently in-flight dials
- keys map[*http2ClientConn][]string
- addConnCalls map[string]*http2addConnCall // in-flight addConnIfNeeded calls
-}
-
-func (p *http2clientConnPool) GetClientConn(req *Request, addr string) (*http2ClientConn, error) {
- return p.getClientConn(req, addr, http2dialOnMiss)
-}
-
-const (
- http2dialOnMiss = true
- http2noDialOnMiss = false
-)
-
-func (p *http2clientConnPool) getClientConn(req *Request, addr string, dialOnMiss bool) (*http2ClientConn, error) {
- // TODO(dneil): Dial a new connection when t.DisableKeepAlives is set?
- if http2isConnectionCloseRequest(req) && dialOnMiss {
- // It gets its own connection.
- http2traceGetConn(req, addr)
- const singleUse = true
- cc, err := p.t.dialClientConn(req.Context(), addr, singleUse)
- if err != nil {
- return nil, err
- }
- return cc, nil
- }
- for {
- p.mu.Lock()
- for _, cc := range p.conns[addr] {
- if cc.ReserveNewRequest() {
- // When a connection is presented to us by the net/http package,
- // the GetConn hook has already been called.
- // Don't call it a second time here.
- if !cc.getConnCalled {
- http2traceGetConn(req, addr)
- }
- cc.getConnCalled = false
- p.mu.Unlock()
- return cc, nil
- }
- }
- if !dialOnMiss {
- p.mu.Unlock()
- return nil, http2ErrNoCachedConn
- }
- http2traceGetConn(req, addr)
- call := p.getStartDialLocked(req.Context(), addr)
- p.mu.Unlock()
- <-call.done
- if http2shouldRetryDial(call, req) {
- continue
- }
- cc, err := call.res, call.err
- if err != nil {
- return nil, err
- }
- if cc.ReserveNewRequest() {
- return cc, nil
- }
- }
-}
-
-// dialCall is an in-flight Transport dial call to a host.
-type http2dialCall struct {
- _ http2incomparable
- p *http2clientConnPool
- // the context associated with the request
- // that created this dialCall
- ctx context.Context
- done chan struct{} // closed when done
- res *http2ClientConn // valid after done is closed
- err error // valid after done is closed
-}
-
-// requires p.mu is held.
-func (p *http2clientConnPool) getStartDialLocked(ctx context.Context, addr string) *http2dialCall {
- if call, ok := p.dialing[addr]; ok {
- // A dial is already in-flight. Don't start another.
- return call
- }
- call := &http2dialCall{p: p, done: make(chan struct{}), ctx: ctx}
- if p.dialing == nil {
- p.dialing = make(map[string]*http2dialCall)
- }
- p.dialing[addr] = call
- go call.dial(call.ctx, addr)
- return call
-}
-
-// run in its own goroutine.
-func (c *http2dialCall) dial(ctx context.Context, addr string) {
- const singleUse = false // shared conn
- c.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse)
-
- c.p.mu.Lock()
- delete(c.p.dialing, addr)
- if c.err == nil {
- c.p.addConnLocked(addr, c.res)
- }
- c.p.mu.Unlock()
-
- close(c.done)
-}
-
-// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't
-// already exist. It coalesces concurrent calls with the same key.
-// This is used by the http1 Transport code when it creates a new connection. Because
-// the http1 Transport doesn't de-dup TCP dials to outbound hosts (because it doesn't know
-// the protocol), it can get into a situation where it has multiple TLS connections.
-// This code decides which ones live or die.
-// The return value used is whether c was used.
-// c is never closed.
-func (p *http2clientConnPool) addConnIfNeeded(key string, t *http2Transport, c *tls.Conn) (used bool, err error) {
- p.mu.Lock()
- for _, cc := range p.conns[key] {
- if cc.CanTakeNewRequest() {
- p.mu.Unlock()
- return false, nil
- }
- }
- call, dup := p.addConnCalls[key]
- if !dup {
- if p.addConnCalls == nil {
- p.addConnCalls = make(map[string]*http2addConnCall)
- }
- call = &http2addConnCall{
- p: p,
- done: make(chan struct{}),
- }
- p.addConnCalls[key] = call
- go call.run(t, key, c)
- }
- p.mu.Unlock()
-
- <-call.done
- if call.err != nil {
- return false, call.err
- }
- return !dup, nil
-}
-
-type http2addConnCall struct {
- _ http2incomparable
- p *http2clientConnPool
- done chan struct{} // closed when done
- err error
-}
-
-func (c *http2addConnCall) run(t *http2Transport, key string, tc *tls.Conn) {
- cc, err := t.NewClientConn(tc)
-
- p := c.p
- p.mu.Lock()
- if err != nil {
- c.err = err
- } else {
- cc.getConnCalled = true // already called by the net/http package
- p.addConnLocked(key, cc)
- }
- delete(p.addConnCalls, key)
- p.mu.Unlock()
- close(c.done)
-}
-
-// p.mu must be held
-func (p *http2clientConnPool) addConnLocked(key string, cc *http2ClientConn) {
- for _, v := range p.conns[key] {
- if v == cc {
- return
- }
- }
- if p.conns == nil {
- p.conns = make(map[string][]*http2ClientConn)
- }
- if p.keys == nil {
- p.keys = make(map[*http2ClientConn][]string)
- }
- p.conns[key] = append(p.conns[key], cc)
- p.keys[cc] = append(p.keys[cc], key)
-}
-
-func (p *http2clientConnPool) MarkDead(cc *http2ClientConn) {
- p.mu.Lock()
- defer p.mu.Unlock()
- for _, key := range p.keys[cc] {
- vv, ok := p.conns[key]
- if !ok {
- continue
- }
- newList := http2filterOutClientConn(vv, cc)
- if len(newList) > 0 {
- p.conns[key] = newList
- } else {
- delete(p.conns, key)
- }
- }
- delete(p.keys, cc)
-}
-
-func (p *http2clientConnPool) closeIdleConnections() {
- p.mu.Lock()
- defer p.mu.Unlock()
- // TODO: don't close a cc if it was just added to the pool
- // milliseconds ago and has never been used. There's currently
- // a small race window with the HTTP/1 Transport's integration
- // where it can add an idle conn just before using it, and
- // somebody else can concurrently call CloseIdleConns and
- // break some caller's RoundTrip.
- for _, vv := range p.conns {
- for _, cc := range vv {
- cc.closeIfIdle()
- }
- }
-}
-
-func http2filterOutClientConn(in []*http2ClientConn, exclude *http2ClientConn) []*http2ClientConn {
- out := in[:0]
- for _, v := range in {
- if v != exclude {
- out = append(out, v)
- }
- }
- // If we filtered it out, zero out the last item to prevent
- // the GC from seeing it.
- if len(in) != len(out) {
- in[len(in)-1] = nil
- }
- return out
-}
-
-// noDialClientConnPool is an implementation of http2.ClientConnPool
-// which never dials. We let the HTTP/1.1 client dial and use its TLS
-// connection instead.
-type http2noDialClientConnPool struct{ *http2clientConnPool }
-
-func (p http2noDialClientConnPool) GetClientConn(req *Request, addr string) (*http2ClientConn, error) {
- return p.getClientConn(req, addr, http2noDialOnMiss)
-}
-
-// shouldRetryDial reports whether the current request should
-// retry dialing after the call finished unsuccessfully, for example
-// if the dial was canceled because of a context cancellation or
-// deadline expiry.
-func http2shouldRetryDial(call *http2dialCall, req *Request) bool {
- if call.err == nil {
- // No error, no need to retry
- return false
- }
- if call.ctx == req.Context() {
- // If the call has the same context as the request, the dial
- // should not be retried, since any cancellation will have come
- // from this request.
- return false
- }
- if !errors.Is(call.err, context.Canceled) && !errors.Is(call.err, context.DeadlineExceeded) {
- // If the call error is not because of a context cancellation or a deadline expiry,
- // the dial should not be retried.
- return false
- }
- // Only retry if the error is a context cancellation error or deadline expiry
- // and the context associated with the call was canceled or expired.
- return call.ctx.Err() != nil
-}
-
-// Buffer chunks are allocated from a pool to reduce pressure on GC.
-// The maximum wasted space per dataBuffer is 2x the largest size class,
-// which happens when the dataBuffer has multiple chunks and there is
-// one unread byte in both the first and last chunks. We use a few size
-// classes to minimize overheads for servers that typically receive very
-// small request bodies.
-//
-// TODO: Benchmark to determine if the pools are necessary. The GC may have
-// improved enough that we can instead allocate chunks like this:
-// make([]byte, max(16<<10, expectedBytesRemaining))
-var (
- http2dataChunkSizeClasses = []int{
- 1 << 10,
- 2 << 10,
- 4 << 10,
- 8 << 10,
- 16 << 10,
- }
- http2dataChunkPools = [...]sync.Pool{
- {New: func() interface{} { return make([]byte, 1<<10) }},
- {New: func() interface{} { return make([]byte, 2<<10) }},
- {New: func() interface{} { return make([]byte, 4<<10) }},
- {New: func() interface{} { return make([]byte, 8<<10) }},
- {New: func() interface{} { return make([]byte, 16<<10) }},
- }
-)
-
-func http2getDataBufferChunk(size int64) []byte {
- i := 0
- for ; i < len(http2dataChunkSizeClasses)-1; i++ {
- if size <= int64(http2dataChunkSizeClasses[i]) {
- break
- }
- }
- return http2dataChunkPools[i].Get().([]byte)
-}
-
-func http2putDataBufferChunk(p []byte) {
- for i, n := range http2dataChunkSizeClasses {
- if len(p) == n {
- http2dataChunkPools[i].Put(p)
- return
- }
- }
- panic(fmt.Sprintf("unexpected buffer len=%v", len(p)))
-}
-
-// dataBuffer is an io.ReadWriter backed by a list of data chunks.
-// Each dataBuffer is used to read DATA frames on a single stream.
-// The buffer is divided into chunks so the server can limit the
-// total memory used by a single connection without limiting the
-// request body size on any single stream.
-type http2dataBuffer struct {
- chunks [][]byte
- r int // next byte to read is chunks[0][r]
- w int // next byte to write is chunks[len(chunks)-1][w]
- size int // total buffered bytes
- expected int64 // we expect at least this many bytes in future Write calls (ignored if <= 0)
-}
-
-var http2errReadEmpty = errors.New("read from empty dataBuffer")
-
-// Read copies bytes from the buffer into p.
-// It is an error to read when no data is available.
-func (b *http2dataBuffer) Read(p []byte) (int, error) {
- if b.size == 0 {
- return 0, http2errReadEmpty
- }
- var ntotal int
- for len(p) > 0 && b.size > 0 {
- readFrom := b.bytesFromFirstChunk()
- n := copy(p, readFrom)
- p = p[n:]
- ntotal += n
- b.r += n
- b.size -= n
- // If the first chunk has been consumed, advance to the next chunk.
- if b.r == len(b.chunks[0]) {
- http2putDataBufferChunk(b.chunks[0])
- end := len(b.chunks) - 1
- copy(b.chunks[:end], b.chunks[1:])
- b.chunks[end] = nil
- b.chunks = b.chunks[:end]
- b.r = 0
- }
- }
- return ntotal, nil
-}
-
-func (b *http2dataBuffer) bytesFromFirstChunk() []byte {
- if len(b.chunks) == 1 {
- return b.chunks[0][b.r:b.w]
- }
- return b.chunks[0][b.r:]
-}
-
-// Len returns the number of bytes of the unread portion of the buffer.
-func (b *http2dataBuffer) Len() int {
- return b.size
-}
-
-// Write appends p to the buffer.
-func (b *http2dataBuffer) Write(p []byte) (int, error) {
- ntotal := len(p)
- for len(p) > 0 {
- // If the last chunk is empty, allocate a new chunk. Try to allocate
- // enough to fully copy p plus any additional bytes we expect to
- // receive. However, this may allocate less than len(p).
- want := int64(len(p))
- if b.expected > want {
- want = b.expected
- }
- chunk := b.lastChunkOrAlloc(want)
- n := copy(chunk[b.w:], p)
- p = p[n:]
- b.w += n
- b.size += n
- b.expected -= int64(n)
- }
- return ntotal, nil
-}
-
-func (b *http2dataBuffer) lastChunkOrAlloc(want int64) []byte {
- if len(b.chunks) != 0 {
- last := b.chunks[len(b.chunks)-1]
- if b.w < len(last) {
- return last
- }
- }
- chunk := http2getDataBufferChunk(want)
- b.chunks = append(b.chunks, chunk)
- b.w = 0
- return chunk
-}
-
-// An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec.
-type http2ErrCode uint32
-
-const (
- http2ErrCodeNo http2ErrCode = 0x0
- http2ErrCodeProtocol http2ErrCode = 0x1
- http2ErrCodeInternal http2ErrCode = 0x2
- http2ErrCodeFlowControl http2ErrCode = 0x3
- http2ErrCodeSettingsTimeout http2ErrCode = 0x4
- http2ErrCodeStreamClosed http2ErrCode = 0x5
- http2ErrCodeFrameSize http2ErrCode = 0x6
- http2ErrCodeRefusedStream http2ErrCode = 0x7
- http2ErrCodeCancel http2ErrCode = 0x8
- http2ErrCodeCompression http2ErrCode = 0x9
- http2ErrCodeConnect http2ErrCode = 0xa
- http2ErrCodeEnhanceYourCalm http2ErrCode = 0xb
- http2ErrCodeInadequateSecurity http2ErrCode = 0xc
- http2ErrCodeHTTP11Required http2ErrCode = 0xd
-)
-
-var http2errCodeName = map[http2ErrCode]string{
- http2ErrCodeNo: "NO_ERROR",
- http2ErrCodeProtocol: "PROTOCOL_ERROR",
- http2ErrCodeInternal: "INTERNAL_ERROR",
- http2ErrCodeFlowControl: "FLOW_CONTROL_ERROR",
- http2ErrCodeSettingsTimeout: "SETTINGS_TIMEOUT",
- http2ErrCodeStreamClosed: "STREAM_CLOSED",
- http2ErrCodeFrameSize: "FRAME_SIZE_ERROR",
- http2ErrCodeRefusedStream: "REFUSED_STREAM",
- http2ErrCodeCancel: "CANCEL",
- http2ErrCodeCompression: "COMPRESSION_ERROR",
- http2ErrCodeConnect: "CONNECT_ERROR",
- http2ErrCodeEnhanceYourCalm: "ENHANCE_YOUR_CALM",
- http2ErrCodeInadequateSecurity: "INADEQUATE_SECURITY",
- http2ErrCodeHTTP11Required: "HTTP_1_1_REQUIRED",
-}
-
-func (e http2ErrCode) String() string {
- if s, ok := http2errCodeName[e]; ok {
- return s
- }
- return fmt.Sprintf("unknown error code 0x%x", uint32(e))
-}
-
-func (e http2ErrCode) stringToken() string {
- if s, ok := http2errCodeName[e]; ok {
- return s
- }
- return fmt.Sprintf("ERR_UNKNOWN_%d", uint32(e))
-}
-
-// ConnectionError is an error that results in the termination of the
-// entire connection.
-type http2ConnectionError http2ErrCode
-
-func (e http2ConnectionError) Error() string {
- return fmt.Sprintf("connection error: %s", http2ErrCode(e))
-}
-
-// StreamError is an error that only affects one stream within an
-// HTTP/2 connection.
-type http2StreamError struct {
- StreamID uint32
- Code http2ErrCode
- Cause error // optional additional detail
-}
-
-// errFromPeer is a sentinel error value for StreamError.Cause to
-// indicate that the StreamError was sent from the peer over the wire
-// and wasn't locally generated in the Transport.
-var http2errFromPeer = errors.New("received from peer")
-
-func http2streamError(id uint32, code http2ErrCode) http2StreamError {
- return http2StreamError{StreamID: id, Code: code}
-}
-
-func (e http2StreamError) Error() string {
- if e.Cause != nil {
- return fmt.Sprintf("stream error: stream ID %d; %v; %v", e.StreamID, e.Code, e.Cause)
- }
- return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code)
-}
-
-// 6.9.1 The Flow Control Window
-// "If a sender receives a WINDOW_UPDATE that causes a flow control
-// window to exceed this maximum it MUST terminate either the stream
-// or the connection, as appropriate. For streams, [...]; for the
-// connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code."
-type http2goAwayFlowError struct{}
-
-func (http2goAwayFlowError) Error() string { return "connection exceeded flow control window size" }
-
-// connError represents an HTTP/2 ConnectionError error code, along
-// with a string (for debugging) explaining why.
-//
-// Errors of this type are only returned by the frame parser functions
-// and converted into ConnectionError(Code), after stashing away
-// the Reason into the Framer's errDetail field, accessible via
-// the (*Framer).ErrorDetail method.
-type http2connError struct {
- Code http2ErrCode // the ConnectionError error code
- Reason string // additional reason
-}
-
-func (e http2connError) Error() string {
- return fmt.Sprintf("http2: connection error: %v: %v", e.Code, e.Reason)
-}
-
-type http2pseudoHeaderError string
-
-func (e http2pseudoHeaderError) Error() string {
- return fmt.Sprintf("invalid pseudo-header %q", string(e))
-}
-
-type http2duplicatePseudoHeaderError string
-
-func (e http2duplicatePseudoHeaderError) Error() string {
- return fmt.Sprintf("duplicate pseudo-header %q", string(e))
-}
-
-type http2headerFieldNameError string
-
-func (e http2headerFieldNameError) Error() string {
- return fmt.Sprintf("invalid header field name %q", string(e))
-}
-
-type http2headerFieldValueError string
-
-func (e http2headerFieldValueError) Error() string {
- return fmt.Sprintf("invalid header field value for %q", string(e))
-}
-
-var (
- http2errMixPseudoHeaderTypes = errors.New("mix of request and response pseudo headers")
- http2errPseudoAfterRegular = errors.New("pseudo header field after regular")
-)
-
-// flow is the flow control window's size.
-type http2flow struct {
- _ http2incomparable
-
- // n is the number of DATA bytes we're allowed to send.
- // A flow is kept both on a conn and a per-stream.
- n int32
-
- // conn points to the shared connection-level flow that is
- // shared by all streams on that conn. It is nil for the flow
- // that's on the conn directly.
- conn *http2flow
-}
-
-func (f *http2flow) setConnFlow(cf *http2flow) { f.conn = cf }
-
-func (f *http2flow) available() int32 {
- n := f.n
- if f.conn != nil && f.conn.n < n {
- n = f.conn.n
- }
- return n
-}
-
-func (f *http2flow) take(n int32) {
- if n > f.available() {
- panic("internal error: took too much")
- }
- f.n -= n
- if f.conn != nil {
- f.conn.n -= n
- }
-}
-
-// add adds n bytes (positive or negative) to the flow control window.
-// It returns false if the sum would exceed 2^31-1.
-func (f *http2flow) add(n int32) bool {
- sum := f.n + n
- if (sum > n) == (f.n > 0) {
- f.n = sum
- return true
- }
- return false
-}
-
-const http2frameHeaderLen = 9
-
-var http2padZeros = make([]byte, 255) // zeros for padding
-
-// A FrameType is a registered frame type as defined in
-// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2
-type http2FrameType uint8
-
-const (
- http2FrameData http2FrameType = 0x0
- http2FrameHeaders http2FrameType = 0x1
- http2FramePriority http2FrameType = 0x2
- http2FrameRSTStream http2FrameType = 0x3
- http2FrameSettings http2FrameType = 0x4
- http2FramePushPromise http2FrameType = 0x5
- http2FramePing http2FrameType = 0x6
- http2FrameGoAway http2FrameType = 0x7
- http2FrameWindowUpdate http2FrameType = 0x8
- http2FrameContinuation http2FrameType = 0x9
-)
-
-var http2frameName = map[http2FrameType]string{
- http2FrameData: "DATA",
- http2FrameHeaders: "HEADERS",
- http2FramePriority: "PRIORITY",
- http2FrameRSTStream: "RST_STREAM",
- http2FrameSettings: "SETTINGS",
- http2FramePushPromise: "PUSH_PROMISE",
- http2FramePing: "PING",
- http2FrameGoAway: "GOAWAY",
- http2FrameWindowUpdate: "WINDOW_UPDATE",
- http2FrameContinuation: "CONTINUATION",
-}
-
-func (t http2FrameType) String() string {
- if s, ok := http2frameName[t]; ok {
- return s
- }
- return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t))
-}
-
-// Flags is a bitmask of HTTP/2 flags.
-// The meaning of flags varies depending on the frame type.
-type http2Flags uint8
-
-// Has reports whether f contains all (0 or more) flags in v.
-func (f http2Flags) Has(v http2Flags) bool {
- return (f & v) == v
-}
-
-// Frame-specific FrameHeader flag bits.
-const (
- // Data Frame
- http2FlagDataEndStream http2Flags = 0x1
- http2FlagDataPadded http2Flags = 0x8
-
- // Headers Frame
- http2FlagHeadersEndStream http2Flags = 0x1
- http2FlagHeadersEndHeaders http2Flags = 0x4
- http2FlagHeadersPadded http2Flags = 0x8
- http2FlagHeadersPriority http2Flags = 0x20
-
- // Settings Frame
- http2FlagSettingsAck http2Flags = 0x1
-
- // Ping Frame
- http2FlagPingAck http2Flags = 0x1
-
- // Continuation Frame
- http2FlagContinuationEndHeaders http2Flags = 0x4
-
- http2FlagPushPromiseEndHeaders http2Flags = 0x4
- http2FlagPushPromisePadded http2Flags = 0x8
-)
-
-var http2flagName = map[http2FrameType]map[http2Flags]string{
- http2FrameData: {
- http2FlagDataEndStream: "END_STREAM",
- http2FlagDataPadded: "PADDED",
- },
- http2FrameHeaders: {
- http2FlagHeadersEndStream: "END_STREAM",
- http2FlagHeadersEndHeaders: "END_HEADERS",
- http2FlagHeadersPadded: "PADDED",
- http2FlagHeadersPriority: "PRIORITY",
- },
- http2FrameSettings: {
- http2FlagSettingsAck: "ACK",
- },
- http2FramePing: {
- http2FlagPingAck: "ACK",
- },
- http2FrameContinuation: {
- http2FlagContinuationEndHeaders: "END_HEADERS",
- },
- http2FramePushPromise: {
- http2FlagPushPromiseEndHeaders: "END_HEADERS",
- http2FlagPushPromisePadded: "PADDED",
- },
-}
-
-// a frameParser parses a frame given its FrameHeader and payload
-// bytes. The length of payload will always equal fh.Length (which
-// might be 0).
-type http2frameParser func(fc *http2frameCache, fh http2FrameHeader, countError func(string), payload []byte) (http2Frame, error)
-
-var http2frameParsers = map[http2FrameType]http2frameParser{
- http2FrameData: http2parseDataFrame,
- http2FrameHeaders: http2parseHeadersFrame,
- http2FramePriority: http2parsePriorityFrame,
- http2FrameRSTStream: http2parseRSTStreamFrame,
- http2FrameSettings: http2parseSettingsFrame,
- http2FramePushPromise: http2parsePushPromise,
- http2FramePing: http2parsePingFrame,
- http2FrameGoAway: http2parseGoAwayFrame,
- http2FrameWindowUpdate: http2parseWindowUpdateFrame,
- http2FrameContinuation: http2parseContinuationFrame,
-}
-
-func http2typeFrameParser(t http2FrameType) http2frameParser {
- if f := http2frameParsers[t]; f != nil {
- return f
- }
- return http2parseUnknownFrame
-}
-
-// A FrameHeader is the 9 byte header of all HTTP/2 frames.
-//
-// See https://httpwg.org/specs/rfc7540.html#FrameHeader
-type http2FrameHeader struct {
- valid bool // caller can access []byte fields in the Frame
-
- // Type is the 1 byte frame type. There are ten standard frame
- // types, but extension frame types may be written by WriteRawFrame
- // and will be returned by ReadFrame (as UnknownFrame).
- Type http2FrameType
-
- // Flags are the 1 byte of 8 potential bit flags per frame.
- // They are specific to the frame type.
- Flags http2Flags
-
- // Length is the length of the frame, not including the 9 byte header.
- // The maximum size is one byte less than 16MB (uint24), but only
- // frames up to 16KB are allowed without peer agreement.
- Length uint32
-
- // StreamID is which stream this frame is for. Certain frames
- // are not stream-specific, in which case this field is 0.
- StreamID uint32
-}
-
-// Header returns h. It exists so FrameHeaders can be embedded in other
-// specific frame types and implement the Frame interface.
-func (h http2FrameHeader) Header() http2FrameHeader { return h }
-
-func (h http2FrameHeader) String() string {
- var buf bytes.Buffer
- buf.WriteString("[FrameHeader ")
- h.writeDebug(&buf)
- buf.WriteByte(']')
- return buf.String()
-}
-
-func (h http2FrameHeader) writeDebug(buf *bytes.Buffer) {
- buf.WriteString(h.Type.String())
- if h.Flags != 0 {
- buf.WriteString(" flags=")
- set := 0
- for i := uint8(0); i < 8; i++ {
- if h.Flags&(1<<i) == 0 {
- continue
- }
- set++
- if set > 1 {
- buf.WriteByte('|')
- }
- name := http2flagName[h.Type][http2Flags(1<<i)]
- if name != "" {
- buf.WriteString(name)
- } else {
- fmt.Fprintf(buf, "0x%x", 1<<i)
- }
- }
- }
- if h.StreamID != 0 {
- fmt.Fprintf(buf, " stream=%d", h.StreamID)
- }
- fmt.Fprintf(buf, " len=%d", h.Length)
-}
-
-func (h *http2FrameHeader) checkValid() {
- if !h.valid {
- panic("Frame accessor called on non-owned Frame")
- }
-}
-
-func (h *http2FrameHeader) invalidate() { h.valid = false }
-
-// frame header bytes.
-// Used only by ReadFrameHeader.
-var http2fhBytes = sync.Pool{
- New: func() interface{} {
- buf := make([]byte, http2frameHeaderLen)
- return &buf
- },
-}
-
-// ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.
-// Most users should use Framer.ReadFrame instead.
-func http2ReadFrameHeader(r io.Reader) (http2FrameHeader, error) {
- bufp := http2fhBytes.Get().(*[]byte)
- defer http2fhBytes.Put(bufp)
- return http2readFrameHeader(*bufp, r)
-}
-
-func http2readFrameHeader(buf []byte, r io.Reader) (http2FrameHeader, error) {
- _, err := io.ReadFull(r, buf[:http2frameHeaderLen])
- if err != nil {
- return http2FrameHeader{}, err
- }
- return http2FrameHeader{
- Length: (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])),
- Type: http2FrameType(buf[3]),
- Flags: http2Flags(buf[4]),
- StreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1),
- valid: true,
- }, nil
-}
-
-// A Frame is the base interface implemented by all frame types.
-// Callers will generally type-assert the specific frame type:
-// *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc.
-//
-// Frames are only valid until the next call to Framer.ReadFrame.
-type http2Frame interface {
- Header() http2FrameHeader
-
- // invalidate is called by Framer.ReadFrame to make this
- // frame's buffers as being invalid, since the subsequent
- // frame will reuse them.
- invalidate()
-}
-
-// A Framer reads and writes Frames.
-type http2Framer struct {
- r io.Reader
- lastFrame http2Frame
- errDetail error
-
- // countError is a non-nil func that's called on a frame parse
- // error with some unique error path token. It's initialized
- // from Transport.CountError or Server.CountError.
- countError func(errToken string)
-
- // lastHeaderStream is non-zero if the last frame was an
- // unfinished HEADERS/CONTINUATION.
- lastHeaderStream uint32
-
- maxReadSize uint32
- headerBuf [http2frameHeaderLen]byte
-
- // TODO: let getReadBuf be configurable, and use a less memory-pinning
- // allocator in server.go to minimize memory pinned for many idle conns.
- // Will probably also need to make frame invalidation have a hook too.
- getReadBuf func(size uint32) []byte
- readBuf []byte // cache for default getReadBuf
-
- maxWriteSize uint32 // zero means unlimited; TODO: implement
-
- w io.Writer
- wbuf []byte
-
- // AllowIllegalWrites permits the Framer's Write methods to
- // write frames that do not conform to the HTTP/2 spec. This
- // permits using the Framer to test other HTTP/2
- // implementations' conformance to the spec.
- // If false, the Write methods will prefer to return an error
- // rather than comply.
- AllowIllegalWrites bool
-
- // AllowIllegalReads permits the Framer's ReadFrame method
- // to return non-compliant frames or frame orders.
- // This is for testing and permits using the Framer to test
- // other HTTP/2 implementations' conformance to the spec.
- // It is not compatible with ReadMetaHeaders.
- AllowIllegalReads bool
-
- // ReadMetaHeaders if non-nil causes ReadFrame to merge
- // HEADERS and CONTINUATION frames together and return
- // MetaHeadersFrame instead.
- ReadMetaHeaders *hpack.Decoder
-
- // MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE.
- // It's used only if ReadMetaHeaders is set; 0 means a sane default
- // (currently 16MB)
- // If the limit is hit, MetaHeadersFrame.Truncated is set true.
- MaxHeaderListSize uint32
-
- // TODO: track which type of frame & with which flags was sent
- // last. Then return an error (unless AllowIllegalWrites) if
- // we're in the middle of a header block and a
- // non-Continuation or Continuation on a different stream is
- // attempted to be written.
-
- logReads, logWrites bool
-
- debugFramer *http2Framer // only use for logging written writes
- debugFramerBuf *bytes.Buffer
- debugReadLoggerf func(string, ...interface{})
- debugWriteLoggerf func(string, ...interface{})
-
- frameCache *http2frameCache // nil if frames aren't reused (default)
-}
-
-func (fr *http2Framer) maxHeaderListSize() uint32 {
- if fr.MaxHeaderListSize == 0 {
- return 16 << 20 // sane default, per docs
- }
- return fr.MaxHeaderListSize
-}
-
-func (f *http2Framer) startWrite(ftype http2FrameType, flags http2Flags, streamID uint32) {
- // Write the FrameHeader.
- f.wbuf = append(f.wbuf[:0],
- 0, // 3 bytes of length, filled in in endWrite
- 0,
- 0,
- byte(ftype),
- byte(flags),
- byte(streamID>>24),
- byte(streamID>>16),
- byte(streamID>>8),
- byte(streamID))
-}
-
-func (f *http2Framer) endWrite() error {
- // Now that we know the final size, fill in the FrameHeader in
- // the space previously reserved for it. Abuse append.
- length := len(f.wbuf) - http2frameHeaderLen
- if length >= (1 << 24) {
- return http2ErrFrameTooLarge
- }
- _ = append(f.wbuf[:0],
- byte(length>>16),
- byte(length>>8),
- byte(length))
- if f.logWrites {
- f.logWrite()
- }
-
- n, err := f.w.Write(f.wbuf)
- if err == nil && n != len(f.wbuf) {
- err = io.ErrShortWrite
- }
- return err
-}
-
-func (f *http2Framer) logWrite() {
- if f.debugFramer == nil {
- f.debugFramerBuf = new(bytes.Buffer)
- f.debugFramer = http2NewFramer(nil, f.debugFramerBuf)
- f.debugFramer.logReads = false // we log it ourselves, saying "wrote" below
- // Let us read anything, even if we accidentally wrote it
- // in the wrong order:
- f.debugFramer.AllowIllegalReads = true
- }
- f.debugFramerBuf.Write(f.wbuf)
- fr, err := f.debugFramer.ReadFrame()
- if err != nil {
- f.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", f)
- return
- }
- f.debugWriteLoggerf("http2: Framer %p: wrote %v", f, http2summarizeFrame(fr))
-}
-
-func (f *http2Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) }
-
-func (f *http2Framer) writeBytes(v []byte) { f.wbuf = append(f.wbuf, v...) }
-
-func (f *http2Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }
-
-func (f *http2Framer) writeUint32(v uint32) {
- f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
-}
-
-const (
- http2minMaxFrameSize = 1 << 14
- http2maxFrameSize = 1<<24 - 1
-)
-
-// SetReuseFrames allows the Framer to reuse Frames.
-// If called on a Framer, Frames returned by calls to ReadFrame are only
-// valid until the next call to ReadFrame.
-func (fr *http2Framer) SetReuseFrames() {
- if fr.frameCache != nil {
- return
- }
- fr.frameCache = &http2frameCache{}
-}
-
-type http2frameCache struct {
- dataFrame http2DataFrame
-}
-
-func (fc *http2frameCache) getDataFrame() *http2DataFrame {
- if fc == nil {
- return &http2DataFrame{}
- }
- return &fc.dataFrame
-}
-
-// NewFramer returns a Framer that writes frames to w and reads them from r.
-func http2NewFramer(w io.Writer, r io.Reader) *http2Framer {
- fr := &http2Framer{
- w: w,
- r: r,
- countError: func(string) {},
- logReads: http2logFrameReads,
- logWrites: http2logFrameWrites,
- debugReadLoggerf: log.Printf,
- debugWriteLoggerf: log.Printf,
- }
- fr.getReadBuf = func(size uint32) []byte {
- if cap(fr.readBuf) >= int(size) {
- return fr.readBuf[:size]
- }
- fr.readBuf = make([]byte, size)
- return fr.readBuf
- }
- fr.SetMaxReadFrameSize(http2maxFrameSize)
- return fr
-}
-
-// SetMaxReadFrameSize sets the maximum size of a frame
-// that will be read by a subsequent call to ReadFrame.
-// It is the caller's responsibility to advertise this
-// limit with a SETTINGS frame.
-func (fr *http2Framer) SetMaxReadFrameSize(v uint32) {
- if v > http2maxFrameSize {
- v = http2maxFrameSize
- }
- fr.maxReadSize = v
-}
-
-// ErrorDetail returns a more detailed error of the last error
-// returned by Framer.ReadFrame. For instance, if ReadFrame
-// returns a StreamError with code PROTOCOL_ERROR, ErrorDetail
-// will say exactly what was invalid. ErrorDetail is not guaranteed
-// to return a non-nil value and like the rest of the http2 package,
-// its return value is not protected by an API compatibility promise.
-// ErrorDetail is reset after the next call to ReadFrame.
-func (fr *http2Framer) ErrorDetail() error {
- return fr.errDetail
-}
-
-// ErrFrameTooLarge is returned from Framer.ReadFrame when the peer
-// sends a frame that is larger than declared with SetMaxReadFrameSize.
-var http2ErrFrameTooLarge = errors.New("http2: frame too large")
-
-// terminalReadFrameError reports whether err is an unrecoverable
-// error from ReadFrame and no other frames should be read.
-func http2terminalReadFrameError(err error) bool {
- if _, ok := err.(http2StreamError); ok {
- return false
- }
- return err != nil
-}
-
-// ReadFrame reads a single frame. The returned Frame is only valid
-// until the next call to ReadFrame.
-//
-// If the frame is larger than previously set with SetMaxReadFrameSize, the
-// returned error is ErrFrameTooLarge. Other errors may be of type
-// ConnectionError, StreamError, or anything else from the underlying
-// reader.
-func (fr *http2Framer) ReadFrame() (http2Frame, error) {
- fr.errDetail = nil
- if fr.lastFrame != nil {
- fr.lastFrame.invalidate()
- }
- fh, err := http2readFrameHeader(fr.headerBuf[:], fr.r)
- if err != nil {
- return nil, err
- }
- if fh.Length > fr.maxReadSize {
- return nil, http2ErrFrameTooLarge
- }
- payload := fr.getReadBuf(fh.Length)
- if _, err := io.ReadFull(fr.r, payload); err != nil {
- return nil, err
- }
- f, err := http2typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload)
- if err != nil {
- if ce, ok := err.(http2connError); ok {
- return nil, fr.connError(ce.Code, ce.Reason)
- }
- return nil, err
- }
- if err := fr.checkFrameOrder(f); err != nil {
- return nil, err
- }
- if fr.logReads {
- fr.debugReadLoggerf("http2: Framer %p: read %v", fr, http2summarizeFrame(f))
- }
- if fh.Type == http2FrameHeaders && fr.ReadMetaHeaders != nil {
- return fr.readMetaFrame(f.(*http2HeadersFrame))
- }
- return f, nil
-}
-
-// connError returns ConnectionError(code) but first
-// stashes away a public reason to the caller can optionally relay it
-// to the peer before hanging up on them. This might help others debug
-// their implementations.
-func (fr *http2Framer) connError(code http2ErrCode, reason string) error {
- fr.errDetail = errors.New(reason)
- return http2ConnectionError(code)
-}
-
-// checkFrameOrder reports an error if f is an invalid frame to return
-// next from ReadFrame. Mostly it checks whether HEADERS and
-// CONTINUATION frames are contiguous.
-func (fr *http2Framer) checkFrameOrder(f http2Frame) error {
- last := fr.lastFrame
- fr.lastFrame = f
- if fr.AllowIllegalReads {
- return nil
- }
-
- fh := f.Header()
- if fr.lastHeaderStream != 0 {
- if fh.Type != http2FrameContinuation {
- return fr.connError(http2ErrCodeProtocol,
- fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d",
- fh.Type, fh.StreamID,
- last.Header().Type, fr.lastHeaderStream))
- }
- if fh.StreamID != fr.lastHeaderStream {
- return fr.connError(http2ErrCodeProtocol,
- fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d",
- fh.StreamID, fr.lastHeaderStream))
- }
- } else if fh.Type == http2FrameContinuation {
- return fr.connError(http2ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID))
- }
-
- switch fh.Type {
- case http2FrameHeaders, http2FrameContinuation:
- if fh.Flags.Has(http2FlagHeadersEndHeaders) {
- fr.lastHeaderStream = 0
- } else {
- fr.lastHeaderStream = fh.StreamID
- }
- }
-
- return nil
-}
-
-// A DataFrame conveys arbitrary, variable-length sequences of octets
-// associated with a stream.
-// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1
-type http2DataFrame struct {
- http2FrameHeader
- data []byte
-}
-
-func (f *http2DataFrame) StreamEnded() bool {
- return f.http2FrameHeader.Flags.Has(http2FlagDataEndStream)
-}
-
-// Data returns the frame's data octets, not including any padding
-// size byte or padding suffix bytes.
-// The caller must not retain the returned memory past the next
-// call to ReadFrame.
-func (f *http2DataFrame) Data() []byte {
- f.checkValid()
- return f.data
-}
-
-func http2parseDataFrame(fc *http2frameCache, fh http2FrameHeader, countError func(string), payload []byte) (http2Frame, error) {
- if fh.StreamID == 0 {
- // DATA frames MUST be associated with a stream. If a
- // DATA frame is received whose stream identifier
- // field is 0x0, the recipient MUST respond with a
- // connection error (Section 5.4.1) of type
- // PROTOCOL_ERROR.
- countError("frame_data_stream_0")
- return nil, http2connError{http2ErrCodeProtocol, "DATA frame with stream ID 0"}
- }
- f := fc.getDataFrame()
- f.http2FrameHeader = fh
-
- var padSize byte
- if fh.Flags.Has(http2FlagDataPadded) {
- var err error
- payload, padSize, err = http2readByte(payload)
- if err != nil {
- countError("frame_data_pad_byte_short")
- return nil, err
- }
- }
- if int(padSize) > len(payload) {
- // If the length of the padding is greater than the
- // length of the frame payload, the recipient MUST
- // treat this as a connection error.
- // Filed: https://github.com/http2/http2-spec/issues/610
- countError("frame_data_pad_too_big")
- return nil, http2connError{http2ErrCodeProtocol, "pad size larger than data payload"}
- }
- f.data = payload[:len(payload)-int(padSize)]
- return f, nil
-}
-
-var (
- http2errStreamID = errors.New("invalid stream ID")
- http2errDepStreamID = errors.New("invalid dependent stream ID")
- http2errPadLength = errors.New("pad length too large")
- http2errPadBytes = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled")
-)
-
-func http2validStreamIDOrZero(streamID uint32) bool {
- return streamID&(1<<31) == 0
-}
-
-func http2validStreamID(streamID uint32) bool {
- return streamID != 0 && streamID&(1<<31) == 0
-}
-
-// WriteData writes a DATA frame.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility not to violate the maximum frame size
-// and to not call other Write methods concurrently.
-func (f *http2Framer) WriteData(streamID uint32, endStream bool, data []byte) error {
- return f.WriteDataPadded(streamID, endStream, data, nil)
-}
-
-// WriteDataPadded writes a DATA frame with optional padding.
-//
-// If pad is nil, the padding bit is not sent.
-// The length of pad must not exceed 255 bytes.
-// The bytes of pad must all be zero, unless f.AllowIllegalWrites is set.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility not to violate the maximum frame size
-// and to not call other Write methods concurrently.
-func (f *http2Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
- if !http2validStreamID(streamID) && !f.AllowIllegalWrites {
- return http2errStreamID
- }
- if len(pad) > 0 {
- if len(pad) > 255 {
- return http2errPadLength
- }
- if !f.AllowIllegalWrites {
- for _, b := range pad {
- if b != 0 {
- // "Padding octets MUST be set to zero when sending."
- return http2errPadBytes
- }
- }
- }
- }
- var flags http2Flags
- if endStream {
- flags |= http2FlagDataEndStream
- }
- if pad != nil {
- flags |= http2FlagDataPadded
- }
- f.startWrite(http2FrameData, flags, streamID)
- if pad != nil {
- f.wbuf = append(f.wbuf, byte(len(pad)))
- }
- f.wbuf = append(f.wbuf, data...)
- f.wbuf = append(f.wbuf, pad...)
- return f.endWrite()
-}
-
-// A SettingsFrame conveys configuration parameters that affect how
-// endpoints communicate, such as preferences and constraints on peer
-// behavior.
-//
-// See https://httpwg.org/specs/rfc7540.html#SETTINGS
-type http2SettingsFrame struct {
- http2FrameHeader
- p []byte
-}
-
-func http2parseSettingsFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (http2Frame, error) {
- if fh.Flags.Has(http2FlagSettingsAck) && fh.Length > 0 {
- // When this (ACK 0x1) bit is set, the payload of the
- // SETTINGS frame MUST be empty. Receipt of a
- // SETTINGS frame with the ACK flag set and a length
- // field value other than 0 MUST be treated as a
- // connection error (Section 5.4.1) of type
- // FRAME_SIZE_ERROR.
- countError("frame_settings_ack_with_length")
- return nil, http2ConnectionError(http2ErrCodeFrameSize)
- }
- if fh.StreamID != 0 {
- // SETTINGS frames always apply to a connection,
- // never a single stream. The stream identifier for a
- // SETTINGS frame MUST be zero (0x0). If an endpoint
- // receives a SETTINGS frame whose stream identifier
- // field is anything other than 0x0, the endpoint MUST
- // respond with a connection error (Section 5.4.1) of
- // type PROTOCOL_ERROR.
- countError("frame_settings_has_stream")
- return nil, http2ConnectionError(http2ErrCodeProtocol)
- }
- if len(p)%6 != 0 {
- countError("frame_settings_mod_6")
- // Expecting even number of 6 byte settings.
- return nil, http2ConnectionError(http2ErrCodeFrameSize)
- }
- f := &http2SettingsFrame{http2FrameHeader: fh, p: p}
- if v, ok := f.Value(http2SettingInitialWindowSize); ok && v > (1<<31)-1 {
- countError("frame_settings_window_size_too_big")
- // Values above the maximum flow control window size of 2^31 - 1 MUST
- // be treated as a connection error (Section 5.4.1) of type
- // FLOW_CONTROL_ERROR.
- return nil, http2ConnectionError(http2ErrCodeFlowControl)
- }
- return f, nil
-}
-
-func (f *http2SettingsFrame) IsAck() bool {
- return f.http2FrameHeader.Flags.Has(http2FlagSettingsAck)
-}
-
-func (f *http2SettingsFrame) Value(id http2SettingID) (v uint32, ok bool) {
- f.checkValid()
- for i := 0; i < f.NumSettings(); i++ {
- if s := f.Setting(i); s.ID == id {
- return s.Val, true
- }
- }
- return 0, false
-}
-
-// Setting returns the setting from the frame at the given 0-based index.
-// The index must be >= 0 and less than f.NumSettings().
-func (f *http2SettingsFrame) Setting(i int) http2Setting {
- buf := f.p
- return http2Setting{
- ID: http2SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])),
- Val: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]),
- }
-}
-
-func (f *http2SettingsFrame) NumSettings() int { return len(f.p) / 6 }
-
-// HasDuplicates reports whether f contains any duplicate setting IDs.
-func (f *http2SettingsFrame) HasDuplicates() bool {
- num := f.NumSettings()
- if num == 0 {
- return false
- }
- // If it's small enough (the common case), just do the n^2
- // thing and avoid a map allocation.
- if num < 10 {
- for i := 0; i < num; i++ {
- idi := f.Setting(i).ID
- for j := i + 1; j < num; j++ {
- idj := f.Setting(j).ID
- if idi == idj {
- return true
- }
- }
- }
- return false
- }
- seen := map[http2SettingID]bool{}
- for i := 0; i < num; i++ {
- id := f.Setting(i).ID
- if seen[id] {
- return true
- }
- seen[id] = true
- }
- return false
-}
-
-// ForeachSetting runs fn for each setting.
-// It stops and returns the first error.
-func (f *http2SettingsFrame) ForeachSetting(fn func(http2Setting) error) error {
- f.checkValid()
- for i := 0; i < f.NumSettings(); i++ {
- if err := fn(f.Setting(i)); err != nil {
- return err
- }
- }
- return nil
-}
-
-// WriteSettings writes a SETTINGS frame with zero or more settings
-// specified and the ACK bit not set.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *http2Framer) WriteSettings(settings ...http2Setting) error {
- f.startWrite(http2FrameSettings, 0, 0)
- for _, s := range settings {
- f.writeUint16(uint16(s.ID))
- f.writeUint32(s.Val)
- }
- return f.endWrite()
-}
-
-// WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *http2Framer) WriteSettingsAck() error {
- f.startWrite(http2FrameSettings, http2FlagSettingsAck, 0)
- return f.endWrite()
-}
-
-// A PingFrame is a mechanism for measuring a minimal round trip time
-// from the sender, as well as determining whether an idle connection
-// is still functional.
-// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7
-type http2PingFrame struct {
- http2FrameHeader
- Data [8]byte
-}
-
-func (f *http2PingFrame) IsAck() bool { return f.Flags.Has(http2FlagPingAck) }
-
-func http2parsePingFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), payload []byte) (http2Frame, error) {
- if len(payload) != 8 {
- countError("frame_ping_length")
- return nil, http2ConnectionError(http2ErrCodeFrameSize)
- }
- if fh.StreamID != 0 {
- countError("frame_ping_has_stream")
- return nil, http2ConnectionError(http2ErrCodeProtocol)
- }
- f := &http2PingFrame{http2FrameHeader: fh}
- copy(f.Data[:], payload)
- return f, nil
-}
-
-func (f *http2Framer) WritePing(ack bool, data [8]byte) error {
- var flags http2Flags
- if ack {
- flags = http2FlagPingAck
- }
- f.startWrite(http2FramePing, flags, 0)
- f.writeBytes(data[:])
- return f.endWrite()
-}
-
-// A GoAwayFrame informs the remote peer to stop creating streams on this connection.
-// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8
-type http2GoAwayFrame struct {
- http2FrameHeader
- LastStreamID uint32
- ErrCode http2ErrCode
- debugData []byte
-}
-
-// DebugData returns any debug data in the GOAWAY frame. Its contents
-// are not defined.
-// The caller must not retain the returned memory past the next
-// call to ReadFrame.
-func (f *http2GoAwayFrame) DebugData() []byte {
- f.checkValid()
- return f.debugData
-}
-
-func http2parseGoAwayFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (http2Frame, error) {
- if fh.StreamID != 0 {
- countError("frame_goaway_has_stream")
- return nil, http2ConnectionError(http2ErrCodeProtocol)
- }
- if len(p) < 8 {
- countError("frame_goaway_short")
- return nil, http2ConnectionError(http2ErrCodeFrameSize)
- }
- return &http2GoAwayFrame{
- http2FrameHeader: fh,
- LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1),
- ErrCode: http2ErrCode(binary.BigEndian.Uint32(p[4:8])),
- debugData: p[8:],
- }, nil
-}
-
-func (f *http2Framer) WriteGoAway(maxStreamID uint32, code http2ErrCode, debugData []byte) error {
- f.startWrite(http2FrameGoAway, 0, 0)
- f.writeUint32(maxStreamID & (1<<31 - 1))
- f.writeUint32(uint32(code))
- f.writeBytes(debugData)
- return f.endWrite()
-}
-
-// An UnknownFrame is the frame type returned when the frame type is unknown
-// or no specific frame type parser exists.
-type http2UnknownFrame struct {
- http2FrameHeader
- p []byte
-}
-
-// Payload returns the frame's payload (after the header). It is not
-// valid to call this method after a subsequent call to
-// Framer.ReadFrame, nor is it valid to retain the returned slice.
-// The memory is owned by the Framer and is invalidated when the next
-// frame is read.
-func (f *http2UnknownFrame) Payload() []byte {
- f.checkValid()
- return f.p
-}
-
-func http2parseUnknownFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (http2Frame, error) {
- return &http2UnknownFrame{fh, p}, nil
-}
-
-// A WindowUpdateFrame is used to implement flow control.
-// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9
-type http2WindowUpdateFrame struct {
- http2FrameHeader
- Increment uint32 // never read with high bit set
-}
-
-func http2parseWindowUpdateFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (http2Frame, error) {
- if len(p) != 4 {
- countError("frame_windowupdate_bad_len")
- return nil, http2ConnectionError(http2ErrCodeFrameSize)
- }
- inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit
- if inc == 0 {
- // A receiver MUST treat the receipt of a
- // WINDOW_UPDATE frame with an flow control window
- // increment of 0 as a stream error (Section 5.4.2) of
- // type PROTOCOL_ERROR; errors on the connection flow
- // control window MUST be treated as a connection
- // error (Section 5.4.1).
- if fh.StreamID == 0 {
- countError("frame_windowupdate_zero_inc_conn")
- return nil, http2ConnectionError(http2ErrCodeProtocol)
- }
- countError("frame_windowupdate_zero_inc_stream")
- return nil, http2streamError(fh.StreamID, http2ErrCodeProtocol)
- }
- return &http2WindowUpdateFrame{
- http2FrameHeader: fh,
- Increment: inc,
- }, nil
-}
-
-// WriteWindowUpdate writes a WINDOW_UPDATE frame.
-// The increment value must be between 1 and 2,147,483,647, inclusive.
-// If the Stream ID is zero, the window update applies to the
-// connection as a whole.
-func (f *http2Framer) WriteWindowUpdate(streamID, incr uint32) error {
- // "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets."
- if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites {
- return errors.New("illegal window increment value")
- }
- f.startWrite(http2FrameWindowUpdate, 0, streamID)
- f.writeUint32(incr)
- return f.endWrite()
-}
-
-// A HeadersFrame is used to open a stream and additionally carries a
-// header block fragment.
-type http2HeadersFrame struct {
- http2FrameHeader
-
- // Priority is set if FlagHeadersPriority is set in the FrameHeader.
- Priority http2PriorityParam
-
- headerFragBuf []byte // not owned
-}
-
-func (f *http2HeadersFrame) HeaderBlockFragment() []byte {
- f.checkValid()
- return f.headerFragBuf
-}
-
-func (f *http2HeadersFrame) HeadersEnded() bool {
- return f.http2FrameHeader.Flags.Has(http2FlagHeadersEndHeaders)
-}
-
-func (f *http2HeadersFrame) StreamEnded() bool {
- return f.http2FrameHeader.Flags.Has(http2FlagHeadersEndStream)
-}
-
-func (f *http2HeadersFrame) HasPriority() bool {
- return f.http2FrameHeader.Flags.Has(http2FlagHeadersPriority)
-}
-
-func http2parseHeadersFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (_ http2Frame, err error) {
- hf := &http2HeadersFrame{
- http2FrameHeader: fh,
- }
- if fh.StreamID == 0 {
- // HEADERS frames MUST be associated with a stream. If a HEADERS frame
- // is received whose stream identifier field is 0x0, the recipient MUST
- // respond with a connection error (Section 5.4.1) of type
- // PROTOCOL_ERROR.
- countError("frame_headers_zero_stream")
- return nil, http2connError{http2ErrCodeProtocol, "HEADERS frame with stream ID 0"}
- }
- var padLength uint8
- if fh.Flags.Has(http2FlagHeadersPadded) {
- if p, padLength, err = http2readByte(p); err != nil {
- countError("frame_headers_pad_short")
- return
- }
- }
- if fh.Flags.Has(http2FlagHeadersPriority) {
- var v uint32
- p, v, err = http2readUint32(p)
- if err != nil {
- countError("frame_headers_prio_short")
- return nil, err
- }
- hf.Priority.StreamDep = v & 0x7fffffff
- hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set
- p, hf.Priority.Weight, err = http2readByte(p)
- if err != nil {
- countError("frame_headers_prio_weight_short")
- return nil, err
- }
- }
- if len(p)-int(padLength) < 0 {
- countError("frame_headers_pad_too_big")
- return nil, http2streamError(fh.StreamID, http2ErrCodeProtocol)
- }
- hf.headerFragBuf = p[:len(p)-int(padLength)]
- return hf, nil
-}
-
-// HeadersFrameParam are the parameters for writing a HEADERS frame.
-type http2HeadersFrameParam struct {
- // StreamID is the required Stream ID to initiate.
- StreamID uint32
- // BlockFragment is part (or all) of a Header Block.
- BlockFragment []byte
-
- // EndStream indicates that the header block is the last that
- // the endpoint will send for the identified stream. Setting
- // this flag causes the stream to enter one of "half closed"
- // states.
- EndStream bool
-
- // EndHeaders indicates that this frame contains an entire
- // header block and is not followed by any
- // CONTINUATION frames.
- EndHeaders bool
-
- // PadLength is the optional number of bytes of zeros to add
- // to this frame.
- PadLength uint8
-
- // Priority, if non-zero, includes stream priority information
- // in the HEADER frame.
- Priority http2PriorityParam
-}
-
-// WriteHeaders writes a single HEADERS frame.
-//
-// This is a low-level header writing method. Encoding headers and
-// splitting them into any necessary CONTINUATION frames is handled
-// elsewhere.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *http2Framer) WriteHeaders(p http2HeadersFrameParam) error {
- if !http2validStreamID(p.StreamID) && !f.AllowIllegalWrites {
- return http2errStreamID
- }
- var flags http2Flags
- if p.PadLength != 0 {
- flags |= http2FlagHeadersPadded
- }
- if p.EndStream {
- flags |= http2FlagHeadersEndStream
- }
- if p.EndHeaders {
- flags |= http2FlagHeadersEndHeaders
- }
- if !p.Priority.IsZero() {
- flags |= http2FlagHeadersPriority
- }
- f.startWrite(http2FrameHeaders, flags, p.StreamID)
- if p.PadLength != 0 {
- f.writeByte(p.PadLength)
- }
- if !p.Priority.IsZero() {
- v := p.Priority.StreamDep
- if !http2validStreamIDOrZero(v) && !f.AllowIllegalWrites {
- return http2errDepStreamID
- }
- if p.Priority.Exclusive {
- v |= 1 << 31
- }
- f.writeUint32(v)
- f.writeByte(p.Priority.Weight)
- }
- f.wbuf = append(f.wbuf, p.BlockFragment...)
- f.wbuf = append(f.wbuf, http2padZeros[:p.PadLength]...)
- return f.endWrite()
-}
-
-// A PriorityFrame specifies the sender-advised priority of a stream.
-// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3
-type http2PriorityFrame struct {
- http2FrameHeader
- http2PriorityParam
-}
-
-// PriorityParam are the stream prioritzation parameters.
-type http2PriorityParam struct {
- // StreamDep is a 31-bit stream identifier for the
- // stream that this stream depends on. Zero means no
- // dependency.
- StreamDep uint32
-
- // Exclusive is whether the dependency is exclusive.
- Exclusive bool
-
- // Weight is the stream's zero-indexed weight. It should be
- // set together with StreamDep, or neither should be set. Per
- // the spec, "Add one to the value to obtain a weight between
- // 1 and 256."
- Weight uint8
-}
-
-func (p http2PriorityParam) IsZero() bool {
- return p == http2PriorityParam{}
-}
-
-func http2parsePriorityFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), payload []byte) (http2Frame, error) {
- if fh.StreamID == 0 {
- countError("frame_priority_zero_stream")
- return nil, http2connError{http2ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
- }
- if len(payload) != 5 {
- countError("frame_priority_bad_length")
- return nil, http2connError{http2ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
- }
- v := binary.BigEndian.Uint32(payload[:4])
- streamID := v & 0x7fffffff // mask off high bit
- return &http2PriorityFrame{
- http2FrameHeader: fh,
- http2PriorityParam: http2PriorityParam{
- Weight: payload[4],
- StreamDep: streamID,
- Exclusive: streamID != v, // was high bit set?
- },
- }, nil
-}
-
-// WritePriority writes a PRIORITY frame.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *http2Framer) WritePriority(streamID uint32, p http2PriorityParam) error {
- if !http2validStreamID(streamID) && !f.AllowIllegalWrites {
- return http2errStreamID
- }
- if !http2validStreamIDOrZero(p.StreamDep) {
- return http2errDepStreamID
- }
- f.startWrite(http2FramePriority, 0, streamID)
- v := p.StreamDep
- if p.Exclusive {
- v |= 1 << 31
- }
- f.writeUint32(v)
- f.writeByte(p.Weight)
- return f.endWrite()
-}
-
-// A RSTStreamFrame allows for abnormal termination of a stream.
-// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4
-type http2RSTStreamFrame struct {
- http2FrameHeader
- ErrCode http2ErrCode
-}
-
-func http2parseRSTStreamFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (http2Frame, error) {
- if len(p) != 4 {
- countError("frame_rststream_bad_len")
- return nil, http2ConnectionError(http2ErrCodeFrameSize)
- }
- if fh.StreamID == 0 {
- countError("frame_rststream_zero_stream")
- return nil, http2ConnectionError(http2ErrCodeProtocol)
- }
- return &http2RSTStreamFrame{fh, http2ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
-}
-
-// WriteRSTStream writes a RST_STREAM frame.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *http2Framer) WriteRSTStream(streamID uint32, code http2ErrCode) error {
- if !http2validStreamID(streamID) && !f.AllowIllegalWrites {
- return http2errStreamID
- }
- f.startWrite(http2FrameRSTStream, 0, streamID)
- f.writeUint32(uint32(code))
- return f.endWrite()
-}
-
-// A ContinuationFrame is used to continue a sequence of header block fragments.
-// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10
-type http2ContinuationFrame struct {
- http2FrameHeader
- headerFragBuf []byte
-}
-
-func http2parseContinuationFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (http2Frame, error) {
- if fh.StreamID == 0 {
- countError("frame_continuation_zero_stream")
- return nil, http2connError{http2ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
- }
- return &http2ContinuationFrame{fh, p}, nil
-}
-
-func (f *http2ContinuationFrame) HeaderBlockFragment() []byte {
- f.checkValid()
- return f.headerFragBuf
-}
-
-func (f *http2ContinuationFrame) HeadersEnded() bool {
- return f.http2FrameHeader.Flags.Has(http2FlagContinuationEndHeaders)
-}
-
-// WriteContinuation writes a CONTINUATION frame.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *http2Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error {
- if !http2validStreamID(streamID) && !f.AllowIllegalWrites {
- return http2errStreamID
- }
- var flags http2Flags
- if endHeaders {
- flags |= http2FlagContinuationEndHeaders
- }
- f.startWrite(http2FrameContinuation, flags, streamID)
- f.wbuf = append(f.wbuf, headerBlockFragment...)
- return f.endWrite()
-}
-
-// A PushPromiseFrame is used to initiate a server stream.
-// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6
-type http2PushPromiseFrame struct {
- http2FrameHeader
- PromiseID uint32
- headerFragBuf []byte // not owned
-}
-
-func (f *http2PushPromiseFrame) HeaderBlockFragment() []byte {
- f.checkValid()
- return f.headerFragBuf
-}
-
-func (f *http2PushPromiseFrame) HeadersEnded() bool {
- return f.http2FrameHeader.Flags.Has(http2FlagPushPromiseEndHeaders)
-}
-
-func http2parsePushPromise(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (_ http2Frame, err error) {
- pp := &http2PushPromiseFrame{
- http2FrameHeader: fh,
- }
- if pp.StreamID == 0 {
- // PUSH_PROMISE frames MUST be associated with an existing,
- // peer-initiated stream. The stream identifier of a
- // PUSH_PROMISE frame indicates the stream it is associated
- // with. If the stream identifier field specifies the value
- // 0x0, a recipient MUST respond with a connection error
- // (Section 5.4.1) of type PROTOCOL_ERROR.
- countError("frame_pushpromise_zero_stream")
- return nil, http2ConnectionError(http2ErrCodeProtocol)
- }
- // The PUSH_PROMISE frame includes optional padding.
- // Padding fields and flags are identical to those defined for DATA frames
- var padLength uint8
- if fh.Flags.Has(http2FlagPushPromisePadded) {
- if p, padLength, err = http2readByte(p); err != nil {
- countError("frame_pushpromise_pad_short")
- return
- }
- }
-
- p, pp.PromiseID, err = http2readUint32(p)
- if err != nil {
- countError("frame_pushpromise_promiseid_short")
- return
- }
- pp.PromiseID = pp.PromiseID & (1<<31 - 1)
-
- if int(padLength) > len(p) {
- // like the DATA frame, error out if padding is longer than the body.
- countError("frame_pushpromise_pad_too_big")
- return nil, http2ConnectionError(http2ErrCodeProtocol)
- }
- pp.headerFragBuf = p[:len(p)-int(padLength)]
- return pp, nil
-}
-
-// PushPromiseParam are the parameters for writing a PUSH_PROMISE frame.
-type http2PushPromiseParam struct {
- // StreamID is the required Stream ID to initiate.
- StreamID uint32
-
- // PromiseID is the required Stream ID which this
- // Push Promises
- PromiseID uint32
-
- // BlockFragment is part (or all) of a Header Block.
- BlockFragment []byte
-
- // EndHeaders indicates that this frame contains an entire
- // header block and is not followed by any
- // CONTINUATION frames.
- EndHeaders bool
-
- // PadLength is the optional number of bytes of zeros to add
- // to this frame.
- PadLength uint8
-}
-
-// WritePushPromise writes a single PushPromise Frame.
-//
-// As with Header Frames, This is the low level call for writing
-// individual frames. Continuation frames are handled elsewhere.
-//
-// It will perform exactly one Write to the underlying Writer.
-// It is the caller's responsibility to not call other Write methods concurrently.
-func (f *http2Framer) WritePushPromise(p http2PushPromiseParam) error {
- if !http2validStreamID(p.StreamID) && !f.AllowIllegalWrites {
- return http2errStreamID
- }
- var flags http2Flags
- if p.PadLength != 0 {
- flags |= http2FlagPushPromisePadded
- }
- if p.EndHeaders {
- flags |= http2FlagPushPromiseEndHeaders
- }
- f.startWrite(http2FramePushPromise, flags, p.StreamID)
- if p.PadLength != 0 {
- f.writeByte(p.PadLength)
- }
- if !http2validStreamID(p.PromiseID) && !f.AllowIllegalWrites {
- return http2errStreamID
- }
- f.writeUint32(p.PromiseID)
- f.wbuf = append(f.wbuf, p.BlockFragment...)
- f.wbuf = append(f.wbuf, http2padZeros[:p.PadLength]...)
- return f.endWrite()
-}
-
-// WriteRawFrame writes a raw frame. This can be used to write
-// extension frames unknown to this package.
-func (f *http2Framer) WriteRawFrame(t http2FrameType, flags http2Flags, streamID uint32, payload []byte) error {
- f.startWrite(t, flags, streamID)
- f.writeBytes(payload)
- return f.endWrite()
-}
-
-func http2readByte(p []byte) (remain []byte, b byte, err error) {
- if len(p) == 0 {
- return nil, 0, io.ErrUnexpectedEOF
- }
- return p[1:], p[0], nil
-}
-
-func http2readUint32(p []byte) (remain []byte, v uint32, err error) {
- if len(p) < 4 {
- return nil, 0, io.ErrUnexpectedEOF
- }
- return p[4:], binary.BigEndian.Uint32(p[:4]), nil
-}
-
-type http2streamEnder interface {
- StreamEnded() bool
-}
-
-type http2headersEnder interface {
- HeadersEnded() bool
-}
-
-type http2headersOrContinuation interface {
- http2headersEnder
- HeaderBlockFragment() []byte
-}
-
-// A MetaHeadersFrame is the representation of one HEADERS frame and
-// zero or more contiguous CONTINUATION frames and the decoding of
-// their HPACK-encoded contents.
-//
-// This type of frame does not appear on the wire and is only returned
-// by the Framer when Framer.ReadMetaHeaders is set.
-type http2MetaHeadersFrame struct {
- *http2HeadersFrame
-
- // Fields are the fields contained in the HEADERS and
- // CONTINUATION frames. The underlying slice is owned by the
- // Framer and must not be retained after the next call to
- // ReadFrame.
- //
- // Fields are guaranteed to be in the correct http2 order and
- // not have unknown pseudo header fields or invalid header
- // field names or values. Required pseudo header fields may be
- // missing, however. Use the MetaHeadersFrame.Pseudo accessor
- // method access pseudo headers.
- Fields []hpack.HeaderField
-
- // Truncated is whether the max header list size limit was hit
- // and Fields is incomplete. The hpack decoder state is still
- // valid, however.
- Truncated bool
-}
-
-// PseudoValue returns the given pseudo header field's value.
-// The provided pseudo field should not contain the leading colon.
-func (mh *http2MetaHeadersFrame) PseudoValue(pseudo string) string {
- for _, hf := range mh.Fields {
- if !hf.IsPseudo() {
- return ""
- }
- if hf.Name[1:] == pseudo {
- return hf.Value
- }
- }
- return ""
-}
-
-// RegularFields returns the regular (non-pseudo) header fields of mh.
-// The caller does not own the returned slice.
-func (mh *http2MetaHeadersFrame) RegularFields() []hpack.HeaderField {
- for i, hf := range mh.Fields {
- if !hf.IsPseudo() {
- return mh.Fields[i:]
- }
- }
- return nil
-}
-
-// PseudoFields returns the pseudo header fields of mh.
-// The caller does not own the returned slice.
-func (mh *http2MetaHeadersFrame) PseudoFields() []hpack.HeaderField {
- for i, hf := range mh.Fields {
- if !hf.IsPseudo() {
- return mh.Fields[:i]
- }
- }
- return mh.Fields
-}
-
-func (mh *http2MetaHeadersFrame) checkPseudos() error {
- var isRequest, isResponse bool
- pf := mh.PseudoFields()
- for i, hf := range pf {
- switch hf.Name {
- case ":method", ":path", ":scheme", ":authority":
- isRequest = true
- case ":status":
- isResponse = true
- default:
- return http2pseudoHeaderError(hf.Name)
- }
- // Check for duplicates.
- // This would be a bad algorithm, but N is 4.
- // And this doesn't allocate.
- for _, hf2 := range pf[:i] {
- if hf.Name == hf2.Name {
- return http2duplicatePseudoHeaderError(hf.Name)
- }
- }
- }
- if isRequest && isResponse {
- return http2errMixPseudoHeaderTypes
- }
- return nil
-}
-
-func (fr *http2Framer) maxHeaderStringLen() int {
- v := fr.maxHeaderListSize()
- if uint32(int(v)) == v {
- return int(v)
- }
- // They had a crazy big number for MaxHeaderBytes anyway,
- // so give them unlimited header lengths:
- return 0
-}
-
-// readMetaFrame returns 0 or more CONTINUATION frames from fr and
-// merge them into the provided hf and returns a MetaHeadersFrame
-// with the decoded hpack values.
-func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFrame, error) {
- if fr.AllowIllegalReads {
- return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders")
- }
- mh := &http2MetaHeadersFrame{
- http2HeadersFrame: hf,
- }
- var remainSize = fr.maxHeaderListSize()
- var sawRegular bool
-
- var invalid error // pseudo header field errors
- hdec := fr.ReadMetaHeaders
- hdec.SetEmitEnabled(true)
- hdec.SetMaxStringLength(fr.maxHeaderStringLen())
- hdec.SetEmitFunc(func(hf hpack.HeaderField) {
- if http2VerboseLogs && fr.logReads {
- fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
- }
- if !httpguts.ValidHeaderFieldValue(hf.Value) {
- // Don't include the value in the error, because it may be sensitive.
- invalid = http2headerFieldValueError(hf.Name)
- }
- isPseudo := strings.HasPrefix(hf.Name, ":")
- if isPseudo {
- if sawRegular {
- invalid = http2errPseudoAfterRegular
- }
- } else {
- sawRegular = true
- if !http2validWireHeaderFieldName(hf.Name) {
- invalid = http2headerFieldNameError(hf.Name)
- }
- }
-
- if invalid != nil {
- hdec.SetEmitEnabled(false)
- return
- }
-
- size := hf.Size()
- if size > remainSize {
- hdec.SetEmitEnabled(false)
- mh.Truncated = true
- return
- }
- remainSize -= size
-
- mh.Fields = append(mh.Fields, hf)
- })
- // Lose reference to MetaHeadersFrame:
- defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {})
-
- var hc http2headersOrContinuation = hf
- for {
- frag := hc.HeaderBlockFragment()
- if _, err := hdec.Write(frag); err != nil {
- return nil, http2ConnectionError(http2ErrCodeCompression)
- }
-
- if hc.HeadersEnded() {
- break
- }
- if f, err := fr.ReadFrame(); err != nil {
- return nil, err
- } else {
- hc = f.(*http2ContinuationFrame) // guaranteed by checkFrameOrder
- }
- }
-
- mh.http2HeadersFrame.headerFragBuf = nil
- mh.http2HeadersFrame.invalidate()
-
- if err := hdec.Close(); err != nil {
- return nil, http2ConnectionError(http2ErrCodeCompression)
- }
- if invalid != nil {
- fr.errDetail = invalid
- if http2VerboseLogs {
- log.Printf("http2: invalid header: %v", invalid)
- }
- return nil, http2StreamError{mh.StreamID, http2ErrCodeProtocol, invalid}
- }
- if err := mh.checkPseudos(); err != nil {
- fr.errDetail = err
- if http2VerboseLogs {
- log.Printf("http2: invalid pseudo headers: %v", err)
- }
- return nil, http2StreamError{mh.StreamID, http2ErrCodeProtocol, err}
- }
- return mh, nil
-}
-
-func http2summarizeFrame(f http2Frame) string {
- var buf bytes.Buffer
- f.Header().writeDebug(&buf)
- switch f := f.(type) {
- case *http2SettingsFrame:
- n := 0
- f.ForeachSetting(func(s http2Setting) error {
- n++
- if n == 1 {
- buf.WriteString(", settings:")
- }
- fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val)
- return nil
- })
- if n > 0 {
- buf.Truncate(buf.Len() - 1) // remove trailing comma
- }
- case *http2DataFrame:
- data := f.Data()
- const max = 256
- if len(data) > max {
- data = data[:max]
- }
- fmt.Fprintf(&buf, " data=%q", data)
- if len(f.Data()) > max {
- fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max)
- }
- case *http2WindowUpdateFrame:
- if f.StreamID == 0 {
- buf.WriteString(" (conn)")
- }
- fmt.Fprintf(&buf, " incr=%v", f.Increment)
- case *http2PingFrame:
- fmt.Fprintf(&buf, " ping=%q", f.Data[:])
- case *http2GoAwayFrame:
- fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q",
- f.LastStreamID, f.ErrCode, f.debugData)
- case *http2RSTStreamFrame:
- fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode)
- }
- return buf.String()
-}
-
-func http2traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool {
- return trace != nil && trace.WroteHeaderField != nil
-}
-
-func http2traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) {
- if trace != nil && trace.WroteHeaderField != nil {
- trace.WroteHeaderField(k, []string{v})
- }
-}
-
-func http2traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error {
- if trace != nil {
- return trace.Got1xxResponse
- }
- return nil
-}
-
-// dialTLSWithContext uses tls.Dialer, added in Go 1.15, to open a TLS
-// connection.
-func (t *http2Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) {
- dialer := &tls.Dialer{
- Config: cfg,
- }
- cn, err := dialer.DialContext(ctx, network, addr)
- if err != nil {
- return nil, err
- }
- tlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed
- return tlsCn, nil
-}
-
-func http2tlsUnderlyingConn(tc *tls.Conn) net.Conn {
- return tc.NetConn()
-}
-
-var http2DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
-
-type http2goroutineLock uint64
-
-func http2newGoroutineLock() http2goroutineLock {
- if !http2DebugGoroutines {
- return 0
- }
- return http2goroutineLock(http2curGoroutineID())
-}
-
-func (g http2goroutineLock) check() {
- if !http2DebugGoroutines {
- return
- }
- if http2curGoroutineID() != uint64(g) {
- panic("running on the wrong goroutine")
- }
-}
-
-func (g http2goroutineLock) checkNotOn() {
- if !http2DebugGoroutines {
- return
- }
- if http2curGoroutineID() == uint64(g) {
- panic("running on the wrong goroutine")
- }
-}
-
-var http2goroutineSpace = []byte("goroutine ")
-
-func http2curGoroutineID() uint64 {
- bp := http2littleBuf.Get().(*[]byte)
- defer http2littleBuf.Put(bp)
- b := *bp
- b = b[:runtime.Stack(b, false)]
- // Parse the 4707 out of "goroutine 4707 ["
- b = bytes.TrimPrefix(b, http2goroutineSpace)
- i := bytes.IndexByte(b, ' ')
- if i < 0 {
- panic(fmt.Sprintf("No space found in %q", b))
- }
- b = b[:i]
- n, err := http2parseUintBytes(b, 10, 64)
- if err != nil {
- panic(fmt.Sprintf("Failed to parse goroutine ID out of %q: %v", b, err))
- }
- return n
-}
-
-var http2littleBuf = sync.Pool{
- New: func() interface{} {
- buf := make([]byte, 64)
- return &buf
- },
-}
-
-// parseUintBytes is like strconv.ParseUint, but using a []byte.
-func http2parseUintBytes(s []byte, base int, bitSize int) (n uint64, err error) {
- var cutoff, maxVal uint64
-
- if bitSize == 0 {
- bitSize = int(strconv.IntSize)
- }
-
- s0 := s
- switch {
- case len(s) < 1:
- err = strconv.ErrSyntax
- goto Error
-
- case 2 <= base && base <= 36:
- // valid base; nothing to do
-
- case base == 0:
- // Look for octal, hex prefix.
- switch {
- case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
- base = 16
- s = s[2:]
- if len(s) < 1 {
- err = strconv.ErrSyntax
- goto Error
- }
- case s[0] == '0':
- base = 8
- default:
- base = 10
- }
-
- default:
- err = errors.New("invalid base " + strconv.Itoa(base))
- goto Error
- }
-
- n = 0
- cutoff = http2cutoff64(base)
- maxVal = 1<<uint(bitSize) - 1
-
- for i := 0; i < len(s); i++ {
- var v byte
- d := s[i]
- switch {
- case '0' <= d && d <= '9':
- v = d - '0'
- case 'a' <= d && d <= 'z':
- v = d - 'a' + 10
- case 'A' <= d && d <= 'Z':
- v = d - 'A' + 10
- default:
- n = 0
- err = strconv.ErrSyntax
- goto Error
- }
- if int(v) >= base {
- n = 0
- err = strconv.ErrSyntax
- goto Error
- }
-
- if n >= cutoff {
- // n*base overflows
- n = 1<<64 - 1
- err = strconv.ErrRange
- goto Error
- }
- n *= uint64(base)
-
- n1 := n + uint64(v)
- if n1 < n || n1 > maxVal {
- // n+v overflows
- n = 1<<64 - 1
- err = strconv.ErrRange
- goto Error
- }
- n = n1
- }
-
- return n, nil
-
-Error:
- return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
-}
-
-// Return the first number n such that n*base >= 1<<64.
-func http2cutoff64(base int) uint64 {
- if base < 2 {
- return 0
- }
- return (1<<64-1)/uint64(base) + 1
-}
-
-var (
- http2commonBuildOnce sync.Once
- http2commonLowerHeader map[string]string // Go-Canonical-Case -> lower-case
- http2commonCanonHeader map[string]string // lower-case -> Go-Canonical-Case
-)
-
-func http2buildCommonHeaderMapsOnce() {
- http2commonBuildOnce.Do(http2buildCommonHeaderMaps)
-}
-
-func http2buildCommonHeaderMaps() {
- common := []string{
- "accept",
- "accept-charset",
- "accept-encoding",
- "accept-language",
- "accept-ranges",
- "age",
- "access-control-allow-credentials",
- "access-control-allow-headers",
- "access-control-allow-methods",
- "access-control-allow-origin",
- "access-control-expose-headers",
- "access-control-max-age",
- "access-control-request-headers",
- "access-control-request-method",
- "allow",
- "authorization",
- "cache-control",
- "content-disposition",
- "content-encoding",
- "content-language",
- "content-length",
- "content-location",
- "content-range",
- "content-type",
- "cookie",
- "date",
- "etag",
- "expect",
- "expires",
- "from",
- "host",
- "if-match",
- "if-modified-since",
- "if-none-match",
- "if-unmodified-since",
- "last-modified",
- "link",
- "location",
- "max-forwards",
- "origin",
- "proxy-authenticate",
- "proxy-authorization",
- "range",
- "referer",
- "refresh",
- "retry-after",
- "server",
- "set-cookie",
- "strict-transport-security",
- "trailer",
- "transfer-encoding",
- "user-agent",
- "vary",
- "via",
- "www-authenticate",
- "x-forwarded-for",
- "x-forwarded-proto",
- }
- http2commonLowerHeader = make(map[string]string, len(common))
- http2commonCanonHeader = make(map[string]string, len(common))
- for _, v := range common {
- chk := CanonicalHeaderKey(v)
- http2commonLowerHeader[chk] = v
- http2commonCanonHeader[v] = chk
- }
-}
-
-func http2lowerHeader(v string) (lower string, ascii bool) {
- http2buildCommonHeaderMapsOnce()
- if s, ok := http2commonLowerHeader[v]; ok {
- return s, true
- }
- return http2asciiToLower(v)
-}
-
-func http2canonicalHeader(v string) string {
- http2buildCommonHeaderMapsOnce()
- if s, ok := http2commonCanonHeader[v]; ok {
- return s
- }
- return CanonicalHeaderKey(v)
-}
-
-var (
- http2VerboseLogs bool
- http2logFrameWrites bool
- http2logFrameReads bool
- http2inTests bool
-)
-
-func init() {
- e := os.Getenv("GODEBUG")
- if strings.Contains(e, "http2debug=1") {
- http2VerboseLogs = true
- }
- if strings.Contains(e, "http2debug=2") {
- http2VerboseLogs = true
- http2logFrameWrites = true
- http2logFrameReads = true
- }
-}
-
-const (
- // ClientPreface is the string that must be sent by new
- // connections from clients.
- http2ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
-
- // SETTINGS_MAX_FRAME_SIZE default
- // https://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2
- http2initialMaxFrameSize = 16384
-
- // NextProtoTLS is the NPN/ALPN protocol negotiated during
- // HTTP/2's TLS setup.
- http2NextProtoTLS = "h2"
-
- // https://httpwg.org/specs/rfc7540.html#SettingValues
- http2initialHeaderTableSize = 4096
-
- http2initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size
-
- http2defaultMaxReadFrameSize = 1 << 20
-)
-
-var (
- http2clientPreface = []byte(http2ClientPreface)
-)
-
-type http2streamState int
-
-// HTTP/2 stream states.
-//
-// See http://tools.ietf.org/html/rfc7540#section-5.1.
-//
-// For simplicity, the server code merges "reserved (local)" into
-// "half-closed (remote)". This is one less state transition to track.
-// The only downside is that we send PUSH_PROMISEs slightly less
-// liberally than allowable. More discussion here:
-// https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0599.html
-//
-// "reserved (remote)" is omitted since the client code does not
-// support server push.
-const (
- http2stateIdle http2streamState = iota
- http2stateOpen
- http2stateHalfClosedLocal
- http2stateHalfClosedRemote
- http2stateClosed
-)
-
-var http2stateName = [...]string{
- http2stateIdle: "Idle",
- http2stateOpen: "Open",
- http2stateHalfClosedLocal: "HalfClosedLocal",
- http2stateHalfClosedRemote: "HalfClosedRemote",
- http2stateClosed: "Closed",
-}
-
-func (st http2streamState) String() string {
- return http2stateName[st]
-}
-
-// Setting is a setting parameter: which setting it is, and its value.
-type http2Setting struct {
- // ID is which setting is being set.
- // See https://httpwg.org/specs/rfc7540.html#SettingFormat
- ID http2SettingID
-
- // Val is the value.
- Val uint32
-}
-
-func (s http2Setting) String() string {
- return fmt.Sprintf("[%v = %d]", s.ID, s.Val)
-}
-
-// Valid reports whether the setting is valid.
-func (s http2Setting) Valid() error {
- // Limits and error codes from 6.5.2 Defined SETTINGS Parameters
- switch s.ID {
- case http2SettingEnablePush:
- if s.Val != 1 && s.Val != 0 {
- return http2ConnectionError(http2ErrCodeProtocol)
- }
- case http2SettingInitialWindowSize:
- if s.Val > 1<<31-1 {
- return http2ConnectionError(http2ErrCodeFlowControl)
- }
- case http2SettingMaxFrameSize:
- if s.Val < 16384 || s.Val > 1<<24-1 {
- return http2ConnectionError(http2ErrCodeProtocol)
- }
- }
- return nil
-}
-
-// A SettingID is an HTTP/2 setting as defined in
-// https://httpwg.org/specs/rfc7540.html#iana-settings
-type http2SettingID uint16
-
-const (
- http2SettingHeaderTableSize http2SettingID = 0x1
- http2SettingEnablePush http2SettingID = 0x2
- http2SettingMaxConcurrentStreams http2SettingID = 0x3
- http2SettingInitialWindowSize http2SettingID = 0x4
- http2SettingMaxFrameSize http2SettingID = 0x5
- http2SettingMaxHeaderListSize http2SettingID = 0x6
-)
-
-var http2settingName = map[http2SettingID]string{
- http2SettingHeaderTableSize: "HEADER_TABLE_SIZE",
- http2SettingEnablePush: "ENABLE_PUSH",
- http2SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS",
- http2SettingInitialWindowSize: "INITIAL_WINDOW_SIZE",
- http2SettingMaxFrameSize: "MAX_FRAME_SIZE",
- http2SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
-}
-
-func (s http2SettingID) String() string {
- if v, ok := http2settingName[s]; ok {
- return v
- }
- return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s))
-}
-
-// validWireHeaderFieldName reports whether v is a valid header field
-// name (key). See httpguts.ValidHeaderName for the base rules.
-//
-// Further, http2 says:
-//
-// "Just as in HTTP/1.x, header field names are strings of ASCII
-// characters that are compared in a case-insensitive
-// fashion. However, header field names MUST be converted to
-// lowercase prior to their encoding in HTTP/2. "
-func http2validWireHeaderFieldName(v string) bool {
- if len(v) == 0 {
- return false
- }
- for _, r := range v {
- if !httpguts.IsTokenRune(r) {
- return false
- }
- if 'A' <= r && r <= 'Z' {
- return false
- }
- }
- return true
-}
-
-func http2httpCodeString(code int) string {
- switch code {
- case 200:
- return "200"
- case 404:
- return "404"
- }
- return strconv.Itoa(code)
-}
-
-// from pkg io
-type http2stringWriter interface {
- WriteString(s string) (n int, err error)
-}
-
-// A gate lets two goroutines coordinate their activities.
-type http2gate chan struct{}
-
-func (g http2gate) Done() { g <- struct{}{} }
-
-func (g http2gate) Wait() { <-g }
-
-// A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).
-type http2closeWaiter chan struct{}
-
-// Init makes a closeWaiter usable.
-// It exists because so a closeWaiter value can be placed inside a
-// larger struct and have the Mutex and Cond's memory in the same
-// allocation.
-func (cw *http2closeWaiter) Init() {
- *cw = make(chan struct{})
-}
-
-// Close marks the closeWaiter as closed and unblocks any waiters.
-func (cw http2closeWaiter) Close() {
- close(cw)
-}
-
-// Wait waits for the closeWaiter to become closed.
-func (cw http2closeWaiter) Wait() {
- <-cw
-}
-
-// bufferedWriter is a buffered writer that writes to w.
-// Its buffered writer is lazily allocated as needed, to minimize
-// idle memory usage with many connections.
-type http2bufferedWriter struct {
- _ http2incomparable
- w io.Writer // immutable
- bw *bufio.Writer // non-nil when data is buffered
-}
-
-func http2newBufferedWriter(w io.Writer) *http2bufferedWriter {
- return &http2bufferedWriter{w: w}
-}
-
-// bufWriterPoolBufferSize is the size of bufio.Writer's
-// buffers created using bufWriterPool.
-//
-// TODO: pick a less arbitrary value? this is a bit under
-// (3 x typical 1500 byte MTU) at least. Other than that,
-// not much thought went into it.
-const http2bufWriterPoolBufferSize = 4 << 10
-
-var http2bufWriterPool = sync.Pool{
- New: func() interface{} {
- return bufio.NewWriterSize(nil, http2bufWriterPoolBufferSize)
- },
-}
-
-func (w *http2bufferedWriter) Available() int {
- if w.bw == nil {
- return http2bufWriterPoolBufferSize
- }
- return w.bw.Available()
-}
-
-func (w *http2bufferedWriter) Write(p []byte) (n int, err error) {
- if w.bw == nil {
- bw := http2bufWriterPool.Get().(*bufio.Writer)
- bw.Reset(w.w)
- w.bw = bw
- }
- return w.bw.Write(p)
-}
-
-func (w *http2bufferedWriter) Flush() error {
- bw := w.bw
- if bw == nil {
- return nil
- }
- err := bw.Flush()
- bw.Reset(nil)
- http2bufWriterPool.Put(bw)
- w.bw = nil
- return err
-}
-
-func http2mustUint31(v int32) uint32 {
- if v < 0 || v > 2147483647 {
- panic("out of range")
- }
- return uint32(v)
-}
-
-// bodyAllowedForStatus reports whether a given response status code
-// permits a body. See RFC 7230, section 3.3.
-func http2bodyAllowedForStatus(status int) bool {
- switch {
- case status >= 100 && status <= 199:
- return false
- case status == 204:
- return false
- case status == 304:
- return false
- }
- return true
-}
-
-type http2httpError struct {
- _ http2incomparable
- msg string
- timeout bool
-}
-
-func (e *http2httpError) Error() string { return e.msg }
-
-func (e *http2httpError) Timeout() bool { return e.timeout }
-
-func (e *http2httpError) Temporary() bool { return true }
-
-var http2errTimeout error = &http2httpError{msg: "http2: timeout awaiting response headers", timeout: true}
-
-type http2connectionStater interface {
- ConnectionState() tls.ConnectionState
-}
-
-var http2sorterPool = sync.Pool{New: func() interface{} { return new(http2sorter) }}
-
-type http2sorter struct {
- v []string // owned by sorter
-}
-
-func (s *http2sorter) Len() int { return len(s.v) }
-
-func (s *http2sorter) Swap(i, j int) { s.v[i], s.v[j] = s.v[j], s.v[i] }
-
-func (s *http2sorter) Less(i, j int) bool { return s.v[i] < s.v[j] }
-
-// Keys returns the sorted keys of h.
-//
-// The returned slice is only valid until s used again or returned to
-// its pool.
-func (s *http2sorter) Keys(h Header) []string {
- keys := s.v[:0]
- for k := range h {
- keys = append(keys, k)
- }
- s.v = keys
- sort.Sort(s)
- return keys
-}
-
-func (s *http2sorter) SortStrings(ss []string) {
- // Our sorter works on s.v, which sorter owns, so
- // stash it away while we sort the user's buffer.
- save := s.v
- s.v = ss
- sort.Sort(s)
- s.v = save
-}
-
-// validPseudoPath reports whether v is a valid :path pseudo-header
-// value. It must be either:
-//
-// - a non-empty string starting with '/'
-// - the string '*', for OPTIONS requests.
-//
-// For now this is only used a quick check for deciding when to clean
-// up Opaque URLs before sending requests from the Transport.
-// See golang.org/issue/16847
-//
-// We used to enforce that the path also didn't start with "//", but
-// Google's GFE accepts such paths and Chrome sends them, so ignore
-// that part of the spec. See golang.org/issue/19103.
-func http2validPseudoPath(v string) bool {
- return (len(v) > 0 && v[0] == '/') || v == "*"
-}
-
-// incomparable is a zero-width, non-comparable type. Adding it to a struct
-// makes that struct also non-comparable, and generally doesn't add
-// any size (as long as it's first).
-type http2incomparable [0]func()
-
-// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like
-// io.Pipe except there are no PipeReader/PipeWriter halves, and the
-// underlying buffer is an interface. (io.Pipe is always unbuffered)
-type http2pipe struct {
- mu sync.Mutex
- c sync.Cond // c.L lazily initialized to &p.mu
- b http2pipeBuffer // nil when done reading
- unread int // bytes unread when done
- err error // read error once empty. non-nil means closed.
- breakErr error // immediate read error (caller doesn't see rest of b)
- donec chan struct{} // closed on error
- readFn func() // optional code to run in Read before error
-}
-
-type http2pipeBuffer interface {
- Len() int
- io.Writer
- io.Reader
-}
-
-// setBuffer initializes the pipe buffer.
-// It has no effect if the pipe is already closed.
-func (p *http2pipe) setBuffer(b http2pipeBuffer) {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.err != nil || p.breakErr != nil {
- return
- }
- p.b = b
-}
-
-func (p *http2pipe) Len() int {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.b == nil {
- return p.unread
- }
- return p.b.Len()
-}
-
-// Read waits until data is available and copies bytes
-// from the buffer into p.
-func (p *http2pipe) Read(d []byte) (n int, err error) {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.c.L == nil {
- p.c.L = &p.mu
- }
- for {
- if p.breakErr != nil {
- return 0, p.breakErr
- }
- if p.b != nil && p.b.Len() > 0 {
- return p.b.Read(d)
- }
- if p.err != nil {
- if p.readFn != nil {
- p.readFn() // e.g. copy trailers
- p.readFn = nil // not sticky like p.err
- }
- p.b = nil
- return 0, p.err
- }
- p.c.Wait()
- }
-}
-
-var http2errClosedPipeWrite = errors.New("write on closed buffer")
-
-// Write copies bytes from p into the buffer and wakes a reader.
-// It is an error to write more data than the buffer can hold.
-func (p *http2pipe) Write(d []byte) (n int, err error) {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.c.L == nil {
- p.c.L = &p.mu
- }
- defer p.c.Signal()
- if p.err != nil {
- return 0, http2errClosedPipeWrite
- }
- if p.breakErr != nil {
- p.unread += len(d)
- return len(d), nil // discard when there is no reader
- }
- return p.b.Write(d)
-}
-
-// CloseWithError causes the next Read (waking up a current blocked
-// Read if needed) to return the provided err after all data has been
-// read.
-//
-// The error must be non-nil.
-func (p *http2pipe) CloseWithError(err error) { p.closeWithError(&p.err, err, nil) }
-
-// BreakWithError causes the next Read (waking up a current blocked
-// Read if needed) to return the provided err immediately, without
-// waiting for unread data.
-func (p *http2pipe) BreakWithError(err error) { p.closeWithError(&p.breakErr, err, nil) }
-
-// closeWithErrorAndCode is like CloseWithError but also sets some code to run
-// in the caller's goroutine before returning the error.
-func (p *http2pipe) closeWithErrorAndCode(err error, fn func()) { p.closeWithError(&p.err, err, fn) }
-
-func (p *http2pipe) closeWithError(dst *error, err error, fn func()) {
- if err == nil {
- panic("err must be non-nil")
- }
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.c.L == nil {
- p.c.L = &p.mu
- }
- defer p.c.Signal()
- if *dst != nil {
- // Already been done.
- return
- }
- p.readFn = fn
- if dst == &p.breakErr {
- if p.b != nil {
- p.unread += p.b.Len()
- }
- p.b = nil
- }
- *dst = err
- p.closeDoneLocked()
-}
-
-// requires p.mu be held.
-func (p *http2pipe) closeDoneLocked() {
- if p.donec == nil {
- return
- }
- // Close if unclosed. This isn't racy since we always
- // hold p.mu while closing.
- select {
- case <-p.donec:
- default:
- close(p.donec)
- }
-}
-
-// Err returns the error (if any) first set by BreakWithError or CloseWithError.
-func (p *http2pipe) Err() error {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.breakErr != nil {
- return p.breakErr
- }
- return p.err
-}
-
-// Done returns a channel which is closed if and when this pipe is closed
-// with CloseWithError.
-func (p *http2pipe) Done() <-chan struct{} {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.donec == nil {
- p.donec = make(chan struct{})
- if p.err != nil || p.breakErr != nil {
- // Already hit an error.
- p.closeDoneLocked()
- }
- }
- return p.donec
-}
-
-const (
- http2prefaceTimeout = 10 * time.Second
- http2firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway
- http2handlerChunkWriteSize = 4 << 10
- http2defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to?
- http2maxQueuedControlFrames = 10000
-)
-
-var (
- http2errClientDisconnected = errors.New("client disconnected")
- http2errClosedBody = errors.New("body closed by handler")
- http2errHandlerComplete = errors.New("http2: request body closed due to handler exiting")
- http2errStreamClosed = errors.New("http2: stream closed")
-)
-
-var http2responseWriterStatePool = sync.Pool{
- New: func() interface{} {
- rws := &http2responseWriterState{}
- rws.bw = bufio.NewWriterSize(http2chunkWriter{rws}, http2handlerChunkWriteSize)
- return rws
- },
-}
-
-// Test hooks.
-var (
- http2testHookOnConn func()
- http2testHookGetServerConn func(*http2serverConn)
- http2testHookOnPanicMu *sync.Mutex // nil except in tests
- http2testHookOnPanic func(sc *http2serverConn, panicVal interface{}) (rePanic bool)
-)
-
-// Server is an HTTP/2 server.
-type http2Server struct {
- // MaxHandlers limits the number of http.Handler ServeHTTP goroutines
- // which may run at a time over all connections.
- // Negative or zero no limit.
- // TODO: implement
- MaxHandlers int
-
- // MaxConcurrentStreams optionally specifies the number of
- // concurrent streams that each client may have open at a
- // time. This is unrelated to the number of http.Handler goroutines
- // which may be active globally, which is MaxHandlers.
- // If zero, MaxConcurrentStreams defaults to at least 100, per
- // the HTTP/2 spec's recommendations.
- MaxConcurrentStreams uint32
-
- // MaxDecoderHeaderTableSize optionally specifies the http2
- // SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It
- // informs the remote endpoint of the maximum size of the header compression
- // table used to decode header blocks, in octets. If zero, the default value
- // of 4096 is used.
- MaxDecoderHeaderTableSize uint32
-
- // MaxEncoderHeaderTableSize optionally specifies an upper limit for the
- // header compression table used for encoding request headers. Received
- // SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero,
- // the default value of 4096 is used.
- MaxEncoderHeaderTableSize uint32
-
- // MaxReadFrameSize optionally specifies the largest frame
- // this server is willing to read. A valid value is between
- // 16k and 16M, inclusive. If zero or otherwise invalid, a
- // default value is used.
- MaxReadFrameSize uint32
-
- // PermitProhibitedCipherSuites, if true, permits the use of
- // cipher suites prohibited by the HTTP/2 spec.
- PermitProhibitedCipherSuites bool
-
- // IdleTimeout specifies how long until idle clients should be
- // closed with a GOAWAY frame. PING frames are not considered
- // activity for the purposes of IdleTimeout.
- IdleTimeout time.Duration
-
- // MaxUploadBufferPerConnection is the size of the initial flow
- // control window for each connections. The HTTP/2 spec does not
- // allow this to be smaller than 65535 or larger than 2^32-1.
- // If the value is outside this range, a default value will be
- // used instead.
- MaxUploadBufferPerConnection int32
-
- // MaxUploadBufferPerStream is the size of the initial flow control
- // window for each stream. The HTTP/2 spec does not allow this to
- // be larger than 2^32-1. If the value is zero or larger than the
- // maximum, a default value will be used instead.
- MaxUploadBufferPerStream int32
-
- // NewWriteScheduler constructs a write scheduler for a connection.
- // If nil, a default scheduler is chosen.
- NewWriteScheduler func() http2WriteScheduler
-
- // CountError, if non-nil, is called on HTTP/2 server errors.
- // It's intended to increment a metric for monitoring, such
- // as an expvar or Prometheus metric.
- // The errType consists of only ASCII word characters.
- CountError func(errType string)
-
- // Internal state. This is a pointer (rather than embedded directly)
- // so that we don't embed a Mutex in this struct, which will make the
- // struct non-copyable, which might break some callers.
- state *http2serverInternalState
-}
-
-func (s *http2Server) initialConnRecvWindowSize() int32 {
- if s.MaxUploadBufferPerConnection >= http2initialWindowSize {
- return s.MaxUploadBufferPerConnection
- }
- return 1 << 20
-}
-
-func (s *http2Server) initialStreamRecvWindowSize() int32 {
- if s.MaxUploadBufferPerStream > 0 {
- return s.MaxUploadBufferPerStream
- }
- return 1 << 20
-}
-
-func (s *http2Server) maxReadFrameSize() uint32 {
- if v := s.MaxReadFrameSize; v >= http2minMaxFrameSize && v <= http2maxFrameSize {
- return v
- }
- return http2defaultMaxReadFrameSize
-}
-
-func (s *http2Server) maxConcurrentStreams() uint32 {
- if v := s.MaxConcurrentStreams; v > 0 {
- return v
- }
- return http2defaultMaxStreams
-}
-
-func (s *http2Server) maxDecoderHeaderTableSize() uint32 {
- if v := s.MaxDecoderHeaderTableSize; v > 0 {
- return v
- }
- return http2initialHeaderTableSize
-}
-
-func (s *http2Server) maxEncoderHeaderTableSize() uint32 {
- if v := s.MaxEncoderHeaderTableSize; v > 0 {
- return v
- }
- return http2initialHeaderTableSize
-}
-
-// maxQueuedControlFrames is the maximum number of control frames like
-// SETTINGS, PING and RST_STREAM that will be queued for writing before
-// the connection is closed to prevent memory exhaustion attacks.
-func (s *http2Server) maxQueuedControlFrames() int {
- // TODO: if anybody asks, add a Server field, and remember to define the
- // behavior of negative values.
- return http2maxQueuedControlFrames
-}
-
-type http2serverInternalState struct {
- mu sync.Mutex
- activeConns map[*http2serverConn]struct{}
-}
-
-func (s *http2serverInternalState) registerConn(sc *http2serverConn) {
- if s == nil {
- return // if the Server was used without calling ConfigureServer
- }
- s.mu.Lock()
- s.activeConns[sc] = struct{}{}
- s.mu.Unlock()
-}
-
-func (s *http2serverInternalState) unregisterConn(sc *http2serverConn) {
- if s == nil {
- return // if the Server was used without calling ConfigureServer
- }
- s.mu.Lock()
- delete(s.activeConns, sc)
- s.mu.Unlock()
-}
-
-func (s *http2serverInternalState) startGracefulShutdown() {
- if s == nil {
- return // if the Server was used without calling ConfigureServer
- }
- s.mu.Lock()
- for sc := range s.activeConns {
- sc.startGracefulShutdown()
- }
- s.mu.Unlock()
-}
-
-// ConfigureServer adds HTTP/2 support to a net/http Server.
-//
-// The configuration conf may be nil.
-//
-// ConfigureServer must be called before s begins serving.
-func http2ConfigureServer(s *Server, conf *http2Server) error {
- if s == nil {
- panic("nil *http.Server")
- }
- if conf == nil {
- conf = new(http2Server)
- }
- conf.state = &http2serverInternalState{activeConns: make(map[*http2serverConn]struct{})}
- if h1, h2 := s, conf; h2.IdleTimeout == 0 {
- if h1.IdleTimeout != 0 {
- h2.IdleTimeout = h1.IdleTimeout
- } else {
- h2.IdleTimeout = h1.ReadTimeout
- }
- }
- s.RegisterOnShutdown(conf.state.startGracefulShutdown)
-
- if s.TLSConfig == nil {
- s.TLSConfig = new(tls.Config)
- } else if s.TLSConfig.CipherSuites != nil && s.TLSConfig.MinVersion < tls.VersionTLS13 {
- // If they already provided a TLS 1.0–1.2 CipherSuite list, return an
- // error if it is missing ECDHE_RSA_WITH_AES_128_GCM_SHA256 or
- // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
- haveRequired := false
- for _, cs := range s.TLSConfig.CipherSuites {
- switch cs {
- case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- // Alternative MTI cipher to not discourage ECDSA-only servers.
- // See http://golang.org/cl/30721 for further information.
- tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
- haveRequired = true
- }
- }
- if !haveRequired {
- return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)")
- }
- }
-
- // Note: not setting MinVersion to tls.VersionTLS12,
- // as we don't want to interfere with HTTP/1.1 traffic
- // on the user's server. We enforce TLS 1.2 later once
- // we accept a connection. Ideally this should be done
- // during next-proto selection, but using TLS <1.2 with
- // HTTP/2 is still the client's bug.
-
- s.TLSConfig.PreferServerCipherSuites = true
-
- if !http2strSliceContains(s.TLSConfig.NextProtos, http2NextProtoTLS) {
- s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, http2NextProtoTLS)
- }
- if !http2strSliceContains(s.TLSConfig.NextProtos, "http/1.1") {
- s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "http/1.1")
- }
-
- if s.TLSNextProto == nil {
- s.TLSNextProto = map[string]func(*Server, *tls.Conn, Handler){}
- }
- protoHandler := func(hs *Server, c *tls.Conn, h Handler) {
- if http2testHookOnConn != nil {
- http2testHookOnConn()
- }
- // The TLSNextProto interface predates contexts, so
- // the net/http package passes down its per-connection
- // base context via an exported but unadvertised
- // method on the Handler. This is for internal
- // net/http<=>http2 use only.
- var ctx context.Context
- type baseContexter interface {
- BaseContext() context.Context
- }
- if bc, ok := h.(baseContexter); ok {
- ctx = bc.BaseContext()
- }
- conf.ServeConn(c, &http2ServeConnOpts{
- Context: ctx,
- Handler: h,
- BaseConfig: hs,
- })
- }
- s.TLSNextProto[http2NextProtoTLS] = protoHandler
- return nil
-}
-
-// ServeConnOpts are options for the Server.ServeConn method.
-type http2ServeConnOpts struct {
- // Context is the base context to use.
- // If nil, context.Background is used.
- Context context.Context
-
- // BaseConfig optionally sets the base configuration
- // for values. If nil, defaults are used.
- BaseConfig *Server
-
- // Handler specifies which handler to use for processing
- // requests. If nil, BaseConfig.Handler is used. If BaseConfig
- // or BaseConfig.Handler is nil, http.DefaultServeMux is used.
- Handler Handler
-
- // UpgradeRequest is an initial request received on a connection
- // undergoing an h2c upgrade. The request body must have been
- // completely read from the connection before calling ServeConn,
- // and the 101 Switching Protocols response written.
- UpgradeRequest *Request
-
- // Settings is the decoded contents of the HTTP2-Settings header
- // in an h2c upgrade request.
- Settings []byte
-
- // SawClientPreface is set if the HTTP/2 connection preface
- // has already been read from the connection.
- SawClientPreface bool
-}
-
-func (o *http2ServeConnOpts) context() context.Context {
- if o != nil && o.Context != nil {
- return o.Context
- }
- return context.Background()
-}
-
-func (o *http2ServeConnOpts) baseConfig() *Server {
- if o != nil && o.BaseConfig != nil {
- return o.BaseConfig
- }
- return new(Server)
-}
-
-func (o *http2ServeConnOpts) handler() Handler {
- if o != nil {
- if o.Handler != nil {
- return o.Handler
- }
- if o.BaseConfig != nil && o.BaseConfig.Handler != nil {
- return o.BaseConfig.Handler
- }
- }
- return DefaultServeMux
-}
-
-// ServeConn serves HTTP/2 requests on the provided connection and
-// blocks until the connection is no longer readable.
-//
-// ServeConn starts speaking HTTP/2 assuming that c has not had any
-// reads or writes. It writes its initial settings frame and expects
-// to be able to read the preface and settings frame from the
-// client. If c has a ConnectionState method like a *tls.Conn, the
-// ConnectionState is used to verify the TLS ciphersuite and to set
-// the Request.TLS field in Handlers.
-//
-// ServeConn does not support h2c by itself. Any h2c support must be
-// implemented in terms of providing a suitably-behaving net.Conn.
-//
-// The opts parameter is optional. If nil, default values are used.
-func (s *http2Server) ServeConn(c net.Conn, opts *http2ServeConnOpts) {
- baseCtx, cancel := http2serverConnBaseContext(c, opts)
- defer cancel()
-
- sc := &http2serverConn{
- srv: s,
- hs: opts.baseConfig(),
- conn: c,
- baseCtx: baseCtx,
- remoteAddrStr: c.RemoteAddr().String(),
- bw: http2newBufferedWriter(c),
- handler: opts.handler(),
- streams: make(map[uint32]*http2stream),
- readFrameCh: make(chan http2readFrameResult),
- wantWriteFrameCh: make(chan http2FrameWriteRequest, 8),
- serveMsgCh: make(chan interface{}, 8),
- wroteFrameCh: make(chan http2frameWriteResult, 1), // buffered; one send in writeFrameAsync
- bodyReadCh: make(chan http2bodyReadMsg), // buffering doesn't matter either way
- doneServing: make(chan struct{}),
- clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value"
- advMaxStreams: s.maxConcurrentStreams(),
- initialStreamSendWindowSize: http2initialWindowSize,
- maxFrameSize: http2initialMaxFrameSize,
- serveG: http2newGoroutineLock(),
- pushEnabled: true,
- sawClientPreface: opts.SawClientPreface,
- }
-
- s.state.registerConn(sc)
- defer s.state.unregisterConn(sc)
-
- // The net/http package sets the write deadline from the
- // http.Server.WriteTimeout during the TLS handshake, but then
- // passes the connection off to us with the deadline already set.
- // Write deadlines are set per stream in serverConn.newStream.
- // Disarm the net.Conn write deadline here.
- if sc.hs.WriteTimeout != 0 {
- sc.conn.SetWriteDeadline(time.Time{})
- }
-
- if s.NewWriteScheduler != nil {
- sc.writeSched = s.NewWriteScheduler()
- } else {
- sc.writeSched = http2NewPriorityWriteScheduler(nil)
- }
-
- // These start at the RFC-specified defaults. If there is a higher
- // configured value for inflow, that will be updated when we send a
- // WINDOW_UPDATE shortly after sending SETTINGS.
- sc.flow.add(http2initialWindowSize)
- sc.inflow.add(http2initialWindowSize)
- sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
- sc.hpackEncoder.SetMaxDynamicTableSizeLimit(s.maxEncoderHeaderTableSize())
-
- fr := http2NewFramer(sc.bw, c)
- if s.CountError != nil {
- fr.countError = s.CountError
- }
- fr.ReadMetaHeaders = hpack.NewDecoder(s.maxDecoderHeaderTableSize(), nil)
- fr.MaxHeaderListSize = sc.maxHeaderListSize()
- fr.SetMaxReadFrameSize(s.maxReadFrameSize())
- sc.framer = fr
-
- if tc, ok := c.(http2connectionStater); ok {
- sc.tlsState = new(tls.ConnectionState)
- *sc.tlsState = tc.ConnectionState()
- // 9.2 Use of TLS Features
- // An implementation of HTTP/2 over TLS MUST use TLS
- // 1.2 or higher with the restrictions on feature set
- // and cipher suite described in this section. Due to
- // implementation limitations, it might not be
- // possible to fail TLS negotiation. An endpoint MUST
- // immediately terminate an HTTP/2 connection that
- // does not meet the TLS requirements described in
- // this section with a connection error (Section
- // 5.4.1) of type INADEQUATE_SECURITY.
- if sc.tlsState.Version < tls.VersionTLS12 {
- sc.rejectConn(http2ErrCodeInadequateSecurity, "TLS version too low")
- return
- }
-
- if sc.tlsState.ServerName == "" {
- // Client must use SNI, but we don't enforce that anymore,
- // since it was causing problems when connecting to bare IP
- // addresses during development.
- //
- // TODO: optionally enforce? Or enforce at the time we receive
- // a new request, and verify the ServerName matches the :authority?
- // But that precludes proxy situations, perhaps.
- //
- // So for now, do nothing here again.
- }
-
- if !s.PermitProhibitedCipherSuites && http2isBadCipher(sc.tlsState.CipherSuite) {
- // "Endpoints MAY choose to generate a connection error
- // (Section 5.4.1) of type INADEQUATE_SECURITY if one of
- // the prohibited cipher suites are negotiated."
- //
- // We choose that. In my opinion, the spec is weak
- // here. It also says both parties must support at least
- // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no
- // excuses here. If we really must, we could allow an
- // "AllowInsecureWeakCiphers" option on the server later.
- // Let's see how it plays out first.
- sc.rejectConn(http2ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite))
- return
- }
- }
-
- if opts.Settings != nil {
- fr := &http2SettingsFrame{
- http2FrameHeader: http2FrameHeader{valid: true},
- p: opts.Settings,
- }
- if err := fr.ForeachSetting(sc.processSetting); err != nil {
- sc.rejectConn(http2ErrCodeProtocol, "invalid settings")
- return
- }
- opts.Settings = nil
- }
-
- if hook := http2testHookGetServerConn; hook != nil {
- hook(sc)
- }
-
- if opts.UpgradeRequest != nil {
- sc.upgradeRequest(opts.UpgradeRequest)
- opts.UpgradeRequest = nil
- }
-
- sc.serve()
-}
-
-func http2serverConnBaseContext(c net.Conn, opts *http2ServeConnOpts) (ctx context.Context, cancel func()) {
- ctx, cancel = context.WithCancel(opts.context())
- ctx = context.WithValue(ctx, LocalAddrContextKey, c.LocalAddr())
- if hs := opts.baseConfig(); hs != nil {
- ctx = context.WithValue(ctx, ServerContextKey, hs)
- }
- return
-}
-
-func (sc *http2serverConn) rejectConn(err http2ErrCode, debug string) {
- sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
- // ignoring errors. hanging up anyway.
- sc.framer.WriteGoAway(0, err, []byte(debug))
- sc.bw.Flush()
- sc.conn.Close()
-}
-
-type http2serverConn struct {
- // Immutable:
- srv *http2Server
- hs *Server
- conn net.Conn
- bw *http2bufferedWriter // writing to conn
- handler Handler
- baseCtx context.Context
- framer *http2Framer
- doneServing chan struct{} // closed when serverConn.serve ends
- readFrameCh chan http2readFrameResult // written by serverConn.readFrames
- wantWriteFrameCh chan http2FrameWriteRequest // from handlers -> serve
- wroteFrameCh chan http2frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes
- bodyReadCh chan http2bodyReadMsg // from handlers -> serve
- serveMsgCh chan interface{} // misc messages & code to send to / run on the serve loop
- flow http2flow // conn-wide (not stream-specific) outbound flow control
- inflow http2flow // conn-wide inbound flow control
- tlsState *tls.ConnectionState // shared by all handlers, like net/http
- remoteAddrStr string
- writeSched http2WriteScheduler
-
- // Everything following is owned by the serve loop; use serveG.check():
- serveG http2goroutineLock // used to verify funcs are on serve()
- pushEnabled bool
- sawClientPreface bool // preface has already been read, used in h2c upgrade
- sawFirstSettings bool // got the initial SETTINGS frame after the preface
- needToSendSettingsAck bool
- unackedSettings int // how many SETTINGS have we sent without ACKs?
- queuedControlFrames int // control frames in the writeSched queue
- clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
- advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
- curClientStreams uint32 // number of open streams initiated by the client
- curPushedStreams uint32 // number of open streams initiated by server push
- maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests
- maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes
- streams map[uint32]*http2stream
- initialStreamSendWindowSize int32
- maxFrameSize int32
- peerMaxHeaderListSize uint32 // zero means unknown (default)
- canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case
- canonHeaderKeysSize int // canonHeader keys size in bytes
- writingFrame bool // started writing a frame (on serve goroutine or separate)
- writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh
- needsFrameFlush bool // last frame write wasn't a flush
- inGoAway bool // we've started to or sent GOAWAY
- inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop
- needToSendGoAway bool // we need to schedule a GOAWAY frame write
- goAwayCode http2ErrCode
- shutdownTimer *time.Timer // nil until used
- idleTimer *time.Timer // nil if unused
-
- // Owned by the writeFrameAsync goroutine:
- headerWriteBuf bytes.Buffer
- hpackEncoder *hpack.Encoder
-
- // Used by startGracefulShutdown.
- shutdownOnce sync.Once
-}
-
-func (sc *http2serverConn) maxHeaderListSize() uint32 {
- n := sc.hs.MaxHeaderBytes
- if n <= 0 {
- n = DefaultMaxHeaderBytes
- }
- // http2's count is in a slightly different unit and includes 32 bytes per pair.
- // So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
- const perFieldOverhead = 32 // per http2 spec
- const typicalHeaders = 10 // conservative
- return uint32(n + typicalHeaders*perFieldOverhead)
-}
-
-func (sc *http2serverConn) curOpenStreams() uint32 {
- sc.serveG.check()
- return sc.curClientStreams + sc.curPushedStreams
-}
-
-// stream represents a stream. This is the minimal metadata needed by
-// the serve goroutine. Most of the actual stream state is owned by
-// the http.Handler's goroutine in the responseWriter. Because the
-// responseWriter's responseWriterState is recycled at the end of a
-// handler, this struct intentionally has no pointer to the
-// *responseWriter{,State} itself, as the Handler ending nils out the
-// responseWriter's state field.
-type http2stream struct {
- // immutable:
- sc *http2serverConn
- id uint32
- body *http2pipe // non-nil if expecting DATA frames
- cw http2closeWaiter // closed wait stream transitions to closed state
- ctx context.Context
- cancelCtx func()
-
- // owned by serverConn's serve loop:
- bodyBytes int64 // body bytes seen so far
- declBodyBytes int64 // or -1 if undeclared
- flow http2flow // limits writing from Handler to client
- inflow http2flow // what the client is allowed to POST/etc to us
- state http2streamState
- resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
- gotTrailerHeader bool // HEADER frame for trailers was seen
- wroteHeaders bool // whether we wrote headers (not status 100)
- readDeadline *time.Timer // nil if unused
- writeDeadline *time.Timer // nil if unused
- closeErr error // set before cw is closed
-
- trailer Header // accumulated trailers
- reqTrailer Header // handler's Request.Trailer
-}
-
-func (sc *http2serverConn) Framer() *http2Framer { return sc.framer }
-
-func (sc *http2serverConn) CloseConn() error { return sc.conn.Close() }
-
-func (sc *http2serverConn) Flush() error { return sc.bw.Flush() }
-
-func (sc *http2serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) {
- return sc.hpackEncoder, &sc.headerWriteBuf
-}
-
-func (sc *http2serverConn) state(streamID uint32) (http2streamState, *http2stream) {
- sc.serveG.check()
- // http://tools.ietf.org/html/rfc7540#section-5.1
- if st, ok := sc.streams[streamID]; ok {
- return st.state, st
- }
- // "The first use of a new stream identifier implicitly closes all
- // streams in the "idle" state that might have been initiated by
- // that peer with a lower-valued stream identifier. For example, if
- // a client sends a HEADERS frame on stream 7 without ever sending a
- // frame on stream 5, then stream 5 transitions to the "closed"
- // state when the first frame for stream 7 is sent or received."
- if streamID%2 == 1 {
- if streamID <= sc.maxClientStreamID {
- return http2stateClosed, nil
- }
- } else {
- if streamID <= sc.maxPushPromiseID {
- return http2stateClosed, nil
- }
- }
- return http2stateIdle, nil
-}
-
-// setConnState calls the net/http ConnState hook for this connection, if configured.
-// Note that the net/http package does StateNew and StateClosed for us.
-// There is currently no plan for StateHijacked or hijacking HTTP/2 connections.
-func (sc *http2serverConn) setConnState(state ConnState) {
- if sc.hs.ConnState != nil {
- sc.hs.ConnState(sc.conn, state)
- }
-}
-
-func (sc *http2serverConn) vlogf(format string, args ...interface{}) {
- if http2VerboseLogs {
- sc.logf(format, args...)
- }
-}
-
-func (sc *http2serverConn) logf(format string, args ...interface{}) {
- if lg := sc.hs.ErrorLog; lg != nil {
- lg.Printf(format, args...)
- } else {
- log.Printf(format, args...)
- }
-}
-
-// errno returns v's underlying uintptr, else 0.
-//
-// TODO: remove this helper function once http2 can use build
-// tags. See comment in isClosedConnError.
-func http2errno(v error) uintptr {
- if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr {
- return uintptr(rv.Uint())
- }
- return 0
-}
-
-// isClosedConnError reports whether err is an error from use of a closed
-// network connection.
-func http2isClosedConnError(err error) bool {
- if err == nil {
- return false
- }
-
- // TODO: remove this string search and be more like the Windows
- // case below. That might involve modifying the standard library
- // to return better error types.
- str := err.Error()
- if strings.Contains(str, "use of closed network connection") {
- return true
- }
-
- // TODO(bradfitz): x/tools/cmd/bundle doesn't really support
- // build tags, so I can't make an http2_windows.go file with
- // Windows-specific stuff. Fix that and move this, once we
- // have a way to bundle this into std's net/http somehow.
- if runtime.GOOS == "windows" {
- if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
- if se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == "wsarecv" {
- const WSAECONNABORTED = 10053
- const WSAECONNRESET = 10054
- if n := http2errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED {
- return true
- }
- }
- }
- }
- return false
-}
-
-func (sc *http2serverConn) condlogf(err error, format string, args ...interface{}) {
- if err == nil {
- return
- }
- if err == io.EOF || err == io.ErrUnexpectedEOF || http2isClosedConnError(err) || err == http2errPrefaceTimeout {
- // Boring, expected errors.
- sc.vlogf(format, args...)
- } else {
- sc.logf(format, args...)
- }
-}
-
-// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size
-// of the entries in the canonHeader cache.
-// This should be larger than the size of unique, uncommon header keys likely to
-// be sent by the peer, while not so high as to permit unreasonable memory usage
-// if the peer sends an unbounded number of unique header keys.
-const http2maxCachedCanonicalHeadersKeysSize = 2048
-
-func (sc *http2serverConn) canonicalHeader(v string) string {
- sc.serveG.check()
- http2buildCommonHeaderMapsOnce()
- cv, ok := http2commonCanonHeader[v]
- if ok {
- return cv
- }
- cv, ok = sc.canonHeader[v]
- if ok {
- return cv
- }
- if sc.canonHeader == nil {
- sc.canonHeader = make(map[string]string)
- }
- cv = CanonicalHeaderKey(v)
- size := 100 + len(v)*2 // 100 bytes of map overhead + key + value
- if sc.canonHeaderKeysSize+size <= http2maxCachedCanonicalHeadersKeysSize {
- sc.canonHeader[v] = cv
- sc.canonHeaderKeysSize += size
- }
- return cv
-}
-
-type http2readFrameResult struct {
- f http2Frame // valid until readMore is called
- err error
-
- // readMore should be called once the consumer no longer needs or
- // retains f. After readMore, f is invalid and more frames can be
- // read.
- readMore func()
-}
-
-// readFrames is the loop that reads incoming frames.
-// It takes care to only read one frame at a time, blocking until the
-// consumer is done with the frame.
-// It's run on its own goroutine.
-func (sc *http2serverConn) readFrames() {
- gate := make(http2gate)
- gateDone := gate.Done
- for {
- f, err := sc.framer.ReadFrame()
- select {
- case sc.readFrameCh <- http2readFrameResult{f, err, gateDone}:
- case <-sc.doneServing:
- return
- }
- select {
- case <-gate:
- case <-sc.doneServing:
- return
- }
- if http2terminalReadFrameError(err) {
- return
- }
- }
-}
-
-// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
-type http2frameWriteResult struct {
- _ http2incomparable
- wr http2FrameWriteRequest // what was written (or attempted)
- err error // result of the writeFrame call
-}
-
-// writeFrameAsync runs in its own goroutine and writes a single frame
-// and then reports when it's done.
-// At most one goroutine can be running writeFrameAsync at a time per
-// serverConn.
-func (sc *http2serverConn) writeFrameAsync(wr http2FrameWriteRequest) {
- err := wr.write.writeFrame(sc)
- sc.wroteFrameCh <- http2frameWriteResult{wr: wr, err: err}
-}
-
-func (sc *http2serverConn) closeAllStreamsOnConnClose() {
- sc.serveG.check()
- for _, st := range sc.streams {
- sc.closeStream(st, http2errClientDisconnected)
- }
-}
-
-func (sc *http2serverConn) stopShutdownTimer() {
- sc.serveG.check()
- if t := sc.shutdownTimer; t != nil {
- t.Stop()
- }
-}
-
-func (sc *http2serverConn) notePanic() {
- // Note: this is for serverConn.serve panicking, not http.Handler code.
- if http2testHookOnPanicMu != nil {
- http2testHookOnPanicMu.Lock()
- defer http2testHookOnPanicMu.Unlock()
- }
- if http2testHookOnPanic != nil {
- if e := recover(); e != nil {
- if http2testHookOnPanic(sc, e) {
- panic(e)
- }
- }
- }
-}
-
-func (sc *http2serverConn) serve() {
- sc.serveG.check()
- defer sc.notePanic()
- defer sc.conn.Close()
- defer sc.closeAllStreamsOnConnClose()
- defer sc.stopShutdownTimer()
- defer close(sc.doneServing) // unblocks handlers trying to send
-
- if http2VerboseLogs {
- sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
- }
-
- sc.writeFrame(http2FrameWriteRequest{
- write: http2writeSettings{
- {http2SettingMaxFrameSize, sc.srv.maxReadFrameSize()},
- {http2SettingMaxConcurrentStreams, sc.advMaxStreams},
- {http2SettingMaxHeaderListSize, sc.maxHeaderListSize()},
- {http2SettingHeaderTableSize, sc.srv.maxDecoderHeaderTableSize()},
- {http2SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())},
- },
- })
- sc.unackedSettings++
-
- // Each connection starts with initialWindowSize inflow tokens.
- // If a higher value is configured, we add more tokens.
- if diff := sc.srv.initialConnRecvWindowSize() - http2initialWindowSize; diff > 0 {
- sc.sendWindowUpdate(nil, int(diff))
- }
-
- if err := sc.readPreface(); err != nil {
- sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err)
- return
- }
- // Now that we've got the preface, get us out of the
- // "StateNew" state. We can't go directly to idle, though.
- // Active means we read some data and anticipate a request. We'll
- // do another Active when we get a HEADERS frame.
- sc.setConnState(StateActive)
- sc.setConnState(StateIdle)
-
- if sc.srv.IdleTimeout != 0 {
- sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
- defer sc.idleTimer.Stop()
- }
-
- go sc.readFrames() // closed by defer sc.conn.Close above
-
- settingsTimer := time.AfterFunc(http2firstSettingsTimeout, sc.onSettingsTimer)
- defer settingsTimer.Stop()
-
- loopNum := 0
- for {
- loopNum++
- select {
- case wr := <-sc.wantWriteFrameCh:
- if se, ok := wr.write.(http2StreamError); ok {
- sc.resetStream(se)
- break
- }
- sc.writeFrame(wr)
- case res := <-sc.wroteFrameCh:
- sc.wroteFrame(res)
- case res := <-sc.readFrameCh:
- // Process any written frames before reading new frames from the client since a
- // written frame could have triggered a new stream to be started.
- if sc.writingFrameAsync {
- select {
- case wroteRes := <-sc.wroteFrameCh:
- sc.wroteFrame(wroteRes)
- default:
- }
- }
- if !sc.processFrameFromReader(res) {
- return
- }
- res.readMore()
- if settingsTimer != nil {
- settingsTimer.Stop()
- settingsTimer = nil
- }
- case m := <-sc.bodyReadCh:
- sc.noteBodyRead(m.st, m.n)
- case msg := <-sc.serveMsgCh:
- switch v := msg.(type) {
- case func(int):
- v(loopNum) // for testing
- case *http2serverMessage:
- switch v {
- case http2settingsTimerMsg:
- sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr())
- return
- case http2idleTimerMsg:
- sc.vlogf("connection is idle")
- sc.goAway(http2ErrCodeNo)
- case http2shutdownTimerMsg:
- sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr())
- return
- case http2gracefulShutdownMsg:
- sc.startGracefulShutdownInternal()
- default:
- panic("unknown timer")
- }
- case *http2startPushRequest:
- sc.startPush(v)
- case func(*http2serverConn):
- v(sc)
- default:
- panic(fmt.Sprintf("unexpected type %T", v))
- }
- }
-
- // If the peer is causing us to generate a lot of control frames,
- // but not reading them from us, assume they are trying to make us
- // run out of memory.
- if sc.queuedControlFrames > sc.srv.maxQueuedControlFrames() {
- sc.vlogf("http2: too many control frames in send queue, closing connection")
- return
- }
-
- // Start the shutdown timer after sending a GOAWAY. When sending GOAWAY
- // with no error code (graceful shutdown), don't start the timer until
- // all open streams have been completed.
- sentGoAway := sc.inGoAway && !sc.needToSendGoAway && !sc.writingFrame
- gracefulShutdownComplete := sc.goAwayCode == http2ErrCodeNo && sc.curOpenStreams() == 0
- if sentGoAway && sc.shutdownTimer == nil && (sc.goAwayCode != http2ErrCodeNo || gracefulShutdownComplete) {
- sc.shutDownIn(http2goAwayTimeout)
- }
- }
-}
-
-func (sc *http2serverConn) awaitGracefulShutdown(sharedCh <-chan struct{}, privateCh chan struct{}) {
- select {
- case <-sc.doneServing:
- case <-sharedCh:
- close(privateCh)
- }
-}
-
-type http2serverMessage int
-
-// Message values sent to serveMsgCh.
-var (
- http2settingsTimerMsg = new(http2serverMessage)
- http2idleTimerMsg = new(http2serverMessage)
- http2shutdownTimerMsg = new(http2serverMessage)
- http2gracefulShutdownMsg = new(http2serverMessage)
-)
-
-func (sc *http2serverConn) onSettingsTimer() { sc.sendServeMsg(http2settingsTimerMsg) }
-
-func (sc *http2serverConn) onIdleTimer() { sc.sendServeMsg(http2idleTimerMsg) }
-
-func (sc *http2serverConn) onShutdownTimer() { sc.sendServeMsg(http2shutdownTimerMsg) }
-
-func (sc *http2serverConn) sendServeMsg(msg interface{}) {
- sc.serveG.checkNotOn() // NOT
- select {
- case sc.serveMsgCh <- msg:
- case <-sc.doneServing:
- }
-}
-
-var http2errPrefaceTimeout = errors.New("timeout waiting for client preface")
-
-// readPreface reads the ClientPreface greeting from the peer or
-// returns errPrefaceTimeout on timeout, or an error if the greeting
-// is invalid.
-func (sc *http2serverConn) readPreface() error {
- if sc.sawClientPreface {
- return nil
- }
- errc := make(chan error, 1)
- go func() {
- // Read the client preface
- buf := make([]byte, len(http2ClientPreface))
- if _, err := io.ReadFull(sc.conn, buf); err != nil {
- errc <- err
- } else if !bytes.Equal(buf, http2clientPreface) {
- errc <- fmt.Errorf("bogus greeting %q", buf)
- } else {
- errc <- nil
- }
- }()
- timer := time.NewTimer(http2prefaceTimeout) // TODO: configurable on *Server?
- defer timer.Stop()
- select {
- case <-timer.C:
- return http2errPrefaceTimeout
- case err := <-errc:
- if err == nil {
- if http2VerboseLogs {
- sc.vlogf("http2: server: client %v said hello", sc.conn.RemoteAddr())
- }
- }
- return err
- }
-}
-
-var http2errChanPool = sync.Pool{
- New: func() interface{} { return make(chan error, 1) },
-}
-
-var http2writeDataPool = sync.Pool{
- New: func() interface{} { return new(http2writeData) },
-}
-
-// writeDataFromHandler writes DATA response frames from a handler on
-// the given stream.
-func (sc *http2serverConn) writeDataFromHandler(stream *http2stream, data []byte, endStream bool) error {
- ch := http2errChanPool.Get().(chan error)
- writeArg := http2writeDataPool.Get().(*http2writeData)
- *writeArg = http2writeData{stream.id, data, endStream}
- err := sc.writeFrameFromHandler(http2FrameWriteRequest{
- write: writeArg,
- stream: stream,
- done: ch,
- })
- if err != nil {
- return err
- }
- var frameWriteDone bool // the frame write is done (successfully or not)
- select {
- case err = <-ch:
- frameWriteDone = true
- case <-sc.doneServing:
- return http2errClientDisconnected
- case <-stream.cw:
- // If both ch and stream.cw were ready (as might
- // happen on the final Write after an http.Handler
- // ends), prefer the write result. Otherwise this
- // might just be us successfully closing the stream.
- // The writeFrameAsync and serve goroutines guarantee
- // that the ch send will happen before the stream.cw
- // close.
- select {
- case err = <-ch:
- frameWriteDone = true
- default:
- return http2errStreamClosed
- }
- }
- http2errChanPool.Put(ch)
- if frameWriteDone {
- http2writeDataPool.Put(writeArg)
- }
- return err
-}
-
-// writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts
-// if the connection has gone away.
-//
-// This must not be run from the serve goroutine itself, else it might
-// deadlock writing to sc.wantWriteFrameCh (which is only mildly
-// buffered and is read by serve itself). If you're on the serve
-// goroutine, call writeFrame instead.
-func (sc *http2serverConn) writeFrameFromHandler(wr http2FrameWriteRequest) error {
- sc.serveG.checkNotOn() // NOT
- select {
- case sc.wantWriteFrameCh <- wr:
- return nil
- case <-sc.doneServing:
- // Serve loop is gone.
- // Client has closed their connection to the server.
- return http2errClientDisconnected
- }
-}
-
-// writeFrame schedules a frame to write and sends it if there's nothing
-// already being written.
-//
-// There is no pushback here (the serve goroutine never blocks). It's
-// the http.Handlers that block, waiting for their previous frames to
-// make it onto the wire
-//
-// If you're not on the serve goroutine, use writeFrameFromHandler instead.
-func (sc *http2serverConn) writeFrame(wr http2FrameWriteRequest) {
- sc.serveG.check()
-
- // If true, wr will not be written and wr.done will not be signaled.
- var ignoreWrite bool
-
- // We are not allowed to write frames on closed streams. RFC 7540 Section
- // 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on
- // a closed stream." Our server never sends PRIORITY, so that exception
- // does not apply.
- //
- // The serverConn might close an open stream while the stream's handler
- // is still running. For example, the server might close a stream when it
- // receives bad data from the client. If this happens, the handler might
- // attempt to write a frame after the stream has been closed (since the
- // handler hasn't yet been notified of the close). In this case, we simply
- // ignore the frame. The handler will notice that the stream is closed when
- // it waits for the frame to be written.
- //
- // As an exception to this rule, we allow sending RST_STREAM after close.
- // This allows us to immediately reject new streams without tracking any
- // state for those streams (except for the queued RST_STREAM frame). This
- // may result in duplicate RST_STREAMs in some cases, but the client should
- // ignore those.
- if wr.StreamID() != 0 {
- _, isReset := wr.write.(http2StreamError)
- if state, _ := sc.state(wr.StreamID()); state == http2stateClosed && !isReset {
- ignoreWrite = true
- }
- }
-
- // Don't send a 100-continue response if we've already sent headers.
- // See golang.org/issue/14030.
- switch wr.write.(type) {
- case *http2writeResHeaders:
- wr.stream.wroteHeaders = true
- case http2write100ContinueHeadersFrame:
- if wr.stream.wroteHeaders {
- // We do not need to notify wr.done because this frame is
- // never written with wr.done != nil.
- if wr.done != nil {
- panic("wr.done != nil for write100ContinueHeadersFrame")
- }
- ignoreWrite = true
- }
- }
-
- if !ignoreWrite {
- if wr.isControl() {
- sc.queuedControlFrames++
- // For extra safety, detect wraparounds, which should not happen,
- // and pull the plug.
- if sc.queuedControlFrames < 0 {
- sc.conn.Close()
- }
- }
- sc.writeSched.Push(wr)
- }
- sc.scheduleFrameWrite()
-}
-
-// startFrameWrite starts a goroutine to write wr (in a separate
-// goroutine since that might block on the network), and updates the
-// serve goroutine's state about the world, updated from info in wr.
-func (sc *http2serverConn) startFrameWrite(wr http2FrameWriteRequest) {
- sc.serveG.check()
- if sc.writingFrame {
- panic("internal error: can only be writing one frame at a time")
- }
-
- st := wr.stream
- if st != nil {
- switch st.state {
- case http2stateHalfClosedLocal:
- switch wr.write.(type) {
- case http2StreamError, http2handlerPanicRST, http2writeWindowUpdate:
- // RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE
- // in this state. (We never send PRIORITY from the server, so that is not checked.)
- default:
- panic(fmt.Sprintf("internal error: attempt to send frame on a half-closed-local stream: %v", wr))
- }
- case http2stateClosed:
- panic(fmt.Sprintf("internal error: attempt to send frame on a closed stream: %v", wr))
- }
- }
- if wpp, ok := wr.write.(*http2writePushPromise); ok {
- var err error
- wpp.promisedID, err = wpp.allocatePromisedID()
- if err != nil {
- sc.writingFrameAsync = false
- wr.replyToWriter(err)
- return
- }
- }
-
- sc.writingFrame = true
- sc.needsFrameFlush = true
- if wr.write.staysWithinBuffer(sc.bw.Available()) {
- sc.writingFrameAsync = false
- err := wr.write.writeFrame(sc)
- sc.wroteFrame(http2frameWriteResult{wr: wr, err: err})
- } else {
- sc.writingFrameAsync = true
- go sc.writeFrameAsync(wr)
- }
-}
-
-// errHandlerPanicked is the error given to any callers blocked in a read from
-// Request.Body when the main goroutine panics. Since most handlers read in the
-// main ServeHTTP goroutine, this will show up rarely.
-var http2errHandlerPanicked = errors.New("http2: handler panicked")
-
-// wroteFrame is called on the serve goroutine with the result of
-// whatever happened on writeFrameAsync.
-func (sc *http2serverConn) wroteFrame(res http2frameWriteResult) {
- sc.serveG.check()
- if !sc.writingFrame {
- panic("internal error: expected to be already writing a frame")
- }
- sc.writingFrame = false
- sc.writingFrameAsync = false
-
- wr := res.wr
-
- if http2writeEndsStream(wr.write) {
- st := wr.stream
- if st == nil {
- panic("internal error: expecting non-nil stream")
- }
- switch st.state {
- case http2stateOpen:
- // Here we would go to stateHalfClosedLocal in
- // theory, but since our handler is done and
- // the net/http package provides no mechanism
- // for closing a ResponseWriter while still
- // reading data (see possible TODO at top of
- // this file), we go into closed state here
- // anyway, after telling the peer we're
- // hanging up on them. We'll transition to
- // stateClosed after the RST_STREAM frame is
- // written.
- st.state = http2stateHalfClosedLocal
- // Section 8.1: a server MAY request that the client abort
- // transmission of a request without error by sending a
- // RST_STREAM with an error code of NO_ERROR after sending
- // a complete response.
- sc.resetStream(http2streamError(st.id, http2ErrCodeNo))
- case http2stateHalfClosedRemote:
- sc.closeStream(st, http2errHandlerComplete)
- }
- } else {
- switch v := wr.write.(type) {
- case http2StreamError:
- // st may be unknown if the RST_STREAM was generated to reject bad input.
- if st, ok := sc.streams[v.StreamID]; ok {
- sc.closeStream(st, v)
- }
- case http2handlerPanicRST:
- sc.closeStream(wr.stream, http2errHandlerPanicked)
- }
- }
-
- // Reply (if requested) to unblock the ServeHTTP goroutine.
- wr.replyToWriter(res.err)
-
- sc.scheduleFrameWrite()
-}
-
-// scheduleFrameWrite tickles the frame writing scheduler.
-//
-// If a frame is already being written, nothing happens. This will be called again
-// when the frame is done being written.
-//
-// If a frame isn't being written and we need to send one, the best frame
-// to send is selected by writeSched.
-//
-// If a frame isn't being written and there's nothing else to send, we
-// flush the write buffer.
-func (sc *http2serverConn) scheduleFrameWrite() {
- sc.serveG.check()
- if sc.writingFrame || sc.inFrameScheduleLoop {
- return
- }
- sc.inFrameScheduleLoop = true
- for !sc.writingFrameAsync {
- if sc.needToSendGoAway {
- sc.needToSendGoAway = false
- sc.startFrameWrite(http2FrameWriteRequest{
- write: &http2writeGoAway{
- maxStreamID: sc.maxClientStreamID,
- code: sc.goAwayCode,
- },
- })
- continue
- }
- if sc.needToSendSettingsAck {
- sc.needToSendSettingsAck = false
- sc.startFrameWrite(http2FrameWriteRequest{write: http2writeSettingsAck{}})
- continue
- }
- if !sc.inGoAway || sc.goAwayCode == http2ErrCodeNo {
- if wr, ok := sc.writeSched.Pop(); ok {
- if wr.isControl() {
- sc.queuedControlFrames--
- }
- sc.startFrameWrite(wr)
- continue
- }
- }
- if sc.needsFrameFlush {
- sc.startFrameWrite(http2FrameWriteRequest{write: http2flushFrameWriter{}})
- sc.needsFrameFlush = false // after startFrameWrite, since it sets this true
- continue
- }
- break
- }
- sc.inFrameScheduleLoop = false
-}
-
-// startGracefulShutdown gracefully shuts down a connection. This
-// sends GOAWAY with ErrCodeNo to tell the client we're gracefully
-// shutting down. The connection isn't closed until all current
-// streams are done.
-//
-// startGracefulShutdown returns immediately; it does not wait until
-// the connection has shut down.
-func (sc *http2serverConn) startGracefulShutdown() {
- sc.serveG.checkNotOn() // NOT
- sc.shutdownOnce.Do(func() { sc.sendServeMsg(http2gracefulShutdownMsg) })
-}
-
-// After sending GOAWAY with an error code (non-graceful shutdown), the
-// connection will close after goAwayTimeout.
-//
-// If we close the connection immediately after sending GOAWAY, there may
-// be unsent data in our kernel receive buffer, which will cause the kernel
-// to send a TCP RST on close() instead of a FIN. This RST will abort the
-// connection immediately, whether or not the client had received the GOAWAY.
-//
-// Ideally we should delay for at least 1 RTT + epsilon so the client has
-// a chance to read the GOAWAY and stop sending messages. Measuring RTT
-// is hard, so we approximate with 1 second. See golang.org/issue/18701.
-//
-// This is a var so it can be shorter in tests, where all requests uses the
-// loopback interface making the expected RTT very small.
-//
-// TODO: configurable?
-var http2goAwayTimeout = 1 * time.Second
-
-func (sc *http2serverConn) startGracefulShutdownInternal() {
- sc.goAway(http2ErrCodeNo)
-}
-
-func (sc *http2serverConn) goAway(code http2ErrCode) {
- sc.serveG.check()
- if sc.inGoAway {
- if sc.goAwayCode == http2ErrCodeNo {
- sc.goAwayCode = code
- }
- return
- }
- sc.inGoAway = true
- sc.needToSendGoAway = true
- sc.goAwayCode = code
- sc.scheduleFrameWrite()
-}
-
-func (sc *http2serverConn) shutDownIn(d time.Duration) {
- sc.serveG.check()
- sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer)
-}
-
-func (sc *http2serverConn) resetStream(se http2StreamError) {
- sc.serveG.check()
- sc.writeFrame(http2FrameWriteRequest{write: se})
- if st, ok := sc.streams[se.StreamID]; ok {
- st.resetQueued = true
- }
-}
-
-// processFrameFromReader processes the serve loop's read from readFrameCh from the
-// frame-reading goroutine.
-// processFrameFromReader returns whether the connection should be kept open.
-func (sc *http2serverConn) processFrameFromReader(res http2readFrameResult) bool {
- sc.serveG.check()
- err := res.err
- if err != nil {
- if err == http2ErrFrameTooLarge {
- sc.goAway(http2ErrCodeFrameSize)
- return true // goAway will close the loop
- }
- clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || http2isClosedConnError(err)
- if clientGone {
- // TODO: could we also get into this state if
- // the peer does a half close
- // (e.g. CloseWrite) because they're done
- // sending frames but they're still wanting
- // our open replies? Investigate.
- // TODO: add CloseWrite to crypto/tls.Conn first
- // so we have a way to test this? I suppose
- // just for testing we could have a non-TLS mode.
- return false
- }
- } else {
- f := res.f
- if http2VerboseLogs {
- sc.vlogf("http2: server read frame %v", http2summarizeFrame(f))
- }
- err = sc.processFrame(f)
- if err == nil {
- return true
- }
- }
-
- switch ev := err.(type) {
- case http2StreamError:
- sc.resetStream(ev)
- return true
- case http2goAwayFlowError:
- sc.goAway(http2ErrCodeFlowControl)
- return true
- case http2ConnectionError:
- sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev)
- sc.goAway(http2ErrCode(ev))
- return true // goAway will handle shutdown
- default:
- if res.err != nil {
- sc.vlogf("http2: server closing client connection; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err)
- } else {
- sc.logf("http2: server closing client connection: %v", err)
- }
- return false
- }
-}
-
-func (sc *http2serverConn) processFrame(f http2Frame) error {
- sc.serveG.check()
-
- // First frame received must be SETTINGS.
- if !sc.sawFirstSettings {
- if _, ok := f.(*http2SettingsFrame); !ok {
- return sc.countError("first_settings", http2ConnectionError(http2ErrCodeProtocol))
- }
- sc.sawFirstSettings = true
- }
-
- // Discard frames for streams initiated after the identified last
- // stream sent in a GOAWAY, or all frames after sending an error.
- // We still need to return connection-level flow control for DATA frames.
- // RFC 9113 Section 6.8.
- if sc.inGoAway && (sc.goAwayCode != http2ErrCodeNo || f.Header().StreamID > sc.maxClientStreamID) {
-
- if f, ok := f.(*http2DataFrame); ok {
- if sc.inflow.available() < int32(f.Length) {
- return sc.countError("data_flow", http2streamError(f.Header().StreamID, http2ErrCodeFlowControl))
- }
- sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
- }
- return nil
- }
-
- switch f := f.(type) {
- case *http2SettingsFrame:
- return sc.processSettings(f)
- case *http2MetaHeadersFrame:
- return sc.processHeaders(f)
- case *http2WindowUpdateFrame:
- return sc.processWindowUpdate(f)
- case *http2PingFrame:
- return sc.processPing(f)
- case *http2DataFrame:
- return sc.processData(f)
- case *http2RSTStreamFrame:
- return sc.processResetStream(f)
- case *http2PriorityFrame:
- return sc.processPriority(f)
- case *http2GoAwayFrame:
- return sc.processGoAway(f)
- case *http2PushPromiseFrame:
- // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
- // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
- return sc.countError("push_promise", http2ConnectionError(http2ErrCodeProtocol))
- default:
- sc.vlogf("http2: server ignoring frame: %v", f.Header())
- return nil
- }
-}
-
-func (sc *http2serverConn) processPing(f *http2PingFrame) error {
- sc.serveG.check()
- if f.IsAck() {
- // 6.7 PING: " An endpoint MUST NOT respond to PING frames
- // containing this flag."
- return nil
- }
- if f.StreamID != 0 {
- // "PING frames are not associated with any individual
- // stream. If a PING frame is received with a stream
- // identifier field value other than 0x0, the recipient MUST
- // respond with a connection error (Section 5.4.1) of type
- // PROTOCOL_ERROR."
- return sc.countError("ping_on_stream", http2ConnectionError(http2ErrCodeProtocol))
- }
- sc.writeFrame(http2FrameWriteRequest{write: http2writePingAck{f}})
- return nil
-}
-
-func (sc *http2serverConn) processWindowUpdate(f *http2WindowUpdateFrame) error {
- sc.serveG.check()
- switch {
- case f.StreamID != 0: // stream-level flow control
- state, st := sc.state(f.StreamID)
- if state == http2stateIdle {
- // Section 5.1: "Receiving any frame other than HEADERS
- // or PRIORITY on a stream in this state MUST be
- // treated as a connection error (Section 5.4.1) of
- // type PROTOCOL_ERROR."
- return sc.countError("stream_idle", http2ConnectionError(http2ErrCodeProtocol))
- }
- if st == nil {
- // "WINDOW_UPDATE can be sent by a peer that has sent a
- // frame bearing the END_STREAM flag. This means that a
- // receiver could receive a WINDOW_UPDATE frame on a "half
- // closed (remote)" or "closed" stream. A receiver MUST
- // NOT treat this as an error, see Section 5.1."
- return nil
- }
- if !st.flow.add(int32(f.Increment)) {
- return sc.countError("bad_flow", http2streamError(f.StreamID, http2ErrCodeFlowControl))
- }
- default: // connection-level flow control
- if !sc.flow.add(int32(f.Increment)) {
- return http2goAwayFlowError{}
- }
- }
- sc.scheduleFrameWrite()
- return nil
-}
-
-func (sc *http2serverConn) processResetStream(f *http2RSTStreamFrame) error {
- sc.serveG.check()
-
- state, st := sc.state(f.StreamID)
- if state == http2stateIdle {
- // 6.4 "RST_STREAM frames MUST NOT be sent for a
- // stream in the "idle" state. If a RST_STREAM frame
- // identifying an idle stream is received, the
- // recipient MUST treat this as a connection error
- // (Section 5.4.1) of type PROTOCOL_ERROR.
- return sc.countError("reset_idle_stream", http2ConnectionError(http2ErrCodeProtocol))
- }
- if st != nil {
- st.cancelCtx()
- sc.closeStream(st, http2streamError(f.StreamID, f.ErrCode))
- }
- return nil
-}
-
-func (sc *http2serverConn) closeStream(st *http2stream, err error) {
- sc.serveG.check()
- if st.state == http2stateIdle || st.state == http2stateClosed {
- panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
- }
- st.state = http2stateClosed
- if st.readDeadline != nil {
- st.readDeadline.Stop()
- }
- if st.writeDeadline != nil {
- st.writeDeadline.Stop()
- }
- if st.isPushed() {
- sc.curPushedStreams--
- } else {
- sc.curClientStreams--
- }
- delete(sc.streams, st.id)
- if len(sc.streams) == 0 {
- sc.setConnState(StateIdle)
- if sc.srv.IdleTimeout != 0 {
- sc.idleTimer.Reset(sc.srv.IdleTimeout)
- }
- if http2h1ServerKeepAlivesDisabled(sc.hs) {
- sc.startGracefulShutdownInternal()
- }
- }
- if p := st.body; p != nil {
- // Return any buffered unread bytes worth of conn-level flow control.
- // See golang.org/issue/16481
- sc.sendWindowUpdate(nil, p.Len())
-
- p.CloseWithError(err)
- }
- if e, ok := err.(http2StreamError); ok {
- if e.Cause != nil {
- err = e.Cause
- } else {
- err = http2errStreamClosed
- }
- }
- st.closeErr = err
- st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
- sc.writeSched.CloseStream(st.id)
-}
-
-func (sc *http2serverConn) processSettings(f *http2SettingsFrame) error {
- sc.serveG.check()
- if f.IsAck() {
- sc.unackedSettings--
- if sc.unackedSettings < 0 {
- // Why is the peer ACKing settings we never sent?
- // The spec doesn't mention this case, but
- // hang up on them anyway.
- return sc.countError("ack_mystery", http2ConnectionError(http2ErrCodeProtocol))
- }
- return nil
- }
- if f.NumSettings() > 100 || f.HasDuplicates() {
- // This isn't actually in the spec, but hang up on
- // suspiciously large settings frames or those with
- // duplicate entries.
- return sc.countError("settings_big_or_dups", http2ConnectionError(http2ErrCodeProtocol))
- }
- if err := f.ForeachSetting(sc.processSetting); err != nil {
- return err
- }
- // TODO: judging by RFC 7540, Section 6.5.3 each SETTINGS frame should be
- // acknowledged individually, even if multiple are received before the ACK.
- sc.needToSendSettingsAck = true
- sc.scheduleFrameWrite()
- return nil
-}
-
-func (sc *http2serverConn) processSetting(s http2Setting) error {
- sc.serveG.check()
- if err := s.Valid(); err != nil {
- return err
- }
- if http2VerboseLogs {
- sc.vlogf("http2: server processing setting %v", s)
- }
- switch s.ID {
- case http2SettingHeaderTableSize:
- sc.hpackEncoder.SetMaxDynamicTableSize(s.Val)
- case http2SettingEnablePush:
- sc.pushEnabled = s.Val != 0
- case http2SettingMaxConcurrentStreams:
- sc.clientMaxStreams = s.Val
- case http2SettingInitialWindowSize:
- return sc.processSettingInitialWindowSize(s.Val)
- case http2SettingMaxFrameSize:
- sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31
- case http2SettingMaxHeaderListSize:
- sc.peerMaxHeaderListSize = s.Val
- default:
- // Unknown setting: "An endpoint that receives a SETTINGS
- // frame with any unknown or unsupported identifier MUST
- // ignore that setting."
- if http2VerboseLogs {
- sc.vlogf("http2: server ignoring unknown setting %v", s)
- }
- }
- return nil
-}
-
-func (sc *http2serverConn) processSettingInitialWindowSize(val uint32) error {
- sc.serveG.check()
- // Note: val already validated to be within range by
- // processSetting's Valid call.
-
- // "A SETTINGS frame can alter the initial flow control window
- // size for all current streams. When the value of
- // SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST
- // adjust the size of all stream flow control windows that it
- // maintains by the difference between the new value and the
- // old value."
- old := sc.initialStreamSendWindowSize
- sc.initialStreamSendWindowSize = int32(val)
- growth := int32(val) - old // may be negative
- for _, st := range sc.streams {
- if !st.flow.add(growth) {
- // 6.9.2 Initial Flow Control Window Size
- // "An endpoint MUST treat a change to
- // SETTINGS_INITIAL_WINDOW_SIZE that causes any flow
- // control window to exceed the maximum size as a
- // connection error (Section 5.4.1) of type
- // FLOW_CONTROL_ERROR."
- return sc.countError("setting_win_size", http2ConnectionError(http2ErrCodeFlowControl))
- }
- }
- return nil
-}
-
-func (sc *http2serverConn) processData(f *http2DataFrame) error {
- sc.serveG.check()
- id := f.Header().StreamID
-
- data := f.Data()
- state, st := sc.state(id)
- if id == 0 || state == http2stateIdle {
- // Section 6.1: "DATA frames MUST be associated with a
- // stream. If a DATA frame is received whose stream
- // identifier field is 0x0, the recipient MUST respond
- // with a connection error (Section 5.4.1) of type
- // PROTOCOL_ERROR."
- //
- // Section 5.1: "Receiving any frame other than HEADERS
- // or PRIORITY on a stream in this state MUST be
- // treated as a connection error (Section 5.4.1) of
- // type PROTOCOL_ERROR."
- return sc.countError("data_on_idle", http2ConnectionError(http2ErrCodeProtocol))
- }
-
- // "If a DATA frame is received whose stream is not in "open"
- // or "half closed (local)" state, the recipient MUST respond
- // with a stream error (Section 5.4.2) of type STREAM_CLOSED."
- if st == nil || state != http2stateOpen || st.gotTrailerHeader || st.resetQueued {
- // This includes sending a RST_STREAM if the stream is
- // in stateHalfClosedLocal (which currently means that
- // the http.Handler returned, so it's done reading &
- // done writing). Try to stop the client from sending
- // more DATA.
-
- // But still enforce their connection-level flow control,
- // and return any flow control bytes since we're not going
- // to consume them.
- if sc.inflow.available() < int32(f.Length) {
- return sc.countError("data_flow", http2streamError(id, http2ErrCodeFlowControl))
- }
- // Deduct the flow control from inflow, since we're
- // going to immediately add it back in
- // sendWindowUpdate, which also schedules sending the
- // frames.
- sc.inflow.take(int32(f.Length))
- sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
-
- if st != nil && st.resetQueued {
- // Already have a stream error in flight. Don't send another.
- return nil
- }
- return sc.countError("closed", http2streamError(id, http2ErrCodeStreamClosed))
- }
- if st.body == nil {
- panic("internal error: should have a body in this state")
- }
-
- // Sender sending more than they'd declared?
- if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
- if sc.inflow.available() < int32(f.Length) {
- return sc.countError("data_flow", http2streamError(id, http2ErrCodeFlowControl))
- }
- sc.inflow.take(int32(f.Length))
- sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
-
- st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
- // RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
- // value of a content-length header field does not equal the sum of the
- // DATA frame payload lengths that form the body.
- return sc.countError("send_too_much", http2streamError(id, http2ErrCodeProtocol))
- }
- if f.Length > 0 {
- // Check whether the client has flow control quota.
- if st.inflow.available() < int32(f.Length) {
- return sc.countError("flow_on_data_length", http2streamError(id, http2ErrCodeFlowControl))
- }
- st.inflow.take(int32(f.Length))
-
- if len(data) > 0 {
- wrote, err := st.body.Write(data)
- if err != nil {
- sc.sendWindowUpdate(nil, int(f.Length)-wrote)
- return sc.countError("body_write_err", http2streamError(id, http2ErrCodeStreamClosed))
- }
- if wrote != len(data) {
- panic("internal error: bad Writer")
- }
- st.bodyBytes += int64(len(data))
- }
-
- // Return any padded flow control now, since we won't
- // refund it later on body reads.
- if pad := int32(f.Length) - int32(len(data)); pad > 0 {
- sc.sendWindowUpdate32(nil, pad)
- sc.sendWindowUpdate32(st, pad)
- }
- }
- if f.StreamEnded() {
- st.endStream()
- }
- return nil
-}
-
-func (sc *http2serverConn) processGoAway(f *http2GoAwayFrame) error {
- sc.serveG.check()
- if f.ErrCode != http2ErrCodeNo {
- sc.logf("http2: received GOAWAY %+v, starting graceful shutdown", f)
- } else {
- sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f)
- }
- sc.startGracefulShutdownInternal()
- // http://tools.ietf.org/html/rfc7540#section-6.8
- // We should not create any new streams, which means we should disable push.
- sc.pushEnabled = false
- return nil
-}
-
-// isPushed reports whether the stream is server-initiated.
-func (st *http2stream) isPushed() bool {
- return st.id%2 == 0
-}
-
-// endStream closes a Request.Body's pipe. It is called when a DATA
-// frame says a request body is over (or after trailers).
-func (st *http2stream) endStream() {
- sc := st.sc
- sc.serveG.check()
-
- if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes {
- st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes",
- st.declBodyBytes, st.bodyBytes))
- } else {
- st.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest)
- st.body.CloseWithError(io.EOF)
- }
- st.state = http2stateHalfClosedRemote
-}
-
-// copyTrailersToHandlerRequest is run in the Handler's goroutine in
-// its Request.Body.Read just before it gets io.EOF.
-func (st *http2stream) copyTrailersToHandlerRequest() {
- for k, vv := range st.trailer {
- if _, ok := st.reqTrailer[k]; ok {
- // Only copy it over it was pre-declared.
- st.reqTrailer[k] = vv
- }
- }
-}
-
-// onReadTimeout is run on its own goroutine (from time.AfterFunc)
-// when the stream's ReadTimeout has fired.
-func (st *http2stream) onReadTimeout() {
- // Wrap the ErrDeadlineExceeded to avoid callers depending on us
- // returning the bare error.
- st.body.CloseWithError(fmt.Errorf("%w", os.ErrDeadlineExceeded))
-}
-
-// onWriteTimeout is run on its own goroutine (from time.AfterFunc)
-// when the stream's WriteTimeout has fired.
-func (st *http2stream) onWriteTimeout() {
- st.sc.writeFrameFromHandler(http2FrameWriteRequest{write: http2StreamError{
- StreamID: st.id,
- Code: http2ErrCodeInternal,
- Cause: os.ErrDeadlineExceeded,
- }})
-}
-
-func (sc *http2serverConn) processHeaders(f *http2MetaHeadersFrame) error {
- sc.serveG.check()
- id := f.StreamID
- // http://tools.ietf.org/html/rfc7540#section-5.1.1
- // Streams initiated by a client MUST use odd-numbered stream
- // identifiers. [...] An endpoint that receives an unexpected
- // stream identifier MUST respond with a connection error
- // (Section 5.4.1) of type PROTOCOL_ERROR.
- if id%2 != 1 {
- return sc.countError("headers_even", http2ConnectionError(http2ErrCodeProtocol))
- }
- // A HEADERS frame can be used to create a new stream or
- // send a trailer for an open one. If we already have a stream
- // open, let it process its own HEADERS frame (trailers at this
- // point, if it's valid).
- if st := sc.streams[f.StreamID]; st != nil {
- if st.resetQueued {
- // We're sending RST_STREAM to close the stream, so don't bother
- // processing this frame.
- return nil
- }
- // RFC 7540, sec 5.1: If an endpoint receives additional frames, other than
- // WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in
- // this state, it MUST respond with a stream error (Section 5.4.2) of
- // type STREAM_CLOSED.
- if st.state == http2stateHalfClosedRemote {
- return sc.countError("headers_half_closed", http2streamError(id, http2ErrCodeStreamClosed))
- }
- return st.processTrailerHeaders(f)
- }
-
- // [...] The identifier of a newly established stream MUST be
- // numerically greater than all streams that the initiating
- // endpoint has opened or reserved. [...] An endpoint that
- // receives an unexpected stream identifier MUST respond with
- // a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
- if id <= sc.maxClientStreamID {
- return sc.countError("stream_went_down", http2ConnectionError(http2ErrCodeProtocol))
- }
- sc.maxClientStreamID = id
-
- if sc.idleTimer != nil {
- sc.idleTimer.Stop()
- }
-
- // http://tools.ietf.org/html/rfc7540#section-5.1.2
- // [...] Endpoints MUST NOT exceed the limit set by their peer. An
- // endpoint that receives a HEADERS frame that causes their
- // advertised concurrent stream limit to be exceeded MUST treat
- // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR
- // or REFUSED_STREAM.
- if sc.curClientStreams+1 > sc.advMaxStreams {
- if sc.unackedSettings == 0 {
- // They should know better.
- return sc.countError("over_max_streams", http2streamError(id, http2ErrCodeProtocol))
- }
- // Assume it's a network race, where they just haven't
- // received our last SETTINGS update. But actually
- // this can't happen yet, because we don't yet provide
- // a way for users to adjust server parameters at
- // runtime.
- return sc.countError("over_max_streams_race", http2streamError(id, http2ErrCodeRefusedStream))
- }
-
- initialState := http2stateOpen
- if f.StreamEnded() {
- initialState = http2stateHalfClosedRemote
- }
- st := sc.newStream(id, 0, initialState)
-
- if f.HasPriority() {
- if err := sc.checkPriority(f.StreamID, f.Priority); err != nil {
- return err
- }
- sc.writeSched.AdjustStream(st.id, f.Priority)
- }
-
- rw, req, err := sc.newWriterAndRequest(st, f)
- if err != nil {
- return err
- }
- st.reqTrailer = req.Trailer
- if st.reqTrailer != nil {
- st.trailer = make(Header)
- }
- st.body = req.Body.(*http2requestBody).pipe // may be nil
- st.declBodyBytes = req.ContentLength
-
- handler := sc.handler.ServeHTTP
- if f.Truncated {
- // Their header list was too long. Send a 431 error.
- handler = http2handleHeaderListTooLong
- } else if err := http2checkValidHTTP2RequestHeaders(req.Header); err != nil {
- handler = http2new400Handler(err)
- }
-
- // The net/http package sets the read deadline from the
- // http.Server.ReadTimeout during the TLS handshake, but then
- // passes the connection off to us with the deadline already
- // set. Disarm it here after the request headers are read,
- // similar to how the http1 server works. Here it's
- // technically more like the http1 Server's ReadHeaderTimeout
- // (in Go 1.8), though. That's a more sane option anyway.
- if sc.hs.ReadTimeout != 0 {
- sc.conn.SetReadDeadline(time.Time{})
- if st.body != nil {
- st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
- }
- }
-
- go sc.runHandler(rw, req, handler)
- return nil
-}
-
-func (sc *http2serverConn) upgradeRequest(req *Request) {
- sc.serveG.check()
- id := uint32(1)
- sc.maxClientStreamID = id
- st := sc.newStream(id, 0, http2stateHalfClosedRemote)
- st.reqTrailer = req.Trailer
- if st.reqTrailer != nil {
- st.trailer = make(Header)
- }
- rw := sc.newResponseWriter(st, req)
-
- // Disable any read deadline set by the net/http package
- // prior to the upgrade.
- if sc.hs.ReadTimeout != 0 {
- sc.conn.SetReadDeadline(time.Time{})
- }
-
- go sc.runHandler(rw, req, sc.handler.ServeHTTP)
-}
-
-func (st *http2stream) processTrailerHeaders(f *http2MetaHeadersFrame) error {
- sc := st.sc
- sc.serveG.check()
- if st.gotTrailerHeader {
- return sc.countError("dup_trailers", http2ConnectionError(http2ErrCodeProtocol))
- }
- st.gotTrailerHeader = true
- if !f.StreamEnded() {
- return sc.countError("trailers_not_ended", http2streamError(st.id, http2ErrCodeProtocol))
- }
-
- if len(f.PseudoFields()) > 0 {
- return sc.countError("trailers_pseudo", http2streamError(st.id, http2ErrCodeProtocol))
- }
- if st.trailer != nil {
- for _, hf := range f.RegularFields() {
- key := sc.canonicalHeader(hf.Name)
- if !httpguts.ValidTrailerHeader(key) {
- // TODO: send more details to the peer somehow. But http2 has
- // no way to send debug data at a stream level. Discuss with
- // HTTP folk.
- return sc.countError("trailers_bogus", http2streamError(st.id, http2ErrCodeProtocol))
- }
- st.trailer[key] = append(st.trailer[key], hf.Value)
- }
- }
- st.endStream()
- return nil
-}
-
-func (sc *http2serverConn) checkPriority(streamID uint32, p http2PriorityParam) error {
- if streamID == p.StreamDep {
- // Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat
- // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR."
- // Section 5.3.3 says that a stream can depend on one of its dependencies,
- // so it's only self-dependencies that are forbidden.
- return sc.countError("priority", http2streamError(streamID, http2ErrCodeProtocol))
- }
- return nil
-}
-
-func (sc *http2serverConn) processPriority(f *http2PriorityFrame) error {
- if err := sc.checkPriority(f.StreamID, f.http2PriorityParam); err != nil {
- return err
- }
- sc.writeSched.AdjustStream(f.StreamID, f.http2PriorityParam)
- return nil
-}
-
-func (sc *http2serverConn) newStream(id, pusherID uint32, state http2streamState) *http2stream {
- sc.serveG.check()
- if id == 0 {
- panic("internal error: cannot create stream with id 0")
- }
-
- ctx, cancelCtx := context.WithCancel(sc.baseCtx)
- st := &http2stream{
- sc: sc,
- id: id,
- state: state,
- ctx: ctx,
- cancelCtx: cancelCtx,
- }
- st.cw.Init()
- st.flow.conn = &sc.flow // link to conn-level counter
- st.flow.add(sc.initialStreamSendWindowSize)
- st.inflow.conn = &sc.inflow // link to conn-level counter
- st.inflow.add(sc.srv.initialStreamRecvWindowSize())
- if sc.hs.WriteTimeout != 0 {
- st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
- }
-
- sc.streams[id] = st
- sc.writeSched.OpenStream(st.id, http2OpenStreamOptions{PusherID: pusherID})
- if st.isPushed() {
- sc.curPushedStreams++
- } else {
- sc.curClientStreams++
- }
- if sc.curOpenStreams() == 1 {
- sc.setConnState(StateActive)
- }
-
- return st
-}
-
-func (sc *http2serverConn) newWriterAndRequest(st *http2stream, f *http2MetaHeadersFrame) (*http2responseWriter, *Request, error) {
- sc.serveG.check()
-
- rp := http2requestParam{
- method: f.PseudoValue("method"),
- scheme: f.PseudoValue("scheme"),
- authority: f.PseudoValue("authority"),
- path: f.PseudoValue("path"),
- }
-
- isConnect := rp.method == "CONNECT"
- if isConnect {
- if rp.path != "" || rp.scheme != "" || rp.authority == "" {
- return nil, nil, sc.countError("bad_connect", http2streamError(f.StreamID, http2ErrCodeProtocol))
- }
- } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
- // See 8.1.2.6 Malformed Requests and Responses:
- //
- // Malformed requests or responses that are detected
- // MUST be treated as a stream error (Section 5.4.2)
- // of type PROTOCOL_ERROR."
- //
- // 8.1.2.3 Request Pseudo-Header Fields
- // "All HTTP/2 requests MUST include exactly one valid
- // value for the :method, :scheme, and :path
- // pseudo-header fields"
- return nil, nil, sc.countError("bad_path_method", http2streamError(f.StreamID, http2ErrCodeProtocol))
- }
-
- rp.header = make(Header)
- for _, hf := range f.RegularFields() {
- rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
- }
- if rp.authority == "" {
- rp.authority = rp.header.Get("Host")
- }
-
- rw, req, err := sc.newWriterAndRequestNoBody(st, rp)
- if err != nil {
- return nil, nil, err
- }
- bodyOpen := !f.StreamEnded()
- if bodyOpen {
- if vv, ok := rp.header["Content-Length"]; ok {
- if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {
- req.ContentLength = int64(cl)
- } else {
- req.ContentLength = 0
- }
- } else {
- req.ContentLength = -1
- }
- req.Body.(*http2requestBody).pipe = &http2pipe{
- b: &http2dataBuffer{expected: req.ContentLength},
- }
- }
- return rw, req, nil
-}
-
-type http2requestParam struct {
- method string
- scheme, authority, path string
- header Header
-}
-
-func (sc *http2serverConn) newWriterAndRequestNoBody(st *http2stream, rp http2requestParam) (*http2responseWriter, *Request, error) {
- sc.serveG.check()
-
- var tlsState *tls.ConnectionState // nil if not scheme https
- if rp.scheme == "https" {
- tlsState = sc.tlsState
- }
-
- needsContinue := rp.header.Get("Expect") == "100-continue"
- if needsContinue {
- rp.header.Del("Expect")
- }
- // Merge Cookie headers into one "; "-delimited value.
- if cookies := rp.header["Cookie"]; len(cookies) > 1 {
- rp.header.Set("Cookie", strings.Join(cookies, "; "))
- }
-
- // Setup Trailers
- var trailer Header
- for _, v := range rp.header["Trailer"] {
- for _, key := range strings.Split(v, ",") {
- key = CanonicalHeaderKey(textproto.TrimString(key))
- switch key {
- case "Transfer-Encoding", "Trailer", "Content-Length":
- // Bogus. (copy of http1 rules)
- // Ignore.
- default:
- if trailer == nil {
- trailer = make(Header)
- }
- trailer[key] = nil
- }
- }
- }
- delete(rp.header, "Trailer")
-
- var url_ *url.URL
- var requestURI string
- if rp.method == "CONNECT" {
- url_ = &url.URL{Host: rp.authority}
- requestURI = rp.authority // mimic HTTP/1 server behavior
- } else {
- var err error
- url_, err = url.ParseRequestURI(rp.path)
- if err != nil {
- return nil, nil, sc.countError("bad_path", http2streamError(st.id, http2ErrCodeProtocol))
- }
- requestURI = rp.path
- }
-
- body := &http2requestBody{
- conn: sc,
- stream: st,
- needsContinue: needsContinue,
- }
- req := &Request{
- Method: rp.method,
- URL: url_,
- RemoteAddr: sc.remoteAddrStr,
- Header: rp.header,
- RequestURI: requestURI,
- Proto: "HTTP/2.0",
- ProtoMajor: 2,
- ProtoMinor: 0,
- TLS: tlsState,
- Host: rp.authority,
- Body: body,
- Trailer: trailer,
- }
- req = req.WithContext(st.ctx)
-
- rw := sc.newResponseWriter(st, req)
- return rw, req, nil
-}
-
-func (sc *http2serverConn) newResponseWriter(st *http2stream, req *Request) *http2responseWriter {
- rws := http2responseWriterStatePool.Get().(*http2responseWriterState)
- bwSave := rws.bw
- *rws = http2responseWriterState{} // zero all the fields
- rws.conn = sc
- rws.bw = bwSave
- rws.bw.Reset(http2chunkWriter{rws})
- rws.stream = st
- rws.req = req
- return &http2responseWriter{rws: rws}
-}
-
-// Run on its own goroutine.
-func (sc *http2serverConn) runHandler(rw *http2responseWriter, req *Request, handler func(ResponseWriter, *Request)) {
- didPanic := true
- defer func() {
- rw.rws.stream.cancelCtx()
- if req.MultipartForm != nil {
- req.MultipartForm.RemoveAll()
- }
- if didPanic {
- e := recover()
- sc.writeFrameFromHandler(http2FrameWriteRequest{
- write: http2handlerPanicRST{rw.rws.stream.id},
- stream: rw.rws.stream,
- })
- // Same as net/http:
- if e != nil && e != ErrAbortHandler {
- const size = 64 << 10
- buf := make([]byte, size)
- buf = buf[:runtime.Stack(buf, false)]
- sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
- }
- return
- }
- rw.handlerDone()
- }()
- handler(rw, req)
- didPanic = false
-}
-
-func http2handleHeaderListTooLong(w ResponseWriter, r *Request) {
- // 10.5.1 Limits on Header Block Size:
- // .. "A server that receives a larger header block than it is
- // willing to handle can send an HTTP 431 (Request Header Fields Too
- // Large) status code"
- const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+
- w.WriteHeader(statusRequestHeaderFieldsTooLarge)
- io.WriteString(w, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>")
-}
-
-// called from handler goroutines.
-// h may be nil.
-func (sc *http2serverConn) writeHeaders(st *http2stream, headerData *http2writeResHeaders) error {
- sc.serveG.checkNotOn() // NOT on
- var errc chan error
- if headerData.h != nil {
- // If there's a header map (which we don't own), so we have to block on
- // waiting for this frame to be written, so an http.Flush mid-handler
- // writes out the correct value of keys, before a handler later potentially
- // mutates it.
- errc = http2errChanPool.Get().(chan error)
- }
- if err := sc.writeFrameFromHandler(http2FrameWriteRequest{
- write: headerData,
- stream: st,
- done: errc,
- }); err != nil {
- return err
- }
- if errc != nil {
- select {
- case err := <-errc:
- http2errChanPool.Put(errc)
- return err
- case <-sc.doneServing:
- return http2errClientDisconnected
- case <-st.cw:
- return http2errStreamClosed
- }
- }
- return nil
-}
-
-// called from handler goroutines.
-func (sc *http2serverConn) write100ContinueHeaders(st *http2stream) {
- sc.writeFrameFromHandler(http2FrameWriteRequest{
- write: http2write100ContinueHeadersFrame{st.id},
- stream: st,
- })
-}
-
-// A bodyReadMsg tells the server loop that the http.Handler read n
-// bytes of the DATA from the client on the given stream.
-type http2bodyReadMsg struct {
- st *http2stream
- n int
-}
-
-// called from handler goroutines.
-// Notes that the handler for the given stream ID read n bytes of its body
-// and schedules flow control tokens to be sent.
-func (sc *http2serverConn) noteBodyReadFromHandler(st *http2stream, n int, err error) {
- sc.serveG.checkNotOn() // NOT on
- if n > 0 {
- select {
- case sc.bodyReadCh <- http2bodyReadMsg{st, n}:
- case <-sc.doneServing:
- }
- }
-}
-
-func (sc *http2serverConn) noteBodyRead(st *http2stream, n int) {
- sc.serveG.check()
- sc.sendWindowUpdate(nil, n) // conn-level
- if st.state != http2stateHalfClosedRemote && st.state != http2stateClosed {
- // Don't send this WINDOW_UPDATE if the stream is closed
- // remotely.
- sc.sendWindowUpdate(st, n)
- }
-}
-
-// st may be nil for conn-level
-func (sc *http2serverConn) sendWindowUpdate(st *http2stream, n int) {
- sc.serveG.check()
- // "The legal range for the increment to the flow control
- // window is 1 to 2^31-1 (2,147,483,647) octets."
- // A Go Read call on 64-bit machines could in theory read
- // a larger Read than this. Very unlikely, but we handle it here
- // rather than elsewhere for now.
- const maxUint31 = 1<<31 - 1
- for n > maxUint31 {
- sc.sendWindowUpdate32(st, maxUint31)
- n -= maxUint31
- }
- sc.sendWindowUpdate32(st, int32(n))
-}
-
-// st may be nil for conn-level
-func (sc *http2serverConn) sendWindowUpdate32(st *http2stream, n int32) {
- sc.serveG.check()
- if n == 0 {
- return
- }
- if n < 0 {
- panic("negative update")
- }
- var streamID uint32
- if st != nil {
- streamID = st.id
- }
- sc.writeFrame(http2FrameWriteRequest{
- write: http2writeWindowUpdate{streamID: streamID, n: uint32(n)},
- stream: st,
- })
- var ok bool
- if st == nil {
- ok = sc.inflow.add(n)
- } else {
- ok = st.inflow.add(n)
- }
- if !ok {
- panic("internal error; sent too many window updates without decrements?")
- }
-}
-
-// requestBody is the Handler's Request.Body type.
-// Read and Close may be called concurrently.
-type http2requestBody struct {
- _ http2incomparable
- stream *http2stream
- conn *http2serverConn
- closeOnce sync.Once // for use by Close only
- sawEOF bool // for use by Read only
- pipe *http2pipe // non-nil if we have a HTTP entity message body
- needsContinue bool // need to send a 100-continue
-}
-
-func (b *http2requestBody) Close() error {
- b.closeOnce.Do(func() {
- if b.pipe != nil {
- b.pipe.BreakWithError(http2errClosedBody)
- }
- })
- return nil
-}
-
-func (b *http2requestBody) Read(p []byte) (n int, err error) {
- if b.needsContinue {
- b.needsContinue = false
- b.conn.write100ContinueHeaders(b.stream)
- }
- if b.pipe == nil || b.sawEOF {
- return 0, io.EOF
- }
- n, err = b.pipe.Read(p)
- if err == io.EOF {
- b.sawEOF = true
- }
- if b.conn == nil && http2inTests {
- return
- }
- b.conn.noteBodyReadFromHandler(b.stream, n, err)
- return
-}
-
-// responseWriter is the http.ResponseWriter implementation. It's
-// intentionally small (1 pointer wide) to minimize garbage. The
-// responseWriterState pointer inside is zeroed at the end of a
-// request (in handlerDone) and calls on the responseWriter thereafter
-// simply crash (caller's mistake), but the much larger responseWriterState
-// and buffers are reused between multiple requests.
-type http2responseWriter struct {
- rws *http2responseWriterState
-}
-
-// Optional http.ResponseWriter interfaces implemented.
-var (
- _ CloseNotifier = (*http2responseWriter)(nil)
- _ Flusher = (*http2responseWriter)(nil)
- _ http2stringWriter = (*http2responseWriter)(nil)
-)
-
-type http2responseWriterState struct {
- // immutable within a request:
- stream *http2stream
- req *Request
- conn *http2serverConn
-
- // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
- bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState}
-
- // mutated by http.Handler goroutine:
- handlerHeader Header // nil until called
- snapHeader Header // snapshot of handlerHeader at WriteHeader time
- trailers []string // set in writeChunk
- status int // status code passed to WriteHeader
- wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
- sentHeader bool // have we sent the header frame?
- handlerDone bool // handler has finished
- dirty bool // a Write failed; don't reuse this responseWriterState
-
- sentContentLen int64 // non-zero if handler set a Content-Length header
- wroteBytes int64
-
- closeNotifierMu sync.Mutex // guards closeNotifierCh
- closeNotifierCh chan bool // nil until first used
-}
-
-type http2chunkWriter struct{ rws *http2responseWriterState }
-
-func (cw http2chunkWriter) Write(p []byte) (n int, err error) {
- n, err = cw.rws.writeChunk(p)
- if err == http2errStreamClosed {
- // If writing failed because the stream has been closed,
- // return the reason it was closed.
- err = cw.rws.stream.closeErr
- }
- return n, err
-}
-
-func (rws *http2responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 }
-
-func (rws *http2responseWriterState) hasNonemptyTrailers() bool {
- for _, trailer := range rws.trailers {
- if _, ok := rws.handlerHeader[trailer]; ok {
- return true
- }
- }
- return false
-}
-
-// declareTrailer is called for each Trailer header when the
-// response header is written. It notes that a header will need to be
-// written in the trailers at the end of the response.
-func (rws *http2responseWriterState) declareTrailer(k string) {
- k = CanonicalHeaderKey(k)
- if !httpguts.ValidTrailerHeader(k) {
- // Forbidden by RFC 7230, section 4.1.2.
- rws.conn.logf("ignoring invalid trailer %q", k)
- return
- }
- if !http2strSliceContains(rws.trailers, k) {
- rws.trailers = append(rws.trailers, k)
- }
-}
-
-// writeChunk writes chunks from the bufio.Writer. But because
-// bufio.Writer may bypass its chunking, sometimes p may be
-// arbitrarily large.
-//
-// writeChunk is also responsible (on the first chunk) for sending the
-// HEADER response.
-func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) {
- if !rws.wroteHeader {
- rws.writeHeader(200)
- }
-
- if rws.handlerDone {
- rws.promoteUndeclaredTrailers()
- }
-
- isHeadResp := rws.req.Method == "HEAD"
- if !rws.sentHeader {
- rws.sentHeader = true
- var ctype, clen string
- if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
- rws.snapHeader.Del("Content-Length")
- if cl, err := strconv.ParseUint(clen, 10, 63); err == nil {
- rws.sentContentLen = int64(cl)
- } else {
- clen = ""
- }
- }
- if clen == "" && rws.handlerDone && http2bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
- clen = strconv.Itoa(len(p))
- }
- _, hasContentType := rws.snapHeader["Content-Type"]
- // If the Content-Encoding is non-blank, we shouldn't
- // sniff the body. See Issue golang.org/issue/31753.
- ce := rws.snapHeader.Get("Content-Encoding")
- hasCE := len(ce) > 0
- if !hasCE && !hasContentType && http2bodyAllowedForStatus(rws.status) && len(p) > 0 {
- ctype = DetectContentType(p)
- }
- var date string
- if _, ok := rws.snapHeader["Date"]; !ok {
- // TODO(bradfitz): be faster here, like net/http? measure.
- date = time.Now().UTC().Format(TimeFormat)
- }
-
- for _, v := range rws.snapHeader["Trailer"] {
- http2foreachHeaderElement(v, rws.declareTrailer)
- }
-
- // "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2),
- // but respect "Connection" == "close" to mean sending a GOAWAY and tearing
- // down the TCP connection when idle, like we do for HTTP/1.
- // TODO: remove more Connection-specific header fields here, in addition
- // to "Connection".
- if _, ok := rws.snapHeader["Connection"]; ok {
- v := rws.snapHeader.Get("Connection")
- delete(rws.snapHeader, "Connection")
- if v == "close" {
- rws.conn.startGracefulShutdown()
- }
- }
-
- endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
- err = rws.conn.writeHeaders(rws.stream, &http2writeResHeaders{
- streamID: rws.stream.id,
- httpResCode: rws.status,
- h: rws.snapHeader,
- endStream: endStream,
- contentType: ctype,
- contentLength: clen,
- date: date,
- })
- if err != nil {
- rws.dirty = true
- return 0, err
- }
- if endStream {
- return 0, nil
- }
- }
- if isHeadResp {
- return len(p), nil
- }
- if len(p) == 0 && !rws.handlerDone {
- return 0, nil
- }
-
- // only send trailers if they have actually been defined by the
- // server handler.
- hasNonemptyTrailers := rws.hasNonemptyTrailers()
- endStream := rws.handlerDone && !hasNonemptyTrailers
- if len(p) > 0 || endStream {
- // only send a 0 byte DATA frame if we're ending the stream.
- if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
- rws.dirty = true
- return 0, err
- }
- }
-
- if rws.handlerDone && hasNonemptyTrailers {
- err = rws.conn.writeHeaders(rws.stream, &http2writeResHeaders{
- streamID: rws.stream.id,
- h: rws.handlerHeader,
- trailers: rws.trailers,
- endStream: true,
- })
- if err != nil {
- rws.dirty = true
- }
- return len(p), err
- }
- return len(p), nil
-}
-
-// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
-// that, if present, signals that the map entry is actually for
-// the response trailers, and not the response headers. The prefix
-// is stripped after the ServeHTTP call finishes and the values are
-// sent in the trailers.
-//
-// This mechanism is intended only for trailers that are not known
-// prior to the headers being written. If the set of trailers is fixed
-// or known before the header is written, the normal Go trailers mechanism
-// is preferred:
-//
-// https://golang.org/pkg/net/http/#ResponseWriter
-// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
-const http2TrailerPrefix = "Trailer:"
-
-// promoteUndeclaredTrailers permits http.Handlers to set trailers
-// after the header has already been flushed. Because the Go
-// ResponseWriter interface has no way to set Trailers (only the
-// Header), and because we didn't want to expand the ResponseWriter
-// interface, and because nobody used trailers, and because RFC 7230
-// says you SHOULD (but not must) predeclare any trailers in the
-// header, the official ResponseWriter rules said trailers in Go must
-// be predeclared, and then we reuse the same ResponseWriter.Header()
-// map to mean both Headers and Trailers. When it's time to write the
-// Trailers, we pick out the fields of Headers that were declared as
-// trailers. That worked for a while, until we found the first major
-// user of Trailers in the wild: gRPC (using them only over http2),
-// and gRPC libraries permit setting trailers mid-stream without
-// predeclaring them. So: change of plans. We still permit the old
-// way, but we also permit this hack: if a Header() key begins with
-// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
-// invalid token byte anyway, there is no ambiguity. (And it's already
-// filtered out) It's mildly hacky, but not terrible.
-//
-// This method runs after the Handler is done and promotes any Header
-// fields to be trailers.
-func (rws *http2responseWriterState) promoteUndeclaredTrailers() {
- for k, vv := range rws.handlerHeader {
- if !strings.HasPrefix(k, http2TrailerPrefix) {
- continue
- }
- trailerKey := strings.TrimPrefix(k, http2TrailerPrefix)
- rws.declareTrailer(trailerKey)
- rws.handlerHeader[CanonicalHeaderKey(trailerKey)] = vv
- }
-
- if len(rws.trailers) > 1 {
- sorter := http2sorterPool.Get().(*http2sorter)
- sorter.SortStrings(rws.trailers)
- http2sorterPool.Put(sorter)
- }
-}
-
-func (w *http2responseWriter) SetReadDeadline(deadline time.Time) error {
- st := w.rws.stream
- if !deadline.IsZero() && deadline.Before(time.Now()) {
- // If we're setting a deadline in the past, reset the stream immediately
- // so writes after SetWriteDeadline returns will fail.
- st.onReadTimeout()
- return nil
- }
- w.rws.conn.sendServeMsg(func(sc *http2serverConn) {
- if st.readDeadline != nil {
- if !st.readDeadline.Stop() {
- // Deadline already exceeded, or stream has been closed.
- return
- }
- }
- if deadline.IsZero() {
- st.readDeadline = nil
- } else if st.readDeadline == nil {
- st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout)
- } else {
- st.readDeadline.Reset(deadline.Sub(time.Now()))
- }
- })
- return nil
-}
-
-func (w *http2responseWriter) SetWriteDeadline(deadline time.Time) error {
- st := w.rws.stream
- if !deadline.IsZero() && deadline.Before(time.Now()) {
- // If we're setting a deadline in the past, reset the stream immediately
- // so writes after SetWriteDeadline returns will fail.
- st.onWriteTimeout()
- return nil
- }
- w.rws.conn.sendServeMsg(func(sc *http2serverConn) {
- if st.writeDeadline != nil {
- if !st.writeDeadline.Stop() {
- // Deadline already exceeded, or stream has been closed.
- return
- }
- }
- if deadline.IsZero() {
- st.writeDeadline = nil
- } else if st.writeDeadline == nil {
- st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout)
- } else {
- st.writeDeadline.Reset(deadline.Sub(time.Now()))
- }
- })
- return nil
-}
-
-func (w *http2responseWriter) Flush() {
- w.FlushError()
-}
-
-func (w *http2responseWriter) FlushError() error {
- rws := w.rws
- if rws == nil {
- panic("Header called after Handler finished")
- }
- var err error
- if rws.bw.Buffered() > 0 {
- err = rws.bw.Flush()
- } else {
- // The bufio.Writer won't call chunkWriter.Write
- // (writeChunk with zero bytes, so we have to do it
- // ourselves to force the HTTP response header and/or
- // final DATA frame (with END_STREAM) to be sent.
- _, err = http2chunkWriter{rws}.Write(nil)
- if err == nil {
- select {
- case <-rws.stream.cw:
- err = rws.stream.closeErr
- default:
- }
- }
- }
- return err
-}
-
-func (w *http2responseWriter) CloseNotify() <-chan bool {
- rws := w.rws
- if rws == nil {
- panic("CloseNotify called after Handler finished")
- }
- rws.closeNotifierMu.Lock()
- ch := rws.closeNotifierCh
- if ch == nil {
- ch = make(chan bool, 1)
- rws.closeNotifierCh = ch
- cw := rws.stream.cw
- go func() {
- cw.Wait() // wait for close
- ch <- true
- }()
- }
- rws.closeNotifierMu.Unlock()
- return ch
-}
-
-func (w *http2responseWriter) Header() Header {
- rws := w.rws
- if rws == nil {
- panic("Header called after Handler finished")
- }
- if rws.handlerHeader == nil {
- rws.handlerHeader = make(Header)
- }
- return rws.handlerHeader
-}
-
-// checkWriteHeaderCode is a copy of net/http's checkWriteHeaderCode.
-func http2checkWriteHeaderCode(code int) {
- // Issue 22880: require valid WriteHeader status codes.
- // For now we only enforce that it's three digits.
- // In the future we might block things over 599 (600 and above aren't defined
- // at http://httpwg.org/specs/rfc7231.html#status.codes).
- // But for now any three digits.
- //
- // We used to send "HTTP/1.1 000 0" on the wire in responses but there's
- // no equivalent bogus thing we can realistically send in HTTP/2,
- // so we'll consistently panic instead and help people find their bugs
- // early. (We can't return an error from WriteHeader even if we wanted to.)
- if code < 100 || code > 999 {
- panic(fmt.Sprintf("invalid WriteHeader code %v", code))
- }
-}
-
-func (w *http2responseWriter) WriteHeader(code int) {
- rws := w.rws
- if rws == nil {
- panic("WriteHeader called after Handler finished")
- }
- rws.writeHeader(code)
-}
-
-func (rws *http2responseWriterState) writeHeader(code int) {
- if rws.wroteHeader {
- return
- }
-
- http2checkWriteHeaderCode(code)
-
- // Handle informational headers
- if code >= 100 && code <= 199 {
- // Per RFC 8297 we must not clear the current header map
- h := rws.handlerHeader
-
- _, cl := h["Content-Length"]
- _, te := h["Transfer-Encoding"]
- if cl || te {
- h = h.Clone()
- h.Del("Content-Length")
- h.Del("Transfer-Encoding")
- }
-
- if rws.conn.writeHeaders(rws.stream, &http2writeResHeaders{
- streamID: rws.stream.id,
- httpResCode: code,
- h: h,
- endStream: rws.handlerDone && !rws.hasTrailers(),
- }) != nil {
- rws.dirty = true
- }
-
- return
- }
-
- rws.wroteHeader = true
- rws.status = code
- if len(rws.handlerHeader) > 0 {
- rws.snapHeader = http2cloneHeader(rws.handlerHeader)
- }
-}
-
-func http2cloneHeader(h Header) Header {
- h2 := make(Header, len(h))
- for k, vv := range h {
- vv2 := make([]string, len(vv))
- copy(vv2, vv)
- h2[k] = vv2
- }
- return h2
-}
-
-// The Life Of A Write is like this:
-//
-// * Handler calls w.Write or w.WriteString ->
-// * -> rws.bw (*bufio.Writer) ->
-// * (Handler might call Flush)
-// * -> chunkWriter{rws}
-// * -> responseWriterState.writeChunk(p []byte)
-// * -> responseWriterState.writeChunk (most of the magic; see comment there)
-func (w *http2responseWriter) Write(p []byte) (n int, err error) {
- return w.write(len(p), p, "")
-}
-
-func (w *http2responseWriter) WriteString(s string) (n int, err error) {
- return w.write(len(s), nil, s)
-}
-
-// either dataB or dataS is non-zero.
-func (w *http2responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) {
- rws := w.rws
- if rws == nil {
- panic("Write called after Handler finished")
- }
- if !rws.wroteHeader {
- w.WriteHeader(200)
- }
- if !http2bodyAllowedForStatus(rws.status) {
- return 0, ErrBodyNotAllowed
- }
- rws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set
- if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen {
- // TODO: send a RST_STREAM
- return 0, errors.New("http2: handler wrote more than declared Content-Length")
- }
-
- if dataB != nil {
- return rws.bw.Write(dataB)
- } else {
- return rws.bw.WriteString(dataS)
- }
-}
-
-func (w *http2responseWriter) handlerDone() {
- rws := w.rws
- dirty := rws.dirty
- rws.handlerDone = true
- w.Flush()
- w.rws = nil
- if !dirty {
- // Only recycle the pool if all prior Write calls to
- // the serverConn goroutine completed successfully. If
- // they returned earlier due to resets from the peer
- // there might still be write goroutines outstanding
- // from the serverConn referencing the rws memory. See
- // issue 20704.
- http2responseWriterStatePool.Put(rws)
- }
-}
-
-// Push errors.
-var (
- http2ErrRecursivePush = errors.New("http2: recursive push not allowed")
- http2ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
-)
-
-var _ Pusher = (*http2responseWriter)(nil)
-
-func (w *http2responseWriter) Push(target string, opts *PushOptions) error {
- st := w.rws.stream
- sc := st.sc
- sc.serveG.checkNotOn()
-
- // No recursive pushes: "PUSH_PROMISE frames MUST only be sent on a peer-initiated stream."
- // http://tools.ietf.org/html/rfc7540#section-6.6
- if st.isPushed() {
- return http2ErrRecursivePush
- }
-
- if opts == nil {
- opts = new(PushOptions)
- }
-
- // Default options.
- if opts.Method == "" {
- opts.Method = "GET"
- }
- if opts.Header == nil {
- opts.Header = Header{}
- }
- wantScheme := "http"
- if w.rws.req.TLS != nil {
- wantScheme = "https"
- }
-
- // Validate the request.
- u, err := url.Parse(target)
- if err != nil {
- return err
- }
- if u.Scheme == "" {
- if !strings.HasPrefix(target, "/") {
- return fmt.Errorf("target must be an absolute URL or an absolute path: %q", target)
- }
- u.Scheme = wantScheme
- u.Host = w.rws.req.Host
- } else {
- if u.Scheme != wantScheme {
- return fmt.Errorf("cannot push URL with scheme %q from request with scheme %q", u.Scheme, wantScheme)
- }
- if u.Host == "" {
- return errors.New("URL must have a host")
- }
- }
- for k := range opts.Header {
- if strings.HasPrefix(k, ":") {
- return fmt.Errorf("promised request headers cannot include pseudo header %q", k)
- }
- // These headers are meaningful only if the request has a body,
- // but PUSH_PROMISE requests cannot have a body.
- // http://tools.ietf.org/html/rfc7540#section-8.2
- // Also disallow Host, since the promised URL must be absolute.
- if http2asciiEqualFold(k, "content-length") ||
- http2asciiEqualFold(k, "content-encoding") ||
- http2asciiEqualFold(k, "trailer") ||
- http2asciiEqualFold(k, "te") ||
- http2asciiEqualFold(k, "expect") ||
- http2asciiEqualFold(k, "host") {
- return fmt.Errorf("promised request headers cannot include %q", k)
- }
- }
- if err := http2checkValidHTTP2RequestHeaders(opts.Header); err != nil {
- return err
- }
-
- // The RFC effectively limits promised requests to GET and HEAD:
- // "Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]"
- // http://tools.ietf.org/html/rfc7540#section-8.2
- if opts.Method != "GET" && opts.Method != "HEAD" {
- return fmt.Errorf("method %q must be GET or HEAD", opts.Method)
- }
-
- msg := &http2startPushRequest{
- parent: st,
- method: opts.Method,
- url: u,
- header: http2cloneHeader(opts.Header),
- done: http2errChanPool.Get().(chan error),
- }
-
- select {
- case <-sc.doneServing:
- return http2errClientDisconnected
- case <-st.cw:
- return http2errStreamClosed
- case sc.serveMsgCh <- msg:
- }
-
- select {
- case <-sc.doneServing:
- return http2errClientDisconnected
- case <-st.cw:
- return http2errStreamClosed
- case err := <-msg.done:
- http2errChanPool.Put(msg.done)
- return err
- }
-}
-
-type http2startPushRequest struct {
- parent *http2stream
- method string
- url *url.URL
- header Header
- done chan error
-}
-
-func (sc *http2serverConn) startPush(msg *http2startPushRequest) {
- sc.serveG.check()
-
- // http://tools.ietf.org/html/rfc7540#section-6.6.
- // PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that
- // is in either the "open" or "half-closed (remote)" state.
- if msg.parent.state != http2stateOpen && msg.parent.state != http2stateHalfClosedRemote {
- // responseWriter.Push checks that the stream is peer-initiated.
- msg.done <- http2errStreamClosed
- return
- }
-
- // http://tools.ietf.org/html/rfc7540#section-6.6.
- if !sc.pushEnabled {
- msg.done <- ErrNotSupported
- return
- }
-
- // PUSH_PROMISE frames must be sent in increasing order by stream ID, so
- // we allocate an ID for the promised stream lazily, when the PUSH_PROMISE
- // is written. Once the ID is allocated, we start the request handler.
- allocatePromisedID := func() (uint32, error) {
- sc.serveG.check()
-
- // Check this again, just in case. Technically, we might have received
- // an updated SETTINGS by the time we got around to writing this frame.
- if !sc.pushEnabled {
- return 0, ErrNotSupported
- }
- // http://tools.ietf.org/html/rfc7540#section-6.5.2.
- if sc.curPushedStreams+1 > sc.clientMaxStreams {
- return 0, http2ErrPushLimitReached
- }
-
- // http://tools.ietf.org/html/rfc7540#section-5.1.1.
- // Streams initiated by the server MUST use even-numbered identifiers.
- // A server that is unable to establish a new stream identifier can send a GOAWAY
- // frame so that the client is forced to open a new connection for new streams.
- if sc.maxPushPromiseID+2 >= 1<<31 {
- sc.startGracefulShutdownInternal()
- return 0, http2ErrPushLimitReached
- }
- sc.maxPushPromiseID += 2
- promisedID := sc.maxPushPromiseID
-
- // http://tools.ietf.org/html/rfc7540#section-8.2.
- // Strictly speaking, the new stream should start in "reserved (local)", then
- // transition to "half closed (remote)" after sending the initial HEADERS, but
- // we start in "half closed (remote)" for simplicity.
- // See further comments at the definition of stateHalfClosedRemote.
- promised := sc.newStream(promisedID, msg.parent.id, http2stateHalfClosedRemote)
- rw, req, err := sc.newWriterAndRequestNoBody(promised, http2requestParam{
- method: msg.method,
- scheme: msg.url.Scheme,
- authority: msg.url.Host,
- path: msg.url.RequestURI(),
- header: http2cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
- })
- if err != nil {
- // Should not happen, since we've already validated msg.url.
- panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err))
- }
-
- go sc.runHandler(rw, req, sc.handler.ServeHTTP)
- return promisedID, nil
- }
-
- sc.writeFrame(http2FrameWriteRequest{
- write: &http2writePushPromise{
- streamID: msg.parent.id,
- method: msg.method,
- url: msg.url,
- h: msg.header,
- allocatePromisedID: allocatePromisedID,
- },
- stream: msg.parent,
- done: msg.done,
- })
-}
-
-// foreachHeaderElement splits v according to the "#rule" construction
-// in RFC 7230 section 7 and calls fn for each non-empty element.
-func http2foreachHeaderElement(v string, fn func(string)) {
- v = textproto.TrimString(v)
- if v == "" {
- return
- }
- if !strings.Contains(v, ",") {
- fn(v)
- return
- }
- for _, f := range strings.Split(v, ",") {
- if f = textproto.TrimString(f); f != "" {
- fn(f)
- }
- }
-}
-
-// From http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.2
-var http2connHeaders = []string{
- "Connection",
- "Keep-Alive",
- "Proxy-Connection",
- "Transfer-Encoding",
- "Upgrade",
-}
-
-// checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request,
-// per RFC 7540 Section 8.1.2.2.
-// The returned error is reported to users.
-func http2checkValidHTTP2RequestHeaders(h Header) error {
- for _, k := range http2connHeaders {
- if _, ok := h[k]; ok {
- return fmt.Errorf("request header %q is not valid in HTTP/2", k)
- }
- }
- te := h["Te"]
- if len(te) > 0 && (len(te) > 1 || (te[0] != "trailers" && te[0] != "")) {
- return errors.New(`request header "TE" may only be "trailers" in HTTP/2`)
- }
- return nil
-}
-
-func http2new400Handler(err error) HandlerFunc {
- return func(w ResponseWriter, r *Request) {
- Error(w, err.Error(), StatusBadRequest)
- }
-}
-
-// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
-// disabled. See comments on h1ServerShutdownChan above for why
-// the code is written this way.
-func http2h1ServerKeepAlivesDisabled(hs *Server) bool {
- var x interface{} = hs
- type I interface {
- doKeepAlives() bool
- }
- if hs, ok := x.(I); ok {
- return !hs.doKeepAlives()
- }
- return false
-}
-
-func (sc *http2serverConn) countError(name string, err error) error {
- if sc == nil || sc.srv == nil {
- return err
- }
- f := sc.srv.CountError
- if f == nil {
- return err
- }
- var typ string
- var code http2ErrCode
- switch e := err.(type) {
- case http2ConnectionError:
- typ = "conn"
- code = http2ErrCode(e)
- case http2StreamError:
- typ = "stream"
- code = http2ErrCode(e.Code)
- default:
- return err
- }
- codeStr := http2errCodeName[code]
- if codeStr == "" {
- codeStr = strconv.Itoa(int(code))
- }
- f(fmt.Sprintf("%s_%s_%s", typ, codeStr, name))
- return err
-}
-
-const (
- // transportDefaultConnFlow is how many connection-level flow control
- // tokens we give the server at start-up, past the default 64k.
- http2transportDefaultConnFlow = 1 << 30
-
- // transportDefaultStreamFlow is how many stream-level flow
- // control tokens we announce to the peer, and how many bytes
- // we buffer per stream.
- http2transportDefaultStreamFlow = 4 << 20
-
- // transportDefaultStreamMinRefresh is the minimum number of bytes we'll send
- // a stream-level WINDOW_UPDATE for at a time.
- http2transportDefaultStreamMinRefresh = 4 << 10
-
- http2defaultUserAgent = "Go-http-client/2.0"
-
- // initialMaxConcurrentStreams is a connections maxConcurrentStreams until
- // it's received servers initial SETTINGS frame, which corresponds with the
- // spec's minimum recommended value.
- http2initialMaxConcurrentStreams = 100
-
- // defaultMaxConcurrentStreams is a connections default maxConcurrentStreams
- // if the server doesn't include one in its initial SETTINGS frame.
- http2defaultMaxConcurrentStreams = 1000
-)
-
-// Transport is an HTTP/2 Transport.
-//
-// A Transport internally caches connections to servers. It is safe
-// for concurrent use by multiple goroutines.
-type http2Transport struct {
- // DialTLSContext specifies an optional dial function with context for
- // creating TLS connections for requests.
- //
- // If DialTLSContext and DialTLS is nil, tls.Dial is used.
- //
- // If the returned net.Conn has a ConnectionState method like tls.Conn,
- // it will be used to set http.Response.TLS.
- DialTLSContext func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error)
-
- // DialTLS specifies an optional dial function for creating
- // TLS connections for requests.
- //
- // If DialTLSContext and DialTLS is nil, tls.Dial is used.
- //
- // Deprecated: Use DialTLSContext instead, which allows the transport
- // to cancel dials as soon as they are no longer needed.
- // If both are set, DialTLSContext takes priority.
- DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error)
-
- // TLSClientConfig specifies the TLS configuration to use with
- // tls.Client. If nil, the default configuration is used.
- TLSClientConfig *tls.Config
-
- // ConnPool optionally specifies an alternate connection pool to use.
- // If nil, the default is used.
- ConnPool http2ClientConnPool
-
- // DisableCompression, if true, prevents the Transport from
- // requesting compression with an "Accept-Encoding: gzip"
- // request header when the Request contains no existing
- // Accept-Encoding value. If the Transport requests gzip on
- // its own and gets a gzipped response, it's transparently
- // decoded in the Response.Body. However, if the user
- // explicitly requested gzip it is not automatically
- // uncompressed.
- DisableCompression bool
-
- // AllowHTTP, if true, permits HTTP/2 requests using the insecure,
- // plain-text "http" scheme. Note that this does not enable h2c support.
- AllowHTTP bool
-
- // MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to
- // send in the initial settings frame. It is how many bytes
- // of response headers are allowed. Unlike the http2 spec, zero here
- // means to use a default limit (currently 10MB). If you actually
- // want to advertise an unlimited value to the peer, Transport
- // interprets the highest possible value here (0xffffffff or 1<<32-1)
- // to mean no limit.
- MaxHeaderListSize uint32
-
- // MaxReadFrameSize is the http2 SETTINGS_MAX_FRAME_SIZE to send in the
- // initial settings frame. It is the size in bytes of the largest frame
- // payload that the sender is willing to receive. If 0, no setting is
- // sent, and the value is provided by the peer, which should be 16384
- // according to the spec:
- // https://datatracker.ietf.org/doc/html/rfc7540#section-6.5.2.
- // Values are bounded in the range 16k to 16M.
- MaxReadFrameSize uint32
-
- // MaxDecoderHeaderTableSize optionally specifies the http2
- // SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It
- // informs the remote endpoint of the maximum size of the header compression
- // table used to decode header blocks, in octets. If zero, the default value
- // of 4096 is used.
- MaxDecoderHeaderTableSize uint32
-
- // MaxEncoderHeaderTableSize optionally specifies an upper limit for the
- // header compression table used for encoding request headers. Received
- // SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero,
- // the default value of 4096 is used.
- MaxEncoderHeaderTableSize uint32
-
- // StrictMaxConcurrentStreams controls whether the server's
- // SETTINGS_MAX_CONCURRENT_STREAMS should be respected
- // globally. If false, new TCP connections are created to the
- // server as needed to keep each under the per-connection
- // SETTINGS_MAX_CONCURRENT_STREAMS limit. If true, the
- // server's SETTINGS_MAX_CONCURRENT_STREAMS is interpreted as
- // a global limit and callers of RoundTrip block when needed,
- // waiting for their turn.
- StrictMaxConcurrentStreams bool
-
- // ReadIdleTimeout is the timeout after which a health check using ping
- // frame will be carried out if no frame is received on the connection.
- // Note that a ping response will is considered a received frame, so if
- // there is no other traffic on the connection, the health check will
- // be performed every ReadIdleTimeout interval.
- // If zero, no health check is performed.
- ReadIdleTimeout time.Duration
-
- // PingTimeout is the timeout after which the connection will be closed
- // if a response to Ping is not received.
- // Defaults to 15s.
- PingTimeout time.Duration
-
- // WriteByteTimeout is the timeout after which the connection will be
- // closed no data can be written to it. The timeout begins when data is
- // available to write, and is extended whenever any bytes are written.
- WriteByteTimeout time.Duration
-
- // CountError, if non-nil, is called on HTTP/2 transport errors.
- // It's intended to increment a metric for monitoring, such
- // as an expvar or Prometheus metric.
- // The errType consists of only ASCII word characters.
- CountError func(errType string)
-
- // t1, if non-nil, is the standard library Transport using
- // this transport. Its settings are used (but not its
- // RoundTrip method, etc).
- t1 *Transport
-
- connPoolOnce sync.Once
- connPoolOrDef http2ClientConnPool // non-nil version of ConnPool
-}
-
-func (t *http2Transport) maxHeaderListSize() uint32 {
- if t.MaxHeaderListSize == 0 {
- return 10 << 20
- }
- if t.MaxHeaderListSize == 0xffffffff {
- return 0
- }
- return t.MaxHeaderListSize
-}
-
-func (t *http2Transport) maxFrameReadSize() uint32 {
- if t.MaxReadFrameSize == 0 {
- return 0 // use the default provided by the peer
- }
- if t.MaxReadFrameSize < http2minMaxFrameSize {
- return http2minMaxFrameSize
- }
- if t.MaxReadFrameSize > http2maxFrameSize {
- return http2maxFrameSize
- }
- return t.MaxReadFrameSize
-}
-
-func (t *http2Transport) disableCompression() bool {
- return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
-}
-
-func (t *http2Transport) pingTimeout() time.Duration {
- if t.PingTimeout == 0 {
- return 15 * time.Second
- }
- return t.PingTimeout
-
-}
-
-// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
-// It returns an error if t1 has already been HTTP/2-enabled.
-//
-// Use ConfigureTransports instead to configure the HTTP/2 Transport.
-func http2ConfigureTransport(t1 *Transport) error {
- _, err := http2ConfigureTransports(t1)
- return err
-}
-
-// ConfigureTransports configures a net/http HTTP/1 Transport to use HTTP/2.
-// It returns a new HTTP/2 Transport for further configuration.
-// It returns an error if t1 has already been HTTP/2-enabled.
-func http2ConfigureTransports(t1 *Transport) (*http2Transport, error) {
- return http2configureTransports(t1)
-}
-
-func http2configureTransports(t1 *Transport) (*http2Transport, error) {
- connPool := new(http2clientConnPool)
- t2 := &http2Transport{
- ConnPool: http2noDialClientConnPool{connPool},
- t1: t1,
- }
- connPool.t = t2
- if err := http2registerHTTPSProtocol(t1, http2noDialH2RoundTripper{t2}); err != nil {
- return nil, err
- }
- if t1.TLSClientConfig == nil {
- t1.TLSClientConfig = new(tls.Config)
- }
- if !http2strSliceContains(t1.TLSClientConfig.NextProtos, "h2") {
- t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...)
- }
- if !http2strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") {
- t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1")
- }
- upgradeFn := func(authority string, c *tls.Conn) RoundTripper {
- addr := http2authorityAddr("https", authority)
- if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {
- go c.Close()
- return http2erringRoundTripper{err}
- } else if !used {
- // Turns out we don't need this c.
- // For example, two goroutines made requests to the same host
- // at the same time, both kicking off TCP dials. (since protocol
- // was unknown)
- go c.Close()
- }
- return t2
- }
- if m := t1.TLSNextProto; len(m) == 0 {
- t1.TLSNextProto = map[string]func(string, *tls.Conn) RoundTripper{
- "h2": upgradeFn,
- }
- } else {
- m["h2"] = upgradeFn
- }
- return t2, nil
-}
-
-func (t *http2Transport) connPool() http2ClientConnPool {
- t.connPoolOnce.Do(t.initConnPool)
- return t.connPoolOrDef
-}
-
-func (t *http2Transport) initConnPool() {
- if t.ConnPool != nil {
- t.connPoolOrDef = t.ConnPool
- } else {
- t.connPoolOrDef = &http2clientConnPool{t: t}
- }
-}
-
-// ClientConn is the state of a single HTTP/2 client connection to an
-// HTTP/2 server.
-type http2ClientConn struct {
- t *http2Transport
- tconn net.Conn // usually *tls.Conn, except specialized impls
- tconnClosed bool
- tlsState *tls.ConnectionState // nil only for specialized impls
- reused uint32 // whether conn is being reused; atomic
- singleUse bool // whether being used for a single http.Request
- getConnCalled bool // used by clientConnPool
-
- // readLoop goroutine fields:
- readerDone chan struct{} // closed on error
- readerErr error // set before readerDone is closed
-
- idleTimeout time.Duration // or 0 for never
- idleTimer *time.Timer
-
- mu sync.Mutex // guards following
- cond *sync.Cond // hold mu; broadcast on flow/closed changes
- flow http2flow // our conn-level flow control quota (cs.flow is per stream)
- inflow http2flow // peer's conn-level flow control
- doNotReuse bool // whether conn is marked to not be reused for any future requests
- closing bool
- closed bool
- seenSettings bool // true if we've seen a settings frame, false otherwise
- wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back
- goAway *http2GoAwayFrame // if non-nil, the GoAwayFrame we received
- goAwayDebug string // goAway frame's debug data, retained as a string
- streams map[uint32]*http2clientStream // client-initiated
- streamsReserved int // incr by ReserveNewRequest; decr on RoundTrip
- nextStreamID uint32
- pendingRequests int // requests blocked and waiting to be sent because len(streams) == maxConcurrentStreams
- pings map[[8]byte]chan struct{} // in flight ping data to notification channel
- br *bufio.Reader
- lastActive time.Time
- lastIdle time.Time // time last idle
- // Settings from peer: (also guarded by wmu)
- maxFrameSize uint32
- maxConcurrentStreams uint32
- peerMaxHeaderListSize uint64
- peerMaxHeaderTableSize uint32
- initialWindowSize uint32
-
- // reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests.
- // Write to reqHeaderMu to lock it, read from it to unlock.
- // Lock reqmu BEFORE mu or wmu.
- reqHeaderMu chan struct{}
-
- // wmu is held while writing.
- // Acquire BEFORE mu when holding both, to avoid blocking mu on network writes.
- // Only acquire both at the same time when changing peer settings.
- wmu sync.Mutex
- bw *bufio.Writer
- fr *http2Framer
- werr error // first write error that has occurred
- hbuf bytes.Buffer // HPACK encoder writes into this
- henc *hpack.Encoder
-}
-
-// clientStream is the state for a single HTTP/2 stream. One of these
-// is created for each Transport.RoundTrip call.
-type http2clientStream struct {
- cc *http2ClientConn
-
- // Fields of Request that we may access even after the response body is closed.
- ctx context.Context
- reqCancel <-chan struct{}
-
- trace *httptrace.ClientTrace // or nil
- ID uint32
- bufPipe http2pipe // buffered pipe with the flow-controlled response payload
- requestedGzip bool
- isHead bool
-
- abortOnce sync.Once
- abort chan struct{} // closed to signal stream should end immediately
- abortErr error // set if abort is closed
-
- peerClosed chan struct{} // closed when the peer sends an END_STREAM flag
- donec chan struct{} // closed after the stream is in the closed state
- on100 chan struct{} // buffered; written to if a 100 is received
-
- respHeaderRecv chan struct{} // closed when headers are received
- res *Response // set if respHeaderRecv is closed
-
- flow http2flow // guarded by cc.mu
- inflow http2flow // guarded by cc.mu
- bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read
- readErr error // sticky read error; owned by transportResponseBody.Read
-
- reqBody io.ReadCloser
- reqBodyContentLength int64 // -1 means unknown
- reqBodyClosed chan struct{} // guarded by cc.mu; non-nil on Close, closed when done
-
- // owned by writeRequest:
- sentEndStream bool // sent an END_STREAM flag to the peer
- sentHeaders bool
-
- // owned by clientConnReadLoop:
- firstByte bool // got the first response byte
- pastHeaders bool // got first MetaHeadersFrame (actual headers)
- pastTrailers bool // got optional second MetaHeadersFrame (trailers)
- num1xx uint8 // number of 1xx responses seen
- readClosed bool // peer sent an END_STREAM flag
- readAborted bool // read loop reset the stream
-
- trailer Header // accumulated trailers
- resTrailer *Header // client's Response.Trailer
-}
-
-var http2got1xxFuncForTests func(int, textproto.MIMEHeader) error
-
-// get1xxTraceFunc returns the value of request's httptrace.ClientTrace.Got1xxResponse func,
-// if any. It returns nil if not set or if the Go version is too old.
-func (cs *http2clientStream) get1xxTraceFunc() func(int, textproto.MIMEHeader) error {
- if fn := http2got1xxFuncForTests; fn != nil {
- return fn
- }
- return http2traceGot1xxResponseFunc(cs.trace)
-}
-
-func (cs *http2clientStream) abortStream(err error) {
- cs.cc.mu.Lock()
- defer cs.cc.mu.Unlock()
- cs.abortStreamLocked(err)
-}
-
-func (cs *http2clientStream) abortStreamLocked(err error) {
- cs.abortOnce.Do(func() {
- cs.abortErr = err
- close(cs.abort)
- })
- if cs.reqBody != nil {
- cs.closeReqBodyLocked()
- }
- // TODO(dneil): Clean up tests where cs.cc.cond is nil.
- if cs.cc.cond != nil {
- // Wake up writeRequestBody if it is waiting on flow control.
- cs.cc.cond.Broadcast()
- }
-}
-
-func (cs *http2clientStream) abortRequestBodyWrite() {
- cc := cs.cc
- cc.mu.Lock()
- defer cc.mu.Unlock()
- if cs.reqBody != nil && cs.reqBodyClosed == nil {
- cs.closeReqBodyLocked()
- cc.cond.Broadcast()
- }
-}
-
-func (cs *http2clientStream) closeReqBodyLocked() {
- if cs.reqBodyClosed != nil {
- return
- }
- cs.reqBodyClosed = make(chan struct{})
- reqBodyClosed := cs.reqBodyClosed
- go func() {
- cs.reqBody.Close()
- close(reqBodyClosed)
- }()
-}
-
-type http2stickyErrWriter struct {
- conn net.Conn
- timeout time.Duration
- err *error
-}
-
-func (sew http2stickyErrWriter) Write(p []byte) (n int, err error) {
- if *sew.err != nil {
- return 0, *sew.err
- }
- for {
- if sew.timeout != 0 {
- sew.conn.SetWriteDeadline(time.Now().Add(sew.timeout))
- }
- nn, err := sew.conn.Write(p[n:])
- n += nn
- if n < len(p) && nn > 0 && errors.Is(err, os.ErrDeadlineExceeded) {
- // Keep extending the deadline so long as we're making progress.
- continue
- }
- if sew.timeout != 0 {
- sew.conn.SetWriteDeadline(time.Time{})
- }
- *sew.err = err
- return n, err
- }
-}
-
-// noCachedConnError is the concrete type of ErrNoCachedConn, which
-// needs to be detected by net/http regardless of whether it's its
-// bundled version (in h2_bundle.go with a rewritten type name) or
-// from a user's x/net/http2. As such, as it has a unique method name
-// (IsHTTP2NoCachedConnError) that net/http sniffs for via func
-// isNoCachedConnError.
-type http2noCachedConnError struct{}
-
-func (http2noCachedConnError) IsHTTP2NoCachedConnError() {}
-
-func (http2noCachedConnError) Error() string { return "http2: no cached connection was available" }
-
-// isNoCachedConnError reports whether err is of type noCachedConnError
-// or its equivalent renamed type in net/http2's h2_bundle.go. Both types
-// may coexist in the same running program.
-func http2isNoCachedConnError(err error) bool {
- _, ok := err.(interface{ IsHTTP2NoCachedConnError() })
- return ok
-}
-
-var http2ErrNoCachedConn error = http2noCachedConnError{}
-
-// RoundTripOpt are options for the Transport.RoundTripOpt method.
-type http2RoundTripOpt struct {
- // OnlyCachedConn controls whether RoundTripOpt may
- // create a new TCP connection. If set true and
- // no cached connection is available, RoundTripOpt
- // will return ErrNoCachedConn.
- OnlyCachedConn bool
-}
-
-func (t *http2Transport) RoundTrip(req *Request) (*Response, error) {
- return t.RoundTripOpt(req, http2RoundTripOpt{})
-}
-
-// authorityAddr returns a given authority (a host/IP, or host:port / ip:port)
-// and returns a host:port. The port 443 is added if needed.
-func http2authorityAddr(scheme string, authority string) (addr string) {
- host, port, err := net.SplitHostPort(authority)
- if err != nil { // authority didn't have a port
- port = "443"
- if scheme == "http" {
- port = "80"
- }
- host = authority
- }
- if a, err := idna.ToASCII(host); err == nil {
- host = a
- }
- // IPv6 address literal, without a port:
- if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
- return host + ":" + port
- }
- return net.JoinHostPort(host, port)
-}
-
-var http2retryBackoffHook func(time.Duration) *time.Timer
-
-func http2backoffNewTimer(d time.Duration) *time.Timer {
- if http2retryBackoffHook != nil {
- return http2retryBackoffHook(d)
- }
- return time.NewTimer(d)
-}
-
-// RoundTripOpt is like RoundTrip, but takes options.
-func (t *http2Transport) RoundTripOpt(req *Request, opt http2RoundTripOpt) (*Response, error) {
- if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) {
- return nil, errors.New("http2: unsupported scheme")
- }
-
- addr := http2authorityAddr(req.URL.Scheme, req.URL.Host)
- for retry := 0; ; retry++ {
- cc, err := t.connPool().GetClientConn(req, addr)
- if err != nil {
- t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err)
- return nil, err
- }
- reused := !atomic.CompareAndSwapUint32(&cc.reused, 0, 1)
- http2traceGotConn(req, cc, reused)
- res, err := cc.RoundTrip(req)
- if err != nil && retry <= 6 {
- if req, err = http2shouldRetryRequest(req, err); err == nil {
- // After the first retry, do exponential backoff with 10% jitter.
- if retry == 0 {
- t.vlogf("RoundTrip retrying after failure: %v", err)
- continue
- }
- backoff := float64(uint(1) << (uint(retry) - 1))
- backoff += backoff * (0.1 * mathrand.Float64())
- d := time.Second * time.Duration(backoff)
- timer := http2backoffNewTimer(d)
- select {
- case <-timer.C:
- t.vlogf("RoundTrip retrying after failure: %v", err)
- continue
- case <-req.Context().Done():
- timer.Stop()
- err = req.Context().Err()
- }
- }
- }
- if err != nil {
- t.vlogf("RoundTrip failure: %v", err)
- return nil, err
- }
- return res, nil
- }
-}
-
-// CloseIdleConnections closes any connections which were previously
-// connected from previous requests but are now sitting idle.
-// It does not interrupt any connections currently in use.
-func (t *http2Transport) CloseIdleConnections() {
- if cp, ok := t.connPool().(http2clientConnPoolIdleCloser); ok {
- cp.closeIdleConnections()
- }
-}
-
-var (
- http2errClientConnClosed = errors.New("http2: client conn is closed")
- http2errClientConnUnusable = errors.New("http2: client conn not usable")
- http2errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY")
-)
-
-// shouldRetryRequest is called by RoundTrip when a request fails to get
-// response headers. It is always called with a non-nil error.
-// It returns either a request to retry (either the same request, or a
-// modified clone), or an error if the request can't be replayed.
-func http2shouldRetryRequest(req *Request, err error) (*Request, error) {
- if !http2canRetryError(err) {
- return nil, err
- }
- // If the Body is nil (or http.NoBody), it's safe to reuse
- // this request and its Body.
- if req.Body == nil || req.Body == NoBody {
- return req, nil
- }
-
- // If the request body can be reset back to its original
- // state via the optional req.GetBody, do that.
- if req.GetBody != nil {
- body, err := req.GetBody()
- if err != nil {
- return nil, err
- }
- newReq := *req
- newReq.Body = body
- return &newReq, nil
- }
-
- // The Request.Body can't reset back to the beginning, but we
- // don't seem to have started to read from it yet, so reuse
- // the request directly.
- if err == http2errClientConnUnusable {
- return req, nil
- }
-
- return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err)
-}
-
-func http2canRetryError(err error) bool {
- if err == http2errClientConnUnusable || err == http2errClientConnGotGoAway {
- return true
- }
- if se, ok := err.(http2StreamError); ok {
- if se.Code == http2ErrCodeProtocol && se.Cause == http2errFromPeer {
- // See golang/go#47635, golang/go#42777
- return true
- }
- return se.Code == http2ErrCodeRefusedStream
- }
- return false
-}
-
-func (t *http2Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*http2ClientConn, error) {
- host, _, err := net.SplitHostPort(addr)
- if err != nil {
- return nil, err
- }
- tconn, err := t.dialTLS(ctx, "tcp", addr, t.newTLSConfig(host))
- if err != nil {
- return nil, err
- }
- return t.newClientConn(tconn, singleUse)
-}
-
-func (t *http2Transport) newTLSConfig(host string) *tls.Config {
- cfg := new(tls.Config)
- if t.TLSClientConfig != nil {
- *cfg = *t.TLSClientConfig.Clone()
- }
- if !http2strSliceContains(cfg.NextProtos, http2NextProtoTLS) {
- cfg.NextProtos = append([]string{http2NextProtoTLS}, cfg.NextProtos...)
- }
- if cfg.ServerName == "" {
- cfg.ServerName = host
- }
- return cfg
-}
-
-func (t *http2Transport) dialTLS(ctx context.Context, network, addr string, tlsCfg *tls.Config) (net.Conn, error) {
- if t.DialTLSContext != nil {
- return t.DialTLSContext(ctx, network, addr, tlsCfg)
- } else if t.DialTLS != nil {
- return t.DialTLS(network, addr, tlsCfg)
- }
-
- tlsCn, err := t.dialTLSWithContext(ctx, network, addr, tlsCfg)
- if err != nil {
- return nil, err
- }
- state := tlsCn.ConnectionState()
- if p := state.NegotiatedProtocol; p != http2NextProtoTLS {
- return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, http2NextProtoTLS)
- }
- if !state.NegotiatedProtocolIsMutual {
- return nil, errors.New("http2: could not negotiate protocol mutually")
- }
- return tlsCn, nil
-}
-
-// disableKeepAlives reports whether connections should be closed as
-// soon as possible after handling the first request.
-func (t *http2Transport) disableKeepAlives() bool {
- return t.t1 != nil && t.t1.DisableKeepAlives
-}
-
-func (t *http2Transport) expectContinueTimeout() time.Duration {
- if t.t1 == nil {
- return 0
- }
- return t.t1.ExpectContinueTimeout
-}
-
-func (t *http2Transport) maxDecoderHeaderTableSize() uint32 {
- if v := t.MaxDecoderHeaderTableSize; v > 0 {
- return v
- }
- return http2initialHeaderTableSize
-}
-
-func (t *http2Transport) maxEncoderHeaderTableSize() uint32 {
- if v := t.MaxEncoderHeaderTableSize; v > 0 {
- return v
- }
- return http2initialHeaderTableSize
-}
-
-func (t *http2Transport) NewClientConn(c net.Conn) (*http2ClientConn, error) {
- return t.newClientConn(c, t.disableKeepAlives())
-}
-
-func (t *http2Transport) newClientConn(c net.Conn, singleUse bool) (*http2ClientConn, error) {
- cc := &http2ClientConn{
- t: t,
- tconn: c,
- readerDone: make(chan struct{}),
- nextStreamID: 1,
- maxFrameSize: 16 << 10, // spec default
- initialWindowSize: 65535, // spec default
- maxConcurrentStreams: http2initialMaxConcurrentStreams, // "infinite", per spec. Use a smaller value until we have received server settings.
- peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead.
- streams: make(map[uint32]*http2clientStream),
- singleUse: singleUse,
- wantSettingsAck: true,
- pings: make(map[[8]byte]chan struct{}),
- reqHeaderMu: make(chan struct{}, 1),
- }
- if d := t.idleConnTimeout(); d != 0 {
- cc.idleTimeout = d
- cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout)
- }
- if http2VerboseLogs {
- t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr())
- }
-
- cc.cond = sync.NewCond(&cc.mu)
- cc.flow.add(int32(http2initialWindowSize))
-
- // TODO: adjust this writer size to account for frame size +
- // MTU + crypto/tls record padding.
- cc.bw = bufio.NewWriter(http2stickyErrWriter{
- conn: c,
- timeout: t.WriteByteTimeout,
- err: &cc.werr,
- })
- cc.br = bufio.NewReader(c)
- cc.fr = http2NewFramer(cc.bw, cc.br)
- if t.maxFrameReadSize() != 0 {
- cc.fr.SetMaxReadFrameSize(t.maxFrameReadSize())
- }
- if t.CountError != nil {
- cc.fr.countError = t.CountError
- }
- maxHeaderTableSize := t.maxDecoderHeaderTableSize()
- cc.fr.ReadMetaHeaders = hpack.NewDecoder(maxHeaderTableSize, nil)
- cc.fr.MaxHeaderListSize = t.maxHeaderListSize()
-
- cc.henc = hpack.NewEncoder(&cc.hbuf)
- cc.henc.SetMaxDynamicTableSizeLimit(t.maxEncoderHeaderTableSize())
- cc.peerMaxHeaderTableSize = http2initialHeaderTableSize
-
- if t.AllowHTTP {
- cc.nextStreamID = 3
- }
-
- if cs, ok := c.(http2connectionStater); ok {
- state := cs.ConnectionState()
- cc.tlsState = &state
- }
-
- initialSettings := []http2Setting{
- {ID: http2SettingEnablePush, Val: 0},
- {ID: http2SettingInitialWindowSize, Val: http2transportDefaultStreamFlow},
- }
- if max := t.maxFrameReadSize(); max != 0 {
- initialSettings = append(initialSettings, http2Setting{ID: http2SettingMaxFrameSize, Val: max})
- }
- if max := t.maxHeaderListSize(); max != 0 {
- initialSettings = append(initialSettings, http2Setting{ID: http2SettingMaxHeaderListSize, Val: max})
- }
- if maxHeaderTableSize != http2initialHeaderTableSize {
- initialSettings = append(initialSettings, http2Setting{ID: http2SettingHeaderTableSize, Val: maxHeaderTableSize})
- }
-
- cc.bw.Write(http2clientPreface)
- cc.fr.WriteSettings(initialSettings...)
- cc.fr.WriteWindowUpdate(0, http2transportDefaultConnFlow)
- cc.inflow.add(http2transportDefaultConnFlow + http2initialWindowSize)
- cc.bw.Flush()
- if cc.werr != nil {
- cc.Close()
- return nil, cc.werr
- }
-
- go cc.readLoop()
- return cc, nil
-}
-
-func (cc *http2ClientConn) healthCheck() {
- pingTimeout := cc.t.pingTimeout()
- // We don't need to periodically ping in the health check, because the readLoop of ClientConn will
- // trigger the healthCheck again if there is no frame received.
- ctx, cancel := context.WithTimeout(context.Background(), pingTimeout)
- defer cancel()
- cc.vlogf("http2: Transport sending health check")
- err := cc.Ping(ctx)
- if err != nil {
- cc.vlogf("http2: Transport health check failure: %v", err)
- cc.closeForLostPing()
- } else {
- cc.vlogf("http2: Transport health check success")
- }
-}
-
-// SetDoNotReuse marks cc as not reusable for future HTTP requests.
-func (cc *http2ClientConn) SetDoNotReuse() {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- cc.doNotReuse = true
-}
-
-func (cc *http2ClientConn) setGoAway(f *http2GoAwayFrame) {
- cc.mu.Lock()
- defer cc.mu.Unlock()
-
- old := cc.goAway
- cc.goAway = f
-
- // Merge the previous and current GoAway error frames.
- if cc.goAwayDebug == "" {
- cc.goAwayDebug = string(f.DebugData())
- }
- if old != nil && old.ErrCode != http2ErrCodeNo {
- cc.goAway.ErrCode = old.ErrCode
- }
- last := f.LastStreamID
- for streamID, cs := range cc.streams {
- if streamID > last {
- cs.abortStreamLocked(http2errClientConnGotGoAway)
- }
- }
-}
-
-// CanTakeNewRequest reports whether the connection can take a new request,
-// meaning it has not been closed or received or sent a GOAWAY.
-//
-// If the caller is going to immediately make a new request on this
-// connection, use ReserveNewRequest instead.
-func (cc *http2ClientConn) CanTakeNewRequest() bool {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- return cc.canTakeNewRequestLocked()
-}
-
-// ReserveNewRequest is like CanTakeNewRequest but also reserves a
-// concurrent stream in cc. The reservation is decremented on the
-// next call to RoundTrip.
-func (cc *http2ClientConn) ReserveNewRequest() bool {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- if st := cc.idleStateLocked(); !st.canTakeNewRequest {
- return false
- }
- cc.streamsReserved++
- return true
-}
-
-// ClientConnState describes the state of a ClientConn.
-type http2ClientConnState struct {
- // Closed is whether the connection is closed.
- Closed bool
-
- // Closing is whether the connection is in the process of
- // closing. It may be closing due to shutdown, being a
- // single-use connection, being marked as DoNotReuse, or
- // having received a GOAWAY frame.
- Closing bool
-
- // StreamsActive is how many streams are active.
- StreamsActive int
-
- // StreamsReserved is how many streams have been reserved via
- // ClientConn.ReserveNewRequest.
- StreamsReserved int
-
- // StreamsPending is how many requests have been sent in excess
- // of the peer's advertised MaxConcurrentStreams setting and
- // are waiting for other streams to complete.
- StreamsPending int
-
- // MaxConcurrentStreams is how many concurrent streams the
- // peer advertised as acceptable. Zero means no SETTINGS
- // frame has been received yet.
- MaxConcurrentStreams uint32
-
- // LastIdle, if non-zero, is when the connection last
- // transitioned to idle state.
- LastIdle time.Time
-}
-
-// State returns a snapshot of cc's state.
-func (cc *http2ClientConn) State() http2ClientConnState {
- cc.wmu.Lock()
- maxConcurrent := cc.maxConcurrentStreams
- if !cc.seenSettings {
- maxConcurrent = 0
- }
- cc.wmu.Unlock()
-
- cc.mu.Lock()
- defer cc.mu.Unlock()
- return http2ClientConnState{
- Closed: cc.closed,
- Closing: cc.closing || cc.singleUse || cc.doNotReuse || cc.goAway != nil,
- StreamsActive: len(cc.streams),
- StreamsReserved: cc.streamsReserved,
- StreamsPending: cc.pendingRequests,
- LastIdle: cc.lastIdle,
- MaxConcurrentStreams: maxConcurrent,
- }
-}
-
-// clientConnIdleState describes the suitability of a client
-// connection to initiate a new RoundTrip request.
-type http2clientConnIdleState struct {
- canTakeNewRequest bool
-}
-
-func (cc *http2ClientConn) idleState() http2clientConnIdleState {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- return cc.idleStateLocked()
-}
-
-func (cc *http2ClientConn) idleStateLocked() (st http2clientConnIdleState) {
- if cc.singleUse && cc.nextStreamID > 1 {
- return
- }
- var maxConcurrentOkay bool
- if cc.t.StrictMaxConcurrentStreams {
- // We'll tell the caller we can take a new request to
- // prevent the caller from dialing a new TCP
- // connection, but then we'll block later before
- // writing it.
- maxConcurrentOkay = true
- } else {
- maxConcurrentOkay = int64(len(cc.streams)+cc.streamsReserved+1) <= int64(cc.maxConcurrentStreams)
- }
-
- st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay &&
- !cc.doNotReuse &&
- int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 &&
- !cc.tooIdleLocked()
- return
-}
-
-func (cc *http2ClientConn) canTakeNewRequestLocked() bool {
- st := cc.idleStateLocked()
- return st.canTakeNewRequest
-}
-
-// tooIdleLocked reports whether this connection has been been sitting idle
-// for too much wall time.
-func (cc *http2ClientConn) tooIdleLocked() bool {
- // The Round(0) strips the monontonic clock reading so the
- // times are compared based on their wall time. We don't want
- // to reuse a connection that's been sitting idle during
- // VM/laptop suspend if monotonic time was also frozen.
- return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && time.Since(cc.lastIdle.Round(0)) > cc.idleTimeout
-}
-
-// onIdleTimeout is called from a time.AfterFunc goroutine. It will
-// only be called when we're idle, but because we're coming from a new
-// goroutine, there could be a new request coming in at the same time,
-// so this simply calls the synchronized closeIfIdle to shut down this
-// connection. The timer could just call closeIfIdle, but this is more
-// clear.
-func (cc *http2ClientConn) onIdleTimeout() {
- cc.closeIfIdle()
-}
-
-func (cc *http2ClientConn) closeConn() {
- t := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn)
- defer t.Stop()
- cc.tconn.Close()
-}
-
-// A tls.Conn.Close can hang for a long time if the peer is unresponsive.
-// Try to shut it down more aggressively.
-func (cc *http2ClientConn) forceCloseConn() {
- tc, ok := cc.tconn.(*tls.Conn)
- if !ok {
- return
- }
- if nc := http2tlsUnderlyingConn(tc); nc != nil {
- nc.Close()
- }
-}
-
-func (cc *http2ClientConn) closeIfIdle() {
- cc.mu.Lock()
- if len(cc.streams) > 0 || cc.streamsReserved > 0 {
- cc.mu.Unlock()
- return
- }
- cc.closed = true
- nextID := cc.nextStreamID
- // TODO: do clients send GOAWAY too? maybe? Just Close:
- cc.mu.Unlock()
-
- if http2VerboseLogs {
- cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, nextID-2)
- }
- cc.closeConn()
-}
-
-func (cc *http2ClientConn) isDoNotReuseAndIdle() bool {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- return cc.doNotReuse && len(cc.streams) == 0
-}
-
-var http2shutdownEnterWaitStateHook = func() {}
-
-// Shutdown gracefully closes the client connection, waiting for running streams to complete.
-func (cc *http2ClientConn) Shutdown(ctx context.Context) error {
- if err := cc.sendGoAway(); err != nil {
- return err
- }
- // Wait for all in-flight streams to complete or connection to close
- done := make(chan struct{})
- cancelled := false // guarded by cc.mu
- go func() {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- for {
- if len(cc.streams) == 0 || cc.closed {
- cc.closed = true
- close(done)
- break
- }
- if cancelled {
- break
- }
- cc.cond.Wait()
- }
- }()
- http2shutdownEnterWaitStateHook()
- select {
- case <-done:
- cc.closeConn()
- return nil
- case <-ctx.Done():
- cc.mu.Lock()
- // Free the goroutine above
- cancelled = true
- cc.cond.Broadcast()
- cc.mu.Unlock()
- return ctx.Err()
- }
-}
-
-func (cc *http2ClientConn) sendGoAway() error {
- cc.mu.Lock()
- closing := cc.closing
- cc.closing = true
- maxStreamID := cc.nextStreamID
- cc.mu.Unlock()
- if closing {
- // GOAWAY sent already
- return nil
- }
-
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
- // Send a graceful shutdown frame to server
- if err := cc.fr.WriteGoAway(maxStreamID, http2ErrCodeNo, nil); err != nil {
- return err
- }
- if err := cc.bw.Flush(); err != nil {
- return err
- }
- // Prevent new requests
- return nil
-}
-
-// closes the client connection immediately. In-flight requests are interrupted.
-// err is sent to streams.
-func (cc *http2ClientConn) closeForError(err error) {
- cc.mu.Lock()
- cc.closed = true
- for _, cs := range cc.streams {
- cs.abortStreamLocked(err)
- }
- cc.cond.Broadcast()
- cc.mu.Unlock()
- cc.closeConn()
-}
-
-// Close closes the client connection immediately.
-//
-// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
-func (cc *http2ClientConn) Close() error {
- err := errors.New("http2: client connection force closed via ClientConn.Close")
- cc.closeForError(err)
- return nil
-}
-
-// closes the client connection immediately. In-flight requests are interrupted.
-func (cc *http2ClientConn) closeForLostPing() {
- err := errors.New("http2: client connection lost")
- if f := cc.t.CountError; f != nil {
- f("conn_close_lost_ping")
- }
- cc.closeForError(err)
-}
-
-// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not
-// exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests.
-var http2errRequestCanceled = errors.New("net/http: request canceled")
-
-func http2commaSeparatedTrailers(req *Request) (string, error) {
- keys := make([]string, 0, len(req.Trailer))
- for k := range req.Trailer {
- k = http2canonicalHeader(k)
- switch k {
- case "Transfer-Encoding", "Trailer", "Content-Length":
- return "", fmt.Errorf("invalid Trailer key %q", k)
- }
- keys = append(keys, k)
- }
- if len(keys) > 0 {
- sort.Strings(keys)
- return strings.Join(keys, ","), nil
- }
- return "", nil
-}
-
-func (cc *http2ClientConn) responseHeaderTimeout() time.Duration {
- if cc.t.t1 != nil {
- return cc.t.t1.ResponseHeaderTimeout
- }
- // No way to do this (yet?) with just an http2.Transport. Probably
- // no need. Request.Cancel this is the new way. We only need to support
- // this for compatibility with the old http.Transport fields when
- // we're doing transparent http2.
- return 0
-}
-
-// checkConnHeaders checks whether req has any invalid connection-level headers.
-// per RFC 7540 section 8.1.2.2: Connection-Specific Header Fields.
-// Certain headers are special-cased as okay but not transmitted later.
-func http2checkConnHeaders(req *Request) error {
- if v := req.Header.Get("Upgrade"); v != "" {
- return fmt.Errorf("http2: invalid Upgrade request header: %q", req.Header["Upgrade"])
- }
- if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") {
- return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv)
- }
- if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !http2asciiEqualFold(vv[0], "close") && !http2asciiEqualFold(vv[0], "keep-alive")) {
- return fmt.Errorf("http2: invalid Connection request header: %q", vv)
- }
- return nil
-}
-
-// actualContentLength returns a sanitized version of
-// req.ContentLength, where 0 actually means zero (not unknown) and -1
-// means unknown.
-func http2actualContentLength(req *Request) int64 {
- if req.Body == nil || req.Body == NoBody {
- return 0
- }
- if req.ContentLength != 0 {
- return req.ContentLength
- }
- return -1
-}
-
-func (cc *http2ClientConn) decrStreamReservations() {
- cc.mu.Lock()
- defer cc.mu.Unlock()
- cc.decrStreamReservationsLocked()
-}
-
-func (cc *http2ClientConn) decrStreamReservationsLocked() {
- if cc.streamsReserved > 0 {
- cc.streamsReserved--
- }
-}
-
-func (cc *http2ClientConn) RoundTrip(req *Request) (*Response, error) {
- ctx := req.Context()
- cs := &http2clientStream{
- cc: cc,
- ctx: ctx,
- reqCancel: req.Cancel,
- isHead: req.Method == "HEAD",
- reqBody: req.Body,
- reqBodyContentLength: http2actualContentLength(req),
- trace: httptrace.ContextClientTrace(ctx),
- peerClosed: make(chan struct{}),
- abort: make(chan struct{}),
- respHeaderRecv: make(chan struct{}),
- donec: make(chan struct{}),
- }
- go cs.doRequest(req)
-
- waitDone := func() error {
- select {
- case <-cs.donec:
- return nil
- case <-ctx.Done():
- return ctx.Err()
- case <-cs.reqCancel:
- return http2errRequestCanceled
- }
- }
-
- handleResponseHeaders := func() (*Response, error) {
- res := cs.res
- if res.StatusCode > 299 {
- // On error or status code 3xx, 4xx, 5xx, etc abort any
- // ongoing write, assuming that the server doesn't care
- // about our request body. If the server replied with 1xx or
- // 2xx, however, then assume the server DOES potentially
- // want our body (e.g. full-duplex streaming:
- // golang.org/issue/13444). If it turns out the server
- // doesn't, they'll RST_STREAM us soon enough. This is a
- // heuristic to avoid adding knobs to Transport. Hopefully
- // we can keep it.
- cs.abortRequestBodyWrite()
- }
- res.Request = req
- res.TLS = cc.tlsState
- if res.Body == http2noBody && http2actualContentLength(req) == 0 {
- // If there isn't a request or response body still being
- // written, then wait for the stream to be closed before
- // RoundTrip returns.
- if err := waitDone(); err != nil {
- return nil, err
- }
- }
- return res, nil
- }
-
- for {
- select {
- case <-cs.respHeaderRecv:
- return handleResponseHeaders()
- case <-cs.abort:
- select {
- case <-cs.respHeaderRecv:
- // If both cs.respHeaderRecv and cs.abort are signaling,
- // pick respHeaderRecv. The server probably wrote the
- // response and immediately reset the stream.
- // golang.org/issue/49645
- return handleResponseHeaders()
- default:
- waitDone()
- return nil, cs.abortErr
- }
- case <-ctx.Done():
- err := ctx.Err()
- cs.abortStream(err)
- return nil, err
- case <-cs.reqCancel:
- cs.abortStream(http2errRequestCanceled)
- return nil, http2errRequestCanceled
- }
- }
-}
-
-// doRequest runs for the duration of the request lifetime.
-//
-// It sends the request and performs post-request cleanup (closing Request.Body, etc.).
-func (cs *http2clientStream) doRequest(req *Request) {
- err := cs.writeRequest(req)
- cs.cleanupWriteRequest(err)
-}
-
-// writeRequest sends a request.
-//
-// It returns nil after the request is written, the response read,
-// and the request stream is half-closed by the peer.
-//
-// It returns non-nil if the request ends otherwise.
-// If the returned error is StreamError, the error Code may be used in resetting the stream.
-func (cs *http2clientStream) writeRequest(req *Request) (err error) {
- cc := cs.cc
- ctx := cs.ctx
-
- if err := http2checkConnHeaders(req); err != nil {
- return err
- }
-
- // Acquire the new-request lock by writing to reqHeaderMu.
- // This lock guards the critical section covering allocating a new stream ID
- // (requires mu) and creating the stream (requires wmu).
- if cc.reqHeaderMu == nil {
- panic("RoundTrip on uninitialized ClientConn") // for tests
- }
- select {
- case cc.reqHeaderMu <- struct{}{}:
- case <-cs.reqCancel:
- return http2errRequestCanceled
- case <-ctx.Done():
- return ctx.Err()
- }
-
- cc.mu.Lock()
- if cc.idleTimer != nil {
- cc.idleTimer.Stop()
- }
- cc.decrStreamReservationsLocked()
- if err := cc.awaitOpenSlotForStreamLocked(cs); err != nil {
- cc.mu.Unlock()
- <-cc.reqHeaderMu
- return err
- }
- cc.addStreamLocked(cs) // assigns stream ID
- if http2isConnectionCloseRequest(req) {
- cc.doNotReuse = true
- }
- cc.mu.Unlock()
-
- // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
- if !cc.t.disableCompression() &&
- req.Header.Get("Accept-Encoding") == "" &&
- req.Header.Get("Range") == "" &&
- !cs.isHead {
- // Request gzip only, not deflate. Deflate is ambiguous and
- // not as universally supported anyway.
- // See: https://zlib.net/zlib_faq.html#faq39
- //
- // Note that we don't request this for HEAD requests,
- // due to a bug in nginx:
- // http://trac.nginx.org/nginx/ticket/358
- // https://golang.org/issue/5522
- //
- // We don't request gzip if the request is for a range, since
- // auto-decoding a portion of a gzipped document will just fail
- // anyway. See https://golang.org/issue/8923
- cs.requestedGzip = true
- }
-
- continueTimeout := cc.t.expectContinueTimeout()
- if continueTimeout != 0 {
- if !httpguts.HeaderValuesContainsToken(req.Header["Expect"], "100-continue") {
- continueTimeout = 0
- } else {
- cs.on100 = make(chan struct{}, 1)
- }
- }
-
- // Past this point (where we send request headers), it is possible for
- // RoundTrip to return successfully. Since the RoundTrip contract permits
- // the caller to "mutate or reuse" the Request after closing the Response's Body,
- // we must take care when referencing the Request from here on.
- err = cs.encodeAndWriteHeaders(req)
- <-cc.reqHeaderMu
- if err != nil {
- return err
- }
-
- hasBody := cs.reqBodyContentLength != 0
- if !hasBody {
- cs.sentEndStream = true
- } else {
- if continueTimeout != 0 {
- http2traceWait100Continue(cs.trace)
- timer := time.NewTimer(continueTimeout)
- select {
- case <-timer.C:
- err = nil
- case <-cs.on100:
- err = nil
- case <-cs.abort:
- err = cs.abortErr
- case <-ctx.Done():
- err = ctx.Err()
- case <-cs.reqCancel:
- err = http2errRequestCanceled
- }
- timer.Stop()
- if err != nil {
- http2traceWroteRequest(cs.trace, err)
- return err
- }
- }
-
- if err = cs.writeRequestBody(req); err != nil {
- if err != http2errStopReqBodyWrite {
- http2traceWroteRequest(cs.trace, err)
- return err
- }
- } else {
- cs.sentEndStream = true
- }
- }
-
- http2traceWroteRequest(cs.trace, err)
-
- var respHeaderTimer <-chan time.Time
- var respHeaderRecv chan struct{}
- if d := cc.responseHeaderTimeout(); d != 0 {
- timer := time.NewTimer(d)
- defer timer.Stop()
- respHeaderTimer = timer.C
- respHeaderRecv = cs.respHeaderRecv
- }
- // Wait until the peer half-closes its end of the stream,
- // or until the request is aborted (via context, error, or otherwise),
- // whichever comes first.
- for {
- select {
- case <-cs.peerClosed:
- return nil
- case <-respHeaderTimer:
- return http2errTimeout
- case <-respHeaderRecv:
- respHeaderRecv = nil
- respHeaderTimer = nil // keep waiting for END_STREAM
- case <-cs.abort:
- return cs.abortErr
- case <-ctx.Done():
- return ctx.Err()
- case <-cs.reqCancel:
- return http2errRequestCanceled
- }
- }
-}
-
-func (cs *http2clientStream) encodeAndWriteHeaders(req *Request) error {
- cc := cs.cc
- ctx := cs.ctx
-
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
-
- // If the request was canceled while waiting for cc.mu, just quit.
- select {
- case <-cs.abort:
- return cs.abortErr
- case <-ctx.Done():
- return ctx.Err()
- case <-cs.reqCancel:
- return http2errRequestCanceled
- default:
- }
-
- // Encode headers.
- //
- // we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is
- // sent by writeRequestBody below, along with any Trailers,
- // again in form HEADERS{1}, CONTINUATION{0,})
- trailers, err := http2commaSeparatedTrailers(req)
- if err != nil {
- return err
- }
- hasTrailers := trailers != ""
- contentLen := http2actualContentLength(req)
- hasBody := contentLen != 0
- hdrs, err := cc.encodeHeaders(req, cs.requestedGzip, trailers, contentLen)
- if err != nil {
- return err
- }
-
- // Write the request.
- endStream := !hasBody && !hasTrailers
- cs.sentHeaders = true
- err = cc.writeHeaders(cs.ID, endStream, int(cc.maxFrameSize), hdrs)
- http2traceWroteHeaders(cs.trace)
- return err
-}
-
-// cleanupWriteRequest performs post-request tasks.
-//
-// If err (the result of writeRequest) is non-nil and the stream is not closed,
-// cleanupWriteRequest will send a reset to the peer.
-func (cs *http2clientStream) cleanupWriteRequest(err error) {
- cc := cs.cc
-
- if cs.ID == 0 {
- // We were canceled before creating the stream, so return our reservation.
- cc.decrStreamReservations()
- }
-
- // TODO: write h12Compare test showing whether
- // Request.Body is closed by the Transport,
- // and in multiple cases: server replies <=299 and >299
- // while still writing request body
- cc.mu.Lock()
- mustCloseBody := false
- if cs.reqBody != nil && cs.reqBodyClosed == nil {
- mustCloseBody = true
- cs.reqBodyClosed = make(chan struct{})
- }
- bodyClosed := cs.reqBodyClosed
- cc.mu.Unlock()
- if mustCloseBody {
- cs.reqBody.Close()
- close(bodyClosed)
- }
- if bodyClosed != nil {
- <-bodyClosed
- }
-
- if err != nil && cs.sentEndStream {
- // If the connection is closed immediately after the response is read,
- // we may be aborted before finishing up here. If the stream was closed
- // cleanly on both sides, there is no error.
- select {
- case <-cs.peerClosed:
- err = nil
- default:
- }
- }
- if err != nil {
- cs.abortStream(err) // possibly redundant, but harmless
- if cs.sentHeaders {
- if se, ok := err.(http2StreamError); ok {
- if se.Cause != http2errFromPeer {
- cc.writeStreamReset(cs.ID, se.Code, err)
- }
- } else {
- cc.writeStreamReset(cs.ID, http2ErrCodeCancel, err)
- }
- }
- cs.bufPipe.CloseWithError(err) // no-op if already closed
- } else {
- if cs.sentHeaders && !cs.sentEndStream {
- cc.writeStreamReset(cs.ID, http2ErrCodeNo, nil)
- }
- cs.bufPipe.CloseWithError(http2errRequestCanceled)
- }
- if cs.ID != 0 {
- cc.forgetStreamID(cs.ID)
- }
-
- cc.wmu.Lock()
- werr := cc.werr
- cc.wmu.Unlock()
- if werr != nil {
- cc.Close()
- }
-
- close(cs.donec)
-}
-
-// awaitOpenSlotForStream waits until len(streams) < maxConcurrentStreams.
-// Must hold cc.mu.
-func (cc *http2ClientConn) awaitOpenSlotForStreamLocked(cs *http2clientStream) error {
- for {
- cc.lastActive = time.Now()
- if cc.closed || !cc.canTakeNewRequestLocked() {
- return http2errClientConnUnusable
- }
- cc.lastIdle = time.Time{}
- if int64(len(cc.streams)) < int64(cc.maxConcurrentStreams) {
- return nil
- }
- cc.pendingRequests++
- cc.cond.Wait()
- cc.pendingRequests--
- select {
- case <-cs.abort:
- return cs.abortErr
- default:
- }
- }
-}
-
-// requires cc.wmu be held
-func (cc *http2ClientConn) writeHeaders(streamID uint32, endStream bool, maxFrameSize int, hdrs []byte) error {
- first := true // first frame written (HEADERS is first, then CONTINUATION)
- for len(hdrs) > 0 && cc.werr == nil {
- chunk := hdrs
- if len(chunk) > maxFrameSize {
- chunk = chunk[:maxFrameSize]
- }
- hdrs = hdrs[len(chunk):]
- endHeaders := len(hdrs) == 0
- if first {
- cc.fr.WriteHeaders(http2HeadersFrameParam{
- StreamID: streamID,
- BlockFragment: chunk,
- EndStream: endStream,
- EndHeaders: endHeaders,
- })
- first = false
- } else {
- cc.fr.WriteContinuation(streamID, endHeaders, chunk)
- }
- }
- cc.bw.Flush()
- return cc.werr
-}
-
-// internal error values; they don't escape to callers
-var (
- // abort request body write; don't send cancel
- http2errStopReqBodyWrite = errors.New("http2: aborting request body write")
-
- // abort request body write, but send stream reset of cancel.
- http2errStopReqBodyWriteAndCancel = errors.New("http2: canceling request")
-
- http2errReqBodyTooLong = errors.New("http2: request body larger than specified content length")
-)
-
-// frameScratchBufferLen returns the length of a buffer to use for
-// outgoing request bodies to read/write to/from.
-//
-// It returns max(1, min(peer's advertised max frame size,
-// Request.ContentLength+1, 512KB)).
-func (cs *http2clientStream) frameScratchBufferLen(maxFrameSize int) int {
- const max = 512 << 10
- n := int64(maxFrameSize)
- if n > max {
- n = max
- }
- if cl := cs.reqBodyContentLength; cl != -1 && cl+1 < n {
- // Add an extra byte past the declared content-length to
- // give the caller's Request.Body io.Reader a chance to
- // give us more bytes than they declared, so we can catch it
- // early.
- n = cl + 1
- }
- if n < 1 {
- return 1
- }
- return int(n) // doesn't truncate; max is 512K
-}
-
-var http2bufPool sync.Pool // of *[]byte
-
-func (cs *http2clientStream) writeRequestBody(req *Request) (err error) {
- cc := cs.cc
- body := cs.reqBody
- sentEnd := false // whether we sent the final DATA frame w/ END_STREAM
-
- hasTrailers := req.Trailer != nil
- remainLen := cs.reqBodyContentLength
- hasContentLen := remainLen != -1
-
- cc.mu.Lock()
- maxFrameSize := int(cc.maxFrameSize)
- cc.mu.Unlock()
-
- // Scratch buffer for reading into & writing from.
- scratchLen := cs.frameScratchBufferLen(maxFrameSize)
- var buf []byte
- if bp, ok := http2bufPool.Get().(*[]byte); ok && len(*bp) >= scratchLen {
- defer http2bufPool.Put(bp)
- buf = *bp
- } else {
- buf = make([]byte, scratchLen)
- defer http2bufPool.Put(&buf)
- }
-
- var sawEOF bool
- for !sawEOF {
- n, err := body.Read(buf)
- if hasContentLen {
- remainLen -= int64(n)
- if remainLen == 0 && err == nil {
- // The request body's Content-Length was predeclared and
- // we just finished reading it all, but the underlying io.Reader
- // returned the final chunk with a nil error (which is one of
- // the two valid things a Reader can do at EOF). Because we'd prefer
- // to send the END_STREAM bit early, double-check that we're actually
- // at EOF. Subsequent reads should return (0, EOF) at this point.
- // If either value is different, we return an error in one of two ways below.
- var scratch [1]byte
- var n1 int
- n1, err = body.Read(scratch[:])
- remainLen -= int64(n1)
- }
- if remainLen < 0 {
- err = http2errReqBodyTooLong
- return err
- }
- }
- if err != nil {
- cc.mu.Lock()
- bodyClosed := cs.reqBodyClosed != nil
- cc.mu.Unlock()
- switch {
- case bodyClosed:
- return http2errStopReqBodyWrite
- case err == io.EOF:
- sawEOF = true
- err = nil
- default:
- return err
- }
- }
-
- remain := buf[:n]
- for len(remain) > 0 && err == nil {
- var allowed int32
- allowed, err = cs.awaitFlowControl(len(remain))
- if err != nil {
- return err
- }
- cc.wmu.Lock()
- data := remain[:allowed]
- remain = remain[allowed:]
- sentEnd = sawEOF && len(remain) == 0 && !hasTrailers
- err = cc.fr.WriteData(cs.ID, sentEnd, data)
- if err == nil {
- // TODO(bradfitz): this flush is for latency, not bandwidth.
- // Most requests won't need this. Make this opt-in or
- // opt-out? Use some heuristic on the body type? Nagel-like
- // timers? Based on 'n'? Only last chunk of this for loop,
- // unless flow control tokens are low? For now, always.
- // If we change this, see comment below.
- err = cc.bw.Flush()
- }
- cc.wmu.Unlock()
- }
- if err != nil {
- return err
- }
- }
-
- if sentEnd {
- // Already sent END_STREAM (which implies we have no
- // trailers) and flushed, because currently all
- // WriteData frames above get a flush. So we're done.
- return nil
- }
-
- // Since the RoundTrip contract permits the caller to "mutate or reuse"
- // a request after the Response's Body is closed, verify that this hasn't
- // happened before accessing the trailers.
- cc.mu.Lock()
- trailer := req.Trailer
- err = cs.abortErr
- cc.mu.Unlock()
- if err != nil {
- return err
- }
-
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
- var trls []byte
- if len(trailer) > 0 {
- trls, err = cc.encodeTrailers(trailer)
- if err != nil {
- return err
- }
- }
-
- // Two ways to send END_STREAM: either with trailers, or
- // with an empty DATA frame.
- if len(trls) > 0 {
- err = cc.writeHeaders(cs.ID, true, maxFrameSize, trls)
- } else {
- err = cc.fr.WriteData(cs.ID, true, nil)
- }
- if ferr := cc.bw.Flush(); ferr != nil && err == nil {
- err = ferr
- }
- return err
-}
-
-// awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow
-// control tokens from the server.
-// It returns either the non-zero number of tokens taken or an error
-// if the stream is dead.
-func (cs *http2clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) {
- cc := cs.cc
- ctx := cs.ctx
- cc.mu.Lock()
- defer cc.mu.Unlock()
- for {
- if cc.closed {
- return 0, http2errClientConnClosed
- }
- if cs.reqBodyClosed != nil {
- return 0, http2errStopReqBodyWrite
- }
- select {
- case <-cs.abort:
- return 0, cs.abortErr
- case <-ctx.Done():
- return 0, ctx.Err()
- case <-cs.reqCancel:
- return 0, http2errRequestCanceled
- default:
- }
- if a := cs.flow.available(); a > 0 {
- take := a
- if int(take) > maxBytes {
-
- take = int32(maxBytes) // can't truncate int; take is int32
- }
- if take > int32(cc.maxFrameSize) {
- take = int32(cc.maxFrameSize)
- }
- cs.flow.take(take)
- return take, nil
- }
- cc.cond.Wait()
- }
-}
-
-var http2errNilRequestURL = errors.New("http2: Request.URI is nil")
-
-// requires cc.wmu be held.
-func (cc *http2ClientConn) encodeHeaders(req *Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) {
- cc.hbuf.Reset()
- if req.URL == nil {
- return nil, http2errNilRequestURL
- }
-
- host := req.Host
- if host == "" {
- host = req.URL.Host
- }
- host, err := httpguts.PunycodeHostPort(host)
- if err != nil {
- return nil, err
- }
-
- var path string
- if req.Method != "CONNECT" {
- path = req.URL.RequestURI()
- if !http2validPseudoPath(path) {
- orig := path
- path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host)
- if !http2validPseudoPath(path) {
- if req.URL.Opaque != "" {
- return nil, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque)
- } else {
- return nil, fmt.Errorf("invalid request :path %q", orig)
- }
- }
- }
- }
-
- // Check for any invalid headers and return an error before we
- // potentially pollute our hpack state. (We want to be able to
- // continue to reuse the hpack encoder for future requests)
- for k, vv := range req.Header {
- if !httpguts.ValidHeaderFieldName(k) {
- return nil, fmt.Errorf("invalid HTTP header name %q", k)
- }
- for _, v := range vv {
- if !httpguts.ValidHeaderFieldValue(v) {
- // Don't include the value in the error, because it may be sensitive.
- return nil, fmt.Errorf("invalid HTTP header value for header %q", k)
- }
- }
- }
-
- enumerateHeaders := func(f func(name, value string)) {
- // 8.1.2.3 Request Pseudo-Header Fields
- // The :path pseudo-header field includes the path and query parts of the
- // target URI (the path-absolute production and optionally a '?' character
- // followed by the query production (see Sections 3.3 and 3.4 of
- // [RFC3986]).
- f(":authority", host)
- m := req.Method
- if m == "" {
- m = MethodGet
- }
- f(":method", m)
- if req.Method != "CONNECT" {
- f(":path", path)
- f(":scheme", req.URL.Scheme)
- }
- if trailers != "" {
- f("trailer", trailers)
- }
-
- var didUA bool
- for k, vv := range req.Header {
- if http2asciiEqualFold(k, "host") || http2asciiEqualFold(k, "content-length") {
- // Host is :authority, already sent.
- // Content-Length is automatic, set below.
- continue
- } else if http2asciiEqualFold(k, "connection") ||
- http2asciiEqualFold(k, "proxy-connection") ||
- http2asciiEqualFold(k, "transfer-encoding") ||
- http2asciiEqualFold(k, "upgrade") ||
- http2asciiEqualFold(k, "keep-alive") {
- // Per 8.1.2.2 Connection-Specific Header
- // Fields, don't send connection-specific
- // fields. We have already checked if any
- // are error-worthy so just ignore the rest.
- continue
- } else if http2asciiEqualFold(k, "user-agent") {
- // Match Go's http1 behavior: at most one
- // User-Agent. If set to nil or empty string,
- // then omit it. Otherwise if not mentioned,
- // include the default (below).
- didUA = true
- if len(vv) < 1 {
- continue
- }
- vv = vv[:1]
- if vv[0] == "" {
- continue
- }
- } else if http2asciiEqualFold(k, "cookie") {
- // Per 8.1.2.5 To allow for better compression efficiency, the
- // Cookie header field MAY be split into separate header fields,
- // each with one or more cookie-pairs.
- for _, v := range vv {
- for {
- p := strings.IndexByte(v, ';')
- if p < 0 {
- break
- }
- f("cookie", v[:p])
- p++
- // strip space after semicolon if any.
- for p+1 <= len(v) && v[p] == ' ' {
- p++
- }
- v = v[p:]
- }
- if len(v) > 0 {
- f("cookie", v)
- }
- }
- continue
- }
-
- for _, v := range vv {
- f(k, v)
- }
- }
- if http2shouldSendReqContentLength(req.Method, contentLength) {
- f("content-length", strconv.FormatInt(contentLength, 10))
- }
- if addGzipHeader {
- f("accept-encoding", "gzip")
- }
- if !didUA {
- f("user-agent", http2defaultUserAgent)
- }
- }
-
- // Do a first pass over the headers counting bytes to ensure
- // we don't exceed cc.peerMaxHeaderListSize. This is done as a
- // separate pass before encoding the headers to prevent
- // modifying the hpack state.
- hlSize := uint64(0)
- enumerateHeaders(func(name, value string) {
- hf := hpack.HeaderField{Name: name, Value: value}
- hlSize += uint64(hf.Size())
- })
-
- if hlSize > cc.peerMaxHeaderListSize {
- return nil, http2errRequestHeaderListSize
- }
-
- trace := httptrace.ContextClientTrace(req.Context())
- traceHeaders := http2traceHasWroteHeaderField(trace)
-
- // Header list size is ok. Write the headers.
- enumerateHeaders(func(name, value string) {
- name, ascii := http2lowerHeader(name)
- if !ascii {
- // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
- // field names have to be ASCII characters (just as in HTTP/1.x).
- return
- }
- cc.writeHeader(name, value)
- if traceHeaders {
- http2traceWroteHeaderField(trace, name, value)
- }
- })
-
- return cc.hbuf.Bytes(), nil
-}
-
-// shouldSendReqContentLength reports whether the http2.Transport should send
-// a "content-length" request header. This logic is basically a copy of the net/http
-// transferWriter.shouldSendContentLength.
-// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown).
-// -1 means unknown.
-func http2shouldSendReqContentLength(method string, contentLength int64) bool {
- if contentLength > 0 {
- return true
- }
- if contentLength < 0 {
- return false
- }
- // For zero bodies, whether we send a content-length depends on the method.
- // It also kinda doesn't matter for http2 either way, with END_STREAM.
- switch method {
- case "POST", "PUT", "PATCH":
- return true
- default:
- return false
- }
-}
-
-// requires cc.wmu be held.
-func (cc *http2ClientConn) encodeTrailers(trailer Header) ([]byte, error) {
- cc.hbuf.Reset()
-
- hlSize := uint64(0)
- for k, vv := range trailer {
- for _, v := range vv {
- hf := hpack.HeaderField{Name: k, Value: v}
- hlSize += uint64(hf.Size())
- }
- }
- if hlSize > cc.peerMaxHeaderListSize {
- return nil, http2errRequestHeaderListSize
- }
-
- for k, vv := range trailer {
- lowKey, ascii := http2lowerHeader(k)
- if !ascii {
- // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
- // field names have to be ASCII characters (just as in HTTP/1.x).
- continue
- }
- // Transfer-Encoding, etc.. have already been filtered at the
- // start of RoundTrip
- for _, v := range vv {
- cc.writeHeader(lowKey, v)
- }
- }
- return cc.hbuf.Bytes(), nil
-}
-
-func (cc *http2ClientConn) writeHeader(name, value string) {
- if http2VerboseLogs {
- log.Printf("http2: Transport encoding header %q = %q", name, value)
- }
- cc.henc.WriteField(hpack.HeaderField{Name: name, Value: value})
-}
-
-type http2resAndError struct {
- _ http2incomparable
- res *Response
- err error
-}
-
-// requires cc.mu be held.
-func (cc *http2ClientConn) addStreamLocked(cs *http2clientStream) {
- cs.flow.add(int32(cc.initialWindowSize))
- cs.flow.setConnFlow(&cc.flow)
- cs.inflow.add(http2transportDefaultStreamFlow)
- cs.inflow.setConnFlow(&cc.inflow)
- cs.ID = cc.nextStreamID
- cc.nextStreamID += 2
- cc.streams[cs.ID] = cs
- if cs.ID == 0 {
- panic("assigned stream ID 0")
- }
-}
-
-func (cc *http2ClientConn) forgetStreamID(id uint32) {
- cc.mu.Lock()
- slen := len(cc.streams)
- delete(cc.streams, id)
- if len(cc.streams) != slen-1 {
- panic("forgetting unknown stream id")
- }
- cc.lastActive = time.Now()
- if len(cc.streams) == 0 && cc.idleTimer != nil {
- cc.idleTimer.Reset(cc.idleTimeout)
- cc.lastIdle = time.Now()
- }
- // Wake up writeRequestBody via clientStream.awaitFlowControl and
- // wake up RoundTrip if there is a pending request.
- cc.cond.Broadcast()
-
- closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil
- if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 {
- if http2VerboseLogs {
- cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, cc.nextStreamID-2)
- }
- cc.closed = true
- defer cc.closeConn()
- }
-
- cc.mu.Unlock()
-}
-
-// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.
-type http2clientConnReadLoop struct {
- _ http2incomparable
- cc *http2ClientConn
-}
-
-// readLoop runs in its own goroutine and reads and dispatches frames.
-func (cc *http2ClientConn) readLoop() {
- rl := &http2clientConnReadLoop{cc: cc}
- defer rl.cleanup()
- cc.readerErr = rl.run()
- if ce, ok := cc.readerErr.(http2ConnectionError); ok {
- cc.wmu.Lock()
- cc.fr.WriteGoAway(0, http2ErrCode(ce), nil)
- cc.wmu.Unlock()
- }
-}
-
-// GoAwayError is returned by the Transport when the server closes the
-// TCP connection after sending a GOAWAY frame.
-type http2GoAwayError struct {
- LastStreamID uint32
- ErrCode http2ErrCode
- DebugData string
-}
-
-func (e http2GoAwayError) Error() string {
- return fmt.Sprintf("http2: server sent GOAWAY and closed the connection; LastStreamID=%v, ErrCode=%v, debug=%q",
- e.LastStreamID, e.ErrCode, e.DebugData)
-}
-
-func http2isEOFOrNetReadError(err error) bool {
- if err == io.EOF {
- return true
- }
- ne, ok := err.(*net.OpError)
- return ok && ne.Op == "read"
-}
-
-func (rl *http2clientConnReadLoop) cleanup() {
- cc := rl.cc
- cc.t.connPool().MarkDead(cc)
- defer cc.closeConn()
- defer close(cc.readerDone)
-
- if cc.idleTimer != nil {
- cc.idleTimer.Stop()
- }
-
- // Close any response bodies if the server closes prematurely.
- // TODO: also do this if we've written the headers but not
- // gotten a response yet.
- err := cc.readerErr
- cc.mu.Lock()
- if cc.goAway != nil && http2isEOFOrNetReadError(err) {
- err = http2GoAwayError{
- LastStreamID: cc.goAway.LastStreamID,
- ErrCode: cc.goAway.ErrCode,
- DebugData: cc.goAwayDebug,
- }
- } else if err == io.EOF {
- err = io.ErrUnexpectedEOF
- }
- cc.closed = true
-
- for _, cs := range cc.streams {
- select {
- case <-cs.peerClosed:
- // The server closed the stream before closing the conn,
- // so no need to interrupt it.
- default:
- cs.abortStreamLocked(err)
- }
- }
- cc.cond.Broadcast()
- cc.mu.Unlock()
-}
-
-// countReadFrameError calls Transport.CountError with a string
-// representing err.
-func (cc *http2ClientConn) countReadFrameError(err error) {
- f := cc.t.CountError
- if f == nil || err == nil {
- return
- }
- if ce, ok := err.(http2ConnectionError); ok {
- errCode := http2ErrCode(ce)
- f(fmt.Sprintf("read_frame_conn_error_%s", errCode.stringToken()))
- return
- }
- if errors.Is(err, io.EOF) {
- f("read_frame_eof")
- return
- }
- if errors.Is(err, io.ErrUnexpectedEOF) {
- f("read_frame_unexpected_eof")
- return
- }
- if errors.Is(err, http2ErrFrameTooLarge) {
- f("read_frame_too_large")
- return
- }
- f("read_frame_other")
-}
-
-func (rl *http2clientConnReadLoop) run() error {
- cc := rl.cc
- gotSettings := false
- readIdleTimeout := cc.t.ReadIdleTimeout
- var t *time.Timer
- if readIdleTimeout != 0 {
- t = time.AfterFunc(readIdleTimeout, cc.healthCheck)
- defer t.Stop()
- }
- for {
- f, err := cc.fr.ReadFrame()
- if t != nil {
- t.Reset(readIdleTimeout)
- }
- if err != nil {
- cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err)
- }
- if se, ok := err.(http2StreamError); ok {
- if cs := rl.streamByID(se.StreamID); cs != nil {
- if se.Cause == nil {
- se.Cause = cc.fr.errDetail
- }
- rl.endStreamError(cs, se)
- }
- continue
- } else if err != nil {
- cc.countReadFrameError(err)
- return err
- }
- if http2VerboseLogs {
- cc.vlogf("http2: Transport received %s", http2summarizeFrame(f))
- }
- if !gotSettings {
- if _, ok := f.(*http2SettingsFrame); !ok {
- cc.logf("protocol error: received %T before a SETTINGS frame", f)
- return http2ConnectionError(http2ErrCodeProtocol)
- }
- gotSettings = true
- }
-
- switch f := f.(type) {
- case *http2MetaHeadersFrame:
- err = rl.processHeaders(f)
- case *http2DataFrame:
- err = rl.processData(f)
- case *http2GoAwayFrame:
- err = rl.processGoAway(f)
- case *http2RSTStreamFrame:
- err = rl.processResetStream(f)
- case *http2SettingsFrame:
- err = rl.processSettings(f)
- case *http2PushPromiseFrame:
- err = rl.processPushPromise(f)
- case *http2WindowUpdateFrame:
- err = rl.processWindowUpdate(f)
- case *http2PingFrame:
- err = rl.processPing(f)
- default:
- cc.logf("Transport: unhandled response frame type %T", f)
- }
- if err != nil {
- if http2VerboseLogs {
- cc.vlogf("http2: Transport conn %p received error from processing frame %v: %v", cc, http2summarizeFrame(f), err)
- }
- return err
- }
- }
-}
-
-func (rl *http2clientConnReadLoop) processHeaders(f *http2MetaHeadersFrame) error {
- cs := rl.streamByID(f.StreamID)
- if cs == nil {
- // We'd get here if we canceled a request while the
- // server had its response still in flight. So if this
- // was just something we canceled, ignore it.
- return nil
- }
- if cs.readClosed {
- rl.endStreamError(cs, http2StreamError{
- StreamID: f.StreamID,
- Code: http2ErrCodeProtocol,
- Cause: errors.New("protocol error: headers after END_STREAM"),
- })
- return nil
- }
- if !cs.firstByte {
- if cs.trace != nil {
- // TODO(bradfitz): move first response byte earlier,
- // when we first read the 9 byte header, not waiting
- // until all the HEADERS+CONTINUATION frames have been
- // merged. This works for now.
- http2traceFirstResponseByte(cs.trace)
- }
- cs.firstByte = true
- }
- if !cs.pastHeaders {
- cs.pastHeaders = true
- } else {
- return rl.processTrailers(cs, f)
- }
-
- res, err := rl.handleResponse(cs, f)
- if err != nil {
- if _, ok := err.(http2ConnectionError); ok {
- return err
- }
- // Any other error type is a stream error.
- rl.endStreamError(cs, http2StreamError{
- StreamID: f.StreamID,
- Code: http2ErrCodeProtocol,
- Cause: err,
- })
- return nil // return nil from process* funcs to keep conn alive
- }
- if res == nil {
- // (nil, nil) special case. See handleResponse docs.
- return nil
- }
- cs.resTrailer = &res.Trailer
- cs.res = res
- close(cs.respHeaderRecv)
- if f.StreamEnded() {
- rl.endStream(cs)
- }
- return nil
-}
-
-// may return error types nil, or ConnectionError. Any other error value
-// is a StreamError of type ErrCodeProtocol. The returned error in that case
-// is the detail.
-//
-// As a special case, handleResponse may return (nil, nil) to skip the
-// frame (currently only used for 1xx responses).
-func (rl *http2clientConnReadLoop) handleResponse(cs *http2clientStream, f *http2MetaHeadersFrame) (*Response, error) {
- if f.Truncated {
- return nil, http2errResponseHeaderListSize
- }
-
- status := f.PseudoValue("status")
- if status == "" {
- return nil, errors.New("malformed response from server: missing status pseudo header")
- }
- statusCode, err := strconv.Atoi(status)
- if err != nil {
- return nil, errors.New("malformed response from server: malformed non-numeric status pseudo header")
- }
-
- regularFields := f.RegularFields()
- strs := make([]string, len(regularFields))
- header := make(Header, len(regularFields))
- res := &Response{
- Proto: "HTTP/2.0",
- ProtoMajor: 2,
- Header: header,
- StatusCode: statusCode,
- Status: status + " " + StatusText(statusCode),
- }
- for _, hf := range regularFields {
- key := http2canonicalHeader(hf.Name)
- if key == "Trailer" {
- t := res.Trailer
- if t == nil {
- t = make(Header)
- res.Trailer = t
- }
- http2foreachHeaderElement(hf.Value, func(v string) {
- t[http2canonicalHeader(v)] = nil
- })
- } else {
- vv := header[key]
- if vv == nil && len(strs) > 0 {
- // More than likely this will be a single-element key.
- // Most headers aren't multi-valued.
- // Set the capacity on strs[0] to 1, so any future append
- // won't extend the slice into the other strings.
- vv, strs = strs[:1:1], strs[1:]
- vv[0] = hf.Value
- header[key] = vv
- } else {
- header[key] = append(vv, hf.Value)
- }
- }
- }
-
- if statusCode >= 100 && statusCode <= 199 {
- if f.StreamEnded() {
- return nil, errors.New("1xx informational response with END_STREAM flag")
- }
- cs.num1xx++
- const max1xxResponses = 5 // arbitrary bound on number of informational responses, same as net/http
- if cs.num1xx > max1xxResponses {
- return nil, errors.New("http2: too many 1xx informational responses")
- }
- if fn := cs.get1xxTraceFunc(); fn != nil {
- if err := fn(statusCode, textproto.MIMEHeader(header)); err != nil {
- return nil, err
- }
- }
- if statusCode == 100 {
- http2traceGot100Continue(cs.trace)
- select {
- case cs.on100 <- struct{}{}:
- default:
- }
- }
- cs.pastHeaders = false // do it all again
- return nil, nil
- }
-
- res.ContentLength = -1
- if clens := res.Header["Content-Length"]; len(clens) == 1 {
- if cl, err := strconv.ParseUint(clens[0], 10, 63); err == nil {
- res.ContentLength = int64(cl)
- } else {
- // TODO: care? unlike http/1, it won't mess up our framing, so it's
- // more safe smuggling-wise to ignore.
- }
- } else if len(clens) > 1 {
- // TODO: care? unlike http/1, it won't mess up our framing, so it's
- // more safe smuggling-wise to ignore.
- } else if f.StreamEnded() && !cs.isHead {
- res.ContentLength = 0
- }
-
- if cs.isHead {
- res.Body = http2noBody
- return res, nil
- }
-
- if f.StreamEnded() {
- if res.ContentLength > 0 {
- res.Body = http2missingBody{}
- } else {
- res.Body = http2noBody
- }
- return res, nil
- }
-
- cs.bufPipe.setBuffer(&http2dataBuffer{expected: res.ContentLength})
- cs.bytesRemain = res.ContentLength
- res.Body = http2transportResponseBody{cs}
-
- if cs.requestedGzip && http2asciiEqualFold(res.Header.Get("Content-Encoding"), "gzip") {
- res.Header.Del("Content-Encoding")
- res.Header.Del("Content-Length")
- res.ContentLength = -1
- res.Body = &http2gzipReader{body: res.Body}
- res.Uncompressed = true
- }
- return res, nil
-}
-
-func (rl *http2clientConnReadLoop) processTrailers(cs *http2clientStream, f *http2MetaHeadersFrame) error {
- if cs.pastTrailers {
- // Too many HEADERS frames for this stream.
- return http2ConnectionError(http2ErrCodeProtocol)
- }
- cs.pastTrailers = true
- if !f.StreamEnded() {
- // We expect that any headers for trailers also
- // has END_STREAM.
- return http2ConnectionError(http2ErrCodeProtocol)
- }
- if len(f.PseudoFields()) > 0 {
- // No pseudo header fields are defined for trailers.
- // TODO: ConnectionError might be overly harsh? Check.
- return http2ConnectionError(http2ErrCodeProtocol)
- }
-
- trailer := make(Header)
- for _, hf := range f.RegularFields() {
- key := http2canonicalHeader(hf.Name)
- trailer[key] = append(trailer[key], hf.Value)
- }
- cs.trailer = trailer
-
- rl.endStream(cs)
- return nil
-}
-
-// transportResponseBody is the concrete type of Transport.RoundTrip's
-// Response.Body. It is an io.ReadCloser.
-type http2transportResponseBody struct {
- cs *http2clientStream
-}
-
-func (b http2transportResponseBody) Read(p []byte) (n int, err error) {
- cs := b.cs
- cc := cs.cc
-
- if cs.readErr != nil {
- return 0, cs.readErr
- }
- n, err = b.cs.bufPipe.Read(p)
- if cs.bytesRemain != -1 {
- if int64(n) > cs.bytesRemain {
- n = int(cs.bytesRemain)
- if err == nil {
- err = errors.New("net/http: server replied with more than declared Content-Length; truncated")
- cs.abortStream(err)
- }
- cs.readErr = err
- return int(cs.bytesRemain), err
- }
- cs.bytesRemain -= int64(n)
- if err == io.EOF && cs.bytesRemain > 0 {
- err = io.ErrUnexpectedEOF
- cs.readErr = err
- return n, err
- }
- }
- if n == 0 {
- // No flow control tokens to send back.
- return
- }
-
- cc.mu.Lock()
- var connAdd, streamAdd int32
- // Check the conn-level first, before the stream-level.
- if v := cc.inflow.available(); v < http2transportDefaultConnFlow/2 {
- connAdd = http2transportDefaultConnFlow - v
- cc.inflow.add(connAdd)
- }
- if err == nil { // No need to refresh if the stream is over or failed.
- // Consider any buffered body data (read from the conn but not
- // consumed by the client) when computing flow control for this
- // stream.
- v := int(cs.inflow.available()) + cs.bufPipe.Len()
- if v < http2transportDefaultStreamFlow-http2transportDefaultStreamMinRefresh {
- streamAdd = int32(http2transportDefaultStreamFlow - v)
- cs.inflow.add(streamAdd)
- }
- }
- cc.mu.Unlock()
-
- if connAdd != 0 || streamAdd != 0 {
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
- if connAdd != 0 {
- cc.fr.WriteWindowUpdate(0, http2mustUint31(connAdd))
- }
- if streamAdd != 0 {
- cc.fr.WriteWindowUpdate(cs.ID, http2mustUint31(streamAdd))
- }
- cc.bw.Flush()
- }
- return
-}
-
-var http2errClosedResponseBody = errors.New("http2: response body closed")
-
-func (b http2transportResponseBody) Close() error {
- cs := b.cs
- cc := cs.cc
-
- unread := cs.bufPipe.Len()
- if unread > 0 {
- cc.mu.Lock()
- // Return connection-level flow control.
- if unread > 0 {
- cc.inflow.add(int32(unread))
- }
- cc.mu.Unlock()
-
- // TODO(dneil): Acquiring this mutex can block indefinitely.
- // Move flow control return to a goroutine?
- cc.wmu.Lock()
- // Return connection-level flow control.
- if unread > 0 {
- cc.fr.WriteWindowUpdate(0, uint32(unread))
- }
- cc.bw.Flush()
- cc.wmu.Unlock()
- }
-
- cs.bufPipe.BreakWithError(http2errClosedResponseBody)
- cs.abortStream(http2errClosedResponseBody)
-
- select {
- case <-cs.donec:
- case <-cs.ctx.Done():
- // See golang/go#49366: The net/http package can cancel the
- // request context after the response body is fully read.
- // Don't treat this as an error.
- return nil
- case <-cs.reqCancel:
- return http2errRequestCanceled
- }
- return nil
-}
-
-func (rl *http2clientConnReadLoop) processData(f *http2DataFrame) error {
- cc := rl.cc
- cs := rl.streamByID(f.StreamID)
- data := f.Data()
- if cs == nil {
- cc.mu.Lock()
- neverSent := cc.nextStreamID
- cc.mu.Unlock()
- if f.StreamID >= neverSent {
- // We never asked for this.
- cc.logf("http2: Transport received unsolicited DATA frame; closing connection")
- return http2ConnectionError(http2ErrCodeProtocol)
- }
- // We probably did ask for this, but canceled. Just ignore it.
- // TODO: be stricter here? only silently ignore things which
- // we canceled, but not things which were closed normally
- // by the peer? Tough without accumulating too much state.
-
- // But at least return their flow control:
- if f.Length > 0 {
- cc.mu.Lock()
- cc.inflow.add(int32(f.Length))
- cc.mu.Unlock()
-
- cc.wmu.Lock()
- cc.fr.WriteWindowUpdate(0, uint32(f.Length))
- cc.bw.Flush()
- cc.wmu.Unlock()
- }
- return nil
- }
- if cs.readClosed {
- cc.logf("protocol error: received DATA after END_STREAM")
- rl.endStreamError(cs, http2StreamError{
- StreamID: f.StreamID,
- Code: http2ErrCodeProtocol,
- })
- return nil
- }
- if !cs.firstByte {
- cc.logf("protocol error: received DATA before a HEADERS frame")
- rl.endStreamError(cs, http2StreamError{
- StreamID: f.StreamID,
- Code: http2ErrCodeProtocol,
- })
- return nil
- }
- if f.Length > 0 {
- if cs.isHead && len(data) > 0 {
- cc.logf("protocol error: received DATA on a HEAD request")
- rl.endStreamError(cs, http2StreamError{
- StreamID: f.StreamID,
- Code: http2ErrCodeProtocol,
- })
- return nil
- }
- // Check connection-level flow control.
- cc.mu.Lock()
- if cs.inflow.available() >= int32(f.Length) {
- cs.inflow.take(int32(f.Length))
- } else {
- cc.mu.Unlock()
- return http2ConnectionError(http2ErrCodeFlowControl)
- }
- // Return any padded flow control now, since we won't
- // refund it later on body reads.
- var refund int
- if pad := int(f.Length) - len(data); pad > 0 {
- refund += pad
- }
-
- didReset := false
- var err error
- if len(data) > 0 {
- if _, err = cs.bufPipe.Write(data); err != nil {
- // Return len(data) now if the stream is already closed,
- // since data will never be read.
- didReset = true
- refund += len(data)
- }
- }
-
- if refund > 0 {
- cc.inflow.add(int32(refund))
- if !didReset {
- cs.inflow.add(int32(refund))
- }
- }
- cc.mu.Unlock()
-
- if refund > 0 {
- cc.wmu.Lock()
- cc.fr.WriteWindowUpdate(0, uint32(refund))
- if !didReset {
- cc.fr.WriteWindowUpdate(cs.ID, uint32(refund))
- }
- cc.bw.Flush()
- cc.wmu.Unlock()
- }
-
- if err != nil {
- rl.endStreamError(cs, err)
- return nil
- }
- }
-
- if f.StreamEnded() {
- rl.endStream(cs)
- }
- return nil
-}
-
-func (rl *http2clientConnReadLoop) endStream(cs *http2clientStream) {
- // TODO: check that any declared content-length matches, like
- // server.go's (*stream).endStream method.
- if !cs.readClosed {
- cs.readClosed = true
- // Close cs.bufPipe and cs.peerClosed with cc.mu held to avoid a
- // race condition: The caller can read io.EOF from Response.Body
- // and close the body before we close cs.peerClosed, causing
- // cleanupWriteRequest to send a RST_STREAM.
- rl.cc.mu.Lock()
- defer rl.cc.mu.Unlock()
- cs.bufPipe.closeWithErrorAndCode(io.EOF, cs.copyTrailers)
- close(cs.peerClosed)
- }
-}
-
-func (rl *http2clientConnReadLoop) endStreamError(cs *http2clientStream, err error) {
- cs.readAborted = true
- cs.abortStream(err)
-}
-
-func (rl *http2clientConnReadLoop) streamByID(id uint32) *http2clientStream {
- rl.cc.mu.Lock()
- defer rl.cc.mu.Unlock()
- cs := rl.cc.streams[id]
- if cs != nil && !cs.readAborted {
- return cs
- }
- return nil
-}
-
-func (cs *http2clientStream) copyTrailers() {
- for k, vv := range cs.trailer {
- t := cs.resTrailer
- if *t == nil {
- *t = make(Header)
- }
- (*t)[k] = vv
- }
-}
-
-func (rl *http2clientConnReadLoop) processGoAway(f *http2GoAwayFrame) error {
- cc := rl.cc
- cc.t.connPool().MarkDead(cc)
- if f.ErrCode != 0 {
- // TODO: deal with GOAWAY more. particularly the error code
- cc.vlogf("transport got GOAWAY with error code = %v", f.ErrCode)
- if fn := cc.t.CountError; fn != nil {
- fn("recv_goaway_" + f.ErrCode.stringToken())
- }
- }
- cc.setGoAway(f)
- return nil
-}
-
-func (rl *http2clientConnReadLoop) processSettings(f *http2SettingsFrame) error {
- cc := rl.cc
- // Locking both mu and wmu here allows frame encoding to read settings with only wmu held.
- // Acquiring wmu when f.IsAck() is unnecessary, but convenient and mostly harmless.
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
-
- if err := rl.processSettingsNoWrite(f); err != nil {
- return err
- }
- if !f.IsAck() {
- cc.fr.WriteSettingsAck()
- cc.bw.Flush()
- }
- return nil
-}
-
-func (rl *http2clientConnReadLoop) processSettingsNoWrite(f *http2SettingsFrame) error {
- cc := rl.cc
- cc.mu.Lock()
- defer cc.mu.Unlock()
-
- if f.IsAck() {
- if cc.wantSettingsAck {
- cc.wantSettingsAck = false
- return nil
- }
- return http2ConnectionError(http2ErrCodeProtocol)
- }
-
- var seenMaxConcurrentStreams bool
- err := f.ForeachSetting(func(s http2Setting) error {
- switch s.ID {
- case http2SettingMaxFrameSize:
- cc.maxFrameSize = s.Val
- case http2SettingMaxConcurrentStreams:
- cc.maxConcurrentStreams = s.Val
- seenMaxConcurrentStreams = true
- case http2SettingMaxHeaderListSize:
- cc.peerMaxHeaderListSize = uint64(s.Val)
- case http2SettingInitialWindowSize:
- // Values above the maximum flow-control
- // window size of 2^31-1 MUST be treated as a
- // connection error (Section 5.4.1) of type
- // FLOW_CONTROL_ERROR.
- if s.Val > math.MaxInt32 {
- return http2ConnectionError(http2ErrCodeFlowControl)
- }
-
- // Adjust flow control of currently-open
- // frames by the difference of the old initial
- // window size and this one.
- delta := int32(s.Val) - int32(cc.initialWindowSize)
- for _, cs := range cc.streams {
- cs.flow.add(delta)
- }
- cc.cond.Broadcast()
-
- cc.initialWindowSize = s.Val
- case http2SettingHeaderTableSize:
- cc.henc.SetMaxDynamicTableSize(s.Val)
- cc.peerMaxHeaderTableSize = s.Val
- default:
- cc.vlogf("Unhandled Setting: %v", s)
- }
- return nil
- })
- if err != nil {
- return err
- }
-
- if !cc.seenSettings {
- if !seenMaxConcurrentStreams {
- // This was the servers initial SETTINGS frame and it
- // didn't contain a MAX_CONCURRENT_STREAMS field so
- // increase the number of concurrent streams this
- // connection can establish to our default.
- cc.maxConcurrentStreams = http2defaultMaxConcurrentStreams
- }
- cc.seenSettings = true
- }
-
- return nil
-}
-
-func (rl *http2clientConnReadLoop) processWindowUpdate(f *http2WindowUpdateFrame) error {
- cc := rl.cc
- cs := rl.streamByID(f.StreamID)
- if f.StreamID != 0 && cs == nil {
- return nil
- }
-
- cc.mu.Lock()
- defer cc.mu.Unlock()
-
- fl := &cc.flow
- if cs != nil {
- fl = &cs.flow
- }
- if !fl.add(int32(f.Increment)) {
- return http2ConnectionError(http2ErrCodeFlowControl)
- }
- cc.cond.Broadcast()
- return nil
-}
-
-func (rl *http2clientConnReadLoop) processResetStream(f *http2RSTStreamFrame) error {
- cs := rl.streamByID(f.StreamID)
- if cs == nil {
- // TODO: return error if server tries to RST_STREAM an idle stream
- return nil
- }
- serr := http2streamError(cs.ID, f.ErrCode)
- serr.Cause = http2errFromPeer
- if f.ErrCode == http2ErrCodeProtocol {
- rl.cc.SetDoNotReuse()
- }
- if fn := cs.cc.t.CountError; fn != nil {
- fn("recv_rststream_" + f.ErrCode.stringToken())
- }
- cs.abortStream(serr)
-
- cs.bufPipe.CloseWithError(serr)
- return nil
-}
-
-// Ping sends a PING frame to the server and waits for the ack.
-func (cc *http2ClientConn) Ping(ctx context.Context) error {
- c := make(chan struct{})
- // Generate a random payload
- var p [8]byte
- for {
- if _, err := rand.Read(p[:]); err != nil {
- return err
- }
- cc.mu.Lock()
- // check for dup before insert
- if _, found := cc.pings[p]; !found {
- cc.pings[p] = c
- cc.mu.Unlock()
- break
- }
- cc.mu.Unlock()
- }
- errc := make(chan error, 1)
- go func() {
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
- if err := cc.fr.WritePing(false, p); err != nil {
- errc <- err
- return
- }
- if err := cc.bw.Flush(); err != nil {
- errc <- err
- return
- }
- }()
- select {
- case <-c:
- return nil
- case err := <-errc:
- return err
- case <-ctx.Done():
- return ctx.Err()
- case <-cc.readerDone:
- // connection closed
- return cc.readerErr
- }
-}
-
-func (rl *http2clientConnReadLoop) processPing(f *http2PingFrame) error {
- if f.IsAck() {
- cc := rl.cc
- cc.mu.Lock()
- defer cc.mu.Unlock()
- // If ack, notify listener if any
- if c, ok := cc.pings[f.Data]; ok {
- close(c)
- delete(cc.pings, f.Data)
- }
- return nil
- }
- cc := rl.cc
- cc.wmu.Lock()
- defer cc.wmu.Unlock()
- if err := cc.fr.WritePing(true, f.Data); err != nil {
- return err
- }
- return cc.bw.Flush()
-}
-
-func (rl *http2clientConnReadLoop) processPushPromise(f *http2PushPromiseFrame) error {
- // We told the peer we don't want them.
- // Spec says:
- // "PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH
- // setting of the peer endpoint is set to 0. An endpoint that
- // has set this setting and has received acknowledgement MUST
- // treat the receipt of a PUSH_PROMISE frame as a connection
- // error (Section 5.4.1) of type PROTOCOL_ERROR."
- return http2ConnectionError(http2ErrCodeProtocol)
-}
-
-func (cc *http2ClientConn) writeStreamReset(streamID uint32, code http2ErrCode, err error) {
- // TODO: map err to more interesting error codes, once the
- // HTTP community comes up with some. But currently for
- // RST_STREAM there's no equivalent to GOAWAY frame's debug
- // data, and the error codes are all pretty vague ("cancel").
- cc.wmu.Lock()
- cc.fr.WriteRSTStream(streamID, code)
- cc.bw.Flush()
- cc.wmu.Unlock()
-}
-
-var (
- http2errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit")
- http2errRequestHeaderListSize = errors.New("http2: request header list larger than peer's advertised limit")
-)
-
-func (cc *http2ClientConn) logf(format string, args ...interface{}) {
- cc.t.logf(format, args...)
-}
-
-func (cc *http2ClientConn) vlogf(format string, args ...interface{}) {
- cc.t.vlogf(format, args...)
-}
-
-func (t *http2Transport) vlogf(format string, args ...interface{}) {
- if http2VerboseLogs {
- t.logf(format, args...)
- }
-}
-
-func (t *http2Transport) logf(format string, args ...interface{}) {
- log.Printf(format, args...)
-}
-
-var http2noBody io.ReadCloser = http2noBodyReader{}
-
-type http2noBodyReader struct{}
-
-func (http2noBodyReader) Close() error { return nil }
-
-func (http2noBodyReader) Read([]byte) (int, error) { return 0, io.EOF }
-
-type http2missingBody struct{}
-
-func (http2missingBody) Close() error { return nil }
-
-func (http2missingBody) Read([]byte) (int, error) { return 0, io.ErrUnexpectedEOF }
-
-func http2strSliceContains(ss []string, s string) bool {
- for _, v := range ss {
- if v == s {
- return true
- }
- }
- return false
-}
-
-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
-// call gzip.NewReader on the first call to Read
-type http2gzipReader struct {
- _ http2incomparable
- body io.ReadCloser // underlying Response.Body
- zr *gzip.Reader // lazily-initialized gzip reader
- zerr error // sticky error
-}
-
-func (gz *http2gzipReader) Read(p []byte) (n int, err error) {
- if gz.zerr != nil {
- return 0, gz.zerr
- }
- if gz.zr == nil {
- gz.zr, err = gzip.NewReader(gz.body)
- if err != nil {
- gz.zerr = err
- return 0, err
- }
- }
- return gz.zr.Read(p)
-}
-
-func (gz *http2gzipReader) Close() error {
- if err := gz.body.Close(); err != nil {
- return err
- }
- gz.zerr = fs.ErrClosed
- return nil
-}
-
-type http2errorReader struct{ err error }
-
-func (r http2errorReader) Read(p []byte) (int, error) { return 0, r.err }
-
-// isConnectionCloseRequest reports whether req should use its own
-// connection for a single request and then close the connection.
-func http2isConnectionCloseRequest(req *Request) bool {
- return req.Close || httpguts.HeaderValuesContainsToken(req.Header["Connection"], "close")
-}
-
-// registerHTTPSProtocol calls Transport.RegisterProtocol but
-// converting panics into errors.
-func http2registerHTTPSProtocol(t *Transport, rt http2noDialH2RoundTripper) (err error) {
- defer func() {
- if e := recover(); e != nil {
- err = fmt.Errorf("%v", e)
- }
- }()
- t.RegisterProtocol("https", rt)
- return nil
-}
-
-// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
-// if there's already has a cached connection to the host.
-// (The field is exported so it can be accessed via reflect from net/http; tested
-// by TestNoDialH2RoundTripperType)
-type http2noDialH2RoundTripper struct{ *http2Transport }
-
-func (rt http2noDialH2RoundTripper) RoundTrip(req *Request) (*Response, error) {
- res, err := rt.http2Transport.RoundTrip(req)
- if http2isNoCachedConnError(err) {
- return nil, ErrSkipAltProtocol
- }
- return res, err
-}
-
-func (t *http2Transport) idleConnTimeout() time.Duration {
- if t.t1 != nil {
- return t.t1.IdleConnTimeout
- }
- return 0
-}
-
-func http2traceGetConn(req *Request, hostPort string) {
- trace := httptrace.ContextClientTrace(req.Context())
- if trace == nil || trace.GetConn == nil {
- return
- }
- trace.GetConn(hostPort)
-}
-
-func http2traceGotConn(req *Request, cc *http2ClientConn, reused bool) {
- trace := httptrace.ContextClientTrace(req.Context())
- if trace == nil || trace.GotConn == nil {
- return
- }
- ci := httptrace.GotConnInfo{Conn: cc.tconn}
- ci.Reused = reused
- cc.mu.Lock()
- ci.WasIdle = len(cc.streams) == 0 && reused
- if ci.WasIdle && !cc.lastActive.IsZero() {
- ci.IdleTime = time.Since(cc.lastActive)
- }
- cc.mu.Unlock()
-
- trace.GotConn(ci)
-}
-
-func http2traceWroteHeaders(trace *httptrace.ClientTrace) {
- if trace != nil && trace.WroteHeaders != nil {
- trace.WroteHeaders()
- }
-}
-
-func http2traceGot100Continue(trace *httptrace.ClientTrace) {
- if trace != nil && trace.Got100Continue != nil {
- trace.Got100Continue()
- }
-}
-
-func http2traceWait100Continue(trace *httptrace.ClientTrace) {
- if trace != nil && trace.Wait100Continue != nil {
- trace.Wait100Continue()
- }
-}
-
-func http2traceWroteRequest(trace *httptrace.ClientTrace, err error) {
- if trace != nil && trace.WroteRequest != nil {
- trace.WroteRequest(httptrace.WroteRequestInfo{Err: err})
- }
-}
-
-func http2traceFirstResponseByte(trace *httptrace.ClientTrace) {
- if trace != nil && trace.GotFirstResponseByte != nil {
- trace.GotFirstResponseByte()
- }
-}
-
-// writeFramer is implemented by any type that is used to write frames.
-type http2writeFramer interface {
- writeFrame(http2writeContext) error
-
- // staysWithinBuffer reports whether this writer promises that
- // it will only write less than or equal to size bytes, and it
- // won't Flush the write context.
- staysWithinBuffer(size int) bool
-}
-
-// writeContext is the interface needed by the various frame writer
-// types below. All the writeFrame methods below are scheduled via the
-// frame writing scheduler (see writeScheduler in writesched.go).
-//
-// This interface is implemented by *serverConn.
-//
-// TODO: decide whether to a) use this in the client code (which didn't
-// end up using this yet, because it has a simpler design, not
-// currently implementing priorities), or b) delete this and
-// make the server code a bit more concrete.
-type http2writeContext interface {
- Framer() *http2Framer
- Flush() error
- CloseConn() error
- // HeaderEncoder returns an HPACK encoder that writes to the
- // returned buffer.
- HeaderEncoder() (*hpack.Encoder, *bytes.Buffer)
-}
-
-// writeEndsStream reports whether w writes a frame that will transition
-// the stream to a half-closed local state. This returns false for RST_STREAM,
-// which closes the entire stream (not just the local half).
-func http2writeEndsStream(w http2writeFramer) bool {
- switch v := w.(type) {
- case *http2writeData:
- return v.endStream
- case *http2writeResHeaders:
- return v.endStream
- case nil:
- // This can only happen if the caller reuses w after it's
- // been intentionally nil'ed out to prevent use. Keep this
- // here to catch future refactoring breaking it.
- panic("writeEndsStream called on nil writeFramer")
- }
- return false
-}
-
-type http2flushFrameWriter struct{}
-
-func (http2flushFrameWriter) writeFrame(ctx http2writeContext) error {
- return ctx.Flush()
-}
-
-func (http2flushFrameWriter) staysWithinBuffer(max int) bool { return false }
-
-type http2writeSettings []http2Setting
-
-func (s http2writeSettings) staysWithinBuffer(max int) bool {
- const settingSize = 6 // uint16 + uint32
- return http2frameHeaderLen+settingSize*len(s) <= max
-
-}
-
-func (s http2writeSettings) writeFrame(ctx http2writeContext) error {
- return ctx.Framer().WriteSettings([]http2Setting(s)...)
-}
-
-type http2writeGoAway struct {
- maxStreamID uint32
- code http2ErrCode
-}
-
-func (p *http2writeGoAway) writeFrame(ctx http2writeContext) error {
- err := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil)
- ctx.Flush() // ignore error: we're hanging up on them anyway
- return err
-}
-
-func (*http2writeGoAway) staysWithinBuffer(max int) bool { return false } // flushes
-
-type http2writeData struct {
- streamID uint32
- p []byte
- endStream bool
-}
-
-func (w *http2writeData) String() string {
- return fmt.Sprintf("writeData(stream=%d, p=%d, endStream=%v)", w.streamID, len(w.p), w.endStream)
-}
-
-func (w *http2writeData) writeFrame(ctx http2writeContext) error {
- return ctx.Framer().WriteData(w.streamID, w.endStream, w.p)
-}
-
-func (w *http2writeData) staysWithinBuffer(max int) bool {
- return http2frameHeaderLen+len(w.p) <= max
-}
-
-// handlerPanicRST is the message sent from handler goroutines when
-// the handler panics.
-type http2handlerPanicRST struct {
- StreamID uint32
-}
-
-func (hp http2handlerPanicRST) writeFrame(ctx http2writeContext) error {
- return ctx.Framer().WriteRSTStream(hp.StreamID, http2ErrCodeInternal)
-}
-
-func (hp http2handlerPanicRST) staysWithinBuffer(max int) bool { return http2frameHeaderLen+4 <= max }
-
-func (se http2StreamError) writeFrame(ctx http2writeContext) error {
- return ctx.Framer().WriteRSTStream(se.StreamID, se.Code)
-}
-
-func (se http2StreamError) staysWithinBuffer(max int) bool { return http2frameHeaderLen+4 <= max }
-
-type http2writePingAck struct{ pf *http2PingFrame }
-
-func (w http2writePingAck) writeFrame(ctx http2writeContext) error {
- return ctx.Framer().WritePing(true, w.pf.Data)
-}
-
-func (w http2writePingAck) staysWithinBuffer(max int) bool {
- return http2frameHeaderLen+len(w.pf.Data) <= max
-}
-
-type http2writeSettingsAck struct{}
-
-func (http2writeSettingsAck) writeFrame(ctx http2writeContext) error {
- return ctx.Framer().WriteSettingsAck()
-}
-
-func (http2writeSettingsAck) staysWithinBuffer(max int) bool { return http2frameHeaderLen <= max }
-
-// splitHeaderBlock splits headerBlock into fragments so that each fragment fits
-// in a single frame, then calls fn for each fragment. firstFrag/lastFrag are true
-// for the first/last fragment, respectively.
-func http2splitHeaderBlock(ctx http2writeContext, headerBlock []byte, fn func(ctx http2writeContext, frag []byte, firstFrag, lastFrag bool) error) error {
- // For now we're lazy and just pick the minimum MAX_FRAME_SIZE
- // that all peers must support (16KB). Later we could care
- // more and send larger frames if the peer advertised it, but
- // there's little point. Most headers are small anyway (so we
- // generally won't have CONTINUATION frames), and extra frames
- // only waste 9 bytes anyway.
- const maxFrameSize = 16384
-
- first := true
- for len(headerBlock) > 0 {
- frag := headerBlock
- if len(frag) > maxFrameSize {
- frag = frag[:maxFrameSize]
- }
- headerBlock = headerBlock[len(frag):]
- if err := fn(ctx, frag, first, len(headerBlock) == 0); err != nil {
- return err
- }
- first = false
- }
- return nil
-}
-
-// writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames
-// for HTTP response headers or trailers from a server handler.
-type http2writeResHeaders struct {
- streamID uint32
- httpResCode int // 0 means no ":status" line
- h Header // may be nil
- trailers []string // if non-nil, which keys of h to write. nil means all.
- endStream bool
-
- date string
- contentType string
- contentLength string
-}
-
-func http2encKV(enc *hpack.Encoder, k, v string) {
- if http2VerboseLogs {
- log.Printf("http2: server encoding header %q = %q", k, v)
- }
- enc.WriteField(hpack.HeaderField{Name: k, Value: v})
-}
-
-func (w *http2writeResHeaders) staysWithinBuffer(max int) bool {
- // TODO: this is a common one. It'd be nice to return true
- // here and get into the fast path if we could be clever and
- // calculate the size fast enough, or at least a conservative
- // upper bound that usually fires. (Maybe if w.h and
- // w.trailers are nil, so we don't need to enumerate it.)
- // Otherwise I'm afraid that just calculating the length to
- // answer this question would be slower than the ~2µs benefit.
- return false
-}
-
-func (w *http2writeResHeaders) writeFrame(ctx http2writeContext) error {
- enc, buf := ctx.HeaderEncoder()
- buf.Reset()
-
- if w.httpResCode != 0 {
- http2encKV(enc, ":status", http2httpCodeString(w.httpResCode))
- }
-
- http2encodeHeaders(enc, w.h, w.trailers)
-
- if w.contentType != "" {
- http2encKV(enc, "content-type", w.contentType)
- }
- if w.contentLength != "" {
- http2encKV(enc, "content-length", w.contentLength)
- }
- if w.date != "" {
- http2encKV(enc, "date", w.date)
- }
-
- headerBlock := buf.Bytes()
- if len(headerBlock) == 0 && w.trailers == nil {
- panic("unexpected empty hpack")
- }
-
- return http2splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock)
-}
-
-func (w *http2writeResHeaders) writeHeaderBlock(ctx http2writeContext, frag []byte, firstFrag, lastFrag bool) error {
- if firstFrag {
- return ctx.Framer().WriteHeaders(http2HeadersFrameParam{
- StreamID: w.streamID,
- BlockFragment: frag,
- EndStream: w.endStream,
- EndHeaders: lastFrag,
- })
- } else {
- return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag)
- }
-}
-
-// writePushPromise is a request to write a PUSH_PROMISE and 0+ CONTINUATION frames.
-type http2writePushPromise struct {
- streamID uint32 // pusher stream
- method string // for :method
- url *url.URL // for :scheme, :authority, :path
- h Header
-
- // Creates an ID for a pushed stream. This runs on serveG just before
- // the frame is written. The returned ID is copied to promisedID.
- allocatePromisedID func() (uint32, error)
- promisedID uint32
-}
-
-func (w *http2writePushPromise) staysWithinBuffer(max int) bool {
- // TODO: see writeResHeaders.staysWithinBuffer
- return false
-}
-
-func (w *http2writePushPromise) writeFrame(ctx http2writeContext) error {
- enc, buf := ctx.HeaderEncoder()
- buf.Reset()
-
- http2encKV(enc, ":method", w.method)
- http2encKV(enc, ":scheme", w.url.Scheme)
- http2encKV(enc, ":authority", w.url.Host)
- http2encKV(enc, ":path", w.url.RequestURI())
- http2encodeHeaders(enc, w.h, nil)
-
- headerBlock := buf.Bytes()
- if len(headerBlock) == 0 {
- panic("unexpected empty hpack")
- }
-
- return http2splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock)
-}
-
-func (w *http2writePushPromise) writeHeaderBlock(ctx http2writeContext, frag []byte, firstFrag, lastFrag bool) error {
- if firstFrag {
- return ctx.Framer().WritePushPromise(http2PushPromiseParam{
- StreamID: w.streamID,
- PromiseID: w.promisedID,
- BlockFragment: frag,
- EndHeaders: lastFrag,
- })
- } else {
- return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag)
- }
-}
-
-type http2write100ContinueHeadersFrame struct {
- streamID uint32
-}
-
-func (w http2write100ContinueHeadersFrame) writeFrame(ctx http2writeContext) error {
- enc, buf := ctx.HeaderEncoder()
- buf.Reset()
- http2encKV(enc, ":status", "100")
- return ctx.Framer().WriteHeaders(http2HeadersFrameParam{
- StreamID: w.streamID,
- BlockFragment: buf.Bytes(),
- EndStream: false,
- EndHeaders: true,
- })
-}
-
-func (w http2write100ContinueHeadersFrame) staysWithinBuffer(max int) bool {
- // Sloppy but conservative:
- return 9+2*(len(":status")+len("100")) <= max
-}
-
-type http2writeWindowUpdate struct {
- streamID uint32 // or 0 for conn-level
- n uint32
-}
-
-func (wu http2writeWindowUpdate) staysWithinBuffer(max int) bool { return http2frameHeaderLen+4 <= max }
-
-func (wu http2writeWindowUpdate) writeFrame(ctx http2writeContext) error {
- return ctx.Framer().WriteWindowUpdate(wu.streamID, wu.n)
-}
-
-// encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k])
-// is encoded only if k is in keys.
-func http2encodeHeaders(enc *hpack.Encoder, h Header, keys []string) {
- if keys == nil {
- sorter := http2sorterPool.Get().(*http2sorter)
- // Using defer here, since the returned keys from the
- // sorter.Keys method is only valid until the sorter
- // is returned:
- defer http2sorterPool.Put(sorter)
- keys = sorter.Keys(h)
- }
- for _, k := range keys {
- vv := h[k]
- k, ascii := http2lowerHeader(k)
- if !ascii {
- // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
- // field names have to be ASCII characters (just as in HTTP/1.x).
- continue
- }
- if !http2validWireHeaderFieldName(k) {
- // Skip it as backup paranoia. Per
- // golang.org/issue/14048, these should
- // already be rejected at a higher level.
- continue
- }
- isTE := k == "transfer-encoding"
- for _, v := range vv {
- if !httpguts.ValidHeaderFieldValue(v) {
- // TODO: return an error? golang.org/issue/14048
- // For now just omit it.
- continue
- }
- // TODO: more of "8.1.2.2 Connection-Specific Header Fields"
- if isTE && v != "trailers" {
- continue
- }
- http2encKV(enc, k, v)
- }
- }
-}
-
-// WriteScheduler is the interface implemented by HTTP/2 write schedulers.
-// Methods are never called concurrently.
-type http2WriteScheduler interface {
- // OpenStream opens a new stream in the write scheduler.
- // It is illegal to call this with streamID=0 or with a streamID that is
- // already open -- the call may panic.
- OpenStream(streamID uint32, options http2OpenStreamOptions)
-
- // CloseStream closes a stream in the write scheduler. Any frames queued on
- // this stream should be discarded. It is illegal to call this on a stream
- // that is not open -- the call may panic.
- CloseStream(streamID uint32)
-
- // AdjustStream adjusts the priority of the given stream. This may be called
- // on a stream that has not yet been opened or has been closed. Note that
- // RFC 7540 allows PRIORITY frames to be sent on streams in any state. See:
- // https://tools.ietf.org/html/rfc7540#section-5.1
- AdjustStream(streamID uint32, priority http2PriorityParam)
-
- // Push queues a frame in the scheduler. In most cases, this will not be
- // called with wr.StreamID()!=0 unless that stream is currently open. The one
- // exception is RST_STREAM frames, which may be sent on idle or closed streams.
- Push(wr http2FrameWriteRequest)
-
- // Pop dequeues the next frame to write. Returns false if no frames can
- // be written. Frames with a given wr.StreamID() are Pop'd in the same
- // order they are Push'd, except RST_STREAM frames. No frames should be
- // discarded except by CloseStream.
- Pop() (wr http2FrameWriteRequest, ok bool)
-}
-
-// OpenStreamOptions specifies extra options for WriteScheduler.OpenStream.
-type http2OpenStreamOptions struct {
- // PusherID is zero if the stream was initiated by the client. Otherwise,
- // PusherID names the stream that pushed the newly opened stream.
- PusherID uint32
-}
-
-// FrameWriteRequest is a request to write a frame.
-type http2FrameWriteRequest struct {
- // write is the interface value that does the writing, once the
- // WriteScheduler has selected this frame to write. The write
- // functions are all defined in write.go.
- write http2writeFramer
-
- // stream is the stream on which this frame will be written.
- // nil for non-stream frames like PING and SETTINGS.
- // nil for RST_STREAM streams, which use the StreamError.StreamID field instead.
- stream *http2stream
-
- // done, if non-nil, must be a buffered channel with space for
- // 1 message and is sent the return value from write (or an
- // earlier error) when the frame has been written.
- done chan error
-}
-
-// StreamID returns the id of the stream this frame will be written to.
-// 0 is used for non-stream frames such as PING and SETTINGS.
-func (wr http2FrameWriteRequest) StreamID() uint32 {
- if wr.stream == nil {
- if se, ok := wr.write.(http2StreamError); ok {
- // (*serverConn).resetStream doesn't set
- // stream because it doesn't necessarily have
- // one. So special case this type of write
- // message.
- return se.StreamID
- }
- return 0
- }
- return wr.stream.id
-}
-
-// isControl reports whether wr is a control frame for MaxQueuedControlFrames
-// purposes. That includes non-stream frames and RST_STREAM frames.
-func (wr http2FrameWriteRequest) isControl() bool {
- return wr.stream == nil
-}
-
-// DataSize returns the number of flow control bytes that must be consumed
-// to write this entire frame. This is 0 for non-DATA frames.
-func (wr http2FrameWriteRequest) DataSize() int {
- if wd, ok := wr.write.(*http2writeData); ok {
- return len(wd.p)
- }
- return 0
-}
-
-// Consume consumes min(n, available) bytes from this frame, where available
-// is the number of flow control bytes available on the stream. Consume returns
-// 0, 1, or 2 frames, where the integer return value gives the number of frames
-// returned.
-//
-// If flow control prevents consuming any bytes, this returns (_, _, 0). If
-// the entire frame was consumed, this returns (wr, _, 1). Otherwise, this
-// returns (consumed, rest, 2), where 'consumed' contains the consumed bytes and
-// 'rest' contains the remaining bytes. The consumed bytes are deducted from the
-// underlying stream's flow control budget.
-func (wr http2FrameWriteRequest) Consume(n int32) (http2FrameWriteRequest, http2FrameWriteRequest, int) {
- var empty http2FrameWriteRequest
-
- // Non-DATA frames are always consumed whole.
- wd, ok := wr.write.(*http2writeData)
- if !ok || len(wd.p) == 0 {
- return wr, empty, 1
- }
-
- // Might need to split after applying limits.
- allowed := wr.stream.flow.available()
- if n < allowed {
- allowed = n
- }
- if wr.stream.sc.maxFrameSize < allowed {
- allowed = wr.stream.sc.maxFrameSize
- }
- if allowed <= 0 {
- return empty, empty, 0
- }
- if len(wd.p) > int(allowed) {
- wr.stream.flow.take(allowed)
- consumed := http2FrameWriteRequest{
- stream: wr.stream,
- write: &http2writeData{
- streamID: wd.streamID,
- p: wd.p[:allowed],
- // Even if the original had endStream set, there
- // are bytes remaining because len(wd.p) > allowed,
- // so we know endStream is false.
- endStream: false,
- },
- // Our caller is blocking on the final DATA frame, not
- // this intermediate frame, so no need to wait.
- done: nil,
- }
- rest := http2FrameWriteRequest{
- stream: wr.stream,
- write: &http2writeData{
- streamID: wd.streamID,
- p: wd.p[allowed:],
- endStream: wd.endStream,
- },
- done: wr.done,
- }
- return consumed, rest, 2
- }
-
- // The frame is consumed whole.
- // NB: This cast cannot overflow because allowed is <= math.MaxInt32.
- wr.stream.flow.take(int32(len(wd.p)))
- return wr, empty, 1
-}
-
-// String is for debugging only.
-func (wr http2FrameWriteRequest) String() string {
- var des string
- if s, ok := wr.write.(fmt.Stringer); ok {
- des = s.String()
- } else {
- des = fmt.Sprintf("%T", wr.write)
- }
- return fmt.Sprintf("[FrameWriteRequest stream=%d, ch=%v, writer=%v]", wr.StreamID(), wr.done != nil, des)
-}
-
-// replyToWriter sends err to wr.done and panics if the send must block
-// This does nothing if wr.done is nil.
-func (wr *http2FrameWriteRequest) replyToWriter(err error) {
- if wr.done == nil {
- return
- }
- select {
- case wr.done <- err:
- default:
- panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wr.write))
- }
- wr.write = nil // prevent use (assume it's tainted after wr.done send)
-}
-
-// writeQueue is used by implementations of WriteScheduler.
-type http2writeQueue struct {
- s []http2FrameWriteRequest
-}
-
-func (q *http2writeQueue) empty() bool { return len(q.s) == 0 }
-
-func (q *http2writeQueue) push(wr http2FrameWriteRequest) {
- q.s = append(q.s, wr)
-}
-
-func (q *http2writeQueue) shift() http2FrameWriteRequest {
- if len(q.s) == 0 {
- panic("invalid use of queue")
- }
- wr := q.s[0]
- // TODO: less copy-happy queue.
- copy(q.s, q.s[1:])
- q.s[len(q.s)-1] = http2FrameWriteRequest{}
- q.s = q.s[:len(q.s)-1]
- return wr
-}
-
-// consume consumes up to n bytes from q.s[0]. If the frame is
-// entirely consumed, it is removed from the queue. If the frame
-// is partially consumed, the frame is kept with the consumed
-// bytes removed. Returns true iff any bytes were consumed.
-func (q *http2writeQueue) consume(n int32) (http2FrameWriteRequest, bool) {
- if len(q.s) == 0 {
- return http2FrameWriteRequest{}, false
- }
- consumed, rest, numresult := q.s[0].Consume(n)
- switch numresult {
- case 0:
- return http2FrameWriteRequest{}, false
- case 1:
- q.shift()
- case 2:
- q.s[0] = rest
- }
- return consumed, true
-}
-
-type http2writeQueuePool []*http2writeQueue
-
-// put inserts an unused writeQueue into the pool.
-
-// put inserts an unused writeQueue into the pool.
-func (p *http2writeQueuePool) put(q *http2writeQueue) {
- for i := range q.s {
- q.s[i] = http2FrameWriteRequest{}
- }
- q.s = q.s[:0]
- *p = append(*p, q)
-}
-
-// get returns an empty writeQueue.
-func (p *http2writeQueuePool) get() *http2writeQueue {
- ln := len(*p)
- if ln == 0 {
- return new(http2writeQueue)
- }
- x := ln - 1
- q := (*p)[x]
- (*p)[x] = nil
- *p = (*p)[:x]
- return q
-}
-
-// RFC 7540, Section 5.3.5: the default weight is 16.
-const http2priorityDefaultWeight = 15 // 16 = 15 + 1
-
-// PriorityWriteSchedulerConfig configures a priorityWriteScheduler.
-type http2PriorityWriteSchedulerConfig struct {
- // MaxClosedNodesInTree controls the maximum number of closed streams to
- // retain in the priority tree. Setting this to zero saves a small amount
- // of memory at the cost of performance.
- //
- // See RFC 7540, Section 5.3.4:
- // "It is possible for a stream to become closed while prioritization
- // information ... is in transit. ... This potentially creates suboptimal
- // prioritization, since the stream could be given a priority that is
- // different from what is intended. To avoid these problems, an endpoint
- // SHOULD retain stream prioritization state for a period after streams
- // become closed. The longer state is retained, the lower the chance that
- // streams are assigned incorrect or default priority values."
- MaxClosedNodesInTree int
-
- // MaxIdleNodesInTree controls the maximum number of idle streams to
- // retain in the priority tree. Setting this to zero saves a small amount
- // of memory at the cost of performance.
- //
- // See RFC 7540, Section 5.3.4:
- // Similarly, streams that are in the "idle" state can be assigned
- // priority or become a parent of other streams. This allows for the
- // creation of a grouping node in the dependency tree, which enables
- // more flexible expressions of priority. Idle streams begin with a
- // default priority (Section 5.3.5).
- MaxIdleNodesInTree int
-
- // ThrottleOutOfOrderWrites enables write throttling to help ensure that
- // data is delivered in priority order. This works around a race where
- // stream B depends on stream A and both streams are about to call Write
- // to queue DATA frames. If B wins the race, a naive scheduler would eagerly
- // write as much data from B as possible, but this is suboptimal because A
- // is a higher-priority stream. With throttling enabled, we write a small
- // amount of data from B to minimize the amount of bandwidth that B can
- // steal from A.
- ThrottleOutOfOrderWrites bool
-}
-
-// NewPriorityWriteScheduler constructs a WriteScheduler that schedules
-// frames by following HTTP/2 priorities as described in RFC 7540 Section 5.3.
-// If cfg is nil, default options are used.
-func http2NewPriorityWriteScheduler(cfg *http2PriorityWriteSchedulerConfig) http2WriteScheduler {
- if cfg == nil {
- // For justification of these defaults, see:
- // https://docs.google.com/document/d/1oLhNg1skaWD4_DtaoCxdSRN5erEXrH-KnLrMwEpOtFY
- cfg = &http2PriorityWriteSchedulerConfig{
- MaxClosedNodesInTree: 10,
- MaxIdleNodesInTree: 10,
- ThrottleOutOfOrderWrites: false,
- }
- }
-
- ws := &http2priorityWriteScheduler{
- nodes: make(map[uint32]*http2priorityNode),
- maxClosedNodesInTree: cfg.MaxClosedNodesInTree,
- maxIdleNodesInTree: cfg.MaxIdleNodesInTree,
- enableWriteThrottle: cfg.ThrottleOutOfOrderWrites,
- }
- ws.nodes[0] = &ws.root
- if cfg.ThrottleOutOfOrderWrites {
- ws.writeThrottleLimit = 1024
- } else {
- ws.writeThrottleLimit = math.MaxInt32
- }
- return ws
-}
-
-type http2priorityNodeState int
-
-const (
- http2priorityNodeOpen http2priorityNodeState = iota
- http2priorityNodeClosed
- http2priorityNodeIdle
-)
-
-// priorityNode is a node in an HTTP/2 priority tree.
-// Each node is associated with a single stream ID.
-// See RFC 7540, Section 5.3.
-type http2priorityNode struct {
- q http2writeQueue // queue of pending frames to write
- id uint32 // id of the stream, or 0 for the root of the tree
- weight uint8 // the actual weight is weight+1, so the value is in [1,256]
- state http2priorityNodeState // open | closed | idle
- bytes int64 // number of bytes written by this node, or 0 if closed
- subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree
-
- // These links form the priority tree.
- parent *http2priorityNode
- kids *http2priorityNode // start of the kids list
- prev, next *http2priorityNode // doubly-linked list of siblings
-}
-
-func (n *http2priorityNode) setParent(parent *http2priorityNode) {
- if n == parent {
- panic("setParent to self")
- }
- if n.parent == parent {
- return
- }
- // Unlink from current parent.
- if parent := n.parent; parent != nil {
- if n.prev == nil {
- parent.kids = n.next
- } else {
- n.prev.next = n.next
- }
- if n.next != nil {
- n.next.prev = n.prev
- }
- }
- // Link to new parent.
- // If parent=nil, remove n from the tree.
- // Always insert at the head of parent.kids (this is assumed by walkReadyInOrder).
- n.parent = parent
- if parent == nil {
- n.next = nil
- n.prev = nil
- } else {
- n.next = parent.kids
- n.prev = nil
- if n.next != nil {
- n.next.prev = n
- }
- parent.kids = n
- }
-}
-
-func (n *http2priorityNode) addBytes(b int64) {
- n.bytes += b
- for ; n != nil; n = n.parent {
- n.subtreeBytes += b
- }
-}
-
-// walkReadyInOrder iterates over the tree in priority order, calling f for each node
-// with a non-empty write queue. When f returns true, this function returns true and the
-// walk halts. tmp is used as scratch space for sorting.
-//
-// f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true
-// if any ancestor p of n is still open (ignoring the root node).
-func (n *http2priorityNode) walkReadyInOrder(openParent bool, tmp *[]*http2priorityNode, f func(*http2priorityNode, bool) bool) bool {
- if !n.q.empty() && f(n, openParent) {
- return true
- }
- if n.kids == nil {
- return false
- }
-
- // Don't consider the root "open" when updating openParent since
- // we can't send data frames on the root stream (only control frames).
- if n.id != 0 {
- openParent = openParent || (n.state == http2priorityNodeOpen)
- }
-
- // Common case: only one kid or all kids have the same weight.
- // Some clients don't use weights; other clients (like web browsers)
- // use mostly-linear priority trees.
- w := n.kids.weight
- needSort := false
- for k := n.kids.next; k != nil; k = k.next {
- if k.weight != w {
- needSort = true
- break
- }
- }
- if !needSort {
- for k := n.kids; k != nil; k = k.next {
- if k.walkReadyInOrder(openParent, tmp, f) {
- return true
- }
- }
- return false
- }
-
- // Uncommon case: sort the child nodes. We remove the kids from the parent,
- // then re-insert after sorting so we can reuse tmp for future sort calls.
- *tmp = (*tmp)[:0]
- for n.kids != nil {
- *tmp = append(*tmp, n.kids)
- n.kids.setParent(nil)
- }
- sort.Sort(http2sortPriorityNodeSiblings(*tmp))
- for i := len(*tmp) - 1; i >= 0; i-- {
- (*tmp)[i].setParent(n) // setParent inserts at the head of n.kids
- }
- for k := n.kids; k != nil; k = k.next {
- if k.walkReadyInOrder(openParent, tmp, f) {
- return true
- }
- }
- return false
-}
-
-type http2sortPriorityNodeSiblings []*http2priorityNode
-
-func (z http2sortPriorityNodeSiblings) Len() int { return len(z) }
-
-func (z http2sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] }
-
-func (z http2sortPriorityNodeSiblings) Less(i, k int) bool {
- // Prefer the subtree that has sent fewer bytes relative to its weight.
- // See sections 5.3.2 and 5.3.4.
- wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes)
- wk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes)
- if bi == 0 && bk == 0 {
- return wi >= wk
- }
- if bk == 0 {
- return false
- }
- return bi/bk <= wi/wk
-}
-
-type http2priorityWriteScheduler struct {
- // root is the root of the priority tree, where root.id = 0.
- // The root queues control frames that are not associated with any stream.
- root http2priorityNode
-
- // nodes maps stream ids to priority tree nodes.
- nodes map[uint32]*http2priorityNode
-
- // maxID is the maximum stream id in nodes.
- maxID uint32
-
- // lists of nodes that have been closed or are idle, but are kept in
- // the tree for improved prioritization. When the lengths exceed either
- // maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded.
- closedNodes, idleNodes []*http2priorityNode
-
- // From the config.
- maxClosedNodesInTree int
- maxIdleNodesInTree int
- writeThrottleLimit int32
- enableWriteThrottle bool
-
- // tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations.
- tmp []*http2priorityNode
-
- // pool of empty queues for reuse.
- queuePool http2writeQueuePool
-}
-
-func (ws *http2priorityWriteScheduler) OpenStream(streamID uint32, options http2OpenStreamOptions) {
- // The stream may be currently idle but cannot be opened or closed.
- if curr := ws.nodes[streamID]; curr != nil {
- if curr.state != http2priorityNodeIdle {
- panic(fmt.Sprintf("stream %d already opened", streamID))
- }
- curr.state = http2priorityNodeOpen
- return
- }
-
- // RFC 7540, Section 5.3.5:
- // "All streams are initially assigned a non-exclusive dependency on stream 0x0.
- // Pushed streams initially depend on their associated stream. In both cases,
- // streams are assigned a default weight of 16."
- parent := ws.nodes[options.PusherID]
- if parent == nil {
- parent = &ws.root
- }
- n := &http2priorityNode{
- q: *ws.queuePool.get(),
- id: streamID,
- weight: http2priorityDefaultWeight,
- state: http2priorityNodeOpen,
- }
- n.setParent(parent)
- ws.nodes[streamID] = n
- if streamID > ws.maxID {
- ws.maxID = streamID
- }
-}
-
-func (ws *http2priorityWriteScheduler) CloseStream(streamID uint32) {
- if streamID == 0 {
- panic("violation of WriteScheduler interface: cannot close stream 0")
- }
- if ws.nodes[streamID] == nil {
- panic(fmt.Sprintf("violation of WriteScheduler interface: unknown stream %d", streamID))
- }
- if ws.nodes[streamID].state != http2priorityNodeOpen {
- panic(fmt.Sprintf("violation of WriteScheduler interface: stream %d already closed", streamID))
- }
-
- n := ws.nodes[streamID]
- n.state = http2priorityNodeClosed
- n.addBytes(-n.bytes)
-
- q := n.q
- ws.queuePool.put(&q)
- n.q.s = nil
- if ws.maxClosedNodesInTree > 0 {
- ws.addClosedOrIdleNode(&ws.closedNodes, ws.maxClosedNodesInTree, n)
- } else {
- ws.removeNode(n)
- }
-}
-
-func (ws *http2priorityWriteScheduler) AdjustStream(streamID uint32, priority http2PriorityParam) {
- if streamID == 0 {
- panic("adjustPriority on root")
- }
-
- // If streamID does not exist, there are two cases:
- // - A closed stream that has been removed (this will have ID <= maxID)
- // - An idle stream that is being used for "grouping" (this will have ID > maxID)
- n := ws.nodes[streamID]
- if n == nil {
- if streamID <= ws.maxID || ws.maxIdleNodesInTree == 0 {
- return
- }
- ws.maxID = streamID
- n = &http2priorityNode{
- q: *ws.queuePool.get(),
- id: streamID,
- weight: http2priorityDefaultWeight,
- state: http2priorityNodeIdle,
- }
- n.setParent(&ws.root)
- ws.nodes[streamID] = n
- ws.addClosedOrIdleNode(&ws.idleNodes, ws.maxIdleNodesInTree, n)
- }
-
- // Section 5.3.1: A dependency on a stream that is not currently in the tree
- // results in that stream being given a default priority (Section 5.3.5).
- parent := ws.nodes[priority.StreamDep]
- if parent == nil {
- n.setParent(&ws.root)
- n.weight = http2priorityDefaultWeight
- return
- }
-
- // Ignore if the client tries to make a node its own parent.
- if n == parent {
- return
- }
-
- // Section 5.3.3:
- // "If a stream is made dependent on one of its own dependencies, the
- // formerly dependent stream is first moved to be dependent on the
- // reprioritized stream's previous parent. The moved dependency retains
- // its weight."
- //
- // That is: if parent depends on n, move parent to depend on n.parent.
- for x := parent.parent; x != nil; x = x.parent {
- if x == n {
- parent.setParent(n.parent)
- break
- }
- }
-
- // Section 5.3.3: The exclusive flag causes the stream to become the sole
- // dependency of its parent stream, causing other dependencies to become
- // dependent on the exclusive stream.
- if priority.Exclusive {
- k := parent.kids
- for k != nil {
- next := k.next
- if k != n {
- k.setParent(n)
- }
- k = next
- }
- }
-
- n.setParent(parent)
- n.weight = priority.Weight
-}
-
-func (ws *http2priorityWriteScheduler) Push(wr http2FrameWriteRequest) {
- var n *http2priorityNode
- if wr.isControl() {
- n = &ws.root
- } else {
- id := wr.StreamID()
- n = ws.nodes[id]
- if n == nil {
- // id is an idle or closed stream. wr should not be a HEADERS or
- // DATA frame. In other case, we push wr onto the root, rather
- // than creating a new priorityNode.
- if wr.DataSize() > 0 {
- panic("add DATA on non-open stream")
- }
- n = &ws.root
- }
- }
- n.q.push(wr)
-}
-
-func (ws *http2priorityWriteScheduler) Pop() (wr http2FrameWriteRequest, ok bool) {
- ws.root.walkReadyInOrder(false, &ws.tmp, func(n *http2priorityNode, openParent bool) bool {
- limit := int32(math.MaxInt32)
- if openParent {
- limit = ws.writeThrottleLimit
- }
- wr, ok = n.q.consume(limit)
- if !ok {
- return false
- }
- n.addBytes(int64(wr.DataSize()))
- // If B depends on A and B continuously has data available but A
- // does not, gradually increase the throttling limit to allow B to
- // steal more and more bandwidth from A.
- if openParent {
- ws.writeThrottleLimit += 1024
- if ws.writeThrottleLimit < 0 {
- ws.writeThrottleLimit = math.MaxInt32
- }
- } else if ws.enableWriteThrottle {
- ws.writeThrottleLimit = 1024
- }
- return true
- })
- return wr, ok
-}
-
-func (ws *http2priorityWriteScheduler) addClosedOrIdleNode(list *[]*http2priorityNode, maxSize int, n *http2priorityNode) {
- if maxSize == 0 {
- return
- }
- if len(*list) == maxSize {
- // Remove the oldest node, then shift left.
- ws.removeNode((*list)[0])
- x := (*list)[1:]
- copy(*list, x)
- *list = (*list)[:len(x)]
- }
- *list = append(*list, n)
-}
-
-func (ws *http2priorityWriteScheduler) removeNode(n *http2priorityNode) {
- for k := n.kids; k != nil; k = k.next {
- k.setParent(n.parent)
- }
- n.setParent(nil)
- delete(ws.nodes, n.id)
-}
-
-// NewRandomWriteScheduler constructs a WriteScheduler that ignores HTTP/2
-// priorities. Control frames like SETTINGS and PING are written before DATA
-// frames, but if no control frames are queued and multiple streams have queued
-// HEADERS or DATA frames, Pop selects a ready stream arbitrarily.
-func http2NewRandomWriteScheduler() http2WriteScheduler {
- return &http2randomWriteScheduler{sq: make(map[uint32]*http2writeQueue)}
-}
-
-type http2randomWriteScheduler struct {
- // zero are frames not associated with a specific stream.
- zero http2writeQueue
-
- // sq contains the stream-specific queues, keyed by stream ID.
- // When a stream is idle, closed, or emptied, it's deleted
- // from the map.
- sq map[uint32]*http2writeQueue
-
- // pool of empty queues for reuse.
- queuePool http2writeQueuePool
-}
-
-func (ws *http2randomWriteScheduler) OpenStream(streamID uint32, options http2OpenStreamOptions) {
- // no-op: idle streams are not tracked
-}
-
-func (ws *http2randomWriteScheduler) CloseStream(streamID uint32) {
- q, ok := ws.sq[streamID]
- if !ok {
- return
- }
- delete(ws.sq, streamID)
- ws.queuePool.put(q)
-}
-
-func (ws *http2randomWriteScheduler) AdjustStream(streamID uint32, priority http2PriorityParam) {
- // no-op: priorities are ignored
-}
-
-func (ws *http2randomWriteScheduler) Push(wr http2FrameWriteRequest) {
- if wr.isControl() {
- ws.zero.push(wr)
- return
- }
- id := wr.StreamID()
- q, ok := ws.sq[id]
- if !ok {
- q = ws.queuePool.get()
- ws.sq[id] = q
- }
- q.push(wr)
-}
-
-func (ws *http2randomWriteScheduler) Pop() (http2FrameWriteRequest, bool) {
- // Control and RST_STREAM frames first.
- if !ws.zero.empty() {
- return ws.zero.shift(), true
- }
- // Iterate over all non-idle streams until finding one that can be consumed.
- for streamID, q := range ws.sq {
- if wr, ok := q.consume(math.MaxInt32); ok {
- if q.empty() {
- delete(ws.sq, streamID)
- ws.queuePool.put(q)
- }
- return wr, true
- }
- }
- return http2FrameWriteRequest{}, false
-}
diff --git a/contrib/go/_std_1.20/src/net/http/http.go b/contrib/go/_std_1.20/src/net/http/http.go
deleted file mode 100644
index 101799f574..0000000000
--- a/contrib/go/_std_1.20/src/net/http/http.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2016 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.
-
-//go:generate bundle -o=h2_bundle.go -prefix=http2 -tags=!nethttpomithttp2 golang.org/x/net/http2
-
-package http
-
-import (
- "io"
- "strconv"
- "strings"
- "time"
- "unicode/utf8"
-
- "golang.org/x/net/http/httpguts"
-)
-
-// incomparable is a zero-width, non-comparable type. Adding it to a struct
-// makes that struct also non-comparable, and generally doesn't add
-// any size (as long as it's first).
-type incomparable [0]func()
-
-// maxInt64 is the effective "infinite" value for the Server and
-// Transport's byte-limiting readers.
-const maxInt64 = 1<<63 - 1
-
-// aLongTimeAgo is a non-zero time, far in the past, used for
-// immediate cancellation of network operations.
-var aLongTimeAgo = time.Unix(1, 0)
-
-// omitBundledHTTP2 is set by omithttp2.go when the nethttpomithttp2
-// build tag is set. That means h2_bundle.go isn't compiled in and we
-// shouldn't try to use it.
-var omitBundledHTTP2 bool
-
-// TODO(bradfitz): move common stuff here. The other files have accumulated
-// generic http stuff in random places.
-
-// contextKey is a value for use with context.WithValue. It's used as
-// a pointer so it fits in an interface{} without allocation.
-type contextKey struct {
- name string
-}
-
-func (k *contextKey) String() string { return "net/http context value " + k.name }
-
-// Given a string of the form "host", "host:port", or "[ipv6::address]:port",
-// return true if the string includes a port.
-func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
-
-// removeEmptyPort strips the empty port in ":port" to ""
-// as mandated by RFC 3986 Section 6.2.3.
-func removeEmptyPort(host string) string {
- if hasPort(host) {
- return strings.TrimSuffix(host, ":")
- }
- return host
-}
-
-func isNotToken(r rune) bool {
- return !httpguts.IsTokenRune(r)
-}
-
-// stringContainsCTLByte reports whether s contains any ASCII control character.
-func stringContainsCTLByte(s string) bool {
- for i := 0; i < len(s); i++ {
- b := s[i]
- if b < ' ' || b == 0x7f {
- return true
- }
- }
- return false
-}
-
-func hexEscapeNonASCII(s string) string {
- newLen := 0
- for i := 0; i < len(s); i++ {
- if s[i] >= utf8.RuneSelf {
- newLen += 3
- } else {
- newLen++
- }
- }
- if newLen == len(s) {
- return s
- }
- b := make([]byte, 0, newLen)
- for i := 0; i < len(s); i++ {
- if s[i] >= utf8.RuneSelf {
- b = append(b, '%')
- b = strconv.AppendInt(b, int64(s[i]), 16)
- } else {
- b = append(b, s[i])
- }
- }
- return string(b)
-}
-
-// NoBody is an io.ReadCloser with no bytes. Read always returns EOF
-// and Close always returns nil. It can be used in an outgoing client
-// request to explicitly signal that a request has zero bytes.
-// An alternative, however, is to simply set Request.Body to nil.
-var NoBody = noBody{}
-
-type noBody struct{}
-
-func (noBody) Read([]byte) (int, error) { return 0, io.EOF }
-func (noBody) Close() error { return nil }
-func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil }
-
-var (
- // verify that an io.Copy from NoBody won't require a buffer:
- _ io.WriterTo = NoBody
- _ io.ReadCloser = NoBody
-)
-
-// PushOptions describes options for Pusher.Push.
-type PushOptions struct {
- // Method specifies the HTTP method for the promised request.
- // If set, it must be "GET" or "HEAD". Empty means "GET".
- Method string
-
- // Header specifies additional promised request headers. This cannot
- // include HTTP/2 pseudo header fields like ":path" and ":scheme",
- // which will be added automatically.
- Header Header
-}
-
-// Pusher is the interface implemented by ResponseWriters that support
-// HTTP/2 server push. For more background, see
-// https://tools.ietf.org/html/rfc7540#section-8.2.
-type Pusher interface {
- // Push initiates an HTTP/2 server push. This constructs a synthetic
- // request using the given target and options, serializes that request
- // into a PUSH_PROMISE frame, then dispatches that request using the
- // server's request handler. If opts is nil, default options are used.
- //
- // The target must either be an absolute path (like "/path") or an absolute
- // URL that contains a valid host and the same scheme as the parent request.
- // If the target is a path, it will inherit the scheme and host of the
- // parent request.
- //
- // The HTTP/2 spec disallows recursive pushes and cross-authority pushes.
- // Push may or may not detect these invalid pushes; however, invalid
- // pushes will be detected and canceled by conforming clients.
- //
- // Handlers that wish to push URL X should call Push before sending any
- // data that may trigger a request for URL X. This avoids a race where the
- // client issues requests for X before receiving the PUSH_PROMISE for X.
- //
- // Push will run in a separate goroutine making the order of arrival
- // non-deterministic. Any required synchronization needs to be implemented
- // by the caller.
- //
- // Push returns ErrNotSupported if the client has disabled push or if push
- // is not supported on the underlying connection.
- Push(target string, opts *PushOptions) error
-}
diff --git a/contrib/go/_std_1.20/src/net/http/httptest/ya.make b/contrib/go/_std_1.20/src/net/http/httptest/ya.make
deleted file mode 100644
index 8dc06bc440..0000000000
--- a/contrib/go/_std_1.20/src/net/http/httptest/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- httptest.go
- recorder.go
- server.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/http/httptrace/ya.make b/contrib/go/_std_1.20/src/net/http/httptrace/ya.make
deleted file mode 100644
index 0fdb12c53a..0000000000
--- a/contrib/go/_std_1.20/src/net/http/httptrace/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- trace.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/http/httputil/reverseproxy.go b/contrib/go/_std_1.20/src/net/http/httputil/reverseproxy.go
deleted file mode 100644
index 58064a5332..0000000000
--- a/contrib/go/_std_1.20/src/net/http/httputil/reverseproxy.go
+++ /dev/null
@@ -1,839 +0,0 @@
-// Copyright 2011 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.
-
-// HTTP reverse proxy handler
-
-package httputil
-
-import (
- "context"
- "errors"
- "fmt"
- "io"
- "log"
- "mime"
- "net"
- "net/http"
- "net/http/httptrace"
- "net/http/internal/ascii"
- "net/textproto"
- "net/url"
- "strings"
- "sync"
- "time"
-
- "golang.org/x/net/http/httpguts"
-)
-
-// A ProxyRequest contains a request to be rewritten by a ReverseProxy.
-type ProxyRequest struct {
- // In is the request received by the proxy.
- // The Rewrite function must not modify In.
- In *http.Request
-
- // Out is the request which will be sent by the proxy.
- // The Rewrite function may modify or replace this request.
- // Hop-by-hop headers are removed from this request
- // before Rewrite is called.
- Out *http.Request
-}
-
-// SetURL routes the outbound request to the scheme, host, and base path
-// provided in target. If the target's path is "/base" and the incoming
-// request was for "/dir", the target request will be for "/base/dir".
-//
-// SetURL rewrites the outbound Host header to match the target's host.
-// To preserve the inbound request's Host header (the default behavior
-// of NewSingleHostReverseProxy):
-//
-// rewriteFunc := func(r *httputil.ProxyRequest) {
-// r.SetURL(url)
-// r.Out.Host = r.In.Host
-// }
-func (r *ProxyRequest) SetURL(target *url.URL) {
- rewriteRequestURL(r.Out, target)
- r.Out.Host = ""
-}
-
-// SetXForwarded sets the X-Forwarded-For, X-Forwarded-Host, and
-// X-Forwarded-Proto headers of the outbound request.
-//
-// - The X-Forwarded-For header is set to the client IP address.
-// - The X-Forwarded-Host header is set to the host name requested
-// by the client.
-// - The X-Forwarded-Proto header is set to "http" or "https", depending
-// on whether the inbound request was made on a TLS-enabled connection.
-//
-// If the outbound request contains an existing X-Forwarded-For header,
-// SetXForwarded appends the client IP address to it. To append to the
-// inbound request's X-Forwarded-For header (the default behavior of
-// ReverseProxy when using a Director function), copy the header
-// from the inbound request before calling SetXForwarded:
-//
-// rewriteFunc := func(r *httputil.ProxyRequest) {
-// r.Out.Header["X-Forwarded-For"] = r.In.Header["X-Forwarded-For"]
-// r.SetXForwarded()
-// }
-func (r *ProxyRequest) SetXForwarded() {
- clientIP, _, err := net.SplitHostPort(r.In.RemoteAddr)
- if err == nil {
- prior := r.Out.Header["X-Forwarded-For"]
- if len(prior) > 0 {
- clientIP = strings.Join(prior, ", ") + ", " + clientIP
- }
- r.Out.Header.Set("X-Forwarded-For", clientIP)
- } else {
- r.Out.Header.Del("X-Forwarded-For")
- }
- r.Out.Header.Set("X-Forwarded-Host", r.In.Host)
- if r.In.TLS == nil {
- r.Out.Header.Set("X-Forwarded-Proto", "http")
- } else {
- r.Out.Header.Set("X-Forwarded-Proto", "https")
- }
-}
-
-// ReverseProxy is an HTTP Handler that takes an incoming request and
-// sends it to another server, proxying the response back to the
-// client.
-//
-// 1xx responses are forwarded to the client if the underlying
-// transport supports ClientTrace.Got1xxResponse.
-type ReverseProxy struct {
- // Rewrite must be a function which modifies
- // the request into a new request to be sent
- // using Transport. Its response is then copied
- // back to the original client unmodified.
- // Rewrite must not access the provided ProxyRequest
- // or its contents after returning.
- //
- // The Forwarded, X-Forwarded, X-Forwarded-Host,
- // and X-Forwarded-Proto headers are removed from the
- // outbound request before Rewrite is called. See also
- // the ProxyRequest.SetXForwarded method.
- //
- // Unparsable query parameters are removed from the
- // outbound request before Rewrite is called.
- // The Rewrite function may copy the inbound URL's
- // RawQuery to the outbound URL to preserve the original
- // parameter string. Note that this can lead to security
- // issues if the proxy's interpretation of query parameters
- // does not match that of the downstream server.
- //
- // At most one of Rewrite or Director may be set.
- Rewrite func(*ProxyRequest)
-
- // Director is a function which modifies
- // the request into a new request to be sent
- // using Transport. Its response is then copied
- // back to the original client unmodified.
- // Director must not access the provided Request
- // after returning.
- //
- // By default, the X-Forwarded-For header is set to the
- // value of the client IP address. If an X-Forwarded-For
- // header already exists, the client IP is appended to the
- // existing values. As a special case, if the header
- // exists in the Request.Header map but has a nil value
- // (such as when set by the Director func), the X-Forwarded-For
- // header is not modified.
- //
- // To prevent IP spoofing, be sure to delete any pre-existing
- // X-Forwarded-For header coming from the client or
- // an untrusted proxy.
- //
- // Hop-by-hop headers are removed from the request after
- // Director returns, which can remove headers added by
- // Director. Use a Rewrite function instead to ensure
- // modifications to the request are preserved.
- //
- // Unparsable query parameters are removed from the outbound
- // request if Request.Form is set after Director returns.
- //
- // At most one of Rewrite or Director may be set.
- Director func(*http.Request)
-
- // The transport used to perform proxy requests.
- // If nil, http.DefaultTransport is used.
- Transport http.RoundTripper
-
- // FlushInterval specifies the flush interval
- // to flush to the client while copying the
- // response body.
- // If zero, no periodic flushing is done.
- // A negative value means to flush immediately
- // after each write to the client.
- // The FlushInterval is ignored when ReverseProxy
- // recognizes a response as a streaming response, or
- // if its ContentLength is -1; for such responses, writes
- // are flushed to the client immediately.
- FlushInterval time.Duration
-
- // ErrorLog specifies an optional logger for errors
- // that occur when attempting to proxy the request.
- // If nil, logging is done via the log package's standard logger.
- ErrorLog *log.Logger
-
- // BufferPool optionally specifies a buffer pool to
- // get byte slices for use by io.CopyBuffer when
- // copying HTTP response bodies.
- BufferPool BufferPool
-
- // ModifyResponse is an optional function that modifies the
- // Response from the backend. It is called if the backend
- // returns a response at all, with any HTTP status code.
- // If the backend is unreachable, the optional ErrorHandler is
- // called without any call to ModifyResponse.
- //
- // If ModifyResponse returns an error, ErrorHandler is called
- // with its error value. If ErrorHandler is nil, its default
- // implementation is used.
- ModifyResponse func(*http.Response) error
-
- // ErrorHandler is an optional function that handles errors
- // reaching the backend or errors from ModifyResponse.
- //
- // If nil, the default is to log the provided error and return
- // a 502 Status Bad Gateway response.
- ErrorHandler func(http.ResponseWriter, *http.Request, error)
-}
-
-// A BufferPool is an interface for getting and returning temporary
-// byte slices for use by io.CopyBuffer.
-type BufferPool interface {
- Get() []byte
- Put([]byte)
-}
-
-func singleJoiningSlash(a, b string) string {
- aslash := strings.HasSuffix(a, "/")
- bslash := strings.HasPrefix(b, "/")
- switch {
- case aslash && bslash:
- return a + b[1:]
- case !aslash && !bslash:
- return a + "/" + b
- }
- return a + b
-}
-
-func joinURLPath(a, b *url.URL) (path, rawpath string) {
- if a.RawPath == "" && b.RawPath == "" {
- return singleJoiningSlash(a.Path, b.Path), ""
- }
- // Same as singleJoiningSlash, but uses EscapedPath to determine
- // whether a slash should be added
- apath := a.EscapedPath()
- bpath := b.EscapedPath()
-
- aslash := strings.HasSuffix(apath, "/")
- bslash := strings.HasPrefix(bpath, "/")
-
- switch {
- case aslash && bslash:
- return a.Path + b.Path[1:], apath + bpath[1:]
- case !aslash && !bslash:
- return a.Path + "/" + b.Path, apath + "/" + bpath
- }
- return a.Path + b.Path, apath + bpath
-}
-
-// NewSingleHostReverseProxy returns a new ReverseProxy that routes
-// URLs to the scheme, host, and base path provided in target. If the
-// target's path is "/base" and the incoming request was for "/dir",
-// the target request will be for /base/dir.
-//
-// NewSingleHostReverseProxy does not rewrite the Host header.
-//
-// To customize the ReverseProxy behavior beyond what
-// NewSingleHostReverseProxy provides, use ReverseProxy directly
-// with a Rewrite function. The ProxyRequest SetURL method
-// may be used to route the outbound request. (Note that SetURL,
-// unlike NewSingleHostReverseProxy, rewrites the Host header
-// of the outbound request by default.)
-//
-// proxy := &ReverseProxy{
-// Rewrite: func(r *ProxyRequest) {
-// r.SetURL(target)
-// r.Out.Host = r.In.Host // if desired
-// }
-// }
-func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy {
- director := func(req *http.Request) {
- rewriteRequestURL(req, target)
- }
- return &ReverseProxy{Director: director}
-}
-
-func rewriteRequestURL(req *http.Request, target *url.URL) {
- targetQuery := target.RawQuery
- req.URL.Scheme = target.Scheme
- req.URL.Host = target.Host
- req.URL.Path, req.URL.RawPath = joinURLPath(target, req.URL)
- if targetQuery == "" || req.URL.RawQuery == "" {
- req.URL.RawQuery = targetQuery + req.URL.RawQuery
- } else {
- req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
- }
-}
-
-func copyHeader(dst, src http.Header) {
- for k, vv := range src {
- for _, v := range vv {
- dst.Add(k, v)
- }
- }
-}
-
-// Hop-by-hop headers. These are removed when sent to the backend.
-// As of RFC 7230, hop-by-hop headers are required to appear in the
-// Connection header field. These are the headers defined by the
-// obsoleted RFC 2616 (section 13.5.1) and are used for backward
-// compatibility.
-var hopHeaders = []string{
- "Connection",
- "Proxy-Connection", // non-standard but still sent by libcurl and rejected by e.g. google
- "Keep-Alive",
- "Proxy-Authenticate",
- "Proxy-Authorization",
- "Te", // canonicalized version of "TE"
- "Trailer", // not Trailers per URL above; https://www.rfc-editor.org/errata_search.php?eid=4522
- "Transfer-Encoding",
- "Upgrade",
-}
-
-func (p *ReverseProxy) defaultErrorHandler(rw http.ResponseWriter, req *http.Request, err error) {
- p.logf("http: proxy error: %v", err)
- rw.WriteHeader(http.StatusBadGateway)
-}
-
-func (p *ReverseProxy) getErrorHandler() func(http.ResponseWriter, *http.Request, error) {
- if p.ErrorHandler != nil {
- return p.ErrorHandler
- }
- return p.defaultErrorHandler
-}
-
-// modifyResponse conditionally runs the optional ModifyResponse hook
-// and reports whether the request should proceed.
-func (p *ReverseProxy) modifyResponse(rw http.ResponseWriter, res *http.Response, req *http.Request) bool {
- if p.ModifyResponse == nil {
- return true
- }
- if err := p.ModifyResponse(res); err != nil {
- res.Body.Close()
- p.getErrorHandler()(rw, req, err)
- return false
- }
- return true
-}
-
-func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
- transport := p.Transport
- if transport == nil {
- transport = http.DefaultTransport
- }
-
- ctx := req.Context()
- if ctx.Done() != nil {
- // CloseNotifier predates context.Context, and has been
- // entirely superseded by it. If the request contains
- // a Context that carries a cancellation signal, don't
- // bother spinning up a goroutine to watch the CloseNotify
- // channel (if any).
- //
- // If the request Context has a nil Done channel (which
- // means it is either context.Background, or a custom
- // Context implementation with no cancellation signal),
- // then consult the CloseNotifier if available.
- } else if cn, ok := rw.(http.CloseNotifier); ok {
- var cancel context.CancelFunc
- ctx, cancel = context.WithCancel(ctx)
- defer cancel()
- notifyChan := cn.CloseNotify()
- go func() {
- select {
- case <-notifyChan:
- cancel()
- case <-ctx.Done():
- }
- }()
- }
-
- outreq := req.Clone(ctx)
- if req.ContentLength == 0 {
- outreq.Body = nil // Issue 16036: nil Body for http.Transport retries
- }
- if outreq.Body != nil {
- // Reading from the request body after returning from a handler is not
- // allowed, and the RoundTrip goroutine that reads the Body can outlive
- // this handler. This can lead to a crash if the handler panics (see
- // Issue 46866). Although calling Close doesn't guarantee there isn't
- // any Read in flight after the handle returns, in practice it's safe to
- // read after closing it.
- defer outreq.Body.Close()
- }
- if outreq.Header == nil {
- outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate
- }
-
- if (p.Director != nil) == (p.Rewrite != nil) {
- p.getErrorHandler()(rw, req, errors.New("ReverseProxy must have exactly one of Director or Rewrite set"))
- return
- }
-
- if p.Director != nil {
- p.Director(outreq)
- if outreq.Form != nil {
- outreq.URL.RawQuery = cleanQueryParams(outreq.URL.RawQuery)
- }
- }
- outreq.Close = false
-
- reqUpType := upgradeType(outreq.Header)
- if !ascii.IsPrint(reqUpType) {
- p.getErrorHandler()(rw, req, fmt.Errorf("client tried to switch to invalid protocol %q", reqUpType))
- return
- }
- removeHopByHopHeaders(outreq.Header)
-
- // Issue 21096: tell backend applications that care about trailer support
- // that we support trailers. (We do, but we don't go out of our way to
- // advertise that unless the incoming client request thought it was worth
- // mentioning.) Note that we look at req.Header, not outreq.Header, since
- // the latter has passed through removeHopByHopHeaders.
- if httpguts.HeaderValuesContainsToken(req.Header["Te"], "trailers") {
- outreq.Header.Set("Te", "trailers")
- }
-
- // After stripping all the hop-by-hop connection headers above, add back any
- // necessary for protocol upgrades, such as for websockets.
- if reqUpType != "" {
- outreq.Header.Set("Connection", "Upgrade")
- outreq.Header.Set("Upgrade", reqUpType)
- }
-
- if p.Rewrite != nil {
- // Strip client-provided forwarding headers.
- // The Rewrite func may use SetXForwarded to set new values
- // for these or copy the previous values from the inbound request.
- outreq.Header.Del("Forwarded")
- outreq.Header.Del("X-Forwarded-For")
- outreq.Header.Del("X-Forwarded-Host")
- outreq.Header.Del("X-Forwarded-Proto")
-
- // Remove unparsable query parameters from the outbound request.
- outreq.URL.RawQuery = cleanQueryParams(outreq.URL.RawQuery)
-
- pr := &ProxyRequest{
- In: req,
- Out: outreq,
- }
- p.Rewrite(pr)
- outreq = pr.Out
- } else {
- if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
- // If we aren't the first proxy retain prior
- // X-Forwarded-For information as a comma+space
- // separated list and fold multiple headers into one.
- prior, ok := outreq.Header["X-Forwarded-For"]
- omit := ok && prior == nil // Issue 38079: nil now means don't populate the header
- if len(prior) > 0 {
- clientIP = strings.Join(prior, ", ") + ", " + clientIP
- }
- if !omit {
- outreq.Header.Set("X-Forwarded-For", clientIP)
- }
- }
- }
-
- if _, ok := outreq.Header["User-Agent"]; !ok {
- // If the outbound request doesn't have a User-Agent header set,
- // don't send the default Go HTTP client User-Agent.
- outreq.Header.Set("User-Agent", "")
- }
-
- trace := &httptrace.ClientTrace{
- Got1xxResponse: func(code int, header textproto.MIMEHeader) error {
- h := rw.Header()
- copyHeader(h, http.Header(header))
- rw.WriteHeader(code)
-
- // Clear headers, it's not automatically done by ResponseWriter.WriteHeader() for 1xx responses
- for k := range h {
- delete(h, k)
- }
-
- return nil
- },
- }
- outreq = outreq.WithContext(httptrace.WithClientTrace(outreq.Context(), trace))
-
- res, err := transport.RoundTrip(outreq)
- if err != nil {
- p.getErrorHandler()(rw, outreq, err)
- return
- }
-
- // Deal with 101 Switching Protocols responses: (WebSocket, h2c, etc)
- if res.StatusCode == http.StatusSwitchingProtocols {
- if !p.modifyResponse(rw, res, outreq) {
- return
- }
- p.handleUpgradeResponse(rw, outreq, res)
- return
- }
-
- removeHopByHopHeaders(res.Header)
-
- if !p.modifyResponse(rw, res, outreq) {
- return
- }
-
- copyHeader(rw.Header(), res.Header)
-
- // The "Trailer" header isn't included in the Transport's response,
- // at least for *http.Transport. Build it up from Trailer.
- announcedTrailers := len(res.Trailer)
- if announcedTrailers > 0 {
- trailerKeys := make([]string, 0, len(res.Trailer))
- for k := range res.Trailer {
- trailerKeys = append(trailerKeys, k)
- }
- rw.Header().Add("Trailer", strings.Join(trailerKeys, ", "))
- }
-
- rw.WriteHeader(res.StatusCode)
-
- err = p.copyResponse(rw, res.Body, p.flushInterval(res))
- if err != nil {
- defer res.Body.Close()
- // Since we're streaming the response, if we run into an error all we can do
- // is abort the request. Issue 23643: ReverseProxy should use ErrAbortHandler
- // on read error while copying body.
- if !shouldPanicOnCopyError(req) {
- p.logf("suppressing panic for copyResponse error in test; copy error: %v", err)
- return
- }
- panic(http.ErrAbortHandler)
- }
- res.Body.Close() // close now, instead of defer, to populate res.Trailer
-
- if len(res.Trailer) > 0 {
- // Force chunking if we saw a response trailer.
- // This prevents net/http from calculating the length for short
- // bodies and adding a Content-Length.
- if fl, ok := rw.(http.Flusher); ok {
- fl.Flush()
- }
- }
-
- if len(res.Trailer) == announcedTrailers {
- copyHeader(rw.Header(), res.Trailer)
- return
- }
-
- for k, vv := range res.Trailer {
- k = http.TrailerPrefix + k
- for _, v := range vv {
- rw.Header().Add(k, v)
- }
- }
-}
-
-var inOurTests bool // whether we're in our own tests
-
-// shouldPanicOnCopyError reports whether the reverse proxy should
-// panic with http.ErrAbortHandler. This is the right thing to do by
-// default, but Go 1.10 and earlier did not, so existing unit tests
-// weren't expecting panics. Only panic in our own tests, or when
-// running under the HTTP server.
-func shouldPanicOnCopyError(req *http.Request) bool {
- if inOurTests {
- // Our tests know to handle this panic.
- return true
- }
- if req.Context().Value(http.ServerContextKey) != nil {
- // We seem to be running under an HTTP server, so
- // it'll recover the panic.
- return true
- }
- // Otherwise act like Go 1.10 and earlier to not break
- // existing tests.
- return false
-}
-
-// removeHopByHopHeaders removes hop-by-hop headers.
-func removeHopByHopHeaders(h http.Header) {
- // RFC 7230, section 6.1: Remove headers listed in the "Connection" header.
- for _, f := range h["Connection"] {
- for _, sf := range strings.Split(f, ",") {
- if sf = textproto.TrimString(sf); sf != "" {
- h.Del(sf)
- }
- }
- }
- // RFC 2616, section 13.5.1: Remove a set of known hop-by-hop headers.
- // This behavior is superseded by the RFC 7230 Connection header, but
- // preserve it for backwards compatibility.
- for _, f := range hopHeaders {
- h.Del(f)
- }
-}
-
-// flushInterval returns the p.FlushInterval value, conditionally
-// overriding its value for a specific request/response.
-func (p *ReverseProxy) flushInterval(res *http.Response) time.Duration {
- resCT := res.Header.Get("Content-Type")
-
- // For Server-Sent Events responses, flush immediately.
- // The MIME type is defined in https://www.w3.org/TR/eventsource/#text-event-stream
- if baseCT, _, _ := mime.ParseMediaType(resCT); baseCT == "text/event-stream" {
- return -1 // negative means immediately
- }
-
- // We might have the case of streaming for which Content-Length might be unset.
- if res.ContentLength == -1 {
- return -1
- }
-
- return p.FlushInterval
-}
-
-func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader, flushInterval time.Duration) error {
- if flushInterval != 0 {
- if wf, ok := dst.(writeFlusher); ok {
- mlw := &maxLatencyWriter{
- dst: wf,
- latency: flushInterval,
- }
- defer mlw.stop()
-
- // set up initial timer so headers get flushed even if body writes are delayed
- mlw.flushPending = true
- mlw.t = time.AfterFunc(flushInterval, mlw.delayedFlush)
-
- dst = mlw
- }
- }
-
- var buf []byte
- if p.BufferPool != nil {
- buf = p.BufferPool.Get()
- defer p.BufferPool.Put(buf)
- }
- _, err := p.copyBuffer(dst, src, buf)
- return err
-}
-
-// copyBuffer returns any write errors or non-EOF read errors, and the amount
-// of bytes written.
-func (p *ReverseProxy) copyBuffer(dst io.Writer, src io.Reader, buf []byte) (int64, error) {
- if len(buf) == 0 {
- buf = make([]byte, 32*1024)
- }
- var written int64
- for {
- nr, rerr := src.Read(buf)
- if rerr != nil && rerr != io.EOF && rerr != context.Canceled {
- p.logf("httputil: ReverseProxy read error during body copy: %v", rerr)
- }
- if nr > 0 {
- nw, werr := dst.Write(buf[:nr])
- if nw > 0 {
- written += int64(nw)
- }
- if werr != nil {
- return written, werr
- }
- if nr != nw {
- return written, io.ErrShortWrite
- }
- }
- if rerr != nil {
- if rerr == io.EOF {
- rerr = nil
- }
- return written, rerr
- }
- }
-}
-
-func (p *ReverseProxy) logf(format string, args ...any) {
- if p.ErrorLog != nil {
- p.ErrorLog.Printf(format, args...)
- } else {
- log.Printf(format, args...)
- }
-}
-
-type writeFlusher interface {
- io.Writer
- http.Flusher
-}
-
-type maxLatencyWriter struct {
- dst writeFlusher
- latency time.Duration // non-zero; negative means to flush immediately
-
- mu sync.Mutex // protects t, flushPending, and dst.Flush
- t *time.Timer
- flushPending bool
-}
-
-func (m *maxLatencyWriter) Write(p []byte) (n int, err error) {
- m.mu.Lock()
- defer m.mu.Unlock()
- n, err = m.dst.Write(p)
- if m.latency < 0 {
- m.dst.Flush()
- return
- }
- if m.flushPending {
- return
- }
- if m.t == nil {
- m.t = time.AfterFunc(m.latency, m.delayedFlush)
- } else {
- m.t.Reset(m.latency)
- }
- m.flushPending = true
- return
-}
-
-func (m *maxLatencyWriter) delayedFlush() {
- m.mu.Lock()
- defer m.mu.Unlock()
- if !m.flushPending { // if stop was called but AfterFunc already started this goroutine
- return
- }
- m.dst.Flush()
- m.flushPending = false
-}
-
-func (m *maxLatencyWriter) stop() {
- m.mu.Lock()
- defer m.mu.Unlock()
- m.flushPending = false
- if m.t != nil {
- m.t.Stop()
- }
-}
-
-func upgradeType(h http.Header) string {
- if !httpguts.HeaderValuesContainsToken(h["Connection"], "Upgrade") {
- return ""
- }
- return h.Get("Upgrade")
-}
-
-func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.Request, res *http.Response) {
- reqUpType := upgradeType(req.Header)
- resUpType := upgradeType(res.Header)
- if !ascii.IsPrint(resUpType) { // We know reqUpType is ASCII, it's checked by the caller.
- p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch to invalid protocol %q", resUpType))
- }
- if !ascii.EqualFold(reqUpType, resUpType) {
- p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch protocol %q when %q was requested", resUpType, reqUpType))
- return
- }
-
- hj, ok := rw.(http.Hijacker)
- if !ok {
- p.getErrorHandler()(rw, req, fmt.Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw))
- return
- }
- backConn, ok := res.Body.(io.ReadWriteCloser)
- if !ok {
- p.getErrorHandler()(rw, req, fmt.Errorf("internal error: 101 switching protocols response with non-writable body"))
- return
- }
-
- backConnCloseCh := make(chan bool)
- go func() {
- // Ensure that the cancellation of a request closes the backend.
- // See issue https://golang.org/issue/35559.
- select {
- case <-req.Context().Done():
- case <-backConnCloseCh:
- }
- backConn.Close()
- }()
-
- defer close(backConnCloseCh)
-
- conn, brw, err := hj.Hijack()
- if err != nil {
- p.getErrorHandler()(rw, req, fmt.Errorf("Hijack failed on protocol switch: %v", err))
- return
- }
- defer conn.Close()
-
- copyHeader(rw.Header(), res.Header)
-
- res.Header = rw.Header()
- res.Body = nil // so res.Write only writes the headers; we have res.Body in backConn above
- if err := res.Write(brw); err != nil {
- p.getErrorHandler()(rw, req, fmt.Errorf("response write: %v", err))
- return
- }
- if err := brw.Flush(); err != nil {
- p.getErrorHandler()(rw, req, fmt.Errorf("response flush: %v", err))
- return
- }
- errc := make(chan error, 1)
- spc := switchProtocolCopier{user: conn, backend: backConn}
- go spc.copyToBackend(errc)
- go spc.copyFromBackend(errc)
- <-errc
-}
-
-// switchProtocolCopier exists so goroutines proxying data back and
-// forth have nice names in stacks.
-type switchProtocolCopier struct {
- user, backend io.ReadWriter
-}
-
-func (c switchProtocolCopier) copyFromBackend(errc chan<- error) {
- _, err := io.Copy(c.user, c.backend)
- errc <- err
-}
-
-func (c switchProtocolCopier) copyToBackend(errc chan<- error) {
- _, err := io.Copy(c.backend, c.user)
- errc <- err
-}
-
-func cleanQueryParams(s string) string {
- reencode := func(s string) string {
- v, _ := url.ParseQuery(s)
- return v.Encode()
- }
- for i := 0; i < len(s); {
- switch s[i] {
- case ';':
- return reencode(s)
- case '%':
- if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {
- return reencode(s)
- }
- i += 3
- default:
- i++
- }
- }
- return s
-}
-
-func ishex(c byte) bool {
- switch {
- case '0' <= c && c <= '9':
- return true
- case 'a' <= c && c <= 'f':
- return true
- case 'A' <= c && c <= 'F':
- return true
- }
- return false
-}
diff --git a/contrib/go/_std_1.20/src/net/http/httputil/ya.make b/contrib/go/_std_1.20/src/net/http/httputil/ya.make
deleted file mode 100644
index ce93e547c1..0000000000
--- a/contrib/go/_std_1.20/src/net/http/httputil/ya.make
+++ /dev/null
@@ -1,10 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- dump.go
- httputil.go
- persist.go
- reverseproxy.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/http/internal/ascii/ya.make b/contrib/go/_std_1.20/src/net/http/internal/ascii/ya.make
deleted file mode 100644
index d6ba1086d0..0000000000
--- a/contrib/go/_std_1.20/src/net/http/internal/ascii/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- print.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/http/internal/ya.make b/contrib/go/_std_1.20/src/net/http/internal/ya.make
deleted file mode 100644
index ed26ce0a09..0000000000
--- a/contrib/go/_std_1.20/src/net/http/internal/ya.make
+++ /dev/null
@@ -1,12 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- chunked.go
-)
-
-END()
-
-RECURSE(
- ascii
- testcert
-)
diff --git a/contrib/go/_std_1.20/src/net/http/pprof/pprof.go b/contrib/go/_std_1.20/src/net/http/pprof/pprof.go
deleted file mode 100644
index db03af1c44..0000000000
--- a/contrib/go/_std_1.20/src/net/http/pprof/pprof.go
+++ /dev/null
@@ -1,456 +0,0 @@
-// Copyright 2010 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 pprof serves via its HTTP server runtime profiling data
-// in the format expected by the pprof visualization tool.
-//
-// The package is typically only imported for the side effect of
-// registering its HTTP handlers.
-// The handled paths all begin with /debug/pprof/.
-//
-// To use pprof, link this package into your program:
-//
-// import _ "net/http/pprof"
-//
-// If your application is not already running an http server, you
-// need to start one. Add "net/http" and "log" to your imports and
-// the following code to your main function:
-//
-// go func() {
-// log.Println(http.ListenAndServe("localhost:6060", nil))
-// }()
-//
-// By default, all the profiles listed in [runtime/pprof.Profile] are
-// available (via [Handler]), in addition to the [Cmdline], [Profile], [Symbol],
-// and [Trace] profiles defined in this package.
-// If you are not using DefaultServeMux, you will have to register handlers
-// with the mux you are using.
-//
-// # Usage examples
-//
-// Use the pprof tool to look at the heap profile:
-//
-// go tool pprof http://localhost:6060/debug/pprof/heap
-//
-// Or to look at a 30-second CPU profile:
-//
-// go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
-//
-// Or to look at the goroutine blocking profile, after calling
-// runtime.SetBlockProfileRate in your program:
-//
-// go tool pprof http://localhost:6060/debug/pprof/block
-//
-// Or to look at the holders of contended mutexes, after calling
-// runtime.SetMutexProfileFraction in your program:
-//
-// go tool pprof http://localhost:6060/debug/pprof/mutex
-//
-// The package also exports a handler that serves execution trace data
-// for the "go tool trace" command. To collect a 5-second execution trace:
-//
-// curl -o trace.out http://localhost:6060/debug/pprof/trace?seconds=5
-// go tool trace trace.out
-//
-// To view all available profiles, open http://localhost:6060/debug/pprof/
-// in your browser.
-//
-// For a study of the facility in action, visit
-//
-// https://blog.golang.org/2011/06/profiling-go-programs.html
-package pprof
-
-import (
- "bufio"
- "bytes"
- "context"
- "fmt"
- "html"
- "internal/profile"
- "io"
- "log"
- "net/http"
- "net/url"
- "os"
- "runtime"
- "runtime/pprof"
- "runtime/trace"
- "sort"
- "strconv"
- "strings"
- "time"
-)
-
-func init() {
- http.HandleFunc("/debug/pprof/", Index)
- http.HandleFunc("/debug/pprof/cmdline", Cmdline)
- http.HandleFunc("/debug/pprof/profile", Profile)
- http.HandleFunc("/debug/pprof/symbol", Symbol)
- http.HandleFunc("/debug/pprof/trace", Trace)
-}
-
-// Cmdline responds with the running program's
-// command line, with arguments separated by NUL bytes.
-// The package initialization registers it as /debug/pprof/cmdline.
-func Cmdline(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("X-Content-Type-Options", "nosniff")
- w.Header().Set("Content-Type", "text/plain; charset=utf-8")
- fmt.Fprint(w, strings.Join(os.Args, "\x00"))
-}
-
-func sleep(r *http.Request, d time.Duration) {
- select {
- case <-time.After(d):
- case <-r.Context().Done():
- }
-}
-
-func durationExceedsWriteTimeout(r *http.Request, seconds float64) bool {
- srv, ok := r.Context().Value(http.ServerContextKey).(*http.Server)
- return ok && srv.WriteTimeout != 0 && seconds >= srv.WriteTimeout.Seconds()
-}
-
-func serveError(w http.ResponseWriter, status int, txt string) {
- w.Header().Set("Content-Type", "text/plain; charset=utf-8")
- w.Header().Set("X-Go-Pprof", "1")
- w.Header().Del("Content-Disposition")
- w.WriteHeader(status)
- fmt.Fprintln(w, txt)
-}
-
-// Profile responds with the pprof-formatted cpu profile.
-// Profiling lasts for duration specified in seconds GET parameter, or for 30 seconds if not specified.
-// The package initialization registers it as /debug/pprof/profile.
-func Profile(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("X-Content-Type-Options", "nosniff")
- sec, err := strconv.ParseInt(r.FormValue("seconds"), 10, 64)
- if sec <= 0 || err != nil {
- sec = 30
- }
-
- if durationExceedsWriteTimeout(r, float64(sec)) {
- serveError(w, http.StatusBadRequest, "profile duration exceeds server's WriteTimeout")
- return
- }
-
- // Set Content Type assuming StartCPUProfile will work,
- // because if it does it starts writing.
- w.Header().Set("Content-Type", "application/octet-stream")
- w.Header().Set("Content-Disposition", `attachment; filename="profile"`)
- if err := pprof.StartCPUProfile(w); err != nil {
- // StartCPUProfile failed, so no writes yet.
- serveError(w, http.StatusInternalServerError,
- fmt.Sprintf("Could not enable CPU profiling: %s", err))
- return
- }
- sleep(r, time.Duration(sec)*time.Second)
- pprof.StopCPUProfile()
-}
-
-// Trace responds with the execution trace in binary form.
-// Tracing lasts for duration specified in seconds GET parameter, or for 1 second if not specified.
-// The package initialization registers it as /debug/pprof/trace.
-func Trace(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("X-Content-Type-Options", "nosniff")
- sec, err := strconv.ParseFloat(r.FormValue("seconds"), 64)
- if sec <= 0 || err != nil {
- sec = 1
- }
-
- if durationExceedsWriteTimeout(r, sec) {
- serveError(w, http.StatusBadRequest, "profile duration exceeds server's WriteTimeout")
- return
- }
-
- // Set Content Type assuming trace.Start will work,
- // because if it does it starts writing.
- w.Header().Set("Content-Type", "application/octet-stream")
- w.Header().Set("Content-Disposition", `attachment; filename="trace"`)
- if err := trace.Start(w); err != nil {
- // trace.Start failed, so no writes yet.
- serveError(w, http.StatusInternalServerError,
- fmt.Sprintf("Could not enable tracing: %s", err))
- return
- }
- sleep(r, time.Duration(sec*float64(time.Second)))
- trace.Stop()
-}
-
-// Symbol looks up the program counters listed in the request,
-// responding with a table mapping program counters to function names.
-// The package initialization registers it as /debug/pprof/symbol.
-func Symbol(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("X-Content-Type-Options", "nosniff")
- w.Header().Set("Content-Type", "text/plain; charset=utf-8")
-
- // We have to read the whole POST body before
- // writing any output. Buffer the output here.
- var buf bytes.Buffer
-
- // We don't know how many symbols we have, but we
- // do have symbol information. Pprof only cares whether
- // this number is 0 (no symbols available) or > 0.
- fmt.Fprintf(&buf, "num_symbols: 1\n")
-
- var b *bufio.Reader
- if r.Method == "POST" {
- b = bufio.NewReader(r.Body)
- } else {
- b = bufio.NewReader(strings.NewReader(r.URL.RawQuery))
- }
-
- for {
- word, err := b.ReadSlice('+')
- if err == nil {
- word = word[0 : len(word)-1] // trim +
- }
- pc, _ := strconv.ParseUint(string(word), 0, 64)
- if pc != 0 {
- f := runtime.FuncForPC(uintptr(pc))
- if f != nil {
- fmt.Fprintf(&buf, "%#x %s\n", pc, f.Name())
- }
- }
-
- // Wait until here to check for err; the last
- // symbol will have an err because it doesn't end in +.
- if err != nil {
- if err != io.EOF {
- fmt.Fprintf(&buf, "reading request: %v\n", err)
- }
- break
- }
- }
-
- w.Write(buf.Bytes())
-}
-
-// Handler returns an HTTP handler that serves the named profile.
-// Available profiles can be found in [runtime/pprof.Profile].
-func Handler(name string) http.Handler {
- return handler(name)
-}
-
-type handler string
-
-func (name handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("X-Content-Type-Options", "nosniff")
- p := pprof.Lookup(string(name))
- if p == nil {
- serveError(w, http.StatusNotFound, "Unknown profile")
- return
- }
- if sec := r.FormValue("seconds"); sec != "" {
- name.serveDeltaProfile(w, r, p, sec)
- return
- }
- gc, _ := strconv.Atoi(r.FormValue("gc"))
- if name == "heap" && gc > 0 {
- runtime.GC()
- }
- debug, _ := strconv.Atoi(r.FormValue("debug"))
- if debug != 0 {
- w.Header().Set("Content-Type", "text/plain; charset=utf-8")
- } else {
- w.Header().Set("Content-Type", "application/octet-stream")
- w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, name))
- }
- p.WriteTo(w, debug)
-}
-
-func (name handler) serveDeltaProfile(w http.ResponseWriter, r *http.Request, p *pprof.Profile, secStr string) {
- sec, err := strconv.ParseInt(secStr, 10, 64)
- if err != nil || sec <= 0 {
- serveError(w, http.StatusBadRequest, `invalid value for "seconds" - must be a positive integer`)
- return
- }
- if !profileSupportsDelta[name] {
- serveError(w, http.StatusBadRequest, `"seconds" parameter is not supported for this profile type`)
- return
- }
- // 'name' should be a key in profileSupportsDelta.
- if durationExceedsWriteTimeout(r, float64(sec)) {
- serveError(w, http.StatusBadRequest, "profile duration exceeds server's WriteTimeout")
- return
- }
- debug, _ := strconv.Atoi(r.FormValue("debug"))
- if debug != 0 {
- serveError(w, http.StatusBadRequest, "seconds and debug params are incompatible")
- return
- }
- p0, err := collectProfile(p)
- if err != nil {
- serveError(w, http.StatusInternalServerError, "failed to collect profile")
- return
- }
-
- t := time.NewTimer(time.Duration(sec) * time.Second)
- defer t.Stop()
-
- select {
- case <-r.Context().Done():
- err := r.Context().Err()
- if err == context.DeadlineExceeded {
- serveError(w, http.StatusRequestTimeout, err.Error())
- } else { // TODO: what's a good status code for canceled requests? 400?
- serveError(w, http.StatusInternalServerError, err.Error())
- }
- return
- case <-t.C:
- }
-
- p1, err := collectProfile(p)
- if err != nil {
- serveError(w, http.StatusInternalServerError, "failed to collect profile")
- return
- }
- ts := p1.TimeNanos
- dur := p1.TimeNanos - p0.TimeNanos
-
- p0.Scale(-1)
-
- p1, err = profile.Merge([]*profile.Profile{p0, p1})
- if err != nil {
- serveError(w, http.StatusInternalServerError, "failed to compute delta")
- return
- }
-
- p1.TimeNanos = ts // set since we don't know what profile.Merge set for TimeNanos.
- p1.DurationNanos = dur
-
- w.Header().Set("Content-Type", "application/octet-stream")
- w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s-delta"`, name))
- p1.Write(w)
-}
-
-func collectProfile(p *pprof.Profile) (*profile.Profile, error) {
- var buf bytes.Buffer
- if err := p.WriteTo(&buf, 0); err != nil {
- return nil, err
- }
- ts := time.Now().UnixNano()
- p0, err := profile.Parse(&buf)
- if err != nil {
- return nil, err
- }
- p0.TimeNanos = ts
- return p0, nil
-}
-
-var profileSupportsDelta = map[handler]bool{
- "allocs": true,
- "block": true,
- "goroutine": true,
- "heap": true,
- "mutex": true,
- "threadcreate": true,
-}
-
-var profileDescriptions = map[string]string{
- "allocs": "A sampling of all past memory allocations",
- "block": "Stack traces that led to blocking on synchronization primitives",
- "cmdline": "The command line invocation of the current program",
- "goroutine": "Stack traces of all current goroutines. Use debug=2 as a query parameter to export in the same format as an unrecovered panic.",
- "heap": "A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample.",
- "mutex": "Stack traces of holders of contended mutexes",
- "profile": "CPU profile. You can specify the duration in the seconds GET parameter. After you get the profile file, use the go tool pprof command to investigate the profile.",
- "threadcreate": "Stack traces that led to the creation of new OS threads",
- "trace": "A trace of execution of the current program. You can specify the duration in the seconds GET parameter. After you get the trace file, use the go tool trace command to investigate the trace.",
-}
-
-type profileEntry struct {
- Name string
- Href string
- Desc string
- Count int
-}
-
-// Index responds with the pprof-formatted profile named by the request.
-// For example, "/debug/pprof/heap" serves the "heap" profile.
-// Index responds to a request for "/debug/pprof/" with an HTML page
-// listing the available profiles.
-func Index(w http.ResponseWriter, r *http.Request) {
- if name, found := strings.CutPrefix(r.URL.Path, "/debug/pprof/"); found {
- if name != "" {
- handler(name).ServeHTTP(w, r)
- return
- }
- }
-
- w.Header().Set("X-Content-Type-Options", "nosniff")
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
-
- var profiles []profileEntry
- for _, p := range pprof.Profiles() {
- profiles = append(profiles, profileEntry{
- Name: p.Name(),
- Href: p.Name(),
- Desc: profileDescriptions[p.Name()],
- Count: p.Count(),
- })
- }
-
- // Adding other profiles exposed from within this package
- for _, p := range []string{"cmdline", "profile", "trace"} {
- profiles = append(profiles, profileEntry{
- Name: p,
- Href: p,
- Desc: profileDescriptions[p],
- })
- }
-
- sort.Slice(profiles, func(i, j int) bool {
- return profiles[i].Name < profiles[j].Name
- })
-
- if err := indexTmplExecute(w, profiles); err != nil {
- log.Print(err)
- }
-}
-
-func indexTmplExecute(w io.Writer, profiles []profileEntry) error {
- var b bytes.Buffer
- b.WriteString(`<html>
-<head>
-<title>/debug/pprof/</title>
-<style>
-.profile-name{
- display:inline-block;
- width:6rem;
-}
-</style>
-</head>
-<body>
-/debug/pprof/
-<br>
-<p>Set debug=1 as a query parameter to export in legacy text format</p>
-<br>
-Types of profiles available:
-<table>
-<thead><td>Count</td><td>Profile</td></thead>
-`)
-
- for _, profile := range profiles {
- link := &url.URL{Path: profile.Href, RawQuery: "debug=1"}
- fmt.Fprintf(&b, "<tr><td>%d</td><td><a href='%s'>%s</a></td></tr>\n", profile.Count, link, html.EscapeString(profile.Name))
- }
-
- b.WriteString(`</table>
-<a href="goroutine?debug=2">full goroutine stack dump</a>
-<br>
-<p>
-Profile Descriptions:
-<ul>
-`)
- for _, profile := range profiles {
- fmt.Fprintf(&b, "<li><div class=profile-name>%s: </div> %s</li>\n", html.EscapeString(profile.Name), html.EscapeString(profile.Desc))
- }
- b.WriteString(`</ul>
-</p>
-</body>
-</html>`)
-
- _, err := w.Write(b.Bytes())
- return err
-}
diff --git a/contrib/go/_std_1.20/src/net/http/pprof/ya.make b/contrib/go/_std_1.20/src/net/http/pprof/ya.make
deleted file mode 100644
index 81237519a8..0000000000
--- a/contrib/go/_std_1.20/src/net/http/pprof/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- pprof.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/http/request.go b/contrib/go/_std_1.20/src/net/http/request.go
deleted file mode 100644
index 9c888b3768..0000000000
--- a/contrib/go/_std_1.20/src/net/http/request.go
+++ /dev/null
@@ -1,1462 +0,0 @@
-// Copyright 2009 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.
-
-// HTTP Request reading and parsing.
-
-package http
-
-import (
- "bufio"
- "bytes"
- "context"
- "crypto/tls"
- "encoding/base64"
- "errors"
- "fmt"
- "io"
- "mime"
- "mime/multipart"
- "net/http/httptrace"
- "net/http/internal/ascii"
- "net/textproto"
- "net/url"
- urlpkg "net/url"
- "strconv"
- "strings"
- "sync"
-
- "golang.org/x/net/http/httpguts"
- "golang.org/x/net/idna"
-)
-
-const (
- defaultMaxMemory = 32 << 20 // 32 MB
-)
-
-// ErrMissingFile is returned by FormFile when the provided file field name
-// is either not present in the request or not a file field.
-var ErrMissingFile = errors.New("http: no such file")
-
-// ProtocolError represents an HTTP protocol error.
-//
-// Deprecated: Not all errors in the http package related to protocol errors
-// are of type ProtocolError.
-type ProtocolError struct {
- ErrorString string
-}
-
-func (pe *ProtocolError) Error() string { return pe.ErrorString }
-
-var (
- // ErrNotSupported indicates that a feature is not supported.
- //
- // It is returned by ResponseController methods to indicate that
- // the handler does not support the method, and by the Push method
- // of Pusher implementations to indicate that HTTP/2 Push support
- // is not available.
- ErrNotSupported = &ProtocolError{"feature not supported"}
-
- // Deprecated: ErrUnexpectedTrailer is no longer returned by
- // anything in the net/http package. Callers should not
- // compare errors against this variable.
- ErrUnexpectedTrailer = &ProtocolError{"trailer header without chunked transfer encoding"}
-
- // ErrMissingBoundary is returned by Request.MultipartReader when the
- // request's Content-Type does not include a "boundary" parameter.
- ErrMissingBoundary = &ProtocolError{"no multipart boundary param in Content-Type"}
-
- // ErrNotMultipart is returned by Request.MultipartReader when the
- // request's Content-Type is not multipart/form-data.
- ErrNotMultipart = &ProtocolError{"request Content-Type isn't multipart/form-data"}
-
- // Deprecated: ErrHeaderTooLong is no longer returned by
- // anything in the net/http package. Callers should not
- // compare errors against this variable.
- ErrHeaderTooLong = &ProtocolError{"header too long"}
-
- // Deprecated: ErrShortBody is no longer returned by
- // anything in the net/http package. Callers should not
- // compare errors against this variable.
- ErrShortBody = &ProtocolError{"entity body too short"}
-
- // Deprecated: ErrMissingContentLength is no longer returned by
- // anything in the net/http package. Callers should not
- // compare errors against this variable.
- ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
-)
-
-func badStringError(what, val string) error { return fmt.Errorf("%s %q", what, val) }
-
-// Headers that Request.Write handles itself and should be skipped.
-var reqWriteExcludeHeader = map[string]bool{
- "Host": true, // not in Header map anyway
- "User-Agent": true,
- "Content-Length": true,
- "Transfer-Encoding": true,
- "Trailer": true,
-}
-
-// A Request represents an HTTP request received by a server
-// or to be sent by a client.
-//
-// The field semantics differ slightly between client and server
-// usage. In addition to the notes on the fields below, see the
-// documentation for Request.Write and RoundTripper.
-type Request struct {
- // Method specifies the HTTP method (GET, POST, PUT, etc.).
- // For client requests, an empty string means GET.
- //
- // Go's HTTP client does not support sending a request with
- // the CONNECT method. See the documentation on Transport for
- // details.
- Method string
-
- // URL specifies either the URI being requested (for server
- // requests) or the URL to access (for client requests).
- //
- // For server requests, the URL is parsed from the URI
- // supplied on the Request-Line as stored in RequestURI. For
- // most requests, fields other than Path and RawQuery will be
- // empty. (See RFC 7230, Section 5.3)
- //
- // For client requests, the URL's Host specifies the server to
- // connect to, while the Request's Host field optionally
- // specifies the Host header value to send in the HTTP
- // request.
- URL *url.URL
-
- // The protocol version for incoming server requests.
- //
- // For client requests, these fields are ignored. The HTTP
- // client code always uses either HTTP/1.1 or HTTP/2.
- // See the docs on Transport for details.
- Proto string // "HTTP/1.0"
- ProtoMajor int // 1
- ProtoMinor int // 0
-
- // Header contains the request header fields either received
- // by the server or to be sent by the client.
- //
- // If a server received a request with header lines,
- //
- // Host: example.com
- // accept-encoding: gzip, deflate
- // Accept-Language: en-us
- // fOO: Bar
- // foo: two
- //
- // then
- //
- // Header = map[string][]string{
- // "Accept-Encoding": {"gzip, deflate"},
- // "Accept-Language": {"en-us"},
- // "Foo": {"Bar", "two"},
- // }
- //
- // For incoming requests, the Host header is promoted to the
- // Request.Host field and removed from the Header map.
- //
- // HTTP defines that header names are case-insensitive. The
- // request parser implements this by using CanonicalHeaderKey,
- // making the first character and any characters following a
- // hyphen uppercase and the rest lowercase.
- //
- // For client requests, certain headers such as Content-Length
- // and Connection are automatically written when needed and
- // values in Header may be ignored. See the documentation
- // for the Request.Write method.
- Header Header
-
- // Body is the request's body.
- //
- // For client requests, a nil body means the request has no
- // body, such as a GET request. The HTTP Client's Transport
- // is responsible for calling the Close method.
- //
- // For server requests, the Request Body is always non-nil
- // but will return EOF immediately when no body is present.
- // The Server will close the request body. The ServeHTTP
- // Handler does not need to.
- //
- // Body must allow Read to be called concurrently with Close.
- // In particular, calling Close should unblock a Read waiting
- // for input.
- Body io.ReadCloser
-
- // GetBody defines an optional func to return a new copy of
- // Body. It is used for client requests when a redirect requires
- // reading the body more than once. Use of GetBody still
- // requires setting Body.
- //
- // For server requests, it is unused.
- GetBody func() (io.ReadCloser, error)
-
- // ContentLength records the length of the associated content.
- // The value -1 indicates that the length is unknown.
- // Values >= 0 indicate that the given number of bytes may
- // be read from Body.
- //
- // For client requests, a value of 0 with a non-nil Body is
- // also treated as unknown.
- ContentLength int64
-
- // TransferEncoding lists the transfer encodings from outermost to
- // innermost. An empty list denotes the "identity" encoding.
- // TransferEncoding can usually be ignored; chunked encoding is
- // automatically added and removed as necessary when sending and
- // receiving requests.
- TransferEncoding []string
-
- // Close indicates whether to close the connection after
- // replying to this request (for servers) or after sending this
- // request and reading its response (for clients).
- //
- // For server requests, the HTTP server handles this automatically
- // and this field is not needed by Handlers.
- //
- // For client requests, setting this field prevents re-use of
- // TCP connections between requests to the same hosts, as if
- // Transport.DisableKeepAlives were set.
- Close bool
-
- // For server requests, Host specifies the host on which the
- // URL is sought. For HTTP/1 (per RFC 7230, section 5.4), this
- // is either the value of the "Host" header or the host name
- // given in the URL itself. For HTTP/2, it is the value of the
- // ":authority" pseudo-header field.
- // It may be of the form "host:port". For international domain
- // names, Host may be in Punycode or Unicode form. Use
- // golang.org/x/net/idna to convert it to either format if
- // needed.
- // To prevent DNS rebinding attacks, server Handlers should
- // validate that the Host header has a value for which the
- // Handler considers itself authoritative. The included
- // ServeMux supports patterns registered to particular host
- // names and thus protects its registered Handlers.
- //
- // For client requests, Host optionally overrides the Host
- // header to send. If empty, the Request.Write method uses
- // the value of URL.Host. Host may contain an international
- // domain name.
- Host string
-
- // Form contains the parsed form data, including both the URL
- // field's query parameters and the PATCH, POST, or PUT form data.
- // This field is only available after ParseForm is called.
- // The HTTP client ignores Form and uses Body instead.
- Form url.Values
-
- // PostForm contains the parsed form data from PATCH, POST
- // or PUT body parameters.
- //
- // This field is only available after ParseForm is called.
- // The HTTP client ignores PostForm and uses Body instead.
- PostForm url.Values
-
- // MultipartForm is the parsed multipart form, including file uploads.
- // This field is only available after ParseMultipartForm is called.
- // The HTTP client ignores MultipartForm and uses Body instead.
- MultipartForm *multipart.Form
-
- // Trailer specifies additional headers that are sent after the request
- // body.
- //
- // For server requests, the Trailer map initially contains only the
- // trailer keys, with nil values. (The client declares which trailers it
- // will later send.) While the handler is reading from Body, it must
- // not reference Trailer. After reading from Body returns EOF, Trailer
- // can be read again and will contain non-nil values, if they were sent
- // by the client.
- //
- // For client requests, Trailer must be initialized to a map containing
- // the trailer keys to later send. The values may be nil or their final
- // values. The ContentLength must be 0 or -1, to send a chunked request.
- // After the HTTP request is sent the map values can be updated while
- // the request body is read. Once the body returns EOF, the caller must
- // not mutate Trailer.
- //
- // Few HTTP clients, servers, or proxies support HTTP trailers.
- Trailer Header
-
- // RemoteAddr allows HTTP servers and other software to record
- // the network address that sent the request, usually for
- // logging. This field is not filled in by ReadRequest and
- // has no defined format. The HTTP server in this package
- // sets RemoteAddr to an "IP:port" address before invoking a
- // handler.
- // This field is ignored by the HTTP client.
- RemoteAddr string
-
- // RequestURI is the unmodified request-target of the
- // Request-Line (RFC 7230, Section 3.1.1) as sent by the client
- // to a server. Usually the URL field should be used instead.
- // It is an error to set this field in an HTTP client request.
- RequestURI string
-
- // TLS allows HTTP servers and other software to record
- // information about the TLS connection on which the request
- // was received. This field is not filled in by ReadRequest.
- // The HTTP server in this package sets the field for
- // TLS-enabled connections before invoking a handler;
- // otherwise it leaves the field nil.
- // This field is ignored by the HTTP client.
- TLS *tls.ConnectionState
-
- // Cancel is an optional channel whose closure indicates that the client
- // request should be regarded as canceled. Not all implementations of
- // RoundTripper may support Cancel.
- //
- // For server requests, this field is not applicable.
- //
- // Deprecated: Set the Request's context with NewRequestWithContext
- // instead. If a Request's Cancel field and context are both
- // set, it is undefined whether Cancel is respected.
- Cancel <-chan struct{}
-
- // Response is the redirect response which caused this request
- // to be created. This field is only populated during client
- // redirects.
- Response *Response
-
- // ctx is either the client or server context. It should only
- // be modified via copying the whole Request using Clone or WithContext.
- // It is unexported to prevent people from using Context wrong
- // and mutating the contexts held by callers of the same request.
- ctx context.Context
-}
-
-// Context returns the request's context. To change the context, use
-// Clone or WithContext.
-//
-// The returned context is always non-nil; it defaults to the
-// background context.
-//
-// For outgoing client requests, the context controls cancellation.
-//
-// For incoming server requests, the context is canceled when the
-// client's connection closes, the request is canceled (with HTTP/2),
-// or when the ServeHTTP method returns.
-func (r *Request) Context() context.Context {
- if r.ctx != nil {
- return r.ctx
- }
- return context.Background()
-}
-
-// WithContext returns a shallow copy of r with its context changed
-// to ctx. The provided ctx must be non-nil.
-//
-// For outgoing client request, the context controls the entire
-// lifetime of a request and its response: obtaining a connection,
-// sending the request, and reading the response headers and body.
-//
-// To create a new request with a context, use NewRequestWithContext.
-// To make a deep copy of a request with a new context, use Request.Clone.
-func (r *Request) WithContext(ctx context.Context) *Request {
- if ctx == nil {
- panic("nil context")
- }
- r2 := new(Request)
- *r2 = *r
- r2.ctx = ctx
- return r2
-}
-
-// Clone returns a deep copy of r with its context changed to ctx.
-// The provided ctx must be non-nil.
-//
-// For an outgoing client request, the context controls the entire
-// lifetime of a request and its response: obtaining a connection,
-// sending the request, and reading the response headers and body.
-func (r *Request) Clone(ctx context.Context) *Request {
- if ctx == nil {
- panic("nil context")
- }
- r2 := new(Request)
- *r2 = *r
- r2.ctx = ctx
- r2.URL = cloneURL(r.URL)
- if r.Header != nil {
- r2.Header = r.Header.Clone()
- }
- if r.Trailer != nil {
- r2.Trailer = r.Trailer.Clone()
- }
- if s := r.TransferEncoding; s != nil {
- s2 := make([]string, len(s))
- copy(s2, s)
- r2.TransferEncoding = s2
- }
- r2.Form = cloneURLValues(r.Form)
- r2.PostForm = cloneURLValues(r.PostForm)
- r2.MultipartForm = cloneMultipartForm(r.MultipartForm)
- return r2
-}
-
-// ProtoAtLeast reports whether the HTTP protocol used
-// in the request is at least major.minor.
-func (r *Request) ProtoAtLeast(major, minor int) bool {
- return r.ProtoMajor > major ||
- r.ProtoMajor == major && r.ProtoMinor >= minor
-}
-
-// UserAgent returns the client's User-Agent, if sent in the request.
-func (r *Request) UserAgent() string {
- return r.Header.Get("User-Agent")
-}
-
-// Cookies parses and returns the HTTP cookies sent with the request.
-func (r *Request) Cookies() []*Cookie {
- return readCookies(r.Header, "")
-}
-
-// ErrNoCookie is returned by Request's Cookie method when a cookie is not found.
-var ErrNoCookie = errors.New("http: named cookie not present")
-
-// Cookie returns the named cookie provided in the request or
-// ErrNoCookie if not found.
-// If multiple cookies match the given name, only one cookie will
-// be returned.
-func (r *Request) Cookie(name string) (*Cookie, error) {
- if name == "" {
- return nil, ErrNoCookie
- }
- for _, c := range readCookies(r.Header, name) {
- return c, nil
- }
- return nil, ErrNoCookie
-}
-
-// AddCookie adds a cookie to the request. Per RFC 6265 section 5.4,
-// AddCookie does not attach more than one Cookie header field. That
-// means all cookies, if any, are written into the same line,
-// separated by semicolon.
-// AddCookie only sanitizes c's name and value, and does not sanitize
-// a Cookie header already present in the request.
-func (r *Request) AddCookie(c *Cookie) {
- s := fmt.Sprintf("%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value))
- if c := r.Header.Get("Cookie"); c != "" {
- r.Header.Set("Cookie", c+"; "+s)
- } else {
- r.Header.Set("Cookie", s)
- }
-}
-
-// Referer returns the referring URL, if sent in the request.
-//
-// Referer is misspelled as in the request itself, a mistake from the
-// earliest days of HTTP. This value can also be fetched from the
-// Header map as Header["Referer"]; the benefit of making it available
-// as a method is that the compiler can diagnose programs that use the
-// alternate (correct English) spelling req.Referrer() but cannot
-// diagnose programs that use Header["Referrer"].
-func (r *Request) Referer() string {
- return r.Header.Get("Referer")
-}
-
-// multipartByReader is a sentinel value.
-// Its presence in Request.MultipartForm indicates that parsing of the request
-// body has been handed off to a MultipartReader instead of ParseMultipartForm.
-var multipartByReader = &multipart.Form{
- Value: make(map[string][]string),
- File: make(map[string][]*multipart.FileHeader),
-}
-
-// MultipartReader returns a MIME multipart reader if this is a
-// multipart/form-data or a multipart/mixed POST request, else returns nil and an error.
-// Use this function instead of ParseMultipartForm to
-// process the request body as a stream.
-func (r *Request) MultipartReader() (*multipart.Reader, error) {
- if r.MultipartForm == multipartByReader {
- return nil, errors.New("http: MultipartReader called twice")
- }
- if r.MultipartForm != nil {
- return nil, errors.New("http: multipart handled by ParseMultipartForm")
- }
- r.MultipartForm = multipartByReader
- return r.multipartReader(true)
-}
-
-func (r *Request) multipartReader(allowMixed bool) (*multipart.Reader, error) {
- v := r.Header.Get("Content-Type")
- if v == "" {
- return nil, ErrNotMultipart
- }
- if r.Body == nil {
- return nil, errors.New("missing form body")
- }
- d, params, err := mime.ParseMediaType(v)
- if err != nil || !(d == "multipart/form-data" || allowMixed && d == "multipart/mixed") {
- return nil, ErrNotMultipart
- }
- boundary, ok := params["boundary"]
- if !ok {
- return nil, ErrMissingBoundary
- }
- return multipart.NewReader(r.Body, boundary), nil
-}
-
-// isH2Upgrade reports whether r represents the http2 "client preface"
-// magic string.
-func (r *Request) isH2Upgrade() bool {
- return r.Method == "PRI" && len(r.Header) == 0 && r.URL.Path == "*" && r.Proto == "HTTP/2.0"
-}
-
-// Return value if nonempty, def otherwise.
-func valueOrDefault(value, def string) string {
- if value != "" {
- return value
- }
- return def
-}
-
-// NOTE: This is not intended to reflect the actual Go version being used.
-// It was changed at the time of Go 1.1 release because the former User-Agent
-// had ended up blocked by some intrusion detection systems.
-// See https://codereview.appspot.com/7532043.
-const defaultUserAgent = "Go-http-client/1.1"
-
-// Write writes an HTTP/1.1 request, which is the header and body, in wire format.
-// This method consults the following fields of the request:
-//
-// Host
-// URL
-// Method (defaults to "GET")
-// Header
-// ContentLength
-// TransferEncoding
-// Body
-//
-// If Body is present, Content-Length is <= 0 and TransferEncoding
-// hasn't been set to "identity", Write adds "Transfer-Encoding:
-// chunked" to the header. Body is closed after it is sent.
-func (r *Request) Write(w io.Writer) error {
- return r.write(w, false, nil, nil)
-}
-
-// WriteProxy is like Write but writes the request in the form
-// expected by an HTTP proxy. In particular, WriteProxy writes the
-// initial Request-URI line of the request with an absolute URI, per
-// section 5.3 of RFC 7230, including the scheme and host.
-// In either case, WriteProxy also writes a Host header, using
-// either r.Host or r.URL.Host.
-func (r *Request) WriteProxy(w io.Writer) error {
- return r.write(w, true, nil, nil)
-}
-
-// errMissingHost is returned by Write when there is no Host or URL present in
-// the Request.
-var errMissingHost = errors.New("http: Request.Write on Request with no Host or URL set")
-
-// extraHeaders may be nil
-// waitForContinue may be nil
-// always closes body
-func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitForContinue func() bool) (err error) {
- trace := httptrace.ContextClientTrace(r.Context())
- if trace != nil && trace.WroteRequest != nil {
- defer func() {
- trace.WroteRequest(httptrace.WroteRequestInfo{
- Err: err,
- })
- }()
- }
- closed := false
- defer func() {
- if closed {
- return
- }
- if closeErr := r.closeBody(); closeErr != nil && err == nil {
- err = closeErr
- }
- }()
-
- // Find the target host. Prefer the Host: header, but if that
- // is not given, use the host from the request URL.
- //
- // Clean the host, in case it arrives with unexpected stuff in it.
- host := r.Host
- if host == "" {
- if r.URL == nil {
- return errMissingHost
- }
- host = r.URL.Host
- }
- host, err = httpguts.PunycodeHostPort(host)
- if err != nil {
- return err
- }
- if !httpguts.ValidHostHeader(host) {
- return errors.New("http: invalid Host header")
- }
-
- // According to RFC 6874, an HTTP client, proxy, or other
- // intermediary must remove any IPv6 zone identifier attached
- // to an outgoing URI.
- host = removeZone(host)
-
- ruri := r.URL.RequestURI()
- if usingProxy && r.URL.Scheme != "" && r.URL.Opaque == "" {
- ruri = r.URL.Scheme + "://" + host + ruri
- } else if r.Method == "CONNECT" && r.URL.Path == "" {
- // CONNECT requests normally give just the host and port, not a full URL.
- ruri = host
- if r.URL.Opaque != "" {
- ruri = r.URL.Opaque
- }
- }
- if stringContainsCTLByte(ruri) {
- return errors.New("net/http: can't write control character in Request.URL")
- }
- // TODO: validate r.Method too? At least it's less likely to
- // come from an attacker (more likely to be a constant in
- // code).
-
- // Wrap the writer in a bufio Writer if it's not already buffered.
- // Don't always call NewWriter, as that forces a bytes.Buffer
- // and other small bufio Writers to have a minimum 4k buffer
- // size.
- var bw *bufio.Writer
- if _, ok := w.(io.ByteWriter); !ok {
- bw = bufio.NewWriter(w)
- w = bw
- }
-
- _, err = fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(r.Method, "GET"), ruri)
- if err != nil {
- return err
- }
-
- // Header lines
- _, err = fmt.Fprintf(w, "Host: %s\r\n", host)
- if err != nil {
- return err
- }
- if trace != nil && trace.WroteHeaderField != nil {
- trace.WroteHeaderField("Host", []string{host})
- }
-
- // Use the defaultUserAgent unless the Header contains one, which
- // may be blank to not send the header.
- userAgent := defaultUserAgent
- if r.Header.has("User-Agent") {
- userAgent = r.Header.Get("User-Agent")
- }
- if userAgent != "" {
- _, err = fmt.Fprintf(w, "User-Agent: %s\r\n", userAgent)
- if err != nil {
- return err
- }
- if trace != nil && trace.WroteHeaderField != nil {
- trace.WroteHeaderField("User-Agent", []string{userAgent})
- }
- }
-
- // Process Body,ContentLength,Close,Trailer
- tw, err := newTransferWriter(r)
- if err != nil {
- return err
- }
- err = tw.writeHeader(w, trace)
- if err != nil {
- return err
- }
-
- err = r.Header.writeSubset(w, reqWriteExcludeHeader, trace)
- if err != nil {
- return err
- }
-
- if extraHeaders != nil {
- err = extraHeaders.write(w, trace)
- if err != nil {
- return err
- }
- }
-
- _, err = io.WriteString(w, "\r\n")
- if err != nil {
- return err
- }
-
- if trace != nil && trace.WroteHeaders != nil {
- trace.WroteHeaders()
- }
-
- // Flush and wait for 100-continue if expected.
- if waitForContinue != nil {
- if bw, ok := w.(*bufio.Writer); ok {
- err = bw.Flush()
- if err != nil {
- return err
- }
- }
- if trace != nil && trace.Wait100Continue != nil {
- trace.Wait100Continue()
- }
- if !waitForContinue() {
- closed = true
- r.closeBody()
- return nil
- }
- }
-
- if bw, ok := w.(*bufio.Writer); ok && tw.FlushHeaders {
- if err := bw.Flush(); err != nil {
- return err
- }
- }
-
- // Write body and trailer
- closed = true
- err = tw.writeBody(w)
- if err != nil {
- if tw.bodyReadError == err {
- err = requestBodyReadError{err}
- }
- return err
- }
-
- if bw != nil {
- return bw.Flush()
- }
- return nil
-}
-
-// requestBodyReadError wraps an error from (*Request).write to indicate
-// that the error came from a Read call on the Request.Body.
-// This error type should not escape the net/http package to users.
-type requestBodyReadError struct{ error }
-
-func idnaASCII(v string) (string, error) {
- // TODO: Consider removing this check after verifying performance is okay.
- // Right now punycode verification, length checks, context checks, and the
- // permissible character tests are all omitted. It also prevents the ToASCII
- // call from salvaging an invalid IDN, when possible. As a result it may be
- // possible to have two IDNs that appear identical to the user where the
- // ASCII-only version causes an error downstream whereas the non-ASCII
- // version does not.
- // Note that for correct ASCII IDNs ToASCII will only do considerably more
- // work, but it will not cause an allocation.
- if ascii.Is(v) {
- return v, nil
- }
- return idna.Lookup.ToASCII(v)
-}
-
-// removeZone removes IPv6 zone identifier from host.
-// E.g., "[fe80::1%en0]:8080" to "[fe80::1]:8080"
-func removeZone(host string) string {
- if !strings.HasPrefix(host, "[") {
- return host
- }
- i := strings.LastIndex(host, "]")
- if i < 0 {
- return host
- }
- j := strings.LastIndex(host[:i], "%")
- if j < 0 {
- return host
- }
- return host[:j] + host[i:]
-}
-
-// ParseHTTPVersion parses an HTTP version string according to RFC 7230, section 2.6.
-// "HTTP/1.0" returns (1, 0, true). Note that strings without
-// a minor version, such as "HTTP/2", are not valid.
-func ParseHTTPVersion(vers string) (major, minor int, ok bool) {
- switch vers {
- case "HTTP/1.1":
- return 1, 1, true
- case "HTTP/1.0":
- return 1, 0, true
- }
- if !strings.HasPrefix(vers, "HTTP/") {
- return 0, 0, false
- }
- if len(vers) != len("HTTP/X.Y") {
- return 0, 0, false
- }
- if vers[6] != '.' {
- return 0, 0, false
- }
- maj, err := strconv.ParseUint(vers[5:6], 10, 0)
- if err != nil {
- return 0, 0, false
- }
- min, err := strconv.ParseUint(vers[7:8], 10, 0)
- if err != nil {
- return 0, 0, false
- }
- return int(maj), int(min), true
-}
-
-func validMethod(method string) bool {
- /*
- Method = "OPTIONS" ; Section 9.2
- | "GET" ; Section 9.3
- | "HEAD" ; Section 9.4
- | "POST" ; Section 9.5
- | "PUT" ; Section 9.6
- | "DELETE" ; Section 9.7
- | "TRACE" ; Section 9.8
- | "CONNECT" ; Section 9.9
- | extension-method
- extension-method = token
- token = 1*<any CHAR except CTLs or separators>
- */
- return len(method) > 0 && strings.IndexFunc(method, isNotToken) == -1
-}
-
-// NewRequest wraps NewRequestWithContext using context.Background.
-func NewRequest(method, url string, body io.Reader) (*Request, error) {
- return NewRequestWithContext(context.Background(), method, url, body)
-}
-
-// NewRequestWithContext returns a new Request given a method, URL, and
-// optional body.
-//
-// If the provided body is also an io.Closer, the returned
-// Request.Body is set to body and will be closed by the Client
-// methods Do, Post, and PostForm, and Transport.RoundTrip.
-//
-// NewRequestWithContext returns a Request suitable for use with
-// Client.Do or Transport.RoundTrip. To create a request for use with
-// testing a Server Handler, either use the NewRequest function in the
-// net/http/httptest package, use ReadRequest, or manually update the
-// Request fields. For an outgoing client request, the context
-// controls the entire lifetime of a request and its response:
-// obtaining a connection, sending the request, and reading the
-// response headers and body. See the Request type's documentation for
-// the difference between inbound and outbound request fields.
-//
-// If body is of type *bytes.Buffer, *bytes.Reader, or
-// *strings.Reader, the returned request's ContentLength is set to its
-// exact value (instead of -1), GetBody is populated (so 307 and 308
-// redirects can replay the body), and Body is set to NoBody if the
-// ContentLength is 0.
-func NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error) {
- if method == "" {
- // We document that "" means "GET" for Request.Method, and people have
- // relied on that from NewRequest, so keep that working.
- // We still enforce validMethod for non-empty methods.
- method = "GET"
- }
- if !validMethod(method) {
- return nil, fmt.Errorf("net/http: invalid method %q", method)
- }
- if ctx == nil {
- return nil, errors.New("net/http: nil Context")
- }
- u, err := urlpkg.Parse(url)
- if err != nil {
- return nil, err
- }
- rc, ok := body.(io.ReadCloser)
- if !ok && body != nil {
- rc = io.NopCloser(body)
- }
- // The host's colon:port should be normalized. See Issue 14836.
- u.Host = removeEmptyPort(u.Host)
- req := &Request{
- ctx: ctx,
- Method: method,
- URL: u,
- Proto: "HTTP/1.1",
- ProtoMajor: 1,
- ProtoMinor: 1,
- Header: make(Header),
- Body: rc,
- Host: u.Host,
- }
- if body != nil {
- switch v := body.(type) {
- case *bytes.Buffer:
- req.ContentLength = int64(v.Len())
- buf := v.Bytes()
- req.GetBody = func() (io.ReadCloser, error) {
- r := bytes.NewReader(buf)
- return io.NopCloser(r), nil
- }
- case *bytes.Reader:
- req.ContentLength = int64(v.Len())
- snapshot := *v
- req.GetBody = func() (io.ReadCloser, error) {
- r := snapshot
- return io.NopCloser(&r), nil
- }
- case *strings.Reader:
- req.ContentLength = int64(v.Len())
- snapshot := *v
- req.GetBody = func() (io.ReadCloser, error) {
- r := snapshot
- return io.NopCloser(&r), nil
- }
- default:
- // This is where we'd set it to -1 (at least
- // if body != NoBody) to mean unknown, but
- // that broke people during the Go 1.8 testing
- // period. People depend on it being 0 I
- // guess. Maybe retry later. See Issue 18117.
- }
- // For client requests, Request.ContentLength of 0
- // means either actually 0, or unknown. The only way
- // to explicitly say that the ContentLength is zero is
- // to set the Body to nil. But turns out too much code
- // depends on NewRequest returning a non-nil Body,
- // so we use a well-known ReadCloser variable instead
- // and have the http package also treat that sentinel
- // variable to mean explicitly zero.
- if req.GetBody != nil && req.ContentLength == 0 {
- req.Body = NoBody
- req.GetBody = func() (io.ReadCloser, error) { return NoBody, nil }
- }
- }
-
- return req, nil
-}
-
-// BasicAuth returns the username and password provided in the request's
-// Authorization header, if the request uses HTTP Basic Authentication.
-// See RFC 2617, Section 2.
-func (r *Request) BasicAuth() (username, password string, ok bool) {
- auth := r.Header.Get("Authorization")
- if auth == "" {
- return "", "", false
- }
- return parseBasicAuth(auth)
-}
-
-// parseBasicAuth parses an HTTP Basic Authentication string.
-// "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" returns ("Aladdin", "open sesame", true).
-func parseBasicAuth(auth string) (username, password string, ok bool) {
- const prefix = "Basic "
- // Case insensitive prefix match. See Issue 22736.
- if len(auth) < len(prefix) || !ascii.EqualFold(auth[:len(prefix)], prefix) {
- return "", "", false
- }
- c, err := base64.StdEncoding.DecodeString(auth[len(prefix):])
- if err != nil {
- return "", "", false
- }
- cs := string(c)
- username, password, ok = strings.Cut(cs, ":")
- if !ok {
- return "", "", false
- }
- return username, password, true
-}
-
-// SetBasicAuth sets the request's Authorization header to use HTTP
-// Basic Authentication with the provided username and password.
-//
-// With HTTP Basic Authentication the provided username and password
-// are not encrypted. It should generally only be used in an HTTPS
-// request.
-//
-// The username may not contain a colon. Some protocols may impose
-// additional requirements on pre-escaping the username and
-// password. For instance, when used with OAuth2, both arguments must
-// be URL encoded first with url.QueryEscape.
-func (r *Request) SetBasicAuth(username, password string) {
- r.Header.Set("Authorization", "Basic "+basicAuth(username, password))
-}
-
-// parseRequestLine parses "GET /foo HTTP/1.1" into its three parts.
-func parseRequestLine(line string) (method, requestURI, proto string, ok bool) {
- method, rest, ok1 := strings.Cut(line, " ")
- requestURI, proto, ok2 := strings.Cut(rest, " ")
- if !ok1 || !ok2 {
- return "", "", "", false
- }
- return method, requestURI, proto, true
-}
-
-var textprotoReaderPool sync.Pool
-
-func newTextprotoReader(br *bufio.Reader) *textproto.Reader {
- if v := textprotoReaderPool.Get(); v != nil {
- tr := v.(*textproto.Reader)
- tr.R = br
- return tr
- }
- return textproto.NewReader(br)
-}
-
-func putTextprotoReader(r *textproto.Reader) {
- r.R = nil
- textprotoReaderPool.Put(r)
-}
-
-// ReadRequest reads and parses an incoming request from b.
-//
-// ReadRequest is a low-level function and should only be used for
-// specialized applications; most code should use the Server to read
-// requests and handle them via the Handler interface. ReadRequest
-// only supports HTTP/1.x requests. For HTTP/2, use golang.org/x/net/http2.
-func ReadRequest(b *bufio.Reader) (*Request, error) {
- req, err := readRequest(b)
- if err != nil {
- return nil, err
- }
-
- delete(req.Header, "Host")
- return req, err
-}
-
-func readRequest(b *bufio.Reader) (req *Request, err error) {
- tp := newTextprotoReader(b)
- defer putTextprotoReader(tp)
-
- req = new(Request)
-
- // First line: GET /index.html HTTP/1.0
- var s string
- if s, err = tp.ReadLine(); err != nil {
- return nil, err
- }
- defer func() {
- if err == io.EOF {
- err = io.ErrUnexpectedEOF
- }
- }()
-
- var ok bool
- req.Method, req.RequestURI, req.Proto, ok = parseRequestLine(s)
- if !ok {
- return nil, badStringError("malformed HTTP request", s)
- }
- if !validMethod(req.Method) {
- return nil, badStringError("invalid method", req.Method)
- }
- rawurl := req.RequestURI
- if req.ProtoMajor, req.ProtoMinor, ok = ParseHTTPVersion(req.Proto); !ok {
- return nil, badStringError("malformed HTTP version", req.Proto)
- }
-
- // CONNECT requests are used two different ways, and neither uses a full URL:
- // The standard use is to tunnel HTTPS through an HTTP proxy.
- // It looks like "CONNECT www.google.com:443 HTTP/1.1", and the parameter is
- // just the authority section of a URL. This information should go in req.URL.Host.
- //
- // The net/rpc package also uses CONNECT, but there the parameter is a path
- // that starts with a slash. It can be parsed with the regular URL parser,
- // and the path will end up in req.URL.Path, where it needs to be in order for
- // RPC to work.
- justAuthority := req.Method == "CONNECT" && !strings.HasPrefix(rawurl, "/")
- if justAuthority {
- rawurl = "http://" + rawurl
- }
-
- if req.URL, err = url.ParseRequestURI(rawurl); err != nil {
- return nil, err
- }
-
- if justAuthority {
- // Strip the bogus "http://" back off.
- req.URL.Scheme = ""
- }
-
- // Subsequent lines: Key: value.
- mimeHeader, err := tp.ReadMIMEHeader()
- if err != nil {
- return nil, err
- }
- req.Header = Header(mimeHeader)
- if len(req.Header["Host"]) > 1 {
- return nil, fmt.Errorf("too many Host headers")
- }
-
- // RFC 7230, section 5.3: Must treat
- // GET /index.html HTTP/1.1
- // Host: www.google.com
- // and
- // GET http://www.google.com/index.html HTTP/1.1
- // Host: doesntmatter
- // the same. In the second case, any Host line is ignored.
- req.Host = req.URL.Host
- if req.Host == "" {
- req.Host = req.Header.get("Host")
- }
-
- fixPragmaCacheControl(req.Header)
-
- req.Close = shouldClose(req.ProtoMajor, req.ProtoMinor, req.Header, false)
-
- err = readTransfer(req, b)
- if err != nil {
- return nil, err
- }
-
- if req.isH2Upgrade() {
- // Because it's neither chunked, nor declared:
- req.ContentLength = -1
-
- // We want to give handlers a chance to hijack the
- // connection, but we need to prevent the Server from
- // dealing with the connection further if it's not
- // hijacked. Set Close to ensure that:
- req.Close = true
- }
- return req, nil
-}
-
-// MaxBytesReader is similar to io.LimitReader but is intended for
-// limiting the size of incoming request bodies. In contrast to
-// io.LimitReader, MaxBytesReader's result is a ReadCloser, returns a
-// non-nil error of type *MaxBytesError for a Read beyond the limit,
-// and closes the underlying reader when its Close method is called.
-//
-// MaxBytesReader prevents clients from accidentally or maliciously
-// sending a large request and wasting server resources. If possible,
-// it tells the ResponseWriter to close the connection after the limit
-// has been reached.
-func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser {
- if n < 0 { // Treat negative limits as equivalent to 0.
- n = 0
- }
- return &maxBytesReader{w: w, r: r, i: n, n: n}
-}
-
-// MaxBytesError is returned by MaxBytesReader when its read limit is exceeded.
-type MaxBytesError struct {
- Limit int64
-}
-
-func (e *MaxBytesError) Error() string {
- // Due to Hyrum's law, this text cannot be changed.
- return "http: request body too large"
-}
-
-type maxBytesReader struct {
- w ResponseWriter
- r io.ReadCloser // underlying reader
- i int64 // max bytes initially, for MaxBytesError
- n int64 // max bytes remaining
- err error // sticky error
-}
-
-func (l *maxBytesReader) Read(p []byte) (n int, err error) {
- if l.err != nil {
- return 0, l.err
- }
- if len(p) == 0 {
- return 0, nil
- }
- // If they asked for a 32KB byte read but only 5 bytes are
- // remaining, no need to read 32KB. 6 bytes will answer the
- // question of the whether we hit the limit or go past it.
- // 0 < len(p) < 2^63
- if int64(len(p))-1 > l.n {
- p = p[:l.n+1]
- }
- n, err = l.r.Read(p)
-
- if int64(n) <= l.n {
- l.n -= int64(n)
- l.err = err
- return n, err
- }
-
- n = int(l.n)
- l.n = 0
-
- // The server code and client code both use
- // maxBytesReader. This "requestTooLarge" check is
- // only used by the server code. To prevent binaries
- // which only using the HTTP Client code (such as
- // cmd/go) from also linking in the HTTP server, don't
- // use a static type assertion to the server
- // "*response" type. Check this interface instead:
- type requestTooLarger interface {
- requestTooLarge()
- }
- if res, ok := l.w.(requestTooLarger); ok {
- res.requestTooLarge()
- }
- l.err = &MaxBytesError{l.i}
- return n, l.err
-}
-
-func (l *maxBytesReader) Close() error {
- return l.r.Close()
-}
-
-func copyValues(dst, src url.Values) {
- for k, vs := range src {
- dst[k] = append(dst[k], vs...)
- }
-}
-
-func parsePostForm(r *Request) (vs url.Values, err error) {
- if r.Body == nil {
- err = errors.New("missing form body")
- return
- }
- ct := r.Header.Get("Content-Type")
- // RFC 7231, section 3.1.1.5 - empty type
- // MAY be treated as application/octet-stream
- if ct == "" {
- ct = "application/octet-stream"
- }
- ct, _, err = mime.ParseMediaType(ct)
- switch {
- case ct == "application/x-www-form-urlencoded":
- var reader io.Reader = r.Body
- maxFormSize := int64(1<<63 - 1)
- if _, ok := r.Body.(*maxBytesReader); !ok {
- maxFormSize = int64(10 << 20) // 10 MB is a lot of text.
- reader = io.LimitReader(r.Body, maxFormSize+1)
- }
- b, e := io.ReadAll(reader)
- if e != nil {
- if err == nil {
- err = e
- }
- break
- }
- if int64(len(b)) > maxFormSize {
- err = errors.New("http: POST too large")
- return
- }
- vs, e = url.ParseQuery(string(b))
- if err == nil {
- err = e
- }
- case ct == "multipart/form-data":
- // handled by ParseMultipartForm (which is calling us, or should be)
- // TODO(bradfitz): there are too many possible
- // orders to call too many functions here.
- // Clean this up and write more tests.
- // request_test.go contains the start of this,
- // in TestParseMultipartFormOrder and others.
- }
- return
-}
-
-// ParseForm populates r.Form and r.PostForm.
-//
-// For all requests, ParseForm parses the raw query from the URL and updates
-// r.Form.
-//
-// For POST, PUT, and PATCH requests, it also reads the request body, parses it
-// as a form and puts the results into both r.PostForm and r.Form. Request body
-// parameters take precedence over URL query string values in r.Form.
-//
-// If the request Body's size has not already been limited by MaxBytesReader,
-// the size is capped at 10MB.
-//
-// For other HTTP methods, or when the Content-Type is not
-// application/x-www-form-urlencoded, the request Body is not read, and
-// r.PostForm is initialized to a non-nil, empty value.
-//
-// ParseMultipartForm calls ParseForm automatically.
-// ParseForm is idempotent.
-func (r *Request) ParseForm() error {
- var err error
- if r.PostForm == nil {
- if r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" {
- r.PostForm, err = parsePostForm(r)
- }
- if r.PostForm == nil {
- r.PostForm = make(url.Values)
- }
- }
- if r.Form == nil {
- if len(r.PostForm) > 0 {
- r.Form = make(url.Values)
- copyValues(r.Form, r.PostForm)
- }
- var newValues url.Values
- if r.URL != nil {
- var e error
- newValues, e = url.ParseQuery(r.URL.RawQuery)
- if err == nil {
- err = e
- }
- }
- if newValues == nil {
- newValues = make(url.Values)
- }
- if r.Form == nil {
- r.Form = newValues
- } else {
- copyValues(r.Form, newValues)
- }
- }
- return err
-}
-
-// ParseMultipartForm parses a request body as multipart/form-data.
-// The whole request body is parsed and up to a total of maxMemory bytes of
-// its file parts are stored in memory, with the remainder stored on
-// disk in temporary files.
-// ParseMultipartForm calls ParseForm if necessary.
-// If ParseForm returns an error, ParseMultipartForm returns it but also
-// continues parsing the request body.
-// After one call to ParseMultipartForm, subsequent calls have no effect.
-func (r *Request) ParseMultipartForm(maxMemory int64) error {
- if r.MultipartForm == multipartByReader {
- return errors.New("http: multipart handled by MultipartReader")
- }
- var parseFormErr error
- if r.Form == nil {
- // Let errors in ParseForm fall through, and just
- // return it at the end.
- parseFormErr = r.ParseForm()
- }
- if r.MultipartForm != nil {
- return nil
- }
-
- mr, err := r.multipartReader(false)
- if err != nil {
- return err
- }
-
- f, err := mr.ReadForm(maxMemory)
- if err != nil {
- return err
- }
-
- if r.PostForm == nil {
- r.PostForm = make(url.Values)
- }
- for k, v := range f.Value {
- r.Form[k] = append(r.Form[k], v...)
- // r.PostForm should also be populated. See Issue 9305.
- r.PostForm[k] = append(r.PostForm[k], v...)
- }
-
- r.MultipartForm = f
-
- return parseFormErr
-}
-
-// FormValue returns the first value for the named component of the query.
-// POST and PUT body parameters take precedence over URL query string values.
-// FormValue calls ParseMultipartForm and ParseForm if necessary and ignores
-// any errors returned by these functions.
-// If key is not present, FormValue returns the empty string.
-// To access multiple values of the same key, call ParseForm and
-// then inspect Request.Form directly.
-func (r *Request) FormValue(key string) string {
- if r.Form == nil {
- r.ParseMultipartForm(defaultMaxMemory)
- }
- if vs := r.Form[key]; len(vs) > 0 {
- return vs[0]
- }
- return ""
-}
-
-// PostFormValue returns the first value for the named component of the POST,
-// PATCH, or PUT request body. URL query parameters are ignored.
-// PostFormValue calls ParseMultipartForm and ParseForm if necessary and ignores
-// any errors returned by these functions.
-// If key is not present, PostFormValue returns the empty string.
-func (r *Request) PostFormValue(key string) string {
- if r.PostForm == nil {
- r.ParseMultipartForm(defaultMaxMemory)
- }
- if vs := r.PostForm[key]; len(vs) > 0 {
- return vs[0]
- }
- return ""
-}
-
-// FormFile returns the first file for the provided form key.
-// FormFile calls ParseMultipartForm and ParseForm if necessary.
-func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) {
- if r.MultipartForm == multipartByReader {
- return nil, nil, errors.New("http: multipart handled by MultipartReader")
- }
- if r.MultipartForm == nil {
- err := r.ParseMultipartForm(defaultMaxMemory)
- if err != nil {
- return nil, nil, err
- }
- }
- if r.MultipartForm != nil && r.MultipartForm.File != nil {
- if fhs := r.MultipartForm.File[key]; len(fhs) > 0 {
- f, err := fhs[0].Open()
- return f, fhs[0], err
- }
- }
- return nil, nil, ErrMissingFile
-}
-
-func (r *Request) expectsContinue() bool {
- return hasToken(r.Header.get("Expect"), "100-continue")
-}
-
-func (r *Request) wantsHttp10KeepAlive() bool {
- if r.ProtoMajor != 1 || r.ProtoMinor != 0 {
- return false
- }
- return hasToken(r.Header.get("Connection"), "keep-alive")
-}
-
-func (r *Request) wantsClose() bool {
- if r.Close {
- return true
- }
- return hasToken(r.Header.get("Connection"), "close")
-}
-
-func (r *Request) closeBody() error {
- if r.Body == nil {
- return nil
- }
- return r.Body.Close()
-}
-
-func (r *Request) isReplayable() bool {
- if r.Body == nil || r.Body == NoBody || r.GetBody != nil {
- switch valueOrDefault(r.Method, "GET") {
- case "GET", "HEAD", "OPTIONS", "TRACE":
- return true
- }
- // The Idempotency-Key, while non-standard, is widely used to
- // mean a POST or other request is idempotent. See
- // https://golang.org/issue/19943#issuecomment-421092421
- if r.Header.has("Idempotency-Key") || r.Header.has("X-Idempotency-Key") {
- return true
- }
- }
- return false
-}
-
-// outgoingLength reports the Content-Length of this outgoing (Client) request.
-// It maps 0 into -1 (unknown) when the Body is non-nil.
-func (r *Request) outgoingLength() int64 {
- if r.Body == nil || r.Body == NoBody {
- return 0
- }
- if r.ContentLength != 0 {
- return r.ContentLength
- }
- return -1
-}
-
-// requestMethodUsuallyLacksBody reports whether the given request
-// method is one that typically does not involve a request body.
-// This is used by the Transport (via
-// transferWriter.shouldSendChunkedRequestBody) to determine whether
-// we try to test-read a byte from a non-nil Request.Body when
-// Request.outgoingLength() returns -1. See the comments in
-// shouldSendChunkedRequestBody.
-func requestMethodUsuallyLacksBody(method string) bool {
- switch method {
- case "GET", "HEAD", "DELETE", "OPTIONS", "PROPFIND", "SEARCH":
- return true
- }
- return false
-}
-
-// requiresHTTP1 reports whether this request requires being sent on
-// an HTTP/1 connection.
-func (r *Request) requiresHTTP1() bool {
- return hasToken(r.Header.Get("Connection"), "upgrade") &&
- ascii.EqualFold(r.Header.Get("Upgrade"), "websocket")
-}
diff --git a/contrib/go/_std_1.20/src/net/http/responsecontroller.go b/contrib/go/_std_1.20/src/net/http/responsecontroller.go
deleted file mode 100644
index 018bdc00eb..0000000000
--- a/contrib/go/_std_1.20/src/net/http/responsecontroller.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2022 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 http
-
-import (
- "bufio"
- "fmt"
- "net"
- "time"
-)
-
-// A ResponseController is used by an HTTP handler to control the response.
-//
-// A ResponseController may not be used after the Handler.ServeHTTP method has returned.
-type ResponseController struct {
- rw ResponseWriter
-}
-
-// NewResponseController creates a ResponseController for a request.
-//
-// The ResponseWriter should be the original value passed to the Handler.ServeHTTP method,
-// or have an Unwrap method returning the original ResponseWriter.
-//
-// If the ResponseWriter implements any of the following methods, the ResponseController
-// will call them as appropriate:
-//
-// Flush()
-// FlushError() error // alternative Flush returning an error
-// Hijack() (net.Conn, *bufio.ReadWriter, error)
-// SetReadDeadline(deadline time.Time) error
-// SetWriteDeadline(deadline time.Time) error
-//
-// If the ResponseWriter does not support a method, ResponseController returns
-// an error matching ErrNotSupported.
-func NewResponseController(rw ResponseWriter) *ResponseController {
- return &ResponseController{rw}
-}
-
-type rwUnwrapper interface {
- Unwrap() ResponseWriter
-}
-
-// Flush flushes buffered data to the client.
-func (c *ResponseController) Flush() error {
- rw := c.rw
- for {
- switch t := rw.(type) {
- case interface{ FlushError() error }:
- return t.FlushError()
- case Flusher:
- t.Flush()
- return nil
- case rwUnwrapper:
- rw = t.Unwrap()
- default:
- return errNotSupported()
- }
- }
-}
-
-// Hijack lets the caller take over the connection.
-// See the Hijacker interface for details.
-func (c *ResponseController) Hijack() (net.Conn, *bufio.ReadWriter, error) {
- rw := c.rw
- for {
- switch t := rw.(type) {
- case Hijacker:
- return t.Hijack()
- case rwUnwrapper:
- rw = t.Unwrap()
- default:
- return nil, nil, errNotSupported()
- }
- }
-}
-
-// SetReadDeadline sets the deadline for reading the entire request, including the body.
-// Reads from the request body after the deadline has been exceeded will return an error.
-// A zero value means no deadline.
-//
-// Setting the read deadline after it has been exceeded will not extend it.
-func (c *ResponseController) SetReadDeadline(deadline time.Time) error {
- rw := c.rw
- for {
- switch t := rw.(type) {
- case interface{ SetReadDeadline(time.Time) error }:
- return t.SetReadDeadline(deadline)
- case rwUnwrapper:
- rw = t.Unwrap()
- default:
- return errNotSupported()
- }
- }
-}
-
-// SetWriteDeadline sets the deadline for writing the response.
-// Writes to the response body after the deadline has been exceeded will not block,
-// but may succeed if the data has been buffered.
-// A zero value means no deadline.
-//
-// Setting the write deadline after it has been exceeded will not extend it.
-func (c *ResponseController) SetWriteDeadline(deadline time.Time) error {
- rw := c.rw
- for {
- switch t := rw.(type) {
- case interface{ SetWriteDeadline(time.Time) error }:
- return t.SetWriteDeadline(deadline)
- case rwUnwrapper:
- rw = t.Unwrap()
- default:
- return errNotSupported()
- }
- }
-}
-
-// errNotSupported returns an error that Is ErrNotSupported,
-// but is not == to it.
-func errNotSupported() error {
- return fmt.Errorf("%w", ErrNotSupported)
-}
diff --git a/contrib/go/_std_1.20/src/net/http/roundtrip.go b/contrib/go/_std_1.20/src/net/http/roundtrip.go
deleted file mode 100644
index c4c5d3b6eb..0000000000
--- a/contrib/go/_std_1.20/src/net/http/roundtrip.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2018 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.
-
-//go:build !js || !wasm
-
-package http
-
-// RoundTrip implements the RoundTripper interface.
-//
-// For higher-level HTTP client support (such as handling of cookies
-// and redirects), see Get, Post, and the Client type.
-//
-// Like the RoundTripper interface, the error types returned
-// by RoundTrip are unspecified.
-func (t *Transport) RoundTrip(req *Request) (*Response, error) {
- return t.roundTrip(req)
-}
diff --git a/contrib/go/_std_1.20/src/net/http/server.go b/contrib/go/_std_1.20/src/net/http/server.go
deleted file mode 100644
index c3c3f91d9a..0000000000
--- a/contrib/go/_std_1.20/src/net/http/server.go
+++ /dev/null
@@ -1,3644 +0,0 @@
-// Copyright 2009 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.
-
-// HTTP server. See RFC 7230 through 7235.
-
-package http
-
-import (
- "bufio"
- "bytes"
- "context"
- "crypto/tls"
- "errors"
- "fmt"
- "internal/godebug"
- "io"
- "log"
- "math/rand"
- "net"
- "net/textproto"
- "net/url"
- urlpkg "net/url"
- "path"
- "runtime"
- "sort"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
- "time"
-
- "golang.org/x/net/http/httpguts"
-)
-
-// Errors used by the HTTP server.
-var (
- // ErrBodyNotAllowed is returned by ResponseWriter.Write calls
- // when the HTTP method or response code does not permit a
- // body.
- ErrBodyNotAllowed = errors.New("http: request method or response status code does not allow body")
-
- // ErrHijacked is returned by ResponseWriter.Write calls when
- // the underlying connection has been hijacked using the
- // Hijacker interface. A zero-byte write on a hijacked
- // connection will return ErrHijacked without any other side
- // effects.
- ErrHijacked = errors.New("http: connection has been hijacked")
-
- // ErrContentLength is returned by ResponseWriter.Write calls
- // when a Handler set a Content-Length response header with a
- // declared size and then attempted to write more bytes than
- // declared.
- ErrContentLength = errors.New("http: wrote more than the declared Content-Length")
-
- // Deprecated: ErrWriteAfterFlush is no longer returned by
- // anything in the net/http package. Callers should not
- // compare errors against this variable.
- ErrWriteAfterFlush = errors.New("unused")
-)
-
-// A Handler responds to an HTTP request.
-//
-// ServeHTTP should write reply headers and data to the ResponseWriter
-// and then return. Returning signals that the request is finished; it
-// is not valid to use the ResponseWriter or read from the
-// Request.Body after or concurrently with the completion of the
-// ServeHTTP call.
-//
-// Depending on the HTTP client software, HTTP protocol version, and
-// any intermediaries between the client and the Go server, it may not
-// be possible to read from the Request.Body after writing to the
-// ResponseWriter. Cautious handlers should read the Request.Body
-// first, and then reply.
-//
-// Except for reading the body, handlers should not modify the
-// provided Request.
-//
-// If ServeHTTP panics, the server (the caller of ServeHTTP) assumes
-// that the effect of the panic was isolated to the active request.
-// It recovers the panic, logs a stack trace to the server error log,
-// and either closes the network connection or sends an HTTP/2
-// RST_STREAM, depending on the HTTP protocol. To abort a handler so
-// the client sees an interrupted response but the server doesn't log
-// an error, panic with the value ErrAbortHandler.
-type Handler interface {
- ServeHTTP(ResponseWriter, *Request)
-}
-
-// A ResponseWriter interface is used by an HTTP handler to
-// construct an HTTP response.
-//
-// A ResponseWriter may not be used after the Handler.ServeHTTP method
-// has returned.
-type ResponseWriter interface {
- // Header returns the header map that will be sent by
- // WriteHeader. The Header map also is the mechanism with which
- // Handlers can set HTTP trailers.
- //
- // Changing the header map after a call to WriteHeader (or
- // Write) has no effect unless the HTTP status code was of the
- // 1xx class or the modified headers are trailers.
- //
- // There are two ways to set Trailers. The preferred way is to
- // predeclare in the headers which trailers you will later
- // send by setting the "Trailer" header to the names of the
- // trailer keys which will come later. In this case, those
- // keys of the Header map are treated as if they were
- // trailers. See the example. The second way, for trailer
- // keys not known to the Handler until after the first Write,
- // is to prefix the Header map keys with the TrailerPrefix
- // constant value. See TrailerPrefix.
- //
- // To suppress automatic response headers (such as "Date"), set
- // their value to nil.
- Header() Header
-
- // Write writes the data to the connection as part of an HTTP reply.
- //
- // If WriteHeader has not yet been called, Write calls
- // WriteHeader(http.StatusOK) before writing the data. If the Header
- // does not contain a Content-Type line, Write adds a Content-Type set
- // to the result of passing the initial 512 bytes of written data to
- // DetectContentType. Additionally, if the total size of all written
- // data is under a few KB and there are no Flush calls, the
- // Content-Length header is added automatically.
- //
- // Depending on the HTTP protocol version and the client, calling
- // Write or WriteHeader may prevent future reads on the
- // Request.Body. For HTTP/1.x requests, handlers should read any
- // needed request body data before writing the response. Once the
- // headers have been flushed (due to either an explicit Flusher.Flush
- // call or writing enough data to trigger a flush), the request body
- // may be unavailable. For HTTP/2 requests, the Go HTTP server permits
- // handlers to continue to read the request body while concurrently
- // writing the response. However, such behavior may not be supported
- // by all HTTP/2 clients. Handlers should read before writing if
- // possible to maximize compatibility.
- Write([]byte) (int, error)
-
- // WriteHeader sends an HTTP response header with the provided
- // status code.
- //
- // If WriteHeader is not called explicitly, the first call to Write
- // will trigger an implicit WriteHeader(http.StatusOK).
- // Thus explicit calls to WriteHeader are mainly used to
- // send error codes or 1xx informational responses.
- //
- // The provided code must be a valid HTTP 1xx-5xx status code.
- // Any number of 1xx headers may be written, followed by at most
- // one 2xx-5xx header. 1xx headers are sent immediately, but 2xx-5xx
- // headers may be buffered. Use the Flusher interface to send
- // buffered data. The header map is cleared when 2xx-5xx headers are
- // sent, but not with 1xx headers.
- //
- // The server will automatically send a 100 (Continue) header
- // on the first read from the request body if the request has
- // an "Expect: 100-continue" header.
- WriteHeader(statusCode int)
-}
-
-// The Flusher interface is implemented by ResponseWriters that allow
-// an HTTP handler to flush buffered data to the client.
-//
-// The default HTTP/1.x and HTTP/2 ResponseWriter implementations
-// support Flusher, but ResponseWriter wrappers may not. Handlers
-// should always test for this ability at runtime.
-//
-// Note that even for ResponseWriters that support Flush,
-// if the client is connected through an HTTP proxy,
-// the buffered data may not reach the client until the response
-// completes.
-type Flusher interface {
- // Flush sends any buffered data to the client.
- Flush()
-}
-
-// The Hijacker interface is implemented by ResponseWriters that allow
-// an HTTP handler to take over the connection.
-//
-// The default ResponseWriter for HTTP/1.x connections supports
-// Hijacker, but HTTP/2 connections intentionally do not.
-// ResponseWriter wrappers may also not support Hijacker. Handlers
-// should always test for this ability at runtime.
-type Hijacker interface {
- // Hijack lets the caller take over the connection.
- // After a call to Hijack the HTTP server library
- // will not do anything else with the connection.
- //
- // It becomes the caller's responsibility to manage
- // and close the connection.
- //
- // The returned net.Conn may have read or write deadlines
- // already set, depending on the configuration of the
- // Server. It is the caller's responsibility to set
- // or clear those deadlines as needed.
- //
- // The returned bufio.Reader may contain unprocessed buffered
- // data from the client.
- //
- // After a call to Hijack, the original Request.Body must not
- // be used. The original Request's Context remains valid and
- // is not canceled until the Request's ServeHTTP method
- // returns.
- Hijack() (net.Conn, *bufio.ReadWriter, error)
-}
-
-// The CloseNotifier interface is implemented by ResponseWriters which
-// allow detecting when the underlying connection has gone away.
-//
-// This mechanism can be used to cancel long operations on the server
-// if the client has disconnected before the response is ready.
-//
-// Deprecated: the CloseNotifier interface predates Go's context package.
-// New code should use Request.Context instead.
-type CloseNotifier interface {
- // CloseNotify returns a channel that receives at most a
- // single value (true) when the client connection has gone
- // away.
- //
- // CloseNotify may wait to notify until Request.Body has been
- // fully read.
- //
- // After the Handler has returned, there is no guarantee
- // that the channel receives a value.
- //
- // If the protocol is HTTP/1.1 and CloseNotify is called while
- // processing an idempotent request (such a GET) while
- // HTTP/1.1 pipelining is in use, the arrival of a subsequent
- // pipelined request may cause a value to be sent on the
- // returned channel. In practice HTTP/1.1 pipelining is not
- // enabled in browsers and not seen often in the wild. If this
- // is a problem, use HTTP/2 or only use CloseNotify on methods
- // such as POST.
- CloseNotify() <-chan bool
-}
-
-var (
- // ServerContextKey is a context key. It can be used in HTTP
- // handlers with Context.Value to access the server that
- // started the handler. The associated value will be of
- // type *Server.
- ServerContextKey = &contextKey{"http-server"}
-
- // LocalAddrContextKey is a context key. It can be used in
- // HTTP handlers with Context.Value to access the local
- // address the connection arrived on.
- // The associated value will be of type net.Addr.
- LocalAddrContextKey = &contextKey{"local-addr"}
-)
-
-// A conn represents the server side of an HTTP connection.
-type conn struct {
- // server is the server on which the connection arrived.
- // Immutable; never nil.
- server *Server
-
- // cancelCtx cancels the connection-level context.
- cancelCtx context.CancelFunc
-
- // rwc is the underlying network connection.
- // This is never wrapped by other types and is the value given out
- // to CloseNotifier callers. It is usually of type *net.TCPConn or
- // *tls.Conn.
- rwc net.Conn
-
- // remoteAddr is rwc.RemoteAddr().String(). It is not populated synchronously
- // inside the Listener's Accept goroutine, as some implementations block.
- // It is populated immediately inside the (*conn).serve goroutine.
- // This is the value of a Handler's (*Request).RemoteAddr.
- remoteAddr string
-
- // tlsState is the TLS connection state when using TLS.
- // nil means not TLS.
- tlsState *tls.ConnectionState
-
- // werr is set to the first write error to rwc.
- // It is set via checkConnErrorWriter{w}, where bufw writes.
- werr error
-
- // r is bufr's read source. It's a wrapper around rwc that provides
- // io.LimitedReader-style limiting (while reading request headers)
- // and functionality to support CloseNotifier. See *connReader docs.
- r *connReader
-
- // bufr reads from r.
- bufr *bufio.Reader
-
- // bufw writes to checkConnErrorWriter{c}, which populates werr on error.
- bufw *bufio.Writer
-
- // lastMethod is the method of the most recent request
- // on this connection, if any.
- lastMethod string
-
- curReq atomic.Pointer[response] // (which has a Request in it)
-
- curState atomic.Uint64 // packed (unixtime<<8|uint8(ConnState))
-
- // mu guards hijackedv
- mu sync.Mutex
-
- // hijackedv is whether this connection has been hijacked
- // by a Handler with the Hijacker interface.
- // It is guarded by mu.
- hijackedv bool
-}
-
-func (c *conn) hijacked() bool {
- c.mu.Lock()
- defer c.mu.Unlock()
- return c.hijackedv
-}
-
-// c.mu must be held.
-func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
- if c.hijackedv {
- return nil, nil, ErrHijacked
- }
- c.r.abortPendingRead()
-
- c.hijackedv = true
- rwc = c.rwc
- rwc.SetDeadline(time.Time{})
-
- buf = bufio.NewReadWriter(c.bufr, bufio.NewWriter(rwc))
- if c.r.hasByte {
- if _, err := c.bufr.Peek(c.bufr.Buffered() + 1); err != nil {
- return nil, nil, fmt.Errorf("unexpected Peek failure reading buffered byte: %v", err)
- }
- }
- c.setState(rwc, StateHijacked, runHooks)
- return
-}
-
-// This should be >= 512 bytes for DetectContentType,
-// but otherwise it's somewhat arbitrary.
-const bufferBeforeChunkingSize = 2048
-
-// chunkWriter writes to a response's conn buffer, and is the writer
-// wrapped by the response.w buffered writer.
-//
-// chunkWriter also is responsible for finalizing the Header, including
-// conditionally setting the Content-Type and setting a Content-Length
-// in cases where the handler's final output is smaller than the buffer
-// size. It also conditionally adds chunk headers, when in chunking mode.
-//
-// See the comment above (*response).Write for the entire write flow.
-type chunkWriter struct {
- res *response
-
- // header is either nil or a deep clone of res.handlerHeader
- // at the time of res.writeHeader, if res.writeHeader is
- // called and extra buffering is being done to calculate
- // Content-Type and/or Content-Length.
- header Header
-
- // wroteHeader tells whether the header's been written to "the
- // wire" (or rather: w.conn.buf). this is unlike
- // (*response).wroteHeader, which tells only whether it was
- // logically written.
- wroteHeader bool
-
- // set by the writeHeader method:
- chunking bool // using chunked transfer encoding for reply body
-}
-
-var (
- crlf = []byte("\r\n")
- colonSpace = []byte(": ")
-)
-
-func (cw *chunkWriter) Write(p []byte) (n int, err error) {
- if !cw.wroteHeader {
- cw.writeHeader(p)
- }
- if cw.res.req.Method == "HEAD" {
- // Eat writes.
- return len(p), nil
- }
- if cw.chunking {
- _, err = fmt.Fprintf(cw.res.conn.bufw, "%x\r\n", len(p))
- if err != nil {
- cw.res.conn.rwc.Close()
- return
- }
- }
- n, err = cw.res.conn.bufw.Write(p)
- if cw.chunking && err == nil {
- _, err = cw.res.conn.bufw.Write(crlf)
- }
- if err != nil {
- cw.res.conn.rwc.Close()
- }
- return
-}
-
-func (cw *chunkWriter) flush() error {
- if !cw.wroteHeader {
- cw.writeHeader(nil)
- }
- return cw.res.conn.bufw.Flush()
-}
-
-func (cw *chunkWriter) close() {
- if !cw.wroteHeader {
- cw.writeHeader(nil)
- }
- if cw.chunking {
- bw := cw.res.conn.bufw // conn's bufio writer
- // zero chunk to mark EOF
- bw.WriteString("0\r\n")
- if trailers := cw.res.finalTrailers(); trailers != nil {
- trailers.Write(bw) // the writer handles noting errors
- }
- // final blank line after the trailers (whether
- // present or not)
- bw.WriteString("\r\n")
- }
-}
-
-// A response represents the server side of an HTTP response.
-type response struct {
- conn *conn
- req *Request // request for this response
- reqBody io.ReadCloser
- cancelCtx context.CancelFunc // when ServeHTTP exits
- wroteHeader bool // a non-1xx header has been (logically) written
- wroteContinue bool // 100 Continue response was written
- wants10KeepAlive bool // HTTP/1.0 w/ Connection "keep-alive"
- wantsClose bool // HTTP request has Connection "close"
-
- // canWriteContinue is an atomic boolean that says whether or
- // not a 100 Continue header can be written to the
- // connection.
- // writeContinueMu must be held while writing the header.
- // These two fields together synchronize the body reader (the
- // expectContinueReader, which wants to write 100 Continue)
- // against the main writer.
- canWriteContinue atomic.Bool
- writeContinueMu sync.Mutex
-
- w *bufio.Writer // buffers output in chunks to chunkWriter
- cw chunkWriter
-
- // handlerHeader is the Header that Handlers get access to,
- // which may be retained and mutated even after WriteHeader.
- // handlerHeader is copied into cw.header at WriteHeader
- // time, and privately mutated thereafter.
- handlerHeader Header
- calledHeader bool // handler accessed handlerHeader via Header
-
- written int64 // number of bytes written in body
- contentLength int64 // explicitly-declared Content-Length; or -1
- status int // status code passed to WriteHeader
-
- // close connection after this reply. set on request and
- // updated after response from handler if there's a
- // "Connection: keep-alive" response header and a
- // Content-Length.
- closeAfterReply bool
-
- // requestBodyLimitHit is set by requestTooLarge when
- // maxBytesReader hits its max size. It is checked in
- // WriteHeader, to make sure we don't consume the
- // remaining request body to try to advance to the next HTTP
- // request. Instead, when this is set, we stop reading
- // subsequent requests on this connection and stop reading
- // input from it.
- requestBodyLimitHit bool
-
- // trailers are the headers to be sent after the handler
- // finishes writing the body. This field is initialized from
- // the Trailer response header when the response header is
- // written.
- trailers []string
-
- handlerDone atomic.Bool // set true when the handler exits
-
- // Buffers for Date, Content-Length, and status code
- dateBuf [len(TimeFormat)]byte
- clenBuf [10]byte
- statusBuf [3]byte
-
- // closeNotifyCh is the channel returned by CloseNotify.
- // TODO(bradfitz): this is currently (for Go 1.8) always
- // non-nil. Make this lazily-created again as it used to be?
- closeNotifyCh chan bool
- didCloseNotify atomic.Bool // atomic (only false->true winner should send)
-}
-
-func (c *response) SetReadDeadline(deadline time.Time) error {
- return c.conn.rwc.SetReadDeadline(deadline)
-}
-
-func (c *response) SetWriteDeadline(deadline time.Time) error {
- return c.conn.rwc.SetWriteDeadline(deadline)
-}
-
-// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
-// that, if present, signals that the map entry is actually for
-// the response trailers, and not the response headers. The prefix
-// is stripped after the ServeHTTP call finishes and the values are
-// sent in the trailers.
-//
-// This mechanism is intended only for trailers that are not known
-// prior to the headers being written. If the set of trailers is fixed
-// or known before the header is written, the normal Go trailers mechanism
-// is preferred:
-//
-// https://pkg.go.dev/net/http#ResponseWriter
-// https://pkg.go.dev/net/http#example-ResponseWriter-Trailers
-const TrailerPrefix = "Trailer:"
-
-// finalTrailers is called after the Handler exits and returns a non-nil
-// value if the Handler set any trailers.
-func (w *response) finalTrailers() Header {
- var t Header
- for k, vv := range w.handlerHeader {
- if kk, found := strings.CutPrefix(k, TrailerPrefix); found {
- if t == nil {
- t = make(Header)
- }
- t[kk] = vv
- }
- }
- for _, k := range w.trailers {
- if t == nil {
- t = make(Header)
- }
- for _, v := range w.handlerHeader[k] {
- t.Add(k, v)
- }
- }
- return t
-}
-
-// declareTrailer is called for each Trailer header when the
-// response header is written. It notes that a header will need to be
-// written in the trailers at the end of the response.
-func (w *response) declareTrailer(k string) {
- k = CanonicalHeaderKey(k)
- if !httpguts.ValidTrailerHeader(k) {
- // Forbidden by RFC 7230, section 4.1.2
- return
- }
- w.trailers = append(w.trailers, k)
-}
-
-// requestTooLarge is called by maxBytesReader when too much input has
-// been read from the client.
-func (w *response) requestTooLarge() {
- w.closeAfterReply = true
- w.requestBodyLimitHit = true
- if !w.wroteHeader {
- w.Header().Set("Connection", "close")
- }
-}
-
-// writerOnly hides an io.Writer value's optional ReadFrom method
-// from io.Copy.
-type writerOnly struct {
- io.Writer
-}
-
-// ReadFrom is here to optimize copying from an *os.File regular file
-// to a *net.TCPConn with sendfile, or from a supported src type such
-// as a *net.TCPConn on Linux with splice.
-func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
- bufp := copyBufPool.Get().(*[]byte)
- buf := *bufp
- defer copyBufPool.Put(bufp)
-
- // Our underlying w.conn.rwc is usually a *TCPConn (with its
- // own ReadFrom method). If not, just fall back to the normal
- // copy method.
- rf, ok := w.conn.rwc.(io.ReaderFrom)
- if !ok {
- return io.CopyBuffer(writerOnly{w}, src, buf)
- }
-
- // Copy the first sniffLen bytes before switching to ReadFrom.
- // This ensures we don't start writing the response before the
- // source is available (see golang.org/issue/5660) and provides
- // enough bytes to perform Content-Type sniffing when required.
- if !w.cw.wroteHeader {
- n0, err := io.CopyBuffer(writerOnly{w}, io.LimitReader(src, sniffLen), buf)
- n += n0
- if err != nil || n0 < sniffLen {
- return n, err
- }
- }
-
- w.w.Flush() // get rid of any previous writes
- w.cw.flush() // make sure Header is written; flush data to rwc
-
- // Now that cw has been flushed, its chunking field is guaranteed initialized.
- if !w.cw.chunking && w.bodyAllowed() {
- n0, err := rf.ReadFrom(src)
- n += n0
- w.written += n0
- return n, err
- }
-
- n0, err := io.CopyBuffer(writerOnly{w}, src, buf)
- n += n0
- return n, err
-}
-
-// debugServerConnections controls whether all server connections are wrapped
-// with a verbose logging wrapper.
-const debugServerConnections = false
-
-// Create new connection from rwc.
-func (srv *Server) newConn(rwc net.Conn) *conn {
- c := &conn{
- server: srv,
- rwc: rwc,
- }
- if debugServerConnections {
- c.rwc = newLoggingConn("server", c.rwc)
- }
- return c
-}
-
-type readResult struct {
- _ incomparable
- n int
- err error
- b byte // byte read, if n == 1
-}
-
-// connReader is the io.Reader wrapper used by *conn. It combines a
-// selectively-activated io.LimitedReader (to bound request header
-// read sizes) with support for selectively keeping an io.Reader.Read
-// call blocked in a background goroutine to wait for activity and
-// trigger a CloseNotifier channel.
-type connReader struct {
- conn *conn
-
- mu sync.Mutex // guards following
- hasByte bool
- byteBuf [1]byte
- cond *sync.Cond
- inRead bool
- aborted bool // set true before conn.rwc deadline is set to past
- remain int64 // bytes remaining
-}
-
-func (cr *connReader) lock() {
- cr.mu.Lock()
- if cr.cond == nil {
- cr.cond = sync.NewCond(&cr.mu)
- }
-}
-
-func (cr *connReader) unlock() { cr.mu.Unlock() }
-
-func (cr *connReader) startBackgroundRead() {
- cr.lock()
- defer cr.unlock()
- if cr.inRead {
- panic("invalid concurrent Body.Read call")
- }
- if cr.hasByte {
- return
- }
- cr.inRead = true
- cr.conn.rwc.SetReadDeadline(time.Time{})
- go cr.backgroundRead()
-}
-
-func (cr *connReader) backgroundRead() {
- n, err := cr.conn.rwc.Read(cr.byteBuf[:])
- cr.lock()
- if n == 1 {
- cr.hasByte = true
- // We were past the end of the previous request's body already
- // (since we wouldn't be in a background read otherwise), so
- // this is a pipelined HTTP request. Prior to Go 1.11 we used to
- // send on the CloseNotify channel and cancel the context here,
- // but the behavior was documented as only "may", and we only
- // did that because that's how CloseNotify accidentally behaved
- // in very early Go releases prior to context support. Once we
- // added context support, people used a Handler's
- // Request.Context() and passed it along. Having that context
- // cancel on pipelined HTTP requests caused problems.
- // Fortunately, almost nothing uses HTTP/1.x pipelining.
- // Unfortunately, apt-get does, or sometimes does.
- // New Go 1.11 behavior: don't fire CloseNotify or cancel
- // contexts on pipelined requests. Shouldn't affect people, but
- // fixes cases like Issue 23921. This does mean that a client
- // closing their TCP connection after sending a pipelined
- // request won't cancel the context, but we'll catch that on any
- // write failure (in checkConnErrorWriter.Write).
- // If the server never writes, yes, there are still contrived
- // server & client behaviors where this fails to ever cancel the
- // context, but that's kinda why HTTP/1.x pipelining died
- // anyway.
- }
- if ne, ok := err.(net.Error); ok && cr.aborted && ne.Timeout() {
- // Ignore this error. It's the expected error from
- // another goroutine calling abortPendingRead.
- } else if err != nil {
- cr.handleReadError(err)
- }
- cr.aborted = false
- cr.inRead = false
- cr.unlock()
- cr.cond.Broadcast()
-}
-
-func (cr *connReader) abortPendingRead() {
- cr.lock()
- defer cr.unlock()
- if !cr.inRead {
- return
- }
- cr.aborted = true
- cr.conn.rwc.SetReadDeadline(aLongTimeAgo)
- for cr.inRead {
- cr.cond.Wait()
- }
- cr.conn.rwc.SetReadDeadline(time.Time{})
-}
-
-func (cr *connReader) setReadLimit(remain int64) { cr.remain = remain }
-func (cr *connReader) setInfiniteReadLimit() { cr.remain = maxInt64 }
-func (cr *connReader) hitReadLimit() bool { return cr.remain <= 0 }
-
-// handleReadError is called whenever a Read from the client returns a
-// non-nil error.
-//
-// The provided non-nil err is almost always io.EOF or a "use of
-// closed network connection". In any case, the error is not
-// particularly interesting, except perhaps for debugging during
-// development. Any error means the connection is dead and we should
-// down its context.
-//
-// It may be called from multiple goroutines.
-func (cr *connReader) handleReadError(_ error) {
- cr.conn.cancelCtx()
- cr.closeNotify()
-}
-
-// may be called from multiple goroutines.
-func (cr *connReader) closeNotify() {
- res := cr.conn.curReq.Load()
- if res != nil && !res.didCloseNotify.Swap(true) {
- res.closeNotifyCh <- true
- }
-}
-
-func (cr *connReader) Read(p []byte) (n int, err error) {
- cr.lock()
- if cr.inRead {
- cr.unlock()
- if cr.conn.hijacked() {
- panic("invalid Body.Read call. After hijacked, the original Request must not be used")
- }
- panic("invalid concurrent Body.Read call")
- }
- if cr.hitReadLimit() {
- cr.unlock()
- return 0, io.EOF
- }
- if len(p) == 0 {
- cr.unlock()
- return 0, nil
- }
- if int64(len(p)) > cr.remain {
- p = p[:cr.remain]
- }
- if cr.hasByte {
- p[0] = cr.byteBuf[0]
- cr.hasByte = false
- cr.unlock()
- return 1, nil
- }
- cr.inRead = true
- cr.unlock()
- n, err = cr.conn.rwc.Read(p)
-
- cr.lock()
- cr.inRead = false
- if err != nil {
- cr.handleReadError(err)
- }
- cr.remain -= int64(n)
- cr.unlock()
-
- cr.cond.Broadcast()
- return n, err
-}
-
-var (
- bufioReaderPool sync.Pool
- bufioWriter2kPool sync.Pool
- bufioWriter4kPool sync.Pool
-)
-
-var copyBufPool = sync.Pool{
- New: func() any {
- b := make([]byte, 32*1024)
- return &b
- },
-}
-
-func bufioWriterPool(size int) *sync.Pool {
- switch size {
- case 2 << 10:
- return &bufioWriter2kPool
- case 4 << 10:
- return &bufioWriter4kPool
- }
- return nil
-}
-
-func newBufioReader(r io.Reader) *bufio.Reader {
- if v := bufioReaderPool.Get(); v != nil {
- br := v.(*bufio.Reader)
- br.Reset(r)
- return br
- }
- // Note: if this reader size is ever changed, update
- // TestHandlerBodyClose's assumptions.
- return bufio.NewReader(r)
-}
-
-func putBufioReader(br *bufio.Reader) {
- br.Reset(nil)
- bufioReaderPool.Put(br)
-}
-
-func newBufioWriterSize(w io.Writer, size int) *bufio.Writer {
- pool := bufioWriterPool(size)
- if pool != nil {
- if v := pool.Get(); v != nil {
- bw := v.(*bufio.Writer)
- bw.Reset(w)
- return bw
- }
- }
- return bufio.NewWriterSize(w, size)
-}
-
-func putBufioWriter(bw *bufio.Writer) {
- bw.Reset(nil)
- if pool := bufioWriterPool(bw.Available()); pool != nil {
- pool.Put(bw)
- }
-}
-
-// DefaultMaxHeaderBytes is the maximum permitted size of the headers
-// in an HTTP request.
-// This can be overridden by setting Server.MaxHeaderBytes.
-const DefaultMaxHeaderBytes = 1 << 20 // 1 MB
-
-func (srv *Server) maxHeaderBytes() int {
- if srv.MaxHeaderBytes > 0 {
- return srv.MaxHeaderBytes
- }
- return DefaultMaxHeaderBytes
-}
-
-func (srv *Server) initialReadLimitSize() int64 {
- return int64(srv.maxHeaderBytes()) + 4096 // bufio slop
-}
-
-// tlsHandshakeTimeout returns the time limit permitted for the TLS
-// handshake, or zero for unlimited.
-//
-// It returns the minimum of any positive ReadHeaderTimeout,
-// ReadTimeout, or WriteTimeout.
-func (srv *Server) tlsHandshakeTimeout() time.Duration {
- var ret time.Duration
- for _, v := range [...]time.Duration{
- srv.ReadHeaderTimeout,
- srv.ReadTimeout,
- srv.WriteTimeout,
- } {
- if v <= 0 {
- continue
- }
- if ret == 0 || v < ret {
- ret = v
- }
- }
- return ret
-}
-
-// wrapper around io.ReadCloser which on first read, sends an
-// HTTP/1.1 100 Continue header
-type expectContinueReader struct {
- resp *response
- readCloser io.ReadCloser
- closed atomic.Bool
- sawEOF atomic.Bool
-}
-
-func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
- if ecr.closed.Load() {
- return 0, ErrBodyReadAfterClose
- }
- w := ecr.resp
- if !w.wroteContinue && w.canWriteContinue.Load() && !w.conn.hijacked() {
- w.wroteContinue = true
- w.writeContinueMu.Lock()
- if w.canWriteContinue.Load() {
- w.conn.bufw.WriteString("HTTP/1.1 100 Continue\r\n\r\n")
- w.conn.bufw.Flush()
- w.canWriteContinue.Store(false)
- }
- w.writeContinueMu.Unlock()
- }
- n, err = ecr.readCloser.Read(p)
- if err == io.EOF {
- ecr.sawEOF.Store(true)
- }
- return
-}
-
-func (ecr *expectContinueReader) Close() error {
- ecr.closed.Store(true)
- return ecr.readCloser.Close()
-}
-
-// TimeFormat is the time format to use when generating times in HTTP
-// headers. It is like time.RFC1123 but hard-codes GMT as the time
-// zone. The time being formatted must be in UTC for Format to
-// generate the correct format.
-//
-// For parsing this time format, see ParseTime.
-const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
-
-// appendTime is a non-allocating version of []byte(t.UTC().Format(TimeFormat))
-func appendTime(b []byte, t time.Time) []byte {
- const days = "SunMonTueWedThuFriSat"
- const months = "JanFebMarAprMayJunJulAugSepOctNovDec"
-
- t = t.UTC()
- yy, mm, dd := t.Date()
- hh, mn, ss := t.Clock()
- day := days[3*t.Weekday():]
- mon := months[3*(mm-1):]
-
- return append(b,
- day[0], day[1], day[2], ',', ' ',
- byte('0'+dd/10), byte('0'+dd%10), ' ',
- mon[0], mon[1], mon[2], ' ',
- byte('0'+yy/1000), byte('0'+(yy/100)%10), byte('0'+(yy/10)%10), byte('0'+yy%10), ' ',
- byte('0'+hh/10), byte('0'+hh%10), ':',
- byte('0'+mn/10), byte('0'+mn%10), ':',
- byte('0'+ss/10), byte('0'+ss%10), ' ',
- 'G', 'M', 'T')
-}
-
-var errTooLarge = errors.New("http: request too large")
-
-// Read next request from connection.
-func (c *conn) readRequest(ctx context.Context) (w *response, err error) {
- if c.hijacked() {
- return nil, ErrHijacked
- }
-
- var (
- wholeReqDeadline time.Time // or zero if none
- hdrDeadline time.Time // or zero if none
- )
- t0 := time.Now()
- if d := c.server.readHeaderTimeout(); d > 0 {
- hdrDeadline = t0.Add(d)
- }
- if d := c.server.ReadTimeout; d > 0 {
- wholeReqDeadline = t0.Add(d)
- }
- c.rwc.SetReadDeadline(hdrDeadline)
- if d := c.server.WriteTimeout; d > 0 {
- defer func() {
- c.rwc.SetWriteDeadline(time.Now().Add(d))
- }()
- }
-
- c.r.setReadLimit(c.server.initialReadLimitSize())
- if c.lastMethod == "POST" {
- // RFC 7230 section 3 tolerance for old buggy clients.
- peek, _ := c.bufr.Peek(4) // ReadRequest will get err below
- c.bufr.Discard(numLeadingCRorLF(peek))
- }
- req, err := readRequest(c.bufr)
- if err != nil {
- if c.r.hitReadLimit() {
- return nil, errTooLarge
- }
- return nil, err
- }
-
- if !http1ServerSupportsRequest(req) {
- return nil, statusError{StatusHTTPVersionNotSupported, "unsupported protocol version"}
- }
-
- c.lastMethod = req.Method
- c.r.setInfiniteReadLimit()
-
- hosts, haveHost := req.Header["Host"]
- isH2Upgrade := req.isH2Upgrade()
- if req.ProtoAtLeast(1, 1) && (!haveHost || len(hosts) == 0) && !isH2Upgrade && req.Method != "CONNECT" {
- return nil, badRequestError("missing required Host header")
- }
- if len(hosts) == 1 && !httpguts.ValidHostHeader(hosts[0]) {
- return nil, badRequestError("malformed Host header")
- }
- for k, vv := range req.Header {
- if !httpguts.ValidHeaderFieldName(k) {
- return nil, badRequestError("invalid header name")
- }
- for _, v := range vv {
- if !httpguts.ValidHeaderFieldValue(v) {
- return nil, badRequestError("invalid header value")
- }
- }
- }
- delete(req.Header, "Host")
-
- ctx, cancelCtx := context.WithCancel(ctx)
- req.ctx = ctx
- req.RemoteAddr = c.remoteAddr
- req.TLS = c.tlsState
- if body, ok := req.Body.(*body); ok {
- body.doEarlyClose = true
- }
-
- // Adjust the read deadline if necessary.
- if !hdrDeadline.Equal(wholeReqDeadline) {
- c.rwc.SetReadDeadline(wholeReqDeadline)
- }
-
- w = &response{
- conn: c,
- cancelCtx: cancelCtx,
- req: req,
- reqBody: req.Body,
- handlerHeader: make(Header),
- contentLength: -1,
- closeNotifyCh: make(chan bool, 1),
-
- // We populate these ahead of time so we're not
- // reading from req.Header after their Handler starts
- // and maybe mutates it (Issue 14940)
- wants10KeepAlive: req.wantsHttp10KeepAlive(),
- wantsClose: req.wantsClose(),
- }
- if isH2Upgrade {
- w.closeAfterReply = true
- }
- w.cw.res = w
- w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize)
- return w, nil
-}
-
-// http1ServerSupportsRequest reports whether Go's HTTP/1.x server
-// supports the given request.
-func http1ServerSupportsRequest(req *Request) bool {
- if req.ProtoMajor == 1 {
- return true
- }
- // Accept "PRI * HTTP/2.0" upgrade requests, so Handlers can
- // wire up their own HTTP/2 upgrades.
- if req.ProtoMajor == 2 && req.ProtoMinor == 0 &&
- req.Method == "PRI" && req.RequestURI == "*" {
- return true
- }
- // Reject HTTP/0.x, and all other HTTP/2+ requests (which
- // aren't encoded in ASCII anyway).
- return false
-}
-
-func (w *response) Header() Header {
- if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {
- // Accessing the header between logically writing it
- // and physically writing it means we need to allocate
- // a clone to snapshot the logically written state.
- w.cw.header = w.handlerHeader.Clone()
- }
- w.calledHeader = true
- return w.handlerHeader
-}
-
-// maxPostHandlerReadBytes is the max number of Request.Body bytes not
-// consumed by a handler that the server will read from the client
-// in order to keep a connection alive. If there are more bytes than
-// this then the server to be paranoid instead sends a "Connection:
-// close" response.
-//
-// This number is approximately what a typical machine's TCP buffer
-// size is anyway. (if we have the bytes on the machine, we might as
-// well read them)
-const maxPostHandlerReadBytes = 256 << 10
-
-func checkWriteHeaderCode(code int) {
- // Issue 22880: require valid WriteHeader status codes.
- // For now we only enforce that it's three digits.
- // In the future we might block things over 599 (600 and above aren't defined
- // at https://httpwg.org/specs/rfc7231.html#status.codes).
- // But for now any three digits.
- //
- // We used to send "HTTP/1.1 000 0" on the wire in responses but there's
- // no equivalent bogus thing we can realistically send in HTTP/2,
- // so we'll consistently panic instead and help people find their bugs
- // early. (We can't return an error from WriteHeader even if we wanted to.)
- if code < 100 || code > 999 {
- panic(fmt.Sprintf("invalid WriteHeader code %v", code))
- }
-}
-
-// relevantCaller searches the call stack for the first function outside of net/http.
-// The purpose of this function is to provide more helpful error messages.
-func relevantCaller() runtime.Frame {
- pc := make([]uintptr, 16)
- n := runtime.Callers(1, pc)
- frames := runtime.CallersFrames(pc[:n])
- var frame runtime.Frame
- for {
- frame, more := frames.Next()
- if !strings.HasPrefix(frame.Function, "net/http.") {
- return frame
- }
- if !more {
- break
- }
- }
- return frame
-}
-
-func (w *response) WriteHeader(code int) {
- if w.conn.hijacked() {
- caller := relevantCaller()
- w.conn.server.logf("http: response.WriteHeader on hijacked connection from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
- return
- }
- if w.wroteHeader {
- caller := relevantCaller()
- w.conn.server.logf("http: superfluous response.WriteHeader call from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
- return
- }
- checkWriteHeaderCode(code)
-
- // Handle informational headers
- if code >= 100 && code <= 199 {
- // Prevent a potential race with an automatically-sent 100 Continue triggered by Request.Body.Read()
- if code == 100 && w.canWriteContinue.Load() {
- w.writeContinueMu.Lock()
- w.canWriteContinue.Store(false)
- w.writeContinueMu.Unlock()
- }
-
- writeStatusLine(w.conn.bufw, w.req.ProtoAtLeast(1, 1), code, w.statusBuf[:])
-
- // Per RFC 8297 we must not clear the current header map
- w.handlerHeader.WriteSubset(w.conn.bufw, excludedHeadersNoBody)
- w.conn.bufw.Write(crlf)
- w.conn.bufw.Flush()
-
- return
- }
-
- w.wroteHeader = true
- w.status = code
-
- if w.calledHeader && w.cw.header == nil {
- w.cw.header = w.handlerHeader.Clone()
- }
-
- if cl := w.handlerHeader.get("Content-Length"); cl != "" {
- v, err := strconv.ParseInt(cl, 10, 64)
- if err == nil && v >= 0 {
- w.contentLength = v
- } else {
- w.conn.server.logf("http: invalid Content-Length of %q", cl)
- w.handlerHeader.Del("Content-Length")
- }
- }
-}
-
-// extraHeader is the set of headers sometimes added by chunkWriter.writeHeader.
-// This type is used to avoid extra allocations from cloning and/or populating
-// the response Header map and all its 1-element slices.
-type extraHeader struct {
- contentType string
- connection string
- transferEncoding string
- date []byte // written if not nil
- contentLength []byte // written if not nil
-}
-
-// Sorted the same as extraHeader.Write's loop.
-var extraHeaderKeys = [][]byte{
- []byte("Content-Type"),
- []byte("Connection"),
- []byte("Transfer-Encoding"),
-}
-
-var (
- headerContentLength = []byte("Content-Length: ")
- headerDate = []byte("Date: ")
-)
-
-// Write writes the headers described in h to w.
-//
-// This method has a value receiver, despite the somewhat large size
-// of h, because it prevents an allocation. The escape analysis isn't
-// smart enough to realize this function doesn't mutate h.
-func (h extraHeader) Write(w *bufio.Writer) {
- if h.date != nil {
- w.Write(headerDate)
- w.Write(h.date)
- w.Write(crlf)
- }
- if h.contentLength != nil {
- w.Write(headerContentLength)
- w.Write(h.contentLength)
- w.Write(crlf)
- }
- for i, v := range []string{h.contentType, h.connection, h.transferEncoding} {
- if v != "" {
- w.Write(extraHeaderKeys[i])
- w.Write(colonSpace)
- w.WriteString(v)
- w.Write(crlf)
- }
- }
-}
-
-// writeHeader finalizes the header sent to the client and writes it
-// to cw.res.conn.bufw.
-//
-// p is not written by writeHeader, but is the first chunk of the body
-// that will be written. It is sniffed for a Content-Type if none is
-// set explicitly. It's also used to set the Content-Length, if the
-// total body size was small and the handler has already finished
-// running.
-func (cw *chunkWriter) writeHeader(p []byte) {
- if cw.wroteHeader {
- return
- }
- cw.wroteHeader = true
-
- w := cw.res
- keepAlivesEnabled := w.conn.server.doKeepAlives()
- isHEAD := w.req.Method == "HEAD"
-
- // header is written out to w.conn.buf below. Depending on the
- // state of the handler, we either own the map or not. If we
- // don't own it, the exclude map is created lazily for
- // WriteSubset to remove headers. The setHeader struct holds
- // headers we need to add.
- header := cw.header
- owned := header != nil
- if !owned {
- header = w.handlerHeader
- }
- var excludeHeader map[string]bool
- delHeader := func(key string) {
- if owned {
- header.Del(key)
- return
- }
- if _, ok := header[key]; !ok {
- return
- }
- if excludeHeader == nil {
- excludeHeader = make(map[string]bool)
- }
- excludeHeader[key] = true
- }
- var setHeader extraHeader
-
- // Don't write out the fake "Trailer:foo" keys. See TrailerPrefix.
- trailers := false
- for k := range cw.header {
- if strings.HasPrefix(k, TrailerPrefix) {
- if excludeHeader == nil {
- excludeHeader = make(map[string]bool)
- }
- excludeHeader[k] = true
- trailers = true
- }
- }
- for _, v := range cw.header["Trailer"] {
- trailers = true
- foreachHeaderElement(v, cw.res.declareTrailer)
- }
-
- te := header.get("Transfer-Encoding")
- hasTE := te != ""
-
- // If the handler is done but never sent a Content-Length
- // response header and this is our first (and last) write, set
- // it, even to zero. This helps HTTP/1.0 clients keep their
- // "keep-alive" connections alive.
- // Exceptions: 304/204/1xx responses never get Content-Length, and if
- // it was a HEAD request, we don't know the difference between
- // 0 actual bytes and 0 bytes because the handler noticed it
- // was a HEAD request and chose not to write anything. So for
- // HEAD, the handler should either write the Content-Length or
- // write non-zero bytes. If it's actually 0 bytes and the
- // handler never looked at the Request.Method, we just don't
- // send a Content-Length header.
- // Further, we don't send an automatic Content-Length if they
- // set a Transfer-Encoding, because they're generally incompatible.
- if w.handlerDone.Load() && !trailers && !hasTE && bodyAllowedForStatus(w.status) && header.get("Content-Length") == "" && (!isHEAD || len(p) > 0) {
- w.contentLength = int64(len(p))
- setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)
- }
-
- // If this was an HTTP/1.0 request with keep-alive and we sent a
- // Content-Length back, we can make this a keep-alive response ...
- if w.wants10KeepAlive && keepAlivesEnabled {
- sentLength := header.get("Content-Length") != ""
- if sentLength && header.get("Connection") == "keep-alive" {
- w.closeAfterReply = false
- }
- }
-
- // Check for an explicit (and valid) Content-Length header.
- hasCL := w.contentLength != -1
-
- if w.wants10KeepAlive && (isHEAD || hasCL || !bodyAllowedForStatus(w.status)) {
- _, connectionHeaderSet := header["Connection"]
- if !connectionHeaderSet {
- setHeader.connection = "keep-alive"
- }
- } else if !w.req.ProtoAtLeast(1, 1) || w.wantsClose {
- w.closeAfterReply = true
- }
-
- if header.get("Connection") == "close" || !keepAlivesEnabled {
- w.closeAfterReply = true
- }
-
- // If the client wanted a 100-continue but we never sent it to
- // them (or, more strictly: we never finished reading their
- // request body), don't reuse this connection because it's now
- // in an unknown state: we might be sending this response at
- // the same time the client is now sending its request body
- // after a timeout. (Some HTTP clients send Expect:
- // 100-continue but knowing that some servers don't support
- // it, the clients set a timer and send the body later anyway)
- // If we haven't seen EOF, we can't skip over the unread body
- // because we don't know if the next bytes on the wire will be
- // the body-following-the-timer or the subsequent request.
- // See Issue 11549.
- if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF.Load() {
- w.closeAfterReply = true
- }
-
- // Per RFC 2616, we should consume the request body before
- // replying, if the handler hasn't already done so. But we
- // don't want to do an unbounded amount of reading here for
- // DoS reasons, so we only try up to a threshold.
- // TODO(bradfitz): where does RFC 2616 say that? See Issue 15527
- // about HTTP/1.x Handlers concurrently reading and writing, like
- // HTTP/2 handlers can do. Maybe this code should be relaxed?
- if w.req.ContentLength != 0 && !w.closeAfterReply {
- var discard, tooBig bool
-
- switch bdy := w.req.Body.(type) {
- case *expectContinueReader:
- if bdy.resp.wroteContinue {
- discard = true
- }
- case *body:
- bdy.mu.Lock()
- switch {
- case bdy.closed:
- if !bdy.sawEOF {
- // Body was closed in handler with non-EOF error.
- w.closeAfterReply = true
- }
- case bdy.unreadDataSizeLocked() >= maxPostHandlerReadBytes:
- tooBig = true
- default:
- discard = true
- }
- bdy.mu.Unlock()
- default:
- discard = true
- }
-
- if discard {
- _, err := io.CopyN(io.Discard, w.reqBody, maxPostHandlerReadBytes+1)
- switch err {
- case nil:
- // There must be even more data left over.
- tooBig = true
- case ErrBodyReadAfterClose:
- // Body was already consumed and closed.
- case io.EOF:
- // The remaining body was just consumed, close it.
- err = w.reqBody.Close()
- if err != nil {
- w.closeAfterReply = true
- }
- default:
- // Some other kind of error occurred, like a read timeout, or
- // corrupt chunked encoding. In any case, whatever remains
- // on the wire must not be parsed as another HTTP request.
- w.closeAfterReply = true
- }
- }
-
- if tooBig {
- w.requestTooLarge()
- delHeader("Connection")
- setHeader.connection = "close"
- }
- }
-
- code := w.status
- if bodyAllowedForStatus(code) {
- // If no content type, apply sniffing algorithm to body.
- _, haveType := header["Content-Type"]
-
- // If the Content-Encoding was set and is non-blank,
- // we shouldn't sniff the body. See Issue 31753.
- ce := header.Get("Content-Encoding")
- hasCE := len(ce) > 0
- if !hasCE && !haveType && !hasTE && len(p) > 0 {
- setHeader.contentType = DetectContentType(p)
- }
- } else {
- for _, k := range suppressedHeaders(code) {
- delHeader(k)
- }
- }
-
- if !header.has("Date") {
- setHeader.date = appendTime(cw.res.dateBuf[:0], time.Now())
- }
-
- if hasCL && hasTE && te != "identity" {
- // TODO: return an error if WriteHeader gets a return parameter
- // For now just ignore the Content-Length.
- w.conn.server.logf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d",
- te, w.contentLength)
- delHeader("Content-Length")
- hasCL = false
- }
-
- if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) || code == StatusNoContent {
- // Response has no body.
- delHeader("Transfer-Encoding")
- } else if hasCL {
- // Content-Length has been provided, so no chunking is to be done.
- delHeader("Transfer-Encoding")
- } else if w.req.ProtoAtLeast(1, 1) {
- // HTTP/1.1 or greater: Transfer-Encoding has been set to identity, and no
- // content-length has been provided. The connection must be closed after the
- // reply is written, and no chunking is to be done. This is the setup
- // recommended in the Server-Sent Events candidate recommendation 11,
- // section 8.
- if hasTE && te == "identity" {
- cw.chunking = false
- w.closeAfterReply = true
- delHeader("Transfer-Encoding")
- } else {
- // HTTP/1.1 or greater: use chunked transfer encoding
- // to avoid closing the connection at EOF.
- cw.chunking = true
- setHeader.transferEncoding = "chunked"
- if hasTE && te == "chunked" {
- // We will send the chunked Transfer-Encoding header later.
- delHeader("Transfer-Encoding")
- }
- }
- } else {
- // HTTP version < 1.1: cannot do chunked transfer
- // encoding and we don't know the Content-Length so
- // signal EOF by closing connection.
- w.closeAfterReply = true
- delHeader("Transfer-Encoding") // in case already set
- }
-
- // Cannot use Content-Length with non-identity Transfer-Encoding.
- if cw.chunking {
- delHeader("Content-Length")
- }
- if !w.req.ProtoAtLeast(1, 0) {
- return
- }
-
- // Only override the Connection header if it is not a successful
- // protocol switch response and if KeepAlives are not enabled.
- // See https://golang.org/issue/36381.
- delConnectionHeader := w.closeAfterReply &&
- (!keepAlivesEnabled || !hasToken(cw.header.get("Connection"), "close")) &&
- !isProtocolSwitchResponse(w.status, header)
- if delConnectionHeader {
- delHeader("Connection")
- if w.req.ProtoAtLeast(1, 1) {
- setHeader.connection = "close"
- }
- }
-
- writeStatusLine(w.conn.bufw, w.req.ProtoAtLeast(1, 1), code, w.statusBuf[:])
- cw.header.WriteSubset(w.conn.bufw, excludeHeader)
- setHeader.Write(w.conn.bufw)
- w.conn.bufw.Write(crlf)
-}
-
-// foreachHeaderElement splits v according to the "#rule" construction
-// in RFC 7230 section 7 and calls fn for each non-empty element.
-func foreachHeaderElement(v string, fn func(string)) {
- v = textproto.TrimString(v)
- if v == "" {
- return
- }
- if !strings.Contains(v, ",") {
- fn(v)
- return
- }
- for _, f := range strings.Split(v, ",") {
- if f = textproto.TrimString(f); f != "" {
- fn(f)
- }
- }
-}
-
-// writeStatusLine writes an HTTP/1.x Status-Line (RFC 7230 Section 3.1.2)
-// to bw. is11 is whether the HTTP request is HTTP/1.1. false means HTTP/1.0.
-// code is the response status code.
-// scratch is an optional scratch buffer. If it has at least capacity 3, it's used.
-func writeStatusLine(bw *bufio.Writer, is11 bool, code int, scratch []byte) {
- if is11 {
- bw.WriteString("HTTP/1.1 ")
- } else {
- bw.WriteString("HTTP/1.0 ")
- }
- if text := StatusText(code); text != "" {
- bw.Write(strconv.AppendInt(scratch[:0], int64(code), 10))
- bw.WriteByte(' ')
- bw.WriteString(text)
- bw.WriteString("\r\n")
- } else {
- // don't worry about performance
- fmt.Fprintf(bw, "%03d status code %d\r\n", code, code)
- }
-}
-
-// bodyAllowed reports whether a Write is allowed for this response type.
-// It's illegal to call this before the header has been flushed.
-func (w *response) bodyAllowed() bool {
- if !w.wroteHeader {
- panic("")
- }
- return bodyAllowedForStatus(w.status)
-}
-
-// The Life Of A Write is like this:
-//
-// Handler starts. No header has been sent. The handler can either
-// write a header, or just start writing. Writing before sending a header
-// sends an implicitly empty 200 OK header.
-//
-// If the handler didn't declare a Content-Length up front, we either
-// go into chunking mode or, if the handler finishes running before
-// the chunking buffer size, we compute a Content-Length and send that
-// in the header instead.
-//
-// Likewise, if the handler didn't set a Content-Type, we sniff that
-// from the initial chunk of output.
-//
-// The Writers are wired together like:
-//
-// 1. *response (the ResponseWriter) ->
-// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes ->
-// 3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type)
-// and which writes the chunk headers, if needed ->
-// 4. conn.bufw, a *bufio.Writer of default (4kB) bytes, writing to ->
-// 5. checkConnErrorWriter{c}, which notes any non-nil error on Write
-// and populates c.werr with it if so, but otherwise writes to ->
-// 6. the rwc, the net.Conn.
-//
-// TODO(bradfitz): short-circuit some of the buffering when the
-// initial header contains both a Content-Type and Content-Length.
-// Also short-circuit in (1) when the header's been sent and not in
-// chunking mode, writing directly to (4) instead, if (2) has no
-// buffered data. More generally, we could short-circuit from (1) to
-// (3) even in chunking mode if the write size from (1) is over some
-// threshold and nothing is in (2). The answer might be mostly making
-// bufferBeforeChunkingSize smaller and having bufio's fast-paths deal
-// with this instead.
-func (w *response) Write(data []byte) (n int, err error) {
- return w.write(len(data), data, "")
-}
-
-func (w *response) WriteString(data string) (n int, err error) {
- return w.write(len(data), nil, data)
-}
-
-// either dataB or dataS is non-zero.
-func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {
- if w.conn.hijacked() {
- if lenData > 0 {
- caller := relevantCaller()
- w.conn.server.logf("http: response.Write on hijacked connection from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
- }
- return 0, ErrHijacked
- }
-
- if w.canWriteContinue.Load() {
- // Body reader wants to write 100 Continue but hasn't yet.
- // Tell it not to. The store must be done while holding the lock
- // because the lock makes sure that there is not an active write
- // this very moment.
- w.writeContinueMu.Lock()
- w.canWriteContinue.Store(false)
- w.writeContinueMu.Unlock()
- }
-
- if !w.wroteHeader {
- w.WriteHeader(StatusOK)
- }
- if lenData == 0 {
- return 0, nil
- }
- if !w.bodyAllowed() {
- return 0, ErrBodyNotAllowed
- }
-
- w.written += int64(lenData) // ignoring errors, for errorKludge
- if w.contentLength != -1 && w.written > w.contentLength {
- return 0, ErrContentLength
- }
- if dataB != nil {
- return w.w.Write(dataB)
- } else {
- return w.w.WriteString(dataS)
- }
-}
-
-func (w *response) finishRequest() {
- w.handlerDone.Store(true)
-
- if !w.wroteHeader {
- w.WriteHeader(StatusOK)
- }
-
- w.w.Flush()
- putBufioWriter(w.w)
- w.cw.close()
- w.conn.bufw.Flush()
-
- w.conn.r.abortPendingRead()
-
- // Close the body (regardless of w.closeAfterReply) so we can
- // re-use its bufio.Reader later safely.
- w.reqBody.Close()
-
- if w.req.MultipartForm != nil {
- w.req.MultipartForm.RemoveAll()
- }
-}
-
-// shouldReuseConnection reports whether the underlying TCP connection can be reused.
-// It must only be called after the handler is done executing.
-func (w *response) shouldReuseConnection() bool {
- if w.closeAfterReply {
- // The request or something set while executing the
- // handler indicated we shouldn't reuse this
- // connection.
- return false
- }
-
- if w.req.Method != "HEAD" && w.contentLength != -1 && w.bodyAllowed() && w.contentLength != w.written {
- // Did not write enough. Avoid getting out of sync.
- return false
- }
-
- // There was some error writing to the underlying connection
- // during the request, so don't re-use this conn.
- if w.conn.werr != nil {
- return false
- }
-
- if w.closedRequestBodyEarly() {
- return false
- }
-
- return true
-}
-
-func (w *response) closedRequestBodyEarly() bool {
- body, ok := w.req.Body.(*body)
- return ok && body.didEarlyClose()
-}
-
-func (w *response) Flush() {
- w.FlushError()
-}
-
-func (w *response) FlushError() error {
- if !w.wroteHeader {
- w.WriteHeader(StatusOK)
- }
- err := w.w.Flush()
- e2 := w.cw.flush()
- if err == nil {
- err = e2
- }
- return err
-}
-
-func (c *conn) finalFlush() {
- if c.bufr != nil {
- // Steal the bufio.Reader (~4KB worth of memory) and its associated
- // reader for a future connection.
- putBufioReader(c.bufr)
- c.bufr = nil
- }
-
- if c.bufw != nil {
- c.bufw.Flush()
- // Steal the bufio.Writer (~4KB worth of memory) and its associated
- // writer for a future connection.
- putBufioWriter(c.bufw)
- c.bufw = nil
- }
-}
-
-// Close the connection.
-func (c *conn) close() {
- c.finalFlush()
- c.rwc.Close()
-}
-
-// rstAvoidanceDelay is the amount of time we sleep after closing the
-// write side of a TCP connection before closing the entire socket.
-// By sleeping, we increase the chances that the client sees our FIN
-// and processes its final data before they process the subsequent RST
-// from closing a connection with known unread data.
-// This RST seems to occur mostly on BSD systems. (And Windows?)
-// This timeout is somewhat arbitrary (~latency around the planet).
-const rstAvoidanceDelay = 500 * time.Millisecond
-
-type closeWriter interface {
- CloseWrite() error
-}
-
-var _ closeWriter = (*net.TCPConn)(nil)
-
-// closeWrite flushes any outstanding data and sends a FIN packet (if
-// client is connected via TCP), signaling that we're done. We then
-// pause for a bit, hoping the client processes it before any
-// subsequent RST.
-//
-// See https://golang.org/issue/3595
-func (c *conn) closeWriteAndWait() {
- c.finalFlush()
- if tcp, ok := c.rwc.(closeWriter); ok {
- tcp.CloseWrite()
- }
- time.Sleep(rstAvoidanceDelay)
-}
-
-// validNextProto reports whether the proto is a valid ALPN protocol name.
-// Everything is valid except the empty string and built-in protocol types,
-// so that those can't be overridden with alternate implementations.
-func validNextProto(proto string) bool {
- switch proto {
- case "", "http/1.1", "http/1.0":
- return false
- }
- return true
-}
-
-const (
- runHooks = true
- skipHooks = false
-)
-
-func (c *conn) setState(nc net.Conn, state ConnState, runHook bool) {
- srv := c.server
- switch state {
- case StateNew:
- srv.trackConn(c, true)
- case StateHijacked, StateClosed:
- srv.trackConn(c, false)
- }
- if state > 0xff || state < 0 {
- panic("internal error")
- }
- packedState := uint64(time.Now().Unix()<<8) | uint64(state)
- c.curState.Store(packedState)
- if !runHook {
- return
- }
- if hook := srv.ConnState; hook != nil {
- hook(nc, state)
- }
-}
-
-func (c *conn) getState() (state ConnState, unixSec int64) {
- packedState := c.curState.Load()
- return ConnState(packedState & 0xff), int64(packedState >> 8)
-}
-
-// badRequestError is a literal string (used by in the server in HTML,
-// unescaped) to tell the user why their request was bad. It should
-// be plain text without user info or other embedded errors.
-func badRequestError(e string) error { return statusError{StatusBadRequest, e} }
-
-// statusError is an error used to respond to a request with an HTTP status.
-// The text should be plain text without user info or other embedded errors.
-type statusError struct {
- code int
- text string
-}
-
-func (e statusError) Error() string { return StatusText(e.code) + ": " + e.text }
-
-// ErrAbortHandler is a sentinel panic value to abort a handler.
-// While any panic from ServeHTTP aborts the response to the client,
-// panicking with ErrAbortHandler also suppresses logging of a stack
-// trace to the server's error log.
-var ErrAbortHandler = errors.New("net/http: abort Handler")
-
-// isCommonNetReadError reports whether err is a common error
-// encountered during reading a request off the network when the
-// client has gone away or had its read fail somehow. This is used to
-// determine which logs are interesting enough to log about.
-func isCommonNetReadError(err error) bool {
- if err == io.EOF {
- return true
- }
- if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
- return true
- }
- if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
- return true
- }
- return false
-}
-
-// Serve a new connection.
-func (c *conn) serve(ctx context.Context) {
- c.remoteAddr = c.rwc.RemoteAddr().String()
- ctx = context.WithValue(ctx, LocalAddrContextKey, c.rwc.LocalAddr())
- var inFlightResponse *response
- defer func() {
- if err := recover(); err != nil && err != ErrAbortHandler {
- const size = 64 << 10
- buf := make([]byte, size)
- buf = buf[:runtime.Stack(buf, false)]
- c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
- }
- if inFlightResponse != nil {
- inFlightResponse.cancelCtx()
- }
- if !c.hijacked() {
- if inFlightResponse != nil {
- inFlightResponse.conn.r.abortPendingRead()
- inFlightResponse.reqBody.Close()
- }
- c.close()
- c.setState(c.rwc, StateClosed, runHooks)
- }
- }()
-
- if tlsConn, ok := c.rwc.(*tls.Conn); ok {
- tlsTO := c.server.tlsHandshakeTimeout()
- if tlsTO > 0 {
- dl := time.Now().Add(tlsTO)
- c.rwc.SetReadDeadline(dl)
- c.rwc.SetWriteDeadline(dl)
- }
- if err := tlsConn.HandshakeContext(ctx); err != nil {
- // If the handshake failed due to the client not speaking
- // TLS, assume they're speaking plaintext HTTP and write a
- // 400 response on the TLS conn's underlying net.Conn.
- if re, ok := err.(tls.RecordHeaderError); ok && re.Conn != nil && tlsRecordHeaderLooksLikeHTTP(re.RecordHeader) {
- io.WriteString(re.Conn, "HTTP/1.0 400 Bad Request\r\n\r\nClient sent an HTTP request to an HTTPS server.\n")
- re.Conn.Close()
- return
- }
- c.server.logf("http: TLS handshake error from %s: %v", c.rwc.RemoteAddr(), err)
- return
- }
- // Restore Conn-level deadlines.
- if tlsTO > 0 {
- c.rwc.SetReadDeadline(time.Time{})
- c.rwc.SetWriteDeadline(time.Time{})
- }
- c.tlsState = new(tls.ConnectionState)
- *c.tlsState = tlsConn.ConnectionState()
- if proto := c.tlsState.NegotiatedProtocol; validNextProto(proto) {
- if fn := c.server.TLSNextProto[proto]; fn != nil {
- h := initALPNRequest{ctx, tlsConn, serverHandler{c.server}}
- // Mark freshly created HTTP/2 as active and prevent any server state hooks
- // from being run on these connections. This prevents closeIdleConns from
- // closing such connections. See issue https://golang.org/issue/39776.
- c.setState(c.rwc, StateActive, skipHooks)
- fn(c.server, tlsConn, h)
- }
- return
- }
- }
-
- // HTTP/1.x from here on.
-
- ctx, cancelCtx := context.WithCancel(ctx)
- c.cancelCtx = cancelCtx
- defer cancelCtx()
-
- c.r = &connReader{conn: c}
- c.bufr = newBufioReader(c.r)
- c.bufw = newBufioWriterSize(checkConnErrorWriter{c}, 4<<10)
-
- for {
- w, err := c.readRequest(ctx)
- if c.r.remain != c.server.initialReadLimitSize() {
- // If we read any bytes off the wire, we're active.
- c.setState(c.rwc, StateActive, runHooks)
- }
- if err != nil {
- const errorHeaders = "\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: close\r\n\r\n"
-
- switch {
- case err == errTooLarge:
- // Their HTTP client may or may not be
- // able to read this if we're
- // responding to them and hanging up
- // while they're still writing their
- // request. Undefined behavior.
- const publicErr = "431 Request Header Fields Too Large"
- fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
- c.closeWriteAndWait()
- return
-
- case isUnsupportedTEError(err):
- // Respond as per RFC 7230 Section 3.3.1 which says,
- // A server that receives a request message with a
- // transfer coding it does not understand SHOULD
- // respond with 501 (Unimplemented).
- code := StatusNotImplemented
-
- // We purposefully aren't echoing back the transfer-encoding's value,
- // so as to mitigate the risk of cross side scripting by an attacker.
- fmt.Fprintf(c.rwc, "HTTP/1.1 %d %s%sUnsupported transfer encoding", code, StatusText(code), errorHeaders)
- return
-
- case isCommonNetReadError(err):
- return // don't reply
-
- default:
- if v, ok := err.(statusError); ok {
- fmt.Fprintf(c.rwc, "HTTP/1.1 %d %s: %s%s%d %s: %s", v.code, StatusText(v.code), v.text, errorHeaders, v.code, StatusText(v.code), v.text)
- return
- }
- publicErr := "400 Bad Request"
- fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
- return
- }
- }
-
- // Expect 100 Continue support
- req := w.req
- if req.expectsContinue() {
- if req.ProtoAtLeast(1, 1) && req.ContentLength != 0 {
- // Wrap the Body reader with one that replies on the connection
- req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
- w.canWriteContinue.Store(true)
- }
- } else if req.Header.get("Expect") != "" {
- w.sendExpectationFailed()
- return
- }
-
- c.curReq.Store(w)
-
- if requestBodyRemains(req.Body) {
- registerOnHitEOF(req.Body, w.conn.r.startBackgroundRead)
- } else {
- w.conn.r.startBackgroundRead()
- }
-
- // HTTP cannot have multiple simultaneous active requests.[*]
- // Until the server replies to this request, it can't read another,
- // so we might as well run the handler in this goroutine.
- // [*] Not strictly true: HTTP pipelining. We could let them all process
- // in parallel even if their responses need to be serialized.
- // But we're not going to implement HTTP pipelining because it
- // was never deployed in the wild and the answer is HTTP/2.
- inFlightResponse = w
- serverHandler{c.server}.ServeHTTP(w, w.req)
- inFlightResponse = nil
- w.cancelCtx()
- if c.hijacked() {
- return
- }
- w.finishRequest()
- c.rwc.SetWriteDeadline(time.Time{})
- if !w.shouldReuseConnection() {
- if w.requestBodyLimitHit || w.closedRequestBodyEarly() {
- c.closeWriteAndWait()
- }
- return
- }
- c.setState(c.rwc, StateIdle, runHooks)
- c.curReq.Store(nil)
-
- if !w.conn.server.doKeepAlives() {
- // We're in shutdown mode. We might've replied
- // to the user without "Connection: close" and
- // they might think they can send another
- // request, but such is life with HTTP/1.1.
- return
- }
-
- if d := c.server.idleTimeout(); d != 0 {
- c.rwc.SetReadDeadline(time.Now().Add(d))
- } else {
- c.rwc.SetReadDeadline(time.Time{})
- }
-
- // Wait for the connection to become readable again before trying to
- // read the next request. This prevents a ReadHeaderTimeout or
- // ReadTimeout from starting until the first bytes of the next request
- // have been received.
- if _, err := c.bufr.Peek(4); err != nil {
- return
- }
-
- c.rwc.SetReadDeadline(time.Time{})
- }
-}
-
-func (w *response) sendExpectationFailed() {
- // TODO(bradfitz): let ServeHTTP handlers handle
- // requests with non-standard expectation[s]? Seems
- // theoretical at best, and doesn't fit into the
- // current ServeHTTP model anyway. We'd need to
- // make the ResponseWriter an optional
- // "ExpectReplier" interface or something.
- //
- // For now we'll just obey RFC 7231 5.1.1 which says
- // "A server that receives an Expect field-value other
- // than 100-continue MAY respond with a 417 (Expectation
- // Failed) status code to indicate that the unexpected
- // expectation cannot be met."
- w.Header().Set("Connection", "close")
- w.WriteHeader(StatusExpectationFailed)
- w.finishRequest()
-}
-
-// Hijack implements the Hijacker.Hijack method. Our response is both a ResponseWriter
-// and a Hijacker.
-func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
- if w.handlerDone.Load() {
- panic("net/http: Hijack called after ServeHTTP finished")
- }
- if w.wroteHeader {
- w.cw.flush()
- }
-
- c := w.conn
- c.mu.Lock()
- defer c.mu.Unlock()
-
- // Release the bufioWriter that writes to the chunk writer, it is not
- // used after a connection has been hijacked.
- rwc, buf, err = c.hijackLocked()
- if err == nil {
- putBufioWriter(w.w)
- w.w = nil
- }
- return rwc, buf, err
-}
-
-func (w *response) CloseNotify() <-chan bool {
- if w.handlerDone.Load() {
- panic("net/http: CloseNotify called after ServeHTTP finished")
- }
- return w.closeNotifyCh
-}
-
-func registerOnHitEOF(rc io.ReadCloser, fn func()) {
- switch v := rc.(type) {
- case *expectContinueReader:
- registerOnHitEOF(v.readCloser, fn)
- case *body:
- v.registerOnHitEOF(fn)
- default:
- panic("unexpected type " + fmt.Sprintf("%T", rc))
- }
-}
-
-// requestBodyRemains reports whether future calls to Read
-// on rc might yield more data.
-func requestBodyRemains(rc io.ReadCloser) bool {
- if rc == NoBody {
- return false
- }
- switch v := rc.(type) {
- case *expectContinueReader:
- return requestBodyRemains(v.readCloser)
- case *body:
- return v.bodyRemains()
- default:
- panic("unexpected type " + fmt.Sprintf("%T", rc))
- }
-}
-
-// The HandlerFunc type is an adapter to allow the use of
-// ordinary functions as HTTP handlers. If f is a function
-// with the appropriate signature, HandlerFunc(f) is a
-// Handler that calls f.
-type HandlerFunc func(ResponseWriter, *Request)
-
-// ServeHTTP calls f(w, r).
-func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
- f(w, r)
-}
-
-// Helper handlers
-
-// Error replies to the request with the specified error message and HTTP code.
-// It does not otherwise end the request; the caller should ensure no further
-// writes are done to w.
-// The error message should be plain text.
-func Error(w ResponseWriter, error string, code int) {
- w.Header().Set("Content-Type", "text/plain; charset=utf-8")
- w.Header().Set("X-Content-Type-Options", "nosniff")
- w.WriteHeader(code)
- fmt.Fprintln(w, error)
-}
-
-// NotFound replies to the request with an HTTP 404 not found error.
-func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) }
-
-// NotFoundHandler returns a simple request handler
-// that replies to each request with a “404 page not found” reply.
-func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
-
-// StripPrefix returns a handler that serves HTTP requests by removing the
-// given prefix from the request URL's Path (and RawPath if set) and invoking
-// the handler h. StripPrefix handles a request for a path that doesn't begin
-// with prefix by replying with an HTTP 404 not found error. The prefix must
-// match exactly: if the prefix in the request contains escaped characters
-// the reply is also an HTTP 404 not found error.
-func StripPrefix(prefix string, h Handler) Handler {
- if prefix == "" {
- return h
- }
- return HandlerFunc(func(w ResponseWriter, r *Request) {
- p := strings.TrimPrefix(r.URL.Path, prefix)
- rp := strings.TrimPrefix(r.URL.RawPath, prefix)
- if len(p) < len(r.URL.Path) && (r.URL.RawPath == "" || len(rp) < len(r.URL.RawPath)) {
- r2 := new(Request)
- *r2 = *r
- r2.URL = new(url.URL)
- *r2.URL = *r.URL
- r2.URL.Path = p
- r2.URL.RawPath = rp
- h.ServeHTTP(w, r2)
- } else {
- NotFound(w, r)
- }
- })
-}
-
-// Redirect replies to the request with a redirect to url,
-// which may be a path relative to the request path.
-//
-// The provided code should be in the 3xx range and is usually
-// StatusMovedPermanently, StatusFound or StatusSeeOther.
-//
-// If the Content-Type header has not been set, Redirect sets it
-// to "text/html; charset=utf-8" and writes a small HTML body.
-// Setting the Content-Type header to any value, including nil,
-// disables that behavior.
-func Redirect(w ResponseWriter, r *Request, url string, code int) {
- if u, err := urlpkg.Parse(url); err == nil {
- // If url was relative, make its path absolute by
- // combining with request path.
- // The client would probably do this for us,
- // but doing it ourselves is more reliable.
- // See RFC 7231, section 7.1.2
- if u.Scheme == "" && u.Host == "" {
- oldpath := r.URL.Path
- if oldpath == "" { // should not happen, but avoid a crash if it does
- oldpath = "/"
- }
-
- // no leading http://server
- if url == "" || url[0] != '/' {
- // make relative path absolute
- olddir, _ := path.Split(oldpath)
- url = olddir + url
- }
-
- var query string
- if i := strings.Index(url, "?"); i != -1 {
- url, query = url[:i], url[i:]
- }
-
- // clean up but preserve trailing slash
- trailing := strings.HasSuffix(url, "/")
- url = path.Clean(url)
- if trailing && !strings.HasSuffix(url, "/") {
- url += "/"
- }
- url += query
- }
- }
-
- h := w.Header()
-
- // RFC 7231 notes that a short HTML body is usually included in
- // the response because older user agents may not understand 301/307.
- // Do it only if the request didn't already have a Content-Type header.
- _, hadCT := h["Content-Type"]
-
- h.Set("Location", hexEscapeNonASCII(url))
- if !hadCT && (r.Method == "GET" || r.Method == "HEAD") {
- h.Set("Content-Type", "text/html; charset=utf-8")
- }
- w.WriteHeader(code)
-
- // Shouldn't send the body for POST or HEAD; that leaves GET.
- if !hadCT && r.Method == "GET" {
- body := "<a href=\"" + htmlEscape(url) + "\">" + StatusText(code) + "</a>.\n"
- fmt.Fprintln(w, body)
- }
-}
-
-var htmlReplacer = strings.NewReplacer(
- "&", "&amp;",
- "<", "&lt;",
- ">", "&gt;",
- // "&#34;" is shorter than "&quot;".
- `"`, "&#34;",
- // "&#39;" is shorter than "&apos;" and apos was not in HTML until HTML5.
- "'", "&#39;",
-)
-
-func htmlEscape(s string) string {
- return htmlReplacer.Replace(s)
-}
-
-// Redirect to a fixed URL
-type redirectHandler struct {
- url string
- code int
-}
-
-func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
- Redirect(w, r, rh.url, rh.code)
-}
-
-// RedirectHandler returns a request handler that redirects
-// each request it receives to the given url using the given
-// status code.
-//
-// The provided code should be in the 3xx range and is usually
-// StatusMovedPermanently, StatusFound or StatusSeeOther.
-func RedirectHandler(url string, code int) Handler {
- return &redirectHandler{url, code}
-}
-
-// ServeMux is an HTTP request multiplexer.
-// It matches the URL of each incoming request against a list of registered
-// patterns and calls the handler for the pattern that
-// most closely matches the URL.
-//
-// Patterns name fixed, rooted paths, like "/favicon.ico",
-// or rooted subtrees, like "/images/" (note the trailing slash).
-// Longer patterns take precedence over shorter ones, so that
-// if there are handlers registered for both "/images/"
-// and "/images/thumbnails/", the latter handler will be
-// called for paths beginning "/images/thumbnails/" and the
-// former will receive requests for any other paths in the
-// "/images/" subtree.
-//
-// Note that since a pattern ending in a slash names a rooted subtree,
-// the pattern "/" matches all paths not matched by other registered
-// patterns, not just the URL with Path == "/".
-//
-// If a subtree has been registered and a request is received naming the
-// subtree root without its trailing slash, ServeMux redirects that
-// request to the subtree root (adding the trailing slash). This behavior can
-// be overridden with a separate registration for the path without
-// the trailing slash. For example, registering "/images/" causes ServeMux
-// to redirect a request for "/images" to "/images/", unless "/images" has
-// been registered separately.
-//
-// Patterns may optionally begin with a host name, restricting matches to
-// URLs on that host only. Host-specific patterns take precedence over
-// general patterns, so that a handler might register for the two patterns
-// "/codesearch" and "codesearch.google.com/" without also taking over
-// requests for "http://www.google.com/".
-//
-// ServeMux also takes care of sanitizing the URL request path and the Host
-// header, stripping the port number and redirecting any request containing . or
-// .. elements or repeated slashes to an equivalent, cleaner URL.
-type ServeMux struct {
- mu sync.RWMutex
- m map[string]muxEntry
- es []muxEntry // slice of entries sorted from longest to shortest.
- hosts bool // whether any patterns contain hostnames
-}
-
-type muxEntry struct {
- h Handler
- pattern string
-}
-
-// NewServeMux allocates and returns a new ServeMux.
-func NewServeMux() *ServeMux { return new(ServeMux) }
-
-// DefaultServeMux is the default ServeMux used by Serve.
-var DefaultServeMux = &defaultServeMux
-
-var defaultServeMux ServeMux
-
-// cleanPath returns the canonical path for p, eliminating . and .. elements.
-func cleanPath(p string) string {
- if p == "" {
- return "/"
- }
- if p[0] != '/' {
- p = "/" + p
- }
- np := path.Clean(p)
- // path.Clean removes trailing slash except for root;
- // put the trailing slash back if necessary.
- if p[len(p)-1] == '/' && np != "/" {
- // Fast path for common case of p being the string we want:
- if len(p) == len(np)+1 && strings.HasPrefix(p, np) {
- np = p
- } else {
- np += "/"
- }
- }
- return np
-}
-
-// stripHostPort returns h without any trailing ":<port>".
-func stripHostPort(h string) string {
- // If no port on host, return unchanged
- if !strings.Contains(h, ":") {
- return h
- }
- host, _, err := net.SplitHostPort(h)
- if err != nil {
- return h // on error, return unchanged
- }
- return host
-}
-
-// Find a handler on a handler map given a path string.
-// Most-specific (longest) pattern wins.
-func (mux *ServeMux) match(path string) (h Handler, pattern string) {
- // Check for exact match first.
- v, ok := mux.m[path]
- if ok {
- return v.h, v.pattern
- }
-
- // Check for longest valid match. mux.es contains all patterns
- // that end in / sorted from longest to shortest.
- for _, e := range mux.es {
- if strings.HasPrefix(path, e.pattern) {
- return e.h, e.pattern
- }
- }
- return nil, ""
-}
-
-// redirectToPathSlash determines if the given path needs appending "/" to it.
-// This occurs when a handler for path + "/" was already registered, but
-// not for path itself. If the path needs appending to, it creates a new
-// URL, setting the path to u.Path + "/" and returning true to indicate so.
-func (mux *ServeMux) redirectToPathSlash(host, path string, u *url.URL) (*url.URL, bool) {
- mux.mu.RLock()
- shouldRedirect := mux.shouldRedirectRLocked(host, path)
- mux.mu.RUnlock()
- if !shouldRedirect {
- return u, false
- }
- path = path + "/"
- u = &url.URL{Path: path, RawQuery: u.RawQuery}
- return u, true
-}
-
-// shouldRedirectRLocked reports whether the given path and host should be redirected to
-// path+"/". This should happen if a handler is registered for path+"/" but
-// not path -- see comments at ServeMux.
-func (mux *ServeMux) shouldRedirectRLocked(host, path string) bool {
- p := []string{path, host + path}
-
- for _, c := range p {
- if _, exist := mux.m[c]; exist {
- return false
- }
- }
-
- n := len(path)
- if n == 0 {
- return false
- }
- for _, c := range p {
- if _, exist := mux.m[c+"/"]; exist {
- return path[n-1] != '/'
- }
- }
-
- return false
-}
-
-// Handler returns the handler to use for the given request,
-// consulting r.Method, r.Host, and r.URL.Path. It always returns
-// a non-nil handler. If the path is not in its canonical form, the
-// handler will be an internally-generated handler that redirects
-// to the canonical path. If the host contains a port, it is ignored
-// when matching handlers.
-//
-// The path and host are used unchanged for CONNECT requests.
-//
-// Handler also returns the registered pattern that matches the
-// request or, in the case of internally-generated redirects,
-// the pattern that will match after following the redirect.
-//
-// If there is no registered handler that applies to the request,
-// Handler returns a “page not found” handler and an empty pattern.
-func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
-
- // CONNECT requests are not canonicalized.
- if r.Method == "CONNECT" {
- // If r.URL.Path is /tree and its handler is not registered,
- // the /tree -> /tree/ redirect applies to CONNECT requests
- // but the path canonicalization does not.
- if u, ok := mux.redirectToPathSlash(r.URL.Host, r.URL.Path, r.URL); ok {
- return RedirectHandler(u.String(), StatusMovedPermanently), u.Path
- }
-
- return mux.handler(r.Host, r.URL.Path)
- }
-
- // All other requests have any port stripped and path cleaned
- // before passing to mux.handler.
- host := stripHostPort(r.Host)
- path := cleanPath(r.URL.Path)
-
- // If the given path is /tree and its handler is not registered,
- // redirect for /tree/.
- if u, ok := mux.redirectToPathSlash(host, path, r.URL); ok {
- return RedirectHandler(u.String(), StatusMovedPermanently), u.Path
- }
-
- if path != r.URL.Path {
- _, pattern = mux.handler(host, path)
- u := &url.URL{Path: path, RawQuery: r.URL.RawQuery}
- return RedirectHandler(u.String(), StatusMovedPermanently), pattern
- }
-
- return mux.handler(host, r.URL.Path)
-}
-
-// handler is the main implementation of Handler.
-// The path is known to be in canonical form, except for CONNECT methods.
-func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
- mux.mu.RLock()
- defer mux.mu.RUnlock()
-
- // Host-specific pattern takes precedence over generic ones
- if mux.hosts {
- h, pattern = mux.match(host + path)
- }
- if h == nil {
- h, pattern = mux.match(path)
- }
- if h == nil {
- h, pattern = NotFoundHandler(), ""
- }
- return
-}
-
-// ServeHTTP dispatches the request to the handler whose
-// pattern most closely matches the request URL.
-func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
- if r.RequestURI == "*" {
- if r.ProtoAtLeast(1, 1) {
- w.Header().Set("Connection", "close")
- }
- w.WriteHeader(StatusBadRequest)
- return
- }
- h, _ := mux.Handler(r)
- h.ServeHTTP(w, r)
-}
-
-// Handle registers the handler for the given pattern.
-// If a handler already exists for pattern, Handle panics.
-func (mux *ServeMux) Handle(pattern string, handler Handler) {
- mux.mu.Lock()
- defer mux.mu.Unlock()
-
- if pattern == "" {
- panic("http: invalid pattern")
- }
- if handler == nil {
- panic("http: nil handler")
- }
- if _, exist := mux.m[pattern]; exist {
- panic("http: multiple registrations for " + pattern)
- }
-
- if mux.m == nil {
- mux.m = make(map[string]muxEntry)
- }
- e := muxEntry{h: handler, pattern: pattern}
- mux.m[pattern] = e
- if pattern[len(pattern)-1] == '/' {
- mux.es = appendSorted(mux.es, e)
- }
-
- if pattern[0] != '/' {
- mux.hosts = true
- }
-}
-
-func appendSorted(es []muxEntry, e muxEntry) []muxEntry {
- n := len(es)
- i := sort.Search(n, func(i int) bool {
- return len(es[i].pattern) < len(e.pattern)
- })
- if i == n {
- return append(es, e)
- }
- // we now know that i points at where we want to insert
- es = append(es, muxEntry{}) // try to grow the slice in place, any entry works.
- copy(es[i+1:], es[i:]) // Move shorter entries down
- es[i] = e
- return es
-}
-
-// HandleFunc registers the handler function for the given pattern.
-func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
- if handler == nil {
- panic("http: nil handler")
- }
- mux.Handle(pattern, HandlerFunc(handler))
-}
-
-// Handle registers the handler for the given pattern
-// in the DefaultServeMux.
-// The documentation for ServeMux explains how patterns are matched.
-func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
-
-// HandleFunc registers the handler function for the given pattern
-// in the DefaultServeMux.
-// The documentation for ServeMux explains how patterns are matched.
-func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
- DefaultServeMux.HandleFunc(pattern, handler)
-}
-
-// Serve accepts incoming HTTP connections on the listener l,
-// creating a new service goroutine for each. The service goroutines
-// read requests and then call handler to reply to them.
-//
-// The handler is typically nil, in which case the DefaultServeMux is used.
-//
-// HTTP/2 support is only enabled if the Listener returns *tls.Conn
-// connections and they were configured with "h2" in the TLS
-// Config.NextProtos.
-//
-// Serve always returns a non-nil error.
-func Serve(l net.Listener, handler Handler) error {
- srv := &Server{Handler: handler}
- return srv.Serve(l)
-}
-
-// ServeTLS accepts incoming HTTPS connections on the listener l,
-// creating a new service goroutine for each. The service goroutines
-// read requests and then call handler to reply to them.
-//
-// The handler is typically nil, in which case the DefaultServeMux is used.
-//
-// Additionally, files containing a certificate and matching private key
-// for the server must be provided. If the certificate is signed by a
-// certificate authority, the certFile should be the concatenation
-// of the server's certificate, any intermediates, and the CA's certificate.
-//
-// ServeTLS always returns a non-nil error.
-func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error {
- srv := &Server{Handler: handler}
- return srv.ServeTLS(l, certFile, keyFile)
-}
-
-// A Server defines parameters for running an HTTP server.
-// The zero value for Server is a valid configuration.
-type Server struct {
- // Addr optionally specifies the TCP address for the server to listen on,
- // in the form "host:port". If empty, ":http" (port 80) is used.
- // The service names are defined in RFC 6335 and assigned by IANA.
- // See net.Dial for details of the address format.
- Addr string
-
- Handler Handler // handler to invoke, http.DefaultServeMux if nil
-
- // DisableGeneralOptionsHandler, if true, passes "OPTIONS *" requests to the Handler,
- // otherwise responds with 200 OK and Content-Length: 0.
- DisableGeneralOptionsHandler bool
-
- // TLSConfig optionally provides a TLS configuration for use
- // by ServeTLS and ListenAndServeTLS. Note that this value is
- // cloned by ServeTLS and ListenAndServeTLS, so it's not
- // possible to modify the configuration with methods like
- // tls.Config.SetSessionTicketKeys. To use
- // SetSessionTicketKeys, use Server.Serve with a TLS Listener
- // instead.
- TLSConfig *tls.Config
-
- // ReadTimeout is the maximum duration for reading the entire
- // request, including the body. A zero or negative value means
- // there will be no timeout.
- //
- // Because ReadTimeout does not let Handlers make per-request
- // decisions on each request body's acceptable deadline or
- // upload rate, most users will prefer to use
- // ReadHeaderTimeout. It is valid to use them both.
- ReadTimeout time.Duration
-
- // ReadHeaderTimeout is the amount of time allowed to read
- // request headers. The connection's read deadline is reset
- // after reading the headers and the Handler can decide what
- // is considered too slow for the body. If ReadHeaderTimeout
- // is zero, the value of ReadTimeout is used. If both are
- // zero, there is no timeout.
- ReadHeaderTimeout time.Duration
-
- // WriteTimeout is the maximum duration before timing out
- // writes of the response. It is reset whenever a new
- // request's header is read. Like ReadTimeout, it does not
- // let Handlers make decisions on a per-request basis.
- // A zero or negative value means there will be no timeout.
- WriteTimeout time.Duration
-
- // IdleTimeout is the maximum amount of time to wait for the
- // next request when keep-alives are enabled. If IdleTimeout
- // is zero, the value of ReadTimeout is used. If both are
- // zero, there is no timeout.
- IdleTimeout time.Duration
-
- // MaxHeaderBytes controls the maximum number of bytes the
- // server will read parsing the request header's keys and
- // values, including the request line. It does not limit the
- // size of the request body.
- // If zero, DefaultMaxHeaderBytes is used.
- MaxHeaderBytes int
-
- // TLSNextProto optionally specifies a function to take over
- // ownership of the provided TLS connection when an ALPN
- // protocol upgrade has occurred. The map key is the protocol
- // name negotiated. The Handler argument should be used to
- // handle HTTP requests and will initialize the Request's TLS
- // and RemoteAddr if not already set. The connection is
- // automatically closed when the function returns.
- // If TLSNextProto is not nil, HTTP/2 support is not enabled
- // automatically.
- TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
-
- // ConnState specifies an optional callback function that is
- // called when a client connection changes state. See the
- // ConnState type and associated constants for details.
- ConnState func(net.Conn, ConnState)
-
- // ErrorLog specifies an optional logger for errors accepting
- // connections, unexpected behavior from handlers, and
- // underlying FileSystem errors.
- // If nil, logging is done via the log package's standard logger.
- ErrorLog *log.Logger
-
- // BaseContext optionally specifies a function that returns
- // the base context for incoming requests on this server.
- // The provided Listener is the specific Listener that's
- // about to start accepting requests.
- // If BaseContext is nil, the default is context.Background().
- // If non-nil, it must return a non-nil context.
- BaseContext func(net.Listener) context.Context
-
- // ConnContext optionally specifies a function that modifies
- // the context used for a new connection c. The provided ctx
- // is derived from the base context and has a ServerContextKey
- // value.
- ConnContext func(ctx context.Context, c net.Conn) context.Context
-
- inShutdown atomic.Bool // true when server is in shutdown
-
- disableKeepAlives atomic.Bool
- nextProtoOnce sync.Once // guards setupHTTP2_* init
- nextProtoErr error // result of http2.ConfigureServer if used
-
- mu sync.Mutex
- listeners map[*net.Listener]struct{}
- activeConn map[*conn]struct{}
- onShutdown []func()
-
- listenerGroup sync.WaitGroup
-}
-
-// Close immediately closes all active net.Listeners and any
-// connections in state StateNew, StateActive, or StateIdle. For a
-// graceful shutdown, use Shutdown.
-//
-// Close does not attempt to close (and does not even know about)
-// any hijacked connections, such as WebSockets.
-//
-// Close returns any error returned from closing the Server's
-// underlying Listener(s).
-func (srv *Server) Close() error {
- srv.inShutdown.Store(true)
- srv.mu.Lock()
- defer srv.mu.Unlock()
- err := srv.closeListenersLocked()
-
- // Unlock srv.mu while waiting for listenerGroup.
- // The group Add and Done calls are made with srv.mu held,
- // to avoid adding a new listener in the window between
- // us setting inShutdown above and waiting here.
- srv.mu.Unlock()
- srv.listenerGroup.Wait()
- srv.mu.Lock()
-
- for c := range srv.activeConn {
- c.rwc.Close()
- delete(srv.activeConn, c)
- }
- return err
-}
-
-// shutdownPollIntervalMax is the max polling interval when checking
-// quiescence during Server.Shutdown. Polling starts with a small
-// interval and backs off to the max.
-// Ideally we could find a solution that doesn't involve polling,
-// but which also doesn't have a high runtime cost (and doesn't
-// involve any contentious mutexes), but that is left as an
-// exercise for the reader.
-const shutdownPollIntervalMax = 500 * time.Millisecond
-
-// Shutdown gracefully shuts down the server without interrupting any
-// active connections. Shutdown works by first closing all open
-// listeners, then closing all idle connections, and then waiting
-// indefinitely for connections to return to idle and then shut down.
-// If the provided context expires before the shutdown is complete,
-// Shutdown returns the context's error, otherwise it returns any
-// error returned from closing the Server's underlying Listener(s).
-//
-// When Shutdown is called, Serve, ListenAndServe, and
-// ListenAndServeTLS immediately return ErrServerClosed. Make sure the
-// program doesn't exit and waits instead for Shutdown to return.
-//
-// Shutdown does not attempt to close nor wait for hijacked
-// connections such as WebSockets. The caller of Shutdown should
-// separately notify such long-lived connections of shutdown and wait
-// for them to close, if desired. See RegisterOnShutdown for a way to
-// register shutdown notification functions.
-//
-// Once Shutdown has been called on a server, it may not be reused;
-// future calls to methods such as Serve will return ErrServerClosed.
-func (srv *Server) Shutdown(ctx context.Context) error {
- srv.inShutdown.Store(true)
-
- srv.mu.Lock()
- lnerr := srv.closeListenersLocked()
- for _, f := range srv.onShutdown {
- go f()
- }
- srv.mu.Unlock()
- srv.listenerGroup.Wait()
-
- pollIntervalBase := time.Millisecond
- nextPollInterval := func() time.Duration {
- // Add 10% jitter.
- interval := pollIntervalBase + time.Duration(rand.Intn(int(pollIntervalBase/10)))
- // Double and clamp for next time.
- pollIntervalBase *= 2
- if pollIntervalBase > shutdownPollIntervalMax {
- pollIntervalBase = shutdownPollIntervalMax
- }
- return interval
- }
-
- timer := time.NewTimer(nextPollInterval())
- defer timer.Stop()
- for {
- if srv.closeIdleConns() {
- return lnerr
- }
- select {
- case <-ctx.Done():
- return ctx.Err()
- case <-timer.C:
- timer.Reset(nextPollInterval())
- }
- }
-}
-
-// RegisterOnShutdown registers a function to call on Shutdown.
-// This can be used to gracefully shutdown connections that have
-// undergone ALPN protocol upgrade or that have been hijacked.
-// This function should start protocol-specific graceful shutdown,
-// but should not wait for shutdown to complete.
-func (srv *Server) RegisterOnShutdown(f func()) {
- srv.mu.Lock()
- srv.onShutdown = append(srv.onShutdown, f)
- srv.mu.Unlock()
-}
-
-// closeIdleConns closes all idle connections and reports whether the
-// server is quiescent.
-func (s *Server) closeIdleConns() bool {
- s.mu.Lock()
- defer s.mu.Unlock()
- quiescent := true
- for c := range s.activeConn {
- st, unixSec := c.getState()
- // Issue 22682: treat StateNew connections as if
- // they're idle if we haven't read the first request's
- // header in over 5 seconds.
- if st == StateNew && unixSec < time.Now().Unix()-5 {
- st = StateIdle
- }
- if st != StateIdle || unixSec == 0 {
- // Assume unixSec == 0 means it's a very new
- // connection, without state set yet.
- quiescent = false
- continue
- }
- c.rwc.Close()
- delete(s.activeConn, c)
- }
- return quiescent
-}
-
-func (s *Server) closeListenersLocked() error {
- var err error
- for ln := range s.listeners {
- if cerr := (*ln).Close(); cerr != nil && err == nil {
- err = cerr
- }
- }
- return err
-}
-
-// A ConnState represents the state of a client connection to a server.
-// It's used by the optional Server.ConnState hook.
-type ConnState int
-
-const (
- // StateNew represents a new connection that is expected to
- // send a request immediately. Connections begin at this
- // state and then transition to either StateActive or
- // StateClosed.
- StateNew ConnState = iota
-
- // StateActive represents a connection that has read 1 or more
- // bytes of a request. The Server.ConnState hook for
- // StateActive fires before the request has entered a handler
- // and doesn't fire again until the request has been
- // handled. After the request is handled, the state
- // transitions to StateClosed, StateHijacked, or StateIdle.
- // For HTTP/2, StateActive fires on the transition from zero
- // to one active request, and only transitions away once all
- // active requests are complete. That means that ConnState
- // cannot be used to do per-request work; ConnState only notes
- // the overall state of the connection.
- StateActive
-
- // StateIdle represents a connection that has finished
- // handling a request and is in the keep-alive state, waiting
- // for a new request. Connections transition from StateIdle
- // to either StateActive or StateClosed.
- StateIdle
-
- // StateHijacked represents a hijacked connection.
- // This is a terminal state. It does not transition to StateClosed.
- StateHijacked
-
- // StateClosed represents a closed connection.
- // This is a terminal state. Hijacked connections do not
- // transition to StateClosed.
- StateClosed
-)
-
-var stateName = map[ConnState]string{
- StateNew: "new",
- StateActive: "active",
- StateIdle: "idle",
- StateHijacked: "hijacked",
- StateClosed: "closed",
-}
-
-func (c ConnState) String() string {
- return stateName[c]
-}
-
-// serverHandler delegates to either the server's Handler or
-// DefaultServeMux and also handles "OPTIONS *" requests.
-type serverHandler struct {
- srv *Server
-}
-
-func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
- handler := sh.srv.Handler
- if handler == nil {
- handler = DefaultServeMux
- }
- if !sh.srv.DisableGeneralOptionsHandler && req.RequestURI == "*" && req.Method == "OPTIONS" {
- handler = globalOptionsHandler{}
- }
-
- if req.URL != nil && strings.Contains(req.URL.RawQuery, ";") {
- var allowQuerySemicolonsInUse atomic.Bool
- req = req.WithContext(context.WithValue(req.Context(), silenceSemWarnContextKey, func() {
- allowQuerySemicolonsInUse.Store(true)
- }))
- defer func() {
- if !allowQuerySemicolonsInUse.Load() {
- sh.srv.logf("http: URL query contains semicolon, which is no longer a supported separator; parts of the query may be stripped when parsed; see golang.org/issue/25192")
- }
- }()
- }
-
- handler.ServeHTTP(rw, req)
-}
-
-var silenceSemWarnContextKey = &contextKey{"silence-semicolons"}
-
-// AllowQuerySemicolons returns a handler that serves requests by converting any
-// unescaped semicolons in the URL query to ampersands, and invoking the handler h.
-//
-// This restores the pre-Go 1.17 behavior of splitting query parameters on both
-// semicolons and ampersands. (See golang.org/issue/25192). Note that this
-// behavior doesn't match that of many proxies, and the mismatch can lead to
-// security issues.
-//
-// AllowQuerySemicolons should be invoked before Request.ParseForm is called.
-func AllowQuerySemicolons(h Handler) Handler {
- return HandlerFunc(func(w ResponseWriter, r *Request) {
- if silenceSemicolonsWarning, ok := r.Context().Value(silenceSemWarnContextKey).(func()); ok {
- silenceSemicolonsWarning()
- }
- if strings.Contains(r.URL.RawQuery, ";") {
- r2 := new(Request)
- *r2 = *r
- r2.URL = new(url.URL)
- *r2.URL = *r.URL
- r2.URL.RawQuery = strings.ReplaceAll(r.URL.RawQuery, ";", "&")
- h.ServeHTTP(w, r2)
- } else {
- h.ServeHTTP(w, r)
- }
- })
-}
-
-// ListenAndServe listens on the TCP network address srv.Addr and then
-// calls Serve to handle requests on incoming connections.
-// Accepted connections are configured to enable TCP keep-alives.
-//
-// If srv.Addr is blank, ":http" is used.
-//
-// ListenAndServe always returns a non-nil error. After Shutdown or Close,
-// the returned error is ErrServerClosed.
-func (srv *Server) ListenAndServe() error {
- if srv.shuttingDown() {
- return ErrServerClosed
- }
- addr := srv.Addr
- if addr == "" {
- addr = ":http"
- }
- ln, err := net.Listen("tcp", addr)
- if err != nil {
- return err
- }
- return srv.Serve(ln)
-}
-
-var testHookServerServe func(*Server, net.Listener) // used if non-nil
-
-// shouldDoServeHTTP2 reports whether Server.Serve should configure
-// automatic HTTP/2. (which sets up the srv.TLSNextProto map)
-func (srv *Server) shouldConfigureHTTP2ForServe() bool {
- if srv.TLSConfig == nil {
- // Compatibility with Go 1.6:
- // If there's no TLSConfig, it's possible that the user just
- // didn't set it on the http.Server, but did pass it to
- // tls.NewListener and passed that listener to Serve.
- // So we should configure HTTP/2 (to set up srv.TLSNextProto)
- // in case the listener returns an "h2" *tls.Conn.
- return true
- }
- // The user specified a TLSConfig on their http.Server.
- // In this, case, only configure HTTP/2 if their tls.Config
- // explicitly mentions "h2". Otherwise http2.ConfigureServer
- // would modify the tls.Config to add it, but they probably already
- // passed this tls.Config to tls.NewListener. And if they did,
- // it's too late anyway to fix it. It would only be potentially racy.
- // See Issue 15908.
- return strSliceContains(srv.TLSConfig.NextProtos, http2NextProtoTLS)
-}
-
-// ErrServerClosed is returned by the Server's Serve, ServeTLS, ListenAndServe,
-// and ListenAndServeTLS methods after a call to Shutdown or Close.
-var ErrServerClosed = errors.New("http: Server closed")
-
-// Serve accepts incoming connections on the Listener l, creating a
-// new service goroutine for each. The service goroutines read requests and
-// then call srv.Handler to reply to them.
-//
-// HTTP/2 support is only enabled if the Listener returns *tls.Conn
-// connections and they were configured with "h2" in the TLS
-// Config.NextProtos.
-//
-// Serve always returns a non-nil error and closes l.
-// After Shutdown or Close, the returned error is ErrServerClosed.
-func (srv *Server) Serve(l net.Listener) error {
- if fn := testHookServerServe; fn != nil {
- fn(srv, l) // call hook with unwrapped listener
- }
-
- origListener := l
- l = &onceCloseListener{Listener: l}
- defer l.Close()
-
- if err := srv.setupHTTP2_Serve(); err != nil {
- return err
- }
-
- if !srv.trackListener(&l, true) {
- return ErrServerClosed
- }
- defer srv.trackListener(&l, false)
-
- baseCtx := context.Background()
- if srv.BaseContext != nil {
- baseCtx = srv.BaseContext(origListener)
- if baseCtx == nil {
- panic("BaseContext returned a nil context")
- }
- }
-
- var tempDelay time.Duration // how long to sleep on accept failure
-
- ctx := context.WithValue(baseCtx, ServerContextKey, srv)
- for {
- rw, err := l.Accept()
- if err != nil {
- if srv.shuttingDown() {
- return ErrServerClosed
- }
- if ne, ok := err.(net.Error); ok && ne.Temporary() {
- if tempDelay == 0 {
- tempDelay = 5 * time.Millisecond
- } else {
- tempDelay *= 2
- }
- if max := 1 * time.Second; tempDelay > max {
- tempDelay = max
- }
- srv.logf("http: Accept error: %v; retrying in %v", err, tempDelay)
- time.Sleep(tempDelay)
- continue
- }
- return err
- }
- connCtx := ctx
- if cc := srv.ConnContext; cc != nil {
- connCtx = cc(connCtx, rw)
- if connCtx == nil {
- panic("ConnContext returned nil")
- }
- }
- tempDelay = 0
- c := srv.newConn(rw)
- c.setState(c.rwc, StateNew, runHooks) // before Serve can return
- go c.serve(connCtx)
- }
-}
-
-// ServeTLS accepts incoming connections on the Listener l, creating a
-// new service goroutine for each. The service goroutines perform TLS
-// setup and then read requests, calling srv.Handler to reply to them.
-//
-// Files containing a certificate and matching private key for the
-// server must be provided if neither the Server's
-// TLSConfig.Certificates nor TLSConfig.GetCertificate are populated.
-// If the certificate is signed by a certificate authority, the
-// certFile should be the concatenation of the server's certificate,
-// any intermediates, and the CA's certificate.
-//
-// ServeTLS always returns a non-nil error. After Shutdown or Close, the
-// returned error is ErrServerClosed.
-func (srv *Server) ServeTLS(l net.Listener, certFile, keyFile string) error {
- // Setup HTTP/2 before srv.Serve, to initialize srv.TLSConfig
- // before we clone it and create the TLS Listener.
- if err := srv.setupHTTP2_ServeTLS(); err != nil {
- return err
- }
-
- config := cloneTLSConfig(srv.TLSConfig)
- if !strSliceContains(config.NextProtos, "http/1.1") {
- config.NextProtos = append(config.NextProtos, "http/1.1")
- }
-
- configHasCert := len(config.Certificates) > 0 || config.GetCertificate != nil
- if !configHasCert || certFile != "" || keyFile != "" {
- var err error
- config.Certificates = make([]tls.Certificate, 1)
- config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
- if err != nil {
- return err
- }
- }
-
- tlsListener := tls.NewListener(l, config)
- return srv.Serve(tlsListener)
-}
-
-// trackListener adds or removes a net.Listener to the set of tracked
-// listeners.
-//
-// We store a pointer to interface in the map set, in case the
-// net.Listener is not comparable. This is safe because we only call
-// trackListener via Serve and can track+defer untrack the same
-// pointer to local variable there. We never need to compare a
-// Listener from another caller.
-//
-// It reports whether the server is still up (not Shutdown or Closed).
-func (s *Server) trackListener(ln *net.Listener, add bool) bool {
- s.mu.Lock()
- defer s.mu.Unlock()
- if s.listeners == nil {
- s.listeners = make(map[*net.Listener]struct{})
- }
- if add {
- if s.shuttingDown() {
- return false
- }
- s.listeners[ln] = struct{}{}
- s.listenerGroup.Add(1)
- } else {
- delete(s.listeners, ln)
- s.listenerGroup.Done()
- }
- return true
-}
-
-func (s *Server) trackConn(c *conn, add bool) {
- s.mu.Lock()
- defer s.mu.Unlock()
- if s.activeConn == nil {
- s.activeConn = make(map[*conn]struct{})
- }
- if add {
- s.activeConn[c] = struct{}{}
- } else {
- delete(s.activeConn, c)
- }
-}
-
-func (s *Server) idleTimeout() time.Duration {
- if s.IdleTimeout != 0 {
- return s.IdleTimeout
- }
- return s.ReadTimeout
-}
-
-func (s *Server) readHeaderTimeout() time.Duration {
- if s.ReadHeaderTimeout != 0 {
- return s.ReadHeaderTimeout
- }
- return s.ReadTimeout
-}
-
-func (s *Server) doKeepAlives() bool {
- return !s.disableKeepAlives.Load() && !s.shuttingDown()
-}
-
-func (s *Server) shuttingDown() bool {
- return s.inShutdown.Load()
-}
-
-// SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled.
-// By default, keep-alives are always enabled. Only very
-// resource-constrained environments or servers in the process of
-// shutting down should disable them.
-func (srv *Server) SetKeepAlivesEnabled(v bool) {
- if v {
- srv.disableKeepAlives.Store(false)
- return
- }
- srv.disableKeepAlives.Store(true)
-
- // Close idle HTTP/1 conns:
- srv.closeIdleConns()
-
- // TODO: Issue 26303: close HTTP/2 conns as soon as they become idle.
-}
-
-func (s *Server) logf(format string, args ...any) {
- if s.ErrorLog != nil {
- s.ErrorLog.Printf(format, args...)
- } else {
- log.Printf(format, args...)
- }
-}
-
-// logf prints to the ErrorLog of the *Server associated with request r
-// via ServerContextKey. If there's no associated server, or if ErrorLog
-// is nil, logging is done via the log package's standard logger.
-func logf(r *Request, format string, args ...any) {
- s, _ := r.Context().Value(ServerContextKey).(*Server)
- if s != nil && s.ErrorLog != nil {
- s.ErrorLog.Printf(format, args...)
- } else {
- log.Printf(format, args...)
- }
-}
-
-// ListenAndServe listens on the TCP network address addr and then calls
-// Serve with handler to handle requests on incoming connections.
-// Accepted connections are configured to enable TCP keep-alives.
-//
-// The handler is typically nil, in which case the DefaultServeMux is used.
-//
-// ListenAndServe always returns a non-nil error.
-func ListenAndServe(addr string, handler Handler) error {
- server := &Server{Addr: addr, Handler: handler}
- return server.ListenAndServe()
-}
-
-// ListenAndServeTLS acts identically to ListenAndServe, except that it
-// expects HTTPS connections. Additionally, files containing a certificate and
-// matching private key for the server must be provided. If the certificate
-// is signed by a certificate authority, the certFile should be the concatenation
-// of the server's certificate, any intermediates, and the CA's certificate.
-func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
- server := &Server{Addr: addr, Handler: handler}
- return server.ListenAndServeTLS(certFile, keyFile)
-}
-
-// ListenAndServeTLS listens on the TCP network address srv.Addr and
-// then calls ServeTLS to handle requests on incoming TLS connections.
-// Accepted connections are configured to enable TCP keep-alives.
-//
-// Filenames containing a certificate and matching private key for the
-// server must be provided if neither the Server's TLSConfig.Certificates
-// nor TLSConfig.GetCertificate are populated. If the certificate is
-// signed by a certificate authority, the certFile should be the
-// concatenation of the server's certificate, any intermediates, and
-// the CA's certificate.
-//
-// If srv.Addr is blank, ":https" is used.
-//
-// ListenAndServeTLS always returns a non-nil error. After Shutdown or
-// Close, the returned error is ErrServerClosed.
-func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
- if srv.shuttingDown() {
- return ErrServerClosed
- }
- addr := srv.Addr
- if addr == "" {
- addr = ":https"
- }
-
- ln, err := net.Listen("tcp", addr)
- if err != nil {
- return err
- }
-
- defer ln.Close()
-
- return srv.ServeTLS(ln, certFile, keyFile)
-}
-
-// setupHTTP2_ServeTLS conditionally configures HTTP/2 on
-// srv and reports whether there was an error setting it up. If it is
-// not configured for policy reasons, nil is returned.
-func (srv *Server) setupHTTP2_ServeTLS() error {
- srv.nextProtoOnce.Do(srv.onceSetNextProtoDefaults)
- return srv.nextProtoErr
-}
-
-// setupHTTP2_Serve is called from (*Server).Serve and conditionally
-// configures HTTP/2 on srv using a more conservative policy than
-// setupHTTP2_ServeTLS because Serve is called after tls.Listen,
-// and may be called concurrently. See shouldConfigureHTTP2ForServe.
-//
-// The tests named TestTransportAutomaticHTTP2* and
-// TestConcurrentServerServe in server_test.go demonstrate some
-// of the supported use cases and motivations.
-func (srv *Server) setupHTTP2_Serve() error {
- srv.nextProtoOnce.Do(srv.onceSetNextProtoDefaults_Serve)
- return srv.nextProtoErr
-}
-
-func (srv *Server) onceSetNextProtoDefaults_Serve() {
- if srv.shouldConfigureHTTP2ForServe() {
- srv.onceSetNextProtoDefaults()
- }
-}
-
-var http2server = godebug.New("http2server")
-
-// onceSetNextProtoDefaults configures HTTP/2, if the user hasn't
-// configured otherwise. (by setting srv.TLSNextProto non-nil)
-// It must only be called via srv.nextProtoOnce (use srv.setupHTTP2_*).
-func (srv *Server) onceSetNextProtoDefaults() {
- if omitBundledHTTP2 || http2server.Value() == "0" {
- return
- }
- // Enable HTTP/2 by default if the user hasn't otherwise
- // configured their TLSNextProto map.
- if srv.TLSNextProto == nil {
- conf := &http2Server{
- NewWriteScheduler: func() http2WriteScheduler { return http2NewPriorityWriteScheduler(nil) },
- }
- srv.nextProtoErr = http2ConfigureServer(srv, conf)
- }
-}
-
-// TimeoutHandler returns a Handler that runs h with the given time limit.
-//
-// The new Handler calls h.ServeHTTP to handle each request, but if a
-// call runs for longer than its time limit, the handler responds with
-// a 503 Service Unavailable error and the given message in its body.
-// (If msg is empty, a suitable default message will be sent.)
-// After such a timeout, writes by h to its ResponseWriter will return
-// ErrHandlerTimeout.
-//
-// TimeoutHandler supports the Pusher interface but does not support
-// the Hijacker or Flusher interfaces.
-func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
- return &timeoutHandler{
- handler: h,
- body: msg,
- dt: dt,
- }
-}
-
-// ErrHandlerTimeout is returned on ResponseWriter Write calls
-// in handlers which have timed out.
-var ErrHandlerTimeout = errors.New("http: Handler timeout")
-
-type timeoutHandler struct {
- handler Handler
- body string
- dt time.Duration
-
- // When set, no context will be created and this context will
- // be used instead.
- testContext context.Context
-}
-
-func (h *timeoutHandler) errorBody() string {
- if h.body != "" {
- return h.body
- }
- return "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>"
-}
-
-func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
- ctx := h.testContext
- if ctx == nil {
- var cancelCtx context.CancelFunc
- ctx, cancelCtx = context.WithTimeout(r.Context(), h.dt)
- defer cancelCtx()
- }
- r = r.WithContext(ctx)
- done := make(chan struct{})
- tw := &timeoutWriter{
- w: w,
- h: make(Header),
- req: r,
- }
- panicChan := make(chan any, 1)
- go func() {
- defer func() {
- if p := recover(); p != nil {
- panicChan <- p
- }
- }()
- h.handler.ServeHTTP(tw, r)
- close(done)
- }()
- select {
- case p := <-panicChan:
- panic(p)
- case <-done:
- tw.mu.Lock()
- defer tw.mu.Unlock()
- dst := w.Header()
- for k, vv := range tw.h {
- dst[k] = vv
- }
- if !tw.wroteHeader {
- tw.code = StatusOK
- }
- w.WriteHeader(tw.code)
- w.Write(tw.wbuf.Bytes())
- case <-ctx.Done():
- tw.mu.Lock()
- defer tw.mu.Unlock()
- switch err := ctx.Err(); err {
- case context.DeadlineExceeded:
- w.WriteHeader(StatusServiceUnavailable)
- io.WriteString(w, h.errorBody())
- tw.err = ErrHandlerTimeout
- default:
- w.WriteHeader(StatusServiceUnavailable)
- tw.err = err
- }
- }
-}
-
-type timeoutWriter struct {
- w ResponseWriter
- h Header
- wbuf bytes.Buffer
- req *Request
-
- mu sync.Mutex
- err error
- wroteHeader bool
- code int
-}
-
-var _ Pusher = (*timeoutWriter)(nil)
-
-// Push implements the Pusher interface.
-func (tw *timeoutWriter) Push(target string, opts *PushOptions) error {
- if pusher, ok := tw.w.(Pusher); ok {
- return pusher.Push(target, opts)
- }
- return ErrNotSupported
-}
-
-func (tw *timeoutWriter) Header() Header { return tw.h }
-
-func (tw *timeoutWriter) Write(p []byte) (int, error) {
- tw.mu.Lock()
- defer tw.mu.Unlock()
- if tw.err != nil {
- return 0, tw.err
- }
- if !tw.wroteHeader {
- tw.writeHeaderLocked(StatusOK)
- }
- return tw.wbuf.Write(p)
-}
-
-func (tw *timeoutWriter) writeHeaderLocked(code int) {
- checkWriteHeaderCode(code)
-
- switch {
- case tw.err != nil:
- return
- case tw.wroteHeader:
- if tw.req != nil {
- caller := relevantCaller()
- logf(tw.req, "http: superfluous response.WriteHeader call from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
- }
- default:
- tw.wroteHeader = true
- tw.code = code
- }
-}
-
-func (tw *timeoutWriter) WriteHeader(code int) {
- tw.mu.Lock()
- defer tw.mu.Unlock()
- tw.writeHeaderLocked(code)
-}
-
-// onceCloseListener wraps a net.Listener, protecting it from
-// multiple Close calls.
-type onceCloseListener struct {
- net.Listener
- once sync.Once
- closeErr error
-}
-
-func (oc *onceCloseListener) Close() error {
- oc.once.Do(oc.close)
- return oc.closeErr
-}
-
-func (oc *onceCloseListener) close() { oc.closeErr = oc.Listener.Close() }
-
-// globalOptionsHandler responds to "OPTIONS *" requests.
-type globalOptionsHandler struct{}
-
-func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) {
- w.Header().Set("Content-Length", "0")
- if r.ContentLength != 0 {
- // Read up to 4KB of OPTIONS body (as mentioned in the
- // spec as being reserved for future use), but anything
- // over that is considered a waste of server resources
- // (or an attack) and we abort and close the connection,
- // courtesy of MaxBytesReader's EOF behavior.
- mb := MaxBytesReader(w, r.Body, 4<<10)
- io.Copy(io.Discard, mb)
- }
-}
-
-// initALPNRequest is an HTTP handler that initializes certain
-// uninitialized fields in its *Request. Such partially-initialized
-// Requests come from ALPN protocol handlers.
-type initALPNRequest struct {
- ctx context.Context
- c *tls.Conn
- h serverHandler
-}
-
-// BaseContext is an exported but unadvertised http.Handler method
-// recognized by x/net/http2 to pass down a context; the TLSNextProto
-// API predates context support so we shoehorn through the only
-// interface we have available.
-func (h initALPNRequest) BaseContext() context.Context { return h.ctx }
-
-func (h initALPNRequest) ServeHTTP(rw ResponseWriter, req *Request) {
- if req.TLS == nil {
- req.TLS = &tls.ConnectionState{}
- *req.TLS = h.c.ConnectionState()
- }
- if req.Body == nil {
- req.Body = NoBody
- }
- if req.RemoteAddr == "" {
- req.RemoteAddr = h.c.RemoteAddr().String()
- }
- h.h.ServeHTTP(rw, req)
-}
-
-// loggingConn is used for debugging.
-type loggingConn struct {
- name string
- net.Conn
-}
-
-var (
- uniqNameMu sync.Mutex
- uniqNameNext = make(map[string]int)
-)
-
-func newLoggingConn(baseName string, c net.Conn) net.Conn {
- uniqNameMu.Lock()
- defer uniqNameMu.Unlock()
- uniqNameNext[baseName]++
- return &loggingConn{
- name: fmt.Sprintf("%s-%d", baseName, uniqNameNext[baseName]),
- Conn: c,
- }
-}
-
-func (c *loggingConn) Write(p []byte) (n int, err error) {
- log.Printf("%s.Write(%d) = ....", c.name, len(p))
- n, err = c.Conn.Write(p)
- log.Printf("%s.Write(%d) = %d, %v", c.name, len(p), n, err)
- return
-}
-
-func (c *loggingConn) Read(p []byte) (n int, err error) {
- log.Printf("%s.Read(%d) = ....", c.name, len(p))
- n, err = c.Conn.Read(p)
- log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err)
- return
-}
-
-func (c *loggingConn) Close() (err error) {
- log.Printf("%s.Close() = ...", c.name)
- err = c.Conn.Close()
- log.Printf("%s.Close() = %v", c.name, err)
- return
-}
-
-// checkConnErrorWriter writes to c.rwc and records any write errors to c.werr.
-// It only contains one field (and a pointer field at that), so it
-// fits in an interface value without an extra allocation.
-type checkConnErrorWriter struct {
- c *conn
-}
-
-func (w checkConnErrorWriter) Write(p []byte) (n int, err error) {
- n, err = w.c.rwc.Write(p)
- if err != nil && w.c.werr == nil {
- w.c.werr = err
- w.c.cancelCtx()
- }
- return
-}
-
-func numLeadingCRorLF(v []byte) (n int) {
- for _, b := range v {
- if b == '\r' || b == '\n' {
- n++
- continue
- }
- break
- }
- return
-
-}
-
-func strSliceContains(ss []string, s string) bool {
- for _, v := range ss {
- if v == s {
- return true
- }
- }
- return false
-}
-
-// tlsRecordHeaderLooksLikeHTTP reports whether a TLS record header
-// looks like it might've been a misdirected plaintext HTTP request.
-func tlsRecordHeaderLooksLikeHTTP(hdr [5]byte) bool {
- switch string(hdr[:]) {
- case "GET /", "HEAD ", "POST ", "PUT /", "OPTIO":
- return true
- }
- return false
-}
-
-// MaxBytesHandler returns a Handler that runs h with its ResponseWriter and Request.Body wrapped by a MaxBytesReader.
-func MaxBytesHandler(h Handler, n int64) Handler {
- return HandlerFunc(func(w ResponseWriter, r *Request) {
- r2 := *r
- r2.Body = MaxBytesReader(w, r.Body, n)
- h.ServeHTTP(w, &r2)
- })
-}
diff --git a/contrib/go/_std_1.20/src/net/http/socks_bundle.go b/contrib/go/_std_1.20/src/net/http/socks_bundle.go
deleted file mode 100644
index e446669589..0000000000
--- a/contrib/go/_std_1.20/src/net/http/socks_bundle.go
+++ /dev/null
@@ -1,473 +0,0 @@
-// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
-//go:generate bundle -o socks_bundle.go -prefix socks golang.org/x/net/internal/socks
-
-// Package socks provides a SOCKS version 5 client implementation.
-//
-// SOCKS protocol version 5 is defined in RFC 1928.
-// Username/Password authentication for SOCKS version 5 is defined in
-// RFC 1929.
-//
-
-package http
-
-import (
- "context"
- "errors"
- "io"
- "net"
- "strconv"
- "time"
-)
-
-var (
- socksnoDeadline = time.Time{}
- socksaLongTimeAgo = time.Unix(1, 0)
-)
-
-func (d *socksDialer) connect(ctx context.Context, c net.Conn, address string) (_ net.Addr, ctxErr error) {
- host, port, err := sockssplitHostPort(address)
- if err != nil {
- return nil, err
- }
- if deadline, ok := ctx.Deadline(); ok && !deadline.IsZero() {
- c.SetDeadline(deadline)
- defer c.SetDeadline(socksnoDeadline)
- }
- if ctx != context.Background() {
- errCh := make(chan error, 1)
- done := make(chan struct{})
- defer func() {
- close(done)
- if ctxErr == nil {
- ctxErr = <-errCh
- }
- }()
- go func() {
- select {
- case <-ctx.Done():
- c.SetDeadline(socksaLongTimeAgo)
- errCh <- ctx.Err()
- case <-done:
- errCh <- nil
- }
- }()
- }
-
- b := make([]byte, 0, 6+len(host)) // the size here is just an estimate
- b = append(b, socksVersion5)
- if len(d.AuthMethods) == 0 || d.Authenticate == nil {
- b = append(b, 1, byte(socksAuthMethodNotRequired))
- } else {
- ams := d.AuthMethods
- if len(ams) > 255 {
- return nil, errors.New("too many authentication methods")
- }
- b = append(b, byte(len(ams)))
- for _, am := range ams {
- b = append(b, byte(am))
- }
- }
- if _, ctxErr = c.Write(b); ctxErr != nil {
- return
- }
-
- if _, ctxErr = io.ReadFull(c, b[:2]); ctxErr != nil {
- return
- }
- if b[0] != socksVersion5 {
- return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
- }
- am := socksAuthMethod(b[1])
- if am == socksAuthMethodNoAcceptableMethods {
- return nil, errors.New("no acceptable authentication methods")
- }
- if d.Authenticate != nil {
- if ctxErr = d.Authenticate(ctx, c, am); ctxErr != nil {
- return
- }
- }
-
- b = b[:0]
- b = append(b, socksVersion5, byte(d.cmd), 0)
- if ip := net.ParseIP(host); ip != nil {
- if ip4 := ip.To4(); ip4 != nil {
- b = append(b, socksAddrTypeIPv4)
- b = append(b, ip4...)
- } else if ip6 := ip.To16(); ip6 != nil {
- b = append(b, socksAddrTypeIPv6)
- b = append(b, ip6...)
- } else {
- return nil, errors.New("unknown address type")
- }
- } else {
- if len(host) > 255 {
- return nil, errors.New("FQDN too long")
- }
- b = append(b, socksAddrTypeFQDN)
- b = append(b, byte(len(host)))
- b = append(b, host...)
- }
- b = append(b, byte(port>>8), byte(port))
- if _, ctxErr = c.Write(b); ctxErr != nil {
- return
- }
-
- if _, ctxErr = io.ReadFull(c, b[:4]); ctxErr != nil {
- return
- }
- if b[0] != socksVersion5 {
- return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
- }
- if cmdErr := socksReply(b[1]); cmdErr != socksStatusSucceeded {
- return nil, errors.New("unknown error " + cmdErr.String())
- }
- if b[2] != 0 {
- return nil, errors.New("non-zero reserved field")
- }
- l := 2
- var a socksAddr
- switch b[3] {
- case socksAddrTypeIPv4:
- l += net.IPv4len
- a.IP = make(net.IP, net.IPv4len)
- case socksAddrTypeIPv6:
- l += net.IPv6len
- a.IP = make(net.IP, net.IPv6len)
- case socksAddrTypeFQDN:
- if _, err := io.ReadFull(c, b[:1]); err != nil {
- return nil, err
- }
- l += int(b[0])
- default:
- return nil, errors.New("unknown address type " + strconv.Itoa(int(b[3])))
- }
- if cap(b) < l {
- b = make([]byte, l)
- } else {
- b = b[:l]
- }
- if _, ctxErr = io.ReadFull(c, b); ctxErr != nil {
- return
- }
- if a.IP != nil {
- copy(a.IP, b)
- } else {
- a.Name = string(b[:len(b)-2])
- }
- a.Port = int(b[len(b)-2])<<8 | int(b[len(b)-1])
- return &a, nil
-}
-
-func sockssplitHostPort(address string) (string, int, error) {
- host, port, err := net.SplitHostPort(address)
- if err != nil {
- return "", 0, err
- }
- portnum, err := strconv.Atoi(port)
- if err != nil {
- return "", 0, err
- }
- if 1 > portnum || portnum > 0xffff {
- return "", 0, errors.New("port number out of range " + port)
- }
- return host, portnum, nil
-}
-
-// A Command represents a SOCKS command.
-type socksCommand int
-
-func (cmd socksCommand) String() string {
- switch cmd {
- case socksCmdConnect:
- return "socks connect"
- case sockscmdBind:
- return "socks bind"
- default:
- return "socks " + strconv.Itoa(int(cmd))
- }
-}
-
-// An AuthMethod represents a SOCKS authentication method.
-type socksAuthMethod int
-
-// A Reply represents a SOCKS command reply code.
-type socksReply int
-
-func (code socksReply) String() string {
- switch code {
- case socksStatusSucceeded:
- return "succeeded"
- case 0x01:
- return "general SOCKS server failure"
- case 0x02:
- return "connection not allowed by ruleset"
- case 0x03:
- return "network unreachable"
- case 0x04:
- return "host unreachable"
- case 0x05:
- return "connection refused"
- case 0x06:
- return "TTL expired"
- case 0x07:
- return "command not supported"
- case 0x08:
- return "address type not supported"
- default:
- return "unknown code: " + strconv.Itoa(int(code))
- }
-}
-
-// Wire protocol constants.
-const (
- socksVersion5 = 0x05
-
- socksAddrTypeIPv4 = 0x01
- socksAddrTypeFQDN = 0x03
- socksAddrTypeIPv6 = 0x04
-
- socksCmdConnect socksCommand = 0x01 // establishes an active-open forward proxy connection
- sockscmdBind socksCommand = 0x02 // establishes a passive-open forward proxy connection
-
- socksAuthMethodNotRequired socksAuthMethod = 0x00 // no authentication required
- socksAuthMethodUsernamePassword socksAuthMethod = 0x02 // use username/password
- socksAuthMethodNoAcceptableMethods socksAuthMethod = 0xff // no acceptable authentication methods
-
- socksStatusSucceeded socksReply = 0x00
-)
-
-// An Addr represents a SOCKS-specific address.
-// Either Name or IP is used exclusively.
-type socksAddr struct {
- Name string // fully-qualified domain name
- IP net.IP
- Port int
-}
-
-func (a *socksAddr) Network() string { return "socks" }
-
-func (a *socksAddr) String() string {
- if a == nil {
- return "<nil>"
- }
- port := strconv.Itoa(a.Port)
- if a.IP == nil {
- return net.JoinHostPort(a.Name, port)
- }
- return net.JoinHostPort(a.IP.String(), port)
-}
-
-// A Conn represents a forward proxy connection.
-type socksConn struct {
- net.Conn
-
- boundAddr net.Addr
-}
-
-// BoundAddr returns the address assigned by the proxy server for
-// connecting to the command target address from the proxy server.
-func (c *socksConn) BoundAddr() net.Addr {
- if c == nil {
- return nil
- }
- return c.boundAddr
-}
-
-// A Dialer holds SOCKS-specific options.
-type socksDialer struct {
- cmd socksCommand // either CmdConnect or cmdBind
- proxyNetwork string // network between a proxy server and a client
- proxyAddress string // proxy server address
-
- // ProxyDial specifies the optional dial function for
- // establishing the transport connection.
- ProxyDial func(context.Context, string, string) (net.Conn, error)
-
- // AuthMethods specifies the list of request authentication
- // methods.
- // If empty, SOCKS client requests only AuthMethodNotRequired.
- AuthMethods []socksAuthMethod
-
- // Authenticate specifies the optional authentication
- // function. It must be non-nil when AuthMethods is not empty.
- // It must return an error when the authentication is failed.
- Authenticate func(context.Context, io.ReadWriter, socksAuthMethod) error
-}
-
-// DialContext connects to the provided address on the provided
-// network.
-//
-// The returned error value may be a net.OpError. When the Op field of
-// net.OpError contains "socks", the Source field contains a proxy
-// server address and the Addr field contains a command target
-// address.
-//
-// See func Dial of the net package of standard library for a
-// description of the network and address parameters.
-func (d *socksDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
- if err := d.validateTarget(network, address); err != nil {
- proxy, dst, _ := d.pathAddrs(address)
- return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
- }
- if ctx == nil {
- proxy, dst, _ := d.pathAddrs(address)
- return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
- }
- var err error
- var c net.Conn
- if d.ProxyDial != nil {
- c, err = d.ProxyDial(ctx, d.proxyNetwork, d.proxyAddress)
- } else {
- var dd net.Dialer
- c, err = dd.DialContext(ctx, d.proxyNetwork, d.proxyAddress)
- }
- if err != nil {
- proxy, dst, _ := d.pathAddrs(address)
- return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
- }
- a, err := d.connect(ctx, c, address)
- if err != nil {
- c.Close()
- proxy, dst, _ := d.pathAddrs(address)
- return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
- }
- return &socksConn{Conn: c, boundAddr: a}, nil
-}
-
-// DialWithConn initiates a connection from SOCKS server to the target
-// network and address using the connection c that is already
-// connected to the SOCKS server.
-//
-// It returns the connection's local address assigned by the SOCKS
-// server.
-func (d *socksDialer) DialWithConn(ctx context.Context, c net.Conn, network, address string) (net.Addr, error) {
- if err := d.validateTarget(network, address); err != nil {
- proxy, dst, _ := d.pathAddrs(address)
- return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
- }
- if ctx == nil {
- proxy, dst, _ := d.pathAddrs(address)
- return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
- }
- a, err := d.connect(ctx, c, address)
- if err != nil {
- proxy, dst, _ := d.pathAddrs(address)
- return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
- }
- return a, nil
-}
-
-// Dial connects to the provided address on the provided network.
-//
-// Unlike DialContext, it returns a raw transport connection instead
-// of a forward proxy connection.
-//
-// Deprecated: Use DialContext or DialWithConn instead.
-func (d *socksDialer) Dial(network, address string) (net.Conn, error) {
- if err := d.validateTarget(network, address); err != nil {
- proxy, dst, _ := d.pathAddrs(address)
- return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
- }
- var err error
- var c net.Conn
- if d.ProxyDial != nil {
- c, err = d.ProxyDial(context.Background(), d.proxyNetwork, d.proxyAddress)
- } else {
- c, err = net.Dial(d.proxyNetwork, d.proxyAddress)
- }
- if err != nil {
- proxy, dst, _ := d.pathAddrs(address)
- return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
- }
- if _, err := d.DialWithConn(context.Background(), c, network, address); err != nil {
- c.Close()
- return nil, err
- }
- return c, nil
-}
-
-func (d *socksDialer) validateTarget(network, address string) error {
- switch network {
- case "tcp", "tcp6", "tcp4":
- default:
- return errors.New("network not implemented")
- }
- switch d.cmd {
- case socksCmdConnect, sockscmdBind:
- default:
- return errors.New("command not implemented")
- }
- return nil
-}
-
-func (d *socksDialer) pathAddrs(address string) (proxy, dst net.Addr, err error) {
- for i, s := range []string{d.proxyAddress, address} {
- host, port, err := sockssplitHostPort(s)
- if err != nil {
- return nil, nil, err
- }
- a := &socksAddr{Port: port}
- a.IP = net.ParseIP(host)
- if a.IP == nil {
- a.Name = host
- }
- if i == 0 {
- proxy = a
- } else {
- dst = a
- }
- }
- return
-}
-
-// NewDialer returns a new Dialer that dials through the provided
-// proxy server's network and address.
-func socksNewDialer(network, address string) *socksDialer {
- return &socksDialer{proxyNetwork: network, proxyAddress: address, cmd: socksCmdConnect}
-}
-
-const (
- socksauthUsernamePasswordVersion = 0x01
- socksauthStatusSucceeded = 0x00
-)
-
-// UsernamePassword are the credentials for the username/password
-// authentication method.
-type socksUsernamePassword struct {
- Username string
- Password string
-}
-
-// Authenticate authenticates a pair of username and password with the
-// proxy server.
-func (up *socksUsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, auth socksAuthMethod) error {
- switch auth {
- case socksAuthMethodNotRequired:
- return nil
- case socksAuthMethodUsernamePassword:
- if len(up.Username) == 0 || len(up.Username) > 255 || len(up.Password) == 0 || len(up.Password) > 255 {
- return errors.New("invalid username/password")
- }
- b := []byte{socksauthUsernamePasswordVersion}
- b = append(b, byte(len(up.Username)))
- b = append(b, up.Username...)
- b = append(b, byte(len(up.Password)))
- b = append(b, up.Password...)
- // TODO(mikio): handle IO deadlines and cancelation if
- // necessary
- if _, err := rw.Write(b); err != nil {
- return err
- }
- if _, err := io.ReadFull(rw, b[:2]); err != nil {
- return err
- }
- if b[0] != socksauthUsernamePasswordVersion {
- return errors.New("invalid username/password version")
- }
- if b[1] != socksauthStatusSucceeded {
- return errors.New("username/password authentication failed")
- }
- return nil
- }
- return errors.New("unsupported authentication method " + strconv.Itoa(int(auth)))
-}
diff --git a/contrib/go/_std_1.20/src/net/http/transfer.go b/contrib/go/_std_1.20/src/net/http/transfer.go
deleted file mode 100644
index 7c7afd7de4..0000000000
--- a/contrib/go/_std_1.20/src/net/http/transfer.go
+++ /dev/null
@@ -1,1124 +0,0 @@
-// Copyright 2009 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 http
-
-import (
- "bufio"
- "bytes"
- "errors"
- "fmt"
- "io"
- "net/http/httptrace"
- "net/http/internal"
- "net/http/internal/ascii"
- "net/textproto"
- "reflect"
- "sort"
- "strconv"
- "strings"
- "sync"
- "time"
-
- "golang.org/x/net/http/httpguts"
-)
-
-// ErrLineTooLong is returned when reading request or response bodies
-// with malformed chunked encoding.
-var ErrLineTooLong = internal.ErrLineTooLong
-
-type errorReader struct {
- err error
-}
-
-func (r errorReader) Read(p []byte) (n int, err error) {
- return 0, r.err
-}
-
-type byteReader struct {
- b byte
- done bool
-}
-
-func (br *byteReader) Read(p []byte) (n int, err error) {
- if br.done {
- return 0, io.EOF
- }
- if len(p) == 0 {
- return 0, nil
- }
- br.done = true
- p[0] = br.b
- return 1, io.EOF
-}
-
-// transferWriter inspects the fields of a user-supplied Request or Response,
-// sanitizes them without changing the user object and provides methods for
-// writing the respective header, body and trailer in wire format.
-type transferWriter struct {
- Method string
- Body io.Reader
- BodyCloser io.Closer
- ResponseToHEAD bool
- ContentLength int64 // -1 means unknown, 0 means exactly none
- Close bool
- TransferEncoding []string
- Header Header
- Trailer Header
- IsResponse bool
- bodyReadError error // any non-EOF error from reading Body
-
- FlushHeaders bool // flush headers to network before body
- ByteReadCh chan readResult // non-nil if probeRequestBody called
-}
-
-func newTransferWriter(r any) (t *transferWriter, err error) {
- t = &transferWriter{}
-
- // Extract relevant fields
- atLeastHTTP11 := false
- switch rr := r.(type) {
- case *Request:
- if rr.ContentLength != 0 && rr.Body == nil {
- return nil, fmt.Errorf("http: Request.ContentLength=%d with nil Body", rr.ContentLength)
- }
- t.Method = valueOrDefault(rr.Method, "GET")
- t.Close = rr.Close
- t.TransferEncoding = rr.TransferEncoding
- t.Header = rr.Header
- t.Trailer = rr.Trailer
- t.Body = rr.Body
- t.BodyCloser = rr.Body
- t.ContentLength = rr.outgoingLength()
- if t.ContentLength < 0 && len(t.TransferEncoding) == 0 && t.shouldSendChunkedRequestBody() {
- t.TransferEncoding = []string{"chunked"}
- }
- // If there's a body, conservatively flush the headers
- // to any bufio.Writer we're writing to, just in case
- // the server needs the headers early, before we copy
- // the body and possibly block. We make an exception
- // for the common standard library in-memory types,
- // though, to avoid unnecessary TCP packets on the
- // wire. (Issue 22088.)
- if t.ContentLength != 0 && !isKnownInMemoryReader(t.Body) {
- t.FlushHeaders = true
- }
-
- atLeastHTTP11 = true // Transport requests are always 1.1 or 2.0
- case *Response:
- t.IsResponse = true
- if rr.Request != nil {
- t.Method = rr.Request.Method
- }
- t.Body = rr.Body
- t.BodyCloser = rr.Body
- t.ContentLength = rr.ContentLength
- t.Close = rr.Close
- t.TransferEncoding = rr.TransferEncoding
- t.Header = rr.Header
- t.Trailer = rr.Trailer
- atLeastHTTP11 = rr.ProtoAtLeast(1, 1)
- t.ResponseToHEAD = noResponseBodyExpected(t.Method)
- }
-
- // Sanitize Body,ContentLength,TransferEncoding
- if t.ResponseToHEAD {
- t.Body = nil
- if chunked(t.TransferEncoding) {
- t.ContentLength = -1
- }
- } else {
- if !atLeastHTTP11 || t.Body == nil {
- t.TransferEncoding = nil
- }
- if chunked(t.TransferEncoding) {
- t.ContentLength = -1
- } else if t.Body == nil { // no chunking, no body
- t.ContentLength = 0
- }
- }
-
- // Sanitize Trailer
- if !chunked(t.TransferEncoding) {
- t.Trailer = nil
- }
-
- return t, nil
-}
-
-// shouldSendChunkedRequestBody reports whether we should try to send a
-// chunked request body to the server. In particular, the case we really
-// want to prevent is sending a GET or other typically-bodyless request to a
-// server with a chunked body when the body has zero bytes, since GETs with
-// bodies (while acceptable according to specs), even zero-byte chunked
-// bodies, are approximately never seen in the wild and confuse most
-// servers. See Issue 18257, as one example.
-//
-// The only reason we'd send such a request is if the user set the Body to a
-// non-nil value (say, io.NopCloser(bytes.NewReader(nil))) and didn't
-// set ContentLength, or NewRequest set it to -1 (unknown), so then we assume
-// there's bytes to send.
-//
-// This code tries to read a byte from the Request.Body in such cases to see
-// whether the body actually has content (super rare) or is actually just
-// a non-nil content-less ReadCloser (the more common case). In that more
-// common case, we act as if their Body were nil instead, and don't send
-// a body.
-func (t *transferWriter) shouldSendChunkedRequestBody() bool {
- // Note that t.ContentLength is the corrected content length
- // from rr.outgoingLength, so 0 actually means zero, not unknown.
- if t.ContentLength >= 0 || t.Body == nil { // redundant checks; caller did them
- return false
- }
- if t.Method == "CONNECT" {
- return false
- }
- if requestMethodUsuallyLacksBody(t.Method) {
- // Only probe the Request.Body for GET/HEAD/DELETE/etc
- // requests, because it's only those types of requests
- // that confuse servers.
- t.probeRequestBody() // adjusts t.Body, t.ContentLength
- return t.Body != nil
- }
- // For all other request types (PUT, POST, PATCH, or anything
- // made-up we've never heard of), assume it's normal and the server
- // can deal with a chunked request body. Maybe we'll adjust this
- // later.
- return true
-}
-
-// probeRequestBody reads a byte from t.Body to see whether it's empty
-// (returns io.EOF right away).
-//
-// But because we've had problems with this blocking users in the past
-// (issue 17480) when the body is a pipe (perhaps waiting on the response
-// headers before the pipe is fed data), we need to be careful and bound how
-// long we wait for it. This delay will only affect users if all the following
-// are true:
-// - the request body blocks
-// - the content length is not set (or set to -1)
-// - the method doesn't usually have a body (GET, HEAD, DELETE, ...)
-// - there is no transfer-encoding=chunked already set.
-//
-// In other words, this delay will not normally affect anybody, and there
-// are workarounds if it does.
-func (t *transferWriter) probeRequestBody() {
- t.ByteReadCh = make(chan readResult, 1)
- go func(body io.Reader) {
- var buf [1]byte
- var rres readResult
- rres.n, rres.err = body.Read(buf[:])
- if rres.n == 1 {
- rres.b = buf[0]
- }
- t.ByteReadCh <- rres
- close(t.ByteReadCh)
- }(t.Body)
- timer := time.NewTimer(200 * time.Millisecond)
- select {
- case rres := <-t.ByteReadCh:
- timer.Stop()
- if rres.n == 0 && rres.err == io.EOF {
- // It was empty.
- t.Body = nil
- t.ContentLength = 0
- } else if rres.n == 1 {
- if rres.err != nil {
- t.Body = io.MultiReader(&byteReader{b: rres.b}, errorReader{rres.err})
- } else {
- t.Body = io.MultiReader(&byteReader{b: rres.b}, t.Body)
- }
- } else if rres.err != nil {
- t.Body = errorReader{rres.err}
- }
- case <-timer.C:
- // Too slow. Don't wait. Read it later, and keep
- // assuming that this is ContentLength == -1
- // (unknown), which means we'll send a
- // "Transfer-Encoding: chunked" header.
- t.Body = io.MultiReader(finishAsyncByteRead{t}, t.Body)
- // Request that Request.Write flush the headers to the
- // network before writing the body, since our body may not
- // become readable until it's seen the response headers.
- t.FlushHeaders = true
- }
-}
-
-func noResponseBodyExpected(requestMethod string) bool {
- return requestMethod == "HEAD"
-}
-
-func (t *transferWriter) shouldSendContentLength() bool {
- if chunked(t.TransferEncoding) {
- return false
- }
- if t.ContentLength > 0 {
- return true
- }
- if t.ContentLength < 0 {
- return false
- }
- // Many servers expect a Content-Length for these methods
- if t.Method == "POST" || t.Method == "PUT" || t.Method == "PATCH" {
- return true
- }
- if t.ContentLength == 0 && isIdentity(t.TransferEncoding) {
- if t.Method == "GET" || t.Method == "HEAD" {
- return false
- }
- return true
- }
-
- return false
-}
-
-func (t *transferWriter) writeHeader(w io.Writer, trace *httptrace.ClientTrace) error {
- if t.Close && !hasToken(t.Header.get("Connection"), "close") {
- if _, err := io.WriteString(w, "Connection: close\r\n"); err != nil {
- return err
- }
- if trace != nil && trace.WroteHeaderField != nil {
- trace.WroteHeaderField("Connection", []string{"close"})
- }
- }
-
- // Write Content-Length and/or Transfer-Encoding whose values are a
- // function of the sanitized field triple (Body, ContentLength,
- // TransferEncoding)
- if t.shouldSendContentLength() {
- if _, err := io.WriteString(w, "Content-Length: "); err != nil {
- return err
- }
- if _, err := io.WriteString(w, strconv.FormatInt(t.ContentLength, 10)+"\r\n"); err != nil {
- return err
- }
- if trace != nil && trace.WroteHeaderField != nil {
- trace.WroteHeaderField("Content-Length", []string{strconv.FormatInt(t.ContentLength, 10)})
- }
- } else if chunked(t.TransferEncoding) {
- if _, err := io.WriteString(w, "Transfer-Encoding: chunked\r\n"); err != nil {
- return err
- }
- if trace != nil && trace.WroteHeaderField != nil {
- trace.WroteHeaderField("Transfer-Encoding", []string{"chunked"})
- }
- }
-
- // Write Trailer header
- if t.Trailer != nil {
- keys := make([]string, 0, len(t.Trailer))
- for k := range t.Trailer {
- k = CanonicalHeaderKey(k)
- switch k {
- case "Transfer-Encoding", "Trailer", "Content-Length":
- return badStringError("invalid Trailer key", k)
- }
- keys = append(keys, k)
- }
- if len(keys) > 0 {
- sort.Strings(keys)
- // TODO: could do better allocation-wise here, but trailers are rare,
- // so being lazy for now.
- if _, err := io.WriteString(w, "Trailer: "+strings.Join(keys, ",")+"\r\n"); err != nil {
- return err
- }
- if trace != nil && trace.WroteHeaderField != nil {
- trace.WroteHeaderField("Trailer", keys)
- }
- }
- }
-
- return nil
-}
-
-// always closes t.BodyCloser
-func (t *transferWriter) writeBody(w io.Writer) (err error) {
- var ncopy int64
- closed := false
- defer func() {
- if closed || t.BodyCloser == nil {
- return
- }
- if closeErr := t.BodyCloser.Close(); closeErr != nil && err == nil {
- err = closeErr
- }
- }()
-
- // Write body. We "unwrap" the body first if it was wrapped in a
- // nopCloser or readTrackingBody. This is to ensure that we can take advantage of
- // OS-level optimizations in the event that the body is an
- // *os.File.
- if t.Body != nil {
- var body = t.unwrapBody()
- if chunked(t.TransferEncoding) {
- if bw, ok := w.(*bufio.Writer); ok && !t.IsResponse {
- w = &internal.FlushAfterChunkWriter{Writer: bw}
- }
- cw := internal.NewChunkedWriter(w)
- _, err = t.doBodyCopy(cw, body)
- if err == nil {
- err = cw.Close()
- }
- } else if t.ContentLength == -1 {
- dst := w
- if t.Method == "CONNECT" {
- dst = bufioFlushWriter{dst}
- }
- ncopy, err = t.doBodyCopy(dst, body)
- } else {
- ncopy, err = t.doBodyCopy(w, io.LimitReader(body, t.ContentLength))
- if err != nil {
- return err
- }
- var nextra int64
- nextra, err = t.doBodyCopy(io.Discard, body)
- ncopy += nextra
- }
- if err != nil {
- return err
- }
- }
- if t.BodyCloser != nil {
- closed = true
- if err := t.BodyCloser.Close(); err != nil {
- return err
- }
- }
-
- if !t.ResponseToHEAD && t.ContentLength != -1 && t.ContentLength != ncopy {
- return fmt.Errorf("http: ContentLength=%d with Body length %d",
- t.ContentLength, ncopy)
- }
-
- if chunked(t.TransferEncoding) {
- // Write Trailer header
- if t.Trailer != nil {
- if err := t.Trailer.Write(w); err != nil {
- return err
- }
- }
- // Last chunk, empty trailer
- _, err = io.WriteString(w, "\r\n")
- }
- return err
-}
-
-// doBodyCopy wraps a copy operation, with any resulting error also
-// being saved in bodyReadError.
-//
-// This function is only intended for use in writeBody.
-func (t *transferWriter) doBodyCopy(dst io.Writer, src io.Reader) (n int64, err error) {
- n, err = io.Copy(dst, src)
- if err != nil && err != io.EOF {
- t.bodyReadError = err
- }
- return
-}
-
-// unwrapBodyReader unwraps the body's inner reader if it's a
-// nopCloser. This is to ensure that body writes sourced from local
-// files (*os.File types) are properly optimized.
-//
-// This function is only intended for use in writeBody.
-func (t *transferWriter) unwrapBody() io.Reader {
- if r, ok := unwrapNopCloser(t.Body); ok {
- return r
- }
- if r, ok := t.Body.(*readTrackingBody); ok {
- r.didRead = true
- return r.ReadCloser
- }
- return t.Body
-}
-
-type transferReader struct {
- // Input
- Header Header
- StatusCode int
- RequestMethod string
- ProtoMajor int
- ProtoMinor int
- // Output
- Body io.ReadCloser
- ContentLength int64
- Chunked bool
- Close bool
- Trailer Header
-}
-
-func (t *transferReader) protoAtLeast(m, n int) bool {
- return t.ProtoMajor > m || (t.ProtoMajor == m && t.ProtoMinor >= n)
-}
-
-// bodyAllowedForStatus reports whether a given response status code
-// permits a body. See RFC 7230, section 3.3.
-func bodyAllowedForStatus(status int) bool {
- switch {
- case status >= 100 && status <= 199:
- return false
- case status == 204:
- return false
- case status == 304:
- return false
- }
- return true
-}
-
-var (
- suppressedHeaders304 = []string{"Content-Type", "Content-Length", "Transfer-Encoding"}
- suppressedHeadersNoBody = []string{"Content-Length", "Transfer-Encoding"}
- excludedHeadersNoBody = map[string]bool{"Content-Length": true, "Transfer-Encoding": true}
-)
-
-func suppressedHeaders(status int) []string {
- switch {
- case status == 304:
- // RFC 7232 section 4.1
- return suppressedHeaders304
- case !bodyAllowedForStatus(status):
- return suppressedHeadersNoBody
- }
- return nil
-}
-
-// msg is *Request or *Response.
-func readTransfer(msg any, r *bufio.Reader) (err error) {
- t := &transferReader{RequestMethod: "GET"}
-
- // Unify input
- isResponse := false
- switch rr := msg.(type) {
- case *Response:
- t.Header = rr.Header
- t.StatusCode = rr.StatusCode
- t.ProtoMajor = rr.ProtoMajor
- t.ProtoMinor = rr.ProtoMinor
- t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header, true)
- isResponse = true
- if rr.Request != nil {
- t.RequestMethod = rr.Request.Method
- }
- case *Request:
- t.Header = rr.Header
- t.RequestMethod = rr.Method
- t.ProtoMajor = rr.ProtoMajor
- t.ProtoMinor = rr.ProtoMinor
- // Transfer semantics for Requests are exactly like those for
- // Responses with status code 200, responding to a GET method
- t.StatusCode = 200
- t.Close = rr.Close
- default:
- panic("unexpected type")
- }
-
- // Default to HTTP/1.1
- if t.ProtoMajor == 0 && t.ProtoMinor == 0 {
- t.ProtoMajor, t.ProtoMinor = 1, 1
- }
-
- // Transfer-Encoding: chunked, and overriding Content-Length.
- if err := t.parseTransferEncoding(); err != nil {
- return err
- }
-
- realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.Chunked)
- if err != nil {
- return err
- }
- if isResponse && t.RequestMethod == "HEAD" {
- if n, err := parseContentLength(t.Header.get("Content-Length")); err != nil {
- return err
- } else {
- t.ContentLength = n
- }
- } else {
- t.ContentLength = realLength
- }
-
- // Trailer
- t.Trailer, err = fixTrailer(t.Header, t.Chunked)
- if err != nil {
- return err
- }
-
- // If there is no Content-Length or chunked Transfer-Encoding on a *Response
- // and the status is not 1xx, 204 or 304, then the body is unbounded.
- // See RFC 7230, section 3.3.
- switch msg.(type) {
- case *Response:
- if realLength == -1 && !t.Chunked && bodyAllowedForStatus(t.StatusCode) {
- // Unbounded body.
- t.Close = true
- }
- }
-
- // Prepare body reader. ContentLength < 0 means chunked encoding
- // or close connection when finished, since multipart is not supported yet
- switch {
- case t.Chunked:
- if isResponse && (noResponseBodyExpected(t.RequestMethod) || !bodyAllowedForStatus(t.StatusCode)) {
- t.Body = NoBody
- } else {
- t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close}
- }
- case realLength == 0:
- t.Body = NoBody
- case realLength > 0:
- t.Body = &body{src: io.LimitReader(r, realLength), closing: t.Close}
- default:
- // realLength < 0, i.e. "Content-Length" not mentioned in header
- if t.Close {
- // Close semantics (i.e. HTTP/1.0)
- t.Body = &body{src: r, closing: t.Close}
- } else {
- // Persistent connection (i.e. HTTP/1.1)
- t.Body = NoBody
- }
- }
-
- // Unify output
- switch rr := msg.(type) {
- case *Request:
- rr.Body = t.Body
- rr.ContentLength = t.ContentLength
- if t.Chunked {
- rr.TransferEncoding = []string{"chunked"}
- }
- rr.Close = t.Close
- rr.Trailer = t.Trailer
- case *Response:
- rr.Body = t.Body
- rr.ContentLength = t.ContentLength
- if t.Chunked {
- rr.TransferEncoding = []string{"chunked"}
- }
- rr.Close = t.Close
- rr.Trailer = t.Trailer
- }
-
- return nil
-}
-
-// Checks whether chunked is part of the encodings stack.
-func chunked(te []string) bool { return len(te) > 0 && te[0] == "chunked" }
-
-// Checks whether the encoding is explicitly "identity".
-func isIdentity(te []string) bool { return len(te) == 1 && te[0] == "identity" }
-
-// unsupportedTEError reports unsupported transfer-encodings.
-type unsupportedTEError struct {
- err string
-}
-
-func (uste *unsupportedTEError) Error() string {
- return uste.err
-}
-
-// isUnsupportedTEError checks if the error is of type
-// unsupportedTEError. It is usually invoked with a non-nil err.
-func isUnsupportedTEError(err error) bool {
- _, ok := err.(*unsupportedTEError)
- return ok
-}
-
-// parseTransferEncoding sets t.Chunked based on the Transfer-Encoding header.
-func (t *transferReader) parseTransferEncoding() error {
- raw, present := t.Header["Transfer-Encoding"]
- if !present {
- return nil
- }
- delete(t.Header, "Transfer-Encoding")
-
- // Issue 12785; ignore Transfer-Encoding on HTTP/1.0 requests.
- if !t.protoAtLeast(1, 1) {
- return nil
- }
-
- // Like nginx, we only support a single Transfer-Encoding header field, and
- // only if set to "chunked". This is one of the most security sensitive
- // surfaces in HTTP/1.1 due to the risk of request smuggling, so we keep it
- // strict and simple.
- if len(raw) != 1 {
- return &unsupportedTEError{fmt.Sprintf("too many transfer encodings: %q", raw)}
- }
- if !ascii.EqualFold(raw[0], "chunked") {
- return &unsupportedTEError{fmt.Sprintf("unsupported transfer encoding: %q", raw[0])}
- }
-
- // RFC 7230 3.3.2 says "A sender MUST NOT send a Content-Length header field
- // in any message that contains a Transfer-Encoding header field."
- //
- // but also: "If a message is received with both a Transfer-Encoding and a
- // Content-Length header field, the Transfer-Encoding overrides the
- // Content-Length. Such a message might indicate an attempt to perform
- // request smuggling (Section 9.5) or response splitting (Section 9.4) and
- // ought to be handled as an error. A sender MUST remove the received
- // Content-Length field prior to forwarding such a message downstream."
- //
- // Reportedly, these appear in the wild.
- delete(t.Header, "Content-Length")
-
- t.Chunked = true
- return nil
-}
-
-// Determine the expected body length, using RFC 7230 Section 3.3. This
-// function is not a method, because ultimately it should be shared by
-// ReadResponse and ReadRequest.
-func fixLength(isResponse bool, status int, requestMethod string, header Header, chunked bool) (int64, error) {
- isRequest := !isResponse
- contentLens := header["Content-Length"]
-
- // Hardening against HTTP request smuggling
- if len(contentLens) > 1 {
- // Per RFC 7230 Section 3.3.2, prevent multiple
- // Content-Length headers if they differ in value.
- // If there are dups of the value, remove the dups.
- // See Issue 16490.
- first := textproto.TrimString(contentLens[0])
- for _, ct := range contentLens[1:] {
- if first != textproto.TrimString(ct) {
- return 0, fmt.Errorf("http: message cannot contain multiple Content-Length headers; got %q", contentLens)
- }
- }
-
- // deduplicate Content-Length
- header.Del("Content-Length")
- header.Add("Content-Length", first)
-
- contentLens = header["Content-Length"]
- }
-
- // Logic based on response type or status
- if isResponse && noResponseBodyExpected(requestMethod) {
- return 0, nil
- }
- if status/100 == 1 {
- return 0, nil
- }
- switch status {
- case 204, 304:
- return 0, nil
- }
-
- // Logic based on Transfer-Encoding
- if chunked {
- return -1, nil
- }
-
- // Logic based on Content-Length
- var cl string
- if len(contentLens) == 1 {
- cl = textproto.TrimString(contentLens[0])
- }
- if cl != "" {
- n, err := parseContentLength(cl)
- if err != nil {
- return -1, err
- }
- return n, nil
- }
- header.Del("Content-Length")
-
- if isRequest {
- // RFC 7230 neither explicitly permits nor forbids an
- // entity-body on a GET request so we permit one if
- // declared, but we default to 0 here (not -1 below)
- // if there's no mention of a body.
- // Likewise, all other request methods are assumed to have
- // no body if neither Transfer-Encoding chunked nor a
- // Content-Length are set.
- return 0, nil
- }
-
- // Body-EOF logic based on other methods (like closing, or chunked coding)
- return -1, nil
-}
-
-// Determine whether to hang up after sending a request and body, or
-// receiving a response and body
-// 'header' is the request headers.
-func shouldClose(major, minor int, header Header, removeCloseHeader bool) bool {
- if major < 1 {
- return true
- }
-
- conv := header["Connection"]
- hasClose := httpguts.HeaderValuesContainsToken(conv, "close")
- if major == 1 && minor == 0 {
- return hasClose || !httpguts.HeaderValuesContainsToken(conv, "keep-alive")
- }
-
- if hasClose && removeCloseHeader {
- header.Del("Connection")
- }
-
- return hasClose
-}
-
-// Parse the trailer header.
-func fixTrailer(header Header, chunked bool) (Header, error) {
- vv, ok := header["Trailer"]
- if !ok {
- return nil, nil
- }
- if !chunked {
- // Trailer and no chunking:
- // this is an invalid use case for trailer header.
- // Nevertheless, no error will be returned and we
- // let users decide if this is a valid HTTP message.
- // The Trailer header will be kept in Response.Header
- // but not populate Response.Trailer.
- // See issue #27197.
- return nil, nil
- }
- header.Del("Trailer")
-
- trailer := make(Header)
- var err error
- for _, v := range vv {
- foreachHeaderElement(v, func(key string) {
- key = CanonicalHeaderKey(key)
- switch key {
- case "Transfer-Encoding", "Trailer", "Content-Length":
- if err == nil {
- err = badStringError("bad trailer key", key)
- return
- }
- }
- trailer[key] = nil
- })
- }
- if err != nil {
- return nil, err
- }
- if len(trailer) == 0 {
- return nil, nil
- }
- return trailer, nil
-}
-
-// body turns a Reader into a ReadCloser.
-// Close ensures that the body has been fully read
-// and then reads the trailer if necessary.
-type body struct {
- src io.Reader
- hdr any // non-nil (Response or Request) value means read trailer
- r *bufio.Reader // underlying wire-format reader for the trailer
- closing bool // is the connection to be closed after reading body?
- doEarlyClose bool // whether Close should stop early
-
- mu sync.Mutex // guards following, and calls to Read and Close
- sawEOF bool
- closed bool
- earlyClose bool // Close called and we didn't read to the end of src
- onHitEOF func() // if non-nil, func to call when EOF is Read
-}
-
-// ErrBodyReadAfterClose is returned when reading a Request or Response
-// Body after the body has been closed. This typically happens when the body is
-// read after an HTTP Handler calls WriteHeader or Write on its
-// ResponseWriter.
-var ErrBodyReadAfterClose = errors.New("http: invalid Read on closed Body")
-
-func (b *body) Read(p []byte) (n int, err error) {
- b.mu.Lock()
- defer b.mu.Unlock()
- if b.closed {
- return 0, ErrBodyReadAfterClose
- }
- return b.readLocked(p)
-}
-
-// Must hold b.mu.
-func (b *body) readLocked(p []byte) (n int, err error) {
- if b.sawEOF {
- return 0, io.EOF
- }
- n, err = b.src.Read(p)
-
- if err == io.EOF {
- b.sawEOF = true
- // Chunked case. Read the trailer.
- if b.hdr != nil {
- if e := b.readTrailer(); e != nil {
- err = e
- // Something went wrong in the trailer, we must not allow any
- // further reads of any kind to succeed from body, nor any
- // subsequent requests on the server connection. See
- // golang.org/issue/12027
- b.sawEOF = false
- b.closed = true
- }
- b.hdr = nil
- } else {
- // If the server declared the Content-Length, our body is a LimitedReader
- // and we need to check whether this EOF arrived early.
- if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > 0 {
- err = io.ErrUnexpectedEOF
- }
- }
- }
-
- // If we can return an EOF here along with the read data, do
- // so. This is optional per the io.Reader contract, but doing
- // so helps the HTTP transport code recycle its connection
- // earlier (since it will see this EOF itself), even if the
- // client doesn't do future reads or Close.
- if err == nil && n > 0 {
- if lr, ok := b.src.(*io.LimitedReader); ok && lr.N == 0 {
- err = io.EOF
- b.sawEOF = true
- }
- }
-
- if b.sawEOF && b.onHitEOF != nil {
- b.onHitEOF()
- }
-
- return n, err
-}
-
-var (
- singleCRLF = []byte("\r\n")
- doubleCRLF = []byte("\r\n\r\n")
-)
-
-func seeUpcomingDoubleCRLF(r *bufio.Reader) bool {
- for peekSize := 4; ; peekSize++ {
- // This loop stops when Peek returns an error,
- // which it does when r's buffer has been filled.
- buf, err := r.Peek(peekSize)
- if bytes.HasSuffix(buf, doubleCRLF) {
- return true
- }
- if err != nil {
- break
- }
- }
- return false
-}
-
-var errTrailerEOF = errors.New("http: unexpected EOF reading trailer")
-
-func (b *body) readTrailer() error {
- // The common case, since nobody uses trailers.
- buf, err := b.r.Peek(2)
- if bytes.Equal(buf, singleCRLF) {
- b.r.Discard(2)
- return nil
- }
- if len(buf) < 2 {
- return errTrailerEOF
- }
- if err != nil {
- return err
- }
-
- // Make sure there's a header terminator coming up, to prevent
- // a DoS with an unbounded size Trailer. It's not easy to
- // slip in a LimitReader here, as textproto.NewReader requires
- // a concrete *bufio.Reader. Also, we can't get all the way
- // back up to our conn's LimitedReader that *might* be backing
- // this bufio.Reader. Instead, a hack: we iteratively Peek up
- // to the bufio.Reader's max size, looking for a double CRLF.
- // This limits the trailer to the underlying buffer size, typically 4kB.
- if !seeUpcomingDoubleCRLF(b.r) {
- return errors.New("http: suspiciously long trailer after chunked body")
- }
-
- hdr, err := textproto.NewReader(b.r).ReadMIMEHeader()
- if err != nil {
- if err == io.EOF {
- return errTrailerEOF
- }
- return err
- }
- switch rr := b.hdr.(type) {
- case *Request:
- mergeSetHeader(&rr.Trailer, Header(hdr))
- case *Response:
- mergeSetHeader(&rr.Trailer, Header(hdr))
- }
- return nil
-}
-
-func mergeSetHeader(dst *Header, src Header) {
- if *dst == nil {
- *dst = src
- return
- }
- for k, vv := range src {
- (*dst)[k] = vv
- }
-}
-
-// unreadDataSizeLocked returns the number of bytes of unread input.
-// It returns -1 if unknown.
-// b.mu must be held.
-func (b *body) unreadDataSizeLocked() int64 {
- if lr, ok := b.src.(*io.LimitedReader); ok {
- return lr.N
- }
- return -1
-}
-
-func (b *body) Close() error {
- b.mu.Lock()
- defer b.mu.Unlock()
- if b.closed {
- return nil
- }
- var err error
- switch {
- case b.sawEOF:
- // Already saw EOF, so no need going to look for it.
- case b.hdr == nil && b.closing:
- // no trailer and closing the connection next.
- // no point in reading to EOF.
- case b.doEarlyClose:
- // Read up to maxPostHandlerReadBytes bytes of the body, looking
- // for EOF (and trailers), so we can re-use this connection.
- if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > maxPostHandlerReadBytes {
- // There was a declared Content-Length, and we have more bytes remaining
- // than our maxPostHandlerReadBytes tolerance. So, give up.
- b.earlyClose = true
- } else {
- var n int64
- // Consume the body, or, which will also lead to us reading
- // the trailer headers after the body, if present.
- n, err = io.CopyN(io.Discard, bodyLocked{b}, maxPostHandlerReadBytes)
- if err == io.EOF {
- err = nil
- }
- if n == maxPostHandlerReadBytes {
- b.earlyClose = true
- }
- }
- default:
- // Fully consume the body, which will also lead to us reading
- // the trailer headers after the body, if present.
- _, err = io.Copy(io.Discard, bodyLocked{b})
- }
- b.closed = true
- return err
-}
-
-func (b *body) didEarlyClose() bool {
- b.mu.Lock()
- defer b.mu.Unlock()
- return b.earlyClose
-}
-
-// bodyRemains reports whether future Read calls might
-// yield data.
-func (b *body) bodyRemains() bool {
- b.mu.Lock()
- defer b.mu.Unlock()
- return !b.sawEOF
-}
-
-func (b *body) registerOnHitEOF(fn func()) {
- b.mu.Lock()
- defer b.mu.Unlock()
- b.onHitEOF = fn
-}
-
-// bodyLocked is an io.Reader reading from a *body when its mutex is
-// already held.
-type bodyLocked struct {
- b *body
-}
-
-func (bl bodyLocked) Read(p []byte) (n int, err error) {
- if bl.b.closed {
- return 0, ErrBodyReadAfterClose
- }
- return bl.b.readLocked(p)
-}
-
-// parseContentLength trims whitespace from s and returns -1 if no value
-// is set, or the value if it's >= 0.
-func parseContentLength(cl string) (int64, error) {
- cl = textproto.TrimString(cl)
- if cl == "" {
- return -1, nil
- }
- n, err := strconv.ParseUint(cl, 10, 63)
- if err != nil {
- return 0, badStringError("bad Content-Length", cl)
- }
- return int64(n), nil
-
-}
-
-// finishAsyncByteRead finishes reading the 1-byte sniff
-// from the ContentLength==0, Body!=nil case.
-type finishAsyncByteRead struct {
- tw *transferWriter
-}
-
-func (fr finishAsyncByteRead) Read(p []byte) (n int, err error) {
- if len(p) == 0 {
- return
- }
- rres := <-fr.tw.ByteReadCh
- n, err = rres.n, rres.err
- if n == 1 {
- p[0] = rres.b
- }
- if err == nil {
- err = io.EOF
- }
- return
-}
-
-var nopCloserType = reflect.TypeOf(io.NopCloser(nil))
-var nopCloserWriterToType = reflect.TypeOf(io.NopCloser(struct {
- io.Reader
- io.WriterTo
-}{}))
-
-// unwrapNopCloser return the underlying reader and true if r is a NopCloser
-// else it return false.
-func unwrapNopCloser(r io.Reader) (underlyingReader io.Reader, isNopCloser bool) {
- switch reflect.TypeOf(r) {
- case nopCloserType, nopCloserWriterToType:
- return reflect.ValueOf(r).Field(0).Interface().(io.Reader), true
- default:
- return nil, false
- }
-}
-
-// isKnownInMemoryReader reports whether r is a type known to not
-// block on Read. Its caller uses this as an optional optimization to
-// send fewer TCP packets.
-func isKnownInMemoryReader(r io.Reader) bool {
- switch r.(type) {
- case *bytes.Reader, *bytes.Buffer, *strings.Reader:
- return true
- }
- if r, ok := unwrapNopCloser(r); ok {
- return isKnownInMemoryReader(r)
- }
- if r, ok := r.(*readTrackingBody); ok {
- return isKnownInMemoryReader(r.ReadCloser)
- }
- return false
-}
-
-// bufioFlushWriter is an io.Writer wrapper that flushes all writes
-// on its wrapped writer if it's a *bufio.Writer.
-type bufioFlushWriter struct{ w io.Writer }
-
-func (fw bufioFlushWriter) Write(p []byte) (n int, err error) {
- n, err = fw.w.Write(p)
- if bw, ok := fw.w.(*bufio.Writer); n > 0 && ok {
- ferr := bw.Flush()
- if ferr != nil && err == nil {
- err = ferr
- }
- }
- return
-}
diff --git a/contrib/go/_std_1.20/src/net/http/transport.go b/contrib/go/_std_1.20/src/net/http/transport.go
deleted file mode 100644
index ddcb64815c..0000000000
--- a/contrib/go/_std_1.20/src/net/http/transport.go
+++ /dev/null
@@ -1,2924 +0,0 @@
-// Copyright 2011 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.
-
-// HTTP client implementation. See RFC 7230 through 7235.
-//
-// This is the low-level Transport implementation of RoundTripper.
-// The high-level interface is in client.go.
-
-package http
-
-import (
- "bufio"
- "compress/gzip"
- "container/list"
- "context"
- "crypto/tls"
- "errors"
- "fmt"
- "internal/godebug"
- "io"
- "log"
- "net"
- "net/http/httptrace"
- "net/http/internal/ascii"
- "net/textproto"
- "net/url"
- "reflect"
- "strings"
- "sync"
- "sync/atomic"
- "time"
-
- "golang.org/x/net/http/httpguts"
- "golang.org/x/net/http/httpproxy"
-)
-
-// DefaultTransport is the default implementation of Transport and is
-// used by DefaultClient. It establishes network connections as needed
-// and caches them for reuse by subsequent calls. It uses HTTP proxies
-// as directed by the environment variables HTTP_PROXY, HTTPS_PROXY
-// and NO_PROXY (or the lowercase versions thereof).
-var DefaultTransport RoundTripper = &Transport{
- Proxy: ProxyFromEnvironment,
- DialContext: defaultTransportDialContext(&net.Dialer{
- Timeout: 30 * time.Second,
- KeepAlive: 30 * time.Second,
- }),
- ForceAttemptHTTP2: true,
- MaxIdleConns: 100,
- IdleConnTimeout: 90 * time.Second,
- TLSHandshakeTimeout: 10 * time.Second,
- ExpectContinueTimeout: 1 * time.Second,
-}
-
-// DefaultMaxIdleConnsPerHost is the default value of Transport's
-// MaxIdleConnsPerHost.
-const DefaultMaxIdleConnsPerHost = 2
-
-// Transport is an implementation of RoundTripper that supports HTTP,
-// HTTPS, and HTTP proxies (for either HTTP or HTTPS with CONNECT).
-//
-// By default, Transport caches connections for future re-use.
-// This may leave many open connections when accessing many hosts.
-// This behavior can be managed using Transport's CloseIdleConnections method
-// and the MaxIdleConnsPerHost and DisableKeepAlives fields.
-//
-// Transports should be reused instead of created as needed.
-// Transports are safe for concurrent use by multiple goroutines.
-//
-// A Transport is a low-level primitive for making HTTP and HTTPS requests.
-// For high-level functionality, such as cookies and redirects, see Client.
-//
-// Transport uses HTTP/1.1 for HTTP URLs and either HTTP/1.1 or HTTP/2
-// for HTTPS URLs, depending on whether the server supports HTTP/2,
-// and how the Transport is configured. The DefaultTransport supports HTTP/2.
-// To explicitly enable HTTP/2 on a transport, use golang.org/x/net/http2
-// and call ConfigureTransport. See the package docs for more about HTTP/2.
-//
-// Responses with status codes in the 1xx range are either handled
-// automatically (100 expect-continue) or ignored. The one
-// exception is HTTP status code 101 (Switching Protocols), which is
-// considered a terminal status and returned by RoundTrip. To see the
-// ignored 1xx responses, use the httptrace trace package's
-// ClientTrace.Got1xxResponse.
-//
-// Transport only retries a request upon encountering a network error
-// if the request is idempotent and either has no body or has its
-// Request.GetBody defined. HTTP requests are considered idempotent if
-// they have HTTP methods GET, HEAD, OPTIONS, or TRACE; or if their
-// Header map contains an "Idempotency-Key" or "X-Idempotency-Key"
-// entry. If the idempotency key value is a zero-length slice, the
-// request is treated as idempotent but the header is not sent on the
-// wire.
-type Transport struct {
- idleMu sync.Mutex
- closeIdle bool // user has requested to close all idle conns
- idleConn map[connectMethodKey][]*persistConn // most recently used at end
- idleConnWait map[connectMethodKey]wantConnQueue // waiting getConns
- idleLRU connLRU
-
- reqMu sync.Mutex
- reqCanceler map[cancelKey]func(error)
-
- altMu sync.Mutex // guards changing altProto only
- altProto atomic.Value // of nil or map[string]RoundTripper, key is URI scheme
-
- connsPerHostMu sync.Mutex
- connsPerHost map[connectMethodKey]int
- connsPerHostWait map[connectMethodKey]wantConnQueue // waiting getConns
-
- // Proxy specifies a function to return a proxy for a given
- // Request. If the function returns a non-nil error, the
- // request is aborted with the provided error.
- //
- // The proxy type is determined by the URL scheme. "http",
- // "https", and "socks5" are supported. If the scheme is empty,
- // "http" is assumed.
- //
- // If Proxy is nil or returns a nil *URL, no proxy is used.
- Proxy func(*Request) (*url.URL, error)
-
- // OnProxyConnectResponse is called when the Transport gets an HTTP response from
- // a proxy for a CONNECT request. It's called before the check for a 200 OK response.
- // If it returns an error, the request fails with that error.
- OnProxyConnectResponse func(ctx context.Context, proxyURL *url.URL, connectReq *Request, connectRes *Response) error
-
- // DialContext specifies the dial function for creating unencrypted TCP connections.
- // If DialContext is nil (and the deprecated Dial below is also nil),
- // then the transport dials using package net.
- //
- // DialContext runs concurrently with calls to RoundTrip.
- // A RoundTrip call that initiates a dial may end up using
- // a connection dialed previously when the earlier connection
- // becomes idle before the later DialContext completes.
- DialContext func(ctx context.Context, network, addr string) (net.Conn, error)
-
- // Dial specifies the dial function for creating unencrypted TCP connections.
- //
- // Dial runs concurrently with calls to RoundTrip.
- // A RoundTrip call that initiates a dial may end up using
- // a connection dialed previously when the earlier connection
- // becomes idle before the later Dial completes.
- //
- // Deprecated: Use DialContext instead, which allows the transport
- // to cancel dials as soon as they are no longer needed.
- // If both are set, DialContext takes priority.
- Dial func(network, addr string) (net.Conn, error)
-
- // DialTLSContext specifies an optional dial function for creating
- // TLS connections for non-proxied HTTPS requests.
- //
- // If DialTLSContext is nil (and the deprecated DialTLS below is also nil),
- // DialContext and TLSClientConfig are used.
- //
- // If DialTLSContext is set, the Dial and DialContext hooks are not used for HTTPS
- // requests and the TLSClientConfig and TLSHandshakeTimeout
- // are ignored. The returned net.Conn is assumed to already be
- // past the TLS handshake.
- DialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)
-
- // DialTLS specifies an optional dial function for creating
- // TLS connections for non-proxied HTTPS requests.
- //
- // Deprecated: Use DialTLSContext instead, which allows the transport
- // to cancel dials as soon as they are no longer needed.
- // If both are set, DialTLSContext takes priority.
- DialTLS func(network, addr string) (net.Conn, error)
-
- // TLSClientConfig specifies the TLS configuration to use with
- // tls.Client.
- // If nil, the default configuration is used.
- // If non-nil, HTTP/2 support may not be enabled by default.
- TLSClientConfig *tls.Config
-
- // TLSHandshakeTimeout specifies the maximum amount of time waiting to
- // wait for a TLS handshake. Zero means no timeout.
- TLSHandshakeTimeout time.Duration
-
- // DisableKeepAlives, if true, disables HTTP keep-alives and
- // will only use the connection to the server for a single
- // HTTP request.
- //
- // This is unrelated to the similarly named TCP keep-alives.
- DisableKeepAlives bool
-
- // DisableCompression, if true, prevents the Transport from
- // requesting compression with an "Accept-Encoding: gzip"
- // request header when the Request contains no existing
- // Accept-Encoding value. If the Transport requests gzip on
- // its own and gets a gzipped response, it's transparently
- // decoded in the Response.Body. However, if the user
- // explicitly requested gzip it is not automatically
- // uncompressed.
- DisableCompression bool
-
- // MaxIdleConns controls the maximum number of idle (keep-alive)
- // connections across all hosts. Zero means no limit.
- MaxIdleConns int
-
- // MaxIdleConnsPerHost, if non-zero, controls the maximum idle
- // (keep-alive) connections to keep per-host. If zero,
- // DefaultMaxIdleConnsPerHost is used.
- MaxIdleConnsPerHost int
-
- // MaxConnsPerHost optionally limits the total number of
- // connections per host, including connections in the dialing,
- // active, and idle states. On limit violation, dials will block.
- //
- // Zero means no limit.
- MaxConnsPerHost int
-
- // IdleConnTimeout is the maximum amount of time an idle
- // (keep-alive) connection will remain idle before closing
- // itself.
- // Zero means no limit.
- IdleConnTimeout time.Duration
-
- // ResponseHeaderTimeout, if non-zero, specifies the amount of
- // time to wait for a server's response headers after fully
- // writing the request (including its body, if any). This
- // time does not include the time to read the response body.
- ResponseHeaderTimeout time.Duration
-
- // ExpectContinueTimeout, if non-zero, specifies the amount of
- // time to wait for a server's first response headers after fully
- // writing the request headers if the request has an
- // "Expect: 100-continue" header. Zero means no timeout and
- // causes the body to be sent immediately, without
- // waiting for the server to approve.
- // This time does not include the time to send the request header.
- ExpectContinueTimeout time.Duration
-
- // TLSNextProto specifies how the Transport switches to an
- // alternate protocol (such as HTTP/2) after a TLS ALPN
- // protocol negotiation. If Transport dials an TLS connection
- // with a non-empty protocol name and TLSNextProto contains a
- // map entry for that key (such as "h2"), then the func is
- // called with the request's authority (such as "example.com"
- // or "example.com:1234") and the TLS connection. The function
- // must return a RoundTripper that then handles the request.
- // If TLSNextProto is not nil, HTTP/2 support is not enabled
- // automatically.
- TLSNextProto map[string]func(authority string, c *tls.Conn) RoundTripper
-
- // ProxyConnectHeader optionally specifies headers to send to
- // proxies during CONNECT requests.
- // To set the header dynamically, see GetProxyConnectHeader.
- ProxyConnectHeader Header
-
- // GetProxyConnectHeader optionally specifies a func to return
- // headers to send to proxyURL during a CONNECT request to the
- // ip:port target.
- // If it returns an error, the Transport's RoundTrip fails with
- // that error. It can return (nil, nil) to not add headers.
- // If GetProxyConnectHeader is non-nil, ProxyConnectHeader is
- // ignored.
- GetProxyConnectHeader func(ctx context.Context, proxyURL *url.URL, target string) (Header, error)
-
- // MaxResponseHeaderBytes specifies a limit on how many
- // response bytes are allowed in the server's response
- // header.
- //
- // Zero means to use a default limit.
- MaxResponseHeaderBytes int64
-
- // WriteBufferSize specifies the size of the write buffer used
- // when writing to the transport.
- // If zero, a default (currently 4KB) is used.
- WriteBufferSize int
-
- // ReadBufferSize specifies the size of the read buffer used
- // when reading from the transport.
- // If zero, a default (currently 4KB) is used.
- ReadBufferSize int
-
- // nextProtoOnce guards initialization of TLSNextProto and
- // h2transport (via onceSetNextProtoDefaults)
- nextProtoOnce sync.Once
- h2transport h2Transport // non-nil if http2 wired up
- tlsNextProtoWasNil bool // whether TLSNextProto was nil when the Once fired
-
- // ForceAttemptHTTP2 controls whether HTTP/2 is enabled when a non-zero
- // Dial, DialTLS, or DialContext func or TLSClientConfig is provided.
- // By default, use of any those fields conservatively disables HTTP/2.
- // To use a custom dialer or TLS config and still attempt HTTP/2
- // upgrades, set this to true.
- ForceAttemptHTTP2 bool
-}
-
-// A cancelKey is the key of the reqCanceler map.
-// We wrap the *Request in this type since we want to use the original request,
-// not any transient one created by roundTrip.
-type cancelKey struct {
- req *Request
-}
-
-func (t *Transport) writeBufferSize() int {
- if t.WriteBufferSize > 0 {
- return t.WriteBufferSize
- }
- return 4 << 10
-}
-
-func (t *Transport) readBufferSize() int {
- if t.ReadBufferSize > 0 {
- return t.ReadBufferSize
- }
- return 4 << 10
-}
-
-// Clone returns a deep copy of t's exported fields.
-func (t *Transport) Clone() *Transport {
- t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
- t2 := &Transport{
- Proxy: t.Proxy,
- OnProxyConnectResponse: t.OnProxyConnectResponse,
- DialContext: t.DialContext,
- Dial: t.Dial,
- DialTLS: t.DialTLS,
- DialTLSContext: t.DialTLSContext,
- TLSHandshakeTimeout: t.TLSHandshakeTimeout,
- DisableKeepAlives: t.DisableKeepAlives,
- DisableCompression: t.DisableCompression,
- MaxIdleConns: t.MaxIdleConns,
- MaxIdleConnsPerHost: t.MaxIdleConnsPerHost,
- MaxConnsPerHost: t.MaxConnsPerHost,
- IdleConnTimeout: t.IdleConnTimeout,
- ResponseHeaderTimeout: t.ResponseHeaderTimeout,
- ExpectContinueTimeout: t.ExpectContinueTimeout,
- ProxyConnectHeader: t.ProxyConnectHeader.Clone(),
- GetProxyConnectHeader: t.GetProxyConnectHeader,
- MaxResponseHeaderBytes: t.MaxResponseHeaderBytes,
- ForceAttemptHTTP2: t.ForceAttemptHTTP2,
- WriteBufferSize: t.WriteBufferSize,
- ReadBufferSize: t.ReadBufferSize,
- }
- if t.TLSClientConfig != nil {
- t2.TLSClientConfig = t.TLSClientConfig.Clone()
- }
- if !t.tlsNextProtoWasNil {
- npm := map[string]func(authority string, c *tls.Conn) RoundTripper{}
- for k, v := range t.TLSNextProto {
- npm[k] = v
- }
- t2.TLSNextProto = npm
- }
- return t2
-}
-
-// h2Transport is the interface we expect to be able to call from
-// net/http against an *http2.Transport that's either bundled into
-// h2_bundle.go or supplied by the user via x/net/http2.
-//
-// We name it with the "h2" prefix to stay out of the "http2" prefix
-// namespace used by x/tools/cmd/bundle for h2_bundle.go.
-type h2Transport interface {
- CloseIdleConnections()
-}
-
-func (t *Transport) hasCustomTLSDialer() bool {
- return t.DialTLS != nil || t.DialTLSContext != nil
-}
-
-var http2client = godebug.New("http2client")
-
-// onceSetNextProtoDefaults initializes TLSNextProto.
-// It must be called via t.nextProtoOnce.Do.
-func (t *Transport) onceSetNextProtoDefaults() {
- t.tlsNextProtoWasNil = (t.TLSNextProto == nil)
- if http2client.Value() == "0" {
- return
- }
-
- // If they've already configured http2 with
- // golang.org/x/net/http2 instead of the bundled copy, try to
- // get at its http2.Transport value (via the "https"
- // altproto map) so we can call CloseIdleConnections on it if
- // requested. (Issue 22891)
- altProto, _ := t.altProto.Load().(map[string]RoundTripper)
- if rv := reflect.ValueOf(altProto["https"]); rv.IsValid() && rv.Type().Kind() == reflect.Struct && rv.Type().NumField() == 1 {
- if v := rv.Field(0); v.CanInterface() {
- if h2i, ok := v.Interface().(h2Transport); ok {
- t.h2transport = h2i
- return
- }
- }
- }
-
- if t.TLSNextProto != nil {
- // This is the documented way to disable http2 on a
- // Transport.
- return
- }
- if !t.ForceAttemptHTTP2 && (t.TLSClientConfig != nil || t.Dial != nil || t.DialContext != nil || t.hasCustomTLSDialer()) {
- // Be conservative and don't automatically enable
- // http2 if they've specified a custom TLS config or
- // custom dialers. Let them opt-in themselves via
- // http2.ConfigureTransport so we don't surprise them
- // by modifying their tls.Config. Issue 14275.
- // However, if ForceAttemptHTTP2 is true, it overrides the above checks.
- return
- }
- if omitBundledHTTP2 {
- return
- }
- t2, err := http2configureTransports(t)
- if err != nil {
- log.Printf("Error enabling Transport HTTP/2 support: %v", err)
- return
- }
- t.h2transport = t2
-
- // Auto-configure the http2.Transport's MaxHeaderListSize from
- // the http.Transport's MaxResponseHeaderBytes. They don't
- // exactly mean the same thing, but they're close.
- //
- // TODO: also add this to x/net/http2.Configure Transport, behind
- // a +build go1.7 build tag:
- if limit1 := t.MaxResponseHeaderBytes; limit1 != 0 && t2.MaxHeaderListSize == 0 {
- const h2max = 1<<32 - 1
- if limit1 >= h2max {
- t2.MaxHeaderListSize = h2max
- } else {
- t2.MaxHeaderListSize = uint32(limit1)
- }
- }
-}
-
-// ProxyFromEnvironment returns the URL of the proxy to use for a
-// given request, as indicated by the environment variables
-// HTTP_PROXY, HTTPS_PROXY and NO_PROXY (or the lowercase versions
-// thereof). Requests use the proxy from the environment variable
-// matching their scheme, unless excluded by NO_PROXY.
-//
-// The environment values may be either a complete URL or a
-// "host[:port]", in which case the "http" scheme is assumed.
-// The schemes "http", "https", and "socks5" are supported.
-// An error is returned if the value is a different form.
-//
-// A nil URL and nil error are returned if no proxy is defined in the
-// environment, or a proxy should not be used for the given request,
-// as defined by NO_PROXY.
-//
-// As a special case, if req.URL.Host is "localhost" (with or without
-// a port number), then a nil URL and nil error will be returned.
-func ProxyFromEnvironment(req *Request) (*url.URL, error) {
- return envProxyFunc()(req.URL)
-}
-
-// ProxyURL returns a proxy function (for use in a Transport)
-// that always returns the same URL.
-func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error) {
- return func(*Request) (*url.URL, error) {
- return fixedURL, nil
- }
-}
-
-// transportRequest is a wrapper around a *Request that adds
-// optional extra headers to write and stores any error to return
-// from roundTrip.
-type transportRequest struct {
- *Request // original request, not to be mutated
- extra Header // extra headers to write, or nil
- trace *httptrace.ClientTrace // optional
- cancelKey cancelKey
-
- mu sync.Mutex // guards err
- err error // first setError value for mapRoundTripError to consider
-}
-
-func (tr *transportRequest) extraHeaders() Header {
- if tr.extra == nil {
- tr.extra = make(Header)
- }
- return tr.extra
-}
-
-func (tr *transportRequest) setError(err error) {
- tr.mu.Lock()
- if tr.err == nil {
- tr.err = err
- }
- tr.mu.Unlock()
-}
-
-// useRegisteredProtocol reports whether an alternate protocol (as registered
-// with Transport.RegisterProtocol) should be respected for this request.
-func (t *Transport) useRegisteredProtocol(req *Request) bool {
- if req.URL.Scheme == "https" && req.requiresHTTP1() {
- // If this request requires HTTP/1, don't use the
- // "https" alternate protocol, which is used by the
- // HTTP/2 code to take over requests if there's an
- // existing cached HTTP/2 connection.
- return false
- }
- return true
-}
-
-// alternateRoundTripper returns the alternate RoundTripper to use
-// for this request if the Request's URL scheme requires one,
-// or nil for the normal case of using the Transport.
-func (t *Transport) alternateRoundTripper(req *Request) RoundTripper {
- if !t.useRegisteredProtocol(req) {
- return nil
- }
- altProto, _ := t.altProto.Load().(map[string]RoundTripper)
- return altProto[req.URL.Scheme]
-}
-
-// roundTrip implements a RoundTripper over HTTP.
-func (t *Transport) roundTrip(req *Request) (*Response, error) {
- t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
- ctx := req.Context()
- trace := httptrace.ContextClientTrace(ctx)
-
- if req.URL == nil {
- req.closeBody()
- return nil, errors.New("http: nil Request.URL")
- }
- if req.Header == nil {
- req.closeBody()
- return nil, errors.New("http: nil Request.Header")
- }
- scheme := req.URL.Scheme
- isHTTP := scheme == "http" || scheme == "https"
- if isHTTP {
- for k, vv := range req.Header {
- if !httpguts.ValidHeaderFieldName(k) {
- req.closeBody()
- return nil, fmt.Errorf("net/http: invalid header field name %q", k)
- }
- for _, v := range vv {
- if !httpguts.ValidHeaderFieldValue(v) {
- req.closeBody()
- // Don't include the value in the error, because it may be sensitive.
- return nil, fmt.Errorf("net/http: invalid header field value for %q", k)
- }
- }
- }
- }
-
- origReq := req
- cancelKey := cancelKey{origReq}
- req = setupRewindBody(req)
-
- if altRT := t.alternateRoundTripper(req); altRT != nil {
- if resp, err := altRT.RoundTrip(req); err != ErrSkipAltProtocol {
- return resp, err
- }
- var err error
- req, err = rewindBody(req)
- if err != nil {
- return nil, err
- }
- }
- if !isHTTP {
- req.closeBody()
- return nil, badStringError("unsupported protocol scheme", scheme)
- }
- if req.Method != "" && !validMethod(req.Method) {
- req.closeBody()
- return nil, fmt.Errorf("net/http: invalid method %q", req.Method)
- }
- if req.URL.Host == "" {
- req.closeBody()
- return nil, errors.New("http: no Host in request URL")
- }
-
- for {
- select {
- case <-ctx.Done():
- req.closeBody()
- return nil, ctx.Err()
- default:
- }
-
- // treq gets modified by roundTrip, so we need to recreate for each retry.
- treq := &transportRequest{Request: req, trace: trace, cancelKey: cancelKey}
- cm, err := t.connectMethodForRequest(treq)
- if err != nil {
- req.closeBody()
- return nil, err
- }
-
- // Get the cached or newly-created connection to either the
- // host (for http or https), the http proxy, or the http proxy
- // pre-CONNECTed to https server. In any case, we'll be ready
- // to send it requests.
- pconn, err := t.getConn(treq, cm)
- if err != nil {
- t.setReqCanceler(cancelKey, nil)
- req.closeBody()
- return nil, err
- }
-
- var resp *Response
- if pconn.alt != nil {
- // HTTP/2 path.
- t.setReqCanceler(cancelKey, nil) // not cancelable with CancelRequest
- resp, err = pconn.alt.RoundTrip(req)
- } else {
- resp, err = pconn.roundTrip(treq)
- }
- if err == nil {
- resp.Request = origReq
- return resp, nil
- }
-
- // Failed. Clean up and determine whether to retry.
- if http2isNoCachedConnError(err) {
- if t.removeIdleConn(pconn) {
- t.decConnsPerHost(pconn.cacheKey)
- }
- } else if !pconn.shouldRetryRequest(req, err) {
- // Issue 16465: return underlying net.Conn.Read error from peek,
- // as we've historically done.
- if e, ok := err.(nothingWrittenError); ok {
- err = e.error
- }
- if e, ok := err.(transportReadFromServerError); ok {
- err = e.err
- }
- return nil, err
- }
- testHookRoundTripRetried()
-
- // Rewind the body if we're able to.
- req, err = rewindBody(req)
- if err != nil {
- return nil, err
- }
- }
-}
-
-var errCannotRewind = errors.New("net/http: cannot rewind body after connection loss")
-
-type readTrackingBody struct {
- io.ReadCloser
- didRead bool
- didClose bool
-}
-
-func (r *readTrackingBody) Read(data []byte) (int, error) {
- r.didRead = true
- return r.ReadCloser.Read(data)
-}
-
-func (r *readTrackingBody) Close() error {
- r.didClose = true
- return r.ReadCloser.Close()
-}
-
-// setupRewindBody returns a new request with a custom body wrapper
-// that can report whether the body needs rewinding.
-// This lets rewindBody avoid an error result when the request
-// does not have GetBody but the body hasn't been read at all yet.
-func setupRewindBody(req *Request) *Request {
- if req.Body == nil || req.Body == NoBody {
- return req
- }
- newReq := *req
- newReq.Body = &readTrackingBody{ReadCloser: req.Body}
- return &newReq
-}
-
-// rewindBody returns a new request with the body rewound.
-// It returns req unmodified if the body does not need rewinding.
-// rewindBody takes care of closing req.Body when appropriate
-// (in all cases except when rewindBody returns req unmodified).
-func rewindBody(req *Request) (rewound *Request, err error) {
- if req.Body == nil || req.Body == NoBody || (!req.Body.(*readTrackingBody).didRead && !req.Body.(*readTrackingBody).didClose) {
- return req, nil // nothing to rewind
- }
- if !req.Body.(*readTrackingBody).didClose {
- req.closeBody()
- }
- if req.GetBody == nil {
- return nil, errCannotRewind
- }
- body, err := req.GetBody()
- if err != nil {
- return nil, err
- }
- newReq := *req
- newReq.Body = &readTrackingBody{ReadCloser: body}
- return &newReq, nil
-}
-
-// shouldRetryRequest reports whether we should retry sending a failed
-// HTTP request on a new connection. The non-nil input error is the
-// error from roundTrip.
-func (pc *persistConn) shouldRetryRequest(req *Request, err error) bool {
- if http2isNoCachedConnError(err) {
- // Issue 16582: if the user started a bunch of
- // requests at once, they can all pick the same conn
- // and violate the server's max concurrent streams.
- // Instead, match the HTTP/1 behavior for now and dial
- // again to get a new TCP connection, rather than failing
- // this request.
- return true
- }
- if err == errMissingHost {
- // User error.
- return false
- }
- if !pc.isReused() {
- // This was a fresh connection. There's no reason the server
- // should've hung up on us.
- //
- // Also, if we retried now, we could loop forever
- // creating new connections and retrying if the server
- // is just hanging up on us because it doesn't like
- // our request (as opposed to sending an error).
- return false
- }
- if _, ok := err.(nothingWrittenError); ok {
- // We never wrote anything, so it's safe to retry, if there's no body or we
- // can "rewind" the body with GetBody.
- return req.outgoingLength() == 0 || req.GetBody != nil
- }
- if !req.isReplayable() {
- // Don't retry non-idempotent requests.
- return false
- }
- if _, ok := err.(transportReadFromServerError); ok {
- // We got some non-EOF net.Conn.Read failure reading
- // the 1st response byte from the server.
- return true
- }
- if err == errServerClosedIdle {
- // The server replied with io.EOF while we were trying to
- // read the response. Probably an unfortunately keep-alive
- // timeout, just as the client was writing a request.
- return true
- }
- return false // conservatively
-}
-
-// ErrSkipAltProtocol is a sentinel error value defined by Transport.RegisterProtocol.
-var ErrSkipAltProtocol = errors.New("net/http: skip alternate protocol")
-
-// RegisterProtocol registers a new protocol with scheme.
-// The Transport will pass requests using the given scheme to rt.
-// It is rt's responsibility to simulate HTTP request semantics.
-//
-// RegisterProtocol can be used by other packages to provide
-// implementations of protocol schemes like "ftp" or "file".
-//
-// If rt.RoundTrip returns ErrSkipAltProtocol, the Transport will
-// handle the RoundTrip itself for that one request, as if the
-// protocol were not registered.
-func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper) {
- t.altMu.Lock()
- defer t.altMu.Unlock()
- oldMap, _ := t.altProto.Load().(map[string]RoundTripper)
- if _, exists := oldMap[scheme]; exists {
- panic("protocol " + scheme + " already registered")
- }
- newMap := make(map[string]RoundTripper)
- for k, v := range oldMap {
- newMap[k] = v
- }
- newMap[scheme] = rt
- t.altProto.Store(newMap)
-}
-
-// CloseIdleConnections closes any connections which were previously
-// connected from previous requests but are now sitting idle in
-// a "keep-alive" state. It does not interrupt any connections currently
-// in use.
-func (t *Transport) CloseIdleConnections() {
- t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
- t.idleMu.Lock()
- m := t.idleConn
- t.idleConn = nil
- t.closeIdle = true // close newly idle connections
- t.idleLRU = connLRU{}
- t.idleMu.Unlock()
- for _, conns := range m {
- for _, pconn := range conns {
- pconn.close(errCloseIdleConns)
- }
- }
- if t2 := t.h2transport; t2 != nil {
- t2.CloseIdleConnections()
- }
-}
-
-// CancelRequest cancels an in-flight request by closing its connection.
-// CancelRequest should only be called after RoundTrip has returned.
-//
-// Deprecated: Use Request.WithContext to create a request with a
-// cancelable context instead. CancelRequest cannot cancel HTTP/2
-// requests.
-func (t *Transport) CancelRequest(req *Request) {
- t.cancelRequest(cancelKey{req}, errRequestCanceled)
-}
-
-// Cancel an in-flight request, recording the error value.
-// Returns whether the request was canceled.
-func (t *Transport) cancelRequest(key cancelKey, err error) bool {
- // This function must not return until the cancel func has completed.
- // See: https://golang.org/issue/34658
- t.reqMu.Lock()
- defer t.reqMu.Unlock()
- cancel := t.reqCanceler[key]
- delete(t.reqCanceler, key)
- if cancel != nil {
- cancel(err)
- }
-
- return cancel != nil
-}
-
-//
-// Private implementation past this point.
-//
-
-var (
- envProxyOnce sync.Once
- envProxyFuncValue func(*url.URL) (*url.URL, error)
-)
-
-// envProxyFunc returns a function that reads the
-// environment variable to determine the proxy address.
-func envProxyFunc() func(*url.URL) (*url.URL, error) {
- envProxyOnce.Do(func() {
- envProxyFuncValue = httpproxy.FromEnvironment().ProxyFunc()
- })
- return envProxyFuncValue
-}
-
-// resetProxyConfig is used by tests.
-func resetProxyConfig() {
- envProxyOnce = sync.Once{}
- envProxyFuncValue = nil
-}
-
-func (t *Transport) connectMethodForRequest(treq *transportRequest) (cm connectMethod, err error) {
- cm.targetScheme = treq.URL.Scheme
- cm.targetAddr = canonicalAddr(treq.URL)
- if t.Proxy != nil {
- cm.proxyURL, err = t.Proxy(treq.Request)
- }
- cm.onlyH1 = treq.requiresHTTP1()
- return cm, err
-}
-
-// proxyAuth returns the Proxy-Authorization header to set
-// on requests, if applicable.
-func (cm *connectMethod) proxyAuth() string {
- if cm.proxyURL == nil {
- return ""
- }
- if u := cm.proxyURL.User; u != nil {
- username := u.Username()
- password, _ := u.Password()
- return "Basic " + basicAuth(username, password)
- }
- return ""
-}
-
-// error values for debugging and testing, not seen by users.
-var (
- errKeepAlivesDisabled = errors.New("http: putIdleConn: keep alives disabled")
- errConnBroken = errors.New("http: putIdleConn: connection is in bad state")
- errCloseIdle = errors.New("http: putIdleConn: CloseIdleConnections was called")
- errTooManyIdle = errors.New("http: putIdleConn: too many idle connections")
- errTooManyIdleHost = errors.New("http: putIdleConn: too many idle connections for host")
- errCloseIdleConns = errors.New("http: CloseIdleConnections called")
- errReadLoopExiting = errors.New("http: persistConn.readLoop exiting")
- errIdleConnTimeout = errors.New("http: idle connection timeout")
-
- // errServerClosedIdle is not seen by users for idempotent requests, but may be
- // seen by a user if the server shuts down an idle connection and sends its FIN
- // in flight with already-written POST body bytes from the client.
- // See https://github.com/golang/go/issues/19943#issuecomment-355607646
- errServerClosedIdle = errors.New("http: server closed idle connection")
-)
-
-// transportReadFromServerError is used by Transport.readLoop when the
-// 1 byte peek read fails and we're actually anticipating a response.
-// Usually this is just due to the inherent keep-alive shut down race,
-// where the server closed the connection at the same time the client
-// wrote. The underlying err field is usually io.EOF or some
-// ECONNRESET sort of thing which varies by platform. But it might be
-// the user's custom net.Conn.Read error too, so we carry it along for
-// them to return from Transport.RoundTrip.
-type transportReadFromServerError struct {
- err error
-}
-
-func (e transportReadFromServerError) Unwrap() error { return e.err }
-
-func (e transportReadFromServerError) Error() string {
- return fmt.Sprintf("net/http: Transport failed to read from server: %v", e.err)
-}
-
-func (t *Transport) putOrCloseIdleConn(pconn *persistConn) {
- if err := t.tryPutIdleConn(pconn); err != nil {
- pconn.close(err)
- }
-}
-
-func (t *Transport) maxIdleConnsPerHost() int {
- if v := t.MaxIdleConnsPerHost; v != 0 {
- return v
- }
- return DefaultMaxIdleConnsPerHost
-}
-
-// tryPutIdleConn adds pconn to the list of idle persistent connections awaiting
-// a new request.
-// If pconn is no longer needed or not in a good state, tryPutIdleConn returns
-// an error explaining why it wasn't registered.
-// tryPutIdleConn does not close pconn. Use putOrCloseIdleConn instead for that.
-func (t *Transport) tryPutIdleConn(pconn *persistConn) error {
- if t.DisableKeepAlives || t.MaxIdleConnsPerHost < 0 {
- return errKeepAlivesDisabled
- }
- if pconn.isBroken() {
- return errConnBroken
- }
- pconn.markReused()
-
- t.idleMu.Lock()
- defer t.idleMu.Unlock()
-
- // HTTP/2 (pconn.alt != nil) connections do not come out of the idle list,
- // because multiple goroutines can use them simultaneously.
- // If this is an HTTP/2 connection being “returned,” we're done.
- if pconn.alt != nil && t.idleLRU.m[pconn] != nil {
- return nil
- }
-
- // Deliver pconn to goroutine waiting for idle connection, if any.
- // (They may be actively dialing, but this conn is ready first.
- // Chrome calls this socket late binding.
- // See https://www.chromium.org/developers/design-documents/network-stack#TOC-Connection-Management.)
- key := pconn.cacheKey
- if q, ok := t.idleConnWait[key]; ok {
- done := false
- if pconn.alt == nil {
- // HTTP/1.
- // Loop over the waiting list until we find a w that isn't done already, and hand it pconn.
- for q.len() > 0 {
- w := q.popFront()
- if w.tryDeliver(pconn, nil) {
- done = true
- break
- }
- }
- } else {
- // HTTP/2.
- // Can hand the same pconn to everyone in the waiting list,
- // and we still won't be done: we want to put it in the idle
- // list unconditionally, for any future clients too.
- for q.len() > 0 {
- w := q.popFront()
- w.tryDeliver(pconn, nil)
- }
- }
- if q.len() == 0 {
- delete(t.idleConnWait, key)
- } else {
- t.idleConnWait[key] = q
- }
- if done {
- return nil
- }
- }
-
- if t.closeIdle {
- return errCloseIdle
- }
- if t.idleConn == nil {
- t.idleConn = make(map[connectMethodKey][]*persistConn)
- }
- idles := t.idleConn[key]
- if len(idles) >= t.maxIdleConnsPerHost() {
- return errTooManyIdleHost
- }
- for _, exist := range idles {
- if exist == pconn {
- log.Fatalf("dup idle pconn %p in freelist", pconn)
- }
- }
- t.idleConn[key] = append(idles, pconn)
- t.idleLRU.add(pconn)
- if t.MaxIdleConns != 0 && t.idleLRU.len() > t.MaxIdleConns {
- oldest := t.idleLRU.removeOldest()
- oldest.close(errTooManyIdle)
- t.removeIdleConnLocked(oldest)
- }
-
- // Set idle timer, but only for HTTP/1 (pconn.alt == nil).
- // The HTTP/2 implementation manages the idle timer itself
- // (see idleConnTimeout in h2_bundle.go).
- if t.IdleConnTimeout > 0 && pconn.alt == nil {
- if pconn.idleTimer != nil {
- pconn.idleTimer.Reset(t.IdleConnTimeout)
- } else {
- pconn.idleTimer = time.AfterFunc(t.IdleConnTimeout, pconn.closeConnIfStillIdle)
- }
- }
- pconn.idleAt = time.Now()
- return nil
-}
-
-// queueForIdleConn queues w to receive the next idle connection for w.cm.
-// As an optimization hint to the caller, queueForIdleConn reports whether
-// it successfully delivered an already-idle connection.
-func (t *Transport) queueForIdleConn(w *wantConn) (delivered bool) {
- if t.DisableKeepAlives {
- return false
- }
-
- t.idleMu.Lock()
- defer t.idleMu.Unlock()
-
- // Stop closing connections that become idle - we might want one.
- // (That is, undo the effect of t.CloseIdleConnections.)
- t.closeIdle = false
-
- if w == nil {
- // Happens in test hook.
- return false
- }
-
- // If IdleConnTimeout is set, calculate the oldest
- // persistConn.idleAt time we're willing to use a cached idle
- // conn.
- var oldTime time.Time
- if t.IdleConnTimeout > 0 {
- oldTime = time.Now().Add(-t.IdleConnTimeout)
- }
-
- // Look for most recently-used idle connection.
- if list, ok := t.idleConn[w.key]; ok {
- stop := false
- delivered := false
- for len(list) > 0 && !stop {
- pconn := list[len(list)-1]
-
- // See whether this connection has been idle too long, considering
- // only the wall time (the Round(0)), in case this is a laptop or VM
- // coming out of suspend with previously cached idle connections.
- tooOld := !oldTime.IsZero() && pconn.idleAt.Round(0).Before(oldTime)
- if tooOld {
- // Async cleanup. Launch in its own goroutine (as if a
- // time.AfterFunc called it); it acquires idleMu, which we're
- // holding, and does a synchronous net.Conn.Close.
- go pconn.closeConnIfStillIdle()
- }
- if pconn.isBroken() || tooOld {
- // If either persistConn.readLoop has marked the connection
- // broken, but Transport.removeIdleConn has not yet removed it
- // from the idle list, or if this persistConn is too old (it was
- // idle too long), then ignore it and look for another. In both
- // cases it's already in the process of being closed.
- list = list[:len(list)-1]
- continue
- }
- delivered = w.tryDeliver(pconn, nil)
- if delivered {
- if pconn.alt != nil {
- // HTTP/2: multiple clients can share pconn.
- // Leave it in the list.
- } else {
- // HTTP/1: only one client can use pconn.
- // Remove it from the list.
- t.idleLRU.remove(pconn)
- list = list[:len(list)-1]
- }
- }
- stop = true
- }
- if len(list) > 0 {
- t.idleConn[w.key] = list
- } else {
- delete(t.idleConn, w.key)
- }
- if stop {
- return delivered
- }
- }
-
- // Register to receive next connection that becomes idle.
- if t.idleConnWait == nil {
- t.idleConnWait = make(map[connectMethodKey]wantConnQueue)
- }
- q := t.idleConnWait[w.key]
- q.cleanFront()
- q.pushBack(w)
- t.idleConnWait[w.key] = q
- return false
-}
-
-// removeIdleConn marks pconn as dead.
-func (t *Transport) removeIdleConn(pconn *persistConn) bool {
- t.idleMu.Lock()
- defer t.idleMu.Unlock()
- return t.removeIdleConnLocked(pconn)
-}
-
-// t.idleMu must be held.
-func (t *Transport) removeIdleConnLocked(pconn *persistConn) bool {
- if pconn.idleTimer != nil {
- pconn.idleTimer.Stop()
- }
- t.idleLRU.remove(pconn)
- key := pconn.cacheKey
- pconns := t.idleConn[key]
- var removed bool
- switch len(pconns) {
- case 0:
- // Nothing
- case 1:
- if pconns[0] == pconn {
- delete(t.idleConn, key)
- removed = true
- }
- default:
- for i, v := range pconns {
- if v != pconn {
- continue
- }
- // Slide down, keeping most recently-used
- // conns at the end.
- copy(pconns[i:], pconns[i+1:])
- t.idleConn[key] = pconns[:len(pconns)-1]
- removed = true
- break
- }
- }
- return removed
-}
-
-func (t *Transport) setReqCanceler(key cancelKey, fn func(error)) {
- t.reqMu.Lock()
- defer t.reqMu.Unlock()
- if t.reqCanceler == nil {
- t.reqCanceler = make(map[cancelKey]func(error))
- }
- if fn != nil {
- t.reqCanceler[key] = fn
- } else {
- delete(t.reqCanceler, key)
- }
-}
-
-// replaceReqCanceler replaces an existing cancel function. If there is no cancel function
-// for the request, we don't set the function and return false.
-// Since CancelRequest will clear the canceler, we can use the return value to detect if
-// the request was canceled since the last setReqCancel call.
-func (t *Transport) replaceReqCanceler(key cancelKey, fn func(error)) bool {
- t.reqMu.Lock()
- defer t.reqMu.Unlock()
- _, ok := t.reqCanceler[key]
- if !ok {
- return false
- }
- if fn != nil {
- t.reqCanceler[key] = fn
- } else {
- delete(t.reqCanceler, key)
- }
- return true
-}
-
-var zeroDialer net.Dialer
-
-func (t *Transport) dial(ctx context.Context, network, addr string) (net.Conn, error) {
- if t.DialContext != nil {
- return t.DialContext(ctx, network, addr)
- }
- if t.Dial != nil {
- c, err := t.Dial(network, addr)
- if c == nil && err == nil {
- err = errors.New("net/http: Transport.Dial hook returned (nil, nil)")
- }
- return c, err
- }
- return zeroDialer.DialContext(ctx, network, addr)
-}
-
-// A wantConn records state about a wanted connection
-// (that is, an active call to getConn).
-// The conn may be gotten by dialing or by finding an idle connection,
-// or a cancellation may make the conn no longer wanted.
-// These three options are racing against each other and use
-// wantConn to coordinate and agree about the winning outcome.
-type wantConn struct {
- cm connectMethod
- key connectMethodKey // cm.key()
- ctx context.Context // context for dial
- ready chan struct{} // closed when pc, err pair is delivered
-
- // hooks for testing to know when dials are done
- // beforeDial is called in the getConn goroutine when the dial is queued.
- // afterDial is called when the dial is completed or canceled.
- beforeDial func()
- afterDial func()
-
- mu sync.Mutex // protects pc, err, close(ready)
- pc *persistConn
- err error
-}
-
-// waiting reports whether w is still waiting for an answer (connection or error).
-func (w *wantConn) waiting() bool {
- select {
- case <-w.ready:
- return false
- default:
- return true
- }
-}
-
-// tryDeliver attempts to deliver pc, err to w and reports whether it succeeded.
-func (w *wantConn) tryDeliver(pc *persistConn, err error) bool {
- w.mu.Lock()
- defer w.mu.Unlock()
-
- if w.pc != nil || w.err != nil {
- return false
- }
-
- w.pc = pc
- w.err = err
- if w.pc == nil && w.err == nil {
- panic("net/http: internal error: misuse of tryDeliver")
- }
- close(w.ready)
- return true
-}
-
-// cancel marks w as no longer wanting a result (for example, due to cancellation).
-// If a connection has been delivered already, cancel returns it with t.putOrCloseIdleConn.
-func (w *wantConn) cancel(t *Transport, err error) {
- w.mu.Lock()
- if w.pc == nil && w.err == nil {
- close(w.ready) // catch misbehavior in future delivery
- }
- pc := w.pc
- w.pc = nil
- w.err = err
- w.mu.Unlock()
-
- if pc != nil {
- t.putOrCloseIdleConn(pc)
- }
-}
-
-// A wantConnQueue is a queue of wantConns.
-type wantConnQueue struct {
- // This is a queue, not a deque.
- // It is split into two stages - head[headPos:] and tail.
- // popFront is trivial (headPos++) on the first stage, and
- // pushBack is trivial (append) on the second stage.
- // If the first stage is empty, popFront can swap the
- // first and second stages to remedy the situation.
- //
- // This two-stage split is analogous to the use of two lists
- // in Okasaki's purely functional queue but without the
- // overhead of reversing the list when swapping stages.
- head []*wantConn
- headPos int
- tail []*wantConn
-}
-
-// len returns the number of items in the queue.
-func (q *wantConnQueue) len() int {
- return len(q.head) - q.headPos + len(q.tail)
-}
-
-// pushBack adds w to the back of the queue.
-func (q *wantConnQueue) pushBack(w *wantConn) {
- q.tail = append(q.tail, w)
-}
-
-// popFront removes and returns the wantConn at the front of the queue.
-func (q *wantConnQueue) popFront() *wantConn {
- if q.headPos >= len(q.head) {
- if len(q.tail) == 0 {
- return nil
- }
- // Pick up tail as new head, clear tail.
- q.head, q.headPos, q.tail = q.tail, 0, q.head[:0]
- }
- w := q.head[q.headPos]
- q.head[q.headPos] = nil
- q.headPos++
- return w
-}
-
-// peekFront returns the wantConn at the front of the queue without removing it.
-func (q *wantConnQueue) peekFront() *wantConn {
- if q.headPos < len(q.head) {
- return q.head[q.headPos]
- }
- if len(q.tail) > 0 {
- return q.tail[0]
- }
- return nil
-}
-
-// cleanFront pops any wantConns that are no longer waiting from the head of the
-// queue, reporting whether any were popped.
-func (q *wantConnQueue) cleanFront() (cleaned bool) {
- for {
- w := q.peekFront()
- if w == nil || w.waiting() {
- return cleaned
- }
- q.popFront()
- cleaned = true
- }
-}
-
-func (t *Transport) customDialTLS(ctx context.Context, network, addr string) (conn net.Conn, err error) {
- if t.DialTLSContext != nil {
- conn, err = t.DialTLSContext(ctx, network, addr)
- } else {
- conn, err = t.DialTLS(network, addr)
- }
- if conn == nil && err == nil {
- err = errors.New("net/http: Transport.DialTLS or DialTLSContext returned (nil, nil)")
- }
- return
-}
-
-// getConn dials and creates a new persistConn to the target as
-// specified in the connectMethod. This includes doing a proxy CONNECT
-// and/or setting up TLS. If this doesn't return an error, the persistConn
-// is ready to write requests to.
-func (t *Transport) getConn(treq *transportRequest, cm connectMethod) (pc *persistConn, err error) {
- req := treq.Request
- trace := treq.trace
- ctx := req.Context()
- if trace != nil && trace.GetConn != nil {
- trace.GetConn(cm.addr())
- }
-
- w := &wantConn{
- cm: cm,
- key: cm.key(),
- ctx: ctx,
- ready: make(chan struct{}, 1),
- beforeDial: testHookPrePendingDial,
- afterDial: testHookPostPendingDial,
- }
- defer func() {
- if err != nil {
- w.cancel(t, err)
- }
- }()
-
- // Queue for idle connection.
- if delivered := t.queueForIdleConn(w); delivered {
- pc := w.pc
- // Trace only for HTTP/1.
- // HTTP/2 calls trace.GotConn itself.
- if pc.alt == nil && trace != nil && trace.GotConn != nil {
- trace.GotConn(pc.gotIdleConnTrace(pc.idleAt))
- }
- // set request canceler to some non-nil function so we
- // can detect whether it was cleared between now and when
- // we enter roundTrip
- t.setReqCanceler(treq.cancelKey, func(error) {})
- return pc, nil
- }
-
- cancelc := make(chan error, 1)
- t.setReqCanceler(treq.cancelKey, func(err error) { cancelc <- err })
-
- // Queue for permission to dial.
- t.queueForDial(w)
-
- // Wait for completion or cancellation.
- select {
- case <-w.ready:
- // Trace success but only for HTTP/1.
- // HTTP/2 calls trace.GotConn itself.
- if w.pc != nil && w.pc.alt == nil && trace != nil && trace.GotConn != nil {
- trace.GotConn(httptrace.GotConnInfo{Conn: w.pc.conn, Reused: w.pc.isReused()})
- }
- if w.err != nil {
- // If the request has been canceled, that's probably
- // what caused w.err; if so, prefer to return the
- // cancellation error (see golang.org/issue/16049).
- select {
- case <-req.Cancel:
- return nil, errRequestCanceledConn
- case <-req.Context().Done():
- return nil, req.Context().Err()
- case err := <-cancelc:
- if err == errRequestCanceled {
- err = errRequestCanceledConn
- }
- return nil, err
- default:
- // return below
- }
- }
- return w.pc, w.err
- case <-req.Cancel:
- return nil, errRequestCanceledConn
- case <-req.Context().Done():
- return nil, req.Context().Err()
- case err := <-cancelc:
- if err == errRequestCanceled {
- err = errRequestCanceledConn
- }
- return nil, err
- }
-}
-
-// queueForDial queues w to wait for permission to begin dialing.
-// Once w receives permission to dial, it will do so in a separate goroutine.
-func (t *Transport) queueForDial(w *wantConn) {
- w.beforeDial()
- if t.MaxConnsPerHost <= 0 {
- go t.dialConnFor(w)
- return
- }
-
- t.connsPerHostMu.Lock()
- defer t.connsPerHostMu.Unlock()
-
- if n := t.connsPerHost[w.key]; n < t.MaxConnsPerHost {
- if t.connsPerHost == nil {
- t.connsPerHost = make(map[connectMethodKey]int)
- }
- t.connsPerHost[w.key] = n + 1
- go t.dialConnFor(w)
- return
- }
-
- if t.connsPerHostWait == nil {
- t.connsPerHostWait = make(map[connectMethodKey]wantConnQueue)
- }
- q := t.connsPerHostWait[w.key]
- q.cleanFront()
- q.pushBack(w)
- t.connsPerHostWait[w.key] = q
-}
-
-// dialConnFor dials on behalf of w and delivers the result to w.
-// dialConnFor has received permission to dial w.cm and is counted in t.connCount[w.cm.key()].
-// If the dial is canceled or unsuccessful, dialConnFor decrements t.connCount[w.cm.key()].
-func (t *Transport) dialConnFor(w *wantConn) {
- defer w.afterDial()
-
- pc, err := t.dialConn(w.ctx, w.cm)
- delivered := w.tryDeliver(pc, err)
- if err == nil && (!delivered || pc.alt != nil) {
- // pconn was not passed to w,
- // or it is HTTP/2 and can be shared.
- // Add to the idle connection pool.
- t.putOrCloseIdleConn(pc)
- }
- if err != nil {
- t.decConnsPerHost(w.key)
- }
-}
-
-// decConnsPerHost decrements the per-host connection count for key,
-// which may in turn give a different waiting goroutine permission to dial.
-func (t *Transport) decConnsPerHost(key connectMethodKey) {
- if t.MaxConnsPerHost <= 0 {
- return
- }
-
- t.connsPerHostMu.Lock()
- defer t.connsPerHostMu.Unlock()
- n := t.connsPerHost[key]
- if n == 0 {
- // Shouldn't happen, but if it does, the counting is buggy and could
- // easily lead to a silent deadlock, so report the problem loudly.
- panic("net/http: internal error: connCount underflow")
- }
-
- // Can we hand this count to a goroutine still waiting to dial?
- // (Some goroutines on the wait list may have timed out or
- // gotten a connection another way. If they're all gone,
- // we don't want to kick off any spurious dial operations.)
- if q := t.connsPerHostWait[key]; q.len() > 0 {
- done := false
- for q.len() > 0 {
- w := q.popFront()
- if w.waiting() {
- go t.dialConnFor(w)
- done = true
- break
- }
- }
- if q.len() == 0 {
- delete(t.connsPerHostWait, key)
- } else {
- // q is a value (like a slice), so we have to store
- // the updated q back into the map.
- t.connsPerHostWait[key] = q
- }
- if done {
- return
- }
- }
-
- // Otherwise, decrement the recorded count.
- if n--; n == 0 {
- delete(t.connsPerHost, key)
- } else {
- t.connsPerHost[key] = n
- }
-}
-
-// Add TLS to a persistent connection, i.e. negotiate a TLS session. If pconn is already a TLS
-// tunnel, this function establishes a nested TLS session inside the encrypted channel.
-// The remote endpoint's name may be overridden by TLSClientConfig.ServerName.
-func (pconn *persistConn) addTLS(ctx context.Context, name string, trace *httptrace.ClientTrace) error {
- // Initiate TLS and check remote host name against certificate.
- cfg := cloneTLSConfig(pconn.t.TLSClientConfig)
- if cfg.ServerName == "" {
- cfg.ServerName = name
- }
- if pconn.cacheKey.onlyH1 {
- cfg.NextProtos = nil
- }
- plainConn := pconn.conn
- tlsConn := tls.Client(plainConn, cfg)
- errc := make(chan error, 2)
- var timer *time.Timer // for canceling TLS handshake
- if d := pconn.t.TLSHandshakeTimeout; d != 0 {
- timer = time.AfterFunc(d, func() {
- errc <- tlsHandshakeTimeoutError{}
- })
- }
- go func() {
- if trace != nil && trace.TLSHandshakeStart != nil {
- trace.TLSHandshakeStart()
- }
- err := tlsConn.HandshakeContext(ctx)
- if timer != nil {
- timer.Stop()
- }
- errc <- err
- }()
- if err := <-errc; err != nil {
- plainConn.Close()
- if trace != nil && trace.TLSHandshakeDone != nil {
- trace.TLSHandshakeDone(tls.ConnectionState{}, err)
- }
- return err
- }
- cs := tlsConn.ConnectionState()
- if trace != nil && trace.TLSHandshakeDone != nil {
- trace.TLSHandshakeDone(cs, nil)
- }
- pconn.tlsState = &cs
- pconn.conn = tlsConn
- return nil
-}
-
-type erringRoundTripper interface {
- RoundTripErr() error
-}
-
-func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *persistConn, err error) {
- pconn = &persistConn{
- t: t,
- cacheKey: cm.key(),
- reqch: make(chan requestAndChan, 1),
- writech: make(chan writeRequest, 1),
- closech: make(chan struct{}),
- writeErrCh: make(chan error, 1),
- writeLoopDone: make(chan struct{}),
- }
- trace := httptrace.ContextClientTrace(ctx)
- wrapErr := func(err error) error {
- if cm.proxyURL != nil {
- // Return a typed error, per Issue 16997
- return &net.OpError{Op: "proxyconnect", Net: "tcp", Err: err}
- }
- return err
- }
- if cm.scheme() == "https" && t.hasCustomTLSDialer() {
- var err error
- pconn.conn, err = t.customDialTLS(ctx, "tcp", cm.addr())
- if err != nil {
- return nil, wrapErr(err)
- }
- if tc, ok := pconn.conn.(*tls.Conn); ok {
- // Handshake here, in case DialTLS didn't. TLSNextProto below
- // depends on it for knowing the connection state.
- if trace != nil && trace.TLSHandshakeStart != nil {
- trace.TLSHandshakeStart()
- }
- if err := tc.HandshakeContext(ctx); err != nil {
- go pconn.conn.Close()
- if trace != nil && trace.TLSHandshakeDone != nil {
- trace.TLSHandshakeDone(tls.ConnectionState{}, err)
- }
- return nil, err
- }
- cs := tc.ConnectionState()
- if trace != nil && trace.TLSHandshakeDone != nil {
- trace.TLSHandshakeDone(cs, nil)
- }
- pconn.tlsState = &cs
- }
- } else {
- conn, err := t.dial(ctx, "tcp", cm.addr())
- if err != nil {
- return nil, wrapErr(err)
- }
- pconn.conn = conn
- if cm.scheme() == "https" {
- var firstTLSHost string
- if firstTLSHost, _, err = net.SplitHostPort(cm.addr()); err != nil {
- return nil, wrapErr(err)
- }
- if err = pconn.addTLS(ctx, firstTLSHost, trace); err != nil {
- return nil, wrapErr(err)
- }
- }
- }
-
- // Proxy setup.
- switch {
- case cm.proxyURL == nil:
- // Do nothing. Not using a proxy.
- case cm.proxyURL.Scheme == "socks5":
- conn := pconn.conn
- d := socksNewDialer("tcp", conn.RemoteAddr().String())
- if u := cm.proxyURL.User; u != nil {
- auth := &socksUsernamePassword{
- Username: u.Username(),
- }
- auth.Password, _ = u.Password()
- d.AuthMethods = []socksAuthMethod{
- socksAuthMethodNotRequired,
- socksAuthMethodUsernamePassword,
- }
- d.Authenticate = auth.Authenticate
- }
- if _, err := d.DialWithConn(ctx, conn, "tcp", cm.targetAddr); err != nil {
- conn.Close()
- return nil, err
- }
- case cm.targetScheme == "http":
- pconn.isProxy = true
- if pa := cm.proxyAuth(); pa != "" {
- pconn.mutateHeaderFunc = func(h Header) {
- h.Set("Proxy-Authorization", pa)
- }
- }
- case cm.targetScheme == "https":
- conn := pconn.conn
- var hdr Header
- if t.GetProxyConnectHeader != nil {
- var err error
- hdr, err = t.GetProxyConnectHeader(ctx, cm.proxyURL, cm.targetAddr)
- if err != nil {
- conn.Close()
- return nil, err
- }
- } else {
- hdr = t.ProxyConnectHeader
- }
- if hdr == nil {
- hdr = make(Header)
- }
- if pa := cm.proxyAuth(); pa != "" {
- hdr = hdr.Clone()
- hdr.Set("Proxy-Authorization", pa)
- }
- connectReq := &Request{
- Method: "CONNECT",
- URL: &url.URL{Opaque: cm.targetAddr},
- Host: cm.targetAddr,
- Header: hdr,
- }
-
- // If there's no done channel (no deadline or cancellation
- // from the caller possible), at least set some (long)
- // timeout here. This will make sure we don't block forever
- // and leak a goroutine if the connection stops replying
- // after the TCP connect.
- connectCtx := ctx
- if ctx.Done() == nil {
- newCtx, cancel := context.WithTimeout(ctx, 1*time.Minute)
- defer cancel()
- connectCtx = newCtx
- }
-
- didReadResponse := make(chan struct{}) // closed after CONNECT write+read is done or fails
- var (
- resp *Response
- err error // write or read error
- )
- // Write the CONNECT request & read the response.
- go func() {
- defer close(didReadResponse)
- err = connectReq.Write(conn)
- if err != nil {
- return
- }
- // Okay to use and discard buffered reader here, because
- // TLS server will not speak until spoken to.
- br := bufio.NewReader(conn)
- resp, err = ReadResponse(br, connectReq)
- }()
- select {
- case <-connectCtx.Done():
- conn.Close()
- <-didReadResponse
- return nil, connectCtx.Err()
- case <-didReadResponse:
- // resp or err now set
- }
- if err != nil {
- conn.Close()
- return nil, err
- }
-
- if t.OnProxyConnectResponse != nil {
- err = t.OnProxyConnectResponse(ctx, cm.proxyURL, connectReq, resp)
- if err != nil {
- return nil, err
- }
- }
-
- if resp.StatusCode != 200 {
- _, text, ok := strings.Cut(resp.Status, " ")
- conn.Close()
- if !ok {
- return nil, errors.New("unknown status code")
- }
- return nil, errors.New(text)
- }
- }
-
- if cm.proxyURL != nil && cm.targetScheme == "https" {
- if err := pconn.addTLS(ctx, cm.tlsHost(), trace); err != nil {
- return nil, err
- }
- }
-
- 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.(erringRoundTripper); ok {
- // pconn.conn was closed by next (http2configureTransports.upgradeFn).
- return nil, e.RoundTripErr()
- }
- return &persistConn{t: t, cacheKey: pconn.cacheKey, alt: alt}, nil
- }
- }
-
- pconn.br = bufio.NewReaderSize(pconn, t.readBufferSize())
- pconn.bw = bufio.NewWriterSize(persistConnWriter{pconn}, t.writeBufferSize())
-
- go pconn.readLoop()
- go pconn.writeLoop()
- return pconn, nil
-}
-
-// persistConnWriter is the io.Writer written to by pc.bw.
-// It accumulates the number of bytes written to the underlying conn,
-// so the retry logic can determine whether any bytes made it across
-// the wire.
-// This is exactly 1 pointer field wide so it can go into an interface
-// without allocation.
-type persistConnWriter struct {
- pc *persistConn
-}
-
-func (w persistConnWriter) Write(p []byte) (n int, err error) {
- n, err = w.pc.conn.Write(p)
- w.pc.nwrite += int64(n)
- return
-}
-
-// ReadFrom exposes persistConnWriter's underlying Conn to io.Copy and if
-// the Conn implements io.ReaderFrom, it can take advantage of optimizations
-// such as sendfile.
-func (w persistConnWriter) ReadFrom(r io.Reader) (n int64, err error) {
- n, err = io.Copy(w.pc.conn, r)
- w.pc.nwrite += n
- return
-}
-
-var _ io.ReaderFrom = (*persistConnWriter)(nil)
-
-// connectMethod is the map key (in its String form) for keeping persistent
-// TCP connections alive for subsequent HTTP requests.
-//
-// A connect method may be of the following types:
-//
-// connectMethod.key().String() Description
-// ------------------------------ -------------------------
-// |http|foo.com http directly to server, no proxy
-// |https|foo.com https directly to server, no proxy
-// |https,h1|foo.com https directly to server w/o HTTP/2, no proxy
-// http://proxy.com|https|foo.com http to proxy, then CONNECT to foo.com
-// http://proxy.com|http http to proxy, http to anywhere after that
-// socks5://proxy.com|http|foo.com socks5 to proxy, then http to foo.com
-// socks5://proxy.com|https|foo.com socks5 to proxy, then https to foo.com
-// https://proxy.com|https|foo.com https to proxy, then CONNECT to foo.com
-// https://proxy.com|http https to proxy, http to anywhere after that
-type connectMethod struct {
- _ incomparable
- proxyURL *url.URL // nil for no proxy, else full proxy URL
- targetScheme string // "http" or "https"
- // If proxyURL specifies an http or https proxy, and targetScheme is http (not https),
- // then targetAddr is not included in the connect method key, because the socket can
- // be reused for different targetAddr values.
- targetAddr string
- onlyH1 bool // whether to disable HTTP/2 and force HTTP/1
-}
-
-func (cm *connectMethod) key() connectMethodKey {
- proxyStr := ""
- targetAddr := cm.targetAddr
- if cm.proxyURL != nil {
- proxyStr = cm.proxyURL.String()
- if (cm.proxyURL.Scheme == "http" || cm.proxyURL.Scheme == "https") && cm.targetScheme == "http" {
- targetAddr = ""
- }
- }
- return connectMethodKey{
- proxy: proxyStr,
- scheme: cm.targetScheme,
- addr: targetAddr,
- onlyH1: cm.onlyH1,
- }
-}
-
-// scheme returns the first hop scheme: http, https, or socks5
-func (cm *connectMethod) scheme() string {
- if cm.proxyURL != nil {
- return cm.proxyURL.Scheme
- }
- return cm.targetScheme
-}
-
-// addr returns the first hop "host:port" to which we need to TCP connect.
-func (cm *connectMethod) addr() string {
- if cm.proxyURL != nil {
- return canonicalAddr(cm.proxyURL)
- }
- return cm.targetAddr
-}
-
-// tlsHost returns the host name to match against the peer's
-// TLS certificate.
-func (cm *connectMethod) tlsHost() string {
- h := cm.targetAddr
- if hasPort(h) {
- h = h[:strings.LastIndex(h, ":")]
- }
- return h
-}
-
-// connectMethodKey is the map key version of connectMethod, with a
-// stringified proxy URL (or the empty string) instead of a pointer to
-// a URL.
-type connectMethodKey struct {
- proxy, scheme, addr string
- onlyH1 bool
-}
-
-func (k connectMethodKey) String() string {
- // Only used by tests.
- var h1 string
- if k.onlyH1 {
- h1 = ",h1"
- }
- return fmt.Sprintf("%s|%s%s|%s", k.proxy, k.scheme, h1, k.addr)
-}
-
-// persistConn wraps a connection, usually a persistent one
-// (but may be used for non-keep-alive requests as well)
-type persistConn struct {
- // alt optionally specifies the TLS NextProto RoundTripper.
- // This is used for HTTP/2 today and future protocols later.
- // If it's non-nil, the rest of the fields are unused.
- alt RoundTripper
-
- t *Transport
- cacheKey connectMethodKey
- conn net.Conn
- tlsState *tls.ConnectionState
- br *bufio.Reader // from conn
- bw *bufio.Writer // to conn
- nwrite int64 // bytes written
- reqch chan requestAndChan // written by roundTrip; read by readLoop
- writech chan writeRequest // written by roundTrip; read by writeLoop
- closech chan struct{} // closed when conn closed
- isProxy bool
- sawEOF bool // whether we've seen EOF from conn; owned by readLoop
- readLimit int64 // bytes allowed to be read; owned by readLoop
- // writeErrCh passes the request write error (usually nil)
- // from the writeLoop goroutine to the readLoop which passes
- // it off to the res.Body reader, which then uses it to decide
- // whether or not a connection can be reused. Issue 7569.
- writeErrCh chan error
-
- writeLoopDone chan struct{} // closed when write loop ends
-
- // Both guarded by Transport.idleMu:
- idleAt time.Time // time it last become idle
- idleTimer *time.Timer // holding an AfterFunc to close it
-
- mu sync.Mutex // guards following fields
- numExpectedResponses int
- closed error // set non-nil when conn is closed, before closech is closed
- canceledErr error // set non-nil if conn is canceled
- broken bool // an error has happened on this connection; marked broken so it's not reused.
- reused bool // whether conn has had successful request/response and is being reused.
- // mutateHeaderFunc is an optional func to modify extra
- // headers on each outbound request before it's written. (the
- // original Request given to RoundTrip is not modified)
- mutateHeaderFunc func(Header)
-}
-
-func (pc *persistConn) maxHeaderResponseSize() int64 {
- if v := pc.t.MaxResponseHeaderBytes; v != 0 {
- return v
- }
- return 10 << 20 // conservative default; same as http2
-}
-
-func (pc *persistConn) Read(p []byte) (n int, err error) {
- if pc.readLimit <= 0 {
- return 0, fmt.Errorf("read limit of %d bytes exhausted", pc.maxHeaderResponseSize())
- }
- if int64(len(p)) > pc.readLimit {
- p = p[:pc.readLimit]
- }
- n, err = pc.conn.Read(p)
- if err == io.EOF {
- pc.sawEOF = true
- }
- pc.readLimit -= int64(n)
- return
-}
-
-// isBroken reports whether this connection is in a known broken state.
-func (pc *persistConn) isBroken() bool {
- pc.mu.Lock()
- b := pc.closed != nil
- pc.mu.Unlock()
- return b
-}
-
-// canceled returns non-nil if the connection was closed due to
-// CancelRequest or due to context cancellation.
-func (pc *persistConn) canceled() error {
- pc.mu.Lock()
- defer pc.mu.Unlock()
- return pc.canceledErr
-}
-
-// isReused reports whether this connection has been used before.
-func (pc *persistConn) isReused() bool {
- pc.mu.Lock()
- r := pc.reused
- pc.mu.Unlock()
- return r
-}
-
-func (pc *persistConn) gotIdleConnTrace(idleAt time.Time) (t httptrace.GotConnInfo) {
- pc.mu.Lock()
- defer pc.mu.Unlock()
- t.Reused = pc.reused
- t.Conn = pc.conn
- t.WasIdle = true
- if !idleAt.IsZero() {
- t.IdleTime = time.Since(idleAt)
- }
- return
-}
-
-func (pc *persistConn) cancelRequest(err error) {
- pc.mu.Lock()
- defer pc.mu.Unlock()
- pc.canceledErr = err
- pc.closeLocked(errRequestCanceled)
-}
-
-// closeConnIfStillIdle closes the connection if it's still sitting idle.
-// This is what's called by the persistConn's idleTimer, and is run in its
-// own goroutine.
-func (pc *persistConn) closeConnIfStillIdle() {
- t := pc.t
- t.idleMu.Lock()
- defer t.idleMu.Unlock()
- if _, ok := t.idleLRU.m[pc]; !ok {
- // Not idle.
- return
- }
- t.removeIdleConnLocked(pc)
- pc.close(errIdleConnTimeout)
-}
-
-// mapRoundTripError returns the appropriate error value for
-// persistConn.roundTrip.
-//
-// The provided err is the first error that (*persistConn).roundTrip
-// happened to receive from its select statement.
-//
-// The startBytesWritten value should be the value of pc.nwrite before the roundTrip
-// started writing the request.
-func (pc *persistConn) mapRoundTripError(req *transportRequest, startBytesWritten int64, err error) error {
- if err == nil {
- return nil
- }
-
- // Wait for the writeLoop goroutine to terminate to avoid data
- // races on callers who mutate the request on failure.
- //
- // When resc in pc.roundTrip and hence rc.ch receives a responseAndError
- // with a non-nil error it implies that the persistConn is either closed
- // or closing. Waiting on pc.writeLoopDone is hence safe as all callers
- // close closech which in turn ensures writeLoop returns.
- <-pc.writeLoopDone
-
- // If the request was canceled, that's better than network
- // failures that were likely the result of tearing down the
- // connection.
- if cerr := pc.canceled(); cerr != nil {
- return cerr
- }
-
- // See if an error was set explicitly.
- req.mu.Lock()
- reqErr := req.err
- req.mu.Unlock()
- if reqErr != nil {
- return reqErr
- }
-
- if err == errServerClosedIdle {
- // Don't decorate
- return err
- }
-
- if _, ok := err.(transportReadFromServerError); ok {
- if pc.nwrite == startBytesWritten {
- return nothingWrittenError{err}
- }
- // Don't decorate
- return err
- }
- if pc.isBroken() {
- if pc.nwrite == startBytesWritten {
- return nothingWrittenError{err}
- }
- return fmt.Errorf("net/http: HTTP/1.x transport connection broken: %w", err)
- }
- return err
-}
-
-// errCallerOwnsConn is an internal sentinel error used when we hand
-// off a writable response.Body to the caller. We use this to prevent
-// closing a net.Conn that is now owned by the caller.
-var errCallerOwnsConn = errors.New("read loop ending; caller owns writable underlying conn")
-
-func (pc *persistConn) readLoop() {
- closeErr := errReadLoopExiting // default value, if not changed below
- defer func() {
- pc.close(closeErr)
- pc.t.removeIdleConn(pc)
- }()
-
- tryPutIdleConn := func(trace *httptrace.ClientTrace) bool {
- if err := pc.t.tryPutIdleConn(pc); err != nil {
- closeErr = err
- if trace != nil && trace.PutIdleConn != nil && err != errKeepAlivesDisabled {
- trace.PutIdleConn(err)
- }
- return false
- }
- if trace != nil && trace.PutIdleConn != nil {
- trace.PutIdleConn(nil)
- }
- return true
- }
-
- // eofc is used to block caller goroutines reading from Response.Body
- // at EOF until this goroutines has (potentially) added the connection
- // back to the idle pool.
- eofc := make(chan struct{})
- defer close(eofc) // unblock reader on errors
-
- // Read this once, before loop starts. (to avoid races in tests)
- testHookMu.Lock()
- testHookReadLoopBeforeNextRead := testHookReadLoopBeforeNextRead
- testHookMu.Unlock()
-
- alive := true
- for alive {
- pc.readLimit = pc.maxHeaderResponseSize()
- _, err := pc.br.Peek(1)
-
- pc.mu.Lock()
- if pc.numExpectedResponses == 0 {
- pc.readLoopPeekFailLocked(err)
- pc.mu.Unlock()
- return
- }
- pc.mu.Unlock()
-
- rc := <-pc.reqch
- trace := httptrace.ContextClientTrace(rc.req.Context())
-
- var resp *Response
- if err == nil {
- resp, err = pc.readResponse(rc, trace)
- } else {
- err = transportReadFromServerError{err}
- closeErr = err
- }
-
- if err != nil {
- if pc.readLimit <= 0 {
- err = fmt.Errorf("net/http: server response headers exceeded %d bytes; aborted", pc.maxHeaderResponseSize())
- }
-
- select {
- case rc.ch <- responseAndError{err: err}:
- case <-rc.callerGone:
- return
- }
- return
- }
- pc.readLimit = maxInt64 // effectively no limit for response bodies
-
- pc.mu.Lock()
- pc.numExpectedResponses--
- pc.mu.Unlock()
-
- bodyWritable := resp.bodyIsWritable()
- hasBody := rc.req.Method != "HEAD" && resp.ContentLength != 0
-
- if resp.Close || rc.req.Close || resp.StatusCode <= 199 || bodyWritable {
- // Don't do keep-alive on error if either party requested a close
- // or we get an unexpected informational (1xx) response.
- // StatusCode 100 is already handled above.
- alive = false
- }
-
- if !hasBody || bodyWritable {
- 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.
- alive = alive &&
- !pc.sawEOF &&
- pc.wroteRequest() &&
- replaced && tryPutIdleConn(trace)
-
- if bodyWritable {
- closeErr = errCallerOwnsConn
- }
-
- select {
- case rc.ch <- responseAndError{res: resp}:
- case <-rc.callerGone:
- return
- }
-
- // Now that they've read from the unbuffered channel, they're safely
- // out of the select that also waits on this goroutine to die, so
- // we're allowed to exit now if needed (if alive is false)
- testHookReadLoopBeforeNextRead()
- continue
- }
-
- waitForBodyRead := make(chan bool, 2)
- body := &bodyEOFSignal{
- body: resp.Body,
- earlyCloseFn: func() error {
- waitForBodyRead <- false
- <-eofc // will be closed by deferred call at the end of the function
- return nil
-
- },
- fn: func(err error) error {
- isEOF := err == io.EOF
- waitForBodyRead <- isEOF
- if isEOF {
- <-eofc // see comment above eofc declaration
- } else if err != nil {
- if cerr := pc.canceled(); cerr != nil {
- return cerr
- }
- }
- return err
- },
- }
-
- resp.Body = body
- if rc.addedGzip && ascii.EqualFold(resp.Header.Get("Content-Encoding"), "gzip") {
- resp.Body = &gzipReader{body: body}
- resp.Header.Del("Content-Encoding")
- resp.Header.Del("Content-Length")
- resp.ContentLength = -1
- resp.Uncompressed = true
- }
-
- select {
- case rc.ch <- responseAndError{res: resp}:
- case <-rc.callerGone:
- return
- }
-
- // Before looping back to the top of this function and peeking on
- // the bufio.Reader, wait for the caller goroutine to finish
- // reading the response body. (or for cancellation or death)
- select {
- case bodyEOF := <-waitForBodyRead:
- replaced := pc.t.replaceReqCanceler(rc.cancelKey, nil) // before pc might return to idle pool
- alive = alive &&
- bodyEOF &&
- !pc.sawEOF &&
- pc.wroteRequest() &&
- replaced && tryPutIdleConn(trace)
- if bodyEOF {
- eofc <- struct{}{}
- }
- case <-rc.req.Cancel:
- alive = false
- pc.t.CancelRequest(rc.req)
- case <-rc.req.Context().Done():
- alive = false
- pc.t.cancelRequest(rc.cancelKey, rc.req.Context().Err())
- case <-pc.closech:
- alive = false
- }
-
- testHookReadLoopBeforeNextRead()
- }
-}
-
-func (pc *persistConn) readLoopPeekFailLocked(peekErr error) {
- if pc.closed != nil {
- return
- }
- if n := pc.br.Buffered(); n > 0 {
- buf, _ := pc.br.Peek(n)
- if is408Message(buf) {
- pc.closeLocked(errServerClosedIdle)
- return
- } else {
- log.Printf("Unsolicited response received on idle HTTP channel starting with %q; err=%v", buf, peekErr)
- }
- }
- if peekErr == io.EOF {
- // common case.
- pc.closeLocked(errServerClosedIdle)
- } else {
- pc.closeLocked(fmt.Errorf("readLoopPeekFailLocked: %w", peekErr))
- }
-}
-
-// is408Message reports whether buf has the prefix of an
-// HTTP 408 Request Timeout response.
-// See golang.org/issue/32310.
-func is408Message(buf []byte) bool {
- if len(buf) < len("HTTP/1.x 408") {
- return false
- }
- if string(buf[:7]) != "HTTP/1." {
- return false
- }
- return string(buf[8:12]) == " 408"
-}
-
-// readResponse reads an HTTP response (or two, in the case of "Expect:
-// 100-continue") from the server. It returns the final non-100 one.
-// trace is optional.
-func (pc *persistConn) readResponse(rc requestAndChan, trace *httptrace.ClientTrace) (resp *Response, err error) {
- if trace != nil && trace.GotFirstResponseByte != nil {
- if peek, err := pc.br.Peek(1); err == nil && len(peek) == 1 {
- trace.GotFirstResponseByte()
- }
- }
- num1xx := 0 // number of informational 1xx headers received
- const max1xxResponses = 5 // arbitrary bound on number of informational responses
-
- continueCh := rc.continueCh
- for {
- resp, err = ReadResponse(pc.br, rc.req)
- if err != nil {
- return
- }
- resCode := resp.StatusCode
- if continueCh != nil {
- if resCode == 100 {
- if trace != nil && trace.Got100Continue != nil {
- trace.Got100Continue()
- }
- continueCh <- struct{}{}
- continueCh = nil
- } else if resCode >= 200 {
- close(continueCh)
- continueCh = nil
- }
- }
- is1xx := 100 <= resCode && resCode <= 199
- // treat 101 as a terminal status, see issue 26161
- is1xxNonTerminal := is1xx && resCode != StatusSwitchingProtocols
- if is1xxNonTerminal {
- num1xx++
- if num1xx > max1xxResponses {
- return nil, errors.New("net/http: too many 1xx informational responses")
- }
- pc.readLimit = pc.maxHeaderResponseSize() // reset the limit
- if trace != nil && trace.Got1xxResponse != nil {
- if err := trace.Got1xxResponse(resCode, textproto.MIMEHeader(resp.Header)); err != nil {
- return nil, err
- }
- }
- continue
- }
- break
- }
- if resp.isProtocolSwitch() {
- resp.Body = newReadWriteCloserBody(pc.br, pc.conn)
- }
-
- resp.TLS = pc.tlsState
- return
-}
-
-// waitForContinue returns the function to block until
-// any response, timeout or connection close. After any of them,
-// the function returns a bool which indicates if the body should be sent.
-func (pc *persistConn) waitForContinue(continueCh <-chan struct{}) func() bool {
- if continueCh == nil {
- return nil
- }
- return func() bool {
- timer := time.NewTimer(pc.t.ExpectContinueTimeout)
- defer timer.Stop()
-
- select {
- case _, ok := <-continueCh:
- return ok
- case <-timer.C:
- return true
- case <-pc.closech:
- return false
- }
- }
-}
-
-func newReadWriteCloserBody(br *bufio.Reader, rwc io.ReadWriteCloser) io.ReadWriteCloser {
- body := &readWriteCloserBody{ReadWriteCloser: rwc}
- if br.Buffered() != 0 {
- body.br = br
- }
- return body
-}
-
-// readWriteCloserBody is the Response.Body type used when we want to
-// give users write access to the Body through the underlying
-// connection (TCP, unless using custom dialers). This is then
-// the concrete type for a Response.Body on the 101 Switching
-// Protocols response, as used by WebSockets, h2c, etc.
-type readWriteCloserBody struct {
- _ incomparable
- br *bufio.Reader // used until empty
- io.ReadWriteCloser
-}
-
-func (b *readWriteCloserBody) Read(p []byte) (n int, err error) {
- if b.br != nil {
- if n := b.br.Buffered(); len(p) > n {
- p = p[:n]
- }
- n, err = b.br.Read(p)
- if b.br.Buffered() == 0 {
- b.br = nil
- }
- return n, err
- }
- return b.ReadWriteCloser.Read(p)
-}
-
-// nothingWrittenError wraps a write errors which ended up writing zero bytes.
-type nothingWrittenError struct {
- error
-}
-
-func (nwe nothingWrittenError) Unwrap() error {
- return nwe.error
-}
-
-func (pc *persistConn) writeLoop() {
- defer close(pc.writeLoopDone)
- for {
- select {
- case wr := <-pc.writech:
- startBytesWritten := pc.nwrite
- err := wr.req.Request.write(pc.bw, pc.isProxy, wr.req.extra, pc.waitForContinue(wr.continueCh))
- if bre, ok := err.(requestBodyReadError); ok {
- err = bre.error
- // Errors reading from the user's
- // Request.Body are high priority.
- // Set it here before sending on the
- // channels below or calling
- // pc.close() which tears down
- // connections and causes other
- // errors.
- wr.req.setError(err)
- }
- if err == nil {
- err = pc.bw.Flush()
- }
- if err != nil {
- if pc.nwrite == startBytesWritten {
- err = nothingWrittenError{err}
- }
- }
- pc.writeErrCh <- err // to the body reader, which might recycle us
- wr.ch <- err // to the roundTrip function
- if err != nil {
- pc.close(err)
- return
- }
- case <-pc.closech:
- return
- }
- }
-}
-
-// maxWriteWaitBeforeConnReuse is how long the a Transport RoundTrip
-// will wait to see the Request's Body.Write result after getting a
-// response from the server. See comments in (*persistConn).wroteRequest.
-const maxWriteWaitBeforeConnReuse = 50 * time.Millisecond
-
-// wroteRequest is a check before recycling a connection that the previous write
-// (from writeLoop above) happened and was successful.
-func (pc *persistConn) wroteRequest() bool {
- select {
- case err := <-pc.writeErrCh:
- // Common case: the write happened well before the response, so
- // avoid creating a timer.
- return err == nil
- default:
- // Rare case: the request was written in writeLoop above but
- // before it could send to pc.writeErrCh, the reader read it
- // all, processed it, and called us here. In this case, give the
- // write goroutine a bit of time to finish its send.
- //
- // Less rare case: We also get here in the legitimate case of
- // Issue 7569, where the writer is still writing (or stalled),
- // but the server has already replied. In this case, we don't
- // want to wait too long, and we want to return false so this
- // connection isn't re-used.
- t := time.NewTimer(maxWriteWaitBeforeConnReuse)
- defer t.Stop()
- select {
- case err := <-pc.writeErrCh:
- return err == nil
- case <-t.C:
- return false
- }
- }
-}
-
-// responseAndError is how the goroutine reading from an HTTP/1 server
-// communicates with the goroutine doing the RoundTrip.
-type responseAndError struct {
- _ incomparable
- res *Response // else use this response (see res method)
- err error
-}
-
-type requestAndChan struct {
- _ incomparable
- req *Request
- cancelKey cancelKey
- ch chan responseAndError // unbuffered; always send in select on callerGone
-
- // whether the Transport (as opposed to the user client code)
- // added the Accept-Encoding gzip header. If the Transport
- // set it, only then do we transparently decode the gzip.
- addedGzip bool
-
- // Optional blocking chan for Expect: 100-continue (for send).
- // If the request has an "Expect: 100-continue" header and
- // the server responds 100 Continue, readLoop send a value
- // to writeLoop via this chan.
- continueCh chan<- struct{}
-
- callerGone <-chan struct{} // closed when roundTrip caller has returned
-}
-
-// A writeRequest is sent by the caller's goroutine to the
-// writeLoop's goroutine to write a request while the read loop
-// concurrently waits on both the write response and the server's
-// reply.
-type writeRequest struct {
- req *transportRequest
- ch chan<- error
-
- // Optional blocking chan for Expect: 100-continue (for receive).
- // If not nil, writeLoop blocks sending request body until
- // it receives from this chan.
- continueCh <-chan struct{}
-}
-
-type httpError struct {
- err string
- timeout bool
-}
-
-func (e *httpError) Error() string { return e.err }
-func (e *httpError) Timeout() bool { return e.timeout }
-func (e *httpError) Temporary() bool { return true }
-
-var errTimeout error = &httpError{err: "net/http: timeout awaiting response headers", timeout: true}
-
-// errRequestCanceled is set to be identical to the one from h2 to facilitate
-// testing.
-var errRequestCanceled = http2errRequestCanceled
-var errRequestCanceledConn = errors.New("net/http: request canceled while waiting for connection") // TODO: unify?
-
-func nop() {}
-
-// testHooks. Always non-nil.
-var (
- testHookEnterRoundTrip = nop
- testHookWaitResLoop = nop
- testHookRoundTripRetried = nop
- testHookPrePendingDial = nop
- testHookPostPendingDial = nop
-
- testHookMu sync.Locker = fakeLocker{} // guards following
- testHookReadLoopBeforeNextRead = nop
-)
-
-func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) {
- testHookEnterRoundTrip()
- if !pc.t.replaceReqCanceler(req.cancelKey, pc.cancelRequest) {
- pc.t.putOrCloseIdleConn(pc)
- return nil, errRequestCanceled
- }
- pc.mu.Lock()
- pc.numExpectedResponses++
- headerFn := pc.mutateHeaderFunc
- pc.mu.Unlock()
-
- if headerFn != nil {
- headerFn(req.extraHeaders())
- }
-
- // Ask for a compressed version if the caller didn't set their
- // own value for Accept-Encoding. We only attempt to
- // uncompress the gzip stream if we were the layer that
- // requested it.
- requestedGzip := false
- if !pc.t.DisableCompression &&
- req.Header.Get("Accept-Encoding") == "" &&
- req.Header.Get("Range") == "" &&
- req.Method != "HEAD" {
- // Request gzip only, not deflate. Deflate is ambiguous and
- // not as universally supported anyway.
- // See: https://zlib.net/zlib_faq.html#faq39
- //
- // Note that we don't request this for HEAD requests,
- // due to a bug in nginx:
- // https://trac.nginx.org/nginx/ticket/358
- // https://golang.org/issue/5522
- //
- // We don't request gzip if the request is for a range, since
- // auto-decoding a portion of a gzipped document will just fail
- // anyway. See https://golang.org/issue/8923
- requestedGzip = true
- req.extraHeaders().Set("Accept-Encoding", "gzip")
- }
-
- var continueCh chan struct{}
- if req.ProtoAtLeast(1, 1) && req.Body != nil && req.expectsContinue() {
- continueCh = make(chan struct{}, 1)
- }
-
- if pc.t.DisableKeepAlives &&
- !req.wantsClose() &&
- !isProtocolSwitchHeader(req.Header) {
- req.extraHeaders().Set("Connection", "close")
- }
-
- gone := make(chan struct{})
- defer close(gone)
-
- defer func() {
- if err != nil {
- pc.t.setReqCanceler(req.cancelKey, nil)
- }
- }()
-
- const debugRoundTrip = false
-
- // Write the request concurrently with waiting for a response,
- // in case the server decides to reply before reading our full
- // request body.
- startBytesWritten := pc.nwrite
- writeErrCh := make(chan error, 1)
- pc.writech <- writeRequest{req, writeErrCh, continueCh}
-
- resc := make(chan responseAndError)
- pc.reqch <- requestAndChan{
- req: req.Request,
- cancelKey: req.cancelKey,
- ch: resc,
- addedGzip: requestedGzip,
- continueCh: continueCh,
- callerGone: gone,
- }
-
- var respHeaderTimer <-chan time.Time
- cancelChan := req.Request.Cancel
- ctxDoneChan := req.Context().Done()
- pcClosed := pc.closech
- canceled := false
- for {
- testHookWaitResLoop()
- select {
- case err := <-writeErrCh:
- if debugRoundTrip {
- req.logf("writeErrCh resv: %T/%#v", err, err)
- }
- if err != nil {
- pc.close(fmt.Errorf("write error: %w", err))
- return nil, pc.mapRoundTripError(req, startBytesWritten, err)
- }
- if d := pc.t.ResponseHeaderTimeout; d > 0 {
- if debugRoundTrip {
- req.logf("starting timer for %v", d)
- }
- timer := time.NewTimer(d)
- defer timer.Stop() // prevent leaks
- respHeaderTimer = timer.C
- }
- case <-pcClosed:
- pcClosed = nil
- if canceled || 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)
- }
- case <-respHeaderTimer:
- if debugRoundTrip {
- req.logf("timeout waiting for response headers.")
- }
- pc.close(errTimeout)
- return nil, errTimeout
- case re := <-resc:
- if (re.res == nil) == (re.err == nil) {
- panic(fmt.Sprintf("internal error: exactly one of res or err should be set; nil=%v", re.res == nil))
- }
- if debugRoundTrip {
- req.logf("resc recv: %p, %T/%#v", re.res, re.err, re.err)
- }
- if re.err != nil {
- return nil, pc.mapRoundTripError(req, startBytesWritten, re.err)
- }
- return re.res, nil
- case <-cancelChan:
- canceled = pc.t.cancelRequest(req.cancelKey, errRequestCanceled)
- cancelChan = nil
- case <-ctxDoneChan:
- canceled = pc.t.cancelRequest(req.cancelKey, req.Context().Err())
- cancelChan = nil
- ctxDoneChan = nil
- }
- }
-}
-
-// tLogKey is a context WithValue key for test debugging contexts containing
-// a t.Logf func. See export_test.go's Request.WithT method.
-type tLogKey struct{}
-
-func (tr *transportRequest) logf(format string, args ...any) {
- if logf, ok := tr.Request.Context().Value(tLogKey{}).(func(string, ...any)); ok {
- logf(time.Now().Format(time.RFC3339Nano)+": "+format, args...)
- }
-}
-
-// markReused marks this connection as having been successfully used for a
-// request and response.
-func (pc *persistConn) markReused() {
- pc.mu.Lock()
- pc.reused = true
- pc.mu.Unlock()
-}
-
-// close closes the underlying TCP connection and closes
-// the pc.closech channel.
-//
-// The provided err is only for testing and debugging; in normal
-// circumstances it should never be seen by users.
-func (pc *persistConn) close(err error) {
- pc.mu.Lock()
- defer pc.mu.Unlock()
- pc.closeLocked(err)
-}
-
-func (pc *persistConn) closeLocked(err error) {
- if err == nil {
- panic("nil error")
- }
- pc.broken = true
- if pc.closed == nil {
- pc.closed = err
- pc.t.decConnsPerHost(pc.cacheKey)
- // Close HTTP/1 (pc.alt == nil) connection.
- // HTTP/2 closes its connection itself.
- if pc.alt == nil {
- if err != errCallerOwnsConn {
- pc.conn.Close()
- }
- close(pc.closech)
- }
- }
- pc.mutateHeaderFunc = nil
-}
-
-var portMap = map[string]string{
- "http": "80",
- "https": "443",
- "socks5": "1080",
-}
-
-// canonicalAddr returns url.Host but always with a ":port" suffix.
-func canonicalAddr(url *url.URL) string {
- addr := url.Hostname()
- if v, err := idnaASCII(addr); err == nil {
- addr = v
- }
- port := url.Port()
- if port == "" {
- port = portMap[url.Scheme]
- }
- return net.JoinHostPort(addr, port)
-}
-
-// bodyEOFSignal is used by the HTTP/1 transport when reading response
-// bodies to make sure we see the end of a response body before
-// proceeding and reading on the connection again.
-//
-// It wraps a ReadCloser but runs fn (if non-nil) at most
-// once, right before its final (error-producing) Read or Close call
-// returns. fn should return the new error to return from Read or Close.
-//
-// If earlyCloseFn is non-nil and Close is called before io.EOF is
-// seen, earlyCloseFn is called instead of fn, and its return value is
-// the return value from Close.
-type bodyEOFSignal struct {
- body io.ReadCloser
- mu sync.Mutex // guards following 4 fields
- closed bool // whether Close has been called
- rerr error // sticky Read error
- fn func(error) error // err will be nil on Read io.EOF
- earlyCloseFn func() error // optional alt Close func used if io.EOF not seen
-}
-
-var errReadOnClosedResBody = errors.New("http: read on closed response body")
-
-func (es *bodyEOFSignal) Read(p []byte) (n int, err error) {
- es.mu.Lock()
- closed, rerr := es.closed, es.rerr
- es.mu.Unlock()
- if closed {
- return 0, errReadOnClosedResBody
- }
- if rerr != nil {
- return 0, rerr
- }
-
- n, err = es.body.Read(p)
- if err != nil {
- es.mu.Lock()
- defer es.mu.Unlock()
- if es.rerr == nil {
- es.rerr = err
- }
- err = es.condfn(err)
- }
- return
-}
-
-func (es *bodyEOFSignal) Close() error {
- es.mu.Lock()
- defer es.mu.Unlock()
- if es.closed {
- return nil
- }
- es.closed = true
- if es.earlyCloseFn != nil && es.rerr != io.EOF {
- return es.earlyCloseFn()
- }
- err := es.body.Close()
- return es.condfn(err)
-}
-
-// caller must hold es.mu.
-func (es *bodyEOFSignal) condfn(err error) error {
- if es.fn == nil {
- return err
- }
- err = es.fn(err)
- es.fn = nil
- return err
-}
-
-// gzipReader wraps a response body so it can lazily
-// call gzip.NewReader on the first call to Read
-type gzipReader struct {
- _ incomparable
- body *bodyEOFSignal // underlying HTTP/1 response body framing
- zr *gzip.Reader // lazily-initialized gzip reader
- zerr error // any error from gzip.NewReader; sticky
-}
-
-func (gz *gzipReader) Read(p []byte) (n int, err error) {
- if gz.zr == nil {
- if gz.zerr == nil {
- gz.zr, gz.zerr = gzip.NewReader(gz.body)
- }
- if gz.zerr != nil {
- return 0, gz.zerr
- }
- }
-
- gz.body.mu.Lock()
- if gz.body.closed {
- err = errReadOnClosedResBody
- }
- gz.body.mu.Unlock()
-
- if err != nil {
- return 0, err
- }
- return gz.zr.Read(p)
-}
-
-func (gz *gzipReader) Close() error {
- return gz.body.Close()
-}
-
-type tlsHandshakeTimeoutError struct{}
-
-func (tlsHandshakeTimeoutError) Timeout() bool { return true }
-func (tlsHandshakeTimeoutError) Temporary() bool { return true }
-func (tlsHandshakeTimeoutError) Error() string { return "net/http: TLS handshake timeout" }
-
-// fakeLocker is a sync.Locker which does nothing. It's used to guard
-// test-only fields when not under test, to avoid runtime atomic
-// overhead.
-type fakeLocker struct{}
-
-func (fakeLocker) Lock() {}
-func (fakeLocker) Unlock() {}
-
-// cloneTLSConfig returns a shallow clone of cfg, or a new zero tls.Config if
-// cfg is nil. This is safe to call even if cfg is in active use by a TLS
-// client or server.
-func cloneTLSConfig(cfg *tls.Config) *tls.Config {
- if cfg == nil {
- return &tls.Config{}
- }
- return cfg.Clone()
-}
-
-type connLRU struct {
- ll *list.List // list.Element.Value type is of *persistConn
- m map[*persistConn]*list.Element
-}
-
-// add adds pc to the head of the linked list.
-func (cl *connLRU) add(pc *persistConn) {
- if cl.ll == nil {
- cl.ll = list.New()
- cl.m = make(map[*persistConn]*list.Element)
- }
- ele := cl.ll.PushFront(pc)
- if _, ok := cl.m[pc]; ok {
- panic("persistConn was already in LRU")
- }
- cl.m[pc] = ele
-}
-
-func (cl *connLRU) removeOldest() *persistConn {
- ele := cl.ll.Back()
- pc := ele.Value.(*persistConn)
- cl.ll.Remove(ele)
- delete(cl.m, pc)
- return pc
-}
-
-// remove removes pc from cl.
-func (cl *connLRU) remove(pc *persistConn) {
- if ele, ok := cl.m[pc]; ok {
- cl.ll.Remove(ele)
- delete(cl.m, pc)
- }
-}
-
-// len returns the number of items in the cache.
-func (cl *connLRU) len() int {
- return len(cl.m)
-}
diff --git a/contrib/go/_std_1.20/src/net/http/transport_default_other.go b/contrib/go/_std_1.20/src/net/http/transport_default_other.go
deleted file mode 100644
index 8a2f1cc42b..0000000000
--- a/contrib/go/_std_1.20/src/net/http/transport_default_other.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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.
-
-//go:build !(js && wasm)
-// +build !js !wasm
-
-package http
-
-import (
- "context"
- "net"
-)
-
-func defaultTransportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) {
- return dialer.DialContext
-}
diff --git a/contrib/go/_std_1.20/src/net/http/ya.make b/contrib/go/_std_1.20/src/net/http/ya.make
deleted file mode 100644
index bf20b09007..0000000000
--- a/contrib/go/_std_1.20/src/net/http/ya.make
+++ /dev/null
@@ -1,40 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- client.go
- clone.go
- cookie.go
- doc.go
- filetransport.go
- fs.go
- h2_bundle.go
- h2_error.go
- header.go
- http.go
- jar.go
- method.go
- request.go
- response.go
- responsecontroller.go
- roundtrip.go
- server.go
- sniff.go
- socks_bundle.go
- status.go
- transfer.go
- transport.go
- transport_default_other.go
-)
-
-END()
-
-RECURSE(
- cgi
- cookiejar
- fcgi
- httptest
- httptrace
- httputil
- internal
- pprof
-)
diff --git a/contrib/go/_std_1.20/src/net/internal/socktest/switch_unix.go b/contrib/go/_std_1.20/src/net/internal/socktest/switch_unix.go
deleted file mode 100644
index f2e95d68c1..0000000000
--- a/contrib/go/_std_1.20/src/net/internal/socktest/switch_unix.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2015 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.
-
-//go:build unix || (js && wasm)
-
-package socktest
-
-// Sockets maps a socket descriptor to the status of socket.
-type Sockets map[int]Status
-
-func (sw *Switch) sockso(s int) *Status {
- sw.smu.RLock()
- defer sw.smu.RUnlock()
- so, ok := sw.sotab[s]
- if !ok {
- return nil
- }
- return &so
-}
-
-// addLocked returns a new Status without locking.
-// sw.smu must be held before call.
-func (sw *Switch) addLocked(s, family, sotype, proto int) *Status {
- sw.once.Do(sw.init)
- so := Status{Cookie: cookie(family, sotype, proto)}
- sw.sotab[s] = so
- return &so
-}
diff --git a/contrib/go/_std_1.20/src/net/internal/socktest/sys_unix.go b/contrib/go/_std_1.20/src/net/internal/socktest/sys_unix.go
deleted file mode 100644
index e1040d3087..0000000000
--- a/contrib/go/_std_1.20/src/net/internal/socktest/sys_unix.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2015 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.
-
-//go:build unix || (js && wasm)
-
-package socktest
-
-import "syscall"
-
-// Socket wraps syscall.Socket.
-func (sw *Switch) Socket(family, sotype, proto int) (s int, err error) {
- sw.once.Do(sw.init)
-
- so := &Status{Cookie: cookie(family, sotype, proto)}
- sw.fmu.RLock()
- f := sw.fltab[FilterSocket]
- sw.fmu.RUnlock()
-
- af, err := f.apply(so)
- if err != nil {
- return -1, err
- }
- s, so.Err = syscall.Socket(family, sotype, proto)
- if err = af.apply(so); err != nil {
- if so.Err == nil {
- syscall.Close(s)
- }
- return -1, err
- }
-
- sw.smu.Lock()
- defer sw.smu.Unlock()
- if so.Err != nil {
- sw.stats.getLocked(so.Cookie).OpenFailed++
- return -1, so.Err
- }
- nso := sw.addLocked(s, family, sotype, proto)
- sw.stats.getLocked(nso.Cookie).Opened++
- return s, nil
-}
-
-// Close wraps syscall.Close.
-func (sw *Switch) Close(s int) (err error) {
- so := sw.sockso(s)
- if so == nil {
- return syscall.Close(s)
- }
- sw.fmu.RLock()
- f := sw.fltab[FilterClose]
- sw.fmu.RUnlock()
-
- af, err := f.apply(so)
- if err != nil {
- return err
- }
- so.Err = syscall.Close(s)
- if err = af.apply(so); err != nil {
- return err
- }
-
- sw.smu.Lock()
- defer sw.smu.Unlock()
- if so.Err != nil {
- sw.stats.getLocked(so.Cookie).CloseFailed++
- return so.Err
- }
- delete(sw.sotab, s)
- sw.stats.getLocked(so.Cookie).Closed++
- return nil
-}
-
-// Connect wraps syscall.Connect.
-func (sw *Switch) Connect(s int, sa syscall.Sockaddr) (err error) {
- so := sw.sockso(s)
- if so == nil {
- return syscall.Connect(s, sa)
- }
- sw.fmu.RLock()
- f := sw.fltab[FilterConnect]
- sw.fmu.RUnlock()
-
- af, err := f.apply(so)
- if err != nil {
- return err
- }
- so.Err = syscall.Connect(s, sa)
- if err = af.apply(so); err != nil {
- return err
- }
-
- sw.smu.Lock()
- defer sw.smu.Unlock()
- if so.Err != nil {
- sw.stats.getLocked(so.Cookie).ConnectFailed++
- return so.Err
- }
- sw.stats.getLocked(so.Cookie).Connected++
- return nil
-}
-
-// Listen wraps syscall.Listen.
-func (sw *Switch) Listen(s, backlog int) (err error) {
- so := sw.sockso(s)
- if so == nil {
- return syscall.Listen(s, backlog)
- }
- sw.fmu.RLock()
- f := sw.fltab[FilterListen]
- sw.fmu.RUnlock()
-
- af, err := f.apply(so)
- if err != nil {
- return err
- }
- so.Err = syscall.Listen(s, backlog)
- if err = af.apply(so); err != nil {
- return err
- }
-
- sw.smu.Lock()
- defer sw.smu.Unlock()
- if so.Err != nil {
- sw.stats.getLocked(so.Cookie).ListenFailed++
- return so.Err
- }
- sw.stats.getLocked(so.Cookie).Listened++
- return nil
-}
-
-// Accept wraps syscall.Accept.
-func (sw *Switch) Accept(s int) (ns int, sa syscall.Sockaddr, err error) {
- so := sw.sockso(s)
- if so == nil {
- return syscall.Accept(s)
- }
- sw.fmu.RLock()
- f := sw.fltab[FilterAccept]
- sw.fmu.RUnlock()
-
- af, err := f.apply(so)
- if err != nil {
- return -1, nil, err
- }
- ns, sa, so.Err = syscall.Accept(s)
- if err = af.apply(so); err != nil {
- if so.Err == nil {
- syscall.Close(ns)
- }
- return -1, nil, err
- }
-
- sw.smu.Lock()
- defer sw.smu.Unlock()
- if so.Err != nil {
- sw.stats.getLocked(so.Cookie).AcceptFailed++
- return -1, nil, so.Err
- }
- nso := sw.addLocked(ns, so.Cookie.Family(), so.Cookie.Type(), so.Cookie.Protocol())
- sw.stats.getLocked(nso.Cookie).Accepted++
- return ns, sa, nil
-}
-
-// GetsockoptInt wraps syscall.GetsockoptInt.
-func (sw *Switch) GetsockoptInt(s, level, opt int) (soerr int, err error) {
- so := sw.sockso(s)
- if so == nil {
- return syscall.GetsockoptInt(s, level, opt)
- }
- sw.fmu.RLock()
- f := sw.fltab[FilterGetsockoptInt]
- sw.fmu.RUnlock()
-
- af, err := f.apply(so)
- if err != nil {
- return -1, err
- }
- soerr, so.Err = syscall.GetsockoptInt(s, level, opt)
- so.SocketErr = syscall.Errno(soerr)
- if err = af.apply(so); err != nil {
- return -1, err
- }
-
- if so.Err != nil {
- return -1, so.Err
- }
- if opt == syscall.SO_ERROR && (so.SocketErr == syscall.Errno(0) || so.SocketErr == syscall.EISCONN) {
- sw.smu.Lock()
- sw.stats.getLocked(so.Cookie).Connected++
- sw.smu.Unlock()
- }
- return soerr, nil
-}
diff --git a/contrib/go/_std_1.20/src/net/internal/socktest/ya.make b/contrib/go/_std_1.20/src/net/internal/socktest/ya.make
deleted file mode 100644
index 51ea9bc7d5..0000000000
--- a/contrib/go/_std_1.20/src/net/internal/socktest/ya.make
+++ /dev/null
@@ -1,30 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- switch.go
- switch_posix.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- switch_unix.go
- sys_unix.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- switch_unix.go
- sys_cloexec.go
- sys_unix.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- switch_windows.go
- sys_windows.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/ip.go b/contrib/go/_std_1.20/src/net/ip.go
deleted file mode 100644
index d9f3da7021..0000000000
--- a/contrib/go/_std_1.20/src/net/ip.go
+++ /dev/null
@@ -1,765 +0,0 @@
-// Copyright 2009 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.
-
-// IP address manipulations
-//
-// IPv4 addresses are 4 bytes; IPv6 addresses are 16 bytes.
-// An IPv4 address can be converted to an IPv6 address by
-// adding a canonical prefix (10 zeros, 2 0xFFs).
-// This library accepts either size of byte slice but always
-// returns 16-byte addresses.
-
-package net
-
-import (
- "internal/bytealg"
- "internal/itoa"
-)
-
-// IP address lengths (bytes).
-const (
- IPv4len = 4
- IPv6len = 16
-)
-
-// An IP is a single IP address, a slice of bytes.
-// Functions in this package accept either 4-byte (IPv4)
-// or 16-byte (IPv6) slices as input.
-//
-// Note that in this documentation, referring to an
-// IP address as an IPv4 address or an IPv6 address
-// is a semantic property of the address, not just the
-// length of the byte slice: a 16-byte slice can still
-// be an IPv4 address.
-type IP []byte
-
-// An IPMask is a bitmask that can be used to manipulate
-// IP addresses for IP addressing and routing.
-//
-// See type IPNet and func ParseCIDR for details.
-type IPMask []byte
-
-// An IPNet represents an IP network.
-type IPNet struct {
- IP IP // network number
- Mask IPMask // network mask
-}
-
-// IPv4 returns the IP address (in 16-byte form) of the
-// IPv4 address a.b.c.d.
-func IPv4(a, b, c, d byte) IP {
- p := make(IP, IPv6len)
- copy(p, v4InV6Prefix)
- p[12] = a
- p[13] = b
- p[14] = c
- p[15] = d
- return p
-}
-
-var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
-
-// IPv4Mask returns the IP mask (in 4-byte form) of the
-// IPv4 mask a.b.c.d.
-func IPv4Mask(a, b, c, d byte) IPMask {
- p := make(IPMask, IPv4len)
- p[0] = a
- p[1] = b
- p[2] = c
- p[3] = d
- return p
-}
-
-// CIDRMask returns an IPMask consisting of 'ones' 1 bits
-// followed by 0s up to a total length of 'bits' bits.
-// For a mask of this form, CIDRMask is the inverse of IPMask.Size.
-func CIDRMask(ones, bits int) IPMask {
- if bits != 8*IPv4len && bits != 8*IPv6len {
- return nil
- }
- if ones < 0 || ones > bits {
- return nil
- }
- l := bits / 8
- m := make(IPMask, l)
- n := uint(ones)
- for i := 0; i < l; i++ {
- if n >= 8 {
- m[i] = 0xff
- n -= 8
- continue
- }
- m[i] = ^byte(0xff >> n)
- n = 0
- }
- return m
-}
-
-// Well-known IPv4 addresses
-var (
- IPv4bcast = IPv4(255, 255, 255, 255) // limited broadcast
- IPv4allsys = IPv4(224, 0, 0, 1) // all systems
- IPv4allrouter = IPv4(224, 0, 0, 2) // all routers
- IPv4zero = IPv4(0, 0, 0, 0) // all zeros
-)
-
-// Well-known IPv6 addresses
-var (
- IPv6zero = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- IPv6unspecified = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
- IPv6loopback = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
- IPv6interfacelocalallnodes = IP{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
- IPv6linklocalallnodes = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
- IPv6linklocalallrouters = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}
-)
-
-// IsUnspecified reports whether ip is an unspecified address, either
-// the IPv4 address "0.0.0.0" or the IPv6 address "::".
-func (ip IP) IsUnspecified() bool {
- return ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified)
-}
-
-// IsLoopback reports whether ip is a loopback address.
-func (ip IP) IsLoopback() bool {
- if ip4 := ip.To4(); ip4 != nil {
- return ip4[0] == 127
- }
- return ip.Equal(IPv6loopback)
-}
-
-// IsPrivate reports whether ip is a private address, according to
-// RFC 1918 (IPv4 addresses) and RFC 4193 (IPv6 addresses).
-func (ip IP) IsPrivate() bool {
- if ip4 := ip.To4(); ip4 != nil {
- // Following RFC 1918, Section 3. Private Address Space which says:
- // The Internet Assigned Numbers Authority (IANA) has reserved the
- // following three blocks of the IP address space for private internets:
- // 10.0.0.0 - 10.255.255.255 (10/8 prefix)
- // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
- // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
- return ip4[0] == 10 ||
- (ip4[0] == 172 && ip4[1]&0xf0 == 16) ||
- (ip4[0] == 192 && ip4[1] == 168)
- }
- // Following RFC 4193, Section 8. IANA Considerations which says:
- // The IANA has assigned the FC00::/7 prefix to "Unique Local Unicast".
- return len(ip) == IPv6len && ip[0]&0xfe == 0xfc
-}
-
-// IsMulticast reports whether ip is a multicast address.
-func (ip IP) IsMulticast() bool {
- if ip4 := ip.To4(); ip4 != nil {
- return ip4[0]&0xf0 == 0xe0
- }
- return len(ip) == IPv6len && ip[0] == 0xff
-}
-
-// IsInterfaceLocalMulticast reports whether ip is
-// an interface-local multicast address.
-func (ip IP) IsInterfaceLocalMulticast() bool {
- return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x01
-}
-
-// IsLinkLocalMulticast reports whether ip is a link-local
-// multicast address.
-func (ip IP) IsLinkLocalMulticast() bool {
- if ip4 := ip.To4(); ip4 != nil {
- return ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0
- }
- return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x02
-}
-
-// IsLinkLocalUnicast reports whether ip is a link-local
-// unicast address.
-func (ip IP) IsLinkLocalUnicast() bool {
- if ip4 := ip.To4(); ip4 != nil {
- return ip4[0] == 169 && ip4[1] == 254
- }
- return len(ip) == IPv6len && ip[0] == 0xfe && ip[1]&0xc0 == 0x80
-}
-
-// IsGlobalUnicast reports whether ip is a global unicast
-// address.
-//
-// The identification of global unicast addresses uses address type
-// identification as defined in RFC 1122, RFC 4632 and RFC 4291 with
-// the exception of IPv4 directed broadcast addresses.
-// It returns true even if ip is in IPv4 private address space or
-// local IPv6 unicast address space.
-func (ip IP) IsGlobalUnicast() bool {
- return (len(ip) == IPv4len || len(ip) == IPv6len) &&
- !ip.Equal(IPv4bcast) &&
- !ip.IsUnspecified() &&
- !ip.IsLoopback() &&
- !ip.IsMulticast() &&
- !ip.IsLinkLocalUnicast()
-}
-
-// Is p all zeros?
-func isZeros(p IP) bool {
- for i := 0; i < len(p); i++ {
- if p[i] != 0 {
- return false
- }
- }
- return true
-}
-
-// To4 converts the IPv4 address ip to a 4-byte representation.
-// If ip is not an IPv4 address, To4 returns nil.
-func (ip IP) To4() IP {
- if len(ip) == IPv4len {
- return ip
- }
- if len(ip) == IPv6len &&
- isZeros(ip[0:10]) &&
- ip[10] == 0xff &&
- ip[11] == 0xff {
- return ip[12:16]
- }
- return nil
-}
-
-// To16 converts the IP address ip to a 16-byte representation.
-// If ip is not an IP address (it is the wrong length), To16 returns nil.
-func (ip IP) To16() IP {
- if len(ip) == IPv4len {
- return IPv4(ip[0], ip[1], ip[2], ip[3])
- }
- if len(ip) == IPv6len {
- return ip
- }
- return nil
-}
-
-// Default route masks for IPv4.
-var (
- classAMask = IPv4Mask(0xff, 0, 0, 0)
- classBMask = IPv4Mask(0xff, 0xff, 0, 0)
- classCMask = IPv4Mask(0xff, 0xff, 0xff, 0)
-)
-
-// DefaultMask returns the default IP mask for the IP address ip.
-// Only IPv4 addresses have default masks; DefaultMask returns
-// nil if ip is not a valid IPv4 address.
-func (ip IP) DefaultMask() IPMask {
- if ip = ip.To4(); ip == nil {
- return nil
- }
- switch {
- case ip[0] < 0x80:
- return classAMask
- case ip[0] < 0xC0:
- return classBMask
- default:
- return classCMask
- }
-}
-
-func allFF(b []byte) bool {
- for _, c := range b {
- if c != 0xff {
- return false
- }
- }
- return true
-}
-
-// Mask returns the result of masking the IP address ip with mask.
-func (ip IP) Mask(mask IPMask) IP {
- if len(mask) == IPv6len && len(ip) == IPv4len && allFF(mask[:12]) {
- mask = mask[12:]
- }
- if len(mask) == IPv4len && len(ip) == IPv6len && bytealg.Equal(ip[:12], v4InV6Prefix) {
- ip = ip[12:]
- }
- n := len(ip)
- if n != len(mask) {
- return nil
- }
- out := make(IP, n)
- for i := 0; i < n; i++ {
- out[i] = ip[i] & mask[i]
- }
- return out
-}
-
-// ubtoa encodes the string form of the integer v to dst[start:] and
-// returns the number of bytes written to dst. The caller must ensure
-// that dst has sufficient length.
-func ubtoa(dst []byte, start int, v byte) int {
- if v < 10 {
- dst[start] = v + '0'
- return 1
- } else if v < 100 {
- dst[start+1] = v%10 + '0'
- dst[start] = v/10 + '0'
- return 2
- }
-
- dst[start+2] = v%10 + '0'
- dst[start+1] = (v/10)%10 + '0'
- dst[start] = v/100 + '0'
- return 3
-}
-
-// String returns the string form of the IP address ip.
-// It returns one of 4 forms:
-// - "<nil>", if ip has length 0
-// - dotted decimal ("192.0.2.1"), if ip is an IPv4 or IP4-mapped IPv6 address
-// - IPv6 conforming to RFC 5952 ("2001:db8::1"), if ip is a valid IPv6 address
-// - the hexadecimal form of ip, without punctuation, if no other cases apply
-func (ip IP) String() string {
- p := ip
-
- if len(ip) == 0 {
- return "<nil>"
- }
-
- // If IPv4, use dotted notation.
- if p4 := p.To4(); len(p4) == IPv4len {
- const maxIPv4StringLen = len("255.255.255.255")
- b := make([]byte, maxIPv4StringLen)
-
- n := ubtoa(b, 0, p4[0])
- b[n] = '.'
- n++
-
- n += ubtoa(b, n, p4[1])
- b[n] = '.'
- n++
-
- n += ubtoa(b, n, p4[2])
- b[n] = '.'
- n++
-
- n += ubtoa(b, n, p4[3])
- return string(b[:n])
- }
- if len(p) != IPv6len {
- return "?" + hexString(ip)
- }
-
- // Find longest run of zeros.
- e0 := -1
- e1 := -1
- for i := 0; i < IPv6len; i += 2 {
- j := i
- for j < IPv6len && p[j] == 0 && p[j+1] == 0 {
- j += 2
- }
- if j > i && j-i > e1-e0 {
- e0 = i
- e1 = j
- i = j
- }
- }
- // The symbol "::" MUST NOT be used to shorten just one 16 bit 0 field.
- if e1-e0 <= 2 {
- e0 = -1
- e1 = -1
- }
-
- const maxLen = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
- b := make([]byte, 0, maxLen)
-
- // Print with possible :: in place of run of zeros
- for i := 0; i < IPv6len; i += 2 {
- if i == e0 {
- b = append(b, ':', ':')
- i = e1
- if i >= IPv6len {
- break
- }
- } else if i > 0 {
- b = append(b, ':')
- }
- b = appendHex(b, (uint32(p[i])<<8)|uint32(p[i+1]))
- }
- return string(b)
-}
-
-func hexString(b []byte) string {
- s := make([]byte, len(b)*2)
- for i, tn := range b {
- s[i*2], s[i*2+1] = hexDigit[tn>>4], hexDigit[tn&0xf]
- }
- return string(s)
-}
-
-// ipEmptyString is like ip.String except that it returns
-// an empty string when ip is unset.
-func ipEmptyString(ip IP) string {
- if len(ip) == 0 {
- return ""
- }
- return ip.String()
-}
-
-// MarshalText implements the encoding.TextMarshaler interface.
-// The encoding is the same as returned by String, with one exception:
-// When len(ip) is zero, it returns an empty slice.
-func (ip IP) MarshalText() ([]byte, error) {
- if len(ip) == 0 {
- return []byte(""), nil
- }
- if len(ip) != IPv4len && len(ip) != IPv6len {
- return nil, &AddrError{Err: "invalid IP address", Addr: hexString(ip)}
- }
- return []byte(ip.String()), nil
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler interface.
-// The IP address is expected in a form accepted by ParseIP.
-func (ip *IP) UnmarshalText(text []byte) error {
- if len(text) == 0 {
- *ip = nil
- return nil
- }
- s := string(text)
- x := ParseIP(s)
- if x == nil {
- return &ParseError{Type: "IP address", Text: s}
- }
- *ip = x
- return nil
-}
-
-// Equal reports whether ip and x are the same IP address.
-// An IPv4 address and that same address in IPv6 form are
-// considered to be equal.
-func (ip IP) Equal(x IP) bool {
- if len(ip) == len(x) {
- return bytealg.Equal(ip, x)
- }
- if len(ip) == IPv4len && len(x) == IPv6len {
- return bytealg.Equal(x[0:12], v4InV6Prefix) && bytealg.Equal(ip, x[12:])
- }
- if len(ip) == IPv6len && len(x) == IPv4len {
- return bytealg.Equal(ip[0:12], v4InV6Prefix) && bytealg.Equal(ip[12:], x)
- }
- return false
-}
-
-func (ip IP) matchAddrFamily(x IP) bool {
- return ip.To4() != nil && x.To4() != nil || ip.To16() != nil && ip.To4() == nil && x.To16() != nil && x.To4() == nil
-}
-
-// If mask is a sequence of 1 bits followed by 0 bits,
-// return the number of 1 bits.
-func simpleMaskLength(mask IPMask) int {
- var n int
- for i, v := range mask {
- if v == 0xff {
- n += 8
- continue
- }
- // found non-ff byte
- // count 1 bits
- for v&0x80 != 0 {
- n++
- v <<= 1
- }
- // rest must be 0 bits
- if v != 0 {
- return -1
- }
- for i++; i < len(mask); i++ {
- if mask[i] != 0 {
- return -1
- }
- }
- break
- }
- return n
-}
-
-// Size returns the number of leading ones and total bits in the mask.
-// If the mask is not in the canonical form--ones followed by zeros--then
-// Size returns 0, 0.
-func (m IPMask) Size() (ones, bits int) {
- ones, bits = simpleMaskLength(m), len(m)*8
- if ones == -1 {
- return 0, 0
- }
- return
-}
-
-// String returns the hexadecimal form of m, with no punctuation.
-func (m IPMask) String() string {
- if len(m) == 0 {
- return "<nil>"
- }
- return hexString(m)
-}
-
-func networkNumberAndMask(n *IPNet) (ip IP, m IPMask) {
- if ip = n.IP.To4(); ip == nil {
- ip = n.IP
- if len(ip) != IPv6len {
- return nil, nil
- }
- }
- m = n.Mask
- switch len(m) {
- case IPv4len:
- if len(ip) != IPv4len {
- return nil, nil
- }
- case IPv6len:
- if len(ip) == IPv4len {
- m = m[12:]
- }
- default:
- return nil, nil
- }
- return
-}
-
-// Contains reports whether the network includes ip.
-func (n *IPNet) Contains(ip IP) bool {
- nn, m := networkNumberAndMask(n)
- if x := ip.To4(); x != nil {
- ip = x
- }
- l := len(ip)
- if l != len(nn) {
- return false
- }
- for i := 0; i < l; i++ {
- if nn[i]&m[i] != ip[i]&m[i] {
- return false
- }
- }
- return true
-}
-
-// Network returns the address's network name, "ip+net".
-func (n *IPNet) Network() string { return "ip+net" }
-
-// String returns the CIDR notation of n like "192.0.2.0/24"
-// or "2001:db8::/48" as defined in RFC 4632 and RFC 4291.
-// If the mask is not in the canonical form, it returns the
-// string which consists of an IP address, followed by a slash
-// character and a mask expressed as hexadecimal form with no
-// punctuation like "198.51.100.0/c000ff00".
-func (n *IPNet) String() string {
- if n == nil {
- return "<nil>"
- }
- nn, m := networkNumberAndMask(n)
- if nn == nil || m == nil {
- return "<nil>"
- }
- l := simpleMaskLength(m)
- if l == -1 {
- return nn.String() + "/" + m.String()
- }
- return nn.String() + "/" + itoa.Uitoa(uint(l))
-}
-
-// Parse IPv4 address (d.d.d.d).
-func parseIPv4(s string) IP {
- var p [IPv4len]byte
- for i := 0; i < IPv4len; i++ {
- if len(s) == 0 {
- // Missing octets.
- return nil
- }
- if i > 0 {
- if s[0] != '.' {
- return nil
- }
- s = s[1:]
- }
- n, c, ok := dtoi(s)
- if !ok || n > 0xFF {
- return nil
- }
- if c > 1 && s[0] == '0' {
- // Reject non-zero components with leading zeroes.
- return nil
- }
- s = s[c:]
- p[i] = byte(n)
- }
- if len(s) != 0 {
- return nil
- }
- return IPv4(p[0], p[1], p[2], p[3])
-}
-
-// parseIPv6Zone parses s as a literal IPv6 address and its associated zone
-// identifier which is described in RFC 4007.
-func parseIPv6Zone(s string) (IP, string) {
- s, zone := splitHostZone(s)
- return parseIPv6(s), zone
-}
-
-// parseIPv6 parses s as a literal IPv6 address described in RFC 4291
-// and RFC 5952.
-func parseIPv6(s string) (ip IP) {
- ip = make(IP, IPv6len)
- ellipsis := -1 // position of ellipsis in ip
-
- // Might have leading ellipsis
- if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
- ellipsis = 0
- s = s[2:]
- // Might be only ellipsis
- if len(s) == 0 {
- return ip
- }
- }
-
- // Loop, parsing hex numbers followed by colon.
- i := 0
- for i < IPv6len {
- // Hex number.
- n, c, ok := xtoi(s)
- if !ok || n > 0xFFFF {
- return nil
- }
-
- // If followed by dot, might be in trailing IPv4.
- if c < len(s) && s[c] == '.' {
- if ellipsis < 0 && i != IPv6len-IPv4len {
- // Not the right place.
- return nil
- }
- if i+IPv4len > IPv6len {
- // Not enough room.
- return nil
- }
- ip4 := parseIPv4(s)
- if ip4 == nil {
- return nil
- }
- ip[i] = ip4[12]
- ip[i+1] = ip4[13]
- ip[i+2] = ip4[14]
- ip[i+3] = ip4[15]
- s = ""
- i += IPv4len
- break
- }
-
- // Save this 16-bit chunk.
- ip[i] = byte(n >> 8)
- ip[i+1] = byte(n)
- i += 2
-
- // Stop at end of string.
- s = s[c:]
- if len(s) == 0 {
- break
- }
-
- // Otherwise must be followed by colon and more.
- if s[0] != ':' || len(s) == 1 {
- return nil
- }
- s = s[1:]
-
- // Look for ellipsis.
- if s[0] == ':' {
- if ellipsis >= 0 { // already have one
- return nil
- }
- ellipsis = i
- s = s[1:]
- if len(s) == 0 { // can be at end
- break
- }
- }
- }
-
- // Must have used entire string.
- if len(s) != 0 {
- return nil
- }
-
- // If didn't parse enough, expand ellipsis.
- if i < IPv6len {
- if ellipsis < 0 {
- return nil
- }
- n := IPv6len - i
- for j := i - 1; j >= ellipsis; j-- {
- ip[j+n] = ip[j]
- }
- for j := ellipsis + n - 1; j >= ellipsis; j-- {
- ip[j] = 0
- }
- } else if ellipsis >= 0 {
- // Ellipsis must represent at least one 0 group.
- return nil
- }
- return ip
-}
-
-// ParseIP parses s as an IP address, returning the result.
-// The string s can be in IPv4 dotted decimal ("192.0.2.1"), IPv6
-// ("2001:db8::68"), or IPv4-mapped IPv6 ("::ffff:192.0.2.1") form.
-// If s is not a valid textual representation of an IP address,
-// ParseIP returns nil.
-func ParseIP(s string) IP {
- for i := 0; i < len(s); i++ {
- switch s[i] {
- case '.':
- return parseIPv4(s)
- case ':':
- return parseIPv6(s)
- }
- }
- return nil
-}
-
-// parseIPZone parses s as an IP address, return it and its associated zone
-// identifier (IPv6 only).
-func parseIPZone(s string) (IP, string) {
- for i := 0; i < len(s); i++ {
- switch s[i] {
- case '.':
- return parseIPv4(s), ""
- case ':':
- return parseIPv6Zone(s)
- }
- }
- return nil, ""
-}
-
-// ParseCIDR parses s as a CIDR notation IP address and prefix length,
-// like "192.0.2.0/24" or "2001:db8::/32", as defined in
-// RFC 4632 and RFC 4291.
-//
-// It returns the IP address and the network implied by the IP and
-// prefix length.
-// For example, ParseCIDR("192.0.2.1/24") returns the IP address
-// 192.0.2.1 and the network 192.0.2.0/24.
-func ParseCIDR(s string) (IP, *IPNet, error) {
- i := bytealg.IndexByteString(s, '/')
- if i < 0 {
- return nil, nil, &ParseError{Type: "CIDR address", Text: s}
- }
- addr, mask := s[:i], s[i+1:]
- iplen := IPv4len
- ip := parseIPv4(addr)
- if ip == nil {
- iplen = IPv6len
- ip = parseIPv6(addr)
- }
- n, i, ok := dtoi(mask)
- if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
- return nil, nil, &ParseError{Type: "CIDR address", Text: s}
- }
- m := CIDRMask(n, 8*iplen)
- return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
-}
-
-func copyIP(x IP) IP {
- y := make(IP, len(x))
- copy(y, x)
- return y
-}
diff --git a/contrib/go/_std_1.20/src/net/iprawsock_posix.go b/contrib/go/_std_1.20/src/net/iprawsock_posix.go
deleted file mode 100644
index 7b4d23927f..0000000000
--- a/contrib/go/_std_1.20/src/net/iprawsock_posix.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2010 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.
-
-//go:build unix || (js && wasm) || windows
-
-package net
-
-import (
- "context"
- "syscall"
-)
-
-func sockaddrToIP(sa syscall.Sockaddr) Addr {
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- return &IPAddr{IP: sa.Addr[0:]}
- case *syscall.SockaddrInet6:
- return &IPAddr{IP: sa.Addr[0:], Zone: zoneCache.name(int(sa.ZoneId))}
- }
- return nil
-}
-
-func (a *IPAddr) family() int {
- if a == nil || len(a.IP) <= IPv4len {
- return syscall.AF_INET
- }
- if a.IP.To4() != nil {
- return syscall.AF_INET
- }
- return syscall.AF_INET6
-}
-
-func (a *IPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
- if a == nil {
- return nil, nil
- }
- return ipToSockaddr(family, a.IP, 0, a.Zone)
-}
-
-func (a *IPAddr) toLocal(net string) sockaddr {
- return &IPAddr{loopbackIP(net), a.Zone}
-}
-
-func (c *IPConn) readFrom(b []byte) (int, *IPAddr, error) {
- // TODO(cw,rsc): consider using readv if we know the family
- // type to avoid the header trim/copy
- var addr *IPAddr
- n, sa, err := c.fd.readFrom(b)
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- addr = &IPAddr{IP: sa.Addr[0:]}
- n = stripIPv4Header(n, b)
- case *syscall.SockaddrInet6:
- addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneCache.name(int(sa.ZoneId))}
- }
- return n, addr, err
-}
-
-func stripIPv4Header(n int, b []byte) int {
- if len(b) < 20 {
- return n
- }
- l := int(b[0]&0x0f) << 2
- if 20 > l || l > len(b) {
- return n
- }
- if b[0]>>4 != 4 {
- return n
- }
- copy(b, b[l:])
- return n - l
-}
-
-func (c *IPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error) {
- var sa syscall.Sockaddr
- n, oobn, flags, sa, err = c.fd.readMsg(b, oob, 0)
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- addr = &IPAddr{IP: sa.Addr[0:]}
- case *syscall.SockaddrInet6:
- addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneCache.name(int(sa.ZoneId))}
- }
- return
-}
-
-func (c *IPConn) writeTo(b []byte, addr *IPAddr) (int, error) {
- if c.fd.isConnected {
- return 0, ErrWriteToConnected
- }
- if addr == nil {
- return 0, errMissingAddress
- }
- sa, err := addr.sockaddr(c.fd.family)
- if err != nil {
- return 0, err
- }
- return c.fd.writeTo(b, sa)
-}
-
-func (c *IPConn) writeMsg(b, oob []byte, addr *IPAddr) (n, oobn int, err error) {
- if c.fd.isConnected {
- return 0, 0, ErrWriteToConnected
- }
- if addr == nil {
- return 0, 0, errMissingAddress
- }
- sa, err := addr.sockaddr(c.fd.family)
- if err != nil {
- return 0, 0, err
- }
- return c.fd.writeMsg(b, oob, sa)
-}
-
-func (sd *sysDialer) dialIP(ctx context.Context, laddr, raddr *IPAddr) (*IPConn, error) {
- network, proto, err := parseNetwork(ctx, sd.network, true)
- if err != nil {
- return nil, err
- }
- switch network {
- case "ip", "ip4", "ip6":
- default:
- return nil, UnknownNetworkError(sd.network)
- }
- ctrlCtxFn := sd.Dialer.ControlContext
- if ctrlCtxFn == nil && sd.Dialer.Control != nil {
- ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
- return sd.Dialer.Control(network, address, c)
- }
- }
- fd, err := internetSocket(ctx, network, laddr, raddr, syscall.SOCK_RAW, proto, "dial", ctrlCtxFn)
- if err != nil {
- return nil, err
- }
- return newIPConn(fd), nil
-}
-
-func (sl *sysListener) listenIP(ctx context.Context, laddr *IPAddr) (*IPConn, error) {
- network, proto, err := parseNetwork(ctx, sl.network, true)
- if err != nil {
- return nil, err
- }
- switch network {
- case "ip", "ip4", "ip6":
- default:
- return nil, UnknownNetworkError(sl.network)
- }
- var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
- if sl.ListenConfig.Control != nil {
- ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
- return sl.ListenConfig.Control(network, address, c)
- }
- }
- fd, err := internetSocket(ctx, network, laddr, nil, syscall.SOCK_RAW, proto, "listen", ctrlCtxFn)
- if err != nil {
- return nil, err
- }
- return newIPConn(fd), nil
-}
diff --git a/contrib/go/_std_1.20/src/net/ipsock_posix.go b/contrib/go/_std_1.20/src/net/ipsock_posix.go
deleted file mode 100644
index 7fd676bd2c..0000000000
--- a/contrib/go/_std_1.20/src/net/ipsock_posix.go
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix || (js && wasm) || windows
-
-package net
-
-import (
- "context"
- "internal/poll"
- "net/netip"
- "runtime"
- "syscall"
-)
-
-// probe probes IPv4, IPv6 and IPv4-mapped IPv6 communication
-// capabilities which are controlled by the IPV6_V6ONLY socket option
-// and kernel configuration.
-//
-// Should we try to use the IPv4 socket interface if we're only
-// dealing with IPv4 sockets? As long as the host system understands
-// IPv4-mapped IPv6, it's okay to pass IPv4-mapped IPv6 addresses to
-// the IPv6 interface. That simplifies our code and is most
-// general. Unfortunately, we need to run on kernels built without
-// IPv6 support too. So probe the kernel to figure it out.
-func (p *ipStackCapabilities) probe() {
- s, err := sysSocket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
- switch err {
- case syscall.EAFNOSUPPORT, syscall.EPROTONOSUPPORT:
- case nil:
- poll.CloseFunc(s)
- p.ipv4Enabled = true
- }
- var probes = []struct {
- laddr TCPAddr
- value int
- }{
- // IPv6 communication capability
- {laddr: TCPAddr{IP: ParseIP("::1")}, value: 1},
- // IPv4-mapped IPv6 address communication capability
- {laddr: TCPAddr{IP: IPv4(127, 0, 0, 1)}, value: 0},
- }
- switch runtime.GOOS {
- case "dragonfly", "openbsd":
- // The latest DragonFly BSD and OpenBSD kernels don't
- // support IPV6_V6ONLY=0. They always return an error
- // and we don't need to probe the capability.
- probes = probes[:1]
- }
- for i := range probes {
- s, err := sysSocket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
- if err != nil {
- continue
- }
- defer poll.CloseFunc(s)
- syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, probes[i].value)
- sa, err := probes[i].laddr.sockaddr(syscall.AF_INET6)
- if err != nil {
- continue
- }
- if err := syscall.Bind(s, sa); err != nil {
- continue
- }
- if i == 0 {
- p.ipv6Enabled = true
- } else {
- p.ipv4MappedIPv6Enabled = true
- }
- }
-}
-
-// favoriteAddrFamily returns the appropriate address family for the
-// given network, laddr, raddr and mode.
-//
-// If mode indicates "listen" and laddr is a wildcard, we assume that
-// the user wants to make a passive-open connection with a wildcard
-// address family, both AF_INET and AF_INET6, and a wildcard address
-// like the following:
-//
-// - A listen for a wildcard communication domain, "tcp" or
-// "udp", with a wildcard address: If the platform supports
-// both IPv6 and IPv4-mapped IPv6 communication capabilities,
-// or does not support IPv4, we use a dual stack, AF_INET6 and
-// IPV6_V6ONLY=0, wildcard address listen. The dual stack
-// wildcard address listen may fall back to an IPv6-only,
-// AF_INET6 and IPV6_V6ONLY=1, wildcard address listen.
-// Otherwise we prefer an IPv4-only, AF_INET, wildcard address
-// listen.
-//
-// - A listen for a wildcard communication domain, "tcp" or
-// "udp", with an IPv4 wildcard address: same as above.
-//
-// - A listen for a wildcard communication domain, "tcp" or
-// "udp", with an IPv6 wildcard address: same as above.
-//
-// - A listen for an IPv4 communication domain, "tcp4" or "udp4",
-// with an IPv4 wildcard address: We use an IPv4-only, AF_INET,
-// wildcard address listen.
-//
-// - A listen for an IPv6 communication domain, "tcp6" or "udp6",
-// with an IPv6 wildcard address: We use an IPv6-only, AF_INET6
-// and IPV6_V6ONLY=1, wildcard address listen.
-//
-// Otherwise guess: If the addresses are IPv4 then returns AF_INET,
-// or else returns AF_INET6. It also returns a boolean value what
-// designates IPV6_V6ONLY option.
-//
-// Note that the latest DragonFly BSD and OpenBSD kernels allow
-// neither "net.inet6.ip6.v6only=1" change nor IPPROTO_IPV6 level
-// IPV6_V6ONLY socket option setting.
-func favoriteAddrFamily(network string, laddr, raddr sockaddr, mode string) (family int, ipv6only bool) {
- switch network[len(network)-1] {
- case '4':
- return syscall.AF_INET, false
- case '6':
- return syscall.AF_INET6, true
- }
-
- if mode == "listen" && (laddr == nil || laddr.isWildcard()) {
- if supportsIPv4map() || !supportsIPv4() {
- return syscall.AF_INET6, false
- }
- if laddr == nil {
- return syscall.AF_INET, false
- }
- return laddr.family(), false
- }
-
- if (laddr == nil || laddr.family() == syscall.AF_INET) &&
- (raddr == nil || raddr.family() == syscall.AF_INET) {
- return syscall.AF_INET, false
- }
- return syscall.AF_INET6, false
-}
-
-func internetSocket(ctx context.Context, net string, laddr, raddr sockaddr, sotype, proto int, mode string, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) (fd *netFD, err error) {
- if (runtime.GOOS == "aix" || runtime.GOOS == "windows" || runtime.GOOS == "openbsd") && mode == "dial" && raddr.isWildcard() {
- raddr = raddr.toLocal(net)
- }
- family, ipv6only := favoriteAddrFamily(net, laddr, raddr, mode)
- return socket(ctx, net, family, sotype, proto, ipv6only, laddr, raddr, ctrlCtxFn)
-}
-
-func ipToSockaddrInet4(ip IP, port int) (syscall.SockaddrInet4, error) {
- if len(ip) == 0 {
- ip = IPv4zero
- }
- ip4 := ip.To4()
- if ip4 == nil {
- return syscall.SockaddrInet4{}, &AddrError{Err: "non-IPv4 address", Addr: ip.String()}
- }
- sa := syscall.SockaddrInet4{Port: port}
- copy(sa.Addr[:], ip4)
- return sa, nil
-}
-
-func ipToSockaddrInet6(ip IP, port int, zone string) (syscall.SockaddrInet6, error) {
- // In general, an IP wildcard address, which is either
- // "0.0.0.0" or "::", means the entire IP addressing
- // space. For some historical reason, it is used to
- // specify "any available address" on some operations
- // of IP node.
- //
- // When the IP node supports IPv4-mapped IPv6 address,
- // we allow a listener to listen to the wildcard
- // address of both IP addressing spaces by specifying
- // IPv6 wildcard address.
- if len(ip) == 0 || ip.Equal(IPv4zero) {
- ip = IPv6zero
- }
- // We accept any IPv6 address including IPv4-mapped
- // IPv6 address.
- ip6 := ip.To16()
- if ip6 == nil {
- return syscall.SockaddrInet6{}, &AddrError{Err: "non-IPv6 address", Addr: ip.String()}
- }
- sa := syscall.SockaddrInet6{Port: port, ZoneId: uint32(zoneCache.index(zone))}
- copy(sa.Addr[:], ip6)
- return sa, nil
-}
-
-func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, error) {
- switch family {
- case syscall.AF_INET:
- sa, err := ipToSockaddrInet4(ip, port)
- if err != nil {
- return nil, err
- }
- return &sa, nil
- case syscall.AF_INET6:
- sa, err := ipToSockaddrInet6(ip, port, zone)
- if err != nil {
- return nil, err
- }
- return &sa, nil
- }
- return nil, &AddrError{Err: "invalid address family", Addr: ip.String()}
-}
-
-func addrPortToSockaddrInet4(ap netip.AddrPort) (syscall.SockaddrInet4, error) {
- // ipToSockaddrInet4 has special handling here for zero length slices.
- // We do not, because netip has no concept of a generic zero IP address.
- addr := ap.Addr()
- if !addr.Is4() {
- return syscall.SockaddrInet4{}, &AddrError{Err: "non-IPv4 address", Addr: addr.String()}
- }
- sa := syscall.SockaddrInet4{
- Addr: addr.As4(),
- Port: int(ap.Port()),
- }
- return sa, nil
-}
-
-func addrPortToSockaddrInet6(ap netip.AddrPort) (syscall.SockaddrInet6, error) {
- // ipToSockaddrInet6 has special handling here for zero length slices.
- // We do not, because netip has no concept of a generic zero IP address.
- //
- // addr is allowed to be an IPv4 address, because As16 will convert it
- // to an IPv4-mapped IPv6 address.
- // The error message is kept consistent with ipToSockaddrInet6.
- addr := ap.Addr()
- if !addr.IsValid() {
- return syscall.SockaddrInet6{}, &AddrError{Err: "non-IPv6 address", Addr: addr.String()}
- }
- sa := syscall.SockaddrInet6{
- Addr: addr.As16(),
- Port: int(ap.Port()),
- ZoneId: uint32(zoneCache.index(addr.Zone())),
- }
- return sa, nil
-}
diff --git a/contrib/go/_std_1.20/src/net/lookup.go b/contrib/go/_std_1.20/src/net/lookup.go
deleted file mode 100644
index 0fd5d2b2c7..0000000000
--- a/contrib/go/_std_1.20/src/net/lookup.go
+++ /dev/null
@@ -1,910 +0,0 @@
-// Copyright 2012 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 net
-
-import (
- "context"
- "errors"
- "internal/nettrace"
- "internal/singleflight"
- "net/netip"
- "sync"
-
- "golang.org/x/net/dns/dnsmessage"
-)
-
-// protocols contains minimal mappings between internet protocol
-// names and numbers for platforms that don't have a complete list of
-// protocol numbers.
-//
-// See https://www.iana.org/assignments/protocol-numbers
-//
-// On Unix, this map is augmented by readProtocols via lookupProtocol.
-var protocols = map[string]int{
- "icmp": 1,
- "igmp": 2,
- "tcp": 6,
- "udp": 17,
- "ipv6-icmp": 58,
-}
-
-// services contains minimal mappings between services names and port
-// numbers for platforms that don't have a complete list of port numbers.
-//
-// See https://www.iana.org/assignments/service-names-port-numbers
-//
-// On Unix, this map is augmented by readServices via goLookupPort.
-var services = map[string]map[string]int{
- "udp": {
- "domain": 53,
- },
- "tcp": {
- "ftp": 21,
- "ftps": 990,
- "gopher": 70, // ʕ◔ϖ◔ʔ
- "http": 80,
- "https": 443,
- "imap2": 143,
- "imap3": 220,
- "imaps": 993,
- "pop3": 110,
- "pop3s": 995,
- "smtp": 25,
- "ssh": 22,
- "telnet": 23,
- },
-}
-
-// dnsWaitGroup can be used by tests to wait for all DNS goroutines to
-// complete. This avoids races on the test hooks.
-var dnsWaitGroup sync.WaitGroup
-
-const maxProtoLength = len("RSVP-E2E-IGNORE") + 10 // with room to grow
-
-func lookupProtocolMap(name string) (int, error) {
- var lowerProtocol [maxProtoLength]byte
- n := copy(lowerProtocol[:], name)
- lowerASCIIBytes(lowerProtocol[:n])
- proto, found := protocols[string(lowerProtocol[:n])]
- if !found || n != len(name) {
- return 0, &AddrError{Err: "unknown IP protocol specified", Addr: name}
- }
- return proto, nil
-}
-
-// maxPortBufSize is the longest reasonable name of a service
-// (non-numeric port).
-// Currently the longest known IANA-unregistered name is
-// "mobility-header", so we use that length, plus some slop in case
-// something longer is added in the future.
-const maxPortBufSize = len("mobility-header") + 10
-
-func lookupPortMap(network, service string) (port int, error error) {
- switch network {
- case "tcp4", "tcp6":
- network = "tcp"
- case "udp4", "udp6":
- network = "udp"
- }
-
- if m, ok := services[network]; ok {
- var lowerService [maxPortBufSize]byte
- n := copy(lowerService[:], service)
- lowerASCIIBytes(lowerService[:n])
- if port, ok := m[string(lowerService[:n])]; ok && n == len(service) {
- return port, nil
- }
- }
- return 0, &AddrError{Err: "unknown port", Addr: network + "/" + service}
-}
-
-// ipVersion returns the provided network's IP version: '4', '6' or 0
-// if network does not end in a '4' or '6' byte.
-func ipVersion(network string) byte {
- if network == "" {
- return 0
- }
- n := network[len(network)-1]
- if n != '4' && n != '6' {
- n = 0
- }
- return n
-}
-
-// DefaultResolver is the resolver used by the package-level Lookup
-// functions and by Dialers without a specified Resolver.
-var DefaultResolver = &Resolver{}
-
-// A Resolver looks up names and numbers.
-//
-// A nil *Resolver is equivalent to a zero Resolver.
-type Resolver struct {
- // PreferGo controls whether Go's built-in DNS resolver is preferred
- // on platforms where it's available. It is equivalent to setting
- // GODEBUG=netdns=go, but scoped to just this resolver.
- PreferGo bool
-
- // StrictErrors controls the behavior of temporary errors
- // (including timeout, socket errors, and SERVFAIL) when using
- // Go's built-in resolver. For a query composed of multiple
- // sub-queries (such as an A+AAAA address lookup, or walking the
- // DNS search list), this option causes such errors to abort the
- // whole query instead of returning a partial result. This is
- // not enabled by default because it may affect compatibility
- // with resolvers that process AAAA queries incorrectly.
- StrictErrors bool
-
- // Dial optionally specifies an alternate dialer for use by
- // Go's built-in DNS resolver to make TCP and UDP connections
- // to DNS services. The host in the address parameter will
- // always be a literal IP address and not a host name, and the
- // port in the address parameter will be a literal port number
- // and not a service name.
- // If the Conn returned is also a PacketConn, sent and received DNS
- // messages must adhere to RFC 1035 section 4.2.1, "UDP usage".
- // Otherwise, DNS messages transmitted over Conn must adhere
- // to RFC 7766 section 5, "Transport Protocol Selection".
- // If nil, the default dialer is used.
- Dial func(ctx context.Context, network, address string) (Conn, error)
-
- // lookupGroup merges LookupIPAddr calls together for lookups for the same
- // host. The lookupGroup key is the LookupIPAddr.host argument.
- // The return values are ([]IPAddr, error).
- lookupGroup singleflight.Group
-
- // TODO(bradfitz): optional interface impl override hook
- // TODO(bradfitz): Timeout time.Duration?
-}
-
-func (r *Resolver) preferGo() bool { return r != nil && r.PreferGo }
-func (r *Resolver) strictErrors() bool { return r != nil && r.StrictErrors }
-
-func (r *Resolver) getLookupGroup() *singleflight.Group {
- if r == nil {
- return &DefaultResolver.lookupGroup
- }
- return &r.lookupGroup
-}
-
-// LookupHost looks up the given host using the local resolver.
-// It returns a slice of that host's addresses.
-//
-// LookupHost uses context.Background internally; to specify the context, use
-// Resolver.LookupHost.
-func LookupHost(host string) (addrs []string, err error) {
- return DefaultResolver.LookupHost(context.Background(), host)
-}
-
-// LookupHost looks up the given host using the local resolver.
-// It returns a slice of that host's addresses.
-func (r *Resolver) LookupHost(ctx context.Context, host string) (addrs []string, err error) {
- // Make sure that no matter what we do later, host=="" is rejected.
- // parseIP, for example, does accept empty strings.
- if host == "" {
- return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host, IsNotFound: true}
- }
- if ip, _ := parseIPZone(host); ip != nil {
- return []string{host}, nil
- }
- return r.lookupHost(ctx, host)
-}
-
-// LookupIP looks up host using the local resolver.
-// It returns a slice of that host's IPv4 and IPv6 addresses.
-func LookupIP(host string) ([]IP, error) {
- addrs, err := DefaultResolver.LookupIPAddr(context.Background(), host)
- if err != nil {
- return nil, err
- }
- ips := make([]IP, len(addrs))
- for i, ia := range addrs {
- ips[i] = ia.IP
- }
- return ips, nil
-}
-
-// LookupIPAddr looks up host using the local resolver.
-// It returns a slice of that host's IPv4 and IPv6 addresses.
-func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, error) {
- return r.lookupIPAddr(ctx, "ip", host)
-}
-
-// LookupIP looks up host for the given network using the local resolver.
-// It returns a slice of that host's IP addresses of the type specified by
-// network.
-// network must be one of "ip", "ip4" or "ip6".
-func (r *Resolver) LookupIP(ctx context.Context, network, host string) ([]IP, error) {
- afnet, _, err := parseNetwork(ctx, network, false)
- if err != nil {
- return nil, err
- }
- switch afnet {
- case "ip", "ip4", "ip6":
- default:
- return nil, UnknownNetworkError(network)
- }
-
- if host == "" {
- return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host, IsNotFound: true}
- }
- addrs, err := r.internetAddrList(ctx, afnet, host)
- if err != nil {
- return nil, err
- }
-
- ips := make([]IP, 0, len(addrs))
- for _, addr := range addrs {
- ips = append(ips, addr.(*IPAddr).IP)
- }
- return ips, nil
-}
-
-// LookupNetIP looks up host using the local resolver.
-// It returns a slice of that host's IP addresses of the type specified by
-// network.
-// The network must be one of "ip", "ip4" or "ip6".
-func (r *Resolver) LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, error) {
- // TODO(bradfitz): make this efficient, making the internal net package
- // type throughout be netip.Addr and only converting to the net.IP slice
- // version at the edge. But for now (2021-10-20), this is a wrapper around
- // the old way.
- ips, err := r.LookupIP(ctx, network, host)
- if err != nil {
- return nil, err
- }
- ret := make([]netip.Addr, 0, len(ips))
- for _, ip := range ips {
- if a, ok := netip.AddrFromSlice(ip); ok {
- ret = append(ret, a)
- }
- }
- return ret, nil
-}
-
-// onlyValuesCtx is a context that uses an underlying context
-// for value lookup if the underlying context hasn't yet expired.
-type onlyValuesCtx struct {
- context.Context
- lookupValues context.Context
-}
-
-var _ context.Context = (*onlyValuesCtx)(nil)
-
-// Value performs a lookup if the original context hasn't expired.
-func (ovc *onlyValuesCtx) Value(key any) any {
- select {
- case <-ovc.lookupValues.Done():
- return nil
- default:
- return ovc.lookupValues.Value(key)
- }
-}
-
-// withUnexpiredValuesPreserved returns a context.Context that only uses lookupCtx
-// for its values, otherwise it is never canceled and has no deadline.
-// If the lookup context expires, any looked up values will return nil.
-// See Issue 28600.
-func withUnexpiredValuesPreserved(lookupCtx context.Context) context.Context {
- return &onlyValuesCtx{Context: context.Background(), lookupValues: lookupCtx}
-}
-
-// lookupIPAddr looks up host using the local resolver and particular network.
-// It returns a slice of that host's IPv4 and IPv6 addresses.
-func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IPAddr, error) {
- // Make sure that no matter what we do later, host=="" is rejected.
- // parseIPZone, for example, does accept empty strings.
- if host == "" {
- return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host, IsNotFound: true}
- }
- if ip, zone := parseIPZone(host); ip != nil {
- return []IPAddr{{IP: ip, Zone: zone}}, nil
- }
- trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace)
- if trace != nil && trace.DNSStart != nil {
- trace.DNSStart(host)
- }
- // The underlying resolver func is lookupIP by default but it
- // can be overridden by tests. This is needed by net/http, so it
- // uses a context key instead of unexported variables.
- resolverFunc := r.lookupIP
- if alt, _ := ctx.Value(nettrace.LookupIPAltResolverKey{}).(func(context.Context, string, string) ([]IPAddr, error)); alt != nil {
- resolverFunc = alt
- }
-
- // We don't want a cancellation of ctx to affect the
- // lookupGroup operation. Otherwise if our context gets
- // canceled it might cause an error to be returned to a lookup
- // using a completely different context. However we need to preserve
- // only the values in context. See Issue 28600.
- lookupGroupCtx, lookupGroupCancel := context.WithCancel(withUnexpiredValuesPreserved(ctx))
-
- lookupKey := network + "\000" + host
- dnsWaitGroup.Add(1)
- ch := r.getLookupGroup().DoChan(lookupKey, func() (any, error) {
- return testHookLookupIP(lookupGroupCtx, resolverFunc, network, host)
- })
-
- dnsWaitGroupDone := func(ch <-chan singleflight.Result, cancelFn context.CancelFunc) {
- <-ch
- dnsWaitGroup.Done()
- cancelFn()
- }
- select {
- case <-ctx.Done():
- // Our context was canceled. If we are the only
- // goroutine looking up this key, then drop the key
- // from the lookupGroup and cancel the lookup.
- // If there are other goroutines looking up this key,
- // let the lookup continue uncanceled, and let later
- // lookups with the same key share the result.
- // See issues 8602, 20703, 22724.
- if r.getLookupGroup().ForgetUnshared(lookupKey) {
- lookupGroupCancel()
- go dnsWaitGroupDone(ch, func() {})
- } else {
- go dnsWaitGroupDone(ch, lookupGroupCancel)
- }
- ctxErr := ctx.Err()
- err := &DNSError{
- Err: mapErr(ctxErr).Error(),
- Name: host,
- IsTimeout: ctxErr == context.DeadlineExceeded,
- }
- if trace != nil && trace.DNSDone != nil {
- trace.DNSDone(nil, false, err)
- }
- return nil, err
- case r := <-ch:
- dnsWaitGroup.Done()
- lookupGroupCancel()
- err := r.Err
- if err != nil {
- if _, ok := err.(*DNSError); !ok {
- isTimeout := false
- if err == context.DeadlineExceeded {
- isTimeout = true
- } else if terr, ok := err.(timeout); ok {
- isTimeout = terr.Timeout()
- }
- err = &DNSError{
- Err: err.Error(),
- Name: host,
- IsTimeout: isTimeout,
- }
- }
- }
- if trace != nil && trace.DNSDone != nil {
- addrs, _ := r.Val.([]IPAddr)
- trace.DNSDone(ipAddrsEface(addrs), r.Shared, err)
- }
- return lookupIPReturn(r.Val, err, r.Shared)
- }
-}
-
-// lookupIPReturn turns the return values from singleflight.Do into
-// the return values from LookupIP.
-func lookupIPReturn(addrsi any, err error, shared bool) ([]IPAddr, error) {
- if err != nil {
- return nil, err
- }
- addrs := addrsi.([]IPAddr)
- if shared {
- clone := make([]IPAddr, len(addrs))
- copy(clone, addrs)
- addrs = clone
- }
- return addrs, nil
-}
-
-// ipAddrsEface returns an empty interface slice of addrs.
-func ipAddrsEface(addrs []IPAddr) []any {
- s := make([]any, len(addrs))
- for i, v := range addrs {
- s[i] = v
- }
- return s
-}
-
-// LookupPort looks up the port for the given network and service.
-//
-// LookupPort uses context.Background internally; to specify the context, use
-// Resolver.LookupPort.
-func LookupPort(network, service string) (port int, err error) {
- return DefaultResolver.LookupPort(context.Background(), network, service)
-}
-
-// LookupPort looks up the port for the given network and service.
-func (r *Resolver) LookupPort(ctx context.Context, network, service string) (port int, err error) {
- port, needsLookup := parsePort(service)
- if needsLookup {
- switch network {
- case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
- case "": // a hint wildcard for Go 1.0 undocumented behavior
- network = "ip"
- default:
- return 0, &AddrError{Err: "unknown network", Addr: network}
- }
- port, err = r.lookupPort(ctx, network, service)
- if err != nil {
- return 0, err
- }
- }
- if 0 > port || port > 65535 {
- return 0, &AddrError{Err: "invalid port", Addr: service}
- }
- return port, nil
-}
-
-// LookupCNAME returns the canonical name for the given host.
-// Callers that do not care about the canonical name can call
-// LookupHost or LookupIP directly; both take care of resolving
-// the canonical name as part of the lookup.
-//
-// A canonical name is the final name after following zero
-// or more CNAME records.
-// LookupCNAME does not return an error if host does not
-// contain DNS "CNAME" records, as long as host resolves to
-// address records.
-//
-// The returned canonical name is validated to be a properly
-// formatted presentation-format domain name.
-//
-// LookupCNAME uses context.Background internally; to specify the context, use
-// Resolver.LookupCNAME.
-func LookupCNAME(host string) (cname string, err error) {
- return DefaultResolver.LookupCNAME(context.Background(), host)
-}
-
-// LookupCNAME returns the canonical name for the given host.
-// Callers that do not care about the canonical name can call
-// LookupHost or LookupIP directly; both take care of resolving
-// the canonical name as part of the lookup.
-//
-// A canonical name is the final name after following zero
-// or more CNAME records.
-// LookupCNAME does not return an error if host does not
-// contain DNS "CNAME" records, as long as host resolves to
-// address records.
-//
-// The returned canonical name is validated to be a properly
-// formatted presentation-format domain name.
-func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error) {
- cname, err := r.lookupCNAME(ctx, host)
- if err != nil {
- return "", err
- }
- if !isDomainName(cname) {
- return "", &DNSError{Err: errMalformedDNSRecordsDetail, Name: host}
- }
- return cname, nil
-}
-
-// LookupSRV tries to resolve an SRV query of the given service,
-// protocol, and domain name. The proto is "tcp" or "udp".
-// The returned records are sorted by priority and randomized
-// by weight within a priority.
-//
-// LookupSRV constructs the DNS name to look up following RFC 2782.
-// That is, it looks up _service._proto.name. To accommodate services
-// publishing SRV records under non-standard names, if both service
-// and proto are empty strings, LookupSRV looks up name directly.
-//
-// The returned service names are validated to be properly
-// formatted presentation-format domain names. If the response contains
-// invalid names, those records are filtered out and an error
-// will be returned alongside the remaining results, if any.
-func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
- return DefaultResolver.LookupSRV(context.Background(), service, proto, name)
-}
-
-// LookupSRV tries to resolve an SRV query of the given service,
-// protocol, and domain name. The proto is "tcp" or "udp".
-// The returned records are sorted by priority and randomized
-// by weight within a priority.
-//
-// LookupSRV constructs the DNS name to look up following RFC 2782.
-// That is, it looks up _service._proto.name. To accommodate services
-// publishing SRV records under non-standard names, if both service
-// and proto are empty strings, LookupSRV looks up name directly.
-//
-// The returned service names are validated to be properly
-// formatted presentation-format domain names. If the response contains
-// invalid names, those records are filtered out and an error
-// will be returned alongside the remaining results, if any.
-func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
- cname, addrs, err := r.lookupSRV(ctx, service, proto, name)
- if err != nil {
- return "", nil, err
- }
- if cname != "" && !isDomainName(cname) {
- return "", nil, &DNSError{Err: "SRV header name is invalid", Name: name}
- }
- filteredAddrs := make([]*SRV, 0, len(addrs))
- for _, addr := range addrs {
- if addr == nil {
- continue
- }
- if !isDomainName(addr.Target) {
- continue
- }
- filteredAddrs = append(filteredAddrs, addr)
- }
- if len(addrs) != len(filteredAddrs) {
- return cname, filteredAddrs, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
- }
- return cname, filteredAddrs, nil
-}
-
-// LookupMX returns the DNS MX records for the given domain name sorted by preference.
-//
-// The returned mail server names are validated to be properly
-// formatted presentation-format domain names. If the response contains
-// invalid names, those records are filtered out and an error
-// will be returned alongside the remaining results, if any.
-//
-// LookupMX uses context.Background internally; to specify the context, use
-// Resolver.LookupMX.
-func LookupMX(name string) ([]*MX, error) {
- return DefaultResolver.LookupMX(context.Background(), name)
-}
-
-// LookupMX returns the DNS MX records for the given domain name sorted by preference.
-//
-// The returned mail server names are validated to be properly
-// formatted presentation-format domain names. If the response contains
-// invalid names, those records are filtered out and an error
-// will be returned alongside the remaining results, if any.
-func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) {
- records, err := r.lookupMX(ctx, name)
- if err != nil {
- return nil, err
- }
- filteredMX := make([]*MX, 0, len(records))
- for _, mx := range records {
- if mx == nil {
- continue
- }
- if !isDomainName(mx.Host) {
- continue
- }
- filteredMX = append(filteredMX, mx)
- }
- if len(records) != len(filteredMX) {
- return filteredMX, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
- }
- return filteredMX, nil
-}
-
-// LookupNS returns the DNS NS records for the given domain name.
-//
-// The returned name server names are validated to be properly
-// formatted presentation-format domain names. If the response contains
-// invalid names, those records are filtered out and an error
-// will be returned alongside the remaining results, if any.
-//
-// LookupNS uses context.Background internally; to specify the context, use
-// Resolver.LookupNS.
-func LookupNS(name string) ([]*NS, error) {
- return DefaultResolver.LookupNS(context.Background(), name)
-}
-
-// LookupNS returns the DNS NS records for the given domain name.
-//
-// The returned name server names are validated to be properly
-// formatted presentation-format domain names. If the response contains
-// invalid names, those records are filtered out and an error
-// will be returned alongside the remaining results, if any.
-func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*NS, error) {
- records, err := r.lookupNS(ctx, name)
- if err != nil {
- return nil, err
- }
- filteredNS := make([]*NS, 0, len(records))
- for _, ns := range records {
- if ns == nil {
- continue
- }
- if !isDomainName(ns.Host) {
- continue
- }
- filteredNS = append(filteredNS, ns)
- }
- if len(records) != len(filteredNS) {
- return filteredNS, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
- }
- return filteredNS, nil
-}
-
-// LookupTXT returns the DNS TXT records for the given domain name.
-//
-// LookupTXT uses context.Background internally; to specify the context, use
-// Resolver.LookupTXT.
-func LookupTXT(name string) ([]string, error) {
- return DefaultResolver.lookupTXT(context.Background(), name)
-}
-
-// LookupTXT returns the DNS TXT records for the given domain name.
-func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, error) {
- return r.lookupTXT(ctx, name)
-}
-
-// LookupAddr performs a reverse lookup for the given address, returning a list
-// of names mapping to that address.
-//
-// The returned names are validated to be properly formatted presentation-format
-// domain names. If the response contains invalid names, those records are filtered
-// out and an error will be returned alongside the remaining results, if any.
-//
-// When using the host C library resolver, at most one result will be
-// returned. To bypass the host resolver, use a custom Resolver.
-//
-// LookupAddr uses context.Background internally; to specify the context, use
-// Resolver.LookupAddr.
-func LookupAddr(addr string) (names []string, err error) {
- return DefaultResolver.LookupAddr(context.Background(), addr)
-}
-
-// LookupAddr performs a reverse lookup for the given address, returning a list
-// of names mapping to that address.
-//
-// The returned names are validated to be properly formatted presentation-format
-// domain names. If the response contains invalid names, those records are filtered
-// out and an error will be returned alongside the remaining results, if any.
-func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error) {
- names, err := r.lookupAddr(ctx, addr)
- if err != nil {
- return nil, err
- }
- filteredNames := make([]string, 0, len(names))
- for _, name := range names {
- if isDomainName(name) {
- filteredNames = append(filteredNames, name)
- }
- }
- if len(names) != len(filteredNames) {
- return filteredNames, &DNSError{Err: errMalformedDNSRecordsDetail, Name: addr}
- }
- return filteredNames, nil
-}
-
-// errMalformedDNSRecordsDetail is the DNSError detail which is returned when a Resolver.Lookup...
-// method receives DNS records which contain invalid DNS names. This may be returned alongside
-// results which have had the malformed records filtered out.
-var errMalformedDNSRecordsDetail = "DNS response contained records which contain invalid names"
-
-// dial makes a new connection to the provided server (which must be
-// an IP address) with the provided network type, using either r.Dial
-// (if both r and r.Dial are non-nil) or else Dialer.DialContext.
-func (r *Resolver) dial(ctx context.Context, network, server string) (Conn, error) {
- // Calling Dial here is scary -- we have to be sure not to
- // dial a name that will require a DNS lookup, or Dial will
- // call back here to translate it. The DNS config parser has
- // already checked that all the cfg.servers are IP
- // addresses, which Dial will use without a DNS lookup.
- var c Conn
- var err error
- if r != nil && r.Dial != nil {
- c, err = r.Dial(ctx, network, server)
- } else {
- var d Dialer
- c, err = d.DialContext(ctx, network, server)
- }
- if err != nil {
- return nil, mapErr(err)
- }
- return c, nil
-}
-
-// goLookupSRV returns the SRV records for a target name, built either
-// from its component service ("sip"), protocol ("tcp"), and name
-// ("example.com."), or from name directly (if service and proto are
-// both empty).
-//
-// In either case, the returned target name ("_sip._tcp.example.com.")
-// is also returned on success.
-//
-// The records are sorted by weight.
-func (r *Resolver) goLookupSRV(ctx context.Context, service, proto, name string) (target string, srvs []*SRV, err error) {
- if service == "" && proto == "" {
- target = name
- } else {
- target = "_" + service + "._" + proto + "." + name
- }
- p, server, err := r.lookup(ctx, target, dnsmessage.TypeSRV, nil)
- if err != nil {
- return "", nil, err
- }
- var cname dnsmessage.Name
- for {
- h, err := p.AnswerHeader()
- if err == dnsmessage.ErrSectionDone {
- break
- }
- if err != nil {
- return "", nil, &DNSError{
- Err: "cannot unmarshal DNS message",
- Name: name,
- Server: server,
- }
- }
- if h.Type != dnsmessage.TypeSRV {
- if err := p.SkipAnswer(); err != nil {
- return "", nil, &DNSError{
- Err: "cannot unmarshal DNS message",
- Name: name,
- Server: server,
- }
- }
- continue
- }
- if cname.Length == 0 && h.Name.Length != 0 {
- cname = h.Name
- }
- srv, err := p.SRVResource()
- if err != nil {
- return "", nil, &DNSError{
- Err: "cannot unmarshal DNS message",
- Name: name,
- Server: server,
- }
- }
- srvs = append(srvs, &SRV{Target: srv.Target.String(), Port: srv.Port, Priority: srv.Priority, Weight: srv.Weight})
- }
- byPriorityWeight(srvs).sort()
- return cname.String(), srvs, nil
-}
-
-// goLookupMX returns the MX records for name.
-func (r *Resolver) goLookupMX(ctx context.Context, name string) ([]*MX, error) {
- p, server, err := r.lookup(ctx, name, dnsmessage.TypeMX, nil)
- if err != nil {
- return nil, err
- }
- var mxs []*MX
- for {
- h, err := p.AnswerHeader()
- if err == dnsmessage.ErrSectionDone {
- break
- }
- if err != nil {
- return nil, &DNSError{
- Err: "cannot unmarshal DNS message",
- Name: name,
- Server: server,
- }
- }
- if h.Type != dnsmessage.TypeMX {
- if err := p.SkipAnswer(); err != nil {
- return nil, &DNSError{
- Err: "cannot unmarshal DNS message",
- Name: name,
- Server: server,
- }
- }
- continue
- }
- mx, err := p.MXResource()
- if err != nil {
- return nil, &DNSError{
- Err: "cannot unmarshal DNS message",
- Name: name,
- Server: server,
- }
- }
- mxs = append(mxs, &MX{Host: mx.MX.String(), Pref: mx.Pref})
-
- }
- byPref(mxs).sort()
- return mxs, nil
-}
-
-// goLookupNS returns the NS records for name.
-func (r *Resolver) goLookupNS(ctx context.Context, name string) ([]*NS, error) {
- p, server, err := r.lookup(ctx, name, dnsmessage.TypeNS, nil)
- if err != nil {
- return nil, err
- }
- var nss []*NS
- for {
- h, err := p.AnswerHeader()
- if err == dnsmessage.ErrSectionDone {
- break
- }
- if err != nil {
- return nil, &DNSError{
- Err: "cannot unmarshal DNS message",
- Name: name,
- Server: server,
- }
- }
- if h.Type != dnsmessage.TypeNS {
- if err := p.SkipAnswer(); err != nil {
- return nil, &DNSError{
- Err: "cannot unmarshal DNS message",
- Name: name,
- Server: server,
- }
- }
- continue
- }
- ns, err := p.NSResource()
- if err != nil {
- return nil, &DNSError{
- Err: "cannot unmarshal DNS message",
- Name: name,
- Server: server,
- }
- }
- nss = append(nss, &NS{Host: ns.NS.String()})
- }
- return nss, nil
-}
-
-// goLookupTXT returns the TXT records from name.
-func (r *Resolver) goLookupTXT(ctx context.Context, name string) ([]string, error) {
- p, server, err := r.lookup(ctx, name, dnsmessage.TypeTXT, nil)
- if err != nil {
- return nil, err
- }
- var txts []string
- for {
- h, err := p.AnswerHeader()
- if err == dnsmessage.ErrSectionDone {
- break
- }
- if err != nil {
- return nil, &DNSError{
- Err: "cannot unmarshal DNS message",
- Name: name,
- Server: server,
- }
- }
- if h.Type != dnsmessage.TypeTXT {
- if err := p.SkipAnswer(); err != nil {
- return nil, &DNSError{
- Err: "cannot unmarshal DNS message",
- Name: name,
- Server: server,
- }
- }
- continue
- }
- txt, err := p.TXTResource()
- if err != nil {
- return nil, &DNSError{
- Err: "cannot unmarshal DNS message",
- Name: name,
- Server: server,
- }
- }
- // Multiple strings in one TXT record need to be
- // concatenated without separator to be consistent
- // with previous Go resolver.
- n := 0
- for _, s := range txt.TXT {
- n += len(s)
- }
- txtJoin := make([]byte, 0, n)
- for _, s := range txt.TXT {
- txtJoin = append(txtJoin, s...)
- }
- if len(txts) == 0 {
- txts = make([]string, 0, 1)
- }
- txts = append(txts, string(txtJoin))
- }
- return txts, nil
-}
-
-func parseCNAMEFromResources(resources []dnsmessage.Resource) (string, error) {
- if len(resources) == 0 {
- return "", errors.New("no CNAME record received")
- }
- c, ok := resources[0].Body.(*dnsmessage.CNAMEResource)
- if !ok {
- return "", errors.New("could not parse CNAME record")
- }
- return c.CNAME.String(), nil
-}
diff --git a/contrib/go/_std_1.20/src/net/lookup_unix.go b/contrib/go/_std_1.20/src/net/lookup_unix.go
deleted file mode 100644
index 600e694044..0000000000
--- a/contrib/go/_std_1.20/src/net/lookup_unix.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2011 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.
-
-//go:build unix
-
-package net
-
-import (
- "context"
- "internal/bytealg"
- "sync"
- "syscall"
-)
-
-var onceReadProtocols sync.Once
-
-// readProtocols loads contents of /etc/protocols into protocols map
-// for quick access.
-func readProtocols() {
- file, err := open("/etc/protocols")
- if err != nil {
- return
- }
- defer file.close()
-
- for line, ok := file.readLine(); ok; line, ok = file.readLine() {
- // tcp 6 TCP # transmission control protocol
- if i := bytealg.IndexByteString(line, '#'); i >= 0 {
- line = line[0:i]
- }
- f := getFields(line)
- if len(f) < 2 {
- continue
- }
- if proto, _, ok := dtoi(f[1]); ok {
- if _, ok := protocols[f[0]]; !ok {
- protocols[f[0]] = proto
- }
- for _, alias := range f[2:] {
- if _, ok := protocols[alias]; !ok {
- protocols[alias] = proto
- }
- }
- }
- }
-}
-
-// lookupProtocol looks up IP protocol name in /etc/protocols and
-// returns correspondent protocol number.
-func lookupProtocol(_ context.Context, name string) (int, error) {
- onceReadProtocols.Do(readProtocols)
- return lookupProtocolMap(name)
-}
-
-func (r *Resolver) lookupHost(ctx context.Context, host string) (addrs []string, err error) {
- order, conf := systemConf().hostLookupOrder(r, host)
- if !r.preferGo() && order == hostLookupCgo {
- if addrs, err, ok := cgoLookupHost(ctx, host); ok {
- return addrs, err
- }
- // cgo not available (or netgo); fall back to Go's DNS resolver
- order = hostLookupFilesDNS
- }
- return r.goLookupHostOrder(ctx, host, order, conf)
-}
-
-func (r *Resolver) lookupIP(ctx context.Context, network, host string) (addrs []IPAddr, err error) {
- if r.preferGo() {
- return r.goLookupIP(ctx, network, host)
- }
- order, conf := systemConf().hostLookupOrder(r, host)
- if order == hostLookupCgo {
- if addrs, err, ok := cgoLookupIP(ctx, network, host); ok {
- return addrs, err
- }
- // cgo not available (or netgo); fall back to Go's DNS resolver
- order = hostLookupFilesDNS
- }
- ips, _, err := r.goLookupIPCNAMEOrder(ctx, network, host, order, conf)
- return ips, err
-}
-
-func (r *Resolver) lookupPort(ctx context.Context, network, service string) (int, error) {
- if !r.preferGo() && systemConf().canUseCgo() {
- if port, err, ok := cgoLookupPort(ctx, network, service); ok {
- if err != nil {
- // Issue 18213: if cgo fails, first check to see whether we
- // have the answer baked-in to the net package.
- if port, err := goLookupPort(network, service); err == nil {
- return port, nil
- }
- }
- return port, err
- }
- }
- return goLookupPort(network, service)
-}
-
-func (r *Resolver) lookupCNAME(ctx context.Context, name string) (string, error) {
- order, conf := systemConf().hostLookupOrder(r, name)
- if !r.preferGo() && order == hostLookupCgo {
- if cname, err, ok := cgoLookupCNAME(ctx, name); ok {
- return cname, err
- }
- }
- return r.goLookupCNAME(ctx, name, order, conf)
-}
-
-func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
- return r.goLookupSRV(ctx, service, proto, name)
-}
-
-func (r *Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
- return r.goLookupMX(ctx, name)
-}
-
-func (r *Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) {
- return r.goLookupNS(ctx, name)
-}
-
-func (r *Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) {
- return r.goLookupTXT(ctx, name)
-}
-
-func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error) {
- order, conf := systemConf().hostLookupOrder(r, "")
- if !r.preferGo() && order == hostLookupCgo {
- if ptrs, err, ok := cgoLookupPTR(ctx, addr); ok {
- return ptrs, err
- }
- }
- return r.goLookupPTR(ctx, addr, conf)
-}
-
-// concurrentThreadsLimit returns the number of threads we permit to
-// run concurrently doing DNS lookups via cgo. A DNS lookup may use a
-// file descriptor so we limit this to less than the number of
-// permitted open files. On some systems, notably Darwin, if
-// getaddrinfo is unable to open a file descriptor it simply returns
-// EAI_NONAME rather than a useful error. Limiting the number of
-// concurrent getaddrinfo calls to less than the permitted number of
-// file descriptors makes that error less likely. We don't bother to
-// apply the same limit to DNS lookups run directly from Go, because
-// there we will return a meaningful "too many open files" error.
-func concurrentThreadsLimit() int {
- var rlim syscall.Rlimit
- if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil {
- return 500
- }
- r := int(rlim.Cur)
- if r > 500 {
- r = 500
- } else if r > 30 {
- r -= 30
- }
- return r
-}
diff --git a/contrib/go/_std_1.20/src/net/lookup_windows.go b/contrib/go/_std_1.20/src/net/lookup_windows.go
deleted file mode 100644
index 4ee728196b..0000000000
--- a/contrib/go/_std_1.20/src/net/lookup_windows.go
+++ /dev/null
@@ -1,436 +0,0 @@
-// Copyright 2009 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 net
-
-import (
- "context"
- "internal/syscall/windows"
- "os"
- "runtime"
- "syscall"
- "unsafe"
-)
-
-const _WSAHOST_NOT_FOUND = syscall.Errno(11001)
-
-func winError(call string, err error) error {
- switch err {
- case _WSAHOST_NOT_FOUND:
- return errNoSuchHost
- }
- return os.NewSyscallError(call, err)
-}
-
-func getprotobyname(name string) (proto int, err error) {
- p, err := syscall.GetProtoByName(name)
- if err != nil {
- return 0, winError("getprotobyname", err)
- }
- return int(p.Proto), nil
-}
-
-// lookupProtocol looks up IP protocol name and returns correspondent protocol number.
-func lookupProtocol(ctx context.Context, name string) (int, error) {
- // GetProtoByName return value is stored in thread local storage.
- // Start new os thread before the call to prevent races.
- type result struct {
- proto int
- err error
- }
- ch := make(chan result) // unbuffered
- go func() {
- acquireThread()
- defer releaseThread()
- runtime.LockOSThread()
- defer runtime.UnlockOSThread()
- proto, err := getprotobyname(name)
- select {
- case ch <- result{proto: proto, err: err}:
- case <-ctx.Done():
- }
- }()
- select {
- case r := <-ch:
- if r.err != nil {
- if proto, err := lookupProtocolMap(name); err == nil {
- return proto, nil
- }
-
- dnsError := &DNSError{Err: r.err.Error(), Name: name}
- if r.err == errNoSuchHost {
- dnsError.IsNotFound = true
- }
- r.err = dnsError
- }
- return r.proto, r.err
- case <-ctx.Done():
- return 0, mapErr(ctx.Err())
- }
-}
-
-func (r *Resolver) lookupHost(ctx context.Context, name string) ([]string, error) {
- ips, err := r.lookupIP(ctx, "ip", name)
- if err != nil {
- return nil, err
- }
- addrs := make([]string, 0, len(ips))
- for _, ip := range ips {
- addrs = append(addrs, ip.String())
- }
- return addrs, nil
-}
-
-// preferGoOverWindows reports whether the resolver should use the
-// pure Go implementation rather than making win32 calls to ask the
-// kernel for its answer.
-func (r *Resolver) preferGoOverWindows() bool {
- conf := systemConf()
- order, _ := conf.hostLookupOrder(r, "") // name is unused
- return order != hostLookupCgo
-}
-
-func (r *Resolver) lookupIP(ctx context.Context, network, name string) ([]IPAddr, error) {
- if r.preferGoOverWindows() {
- return r.goLookupIP(ctx, network, name)
- }
- // TODO(bradfitz,brainman): use ctx more. See TODO below.
-
- var family int32 = syscall.AF_UNSPEC
- switch ipVersion(network) {
- case '4':
- family = syscall.AF_INET
- case '6':
- family = syscall.AF_INET6
- }
-
- getaddr := func() ([]IPAddr, error) {
- acquireThread()
- defer releaseThread()
- hints := syscall.AddrinfoW{
- Family: family,
- Socktype: syscall.SOCK_STREAM,
- Protocol: syscall.IPPROTO_IP,
- }
- var result *syscall.AddrinfoW
- name16p, err := syscall.UTF16PtrFromString(name)
- if err != nil {
- return nil, &DNSError{Name: name, Err: err.Error()}
- }
- e := syscall.GetAddrInfoW(name16p, nil, &hints, &result)
- if e != nil {
- err := winError("getaddrinfow", e)
- dnsError := &DNSError{Err: err.Error(), Name: name}
- if err == errNoSuchHost {
- dnsError.IsNotFound = true
- }
- return nil, dnsError
- }
- defer syscall.FreeAddrInfoW(result)
- addrs := make([]IPAddr, 0, 5)
- for ; result != nil; result = result.Next {
- addr := unsafe.Pointer(result.Addr)
- switch result.Family {
- case syscall.AF_INET:
- a := (*syscall.RawSockaddrInet4)(addr).Addr
- addrs = append(addrs, IPAddr{IP: copyIP(a[:])})
- case syscall.AF_INET6:
- a := (*syscall.RawSockaddrInet6)(addr).Addr
- zone := zoneCache.name(int((*syscall.RawSockaddrInet6)(addr).Scope_id))
- addrs = append(addrs, IPAddr{IP: copyIP(a[:]), Zone: zone})
- default:
- return nil, &DNSError{Err: syscall.EWINDOWS.Error(), Name: name}
- }
- }
- return addrs, nil
- }
-
- type ret struct {
- addrs []IPAddr
- err error
- }
-
- var ch chan ret
- if ctx.Err() == nil {
- ch = make(chan ret, 1)
- go func() {
- addr, err := getaddr()
- ch <- ret{addrs: addr, err: err}
- }()
- }
-
- select {
- case r := <-ch:
- return r.addrs, r.err
- case <-ctx.Done():
- // TODO(bradfitz,brainman): cancel the ongoing
- // GetAddrInfoW? It would require conditionally using
- // GetAddrInfoEx with lpOverlapped, which requires
- // Windows 8 or newer. I guess we'll need oldLookupIP,
- // newLookupIP, and newerLookUP.
- //
- // For now we just let it finish and write to the
- // buffered channel.
- return nil, &DNSError{
- Name: name,
- Err: ctx.Err().Error(),
- IsTimeout: ctx.Err() == context.DeadlineExceeded,
- }
- }
-}
-
-func (r *Resolver) lookupPort(ctx context.Context, network, service string) (int, error) {
- if r.preferGoOverWindows() {
- return lookupPortMap(network, service)
- }
-
- // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
- acquireThread()
- defer releaseThread()
- var stype int32
- switch network {
- case "tcp4", "tcp6":
- stype = syscall.SOCK_STREAM
- case "udp4", "udp6":
- stype = syscall.SOCK_DGRAM
- }
- hints := syscall.AddrinfoW{
- Family: syscall.AF_UNSPEC,
- Socktype: stype,
- Protocol: syscall.IPPROTO_IP,
- }
- var result *syscall.AddrinfoW
- e := syscall.GetAddrInfoW(nil, syscall.StringToUTF16Ptr(service), &hints, &result)
- if e != nil {
- if port, err := lookupPortMap(network, service); err == nil {
- return port, nil
- }
- err := winError("getaddrinfow", e)
- dnsError := &DNSError{Err: err.Error(), Name: network + "/" + service}
- if err == errNoSuchHost {
- dnsError.IsNotFound = true
- }
- return 0, dnsError
- }
- defer syscall.FreeAddrInfoW(result)
- if result == nil {
- return 0, &DNSError{Err: syscall.EINVAL.Error(), Name: network + "/" + service}
- }
- addr := unsafe.Pointer(result.Addr)
- switch result.Family {
- case syscall.AF_INET:
- a := (*syscall.RawSockaddrInet4)(addr)
- return int(syscall.Ntohs(a.Port)), nil
- case syscall.AF_INET6:
- a := (*syscall.RawSockaddrInet6)(addr)
- return int(syscall.Ntohs(a.Port)), nil
- }
- return 0, &DNSError{Err: syscall.EINVAL.Error(), Name: network + "/" + service}
-}
-
-func (r *Resolver) lookupCNAME(ctx context.Context, name string) (string, error) {
- if order, conf := systemConf().hostLookupOrder(r, ""); order != hostLookupCgo {
- return r.goLookupCNAME(ctx, name, order, conf)
- }
-
- // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
- acquireThread()
- defer releaseThread()
- var rec *syscall.DNSRecord
- e := syscall.DnsQuery(name, syscall.DNS_TYPE_CNAME, 0, nil, &rec, nil)
- // windows returns DNS_INFO_NO_RECORDS if there are no CNAME-s
- if errno, ok := e.(syscall.Errno); ok && errno == syscall.DNS_INFO_NO_RECORDS {
- // if there are no aliases, the canonical name is the input name
- return absDomainName(name), nil
- }
- if e != nil {
- return "", &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
- }
- defer syscall.DnsRecordListFree(rec, 1)
-
- resolved := resolveCNAME(syscall.StringToUTF16Ptr(name), rec)
- cname := windows.UTF16PtrToString(resolved)
- return absDomainName(cname), nil
-}
-
-func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
- if r.preferGoOverWindows() {
- return r.goLookupSRV(ctx, service, proto, name)
- }
- // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
- acquireThread()
- defer releaseThread()
- var target string
- if service == "" && proto == "" {
- target = name
- } else {
- target = "_" + service + "._" + proto + "." + name
- }
- var rec *syscall.DNSRecord
- e := syscall.DnsQuery(target, syscall.DNS_TYPE_SRV, 0, nil, &rec, nil)
- if e != nil {
- return "", nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: target}
- }
- defer syscall.DnsRecordListFree(rec, 1)
-
- srvs := make([]*SRV, 0, 10)
- for _, p := range validRecs(rec, syscall.DNS_TYPE_SRV, target) {
- v := (*syscall.DNSSRVData)(unsafe.Pointer(&p.Data[0]))
- srvs = append(srvs, &SRV{absDomainName(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Target))[:])), v.Port, v.Priority, v.Weight})
- }
- byPriorityWeight(srvs).sort()
- return absDomainName(target), srvs, nil
-}
-
-func (r *Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
- if r.preferGoOverWindows() {
- return r.goLookupMX(ctx, name)
- }
- // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
- acquireThread()
- defer releaseThread()
- var rec *syscall.DNSRecord
- e := syscall.DnsQuery(name, syscall.DNS_TYPE_MX, 0, nil, &rec, nil)
- if e != nil {
- return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
- }
- defer syscall.DnsRecordListFree(rec, 1)
-
- mxs := make([]*MX, 0, 10)
- for _, p := range validRecs(rec, syscall.DNS_TYPE_MX, name) {
- v := (*syscall.DNSMXData)(unsafe.Pointer(&p.Data[0]))
- mxs = append(mxs, &MX{absDomainName(windows.UTF16PtrToString(v.NameExchange)), v.Preference})
- }
- byPref(mxs).sort()
- return mxs, nil
-}
-
-func (r *Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) {
- if r.preferGoOverWindows() {
- return r.goLookupNS(ctx, name)
- }
- // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
- acquireThread()
- defer releaseThread()
- var rec *syscall.DNSRecord
- e := syscall.DnsQuery(name, syscall.DNS_TYPE_NS, 0, nil, &rec, nil)
- if e != nil {
- return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
- }
- defer syscall.DnsRecordListFree(rec, 1)
-
- nss := make([]*NS, 0, 10)
- for _, p := range validRecs(rec, syscall.DNS_TYPE_NS, name) {
- v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
- nss = append(nss, &NS{absDomainName(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]))})
- }
- return nss, nil
-}
-
-func (r *Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) {
- if r.preferGoOverWindows() {
- return r.goLookupTXT(ctx, name)
- }
- // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
- acquireThread()
- defer releaseThread()
- var rec *syscall.DNSRecord
- e := syscall.DnsQuery(name, syscall.DNS_TYPE_TEXT, 0, nil, &rec, nil)
- if e != nil {
- return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
- }
- defer syscall.DnsRecordListFree(rec, 1)
-
- txts := make([]string, 0, 10)
- for _, p := range validRecs(rec, syscall.DNS_TYPE_TEXT, name) {
- d := (*syscall.DNSTXTData)(unsafe.Pointer(&p.Data[0]))
- s := ""
- for _, v := range (*[1 << 10]*uint16)(unsafe.Pointer(&(d.StringArray[0])))[:d.StringCount:d.StringCount] {
- s += windows.UTF16PtrToString(v)
- }
- txts = append(txts, s)
- }
- return txts, nil
-}
-
-func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error) {
- if r.preferGoOverWindows() {
- return r.goLookupPTR(ctx, addr, nil)
- }
-
- // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
- acquireThread()
- defer releaseThread()
- arpa, err := reverseaddr(addr)
- if err != nil {
- return nil, err
- }
- var rec *syscall.DNSRecord
- e := syscall.DnsQuery(arpa, syscall.DNS_TYPE_PTR, 0, nil, &rec, nil)
- if e != nil {
- return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: addr}
- }
- defer syscall.DnsRecordListFree(rec, 1)
-
- ptrs := make([]string, 0, 10)
- for _, p := range validRecs(rec, syscall.DNS_TYPE_PTR, arpa) {
- v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
- ptrs = append(ptrs, absDomainName(windows.UTF16PtrToString(v.Host)))
- }
- return ptrs, nil
-}
-
-const dnsSectionMask = 0x0003
-
-// returns only results applicable to name and resolves CNAME entries.
-func validRecs(r *syscall.DNSRecord, dnstype uint16, name string) []*syscall.DNSRecord {
- cname := syscall.StringToUTF16Ptr(name)
- if dnstype != syscall.DNS_TYPE_CNAME {
- cname = resolveCNAME(cname, r)
- }
- rec := make([]*syscall.DNSRecord, 0, 10)
- for p := r; p != nil; p = p.Next {
- // in case of a local machine, DNS records are returned with DNSREC_QUESTION flag instead of DNS_ANSWER
- if p.Dw&dnsSectionMask != syscall.DnsSectionAnswer && p.Dw&dnsSectionMask != syscall.DnsSectionQuestion {
- continue
- }
- if p.Type != dnstype {
- continue
- }
- if !syscall.DnsNameCompare(cname, p.Name) {
- continue
- }
- rec = append(rec, p)
- }
- return rec
-}
-
-// returns the last CNAME in chain.
-func resolveCNAME(name *uint16, r *syscall.DNSRecord) *uint16 {
- // limit cname resolving to 10 in case of an infinite CNAME loop
-Cname:
- for cnameloop := 0; cnameloop < 10; cnameloop++ {
- for p := r; p != nil; p = p.Next {
- if p.Dw&dnsSectionMask != syscall.DnsSectionAnswer {
- continue
- }
- if p.Type != syscall.DNS_TYPE_CNAME {
- continue
- }
- if !syscall.DnsNameCompare(name, p.Name) {
- continue
- }
- name = (*syscall.DNSPTRData)(unsafe.Pointer(&r.Data[0])).Host
- continue Cname
- }
- break
- }
- return name
-}
-
-// concurrentThreadsLimit returns the number of threads we permit to
-// run concurrently doing DNS lookups.
-func concurrentThreadsLimit() int {
- return 500
-}
diff --git a/contrib/go/_std_1.20/src/net/mail/message.go b/contrib/go/_std_1.20/src/net/mail/message.go
deleted file mode 100644
index 862f72de78..0000000000
--- a/contrib/go/_std_1.20/src/net/mail/message.go
+++ /dev/null
@@ -1,911 +0,0 @@
-// Copyright 2011 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 mail implements parsing of mail messages.
-
-For the most part, this package follows the syntax as specified by RFC 5322 and
-extended by RFC 6532.
-Notable divergences:
- - Obsolete address formats are not parsed, including addresses with
- embedded route information.
- - The full range of spacing (the CFWS syntax element) is not supported,
- such as breaking addresses across lines.
- - No unicode normalization is performed.
- - The special characters ()[]:;@\, are allowed to appear unquoted in names.
- - A leading From line is permitted, as in mbox format (RFC 4155).
-*/
-package mail
-
-import (
- "bufio"
- "errors"
- "fmt"
- "io"
- "log"
- "mime"
- "net/textproto"
- "strings"
- "sync"
- "time"
- "unicode/utf8"
-)
-
-var debug = debugT(false)
-
-type debugT bool
-
-func (d debugT) Printf(format string, args ...any) {
- if d {
- log.Printf(format, args...)
- }
-}
-
-// A Message represents a parsed mail message.
-type Message struct {
- Header Header
- Body io.Reader
-}
-
-// ReadMessage reads a message from r.
-// The headers are parsed, and the body of the message will be available
-// for reading from msg.Body.
-func ReadMessage(r io.Reader) (msg *Message, err error) {
- tp := textproto.NewReader(bufio.NewReader(r))
-
- hdr, err := readHeader(tp)
- if err != nil {
- return nil, err
- }
-
- return &Message{
- Header: Header(hdr),
- Body: tp.R,
- }, nil
-}
-
-// readHeader reads the message headers from r.
-// This is like textproto.ReadMIMEHeader, but doesn't validate.
-// The fix for issue #53188 tightened up net/textproto to enforce
-// restrictions of RFC 7230.
-// This package implements RFC 5322, which does not have those restrictions.
-// This function copies the relevant code from net/textproto,
-// simplified for RFC 5322.
-func readHeader(r *textproto.Reader) (map[string][]string, error) {
- m := make(map[string][]string)
-
- // The first line cannot start with a leading space.
- if buf, err := r.R.Peek(1); err == nil && (buf[0] == ' ' || buf[0] == '\t') {
- line, err := r.ReadLine()
- if err != nil {
- return m, err
- }
- return m, errors.New("malformed initial line: " + line)
- }
-
- for {
- kv, err := r.ReadContinuedLine()
- if kv == "" {
- return m, err
- }
-
- // Key ends at first colon.
- k, v, ok := strings.Cut(kv, ":")
- if !ok {
- return m, errors.New("malformed header line: " + kv)
- }
- key := textproto.CanonicalMIMEHeaderKey(k)
-
- // Permit empty key, because that is what we did in the past.
- if key == "" {
- continue
- }
-
- // Skip initial spaces in value.
- value := strings.TrimLeft(v, " \t")
-
- m[key] = append(m[key], value)
-
- if err != nil {
- return m, err
- }
- }
-}
-
-// Layouts suitable for passing to time.Parse.
-// These are tried in order.
-var (
- dateLayoutsBuildOnce sync.Once
- dateLayouts []string
-)
-
-func buildDateLayouts() {
- // Generate layouts based on RFC 5322, section 3.3.
-
- dows := [...]string{"", "Mon, "} // day-of-week
- days := [...]string{"2", "02"} // day = 1*2DIGIT
- years := [...]string{"2006", "06"} // year = 4*DIGIT / 2*DIGIT
- seconds := [...]string{":05", ""} // second
- // "-0700 (MST)" is not in RFC 5322, but is common.
- zones := [...]string{"-0700", "MST", "UT"} // zone = (("+" / "-") 4DIGIT) / "UT" / "GMT" / ...
-
- for _, dow := range dows {
- for _, day := range days {
- for _, year := range years {
- for _, second := range seconds {
- for _, zone := range zones {
- s := dow + day + " Jan " + year + " 15:04" + second + " " + zone
- dateLayouts = append(dateLayouts, s)
- }
- }
- }
- }
- }
-}
-
-// ParseDate parses an RFC 5322 date string.
-func ParseDate(date string) (time.Time, error) {
- dateLayoutsBuildOnce.Do(buildDateLayouts)
- // CR and LF must match and are tolerated anywhere in the date field.
- date = strings.ReplaceAll(date, "\r\n", "")
- if strings.Contains(date, "\r") {
- return time.Time{}, errors.New("mail: header has a CR without LF")
- }
- // Re-using some addrParser methods which support obsolete text, i.e. non-printable ASCII
- p := addrParser{date, nil}
- p.skipSpace()
-
- // RFC 5322: zone = (FWS ( "+" / "-" ) 4DIGIT) / obs-zone
- // zone length is always 5 chars unless obsolete (obs-zone)
- if ind := strings.IndexAny(p.s, "+-"); ind != -1 && len(p.s) >= ind+5 {
- date = p.s[:ind+5]
- p.s = p.s[ind+5:]
- } else {
- ind := strings.Index(p.s, "T")
- if ind == 0 {
- // In this case we have the following date formats:
- // * Thu, 20 Nov 1997 09:55:06 MDT
- // * Thu, 20 Nov 1997 09:55:06 MDT (MDT)
- // * Thu, 20 Nov 1997 09:55:06 MDT (This comment)
- ind = strings.Index(p.s[1:], "T")
- if ind != -1 {
- ind++
- }
- }
-
- if ind != -1 && len(p.s) >= ind+5 {
- // The last letter T of the obsolete time zone is checked when no standard time zone is found.
- // If T is misplaced, the date to parse is garbage.
- date = p.s[:ind+1]
- p.s = p.s[ind+1:]
- }
- }
- if !p.skipCFWS() {
- return time.Time{}, errors.New("mail: misformatted parenthetical comment")
- }
- for _, layout := range dateLayouts {
- t, err := time.Parse(layout, date)
- if err == nil {
- return t, nil
- }
- }
- return time.Time{}, errors.New("mail: header could not be parsed")
-}
-
-// A Header represents the key-value pairs in a mail message header.
-type Header map[string][]string
-
-// Get gets the first value associated with the given key.
-// It is case insensitive; CanonicalMIMEHeaderKey is used
-// to canonicalize the provided key.
-// If there are no values associated with the key, Get returns "".
-// To access multiple values of a key, or to use non-canonical keys,
-// access the map directly.
-func (h Header) Get(key string) string {
- return textproto.MIMEHeader(h).Get(key)
-}
-
-var ErrHeaderNotPresent = errors.New("mail: header not in message")
-
-// Date parses the Date header field.
-func (h Header) Date() (time.Time, error) {
- hdr := h.Get("Date")
- if hdr == "" {
- return time.Time{}, ErrHeaderNotPresent
- }
- return ParseDate(hdr)
-}
-
-// AddressList parses the named header field as a list of addresses.
-func (h Header) AddressList(key string) ([]*Address, error) {
- hdr := h.Get(key)
- if hdr == "" {
- return nil, ErrHeaderNotPresent
- }
- return ParseAddressList(hdr)
-}
-
-// Address represents a single mail address.
-// An address such as "Barry Gibbs <bg@example.com>" is represented
-// as Address{Name: "Barry Gibbs", Address: "bg@example.com"}.
-type Address struct {
- Name string // Proper name; may be empty.
- Address string // user@domain
-}
-
-// ParseAddress parses a single RFC 5322 address, e.g. "Barry Gibbs <bg@example.com>"
-func ParseAddress(address string) (*Address, error) {
- return (&addrParser{s: address}).parseSingleAddress()
-}
-
-// ParseAddressList parses the given string as a list of addresses.
-func ParseAddressList(list string) ([]*Address, error) {
- return (&addrParser{s: list}).parseAddressList()
-}
-
-// An AddressParser is an RFC 5322 address parser.
-type AddressParser struct {
- // WordDecoder optionally specifies a decoder for RFC 2047 encoded-words.
- WordDecoder *mime.WordDecoder
-}
-
-// Parse parses a single RFC 5322 address of the
-// form "Gogh Fir <gf@example.com>" or "foo@example.com".
-func (p *AddressParser) Parse(address string) (*Address, error) {
- return (&addrParser{s: address, dec: p.WordDecoder}).parseSingleAddress()
-}
-
-// ParseList parses the given string as a list of comma-separated addresses
-// of the form "Gogh Fir <gf@example.com>" or "foo@example.com".
-func (p *AddressParser) ParseList(list string) ([]*Address, error) {
- return (&addrParser{s: list, dec: p.WordDecoder}).parseAddressList()
-}
-
-// String formats the address as a valid RFC 5322 address.
-// If the address's name contains non-ASCII characters
-// the name will be rendered according to RFC 2047.
-func (a *Address) String() string {
- // Format address local@domain
- at := strings.LastIndex(a.Address, "@")
- var local, domain string
- if at < 0 {
- // This is a malformed address ("@" is required in addr-spec);
- // treat the whole address as local-part.
- local = a.Address
- } else {
- local, domain = a.Address[:at], a.Address[at+1:]
- }
-
- // Add quotes if needed
- quoteLocal := false
- for i, r := range local {
- if isAtext(r, false, false) {
- continue
- }
- if r == '.' {
- // Dots are okay if they are surrounded by atext.
- // We only need to check that the previous byte is
- // not a dot, and this isn't the end of the string.
- if i > 0 && local[i-1] != '.' && i < len(local)-1 {
- continue
- }
- }
- quoteLocal = true
- break
- }
- if quoteLocal {
- local = quoteString(local)
-
- }
-
- s := "<" + local + "@" + domain + ">"
-
- if a.Name == "" {
- return s
- }
-
- // If every character is printable ASCII, quoting is simple.
- allPrintable := true
- for _, r := range a.Name {
- // isWSP here should actually be isFWS,
- // but we don't support folding yet.
- if !isVchar(r) && !isWSP(r) || isMultibyte(r) {
- allPrintable = false
- break
- }
- }
- if allPrintable {
- return quoteString(a.Name) + " " + s
- }
-
- // Text in an encoded-word in a display-name must not contain certain
- // characters like quotes or parentheses (see RFC 2047 section 5.3).
- // When this is the case encode the name using base64 encoding.
- if strings.ContainsAny(a.Name, "\"#$%&'(),.:;<>@[]^`{|}~") {
- return mime.BEncoding.Encode("utf-8", a.Name) + " " + s
- }
- return mime.QEncoding.Encode("utf-8", a.Name) + " " + s
-}
-
-type addrParser struct {
- s string
- dec *mime.WordDecoder // may be nil
-}
-
-func (p *addrParser) parseAddressList() ([]*Address, error) {
- var list []*Address
- for {
- p.skipSpace()
-
- // allow skipping empty entries (RFC5322 obs-addr-list)
- if p.consume(',') {
- continue
- }
-
- addrs, err := p.parseAddress(true)
- if err != nil {
- return nil, err
- }
- list = append(list, addrs...)
-
- if !p.skipCFWS() {
- return nil, errors.New("mail: misformatted parenthetical comment")
- }
- if p.empty() {
- break
- }
- if p.peek() != ',' {
- return nil, errors.New("mail: expected comma")
- }
-
- // Skip empty entries for obs-addr-list.
- for p.consume(',') {
- p.skipSpace()
- }
- if p.empty() {
- break
- }
- }
- return list, nil
-}
-
-func (p *addrParser) parseSingleAddress() (*Address, error) {
- addrs, err := p.parseAddress(true)
- if err != nil {
- return nil, err
- }
- if !p.skipCFWS() {
- return nil, errors.New("mail: misformatted parenthetical comment")
- }
- if !p.empty() {
- return nil, fmt.Errorf("mail: expected single address, got %q", p.s)
- }
- if len(addrs) == 0 {
- return nil, errors.New("mail: empty group")
- }
- if len(addrs) > 1 {
- return nil, errors.New("mail: group with multiple addresses")
- }
- return addrs[0], nil
-}
-
-// parseAddress parses a single RFC 5322 address at the start of p.
-func (p *addrParser) parseAddress(handleGroup bool) ([]*Address, error) {
- debug.Printf("parseAddress: %q", p.s)
- p.skipSpace()
- if p.empty() {
- return nil, errors.New("mail: no address")
- }
-
- // address = mailbox / group
- // mailbox = name-addr / addr-spec
- // group = display-name ":" [group-list] ";" [CFWS]
-
- // addr-spec has a more restricted grammar than name-addr,
- // so try parsing it first, and fallback to name-addr.
- // TODO(dsymonds): Is this really correct?
- spec, err := p.consumeAddrSpec()
- if err == nil {
- var displayName string
- p.skipSpace()
- if !p.empty() && p.peek() == '(' {
- displayName, err = p.consumeDisplayNameComment()
- if err != nil {
- return nil, err
- }
- }
-
- return []*Address{{
- Name: displayName,
- Address: spec,
- }}, err
- }
- debug.Printf("parseAddress: not an addr-spec: %v", err)
- debug.Printf("parseAddress: state is now %q", p.s)
-
- // display-name
- var displayName string
- if p.peek() != '<' {
- displayName, err = p.consumePhrase()
- if err != nil {
- return nil, err
- }
- }
- debug.Printf("parseAddress: displayName=%q", displayName)
-
- p.skipSpace()
- if handleGroup {
- if p.consume(':') {
- return p.consumeGroupList()
- }
- }
- // angle-addr = "<" addr-spec ">"
- if !p.consume('<') {
- atext := true
- for _, r := range displayName {
- if !isAtext(r, true, false) {
- atext = false
- break
- }
- }
- if atext {
- // The input is like "foo.bar"; it's possible the input
- // meant to be "foo.bar@domain", or "foo.bar <...>".
- return nil, errors.New("mail: missing '@' or angle-addr")
- }
- // The input is like "Full Name", which couldn't possibly be a
- // valid email address if followed by "@domain"; the input
- // likely meant to be "Full Name <...>".
- return nil, errors.New("mail: no angle-addr")
- }
- spec, err = p.consumeAddrSpec()
- if err != nil {
- return nil, err
- }
- if !p.consume('>') {
- return nil, errors.New("mail: unclosed angle-addr")
- }
- debug.Printf("parseAddress: spec=%q", spec)
-
- return []*Address{{
- Name: displayName,
- Address: spec,
- }}, nil
-}
-
-func (p *addrParser) consumeGroupList() ([]*Address, error) {
- var group []*Address
- // handle empty group.
- p.skipSpace()
- if p.consume(';') {
- p.skipCFWS()
- return group, nil
- }
-
- for {
- p.skipSpace()
- // embedded groups not allowed.
- addrs, err := p.parseAddress(false)
- if err != nil {
- return nil, err
- }
- group = append(group, addrs...)
-
- if !p.skipCFWS() {
- return nil, errors.New("mail: misformatted parenthetical comment")
- }
- if p.consume(';') {
- p.skipCFWS()
- break
- }
- if !p.consume(',') {
- return nil, errors.New("mail: expected comma")
- }
- }
- return group, nil
-}
-
-// consumeAddrSpec parses a single RFC 5322 addr-spec at the start of p.
-func (p *addrParser) consumeAddrSpec() (spec string, err error) {
- debug.Printf("consumeAddrSpec: %q", p.s)
-
- orig := *p
- defer func() {
- if err != nil {
- *p = orig
- }
- }()
-
- // local-part = dot-atom / quoted-string
- var localPart string
- p.skipSpace()
- if p.empty() {
- return "", errors.New("mail: no addr-spec")
- }
- if p.peek() == '"' {
- // quoted-string
- debug.Printf("consumeAddrSpec: parsing quoted-string")
- localPart, err = p.consumeQuotedString()
- if localPart == "" {
- err = errors.New("mail: empty quoted string in addr-spec")
- }
- } else {
- // dot-atom
- debug.Printf("consumeAddrSpec: parsing dot-atom")
- localPart, err = p.consumeAtom(true, false)
- }
- if err != nil {
- debug.Printf("consumeAddrSpec: failed: %v", err)
- return "", err
- }
-
- if !p.consume('@') {
- return "", errors.New("mail: missing @ in addr-spec")
- }
-
- // domain = dot-atom / domain-literal
- var domain string
- p.skipSpace()
- if p.empty() {
- return "", errors.New("mail: no domain in addr-spec")
- }
- // TODO(dsymonds): Handle domain-literal
- domain, err = p.consumeAtom(true, false)
- if err != nil {
- return "", err
- }
-
- return localPart + "@" + domain, nil
-}
-
-// consumePhrase parses the RFC 5322 phrase at the start of p.
-func (p *addrParser) consumePhrase() (phrase string, err error) {
- debug.Printf("consumePhrase: [%s]", p.s)
- // phrase = 1*word
- var words []string
- var isPrevEncoded bool
- for {
- // word = atom / quoted-string
- var word string
- p.skipSpace()
- if p.empty() {
- break
- }
- isEncoded := false
- if p.peek() == '"' {
- // quoted-string
- word, err = p.consumeQuotedString()
- } else {
- // atom
- // We actually parse dot-atom here to be more permissive
- // than what RFC 5322 specifies.
- word, err = p.consumeAtom(true, true)
- if err == nil {
- word, isEncoded, err = p.decodeRFC2047Word(word)
- }
- }
-
- if err != nil {
- break
- }
- debug.Printf("consumePhrase: consumed %q", word)
- if isPrevEncoded && isEncoded {
- words[len(words)-1] += word
- } else {
- words = append(words, word)
- }
- isPrevEncoded = isEncoded
- }
- // Ignore any error if we got at least one word.
- if err != nil && len(words) == 0 {
- debug.Printf("consumePhrase: hit err: %v", err)
- return "", fmt.Errorf("mail: missing word in phrase: %v", err)
- }
- phrase = strings.Join(words, " ")
- return phrase, nil
-}
-
-// consumeQuotedString parses the quoted string at the start of p.
-func (p *addrParser) consumeQuotedString() (qs string, err error) {
- // Assume first byte is '"'.
- i := 1
- qsb := make([]rune, 0, 10)
-
- escaped := false
-
-Loop:
- for {
- r, size := utf8.DecodeRuneInString(p.s[i:])
-
- switch {
- case size == 0:
- return "", errors.New("mail: unclosed quoted-string")
-
- case size == 1 && r == utf8.RuneError:
- return "", fmt.Errorf("mail: invalid utf-8 in quoted-string: %q", p.s)
-
- case escaped:
- // quoted-pair = ("\" (VCHAR / WSP))
-
- if !isVchar(r) && !isWSP(r) {
- return "", fmt.Errorf("mail: bad character in quoted-string: %q", r)
- }
-
- qsb = append(qsb, r)
- escaped = false
-
- case isQtext(r) || isWSP(r):
- // qtext (printable US-ASCII excluding " and \), or
- // FWS (almost; we're ignoring CRLF)
- qsb = append(qsb, r)
-
- case r == '"':
- break Loop
-
- case r == '\\':
- escaped = true
-
- default:
- return "", fmt.Errorf("mail: bad character in quoted-string: %q", r)
-
- }
-
- i += size
- }
- p.s = p.s[i+1:]
- return string(qsb), nil
-}
-
-// consumeAtom parses an RFC 5322 atom at the start of p.
-// If dot is true, consumeAtom parses an RFC 5322 dot-atom instead.
-// If permissive is true, consumeAtom will not fail on:
-// - leading/trailing/double dots in the atom (see golang.org/issue/4938)
-// - special characters (RFC 5322 3.2.3) except '<', '>', ':' and '"' (see golang.org/issue/21018)
-func (p *addrParser) consumeAtom(dot bool, permissive bool) (atom string, err error) {
- i := 0
-
-Loop:
- for {
- r, size := utf8.DecodeRuneInString(p.s[i:])
- switch {
- case size == 1 && r == utf8.RuneError:
- return "", fmt.Errorf("mail: invalid utf-8 in address: %q", p.s)
-
- case size == 0 || !isAtext(r, dot, permissive):
- break Loop
-
- default:
- i += size
-
- }
- }
-
- if i == 0 {
- return "", errors.New("mail: invalid string")
- }
- atom, p.s = p.s[:i], p.s[i:]
- if !permissive {
- if strings.HasPrefix(atom, ".") {
- return "", errors.New("mail: leading dot in atom")
- }
- if strings.Contains(atom, "..") {
- return "", errors.New("mail: double dot in atom")
- }
- if strings.HasSuffix(atom, ".") {
- return "", errors.New("mail: trailing dot in atom")
- }
- }
- return atom, nil
-}
-
-func (p *addrParser) consumeDisplayNameComment() (string, error) {
- if !p.consume('(') {
- return "", errors.New("mail: comment does not start with (")
- }
- comment, ok := p.consumeComment()
- if !ok {
- return "", errors.New("mail: misformatted parenthetical comment")
- }
-
- // TODO(stapelberg): parse quoted-string within comment
- words := strings.FieldsFunc(comment, func(r rune) bool { return r == ' ' || r == '\t' })
- for idx, word := range words {
- decoded, isEncoded, err := p.decodeRFC2047Word(word)
- if err != nil {
- return "", err
- }
- if isEncoded {
- words[idx] = decoded
- }
- }
-
- return strings.Join(words, " "), nil
-}
-
-func (p *addrParser) consume(c byte) bool {
- if p.empty() || p.peek() != c {
- return false
- }
- p.s = p.s[1:]
- return true
-}
-
-// skipSpace skips the leading space and tab characters.
-func (p *addrParser) skipSpace() {
- p.s = strings.TrimLeft(p.s, " \t")
-}
-
-func (p *addrParser) peek() byte {
- return p.s[0]
-}
-
-func (p *addrParser) empty() bool {
- return p.len() == 0
-}
-
-func (p *addrParser) len() int {
- return len(p.s)
-}
-
-// skipCFWS skips CFWS as defined in RFC5322.
-func (p *addrParser) skipCFWS() bool {
- p.skipSpace()
-
- for {
- if !p.consume('(') {
- break
- }
-
- if _, ok := p.consumeComment(); !ok {
- return false
- }
-
- p.skipSpace()
- }
-
- return true
-}
-
-func (p *addrParser) consumeComment() (string, bool) {
- // '(' already consumed.
- depth := 1
-
- var comment string
- for {
- if p.empty() || depth == 0 {
- break
- }
-
- if p.peek() == '\\' && p.len() > 1 {
- p.s = p.s[1:]
- } else if p.peek() == '(' {
- depth++
- } else if p.peek() == ')' {
- depth--
- }
- if depth > 0 {
- comment += p.s[:1]
- }
- p.s = p.s[1:]
- }
-
- return comment, depth == 0
-}
-
-func (p *addrParser) decodeRFC2047Word(s string) (word string, isEncoded bool, err error) {
- dec := p.dec
- if dec == nil {
- dec = &rfc2047Decoder
- }
-
- // Substitute our own CharsetReader function so that we can tell
- // whether an error from the Decode method was due to the
- // CharsetReader (meaning the charset is invalid).
- // We used to look for the charsetError type in the error result,
- // but that behaves badly with CharsetReaders other than the
- // one in rfc2047Decoder.
- adec := *dec
- charsetReaderError := false
- adec.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {
- if dec.CharsetReader == nil {
- charsetReaderError = true
- return nil, charsetError(charset)
- }
- r, err := dec.CharsetReader(charset, input)
- if err != nil {
- charsetReaderError = true
- }
- return r, err
- }
- word, err = adec.Decode(s)
- if err == nil {
- return word, true, nil
- }
-
- // If the error came from the character set reader
- // (meaning the character set itself is invalid
- // but the decoding worked fine until then),
- // return the original text and the error,
- // with isEncoded=true.
- if charsetReaderError {
- return s, true, err
- }
-
- // Ignore invalid RFC 2047 encoded-word errors.
- return s, false, nil
-}
-
-var rfc2047Decoder = mime.WordDecoder{
- CharsetReader: func(charset string, input io.Reader) (io.Reader, error) {
- return nil, charsetError(charset)
- },
-}
-
-type charsetError string
-
-func (e charsetError) Error() string {
- return fmt.Sprintf("charset not supported: %q", string(e))
-}
-
-// isAtext reports whether r is an RFC 5322 atext character.
-// If dot is true, period is included.
-// If permissive is true, RFC 5322 3.2.3 specials is included,
-// except '<', '>', ':' and '"'.
-func isAtext(r rune, dot, permissive bool) bool {
- switch r {
- case '.':
- return dot
-
- // RFC 5322 3.2.3. specials
- case '(', ')', '[', ']', ';', '@', '\\', ',':
- return permissive
-
- case '<', '>', '"', ':':
- return false
- }
- return isVchar(r)
-}
-
-// isQtext reports whether r is an RFC 5322 qtext character.
-func isQtext(r rune) bool {
- // Printable US-ASCII, excluding backslash or quote.
- if r == '\\' || r == '"' {
- return false
- }
- return isVchar(r)
-}
-
-// quoteString renders a string as an RFC 5322 quoted-string.
-func quoteString(s string) string {
- var b strings.Builder
- b.WriteByte('"')
- for _, r := range s {
- if isQtext(r) || isWSP(r) {
- b.WriteRune(r)
- } else if isVchar(r) {
- b.WriteByte('\\')
- b.WriteRune(r)
- }
- }
- b.WriteByte('"')
- return b.String()
-}
-
-// isVchar reports whether r is an RFC 5322 VCHAR character.
-func isVchar(r rune) bool {
- // Visible (printing) characters.
- return '!' <= r && r <= '~' || isMultibyte(r)
-}
-
-// isMultibyte reports whether r is a multi-byte UTF-8 character
-// as supported by RFC 6532.
-func isMultibyte(r rune) bool {
- return r >= utf8.RuneSelf
-}
-
-// isWSP reports whether r is a WSP (white space).
-// WSP is a space or horizontal tab (RFC 5234 Appendix B).
-func isWSP(r rune) bool {
- return r == ' ' || r == '\t'
-}
diff --git a/contrib/go/_std_1.20/src/net/net.go b/contrib/go/_std_1.20/src/net/net.go
deleted file mode 100644
index 0a4f7471c4..0000000000
--- a/contrib/go/_std_1.20/src/net/net.go
+++ /dev/null
@@ -1,771 +0,0 @@
-// Copyright 2009 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 net provides a portable interface for network I/O, including
-TCP/IP, UDP, domain name resolution, and Unix domain sockets.
-
-Although the package provides access to low-level networking
-primitives, most clients will need only the basic interface provided
-by the Dial, Listen, and Accept functions and the associated
-Conn and Listener interfaces. The crypto/tls package uses
-the same interfaces and similar Dial and Listen functions.
-
-The Dial function connects to a server:
-
- conn, err := net.Dial("tcp", "golang.org:80")
- if err != nil {
- // handle error
- }
- fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
- status, err := bufio.NewReader(conn).ReadString('\n')
- // ...
-
-The Listen function creates servers:
-
- ln, err := net.Listen("tcp", ":8080")
- if err != nil {
- // handle error
- }
- for {
- conn, err := ln.Accept()
- if err != nil {
- // handle error
- }
- go handleConnection(conn)
- }
-
-# Name Resolution
-
-The method for resolving domain names, whether indirectly with functions like Dial
-or directly with functions like LookupHost and LookupAddr, varies by operating system.
-
-On Unix systems, the resolver has two options for resolving names.
-It can use a pure Go resolver that sends DNS requests directly to the servers
-listed in /etc/resolv.conf, or it can use a cgo-based resolver that calls C
-library routines such as getaddrinfo and getnameinfo.
-
-By default the pure Go resolver is used, because a blocked DNS request consumes
-only a goroutine, while a blocked C call consumes an operating system thread.
-When cgo is available, the cgo-based resolver is used instead under a variety of
-conditions: on systems that do not let programs make direct DNS requests (OS X),
-when the LOCALDOMAIN environment variable is present (even if empty),
-when the RES_OPTIONS or HOSTALIASES environment variable is non-empty,
-when the ASR_CONFIG environment variable is non-empty (OpenBSD only),
-when /etc/resolv.conf or /etc/nsswitch.conf specify the use of features that the
-Go resolver does not implement, and when the name being looked up ends in .local
-or is an mDNS name.
-
-The resolver decision can be overridden by setting the netdns value of the
-GODEBUG environment variable (see package runtime) to go or cgo, as in:
-
- export GODEBUG=netdns=go # force pure Go resolver
- export GODEBUG=netdns=cgo # force native resolver (cgo, win32)
-
-The decision can also be forced while building the Go source tree
-by setting the netgo or netcgo build tag.
-
-A numeric netdns setting, as in GODEBUG=netdns=1, causes the resolver
-to print debugging information about its decisions.
-To force a particular resolver while also printing debugging information,
-join the two settings by a plus sign, as in GODEBUG=netdns=go+1.
-
-On Plan 9, the resolver always accesses /net/cs and /net/dns.
-
-On Windows, in Go 1.18.x and earlier, the resolver always used C
-library functions, such as GetAddrInfo and DnsQuery.
-*/
-package net
-
-import (
- "context"
- "errors"
- "internal/poll"
- "io"
- "os"
- "sync"
- "syscall"
- "time"
-)
-
-// netGo and netCgo contain the state of the build tags used
-// to build this binary, and whether cgo is available.
-// conf.go mirrors these into conf for easier testing.
-var (
- netGo bool // set true in cgo_stub.go for build tag "netgo" (or no cgo)
- netCgo bool // set true in conf_netcgo.go for build tag "netcgo"
-)
-
-// Addr represents a network end point address.
-//
-// The two methods Network and String conventionally return strings
-// that can be passed as the arguments to Dial, but the exact form
-// and meaning of the strings is up to the implementation.
-type Addr interface {
- Network() string // name of the network (for example, "tcp", "udp")
- String() string // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80")
-}
-
-// Conn is a generic stream-oriented network connection.
-//
-// Multiple goroutines may invoke methods on a Conn simultaneously.
-type Conn interface {
- // Read reads data from the connection.
- // Read can be made to time out and return an error after a fixed
- // time limit; see SetDeadline and SetReadDeadline.
- Read(b []byte) (n int, err error)
-
- // Write writes data to the connection.
- // Write can be made to time out and return an error after a fixed
- // time limit; see SetDeadline and SetWriteDeadline.
- Write(b []byte) (n int, err error)
-
- // Close closes the connection.
- // Any blocked Read or Write operations will be unblocked and return errors.
- Close() error
-
- // LocalAddr returns the local network address, if known.
- LocalAddr() Addr
-
- // RemoteAddr returns the remote network address, if known.
- RemoteAddr() Addr
-
- // SetDeadline sets the read and write deadlines associated
- // with the connection. It is equivalent to calling both
- // SetReadDeadline and SetWriteDeadline.
- //
- // A deadline is an absolute time after which I/O operations
- // fail instead of blocking. The deadline applies to all future
- // and pending I/O, not just the immediately following call to
- // Read or Write. After a deadline has been exceeded, the
- // connection can be refreshed by setting a deadline in the future.
- //
- // If the deadline is exceeded a call to Read or Write or to other
- // I/O methods will return an error that wraps os.ErrDeadlineExceeded.
- // This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
- // The error's Timeout method will return true, but note that there
- // are other possible errors for which the Timeout method will
- // return true even if the deadline has not been exceeded.
- //
- // An idle timeout can be implemented by repeatedly extending
- // the deadline after successful Read or Write calls.
- //
- // A zero value for t means I/O operations will not time out.
- SetDeadline(t time.Time) error
-
- // SetReadDeadline sets the deadline for future Read calls
- // and any currently-blocked Read call.
- // A zero value for t means Read will not time out.
- SetReadDeadline(t time.Time) error
-
- // SetWriteDeadline sets the deadline for future Write calls
- // and any currently-blocked Write call.
- // Even if write times out, it may return n > 0, indicating that
- // some of the data was successfully written.
- // A zero value for t means Write will not time out.
- SetWriteDeadline(t time.Time) error
-}
-
-type conn struct {
- fd *netFD
-}
-
-func (c *conn) ok() bool { return c != nil && c.fd != nil }
-
-// Implementation of the Conn interface.
-
-// Read implements the Conn Read method.
-func (c *conn) Read(b []byte) (int, error) {
- if !c.ok() {
- return 0, syscall.EINVAL
- }
- n, err := c.fd.Read(b)
- if err != nil && err != io.EOF {
- err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return n, err
-}
-
-// Write implements the Conn Write method.
-func (c *conn) Write(b []byte) (int, error) {
- if !c.ok() {
- return 0, syscall.EINVAL
- }
- n, err := c.fd.Write(b)
- if err != nil {
- err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return n, err
-}
-
-// Close closes the connection.
-func (c *conn) Close() error {
- if !c.ok() {
- return syscall.EINVAL
- }
- err := c.fd.Close()
- if err != nil {
- err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return err
-}
-
-// LocalAddr returns the local network address.
-// The Addr returned is shared by all invocations of LocalAddr, so
-// do not modify it.
-func (c *conn) LocalAddr() Addr {
- if !c.ok() {
- return nil
- }
- return c.fd.laddr
-}
-
-// RemoteAddr returns the remote network address.
-// The Addr returned is shared by all invocations of RemoteAddr, so
-// do not modify it.
-func (c *conn) RemoteAddr() Addr {
- if !c.ok() {
- return nil
- }
- return c.fd.raddr
-}
-
-// SetDeadline implements the Conn SetDeadline method.
-func (c *conn) SetDeadline(t time.Time) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := c.fd.SetDeadline(t); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
- }
- return nil
-}
-
-// SetReadDeadline implements the Conn SetReadDeadline method.
-func (c *conn) SetReadDeadline(t time.Time) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := c.fd.SetReadDeadline(t); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
- }
- return nil
-}
-
-// SetWriteDeadline implements the Conn SetWriteDeadline method.
-func (c *conn) SetWriteDeadline(t time.Time) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := c.fd.SetWriteDeadline(t); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
- }
- return nil
-}
-
-// SetReadBuffer sets the size of the operating system's
-// receive buffer associated with the connection.
-func (c *conn) SetReadBuffer(bytes int) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := setReadBuffer(c.fd, bytes); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
- }
- return nil
-}
-
-// SetWriteBuffer sets the size of the operating system's
-// transmit buffer associated with the connection.
-func (c *conn) SetWriteBuffer(bytes int) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := setWriteBuffer(c.fd, bytes); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
- }
- return nil
-}
-
-// File returns a copy of the underlying os.File.
-// It is the caller's responsibility to close f when finished.
-// Closing c does not affect f, and closing f does not affect c.
-//
-// The returned os.File's file descriptor is different from the connection's.
-// Attempting to change properties of the original using this duplicate
-// may or may not have the desired effect.
-func (c *conn) File() (f *os.File, err error) {
- f, err = c.fd.dup()
- if err != nil {
- err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return
-}
-
-// PacketConn is a generic packet-oriented network connection.
-//
-// Multiple goroutines may invoke methods on a PacketConn simultaneously.
-type PacketConn interface {
- // ReadFrom reads a packet from the connection,
- // copying the payload into p. It returns the number of
- // bytes copied into p and the return address that
- // was on the packet.
- // It returns the number of bytes read (0 <= n <= len(p))
- // and any error encountered. Callers should always process
- // the n > 0 bytes returned before considering the error err.
- // ReadFrom can be made to time out and return an error after a
- // fixed time limit; see SetDeadline and SetReadDeadline.
- ReadFrom(p []byte) (n int, addr Addr, err error)
-
- // WriteTo writes a packet with payload p to addr.
- // WriteTo can be made to time out and return an Error after a
- // fixed time limit; see SetDeadline and SetWriteDeadline.
- // On packet-oriented connections, write timeouts are rare.
- WriteTo(p []byte, addr Addr) (n int, err error)
-
- // Close closes the connection.
- // Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
- Close() error
-
- // LocalAddr returns the local network address, if known.
- LocalAddr() Addr
-
- // SetDeadline sets the read and write deadlines associated
- // with the connection. It is equivalent to calling both
- // SetReadDeadline and SetWriteDeadline.
- //
- // A deadline is an absolute time after which I/O operations
- // fail instead of blocking. The deadline applies to all future
- // and pending I/O, not just the immediately following call to
- // Read or Write. After a deadline has been exceeded, the
- // connection can be refreshed by setting a deadline in the future.
- //
- // If the deadline is exceeded a call to Read or Write or to other
- // I/O methods will return an error that wraps os.ErrDeadlineExceeded.
- // This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
- // The error's Timeout method will return true, but note that there
- // are other possible errors for which the Timeout method will
- // return true even if the deadline has not been exceeded.
- //
- // An idle timeout can be implemented by repeatedly extending
- // the deadline after successful ReadFrom or WriteTo calls.
- //
- // A zero value for t means I/O operations will not time out.
- SetDeadline(t time.Time) error
-
- // SetReadDeadline sets the deadline for future ReadFrom calls
- // and any currently-blocked ReadFrom call.
- // A zero value for t means ReadFrom will not time out.
- SetReadDeadline(t time.Time) error
-
- // SetWriteDeadline sets the deadline for future WriteTo calls
- // and any currently-blocked WriteTo call.
- // Even if write times out, it may return n > 0, indicating that
- // some of the data was successfully written.
- // A zero value for t means WriteTo will not time out.
- SetWriteDeadline(t time.Time) error
-}
-
-var listenerBacklogCache struct {
- sync.Once
- val int
-}
-
-// listenerBacklog is a caching wrapper around maxListenerBacklog.
-func listenerBacklog() int {
- listenerBacklogCache.Do(func() { listenerBacklogCache.val = maxListenerBacklog() })
- return listenerBacklogCache.val
-}
-
-// A Listener is a generic network listener for stream-oriented protocols.
-//
-// Multiple goroutines may invoke methods on a Listener simultaneously.
-type Listener interface {
- // Accept waits for and returns the next connection to the listener.
- Accept() (Conn, error)
-
- // Close closes the listener.
- // Any blocked Accept operations will be unblocked and return errors.
- Close() error
-
- // Addr returns the listener's network address.
- Addr() Addr
-}
-
-// An Error represents a network error.
-type Error interface {
- error
- Timeout() bool // Is the error a timeout?
-
- // Deprecated: Temporary errors are not well-defined.
- // Most "temporary" errors are timeouts, and the few exceptions are surprising.
- // Do not use this method.
- Temporary() bool
-}
-
-// Various errors contained in OpError.
-var (
- // For connection setup operations.
- errNoSuitableAddress = errors.New("no suitable address found")
-
- // For connection setup and write operations.
- errMissingAddress = errors.New("missing address")
-
- // For both read and write operations.
- errCanceled = canceledError{}
- ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection")
-)
-
-// canceledError lets us return the same error string we have always
-// returned, while still being Is context.Canceled.
-type canceledError struct{}
-
-func (canceledError) Error() string { return "operation was canceled" }
-
-func (canceledError) Is(err error) bool { return err == context.Canceled }
-
-// mapErr maps from the context errors to the historical internal net
-// error values.
-func mapErr(err error) error {
- switch err {
- case context.Canceled:
- return errCanceled
- case context.DeadlineExceeded:
- return errTimeout
- default:
- return err
- }
-}
-
-// OpError is the error type usually returned by functions in the net
-// package. It describes the operation, network type, and address of
-// an error.
-type OpError struct {
- // Op is the operation which caused the error, such as
- // "read" or "write".
- Op string
-
- // Net is the network type on which this error occurred,
- // such as "tcp" or "udp6".
- Net string
-
- // For operations involving a remote network connection, like
- // Dial, Read, or Write, Source is the corresponding local
- // network address.
- Source Addr
-
- // Addr is the network address for which this error occurred.
- // For local operations, like Listen or SetDeadline, Addr is
- // the address of the local endpoint being manipulated.
- // For operations involving a remote network connection, like
- // Dial, Read, or Write, Addr is the remote address of that
- // connection.
- Addr Addr
-
- // Err is the error that occurred during the operation.
- // The Error method panics if the error is nil.
- Err error
-}
-
-func (e *OpError) Unwrap() error { return e.Err }
-
-func (e *OpError) Error() string {
- if e == nil {
- return "<nil>"
- }
- s := e.Op
- if e.Net != "" {
- s += " " + e.Net
- }
- if e.Source != nil {
- s += " " + e.Source.String()
- }
- if e.Addr != nil {
- if e.Source != nil {
- s += "->"
- } else {
- s += " "
- }
- s += e.Addr.String()
- }
- s += ": " + e.Err.Error()
- return s
-}
-
-var (
- // aLongTimeAgo is a non-zero time, far in the past, used for
- // immediate cancellation of dials.
- aLongTimeAgo = time.Unix(1, 0)
-
- // noDeadline and noCancel are just zero values for
- // readability with functions taking too many parameters.
- noDeadline = time.Time{}
- noCancel = (chan struct{})(nil)
-)
-
-type timeout interface {
- Timeout() bool
-}
-
-func (e *OpError) Timeout() bool {
- if ne, ok := e.Err.(*os.SyscallError); ok {
- t, ok := ne.Err.(timeout)
- return ok && t.Timeout()
- }
- t, ok := e.Err.(timeout)
- return ok && t.Timeout()
-}
-
-type temporary interface {
- Temporary() bool
-}
-
-func (e *OpError) Temporary() bool {
- // Treat ECONNRESET and ECONNABORTED as temporary errors when
- // they come from calling accept. See issue 6163.
- if e.Op == "accept" && isConnError(e.Err) {
- return true
- }
-
- if ne, ok := e.Err.(*os.SyscallError); ok {
- t, ok := ne.Err.(temporary)
- return ok && t.Temporary()
- }
- t, ok := e.Err.(temporary)
- return ok && t.Temporary()
-}
-
-// A ParseError is the error type of literal network address parsers.
-type ParseError struct {
- // Type is the type of string that was expected, such as
- // "IP address", "CIDR address".
- Type string
-
- // Text is the malformed text string.
- Text string
-}
-
-func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
-
-func (e *ParseError) Timeout() bool { return false }
-func (e *ParseError) Temporary() bool { return false }
-
-type AddrError struct {
- Err string
- Addr string
-}
-
-func (e *AddrError) Error() string {
- if e == nil {
- return "<nil>"
- }
- s := e.Err
- if e.Addr != "" {
- s = "address " + e.Addr + ": " + s
- }
- return s
-}
-
-func (e *AddrError) Timeout() bool { return false }
-func (e *AddrError) Temporary() bool { return false }
-
-type UnknownNetworkError string
-
-func (e UnknownNetworkError) Error() string { return "unknown network " + string(e) }
-func (e UnknownNetworkError) Timeout() bool { return false }
-func (e UnknownNetworkError) Temporary() bool { return false }
-
-type InvalidAddrError string
-
-func (e InvalidAddrError) Error() string { return string(e) }
-func (e InvalidAddrError) Timeout() bool { return false }
-func (e InvalidAddrError) Temporary() bool { return false }
-
-// errTimeout exists to return the historical "i/o timeout" string
-// for context.DeadlineExceeded. See mapErr.
-// It is also used when Dialer.Deadline is exceeded.
-// error.Is(errTimeout, context.DeadlineExceeded) returns true.
-//
-// TODO(iant): We could consider changing this to os.ErrDeadlineExceeded
-// in the future, if we make
-//
-// errors.Is(os.ErrDeadlineExceeded, context.DeadlineExceeded)
-//
-// return true.
-var errTimeout error = &timeoutError{}
-
-type timeoutError struct{}
-
-func (e *timeoutError) Error() string { return "i/o timeout" }
-func (e *timeoutError) Timeout() bool { return true }
-func (e *timeoutError) Temporary() bool { return true }
-
-func (e *timeoutError) Is(err error) bool {
- return err == context.DeadlineExceeded
-}
-
-// DNSConfigError represents an error reading the machine's DNS configuration.
-// (No longer used; kept for compatibility.)
-type DNSConfigError struct {
- Err error
-}
-
-func (e *DNSConfigError) Unwrap() error { return e.Err }
-func (e *DNSConfigError) Error() string { return "error reading DNS config: " + e.Err.Error() }
-func (e *DNSConfigError) Timeout() bool { return false }
-func (e *DNSConfigError) Temporary() bool { return false }
-
-// Various errors contained in DNSError.
-var (
- errNoSuchHost = errors.New("no such host")
-)
-
-// DNSError represents a DNS lookup error.
-type DNSError struct {
- Err string // description of the error
- Name string // name looked for
- Server string // server used
- IsTimeout bool // if true, timed out; not all timeouts set this
- IsTemporary bool // if true, error is temporary; not all errors set this
- IsNotFound bool // if true, host could not be found
-}
-
-func (e *DNSError) Error() string {
- if e == nil {
- return "<nil>"
- }
- s := "lookup " + e.Name
- if e.Server != "" {
- s += " on " + e.Server
- }
- s += ": " + e.Err
- return s
-}
-
-// Timeout reports whether the DNS lookup is known to have timed out.
-// This is not always known; a DNS lookup may fail due to a timeout
-// and return a DNSError for which Timeout returns false.
-func (e *DNSError) Timeout() bool { return e.IsTimeout }
-
-// Temporary reports whether the DNS error is known to be temporary.
-// This is not always known; a DNS lookup may fail due to a temporary
-// error and return a DNSError for which Temporary returns false.
-func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
-
-// errClosed exists just so that the docs for ErrClosed don't mention
-// the internal package poll.
-var errClosed = poll.ErrNetClosing
-
-// ErrClosed is the error returned by an I/O call on a network
-// connection that has already been closed, or that is closed by
-// another goroutine before the I/O is completed. This may be wrapped
-// in another error, and should normally be tested using
-// errors.Is(err, net.ErrClosed).
-var ErrClosed error = errClosed
-
-type writerOnly struct {
- io.Writer
-}
-
-// Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
-// applicable.
-func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
- // Use wrapper to hide existing r.ReadFrom from io.Copy.
- return io.Copy(writerOnly{w}, r)
-}
-
-// Limit the number of concurrent cgo-using goroutines, because
-// each will block an entire operating system thread. The usual culprit
-// is resolving many DNS names in separate goroutines but the DNS
-// server is not responding. Then the many lookups each use a different
-// thread, and the system or the program runs out of threads.
-
-var threadLimit chan struct{}
-
-var threadOnce sync.Once
-
-func acquireThread() {
- threadOnce.Do(func() {
- threadLimit = make(chan struct{}, concurrentThreadsLimit())
- })
- threadLimit <- struct{}{}
-}
-
-func releaseThread() {
- <-threadLimit
-}
-
-// buffersWriter is the interface implemented by Conns that support a
-// "writev"-like batch write optimization.
-// writeBuffers should fully consume and write all chunks from the
-// provided Buffers, else it should report a non-nil error.
-type buffersWriter interface {
- writeBuffers(*Buffers) (int64, error)
-}
-
-// Buffers contains zero or more runs of bytes to write.
-//
-// On certain machines, for certain types of connections, this is
-// optimized into an OS-specific batch write operation (such as
-// "writev").
-type Buffers [][]byte
-
-var (
- _ io.WriterTo = (*Buffers)(nil)
- _ io.Reader = (*Buffers)(nil)
-)
-
-// WriteTo writes contents of the buffers to w.
-//
-// WriteTo implements io.WriterTo for Buffers.
-//
-// WriteTo modifies the slice v as well as v[i] for 0 <= i < len(v),
-// but does not modify v[i][j] for any i, j.
-func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) {
- if wv, ok := w.(buffersWriter); ok {
- return wv.writeBuffers(v)
- }
- for _, b := range *v {
- nb, err := w.Write(b)
- n += int64(nb)
- if err != nil {
- v.consume(n)
- return n, err
- }
- }
- v.consume(n)
- return n, nil
-}
-
-// Read from the buffers.
-//
-// Read implements io.Reader for Buffers.
-//
-// Read modifies the slice v as well as v[i] for 0 <= i < len(v),
-// but does not modify v[i][j] for any i, j.
-func (v *Buffers) Read(p []byte) (n int, err error) {
- for len(p) > 0 && len(*v) > 0 {
- n0 := copy(p, (*v)[0])
- v.consume(int64(n0))
- p = p[n0:]
- n += n0
- }
- if len(*v) == 0 {
- err = io.EOF
- }
- return
-}
-
-func (v *Buffers) consume(n int64) {
- for len(*v) > 0 {
- ln0 := int64(len((*v)[0]))
- if ln0 > n {
- (*v)[0] = (*v)[0][n:]
- return
- }
- n -= ln0
- (*v)[0] = nil
- *v = (*v)[1:]
- }
-}
diff --git a/contrib/go/_std_1.20/src/net/netip/netip.go b/contrib/go/_std_1.20/src/net/netip/netip.go
deleted file mode 100644
index 5d3050b281..0000000000
--- a/contrib/go/_std_1.20/src/net/netip/netip.go
+++ /dev/null
@@ -1,1493 +0,0 @@
-// 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 netip defines an IP address type that's a small value type.
-// Building on that Addr type, the package also defines AddrPort (an
-// IP address and a port), and Prefix (an IP address and a bit length
-// prefix).
-//
-// Compared to the net.IP type, this package's Addr type takes less
-// memory, is immutable, and is comparable (supports == and being a
-// map key).
-package netip
-
-import (
- "errors"
- "internal/bytealg"
- "internal/intern"
- "internal/itoa"
- "math"
- "strconv"
-)
-
-// Sizes: (64-bit)
-// net.IP: 24 byte slice header + {4, 16} = 28 to 40 bytes
-// net.IPAddr: 40 byte slice header + {4, 16} = 44 to 56 bytes + zone length
-// netip.Addr: 24 bytes (zone is per-name singleton, shared across all users)
-
-// Addr represents an IPv4 or IPv6 address (with or without a scoped
-// addressing zone), similar to net.IP or net.IPAddr.
-//
-// Unlike net.IP or net.IPAddr, Addr is a comparable value
-// type (it supports == and can be a map key) and is immutable.
-//
-// The zero Addr is not a valid IP address.
-// Addr{} is distinct from both 0.0.0.0 and ::.
-type Addr struct {
- // addr is the hi and lo bits of an IPv6 address. If z==z4,
- // hi and lo contain the IPv4-mapped IPv6 address.
- //
- // hi and lo are constructed by interpreting a 16-byte IPv6
- // address as a big-endian 128-bit number. The most significant
- // bits of that number go into hi, the rest into lo.
- //
- // For example, 0011:2233:4455:6677:8899:aabb:ccdd:eeff is stored as:
- // addr.hi = 0x0011223344556677
- // addr.lo = 0x8899aabbccddeeff
- //
- // We store IPs like this, rather than as [16]byte, because it
- // turns most operations on IPs into arithmetic and bit-twiddling
- // operations on 64-bit registers, which is much faster than
- // bytewise processing.
- addr uint128
-
- // z is a combination of the address family and the IPv6 zone.
- //
- // nil means invalid IP address (for a zero Addr).
- // z4 means an IPv4 address.
- // z6noz means an IPv6 address without a zone.
- //
- // Otherwise it's the interned zone name string.
- z *intern.Value
-}
-
-// z0, z4, and z6noz are sentinel Addr.z values.
-// See the Addr type's field docs.
-var (
- z0 = (*intern.Value)(nil)
- z4 = new(intern.Value)
- z6noz = new(intern.Value)
-)
-
-// IPv6LinkLocalAllNodes returns the IPv6 link-local all nodes multicast
-// address ff02::1.
-func IPv6LinkLocalAllNodes() Addr { return AddrFrom16([16]byte{0: 0xff, 1: 0x02, 15: 0x01}) }
-
-// IPv6LinkLocalAllRouters returns the IPv6 link-local all routers multicast
-// address ff02::2.
-func IPv6LinkLocalAllRouters() Addr { return AddrFrom16([16]byte{0: 0xff, 1: 0x02, 15: 0x02}) }
-
-// IPv6Loopback returns the IPv6 loopback address ::1.
-func IPv6Loopback() Addr { return AddrFrom16([16]byte{15: 0x01}) }
-
-// IPv6Unspecified returns the IPv6 unspecified address "::".
-func IPv6Unspecified() Addr { return Addr{z: z6noz} }
-
-// IPv4Unspecified returns the IPv4 unspecified address "0.0.0.0".
-func IPv4Unspecified() Addr { return AddrFrom4([4]byte{}) }
-
-// AddrFrom4 returns the address of the IPv4 address given by the bytes in addr.
-func AddrFrom4(addr [4]byte) Addr {
- return Addr{
- addr: uint128{0, 0xffff00000000 | uint64(addr[0])<<24 | uint64(addr[1])<<16 | uint64(addr[2])<<8 | uint64(addr[3])},
- z: z4,
- }
-}
-
-// AddrFrom16 returns the IPv6 address given by the bytes in addr.
-// An IPv4-mapped IPv6 address is left as an IPv6 address.
-// (Use Unmap to convert them if needed.)
-func AddrFrom16(addr [16]byte) Addr {
- return Addr{
- addr: uint128{
- beUint64(addr[:8]),
- beUint64(addr[8:]),
- },
- z: z6noz,
- }
-}
-
-// ParseAddr parses s as an IP address, returning the result. The string
-// s can be in dotted decimal ("192.0.2.1"), IPv6 ("2001:db8::68"),
-// or IPv6 with a scoped addressing zone ("fe80::1cc0:3e8c:119f:c2e1%ens18").
-func ParseAddr(s string) (Addr, error) {
- for i := 0; i < len(s); i++ {
- switch s[i] {
- case '.':
- return parseIPv4(s)
- case ':':
- return parseIPv6(s)
- case '%':
- // Assume that this was trying to be an IPv6 address with
- // a zone specifier, but the address is missing.
- return Addr{}, parseAddrError{in: s, msg: "missing IPv6 address"}
- }
- }
- return Addr{}, parseAddrError{in: s, msg: "unable to parse IP"}
-}
-
-// MustParseAddr calls ParseAddr(s) and panics on error.
-// It is intended for use in tests with hard-coded strings.
-func MustParseAddr(s string) Addr {
- ip, err := ParseAddr(s)
- if err != nil {
- panic(err)
- }
- return ip
-}
-
-type parseAddrError struct {
- in string // the string given to ParseAddr
- msg string // an explanation of the parse failure
- at string // optionally, the unparsed portion of in at which the error occurred.
-}
-
-func (err parseAddrError) Error() string {
- q := strconv.Quote
- if err.at != "" {
- return "ParseAddr(" + q(err.in) + "): " + err.msg + " (at " + q(err.at) + ")"
- }
- return "ParseAddr(" + q(err.in) + "): " + err.msg
-}
-
-// parseIPv4 parses s as an IPv4 address (in form "192.168.0.1").
-func parseIPv4(s string) (ip Addr, err error) {
- var fields [4]uint8
- var val, pos int
- var digLen int // number of digits in current octet
- for i := 0; i < len(s); i++ {
- if s[i] >= '0' && s[i] <= '9' {
- if digLen == 1 && val == 0 {
- return Addr{}, parseAddrError{in: s, msg: "IPv4 field has octet with leading zero"}
- }
- val = val*10 + int(s[i]) - '0'
- digLen++
- if val > 255 {
- return Addr{}, parseAddrError{in: s, msg: "IPv4 field has value >255"}
- }
- } else if s[i] == '.' {
- // .1.2.3
- // 1.2.3.
- // 1..2.3
- if i == 0 || i == len(s)-1 || s[i-1] == '.' {
- return Addr{}, parseAddrError{in: s, msg: "IPv4 field must have at least one digit", at: s[i:]}
- }
- // 1.2.3.4.5
- if pos == 3 {
- return Addr{}, parseAddrError{in: s, msg: "IPv4 address too long"}
- }
- fields[pos] = uint8(val)
- pos++
- val = 0
- digLen = 0
- } else {
- return Addr{}, parseAddrError{in: s, msg: "unexpected character", at: s[i:]}
- }
- }
- if pos < 3 {
- return Addr{}, parseAddrError{in: s, msg: "IPv4 address too short"}
- }
- fields[3] = uint8(val)
- return AddrFrom4(fields), nil
-}
-
-// parseIPv6 parses s as an IPv6 address (in form "2001:db8::68").
-func parseIPv6(in string) (Addr, error) {
- s := in
-
- // Split off the zone right from the start. Yes it's a second scan
- // of the string, but trying to handle it inline makes a bunch of
- // other inner loop conditionals more expensive, and it ends up
- // being slower.
- zone := ""
- i := bytealg.IndexByteString(s, '%')
- if i != -1 {
- s, zone = s[:i], s[i+1:]
- if zone == "" {
- // Not allowed to have an empty zone if explicitly specified.
- return Addr{}, parseAddrError{in: in, msg: "zone must be a non-empty string"}
- }
- }
-
- var ip [16]byte
- ellipsis := -1 // position of ellipsis in ip
-
- // Might have leading ellipsis
- if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
- ellipsis = 0
- s = s[2:]
- // Might be only ellipsis
- if len(s) == 0 {
- return IPv6Unspecified().WithZone(zone), nil
- }
- }
-
- // Loop, parsing hex numbers followed by colon.
- i = 0
- for i < 16 {
- // Hex number. Similar to parseIPv4, inlining the hex number
- // parsing yields a significant performance increase.
- off := 0
- acc := uint32(0)
- for ; off < len(s); off++ {
- c := s[off]
- if c >= '0' && c <= '9' {
- acc = (acc << 4) + uint32(c-'0')
- } else if c >= 'a' && c <= 'f' {
- acc = (acc << 4) + uint32(c-'a'+10)
- } else if c >= 'A' && c <= 'F' {
- acc = (acc << 4) + uint32(c-'A'+10)
- } else {
- break
- }
- if acc > math.MaxUint16 {
- // Overflow, fail.
- return Addr{}, parseAddrError{in: in, msg: "IPv6 field has value >=2^16", at: s}
- }
- }
- if off == 0 {
- // No digits found, fail.
- return Addr{}, parseAddrError{in: in, msg: "each colon-separated field must have at least one digit", at: s}
- }
-
- // If followed by dot, might be in trailing IPv4.
- if off < len(s) && s[off] == '.' {
- if ellipsis < 0 && i != 12 {
- // Not the right place.
- return Addr{}, parseAddrError{in: in, msg: "embedded IPv4 address must replace the final 2 fields of the address", at: s}
- }
- if i+4 > 16 {
- // Not enough room.
- return Addr{}, parseAddrError{in: in, msg: "too many hex fields to fit an embedded IPv4 at the end of the address", at: s}
- }
- // TODO: could make this a bit faster by having a helper
- // that parses to a [4]byte, and have both parseIPv4 and
- // parseIPv6 use it.
- ip4, err := parseIPv4(s)
- if err != nil {
- return Addr{}, parseAddrError{in: in, msg: err.Error(), at: s}
- }
- ip[i] = ip4.v4(0)
- ip[i+1] = ip4.v4(1)
- ip[i+2] = ip4.v4(2)
- ip[i+3] = ip4.v4(3)
- s = ""
- i += 4
- break
- }
-
- // Save this 16-bit chunk.
- ip[i] = byte(acc >> 8)
- ip[i+1] = byte(acc)
- i += 2
-
- // Stop at end of string.
- s = s[off:]
- if len(s) == 0 {
- break
- }
-
- // Otherwise must be followed by colon and more.
- if s[0] != ':' {
- return Addr{}, parseAddrError{in: in, msg: "unexpected character, want colon", at: s}
- } else if len(s) == 1 {
- return Addr{}, parseAddrError{in: in, msg: "colon must be followed by more characters", at: s}
- }
- s = s[1:]
-
- // Look for ellipsis.
- if s[0] == ':' {
- if ellipsis >= 0 { // already have one
- return Addr{}, parseAddrError{in: in, msg: "multiple :: in address", at: s}
- }
- ellipsis = i
- s = s[1:]
- if len(s) == 0 { // can be at end
- break
- }
- }
- }
-
- // Must have used entire string.
- if len(s) != 0 {
- return Addr{}, parseAddrError{in: in, msg: "trailing garbage after address", at: s}
- }
-
- // If didn't parse enough, expand ellipsis.
- if i < 16 {
- if ellipsis < 0 {
- return Addr{}, parseAddrError{in: in, msg: "address string too short"}
- }
- n := 16 - i
- for j := i - 1; j >= ellipsis; j-- {
- ip[j+n] = ip[j]
- }
- for j := ellipsis + n - 1; j >= ellipsis; j-- {
- ip[j] = 0
- }
- } else if ellipsis >= 0 {
- // Ellipsis must represent at least one 0 group.
- return Addr{}, parseAddrError{in: in, msg: "the :: must expand to at least one field of zeros"}
- }
- return AddrFrom16(ip).WithZone(zone), nil
-}
-
-// AddrFromSlice parses the 4- or 16-byte byte slice as an IPv4 or IPv6 address.
-// Note that a net.IP can be passed directly as the []byte argument.
-// If slice's length is not 4 or 16, AddrFromSlice returns Addr{}, false.
-func AddrFromSlice(slice []byte) (ip Addr, ok bool) {
- switch len(slice) {
- case 4:
- return AddrFrom4([4]byte(slice)), true
- case 16:
- return AddrFrom16([16]byte(slice)), true
- }
- return Addr{}, false
-}
-
-// v4 returns the i'th byte of ip. If ip is not an IPv4, v4 returns
-// unspecified garbage.
-func (ip Addr) v4(i uint8) uint8 {
- return uint8(ip.addr.lo >> ((3 - i) * 8))
-}
-
-// v6 returns the i'th byte of ip. If ip is an IPv4 address, this
-// accesses the IPv4-mapped IPv6 address form of the IP.
-func (ip Addr) v6(i uint8) uint8 {
- return uint8(*(ip.addr.halves()[(i/8)%2]) >> ((7 - i%8) * 8))
-}
-
-// v6u16 returns the i'th 16-bit word of ip. If ip is an IPv4 address,
-// this accesses the IPv4-mapped IPv6 address form of the IP.
-func (ip Addr) v6u16(i uint8) uint16 {
- return uint16(*(ip.addr.halves()[(i/4)%2]) >> ((3 - i%4) * 16))
-}
-
-// isZero reports whether ip is the zero value of the IP type.
-// The zero value is not a valid IP address of any type.
-//
-// Note that "0.0.0.0" and "::" are not the zero value. Use IsUnspecified to
-// check for these values instead.
-func (ip Addr) isZero() bool {
- // Faster than comparing ip == Addr{}, but effectively equivalent,
- // as there's no way to make an IP with a nil z from this package.
- return ip.z == z0
-}
-
-// IsValid reports whether the Addr is an initialized address (not the zero Addr).
-//
-// Note that "0.0.0.0" and "::" are both valid values.
-func (ip Addr) IsValid() bool { return ip.z != z0 }
-
-// BitLen returns the number of bits in the IP address:
-// 128 for IPv6, 32 for IPv4, and 0 for the zero Addr.
-//
-// Note that IPv4-mapped IPv6 addresses are considered IPv6 addresses
-// and therefore have bit length 128.
-func (ip Addr) BitLen() int {
- switch ip.z {
- case z0:
- return 0
- case z4:
- return 32
- }
- return 128
-}
-
-// Zone returns ip's IPv6 scoped addressing zone, if any.
-func (ip Addr) Zone() string {
- if ip.z == nil {
- return ""
- }
- zone, _ := ip.z.Get().(string)
- return zone
-}
-
-// Compare returns an integer comparing two IPs.
-// The result will be 0 if ip == ip2, -1 if ip < ip2, and +1 if ip > ip2.
-// The definition of "less than" is the same as the Less method.
-func (ip Addr) Compare(ip2 Addr) int {
- f1, f2 := ip.BitLen(), ip2.BitLen()
- if f1 < f2 {
- return -1
- }
- if f1 > f2 {
- return 1
- }
- hi1, hi2 := ip.addr.hi, ip2.addr.hi
- if hi1 < hi2 {
- return -1
- }
- if hi1 > hi2 {
- return 1
- }
- lo1, lo2 := ip.addr.lo, ip2.addr.lo
- if lo1 < lo2 {
- return -1
- }
- if lo1 > lo2 {
- return 1
- }
- if ip.Is6() {
- za, zb := ip.Zone(), ip2.Zone()
- if za < zb {
- return -1
- }
- if za > zb {
- return 1
- }
- }
- return 0
-}
-
-// Less reports whether ip sorts before ip2.
-// IP addresses sort first by length, then their address.
-// IPv6 addresses with zones sort just after the same address without a zone.
-func (ip Addr) Less(ip2 Addr) bool { return ip.Compare(ip2) == -1 }
-
-// Is4 reports whether ip is an IPv4 address.
-//
-// It returns false for IPv4-mapped IPv6 addresses. See Addr.Unmap.
-func (ip Addr) Is4() bool {
- return ip.z == z4
-}
-
-// Is4In6 reports whether ip is an IPv4-mapped IPv6 address.
-func (ip Addr) Is4In6() bool {
- return ip.Is6() && ip.addr.hi == 0 && ip.addr.lo>>32 == 0xffff
-}
-
-// Is6 reports whether ip is an IPv6 address, including IPv4-mapped
-// IPv6 addresses.
-func (ip Addr) Is6() bool {
- return ip.z != z0 && ip.z != z4
-}
-
-// Unmap returns ip with any IPv4-mapped IPv6 address prefix removed.
-//
-// That is, if ip is an IPv6 address wrapping an IPv4 address, it
-// returns the wrapped IPv4 address. Otherwise it returns ip unmodified.
-func (ip Addr) Unmap() Addr {
- if ip.Is4In6() {
- ip.z = z4
- }
- return ip
-}
-
-// WithZone returns an IP that's the same as ip but with the provided
-// zone. If zone is empty, the zone is removed. If ip is an IPv4
-// address, WithZone is a no-op and returns ip unchanged.
-func (ip Addr) WithZone(zone string) Addr {
- if !ip.Is6() {
- return ip
- }
- if zone == "" {
- ip.z = z6noz
- return ip
- }
- ip.z = intern.GetByString(zone)
- return ip
-}
-
-// withoutZone unconditionally strips the zone from ip.
-// It's similar to WithZone, but small enough to be inlinable.
-func (ip Addr) withoutZone() Addr {
- if !ip.Is6() {
- return ip
- }
- ip.z = z6noz
- return ip
-}
-
-// hasZone reports whether ip has an IPv6 zone.
-func (ip Addr) hasZone() bool {
- return ip.z != z0 && ip.z != z4 && ip.z != z6noz
-}
-
-// IsLinkLocalUnicast reports whether ip is a link-local unicast address.
-func (ip Addr) IsLinkLocalUnicast() bool {
- // Dynamic Configuration of IPv4 Link-Local Addresses
- // https://datatracker.ietf.org/doc/html/rfc3927#section-2.1
- if ip.Is4() {
- return ip.v4(0) == 169 && ip.v4(1) == 254
- }
- // IP Version 6 Addressing Architecture (2.4 Address Type Identification)
- // https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
- if ip.Is6() {
- return ip.v6u16(0)&0xffc0 == 0xfe80
- }
- return false // zero value
-}
-
-// IsLoopback reports whether ip is a loopback address.
-func (ip Addr) IsLoopback() bool {
- // Requirements for Internet Hosts -- Communication Layers (3.2.1.3 Addressing)
- // https://datatracker.ietf.org/doc/html/rfc1122#section-3.2.1.3
- if ip.Is4() {
- return ip.v4(0) == 127
- }
- // IP Version 6 Addressing Architecture (2.4 Address Type Identification)
- // https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
- if ip.Is6() {
- return ip.addr.hi == 0 && ip.addr.lo == 1
- }
- return false // zero value
-}
-
-// IsMulticast reports whether ip is a multicast address.
-func (ip Addr) IsMulticast() bool {
- // Host Extensions for IP Multicasting (4. HOST GROUP ADDRESSES)
- // https://datatracker.ietf.org/doc/html/rfc1112#section-4
- if ip.Is4() {
- return ip.v4(0)&0xf0 == 0xe0
- }
- // IP Version 6 Addressing Architecture (2.4 Address Type Identification)
- // https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
- if ip.Is6() {
- return ip.addr.hi>>(64-8) == 0xff // ip.v6(0) == 0xff
- }
- return false // zero value
-}
-
-// IsInterfaceLocalMulticast reports whether ip is an IPv6 interface-local
-// multicast address.
-func (ip Addr) IsInterfaceLocalMulticast() bool {
- // IPv6 Addressing Architecture (2.7.1. Pre-Defined Multicast Addresses)
- // https://datatracker.ietf.org/doc/html/rfc4291#section-2.7.1
- if ip.Is6() {
- return ip.v6u16(0)&0xff0f == 0xff01
- }
- return false // zero value
-}
-
-// IsLinkLocalMulticast reports whether ip is a link-local multicast address.
-func (ip Addr) IsLinkLocalMulticast() bool {
- // IPv4 Multicast Guidelines (4. Local Network Control Block (224.0.0/24))
- // https://datatracker.ietf.org/doc/html/rfc5771#section-4
- if ip.Is4() {
- return ip.v4(0) == 224 && ip.v4(1) == 0 && ip.v4(2) == 0
- }
- // IPv6 Addressing Architecture (2.7.1. Pre-Defined Multicast Addresses)
- // https://datatracker.ietf.org/doc/html/rfc4291#section-2.7.1
- if ip.Is6() {
- return ip.v6u16(0)&0xff0f == 0xff02
- }
- return false // zero value
-}
-
-// IsGlobalUnicast reports whether ip is a global unicast address.
-//
-// It returns true for IPv6 addresses which fall outside of the current
-// IANA-allocated 2000::/3 global unicast space, with the exception of the
-// link-local address space. It also returns true even if ip is in the IPv4
-// private address space or IPv6 unique local address space.
-// It returns false for the zero Addr.
-//
-// For reference, see RFC 1122, RFC 4291, and RFC 4632.
-func (ip Addr) IsGlobalUnicast() bool {
- if ip.z == z0 {
- // Invalid or zero-value.
- return false
- }
-
- // Match package net's IsGlobalUnicast logic. Notably private IPv4 addresses
- // and ULA IPv6 addresses are still considered "global unicast".
- if ip.Is4() && (ip == IPv4Unspecified() || ip == AddrFrom4([4]byte{255, 255, 255, 255})) {
- return false
- }
-
- return ip != IPv6Unspecified() &&
- !ip.IsLoopback() &&
- !ip.IsMulticast() &&
- !ip.IsLinkLocalUnicast()
-}
-
-// IsPrivate reports whether ip is a private address, according to RFC 1918
-// (IPv4 addresses) and RFC 4193 (IPv6 addresses). That is, it reports whether
-// ip is in 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, or fc00::/7. This is the
-// same as net.IP.IsPrivate.
-func (ip Addr) IsPrivate() bool {
- // Match the stdlib's IsPrivate logic.
- if ip.Is4() {
- // RFC 1918 allocates 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16 as
- // private IPv4 address subnets.
- return ip.v4(0) == 10 ||
- (ip.v4(0) == 172 && ip.v4(1)&0xf0 == 16) ||
- (ip.v4(0) == 192 && ip.v4(1) == 168)
- }
-
- if ip.Is6() {
- // RFC 4193 allocates fc00::/7 as the unique local unicast IPv6 address
- // subnet.
- return ip.v6(0)&0xfe == 0xfc
- }
-
- return false // zero value
-}
-
-// IsUnspecified reports whether ip is an unspecified address, either the IPv4
-// address "0.0.0.0" or the IPv6 address "::".
-//
-// Note that the zero Addr is not an unspecified address.
-func (ip Addr) IsUnspecified() bool {
- return ip == IPv4Unspecified() || ip == IPv6Unspecified()
-}
-
-// Prefix keeps only the top b bits of IP, producing a Prefix
-// of the specified length.
-// If ip is a zero Addr, Prefix always returns a zero Prefix and a nil error.
-// Otherwise, if bits is less than zero or greater than ip.BitLen(),
-// Prefix returns an error.
-func (ip Addr) Prefix(b int) (Prefix, error) {
- if b < 0 {
- return Prefix{}, errors.New("negative Prefix bits")
- }
- effectiveBits := b
- switch ip.z {
- case z0:
- return Prefix{}, nil
- case z4:
- if b > 32 {
- return Prefix{}, errors.New("prefix length " + itoa.Itoa(b) + " too large for IPv4")
- }
- effectiveBits += 96
- default:
- if b > 128 {
- return Prefix{}, errors.New("prefix length " + itoa.Itoa(b) + " too large for IPv6")
- }
- }
- ip.addr = ip.addr.and(mask6(effectiveBits))
- return PrefixFrom(ip, b), nil
-}
-
-const (
- netIPv4len = 4
- netIPv6len = 16
-)
-
-// As16 returns the IP address in its 16-byte representation.
-// IPv4 addresses are returned as IPv4-mapped IPv6 addresses.
-// IPv6 addresses with zones are returned without their zone (use the
-// Zone method to get it).
-// The ip zero value returns all zeroes.
-func (ip Addr) As16() (a16 [16]byte) {
- bePutUint64(a16[:8], ip.addr.hi)
- bePutUint64(a16[8:], ip.addr.lo)
- return a16
-}
-
-// As4 returns an IPv4 or IPv4-in-IPv6 address in its 4-byte representation.
-// If ip is the zero Addr or an IPv6 address, As4 panics.
-// Note that 0.0.0.0 is not the zero Addr.
-func (ip Addr) As4() (a4 [4]byte) {
- if ip.z == z4 || ip.Is4In6() {
- bePutUint32(a4[:], uint32(ip.addr.lo))
- return a4
- }
- if ip.z == z0 {
- panic("As4 called on IP zero value")
- }
- panic("As4 called on IPv6 address")
-}
-
-// AsSlice returns an IPv4 or IPv6 address in its respective 4-byte or 16-byte representation.
-func (ip Addr) AsSlice() []byte {
- switch ip.z {
- case z0:
- return nil
- case z4:
- var ret [4]byte
- bePutUint32(ret[:], uint32(ip.addr.lo))
- return ret[:]
- default:
- var ret [16]byte
- bePutUint64(ret[:8], ip.addr.hi)
- bePutUint64(ret[8:], ip.addr.lo)
- return ret[:]
- }
-}
-
-// Next returns the address following ip.
-// If there is none, it returns the zero Addr.
-func (ip Addr) Next() Addr {
- ip.addr = ip.addr.addOne()
- if ip.Is4() {
- if uint32(ip.addr.lo) == 0 {
- // Overflowed.
- return Addr{}
- }
- } else {
- if ip.addr.isZero() {
- // Overflowed
- return Addr{}
- }
- }
- return ip
-}
-
-// Prev returns the IP before ip.
-// If there is none, it returns the IP zero value.
-func (ip Addr) Prev() Addr {
- if ip.Is4() {
- if uint32(ip.addr.lo) == 0 {
- return Addr{}
- }
- } else if ip.addr.isZero() {
- return Addr{}
- }
- ip.addr = ip.addr.subOne()
- return ip
-}
-
-// String returns the string form of the IP address ip.
-// It returns one of 5 forms:
-//
-// - "invalid IP", if ip is the zero Addr
-// - IPv4 dotted decimal ("192.0.2.1")
-// - IPv6 ("2001:db8::1")
-// - "::ffff:1.2.3.4" (if Is4In6)
-// - IPv6 with zone ("fe80:db8::1%eth0")
-//
-// Note that unlike package net's IP.String method,
-// IPv4-mapped IPv6 addresses format with a "::ffff:"
-// prefix before the dotted quad.
-func (ip Addr) String() string {
- switch ip.z {
- case z0:
- return "invalid IP"
- case z4:
- return ip.string4()
- default:
- if ip.Is4In6() {
- if z := ip.Zone(); z != "" {
- return "::ffff:" + ip.Unmap().string4() + "%" + z
- } else {
- return "::ffff:" + ip.Unmap().string4()
- }
- }
- return ip.string6()
- }
-}
-
-// AppendTo appends a text encoding of ip,
-// as generated by MarshalText,
-// to b and returns the extended buffer.
-func (ip Addr) AppendTo(b []byte) []byte {
- switch ip.z {
- case z0:
- return b
- case z4:
- return ip.appendTo4(b)
- default:
- if ip.Is4In6() {
- b = append(b, "::ffff:"...)
- b = ip.Unmap().appendTo4(b)
- if z := ip.Zone(); z != "" {
- b = append(b, '%')
- b = append(b, z...)
- }
- return b
- }
- return ip.appendTo6(b)
- }
-}
-
-// digits is a string of the hex digits from 0 to f. It's used in
-// appendDecimal and appendHex to format IP addresses.
-const digits = "0123456789abcdef"
-
-// appendDecimal appends the decimal string representation of x to b.
-func appendDecimal(b []byte, x uint8) []byte {
- // Using this function rather than strconv.AppendUint makes IPv4
- // string building 2x faster.
-
- if x >= 100 {
- b = append(b, digits[x/100])
- }
- if x >= 10 {
- b = append(b, digits[x/10%10])
- }
- return append(b, digits[x%10])
-}
-
-// appendHex appends the hex string representation of x to b.
-func appendHex(b []byte, x uint16) []byte {
- // Using this function rather than strconv.AppendUint makes IPv6
- // string building 2x faster.
-
- if x >= 0x1000 {
- b = append(b, digits[x>>12])
- }
- if x >= 0x100 {
- b = append(b, digits[x>>8&0xf])
- }
- if x >= 0x10 {
- b = append(b, digits[x>>4&0xf])
- }
- return append(b, digits[x&0xf])
-}
-
-// appendHexPad appends the fully padded hex string representation of x to b.
-func appendHexPad(b []byte, x uint16) []byte {
- return append(b, digits[x>>12], digits[x>>8&0xf], digits[x>>4&0xf], digits[x&0xf])
-}
-
-func (ip Addr) string4() string {
- const max = len("255.255.255.255")
- ret := make([]byte, 0, max)
- ret = ip.appendTo4(ret)
- return string(ret)
-}
-
-func (ip Addr) appendTo4(ret []byte) []byte {
- ret = appendDecimal(ret, ip.v4(0))
- ret = append(ret, '.')
- ret = appendDecimal(ret, ip.v4(1))
- ret = append(ret, '.')
- ret = appendDecimal(ret, ip.v4(2))
- ret = append(ret, '.')
- ret = appendDecimal(ret, ip.v4(3))
- return ret
-}
-
-// string6 formats ip in IPv6 textual representation. It follows the
-// guidelines in section 4 of RFC 5952
-// (https://tools.ietf.org/html/rfc5952#section-4): no unnecessary
-// zeros, use :: to elide the longest run of zeros, and don't use ::
-// to compact a single zero field.
-func (ip Addr) string6() string {
- // Use a zone with a "plausibly long" name, so that most zone-ful
- // IP addresses won't require additional allocation.
- //
- // The compiler does a cool optimization here, where ret ends up
- // stack-allocated and so the only allocation this function does
- // is to construct the returned string. As such, it's okay to be a
- // bit greedy here, size-wise.
- const max = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0")
- ret := make([]byte, 0, max)
- ret = ip.appendTo6(ret)
- return string(ret)
-}
-
-func (ip Addr) appendTo6(ret []byte) []byte {
- zeroStart, zeroEnd := uint8(255), uint8(255)
- for i := uint8(0); i < 8; i++ {
- j := i
- for j < 8 && ip.v6u16(j) == 0 {
- j++
- }
- if l := j - i; l >= 2 && l > zeroEnd-zeroStart {
- zeroStart, zeroEnd = i, j
- }
- }
-
- for i := uint8(0); i < 8; i++ {
- if i == zeroStart {
- ret = append(ret, ':', ':')
- i = zeroEnd
- if i >= 8 {
- break
- }
- } else if i > 0 {
- ret = append(ret, ':')
- }
-
- ret = appendHex(ret, ip.v6u16(i))
- }
-
- if ip.z != z6noz {
- ret = append(ret, '%')
- ret = append(ret, ip.Zone()...)
- }
- return ret
-}
-
-// StringExpanded is like String but IPv6 addresses are expanded with leading
-// zeroes and no "::" compression. For example, "2001:db8::1" becomes
-// "2001:0db8:0000:0000:0000:0000:0000:0001".
-func (ip Addr) StringExpanded() string {
- switch ip.z {
- case z0, z4:
- return ip.String()
- }
-
- const size = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
- ret := make([]byte, 0, size)
- for i := uint8(0); i < 8; i++ {
- if i > 0 {
- ret = append(ret, ':')
- }
-
- ret = appendHexPad(ret, ip.v6u16(i))
- }
-
- if ip.z != z6noz {
- // The addition of a zone will cause a second allocation, but when there
- // is no zone the ret slice will be stack allocated.
- ret = append(ret, '%')
- ret = append(ret, ip.Zone()...)
- }
- return string(ret)
-}
-
-// MarshalText implements the encoding.TextMarshaler interface,
-// The encoding is the same as returned by String, with one exception:
-// If ip is the zero Addr, the encoding is the empty string.
-func (ip Addr) MarshalText() ([]byte, error) {
- switch ip.z {
- case z0:
- return []byte(""), nil
- case z4:
- max := len("255.255.255.255")
- b := make([]byte, 0, max)
- return ip.appendTo4(b), nil
- default:
- max := len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0")
- b := make([]byte, 0, max)
- if ip.Is4In6() {
- b = append(b, "::ffff:"...)
- b = ip.Unmap().appendTo4(b)
- if z := ip.Zone(); z != "" {
- b = append(b, '%')
- b = append(b, z...)
- }
- return b, nil
- }
- return ip.appendTo6(b), nil
- }
-
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler interface.
-// The IP address is expected in a form accepted by ParseAddr.
-//
-// If text is empty, UnmarshalText sets *ip to the zero Addr and
-// returns no error.
-func (ip *Addr) UnmarshalText(text []byte) error {
- if len(text) == 0 {
- *ip = Addr{}
- return nil
- }
- var err error
- *ip, err = ParseAddr(string(text))
- return err
-}
-
-func (ip Addr) marshalBinaryWithTrailingBytes(trailingBytes int) []byte {
- var b []byte
- switch ip.z {
- case z0:
- b = make([]byte, trailingBytes)
- case z4:
- b = make([]byte, 4+trailingBytes)
- bePutUint32(b, uint32(ip.addr.lo))
- default:
- z := ip.Zone()
- b = make([]byte, 16+len(z)+trailingBytes)
- bePutUint64(b[:8], ip.addr.hi)
- bePutUint64(b[8:], ip.addr.lo)
- copy(b[16:], z)
- }
- return b
-}
-
-// MarshalBinary implements the encoding.BinaryMarshaler interface.
-// It returns a zero-length slice for the zero Addr,
-// the 4-byte form for an IPv4 address,
-// and the 16-byte form with zone appended for an IPv6 address.
-func (ip Addr) MarshalBinary() ([]byte, error) {
- return ip.marshalBinaryWithTrailingBytes(0), nil
-}
-
-// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
-// It expects data in the form generated by MarshalBinary.
-func (ip *Addr) UnmarshalBinary(b []byte) error {
- n := len(b)
- switch {
- case n == 0:
- *ip = Addr{}
- return nil
- case n == 4:
- *ip = AddrFrom4([4]byte(b))
- return nil
- case n == 16:
- *ip = AddrFrom16([16]byte(b))
- return nil
- case n > 16:
- *ip = AddrFrom16([16]byte(b[:16])).WithZone(string(b[16:]))
- return nil
- }
- return errors.New("unexpected slice size")
-}
-
-// AddrPort is an IP and a port number.
-type AddrPort struct {
- ip Addr
- port uint16
-}
-
-// AddrPortFrom returns an AddrPort with the provided IP and port.
-// It does not allocate.
-func AddrPortFrom(ip Addr, port uint16) AddrPort { return AddrPort{ip: ip, port: port} }
-
-// Addr returns p's IP address.
-func (p AddrPort) Addr() Addr { return p.ip }
-
-// Port returns p's port.
-func (p AddrPort) Port() uint16 { return p.port }
-
-// splitAddrPort splits s into an IP address string and a port
-// string. It splits strings shaped like "foo:bar" or "[foo]:bar",
-// without further validating the substrings. v6 indicates whether the
-// ip string should parse as an IPv6 address or an IPv4 address, in
-// order for s to be a valid ip:port string.
-func splitAddrPort(s string) (ip, port string, v6 bool, err error) {
- i := stringsLastIndexByte(s, ':')
- if i == -1 {
- return "", "", false, errors.New("not an ip:port")
- }
-
- ip, port = s[:i], s[i+1:]
- if len(ip) == 0 {
- return "", "", false, errors.New("no IP")
- }
- if len(port) == 0 {
- return "", "", false, errors.New("no port")
- }
- if ip[0] == '[' {
- if len(ip) < 2 || ip[len(ip)-1] != ']' {
- return "", "", false, errors.New("missing ]")
- }
- ip = ip[1 : len(ip)-1]
- v6 = true
- }
-
- return ip, port, v6, nil
-}
-
-// ParseAddrPort parses s as an AddrPort.
-//
-// It doesn't do any name resolution: both the address and the port
-// must be numeric.
-func ParseAddrPort(s string) (AddrPort, error) {
- var ipp AddrPort
- ip, port, v6, err := splitAddrPort(s)
- if err != nil {
- return ipp, err
- }
- port16, err := strconv.ParseUint(port, 10, 16)
- if err != nil {
- return ipp, errors.New("invalid port " + strconv.Quote(port) + " parsing " + strconv.Quote(s))
- }
- ipp.port = uint16(port16)
- ipp.ip, err = ParseAddr(ip)
- if err != nil {
- return AddrPort{}, err
- }
- if v6 && ipp.ip.Is4() {
- return AddrPort{}, errors.New("invalid ip:port " + strconv.Quote(s) + ", square brackets can only be used with IPv6 addresses")
- } else if !v6 && ipp.ip.Is6() {
- return AddrPort{}, errors.New("invalid ip:port " + strconv.Quote(s) + ", IPv6 addresses must be surrounded by square brackets")
- }
- return ipp, nil
-}
-
-// MustParseAddrPort calls ParseAddrPort(s) and panics on error.
-// It is intended for use in tests with hard-coded strings.
-func MustParseAddrPort(s string) AddrPort {
- ip, err := ParseAddrPort(s)
- if err != nil {
- panic(err)
- }
- return ip
-}
-
-// IsValid reports whether p.Addr() is valid.
-// All ports are valid, including zero.
-func (p AddrPort) IsValid() bool { return p.ip.IsValid() }
-
-func (p AddrPort) String() string {
- switch p.ip.z {
- case z0:
- return "invalid AddrPort"
- case z4:
- a := p.ip.As4()
- buf := make([]byte, 0, 21)
- for i := range a {
- buf = strconv.AppendUint(buf, uint64(a[i]), 10)
- buf = append(buf, "...:"[i])
- }
- buf = strconv.AppendUint(buf, uint64(p.port), 10)
- return string(buf)
- default:
- // TODO: this could be more efficient allocation-wise:
- return joinHostPort(p.ip.String(), itoa.Itoa(int(p.port)))
- }
-}
-
-func joinHostPort(host, port string) string {
- // We assume that host is a literal IPv6 address if host has
- // colons.
- if bytealg.IndexByteString(host, ':') >= 0 {
- return "[" + host + "]:" + port
- }
- return host + ":" + port
-}
-
-// AppendTo appends a text encoding of p,
-// as generated by MarshalText,
-// to b and returns the extended buffer.
-func (p AddrPort) AppendTo(b []byte) []byte {
- switch p.ip.z {
- case z0:
- return b
- case z4:
- b = p.ip.appendTo4(b)
- default:
- if p.ip.Is4In6() {
- b = append(b, "[::ffff:"...)
- b = p.ip.Unmap().appendTo4(b)
- if z := p.ip.Zone(); z != "" {
- b = append(b, '%')
- b = append(b, z...)
- }
- } else {
- b = append(b, '[')
- b = p.ip.appendTo6(b)
- }
- b = append(b, ']')
- }
- b = append(b, ':')
- b = strconv.AppendUint(b, uint64(p.port), 10)
- return b
-}
-
-// MarshalText implements the encoding.TextMarshaler interface. The
-// encoding is the same as returned by String, with one exception: if
-// p.Addr() is the zero Addr, the encoding is the empty string.
-func (p AddrPort) MarshalText() ([]byte, error) {
- var max int
- switch p.ip.z {
- case z0:
- case z4:
- max = len("255.255.255.255:65535")
- default:
- max = len("[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0]:65535")
- }
- b := make([]byte, 0, max)
- b = p.AppendTo(b)
- return b, nil
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler
-// interface. The AddrPort is expected in a form
-// generated by MarshalText or accepted by ParseAddrPort.
-func (p *AddrPort) UnmarshalText(text []byte) error {
- if len(text) == 0 {
- *p = AddrPort{}
- return nil
- }
- var err error
- *p, err = ParseAddrPort(string(text))
- return err
-}
-
-// MarshalBinary implements the encoding.BinaryMarshaler interface.
-// It returns Addr.MarshalBinary with an additional two bytes appended
-// containing the port in little-endian.
-func (p AddrPort) MarshalBinary() ([]byte, error) {
- b := p.Addr().marshalBinaryWithTrailingBytes(2)
- lePutUint16(b[len(b)-2:], p.Port())
- return b, nil
-}
-
-// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
-// It expects data in the form generated by MarshalBinary.
-func (p *AddrPort) UnmarshalBinary(b []byte) error {
- if len(b) < 2 {
- return errors.New("unexpected slice size")
- }
- var addr Addr
- err := addr.UnmarshalBinary(b[:len(b)-2])
- if err != nil {
- return err
- }
- *p = AddrPortFrom(addr, leUint16(b[len(b)-2:]))
- return nil
-}
-
-// Prefix is an IP address prefix (CIDR) representing an IP network.
-//
-// The first Bits() of Addr() are specified. The remaining bits match any address.
-// The range of Bits() is [0,32] for IPv4 or [0,128] for IPv6.
-type Prefix struct {
- ip Addr
-
- // bits is logically a uint8 (storing [0,128]) but also
- // encodes an "invalid" bit, currently represented by the
- // invalidPrefixBits sentinel value. It could be packed into
- // the uint8 more with more complicated expressions in the
- // accessors, but the extra byte (in padding anyway) doesn't
- // hurt and simplifies code below.
- bits int16
-}
-
-// invalidPrefixBits is the Prefix.bits value used when PrefixFrom is
-// outside the range of a uint8. It's returned as the int -1 in the
-// public API.
-const invalidPrefixBits = -1
-
-// PrefixFrom returns a Prefix with the provided IP address and bit
-// prefix length.
-//
-// It does not allocate. Unlike Addr.Prefix, PrefixFrom does not mask
-// off the host bits of ip.
-//
-// If bits is less than zero or greater than ip.BitLen, Prefix.Bits
-// will return an invalid value -1.
-func PrefixFrom(ip Addr, bits int) Prefix {
- if bits < 0 || bits > ip.BitLen() {
- bits = invalidPrefixBits
- }
- b16 := int16(bits)
- return Prefix{
- ip: ip.withoutZone(),
- bits: b16,
- }
-}
-
-// Addr returns p's IP address.
-func (p Prefix) Addr() Addr { return p.ip }
-
-// Bits returns p's prefix length.
-//
-// It reports -1 if invalid.
-func (p Prefix) Bits() int { return int(p.bits) }
-
-// IsValid reports whether p.Bits() has a valid range for p.Addr().
-// If p.Addr() is the zero Addr, IsValid returns false.
-// Note that if p is the zero Prefix, then p.IsValid() == false.
-func (p Prefix) IsValid() bool { return !p.ip.isZero() && p.bits >= 0 && int(p.bits) <= p.ip.BitLen() }
-
-func (p Prefix) isZero() bool { return p == Prefix{} }
-
-// IsSingleIP reports whether p contains exactly one IP.
-func (p Prefix) IsSingleIP() bool { return p.bits != 0 && int(p.bits) == p.ip.BitLen() }
-
-// ParsePrefix parses s as an IP address prefix.
-// The string can be in the form "192.168.1.0/24" or "2001:db8::/32",
-// the CIDR notation defined in RFC 4632 and RFC 4291.
-// IPv6 zones are not permitted in prefixes, and an error will be returned if a
-// zone is present.
-//
-// Note that masked address bits are not zeroed. Use Masked for that.
-func ParsePrefix(s string) (Prefix, error) {
- i := stringsLastIndexByte(s, '/')
- if i < 0 {
- return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): no '/'")
- }
- ip, err := ParseAddr(s[:i])
- if err != nil {
- return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): " + err.Error())
- }
- // IPv6 zones are not allowed: https://go.dev/issue/51899
- if ip.Is6() && ip.z != z6noz {
- return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): IPv6 zones cannot be present in a prefix")
- }
-
- bitsStr := s[i+1:]
- bits, err := strconv.Atoi(bitsStr)
- if err != nil {
- return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): bad bits after slash: " + strconv.Quote(bitsStr))
- }
- maxBits := 32
- if ip.Is6() {
- maxBits = 128
- }
- if bits < 0 || bits > maxBits {
- return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): prefix length out of range")
- }
- return PrefixFrom(ip, bits), nil
-}
-
-// MustParsePrefix calls ParsePrefix(s) and panics on error.
-// It is intended for use in tests with hard-coded strings.
-func MustParsePrefix(s string) Prefix {
- ip, err := ParsePrefix(s)
- if err != nil {
- panic(err)
- }
- return ip
-}
-
-// Masked returns p in its canonical form, with all but the high
-// p.Bits() bits of p.Addr() masked off.
-//
-// If p is zero or otherwise invalid, Masked returns the zero Prefix.
-func (p Prefix) Masked() Prefix {
- if m, err := p.ip.Prefix(int(p.bits)); err == nil {
- return m
- }
- return Prefix{}
-}
-
-// Contains reports whether the network p includes ip.
-//
-// An IPv4 address will not match an IPv6 prefix.
-// An IPv4-mapped IPv6 address will not match an IPv4 prefix.
-// A zero-value IP will not match any prefix.
-// If ip has an IPv6 zone, Contains returns false,
-// because Prefixes strip zones.
-func (p Prefix) Contains(ip Addr) bool {
- if !p.IsValid() || ip.hasZone() {
- return false
- }
- if f1, f2 := p.ip.BitLen(), ip.BitLen(); f1 == 0 || f2 == 0 || f1 != f2 {
- return false
- }
- if ip.Is4() {
- // xor the IP addresses together; mismatched bits are now ones.
- // Shift away the number of bits we don't care about.
- // Shifts in Go are more efficient if the compiler can prove
- // that the shift amount is smaller than the width of the shifted type (64 here).
- // We know that p.bits is in the range 0..32 because p is Valid;
- // the compiler doesn't know that, so mask with 63 to help it.
- // Now truncate to 32 bits, because this is IPv4.
- // If all the bits we care about are equal, the result will be zero.
- return uint32((ip.addr.lo^p.ip.addr.lo)>>((32-p.bits)&63)) == 0
- } else {
- // xor the IP addresses together.
- // Mask away the bits we don't care about.
- // If all the bits we care about are equal, the result will be zero.
- return ip.addr.xor(p.ip.addr).and(mask6(int(p.bits))).isZero()
- }
-}
-
-// Overlaps reports whether p and o contain any IP addresses in common.
-//
-// If p and o are of different address families or either have a zero
-// IP, it reports false. Like the Contains method, a prefix with an
-// IPv4-mapped IPv6 address is still treated as an IPv6 mask.
-func (p Prefix) Overlaps(o Prefix) bool {
- if !p.IsValid() || !o.IsValid() {
- return false
- }
- if p == o {
- return true
- }
- if p.ip.Is4() != o.ip.Is4() {
- return false
- }
- var minBits int16
- if p.bits < o.bits {
- minBits = p.bits
- } else {
- minBits = o.bits
- }
- if minBits == 0 {
- return true
- }
- // One of these Prefix calls might look redundant, but we don't require
- // that p and o values are normalized (via Prefix.Masked) first,
- // so the Prefix call on the one that's already minBits serves to zero
- // out any remaining bits in IP.
- var err error
- if p, err = p.ip.Prefix(int(minBits)); err != nil {
- return false
- }
- if o, err = o.ip.Prefix(int(minBits)); err != nil {
- return false
- }
- return p.ip == o.ip
-}
-
-// AppendTo appends a text encoding of p,
-// as generated by MarshalText,
-// to b and returns the extended buffer.
-func (p Prefix) AppendTo(b []byte) []byte {
- if p.isZero() {
- return b
- }
- if !p.IsValid() {
- return append(b, "invalid Prefix"...)
- }
-
- // p.ip is non-nil, because p is valid.
- if p.ip.z == z4 {
- b = p.ip.appendTo4(b)
- } else {
- if p.ip.Is4In6() {
- b = append(b, "::ffff:"...)
- b = p.ip.Unmap().appendTo4(b)
- } else {
- b = p.ip.appendTo6(b)
- }
- }
-
- b = append(b, '/')
- b = appendDecimal(b, uint8(p.bits))
- return b
-}
-
-// MarshalText implements the encoding.TextMarshaler interface,
-// The encoding is the same as returned by String, with one exception:
-// If p is the zero value, the encoding is the empty string.
-func (p Prefix) MarshalText() ([]byte, error) {
- var max int
- switch p.ip.z {
- case z0:
- case z4:
- max = len("255.255.255.255/32")
- default:
- max = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0/128")
- }
- b := make([]byte, 0, max)
- b = p.AppendTo(b)
- return b, nil
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler interface.
-// The IP address is expected in a form accepted by ParsePrefix
-// or generated by MarshalText.
-func (p *Prefix) UnmarshalText(text []byte) error {
- if len(text) == 0 {
- *p = Prefix{}
- return nil
- }
- var err error
- *p, err = ParsePrefix(string(text))
- return err
-}
-
-// MarshalBinary implements the encoding.BinaryMarshaler interface.
-// It returns Addr.MarshalBinary with an additional byte appended
-// containing the prefix bits.
-func (p Prefix) MarshalBinary() ([]byte, error) {
- b := p.Addr().withoutZone().marshalBinaryWithTrailingBytes(1)
- b[len(b)-1] = uint8(p.Bits())
- return b, nil
-}
-
-// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
-// It expects data in the form generated by MarshalBinary.
-func (p *Prefix) UnmarshalBinary(b []byte) error {
- if len(b) < 1 {
- return errors.New("unexpected slice size")
- }
- var addr Addr
- err := addr.UnmarshalBinary(b[:len(b)-1])
- if err != nil {
- return err
- }
- *p = PrefixFrom(addr, int(b[len(b)-1]))
- return nil
-}
-
-// String returns the CIDR notation of p: "<ip>/<bits>".
-func (p Prefix) String() string {
- if !p.IsValid() {
- return "invalid Prefix"
- }
- return p.ip.String() + "/" + itoa.Itoa(int(p.bits))
-}
diff --git a/contrib/go/_std_1.20/src/net/netip/ya.make b/contrib/go/_std_1.20/src/net/netip/ya.make
deleted file mode 100644
index a5e722347d..0000000000
--- a/contrib/go/_std_1.20/src/net/netip/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- leaf_alts.go
- netip.go
- uint128.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/port_unix.go b/contrib/go/_std_1.20/src/net/port_unix.go
deleted file mode 100644
index b05b588f17..0000000000
--- a/contrib/go/_std_1.20/src/net/port_unix.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix || (js && wasm)
-
-// Read system port mappings from /etc/services
-
-package net
-
-import (
- "internal/bytealg"
- "sync"
-)
-
-var onceReadServices sync.Once
-
-func readServices() {
- file, err := open("/etc/services")
- if err != nil {
- return
- }
- defer file.close()
-
- for line, ok := file.readLine(); ok; line, ok = file.readLine() {
- // "http 80/tcp www www-http # World Wide Web HTTP"
- if i := bytealg.IndexByteString(line, '#'); i >= 0 {
- line = line[:i]
- }
- f := getFields(line)
- if len(f) < 2 {
- continue
- }
- portnet := f[1] // "80/tcp"
- port, j, ok := dtoi(portnet)
- if !ok || port <= 0 || j >= len(portnet) || portnet[j] != '/' {
- continue
- }
- netw := portnet[j+1:] // "tcp"
- m, ok1 := services[netw]
- if !ok1 {
- m = make(map[string]int)
- services[netw] = m
- }
- for i := 0; i < len(f); i++ {
- if i != 1 { // f[1] was port/net
- m[f[i]] = port
- }
- }
- }
-}
-
-// goLookupPort is the native Go implementation of LookupPort.
-func goLookupPort(network, service string) (port int, err error) {
- onceReadServices.Do(readServices)
- return lookupPortMap(network, service)
-}
diff --git a/contrib/go/_std_1.20/src/net/rawconn.go b/contrib/go/_std_1.20/src/net/rawconn.go
deleted file mode 100644
index c786354582..0000000000
--- a/contrib/go/_std_1.20/src/net/rawconn.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2017 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 net
-
-import (
- "runtime"
- "syscall"
-)
-
-// BUG(tmm1): On Windows, the Write method of syscall.RawConn
-// does not integrate with the runtime's network poller. It cannot
-// wait for the connection to become writeable, and does not respect
-// deadlines. If the user-provided callback returns false, the Write
-// method will fail immediately.
-
-// BUG(mikio): On JS and Plan 9, the Control, Read and Write
-// methods of syscall.RawConn are not implemented.
-
-type rawConn struct {
- fd *netFD
-}
-
-func (c *rawConn) ok() bool { return c != nil && c.fd != nil }
-
-func (c *rawConn) Control(f func(uintptr)) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- err := c.fd.pfd.RawControl(f)
- runtime.KeepAlive(c.fd)
- if err != nil {
- err = &OpError{Op: "raw-control", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
- }
- return err
-}
-
-func (c *rawConn) Read(f func(uintptr) bool) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- err := c.fd.pfd.RawRead(f)
- runtime.KeepAlive(c.fd)
- if err != nil {
- err = &OpError{Op: "raw-read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return err
-}
-
-func (c *rawConn) Write(f func(uintptr) bool) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- err := c.fd.pfd.RawWrite(f)
- runtime.KeepAlive(c.fd)
- if err != nil {
- err = &OpError{Op: "raw-write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return err
-}
-
-func newRawConn(fd *netFD) (*rawConn, error) {
- return &rawConn{fd: fd}, nil
-}
-
-type rawListener struct {
- rawConn
-}
-
-func (l *rawListener) Read(func(uintptr) bool) error {
- return syscall.EINVAL
-}
-
-func (l *rawListener) Write(func(uintptr) bool) error {
- return syscall.EINVAL
-}
-
-func newRawListener(fd *netFD) (*rawListener, error) {
- return &rawListener{rawConn{fd: fd}}, nil
-}
diff --git a/contrib/go/_std_1.20/src/net/rpc/jsonrpc/ya.make b/contrib/go/_std_1.20/src/net/rpc/jsonrpc/ya.make
deleted file mode 100644
index 85e331ff3b..0000000000
--- a/contrib/go/_std_1.20/src/net/rpc/jsonrpc/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- client.go
- server.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/rpc/server.go b/contrib/go/_std_1.20/src/net/rpc/server.go
deleted file mode 100644
index 109ebba541..0000000000
--- a/contrib/go/_std_1.20/src/net/rpc/server.go
+++ /dev/null
@@ -1,725 +0,0 @@
-// Copyright 2009 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 rpc provides access to the exported methods of an object across a
-network or other I/O connection. A server registers an object, making it visible
-as a service with the name of the type of the object. After registration, exported
-methods of the object will be accessible remotely. A server may register multiple
-objects (services) of different types but it is an error to register multiple
-objects of the same type.
-
-Only methods that satisfy these criteria will be made available for remote access;
-other methods will be ignored:
-
- - the method's type is exported.
- - the method is exported.
- - the method has two arguments, both exported (or builtin) types.
- - the method's second argument is a pointer.
- - the method has return type error.
-
-In effect, the method must look schematically like
-
- func (t *T) MethodName(argType T1, replyType *T2) error
-
-where T1 and T2 can be marshaled by encoding/gob.
-These requirements apply even if a different codec is used.
-(In the future, these requirements may soften for custom codecs.)
-
-The method's first argument represents the arguments provided by the caller; the
-second argument represents the result parameters to be returned to the caller.
-The method's return value, if non-nil, is passed back as a string that the client
-sees as if created by errors.New. If an error is returned, the reply parameter
-will not be sent back to the client.
-
-The server may handle requests on a single connection by calling ServeConn. More
-typically it will create a network listener and call Accept or, for an HTTP
-listener, HandleHTTP and http.Serve.
-
-A client wishing to use the service establishes a connection and then invokes
-NewClient on the connection. The convenience function Dial (DialHTTP) performs
-both steps for a raw network connection (an HTTP connection). The resulting
-Client object has two methods, Call and Go, that specify the service and method to
-call, a pointer containing the arguments, and a pointer to receive the result
-parameters.
-
-The Call method waits for the remote call to complete while the Go method
-launches the call asynchronously and signals completion using the Call
-structure's Done channel.
-
-Unless an explicit codec is set up, package encoding/gob is used to
-transport the data.
-
-Here is a simple example. A server wishes to export an object of type Arith:
-
- package server
-
- import "errors"
-
- type Args struct {
- A, B int
- }
-
- type Quotient struct {
- Quo, Rem int
- }
-
- type Arith int
-
- func (t *Arith) Multiply(args *Args, reply *int) error {
- *reply = args.A * args.B
- return nil
- }
-
- func (t *Arith) Divide(args *Args, quo *Quotient) error {
- if args.B == 0 {
- return errors.New("divide by zero")
- }
- quo.Quo = args.A / args.B
- quo.Rem = args.A % args.B
- return nil
- }
-
-The server calls (for HTTP service):
-
- arith := new(Arith)
- rpc.Register(arith)
- rpc.HandleHTTP()
- l, e := net.Listen("tcp", ":1234")
- if e != nil {
- log.Fatal("listen error:", e)
- }
- go http.Serve(l, nil)
-
-At this point, clients can see a service "Arith" with methods "Arith.Multiply" and
-"Arith.Divide". To invoke one, a client first dials the server:
-
- client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
- if err != nil {
- log.Fatal("dialing:", err)
- }
-
-Then it can make a remote call:
-
- // Synchronous call
- args := &server.Args{7,8}
- var reply int
- err = client.Call("Arith.Multiply", args, &reply)
- if err != nil {
- log.Fatal("arith error:", err)
- }
- fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)
-
-or
-
- // Asynchronous call
- quotient := new(Quotient)
- divCall := client.Go("Arith.Divide", args, quotient, nil)
- replyCall := <-divCall.Done // will be equal to divCall
- // check errors, print, etc.
-
-A server implementation will often provide a simple, type-safe wrapper for the
-client.
-
-The net/rpc package is frozen and is not accepting new features.
-*/
-package rpc
-
-import (
- "bufio"
- "encoding/gob"
- "errors"
- "go/token"
- "io"
- "log"
- "net"
- "net/http"
- "reflect"
- "strings"
- "sync"
-)
-
-const (
- // Defaults used by HandleHTTP
- DefaultRPCPath = "/_goRPC_"
- DefaultDebugPath = "/debug/rpc"
-)
-
-// Precompute the reflect type for error. Can't use error directly
-// because Typeof takes an empty interface value. This is annoying.
-var typeOfError = reflect.TypeOf((*error)(nil)).Elem()
-
-type methodType struct {
- sync.Mutex // protects counters
- method reflect.Method
- ArgType reflect.Type
- ReplyType reflect.Type
- numCalls uint
-}
-
-type service struct {
- name string // name of service
- rcvr reflect.Value // receiver of methods for the service
- typ reflect.Type // type of the receiver
- method map[string]*methodType // registered methods
-}
-
-// Request is a header written before every RPC call. It is used internally
-// but documented here as an aid to debugging, such as when analyzing
-// network traffic.
-type Request struct {
- ServiceMethod string // format: "Service.Method"
- Seq uint64 // sequence number chosen by client
- next *Request // for free list in Server
-}
-
-// Response is a header written before every RPC return. It is used internally
-// but documented here as an aid to debugging, such as when analyzing
-// network traffic.
-type Response struct {
- ServiceMethod string // echoes that of the Request
- Seq uint64 // echoes that of the request
- Error string // error, if any.
- next *Response // for free list in Server
-}
-
-// Server represents an RPC Server.
-type Server struct {
- serviceMap sync.Map // map[string]*service
- reqLock sync.Mutex // protects freeReq
- freeReq *Request
- respLock sync.Mutex // protects freeResp
- freeResp *Response
-}
-
-// NewServer returns a new Server.
-func NewServer() *Server {
- return &Server{}
-}
-
-// DefaultServer is the default instance of *Server.
-var DefaultServer = NewServer()
-
-// Is this type exported or a builtin?
-func isExportedOrBuiltinType(t reflect.Type) bool {
- for t.Kind() == reflect.Pointer {
- t = t.Elem()
- }
- // PkgPath will be non-empty even for an exported type,
- // so we need to check the type name as well.
- return token.IsExported(t.Name()) || t.PkgPath() == ""
-}
-
-// Register publishes in the server the set of methods of the
-// receiver value that satisfy the following conditions:
-// - exported method of exported type
-// - two arguments, both of exported type
-// - the second argument is a pointer
-// - one return value, of type error
-//
-// It returns an error if the receiver is not an exported type or has
-// no suitable methods. It also logs the error using package log.
-// The client accesses each method using a string of the form "Type.Method",
-// where Type is the receiver's concrete type.
-func (server *Server) Register(rcvr any) error {
- return server.register(rcvr, "", false)
-}
-
-// RegisterName is like Register but uses the provided name for the type
-// instead of the receiver's concrete type.
-func (server *Server) RegisterName(name string, rcvr any) error {
- return server.register(rcvr, name, true)
-}
-
-// logRegisterError specifies whether to log problems during method registration.
-// To debug registration, recompile the package with this set to true.
-const logRegisterError = false
-
-func (server *Server) register(rcvr any, name string, useName bool) error {
- s := new(service)
- s.typ = reflect.TypeOf(rcvr)
- s.rcvr = reflect.ValueOf(rcvr)
- sname := name
- if !useName {
- sname = reflect.Indirect(s.rcvr).Type().Name()
- }
- if sname == "" {
- s := "rpc.Register: no service name for type " + s.typ.String()
- log.Print(s)
- return errors.New(s)
- }
- if !useName && !token.IsExported(sname) {
- s := "rpc.Register: type " + sname + " is not exported"
- log.Print(s)
- return errors.New(s)
- }
- s.name = sname
-
- // Install the methods
- s.method = suitableMethods(s.typ, logRegisterError)
-
- if len(s.method) == 0 {
- str := ""
-
- // To help the user, see if a pointer receiver would work.
- method := suitableMethods(reflect.PointerTo(s.typ), false)
- if len(method) != 0 {
- str = "rpc.Register: type " + sname + " has no exported methods of suitable type (hint: pass a pointer to value of that type)"
- } else {
- str = "rpc.Register: type " + sname + " has no exported methods of suitable type"
- }
- log.Print(str)
- return errors.New(str)
- }
-
- if _, dup := server.serviceMap.LoadOrStore(sname, s); dup {
- return errors.New("rpc: service already defined: " + sname)
- }
- return nil
-}
-
-// suitableMethods returns suitable Rpc methods of typ. It will log
-// errors if logErr is true.
-func suitableMethods(typ reflect.Type, logErr bool) map[string]*methodType {
- methods := make(map[string]*methodType)
- for m := 0; m < typ.NumMethod(); m++ {
- method := typ.Method(m)
- mtype := method.Type
- mname := method.Name
- // Method must be exported.
- if !method.IsExported() {
- continue
- }
- // Method needs three ins: receiver, *args, *reply.
- if mtype.NumIn() != 3 {
- if logErr {
- log.Printf("rpc.Register: method %q has %d input parameters; needs exactly three\n", mname, mtype.NumIn())
- }
- continue
- }
- // First arg need not be a pointer.
- argType := mtype.In(1)
- if !isExportedOrBuiltinType(argType) {
- if logErr {
- log.Printf("rpc.Register: argument type of method %q is not exported: %q\n", mname, argType)
- }
- continue
- }
- // Second arg must be a pointer.
- replyType := mtype.In(2)
- if replyType.Kind() != reflect.Pointer {
- if logErr {
- log.Printf("rpc.Register: reply type of method %q is not a pointer: %q\n", mname, replyType)
- }
- continue
- }
- // Reply type must be exported.
- if !isExportedOrBuiltinType(replyType) {
- if logErr {
- log.Printf("rpc.Register: reply type of method %q is not exported: %q\n", mname, replyType)
- }
- continue
- }
- // Method needs one out.
- if mtype.NumOut() != 1 {
- if logErr {
- log.Printf("rpc.Register: method %q has %d output parameters; needs exactly one\n", mname, mtype.NumOut())
- }
- continue
- }
- // The return type of the method must be error.
- if returnType := mtype.Out(0); returnType != typeOfError {
- if logErr {
- log.Printf("rpc.Register: return type of method %q is %q, must be error\n", mname, returnType)
- }
- continue
- }
- methods[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType}
- }
- return methods
-}
-
-// A value sent as a placeholder for the server's response value when the server
-// receives an invalid request. It is never decoded by the client since the Response
-// contains an error when it is used.
-var invalidRequest = struct{}{}
-
-func (server *Server) sendResponse(sending *sync.Mutex, req *Request, reply any, codec ServerCodec, errmsg string) {
- resp := server.getResponse()
- // Encode the response header
- resp.ServiceMethod = req.ServiceMethod
- if errmsg != "" {
- resp.Error = errmsg
- reply = invalidRequest
- }
- resp.Seq = req.Seq
- sending.Lock()
- err := codec.WriteResponse(resp, reply)
- if debugLog && err != nil {
- log.Println("rpc: writing response:", err)
- }
- sending.Unlock()
- server.freeResponse(resp)
-}
-
-func (m *methodType) NumCalls() (n uint) {
- m.Lock()
- n = m.numCalls
- m.Unlock()
- return n
-}
-
-func (s *service) call(server *Server, sending *sync.Mutex, wg *sync.WaitGroup, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) {
- if wg != nil {
- defer wg.Done()
- }
- mtype.Lock()
- mtype.numCalls++
- mtype.Unlock()
- function := mtype.method.Func
- // Invoke the method, providing a new value for the reply.
- returnValues := function.Call([]reflect.Value{s.rcvr, argv, replyv})
- // The return value for the method is an error.
- errInter := returnValues[0].Interface()
- errmsg := ""
- if errInter != nil {
- errmsg = errInter.(error).Error()
- }
- server.sendResponse(sending, req, replyv.Interface(), codec, errmsg)
- server.freeRequest(req)
-}
-
-type gobServerCodec struct {
- rwc io.ReadWriteCloser
- dec *gob.Decoder
- enc *gob.Encoder
- encBuf *bufio.Writer
- closed bool
-}
-
-func (c *gobServerCodec) ReadRequestHeader(r *Request) error {
- return c.dec.Decode(r)
-}
-
-func (c *gobServerCodec) ReadRequestBody(body any) error {
- return c.dec.Decode(body)
-}
-
-func (c *gobServerCodec) WriteResponse(r *Response, body any) (err error) {
- if err = c.enc.Encode(r); err != nil {
- if c.encBuf.Flush() == nil {
- // Gob couldn't encode the header. Should not happen, so if it does,
- // shut down the connection to signal that the connection is broken.
- log.Println("rpc: gob error encoding response:", err)
- c.Close()
- }
- return
- }
- if err = c.enc.Encode(body); err != nil {
- if c.encBuf.Flush() == nil {
- // Was a gob problem encoding the body but the header has been written.
- // Shut down the connection to signal that the connection is broken.
- log.Println("rpc: gob error encoding body:", err)
- c.Close()
- }
- return
- }
- return c.encBuf.Flush()
-}
-
-func (c *gobServerCodec) Close() error {
- if c.closed {
- // Only call c.rwc.Close once; otherwise the semantics are undefined.
- return nil
- }
- c.closed = true
- return c.rwc.Close()
-}
-
-// ServeConn runs the server on a single connection.
-// ServeConn blocks, serving the connection until the client hangs up.
-// The caller typically invokes ServeConn in a go statement.
-// ServeConn uses the gob wire format (see package gob) on the
-// connection. To use an alternate codec, use ServeCodec.
-// See NewClient's comment for information about concurrent access.
-func (server *Server) ServeConn(conn io.ReadWriteCloser) {
- buf := bufio.NewWriter(conn)
- srv := &gobServerCodec{
- rwc: conn,
- dec: gob.NewDecoder(conn),
- enc: gob.NewEncoder(buf),
- encBuf: buf,
- }
- server.ServeCodec(srv)
-}
-
-// ServeCodec is like ServeConn but uses the specified codec to
-// decode requests and encode responses.
-func (server *Server) ServeCodec(codec ServerCodec) {
- sending := new(sync.Mutex)
- wg := new(sync.WaitGroup)
- for {
- service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
- if err != nil {
- if debugLog && err != io.EOF {
- log.Println("rpc:", err)
- }
- if !keepReading {
- break
- }
- // send a response if we actually managed to read a header.
- if req != nil {
- server.sendResponse(sending, req, invalidRequest, codec, err.Error())
- server.freeRequest(req)
- }
- continue
- }
- wg.Add(1)
- go service.call(server, sending, wg, mtype, req, argv, replyv, codec)
- }
- // We've seen that there are no more requests.
- // Wait for responses to be sent before closing codec.
- wg.Wait()
- codec.Close()
-}
-
-// ServeRequest is like ServeCodec but synchronously serves a single request.
-// It does not close the codec upon completion.
-func (server *Server) ServeRequest(codec ServerCodec) error {
- sending := new(sync.Mutex)
- service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
- if err != nil {
- if !keepReading {
- return err
- }
- // send a response if we actually managed to read a header.
- if req != nil {
- server.sendResponse(sending, req, invalidRequest, codec, err.Error())
- server.freeRequest(req)
- }
- return err
- }
- service.call(server, sending, nil, mtype, req, argv, replyv, codec)
- return nil
-}
-
-func (server *Server) getRequest() *Request {
- server.reqLock.Lock()
- req := server.freeReq
- if req == nil {
- req = new(Request)
- } else {
- server.freeReq = req.next
- *req = Request{}
- }
- server.reqLock.Unlock()
- return req
-}
-
-func (server *Server) freeRequest(req *Request) {
- server.reqLock.Lock()
- req.next = server.freeReq
- server.freeReq = req
- server.reqLock.Unlock()
-}
-
-func (server *Server) getResponse() *Response {
- server.respLock.Lock()
- resp := server.freeResp
- if resp == nil {
- resp = new(Response)
- } else {
- server.freeResp = resp.next
- *resp = Response{}
- }
- server.respLock.Unlock()
- return resp
-}
-
-func (server *Server) freeResponse(resp *Response) {
- server.respLock.Lock()
- resp.next = server.freeResp
- server.freeResp = resp
- server.respLock.Unlock()
-}
-
-func (server *Server) readRequest(codec ServerCodec) (service *service, mtype *methodType, req *Request, argv, replyv reflect.Value, keepReading bool, err error) {
- service, mtype, req, keepReading, err = server.readRequestHeader(codec)
- if err != nil {
- if !keepReading {
- return
- }
- // discard body
- codec.ReadRequestBody(nil)
- return
- }
-
- // Decode the argument value.
- argIsValue := false // if true, need to indirect before calling.
- if mtype.ArgType.Kind() == reflect.Pointer {
- argv = reflect.New(mtype.ArgType.Elem())
- } else {
- argv = reflect.New(mtype.ArgType)
- argIsValue = true
- }
- // argv guaranteed to be a pointer now.
- if err = codec.ReadRequestBody(argv.Interface()); err != nil {
- return
- }
- if argIsValue {
- argv = argv.Elem()
- }
-
- replyv = reflect.New(mtype.ReplyType.Elem())
-
- switch mtype.ReplyType.Elem().Kind() {
- case reflect.Map:
- replyv.Elem().Set(reflect.MakeMap(mtype.ReplyType.Elem()))
- case reflect.Slice:
- replyv.Elem().Set(reflect.MakeSlice(mtype.ReplyType.Elem(), 0, 0))
- }
- return
-}
-
-func (server *Server) readRequestHeader(codec ServerCodec) (svc *service, mtype *methodType, req *Request, keepReading bool, err error) {
- // Grab the request header.
- req = server.getRequest()
- err = codec.ReadRequestHeader(req)
- if err != nil {
- req = nil
- if err == io.EOF || err == io.ErrUnexpectedEOF {
- return
- }
- err = errors.New("rpc: server cannot decode request: " + err.Error())
- return
- }
-
- // We read the header successfully. If we see an error now,
- // we can still recover and move on to the next request.
- keepReading = true
-
- dot := strings.LastIndex(req.ServiceMethod, ".")
- if dot < 0 {
- err = errors.New("rpc: service/method request ill-formed: " + req.ServiceMethod)
- return
- }
- serviceName := req.ServiceMethod[:dot]
- methodName := req.ServiceMethod[dot+1:]
-
- // Look up the request.
- svci, ok := server.serviceMap.Load(serviceName)
- if !ok {
- err = errors.New("rpc: can't find service " + req.ServiceMethod)
- return
- }
- svc = svci.(*service)
- mtype = svc.method[methodName]
- if mtype == nil {
- err = errors.New("rpc: can't find method " + req.ServiceMethod)
- }
- return
-}
-
-// Accept accepts connections on the listener and serves requests
-// for each incoming connection. Accept blocks until the listener
-// returns a non-nil error. The caller typically invokes Accept in a
-// go statement.
-func (server *Server) Accept(lis net.Listener) {
- for {
- conn, err := lis.Accept()
- if err != nil {
- log.Print("rpc.Serve: accept:", err.Error())
- return
- }
- go server.ServeConn(conn)
- }
-}
-
-// Register publishes the receiver's methods in the DefaultServer.
-func Register(rcvr any) error { return DefaultServer.Register(rcvr) }
-
-// RegisterName is like Register but uses the provided name for the type
-// instead of the receiver's concrete type.
-func RegisterName(name string, rcvr any) error {
- return DefaultServer.RegisterName(name, rcvr)
-}
-
-// A ServerCodec implements reading of RPC requests and writing of
-// RPC responses for the server side of an RPC session.
-// The server calls ReadRequestHeader and ReadRequestBody in pairs
-// to read requests from the connection, and it calls WriteResponse to
-// write a response back. The server calls Close when finished with the
-// connection. ReadRequestBody may be called with a nil
-// argument to force the body of the request to be read and discarded.
-// See NewClient's comment for information about concurrent access.
-type ServerCodec interface {
- ReadRequestHeader(*Request) error
- ReadRequestBody(any) error
- WriteResponse(*Response, any) error
-
- // Close can be called multiple times and must be idempotent.
- Close() error
-}
-
-// ServeConn runs the DefaultServer on a single connection.
-// ServeConn blocks, serving the connection until the client hangs up.
-// The caller typically invokes ServeConn in a go statement.
-// ServeConn uses the gob wire format (see package gob) on the
-// connection. To use an alternate codec, use ServeCodec.
-// See NewClient's comment for information about concurrent access.
-func ServeConn(conn io.ReadWriteCloser) {
- DefaultServer.ServeConn(conn)
-}
-
-// ServeCodec is like ServeConn but uses the specified codec to
-// decode requests and encode responses.
-func ServeCodec(codec ServerCodec) {
- DefaultServer.ServeCodec(codec)
-}
-
-// ServeRequest is like ServeCodec but synchronously serves a single request.
-// It does not close the codec upon completion.
-func ServeRequest(codec ServerCodec) error {
- return DefaultServer.ServeRequest(codec)
-}
-
-// Accept accepts connections on the listener and serves requests
-// to DefaultServer for each incoming connection.
-// Accept blocks; the caller typically invokes it in a go statement.
-func Accept(lis net.Listener) { DefaultServer.Accept(lis) }
-
-// Can connect to RPC service using HTTP CONNECT to rpcPath.
-var connected = "200 Connected to Go RPC"
-
-// ServeHTTP implements an http.Handler that answers RPC requests.
-func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
- if req.Method != "CONNECT" {
- w.Header().Set("Content-Type", "text/plain; charset=utf-8")
- w.WriteHeader(http.StatusMethodNotAllowed)
- io.WriteString(w, "405 must CONNECT\n")
- return
- }
- conn, _, err := w.(http.Hijacker).Hijack()
- if err != nil {
- log.Print("rpc hijacking ", req.RemoteAddr, ": ", err.Error())
- return
- }
- io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n")
- server.ServeConn(conn)
-}
-
-// HandleHTTP registers an HTTP handler for RPC messages on rpcPath,
-// and a debugging handler on debugPath.
-// It is still necessary to invoke http.Serve(), typically in a go statement.
-func (server *Server) HandleHTTP(rpcPath, debugPath string) {
- http.Handle(rpcPath, server)
- http.Handle(debugPath, debugHTTP{server})
-}
-
-// HandleHTTP registers an HTTP handler for RPC messages to DefaultServer
-// on DefaultRPCPath and a debugging handler on DefaultDebugPath.
-// It is still necessary to invoke http.Serve(), typically in a go statement.
-func HandleHTTP() {
- DefaultServer.HandleHTTP(DefaultRPCPath, DefaultDebugPath)
-}
diff --git a/contrib/go/_std_1.20/src/net/rpc/ya.make b/contrib/go/_std_1.20/src/net/rpc/ya.make
deleted file mode 100644
index cec204b41f..0000000000
--- a/contrib/go/_std_1.20/src/net/rpc/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- client.go
- debug.go
- server.go
-)
-
-END()
-
-RECURSE(
- jsonrpc
-)
diff --git a/contrib/go/_std_1.20/src/net/sendfile_linux.go b/contrib/go/_std_1.20/src/net/sendfile_linux.go
deleted file mode 100644
index 0299fdc3b5..0000000000
--- a/contrib/go/_std_1.20/src/net/sendfile_linux.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2011 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 net
-
-import (
- "internal/poll"
- "io"
- "os"
-)
-
-// sendFile copies the contents of r to c using the sendfile
-// system call to minimize copies.
-//
-// if handled == true, sendFile returns the number (potentially zero) of bytes
-// copied and any non-EOF error.
-//
-// if handled == false, sendFile performed no work.
-func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
- var remain int64 = 1 << 62 // by default, copy until EOF
-
- lr, ok := r.(*io.LimitedReader)
- if ok {
- remain, r = lr.N, lr.R
- if remain <= 0 {
- return 0, nil, true
- }
- }
- f, ok := r.(*os.File)
- if !ok {
- return 0, nil, false
- }
-
- sc, err := f.SyscallConn()
- if err != nil {
- return 0, nil, false
- }
-
- var werr error
- err = sc.Read(func(fd uintptr) bool {
- written, werr, handled = poll.SendFile(&c.pfd, int(fd), remain)
- return true
- })
- if err == nil {
- err = werr
- }
-
- if lr != nil {
- lr.N = remain - written
- }
- return written, wrapSyscallError("sendfile", err), handled
-}
diff --git a/contrib/go/_std_1.20/src/net/smtp/ya.make b/contrib/go/_std_1.20/src/net/smtp/ya.make
deleted file mode 100644
index 695be0b175..0000000000
--- a/contrib/go/_std_1.20/src/net/smtp/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- auth.go
- smtp.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/sock_cloexec.go b/contrib/go/_std_1.20/src/net/sock_cloexec.go
deleted file mode 100644
index 3f1cc9827a..0000000000
--- a/contrib/go/_std_1.20/src/net/sock_cloexec.go
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2013 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.
-
-// This file implements sysSocket for platforms that provide a fast path for
-// setting SetNonblock and CloseOnExec.
-
-//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris
-
-package net
-
-import (
- "os"
- "syscall"
-)
-
-// Wrapper around the socket system call that marks the returned file
-// descriptor as nonblocking and close-on-exec.
-func sysSocket(family, sotype, proto int) (int, error) {
- s, err := socketFunc(family, sotype|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, proto)
- if err != nil {
- return -1, os.NewSyscallError("socket", err)
- }
- return s, nil
-}
diff --git a/contrib/go/_std_1.20/src/net/sockaddr_posix.go b/contrib/go/_std_1.20/src/net/sockaddr_posix.go
deleted file mode 100644
index 76c3233b29..0000000000
--- a/contrib/go/_std_1.20/src/net/sockaddr_posix.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 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.
-
-//go:build unix || (js && wasm) || windows
-
-package net
-
-import (
- "syscall"
-)
-
-// A sockaddr represents a TCP, UDP, IP or Unix network endpoint
-// address that can be converted into a syscall.Sockaddr.
-type sockaddr interface {
- Addr
-
- // family returns the platform-dependent address family
- // identifier.
- family() int
-
- // isWildcard reports whether the address is a wildcard
- // address.
- isWildcard() bool
-
- // sockaddr returns the address converted into a syscall
- // sockaddr type that implements syscall.Sockaddr
- // interface. It returns a nil interface when the address is
- // nil.
- sockaddr(family int) (syscall.Sockaddr, error)
-
- // toLocal maps the zero address to a local system address (127.0.0.1 or ::1)
- toLocal(net string) sockaddr
-}
diff --git a/contrib/go/_std_1.20/src/net/splice_linux.go b/contrib/go/_std_1.20/src/net/splice_linux.go
deleted file mode 100644
index 69c3f65770..0000000000
--- a/contrib/go/_std_1.20/src/net/splice_linux.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2018 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 net
-
-import (
- "internal/poll"
- "io"
-)
-
-// splice transfers data from r to c using the splice system call to minimize
-// copies from and to userspace. c must be a TCP connection. Currently, splice
-// is only enabled if r is a TCP or a stream-oriented Unix connection.
-//
-// If splice returns handled == false, it has performed no work.
-func splice(c *netFD, r io.Reader) (written int64, err error, handled bool) {
- var remain int64 = 1 << 62 // by default, copy until EOF
- lr, ok := r.(*io.LimitedReader)
- if ok {
- remain, r = lr.N, lr.R
- if remain <= 0 {
- return 0, nil, true
- }
- }
-
- var s *netFD
- if tc, ok := r.(*TCPConn); ok {
- s = tc.fd
- } else if uc, ok := r.(*UnixConn); ok {
- if uc.fd.net != "unix" {
- return 0, nil, false
- }
- s = uc.fd
- } else {
- return 0, nil, false
- }
-
- written, handled, sc, err := poll.Splice(&c.pfd, &s.pfd, remain)
- if lr != nil {
- lr.N -= written
- }
- return written, wrapSyscallError(sc, err), handled
-}
diff --git a/contrib/go/_std_1.20/src/net/tcpsock.go b/contrib/go/_std_1.20/src/net/tcpsock.go
deleted file mode 100644
index 672170e681..0000000000
--- a/contrib/go/_std_1.20/src/net/tcpsock.go
+++ /dev/null
@@ -1,380 +0,0 @@
-// Copyright 2009 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 net
-
-import (
- "context"
- "internal/itoa"
- "io"
- "net/netip"
- "os"
- "syscall"
- "time"
-)
-
-// BUG(mikio): On JS and Windows, the File method of TCPConn and
-// TCPListener is not implemented.
-
-// TCPAddr represents the address of a TCP end point.
-type TCPAddr struct {
- IP IP
- Port int
- Zone string // IPv6 scoped addressing zone
-}
-
-// AddrPort returns the TCPAddr a as a netip.AddrPort.
-//
-// If a.Port does not fit in a uint16, it's silently truncated.
-//
-// If a is nil, a zero value is returned.
-func (a *TCPAddr) AddrPort() netip.AddrPort {
- if a == nil {
- return netip.AddrPort{}
- }
- na, _ := netip.AddrFromSlice(a.IP)
- na = na.WithZone(a.Zone)
- return netip.AddrPortFrom(na, uint16(a.Port))
-}
-
-// Network returns the address's network name, "tcp".
-func (a *TCPAddr) Network() string { return "tcp" }
-
-func (a *TCPAddr) String() string {
- if a == nil {
- return "<nil>"
- }
- ip := ipEmptyString(a.IP)
- if a.Zone != "" {
- return JoinHostPort(ip+"%"+a.Zone, itoa.Itoa(a.Port))
- }
- return JoinHostPort(ip, itoa.Itoa(a.Port))
-}
-
-func (a *TCPAddr) isWildcard() bool {
- if a == nil || a.IP == nil {
- return true
- }
- return a.IP.IsUnspecified()
-}
-
-func (a *TCPAddr) opAddr() Addr {
- if a == nil {
- return nil
- }
- return a
-}
-
-// ResolveTCPAddr returns an address of TCP end point.
-//
-// The network must be a TCP network name.
-//
-// If the host in the address parameter is not a literal IP address or
-// the port is not a literal port number, ResolveTCPAddr resolves the
-// address to an address of TCP end point.
-// Otherwise, it parses the address as a pair of literal IP address
-// and port number.
-// The address parameter can use a host name, but this is not
-// recommended, because it will return at most one of the host name's
-// IP addresses.
-//
-// See func Dial for a description of the network and address
-// parameters.
-func ResolveTCPAddr(network, address string) (*TCPAddr, error) {
- switch network {
- case "tcp", "tcp4", "tcp6":
- case "": // a hint wildcard for Go 1.0 undocumented behavior
- network = "tcp"
- default:
- return nil, UnknownNetworkError(network)
- }
- addrs, err := DefaultResolver.internetAddrList(context.Background(), network, address)
- if err != nil {
- return nil, err
- }
- return addrs.forResolve(network, address).(*TCPAddr), nil
-}
-
-// TCPAddrFromAddrPort returns addr as a TCPAddr. If addr.IsValid() is false,
-// then the returned TCPAddr will contain a nil IP field, indicating an
-// address family-agnostic unspecified address.
-func TCPAddrFromAddrPort(addr netip.AddrPort) *TCPAddr {
- return &TCPAddr{
- IP: addr.Addr().AsSlice(),
- Zone: addr.Addr().Zone(),
- Port: int(addr.Port()),
- }
-}
-
-// TCPConn is an implementation of the Conn interface for TCP network
-// connections.
-type TCPConn struct {
- conn
-}
-
-// SyscallConn returns a raw network connection.
-// This implements the syscall.Conn interface.
-func (c *TCPConn) SyscallConn() (syscall.RawConn, error) {
- if !c.ok() {
- return nil, syscall.EINVAL
- }
- return newRawConn(c.fd)
-}
-
-// ReadFrom implements the io.ReaderFrom ReadFrom method.
-func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
- if !c.ok() {
- return 0, syscall.EINVAL
- }
- n, err := c.readFrom(r)
- if err != nil && err != io.EOF {
- err = &OpError{Op: "readfrom", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return n, err
-}
-
-// CloseRead shuts down the reading side of the TCP connection.
-// Most callers should just use Close.
-func (c *TCPConn) CloseRead() error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := c.fd.closeRead(); err != nil {
- return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return nil
-}
-
-// CloseWrite shuts down the writing side of the TCP connection.
-// Most callers should just use Close.
-func (c *TCPConn) CloseWrite() error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := c.fd.closeWrite(); err != nil {
- return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return nil
-}
-
-// SetLinger sets the behavior of Close on a connection which still
-// has data waiting to be sent or to be acknowledged.
-//
-// If sec < 0 (the default), the operating system finishes sending the
-// data in the background.
-//
-// If sec == 0, the operating system discards any unsent or
-// unacknowledged data.
-//
-// If sec > 0, the data is sent in the background as with sec < 0. On
-// some operating systems after sec seconds have elapsed any remaining
-// unsent data may be discarded.
-func (c *TCPConn) SetLinger(sec int) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := setLinger(c.fd, sec); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return nil
-}
-
-// SetKeepAlive sets whether the operating system should send
-// keep-alive messages on the connection.
-func (c *TCPConn) SetKeepAlive(keepalive bool) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := setKeepAlive(c.fd, keepalive); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return nil
-}
-
-// SetKeepAlivePeriod sets period between keep-alives.
-func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := setKeepAlivePeriod(c.fd, d); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return nil
-}
-
-// SetNoDelay controls whether the operating system should delay
-// packet transmission in hopes of sending fewer packets (Nagle's
-// algorithm). The default is true (no delay), meaning that data is
-// sent as soon as possible after a Write.
-func (c *TCPConn) SetNoDelay(noDelay bool) error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := setNoDelay(c.fd, noDelay); err != nil {
- return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return nil
-}
-
-func newTCPConn(fd *netFD, keepAlive time.Duration, keepAliveHook func(time.Duration)) *TCPConn {
- setNoDelay(fd, true)
- if keepAlive == 0 {
- keepAlive = defaultTCPKeepAlive
- }
- if keepAlive > 0 {
- setKeepAlive(fd, true)
- setKeepAlivePeriod(fd, keepAlive)
- if keepAliveHook != nil {
- keepAliveHook(keepAlive)
- }
- }
- return &TCPConn{conn{fd}}
-}
-
-// DialTCP acts like Dial for TCP networks.
-//
-// The network must be a TCP network name; see func Dial for details.
-//
-// If laddr is nil, a local address is automatically chosen.
-// If the IP field of raddr is nil or an unspecified IP address, the
-// local system is assumed.
-func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error) {
- switch network {
- case "tcp", "tcp4", "tcp6":
- default:
- return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
- }
- if raddr == nil {
- return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
- }
- sd := &sysDialer{network: network, address: raddr.String()}
- c, err := sd.dialTCP(context.Background(), laddr, raddr)
- if err != nil {
- return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
- }
- return c, nil
-}
-
-// TCPListener is a TCP network listener. Clients should typically
-// use variables of type Listener instead of assuming TCP.
-type TCPListener struct {
- fd *netFD
- lc ListenConfig
-}
-
-// SyscallConn returns a raw network connection.
-// This implements the syscall.Conn interface.
-//
-// The returned RawConn only supports calling Control. Read and
-// Write return an error.
-func (l *TCPListener) SyscallConn() (syscall.RawConn, error) {
- if !l.ok() {
- return nil, syscall.EINVAL
- }
- return newRawListener(l.fd)
-}
-
-// AcceptTCP accepts the next incoming call and returns the new
-// connection.
-func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
- if !l.ok() {
- return nil, syscall.EINVAL
- }
- c, err := l.accept()
- if err != nil {
- return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
- }
- return c, nil
-}
-
-// Accept implements the Accept method in the Listener interface; it
-// waits for the next call and returns a generic Conn.
-func (l *TCPListener) Accept() (Conn, error) {
- if !l.ok() {
- return nil, syscall.EINVAL
- }
- c, err := l.accept()
- if err != nil {
- return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
- }
- return c, nil
-}
-
-// Close stops listening on the TCP address.
-// Already Accepted connections are not closed.
-func (l *TCPListener) Close() error {
- if !l.ok() {
- return syscall.EINVAL
- }
- if err := l.close(); err != nil {
- return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
- }
- return nil
-}
-
-// Addr returns the listener's network address, a *TCPAddr.
-// The Addr returned is shared by all invocations of Addr, so
-// do not modify it.
-func (l *TCPListener) Addr() Addr { return l.fd.laddr }
-
-// SetDeadline sets the deadline associated with the listener.
-// A zero time value disables the deadline.
-func (l *TCPListener) SetDeadline(t time.Time) error {
- if !l.ok() {
- return syscall.EINVAL
- }
- if err := l.fd.pfd.SetDeadline(t); err != nil {
- return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
- }
- return nil
-}
-
-// File returns a copy of the underlying os.File.
-// It is the caller's responsibility to close f when finished.
-// Closing l does not affect f, and closing f does not affect l.
-//
-// The returned os.File's file descriptor is different from the
-// connection's. Attempting to change properties of the original
-// using this duplicate may or may not have the desired effect.
-func (l *TCPListener) File() (f *os.File, err error) {
- if !l.ok() {
- return nil, syscall.EINVAL
- }
- f, err = l.file()
- if err != nil {
- return nil, &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
- }
- return
-}
-
-// ListenTCP acts like Listen for TCP networks.
-//
-// The network must be a TCP network name; see func Dial for details.
-//
-// If the IP field of laddr is nil or an unspecified IP address,
-// ListenTCP listens on all available unicast and anycast IP addresses
-// of the local system.
-// If the Port field of laddr is 0, a port number is automatically
-// chosen.
-func ListenTCP(network string, laddr *TCPAddr) (*TCPListener, error) {
- switch network {
- case "tcp", "tcp4", "tcp6":
- default:
- return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
- }
- if laddr == nil {
- laddr = &TCPAddr{}
- }
- sl := &sysListener{network: network, address: laddr.String()}
- ln, err := sl.listenTCP(context.Background(), laddr)
- if err != nil {
- return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
- }
- return ln, nil
-}
-
-// roundDurationUp rounds d to the next multiple of to.
-func roundDurationUp(d time.Duration, to time.Duration) time.Duration {
- return (d + to - 1) / to
-}
diff --git a/contrib/go/_std_1.20/src/net/tcpsock_posix.go b/contrib/go/_std_1.20/src/net/tcpsock_posix.go
deleted file mode 100644
index 0b3fa1ae0c..0000000000
--- a/contrib/go/_std_1.20/src/net/tcpsock_posix.go
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix || (js && wasm) || windows
-
-package net
-
-import (
- "context"
- "io"
- "os"
- "syscall"
-)
-
-func sockaddrToTCP(sa syscall.Sockaddr) Addr {
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- return &TCPAddr{IP: sa.Addr[0:], Port: sa.Port}
- case *syscall.SockaddrInet6:
- return &TCPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneCache.name(int(sa.ZoneId))}
- }
- return nil
-}
-
-func (a *TCPAddr) family() int {
- if a == nil || len(a.IP) <= IPv4len {
- return syscall.AF_INET
- }
- if a.IP.To4() != nil {
- return syscall.AF_INET
- }
- return syscall.AF_INET6
-}
-
-func (a *TCPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
- if a == nil {
- return nil, nil
- }
- return ipToSockaddr(family, a.IP, a.Port, a.Zone)
-}
-
-func (a *TCPAddr) toLocal(net string) sockaddr {
- return &TCPAddr{loopbackIP(net), a.Port, a.Zone}
-}
-
-func (c *TCPConn) readFrom(r io.Reader) (int64, error) {
- if n, err, handled := splice(c.fd, r); handled {
- return n, err
- }
- if n, err, handled := sendFile(c.fd, r); handled {
- return n, err
- }
- return genericReadFrom(c, r)
-}
-
-func (sd *sysDialer) dialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
- if h := sd.testHookDialTCP; h != nil {
- return h(ctx, sd.network, laddr, raddr)
- }
- if h := testHookDialTCP; h != nil {
- return h(ctx, sd.network, laddr, raddr)
- }
- return sd.doDialTCP(ctx, laddr, raddr)
-}
-
-func (sd *sysDialer) doDialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
- ctrlCtxFn := sd.Dialer.ControlContext
- if ctrlCtxFn == nil && sd.Dialer.Control != nil {
- ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
- return sd.Dialer.Control(network, address, c)
- }
- }
- fd, err := internetSocket(ctx, sd.network, laddr, raddr, syscall.SOCK_STREAM, 0, "dial", ctrlCtxFn)
-
- // TCP has a rarely used mechanism called a 'simultaneous connection' in
- // which Dial("tcp", addr1, addr2) run on the machine at addr1 can
- // connect to a simultaneous Dial("tcp", addr2, addr1) run on the machine
- // at addr2, without either machine executing Listen. If laddr == nil,
- // it means we want the kernel to pick an appropriate originating local
- // address. Some Linux kernels cycle blindly through a fixed range of
- // local ports, regardless of destination port. If a kernel happens to
- // pick local port 50001 as the source for a Dial("tcp", "", "localhost:50001"),
- // then the Dial will succeed, having simultaneously connected to itself.
- // This can only happen when we are letting the kernel pick a port (laddr == nil)
- // and when there is no listener for the destination address.
- // It's hard to argue this is anything other than a kernel bug. If we
- // see this happen, rather than expose the buggy effect to users, we
- // close the fd and try again. If it happens twice more, we relent and
- // use the result. See also:
- // https://golang.org/issue/2690
- // https://stackoverflow.com/questions/4949858/
- //
- // The opposite can also happen: if we ask the kernel to pick an appropriate
- // originating local address, sometimes it picks one that is already in use.
- // So if the error is EADDRNOTAVAIL, we have to try again too, just for
- // a different reason.
- //
- // The kernel socket code is no doubt enjoying watching us squirm.
- for i := 0; i < 2 && (laddr == nil || laddr.Port == 0) && (selfConnect(fd, err) || spuriousENOTAVAIL(err)); i++ {
- if err == nil {
- fd.Close()
- }
- fd, err = internetSocket(ctx, sd.network, laddr, raddr, syscall.SOCK_STREAM, 0, "dial", ctrlCtxFn)
- }
-
- if err != nil {
- return nil, err
- }
- return newTCPConn(fd, sd.Dialer.KeepAlive, testHookSetKeepAlive), nil
-}
-
-func selfConnect(fd *netFD, err error) bool {
- // If the connect failed, we clearly didn't connect to ourselves.
- if err != nil {
- return false
- }
-
- // The socket constructor can return an fd with raddr nil under certain
- // unknown conditions. The errors in the calls there to Getpeername
- // are discarded, but we can't catch the problem there because those
- // calls are sometimes legally erroneous with a "socket not connected".
- // Since this code (selfConnect) is already trying to work around
- // a problem, we make sure if this happens we recognize trouble and
- // ask the DialTCP routine to try again.
- // TODO: try to understand what's really going on.
- if fd.laddr == nil || fd.raddr == nil {
- return true
- }
- l := fd.laddr.(*TCPAddr)
- r := fd.raddr.(*TCPAddr)
- return l.Port == r.Port && l.IP.Equal(r.IP)
-}
-
-func spuriousENOTAVAIL(err error) bool {
- if op, ok := err.(*OpError); ok {
- err = op.Err
- }
- if sys, ok := err.(*os.SyscallError); ok {
- err = sys.Err
- }
- return err == syscall.EADDRNOTAVAIL
-}
-
-func (ln *TCPListener) ok() bool { return ln != nil && ln.fd != nil }
-
-func (ln *TCPListener) accept() (*TCPConn, error) {
- fd, err := ln.fd.accept()
- if err != nil {
- return nil, err
- }
- return newTCPConn(fd, ln.lc.KeepAlive, nil), nil
-}
-
-func (ln *TCPListener) close() error {
- return ln.fd.Close()
-}
-
-func (ln *TCPListener) file() (*os.File, error) {
- f, err := ln.fd.dup()
- if err != nil {
- return nil, err
- }
- return f, nil
-}
-
-func (sl *sysListener) listenTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) {
- var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
- if sl.ListenConfig.Control != nil {
- ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
- return sl.ListenConfig.Control(network, address, c)
- }
- }
- fd, err := internetSocket(ctx, sl.network, laddr, nil, syscall.SOCK_STREAM, 0, "listen", ctrlCtxFn)
- if err != nil {
- return nil, err
- }
- return &TCPListener{fd: fd, lc: sl.ListenConfig}, nil
-}
diff --git a/contrib/go/_std_1.20/src/net/textproto/ya.make b/contrib/go/_std_1.20/src/net/textproto/ya.make
deleted file mode 100644
index 36faa708eb..0000000000
--- a/contrib/go/_std_1.20/src/net/textproto/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- header.go
- pipeline.go
- reader.go
- textproto.go
- writer.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/udpsock_posix.go b/contrib/go/_std_1.20/src/net/udpsock_posix.go
deleted file mode 100644
index ffeec81cff..0000000000
--- a/contrib/go/_std_1.20/src/net/udpsock_posix.go
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix || (js && wasm) || windows
-
-package net
-
-import (
- "context"
- "net/netip"
- "syscall"
-)
-
-func sockaddrToUDP(sa syscall.Sockaddr) Addr {
- switch sa := sa.(type) {
- case *syscall.SockaddrInet4:
- return &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
- case *syscall.SockaddrInet6:
- return &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneCache.name(int(sa.ZoneId))}
- }
- return nil
-}
-
-func (a *UDPAddr) family() int {
- if a == nil || len(a.IP) <= IPv4len {
- return syscall.AF_INET
- }
- if a.IP.To4() != nil {
- return syscall.AF_INET
- }
- return syscall.AF_INET6
-}
-
-func (a *UDPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
- if a == nil {
- return nil, nil
- }
- return ipToSockaddr(family, a.IP, a.Port, a.Zone)
-}
-
-func (a *UDPAddr) toLocal(net string) sockaddr {
- return &UDPAddr{loopbackIP(net), a.Port, a.Zone}
-}
-
-func (c *UDPConn) readFrom(b []byte, addr *UDPAddr) (int, *UDPAddr, error) {
- var n int
- var err error
- switch c.fd.family {
- case syscall.AF_INET:
- var from syscall.SockaddrInet4
- n, err = c.fd.readFromInet4(b, &from)
- if err == nil {
- ip := from.Addr // copy from.Addr; ip escapes, so this line allocates 4 bytes
- *addr = UDPAddr{IP: ip[:], Port: from.Port}
- }
- case syscall.AF_INET6:
- var from syscall.SockaddrInet6
- n, err = c.fd.readFromInet6(b, &from)
- if err == nil {
- ip := from.Addr // copy from.Addr; ip escapes, so this line allocates 16 bytes
- *addr = UDPAddr{IP: ip[:], Port: from.Port, Zone: zoneCache.name(int(from.ZoneId))}
- }
- }
- if err != nil {
- // No sockaddr, so don't return UDPAddr.
- addr = nil
- }
- return n, addr, err
-}
-
-func (c *UDPConn) readFromAddrPort(b []byte) (n int, addr netip.AddrPort, err error) {
- var ip netip.Addr
- var port int
- switch c.fd.family {
- case syscall.AF_INET:
- var from syscall.SockaddrInet4
- n, err = c.fd.readFromInet4(b, &from)
- if err == nil {
- ip = netip.AddrFrom4(from.Addr)
- port = from.Port
- }
- case syscall.AF_INET6:
- var from syscall.SockaddrInet6
- n, err = c.fd.readFromInet6(b, &from)
- if err == nil {
- ip = netip.AddrFrom16(from.Addr).WithZone(zoneCache.name(int(from.ZoneId)))
- port = from.Port
- }
- }
- if err == nil {
- addr = netip.AddrPortFrom(ip, uint16(port))
- }
- return n, addr, err
-}
-
-func (c *UDPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr netip.AddrPort, err error) {
- switch c.fd.family {
- case syscall.AF_INET:
- var sa syscall.SockaddrInet4
- n, oobn, flags, err = c.fd.readMsgInet4(b, oob, 0, &sa)
- ip := netip.AddrFrom4(sa.Addr)
- addr = netip.AddrPortFrom(ip, uint16(sa.Port))
- case syscall.AF_INET6:
- var sa syscall.SockaddrInet6
- n, oobn, flags, err = c.fd.readMsgInet6(b, oob, 0, &sa)
- ip := netip.AddrFrom16(sa.Addr).WithZone(zoneCache.name(int(sa.ZoneId)))
- addr = netip.AddrPortFrom(ip, uint16(sa.Port))
- }
- return
-}
-
-func (c *UDPConn) writeTo(b []byte, addr *UDPAddr) (int, error) {
- if c.fd.isConnected {
- return 0, ErrWriteToConnected
- }
- if addr == nil {
- return 0, errMissingAddress
- }
-
- switch c.fd.family {
- case syscall.AF_INET:
- sa, err := ipToSockaddrInet4(addr.IP, addr.Port)
- if err != nil {
- return 0, err
- }
- return c.fd.writeToInet4(b, &sa)
- case syscall.AF_INET6:
- sa, err := ipToSockaddrInet6(addr.IP, addr.Port, addr.Zone)
- if err != nil {
- return 0, err
- }
- return c.fd.writeToInet6(b, &sa)
- default:
- return 0, &AddrError{Err: "invalid address family", Addr: addr.IP.String()}
- }
-}
-
-func (c *UDPConn) writeToAddrPort(b []byte, addr netip.AddrPort) (int, error) {
- if c.fd.isConnected {
- return 0, ErrWriteToConnected
- }
- if !addr.IsValid() {
- return 0, errMissingAddress
- }
-
- switch c.fd.family {
- case syscall.AF_INET:
- sa, err := addrPortToSockaddrInet4(addr)
- if err != nil {
- return 0, err
- }
- return c.fd.writeToInet4(b, &sa)
- case syscall.AF_INET6:
- sa, err := addrPortToSockaddrInet6(addr)
- if err != nil {
- return 0, err
- }
- return c.fd.writeToInet6(b, &sa)
- default:
- return 0, &AddrError{Err: "invalid address family", Addr: addr.Addr().String()}
- }
-}
-
-func (c *UDPConn) writeMsg(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
- if c.fd.isConnected && addr != nil {
- return 0, 0, ErrWriteToConnected
- }
- if !c.fd.isConnected && addr == nil {
- return 0, 0, errMissingAddress
- }
- sa, err := addr.sockaddr(c.fd.family)
- if err != nil {
- return 0, 0, err
- }
- return c.fd.writeMsg(b, oob, sa)
-}
-
-func (c *UDPConn) writeMsgAddrPort(b, oob []byte, addr netip.AddrPort) (n, oobn int, err error) {
- if c.fd.isConnected && addr.IsValid() {
- return 0, 0, ErrWriteToConnected
- }
- if !c.fd.isConnected && !addr.IsValid() {
- return 0, 0, errMissingAddress
- }
-
- switch c.fd.family {
- case syscall.AF_INET:
- sa, err := addrPortToSockaddrInet4(addr)
- if err != nil {
- return 0, 0, err
- }
- return c.fd.writeMsgInet4(b, oob, &sa)
- case syscall.AF_INET6:
- sa, err := addrPortToSockaddrInet6(addr)
- if err != nil {
- return 0, 0, err
- }
- return c.fd.writeMsgInet6(b, oob, &sa)
- default:
- return 0, 0, &AddrError{Err: "invalid address family", Addr: addr.Addr().String()}
- }
-}
-
-func (sd *sysDialer) dialUDP(ctx context.Context, laddr, raddr *UDPAddr) (*UDPConn, error) {
- ctrlCtxFn := sd.Dialer.ControlContext
- if ctrlCtxFn == nil && sd.Dialer.Control != nil {
- ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
- return sd.Dialer.Control(network, address, c)
- }
- }
- fd, err := internetSocket(ctx, sd.network, laddr, raddr, syscall.SOCK_DGRAM, 0, "dial", ctrlCtxFn)
- if err != nil {
- return nil, err
- }
- return newUDPConn(fd), nil
-}
-
-func (sl *sysListener) listenUDP(ctx context.Context, laddr *UDPAddr) (*UDPConn, error) {
- var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
- if sl.ListenConfig.Control != nil {
- ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
- return sl.ListenConfig.Control(network, address, c)
- }
- }
- fd, err := internetSocket(ctx, sl.network, laddr, nil, syscall.SOCK_DGRAM, 0, "listen", ctrlCtxFn)
- if err != nil {
- return nil, err
- }
- return newUDPConn(fd), nil
-}
-
-func (sl *sysListener) listenMulticastUDP(ctx context.Context, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
- var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
- if sl.ListenConfig.Control != nil {
- ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
- return sl.ListenConfig.Control(network, address, c)
- }
- }
- fd, err := internetSocket(ctx, sl.network, gaddr, nil, syscall.SOCK_DGRAM, 0, "listen", ctrlCtxFn)
- if err != nil {
- return nil, err
- }
- c := newUDPConn(fd)
- if ip4 := gaddr.IP.To4(); ip4 != nil {
- if err := listenIPv4MulticastUDP(c, ifi, ip4); err != nil {
- c.Close()
- return nil, err
- }
- } else {
- if err := listenIPv6MulticastUDP(c, ifi, gaddr.IP); err != nil {
- c.Close()
- return nil, err
- }
- }
- return c, nil
-}
-
-func listenIPv4MulticastUDP(c *UDPConn, ifi *Interface, ip IP) error {
- if ifi != nil {
- if err := setIPv4MulticastInterface(c.fd, ifi); err != nil {
- return err
- }
- }
- if err := setIPv4MulticastLoopback(c.fd, false); err != nil {
- return err
- }
- if err := joinIPv4Group(c.fd, ifi, ip); err != nil {
- return err
- }
- return nil
-}
-
-func listenIPv6MulticastUDP(c *UDPConn, ifi *Interface, ip IP) error {
- if ifi != nil {
- if err := setIPv6MulticastInterface(c.fd, ifi); err != nil {
- return err
- }
- }
- if err := setIPv6MulticastLoopback(c.fd, false); err != nil {
- return err
- }
- if err := joinIPv6Group(c.fd, ifi, ip); err != nil {
- return err
- }
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/net/unixsock.go b/contrib/go/_std_1.20/src/net/unixsock.go
deleted file mode 100644
index b38438c11a..0000000000
--- a/contrib/go/_std_1.20/src/net/unixsock.go
+++ /dev/null
@@ -1,352 +0,0 @@
-// Copyright 2009 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 net
-
-import (
- "context"
- "os"
- "sync"
- "syscall"
- "time"
-)
-
-// BUG(mikio): On JS and Plan 9, methods and functions related
-// to UnixConn and UnixListener are not implemented.
-
-// BUG(mikio): On Windows, methods and functions related to UnixConn
-// and UnixListener don't work for "unixgram" and "unixpacket".
-
-// UnixAddr represents the address of a Unix domain socket end point.
-type UnixAddr struct {
- Name string
- Net string
-}
-
-// Network returns the address's network name, "unix", "unixgram" or
-// "unixpacket".
-func (a *UnixAddr) Network() string {
- return a.Net
-}
-
-func (a *UnixAddr) String() string {
- if a == nil {
- return "<nil>"
- }
- return a.Name
-}
-
-func (a *UnixAddr) isWildcard() bool {
- return a == nil || a.Name == ""
-}
-
-func (a *UnixAddr) opAddr() Addr {
- if a == nil {
- return nil
- }
- return a
-}
-
-// ResolveUnixAddr returns an address of Unix domain socket end point.
-//
-// The network must be a Unix network name.
-//
-// See func Dial for a description of the network and address
-// parameters.
-func ResolveUnixAddr(network, address string) (*UnixAddr, error) {
- switch network {
- case "unix", "unixgram", "unixpacket":
- return &UnixAddr{Name: address, Net: network}, nil
- default:
- return nil, UnknownNetworkError(network)
- }
-}
-
-// UnixConn is an implementation of the Conn interface for connections
-// to Unix domain sockets.
-type UnixConn struct {
- conn
-}
-
-// SyscallConn returns a raw network connection.
-// This implements the syscall.Conn interface.
-func (c *UnixConn) SyscallConn() (syscall.RawConn, error) {
- if !c.ok() {
- return nil, syscall.EINVAL
- }
- return newRawConn(c.fd)
-}
-
-// CloseRead shuts down the reading side of the Unix domain connection.
-// Most callers should just use Close.
-func (c *UnixConn) CloseRead() error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := c.fd.closeRead(); err != nil {
- return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return nil
-}
-
-// CloseWrite shuts down the writing side of the Unix domain connection.
-// Most callers should just use Close.
-func (c *UnixConn) CloseWrite() error {
- if !c.ok() {
- return syscall.EINVAL
- }
- if err := c.fd.closeWrite(); err != nil {
- return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return nil
-}
-
-// ReadFromUnix acts like ReadFrom but returns a UnixAddr.
-func (c *UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error) {
- if !c.ok() {
- return 0, nil, syscall.EINVAL
- }
- n, addr, err := c.readFrom(b)
- if err != nil {
- err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return n, addr, err
-}
-
-// ReadFrom implements the PacketConn ReadFrom method.
-func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error) {
- if !c.ok() {
- return 0, nil, syscall.EINVAL
- }
- n, addr, err := c.readFrom(b)
- if err != nil {
- err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- if addr == nil {
- return n, nil, err
- }
- return n, addr, err
-}
-
-// ReadMsgUnix reads a message from c, copying the payload into b and
-// the associated out-of-band data into oob. It returns the number of
-// bytes copied into b, the number of bytes copied into oob, the flags
-// that were set on the message and the source address of the message.
-//
-// Note that if len(b) == 0 and len(oob) > 0, this function will still
-// read (and discard) 1 byte from the connection.
-func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
- if !c.ok() {
- return 0, 0, 0, nil, syscall.EINVAL
- }
- n, oobn, flags, addr, err = c.readMsg(b, oob)
- if err != nil {
- err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
- }
- return
-}
-
-// WriteToUnix acts like WriteTo but takes a UnixAddr.
-func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error) {
- if !c.ok() {
- return 0, syscall.EINVAL
- }
- n, err := c.writeTo(b, addr)
- if err != nil {
- err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
- }
- return n, err
-}
-
-// WriteTo implements the PacketConn WriteTo method.
-func (c *UnixConn) WriteTo(b []byte, addr Addr) (int, error) {
- if !c.ok() {
- return 0, syscall.EINVAL
- }
- a, ok := addr.(*UnixAddr)
- if !ok {
- return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
- }
- n, err := c.writeTo(b, a)
- if err != nil {
- err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: a.opAddr(), Err: err}
- }
- return n, err
-}
-
-// WriteMsgUnix writes a message to addr via c, copying the payload
-// from b and the associated out-of-band data from oob. It returns the
-// number of payload and out-of-band bytes written.
-//
-// Note that if len(b) == 0 and len(oob) > 0, this function will still
-// write 1 byte to the connection.
-func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) {
- if !c.ok() {
- return 0, 0, syscall.EINVAL
- }
- n, oobn, err = c.writeMsg(b, oob, addr)
- if err != nil {
- err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
- }
- return
-}
-
-func newUnixConn(fd *netFD) *UnixConn { return &UnixConn{conn{fd}} }
-
-// DialUnix acts like Dial for Unix networks.
-//
-// The network must be a Unix network name; see func Dial for details.
-//
-// If laddr is non-nil, it is used as the local address for the
-// connection.
-func DialUnix(network string, laddr, raddr *UnixAddr) (*UnixConn, error) {
- switch network {
- case "unix", "unixgram", "unixpacket":
- default:
- return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
- }
- sd := &sysDialer{network: network, address: raddr.String()}
- c, err := sd.dialUnix(context.Background(), laddr, raddr)
- if err != nil {
- return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
- }
- return c, nil
-}
-
-// UnixListener is a Unix domain socket listener. Clients should
-// typically use variables of type Listener instead of assuming Unix
-// domain sockets.
-type UnixListener struct {
- fd *netFD
- path string
- unlink bool
- unlinkOnce sync.Once
-}
-
-func (ln *UnixListener) ok() bool { return ln != nil && ln.fd != nil }
-
-// SyscallConn returns a raw network connection.
-// This implements the syscall.Conn interface.
-//
-// The returned RawConn only supports calling Control. Read and
-// Write return an error.
-func (l *UnixListener) SyscallConn() (syscall.RawConn, error) {
- if !l.ok() {
- return nil, syscall.EINVAL
- }
- return newRawListener(l.fd)
-}
-
-// AcceptUnix accepts the next incoming call and returns the new
-// connection.
-func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
- if !l.ok() {
- return nil, syscall.EINVAL
- }
- c, err := l.accept()
- if err != nil {
- return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
- }
- return c, nil
-}
-
-// Accept implements the Accept method in the Listener interface.
-// Returned connections will be of type *UnixConn.
-func (l *UnixListener) Accept() (Conn, error) {
- if !l.ok() {
- return nil, syscall.EINVAL
- }
- c, err := l.accept()
- if err != nil {
- return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
- }
- return c, nil
-}
-
-// Close stops listening on the Unix address. Already accepted
-// connections are not closed.
-func (l *UnixListener) Close() error {
- if !l.ok() {
- return syscall.EINVAL
- }
- if err := l.close(); err != nil {
- return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
- }
- return nil
-}
-
-// Addr returns the listener's network address.
-// The Addr returned is shared by all invocations of Addr, so
-// do not modify it.
-func (l *UnixListener) Addr() Addr { return l.fd.laddr }
-
-// SetDeadline sets the deadline associated with the listener.
-// A zero time value disables the deadline.
-func (l *UnixListener) SetDeadline(t time.Time) error {
- if !l.ok() {
- return syscall.EINVAL
- }
- if err := l.fd.pfd.SetDeadline(t); err != nil {
- return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
- }
- return nil
-}
-
-// File returns a copy of the underlying os.File.
-// It is the caller's responsibility to close f when finished.
-// Closing l does not affect f, and closing f does not affect l.
-//
-// The returned os.File's file descriptor is different from the
-// connection's. Attempting to change properties of the original
-// using this duplicate may or may not have the desired effect.
-func (l *UnixListener) File() (f *os.File, err error) {
- if !l.ok() {
- return nil, syscall.EINVAL
- }
- f, err = l.file()
- if err != nil {
- err = &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
- }
- return
-}
-
-// ListenUnix acts like Listen for Unix networks.
-//
-// The network must be "unix" or "unixpacket".
-func ListenUnix(network string, laddr *UnixAddr) (*UnixListener, error) {
- switch network {
- case "unix", "unixpacket":
- default:
- return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
- }
- if laddr == nil {
- return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: errMissingAddress}
- }
- sl := &sysListener{network: network, address: laddr.String()}
- ln, err := sl.listenUnix(context.Background(), laddr)
- if err != nil {
- return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
- }
- return ln, nil
-}
-
-// ListenUnixgram acts like ListenPacket for Unix networks.
-//
-// The network must be "unixgram".
-func ListenUnixgram(network string, laddr *UnixAddr) (*UnixConn, error) {
- switch network {
- case "unixgram":
- default:
- return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
- }
- if laddr == nil {
- return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: errMissingAddress}
- }
- sl := &sysListener{network: network, address: laddr.String()}
- c, err := sl.listenUnixgram(context.Background(), laddr)
- if err != nil {
- return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
- }
- return c, nil
-}
diff --git a/contrib/go/_std_1.20/src/net/unixsock_posix.go b/contrib/go/_std_1.20/src/net/unixsock_posix.go
deleted file mode 100644
index c16b483603..0000000000
--- a/contrib/go/_std_1.20/src/net/unixsock_posix.go
+++ /dev/null
@@ -1,245 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix || (js && wasm) || windows
-
-package net
-
-import (
- "context"
- "errors"
- "os"
- "syscall"
-)
-
-func unixSocket(ctx context.Context, net string, laddr, raddr sockaddr, mode string, ctxCtrlFn func(context.Context, string, string, syscall.RawConn) error) (*netFD, error) {
- var sotype int
- switch net {
- case "unix":
- sotype = syscall.SOCK_STREAM
- case "unixgram":
- sotype = syscall.SOCK_DGRAM
- case "unixpacket":
- sotype = syscall.SOCK_SEQPACKET
- default:
- return nil, UnknownNetworkError(net)
- }
-
- switch mode {
- case "dial":
- if laddr != nil && laddr.isWildcard() {
- laddr = nil
- }
- if raddr != nil && raddr.isWildcard() {
- raddr = nil
- }
- if raddr == nil && (sotype != syscall.SOCK_DGRAM || laddr == nil) {
- return nil, errMissingAddress
- }
- case "listen":
- default:
- return nil, errors.New("unknown mode: " + mode)
- }
-
- fd, err := socket(ctx, net, syscall.AF_UNIX, sotype, 0, false, laddr, raddr, ctxCtrlFn)
- if err != nil {
- return nil, err
- }
- return fd, nil
-}
-
-func sockaddrToUnix(sa syscall.Sockaddr) Addr {
- if s, ok := sa.(*syscall.SockaddrUnix); ok {
- return &UnixAddr{Name: s.Name, Net: "unix"}
- }
- return nil
-}
-
-func sockaddrToUnixgram(sa syscall.Sockaddr) Addr {
- if s, ok := sa.(*syscall.SockaddrUnix); ok {
- return &UnixAddr{Name: s.Name, Net: "unixgram"}
- }
- return nil
-}
-
-func sockaddrToUnixpacket(sa syscall.Sockaddr) Addr {
- if s, ok := sa.(*syscall.SockaddrUnix); ok {
- return &UnixAddr{Name: s.Name, Net: "unixpacket"}
- }
- return nil
-}
-
-func sotypeToNet(sotype int) string {
- switch sotype {
- case syscall.SOCK_STREAM:
- return "unix"
- case syscall.SOCK_DGRAM:
- return "unixgram"
- case syscall.SOCK_SEQPACKET:
- return "unixpacket"
- default:
- panic("sotypeToNet unknown socket type")
- }
-}
-
-func (a *UnixAddr) family() int {
- return syscall.AF_UNIX
-}
-
-func (a *UnixAddr) sockaddr(family int) (syscall.Sockaddr, error) {
- if a == nil {
- return nil, nil
- }
- return &syscall.SockaddrUnix{Name: a.Name}, nil
-}
-
-func (a *UnixAddr) toLocal(net string) sockaddr {
- return a
-}
-
-func (c *UnixConn) readFrom(b []byte) (int, *UnixAddr, error) {
- var addr *UnixAddr
- n, sa, err := c.fd.readFrom(b)
- switch sa := sa.(type) {
- case *syscall.SockaddrUnix:
- if sa.Name != "" {
- addr = &UnixAddr{Name: sa.Name, Net: sotypeToNet(c.fd.sotype)}
- }
- }
- return n, addr, err
-}
-
-func (c *UnixConn) readMsg(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
- var sa syscall.Sockaddr
- n, oobn, flags, sa, err = c.fd.readMsg(b, oob, readMsgFlags)
- if readMsgFlags == 0 && err == nil && oobn > 0 {
- setReadMsgCloseOnExec(oob[:oobn])
- }
-
- switch sa := sa.(type) {
- case *syscall.SockaddrUnix:
- if sa.Name != "" {
- addr = &UnixAddr{Name: sa.Name, Net: sotypeToNet(c.fd.sotype)}
- }
- }
- return
-}
-
-func (c *UnixConn) writeTo(b []byte, addr *UnixAddr) (int, error) {
- if c.fd.isConnected {
- return 0, ErrWriteToConnected
- }
- if addr == nil {
- return 0, errMissingAddress
- }
- if addr.Net != sotypeToNet(c.fd.sotype) {
- return 0, syscall.EAFNOSUPPORT
- }
- sa := &syscall.SockaddrUnix{Name: addr.Name}
- return c.fd.writeTo(b, sa)
-}
-
-func (c *UnixConn) writeMsg(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) {
- if c.fd.sotype == syscall.SOCK_DGRAM && c.fd.isConnected {
- return 0, 0, ErrWriteToConnected
- }
- var sa syscall.Sockaddr
- if addr != nil {
- if addr.Net != sotypeToNet(c.fd.sotype) {
- return 0, 0, syscall.EAFNOSUPPORT
- }
- sa = &syscall.SockaddrUnix{Name: addr.Name}
- }
- return c.fd.writeMsg(b, oob, sa)
-}
-
-func (sd *sysDialer) dialUnix(ctx context.Context, laddr, raddr *UnixAddr) (*UnixConn, error) {
- ctrlCtxFn := sd.Dialer.ControlContext
- if ctrlCtxFn == nil && sd.Dialer.Control != nil {
- ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
- return sd.Dialer.Control(network, address, c)
- }
- }
- fd, err := unixSocket(ctx, sd.network, laddr, raddr, "dial", ctrlCtxFn)
- if err != nil {
- return nil, err
- }
- return newUnixConn(fd), nil
-}
-
-func (ln *UnixListener) accept() (*UnixConn, error) {
- fd, err := ln.fd.accept()
- if err != nil {
- return nil, err
- }
- return newUnixConn(fd), nil
-}
-
-func (ln *UnixListener) close() error {
- // The operating system doesn't clean up
- // the file that announcing created, so
- // we have to clean it up ourselves.
- // There's a race here--we can't know for
- // sure whether someone else has come along
- // and replaced our socket name already--
- // but this sequence (remove then close)
- // is at least compatible with the auto-remove
- // sequence in ListenUnix. It's only non-Go
- // programs that can mess us up.
- // Even if there are racy calls to Close, we want to unlink only for the first one.
- ln.unlinkOnce.Do(func() {
- if ln.path[0] != '@' && ln.unlink {
- syscall.Unlink(ln.path)
- }
- })
- return ln.fd.Close()
-}
-
-func (ln *UnixListener) file() (*os.File, error) {
- f, err := ln.fd.dup()
- if err != nil {
- return nil, err
- }
- return f, nil
-}
-
-// SetUnlinkOnClose sets whether the underlying socket file should be removed
-// from the file system when the listener is closed.
-//
-// The default behavior is to unlink the socket file only when package net created it.
-// That is, when the listener and the underlying socket file were created by a call to
-// Listen or ListenUnix, then by default closing the listener will remove the socket file.
-// but if the listener was created by a call to FileListener to use an already existing
-// socket file, then by default closing the listener will not remove the socket file.
-func (l *UnixListener) SetUnlinkOnClose(unlink bool) {
- l.unlink = unlink
-}
-
-func (sl *sysListener) listenUnix(ctx context.Context, laddr *UnixAddr) (*UnixListener, error) {
- var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
- if sl.ListenConfig.Control != nil {
- ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
- return sl.ListenConfig.Control(network, address, c)
- }
- }
- fd, err := unixSocket(ctx, sl.network, laddr, nil, "listen", ctrlCtxFn)
- if err != nil {
- return nil, err
- }
- return &UnixListener{fd: fd, path: fd.laddr.String(), unlink: true}, nil
-}
-
-func (sl *sysListener) listenUnixgram(ctx context.Context, laddr *UnixAddr) (*UnixConn, error) {
- var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
- if sl.ListenConfig.Control != nil {
- ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
- return sl.ListenConfig.Control(network, address, c)
- }
- }
- fd, err := unixSocket(ctx, sl.network, laddr, nil, "listen", ctrlCtxFn)
- if err != nil {
- return nil, err
- }
- return newUnixConn(fd), nil
-}
diff --git a/contrib/go/_std_1.20/src/net/unixsock_readmsg_other.go b/contrib/go/_std_1.20/src/net/unixsock_readmsg_other.go
deleted file mode 100644
index b3d19fe73d..0000000000
--- a/contrib/go/_std_1.20/src/net/unixsock_readmsg_other.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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.
-
-//go:build (js && wasm) || windows
-
-package net
-
-const readMsgFlags = 0
-
-func setReadMsgCloseOnExec(oob []byte) {}
diff --git a/contrib/go/_std_1.20/src/net/url/url.go b/contrib/go/_std_1.20/src/net/url/url.go
deleted file mode 100644
index d530a50d40..0000000000
--- a/contrib/go/_std_1.20/src/net/url/url.go
+++ /dev/null
@@ -1,1268 +0,0 @@
-// Copyright 2009 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 url parses URLs and implements query escaping.
-package url
-
-// See RFC 3986. This package generally follows RFC 3986, except where
-// it deviates for compatibility reasons. When sending changes, first
-// search old issues for history on decisions. Unit tests should also
-// contain references to issue numbers with details.
-
-import (
- "errors"
- "fmt"
- "path"
- "sort"
- "strconv"
- "strings"
-)
-
-// Error reports an error and the operation and URL that caused it.
-type Error struct {
- Op string
- URL string
- Err error
-}
-
-func (e *Error) Unwrap() error { return e.Err }
-func (e *Error) Error() string { return fmt.Sprintf("%s %q: %s", e.Op, e.URL, e.Err) }
-
-func (e *Error) Timeout() bool {
- t, ok := e.Err.(interface {
- Timeout() bool
- })
- return ok && t.Timeout()
-}
-
-func (e *Error) Temporary() bool {
- t, ok := e.Err.(interface {
- Temporary() bool
- })
- return ok && t.Temporary()
-}
-
-const upperhex = "0123456789ABCDEF"
-
-func ishex(c byte) bool {
- switch {
- case '0' <= c && c <= '9':
- return true
- case 'a' <= c && c <= 'f':
- return true
- case 'A' <= c && c <= 'F':
- return true
- }
- return false
-}
-
-func unhex(c byte) byte {
- switch {
- case '0' <= c && c <= '9':
- return c - '0'
- case 'a' <= c && c <= 'f':
- return c - 'a' + 10
- case 'A' <= c && c <= 'F':
- return c - 'A' + 10
- }
- return 0
-}
-
-type encoding int
-
-const (
- encodePath encoding = 1 + iota
- encodePathSegment
- encodeHost
- encodeZone
- encodeUserPassword
- encodeQueryComponent
- encodeFragment
-)
-
-type EscapeError string
-
-func (e EscapeError) Error() string {
- return "invalid URL escape " + strconv.Quote(string(e))
-}
-
-type InvalidHostError string
-
-func (e InvalidHostError) Error() string {
- return "invalid character " + strconv.Quote(string(e)) + " in host name"
-}
-
-// Return true if the specified character should be escaped when
-// appearing in a URL string, according to RFC 3986.
-//
-// Please be informed that for now shouldEscape does not check all
-// reserved characters correctly. See golang.org/issue/5684.
-func shouldEscape(c byte, mode encoding) bool {
- // §2.3 Unreserved characters (alphanum)
- if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {
- return false
- }
-
- if mode == encodeHost || mode == encodeZone {
- // §3.2.2 Host allows
- // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
- // as part of reg-name.
- // We add : because we include :port as part of host.
- // We add [ ] because we include [ipv6]:port as part of host.
- // We add < > because they're the only characters left that
- // we could possibly allow, and Parse will reject them if we
- // escape them (because hosts can't use %-encoding for
- // ASCII bytes).
- switch c {
- case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=', ':', '[', ']', '<', '>', '"':
- return false
- }
- }
-
- switch c {
- case '-', '_', '.', '~': // §2.3 Unreserved characters (mark)
- return false
-
- case '$', '&', '+', ',', '/', ':', ';', '=', '?', '@': // §2.2 Reserved characters (reserved)
- // Different sections of the URL allow a few of
- // the reserved characters to appear unescaped.
- switch mode {
- case encodePath: // §3.3
- // The RFC allows : @ & = + $ but saves / ; , for assigning
- // meaning to individual path segments. This package
- // only manipulates the path as a whole, so we allow those
- // last three as well. That leaves only ? to escape.
- return c == '?'
-
- case encodePathSegment: // §3.3
- // The RFC allows : @ & = + $ but saves / ; , for assigning
- // meaning to individual path segments.
- return c == '/' || c == ';' || c == ',' || c == '?'
-
- case encodeUserPassword: // §3.2.1
- // The RFC allows ';', ':', '&', '=', '+', '$', and ',' in
- // userinfo, so we must escape only '@', '/', and '?'.
- // The parsing of userinfo treats ':' as special so we must escape
- // that too.
- return c == '@' || c == '/' || c == '?' || c == ':'
-
- case encodeQueryComponent: // §3.4
- // The RFC reserves (so we must escape) everything.
- return true
-
- case encodeFragment: // §4.1
- // The RFC text is silent but the grammar allows
- // everything, so escape nothing.
- return false
- }
- }
-
- if mode == encodeFragment {
- // RFC 3986 §2.2 allows not escaping sub-delims. A subset of sub-delims are
- // included in reserved from RFC 2396 §2.2. The remaining sub-delims do not
- // need to be escaped. To minimize potential breakage, we apply two restrictions:
- // (1) we always escape sub-delims outside of the fragment, and (2) we always
- // escape single quote to avoid breaking callers that had previously assumed that
- // single quotes would be escaped. See issue #19917.
- switch c {
- case '!', '(', ')', '*':
- return false
- }
- }
-
- // Everything else must be escaped.
- return true
-}
-
-// QueryUnescape does the inverse transformation of QueryEscape,
-// converting each 3-byte encoded substring of the form "%AB" into the
-// hex-decoded byte 0xAB.
-// It returns an error if any % is not followed by two hexadecimal
-// digits.
-func QueryUnescape(s string) (string, error) {
- return unescape(s, encodeQueryComponent)
-}
-
-// PathUnescape does the inverse transformation of PathEscape,
-// converting each 3-byte encoded substring of the form "%AB" into the
-// hex-decoded byte 0xAB. It returns an error if any % is not followed
-// by two hexadecimal digits.
-//
-// PathUnescape is identical to QueryUnescape except that it does not
-// unescape '+' to ' ' (space).
-func PathUnescape(s string) (string, error) {
- return unescape(s, encodePathSegment)
-}
-
-// unescape unescapes a string; the mode specifies
-// which section of the URL string is being unescaped.
-func unescape(s string, mode encoding) (string, error) {
- // Count %, check that they're well-formed.
- n := 0
- hasPlus := false
- for i := 0; i < len(s); {
- switch s[i] {
- case '%':
- n++
- if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {
- s = s[i:]
- if len(s) > 3 {
- s = s[:3]
- }
- return "", EscapeError(s)
- }
- // Per https://tools.ietf.org/html/rfc3986#page-21
- // in the host component %-encoding can only be used
- // for non-ASCII bytes.
- // But https://tools.ietf.org/html/rfc6874#section-2
- // introduces %25 being allowed to escape a percent sign
- // in IPv6 scoped-address literals. Yay.
- if mode == encodeHost && unhex(s[i+1]) < 8 && s[i:i+3] != "%25" {
- return "", EscapeError(s[i : i+3])
- }
- if mode == encodeZone {
- // RFC 6874 says basically "anything goes" for zone identifiers
- // and that even non-ASCII can be redundantly escaped,
- // but it seems prudent to restrict %-escaped bytes here to those
- // that are valid host name bytes in their unescaped form.
- // That is, you can use escaping in the zone identifier but not
- // to introduce bytes you couldn't just write directly.
- // But Windows puts spaces here! Yay.
- v := unhex(s[i+1])<<4 | unhex(s[i+2])
- if s[i:i+3] != "%25" && v != ' ' && shouldEscape(v, encodeHost) {
- return "", EscapeError(s[i : i+3])
- }
- }
- i += 3
- case '+':
- hasPlus = mode == encodeQueryComponent
- i++
- default:
- if (mode == encodeHost || mode == encodeZone) && s[i] < 0x80 && shouldEscape(s[i], mode) {
- return "", InvalidHostError(s[i : i+1])
- }
- i++
- }
- }
-
- if n == 0 && !hasPlus {
- return s, nil
- }
-
- var t strings.Builder
- t.Grow(len(s) - 2*n)
- for i := 0; i < len(s); i++ {
- switch s[i] {
- case '%':
- t.WriteByte(unhex(s[i+1])<<4 | unhex(s[i+2]))
- i += 2
- case '+':
- if mode == encodeQueryComponent {
- t.WriteByte(' ')
- } else {
- t.WriteByte('+')
- }
- default:
- t.WriteByte(s[i])
- }
- }
- return t.String(), nil
-}
-
-// QueryEscape escapes the string so it can be safely placed
-// inside a URL query.
-func QueryEscape(s string) string {
- return escape(s, encodeQueryComponent)
-}
-
-// PathEscape escapes the string so it can be safely placed inside a URL path segment,
-// replacing special characters (including /) with %XX sequences as needed.
-func PathEscape(s string) string {
- return escape(s, encodePathSegment)
-}
-
-func escape(s string, mode encoding) string {
- spaceCount, hexCount := 0, 0
- for i := 0; i < len(s); i++ {
- c := s[i]
- if shouldEscape(c, mode) {
- if c == ' ' && mode == encodeQueryComponent {
- spaceCount++
- } else {
- hexCount++
- }
- }
- }
-
- if spaceCount == 0 && hexCount == 0 {
- return s
- }
-
- var buf [64]byte
- var t []byte
-
- required := len(s) + 2*hexCount
- if required <= len(buf) {
- t = buf[:required]
- } else {
- t = make([]byte, required)
- }
-
- if hexCount == 0 {
- copy(t, s)
- for i := 0; i < len(s); i++ {
- if s[i] == ' ' {
- t[i] = '+'
- }
- }
- return string(t)
- }
-
- j := 0
- for i := 0; i < len(s); i++ {
- switch c := s[i]; {
- case c == ' ' && mode == encodeQueryComponent:
- t[j] = '+'
- j++
- case shouldEscape(c, mode):
- t[j] = '%'
- t[j+1] = upperhex[c>>4]
- t[j+2] = upperhex[c&15]
- j += 3
- default:
- t[j] = s[i]
- j++
- }
- }
- return string(t)
-}
-
-// A URL represents a parsed URL (technically, a URI reference).
-//
-// The general form represented is:
-//
-// [scheme:][//[userinfo@]host][/]path[?query][#fragment]
-//
-// URLs that do not start with a slash after the scheme are interpreted as:
-//
-// scheme:opaque[?query][#fragment]
-//
-// Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.
-// A consequence is that it is impossible to tell which slashes in the Path were
-// slashes in the raw URL and which were %2f. This distinction is rarely important,
-// but when it is, the code should use the EscapedPath method, which preserves
-// the original encoding of Path.
-//
-// The RawPath field is an optional field which is only set when the default
-// encoding of Path is different from the escaped path. See the EscapedPath method
-// for more details.
-//
-// URL's String method uses the EscapedPath method to obtain the path.
-type URL struct {
- Scheme string
- Opaque string // encoded opaque data
- User *Userinfo // username and password information
- Host string // host or host:port
- Path string // path (relative paths may omit leading slash)
- RawPath string // encoded path hint (see EscapedPath method)
- OmitHost bool // do not emit empty host (authority)
- ForceQuery bool // append a query ('?') even if RawQuery is empty
- RawQuery string // encoded query values, without '?'
- Fragment string // fragment for references, without '#'
- RawFragment string // encoded fragment hint (see EscapedFragment method)
-}
-
-// User returns a Userinfo containing the provided username
-// and no password set.
-func User(username string) *Userinfo {
- return &Userinfo{username, "", false}
-}
-
-// UserPassword returns a Userinfo containing the provided username
-// and password.
-//
-// This functionality should only be used with legacy web sites.
-// RFC 2396 warns that interpreting Userinfo this way
-// “is NOT RECOMMENDED, because the passing of authentication
-// information in clear text (such as URI) has proven to be a
-// security risk in almost every case where it has been used.”
-func UserPassword(username, password string) *Userinfo {
- return &Userinfo{username, password, true}
-}
-
-// The Userinfo type is an immutable encapsulation of username and
-// password details for a URL. An existing Userinfo value is guaranteed
-// to have a username set (potentially empty, as allowed by RFC 2396),
-// and optionally a password.
-type Userinfo struct {
- username string
- password string
- passwordSet bool
-}
-
-// Username returns the username.
-func (u *Userinfo) Username() string {
- if u == nil {
- return ""
- }
- return u.username
-}
-
-// Password returns the password in case it is set, and whether it is set.
-func (u *Userinfo) Password() (string, bool) {
- if u == nil {
- return "", false
- }
- return u.password, u.passwordSet
-}
-
-// String returns the encoded userinfo information in the standard form
-// of "username[:password]".
-func (u *Userinfo) String() string {
- if u == nil {
- return ""
- }
- s := escape(u.username, encodeUserPassword)
- if u.passwordSet {
- s += ":" + escape(u.password, encodeUserPassword)
- }
- return s
-}
-
-// Maybe rawURL is of the form scheme:path.
-// (Scheme must be [a-zA-Z][a-zA-Z0-9+.-]*)
-// If so, return scheme, path; else return "", rawURL.
-func getScheme(rawURL string) (scheme, path string, err error) {
- for i := 0; i < len(rawURL); i++ {
- c := rawURL[i]
- switch {
- case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
- // do nothing
- case '0' <= c && c <= '9' || c == '+' || c == '-' || c == '.':
- if i == 0 {
- return "", rawURL, nil
- }
- case c == ':':
- if i == 0 {
- return "", "", errors.New("missing protocol scheme")
- }
- return rawURL[:i], rawURL[i+1:], nil
- default:
- // we have encountered an invalid character,
- // so there is no valid scheme
- return "", rawURL, nil
- }
- }
- return "", rawURL, nil
-}
-
-// Parse parses a raw url into a URL structure.
-//
-// The url may be relative (a path, without a host) or absolute
-// (starting with a scheme). Trying to parse a hostname and path
-// without a scheme is invalid but may not necessarily return an
-// error, due to parsing ambiguities.
-func Parse(rawURL string) (*URL, error) {
- // Cut off #frag
- u, frag, _ := strings.Cut(rawURL, "#")
- url, err := parse(u, false)
- if err != nil {
- return nil, &Error{"parse", u, err}
- }
- if frag == "" {
- return url, nil
- }
- if err = url.setFragment(frag); err != nil {
- return nil, &Error{"parse", rawURL, err}
- }
- return url, nil
-}
-
-// ParseRequestURI parses a raw url into a URL structure. It assumes that
-// url was received in an HTTP request, so the url is interpreted
-// only as an absolute URI or an absolute path.
-// The string url is assumed not to have a #fragment suffix.
-// (Web browsers strip #fragment before sending the URL to a web server.)
-func ParseRequestURI(rawURL string) (*URL, error) {
- url, err := parse(rawURL, true)
- if err != nil {
- return nil, &Error{"parse", rawURL, err}
- }
- return url, nil
-}
-
-// parse parses a URL from a string in one of two contexts. If
-// viaRequest is true, the URL is assumed to have arrived via an HTTP request,
-// in which case only absolute URLs or path-absolute relative URLs are allowed.
-// If viaRequest is false, all forms of relative URLs are allowed.
-func parse(rawURL string, viaRequest bool) (*URL, error) {
- var rest string
- var err error
-
- if stringContainsCTLByte(rawURL) {
- return nil, errors.New("net/url: invalid control character in URL")
- }
-
- if rawURL == "" && viaRequest {
- return nil, errors.New("empty url")
- }
- url := new(URL)
-
- if rawURL == "*" {
- url.Path = "*"
- return url, nil
- }
-
- // Split off possible leading "http:", "mailto:", etc.
- // Cannot contain escaped characters.
- if url.Scheme, rest, err = getScheme(rawURL); err != nil {
- return nil, err
- }
- url.Scheme = strings.ToLower(url.Scheme)
-
- if strings.HasSuffix(rest, "?") && strings.Count(rest, "?") == 1 {
- url.ForceQuery = true
- rest = rest[:len(rest)-1]
- } else {
- rest, url.RawQuery, _ = strings.Cut(rest, "?")
- }
-
- if !strings.HasPrefix(rest, "/") {
- if url.Scheme != "" {
- // We consider rootless paths per RFC 3986 as opaque.
- url.Opaque = rest
- return url, nil
- }
- if viaRequest {
- return nil, errors.New("invalid URI for request")
- }
-
- // Avoid confusion with malformed schemes, like cache_object:foo/bar.
- // See golang.org/issue/16822.
- //
- // RFC 3986, §3.3:
- // In addition, a URI reference (Section 4.1) may be a relative-path reference,
- // in which case the first path segment cannot contain a colon (":") character.
- if segment, _, _ := strings.Cut(rest, "/"); strings.Contains(segment, ":") {
- // First path segment has colon. Not allowed in relative URL.
- return nil, errors.New("first path segment in URL cannot contain colon")
- }
- }
-
- if (url.Scheme != "" || !viaRequest && !strings.HasPrefix(rest, "///")) && strings.HasPrefix(rest, "//") {
- var authority string
- authority, rest = rest[2:], ""
- if i := strings.Index(authority, "/"); i >= 0 {
- authority, rest = authority[:i], authority[i:]
- }
- url.User, url.Host, err = parseAuthority(authority)
- if err != nil {
- return nil, err
- }
- } else if url.Scheme != "" && strings.HasPrefix(rest, "/") {
- // OmitHost is set to true when rawURL has an empty host (authority).
- // See golang.org/issue/46059.
- url.OmitHost = true
- }
-
- // Set Path and, optionally, RawPath.
- // RawPath is a hint of the encoding of Path. We don't want to set it if
- // the default escaping of Path is equivalent, to help make sure that people
- // don't rely on it in general.
- if err := url.setPath(rest); err != nil {
- return nil, err
- }
- return url, nil
-}
-
-func parseAuthority(authority string) (user *Userinfo, host string, err error) {
- i := strings.LastIndex(authority, "@")
- if i < 0 {
- host, err = parseHost(authority)
- } else {
- host, err = parseHost(authority[i+1:])
- }
- if err != nil {
- return nil, "", err
- }
- if i < 0 {
- return nil, host, nil
- }
- userinfo := authority[:i]
- if !validUserinfo(userinfo) {
- return nil, "", errors.New("net/url: invalid userinfo")
- }
- if !strings.Contains(userinfo, ":") {
- if userinfo, err = unescape(userinfo, encodeUserPassword); err != nil {
- return nil, "", err
- }
- user = User(userinfo)
- } else {
- username, password, _ := strings.Cut(userinfo, ":")
- if username, err = unescape(username, encodeUserPassword); err != nil {
- return nil, "", err
- }
- if password, err = unescape(password, encodeUserPassword); err != nil {
- return nil, "", err
- }
- user = UserPassword(username, password)
- }
- return user, host, nil
-}
-
-// parseHost parses host as an authority without user
-// information. That is, as host[:port].
-func parseHost(host string) (string, error) {
- if strings.HasPrefix(host, "[") {
- // Parse an IP-Literal in RFC 3986 and RFC 6874.
- // E.g., "[fe80::1]", "[fe80::1%25en0]", "[fe80::1]:80".
- i := strings.LastIndex(host, "]")
- if i < 0 {
- return "", errors.New("missing ']' in host")
- }
- colonPort := host[i+1:]
- if !validOptionalPort(colonPort) {
- return "", fmt.Errorf("invalid port %q after host", colonPort)
- }
-
- // RFC 6874 defines that %25 (%-encoded percent) introduces
- // the zone identifier, and the zone identifier can use basically
- // any %-encoding it likes. That's different from the host, which
- // can only %-encode non-ASCII bytes.
- // We do impose some restrictions on the zone, to avoid stupidity
- // like newlines.
- zone := strings.Index(host[:i], "%25")
- if zone >= 0 {
- host1, err := unescape(host[:zone], encodeHost)
- if err != nil {
- return "", err
- }
- host2, err := unescape(host[zone:i], encodeZone)
- if err != nil {
- return "", err
- }
- host3, err := unescape(host[i:], encodeHost)
- if err != nil {
- return "", err
- }
- return host1 + host2 + host3, nil
- }
- } else if i := strings.LastIndex(host, ":"); i != -1 {
- colonPort := host[i:]
- if !validOptionalPort(colonPort) {
- return "", fmt.Errorf("invalid port %q after host", colonPort)
- }
- }
-
- var err error
- if host, err = unescape(host, encodeHost); err != nil {
- return "", err
- }
- return host, nil
-}
-
-// setPath sets the Path and RawPath fields of the URL based on the provided
-// escaped path p. It maintains the invariant that RawPath is only specified
-// when it differs from the default encoding of the path.
-// For example:
-// - setPath("/foo/bar") will set Path="/foo/bar" and RawPath=""
-// - setPath("/foo%2fbar") will set Path="/foo/bar" and RawPath="/foo%2fbar"
-// setPath will return an error only if the provided path contains an invalid
-// escaping.
-func (u *URL) setPath(p string) error {
- path, err := unescape(p, encodePath)
- if err != nil {
- return err
- }
- u.Path = path
- if escp := escape(path, encodePath); p == escp {
- // Default encoding is fine.
- u.RawPath = ""
- } else {
- u.RawPath = p
- }
- return nil
-}
-
-// EscapedPath returns the escaped form of u.Path.
-// In general there are multiple possible escaped forms of any path.
-// EscapedPath returns u.RawPath when it is a valid escaping of u.Path.
-// Otherwise EscapedPath ignores u.RawPath and computes an escaped
-// form on its own.
-// The String and RequestURI methods use EscapedPath to construct
-// their results.
-// In general, code should call EscapedPath instead of
-// reading u.RawPath directly.
-func (u *URL) EscapedPath() string {
- if u.RawPath != "" && validEncoded(u.RawPath, encodePath) {
- p, err := unescape(u.RawPath, encodePath)
- if err == nil && p == u.Path {
- return u.RawPath
- }
- }
- if u.Path == "*" {
- return "*" // don't escape (Issue 11202)
- }
- return escape(u.Path, encodePath)
-}
-
-// validEncoded reports whether s is a valid encoded path or fragment,
-// according to mode.
-// It must not contain any bytes that require escaping during encoding.
-func validEncoded(s string, mode encoding) bool {
- for i := 0; i < len(s); i++ {
- // RFC 3986, Appendix A.
- // pchar = unreserved / pct-encoded / sub-delims / ":" / "@".
- // shouldEscape is not quite compliant with the RFC,
- // so we check the sub-delims ourselves and let
- // shouldEscape handle the others.
- switch s[i] {
- case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=', ':', '@':
- // ok
- case '[', ']':
- // ok - not specified in RFC 3986 but left alone by modern browsers
- case '%':
- // ok - percent encoded, will decode
- default:
- if shouldEscape(s[i], mode) {
- return false
- }
- }
- }
- return true
-}
-
-// setFragment is like setPath but for Fragment/RawFragment.
-func (u *URL) setFragment(f string) error {
- frag, err := unescape(f, encodeFragment)
- if err != nil {
- return err
- }
- u.Fragment = frag
- if escf := escape(frag, encodeFragment); f == escf {
- // Default encoding is fine.
- u.RawFragment = ""
- } else {
- u.RawFragment = f
- }
- return nil
-}
-
-// EscapedFragment returns the escaped form of u.Fragment.
-// In general there are multiple possible escaped forms of any fragment.
-// EscapedFragment returns u.RawFragment when it is a valid escaping of u.Fragment.
-// Otherwise EscapedFragment ignores u.RawFragment and computes an escaped
-// form on its own.
-// The String method uses EscapedFragment to construct its result.
-// In general, code should call EscapedFragment instead of
-// reading u.RawFragment directly.
-func (u *URL) EscapedFragment() string {
- if u.RawFragment != "" && validEncoded(u.RawFragment, encodeFragment) {
- f, err := unescape(u.RawFragment, encodeFragment)
- if err == nil && f == u.Fragment {
- return u.RawFragment
- }
- }
- return escape(u.Fragment, encodeFragment)
-}
-
-// validOptionalPort reports whether port is either an empty string
-// or matches /^:\d*$/
-func validOptionalPort(port string) bool {
- if port == "" {
- return true
- }
- if port[0] != ':' {
- return false
- }
- for _, b := range port[1:] {
- if b < '0' || b > '9' {
- return false
- }
- }
- return true
-}
-
-// String reassembles the URL into a valid URL string.
-// The general form of the result is one of:
-//
-// scheme:opaque?query#fragment
-// scheme://userinfo@host/path?query#fragment
-//
-// If u.Opaque is non-empty, String uses the first form;
-// otherwise it uses the second form.
-// Any non-ASCII characters in host are escaped.
-// To obtain the path, String uses u.EscapedPath().
-//
-// In the second form, the following rules apply:
-// - if u.Scheme is empty, scheme: is omitted.
-// - if u.User is nil, userinfo@ is omitted.
-// - if u.Host is empty, host/ is omitted.
-// - if u.Scheme and u.Host are empty and u.User is nil,
-// the entire scheme://userinfo@host/ is omitted.
-// - if u.Host is non-empty and u.Path begins with a /,
-// the form host/path does not add its own /.
-// - if u.RawQuery is empty, ?query is omitted.
-// - if u.Fragment is empty, #fragment is omitted.
-func (u *URL) String() string {
- var buf strings.Builder
- if u.Scheme != "" {
- buf.WriteString(u.Scheme)
- buf.WriteByte(':')
- }
- if u.Opaque != "" {
- buf.WriteString(u.Opaque)
- } else {
- if u.Scheme != "" || u.Host != "" || u.User != nil {
- if u.OmitHost && u.Host == "" && u.User == nil {
- // omit empty host
- } else {
- if u.Host != "" || u.Path != "" || u.User != nil {
- buf.WriteString("//")
- }
- if ui := u.User; ui != nil {
- buf.WriteString(ui.String())
- buf.WriteByte('@')
- }
- if h := u.Host; h != "" {
- buf.WriteString(escape(h, encodeHost))
- }
- }
- }
- path := u.EscapedPath()
- if path != "" && path[0] != '/' && u.Host != "" {
- buf.WriteByte('/')
- }
- if buf.Len() == 0 {
- // RFC 3986 §4.2
- // A path segment that contains a colon character (e.g., "this:that")
- // cannot be used as the first segment of a relative-path reference, as
- // it would be mistaken for a scheme name. Such a segment must be
- // preceded by a dot-segment (e.g., "./this:that") to make a relative-
- // path reference.
- if segment, _, _ := strings.Cut(path, "/"); strings.Contains(segment, ":") {
- buf.WriteString("./")
- }
- }
- buf.WriteString(path)
- }
- if u.ForceQuery || u.RawQuery != "" {
- buf.WriteByte('?')
- buf.WriteString(u.RawQuery)
- }
- if u.Fragment != "" {
- buf.WriteByte('#')
- buf.WriteString(u.EscapedFragment())
- }
- return buf.String()
-}
-
-// Redacted is like String but replaces any password with "xxxxx".
-// Only the password in u.URL is redacted.
-func (u *URL) Redacted() string {
- if u == nil {
- return ""
- }
-
- ru := *u
- if _, has := ru.User.Password(); has {
- ru.User = UserPassword(ru.User.Username(), "xxxxx")
- }
- return ru.String()
-}
-
-// Values maps a string key to a list of values.
-// It is typically used for query parameters and form values.
-// Unlike in the http.Header map, the keys in a Values map
-// are case-sensitive.
-type Values map[string][]string
-
-// Get gets the first value associated with the given key.
-// If there are no values associated with the key, Get returns
-// the empty string. To access multiple values, use the map
-// directly.
-func (v Values) Get(key string) string {
- if v == nil {
- return ""
- }
- vs := v[key]
- if len(vs) == 0 {
- return ""
- }
- return vs[0]
-}
-
-// Set sets the key to value. It replaces any existing
-// values.
-func (v Values) Set(key, value string) {
- v[key] = []string{value}
-}
-
-// Add adds the value to key. It appends to any existing
-// values associated with key.
-func (v Values) Add(key, value string) {
- v[key] = append(v[key], value)
-}
-
-// Del deletes the values associated with key.
-func (v Values) Del(key string) {
- delete(v, key)
-}
-
-// Has checks whether a given key is set.
-func (v Values) Has(key string) bool {
- _, ok := v[key]
- return ok
-}
-
-// ParseQuery parses the URL-encoded query string and returns
-// a map listing the values specified for each key.
-// ParseQuery always returns a non-nil map containing all the
-// valid query parameters found; err describes the first decoding error
-// encountered, if any.
-//
-// Query is expected to be a list of key=value settings separated by ampersands.
-// A setting without an equals sign is interpreted as a key set to an empty
-// value.
-// Settings containing a non-URL-encoded semicolon are considered invalid.
-func ParseQuery(query string) (Values, error) {
- m := make(Values)
- err := parseQuery(m, query)
- return m, err
-}
-
-func parseQuery(m Values, query string) (err error) {
- for query != "" {
- var key string
- key, query, _ = strings.Cut(query, "&")
- if strings.Contains(key, ";") {
- err = fmt.Errorf("invalid semicolon separator in query")
- continue
- }
- if key == "" {
- continue
- }
- key, value, _ := strings.Cut(key, "=")
- key, err1 := QueryUnescape(key)
- if err1 != nil {
- if err == nil {
- err = err1
- }
- continue
- }
- value, err1 = QueryUnescape(value)
- if err1 != nil {
- if err == nil {
- err = err1
- }
- continue
- }
- m[key] = append(m[key], value)
- }
- return err
-}
-
-// Encode encodes the values into “URL encoded” form
-// ("bar=baz&foo=quux") sorted by key.
-func (v Values) Encode() string {
- if v == nil {
- return ""
- }
- var buf strings.Builder
- keys := make([]string, 0, len(v))
- for k := range v {
- keys = append(keys, k)
- }
- sort.Strings(keys)
- for _, k := range keys {
- vs := v[k]
- keyEscaped := QueryEscape(k)
- for _, v := range vs {
- if buf.Len() > 0 {
- buf.WriteByte('&')
- }
- buf.WriteString(keyEscaped)
- buf.WriteByte('=')
- buf.WriteString(QueryEscape(v))
- }
- }
- return buf.String()
-}
-
-// resolvePath applies special path segments from refs and applies
-// them to base, per RFC 3986.
-func resolvePath(base, ref string) string {
- var full string
- if ref == "" {
- full = base
- } else if ref[0] != '/' {
- i := strings.LastIndex(base, "/")
- full = base[:i+1] + ref
- } else {
- full = ref
- }
- if full == "" {
- return ""
- }
-
- var (
- elem string
- dst strings.Builder
- )
- first := true
- remaining := full
- // We want to return a leading '/', so write it now.
- dst.WriteByte('/')
- found := true
- for found {
- elem, remaining, found = strings.Cut(remaining, "/")
- if elem == "." {
- first = false
- // drop
- continue
- }
-
- if elem == ".." {
- // Ignore the leading '/' we already wrote.
- str := dst.String()[1:]
- index := strings.LastIndexByte(str, '/')
-
- dst.Reset()
- dst.WriteByte('/')
- if index == -1 {
- first = true
- } else {
- dst.WriteString(str[:index])
- }
- } else {
- if !first {
- dst.WriteByte('/')
- }
- dst.WriteString(elem)
- first = false
- }
- }
-
- if elem == "." || elem == ".." {
- dst.WriteByte('/')
- }
-
- // We wrote an initial '/', but we don't want two.
- r := dst.String()
- if len(r) > 1 && r[1] == '/' {
- r = r[1:]
- }
- return r
-}
-
-// IsAbs reports whether the URL is absolute.
-// Absolute means that it has a non-empty scheme.
-func (u *URL) IsAbs() bool {
- return u.Scheme != ""
-}
-
-// Parse parses a URL in the context of the receiver. The provided URL
-// may be relative or absolute. Parse returns nil, err on parse
-// failure, otherwise its return value is the same as ResolveReference.
-func (u *URL) Parse(ref string) (*URL, error) {
- refURL, err := Parse(ref)
- if err != nil {
- return nil, err
- }
- return u.ResolveReference(refURL), nil
-}
-
-// ResolveReference resolves a URI reference to an absolute URI from
-// an absolute base URI u, per RFC 3986 Section 5.2. The URI reference
-// may be relative or absolute. ResolveReference always returns a new
-// URL instance, even if the returned URL is identical to either the
-// base or reference. If ref is an absolute URL, then ResolveReference
-// ignores base and returns a copy of ref.
-func (u *URL) ResolveReference(ref *URL) *URL {
- url := *ref
- if ref.Scheme == "" {
- url.Scheme = u.Scheme
- }
- if ref.Scheme != "" || ref.Host != "" || ref.User != nil {
- // The "absoluteURI" or "net_path" cases.
- // We can ignore the error from setPath since we know we provided a
- // validly-escaped path.
- url.setPath(resolvePath(ref.EscapedPath(), ""))
- return &url
- }
- if ref.Opaque != "" {
- url.User = nil
- url.Host = ""
- url.Path = ""
- return &url
- }
- if ref.Path == "" && !ref.ForceQuery && ref.RawQuery == "" {
- url.RawQuery = u.RawQuery
- if ref.Fragment == "" {
- url.Fragment = u.Fragment
- url.RawFragment = u.RawFragment
- }
- }
- // The "abs_path" or "rel_path" cases.
- url.Host = u.Host
- url.User = u.User
- url.setPath(resolvePath(u.EscapedPath(), ref.EscapedPath()))
- return &url
-}
-
-// Query parses RawQuery and returns the corresponding values.
-// It silently discards malformed value pairs.
-// To check errors use ParseQuery.
-func (u *URL) Query() Values {
- v, _ := ParseQuery(u.RawQuery)
- return v
-}
-
-// RequestURI returns the encoded path?query or opaque?query
-// string that would be used in an HTTP request for u.
-func (u *URL) RequestURI() string {
- result := u.Opaque
- if result == "" {
- result = u.EscapedPath()
- if result == "" {
- result = "/"
- }
- } else {
- if strings.HasPrefix(result, "//") {
- result = u.Scheme + ":" + result
- }
- }
- if u.ForceQuery || u.RawQuery != "" {
- result += "?" + u.RawQuery
- }
- return result
-}
-
-// Hostname returns u.Host, stripping any valid port number if present.
-//
-// If the result is enclosed in square brackets, as literal IPv6 addresses are,
-// the square brackets are removed from the result.
-func (u *URL) Hostname() string {
- host, _ := splitHostPort(u.Host)
- return host
-}
-
-// Port returns the port part of u.Host, without the leading colon.
-//
-// If u.Host doesn't contain a valid numeric port, Port returns an empty string.
-func (u *URL) Port() string {
- _, port := splitHostPort(u.Host)
- return port
-}
-
-// splitHostPort separates host and port. If the port is not valid, it returns
-// the entire input as host, and it doesn't check the validity of the host.
-// Unlike net.SplitHostPort, but per RFC 3986, it requires ports to be numeric.
-func splitHostPort(hostPort string) (host, port string) {
- host = hostPort
-
- colon := strings.LastIndexByte(host, ':')
- if colon != -1 && validOptionalPort(host[colon:]) {
- host, port = host[:colon], host[colon+1:]
- }
-
- if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
- host = host[1 : len(host)-1]
- }
-
- return
-}
-
-// Marshaling interface implementations.
-// Would like to implement MarshalText/UnmarshalText but that will change the JSON representation of URLs.
-
-func (u *URL) MarshalBinary() (text []byte, err error) {
- return []byte(u.String()), nil
-}
-
-func (u *URL) UnmarshalBinary(text []byte) error {
- u1, err := Parse(string(text))
- if err != nil {
- return err
- }
- *u = *u1
- return nil
-}
-
-// JoinPath returns a new URL with the provided path elements joined to
-// any existing path and the resulting path cleaned of any ./ or ../ elements.
-// Any sequences of multiple / characters will be reduced to a single /.
-func (u *URL) JoinPath(elem ...string) *URL {
- elem = append([]string{u.EscapedPath()}, elem...)
- var p string
- if !strings.HasPrefix(elem[0], "/") {
- // Return a relative path if u is relative,
- // but ensure that it contains no ../ elements.
- elem[0] = "/" + elem[0]
- p = path.Join(elem...)[1:]
- } else {
- p = path.Join(elem...)
- }
- // path.Join will remove any trailing slashes.
- // Preserve at least one.
- if strings.HasSuffix(elem[len(elem)-1], "/") && !strings.HasSuffix(p, "/") {
- p += "/"
- }
- url := *u
- url.setPath(p)
- return &url
-}
-
-// validUserinfo reports whether s is a valid userinfo string per RFC 3986
-// Section 3.2.1:
-//
-// userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
-// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
-// sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
-// / "*" / "+" / "," / ";" / "="
-//
-// It doesn't validate pct-encoded. The caller does that via func unescape.
-func validUserinfo(s string) bool {
- for _, r := range s {
- if 'A' <= r && r <= 'Z' {
- continue
- }
- if 'a' <= r && r <= 'z' {
- continue
- }
- if '0' <= r && r <= '9' {
- continue
- }
- switch r {
- case '-', '.', '_', ':', '~', '!', '$', '&', '\'',
- '(', ')', '*', '+', ',', ';', '=', '%', '@':
- continue
- default:
- return false
- }
- }
- return true
-}
-
-// stringContainsCTLByte reports whether s contains any ASCII control character.
-func stringContainsCTLByte(s string) bool {
- for i := 0; i < len(s); i++ {
- b := s[i]
- if b < ' ' || b == 0x7f {
- return true
- }
- }
- return false
-}
-
-// JoinPath returns a URL string with the provided path elements joined to
-// the existing path of base and the resulting path cleaned of any ./ or ../ elements.
-func JoinPath(base string, elem ...string) (result string, err error) {
- url, err := Parse(base)
- if err != nil {
- return
- }
- result = url.JoinPath(elem...).String()
- return
-}
diff --git a/contrib/go/_std_1.20/src/net/url/ya.make b/contrib/go/_std_1.20/src/net/url/ya.make
deleted file mode 100644
index 7eba52c30f..0000000000
--- a/contrib/go/_std_1.20/src/net/url/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- url.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/net/ya.make b/contrib/go/_std_1.20/src/net/ya.make
deleted file mode 100644
index 97aa726a2e..0000000000
--- a/contrib/go/_std_1.20/src/net/ya.make
+++ /dev/null
@@ -1,149 +0,0 @@
-GO_LIBRARY()
-
-NO_COMPILER_WARNINGS()
-
-SRCS(
- addrselect.go
- conf.go
- dial.go
- dnsclient.go
- dnsclient_unix.go
- dnsconfig.go
- error_posix.go
- fd_posix.go
- file.go
- hook.go
- hosts.go
- interface.go
- ip.go
- iprawsock.go
- iprawsock_posix.go
- ipsock.go
- ipsock_posix.go
- lookup.go
- mac.go
- net.go
- nss.go
- parse.go
- pipe.go
- port.go
- rawconn.go
- sock_posix.go
- sockaddr_posix.go
- sockopt_posix.go
- sockoptip_posix.go
- tcpsock.go
- tcpsock_posix.go
- tcpsockopt_posix.go
- udpsock.go
- udpsock_posix.go
- unixsock.go
- unixsock_posix.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- cgo_darwin.go
- cgo_unix.go
- cgo_unix_syscall.go
- dnsconfig_unix.go
- error_unix.go
- fd_unix.go
- file_unix.go
- hook_unix.go
- interface_bsd.go
- interface_darwin.go
- lookup_unix.go
- port_unix.go
- sendfile_unix_alt.go
- sock_bsd.go
- sockopt_bsd.go
- sockoptip_bsdvar.go
- splice_stub.go
- sys_cloexec.go
- tcpsockopt_darwin.go
- unixsock_readmsg_cloexec.go
- writev_unix.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- dnsconfig_unix.go
- error_unix.go
- fd_unix.go
- file_unix.go
- hook_unix.go
- interface_linux.go
- lookup_unix.go
- port_unix.go
- sendfile_linux.go
- sock_cloexec.go
- sock_linux.go
- sockopt_linux.go
- sockoptip_linux.go
- splice_linux.go
- tcpsockopt_unix.go
- unixsock_readmsg_cmsg_cloexec.go
- writev_unix.go
- )
-ENDIF()
-
-IF (CGO_ENABLED)
- IF(OS_LINUX)
- CGO_LDFLAGS(
- -lresolv
- )
-
- SRCS(
- cgo_unix.go
- )
-
- CGO_SRCS(
- cgo_linux.go
- cgo_resnew.go
- cgo_socknew.go
- cgo_unix_cgo.go
- cgo_unix_cgo_res.go
- )
- ENDIF()
-ELSE()
- IF(OS_LINUX)
- SRCS(
- cgo_stub.go
- )
- ENDIF()
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- cgo_windows.go
- dnsconfig_windows.go
- error_windows.go
- fd_windows.go
- file_windows.go
- hook_windows.go
- interface_windows.go
- lookup_windows.go
- sendfile_windows.go
- sock_windows.go
- sockopt_windows.go
- sockoptip_windows.go
- splice_stub.go
- tcpsockopt_windows.go
- unixsock_readmsg_other.go
- )
-ENDIF()
-
-END()
-
-RECURSE(
- http
- internal
- mail
- netip
- rpc
- smtp
- textproto
- url
-)
diff --git a/contrib/go/_std_1.20/src/os/dir_darwin.go b/contrib/go/_std_1.20/src/os/dir_darwin.go
deleted file mode 100644
index deba3eb37f..0000000000
--- a/contrib/go/_std_1.20/src/os/dir_darwin.go
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2009 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 os
-
-import (
- "io"
- "runtime"
- "syscall"
- "unsafe"
-)
-
-// Auxiliary information if the File describes a directory
-type dirInfo struct {
- dir uintptr // Pointer to DIR structure from dirent.h
-}
-
-func (d *dirInfo) close() {
- if d.dir == 0 {
- return
- }
- closedir(d.dir)
- d.dir = 0
-}
-
-func (f *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEntry, infos []FileInfo, err error) {
- if f.dirinfo == nil {
- dir, call, errno := f.pfd.OpenDir()
- if errno != nil {
- return nil, nil, nil, &PathError{Op: call, Path: f.name, Err: errno}
- }
- f.dirinfo = &dirInfo{
- dir: dir,
- }
- }
- d := f.dirinfo
-
- size := n
- if size <= 0 {
- size = 100
- n = -1
- }
-
- var dirent syscall.Dirent
- var entptr *syscall.Dirent
- for len(names)+len(dirents)+len(infos) < size || n == -1 {
- if errno := readdir_r(d.dir, &dirent, &entptr); errno != 0 {
- if errno == syscall.EINTR {
- continue
- }
- return names, dirents, infos, &PathError{Op: "readdir", Path: f.name, Err: errno}
- }
- if entptr == nil { // EOF
- break
- }
- if dirent.Ino == 0 {
- continue
- }
- name := (*[len(syscall.Dirent{}.Name)]byte)(unsafe.Pointer(&dirent.Name))[:]
- for i, c := range name {
- if c == 0 {
- name = name[:i]
- break
- }
- }
- // Check for useless names before allocating a string.
- if string(name) == "." || string(name) == ".." {
- continue
- }
- if mode == readdirName {
- names = append(names, string(name))
- } else if mode == readdirDirEntry {
- de, err := newUnixDirent(f.name, string(name), dtToType(dirent.Type))
- if IsNotExist(err) {
- // File disappeared between readdir and stat.
- // Treat as if it didn't exist.
- continue
- }
- if err != nil {
- return nil, dirents, nil, err
- }
- dirents = append(dirents, de)
- } else {
- info, err := lstat(f.name + "/" + string(name))
- if IsNotExist(err) {
- // File disappeared between readdir + stat.
- // Treat as if it didn't exist.
- continue
- }
- if err != nil {
- return nil, nil, infos, err
- }
- infos = append(infos, info)
- }
- runtime.KeepAlive(f)
- }
-
- if n > 0 && len(names)+len(dirents)+len(infos) == 0 {
- return nil, nil, nil, io.EOF
- }
- return names, dirents, infos, nil
-}
-
-func dtToType(typ uint8) FileMode {
- switch typ {
- case syscall.DT_BLK:
- return ModeDevice
- case syscall.DT_CHR:
- return ModeDevice | ModeCharDevice
- case syscall.DT_DIR:
- return ModeDir
- case syscall.DT_FIFO:
- return ModeNamedPipe
- case syscall.DT_LNK:
- return ModeSymlink
- case syscall.DT_REG:
- return 0
- case syscall.DT_SOCK:
- return ModeSocket
- }
- return ^FileMode(0)
-}
-
-// Implemented in syscall/syscall_darwin.go.
-
-//go:linkname closedir syscall.closedir
-func closedir(dir uintptr) (err error)
-
-//go:linkname readdir_r syscall.readdir_r
-func readdir_r(dir uintptr, entry *syscall.Dirent, result **syscall.Dirent) (res syscall.Errno)
diff --git a/contrib/go/_std_1.20/src/os/dir_unix.go b/contrib/go/_std_1.20/src/os/dir_unix.go
deleted file mode 100644
index 9b3871a3e8..0000000000
--- a/contrib/go/_std_1.20/src/os/dir_unix.go
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2009 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.
-
-//go:build aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
-
-package os
-
-import (
- "io"
- "runtime"
- "sync"
- "syscall"
- "unsafe"
-)
-
-// Auxiliary information if the File describes a directory
-type dirInfo struct {
- buf *[]byte // buffer for directory I/O
- nbuf int // length of buf; return value from Getdirentries
- bufp int // location of next record in buf.
-}
-
-const (
- // More than 5760 to work around https://golang.org/issue/24015.
- blockSize = 8192
-)
-
-var dirBufPool = sync.Pool{
- New: func() any {
- // The buffer must be at least a block long.
- buf := make([]byte, blockSize)
- return &buf
- },
-}
-
-func (d *dirInfo) close() {
- if d.buf != nil {
- dirBufPool.Put(d.buf)
- d.buf = nil
- }
-}
-
-func (f *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEntry, infos []FileInfo, err error) {
- // If this file has no dirinfo, create one.
- if f.dirinfo == nil {
- f.dirinfo = new(dirInfo)
- f.dirinfo.buf = dirBufPool.Get().(*[]byte)
- }
- d := f.dirinfo
-
- // Change the meaning of n for the implementation below.
- //
- // The n above was for the public interface of "if n <= 0,
- // Readdir returns all the FileInfo from the directory in a
- // single slice".
- //
- // But below, we use only negative to mean looping until the
- // end and positive to mean bounded, with positive
- // terminating at 0.
- if n == 0 {
- n = -1
- }
-
- for n != 0 {
- // Refill the buffer if necessary
- if d.bufp >= d.nbuf {
- d.bufp = 0
- var errno error
- d.nbuf, errno = f.pfd.ReadDirent(*d.buf)
- runtime.KeepAlive(f)
- if errno != nil {
- return names, dirents, infos, &PathError{Op: "readdirent", Path: f.name, Err: errno}
- }
- if d.nbuf <= 0 {
- break // EOF
- }
- }
-
- // Drain the buffer
- buf := (*d.buf)[d.bufp:d.nbuf]
- reclen, ok := direntReclen(buf)
- if !ok || reclen > uint64(len(buf)) {
- break
- }
- rec := buf[:reclen]
- d.bufp += int(reclen)
- ino, ok := direntIno(rec)
- if !ok {
- break
- }
- if ino == 0 {
- continue
- }
- const namoff = uint64(unsafe.Offsetof(syscall.Dirent{}.Name))
- namlen, ok := direntNamlen(rec)
- if !ok || namoff+namlen > uint64(len(rec)) {
- break
- }
- name := rec[namoff : namoff+namlen]
- for i, c := range name {
- if c == 0 {
- name = name[:i]
- break
- }
- }
- // Check for useless names before allocating a string.
- if string(name) == "." || string(name) == ".." {
- continue
- }
- if n > 0 { // see 'n == 0' comment above
- n--
- }
- if mode == readdirName {
- names = append(names, string(name))
- } else if mode == readdirDirEntry {
- de, err := newUnixDirent(f.name, string(name), direntType(rec))
- if IsNotExist(err) {
- // File disappeared between readdir and stat.
- // Treat as if it didn't exist.
- continue
- }
- if err != nil {
- return nil, dirents, nil, err
- }
- dirents = append(dirents, de)
- } else {
- info, err := lstat(f.name + "/" + string(name))
- if IsNotExist(err) {
- // File disappeared between readdir + stat.
- // Treat as if it didn't exist.
- continue
- }
- if err != nil {
- return nil, nil, infos, err
- }
- infos = append(infos, info)
- }
- }
-
- if n > 0 && len(names)+len(dirents)+len(infos) == 0 {
- return nil, nil, nil, io.EOF
- }
- return names, dirents, infos, nil
-}
-
-// readInt returns the size-bytes unsigned integer in native byte order at offset off.
-func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
- if len(b) < int(off+size) {
- return 0, false
- }
- if isBigEndian {
- return readIntBE(b[off:], size), true
- }
- return readIntLE(b[off:], size), true
-}
-
-func readIntBE(b []byte, size uintptr) uint64 {
- switch size {
- case 1:
- return uint64(b[0])
- case 2:
- _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[1]) | uint64(b[0])<<8
- case 4:
- _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24
- case 8:
- _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
- uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
- default:
- panic("syscall: readInt with unsupported size")
- }
-}
-
-func readIntLE(b []byte, size uintptr) uint64 {
- switch size {
- case 1:
- return uint64(b[0])
- case 2:
- _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[0]) | uint64(b[1])<<8
- case 4:
- _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
- case 8:
- _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
- uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
- default:
- panic("syscall: readInt with unsupported size")
- }
-}
diff --git a/contrib/go/_std_1.20/src/os/dir_windows.go b/contrib/go/_std_1.20/src/os/dir_windows.go
deleted file mode 100644
index 445e4f7c4f..0000000000
--- a/contrib/go/_std_1.20/src/os/dir_windows.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2009 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 os
-
-import (
- "io"
- "runtime"
- "syscall"
-)
-
-func (file *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEntry, infos []FileInfo, err error) {
- // If this file has no dirinfo, create one.
- needdata := true
- if file.dirinfo == nil {
- needdata = false
- file.dirinfo, err = openDir(file.name)
- if err != nil {
- err = &PathError{Op: "readdir", Path: file.name, Err: err}
- return
- }
- }
- wantAll := n <= 0
- if wantAll {
- n = -1
- }
- d := &file.dirinfo.data
- for n != 0 && !file.dirinfo.isempty {
- if needdata {
- e := syscall.FindNextFile(file.dirinfo.h, d)
- runtime.KeepAlive(file)
- if e != nil {
- if e == syscall.ERROR_NO_MORE_FILES {
- break
- } else {
- err = &PathError{Op: "FindNextFile", Path: file.name, Err: e}
- return
- }
- }
- }
- needdata = true
- name := syscall.UTF16ToString(d.FileName[0:])
- if name == "." || name == ".." { // Useless names
- continue
- }
- if mode == readdirName {
- names = append(names, name)
- } else {
- f := newFileStatFromWin32finddata(d)
- f.name = name
- f.path = file.dirinfo.path
- f.appendNameToPath = true
- if mode == readdirDirEntry {
- dirents = append(dirents, dirEntry{f})
- } else {
- infos = append(infos, f)
- }
- }
- n--
- }
- if !wantAll && len(names)+len(dirents)+len(infos) == 0 {
- return nil, nil, nil, io.EOF
- }
- return names, dirents, infos, nil
-}
-
-type dirEntry struct {
- fs *fileStat
-}
-
-func (de dirEntry) Name() string { return de.fs.Name() }
-func (de dirEntry) IsDir() bool { return de.fs.IsDir() }
-func (de dirEntry) Type() FileMode { return de.fs.Mode().Type() }
-func (de dirEntry) Info() (FileInfo, error) { return de.fs, nil }
diff --git a/contrib/go/_std_1.20/src/os/error.go b/contrib/go/_std_1.20/src/os/error.go
deleted file mode 100644
index 9827446e65..0000000000
--- a/contrib/go/_std_1.20/src/os/error.go
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2009 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 os
-
-import (
- "internal/poll"
- "io/fs"
-)
-
-// Portable analogs of some common system call errors.
-//
-// Errors returned from this package may be tested against these errors
-// with errors.Is.
-var (
- // ErrInvalid indicates an invalid argument.
- // Methods on File will return this error when the receiver is nil.
- ErrInvalid = fs.ErrInvalid // "invalid argument"
-
- ErrPermission = fs.ErrPermission // "permission denied"
- ErrExist = fs.ErrExist // "file already exists"
- ErrNotExist = fs.ErrNotExist // "file does not exist"
- ErrClosed = fs.ErrClosed // "file already closed"
-
- ErrNoDeadline = errNoDeadline() // "file type does not support deadline"
- ErrDeadlineExceeded = errDeadlineExceeded() // "i/o timeout"
-)
-
-func errNoDeadline() error { return poll.ErrNoDeadline }
-
-// errDeadlineExceeded returns the value for os.ErrDeadlineExceeded.
-// This error comes from the internal/poll package, which is also
-// used by package net. Doing this this way ensures that the net
-// package will return os.ErrDeadlineExceeded for an exceeded deadline,
-// as documented by net.Conn.SetDeadline, without requiring any extra
-// work in the net package and without requiring the internal/poll
-// package to import os (which it can't, because that would be circular).
-func errDeadlineExceeded() error { return poll.ErrDeadlineExceeded }
-
-type timeout interface {
- Timeout() bool
-}
-
-// PathError records an error and the operation and file path that caused it.
-type PathError = fs.PathError
-
-// SyscallError records an error from a specific system call.
-type SyscallError struct {
- Syscall string
- Err error
-}
-
-func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Err.Error() }
-
-func (e *SyscallError) Unwrap() error { return e.Err }
-
-// Timeout reports whether this error represents a timeout.
-func (e *SyscallError) Timeout() bool {
- t, ok := e.Err.(timeout)
- return ok && t.Timeout()
-}
-
-// NewSyscallError returns, as an error, a new SyscallError
-// with the given system call name and error details.
-// As a convenience, if err is nil, NewSyscallError returns nil.
-func NewSyscallError(syscall string, err error) error {
- if err == nil {
- return nil
- }
- return &SyscallError{syscall, err}
-}
-
-// IsExist returns a boolean indicating whether the error is known to report
-// that a file or directory already exists. It is satisfied by ErrExist as
-// well as some syscall errors.
-//
-// This function predates errors.Is. It only supports errors returned by
-// the os package. New code should use errors.Is(err, fs.ErrExist).
-func IsExist(err error) bool {
- return underlyingErrorIs(err, ErrExist)
-}
-
-// IsNotExist returns a boolean indicating whether the error is known to
-// report that a file or directory does not exist. It is satisfied by
-// ErrNotExist as well as some syscall errors.
-//
-// This function predates errors.Is. It only supports errors returned by
-// the os package. New code should use errors.Is(err, fs.ErrNotExist).
-func IsNotExist(err error) bool {
- return underlyingErrorIs(err, ErrNotExist)
-}
-
-// IsPermission returns a boolean indicating whether the error is known to
-// report that permission is denied. It is satisfied by ErrPermission as well
-// as some syscall errors.
-//
-// This function predates errors.Is. It only supports errors returned by
-// the os package. New code should use errors.Is(err, fs.ErrPermission).
-func IsPermission(err error) bool {
- return underlyingErrorIs(err, ErrPermission)
-}
-
-// IsTimeout returns a boolean indicating whether the error is known
-// to report that a timeout occurred.
-//
-// This function predates errors.Is, and the notion of whether an
-// error indicates a timeout can be ambiguous. For example, the Unix
-// error EWOULDBLOCK sometimes indicates a timeout and sometimes does not.
-// New code should use errors.Is with a value appropriate to the call
-// returning the error, such as os.ErrDeadlineExceeded.
-func IsTimeout(err error) bool {
- terr, ok := underlyingError(err).(timeout)
- return ok && terr.Timeout()
-}
-
-func underlyingErrorIs(err, target error) bool {
- // Note that this function is not errors.Is:
- // underlyingError only unwraps the specific error-wrapping types
- // that it historically did, not all errors implementing Unwrap().
- err = underlyingError(err)
- if err == target {
- return true
- }
- // To preserve prior behavior, only examine syscall errors.
- e, ok := err.(syscallErrorType)
- return ok && e.Is(target)
-}
-
-// underlyingError returns the underlying error for known os error types.
-func underlyingError(err error) error {
- switch err := err.(type) {
- case *PathError:
- return err.Err
- case *LinkError:
- return err.Err
- case *SyscallError:
- return err.Err
- }
- return err
-}
diff --git a/contrib/go/_std_1.20/src/os/error_posix.go b/contrib/go/_std_1.20/src/os/error_posix.go
deleted file mode 100644
index 5ca2e60e5b..0000000000
--- a/contrib/go/_std_1.20/src/os/error_posix.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2017 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.
-
-//go:build unix || (js && wasm) || windows
-
-package os
-
-import "syscall"
-
-// wrapSyscallError takes an error and a syscall name. If the error is
-// a syscall.Errno, it wraps it in a os.SyscallError using the syscall name.
-func wrapSyscallError(name string, err error) error {
- if _, ok := err.(syscall.Errno); ok {
- err = NewSyscallError(name, err)
- }
- return err
-}
diff --git a/contrib/go/_std_1.20/src/os/exec.go b/contrib/go/_std_1.20/src/os/exec.go
deleted file mode 100644
index d01ca592ba..0000000000
--- a/contrib/go/_std_1.20/src/os/exec.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2009 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 os
-
-import (
- "errors"
- "internal/testlog"
- "runtime"
- "sync"
- "sync/atomic"
- "syscall"
- "time"
-)
-
-// ErrProcessDone indicates a Process has finished.
-var ErrProcessDone = errors.New("os: process already finished")
-
-// Process stores the information about a process created by StartProcess.
-type Process struct {
- Pid int
- handle uintptr // handle is accessed atomically on Windows
- isdone atomic.Bool // process has been successfully waited on
- sigMu sync.RWMutex // avoid race between wait and signal
-}
-
-func newProcess(pid int, handle uintptr) *Process {
- p := &Process{Pid: pid, handle: handle}
- runtime.SetFinalizer(p, (*Process).Release)
- return p
-}
-
-func (p *Process) setDone() {
- p.isdone.Store(true)
-}
-
-func (p *Process) done() bool {
- return p.isdone.Load()
-}
-
-// ProcAttr holds the attributes that will be applied to a new process
-// started by StartProcess.
-type ProcAttr struct {
- // If Dir is non-empty, the child changes into the directory before
- // creating the process.
- Dir string
- // If Env is non-nil, it gives the environment variables for the
- // new process in the form returned by Environ.
- // If it is nil, the result of Environ will be used.
- Env []string
- // Files specifies the open files inherited by the new process. The
- // first three entries correspond to standard input, standard output, and
- // standard error. An implementation may support additional entries,
- // depending on the underlying operating system. A nil entry corresponds
- // to that file being closed when the process starts.
- // On Unix systems, StartProcess will change these File values
- // to blocking mode, which means that SetDeadline will stop working
- // and calling Close will not interrupt a Read or Write.
- Files []*File
-
- // Operating system-specific process creation attributes.
- // Note that setting this field means that your program
- // may not execute properly or even compile on some
- // operating systems.
- Sys *syscall.SysProcAttr
-}
-
-// A Signal represents an operating system signal.
-// The usual underlying implementation is operating system-dependent:
-// on Unix it is syscall.Signal.
-type Signal interface {
- String() string
- Signal() // to distinguish from other Stringers
-}
-
-// Getpid returns the process id of the caller.
-func Getpid() int { return syscall.Getpid() }
-
-// Getppid returns the process id of the caller's parent.
-func Getppid() int { return syscall.Getppid() }
-
-// FindProcess looks for a running process by its pid.
-//
-// The Process it returns can be used to obtain information
-// about the underlying operating system process.
-//
-// On Unix systems, FindProcess always succeeds and returns a Process
-// for the given pid, regardless of whether the process exists.
-func FindProcess(pid int) (*Process, error) {
- return findProcess(pid)
-}
-
-// StartProcess starts a new process with the program, arguments and attributes
-// specified by name, argv and attr. The argv slice will become os.Args in the
-// new process, so it normally starts with the program name.
-//
-// If the calling goroutine has locked the operating system thread
-// with runtime.LockOSThread and modified any inheritable OS-level
-// thread state (for example, Linux or Plan 9 name spaces), the new
-// process will inherit the caller's thread state.
-//
-// StartProcess is a low-level interface. The os/exec package provides
-// higher-level interfaces.
-//
-// If there is an error, it will be of type *PathError.
-func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error) {
- testlog.Open(name)
- return startProcess(name, argv, attr)
-}
-
-// Release releases any resources associated with the Process p,
-// rendering it unusable in the future.
-// Release only needs to be called if Wait is not.
-func (p *Process) Release() error {
- return p.release()
-}
-
-// Kill causes the Process to exit immediately. Kill does not wait until
-// the Process has actually exited. This only kills the Process itself,
-// not any other processes it may have started.
-func (p *Process) Kill() error {
- return p.kill()
-}
-
-// Wait waits for the Process to exit, and then returns a
-// ProcessState describing its status and an error, if any.
-// Wait releases any resources associated with the Process.
-// On most operating systems, the Process must be a child
-// of the current process or an error will be returned.
-func (p *Process) Wait() (*ProcessState, error) {
- return p.wait()
-}
-
-// Signal sends a signal to the Process.
-// Sending Interrupt on Windows is not implemented.
-func (p *Process) Signal(sig Signal) error {
- return p.signal(sig)
-}
-
-// UserTime returns the user CPU time of the exited process and its children.
-func (p *ProcessState) UserTime() time.Duration {
- return p.userTime()
-}
-
-// SystemTime returns the system CPU time of the exited process and its children.
-func (p *ProcessState) SystemTime() time.Duration {
- return p.systemTime()
-}
-
-// Exited reports whether the program has exited.
-// On Unix systems this reports true if the program exited due to calling exit,
-// but false if the program terminated due to a signal.
-func (p *ProcessState) Exited() bool {
- return p.exited()
-}
-
-// Success reports whether the program exited successfully,
-// such as with exit status 0 on Unix.
-func (p *ProcessState) Success() bool {
- return p.success()
-}
-
-// Sys returns system-dependent exit information about
-// the process. Convert it to the appropriate underlying
-// type, such as syscall.WaitStatus on Unix, to access its contents.
-func (p *ProcessState) Sys() any {
- return p.sys()
-}
-
-// SysUsage returns system-dependent resource usage information about
-// the exited process. Convert it to the appropriate underlying
-// type, such as *syscall.Rusage on Unix, to access its contents.
-// (On Unix, *syscall.Rusage matches struct rusage as defined in the
-// getrusage(2) manual page.)
-func (p *ProcessState) SysUsage() any {
- return p.sysUsage()
-}
diff --git a/contrib/go/_std_1.20/src/os/exec/exec.go b/contrib/go/_std_1.20/src/os/exec/exec.go
deleted file mode 100644
index 2f4bdffe9c..0000000000
--- a/contrib/go/_std_1.20/src/os/exec/exec.go
+++ /dev/null
@@ -1,1303 +0,0 @@
-// Copyright 2009 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 exec runs external commands. It wraps os.StartProcess to make it
-// easier to remap stdin and stdout, connect I/O with pipes, and do other
-// adjustments.
-//
-// Unlike the "system" library call from C and other languages, the
-// os/exec package intentionally does not invoke the system shell and
-// does not expand any glob patterns or handle other expansions,
-// pipelines, or redirections typically done by shells. The package
-// behaves more like C's "exec" family of functions. To expand glob
-// patterns, either call the shell directly, taking care to escape any
-// dangerous input, or use the path/filepath package's Glob function.
-// To expand environment variables, use package os's ExpandEnv.
-//
-// Note that the examples in this package assume a Unix system.
-// They may not run on Windows, and they do not run in the Go Playground
-// used by golang.org and godoc.org.
-//
-// # Executables in the current directory
-//
-// The functions Command and LookPath look for a program
-// in the directories listed in the current path, following the
-// conventions of the host operating system.
-// Operating systems have for decades included the current
-// directory in this search, sometimes implicitly and sometimes
-// configured explicitly that way by default.
-// Modern practice is that including the current directory
-// is usually unexpected and often leads to security problems.
-//
-// To avoid those security problems, as of Go 1.19, this package will not resolve a program
-// using an implicit or explicit path entry relative to the current directory.
-// That is, if you run exec.LookPath("go"), it will not successfully return
-// ./go on Unix nor .\go.exe on Windows, no matter how the path is configured.
-// Instead, if the usual path algorithms would result in that answer,
-// these functions return an error err satisfying errors.Is(err, ErrDot).
-//
-// For example, consider these two program snippets:
-//
-// path, err := exec.LookPath("prog")
-// if err != nil {
-// log.Fatal(err)
-// }
-// use(path)
-//
-// and
-//
-// cmd := exec.Command("prog")
-// if err := cmd.Run(); err != nil {
-// log.Fatal(err)
-// }
-//
-// These will not find and run ./prog or .\prog.exe,
-// no matter how the current path is configured.
-//
-// Code that always wants to run a program from the current directory
-// can be rewritten to say "./prog" instead of "prog".
-//
-// Code that insists on including results from relative path entries
-// can instead override the error using an errors.Is check:
-//
-// path, err := exec.LookPath("prog")
-// if errors.Is(err, exec.ErrDot) {
-// err = nil
-// }
-// if err != nil {
-// log.Fatal(err)
-// }
-// use(path)
-//
-// and
-//
-// cmd := exec.Command("prog")
-// if errors.Is(cmd.Err, exec.ErrDot) {
-// cmd.Err = nil
-// }
-// if err := cmd.Run(); err != nil {
-// log.Fatal(err)
-// }
-//
-// Setting the environment variable GODEBUG=execerrdot=0
-// disables generation of ErrDot entirely, temporarily restoring the pre-Go 1.19
-// behavior for programs that are unable to apply more targeted fixes.
-// A future version of Go may remove support for this variable.
-//
-// Before adding such overrides, make sure you understand the
-// security implications of doing so.
-// See https://go.dev/blog/path-security for more information.
-package exec
-
-import (
- "bytes"
- "context"
- "errors"
- "internal/godebug"
- "internal/syscall/execenv"
- "io"
- "os"
- "path/filepath"
- "runtime"
- "strconv"
- "strings"
- "syscall"
- "time"
-)
-
-// Error is returned by LookPath when it fails to classify a file as an
-// executable.
-type Error struct {
- // Name is the file name for which the error occurred.
- Name string
- // Err is the underlying error.
- Err error
-}
-
-func (e *Error) Error() string {
- return "exec: " + strconv.Quote(e.Name) + ": " + e.Err.Error()
-}
-
-func (e *Error) Unwrap() error { return e.Err }
-
-// ErrWaitDelay is returned by (*Cmd).Wait if the process exits with a
-// successful status code but its output pipes are not closed before the
-// command's WaitDelay expires.
-var ErrWaitDelay = errors.New("exec: WaitDelay expired before I/O complete")
-
-// wrappedError wraps an error without relying on fmt.Errorf.
-type wrappedError struct {
- prefix string
- err error
-}
-
-func (w wrappedError) Error() string {
- return w.prefix + ": " + w.err.Error()
-}
-
-func (w wrappedError) Unwrap() error {
- return w.err
-}
-
-// Cmd represents an external command being prepared or run.
-//
-// A Cmd cannot be reused after calling its Run, Output or CombinedOutput
-// methods.
-type Cmd struct {
- // Path is the path of the command to run.
- //
- // This is the only field that must be set to a non-zero
- // value. If Path is relative, it is evaluated relative
- // to Dir.
- Path string
-
- // Args holds command line arguments, including the command as Args[0].
- // If the Args field is empty or nil, Run uses {Path}.
- //
- // In typical use, both Path and Args are set by calling Command.
- Args []string
-
- // Env specifies the environment of the process.
- // Each entry is of the form "key=value".
- // If Env is nil, the new process uses the current process's
- // environment.
- // If Env contains duplicate environment keys, only the last
- // value in the slice for each duplicate key is used.
- // As a special case on Windows, SYSTEMROOT is always added if
- // missing and not explicitly set to the empty string.
- Env []string
-
- // Dir specifies the working directory of the command.
- // If Dir is the empty string, Run runs the command in the
- // calling process's current directory.
- Dir string
-
- // Stdin specifies the process's standard input.
- //
- // If Stdin is nil, the process reads from the null device (os.DevNull).
- //
- // If Stdin is an *os.File, the process's standard input is connected
- // directly to that file.
- //
- // Otherwise, during the execution of the command a separate
- // goroutine reads from Stdin and delivers that data to the command
- // over a pipe. In this case, Wait does not complete until the goroutine
- // stops copying, either because it has reached the end of Stdin
- // (EOF or a read error), or because writing to the pipe returned an error,
- // or because a nonzero WaitDelay was set and expired.
- Stdin io.Reader
-
- // Stdout and Stderr specify the process's standard output and error.
- //
- // If either is nil, Run connects the corresponding file descriptor
- // to the null device (os.DevNull).
- //
- // If either is an *os.File, the corresponding output from the process
- // is connected directly to that file.
- //
- // Otherwise, during the execution of the command a separate goroutine
- // reads from the process over a pipe and delivers that data to the
- // corresponding Writer. In this case, Wait does not complete until the
- // goroutine reaches EOF or encounters an error or a nonzero WaitDelay
- // expires.
- //
- // If Stdout and Stderr are the same writer, and have a type that can
- // be compared with ==, at most one goroutine at a time will call Write.
- Stdout io.Writer
- Stderr io.Writer
-
- // ExtraFiles specifies additional open files to be inherited by the
- // new process. It does not include standard input, standard output, or
- // standard error. If non-nil, entry i becomes file descriptor 3+i.
- //
- // ExtraFiles is not supported on Windows.
- ExtraFiles []*os.File
-
- // SysProcAttr holds optional, operating system-specific attributes.
- // Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
- SysProcAttr *syscall.SysProcAttr
-
- // Process is the underlying process, once started.
- Process *os.Process
-
- // ProcessState contains information about an exited process.
- // If the process was started successfully, Wait or Run will
- // populate its ProcessState when the command completes.
- ProcessState *os.ProcessState
-
- // ctx is the context passed to CommandContext, if any.
- ctx context.Context
-
- Err error // LookPath error, if any.
-
- // If Cancel is non-nil, the command must have been created with
- // CommandContext and Cancel will be called when the command's
- // Context is done. By default, CommandContext sets Cancel to
- // call the Kill method on the command's Process.
- //
- // Typically a custom Cancel will send a signal to the command's
- // Process, but it may instead take other actions to initiate cancellation,
- // such as closing a stdin or stdout pipe or sending a shutdown request on a
- // network socket.
- //
- // If the command exits with a success status after Cancel is
- // called, and Cancel does not return an error equivalent to
- // os.ErrProcessDone, then Wait and similar methods will return a non-nil
- // error: either an error wrapping the one returned by Cancel,
- // or the error from the Context.
- // (If the command exits with a non-success status, or Cancel
- // returns an error that wraps os.ErrProcessDone, Wait and similar methods
- // continue to return the command's usual exit status.)
- //
- // If Cancel is set to nil, nothing will happen immediately when the command's
- // Context is done, but a nonzero WaitDelay will still take effect. That may
- // be useful, for example, to work around deadlocks in commands that do not
- // support shutdown signals but are expected to always finish quickly.
- //
- // Cancel will not be called if Start returns a non-nil error.
- Cancel func() error
-
- // If WaitDelay is non-zero, it bounds the time spent waiting on two sources
- // of unexpected delay in Wait: a child process that fails to exit after the
- // associated Context is canceled, and a child process that exits but leaves
- // its I/O pipes unclosed.
- //
- // The WaitDelay timer starts when either the associated Context is done or a
- // call to Wait observes that the child process has exited, whichever occurs
- // first. When the delay has elapsed, the command shuts down the child process
- // and/or its I/O pipes.
- //
- // If the child process has failed to exit — perhaps because it ignored or
- // failed to receive a shutdown signal from a Cancel function, or because no
- // Cancel function was set — then it will be terminated using os.Process.Kill.
- //
- // Then, if the I/O pipes communicating with the child process are still open,
- // those pipes are closed in order to unblock any goroutines currently blocked
- // on Read or Write calls.
- //
- // If pipes are closed due to WaitDelay, no Cancel call has occurred,
- // and the command has otherwise exited with a successful status, Wait and
- // similar methods will return ErrWaitDelay instead of nil.
- //
- // If WaitDelay is zero (the default), I/O pipes will be read until EOF,
- // which might not occur until orphaned subprocesses of the command have
- // also closed their descriptors for the pipes.
- WaitDelay time.Duration
-
- // childIOFiles holds closers for any of the child process's
- // stdin, stdout, and/or stderr files that were opened by the Cmd itself
- // (not supplied by the caller). These should be closed as soon as they
- // are inherited by the child process.
- childIOFiles []io.Closer
-
- // parentIOPipes holds closers for the parent's end of any pipes
- // connected to the child's stdin, stdout, and/or stderr streams
- // that were opened by the Cmd itself (not supplied by the caller).
- // These should be closed after Wait sees the command and copying
- // goroutines exit, or after WaitDelay has expired.
- parentIOPipes []io.Closer
-
- // goroutine holds a set of closures to execute to copy data
- // to and/or from the command's I/O pipes.
- goroutine []func() error
-
- // If goroutineErr is non-nil, it receives the first error from a copying
- // goroutine once all such goroutines have completed.
- // goroutineErr is set to nil once its error has been received.
- goroutineErr <-chan error
-
- // If ctxResult is non-nil, it receives the result of watchCtx exactly once.
- ctxResult <-chan ctxResult
-
- // The stack saved when the Command was created, if GODEBUG contains
- // execwait=2. Used for debugging leaks.
- createdByStack []byte
-
- // For a security release long ago, we created x/sys/execabs,
- // which manipulated the unexported lookPathErr error field
- // in this struct. For Go 1.19 we exported the field as Err error,
- // above, but we have to keep lookPathErr around for use by
- // old programs building against new toolchains.
- // The String and Start methods look for an error in lookPathErr
- // in preference to Err, to preserve the errors that execabs sets.
- //
- // In general we don't guarantee misuse of reflect like this,
- // but the misuse of reflect was by us, the best of various bad
- // options to fix the security problem, and people depend on
- // those old copies of execabs continuing to work.
- // The result is that we have to leave this variable around for the
- // rest of time, a compatibility scar.
- //
- // See https://go.dev/blog/path-security
- // and https://go.dev/issue/43724 for more context.
- lookPathErr error
-}
-
-// A ctxResult reports the result of watching the Context associated with a
-// running command (and sending corresponding signals if needed).
-type ctxResult struct {
- err error
-
- // If timer is non-nil, it expires after WaitDelay has elapsed after
- // the Context is done.
- //
- // (If timer is nil, that means that the Context was not done before the
- // command completed, or no WaitDelay was set, or the WaitDelay already
- // expired and its effect was already applied.)
- timer *time.Timer
-}
-
-var execwait = godebug.New("execwait")
-var execerrdot = godebug.New("execerrdot")
-
-// Command returns the Cmd struct to execute the named program with
-// the given arguments.
-//
-// It sets only the Path and Args in the returned structure.
-//
-// If name contains no path separators, Command uses LookPath to
-// resolve name to a complete path if possible. Otherwise it uses name
-// directly as Path.
-//
-// The returned Cmd's Args field is constructed from the command name
-// followed by the elements of arg, so arg should not include the
-// command name itself. For example, Command("echo", "hello").
-// Args[0] is always name, not the possibly resolved Path.
-//
-// On Windows, processes receive the whole command line as a single string
-// and do their own parsing. Command combines and quotes Args into a command
-// line string with an algorithm compatible with applications using
-// CommandLineToArgvW (which is the most common way). Notable exceptions are
-// msiexec.exe and cmd.exe (and thus, all batch files), which have a different
-// unquoting algorithm. In these or other similar cases, you can do the
-// quoting yourself and provide the full command line in SysProcAttr.CmdLine,
-// leaving Args empty.
-func Command(name string, arg ...string) *Cmd {
- cmd := &Cmd{
- Path: name,
- Args: append([]string{name}, arg...),
- }
-
- if v := execwait.Value(); v != "" {
- if v == "2" {
- // Obtain the caller stack. (This is equivalent to runtime/debug.Stack,
- // copied to avoid importing the whole package.)
- stack := make([]byte, 1024)
- for {
- n := runtime.Stack(stack, false)
- if n < len(stack) {
- stack = stack[:n]
- break
- }
- stack = make([]byte, 2*len(stack))
- }
-
- if i := bytes.Index(stack, []byte("\nos/exec.Command(")); i >= 0 {
- stack = stack[i+1:]
- }
- cmd.createdByStack = stack
- }
-
- runtime.SetFinalizer(cmd, func(c *Cmd) {
- if c.Process != nil && c.ProcessState == nil {
- debugHint := ""
- if c.createdByStack == nil {
- debugHint = " (set GODEBUG=execwait=2 to capture stacks for debugging)"
- } else {
- os.Stderr.WriteString("GODEBUG=execwait=2 detected a leaked exec.Cmd created by:\n")
- os.Stderr.Write(c.createdByStack)
- os.Stderr.WriteString("\n")
- debugHint = ""
- }
- panic("exec: Cmd started a Process but leaked without a call to Wait" + debugHint)
- }
- })
- }
-
- if filepath.Base(name) == name {
- lp, err := LookPath(name)
- if lp != "" {
- // Update cmd.Path even if err is non-nil.
- // If err is ErrDot (especially on Windows), lp may include a resolved
- // extension (like .exe or .bat) that should be preserved.
- cmd.Path = lp
- }
- if err != nil {
- cmd.Err = err
- }
- }
- return cmd
-}
-
-// CommandContext is like Command but includes a context.
-//
-// The provided context is used to interrupt the process
-// (by calling cmd.Cancel or os.Process.Kill)
-// if the context becomes done before the command completes on its own.
-//
-// CommandContext sets the command's Cancel function to invoke the Kill method
-// on its Process, and leaves its WaitDelay unset. The caller may change the
-// cancellation behavior by modifying those fields before starting the command.
-func CommandContext(ctx context.Context, name string, arg ...string) *Cmd {
- if ctx == nil {
- panic("nil Context")
- }
- cmd := Command(name, arg...)
- cmd.ctx = ctx
- cmd.Cancel = func() error {
- return cmd.Process.Kill()
- }
- return cmd
-}
-
-// String returns a human-readable description of c.
-// It is intended only for debugging.
-// In particular, it is not suitable for use as input to a shell.
-// The output of String may vary across Go releases.
-func (c *Cmd) String() string {
- if c.Err != nil || c.lookPathErr != nil {
- // failed to resolve path; report the original requested path (plus args)
- return strings.Join(c.Args, " ")
- }
- // report the exact executable path (plus args)
- b := new(strings.Builder)
- b.WriteString(c.Path)
- for _, a := range c.Args[1:] {
- b.WriteByte(' ')
- b.WriteString(a)
- }
- return b.String()
-}
-
-// interfaceEqual protects against panics from doing equality tests on
-// two interfaces with non-comparable underlying types.
-func interfaceEqual(a, b any) bool {
- defer func() {
- recover()
- }()
- return a == b
-}
-
-func (c *Cmd) argv() []string {
- if len(c.Args) > 0 {
- return c.Args
- }
- return []string{c.Path}
-}
-
-func (c *Cmd) childStdin() (*os.File, error) {
- if c.Stdin == nil {
- f, err := os.Open(os.DevNull)
- if err != nil {
- return nil, err
- }
- c.childIOFiles = append(c.childIOFiles, f)
- return f, nil
- }
-
- if f, ok := c.Stdin.(*os.File); ok {
- return f, nil
- }
-
- pr, pw, err := os.Pipe()
- if err != nil {
- return nil, err
- }
-
- c.childIOFiles = append(c.childIOFiles, pr)
- c.parentIOPipes = append(c.parentIOPipes, pw)
- c.goroutine = append(c.goroutine, func() error {
- _, err := io.Copy(pw, c.Stdin)
- if skipStdinCopyError(err) {
- err = nil
- }
- if err1 := pw.Close(); err == nil {
- err = err1
- }
- return err
- })
- return pr, nil
-}
-
-func (c *Cmd) childStdout() (*os.File, error) {
- return c.writerDescriptor(c.Stdout)
-}
-
-func (c *Cmd) childStderr(childStdout *os.File) (*os.File, error) {
- if c.Stderr != nil && interfaceEqual(c.Stderr, c.Stdout) {
- return childStdout, nil
- }
- return c.writerDescriptor(c.Stderr)
-}
-
-// writerDescriptor returns an os.File to which the child process
-// can write to send data to w.
-//
-// If w is nil, writerDescriptor returns a File that writes to os.DevNull.
-func (c *Cmd) writerDescriptor(w io.Writer) (*os.File, error) {
- if w == nil {
- f, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0)
- if err != nil {
- return nil, err
- }
- c.childIOFiles = append(c.childIOFiles, f)
- return f, nil
- }
-
- if f, ok := w.(*os.File); ok {
- return f, nil
- }
-
- pr, pw, err := os.Pipe()
- if err != nil {
- return nil, err
- }
-
- c.childIOFiles = append(c.childIOFiles, pw)
- c.parentIOPipes = append(c.parentIOPipes, pr)
- c.goroutine = append(c.goroutine, func() error {
- _, err := io.Copy(w, pr)
- pr.Close() // in case io.Copy stopped due to write error
- return err
- })
- return pw, nil
-}
-
-func closeDescriptors(closers []io.Closer) {
- for _, fd := range closers {
- fd.Close()
- }
-}
-
-// Run starts the specified command and waits for it to complete.
-//
-// The returned error is nil if the command runs, has no problems
-// copying stdin, stdout, and stderr, and exits with a zero exit
-// status.
-//
-// If the command starts but does not complete successfully, the error is of
-// type *ExitError. Other error types may be returned for other situations.
-//
-// If the calling goroutine has locked the operating system thread
-// with runtime.LockOSThread and modified any inheritable OS-level
-// thread state (for example, Linux or Plan 9 name spaces), the new
-// process will inherit the caller's thread state.
-func (c *Cmd) Run() error {
- if err := c.Start(); err != nil {
- return err
- }
- return c.Wait()
-}
-
-// lookExtensions finds windows executable by its dir and path.
-// It uses LookPath to try appropriate extensions.
-// lookExtensions does not search PATH, instead it converts `prog` into `.\prog`.
-func lookExtensions(path, dir string) (string, error) {
- if filepath.Base(path) == path {
- path = "." + string(filepath.Separator) + path
- }
- if dir == "" {
- return LookPath(path)
- }
- if filepath.VolumeName(path) != "" {
- return LookPath(path)
- }
- if len(path) > 1 && os.IsPathSeparator(path[0]) {
- return LookPath(path)
- }
- dirandpath := filepath.Join(dir, path)
- // We assume that LookPath will only add file extension.
- lp, err := LookPath(dirandpath)
- if err != nil {
- return "", err
- }
- ext := strings.TrimPrefix(lp, dirandpath)
- return path + ext, nil
-}
-
-// Start starts the specified command but does not wait for it to complete.
-//
-// If Start returns successfully, the c.Process field will be set.
-//
-// After a successful call to Start the Wait method must be called in
-// order to release associated system resources.
-func (c *Cmd) Start() error {
- // Check for doubled Start calls before we defer failure cleanup. If the prior
- // call to Start succeeded, we don't want to spuriously close its pipes.
- if c.Process != nil {
- return errors.New("exec: already started")
- }
-
- started := false
- defer func() {
- closeDescriptors(c.childIOFiles)
- c.childIOFiles = nil
-
- if !started {
- closeDescriptors(c.parentIOPipes)
- c.parentIOPipes = nil
- }
- }()
-
- if c.Path == "" && c.Err == nil && c.lookPathErr == nil {
- c.Err = errors.New("exec: no command")
- }
- if c.Err != nil || c.lookPathErr != nil {
- if c.lookPathErr != nil {
- return c.lookPathErr
- }
- return c.Err
- }
- if runtime.GOOS == "windows" {
- lp, err := lookExtensions(c.Path, c.Dir)
- if err != nil {
- return err
- }
- c.Path = lp
- }
- if c.Cancel != nil && c.ctx == nil {
- return errors.New("exec: command with a non-nil Cancel was not created with CommandContext")
- }
- if c.ctx != nil {
- select {
- case <-c.ctx.Done():
- return c.ctx.Err()
- default:
- }
- }
-
- childFiles := make([]*os.File, 0, 3+len(c.ExtraFiles))
- stdin, err := c.childStdin()
- if err != nil {
- return err
- }
- childFiles = append(childFiles, stdin)
- stdout, err := c.childStdout()
- if err != nil {
- return err
- }
- childFiles = append(childFiles, stdout)
- stderr, err := c.childStderr(stdout)
- if err != nil {
- return err
- }
- childFiles = append(childFiles, stderr)
- childFiles = append(childFiles, c.ExtraFiles...)
-
- env, err := c.environ()
- if err != nil {
- return err
- }
-
- c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
- Dir: c.Dir,
- Files: childFiles,
- Env: env,
- Sys: c.SysProcAttr,
- })
- if err != nil {
- return err
- }
- started = true
-
- // Don't allocate the goroutineErr channel unless there are goroutines to start.
- if len(c.goroutine) > 0 {
- goroutineErr := make(chan error, 1)
- c.goroutineErr = goroutineErr
-
- type goroutineStatus struct {
- running int
- firstErr error
- }
- statusc := make(chan goroutineStatus, 1)
- statusc <- goroutineStatus{running: len(c.goroutine)}
- for _, fn := range c.goroutine {
- go func(fn func() error) {
- err := fn()
-
- status := <-statusc
- if status.firstErr == nil {
- status.firstErr = err
- }
- status.running--
- if status.running == 0 {
- goroutineErr <- status.firstErr
- } else {
- statusc <- status
- }
- }(fn)
- }
- c.goroutine = nil // Allow the goroutines' closures to be GC'd when they complete.
- }
-
- // If we have anything to do when the command's Context expires,
- // start a goroutine to watch for cancellation.
- //
- // (Even if the command was created by CommandContext, a helper library may
- // have explicitly set its Cancel field back to nil, indicating that it should
- // be allowed to continue running after cancellation after all.)
- if (c.Cancel != nil || c.WaitDelay != 0) && c.ctx != nil && c.ctx.Done() != nil {
- resultc := make(chan ctxResult)
- c.ctxResult = resultc
- go c.watchCtx(resultc)
- }
-
- return nil
-}
-
-// watchCtx watches c.ctx until it is able to send a result to resultc.
-//
-// If c.ctx is done before a result can be sent, watchCtx calls c.Cancel,
-// and/or kills cmd.Process it after c.WaitDelay has elapsed.
-//
-// watchCtx manipulates c.goroutineErr, so its result must be received before
-// c.awaitGoroutines is called.
-func (c *Cmd) watchCtx(resultc chan<- ctxResult) {
- select {
- case resultc <- ctxResult{}:
- return
- case <-c.ctx.Done():
- }
-
- var err error
- if c.Cancel != nil {
- if interruptErr := c.Cancel(); interruptErr == nil {
- // We appear to have successfully interrupted the command, so any
- // program behavior from this point may be due to ctx even if the
- // command exits with code 0.
- err = c.ctx.Err()
- } else if errors.Is(interruptErr, os.ErrProcessDone) {
- // The process already finished: we just didn't notice it yet.
- // (Perhaps c.Wait hadn't been called, or perhaps it happened to race with
- // c.ctx being cancelled.) Don't inject a needless error.
- } else {
- err = wrappedError{
- prefix: "exec: canceling Cmd",
- err: interruptErr,
- }
- }
- }
- if c.WaitDelay == 0 {
- resultc <- ctxResult{err: err}
- return
- }
-
- timer := time.NewTimer(c.WaitDelay)
- select {
- case resultc <- ctxResult{err: err, timer: timer}:
- // c.Process.Wait returned and we've handed the timer off to c.Wait.
- // It will take care of goroutine shutdown from here.
- return
- case <-timer.C:
- }
-
- killed := false
- if killErr := c.Process.Kill(); killErr == nil {
- // We appear to have killed the process. c.Process.Wait should return a
- // non-nil error to c.Wait unless the Kill signal races with a successful
- // exit, and if that does happen we shouldn't report a spurious error,
- // so don't set err to anything here.
- killed = true
- } else if !errors.Is(killErr, os.ErrProcessDone) {
- err = wrappedError{
- prefix: "exec: killing Cmd",
- err: killErr,
- }
- }
-
- if c.goroutineErr != nil {
- select {
- case goroutineErr := <-c.goroutineErr:
- // Forward goroutineErr only if we don't have reason to believe it was
- // caused by a call to Cancel or Kill above.
- if err == nil && !killed {
- err = goroutineErr
- }
- default:
- // Close the child process's I/O pipes, in case it abandoned some
- // subprocess that inherited them and is still holding them open
- // (see https://go.dev/issue/23019).
- //
- // We close the goroutine pipes only after we have sent any signals we're
- // going to send to the process (via Signal or Kill above): if we send
- // SIGKILL to the process, we would prefer for it to die of SIGKILL, not
- // SIGPIPE. (However, this may still cause any orphaned subprocesses to
- // terminate with SIGPIPE.)
- closeDescriptors(c.parentIOPipes)
- // Wait for the copying goroutines to finish, but report ErrWaitDelay for
- // the error: any other error here could result from closing the pipes.
- _ = <-c.goroutineErr
- if err == nil {
- err = ErrWaitDelay
- }
- }
-
- // Since we have already received the only result from c.goroutineErr,
- // set it to nil to prevent awaitGoroutines from blocking on it.
- c.goroutineErr = nil
- }
-
- resultc <- ctxResult{err: err}
-}
-
-// An ExitError reports an unsuccessful exit by a command.
-type ExitError struct {
- *os.ProcessState
-
- // Stderr holds a subset of the standard error output from the
- // Cmd.Output method if standard error was not otherwise being
- // collected.
- //
- // If the error output is long, Stderr may contain only a prefix
- // and suffix of the output, with the middle replaced with
- // text about the number of omitted bytes.
- //
- // Stderr is provided for debugging, for inclusion in error messages.
- // Users with other needs should redirect Cmd.Stderr as needed.
- Stderr []byte
-}
-
-func (e *ExitError) Error() string {
- return e.ProcessState.String()
-}
-
-// Wait waits for the command to exit and waits for any copying to
-// stdin or copying from stdout or stderr to complete.
-//
-// The command must have been started by Start.
-//
-// The returned error is nil if the command runs, has no problems
-// copying stdin, stdout, and stderr, and exits with a zero exit
-// status.
-//
-// If the command fails to run or doesn't complete successfully, the
-// error is of type *ExitError. Other error types may be
-// returned for I/O problems.
-//
-// If any of c.Stdin, c.Stdout or c.Stderr are not an *os.File, Wait also waits
-// for the respective I/O loop copying to or from the process to complete.
-//
-// Wait releases any resources associated with the Cmd.
-func (c *Cmd) Wait() error {
- if c.Process == nil {
- return errors.New("exec: not started")
- }
- if c.ProcessState != nil {
- return errors.New("exec: Wait was already called")
- }
-
- state, err := c.Process.Wait()
- if err == nil && !state.Success() {
- err = &ExitError{ProcessState: state}
- }
- c.ProcessState = state
-
- var timer *time.Timer
- if c.ctxResult != nil {
- watch := <-c.ctxResult
- timer = watch.timer
- // If c.Process.Wait returned an error, prefer that.
- // Otherwise, report any error from the watchCtx goroutine,
- // such as a Context cancellation or a WaitDelay overrun.
- if err == nil && watch.err != nil {
- err = watch.err
- }
- }
-
- if goroutineErr := c.awaitGoroutines(timer); err == nil {
- // Report an error from the copying goroutines only if the program otherwise
- // exited normally on its own. Otherwise, the copying error may be due to the
- // abnormal termination.
- err = goroutineErr
- }
- closeDescriptors(c.parentIOPipes)
- c.parentIOPipes = nil
-
- return err
-}
-
-// awaitGoroutines waits for the results of the goroutines copying data to or
-// from the command's I/O pipes.
-//
-// If c.WaitDelay elapses before the goroutines complete, awaitGoroutines
-// forcibly closes their pipes and returns ErrWaitDelay.
-//
-// If timer is non-nil, it must send to timer.C at the end of c.WaitDelay.
-func (c *Cmd) awaitGoroutines(timer *time.Timer) error {
- defer func() {
- if timer != nil {
- timer.Stop()
- }
- c.goroutineErr = nil
- }()
-
- if c.goroutineErr == nil {
- return nil // No running goroutines to await.
- }
-
- if timer == nil {
- if c.WaitDelay == 0 {
- return <-c.goroutineErr
- }
-
- select {
- case err := <-c.goroutineErr:
- // Avoid the overhead of starting a timer.
- return err
- default:
- }
-
- // No existing timer was started: either there is no Context associated with
- // the command, or c.Process.Wait completed before the Context was done.
- timer = time.NewTimer(c.WaitDelay)
- }
-
- select {
- case <-timer.C:
- closeDescriptors(c.parentIOPipes)
- // Wait for the copying goroutines to finish, but ignore any error
- // (since it was probably caused by closing the pipes).
- _ = <-c.goroutineErr
- return ErrWaitDelay
-
- case err := <-c.goroutineErr:
- return err
- }
-}
-
-// Output runs the command and returns its standard output.
-// Any returned error will usually be of type *ExitError.
-// If c.Stderr was nil, Output populates ExitError.Stderr.
-func (c *Cmd) Output() ([]byte, error) {
- if c.Stdout != nil {
- return nil, errors.New("exec: Stdout already set")
- }
- var stdout bytes.Buffer
- c.Stdout = &stdout
-
- captureErr := c.Stderr == nil
- if captureErr {
- c.Stderr = &prefixSuffixSaver{N: 32 << 10}
- }
-
- err := c.Run()
- if err != nil && captureErr {
- if ee, ok := err.(*ExitError); ok {
- ee.Stderr = c.Stderr.(*prefixSuffixSaver).Bytes()
- }
- }
- return stdout.Bytes(), err
-}
-
-// CombinedOutput runs the command and returns its combined standard
-// output and standard error.
-func (c *Cmd) CombinedOutput() ([]byte, error) {
- if c.Stdout != nil {
- return nil, errors.New("exec: Stdout already set")
- }
- if c.Stderr != nil {
- return nil, errors.New("exec: Stderr already set")
- }
- var b bytes.Buffer
- c.Stdout = &b
- c.Stderr = &b
- err := c.Run()
- return b.Bytes(), err
-}
-
-// StdinPipe returns a pipe that will be connected to the command's
-// standard input when the command starts.
-// The pipe will be closed automatically after Wait sees the command exit.
-// A caller need only call Close to force the pipe to close sooner.
-// For example, if the command being run will not exit until standard input
-// is closed, the caller must close the pipe.
-func (c *Cmd) StdinPipe() (io.WriteCloser, error) {
- if c.Stdin != nil {
- return nil, errors.New("exec: Stdin already set")
- }
- if c.Process != nil {
- return nil, errors.New("exec: StdinPipe after process started")
- }
- pr, pw, err := os.Pipe()
- if err != nil {
- return nil, err
- }
- c.Stdin = pr
- c.childIOFiles = append(c.childIOFiles, pr)
- c.parentIOPipes = append(c.parentIOPipes, pw)
- return pw, nil
-}
-
-// StdoutPipe returns a pipe that will be connected to the command's
-// standard output when the command starts.
-//
-// Wait will close the pipe after seeing the command exit, so most callers
-// need not close the pipe themselves. It is thus incorrect to call Wait
-// before all reads from the pipe have completed.
-// For the same reason, it is incorrect to call Run when using StdoutPipe.
-// See the example for idiomatic usage.
-func (c *Cmd) StdoutPipe() (io.ReadCloser, error) {
- if c.Stdout != nil {
- return nil, errors.New("exec: Stdout already set")
- }
- if c.Process != nil {
- return nil, errors.New("exec: StdoutPipe after process started")
- }
- pr, pw, err := os.Pipe()
- if err != nil {
- return nil, err
- }
- c.Stdout = pw
- c.childIOFiles = append(c.childIOFiles, pw)
- c.parentIOPipes = append(c.parentIOPipes, pr)
- return pr, nil
-}
-
-// StderrPipe returns a pipe that will be connected to the command's
-// standard error when the command starts.
-//
-// Wait will close the pipe after seeing the command exit, so most callers
-// need not close the pipe themselves. It is thus incorrect to call Wait
-// before all reads from the pipe have completed.
-// For the same reason, it is incorrect to use Run when using StderrPipe.
-// See the StdoutPipe example for idiomatic usage.
-func (c *Cmd) StderrPipe() (io.ReadCloser, error) {
- if c.Stderr != nil {
- return nil, errors.New("exec: Stderr already set")
- }
- if c.Process != nil {
- return nil, errors.New("exec: StderrPipe after process started")
- }
- pr, pw, err := os.Pipe()
- if err != nil {
- return nil, err
- }
- c.Stderr = pw
- c.childIOFiles = append(c.childIOFiles, pw)
- c.parentIOPipes = append(c.parentIOPipes, pr)
- return pr, nil
-}
-
-// prefixSuffixSaver is an io.Writer which retains the first N bytes
-// and the last N bytes written to it. The Bytes() methods reconstructs
-// it with a pretty error message.
-type prefixSuffixSaver struct {
- N int // max size of prefix or suffix
- prefix []byte
- suffix []byte // ring buffer once len(suffix) == N
- suffixOff int // offset to write into suffix
- skipped int64
-
- // TODO(bradfitz): we could keep one large []byte and use part of it for
- // the prefix, reserve space for the '... Omitting N bytes ...' message,
- // then the ring buffer suffix, and just rearrange the ring buffer
- // suffix when Bytes() is called, but it doesn't seem worth it for
- // now just for error messages. It's only ~64KB anyway.
-}
-
-func (w *prefixSuffixSaver) Write(p []byte) (n int, err error) {
- lenp := len(p)
- p = w.fill(&w.prefix, p)
-
- // Only keep the last w.N bytes of suffix data.
- if overage := len(p) - w.N; overage > 0 {
- p = p[overage:]
- w.skipped += int64(overage)
- }
- p = w.fill(&w.suffix, p)
-
- // w.suffix is full now if p is non-empty. Overwrite it in a circle.
- for len(p) > 0 { // 0, 1, or 2 iterations.
- n := copy(w.suffix[w.suffixOff:], p)
- p = p[n:]
- w.skipped += int64(n)
- w.suffixOff += n
- if w.suffixOff == w.N {
- w.suffixOff = 0
- }
- }
- return lenp, nil
-}
-
-// fill appends up to len(p) bytes of p to *dst, such that *dst does not
-// grow larger than w.N. It returns the un-appended suffix of p.
-func (w *prefixSuffixSaver) fill(dst *[]byte, p []byte) (pRemain []byte) {
- if remain := w.N - len(*dst); remain > 0 {
- add := minInt(len(p), remain)
- *dst = append(*dst, p[:add]...)
- p = p[add:]
- }
- return p
-}
-
-func (w *prefixSuffixSaver) Bytes() []byte {
- if w.suffix == nil {
- return w.prefix
- }
- if w.skipped == 0 {
- return append(w.prefix, w.suffix...)
- }
- var buf bytes.Buffer
- buf.Grow(len(w.prefix) + len(w.suffix) + 50)
- buf.Write(w.prefix)
- buf.WriteString("\n... omitting ")
- buf.WriteString(strconv.FormatInt(w.skipped, 10))
- buf.WriteString(" bytes ...\n")
- buf.Write(w.suffix[w.suffixOff:])
- buf.Write(w.suffix[:w.suffixOff])
- return buf.Bytes()
-}
-
-func minInt(a, b int) int {
- if a < b {
- return a
- }
- return b
-}
-
-// environ returns a best-effort copy of the environment in which the command
-// would be run as it is currently configured. If an error occurs in computing
-// the environment, it is returned alongside the best-effort copy.
-func (c *Cmd) environ() ([]string, error) {
- var err error
-
- env := c.Env
- if env == nil {
- env, err = execenv.Default(c.SysProcAttr)
- if err != nil {
- env = os.Environ()
- // Note that the non-nil err is preserved despite env being overridden.
- }
-
- if c.Dir != "" {
- switch runtime.GOOS {
- case "windows", "plan9":
- // Windows and Plan 9 do not use the PWD variable, so we don't need to
- // keep it accurate.
- default:
- // On POSIX platforms, PWD represents “an absolute pathname of the
- // current working directory.” Since we are changing the working
- // directory for the command, we should also update PWD to reflect that.
- //
- // Unfortunately, we didn't always do that, so (as proposed in
- // https://go.dev/issue/50599) to avoid unintended collateral damage we
- // only implicitly update PWD when Env is nil. That way, we're much
- // less likely to override an intentional change to the variable.
- if pwd, absErr := filepath.Abs(c.Dir); absErr == nil {
- env = append(env, "PWD="+pwd)
- } else if err == nil {
- err = absErr
- }
- }
- }
- }
-
- env, dedupErr := dedupEnv(env)
- if err == nil {
- err = dedupErr
- }
- return addCriticalEnv(env), err
-}
-
-// Environ returns a copy of the environment in which the command would be run
-// as it is currently configured.
-func (c *Cmd) Environ() []string {
- // Intentionally ignore errors: environ returns a best-effort environment no matter what.
- env, _ := c.environ()
- return env
-}
-
-// dedupEnv returns a copy of env with any duplicates removed, in favor of
-// later values.
-// Items not of the normal environment "key=value" form are preserved unchanged.
-// Except on Plan 9, items containing NUL characters are removed, and
-// an error is returned along with the remaining values.
-func dedupEnv(env []string) ([]string, error) {
- return dedupEnvCase(runtime.GOOS == "windows", runtime.GOOS == "plan9", env)
-}
-
-// dedupEnvCase is dedupEnv with a case option for testing.
-// If caseInsensitive is true, the case of keys is ignored.
-// If nulOK is false, items containing NUL characters are allowed.
-func dedupEnvCase(caseInsensitive, nulOK bool, env []string) ([]string, error) {
- // Construct the output in reverse order, to preserve the
- // last occurrence of each key.
- var err error
- out := make([]string, 0, len(env))
- saw := make(map[string]bool, len(env))
- for n := len(env); n > 0; n-- {
- kv := env[n-1]
-
- // Reject NUL in environment variables to prevent security issues (#56284);
- // except on Plan 9, which uses NUL as os.PathListSeparator (#56544).
- if !nulOK && strings.IndexByte(kv, 0) != -1 {
- err = errors.New("exec: environment variable contains NUL")
- continue
- }
-
- i := strings.Index(kv, "=")
- if i == 0 {
- // We observe in practice keys with a single leading "=" on Windows.
- // TODO(#49886): Should we consume only the first leading "=" as part
- // of the key, or parse through arbitrarily many of them until a non-"="?
- i = strings.Index(kv[1:], "=") + 1
- }
- if i < 0 {
- if kv != "" {
- // The entry is not of the form "key=value" (as it is required to be).
- // Leave it as-is for now.
- // TODO(#52436): should we strip or reject these bogus entries?
- out = append(out, kv)
- }
- continue
- }
- k := kv[:i]
- if caseInsensitive {
- k = strings.ToLower(k)
- }
- if saw[k] {
- continue
- }
-
- saw[k] = true
- out = append(out, kv)
- }
-
- // Now reverse the slice to restore the original order.
- for i := 0; i < len(out)/2; i++ {
- j := len(out) - i - 1
- out[i], out[j] = out[j], out[i]
- }
-
- return out, err
-}
-
-// addCriticalEnv adds any critical environment variables that are required
-// (or at least almost always required) on the operating system.
-// Currently this is only used for Windows.
-func addCriticalEnv(env []string) []string {
- if runtime.GOOS != "windows" {
- return env
- }
- for _, kv := range env {
- k, _, ok := strings.Cut(kv, "=")
- if !ok {
- continue
- }
- if strings.EqualFold(k, "SYSTEMROOT") {
- // We already have it.
- return env
- }
- }
- return append(env, "SYSTEMROOT="+os.Getenv("SYSTEMROOT"))
-}
-
-// ErrDot indicates that a path lookup resolved to an executable
-// in the current directory due to ‘.’ being in the path, either
-// implicitly or explicitly. See the package documentation for details.
-//
-// Note that functions in this package do not return ErrDot directly.
-// Code should use errors.Is(err, ErrDot), not err == ErrDot,
-// to test whether a returned error err is due to this condition.
-var ErrDot = errors.New("cannot run executable found relative to current directory")
diff --git a/contrib/go/_std_1.20/src/os/exec/internal/fdtest/exists_unix.go b/contrib/go/_std_1.20/src/os/exec/internal/fdtest/exists_unix.go
deleted file mode 100644
index 265cb69822..0000000000
--- a/contrib/go/_std_1.20/src/os/exec/internal/fdtest/exists_unix.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// 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.
-
-//go:build unix
-
-// Package fdtest provides test helpers for working with file descriptors across exec.
-package fdtest
-
-import (
- "syscall"
-)
-
-// Exists returns true if fd is a valid file descriptor.
-func Exists(fd uintptr) bool {
- var s syscall.Stat_t
- err := syscall.Fstat(int(fd), &s)
- return err != syscall.EBADF
-}
diff --git a/contrib/go/_std_1.20/src/os/exec/internal/fdtest/ya.make b/contrib/go/_std_1.20/src/os/exec/internal/fdtest/ya.make
deleted file mode 100644
index 3c3136d225..0000000000
--- a/contrib/go/_std_1.20/src/os/exec/internal/fdtest/ya.make
+++ /dev/null
@@ -1,21 +0,0 @@
-GO_LIBRARY()
-
-IF (OS_DARWIN)
- SRCS(
- exists_unix.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- exists_unix.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- exists_windows.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/os/exec/lp_unix.go b/contrib/go/_std_1.20/src/os/exec/lp_unix.go
deleted file mode 100644
index 2af9b01cf6..0000000000
--- a/contrib/go/_std_1.20/src/os/exec/lp_unix.go
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2010 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.
-
-//go:build unix
-
-package exec
-
-import (
- "errors"
- "internal/syscall/unix"
- "io/fs"
- "os"
- "path/filepath"
- "strings"
- "syscall"
-)
-
-// ErrNotFound is the error resulting if a path search failed to find an executable file.
-var ErrNotFound = errors.New("executable file not found in $PATH")
-
-func findExecutable(file string) error {
- d, err := os.Stat(file)
- if err != nil {
- return err
- }
- m := d.Mode()
- if m.IsDir() {
- return syscall.EISDIR
- }
- err = unix.Eaccess(file, unix.X_OK)
- // ENOSYS means Eaccess is not available or not implemented.
- // EPERM can be returned by Linux containers employing seccomp.
- // In both cases, fall back to checking the permission bits.
- if err == nil || (err != syscall.ENOSYS && err != syscall.EPERM) {
- return err
- }
- if m&0111 != 0 {
- return nil
- }
- return fs.ErrPermission
-}
-
-// LookPath searches for an executable named file in the
-// directories named by the PATH environment variable.
-// If file contains a slash, it is tried directly and the PATH is not consulted.
-// Otherwise, on success, the result is an absolute path.
-//
-// In older versions of Go, LookPath could return a path relative to the current directory.
-// As of Go 1.19, LookPath will instead return that path along with an error satisfying
-// errors.Is(err, ErrDot). See the package documentation for more details.
-func LookPath(file string) (string, error) {
- // NOTE(rsc): I wish we could use the Plan 9 behavior here
- // (only bypass the path if file begins with / or ./ or ../)
- // but that would not match all the Unix shells.
-
- if strings.Contains(file, "/") {
- err := findExecutable(file)
- if err == nil {
- return file, nil
- }
- return "", &Error{file, err}
- }
- path := os.Getenv("PATH")
- for _, dir := range filepath.SplitList(path) {
- if dir == "" {
- // Unix shell semantics: path element "" means "."
- dir = "."
- }
- path := filepath.Join(dir, file)
- if err := findExecutable(path); err == nil {
- if !filepath.IsAbs(path) && execerrdot.Value() != "0" {
- return path, &Error{file, ErrDot}
- }
- return path, nil
- }
- }
- return "", &Error{file, ErrNotFound}
-}
diff --git a/contrib/go/_std_1.20/src/os/exec/lp_windows.go b/contrib/go/_std_1.20/src/os/exec/lp_windows.go
deleted file mode 100644
index 97bfa58244..0000000000
--- a/contrib/go/_std_1.20/src/os/exec/lp_windows.go
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2010 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 exec
-
-import (
- "errors"
- "io/fs"
- "os"
- "path/filepath"
- "strings"
- "syscall"
-)
-
-// ErrNotFound is the error resulting if a path search failed to find an executable file.
-var ErrNotFound = errors.New("executable file not found in %PATH%")
-
-func chkStat(file string) error {
- d, err := os.Stat(file)
- if err != nil {
- return err
- }
- if d.IsDir() {
- return fs.ErrPermission
- }
- return nil
-}
-
-func hasExt(file string) bool {
- i := strings.LastIndex(file, ".")
- if i < 0 {
- return false
- }
- return strings.LastIndexAny(file, `:\/`) < i
-}
-
-func findExecutable(file string, exts []string) (string, error) {
- if len(exts) == 0 {
- return file, chkStat(file)
- }
- if hasExt(file) {
- if chkStat(file) == nil {
- return file, nil
- }
- }
- for _, e := range exts {
- if f := file + e; chkStat(f) == nil {
- return f, nil
- }
- }
- return "", fs.ErrNotExist
-}
-
-// LookPath searches for an executable named file in the
-// directories named by the PATH environment variable.
-// LookPath also uses PATHEXT environment variable to match
-// a suitable candidate.
-// If file contains a slash, it is tried directly and the PATH is not consulted.
-// Otherwise, on success, the result is an absolute path.
-//
-// In older versions of Go, LookPath could return a path relative to the current directory.
-// As of Go 1.19, LookPath will instead return that path along with an error satisfying
-// errors.Is(err, ErrDot). See the package documentation for more details.
-func LookPath(file string) (string, error) {
- var exts []string
- x := os.Getenv(`PATHEXT`)
- if x != "" {
- for _, e := range strings.Split(strings.ToLower(x), `;`) {
- if e == "" {
- continue
- }
- if e[0] != '.' {
- e = "." + e
- }
- exts = append(exts, e)
- }
- } else {
- exts = []string{".com", ".exe", ".bat", ".cmd"}
- }
-
- if strings.ContainsAny(file, `:\/`) {
- f, err := findExecutable(file, exts)
- if err == nil {
- return f, nil
- }
- return "", &Error{file, err}
- }
-
- // On Windows, creating the NoDefaultCurrentDirectoryInExePath
- // environment variable (with any value or no value!) signals that
- // path lookups should skip the current directory.
- // In theory we are supposed to call NeedCurrentDirectoryForExePathW
- // "as the registry location of this environment variable can change"
- // but that seems exceedingly unlikely: it would break all users who
- // have configured their environment this way!
- // https://docs.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-needcurrentdirectoryforexepathw
- // See also go.dev/issue/43947.
- var (
- dotf string
- dotErr error
- )
- if _, found := syscall.Getenv("NoDefaultCurrentDirectoryInExePath"); !found {
- if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
- if execerrdot.Value() == "0" {
- return f, nil
- }
- dotf, dotErr = f, &Error{file, ErrDot}
- }
- }
-
- path := os.Getenv("path")
- for _, dir := range filepath.SplitList(path) {
- if f, err := findExecutable(filepath.Join(dir, file), exts); err == nil {
- if dotErr != nil {
- // https://go.dev/issue/53536: if we resolved a relative path implicitly,
- // and it is the same executable that would be resolved from the explicit %PATH%,
- // prefer the explicit name for the executable (and, likely, no error) instead
- // of the equivalent implicit name with ErrDot.
- //
- // Otherwise, return the ErrDot for the implicit path as soon as we find
- // out that the explicit one doesn't match.
- dotfi, dotfiErr := os.Lstat(dotf)
- fi, fiErr := os.Lstat(f)
- if dotfiErr != nil || fiErr != nil || !os.SameFile(dotfi, fi) {
- return dotf, dotErr
- }
- }
-
- if !filepath.IsAbs(f) && execerrdot.Value() != "0" {
- return f, &Error{file, ErrDot}
- }
- return f, nil
- }
- }
-
- if dotErr != nil {
- return dotf, dotErr
- }
- return "", &Error{file, ErrNotFound}
-}
diff --git a/contrib/go/_std_1.20/src/os/exec/ya.make b/contrib/go/_std_1.20/src/os/exec/ya.make
deleted file mode 100644
index 4e11e6837a..0000000000
--- a/contrib/go/_std_1.20/src/os/exec/ya.make
+++ /dev/null
@@ -1,32 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- exec.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- exec_unix.go
- lp_unix.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- exec_unix.go
- lp_unix.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- exec_windows.go
- lp_windows.go
- )
-ENDIF()
-
-END()
-
-RECURSE(
- internal
-)
diff --git a/contrib/go/_std_1.20/src/os/exec_posix.go b/contrib/go/_std_1.20/src/os/exec_posix.go
deleted file mode 100644
index e1e7d53a27..0000000000
--- a/contrib/go/_std_1.20/src/os/exec_posix.go
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix || (js && wasm) || windows
-
-package os
-
-import (
- "internal/itoa"
- "internal/syscall/execenv"
- "runtime"
- "syscall"
-)
-
-// The only signal values guaranteed to be present in the os package on all
-// systems are os.Interrupt (send the process an interrupt) and os.Kill (force
-// the process to exit). On Windows, sending os.Interrupt to a process with
-// os.Process.Signal is not implemented; it will return an error instead of
-// sending a signal.
-var (
- Interrupt Signal = syscall.SIGINT
- Kill Signal = syscall.SIGKILL
-)
-
-func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
- // If there is no SysProcAttr (ie. no Chroot or changed
- // UID/GID), double-check existence of the directory we want
- // to chdir into. We can make the error clearer this way.
- if attr != nil && attr.Sys == nil && attr.Dir != "" {
- if _, err := Stat(attr.Dir); err != nil {
- pe := err.(*PathError)
- pe.Op = "chdir"
- return nil, pe
- }
- }
-
- sysattr := &syscall.ProcAttr{
- Dir: attr.Dir,
- Env: attr.Env,
- Sys: attr.Sys,
- }
- if sysattr.Env == nil {
- sysattr.Env, err = execenv.Default(sysattr.Sys)
- if err != nil {
- return nil, err
- }
- }
- sysattr.Files = make([]uintptr, 0, len(attr.Files))
- for _, f := range attr.Files {
- sysattr.Files = append(sysattr.Files, f.Fd())
- }
-
- pid, h, e := syscall.StartProcess(name, argv, sysattr)
-
- // Make sure we don't run the finalizers of attr.Files.
- runtime.KeepAlive(attr)
-
- if e != nil {
- return nil, &PathError{Op: "fork/exec", Path: name, Err: e}
- }
-
- return newProcess(pid, h), nil
-}
-
-func (p *Process) kill() error {
- return p.Signal(Kill)
-}
-
-// ProcessState stores information about a process, as reported by Wait.
-type ProcessState struct {
- pid int // The process's id.
- status syscall.WaitStatus // System-dependent status info.
- rusage *syscall.Rusage
-}
-
-// Pid returns the process id of the exited process.
-func (p *ProcessState) Pid() int {
- return p.pid
-}
-
-func (p *ProcessState) exited() bool {
- return p.status.Exited()
-}
-
-func (p *ProcessState) success() bool {
- return p.status.ExitStatus() == 0
-}
-
-func (p *ProcessState) sys() any {
- return p.status
-}
-
-func (p *ProcessState) sysUsage() any {
- return p.rusage
-}
-
-func (p *ProcessState) String() string {
- if p == nil {
- return "<nil>"
- }
- status := p.Sys().(syscall.WaitStatus)
- res := ""
- switch {
- case status.Exited():
- code := status.ExitStatus()
- if runtime.GOOS == "windows" && uint(code) >= 1<<16 { // windows uses large hex numbers
- res = "exit status " + uitox(uint(code))
- } else { // unix systems use small decimal integers
- res = "exit status " + itoa.Itoa(code) // unix
- }
- case status.Signaled():
- res = "signal: " + status.Signal().String()
- case status.Stopped():
- res = "stop signal: " + status.StopSignal().String()
- if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != 0 {
- res += " (trap " + itoa.Itoa(status.TrapCause()) + ")"
- }
- case status.Continued():
- res = "continued"
- }
- if status.CoreDump() {
- res += " (core dumped)"
- }
- return res
-}
-
-// ExitCode returns the exit code of the exited process, or -1
-// if the process hasn't exited or was terminated by a signal.
-func (p *ProcessState) ExitCode() int {
- // return -1 if the process hasn't started.
- if p == nil {
- return -1
- }
- return p.status.ExitStatus()
-}
diff --git a/contrib/go/_std_1.20/src/os/exec_unix.go b/contrib/go/_std_1.20/src/os/exec_unix.go
deleted file mode 100644
index 90a4a61222..0000000000
--- a/contrib/go/_std_1.20/src/os/exec_unix.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix || (js && wasm)
-
-package os
-
-import (
- "errors"
- "runtime"
- "syscall"
- "time"
-)
-
-func (p *Process) wait() (ps *ProcessState, err error) {
- if p.Pid == -1 {
- return nil, syscall.EINVAL
- }
-
- // If we can block until Wait4 will succeed immediately, do so.
- ready, err := p.blockUntilWaitable()
- if err != nil {
- return nil, err
- }
- if ready {
- // Mark the process done now, before the call to Wait4,
- // so that Process.signal will not send a signal.
- p.setDone()
- // Acquire a write lock on sigMu to wait for any
- // active call to the signal method to complete.
- p.sigMu.Lock()
- p.sigMu.Unlock()
- }
-
- var (
- status syscall.WaitStatus
- rusage syscall.Rusage
- pid1 int
- e error
- )
- for {
- pid1, e = syscall.Wait4(p.Pid, &status, 0, &rusage)
- if e != syscall.EINTR {
- break
- }
- }
- if e != nil {
- return nil, NewSyscallError("wait", e)
- }
- if pid1 != 0 {
- p.setDone()
- }
- ps = &ProcessState{
- pid: pid1,
- status: status,
- rusage: &rusage,
- }
- return ps, nil
-}
-
-func (p *Process) signal(sig Signal) error {
- if p.Pid == -1 {
- return errors.New("os: process already released")
- }
- if p.Pid == 0 {
- return errors.New("os: process not initialized")
- }
- p.sigMu.RLock()
- defer p.sigMu.RUnlock()
- if p.done() {
- return ErrProcessDone
- }
- s, ok := sig.(syscall.Signal)
- if !ok {
- return errors.New("os: unsupported signal type")
- }
- if e := syscall.Kill(p.Pid, s); e != nil {
- if e == syscall.ESRCH {
- return ErrProcessDone
- }
- return e
- }
- return nil
-}
-
-func (p *Process) release() error {
- // NOOP for unix.
- p.Pid = -1
- // no need for a finalizer anymore
- runtime.SetFinalizer(p, nil)
- return nil
-}
-
-func findProcess(pid int) (p *Process, err error) {
- // NOOP for unix.
- return newProcess(pid, 0), nil
-}
-
-func (p *ProcessState) userTime() time.Duration {
- return time.Duration(p.rusage.Utime.Nano()) * time.Nanosecond
-}
-
-func (p *ProcessState) systemTime() time.Duration {
- return time.Duration(p.rusage.Stime.Nano()) * time.Nanosecond
-}
diff --git a/contrib/go/_std_1.20/src/os/executable_procfs.go b/contrib/go/_std_1.20/src/os/executable_procfs.go
deleted file mode 100644
index 18348eab91..0000000000
--- a/contrib/go/_std_1.20/src/os/executable_procfs.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2016 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.
-
-//go:build linux || netbsd || (js && wasm)
-
-package os
-
-import (
- "errors"
- "runtime"
-)
-
-func executable() (string, error) {
- var procfn string
- switch runtime.GOOS {
- default:
- return "", errors.New("Executable not implemented for " + runtime.GOOS)
- case "linux", "android":
- procfn = "/proc/self/exe"
- case "netbsd":
- procfn = "/proc/curproc/exe"
- }
- path, err := Readlink(procfn)
-
- // When the executable has been deleted then Readlink returns a
- // path appended with " (deleted)".
- return stringsTrimSuffix(path, " (deleted)"), err
-}
-
-// stringsTrimSuffix is the same as strings.TrimSuffix.
-func stringsTrimSuffix(s, suffix string) string {
- if len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix {
- return s[:len(s)-len(suffix)]
- }
- return s
-}
diff --git a/contrib/go/_std_1.20/src/os/file.go b/contrib/go/_std_1.20/src/os/file.go
deleted file mode 100644
index 3d71ac068e..0000000000
--- a/contrib/go/_std_1.20/src/os/file.go
+++ /dev/null
@@ -1,730 +0,0 @@
-// Copyright 2009 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 os provides a platform-independent interface to operating system
-// functionality. The design is Unix-like, although the error handling is
-// Go-like; failing calls return values of type error rather than error numbers.
-// Often, more information is available within the error. For example,
-// if a call that takes a file name fails, such as Open or Stat, the error
-// will include the failing file name when printed and will be of type
-// *PathError, which may be unpacked for more information.
-//
-// The os interface is intended to be uniform across all operating systems.
-// Features not generally available appear in the system-specific package syscall.
-//
-// Here is a simple example, opening a file and reading some of it.
-//
-// file, err := os.Open("file.go") // For read access.
-// if err != nil {
-// log.Fatal(err)
-// }
-//
-// If the open fails, the error string will be self-explanatory, like
-//
-// open file.go: no such file or directory
-//
-// The file's data can then be read into a slice of bytes. Read and
-// Write take their byte counts from the length of the argument slice.
-//
-// data := make([]byte, 100)
-// count, err := file.Read(data)
-// if err != nil {
-// log.Fatal(err)
-// }
-// fmt.Printf("read %d bytes: %q\n", count, data[:count])
-//
-// Note: The maximum number of concurrent operations on a File may be limited by
-// the OS or the system. The number should be high, but exceeding it may degrade
-// performance or cause other issues.
-package os
-
-import (
- "errors"
- "internal/poll"
- "internal/safefilepath"
- "internal/testlog"
- "io"
- "io/fs"
- "runtime"
- "syscall"
- "time"
- "unsafe"
-)
-
-// Name returns the name of the file as presented to Open.
-func (f *File) Name() string { return f.name }
-
-// Stdin, Stdout, and Stderr are open Files pointing to the standard input,
-// standard output, and standard error file descriptors.
-//
-// Note that the Go runtime writes to standard error for panics and crashes;
-// closing Stderr may cause those messages to go elsewhere, perhaps
-// to a file opened later.
-var (
- Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
- Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
- Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
-)
-
-// Flags to OpenFile wrapping those of the underlying system. Not all
-// flags may be implemented on a given system.
-const (
- // Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
- O_RDONLY int = syscall.O_RDONLY // open the file read-only.
- O_WRONLY int = syscall.O_WRONLY // open the file write-only.
- O_RDWR int = syscall.O_RDWR // open the file read-write.
- // The remaining values may be or'ed in to control behavior.
- O_APPEND int = syscall.O_APPEND // append data to the file when writing.
- O_CREATE int = syscall.O_CREAT // create a new file if none exists.
- O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist.
- O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
- O_TRUNC int = syscall.O_TRUNC // truncate regular writable file when opened.
-)
-
-// Seek whence values.
-//
-// Deprecated: Use io.SeekStart, io.SeekCurrent, and io.SeekEnd.
-const (
- SEEK_SET int = 0 // seek relative to the origin of the file
- SEEK_CUR int = 1 // seek relative to the current offset
- SEEK_END int = 2 // seek relative to the end
-)
-
-// LinkError records an error during a link or symlink or rename
-// system call and the paths that caused it.
-type LinkError struct {
- Op string
- Old string
- New string
- Err error
-}
-
-func (e *LinkError) Error() string {
- return e.Op + " " + e.Old + " " + e.New + ": " + e.Err.Error()
-}
-
-func (e *LinkError) Unwrap() error {
- return e.Err
-}
-
-// Read reads up to len(b) bytes from the File and stores them in b.
-// It returns the number of bytes read and any error encountered.
-// At end of file, Read returns 0, io.EOF.
-func (f *File) Read(b []byte) (n int, err error) {
- if err := f.checkValid("read"); err != nil {
- return 0, err
- }
- n, e := f.read(b)
- return n, f.wrapErr("read", e)
-}
-
-// ReadAt reads len(b) bytes from the File starting at byte offset off.
-// It returns the number of bytes read and the error, if any.
-// ReadAt always returns a non-nil error when n < len(b).
-// At end of file, that error is io.EOF.
-func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
- if err := f.checkValid("read"); err != nil {
- return 0, err
- }
-
- if off < 0 {
- return 0, &PathError{Op: "readat", Path: f.name, Err: errors.New("negative offset")}
- }
-
- for len(b) > 0 {
- m, e := f.pread(b, off)
- if e != nil {
- err = f.wrapErr("read", e)
- break
- }
- n += m
- b = b[m:]
- off += int64(m)
- }
- return
-}
-
-// ReadFrom implements io.ReaderFrom.
-func (f *File) ReadFrom(r io.Reader) (n int64, err error) {
- if err := f.checkValid("write"); err != nil {
- return 0, err
- }
- n, handled, e := f.readFrom(r)
- if !handled {
- return genericReadFrom(f, r) // without wrapping
- }
- return n, f.wrapErr("write", e)
-}
-
-func genericReadFrom(f *File, r io.Reader) (int64, error) {
- return io.Copy(onlyWriter{f}, r)
-}
-
-type onlyWriter struct {
- io.Writer
-}
-
-// Write writes len(b) bytes from b to the File.
-// It returns the number of bytes written and an error, if any.
-// Write returns a non-nil error when n != len(b).
-func (f *File) Write(b []byte) (n int, err error) {
- if err := f.checkValid("write"); err != nil {
- return 0, err
- }
- n, e := f.write(b)
- if n < 0 {
- n = 0
- }
- if n != len(b) {
- err = io.ErrShortWrite
- }
-
- epipecheck(f, e)
-
- if e != nil {
- err = f.wrapErr("write", e)
- }
-
- return n, err
-}
-
-var errWriteAtInAppendMode = errors.New("os: invalid use of WriteAt on file opened with O_APPEND")
-
-// WriteAt writes len(b) bytes to the File starting at byte offset off.
-// It returns the number of bytes written and an error, if any.
-// WriteAt returns a non-nil error when n != len(b).
-//
-// If file was opened with the O_APPEND flag, WriteAt returns an error.
-func (f *File) WriteAt(b []byte, off int64) (n int, err error) {
- if err := f.checkValid("write"); err != nil {
- return 0, err
- }
- if f.appendMode {
- return 0, errWriteAtInAppendMode
- }
-
- if off < 0 {
- return 0, &PathError{Op: "writeat", Path: f.name, Err: errors.New("negative offset")}
- }
-
- for len(b) > 0 {
- m, e := f.pwrite(b, off)
- if e != nil {
- err = f.wrapErr("write", e)
- break
- }
- n += m
- b = b[m:]
- off += int64(m)
- }
- return
-}
-
-// Seek sets the offset for the next Read or Write on file to offset, interpreted
-// according to whence: 0 means relative to the origin of the file, 1 means
-// relative to the current offset, and 2 means relative to the end.
-// It returns the new offset and an error, if any.
-// The behavior of Seek on a file opened with O_APPEND is not specified.
-func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
- if err := f.checkValid("seek"); err != nil {
- return 0, err
- }
- r, e := f.seek(offset, whence)
- if e == nil && f.dirinfo != nil && r != 0 {
- e = syscall.EISDIR
- }
- if e != nil {
- return 0, f.wrapErr("seek", e)
- }
- return r, nil
-}
-
-// WriteString is like Write, but writes the contents of string s rather than
-// a slice of bytes.
-func (f *File) WriteString(s string) (n int, err error) {
- b := unsafe.Slice(unsafe.StringData(s), len(s))
- return f.Write(b)
-}
-
-// Mkdir creates a new directory with the specified name and permission
-// bits (before umask).
-// If there is an error, it will be of type *PathError.
-func Mkdir(name string, perm FileMode) error {
- longName := fixLongPath(name)
- e := ignoringEINTR(func() error {
- return syscall.Mkdir(longName, syscallMode(perm))
- })
-
- if e != nil {
- return &PathError{Op: "mkdir", Path: name, Err: e}
- }
-
- // mkdir(2) itself won't handle the sticky bit on *BSD and Solaris
- if !supportsCreateWithStickyBit && perm&ModeSticky != 0 {
- e = setStickyBit(name)
-
- if e != nil {
- Remove(name)
- return e
- }
- }
-
- return nil
-}
-
-// setStickyBit adds ModeSticky to the permission bits of path, non atomic.
-func setStickyBit(name string) error {
- fi, err := Stat(name)
- if err != nil {
- return err
- }
- return Chmod(name, fi.Mode()|ModeSticky)
-}
-
-// Chdir changes the current working directory to the named directory.
-// If there is an error, it will be of type *PathError.
-func Chdir(dir string) error {
- if e := syscall.Chdir(dir); e != nil {
- testlog.Open(dir) // observe likely non-existent directory
- return &PathError{Op: "chdir", Path: dir, Err: e}
- }
- if log := testlog.Logger(); log != nil {
- wd, err := Getwd()
- if err == nil {
- log.Chdir(wd)
- }
- }
- return nil
-}
-
-// Open opens the named file for reading. If successful, methods on
-// the returned file can be used for reading; the associated file
-// descriptor has mode O_RDONLY.
-// If there is an error, it will be of type *PathError.
-func Open(name string) (*File, error) {
- return OpenFile(name, O_RDONLY, 0)
-}
-
-// Create creates or truncates the named file. If the file already exists,
-// it is truncated. If the file does not exist, it is created with mode 0666
-// (before umask). If successful, methods on the returned File can
-// be used for I/O; the associated file descriptor has mode O_RDWR.
-// If there is an error, it will be of type *PathError.
-func Create(name string) (*File, error) {
- return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
-}
-
-// OpenFile is the generalized open call; most users will use Open
-// or Create instead. It opens the named file with specified flag
-// (O_RDONLY etc.). If the file does not exist, and the O_CREATE flag
-// is passed, it is created with mode perm (before umask). If successful,
-// methods on the returned File can be used for I/O.
-// If there is an error, it will be of type *PathError.
-func OpenFile(name string, flag int, perm FileMode) (*File, error) {
- testlog.Open(name)
- f, err := openFileNolog(name, flag, perm)
- if err != nil {
- return nil, err
- }
- f.appendMode = flag&O_APPEND != 0
-
- return f, nil
-}
-
-// lstat is overridden in tests.
-var lstat = Lstat
-
-// Rename renames (moves) oldpath to newpath.
-// If newpath already exists and is not a directory, Rename replaces it.
-// OS-specific restrictions may apply when oldpath and newpath are in different directories.
-// Even within the same directory, on non-Unix platforms Rename is not an atomic operation.
-// If there is an error, it will be of type *LinkError.
-func Rename(oldpath, newpath string) error {
- return rename(oldpath, newpath)
-}
-
-// Many functions in package syscall return a count of -1 instead of 0.
-// Using fixCount(call()) instead of call() corrects the count.
-func fixCount(n int, err error) (int, error) {
- if n < 0 {
- n = 0
- }
- return n, err
-}
-
-// wrapErr wraps an error that occurred during an operation on an open file.
-// It passes io.EOF through unchanged, otherwise converts
-// poll.ErrFileClosing to ErrClosed and wraps the error in a PathError.
-func (f *File) wrapErr(op string, err error) error {
- if err == nil || err == io.EOF {
- return err
- }
- if err == poll.ErrFileClosing {
- err = ErrClosed
- }
- return &PathError{Op: op, Path: f.name, Err: err}
-}
-
-// TempDir returns the default directory to use for temporary files.
-//
-// On Unix systems, it returns $TMPDIR if non-empty, else /tmp.
-// On Windows, it uses GetTempPath, returning the first non-empty
-// value from %TMP%, %TEMP%, %USERPROFILE%, or the Windows directory.
-// On Plan 9, it returns /tmp.
-//
-// The directory is neither guaranteed to exist nor have accessible
-// permissions.
-func TempDir() string {
- return tempDir()
-}
-
-// UserCacheDir returns the default root directory to use for user-specific
-// cached data. Users should create their own application-specific subdirectory
-// within this one and use that.
-//
-// On Unix systems, it returns $XDG_CACHE_HOME as specified by
-// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if
-// non-empty, else $HOME/.cache.
-// On Darwin, it returns $HOME/Library/Caches.
-// On Windows, it returns %LocalAppData%.
-// On Plan 9, it returns $home/lib/cache.
-//
-// If the location cannot be determined (for example, $HOME is not defined),
-// then it will return an error.
-func UserCacheDir() (string, error) {
- var dir string
-
- switch runtime.GOOS {
- case "windows":
- dir = Getenv("LocalAppData")
- if dir == "" {
- return "", errors.New("%LocalAppData% is not defined")
- }
-
- case "darwin", "ios":
- dir = Getenv("HOME")
- if dir == "" {
- return "", errors.New("$HOME is not defined")
- }
- dir += "/Library/Caches"
-
- case "plan9":
- dir = Getenv("home")
- if dir == "" {
- return "", errors.New("$home is not defined")
- }
- dir += "/lib/cache"
-
- default: // Unix
- dir = Getenv("XDG_CACHE_HOME")
- if dir == "" {
- dir = Getenv("HOME")
- if dir == "" {
- return "", errors.New("neither $XDG_CACHE_HOME nor $HOME are defined")
- }
- dir += "/.cache"
- }
- }
-
- return dir, nil
-}
-
-// UserConfigDir returns the default root directory to use for user-specific
-// configuration data. Users should create their own application-specific
-// subdirectory within this one and use that.
-//
-// On Unix systems, it returns $XDG_CONFIG_HOME as specified by
-// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if
-// non-empty, else $HOME/.config.
-// On Darwin, it returns $HOME/Library/Application Support.
-// On Windows, it returns %AppData%.
-// On Plan 9, it returns $home/lib.
-//
-// If the location cannot be determined (for example, $HOME is not defined),
-// then it will return an error.
-func UserConfigDir() (string, error) {
- var dir string
-
- switch runtime.GOOS {
- case "windows":
- dir = Getenv("AppData")
- if dir == "" {
- return "", errors.New("%AppData% is not defined")
- }
-
- case "darwin", "ios":
- dir = Getenv("HOME")
- if dir == "" {
- return "", errors.New("$HOME is not defined")
- }
- dir += "/Library/Application Support"
-
- case "plan9":
- dir = Getenv("home")
- if dir == "" {
- return "", errors.New("$home is not defined")
- }
- dir += "/lib"
-
- default: // Unix
- dir = Getenv("XDG_CONFIG_HOME")
- if dir == "" {
- dir = Getenv("HOME")
- if dir == "" {
- return "", errors.New("neither $XDG_CONFIG_HOME nor $HOME are defined")
- }
- dir += "/.config"
- }
- }
-
- return dir, nil
-}
-
-// UserHomeDir returns the current user's home directory.
-//
-// On Unix, including macOS, it returns the $HOME environment variable.
-// On Windows, it returns %USERPROFILE%.
-// On Plan 9, it returns the $home environment variable.
-func UserHomeDir() (string, error) {
- env, enverr := "HOME", "$HOME"
- switch runtime.GOOS {
- case "windows":
- env, enverr = "USERPROFILE", "%userprofile%"
- case "plan9":
- env, enverr = "home", "$home"
- }
- if v := Getenv(env); v != "" {
- return v, nil
- }
- // On some geese the home directory is not always defined.
- switch runtime.GOOS {
- case "android":
- return "/sdcard", nil
- case "ios":
- return "/", nil
- }
- return "", errors.New(enverr + " is not defined")
-}
-
-// Chmod changes the mode of the named file to mode.
-// If the file is a symbolic link, it changes the mode of the link's target.
-// If there is an error, it will be of type *PathError.
-//
-// A different subset of the mode bits are used, depending on the
-// operating system.
-//
-// On Unix, the mode's permission bits, ModeSetuid, ModeSetgid, and
-// ModeSticky are used.
-//
-// On Windows, only the 0200 bit (owner writable) of mode is used; it
-// controls whether the file's read-only attribute is set or cleared.
-// The other bits are currently unused. For compatibility with Go 1.12
-// and earlier, use a non-zero mode. Use mode 0400 for a read-only
-// file and 0600 for a readable+writable file.
-//
-// On Plan 9, the mode's permission bits, ModeAppend, ModeExclusive,
-// and ModeTemporary are used.
-func Chmod(name string, mode FileMode) error { return chmod(name, mode) }
-
-// Chmod changes the mode of the file to mode.
-// If there is an error, it will be of type *PathError.
-func (f *File) Chmod(mode FileMode) error { return f.chmod(mode) }
-
-// SetDeadline sets the read and write deadlines for a File.
-// It is equivalent to calling both SetReadDeadline and SetWriteDeadline.
-//
-// Only some kinds of files support setting a deadline. Calls to SetDeadline
-// for files that do not support deadlines will return ErrNoDeadline.
-// On most systems ordinary files do not support deadlines, but pipes do.
-//
-// A deadline is an absolute time after which I/O operations fail with an
-// error instead of blocking. The deadline applies to all future and pending
-// I/O, not just the immediately following call to Read or Write.
-// After a deadline has been exceeded, the connection can be refreshed
-// by setting a deadline in the future.
-//
-// If the deadline is exceeded a call to Read or Write or to other I/O
-// methods will return an error that wraps ErrDeadlineExceeded.
-// This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
-// That error implements the Timeout method, and calling the Timeout
-// method will return true, but there are other possible errors for which
-// the Timeout will return true even if the deadline has not been exceeded.
-//
-// An idle timeout can be implemented by repeatedly extending
-// the deadline after successful Read or Write calls.
-//
-// A zero value for t means I/O operations will not time out.
-func (f *File) SetDeadline(t time.Time) error {
- return f.setDeadline(t)
-}
-
-// SetReadDeadline sets the deadline for future Read calls and any
-// currently-blocked Read call.
-// A zero value for t means Read will not time out.
-// Not all files support setting deadlines; see SetDeadline.
-func (f *File) SetReadDeadline(t time.Time) error {
- return f.setReadDeadline(t)
-}
-
-// SetWriteDeadline sets the deadline for any future Write calls and any
-// currently-blocked Write call.
-// Even if Write times out, it may return n > 0, indicating that
-// some of the data was successfully written.
-// A zero value for t means Write will not time out.
-// Not all files support setting deadlines; see SetDeadline.
-func (f *File) SetWriteDeadline(t time.Time) error {
- return f.setWriteDeadline(t)
-}
-
-// SyscallConn returns a raw file.
-// This implements the syscall.Conn interface.
-func (f *File) SyscallConn() (syscall.RawConn, error) {
- if err := f.checkValid("SyscallConn"); err != nil {
- return nil, err
- }
- return newRawConn(f)
-}
-
-// DirFS returns a file system (an fs.FS) for the tree of files rooted at the directory dir.
-//
-// Note that DirFS("/prefix") only guarantees that the Open calls it makes to the
-// operating system will begin with "/prefix": DirFS("/prefix").Open("file") is the
-// same as os.Open("/prefix/file"). So if /prefix/file is a symbolic link pointing outside
-// the /prefix tree, then using DirFS does not stop the access any more than using
-// os.Open does. Additionally, the root of the fs.FS returned for a relative path,
-// DirFS("prefix"), will be affected by later calls to Chdir. DirFS is therefore not
-// a general substitute for a chroot-style security mechanism when the directory tree
-// contains arbitrary content.
-//
-// The directory dir must not be "".
-//
-// The result implements fs.StatFS.
-func DirFS(dir string) fs.FS {
- return dirFS(dir)
-}
-
-// containsAny reports whether any bytes in chars are within s.
-func containsAny(s, chars string) bool {
- for i := 0; i < len(s); i++ {
- for j := 0; j < len(chars); j++ {
- if s[i] == chars[j] {
- return true
- }
- }
- }
- return false
-}
-
-type dirFS string
-
-func (dir dirFS) Open(name string) (fs.File, error) {
- fullname, err := dir.join(name)
- if err != nil {
- return nil, &PathError{Op: "stat", Path: name, Err: err}
- }
- f, err := Open(fullname)
- if err != nil {
- // DirFS takes a string appropriate for GOOS,
- // while the name argument here is always slash separated.
- // dir.join will have mixed the two; undo that for
- // error reporting.
- err.(*PathError).Path = name
- return nil, err
- }
- return f, nil
-}
-
-func (dir dirFS) Stat(name string) (fs.FileInfo, error) {
- fullname, err := dir.join(name)
- if err != nil {
- return nil, &PathError{Op: "stat", Path: name, Err: err}
- }
- f, err := Stat(fullname)
- if err != nil {
- // See comment in dirFS.Open.
- err.(*PathError).Path = name
- return nil, err
- }
- return f, nil
-}
-
-// join returns the path for name in dir.
-func (dir dirFS) join(name string) (string, error) {
- if dir == "" {
- return "", errors.New("os: DirFS with empty root")
- }
- if !fs.ValidPath(name) {
- return "", ErrInvalid
- }
- name, err := safefilepath.FromFS(name)
- if err != nil {
- return "", ErrInvalid
- }
- if IsPathSeparator(dir[len(dir)-1]) {
- return string(dir) + name, nil
- }
- return string(dir) + string(PathSeparator) + name, nil
-}
-
-// ReadFile reads the named file and returns the contents.
-// A successful call returns err == nil, not err == EOF.
-// Because ReadFile reads the whole file, it does not treat an EOF from Read
-// as an error to be reported.
-func ReadFile(name string) ([]byte, error) {
- f, err := Open(name)
- if err != nil {
- return nil, err
- }
- defer f.Close()
-
- var size int
- if info, err := f.Stat(); err == nil {
- size64 := info.Size()
- if int64(int(size64)) == size64 {
- size = int(size64)
- }
- }
- size++ // one byte for final read at EOF
-
- // If a file claims a small size, read at least 512 bytes.
- // In particular, files in Linux's /proc claim size 0 but
- // then do not work right if read in small pieces,
- // so an initial read of 1 byte would not work correctly.
- if size < 512 {
- size = 512
- }
-
- data := make([]byte, 0, size)
- for {
- if len(data) >= cap(data) {
- d := append(data[:cap(data)], 0)
- data = d[:len(data)]
- }
- n, err := f.Read(data[len(data):cap(data)])
- data = data[:len(data)+n]
- if err != nil {
- if err == io.EOF {
- err = nil
- }
- return data, err
- }
- }
-}
-
-// WriteFile writes data to the named file, creating it if necessary.
-// If the file does not exist, WriteFile creates it with permissions perm (before umask);
-// otherwise WriteFile truncates it before writing, without changing permissions.
-// Since Writefile requires multiple system calls to complete, a failure mid-operation
-// can leave the file in a partially written state.
-func WriteFile(name string, data []byte, perm FileMode) error {
- f, err := OpenFile(name, O_WRONLY|O_CREATE|O_TRUNC, perm)
- if err != nil {
- return err
- }
- _, err = f.Write(data)
- if err1 := f.Close(); err1 != nil && err == nil {
- err = err1
- }
- return err
-}
diff --git a/contrib/go/_std_1.20/src/os/file_posix.go b/contrib/go/_std_1.20/src/os/file_posix.go
deleted file mode 100644
index c6d18ffeb6..0000000000
--- a/contrib/go/_std_1.20/src/os/file_posix.go
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix || (js && wasm) || windows
-
-package os
-
-import (
- "runtime"
- "syscall"
- "time"
-)
-
-func sigpipe() // implemented in package runtime
-
-// Close closes the File, rendering it unusable for I/O.
-// On files that support SetDeadline, any pending I/O operations will
-// be canceled and return immediately with an ErrClosed error.
-// Close will return an error if it has already been called.
-func (f *File) Close() error {
- if f == nil {
- return ErrInvalid
- }
- return f.file.close()
-}
-
-// read reads up to len(b) bytes from the File.
-// It returns the number of bytes read and an error, if any.
-func (f *File) read(b []byte) (n int, err error) {
- n, err = f.pfd.Read(b)
- runtime.KeepAlive(f)
- return n, err
-}
-
-// pread reads len(b) bytes from the File starting at byte offset off.
-// It returns the number of bytes read and the error, if any.
-// EOF is signaled by a zero count with err set to nil.
-func (f *File) pread(b []byte, off int64) (n int, err error) {
- n, err = f.pfd.Pread(b, off)
- runtime.KeepAlive(f)
- return n, err
-}
-
-// write writes len(b) bytes to the File.
-// It returns the number of bytes written and an error, if any.
-func (f *File) write(b []byte) (n int, err error) {
- n, err = f.pfd.Write(b)
- runtime.KeepAlive(f)
- return n, err
-}
-
-// pwrite writes len(b) bytes to the File starting at byte offset off.
-// It returns the number of bytes written and an error, if any.
-func (f *File) pwrite(b []byte, off int64) (n int, err error) {
- n, err = f.pfd.Pwrite(b, off)
- runtime.KeepAlive(f)
- return n, err
-}
-
-// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
-func syscallMode(i FileMode) (o uint32) {
- o |= uint32(i.Perm())
- if i&ModeSetuid != 0 {
- o |= syscall.S_ISUID
- }
- if i&ModeSetgid != 0 {
- o |= syscall.S_ISGID
- }
- if i&ModeSticky != 0 {
- o |= syscall.S_ISVTX
- }
- // No mapping for Go's ModeTemporary (plan9 only).
- return
-}
-
-// See docs in file.go:Chmod.
-func chmod(name string, mode FileMode) error {
- longName := fixLongPath(name)
- e := ignoringEINTR(func() error {
- return syscall.Chmod(longName, syscallMode(mode))
- })
- if e != nil {
- return &PathError{Op: "chmod", Path: name, Err: e}
- }
- return nil
-}
-
-// See docs in file.go:(*File).Chmod.
-func (f *File) chmod(mode FileMode) error {
- if err := f.checkValid("chmod"); err != nil {
- return err
- }
- if e := f.pfd.Fchmod(syscallMode(mode)); e != nil {
- return f.wrapErr("chmod", e)
- }
- return nil
-}
-
-// Chown changes the numeric uid and gid of the named file.
-// If the file is a symbolic link, it changes the uid and gid of the link's target.
-// A uid or gid of -1 means to not change that value.
-// If there is an error, it will be of type *PathError.
-//
-// On Windows or Plan 9, Chown always returns the syscall.EWINDOWS or
-// EPLAN9 error, wrapped in *PathError.
-func Chown(name string, uid, gid int) error {
- e := ignoringEINTR(func() error {
- return syscall.Chown(name, uid, gid)
- })
- if e != nil {
- return &PathError{Op: "chown", Path: name, Err: e}
- }
- return nil
-}
-
-// Lchown changes the numeric uid and gid of the named file.
-// If the file is a symbolic link, it changes the uid and gid of the link itself.
-// If there is an error, it will be of type *PathError.
-//
-// On Windows, it always returns the syscall.EWINDOWS error, wrapped
-// in *PathError.
-func Lchown(name string, uid, gid int) error {
- e := ignoringEINTR(func() error {
- return syscall.Lchown(name, uid, gid)
- })
- if e != nil {
- return &PathError{Op: "lchown", Path: name, Err: e}
- }
- return nil
-}
-
-// Chown changes the numeric uid and gid of the named file.
-// If there is an error, it will be of type *PathError.
-//
-// On Windows, it always returns the syscall.EWINDOWS error, wrapped
-// in *PathError.
-func (f *File) Chown(uid, gid int) error {
- if err := f.checkValid("chown"); err != nil {
- return err
- }
- if e := f.pfd.Fchown(uid, gid); e != nil {
- return f.wrapErr("chown", e)
- }
- return nil
-}
-
-// Truncate changes the size of the file.
-// It does not change the I/O offset.
-// If there is an error, it will be of type *PathError.
-func (f *File) Truncate(size int64) error {
- if err := f.checkValid("truncate"); err != nil {
- return err
- }
- if e := f.pfd.Ftruncate(size); e != nil {
- return f.wrapErr("truncate", e)
- }
- return nil
-}
-
-// Sync commits the current contents of the file to stable storage.
-// Typically, this means flushing the file system's in-memory copy
-// of recently written data to disk.
-func (f *File) Sync() error {
- if err := f.checkValid("sync"); err != nil {
- return err
- }
- if e := f.pfd.Fsync(); e != nil {
- return f.wrapErr("sync", e)
- }
- return nil
-}
-
-// Chtimes changes the access and modification times of the named
-// file, similar to the Unix utime() or utimes() functions.
-//
-// The underlying filesystem may truncate or round the values to a
-// less precise time unit.
-// If there is an error, it will be of type *PathError.
-func Chtimes(name string, atime time.Time, mtime time.Time) error {
- var utimes [2]syscall.Timespec
- utimes[0] = syscall.NsecToTimespec(atime.UnixNano())
- utimes[1] = syscall.NsecToTimespec(mtime.UnixNano())
- if e := syscall.UtimesNano(fixLongPath(name), utimes[0:]); e != nil {
- return &PathError{Op: "chtimes", Path: name, Err: e}
- }
- return nil
-}
-
-// Chdir changes the current working directory to the file,
-// which must be a directory.
-// If there is an error, it will be of type *PathError.
-func (f *File) Chdir() error {
- if err := f.checkValid("chdir"); err != nil {
- return err
- }
- if e := f.pfd.Fchdir(); e != nil {
- return f.wrapErr("chdir", e)
- }
- return nil
-}
-
-// setDeadline sets the read and write deadline.
-func (f *File) setDeadline(t time.Time) error {
- if err := f.checkValid("SetDeadline"); err != nil {
- return err
- }
- return f.pfd.SetDeadline(t)
-}
-
-// setReadDeadline sets the read deadline.
-func (f *File) setReadDeadline(t time.Time) error {
- if err := f.checkValid("SetReadDeadline"); err != nil {
- return err
- }
- return f.pfd.SetReadDeadline(t)
-}
-
-// setWriteDeadline sets the write deadline.
-func (f *File) setWriteDeadline(t time.Time) error {
- if err := f.checkValid("SetWriteDeadline"); err != nil {
- return err
- }
- return f.pfd.SetWriteDeadline(t)
-}
-
-// checkValid checks whether f is valid for use.
-// If not, it returns an appropriate error, perhaps incorporating the operation name op.
-func (f *File) checkValid(op string) error {
- if f == nil {
- return ErrInvalid
- }
- return nil
-}
-
-// ignoringEINTR makes a function call and repeats it if it returns an
-// EINTR error. This appears to be required even though we install all
-// signal handlers with SA_RESTART: see #22838, #38033, #38836, #40846.
-// Also #20400 and #36644 are issues in which a signal handler is
-// installed without setting SA_RESTART. None of these are the common case,
-// but there are enough of them that it seems that we can't avoid
-// an EINTR loop.
-func ignoringEINTR(fn func() error) error {
- for {
- err := fn()
- if err != syscall.EINTR {
- return err
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/os/file_unix.go b/contrib/go/_std_1.20/src/os/file_unix.go
deleted file mode 100644
index 72d03047c3..0000000000
--- a/contrib/go/_std_1.20/src/os/file_unix.go
+++ /dev/null
@@ -1,465 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix || (js && wasm)
-
-package os
-
-import (
- "internal/poll"
- "internal/syscall/unix"
- "runtime"
- "syscall"
- _ "unsafe" // for go:linkname
-
-)
-
-// fixLongPath is a noop on non-Windows platforms.
-func fixLongPath(path string) string {
- return path
-}
-
-func rename(oldname, newname string) error {
- fi, err := Lstat(newname)
- if err == nil && fi.IsDir() {
- // There are two independent errors this function can return:
- // one for a bad oldname, and one for a bad newname.
- // At this point we've determined the newname is bad.
- // But just in case oldname is also bad, prioritize returning
- // the oldname error because that's what we did historically.
- // However, if the old name and new name are not the same, yet
- // they refer to the same file, it implies a case-only
- // rename on a case-insensitive filesystem, which is ok.
- if ofi, err := Lstat(oldname); err != nil {
- if pe, ok := err.(*PathError); ok {
- err = pe.Err
- }
- return &LinkError{"rename", oldname, newname, err}
- } else if newname == oldname || !SameFile(fi, ofi) {
- return &LinkError{"rename", oldname, newname, syscall.EEXIST}
- }
- }
- err = ignoringEINTR(func() error {
- return syscall.Rename(oldname, newname)
- })
- if err != nil {
- return &LinkError{"rename", oldname, newname, err}
- }
- return nil
-}
-
-// file is the real representation of *File.
-// The extra level of indirection ensures that no clients of os
-// can overwrite this data, which could cause the finalizer
-// to close the wrong file descriptor.
-type file struct {
- pfd poll.FD
- name string
- dirinfo *dirInfo // nil unless directory being read
- nonblock bool // whether we set nonblocking mode
- stdoutOrErr bool // whether this is stdout or stderr
- appendMode bool // whether file is opened for appending
-}
-
-// Fd returns the integer Unix file descriptor referencing the open file.
-// If f is closed, the file descriptor becomes invalid.
-// If f is garbage collected, a finalizer may close the file descriptor,
-// making it invalid; see runtime.SetFinalizer for more information on when
-// a finalizer might be run. On Unix systems this will cause the SetDeadline
-// methods to stop working.
-// Because file descriptors can be reused, the returned file descriptor may
-// only be closed through the Close method of f, or by its finalizer during
-// garbage collection. Otherwise, during garbage collection the finalizer
-// may close an unrelated file descriptor with the same (reused) number.
-//
-// As an alternative, see the f.SyscallConn method.
-func (f *File) Fd() uintptr {
- if f == nil {
- return ^(uintptr(0))
- }
-
- // If we put the file descriptor into nonblocking mode,
- // then set it to blocking mode before we return it,
- // because historically we have always returned a descriptor
- // opened in blocking mode. The File will continue to work,
- // but any blocking operation will tie up a thread.
- if f.nonblock {
- f.pfd.SetBlocking()
- }
-
- return uintptr(f.pfd.Sysfd)
-}
-
-// NewFile returns a new File with the given file descriptor and
-// name. The returned value will be nil if fd is not a valid file
-// descriptor. On Unix systems, if the file descriptor is in
-// non-blocking mode, NewFile will attempt to return a pollable File
-// (one for which the SetDeadline methods work).
-//
-// After passing it to NewFile, fd may become invalid under the same
-// conditions described in the comments of the Fd method, and the same
-// constraints apply.
-func NewFile(fd uintptr, name string) *File {
- kind := kindNewFile
- if nb, err := unix.IsNonblock(int(fd)); err == nil && nb {
- kind = kindNonBlock
- }
- return newFile(fd, name, kind)
-}
-
-// net_newUnixFile is a hidden entry point called by net.conn.File.
-// This is used so that a nonblocking network connection will become
-// blocking if code calls the Fd method. We don't want that for direct
-// calls to NewFile: passing a nonblocking descriptor to NewFile should
-// remain nonblocking if you get it back using Fd. But for net.conn.File
-// the call to NewFile is hidden from the user. Historically in that case
-// the Fd method has returned a blocking descriptor, and we want to
-// retain that behavior because existing code expects it and depends on it.
-//
-//go:linkname net_newUnixFile net.newUnixFile
-func net_newUnixFile(fd uintptr, name string) *File {
- f := newFile(fd, name, kindNonBlock)
- f.nonblock = true // tell Fd to return blocking descriptor
- return f
-}
-
-// newFileKind describes the kind of file to newFile.
-type newFileKind int
-
-const (
- kindNewFile newFileKind = iota
- kindOpenFile
- kindPipe
- kindNonBlock
-)
-
-// newFile is like NewFile, but if called from OpenFile or Pipe
-// (as passed in the kind parameter) it tries to add the file to
-// the runtime poller.
-func newFile(fd uintptr, name string, kind newFileKind) *File {
- fdi := int(fd)
- if fdi < 0 {
- return nil
- }
- f := &File{&file{
- pfd: poll.FD{
- Sysfd: fdi,
- IsStream: true,
- ZeroReadIsEOF: true,
- },
- name: name,
- stdoutOrErr: fdi == 1 || fdi == 2,
- }}
-
- pollable := kind == kindOpenFile || kind == kindPipe || kind == kindNonBlock
-
- // If the caller passed a non-blocking filedes (kindNonBlock),
- // we assume they know what they are doing so we allow it to be
- // used with kqueue.
- if kind == kindOpenFile {
- switch runtime.GOOS {
- case "darwin", "ios", "dragonfly", "freebsd", "netbsd", "openbsd":
- var st syscall.Stat_t
- err := ignoringEINTR(func() error {
- return syscall.Fstat(fdi, &st)
- })
- typ := st.Mode & syscall.S_IFMT
- // Don't try to use kqueue with regular files on *BSDs.
- // On FreeBSD a regular file is always
- // reported as ready for writing.
- // On Dragonfly, NetBSD and OpenBSD the fd is signaled
- // only once as ready (both read and write).
- // Issue 19093.
- // Also don't add directories to the netpoller.
- if err == nil && (typ == syscall.S_IFREG || typ == syscall.S_IFDIR) {
- pollable = false
- }
-
- // In addition to the behavior described above for regular files,
- // on Darwin, kqueue does not work properly with fifos:
- // closing the last writer does not cause a kqueue event
- // for any readers. See issue #24164.
- if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && typ == syscall.S_IFIFO {
- pollable = false
- }
- }
- }
-
- clearNonBlock := false
- if pollable {
- if kind == kindNonBlock {
- // The descriptor is already in non-blocking mode.
- // We only set f.nonblock if we put the file into
- // non-blocking mode.
- } else if err := syscall.SetNonblock(fdi, true); err == nil {
- f.nonblock = true
- clearNonBlock = true
- } else {
- pollable = false
- }
- }
-
- // An error here indicates a failure to register
- // with the netpoll system. That can happen for
- // a file descriptor that is not supported by
- // epoll/kqueue; for example, disk files on
- // Linux systems. We assume that any real error
- // will show up in later I/O.
- // We do restore the blocking behavior if it was set by us.
- if pollErr := f.pfd.Init("file", pollable); pollErr != nil && clearNonBlock {
- if err := syscall.SetNonblock(fdi, false); err == nil {
- f.nonblock = false
- }
- }
-
- runtime.SetFinalizer(f.file, (*file).close)
- return f
-}
-
-// epipecheck raises SIGPIPE if we get an EPIPE error on standard
-// output or standard error. See the SIGPIPE docs in os/signal, and
-// issue 11845.
-func epipecheck(file *File, e error) {
- if e == syscall.EPIPE && file.stdoutOrErr {
- sigpipe()
- }
-}
-
-// DevNull is the name of the operating system's “null device.”
-// On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
-const DevNull = "/dev/null"
-
-// openFileNolog is the Unix implementation of OpenFile.
-// Changes here should be reflected in openFdAt, if relevant.
-func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
- setSticky := false
- if !supportsCreateWithStickyBit && flag&O_CREATE != 0 && perm&ModeSticky != 0 {
- if _, err := Stat(name); IsNotExist(err) {
- setSticky = true
- }
- }
-
- var r int
- for {
- var e error
- r, e = syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
- if e == nil {
- break
- }
-
- // We have to check EINTR here, per issues 11180 and 39237.
- if e == syscall.EINTR {
- continue
- }
-
- return nil, &PathError{Op: "open", Path: name, Err: e}
- }
-
- // open(2) itself won't handle the sticky bit on *BSD and Solaris
- if setSticky {
- setStickyBit(name)
- }
-
- // There's a race here with fork/exec, which we are
- // content to live with. See ../syscall/exec_unix.go.
- if !supportsCloseOnExec {
- syscall.CloseOnExec(r)
- }
-
- kind := kindOpenFile
- if unix.HasNonblockFlag(flag) {
- kind = kindNonBlock
- }
-
- return newFile(uintptr(r), name, kind), nil
-}
-
-func (file *file) close() error {
- if file == nil {
- return syscall.EINVAL
- }
- if file.dirinfo != nil {
- file.dirinfo.close()
- file.dirinfo = nil
- }
- var err error
- if e := file.pfd.Close(); e != nil {
- if e == poll.ErrFileClosing {
- e = ErrClosed
- }
- err = &PathError{Op: "close", Path: file.name, Err: e}
- }
-
- // no need for a finalizer anymore
- runtime.SetFinalizer(file, nil)
- return err
-}
-
-// seek sets the offset for the next Read or Write on file to offset, interpreted
-// according to whence: 0 means relative to the origin of the file, 1 means
-// relative to the current offset, and 2 means relative to the end.
-// It returns the new offset and an error, if any.
-func (f *File) seek(offset int64, whence int) (ret int64, err error) {
- if f.dirinfo != nil {
- // Free cached dirinfo, so we allocate a new one if we
- // access this file as a directory again. See #35767 and #37161.
- f.dirinfo.close()
- f.dirinfo = nil
- }
- ret, err = f.pfd.Seek(offset, whence)
- runtime.KeepAlive(f)
- return ret, err
-}
-
-// Truncate changes the size of the named file.
-// If the file is a symbolic link, it changes the size of the link's target.
-// If there is an error, it will be of type *PathError.
-func Truncate(name string, size int64) error {
- e := ignoringEINTR(func() error {
- return syscall.Truncate(name, size)
- })
- if e != nil {
- return &PathError{Op: "truncate", Path: name, Err: e}
- }
- return nil
-}
-
-// Remove removes the named file or (empty) directory.
-// If there is an error, it will be of type *PathError.
-func Remove(name string) error {
- // System call interface forces us to know
- // whether name is a file or directory.
- // Try both: it is cheaper on average than
- // doing a Stat plus the right one.
- e := ignoringEINTR(func() error {
- return syscall.Unlink(name)
- })
- if e == nil {
- return nil
- }
- e1 := ignoringEINTR(func() error {
- return syscall.Rmdir(name)
- })
- if e1 == nil {
- return nil
- }
-
- // Both failed: figure out which error to return.
- // OS X and Linux differ on whether unlink(dir)
- // returns EISDIR, so can't use that. However,
- // both agree that rmdir(file) returns ENOTDIR,
- // so we can use that to decide which error is real.
- // Rmdir might also return ENOTDIR if given a bad
- // file path, like /etc/passwd/foo, but in that case,
- // both errors will be ENOTDIR, so it's okay to
- // use the error from unlink.
- if e1 != syscall.ENOTDIR {
- e = e1
- }
- return &PathError{Op: "remove", Path: name, Err: e}
-}
-
-func tempDir() string {
- dir := Getenv("TMPDIR")
- if dir == "" {
- if runtime.GOOS == "android" {
- dir = "/data/local/tmp"
- } else {
- dir = "/tmp"
- }
- }
- return dir
-}
-
-// Link creates newname as a hard link to the oldname file.
-// If there is an error, it will be of type *LinkError.
-func Link(oldname, newname string) error {
- e := ignoringEINTR(func() error {
- return syscall.Link(oldname, newname)
- })
- if e != nil {
- return &LinkError{"link", oldname, newname, e}
- }
- return nil
-}
-
-// Symlink creates newname as a symbolic link to oldname.
-// On Windows, a symlink to a non-existent oldname creates a file symlink;
-// if oldname is later created as a directory the symlink will not work.
-// If there is an error, it will be of type *LinkError.
-func Symlink(oldname, newname string) error {
- e := ignoringEINTR(func() error {
- return syscall.Symlink(oldname, newname)
- })
- if e != nil {
- return &LinkError{"symlink", oldname, newname, e}
- }
- return nil
-}
-
-// Readlink returns the destination of the named symbolic link.
-// If there is an error, it will be of type *PathError.
-func Readlink(name string) (string, error) {
- for len := 128; ; len *= 2 {
- b := make([]byte, len)
- var (
- n int
- e error
- )
- for {
- n, e = fixCount(syscall.Readlink(name, b))
- if e != syscall.EINTR {
- break
- }
- }
- // buffer too small
- if runtime.GOOS == "aix" && e == syscall.ERANGE {
- continue
- }
- if e != nil {
- return "", &PathError{Op: "readlink", Path: name, Err: e}
- }
- if n < len {
- return string(b[0:n]), nil
- }
- }
-}
-
-type unixDirent struct {
- parent string
- name string
- typ FileMode
- info FileInfo
-}
-
-func (d *unixDirent) Name() string { return d.name }
-func (d *unixDirent) IsDir() bool { return d.typ.IsDir() }
-func (d *unixDirent) Type() FileMode { return d.typ }
-
-func (d *unixDirent) Info() (FileInfo, error) {
- if d.info != nil {
- return d.info, nil
- }
- return lstat(d.parent + "/" + d.name)
-}
-
-func newUnixDirent(parent, name string, typ FileMode) (DirEntry, error) {
- ude := &unixDirent{
- parent: parent,
- name: name,
- typ: typ,
- }
- if typ != ^FileMode(0) && !testingForceReadDirLstat {
- return ude, nil
- }
-
- info, err := lstat(parent + "/" + name)
- if err != nil {
- return nil, err
- }
-
- ude.typ = info.Mode().Type()
- ude.info = info
- return ude, nil
-}
diff --git a/contrib/go/_std_1.20/src/os/file_windows.go b/contrib/go/_std_1.20/src/os/file_windows.go
deleted file mode 100644
index d94b78f524..0000000000
--- a/contrib/go/_std_1.20/src/os/file_windows.go
+++ /dev/null
@@ -1,509 +0,0 @@
-// Copyright 2009 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 os
-
-import (
- "errors"
- "internal/poll"
- "internal/syscall/windows"
- "runtime"
- "syscall"
- "unicode/utf16"
- "unsafe"
-)
-
-// file is the real representation of *File.
-// The extra level of indirection ensures that no clients of os
-// can overwrite this data, which could cause the finalizer
-// to close the wrong file descriptor.
-type file struct {
- pfd poll.FD
- name string
- dirinfo *dirInfo // nil unless directory being read
- appendMode bool // whether file is opened for appending
-}
-
-// Fd returns the Windows handle referencing the open file.
-// If f is closed, the file descriptor becomes invalid.
-// If f is garbage collected, a finalizer may close the file descriptor,
-// making it invalid; see runtime.SetFinalizer for more information on when
-// a finalizer might be run. On Unix systems this will cause the SetDeadline
-// methods to stop working.
-func (file *File) Fd() uintptr {
- if file == nil {
- return uintptr(syscall.InvalidHandle)
- }
- return uintptr(file.pfd.Sysfd)
-}
-
-// newFile returns a new File with the given file handle and name.
-// Unlike NewFile, it does not check that h is syscall.InvalidHandle.
-func newFile(h syscall.Handle, name string, kind string) *File {
- if kind == "file" {
- var m uint32
- if syscall.GetConsoleMode(h, &m) == nil {
- kind = "console"
- }
- if t, err := syscall.GetFileType(h); err == nil && t == syscall.FILE_TYPE_PIPE {
- kind = "pipe"
- }
- }
-
- f := &File{&file{
- pfd: poll.FD{
- Sysfd: h,
- IsStream: true,
- ZeroReadIsEOF: true,
- },
- name: name,
- }}
- runtime.SetFinalizer(f.file, (*file).close)
-
- // Ignore initialization errors.
- // Assume any problems will show up in later I/O.
- f.pfd.Init(kind, false)
-
- return f
-}
-
-// newConsoleFile creates new File that will be used as console.
-func newConsoleFile(h syscall.Handle, name string) *File {
- return newFile(h, name, "console")
-}
-
-// NewFile returns a new File with the given file descriptor and
-// name. The returned value will be nil if fd is not a valid file
-// descriptor.
-func NewFile(fd uintptr, name string) *File {
- h := syscall.Handle(fd)
- if h == syscall.InvalidHandle {
- return nil
- }
- return newFile(h, name, "file")
-}
-
-// Auxiliary information if the File describes a directory
-type dirInfo struct {
- h syscall.Handle // search handle created with FindFirstFile
- data syscall.Win32finddata
- path string
- isempty bool // set if FindFirstFile returns ERROR_FILE_NOT_FOUND
-}
-
-func (d *dirInfo) close() error {
- return syscall.FindClose(d.h)
-}
-
-func epipecheck(file *File, e error) {
-}
-
-// DevNull is the name of the operating system's “null device.”
-// On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
-const DevNull = "NUL"
-
-func openDir(name string) (d *dirInfo, e error) {
- var mask string
-
- path := fixLongPath(name)
-
- if len(path) == 2 && path[1] == ':' { // it is a drive letter, like C:
- mask = path + `*`
- } else if len(path) > 0 {
- lc := path[len(path)-1]
- if lc == '/' || lc == '\\' {
- mask = path + `*`
- } else {
- mask = path + `\*`
- }
- } else {
- mask = `\*`
- }
- maskp, e := syscall.UTF16PtrFromString(mask)
- if e != nil {
- return nil, e
- }
- d = new(dirInfo)
- d.h, e = syscall.FindFirstFile(maskp, &d.data)
- if e != nil {
- // FindFirstFile returns ERROR_FILE_NOT_FOUND when
- // no matching files can be found. Then, if directory
- // exists, we should proceed.
- // If FindFirstFile failed because name does not point
- // to a directory, we should return ENOTDIR.
- var fa syscall.Win32FileAttributeData
- pathp, e1 := syscall.UTF16PtrFromString(path)
- if e1 != nil {
- return nil, e
- }
- e1 = syscall.GetFileAttributesEx(pathp, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
- if e1 != nil {
- return nil, e
- }
- if fa.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY == 0 {
- return nil, syscall.ENOTDIR
- }
- if e != syscall.ERROR_FILE_NOT_FOUND {
- return nil, e
- }
- d.isempty = true
- }
- d.path = path
- if !isAbs(d.path) {
- d.path, e = syscall.FullPath(d.path)
- if e != nil {
- d.close()
- return nil, e
- }
- }
- return d, nil
-}
-
-// openFileNolog is the Windows implementation of OpenFile.
-func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
- if name == "" {
- return nil, &PathError{Op: "open", Path: name, Err: syscall.ENOENT}
- }
- path := fixLongPath(name)
- r, e := syscall.Open(path, flag|syscall.O_CLOEXEC, syscallMode(perm))
- if e != nil {
- // We should return EISDIR when we are trying to open a directory with write access.
- if e == syscall.ERROR_ACCESS_DENIED && (flag&O_WRONLY != 0 || flag&O_RDWR != 0) {
- pathp, e1 := syscall.UTF16PtrFromString(path)
- if e1 == nil {
- var fa syscall.Win32FileAttributeData
- e1 = syscall.GetFileAttributesEx(pathp, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
- if e1 == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
- e = syscall.EISDIR
- }
- }
- }
- return nil, &PathError{Op: "open", Path: name, Err: e}
- }
- f, e := newFile(r, name, "file"), nil
- if e != nil {
- return nil, &PathError{Op: "open", Path: name, Err: e}
- }
- return f, nil
-}
-
-func (file *file) close() error {
- if file == nil {
- return syscall.EINVAL
- }
- if file.dirinfo != nil {
- file.dirinfo.close()
- file.dirinfo = nil
- }
- var err error
- if e := file.pfd.Close(); e != nil {
- if e == poll.ErrFileClosing {
- e = ErrClosed
- }
- err = &PathError{Op: "close", Path: file.name, Err: e}
- }
-
- // no need for a finalizer anymore
- runtime.SetFinalizer(file, nil)
- return err
-}
-
-// seek sets the offset for the next Read or Write on file to offset, interpreted
-// according to whence: 0 means relative to the origin of the file, 1 means
-// relative to the current offset, and 2 means relative to the end.
-// It returns the new offset and an error, if any.
-func (f *File) seek(offset int64, whence int) (ret int64, err error) {
- if f.dirinfo != nil {
- // Free cached dirinfo, so we allocate a new one if we
- // access this file as a directory again. See #35767 and #37161.
- f.dirinfo.close()
- f.dirinfo = nil
- }
- ret, err = f.pfd.Seek(offset, whence)
- runtime.KeepAlive(f)
- return ret, err
-}
-
-// Truncate changes the size of the named file.
-// If the file is a symbolic link, it changes the size of the link's target.
-func Truncate(name string, size int64) error {
- f, e := OpenFile(name, O_WRONLY|O_CREATE, 0666)
- if e != nil {
- return e
- }
- defer f.Close()
- e1 := f.Truncate(size)
- if e1 != nil {
- return e1
- }
- return nil
-}
-
-// Remove removes the named file or directory.
-// If there is an error, it will be of type *PathError.
-func Remove(name string) error {
- p, e := syscall.UTF16PtrFromString(fixLongPath(name))
- if e != nil {
- return &PathError{Op: "remove", Path: name, Err: e}
- }
-
- // Go file interface forces us to know whether
- // name is a file or directory. Try both.
- e = syscall.DeleteFile(p)
- if e == nil {
- return nil
- }
- e1 := syscall.RemoveDirectory(p)
- if e1 == nil {
- return nil
- }
-
- // Both failed: figure out which error to return.
- if e1 != e {
- a, e2 := syscall.GetFileAttributes(p)
- if e2 != nil {
- e = e2
- } else {
- if a&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
- e = e1
- } else if a&syscall.FILE_ATTRIBUTE_READONLY != 0 {
- if e1 = syscall.SetFileAttributes(p, a&^syscall.FILE_ATTRIBUTE_READONLY); e1 == nil {
- if e = syscall.DeleteFile(p); e == nil {
- return nil
- }
- }
- }
- }
- }
- return &PathError{Op: "remove", Path: name, Err: e}
-}
-
-func rename(oldname, newname string) error {
- e := windows.Rename(fixLongPath(oldname), fixLongPath(newname))
- if e != nil {
- return &LinkError{"rename", oldname, newname, e}
- }
- return nil
-}
-
-// Pipe returns a connected pair of Files; reads from r return bytes written to w.
-// It returns the files and an error, if any. The Windows handles underlying
-// the returned files are marked as inheritable by child processes.
-func Pipe() (r *File, w *File, err error) {
- var p [2]syscall.Handle
- e := syscall.Pipe(p[:])
- if e != nil {
- return nil, nil, NewSyscallError("pipe", e)
- }
- return newFile(p[0], "|0", "pipe"), newFile(p[1], "|1", "pipe"), nil
-}
-
-func tempDir() string {
- n := uint32(syscall.MAX_PATH)
- for {
- b := make([]uint16, n)
- n, _ = syscall.GetTempPath(uint32(len(b)), &b[0])
- if n > uint32(len(b)) {
- continue
- }
- if n == 3 && b[1] == ':' && b[2] == '\\' {
- // Do nothing for path, like C:\.
- } else if n > 0 && b[n-1] == '\\' {
- // Otherwise remove terminating \.
- n--
- }
- return string(utf16.Decode(b[:n]))
- }
-}
-
-// Link creates newname as a hard link to the oldname file.
-// If there is an error, it will be of type *LinkError.
-func Link(oldname, newname string) error {
- n, err := syscall.UTF16PtrFromString(fixLongPath(newname))
- if err != nil {
- return &LinkError{"link", oldname, newname, err}
- }
- o, err := syscall.UTF16PtrFromString(fixLongPath(oldname))
- if err != nil {
- return &LinkError{"link", oldname, newname, err}
- }
- err = syscall.CreateHardLink(n, o, 0)
- if err != nil {
- return &LinkError{"link", oldname, newname, err}
- }
- return nil
-}
-
-// Symlink creates newname as a symbolic link to oldname.
-// On Windows, a symlink to a non-existent oldname creates a file symlink;
-// if oldname is later created as a directory the symlink will not work.
-// If there is an error, it will be of type *LinkError.
-func Symlink(oldname, newname string) error {
- // '/' does not work in link's content
- oldname = fromSlash(oldname)
-
- // need the exact location of the oldname when it's relative to determine if it's a directory
- destpath := oldname
- if v := volumeName(oldname); v == "" {
- if len(oldname) > 0 && IsPathSeparator(oldname[0]) {
- // oldname is relative to the volume containing newname.
- if v = volumeName(newname); v != "" {
- // Prepend the volume explicitly, because it may be different from the
- // volume of the current working directory.
- destpath = v + oldname
- }
- } else {
- // oldname is relative to newname.
- destpath = dirname(newname) + `\` + oldname
- }
- }
-
- fi, err := Stat(destpath)
- isdir := err == nil && fi.IsDir()
-
- n, err := syscall.UTF16PtrFromString(fixLongPath(newname))
- if err != nil {
- return &LinkError{"symlink", oldname, newname, err}
- }
- o, err := syscall.UTF16PtrFromString(fixLongPath(oldname))
- if err != nil {
- return &LinkError{"symlink", oldname, newname, err}
- }
-
- var flags uint32 = windows.SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
- if isdir {
- flags |= syscall.SYMBOLIC_LINK_FLAG_DIRECTORY
- }
- err = syscall.CreateSymbolicLink(n, o, flags)
- if err != nil {
- // the unprivileged create flag is unsupported
- // below Windows 10 (1703, v10.0.14972). retry without it.
- flags &^= windows.SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
- err = syscall.CreateSymbolicLink(n, o, flags)
- if err != nil {
- return &LinkError{"symlink", oldname, newname, err}
- }
- }
- return nil
-}
-
-// openSymlink calls CreateFile Windows API with FILE_FLAG_OPEN_REPARSE_POINT
-// parameter, so that Windows does not follow symlink, if path is a symlink.
-// openSymlink returns opened file handle.
-func openSymlink(path string) (syscall.Handle, error) {
- p, err := syscall.UTF16PtrFromString(path)
- if err != nil {
- return 0, err
- }
- attrs := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS)
- // Use FILE_FLAG_OPEN_REPARSE_POINT, otherwise CreateFile will follow symlink.
- // See https://docs.microsoft.com/en-us/windows/desktop/FileIO/symbolic-link-effects-on-file-systems-functions#createfile-and-createfiletransacted
- attrs |= syscall.FILE_FLAG_OPEN_REPARSE_POINT
- h, err := syscall.CreateFile(p, 0, 0, nil, syscall.OPEN_EXISTING, attrs, 0)
- if err != nil {
- return 0, err
- }
- return h, nil
-}
-
-// normaliseLinkPath converts absolute paths returned by
-// DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, ...)
-// into paths acceptable by all Windows APIs.
-// For example, it converts
-//
-// \??\C:\foo\bar into C:\foo\bar
-// \??\UNC\foo\bar into \\foo\bar
-// \??\Volume{abc}\ into C:\
-func normaliseLinkPath(path string) (string, error) {
- if len(path) < 4 || path[:4] != `\??\` {
- // unexpected path, return it as is
- return path, nil
- }
- // we have path that start with \??\
- s := path[4:]
- switch {
- case len(s) >= 2 && s[1] == ':': // \??\C:\foo\bar
- return s, nil
- case len(s) >= 4 && s[:4] == `UNC\`: // \??\UNC\foo\bar
- return `\\` + s[4:], nil
- }
-
- // handle paths, like \??\Volume{abc}\...
-
- err := windows.LoadGetFinalPathNameByHandle()
- if err != nil {
- // we must be using old version of Windows
- return "", err
- }
-
- h, err := openSymlink(path)
- if err != nil {
- return "", err
- }
- defer syscall.CloseHandle(h)
-
- buf := make([]uint16, 100)
- for {
- n, err := windows.GetFinalPathNameByHandle(h, &buf[0], uint32(len(buf)), windows.VOLUME_NAME_DOS)
- if err != nil {
- return "", err
- }
- if n < uint32(len(buf)) {
- break
- }
- buf = make([]uint16, n)
- }
- s = syscall.UTF16ToString(buf)
- if len(s) > 4 && s[:4] == `\\?\` {
- s = s[4:]
- if len(s) > 3 && s[:3] == `UNC` {
- // return path like \\server\share\...
- return `\` + s[3:], nil
- }
- return s, nil
- }
- return "", errors.New("GetFinalPathNameByHandle returned unexpected path: " + s)
-}
-
-func readlink(path string) (string, error) {
- h, err := openSymlink(path)
- if err != nil {
- return "", err
- }
- defer syscall.CloseHandle(h)
-
- rdbbuf := make([]byte, syscall.MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
- var bytesReturned uint32
- err = syscall.DeviceIoControl(h, syscall.FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
- if err != nil {
- return "", err
- }
-
- rdb := (*windows.REPARSE_DATA_BUFFER)(unsafe.Pointer(&rdbbuf[0]))
- switch rdb.ReparseTag {
- case syscall.IO_REPARSE_TAG_SYMLINK:
- rb := (*windows.SymbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.DUMMYUNIONNAME))
- s := rb.Path()
- if rb.Flags&windows.SYMLINK_FLAG_RELATIVE != 0 {
- return s, nil
- }
- return normaliseLinkPath(s)
- case windows.IO_REPARSE_TAG_MOUNT_POINT:
- return normaliseLinkPath((*windows.MountPointReparseBuffer)(unsafe.Pointer(&rdb.DUMMYUNIONNAME)).Path())
- default:
- // the path is not a symlink or junction but another type of reparse
- // point
- return "", syscall.ENOENT
- }
-}
-
-// Readlink returns the destination of the named symbolic link.
-// If there is an error, it will be of type *PathError.
-func Readlink(name string) (string, error) {
- s, err := readlink(fixLongPath(name))
- if err != nil {
- return "", &PathError{Op: "readlink", Path: name, Err: err}
- }
- return s, nil
-}
diff --git a/contrib/go/_std_1.20/src/os/path_unix.go b/contrib/go/_std_1.20/src/os/path_unix.go
deleted file mode 100644
index 3c6310a4df..0000000000
--- a/contrib/go/_std_1.20/src/os/path_unix.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2011 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.
-
-//go:build unix || (js && wasm)
-
-package os
-
-const (
- PathSeparator = '/' // OS-specific path separator
- PathListSeparator = ':' // OS-specific path list separator
-)
-
-// IsPathSeparator reports whether c is a directory separator character.
-func IsPathSeparator(c uint8) bool {
- return PathSeparator == c
-}
-
-// basename removes trailing slashes and the leading directory name from path name.
-func basename(name string) string {
- i := len(name) - 1
- // Remove trailing slashes
- for ; i > 0 && name[i] == '/'; i-- {
- name = name[:i]
- }
- // Remove leading directory name
- for i--; i >= 0; i-- {
- if name[i] == '/' {
- name = name[i+1:]
- break
- }
- }
-
- return name
-}
-
-// splitPath returns the base name and parent directory.
-func splitPath(path string) (string, string) {
- // if no better parent is found, the path is relative from "here"
- dirname := "."
-
- // Remove all but one leading slash.
- for len(path) > 1 && path[0] == '/' && path[1] == '/' {
- path = path[1:]
- }
-
- i := len(path) - 1
-
- // Remove trailing slashes.
- for ; i > 0 && path[i] == '/'; i-- {
- path = path[:i]
- }
-
- // if no slashes in path, base is path
- basename := path
-
- // Remove leading directory path
- for i--; i >= 0; i-- {
- if path[i] == '/' {
- if i == 0 {
- dirname = path[:1]
- } else {
- dirname = path[:i]
- }
- basename = path[i+1:]
- break
- }
- }
-
- return dirname, basename
-}
-
-func fixRootDirectory(p string) string {
- return p
-}
diff --git a/contrib/go/_std_1.20/src/os/pipe2_unix.go b/contrib/go/_std_1.20/src/os/pipe2_unix.go
deleted file mode 100644
index 1e2e8ccb67..0000000000
--- a/contrib/go/_std_1.20/src/os/pipe2_unix.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2017 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.
-
-//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris
-
-package os
-
-import "syscall"
-
-// Pipe returns a connected pair of Files; reads from r return bytes written to w.
-// It returns the files and an error, if any.
-func Pipe() (r *File, w *File, err error) {
- var p [2]int
-
- e := syscall.Pipe2(p[0:], syscall.O_CLOEXEC)
- if e != nil {
- return nil, nil, NewSyscallError("pipe2", e)
- }
-
- return newFile(uintptr(p[0]), "|0", kindPipe), newFile(uintptr(p[1]), "|1", kindPipe), nil
-}
diff --git a/contrib/go/_std_1.20/src/os/pipe_unix.go b/contrib/go/_std_1.20/src/os/pipe_unix.go
deleted file mode 100644
index 710f77670e..0000000000
--- a/contrib/go/_std_1.20/src/os/pipe_unix.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2009 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.
-
-//go:build aix || darwin || (js && wasm)
-
-package os
-
-import "syscall"
-
-// Pipe returns a connected pair of Files; reads from r return bytes written to w.
-// It returns the files and an error, if any.
-func Pipe() (r *File, w *File, err error) {
- var p [2]int
-
- // See ../syscall/exec.go for description of lock.
- syscall.ForkLock.RLock()
- e := syscall.Pipe(p[0:])
- if e != nil {
- syscall.ForkLock.RUnlock()
- return nil, nil, NewSyscallError("pipe", e)
- }
- syscall.CloseOnExec(p[0])
- syscall.CloseOnExec(p[1])
- syscall.ForkLock.RUnlock()
-
- return newFile(uintptr(p[0]), "|0", kindPipe), newFile(uintptr(p[1]), "|1", kindPipe), nil
-}
diff --git a/contrib/go/_std_1.20/src/os/readfrom_linux.go b/contrib/go/_std_1.20/src/os/readfrom_linux.go
deleted file mode 100644
index 63ea45cf65..0000000000
--- a/contrib/go/_std_1.20/src/os/readfrom_linux.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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 os
-
-import (
- "internal/poll"
- "io"
-)
-
-var pollCopyFileRange = poll.CopyFileRange
-
-func (f *File) readFrom(r io.Reader) (written int64, handled bool, err error) {
- // copy_file_range(2) does not support destinations opened with
- // O_APPEND, so don't even try.
- if f.appendMode {
- return 0, false, nil
- }
-
- remain := int64(1 << 62)
-
- lr, ok := r.(*io.LimitedReader)
- if ok {
- remain, r = lr.N, lr.R
- if remain <= 0 {
- return 0, true, nil
- }
- }
-
- src, ok := r.(*File)
- if !ok {
- return 0, false, nil
- }
- if src.checkValid("ReadFrom") != nil {
- // Avoid returning the error as we report handled as false,
- // leave further error handling as the responsibility of the caller.
- return 0, false, nil
- }
-
- written, handled, err = pollCopyFileRange(&f.pfd, &src.pfd, remain)
- if lr != nil {
- lr.N -= written
- }
- return written, handled, NewSyscallError("copy_file_range", err)
-}
diff --git a/contrib/go/_std_1.20/src/os/removeall_at.go b/contrib/go/_std_1.20/src/os/removeall_at.go
deleted file mode 100644
index 8b46152a9e..0000000000
--- a/contrib/go/_std_1.20/src/os/removeall_at.go
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2018 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.
-
-//go:build unix
-
-package os
-
-import (
- "internal/syscall/unix"
- "io"
- "syscall"
-)
-
-func removeAll(path string) error {
- if path == "" {
- // fail silently to retain compatibility with previous behavior
- // of RemoveAll. See issue 28830.
- return nil
- }
-
- // The rmdir system call does not permit removing ".",
- // so we don't permit it either.
- if endsWithDot(path) {
- return &PathError{Op: "RemoveAll", Path: path, Err: syscall.EINVAL}
- }
-
- // Simple case: if Remove works, we're done.
- err := Remove(path)
- if err == nil || IsNotExist(err) {
- return nil
- }
-
- // RemoveAll recurses by deleting the path base from
- // its parent directory
- parentDir, base := splitPath(path)
-
- parent, err := Open(parentDir)
- if IsNotExist(err) {
- // If parent does not exist, base cannot exist. Fail silently
- return nil
- }
- if err != nil {
- return err
- }
- defer parent.Close()
-
- if err := removeAllFrom(parent, base); err != nil {
- if pathErr, ok := err.(*PathError); ok {
- pathErr.Path = parentDir + string(PathSeparator) + pathErr.Path
- err = pathErr
- }
- return err
- }
- return nil
-}
-
-func removeAllFrom(parent *File, base string) error {
- parentFd := int(parent.Fd())
- // Simple case: if Unlink (aka remove) works, we're done.
- err := unix.Unlinkat(parentFd, base, 0)
- if err == nil || IsNotExist(err) {
- return nil
- }
-
- // EISDIR means that we have a directory, and we need to
- // remove its contents.
- // EPERM or EACCES means that we don't have write permission on
- // the parent directory, but this entry might still be a directory
- // whose contents need to be removed.
- // Otherwise just return the error.
- if err != syscall.EISDIR && err != syscall.EPERM && err != syscall.EACCES {
- return &PathError{Op: "unlinkat", Path: base, Err: err}
- }
-
- // Is this a directory we need to recurse into?
- var statInfo syscall.Stat_t
- statErr := unix.Fstatat(parentFd, base, &statInfo, unix.AT_SYMLINK_NOFOLLOW)
- if statErr != nil {
- if IsNotExist(statErr) {
- return nil
- }
- return &PathError{Op: "fstatat", Path: base, Err: statErr}
- }
- if statInfo.Mode&syscall.S_IFMT != syscall.S_IFDIR {
- // Not a directory; return the error from the unix.Unlinkat.
- return &PathError{Op: "unlinkat", Path: base, Err: err}
- }
-
- // Remove the directory's entries.
- var recurseErr error
- for {
- const reqSize = 1024
- var respSize int
-
- // Open the directory to recurse into
- file, err := openFdAt(parentFd, base)
- if err != nil {
- if IsNotExist(err) {
- return nil
- }
- recurseErr = &PathError{Op: "openfdat", Path: base, Err: err}
- break
- }
-
- for {
- numErr := 0
-
- names, readErr := file.Readdirnames(reqSize)
- // Errors other than EOF should stop us from continuing.
- if readErr != nil && readErr != io.EOF {
- file.Close()
- if IsNotExist(readErr) {
- return nil
- }
- return &PathError{Op: "readdirnames", Path: base, Err: readErr}
- }
-
- respSize = len(names)
- for _, name := range names {
- err := removeAllFrom(file, name)
- if err != nil {
- if pathErr, ok := err.(*PathError); ok {
- pathErr.Path = base + string(PathSeparator) + pathErr.Path
- }
- numErr++
- if recurseErr == nil {
- recurseErr = err
- }
- }
- }
-
- // If we can delete any entry, break to start new iteration.
- // Otherwise, we discard current names, get next entries and try deleting them.
- if numErr != reqSize {
- break
- }
- }
-
- // Removing files from the directory may have caused
- // the OS to reshuffle it. Simply calling Readdirnames
- // again may skip some entries. The only reliable way
- // to avoid this is to close and re-open the
- // directory. See issue 20841.
- file.Close()
-
- // Finish when the end of the directory is reached
- if respSize < reqSize {
- break
- }
- }
-
- // Remove the directory itself.
- unlinkError := unix.Unlinkat(parentFd, base, unix.AT_REMOVEDIR)
- if unlinkError == nil || IsNotExist(unlinkError) {
- return nil
- }
-
- if recurseErr != nil {
- return recurseErr
- }
- return &PathError{Op: "unlinkat", Path: base, Err: unlinkError}
-}
-
-// openFdAt opens path relative to the directory in fd.
-// Other than that this should act like openFileNolog.
-// This acts like openFileNolog rather than OpenFile because
-// we are going to (try to) remove the file.
-// The contents of this file are not relevant for test caching.
-func openFdAt(dirfd int, name string) (*File, error) {
- var r int
- for {
- var e error
- r, e = unix.Openat(dirfd, name, O_RDONLY|syscall.O_CLOEXEC, 0)
- if e == nil {
- break
- }
-
- // See comment in openFileNolog.
- if e == syscall.EINTR {
- continue
- }
-
- return nil, e
- }
-
- if !supportsCloseOnExec {
- syscall.CloseOnExec(r)
- }
-
- return newFile(uintptr(r), name, kindOpenFile), nil
-}
diff --git a/contrib/go/_std_1.20/src/os/signal/doc.go b/contrib/go/_std_1.20/src/os/signal/doc.go
deleted file mode 100644
index 1b9f40d9a8..0000000000
--- a/contrib/go/_std_1.20/src/os/signal/doc.go
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2015 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 signal implements access to incoming signals.
-
-Signals are primarily used on Unix-like systems. For the use of this
-package on Windows and Plan 9, see below.
-
-# Types of signals
-
-The signals SIGKILL and SIGSTOP may not be caught by a program, and
-therefore cannot be affected by this package.
-
-Synchronous signals are signals triggered by errors in program
-execution: SIGBUS, SIGFPE, and SIGSEGV. These are only considered
-synchronous when caused by program execution, not when sent using
-os.Process.Kill or the kill program or some similar mechanism. In
-general, except as discussed below, Go programs will convert a
-synchronous signal into a run-time panic.
-
-The remaining signals are asynchronous signals. They are not
-triggered by program errors, but are instead sent from the kernel or
-from some other program.
-
-Of the asynchronous signals, the SIGHUP signal is sent when a program
-loses its controlling terminal. The SIGINT signal is sent when the
-user at the controlling terminal presses the interrupt character,
-which by default is ^C (Control-C). The SIGQUIT signal is sent when
-the user at the controlling terminal presses the quit character, which
-by default is ^\ (Control-Backslash). In general you can cause a
-program to simply exit by pressing ^C, and you can cause it to exit
-with a stack dump by pressing ^\.
-
-# Default behavior of signals in Go programs
-
-By default, a synchronous signal is converted into a run-time panic. A
-SIGHUP, SIGINT, or SIGTERM signal causes the program to exit. A
-SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT, or SIGSYS signal
-causes the program to exit with a stack dump. A SIGTSTP, SIGTTIN, or
-SIGTTOU signal gets the system default behavior (these signals are
-used by the shell for job control). The SIGPROF signal is handled
-directly by the Go runtime to implement runtime.CPUProfile. Other
-signals will be caught but no action will be taken.
-
-If the Go program is started with either SIGHUP or SIGINT ignored
-(signal handler set to SIG_IGN), they will remain ignored.
-
-If the Go program is started with a non-empty signal mask, that will
-generally be honored. However, some signals are explicitly unblocked:
-the synchronous signals, SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF,
-and, on Linux, signals 32 (SIGCANCEL) and 33 (SIGSETXID)
-(SIGCANCEL and SIGSETXID are used internally by glibc). Subprocesses
-started by os.Exec, or by the os/exec package, will inherit the
-modified signal mask.
-
-# Changing the behavior of signals in Go programs
-
-The functions in this package allow a program to change the way Go
-programs handle signals.
-
-Notify disables the default behavior for a given set of asynchronous
-signals and instead delivers them over one or more registered
-channels. Specifically, it applies to the signals SIGHUP, SIGINT,
-SIGQUIT, SIGABRT, and SIGTERM. It also applies to the job control
-signals SIGTSTP, SIGTTIN, and SIGTTOU, in which case the system
-default behavior does not occur. It also applies to some signals that
-otherwise cause no action: SIGUSR1, SIGUSR2, SIGPIPE, SIGALRM,
-SIGCHLD, SIGCONT, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGWINCH,
-SIGIO, SIGPWR, SIGSYS, SIGINFO, SIGTHR, SIGWAITING, SIGLWP, SIGFREEZE,
-SIGTHAW, SIGLOST, SIGXRES, SIGJVM1, SIGJVM2, and any real time signals
-used on the system. Note that not all of these signals are available
-on all systems.
-
-If the program was started with SIGHUP or SIGINT ignored, and Notify
-is called for either signal, a signal handler will be installed for
-that signal and it will no longer be ignored. If, later, Reset or
-Ignore is called for that signal, or Stop is called on all channels
-passed to Notify for that signal, the signal will once again be
-ignored. Reset will restore the system default behavior for the
-signal, while Ignore will cause the system to ignore the signal
-entirely.
-
-If the program is started with a non-empty signal mask, some signals
-will be explicitly unblocked as described above. If Notify is called
-for a blocked signal, it will be unblocked. If, later, Reset is
-called for that signal, or Stop is called on all channels passed to
-Notify for that signal, the signal will once again be blocked.
-
-# SIGPIPE
-
-When a Go program writes to a broken pipe, the kernel will raise a
-SIGPIPE signal.
-
-If the program has not called Notify to receive SIGPIPE signals, then
-the behavior depends on the file descriptor number. A write to a
-broken pipe on file descriptors 1 or 2 (standard output or standard
-error) will cause the program to exit with a SIGPIPE signal. A write
-to a broken pipe on some other file descriptor will take no action on
-the SIGPIPE signal, and the write will fail with an EPIPE error.
-
-If the program has called Notify to receive SIGPIPE signals, the file
-descriptor number does not matter. The SIGPIPE signal will be
-delivered to the Notify channel, and the write will fail with an EPIPE
-error.
-
-This means that, by default, command line programs will behave like
-typical Unix command line programs, while other programs will not
-crash with SIGPIPE when writing to a closed network connection.
-
-# Go programs that use cgo or SWIG
-
-In a Go program that includes non-Go code, typically C/C++ code
-accessed using cgo or SWIG, Go's startup code normally runs first. It
-configures the signal handlers as expected by the Go runtime, before
-the non-Go startup code runs. If the non-Go startup code wishes to
-install its own signal handlers, it must take certain steps to keep Go
-working well. This section documents those steps and the overall
-effect changes to signal handler settings by the non-Go code can have
-on Go programs. In rare cases, the non-Go code may run before the Go
-code, in which case the next section also applies.
-
-If the non-Go code called by the Go program does not change any signal
-handlers or masks, then the behavior is the same as for a pure Go
-program.
-
-If the non-Go code installs any signal handlers, it must use the
-SA_ONSTACK flag with sigaction. Failing to do so is likely to cause
-the program to crash if the signal is received. Go programs routinely
-run with a limited stack, and therefore set up an alternate signal
-stack.
-
-If the non-Go code installs a signal handler for any of the
-synchronous signals (SIGBUS, SIGFPE, SIGSEGV), then it should record
-the existing Go signal handler. If those signals occur while
-executing Go code, it should invoke the Go signal handler (whether the
-signal occurs while executing Go code can be determined by looking at
-the PC passed to the signal handler). Otherwise some Go run-time
-panics will not occur as expected.
-
-If the non-Go code installs a signal handler for any of the
-asynchronous signals, it may invoke the Go signal handler or not as it
-chooses. Naturally, if it does not invoke the Go signal handler, the
-Go behavior described above will not occur. This can be an issue with
-the SIGPROF signal in particular.
-
-The non-Go code should not change the signal mask on any threads
-created by the Go runtime. If the non-Go code starts new threads of
-its own, it may set the signal mask as it pleases.
-
-If the non-Go code starts a new thread, changes the signal mask, and
-then invokes a Go function in that thread, the Go runtime will
-automatically unblock certain signals: the synchronous signals,
-SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF, SIGCANCEL, and
-SIGSETXID. When the Go function returns, the non-Go signal mask will
-be restored.
-
-If the Go signal handler is invoked on a non-Go thread not running Go
-code, the handler generally forwards the signal to the non-Go code, as
-follows. If the signal is SIGPROF, the Go handler does
-nothing. Otherwise, the Go handler removes itself, unblocks the
-signal, and raises it again, to invoke any non-Go handler or default
-system handler. If the program does not exit, the Go handler then
-reinstalls itself and continues execution of the program.
-
-If a SIGPIPE signal is received, the Go program will invoke the
-special handling described above if the SIGPIPE is received on a Go
-thread. If the SIGPIPE is received on a non-Go thread the signal will
-be forwarded to the non-Go handler, if any; if there is none the
-default system handler will cause the program to terminate.
-
-# Non-Go programs that call Go code
-
-When Go code is built with options like -buildmode=c-shared, it will
-be run as part of an existing non-Go program. The non-Go code may
-have already installed signal handlers when the Go code starts (that
-may also happen in unusual cases when using cgo or SWIG; in that case,
-the discussion here applies). For -buildmode=c-archive the Go runtime
-will initialize signals at global constructor time. For
--buildmode=c-shared the Go runtime will initialize signals when the
-shared library is loaded.
-
-If the Go runtime sees an existing signal handler for the SIGCANCEL or
-SIGSETXID signals (which are used only on Linux), it will turn on
-the SA_ONSTACK flag and otherwise keep the signal handler.
-
-For the synchronous signals and SIGPIPE, the Go runtime will install a
-signal handler. It will save any existing signal handler. If a
-synchronous signal arrives while executing non-Go code, the Go runtime
-will invoke the existing signal handler instead of the Go signal
-handler.
-
-Go code built with -buildmode=c-archive or -buildmode=c-shared will
-not install any other signal handlers by default. If there is an
-existing signal handler, the Go runtime will turn on the SA_ONSTACK
-flag and otherwise keep the signal handler. If Notify is called for an
-asynchronous signal, a Go signal handler will be installed for that
-signal. If, later, Reset is called for that signal, the original
-handling for that signal will be reinstalled, restoring the non-Go
-signal handler if any.
-
-Go code built without -buildmode=c-archive or -buildmode=c-shared will
-install a signal handler for the asynchronous signals listed above,
-and save any existing signal handler. If a signal is delivered to a
-non-Go thread, it will act as described above, except that if there is
-an existing non-Go signal handler, that handler will be installed
-before raising the signal.
-
-# Windows
-
-On Windows a ^C (Control-C) or ^BREAK (Control-Break) normally cause
-the program to exit. If Notify is called for os.Interrupt, ^C or ^BREAK
-will cause os.Interrupt to be sent on the channel, and the program will
-not exit. If Reset is called, or Stop is called on all channels passed
-to Notify, then the default behavior will be restored.
-
-Additionally, if Notify is called, and Windows sends CTRL_CLOSE_EVENT,
-CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT to the process, Notify will
-return syscall.SIGTERM. Unlike Control-C and Control-Break, Notify does
-not change process behavior when either CTRL_CLOSE_EVENT,
-CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT is received - the process will
-still get terminated unless it exits. But receiving syscall.SIGTERM will
-give the process an opportunity to clean up before termination.
-
-# Plan 9
-
-On Plan 9, signals have type syscall.Note, which is a string. Calling
-Notify with a syscall.Note will cause that value to be sent on the
-channel when that string is posted as a note.
-*/
-package signal
diff --git a/contrib/go/_std_1.20/src/os/signal/signal_unix.go b/contrib/go/_std_1.20/src/os/signal/signal_unix.go
deleted file mode 100644
index 772175a922..0000000000
--- a/contrib/go/_std_1.20/src/os/signal/signal_unix.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2012 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.
-
-//go:build unix || (js && wasm) || windows
-
-package signal
-
-import (
- "os"
- "syscall"
-)
-
-// Defined by the runtime package.
-func signal_disable(uint32)
-func signal_enable(uint32)
-func signal_ignore(uint32)
-func signal_ignored(uint32) bool
-func signal_recv() uint32
-
-func loop() {
- for {
- process(syscall.Signal(signal_recv()))
- }
-}
-
-func init() {
- watchSignalLoop = loop
-}
-
-const (
- numSig = 65 // max across all systems
-)
-
-func signum(sig os.Signal) int {
- switch sig := sig.(type) {
- case syscall.Signal:
- i := int(sig)
- if i < 0 || i >= numSig {
- return -1
- }
- return i
- default:
- return -1
- }
-}
-
-func enableSignal(sig int) {
- signal_enable(uint32(sig))
-}
-
-func disableSignal(sig int) {
- signal_disable(uint32(sig))
-}
-
-func ignoreSignal(sig int) {
- signal_ignore(uint32(sig))
-}
-
-func signalIgnored(sig int) bool {
- return signal_ignored(uint32(sig))
-}
diff --git a/contrib/go/_std_1.20/src/os/signal/ya.make b/contrib/go/_std_1.20/src/os/signal/ya.make
deleted file mode 100644
index 1de608d623..0000000000
--- a/contrib/go/_std_1.20/src/os/signal/ya.make
+++ /dev/null
@@ -1,10 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- doc.go
- sig.s
- signal.go
- signal_unix.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/os/stat_unix.go b/contrib/go/_std_1.20/src/os/stat_unix.go
deleted file mode 100644
index 437afc02b4..0000000000
--- a/contrib/go/_std_1.20/src/os/stat_unix.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2016 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.
-
-//go:build unix || (js && wasm)
-
-package os
-
-import (
- "syscall"
-)
-
-// Stat returns the FileInfo structure describing file.
-// If there is an error, it will be of type *PathError.
-func (f *File) Stat() (FileInfo, error) {
- if f == nil {
- return nil, ErrInvalid
- }
- var fs fileStat
- err := f.pfd.Fstat(&fs.sys)
- if err != nil {
- return nil, &PathError{Op: "stat", Path: f.name, Err: err}
- }
- fillFileStatFromSys(&fs, f.name)
- return &fs, nil
-}
-
-// statNolog stats a file with no test logging.
-func statNolog(name string) (FileInfo, error) {
- var fs fileStat
- err := ignoringEINTR(func() error {
- return syscall.Stat(name, &fs.sys)
- })
- if err != nil {
- return nil, &PathError{Op: "stat", Path: name, Err: err}
- }
- fillFileStatFromSys(&fs, name)
- return &fs, nil
-}
-
-// lstatNolog lstats a file with no test logging.
-func lstatNolog(name string) (FileInfo, error) {
- var fs fileStat
- err := ignoringEINTR(func() error {
- return syscall.Lstat(name, &fs.sys)
- })
- if err != nil {
- return nil, &PathError{Op: "lstat", Path: name, Err: err}
- }
- fillFileStatFromSys(&fs, name)
- return &fs, nil
-}
diff --git a/contrib/go/_std_1.20/src/os/stat_windows.go b/contrib/go/_std_1.20/src/os/stat_windows.go
deleted file mode 100644
index 8747c19888..0000000000
--- a/contrib/go/_std_1.20/src/os/stat_windows.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2009 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 os
-
-import (
- "internal/syscall/windows"
- "syscall"
- "unsafe"
-)
-
-// Stat returns the FileInfo structure describing file.
-// If there is an error, it will be of type *PathError.
-func (file *File) Stat() (FileInfo, error) {
- if file == nil {
- return nil, ErrInvalid
- }
- return statHandle(file.name, file.pfd.Sysfd)
-}
-
-// stat implements both Stat and Lstat of a file.
-func stat(funcname, name string, createFileAttrs uint32) (FileInfo, error) {
- if len(name) == 0 {
- return nil, &PathError{Op: funcname, Path: name, Err: syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
- }
- namep, err := syscall.UTF16PtrFromString(fixLongPath(name))
- if err != nil {
- return nil, &PathError{Op: funcname, Path: name, Err: err}
- }
-
- // Try GetFileAttributesEx first, because it is faster than CreateFile.
- // See https://golang.org/issues/19922#issuecomment-300031421 for details.
- var fa syscall.Win32FileAttributeData
- err = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
- if err == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
- // Not a symlink.
- fs := &fileStat{
- FileAttributes: fa.FileAttributes,
- CreationTime: fa.CreationTime,
- LastAccessTime: fa.LastAccessTime,
- LastWriteTime: fa.LastWriteTime,
- FileSizeHigh: fa.FileSizeHigh,
- FileSizeLow: fa.FileSizeLow,
- }
- if err := fs.saveInfoFromPath(name); err != nil {
- return nil, err
- }
- return fs, nil
- }
- // GetFileAttributesEx fails with ERROR_SHARING_VIOLATION error for
- // files, like c:\pagefile.sys. Use FindFirstFile for such files.
- if err == windows.ERROR_SHARING_VIOLATION {
- var fd syscall.Win32finddata
- sh, err := syscall.FindFirstFile(namep, &fd)
- if err != nil {
- return nil, &PathError{Op: "FindFirstFile", Path: name, Err: err}
- }
- syscall.FindClose(sh)
- fs := newFileStatFromWin32finddata(&fd)
- if err := fs.saveInfoFromPath(name); err != nil {
- return nil, err
- }
- return fs, nil
- }
-
- // Finally use CreateFile.
- h, err := syscall.CreateFile(namep, 0, 0, nil,
- syscall.OPEN_EXISTING, createFileAttrs, 0)
- if err != nil {
- return nil, &PathError{Op: "CreateFile", Path: name, Err: err}
- }
- defer syscall.CloseHandle(h)
- return statHandle(name, h)
-}
-
-func statHandle(name string, h syscall.Handle) (FileInfo, error) {
- ft, err := syscall.GetFileType(h)
- if err != nil {
- return nil, &PathError{Op: "GetFileType", Path: name, Err: err}
- }
- switch ft {
- case syscall.FILE_TYPE_PIPE, syscall.FILE_TYPE_CHAR:
- return &fileStat{name: basename(name), filetype: ft}, nil
- }
- fs, err := newFileStatFromGetFileInformationByHandle(name, h)
- if err != nil {
- return nil, err
- }
- fs.filetype = ft
- return fs, err
-}
-
-// statNolog implements Stat for Windows.
-func statNolog(name string) (FileInfo, error) {
- return stat("Stat", name, syscall.FILE_FLAG_BACKUP_SEMANTICS)
-}
-
-// lstatNolog implements Lstat for Windows.
-func lstatNolog(name string) (FileInfo, error) {
- attrs := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS)
- // Use FILE_FLAG_OPEN_REPARSE_POINT, otherwise CreateFile will follow symlink.
- // See https://docs.microsoft.com/en-us/windows/desktop/FileIO/symbolic-link-effects-on-file-systems-functions#createfile-and-createfiletransacted
- attrs |= syscall.FILE_FLAG_OPEN_REPARSE_POINT
- return stat("Lstat", name, attrs)
-}
diff --git a/contrib/go/_std_1.20/src/os/sticky_bsd.go b/contrib/go/_std_1.20/src/os/sticky_bsd.go
deleted file mode 100644
index e71daf7c74..0000000000
--- a/contrib/go/_std_1.20/src/os/sticky_bsd.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 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.
-
-//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || netbsd || openbsd || solaris
-
-package os
-
-// According to sticky(8), neither open(2) nor mkdir(2) will create
-// a file with the sticky bit set.
-const supportsCreateWithStickyBit = false
diff --git a/contrib/go/_std_1.20/src/os/sticky_notbsd.go b/contrib/go/_std_1.20/src/os/sticky_notbsd.go
deleted file mode 100644
index 9a87fbde92..0000000000
--- a/contrib/go/_std_1.20/src/os/sticky_notbsd.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2014 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.
-
-//go:build !aix && !darwin && !dragonfly && !freebsd && (!js || !wasm) && !netbsd && !openbsd && !solaris
-
-package os
-
-const supportsCreateWithStickyBit = true
diff --git a/contrib/go/_std_1.20/src/os/sys_bsd.go b/contrib/go/_std_1.20/src/os/sys_bsd.go
deleted file mode 100644
index e272c24571..0000000000
--- a/contrib/go/_std_1.20/src/os/sys_bsd.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2009 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.
-
-//go:build darwin || dragonfly || freebsd || (js && wasm) || netbsd || openbsd
-
-package os
-
-import "syscall"
-
-func hostname() (name string, err error) {
- name, err = syscall.Sysctl("kern.hostname")
- if err != nil {
- return "", NewSyscallError("sysctl kern.hostname", err)
- }
- return name, nil
-}
diff --git a/contrib/go/_std_1.20/src/os/tempfile.go b/contrib/go/_std_1.20/src/os/tempfile.go
deleted file mode 100644
index 3be3d13dfb..0000000000
--- a/contrib/go/_std_1.20/src/os/tempfile.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2010 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 os
-
-import (
- "errors"
- "internal/itoa"
-)
-
-// fastrand provided by runtime.
-// We generate random temporary file names so that there's a good
-// chance the file doesn't exist yet - keeps the number of tries in
-// TempFile to a minimum.
-func fastrand() uint32
-
-func nextRandom() string {
- return itoa.Uitoa(uint(fastrand()))
-}
-
-// CreateTemp creates a new temporary file in the directory dir,
-// opens the file for reading and writing, and returns the resulting file.
-// The filename is generated by taking pattern and adding a random string to the end.
-// If pattern includes a "*", the random string replaces the last "*".
-// If dir is the empty string, CreateTemp uses the default directory for temporary files, as returned by TempDir.
-// Multiple programs or goroutines calling CreateTemp simultaneously will not choose the same file.
-// The caller can use the file's Name method to find the pathname of the file.
-// It is the caller's responsibility to remove the file when it is no longer needed.
-func CreateTemp(dir, pattern string) (*File, error) {
- if dir == "" {
- dir = TempDir()
- }
-
- prefix, suffix, err := prefixAndSuffix(pattern)
- if err != nil {
- return nil, &PathError{Op: "createtemp", Path: pattern, Err: err}
- }
- prefix = joinPath(dir, prefix)
-
- try := 0
- for {
- name := prefix + nextRandom() + suffix
- f, err := OpenFile(name, O_RDWR|O_CREATE|O_EXCL, 0600)
- if IsExist(err) {
- if try++; try < 10000 {
- continue
- }
- return nil, &PathError{Op: "createtemp", Path: prefix + "*" + suffix, Err: ErrExist}
- }
- return f, err
- }
-}
-
-var errPatternHasSeparator = errors.New("pattern contains path separator")
-
-// prefixAndSuffix splits pattern by the last wildcard "*", if applicable,
-// returning prefix as the part before "*" and suffix as the part after "*".
-func prefixAndSuffix(pattern string) (prefix, suffix string, err error) {
- for i := 0; i < len(pattern); i++ {
- if IsPathSeparator(pattern[i]) {
- return "", "", errPatternHasSeparator
- }
- }
- if pos := lastIndex(pattern, '*'); pos != -1 {
- prefix, suffix = pattern[:pos], pattern[pos+1:]
- } else {
- prefix = pattern
- }
- return prefix, suffix, nil
-}
-
-// MkdirTemp creates a new temporary directory in the directory dir
-// and returns the pathname of the new directory.
-// The new directory's name is generated by adding a random string to the end of pattern.
-// If pattern includes a "*", the random string replaces the last "*" instead.
-// If dir is the empty string, MkdirTemp uses the default directory for temporary files, as returned by TempDir.
-// Multiple programs or goroutines calling MkdirTemp simultaneously will not choose the same directory.
-// It is the caller's responsibility to remove the directory when it is no longer needed.
-func MkdirTemp(dir, pattern string) (string, error) {
- if dir == "" {
- dir = TempDir()
- }
-
- prefix, suffix, err := prefixAndSuffix(pattern)
- if err != nil {
- return "", &PathError{Op: "mkdirtemp", Path: pattern, Err: err}
- }
- prefix = joinPath(dir, prefix)
-
- try := 0
- for {
- name := prefix + nextRandom() + suffix
- err := Mkdir(name, 0700)
- if err == nil {
- return name, nil
- }
- if IsExist(err) {
- if try++; try < 10000 {
- continue
- }
- return "", &PathError{Op: "mkdirtemp", Path: dir + string(PathSeparator) + prefix + "*" + suffix, Err: ErrExist}
- }
- if IsNotExist(err) {
- if _, err := Stat(dir); IsNotExist(err) {
- return "", err
- }
- }
- return "", err
- }
-}
-
-func joinPath(dir, name string) string {
- if len(dir) > 0 && IsPathSeparator(dir[len(dir)-1]) {
- return dir + name
- }
- return dir + string(PathSeparator) + name
-}
-
-// LastIndexByte from the strings package.
-func lastIndex(s string, sep byte) int {
- for i := len(s) - 1; i >= 0; i-- {
- if s[i] == sep {
- return i
- }
- }
- return -1
-}
diff --git a/contrib/go/_std_1.20/src/os/types_windows.go b/contrib/go/_std_1.20/src/os/types_windows.go
deleted file mode 100644
index d444e8b48a..0000000000
--- a/contrib/go/_std_1.20/src/os/types_windows.go
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2009 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 os
-
-import (
- "internal/syscall/windows"
- "sync"
- "syscall"
- "time"
- "unsafe"
-)
-
-// A fileStat is the implementation of FileInfo returned by Stat and Lstat.
-type fileStat struct {
- name string
-
- // from ByHandleFileInformation, Win32FileAttributeData and Win32finddata
- FileAttributes uint32
- CreationTime syscall.Filetime
- LastAccessTime syscall.Filetime
- LastWriteTime syscall.Filetime
- FileSizeHigh uint32
- FileSizeLow uint32
-
- // from Win32finddata
- Reserved0 uint32
-
- // what syscall.GetFileType returns
- filetype uint32
-
- // used to implement SameFile
- sync.Mutex
- path string
- vol uint32
- idxhi uint32
- idxlo uint32
- appendNameToPath bool
-}
-
-// newFileStatFromGetFileInformationByHandle calls GetFileInformationByHandle
-// to gather all required information about the file handle h.
-func newFileStatFromGetFileInformationByHandle(path string, h syscall.Handle) (fs *fileStat, err error) {
- var d syscall.ByHandleFileInformation
- err = syscall.GetFileInformationByHandle(h, &d)
- if err != nil {
- return nil, &PathError{Op: "GetFileInformationByHandle", Path: path, Err: err}
- }
-
- var ti windows.FILE_ATTRIBUTE_TAG_INFO
- err = windows.GetFileInformationByHandleEx(h, windows.FileAttributeTagInfo, (*byte)(unsafe.Pointer(&ti)), uint32(unsafe.Sizeof(ti)))
- if err != nil {
- if errno, ok := err.(syscall.Errno); ok && errno == windows.ERROR_INVALID_PARAMETER {
- // It appears calling GetFileInformationByHandleEx with
- // FILE_ATTRIBUTE_TAG_INFO fails on FAT file system with
- // ERROR_INVALID_PARAMETER. Clear ti.ReparseTag in that
- // instance to indicate no symlinks are possible.
- ti.ReparseTag = 0
- } else {
- return nil, &PathError{Op: "GetFileInformationByHandleEx", Path: path, Err: err}
- }
- }
-
- return &fileStat{
- name: basename(path),
- FileAttributes: d.FileAttributes,
- CreationTime: d.CreationTime,
- LastAccessTime: d.LastAccessTime,
- LastWriteTime: d.LastWriteTime,
- FileSizeHigh: d.FileSizeHigh,
- FileSizeLow: d.FileSizeLow,
- vol: d.VolumeSerialNumber,
- idxhi: d.FileIndexHigh,
- idxlo: d.FileIndexLow,
- Reserved0: ti.ReparseTag,
- // fileStat.path is used by os.SameFile to decide if it needs
- // to fetch vol, idxhi and idxlo. But these are already set,
- // so set fileStat.path to "" to prevent os.SameFile doing it again.
- }, nil
-}
-
-// newFileStatFromWin32finddata copies all required information
-// from syscall.Win32finddata d into the newly created fileStat.
-func newFileStatFromWin32finddata(d *syscall.Win32finddata) *fileStat {
- return &fileStat{
- FileAttributes: d.FileAttributes,
- CreationTime: d.CreationTime,
- LastAccessTime: d.LastAccessTime,
- LastWriteTime: d.LastWriteTime,
- FileSizeHigh: d.FileSizeHigh,
- FileSizeLow: d.FileSizeLow,
- Reserved0: d.Reserved0,
- }
-}
-
-func (fs *fileStat) isSymlink() bool {
- // Use instructions described at
- // https://blogs.msdn.microsoft.com/oldnewthing/20100212-00/?p=14963/
- // to recognize whether it's a symlink.
- if fs.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
- return false
- }
- return fs.Reserved0 == syscall.IO_REPARSE_TAG_SYMLINK ||
- fs.Reserved0 == windows.IO_REPARSE_TAG_MOUNT_POINT
-}
-
-func (fs *fileStat) Size() int64 {
- return int64(fs.FileSizeHigh)<<32 + int64(fs.FileSizeLow)
-}
-
-func (fs *fileStat) Mode() (m FileMode) {
- if fs.FileAttributes&syscall.FILE_ATTRIBUTE_READONLY != 0 {
- m |= 0444
- } else {
- m |= 0666
- }
- if fs.isSymlink() {
- return m | ModeSymlink
- }
- if fs.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
- m |= ModeDir | 0111
- }
- switch fs.filetype {
- case syscall.FILE_TYPE_PIPE:
- m |= ModeNamedPipe
- case syscall.FILE_TYPE_CHAR:
- m |= ModeDevice | ModeCharDevice
- }
- return m
-}
-
-func (fs *fileStat) ModTime() time.Time {
- return time.Unix(0, fs.LastWriteTime.Nanoseconds())
-}
-
-// Sys returns syscall.Win32FileAttributeData for file fs.
-func (fs *fileStat) Sys() any {
- return &syscall.Win32FileAttributeData{
- FileAttributes: fs.FileAttributes,
- CreationTime: fs.CreationTime,
- LastAccessTime: fs.LastAccessTime,
- LastWriteTime: fs.LastWriteTime,
- FileSizeHigh: fs.FileSizeHigh,
- FileSizeLow: fs.FileSizeLow,
- }
-}
-
-func (fs *fileStat) loadFileId() error {
- fs.Lock()
- defer fs.Unlock()
- if fs.path == "" {
- // already done
- return nil
- }
- var path string
- if fs.appendNameToPath {
- path = fs.path + `\` + fs.name
- } else {
- path = fs.path
- }
- pathp, err := syscall.UTF16PtrFromString(path)
- if err != nil {
- return err
- }
- attrs := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS)
- if fs.isSymlink() {
- // Use FILE_FLAG_OPEN_REPARSE_POINT, otherwise CreateFile will follow symlink.
- // See https://docs.microsoft.com/en-us/windows/desktop/FileIO/symbolic-link-effects-on-file-systems-functions#createfile-and-createfiletransacted
- attrs |= syscall.FILE_FLAG_OPEN_REPARSE_POINT
- }
- h, err := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, attrs, 0)
- if err != nil {
- return err
- }
- defer syscall.CloseHandle(h)
- var i syscall.ByHandleFileInformation
- err = syscall.GetFileInformationByHandle(h, &i)
- if err != nil {
- return err
- }
- fs.path = ""
- fs.vol = i.VolumeSerialNumber
- fs.idxhi = i.FileIndexHigh
- fs.idxlo = i.FileIndexLow
- return nil
-}
-
-// saveInfoFromPath saves full path of the file to be used by os.SameFile later,
-// and set name from path.
-func (fs *fileStat) saveInfoFromPath(path string) error {
- fs.path = path
- if !isAbs(fs.path) {
- var err error
- fs.path, err = syscall.FullPath(fs.path)
- if err != nil {
- return &PathError{Op: "FullPath", Path: path, Err: err}
- }
- }
- fs.name = basename(path)
- return nil
-}
-
-func sameFile(fs1, fs2 *fileStat) bool {
- e := fs1.loadFileId()
- if e != nil {
- return false
- }
- e = fs2.loadFileId()
- if e != nil {
- return false
- }
- return fs1.vol == fs2.vol && fs1.idxhi == fs2.idxhi && fs1.idxlo == fs2.idxlo
-}
-
-// For testing.
-func atime(fi FileInfo) time.Time {
- return time.Unix(0, fi.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
-}
diff --git a/contrib/go/_std_1.20/src/os/wait_unimp.go b/contrib/go/_std_1.20/src/os/wait_unimp.go
deleted file mode 100644
index bc93e44cf9..0000000000
--- a/contrib/go/_std_1.20/src/os/wait_unimp.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2016 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.
-
-// aix, darwin, js/wasm, openbsd and solaris don't implement
-// waitid/wait6. netbsd implements wait6, but that is causing test
-// failures, see issue #48789.
-
-//go:build aix || darwin || (js && wasm) || openbsd || solaris
-
-package os
-
-// blockUntilWaitable attempts to block until a call to p.Wait will
-// succeed immediately, and reports whether it has done so.
-// It does not actually call p.Wait.
-// This version is used on systems that do not implement waitid,
-// or where we have not implemented it yet. Note that this is racy:
-// a call to Process.Signal can in an extremely unlikely case send a
-// signal to the wrong process, see issue #13987.
-func (p *Process) blockUntilWaitable() (bool, error) {
- return false, nil
-}
diff --git a/contrib/go/_std_1.20/src/os/ya.make b/contrib/go/_std_1.20/src/os/ya.make
deleted file mode 100644
index c5da16fcef..0000000000
--- a/contrib/go/_std_1.20/src/os/ya.make
+++ /dev/null
@@ -1,93 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- dir.go
- endian_little.go
- env.go
- error.go
- error_errno.go
- error_posix.go
- exec.go
- exec_posix.go
- executable.go
- file.go
- file_posix.go
- getwd.go
- path.go
- proc.go
- rawconn.go
- stat.go
- str.go
- sys.go
- tempfile.go
- types.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- dir_darwin.go
- exec_unix.go
- executable_darwin.go
- file_unix.go
- path_unix.go
- pipe_unix.go
- readfrom_stub.go
- removeall_at.go
- rlimit.go
- rlimit_darwin.go
- stat_darwin.go
- stat_unix.go
- sticky_bsd.go
- sys_bsd.go
- sys_unix.go
- types_unix.go
- wait_unimp.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- dir_unix.go
- dirent_linux.go
- exec_unix.go
- executable_procfs.go
- file_unix.go
- path_unix.go
- pipe2_unix.go
- readfrom_linux.go
- removeall_at.go
- rlimit.go
- rlimit_stub.go
- stat_linux.go
- stat_unix.go
- sticky_notbsd.go
- sys_linux.go
- sys_unix.go
- types_unix.go
- wait_waitid.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- dir_windows.go
- exec_windows.go
- executable_windows.go
- file_windows.go
- path_windows.go
- readfrom_stub.go
- removeall_noat.go
- stat_windows.go
- sticky_notbsd.go
- sys_windows.go
- types_windows.go
- )
-ENDIF()
-
-END()
-
-RECURSE(
- exec
- signal
- user
-)
diff --git a/contrib/go/_std_1.20/src/path/filepath/path.go b/contrib/go/_std_1.20/src/path/filepath/path.go
deleted file mode 100644
index 32dd887998..0000000000
--- a/contrib/go/_std_1.20/src/path/filepath/path.go
+++ /dev/null
@@ -1,666 +0,0 @@
-// Copyright 2009 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 filepath implements utility routines for manipulating filename paths
-// in a way compatible with the target operating system-defined file paths.
-//
-// The filepath package uses either forward slashes or backslashes,
-// depending on the operating system. To process paths such as URLs
-// that always use forward slashes regardless of the operating
-// system, see the path package.
-package filepath
-
-import (
- "errors"
- "io/fs"
- "os"
- "runtime"
- "sort"
- "strings"
-)
-
-// A lazybuf is a lazily constructed path buffer.
-// It supports append, reading previously appended bytes,
-// and retrieving the final string. It does not allocate a buffer
-// to hold the output until that output diverges from s.
-type lazybuf struct {
- path string
- buf []byte
- w int
- volAndPath string
- volLen int
-}
-
-func (b *lazybuf) index(i int) byte {
- if b.buf != nil {
- return b.buf[i]
- }
- return b.path[i]
-}
-
-func (b *lazybuf) append(c byte) {
- if b.buf == nil {
- if b.w < len(b.path) && b.path[b.w] == c {
- b.w++
- return
- }
- b.buf = make([]byte, len(b.path))
- copy(b.buf, b.path[:b.w])
- }
- b.buf[b.w] = c
- b.w++
-}
-
-func (b *lazybuf) string() string {
- if b.buf == nil {
- return b.volAndPath[:b.volLen+b.w]
- }
- return b.volAndPath[:b.volLen] + string(b.buf[:b.w])
-}
-
-const (
- Separator = os.PathSeparator
- ListSeparator = os.PathListSeparator
-)
-
-// Clean returns the shortest path name equivalent to path
-// by purely lexical processing. It applies the following rules
-// iteratively until no further processing can be done:
-//
-// 1. Replace multiple Separator elements with a single one.
-// 2. Eliminate each . path name element (the current directory).
-// 3. Eliminate each inner .. path name element (the parent directory)
-// along with the non-.. element that precedes it.
-// 4. Eliminate .. elements that begin a rooted path:
-// that is, replace "/.." by "/" at the beginning of a path,
-// assuming Separator is '/'.
-//
-// The returned path ends in a slash only if it represents a root directory,
-// such as "/" on Unix or `C:\` on Windows.
-//
-// Finally, any occurrences of slash are replaced by Separator.
-//
-// If the result of this process is an empty string, Clean
-// returns the string ".".
-//
-// See also Rob Pike, “Lexical File Names in Plan 9 or
-// Getting Dot-Dot Right,”
-// https://9p.io/sys/doc/lexnames.html
-func Clean(path string) string {
- originalPath := path
- volLen := volumeNameLen(path)
- path = path[volLen:]
- if path == "" {
- if volLen > 1 && os.IsPathSeparator(originalPath[0]) && os.IsPathSeparator(originalPath[1]) {
- // should be UNC
- return FromSlash(originalPath)
- }
- return originalPath + "."
- }
- rooted := os.IsPathSeparator(path[0])
-
- // Invariants:
- // reading from path; r is index of next byte to process.
- // writing to buf; w is index of next byte to write.
- // dotdot is index in buf where .. must stop, either because
- // it is the leading slash or it is a leading ../../.. prefix.
- n := len(path)
- out := lazybuf{path: path, volAndPath: originalPath, volLen: volLen}
- r, dotdot := 0, 0
- if rooted {
- out.append(Separator)
- r, dotdot = 1, 1
- }
-
- for r < n {
- switch {
- case os.IsPathSeparator(path[r]):
- // empty path element
- r++
- case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])):
- // . element
- r++
- case path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])):
- // .. element: remove to last separator
- r += 2
- switch {
- case out.w > dotdot:
- // can backtrack
- out.w--
- for out.w > dotdot && !os.IsPathSeparator(out.index(out.w)) {
- out.w--
- }
- case !rooted:
- // cannot backtrack, but not rooted, so append .. element.
- if out.w > 0 {
- out.append(Separator)
- }
- out.append('.')
- out.append('.')
- dotdot = out.w
- }
- default:
- // real path element.
- // add slash if needed
- if rooted && out.w != 1 || !rooted && out.w != 0 {
- out.append(Separator)
- }
- // If a ':' appears in the path element at the start of a Windows path,
- // insert a .\ at the beginning to avoid converting relative paths
- // like a/../c: into c:.
- if runtime.GOOS == "windows" && out.w == 0 && out.volLen == 0 && r != 0 {
- for i := r; i < n && !os.IsPathSeparator(path[i]); i++ {
- if path[i] == ':' {
- out.append('.')
- out.append(Separator)
- break
- }
- }
- }
- // copy element
- for ; r < n && !os.IsPathSeparator(path[r]); r++ {
- out.append(path[r])
- }
- }
- }
-
- // Turn empty string into "."
- if out.w == 0 {
- out.append('.')
- }
-
- return FromSlash(out.string())
-}
-
-// IsLocal reports whether path, using lexical analysis only, has all of these properties:
-//
-// - is within the subtree rooted at the directory in which path is evaluated
-// - is not an absolute path
-// - is not empty
-// - on Windows, is not a reserved name such as "NUL"
-//
-// If IsLocal(path) returns true, then
-// Join(base, path) will always produce a path contained within base and
-// Clean(path) will always produce an unrooted path with no ".." path elements.
-//
-// IsLocal is a purely lexical operation.
-// In particular, it does not account for the effect of any symbolic links
-// that may exist in the filesystem.
-func IsLocal(path string) bool {
- return isLocal(path)
-}
-
-func unixIsLocal(path string) bool {
- if IsAbs(path) || path == "" {
- return false
- }
- hasDots := false
- for p := path; p != ""; {
- var part string
- part, p, _ = strings.Cut(p, "/")
- if part == "." || part == ".." {
- hasDots = true
- break
- }
- }
- if hasDots {
- path = Clean(path)
- }
- if path == ".." || strings.HasPrefix(path, "../") {
- return false
- }
- return true
-}
-
-// ToSlash returns the result of replacing each separator character
-// in path with a slash ('/') character. Multiple separators are
-// replaced by multiple slashes.
-func ToSlash(path string) string {
- if Separator == '/' {
- return path
- }
- return strings.ReplaceAll(path, string(Separator), "/")
-}
-
-// FromSlash returns the result of replacing each slash ('/') character
-// in path with a separator character. Multiple slashes are replaced
-// by multiple separators.
-func FromSlash(path string) string {
- if Separator == '/' {
- return path
- }
- return strings.ReplaceAll(path, "/", string(Separator))
-}
-
-// SplitList splits a list of paths joined by the OS-specific ListSeparator,
-// usually found in PATH or GOPATH environment variables.
-// Unlike strings.Split, SplitList returns an empty slice when passed an empty
-// string.
-func SplitList(path string) []string {
- return splitList(path)
-}
-
-// Split splits path immediately following the final Separator,
-// separating it into a directory and file name component.
-// If there is no Separator in path, Split returns an empty dir
-// and file set to path.
-// The returned values have the property that path = dir+file.
-func Split(path string) (dir, file string) {
- vol := VolumeName(path)
- i := len(path) - 1
- for i >= len(vol) && !os.IsPathSeparator(path[i]) {
- i--
- }
- return path[:i+1], path[i+1:]
-}
-
-// Join joins any number of path elements into a single path,
-// separating them with an OS specific Separator. Empty elements
-// are ignored. The result is Cleaned. However, if the argument
-// list is empty or all its elements are empty, Join returns
-// an empty string.
-// On Windows, the result will only be a UNC path if the first
-// non-empty element is a UNC path.
-func Join(elem ...string) string {
- return join(elem)
-}
-
-// Ext returns the file name extension used by path.
-// The extension is the suffix beginning at the final dot
-// in the final element of path; it is empty if there is
-// no dot.
-func Ext(path string) string {
- for i := len(path) - 1; i >= 0 && !os.IsPathSeparator(path[i]); i-- {
- if path[i] == '.' {
- return path[i:]
- }
- }
- return ""
-}
-
-// EvalSymlinks returns the path name after the evaluation of any symbolic
-// links.
-// If path is relative the result will be relative to the current directory,
-// unless one of the components is an absolute symbolic link.
-// EvalSymlinks calls Clean on the result.
-func EvalSymlinks(path string) (string, error) {
- return evalSymlinks(path)
-}
-
-// Abs returns an absolute representation of path.
-// If the path is not absolute it will be joined with the current
-// working directory to turn it into an absolute path. The absolute
-// path name for a given file is not guaranteed to be unique.
-// Abs calls Clean on the result.
-func Abs(path string) (string, error) {
- return abs(path)
-}
-
-func unixAbs(path string) (string, error) {
- if IsAbs(path) {
- return Clean(path), nil
- }
- wd, err := os.Getwd()
- if err != nil {
- return "", err
- }
- return Join(wd, path), nil
-}
-
-// Rel returns a relative path that is lexically equivalent to targpath when
-// joined to basepath with an intervening separator. That is,
-// Join(basepath, Rel(basepath, targpath)) is equivalent to targpath itself.
-// On success, the returned path will always be relative to basepath,
-// even if basepath and targpath share no elements.
-// An error is returned if targpath can't be made relative to basepath or if
-// knowing the current working directory would be necessary to compute it.
-// Rel calls Clean on the result.
-func Rel(basepath, targpath string) (string, error) {
- baseVol := VolumeName(basepath)
- targVol := VolumeName(targpath)
- base := Clean(basepath)
- targ := Clean(targpath)
- if sameWord(targ, base) {
- return ".", nil
- }
- base = base[len(baseVol):]
- targ = targ[len(targVol):]
- if base == "." {
- base = ""
- } else if base == "" && volumeNameLen(baseVol) > 2 /* isUNC */ {
- // Treat any targetpath matching `\\host\share` basepath as absolute path.
- base = string(Separator)
- }
-
- // Can't use IsAbs - `\a` and `a` are both relative in Windows.
- baseSlashed := len(base) > 0 && base[0] == Separator
- targSlashed := len(targ) > 0 && targ[0] == Separator
- if baseSlashed != targSlashed || !sameWord(baseVol, targVol) {
- return "", errors.New("Rel: can't make " + targpath + " relative to " + basepath)
- }
- // Position base[b0:bi] and targ[t0:ti] at the first differing elements.
- bl := len(base)
- tl := len(targ)
- var b0, bi, t0, ti int
- for {
- for bi < bl && base[bi] != Separator {
- bi++
- }
- for ti < tl && targ[ti] != Separator {
- ti++
- }
- if !sameWord(targ[t0:ti], base[b0:bi]) {
- break
- }
- if bi < bl {
- bi++
- }
- if ti < tl {
- ti++
- }
- b0 = bi
- t0 = ti
- }
- if base[b0:bi] == ".." {
- return "", errors.New("Rel: can't make " + targpath + " relative to " + basepath)
- }
- if b0 != bl {
- // Base elements left. Must go up before going down.
- seps := strings.Count(base[b0:bl], string(Separator))
- size := 2 + seps*3
- if tl != t0 {
- size += 1 + tl - t0
- }
- buf := make([]byte, size)
- n := copy(buf, "..")
- for i := 0; i < seps; i++ {
- buf[n] = Separator
- copy(buf[n+1:], "..")
- n += 3
- }
- if t0 != tl {
- buf[n] = Separator
- copy(buf[n+1:], targ[t0:])
- }
- return string(buf), nil
- }
- return targ[t0:], nil
-}
-
-// SkipDir is used as a return value from WalkFuncs to indicate that
-// the directory named in the call is to be skipped. It is not returned
-// as an error by any function.
-var SkipDir error = fs.SkipDir
-
-// SkipAll is used as a return value from WalkFuncs to indicate that
-// all remaining files and directories are to be skipped. It is not returned
-// as an error by any function.
-var SkipAll error = fs.SkipAll
-
-// WalkFunc is the type of the function called by Walk to visit each
-// file or directory.
-//
-// The path argument contains the argument to Walk as a prefix.
-// That is, if Walk is called with root argument "dir" and finds a file
-// named "a" in that directory, the walk function will be called with
-// argument "dir/a".
-//
-// The directory and file are joined with Join, which may clean the
-// directory name: if Walk is called with the root argument "x/../dir"
-// and finds a file named "a" in that directory, the walk function will
-// be called with argument "dir/a", not "x/../dir/a".
-//
-// The info argument is the fs.FileInfo for the named path.
-//
-// The error result returned by the function controls how Walk continues.
-// If the function returns the special value SkipDir, Walk skips the
-// current directory (path if info.IsDir() is true, otherwise path's
-// parent directory). If the function returns the special value SkipAll,
-// Walk skips all remaining files and directories. Otherwise, if the function
-// returns a non-nil error, Walk stops entirely and returns that error.
-//
-// The err argument reports an error related to path, signaling that Walk
-// will not walk into that directory. The function can decide how to
-// handle that error; as described earlier, returning the error will
-// cause Walk to stop walking the entire tree.
-//
-// Walk calls the function with a non-nil err argument in two cases.
-//
-// First, if an os.Lstat on the root directory or any directory or file
-// in the tree fails, Walk calls the function with path set to that
-// directory or file's path, info set to nil, and err set to the error
-// from os.Lstat.
-//
-// Second, if a directory's Readdirnames method fails, Walk calls the
-// function with path set to the directory's path, info, set to an
-// fs.FileInfo describing the directory, and err set to the error from
-// Readdirnames.
-type WalkFunc func(path string, info fs.FileInfo, err error) error
-
-var lstat = os.Lstat // for testing
-
-// walkDir recursively descends path, calling walkDirFn.
-func walkDir(path string, d fs.DirEntry, walkDirFn fs.WalkDirFunc) error {
- if err := walkDirFn(path, d, nil); err != nil || !d.IsDir() {
- if err == SkipDir && d.IsDir() {
- // Successfully skipped directory.
- err = nil
- }
- return err
- }
-
- dirs, err := readDir(path)
- if err != nil {
- // Second call, to report ReadDir error.
- err = walkDirFn(path, d, err)
- if err != nil {
- if err == SkipDir && d.IsDir() {
- err = nil
- }
- return err
- }
- }
-
- for _, d1 := range dirs {
- path1 := Join(path, d1.Name())
- if err := walkDir(path1, d1, walkDirFn); err != nil {
- if err == SkipDir {
- break
- }
- return err
- }
- }
- return nil
-}
-
-// walk recursively descends path, calling walkFn.
-func walk(path string, info fs.FileInfo, walkFn WalkFunc) error {
- if !info.IsDir() {
- return walkFn(path, info, nil)
- }
-
- names, err := readDirNames(path)
- err1 := walkFn(path, info, err)
- // If err != nil, walk can't walk into this directory.
- // err1 != nil means walkFn want walk to skip this directory or stop walking.
- // Therefore, if one of err and err1 isn't nil, walk will return.
- if err != nil || err1 != nil {
- // The caller's behavior is controlled by the return value, which is decided
- // by walkFn. walkFn may ignore err and return nil.
- // If walkFn returns SkipDir or SkipAll, it will be handled by the caller.
- // So walk should return whatever walkFn returns.
- return err1
- }
-
- for _, name := range names {
- filename := Join(path, name)
- fileInfo, err := lstat(filename)
- if err != nil {
- if err := walkFn(filename, fileInfo, err); err != nil && err != SkipDir {
- return err
- }
- } else {
- err = walk(filename, fileInfo, walkFn)
- if err != nil {
- if !fileInfo.IsDir() || err != SkipDir {
- return err
- }
- }
- }
- }
- return nil
-}
-
-// WalkDir walks the file tree rooted at root, calling fn for each file or
-// directory in the tree, including root.
-//
-// All errors that arise visiting files and directories are filtered by fn:
-// see the fs.WalkDirFunc documentation for details.
-//
-// The files are walked in lexical order, which makes the output deterministic
-// but requires WalkDir to read an entire directory into memory before proceeding
-// to walk that directory.
-//
-// WalkDir does not follow symbolic links.
-//
-// WalkDir calls fn with paths that use the separator character appropriate
-// for the operating system. This is unlike [io/fs.WalkDir], which always
-// uses slash separated paths.
-func WalkDir(root string, fn fs.WalkDirFunc) error {
- info, err := os.Lstat(root)
- if err != nil {
- err = fn(root, nil, err)
- } else {
- err = walkDir(root, &statDirEntry{info}, fn)
- }
- if err == SkipDir || err == SkipAll {
- return nil
- }
- return err
-}
-
-type statDirEntry struct {
- info fs.FileInfo
-}
-
-func (d *statDirEntry) Name() string { return d.info.Name() }
-func (d *statDirEntry) IsDir() bool { return d.info.IsDir() }
-func (d *statDirEntry) Type() fs.FileMode { return d.info.Mode().Type() }
-func (d *statDirEntry) Info() (fs.FileInfo, error) { return d.info, nil }
-
-// Walk walks the file tree rooted at root, calling fn for each file or
-// directory in the tree, including root.
-//
-// All errors that arise visiting files and directories are filtered by fn:
-// see the WalkFunc documentation for details.
-//
-// The files are walked in lexical order, which makes the output deterministic
-// but requires Walk to read an entire directory into memory before proceeding
-// to walk that directory.
-//
-// Walk does not follow symbolic links.
-//
-// Walk is less efficient than WalkDir, introduced in Go 1.16,
-// which avoids calling os.Lstat on every visited file or directory.
-func Walk(root string, fn WalkFunc) error {
- info, err := os.Lstat(root)
- if err != nil {
- err = fn(root, nil, err)
- } else {
- err = walk(root, info, fn)
- }
- if err == SkipDir || err == SkipAll {
- return nil
- }
- return err
-}
-
-// readDir reads the directory named by dirname and returns
-// a sorted list of directory entries.
-func readDir(dirname string) ([]fs.DirEntry, error) {
- f, err := os.Open(dirname)
- if err != nil {
- return nil, err
- }
- dirs, err := f.ReadDir(-1)
- f.Close()
- if err != nil {
- return nil, err
- }
- sort.Slice(dirs, func(i, j int) bool { return dirs[i].Name() < dirs[j].Name() })
- return dirs, nil
-}
-
-// readDirNames reads the directory named by dirname and returns
-// a sorted list of directory entry names.
-func readDirNames(dirname string) ([]string, error) {
- f, err := os.Open(dirname)
- if err != nil {
- return nil, err
- }
- names, err := f.Readdirnames(-1)
- f.Close()
- if err != nil {
- return nil, err
- }
- sort.Strings(names)
- return names, nil
-}
-
-// Base returns the last element of path.
-// Trailing path separators are removed before extracting the last element.
-// If the path is empty, Base returns ".".
-// If the path consists entirely of separators, Base returns a single separator.
-func Base(path string) string {
- if path == "" {
- return "."
- }
- // Strip trailing slashes.
- for len(path) > 0 && os.IsPathSeparator(path[len(path)-1]) {
- path = path[0 : len(path)-1]
- }
- // Throw away volume name
- path = path[len(VolumeName(path)):]
- // Find the last element
- i := len(path) - 1
- for i >= 0 && !os.IsPathSeparator(path[i]) {
- i--
- }
- if i >= 0 {
- path = path[i+1:]
- }
- // If empty now, it had only slashes.
- if path == "" {
- return string(Separator)
- }
- return path
-}
-
-// Dir returns all but the last element of path, typically the path's directory.
-// After dropping the final element, Dir calls Clean on the path and trailing
-// slashes are removed.
-// If the path is empty, Dir returns ".".
-// If the path consists entirely of separators, Dir returns a single separator.
-// The returned path does not end in a separator unless it is the root directory.
-func Dir(path string) string {
- vol := VolumeName(path)
- i := len(path) - 1
- for i >= len(vol) && !os.IsPathSeparator(path[i]) {
- i--
- }
- dir := Clean(path[len(vol) : i+1])
- if dir == "." && len(vol) > 2 {
- // must be UNC
- return vol
- }
- return vol + dir
-}
-
-// VolumeName returns leading volume name.
-// Given "C:\foo\bar" it returns "C:" on Windows.
-// Given "\\host\share\foo" it returns "\\host\share".
-// On other platforms it returns "".
-func VolumeName(path string) string {
- return FromSlash(path[:volumeNameLen(path)])
-}
diff --git a/contrib/go/_std_1.20/src/path/filepath/path_unix.go b/contrib/go/_std_1.20/src/path/filepath/path_unix.go
deleted file mode 100644
index ab1d08d356..0000000000
--- a/contrib/go/_std_1.20/src/path/filepath/path_unix.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2010 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.
-
-//go:build unix || (js && wasm)
-
-package filepath
-
-import "strings"
-
-func isLocal(path string) bool {
- return unixIsLocal(path)
-}
-
-// IsAbs reports whether the path is absolute.
-func IsAbs(path string) bool {
- return strings.HasPrefix(path, "/")
-}
-
-// volumeNameLen returns length of the leading volume name on Windows.
-// It returns 0 elsewhere.
-func volumeNameLen(path string) int {
- return 0
-}
-
-// HasPrefix exists for historical compatibility and should not be used.
-//
-// Deprecated: HasPrefix does not respect path boundaries and
-// does not ignore case when required.
-func HasPrefix(p, prefix string) bool {
- return strings.HasPrefix(p, prefix)
-}
-
-func splitList(path string) []string {
- if path == "" {
- return []string{}
- }
- return strings.Split(path, string(ListSeparator))
-}
-
-func abs(path string) (string, error) {
- return unixAbs(path)
-}
-
-func join(elem []string) string {
- // If there's a bug here, fix the logic in ./path_plan9.go too.
- for i, e := range elem {
- if e != "" {
- return Clean(strings.Join(elem[i:], string(Separator)))
- }
- }
- return ""
-}
-
-func sameWord(a, b string) bool {
- return a == b
-}
diff --git a/contrib/go/_std_1.20/src/path/filepath/symlink.go b/contrib/go/_std_1.20/src/path/filepath/symlink.go
deleted file mode 100644
index 6fefd15977..0000000000
--- a/contrib/go/_std_1.20/src/path/filepath/symlink.go
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2012 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 filepath
-
-import (
- "errors"
- "io/fs"
- "os"
- "runtime"
- "syscall"
-)
-
-func walkSymlinks(path string) (string, error) {
- volLen := volumeNameLen(path)
- pathSeparator := string(os.PathSeparator)
-
- if volLen < len(path) && os.IsPathSeparator(path[volLen]) {
- volLen++
- }
- vol := path[:volLen]
- dest := vol
- linksWalked := 0
- for start, end := volLen, volLen; start < len(path); start = end {
- for start < len(path) && os.IsPathSeparator(path[start]) {
- start++
- }
- end = start
- for end < len(path) && !os.IsPathSeparator(path[end]) {
- end++
- }
-
- // On Windows, "." can be a symlink.
- // We look it up, and use the value if it is absolute.
- // If not, we just return ".".
- isWindowsDot := runtime.GOOS == "windows" && path[volumeNameLen(path):] == "."
-
- // The next path component is in path[start:end].
- if end == start {
- // No more path components.
- break
- } else if path[start:end] == "." && !isWindowsDot {
- // Ignore path component ".".
- continue
- } else if path[start:end] == ".." {
- // Back up to previous component if possible.
- // Note that volLen includes any leading slash.
-
- // Set r to the index of the last slash in dest,
- // after the volume.
- var r int
- for r = len(dest) - 1; r >= volLen; r-- {
- if os.IsPathSeparator(dest[r]) {
- break
- }
- }
- if r < volLen || dest[r+1:] == ".." {
- // Either path has no slashes
- // (it's empty or just "C:")
- // or it ends in a ".." we had to keep.
- // Either way, keep this "..".
- if len(dest) > volLen {
- dest += pathSeparator
- }
- dest += ".."
- } else {
- // Discard everything since the last slash.
- dest = dest[:r]
- }
- continue
- }
-
- // Ordinary path component. Add it to result.
-
- if len(dest) > volumeNameLen(dest) && !os.IsPathSeparator(dest[len(dest)-1]) {
- dest += pathSeparator
- }
-
- dest += path[start:end]
-
- // Resolve symlink.
-
- fi, err := os.Lstat(dest)
- if err != nil {
- return "", err
- }
-
- if fi.Mode()&fs.ModeSymlink == 0 {
- if !fi.Mode().IsDir() && end < len(path) {
- return "", syscall.ENOTDIR
- }
- continue
- }
-
- // Found symlink.
-
- linksWalked++
- if linksWalked > 255 {
- return "", errors.New("EvalSymlinks: too many links")
- }
-
- link, err := os.Readlink(dest)
- if err != nil {
- return "", err
- }
-
- if isWindowsDot && !IsAbs(link) {
- // On Windows, if "." is a relative symlink,
- // just return ".".
- break
- }
-
- path = link + path[end:]
-
- v := volumeNameLen(link)
- if v > 0 {
- // Symlink to drive name is an absolute path.
- if v < len(link) && os.IsPathSeparator(link[v]) {
- v++
- }
- vol = link[:v]
- dest = vol
- end = len(vol)
- } else if len(link) > 0 && os.IsPathSeparator(link[0]) {
- // Symlink to absolute path.
- dest = link[:1]
- end = 1
- } else {
- // Symlink to relative path; replace last
- // path component in dest.
- var r int
- for r = len(dest) - 1; r >= volLen; r-- {
- if os.IsPathSeparator(dest[r]) {
- break
- }
- }
- if r < volLen {
- dest = vol
- } else {
- dest = dest[:r]
- }
- end = 0
- }
- }
- return Clean(dest), nil
-}
diff --git a/contrib/go/_std_1.20/src/path/filepath/symlink_windows.go b/contrib/go/_std_1.20/src/path/filepath/symlink_windows.go
deleted file mode 100644
index 9a436d5978..0000000000
--- a/contrib/go/_std_1.20/src/path/filepath/symlink_windows.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2012 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 filepath
-
-import (
- "strings"
- "syscall"
-)
-
-// normVolumeName is like VolumeName, but makes drive letter upper case.
-// result of EvalSymlinks must be unique, so we have
-// EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`).
-func normVolumeName(path string) string {
- volume := VolumeName(path)
-
- if len(volume) > 2 { // isUNC
- return volume
- }
-
- return strings.ToUpper(volume)
-}
-
-// normBase returns the last element of path with correct case.
-func normBase(path string) (string, error) {
- p, err := syscall.UTF16PtrFromString(path)
- if err != nil {
- return "", err
- }
-
- var data syscall.Win32finddata
-
- h, err := syscall.FindFirstFile(p, &data)
- if err != nil {
- return "", err
- }
- syscall.FindClose(h)
-
- return syscall.UTF16ToString(data.FileName[:]), nil
-}
-
-// baseIsDotDot reports whether the last element of path is "..".
-// The given path should be 'Clean'-ed in advance.
-func baseIsDotDot(path string) bool {
- i := strings.LastIndexByte(path, Separator)
- return path[i+1:] == ".."
-}
-
-// toNorm returns the normalized path that is guaranteed to be unique.
-// It should accept the following formats:
-// - UNC paths (e.g \\server\share\foo\bar)
-// - absolute paths (e.g C:\foo\bar)
-// - relative paths begin with drive letter (e.g C:foo\bar, C:..\foo\bar, C:.., C:.)
-// - relative paths begin with '\' (e.g \foo\bar)
-// - relative paths begin without '\' (e.g foo\bar, ..\foo\bar, .., .)
-//
-// The returned normalized path will be in the same form (of 5 listed above) as the input path.
-// If two paths A and B are indicating the same file with the same format, toNorm(A) should be equal to toNorm(B).
-// The normBase parameter should be equal to the normBase func, except for in tests. See docs on the normBase func.
-func toNorm(path string, normBase func(string) (string, error)) (string, error) {
- if path == "" {
- return path, nil
- }
-
- path = Clean(path)
-
- volume := normVolumeName(path)
- path = path[len(volume):]
-
- // skip special cases
- if path == "" || path == "." || path == `\` {
- return volume + path, nil
- }
-
- var normPath string
-
- for {
- if baseIsDotDot(path) {
- normPath = path + `\` + normPath
-
- break
- }
-
- name, err := normBase(volume + path)
- if err != nil {
- return "", err
- }
-
- normPath = name + `\` + normPath
-
- i := strings.LastIndexByte(path, Separator)
- if i == -1 {
- break
- }
- if i == 0 { // `\Go` or `C:\Go`
- normPath = `\` + normPath
-
- break
- }
-
- path = path[:i]
- }
-
- normPath = normPath[:len(normPath)-1] // remove trailing '\'
-
- return volume + normPath, nil
-}
-
-func evalSymlinks(path string) (string, error) {
- newpath, err := walkSymlinks(path)
- if err != nil {
- return "", err
- }
- newpath, err = toNorm(newpath, normBase)
- if err != nil {
- return "", err
- }
- return newpath, nil
-}
diff --git a/contrib/go/_std_1.20/src/path/filepath/ya.make b/contrib/go/_std_1.20/src/path/filepath/ya.make
deleted file mode 100644
index 328123131e..0000000000
--- a/contrib/go/_std_1.20/src/path/filepath/ya.make
+++ /dev/null
@@ -1,30 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- match.go
- path.go
- symlink.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- path_unix.go
- symlink_unix.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- path_unix.go
- symlink_unix.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- path_windows.go
- symlink_windows.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/path/ya.make b/contrib/go/_std_1.20/src/path/ya.make
deleted file mode 100644
index d4de534ccf..0000000000
--- a/contrib/go/_std_1.20/src/path/ya.make
+++ /dev/null
@@ -1,12 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- match.go
- path.go
-)
-
-END()
-
-RECURSE(
- filepath
-)
diff --git a/contrib/go/_std_1.20/src/reflect/abi.go b/contrib/go/_std_1.20/src/reflect/abi.go
deleted file mode 100644
index 32cb314188..0000000000
--- a/contrib/go/_std_1.20/src/reflect/abi.go
+++ /dev/null
@@ -1,510 +0,0 @@
-// 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 reflect
-
-import (
- "internal/abi"
- "internal/goarch"
- "unsafe"
-)
-
-// These variables are used by the register assignment
-// algorithm in this file.
-//
-// They should be modified with care (no other reflect code
-// may be executing) and are generally only modified
-// when testing this package.
-//
-// They should never be set higher than their internal/abi
-// constant counterparts, because the system relies on a
-// structure that is at least large enough to hold the
-// registers the system supports.
-//
-// Currently they're set to zero because using the actual
-// constants will break every part of the toolchain that
-// uses reflect to call functions (e.g. go test, or anything
-// that uses text/template). The values that are currently
-// commented out there should be the actual values once
-// we're ready to use the register ABI everywhere.
-var (
- intArgRegs = abi.IntArgRegs
- floatArgRegs = abi.FloatArgRegs
- floatRegSize = uintptr(abi.EffectiveFloatRegSize)
-)
-
-// abiStep represents an ABI "instruction." Each instruction
-// describes one part of how to translate between a Go value
-// in memory and a call frame.
-type abiStep struct {
- kind abiStepKind
-
- // offset and size together describe a part of a Go value
- // in memory.
- offset uintptr
- size uintptr // size in bytes of the part
-
- // These fields describe the ABI side of the translation.
- stkOff uintptr // stack offset, used if kind == abiStepStack
- ireg int // integer register index, used if kind == abiStepIntReg or kind == abiStepPointer
- freg int // FP register index, used if kind == abiStepFloatReg
-}
-
-// abiStepKind is the "op-code" for an abiStep instruction.
-type abiStepKind int
-
-const (
- abiStepBad abiStepKind = iota
- abiStepStack // copy to/from stack
- abiStepIntReg // copy to/from integer register
- abiStepPointer // copy pointer to/from integer register
- abiStepFloatReg // copy to/from FP register
-)
-
-// abiSeq represents a sequence of ABI instructions for copying
-// from a series of reflect.Values to a call frame (for call arguments)
-// or vice-versa (for call results).
-//
-// An abiSeq should be populated by calling its addArg method.
-type abiSeq struct {
- // steps is the set of instructions.
- //
- // The instructions are grouped together by whole arguments,
- // with the starting index for the instructions
- // of the i'th Go value available in valueStart.
- //
- // For instance, if this abiSeq represents 3 arguments
- // passed to a function, then the 2nd argument's steps
- // begin at steps[valueStart[1]].
- //
- // Because reflect accepts Go arguments in distinct
- // Values and each Value is stored separately, each abiStep
- // that begins a new argument will have its offset
- // field == 0.
- steps []abiStep
- valueStart []int
-
- stackBytes uintptr // stack space used
- iregs, fregs int // registers used
-}
-
-func (a *abiSeq) dump() {
- for i, p := range a.steps {
- println("part", i, p.kind, p.offset, p.size, p.stkOff, p.ireg, p.freg)
- }
- print("values ")
- for _, i := range a.valueStart {
- print(i, " ")
- }
- println()
- println("stack", a.stackBytes)
- println("iregs", a.iregs)
- println("fregs", a.fregs)
-}
-
-// stepsForValue returns the ABI instructions for translating
-// the i'th Go argument or return value represented by this
-// abiSeq to the Go ABI.
-func (a *abiSeq) stepsForValue(i int) []abiStep {
- s := a.valueStart[i]
- var e int
- if i == len(a.valueStart)-1 {
- e = len(a.steps)
- } else {
- e = a.valueStart[i+1]
- }
- return a.steps[s:e]
-}
-
-// addArg extends the abiSeq with a new Go value of type t.
-//
-// If the value was stack-assigned, returns the single
-// abiStep describing that translation, and nil otherwise.
-func (a *abiSeq) addArg(t *rtype) *abiStep {
- // We'll always be adding a new value, so do that first.
- pStart := len(a.steps)
- a.valueStart = append(a.valueStart, pStart)
- if t.size == 0 {
- // If the size of the argument type is zero, then
- // in order to degrade gracefully into ABI0, we need
- // to stack-assign this type. The reason is that
- // although zero-sized types take up no space on the
- // stack, they do cause the next argument to be aligned.
- // So just do that here, but don't bother actually
- // generating a new ABI step for it (there's nothing to
- // actually copy).
- //
- // We cannot handle this in the recursive case of
- // regAssign because zero-sized *fields* of a
- // non-zero-sized struct do not cause it to be
- // stack-assigned. So we need a special case here
- // at the top.
- a.stackBytes = align(a.stackBytes, uintptr(t.align))
- return nil
- }
- // Hold a copy of "a" so that we can roll back if
- // register assignment fails.
- aOld := *a
- if !a.regAssign(t, 0) {
- // Register assignment failed. Roll back any changes
- // and stack-assign.
- *a = aOld
- a.stackAssign(t.size, uintptr(t.align))
- return &a.steps[len(a.steps)-1]
- }
- return nil
-}
-
-// addRcvr extends the abiSeq with a new method call
-// receiver according to the interface calling convention.
-//
-// If the receiver was stack-assigned, returns the single
-// abiStep describing that translation, and nil otherwise.
-// Returns true if the receiver is a pointer.
-func (a *abiSeq) addRcvr(rcvr *rtype) (*abiStep, bool) {
- // The receiver is always one word.
- a.valueStart = append(a.valueStart, len(a.steps))
- var ok, ptr bool
- if ifaceIndir(rcvr) || rcvr.pointers() {
- ok = a.assignIntN(0, goarch.PtrSize, 1, 0b1)
- ptr = true
- } else {
- // TODO(mknyszek): Is this case even possible?
- // The interface data work never contains a non-pointer
- // value. This case was copied over from older code
- // in the reflect package which only conditionally added
- // a pointer bit to the reflect.(Value).Call stack frame's
- // GC bitmap.
- ok = a.assignIntN(0, goarch.PtrSize, 1, 0b0)
- ptr = false
- }
- if !ok {
- a.stackAssign(goarch.PtrSize, goarch.PtrSize)
- return &a.steps[len(a.steps)-1], ptr
- }
- return nil, ptr
-}
-
-// regAssign attempts to reserve argument registers for a value of
-// type t, stored at some offset.
-//
-// It returns whether or not the assignment succeeded, but
-// leaves any changes it made to a.steps behind, so the caller
-// must undo that work by adjusting a.steps if it fails.
-//
-// This method along with the assign* methods represent the
-// complete register-assignment algorithm for the Go ABI.
-func (a *abiSeq) regAssign(t *rtype, offset uintptr) bool {
- switch t.Kind() {
- case UnsafePointer, Pointer, Chan, Map, Func:
- return a.assignIntN(offset, t.size, 1, 0b1)
- case Bool, Int, Uint, Int8, Uint8, Int16, Uint16, Int32, Uint32, Uintptr:
- return a.assignIntN(offset, t.size, 1, 0b0)
- case Int64, Uint64:
- switch goarch.PtrSize {
- case 4:
- return a.assignIntN(offset, 4, 2, 0b0)
- case 8:
- return a.assignIntN(offset, 8, 1, 0b0)
- }
- case Float32, Float64:
- return a.assignFloatN(offset, t.size, 1)
- case Complex64:
- return a.assignFloatN(offset, 4, 2)
- case Complex128:
- return a.assignFloatN(offset, 8, 2)
- case String:
- return a.assignIntN(offset, goarch.PtrSize, 2, 0b01)
- case Interface:
- return a.assignIntN(offset, goarch.PtrSize, 2, 0b10)
- case Slice:
- return a.assignIntN(offset, goarch.PtrSize, 3, 0b001)
- case Array:
- tt := (*arrayType)(unsafe.Pointer(t))
- switch tt.len {
- case 0:
- // There's nothing to assign, so don't modify
- // a.steps but succeed so the caller doesn't
- // try to stack-assign this value.
- return true
- case 1:
- return a.regAssign(tt.elem, offset)
- default:
- return false
- }
- case Struct:
- st := (*structType)(unsafe.Pointer(t))
- for i := range st.fields {
- f := &st.fields[i]
- if !a.regAssign(f.typ, offset+f.offset) {
- return false
- }
- }
- return true
- default:
- print("t.Kind == ", t.Kind(), "\n")
- panic("unknown type kind")
- }
- panic("unhandled register assignment path")
-}
-
-// assignIntN assigns n values to registers, each "size" bytes large,
-// from the data at [offset, offset+n*size) in memory. Each value at
-// [offset+i*size, offset+(i+1)*size) for i < n is assigned to the
-// next n integer registers.
-//
-// Bit i in ptrMap indicates whether the i'th value is a pointer.
-// n must be <= 8.
-//
-// Returns whether assignment succeeded.
-func (a *abiSeq) assignIntN(offset, size uintptr, n int, ptrMap uint8) bool {
- if n > 8 || n < 0 {
- panic("invalid n")
- }
- if ptrMap != 0 && size != goarch.PtrSize {
- panic("non-empty pointer map passed for non-pointer-size values")
- }
- if a.iregs+n > intArgRegs {
- return false
- }
- for i := 0; i < n; i++ {
- kind := abiStepIntReg
- if ptrMap&(uint8(1)<<i) != 0 {
- kind = abiStepPointer
- }
- a.steps = append(a.steps, abiStep{
- kind: kind,
- offset: offset + uintptr(i)*size,
- size: size,
- ireg: a.iregs,
- })
- a.iregs++
- }
- return true
-}
-
-// assignFloatN assigns n values to registers, each "size" bytes large,
-// from the data at [offset, offset+n*size) in memory. Each value at
-// [offset+i*size, offset+(i+1)*size) for i < n is assigned to the
-// next n floating-point registers.
-//
-// Returns whether assignment succeeded.
-func (a *abiSeq) assignFloatN(offset, size uintptr, n int) bool {
- if n < 0 {
- panic("invalid n")
- }
- if a.fregs+n > floatArgRegs || floatRegSize < size {
- return false
- }
- for i := 0; i < n; i++ {
- a.steps = append(a.steps, abiStep{
- kind: abiStepFloatReg,
- offset: offset + uintptr(i)*size,
- size: size,
- freg: a.fregs,
- })
- a.fregs++
- }
- return true
-}
-
-// stackAssign reserves space for one value that is "size" bytes
-// large with alignment "alignment" to the stack.
-//
-// Should not be called directly; use addArg instead.
-func (a *abiSeq) stackAssign(size, alignment uintptr) {
- a.stackBytes = align(a.stackBytes, alignment)
- a.steps = append(a.steps, abiStep{
- kind: abiStepStack,
- offset: 0, // Only used for whole arguments, so the memory offset is 0.
- size: size,
- stkOff: a.stackBytes,
- })
- a.stackBytes += size
-}
-
-// abiDesc describes the ABI for a function or method.
-type abiDesc struct {
- // call and ret represent the translation steps for
- // the call and return paths of a Go function.
- call, ret abiSeq
-
- // These fields describe the stack space allocated
- // for the call. stackCallArgsSize is the amount of space
- // reserved for arguments but not return values. retOffset
- // is the offset at which return values begin, and
- // spill is the size in bytes of additional space reserved
- // to spill argument registers into in case of preemption in
- // reflectcall's stack frame.
- stackCallArgsSize, retOffset, spill uintptr
-
- // stackPtrs is a bitmap that indicates whether
- // each word in the ABI stack space (stack-assigned
- // args + return values) is a pointer. Used
- // as the heap pointer bitmap for stack space
- // passed to reflectcall.
- stackPtrs *bitVector
-
- // inRegPtrs is a bitmap whose i'th bit indicates
- // whether the i'th integer argument register contains
- // a pointer. Used by makeFuncStub and methodValueCall
- // to make result pointers visible to the GC.
- //
- // outRegPtrs is the same, but for result values.
- // Used by reflectcall to make result pointers visible
- // to the GC.
- inRegPtrs, outRegPtrs abi.IntArgRegBitmap
-}
-
-func (a *abiDesc) dump() {
- println("ABI")
- println("call")
- a.call.dump()
- println("ret")
- a.ret.dump()
- println("stackCallArgsSize", a.stackCallArgsSize)
- println("retOffset", a.retOffset)
- println("spill", a.spill)
- print("inRegPtrs:")
- dumpPtrBitMap(a.inRegPtrs)
- println()
- print("outRegPtrs:")
- dumpPtrBitMap(a.outRegPtrs)
- println()
-}
-
-func dumpPtrBitMap(b abi.IntArgRegBitmap) {
- for i := 0; i < intArgRegs; i++ {
- x := 0
- if b.Get(i) {
- x = 1
- }
- print(" ", x)
- }
-}
-
-func newAbiDesc(t *funcType, rcvr *rtype) abiDesc {
- // We need to add space for this argument to
- // the frame so that it can spill args into it.
- //
- // The size of this space is just the sum of the sizes
- // of each register-allocated type.
- //
- // TODO(mknyszek): Remove this when we no longer have
- // caller reserved spill space.
- spill := uintptr(0)
-
- // Compute gc program & stack bitmap for stack arguments
- stackPtrs := new(bitVector)
-
- // Compute the stack frame pointer bitmap and register
- // pointer bitmap for arguments.
- inRegPtrs := abi.IntArgRegBitmap{}
-
- // Compute abiSeq for input parameters.
- var in abiSeq
- if rcvr != nil {
- stkStep, isPtr := in.addRcvr(rcvr)
- if stkStep != nil {
- if isPtr {
- stackPtrs.append(1)
- } else {
- stackPtrs.append(0)
- }
- } else {
- spill += goarch.PtrSize
- }
- }
- for i, arg := range t.in() {
- stkStep := in.addArg(arg)
- if stkStep != nil {
- addTypeBits(stackPtrs, stkStep.stkOff, arg)
- } else {
- spill = align(spill, uintptr(arg.align))
- spill += arg.size
- for _, st := range in.stepsForValue(i) {
- if st.kind == abiStepPointer {
- inRegPtrs.Set(st.ireg)
- }
- }
- }
- }
- spill = align(spill, goarch.PtrSize)
-
- // From the input parameters alone, we now know
- // the stackCallArgsSize and retOffset.
- stackCallArgsSize := in.stackBytes
- retOffset := align(in.stackBytes, goarch.PtrSize)
-
- // Compute the stack frame pointer bitmap and register
- // pointer bitmap for return values.
- outRegPtrs := abi.IntArgRegBitmap{}
-
- // Compute abiSeq for output parameters.
- var out abiSeq
- // Stack-assigned return values do not share
- // space with arguments like they do with registers,
- // so we need to inject a stack offset here.
- // Fake it by artificially extending stackBytes by
- // the return offset.
- out.stackBytes = retOffset
- for i, res := range t.out() {
- stkStep := out.addArg(res)
- if stkStep != nil {
- addTypeBits(stackPtrs, stkStep.stkOff, res)
- } else {
- for _, st := range out.stepsForValue(i) {
- if st.kind == abiStepPointer {
- outRegPtrs.Set(st.ireg)
- }
- }
- }
- }
- // Undo the faking from earlier so that stackBytes
- // is accurate.
- out.stackBytes -= retOffset
- return abiDesc{in, out, stackCallArgsSize, retOffset, spill, stackPtrs, inRegPtrs, outRegPtrs}
-}
-
-// intFromReg loads an argSize sized integer from reg and places it at to.
-//
-// argSize must be non-zero, fit in a register, and a power-of-two.
-func intFromReg(r *abi.RegArgs, reg int, argSize uintptr, to unsafe.Pointer) {
- memmove(to, r.IntRegArgAddr(reg, argSize), argSize)
-}
-
-// intToReg loads an argSize sized integer and stores it into reg.
-//
-// argSize must be non-zero, fit in a register, and a power-of-two.
-func intToReg(r *abi.RegArgs, reg int, argSize uintptr, from unsafe.Pointer) {
- memmove(r.IntRegArgAddr(reg, argSize), from, argSize)
-}
-
-// floatFromReg loads a float value from its register representation in r.
-//
-// argSize must be 4 or 8.
-func floatFromReg(r *abi.RegArgs, reg int, argSize uintptr, to unsafe.Pointer) {
- switch argSize {
- case 4:
- *(*float32)(to) = archFloat32FromReg(r.Floats[reg])
- case 8:
- *(*float64)(to) = *(*float64)(unsafe.Pointer(&r.Floats[reg]))
- default:
- panic("bad argSize")
- }
-}
-
-// floatToReg stores a float value in its register representation in r.
-//
-// argSize must be either 4 or 8.
-func floatToReg(r *abi.RegArgs, reg int, argSize uintptr, from unsafe.Pointer) {
- switch argSize {
- case 4:
- r.Floats[reg] = archFloat32ToReg(*(*float32)(from))
- case 8:
- r.Floats[reg] = *(*uint64)(from)
- default:
- panic("bad argSize")
- }
-}
diff --git a/contrib/go/_std_1.20/src/reflect/deepequal.go b/contrib/go/_std_1.20/src/reflect/deepequal.go
deleted file mode 100644
index c898bc834a..0000000000
--- a/contrib/go/_std_1.20/src/reflect/deepequal.go
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright 2009 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.
-
-// Deep equality test via reflection
-
-package reflect
-
-import (
- "internal/bytealg"
- "unsafe"
-)
-
-// During deepValueEqual, must keep track of checks that are
-// in progress. The comparison algorithm assumes that all
-// checks in progress are true when it reencounters them.
-// Visited comparisons are stored in a map indexed by visit.
-type visit struct {
- a1 unsafe.Pointer
- a2 unsafe.Pointer
- typ Type
-}
-
-// Tests for deep equality using reflected types. The map argument tracks
-// comparisons that have already been seen, which allows short circuiting on
-// recursive types.
-func deepValueEqual(v1, v2 Value, visited map[visit]bool) bool {
- if !v1.IsValid() || !v2.IsValid() {
- return v1.IsValid() == v2.IsValid()
- }
- if v1.Type() != v2.Type() {
- return false
- }
-
- // We want to avoid putting more in the visited map than we need to.
- // For any possible reference cycle that might be encountered,
- // hard(v1, v2) needs to return true for at least one of the types in the cycle,
- // and it's safe and valid to get Value's internal pointer.
- hard := func(v1, v2 Value) bool {
- switch v1.Kind() {
- case Pointer:
- if v1.typ.ptrdata == 0 {
- // not-in-heap pointers can't be cyclic.
- // At least, all of our current uses of runtime/internal/sys.NotInHeap
- // have that property. The runtime ones aren't cyclic (and we don't use
- // DeepEqual on them anyway), and the cgo-generated ones are
- // all empty structs.
- return false
- }
- fallthrough
- case Map, Slice, Interface:
- // Nil pointers cannot be cyclic. Avoid putting them in the visited map.
- return !v1.IsNil() && !v2.IsNil()
- }
- return false
- }
-
- if hard(v1, v2) {
- // For a Pointer or Map value, we need to check flagIndir,
- // which we do by calling the pointer method.
- // For Slice or Interface, flagIndir is always set,
- // and using v.ptr suffices.
- ptrval := func(v Value) unsafe.Pointer {
- switch v.Kind() {
- case Pointer, Map:
- return v.pointer()
- default:
- return v.ptr
- }
- }
- addr1 := ptrval(v1)
- addr2 := ptrval(v2)
- if uintptr(addr1) > uintptr(addr2) {
- // Canonicalize order to reduce number of entries in visited.
- // Assumes non-moving garbage collector.
- addr1, addr2 = addr2, addr1
- }
-
- // Short circuit if references are already seen.
- typ := v1.Type()
- v := visit{addr1, addr2, typ}
- if visited[v] {
- return true
- }
-
- // Remember for later.
- visited[v] = true
- }
-
- switch v1.Kind() {
- case Array:
- for i := 0; i < v1.Len(); i++ {
- if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
- return false
- }
- }
- return true
- case Slice:
- if v1.IsNil() != v2.IsNil() {
- return false
- }
- if v1.Len() != v2.Len() {
- return false
- }
- if v1.UnsafePointer() == v2.UnsafePointer() {
- return true
- }
- // Special case for []byte, which is common.
- if v1.Type().Elem().Kind() == Uint8 {
- return bytealg.Equal(v1.Bytes(), v2.Bytes())
- }
- for i := 0; i < v1.Len(); i++ {
- if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
- return false
- }
- }
- return true
- case Interface:
- if v1.IsNil() || v2.IsNil() {
- return v1.IsNil() == v2.IsNil()
- }
- return deepValueEqual(v1.Elem(), v2.Elem(), visited)
- case Pointer:
- if v1.UnsafePointer() == v2.UnsafePointer() {
- return true
- }
- return deepValueEqual(v1.Elem(), v2.Elem(), visited)
- case Struct:
- for i, n := 0, v1.NumField(); i < n; i++ {
- if !deepValueEqual(v1.Field(i), v2.Field(i), visited) {
- return false
- }
- }
- return true
- case Map:
- if v1.IsNil() != v2.IsNil() {
- return false
- }
- if v1.Len() != v2.Len() {
- return false
- }
- if v1.UnsafePointer() == v2.UnsafePointer() {
- return true
- }
- for _, k := range v1.MapKeys() {
- val1 := v1.MapIndex(k)
- val2 := v2.MapIndex(k)
- if !val1.IsValid() || !val2.IsValid() || !deepValueEqual(val1, val2, visited) {
- return false
- }
- }
- return true
- case Func:
- if v1.IsNil() && v2.IsNil() {
- return true
- }
- // Can't do better than this:
- return false
- case Int, Int8, Int16, Int32, Int64:
- return v1.Int() == v2.Int()
- case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
- return v1.Uint() == v2.Uint()
- case String:
- return v1.String() == v2.String()
- case Bool:
- return v1.Bool() == v2.Bool()
- case Float32, Float64:
- return v1.Float() == v2.Float()
- case Complex64, Complex128:
- return v1.Complex() == v2.Complex()
- default:
- // Normal equality suffices
- return valueInterface(v1, false) == valueInterface(v2, false)
- }
-}
-
-// DeepEqual reports whether x and y are “deeply equal,” defined as follows.
-// Two values of identical type are deeply equal if one of the following cases applies.
-// Values of distinct types are never deeply equal.
-//
-// Array values are deeply equal when their corresponding elements are deeply equal.
-//
-// Struct values are deeply equal if their corresponding fields,
-// both exported and unexported, are deeply equal.
-//
-// Func values are deeply equal if both are nil; otherwise they are not deeply equal.
-//
-// Interface values are deeply equal if they hold deeply equal concrete values.
-//
-// Map values are deeply equal when all of the following are true:
-// they are both nil or both non-nil, they have the same length,
-// and either they are the same map object or their corresponding keys
-// (matched using Go equality) map to deeply equal values.
-//
-// Pointer values are deeply equal if they are equal using Go's == operator
-// or if they point to deeply equal values.
-//
-// Slice values are deeply equal when all of the following are true:
-// they are both nil or both non-nil, they have the same length,
-// and either they point to the same initial entry of the same underlying array
-// (that is, &x[0] == &y[0]) or their corresponding elements (up to length) are deeply equal.
-// Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil))
-// are not deeply equal.
-//
-// Other values - numbers, bools, strings, and channels - are deeply equal
-// if they are equal using Go's == operator.
-//
-// In general DeepEqual is a recursive relaxation of Go's == operator.
-// However, this idea is impossible to implement without some inconsistency.
-// Specifically, it is possible for a value to be unequal to itself,
-// either because it is of func type (uncomparable in general)
-// or because it is a floating-point NaN value (not equal to itself in floating-point comparison),
-// or because it is an array, struct, or interface containing
-// such a value.
-// On the other hand, pointer values are always equal to themselves,
-// even if they point at or contain such problematic values,
-// because they compare equal using Go's == operator, and that
-// is a sufficient condition to be deeply equal, regardless of content.
-// DeepEqual has been defined so that the same short-cut applies
-// to slices and maps: if x and y are the same slice or the same map,
-// they are deeply equal regardless of content.
-//
-// As DeepEqual traverses the data values it may find a cycle. The
-// second and subsequent times that DeepEqual compares two pointer
-// values that have been compared before, it treats the values as
-// equal rather than examining the values to which they point.
-// This ensures that DeepEqual terminates.
-func DeepEqual(x, y any) bool {
- if x == nil || y == nil {
- return x == y
- }
- v1 := ValueOf(x)
- v2 := ValueOf(y)
- if v1.Type() != v2.Type() {
- return false
- }
- return deepValueEqual(v1, v2, make(map[visit]bool))
-}
diff --git a/contrib/go/_std_1.20/src/reflect/makefunc.go b/contrib/go/_std_1.20/src/reflect/makefunc.go
deleted file mode 100644
index ee0729903e..0000000000
--- a/contrib/go/_std_1.20/src/reflect/makefunc.go
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2012 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.
-
-// MakeFunc implementation.
-
-package reflect
-
-import (
- "internal/abi"
- "unsafe"
-)
-
-// makeFuncImpl is the closure value implementing the function
-// returned by MakeFunc.
-// The first three words of this type must be kept in sync with
-// methodValue and runtime.reflectMethodValue.
-// Any changes should be reflected in all three.
-type makeFuncImpl struct {
- makeFuncCtxt
- ftyp *funcType
- fn func([]Value) []Value
-}
-
-// MakeFunc returns a new function of the given Type
-// that wraps the function fn. When called, that new function
-// does the following:
-//
-// - converts its arguments to a slice of Values.
-// - runs results := fn(args).
-// - returns the results as a slice of Values, one per formal result.
-//
-// The implementation fn can assume that the argument Value slice
-// has the number and type of arguments given by typ.
-// If typ describes a variadic function, the final Value is itself
-// a slice representing the variadic arguments, as in the
-// body of a variadic function. The result Value slice returned by fn
-// must have the number and type of results given by typ.
-//
-// The Value.Call method allows the caller to invoke a typed function
-// in terms of Values; in contrast, MakeFunc allows the caller to implement
-// a typed function in terms of Values.
-//
-// The Examples section of the documentation includes an illustration
-// of how to use MakeFunc to build a swap function for different types.
-func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value {
- if typ.Kind() != Func {
- panic("reflect: call of MakeFunc with non-Func type")
- }
-
- t := typ.common()
- ftyp := (*funcType)(unsafe.Pointer(t))
-
- code := abi.FuncPCABI0(makeFuncStub)
-
- // makeFuncImpl contains a stack map for use by the runtime
- _, _, abid := funcLayout(ftyp, nil)
-
- impl := &makeFuncImpl{
- makeFuncCtxt: makeFuncCtxt{
- fn: code,
- stack: abid.stackPtrs,
- argLen: abid.stackCallArgsSize,
- regPtrs: abid.inRegPtrs,
- },
- ftyp: ftyp,
- fn: fn,
- }
-
- return Value{t, unsafe.Pointer(impl), flag(Func)}
-}
-
-// makeFuncStub is an assembly function that is the code half of
-// the function returned from MakeFunc. It expects a *callReflectFunc
-// as its context register, and its job is to invoke callReflect(ctxt, frame)
-// where ctxt is the context register and frame is a pointer to the first
-// word in the passed-in argument frame.
-func makeFuncStub()
-
-// The first 3 words of this type must be kept in sync with
-// makeFuncImpl and runtime.reflectMethodValue.
-// Any changes should be reflected in all three.
-type methodValue struct {
- makeFuncCtxt
- method int
- rcvr Value
-}
-
-// makeMethodValue converts v from the rcvr+method index representation
-// of a method value to an actual method func value, which is
-// basically the receiver value with a special bit set, into a true
-// func value - a value holding an actual func. The output is
-// semantically equivalent to the input as far as the user of package
-// reflect can tell, but the true func representation can be handled
-// by code like Convert and Interface and Assign.
-func makeMethodValue(op string, v Value) Value {
- if v.flag&flagMethod == 0 {
- panic("reflect: internal error: invalid use of makeMethodValue")
- }
-
- // Ignoring the flagMethod bit, v describes the receiver, not the method type.
- fl := v.flag & (flagRO | flagAddr | flagIndir)
- fl |= flag(v.typ.Kind())
- rcvr := Value{v.typ, v.ptr, fl}
-
- // v.Type returns the actual type of the method value.
- ftyp := (*funcType)(unsafe.Pointer(v.Type().(*rtype)))
-
- code := methodValueCallCodePtr()
-
- // methodValue contains a stack map for use by the runtime
- _, _, abid := funcLayout(ftyp, nil)
- fv := &methodValue{
- makeFuncCtxt: makeFuncCtxt{
- fn: code,
- stack: abid.stackPtrs,
- argLen: abid.stackCallArgsSize,
- regPtrs: abid.inRegPtrs,
- },
- method: int(v.flag) >> flagMethodShift,
- rcvr: rcvr,
- }
-
- // Cause panic if method is not appropriate.
- // The panic would still happen during the call if we omit this,
- // but we want Interface() and other operations to fail early.
- methodReceiver(op, fv.rcvr, fv.method)
-
- return Value{&ftyp.rtype, unsafe.Pointer(fv), v.flag&flagRO | flag(Func)}
-}
-
-func methodValueCallCodePtr() uintptr {
- return abi.FuncPCABI0(methodValueCall)
-}
-
-// methodValueCall is an assembly function that is the code half of
-// the function returned from makeMethodValue. It expects a *methodValue
-// as its context register, and its job is to invoke callMethod(ctxt, frame)
-// where ctxt is the context register and frame is a pointer to the first
-// word in the passed-in argument frame.
-func methodValueCall()
-
-// This structure must be kept in sync with runtime.reflectMethodValue.
-// Any changes should be reflected in all both.
-type makeFuncCtxt struct {
- fn uintptr
- stack *bitVector // ptrmap for both stack args and results
- argLen uintptr // just args
- regPtrs abi.IntArgRegBitmap
-}
-
-// moveMakeFuncArgPtrs uses ctxt.regPtrs to copy integer pointer arguments
-// in args.Ints to args.Ptrs where the GC can see them.
-//
-// This is similar to what reflectcallmove does in the runtime, except
-// that happens on the return path, whereas this happens on the call path.
-//
-// nosplit because pointers are being held in uintptr slots in args, so
-// having our stack scanned now could lead to accidentally freeing
-// memory.
-//
-//go:nosplit
-func moveMakeFuncArgPtrs(ctxt *makeFuncCtxt, args *abi.RegArgs) {
- for i, arg := range args.Ints {
- // Avoid write barriers! Because our write barrier enqueues what
- // was there before, we might enqueue garbage.
- if ctxt.regPtrs.Get(i) {
- *(*uintptr)(unsafe.Pointer(&args.Ptrs[i])) = arg
- } else {
- // We *must* zero this space ourselves because it's defined in
- // assembly code and the GC will scan these pointers. Otherwise,
- // there will be garbage here.
- *(*uintptr)(unsafe.Pointer(&args.Ptrs[i])) = 0
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/reflect/swapper.go b/contrib/go/_std_1.20/src/reflect/swapper.go
deleted file mode 100644
index 745c7b9f49..0000000000
--- a/contrib/go/_std_1.20/src/reflect/swapper.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2016 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 reflect
-
-import (
- "internal/goarch"
- "internal/unsafeheader"
- "unsafe"
-)
-
-// Swapper returns a function that swaps the elements in the provided
-// slice.
-//
-// Swapper panics if the provided interface is not a slice.
-func Swapper(slice any) func(i, j int) {
- v := ValueOf(slice)
- if v.Kind() != Slice {
- panic(&ValueError{Method: "Swapper", Kind: v.Kind()})
- }
- // Fast path for slices of size 0 and 1. Nothing to swap.
- switch v.Len() {
- case 0:
- return func(i, j int) { panic("reflect: slice index out of range") }
- case 1:
- return func(i, j int) {
- if i != 0 || j != 0 {
- panic("reflect: slice index out of range")
- }
- }
- }
-
- typ := v.Type().Elem().(*rtype)
- size := typ.Size()
- hasPtr := typ.ptrdata != 0
-
- // Some common & small cases, without using memmove:
- if hasPtr {
- if size == goarch.PtrSize {
- ps := *(*[]unsafe.Pointer)(v.ptr)
- return func(i, j int) { ps[i], ps[j] = ps[j], ps[i] }
- }
- if typ.Kind() == String {
- ss := *(*[]string)(v.ptr)
- return func(i, j int) { ss[i], ss[j] = ss[j], ss[i] }
- }
- } else {
- switch size {
- case 8:
- is := *(*[]int64)(v.ptr)
- return func(i, j int) { is[i], is[j] = is[j], is[i] }
- case 4:
- is := *(*[]int32)(v.ptr)
- return func(i, j int) { is[i], is[j] = is[j], is[i] }
- case 2:
- is := *(*[]int16)(v.ptr)
- return func(i, j int) { is[i], is[j] = is[j], is[i] }
- case 1:
- is := *(*[]int8)(v.ptr)
- return func(i, j int) { is[i], is[j] = is[j], is[i] }
- }
- }
-
- s := (*unsafeheader.Slice)(v.ptr)
- tmp := unsafe_New(typ) // swap scratch space
-
- return func(i, j int) {
- if uint(i) >= uint(s.Len) || uint(j) >= uint(s.Len) {
- panic("reflect: slice index out of range")
- }
- val1 := arrayAt(s.Data, i, size, "i < s.Len")
- val2 := arrayAt(s.Data, j, size, "j < s.Len")
- typedmemmove(typ, tmp, val1)
- typedmemmove(typ, val1, val2)
- typedmemmove(typ, val2, tmp)
- }
-}
diff --git a/contrib/go/_std_1.20/src/reflect/type.go b/contrib/go/_std_1.20/src/reflect/type.go
deleted file mode 100644
index 01d14567c3..0000000000
--- a/contrib/go/_std_1.20/src/reflect/type.go
+++ /dev/null
@@ -1,3186 +0,0 @@
-// Copyright 2009 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 reflect implements run-time reflection, allowing a program to
-// manipulate objects with arbitrary types. The typical use is to take a value
-// with static type interface{} and extract its dynamic type information by
-// calling TypeOf, which returns a Type.
-//
-// A call to ValueOf returns a Value representing the run-time data.
-// Zero takes a Type and returns a Value representing a zero value
-// for that type.
-//
-// See "The Laws of Reflection" for an introduction to reflection in Go:
-// https://golang.org/doc/articles/laws_of_reflection.html
-package reflect
-
-import (
- "internal/goarch"
- "strconv"
- "sync"
- "unicode"
- "unicode/utf8"
- "unsafe"
-)
-
-// Type is the representation of a Go type.
-//
-// Not all methods apply to all kinds of types. Restrictions,
-// if any, are noted in the documentation for each method.
-// Use the Kind method to find out the kind of type before
-// calling kind-specific methods. Calling a method
-// inappropriate to the kind of type causes a run-time panic.
-//
-// Type values are comparable, such as with the == operator,
-// so they can be used as map keys.
-// Two Type values are equal if they represent identical types.
-type Type interface {
- // Methods applicable to all types.
-
- // Align returns the alignment in bytes of a value of
- // this type when allocated in memory.
- Align() int
-
- // FieldAlign returns the alignment in bytes of a value of
- // this type when used as a field in a struct.
- FieldAlign() int
-
- // Method returns the i'th method in the type's method set.
- // It panics if i is not in the range [0, NumMethod()).
- //
- // For a non-interface type T or *T, the returned Method's Type and Func
- // fields describe a function whose first argument is the receiver,
- // and only exported methods are accessible.
- //
- // For an interface type, the returned Method's Type field gives the
- // method signature, without a receiver, and the Func field is nil.
- //
- // Methods are sorted in lexicographic order.
- Method(int) Method
-
- // MethodByName returns the method with that name in the type's
- // method set and a boolean indicating if the method was found.
- //
- // For a non-interface type T or *T, the returned Method's Type and Func
- // fields describe a function whose first argument is the receiver.
- //
- // For an interface type, the returned Method's Type field gives the
- // method signature, without a receiver, and the Func field is nil.
- MethodByName(string) (Method, bool)
-
- // NumMethod returns the number of methods accessible using Method.
- //
- // For a non-interface type, it returns the number of exported methods.
- //
- // For an interface type, it returns the number of exported and unexported methods.
- NumMethod() int
-
- // Name returns the type's name within its package for a defined type.
- // For other (non-defined) types it returns the empty string.
- Name() string
-
- // PkgPath returns a defined type's package path, that is, the import path
- // that uniquely identifies the package, such as "encoding/base64".
- // If the type was predeclared (string, error) or not defined (*T, struct{},
- // []int, or A where A is an alias for a non-defined type), the package path
- // will be the empty string.
- PkgPath() string
-
- // Size returns the number of bytes needed to store
- // a value of the given type; it is analogous to unsafe.Sizeof.
- Size() uintptr
-
- // String returns a string representation of the type.
- // The string representation may use shortened package names
- // (e.g., base64 instead of "encoding/base64") and is not
- // guaranteed to be unique among types. To test for type identity,
- // compare the Types directly.
- String() string
-
- // Kind returns the specific kind of this type.
- Kind() Kind
-
- // Implements reports whether the type implements the interface type u.
- Implements(u Type) bool
-
- // AssignableTo reports whether a value of the type is assignable to type u.
- AssignableTo(u Type) bool
-
- // ConvertibleTo reports whether a value of the type is convertible to type u.
- // Even if ConvertibleTo returns true, the conversion may still panic.
- // For example, a slice of type []T is convertible to *[N]T,
- // but the conversion will panic if its length is less than N.
- ConvertibleTo(u Type) bool
-
- // Comparable reports whether values of this type are comparable.
- // Even if Comparable returns true, the comparison may still panic.
- // For example, values of interface type are comparable,
- // but the comparison will panic if their dynamic type is not comparable.
- Comparable() bool
-
- // Methods applicable only to some types, depending on Kind.
- // The methods allowed for each kind are:
- //
- // Int*, Uint*, Float*, Complex*: Bits
- // Array: Elem, Len
- // Chan: ChanDir, Elem
- // Func: In, NumIn, Out, NumOut, IsVariadic.
- // Map: Key, Elem
- // Pointer: Elem
- // Slice: Elem
- // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField
-
- // Bits returns the size of the type in bits.
- // It panics if the type's Kind is not one of the
- // sized or unsized Int, Uint, Float, or Complex kinds.
- Bits() int
-
- // ChanDir returns a channel type's direction.
- // It panics if the type's Kind is not Chan.
- ChanDir() ChanDir
-
- // IsVariadic reports whether a function type's final input parameter
- // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's
- // implicit actual type []T.
- //
- // For concreteness, if t represents func(x int, y ... float64), then
- //
- // t.NumIn() == 2
- // t.In(0) is the reflect.Type for "int"
- // t.In(1) is the reflect.Type for "[]float64"
- // t.IsVariadic() == true
- //
- // IsVariadic panics if the type's Kind is not Func.
- IsVariadic() bool
-
- // Elem returns a type's element type.
- // It panics if the type's Kind is not Array, Chan, Map, Pointer, or Slice.
- Elem() Type
-
- // Field returns a struct type's i'th field.
- // It panics if the type's Kind is not Struct.
- // It panics if i is not in the range [0, NumField()).
- Field(i int) StructField
-
- // FieldByIndex returns the nested field corresponding
- // to the index sequence. It is equivalent to calling Field
- // successively for each index i.
- // It panics if the type's Kind is not Struct.
- FieldByIndex(index []int) StructField
-
- // FieldByName returns the struct field with the given name
- // and a boolean indicating if the field was found.
- FieldByName(name string) (StructField, bool)
-
- // FieldByNameFunc returns the struct field with a name
- // that satisfies the match function and a boolean indicating if
- // the field was found.
- //
- // FieldByNameFunc considers the fields in the struct itself
- // and then the fields in any embedded structs, in breadth first order,
- // stopping at the shallowest nesting depth containing one or more
- // fields satisfying the match function. If multiple fields at that depth
- // satisfy the match function, they cancel each other
- // and FieldByNameFunc returns no match.
- // This behavior mirrors Go's handling of name lookup in
- // structs containing embedded fields.
- FieldByNameFunc(match func(string) bool) (StructField, bool)
-
- // In returns the type of a function type's i'th input parameter.
- // It panics if the type's Kind is not Func.
- // It panics if i is not in the range [0, NumIn()).
- In(i int) Type
-
- // Key returns a map type's key type.
- // It panics if the type's Kind is not Map.
- Key() Type
-
- // Len returns an array type's length.
- // It panics if the type's Kind is not Array.
- Len() int
-
- // NumField returns a struct type's field count.
- // It panics if the type's Kind is not Struct.
- NumField() int
-
- // NumIn returns a function type's input parameter count.
- // It panics if the type's Kind is not Func.
- NumIn() int
-
- // NumOut returns a function type's output parameter count.
- // It panics if the type's Kind is not Func.
- NumOut() int
-
- // Out returns the type of a function type's i'th output parameter.
- // It panics if the type's Kind is not Func.
- // It panics if i is not in the range [0, NumOut()).
- Out(i int) Type
-
- common() *rtype
- uncommon() *uncommonType
-}
-
-// BUG(rsc): FieldByName and related functions consider struct field names to be equal
-// if the names are equal, even if they are unexported names originating
-// in different packages. The practical effect of this is that the result of
-// t.FieldByName("x") is not well defined if the struct type t contains
-// multiple fields named x (embedded from different packages).
-// FieldByName may return one of the fields named x or may report that there are none.
-// See https://golang.org/issue/4876 for more details.
-
-/*
- * These data structures are known to the compiler (../cmd/compile/internal/reflectdata/reflect.go).
- * A few are known to ../runtime/type.go to convey to debuggers.
- * They are also known to ../runtime/type.go.
- */
-
-// A Kind represents the specific kind of type that a Type represents.
-// The zero Kind is not a valid kind.
-type Kind uint
-
-const (
- Invalid Kind = iota
- Bool
- Int
- Int8
- Int16
- Int32
- Int64
- Uint
- Uint8
- Uint16
- Uint32
- Uint64
- Uintptr
- Float32
- Float64
- Complex64
- Complex128
- Array
- Chan
- Func
- Interface
- Map
- Pointer
- Slice
- String
- Struct
- UnsafePointer
-)
-
-// Ptr is the old name for the Pointer kind.
-const Ptr = Pointer
-
-// tflag is used by an rtype to signal what extra type information is
-// available in the memory directly following the rtype value.
-//
-// tflag values must be kept in sync with copies in:
-//
-// cmd/compile/internal/reflectdata/reflect.go
-// cmd/link/internal/ld/decodesym.go
-// runtime/type.go
-type tflag uint8
-
-const (
- // tflagUncommon means that there is a pointer, *uncommonType,
- // just beyond the outer type structure.
- //
- // For example, if t.Kind() == Struct and t.tflag&tflagUncommon != 0,
- // then t has uncommonType data and it can be accessed as:
- //
- // type tUncommon struct {
- // structType
- // u uncommonType
- // }
- // u := &(*tUncommon)(unsafe.Pointer(t)).u
- tflagUncommon tflag = 1 << 0
-
- // tflagExtraStar means the name in the str field has an
- // extraneous '*' prefix. This is because for most types T in
- // a program, the type *T also exists and reusing the str data
- // saves binary size.
- tflagExtraStar tflag = 1 << 1
-
- // tflagNamed means the type has a name.
- tflagNamed tflag = 1 << 2
-
- // tflagRegularMemory means that equal and hash functions can treat
- // this type as a single region of t.size bytes.
- tflagRegularMemory tflag = 1 << 3
-)
-
-// rtype is the common implementation of most values.
-// It is embedded in other struct types.
-//
-// rtype must be kept in sync with ../runtime/type.go:/^type._type.
-type rtype struct {
- size uintptr
- ptrdata uintptr // number of bytes in the type that can contain pointers
- hash uint32 // hash of type; avoids computation in hash tables
- tflag tflag // extra type information flags
- align uint8 // alignment of variable with this type
- fieldAlign uint8 // alignment of struct field with this type
- kind uint8 // enumeration for C
- // function for comparing objects of this type
- // (ptr to object A, ptr to object B) -> ==?
- equal func(unsafe.Pointer, unsafe.Pointer) bool
- gcdata *byte // garbage collection data
- str nameOff // string form
- ptrToThis typeOff // type for pointer to this type, may be zero
-}
-
-// Method on non-interface type
-type method struct {
- name nameOff // name of method
- mtyp typeOff // method type (without receiver)
- ifn textOff // fn used in interface call (one-word receiver)
- tfn textOff // fn used for normal method call
-}
-
-// uncommonType is present only for defined types or types with methods
-// (if T is a defined type, the uncommonTypes for T and *T have methods).
-// Using a pointer to this struct reduces the overall size required
-// to describe a non-defined type with no methods.
-type uncommonType struct {
- pkgPath nameOff // import path; empty for built-in types like int, string
- mcount uint16 // number of methods
- xcount uint16 // number of exported methods
- moff uint32 // offset from this uncommontype to [mcount]method
- _ uint32 // unused
-}
-
-// ChanDir represents a channel type's direction.
-type ChanDir int
-
-const (
- RecvDir ChanDir = 1 << iota // <-chan
- SendDir // chan<-
- BothDir = RecvDir | SendDir // chan
-)
-
-// arrayType represents a fixed array type.
-type arrayType struct {
- rtype
- elem *rtype // array element type
- slice *rtype // slice type
- len uintptr
-}
-
-// chanType represents a channel type.
-type chanType struct {
- rtype
- elem *rtype // channel element type
- dir uintptr // channel direction (ChanDir)
-}
-
-// funcType represents a function type.
-//
-// A *rtype for each in and out parameter is stored in an array that
-// directly follows the funcType (and possibly its uncommonType). So
-// a function type with one method, one input, and one output is:
-//
-// struct {
-// funcType
-// uncommonType
-// [2]*rtype // [0] is in, [1] is out
-// }
-type funcType struct {
- rtype
- inCount uint16
- outCount uint16 // top bit is set if last input parameter is ...
-}
-
-// imethod represents a method on an interface type
-type imethod struct {
- name nameOff // name of method
- typ typeOff // .(*FuncType) underneath
-}
-
-// interfaceType represents an interface type.
-type interfaceType struct {
- rtype
- pkgPath name // import path
- methods []imethod // sorted by hash
-}
-
-// mapType represents a map type.
-type mapType struct {
- rtype
- key *rtype // map key type
- elem *rtype // map element (value) type
- bucket *rtype // internal bucket structure
- // function for hashing keys (ptr to key, seed) -> hash
- hasher func(unsafe.Pointer, uintptr) uintptr
- keysize uint8 // size of key slot
- valuesize uint8 // size of value slot
- bucketsize uint16 // size of bucket
- flags uint32
-}
-
-// ptrType represents a pointer type.
-type ptrType struct {
- rtype
- elem *rtype // pointer element (pointed at) type
-}
-
-// sliceType represents a slice type.
-type sliceType struct {
- rtype
- elem *rtype // slice element type
-}
-
-// Struct field
-type structField struct {
- name name // name is always non-empty
- typ *rtype // type of field
- offset uintptr // byte offset of field
-}
-
-func (f *structField) embedded() bool {
- return f.name.embedded()
-}
-
-// structType represents a struct type.
-type structType struct {
- rtype
- pkgPath name
- fields []structField // sorted by offset
-}
-
-// name is an encoded type name with optional extra data.
-//
-// The first byte is a bit field containing:
-//
-// 1<<0 the name is exported
-// 1<<1 tag data follows the name
-// 1<<2 pkgPath nameOff follows the name and tag
-// 1<<3 the name is of an embedded (a.k.a. anonymous) field
-//
-// Following that, there is a varint-encoded length of the name,
-// followed by the name itself.
-//
-// If tag data is present, it also has a varint-encoded length
-// followed by the tag itself.
-//
-// If the import path follows, then 4 bytes at the end of
-// the data form a nameOff. The import path is only set for concrete
-// methods that are defined in a different package than their type.
-//
-// If a name starts with "*", then the exported bit represents
-// whether the pointed to type is exported.
-//
-// Note: this encoding must match here and in:
-// cmd/compile/internal/reflectdata/reflect.go
-// runtime/type.go
-// internal/reflectlite/type.go
-// cmd/link/internal/ld/decodesym.go
-
-type name struct {
- bytes *byte
-}
-
-func (n name) data(off int, whySafe string) *byte {
- return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe))
-}
-
-func (n name) isExported() bool {
- return (*n.bytes)&(1<<0) != 0
-}
-
-func (n name) hasTag() bool {
- return (*n.bytes)&(1<<1) != 0
-}
-
-func (n name) embedded() bool {
- return (*n.bytes)&(1<<3) != 0
-}
-
-// readVarint parses a varint as encoded by encoding/binary.
-// It returns the number of encoded bytes and the encoded value.
-func (n name) readVarint(off int) (int, int) {
- v := 0
- for i := 0; ; i++ {
- x := *n.data(off+i, "read varint")
- v += int(x&0x7f) << (7 * i)
- if x&0x80 == 0 {
- return i + 1, v
- }
- }
-}
-
-// writeVarint writes n to buf in varint form. Returns the
-// number of bytes written. n must be nonnegative.
-// Writes at most 10 bytes.
-func writeVarint(buf []byte, n int) int {
- for i := 0; ; i++ {
- b := byte(n & 0x7f)
- n >>= 7
- if n == 0 {
- buf[i] = b
- return i + 1
- }
- buf[i] = b | 0x80
- }
-}
-
-func (n name) name() string {
- if n.bytes == nil {
- return ""
- }
- i, l := n.readVarint(1)
- return unsafe.String(n.data(1+i, "non-empty string"), l)
-}
-
-func (n name) tag() string {
- if !n.hasTag() {
- return ""
- }
- i, l := n.readVarint(1)
- i2, l2 := n.readVarint(1 + i + l)
- return unsafe.String(n.data(1+i+l+i2, "non-empty string"), l2)
-}
-
-func (n name) pkgPath() string {
- if n.bytes == nil || *n.data(0, "name flag field")&(1<<2) == 0 {
- return ""
- }
- i, l := n.readVarint(1)
- off := 1 + i + l
- if n.hasTag() {
- i2, l2 := n.readVarint(off)
- off += i2 + l2
- }
- var nameOff int32
- // Note that this field may not be aligned in memory,
- // so we cannot use a direct int32 assignment here.
- copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off, "name offset field")))[:])
- pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.bytes), nameOff))}
- return pkgPathName.name()
-}
-
-func newName(n, tag string, exported, embedded bool) name {
- if len(n) >= 1<<29 {
- panic("reflect.nameFrom: name too long: " + n[:1024] + "...")
- }
- if len(tag) >= 1<<29 {
- panic("reflect.nameFrom: tag too long: " + tag[:1024] + "...")
- }
- var nameLen [10]byte
- var tagLen [10]byte
- nameLenLen := writeVarint(nameLen[:], len(n))
- tagLenLen := writeVarint(tagLen[:], len(tag))
-
- var bits byte
- l := 1 + nameLenLen + len(n)
- if exported {
- bits |= 1 << 0
- }
- if len(tag) > 0 {
- l += tagLenLen + len(tag)
- bits |= 1 << 1
- }
- if embedded {
- bits |= 1 << 3
- }
-
- b := make([]byte, l)
- b[0] = bits
- copy(b[1:], nameLen[:nameLenLen])
- copy(b[1+nameLenLen:], n)
- if len(tag) > 0 {
- tb := b[1+nameLenLen+len(n):]
- copy(tb, tagLen[:tagLenLen])
- copy(tb[tagLenLen:], tag)
- }
-
- return name{bytes: &b[0]}
-}
-
-/*
- * The compiler knows the exact layout of all the data structures above.
- * The compiler does not know about the data structures and methods below.
- */
-
-// Method represents a single method.
-type Method struct {
- // Name is the method name.
- Name string
-
- // PkgPath is the package path that qualifies a lower case (unexported)
- // method name. It is empty for upper case (exported) method names.
- // The combination of PkgPath and Name uniquely identifies a method
- // in a method set.
- // See https://golang.org/ref/spec#Uniqueness_of_identifiers
- PkgPath string
-
- Type Type // method type
- Func Value // func with receiver as first argument
- Index int // index for Type.Method
-}
-
-// IsExported reports whether the method is exported.
-func (m Method) IsExported() bool {
- return m.PkgPath == ""
-}
-
-const (
- kindDirectIface = 1 << 5
- kindGCProg = 1 << 6 // Type.gc points to GC program
- kindMask = (1 << 5) - 1
-)
-
-// String returns the name of k.
-func (k Kind) String() string {
- if uint(k) < uint(len(kindNames)) {
- return kindNames[uint(k)]
- }
- return "kind" + strconv.Itoa(int(k))
-}
-
-var kindNames = []string{
- Invalid: "invalid",
- Bool: "bool",
- Int: "int",
- Int8: "int8",
- Int16: "int16",
- Int32: "int32",
- Int64: "int64",
- Uint: "uint",
- Uint8: "uint8",
- Uint16: "uint16",
- Uint32: "uint32",
- Uint64: "uint64",
- Uintptr: "uintptr",
- Float32: "float32",
- Float64: "float64",
- Complex64: "complex64",
- Complex128: "complex128",
- Array: "array",
- Chan: "chan",
- Func: "func",
- Interface: "interface",
- Map: "map",
- Pointer: "ptr",
- Slice: "slice",
- String: "string",
- Struct: "struct",
- UnsafePointer: "unsafe.Pointer",
-}
-
-func (t *uncommonType) methods() []method {
- if t.mcount == 0 {
- return nil
- }
- return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.mcount > 0"))[:t.mcount:t.mcount]
-}
-
-func (t *uncommonType) exportedMethods() []method {
- if t.xcount == 0 {
- return nil
- }
- return (*[1 << 16]method)(add(unsafe.Pointer(t), uintptr(t.moff), "t.xcount > 0"))[:t.xcount:t.xcount]
-}
-
-// resolveNameOff resolves a name offset from a base pointer.
-// The (*rtype).nameOff method is a convenience wrapper for this function.
-// Implemented in the runtime package.
-func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
-
-// resolveTypeOff resolves an *rtype offset from a base type.
-// The (*rtype).typeOff method is a convenience wrapper for this function.
-// Implemented in the runtime package.
-func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
-
-// resolveTextOff resolves a function pointer offset from a base type.
-// The (*rtype).textOff method is a convenience wrapper for this function.
-// Implemented in the runtime package.
-func resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
-
-// addReflectOff adds a pointer to the reflection lookup map in the runtime.
-// It returns a new ID that can be used as a typeOff or textOff, and will
-// be resolved correctly. Implemented in the runtime package.
-func addReflectOff(ptr unsafe.Pointer) int32
-
-// resolveReflectName adds a name to the reflection lookup map in the runtime.
-// It returns a new nameOff that can be used to refer to the pointer.
-func resolveReflectName(n name) nameOff {
- return nameOff(addReflectOff(unsafe.Pointer(n.bytes)))
-}
-
-// resolveReflectType adds a *rtype to the reflection lookup map in the runtime.
-// It returns a new typeOff that can be used to refer to the pointer.
-func resolveReflectType(t *rtype) typeOff {
- return typeOff(addReflectOff(unsafe.Pointer(t)))
-}
-
-// resolveReflectText adds a function pointer to the reflection lookup map in
-// the runtime. It returns a new textOff that can be used to refer to the
-// pointer.
-func resolveReflectText(ptr unsafe.Pointer) textOff {
- return textOff(addReflectOff(ptr))
-}
-
-type nameOff int32 // offset to a name
-type typeOff int32 // offset to an *rtype
-type textOff int32 // offset from top of text section
-
-func (t *rtype) nameOff(off nameOff) name {
- return name{(*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
-}
-
-func (t *rtype) typeOff(off typeOff) *rtype {
- return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off)))
-}
-
-func (t *rtype) textOff(off textOff) unsafe.Pointer {
- return resolveTextOff(unsafe.Pointer(t), int32(off))
-}
-
-func (t *rtype) uncommon() *uncommonType {
- if t.tflag&tflagUncommon == 0 {
- return nil
- }
- switch t.Kind() {
- case Struct:
- return &(*structTypeUncommon)(unsafe.Pointer(t)).u
- case Pointer:
- type u struct {
- ptrType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- case Func:
- type u struct {
- funcType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- case Slice:
- type u struct {
- sliceType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- case Array:
- type u struct {
- arrayType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- case Chan:
- type u struct {
- chanType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- case Map:
- type u struct {
- mapType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- case Interface:
- type u struct {
- interfaceType
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- default:
- type u struct {
- rtype
- u uncommonType
- }
- return &(*u)(unsafe.Pointer(t)).u
- }
-}
-
-func (t *rtype) String() string {
- s := t.nameOff(t.str).name()
- if t.tflag&tflagExtraStar != 0 {
- return s[1:]
- }
- return s
-}
-
-func (t *rtype) Size() uintptr { return t.size }
-
-func (t *rtype) Bits() int {
- if t == nil {
- panic("reflect: Bits of nil Type")
- }
- k := t.Kind()
- if k < Int || k > Complex128 {
- panic("reflect: Bits of non-arithmetic Type " + t.String())
- }
- return int(t.size) * 8
-}
-
-func (t *rtype) Align() int { return int(t.align) }
-
-func (t *rtype) FieldAlign() int { return int(t.fieldAlign) }
-
-func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
-
-func (t *rtype) pointers() bool { return t.ptrdata != 0 }
-
-func (t *rtype) common() *rtype { return t }
-
-func (t *rtype) exportedMethods() []method {
- ut := t.uncommon()
- if ut == nil {
- return nil
- }
- return ut.exportedMethods()
-}
-
-func (t *rtype) NumMethod() int {
- if t.Kind() == Interface {
- tt := (*interfaceType)(unsafe.Pointer(t))
- return tt.NumMethod()
- }
- return len(t.exportedMethods())
-}
-
-func (t *rtype) Method(i int) (m Method) {
- if t.Kind() == Interface {
- tt := (*interfaceType)(unsafe.Pointer(t))
- return tt.Method(i)
- }
- methods := t.exportedMethods()
- if i < 0 || i >= len(methods) {
- panic("reflect: Method index out of range")
- }
- p := methods[i]
- pname := t.nameOff(p.name)
- m.Name = pname.name()
- fl := flag(Func)
- mtyp := t.typeOff(p.mtyp)
- ft := (*funcType)(unsafe.Pointer(mtyp))
- in := make([]Type, 0, 1+len(ft.in()))
- in = append(in, t)
- for _, arg := range ft.in() {
- in = append(in, arg)
- }
- out := make([]Type, 0, len(ft.out()))
- for _, ret := range ft.out() {
- out = append(out, ret)
- }
- mt := FuncOf(in, out, ft.IsVariadic())
- m.Type = mt
- tfn := t.textOff(p.tfn)
- fn := unsafe.Pointer(&tfn)
- m.Func = Value{mt.(*rtype), fn, fl}
-
- m.Index = i
- return m
-}
-
-func (t *rtype) MethodByName(name string) (m Method, ok bool) {
- if t.Kind() == Interface {
- tt := (*interfaceType)(unsafe.Pointer(t))
- return tt.MethodByName(name)
- }
- ut := t.uncommon()
- if ut == nil {
- return Method{}, false
- }
-
- methods := ut.exportedMethods()
-
- // We are looking for the first index i where the string becomes >= s.
- // This is a copy of sort.Search, with f(h) replaced by (t.nameOff(methods[h].name).name() >= name).
- i, j := 0, len(methods)
- for i < j {
- h := int(uint(i+j) >> 1) // avoid overflow when computing h
- // i ≤ h < j
- if !(t.nameOff(methods[h].name).name() >= name) {
- i = h + 1 // preserves f(i-1) == false
- } else {
- j = h // preserves f(j) == true
- }
- }
- // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i.
- if i < len(methods) && name == t.nameOff(methods[i].name).name() {
- return t.Method(i), true
- }
-
- return Method{}, false
-}
-
-func (t *rtype) PkgPath() string {
- if t.tflag&tflagNamed == 0 {
- return ""
- }
- ut := t.uncommon()
- if ut == nil {
- return ""
- }
- return t.nameOff(ut.pkgPath).name()
-}
-
-func (t *rtype) hasName() bool {
- return t.tflag&tflagNamed != 0
-}
-
-func (t *rtype) Name() string {
- if !t.hasName() {
- return ""
- }
- s := t.String()
- i := len(s) - 1
- sqBrackets := 0
- for i >= 0 && (s[i] != '.' || sqBrackets != 0) {
- switch s[i] {
- case ']':
- sqBrackets++
- case '[':
- sqBrackets--
- }
- i--
- }
- return s[i+1:]
-}
-
-func (t *rtype) ChanDir() ChanDir {
- if t.Kind() != Chan {
- panic("reflect: ChanDir of non-chan type " + t.String())
- }
- tt := (*chanType)(unsafe.Pointer(t))
- return ChanDir(tt.dir)
-}
-
-func (t *rtype) IsVariadic() bool {
- if t.Kind() != Func {
- panic("reflect: IsVariadic of non-func type " + t.String())
- }
- tt := (*funcType)(unsafe.Pointer(t))
- return tt.outCount&(1<<15) != 0
-}
-
-func (t *rtype) Elem() Type {
- switch t.Kind() {
- case Array:
- tt := (*arrayType)(unsafe.Pointer(t))
- return toType(tt.elem)
- case Chan:
- tt := (*chanType)(unsafe.Pointer(t))
- return toType(tt.elem)
- case Map:
- tt := (*mapType)(unsafe.Pointer(t))
- return toType(tt.elem)
- case Pointer:
- tt := (*ptrType)(unsafe.Pointer(t))
- return toType(tt.elem)
- case Slice:
- tt := (*sliceType)(unsafe.Pointer(t))
- return toType(tt.elem)
- }
- panic("reflect: Elem of invalid type " + t.String())
-}
-
-func (t *rtype) Field(i int) StructField {
- if t.Kind() != Struct {
- panic("reflect: Field of non-struct type " + t.String())
- }
- tt := (*structType)(unsafe.Pointer(t))
- return tt.Field(i)
-}
-
-func (t *rtype) FieldByIndex(index []int) StructField {
- if t.Kind() != Struct {
- panic("reflect: FieldByIndex of non-struct type " + t.String())
- }
- tt := (*structType)(unsafe.Pointer(t))
- return tt.FieldByIndex(index)
-}
-
-func (t *rtype) FieldByName(name string) (StructField, bool) {
- if t.Kind() != Struct {
- panic("reflect: FieldByName of non-struct type " + t.String())
- }
- tt := (*structType)(unsafe.Pointer(t))
- return tt.FieldByName(name)
-}
-
-func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) {
- if t.Kind() != Struct {
- panic("reflect: FieldByNameFunc of non-struct type " + t.String())
- }
- tt := (*structType)(unsafe.Pointer(t))
- return tt.FieldByNameFunc(match)
-}
-
-func (t *rtype) In(i int) Type {
- if t.Kind() != Func {
- panic("reflect: In of non-func type " + t.String())
- }
- tt := (*funcType)(unsafe.Pointer(t))
- return toType(tt.in()[i])
-}
-
-func (t *rtype) Key() Type {
- if t.Kind() != Map {
- panic("reflect: Key of non-map type " + t.String())
- }
- tt := (*mapType)(unsafe.Pointer(t))
- return toType(tt.key)
-}
-
-func (t *rtype) Len() int {
- if t.Kind() != Array {
- panic("reflect: Len of non-array type " + t.String())
- }
- tt := (*arrayType)(unsafe.Pointer(t))
- return int(tt.len)
-}
-
-func (t *rtype) NumField() int {
- if t.Kind() != Struct {
- panic("reflect: NumField of non-struct type " + t.String())
- }
- tt := (*structType)(unsafe.Pointer(t))
- return len(tt.fields)
-}
-
-func (t *rtype) NumIn() int {
- if t.Kind() != Func {
- panic("reflect: NumIn of non-func type " + t.String())
- }
- tt := (*funcType)(unsafe.Pointer(t))
- return int(tt.inCount)
-}
-
-func (t *rtype) NumOut() int {
- if t.Kind() != Func {
- panic("reflect: NumOut of non-func type " + t.String())
- }
- tt := (*funcType)(unsafe.Pointer(t))
- return len(tt.out())
-}
-
-func (t *rtype) Out(i int) Type {
- if t.Kind() != Func {
- panic("reflect: Out of non-func type " + t.String())
- }
- tt := (*funcType)(unsafe.Pointer(t))
- return toType(tt.out()[i])
-}
-
-func (t *funcType) in() []*rtype {
- uadd := unsafe.Sizeof(*t)
- if t.tflag&tflagUncommon != 0 {
- uadd += unsafe.Sizeof(uncommonType{})
- }
- if t.inCount == 0 {
- return nil
- }
- return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.inCount:t.inCount]
-}
-
-func (t *funcType) out() []*rtype {
- uadd := unsafe.Sizeof(*t)
- if t.tflag&tflagUncommon != 0 {
- uadd += unsafe.Sizeof(uncommonType{})
- }
- outCount := t.outCount & (1<<15 - 1)
- if outCount == 0 {
- return nil
- }
- return (*[1 << 20]*rtype)(add(unsafe.Pointer(t), uadd, "outCount > 0"))[t.inCount : t.inCount+outCount : t.inCount+outCount]
-}
-
-// add returns p+x.
-//
-// The whySafe string is ignored, so that the function still inlines
-// as efficiently as p+x, but all call sites should use the string to
-// record why the addition is safe, which is to say why the addition
-// does not cause x to advance to the very end of p's allocation
-// and therefore point incorrectly at the next block in memory.
-func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
- return unsafe.Pointer(uintptr(p) + x)
-}
-
-func (d ChanDir) String() string {
- switch d {
- case SendDir:
- return "chan<-"
- case RecvDir:
- return "<-chan"
- case BothDir:
- return "chan"
- }
- return "ChanDir" + strconv.Itoa(int(d))
-}
-
-// Method returns the i'th method in the type's method set.
-func (t *interfaceType) Method(i int) (m Method) {
- if i < 0 || i >= len(t.methods) {
- return
- }
- p := &t.methods[i]
- pname := t.nameOff(p.name)
- m.Name = pname.name()
- if !pname.isExported() {
- m.PkgPath = pname.pkgPath()
- if m.PkgPath == "" {
- m.PkgPath = t.pkgPath.name()
- }
- }
- m.Type = toType(t.typeOff(p.typ))
- m.Index = i
- return
-}
-
-// NumMethod returns the number of interface methods in the type's method set.
-func (t *interfaceType) NumMethod() int { return len(t.methods) }
-
-// MethodByName method with the given name in the type's method set.
-func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
- if t == nil {
- return
- }
- var p *imethod
- for i := range t.methods {
- p = &t.methods[i]
- if t.nameOff(p.name).name() == name {
- return t.Method(i), true
- }
- }
- return
-}
-
-// A StructField describes a single field in a struct.
-type StructField struct {
- // Name is the field name.
- Name string
-
- // PkgPath is the package path that qualifies a lower case (unexported)
- // field name. It is empty for upper case (exported) field names.
- // See https://golang.org/ref/spec#Uniqueness_of_identifiers
- PkgPath string
-
- Type Type // field type
- Tag StructTag // field tag string
- Offset uintptr // offset within struct, in bytes
- Index []int // index sequence for Type.FieldByIndex
- Anonymous bool // is an embedded field
-}
-
-// IsExported reports whether the field is exported.
-func (f StructField) IsExported() bool {
- return f.PkgPath == ""
-}
-
-// A StructTag is the tag string in a struct field.
-//
-// By convention, tag strings are a concatenation of
-// optionally space-separated key:"value" pairs.
-// Each key is a non-empty string consisting of non-control
-// characters other than space (U+0020 ' '), quote (U+0022 '"'),
-// and colon (U+003A ':'). Each value is quoted using U+0022 '"'
-// characters and Go string literal syntax.
-type StructTag string
-
-// Get returns the value associated with key in the tag string.
-// If there is no such key in the tag, Get returns the empty string.
-// If the tag does not have the conventional format, the value
-// returned by Get is unspecified. To determine whether a tag is
-// explicitly set to the empty string, use Lookup.
-func (tag StructTag) Get(key string) string {
- v, _ := tag.Lookup(key)
- return v
-}
-
-// Lookup returns the value associated with key in the tag string.
-// If the key is present in the tag the value (which may be empty)
-// is returned. Otherwise the returned value will be the empty string.
-// The ok return value reports whether the value was explicitly set in
-// the tag string. If the tag does not have the conventional format,
-// the value returned by Lookup is unspecified.
-func (tag StructTag) Lookup(key string) (value string, ok bool) {
- // When modifying this code, also update the validateStructTag code
- // in cmd/vet/structtag.go.
-
- for tag != "" {
- // Skip leading space.
- i := 0
- for i < len(tag) && tag[i] == ' ' {
- i++
- }
- tag = tag[i:]
- if tag == "" {
- break
- }
-
- // Scan to colon. A space, a quote or a control character is a syntax error.
- // Strictly speaking, control chars include the range [0x7f, 0x9f], not just
- // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
- // as it is simpler to inspect the tag's bytes than the tag's runes.
- i = 0
- for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
- i++
- }
- if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
- break
- }
- name := string(tag[:i])
- tag = tag[i+1:]
-
- // Scan quoted string to find value.
- i = 1
- for i < len(tag) && tag[i] != '"' {
- if tag[i] == '\\' {
- i++
- }
- i++
- }
- if i >= len(tag) {
- break
- }
- qvalue := string(tag[:i+1])
- tag = tag[i+1:]
-
- if key == name {
- value, err := strconv.Unquote(qvalue)
- if err != nil {
- break
- }
- return value, true
- }
- }
- return "", false
-}
-
-// Field returns the i'th struct field.
-func (t *structType) Field(i int) (f StructField) {
- if i < 0 || i >= len(t.fields) {
- panic("reflect: Field index out of bounds")
- }
- p := &t.fields[i]
- f.Type = toType(p.typ)
- f.Name = p.name.name()
- f.Anonymous = p.embedded()
- if !p.name.isExported() {
- f.PkgPath = t.pkgPath.name()
- }
- if tag := p.name.tag(); tag != "" {
- f.Tag = StructTag(tag)
- }
- f.Offset = p.offset
-
- // NOTE(rsc): This is the only allocation in the interface
- // presented by a reflect.Type. It would be nice to avoid,
- // at least in the common cases, but we need to make sure
- // that misbehaving clients of reflect cannot affect other
- // uses of reflect. One possibility is CL 5371098, but we
- // postponed that ugliness until there is a demonstrated
- // need for the performance. This is issue 2320.
- f.Index = []int{i}
- return
-}
-
-// TODO(gri): Should there be an error/bool indicator if the index
-// is wrong for FieldByIndex?
-
-// FieldByIndex returns the nested field corresponding to index.
-func (t *structType) FieldByIndex(index []int) (f StructField) {
- f.Type = toType(&t.rtype)
- for i, x := range index {
- if i > 0 {
- ft := f.Type
- if ft.Kind() == Pointer && ft.Elem().Kind() == Struct {
- ft = ft.Elem()
- }
- f.Type = ft
- }
- f = f.Type.Field(x)
- }
- return
-}
-
-// A fieldScan represents an item on the fieldByNameFunc scan work list.
-type fieldScan struct {
- typ *structType
- index []int
-}
-
-// FieldByNameFunc returns the struct field with a name that satisfies the
-// match function and a boolean to indicate if the field was found.
-func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) {
- // This uses the same condition that the Go language does: there must be a unique instance
- // of the match at a given depth level. If there are multiple instances of a match at the
- // same depth, they annihilate each other and inhibit any possible match at a lower level.
- // The algorithm is breadth first search, one depth level at a time.
-
- // The current and next slices are work queues:
- // current lists the fields to visit on this depth level,
- // and next lists the fields on the next lower level.
- current := []fieldScan{}
- next := []fieldScan{{typ: t}}
-
- // nextCount records the number of times an embedded type has been
- // encountered and considered for queueing in the 'next' slice.
- // We only queue the first one, but we increment the count on each.
- // If a struct type T can be reached more than once at a given depth level,
- // then it annihilates itself and need not be considered at all when we
- // process that next depth level.
- var nextCount map[*structType]int
-
- // visited records the structs that have been considered already.
- // Embedded pointer fields can create cycles in the graph of
- // reachable embedded types; visited avoids following those cycles.
- // It also avoids duplicated effort: if we didn't find the field in an
- // embedded type T at level 2, we won't find it in one at level 4 either.
- visited := map[*structType]bool{}
-
- for len(next) > 0 {
- current, next = next, current[:0]
- count := nextCount
- nextCount = nil
-
- // Process all the fields at this depth, now listed in 'current'.
- // The loop queues embedded fields found in 'next', for processing during the next
- // iteration. The multiplicity of the 'current' field counts is recorded
- // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'.
- for _, scan := range current {
- t := scan.typ
- if visited[t] {
- // We've looked through this type before, at a higher level.
- // That higher level would shadow the lower level we're now at,
- // so this one can't be useful to us. Ignore it.
- continue
- }
- visited[t] = true
- for i := range t.fields {
- f := &t.fields[i]
- // Find name and (for embedded field) type for field f.
- fname := f.name.name()
- var ntyp *rtype
- if f.embedded() {
- // Embedded field of type T or *T.
- ntyp = f.typ
- if ntyp.Kind() == Pointer {
- ntyp = ntyp.Elem().common()
- }
- }
-
- // Does it match?
- if match(fname) {
- // Potential match
- if count[t] > 1 || ok {
- // Name appeared multiple times at this level: annihilate.
- return StructField{}, false
- }
- result = t.Field(i)
- result.Index = nil
- result.Index = append(result.Index, scan.index...)
- result.Index = append(result.Index, i)
- ok = true
- continue
- }
-
- // Queue embedded struct fields for processing with next level,
- // but only if we haven't seen a match yet at this level and only
- // if the embedded types haven't already been queued.
- if ok || ntyp == nil || ntyp.Kind() != Struct {
- continue
- }
- styp := (*structType)(unsafe.Pointer(ntyp))
- if nextCount[styp] > 0 {
- nextCount[styp] = 2 // exact multiple doesn't matter
- continue
- }
- if nextCount == nil {
- nextCount = map[*structType]int{}
- }
- nextCount[styp] = 1
- if count[t] > 1 {
- nextCount[styp] = 2 // exact multiple doesn't matter
- }
- var index []int
- index = append(index, scan.index...)
- index = append(index, i)
- next = append(next, fieldScan{styp, index})
- }
- }
- if ok {
- break
- }
- }
- return
-}
-
-// FieldByName returns the struct field with the given name
-// and a boolean to indicate if the field was found.
-func (t *structType) FieldByName(name string) (f StructField, present bool) {
- // Quick check for top-level name, or struct without embedded fields.
- hasEmbeds := false
- if name != "" {
- for i := range t.fields {
- tf := &t.fields[i]
- if tf.name.name() == name {
- return t.Field(i), true
- }
- if tf.embedded() {
- hasEmbeds = true
- }
- }
- }
- if !hasEmbeds {
- return
- }
- return t.FieldByNameFunc(func(s string) bool { return s == name })
-}
-
-// TypeOf returns the reflection Type that represents the dynamic type of i.
-// If i is a nil interface value, TypeOf returns nil.
-func TypeOf(i any) Type {
- eface := *(*emptyInterface)(unsafe.Pointer(&i))
- return toType(eface.typ)
-}
-
-// rtypeOf directly extracts the *rtype of the provided value.
-func rtypeOf(i any) *rtype {
- eface := *(*emptyInterface)(unsafe.Pointer(&i))
- return eface.typ
-}
-
-// ptrMap is the cache for PointerTo.
-var ptrMap sync.Map // map[*rtype]*ptrType
-
-// PtrTo returns the pointer type with element t.
-// For example, if t represents type Foo, PtrTo(t) represents *Foo.
-//
-// PtrTo is the old spelling of PointerTo.
-// The two functions behave identically.
-func PtrTo(t Type) Type { return PointerTo(t) }
-
-// PointerTo returns the pointer type with element t.
-// For example, if t represents type Foo, PointerTo(t) represents *Foo.
-func PointerTo(t Type) Type {
- return t.(*rtype).ptrTo()
-}
-
-func (t *rtype) ptrTo() *rtype {
- if t.ptrToThis != 0 {
- return t.typeOff(t.ptrToThis)
- }
-
- // Check the cache.
- if pi, ok := ptrMap.Load(t); ok {
- return &pi.(*ptrType).rtype
- }
-
- // Look in known types.
- s := "*" + t.String()
- for _, tt := range typesByString(s) {
- p := (*ptrType)(unsafe.Pointer(tt))
- if p.elem != t {
- continue
- }
- pi, _ := ptrMap.LoadOrStore(t, p)
- return &pi.(*ptrType).rtype
- }
-
- // Create a new ptrType starting with the description
- // of an *unsafe.Pointer.
- var iptr any = (*unsafe.Pointer)(nil)
- prototype := *(**ptrType)(unsafe.Pointer(&iptr))
- pp := *prototype
-
- pp.str = resolveReflectName(newName(s, "", false, false))
- pp.ptrToThis = 0
-
- // For the type structures linked into the binary, the
- // compiler provides a good hash of the string.
- // Create a good hash for the new string by using
- // the FNV-1 hash's mixing function to combine the
- // old hash and the new "*".
- pp.hash = fnv1(t.hash, '*')
-
- pp.elem = t
-
- pi, _ := ptrMap.LoadOrStore(t, &pp)
- return &pi.(*ptrType).rtype
-}
-
-// fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function.
-func fnv1(x uint32, list ...byte) uint32 {
- for _, b := range list {
- x = x*16777619 ^ uint32(b)
- }
- return x
-}
-
-func (t *rtype) Implements(u Type) bool {
- if u == nil {
- panic("reflect: nil type passed to Type.Implements")
- }
- if u.Kind() != Interface {
- panic("reflect: non-interface type passed to Type.Implements")
- }
- return implements(u.(*rtype), t)
-}
-
-func (t *rtype) AssignableTo(u Type) bool {
- if u == nil {
- panic("reflect: nil type passed to Type.AssignableTo")
- }
- uu := u.(*rtype)
- return directlyAssignable(uu, t) || implements(uu, t)
-}
-
-func (t *rtype) ConvertibleTo(u Type) bool {
- if u == nil {
- panic("reflect: nil type passed to Type.ConvertibleTo")
- }
- uu := u.(*rtype)
- return convertOp(uu, t) != nil
-}
-
-func (t *rtype) Comparable() bool {
- return t.equal != nil
-}
-
-// implements reports whether the type V implements the interface type T.
-func implements(T, V *rtype) bool {
- if T.Kind() != Interface {
- return false
- }
- t := (*interfaceType)(unsafe.Pointer(T))
- if len(t.methods) == 0 {
- return true
- }
-
- // The same algorithm applies in both cases, but the
- // method tables for an interface type and a concrete type
- // are different, so the code is duplicated.
- // In both cases the algorithm is a linear scan over the two
- // lists - T's methods and V's methods - simultaneously.
- // Since method tables are stored in a unique sorted order
- // (alphabetical, with no duplicate method names), the scan
- // through V's methods must hit a match for each of T's
- // methods along the way, or else V does not implement T.
- // This lets us run the scan in overall linear time instead of
- // the quadratic time a naive search would require.
- // See also ../runtime/iface.go.
- if V.Kind() == Interface {
- v := (*interfaceType)(unsafe.Pointer(V))
- i := 0
- for j := 0; j < len(v.methods); j++ {
- tm := &t.methods[i]
- tmName := t.nameOff(tm.name)
- vm := &v.methods[j]
- vmName := V.nameOff(vm.name)
- if vmName.name() == tmName.name() && V.typeOff(vm.typ) == t.typeOff(tm.typ) {
- if !tmName.isExported() {
- tmPkgPath := tmName.pkgPath()
- if tmPkgPath == "" {
- tmPkgPath = t.pkgPath.name()
- }
- vmPkgPath := vmName.pkgPath()
- if vmPkgPath == "" {
- vmPkgPath = v.pkgPath.name()
- }
- if tmPkgPath != vmPkgPath {
- continue
- }
- }
- if i++; i >= len(t.methods) {
- return true
- }
- }
- }
- return false
- }
-
- v := V.uncommon()
- if v == nil {
- return false
- }
- i := 0
- vmethods := v.methods()
- for j := 0; j < int(v.mcount); j++ {
- tm := &t.methods[i]
- tmName := t.nameOff(tm.name)
- vm := vmethods[j]
- vmName := V.nameOff(vm.name)
- if vmName.name() == tmName.name() && V.typeOff(vm.mtyp) == t.typeOff(tm.typ) {
- if !tmName.isExported() {
- tmPkgPath := tmName.pkgPath()
- if tmPkgPath == "" {
- tmPkgPath = t.pkgPath.name()
- }
- vmPkgPath := vmName.pkgPath()
- if vmPkgPath == "" {
- vmPkgPath = V.nameOff(v.pkgPath).name()
- }
- if tmPkgPath != vmPkgPath {
- continue
- }
- }
- if i++; i >= len(t.methods) {
- return true
- }
- }
- }
- return false
-}
-
-// specialChannelAssignability reports whether a value x of channel type V
-// can be directly assigned (using memmove) to another channel type T.
-// https://golang.org/doc/go_spec.html#Assignability
-// T and V must be both of Chan kind.
-func specialChannelAssignability(T, V *rtype) bool {
- // Special case:
- // x is a bidirectional channel value, T is a channel type,
- // x's type V and T have identical element types,
- // and at least one of V or T is not a defined type.
- return V.ChanDir() == BothDir && (T.Name() == "" || V.Name() == "") && haveIdenticalType(T.Elem(), V.Elem(), true)
-}
-
-// directlyAssignable reports whether a value x of type V can be directly
-// assigned (using memmove) to a value of type T.
-// https://golang.org/doc/go_spec.html#Assignability
-// Ignoring the interface rules (implemented elsewhere)
-// and the ideal constant rules (no ideal constants at run time).
-func directlyAssignable(T, V *rtype) bool {
- // x's type V is identical to T?
- if T == V {
- return true
- }
-
- // Otherwise at least one of T and V must not be defined
- // and they must have the same kind.
- if T.hasName() && V.hasName() || T.Kind() != V.Kind() {
- return false
- }
-
- if T.Kind() == Chan && specialChannelAssignability(T, V) {
- return true
- }
-
- // x's type T and V must have identical underlying types.
- return haveIdenticalUnderlyingType(T, V, true)
-}
-
-func haveIdenticalType(T, V Type, cmpTags bool) bool {
- if cmpTags {
- return T == V
- }
-
- if T.Name() != V.Name() || T.Kind() != V.Kind() || T.PkgPath() != V.PkgPath() {
- return false
- }
-
- return haveIdenticalUnderlyingType(T.common(), V.common(), false)
-}
-
-func haveIdenticalUnderlyingType(T, V *rtype, cmpTags bool) bool {
- if T == V {
- return true
- }
-
- kind := T.Kind()
- if kind != V.Kind() {
- return false
- }
-
- // Non-composite types of equal kind have same underlying type
- // (the predefined instance of the type).
- if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
- return true
- }
-
- // Composite types.
- switch kind {
- case Array:
- return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
-
- case Chan:
- return V.ChanDir() == T.ChanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
-
- case Func:
- t := (*funcType)(unsafe.Pointer(T))
- v := (*funcType)(unsafe.Pointer(V))
- if t.outCount != v.outCount || t.inCount != v.inCount {
- return false
- }
- for i := 0; i < t.NumIn(); i++ {
- if !haveIdenticalType(t.In(i), v.In(i), cmpTags) {
- return false
- }
- }
- for i := 0; i < t.NumOut(); i++ {
- if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) {
- return false
- }
- }
- return true
-
- case Interface:
- t := (*interfaceType)(unsafe.Pointer(T))
- v := (*interfaceType)(unsafe.Pointer(V))
- if len(t.methods) == 0 && len(v.methods) == 0 {
- return true
- }
- // Might have the same methods but still
- // need a run time conversion.
- return false
-
- case Map:
- return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
-
- case Pointer, Slice:
- return haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
-
- case Struct:
- t := (*structType)(unsafe.Pointer(T))
- v := (*structType)(unsafe.Pointer(V))
- if len(t.fields) != len(v.fields) {
- return false
- }
- if t.pkgPath.name() != v.pkgPath.name() {
- return false
- }
- for i := range t.fields {
- tf := &t.fields[i]
- vf := &v.fields[i]
- if tf.name.name() != vf.name.name() {
- return false
- }
- if !haveIdenticalType(tf.typ, vf.typ, cmpTags) {
- return false
- }
- if cmpTags && tf.name.tag() != vf.name.tag() {
- return false
- }
- if tf.offset != vf.offset {
- return false
- }
- if tf.embedded() != vf.embedded() {
- return false
- }
- }
- return true
- }
-
- return false
-}
-
-// typelinks is implemented in package runtime.
-// It returns a slice of the sections in each module,
-// and a slice of *rtype offsets in each module.
-//
-// The types in each module are sorted by string. That is, the first
-// two linked types of the first module are:
-//
-// d0 := sections[0]
-// t1 := (*rtype)(add(d0, offset[0][0]))
-// t2 := (*rtype)(add(d0, offset[0][1]))
-//
-// and
-//
-// t1.String() < t2.String()
-//
-// Note that strings are not unique identifiers for types:
-// there can be more than one with a given string.
-// Only types we might want to look up are included:
-// pointers, channels, maps, slices, and arrays.
-func typelinks() (sections []unsafe.Pointer, offset [][]int32)
-
-func rtypeOff(section unsafe.Pointer, off int32) *rtype {
- return (*rtype)(add(section, uintptr(off), "sizeof(rtype) > 0"))
-}
-
-// typesByString returns the subslice of typelinks() whose elements have
-// the given string representation.
-// It may be empty (no known types with that string) or may have
-// multiple elements (multiple types with that string).
-func typesByString(s string) []*rtype {
- sections, offset := typelinks()
- var ret []*rtype
-
- for offsI, offs := range offset {
- section := sections[offsI]
-
- // We are looking for the first index i where the string becomes >= s.
- // This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s).
- i, j := 0, len(offs)
- for i < j {
- h := i + (j-i)>>1 // avoid overflow when computing h
- // i ≤ h < j
- if !(rtypeOff(section, offs[h]).String() >= s) {
- i = h + 1 // preserves f(i-1) == false
- } else {
- j = h // preserves f(j) == true
- }
- }
- // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i.
-
- // Having found the first, linear scan forward to find the last.
- // We could do a second binary search, but the caller is going
- // to do a linear scan anyway.
- for j := i; j < len(offs); j++ {
- typ := rtypeOff(section, offs[j])
- if typ.String() != s {
- break
- }
- ret = append(ret, typ)
- }
- }
- return ret
-}
-
-// The lookupCache caches ArrayOf, ChanOf, MapOf and SliceOf lookups.
-var lookupCache sync.Map // map[cacheKey]*rtype
-
-// A cacheKey is the key for use in the lookupCache.
-// Four values describe any of the types we are looking for:
-// type kind, one or two subtypes, and an extra integer.
-type cacheKey struct {
- kind Kind
- t1 *rtype
- t2 *rtype
- extra uintptr
-}
-
-// The funcLookupCache caches FuncOf lookups.
-// FuncOf does not share the common lookupCache since cacheKey is not
-// sufficient to represent functions unambiguously.
-var funcLookupCache struct {
- sync.Mutex // Guards stores (but not loads) on m.
-
- // m is a map[uint32][]*rtype keyed by the hash calculated in FuncOf.
- // Elements of m are append-only and thus safe for concurrent reading.
- m sync.Map
-}
-
-// ChanOf returns the channel type with the given direction and element type.
-// For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int.
-//
-// The gc runtime imposes a limit of 64 kB on channel element types.
-// If t's size is equal to or exceeds this limit, ChanOf panics.
-func ChanOf(dir ChanDir, t Type) Type {
- typ := t.(*rtype)
-
- // Look in cache.
- ckey := cacheKey{Chan, typ, nil, uintptr(dir)}
- if ch, ok := lookupCache.Load(ckey); ok {
- return ch.(*rtype)
- }
-
- // This restriction is imposed by the gc compiler and the runtime.
- if typ.size >= 1<<16 {
- panic("reflect.ChanOf: element size too large")
- }
-
- // Look in known types.
- var s string
- switch dir {
- default:
- panic("reflect.ChanOf: invalid dir")
- case SendDir:
- s = "chan<- " + typ.String()
- case RecvDir:
- s = "<-chan " + typ.String()
- case BothDir:
- typeStr := typ.String()
- if typeStr[0] == '<' {
- // typ is recv chan, need parentheses as "<-" associates with leftmost
- // chan possible, see:
- // * https://golang.org/ref/spec#Channel_types
- // * https://github.com/golang/go/issues/39897
- s = "chan (" + typeStr + ")"
- } else {
- s = "chan " + typeStr
- }
- }
- for _, tt := range typesByString(s) {
- ch := (*chanType)(unsafe.Pointer(tt))
- if ch.elem == typ && ch.dir == uintptr(dir) {
- ti, _ := lookupCache.LoadOrStore(ckey, tt)
- return ti.(Type)
- }
- }
-
- // Make a channel type.
- var ichan any = (chan unsafe.Pointer)(nil)
- prototype := *(**chanType)(unsafe.Pointer(&ichan))
- ch := *prototype
- ch.tflag = tflagRegularMemory
- ch.dir = uintptr(dir)
- ch.str = resolveReflectName(newName(s, "", false, false))
- ch.hash = fnv1(typ.hash, 'c', byte(dir))
- ch.elem = typ
-
- ti, _ := lookupCache.LoadOrStore(ckey, &ch.rtype)
- return ti.(Type)
-}
-
-// MapOf returns the map type with the given key and element types.
-// For example, if k represents int and e represents string,
-// MapOf(k, e) represents map[int]string.
-//
-// If the key type is not a valid map key type (that is, if it does
-// not implement Go's == operator), MapOf panics.
-func MapOf(key, elem Type) Type {
- ktyp := key.(*rtype)
- etyp := elem.(*rtype)
-
- if ktyp.equal == nil {
- panic("reflect.MapOf: invalid key type " + ktyp.String())
- }
-
- // Look in cache.
- ckey := cacheKey{Map, ktyp, etyp, 0}
- if mt, ok := lookupCache.Load(ckey); ok {
- return mt.(Type)
- }
-
- // Look in known types.
- s := "map[" + ktyp.String() + "]" + etyp.String()
- for _, tt := range typesByString(s) {
- mt := (*mapType)(unsafe.Pointer(tt))
- if mt.key == ktyp && mt.elem == etyp {
- ti, _ := lookupCache.LoadOrStore(ckey, tt)
- return ti.(Type)
- }
- }
-
- // Make a map type.
- // Note: flag values must match those used in the TMAP case
- // in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
- var imap any = (map[unsafe.Pointer]unsafe.Pointer)(nil)
- mt := **(**mapType)(unsafe.Pointer(&imap))
- mt.str = resolveReflectName(newName(s, "", false, false))
- mt.tflag = 0
- mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
- mt.key = ktyp
- mt.elem = etyp
- mt.bucket = bucketOf(ktyp, etyp)
- mt.hasher = func(p unsafe.Pointer, seed uintptr) uintptr {
- return typehash(ktyp, p, seed)
- }
- mt.flags = 0
- if ktyp.size > maxKeySize {
- mt.keysize = uint8(goarch.PtrSize)
- mt.flags |= 1 // indirect key
- } else {
- mt.keysize = uint8(ktyp.size)
- }
- if etyp.size > maxValSize {
- mt.valuesize = uint8(goarch.PtrSize)
- mt.flags |= 2 // indirect value
- } else {
- mt.valuesize = uint8(etyp.size)
- }
- mt.bucketsize = uint16(mt.bucket.size)
- if isReflexive(ktyp) {
- mt.flags |= 4
- }
- if needKeyUpdate(ktyp) {
- mt.flags |= 8
- }
- if hashMightPanic(ktyp) {
- mt.flags |= 16
- }
- mt.ptrToThis = 0
-
- ti, _ := lookupCache.LoadOrStore(ckey, &mt.rtype)
- return ti.(Type)
-}
-
-var funcTypes []Type
-var funcTypesMutex sync.Mutex
-
-func initFuncTypes(n int) Type {
- funcTypesMutex.Lock()
- defer funcTypesMutex.Unlock()
- if n >= len(funcTypes) {
- newFuncTypes := make([]Type, n+1)
- copy(newFuncTypes, funcTypes)
- funcTypes = newFuncTypes
- }
- if funcTypes[n] != nil {
- return funcTypes[n]
- }
-
- funcTypes[n] = StructOf([]StructField{
- {
- Name: "FuncType",
- Type: TypeOf(funcType{}),
- },
- {
- Name: "Args",
- Type: ArrayOf(n, TypeOf(&rtype{})),
- },
- })
- return funcTypes[n]
-}
-
-// FuncOf returns the function type with the given argument and result types.
-// For example if k represents int and e represents string,
-// FuncOf([]Type{k}, []Type{e}, false) represents func(int) string.
-//
-// The variadic argument controls whether the function is variadic. FuncOf
-// panics if the in[len(in)-1] does not represent a slice and variadic is
-// true.
-func FuncOf(in, out []Type, variadic bool) Type {
- if variadic && (len(in) == 0 || in[len(in)-1].Kind() != Slice) {
- panic("reflect.FuncOf: last arg of variadic func must be slice")
- }
-
- // Make a func type.
- var ifunc any = (func())(nil)
- prototype := *(**funcType)(unsafe.Pointer(&ifunc))
- n := len(in) + len(out)
-
- if n > 128 {
- panic("reflect.FuncOf: too many arguments")
- }
-
- o := New(initFuncTypes(n)).Elem()
- ft := (*funcType)(unsafe.Pointer(o.Field(0).Addr().Pointer()))
- args := unsafe.Slice((**rtype)(unsafe.Pointer(o.Field(1).Addr().Pointer())), n)[0:0:n]
- *ft = *prototype
-
- // Build a hash and minimally populate ft.
- var hash uint32
- for _, in := range in {
- t := in.(*rtype)
- args = append(args, t)
- hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash))
- }
- if variadic {
- hash = fnv1(hash, 'v')
- }
- hash = fnv1(hash, '.')
- for _, out := range out {
- t := out.(*rtype)
- args = append(args, t)
- hash = fnv1(hash, byte(t.hash>>24), byte(t.hash>>16), byte(t.hash>>8), byte(t.hash))
- }
-
- ft.tflag = 0
- ft.hash = hash
- ft.inCount = uint16(len(in))
- ft.outCount = uint16(len(out))
- if variadic {
- ft.outCount |= 1 << 15
- }
-
- // Look in cache.
- if ts, ok := funcLookupCache.m.Load(hash); ok {
- for _, t := range ts.([]*rtype) {
- if haveIdenticalUnderlyingType(&ft.rtype, t, true) {
- return t
- }
- }
- }
-
- // Not in cache, lock and retry.
- funcLookupCache.Lock()
- defer funcLookupCache.Unlock()
- if ts, ok := funcLookupCache.m.Load(hash); ok {
- for _, t := range ts.([]*rtype) {
- if haveIdenticalUnderlyingType(&ft.rtype, t, true) {
- return t
- }
- }
- }
-
- addToCache := func(tt *rtype) Type {
- var rts []*rtype
- if rti, ok := funcLookupCache.m.Load(hash); ok {
- rts = rti.([]*rtype)
- }
- funcLookupCache.m.Store(hash, append(rts, tt))
- return tt
- }
-
- // Look in known types for the same string representation.
- str := funcStr(ft)
- for _, tt := range typesByString(str) {
- if haveIdenticalUnderlyingType(&ft.rtype, tt, true) {
- return addToCache(tt)
- }
- }
-
- // Populate the remaining fields of ft and store in cache.
- ft.str = resolveReflectName(newName(str, "", false, false))
- ft.ptrToThis = 0
- return addToCache(&ft.rtype)
-}
-
-// funcStr builds a string representation of a funcType.
-func funcStr(ft *funcType) string {
- repr := make([]byte, 0, 64)
- repr = append(repr, "func("...)
- for i, t := range ft.in() {
- if i > 0 {
- repr = append(repr, ", "...)
- }
- if ft.IsVariadic() && i == int(ft.inCount)-1 {
- repr = append(repr, "..."...)
- repr = append(repr, (*sliceType)(unsafe.Pointer(t)).elem.String()...)
- } else {
- repr = append(repr, t.String()...)
- }
- }
- repr = append(repr, ')')
- out := ft.out()
- if len(out) == 1 {
- repr = append(repr, ' ')
- } else if len(out) > 1 {
- repr = append(repr, " ("...)
- }
- for i, t := range out {
- if i > 0 {
- repr = append(repr, ", "...)
- }
- repr = append(repr, t.String()...)
- }
- if len(out) > 1 {
- repr = append(repr, ')')
- }
- return string(repr)
-}
-
-// isReflexive reports whether the == operation on the type is reflexive.
-// That is, x == x for all values x of type t.
-func isReflexive(t *rtype) bool {
- switch t.Kind() {
- case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Pointer, String, UnsafePointer:
- return true
- case Float32, Float64, Complex64, Complex128, Interface:
- return false
- case Array:
- tt := (*arrayType)(unsafe.Pointer(t))
- return isReflexive(tt.elem)
- case Struct:
- tt := (*structType)(unsafe.Pointer(t))
- for _, f := range tt.fields {
- if !isReflexive(f.typ) {
- return false
- }
- }
- return true
- default:
- // Func, Map, Slice, Invalid
- panic("isReflexive called on non-key type " + t.String())
- }
-}
-
-// needKeyUpdate reports whether map overwrites require the key to be copied.
-func needKeyUpdate(t *rtype) bool {
- switch t.Kind() {
- case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Pointer, UnsafePointer:
- return false
- case Float32, Float64, Complex64, Complex128, Interface, String:
- // Float keys can be updated from +0 to -0.
- // String keys can be updated to use a smaller backing store.
- // Interfaces might have floats of strings in them.
- return true
- case Array:
- tt := (*arrayType)(unsafe.Pointer(t))
- return needKeyUpdate(tt.elem)
- case Struct:
- tt := (*structType)(unsafe.Pointer(t))
- for _, f := range tt.fields {
- if needKeyUpdate(f.typ) {
- return true
- }
- }
- return false
- default:
- // Func, Map, Slice, Invalid
- panic("needKeyUpdate called on non-key type " + t.String())
- }
-}
-
-// hashMightPanic reports whether the hash of a map key of type t might panic.
-func hashMightPanic(t *rtype) bool {
- switch t.Kind() {
- case Interface:
- return true
- case Array:
- tt := (*arrayType)(unsafe.Pointer(t))
- return hashMightPanic(tt.elem)
- case Struct:
- tt := (*structType)(unsafe.Pointer(t))
- for _, f := range tt.fields {
- if hashMightPanic(f.typ) {
- return true
- }
- }
- return false
- default:
- return false
- }
-}
-
-// Make sure these routines stay in sync with ../runtime/map.go!
-// These types exist only for GC, so we only fill out GC relevant info.
-// Currently, that's just size and the GC program. We also fill in string
-// for possible debugging use.
-const (
- bucketSize uintptr = 8
- maxKeySize uintptr = 128
- maxValSize uintptr = 128
-)
-
-func bucketOf(ktyp, etyp *rtype) *rtype {
- if ktyp.size > maxKeySize {
- ktyp = PointerTo(ktyp).(*rtype)
- }
- if etyp.size > maxValSize {
- etyp = PointerTo(etyp).(*rtype)
- }
-
- // Prepare GC data if any.
- // A bucket is at most bucketSize*(1+maxKeySize+maxValSize)+ptrSize bytes,
- // or 2064 bytes, or 258 pointer-size words, or 33 bytes of pointer bitmap.
- // Note that since the key and value are known to be <= 128 bytes,
- // they're guaranteed to have bitmaps instead of GC programs.
- var gcdata *byte
- var ptrdata uintptr
-
- size := bucketSize*(1+ktyp.size+etyp.size) + goarch.PtrSize
- if size&uintptr(ktyp.align-1) != 0 || size&uintptr(etyp.align-1) != 0 {
- panic("reflect: bad size computation in MapOf")
- }
-
- if ktyp.ptrdata != 0 || etyp.ptrdata != 0 {
- nptr := (bucketSize*(1+ktyp.size+etyp.size) + goarch.PtrSize) / goarch.PtrSize
- n := (nptr + 7) / 8
- // Runtime needs pointer masks to be a multiple of uintptr in size.
- n = (n + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1)
- mask := make([]byte, n)
- base := bucketSize / goarch.PtrSize
-
- if ktyp.ptrdata != 0 {
- emitGCMask(mask, base, ktyp, bucketSize)
- }
- base += bucketSize * ktyp.size / goarch.PtrSize
-
- if etyp.ptrdata != 0 {
- emitGCMask(mask, base, etyp, bucketSize)
- }
- base += bucketSize * etyp.size / goarch.PtrSize
-
- word := base
- mask[word/8] |= 1 << (word % 8)
- gcdata = &mask[0]
- ptrdata = (word + 1) * goarch.PtrSize
-
- // overflow word must be last
- if ptrdata != size {
- panic("reflect: bad layout computation in MapOf")
- }
- }
-
- b := &rtype{
- align: goarch.PtrSize,
- size: size,
- kind: uint8(Struct),
- ptrdata: ptrdata,
- gcdata: gcdata,
- }
- s := "bucket(" + ktyp.String() + "," + etyp.String() + ")"
- b.str = resolveReflectName(newName(s, "", false, false))
- return b
-}
-
-func (t *rtype) gcSlice(begin, end uintptr) []byte {
- return (*[1 << 30]byte)(unsafe.Pointer(t.gcdata))[begin:end:end]
-}
-
-// emitGCMask writes the GC mask for [n]typ into out, starting at bit
-// offset base.
-func emitGCMask(out []byte, base uintptr, typ *rtype, n uintptr) {
- if typ.kind&kindGCProg != 0 {
- panic("reflect: unexpected GC program")
- }
- ptrs := typ.ptrdata / goarch.PtrSize
- words := typ.size / goarch.PtrSize
- mask := typ.gcSlice(0, (ptrs+7)/8)
- for j := uintptr(0); j < ptrs; j++ {
- if (mask[j/8]>>(j%8))&1 != 0 {
- for i := uintptr(0); i < n; i++ {
- k := base + i*words + j
- out[k/8] |= 1 << (k % 8)
- }
- }
- }
-}
-
-// appendGCProg appends the GC program for the first ptrdata bytes of
-// typ to dst and returns the extended slice.
-func appendGCProg(dst []byte, typ *rtype) []byte {
- if typ.kind&kindGCProg != 0 {
- // Element has GC program; emit one element.
- n := uintptr(*(*uint32)(unsafe.Pointer(typ.gcdata)))
- prog := typ.gcSlice(4, 4+n-1)
- return append(dst, prog...)
- }
-
- // Element is small with pointer mask; use as literal bits.
- ptrs := typ.ptrdata / goarch.PtrSize
- mask := typ.gcSlice(0, (ptrs+7)/8)
-
- // Emit 120-bit chunks of full bytes (max is 127 but we avoid using partial bytes).
- for ; ptrs > 120; ptrs -= 120 {
- dst = append(dst, 120)
- dst = append(dst, mask[:15]...)
- mask = mask[15:]
- }
-
- dst = append(dst, byte(ptrs))
- dst = append(dst, mask...)
- return dst
-}
-
-// SliceOf returns the slice type with element type t.
-// For example, if t represents int, SliceOf(t) represents []int.
-func SliceOf(t Type) Type {
- typ := t.(*rtype)
-
- // Look in cache.
- ckey := cacheKey{Slice, typ, nil, 0}
- if slice, ok := lookupCache.Load(ckey); ok {
- return slice.(Type)
- }
-
- // Look in known types.
- s := "[]" + typ.String()
- for _, tt := range typesByString(s) {
- slice := (*sliceType)(unsafe.Pointer(tt))
- if slice.elem == typ {
- ti, _ := lookupCache.LoadOrStore(ckey, tt)
- return ti.(Type)
- }
- }
-
- // Make a slice type.
- var islice any = ([]unsafe.Pointer)(nil)
- prototype := *(**sliceType)(unsafe.Pointer(&islice))
- slice := *prototype
- slice.tflag = 0
- slice.str = resolveReflectName(newName(s, "", false, false))
- slice.hash = fnv1(typ.hash, '[')
- slice.elem = typ
- slice.ptrToThis = 0
-
- ti, _ := lookupCache.LoadOrStore(ckey, &slice.rtype)
- return ti.(Type)
-}
-
-// The structLookupCache caches StructOf lookups.
-// StructOf does not share the common lookupCache since we need to pin
-// the memory associated with *structTypeFixedN.
-var structLookupCache struct {
- sync.Mutex // Guards stores (but not loads) on m.
-
- // m is a map[uint32][]Type keyed by the hash calculated in StructOf.
- // Elements in m are append-only and thus safe for concurrent reading.
- m sync.Map
-}
-
-type structTypeUncommon struct {
- structType
- u uncommonType
-}
-
-// isLetter reports whether a given 'rune' is classified as a Letter.
-func isLetter(ch rune) bool {
- return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch)
-}
-
-// isValidFieldName checks if a string is a valid (struct) field name or not.
-//
-// According to the language spec, a field name should be an identifier.
-//
-// identifier = letter { letter | unicode_digit } .
-// letter = unicode_letter | "_" .
-func isValidFieldName(fieldName string) bool {
- for i, c := range fieldName {
- if i == 0 && !isLetter(c) {
- return false
- }
-
- if !(isLetter(c) || unicode.IsDigit(c)) {
- return false
- }
- }
-
- return len(fieldName) > 0
-}
-
-// StructOf returns the struct type containing fields.
-// The Offset and Index fields are ignored and computed as they would be
-// by the compiler.
-//
-// StructOf currently does not generate wrapper methods for embedded
-// fields and panics if passed unexported StructFields.
-// These limitations may be lifted in a future version.
-func StructOf(fields []StructField) Type {
- var (
- hash = fnv1(0, []byte("struct {")...)
- size uintptr
- typalign uint8
- comparable = true
- methods []method
-
- fs = make([]structField, len(fields))
- repr = make([]byte, 0, 64)
- fset = map[string]struct{}{} // fields' names
-
- hasGCProg = false // records whether a struct-field type has a GCProg
- )
-
- lastzero := uintptr(0)
- repr = append(repr, "struct {"...)
- pkgpath := ""
- for i, field := range fields {
- if field.Name == "" {
- panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no name")
- }
- if !isValidFieldName(field.Name) {
- panic("reflect.StructOf: field " + strconv.Itoa(i) + " has invalid name")
- }
- if field.Type == nil {
- panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no type")
- }
- f, fpkgpath := runtimeStructField(field)
- ft := f.typ
- if ft.kind&kindGCProg != 0 {
- hasGCProg = true
- }
- if fpkgpath != "" {
- if pkgpath == "" {
- pkgpath = fpkgpath
- } else if pkgpath != fpkgpath {
- panic("reflect.Struct: fields with different PkgPath " + pkgpath + " and " + fpkgpath)
- }
- }
-
- // Update string and hash
- name := f.name.name()
- hash = fnv1(hash, []byte(name)...)
- repr = append(repr, (" " + name)...)
- if f.embedded() {
- // Embedded field
- if f.typ.Kind() == Pointer {
- // Embedded ** and *interface{} are illegal
- elem := ft.Elem()
- if k := elem.Kind(); k == Pointer || k == Interface {
- panic("reflect.StructOf: illegal embedded field type " + ft.String())
- }
- }
-
- switch f.typ.Kind() {
- case Interface:
- ift := (*interfaceType)(unsafe.Pointer(ft))
- for im, m := range ift.methods {
- if ift.nameOff(m.name).pkgPath() != "" {
- // TODO(sbinet). Issue 15924.
- panic("reflect: embedded interface with unexported method(s) not implemented")
- }
-
- var (
- mtyp = ift.typeOff(m.typ)
- ifield = i
- imethod = im
- ifn Value
- tfn Value
- )
-
- if ft.kind&kindDirectIface != 0 {
- tfn = MakeFunc(mtyp, func(in []Value) []Value {
- var args []Value
- var recv = in[0]
- if len(in) > 1 {
- args = in[1:]
- }
- return recv.Field(ifield).Method(imethod).Call(args)
- })
- ifn = MakeFunc(mtyp, func(in []Value) []Value {
- var args []Value
- var recv = in[0]
- if len(in) > 1 {
- args = in[1:]
- }
- return recv.Field(ifield).Method(imethod).Call(args)
- })
- } else {
- tfn = MakeFunc(mtyp, func(in []Value) []Value {
- var args []Value
- var recv = in[0]
- if len(in) > 1 {
- args = in[1:]
- }
- return recv.Field(ifield).Method(imethod).Call(args)
- })
- ifn = MakeFunc(mtyp, func(in []Value) []Value {
- var args []Value
- var recv = Indirect(in[0])
- if len(in) > 1 {
- args = in[1:]
- }
- return recv.Field(ifield).Method(imethod).Call(args)
- })
- }
-
- methods = append(methods, method{
- name: resolveReflectName(ift.nameOff(m.name)),
- mtyp: resolveReflectType(mtyp),
- ifn: resolveReflectText(unsafe.Pointer(&ifn)),
- tfn: resolveReflectText(unsafe.Pointer(&tfn)),
- })
- }
- case Pointer:
- ptr := (*ptrType)(unsafe.Pointer(ft))
- if unt := ptr.uncommon(); unt != nil {
- if i > 0 && unt.mcount > 0 {
- // Issue 15924.
- panic("reflect: embedded type with methods not implemented if type is not first field")
- }
- if len(fields) > 1 {
- panic("reflect: embedded type with methods not implemented if there is more than one field")
- }
- for _, m := range unt.methods() {
- mname := ptr.nameOff(m.name)
- if mname.pkgPath() != "" {
- // TODO(sbinet).
- // Issue 15924.
- panic("reflect: embedded interface with unexported method(s) not implemented")
- }
- methods = append(methods, method{
- name: resolveReflectName(mname),
- mtyp: resolveReflectType(ptr.typeOff(m.mtyp)),
- ifn: resolveReflectText(ptr.textOff(m.ifn)),
- tfn: resolveReflectText(ptr.textOff(m.tfn)),
- })
- }
- }
- if unt := ptr.elem.uncommon(); unt != nil {
- for _, m := range unt.methods() {
- mname := ptr.nameOff(m.name)
- if mname.pkgPath() != "" {
- // TODO(sbinet)
- // Issue 15924.
- panic("reflect: embedded interface with unexported method(s) not implemented")
- }
- methods = append(methods, method{
- name: resolveReflectName(mname),
- mtyp: resolveReflectType(ptr.elem.typeOff(m.mtyp)),
- ifn: resolveReflectText(ptr.elem.textOff(m.ifn)),
- tfn: resolveReflectText(ptr.elem.textOff(m.tfn)),
- })
- }
- }
- default:
- if unt := ft.uncommon(); unt != nil {
- if i > 0 && unt.mcount > 0 {
- // Issue 15924.
- panic("reflect: embedded type with methods not implemented if type is not first field")
- }
- if len(fields) > 1 && ft.kind&kindDirectIface != 0 {
- panic("reflect: embedded type with methods not implemented for non-pointer type")
- }
- for _, m := range unt.methods() {
- mname := ft.nameOff(m.name)
- if mname.pkgPath() != "" {
- // TODO(sbinet)
- // Issue 15924.
- panic("reflect: embedded interface with unexported method(s) not implemented")
- }
- methods = append(methods, method{
- name: resolveReflectName(mname),
- mtyp: resolveReflectType(ft.typeOff(m.mtyp)),
- ifn: resolveReflectText(ft.textOff(m.ifn)),
- tfn: resolveReflectText(ft.textOff(m.tfn)),
- })
-
- }
- }
- }
- }
- if _, dup := fset[name]; dup && name != "_" {
- panic("reflect.StructOf: duplicate field " + name)
- }
- fset[name] = struct{}{}
-
- hash = fnv1(hash, byte(ft.hash>>24), byte(ft.hash>>16), byte(ft.hash>>8), byte(ft.hash))
-
- repr = append(repr, (" " + ft.String())...)
- if f.name.hasTag() {
- hash = fnv1(hash, []byte(f.name.tag())...)
- repr = append(repr, (" " + strconv.Quote(f.name.tag()))...)
- }
- if i < len(fields)-1 {
- repr = append(repr, ';')
- }
-
- comparable = comparable && (ft.equal != nil)
-
- offset := align(size, uintptr(ft.align))
- if offset < size {
- panic("reflect.StructOf: struct size would exceed virtual address space")
- }
- if ft.align > typalign {
- typalign = ft.align
- }
- size = offset + ft.size
- if size < offset {
- panic("reflect.StructOf: struct size would exceed virtual address space")
- }
- f.offset = offset
-
- if ft.size == 0 {
- lastzero = size
- }
-
- fs[i] = f
- }
-
- if size > 0 && lastzero == size {
- // This is a non-zero sized struct that ends in a
- // zero-sized field. We add an extra byte of padding,
- // to ensure that taking the address of the final
- // zero-sized field can't manufacture a pointer to the
- // next object in the heap. See issue 9401.
- size++
- if size == 0 {
- panic("reflect.StructOf: struct size would exceed virtual address space")
- }
- }
-
- var typ *structType
- var ut *uncommonType
-
- if len(methods) == 0 {
- t := new(structTypeUncommon)
- typ = &t.structType
- ut = &t.u
- } else {
- // A *rtype representing a struct is followed directly in memory by an
- // array of method objects representing the methods attached to the
- // struct. To get the same layout for a run time generated type, we
- // need an array directly following the uncommonType memory.
- // A similar strategy is used for funcTypeFixed4, ...funcTypeFixedN.
- tt := New(StructOf([]StructField{
- {Name: "S", Type: TypeOf(structType{})},
- {Name: "U", Type: TypeOf(uncommonType{})},
- {Name: "M", Type: ArrayOf(len(methods), TypeOf(methods[0]))},
- }))
-
- typ = (*structType)(tt.Elem().Field(0).Addr().UnsafePointer())
- ut = (*uncommonType)(tt.Elem().Field(1).Addr().UnsafePointer())
-
- copy(tt.Elem().Field(2).Slice(0, len(methods)).Interface().([]method), methods)
- }
- // TODO(sbinet): Once we allow embedding multiple types,
- // methods will need to be sorted like the compiler does.
- // TODO(sbinet): Once we allow non-exported methods, we will
- // need to compute xcount as the number of exported methods.
- ut.mcount = uint16(len(methods))
- ut.xcount = ut.mcount
- ut.moff = uint32(unsafe.Sizeof(uncommonType{}))
-
- if len(fs) > 0 {
- repr = append(repr, ' ')
- }
- repr = append(repr, '}')
- hash = fnv1(hash, '}')
- str := string(repr)
-
- // Round the size up to be a multiple of the alignment.
- s := align(size, uintptr(typalign))
- if s < size {
- panic("reflect.StructOf: struct size would exceed virtual address space")
- }
- size = s
-
- // Make the struct type.
- var istruct any = struct{}{}
- prototype := *(**structType)(unsafe.Pointer(&istruct))
- *typ = *prototype
- typ.fields = fs
- if pkgpath != "" {
- typ.pkgPath = newName(pkgpath, "", false, false)
- }
-
- // Look in cache.
- if ts, ok := structLookupCache.m.Load(hash); ok {
- for _, st := range ts.([]Type) {
- t := st.common()
- if haveIdenticalUnderlyingType(&typ.rtype, t, true) {
- return t
- }
- }
- }
-
- // Not in cache, lock and retry.
- structLookupCache.Lock()
- defer structLookupCache.Unlock()
- if ts, ok := structLookupCache.m.Load(hash); ok {
- for _, st := range ts.([]Type) {
- t := st.common()
- if haveIdenticalUnderlyingType(&typ.rtype, t, true) {
- return t
- }
- }
- }
-
- addToCache := func(t Type) Type {
- var ts []Type
- if ti, ok := structLookupCache.m.Load(hash); ok {
- ts = ti.([]Type)
- }
- structLookupCache.m.Store(hash, append(ts, t))
- return t
- }
-
- // Look in known types.
- for _, t := range typesByString(str) {
- if haveIdenticalUnderlyingType(&typ.rtype, t, true) {
- // even if 't' wasn't a structType with methods, we should be ok
- // as the 'u uncommonType' field won't be accessed except when
- // tflag&tflagUncommon is set.
- return addToCache(t)
- }
- }
-
- typ.str = resolveReflectName(newName(str, "", false, false))
- typ.tflag = 0 // TODO: set tflagRegularMemory
- typ.hash = hash
- typ.size = size
- typ.ptrdata = typeptrdata(typ.common())
- typ.align = typalign
- typ.fieldAlign = typalign
- typ.ptrToThis = 0
- if len(methods) > 0 {
- typ.tflag |= tflagUncommon
- }
-
- if hasGCProg {
- lastPtrField := 0
- for i, ft := range fs {
- if ft.typ.pointers() {
- lastPtrField = i
- }
- }
- prog := []byte{0, 0, 0, 0} // will be length of prog
- var off uintptr
- for i, ft := range fs {
- if i > lastPtrField {
- // gcprog should not include anything for any field after
- // the last field that contains pointer data
- break
- }
- if !ft.typ.pointers() {
- // Ignore pointerless fields.
- continue
- }
- // Pad to start of this field with zeros.
- if ft.offset > off {
- n := (ft.offset - off) / goarch.PtrSize
- prog = append(prog, 0x01, 0x00) // emit a 0 bit
- if n > 1 {
- prog = append(prog, 0x81) // repeat previous bit
- prog = appendVarint(prog, n-1) // n-1 times
- }
- off = ft.offset
- }
-
- prog = appendGCProg(prog, ft.typ)
- off += ft.typ.ptrdata
- }
- prog = append(prog, 0)
- *(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4)
- typ.kind |= kindGCProg
- typ.gcdata = &prog[0]
- } else {
- typ.kind &^= kindGCProg
- bv := new(bitVector)
- addTypeBits(bv, 0, typ.common())
- if len(bv.data) > 0 {
- typ.gcdata = &bv.data[0]
- }
- }
- typ.equal = nil
- if comparable {
- typ.equal = func(p, q unsafe.Pointer) bool {
- for _, ft := range typ.fields {
- pi := add(p, ft.offset, "&x.field safe")
- qi := add(q, ft.offset, "&x.field safe")
- if !ft.typ.equal(pi, qi) {
- return false
- }
- }
- return true
- }
- }
-
- switch {
- case len(fs) == 1 && !ifaceIndir(fs[0].typ):
- // structs of 1 direct iface type can be direct
- typ.kind |= kindDirectIface
- default:
- typ.kind &^= kindDirectIface
- }
-
- return addToCache(&typ.rtype)
-}
-
-// runtimeStructField takes a StructField value passed to StructOf and
-// returns both the corresponding internal representation, of type
-// structField, and the pkgpath value to use for this field.
-func runtimeStructField(field StructField) (structField, string) {
- if field.Anonymous && field.PkgPath != "" {
- panic("reflect.StructOf: field \"" + field.Name + "\" is anonymous but has PkgPath set")
- }
-
- if field.IsExported() {
- // Best-effort check for misuse.
- // Since this field will be treated as exported, not much harm done if Unicode lowercase slips through.
- c := field.Name[0]
- if 'a' <= c && c <= 'z' || c == '_' {
- panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath")
- }
- }
-
- resolveReflectType(field.Type.common()) // install in runtime
- f := structField{
- name: newName(field.Name, string(field.Tag), field.IsExported(), field.Anonymous),
- typ: field.Type.common(),
- offset: 0,
- }
- return f, field.PkgPath
-}
-
-// typeptrdata returns the length in bytes of the prefix of t
-// containing pointer data. Anything after this offset is scalar data.
-// keep in sync with ../cmd/compile/internal/reflectdata/reflect.go
-func typeptrdata(t *rtype) uintptr {
- switch t.Kind() {
- case Struct:
- st := (*structType)(unsafe.Pointer(t))
- // find the last field that has pointers.
- field := -1
- for i := range st.fields {
- ft := st.fields[i].typ
- if ft.pointers() {
- field = i
- }
- }
- if field == -1 {
- return 0
- }
- f := st.fields[field]
- return f.offset + f.typ.ptrdata
-
- default:
- panic("reflect.typeptrdata: unexpected type, " + t.String())
- }
-}
-
-// See cmd/compile/internal/reflectdata/reflect.go for derivation of constant.
-const maxPtrmaskBytes = 2048
-
-// ArrayOf returns the array type with the given length and element type.
-// For example, if t represents int, ArrayOf(5, t) represents [5]int.
-//
-// If the resulting type would be larger than the available address space,
-// ArrayOf panics.
-func ArrayOf(length int, elem Type) Type {
- if length < 0 {
- panic("reflect: negative length passed to ArrayOf")
- }
-
- typ := elem.(*rtype)
-
- // Look in cache.
- ckey := cacheKey{Array, typ, nil, uintptr(length)}
- if array, ok := lookupCache.Load(ckey); ok {
- return array.(Type)
- }
-
- // Look in known types.
- s := "[" + strconv.Itoa(length) + "]" + typ.String()
- for _, tt := range typesByString(s) {
- array := (*arrayType)(unsafe.Pointer(tt))
- if array.elem == typ {
- ti, _ := lookupCache.LoadOrStore(ckey, tt)
- return ti.(Type)
- }
- }
-
- // Make an array type.
- var iarray any = [1]unsafe.Pointer{}
- prototype := *(**arrayType)(unsafe.Pointer(&iarray))
- array := *prototype
- array.tflag = typ.tflag & tflagRegularMemory
- array.str = resolveReflectName(newName(s, "", false, false))
- array.hash = fnv1(typ.hash, '[')
- for n := uint32(length); n > 0; n >>= 8 {
- array.hash = fnv1(array.hash, byte(n))
- }
- array.hash = fnv1(array.hash, ']')
- array.elem = typ
- array.ptrToThis = 0
- if typ.size > 0 {
- max := ^uintptr(0) / typ.size
- if uintptr(length) > max {
- panic("reflect.ArrayOf: array size would exceed virtual address space")
- }
- }
- array.size = typ.size * uintptr(length)
- if length > 0 && typ.ptrdata != 0 {
- array.ptrdata = typ.size*uintptr(length-1) + typ.ptrdata
- }
- array.align = typ.align
- array.fieldAlign = typ.fieldAlign
- array.len = uintptr(length)
- array.slice = SliceOf(elem).(*rtype)
-
- switch {
- case typ.ptrdata == 0 || array.size == 0:
- // No pointers.
- array.gcdata = nil
- array.ptrdata = 0
-
- case length == 1:
- // In memory, 1-element array looks just like the element.
- array.kind |= typ.kind & kindGCProg
- array.gcdata = typ.gcdata
- array.ptrdata = typ.ptrdata
-
- case typ.kind&kindGCProg == 0 && array.size <= maxPtrmaskBytes*8*goarch.PtrSize:
- // Element is small with pointer mask; array is still small.
- // Create direct pointer mask by turning each 1 bit in elem
- // into length 1 bits in larger mask.
- n := (array.ptrdata/goarch.PtrSize + 7) / 8
- // Runtime needs pointer masks to be a multiple of uintptr in size.
- n = (n + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1)
- mask := make([]byte, n)
- emitGCMask(mask, 0, typ, array.len)
- array.gcdata = &mask[0]
-
- default:
- // Create program that emits one element
- // and then repeats to make the array.
- prog := []byte{0, 0, 0, 0} // will be length of prog
- prog = appendGCProg(prog, typ)
- // Pad from ptrdata to size.
- elemPtrs := typ.ptrdata / goarch.PtrSize
- elemWords := typ.size / goarch.PtrSize
- if elemPtrs < elemWords {
- // Emit literal 0 bit, then repeat as needed.
- prog = append(prog, 0x01, 0x00)
- if elemPtrs+1 < elemWords {
- prog = append(prog, 0x81)
- prog = appendVarint(prog, elemWords-elemPtrs-1)
- }
- }
- // Repeat length-1 times.
- if elemWords < 0x80 {
- prog = append(prog, byte(elemWords|0x80))
- } else {
- prog = append(prog, 0x80)
- prog = appendVarint(prog, elemWords)
- }
- prog = appendVarint(prog, uintptr(length)-1)
- prog = append(prog, 0)
- *(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4)
- array.kind |= kindGCProg
- array.gcdata = &prog[0]
- array.ptrdata = array.size // overestimate but ok; must match program
- }
-
- etyp := typ.common()
- esize := etyp.Size()
-
- array.equal = nil
- if eequal := etyp.equal; eequal != nil {
- array.equal = func(p, q unsafe.Pointer) bool {
- for i := 0; i < length; i++ {
- pi := arrayAt(p, i, esize, "i < length")
- qi := arrayAt(q, i, esize, "i < length")
- if !eequal(pi, qi) {
- return false
- }
-
- }
- return true
- }
- }
-
- switch {
- case length == 1 && !ifaceIndir(typ):
- // array of 1 direct iface type can be direct
- array.kind |= kindDirectIface
- default:
- array.kind &^= kindDirectIface
- }
-
- ti, _ := lookupCache.LoadOrStore(ckey, &array.rtype)
- return ti.(Type)
-}
-
-func appendVarint(x []byte, v uintptr) []byte {
- for ; v >= 0x80; v >>= 7 {
- x = append(x, byte(v|0x80))
- }
- x = append(x, byte(v))
- return x
-}
-
-// toType converts from a *rtype to a Type that can be returned
-// to the client of package reflect. In gc, the only concern is that
-// a nil *rtype must be replaced by a nil Type, but in gccgo this
-// function takes care of ensuring that multiple *rtype for the same
-// type are coalesced into a single Type.
-func toType(t *rtype) Type {
- if t == nil {
- return nil
- }
- return t
-}
-
-type layoutKey struct {
- ftyp *funcType // function signature
- rcvr *rtype // receiver type, or nil if none
-}
-
-type layoutType struct {
- t *rtype
- framePool *sync.Pool
- abid abiDesc
-}
-
-var layoutCache sync.Map // map[layoutKey]layoutType
-
-// funcLayout computes a struct type representing the layout of the
-// stack-assigned function arguments and return values for the function
-// type t.
-// If rcvr != nil, rcvr specifies the type of the receiver.
-// The returned type exists only for GC, so we only fill out GC relevant info.
-// Currently, that's just size and the GC program. We also fill in
-// the name for possible debugging use.
-func funcLayout(t *funcType, rcvr *rtype) (frametype *rtype, framePool *sync.Pool, abid abiDesc) {
- if t.Kind() != Func {
- panic("reflect: funcLayout of non-func type " + t.String())
- }
- if rcvr != nil && rcvr.Kind() == Interface {
- panic("reflect: funcLayout with interface receiver " + rcvr.String())
- }
- k := layoutKey{t, rcvr}
- if lti, ok := layoutCache.Load(k); ok {
- lt := lti.(layoutType)
- return lt.t, lt.framePool, lt.abid
- }
-
- // Compute the ABI layout.
- abid = newAbiDesc(t, rcvr)
-
- // build dummy rtype holding gc program
- x := &rtype{
- align: goarch.PtrSize,
- // Don't add spill space here; it's only necessary in
- // reflectcall's frame, not in the allocated frame.
- // TODO(mknyszek): Remove this comment when register
- // spill space in the frame is no longer required.
- size: align(abid.retOffset+abid.ret.stackBytes, goarch.PtrSize),
- ptrdata: uintptr(abid.stackPtrs.n) * goarch.PtrSize,
- }
- if abid.stackPtrs.n > 0 {
- x.gcdata = &abid.stackPtrs.data[0]
- }
-
- var s string
- if rcvr != nil {
- s = "methodargs(" + rcvr.String() + ")(" + t.String() + ")"
- } else {
- s = "funcargs(" + t.String() + ")"
- }
- x.str = resolveReflectName(newName(s, "", false, false))
-
- // cache result for future callers
- framePool = &sync.Pool{New: func() any {
- return unsafe_New(x)
- }}
- lti, _ := layoutCache.LoadOrStore(k, layoutType{
- t: x,
- framePool: framePool,
- abid: abid,
- })
- lt := lti.(layoutType)
- return lt.t, lt.framePool, lt.abid
-}
-
-// ifaceIndir reports whether t is stored indirectly in an interface value.
-func ifaceIndir(t *rtype) bool {
- return t.kind&kindDirectIface == 0
-}
-
-// Note: this type must agree with runtime.bitvector.
-type bitVector struct {
- n uint32 // number of bits
- data []byte
-}
-
-// append a bit to the bitmap.
-func (bv *bitVector) append(bit uint8) {
- if bv.n%(8*goarch.PtrSize) == 0 {
- // Runtime needs pointer masks to be a multiple of uintptr in size.
- // Since reflect passes bv.data directly to the runtime as a pointer mask,
- // we append a full uintptr of zeros at a time.
- for i := 0; i < goarch.PtrSize; i++ {
- bv.data = append(bv.data, 0)
- }
- }
- bv.data[bv.n/8] |= bit << (bv.n % 8)
- bv.n++
-}
-
-func addTypeBits(bv *bitVector, offset uintptr, t *rtype) {
- if t.ptrdata == 0 {
- return
- }
-
- switch Kind(t.kind & kindMask) {
- case Chan, Func, Map, Pointer, Slice, String, UnsafePointer:
- // 1 pointer at start of representation
- for bv.n < uint32(offset/uintptr(goarch.PtrSize)) {
- bv.append(0)
- }
- bv.append(1)
-
- case Interface:
- // 2 pointers
- for bv.n < uint32(offset/uintptr(goarch.PtrSize)) {
- bv.append(0)
- }
- bv.append(1)
- bv.append(1)
-
- case Array:
- // repeat inner type
- tt := (*arrayType)(unsafe.Pointer(t))
- for i := 0; i < int(tt.len); i++ {
- addTypeBits(bv, offset+uintptr(i)*tt.elem.size, tt.elem)
- }
-
- case Struct:
- // apply fields
- tt := (*structType)(unsafe.Pointer(t))
- for i := range tt.fields {
- f := &tt.fields[i]
- addTypeBits(bv, offset+f.offset, f.typ)
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/reflect/value.go b/contrib/go/_std_1.20/src/reflect/value.go
deleted file mode 100644
index 42bb5ea527..0000000000
--- a/contrib/go/_std_1.20/src/reflect/value.go
+++ /dev/null
@@ -1,3860 +0,0 @@
-// Copyright 2009 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 reflect
-
-import (
- "errors"
- "internal/abi"
- "internal/goarch"
- "internal/itoa"
- "internal/unsafeheader"
- "math"
- "runtime"
- "unsafe"
-)
-
-// Value is the reflection interface to a Go value.
-//
-// Not all methods apply to all kinds of values. Restrictions,
-// if any, are noted in the documentation for each method.
-// Use the Kind method to find out the kind of value before
-// calling kind-specific methods. Calling a method
-// inappropriate to the kind of type causes a run time panic.
-//
-// The zero Value represents no value.
-// Its IsValid method returns false, its Kind method returns Invalid,
-// its String method returns "<invalid Value>", and all other methods panic.
-// Most functions and methods never return an invalid value.
-// If one does, its documentation states the conditions explicitly.
-//
-// A Value can be used concurrently by multiple goroutines provided that
-// the underlying Go value can be used concurrently for the equivalent
-// direct operations.
-//
-// To compare two Values, compare the results of the Interface method.
-// Using == on two Values does not compare the underlying values
-// they represent.
-type Value struct {
- // typ holds the type of the value represented by a Value.
- typ *rtype
-
- // Pointer-valued data or, if flagIndir is set, pointer to data.
- // Valid when either flagIndir is set or typ.pointers() is true.
- ptr unsafe.Pointer
-
- // flag holds metadata about the value.
- //
- // The lowest five bits give the Kind of the value, mirroring typ.Kind().
- //
- // The next set of bits are flag bits:
- // - flagStickyRO: obtained via unexported not embedded field, so read-only
- // - flagEmbedRO: obtained via unexported embedded field, so read-only
- // - flagIndir: val holds a pointer to the data
- // - flagAddr: v.CanAddr is true (implies flagIndir and ptr is non-nil)
- // - flagMethod: v is a method value.
- // If ifaceIndir(typ), code can assume that flagIndir is set.
- //
- // The remaining 22+ bits give a method number for method values.
- // If flag.kind() != Func, code can assume that flagMethod is unset.
- flag
-
- // A method value represents a curried method invocation
- // like r.Read for some receiver r. The typ+val+flag bits describe
- // the receiver r, but the flag's Kind bits say Func (methods are
- // functions), and the top bits of the flag give the method number
- // in r's type's method table.
-}
-
-type flag uintptr
-
-const (
- flagKindWidth = 5 // there are 27 kinds
- flagKindMask flag = 1<<flagKindWidth - 1
- flagStickyRO flag = 1 << 5
- flagEmbedRO flag = 1 << 6
- flagIndir flag = 1 << 7
- flagAddr flag = 1 << 8
- flagMethod flag = 1 << 9
- flagMethodShift = 10
- flagRO flag = flagStickyRO | flagEmbedRO
-)
-
-func (f flag) kind() Kind {
- return Kind(f & flagKindMask)
-}
-
-func (f flag) ro() flag {
- if f&flagRO != 0 {
- return flagStickyRO
- }
- return 0
-}
-
-// pointer returns the underlying pointer represented by v.
-// v.Kind() must be Pointer, Map, Chan, Func, or UnsafePointer
-// if v.Kind() == Pointer, the base type must not be not-in-heap.
-func (v Value) pointer() unsafe.Pointer {
- if v.typ.size != goarch.PtrSize || !v.typ.pointers() {
- panic("can't call pointer on a non-pointer Value")
- }
- if v.flag&flagIndir != 0 {
- return *(*unsafe.Pointer)(v.ptr)
- }
- return v.ptr
-}
-
-// packEface converts v to the empty interface.
-func packEface(v Value) any {
- t := v.typ
- var i any
- e := (*emptyInterface)(unsafe.Pointer(&i))
- // First, fill in the data portion of the interface.
- switch {
- case ifaceIndir(t):
- if v.flag&flagIndir == 0 {
- panic("bad indir")
- }
- // Value is indirect, and so is the interface we're making.
- ptr := v.ptr
- if v.flag&flagAddr != 0 {
- // TODO: pass safe boolean from valueInterface so
- // we don't need to copy if safe==true?
- c := unsafe_New(t)
- typedmemmove(t, c, ptr)
- ptr = c
- }
- e.word = ptr
- case v.flag&flagIndir != 0:
- // Value is indirect, but interface is direct. We need
- // to load the data at v.ptr into the interface data word.
- e.word = *(*unsafe.Pointer)(v.ptr)
- default:
- // Value is direct, and so is the interface.
- e.word = v.ptr
- }
- // Now, fill in the type portion. We're very careful here not
- // to have any operation between the e.word and e.typ assignments
- // that would let the garbage collector observe the partially-built
- // interface value.
- e.typ = t
- return i
-}
-
-// unpackEface converts the empty interface i to a Value.
-func unpackEface(i any) Value {
- e := (*emptyInterface)(unsafe.Pointer(&i))
- // NOTE: don't read e.word until we know whether it is really a pointer or not.
- t := e.typ
- if t == nil {
- return Value{}
- }
- f := flag(t.Kind())
- if ifaceIndir(t) {
- f |= flagIndir
- }
- return Value{t, e.word, f}
-}
-
-// A ValueError occurs when a Value method is invoked on
-// a Value that does not support it. Such cases are documented
-// in the description of each method.
-type ValueError struct {
- Method string
- Kind Kind
-}
-
-func (e *ValueError) Error() string {
- if e.Kind == 0 {
- return "reflect: call of " + e.Method + " on zero Value"
- }
- return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
-}
-
-// valueMethodName returns the name of the exported calling method on Value.
-func valueMethodName() string {
- var pc [5]uintptr
- n := runtime.Callers(1, pc[:])
- frames := runtime.CallersFrames(pc[:n])
- var frame runtime.Frame
- for more := true; more; {
- const prefix = "reflect.Value."
- frame, more = frames.Next()
- name := frame.Function
- if len(name) > len(prefix) && name[:len(prefix)] == prefix {
- methodName := name[len(prefix):]
- if len(methodName) > 0 && 'A' <= methodName[0] && methodName[0] <= 'Z' {
- return name
- }
- }
- }
- return "unknown method"
-}
-
-// emptyInterface is the header for an interface{} value.
-type emptyInterface struct {
- typ *rtype
- word unsafe.Pointer
-}
-
-// nonEmptyInterface is the header for an interface value with methods.
-type nonEmptyInterface struct {
- // see ../runtime/iface.go:/Itab
- itab *struct {
- ityp *rtype // static interface type
- typ *rtype // dynamic concrete type
- hash uint32 // copy of typ.hash
- _ [4]byte
- fun [100000]unsafe.Pointer // method table
- }
- word unsafe.Pointer
-}
-
-// mustBe panics if f's kind is not expected.
-// Making this a method on flag instead of on Value
-// (and embedding flag in Value) means that we can write
-// the very clear v.mustBe(Bool) and have it compile into
-// v.flag.mustBe(Bool), which will only bother to copy the
-// single important word for the receiver.
-func (f flag) mustBe(expected Kind) {
- // TODO(mvdan): use f.kind() again once mid-stack inlining gets better
- if Kind(f&flagKindMask) != expected {
- panic(&ValueError{valueMethodName(), f.kind()})
- }
-}
-
-// mustBeExported panics if f records that the value was obtained using
-// an unexported field.
-func (f flag) mustBeExported() {
- if f == 0 || f&flagRO != 0 {
- f.mustBeExportedSlow()
- }
-}
-
-func (f flag) mustBeExportedSlow() {
- if f == 0 {
- panic(&ValueError{valueMethodName(), Invalid})
- }
- if f&flagRO != 0 {
- panic("reflect: " + valueMethodName() + " using value obtained using unexported field")
- }
-}
-
-// mustBeAssignable panics if f records that the value is not assignable,
-// which is to say that either it was obtained using an unexported field
-// or it is not addressable.
-func (f flag) mustBeAssignable() {
- if f&flagRO != 0 || f&flagAddr == 0 {
- f.mustBeAssignableSlow()
- }
-}
-
-func (f flag) mustBeAssignableSlow() {
- if f == 0 {
- panic(&ValueError{valueMethodName(), Invalid})
- }
- // Assignable if addressable and not read-only.
- if f&flagRO != 0 {
- panic("reflect: " + valueMethodName() + " using value obtained using unexported field")
- }
- if f&flagAddr == 0 {
- panic("reflect: " + valueMethodName() + " using unaddressable value")
- }
-}
-
-// Addr returns a pointer value representing the address of v.
-// It panics if CanAddr() returns false.
-// Addr is typically used to obtain a pointer to a struct field
-// or slice element in order to call a method that requires a
-// pointer receiver.
-func (v Value) Addr() Value {
- if v.flag&flagAddr == 0 {
- panic("reflect.Value.Addr of unaddressable value")
- }
- // Preserve flagRO instead of using v.flag.ro() so that
- // v.Addr().Elem() is equivalent to v (#32772)
- fl := v.flag & flagRO
- return Value{v.typ.ptrTo(), v.ptr, fl | flag(Pointer)}
-}
-
-// Bool returns v's underlying value.
-// It panics if v's kind is not Bool.
-func (v Value) Bool() bool {
- // panicNotBool is split out to keep Bool inlineable.
- if v.kind() != Bool {
- v.panicNotBool()
- }
- return *(*bool)(v.ptr)
-}
-
-func (v Value) panicNotBool() {
- v.mustBe(Bool)
-}
-
-var bytesType = rtypeOf(([]byte)(nil))
-
-// Bytes returns v's underlying value.
-// It panics if v's underlying value is not a slice of bytes or
-// an addressable array of bytes.
-func (v Value) Bytes() []byte {
- // bytesSlow is split out to keep Bytes inlineable for unnamed []byte.
- if v.typ == bytesType {
- return *(*[]byte)(v.ptr)
- }
- return v.bytesSlow()
-}
-
-func (v Value) bytesSlow() []byte {
- switch v.kind() {
- case Slice:
- if v.typ.Elem().Kind() != Uint8 {
- panic("reflect.Value.Bytes of non-byte slice")
- }
- // Slice is always bigger than a word; assume flagIndir.
- return *(*[]byte)(v.ptr)
- case Array:
- if v.typ.Elem().Kind() != Uint8 {
- panic("reflect.Value.Bytes of non-byte array")
- }
- if !v.CanAddr() {
- panic("reflect.Value.Bytes of unaddressable byte array")
- }
- p := (*byte)(v.ptr)
- n := int((*arrayType)(unsafe.Pointer(v.typ)).len)
- return unsafe.Slice(p, n)
- }
- panic(&ValueError{"reflect.Value.Bytes", v.kind()})
-}
-
-// runes returns v's underlying value.
-// It panics if v's underlying value is not a slice of runes (int32s).
-func (v Value) runes() []rune {
- v.mustBe(Slice)
- if v.typ.Elem().Kind() != Int32 {
- panic("reflect.Value.Bytes of non-rune slice")
- }
- // Slice is always bigger than a word; assume flagIndir.
- return *(*[]rune)(v.ptr)
-}
-
-// CanAddr reports whether the value's address can be obtained with Addr.
-// Such values are called addressable. A value is addressable if it is
-// an element of a slice, an element of an addressable array,
-// a field of an addressable struct, or the result of dereferencing a pointer.
-// If CanAddr returns false, calling Addr will panic.
-func (v Value) CanAddr() bool {
- return v.flag&flagAddr != 0
-}
-
-// CanSet reports whether the value of v can be changed.
-// A Value can be changed only if it is addressable and was not
-// obtained by the use of unexported struct fields.
-// If CanSet returns false, calling Set or any type-specific
-// setter (e.g., SetBool, SetInt) will panic.
-func (v Value) CanSet() bool {
- return v.flag&(flagAddr|flagRO) == flagAddr
-}
-
-// Call calls the function v with the input arguments in.
-// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]).
-// Call panics if v's Kind is not Func.
-// It returns the output results as Values.
-// As in Go, each input argument must be assignable to the
-// type of the function's corresponding input parameter.
-// If v is a variadic function, Call creates the variadic slice parameter
-// itself, copying in the corresponding values.
-func (v Value) Call(in []Value) []Value {
- v.mustBe(Func)
- v.mustBeExported()
- return v.call("Call", in)
-}
-
-// CallSlice calls the variadic function v with the input arguments in,
-// assigning the slice in[len(in)-1] to v's final variadic argument.
-// For example, if len(in) == 3, v.CallSlice(in) represents the Go call v(in[0], in[1], in[2]...).
-// CallSlice panics if v's Kind is not Func or if v is not variadic.
-// It returns the output results as Values.
-// As in Go, each input argument must be assignable to the
-// type of the function's corresponding input parameter.
-func (v Value) CallSlice(in []Value) []Value {
- v.mustBe(Func)
- v.mustBeExported()
- return v.call("CallSlice", in)
-}
-
-var callGC bool // for testing; see TestCallMethodJump and TestCallArgLive
-
-const debugReflectCall = false
-
-func (v Value) call(op string, in []Value) []Value {
- // Get function pointer, type.
- t := (*funcType)(unsafe.Pointer(v.typ))
- var (
- fn unsafe.Pointer
- rcvr Value
- rcvrtype *rtype
- )
- if v.flag&flagMethod != 0 {
- rcvr = v
- rcvrtype, t, fn = methodReceiver(op, v, int(v.flag)>>flagMethodShift)
- } else if v.flag&flagIndir != 0 {
- fn = *(*unsafe.Pointer)(v.ptr)
- } else {
- fn = v.ptr
- }
-
- if fn == nil {
- panic("reflect.Value.Call: call of nil function")
- }
-
- isSlice := op == "CallSlice"
- n := t.NumIn()
- isVariadic := t.IsVariadic()
- if isSlice {
- if !isVariadic {
- panic("reflect: CallSlice of non-variadic function")
- }
- if len(in) < n {
- panic("reflect: CallSlice with too few input arguments")
- }
- if len(in) > n {
- panic("reflect: CallSlice with too many input arguments")
- }
- } else {
- if isVariadic {
- n--
- }
- if len(in) < n {
- panic("reflect: Call with too few input arguments")
- }
- if !isVariadic && len(in) > n {
- panic("reflect: Call with too many input arguments")
- }
- }
- for _, x := range in {
- if x.Kind() == Invalid {
- panic("reflect: " + op + " using zero Value argument")
- }
- }
- for i := 0; i < n; i++ {
- if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(targ) {
- panic("reflect: " + op + " using " + xt.String() + " as type " + targ.String())
- }
- }
- if !isSlice && isVariadic {
- // prepare slice for remaining values
- m := len(in) - n
- slice := MakeSlice(t.In(n), m, m)
- elem := t.In(n).Elem()
- for i := 0; i < m; i++ {
- x := in[n+i]
- if xt := x.Type(); !xt.AssignableTo(elem) {
- panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + op)
- }
- slice.Index(i).Set(x)
- }
- origIn := in
- in = make([]Value, n+1)
- copy(in[:n], origIn)
- in[n] = slice
- }
-
- nin := len(in)
- if nin != t.NumIn() {
- panic("reflect.Value.Call: wrong argument count")
- }
- nout := t.NumOut()
-
- // Register argument space.
- var regArgs abi.RegArgs
-
- // Compute frame type.
- frametype, framePool, abid := funcLayout(t, rcvrtype)
-
- // Allocate a chunk of memory for frame if needed.
- var stackArgs unsafe.Pointer
- if frametype.size != 0 {
- if nout == 0 {
- stackArgs = framePool.Get().(unsafe.Pointer)
- } else {
- // Can't use pool if the function has return values.
- // We will leak pointer to args in ret, so its lifetime is not scoped.
- stackArgs = unsafe_New(frametype)
- }
- }
- frameSize := frametype.size
-
- if debugReflectCall {
- println("reflect.call", t.String())
- abid.dump()
- }
-
- // Copy inputs into args.
-
- // Handle receiver.
- inStart := 0
- if rcvrtype != nil {
- // Guaranteed to only be one word in size,
- // so it will only take up exactly 1 abiStep (either
- // in a register or on the stack).
- switch st := abid.call.steps[0]; st.kind {
- case abiStepStack:
- storeRcvr(rcvr, stackArgs)
- case abiStepPointer:
- storeRcvr(rcvr, unsafe.Pointer(&regArgs.Ptrs[st.ireg]))
- fallthrough
- case abiStepIntReg:
- storeRcvr(rcvr, unsafe.Pointer(&regArgs.Ints[st.ireg]))
- case abiStepFloatReg:
- storeRcvr(rcvr, unsafe.Pointer(&regArgs.Floats[st.freg]))
- default:
- panic("unknown ABI parameter kind")
- }
- inStart = 1
- }
-
- // Handle arguments.
- for i, v := range in {
- v.mustBeExported()
- targ := t.In(i).(*rtype)
- // TODO(mknyszek): Figure out if it's possible to get some
- // scratch space for this assignment check. Previously, it
- // was possible to use space in the argument frame.
- v = v.assignTo("reflect.Value.Call", targ, nil)
- stepsLoop:
- for _, st := range abid.call.stepsForValue(i + inStart) {
- switch st.kind {
- case abiStepStack:
- // Copy values to the "stack."
- addr := add(stackArgs, st.stkOff, "precomputed stack arg offset")
- if v.flag&flagIndir != 0 {
- typedmemmove(targ, addr, v.ptr)
- } else {
- *(*unsafe.Pointer)(addr) = v.ptr
- }
- // There's only one step for a stack-allocated value.
- break stepsLoop
- case abiStepIntReg, abiStepPointer:
- // Copy values to "integer registers."
- if v.flag&flagIndir != 0 {
- offset := add(v.ptr, st.offset, "precomputed value offset")
- if st.kind == abiStepPointer {
- // Duplicate this pointer in the pointer area of the
- // register space. Otherwise, there's the potential for
- // this to be the last reference to v.ptr.
- regArgs.Ptrs[st.ireg] = *(*unsafe.Pointer)(offset)
- }
- intToReg(&regArgs, st.ireg, st.size, offset)
- } else {
- if st.kind == abiStepPointer {
- // See the comment in abiStepPointer case above.
- regArgs.Ptrs[st.ireg] = v.ptr
- }
- regArgs.Ints[st.ireg] = uintptr(v.ptr)
- }
- case abiStepFloatReg:
- // Copy values to "float registers."
- if v.flag&flagIndir == 0 {
- panic("attempted to copy pointer to FP register")
- }
- offset := add(v.ptr, st.offset, "precomputed value offset")
- floatToReg(&regArgs, st.freg, st.size, offset)
- default:
- panic("unknown ABI part kind")
- }
- }
- }
- // TODO(mknyszek): Remove this when we no longer have
- // caller reserved spill space.
- frameSize = align(frameSize, goarch.PtrSize)
- frameSize += abid.spill
-
- // Mark pointers in registers for the return path.
- regArgs.ReturnIsPtr = abid.outRegPtrs
-
- if debugReflectCall {
- regArgs.Dump()
- }
-
- // For testing; see TestCallArgLive.
- if callGC {
- runtime.GC()
- }
-
- // Call.
- call(frametype, fn, stackArgs, uint32(frametype.size), uint32(abid.retOffset), uint32(frameSize), &regArgs)
-
- // For testing; see TestCallMethodJump.
- if callGC {
- runtime.GC()
- }
-
- var ret []Value
- if nout == 0 {
- if stackArgs != nil {
- typedmemclr(frametype, stackArgs)
- framePool.Put(stackArgs)
- }
- } else {
- if stackArgs != nil {
- // Zero the now unused input area of args,
- // because the Values returned by this function contain pointers to the args object,
- // and will thus keep the args object alive indefinitely.
- typedmemclrpartial(frametype, stackArgs, 0, abid.retOffset)
- }
-
- // Wrap Values around return values in args.
- ret = make([]Value, nout)
- for i := 0; i < nout; i++ {
- tv := t.Out(i)
- if tv.Size() == 0 {
- // For zero-sized return value, args+off may point to the next object.
- // In this case, return the zero value instead.
- ret[i] = Zero(tv)
- continue
- }
- steps := abid.ret.stepsForValue(i)
- if st := steps[0]; st.kind == abiStepStack {
- // This value is on the stack. If part of a value is stack
- // allocated, the entire value is according to the ABI. So
- // just make an indirection into the allocated frame.
- fl := flagIndir | flag(tv.Kind())
- ret[i] = Value{tv.common(), add(stackArgs, st.stkOff, "tv.Size() != 0"), fl}
- // Note: this does introduce false sharing between results -
- // if any result is live, they are all live.
- // (And the space for the args is live as well, but as we've
- // cleared that space it isn't as big a deal.)
- continue
- }
-
- // Handle pointers passed in registers.
- if !ifaceIndir(tv.common()) {
- // Pointer-valued data gets put directly
- // into v.ptr.
- if steps[0].kind != abiStepPointer {
- print("kind=", steps[0].kind, ", type=", tv.String(), "\n")
- panic("mismatch between ABI description and types")
- }
- ret[i] = Value{tv.common(), regArgs.Ptrs[steps[0].ireg], flag(tv.Kind())}
- continue
- }
-
- // All that's left is values passed in registers that we need to
- // create space for and copy values back into.
- //
- // TODO(mknyszek): We make a new allocation for each register-allocated
- // value, but previously we could always point into the heap-allocated
- // stack frame. This is a regression that could be fixed by adding
- // additional space to the allocated stack frame and storing the
- // register-allocated return values into the allocated stack frame and
- // referring there in the resulting Value.
- s := unsafe_New(tv.common())
- for _, st := range steps {
- switch st.kind {
- case abiStepIntReg:
- offset := add(s, st.offset, "precomputed value offset")
- intFromReg(&regArgs, st.ireg, st.size, offset)
- case abiStepPointer:
- s := add(s, st.offset, "precomputed value offset")
- *((*unsafe.Pointer)(s)) = regArgs.Ptrs[st.ireg]
- case abiStepFloatReg:
- offset := add(s, st.offset, "precomputed value offset")
- floatFromReg(&regArgs, st.freg, st.size, offset)
- case abiStepStack:
- panic("register-based return value has stack component")
- default:
- panic("unknown ABI part kind")
- }
- }
- ret[i] = Value{tv.common(), s, flagIndir | flag(tv.Kind())}
- }
- }
-
- return ret
-}
-
-// callReflect is the call implementation used by a function
-// returned by MakeFunc. In many ways it is the opposite of the
-// method Value.call above. The method above converts a call using Values
-// into a call of a function with a concrete argument frame, while
-// callReflect converts a call of a function with a concrete argument
-// frame into a call using Values.
-// It is in this file so that it can be next to the call method above.
-// The remainder of the MakeFunc implementation is in makefunc.go.
-//
-// NOTE: This function must be marked as a "wrapper" in the generated code,
-// so that the linker can make it work correctly for panic and recover.
-// The gc compilers know to do that for the name "reflect.callReflect".
-//
-// ctxt is the "closure" generated by MakeFunc.
-// frame is a pointer to the arguments to that closure on the stack.
-// retValid points to a boolean which should be set when the results
-// section of frame is set.
-//
-// regs contains the argument values passed in registers and will contain
-// the values returned from ctxt.fn in registers.
-func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer, retValid *bool, regs *abi.RegArgs) {
- if callGC {
- // Call GC upon entry during testing.
- // Getting our stack scanned here is the biggest hazard, because
- // our caller (makeFuncStub) could have failed to place the last
- // pointer to a value in regs' pointer space, in which case it
- // won't be visible to the GC.
- runtime.GC()
- }
- ftyp := ctxt.ftyp
- f := ctxt.fn
-
- _, _, abid := funcLayout(ftyp, nil)
-
- // Copy arguments into Values.
- ptr := frame
- in := make([]Value, 0, int(ftyp.inCount))
- for i, typ := range ftyp.in() {
- if typ.Size() == 0 {
- in = append(in, Zero(typ))
- continue
- }
- v := Value{typ, nil, flag(typ.Kind())}
- steps := abid.call.stepsForValue(i)
- if st := steps[0]; st.kind == abiStepStack {
- if ifaceIndir(typ) {
- // value cannot be inlined in interface data.
- // Must make a copy, because f might keep a reference to it,
- // and we cannot let f keep a reference to the stack frame
- // after this function returns, not even a read-only reference.
- v.ptr = unsafe_New(typ)
- if typ.size > 0 {
- typedmemmove(typ, v.ptr, add(ptr, st.stkOff, "typ.size > 0"))
- }
- v.flag |= flagIndir
- } else {
- v.ptr = *(*unsafe.Pointer)(add(ptr, st.stkOff, "1-ptr"))
- }
- } else {
- if ifaceIndir(typ) {
- // All that's left is values passed in registers that we need to
- // create space for the values.
- v.flag |= flagIndir
- v.ptr = unsafe_New(typ)
- for _, st := range steps {
- switch st.kind {
- case abiStepIntReg:
- offset := add(v.ptr, st.offset, "precomputed value offset")
- intFromReg(regs, st.ireg, st.size, offset)
- case abiStepPointer:
- s := add(v.ptr, st.offset, "precomputed value offset")
- *((*unsafe.Pointer)(s)) = regs.Ptrs[st.ireg]
- case abiStepFloatReg:
- offset := add(v.ptr, st.offset, "precomputed value offset")
- floatFromReg(regs, st.freg, st.size, offset)
- case abiStepStack:
- panic("register-based return value has stack component")
- default:
- panic("unknown ABI part kind")
- }
- }
- } else {
- // Pointer-valued data gets put directly
- // into v.ptr.
- if steps[0].kind != abiStepPointer {
- print("kind=", steps[0].kind, ", type=", typ.String(), "\n")
- panic("mismatch between ABI description and types")
- }
- v.ptr = regs.Ptrs[steps[0].ireg]
- }
- }
- in = append(in, v)
- }
-
- // Call underlying function.
- out := f(in)
- numOut := ftyp.NumOut()
- if len(out) != numOut {
- panic("reflect: wrong return count from function created by MakeFunc")
- }
-
- // Copy results back into argument frame and register space.
- if numOut > 0 {
- for i, typ := range ftyp.out() {
- v := out[i]
- if v.typ == nil {
- panic("reflect: function created by MakeFunc using " + funcName(f) +
- " returned zero Value")
- }
- if v.flag&flagRO != 0 {
- panic("reflect: function created by MakeFunc using " + funcName(f) +
- " returned value obtained from unexported field")
- }
- if typ.size == 0 {
- continue
- }
-
- // Convert v to type typ if v is assignable to a variable
- // of type t in the language spec.
- // See issue 28761.
- //
- //
- // TODO(mknyszek): In the switch to the register ABI we lost
- // the scratch space here for the register cases (and
- // temporarily for all the cases).
- //
- // If/when this happens, take note of the following:
- //
- // We must clear the destination before calling assignTo,
- // in case assignTo writes (with memory barriers) to the
- // target location used as scratch space. See issue 39541.
- v = v.assignTo("reflect.MakeFunc", typ, nil)
- stepsLoop:
- for _, st := range abid.ret.stepsForValue(i) {
- switch st.kind {
- case abiStepStack:
- // Copy values to the "stack."
- addr := add(ptr, st.stkOff, "precomputed stack arg offset")
- // Do not use write barriers. The stack space used
- // for this call is not adequately zeroed, and we
- // are careful to keep the arguments alive until we
- // return to makeFuncStub's caller.
- if v.flag&flagIndir != 0 {
- memmove(addr, v.ptr, st.size)
- } else {
- // This case must be a pointer type.
- *(*uintptr)(addr) = uintptr(v.ptr)
- }
- // There's only one step for a stack-allocated value.
- break stepsLoop
- case abiStepIntReg, abiStepPointer:
- // Copy values to "integer registers."
- if v.flag&flagIndir != 0 {
- offset := add(v.ptr, st.offset, "precomputed value offset")
- intToReg(regs, st.ireg, st.size, offset)
- } else {
- // Only populate the Ints space on the return path.
- // This is safe because out is kept alive until the
- // end of this function, and the return path through
- // makeFuncStub has no preemption, so these pointers
- // are always visible to the GC.
- regs.Ints[st.ireg] = uintptr(v.ptr)
- }
- case abiStepFloatReg:
- // Copy values to "float registers."
- if v.flag&flagIndir == 0 {
- panic("attempted to copy pointer to FP register")
- }
- offset := add(v.ptr, st.offset, "precomputed value offset")
- floatToReg(regs, st.freg, st.size, offset)
- default:
- panic("unknown ABI part kind")
- }
- }
- }
- }
-
- // Announce that the return values are valid.
- // After this point the runtime can depend on the return values being valid.
- *retValid = true
-
- // We have to make sure that the out slice lives at least until
- // the runtime knows the return values are valid. Otherwise, the
- // return values might not be scanned by anyone during a GC.
- // (out would be dead, and the return slots not yet alive.)
- runtime.KeepAlive(out)
-
- // runtime.getArgInfo expects to be able to find ctxt on the
- // stack when it finds our caller, makeFuncStub. Make sure it
- // doesn't get garbage collected.
- runtime.KeepAlive(ctxt)
-}
-
-// methodReceiver returns information about the receiver
-// described by v. The Value v may or may not have the
-// flagMethod bit set, so the kind cached in v.flag should
-// not be used.
-// The return value rcvrtype gives the method's actual receiver type.
-// The return value t gives the method type signature (without the receiver).
-// The return value fn is a pointer to the method code.
-func methodReceiver(op string, v Value, methodIndex int) (rcvrtype *rtype, t *funcType, fn unsafe.Pointer) {
- i := methodIndex
- if v.typ.Kind() == Interface {
- tt := (*interfaceType)(unsafe.Pointer(v.typ))
- if uint(i) >= uint(len(tt.methods)) {
- panic("reflect: internal error: invalid method index")
- }
- m := &tt.methods[i]
- if !tt.nameOff(m.name).isExported() {
- panic("reflect: " + op + " of unexported method")
- }
- iface := (*nonEmptyInterface)(v.ptr)
- if iface.itab == nil {
- panic("reflect: " + op + " of method on nil interface value")
- }
- rcvrtype = iface.itab.typ
- fn = unsafe.Pointer(&iface.itab.fun[i])
- t = (*funcType)(unsafe.Pointer(tt.typeOff(m.typ)))
- } else {
- rcvrtype = v.typ
- ms := v.typ.exportedMethods()
- if uint(i) >= uint(len(ms)) {
- panic("reflect: internal error: invalid method index")
- }
- m := ms[i]
- if !v.typ.nameOff(m.name).isExported() {
- panic("reflect: " + op + " of unexported method")
- }
- ifn := v.typ.textOff(m.ifn)
- fn = unsafe.Pointer(&ifn)
- t = (*funcType)(unsafe.Pointer(v.typ.typeOff(m.mtyp)))
- }
- return
-}
-
-// v is a method receiver. Store at p the word which is used to
-// encode that receiver at the start of the argument list.
-// Reflect uses the "interface" calling convention for
-// methods, which always uses one word to record the receiver.
-func storeRcvr(v Value, p unsafe.Pointer) {
- t := v.typ
- if t.Kind() == Interface {
- // the interface data word becomes the receiver word
- iface := (*nonEmptyInterface)(v.ptr)
- *(*unsafe.Pointer)(p) = iface.word
- } else if v.flag&flagIndir != 0 && !ifaceIndir(t) {
- *(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
- } else {
- *(*unsafe.Pointer)(p) = v.ptr
- }
-}
-
-// align returns the result of rounding x up to a multiple of n.
-// n must be a power of two.
-func align(x, n uintptr) uintptr {
- return (x + n - 1) &^ (n - 1)
-}
-
-// callMethod is the call implementation used by a function returned
-// by makeMethodValue (used by v.Method(i).Interface()).
-// It is a streamlined version of the usual reflect call: the caller has
-// already laid out the argument frame for us, so we don't have
-// to deal with individual Values for each argument.
-// It is in this file so that it can be next to the two similar functions above.
-// The remainder of the makeMethodValue implementation is in makefunc.go.
-//
-// NOTE: This function must be marked as a "wrapper" in the generated code,
-// so that the linker can make it work correctly for panic and recover.
-// The gc compilers know to do that for the name "reflect.callMethod".
-//
-// ctxt is the "closure" generated by makeVethodValue.
-// frame is a pointer to the arguments to that closure on the stack.
-// retValid points to a boolean which should be set when the results
-// section of frame is set.
-//
-// regs contains the argument values passed in registers and will contain
-// the values returned from ctxt.fn in registers.
-func callMethod(ctxt *methodValue, frame unsafe.Pointer, retValid *bool, regs *abi.RegArgs) {
- rcvr := ctxt.rcvr
- rcvrType, valueFuncType, methodFn := methodReceiver("call", rcvr, ctxt.method)
-
- // There are two ABIs at play here.
- //
- // methodValueCall was invoked with the ABI assuming there was no
- // receiver ("value ABI") and that's what frame and regs are holding.
- //
- // Meanwhile, we need to actually call the method with a receiver, which
- // has its own ABI ("method ABI"). Everything that follows is a translation
- // between the two.
- _, _, valueABI := funcLayout(valueFuncType, nil)
- valueFrame, valueRegs := frame, regs
- methodFrameType, methodFramePool, methodABI := funcLayout(valueFuncType, rcvrType)
-
- // Make a new frame that is one word bigger so we can store the receiver.
- // This space is used for both arguments and return values.
- methodFrame := methodFramePool.Get().(unsafe.Pointer)
- var methodRegs abi.RegArgs
-
- // Deal with the receiver. It's guaranteed to only be one word in size.
- switch st := methodABI.call.steps[0]; st.kind {
- case abiStepStack:
- // Only copy the receiver to the stack if the ABI says so.
- // Otherwise, it'll be in a register already.
- storeRcvr(rcvr, methodFrame)
- case abiStepPointer:
- // Put the receiver in a register.
- storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ptrs[st.ireg]))
- fallthrough
- case abiStepIntReg:
- storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ints[st.ireg]))
- case abiStepFloatReg:
- storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Floats[st.freg]))
- default:
- panic("unknown ABI parameter kind")
- }
-
- // Translate the rest of the arguments.
- for i, t := range valueFuncType.in() {
- valueSteps := valueABI.call.stepsForValue(i)
- methodSteps := methodABI.call.stepsForValue(i + 1)
-
- // Zero-sized types are trivial: nothing to do.
- if len(valueSteps) == 0 {
- if len(methodSteps) != 0 {
- panic("method ABI and value ABI do not align")
- }
- continue
- }
-
- // There are four cases to handle in translating each
- // argument:
- // 1. Stack -> stack translation.
- // 2. Stack -> registers translation.
- // 3. Registers -> stack translation.
- // 4. Registers -> registers translation.
-
- // If the value ABI passes the value on the stack,
- // then the method ABI does too, because it has strictly
- // fewer arguments. Simply copy between the two.
- if vStep := valueSteps[0]; vStep.kind == abiStepStack {
- mStep := methodSteps[0]
- // Handle stack -> stack translation.
- if mStep.kind == abiStepStack {
- if vStep.size != mStep.size {
- panic("method ABI and value ABI do not align")
- }
- typedmemmove(t,
- add(methodFrame, mStep.stkOff, "precomputed stack offset"),
- add(valueFrame, vStep.stkOff, "precomputed stack offset"))
- continue
- }
- // Handle stack -> register translation.
- for _, mStep := range methodSteps {
- from := add(valueFrame, vStep.stkOff+mStep.offset, "precomputed stack offset")
- switch mStep.kind {
- case abiStepPointer:
- // Do the pointer copy directly so we get a write barrier.
- methodRegs.Ptrs[mStep.ireg] = *(*unsafe.Pointer)(from)
- fallthrough // We need to make sure this ends up in Ints, too.
- case abiStepIntReg:
- intToReg(&methodRegs, mStep.ireg, mStep.size, from)
- case abiStepFloatReg:
- floatToReg(&methodRegs, mStep.freg, mStep.size, from)
- default:
- panic("unexpected method step")
- }
- }
- continue
- }
- // Handle register -> stack translation.
- if mStep := methodSteps[0]; mStep.kind == abiStepStack {
- for _, vStep := range valueSteps {
- to := add(methodFrame, mStep.stkOff+vStep.offset, "precomputed stack offset")
- switch vStep.kind {
- case abiStepPointer:
- // Do the pointer copy directly so we get a write barrier.
- *(*unsafe.Pointer)(to) = valueRegs.Ptrs[vStep.ireg]
- case abiStepIntReg:
- intFromReg(valueRegs, vStep.ireg, vStep.size, to)
- case abiStepFloatReg:
- floatFromReg(valueRegs, vStep.freg, vStep.size, to)
- default:
- panic("unexpected value step")
- }
- }
- continue
- }
- // Handle register -> register translation.
- if len(valueSteps) != len(methodSteps) {
- // Because it's the same type for the value, and it's assigned
- // to registers both times, it should always take up the same
- // number of registers for each ABI.
- panic("method ABI and value ABI don't align")
- }
- for i, vStep := range valueSteps {
- mStep := methodSteps[i]
- if mStep.kind != vStep.kind {
- panic("method ABI and value ABI don't align")
- }
- switch vStep.kind {
- case abiStepPointer:
- // Copy this too, so we get a write barrier.
- methodRegs.Ptrs[mStep.ireg] = valueRegs.Ptrs[vStep.ireg]
- fallthrough
- case abiStepIntReg:
- methodRegs.Ints[mStep.ireg] = valueRegs.Ints[vStep.ireg]
- case abiStepFloatReg:
- methodRegs.Floats[mStep.freg] = valueRegs.Floats[vStep.freg]
- default:
- panic("unexpected value step")
- }
- }
- }
-
- methodFrameSize := methodFrameType.size
- // TODO(mknyszek): Remove this when we no longer have
- // caller reserved spill space.
- methodFrameSize = align(methodFrameSize, goarch.PtrSize)
- methodFrameSize += methodABI.spill
-
- // Mark pointers in registers for the return path.
- methodRegs.ReturnIsPtr = methodABI.outRegPtrs
-
- // Call.
- // Call copies the arguments from scratch to the stack, calls fn,
- // and then copies the results back into scratch.
- call(methodFrameType, methodFn, methodFrame, uint32(methodFrameType.size), uint32(methodABI.retOffset), uint32(methodFrameSize), &methodRegs)
-
- // Copy return values.
- //
- // This is somewhat simpler because both ABIs have an identical
- // return value ABI (the types are identical). As a result, register
- // results can simply be copied over. Stack-allocated values are laid
- // out the same, but are at different offsets from the start of the frame
- // Ignore any changes to args.
- // Avoid constructing out-of-bounds pointers if there are no return values.
- // because the arguments may be laid out differently.
- if valueRegs != nil {
- *valueRegs = methodRegs
- }
- if retSize := methodFrameType.size - methodABI.retOffset; retSize > 0 {
- valueRet := add(valueFrame, valueABI.retOffset, "valueFrame's size > retOffset")
- methodRet := add(methodFrame, methodABI.retOffset, "methodFrame's size > retOffset")
- // This copies to the stack. Write barriers are not needed.
- memmove(valueRet, methodRet, retSize)
- }
-
- // Tell the runtime it can now depend on the return values
- // being properly initialized.
- *retValid = true
-
- // Clear the scratch space and put it back in the pool.
- // This must happen after the statement above, so that the return
- // values will always be scanned by someone.
- typedmemclr(methodFrameType, methodFrame)
- methodFramePool.Put(methodFrame)
-
- // See the comment in callReflect.
- runtime.KeepAlive(ctxt)
-
- // Keep valueRegs alive because it may hold live pointer results.
- // The caller (methodValueCall) has it as a stack object, which is only
- // scanned when there is a reference to it.
- runtime.KeepAlive(valueRegs)
-}
-
-// funcName returns the name of f, for use in error messages.
-func funcName(f func([]Value) []Value) string {
- pc := *(*uintptr)(unsafe.Pointer(&f))
- rf := runtime.FuncForPC(pc)
- if rf != nil {
- return rf.Name()
- }
- return "closure"
-}
-
-// Cap returns v's capacity.
-// It panics if v's Kind is not Array, Chan, Slice or pointer to Array.
-func (v Value) Cap() int {
- // capNonSlice is split out to keep Cap inlineable for slice kinds.
- if v.kind() == Slice {
- return (*unsafeheader.Slice)(v.ptr).Cap
- }
- return v.capNonSlice()
-}
-
-func (v Value) capNonSlice() int {
- k := v.kind()
- switch k {
- case Array:
- return v.typ.Len()
- case Chan:
- return chancap(v.pointer())
- case Ptr:
- if v.typ.Elem().Kind() == Array {
- return v.typ.Elem().Len()
- }
- panic("reflect: call of reflect.Value.Cap on ptr to non-array Value")
- }
- panic(&ValueError{"reflect.Value.Cap", v.kind()})
-}
-
-// Close closes the channel v.
-// It panics if v's Kind is not Chan.
-func (v Value) Close() {
- v.mustBe(Chan)
- v.mustBeExported()
- chanclose(v.pointer())
-}
-
-// CanComplex reports whether Complex can be used without panicking.
-func (v Value) CanComplex() bool {
- switch v.kind() {
- case Complex64, Complex128:
- return true
- default:
- return false
- }
-}
-
-// Complex returns v's underlying value, as a complex128.
-// It panics if v's Kind is not Complex64 or Complex128
-func (v Value) Complex() complex128 {
- k := v.kind()
- switch k {
- case Complex64:
- return complex128(*(*complex64)(v.ptr))
- case Complex128:
- return *(*complex128)(v.ptr)
- }
- panic(&ValueError{"reflect.Value.Complex", v.kind()})
-}
-
-// Elem returns the value that the interface v contains
-// or that the pointer v points to.
-// It panics if v's Kind is not Interface or Pointer.
-// It returns the zero Value if v is nil.
-func (v Value) Elem() Value {
- k := v.kind()
- switch k {
- case Interface:
- var eface any
- if v.typ.NumMethod() == 0 {
- eface = *(*any)(v.ptr)
- } else {
- eface = (any)(*(*interface {
- M()
- })(v.ptr))
- }
- x := unpackEface(eface)
- if x.flag != 0 {
- x.flag |= v.flag.ro()
- }
- return x
- case Pointer:
- ptr := v.ptr
- if v.flag&flagIndir != 0 {
- if ifaceIndir(v.typ) {
- // This is a pointer to a not-in-heap object. ptr points to a uintptr
- // in the heap. That uintptr is the address of a not-in-heap object.
- // In general, pointers to not-in-heap objects can be total junk.
- // But Elem() is asking to dereference it, so the user has asserted
- // that at least it is a valid pointer (not just an integer stored in
- // a pointer slot). So let's check, to make sure that it isn't a pointer
- // that the runtime will crash on if it sees it during GC or write barriers.
- // Since it is a not-in-heap pointer, all pointers to the heap are
- // forbidden! That makes the test pretty easy.
- // See issue 48399.
- if !verifyNotInHeapPtr(*(*uintptr)(ptr)) {
- panic("reflect: reflect.Value.Elem on an invalid notinheap pointer")
- }
- }
- ptr = *(*unsafe.Pointer)(ptr)
- }
- // The returned value's address is v's value.
- if ptr == nil {
- return Value{}
- }
- tt := (*ptrType)(unsafe.Pointer(v.typ))
- typ := tt.elem
- fl := v.flag&flagRO | flagIndir | flagAddr
- fl |= flag(typ.Kind())
- return Value{typ, ptr, fl}
- }
- panic(&ValueError{"reflect.Value.Elem", v.kind()})
-}
-
-// Field returns the i'th field of the struct v.
-// It panics if v's Kind is not Struct or i is out of range.
-func (v Value) Field(i int) Value {
- if v.kind() != Struct {
- panic(&ValueError{"reflect.Value.Field", v.kind()})
- }
- tt := (*structType)(unsafe.Pointer(v.typ))
- if uint(i) >= uint(len(tt.fields)) {
- panic("reflect: Field index out of range")
- }
- field := &tt.fields[i]
- typ := field.typ
-
- // Inherit permission bits from v, but clear flagEmbedRO.
- fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
- // Using an unexported field forces flagRO.
- if !field.name.isExported() {
- if field.embedded() {
- fl |= flagEmbedRO
- } else {
- fl |= flagStickyRO
- }
- }
- // Either flagIndir is set and v.ptr points at struct,
- // or flagIndir is not set and v.ptr is the actual struct data.
- // In the former case, we want v.ptr + offset.
- // In the latter case, we must have field.offset = 0,
- // so v.ptr + field.offset is still the correct address.
- ptr := add(v.ptr, field.offset, "same as non-reflect &v.field")
- return Value{typ, ptr, fl}
-}
-
-// FieldByIndex returns the nested field corresponding to index.
-// It panics if evaluation requires stepping through a nil
-// pointer or a field that is not a struct.
-func (v Value) FieldByIndex(index []int) Value {
- if len(index) == 1 {
- return v.Field(index[0])
- }
- v.mustBe(Struct)
- for i, x := range index {
- if i > 0 {
- if v.Kind() == Pointer && v.typ.Elem().Kind() == Struct {
- if v.IsNil() {
- panic("reflect: indirection through nil pointer to embedded struct")
- }
- v = v.Elem()
- }
- }
- v = v.Field(x)
- }
- return v
-}
-
-// FieldByIndexErr returns the nested field corresponding to index.
-// It returns an error if evaluation requires stepping through a nil
-// pointer, but panics if it must step through a field that
-// is not a struct.
-func (v Value) FieldByIndexErr(index []int) (Value, error) {
- if len(index) == 1 {
- return v.Field(index[0]), nil
- }
- v.mustBe(Struct)
- for i, x := range index {
- if i > 0 {
- if v.Kind() == Ptr && v.typ.Elem().Kind() == Struct {
- if v.IsNil() {
- return Value{}, errors.New("reflect: indirection through nil pointer to embedded struct field " + v.typ.Elem().Name())
- }
- v = v.Elem()
- }
- }
- v = v.Field(x)
- }
- return v, nil
-}
-
-// FieldByName returns the struct field with the given name.
-// It returns the zero Value if no field was found.
-// It panics if v's Kind is not struct.
-func (v Value) FieldByName(name string) Value {
- v.mustBe(Struct)
- if f, ok := v.typ.FieldByName(name); ok {
- return v.FieldByIndex(f.Index)
- }
- return Value{}
-}
-
-// FieldByNameFunc returns the struct field with a name
-// that satisfies the match function.
-// It panics if v's Kind is not struct.
-// It returns the zero Value if no field was found.
-func (v Value) FieldByNameFunc(match func(string) bool) Value {
- if f, ok := v.typ.FieldByNameFunc(match); ok {
- return v.FieldByIndex(f.Index)
- }
- return Value{}
-}
-
-// CanFloat reports whether Float can be used without panicking.
-func (v Value) CanFloat() bool {
- switch v.kind() {
- case Float32, Float64:
- return true
- default:
- return false
- }
-}
-
-// Float returns v's underlying value, as a float64.
-// It panics if v's Kind is not Float32 or Float64
-func (v Value) Float() float64 {
- k := v.kind()
- switch k {
- case Float32:
- return float64(*(*float32)(v.ptr))
- case Float64:
- return *(*float64)(v.ptr)
- }
- panic(&ValueError{"reflect.Value.Float", v.kind()})
-}
-
-var uint8Type = rtypeOf(uint8(0))
-
-// Index returns v's i'th element.
-// It panics if v's Kind is not Array, Slice, or String or i is out of range.
-func (v Value) Index(i int) Value {
- switch v.kind() {
- case Array:
- tt := (*arrayType)(unsafe.Pointer(v.typ))
- if uint(i) >= uint(tt.len) {
- panic("reflect: array index out of range")
- }
- typ := tt.elem
- offset := uintptr(i) * typ.size
-
- // Either flagIndir is set and v.ptr points at array,
- // or flagIndir is not set and v.ptr is the actual array data.
- // In the former case, we want v.ptr + offset.
- // In the latter case, we must be doing Index(0), so offset = 0,
- // so v.ptr + offset is still the correct address.
- val := add(v.ptr, offset, "same as &v[i], i < tt.len")
- fl := v.flag&(flagIndir|flagAddr) | v.flag.ro() | flag(typ.Kind()) // bits same as overall array
- return Value{typ, val, fl}
-
- case Slice:
- // Element flag same as Elem of Pointer.
- // Addressable, indirect, possibly read-only.
- s := (*unsafeheader.Slice)(v.ptr)
- if uint(i) >= uint(s.Len) {
- panic("reflect: slice index out of range")
- }
- tt := (*sliceType)(unsafe.Pointer(v.typ))
- typ := tt.elem
- val := arrayAt(s.Data, i, typ.size, "i < s.Len")
- fl := flagAddr | flagIndir | v.flag.ro() | flag(typ.Kind())
- return Value{typ, val, fl}
-
- case String:
- s := (*unsafeheader.String)(v.ptr)
- if uint(i) >= uint(s.Len) {
- panic("reflect: string index out of range")
- }
- p := arrayAt(s.Data, i, 1, "i < s.Len")
- fl := v.flag.ro() | flag(Uint8) | flagIndir
- return Value{uint8Type, p, fl}
- }
- panic(&ValueError{"reflect.Value.Index", v.kind()})
-}
-
-// CanInt reports whether Int can be used without panicking.
-func (v Value) CanInt() bool {
- switch v.kind() {
- case Int, Int8, Int16, Int32, Int64:
- return true
- default:
- return false
- }
-}
-
-// Int returns v's underlying value, as an int64.
-// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.
-func (v Value) Int() int64 {
- k := v.kind()
- p := v.ptr
- switch k {
- case Int:
- return int64(*(*int)(p))
- case Int8:
- return int64(*(*int8)(p))
- case Int16:
- return int64(*(*int16)(p))
- case Int32:
- return int64(*(*int32)(p))
- case Int64:
- return *(*int64)(p)
- }
- panic(&ValueError{"reflect.Value.Int", v.kind()})
-}
-
-// CanInterface reports whether Interface can be used without panicking.
-func (v Value) CanInterface() bool {
- if v.flag == 0 {
- panic(&ValueError{"reflect.Value.CanInterface", Invalid})
- }
- return v.flag&flagRO == 0
-}
-
-// Interface returns v's current value as an interface{}.
-// It is equivalent to:
-//
-// var i interface{} = (v's underlying value)
-//
-// It panics if the Value was obtained by accessing
-// unexported struct fields.
-func (v Value) Interface() (i any) {
- return valueInterface(v, true)
-}
-
-func valueInterface(v Value, safe bool) any {
- if v.flag == 0 {
- panic(&ValueError{"reflect.Value.Interface", Invalid})
- }
- if safe && v.flag&flagRO != 0 {
- // Do not allow access to unexported values via Interface,
- // because they might be pointers that should not be
- // writable or methods or function that should not be callable.
- panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
- }
- if v.flag&flagMethod != 0 {
- v = makeMethodValue("Interface", v)
- }
-
- if v.kind() == Interface {
- // Special case: return the element inside the interface.
- // Empty interface has one layout, all interfaces with
- // methods have a second layout.
- if v.NumMethod() == 0 {
- return *(*any)(v.ptr)
- }
- return *(*interface {
- M()
- })(v.ptr)
- }
-
- // TODO: pass safe to packEface so we don't need to copy if safe==true?
- return packEface(v)
-}
-
-// InterfaceData returns a pair of unspecified uintptr values.
-// It panics if v's Kind is not Interface.
-//
-// In earlier versions of Go, this function returned the interface's
-// value as a uintptr pair. As of Go 1.4, the implementation of
-// interface values precludes any defined use of InterfaceData.
-//
-// Deprecated: The memory representation of interface values is not
-// compatible with InterfaceData.
-func (v Value) InterfaceData() [2]uintptr {
- v.mustBe(Interface)
- // We treat this as a read operation, so we allow
- // it even for unexported data, because the caller
- // has to import "unsafe" to turn it into something
- // that can be abused.
- // Interface value is always bigger than a word; assume flagIndir.
- return *(*[2]uintptr)(v.ptr)
-}
-
-// IsNil reports whether its argument v is nil. The argument must be
-// a chan, func, interface, map, pointer, or slice value; if it is
-// not, IsNil panics. Note that IsNil is not always equivalent to a
-// regular comparison with nil in Go. For example, if v was created
-// by calling ValueOf with an uninitialized interface variable i,
-// i==nil will be true but v.IsNil will panic as v will be the zero
-// Value.
-func (v Value) IsNil() bool {
- k := v.kind()
- switch k {
- case Chan, Func, Map, Pointer, UnsafePointer:
- if v.flag&flagMethod != 0 {
- return false
- }
- ptr := v.ptr
- if v.flag&flagIndir != 0 {
- ptr = *(*unsafe.Pointer)(ptr)
- }
- return ptr == nil
- case Interface, Slice:
- // Both interface and slice are nil if first word is 0.
- // Both are always bigger than a word; assume flagIndir.
- return *(*unsafe.Pointer)(v.ptr) == nil
- }
- panic(&ValueError{"reflect.Value.IsNil", v.kind()})
-}
-
-// IsValid reports whether v represents a value.
-// It returns false if v is the zero Value.
-// If IsValid returns false, all other methods except String panic.
-// Most functions and methods never return an invalid Value.
-// If one does, its documentation states the conditions explicitly.
-func (v Value) IsValid() bool {
- return v.flag != 0
-}
-
-// IsZero reports whether v is the zero value for its type.
-// It panics if the argument is invalid.
-func (v Value) IsZero() bool {
- switch v.kind() {
- case Bool:
- return !v.Bool()
- case Int, Int8, Int16, Int32, Int64:
- return v.Int() == 0
- case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
- return v.Uint() == 0
- case Float32, Float64:
- return math.Float64bits(v.Float()) == 0
- case Complex64, Complex128:
- c := v.Complex()
- return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
- case Array:
- // If the type is comparable, then compare directly with zero.
- if v.typ.equal != nil && v.typ.size <= maxZero {
- if v.flag&flagIndir == 0 {
- return v.ptr == nil
- }
- return v.typ.equal(v.ptr, unsafe.Pointer(&zeroVal[0]))
- }
-
- n := v.Len()
- for i := 0; i < n; i++ {
- if !v.Index(i).IsZero() {
- return false
- }
- }
- return true
- case Chan, Func, Interface, Map, Pointer, Slice, UnsafePointer:
- return v.IsNil()
- case String:
- return v.Len() == 0
- case Struct:
- // If the type is comparable, then compare directly with zero.
- if v.typ.equal != nil && v.typ.size <= maxZero {
- if v.flag&flagIndir == 0 {
- return v.ptr == nil
- }
- return v.typ.equal(v.ptr, unsafe.Pointer(&zeroVal[0]))
- }
-
- n := v.NumField()
- for i := 0; i < n; i++ {
- if !v.Field(i).IsZero() {
- return false
- }
- }
- return true
- default:
- // This should never happen, but will act as a safeguard for later,
- // as a default value doesn't makes sense here.
- panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
- }
-}
-
-// SetZero sets v to be the zero value of v's type.
-// It panics if CanSet returns false.
-func (v Value) SetZero() {
- v.mustBeAssignable()
- switch v.kind() {
- case Bool:
- *(*bool)(v.ptr) = false
- case Int:
- *(*int)(v.ptr) = 0
- case Int8:
- *(*int8)(v.ptr) = 0
- case Int16:
- *(*int16)(v.ptr) = 0
- case Int32:
- *(*int32)(v.ptr) = 0
- case Int64:
- *(*int64)(v.ptr) = 0
- case Uint:
- *(*uint)(v.ptr) = 0
- case Uint8:
- *(*uint8)(v.ptr) = 0
- case Uint16:
- *(*uint16)(v.ptr) = 0
- case Uint32:
- *(*uint32)(v.ptr) = 0
- case Uint64:
- *(*uint64)(v.ptr) = 0
- case Uintptr:
- *(*uintptr)(v.ptr) = 0
- case Float32:
- *(*float32)(v.ptr) = 0
- case Float64:
- *(*float64)(v.ptr) = 0
- case Complex64:
- *(*complex64)(v.ptr) = 0
- case Complex128:
- *(*complex128)(v.ptr) = 0
- case String:
- *(*string)(v.ptr) = ""
- case Slice:
- *(*unsafeheader.Slice)(v.ptr) = unsafeheader.Slice{}
- case Interface:
- *(*[2]unsafe.Pointer)(v.ptr) = [2]unsafe.Pointer{}
- case Chan, Func, Map, Pointer, UnsafePointer:
- *(*unsafe.Pointer)(v.ptr) = nil
- case Array, Struct:
- typedmemclr(v.typ, v.ptr)
- default:
- // This should never happen, but will act as a safeguard for later,
- // as a default value doesn't makes sense here.
- panic(&ValueError{"reflect.Value.SetZero", v.Kind()})
- }
-}
-
-// Kind returns v's Kind.
-// If v is the zero Value (IsValid returns false), Kind returns Invalid.
-func (v Value) Kind() Kind {
- return v.kind()
-}
-
-// Len returns v's length.
-// It panics if v's Kind is not Array, Chan, Map, Slice, String, or pointer to Array.
-func (v Value) Len() int {
- // lenNonSlice is split out to keep Len inlineable for slice kinds.
- if v.kind() == Slice {
- return (*unsafeheader.Slice)(v.ptr).Len
- }
- return v.lenNonSlice()
-}
-
-func (v Value) lenNonSlice() int {
- switch k := v.kind(); k {
- case Array:
- tt := (*arrayType)(unsafe.Pointer(v.typ))
- return int(tt.len)
- case Chan:
- return chanlen(v.pointer())
- case Map:
- return maplen(v.pointer())
- case String:
- // String is bigger than a word; assume flagIndir.
- return (*unsafeheader.String)(v.ptr).Len
- case Ptr:
- if v.typ.Elem().Kind() == Array {
- return v.typ.Elem().Len()
- }
- panic("reflect: call of reflect.Value.Len on ptr to non-array Value")
- }
- panic(&ValueError{"reflect.Value.Len", v.kind()})
-}
-
-var stringType = rtypeOf("")
-
-// MapIndex returns the value associated with key in the map v.
-// It panics if v's Kind is not Map.
-// It returns the zero Value if key is not found in the map or if v represents a nil map.
-// As in Go, the key's value must be assignable to the map's key type.
-func (v Value) MapIndex(key Value) Value {
- v.mustBe(Map)
- tt := (*mapType)(unsafe.Pointer(v.typ))
-
- // Do not require key to be exported, so that DeepEqual
- // and other programs can use all the keys returned by
- // MapKeys as arguments to MapIndex. If either the map
- // or the key is unexported, though, the result will be
- // considered unexported. This is consistent with the
- // behavior for structs, which allow read but not write
- // of unexported fields.
-
- var e unsafe.Pointer
- if (tt.key == stringType || key.kind() == String) && tt.key == key.typ && tt.elem.size <= maxValSize {
- k := *(*string)(key.ptr)
- e = mapaccess_faststr(v.typ, v.pointer(), k)
- } else {
- key = key.assignTo("reflect.Value.MapIndex", tt.key, nil)
- var k unsafe.Pointer
- if key.flag&flagIndir != 0 {
- k = key.ptr
- } else {
- k = unsafe.Pointer(&key.ptr)
- }
- e = mapaccess(v.typ, v.pointer(), k)
- }
- if e == nil {
- return Value{}
- }
- typ := tt.elem
- fl := (v.flag | key.flag).ro()
- fl |= flag(typ.Kind())
- return copyVal(typ, fl, e)
-}
-
-// MapKeys returns a slice containing all the keys present in the map,
-// in unspecified order.
-// It panics if v's Kind is not Map.
-// It returns an empty slice if v represents a nil map.
-func (v Value) MapKeys() []Value {
- v.mustBe(Map)
- tt := (*mapType)(unsafe.Pointer(v.typ))
- keyType := tt.key
-
- fl := v.flag.ro() | flag(keyType.Kind())
-
- m := v.pointer()
- mlen := int(0)
- if m != nil {
- mlen = maplen(m)
- }
- var it hiter
- mapiterinit(v.typ, m, &it)
- a := make([]Value, mlen)
- var i int
- for i = 0; i < len(a); i++ {
- key := mapiterkey(&it)
- if key == nil {
- // Someone deleted an entry from the map since we
- // called maplen above. It's a data race, but nothing
- // we can do about it.
- break
- }
- a[i] = copyVal(keyType, fl, key)
- mapiternext(&it)
- }
- return a[:i]
-}
-
-// hiter's structure matches runtime.hiter's structure.
-// Having a clone here allows us to embed a map iterator
-// inside type MapIter so that MapIters can be re-used
-// without doing any allocations.
-type hiter struct {
- key unsafe.Pointer
- elem unsafe.Pointer
- t unsafe.Pointer
- h unsafe.Pointer
- buckets unsafe.Pointer
- bptr unsafe.Pointer
- overflow *[]unsafe.Pointer
- oldoverflow *[]unsafe.Pointer
- startBucket uintptr
- offset uint8
- wrapped bool
- B uint8
- i uint8
- bucket uintptr
- checkBucket uintptr
-}
-
-func (h *hiter) initialized() bool {
- return h.t != nil
-}
-
-// A MapIter is an iterator for ranging over a map.
-// See Value.MapRange.
-type MapIter struct {
- m Value
- hiter hiter
-}
-
-// Key returns the key of iter's current map entry.
-func (iter *MapIter) Key() Value {
- if !iter.hiter.initialized() {
- panic("MapIter.Key called before Next")
- }
- iterkey := mapiterkey(&iter.hiter)
- if iterkey == nil {
- panic("MapIter.Key called on exhausted iterator")
- }
-
- t := (*mapType)(unsafe.Pointer(iter.m.typ))
- ktype := t.key
- return copyVal(ktype, iter.m.flag.ro()|flag(ktype.Kind()), iterkey)
-}
-
-// SetIterKey assigns to v the key of iter's current map entry.
-// It is equivalent to v.Set(iter.Key()), but it avoids allocating a new Value.
-// As in Go, the key must be assignable to v's type and
-// must not be derived from an unexported field.
-func (v Value) SetIterKey(iter *MapIter) {
- if !iter.hiter.initialized() {
- panic("reflect: Value.SetIterKey called before Next")
- }
- iterkey := mapiterkey(&iter.hiter)
- if iterkey == nil {
- panic("reflect: Value.SetIterKey called on exhausted iterator")
- }
-
- v.mustBeAssignable()
- var target unsafe.Pointer
- if v.kind() == Interface {
- target = v.ptr
- }
-
- t := (*mapType)(unsafe.Pointer(iter.m.typ))
- ktype := t.key
-
- iter.m.mustBeExported() // do not let unexported m leak
- key := Value{ktype, iterkey, iter.m.flag | flag(ktype.Kind()) | flagIndir}
- key = key.assignTo("reflect.MapIter.SetKey", v.typ, target)
- typedmemmove(v.typ, v.ptr, key.ptr)
-}
-
-// Value returns the value of iter's current map entry.
-func (iter *MapIter) Value() Value {
- if !iter.hiter.initialized() {
- panic("MapIter.Value called before Next")
- }
- iterelem := mapiterelem(&iter.hiter)
- if iterelem == nil {
- panic("MapIter.Value called on exhausted iterator")
- }
-
- t := (*mapType)(unsafe.Pointer(iter.m.typ))
- vtype := t.elem
- return copyVal(vtype, iter.m.flag.ro()|flag(vtype.Kind()), iterelem)
-}
-
-// SetIterValue assigns to v the value of iter's current map entry.
-// It is equivalent to v.Set(iter.Value()), but it avoids allocating a new Value.
-// As in Go, the value must be assignable to v's type and
-// must not be derived from an unexported field.
-func (v Value) SetIterValue(iter *MapIter) {
- if !iter.hiter.initialized() {
- panic("reflect: Value.SetIterValue called before Next")
- }
- iterelem := mapiterelem(&iter.hiter)
- if iterelem == nil {
- panic("reflect: Value.SetIterValue called on exhausted iterator")
- }
-
- v.mustBeAssignable()
- var target unsafe.Pointer
- if v.kind() == Interface {
- target = v.ptr
- }
-
- t := (*mapType)(unsafe.Pointer(iter.m.typ))
- vtype := t.elem
-
- iter.m.mustBeExported() // do not let unexported m leak
- elem := Value{vtype, iterelem, iter.m.flag | flag(vtype.Kind()) | flagIndir}
- elem = elem.assignTo("reflect.MapIter.SetValue", v.typ, target)
- typedmemmove(v.typ, v.ptr, elem.ptr)
-}
-
-// Next advances the map iterator and reports whether there is another
-// entry. It returns false when iter is exhausted; subsequent
-// calls to Key, Value, or Next will panic.
-func (iter *MapIter) Next() bool {
- if !iter.m.IsValid() {
- panic("MapIter.Next called on an iterator that does not have an associated map Value")
- }
- if !iter.hiter.initialized() {
- mapiterinit(iter.m.typ, iter.m.pointer(), &iter.hiter)
- } else {
- if mapiterkey(&iter.hiter) == nil {
- panic("MapIter.Next called on exhausted iterator")
- }
- mapiternext(&iter.hiter)
- }
- return mapiterkey(&iter.hiter) != nil
-}
-
-// Reset modifies iter to iterate over v.
-// It panics if v's Kind is not Map and v is not the zero Value.
-// Reset(Value{}) causes iter to not to refer to any map,
-// which may allow the previously iterated-over map to be garbage collected.
-func (iter *MapIter) Reset(v Value) {
- if v.IsValid() {
- v.mustBe(Map)
- }
- iter.m = v
- iter.hiter = hiter{}
-}
-
-// MapRange returns a range iterator for a map.
-// It panics if v's Kind is not Map.
-//
-// Call Next to advance the iterator, and Key/Value to access each entry.
-// Next returns false when the iterator is exhausted.
-// MapRange follows the same iteration semantics as a range statement.
-//
-// Example:
-//
-// iter := reflect.ValueOf(m).MapRange()
-// for iter.Next() {
-// k := iter.Key()
-// v := iter.Value()
-// ...
-// }
-func (v Value) MapRange() *MapIter {
- // This is inlinable to take advantage of "function outlining".
- // The allocation of MapIter can be stack allocated if the caller
- // does not allow it to escape.
- // See https://blog.filippo.io/efficient-go-apis-with-the-inliner/
- if v.kind() != Map {
- v.panicNotMap()
- }
- return &MapIter{m: v}
-}
-
-func (f flag) panicNotMap() {
- f.mustBe(Map)
-}
-
-// copyVal returns a Value containing the map key or value at ptr,
-// allocating a new variable as needed.
-func copyVal(typ *rtype, fl flag, ptr unsafe.Pointer) Value {
- if ifaceIndir(typ) {
- // Copy result so future changes to the map
- // won't change the underlying value.
- c := unsafe_New(typ)
- typedmemmove(typ, c, ptr)
- return Value{typ, c, fl | flagIndir}
- }
- return Value{typ, *(*unsafe.Pointer)(ptr), fl}
-}
-
-// Method returns a function value corresponding to v's i'th method.
-// The arguments to a Call on the returned function should not include
-// a receiver; the returned function will always use v as the receiver.
-// Method panics if i is out of range or if v is a nil interface value.
-func (v Value) Method(i int) Value {
- if v.typ == nil {
- panic(&ValueError{"reflect.Value.Method", Invalid})
- }
- if v.flag&flagMethod != 0 || uint(i) >= uint(v.typ.NumMethod()) {
- panic("reflect: Method index out of range")
- }
- if v.typ.Kind() == Interface && v.IsNil() {
- panic("reflect: Method on nil interface value")
- }
- fl := v.flag.ro() | (v.flag & flagIndir)
- fl |= flag(Func)
- fl |= flag(i)<<flagMethodShift | flagMethod
- return Value{v.typ, v.ptr, fl}
-}
-
-// NumMethod returns the number of methods in the value's method set.
-//
-// For a non-interface type, it returns the number of exported methods.
-//
-// For an interface type, it returns the number of exported and unexported methods.
-func (v Value) NumMethod() int {
- if v.typ == nil {
- panic(&ValueError{"reflect.Value.NumMethod", Invalid})
- }
- if v.flag&flagMethod != 0 {
- return 0
- }
- return v.typ.NumMethod()
-}
-
-// MethodByName returns a function value corresponding to the method
-// of v with the given name.
-// The arguments to a Call on the returned function should not include
-// a receiver; the returned function will always use v as the receiver.
-// It returns the zero Value if no method was found.
-func (v Value) MethodByName(name string) Value {
- if v.typ == nil {
- panic(&ValueError{"reflect.Value.MethodByName", Invalid})
- }
- if v.flag&flagMethod != 0 {
- return Value{}
- }
- m, ok := v.typ.MethodByName(name)
- if !ok {
- return Value{}
- }
- return v.Method(m.Index)
-}
-
-// NumField returns the number of fields in the struct v.
-// It panics if v's Kind is not Struct.
-func (v Value) NumField() int {
- v.mustBe(Struct)
- tt := (*structType)(unsafe.Pointer(v.typ))
- return len(tt.fields)
-}
-
-// OverflowComplex reports whether the complex128 x cannot be represented by v's type.
-// It panics if v's Kind is not Complex64 or Complex128.
-func (v Value) OverflowComplex(x complex128) bool {
- k := v.kind()
- switch k {
- case Complex64:
- return overflowFloat32(real(x)) || overflowFloat32(imag(x))
- case Complex128:
- return false
- }
- panic(&ValueError{"reflect.Value.OverflowComplex", v.kind()})
-}
-
-// OverflowFloat reports whether the float64 x cannot be represented by v's type.
-// It panics if v's Kind is not Float32 or Float64.
-func (v Value) OverflowFloat(x float64) bool {
- k := v.kind()
- switch k {
- case Float32:
- return overflowFloat32(x)
- case Float64:
- return false
- }
- panic(&ValueError{"reflect.Value.OverflowFloat", v.kind()})
-}
-
-func overflowFloat32(x float64) bool {
- if x < 0 {
- x = -x
- }
- return math.MaxFloat32 < x && x <= math.MaxFloat64
-}
-
-// OverflowInt reports whether the int64 x cannot be represented by v's type.
-// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.
-func (v Value) OverflowInt(x int64) bool {
- k := v.kind()
- switch k {
- case Int, Int8, Int16, Int32, Int64:
- bitSize := v.typ.size * 8
- trunc := (x << (64 - bitSize)) >> (64 - bitSize)
- return x != trunc
- }
- panic(&ValueError{"reflect.Value.OverflowInt", v.kind()})
-}
-
-// OverflowUint reports whether the uint64 x cannot be represented by v's type.
-// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
-func (v Value) OverflowUint(x uint64) bool {
- k := v.kind()
- switch k {
- case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
- bitSize := v.typ.size * 8
- trunc := (x << (64 - bitSize)) >> (64 - bitSize)
- return x != trunc
- }
- panic(&ValueError{"reflect.Value.OverflowUint", v.kind()})
-}
-
-//go:nocheckptr
-// This prevents inlining Value.Pointer when -d=checkptr is enabled,
-// which ensures cmd/compile can recognize unsafe.Pointer(v.Pointer())
-// and make an exception.
-
-// Pointer returns v's value as a uintptr.
-// It panics if v's Kind is not Chan, Func, Map, Pointer, Slice, or UnsafePointer.
-//
-// If v's Kind is Func, the returned pointer is an underlying
-// code pointer, but not necessarily enough to identify a
-// single function uniquely. The only guarantee is that the
-// result is zero if and only if v is a nil func Value.
-//
-// If v's Kind is Slice, the returned pointer is to the first
-// element of the slice. If the slice is nil the returned value
-// is 0. If the slice is empty but non-nil the return value is non-zero.
-//
-// It's preferred to use uintptr(Value.UnsafePointer()) to get the equivalent result.
-func (v Value) Pointer() uintptr {
- k := v.kind()
- switch k {
- case Pointer:
- if v.typ.ptrdata == 0 {
- val := *(*uintptr)(v.ptr)
- // Since it is a not-in-heap pointer, all pointers to the heap are
- // forbidden! See comment in Value.Elem and issue #48399.
- if !verifyNotInHeapPtr(val) {
- panic("reflect: reflect.Value.Pointer on an invalid notinheap pointer")
- }
- return val
- }
- fallthrough
- case Chan, Map, UnsafePointer:
- return uintptr(v.pointer())
- case Func:
- if v.flag&flagMethod != 0 {
- // As the doc comment says, the returned pointer is an
- // underlying code pointer but not necessarily enough to
- // identify a single function uniquely. All method expressions
- // created via reflect have the same underlying code pointer,
- // so their Pointers are equal. The function used here must
- // match the one used in makeMethodValue.
- return methodValueCallCodePtr()
- }
- p := v.pointer()
- // Non-nil func value points at data block.
- // First word of data block is actual code.
- if p != nil {
- p = *(*unsafe.Pointer)(p)
- }
- return uintptr(p)
-
- case Slice:
- return uintptr((*unsafeheader.Slice)(v.ptr).Data)
- }
- panic(&ValueError{"reflect.Value.Pointer", v.kind()})
-}
-
-// Recv receives and returns a value from the channel v.
-// It panics if v's Kind is not Chan.
-// The receive blocks until a value is ready.
-// The boolean value ok is true if the value x corresponds to a send
-// on the channel, false if it is a zero value received because the channel is closed.
-func (v Value) Recv() (x Value, ok bool) {
- v.mustBe(Chan)
- v.mustBeExported()
- return v.recv(false)
-}
-
-// internal recv, possibly non-blocking (nb).
-// v is known to be a channel.
-func (v Value) recv(nb bool) (val Value, ok bool) {
- tt := (*chanType)(unsafe.Pointer(v.typ))
- if ChanDir(tt.dir)&RecvDir == 0 {
- panic("reflect: recv on send-only channel")
- }
- t := tt.elem
- val = Value{t, nil, flag(t.Kind())}
- var p unsafe.Pointer
- if ifaceIndir(t) {
- p = unsafe_New(t)
- val.ptr = p
- val.flag |= flagIndir
- } else {
- p = unsafe.Pointer(&val.ptr)
- }
- selected, ok := chanrecv(v.pointer(), nb, p)
- if !selected {
- val = Value{}
- }
- return
-}
-
-// Send sends x on the channel v.
-// It panics if v's kind is not Chan or if x's type is not the same type as v's element type.
-// As in Go, x's value must be assignable to the channel's element type.
-func (v Value) Send(x Value) {
- v.mustBe(Chan)
- v.mustBeExported()
- v.send(x, false)
-}
-
-// internal send, possibly non-blocking.
-// v is known to be a channel.
-func (v Value) send(x Value, nb bool) (selected bool) {
- tt := (*chanType)(unsafe.Pointer(v.typ))
- if ChanDir(tt.dir)&SendDir == 0 {
- panic("reflect: send on recv-only channel")
- }
- x.mustBeExported()
- x = x.assignTo("reflect.Value.Send", tt.elem, nil)
- var p unsafe.Pointer
- if x.flag&flagIndir != 0 {
- p = x.ptr
- } else {
- p = unsafe.Pointer(&x.ptr)
- }
- return chansend(v.pointer(), p, nb)
-}
-
-// Set assigns x to the value v.
-// It panics if CanSet returns false.
-// As in Go, x's value must be assignable to v's type and
-// must not be derived from an unexported field.
-func (v Value) Set(x Value) {
- v.mustBeAssignable()
- x.mustBeExported() // do not let unexported x leak
- var target unsafe.Pointer
- if v.kind() == Interface {
- target = v.ptr
- }
- x = x.assignTo("reflect.Set", v.typ, target)
- if x.flag&flagIndir != 0 {
- if x.ptr == unsafe.Pointer(&zeroVal[0]) {
- typedmemclr(v.typ, v.ptr)
- } else {
- typedmemmove(v.typ, v.ptr, x.ptr)
- }
- } else {
- *(*unsafe.Pointer)(v.ptr) = x.ptr
- }
-}
-
-// SetBool sets v's underlying value.
-// It panics if v's Kind is not Bool or if CanSet() is false.
-func (v Value) SetBool(x bool) {
- v.mustBeAssignable()
- v.mustBe(Bool)
- *(*bool)(v.ptr) = x
-}
-
-// SetBytes sets v's underlying value.
-// It panics if v's underlying value is not a slice of bytes.
-func (v Value) SetBytes(x []byte) {
- v.mustBeAssignable()
- v.mustBe(Slice)
- if v.typ.Elem().Kind() != Uint8 {
- panic("reflect.Value.SetBytes of non-byte slice")
- }
- *(*[]byte)(v.ptr) = x
-}
-
-// setRunes sets v's underlying value.
-// It panics if v's underlying value is not a slice of runes (int32s).
-func (v Value) setRunes(x []rune) {
- v.mustBeAssignable()
- v.mustBe(Slice)
- if v.typ.Elem().Kind() != Int32 {
- panic("reflect.Value.setRunes of non-rune slice")
- }
- *(*[]rune)(v.ptr) = x
-}
-
-// SetComplex sets v's underlying value to x.
-// It panics if v's Kind is not Complex64 or Complex128, or if CanSet() is false.
-func (v Value) SetComplex(x complex128) {
- v.mustBeAssignable()
- switch k := v.kind(); k {
- default:
- panic(&ValueError{"reflect.Value.SetComplex", v.kind()})
- case Complex64:
- *(*complex64)(v.ptr) = complex64(x)
- case Complex128:
- *(*complex128)(v.ptr) = x
- }
-}
-
-// SetFloat sets v's underlying value to x.
-// It panics if v's Kind is not Float32 or Float64, or if CanSet() is false.
-func (v Value) SetFloat(x float64) {
- v.mustBeAssignable()
- switch k := v.kind(); k {
- default:
- panic(&ValueError{"reflect.Value.SetFloat", v.kind()})
- case Float32:
- *(*float32)(v.ptr) = float32(x)
- case Float64:
- *(*float64)(v.ptr) = x
- }
-}
-
-// SetInt sets v's underlying value to x.
-// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64, or if CanSet() is false.
-func (v Value) SetInt(x int64) {
- v.mustBeAssignable()
- switch k := v.kind(); k {
- default:
- panic(&ValueError{"reflect.Value.SetInt", v.kind()})
- case Int:
- *(*int)(v.ptr) = int(x)
- case Int8:
- *(*int8)(v.ptr) = int8(x)
- case Int16:
- *(*int16)(v.ptr) = int16(x)
- case Int32:
- *(*int32)(v.ptr) = int32(x)
- case Int64:
- *(*int64)(v.ptr) = x
- }
-}
-
-// SetLen sets v's length to n.
-// It panics if v's Kind is not Slice or if n is negative or
-// greater than the capacity of the slice.
-func (v Value) SetLen(n int) {
- v.mustBeAssignable()
- v.mustBe(Slice)
- s := (*unsafeheader.Slice)(v.ptr)
- if uint(n) > uint(s.Cap) {
- panic("reflect: slice length out of range in SetLen")
- }
- s.Len = n
-}
-
-// SetCap sets v's capacity to n.
-// It panics if v's Kind is not Slice or if n is smaller than the length or
-// greater than the capacity of the slice.
-func (v Value) SetCap(n int) {
- v.mustBeAssignable()
- v.mustBe(Slice)
- s := (*unsafeheader.Slice)(v.ptr)
- if n < s.Len || n > s.Cap {
- panic("reflect: slice capacity out of range in SetCap")
- }
- s.Cap = n
-}
-
-// SetMapIndex sets the element associated with key in the map v to elem.
-// It panics if v's Kind is not Map.
-// If elem is the zero Value, SetMapIndex deletes the key from the map.
-// Otherwise if v holds a nil map, SetMapIndex will panic.
-// As in Go, key's elem must be assignable to the map's key type,
-// and elem's value must be assignable to the map's elem type.
-func (v Value) SetMapIndex(key, elem Value) {
- v.mustBe(Map)
- v.mustBeExported()
- key.mustBeExported()
- tt := (*mapType)(unsafe.Pointer(v.typ))
-
- if (tt.key == stringType || key.kind() == String) && tt.key == key.typ && tt.elem.size <= maxValSize {
- k := *(*string)(key.ptr)
- if elem.typ == nil {
- mapdelete_faststr(v.typ, v.pointer(), k)
- return
- }
- elem.mustBeExported()
- elem = elem.assignTo("reflect.Value.SetMapIndex", tt.elem, nil)
- var e unsafe.Pointer
- if elem.flag&flagIndir != 0 {
- e = elem.ptr
- } else {
- e = unsafe.Pointer(&elem.ptr)
- }
- mapassign_faststr(v.typ, v.pointer(), k, e)
- return
- }
-
- key = key.assignTo("reflect.Value.SetMapIndex", tt.key, nil)
- var k unsafe.Pointer
- if key.flag&flagIndir != 0 {
- k = key.ptr
- } else {
- k = unsafe.Pointer(&key.ptr)
- }
- if elem.typ == nil {
- mapdelete(v.typ, v.pointer(), k)
- return
- }
- elem.mustBeExported()
- elem = elem.assignTo("reflect.Value.SetMapIndex", tt.elem, nil)
- var e unsafe.Pointer
- if elem.flag&flagIndir != 0 {
- e = elem.ptr
- } else {
- e = unsafe.Pointer(&elem.ptr)
- }
- mapassign(v.typ, v.pointer(), k, e)
-}
-
-// SetUint sets v's underlying value to x.
-// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64, or if CanSet() is false.
-func (v Value) SetUint(x uint64) {
- v.mustBeAssignable()
- switch k := v.kind(); k {
- default:
- panic(&ValueError{"reflect.Value.SetUint", v.kind()})
- case Uint:
- *(*uint)(v.ptr) = uint(x)
- case Uint8:
- *(*uint8)(v.ptr) = uint8(x)
- case Uint16:
- *(*uint16)(v.ptr) = uint16(x)
- case Uint32:
- *(*uint32)(v.ptr) = uint32(x)
- case Uint64:
- *(*uint64)(v.ptr) = x
- case Uintptr:
- *(*uintptr)(v.ptr) = uintptr(x)
- }
-}
-
-// SetPointer sets the [unsafe.Pointer] value v to x.
-// It panics if v's Kind is not UnsafePointer.
-func (v Value) SetPointer(x unsafe.Pointer) {
- v.mustBeAssignable()
- v.mustBe(UnsafePointer)
- *(*unsafe.Pointer)(v.ptr) = x
-}
-
-// SetString sets v's underlying value to x.
-// It panics if v's Kind is not String or if CanSet() is false.
-func (v Value) SetString(x string) {
- v.mustBeAssignable()
- v.mustBe(String)
- *(*string)(v.ptr) = x
-}
-
-// Slice returns v[i:j].
-// It panics if v's Kind is not Array, Slice or String, or if v is an unaddressable array,
-// or if the indexes are out of bounds.
-func (v Value) Slice(i, j int) Value {
- var (
- cap int
- typ *sliceType
- base unsafe.Pointer
- )
- switch kind := v.kind(); kind {
- default:
- panic(&ValueError{"reflect.Value.Slice", v.kind()})
-
- case Array:
- if v.flag&flagAddr == 0 {
- panic("reflect.Value.Slice: slice of unaddressable array")
- }
- tt := (*arrayType)(unsafe.Pointer(v.typ))
- cap = int(tt.len)
- typ = (*sliceType)(unsafe.Pointer(tt.slice))
- base = v.ptr
-
- case Slice:
- typ = (*sliceType)(unsafe.Pointer(v.typ))
- s := (*unsafeheader.Slice)(v.ptr)
- base = s.Data
- cap = s.Cap
-
- case String:
- s := (*unsafeheader.String)(v.ptr)
- if i < 0 || j < i || j > s.Len {
- panic("reflect.Value.Slice: string slice index out of bounds")
- }
- var t unsafeheader.String
- if i < s.Len {
- t = unsafeheader.String{Data: arrayAt(s.Data, i, 1, "i < s.Len"), Len: j - i}
- }
- return Value{v.typ, unsafe.Pointer(&t), v.flag}
- }
-
- if i < 0 || j < i || j > cap {
- panic("reflect.Value.Slice: slice index out of bounds")
- }
-
- // Declare slice so that gc can see the base pointer in it.
- var x []unsafe.Pointer
-
- // Reinterpret as *unsafeheader.Slice to edit.
- s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
- s.Len = j - i
- s.Cap = cap - i
- if cap-i > 0 {
- s.Data = arrayAt(base, i, typ.elem.Size(), "i < cap")
- } else {
- // do not advance pointer, to avoid pointing beyond end of slice
- s.Data = base
- }
-
- fl := v.flag.ro() | flagIndir | flag(Slice)
- return Value{typ.common(), unsafe.Pointer(&x), fl}
-}
-
-// Slice3 is the 3-index form of the slice operation: it returns v[i:j:k].
-// It panics if v's Kind is not Array or Slice, or if v is an unaddressable array,
-// or if the indexes are out of bounds.
-func (v Value) Slice3(i, j, k int) Value {
- var (
- cap int
- typ *sliceType
- base unsafe.Pointer
- )
- switch kind := v.kind(); kind {
- default:
- panic(&ValueError{"reflect.Value.Slice3", v.kind()})
-
- case Array:
- if v.flag&flagAddr == 0 {
- panic("reflect.Value.Slice3: slice of unaddressable array")
- }
- tt := (*arrayType)(unsafe.Pointer(v.typ))
- cap = int(tt.len)
- typ = (*sliceType)(unsafe.Pointer(tt.slice))
- base = v.ptr
-
- case Slice:
- typ = (*sliceType)(unsafe.Pointer(v.typ))
- s := (*unsafeheader.Slice)(v.ptr)
- base = s.Data
- cap = s.Cap
- }
-
- if i < 0 || j < i || k < j || k > cap {
- panic("reflect.Value.Slice3: slice index out of bounds")
- }
-
- // Declare slice so that the garbage collector
- // can see the base pointer in it.
- var x []unsafe.Pointer
-
- // Reinterpret as *unsafeheader.Slice to edit.
- s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
- s.Len = j - i
- s.Cap = k - i
- if k-i > 0 {
- s.Data = arrayAt(base, i, typ.elem.Size(), "i < k <= cap")
- } else {
- // do not advance pointer, to avoid pointing beyond end of slice
- s.Data = base
- }
-
- fl := v.flag.ro() | flagIndir | flag(Slice)
- return Value{typ.common(), unsafe.Pointer(&x), fl}
-}
-
-// String returns the string v's underlying value, as a string.
-// String is a special case because of Go's String method convention.
-// Unlike the other getters, it does not panic if v's Kind is not String.
-// Instead, it returns a string of the form "<T value>" where T is v's type.
-// The fmt package treats Values specially. It does not call their String
-// method implicitly but instead prints the concrete values they hold.
-func (v Value) String() string {
- // stringNonString is split out to keep String inlineable for string kinds.
- if v.kind() == String {
- return *(*string)(v.ptr)
- }
- return v.stringNonString()
-}
-
-func (v Value) stringNonString() string {
- if v.kind() == Invalid {
- return "<invalid Value>"
- }
- // If you call String on a reflect.Value of other type, it's better to
- // print something than to panic. Useful in debugging.
- return "<" + v.Type().String() + " Value>"
-}
-
-// TryRecv attempts to receive a value from the channel v but will not block.
-// It panics if v's Kind is not Chan.
-// If the receive delivers a value, x is the transferred value and ok is true.
-// If the receive cannot finish without blocking, x is the zero Value and ok is false.
-// If the channel is closed, x is the zero value for the channel's element type and ok is false.
-func (v Value) TryRecv() (x Value, ok bool) {
- v.mustBe(Chan)
- v.mustBeExported()
- return v.recv(true)
-}
-
-// TrySend attempts to send x on the channel v but will not block.
-// It panics if v's Kind is not Chan.
-// It reports whether the value was sent.
-// As in Go, x's value must be assignable to the channel's element type.
-func (v Value) TrySend(x Value) bool {
- v.mustBe(Chan)
- v.mustBeExported()
- return v.send(x, true)
-}
-
-// Type returns v's type.
-func (v Value) Type() Type {
- if v.flag != 0 && v.flag&flagMethod == 0 {
- return v.typ
- }
- return v.typeSlow()
-}
-
-func (v Value) typeSlow() Type {
- if v.flag == 0 {
- panic(&ValueError{"reflect.Value.Type", Invalid})
- }
- if v.flag&flagMethod == 0 {
- return v.typ
- }
-
- // Method value.
- // v.typ describes the receiver, not the method type.
- i := int(v.flag) >> flagMethodShift
- if v.typ.Kind() == Interface {
- // Method on interface.
- tt := (*interfaceType)(unsafe.Pointer(v.typ))
- if uint(i) >= uint(len(tt.methods)) {
- panic("reflect: internal error: invalid method index")
- }
- m := &tt.methods[i]
- return v.typ.typeOff(m.typ)
- }
- // Method on concrete type.
- ms := v.typ.exportedMethods()
- if uint(i) >= uint(len(ms)) {
- panic("reflect: internal error: invalid method index")
- }
- m := ms[i]
- return v.typ.typeOff(m.mtyp)
-}
-
-// CanUint reports whether Uint can be used without panicking.
-func (v Value) CanUint() bool {
- switch v.kind() {
- case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
- return true
- default:
- return false
- }
-}
-
-// Uint returns v's underlying value, as a uint64.
-// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
-func (v Value) Uint() uint64 {
- k := v.kind()
- p := v.ptr
- switch k {
- case Uint:
- return uint64(*(*uint)(p))
- case Uint8:
- return uint64(*(*uint8)(p))
- case Uint16:
- return uint64(*(*uint16)(p))
- case Uint32:
- return uint64(*(*uint32)(p))
- case Uint64:
- return *(*uint64)(p)
- case Uintptr:
- return uint64(*(*uintptr)(p))
- }
- panic(&ValueError{"reflect.Value.Uint", v.kind()})
-}
-
-//go:nocheckptr
-// This prevents inlining Value.UnsafeAddr when -d=checkptr is enabled,
-// which ensures cmd/compile can recognize unsafe.Pointer(v.UnsafeAddr())
-// and make an exception.
-
-// UnsafeAddr returns a pointer to v's data, as a uintptr.
-// It panics if v is not addressable.
-//
-// It's preferred to use uintptr(Value.Addr().UnsafePointer()) to get the equivalent result.
-func (v Value) UnsafeAddr() uintptr {
- if v.typ == nil {
- panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
- }
- if v.flag&flagAddr == 0 {
- panic("reflect.Value.UnsafeAddr of unaddressable value")
- }
- return uintptr(v.ptr)
-}
-
-// UnsafePointer returns v's value as a [unsafe.Pointer].
-// It panics if v's Kind is not Chan, Func, Map, Pointer, Slice, or UnsafePointer.
-//
-// If v's Kind is Func, the returned pointer is an underlying
-// code pointer, but not necessarily enough to identify a
-// single function uniquely. The only guarantee is that the
-// result is zero if and only if v is a nil func Value.
-//
-// If v's Kind is Slice, the returned pointer is to the first
-// element of the slice. If the slice is nil the returned value
-// is nil. If the slice is empty but non-nil the return value is non-nil.
-func (v Value) UnsafePointer() unsafe.Pointer {
- k := v.kind()
- switch k {
- case Pointer:
- if v.typ.ptrdata == 0 {
- // Since it is a not-in-heap pointer, all pointers to the heap are
- // forbidden! See comment in Value.Elem and issue #48399.
- if !verifyNotInHeapPtr(*(*uintptr)(v.ptr)) {
- panic("reflect: reflect.Value.UnsafePointer on an invalid notinheap pointer")
- }
- return *(*unsafe.Pointer)(v.ptr)
- }
- fallthrough
- case Chan, Map, UnsafePointer:
- return v.pointer()
- case Func:
- if v.flag&flagMethod != 0 {
- // As the doc comment says, the returned pointer is an
- // underlying code pointer but not necessarily enough to
- // identify a single function uniquely. All method expressions
- // created via reflect have the same underlying code pointer,
- // so their Pointers are equal. The function used here must
- // match the one used in makeMethodValue.
- code := methodValueCallCodePtr()
- return *(*unsafe.Pointer)(unsafe.Pointer(&code))
- }
- p := v.pointer()
- // Non-nil func value points at data block.
- // First word of data block is actual code.
- if p != nil {
- p = *(*unsafe.Pointer)(p)
- }
- return p
-
- case Slice:
- return (*unsafeheader.Slice)(v.ptr).Data
- }
- panic(&ValueError{"reflect.Value.UnsafePointer", v.kind()})
-}
-
-// StringHeader is the runtime representation of a string.
-// It cannot be used safely or portably and its representation may
-// change in a later release.
-// Moreover, the Data field is not sufficient to guarantee the data
-// it references will not be garbage collected, so programs must keep
-// a separate, correctly typed pointer to the underlying data.
-//
-// In new code, use unsafe.String or unsafe.StringData instead.
-type StringHeader struct {
- Data uintptr
- Len int
-}
-
-// SliceHeader is the runtime representation of a slice.
-// It cannot be used safely or portably and its representation may
-// change in a later release.
-// Moreover, the Data field is not sufficient to guarantee the data
-// it references will not be garbage collected, so programs must keep
-// a separate, correctly typed pointer to the underlying data.
-//
-// In new code, use unsafe.Slice or unsafe.SliceData instead.
-type SliceHeader struct {
- Data uintptr
- Len int
- Cap int
-}
-
-func typesMustMatch(what string, t1, t2 Type) {
- if t1 != t2 {
- panic(what + ": " + t1.String() + " != " + t2.String())
- }
-}
-
-// arrayAt returns the i-th element of p,
-// an array whose elements are eltSize bytes wide.
-// The array pointed at by p must have at least i+1 elements:
-// it is invalid (but impossible to check here) to pass i >= len,
-// because then the result will point outside the array.
-// whySafe must explain why i < len. (Passing "i < len" is fine;
-// the benefit is to surface this assumption at the call site.)
-func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
- return add(p, uintptr(i)*eltSize, "i < len")
-}
-
-// Grow increases the slice's capacity, if necessary, to guarantee space for
-// another n elements. After Grow(n), at least n elements can be appended
-// to the slice without another allocation.
-//
-// It panics if v's Kind is not a Slice or if n is negative or too large to
-// allocate the memory.
-func (v Value) Grow(n int) {
- v.mustBeAssignable()
- v.mustBe(Slice)
- v.grow(n)
-}
-
-// grow is identical to Grow but does not check for assignability.
-func (v Value) grow(n int) {
- p := (*unsafeheader.Slice)(v.ptr)
- switch {
- case n < 0:
- panic("reflect.Value.Grow: negative len")
- case p.Len+n < 0:
- panic("reflect.Value.Grow: slice overflow")
- case p.Len+n > p.Cap:
- t := v.typ.Elem().(*rtype)
- *p = growslice(t, *p, n)
- }
-}
-
-// extendSlice extends a slice by n elements.
-//
-// Unlike Value.grow, which modifies the slice in place and
-// does not change the length of the slice in place,
-// extendSlice returns a new slice value with the length
-// incremented by the number of specified elements.
-func (v Value) extendSlice(n int) Value {
- v.mustBeExported()
- v.mustBe(Slice)
-
- // Shallow copy the slice header to avoid mutating the source slice.
- sh := *(*unsafeheader.Slice)(v.ptr)
- s := &sh
- v.ptr = unsafe.Pointer(s)
- v.flag = flagIndir | flag(Slice) // equivalent flag to MakeSlice
-
- v.grow(n) // fine to treat as assignable since we allocate a new slice header
- s.Len += n
- return v
-}
-
-// Append appends the values x to a slice s and returns the resulting slice.
-// As in Go, each x's value must be assignable to the slice's element type.
-func Append(s Value, x ...Value) Value {
- s.mustBe(Slice)
- n := s.Len()
- s = s.extendSlice(len(x))
- for i, v := range x {
- s.Index(n + i).Set(v)
- }
- return s
-}
-
-// AppendSlice appends a slice t to a slice s and returns the resulting slice.
-// The slices s and t must have the same element type.
-func AppendSlice(s, t Value) Value {
- s.mustBe(Slice)
- t.mustBe(Slice)
- typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
- ns := s.Len()
- nt := t.Len()
- s = s.extendSlice(nt)
- Copy(s.Slice(ns, ns+nt), t)
- return s
-}
-
-// Copy copies the contents of src into dst until either
-// dst has been filled or src has been exhausted.
-// It returns the number of elements copied.
-// Dst and src each must have kind Slice or Array, and
-// dst and src must have the same element type.
-//
-// As a special case, src can have kind String if the element type of dst is kind Uint8.
-func Copy(dst, src Value) int {
- dk := dst.kind()
- if dk != Array && dk != Slice {
- panic(&ValueError{"reflect.Copy", dk})
- }
- if dk == Array {
- dst.mustBeAssignable()
- }
- dst.mustBeExported()
-
- sk := src.kind()
- var stringCopy bool
- if sk != Array && sk != Slice {
- stringCopy = sk == String && dst.typ.Elem().Kind() == Uint8
- if !stringCopy {
- panic(&ValueError{"reflect.Copy", sk})
- }
- }
- src.mustBeExported()
-
- de := dst.typ.Elem()
- if !stringCopy {
- se := src.typ.Elem()
- typesMustMatch("reflect.Copy", de, se)
- }
-
- var ds, ss unsafeheader.Slice
- if dk == Array {
- ds.Data = dst.ptr
- ds.Len = dst.Len()
- ds.Cap = ds.Len
- } else {
- ds = *(*unsafeheader.Slice)(dst.ptr)
- }
- if sk == Array {
- ss.Data = src.ptr
- ss.Len = src.Len()
- ss.Cap = ss.Len
- } else if sk == Slice {
- ss = *(*unsafeheader.Slice)(src.ptr)
- } else {
- sh := *(*unsafeheader.String)(src.ptr)
- ss.Data = sh.Data
- ss.Len = sh.Len
- ss.Cap = sh.Len
- }
-
- return typedslicecopy(de.common(), ds, ss)
-}
-
-// A runtimeSelect is a single case passed to rselect.
-// This must match ../runtime/select.go:/runtimeSelect
-type runtimeSelect struct {
- dir SelectDir // SelectSend, SelectRecv or SelectDefault
- typ *rtype // channel type
- ch unsafe.Pointer // channel
- val unsafe.Pointer // ptr to data (SendDir) or ptr to receive buffer (RecvDir)
-}
-
-// rselect runs a select. It returns the index of the chosen case.
-// If the case was a receive, val is filled in with the received value.
-// The conventional OK bool indicates whether the receive corresponds
-// to a sent value.
-//
-//go:noescape
-func rselect([]runtimeSelect) (chosen int, recvOK bool)
-
-// A SelectDir describes the communication direction of a select case.
-type SelectDir int
-
-// NOTE: These values must match ../runtime/select.go:/selectDir.
-
-const (
- _ SelectDir = iota
- SelectSend // case Chan <- Send
- SelectRecv // case <-Chan:
- SelectDefault // default
-)
-
-// A SelectCase describes a single case in a select operation.
-// The kind of case depends on Dir, the communication direction.
-//
-// If Dir is SelectDefault, the case represents a default case.
-// Chan and Send must be zero Values.
-//
-// If Dir is SelectSend, the case represents a send operation.
-// Normally Chan's underlying value must be a channel, and Send's underlying value must be
-// assignable to the channel's element type. As a special case, if Chan is a zero Value,
-// then the case is ignored, and the field Send will also be ignored and may be either zero
-// or non-zero.
-//
-// If Dir is SelectRecv, the case represents a receive operation.
-// Normally Chan's underlying value must be a channel and Send must be a zero Value.
-// If Chan is a zero Value, then the case is ignored, but Send must still be a zero Value.
-// When a receive operation is selected, the received Value is returned by Select.
-type SelectCase struct {
- Dir SelectDir // direction of case
- Chan Value // channel to use (for send or receive)
- Send Value // value to send (for send)
-}
-
-// Select executes a select operation described by the list of cases.
-// Like the Go select statement, it blocks until at least one of the cases
-// can proceed, makes a uniform pseudo-random choice,
-// and then executes that case. It returns the index of the chosen case
-// and, if that case was a receive operation, the value received and a
-// boolean indicating whether the value corresponds to a send on the channel
-// (as opposed to a zero value received because the channel is closed).
-// Select supports a maximum of 65536 cases.
-func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
- if len(cases) > 65536 {
- panic("reflect.Select: too many cases (max 65536)")
- }
- // NOTE: Do not trust that caller is not modifying cases data underfoot.
- // The range is safe because the caller cannot modify our copy of the len
- // and each iteration makes its own copy of the value c.
- var runcases []runtimeSelect
- if len(cases) > 4 {
- // Slice is heap allocated due to runtime dependent capacity.
- runcases = make([]runtimeSelect, len(cases))
- } else {
- // Slice can be stack allocated due to constant capacity.
- runcases = make([]runtimeSelect, len(cases), 4)
- }
-
- haveDefault := false
- for i, c := range cases {
- rc := &runcases[i]
- rc.dir = c.Dir
- switch c.Dir {
- default:
- panic("reflect.Select: invalid Dir")
-
- case SelectDefault: // default
- if haveDefault {
- panic("reflect.Select: multiple default cases")
- }
- haveDefault = true
- if c.Chan.IsValid() {
- panic("reflect.Select: default case has Chan value")
- }
- if c.Send.IsValid() {
- panic("reflect.Select: default case has Send value")
- }
-
- case SelectSend:
- ch := c.Chan
- if !ch.IsValid() {
- break
- }
- ch.mustBe(Chan)
- ch.mustBeExported()
- tt := (*chanType)(unsafe.Pointer(ch.typ))
- if ChanDir(tt.dir)&SendDir == 0 {
- panic("reflect.Select: SendDir case using recv-only channel")
- }
- rc.ch = ch.pointer()
- rc.typ = &tt.rtype
- v := c.Send
- if !v.IsValid() {
- panic("reflect.Select: SendDir case missing Send value")
- }
- v.mustBeExported()
- v = v.assignTo("reflect.Select", tt.elem, nil)
- if v.flag&flagIndir != 0 {
- rc.val = v.ptr
- } else {
- rc.val = unsafe.Pointer(&v.ptr)
- }
-
- case SelectRecv:
- if c.Send.IsValid() {
- panic("reflect.Select: RecvDir case has Send value")
- }
- ch := c.Chan
- if !ch.IsValid() {
- break
- }
- ch.mustBe(Chan)
- ch.mustBeExported()
- tt := (*chanType)(unsafe.Pointer(ch.typ))
- if ChanDir(tt.dir)&RecvDir == 0 {
- panic("reflect.Select: RecvDir case using send-only channel")
- }
- rc.ch = ch.pointer()
- rc.typ = &tt.rtype
- rc.val = unsafe_New(tt.elem)
- }
- }
-
- chosen, recvOK = rselect(runcases)
- if runcases[chosen].dir == SelectRecv {
- tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
- t := tt.elem
- p := runcases[chosen].val
- fl := flag(t.Kind())
- if ifaceIndir(t) {
- recv = Value{t, p, fl | flagIndir}
- } else {
- recv = Value{t, *(*unsafe.Pointer)(p), fl}
- }
- }
- return chosen, recv, recvOK
-}
-
-/*
- * constructors
- */
-
-// implemented in package runtime
-func unsafe_New(*rtype) unsafe.Pointer
-func unsafe_NewArray(*rtype, int) unsafe.Pointer
-
-// MakeSlice creates a new zero-initialized slice value
-// for the specified slice type, length, and capacity.
-func MakeSlice(typ Type, len, cap int) Value {
- if typ.Kind() != Slice {
- panic("reflect.MakeSlice of non-slice type")
- }
- if len < 0 {
- panic("reflect.MakeSlice: negative len")
- }
- if cap < 0 {
- panic("reflect.MakeSlice: negative cap")
- }
- if len > cap {
- panic("reflect.MakeSlice: len > cap")
- }
-
- s := unsafeheader.Slice{Data: unsafe_NewArray(typ.Elem().(*rtype), cap), Len: len, Cap: cap}
- return Value{typ.(*rtype), unsafe.Pointer(&s), flagIndir | flag(Slice)}
-}
-
-// MakeChan creates a new channel with the specified type and buffer size.
-func MakeChan(typ Type, buffer int) Value {
- if typ.Kind() != Chan {
- panic("reflect.MakeChan of non-chan type")
- }
- if buffer < 0 {
- panic("reflect.MakeChan: negative buffer size")
- }
- if typ.ChanDir() != BothDir {
- panic("reflect.MakeChan: unidirectional channel type")
- }
- t := typ.(*rtype)
- ch := makechan(t, buffer)
- return Value{t, ch, flag(Chan)}
-}
-
-// MakeMap creates a new map with the specified type.
-func MakeMap(typ Type) Value {
- return MakeMapWithSize(typ, 0)
-}
-
-// MakeMapWithSize creates a new map with the specified type
-// and initial space for approximately n elements.
-func MakeMapWithSize(typ Type, n int) Value {
- if typ.Kind() != Map {
- panic("reflect.MakeMapWithSize of non-map type")
- }
- t := typ.(*rtype)
- m := makemap(t, n)
- return Value{t, m, flag(Map)}
-}
-
-// Indirect returns the value that v points to.
-// If v is a nil pointer, Indirect returns a zero Value.
-// If v is not a pointer, Indirect returns v.
-func Indirect(v Value) Value {
- if v.Kind() != Pointer {
- return v
- }
- return v.Elem()
-}
-
-// ValueOf returns a new Value initialized to the concrete value
-// stored in the interface i. ValueOf(nil) returns the zero Value.
-func ValueOf(i any) Value {
- if i == nil {
- return Value{}
- }
-
- // TODO: Maybe allow contents of a Value to live on the stack.
- // For now we make the contents always escape to the heap. It
- // makes life easier in a few places (see chanrecv/mapassign
- // comment below).
- escapes(i)
-
- return unpackEface(i)
-}
-
-// Zero returns a Value representing the zero value for the specified type.
-// The result is different from the zero value of the Value struct,
-// which represents no value at all.
-// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
-// The returned value is neither addressable nor settable.
-func Zero(typ Type) Value {
- if typ == nil {
- panic("reflect: Zero(nil)")
- }
- t := typ.(*rtype)
- fl := flag(t.Kind())
- if ifaceIndir(t) {
- var p unsafe.Pointer
- if t.size <= maxZero {
- p = unsafe.Pointer(&zeroVal[0])
- } else {
- p = unsafe_New(t)
- }
- return Value{t, p, fl | flagIndir}
- }
- return Value{t, nil, fl}
-}
-
-// must match declarations in runtime/map.go.
-const maxZero = 1024
-
-//go:linkname zeroVal runtime.zeroVal
-var zeroVal [maxZero]byte
-
-// New returns a Value representing a pointer to a new zero value
-// for the specified type. That is, the returned Value's Type is PointerTo(typ).
-func New(typ Type) Value {
- if typ == nil {
- panic("reflect: New(nil)")
- }
- t := typ.(*rtype)
- pt := t.ptrTo()
- if ifaceIndir(pt) {
- // This is a pointer to a not-in-heap type.
- panic("reflect: New of type that may not be allocated in heap (possibly undefined cgo C type)")
- }
- ptr := unsafe_New(t)
- fl := flag(Pointer)
- return Value{pt, ptr, fl}
-}
-
-// NewAt returns a Value representing a pointer to a value of the
-// specified type, using p as that pointer.
-func NewAt(typ Type, p unsafe.Pointer) Value {
- fl := flag(Pointer)
- t := typ.(*rtype)
- return Value{t.ptrTo(), p, fl}
-}
-
-// assignTo returns a value v that can be assigned directly to dst.
-// It panics if v is not assignable to dst.
-// For a conversion to an interface type, target, if not nil,
-// is a suggested scratch space to use.
-// target must be initialized memory (or nil).
-func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value {
- if v.flag&flagMethod != 0 {
- v = makeMethodValue(context, v)
- }
-
- switch {
- case directlyAssignable(dst, v.typ):
- // Overwrite type so that they match.
- // Same memory layout, so no harm done.
- fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
- fl |= flag(dst.Kind())
- return Value{dst, v.ptr, fl}
-
- case implements(dst, v.typ):
- if v.Kind() == Interface && v.IsNil() {
- // A nil ReadWriter passed to nil Reader is OK,
- // but using ifaceE2I below will panic.
- // Avoid the panic by returning a nil dst (e.g., Reader) explicitly.
- return Value{dst, nil, flag(Interface)}
- }
- x := valueInterface(v, false)
- if target == nil {
- target = unsafe_New(dst)
- }
- if dst.NumMethod() == 0 {
- *(*any)(target) = x
- } else {
- ifaceE2I(dst, x, target)
- }
- return Value{dst, target, flagIndir | flag(Interface)}
- }
-
- // Failed.
- panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
-}
-
-// Convert returns the value v converted to type t.
-// If the usual Go conversion rules do not allow conversion
-// of the value v to type t, or if converting v to type t panics, Convert panics.
-func (v Value) Convert(t Type) Value {
- if v.flag&flagMethod != 0 {
- v = makeMethodValue("Convert", v)
- }
- op := convertOp(t.common(), v.typ)
- if op == nil {
- panic("reflect.Value.Convert: value of type " + v.typ.String() + " cannot be converted to type " + t.String())
- }
- return op(v, t)
-}
-
-// CanConvert reports whether the value v can be converted to type t.
-// If v.CanConvert(t) returns true then v.Convert(t) will not panic.
-func (v Value) CanConvert(t Type) bool {
- vt := v.Type()
- if !vt.ConvertibleTo(t) {
- return false
- }
- // Converting from slice to array or to pointer-to-array can panic
- // depending on the value.
- switch {
- case vt.Kind() == Slice && t.Kind() == Array:
- if t.Len() > v.Len() {
- return false
- }
- case vt.Kind() == Slice && t.Kind() == Pointer && t.Elem().Kind() == Array:
- n := t.Elem().Len()
- if n > v.Len() {
- return false
- }
- }
- return true
-}
-
-// Comparable reports whether the value v is comparable.
-// If the type of v is an interface, this checks the dynamic type.
-// If this reports true then v.Interface() == x will not panic for any x,
-// nor will v.Equal(u) for any Value u.
-func (v Value) Comparable() bool {
- k := v.Kind()
- switch k {
- case Invalid:
- return false
-
- case Array:
- switch v.Type().Elem().Kind() {
- case Interface, Array, Struct:
- for i := 0; i < v.Type().Len(); i++ {
- if !v.Index(i).Comparable() {
- return false
- }
- }
- return true
- }
- return v.Type().Comparable()
-
- case Interface:
- return v.Elem().Comparable()
-
- case Struct:
- for i := 0; i < v.NumField(); i++ {
- if !v.Field(i).Comparable() {
- return false
- }
- }
- return true
-
- default:
- return v.Type().Comparable()
- }
-}
-
-// Equal reports true if v is equal to u.
-// For two invalid values, Equal will report true.
-// For an interface value, Equal will compare the value within the interface.
-// Otherwise, If the values have different types, Equal will report false.
-// Otherwise, for arrays and structs Equal will compare each element in order,
-// and report false if it finds non-equal elements.
-// During all comparisons, if values of the same type are compared,
-// and the type is not comparable, Equal will panic.
-func (v Value) Equal(u Value) bool {
- if v.Kind() == Interface {
- v = v.Elem()
- }
- if u.Kind() == Interface {
- u = u.Elem()
- }
-
- if !v.IsValid() || !u.IsValid() {
- return v.IsValid() == u.IsValid()
- }
-
- if v.Kind() != u.Kind() || v.Type() != u.Type() {
- return false
- }
-
- // Handle each Kind directly rather than calling valueInterface
- // to avoid allocating.
- switch v.Kind() {
- default:
- panic("reflect.Value.Equal: invalid Kind")
- case Bool:
- return v.Bool() == u.Bool()
- case Int, Int8, Int16, Int32, Int64:
- return v.Int() == u.Int()
- case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
- return v.Uint() == u.Uint()
- case Float32, Float64:
- return v.Float() == u.Float()
- case Complex64, Complex128:
- return v.Complex() == u.Complex()
- case String:
- return v.String() == u.String()
- case Chan, Pointer, UnsafePointer:
- return v.Pointer() == u.Pointer()
- case Array:
- // u and v have the same type so they have the same length
- vl := v.Len()
- if vl == 0 {
- // panic on [0]func()
- if !v.Type().Elem().Comparable() {
- break
- }
- return true
- }
- for i := 0; i < vl; i++ {
- if !v.Index(i).Equal(u.Index(i)) {
- return false
- }
- }
- return true
- case Struct:
- // u and v have the same type so they have the same fields
- nf := v.NumField()
- for i := 0; i < nf; i++ {
- if !v.Field(i).Equal(u.Field(i)) {
- return false
- }
- }
- return true
- case Func, Map, Slice:
- break
- }
- panic("reflect.Value.Equal: values of type " + v.Type().String() + " are not comparable")
-}
-
-// convertOp returns the function to convert a value of type src
-// to a value of type dst. If the conversion is illegal, convertOp returns nil.
-func convertOp(dst, src *rtype) func(Value, Type) Value {
- switch src.Kind() {
- case Int, Int8, Int16, Int32, Int64:
- switch dst.Kind() {
- case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
- return cvtInt
- case Float32, Float64:
- return cvtIntFloat
- case String:
- return cvtIntString
- }
-
- case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
- switch dst.Kind() {
- case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
- return cvtUint
- case Float32, Float64:
- return cvtUintFloat
- case String:
- return cvtUintString
- }
-
- case Float32, Float64:
- switch dst.Kind() {
- case Int, Int8, Int16, Int32, Int64:
- return cvtFloatInt
- case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
- return cvtFloatUint
- case Float32, Float64:
- return cvtFloat
- }
-
- case Complex64, Complex128:
- switch dst.Kind() {
- case Complex64, Complex128:
- return cvtComplex
- }
-
- case String:
- if dst.Kind() == Slice && dst.Elem().PkgPath() == "" {
- switch dst.Elem().Kind() {
- case Uint8:
- return cvtStringBytes
- case Int32:
- return cvtStringRunes
- }
- }
-
- case Slice:
- if dst.Kind() == String && src.Elem().PkgPath() == "" {
- switch src.Elem().Kind() {
- case Uint8:
- return cvtBytesString
- case Int32:
- return cvtRunesString
- }
- }
- // "x is a slice, T is a pointer-to-array type,
- // and the slice and array types have identical element types."
- if dst.Kind() == Pointer && dst.Elem().Kind() == Array && src.Elem() == dst.Elem().Elem() {
- return cvtSliceArrayPtr
- }
- // "x is a slice, T is a array type,
- // and the slice and array types have identical element types."
- if dst.Kind() == Array && src.Elem() == dst.Elem() {
- return cvtSliceArray
- }
-
- case Chan:
- if dst.Kind() == Chan && specialChannelAssignability(dst, src) {
- return cvtDirect
- }
- }
-
- // dst and src have same underlying type.
- if haveIdenticalUnderlyingType(dst, src, false) {
- return cvtDirect
- }
-
- // dst and src are non-defined pointer types with same underlying base type.
- if dst.Kind() == Pointer && dst.Name() == "" &&
- src.Kind() == Pointer && src.Name() == "" &&
- haveIdenticalUnderlyingType(dst.Elem().common(), src.Elem().common(), false) {
- return cvtDirect
- }
-
- if implements(dst, src) {
- if src.Kind() == Interface {
- return cvtI2I
- }
- return cvtT2I
- }
-
- return nil
-}
-
-// makeInt returns a Value of type t equal to bits (possibly truncated),
-// where t is a signed or unsigned int type.
-func makeInt(f flag, bits uint64, t Type) Value {
- typ := t.common()
- ptr := unsafe_New(typ)
- switch typ.size {
- case 1:
- *(*uint8)(ptr) = uint8(bits)
- case 2:
- *(*uint16)(ptr) = uint16(bits)
- case 4:
- *(*uint32)(ptr) = uint32(bits)
- case 8:
- *(*uint64)(ptr) = bits
- }
- return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
-}
-
-// makeFloat returns a Value of type t equal to v (possibly truncated to float32),
-// where t is a float32 or float64 type.
-func makeFloat(f flag, v float64, t Type) Value {
- typ := t.common()
- ptr := unsafe_New(typ)
- switch typ.size {
- case 4:
- *(*float32)(ptr) = float32(v)
- case 8:
- *(*float64)(ptr) = v
- }
- return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
-}
-
-// makeFloat32 returns a Value of type t equal to v, where t is a float32 type.
-func makeFloat32(f flag, v float32, t Type) Value {
- typ := t.common()
- ptr := unsafe_New(typ)
- *(*float32)(ptr) = v
- return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
-}
-
-// makeComplex returns a Value of type t equal to v (possibly truncated to complex64),
-// where t is a complex64 or complex128 type.
-func makeComplex(f flag, v complex128, t Type) Value {
- typ := t.common()
- ptr := unsafe_New(typ)
- switch typ.size {
- case 8:
- *(*complex64)(ptr) = complex64(v)
- case 16:
- *(*complex128)(ptr) = v
- }
- return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
-}
-
-func makeString(f flag, v string, t Type) Value {
- ret := New(t).Elem()
- ret.SetString(v)
- ret.flag = ret.flag&^flagAddr | f
- return ret
-}
-
-func makeBytes(f flag, v []byte, t Type) Value {
- ret := New(t).Elem()
- ret.SetBytes(v)
- ret.flag = ret.flag&^flagAddr | f
- return ret
-}
-
-func makeRunes(f flag, v []rune, t Type) Value {
- ret := New(t).Elem()
- ret.setRunes(v)
- ret.flag = ret.flag&^flagAddr | f
- return ret
-}
-
-// These conversion functions are returned by convertOp
-// for classes of conversions. For example, the first function, cvtInt,
-// takes any value v of signed int type and returns the value converted
-// to type t, where t is any signed or unsigned int type.
-
-// convertOp: intXX -> [u]intXX
-func cvtInt(v Value, t Type) Value {
- return makeInt(v.flag.ro(), uint64(v.Int()), t)
-}
-
-// convertOp: uintXX -> [u]intXX
-func cvtUint(v Value, t Type) Value {
- return makeInt(v.flag.ro(), v.Uint(), t)
-}
-
-// convertOp: floatXX -> intXX
-func cvtFloatInt(v Value, t Type) Value {
- return makeInt(v.flag.ro(), uint64(int64(v.Float())), t)
-}
-
-// convertOp: floatXX -> uintXX
-func cvtFloatUint(v Value, t Type) Value {
- return makeInt(v.flag.ro(), uint64(v.Float()), t)
-}
-
-// convertOp: intXX -> floatXX
-func cvtIntFloat(v Value, t Type) Value {
- return makeFloat(v.flag.ro(), float64(v.Int()), t)
-}
-
-// convertOp: uintXX -> floatXX
-func cvtUintFloat(v Value, t Type) Value {
- return makeFloat(v.flag.ro(), float64(v.Uint()), t)
-}
-
-// convertOp: floatXX -> floatXX
-func cvtFloat(v Value, t Type) Value {
- if v.Type().Kind() == Float32 && t.Kind() == Float32 {
- // Don't do any conversion if both types have underlying type float32.
- // This avoids converting to float64 and back, which will
- // convert a signaling NaN to a quiet NaN. See issue 36400.
- return makeFloat32(v.flag.ro(), *(*float32)(v.ptr), t)
- }
- return makeFloat(v.flag.ro(), v.Float(), t)
-}
-
-// convertOp: complexXX -> complexXX
-func cvtComplex(v Value, t Type) Value {
- return makeComplex(v.flag.ro(), v.Complex(), t)
-}
-
-// convertOp: intXX -> string
-func cvtIntString(v Value, t Type) Value {
- s := "\uFFFD"
- if x := v.Int(); int64(rune(x)) == x {
- s = string(rune(x))
- }
- return makeString(v.flag.ro(), s, t)
-}
-
-// convertOp: uintXX -> string
-func cvtUintString(v Value, t Type) Value {
- s := "\uFFFD"
- if x := v.Uint(); uint64(rune(x)) == x {
- s = string(rune(x))
- }
- return makeString(v.flag.ro(), s, t)
-}
-
-// convertOp: []byte -> string
-func cvtBytesString(v Value, t Type) Value {
- return makeString(v.flag.ro(), string(v.Bytes()), t)
-}
-
-// convertOp: string -> []byte
-func cvtStringBytes(v Value, t Type) Value {
- return makeBytes(v.flag.ro(), []byte(v.String()), t)
-}
-
-// convertOp: []rune -> string
-func cvtRunesString(v Value, t Type) Value {
- return makeString(v.flag.ro(), string(v.runes()), t)
-}
-
-// convertOp: string -> []rune
-func cvtStringRunes(v Value, t Type) Value {
- return makeRunes(v.flag.ro(), []rune(v.String()), t)
-}
-
-// convertOp: []T -> *[N]T
-func cvtSliceArrayPtr(v Value, t Type) Value {
- n := t.Elem().Len()
- if n > v.Len() {
- panic("reflect: cannot convert slice with length " + itoa.Itoa(v.Len()) + " to pointer to array with length " + itoa.Itoa(n))
- }
- h := (*unsafeheader.Slice)(v.ptr)
- return Value{t.common(), h.Data, v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Pointer)}
-}
-
-// convertOp: []T -> [N]T
-func cvtSliceArray(v Value, t Type) Value {
- n := t.Len()
- if n > v.Len() {
- panic("reflect: cannot convert slice with length " + itoa.Itoa(v.Len()) + " to array with length " + itoa.Itoa(n))
- }
- h := (*unsafeheader.Slice)(v.ptr)
- typ := t.common()
- ptr := h.Data
- c := unsafe_New(typ)
- typedmemmove(typ, c, ptr)
- ptr = c
-
- return Value{typ, ptr, v.flag&^(flagAddr|flagKindMask) | flag(Array)}
-}
-
-// convertOp: direct copy
-func cvtDirect(v Value, typ Type) Value {
- f := v.flag
- t := typ.common()
- ptr := v.ptr
- if f&flagAddr != 0 {
- // indirect, mutable word - make a copy
- c := unsafe_New(t)
- typedmemmove(t, c, ptr)
- ptr = c
- f &^= flagAddr
- }
- return Value{t, ptr, v.flag.ro() | f} // v.flag.ro()|f == f?
-}
-
-// convertOp: concrete -> interface
-func cvtT2I(v Value, typ Type) Value {
- target := unsafe_New(typ.common())
- x := valueInterface(v, false)
- if typ.NumMethod() == 0 {
- *(*any)(target) = x
- } else {
- ifaceE2I(typ.(*rtype), x, target)
- }
- return Value{typ.common(), target, v.flag.ro() | flagIndir | flag(Interface)}
-}
-
-// convertOp: interface -> interface
-func cvtI2I(v Value, typ Type) Value {
- if v.IsNil() {
- ret := Zero(typ)
- ret.flag |= v.flag.ro()
- return ret
- }
- return cvtT2I(v.Elem(), typ)
-}
-
-// implemented in ../runtime
-func chancap(ch unsafe.Pointer) int
-func chanclose(ch unsafe.Pointer)
-func chanlen(ch unsafe.Pointer) int
-
-// Note: some of the noescape annotations below are technically a lie,
-// but safe in the context of this package. Functions like chansend
-// and mapassign don't escape the referent, but may escape anything
-// the referent points to (they do shallow copies of the referent).
-// It is safe in this package because the referent may only point
-// to something a Value may point to, and that is always in the heap
-// (due to the escapes() call in ValueOf).
-
-//go:noescape
-func chanrecv(ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
-
-//go:noescape
-func chansend(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
-
-func makechan(typ *rtype, size int) (ch unsafe.Pointer)
-func makemap(t *rtype, cap int) (m unsafe.Pointer)
-
-//go:noescape
-func mapaccess(t *rtype, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
-
-//go:noescape
-func mapaccess_faststr(t *rtype, m unsafe.Pointer, key string) (val unsafe.Pointer)
-
-//go:noescape
-func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
-
-//go:noescape
-func mapassign_faststr(t *rtype, m unsafe.Pointer, key string, val unsafe.Pointer)
-
-//go:noescape
-func mapdelete(t *rtype, m unsafe.Pointer, key unsafe.Pointer)
-
-//go:noescape
-func mapdelete_faststr(t *rtype, m unsafe.Pointer, key string)
-
-//go:noescape
-func mapiterinit(t *rtype, m unsafe.Pointer, it *hiter)
-
-//go:noescape
-func mapiterkey(it *hiter) (key unsafe.Pointer)
-
-//go:noescape
-func mapiterelem(it *hiter) (elem unsafe.Pointer)
-
-//go:noescape
-func mapiternext(it *hiter)
-
-//go:noescape
-func maplen(m unsafe.Pointer) int
-
-// call calls fn with "stackArgsSize" bytes of stack arguments laid out
-// at stackArgs and register arguments laid out in regArgs. frameSize is
-// the total amount of stack space that will be reserved by call, so this
-// should include enough space to spill register arguments to the stack in
-// case of preemption.
-//
-// After fn returns, call copies stackArgsSize-stackRetOffset result bytes
-// back into stackArgs+stackRetOffset before returning, for any return
-// values passed on the stack. Register-based return values will be found
-// in the same regArgs structure.
-//
-// regArgs must also be prepared with an appropriate ReturnIsPtr bitmap
-// indicating which registers will contain pointer-valued return values. The
-// purpose of this bitmap is to keep pointers visible to the GC between
-// returning from reflectcall and actually using them.
-//
-// If copying result bytes back from the stack, the caller must pass the
-// argument frame type as stackArgsType, so that call can execute appropriate
-// write barriers during the copy.
-//
-// Arguments passed through to call do not escape. The type is used only in a
-// very limited callee of call, the stackArgs are copied, and regArgs is only
-// used in the call frame.
-//
-//go:noescape
-//go:linkname call runtime.reflectcall
-func call(stackArgsType *rtype, f, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-
-func ifaceE2I(t *rtype, src any, dst unsafe.Pointer)
-
-// memmove copies size bytes to dst from src. No write barriers are used.
-//
-//go:noescape
-func memmove(dst, src unsafe.Pointer, size uintptr)
-
-// typedmemmove copies a value of type t to dst from src.
-//
-//go:noescape
-func typedmemmove(t *rtype, dst, src unsafe.Pointer)
-
-// typedmemmovepartial is like typedmemmove but assumes that
-// dst and src point off bytes into the value and only copies size bytes.
-//
-//go:noescape
-func typedmemmovepartial(t *rtype, dst, src unsafe.Pointer, off, size uintptr)
-
-// typedmemclr zeros the value at ptr of type t.
-//
-//go:noescape
-func typedmemclr(t *rtype, ptr unsafe.Pointer)
-
-// typedmemclrpartial is like typedmemclr but assumes that
-// dst points off bytes into the value and only clears size bytes.
-//
-//go:noescape
-func typedmemclrpartial(t *rtype, ptr unsafe.Pointer, off, size uintptr)
-
-// typedslicecopy copies a slice of elemType values from src to dst,
-// returning the number of elements copied.
-//
-//go:noescape
-func typedslicecopy(elemType *rtype, dst, src unsafeheader.Slice) int
-
-//go:noescape
-func typehash(t *rtype, p unsafe.Pointer, h uintptr) uintptr
-
-func verifyNotInHeapPtr(p uintptr) bool
-
-//go:noescape
-func growslice(t *rtype, old unsafeheader.Slice, num int) unsafeheader.Slice
-
-// Dummy annotation marking that the value x escapes,
-// for use in cases where the reflect code is so clever that
-// the compiler cannot follow.
-func escapes(x any) {
- if dummy.b {
- dummy.x = x
- }
-}
-
-var dummy struct {
- b bool
- x any
-}
diff --git a/contrib/go/_std_1.20/src/reflect/ya.make b/contrib/go/_std_1.20/src/reflect/ya.make
deleted file mode 100644
index e985631eaf..0000000000
--- a/contrib/go/_std_1.20/src/reflect/ya.make
+++ /dev/null
@@ -1,30 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- abi.go
- deepequal.go
- float32reg_generic.go
- makefunc.go
- swapper.go
- type.go
- value.go
- visiblefields.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- asm_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- asm_amd64.s
- )
-ENDIF()
-
-END()
-
-RECURSE(
- internal
-)
diff --git a/contrib/go/_std_1.20/src/regexp/regexp.go b/contrib/go/_std_1.20/src/regexp/regexp.go
deleted file mode 100644
index 990c06e891..0000000000
--- a/contrib/go/_std_1.20/src/regexp/regexp.go
+++ /dev/null
@@ -1,1285 +0,0 @@
-// Copyright 2009 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 regexp implements regular expression search.
-//
-// The syntax of the regular expressions accepted is the same
-// general syntax used by Perl, Python, and other languages.
-// More precisely, it is the syntax accepted by RE2 and described at
-// https://golang.org/s/re2syntax, except for \C.
-// For an overview of the syntax, run
-//
-// go doc regexp/syntax
-//
-// The regexp implementation provided by this package is
-// guaranteed to run in time linear in the size of the input.
-// (This is a property not guaranteed by most open source
-// implementations of regular expressions.) For more information
-// about this property, see
-//
-// https://swtch.com/~rsc/regexp/regexp1.html
-//
-// or any book about automata theory.
-//
-// All characters are UTF-8-encoded code points.
-// Following utf8.DecodeRune, each byte of an invalid UTF-8 sequence
-// is treated as if it encoded utf8.RuneError (U+FFFD).
-//
-// There are 16 methods of Regexp that match a regular expression and identify
-// the matched text. Their names are matched by this regular expression:
-//
-// Find(All)?(String)?(Submatch)?(Index)?
-//
-// If 'All' is present, the routine matches successive non-overlapping
-// matches of the entire expression. Empty matches abutting a preceding
-// match are ignored. The return value is a slice containing the successive
-// return values of the corresponding non-'All' routine. These routines take
-// an extra integer argument, n. If n >= 0, the function returns at most n
-// matches/submatches; otherwise, it returns all of them.
-//
-// If 'String' is present, the argument is a string; otherwise it is a slice
-// of bytes; return values are adjusted as appropriate.
-//
-// If 'Submatch' is present, the return value is a slice identifying the
-// successive submatches of the expression. Submatches are matches of
-// parenthesized subexpressions (also known as capturing groups) within the
-// regular expression, numbered from left to right in order of opening
-// parenthesis. Submatch 0 is the match of the entire expression, submatch 1 is
-// the match of the first parenthesized subexpression, and so on.
-//
-// If 'Index' is present, matches and submatches are identified by byte index
-// pairs within the input string: result[2*n:2*n+2] identifies the indexes of
-// the nth submatch. The pair for n==0 identifies the match of the entire
-// expression. If 'Index' is not present, the match is identified by the text
-// of the match/submatch. If an index is negative or text is nil, it means that
-// subexpression did not match any string in the input. For 'String' versions
-// an empty string means either no match or an empty match.
-//
-// There is also a subset of the methods that can be applied to text read
-// from a RuneReader:
-//
-// MatchReader, FindReaderIndex, FindReaderSubmatchIndex
-//
-// This set may grow. Note that regular expression matches may need to
-// examine text beyond the text returned by a match, so the methods that
-// match text from a RuneReader may read arbitrarily far into the input
-// before returning.
-//
-// (There are a few other methods that do not match this pattern.)
-package regexp
-
-import (
- "bytes"
- "io"
- "regexp/syntax"
- "strconv"
- "strings"
- "sync"
- "unicode"
- "unicode/utf8"
-)
-
-// Regexp is the representation of a compiled regular expression.
-// A Regexp is safe for concurrent use by multiple goroutines,
-// except for configuration methods, such as Longest.
-type Regexp struct {
- expr string // as passed to Compile
- prog *syntax.Prog // compiled program
- onepass *onePassProg // onepass program or nil
- numSubexp int
- maxBitStateLen int
- subexpNames []string
- prefix string // required prefix in unanchored matches
- prefixBytes []byte // prefix, as a []byte
- prefixRune rune // first rune in prefix
- prefixEnd uint32 // pc for last rune in prefix
- mpool int // pool for machines
- matchcap int // size of recorded match lengths
- prefixComplete bool // prefix is the entire regexp
- cond syntax.EmptyOp // empty-width conditions required at start of match
- minInputLen int // minimum length of the input in bytes
-
- // This field can be modified by the Longest method,
- // but it is otherwise read-only.
- longest bool // whether regexp prefers leftmost-longest match
-}
-
-// String returns the source text used to compile the regular expression.
-func (re *Regexp) String() string {
- return re.expr
-}
-
-// Copy returns a new Regexp object copied from re.
-// Calling Longest on one copy does not affect another.
-//
-// Deprecated: In earlier releases, when using a Regexp in multiple goroutines,
-// giving each goroutine its own copy helped to avoid lock contention.
-// As of Go 1.12, using Copy is no longer necessary to avoid lock contention.
-// Copy may still be appropriate if the reason for its use is to make
-// two copies with different Longest settings.
-func (re *Regexp) Copy() *Regexp {
- re2 := *re
- return &re2
-}
-
-// Compile parses a regular expression and returns, if successful,
-// a Regexp object that can be used to match against text.
-//
-// When matching against text, the regexp returns a match that
-// begins as early as possible in the input (leftmost), and among those
-// it chooses the one that a backtracking search would have found first.
-// This so-called leftmost-first matching is the same semantics
-// that Perl, Python, and other implementations use, although this
-// package implements it without the expense of backtracking.
-// For POSIX leftmost-longest matching, see CompilePOSIX.
-func Compile(expr string) (*Regexp, error) {
- return compile(expr, syntax.Perl, false)
-}
-
-// CompilePOSIX is like Compile but restricts the regular expression
-// to POSIX ERE (egrep) syntax and changes the match semantics to
-// leftmost-longest.
-//
-// That is, when matching against text, the regexp returns a match that
-// begins as early as possible in the input (leftmost), and among those
-// it chooses a match that is as long as possible.
-// This so-called leftmost-longest matching is the same semantics
-// that early regular expression implementations used and that POSIX
-// specifies.
-//
-// However, there can be multiple leftmost-longest matches, with different
-// submatch choices, and here this package diverges from POSIX.
-// Among the possible leftmost-longest matches, this package chooses
-// the one that a backtracking search would have found first, while POSIX
-// specifies that the match be chosen to maximize the length of the first
-// subexpression, then the second, and so on from left to right.
-// The POSIX rule is computationally prohibitive and not even well-defined.
-// See https://swtch.com/~rsc/regexp/regexp2.html#posix for details.
-func CompilePOSIX(expr string) (*Regexp, error) {
- return compile(expr, syntax.POSIX, true)
-}
-
-// Longest makes future searches prefer the leftmost-longest match.
-// That is, when matching against text, the regexp returns a match that
-// begins as early as possible in the input (leftmost), and among those
-// it chooses a match that is as long as possible.
-// This method modifies the Regexp and may not be called concurrently
-// with any other methods.
-func (re *Regexp) Longest() {
- re.longest = true
-}
-
-func compile(expr string, mode syntax.Flags, longest bool) (*Regexp, error) {
- re, err := syntax.Parse(expr, mode)
- if err != nil {
- return nil, err
- }
- maxCap := re.MaxCap()
- capNames := re.CapNames()
-
- re = re.Simplify()
- prog, err := syntax.Compile(re)
- if err != nil {
- return nil, err
- }
- matchcap := prog.NumCap
- if matchcap < 2 {
- matchcap = 2
- }
- regexp := &Regexp{
- expr: expr,
- prog: prog,
- onepass: compileOnePass(prog),
- numSubexp: maxCap,
- subexpNames: capNames,
- cond: prog.StartCond(),
- longest: longest,
- matchcap: matchcap,
- minInputLen: minInputLen(re),
- }
- if regexp.onepass == nil {
- regexp.prefix, regexp.prefixComplete = prog.Prefix()
- regexp.maxBitStateLen = maxBitStateLen(prog)
- } else {
- regexp.prefix, regexp.prefixComplete, regexp.prefixEnd = onePassPrefix(prog)
- }
- if regexp.prefix != "" {
- // TODO(rsc): Remove this allocation by adding
- // IndexString to package bytes.
- regexp.prefixBytes = []byte(regexp.prefix)
- regexp.prefixRune, _ = utf8.DecodeRuneInString(regexp.prefix)
- }
-
- n := len(prog.Inst)
- i := 0
- for matchSize[i] != 0 && matchSize[i] < n {
- i++
- }
- regexp.mpool = i
-
- return regexp, nil
-}
-
-// Pools of *machine for use during (*Regexp).doExecute,
-// split up by the size of the execution queues.
-// matchPool[i] machines have queue size matchSize[i].
-// On a 64-bit system each queue entry is 16 bytes,
-// so matchPool[0] has 16*2*128 = 4kB queues, etc.
-// The final matchPool is a catch-all for very large queues.
-var (
- matchSize = [...]int{128, 512, 2048, 16384, 0}
- matchPool [len(matchSize)]sync.Pool
-)
-
-// get returns a machine to use for matching re.
-// It uses the re's machine cache if possible, to avoid
-// unnecessary allocation.
-func (re *Regexp) get() *machine {
- m, ok := matchPool[re.mpool].Get().(*machine)
- if !ok {
- m = new(machine)
- }
- m.re = re
- m.p = re.prog
- if cap(m.matchcap) < re.matchcap {
- m.matchcap = make([]int, re.matchcap)
- for _, t := range m.pool {
- t.cap = make([]int, re.matchcap)
- }
- }
-
- // Allocate queues if needed.
- // Or reallocate, for "large" match pool.
- n := matchSize[re.mpool]
- if n == 0 { // large pool
- n = len(re.prog.Inst)
- }
- if len(m.q0.sparse) < n {
- m.q0 = queue{make([]uint32, n), make([]entry, 0, n)}
- m.q1 = queue{make([]uint32, n), make([]entry, 0, n)}
- }
- return m
-}
-
-// put returns a machine to the correct machine pool.
-func (re *Regexp) put(m *machine) {
- m.re = nil
- m.p = nil
- m.inputs.clear()
- matchPool[re.mpool].Put(m)
-}
-
-// minInputLen walks the regexp to find the minimum length of any matchable input.
-func minInputLen(re *syntax.Regexp) int {
- switch re.Op {
- default:
- return 0
- case syntax.OpAnyChar, syntax.OpAnyCharNotNL, syntax.OpCharClass:
- return 1
- case syntax.OpLiteral:
- l := 0
- for _, r := range re.Rune {
- if r == utf8.RuneError {
- l++
- } else {
- l += utf8.RuneLen(r)
- }
- }
- return l
- case syntax.OpCapture, syntax.OpPlus:
- return minInputLen(re.Sub[0])
- case syntax.OpRepeat:
- return re.Min * minInputLen(re.Sub[0])
- case syntax.OpConcat:
- l := 0
- for _, sub := range re.Sub {
- l += minInputLen(sub)
- }
- return l
- case syntax.OpAlternate:
- l := minInputLen(re.Sub[0])
- var lnext int
- for _, sub := range re.Sub[1:] {
- lnext = minInputLen(sub)
- if lnext < l {
- l = lnext
- }
- }
- return l
- }
-}
-
-// MustCompile is like Compile but panics if the expression cannot be parsed.
-// It simplifies safe initialization of global variables holding compiled regular
-// expressions.
-func MustCompile(str string) *Regexp {
- regexp, err := Compile(str)
- if err != nil {
- panic(`regexp: Compile(` + quote(str) + `): ` + err.Error())
- }
- return regexp
-}
-
-// MustCompilePOSIX is like CompilePOSIX but panics if the expression cannot be parsed.
-// It simplifies safe initialization of global variables holding compiled regular
-// expressions.
-func MustCompilePOSIX(str string) *Regexp {
- regexp, err := CompilePOSIX(str)
- if err != nil {
- panic(`regexp: CompilePOSIX(` + quote(str) + `): ` + err.Error())
- }
- return regexp
-}
-
-func quote(s string) string {
- if strconv.CanBackquote(s) {
- return "`" + s + "`"
- }
- return strconv.Quote(s)
-}
-
-// NumSubexp returns the number of parenthesized subexpressions in this Regexp.
-func (re *Regexp) NumSubexp() int {
- return re.numSubexp
-}
-
-// SubexpNames returns the names of the parenthesized subexpressions
-// in this Regexp. The name for the first sub-expression is names[1],
-// so that if m is a match slice, the name for m[i] is SubexpNames()[i].
-// Since the Regexp as a whole cannot be named, names[0] is always
-// the empty string. The slice should not be modified.
-func (re *Regexp) SubexpNames() []string {
- return re.subexpNames
-}
-
-// SubexpIndex returns the index of the first subexpression with the given name,
-// or -1 if there is no subexpression with that name.
-//
-// Note that multiple subexpressions can be written using the same name, as in
-// (?P<bob>a+)(?P<bob>b+), which declares two subexpressions named "bob".
-// In this case, SubexpIndex returns the index of the leftmost such subexpression
-// in the regular expression.
-func (re *Regexp) SubexpIndex(name string) int {
- if name != "" {
- for i, s := range re.subexpNames {
- if name == s {
- return i
- }
- }
- }
- return -1
-}
-
-const endOfText rune = -1
-
-// input abstracts different representations of the input text. It provides
-// one-character lookahead.
-type input interface {
- step(pos int) (r rune, width int) // advance one rune
- canCheckPrefix() bool // can we look ahead without losing info?
- hasPrefix(re *Regexp) bool
- index(re *Regexp, pos int) int
- context(pos int) lazyFlag
-}
-
-// inputString scans a string.
-type inputString struct {
- str string
-}
-
-func (i *inputString) step(pos int) (rune, int) {
- if pos < len(i.str) {
- c := i.str[pos]
- if c < utf8.RuneSelf {
- return rune(c), 1
- }
- return utf8.DecodeRuneInString(i.str[pos:])
- }
- return endOfText, 0
-}
-
-func (i *inputString) canCheckPrefix() bool {
- return true
-}
-
-func (i *inputString) hasPrefix(re *Regexp) bool {
- return strings.HasPrefix(i.str, re.prefix)
-}
-
-func (i *inputString) index(re *Regexp, pos int) int {
- return strings.Index(i.str[pos:], re.prefix)
-}
-
-func (i *inputString) context(pos int) lazyFlag {
- r1, r2 := endOfText, endOfText
- // 0 < pos && pos <= len(i.str)
- if uint(pos-1) < uint(len(i.str)) {
- r1 = rune(i.str[pos-1])
- if r1 >= utf8.RuneSelf {
- r1, _ = utf8.DecodeLastRuneInString(i.str[:pos])
- }
- }
- // 0 <= pos && pos < len(i.str)
- if uint(pos) < uint(len(i.str)) {
- r2 = rune(i.str[pos])
- if r2 >= utf8.RuneSelf {
- r2, _ = utf8.DecodeRuneInString(i.str[pos:])
- }
- }
- return newLazyFlag(r1, r2)
-}
-
-// inputBytes scans a byte slice.
-type inputBytes struct {
- str []byte
-}
-
-func (i *inputBytes) step(pos int) (rune, int) {
- if pos < len(i.str) {
- c := i.str[pos]
- if c < utf8.RuneSelf {
- return rune(c), 1
- }
- return utf8.DecodeRune(i.str[pos:])
- }
- return endOfText, 0
-}
-
-func (i *inputBytes) canCheckPrefix() bool {
- return true
-}
-
-func (i *inputBytes) hasPrefix(re *Regexp) bool {
- return bytes.HasPrefix(i.str, re.prefixBytes)
-}
-
-func (i *inputBytes) index(re *Regexp, pos int) int {
- return bytes.Index(i.str[pos:], re.prefixBytes)
-}
-
-func (i *inputBytes) context(pos int) lazyFlag {
- r1, r2 := endOfText, endOfText
- // 0 < pos && pos <= len(i.str)
- if uint(pos-1) < uint(len(i.str)) {
- r1 = rune(i.str[pos-1])
- if r1 >= utf8.RuneSelf {
- r1, _ = utf8.DecodeLastRune(i.str[:pos])
- }
- }
- // 0 <= pos && pos < len(i.str)
- if uint(pos) < uint(len(i.str)) {
- r2 = rune(i.str[pos])
- if r2 >= utf8.RuneSelf {
- r2, _ = utf8.DecodeRune(i.str[pos:])
- }
- }
- return newLazyFlag(r1, r2)
-}
-
-// inputReader scans a RuneReader.
-type inputReader struct {
- r io.RuneReader
- atEOT bool
- pos int
-}
-
-func (i *inputReader) step(pos int) (rune, int) {
- if !i.atEOT && pos != i.pos {
- return endOfText, 0
-
- }
- r, w, err := i.r.ReadRune()
- if err != nil {
- i.atEOT = true
- return endOfText, 0
- }
- i.pos += w
- return r, w
-}
-
-func (i *inputReader) canCheckPrefix() bool {
- return false
-}
-
-func (i *inputReader) hasPrefix(re *Regexp) bool {
- return false
-}
-
-func (i *inputReader) index(re *Regexp, pos int) int {
- return -1
-}
-
-func (i *inputReader) context(pos int) lazyFlag {
- return 0 // not used
-}
-
-// LiteralPrefix returns a literal string that must begin any match
-// of the regular expression re. It returns the boolean true if the
-// literal string comprises the entire regular expression.
-func (re *Regexp) LiteralPrefix() (prefix string, complete bool) {
- return re.prefix, re.prefixComplete
-}
-
-// MatchReader reports whether the text returned by the RuneReader
-// contains any match of the regular expression re.
-func (re *Regexp) MatchReader(r io.RuneReader) bool {
- return re.doMatch(r, nil, "")
-}
-
-// MatchString reports whether the string s
-// contains any match of the regular expression re.
-func (re *Regexp) MatchString(s string) bool {
- return re.doMatch(nil, nil, s)
-}
-
-// Match reports whether the byte slice b
-// contains any match of the regular expression re.
-func (re *Regexp) Match(b []byte) bool {
- return re.doMatch(nil, b, "")
-}
-
-// MatchReader reports whether the text returned by the RuneReader
-// contains any match of the regular expression pattern.
-// More complicated queries need to use Compile and the full Regexp interface.
-func MatchReader(pattern string, r io.RuneReader) (matched bool, err error) {
- re, err := Compile(pattern)
- if err != nil {
- return false, err
- }
- return re.MatchReader(r), nil
-}
-
-// MatchString reports whether the string s
-// contains any match of the regular expression pattern.
-// More complicated queries need to use Compile and the full Regexp interface.
-func MatchString(pattern string, s string) (matched bool, err error) {
- re, err := Compile(pattern)
- if err != nil {
- return false, err
- }
- return re.MatchString(s), nil
-}
-
-// Match reports whether the byte slice b
-// contains any match of the regular expression pattern.
-// More complicated queries need to use Compile and the full Regexp interface.
-func Match(pattern string, b []byte) (matched bool, err error) {
- re, err := Compile(pattern)
- if err != nil {
- return false, err
- }
- return re.Match(b), nil
-}
-
-// ReplaceAllString returns a copy of src, replacing matches of the Regexp
-// with the replacement string repl. Inside repl, $ signs are interpreted as
-// in Expand, so for instance $1 represents the text of the first submatch.
-func (re *Regexp) ReplaceAllString(src, repl string) string {
- n := 2
- if strings.Contains(repl, "$") {
- n = 2 * (re.numSubexp + 1)
- }
- b := re.replaceAll(nil, src, n, func(dst []byte, match []int) []byte {
- return re.expand(dst, repl, nil, src, match)
- })
- return string(b)
-}
-
-// ReplaceAllLiteralString returns a copy of src, replacing matches of the Regexp
-// with the replacement string repl. The replacement repl is substituted directly,
-// without using Expand.
-func (re *Regexp) ReplaceAllLiteralString(src, repl string) string {
- return string(re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte {
- return append(dst, repl...)
- }))
-}
-
-// ReplaceAllStringFunc returns a copy of src in which all matches of the
-// Regexp have been replaced by the return value of function repl applied
-// to the matched substring. The replacement returned by repl is substituted
-// directly, without using Expand.
-func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string {
- b := re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte {
- return append(dst, repl(src[match[0]:match[1]])...)
- })
- return string(b)
-}
-
-func (re *Regexp) replaceAll(bsrc []byte, src string, nmatch int, repl func(dst []byte, m []int) []byte) []byte {
- lastMatchEnd := 0 // end position of the most recent match
- searchPos := 0 // position where we next look for a match
- var buf []byte
- var endPos int
- if bsrc != nil {
- endPos = len(bsrc)
- } else {
- endPos = len(src)
- }
- if nmatch > re.prog.NumCap {
- nmatch = re.prog.NumCap
- }
-
- var dstCap [2]int
- for searchPos <= endPos {
- a := re.doExecute(nil, bsrc, src, searchPos, nmatch, dstCap[:0])
- if len(a) == 0 {
- break // no more matches
- }
-
- // Copy the unmatched characters before this match.
- if bsrc != nil {
- buf = append(buf, bsrc[lastMatchEnd:a[0]]...)
- } else {
- buf = append(buf, src[lastMatchEnd:a[0]]...)
- }
-
- // Now insert a copy of the replacement string, but not for a
- // match of the empty string immediately after another match.
- // (Otherwise, we get double replacement for patterns that
- // match both empty and nonempty strings.)
- if a[1] > lastMatchEnd || a[0] == 0 {
- buf = repl(buf, a)
- }
- lastMatchEnd = a[1]
-
- // Advance past this match; always advance at least one character.
- var width int
- if bsrc != nil {
- _, width = utf8.DecodeRune(bsrc[searchPos:])
- } else {
- _, width = utf8.DecodeRuneInString(src[searchPos:])
- }
- if searchPos+width > a[1] {
- searchPos += width
- } else if searchPos+1 > a[1] {
- // This clause is only needed at the end of the input
- // string. In that case, DecodeRuneInString returns width=0.
- searchPos++
- } else {
- searchPos = a[1]
- }
- }
-
- // Copy the unmatched characters after the last match.
- if bsrc != nil {
- buf = append(buf, bsrc[lastMatchEnd:]...)
- } else {
- buf = append(buf, src[lastMatchEnd:]...)
- }
-
- return buf
-}
-
-// ReplaceAll returns a copy of src, replacing matches of the Regexp
-// with the replacement text repl. Inside repl, $ signs are interpreted as
-// in Expand, so for instance $1 represents the text of the first submatch.
-func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
- n := 2
- if bytes.IndexByte(repl, '$') >= 0 {
- n = 2 * (re.numSubexp + 1)
- }
- srepl := ""
- b := re.replaceAll(src, "", n, func(dst []byte, match []int) []byte {
- if len(srepl) != len(repl) {
- srepl = string(repl)
- }
- return re.expand(dst, srepl, src, "", match)
- })
- return b
-}
-
-// ReplaceAllLiteral returns a copy of src, replacing matches of the Regexp
-// with the replacement bytes repl. The replacement repl is substituted directly,
-// without using Expand.
-func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte {
- return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte {
- return append(dst, repl...)
- })
-}
-
-// ReplaceAllFunc returns a copy of src in which all matches of the
-// Regexp have been replaced by the return value of function repl applied
-// to the matched byte slice. The replacement returned by repl is substituted
-// directly, without using Expand.
-func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte {
- return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte {
- return append(dst, repl(src[match[0]:match[1]])...)
- })
-}
-
-// Bitmap used by func special to check whether a character needs to be escaped.
-var specialBytes [16]byte
-
-// special reports whether byte b needs to be escaped by QuoteMeta.
-func special(b byte) bool {
- return b < utf8.RuneSelf && specialBytes[b%16]&(1<<(b/16)) != 0
-}
-
-func init() {
- for _, b := range []byte(`\.+*?()|[]{}^$`) {
- specialBytes[b%16] |= 1 << (b / 16)
- }
-}
-
-// QuoteMeta returns a string that escapes all regular expression metacharacters
-// inside the argument text; the returned string is a regular expression matching
-// the literal text.
-func QuoteMeta(s string) string {
- // A byte loop is correct because all metacharacters are ASCII.
- var i int
- for i = 0; i < len(s); i++ {
- if special(s[i]) {
- break
- }
- }
- // No meta characters found, so return original string.
- if i >= len(s) {
- return s
- }
-
- b := make([]byte, 2*len(s)-i)
- copy(b, s[:i])
- j := i
- for ; i < len(s); i++ {
- if special(s[i]) {
- b[j] = '\\'
- j++
- }
- b[j] = s[i]
- j++
- }
- return string(b[:j])
-}
-
-// The number of capture values in the program may correspond
-// to fewer capturing expressions than are in the regexp.
-// For example, "(a){0}" turns into an empty program, so the
-// maximum capture in the program is 0 but we need to return
-// an expression for \1. Pad appends -1s to the slice a as needed.
-func (re *Regexp) pad(a []int) []int {
- if a == nil {
- // No match.
- return nil
- }
- n := (1 + re.numSubexp) * 2
- for len(a) < n {
- a = append(a, -1)
- }
- return a
-}
-
-// allMatches calls deliver at most n times
-// with the location of successive matches in the input text.
-// The input text is b if non-nil, otherwise s.
-func (re *Regexp) allMatches(s string, b []byte, n int, deliver func([]int)) {
- var end int
- if b == nil {
- end = len(s)
- } else {
- end = len(b)
- }
-
- for pos, i, prevMatchEnd := 0, 0, -1; i < n && pos <= end; {
- matches := re.doExecute(nil, b, s, pos, re.prog.NumCap, nil)
- if len(matches) == 0 {
- break
- }
-
- accept := true
- if matches[1] == pos {
- // We've found an empty match.
- if matches[0] == prevMatchEnd {
- // We don't allow an empty match right
- // after a previous match, so ignore it.
- accept = false
- }
- var width int
- if b == nil {
- is := inputString{str: s}
- _, width = is.step(pos)
- } else {
- ib := inputBytes{str: b}
- _, width = ib.step(pos)
- }
- if width > 0 {
- pos += width
- } else {
- pos = end + 1
- }
- } else {
- pos = matches[1]
- }
- prevMatchEnd = matches[1]
-
- if accept {
- deliver(re.pad(matches))
- i++
- }
- }
-}
-
-// Find returns a slice holding the text of the leftmost match in b of the regular expression.
-// A return value of nil indicates no match.
-func (re *Regexp) Find(b []byte) []byte {
- var dstCap [2]int
- a := re.doExecute(nil, b, "", 0, 2, dstCap[:0])
- if a == nil {
- return nil
- }
- return b[a[0]:a[1]:a[1]]
-}
-
-// FindIndex returns a two-element slice of integers defining the location of
-// the leftmost match in b of the regular expression. The match itself is at
-// b[loc[0]:loc[1]].
-// A return value of nil indicates no match.
-func (re *Regexp) FindIndex(b []byte) (loc []int) {
- a := re.doExecute(nil, b, "", 0, 2, nil)
- if a == nil {
- return nil
- }
- return a[0:2]
-}
-
-// FindString returns a string holding the text of the leftmost match in s of the regular
-// expression. If there is no match, the return value is an empty string,
-// but it will also be empty if the regular expression successfully matches
-// an empty string. Use FindStringIndex or FindStringSubmatch if it is
-// necessary to distinguish these cases.
-func (re *Regexp) FindString(s string) string {
- var dstCap [2]int
- a := re.doExecute(nil, nil, s, 0, 2, dstCap[:0])
- if a == nil {
- return ""
- }
- return s[a[0]:a[1]]
-}
-
-// FindStringIndex returns a two-element slice of integers defining the
-// location of the leftmost match in s of the regular expression. The match
-// itself is at s[loc[0]:loc[1]].
-// A return value of nil indicates no match.
-func (re *Regexp) FindStringIndex(s string) (loc []int) {
- a := re.doExecute(nil, nil, s, 0, 2, nil)
- if a == nil {
- return nil
- }
- return a[0:2]
-}
-
-// FindReaderIndex returns a two-element slice of integers defining the
-// location of the leftmost match of the regular expression in text read from
-// the RuneReader. The match text was found in the input stream at
-// byte offset loc[0] through loc[1]-1.
-// A return value of nil indicates no match.
-func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int) {
- a := re.doExecute(r, nil, "", 0, 2, nil)
- if a == nil {
- return nil
- }
- return a[0:2]
-}
-
-// FindSubmatch returns a slice of slices holding the text of the leftmost
-// match of the regular expression in b and the matches, if any, of its
-// subexpressions, as defined by the 'Submatch' descriptions in the package
-// comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindSubmatch(b []byte) [][]byte {
- var dstCap [4]int
- a := re.doExecute(nil, b, "", 0, re.prog.NumCap, dstCap[:0])
- if a == nil {
- return nil
- }
- ret := make([][]byte, 1+re.numSubexp)
- for i := range ret {
- if 2*i < len(a) && a[2*i] >= 0 {
- ret[i] = b[a[2*i]:a[2*i+1]:a[2*i+1]]
- }
- }
- return ret
-}
-
-// Expand appends template to dst and returns the result; during the
-// append, Expand replaces variables in the template with corresponding
-// matches drawn from src. The match slice should have been returned by
-// FindSubmatchIndex.
-//
-// In the template, a variable is denoted by a substring of the form
-// $name or ${name}, where name is a non-empty sequence of letters,
-// digits, and underscores. A purely numeric name like $1 refers to
-// the submatch with the corresponding index; other names refer to
-// capturing parentheses named with the (?P<name>...) syntax. A
-// reference to an out of range or unmatched index or a name that is not
-// present in the regular expression is replaced with an empty slice.
-//
-// In the $name form, name is taken to be as long as possible: $1x is
-// equivalent to ${1x}, not ${1}x, and, $10 is equivalent to ${10}, not ${1}0.
-//
-// To insert a literal $ in the output, use $$ in the template.
-func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte {
- return re.expand(dst, string(template), src, "", match)
-}
-
-// ExpandString is like Expand but the template and source are strings.
-// It appends to and returns a byte slice in order to give the calling
-// code control over allocation.
-func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte {
- return re.expand(dst, template, nil, src, match)
-}
-
-func (re *Regexp) expand(dst []byte, template string, bsrc []byte, src string, match []int) []byte {
- for len(template) > 0 {
- before, after, ok := strings.Cut(template, "$")
- if !ok {
- break
- }
- dst = append(dst, before...)
- template = after
- if template != "" && template[0] == '$' {
- // Treat $$ as $.
- dst = append(dst, '$')
- template = template[1:]
- continue
- }
- name, num, rest, ok := extract(template)
- if !ok {
- // Malformed; treat $ as raw text.
- dst = append(dst, '$')
- continue
- }
- template = rest
- if num >= 0 {
- if 2*num+1 < len(match) && match[2*num] >= 0 {
- if bsrc != nil {
- dst = append(dst, bsrc[match[2*num]:match[2*num+1]]...)
- } else {
- dst = append(dst, src[match[2*num]:match[2*num+1]]...)
- }
- }
- } else {
- for i, namei := range re.subexpNames {
- if name == namei && 2*i+1 < len(match) && match[2*i] >= 0 {
- if bsrc != nil {
- dst = append(dst, bsrc[match[2*i]:match[2*i+1]]...)
- } else {
- dst = append(dst, src[match[2*i]:match[2*i+1]]...)
- }
- break
- }
- }
- }
- }
- dst = append(dst, template...)
- return dst
-}
-
-// extract returns the name from a leading "name" or "{name}" in str.
-// (The $ has already been removed by the caller.)
-// If it is a number, extract returns num set to that number; otherwise num = -1.
-func extract(str string) (name string, num int, rest string, ok bool) {
- if str == "" {
- return
- }
- brace := false
- if str[0] == '{' {
- brace = true
- str = str[1:]
- }
- i := 0
- for i < len(str) {
- rune, size := utf8.DecodeRuneInString(str[i:])
- if !unicode.IsLetter(rune) && !unicode.IsDigit(rune) && rune != '_' {
- break
- }
- i += size
- }
- if i == 0 {
- // empty name is not okay
- return
- }
- name = str[:i]
- if brace {
- if i >= len(str) || str[i] != '}' {
- // missing closing brace
- return
- }
- i++
- }
-
- // Parse number.
- num = 0
- for i := 0; i < len(name); i++ {
- if name[i] < '0' || '9' < name[i] || num >= 1e8 {
- num = -1
- break
- }
- num = num*10 + int(name[i]) - '0'
- }
- // Disallow leading zeros.
- if name[0] == '0' && len(name) > 1 {
- num = -1
- }
-
- rest = str[i:]
- ok = true
- return
-}
-
-// FindSubmatchIndex returns a slice holding the index pairs identifying the
-// leftmost match of the regular expression in b and the matches, if any, of
-// its subexpressions, as defined by the 'Submatch' and 'Index' descriptions
-// in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindSubmatchIndex(b []byte) []int {
- return re.pad(re.doExecute(nil, b, "", 0, re.prog.NumCap, nil))
-}
-
-// FindStringSubmatch returns a slice of strings holding the text of the
-// leftmost match of the regular expression in s and the matches, if any, of
-// its subexpressions, as defined by the 'Submatch' description in the
-// package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindStringSubmatch(s string) []string {
- var dstCap [4]int
- a := re.doExecute(nil, nil, s, 0, re.prog.NumCap, dstCap[:0])
- if a == nil {
- return nil
- }
- ret := make([]string, 1+re.numSubexp)
- for i := range ret {
- if 2*i < len(a) && a[2*i] >= 0 {
- ret[i] = s[a[2*i]:a[2*i+1]]
- }
- }
- return ret
-}
-
-// FindStringSubmatchIndex returns a slice holding the index pairs
-// identifying the leftmost match of the regular expression in s and the
-// matches, if any, of its subexpressions, as defined by the 'Submatch' and
-// 'Index' descriptions in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindStringSubmatchIndex(s string) []int {
- return re.pad(re.doExecute(nil, nil, s, 0, re.prog.NumCap, nil))
-}
-
-// FindReaderSubmatchIndex returns a slice holding the index pairs
-// identifying the leftmost match of the regular expression of text read by
-// the RuneReader, and the matches, if any, of its subexpressions, as defined
-// by the 'Submatch' and 'Index' descriptions in the package comment. A
-// return value of nil indicates no match.
-func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int {
- return re.pad(re.doExecute(r, nil, "", 0, re.prog.NumCap, nil))
-}
-
-const startSize = 10 // The size at which to start a slice in the 'All' routines.
-
-// FindAll is the 'All' version of Find; it returns a slice of all successive
-// matches of the expression, as defined by the 'All' description in the
-// package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAll(b []byte, n int) [][]byte {
- if n < 0 {
- n = len(b) + 1
- }
- var result [][]byte
- re.allMatches("", b, n, func(match []int) {
- if result == nil {
- result = make([][]byte, 0, startSize)
- }
- result = append(result, b[match[0]:match[1]:match[1]])
- })
- return result
-}
-
-// FindAllIndex is the 'All' version of FindIndex; it returns a slice of all
-// successive matches of the expression, as defined by the 'All' description
-// in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllIndex(b []byte, n int) [][]int {
- if n < 0 {
- n = len(b) + 1
- }
- var result [][]int
- re.allMatches("", b, n, func(match []int) {
- if result == nil {
- result = make([][]int, 0, startSize)
- }
- result = append(result, match[0:2])
- })
- return result
-}
-
-// FindAllString is the 'All' version of FindString; it returns a slice of all
-// successive matches of the expression, as defined by the 'All' description
-// in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllString(s string, n int) []string {
- if n < 0 {
- n = len(s) + 1
- }
- var result []string
- re.allMatches(s, nil, n, func(match []int) {
- if result == nil {
- result = make([]string, 0, startSize)
- }
- result = append(result, s[match[0]:match[1]])
- })
- return result
-}
-
-// FindAllStringIndex is the 'All' version of FindStringIndex; it returns a
-// slice of all successive matches of the expression, as defined by the 'All'
-// description in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllStringIndex(s string, n int) [][]int {
- if n < 0 {
- n = len(s) + 1
- }
- var result [][]int
- re.allMatches(s, nil, n, func(match []int) {
- if result == nil {
- result = make([][]int, 0, startSize)
- }
- result = append(result, match[0:2])
- })
- return result
-}
-
-// FindAllSubmatch is the 'All' version of FindSubmatch; it returns a slice
-// of all successive matches of the expression, as defined by the 'All'
-// description in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte {
- if n < 0 {
- n = len(b) + 1
- }
- var result [][][]byte
- re.allMatches("", b, n, func(match []int) {
- if result == nil {
- result = make([][][]byte, 0, startSize)
- }
- slice := make([][]byte, len(match)/2)
- for j := range slice {
- if match[2*j] >= 0 {
- slice[j] = b[match[2*j]:match[2*j+1]:match[2*j+1]]
- }
- }
- result = append(result, slice)
- })
- return result
-}
-
-// FindAllSubmatchIndex is the 'All' version of FindSubmatchIndex; it returns
-// a slice of all successive matches of the expression, as defined by the
-// 'All' description in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int {
- if n < 0 {
- n = len(b) + 1
- }
- var result [][]int
- re.allMatches("", b, n, func(match []int) {
- if result == nil {
- result = make([][]int, 0, startSize)
- }
- result = append(result, match)
- })
- return result
-}
-
-// FindAllStringSubmatch is the 'All' version of FindStringSubmatch; it
-// returns a slice of all successive matches of the expression, as defined by
-// the 'All' description in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string {
- if n < 0 {
- n = len(s) + 1
- }
- var result [][]string
- re.allMatches(s, nil, n, func(match []int) {
- if result == nil {
- result = make([][]string, 0, startSize)
- }
- slice := make([]string, len(match)/2)
- for j := range slice {
- if match[2*j] >= 0 {
- slice[j] = s[match[2*j]:match[2*j+1]]
- }
- }
- result = append(result, slice)
- })
- return result
-}
-
-// FindAllStringSubmatchIndex is the 'All' version of
-// FindStringSubmatchIndex; it returns a slice of all successive matches of
-// the expression, as defined by the 'All' description in the package
-// comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int {
- if n < 0 {
- n = len(s) + 1
- }
- var result [][]int
- re.allMatches(s, nil, n, func(match []int) {
- if result == nil {
- result = make([][]int, 0, startSize)
- }
- result = append(result, match)
- })
- return result
-}
-
-// Split slices s into substrings separated by the expression and returns a slice of
-// the substrings between those expression matches.
-//
-// The slice returned by this method consists of all the substrings of s
-// not contained in the slice returned by FindAllString. When called on an expression
-// that contains no metacharacters, it is equivalent to strings.SplitN.
-//
-// Example:
-//
-// s := regexp.MustCompile("a*").Split("abaabaccadaaae", 5)
-// // s: ["", "b", "b", "c", "cadaaae"]
-//
-// The count determines the number of substrings to return:
-//
-// n > 0: at most n substrings; the last substring will be the unsplit remainder.
-// n == 0: the result is nil (zero substrings)
-// n < 0: all substrings
-func (re *Regexp) Split(s string, n int) []string {
-
- if n == 0 {
- return nil
- }
-
- if len(re.expr) > 0 && len(s) == 0 {
- return []string{""}
- }
-
- matches := re.FindAllStringIndex(s, n)
- strings := make([]string, 0, len(matches))
-
- beg := 0
- end := 0
- for _, match := range matches {
- if n > 0 && len(strings) >= n-1 {
- break
- }
-
- end = match[0]
- if match[1] != 0 {
- strings = append(strings, s[beg:end])
- }
- beg = match[1]
- }
-
- if end != len(s) {
- strings = append(strings, s[beg:])
- }
-
- return strings
-}
diff --git a/contrib/go/_std_1.20/src/regexp/syntax/op_string.go b/contrib/go/_std_1.20/src/regexp/syntax/op_string.go
deleted file mode 100644
index 3952b2bdd5..0000000000
--- a/contrib/go/_std_1.20/src/regexp/syntax/op_string.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Code generated by "stringer -type Op -trimprefix Op"; DO NOT EDIT.
-
-package syntax
-
-import "strconv"
-
-const (
- _Op_name_0 = "NoMatchEmptyMatchLiteralCharClassAnyCharNotNLAnyCharBeginLineEndLineBeginTextEndTextWordBoundaryNoWordBoundaryCaptureStarPlusQuestRepeatConcatAlternate"
- _Op_name_1 = "opPseudo"
-)
-
-var (
- _Op_index_0 = [...]uint8{0, 7, 17, 24, 33, 45, 52, 61, 68, 77, 84, 96, 110, 117, 121, 125, 130, 136, 142, 151}
-)
-
-func (i Op) String() string {
- switch {
- case 1 <= i && i <= 19:
- i -= 1
- return _Op_name_0[_Op_index_0[i]:_Op_index_0[i+1]]
- case i == 128:
- return _Op_name_1
- default:
- return "Op(" + strconv.FormatInt(int64(i), 10) + ")"
- }
-}
diff --git a/contrib/go/_std_1.20/src/regexp/syntax/prog.go b/contrib/go/_std_1.20/src/regexp/syntax/prog.go
deleted file mode 100644
index 896cdc42c2..0000000000
--- a/contrib/go/_std_1.20/src/regexp/syntax/prog.go
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright 2011 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 syntax
-
-import (
- "strconv"
- "strings"
- "unicode"
- "unicode/utf8"
-)
-
-// Compiled program.
-// May not belong in this package, but convenient for now.
-
-// A Prog is a compiled regular expression program.
-type Prog struct {
- Inst []Inst
- Start int // index of start instruction
- NumCap int // number of InstCapture insts in re
-}
-
-// An InstOp is an instruction opcode.
-type InstOp uint8
-
-const (
- InstAlt InstOp = iota
- InstAltMatch
- InstCapture
- InstEmptyWidth
- InstMatch
- InstFail
- InstNop
- InstRune
- InstRune1
- InstRuneAny
- InstRuneAnyNotNL
-)
-
-var instOpNames = []string{
- "InstAlt",
- "InstAltMatch",
- "InstCapture",
- "InstEmptyWidth",
- "InstMatch",
- "InstFail",
- "InstNop",
- "InstRune",
- "InstRune1",
- "InstRuneAny",
- "InstRuneAnyNotNL",
-}
-
-func (i InstOp) String() string {
- if uint(i) >= uint(len(instOpNames)) {
- return ""
- }
- return instOpNames[i]
-}
-
-// An EmptyOp specifies a kind or mixture of zero-width assertions.
-type EmptyOp uint8
-
-const (
- EmptyBeginLine EmptyOp = 1 << iota
- EmptyEndLine
- EmptyBeginText
- EmptyEndText
- EmptyWordBoundary
- EmptyNoWordBoundary
-)
-
-// EmptyOpContext returns the zero-width assertions
-// satisfied at the position between the runes r1 and r2.
-// Passing r1 == -1 indicates that the position is
-// at the beginning of the text.
-// Passing r2 == -1 indicates that the position is
-// at the end of the text.
-func EmptyOpContext(r1, r2 rune) EmptyOp {
- var op EmptyOp = EmptyNoWordBoundary
- var boundary byte
- switch {
- case IsWordChar(r1):
- boundary = 1
- case r1 == '\n':
- op |= EmptyBeginLine
- case r1 < 0:
- op |= EmptyBeginText | EmptyBeginLine
- }
- switch {
- case IsWordChar(r2):
- boundary ^= 1
- case r2 == '\n':
- op |= EmptyEndLine
- case r2 < 0:
- op |= EmptyEndText | EmptyEndLine
- }
- if boundary != 0 { // IsWordChar(r1) != IsWordChar(r2)
- op ^= (EmptyWordBoundary | EmptyNoWordBoundary)
- }
- return op
-}
-
-// IsWordChar reports whether r is considered a “word character”
-// during the evaluation of the \b and \B zero-width assertions.
-// These assertions are ASCII-only: the word characters are [A-Za-z0-9_].
-func IsWordChar(r rune) bool {
- return 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' || '0' <= r && r <= '9' || r == '_'
-}
-
-// An Inst is a single instruction in a regular expression program.
-type Inst struct {
- Op InstOp
- Out uint32 // all but InstMatch, InstFail
- Arg uint32 // InstAlt, InstAltMatch, InstCapture, InstEmptyWidth
- Rune []rune
-}
-
-func (p *Prog) String() string {
- var b strings.Builder
- dumpProg(&b, p)
- return b.String()
-}
-
-// skipNop follows any no-op or capturing instructions.
-func (p *Prog) skipNop(pc uint32) *Inst {
- i := &p.Inst[pc]
- for i.Op == InstNop || i.Op == InstCapture {
- i = &p.Inst[i.Out]
- }
- return i
-}
-
-// op returns i.Op but merges all the Rune special cases into InstRune
-func (i *Inst) op() InstOp {
- op := i.Op
- switch op {
- case InstRune1, InstRuneAny, InstRuneAnyNotNL:
- op = InstRune
- }
- return op
-}
-
-// Prefix returns a literal string that all matches for the
-// regexp must start with. Complete is true if the prefix
-// is the entire match.
-func (p *Prog) Prefix() (prefix string, complete bool) {
- i := p.skipNop(uint32(p.Start))
-
- // Avoid allocation of buffer if prefix is empty.
- if i.op() != InstRune || len(i.Rune) != 1 {
- return "", i.Op == InstMatch
- }
-
- // Have prefix; gather characters.
- var buf strings.Builder
- for i.op() == InstRune && len(i.Rune) == 1 && Flags(i.Arg)&FoldCase == 0 && i.Rune[0] != utf8.RuneError {
- buf.WriteRune(i.Rune[0])
- i = p.skipNop(i.Out)
- }
- return buf.String(), i.Op == InstMatch
-}
-
-// StartCond returns the leading empty-width conditions that must
-// be true in any match. It returns ^EmptyOp(0) if no matches are possible.
-func (p *Prog) StartCond() EmptyOp {
- var flag EmptyOp
- pc := uint32(p.Start)
- i := &p.Inst[pc]
-Loop:
- for {
- switch i.Op {
- case InstEmptyWidth:
- flag |= EmptyOp(i.Arg)
- case InstFail:
- return ^EmptyOp(0)
- case InstCapture, InstNop:
- // skip
- default:
- break Loop
- }
- pc = i.Out
- i = &p.Inst[pc]
- }
- return flag
-}
-
-const noMatch = -1
-
-// MatchRune reports whether the instruction matches (and consumes) r.
-// It should only be called when i.Op == InstRune.
-func (i *Inst) MatchRune(r rune) bool {
- return i.MatchRunePos(r) != noMatch
-}
-
-// MatchRunePos checks whether the instruction matches (and consumes) r.
-// If so, MatchRunePos returns the index of the matching rune pair
-// (or, when len(i.Rune) == 1, rune singleton).
-// If not, MatchRunePos returns -1.
-// MatchRunePos should only be called when i.Op == InstRune.
-func (i *Inst) MatchRunePos(r rune) int {
- rune := i.Rune
-
- switch len(rune) {
- case 0:
- return noMatch
-
- case 1:
- // Special case: single-rune slice is from literal string, not char class.
- r0 := rune[0]
- if r == r0 {
- return 0
- }
- if Flags(i.Arg)&FoldCase != 0 {
- for r1 := unicode.SimpleFold(r0); r1 != r0; r1 = unicode.SimpleFold(r1) {
- if r == r1 {
- return 0
- }
- }
- }
- return noMatch
-
- case 2:
- if r >= rune[0] && r <= rune[1] {
- return 0
- }
- return noMatch
-
- case 4, 6, 8:
- // Linear search for a few pairs.
- // Should handle ASCII well.
- for j := 0; j < len(rune); j += 2 {
- if r < rune[j] {
- return noMatch
- }
- if r <= rune[j+1] {
- return j / 2
- }
- }
- return noMatch
- }
-
- // Otherwise binary search.
- lo := 0
- hi := len(rune) / 2
- for lo < hi {
- m := lo + (hi-lo)/2
- if c := rune[2*m]; c <= r {
- if r <= rune[2*m+1] {
- return m
- }
- lo = m + 1
- } else {
- hi = m
- }
- }
- return noMatch
-}
-
-// MatchEmptyWidth reports whether the instruction matches
-// an empty string between the runes before and after.
-// It should only be called when i.Op == InstEmptyWidth.
-func (i *Inst) MatchEmptyWidth(before rune, after rune) bool {
- switch EmptyOp(i.Arg) {
- case EmptyBeginLine:
- return before == '\n' || before == -1
- case EmptyEndLine:
- return after == '\n' || after == -1
- case EmptyBeginText:
- return before == -1
- case EmptyEndText:
- return after == -1
- case EmptyWordBoundary:
- return IsWordChar(before) != IsWordChar(after)
- case EmptyNoWordBoundary:
- return IsWordChar(before) == IsWordChar(after)
- }
- panic("unknown empty width arg")
-}
-
-func (i *Inst) String() string {
- var b strings.Builder
- dumpInst(&b, i)
- return b.String()
-}
-
-func bw(b *strings.Builder, args ...string) {
- for _, s := range args {
- b.WriteString(s)
- }
-}
-
-func dumpProg(b *strings.Builder, p *Prog) {
- for j := range p.Inst {
- i := &p.Inst[j]
- pc := strconv.Itoa(j)
- if len(pc) < 3 {
- b.WriteString(" "[len(pc):])
- }
- if j == p.Start {
- pc += "*"
- }
- bw(b, pc, "\t")
- dumpInst(b, i)
- bw(b, "\n")
- }
-}
-
-func u32(i uint32) string {
- return strconv.FormatUint(uint64(i), 10)
-}
-
-func dumpInst(b *strings.Builder, i *Inst) {
- switch i.Op {
- case InstAlt:
- bw(b, "alt -> ", u32(i.Out), ", ", u32(i.Arg))
- case InstAltMatch:
- bw(b, "altmatch -> ", u32(i.Out), ", ", u32(i.Arg))
- case InstCapture:
- bw(b, "cap ", u32(i.Arg), " -> ", u32(i.Out))
- case InstEmptyWidth:
- bw(b, "empty ", u32(i.Arg), " -> ", u32(i.Out))
- case InstMatch:
- bw(b, "match")
- case InstFail:
- bw(b, "fail")
- case InstNop:
- bw(b, "nop -> ", u32(i.Out))
- case InstRune:
- if i.Rune == nil {
- // shouldn't happen
- bw(b, "rune <nil>")
- }
- bw(b, "rune ", strconv.QuoteToASCII(string(i.Rune)))
- if Flags(i.Arg)&FoldCase != 0 {
- bw(b, "/i")
- }
- bw(b, " -> ", u32(i.Out))
- case InstRune1:
- bw(b, "rune1 ", strconv.QuoteToASCII(string(i.Rune)), " -> ", u32(i.Out))
- case InstRuneAny:
- bw(b, "any -> ", u32(i.Out))
- case InstRuneAnyNotNL:
- bw(b, "anynotnl -> ", u32(i.Out))
- }
-}
diff --git a/contrib/go/_std_1.20/src/regexp/syntax/ya.make b/contrib/go/_std_1.20/src/regexp/syntax/ya.make
deleted file mode 100644
index 28101de956..0000000000
--- a/contrib/go/_std_1.20/src/regexp/syntax/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- compile.go
- doc.go
- op_string.go
- parse.go
- perl_groups.go
- prog.go
- regexp.go
- simplify.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/regexp/ya.make b/contrib/go/_std_1.20/src/regexp/ya.make
deleted file mode 100644
index abf8a05115..0000000000
--- a/contrib/go/_std_1.20/src/regexp/ya.make
+++ /dev/null
@@ -1,14 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- backtrack.go
- exec.go
- onepass.go
- regexp.go
-)
-
-END()
-
-RECURSE(
- syntax
-)
diff --git a/contrib/go/_std_1.20/src/runtime/alg.go b/contrib/go/_std_1.20/src/runtime/alg.go
deleted file mode 100644
index 2a413eeef3..0000000000
--- a/contrib/go/_std_1.20/src/runtime/alg.go
+++ /dev/null
@@ -1,353 +0,0 @@
-// Copyright 2014 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 runtime
-
-import (
- "internal/cpu"
- "internal/goarch"
- "unsafe"
-)
-
-const (
- c0 = uintptr((8-goarch.PtrSize)/4*2860486313 + (goarch.PtrSize-4)/4*33054211828000289)
- c1 = uintptr((8-goarch.PtrSize)/4*3267000013 + (goarch.PtrSize-4)/4*23344194077549503)
-)
-
-func memhash0(p unsafe.Pointer, h uintptr) uintptr {
- return h
-}
-
-func memhash8(p unsafe.Pointer, h uintptr) uintptr {
- return memhash(p, h, 1)
-}
-
-func memhash16(p unsafe.Pointer, h uintptr) uintptr {
- return memhash(p, h, 2)
-}
-
-func memhash128(p unsafe.Pointer, h uintptr) uintptr {
- return memhash(p, h, 16)
-}
-
-//go:nosplit
-func memhash_varlen(p unsafe.Pointer, h uintptr) uintptr {
- ptr := getclosureptr()
- size := *(*uintptr)(unsafe.Pointer(ptr + unsafe.Sizeof(h)))
- return memhash(p, h, size)
-}
-
-// runtime variable to check if the processor we're running on
-// actually supports the instructions used by the AES-based
-// hash implementation.
-var useAeshash bool
-
-// in asm_*.s
-func memhash(p unsafe.Pointer, h, s uintptr) uintptr
-func memhash32(p unsafe.Pointer, h uintptr) uintptr
-func memhash64(p unsafe.Pointer, h uintptr) uintptr
-func strhash(p unsafe.Pointer, h uintptr) uintptr
-
-func strhashFallback(a unsafe.Pointer, h uintptr) uintptr {
- x := (*stringStruct)(a)
- return memhashFallback(x.str, h, uintptr(x.len))
-}
-
-// NOTE: Because NaN != NaN, a map can contain any
-// number of (mostly useless) entries keyed with NaNs.
-// To avoid long hash chains, we assign a random number
-// as the hash value for a NaN.
-
-func f32hash(p unsafe.Pointer, h uintptr) uintptr {
- f := *(*float32)(p)
- switch {
- case f == 0:
- return c1 * (c0 ^ h) // +0, -0
- case f != f:
- return c1 * (c0 ^ h ^ uintptr(fastrand())) // any kind of NaN
- default:
- return memhash(p, h, 4)
- }
-}
-
-func f64hash(p unsafe.Pointer, h uintptr) uintptr {
- f := *(*float64)(p)
- switch {
- case f == 0:
- return c1 * (c0 ^ h) // +0, -0
- case f != f:
- return c1 * (c0 ^ h ^ uintptr(fastrand())) // any kind of NaN
- default:
- return memhash(p, h, 8)
- }
-}
-
-func c64hash(p unsafe.Pointer, h uintptr) uintptr {
- x := (*[2]float32)(p)
- return f32hash(unsafe.Pointer(&x[1]), f32hash(unsafe.Pointer(&x[0]), h))
-}
-
-func c128hash(p unsafe.Pointer, h uintptr) uintptr {
- x := (*[2]float64)(p)
- return f64hash(unsafe.Pointer(&x[1]), f64hash(unsafe.Pointer(&x[0]), h))
-}
-
-func interhash(p unsafe.Pointer, h uintptr) uintptr {
- a := (*iface)(p)
- tab := a.tab
- if tab == nil {
- return h
- }
- t := tab._type
- if t.equal == nil {
- // Check hashability here. We could do this check inside
- // typehash, but we want to report the topmost type in
- // the error text (e.g. in a struct with a field of slice type
- // we want to report the struct, not the slice).
- panic(errorString("hash of unhashable type " + t.string()))
- }
- if isDirectIface(t) {
- return c1 * typehash(t, unsafe.Pointer(&a.data), h^c0)
- } else {
- return c1 * typehash(t, a.data, h^c0)
- }
-}
-
-func nilinterhash(p unsafe.Pointer, h uintptr) uintptr {
- a := (*eface)(p)
- t := a._type
- if t == nil {
- return h
- }
- if t.equal == nil {
- // See comment in interhash above.
- panic(errorString("hash of unhashable type " + t.string()))
- }
- if isDirectIface(t) {
- return c1 * typehash(t, unsafe.Pointer(&a.data), h^c0)
- } else {
- return c1 * typehash(t, a.data, h^c0)
- }
-}
-
-// typehash computes the hash of the object of type t at address p.
-// h is the seed.
-// This function is seldom used. Most maps use for hashing either
-// fixed functions (e.g. f32hash) or compiler-generated functions
-// (e.g. for a type like struct { x, y string }). This implementation
-// is slower but more general and is used for hashing interface types
-// (called from interhash or nilinterhash, above) or for hashing in
-// maps generated by reflect.MapOf (reflect_typehash, below).
-// Note: this function must match the compiler generated
-// functions exactly. See issue 37716.
-func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
- if t.tflag&tflagRegularMemory != 0 {
- // Handle ptr sizes specially, see issue 37086.
- switch t.size {
- case 4:
- return memhash32(p, h)
- case 8:
- return memhash64(p, h)
- default:
- return memhash(p, h, t.size)
- }
- }
- switch t.kind & kindMask {
- case kindFloat32:
- return f32hash(p, h)
- case kindFloat64:
- return f64hash(p, h)
- case kindComplex64:
- return c64hash(p, h)
- case kindComplex128:
- return c128hash(p, h)
- case kindString:
- return strhash(p, h)
- case kindInterface:
- i := (*interfacetype)(unsafe.Pointer(t))
- if len(i.mhdr) == 0 {
- return nilinterhash(p, h)
- }
- return interhash(p, h)
- case kindArray:
- a := (*arraytype)(unsafe.Pointer(t))
- for i := uintptr(0); i < a.len; i++ {
- h = typehash(a.elem, add(p, i*a.elem.size), h)
- }
- return h
- case kindStruct:
- s := (*structtype)(unsafe.Pointer(t))
- for _, f := range s.fields {
- if f.name.isBlank() {
- continue
- }
- h = typehash(f.typ, add(p, f.offset), h)
- }
- return h
- default:
- // Should never happen, as typehash should only be called
- // with comparable types.
- panic(errorString("hash of unhashable type " + t.string()))
- }
-}
-
-//go:linkname reflect_typehash reflect.typehash
-func reflect_typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
- return typehash(t, p, h)
-}
-
-func memequal0(p, q unsafe.Pointer) bool {
- return true
-}
-func memequal8(p, q unsafe.Pointer) bool {
- return *(*int8)(p) == *(*int8)(q)
-}
-func memequal16(p, q unsafe.Pointer) bool {
- return *(*int16)(p) == *(*int16)(q)
-}
-func memequal32(p, q unsafe.Pointer) bool {
- return *(*int32)(p) == *(*int32)(q)
-}
-func memequal64(p, q unsafe.Pointer) bool {
- return *(*int64)(p) == *(*int64)(q)
-}
-func memequal128(p, q unsafe.Pointer) bool {
- return *(*[2]int64)(p) == *(*[2]int64)(q)
-}
-func f32equal(p, q unsafe.Pointer) bool {
- return *(*float32)(p) == *(*float32)(q)
-}
-func f64equal(p, q unsafe.Pointer) bool {
- return *(*float64)(p) == *(*float64)(q)
-}
-func c64equal(p, q unsafe.Pointer) bool {
- return *(*complex64)(p) == *(*complex64)(q)
-}
-func c128equal(p, q unsafe.Pointer) bool {
- return *(*complex128)(p) == *(*complex128)(q)
-}
-func strequal(p, q unsafe.Pointer) bool {
- return *(*string)(p) == *(*string)(q)
-}
-func interequal(p, q unsafe.Pointer) bool {
- x := *(*iface)(p)
- y := *(*iface)(q)
- return x.tab == y.tab && ifaceeq(x.tab, x.data, y.data)
-}
-func nilinterequal(p, q unsafe.Pointer) bool {
- x := *(*eface)(p)
- y := *(*eface)(q)
- return x._type == y._type && efaceeq(x._type, x.data, y.data)
-}
-func efaceeq(t *_type, x, y unsafe.Pointer) bool {
- if t == nil {
- return true
- }
- eq := t.equal
- if eq == nil {
- panic(errorString("comparing uncomparable type " + t.string()))
- }
- if isDirectIface(t) {
- // Direct interface types are ptr, chan, map, func, and single-element structs/arrays thereof.
- // Maps and funcs are not comparable, so they can't reach here.
- // Ptrs, chans, and single-element items can be compared directly using ==.
- return x == y
- }
- return eq(x, y)
-}
-func ifaceeq(tab *itab, x, y unsafe.Pointer) bool {
- if tab == nil {
- return true
- }
- t := tab._type
- eq := t.equal
- if eq == nil {
- panic(errorString("comparing uncomparable type " + t.string()))
- }
- if isDirectIface(t) {
- // See comment in efaceeq.
- return x == y
- }
- return eq(x, y)
-}
-
-// Testing adapters for hash quality tests (see hash_test.go)
-func stringHash(s string, seed uintptr) uintptr {
- return strhash(noescape(unsafe.Pointer(&s)), seed)
-}
-
-func bytesHash(b []byte, seed uintptr) uintptr {
- s := (*slice)(unsafe.Pointer(&b))
- return memhash(s.array, seed, uintptr(s.len))
-}
-
-func int32Hash(i uint32, seed uintptr) uintptr {
- return memhash32(noescape(unsafe.Pointer(&i)), seed)
-}
-
-func int64Hash(i uint64, seed uintptr) uintptr {
- return memhash64(noescape(unsafe.Pointer(&i)), seed)
-}
-
-func efaceHash(i any, seed uintptr) uintptr {
- return nilinterhash(noescape(unsafe.Pointer(&i)), seed)
-}
-
-func ifaceHash(i interface {
- F()
-}, seed uintptr) uintptr {
- return interhash(noescape(unsafe.Pointer(&i)), seed)
-}
-
-const hashRandomBytes = goarch.PtrSize / 4 * 64
-
-// used in asm_{386,amd64,arm64}.s to seed the hash function
-var aeskeysched [hashRandomBytes]byte
-
-// used in hash{32,64}.go to seed the hash function
-var hashkey [4]uintptr
-
-func alginit() {
- // Install AES hash algorithms if the instructions needed are present.
- if (GOARCH == "386" || GOARCH == "amd64") &&
- cpu.X86.HasAES && // AESENC
- cpu.X86.HasSSSE3 && // PSHUFB
- cpu.X86.HasSSE41 { // PINSR{D,Q}
- initAlgAES()
- return
- }
- if GOARCH == "arm64" && cpu.ARM64.HasAES {
- initAlgAES()
- return
- }
- getRandomData((*[len(hashkey) * goarch.PtrSize]byte)(unsafe.Pointer(&hashkey))[:])
- hashkey[0] |= 1 // make sure these numbers are odd
- hashkey[1] |= 1
- hashkey[2] |= 1
- hashkey[3] |= 1
-}
-
-func initAlgAES() {
- useAeshash = true
- // Initialize with random data so hash collisions will be hard to engineer.
- getRandomData(aeskeysched[:])
-}
-
-// Note: These routines perform the read with a native endianness.
-func readUnaligned32(p unsafe.Pointer) uint32 {
- q := (*[4]byte)(p)
- if goarch.BigEndian {
- return uint32(q[3]) | uint32(q[2])<<8 | uint32(q[1])<<16 | uint32(q[0])<<24
- }
- return uint32(q[0]) | uint32(q[1])<<8 | uint32(q[2])<<16 | uint32(q[3])<<24
-}
-
-func readUnaligned64(p unsafe.Pointer) uint64 {
- q := (*[8]byte)(p)
- if goarch.BigEndian {
- return uint64(q[7]) | uint64(q[6])<<8 | uint64(q[5])<<16 | uint64(q[4])<<24 |
- uint64(q[3])<<32 | uint64(q[2])<<40 | uint64(q[1])<<48 | uint64(q[0])<<56
- }
- return uint64(q[0]) | uint64(q[1])<<8 | uint64(q[2])<<16 | uint64(q[3])<<24 | uint64(q[4])<<32 | uint64(q[5])<<40 | uint64(q[6])<<48 | uint64(q[7])<<56
-}
diff --git a/contrib/go/_std_1.20/src/runtime/arena.go b/contrib/go/_std_1.20/src/runtime/arena.go
deleted file mode 100644
index c338d302b0..0000000000
--- a/contrib/go/_std_1.20/src/runtime/arena.go
+++ /dev/null
@@ -1,1003 +0,0 @@
-// Copyright 2022 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.
-
-// Implementation of (safe) user arenas.
-//
-// This file contains the implementation of user arenas wherein Go values can
-// be manually allocated and freed in bulk. The act of manually freeing memory,
-// potentially before a GC cycle, means that a garbage collection cycle can be
-// delayed, improving efficiency by reducing GC cycle frequency. There are other
-// potential efficiency benefits, such as improved locality and access to a more
-// efficient allocation strategy.
-//
-// What makes the arenas here safe is that once they are freed, accessing the
-// arena's memory will cause an explicit program fault, and the arena's address
-// space will not be reused until no more pointers into it are found. There's one
-// exception to this: if an arena allocated memory that isn't exhausted, it's placed
-// back into a pool for reuse. This means that a crash is not always guaranteed.
-//
-// While this may seem unsafe, it still prevents memory corruption, and is in fact
-// necessary in order to make new(T) a valid implementation of arenas. Such a property
-// is desirable to allow for a trivial implementation. (It also avoids complexities
-// that arise from synchronization with the GC when trying to set the arena chunks to
-// fault while the GC is active.)
-//
-// The implementation works in layers. At the bottom, arenas are managed in chunks.
-// Each chunk must be a multiple of the heap arena size, or the heap arena size must
-// be divisible by the arena chunks. The address space for each chunk, and each
-// corresponding heapArena for that addres space, are eternelly reserved for use as
-// arena chunks. That is, they can never be used for the general heap. Each chunk
-// is also represented by a single mspan, and is modeled as a single large heap
-// allocation. It must be, because each chunk contains ordinary Go values that may
-// point into the heap, so it must be scanned just like any other object. Any
-// pointer into a chunk will therefore always cause the whole chunk to be scanned
-// while its corresponding arena is still live.
-//
-// Chunks may be allocated either from new memory mapped by the OS on our behalf,
-// or by reusing old freed chunks. When chunks are freed, their underlying memory
-// is returned to the OS, set to fault on access, and may not be reused until the
-// program doesn't point into the chunk anymore (the code refers to this state as
-// "quarantined"), a property checked by the GC.
-//
-// The sweeper handles moving chunks out of this quarantine state to be ready for
-// reuse. When the chunk is placed into the quarantine state, its corresponding
-// span is marked as noscan so that the GC doesn't try to scan memory that would
-// cause a fault.
-//
-// At the next layer are the user arenas themselves. They consist of a single
-// active chunk which new Go values are bump-allocated into and a list of chunks
-// that were exhausted when allocating into the arena. Once the arena is freed,
-// it frees all full chunks it references, and places the active one onto a reuse
-// list for a future arena to use. Each arena keeps its list of referenced chunks
-// explicitly live until it is freed. Each user arena also maps to an object which
-// has a finalizer attached that ensures the arena's chunks are all freed even if
-// the arena itself is never explicitly freed.
-//
-// Pointer-ful memory is bump-allocated from low addresses to high addresses in each
-// chunk, while pointer-free memory is bump-allocated from high address to low
-// addresses. The reason for this is to take advantage of a GC optimization wherein
-// the GC will stop scanning an object when there are no more pointers in it, which
-// also allows us to elide clearing the heap bitmap for pointer-free Go values
-// allocated into arenas.
-//
-// Note that arenas are not safe to use concurrently.
-//
-// In summary, there are 2 resources: arenas, and arena chunks. They exist in the
-// following lifecycle:
-//
-// (1) A new arena is created via newArena.
-// (2) Chunks are allocated to hold memory allocated into the arena with new or slice.
-// (a) Chunks are first allocated from the reuse list of partially-used chunks.
-// (b) If there are no such chunks, then chunks on the ready list are taken.
-// (c) Failing all the above, memory for a new chunk is mapped.
-// (3) The arena is freed, or all references to it are dropped, triggering its finalizer.
-// (a) If the GC is not active, exhausted chunks are set to fault and placed on a
-// quarantine list.
-// (b) If the GC is active, exhausted chunks are placed on a fault list and will
-// go through step (a) at a later point in time.
-// (c) Any remaining partially-used chunk is placed on a reuse list.
-// (4) Once no more pointers are found into quarantined arena chunks, the sweeper
-// takes these chunks out of quarantine and places them on the ready list.
-
-package runtime
-
-import (
- "internal/goarch"
- "runtime/internal/atomic"
- "runtime/internal/math"
- "unsafe"
-)
-
-// Functions starting with arena_ are meant to be exported to downstream users
-// of arenas. They should wrap these functions in a higher-lever API.
-//
-// The underlying arena and its resources are managed through an opaque unsafe.Pointer.
-
-// arena_newArena is a wrapper around newUserArena.
-//
-//go:linkname arena_newArena arena.runtime_arena_newArena
-func arena_newArena() unsafe.Pointer {
- return unsafe.Pointer(newUserArena())
-}
-
-// arena_arena_New is a wrapper around (*userArena).new, except that typ
-// is an any (must be a *_type, still) and typ must be a type descriptor
-// for a pointer to the type to actually be allocated, i.e. pass a *T
-// to allocate a T. This is necessary because this function returns a *T.
-//
-//go:linkname arena_arena_New arena.runtime_arena_arena_New
-func arena_arena_New(arena unsafe.Pointer, typ any) any {
- t := (*_type)(efaceOf(&typ).data)
- if t.kind&kindMask != kindPtr {
- throw("arena_New: non-pointer type")
- }
- te := (*ptrtype)(unsafe.Pointer(t)).elem
- x := ((*userArena)(arena)).new(te)
- var result any
- e := efaceOf(&result)
- e._type = t
- e.data = x
- return result
-}
-
-// arena_arena_Slice is a wrapper around (*userArena).slice.
-//
-//go:linkname arena_arena_Slice arena.runtime_arena_arena_Slice
-func arena_arena_Slice(arena unsafe.Pointer, slice any, cap int) {
- ((*userArena)(arena)).slice(slice, cap)
-}
-
-// arena_arena_Free is a wrapper around (*userArena).free.
-//
-//go:linkname arena_arena_Free arena.runtime_arena_arena_Free
-func arena_arena_Free(arena unsafe.Pointer) {
- ((*userArena)(arena)).free()
-}
-
-// arena_heapify takes a value that lives in an arena and makes a copy
-// of it on the heap. Values that don't live in an arena are returned unmodified.
-//
-//go:linkname arena_heapify arena.runtime_arena_heapify
-func arena_heapify(s any) any {
- var v unsafe.Pointer
- e := efaceOf(&s)
- t := e._type
- switch t.kind & kindMask {
- case kindString:
- v = stringStructOf((*string)(e.data)).str
- case kindSlice:
- v = (*slice)(e.data).array
- case kindPtr:
- v = e.data
- default:
- panic("arena: Clone only supports pointers, slices, and strings")
- }
- span := spanOf(uintptr(v))
- if span == nil || !span.isUserArenaChunk {
- // Not stored in a user arena chunk.
- return s
- }
- // Heap-allocate storage for a copy.
- var x any
- switch t.kind & kindMask {
- case kindString:
- s1 := s.(string)
- s2, b := rawstring(len(s1))
- copy(b, s1)
- x = s2
- case kindSlice:
- len := (*slice)(e.data).len
- et := (*slicetype)(unsafe.Pointer(t)).elem
- sl := new(slice)
- *sl = slice{makeslicecopy(et, len, len, (*slice)(e.data).array), len, len}
- xe := efaceOf(&x)
- xe._type = t
- xe.data = unsafe.Pointer(sl)
- case kindPtr:
- et := (*ptrtype)(unsafe.Pointer(t)).elem
- e2 := newobject(et)
- typedmemmove(et, e2, e.data)
- xe := efaceOf(&x)
- xe._type = t
- xe.data = e2
- }
- return x
-}
-
-const (
- // userArenaChunkBytes is the size of a user arena chunk.
- userArenaChunkBytesMax = 8 << 20
- userArenaChunkBytes = uintptr(int64(userArenaChunkBytesMax-heapArenaBytes)&(int64(userArenaChunkBytesMax-heapArenaBytes)>>63) + heapArenaBytes) // min(userArenaChunkBytesMax, heapArenaBytes)
-
- // userArenaChunkPages is the number of pages a user arena chunk uses.
- userArenaChunkPages = userArenaChunkBytes / pageSize
-
- // userArenaChunkMaxAllocBytes is the maximum size of an object that can
- // be allocated from an arena. This number is chosen to cap worst-case
- // fragmentation of user arenas to 25%. Larger allocations are redirected
- // to the heap.
- userArenaChunkMaxAllocBytes = userArenaChunkBytes / 4
-)
-
-func init() {
- if userArenaChunkPages*pageSize != userArenaChunkBytes {
- throw("user arena chunk size is not a mutliple of the page size")
- }
- if userArenaChunkBytes%physPageSize != 0 {
- throw("user arena chunk size is not a mutliple of the physical page size")
- }
- if userArenaChunkBytes < heapArenaBytes {
- if heapArenaBytes%userArenaChunkBytes != 0 {
- throw("user arena chunk size is smaller than a heap arena, but doesn't divide it")
- }
- } else {
- if userArenaChunkBytes%heapArenaBytes != 0 {
- throw("user arena chunks size is larger than a heap arena, but not a multiple")
- }
- }
- lockInit(&userArenaState.lock, lockRankUserArenaState)
-}
-
-type userArena struct {
- // full is a list of full chunks that have not enough free memory left, and
- // that we'll free once this user arena is freed.
- //
- // Can't use mSpanList here because it's not-in-heap.
- fullList *mspan
-
- // active is the user arena chunk we're currently allocating into.
- active *mspan
-
- // refs is a set of references to the arena chunks so that they're kept alive.
- //
- // The last reference in the list always refers to active, while the rest of
- // them correspond to fullList. Specifically, the head of fullList is the
- // second-to-last one, fullList.next is the third-to-last, and so on.
- //
- // In other words, every time a new chunk becomes active, its appended to this
- // list.
- refs []unsafe.Pointer
-
- // defunct is true if free has been called on this arena.
- //
- // This is just a best-effort way to discover a concurrent allocation
- // and free. Also used to detect a double-free.
- defunct atomic.Bool
-}
-
-// newUserArena creates a new userArena ready to be used.
-func newUserArena() *userArena {
- a := new(userArena)
- SetFinalizer(a, func(a *userArena) {
- // If arena handle is dropped without being freed, then call
- // free on the arena, so the arena chunks are never reclaimed
- // by the garbage collector.
- a.free()
- })
- a.refill()
- return a
-}
-
-// new allocates a new object of the provided type into the arena, and returns
-// its pointer.
-//
-// This operation is not safe to call concurrently with other operations on the
-// same arena.
-func (a *userArena) new(typ *_type) unsafe.Pointer {
- return a.alloc(typ, -1)
-}
-
-// slice allocates a new slice backing store. slice must be a pointer to a slice
-// (i.e. *[]T), because userArenaSlice will update the slice directly.
-//
-// cap determines the capacity of the slice backing store and must be non-negative.
-//
-// This operation is not safe to call concurrently with other operations on the
-// same arena.
-func (a *userArena) slice(sl any, cap int) {
- if cap < 0 {
- panic("userArena.slice: negative cap")
- }
- i := efaceOf(&sl)
- typ := i._type
- if typ.kind&kindMask != kindPtr {
- panic("slice result of non-ptr type")
- }
- typ = (*ptrtype)(unsafe.Pointer(typ)).elem
- if typ.kind&kindMask != kindSlice {
- panic("slice of non-ptr-to-slice type")
- }
- typ = (*slicetype)(unsafe.Pointer(typ)).elem
- // t is now the element type of the slice we want to allocate.
-
- *((*slice)(i.data)) = slice{a.alloc(typ, cap), cap, cap}
-}
-
-// free returns the userArena's chunks back to mheap and marks it as defunct.
-//
-// Must be called at most once for any given arena.
-//
-// This operation is not safe to call concurrently with other operations on the
-// same arena.
-func (a *userArena) free() {
- // Check for a double-free.
- if a.defunct.Load() {
- panic("arena double free")
- }
-
- // Mark ourselves as defunct.
- a.defunct.Store(true)
- SetFinalizer(a, nil)
-
- // Free all the full arenas.
- //
- // The refs on this list are in reverse order from the second-to-last.
- s := a.fullList
- i := len(a.refs) - 2
- for s != nil {
- a.fullList = s.next
- s.next = nil
- freeUserArenaChunk(s, a.refs[i])
- s = a.fullList
- i--
- }
- if a.fullList != nil || i >= 0 {
- // There's still something left on the full list, or we
- // failed to actually iterate over the entire refs list.
- throw("full list doesn't match refs list in length")
- }
-
- // Put the active chunk onto the reuse list.
- //
- // Note that active's reference is always the last reference in refs.
- s = a.active
- if s != nil {
- if raceenabled || msanenabled || asanenabled {
- // Don't reuse arenas with sanitizers enabled. We want to catch
- // any use-after-free errors aggressively.
- freeUserArenaChunk(s, a.refs[len(a.refs)-1])
- } else {
- lock(&userArenaState.lock)
- userArenaState.reuse = append(userArenaState.reuse, liveUserArenaChunk{s, a.refs[len(a.refs)-1]})
- unlock(&userArenaState.lock)
- }
- }
- // nil out a.active so that a race with freeing will more likely cause a crash.
- a.active = nil
- a.refs = nil
-}
-
-// alloc reserves space in the current chunk or calls refill and reserves space
-// in a new chunk. If cap is negative, the type will be taken literally, otherwise
-// it will be considered as an element type for a slice backing store with capacity
-// cap.
-func (a *userArena) alloc(typ *_type, cap int) unsafe.Pointer {
- s := a.active
- var x unsafe.Pointer
- for {
- x = s.userArenaNextFree(typ, cap)
- if x != nil {
- break
- }
- s = a.refill()
- }
- return x
-}
-
-// refill inserts the current arena chunk onto the full list and obtains a new
-// one, either from the partial list or allocating a new one, both from mheap.
-func (a *userArena) refill() *mspan {
- // If there's an active chunk, assume it's full.
- s := a.active
- if s != nil {
- if s.userArenaChunkFree.size() > userArenaChunkMaxAllocBytes {
- // It's difficult to tell when we're actually out of memory
- // in a chunk because the allocation that failed may still leave
- // some free space available. However, that amount of free space
- // should never exceed the maximum allocation size.
- throw("wasted too much memory in an arena chunk")
- }
- s.next = a.fullList
- a.fullList = s
- a.active = nil
- s = nil
- }
- var x unsafe.Pointer
-
- // Check the partially-used list.
- lock(&userArenaState.lock)
- if len(userArenaState.reuse) > 0 {
- // Pick off the last arena chunk from the list.
- n := len(userArenaState.reuse) - 1
- x = userArenaState.reuse[n].x
- s = userArenaState.reuse[n].mspan
- userArenaState.reuse[n].x = nil
- userArenaState.reuse[n].mspan = nil
- userArenaState.reuse = userArenaState.reuse[:n]
- }
- unlock(&userArenaState.lock)
- if s == nil {
- // Allocate a new one.
- x, s = newUserArenaChunk()
- if s == nil {
- throw("out of memory")
- }
- }
- a.refs = append(a.refs, x)
- a.active = s
- return s
-}
-
-type liveUserArenaChunk struct {
- *mspan // Must represent a user arena chunk.
-
- // Reference to mspan.base() to keep the chunk alive.
- x unsafe.Pointer
-}
-
-var userArenaState struct {
- lock mutex
-
- // reuse contains a list of partially-used and already-live
- // user arena chunks that can be quickly reused for another
- // arena.
- //
- // Protected by lock.
- reuse []liveUserArenaChunk
-
- // fault contains full user arena chunks that need to be faulted.
- //
- // Protected by lock.
- fault []liveUserArenaChunk
-}
-
-// userArenaNextFree reserves space in the user arena for an item of the specified
-// type. If cap is not -1, this is for an array of cap elements of type t.
-func (s *mspan) userArenaNextFree(typ *_type, cap int) unsafe.Pointer {
- size := typ.size
- if cap > 0 {
- if size > ^uintptr(0)/uintptr(cap) {
- // Overflow.
- throw("out of memory")
- }
- size *= uintptr(cap)
- }
- if size == 0 || cap == 0 {
- return unsafe.Pointer(&zerobase)
- }
- if size > userArenaChunkMaxAllocBytes {
- // Redirect allocations that don't fit into a chunk well directly
- // from the heap.
- if cap >= 0 {
- return newarray(typ, cap)
- }
- return newobject(typ)
- }
-
- // Prevent preemption as we set up the space for a new object.
- //
- // Act like we're allocating.
- mp := acquirem()
- if mp.mallocing != 0 {
- throw("malloc deadlock")
- }
- if mp.gsignal == getg() {
- throw("malloc during signal")
- }
- mp.mallocing = 1
-
- var ptr unsafe.Pointer
- if typ.ptrdata == 0 {
- // Allocate pointer-less objects from the tail end of the chunk.
- v, ok := s.userArenaChunkFree.takeFromBack(size, typ.align)
- if ok {
- ptr = unsafe.Pointer(v)
- }
- } else {
- v, ok := s.userArenaChunkFree.takeFromFront(size, typ.align)
- if ok {
- ptr = unsafe.Pointer(v)
- }
- }
- if ptr == nil {
- // Failed to allocate.
- mp.mallocing = 0
- releasem(mp)
- return nil
- }
- if s.needzero != 0 {
- throw("arena chunk needs zeroing, but should already be zeroed")
- }
- // Set up heap bitmap and do extra accounting.
- if typ.ptrdata != 0 {
- if cap >= 0 {
- userArenaHeapBitsSetSliceType(typ, cap, ptr, s.base())
- } else {
- userArenaHeapBitsSetType(typ, ptr, s.base())
- }
- c := getMCache(mp)
- if c == nil {
- throw("mallocgc called without a P or outside bootstrapping")
- }
- if cap > 0 {
- c.scanAlloc += size - (typ.size - typ.ptrdata)
- } else {
- c.scanAlloc += typ.ptrdata
- }
- }
-
- // Ensure that the stores above that initialize x to
- // type-safe memory and set the heap bits occur before
- // the caller can make ptr observable to the garbage
- // collector. Otherwise, on weakly ordered machines,
- // the garbage collector could follow a pointer to x,
- // but see uninitialized memory or stale heap bits.
- publicationBarrier()
-
- mp.mallocing = 0
- releasem(mp)
-
- return ptr
-}
-
-// userArenaHeapBitsSetType is the equivalent of heapBitsSetType but for
-// non-slice-backing-store Go values allocated in a user arena chunk. It
-// sets up the heap bitmap for the value with type typ allocated at address ptr.
-// base is the base address of the arena chunk.
-func userArenaHeapBitsSetType(typ *_type, ptr unsafe.Pointer, base uintptr) {
- h := writeHeapBitsForAddr(uintptr(ptr))
-
- // Our last allocation might have ended right at a noMorePtrs mark,
- // which we would not have erased. We need to erase that mark here,
- // because we're going to start adding new heap bitmap bits.
- // We only need to clear one mark, because below we make sure to
- // pad out the bits with zeroes and only write one noMorePtrs bit
- // for each new object.
- // (This is only necessary at noMorePtrs boundaries, as noMorePtrs
- // marks within an object allocated with newAt will be erased by
- // the normal writeHeapBitsForAddr mechanism.)
- //
- // Note that we skip this if this is the first allocation in the
- // arena because there's definitely no previous noMorePtrs mark
- // (in fact, we *must* do this, because we're going to try to back
- // up a pointer to fix this up).
- if uintptr(ptr)%(8*goarch.PtrSize*goarch.PtrSize) == 0 && uintptr(ptr) != base {
- // Back up one pointer and rewrite that pointer. That will
- // cause the writeHeapBits implementation to clear the
- // noMorePtrs bit we need to clear.
- r := heapBitsForAddr(uintptr(ptr)-goarch.PtrSize, goarch.PtrSize)
- _, p := r.next()
- b := uintptr(0)
- if p == uintptr(ptr)-goarch.PtrSize {
- b = 1
- }
- h = writeHeapBitsForAddr(uintptr(ptr) - goarch.PtrSize)
- h = h.write(b, 1)
- }
-
- p := typ.gcdata // start of 1-bit pointer mask (or GC program)
- var gcProgBits uintptr
- if typ.kind&kindGCProg != 0 {
- // Expand gc program, using the object itself for storage.
- gcProgBits = runGCProg(addb(p, 4), (*byte)(ptr))
- p = (*byte)(ptr)
- }
- nb := typ.ptrdata / goarch.PtrSize
-
- for i := uintptr(0); i < nb; i += ptrBits {
- k := nb - i
- if k > ptrBits {
- k = ptrBits
- }
- h = h.write(readUintptr(addb(p, i/8)), k)
- }
- // Note: we call pad here to ensure we emit explicit 0 bits
- // for the pointerless tail of the object. This ensures that
- // there's only a single noMorePtrs mark for the next object
- // to clear. We don't need to do this to clear stale noMorePtrs
- // markers from previous uses because arena chunk pointer bitmaps
- // are always fully cleared when reused.
- h = h.pad(typ.size - typ.ptrdata)
- h.flush(uintptr(ptr), typ.size)
-
- if typ.kind&kindGCProg != 0 {
- // Zero out temporary ptrmask buffer inside object.
- memclrNoHeapPointers(ptr, (gcProgBits+7)/8)
- }
-
- // Double-check that the bitmap was written out correctly.
- //
- // Derived from heapBitsSetType.
- const doubleCheck = false
- if doubleCheck {
- size := typ.size
- x := uintptr(ptr)
- h := heapBitsForAddr(x, size)
- for i := uintptr(0); i < size; i += goarch.PtrSize {
- // Compute the pointer bit we want at offset i.
- want := false
- off := i % typ.size
- if off < typ.ptrdata {
- j := off / goarch.PtrSize
- want = *addb(typ.gcdata, j/8)>>(j%8)&1 != 0
- }
- if want {
- var addr uintptr
- h, addr = h.next()
- if addr != x+i {
- throw("userArenaHeapBitsSetType: pointer entry not correct")
- }
- }
- }
- if _, addr := h.next(); addr != 0 {
- throw("userArenaHeapBitsSetType: extra pointer")
- }
- }
-}
-
-// userArenaHeapBitsSetSliceType is the equivalent of heapBitsSetType but for
-// Go slice backing store values allocated in a user arena chunk. It sets up the
-// heap bitmap for n consecutive values with type typ allocated at address ptr.
-func userArenaHeapBitsSetSliceType(typ *_type, n int, ptr unsafe.Pointer, base uintptr) {
- mem, overflow := math.MulUintptr(typ.size, uintptr(n))
- if overflow || n < 0 || mem > maxAlloc {
- panic(plainError("runtime: allocation size out of range"))
- }
- for i := 0; i < n; i++ {
- userArenaHeapBitsSetType(typ, add(ptr, uintptr(i)*typ.size), base)
- }
-}
-
-// newUserArenaChunk allocates a user arena chunk, which maps to a single
-// heap arena and single span. Returns a pointer to the base of the chunk
-// (this is really important: we need to keep the chunk alive) and the span.
-func newUserArenaChunk() (unsafe.Pointer, *mspan) {
- if gcphase == _GCmarktermination {
- throw("newUserArenaChunk called with gcphase == _GCmarktermination")
- }
-
- // Deduct assist credit. Because user arena chunks are modeled as one
- // giant heap object which counts toward heapLive, we're obligated to
- // assist the GC proportionally (and it's worth noting that the arena
- // does represent additional work for the GC, but we also have no idea
- // what that looks like until we actually allocate things into the
- // arena).
- deductAssistCredit(userArenaChunkBytes)
-
- // Set mp.mallocing to keep from being preempted by GC.
- mp := acquirem()
- if mp.mallocing != 0 {
- throw("malloc deadlock")
- }
- if mp.gsignal == getg() {
- throw("malloc during signal")
- }
- mp.mallocing = 1
-
- // Allocate a new user arena.
- var span *mspan
- systemstack(func() {
- span = mheap_.allocUserArenaChunk()
- })
- if span == nil {
- throw("out of memory")
- }
- x := unsafe.Pointer(span.base())
-
- // Allocate black during GC.
- // All slots hold nil so no scanning is needed.
- // This may be racing with GC so do it atomically if there can be
- // a race marking the bit.
- if gcphase != _GCoff {
- gcmarknewobject(span, span.base(), span.elemsize)
- }
-
- if raceenabled {
- // TODO(mknyszek): Track individual objects.
- racemalloc(unsafe.Pointer(span.base()), span.elemsize)
- }
-
- if msanenabled {
- // TODO(mknyszek): Track individual objects.
- msanmalloc(unsafe.Pointer(span.base()), span.elemsize)
- }
-
- if asanenabled {
- // TODO(mknyszek): Track individual objects.
- rzSize := computeRZlog(span.elemsize)
- span.elemsize -= rzSize
- span.limit -= rzSize
- span.userArenaChunkFree = makeAddrRange(span.base(), span.limit)
- asanpoison(unsafe.Pointer(span.limit), span.npages*pageSize-span.elemsize)
- asanunpoison(unsafe.Pointer(span.base()), span.elemsize)
- }
-
- if rate := MemProfileRate; rate > 0 {
- c := getMCache(mp)
- if c == nil {
- throw("newUserArenaChunk called without a P or outside bootstrapping")
- }
- // Note cache c only valid while m acquired; see #47302
- if rate != 1 && userArenaChunkBytes < c.nextSample {
- c.nextSample -= userArenaChunkBytes
- } else {
- profilealloc(mp, unsafe.Pointer(span.base()), userArenaChunkBytes)
- }
- }
- mp.mallocing = 0
- releasem(mp)
-
- // Again, because this chunk counts toward heapLive, potentially trigger a GC.
- if t := (gcTrigger{kind: gcTriggerHeap}); t.test() {
- gcStart(t)
- }
-
- if debug.malloc {
- if debug.allocfreetrace != 0 {
- tracealloc(unsafe.Pointer(span.base()), userArenaChunkBytes, nil)
- }
-
- if inittrace.active && inittrace.id == getg().goid {
- // Init functions are executed sequentially in a single goroutine.
- inittrace.bytes += uint64(userArenaChunkBytes)
- }
- }
-
- // Double-check it's aligned to the physical page size. Based on the current
- // implementation this is trivially true, but it need not be in the future.
- // However, if it's not aligned to the physical page size then we can't properly
- // set it to fault later.
- if uintptr(x)%physPageSize != 0 {
- throw("user arena chunk is not aligned to the physical page size")
- }
-
- return x, span
-}
-
-// isUnusedUserArenaChunk indicates that the arena chunk has been set to fault
-// and doesn't contain any scannable memory anymore. However, it might still be
-// mSpanInUse as it sits on the quarantine list, since it needs to be swept.
-//
-// This is not safe to execute unless the caller has ownership of the mspan or
-// the world is stopped (preemption is prevented while the relevant state changes).
-//
-// This is really only meant to be used by accounting tests in the runtime to
-// distinguish when a span shouldn't be counted (since mSpanInUse might not be
-// enough).
-func (s *mspan) isUnusedUserArenaChunk() bool {
- return s.isUserArenaChunk && s.spanclass == makeSpanClass(0, true)
-}
-
-// setUserArenaChunkToFault sets the address space for the user arena chunk to fault
-// and releases any underlying memory resources.
-//
-// Must be in a non-preemptible state to ensure the consistency of statistics
-// exported to MemStats.
-func (s *mspan) setUserArenaChunkToFault() {
- if !s.isUserArenaChunk {
- throw("invalid span in heapArena for user arena")
- }
- if s.npages*pageSize != userArenaChunkBytes {
- throw("span on userArena.faultList has invalid size")
- }
-
- // Update the span class to be noscan. What we want to happen is that
- // any pointer into the span keeps it from getting recycled, so we want
- // the mark bit to get set, but we're about to set the address space to fault,
- // so we have to prevent the GC from scanning this memory.
- //
- // It's OK to set it here because (1) a GC isn't in progress, so the scanning code
- // won't make a bad decision, (2) we're currently non-preemptible and in the runtime,
- // so a GC is blocked from starting. We might race with sweeping, which could
- // put it on the "wrong" sweep list, but really don't care because the chunk is
- // treated as a large object span and there's no meaningful difference between scan
- // and noscan large objects in the sweeper. The STW at the start of the GC acts as a
- // barrier for this update.
- s.spanclass = makeSpanClass(0, true)
-
- // Actually set the arena chunk to fault, so we'll get dangling pointer errors.
- // sysFault currently uses a method on each OS that forces it to evacuate all
- // memory backing the chunk.
- sysFault(unsafe.Pointer(s.base()), s.npages*pageSize)
-
- // Everything on the list is counted as in-use, however sysFault transitions to
- // Reserved, not Prepared, so we skip updating heapFree or heapReleased and just
- // remove the memory from the total altogether; it's just address space now.
- gcController.heapInUse.add(-int64(s.npages * pageSize))
-
- // Count this as a free of an object right now as opposed to when
- // the span gets off the quarantine list. The main reason is so that the
- // amount of bytes allocated doesn't exceed how much is counted as
- // "mapped ready," which could cause a deadlock in the pacer.
- gcController.totalFree.Add(int64(s.npages * pageSize))
-
- // Update consistent stats to match.
- //
- // We're non-preemptible, so it's safe to update consistent stats (our P
- // won't change out from under us).
- stats := memstats.heapStats.acquire()
- atomic.Xaddint64(&stats.committed, -int64(s.npages*pageSize))
- atomic.Xaddint64(&stats.inHeap, -int64(s.npages*pageSize))
- atomic.Xadd64(&stats.largeFreeCount, 1)
- atomic.Xadd64(&stats.largeFree, int64(s.npages*pageSize))
- memstats.heapStats.release()
-
- // This counts as a free, so update heapLive.
- gcController.update(-int64(s.npages*pageSize), 0)
-
- // Mark it as free for the race detector.
- if raceenabled {
- racefree(unsafe.Pointer(s.base()), s.elemsize)
- }
-
- systemstack(func() {
- // Add the user arena to the quarantine list.
- lock(&mheap_.lock)
- mheap_.userArena.quarantineList.insert(s)
- unlock(&mheap_.lock)
- })
-}
-
-// inUserArenaChunk returns true if p points to a user arena chunk.
-func inUserArenaChunk(p uintptr) bool {
- s := spanOf(p)
- if s == nil {
- return false
- }
- return s.isUserArenaChunk
-}
-
-// freeUserArenaChunk releases the user arena represented by s back to the runtime.
-//
-// x must be a live pointer within s.
-//
-// The runtime will set the user arena to fault once it's safe (the GC is no longer running)
-// and then once the user arena is no longer referenced by the application, will allow it to
-// be reused.
-func freeUserArenaChunk(s *mspan, x unsafe.Pointer) {
- if !s.isUserArenaChunk {
- throw("span is not for a user arena")
- }
- if s.npages*pageSize != userArenaChunkBytes {
- throw("invalid user arena span size")
- }
-
- // Mark the region as free to various santizers immediately instead
- // of handling them at sweep time.
- if raceenabled {
- racefree(unsafe.Pointer(s.base()), s.elemsize)
- }
- if msanenabled {
- msanfree(unsafe.Pointer(s.base()), s.elemsize)
- }
- if asanenabled {
- asanpoison(unsafe.Pointer(s.base()), s.elemsize)
- }
-
- // Make ourselves non-preemptible as we manipulate state and statistics.
- //
- // Also required by setUserArenaChunksToFault.
- mp := acquirem()
-
- // We can only set user arenas to fault if we're in the _GCoff phase.
- if gcphase == _GCoff {
- lock(&userArenaState.lock)
- faultList := userArenaState.fault
- userArenaState.fault = nil
- unlock(&userArenaState.lock)
-
- s.setUserArenaChunkToFault()
- for _, lc := range faultList {
- lc.mspan.setUserArenaChunkToFault()
- }
-
- // Until the chunks are set to fault, keep them alive via the fault list.
- KeepAlive(x)
- KeepAlive(faultList)
- } else {
- // Put the user arena on the fault list.
- lock(&userArenaState.lock)
- userArenaState.fault = append(userArenaState.fault, liveUserArenaChunk{s, x})
- unlock(&userArenaState.lock)
- }
- releasem(mp)
-}
-
-// allocUserArenaChunk attempts to reuse a free user arena chunk represented
-// as a span.
-//
-// Must be in a non-preemptible state to ensure the consistency of statistics
-// exported to MemStats.
-//
-// Acquires the heap lock. Must run on the system stack for that reason.
-//
-//go:systemstack
-func (h *mheap) allocUserArenaChunk() *mspan {
- var s *mspan
- var base uintptr
-
- // First check the free list.
- lock(&h.lock)
- if !h.userArena.readyList.isEmpty() {
- s = h.userArena.readyList.first
- h.userArena.readyList.remove(s)
- base = s.base()
- } else {
- // Free list was empty, so allocate a new arena.
- hintList := &h.userArena.arenaHints
- if raceenabled {
- // In race mode just use the regular heap hints. We might fragment
- // the address space, but the race detector requires that the heap
- // is mapped contiguously.
- hintList = &h.arenaHints
- }
- v, size := h.sysAlloc(userArenaChunkBytes, hintList, false)
- if size%userArenaChunkBytes != 0 {
- throw("sysAlloc size is not divisible by userArenaChunkBytes")
- }
- if size > userArenaChunkBytes {
- // We got more than we asked for. This can happen if
- // heapArenaSize > userArenaChunkSize, or if sysAlloc just returns
- // some extra as a result of trying to find an aligned region.
- //
- // Divide it up and put it on the ready list.
- for i := uintptr(userArenaChunkBytes); i < size; i += userArenaChunkBytes {
- s := h.allocMSpanLocked()
- s.init(uintptr(v)+i, userArenaChunkPages)
- h.userArena.readyList.insertBack(s)
- }
- size = userArenaChunkBytes
- }
- base = uintptr(v)
- if base == 0 {
- // Out of memory.
- unlock(&h.lock)
- return nil
- }
- s = h.allocMSpanLocked()
- }
- unlock(&h.lock)
-
- // sysAlloc returns Reserved address space, and any span we're
- // reusing is set to fault (so, also Reserved), so transition
- // it to Prepared and then Ready.
- //
- // Unlike (*mheap).grow, just map in everything that we
- // asked for. We're likely going to use it all.
- sysMap(unsafe.Pointer(base), userArenaChunkBytes, &gcController.heapReleased)
- sysUsed(unsafe.Pointer(base), userArenaChunkBytes, userArenaChunkBytes)
-
- // Model the user arena as a heap span for a large object.
- spc := makeSpanClass(0, false)
- h.initSpan(s, spanAllocHeap, spc, base, userArenaChunkPages)
- s.isUserArenaChunk = true
-
- // Account for this new arena chunk memory.
- gcController.heapInUse.add(int64(userArenaChunkBytes))
- gcController.heapReleased.add(-int64(userArenaChunkBytes))
-
- stats := memstats.heapStats.acquire()
- atomic.Xaddint64(&stats.inHeap, int64(userArenaChunkBytes))
- atomic.Xaddint64(&stats.committed, int64(userArenaChunkBytes))
-
- // Model the arena as a single large malloc.
- atomic.Xadd64(&stats.largeAlloc, int64(userArenaChunkBytes))
- atomic.Xadd64(&stats.largeAllocCount, 1)
- memstats.heapStats.release()
-
- // Count the alloc in inconsistent, internal stats.
- gcController.totalAlloc.Add(int64(userArenaChunkBytes))
-
- // Update heapLive.
- gcController.update(int64(userArenaChunkBytes), 0)
-
- // Put the large span in the mcentral swept list so that it's
- // visible to the background sweeper.
- h.central[spc].mcentral.fullSwept(h.sweepgen).push(s)
- s.limit = s.base() + userArenaChunkBytes
- s.freeindex = 1
- s.allocCount = 1
-
- // This must clear the entire heap bitmap so that it's safe
- // to allocate noscan data without writing anything out.
- s.initHeapBits(true)
-
- // Clear the span preemptively. It's an arena chunk, so let's assume
- // everything is going to be used.
- //
- // This also seems to make a massive difference as to whether or
- // not Linux decides to back this memory with transparent huge
- // pages. There's latency involved in this zeroing, but the hugepage
- // gains are almost always worth it. Note: it's important that we
- // clear even if it's freshly mapped and we know there's no point
- // to zeroing as *that* is the critical signal to use huge pages.
- memclrNoHeapPointers(unsafe.Pointer(s.base()), s.elemsize)
- s.needzero = 0
-
- s.freeIndexForScan = 1
-
- // Set up the range for allocation.
- s.userArenaChunkFree = makeAddrRange(base, s.limit)
- return s
-}
diff --git a/contrib/go/_std_1.20/src/runtime/asm.s b/contrib/go/_std_1.20/src/runtime/asm.s
deleted file mode 100644
index 84d56de7dd..0000000000
--- a/contrib/go/_std_1.20/src/runtime/asm.s
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2014 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.
-
-#include "textflag.h"
-
-#ifndef GOARCH_amd64
-TEXT ·sigpanic0(SB),NOSPLIT,$0-0
- JMP ·sigpanic<ABIInternal>(SB)
-#endif
diff --git a/contrib/go/_std_1.20/src/runtime/asm_amd64.s b/contrib/go/_std_1.20/src/runtime/asm_amd64.s
deleted file mode 100644
index 13c8de499e..0000000000
--- a/contrib/go/_std_1.20/src/runtime/asm_amd64.s
+++ /dev/null
@@ -1,2066 +0,0 @@
-// Copyright 2009 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.
-
-#include "go_asm.h"
-#include "go_tls.h"
-#include "funcdata.h"
-#include "textflag.h"
-#include "cgo/abi_amd64.h"
-
-// _rt0_amd64 is common startup code for most amd64 systems when using
-// internal linking. This is the entry point for the program from the
-// kernel for an ordinary -buildmode=exe program. The stack holds the
-// number of arguments and the C-style argv.
-TEXT _rt0_amd64(SB),NOSPLIT,$-8
- MOVQ 0(SP), DI // argc
- LEAQ 8(SP), SI // argv
- JMP runtime·rt0_go(SB)
-
-// main is common startup code for most amd64 systems when using
-// external linking. The C startup code will call the symbol "main"
-// passing argc and argv in the usual C ABI registers DI and SI.
-TEXT main(SB),NOSPLIT,$-8
- JMP runtime·rt0_go(SB)
-
-// _rt0_amd64_lib is common startup code for most amd64 systems when
-// using -buildmode=c-archive or -buildmode=c-shared. The linker will
-// arrange to invoke this function as a global constructor (for
-// c-archive) or when the shared library is loaded (for c-shared).
-// We expect argc and argv to be passed in the usual C ABI registers
-// DI and SI.
-TEXT _rt0_amd64_lib(SB),NOSPLIT,$0
- // Transition from C ABI to Go ABI.
- PUSH_REGS_HOST_TO_ABI0()
-
- MOVQ DI, _rt0_amd64_lib_argc<>(SB)
- MOVQ SI, _rt0_amd64_lib_argv<>(SB)
-
- // Synchronous initialization.
- CALL runtime·libpreinit(SB)
-
- // Create a new thread to finish Go runtime initialization.
- MOVQ _cgo_sys_thread_create(SB), AX
- TESTQ AX, AX
- JZ nocgo
-
- // We're calling back to C.
- // Align stack per ELF ABI requirements.
- MOVQ SP, BX // Callee-save in C ABI
- ANDQ $~15, SP
- MOVQ $_rt0_amd64_lib_go(SB), DI
- MOVQ $0, SI
- CALL AX
- MOVQ BX, SP
- JMP restore
-
-nocgo:
- ADJSP $16
- MOVQ $0x800000, 0(SP) // stacksize
- MOVQ $_rt0_amd64_lib_go(SB), AX
- MOVQ AX, 8(SP) // fn
- CALL runtime·newosproc0(SB)
- ADJSP $-16
-
-restore:
- POP_REGS_HOST_TO_ABI0()
- RET
-
-// _rt0_amd64_lib_go initializes the Go runtime.
-// This is started in a separate thread by _rt0_amd64_lib.
-TEXT _rt0_amd64_lib_go(SB),NOSPLIT,$0
- MOVQ _rt0_amd64_lib_argc<>(SB), DI
- MOVQ _rt0_amd64_lib_argv<>(SB), SI
- JMP runtime·rt0_go(SB)
-
-DATA _rt0_amd64_lib_argc<>(SB)/8, $0
-GLOBL _rt0_amd64_lib_argc<>(SB),NOPTR, $8
-DATA _rt0_amd64_lib_argv<>(SB)/8, $0
-GLOBL _rt0_amd64_lib_argv<>(SB),NOPTR, $8
-
-#ifdef GOAMD64_v2
-DATA bad_cpu_msg<>+0x00(SB)/84, $"This program can only be run on AMD64 processors with v2 microarchitecture support.\n"
-#endif
-
-#ifdef GOAMD64_v3
-DATA bad_cpu_msg<>+0x00(SB)/84, $"This program can only be run on AMD64 processors with v3 microarchitecture support.\n"
-#endif
-
-#ifdef GOAMD64_v4
-DATA bad_cpu_msg<>+0x00(SB)/84, $"This program can only be run on AMD64 processors with v4 microarchitecture support.\n"
-#endif
-
-GLOBL bad_cpu_msg<>(SB), RODATA, $84
-
-// Define a list of AMD64 microarchitecture level features
-// https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels
-
- // SSE3 SSSE3 CMPXCHNG16 SSE4.1 SSE4.2 POPCNT
-#define V2_FEATURES_CX (1 << 0 | 1 << 9 | 1 << 13 | 1 << 19 | 1 << 20 | 1 << 23)
- // LAHF/SAHF
-#define V2_EXT_FEATURES_CX (1 << 0)
- // FMA MOVBE OSXSAVE AVX F16C
-#define V3_FEATURES_CX (V2_FEATURES_CX | 1 << 12 | 1 << 22 | 1 << 27 | 1 << 28 | 1 << 29)
- // ABM (FOR LZNCT)
-#define V3_EXT_FEATURES_CX (V2_EXT_FEATURES_CX | 1 << 5)
- // BMI1 AVX2 BMI2
-#define V3_EXT_FEATURES_BX (1 << 3 | 1 << 5 | 1 << 8)
- // XMM YMM
-#define V3_OS_SUPPORT_AX (1 << 1 | 1 << 2)
-
-#define V4_FEATURES_CX V3_FEATURES_CX
-
-#define V4_EXT_FEATURES_CX V3_EXT_FEATURES_CX
- // AVX512F AVX512DQ AVX512CD AVX512BW AVX512VL
-#define V4_EXT_FEATURES_BX (V3_EXT_FEATURES_BX | 1 << 16 | 1 << 17 | 1 << 28 | 1 << 30 | 1 << 31)
- // OPMASK ZMM
-#define V4_OS_SUPPORT_AX (V3_OS_SUPPORT_AX | 1 << 5 | (1 << 6 | 1 << 7))
-
-#ifdef GOAMD64_v2
-#define NEED_MAX_CPUID 0x80000001
-#define NEED_FEATURES_CX V2_FEATURES_CX
-#define NEED_EXT_FEATURES_CX V2_EXT_FEATURES_CX
-#endif
-
-#ifdef GOAMD64_v3
-#define NEED_MAX_CPUID 0x80000001
-#define NEED_FEATURES_CX V3_FEATURES_CX
-#define NEED_EXT_FEATURES_CX V3_EXT_FEATURES_CX
-#define NEED_EXT_FEATURES_BX V3_EXT_FEATURES_BX
-#define NEED_OS_SUPPORT_AX V3_OS_SUPPORT_AX
-#endif
-
-#ifdef GOAMD64_v4
-#define NEED_MAX_CPUID 0x80000001
-#define NEED_FEATURES_CX V4_FEATURES_CX
-#define NEED_EXT_FEATURES_CX V4_EXT_FEATURES_CX
-#define NEED_EXT_FEATURES_BX V4_EXT_FEATURES_BX
-
-// Darwin requires a different approach to check AVX512 support, see CL 285572.
-#ifdef GOOS_darwin
-#define NEED_OS_SUPPORT_AX V3_OS_SUPPORT_AX
-// These values are from:
-// https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/osfmk/i386/cpu_capabilities.h
-#define commpage64_base_address 0x00007fffffe00000
-#define commpage64_cpu_capabilities64 (commpage64_base_address+0x010)
-#define commpage64_version (commpage64_base_address+0x01E)
-#define hasAVX512F 0x0000004000000000
-#define hasAVX512CD 0x0000008000000000
-#define hasAVX512DQ 0x0000010000000000
-#define hasAVX512BW 0x0000020000000000
-#define hasAVX512VL 0x0000100000000000
-#define NEED_DARWIN_SUPPORT (hasAVX512F | hasAVX512DQ | hasAVX512CD | hasAVX512BW | hasAVX512VL)
-#else
-#define NEED_OS_SUPPORT_AX V4_OS_SUPPORT_AX
-#endif
-
-#endif
-
-TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
- // copy arguments forward on an even stack
- MOVQ DI, AX // argc
- MOVQ SI, BX // argv
- SUBQ $(5*8), SP // 3args 2auto
- ANDQ $~15, SP
- MOVQ AX, 24(SP)
- MOVQ BX, 32(SP)
-
- // create istack out of the given (operating system) stack.
- // _cgo_init may update stackguard.
- MOVQ $runtime·g0(SB), DI
- LEAQ (-64*1024+104)(SP), BX
- MOVQ BX, g_stackguard0(DI)
- MOVQ BX, g_stackguard1(DI)
- MOVQ BX, (g_stack+stack_lo)(DI)
- MOVQ SP, (g_stack+stack_hi)(DI)
-
- // find out information about the processor we're on
- MOVL $0, AX
- CPUID
- CMPL AX, $0
- JE nocpuinfo
-
- CMPL BX, $0x756E6547 // "Genu"
- JNE notintel
- CMPL DX, $0x49656E69 // "ineI"
- JNE notintel
- CMPL CX, $0x6C65746E // "ntel"
- JNE notintel
- MOVB $1, runtime·isIntel(SB)
-
-notintel:
- // Load EAX=1 cpuid flags
- MOVL $1, AX
- CPUID
- MOVL AX, runtime·processorVersionInfo(SB)
-
-nocpuinfo:
- // if there is an _cgo_init, call it.
- MOVQ _cgo_init(SB), AX
- TESTQ AX, AX
- JZ needtls
- // arg 1: g0, already in DI
- MOVQ $setg_gcc<>(SB), SI // arg 2: setg_gcc
- MOVQ $0, DX // arg 3, 4: not used when using platform's TLS
- MOVQ $0, CX
-#ifdef GOOS_android
- MOVQ $runtime·tls_g(SB), DX // arg 3: &tls_g
- // arg 4: TLS base, stored in slot 0 (Android's TLS_SLOT_SELF).
- // Compensate for tls_g (+16).
- MOVQ -16(TLS), CX
-#endif
-#ifdef GOOS_windows
- MOVQ $runtime·tls_g(SB), DX // arg 3: &tls_g
- // Adjust for the Win64 calling convention.
- MOVQ CX, R9 // arg 4
- MOVQ DX, R8 // arg 3
- MOVQ SI, DX // arg 2
- MOVQ DI, CX // arg 1
-#endif
- CALL AX
-
- // update stackguard after _cgo_init
- MOVQ $runtime·g0(SB), CX
- MOVQ (g_stack+stack_lo)(CX), AX
- ADDQ $const__StackGuard, AX
- MOVQ AX, g_stackguard0(CX)
- MOVQ AX, g_stackguard1(CX)
-
-#ifndef GOOS_windows
- JMP ok
-#endif
-needtls:
-#ifdef GOOS_plan9
- // skip TLS setup on Plan 9
- JMP ok
-#endif
-#ifdef GOOS_solaris
- // skip TLS setup on Solaris
- JMP ok
-#endif
-#ifdef GOOS_illumos
- // skip TLS setup on illumos
- JMP ok
-#endif
-#ifdef GOOS_darwin
- // skip TLS setup on Darwin
- JMP ok
-#endif
-#ifdef GOOS_openbsd
- // skip TLS setup on OpenBSD
- JMP ok
-#endif
-
-#ifdef GOOS_windows
- CALL runtime·wintls(SB)
-#endif
-
- LEAQ runtime·m0+m_tls(SB), DI
- CALL runtime·settls(SB)
-
- // store through it, to make sure it works
- get_tls(BX)
- MOVQ $0x123, g(BX)
- MOVQ runtime·m0+m_tls(SB), AX
- CMPQ AX, $0x123
- JEQ 2(PC)
- CALL runtime·abort(SB)
-ok:
- // set the per-goroutine and per-mach "registers"
- get_tls(BX)
- LEAQ runtime·g0(SB), CX
- MOVQ CX, g(BX)
- LEAQ runtime·m0(SB), AX
-
- // save m->g0 = g0
- MOVQ CX, m_g0(AX)
- // save m0 to g0->m
- MOVQ AX, g_m(CX)
-
- CLD // convention is D is always left cleared
-
- // Check GOAMD64 reqirements
- // We need to do this after setting up TLS, so that
- // we can report an error if there is a failure. See issue 49586.
-#ifdef NEED_FEATURES_CX
- MOVL $0, AX
- CPUID
- CMPL AX, $0
- JE bad_cpu
- MOVL $1, AX
- CPUID
- ANDL $NEED_FEATURES_CX, CX
- CMPL CX, $NEED_FEATURES_CX
- JNE bad_cpu
-#endif
-
-#ifdef NEED_MAX_CPUID
- MOVL $0x80000000, AX
- CPUID
- CMPL AX, $NEED_MAX_CPUID
- JL bad_cpu
-#endif
-
-#ifdef NEED_EXT_FEATURES_BX
- MOVL $7, AX
- MOVL $0, CX
- CPUID
- ANDL $NEED_EXT_FEATURES_BX, BX
- CMPL BX, $NEED_EXT_FEATURES_BX
- JNE bad_cpu
-#endif
-
-#ifdef NEED_EXT_FEATURES_CX
- MOVL $0x80000001, AX
- CPUID
- ANDL $NEED_EXT_FEATURES_CX, CX
- CMPL CX, $NEED_EXT_FEATURES_CX
- JNE bad_cpu
-#endif
-
-#ifdef NEED_OS_SUPPORT_AX
- XORL CX, CX
- XGETBV
- ANDL $NEED_OS_SUPPORT_AX, AX
- CMPL AX, $NEED_OS_SUPPORT_AX
- JNE bad_cpu
-#endif
-
-#ifdef NEED_DARWIN_SUPPORT
- MOVQ $commpage64_version, BX
- CMPW (BX), $13 // cpu_capabilities64 undefined in versions < 13
- JL bad_cpu
- MOVQ $commpage64_cpu_capabilities64, BX
- MOVQ (BX), BX
- MOVQ $NEED_DARWIN_SUPPORT, CX
- ANDQ CX, BX
- CMPQ BX, CX
- JNE bad_cpu
-#endif
-
- CALL runtime·check(SB)
-
- MOVL 24(SP), AX // copy argc
- MOVL AX, 0(SP)
- MOVQ 32(SP), AX // copy argv
- MOVQ AX, 8(SP)
- CALL runtime·args(SB)
- CALL runtime·osinit(SB)
- CALL runtime·schedinit(SB)
-
- // create a new goroutine to start program
- MOVQ $runtime·mainPC(SB), AX // entry
- PUSHQ AX
- CALL runtime·newproc(SB)
- POPQ AX
-
- // start this M
- CALL runtime·mstart(SB)
-
- CALL runtime·abort(SB) // mstart should never return
- RET
-
-bad_cpu: // show that the program requires a certain microarchitecture level.
- MOVQ $2, 0(SP)
- MOVQ $bad_cpu_msg<>(SB), AX
- MOVQ AX, 8(SP)
- MOVQ $84, 16(SP)
- CALL runtime·write(SB)
- MOVQ $1, 0(SP)
- CALL runtime·exit(SB)
- CALL runtime·abort(SB)
- RET
-
- // Prevent dead-code elimination of debugCallV2, which is
- // intended to be called by debuggers.
- MOVQ $runtime·debugCallV2<ABIInternal>(SB), AX
- RET
-
-// mainPC is a function value for runtime.main, to be passed to newproc.
-// The reference to runtime.main is made via ABIInternal, since the
-// actual function (not the ABI0 wrapper) is needed by newproc.
-DATA runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
-GLOBL runtime·mainPC(SB),RODATA,$8
-
-TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
- BYTE $0xcc
- RET
-
-TEXT runtime·asminit(SB),NOSPLIT,$0-0
- // No per-thread init.
- RET
-
-TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
- CALL runtime·mstart0(SB)
- RET // not reached
-
-/*
- * go-routine
- */
-
-// func gogo(buf *gobuf)
-// restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB), NOSPLIT, $0-8
- MOVQ buf+0(FP), BX // gobuf
- MOVQ gobuf_g(BX), DX
- MOVQ 0(DX), CX // make sure g != nil
- JMP gogo<>(SB)
-
-TEXT gogo<>(SB), NOSPLIT, $0
- get_tls(CX)
- MOVQ DX, g(CX)
- MOVQ DX, R14 // set the g register
- MOVQ gobuf_sp(BX), SP // restore SP
- MOVQ gobuf_ret(BX), AX
- MOVQ gobuf_ctxt(BX), DX
- MOVQ gobuf_bp(BX), BP
- MOVQ $0, gobuf_sp(BX) // clear to help garbage collector
- MOVQ $0, gobuf_ret(BX)
- MOVQ $0, gobuf_ctxt(BX)
- MOVQ $0, gobuf_bp(BX)
- MOVQ gobuf_pc(BX), BX
- JMP BX
-
-// func mcall(fn func(*g))
-// Switch to m->g0's stack, call fn(g).
-// Fn must never return. It should gogo(&g->sched)
-// to keep running g.
-TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT, $0-8
- MOVQ AX, DX // DX = fn
-
- // save state in g->sched
- MOVQ 0(SP), BX // caller's PC
- MOVQ BX, (g_sched+gobuf_pc)(R14)
- LEAQ fn+0(FP), BX // caller's SP
- MOVQ BX, (g_sched+gobuf_sp)(R14)
- MOVQ BP, (g_sched+gobuf_bp)(R14)
-
- // switch to m->g0 & its stack, call fn
- MOVQ g_m(R14), BX
- MOVQ m_g0(BX), SI // SI = g.m.g0
- CMPQ SI, R14 // if g == m->g0 call badmcall
- JNE goodm
- JMP runtime·badmcall(SB)
-goodm:
- MOVQ R14, AX // AX (and arg 0) = g
- MOVQ SI, R14 // g = g.m.g0
- get_tls(CX) // Set G in TLS
- MOVQ R14, g(CX)
- MOVQ (g_sched+gobuf_sp)(R14), SP // sp = g0.sched.sp
- PUSHQ AX // open up space for fn's arg spill slot
- MOVQ 0(DX), R12
- CALL R12 // fn(g)
- POPQ AX
- JMP runtime·badmcall2(SB)
- RET
-
-// systemstack_switch is a dummy routine that systemstack leaves at the bottom
-// of the G stack. We need to distinguish the routine that
-// lives at the bottom of the G stack from the one that lives
-// at the top of the system stack because the one at the top of
-// the system stack terminates the stack walk (see topofstack()).
-TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
- RET
-
-// func systemstack(fn func())
-TEXT runtime·systemstack(SB), NOSPLIT, $0-8
- MOVQ fn+0(FP), DI // DI = fn
- get_tls(CX)
- MOVQ g(CX), AX // AX = g
- MOVQ g_m(AX), BX // BX = m
-
- CMPQ AX, m_gsignal(BX)
- JEQ noswitch
-
- MOVQ m_g0(BX), DX // DX = g0
- CMPQ AX, DX
- JEQ noswitch
-
- CMPQ AX, m_curg(BX)
- JNE bad
-
- // switch stacks
- // save our state in g->sched. Pretend to
- // be systemstack_switch if the G stack is scanned.
- CALL gosave_systemstack_switch<>(SB)
-
- // switch to g0
- MOVQ DX, g(CX)
- MOVQ DX, R14 // set the g register
- MOVQ (g_sched+gobuf_sp)(DX), BX
- MOVQ BX, SP
-
- // call target function
- MOVQ DI, DX
- MOVQ 0(DI), DI
- CALL DI
-
- // switch back to g
- get_tls(CX)
- MOVQ g(CX), AX
- MOVQ g_m(AX), BX
- MOVQ m_curg(BX), AX
- MOVQ AX, g(CX)
- MOVQ (g_sched+gobuf_sp)(AX), SP
- MOVQ $0, (g_sched+gobuf_sp)(AX)
- RET
-
-noswitch:
- // already on m stack; tail call the function
- // Using a tail call here cleans up tracebacks since we won't stop
- // at an intermediate systemstack.
- MOVQ DI, DX
- MOVQ 0(DI), DI
- JMP DI
-
-bad:
- // Bad: g is not gsignal, not g0, not curg. What is it?
- MOVQ $runtime·badsystemstack(SB), AX
- CALL AX
- INT $3
-
-
-/*
- * support for morestack
- */
-
-// Called during function prolog when more stack is needed.
-//
-// The traceback routines see morestack on a g0 as being
-// the top of a stack (for example, morestack calling newstack
-// calling the scheduler calling newm calling gc), so we must
-// record an argument size. For that purpose, it has no arguments.
-TEXT runtime·morestack(SB),NOSPLIT,$0-0
- // Cannot grow scheduler stack (m->g0).
- get_tls(CX)
- MOVQ g(CX), BX
- MOVQ g_m(BX), BX
- MOVQ m_g0(BX), SI
- CMPQ g(CX), SI
- JNE 3(PC)
- CALL runtime·badmorestackg0(SB)
- CALL runtime·abort(SB)
-
- // Cannot grow signal stack (m->gsignal).
- MOVQ m_gsignal(BX), SI
- CMPQ g(CX), SI
- JNE 3(PC)
- CALL runtime·badmorestackgsignal(SB)
- CALL runtime·abort(SB)
-
- // Called from f.
- // Set m->morebuf to f's caller.
- NOP SP // tell vet SP changed - stop checking offsets
- MOVQ 8(SP), AX // f's caller's PC
- MOVQ AX, (m_morebuf+gobuf_pc)(BX)
- LEAQ 16(SP), AX // f's caller's SP
- MOVQ AX, (m_morebuf+gobuf_sp)(BX)
- get_tls(CX)
- MOVQ g(CX), SI
- MOVQ SI, (m_morebuf+gobuf_g)(BX)
-
- // Set g->sched to context in f.
- MOVQ 0(SP), AX // f's PC
- MOVQ AX, (g_sched+gobuf_pc)(SI)
- LEAQ 8(SP), AX // f's SP
- MOVQ AX, (g_sched+gobuf_sp)(SI)
- MOVQ BP, (g_sched+gobuf_bp)(SI)
- MOVQ DX, (g_sched+gobuf_ctxt)(SI)
-
- // Call newstack on m->g0's stack.
- MOVQ m_g0(BX), BX
- MOVQ BX, g(CX)
- MOVQ (g_sched+gobuf_sp)(BX), SP
- CALL runtime·newstack(SB)
- CALL runtime·abort(SB) // crash if newstack returns
- RET
-
-// morestack but not preserving ctxt.
-TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0
- MOVL $0, DX
- JMP runtime·morestack(SB)
-
-// spillArgs stores return values from registers to a *internal/abi.RegArgs in R12.
-TEXT ·spillArgs(SB),NOSPLIT,$0-0
- MOVQ AX, 0(R12)
- MOVQ BX, 8(R12)
- MOVQ CX, 16(R12)
- MOVQ DI, 24(R12)
- MOVQ SI, 32(R12)
- MOVQ R8, 40(R12)
- MOVQ R9, 48(R12)
- MOVQ R10, 56(R12)
- MOVQ R11, 64(R12)
- MOVQ X0, 72(R12)
- MOVQ X1, 80(R12)
- MOVQ X2, 88(R12)
- MOVQ X3, 96(R12)
- MOVQ X4, 104(R12)
- MOVQ X5, 112(R12)
- MOVQ X6, 120(R12)
- MOVQ X7, 128(R12)
- MOVQ X8, 136(R12)
- MOVQ X9, 144(R12)
- MOVQ X10, 152(R12)
- MOVQ X11, 160(R12)
- MOVQ X12, 168(R12)
- MOVQ X13, 176(R12)
- MOVQ X14, 184(R12)
- RET
-
-// unspillArgs loads args into registers from a *internal/abi.RegArgs in R12.
-TEXT ·unspillArgs(SB),NOSPLIT,$0-0
- MOVQ 0(R12), AX
- MOVQ 8(R12), BX
- MOVQ 16(R12), CX
- MOVQ 24(R12), DI
- MOVQ 32(R12), SI
- MOVQ 40(R12), R8
- MOVQ 48(R12), R9
- MOVQ 56(R12), R10
- MOVQ 64(R12), R11
- MOVQ 72(R12), X0
- MOVQ 80(R12), X1
- MOVQ 88(R12), X2
- MOVQ 96(R12), X3
- MOVQ 104(R12), X4
- MOVQ 112(R12), X5
- MOVQ 120(R12), X6
- MOVQ 128(R12), X7
- MOVQ 136(R12), X8
- MOVQ 144(R12), X9
- MOVQ 152(R12), X10
- MOVQ 160(R12), X11
- MOVQ 168(R12), X12
- MOVQ 176(R12), X13
- MOVQ 184(R12), X14
- RET
-
-// reflectcall: call a function with the given argument list
-// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
-// we don't have variable-sized frames, so we use a small number
-// of constant-sized-frame functions to encode a few bits of size in the pc.
-// Caution: ugly multiline assembly macros in your future!
-
-#define DISPATCH(NAME,MAXSIZE) \
- CMPQ CX, $MAXSIZE; \
- JA 3(PC); \
- MOVQ $NAME(SB), AX; \
- JMP AX
-// Note: can't just "JMP NAME(SB)" - bad inlining results.
-
-TEXT ·reflectcall(SB), NOSPLIT, $0-48
- MOVLQZX frameSize+32(FP), CX
- DISPATCH(runtime·call16, 16)
- DISPATCH(runtime·call32, 32)
- DISPATCH(runtime·call64, 64)
- DISPATCH(runtime·call128, 128)
- DISPATCH(runtime·call256, 256)
- DISPATCH(runtime·call512, 512)
- DISPATCH(runtime·call1024, 1024)
- DISPATCH(runtime·call2048, 2048)
- DISPATCH(runtime·call4096, 4096)
- DISPATCH(runtime·call8192, 8192)
- DISPATCH(runtime·call16384, 16384)
- DISPATCH(runtime·call32768, 32768)
- DISPATCH(runtime·call65536, 65536)
- DISPATCH(runtime·call131072, 131072)
- DISPATCH(runtime·call262144, 262144)
- DISPATCH(runtime·call524288, 524288)
- DISPATCH(runtime·call1048576, 1048576)
- DISPATCH(runtime·call2097152, 2097152)
- DISPATCH(runtime·call4194304, 4194304)
- DISPATCH(runtime·call8388608, 8388608)
- DISPATCH(runtime·call16777216, 16777216)
- DISPATCH(runtime·call33554432, 33554432)
- DISPATCH(runtime·call67108864, 67108864)
- DISPATCH(runtime·call134217728, 134217728)
- DISPATCH(runtime·call268435456, 268435456)
- DISPATCH(runtime·call536870912, 536870912)
- DISPATCH(runtime·call1073741824, 1073741824)
- MOVQ $runtime·badreflectcall(SB), AX
- JMP AX
-
-#define CALLFN(NAME,MAXSIZE) \
-TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \
- NO_LOCAL_POINTERS; \
- /* copy arguments to stack */ \
- MOVQ stackArgs+16(FP), SI; \
- MOVLQZX stackArgsSize+24(FP), CX; \
- MOVQ SP, DI; \
- REP;MOVSB; \
- /* set up argument registers */ \
- MOVQ regArgs+40(FP), R12; \
- CALL ·unspillArgs(SB); \
- /* call function */ \
- MOVQ f+8(FP), DX; \
- PCDATA $PCDATA_StackMapIndex, $0; \
- MOVQ (DX), R12; \
- CALL R12; \
- /* copy register return values back */ \
- MOVQ regArgs+40(FP), R12; \
- CALL ·spillArgs(SB); \
- MOVLQZX stackArgsSize+24(FP), CX; \
- MOVLQZX stackRetOffset+28(FP), BX; \
- MOVQ stackArgs+16(FP), DI; \
- MOVQ stackArgsType+0(FP), DX; \
- MOVQ SP, SI; \
- ADDQ BX, DI; \
- ADDQ BX, SI; \
- SUBQ BX, CX; \
- CALL callRet<>(SB); \
- RET
-
-// callRet copies return values back at the end of call*. This is a
-// separate function so it can allocate stack space for the arguments
-// to reflectcallmove. It does not follow the Go ABI; it expects its
-// arguments in registers.
-TEXT callRet<>(SB), NOSPLIT, $40-0
- NO_LOCAL_POINTERS
- MOVQ DX, 0(SP)
- MOVQ DI, 8(SP)
- MOVQ SI, 16(SP)
- MOVQ CX, 24(SP)
- MOVQ R12, 32(SP)
- CALL runtime·reflectcallmove(SB)
- RET
-
-CALLFN(·call16, 16)
-CALLFN(·call32, 32)
-CALLFN(·call64, 64)
-CALLFN(·call128, 128)
-CALLFN(·call256, 256)
-CALLFN(·call512, 512)
-CALLFN(·call1024, 1024)
-CALLFN(·call2048, 2048)
-CALLFN(·call4096, 4096)
-CALLFN(·call8192, 8192)
-CALLFN(·call16384, 16384)
-CALLFN(·call32768, 32768)
-CALLFN(·call65536, 65536)
-CALLFN(·call131072, 131072)
-CALLFN(·call262144, 262144)
-CALLFN(·call524288, 524288)
-CALLFN(·call1048576, 1048576)
-CALLFN(·call2097152, 2097152)
-CALLFN(·call4194304, 4194304)
-CALLFN(·call8388608, 8388608)
-CALLFN(·call16777216, 16777216)
-CALLFN(·call33554432, 33554432)
-CALLFN(·call67108864, 67108864)
-CALLFN(·call134217728, 134217728)
-CALLFN(·call268435456, 268435456)
-CALLFN(·call536870912, 536870912)
-CALLFN(·call1073741824, 1073741824)
-
-TEXT runtime·procyield(SB),NOSPLIT,$0-0
- MOVL cycles+0(FP), AX
-again:
- PAUSE
- SUBL $1, AX
- JNZ again
- RET
-
-
-TEXT ·publicationBarrier(SB),NOSPLIT,$0-0
- // Stores are already ordered on x86, so this is just a
- // compile barrier.
- RET
-
-// Save state of caller into g->sched,
-// but using fake PC from systemstack_switch.
-// Must only be called from functions with no locals ($0)
-// or else unwinding from systemstack_switch is incorrect.
-// Smashes R9.
-TEXT gosave_systemstack_switch<>(SB),NOSPLIT,$0
- MOVQ $runtime·systemstack_switch(SB), R9
- MOVQ R9, (g_sched+gobuf_pc)(R14)
- LEAQ 8(SP), R9
- MOVQ R9, (g_sched+gobuf_sp)(R14)
- MOVQ $0, (g_sched+gobuf_ret)(R14)
- MOVQ BP, (g_sched+gobuf_bp)(R14)
- // Assert ctxt is zero. See func save.
- MOVQ (g_sched+gobuf_ctxt)(R14), R9
- TESTQ R9, R9
- JZ 2(PC)
- CALL runtime·abort(SB)
- RET
-
-// func asmcgocall_no_g(fn, arg unsafe.Pointer)
-// Call fn(arg) aligned appropriately for the gcc ABI.
-// Called on a system stack, and there may be no g yet (during needm).
-TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
- MOVQ fn+0(FP), AX
- MOVQ arg+8(FP), BX
- MOVQ SP, DX
- SUBQ $32, SP
- ANDQ $~15, SP // alignment
- MOVQ DX, 8(SP)
- MOVQ BX, DI // DI = first argument in AMD64 ABI
- MOVQ BX, CX // CX = first argument in Win64
- CALL AX
- MOVQ 8(SP), DX
- MOVQ DX, SP
- RET
-
-// func asmcgocall(fn, arg unsafe.Pointer) int32
-// Call fn(arg) on the scheduler stack,
-// aligned appropriately for the gcc ABI.
-// See cgocall.go for more details.
-TEXT ·asmcgocall(SB),NOSPLIT,$0-20
- MOVQ fn+0(FP), AX
- MOVQ arg+8(FP), BX
-
- MOVQ SP, DX
-
- // Figure out if we need to switch to m->g0 stack.
- // We get called to create new OS threads too, and those
- // come in on the m->g0 stack already. Or we might already
- // be on the m->gsignal stack.
- get_tls(CX)
- MOVQ g(CX), DI
- CMPQ DI, $0
- JEQ nosave
- MOVQ g_m(DI), R8
- MOVQ m_gsignal(R8), SI
- CMPQ DI, SI
- JEQ nosave
- MOVQ m_g0(R8), SI
- CMPQ DI, SI
- JEQ nosave
-
- // Switch to system stack.
- CALL gosave_systemstack_switch<>(SB)
- MOVQ SI, g(CX)
- MOVQ (g_sched+gobuf_sp)(SI), SP
-
- // Now on a scheduling stack (a pthread-created stack).
- // Make sure we have enough room for 4 stack-backed fast-call
- // registers as per windows amd64 calling convention.
- SUBQ $64, SP
- ANDQ $~15, SP // alignment for gcc ABI
- MOVQ DI, 48(SP) // save g
- MOVQ (g_stack+stack_hi)(DI), DI
- SUBQ DX, DI
- MOVQ DI, 40(SP) // save depth in stack (can't just save SP, as stack might be copied during a callback)
- MOVQ BX, DI // DI = first argument in AMD64 ABI
- MOVQ BX, CX // CX = first argument in Win64
- CALL AX
-
- // Restore registers, g, stack pointer.
- get_tls(CX)
- MOVQ 48(SP), DI
- MOVQ (g_stack+stack_hi)(DI), SI
- SUBQ 40(SP), SI
- MOVQ DI, g(CX)
- MOVQ SI, SP
-
- MOVL AX, ret+16(FP)
- RET
-
-nosave:
- // Running on a system stack, perhaps even without a g.
- // Having no g can happen during thread creation or thread teardown
- // (see needm/dropm on Solaris, for example).
- // This code is like the above sequence but without saving/restoring g
- // and without worrying about the stack moving out from under us
- // (because we're on a system stack, not a goroutine stack).
- // The above code could be used directly if already on a system stack,
- // but then the only path through this code would be a rare case on Solaris.
- // Using this code for all "already on system stack" calls exercises it more,
- // which should help keep it correct.
- SUBQ $64, SP
- ANDQ $~15, SP
- MOVQ $0, 48(SP) // where above code stores g, in case someone looks during debugging
- MOVQ DX, 40(SP) // save original stack pointer
- MOVQ BX, DI // DI = first argument in AMD64 ABI
- MOVQ BX, CX // CX = first argument in Win64
- CALL AX
- MOVQ 40(SP), SI // restore original stack pointer
- MOVQ SI, SP
- MOVL AX, ret+16(FP)
- RET
-
-#ifdef GOOS_windows
-// Dummy TLS that's used on Windows so that we don't crash trying
-// to restore the G register in needm. needm and its callees are
-// very careful never to actually use the G, the TLS just can't be
-// unset since we're in Go code.
-GLOBL zeroTLS<>(SB),RODATA,$const_tlsSize
-#endif
-
-// func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
-// See cgocall.go for more details.
-TEXT ·cgocallback(SB),NOSPLIT,$24-24
- NO_LOCAL_POINTERS
-
- // If g is nil, Go did not create the current thread.
- // Call needm to obtain one m for temporary use.
- // In this case, we're running on the thread stack, so there's
- // lots of space, but the linker doesn't know. Hide the call from
- // the linker analysis by using an indirect call through AX.
- get_tls(CX)
-#ifdef GOOS_windows
- MOVL $0, BX
- CMPQ CX, $0
- JEQ 2(PC)
-#endif
- MOVQ g(CX), BX
- CMPQ BX, $0
- JEQ needm
- MOVQ g_m(BX), BX
- MOVQ BX, savedm-8(SP) // saved copy of oldm
- JMP havem
-needm:
-#ifdef GOOS_windows
- // Set up a dummy TLS value. needm is careful not to use it,
- // but it needs to be there to prevent autogenerated code from
- // crashing when it loads from it.
- // We don't need to clear it or anything later because needm
- // will set up TLS properly.
- MOVQ $zeroTLS<>(SB), DI
- CALL runtime·settls(SB)
-#endif
- // On some platforms (Windows) we cannot call needm through
- // an ABI wrapper because there's no TLS set up, and the ABI
- // wrapper will try to restore the G register (R14) from TLS.
- // Clear X15 because Go expects it and we're not calling
- // through a wrapper, but otherwise avoid setting the G
- // register in the wrapper and call needm directly. It
- // takes no arguments and doesn't return any values so
- // there's no need to handle that. Clear R14 so that there's
- // a bad value in there, in case needm tries to use it.
- XORPS X15, X15
- XORQ R14, R14
- MOVQ $runtime·needm<ABIInternal>(SB), AX
- CALL AX
- MOVQ $0, savedm-8(SP) // dropm on return
- get_tls(CX)
- MOVQ g(CX), BX
- MOVQ g_m(BX), BX
-
- // Set m->sched.sp = SP, so that if a panic happens
- // during the function we are about to execute, it will
- // have a valid SP to run on the g0 stack.
- // The next few lines (after the havem label)
- // will save this SP onto the stack and then write
- // the same SP back to m->sched.sp. That seems redundant,
- // but if an unrecovered panic happens, unwindm will
- // restore the g->sched.sp from the stack location
- // and then systemstack will try to use it. If we don't set it here,
- // that restored SP will be uninitialized (typically 0) and
- // will not be usable.
- MOVQ m_g0(BX), SI
- MOVQ SP, (g_sched+gobuf_sp)(SI)
-
-havem:
- // Now there's a valid m, and we're running on its m->g0.
- // Save current m->g0->sched.sp on stack and then set it to SP.
- // Save current sp in m->g0->sched.sp in preparation for
- // switch back to m->curg stack.
- // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
- MOVQ m_g0(BX), SI
- MOVQ (g_sched+gobuf_sp)(SI), AX
- MOVQ AX, 0(SP)
- MOVQ SP, (g_sched+gobuf_sp)(SI)
-
- // Switch to m->curg stack and call runtime.cgocallbackg.
- // Because we are taking over the execution of m->curg
- // but *not* resuming what had been running, we need to
- // save that information (m->curg->sched) so we can restore it.
- // We can restore m->curg->sched.sp easily, because calling
- // runtime.cgocallbackg leaves SP unchanged upon return.
- // To save m->curg->sched.pc, we push it onto the curg stack and
- // open a frame the same size as cgocallback's g0 frame.
- // Once we switch to the curg stack, the pushed PC will appear
- // to be the return PC of cgocallback, so that the traceback
- // will seamlessly trace back into the earlier calls.
- MOVQ m_curg(BX), SI
- MOVQ SI, g(CX)
- MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
- MOVQ (g_sched+gobuf_pc)(SI), BX
- MOVQ BX, -8(DI) // "push" return PC on the g stack
- // Gather our arguments into registers.
- MOVQ fn+0(FP), BX
- MOVQ frame+8(FP), CX
- MOVQ ctxt+16(FP), DX
- // Compute the size of the frame, including return PC and, if
- // GOEXPERIMENT=framepointer, the saved base pointer
- LEAQ fn+0(FP), AX
- SUBQ SP, AX // AX is our actual frame size
- SUBQ AX, DI // Allocate the same frame size on the g stack
- MOVQ DI, SP
-
- MOVQ BX, 0(SP)
- MOVQ CX, 8(SP)
- MOVQ DX, 16(SP)
- MOVQ $runtime·cgocallbackg(SB), AX
- CALL AX // indirect call to bypass nosplit check. We're on a different stack now.
-
- // Compute the size of the frame again. FP and SP have
- // completely different values here than they did above,
- // but only their difference matters.
- LEAQ fn+0(FP), AX
- SUBQ SP, AX
-
- // Restore g->sched (== m->curg->sched) from saved values.
- get_tls(CX)
- MOVQ g(CX), SI
- MOVQ SP, DI
- ADDQ AX, DI
- MOVQ -8(DI), BX
- MOVQ BX, (g_sched+gobuf_pc)(SI)
- MOVQ DI, (g_sched+gobuf_sp)(SI)
-
- // Switch back to m->g0's stack and restore m->g0->sched.sp.
- // (Unlike m->curg, the g0 goroutine never uses sched.pc,
- // so we do not have to restore it.)
- MOVQ g(CX), BX
- MOVQ g_m(BX), BX
- MOVQ m_g0(BX), SI
- MOVQ SI, g(CX)
- MOVQ (g_sched+gobuf_sp)(SI), SP
- MOVQ 0(SP), AX
- MOVQ AX, (g_sched+gobuf_sp)(SI)
-
- // If the m on entry was nil, we called needm above to borrow an m
- // for the duration of the call. Since the call is over, return it with dropm.
- MOVQ savedm-8(SP), BX
- CMPQ BX, $0
- JNE done
- MOVQ $runtime·dropm(SB), AX
- CALL AX
-#ifdef GOOS_windows
- // We need to clear the TLS pointer in case the next
- // thread that comes into Go tries to reuse that space
- // but uses the same M.
- XORQ DI, DI
- CALL runtime·settls(SB)
-#endif
-done:
-
- // Done!
- RET
-
-// func setg(gg *g)
-// set g. for use by needm.
-TEXT runtime·setg(SB), NOSPLIT, $0-8
- MOVQ gg+0(FP), BX
- get_tls(CX)
- MOVQ BX, g(CX)
- RET
-
-// void setg_gcc(G*); set g called from gcc.
-TEXT setg_gcc<>(SB),NOSPLIT,$0
- get_tls(AX)
- MOVQ DI, g(AX)
- MOVQ DI, R14 // set the g register
- RET
-
-TEXT runtime·abort(SB),NOSPLIT,$0-0
- INT $3
-loop:
- JMP loop
-
-// check that SP is in range [g->stack.lo, g->stack.hi)
-TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
- get_tls(CX)
- MOVQ g(CX), AX
- CMPQ (g_stack+stack_hi)(AX), SP
- JHI 2(PC)
- CALL runtime·abort(SB)
- CMPQ SP, (g_stack+stack_lo)(AX)
- JHI 2(PC)
- CALL runtime·abort(SB)
- RET
-
-// func cputicks() int64
-TEXT runtime·cputicks(SB),NOSPLIT,$0-0
- CMPB internal∕cpu·X86+const_offsetX86HasRDTSCP(SB), $1
- JNE fences
- // Instruction stream serializing RDTSCP is supported.
- // RDTSCP is supported by Intel Nehalem (2008) and
- // AMD K8 Rev. F (2006) and newer.
- RDTSCP
-done:
- SHLQ $32, DX
- ADDQ DX, AX
- MOVQ AX, ret+0(FP)
- RET
-fences:
- // MFENCE is instruction stream serializing and flushes the
- // store buffers on AMD. The serialization semantics of LFENCE on AMD
- // are dependent on MSR C001_1029 and CPU generation.
- // LFENCE on Intel does wait for all previous instructions to have executed.
- // Intel recommends MFENCE;LFENCE in its manuals before RDTSC to have all
- // previous instructions executed and all previous loads and stores to globally visible.
- // Using MFENCE;LFENCE here aligns the serializing properties without
- // runtime detection of CPU manufacturer.
- MFENCE
- LFENCE
- RDTSC
- JMP done
-
-// func memhash(p unsafe.Pointer, h, s uintptr) uintptr
-// hash function using AES hardware instructions
-TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT,$0-32
- // AX = ptr to data
- // BX = seed
- // CX = size
- CMPB runtime·useAeshash(SB), $0
- JEQ noaes
- JMP aeshashbody<>(SB)
-noaes:
- JMP runtime·memhashFallback<ABIInternal>(SB)
-
-// func strhash(p unsafe.Pointer, h uintptr) uintptr
-TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT,$0-24
- // AX = ptr to string struct
- // BX = seed
- CMPB runtime·useAeshash(SB), $0
- JEQ noaes
- MOVQ 8(AX), CX // length of string
- MOVQ (AX), AX // string data
- JMP aeshashbody<>(SB)
-noaes:
- JMP runtime·strhashFallback<ABIInternal>(SB)
-
-// AX: data
-// BX: hash seed
-// CX: length
-// At return: AX = return value
-TEXT aeshashbody<>(SB),NOSPLIT,$0-0
- // Fill an SSE register with our seeds.
- MOVQ BX, X0 // 64 bits of per-table hash seed
- PINSRW $4, CX, X0 // 16 bits of length
- PSHUFHW $0, X0, X0 // repeat length 4 times total
- MOVO X0, X1 // save unscrambled seed
- PXOR runtime·aeskeysched(SB), X0 // xor in per-process seed
- AESENC X0, X0 // scramble seed
-
- CMPQ CX, $16
- JB aes0to15
- JE aes16
- CMPQ CX, $32
- JBE aes17to32
- CMPQ CX, $64
- JBE aes33to64
- CMPQ CX, $128
- JBE aes65to128
- JMP aes129plus
-
-aes0to15:
- TESTQ CX, CX
- JE aes0
-
- ADDQ $16, AX
- TESTW $0xff0, AX
- JE endofpage
-
- // 16 bytes loaded at this address won't cross
- // a page boundary, so we can load it directly.
- MOVOU -16(AX), X1
- ADDQ CX, CX
- MOVQ $masks<>(SB), AX
- PAND (AX)(CX*8), X1
-final1:
- PXOR X0, X1 // xor data with seed
- AESENC X1, X1 // scramble combo 3 times
- AESENC X1, X1
- AESENC X1, X1
- MOVQ X1, AX // return X1
- RET
-
-endofpage:
- // address ends in 1111xxxx. Might be up against
- // a page boundary, so load ending at last byte.
- // Then shift bytes down using pshufb.
- MOVOU -32(AX)(CX*1), X1
- ADDQ CX, CX
- MOVQ $shifts<>(SB), AX
- PSHUFB (AX)(CX*8), X1
- JMP final1
-
-aes0:
- // Return scrambled input seed
- AESENC X0, X0
- MOVQ X0, AX // return X0
- RET
-
-aes16:
- MOVOU (AX), X1
- JMP final1
-
-aes17to32:
- // make second starting seed
- PXOR runtime·aeskeysched+16(SB), X1
- AESENC X1, X1
-
- // load data to be hashed
- MOVOU (AX), X2
- MOVOU -16(AX)(CX*1), X3
-
- // xor with seed
- PXOR X0, X2
- PXOR X1, X3
-
- // scramble 3 times
- AESENC X2, X2
- AESENC X3, X3
- AESENC X2, X2
- AESENC X3, X3
- AESENC X2, X2
- AESENC X3, X3
-
- // combine results
- PXOR X3, X2
- MOVQ X2, AX // return X2
- RET
-
-aes33to64:
- // make 3 more starting seeds
- MOVO X1, X2
- MOVO X1, X3
- PXOR runtime·aeskeysched+16(SB), X1
- PXOR runtime·aeskeysched+32(SB), X2
- PXOR runtime·aeskeysched+48(SB), X3
- AESENC X1, X1
- AESENC X2, X2
- AESENC X3, X3
-
- MOVOU (AX), X4
- MOVOU 16(AX), X5
- MOVOU -32(AX)(CX*1), X6
- MOVOU -16(AX)(CX*1), X7
-
- PXOR X0, X4
- PXOR X1, X5
- PXOR X2, X6
- PXOR X3, X7
-
- AESENC X4, X4
- AESENC X5, X5
- AESENC X6, X6
- AESENC X7, X7
-
- AESENC X4, X4
- AESENC X5, X5
- AESENC X6, X6
- AESENC X7, X7
-
- AESENC X4, X4
- AESENC X5, X5
- AESENC X6, X6
- AESENC X7, X7
-
- PXOR X6, X4
- PXOR X7, X5
- PXOR X5, X4
- MOVQ X4, AX // return X4
- RET
-
-aes65to128:
- // make 7 more starting seeds
- MOVO X1, X2
- MOVO X1, X3
- MOVO X1, X4
- MOVO X1, X5
- MOVO X1, X6
- MOVO X1, X7
- PXOR runtime·aeskeysched+16(SB), X1
- PXOR runtime·aeskeysched+32(SB), X2
- PXOR runtime·aeskeysched+48(SB), X3
- PXOR runtime·aeskeysched+64(SB), X4
- PXOR runtime·aeskeysched+80(SB), X5
- PXOR runtime·aeskeysched+96(SB), X6
- PXOR runtime·aeskeysched+112(SB), X7
- AESENC X1, X1
- AESENC X2, X2
- AESENC X3, X3
- AESENC X4, X4
- AESENC X5, X5
- AESENC X6, X6
- AESENC X7, X7
-
- // load data
- MOVOU (AX), X8
- MOVOU 16(AX), X9
- MOVOU 32(AX), X10
- MOVOU 48(AX), X11
- MOVOU -64(AX)(CX*1), X12
- MOVOU -48(AX)(CX*1), X13
- MOVOU -32(AX)(CX*1), X14
- MOVOU -16(AX)(CX*1), X15
-
- // xor with seed
- PXOR X0, X8
- PXOR X1, X9
- PXOR X2, X10
- PXOR X3, X11
- PXOR X4, X12
- PXOR X5, X13
- PXOR X6, X14
- PXOR X7, X15
-
- // scramble 3 times
- AESENC X8, X8
- AESENC X9, X9
- AESENC X10, X10
- AESENC X11, X11
- AESENC X12, X12
- AESENC X13, X13
- AESENC X14, X14
- AESENC X15, X15
-
- AESENC X8, X8
- AESENC X9, X9
- AESENC X10, X10
- AESENC X11, X11
- AESENC X12, X12
- AESENC X13, X13
- AESENC X14, X14
- AESENC X15, X15
-
- AESENC X8, X8
- AESENC X9, X9
- AESENC X10, X10
- AESENC X11, X11
- AESENC X12, X12
- AESENC X13, X13
- AESENC X14, X14
- AESENC X15, X15
-
- // combine results
- PXOR X12, X8
- PXOR X13, X9
- PXOR X14, X10
- PXOR X15, X11
- PXOR X10, X8
- PXOR X11, X9
- PXOR X9, X8
- // X15 must be zero on return
- PXOR X15, X15
- MOVQ X8, AX // return X8
- RET
-
-aes129plus:
- // make 7 more starting seeds
- MOVO X1, X2
- MOVO X1, X3
- MOVO X1, X4
- MOVO X1, X5
- MOVO X1, X6
- MOVO X1, X7
- PXOR runtime·aeskeysched+16(SB), X1
- PXOR runtime·aeskeysched+32(SB), X2
- PXOR runtime·aeskeysched+48(SB), X3
- PXOR runtime·aeskeysched+64(SB), X4
- PXOR runtime·aeskeysched+80(SB), X5
- PXOR runtime·aeskeysched+96(SB), X6
- PXOR runtime·aeskeysched+112(SB), X7
- AESENC X1, X1
- AESENC X2, X2
- AESENC X3, X3
- AESENC X4, X4
- AESENC X5, X5
- AESENC X6, X6
- AESENC X7, X7
-
- // start with last (possibly overlapping) block
- MOVOU -128(AX)(CX*1), X8
- MOVOU -112(AX)(CX*1), X9
- MOVOU -96(AX)(CX*1), X10
- MOVOU -80(AX)(CX*1), X11
- MOVOU -64(AX)(CX*1), X12
- MOVOU -48(AX)(CX*1), X13
- MOVOU -32(AX)(CX*1), X14
- MOVOU -16(AX)(CX*1), X15
-
- // xor in seed
- PXOR X0, X8
- PXOR X1, X9
- PXOR X2, X10
- PXOR X3, X11
- PXOR X4, X12
- PXOR X5, X13
- PXOR X6, X14
- PXOR X7, X15
-
- // compute number of remaining 128-byte blocks
- DECQ CX
- SHRQ $7, CX
-
-aesloop:
- // scramble state
- AESENC X8, X8
- AESENC X9, X9
- AESENC X10, X10
- AESENC X11, X11
- AESENC X12, X12
- AESENC X13, X13
- AESENC X14, X14
- AESENC X15, X15
-
- // scramble state, xor in a block
- MOVOU (AX), X0
- MOVOU 16(AX), X1
- MOVOU 32(AX), X2
- MOVOU 48(AX), X3
- AESENC X0, X8
- AESENC X1, X9
- AESENC X2, X10
- AESENC X3, X11
- MOVOU 64(AX), X4
- MOVOU 80(AX), X5
- MOVOU 96(AX), X6
- MOVOU 112(AX), X7
- AESENC X4, X12
- AESENC X5, X13
- AESENC X6, X14
- AESENC X7, X15
-
- ADDQ $128, AX
- DECQ CX
- JNE aesloop
-
- // 3 more scrambles to finish
- AESENC X8, X8
- AESENC X9, X9
- AESENC X10, X10
- AESENC X11, X11
- AESENC X12, X12
- AESENC X13, X13
- AESENC X14, X14
- AESENC X15, X15
- AESENC X8, X8
- AESENC X9, X9
- AESENC X10, X10
- AESENC X11, X11
- AESENC X12, X12
- AESENC X13, X13
- AESENC X14, X14
- AESENC X15, X15
- AESENC X8, X8
- AESENC X9, X9
- AESENC X10, X10
- AESENC X11, X11
- AESENC X12, X12
- AESENC X13, X13
- AESENC X14, X14
- AESENC X15, X15
-
- PXOR X12, X8
- PXOR X13, X9
- PXOR X14, X10
- PXOR X15, X11
- PXOR X10, X8
- PXOR X11, X9
- PXOR X9, X8
- // X15 must be zero on return
- PXOR X15, X15
- MOVQ X8, AX // return X8
- RET
-
-// func memhash32(p unsafe.Pointer, h uintptr) uintptr
-// ABIInternal for performance.
-TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT,$0-24
- // AX = ptr to data
- // BX = seed
- CMPB runtime·useAeshash(SB), $0
- JEQ noaes
- MOVQ BX, X0 // X0 = seed
- PINSRD $2, (AX), X0 // data
- AESENC runtime·aeskeysched+0(SB), X0
- AESENC runtime·aeskeysched+16(SB), X0
- AESENC runtime·aeskeysched+32(SB), X0
- MOVQ X0, AX // return X0
- RET
-noaes:
- JMP runtime·memhash32Fallback<ABIInternal>(SB)
-
-// func memhash64(p unsafe.Pointer, h uintptr) uintptr
-// ABIInternal for performance.
-TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT,$0-24
- // AX = ptr to data
- // BX = seed
- CMPB runtime·useAeshash(SB), $0
- JEQ noaes
- MOVQ BX, X0 // X0 = seed
- PINSRQ $1, (AX), X0 // data
- AESENC runtime·aeskeysched+0(SB), X0
- AESENC runtime·aeskeysched+16(SB), X0
- AESENC runtime·aeskeysched+32(SB), X0
- MOVQ X0, AX // return X0
- RET
-noaes:
- JMP runtime·memhash64Fallback<ABIInternal>(SB)
-
-// simple mask to get rid of data in the high part of the register.
-DATA masks<>+0x00(SB)/8, $0x0000000000000000
-DATA masks<>+0x08(SB)/8, $0x0000000000000000
-DATA masks<>+0x10(SB)/8, $0x00000000000000ff
-DATA masks<>+0x18(SB)/8, $0x0000000000000000
-DATA masks<>+0x20(SB)/8, $0x000000000000ffff
-DATA masks<>+0x28(SB)/8, $0x0000000000000000
-DATA masks<>+0x30(SB)/8, $0x0000000000ffffff
-DATA masks<>+0x38(SB)/8, $0x0000000000000000
-DATA masks<>+0x40(SB)/8, $0x00000000ffffffff
-DATA masks<>+0x48(SB)/8, $0x0000000000000000
-DATA masks<>+0x50(SB)/8, $0x000000ffffffffff
-DATA masks<>+0x58(SB)/8, $0x0000000000000000
-DATA masks<>+0x60(SB)/8, $0x0000ffffffffffff
-DATA masks<>+0x68(SB)/8, $0x0000000000000000
-DATA masks<>+0x70(SB)/8, $0x00ffffffffffffff
-DATA masks<>+0x78(SB)/8, $0x0000000000000000
-DATA masks<>+0x80(SB)/8, $0xffffffffffffffff
-DATA masks<>+0x88(SB)/8, $0x0000000000000000
-DATA masks<>+0x90(SB)/8, $0xffffffffffffffff
-DATA masks<>+0x98(SB)/8, $0x00000000000000ff
-DATA masks<>+0xa0(SB)/8, $0xffffffffffffffff
-DATA masks<>+0xa8(SB)/8, $0x000000000000ffff
-DATA masks<>+0xb0(SB)/8, $0xffffffffffffffff
-DATA masks<>+0xb8(SB)/8, $0x0000000000ffffff
-DATA masks<>+0xc0(SB)/8, $0xffffffffffffffff
-DATA masks<>+0xc8(SB)/8, $0x00000000ffffffff
-DATA masks<>+0xd0(SB)/8, $0xffffffffffffffff
-DATA masks<>+0xd8(SB)/8, $0x000000ffffffffff
-DATA masks<>+0xe0(SB)/8, $0xffffffffffffffff
-DATA masks<>+0xe8(SB)/8, $0x0000ffffffffffff
-DATA masks<>+0xf0(SB)/8, $0xffffffffffffffff
-DATA masks<>+0xf8(SB)/8, $0x00ffffffffffffff
-GLOBL masks<>(SB),RODATA,$256
-
-// func checkASM() bool
-TEXT ·checkASM(SB),NOSPLIT,$0-1
- // check that masks<>(SB) and shifts<>(SB) are aligned to 16-byte
- MOVQ $masks<>(SB), AX
- MOVQ $shifts<>(SB), BX
- ORQ BX, AX
- TESTQ $15, AX
- SETEQ ret+0(FP)
- RET
-
-// these are arguments to pshufb. They move data down from
-// the high bytes of the register to the low bytes of the register.
-// index is how many bytes to move.
-DATA shifts<>+0x00(SB)/8, $0x0000000000000000
-DATA shifts<>+0x08(SB)/8, $0x0000000000000000
-DATA shifts<>+0x10(SB)/8, $0xffffffffffffff0f
-DATA shifts<>+0x18(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x20(SB)/8, $0xffffffffffff0f0e
-DATA shifts<>+0x28(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x30(SB)/8, $0xffffffffff0f0e0d
-DATA shifts<>+0x38(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x40(SB)/8, $0xffffffff0f0e0d0c
-DATA shifts<>+0x48(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x50(SB)/8, $0xffffff0f0e0d0c0b
-DATA shifts<>+0x58(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x60(SB)/8, $0xffff0f0e0d0c0b0a
-DATA shifts<>+0x68(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x70(SB)/8, $0xff0f0e0d0c0b0a09
-DATA shifts<>+0x78(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x80(SB)/8, $0x0f0e0d0c0b0a0908
-DATA shifts<>+0x88(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x90(SB)/8, $0x0e0d0c0b0a090807
-DATA shifts<>+0x98(SB)/8, $0xffffffffffffff0f
-DATA shifts<>+0xa0(SB)/8, $0x0d0c0b0a09080706
-DATA shifts<>+0xa8(SB)/8, $0xffffffffffff0f0e
-DATA shifts<>+0xb0(SB)/8, $0x0c0b0a0908070605
-DATA shifts<>+0xb8(SB)/8, $0xffffffffff0f0e0d
-DATA shifts<>+0xc0(SB)/8, $0x0b0a090807060504
-DATA shifts<>+0xc8(SB)/8, $0xffffffff0f0e0d0c
-DATA shifts<>+0xd0(SB)/8, $0x0a09080706050403
-DATA shifts<>+0xd8(SB)/8, $0xffffff0f0e0d0c0b
-DATA shifts<>+0xe0(SB)/8, $0x0908070605040302
-DATA shifts<>+0xe8(SB)/8, $0xffff0f0e0d0c0b0a
-DATA shifts<>+0xf0(SB)/8, $0x0807060504030201
-DATA shifts<>+0xf8(SB)/8, $0xff0f0e0d0c0b0a09
-GLOBL shifts<>(SB),RODATA,$256
-
-TEXT runtime·return0(SB), NOSPLIT, $0
- MOVL $0, AX
- RET
-
-
-// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
-// Must obey the gcc calling convention.
-TEXT _cgo_topofstack(SB),NOSPLIT,$0
- get_tls(CX)
- MOVQ g(CX), AX
- MOVQ g_m(AX), AX
- MOVQ m_curg(AX), AX
- MOVQ (g_stack+stack_hi)(AX), AX
- RET
-
-// The top-most function running on a goroutine
-// returns to goexit+PCQuantum.
-TEXT runtime·goexit(SB),NOSPLIT|TOPFRAME,$0-0
- BYTE $0x90 // NOP
- CALL runtime·goexit1(SB) // does not return
- // traceback from goexit1 must hit code range of goexit
- BYTE $0x90 // NOP
-
-// This is called from .init_array and follows the platform, not Go, ABI.
-TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
- PUSHQ R15 // The access to global variables below implicitly uses R15, which is callee-save
- MOVQ runtime·lastmoduledatap(SB), AX
- MOVQ DI, moduledata_next(AX)
- MOVQ DI, runtime·lastmoduledatap(SB)
- POPQ R15
- RET
-
-// Initialize special registers then jump to sigpanic.
-// This function is injected from the signal handler for panicking
-// signals. It is quite painful to set X15 in the signal context,
-// so we do it here.
-TEXT ·sigpanic0(SB),NOSPLIT,$0-0
- get_tls(R14)
- MOVQ g(R14), R14
-#ifndef GOOS_plan9
- XORPS X15, X15
-#endif
- JMP ·sigpanic<ABIInternal>(SB)
-
-// gcWriteBarrier performs a heap pointer write and informs the GC.
-//
-// gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:
-// - DI is the destination of the write
-// - AX is the value being written at DI
-// It clobbers FLAGS. It does not clobber any general-purpose registers,
-// but may clobber others (e.g., SSE registers).
-// Defined as ABIInternal since it does not use the stack-based Go ABI.
-TEXT runtime·gcWriteBarrier<ABIInternal>(SB),NOSPLIT,$112
- // Save the registers clobbered by the fast path. This is slightly
- // faster than having the caller spill these.
- MOVQ R12, 96(SP)
- MOVQ R13, 104(SP)
- // TODO: Consider passing g.m.p in as an argument so they can be shared
- // across a sequence of write barriers.
- MOVQ g_m(R14), R13
- MOVQ m_p(R13), R13
- MOVQ (p_wbBuf+wbBuf_next)(R13), R12
- // Increment wbBuf.next position.
- LEAQ 16(R12), R12
- MOVQ R12, (p_wbBuf+wbBuf_next)(R13)
- CMPQ R12, (p_wbBuf+wbBuf_end)(R13)
- // Record the write.
- MOVQ AX, -16(R12) // Record value
- // Note: This turns bad pointer writes into bad
- // pointer reads, which could be confusing. We could avoid
- // reading from obviously bad pointers, which would
- // take care of the vast majority of these. We could
- // patch this up in the signal handler, or use XCHG to
- // combine the read and the write.
- MOVQ (DI), R13
- MOVQ R13, -8(R12) // Record *slot
- // Is the buffer full? (flags set in CMPQ above)
- JEQ flush
-ret:
- MOVQ 96(SP), R12
- MOVQ 104(SP), R13
- // Do the write.
- MOVQ AX, (DI)
- RET
-
-flush:
- // Save all general purpose registers since these could be
- // clobbered by wbBufFlush and were not saved by the caller.
- // It is possible for wbBufFlush to clobber other registers
- // (e.g., SSE registers), but the compiler takes care of saving
- // those in the caller if necessary. This strikes a balance
- // with registers that are likely to be used.
- //
- // We don't have type information for these, but all code under
- // here is NOSPLIT, so nothing will observe these.
- //
- // TODO: We could strike a different balance; e.g., saving X0
- // and not saving GP registers that are less likely to be used.
- MOVQ DI, 0(SP) // Also first argument to wbBufFlush
- MOVQ AX, 8(SP) // Also second argument to wbBufFlush
- MOVQ BX, 16(SP)
- MOVQ CX, 24(SP)
- MOVQ DX, 32(SP)
- // DI already saved
- MOVQ SI, 40(SP)
- MOVQ BP, 48(SP)
- MOVQ R8, 56(SP)
- MOVQ R9, 64(SP)
- MOVQ R10, 72(SP)
- MOVQ R11, 80(SP)
- // R12 already saved
- // R13 already saved
- // R14 is g
- MOVQ R15, 88(SP)
-
- // This takes arguments DI and AX
- CALL runtime·wbBufFlush(SB)
-
- MOVQ 0(SP), DI
- MOVQ 8(SP), AX
- MOVQ 16(SP), BX
- MOVQ 24(SP), CX
- MOVQ 32(SP), DX
- MOVQ 40(SP), SI
- MOVQ 48(SP), BP
- MOVQ 56(SP), R8
- MOVQ 64(SP), R9
- MOVQ 72(SP), R10
- MOVQ 80(SP), R11
- MOVQ 88(SP), R15
- JMP ret
-
-// gcWriteBarrierCX is gcWriteBarrier, but with args in DI and CX.
-// Defined as ABIInternal since it does not use the stable Go ABI.
-TEXT runtime·gcWriteBarrierCX<ABIInternal>(SB),NOSPLIT,$0
- XCHGQ CX, AX
- CALL runtime·gcWriteBarrier<ABIInternal>(SB)
- XCHGQ CX, AX
- RET
-
-// gcWriteBarrierDX is gcWriteBarrier, but with args in DI and DX.
-// Defined as ABIInternal since it does not use the stable Go ABI.
-TEXT runtime·gcWriteBarrierDX<ABIInternal>(SB),NOSPLIT,$0
- XCHGQ DX, AX
- CALL runtime·gcWriteBarrier<ABIInternal>(SB)
- XCHGQ DX, AX
- RET
-
-// gcWriteBarrierBX is gcWriteBarrier, but with args in DI and BX.
-// Defined as ABIInternal since it does not use the stable Go ABI.
-TEXT runtime·gcWriteBarrierBX<ABIInternal>(SB),NOSPLIT,$0
- XCHGQ BX, AX
- CALL runtime·gcWriteBarrier<ABIInternal>(SB)
- XCHGQ BX, AX
- RET
-
-// gcWriteBarrierBP is gcWriteBarrier, but with args in DI and BP.
-// Defined as ABIInternal since it does not use the stable Go ABI.
-TEXT runtime·gcWriteBarrierBP<ABIInternal>(SB),NOSPLIT,$0
- XCHGQ BP, AX
- CALL runtime·gcWriteBarrier<ABIInternal>(SB)
- XCHGQ BP, AX
- RET
-
-// gcWriteBarrierSI is gcWriteBarrier, but with args in DI and SI.
-// Defined as ABIInternal since it does not use the stable Go ABI.
-TEXT runtime·gcWriteBarrierSI<ABIInternal>(SB),NOSPLIT,$0
- XCHGQ SI, AX
- CALL runtime·gcWriteBarrier<ABIInternal>(SB)
- XCHGQ SI, AX
- RET
-
-// gcWriteBarrierR8 is gcWriteBarrier, but with args in DI and R8.
-// Defined as ABIInternal since it does not use the stable Go ABI.
-TEXT runtime·gcWriteBarrierR8<ABIInternal>(SB),NOSPLIT,$0
- XCHGQ R8, AX
- CALL runtime·gcWriteBarrier<ABIInternal>(SB)
- XCHGQ R8, AX
- RET
-
-// gcWriteBarrierR9 is gcWriteBarrier, but with args in DI and R9.
-// Defined as ABIInternal since it does not use the stable Go ABI.
-TEXT runtime·gcWriteBarrierR9<ABIInternal>(SB),NOSPLIT,$0
- XCHGQ R9, AX
- CALL runtime·gcWriteBarrier<ABIInternal>(SB)
- XCHGQ R9, AX
- RET
-
-DATA debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
-GLOBL debugCallFrameTooLarge<>(SB), RODATA, $20 // Size duplicated below
-
-// debugCallV2 is the entry point for debugger-injected function
-// calls on running goroutines. It informs the runtime that a
-// debug call has been injected and creates a call frame for the
-// debugger to fill in.
-//
-// To inject a function call, a debugger should:
-// 1. Check that the goroutine is in state _Grunning and that
-// there are at least 256 bytes free on the stack.
-// 2. Push the current PC on the stack (updating SP).
-// 3. Write the desired argument frame size at SP-16 (using the SP
-// after step 2).
-// 4. Save all machine registers (including flags and XMM registers)
-// so they can be restored later by the debugger.
-// 5. Set the PC to debugCallV2 and resume execution.
-//
-// If the goroutine is in state _Grunnable, then it's not generally
-// safe to inject a call because it may return out via other runtime
-// operations. Instead, the debugger should unwind the stack to find
-// the return to non-runtime code, add a temporary breakpoint there,
-// and inject the call once that breakpoint is hit.
-//
-// If the goroutine is in any other state, it's not safe to inject a call.
-//
-// This function communicates back to the debugger by setting R12 and
-// invoking INT3 to raise a breakpoint signal. See the comments in the
-// implementation for the protocol the debugger is expected to
-// follow. InjectDebugCall in the runtime tests demonstrates this protocol.
-//
-// The debugger must ensure that any pointers passed to the function
-// obey escape analysis requirements. Specifically, it must not pass
-// a stack pointer to an escaping argument. debugCallV2 cannot check
-// this invariant.
-//
-// This is ABIInternal because Go code injects its PC directly into new
-// goroutine stacks.
-TEXT runtime·debugCallV2<ABIInternal>(SB),NOSPLIT,$152-0
- // Save all registers that may contain pointers so they can be
- // conservatively scanned.
- //
- // We can't do anything that might clobber any of these
- // registers before this.
- MOVQ R15, r15-(14*8+8)(SP)
- MOVQ R14, r14-(13*8+8)(SP)
- MOVQ R13, r13-(12*8+8)(SP)
- MOVQ R12, r12-(11*8+8)(SP)
- MOVQ R11, r11-(10*8+8)(SP)
- MOVQ R10, r10-(9*8+8)(SP)
- MOVQ R9, r9-(8*8+8)(SP)
- MOVQ R8, r8-(7*8+8)(SP)
- MOVQ DI, di-(6*8+8)(SP)
- MOVQ SI, si-(5*8+8)(SP)
- MOVQ BP, bp-(4*8+8)(SP)
- MOVQ BX, bx-(3*8+8)(SP)
- MOVQ DX, dx-(2*8+8)(SP)
- // Save the frame size before we clobber it. Either of the last
- // saves could clobber this depending on whether there's a saved BP.
- MOVQ frameSize-24(FP), DX // aka -16(RSP) before prologue
- MOVQ CX, cx-(1*8+8)(SP)
- MOVQ AX, ax-(0*8+8)(SP)
-
- // Save the argument frame size.
- MOVQ DX, frameSize-128(SP)
-
- // Perform a safe-point check.
- MOVQ retpc-8(FP), AX // Caller's PC
- MOVQ AX, 0(SP)
- CALL runtime·debugCallCheck(SB)
- MOVQ 8(SP), AX
- TESTQ AX, AX
- JZ good
- // The safety check failed. Put the reason string at the top
- // of the stack.
- MOVQ AX, 0(SP)
- MOVQ 16(SP), AX
- MOVQ AX, 8(SP)
- // Set R12 to 8 and invoke INT3. The debugger should get the
- // reason a call can't be injected from the top of the stack
- // and resume execution.
- MOVQ $8, R12
- BYTE $0xcc
- JMP restore
-
-good:
- // Registers are saved and it's safe to make a call.
- // Open up a call frame, moving the stack if necessary.
- //
- // Once the frame is allocated, this will set R12 to 0 and
- // invoke INT3. The debugger should write the argument
- // frame for the call at SP, set up argument registers, push
- // the trapping PC on the stack, set the PC to the function to
- // call, set RDX to point to the closure (if a closure call),
- // and resume execution.
- //
- // If the function returns, this will set R12 to 1 and invoke
- // INT3. The debugger can then inspect any return value saved
- // on the stack at SP and in registers and resume execution again.
- //
- // If the function panics, this will set R12 to 2 and invoke INT3.
- // The interface{} value of the panic will be at SP. The debugger
- // can inspect the panic value and resume execution again.
-#define DEBUG_CALL_DISPATCH(NAME,MAXSIZE) \
- CMPQ AX, $MAXSIZE; \
- JA 5(PC); \
- MOVQ $NAME(SB), AX; \
- MOVQ AX, 0(SP); \
- CALL runtime·debugCallWrap(SB); \
- JMP restore
-
- MOVQ frameSize-128(SP), AX
- DEBUG_CALL_DISPATCH(debugCall32<>, 32)
- DEBUG_CALL_DISPATCH(debugCall64<>, 64)
- DEBUG_CALL_DISPATCH(debugCall128<>, 128)
- DEBUG_CALL_DISPATCH(debugCall256<>, 256)
- DEBUG_CALL_DISPATCH(debugCall512<>, 512)
- DEBUG_CALL_DISPATCH(debugCall1024<>, 1024)
- DEBUG_CALL_DISPATCH(debugCall2048<>, 2048)
- DEBUG_CALL_DISPATCH(debugCall4096<>, 4096)
- DEBUG_CALL_DISPATCH(debugCall8192<>, 8192)
- DEBUG_CALL_DISPATCH(debugCall16384<>, 16384)
- DEBUG_CALL_DISPATCH(debugCall32768<>, 32768)
- DEBUG_CALL_DISPATCH(debugCall65536<>, 65536)
- // The frame size is too large. Report the error.
- MOVQ $debugCallFrameTooLarge<>(SB), AX
- MOVQ AX, 0(SP)
- MOVQ $20, 8(SP) // length of debugCallFrameTooLarge string
- MOVQ $8, R12
- BYTE $0xcc
- JMP restore
-
-restore:
- // Calls and failures resume here.
- //
- // Set R12 to 16 and invoke INT3. The debugger should restore
- // all registers except RIP and RSP and resume execution.
- MOVQ $16, R12
- BYTE $0xcc
- // We must not modify flags after this point.
-
- // Restore pointer-containing registers, which may have been
- // modified from the debugger's copy by stack copying.
- MOVQ ax-(0*8+8)(SP), AX
- MOVQ cx-(1*8+8)(SP), CX
- MOVQ dx-(2*8+8)(SP), DX
- MOVQ bx-(3*8+8)(SP), BX
- MOVQ bp-(4*8+8)(SP), BP
- MOVQ si-(5*8+8)(SP), SI
- MOVQ di-(6*8+8)(SP), DI
- MOVQ r8-(7*8+8)(SP), R8
- MOVQ r9-(8*8+8)(SP), R9
- MOVQ r10-(9*8+8)(SP), R10
- MOVQ r11-(10*8+8)(SP), R11
- MOVQ r12-(11*8+8)(SP), R12
- MOVQ r13-(12*8+8)(SP), R13
- MOVQ r14-(13*8+8)(SP), R14
- MOVQ r15-(14*8+8)(SP), R15
-
- RET
-
-// runtime.debugCallCheck assumes that functions defined with the
-// DEBUG_CALL_FN macro are safe points to inject calls.
-#define DEBUG_CALL_FN(NAME,MAXSIZE) \
-TEXT NAME(SB),WRAPPER,$MAXSIZE-0; \
- NO_LOCAL_POINTERS; \
- MOVQ $0, R12; \
- BYTE $0xcc; \
- MOVQ $1, R12; \
- BYTE $0xcc; \
- RET
-DEBUG_CALL_FN(debugCall32<>, 32)
-DEBUG_CALL_FN(debugCall64<>, 64)
-DEBUG_CALL_FN(debugCall128<>, 128)
-DEBUG_CALL_FN(debugCall256<>, 256)
-DEBUG_CALL_FN(debugCall512<>, 512)
-DEBUG_CALL_FN(debugCall1024<>, 1024)
-DEBUG_CALL_FN(debugCall2048<>, 2048)
-DEBUG_CALL_FN(debugCall4096<>, 4096)
-DEBUG_CALL_FN(debugCall8192<>, 8192)
-DEBUG_CALL_FN(debugCall16384<>, 16384)
-DEBUG_CALL_FN(debugCall32768<>, 32768)
-DEBUG_CALL_FN(debugCall65536<>, 65536)
-
-// func debugCallPanicked(val interface{})
-TEXT runtime·debugCallPanicked(SB),NOSPLIT,$16-16
- // Copy the panic value to the top of stack.
- MOVQ val_type+0(FP), AX
- MOVQ AX, 0(SP)
- MOVQ val_data+8(FP), AX
- MOVQ AX, 8(SP)
- MOVQ $2, R12
- BYTE $0xcc
- RET
-
-// Note: these functions use a special calling convention to save generated code space.
-// Arguments are passed in registers, but the space for those arguments are allocated
-// in the caller's stack frame. These stubs write the args into that stack space and
-// then tail call to the corresponding runtime handler.
-// The tail call makes these stubs disappear in backtraces.
-// Defined as ABIInternal since they do not use the stack-based Go ABI.
-TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ CX, BX
- JMP runtime·goPanicIndex<ABIInternal>(SB)
-TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ CX, BX
- JMP runtime·goPanicIndexU<ABIInternal>(SB)
-TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ CX, AX
- MOVQ DX, BX
- JMP runtime·goPanicSliceAlen<ABIInternal>(SB)
-TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ CX, AX
- MOVQ DX, BX
- JMP runtime·goPanicSliceAlenU<ABIInternal>(SB)
-TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ CX, AX
- MOVQ DX, BX
- JMP runtime·goPanicSliceAcap<ABIInternal>(SB)
-TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ CX, AX
- MOVQ DX, BX
- JMP runtime·goPanicSliceAcapU<ABIInternal>(SB)
-TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ CX, BX
- JMP runtime·goPanicSliceB<ABIInternal>(SB)
-TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ CX, BX
- JMP runtime·goPanicSliceBU<ABIInternal>(SB)
-TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ DX, AX
- JMP runtime·goPanicSlice3Alen<ABIInternal>(SB)
-TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ DX, AX
- JMP runtime·goPanicSlice3AlenU<ABIInternal>(SB)
-TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ DX, AX
- JMP runtime·goPanicSlice3Acap<ABIInternal>(SB)
-TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ DX, AX
- JMP runtime·goPanicSlice3AcapU<ABIInternal>(SB)
-TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ CX, AX
- MOVQ DX, BX
- JMP runtime·goPanicSlice3B<ABIInternal>(SB)
-TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ CX, AX
- MOVQ DX, BX
- JMP runtime·goPanicSlice3BU<ABIInternal>(SB)
-TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ CX, BX
- JMP runtime·goPanicSlice3C<ABIInternal>(SB)
-TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ CX, BX
- JMP runtime·goPanicSlice3CU<ABIInternal>(SB)
-TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
- MOVQ DX, AX
- JMP runtime·goPanicSliceConvert<ABIInternal>(SB)
-
-#ifdef GOOS_android
-// Use the free TLS_SLOT_APP slot #2 on Android Q.
-// Earlier androids are set up in gcc_android.c.
-DATA runtime·tls_g+0(SB)/8, $16
-GLOBL runtime·tls_g+0(SB), NOPTR, $8
-#endif
-#ifdef GOOS_windows
-GLOBL runtime·tls_g+0(SB), NOPTR, $8
-#endif
-
-// The compiler and assembler's -spectre=ret mode rewrites
-// all indirect CALL AX / JMP AX instructions to be
-// CALL retpolineAX / JMP retpolineAX.
-// See https://support.google.com/faqs/answer/7625886.
-#define RETPOLINE(reg) \
- /* CALL setup */ BYTE $0xE8; BYTE $(2+2); BYTE $0; BYTE $0; BYTE $0; \
- /* nospec: */ \
- /* PAUSE */ BYTE $0xF3; BYTE $0x90; \
- /* JMP nospec */ BYTE $0xEB; BYTE $-(2+2); \
- /* setup: */ \
- /* MOVQ AX, 0(SP) */ BYTE $0x48|((reg&8)>>1); BYTE $0x89; \
- BYTE $0x04|((reg&7)<<3); BYTE $0x24; \
- /* RET */ BYTE $0xC3
-
-TEXT runtime·retpolineAX(SB),NOSPLIT,$0; RETPOLINE(0)
-TEXT runtime·retpolineCX(SB),NOSPLIT,$0; RETPOLINE(1)
-TEXT runtime·retpolineDX(SB),NOSPLIT,$0; RETPOLINE(2)
-TEXT runtime·retpolineBX(SB),NOSPLIT,$0; RETPOLINE(3)
-/* SP is 4, can't happen / magic encodings */
-TEXT runtime·retpolineBP(SB),NOSPLIT,$0; RETPOLINE(5)
-TEXT runtime·retpolineSI(SB),NOSPLIT,$0; RETPOLINE(6)
-TEXT runtime·retpolineDI(SB),NOSPLIT,$0; RETPOLINE(7)
-TEXT runtime·retpolineR8(SB),NOSPLIT,$0; RETPOLINE(8)
-TEXT runtime·retpolineR9(SB),NOSPLIT,$0; RETPOLINE(9)
-TEXT runtime·retpolineR10(SB),NOSPLIT,$0; RETPOLINE(10)
-TEXT runtime·retpolineR11(SB),NOSPLIT,$0; RETPOLINE(11)
-TEXT runtime·retpolineR12(SB),NOSPLIT,$0; RETPOLINE(12)
-TEXT runtime·retpolineR13(SB),NOSPLIT,$0; RETPOLINE(13)
-TEXT runtime·retpolineR14(SB),NOSPLIT,$0; RETPOLINE(14)
-TEXT runtime·retpolineR15(SB),NOSPLIT,$0; RETPOLINE(15)
diff --git a/contrib/go/_std_1.20/src/runtime/asm_arm64.s b/contrib/go/_std_1.20/src/runtime/asm_arm64.s
deleted file mode 100644
index 7eb5bcfd21..0000000000
--- a/contrib/go/_std_1.20/src/runtime/asm_arm64.s
+++ /dev/null
@@ -1,1525 +0,0 @@
-// Copyright 2015 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.
-
-#include "go_asm.h"
-#include "go_tls.h"
-#include "tls_arm64.h"
-#include "funcdata.h"
-#include "textflag.h"
-
-TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
- // SP = stack; R0 = argc; R1 = argv
-
- SUB $32, RSP
- MOVW R0, 8(RSP) // argc
- MOVD R1, 16(RSP) // argv
-
-#ifdef TLS_darwin
- // Initialize TLS.
- MOVD ZR, g // clear g, make sure it's not junk.
- SUB $32, RSP
- MRS_TPIDR_R0
- AND $~7, R0
- MOVD R0, 16(RSP) // arg2: TLS base
- MOVD $runtime·tls_g(SB), R2
- MOVD R2, 8(RSP) // arg1: &tlsg
- BL ·tlsinit(SB)
- ADD $32, RSP
-#endif
-
- // create istack out of the given (operating system) stack.
- // _cgo_init may update stackguard.
- MOVD $runtime·g0(SB), g
- MOVD RSP, R7
- MOVD $(-64*1024)(R7), R0
- MOVD R0, g_stackguard0(g)
- MOVD R0, g_stackguard1(g)
- MOVD R0, (g_stack+stack_lo)(g)
- MOVD R7, (g_stack+stack_hi)(g)
-
- // if there is a _cgo_init, call it using the gcc ABI.
- MOVD _cgo_init(SB), R12
- CBZ R12, nocgo
-
-#ifdef GOOS_android
- MRS_TPIDR_R0 // load TLS base pointer
- MOVD R0, R3 // arg 3: TLS base pointer
- MOVD $runtime·tls_g(SB), R2 // arg 2: &tls_g
-#else
- MOVD $0, R2 // arg 2: not used when using platform's TLS
-#endif
- MOVD $setg_gcc<>(SB), R1 // arg 1: setg
- MOVD g, R0 // arg 0: G
- SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
- BL (R12)
- ADD $16, RSP
-
-nocgo:
- BL runtime·save_g(SB)
- // update stackguard after _cgo_init
- MOVD (g_stack+stack_lo)(g), R0
- ADD $const__StackGuard, R0
- MOVD R0, g_stackguard0(g)
- MOVD R0, g_stackguard1(g)
-
- // set the per-goroutine and per-mach "registers"
- MOVD $runtime·m0(SB), R0
-
- // save m->g0 = g0
- MOVD g, m_g0(R0)
- // save m0 to g0->m
- MOVD R0, g_m(g)
-
- BL runtime·check(SB)
-
-#ifdef GOOS_windows
- BL runtime·wintls(SB)
-#endif
-
- MOVW 8(RSP), R0 // copy argc
- MOVW R0, -8(RSP)
- MOVD 16(RSP), R0 // copy argv
- MOVD R0, 0(RSP)
- BL runtime·args(SB)
- BL runtime·osinit(SB)
- BL runtime·schedinit(SB)
-
- // create a new goroutine to start program
- MOVD $runtime·mainPC(SB), R0 // entry
- SUB $16, RSP
- MOVD R0, 8(RSP) // arg
- MOVD $0, 0(RSP) // dummy LR
- BL runtime·newproc(SB)
- ADD $16, RSP
-
- // start this M
- BL runtime·mstart(SB)
-
- // Prevent dead-code elimination of debugCallV2, which is
- // intended to be called by debuggers.
- MOVD $runtime·debugCallV2<ABIInternal>(SB), R0
-
- MOVD $0, R0
- MOVD R0, (R0) // boom
- UNDEF
-
-DATA runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
-GLOBL runtime·mainPC(SB),RODATA,$8
-
-// Windows ARM64 needs an immediate 0xf000 argument.
-// See go.dev/issues/53837.
-#define BREAK \
-#ifdef GOOS_windows \
- BRK $0xf000 \
-#else \
- BRK \
-#endif \
-
-
-TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
- BREAK
- RET
-
-TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
- RET
-
-TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
- BL runtime·mstart0(SB)
- RET // not reached
-
-/*
- * go-routine
- */
-
-// void gogo(Gobuf*)
-// restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
- MOVD buf+0(FP), R5
- MOVD gobuf_g(R5), R6
- MOVD 0(R6), R4 // make sure g != nil
- B gogo<>(SB)
-
-TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
- MOVD R6, g
- BL runtime·save_g(SB)
-
- MOVD gobuf_sp(R5), R0
- MOVD R0, RSP
- MOVD gobuf_bp(R5), R29
- MOVD gobuf_lr(R5), LR
- MOVD gobuf_ret(R5), R0
- MOVD gobuf_ctxt(R5), R26
- MOVD $0, gobuf_sp(R5)
- MOVD $0, gobuf_bp(R5)
- MOVD $0, gobuf_ret(R5)
- MOVD $0, gobuf_lr(R5)
- MOVD $0, gobuf_ctxt(R5)
- CMP ZR, ZR // set condition codes for == test, needed by stack split
- MOVD gobuf_pc(R5), R6
- B (R6)
-
-// void mcall(fn func(*g))
-// Switch to m->g0's stack, call fn(g).
-// Fn must never return. It should gogo(&g->sched)
-// to keep running g.
-TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8
- MOVD R0, R26 // context
-
- // Save caller state in g->sched
- MOVD RSP, R0
- MOVD R0, (g_sched+gobuf_sp)(g)
- MOVD R29, (g_sched+gobuf_bp)(g)
- MOVD LR, (g_sched+gobuf_pc)(g)
- MOVD $0, (g_sched+gobuf_lr)(g)
-
- // Switch to m->g0 & its stack, call fn.
- MOVD g, R3
- MOVD g_m(g), R8
- MOVD m_g0(R8), g
- BL runtime·save_g(SB)
- CMP g, R3
- BNE 2(PC)
- B runtime·badmcall(SB)
-
- MOVD (g_sched+gobuf_sp)(g), R0
- MOVD R0, RSP // sp = m->g0->sched.sp
- MOVD (g_sched+gobuf_bp)(g), R29
- MOVD R3, R0 // arg = g
- MOVD $0, -16(RSP) // dummy LR
- SUB $16, RSP
- MOVD 0(R26), R4 // code pointer
- BL (R4)
- B runtime·badmcall2(SB)
-
-// systemstack_switch is a dummy routine that systemstack leaves at the bottom
-// of the G stack. We need to distinguish the routine that
-// lives at the bottom of the G stack from the one that lives
-// at the top of the system stack because the one at the top of
-// the system stack terminates the stack walk (see topofstack()).
-TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
- UNDEF
- BL (LR) // make sure this function is not leaf
- RET
-
-// func systemstack(fn func())
-TEXT runtime·systemstack(SB), NOSPLIT, $0-8
- MOVD fn+0(FP), R3 // R3 = fn
- MOVD R3, R26 // context
- MOVD g_m(g), R4 // R4 = m
-
- MOVD m_gsignal(R4), R5 // R5 = gsignal
- CMP g, R5
- BEQ noswitch
-
- MOVD m_g0(R4), R5 // R5 = g0
- CMP g, R5
- BEQ noswitch
-
- MOVD m_curg(R4), R6
- CMP g, R6
- BEQ switch
-
- // Bad: g is not gsignal, not g0, not curg. What is it?
- // Hide call from linker nosplit analysis.
- MOVD $runtime·badsystemstack(SB), R3
- BL (R3)
- B runtime·abort(SB)
-
-switch:
- // save our state in g->sched. Pretend to
- // be systemstack_switch if the G stack is scanned.
- BL gosave_systemstack_switch<>(SB)
-
- // switch to g0
- MOVD R5, g
- BL runtime·save_g(SB)
- MOVD (g_sched+gobuf_sp)(g), R3
- MOVD R3, RSP
- MOVD (g_sched+gobuf_bp)(g), R29
-
- // call target function
- MOVD 0(R26), R3 // code pointer
- BL (R3)
-
- // switch back to g
- MOVD g_m(g), R3
- MOVD m_curg(R3), g
- BL runtime·save_g(SB)
- MOVD (g_sched+gobuf_sp)(g), R0
- MOVD R0, RSP
- MOVD (g_sched+gobuf_bp)(g), R29
- MOVD $0, (g_sched+gobuf_sp)(g)
- MOVD $0, (g_sched+gobuf_bp)(g)
- RET
-
-noswitch:
- // already on m stack, just call directly
- // Using a tail call here cleans up tracebacks since we won't stop
- // at an intermediate systemstack.
- MOVD 0(R26), R3 // code pointer
- MOVD.P 16(RSP), R30 // restore LR
- SUB $8, RSP, R29 // restore FP
- B (R3)
-
-/*
- * support for morestack
- */
-
-// Called during function prolog when more stack is needed.
-// Caller has already loaded:
-// R3 prolog's LR (R30)
-//
-// The traceback routines see morestack on a g0 as being
-// the top of a stack (for example, morestack calling newstack
-// calling the scheduler calling newm calling gc), so we must
-// record an argument size. For that purpose, it has no arguments.
-TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
- // Cannot grow scheduler stack (m->g0).
- MOVD g_m(g), R8
- MOVD m_g0(R8), R4
- CMP g, R4
- BNE 3(PC)
- BL runtime·badmorestackg0(SB)
- B runtime·abort(SB)
-
- // Cannot grow signal stack (m->gsignal).
- MOVD m_gsignal(R8), R4
- CMP g, R4
- BNE 3(PC)
- BL runtime·badmorestackgsignal(SB)
- B runtime·abort(SB)
-
- // Called from f.
- // Set g->sched to context in f
- MOVD RSP, R0
- MOVD R0, (g_sched+gobuf_sp)(g)
- MOVD R29, (g_sched+gobuf_bp)(g)
- MOVD LR, (g_sched+gobuf_pc)(g)
- MOVD R3, (g_sched+gobuf_lr)(g)
- MOVD R26, (g_sched+gobuf_ctxt)(g)
-
- // Called from f.
- // Set m->morebuf to f's callers.
- MOVD R3, (m_morebuf+gobuf_pc)(R8) // f's caller's PC
- MOVD RSP, R0
- MOVD R0, (m_morebuf+gobuf_sp)(R8) // f's caller's RSP
- MOVD g, (m_morebuf+gobuf_g)(R8)
-
- // Call newstack on m->g0's stack.
- MOVD m_g0(R8), g
- BL runtime·save_g(SB)
- MOVD (g_sched+gobuf_sp)(g), R0
- MOVD R0, RSP
- MOVD (g_sched+gobuf_bp)(g), R29
- MOVD.W $0, -16(RSP) // create a call frame on g0 (saved LR; keep 16-aligned)
- BL runtime·newstack(SB)
-
- // Not reached, but make sure the return PC from the call to newstack
- // is still in this function, and not the beginning of the next.
- UNDEF
-
-TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
- // Force SPWRITE. This function doesn't actually write SP,
- // but it is called with a special calling convention where
- // the caller doesn't save LR on stack but passes it as a
- // register (R3), and the unwinder currently doesn't understand.
- // Make it SPWRITE to stop unwinding. (See issue 54332)
- MOVD RSP, RSP
-
- MOVW $0, R26
- B runtime·morestack(SB)
-
-// spillArgs stores return values from registers to a *internal/abi.RegArgs in R20.
-TEXT ·spillArgs(SB),NOSPLIT,$0-0
- STP (R0, R1), (0*8)(R20)
- STP (R2, R3), (2*8)(R20)
- STP (R4, R5), (4*8)(R20)
- STP (R6, R7), (6*8)(R20)
- STP (R8, R9), (8*8)(R20)
- STP (R10, R11), (10*8)(R20)
- STP (R12, R13), (12*8)(R20)
- STP (R14, R15), (14*8)(R20)
- FSTPD (F0, F1), (16*8)(R20)
- FSTPD (F2, F3), (18*8)(R20)
- FSTPD (F4, F5), (20*8)(R20)
- FSTPD (F6, F7), (22*8)(R20)
- FSTPD (F8, F9), (24*8)(R20)
- FSTPD (F10, F11), (26*8)(R20)
- FSTPD (F12, F13), (28*8)(R20)
- FSTPD (F14, F15), (30*8)(R20)
- RET
-
-// unspillArgs loads args into registers from a *internal/abi.RegArgs in R20.
-TEXT ·unspillArgs(SB),NOSPLIT,$0-0
- LDP (0*8)(R20), (R0, R1)
- LDP (2*8)(R20), (R2, R3)
- LDP (4*8)(R20), (R4, R5)
- LDP (6*8)(R20), (R6, R7)
- LDP (8*8)(R20), (R8, R9)
- LDP (10*8)(R20), (R10, R11)
- LDP (12*8)(R20), (R12, R13)
- LDP (14*8)(R20), (R14, R15)
- FLDPD (16*8)(R20), (F0, F1)
- FLDPD (18*8)(R20), (F2, F3)
- FLDPD (20*8)(R20), (F4, F5)
- FLDPD (22*8)(R20), (F6, F7)
- FLDPD (24*8)(R20), (F8, F9)
- FLDPD (26*8)(R20), (F10, F11)
- FLDPD (28*8)(R20), (F12, F13)
- FLDPD (30*8)(R20), (F14, F15)
- RET
-
-// reflectcall: call a function with the given argument list
-// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
-// we don't have variable-sized frames, so we use a small number
-// of constant-sized-frame functions to encode a few bits of size in the pc.
-// Caution: ugly multiline assembly macros in your future!
-
-#define DISPATCH(NAME,MAXSIZE) \
- MOVD $MAXSIZE, R27; \
- CMP R27, R16; \
- BGT 3(PC); \
- MOVD $NAME(SB), R27; \
- B (R27)
-// Note: can't just "B NAME(SB)" - bad inlining results.
-
-TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
- MOVWU frameSize+32(FP), R16
- DISPATCH(runtime·call16, 16)
- DISPATCH(runtime·call32, 32)
- DISPATCH(runtime·call64, 64)
- DISPATCH(runtime·call128, 128)
- DISPATCH(runtime·call256, 256)
- DISPATCH(runtime·call512, 512)
- DISPATCH(runtime·call1024, 1024)
- DISPATCH(runtime·call2048, 2048)
- DISPATCH(runtime·call4096, 4096)
- DISPATCH(runtime·call8192, 8192)
- DISPATCH(runtime·call16384, 16384)
- DISPATCH(runtime·call32768, 32768)
- DISPATCH(runtime·call65536, 65536)
- DISPATCH(runtime·call131072, 131072)
- DISPATCH(runtime·call262144, 262144)
- DISPATCH(runtime·call524288, 524288)
- DISPATCH(runtime·call1048576, 1048576)
- DISPATCH(runtime·call2097152, 2097152)
- DISPATCH(runtime·call4194304, 4194304)
- DISPATCH(runtime·call8388608, 8388608)
- DISPATCH(runtime·call16777216, 16777216)
- DISPATCH(runtime·call33554432, 33554432)
- DISPATCH(runtime·call67108864, 67108864)
- DISPATCH(runtime·call134217728, 134217728)
- DISPATCH(runtime·call268435456, 268435456)
- DISPATCH(runtime·call536870912, 536870912)
- DISPATCH(runtime·call1073741824, 1073741824)
- MOVD $runtime·badreflectcall(SB), R0
- B (R0)
-
-#define CALLFN(NAME,MAXSIZE) \
-TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \
- NO_LOCAL_POINTERS; \
- /* copy arguments to stack */ \
- MOVD stackArgs+16(FP), R3; \
- MOVWU stackArgsSize+24(FP), R4; \
- ADD $8, RSP, R5; \
- BIC $0xf, R4, R6; \
- CBZ R6, 6(PC); \
- /* if R6=(argsize&~15) != 0 */ \
- ADD R6, R5, R6; \
- /* copy 16 bytes a time */ \
- LDP.P 16(R3), (R7, R8); \
- STP.P (R7, R8), 16(R5); \
- CMP R5, R6; \
- BNE -3(PC); \
- AND $0xf, R4, R6; \
- CBZ R6, 6(PC); \
- /* if R6=(argsize&15) != 0 */ \
- ADD R6, R5, R6; \
- /* copy 1 byte a time for the rest */ \
- MOVBU.P 1(R3), R7; \
- MOVBU.P R7, 1(R5); \
- CMP R5, R6; \
- BNE -3(PC); \
- /* set up argument registers */ \
- MOVD regArgs+40(FP), R20; \
- CALL ·unspillArgs(SB); \
- /* call function */ \
- MOVD f+8(FP), R26; \
- MOVD (R26), R20; \
- PCDATA $PCDATA_StackMapIndex, $0; \
- BL (R20); \
- /* copy return values back */ \
- MOVD regArgs+40(FP), R20; \
- CALL ·spillArgs(SB); \
- MOVD stackArgsType+0(FP), R7; \
- MOVD stackArgs+16(FP), R3; \
- MOVWU stackArgsSize+24(FP), R4; \
- MOVWU stackRetOffset+28(FP), R6; \
- ADD $8, RSP, R5; \
- ADD R6, R5; \
- ADD R6, R3; \
- SUB R6, R4; \
- BL callRet<>(SB); \
- RET
-
-// callRet copies return values back at the end of call*. This is a
-// separate function so it can allocate stack space for the arguments
-// to reflectcallmove. It does not follow the Go ABI; it expects its
-// arguments in registers.
-TEXT callRet<>(SB), NOSPLIT, $48-0
- NO_LOCAL_POINTERS
- STP (R7, R3), 8(RSP)
- STP (R5, R4), 24(RSP)
- MOVD R20, 40(RSP)
- BL runtime·reflectcallmove(SB)
- RET
-
-CALLFN(·call16, 16)
-CALLFN(·call32, 32)
-CALLFN(·call64, 64)
-CALLFN(·call128, 128)
-CALLFN(·call256, 256)
-CALLFN(·call512, 512)
-CALLFN(·call1024, 1024)
-CALLFN(·call2048, 2048)
-CALLFN(·call4096, 4096)
-CALLFN(·call8192, 8192)
-CALLFN(·call16384, 16384)
-CALLFN(·call32768, 32768)
-CALLFN(·call65536, 65536)
-CALLFN(·call131072, 131072)
-CALLFN(·call262144, 262144)
-CALLFN(·call524288, 524288)
-CALLFN(·call1048576, 1048576)
-CALLFN(·call2097152, 2097152)
-CALLFN(·call4194304, 4194304)
-CALLFN(·call8388608, 8388608)
-CALLFN(·call16777216, 16777216)
-CALLFN(·call33554432, 33554432)
-CALLFN(·call67108864, 67108864)
-CALLFN(·call134217728, 134217728)
-CALLFN(·call268435456, 268435456)
-CALLFN(·call536870912, 536870912)
-CALLFN(·call1073741824, 1073741824)
-
-// func memhash32(p unsafe.Pointer, h uintptr) uintptr
-TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
- MOVB runtime·useAeshash(SB), R10
- CBZ R10, noaes
- MOVD $runtime·aeskeysched+0(SB), R3
-
- VEOR V0.B16, V0.B16, V0.B16
- VLD1 (R3), [V2.B16]
- VLD1 (R0), V0.S[1]
- VMOV R1, V0.S[0]
-
- AESE V2.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V2.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V2.B16, V0.B16
-
- VMOV V0.D[0], R0
- RET
-noaes:
- B runtime·memhash32Fallback<ABIInternal>(SB)
-
-// func memhash64(p unsafe.Pointer, h uintptr) uintptr
-TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
- MOVB runtime·useAeshash(SB), R10
- CBZ R10, noaes
- MOVD $runtime·aeskeysched+0(SB), R3
-
- VEOR V0.B16, V0.B16, V0.B16
- VLD1 (R3), [V2.B16]
- VLD1 (R0), V0.D[1]
- VMOV R1, V0.D[0]
-
- AESE V2.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V2.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V2.B16, V0.B16
-
- VMOV V0.D[0], R0
- RET
-noaes:
- B runtime·memhash64Fallback<ABIInternal>(SB)
-
-// func memhash(p unsafe.Pointer, h, size uintptr) uintptr
-TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
- MOVB runtime·useAeshash(SB), R10
- CBZ R10, noaes
- B aeshashbody<>(SB)
-noaes:
- B runtime·memhashFallback<ABIInternal>(SB)
-
-// func strhash(p unsafe.Pointer, h uintptr) uintptr
-TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
- MOVB runtime·useAeshash(SB), R10
- CBZ R10, noaes
- LDP (R0), (R0, R2) // string data / length
- B aeshashbody<>(SB)
-noaes:
- B runtime·strhashFallback<ABIInternal>(SB)
-
-// R0: data
-// R1: seed data
-// R2: length
-// At return, R0 = return value
-TEXT aeshashbody<>(SB),NOSPLIT|NOFRAME,$0
- VEOR V30.B16, V30.B16, V30.B16
- VMOV R1, V30.D[0]
- VMOV R2, V30.D[1] // load length into seed
-
- MOVD $runtime·aeskeysched+0(SB), R4
- VLD1.P 16(R4), [V0.B16]
- AESE V30.B16, V0.B16
- AESMC V0.B16, V0.B16
- CMP $16, R2
- BLO aes0to15
- BEQ aes16
- CMP $32, R2
- BLS aes17to32
- CMP $64, R2
- BLS aes33to64
- CMP $128, R2
- BLS aes65to128
- B aes129plus
-
-aes0to15:
- CBZ R2, aes0
- VEOR V2.B16, V2.B16, V2.B16
- TBZ $3, R2, less_than_8
- VLD1.P 8(R0), V2.D[0]
-
-less_than_8:
- TBZ $2, R2, less_than_4
- VLD1.P 4(R0), V2.S[2]
-
-less_than_4:
- TBZ $1, R2, less_than_2
- VLD1.P 2(R0), V2.H[6]
-
-less_than_2:
- TBZ $0, R2, done
- VLD1 (R0), V2.B[14]
-done:
- AESE V0.B16, V2.B16
- AESMC V2.B16, V2.B16
- AESE V0.B16, V2.B16
- AESMC V2.B16, V2.B16
- AESE V0.B16, V2.B16
-
- VMOV V2.D[0], R0
- RET
-
-aes0:
- VMOV V0.D[0], R0
- RET
-
-aes16:
- VLD1 (R0), [V2.B16]
- B done
-
-aes17to32:
- // make second seed
- VLD1 (R4), [V1.B16]
- AESE V30.B16, V1.B16
- AESMC V1.B16, V1.B16
- SUB $16, R2, R10
- VLD1.P (R0)(R10), [V2.B16]
- VLD1 (R0), [V3.B16]
-
- AESE V0.B16, V2.B16
- AESMC V2.B16, V2.B16
- AESE V1.B16, V3.B16
- AESMC V3.B16, V3.B16
-
- AESE V0.B16, V2.B16
- AESMC V2.B16, V2.B16
- AESE V1.B16, V3.B16
- AESMC V3.B16, V3.B16
-
- AESE V0.B16, V2.B16
- AESE V1.B16, V3.B16
-
- VEOR V3.B16, V2.B16, V2.B16
-
- VMOV V2.D[0], R0
- RET
-
-aes33to64:
- VLD1 (R4), [V1.B16, V2.B16, V3.B16]
- AESE V30.B16, V1.B16
- AESMC V1.B16, V1.B16
- AESE V30.B16, V2.B16
- AESMC V2.B16, V2.B16
- AESE V30.B16, V3.B16
- AESMC V3.B16, V3.B16
- SUB $32, R2, R10
-
- VLD1.P (R0)(R10), [V4.B16, V5.B16]
- VLD1 (R0), [V6.B16, V7.B16]
-
- AESE V0.B16, V4.B16
- AESMC V4.B16, V4.B16
- AESE V1.B16, V5.B16
- AESMC V5.B16, V5.B16
- AESE V2.B16, V6.B16
- AESMC V6.B16, V6.B16
- AESE V3.B16, V7.B16
- AESMC V7.B16, V7.B16
-
- AESE V0.B16, V4.B16
- AESMC V4.B16, V4.B16
- AESE V1.B16, V5.B16
- AESMC V5.B16, V5.B16
- AESE V2.B16, V6.B16
- AESMC V6.B16, V6.B16
- AESE V3.B16, V7.B16
- AESMC V7.B16, V7.B16
-
- AESE V0.B16, V4.B16
- AESE V1.B16, V5.B16
- AESE V2.B16, V6.B16
- AESE V3.B16, V7.B16
-
- VEOR V6.B16, V4.B16, V4.B16
- VEOR V7.B16, V5.B16, V5.B16
- VEOR V5.B16, V4.B16, V4.B16
-
- VMOV V4.D[0], R0
- RET
-
-aes65to128:
- VLD1.P 64(R4), [V1.B16, V2.B16, V3.B16, V4.B16]
- VLD1 (R4), [V5.B16, V6.B16, V7.B16]
- AESE V30.B16, V1.B16
- AESMC V1.B16, V1.B16
- AESE V30.B16, V2.B16
- AESMC V2.B16, V2.B16
- AESE V30.B16, V3.B16
- AESMC V3.B16, V3.B16
- AESE V30.B16, V4.B16
- AESMC V4.B16, V4.B16
- AESE V30.B16, V5.B16
- AESMC V5.B16, V5.B16
- AESE V30.B16, V6.B16
- AESMC V6.B16, V6.B16
- AESE V30.B16, V7.B16
- AESMC V7.B16, V7.B16
-
- SUB $64, R2, R10
- VLD1.P (R0)(R10), [V8.B16, V9.B16, V10.B16, V11.B16]
- VLD1 (R0), [V12.B16, V13.B16, V14.B16, V15.B16]
- AESE V0.B16, V8.B16
- AESMC V8.B16, V8.B16
- AESE V1.B16, V9.B16
- AESMC V9.B16, V9.B16
- AESE V2.B16, V10.B16
- AESMC V10.B16, V10.B16
- AESE V3.B16, V11.B16
- AESMC V11.B16, V11.B16
- AESE V4.B16, V12.B16
- AESMC V12.B16, V12.B16
- AESE V5.B16, V13.B16
- AESMC V13.B16, V13.B16
- AESE V6.B16, V14.B16
- AESMC V14.B16, V14.B16
- AESE V7.B16, V15.B16
- AESMC V15.B16, V15.B16
-
- AESE V0.B16, V8.B16
- AESMC V8.B16, V8.B16
- AESE V1.B16, V9.B16
- AESMC V9.B16, V9.B16
- AESE V2.B16, V10.B16
- AESMC V10.B16, V10.B16
- AESE V3.B16, V11.B16
- AESMC V11.B16, V11.B16
- AESE V4.B16, V12.B16
- AESMC V12.B16, V12.B16
- AESE V5.B16, V13.B16
- AESMC V13.B16, V13.B16
- AESE V6.B16, V14.B16
- AESMC V14.B16, V14.B16
- AESE V7.B16, V15.B16
- AESMC V15.B16, V15.B16
-
- AESE V0.B16, V8.B16
- AESE V1.B16, V9.B16
- AESE V2.B16, V10.B16
- AESE V3.B16, V11.B16
- AESE V4.B16, V12.B16
- AESE V5.B16, V13.B16
- AESE V6.B16, V14.B16
- AESE V7.B16, V15.B16
-
- VEOR V12.B16, V8.B16, V8.B16
- VEOR V13.B16, V9.B16, V9.B16
- VEOR V14.B16, V10.B16, V10.B16
- VEOR V15.B16, V11.B16, V11.B16
- VEOR V10.B16, V8.B16, V8.B16
- VEOR V11.B16, V9.B16, V9.B16
- VEOR V9.B16, V8.B16, V8.B16
-
- VMOV V8.D[0], R0
- RET
-
-aes129plus:
- PRFM (R0), PLDL1KEEP
- VLD1.P 64(R4), [V1.B16, V2.B16, V3.B16, V4.B16]
- VLD1 (R4), [V5.B16, V6.B16, V7.B16]
- AESE V30.B16, V1.B16
- AESMC V1.B16, V1.B16
- AESE V30.B16, V2.B16
- AESMC V2.B16, V2.B16
- AESE V30.B16, V3.B16
- AESMC V3.B16, V3.B16
- AESE V30.B16, V4.B16
- AESMC V4.B16, V4.B16
- AESE V30.B16, V5.B16
- AESMC V5.B16, V5.B16
- AESE V30.B16, V6.B16
- AESMC V6.B16, V6.B16
- AESE V30.B16, V7.B16
- AESMC V7.B16, V7.B16
- ADD R0, R2, R10
- SUB $128, R10, R10
- VLD1.P 64(R10), [V8.B16, V9.B16, V10.B16, V11.B16]
- VLD1 (R10), [V12.B16, V13.B16, V14.B16, V15.B16]
- SUB $1, R2, R2
- LSR $7, R2, R2
-
-aesloop:
- AESE V8.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V9.B16, V1.B16
- AESMC V1.B16, V1.B16
- AESE V10.B16, V2.B16
- AESMC V2.B16, V2.B16
- AESE V11.B16, V3.B16
- AESMC V3.B16, V3.B16
- AESE V12.B16, V4.B16
- AESMC V4.B16, V4.B16
- AESE V13.B16, V5.B16
- AESMC V5.B16, V5.B16
- AESE V14.B16, V6.B16
- AESMC V6.B16, V6.B16
- AESE V15.B16, V7.B16
- AESMC V7.B16, V7.B16
-
- VLD1.P 64(R0), [V8.B16, V9.B16, V10.B16, V11.B16]
- AESE V8.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V9.B16, V1.B16
- AESMC V1.B16, V1.B16
- AESE V10.B16, V2.B16
- AESMC V2.B16, V2.B16
- AESE V11.B16, V3.B16
- AESMC V3.B16, V3.B16
-
- VLD1.P 64(R0), [V12.B16, V13.B16, V14.B16, V15.B16]
- AESE V12.B16, V4.B16
- AESMC V4.B16, V4.B16
- AESE V13.B16, V5.B16
- AESMC V5.B16, V5.B16
- AESE V14.B16, V6.B16
- AESMC V6.B16, V6.B16
- AESE V15.B16, V7.B16
- AESMC V7.B16, V7.B16
- SUB $1, R2, R2
- CBNZ R2, aesloop
-
- AESE V8.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V9.B16, V1.B16
- AESMC V1.B16, V1.B16
- AESE V10.B16, V2.B16
- AESMC V2.B16, V2.B16
- AESE V11.B16, V3.B16
- AESMC V3.B16, V3.B16
- AESE V12.B16, V4.B16
- AESMC V4.B16, V4.B16
- AESE V13.B16, V5.B16
- AESMC V5.B16, V5.B16
- AESE V14.B16, V6.B16
- AESMC V6.B16, V6.B16
- AESE V15.B16, V7.B16
- AESMC V7.B16, V7.B16
-
- AESE V8.B16, V0.B16
- AESMC V0.B16, V0.B16
- AESE V9.B16, V1.B16
- AESMC V1.B16, V1.B16
- AESE V10.B16, V2.B16
- AESMC V2.B16, V2.B16
- AESE V11.B16, V3.B16
- AESMC V3.B16, V3.B16
- AESE V12.B16, V4.B16
- AESMC V4.B16, V4.B16
- AESE V13.B16, V5.B16
- AESMC V5.B16, V5.B16
- AESE V14.B16, V6.B16
- AESMC V6.B16, V6.B16
- AESE V15.B16, V7.B16
- AESMC V7.B16, V7.B16
-
- AESE V8.B16, V0.B16
- AESE V9.B16, V1.B16
- AESE V10.B16, V2.B16
- AESE V11.B16, V3.B16
- AESE V12.B16, V4.B16
- AESE V13.B16, V5.B16
- AESE V14.B16, V6.B16
- AESE V15.B16, V7.B16
-
- VEOR V0.B16, V1.B16, V0.B16
- VEOR V2.B16, V3.B16, V2.B16
- VEOR V4.B16, V5.B16, V4.B16
- VEOR V6.B16, V7.B16, V6.B16
- VEOR V0.B16, V2.B16, V0.B16
- VEOR V4.B16, V6.B16, V4.B16
- VEOR V4.B16, V0.B16, V0.B16
-
- VMOV V0.D[0], R0
- RET
-
-TEXT runtime·procyield(SB),NOSPLIT,$0-0
- MOVWU cycles+0(FP), R0
-again:
- YIELD
- SUBW $1, R0
- CBNZ R0, again
- RET
-
-// Save state of caller into g->sched,
-// but using fake PC from systemstack_switch.
-// Must only be called from functions with no locals ($0)
-// or else unwinding from systemstack_switch is incorrect.
-// Smashes R0.
-TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
- MOVD $runtime·systemstack_switch(SB), R0
- ADD $8, R0 // get past prologue
- MOVD R0, (g_sched+gobuf_pc)(g)
- MOVD RSP, R0
- MOVD R0, (g_sched+gobuf_sp)(g)
- MOVD R29, (g_sched+gobuf_bp)(g)
- MOVD $0, (g_sched+gobuf_lr)(g)
- MOVD $0, (g_sched+gobuf_ret)(g)
- // Assert ctxt is zero. See func save.
- MOVD (g_sched+gobuf_ctxt)(g), R0
- CBZ R0, 2(PC)
- CALL runtime·abort(SB)
- RET
-
-// func asmcgocall_no_g(fn, arg unsafe.Pointer)
-// Call fn(arg) aligned appropriately for the gcc ABI.
-// Called on a system stack, and there may be no g yet (during needm).
-TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
- MOVD fn+0(FP), R1
- MOVD arg+8(FP), R0
- SUB $16, RSP // skip over saved frame pointer below RSP
- BL (R1)
- ADD $16, RSP // skip over saved frame pointer below RSP
- RET
-
-// func asmcgocall(fn, arg unsafe.Pointer) int32
-// Call fn(arg) on the scheduler stack,
-// aligned appropriately for the gcc ABI.
-// See cgocall.go for more details.
-TEXT ·asmcgocall(SB),NOSPLIT,$0-20
- MOVD fn+0(FP), R1
- MOVD arg+8(FP), R0
-
- MOVD RSP, R2 // save original stack pointer
- CBZ g, nosave
- MOVD g, R4
-
- // Figure out if we need to switch to m->g0 stack.
- // We get called to create new OS threads too, and those
- // come in on the m->g0 stack already. Or we might already
- // be on the m->gsignal stack.
- MOVD g_m(g), R8
- MOVD m_gsignal(R8), R3
- CMP R3, g
- BEQ nosave
- MOVD m_g0(R8), R3
- CMP R3, g
- BEQ nosave
-
- // Switch to system stack.
- MOVD R0, R9 // gosave_systemstack_switch<> and save_g might clobber R0
- BL gosave_systemstack_switch<>(SB)
- MOVD R3, g
- BL runtime·save_g(SB)
- MOVD (g_sched+gobuf_sp)(g), R0
- MOVD R0, RSP
- MOVD (g_sched+gobuf_bp)(g), R29
- MOVD R9, R0
-
- // Now on a scheduling stack (a pthread-created stack).
- // Save room for two of our pointers /*, plus 32 bytes of callee
- // save area that lives on the caller stack. */
- MOVD RSP, R13
- SUB $16, R13
- MOVD R13, RSP
- MOVD R4, 0(RSP) // save old g on stack
- MOVD (g_stack+stack_hi)(R4), R4
- SUB R2, R4
- MOVD R4, 8(RSP) // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
- BL (R1)
- MOVD R0, R9
-
- // Restore g, stack pointer. R0 is errno, so don't touch it
- MOVD 0(RSP), g
- BL runtime·save_g(SB)
- MOVD (g_stack+stack_hi)(g), R5
- MOVD 8(RSP), R6
- SUB R6, R5
- MOVD R9, R0
- MOVD R5, RSP
-
- MOVW R0, ret+16(FP)
- RET
-
-nosave:
- // Running on a system stack, perhaps even without a g.
- // Having no g can happen during thread creation or thread teardown
- // (see needm/dropm on Solaris, for example).
- // This code is like the above sequence but without saving/restoring g
- // and without worrying about the stack moving out from under us
- // (because we're on a system stack, not a goroutine stack).
- // The above code could be used directly if already on a system stack,
- // but then the only path through this code would be a rare case on Solaris.
- // Using this code for all "already on system stack" calls exercises it more,
- // which should help keep it correct.
- MOVD RSP, R13
- SUB $16, R13
- MOVD R13, RSP
- MOVD $0, R4
- MOVD R4, 0(RSP) // Where above code stores g, in case someone looks during debugging.
- MOVD R2, 8(RSP) // Save original stack pointer.
- BL (R1)
- // Restore stack pointer.
- MOVD 8(RSP), R2
- MOVD R2, RSP
- MOVD R0, ret+16(FP)
- RET
-
-// cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
-// See cgocall.go for more details.
-TEXT ·cgocallback(SB),NOSPLIT,$24-24
- NO_LOCAL_POINTERS
-
- // Load g from thread-local storage.
- BL runtime·load_g(SB)
-
- // If g is nil, Go did not create the current thread.
- // Call needm to obtain one for temporary use.
- // In this case, we're running on the thread stack, so there's
- // lots of space, but the linker doesn't know. Hide the call from
- // the linker analysis by using an indirect call.
- CBZ g, needm
-
- MOVD g_m(g), R8
- MOVD R8, savedm-8(SP)
- B havem
-
-needm:
- MOVD g, savedm-8(SP) // g is zero, so is m.
- MOVD $runtime·needm(SB), R0
- BL (R0)
-
- // Set m->g0->sched.sp = SP, so that if a panic happens
- // during the function we are about to execute, it will
- // have a valid SP to run on the g0 stack.
- // The next few lines (after the havem label)
- // will save this SP onto the stack and then write
- // the same SP back to m->sched.sp. That seems redundant,
- // but if an unrecovered panic happens, unwindm will
- // restore the g->sched.sp from the stack location
- // and then systemstack will try to use it. If we don't set it here,
- // that restored SP will be uninitialized (typically 0) and
- // will not be usable.
- MOVD g_m(g), R8
- MOVD m_g0(R8), R3
- MOVD RSP, R0
- MOVD R0, (g_sched+gobuf_sp)(R3)
- MOVD R29, (g_sched+gobuf_bp)(R3)
-
-havem:
- // Now there's a valid m, and we're running on its m->g0.
- // Save current m->g0->sched.sp on stack and then set it to SP.
- // Save current sp in m->g0->sched.sp in preparation for
- // switch back to m->curg stack.
- // NOTE: unwindm knows that the saved g->sched.sp is at 16(RSP) aka savedsp-16(SP).
- // Beware that the frame size is actually 32+16.
- MOVD m_g0(R8), R3
- MOVD (g_sched+gobuf_sp)(R3), R4
- MOVD R4, savedsp-16(SP)
- MOVD RSP, R0
- MOVD R0, (g_sched+gobuf_sp)(R3)
-
- // Switch to m->curg stack and call runtime.cgocallbackg.
- // Because we are taking over the execution of m->curg
- // but *not* resuming what had been running, we need to
- // save that information (m->curg->sched) so we can restore it.
- // We can restore m->curg->sched.sp easily, because calling
- // runtime.cgocallbackg leaves SP unchanged upon return.
- // To save m->curg->sched.pc, we push it onto the curg stack and
- // open a frame the same size as cgocallback's g0 frame.
- // Once we switch to the curg stack, the pushed PC will appear
- // to be the return PC of cgocallback, so that the traceback
- // will seamlessly trace back into the earlier calls.
- MOVD m_curg(R8), g
- BL runtime·save_g(SB)
- MOVD (g_sched+gobuf_sp)(g), R4 // prepare stack as R4
- MOVD (g_sched+gobuf_pc)(g), R5
- MOVD R5, -48(R4)
- MOVD (g_sched+gobuf_bp)(g), R5
- MOVD R5, -56(R4)
- // Gather our arguments into registers.
- MOVD fn+0(FP), R1
- MOVD frame+8(FP), R2
- MOVD ctxt+16(FP), R3
- MOVD $-48(R4), R0 // maintain 16-byte SP alignment
- MOVD R0, RSP // switch stack
- MOVD R1, 8(RSP)
- MOVD R2, 16(RSP)
- MOVD R3, 24(RSP)
- MOVD $runtime·cgocallbackg(SB), R0
- CALL (R0) // indirect call to bypass nosplit check. We're on a different stack now.
-
- // Restore g->sched (== m->curg->sched) from saved values.
- MOVD 0(RSP), R5
- MOVD R5, (g_sched+gobuf_pc)(g)
- MOVD RSP, R4
- ADD $48, R4, R4
- MOVD R4, (g_sched+gobuf_sp)(g)
-
- // Switch back to m->g0's stack and restore m->g0->sched.sp.
- // (Unlike m->curg, the g0 goroutine never uses sched.pc,
- // so we do not have to restore it.)
- MOVD g_m(g), R8
- MOVD m_g0(R8), g
- BL runtime·save_g(SB)
- MOVD (g_sched+gobuf_sp)(g), R0
- MOVD R0, RSP
- MOVD savedsp-16(SP), R4
- MOVD R4, (g_sched+gobuf_sp)(g)
-
- // If the m on entry was nil, we called needm above to borrow an m
- // for the duration of the call. Since the call is over, return it with dropm.
- MOVD savedm-8(SP), R6
- CBNZ R6, droppedm
- MOVD $runtime·dropm(SB), R0
- BL (R0)
-droppedm:
-
- // Done!
- RET
-
-// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
-// Must obey the gcc calling convention.
-TEXT _cgo_topofstack(SB),NOSPLIT,$24
- // g (R28) and REGTMP (R27) might be clobbered by load_g. They
- // are callee-save in the gcc calling convention, so save them.
- MOVD R27, savedR27-8(SP)
- MOVD g, saveG-16(SP)
-
- BL runtime·load_g(SB)
- MOVD g_m(g), R0
- MOVD m_curg(R0), R0
- MOVD (g_stack+stack_hi)(R0), R0
-
- MOVD saveG-16(SP), g
- MOVD savedR28-8(SP), R27
- RET
-
-// void setg(G*); set g. for use by needm.
-TEXT runtime·setg(SB), NOSPLIT, $0-8
- MOVD gg+0(FP), g
- // This only happens if iscgo, so jump straight to save_g
- BL runtime·save_g(SB)
- RET
-
-// void setg_gcc(G*); set g called from gcc
-TEXT setg_gcc<>(SB),NOSPLIT,$8
- MOVD R0, g
- MOVD R27, savedR27-8(SP)
- BL runtime·save_g(SB)
- MOVD savedR27-8(SP), R27
- RET
-
-TEXT runtime·emptyfunc(SB),0,$0-0
- RET
-
-TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
- MOVD ZR, R0
- MOVD (R0), R0
- UNDEF
-
-TEXT runtime·return0(SB), NOSPLIT, $0
- MOVW $0, R0
- RET
-
-// The top-most function running on a goroutine
-// returns to goexit+PCQuantum.
-TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
- MOVD R0, R0 // NOP
- BL runtime·goexit1(SB) // does not return
-
-// This is called from .init_array and follows the platform, not Go, ABI.
-TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
- SUB $0x10, RSP
- MOVD R27, 8(RSP) // The access to global variables below implicitly uses R27, which is callee-save
- MOVD runtime·lastmoduledatap(SB), R1
- MOVD R0, moduledata_next(R1)
- MOVD R0, runtime·lastmoduledatap(SB)
- MOVD 8(RSP), R27
- ADD $0x10, RSP
- RET
-
-TEXT ·checkASM(SB),NOSPLIT,$0-1
- MOVW $1, R3
- MOVB R3, ret+0(FP)
- RET
-
-// gcWriteBarrier performs a heap pointer write and informs the GC.
-//
-// gcWriteBarrier does NOT follow the Go ABI. It takes two arguments:
-// - R2 is the destination of the write
-// - R3 is the value being written at R2
-// It clobbers condition codes.
-// It does not clobber any general-purpose registers,
-// but may clobber others (e.g., floating point registers)
-// The act of CALLing gcWriteBarrier will clobber R30 (LR).
-//
-// Defined as ABIInternal since the compiler generates ABIInternal
-// calls to it directly and it does not use the stack-based Go ABI.
-TEXT runtime·gcWriteBarrier<ABIInternal>(SB),NOSPLIT,$200
- // Save the registers clobbered by the fast path.
- STP (R0, R1), 184(RSP)
- MOVD g_m(g), R0
- MOVD m_p(R0), R0
- MOVD (p_wbBuf+wbBuf_next)(R0), R1
- // Increment wbBuf.next position.
- ADD $16, R1
- MOVD R1, (p_wbBuf+wbBuf_next)(R0)
- MOVD (p_wbBuf+wbBuf_end)(R0), R0
- CMP R1, R0
- // Record the write.
- MOVD R3, -16(R1) // Record value
- MOVD (R2), R0 // TODO: This turns bad writes into bad reads.
- MOVD R0, -8(R1) // Record *slot
- // Is the buffer full? (flags set in CMP above)
- BEQ flush
-ret:
- LDP 184(RSP), (R0, R1)
- // Do the write.
- MOVD R3, (R2)
- RET
-
-flush:
- // Save all general purpose registers since these could be
- // clobbered by wbBufFlush and were not saved by the caller.
- // R0 and R1 already saved
- STP (R2, R3), 1*8(RSP) // Also first and second arguments to wbBufFlush
- STP (R4, R5), 3*8(RSP)
- STP (R6, R7), 5*8(RSP)
- STP (R8, R9), 7*8(RSP)
- STP (R10, R11), 9*8(RSP)
- STP (R12, R13), 11*8(RSP)
- STP (R14, R15), 13*8(RSP)
- // R16, R17 may be clobbered by linker trampoline
- // R18 is unused.
- STP (R19, R20), 15*8(RSP)
- STP (R21, R22), 17*8(RSP)
- STP (R23, R24), 19*8(RSP)
- STP (R25, R26), 21*8(RSP)
- // R27 is temp register.
- // R28 is g.
- // R29 is frame pointer (unused).
- // R30 is LR, which was saved by the prologue.
- // R31 is SP.
-
- // This takes arguments R2 and R3.
- CALL runtime·wbBufFlush(SB)
- LDP 1*8(RSP), (R2, R3)
- LDP 3*8(RSP), (R4, R5)
- LDP 5*8(RSP), (R6, R7)
- LDP 7*8(RSP), (R8, R9)
- LDP 9*8(RSP), (R10, R11)
- LDP 11*8(RSP), (R12, R13)
- LDP 13*8(RSP), (R14, R15)
- LDP 15*8(RSP), (R19, R20)
- LDP 17*8(RSP), (R21, R22)
- LDP 19*8(RSP), (R23, R24)
- LDP 21*8(RSP), (R25, R26)
- JMP ret
-
-DATA debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
-GLOBL debugCallFrameTooLarge<>(SB), RODATA, $20 // Size duplicated below
-
-// debugCallV2 is the entry point for debugger-injected function
-// calls on running goroutines. It informs the runtime that a
-// debug call has been injected and creates a call frame for the
-// debugger to fill in.
-//
-// To inject a function call, a debugger should:
-// 1. Check that the goroutine is in state _Grunning and that
-// there are at least 288 bytes free on the stack.
-// 2. Set SP as SP-16.
-// 3. Store the current LR in (SP) (using the SP after step 2).
-// 4. Store the current PC in the LR register.
-// 5. Write the desired argument frame size at SP-16
-// 6. Save all machine registers (including flags and fpsimd registers)
-// so they can be restored later by the debugger.
-// 7. Set the PC to debugCallV2 and resume execution.
-//
-// If the goroutine is in state _Grunnable, then it's not generally
-// safe to inject a call because it may return out via other runtime
-// operations. Instead, the debugger should unwind the stack to find
-// the return to non-runtime code, add a temporary breakpoint there,
-// and inject the call once that breakpoint is hit.
-//
-// If the goroutine is in any other state, it's not safe to inject a call.
-//
-// This function communicates back to the debugger by setting R20 and
-// invoking BRK to raise a breakpoint signal. Note that the signal PC of
-// the signal triggered by the BRK instruction is the PC where the signal
-// is trapped, not the next PC, so to resume execution, the debugger needs
-// to set the signal PC to PC+4. See the comments in the implementation for
-// the protocol the debugger is expected to follow. InjectDebugCall in the
-// runtime tests demonstrates this protocol.
-//
-// The debugger must ensure that any pointers passed to the function
-// obey escape analysis requirements. Specifically, it must not pass
-// a stack pointer to an escaping argument. debugCallV2 cannot check
-// this invariant.
-//
-// This is ABIInternal because Go code injects its PC directly into new
-// goroutine stacks.
-TEXT runtime·debugCallV2<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-0
- STP (R29, R30), -280(RSP)
- SUB $272, RSP, RSP
- SUB $8, RSP, R29
- // Save all registers that may contain pointers so they can be
- // conservatively scanned.
- //
- // We can't do anything that might clobber any of these
- // registers before this.
- STP (R27, g), (30*8)(RSP)
- STP (R25, R26), (28*8)(RSP)
- STP (R23, R24), (26*8)(RSP)
- STP (R21, R22), (24*8)(RSP)
- STP (R19, R20), (22*8)(RSP)
- STP (R16, R17), (20*8)(RSP)
- STP (R14, R15), (18*8)(RSP)
- STP (R12, R13), (16*8)(RSP)
- STP (R10, R11), (14*8)(RSP)
- STP (R8, R9), (12*8)(RSP)
- STP (R6, R7), (10*8)(RSP)
- STP (R4, R5), (8*8)(RSP)
- STP (R2, R3), (6*8)(RSP)
- STP (R0, R1), (4*8)(RSP)
-
- // Perform a safe-point check.
- MOVD R30, 8(RSP) // Caller's PC
- CALL runtime·debugCallCheck(SB)
- MOVD 16(RSP), R0
- CBZ R0, good
-
- // The safety check failed. Put the reason string at the top
- // of the stack.
- MOVD R0, 8(RSP)
- MOVD 24(RSP), R0
- MOVD R0, 16(RSP)
-
- // Set R20 to 8 and invoke BRK. The debugger should get the
- // reason a call can't be injected from SP+8 and resume execution.
- MOVD $8, R20
- BREAK
- JMP restore
-
-good:
- // Registers are saved and it's safe to make a call.
- // Open up a call frame, moving the stack if necessary.
- //
- // Once the frame is allocated, this will set R20 to 0 and
- // invoke BRK. The debugger should write the argument
- // frame for the call at SP+8, set up argument registers,
- // set the LR as the signal PC + 4, set the PC to the function
- // to call, set R26 to point to the closure (if a closure call),
- // and resume execution.
- //
- // If the function returns, this will set R20 to 1 and invoke
- // BRK. The debugger can then inspect any return value saved
- // on the stack at SP+8 and in registers. To resume execution,
- // the debugger should restore the LR from (SP).
- //
- // If the function panics, this will set R20 to 2 and invoke BRK.
- // The interface{} value of the panic will be at SP+8. The debugger
- // can inspect the panic value and resume execution again.
-#define DEBUG_CALL_DISPATCH(NAME,MAXSIZE) \
- CMP $MAXSIZE, R0; \
- BGT 5(PC); \
- MOVD $NAME(SB), R0; \
- MOVD R0, 8(RSP); \
- CALL runtime·debugCallWrap(SB); \
- JMP restore
-
- MOVD 256(RSP), R0 // the argument frame size
- DEBUG_CALL_DISPATCH(debugCall32<>, 32)
- DEBUG_CALL_DISPATCH(debugCall64<>, 64)
- DEBUG_CALL_DISPATCH(debugCall128<>, 128)
- DEBUG_CALL_DISPATCH(debugCall256<>, 256)
- DEBUG_CALL_DISPATCH(debugCall512<>, 512)
- DEBUG_CALL_DISPATCH(debugCall1024<>, 1024)
- DEBUG_CALL_DISPATCH(debugCall2048<>, 2048)
- DEBUG_CALL_DISPATCH(debugCall4096<>, 4096)
- DEBUG_CALL_DISPATCH(debugCall8192<>, 8192)
- DEBUG_CALL_DISPATCH(debugCall16384<>, 16384)
- DEBUG_CALL_DISPATCH(debugCall32768<>, 32768)
- DEBUG_CALL_DISPATCH(debugCall65536<>, 65536)
- // The frame size is too large. Report the error.
- MOVD $debugCallFrameTooLarge<>(SB), R0
- MOVD R0, 8(RSP)
- MOVD $20, R0
- MOVD R0, 16(RSP) // length of debugCallFrameTooLarge string
- MOVD $8, R20
- BREAK
- JMP restore
-
-restore:
- // Calls and failures resume here.
- //
- // Set R20 to 16 and invoke BRK. The debugger should restore
- // all registers except for PC and RSP and resume execution.
- MOVD $16, R20
- BREAK
- // We must not modify flags after this point.
-
- // Restore pointer-containing registers, which may have been
- // modified from the debugger's copy by stack copying.
- LDP (30*8)(RSP), (R27, g)
- LDP (28*8)(RSP), (R25, R26)
- LDP (26*8)(RSP), (R23, R24)
- LDP (24*8)(RSP), (R21, R22)
- LDP (22*8)(RSP), (R19, R20)
- LDP (20*8)(RSP), (R16, R17)
- LDP (18*8)(RSP), (R14, R15)
- LDP (16*8)(RSP), (R12, R13)
- LDP (14*8)(RSP), (R10, R11)
- LDP (12*8)(RSP), (R8, R9)
- LDP (10*8)(RSP), (R6, R7)
- LDP (8*8)(RSP), (R4, R5)
- LDP (6*8)(RSP), (R2, R3)
- LDP (4*8)(RSP), (R0, R1)
-
- LDP -8(RSP), (R29, R27)
- ADD $288, RSP, RSP // Add 16 more bytes, see saveSigContext
- MOVD -16(RSP), R30 // restore old lr
- JMP (R27)
-
-// runtime.debugCallCheck assumes that functions defined with the
-// DEBUG_CALL_FN macro are safe points to inject calls.
-#define DEBUG_CALL_FN(NAME,MAXSIZE) \
-TEXT NAME(SB),WRAPPER,$MAXSIZE-0; \
- NO_LOCAL_POINTERS; \
- MOVD $0, R20; \
- BREAK; \
- MOVD $1, R20; \
- BREAK; \
- RET
-DEBUG_CALL_FN(debugCall32<>, 32)
-DEBUG_CALL_FN(debugCall64<>, 64)
-DEBUG_CALL_FN(debugCall128<>, 128)
-DEBUG_CALL_FN(debugCall256<>, 256)
-DEBUG_CALL_FN(debugCall512<>, 512)
-DEBUG_CALL_FN(debugCall1024<>, 1024)
-DEBUG_CALL_FN(debugCall2048<>, 2048)
-DEBUG_CALL_FN(debugCall4096<>, 4096)
-DEBUG_CALL_FN(debugCall8192<>, 8192)
-DEBUG_CALL_FN(debugCall16384<>, 16384)
-DEBUG_CALL_FN(debugCall32768<>, 32768)
-DEBUG_CALL_FN(debugCall65536<>, 65536)
-
-// func debugCallPanicked(val interface{})
-TEXT runtime·debugCallPanicked(SB),NOSPLIT,$16-16
- // Copy the panic value to the top of stack at SP+8.
- MOVD val_type+0(FP), R0
- MOVD R0, 8(RSP)
- MOVD val_data+8(FP), R0
- MOVD R0, 16(RSP)
- MOVD $2, R20
- BREAK
- RET
-
-// Note: these functions use a special calling convention to save generated code space.
-// Arguments are passed in registers, but the space for those arguments are allocated
-// in the caller's stack frame. These stubs write the args into that stack space and
-// then tail call to the corresponding runtime handler.
-// The tail call makes these stubs disappear in backtraces.
-//
-// Defined as ABIInternal since the compiler generates ABIInternal
-// calls to it directly and it does not use the stack-based Go ABI.
-TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
- JMP runtime·goPanicIndex<ABIInternal>(SB)
-TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
- JMP runtime·goPanicIndexU<ABIInternal>(SB)
-TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
- MOVD R1, R0
- MOVD R2, R1
- JMP runtime·goPanicSliceAlen<ABIInternal>(SB)
-TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVD R1, R0
- MOVD R2, R1
- JMP runtime·goPanicSliceAlenU<ABIInternal>(SB)
-TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
- MOVD R1, R0
- MOVD R2, R1
- JMP runtime·goPanicSliceAcap<ABIInternal>(SB)
-TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVD R1, R0
- MOVD R2, R1
- JMP runtime·goPanicSliceAcapU<ABIInternal>(SB)
-TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
- JMP runtime·goPanicSliceB<ABIInternal>(SB)
-TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
- JMP runtime·goPanicSliceBU<ABIInternal>(SB)
-TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
- MOVD R2, R0
- MOVD R3, R1
- JMP runtime·goPanicSlice3Alen<ABIInternal>(SB)
-TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVD R2, R0
- MOVD R3, R1
- JMP runtime·goPanicSlice3AlenU<ABIInternal>(SB)
-TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
- MOVD R2, R0
- MOVD R3, R1
- JMP runtime·goPanicSlice3Acap<ABIInternal>(SB)
-TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVD R2, R0
- MOVD R3, R1
- JMP runtime·goPanicSlice3AcapU<ABIInternal>(SB)
-TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
- MOVD R1, R0
- MOVD R2, R1
- JMP runtime·goPanicSlice3B<ABIInternal>(SB)
-TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
- MOVD R1, R0
- MOVD R2, R1
- JMP runtime·goPanicSlice3BU<ABIInternal>(SB)
-TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
- JMP runtime·goPanicSlice3C<ABIInternal>(SB)
-TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
- JMP runtime·goPanicSlice3CU<ABIInternal>(SB)
-TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
- MOVD R2, R0
- MOVD R3, R1
- JMP runtime·goPanicSliceConvert<ABIInternal>(SB)
diff --git a/contrib/go/_std_1.20/src/runtime/atomic_pointer.go b/contrib/go/_std_1.20/src/runtime/atomic_pointer.go
deleted file mode 100644
index 25e0e651b4..0000000000
--- a/contrib/go/_std_1.20/src/runtime/atomic_pointer.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2009 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 runtime
-
-import (
- "runtime/internal/atomic"
- "unsafe"
-)
-
-// These functions cannot have go:noescape annotations,
-// because while ptr does not escape, new does.
-// If new is marked as not escaping, the compiler will make incorrect
-// escape analysis decisions about the pointer value being stored.
-
-// atomicwb performs a write barrier before an atomic pointer write.
-// The caller should guard the call with "if writeBarrier.enabled".
-//
-//go:nosplit
-func atomicwb(ptr *unsafe.Pointer, new unsafe.Pointer) {
- slot := (*uintptr)(unsafe.Pointer(ptr))
- if !getg().m.p.ptr().wbBuf.putFast(*slot, uintptr(new)) {
- wbBufFlush(slot, uintptr(new))
- }
-}
-
-// atomicstorep performs *ptr = new atomically and invokes a write barrier.
-//
-//go:nosplit
-func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) {
- if writeBarrier.enabled {
- atomicwb((*unsafe.Pointer)(ptr), new)
- }
- atomic.StorepNoWB(noescape(ptr), new)
-}
-
-// atomic_storePointer is the implementation of runtime/internal/UnsafePointer.Store
-// (like StoreNoWB but with the write barrier).
-//
-//go:nosplit
-//go:linkname atomic_storePointer runtime/internal/atomic.storePointer
-func atomic_storePointer(ptr *unsafe.Pointer, new unsafe.Pointer) {
- atomicstorep(unsafe.Pointer(ptr), new)
-}
-
-// atomic_casPointer is the implementation of runtime/internal/UnsafePointer.CompareAndSwap
-// (like CompareAndSwapNoWB but with the write barrier).
-//
-//go:nosplit
-//go:linkname atomic_casPointer runtime/internal/atomic.casPointer
-func atomic_casPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
- if writeBarrier.enabled {
- atomicwb(ptr, new)
- }
- return atomic.Casp1(ptr, old, new)
-}
-
-// Like above, but implement in terms of sync/atomic's uintptr operations.
-// We cannot just call the runtime routines, because the race detector expects
-// to be able to intercept the sync/atomic forms but not the runtime forms.
-
-//go:linkname sync_atomic_StoreUintptr sync/atomic.StoreUintptr
-func sync_atomic_StoreUintptr(ptr *uintptr, new uintptr)
-
-//go:linkname sync_atomic_StorePointer sync/atomic.StorePointer
-//go:nosplit
-func sync_atomic_StorePointer(ptr *unsafe.Pointer, new unsafe.Pointer) {
- if writeBarrier.enabled {
- atomicwb(ptr, new)
- }
- sync_atomic_StoreUintptr((*uintptr)(unsafe.Pointer(ptr)), uintptr(new))
-}
-
-//go:linkname sync_atomic_SwapUintptr sync/atomic.SwapUintptr
-func sync_atomic_SwapUintptr(ptr *uintptr, new uintptr) uintptr
-
-//go:linkname sync_atomic_SwapPointer sync/atomic.SwapPointer
-//go:nosplit
-func sync_atomic_SwapPointer(ptr *unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer {
- if writeBarrier.enabled {
- atomicwb(ptr, new)
- }
- old := unsafe.Pointer(sync_atomic_SwapUintptr((*uintptr)(noescape(unsafe.Pointer(ptr))), uintptr(new)))
- return old
-}
-
-//go:linkname sync_atomic_CompareAndSwapUintptr sync/atomic.CompareAndSwapUintptr
-func sync_atomic_CompareAndSwapUintptr(ptr *uintptr, old, new uintptr) bool
-
-//go:linkname sync_atomic_CompareAndSwapPointer sync/atomic.CompareAndSwapPointer
-//go:nosplit
-func sync_atomic_CompareAndSwapPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
- if writeBarrier.enabled {
- atomicwb(ptr, new)
- }
- return sync_atomic_CompareAndSwapUintptr((*uintptr)(noescape(unsafe.Pointer(ptr))), uintptr(old), uintptr(new))
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo.go b/contrib/go/_std_1.20/src/runtime/cgo.go
deleted file mode 100644
index d90468240d..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2014 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 runtime
-
-import "unsafe"
-
-//go:cgo_export_static main
-
-// Filled in by runtime/cgo when linked into binary.
-
-//go:linkname _cgo_init _cgo_init
-//go:linkname _cgo_thread_start _cgo_thread_start
-//go:linkname _cgo_sys_thread_create _cgo_sys_thread_create
-//go:linkname _cgo_notify_runtime_init_done _cgo_notify_runtime_init_done
-//go:linkname _cgo_callers _cgo_callers
-//go:linkname _cgo_set_context_function _cgo_set_context_function
-//go:linkname _cgo_yield _cgo_yield
-
-var (
- _cgo_init unsafe.Pointer
- _cgo_thread_start unsafe.Pointer
- _cgo_sys_thread_create unsafe.Pointer
- _cgo_notify_runtime_init_done unsafe.Pointer
- _cgo_callers unsafe.Pointer
- _cgo_set_context_function unsafe.Pointer
- _cgo_yield unsafe.Pointer
-)
-
-// iscgo is set to true by the runtime/cgo package
-var iscgo bool
-
-// cgoHasExtraM is set on startup when an extra M is created for cgo.
-// The extra M must be created before any C/C++ code calls cgocallback.
-var cgoHasExtraM bool
-
-// cgoUse is called by cgo-generated code (using go:linkname to get at
-// an unexported name). The calls serve two purposes:
-// 1) they are opaque to escape analysis, so the argument is considered to
-// escape to the heap.
-// 2) they keep the argument alive until the call site; the call is emitted after
-// the end of the (presumed) use of the argument by C.
-// cgoUse should not actually be called (see cgoAlwaysFalse).
-func cgoUse(any) { throw("cgoUse should not be called") }
-
-// cgoAlwaysFalse is a boolean value that is always false.
-// The cgo-generated code says if cgoAlwaysFalse { cgoUse(p) }.
-// The compiler cannot see that cgoAlwaysFalse is always false,
-// so it emits the test and keeps the call, giving the desired
-// escape analysis result. The test is cheaper than the call.
-var cgoAlwaysFalse bool
-
-var cgo_yield = &_cgo_yield
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/asm_amd64.s b/contrib/go/_std_1.20/src/runtime/cgo/asm_amd64.s
deleted file mode 100644
index 386299c548..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/asm_amd64.s
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2009 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.
-
-#include "textflag.h"
-#include "abi_amd64.h"
-
-// Called by C code generated by cmd/cgo.
-// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
-// Saves C callee-saved registers and calls cgocallback with three arguments.
-// fn is the PC of a func(a unsafe.Pointer) function.
-// This signature is known to SWIG, so we can't change it.
-TEXT crosscall2(SB),NOSPLIT,$0-0
- PUSH_REGS_HOST_TO_ABI0()
-
- // Make room for arguments to cgocallback.
- ADJSP $0x18
-#ifndef GOOS_windows
- MOVQ DI, 0x0(SP) /* fn */
- MOVQ SI, 0x8(SP) /* arg */
- // Skip n in DX.
- MOVQ CX, 0x10(SP) /* ctxt */
-#else
- MOVQ CX, 0x0(SP) /* fn */
- MOVQ DX, 0x8(SP) /* arg */
- // Skip n in R8.
- MOVQ R9, 0x10(SP) /* ctxt */
-#endif
-
- CALL runtime·cgocallback(SB)
-
- ADJSP $-0x18
- POP_REGS_HOST_TO_ABI0()
- RET
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/asm_arm64.s b/contrib/go/_std_1.20/src/runtime/cgo/asm_arm64.s
deleted file mode 100644
index e808dedcfc..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/asm_arm64.s
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2015 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.
-
-#include "textflag.h"
-#include "abi_arm64.h"
-
-// Called by C code generated by cmd/cgo.
-// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
-// Saves C callee-saved registers and calls cgocallback with three arguments.
-// fn is the PC of a func(a unsafe.Pointer) function.
-TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
- /*
- * We still need to save all callee save register as before, and then
- * push 3 args for fn (R0, R1, R3), skipping R2.
- * Also note that at procedure entry in gc world, 8(RSP) will be the
- * first arg.
- */
- SUB $(8*24), RSP
- STP (R0, R1), (8*1)(RSP)
- MOVD R3, (8*3)(RSP)
-
- SAVE_R19_TO_R28(8*4)
- SAVE_F8_TO_F15(8*14)
- STP (R29, R30), (8*22)(RSP)
-
-
- // Initialize Go ABI environment
- BL runtime·load_g(SB)
- BL runtime·cgocallback(SB)
-
- RESTORE_R19_TO_R28(8*4)
- RESTORE_F8_TO_F15(8*14)
- LDP (8*22)(RSP), (R29, R30)
-
- ADD $(8*24), RSP
- RET
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/callbacks.go b/contrib/go/_std_1.20/src/runtime/cgo/callbacks.go
deleted file mode 100644
index e7c8ef3e07..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/callbacks.go
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2011 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 cgo
-
-import "unsafe"
-
-// These utility functions are available to be called from code
-// compiled with gcc via crosscall2.
-
-// The declaration of crosscall2 is:
-// void crosscall2(void (*fn)(void *), void *, int);
-//
-// We need to export the symbol crosscall2 in order to support
-// callbacks from shared libraries. This applies regardless of
-// linking mode.
-//
-// Compatibility note: SWIG uses crosscall2 in exactly one situation:
-// to call _cgo_panic using the pattern shown below. We need to keep
-// that pattern working. In particular, crosscall2 actually takes four
-// arguments, but it works to call it with three arguments when
-// calling _cgo_panic.
-//
-//go:cgo_export_static crosscall2
-//go:cgo_export_dynamic crosscall2
-
-// Panic. The argument is converted into a Go string.
-
-// Call like this in code compiled with gcc:
-// struct { const char *p; } a;
-// a.p = /* string to pass to panic */;
-// crosscall2(_cgo_panic, &a, sizeof a);
-// /* The function call will not return. */
-
-// TODO: We should export a regular C function to panic, change SWIG
-// to use that instead of the above pattern, and then we can drop
-// backwards-compatibility from crosscall2 and stop exporting it.
-
-//go:linkname _runtime_cgo_panic_internal runtime._cgo_panic_internal
-func _runtime_cgo_panic_internal(p *byte)
-
-//go:linkname _cgo_panic _cgo_panic
-//go:cgo_export_static _cgo_panic
-//go:cgo_export_dynamic _cgo_panic
-func _cgo_panic(a *struct{ cstr *byte }) {
- _runtime_cgo_panic_internal(a.cstr)
-}
-
-//go:cgo_import_static x_cgo_init
-//go:linkname x_cgo_init x_cgo_init
-//go:linkname _cgo_init _cgo_init
-var x_cgo_init byte
-var _cgo_init = &x_cgo_init
-
-//go:cgo_import_static x_cgo_thread_start
-//go:linkname x_cgo_thread_start x_cgo_thread_start
-//go:linkname _cgo_thread_start _cgo_thread_start
-var x_cgo_thread_start byte
-var _cgo_thread_start = &x_cgo_thread_start
-
-// Creates a new system thread without updating any Go state.
-//
-// This method is invoked during shared library loading to create a new OS
-// thread to perform the runtime initialization. This method is similar to
-// _cgo_sys_thread_start except that it doesn't update any Go state.
-
-//go:cgo_import_static x_cgo_sys_thread_create
-//go:linkname x_cgo_sys_thread_create x_cgo_sys_thread_create
-//go:linkname _cgo_sys_thread_create _cgo_sys_thread_create
-var x_cgo_sys_thread_create byte
-var _cgo_sys_thread_create = &x_cgo_sys_thread_create
-
-// Notifies that the runtime has been initialized.
-//
-// We currently block at every CGO entry point (via _cgo_wait_runtime_init_done)
-// to ensure that the runtime has been initialized before the CGO call is
-// executed. This is necessary for shared libraries where we kickoff runtime
-// initialization in a separate thread and return without waiting for this
-// thread to complete the init.
-
-//go:cgo_import_static x_cgo_notify_runtime_init_done
-//go:linkname x_cgo_notify_runtime_init_done x_cgo_notify_runtime_init_done
-//go:linkname _cgo_notify_runtime_init_done _cgo_notify_runtime_init_done
-var x_cgo_notify_runtime_init_done byte
-var _cgo_notify_runtime_init_done = &x_cgo_notify_runtime_init_done
-
-// Sets the traceback context function. See runtime.SetCgoTraceback.
-
-//go:cgo_import_static x_cgo_set_context_function
-//go:linkname x_cgo_set_context_function x_cgo_set_context_function
-//go:linkname _cgo_set_context_function _cgo_set_context_function
-var x_cgo_set_context_function byte
-var _cgo_set_context_function = &x_cgo_set_context_function
-
-// Calls a libc function to execute background work injected via libc
-// interceptors, such as processing pending signals under the thread
-// sanitizer.
-//
-// Left as a nil pointer if no libc interceptors are expected.
-
-//go:cgo_import_static _cgo_yield
-//go:linkname _cgo_yield _cgo_yield
-var _cgo_yield unsafe.Pointer
-
-//go:cgo_export_static _cgo_topofstack
-//go:cgo_export_dynamic _cgo_topofstack
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/cgo.go b/contrib/go/_std_1.20/src/runtime/cgo/cgo.go
deleted file mode 100644
index b8473e532d..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/cgo.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2010 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 cgo contains runtime support for code generated
-by the cgo tool. See the documentation for the cgo command
-for details on using cgo.
-*/
-package cgo
-
-/*
-
-#cgo darwin,!arm64 LDFLAGS: -lpthread
-#cgo darwin,arm64 LDFLAGS: -framework CoreFoundation
-#cgo dragonfly LDFLAGS: -lpthread
-#cgo freebsd LDFLAGS: -lpthread
-#cgo android LDFLAGS: -llog
-#cgo !android,linux LDFLAGS: -lpthread
-#cgo netbsd LDFLAGS: -lpthread
-#cgo openbsd LDFLAGS: -lpthread
-#cgo aix LDFLAGS: -Wl,-berok
-#cgo solaris LDFLAGS: -lxnet
-#cgo solaris LDFLAGS: -lsocket
-
-// We use -fno-stack-protector because internal linking won't find
-// the support functions. See issues #52919 and #54313.
-#cgo CFLAGS: -Wall -Werror -fno-stack-protector
-
-#cgo solaris CPPFLAGS: -D_POSIX_PTHREAD_SEMANTICS
-
-*/
-import "C"
-
-import "runtime/internal/sys"
-
-// Incomplete is used specifically for the semantics of incomplete C types.
-type Incomplete struct {
- _ sys.NotInHeap
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_context.c b/contrib/go/_std_1.20/src/runtime/cgo/gcc_context.c
deleted file mode 100644
index 5fc0abb8bc..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_context.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2016 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.
-
-// +build cgo
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris windows
-
-#include "libcgo.h"
-
-// Releases the cgo traceback context.
-void _cgo_release_context(uintptr_t ctxt) {
- void (*pfn)(struct context_arg*);
-
- pfn = _cgo_get_context_function();
- if (ctxt != 0 && pfn != nil) {
- struct context_arg arg;
-
- arg.Context = ctxt;
- (*pfn)(&arg);
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_fatalf.c b/contrib/go/_std_1.20/src/runtime/cgo/gcc_fatalf.c
deleted file mode 100644
index 597e750f12..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_fatalf.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2014 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.
-
-// +build aix !android,linux freebsd
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "libcgo.h"
-
-void
-fatalf(const char* format, ...)
-{
- va_list ap;
-
- fprintf(stderr, "runtime/cgo: ");
- va_start(ap, format);
- vfprintf(stderr, format, ap);
- va_end(ap);
- fprintf(stderr, "\n");
- abort();
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_libinit.c b/contrib/go/_std_1.20/src/runtime/cgo/gcc_libinit.c
deleted file mode 100644
index 3304d95fdf..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_libinit.c
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2015 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.
-
-// +build cgo
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
-
-#include <pthread.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h> // strerror
-#include <time.h>
-#include "libcgo.h"
-#include "libcgo_unix.h"
-
-static pthread_cond_t runtime_init_cond = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t runtime_init_mu = PTHREAD_MUTEX_INITIALIZER;
-static int runtime_init_done;
-
-// The context function, used when tracing back C calls into Go.
-static void (*cgo_context_function)(struct context_arg*);
-
-void
-x_cgo_sys_thread_create(void* (*func)(void*), void* arg) {
- pthread_t p;
- int err = _cgo_try_pthread_create(&p, NULL, func, arg);
- if (err != 0) {
- fprintf(stderr, "pthread_create failed: %s", strerror(err));
- abort();
- }
-}
-
-uintptr_t
-_cgo_wait_runtime_init_done(void) {
- void (*pfn)(struct context_arg*);
-
- pthread_mutex_lock(&runtime_init_mu);
- while (runtime_init_done == 0) {
- pthread_cond_wait(&runtime_init_cond, &runtime_init_mu);
- }
-
- // TODO(iant): For the case of a new C thread calling into Go, such
- // as when using -buildmode=c-archive, we know that Go runtime
- // initialization is complete but we do not know that all Go init
- // functions have been run. We should not fetch cgo_context_function
- // until they have been, because that is where a call to
- // SetCgoTraceback is likely to occur. We are going to wait for Go
- // initialization to be complete anyhow, later, by waiting for
- // main_init_done to be closed in cgocallbackg1. We should wait here
- // instead. See also issue #15943.
- pfn = cgo_context_function;
-
- pthread_mutex_unlock(&runtime_init_mu);
- if (pfn != nil) {
- struct context_arg arg;
-
- arg.Context = 0;
- (*pfn)(&arg);
- return arg.Context;
- }
- return 0;
-}
-
-void
-x_cgo_notify_runtime_init_done(void* dummy __attribute__ ((unused))) {
- pthread_mutex_lock(&runtime_init_mu);
- runtime_init_done = 1;
- pthread_cond_broadcast(&runtime_init_cond);
- pthread_mutex_unlock(&runtime_init_mu);
-}
-
-// Sets the context function to call to record the traceback context
-// when calling a Go function from C code. Called from runtime.SetCgoTraceback.
-void x_cgo_set_context_function(void (*context)(struct context_arg*)) {
- pthread_mutex_lock(&runtime_init_mu);
- cgo_context_function = context;
- pthread_mutex_unlock(&runtime_init_mu);
-}
-
-// Gets the context function.
-void (*(_cgo_get_context_function(void)))(struct context_arg*) {
- void (*ret)(struct context_arg*);
-
- pthread_mutex_lock(&runtime_init_mu);
- ret = cgo_context_function;
- pthread_mutex_unlock(&runtime_init_mu);
- return ret;
-}
-
-// _cgo_try_pthread_create retries pthread_create if it fails with
-// EAGAIN.
-int
-_cgo_try_pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*pfn)(void*), void* arg) {
- int tries;
- int err;
- struct timespec ts;
-
- for (tries = 0; tries < 20; tries++) {
- err = pthread_create(thread, attr, pfn, arg);
- if (err == 0) {
- pthread_detach(*thread);
- return 0;
- }
- if (err != EAGAIN) {
- return err;
- }
- ts.tv_sec = 0;
- ts.tv_nsec = (tries + 1) * 1000 * 1000; // Milliseconds.
- nanosleep(&ts, nil);
- }
- return EAGAIN;
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_mmap.c b/contrib/go/_std_1.20/src/runtime/cgo/gcc_mmap.c
deleted file mode 100644
index 83d857f0d1..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_mmap.c
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2015 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.
-
-// +build linux,amd64 linux,arm64 linux,ppc64le freebsd,amd64
-
-#include <errno.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-
-#include "libcgo.h"
-
-uintptr_t
-x_cgo_mmap(void *addr, uintptr_t length, int32_t prot, int32_t flags, int32_t fd, uint32_t offset) {
- void *p;
-
- _cgo_tsan_acquire();
- p = mmap(addr, length, prot, flags, fd, offset);
- _cgo_tsan_release();
- if (p == MAP_FAILED) {
- /* This is what the Go code expects on failure. */
- return (uintptr_t)errno;
- }
- return (uintptr_t)p;
-}
-
-void
-x_cgo_munmap(void *addr, uintptr_t length) {
- int r;
-
- _cgo_tsan_acquire();
- r = munmap(addr, length);
- _cgo_tsan_release();
- if (r < 0) {
- /* The Go runtime is not prepared for munmap to fail. */
- abort();
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_setenv.c b/contrib/go/_std_1.20/src/runtime/cgo/gcc_setenv.c
deleted file mode 100644
index d4f798357a..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_setenv.c
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2011 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.
-
-// +build cgo
-// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
-
-#include "libcgo.h"
-
-#include <stdlib.h>
-
-/* Stub for calling setenv */
-void
-x_cgo_setenv(char **arg)
-{
- _cgo_tsan_acquire();
- setenv(arg[0], arg[1], 1);
- _cgo_tsan_release();
-}
-
-/* Stub for calling unsetenv */
-void
-x_cgo_unsetenv(char **arg)
-{
- _cgo_tsan_acquire();
- unsetenv(arg[0]);
- _cgo_tsan_release();
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_sigaction.c b/contrib/go/_std_1.20/src/runtime/cgo/gcc_sigaction.c
deleted file mode 100644
index fcf1e50740..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_sigaction.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2016 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.
-
-// +build linux,amd64 linux,arm64 linux,ppc64le
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-#include <signal.h>
-
-#include "libcgo.h"
-
-// go_sigaction_t is a C version of the sigactiont struct from
-// defs_linux_amd64.go. This definition — and its conversion to and from struct
-// sigaction — are specific to linux/amd64.
-typedef struct {
- uintptr_t handler;
- uint64_t flags;
- uintptr_t restorer;
- uint64_t mask;
-} go_sigaction_t;
-
-// SA_RESTORER is part of the kernel interface.
-// This is Linux i386/amd64 specific.
-#ifndef SA_RESTORER
-#define SA_RESTORER 0x4000000
-#endif
-
-int32_t
-x_cgo_sigaction(intptr_t signum, const go_sigaction_t *goact, go_sigaction_t *oldgoact) {
- int32_t ret;
- struct sigaction act;
- struct sigaction oldact;
- size_t i;
-
- _cgo_tsan_acquire();
-
- memset(&act, 0, sizeof act);
- memset(&oldact, 0, sizeof oldact);
-
- if (goact) {
- if (goact->flags & SA_SIGINFO) {
- act.sa_sigaction = (void(*)(int, siginfo_t*, void*))(goact->handler);
- } else {
- act.sa_handler = (void(*)(int))(goact->handler);
- }
- sigemptyset(&act.sa_mask);
- for (i = 0; i < 8 * sizeof(goact->mask); i++) {
- if (goact->mask & ((uint64_t)(1)<<i)) {
- sigaddset(&act.sa_mask, (int)(i+1));
- }
- }
- act.sa_flags = (int)(goact->flags & ~(uint64_t)SA_RESTORER);
- }
-
- ret = sigaction((int)signum, goact ? &act : NULL, oldgoact ? &oldact : NULL);
- if (ret == -1) {
- // runtime.rt_sigaction expects _cgo_sigaction to return errno on error.
- _cgo_tsan_release();
- return errno;
- }
-
- if (oldgoact) {
- if (oldact.sa_flags & SA_SIGINFO) {
- oldgoact->handler = (uintptr_t)(oldact.sa_sigaction);
- } else {
- oldgoact->handler = (uintptr_t)(oldact.sa_handler);
- }
- oldgoact->mask = 0;
- for (i = 0; i < 8 * sizeof(oldgoact->mask); i++) {
- if (sigismember(&oldact.sa_mask, (int)(i+1)) == 1) {
- oldgoact->mask |= (uint64_t)(1)<<i;
- }
- }
- oldgoact->flags = (uint64_t)oldact.sa_flags;
- }
-
- _cgo_tsan_release();
- return ret;
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_traceback.c b/contrib/go/_std_1.20/src/runtime/cgo/gcc_traceback.c
deleted file mode 100644
index 6e9470c43c..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_traceback.c
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2016 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.
-
-// +build cgo,darwin cgo,linux
-
-#include <stdint.h>
-#include "libcgo.h"
-
-#ifndef __has_feature
-#define __has_feature(x) 0
-#endif
-
-#if __has_feature(memory_sanitizer)
-#include <sanitizer/msan_interface.h>
-#endif
-
-// Call the user's traceback function and then call sigtramp.
-// The runtime signal handler will jump to this code.
-// We do it this way so that the user's traceback function will be called
-// by a C function with proper unwind info.
-void
-x_cgo_callers(uintptr_t sig, void *info, void *context, void (*cgoTraceback)(struct cgoTracebackArg*), uintptr_t* cgoCallers, void (*sigtramp)(uintptr_t, void*, void*)) {
- struct cgoTracebackArg arg;
-
- arg.Context = 0;
- arg.SigContext = (uintptr_t)(context);
- arg.Buf = cgoCallers;
- arg.Max = 32; // must match len(runtime.cgoCallers)
-
-#if __has_feature(memory_sanitizer)
- // This function is called directly from the signal handler.
- // The arguments are passed in registers, so whether msan
- // considers cgoCallers to be initialized depends on whether
- // it considers the appropriate register to be initialized.
- // That can cause false reports in rare cases.
- // Explicitly unpoison the memory to avoid that.
- // See issue #47543 for more details.
- __msan_unpoison(&arg, sizeof arg);
-#endif
-
- (*cgoTraceback)(&arg);
- sigtramp(sig, info, context);
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/handle.go b/contrib/go/_std_1.20/src/runtime/cgo/handle.go
deleted file mode 100644
index d711900d79..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/handle.go
+++ /dev/null
@@ -1,144 +0,0 @@
-// 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 cgo
-
-import (
- "sync"
- "sync/atomic"
-)
-
-// Handle provides a way to pass values that contain Go pointers
-// (pointers to memory allocated by Go) between Go and C without
-// breaking the cgo pointer passing rules. A Handle is an integer
-// value that can represent any Go value. A Handle can be passed
-// through C and back to Go, and Go code can use the Handle to
-// retrieve the original Go value.
-//
-// The underlying type of Handle is guaranteed to fit in an integer type
-// that is large enough to hold the bit pattern of any pointer. The zero
-// value of a Handle is not valid, and thus is safe to use as a sentinel
-// in C APIs.
-//
-// For instance, on the Go side:
-//
-// package main
-//
-// /*
-// #include <stdint.h> // for uintptr_t
-//
-// extern void MyGoPrint(uintptr_t handle);
-// void myprint(uintptr_t handle);
-// */
-// import "C"
-// import "runtime/cgo"
-//
-// //export MyGoPrint
-// func MyGoPrint(handle C.uintptr_t) {
-// h := cgo.Handle(handle)
-// val := h.Value().(string)
-// println(val)
-// h.Delete()
-// }
-//
-// func main() {
-// val := "hello Go"
-// C.myprint(C.uintptr_t(cgo.NewHandle(val)))
-// // Output: hello Go
-// }
-//
-// and on the C side:
-//
-// #include <stdint.h> // for uintptr_t
-//
-// // A Go function
-// extern void MyGoPrint(uintptr_t handle);
-//
-// // A C function
-// void myprint(uintptr_t handle) {
-// MyGoPrint(handle);
-// }
-//
-// Some C functions accept a void* argument that points to an arbitrary
-// data value supplied by the caller. It is not safe to coerce a cgo.Handle
-// (an integer) to a Go unsafe.Pointer, but instead we can pass the address
-// of the cgo.Handle to the void* parameter, as in this variant of the
-// previous example:
-//
-// package main
-//
-// /*
-// extern void MyGoPrint(void *context);
-// static inline void myprint(void *context) {
-// MyGoPrint(context);
-// }
-// */
-// import "C"
-// import (
-// "runtime/cgo"
-// "unsafe"
-// )
-//
-// //export MyGoPrint
-// func MyGoPrint(context unsafe.Pointer) {
-// h := *(*cgo.Handle)(context)
-// val := h.Value().(string)
-// println(val)
-// h.Delete()
-// }
-//
-// func main() {
-// val := "hello Go"
-// h := cgo.NewHandle(val)
-// C.myprint(unsafe.Pointer(&h))
-// // Output: hello Go
-// }
-type Handle uintptr
-
-// NewHandle returns a handle for a given value.
-//
-// The handle is valid until the program calls Delete on it. The handle
-// uses resources, and this package assumes that C code may hold on to
-// the handle, so a program must explicitly call Delete when the handle
-// is no longer needed.
-//
-// The intended use is to pass the returned handle to C code, which
-// passes it back to Go, which calls Value.
-func NewHandle(v any) Handle {
- h := atomic.AddUintptr(&handleIdx, 1)
- if h == 0 {
- panic("runtime/cgo: ran out of handle space")
- }
-
- handles.Store(h, v)
- return Handle(h)
-}
-
-// Value returns the associated Go value for a valid handle.
-//
-// The method panics if the handle is invalid.
-func (h Handle) Value() any {
- v, ok := handles.Load(uintptr(h))
- if !ok {
- panic("runtime/cgo: misuse of an invalid Handle")
- }
- return v
-}
-
-// Delete invalidates a handle. This method should only be called once
-// the program no longer needs to pass the handle to C and the C code
-// no longer has a copy of the handle value.
-//
-// The method panics if the handle is invalid.
-func (h Handle) Delete() {
- _, ok := handles.LoadAndDelete(uintptr(h))
- if !ok {
- panic("runtime/cgo: misuse of an invalid Handle")
- }
-}
-
-var (
- handles = sync.Map{} // map[Handle]interface{}
- handleIdx uintptr // atomic
-)
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/libcgo.h b/contrib/go/_std_1.20/src/runtime/cgo/libcgo.h
deleted file mode 100644
index af4960e7e9..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/libcgo.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2009 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.
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#undef nil
-#define nil ((void*)0)
-#define nelem(x) (sizeof(x)/sizeof((x)[0]))
-
-typedef uint32_t uint32;
-typedef uint64_t uint64;
-typedef uintptr_t uintptr;
-
-/*
- * The beginning of the per-goroutine structure,
- * as defined in ../pkg/runtime/runtime.h.
- * Just enough to edit these two fields.
- */
-typedef struct G G;
-struct G
-{
- uintptr stacklo;
- uintptr stackhi;
-};
-
-/*
- * Arguments to the _cgo_thread_start call.
- * Also known to ../pkg/runtime/runtime.h.
- */
-typedef struct ThreadStart ThreadStart;
-struct ThreadStart
-{
- G *g;
- uintptr *tls;
- void (*fn)(void);
-};
-
-/*
- * Called by 5c/6c/8c world.
- * Makes a local copy of the ThreadStart and
- * calls _cgo_sys_thread_start(ts).
- */
-extern void (*_cgo_thread_start)(ThreadStart *ts);
-
-/*
- * Creates a new operating system thread without updating any Go state
- * (OS dependent).
- */
-extern void (*_cgo_sys_thread_create)(void* (*func)(void*), void* arg);
-
-/*
- * Creates the new operating system thread (OS, arch dependent).
- */
-void _cgo_sys_thread_start(ThreadStart *ts);
-
-/*
- * Waits for the Go runtime to be initialized (OS dependent).
- * If runtime.SetCgoTraceback is used to set a context function,
- * calls the context function and returns the context value.
- */
-uintptr_t _cgo_wait_runtime_init_done(void);
-
-/*
- * Call fn in the 6c world.
- */
-void crosscall_amd64(void (*fn)(void), void (*setg_gcc)(void*), void *g);
-
-/*
- * Call fn in the 8c world.
- */
-void crosscall_386(void (*fn)(void));
-
-/*
- * Prints error then calls abort. For linux and android.
- */
-void fatalf(const char* format, ...);
-
-/*
- * Registers the current mach thread port for EXC_BAD_ACCESS processing.
- */
-void darwin_arm_init_thread_exception_port(void);
-
-/*
- * Starts a mach message server processing EXC_BAD_ACCESS.
- */
-void darwin_arm_init_mach_exception_handler(void);
-
-/*
- * The cgo context function. See runtime.SetCgoTraceback.
- */
-struct context_arg {
- uintptr_t Context;
-};
-extern void (*(_cgo_get_context_function(void)))(struct context_arg*);
-
-/*
- * The argument for the cgo traceback callback. See runtime.SetCgoTraceback.
- */
-struct cgoTracebackArg {
- uintptr_t Context;
- uintptr_t SigContext;
- uintptr_t* Buf;
- uintptr_t Max;
-};
-
-/*
- * TSAN support. This is only useful when building with
- * CGO_CFLAGS="-fsanitize=thread" CGO_LDFLAGS="-fsanitize=thread" go install
- */
-#undef CGO_TSAN
-#if defined(__has_feature)
-# if __has_feature(thread_sanitizer)
-# define CGO_TSAN
-# endif
-#elif defined(__SANITIZE_THREAD__)
-# define CGO_TSAN
-#endif
-
-#ifdef CGO_TSAN
-
-// These must match the definitions in yesTsanProlog in cmd/cgo/out.go.
-// In general we should call _cgo_tsan_acquire when we enter C code,
-// and call _cgo_tsan_release when we return to Go code.
-// This is only necessary when calling code that might be instrumented
-// by TSAN, which mostly means system library calls that TSAN intercepts.
-// See the comment in cmd/cgo/out.go for more details.
-
-long long _cgo_sync __attribute__ ((common));
-
-extern void __tsan_acquire(void*);
-extern void __tsan_release(void*);
-
-__attribute__ ((unused))
-static void _cgo_tsan_acquire() {
- __tsan_acquire(&_cgo_sync);
-}
-
-__attribute__ ((unused))
-static void _cgo_tsan_release() {
- __tsan_release(&_cgo_sync);
-}
-
-#else // !defined(CGO_TSAN)
-
-#define _cgo_tsan_acquire()
-#define _cgo_tsan_release()
-
-#endif // !defined(CGO_TSAN)
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/linux_syscall.c b/contrib/go/_std_1.20/src/runtime/cgo/linux_syscall.c
deleted file mode 100644
index 59761c8b40..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/linux_syscall.c
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build linux
-
-#ifndef _GNU_SOURCE // setres[ug]id() API.
-#define _GNU_SOURCE
-#endif
-
-#include <grp.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>
-#include "libcgo.h"
-
-/*
- * Assumed POSIX compliant libc system call wrappers. For linux, the
- * glibc/nptl/setxid mechanism ensures that POSIX semantics are
- * honored for all pthreads (by default), and this in turn with cgo
- * ensures that all Go threads launched with cgo are kept in sync for
- * these function calls.
- */
-
-// argset_t matches runtime/cgocall.go:argset.
-typedef struct {
- uintptr_t* args;
- uintptr_t retval;
-} argset_t;
-
-// libc backed posix-compliant syscalls.
-
-#define SET_RETVAL(fn) \
- uintptr_t ret = (uintptr_t) fn ; \
- if (ret == (uintptr_t) -1) { \
- x->retval = (uintptr_t) errno; \
- } else \
- x->retval = ret
-
-void
-_cgo_libc_setegid(argset_t* x) {
- SET_RETVAL(setegid((gid_t) x->args[0]));
-}
-
-void
-_cgo_libc_seteuid(argset_t* x) {
- SET_RETVAL(seteuid((uid_t) x->args[0]));
-}
-
-void
-_cgo_libc_setgid(argset_t* x) {
- SET_RETVAL(setgid((gid_t) x->args[0]));
-}
-
-void
-_cgo_libc_setgroups(argset_t* x) {
- SET_RETVAL(setgroups((size_t) x->args[0], (const gid_t *) x->args[1]));
-}
-
-void
-_cgo_libc_setregid(argset_t* x) {
- SET_RETVAL(setregid((gid_t) x->args[0], (gid_t) x->args[1]));
-}
-
-void
-_cgo_libc_setresgid(argset_t* x) {
- SET_RETVAL(setresgid((gid_t) x->args[0], (gid_t) x->args[1],
- (gid_t) x->args[2]));
-}
-
-void
-_cgo_libc_setresuid(argset_t* x) {
- SET_RETVAL(setresuid((uid_t) x->args[0], (uid_t) x->args[1],
- (uid_t) x->args[2]));
-}
-
-void
-_cgo_libc_setreuid(argset_t* x) {
- SET_RETVAL(setreuid((uid_t) x->args[0], (uid_t) x->args[1]));
-}
-
-void
-_cgo_libc_setuid(argset_t* x) {
- SET_RETVAL(setuid((uid_t) x->args[0]));
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/ya.make b/contrib/go/_std_1.20/src/runtime/cgo/ya.make
deleted file mode 100644
index 735f6005cb..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgo/ya.make
+++ /dev/null
@@ -1,123 +0,0 @@
-IF (CGO_ENABLED)
- GO_LIBRARY()
-
- PEERDIR(
- library/cpp/sanitizer/include
- )
-
- NO_COMPILER_WARNINGS()
-
- SRCS(
- callbacks.go
- CGO_EXPORT gcc_context.c
- CGO_EXPORT gcc_util.c
- handle.go
- iscgo.go
- libcgo.h
- libcgo_unix.h
- )
- CGO_SRCS(
- cgo.go
- )
-
- IF (ARCH_ARM64)
- SRCS(
- abi_arm64.h
- asm_arm64.s
- gcc_arm64.S
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- abi_amd64.h
- asm_amd64.s
- gcc_amd64.S
- )
- ENDIF()
-
- IF (OS_DARWIN)
- SRCS(
- callbacks_traceback.go
- CGO_EXPORT gcc_libinit.c
- CGO_EXPORT gcc_setenv.c
- CGO_EXPORT gcc_traceback.c
- setenv.go
- )
-
- IF (ARCH_ARM64)
- CGO_LDFLAGS(
- -framework
- CoreFoundation
- )
-
- SRCS(
- CGO_EXPORT gcc_darwin_arm64.c
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- CGO_LDFLAGS(
- -lpthread
- )
-
- SRCS(
- CGO_EXPORT gcc_darwin_amd64.c
- )
- ENDIF()
- ENDIF()
-
- IF (OS_LINUX)
- CGO_LDFLAGS(
- -lpthread
- )
-
- SRCS(
- callbacks_traceback.go
- CGO_EXPORT gcc_fatalf.c
- CGO_EXPORT gcc_libinit.c
- CGO_EXPORT gcc_mmap.c
- CGO_EXPORT gcc_setenv.c
- CGO_EXPORT gcc_sigaction.c
- CGO_EXPORT gcc_traceback.c
- linux.go
- CGO_EXPORT linux_syscall.c
- mmap.go
- setenv.go
- sigaction.go
- )
-
- IF (ARCH_ARM64)
- SRCS(
- CGO_EXPORT gcc_linux_arm64.c
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- CGO_EXPORT gcc_linux_amd64.c
- )
- ENDIF()
- ENDIF()
-
- IF (OS_WINDOWS)
- SRCS(
- CGO_EXPORT gcc_libinit_windows.c
- libcgo_windows.h
- )
-
- IF (ARCH_ARM64)
- SRCS(
- CGO_EXPORT gcc_windows_arm64.c
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- CGO_EXPORT gcc_windows_amd64.c
- )
- ENDIF()
- ENDIF()
-
- END()
-ENDIF()
diff --git a/contrib/go/_std_1.20/src/runtime/cgocall.go b/contrib/go/_std_1.20/src/runtime/cgocall.go
deleted file mode 100644
index 9c75280d62..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgocall.go
+++ /dev/null
@@ -1,641 +0,0 @@
-// Copyright 2009 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.
-
-// Cgo call and callback support.
-//
-// To call into the C function f from Go, the cgo-generated code calls
-// runtime.cgocall(_cgo_Cfunc_f, frame), where _cgo_Cfunc_f is a
-// gcc-compiled function written by cgo.
-//
-// runtime.cgocall (below) calls entersyscall so as not to block
-// other goroutines or the garbage collector, and then calls
-// runtime.asmcgocall(_cgo_Cfunc_f, frame).
-//
-// runtime.asmcgocall (in asm_$GOARCH.s) switches to the m->g0 stack
-// (assumed to be an operating system-allocated stack, so safe to run
-// gcc-compiled code on) and calls _cgo_Cfunc_f(frame).
-//
-// _cgo_Cfunc_f invokes the actual C function f with arguments
-// taken from the frame structure, records the results in the frame,
-// and returns to runtime.asmcgocall.
-//
-// After it regains control, runtime.asmcgocall switches back to the
-// original g (m->curg)'s stack and returns to runtime.cgocall.
-//
-// After it regains control, runtime.cgocall calls exitsyscall, which blocks
-// until this m can run Go code without violating the $GOMAXPROCS limit,
-// and then unlocks g from m.
-//
-// The above description skipped over the possibility of the gcc-compiled
-// function f calling back into Go. If that happens, we continue down
-// the rabbit hole during the execution of f.
-//
-// To make it possible for gcc-compiled C code to call a Go function p.GoF,
-// cgo writes a gcc-compiled function named GoF (not p.GoF, since gcc doesn't
-// know about packages). The gcc-compiled C function f calls GoF.
-//
-// GoF initializes "frame", a structure containing all of its
-// arguments and slots for p.GoF's results. It calls
-// crosscall2(_cgoexp_GoF, frame, framesize, ctxt) using the gcc ABI.
-//
-// crosscall2 (in cgo/asm_$GOARCH.s) is a four-argument adapter from
-// the gcc function call ABI to the gc function call ABI. At this
-// point we're in the Go runtime, but we're still running on m.g0's
-// stack and outside the $GOMAXPROCS limit. crosscall2 calls
-// runtime.cgocallback(_cgoexp_GoF, frame, ctxt) using the gc ABI.
-// (crosscall2's framesize argument is no longer used, but there's one
-// case where SWIG calls crosscall2 directly and expects to pass this
-// argument. See _cgo_panic.)
-//
-// runtime.cgocallback (in asm_$GOARCH.s) switches from m.g0's stack
-// to the original g (m.curg)'s stack, on which it calls
-// runtime.cgocallbackg(_cgoexp_GoF, frame, ctxt). As part of the
-// stack switch, runtime.cgocallback saves the current SP as
-// m.g0.sched.sp, so that any use of m.g0's stack during the execution
-// of the callback will be done below the existing stack frames.
-// Before overwriting m.g0.sched.sp, it pushes the old value on the
-// m.g0 stack, so that it can be restored later.
-//
-// runtime.cgocallbackg (below) is now running on a real goroutine
-// stack (not an m.g0 stack). First it calls runtime.exitsyscall, which will
-// block until the $GOMAXPROCS limit allows running this goroutine.
-// Once exitsyscall has returned, it is safe to do things like call the memory
-// allocator or invoke the Go callback function. runtime.cgocallbackg
-// first defers a function to unwind m.g0.sched.sp, so that if p.GoF
-// panics, m.g0.sched.sp will be restored to its old value: the m.g0 stack
-// and the m.curg stack will be unwound in lock step.
-// Then it calls _cgoexp_GoF(frame).
-//
-// _cgoexp_GoF, which was generated by cmd/cgo, unpacks the arguments
-// from frame, calls p.GoF, writes the results back to frame, and
-// returns. Now we start unwinding this whole process.
-//
-// runtime.cgocallbackg pops but does not execute the deferred
-// function to unwind m.g0.sched.sp, calls runtime.entersyscall, and
-// returns to runtime.cgocallback.
-//
-// After it regains control, runtime.cgocallback switches back to
-// m.g0's stack (the pointer is still in m.g0.sched.sp), restores the old
-// m.g0.sched.sp value from the stack, and returns to crosscall2.
-//
-// crosscall2 restores the callee-save registers for gcc and returns
-// to GoF, which unpacks any result values and returns to f.
-
-package runtime
-
-import (
- "internal/goarch"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// Addresses collected in a cgo backtrace when crashing.
-// Length must match arg.Max in x_cgo_callers in runtime/cgo/gcc_traceback.c.
-type cgoCallers [32]uintptr
-
-// argset matches runtime/cgo/linux_syscall.c:argset_t
-type argset struct {
- args unsafe.Pointer
- retval uintptr
-}
-
-// wrapper for syscall package to call cgocall for libc (cgo) calls.
-//
-//go:linkname syscall_cgocaller syscall.cgocaller
-//go:nosplit
-//go:uintptrescapes
-func syscall_cgocaller(fn unsafe.Pointer, args ...uintptr) uintptr {
- as := argset{args: unsafe.Pointer(&args[0])}
- cgocall(fn, unsafe.Pointer(&as))
- return as.retval
-}
-
-var ncgocall uint64 // number of cgo calls in total for dead m
-
-// Call from Go to C.
-//
-// This must be nosplit because it's used for syscalls on some
-// platforms. Syscalls may have untyped arguments on the stack, so
-// it's not safe to grow or scan the stack.
-//
-//go:nosplit
-func cgocall(fn, arg unsafe.Pointer) int32 {
- if !iscgo && GOOS != "solaris" && GOOS != "illumos" && GOOS != "windows" {
- throw("cgocall unavailable")
- }
-
- if fn == nil {
- throw("cgocall nil")
- }
-
- if raceenabled {
- racereleasemerge(unsafe.Pointer(&racecgosync))
- }
-
- mp := getg().m
- mp.ncgocall++
- mp.ncgo++
-
- // Reset traceback.
- mp.cgoCallers[0] = 0
-
- // Announce we are entering a system call
- // so that the scheduler knows to create another
- // M to run goroutines while we are in the
- // foreign code.
- //
- // The call to asmcgocall is guaranteed not to
- // grow the stack and does not allocate memory,
- // so it is safe to call while "in a system call", outside
- // the $GOMAXPROCS accounting.
- //
- // fn may call back into Go code, in which case we'll exit the
- // "system call", run the Go code (which may grow the stack),
- // and then re-enter the "system call" reusing the PC and SP
- // saved by entersyscall here.
- entersyscall()
-
- // Tell asynchronous preemption that we're entering external
- // code. We do this after entersyscall because this may block
- // and cause an async preemption to fail, but at this point a
- // sync preemption will succeed (though this is not a matter
- // of correctness).
- osPreemptExtEnter(mp)
-
- mp.incgo = true
- errno := asmcgocall(fn, arg)
-
- // Update accounting before exitsyscall because exitsyscall may
- // reschedule us on to a different M.
- mp.incgo = false
- mp.ncgo--
-
- osPreemptExtExit(mp)
-
- exitsyscall()
-
- // Note that raceacquire must be called only after exitsyscall has
- // wired this M to a P.
- if raceenabled {
- raceacquire(unsafe.Pointer(&racecgosync))
- }
-
- // From the garbage collector's perspective, time can move
- // backwards in the sequence above. If there's a callback into
- // Go code, GC will see this function at the call to
- // asmcgocall. When the Go call later returns to C, the
- // syscall PC/SP is rolled back and the GC sees this function
- // back at the call to entersyscall. Normally, fn and arg
- // would be live at entersyscall and dead at asmcgocall, so if
- // time moved backwards, GC would see these arguments as dead
- // and then live. Prevent these undead arguments from crashing
- // GC by forcing them to stay live across this time warp.
- KeepAlive(fn)
- KeepAlive(arg)
- KeepAlive(mp)
-
- return errno
-}
-
-// Call from C back to Go. fn must point to an ABIInternal Go entry-point.
-//
-//go:nosplit
-func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
- gp := getg()
- if gp != gp.m.curg {
- println("runtime: bad g in cgocallback")
- exit(2)
- }
-
- // The call from C is on gp.m's g0 stack, so we must ensure
- // that we stay on that M. We have to do this before calling
- // exitsyscall, since it would otherwise be free to move us to
- // a different M. The call to unlockOSThread is in unwindm.
- lockOSThread()
-
- checkm := gp.m
-
- // Save current syscall parameters, so m.syscall can be
- // used again if callback decide to make syscall.
- syscall := gp.m.syscall
-
- // entersyscall saves the caller's SP to allow the GC to trace the Go
- // stack. However, since we're returning to an earlier stack frame and
- // need to pair with the entersyscall() call made by cgocall, we must
- // save syscall* and let reentersyscall restore them.
- savedsp := unsafe.Pointer(gp.syscallsp)
- savedpc := gp.syscallpc
- exitsyscall() // coming out of cgo call
- gp.m.incgo = false
-
- osPreemptExtExit(gp.m)
-
- cgocallbackg1(fn, frame, ctxt) // will call unlockOSThread
-
- // At this point unlockOSThread has been called.
- // The following code must not change to a different m.
- // This is enforced by checking incgo in the schedule function.
-
- gp.m.incgo = true
-
- if gp.m != checkm {
- throw("m changed unexpectedly in cgocallbackg")
- }
-
- osPreemptExtEnter(gp.m)
-
- // going back to cgo call
- reentersyscall(savedpc, uintptr(savedsp))
-
- gp.m.syscall = syscall
-}
-
-func cgocallbackg1(fn, frame unsafe.Pointer, ctxt uintptr) {
- gp := getg()
-
- // When we return, undo the call to lockOSThread in cgocallbackg.
- // We must still stay on the same m.
- defer unlockOSThread()
-
- if gp.m.needextram || extraMWaiters.Load() > 0 {
- gp.m.needextram = false
- systemstack(newextram)
- }
-
- if ctxt != 0 {
- s := append(gp.cgoCtxt, ctxt)
-
- // Now we need to set gp.cgoCtxt = s, but we could get
- // a SIGPROF signal while manipulating the slice, and
- // the SIGPROF handler could pick up gp.cgoCtxt while
- // tracing up the stack. We need to ensure that the
- // handler always sees a valid slice, so set the
- // values in an order such that it always does.
- p := (*slice)(unsafe.Pointer(&gp.cgoCtxt))
- atomicstorep(unsafe.Pointer(&p.array), unsafe.Pointer(&s[0]))
- p.cap = cap(s)
- p.len = len(s)
-
- defer func(gp *g) {
- // Decrease the length of the slice by one, safely.
- p := (*slice)(unsafe.Pointer(&gp.cgoCtxt))
- p.len--
- }(gp)
- }
-
- if gp.m.ncgo == 0 {
- // The C call to Go came from a thread not currently running
- // any Go. In the case of -buildmode=c-archive or c-shared,
- // this call may be coming in before package initialization
- // is complete. Wait until it is.
- <-main_init_done
- }
-
- // Check whether the profiler needs to be turned on or off; this route to
- // run Go code does not use runtime.execute, so bypasses the check there.
- hz := sched.profilehz
- if gp.m.profilehz != hz {
- setThreadCPUProfiler(hz)
- }
-
- // Add entry to defer stack in case of panic.
- restore := true
- defer unwindm(&restore)
-
- if raceenabled {
- raceacquire(unsafe.Pointer(&racecgosync))
- }
-
- // Invoke callback. This function is generated by cmd/cgo and
- // will unpack the argument frame and call the Go function.
- var cb func(frame unsafe.Pointer)
- cbFV := funcval{uintptr(fn)}
- *(*unsafe.Pointer)(unsafe.Pointer(&cb)) = noescape(unsafe.Pointer(&cbFV))
- cb(frame)
-
- if raceenabled {
- racereleasemerge(unsafe.Pointer(&racecgosync))
- }
-
- // Do not unwind m->g0->sched.sp.
- // Our caller, cgocallback, will do that.
- restore = false
-}
-
-func unwindm(restore *bool) {
- if *restore {
- // Restore sp saved by cgocallback during
- // unwind of g's stack (see comment at top of file).
- mp := acquirem()
- sched := &mp.g0.sched
- sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + alignUp(sys.MinFrameSize, sys.StackAlign)))
-
- // Do the accounting that cgocall will not have a chance to do
- // during an unwind.
- //
- // In the case where a Go call originates from C, ncgo is 0
- // and there is no matching cgocall to end.
- if mp.ncgo > 0 {
- mp.incgo = false
- mp.ncgo--
- osPreemptExtExit(mp)
- }
-
- releasem(mp)
- }
-}
-
-// called from assembly.
-func badcgocallback() {
- throw("misaligned stack in cgocallback")
-}
-
-// called from (incomplete) assembly.
-func cgounimpl() {
- throw("cgo not implemented")
-}
-
-var racecgosync uint64 // represents possible synchronization in C code
-
-// Pointer checking for cgo code.
-
-// We want to detect all cases where a program that does not use
-// unsafe makes a cgo call passing a Go pointer to memory that
-// contains a Go pointer. Here a Go pointer is defined as a pointer
-// to memory allocated by the Go runtime. Programs that use unsafe
-// can evade this restriction easily, so we don't try to catch them.
-// The cgo program will rewrite all possibly bad pointer arguments to
-// call cgoCheckPointer, where we can catch cases of a Go pointer
-// pointing to a Go pointer.
-
-// Complicating matters, taking the address of a slice or array
-// element permits the C program to access all elements of the slice
-// or array. In that case we will see a pointer to a single element,
-// but we need to check the entire data structure.
-
-// The cgoCheckPointer call takes additional arguments indicating that
-// it was called on an address expression. An additional argument of
-// true means that it only needs to check a single element. An
-// additional argument of a slice or array means that it needs to
-// check the entire slice/array, but nothing else. Otherwise, the
-// pointer could be anything, and we check the entire heap object,
-// which is conservative but safe.
-
-// When and if we implement a moving garbage collector,
-// cgoCheckPointer will pin the pointer for the duration of the cgo
-// call. (This is necessary but not sufficient; the cgo program will
-// also have to change to pin Go pointers that cannot point to Go
-// pointers.)
-
-// cgoCheckPointer checks if the argument contains a Go pointer that
-// points to a Go pointer, and panics if it does.
-func cgoCheckPointer(ptr any, arg any) {
- if debug.cgocheck == 0 {
- return
- }
-
- ep := efaceOf(&ptr)
- t := ep._type
-
- top := true
- if arg != nil && (t.kind&kindMask == kindPtr || t.kind&kindMask == kindUnsafePointer) {
- p := ep.data
- if t.kind&kindDirectIface == 0 {
- p = *(*unsafe.Pointer)(p)
- }
- if p == nil || !cgoIsGoPointer(p) {
- return
- }
- aep := efaceOf(&arg)
- switch aep._type.kind & kindMask {
- case kindBool:
- if t.kind&kindMask == kindUnsafePointer {
- // We don't know the type of the element.
- break
- }
- pt := (*ptrtype)(unsafe.Pointer(t))
- cgoCheckArg(pt.elem, p, true, false, cgoCheckPointerFail)
- return
- case kindSlice:
- // Check the slice rather than the pointer.
- ep = aep
- t = ep._type
- case kindArray:
- // Check the array rather than the pointer.
- // Pass top as false since we have a pointer
- // to the array.
- ep = aep
- t = ep._type
- top = false
- default:
- throw("can't happen")
- }
- }
-
- cgoCheckArg(t, ep.data, t.kind&kindDirectIface == 0, top, cgoCheckPointerFail)
-}
-
-const cgoCheckPointerFail = "cgo argument has Go pointer to Go pointer"
-const cgoResultFail = "cgo result has Go pointer"
-
-// cgoCheckArg is the real work of cgoCheckPointer. The argument p
-// is either a pointer to the value (of type t), or the value itself,
-// depending on indir. The top parameter is whether we are at the top
-// level, where Go pointers are allowed.
-func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
- if t.ptrdata == 0 || p == nil {
- // If the type has no pointers there is nothing to do.
- return
- }
-
- switch t.kind & kindMask {
- default:
- throw("can't happen")
- case kindArray:
- at := (*arraytype)(unsafe.Pointer(t))
- if !indir {
- if at.len != 1 {
- throw("can't happen")
- }
- cgoCheckArg(at.elem, p, at.elem.kind&kindDirectIface == 0, top, msg)
- return
- }
- for i := uintptr(0); i < at.len; i++ {
- cgoCheckArg(at.elem, p, true, top, msg)
- p = add(p, at.elem.size)
- }
- case kindChan, kindMap:
- // These types contain internal pointers that will
- // always be allocated in the Go heap. It's never OK
- // to pass them to C.
- panic(errorString(msg))
- case kindFunc:
- if indir {
- p = *(*unsafe.Pointer)(p)
- }
- if !cgoIsGoPointer(p) {
- return
- }
- panic(errorString(msg))
- case kindInterface:
- it := *(**_type)(p)
- if it == nil {
- return
- }
- // A type known at compile time is OK since it's
- // constant. A type not known at compile time will be
- // in the heap and will not be OK.
- if inheap(uintptr(unsafe.Pointer(it))) {
- panic(errorString(msg))
- }
- p = *(*unsafe.Pointer)(add(p, goarch.PtrSize))
- if !cgoIsGoPointer(p) {
- return
- }
- if !top {
- panic(errorString(msg))
- }
- cgoCheckArg(it, p, it.kind&kindDirectIface == 0, false, msg)
- case kindSlice:
- st := (*slicetype)(unsafe.Pointer(t))
- s := (*slice)(p)
- p = s.array
- if p == nil || !cgoIsGoPointer(p) {
- return
- }
- if !top {
- panic(errorString(msg))
- }
- if st.elem.ptrdata == 0 {
- return
- }
- for i := 0; i < s.cap; i++ {
- cgoCheckArg(st.elem, p, true, false, msg)
- p = add(p, st.elem.size)
- }
- case kindString:
- ss := (*stringStruct)(p)
- if !cgoIsGoPointer(ss.str) {
- return
- }
- if !top {
- panic(errorString(msg))
- }
- case kindStruct:
- st := (*structtype)(unsafe.Pointer(t))
- if !indir {
- if len(st.fields) != 1 {
- throw("can't happen")
- }
- cgoCheckArg(st.fields[0].typ, p, st.fields[0].typ.kind&kindDirectIface == 0, top, msg)
- return
- }
- for _, f := range st.fields {
- if f.typ.ptrdata == 0 {
- continue
- }
- cgoCheckArg(f.typ, add(p, f.offset), true, top, msg)
- }
- case kindPtr, kindUnsafePointer:
- if indir {
- p = *(*unsafe.Pointer)(p)
- if p == nil {
- return
- }
- }
-
- if !cgoIsGoPointer(p) {
- return
- }
- if !top {
- panic(errorString(msg))
- }
-
- cgoCheckUnknownPointer(p, msg)
- }
-}
-
-// cgoCheckUnknownPointer is called for an arbitrary pointer into Go
-// memory. It checks whether that Go memory contains any other
-// pointer into Go memory. If it does, we panic.
-// The return values are unused but useful to see in panic tracebacks.
-func cgoCheckUnknownPointer(p unsafe.Pointer, msg string) (base, i uintptr) {
- if inheap(uintptr(p)) {
- b, span, _ := findObject(uintptr(p), 0, 0)
- base = b
- if base == 0 {
- return
- }
- n := span.elemsize
- hbits := heapBitsForAddr(base, n)
- for {
- var addr uintptr
- if hbits, addr = hbits.next(); addr == 0 {
- break
- }
- if cgoIsGoPointer(*(*unsafe.Pointer)(unsafe.Pointer(addr))) {
- panic(errorString(msg))
- }
- }
-
- return
- }
-
- for _, datap := range activeModules() {
- if cgoInRange(p, datap.data, datap.edata) || cgoInRange(p, datap.bss, datap.ebss) {
- // We have no way to know the size of the object.
- // We have to assume that it might contain a pointer.
- panic(errorString(msg))
- }
- // In the text or noptr sections, we know that the
- // pointer does not point to a Go pointer.
- }
-
- return
-}
-
-// cgoIsGoPointer reports whether the pointer is a Go pointer--a
-// pointer to Go memory. We only care about Go memory that might
-// contain pointers.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func cgoIsGoPointer(p unsafe.Pointer) bool {
- if p == nil {
- return false
- }
-
- if inHeapOrStack(uintptr(p)) {
- return true
- }
-
- for _, datap := range activeModules() {
- if cgoInRange(p, datap.data, datap.edata) || cgoInRange(p, datap.bss, datap.ebss) {
- return true
- }
- }
-
- return false
-}
-
-// cgoInRange reports whether p is between start and end.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func cgoInRange(p unsafe.Pointer, start, end uintptr) bool {
- return start <= uintptr(p) && uintptr(p) < end
-}
-
-// cgoCheckResult is called to check the result parameter of an
-// exported Go function. It panics if the result is or contains a Go
-// pointer.
-func cgoCheckResult(val any) {
- if debug.cgocheck == 0 {
- return
- }
-
- ep := efaceOf(&val)
- t := ep._type
- cgoCheckArg(t, ep.data, t.kind&kindDirectIface == 0, false, cgoResultFail)
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cgocheck.go b/contrib/go/_std_1.20/src/runtime/cgocheck.go
deleted file mode 100644
index 84e7516758..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cgocheck.go
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2015 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.
-
-// Code to check that pointer writes follow the cgo rules.
-// These functions are invoked via the write barrier when debug.cgocheck > 1.
-
-package runtime
-
-import (
- "internal/goarch"
- "unsafe"
-)
-
-const cgoWriteBarrierFail = "Go pointer stored into non-Go memory"
-
-// cgoCheckWriteBarrier is called whenever a pointer is stored into memory.
-// It throws if the program is storing a Go pointer into non-Go memory.
-//
-// This is called from the write barrier, so its entire call tree must
-// be nosplit.
-//
-//go:nosplit
-//go:nowritebarrier
-func cgoCheckWriteBarrier(dst *uintptr, src uintptr) {
- if !cgoIsGoPointer(unsafe.Pointer(src)) {
- return
- }
- if cgoIsGoPointer(unsafe.Pointer(dst)) {
- return
- }
-
- // If we are running on the system stack then dst might be an
- // address on the stack, which is OK.
- gp := getg()
- if gp == gp.m.g0 || gp == gp.m.gsignal {
- return
- }
-
- // Allocating memory can write to various mfixalloc structs
- // that look like they are non-Go memory.
- if gp.m.mallocing != 0 {
- return
- }
-
- // It's OK if writing to memory allocated by persistentalloc.
- // Do this check last because it is more expensive and rarely true.
- // If it is false the expense doesn't matter since we are crashing.
- if inPersistentAlloc(uintptr(unsafe.Pointer(dst))) {
- return
- }
-
- systemstack(func() {
- println("write of Go pointer", hex(src), "to non-Go memory", hex(uintptr(unsafe.Pointer(dst))))
- throw(cgoWriteBarrierFail)
- })
-}
-
-// cgoCheckMemmove is called when moving a block of memory.
-// dst and src point off bytes into the value to copy.
-// size is the number of bytes to copy.
-// It throws if the program is copying a block that contains a Go pointer
-// into non-Go memory.
-//
-//go:nosplit
-//go:nowritebarrier
-func cgoCheckMemmove(typ *_type, dst, src unsafe.Pointer, off, size uintptr) {
- if typ.ptrdata == 0 {
- return
- }
- if !cgoIsGoPointer(src) {
- return
- }
- if cgoIsGoPointer(dst) {
- return
- }
- cgoCheckTypedBlock(typ, src, off, size)
-}
-
-// cgoCheckSliceCopy is called when copying n elements of a slice.
-// src and dst are pointers to the first element of the slice.
-// typ is the element type of the slice.
-// It throws if the program is copying slice elements that contain Go pointers
-// into non-Go memory.
-//
-//go:nosplit
-//go:nowritebarrier
-func cgoCheckSliceCopy(typ *_type, dst, src unsafe.Pointer, n int) {
- if typ.ptrdata == 0 {
- return
- }
- if !cgoIsGoPointer(src) {
- return
- }
- if cgoIsGoPointer(dst) {
- return
- }
- p := src
- for i := 0; i < n; i++ {
- cgoCheckTypedBlock(typ, p, 0, typ.size)
- p = add(p, typ.size)
- }
-}
-
-// cgoCheckTypedBlock checks the block of memory at src, for up to size bytes,
-// and throws if it finds a Go pointer. The type of the memory is typ,
-// and src is off bytes into that type.
-//
-//go:nosplit
-//go:nowritebarrier
-func cgoCheckTypedBlock(typ *_type, src unsafe.Pointer, off, size uintptr) {
- // Anything past typ.ptrdata is not a pointer.
- if typ.ptrdata <= off {
- return
- }
- if ptrdataSize := typ.ptrdata - off; size > ptrdataSize {
- size = ptrdataSize
- }
-
- if typ.kind&kindGCProg == 0 {
- cgoCheckBits(src, typ.gcdata, off, size)
- return
- }
-
- // The type has a GC program. Try to find GC bits somewhere else.
- for _, datap := range activeModules() {
- if cgoInRange(src, datap.data, datap.edata) {
- doff := uintptr(src) - datap.data
- cgoCheckBits(add(src, -doff), datap.gcdatamask.bytedata, off+doff, size)
- return
- }
- if cgoInRange(src, datap.bss, datap.ebss) {
- boff := uintptr(src) - datap.bss
- cgoCheckBits(add(src, -boff), datap.gcbssmask.bytedata, off+boff, size)
- return
- }
- }
-
- s := spanOfUnchecked(uintptr(src))
- if s.state.get() == mSpanManual {
- // There are no heap bits for value stored on the stack.
- // For a channel receive src might be on the stack of some
- // other goroutine, so we can't unwind the stack even if
- // we wanted to.
- // We can't expand the GC program without extra storage
- // space we can't easily get.
- // Fortunately we have the type information.
- systemstack(func() {
- cgoCheckUsingType(typ, src, off, size)
- })
- return
- }
-
- // src must be in the regular heap.
-
- hbits := heapBitsForAddr(uintptr(src), size)
- for {
- var addr uintptr
- if hbits, addr = hbits.next(); addr == 0 {
- break
- }
- v := *(*unsafe.Pointer)(unsafe.Pointer(addr))
- if cgoIsGoPointer(v) {
- throw(cgoWriteBarrierFail)
- }
- }
-}
-
-// cgoCheckBits checks the block of memory at src, for up to size
-// bytes, and throws if it finds a Go pointer. The gcbits mark each
-// pointer value. The src pointer is off bytes into the gcbits.
-//
-//go:nosplit
-//go:nowritebarrier
-func cgoCheckBits(src unsafe.Pointer, gcbits *byte, off, size uintptr) {
- skipMask := off / goarch.PtrSize / 8
- skipBytes := skipMask * goarch.PtrSize * 8
- ptrmask := addb(gcbits, skipMask)
- src = add(src, skipBytes)
- off -= skipBytes
- size += off
- var bits uint32
- for i := uintptr(0); i < size; i += goarch.PtrSize {
- if i&(goarch.PtrSize*8-1) == 0 {
- bits = uint32(*ptrmask)
- ptrmask = addb(ptrmask, 1)
- } else {
- bits >>= 1
- }
- if off > 0 {
- off -= goarch.PtrSize
- } else {
- if bits&1 != 0 {
- v := *(*unsafe.Pointer)(add(src, i))
- if cgoIsGoPointer(v) {
- throw(cgoWriteBarrierFail)
- }
- }
- }
- }
-}
-
-// cgoCheckUsingType is like cgoCheckTypedBlock, but is a last ditch
-// fall back to look for pointers in src using the type information.
-// We only use this when looking at a value on the stack when the type
-// uses a GC program, because otherwise it's more efficient to use the
-// GC bits. This is called on the system stack.
-//
-//go:nowritebarrier
-//go:systemstack
-func cgoCheckUsingType(typ *_type, src unsafe.Pointer, off, size uintptr) {
- if typ.ptrdata == 0 {
- return
- }
-
- // Anything past typ.ptrdata is not a pointer.
- if typ.ptrdata <= off {
- return
- }
- if ptrdataSize := typ.ptrdata - off; size > ptrdataSize {
- size = ptrdataSize
- }
-
- if typ.kind&kindGCProg == 0 {
- cgoCheckBits(src, typ.gcdata, off, size)
- return
- }
- switch typ.kind & kindMask {
- default:
- throw("can't happen")
- case kindArray:
- at := (*arraytype)(unsafe.Pointer(typ))
- for i := uintptr(0); i < at.len; i++ {
- if off < at.elem.size {
- cgoCheckUsingType(at.elem, src, off, size)
- }
- src = add(src, at.elem.size)
- skipped := off
- if skipped > at.elem.size {
- skipped = at.elem.size
- }
- checked := at.elem.size - skipped
- off -= skipped
- if size <= checked {
- return
- }
- size -= checked
- }
- case kindStruct:
- st := (*structtype)(unsafe.Pointer(typ))
- for _, f := range st.fields {
- if off < f.typ.size {
- cgoCheckUsingType(f.typ, src, off, size)
- }
- src = add(src, f.typ.size)
- skipped := off
- if skipped > f.typ.size {
- skipped = f.typ.size
- }
- checked := f.typ.size - skipped
- off -= skipped
- if size <= checked {
- return
- }
- size -= checked
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/chan.go b/contrib/go/_std_1.20/src/runtime/chan.go
deleted file mode 100644
index 6a0ad35b86..0000000000
--- a/contrib/go/_std_1.20/src/runtime/chan.go
+++ /dev/null
@@ -1,851 +0,0 @@
-// Copyright 2014 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 runtime
-
-// This file contains the implementation of Go channels.
-
-// Invariants:
-// At least one of c.sendq and c.recvq is empty,
-// except for the case of an unbuffered channel with a single goroutine
-// blocked on it for both sending and receiving using a select statement,
-// in which case the length of c.sendq and c.recvq is limited only by the
-// size of the select statement.
-//
-// For buffered channels, also:
-// c.qcount > 0 implies that c.recvq is empty.
-// c.qcount < c.dataqsiz implies that c.sendq is empty.
-
-import (
- "internal/abi"
- "runtime/internal/atomic"
- "runtime/internal/math"
- "unsafe"
-)
-
-const (
- maxAlign = 8
- hchanSize = unsafe.Sizeof(hchan{}) + uintptr(-int(unsafe.Sizeof(hchan{}))&(maxAlign-1))
- debugChan = false
-)
-
-type hchan struct {
- qcount uint // total data in the queue
- dataqsiz uint // size of the circular queue
- buf unsafe.Pointer // points to an array of dataqsiz elements
- elemsize uint16
- closed uint32
- elemtype *_type // element type
- sendx uint // send index
- recvx uint // receive index
- recvq waitq // list of recv waiters
- sendq waitq // list of send waiters
-
- // lock protects all fields in hchan, as well as several
- // fields in sudogs blocked on this channel.
- //
- // Do not change another G's status while holding this lock
- // (in particular, do not ready a G), as this can deadlock
- // with stack shrinking.
- lock mutex
-}
-
-type waitq struct {
- first *sudog
- last *sudog
-}
-
-//go:linkname reflect_makechan reflect.makechan
-func reflect_makechan(t *chantype, size int) *hchan {
- return makechan(t, size)
-}
-
-func makechan64(t *chantype, size int64) *hchan {
- if int64(int(size)) != size {
- panic(plainError("makechan: size out of range"))
- }
-
- return makechan(t, int(size))
-}
-
-func makechan(t *chantype, size int) *hchan {
- elem := t.elem
-
- // compiler checks this but be safe.
- if elem.size >= 1<<16 {
- throw("makechan: invalid channel element type")
- }
- if hchanSize%maxAlign != 0 || elem.align > maxAlign {
- throw("makechan: bad alignment")
- }
-
- mem, overflow := math.MulUintptr(elem.size, uintptr(size))
- if overflow || mem > maxAlloc-hchanSize || size < 0 {
- panic(plainError("makechan: size out of range"))
- }
-
- // Hchan does not contain pointers interesting for GC when elements stored in buf do not contain pointers.
- // buf points into the same allocation, elemtype is persistent.
- // SudoG's are referenced from their owning thread so they can't be collected.
- // TODO(dvyukov,rlh): Rethink when collector can move allocated objects.
- var c *hchan
- switch {
- case mem == 0:
- // Queue or element size is zero.
- c = (*hchan)(mallocgc(hchanSize, nil, true))
- // Race detector uses this location for synchronization.
- c.buf = c.raceaddr()
- case elem.ptrdata == 0:
- // Elements do not contain pointers.
- // Allocate hchan and buf in one call.
- c = (*hchan)(mallocgc(hchanSize+mem, nil, true))
- c.buf = add(unsafe.Pointer(c), hchanSize)
- default:
- // Elements contain pointers.
- c = new(hchan)
- c.buf = mallocgc(mem, elem, true)
- }
-
- c.elemsize = uint16(elem.size)
- c.elemtype = elem
- c.dataqsiz = uint(size)
- lockInit(&c.lock, lockRankHchan)
-
- if debugChan {
- print("makechan: chan=", c, "; elemsize=", elem.size, "; dataqsiz=", size, "\n")
- }
- return c
-}
-
-// chanbuf(c, i) is pointer to the i'th slot in the buffer.
-func chanbuf(c *hchan, i uint) unsafe.Pointer {
- return add(c.buf, uintptr(i)*uintptr(c.elemsize))
-}
-
-// full reports whether a send on c would block (that is, the channel is full).
-// It uses a single word-sized read of mutable state, so although
-// the answer is instantaneously true, the correct answer may have changed
-// by the time the calling function receives the return value.
-func full(c *hchan) bool {
- // c.dataqsiz is immutable (never written after the channel is created)
- // so it is safe to read at any time during channel operation.
- if c.dataqsiz == 0 {
- // Assumes that a pointer read is relaxed-atomic.
- return c.recvq.first == nil
- }
- // Assumes that a uint read is relaxed-atomic.
- return c.qcount == c.dataqsiz
-}
-
-// entry point for c <- x from compiled code.
-//
-//go:nosplit
-func chansend1(c *hchan, elem unsafe.Pointer) {
- chansend(c, elem, true, getcallerpc())
-}
-
-/*
- * generic single channel send/recv
- * If block is not nil,
- * then the protocol will not
- * sleep but return if it could
- * not complete.
- *
- * sleep can wake up with g.param == nil
- * when a channel involved in the sleep has
- * been closed. it is easiest to loop and re-run
- * the operation; we'll see that it's now closed.
- */
-func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool {
- if c == nil {
- if !block {
- return false
- }
- gopark(nil, nil, waitReasonChanSendNilChan, traceEvGoStop, 2)
- throw("unreachable")
- }
-
- if debugChan {
- print("chansend: chan=", c, "\n")
- }
-
- if raceenabled {
- racereadpc(c.raceaddr(), callerpc, abi.FuncPCABIInternal(chansend))
- }
-
- // Fast path: check for failed non-blocking operation without acquiring the lock.
- //
- // After observing that the channel is not closed, we observe that the channel is
- // not ready for sending. Each of these observations is a single word-sized read
- // (first c.closed and second full()).
- // Because a closed channel cannot transition from 'ready for sending' to
- // 'not ready for sending', even if the channel is closed between the two observations,
- // they imply a moment between the two when the channel was both not yet closed
- // and not ready for sending. We behave as if we observed the channel at that moment,
- // and report that the send cannot proceed.
- //
- // It is okay if the reads are reordered here: if we observe that the channel is not
- // ready for sending and then observe that it is not closed, that implies that the
- // channel wasn't closed during the first observation. However, nothing here
- // guarantees forward progress. We rely on the side effects of lock release in
- // chanrecv() and closechan() to update this thread's view of c.closed and full().
- if !block && c.closed == 0 && full(c) {
- return false
- }
-
- var t0 int64
- if blockprofilerate > 0 {
- t0 = cputicks()
- }
-
- lock(&c.lock)
-
- if c.closed != 0 {
- unlock(&c.lock)
- panic(plainError("send on closed channel"))
- }
-
- if sg := c.recvq.dequeue(); sg != nil {
- // Found a waiting receiver. We pass the value we want to send
- // directly to the receiver, bypassing the channel buffer (if any).
- send(c, sg, ep, func() { unlock(&c.lock) }, 3)
- return true
- }
-
- if c.qcount < c.dataqsiz {
- // Space is available in the channel buffer. Enqueue the element to send.
- qp := chanbuf(c, c.sendx)
- if raceenabled {
- racenotify(c, c.sendx, nil)
- }
- typedmemmove(c.elemtype, qp, ep)
- c.sendx++
- if c.sendx == c.dataqsiz {
- c.sendx = 0
- }
- c.qcount++
- unlock(&c.lock)
- return true
- }
-
- if !block {
- unlock(&c.lock)
- return false
- }
-
- // Block on the channel. Some receiver will complete our operation for us.
- gp := getg()
- mysg := acquireSudog()
- mysg.releasetime = 0
- if t0 != 0 {
- mysg.releasetime = -1
- }
- // No stack splits between assigning elem and enqueuing mysg
- // on gp.waiting where copystack can find it.
- mysg.elem = ep
- mysg.waitlink = nil
- mysg.g = gp
- mysg.isSelect = false
- mysg.c = c
- gp.waiting = mysg
- gp.param = nil
- c.sendq.enqueue(mysg)
- // Signal to anyone trying to shrink our stack that we're about
- // to park on a channel. The window between when this G's status
- // changes and when we set gp.activeStackChans is not safe for
- // stack shrinking.
- gp.parkingOnChan.Store(true)
- gopark(chanparkcommit, unsafe.Pointer(&c.lock), waitReasonChanSend, traceEvGoBlockSend, 2)
- // Ensure the value being sent is kept alive until the
- // receiver copies it out. The sudog has a pointer to the
- // stack object, but sudogs aren't considered as roots of the
- // stack tracer.
- KeepAlive(ep)
-
- // someone woke us up.
- if mysg != gp.waiting {
- throw("G waiting list is corrupted")
- }
- gp.waiting = nil
- gp.activeStackChans = false
- closed := !mysg.success
- gp.param = nil
- if mysg.releasetime > 0 {
- blockevent(mysg.releasetime-t0, 2)
- }
- mysg.c = nil
- releaseSudog(mysg)
- if closed {
- if c.closed == 0 {
- throw("chansend: spurious wakeup")
- }
- panic(plainError("send on closed channel"))
- }
- return true
-}
-
-// send processes a send operation on an empty channel c.
-// The value ep sent by the sender is copied to the receiver sg.
-// The receiver is then woken up to go on its merry way.
-// Channel c must be empty and locked. send unlocks c with unlockf.
-// sg must already be dequeued from c.
-// ep must be non-nil and point to the heap or the caller's stack.
-func send(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) {
- if raceenabled {
- if c.dataqsiz == 0 {
- racesync(c, sg)
- } else {
- // Pretend we go through the buffer, even though
- // we copy directly. Note that we need to increment
- // the head/tail locations only when raceenabled.
- racenotify(c, c.recvx, nil)
- racenotify(c, c.recvx, sg)
- c.recvx++
- if c.recvx == c.dataqsiz {
- c.recvx = 0
- }
- c.sendx = c.recvx // c.sendx = (c.sendx+1) % c.dataqsiz
- }
- }
- if sg.elem != nil {
- sendDirect(c.elemtype, sg, ep)
- sg.elem = nil
- }
- gp := sg.g
- unlockf()
- gp.param = unsafe.Pointer(sg)
- sg.success = true
- if sg.releasetime != 0 {
- sg.releasetime = cputicks()
- }
- goready(gp, skip+1)
-}
-
-// Sends and receives on unbuffered or empty-buffered channels are the
-// only operations where one running goroutine writes to the stack of
-// another running goroutine. The GC assumes that stack writes only
-// happen when the goroutine is running and are only done by that
-// goroutine. Using a write barrier is sufficient to make up for
-// violating that assumption, but the write barrier has to work.
-// typedmemmove will call bulkBarrierPreWrite, but the target bytes
-// are not in the heap, so that will not help. We arrange to call
-// memmove and typeBitsBulkBarrier instead.
-
-func sendDirect(t *_type, sg *sudog, src unsafe.Pointer) {
- // src is on our stack, dst is a slot on another stack.
-
- // Once we read sg.elem out of sg, it will no longer
- // be updated if the destination's stack gets copied (shrunk).
- // So make sure that no preemption points can happen between read & use.
- dst := sg.elem
- typeBitsBulkBarrier(t, uintptr(dst), uintptr(src), t.size)
- // No need for cgo write barrier checks because dst is always
- // Go memory.
- memmove(dst, src, t.size)
-}
-
-func recvDirect(t *_type, sg *sudog, dst unsafe.Pointer) {
- // dst is on our stack or the heap, src is on another stack.
- // The channel is locked, so src will not move during this
- // operation.
- src := sg.elem
- typeBitsBulkBarrier(t, uintptr(dst), uintptr(src), t.size)
- memmove(dst, src, t.size)
-}
-
-func closechan(c *hchan) {
- if c == nil {
- panic(plainError("close of nil channel"))
- }
-
- lock(&c.lock)
- if c.closed != 0 {
- unlock(&c.lock)
- panic(plainError("close of closed channel"))
- }
-
- if raceenabled {
- callerpc := getcallerpc()
- racewritepc(c.raceaddr(), callerpc, abi.FuncPCABIInternal(closechan))
- racerelease(c.raceaddr())
- }
-
- c.closed = 1
-
- var glist gList
-
- // release all readers
- for {
- sg := c.recvq.dequeue()
- if sg == nil {
- break
- }
- if sg.elem != nil {
- typedmemclr(c.elemtype, sg.elem)
- sg.elem = nil
- }
- if sg.releasetime != 0 {
- sg.releasetime = cputicks()
- }
- gp := sg.g
- gp.param = unsafe.Pointer(sg)
- sg.success = false
- if raceenabled {
- raceacquireg(gp, c.raceaddr())
- }
- glist.push(gp)
- }
-
- // release all writers (they will panic)
- for {
- sg := c.sendq.dequeue()
- if sg == nil {
- break
- }
- sg.elem = nil
- if sg.releasetime != 0 {
- sg.releasetime = cputicks()
- }
- gp := sg.g
- gp.param = unsafe.Pointer(sg)
- sg.success = false
- if raceenabled {
- raceacquireg(gp, c.raceaddr())
- }
- glist.push(gp)
- }
- unlock(&c.lock)
-
- // Ready all Gs now that we've dropped the channel lock.
- for !glist.empty() {
- gp := glist.pop()
- gp.schedlink = 0
- goready(gp, 3)
- }
-}
-
-// empty reports whether a read from c would block (that is, the channel is
-// empty). It uses a single atomic read of mutable state.
-func empty(c *hchan) bool {
- // c.dataqsiz is immutable.
- if c.dataqsiz == 0 {
- return atomic.Loadp(unsafe.Pointer(&c.sendq.first)) == nil
- }
- return atomic.Loaduint(&c.qcount) == 0
-}
-
-// entry points for <- c from compiled code.
-//
-//go:nosplit
-func chanrecv1(c *hchan, elem unsafe.Pointer) {
- chanrecv(c, elem, true)
-}
-
-//go:nosplit
-func chanrecv2(c *hchan, elem unsafe.Pointer) (received bool) {
- _, received = chanrecv(c, elem, true)
- return
-}
-
-// chanrecv receives on channel c and writes the received data to ep.
-// ep may be nil, in which case received data is ignored.
-// If block == false and no elements are available, returns (false, false).
-// Otherwise, if c is closed, zeros *ep and returns (true, false).
-// Otherwise, fills in *ep with an element and returns (true, true).
-// A non-nil ep must point to the heap or the caller's stack.
-func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) {
- // raceenabled: don't need to check ep, as it is always on the stack
- // or is new memory allocated by reflect.
-
- if debugChan {
- print("chanrecv: chan=", c, "\n")
- }
-
- if c == nil {
- if !block {
- return
- }
- gopark(nil, nil, waitReasonChanReceiveNilChan, traceEvGoStop, 2)
- throw("unreachable")
- }
-
- // Fast path: check for failed non-blocking operation without acquiring the lock.
- if !block && empty(c) {
- // After observing that the channel is not ready for receiving, we observe whether the
- // channel is closed.
- //
- // Reordering of these checks could lead to incorrect behavior when racing with a close.
- // For example, if the channel was open and not empty, was closed, and then drained,
- // reordered reads could incorrectly indicate "open and empty". To prevent reordering,
- // we use atomic loads for both checks, and rely on emptying and closing to happen in
- // separate critical sections under the same lock. This assumption fails when closing
- // an unbuffered channel with a blocked send, but that is an error condition anyway.
- if atomic.Load(&c.closed) == 0 {
- // Because a channel cannot be reopened, the later observation of the channel
- // being not closed implies that it was also not closed at the moment of the
- // first observation. We behave as if we observed the channel at that moment
- // and report that the receive cannot proceed.
- return
- }
- // The channel is irreversibly closed. Re-check whether the channel has any pending data
- // to receive, which could have arrived between the empty and closed checks above.
- // Sequential consistency is also required here, when racing with such a send.
- if empty(c) {
- // The channel is irreversibly closed and empty.
- if raceenabled {
- raceacquire(c.raceaddr())
- }
- if ep != nil {
- typedmemclr(c.elemtype, ep)
- }
- return true, false
- }
- }
-
- var t0 int64
- if blockprofilerate > 0 {
- t0 = cputicks()
- }
-
- lock(&c.lock)
-
- if c.closed != 0 {
- if c.qcount == 0 {
- if raceenabled {
- raceacquire(c.raceaddr())
- }
- unlock(&c.lock)
- if ep != nil {
- typedmemclr(c.elemtype, ep)
- }
- return true, false
- }
- // The channel has been closed, but the channel's buffer have data.
- } else {
- // Just found waiting sender with not closed.
- if sg := c.sendq.dequeue(); sg != nil {
- // Found a waiting sender. If buffer is size 0, receive value
- // directly from sender. Otherwise, receive from head of queue
- // and add sender's value to the tail of the queue (both map to
- // the same buffer slot because the queue is full).
- recv(c, sg, ep, func() { unlock(&c.lock) }, 3)
- return true, true
- }
- }
-
- if c.qcount > 0 {
- // Receive directly from queue
- qp := chanbuf(c, c.recvx)
- if raceenabled {
- racenotify(c, c.recvx, nil)
- }
- if ep != nil {
- typedmemmove(c.elemtype, ep, qp)
- }
- typedmemclr(c.elemtype, qp)
- c.recvx++
- if c.recvx == c.dataqsiz {
- c.recvx = 0
- }
- c.qcount--
- unlock(&c.lock)
- return true, true
- }
-
- if !block {
- unlock(&c.lock)
- return false, false
- }
-
- // no sender available: block on this channel.
- gp := getg()
- mysg := acquireSudog()
- mysg.releasetime = 0
- if t0 != 0 {
- mysg.releasetime = -1
- }
- // No stack splits between assigning elem and enqueuing mysg
- // on gp.waiting where copystack can find it.
- mysg.elem = ep
- mysg.waitlink = nil
- gp.waiting = mysg
- mysg.g = gp
- mysg.isSelect = false
- mysg.c = c
- gp.param = nil
- c.recvq.enqueue(mysg)
- // Signal to anyone trying to shrink our stack that we're about
- // to park on a channel. The window between when this G's status
- // changes and when we set gp.activeStackChans is not safe for
- // stack shrinking.
- gp.parkingOnChan.Store(true)
- gopark(chanparkcommit, unsafe.Pointer(&c.lock), waitReasonChanReceive, traceEvGoBlockRecv, 2)
-
- // someone woke us up
- if mysg != gp.waiting {
- throw("G waiting list is corrupted")
- }
- gp.waiting = nil
- gp.activeStackChans = false
- if mysg.releasetime > 0 {
- blockevent(mysg.releasetime-t0, 2)
- }
- success := mysg.success
- gp.param = nil
- mysg.c = nil
- releaseSudog(mysg)
- return true, success
-}
-
-// recv processes a receive operation on a full channel c.
-// There are 2 parts:
-// 1. The value sent by the sender sg is put into the channel
-// and the sender is woken up to go on its merry way.
-// 2. The value received by the receiver (the current G) is
-// written to ep.
-//
-// For synchronous channels, both values are the same.
-// For asynchronous channels, the receiver gets its data from
-// the channel buffer and the sender's data is put in the
-// channel buffer.
-// Channel c must be full and locked. recv unlocks c with unlockf.
-// sg must already be dequeued from c.
-// A non-nil ep must point to the heap or the caller's stack.
-func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) {
- if c.dataqsiz == 0 {
- if raceenabled {
- racesync(c, sg)
- }
- if ep != nil {
- // copy data from sender
- recvDirect(c.elemtype, sg, ep)
- }
- } else {
- // Queue is full. Take the item at the
- // head of the queue. Make the sender enqueue
- // its item at the tail of the queue. Since the
- // queue is full, those are both the same slot.
- qp := chanbuf(c, c.recvx)
- if raceenabled {
- racenotify(c, c.recvx, nil)
- racenotify(c, c.recvx, sg)
- }
- // copy data from queue to receiver
- if ep != nil {
- typedmemmove(c.elemtype, ep, qp)
- }
- // copy data from sender to queue
- typedmemmove(c.elemtype, qp, sg.elem)
- c.recvx++
- if c.recvx == c.dataqsiz {
- c.recvx = 0
- }
- c.sendx = c.recvx // c.sendx = (c.sendx+1) % c.dataqsiz
- }
- sg.elem = nil
- gp := sg.g
- unlockf()
- gp.param = unsafe.Pointer(sg)
- sg.success = true
- if sg.releasetime != 0 {
- sg.releasetime = cputicks()
- }
- goready(gp, skip+1)
-}
-
-func chanparkcommit(gp *g, chanLock unsafe.Pointer) bool {
- // There are unlocked sudogs that point into gp's stack. Stack
- // copying must lock the channels of those sudogs.
- // Set activeStackChans here instead of before we try parking
- // because we could self-deadlock in stack growth on the
- // channel lock.
- gp.activeStackChans = true
- // Mark that it's safe for stack shrinking to occur now,
- // because any thread acquiring this G's stack for shrinking
- // is guaranteed to observe activeStackChans after this store.
- gp.parkingOnChan.Store(false)
- // Make sure we unlock after setting activeStackChans and
- // unsetting parkingOnChan. The moment we unlock chanLock
- // we risk gp getting readied by a channel operation and
- // so gp could continue running before everything before
- // the unlock is visible (even to gp itself).
- unlock((*mutex)(chanLock))
- return true
-}
-
-// compiler implements
-//
-// select {
-// case c <- v:
-// ... foo
-// default:
-// ... bar
-// }
-//
-// as
-//
-// if selectnbsend(c, v) {
-// ... foo
-// } else {
-// ... bar
-// }
-func selectnbsend(c *hchan, elem unsafe.Pointer) (selected bool) {
- return chansend(c, elem, false, getcallerpc())
-}
-
-// compiler implements
-//
-// select {
-// case v, ok = <-c:
-// ... foo
-// default:
-// ... bar
-// }
-//
-// as
-//
-// if selected, ok = selectnbrecv(&v, c); selected {
-// ... foo
-// } else {
-// ... bar
-// }
-func selectnbrecv(elem unsafe.Pointer, c *hchan) (selected, received bool) {
- return chanrecv(c, elem, false)
-}
-
-//go:linkname reflect_chansend reflect.chansend
-func reflect_chansend(c *hchan, elem unsafe.Pointer, nb bool) (selected bool) {
- return chansend(c, elem, !nb, getcallerpc())
-}
-
-//go:linkname reflect_chanrecv reflect.chanrecv
-func reflect_chanrecv(c *hchan, nb bool, elem unsafe.Pointer) (selected bool, received bool) {
- return chanrecv(c, elem, !nb)
-}
-
-//go:linkname reflect_chanlen reflect.chanlen
-func reflect_chanlen(c *hchan) int {
- if c == nil {
- return 0
- }
- return int(c.qcount)
-}
-
-//go:linkname reflectlite_chanlen internal/reflectlite.chanlen
-func reflectlite_chanlen(c *hchan) int {
- if c == nil {
- return 0
- }
- return int(c.qcount)
-}
-
-//go:linkname reflect_chancap reflect.chancap
-func reflect_chancap(c *hchan) int {
- if c == nil {
- return 0
- }
- return int(c.dataqsiz)
-}
-
-//go:linkname reflect_chanclose reflect.chanclose
-func reflect_chanclose(c *hchan) {
- closechan(c)
-}
-
-func (q *waitq) enqueue(sgp *sudog) {
- sgp.next = nil
- x := q.last
- if x == nil {
- sgp.prev = nil
- q.first = sgp
- q.last = sgp
- return
- }
- sgp.prev = x
- x.next = sgp
- q.last = sgp
-}
-
-func (q *waitq) dequeue() *sudog {
- for {
- sgp := q.first
- if sgp == nil {
- return nil
- }
- y := sgp.next
- if y == nil {
- q.first = nil
- q.last = nil
- } else {
- y.prev = nil
- q.first = y
- sgp.next = nil // mark as removed (see dequeueSudoG)
- }
-
- // if a goroutine was put on this queue because of a
- // select, there is a small window between the goroutine
- // being woken up by a different case and it grabbing the
- // channel locks. Once it has the lock
- // it removes itself from the queue, so we won't see it after that.
- // We use a flag in the G struct to tell us when someone
- // else has won the race to signal this goroutine but the goroutine
- // hasn't removed itself from the queue yet.
- if sgp.isSelect && !sgp.g.selectDone.CompareAndSwap(0, 1) {
- continue
- }
-
- return sgp
- }
-}
-
-func (c *hchan) raceaddr() unsafe.Pointer {
- // Treat read-like and write-like operations on the channel to
- // happen at this address. Avoid using the address of qcount
- // or dataqsiz, because the len() and cap() builtins read
- // those addresses, and we don't want them racing with
- // operations like close().
- return unsafe.Pointer(&c.buf)
-}
-
-func racesync(c *hchan, sg *sudog) {
- racerelease(chanbuf(c, 0))
- raceacquireg(sg.g, chanbuf(c, 0))
- racereleaseg(sg.g, chanbuf(c, 0))
- raceacquire(chanbuf(c, 0))
-}
-
-// Notify the race detector of a send or receive involving buffer entry idx
-// and a channel c or its communicating partner sg.
-// This function handles the special case of c.elemsize==0.
-func racenotify(c *hchan, idx uint, sg *sudog) {
- // We could have passed the unsafe.Pointer corresponding to entry idx
- // instead of idx itself. However, in a future version of this function,
- // we can use idx to better handle the case of elemsize==0.
- // A future improvement to the detector is to call TSan with c and idx:
- // this way, Go will continue to not allocating buffer entries for channels
- // of elemsize==0, yet the race detector can be made to handle multiple
- // sync objects underneath the hood (one sync object per idx)
- qp := chanbuf(c, idx)
- // When elemsize==0, we don't allocate a full buffer for the channel.
- // Instead of individual buffer entries, the race detector uses the
- // c.buf as the only buffer entry. This simplification prevents us from
- // following the memory model's happens-before rules (rules that are
- // implemented in racereleaseacquire). Instead, we accumulate happens-before
- // information in the synchronization object associated with c.buf.
- if c.elemsize == 0 {
- if sg == nil {
- raceacquire(qp)
- racerelease(qp)
- } else {
- raceacquireg(sg.g, qp)
- racereleaseg(sg.g, qp)
- }
- } else {
- if sg == nil {
- racereleaseacquire(qp)
- } else {
- racereleaseacquireg(sg.g, qp)
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/checkptr.go b/contrib/go/_std_1.20/src/runtime/checkptr.go
deleted file mode 100644
index 2d4afd5cf6..0000000000
--- a/contrib/go/_std_1.20/src/runtime/checkptr.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-import "unsafe"
-
-func checkptrAlignment(p unsafe.Pointer, elem *_type, n uintptr) {
- // nil pointer is always suitably aligned (#47430).
- if p == nil {
- return
- }
-
- // Check that (*[n]elem)(p) is appropriately aligned.
- // Note that we allow unaligned pointers if the types they point to contain
- // no pointers themselves. See issue 37298.
- // TODO(mdempsky): What about fieldAlign?
- if elem.ptrdata != 0 && uintptr(p)&(uintptr(elem.align)-1) != 0 {
- throw("checkptr: misaligned pointer conversion")
- }
-
- // Check that (*[n]elem)(p) doesn't straddle multiple heap objects.
- // TODO(mdempsky): Fix #46938 so we don't need to worry about overflow here.
- if checkptrStraddles(p, n*elem.size) {
- throw("checkptr: converted pointer straddles multiple allocations")
- }
-}
-
-// checkptrStraddles reports whether the first size-bytes of memory
-// addressed by ptr is known to straddle more than one Go allocation.
-func checkptrStraddles(ptr unsafe.Pointer, size uintptr) bool {
- if size <= 1 {
- return false
- }
-
- // Check that add(ptr, size-1) won't overflow. This avoids the risk
- // of producing an illegal pointer value (assuming ptr is legal).
- if uintptr(ptr) >= -(size - 1) {
- return true
- }
- end := add(ptr, size-1)
-
- // TODO(mdempsky): Detect when [ptr, end] contains Go allocations,
- // but neither ptr nor end point into one themselves.
-
- return checkptrBase(ptr) != checkptrBase(end)
-}
-
-func checkptrArithmetic(p unsafe.Pointer, originals []unsafe.Pointer) {
- if 0 < uintptr(p) && uintptr(p) < minLegalPointer {
- throw("checkptr: pointer arithmetic computed bad pointer value")
- }
-
- // Check that if the computed pointer p points into a heap
- // object, then one of the original pointers must have pointed
- // into the same object.
- base := checkptrBase(p)
- if base == 0 {
- return
- }
-
- for _, original := range originals {
- if base == checkptrBase(original) {
- return
- }
- }
-
- throw("checkptr: pointer arithmetic result points to invalid allocation")
-}
-
-// checkptrBase returns the base address for the allocation containing
-// the address p.
-//
-// Importantly, if p1 and p2 point into the same variable, then
-// checkptrBase(p1) == checkptrBase(p2). However, the converse/inverse
-// is not necessarily true as allocations can have trailing padding,
-// and multiple variables may be packed into a single allocation.
-func checkptrBase(p unsafe.Pointer) uintptr {
- // stack
- if gp := getg(); gp.stack.lo <= uintptr(p) && uintptr(p) < gp.stack.hi {
- // TODO(mdempsky): Walk the stack to identify the
- // specific stack frame or even stack object that p
- // points into.
- //
- // In the mean time, use "1" as a pseudo-address to
- // represent the stack. This is an invalid address on
- // all platforms, so it's guaranteed to be distinct
- // from any of the addresses we might return below.
- return 1
- }
-
- // heap (must check after stack because of #35068)
- if base, _, _ := findObject(uintptr(p), 0, 0); base != 0 {
- return base
- }
-
- // data or bss
- for _, datap := range activeModules() {
- if datap.data <= uintptr(p) && uintptr(p) < datap.edata {
- return datap.data
- }
- if datap.bss <= uintptr(p) && uintptr(p) < datap.ebss {
- return datap.bss
- }
- }
-
- return 0
-}
diff --git a/contrib/go/_std_1.20/src/runtime/coverage/apis.go b/contrib/go/_std_1.20/src/runtime/coverage/apis.go
deleted file mode 100644
index 7d851f9362..0000000000
--- a/contrib/go/_std_1.20/src/runtime/coverage/apis.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2022 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 coverage
-
-import (
- "fmt"
- "internal/coverage"
- "io"
- "reflect"
- "sync/atomic"
- "unsafe"
-)
-
-// WriteMetaDir writes a coverage meta-data file for the currently
-// running program to the directory specified in 'dir'. An error will
-// be returned if the operation can't be completed successfully (for
-// example, if the currently running program was not built with
-// "-cover", or if the directory does not exist).
-func WriteMetaDir(dir string) error {
- if !finalHashComputed {
- return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
- }
- return emitMetaDataToDirectory(dir, getCovMetaList())
-}
-
-// WriteMeta writes the meta-data content (the payload that would
-// normally be emitted to a meta-data file) for the currently running
-// program to the the writer 'w'. An error will be returned if the
-// operation can't be completed successfully (for example, if the
-// currently running program was not built with "-cover", or if a
-// write fails).
-func WriteMeta(w io.Writer) error {
- if w == nil {
- return fmt.Errorf("error: nil writer in WriteMeta")
- }
- if !finalHashComputed {
- return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
- }
- ml := getCovMetaList()
- return writeMetaData(w, ml, cmode, cgran, finalHash)
-}
-
-// WriteCountersDir writes a coverage counter-data file for the
-// currently running program to the directory specified in 'dir'. An
-// error will be returned if the operation can't be completed
-// successfully (for example, if the currently running program was not
-// built with "-cover", or if the directory does not exist). The
-// counter data written will be a snapshot taken at the point of the
-// call.
-func WriteCountersDir(dir string) error {
- return emitCounterDataToDirectory(dir)
-}
-
-// WriteCounters writes coverage counter-data content for
-// the currently running program to the writer 'w'. An error will be
-// returned if the operation can't be completed successfully (for
-// example, if the currently running program was not built with
-// "-cover", or if a write fails). The counter data written will be a
-// snapshot taken at the point of the invocation.
-func WriteCounters(w io.Writer) error {
- if w == nil {
- return fmt.Errorf("error: nil writer in WriteCounters")
- }
- // Ask the runtime for the list of coverage counter symbols.
- cl := getCovCounterList()
- if len(cl) == 0 {
- return fmt.Errorf("program not built with -cover")
- }
- if !finalHashComputed {
- return fmt.Errorf("meta-data not written yet, unable to write counter data")
- }
-
- pm := getCovPkgMap()
- s := &emitState{
- counterlist: cl,
- pkgmap: pm,
- }
- return s.emitCounterDataToWriter(w)
-}
-
-// ClearCounters clears/resets all coverage counter variables in the
-// currently running program. It returns an error if the program in
-// question was not built with the "-cover" flag. Clearing of coverage
-// counters is also not supported for programs not using atomic
-// counter mode (see more detailed comments below for the rationale
-// here).
-func ClearCounters() error {
- cl := getCovCounterList()
- if len(cl) == 0 {
- return fmt.Errorf("program not built with -cover")
- }
- if cmode != coverage.CtrModeAtomic {
- return fmt.Errorf("ClearCounters invoked for program build with -covermode=%s (please use -covermode=atomic)", cmode.String())
- }
-
- // Implementation note: this function would be faster and simpler
- // if we could just zero out the entire counter array, but for the
- // moment we go through and zero out just the slots in the array
- // corresponding to the counter values. We do this to avoid the
- // following bad scenario: suppose that a user builds their Go
- // program with "-cover", and that program has a function (call it
- // main.XYZ) that invokes ClearCounters:
- //
- // func XYZ() {
- // ... do some stuff ...
- // coverage.ClearCounters()
- // if someCondition { <<--- HERE
- // ...
- // }
- // }
- //
- // At the point where ClearCounters executes, main.XYZ has not yet
- // finished running, thus as soon as the call returns the line
- // marked "HERE" above will trigger the writing of a non-zero
- // value into main.XYZ's counter slab. However since we've just
- // finished clearing the entire counter segment, we will have lost
- // the values in the prolog portion of main.XYZ's counter slab
- // (nctrs, pkgid, funcid). This means that later on at the end of
- // program execution as we walk through the entire counter array
- // for the program looking for executed functions, we'll zoom past
- // main.XYZ's prolog (which was zero'd) and hit the non-zero
- // counter value corresponding to the "HERE" block, which will
- // then be interpreted as the start of another live function.
- // Things will go downhill from there.
- //
- // This same scenario is also a potential risk if the program is
- // running on an architecture that permits reordering of
- // writes/stores, since the inconsistency described above could
- // arise here. Example scenario:
- //
- // func ABC() {
- // ... // prolog
- // if alwaysTrue() {
- // XYZ() // counter update here
- // }
- // }
- //
- // In the instrumented version of ABC, the prolog of the function
- // will contain a series of stores to the initial portion of the
- // counter array to write number-of-counters, pkgid, funcid. Later
- // in the function there is also a store to increment a counter
- // for the block containing the call to XYZ(). If the CPU is
- // allowed to reorder stores and decides to issue the XYZ store
- // before the prolog stores, this could be observable as an
- // inconsistency similar to the one above. Hence the requirement
- // for atomic counter mode: according to package atomic docs,
- // "...operations that happen in a specific order on one thread,
- // will always be observed to happen in exactly that order by
- // another thread". Thus we can be sure that there will be no
- // inconsistency when reading the counter array from the thread
- // running ClearCounters.
-
- var sd []atomic.Uint32
-
- bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&sd))
- for _, c := range cl {
- bufHdr.Data = uintptr(unsafe.Pointer(c.Counters))
- bufHdr.Len = int(c.Len)
- bufHdr.Cap = int(c.Len)
- for i := 0; i < len(sd); i++ {
- // Skip ahead until the next non-zero value.
- sdi := sd[i].Load()
- if sdi == 0 {
- continue
- }
- // We found a function that was executed; clear its counters.
- nCtrs := sdi
- for j := 0; j < int(nCtrs); j++ {
- sd[i+coverage.FirstCtrOffset+j].Store(0)
- }
- // Move to next function.
- i += coverage.FirstCtrOffset + int(nCtrs) - 1
- }
- }
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/runtime/coverage/emit.go b/contrib/go/_std_1.20/src/runtime/coverage/emit.go
deleted file mode 100644
index 2aed99c718..0000000000
--- a/contrib/go/_std_1.20/src/runtime/coverage/emit.go
+++ /dev/null
@@ -1,667 +0,0 @@
-// Copyright 2022 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 coverage
-
-import (
- "crypto/md5"
- "fmt"
- "internal/coverage"
- "internal/coverage/encodecounter"
- "internal/coverage/encodemeta"
- "internal/coverage/rtcov"
- "io"
- "os"
- "path/filepath"
- "reflect"
- "runtime"
- "sync/atomic"
- "time"
- "unsafe"
-)
-
-// This file contains functions that support the writing of data files
-// emitted at the end of code coverage testing runs, from instrumented
-// executables.
-
-// getCovMetaList returns a list of meta-data blobs registered
-// for the currently executing instrumented program. It is defined in the
-// runtime.
-func getCovMetaList() []rtcov.CovMetaBlob
-
-// getCovCounterList returns a list of counter-data blobs registered
-// for the currently executing instrumented program. It is defined in the
-// runtime.
-func getCovCounterList() []rtcov.CovCounterBlob
-
-// getCovPkgMap returns a map storing the remapped package IDs for
-// hard-coded runtime packages (see internal/coverage/pkgid.go for
-// more on why hard-coded package IDs are needed). This function
-// is defined in the runtime.
-func getCovPkgMap() map[int]int
-
-// emitState holds useful state information during the emit process.
-//
-// When an instrumented program finishes execution and starts the
-// process of writing out coverage data, it's possible that an
-// existing meta-data file already exists in the output directory. In
-// this case openOutputFiles() below will leave the 'mf' field below
-// as nil. If a new meta-data file is needed, field 'mfname' will be
-// the final desired path of the meta file, 'mftmp' will be a
-// temporary file, and 'mf' will be an open os.File pointer for
-// 'mftmp'. The meta-data file payload will be written to 'mf', the
-// temp file will be then closed and renamed (from 'mftmp' to
-// 'mfname'), so as to insure that the meta-data file is created
-// atomically; we want this so that things work smoothly in cases
-// where there are several instances of a given instrumented program
-// all terminating at the same time and trying to create meta-data
-// files simultaneously.
-//
-// For counter data files there is less chance of a collision, hence
-// the openOutputFiles() stores the counter data file in 'cfname' and
-// then places the *io.File into 'cf'.
-type emitState struct {
- mfname string // path of final meta-data output file
- mftmp string // path to meta-data temp file (if needed)
- mf *os.File // open os.File for meta-data temp file
- cfname string // path of final counter data file
- cftmp string // path to counter data temp file
- cf *os.File // open os.File for counter data file
- outdir string // output directory
-
- // List of meta-data symbols obtained from the runtime
- metalist []rtcov.CovMetaBlob
-
- // List of counter-data symbols obtained from the runtime
- counterlist []rtcov.CovCounterBlob
-
- // Table to use for remapping hard-coded pkg ids.
- pkgmap map[int]int
-
- // emit debug trace output
- debug bool
-}
-
-var (
- // finalHash is computed at init time from the list of meta-data
- // symbols registered during init. It is used both for writing the
- // meta-data file and counter-data files.
- finalHash [16]byte
- // Set to true when we've computed finalHash + finalMetaLen.
- finalHashComputed bool
- // Total meta-data length.
- finalMetaLen uint64
- // Records whether we've already attempted to write meta-data.
- metaDataEmitAttempted bool
- // Counter mode for this instrumented program run.
- cmode coverage.CounterMode
- // Counter granularity for this instrumented program run.
- cgran coverage.CounterGranularity
- // Cached value of GOCOVERDIR environment variable.
- goCoverDir string
- // Copy of os.Args made at init time, converted into map format.
- capturedOsArgs map[string]string
- // Flag used in tests to signal that coverage data already written.
- covProfileAlreadyEmitted bool
-)
-
-// fileType is used to select between counter-data files and
-// meta-data files.
-type fileType int
-
-const (
- noFile = 1 << iota
- metaDataFile
- counterDataFile
-)
-
-// emitMetaData emits the meta-data output file for this coverage run.
-// This entry point is intended to be invoked by the compiler from
-// an instrumented program's main package init func.
-func emitMetaData() {
- if covProfileAlreadyEmitted {
- return
- }
- ml, err := prepareForMetaEmit()
- if err != nil {
- fmt.Fprintf(os.Stderr, "error: coverage meta-data prep failed: %v\n", err)
- if os.Getenv("GOCOVERDEBUG") != "" {
- panic("meta-data write failure")
- }
- }
- if len(ml) == 0 {
- fmt.Fprintf(os.Stderr, "program not built with -cover\n")
- return
- }
-
- goCoverDir = os.Getenv("GOCOVERDIR")
- if goCoverDir == "" {
- fmt.Fprintf(os.Stderr, "warning: GOCOVERDIR not set, no coverage data emitted\n")
- return
- }
-
- if err := emitMetaDataToDirectory(goCoverDir, ml); err != nil {
- fmt.Fprintf(os.Stderr, "error: coverage meta-data emit failed: %v\n", err)
- if os.Getenv("GOCOVERDEBUG") != "" {
- panic("meta-data write failure")
- }
- }
-}
-
-func modeClash(m coverage.CounterMode) bool {
- if m == coverage.CtrModeRegOnly || m == coverage.CtrModeTestMain {
- return false
- }
- if cmode == coverage.CtrModeInvalid {
- cmode = m
- return false
- }
- return cmode != m
-}
-
-func granClash(g coverage.CounterGranularity) bool {
- if cgran == coverage.CtrGranularityInvalid {
- cgran = g
- return false
- }
- return cgran != g
-}
-
-// prepareForMetaEmit performs preparatory steps needed prior to
-// emitting a meta-data file, notably computing a final hash of
-// all meta-data blobs and capturing os args.
-func prepareForMetaEmit() ([]rtcov.CovMetaBlob, error) {
- // Ask the runtime for the list of coverage meta-data symbols.
- ml := getCovMetaList()
-
- // In the normal case (go build -o prog.exe ... ; ./prog.exe)
- // len(ml) will always be non-zero, but we check here since at
- // some point this function will be reachable via user-callable
- // APIs (for example, to write out coverage data from a server
- // program that doesn't ever call os.Exit).
- if len(ml) == 0 {
- return nil, nil
- }
-
- s := &emitState{
- metalist: ml,
- debug: os.Getenv("GOCOVERDEBUG") != "",
- }
-
- // Capture os.Args() now so as to avoid issues if args
- // are rewritten during program execution.
- capturedOsArgs = captureOsArgs()
-
- if s.debug {
- fmt.Fprintf(os.Stderr, "=+= GOCOVERDIR is %s\n", os.Getenv("GOCOVERDIR"))
- fmt.Fprintf(os.Stderr, "=+= contents of covmetalist:\n")
- for k, b := range ml {
- fmt.Fprintf(os.Stderr, "=+= slot: %d path: %s ", k, b.PkgPath)
- if b.PkgID != -1 {
- fmt.Fprintf(os.Stderr, " hcid: %d", b.PkgID)
- }
- fmt.Fprintf(os.Stderr, "\n")
- }
- pm := getCovPkgMap()
- fmt.Fprintf(os.Stderr, "=+= remap table:\n")
- for from, to := range pm {
- fmt.Fprintf(os.Stderr, "=+= from %d to %d\n",
- uint32(from), uint32(to))
- }
- }
-
- h := md5.New()
- tlen := uint64(unsafe.Sizeof(coverage.MetaFileHeader{}))
- for _, entry := range ml {
- if _, err := h.Write(entry.Hash[:]); err != nil {
- return nil, err
- }
- tlen += uint64(entry.Len)
- ecm := coverage.CounterMode(entry.CounterMode)
- if modeClash(ecm) {
- return nil, fmt.Errorf("coverage counter mode clash: package %s uses mode=%d, but package %s uses mode=%s\n", ml[0].PkgPath, cmode, entry.PkgPath, ecm)
- }
- ecg := coverage.CounterGranularity(entry.CounterGranularity)
- if granClash(ecg) {
- return nil, fmt.Errorf("coverage counter granularity clash: package %s uses gran=%d, but package %s uses gran=%s\n", ml[0].PkgPath, cgran, entry.PkgPath, ecg)
- }
- }
-
- // Hash mode and granularity as well.
- h.Write([]byte(cmode.String()))
- h.Write([]byte(cgran.String()))
-
- // Compute final digest.
- fh := h.Sum(nil)
- copy(finalHash[:], fh)
- finalHashComputed = true
- finalMetaLen = tlen
-
- return ml, nil
-}
-
-// emitMetaData emits the meta-data output file to the specified
-// directory, returning an error if something went wrong.
-func emitMetaDataToDirectory(outdir string, ml []rtcov.CovMetaBlob) error {
- ml, err := prepareForMetaEmit()
- if err != nil {
- return err
- }
- if len(ml) == 0 {
- return nil
- }
-
- metaDataEmitAttempted = true
-
- s := &emitState{
- metalist: ml,
- debug: os.Getenv("GOCOVERDEBUG") != "",
- outdir: outdir,
- }
-
- // Open output files.
- if err := s.openOutputFiles(finalHash, finalMetaLen, metaDataFile); err != nil {
- return err
- }
-
- // Emit meta-data file only if needed (may already be present).
- if s.needMetaDataFile() {
- if err := s.emitMetaDataFile(finalHash, finalMetaLen); err != nil {
- return err
- }
- }
- return nil
-}
-
-// emitCounterData emits the counter data output file for this coverage run.
-// This entry point is intended to be invoked by the runtime when an
-// instrumented program is terminating or calling os.Exit().
-func emitCounterData() {
- if goCoverDir == "" || !finalHashComputed || covProfileAlreadyEmitted {
- return
- }
- if err := emitCounterDataToDirectory(goCoverDir); err != nil {
- fmt.Fprintf(os.Stderr, "error: coverage counter data emit failed: %v\n", err)
- if os.Getenv("GOCOVERDEBUG") != "" {
- panic("counter-data write failure")
- }
- }
-}
-
-// emitMetaData emits the counter-data output file for this coverage run.
-func emitCounterDataToDirectory(outdir string) error {
- // Ask the runtime for the list of coverage counter symbols.
- cl := getCovCounterList()
- if len(cl) == 0 {
- // no work to do here.
- return nil
- }
-
- if !finalHashComputed {
- return fmt.Errorf("error: meta-data not available (binary not built with -cover?)")
- }
-
- // Ask the runtime for the list of coverage counter symbols.
- pm := getCovPkgMap()
- s := &emitState{
- counterlist: cl,
- pkgmap: pm,
- outdir: outdir,
- debug: os.Getenv("GOCOVERDEBUG") != "",
- }
-
- // Open output file.
- if err := s.openOutputFiles(finalHash, finalMetaLen, counterDataFile); err != nil {
- return err
- }
- if s.cf == nil {
- return fmt.Errorf("counter data output file open failed (no additional info")
- }
-
- // Emit counter data file.
- if err := s.emitCounterDataFile(finalHash, s.cf); err != nil {
- return err
- }
- if err := s.cf.Close(); err != nil {
- return fmt.Errorf("closing counter data file: %v", err)
- }
-
- // Counter file has now been closed. Rename the temp to the
- // final desired path.
- if err := os.Rename(s.cftmp, s.cfname); err != nil {
- return fmt.Errorf("writing %s: rename from %s failed: %v\n", s.cfname, s.cftmp, err)
- }
-
- return nil
-}
-
-// emitMetaData emits counter data for this coverage run to an io.Writer.
-func (s *emitState) emitCounterDataToWriter(w io.Writer) error {
- if err := s.emitCounterDataFile(finalHash, w); err != nil {
- return err
- }
- return nil
-}
-
-// openMetaFile determines whether we need to emit a meta-data output
-// file, or whether we can reuse the existing file in the coverage out
-// dir. It updates mfname/mftmp/mf fields in 's', returning an error
-// if something went wrong. See the comment on the emitState type
-// definition above for more on how file opening is managed.
-func (s *emitState) openMetaFile(metaHash [16]byte, metaLen uint64) error {
-
- // Open meta-outfile for reading to see if it exists.
- fn := fmt.Sprintf("%s.%x", coverage.MetaFilePref, metaHash)
- s.mfname = filepath.Join(s.outdir, fn)
- fi, err := os.Stat(s.mfname)
- if err != nil || fi.Size() != int64(metaLen) {
- // We need a new meta-file.
- tname := "tmp." + fn + fmt.Sprintf("%d", time.Now().UnixNano())
- s.mftmp = filepath.Join(s.outdir, tname)
- s.mf, err = os.Create(s.mftmp)
- if err != nil {
- return fmt.Errorf("creating meta-data file %s: %v", s.mftmp, err)
- }
- }
- return nil
-}
-
-// openCounterFile opens an output file for the counter data portion
-// of a test coverage run. If updates the 'cfname' and 'cf' fields in
-// 's', returning an error if something went wrong.
-func (s *emitState) openCounterFile(metaHash [16]byte) error {
- processID := os.Getpid()
- fn := fmt.Sprintf(coverage.CounterFileTempl, coverage.CounterFilePref, metaHash, processID, time.Now().UnixNano())
- s.cfname = filepath.Join(s.outdir, fn)
- s.cftmp = filepath.Join(s.outdir, "tmp."+fn)
- var err error
- s.cf, err = os.Create(s.cftmp)
- if err != nil {
- return fmt.Errorf("creating counter data file %s: %v", s.cftmp, err)
- }
- return nil
-}
-
-// openOutputFiles opens output files in preparation for emitting
-// coverage data. In the case of the meta-data file, openOutputFiles
-// may determine that we can reuse an existing meta-data file in the
-// outdir, in which case it will leave the 'mf' field in the state
-// struct as nil. If a new meta-file is needed, the field 'mfname'
-// will be the final desired path of the meta file, 'mftmp' will be a
-// temporary file, and 'mf' will be an open os.File pointer for
-// 'mftmp'. The idea is that the client/caller will write content into
-// 'mf', close it, and then rename 'mftmp' to 'mfname'. This function
-// also opens the counter data output file, setting 'cf' and 'cfname'
-// in the state struct.
-func (s *emitState) openOutputFiles(metaHash [16]byte, metaLen uint64, which fileType) error {
- fi, err := os.Stat(s.outdir)
- if err != nil {
- return fmt.Errorf("output directory %q inaccessible (err: %v); no coverage data written", s.outdir, err)
- }
- if !fi.IsDir() {
- return fmt.Errorf("output directory %q not a directory; no coverage data written", s.outdir)
- }
-
- if (which & metaDataFile) != 0 {
- if err := s.openMetaFile(metaHash, metaLen); err != nil {
- return err
- }
- }
- if (which & counterDataFile) != 0 {
- if err := s.openCounterFile(metaHash); err != nil {
- return err
- }
- }
- return nil
-}
-
-// emitMetaDataFile emits coverage meta-data to a previously opened
-// temporary file (s.mftmp), then renames the generated file to the
-// final path (s.mfname).
-func (s *emitState) emitMetaDataFile(finalHash [16]byte, tlen uint64) error {
- if err := writeMetaData(s.mf, s.metalist, cmode, cgran, finalHash); err != nil {
- return fmt.Errorf("writing %s: %v\n", s.mftmp, err)
- }
- if err := s.mf.Close(); err != nil {
- return fmt.Errorf("closing meta data temp file: %v", err)
- }
-
- // Temp file has now been flushed and closed. Rename the temp to the
- // final desired path.
- if err := os.Rename(s.mftmp, s.mfname); err != nil {
- return fmt.Errorf("writing %s: rename from %s failed: %v\n", s.mfname, s.mftmp, err)
- }
-
- return nil
-}
-
-// needMetaDataFile returns TRUE if we need to emit a meta-data file
-// for this program run. It should be used only after
-// openOutputFiles() has been invoked.
-func (s *emitState) needMetaDataFile() bool {
- return s.mf != nil
-}
-
-func writeMetaData(w io.Writer, metalist []rtcov.CovMetaBlob, cmode coverage.CounterMode, gran coverage.CounterGranularity, finalHash [16]byte) error {
- mfw := encodemeta.NewCoverageMetaFileWriter("<io.Writer>", w)
-
- // Note: "sd" is re-initialized on each iteration of the loop
- // below, and would normally be declared inside the loop, but
- // placed here escape analysis since we capture it in bufHdr.
- var sd []byte
- bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&sd))
-
- var blobs [][]byte
- for _, e := range metalist {
- bufHdr.Data = uintptr(unsafe.Pointer(e.P))
- bufHdr.Len = int(e.Len)
- bufHdr.Cap = int(e.Len)
- blobs = append(blobs, sd)
- }
- return mfw.Write(finalHash, blobs, cmode, gran)
-}
-
-func (s *emitState) NumFuncs() (int, error) {
- var sd []atomic.Uint32
- bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&sd))
-
- totalFuncs := 0
- for _, c := range s.counterlist {
- bufHdr.Data = uintptr(unsafe.Pointer(c.Counters))
- bufHdr.Len = int(c.Len)
- bufHdr.Cap = int(c.Len)
- for i := 0; i < len(sd); i++ {
- // Skip ahead until the next non-zero value.
- sdi := sd[i].Load()
- if sdi == 0 {
- continue
- }
-
- // We found a function that was executed.
- nCtrs := sdi
-
- // Check to make sure that we have at least one live
- // counter. See the implementation note in ClearCoverageCounters
- // for a description of why this is needed.
- isLive := false
- st := i + coverage.FirstCtrOffset
- counters := sd[st : st+int(nCtrs)]
- for i := 0; i < len(counters); i++ {
- if counters[i].Load() != 0 {
- isLive = true
- break
- }
- }
- if !isLive {
- // Skip this function.
- i += coverage.FirstCtrOffset + int(nCtrs) - 1
- continue
- }
-
- totalFuncs++
-
- // Move to the next function.
- i += coverage.FirstCtrOffset + int(nCtrs) - 1
- }
- }
- return totalFuncs, nil
-}
-
-func (s *emitState) VisitFuncs(f encodecounter.CounterVisitorFn) error {
- var sd []atomic.Uint32
- var tcounters []uint32
- bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&sd))
-
- rdCounters := func(actrs []atomic.Uint32, ctrs []uint32) []uint32 {
- ctrs = ctrs[:0]
- for i := range actrs {
- ctrs = append(ctrs, actrs[i].Load())
- }
- return ctrs
- }
-
- dpkg := uint32(0)
- for _, c := range s.counterlist {
- bufHdr.Data = uintptr(unsafe.Pointer(c.Counters))
- bufHdr.Len = int(c.Len)
- bufHdr.Cap = int(c.Len)
- for i := 0; i < len(sd); i++ {
- // Skip ahead until the next non-zero value.
- sdi := sd[i].Load()
- if sdi == 0 {
- continue
- }
-
- // We found a function that was executed.
- nCtrs := sd[i+coverage.NumCtrsOffset].Load()
- pkgId := sd[i+coverage.PkgIdOffset].Load()
- funcId := sd[i+coverage.FuncIdOffset].Load()
- cst := i + coverage.FirstCtrOffset
- counters := sd[cst : cst+int(nCtrs)]
-
- // Check to make sure that we have at least one live
- // counter. See the implementation note in ClearCoverageCounters
- // for a description of why this is needed.
- isLive := false
- for i := 0; i < len(counters); i++ {
- if counters[i].Load() != 0 {
- isLive = true
- break
- }
- }
- if !isLive {
- // Skip this function.
- i += coverage.FirstCtrOffset + int(nCtrs) - 1
- continue
- }
-
- if s.debug {
- if pkgId != dpkg {
- dpkg = pkgId
- fmt.Fprintf(os.Stderr, "\n=+= %d: pk=%d visit live fcn",
- i, pkgId)
- }
- fmt.Fprintf(os.Stderr, " {i=%d F%d NC%d}", i, funcId, nCtrs)
- }
-
- // Vet and/or fix up package ID. A package ID of zero
- // indicates that there is some new package X that is a
- // runtime dependency, and this package has code that
- // executes before its corresponding init package runs.
- // This is a fatal error that we should only see during
- // Go development (e.g. tip).
- ipk := int32(pkgId)
- if ipk == 0 {
- fmt.Fprintf(os.Stderr, "\n")
- reportErrorInHardcodedList(int32(i), ipk, funcId, nCtrs)
- } else if ipk < 0 {
- if newId, ok := s.pkgmap[int(ipk)]; ok {
- pkgId = uint32(newId)
- } else {
- fmt.Fprintf(os.Stderr, "\n")
- reportErrorInHardcodedList(int32(i), ipk, funcId, nCtrs)
- }
- } else {
- // The package ID value stored in the counter array
- // has 1 added to it (so as to preclude the
- // possibility of a zero value ; see
- // runtime.addCovMeta), so subtract off 1 here to form
- // the real package ID.
- pkgId--
- }
-
- tcounters = rdCounters(counters, tcounters)
- if err := f(pkgId, funcId, tcounters); err != nil {
- return err
- }
-
- // Skip over this function.
- i += coverage.FirstCtrOffset + int(nCtrs) - 1
- }
- if s.debug {
- fmt.Fprintf(os.Stderr, "\n")
- }
- }
- return nil
-}
-
-// captureOsArgs converts os.Args() into the format we use to store
-// this info in the counter data file (counter data file "args"
-// section is a generic key-value collection). See the 'args' section
-// in internal/coverage/defs.go for more info. The args map
-// is also used to capture GOOS + GOARCH values as well.
-func captureOsArgs() map[string]string {
- m := make(map[string]string)
- m["argc"] = fmt.Sprintf("%d", len(os.Args))
- for k, a := range os.Args {
- m[fmt.Sprintf("argv%d", k)] = a
- }
- m["GOOS"] = runtime.GOOS
- m["GOARCH"] = runtime.GOARCH
- return m
-}
-
-// emitCounterDataFile emits the counter data portion of a
-// coverage output file (to the file 's.cf').
-func (s *emitState) emitCounterDataFile(finalHash [16]byte, w io.Writer) error {
- cfw := encodecounter.NewCoverageDataWriter(w, coverage.CtrULeb128)
- if err := cfw.Write(finalHash, capturedOsArgs, s); err != nil {
- return err
- }
- return nil
-}
-
-// markProfileEmitted signals the runtime/coverage machinery that
-// coverate data output files have already been written out, and there
-// is no need to take any additional action at exit time. This
-// function is called (via linknamed reference) from the
-// coverage-related boilerplate code in _testmain.go emitted for go
-// unit tests.
-func markProfileEmitted(val bool) {
- covProfileAlreadyEmitted = val
-}
-
-func reportErrorInHardcodedList(slot, pkgID int32, fnID, nCtrs uint32) {
- metaList := getCovMetaList()
- pkgMap := getCovPkgMap()
-
- println("internal error in coverage meta-data tracking:")
- println("encountered bad pkgID:", pkgID, " at slot:", slot,
- " fnID:", fnID, " numCtrs:", nCtrs)
- println("list of hard-coded runtime package IDs needs revising.")
- println("[see the comment on the 'rtPkgs' var in ")
- println(" <goroot>/src/internal/coverage/pkid.go]")
- println("registered list:")
- for k, b := range metaList {
- print("slot: ", k, " path='", b.PkgPath, "' ")
- if b.PkgID != -1 {
- print(" hard-coded id: ", b.PkgID)
- }
- println("")
- }
- println("remap table:")
- for from, to := range pkgMap {
- println("from ", from, " to ", to)
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/coverage/testsupport.go b/contrib/go/_std_1.20/src/runtime/coverage/testsupport.go
deleted file mode 100644
index a481bbbd9d..0000000000
--- a/contrib/go/_std_1.20/src/runtime/coverage/testsupport.go
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright 2022 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 coverage
-
-import (
- "fmt"
- "internal/coverage"
- "internal/coverage/calloc"
- "internal/coverage/cformat"
- "internal/coverage/cmerge"
- "internal/coverage/decodecounter"
- "internal/coverage/decodemeta"
- "internal/coverage/pods"
- "io"
- "os"
- "strings"
-)
-
-// processCoverTestDir is called (via a linknamed reference) from
-// testmain code when "go test -cover" is in effect. It is not
-// intended to be used other than internally by the Go command's
-// generated code.
-func processCoverTestDir(dir string, cfile string, cm string, cpkg string) error {
- return processCoverTestDirInternal(dir, cfile, cm, cpkg, os.Stdout)
-}
-
-// processCoverTestDirInternal is an io.Writer version of processCoverTestDir,
-// exposed for unit testing.
-func processCoverTestDirInternal(dir string, cfile string, cm string, cpkg string, w io.Writer) error {
- cmode := coverage.ParseCounterMode(cm)
- if cmode == coverage.CtrModeInvalid {
- return fmt.Errorf("invalid counter mode %q", cm)
- }
-
- // Emit meta-data and counter data.
- ml := getCovMetaList()
- if len(ml) == 0 {
- // This corresponds to the case where we have a package that
- // contains test code but no functions (which is fine). In this
- // case there is no need to emit anything.
- } else {
- if err := emitMetaDataToDirectory(dir, ml); err != nil {
- return err
- }
- if err := emitCounterDataToDirectory(dir); err != nil {
- return err
- }
- }
-
- // Collect pods from test run. For the majority of cases we would
- // expect to see a single pod here, but allow for multiple pods in
- // case the test harness is doing extra work to collect data files
- // from builds that it kicks off as part of the testing.
- podlist, err := pods.CollectPods([]string{dir}, false)
- if err != nil {
- return fmt.Errorf("reading from %s: %v", dir, err)
- }
-
- // Open text output file if appropriate.
- var tf *os.File
- var tfClosed bool
- if cfile != "" {
- var err error
- tf, err = os.Create(cfile)
- if err != nil {
- return fmt.Errorf("internal error: opening coverage data output file %q: %v", cfile, err)
- }
- defer func() {
- if !tfClosed {
- tfClosed = true
- tf.Close()
- }
- }()
- }
-
- // Read/process the pods.
- ts := &tstate{
- cm: &cmerge.Merger{},
- cf: cformat.NewFormatter(cmode),
- cmode: cmode,
- }
- // Generate the expected hash string based on the final meta-data
- // hash for this test, then look only for pods that refer to that
- // hash (just in case there are multiple instrumented executables
- // in play). See issue #57924 for more on this.
- hashstring := fmt.Sprintf("%x", finalHash)
- for _, p := range podlist {
- if !strings.Contains(p.MetaFile, hashstring) {
- continue
- }
- if err := ts.processPod(p); err != nil {
- return err
- }
- }
-
- // Emit percent.
- if err := ts.cf.EmitPercent(w, cpkg, true); err != nil {
- return err
- }
-
- // Emit text output.
- if tf != nil {
- if err := ts.cf.EmitTextual(tf); err != nil {
- return err
- }
- tfClosed = true
- if err := tf.Close(); err != nil {
- return fmt.Errorf("closing %s: %v", cfile, err)
- }
- }
-
- return nil
-}
-
-type tstate struct {
- calloc.BatchCounterAlloc
- cm *cmerge.Merger
- cf *cformat.Formatter
- cmode coverage.CounterMode
-}
-
-// processPod reads coverage counter data for a specific pod.
-func (ts *tstate) processPod(p pods.Pod) error {
- // Open meta-data file
- f, err := os.Open(p.MetaFile)
- if err != nil {
- return fmt.Errorf("unable to open meta-data file %s: %v", p.MetaFile, err)
- }
- defer func() {
- f.Close()
- }()
- var mfr *decodemeta.CoverageMetaFileReader
- mfr, err = decodemeta.NewCoverageMetaFileReader(f, nil)
- if err != nil {
- return fmt.Errorf("error reading meta-data file %s: %v", p.MetaFile, err)
- }
- newmode := mfr.CounterMode()
- if newmode != ts.cmode {
- return fmt.Errorf("internal error: counter mode clash: %q from test harness, %q from data file %s", ts.cmode.String(), newmode.String(), p.MetaFile)
- }
- newgran := mfr.CounterGranularity()
- if err := ts.cm.SetModeAndGranularity(p.MetaFile, cmode, newgran); err != nil {
- return err
- }
-
- // A map to store counter data, indexed by pkgid/fnid tuple.
- pmm := make(map[pkfunc][]uint32)
-
- // Helper to read a single counter data file.
- readcdf := func(cdf string) error {
- cf, err := os.Open(cdf)
- if err != nil {
- return fmt.Errorf("opening counter data file %s: %s", cdf, err)
- }
- defer cf.Close()
- var cdr *decodecounter.CounterDataReader
- cdr, err = decodecounter.NewCounterDataReader(cdf, cf)
- if err != nil {
- return fmt.Errorf("reading counter data file %s: %s", cdf, err)
- }
- var data decodecounter.FuncPayload
- for {
- ok, err := cdr.NextFunc(&data)
- if err != nil {
- return fmt.Errorf("reading counter data file %s: %v", cdf, err)
- }
- if !ok {
- break
- }
-
- // NB: sanity check on pkg and func IDs?
- key := pkfunc{pk: data.PkgIdx, fcn: data.FuncIdx}
- if prev, found := pmm[key]; found {
- // Note: no overflow reporting here.
- if err, _ := ts.cm.MergeCounters(data.Counters, prev); err != nil {
- return fmt.Errorf("processing counter data file %s: %v", cdf, err)
- }
- }
- c := ts.AllocateCounters(len(data.Counters))
- copy(c, data.Counters)
- pmm[key] = c
- }
- return nil
- }
-
- // Read counter data files.
- for _, cdf := range p.CounterDataFiles {
- if err := readcdf(cdf); err != nil {
- return err
- }
- }
-
- // Visit meta-data file.
- np := uint32(mfr.NumPackages())
- payload := []byte{}
- for pkIdx := uint32(0); pkIdx < np; pkIdx++ {
- var pd *decodemeta.CoverageMetaDataDecoder
- pd, payload, err = mfr.GetPackageDecoder(pkIdx, payload)
- if err != nil {
- return fmt.Errorf("reading pkg %d from meta-file %s: %s", pkIdx, p.MetaFile, err)
- }
- ts.cf.SetPackage(pd.PackagePath())
- var fd coverage.FuncDesc
- nf := pd.NumFuncs()
- for fnIdx := uint32(0); fnIdx < nf; fnIdx++ {
- if err := pd.ReadFunc(fnIdx, &fd); err != nil {
- return fmt.Errorf("reading meta-data file %s: %v",
- p.MetaFile, err)
- }
- key := pkfunc{pk: pkIdx, fcn: fnIdx}
- counters, haveCounters := pmm[key]
- for i := 0; i < len(fd.Units); i++ {
- u := fd.Units[i]
- // Skip units with non-zero parent (no way to represent
- // these in the existing format).
- if u.Parent != 0 {
- continue
- }
- count := uint32(0)
- if haveCounters {
- count = counters[i]
- }
- ts.cf.AddUnit(fd.Srcfile, fd.Funcname, fd.Lit, u, count)
- }
- }
- }
- return nil
-}
-
-type pkfunc struct {
- pk, fcn uint32
-}
diff --git a/contrib/go/_std_1.20/src/runtime/coverage/ya.make b/contrib/go/_std_1.20/src/runtime/coverage/ya.make
deleted file mode 100644
index 2412dbafd8..0000000000
--- a/contrib/go/_std_1.20/src/runtime/coverage/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- apis.go
- dummy.s
- emit.go
- hooks.go
- testsupport.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/runtime/cpuflags_arm64.go b/contrib/go/_std_1.20/src/runtime/cpuflags_arm64.go
deleted file mode 100644
index a0f1d114d8..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cpuflags_arm64.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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 runtime
-
-import (
- "internal/cpu"
-)
-
-var arm64UseAlignedLoads bool
-
-func init() {
- if cpu.ARM64.IsNeoverseN1 || cpu.ARM64.IsNeoverseV1 {
- arm64UseAlignedLoads = true
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cpuprof.go b/contrib/go/_std_1.20/src/runtime/cpuprof.go
deleted file mode 100644
index 6ef374eaa4..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cpuprof.go
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2011 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.
-
-// CPU profiling.
-//
-// The signal handler for the profiling clock tick adds a new stack trace
-// to a log of recent traces. The log is read by a user goroutine that
-// turns it into formatted profile data. If the reader does not keep up
-// with the log, those writes will be recorded as a count of lost records.
-// The actual profile buffer is in profbuf.go.
-
-package runtime
-
-import (
- "internal/abi"
- "runtime/internal/sys"
- "unsafe"
-)
-
-const (
- maxCPUProfStack = 64
-
- // profBufWordCount is the size of the CPU profile buffer's storage for the
- // header and stack of each sample, measured in 64-bit words. Every sample
- // has a required header of two words. With a small additional header (a
- // word or two) and stacks at the profiler's maximum length of 64 frames,
- // that capacity can support 1900 samples or 19 thread-seconds at a 100 Hz
- // sample rate, at a cost of 1 MiB.
- profBufWordCount = 1 << 17
- // profBufTagCount is the size of the CPU profile buffer's storage for the
- // goroutine tags associated with each sample. A capacity of 1<<14 means
- // room for 16k samples, or 160 thread-seconds at a 100 Hz sample rate.
- profBufTagCount = 1 << 14
-)
-
-type cpuProfile struct {
- lock mutex
- on bool // profiling is on
- log *profBuf // profile events written here
-
- // extra holds extra stacks accumulated in addNonGo
- // corresponding to profiling signals arriving on
- // non-Go-created threads. Those stacks are written
- // to log the next time a normal Go thread gets the
- // signal handler.
- // Assuming the stacks are 2 words each (we don't get
- // a full traceback from those threads), plus one word
- // size for framing, 100 Hz profiling would generate
- // 300 words per second.
- // Hopefully a normal Go thread will get the profiling
- // signal at least once every few seconds.
- extra [1000]uintptr
- numExtra int
- lostExtra uint64 // count of frames lost because extra is full
- lostAtomic uint64 // count of frames lost because of being in atomic64 on mips/arm; updated racily
-}
-
-var cpuprof cpuProfile
-
-// SetCPUProfileRate sets the CPU profiling rate to hz samples per second.
-// If hz <= 0, SetCPUProfileRate turns off profiling.
-// If the profiler is on, the rate cannot be changed without first turning it off.
-//
-// Most clients should use the runtime/pprof package or
-// the testing package's -test.cpuprofile flag instead of calling
-// SetCPUProfileRate directly.
-func SetCPUProfileRate(hz int) {
- // Clamp hz to something reasonable.
- if hz < 0 {
- hz = 0
- }
- if hz > 1000000 {
- hz = 1000000
- }
-
- lock(&cpuprof.lock)
- if hz > 0 {
- if cpuprof.on || cpuprof.log != nil {
- print("runtime: cannot set cpu profile rate until previous profile has finished.\n")
- unlock(&cpuprof.lock)
- return
- }
-
- cpuprof.on = true
- cpuprof.log = newProfBuf(1, profBufWordCount, profBufTagCount)
- hdr := [1]uint64{uint64(hz)}
- cpuprof.log.write(nil, nanotime(), hdr[:], nil)
- setcpuprofilerate(int32(hz))
- } else if cpuprof.on {
- setcpuprofilerate(0)
- cpuprof.on = false
- cpuprof.addExtra()
- cpuprof.log.close()
- }
- unlock(&cpuprof.lock)
-}
-
-// add adds the stack trace to the profile.
-// It is called from signal handlers and other limited environments
-// and cannot allocate memory or acquire locks that might be
-// held at the time of the signal, nor can it use substantial amounts
-// of stack.
-//
-//go:nowritebarrierrec
-func (p *cpuProfile) add(tagPtr *unsafe.Pointer, stk []uintptr) {
- // Simple cas-lock to coordinate with setcpuprofilerate.
- for !prof.signalLock.CompareAndSwap(0, 1) {
- // TODO: Is it safe to osyield here? https://go.dev/issue/52672
- osyield()
- }
-
- if prof.hz.Load() != 0 { // implies cpuprof.log != nil
- if p.numExtra > 0 || p.lostExtra > 0 || p.lostAtomic > 0 {
- p.addExtra()
- }
- hdr := [1]uint64{1}
- // Note: write "knows" that the argument is &gp.labels,
- // because otherwise its write barrier behavior may not
- // be correct. See the long comment there before
- // changing the argument here.
- cpuprof.log.write(tagPtr, nanotime(), hdr[:], stk)
- }
-
- prof.signalLock.Store(0)
-}
-
-// addNonGo adds the non-Go stack trace to the profile.
-// It is called from a non-Go thread, so we cannot use much stack at all,
-// nor do anything that needs a g or an m.
-// In particular, we can't call cpuprof.log.write.
-// Instead, we copy the stack into cpuprof.extra,
-// which will be drained the next time a Go thread
-// gets the signal handling event.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func (p *cpuProfile) addNonGo(stk []uintptr) {
- // Simple cas-lock to coordinate with SetCPUProfileRate.
- // (Other calls to add or addNonGo should be blocked out
- // by the fact that only one SIGPROF can be handled by the
- // process at a time. If not, this lock will serialize those too.
- // The use of timer_create(2) on Linux to request process-targeted
- // signals may have changed this.)
- for !prof.signalLock.CompareAndSwap(0, 1) {
- // TODO: Is it safe to osyield here? https://go.dev/issue/52672
- osyield()
- }
-
- if cpuprof.numExtra+1+len(stk) < len(cpuprof.extra) {
- i := cpuprof.numExtra
- cpuprof.extra[i] = uintptr(1 + len(stk))
- copy(cpuprof.extra[i+1:], stk)
- cpuprof.numExtra += 1 + len(stk)
- } else {
- cpuprof.lostExtra++
- }
-
- prof.signalLock.Store(0)
-}
-
-// addExtra adds the "extra" profiling events,
-// queued by addNonGo, to the profile log.
-// addExtra is called either from a signal handler on a Go thread
-// or from an ordinary goroutine; either way it can use stack
-// and has a g. The world may be stopped, though.
-func (p *cpuProfile) addExtra() {
- // Copy accumulated non-Go profile events.
- hdr := [1]uint64{1}
- for i := 0; i < p.numExtra; {
- p.log.write(nil, 0, hdr[:], p.extra[i+1:i+int(p.extra[i])])
- i += int(p.extra[i])
- }
- p.numExtra = 0
-
- // Report any lost events.
- if p.lostExtra > 0 {
- hdr := [1]uint64{p.lostExtra}
- lostStk := [2]uintptr{
- abi.FuncPCABIInternal(_LostExternalCode) + sys.PCQuantum,
- abi.FuncPCABIInternal(_ExternalCode) + sys.PCQuantum,
- }
- p.log.write(nil, 0, hdr[:], lostStk[:])
- p.lostExtra = 0
- }
-
- if p.lostAtomic > 0 {
- hdr := [1]uint64{p.lostAtomic}
- lostStk := [2]uintptr{
- abi.FuncPCABIInternal(_LostSIGPROFDuringAtomic64) + sys.PCQuantum,
- abi.FuncPCABIInternal(_System) + sys.PCQuantum,
- }
- p.log.write(nil, 0, hdr[:], lostStk[:])
- p.lostAtomic = 0
- }
-
-}
-
-// CPUProfile panics.
-// It formerly provided raw access to chunks of
-// a pprof-format profile generated by the runtime.
-// The details of generating that format have changed,
-// so this functionality has been removed.
-//
-// Deprecated: Use the runtime/pprof package,
-// or the handlers in the net/http/pprof package,
-// or the testing package's -test.cpuprofile flag instead.
-func CPUProfile() []byte {
- panic("CPUProfile no longer available")
-}
-
-//go:linkname runtime_pprof_runtime_cyclesPerSecond runtime/pprof.runtime_cyclesPerSecond
-func runtime_pprof_runtime_cyclesPerSecond() int64 {
- return tickspersecond()
-}
-
-// readProfile, provided to runtime/pprof, returns the next chunk of
-// binary CPU profiling stack trace data, blocking until data is available.
-// If profiling is turned off and all the profile data accumulated while it was
-// on has been returned, readProfile returns eof=true.
-// The caller must save the returned data and tags before calling readProfile again.
-// The returned data contains a whole number of records, and tags contains
-// exactly one entry per record.
-//
-//go:linkname runtime_pprof_readProfile runtime/pprof.readProfile
-func runtime_pprof_readProfile() ([]uint64, []unsafe.Pointer, bool) {
- lock(&cpuprof.lock)
- log := cpuprof.log
- unlock(&cpuprof.lock)
- data, tags, eof := log.read(profBufBlocking)
- if len(data) == 0 && eof {
- lock(&cpuprof.lock)
- cpuprof.log = nil
- unlock(&cpuprof.lock)
- }
- return data, tags, eof
-}
diff --git a/contrib/go/_std_1.20/src/runtime/cputicks.go b/contrib/go/_std_1.20/src/runtime/cputicks.go
deleted file mode 100644
index 91270617fc..0000000000
--- a/contrib/go/_std_1.20/src/runtime/cputicks.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 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.
-
-//go:build !arm && !arm64 && !loong64 && !mips64 && !mips64le && !mips && !mipsle && !wasm
-
-package runtime
-
-// careful: cputicks is not guaranteed to be monotonic! In particular, we have
-// noticed drift between cpus on certain os/arch combinations. See issue 8976.
-func cputicks() int64
diff --git a/contrib/go/_std_1.20/src/runtime/debug.go b/contrib/go/_std_1.20/src/runtime/debug.go
deleted file mode 100644
index 669c36f0d5..0000000000
--- a/contrib/go/_std_1.20/src/runtime/debug.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2009 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 runtime
-
-import (
- "runtime/internal/atomic"
- "unsafe"
-)
-
-// GOMAXPROCS sets the maximum number of CPUs that can be executing
-// simultaneously and returns the previous setting. It defaults to
-// the value of runtime.NumCPU. If n < 1, it does not change the current setting.
-// This call will go away when the scheduler improves.
-func GOMAXPROCS(n int) int {
- if GOARCH == "wasm" && n > 1 {
- n = 1 // WebAssembly has no threads yet, so only one CPU is possible.
- }
-
- lock(&sched.lock)
- ret := int(gomaxprocs)
- unlock(&sched.lock)
- if n <= 0 || n == ret {
- return ret
- }
-
- stopTheWorldGC("GOMAXPROCS")
-
- // newprocs will be processed by startTheWorld
- newprocs = int32(n)
-
- startTheWorldGC()
- return ret
-}
-
-// NumCPU returns the number of logical CPUs usable by the current process.
-//
-// The set of available CPUs is checked by querying the operating system
-// at process startup. Changes to operating system CPU allocation after
-// process startup are not reflected.
-func NumCPU() int {
- return int(ncpu)
-}
-
-// NumCgoCall returns the number of cgo calls made by the current process.
-func NumCgoCall() int64 {
- var n = int64(atomic.Load64(&ncgocall))
- for mp := (*m)(atomic.Loadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink {
- n += int64(mp.ncgocall)
- }
- return n
-}
-
-// NumGoroutine returns the number of goroutines that currently exist.
-func NumGoroutine() int {
- return int(gcount())
-}
-
-//go:linkname debug_modinfo runtime/debug.modinfo
-func debug_modinfo() string {
- return modinfo
-}
-
-// mayMoreStackPreempt is a maymorestack hook that forces a preemption
-// at every possible cooperative preemption point.
-//
-// This is valuable to apply to the runtime, which can be sensitive to
-// preemption points. To apply this to all preemption points in the
-// runtime and runtime-like code, use the following in bash or zsh:
-//
-// X=(-{gc,asm}flags={runtime/...,reflect,sync}=-d=maymorestack=runtime.mayMoreStackPreempt) GOFLAGS=${X[@]}
-//
-// This must be deeply nosplit because it is called from a function
-// prologue before the stack is set up and because the compiler will
-// call it from any splittable prologue (leading to infinite
-// recursion).
-//
-// Ideally it should also use very little stack because the linker
-// doesn't currently account for this in nosplit stack depth checking.
-//
-// Ensure mayMoreStackPreempt can be called for all ABIs.
-//
-//go:nosplit
-//go:linkname mayMoreStackPreempt
-func mayMoreStackPreempt() {
- // Don't do anything on the g0 or gsignal stack.
- gp := getg()
- if gp == gp.m.g0 || gp == gp.m.gsignal {
- return
- }
- // Force a preemption, unless the stack is already poisoned.
- if gp.stackguard0 < stackPoisonMin {
- gp.stackguard0 = stackPreempt
- }
-}
-
-// mayMoreStackMove is a maymorestack hook that forces stack movement
-// at every possible point.
-//
-// See mayMoreStackPreempt.
-//
-//go:nosplit
-//go:linkname mayMoreStackMove
-func mayMoreStackMove() {
- // Don't do anything on the g0 or gsignal stack.
- gp := getg()
- if gp == gp.m.g0 || gp == gp.m.gsignal {
- return
- }
- // Force stack movement, unless the stack is already poisoned.
- if gp.stackguard0 < stackPoisonMin {
- gp.stackguard0 = stackForceMove
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/debug/mod.go b/contrib/go/_std_1.20/src/runtime/debug/mod.go
deleted file mode 100644
index 8b7a42305e..0000000000
--- a/contrib/go/_std_1.20/src/runtime/debug/mod.go
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2018 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 debug
-
-import (
- "fmt"
- "runtime"
- "strconv"
- "strings"
-)
-
-// exported from runtime.
-func modinfo() string
-
-// ReadBuildInfo returns the build information embedded
-// in the running binary. The information is available only
-// in binaries built with module support.
-func ReadBuildInfo() (info *BuildInfo, ok bool) {
- data := modinfo()
- if len(data) < 32 {
- return nil, false
- }
- data = data[16 : len(data)-16]
- bi, err := ParseBuildInfo(data)
- if err != nil {
- return nil, false
- }
-
- // The go version is stored separately from other build info, mostly for
- // historical reasons. It is not part of the modinfo() string, and
- // ParseBuildInfo does not recognize it. We inject it here to hide this
- // awkwardness from the user.
- bi.GoVersion = runtime.Version()
-
- return bi, true
-}
-
-// BuildInfo represents the build information read from a Go binary.
-type BuildInfo struct {
- // GoVersion is the version of the Go toolchain that built the binary
- // (for example, "go1.19.2").
- GoVersion string
-
- // Path is the package path of the main package for the binary
- // (for example, "golang.org/x/tools/cmd/stringer").
- Path string
-
- // Main describes the module that contains the main package for the binary.
- Main Module
-
- // Deps describes all the dependency modules, both direct and indirect,
- // that contributed packages to the build of this binary.
- Deps []*Module
-
- // Settings describes the build settings used to build the binary.
- Settings []BuildSetting
-}
-
-// A Module describes a single module included in a build.
-type Module struct {
- Path string // module path
- Version string // module version
- Sum string // checksum
- Replace *Module // replaced by this module
-}
-
-// A BuildSetting is a key-value pair describing one setting that influenced a build.
-//
-// Defined keys include:
-//
-// - -buildmode: the buildmode flag used (typically "exe")
-// - -compiler: the compiler toolchain flag used (typically "gc")
-// - CGO_ENABLED: the effective CGO_ENABLED environment variable
-// - CGO_CFLAGS: the effective CGO_CFLAGS environment variable
-// - CGO_CPPFLAGS: the effective CGO_CPPFLAGS environment variable
-// - CGO_CXXFLAGS: the effective CGO_CPPFLAGS environment variable
-// - CGO_LDFLAGS: the effective CGO_CPPFLAGS environment variable
-// - GOARCH: the architecture target
-// - GOAMD64/GOARM64/GO386/etc: the architecture feature level for GOARCH
-// - GOOS: the operating system target
-// - vcs: the version control system for the source tree where the build ran
-// - vcs.revision: the revision identifier for the current commit or checkout
-// - vcs.time: the modification time associated with vcs.revision, in RFC3339 format
-// - vcs.modified: true or false indicating whether the source tree had local modifications
-type BuildSetting struct {
- // Key and Value describe the build setting.
- // Key must not contain an equals sign, space, tab, or newline.
- // Value must not contain newlines ('\n').
- Key, Value string
-}
-
-// quoteKey reports whether key is required to be quoted.
-func quoteKey(key string) bool {
- return len(key) == 0 || strings.ContainsAny(key, "= \t\r\n\"`")
-}
-
-// quoteValue reports whether value is required to be quoted.
-func quoteValue(value string) bool {
- return strings.ContainsAny(value, " \t\r\n\"`")
-}
-
-func (bi *BuildInfo) String() string {
- buf := new(strings.Builder)
- if bi.GoVersion != "" {
- fmt.Fprintf(buf, "go\t%s\n", bi.GoVersion)
- }
- if bi.Path != "" {
- fmt.Fprintf(buf, "path\t%s\n", bi.Path)
- }
- var formatMod func(string, Module)
- formatMod = func(word string, m Module) {
- buf.WriteString(word)
- buf.WriteByte('\t')
- buf.WriteString(m.Path)
- buf.WriteByte('\t')
- buf.WriteString(m.Version)
- if m.Replace == nil {
- buf.WriteByte('\t')
- buf.WriteString(m.Sum)
- } else {
- buf.WriteByte('\n')
- formatMod("=>", *m.Replace)
- }
- buf.WriteByte('\n')
- }
- if bi.Main != (Module{}) {
- formatMod("mod", bi.Main)
- }
- for _, dep := range bi.Deps {
- formatMod("dep", *dep)
- }
- for _, s := range bi.Settings {
- key := s.Key
- if quoteKey(key) {
- key = strconv.Quote(key)
- }
- value := s.Value
- if quoteValue(value) {
- value = strconv.Quote(value)
- }
- fmt.Fprintf(buf, "build\t%s=%s\n", key, value)
- }
-
- return buf.String()
-}
-
-func ParseBuildInfo(data string) (bi *BuildInfo, err error) {
- lineNum := 1
- defer func() {
- if err != nil {
- err = fmt.Errorf("could not parse Go build info: line %d: %w", lineNum, err)
- }
- }()
-
- var (
- pathLine = "path\t"
- modLine = "mod\t"
- depLine = "dep\t"
- repLine = "=>\t"
- buildLine = "build\t"
- newline = "\n"
- tab = "\t"
- )
-
- readModuleLine := func(elem []string) (Module, error) {
- if len(elem) != 2 && len(elem) != 3 {
- return Module{}, fmt.Errorf("expected 2 or 3 columns; got %d", len(elem))
- }
- version := elem[1]
- sum := ""
- if len(elem) == 3 {
- sum = elem[2]
- }
- return Module{
- Path: elem[0],
- Version: version,
- Sum: sum,
- }, nil
- }
-
- bi = new(BuildInfo)
- var (
- last *Module
- line string
- ok bool
- )
- // Reverse of BuildInfo.String(), except for go version.
- for len(data) > 0 {
- line, data, ok = strings.Cut(data, newline)
- if !ok {
- break
- }
- switch {
- case strings.HasPrefix(line, pathLine):
- elem := line[len(pathLine):]
- bi.Path = string(elem)
- case strings.HasPrefix(line, modLine):
- elem := strings.Split(line[len(modLine):], tab)
- last = &bi.Main
- *last, err = readModuleLine(elem)
- if err != nil {
- return nil, err
- }
- case strings.HasPrefix(line, depLine):
- elem := strings.Split(line[len(depLine):], tab)
- last = new(Module)
- bi.Deps = append(bi.Deps, last)
- *last, err = readModuleLine(elem)
- if err != nil {
- return nil, err
- }
- case strings.HasPrefix(line, repLine):
- elem := strings.Split(line[len(repLine):], tab)
- if len(elem) != 3 {
- return nil, fmt.Errorf("expected 3 columns for replacement; got %d", len(elem))
- }
- if last == nil {
- return nil, fmt.Errorf("replacement with no module on previous line")
- }
- last.Replace = &Module{
- Path: string(elem[0]),
- Version: string(elem[1]),
- Sum: string(elem[2]),
- }
- last = nil
- case strings.HasPrefix(line, buildLine):
- kv := line[len(buildLine):]
- if len(kv) < 1 {
- return nil, fmt.Errorf("build line missing '='")
- }
-
- var key, rawValue string
- switch kv[0] {
- case '=':
- return nil, fmt.Errorf("build line with missing key")
-
- case '`', '"':
- rawKey, err := strconv.QuotedPrefix(kv)
- if err != nil {
- return nil, fmt.Errorf("invalid quoted key in build line")
- }
- if len(kv) == len(rawKey) {
- return nil, fmt.Errorf("build line missing '=' after quoted key")
- }
- if c := kv[len(rawKey)]; c != '=' {
- return nil, fmt.Errorf("unexpected character after quoted key: %q", c)
- }
- key, _ = strconv.Unquote(rawKey)
- rawValue = kv[len(rawKey)+1:]
-
- default:
- var ok bool
- key, rawValue, ok = strings.Cut(kv, "=")
- if !ok {
- return nil, fmt.Errorf("build line missing '=' after key")
- }
- if quoteKey(key) {
- return nil, fmt.Errorf("unquoted key %q must be quoted", key)
- }
- }
-
- var value string
- if len(rawValue) > 0 {
- switch rawValue[0] {
- case '`', '"':
- var err error
- value, err = strconv.Unquote(rawValue)
- if err != nil {
- return nil, fmt.Errorf("invalid quoted value in build line")
- }
-
- default:
- value = rawValue
- if quoteValue(value) {
- return nil, fmt.Errorf("unquoted value %q must be quoted", value)
- }
- }
- }
-
- bi.Settings = append(bi.Settings, BuildSetting{Key: key, Value: value})
- }
- lineNum++
- }
- return bi, nil
-}
diff --git a/contrib/go/_std_1.20/src/runtime/debug/ya.make b/contrib/go/_std_1.20/src/runtime/debug/ya.make
deleted file mode 100644
index 82972f18ed..0000000000
--- a/contrib/go/_std_1.20/src/runtime/debug/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- debug.s
- garbage.go
- mod.go
- stack.go
- stubs.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/runtime/debugcall.go b/contrib/go/_std_1.20/src/runtime/debugcall.go
deleted file mode 100644
index a4393b121a..0000000000
--- a/contrib/go/_std_1.20/src/runtime/debugcall.go
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2018 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.
-
-//go:build amd64 || arm64
-
-package runtime
-
-import "unsafe"
-
-const (
- debugCallSystemStack = "executing on Go runtime stack"
- debugCallUnknownFunc = "call from unknown function"
- debugCallRuntime = "call from within the Go runtime"
- debugCallUnsafePoint = "call not at safe point"
-)
-
-func debugCallV2()
-func debugCallPanicked(val any)
-
-// debugCallCheck checks whether it is safe to inject a debugger
-// function call with return PC pc. If not, it returns a string
-// explaining why.
-//
-//go:nosplit
-func debugCallCheck(pc uintptr) string {
- // No user calls from the system stack.
- if getg() != getg().m.curg {
- return debugCallSystemStack
- }
- if sp := getcallersp(); !(getg().stack.lo < sp && sp <= getg().stack.hi) {
- // Fast syscalls (nanotime) and racecall switch to the
- // g0 stack without switching g. We can't safely make
- // a call in this state. (We can't even safely
- // systemstack.)
- return debugCallSystemStack
- }
-
- // Switch to the system stack to avoid overflowing the user
- // stack.
- var ret string
- systemstack(func() {
- f := findfunc(pc)
- if !f.valid() {
- ret = debugCallUnknownFunc
- return
- }
-
- name := funcname(f)
-
- switch name {
- case "debugCall32",
- "debugCall64",
- "debugCall128",
- "debugCall256",
- "debugCall512",
- "debugCall1024",
- "debugCall2048",
- "debugCall4096",
- "debugCall8192",
- "debugCall16384",
- "debugCall32768",
- "debugCall65536":
- // These functions are allowed so that the debugger can initiate multiple function calls.
- // See: https://golang.org/cl/161137/
- return
- }
-
- // Disallow calls from the runtime. We could
- // potentially make this condition tighter (e.g., not
- // when locks are held), but there are enough tightly
- // coded sequences (e.g., defer handling) that it's
- // better to play it safe.
- if pfx := "runtime."; len(name) > len(pfx) && name[:len(pfx)] == pfx {
- ret = debugCallRuntime
- return
- }
-
- // Check that this isn't an unsafe-point.
- if pc != f.entry() {
- pc--
- }
- up := pcdatavalue(f, _PCDATA_UnsafePoint, pc, nil)
- if up != _PCDATA_UnsafePointSafe {
- // Not at a safe point.
- ret = debugCallUnsafePoint
- }
- })
- return ret
-}
-
-// debugCallWrap starts a new goroutine to run a debug call and blocks
-// the calling goroutine. On the goroutine, it prepares to recover
-// panics from the debug call, and then calls the call dispatching
-// function at PC dispatch.
-//
-// This must be deeply nosplit because there are untyped values on the
-// stack from debugCallV2.
-//
-//go:nosplit
-func debugCallWrap(dispatch uintptr) {
- var lockedm bool
- var lockedExt uint32
- callerpc := getcallerpc()
- gp := getg()
-
- // Create a new goroutine to execute the call on. Run this on
- // the system stack to avoid growing our stack.
- systemstack(func() {
- // TODO(mknyszek): It would be nice to wrap these arguments in an allocated
- // closure and start the goroutine with that closure, but the compiler disallows
- // implicit closure allocation in the runtime.
- fn := debugCallWrap1
- newg := newproc1(*(**funcval)(unsafe.Pointer(&fn)), gp, callerpc)
- args := &debugCallWrapArgs{
- dispatch: dispatch,
- callingG: gp,
- }
- newg.param = unsafe.Pointer(args)
-
- // If the current G is locked, then transfer that
- // locked-ness to the new goroutine.
- if gp.lockedm != 0 {
- // Save lock state to restore later.
- mp := gp.m
- if mp != gp.lockedm.ptr() {
- throw("inconsistent lockedm")
- }
-
- lockedm = true
- lockedExt = mp.lockedExt
-
- // Transfer external lock count to internal so
- // it can't be unlocked from the debug call.
- mp.lockedInt++
- mp.lockedExt = 0
-
- mp.lockedg.set(newg)
- newg.lockedm.set(mp)
- gp.lockedm = 0
- }
-
- // Mark the calling goroutine as being at an async
- // safe-point, since it has a few conservative frames
- // at the bottom of the stack. This also prevents
- // stack shrinks.
- gp.asyncSafePoint = true
-
- // Stash newg away so we can execute it below (mcall's
- // closure can't capture anything).
- gp.schedlink.set(newg)
- })
-
- // Switch to the new goroutine.
- mcall(func(gp *g) {
- // Get newg.
- newg := gp.schedlink.ptr()
- gp.schedlink = 0
-
- // Park the calling goroutine.
- if trace.enabled {
- traceGoPark(traceEvGoBlock, 1)
- }
- casGToWaiting(gp, _Grunning, waitReasonDebugCall)
- dropg()
-
- // Directly execute the new goroutine. The debug
- // protocol will continue on the new goroutine, so
- // it's important we not just let the scheduler do
- // this or it may resume a different goroutine.
- execute(newg, true)
- })
-
- // We'll resume here when the call returns.
-
- // Restore locked state.
- if lockedm {
- mp := gp.m
- mp.lockedExt = lockedExt
- mp.lockedInt--
- mp.lockedg.set(gp)
- gp.lockedm.set(mp)
- }
-
- gp.asyncSafePoint = false
-}
-
-type debugCallWrapArgs struct {
- dispatch uintptr
- callingG *g
-}
-
-// debugCallWrap1 is the continuation of debugCallWrap on the callee
-// goroutine.
-func debugCallWrap1() {
- gp := getg()
- args := (*debugCallWrapArgs)(gp.param)
- dispatch, callingG := args.dispatch, args.callingG
- gp.param = nil
-
- // Dispatch call and trap panics.
- debugCallWrap2(dispatch)
-
- // Resume the caller goroutine.
- getg().schedlink.set(callingG)
- mcall(func(gp *g) {
- callingG := gp.schedlink.ptr()
- gp.schedlink = 0
-
- // Unlock this goroutine from the M if necessary. The
- // calling G will relock.
- if gp.lockedm != 0 {
- gp.lockedm = 0
- gp.m.lockedg = 0
- }
-
- // Switch back to the calling goroutine. At some point
- // the scheduler will schedule us again and we'll
- // finish exiting.
- if trace.enabled {
- traceGoSched()
- }
- casgstatus(gp, _Grunning, _Grunnable)
- dropg()
- lock(&sched.lock)
- globrunqput(gp)
- unlock(&sched.lock)
-
- if trace.enabled {
- traceGoUnpark(callingG, 0)
- }
- casgstatus(callingG, _Gwaiting, _Grunnable)
- execute(callingG, true)
- })
-}
-
-func debugCallWrap2(dispatch uintptr) {
- // Call the dispatch function and trap panics.
- var dispatchF func()
- dispatchFV := funcval{dispatch}
- *(*unsafe.Pointer)(unsafe.Pointer(&dispatchF)) = noescape(unsafe.Pointer(&dispatchFV))
-
- var ok bool
- defer func() {
- if !ok {
- err := recover()
- debugCallPanicked(err)
- }
- }()
- dispatchF()
- ok = true
-}
diff --git a/contrib/go/_std_1.20/src/runtime/debuglog.go b/contrib/go/_std_1.20/src/runtime/debuglog.go
deleted file mode 100644
index b18774e6c0..0000000000
--- a/contrib/go/_std_1.20/src/runtime/debuglog.go
+++ /dev/null
@@ -1,831 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file provides an internal debug logging facility. The debug
-// log is a lightweight, in-memory, per-M ring buffer. By default, the
-// runtime prints the debug log on panic.
-//
-// To print something to the debug log, call dlog to obtain a dlogger
-// and use the methods on that to add values. The values will be
-// space-separated in the output (much like println).
-//
-// This facility can be enabled by passing -tags debuglog when
-// building. Without this tag, dlog calls compile to nothing.
-
-package runtime
-
-import (
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// debugLogBytes is the size of each per-M ring buffer. This is
-// allocated off-heap to avoid blowing up the M and hence the GC'd
-// heap size.
-const debugLogBytes = 16 << 10
-
-// debugLogStringLimit is the maximum number of bytes in a string.
-// Above this, the string will be truncated with "..(n more bytes).."
-const debugLogStringLimit = debugLogBytes / 8
-
-// dlog returns a debug logger. The caller can use methods on the
-// returned logger to add values, which will be space-separated in the
-// final output, much like println. The caller must call end() to
-// finish the message.
-//
-// dlog can be used from highly-constrained corners of the runtime: it
-// is safe to use in the signal handler, from within the write
-// barrier, from within the stack implementation, and in places that
-// must be recursively nosplit.
-//
-// This will be compiled away if built without the debuglog build tag.
-// However, argument construction may not be. If any of the arguments
-// are not literals or trivial expressions, consider protecting the
-// call with "if dlogEnabled".
-//
-//go:nosplit
-//go:nowritebarrierrec
-func dlog() *dlogger {
- if !dlogEnabled {
- return nil
- }
-
- // Get the time.
- tick, nano := uint64(cputicks()), uint64(nanotime())
-
- // Try to get a cached logger.
- l := getCachedDlogger()
-
- // If we couldn't get a cached logger, try to get one from the
- // global pool.
- if l == nil {
- allp := (*uintptr)(unsafe.Pointer(&allDloggers))
- all := (*dlogger)(unsafe.Pointer(atomic.Loaduintptr(allp)))
- for l1 := all; l1 != nil; l1 = l1.allLink {
- if l1.owned.Load() == 0 && l1.owned.CompareAndSwap(0, 1) {
- l = l1
- break
- }
- }
- }
-
- // If that failed, allocate a new logger.
- if l == nil {
- // Use sysAllocOS instead of sysAlloc because we want to interfere
- // with the runtime as little as possible, and sysAlloc updates accounting.
- l = (*dlogger)(sysAllocOS(unsafe.Sizeof(dlogger{})))
- if l == nil {
- throw("failed to allocate debug log")
- }
- l.w.r.data = &l.w.data
- l.owned.Store(1)
-
- // Prepend to allDloggers list.
- headp := (*uintptr)(unsafe.Pointer(&allDloggers))
- for {
- head := atomic.Loaduintptr(headp)
- l.allLink = (*dlogger)(unsafe.Pointer(head))
- if atomic.Casuintptr(headp, head, uintptr(unsafe.Pointer(l))) {
- break
- }
- }
- }
-
- // If the time delta is getting too high, write a new sync
- // packet. We set the limit so we don't write more than 6
- // bytes of delta in the record header.
- const deltaLimit = 1<<(3*7) - 1 // ~2ms between sync packets
- if tick-l.w.tick > deltaLimit || nano-l.w.nano > deltaLimit {
- l.w.writeSync(tick, nano)
- }
-
- // Reserve space for framing header.
- l.w.ensure(debugLogHeaderSize)
- l.w.write += debugLogHeaderSize
-
- // Write record header.
- l.w.uvarint(tick - l.w.tick)
- l.w.uvarint(nano - l.w.nano)
- gp := getg()
- if gp != nil && gp.m != nil && gp.m.p != 0 {
- l.w.varint(int64(gp.m.p.ptr().id))
- } else {
- l.w.varint(-1)
- }
-
- return l
-}
-
-// A dlogger writes to the debug log.
-//
-// To obtain a dlogger, call dlog(). When done with the dlogger, call
-// end().
-type dlogger struct {
- _ sys.NotInHeap
- w debugLogWriter
-
- // allLink is the next dlogger in the allDloggers list.
- allLink *dlogger
-
- // owned indicates that this dlogger is owned by an M. This is
- // accessed atomically.
- owned atomic.Uint32
-}
-
-// allDloggers is a list of all dloggers, linked through
-// dlogger.allLink. This is accessed atomically. This is prepend only,
-// so it doesn't need to protect against ABA races.
-var allDloggers *dlogger
-
-//go:nosplit
-func (l *dlogger) end() {
- if !dlogEnabled {
- return
- }
-
- // Fill in framing header.
- size := l.w.write - l.w.r.end
- if !l.w.writeFrameAt(l.w.r.end, size) {
- throw("record too large")
- }
-
- // Commit the record.
- l.w.r.end = l.w.write
-
- // Attempt to return this logger to the cache.
- if putCachedDlogger(l) {
- return
- }
-
- // Return the logger to the global pool.
- l.owned.Store(0)
-}
-
-const (
- debugLogUnknown = 1 + iota
- debugLogBoolTrue
- debugLogBoolFalse
- debugLogInt
- debugLogUint
- debugLogHex
- debugLogPtr
- debugLogString
- debugLogConstString
- debugLogStringOverflow
-
- debugLogPC
- debugLogTraceback
-)
-
-//go:nosplit
-func (l *dlogger) b(x bool) *dlogger {
- if !dlogEnabled {
- return l
- }
- if x {
- l.w.byte(debugLogBoolTrue)
- } else {
- l.w.byte(debugLogBoolFalse)
- }
- return l
-}
-
-//go:nosplit
-func (l *dlogger) i(x int) *dlogger {
- return l.i64(int64(x))
-}
-
-//go:nosplit
-func (l *dlogger) i8(x int8) *dlogger {
- return l.i64(int64(x))
-}
-
-//go:nosplit
-func (l *dlogger) i16(x int16) *dlogger {
- return l.i64(int64(x))
-}
-
-//go:nosplit
-func (l *dlogger) i32(x int32) *dlogger {
- return l.i64(int64(x))
-}
-
-//go:nosplit
-func (l *dlogger) i64(x int64) *dlogger {
- if !dlogEnabled {
- return l
- }
- l.w.byte(debugLogInt)
- l.w.varint(x)
- return l
-}
-
-//go:nosplit
-func (l *dlogger) u(x uint) *dlogger {
- return l.u64(uint64(x))
-}
-
-//go:nosplit
-func (l *dlogger) uptr(x uintptr) *dlogger {
- return l.u64(uint64(x))
-}
-
-//go:nosplit
-func (l *dlogger) u8(x uint8) *dlogger {
- return l.u64(uint64(x))
-}
-
-//go:nosplit
-func (l *dlogger) u16(x uint16) *dlogger {
- return l.u64(uint64(x))
-}
-
-//go:nosplit
-func (l *dlogger) u32(x uint32) *dlogger {
- return l.u64(uint64(x))
-}
-
-//go:nosplit
-func (l *dlogger) u64(x uint64) *dlogger {
- if !dlogEnabled {
- return l
- }
- l.w.byte(debugLogUint)
- l.w.uvarint(x)
- return l
-}
-
-//go:nosplit
-func (l *dlogger) hex(x uint64) *dlogger {
- if !dlogEnabled {
- return l
- }
- l.w.byte(debugLogHex)
- l.w.uvarint(x)
- return l
-}
-
-//go:nosplit
-func (l *dlogger) p(x any) *dlogger {
- if !dlogEnabled {
- return l
- }
- l.w.byte(debugLogPtr)
- if x == nil {
- l.w.uvarint(0)
- } else {
- v := efaceOf(&x)
- switch v._type.kind & kindMask {
- case kindChan, kindFunc, kindMap, kindPtr, kindUnsafePointer:
- l.w.uvarint(uint64(uintptr(v.data)))
- default:
- throw("not a pointer type")
- }
- }
- return l
-}
-
-//go:nosplit
-func (l *dlogger) s(x string) *dlogger {
- if !dlogEnabled {
- return l
- }
-
- strData := unsafe.StringData(x)
- datap := &firstmoduledata
- if len(x) > 4 && datap.etext <= uintptr(unsafe.Pointer(strData)) && uintptr(unsafe.Pointer(strData)) < datap.end {
- // String constants are in the rodata section, which
- // isn't recorded in moduledata. But it has to be
- // somewhere between etext and end.
- l.w.byte(debugLogConstString)
- l.w.uvarint(uint64(len(x)))
- l.w.uvarint(uint64(uintptr(unsafe.Pointer(strData)) - datap.etext))
- } else {
- l.w.byte(debugLogString)
- // We can't use unsafe.Slice as it may panic, which isn't safe
- // in this (potentially) nowritebarrier context.
- var b []byte
- bb := (*slice)(unsafe.Pointer(&b))
- bb.array = unsafe.Pointer(strData)
- bb.len, bb.cap = len(x), len(x)
- if len(b) > debugLogStringLimit {
- b = b[:debugLogStringLimit]
- }
- l.w.uvarint(uint64(len(b)))
- l.w.bytes(b)
- if len(b) != len(x) {
- l.w.byte(debugLogStringOverflow)
- l.w.uvarint(uint64(len(x) - len(b)))
- }
- }
- return l
-}
-
-//go:nosplit
-func (l *dlogger) pc(x uintptr) *dlogger {
- if !dlogEnabled {
- return l
- }
- l.w.byte(debugLogPC)
- l.w.uvarint(uint64(x))
- return l
-}
-
-//go:nosplit
-func (l *dlogger) traceback(x []uintptr) *dlogger {
- if !dlogEnabled {
- return l
- }
- l.w.byte(debugLogTraceback)
- l.w.uvarint(uint64(len(x)))
- for _, pc := range x {
- l.w.uvarint(uint64(pc))
- }
- return l
-}
-
-// A debugLogWriter is a ring buffer of binary debug log records.
-//
-// A log record consists of a 2-byte framing header and a sequence of
-// fields. The framing header gives the size of the record as a little
-// endian 16-bit value. Each field starts with a byte indicating its
-// type, followed by type-specific data. If the size in the framing
-// header is 0, it's a sync record consisting of two little endian
-// 64-bit values giving a new time base.
-//
-// Because this is a ring buffer, new records will eventually
-// overwrite old records. Hence, it maintains a reader that consumes
-// the log as it gets overwritten. That reader state is where an
-// actual log reader would start.
-type debugLogWriter struct {
- _ sys.NotInHeap
- write uint64
- data debugLogBuf
-
- // tick and nano are the time bases from the most recently
- // written sync record.
- tick, nano uint64
-
- // r is a reader that consumes records as they get overwritten
- // by the writer. It also acts as the initial reader state
- // when printing the log.
- r debugLogReader
-
- // buf is a scratch buffer for encoding. This is here to
- // reduce stack usage.
- buf [10]byte
-}
-
-type debugLogBuf struct {
- _ sys.NotInHeap
- b [debugLogBytes]byte
-}
-
-const (
- // debugLogHeaderSize is the number of bytes in the framing
- // header of every dlog record.
- debugLogHeaderSize = 2
-
- // debugLogSyncSize is the number of bytes in a sync record.
- debugLogSyncSize = debugLogHeaderSize + 2*8
-)
-
-//go:nosplit
-func (l *debugLogWriter) ensure(n uint64) {
- for l.write+n >= l.r.begin+uint64(len(l.data.b)) {
- // Consume record at begin.
- if l.r.skip() == ^uint64(0) {
- // Wrapped around within a record.
- //
- // TODO(austin): It would be better to just
- // eat the whole buffer at this point, but we
- // have to communicate that to the reader
- // somehow.
- throw("record wrapped around")
- }
- }
-}
-
-//go:nosplit
-func (l *debugLogWriter) writeFrameAt(pos, size uint64) bool {
- l.data.b[pos%uint64(len(l.data.b))] = uint8(size)
- l.data.b[(pos+1)%uint64(len(l.data.b))] = uint8(size >> 8)
- return size <= 0xFFFF
-}
-
-//go:nosplit
-func (l *debugLogWriter) writeSync(tick, nano uint64) {
- l.tick, l.nano = tick, nano
- l.ensure(debugLogHeaderSize)
- l.writeFrameAt(l.write, 0)
- l.write += debugLogHeaderSize
- l.writeUint64LE(tick)
- l.writeUint64LE(nano)
- l.r.end = l.write
-}
-
-//go:nosplit
-func (l *debugLogWriter) writeUint64LE(x uint64) {
- var b [8]byte
- b[0] = byte(x)
- b[1] = byte(x >> 8)
- b[2] = byte(x >> 16)
- b[3] = byte(x >> 24)
- b[4] = byte(x >> 32)
- b[5] = byte(x >> 40)
- b[6] = byte(x >> 48)
- b[7] = byte(x >> 56)
- l.bytes(b[:])
-}
-
-//go:nosplit
-func (l *debugLogWriter) byte(x byte) {
- l.ensure(1)
- pos := l.write
- l.write++
- l.data.b[pos%uint64(len(l.data.b))] = x
-}
-
-//go:nosplit
-func (l *debugLogWriter) bytes(x []byte) {
- l.ensure(uint64(len(x)))
- pos := l.write
- l.write += uint64(len(x))
- for len(x) > 0 {
- n := copy(l.data.b[pos%uint64(len(l.data.b)):], x)
- pos += uint64(n)
- x = x[n:]
- }
-}
-
-//go:nosplit
-func (l *debugLogWriter) varint(x int64) {
- var u uint64
- if x < 0 {
- u = (^uint64(x) << 1) | 1 // complement i, bit 0 is 1
- } else {
- u = (uint64(x) << 1) // do not complement i, bit 0 is 0
- }
- l.uvarint(u)
-}
-
-//go:nosplit
-func (l *debugLogWriter) uvarint(u uint64) {
- i := 0
- for u >= 0x80 {
- l.buf[i] = byte(u) | 0x80
- u >>= 7
- i++
- }
- l.buf[i] = byte(u)
- i++
- l.bytes(l.buf[:i])
-}
-
-type debugLogReader struct {
- data *debugLogBuf
-
- // begin and end are the positions in the log of the beginning
- // and end of the log data, modulo len(data).
- begin, end uint64
-
- // tick and nano are the current time base at begin.
- tick, nano uint64
-}
-
-//go:nosplit
-func (r *debugLogReader) skip() uint64 {
- // Read size at pos.
- if r.begin+debugLogHeaderSize > r.end {
- return ^uint64(0)
- }
- size := uint64(r.readUint16LEAt(r.begin))
- if size == 0 {
- // Sync packet.
- r.tick = r.readUint64LEAt(r.begin + debugLogHeaderSize)
- r.nano = r.readUint64LEAt(r.begin + debugLogHeaderSize + 8)
- size = debugLogSyncSize
- }
- if r.begin+size > r.end {
- return ^uint64(0)
- }
- r.begin += size
- return size
-}
-
-//go:nosplit
-func (r *debugLogReader) readUint16LEAt(pos uint64) uint16 {
- return uint16(r.data.b[pos%uint64(len(r.data.b))]) |
- uint16(r.data.b[(pos+1)%uint64(len(r.data.b))])<<8
-}
-
-//go:nosplit
-func (r *debugLogReader) readUint64LEAt(pos uint64) uint64 {
- var b [8]byte
- for i := range b {
- b[i] = r.data.b[pos%uint64(len(r.data.b))]
- pos++
- }
- return uint64(b[0]) | uint64(b[1])<<8 |
- uint64(b[2])<<16 | uint64(b[3])<<24 |
- uint64(b[4])<<32 | uint64(b[5])<<40 |
- uint64(b[6])<<48 | uint64(b[7])<<56
-}
-
-func (r *debugLogReader) peek() (tick uint64) {
- // Consume any sync records.
- size := uint64(0)
- for size == 0 {
- if r.begin+debugLogHeaderSize > r.end {
- return ^uint64(0)
- }
- size = uint64(r.readUint16LEAt(r.begin))
- if size != 0 {
- break
- }
- if r.begin+debugLogSyncSize > r.end {
- return ^uint64(0)
- }
- // Sync packet.
- r.tick = r.readUint64LEAt(r.begin + debugLogHeaderSize)
- r.nano = r.readUint64LEAt(r.begin + debugLogHeaderSize + 8)
- r.begin += debugLogSyncSize
- }
-
- // Peek tick delta.
- if r.begin+size > r.end {
- return ^uint64(0)
- }
- pos := r.begin + debugLogHeaderSize
- var u uint64
- for i := uint(0); ; i += 7 {
- b := r.data.b[pos%uint64(len(r.data.b))]
- pos++
- u |= uint64(b&^0x80) << i
- if b&0x80 == 0 {
- break
- }
- }
- if pos > r.begin+size {
- return ^uint64(0)
- }
- return r.tick + u
-}
-
-func (r *debugLogReader) header() (end, tick, nano uint64, p int) {
- // Read size. We've already skipped sync packets and checked
- // bounds in peek.
- size := uint64(r.readUint16LEAt(r.begin))
- end = r.begin + size
- r.begin += debugLogHeaderSize
-
- // Read tick, nano, and p.
- tick = r.uvarint() + r.tick
- nano = r.uvarint() + r.nano
- p = int(r.varint())
-
- return
-}
-
-func (r *debugLogReader) uvarint() uint64 {
- var u uint64
- for i := uint(0); ; i += 7 {
- b := r.data.b[r.begin%uint64(len(r.data.b))]
- r.begin++
- u |= uint64(b&^0x80) << i
- if b&0x80 == 0 {
- break
- }
- }
- return u
-}
-
-func (r *debugLogReader) varint() int64 {
- u := r.uvarint()
- var v int64
- if u&1 == 0 {
- v = int64(u >> 1)
- } else {
- v = ^int64(u >> 1)
- }
- return v
-}
-
-func (r *debugLogReader) printVal() bool {
- typ := r.data.b[r.begin%uint64(len(r.data.b))]
- r.begin++
-
- switch typ {
- default:
- print("<unknown field type ", hex(typ), " pos ", r.begin-1, " end ", r.end, ">\n")
- return false
-
- case debugLogUnknown:
- print("<unknown kind>")
-
- case debugLogBoolTrue:
- print(true)
-
- case debugLogBoolFalse:
- print(false)
-
- case debugLogInt:
- print(r.varint())
-
- case debugLogUint:
- print(r.uvarint())
-
- case debugLogHex, debugLogPtr:
- print(hex(r.uvarint()))
-
- case debugLogString:
- sl := r.uvarint()
- if r.begin+sl > r.end {
- r.begin = r.end
- print("<string length corrupted>")
- break
- }
- for sl > 0 {
- b := r.data.b[r.begin%uint64(len(r.data.b)):]
- if uint64(len(b)) > sl {
- b = b[:sl]
- }
- r.begin += uint64(len(b))
- sl -= uint64(len(b))
- gwrite(b)
- }
-
- case debugLogConstString:
- len, ptr := int(r.uvarint()), uintptr(r.uvarint())
- ptr += firstmoduledata.etext
- // We can't use unsafe.String as it may panic, which isn't safe
- // in this (potentially) nowritebarrier context.
- str := stringStruct{
- str: unsafe.Pointer(ptr),
- len: len,
- }
- s := *(*string)(unsafe.Pointer(&str))
- print(s)
-
- case debugLogStringOverflow:
- print("..(", r.uvarint(), " more bytes)..")
-
- case debugLogPC:
- printDebugLogPC(uintptr(r.uvarint()), false)
-
- case debugLogTraceback:
- n := int(r.uvarint())
- for i := 0; i < n; i++ {
- print("\n\t")
- // gentraceback PCs are always return PCs.
- // Convert them to call PCs.
- //
- // TODO(austin): Expand inlined frames.
- printDebugLogPC(uintptr(r.uvarint()), true)
- }
- }
-
- return true
-}
-
-// printDebugLog prints the debug log.
-func printDebugLog() {
- if !dlogEnabled {
- return
- }
-
- // This function should not panic or throw since it is used in
- // the fatal panic path and this may deadlock.
-
- printlock()
-
- // Get the list of all debug logs.
- allp := (*uintptr)(unsafe.Pointer(&allDloggers))
- all := (*dlogger)(unsafe.Pointer(atomic.Loaduintptr(allp)))
-
- // Count the logs.
- n := 0
- for l := all; l != nil; l = l.allLink {
- n++
- }
- if n == 0 {
- printunlock()
- return
- }
-
- // Prepare read state for all logs.
- type readState struct {
- debugLogReader
- first bool
- lost uint64
- nextTick uint64
- }
- // Use sysAllocOS instead of sysAlloc because we want to interfere
- // with the runtime as little as possible, and sysAlloc updates accounting.
- state1 := sysAllocOS(unsafe.Sizeof(readState{}) * uintptr(n))
- if state1 == nil {
- println("failed to allocate read state for", n, "logs")
- printunlock()
- return
- }
- state := (*[1 << 20]readState)(state1)[:n]
- {
- l := all
- for i := range state {
- s := &state[i]
- s.debugLogReader = l.w.r
- s.first = true
- s.lost = l.w.r.begin
- s.nextTick = s.peek()
- l = l.allLink
- }
- }
-
- // Print records.
- for {
- // Find the next record.
- var best struct {
- tick uint64
- i int
- }
- best.tick = ^uint64(0)
- for i := range state {
- if state[i].nextTick < best.tick {
- best.tick = state[i].nextTick
- best.i = i
- }
- }
- if best.tick == ^uint64(0) {
- break
- }
-
- // Print record.
- s := &state[best.i]
- if s.first {
- print(">> begin log ", best.i)
- if s.lost != 0 {
- print("; lost first ", s.lost>>10, "KB")
- }
- print(" <<\n")
- s.first = false
- }
-
- end, _, nano, p := s.header()
- oldEnd := s.end
- s.end = end
-
- print("[")
- var tmpbuf [21]byte
- pnano := int64(nano) - runtimeInitTime
- if pnano < 0 {
- // Logged before runtimeInitTime was set.
- pnano = 0
- }
- pnanoBytes := itoaDiv(tmpbuf[:], uint64(pnano), 9)
- print(slicebytetostringtmp((*byte)(noescape(unsafe.Pointer(&pnanoBytes[0]))), len(pnanoBytes)))
- print(" P ", p, "] ")
-
- for i := 0; s.begin < s.end; i++ {
- if i > 0 {
- print(" ")
- }
- if !s.printVal() {
- // Abort this P log.
- print("<aborting P log>")
- end = oldEnd
- break
- }
- }
- println()
-
- // Move on to the next record.
- s.begin = end
- s.end = oldEnd
- s.nextTick = s.peek()
- }
-
- printunlock()
-}
-
-// printDebugLogPC prints a single symbolized PC. If returnPC is true,
-// pc is a return PC that must first be converted to a call PC.
-func printDebugLogPC(pc uintptr, returnPC bool) {
- fn := findfunc(pc)
- if returnPC && (!fn.valid() || pc > fn.entry()) {
- // TODO(austin): Don't back up if the previous frame
- // was a sigpanic.
- pc--
- }
-
- print(hex(pc))
- if !fn.valid() {
- print(" [unknown PC]")
- } else {
- name := funcname(fn)
- file, line := funcline(fn, pc)
- print(" [", name, "+", hex(pc-fn.entry()),
- " ", file, ":", line, "]")
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/defs_darwin_amd64.go b/contrib/go/_std_1.20/src/runtime/defs_darwin_amd64.go
deleted file mode 100644
index 84e6f37203..0000000000
--- a/contrib/go/_std_1.20/src/runtime/defs_darwin_amd64.go
+++ /dev/null
@@ -1,375 +0,0 @@
-// created by cgo -cdefs and then converted to Go
-// cgo -cdefs defs_darwin.go
-
-package runtime
-
-import "unsafe"
-
-const (
- _EINTR = 0x4
- _EFAULT = 0xe
- _EAGAIN = 0x23
- _ETIMEDOUT = 0x3c
-
- _PROT_NONE = 0x0
- _PROT_READ = 0x1
- _PROT_WRITE = 0x2
- _PROT_EXEC = 0x4
-
- _MAP_ANON = 0x1000
- _MAP_PRIVATE = 0x2
- _MAP_FIXED = 0x10
-
- _MADV_DONTNEED = 0x4
- _MADV_FREE = 0x5
- _MADV_FREE_REUSABLE = 0x7
- _MADV_FREE_REUSE = 0x8
-
- _SA_SIGINFO = 0x40
- _SA_RESTART = 0x2
- _SA_ONSTACK = 0x1
- _SA_USERTRAMP = 0x100
- _SA_64REGSET = 0x200
-
- _SIGHUP = 0x1
- _SIGINT = 0x2
- _SIGQUIT = 0x3
- _SIGILL = 0x4
- _SIGTRAP = 0x5
- _SIGABRT = 0x6
- _SIGEMT = 0x7
- _SIGFPE = 0x8
- _SIGKILL = 0x9
- _SIGBUS = 0xa
- _SIGSEGV = 0xb
- _SIGSYS = 0xc
- _SIGPIPE = 0xd
- _SIGALRM = 0xe
- _SIGTERM = 0xf
- _SIGURG = 0x10
- _SIGSTOP = 0x11
- _SIGTSTP = 0x12
- _SIGCONT = 0x13
- _SIGCHLD = 0x14
- _SIGTTIN = 0x15
- _SIGTTOU = 0x16
- _SIGIO = 0x17
- _SIGXCPU = 0x18
- _SIGXFSZ = 0x19
- _SIGVTALRM = 0x1a
- _SIGPROF = 0x1b
- _SIGWINCH = 0x1c
- _SIGINFO = 0x1d
- _SIGUSR1 = 0x1e
- _SIGUSR2 = 0x1f
-
- _FPE_INTDIV = 0x7
- _FPE_INTOVF = 0x8
- _FPE_FLTDIV = 0x1
- _FPE_FLTOVF = 0x2
- _FPE_FLTUND = 0x3
- _FPE_FLTRES = 0x4
- _FPE_FLTINV = 0x5
- _FPE_FLTSUB = 0x6
-
- _BUS_ADRALN = 0x1
- _BUS_ADRERR = 0x2
- _BUS_OBJERR = 0x3
-
- _SEGV_MAPERR = 0x1
- _SEGV_ACCERR = 0x2
-
- _ITIMER_REAL = 0x0
- _ITIMER_VIRTUAL = 0x1
- _ITIMER_PROF = 0x2
-
- _EV_ADD = 0x1
- _EV_DELETE = 0x2
- _EV_CLEAR = 0x20
- _EV_RECEIPT = 0x40
- _EV_ERROR = 0x4000
- _EV_EOF = 0x8000
- _EVFILT_READ = -0x1
- _EVFILT_WRITE = -0x2
-
- _PTHREAD_CREATE_DETACHED = 0x2
-
- _F_SETFD = 0x2
- _F_GETFL = 0x3
- _F_SETFL = 0x4
- _FD_CLOEXEC = 0x1
-
- _O_WRONLY = 0x1
- _O_NONBLOCK = 0x4
- _O_CREAT = 0x200
- _O_TRUNC = 0x400
-)
-
-type stackt struct {
- ss_sp *byte
- ss_size uintptr
- ss_flags int32
- pad_cgo_0 [4]byte
-}
-
-type sigactiont struct {
- __sigaction_u [8]byte
- sa_tramp unsafe.Pointer
- sa_mask uint32
- sa_flags int32
-}
-
-type usigactiont struct {
- __sigaction_u [8]byte
- sa_mask uint32
- sa_flags int32
-}
-
-type siginfo struct {
- si_signo int32
- si_errno int32
- si_code int32
- si_pid int32
- si_uid uint32
- si_status int32
- si_addr uint64
- si_value [8]byte
- si_band int64
- __pad [7]uint64
-}
-
-type timeval struct {
- tv_sec int64
- tv_usec int32
- pad_cgo_0 [4]byte
-}
-
-func (tv *timeval) set_usec(x int32) {
- tv.tv_usec = x
-}
-
-type itimerval struct {
- it_interval timeval
- it_value timeval
-}
-
-type timespec struct {
- tv_sec int64
- tv_nsec int64
-}
-
-//go:nosplit
-func (ts *timespec) setNsec(ns int64) {
- ts.tv_sec = ns / 1e9
- ts.tv_nsec = ns % 1e9
-}
-
-type fpcontrol struct {
- pad_cgo_0 [2]byte
-}
-
-type fpstatus struct {
- pad_cgo_0 [2]byte
-}
-
-type regmmst struct {
- mmst_reg [10]int8
- mmst_rsrv [6]int8
-}
-
-type regxmm struct {
- xmm_reg [16]int8
-}
-
-type regs64 struct {
- rax uint64
- rbx uint64
- rcx uint64
- rdx uint64
- rdi uint64
- rsi uint64
- rbp uint64
- rsp uint64
- r8 uint64
- r9 uint64
- r10 uint64
- r11 uint64
- r12 uint64
- r13 uint64
- r14 uint64
- r15 uint64
- rip uint64
- rflags uint64
- cs uint64
- fs uint64
- gs uint64
-}
-
-type floatstate64 struct {
- fpu_reserved [2]int32
- fpu_fcw fpcontrol
- fpu_fsw fpstatus
- fpu_ftw uint8
- fpu_rsrv1 uint8
- fpu_fop uint16
- fpu_ip uint32
- fpu_cs uint16
- fpu_rsrv2 uint16
- fpu_dp uint32
- fpu_ds uint16
- fpu_rsrv3 uint16
- fpu_mxcsr uint32
- fpu_mxcsrmask uint32
- fpu_stmm0 regmmst
- fpu_stmm1 regmmst
- fpu_stmm2 regmmst
- fpu_stmm3 regmmst
- fpu_stmm4 regmmst
- fpu_stmm5 regmmst
- fpu_stmm6 regmmst
- fpu_stmm7 regmmst
- fpu_xmm0 regxmm
- fpu_xmm1 regxmm
- fpu_xmm2 regxmm
- fpu_xmm3 regxmm
- fpu_xmm4 regxmm
- fpu_xmm5 regxmm
- fpu_xmm6 regxmm
- fpu_xmm7 regxmm
- fpu_xmm8 regxmm
- fpu_xmm9 regxmm
- fpu_xmm10 regxmm
- fpu_xmm11 regxmm
- fpu_xmm12 regxmm
- fpu_xmm13 regxmm
- fpu_xmm14 regxmm
- fpu_xmm15 regxmm
- fpu_rsrv4 [96]int8
- fpu_reserved1 int32
-}
-
-type exceptionstate64 struct {
- trapno uint16
- cpu uint16
- err uint32
- faultvaddr uint64
-}
-
-type mcontext64 struct {
- es exceptionstate64
- ss regs64
- fs floatstate64
- pad_cgo_0 [4]byte
-}
-
-type regs32 struct {
- eax uint32
- ebx uint32
- ecx uint32
- edx uint32
- edi uint32
- esi uint32
- ebp uint32
- esp uint32
- ss uint32
- eflags uint32
- eip uint32
- cs uint32
- ds uint32
- es uint32
- fs uint32
- gs uint32
-}
-
-type floatstate32 struct {
- fpu_reserved [2]int32
- fpu_fcw fpcontrol
- fpu_fsw fpstatus
- fpu_ftw uint8
- fpu_rsrv1 uint8
- fpu_fop uint16
- fpu_ip uint32
- fpu_cs uint16
- fpu_rsrv2 uint16
- fpu_dp uint32
- fpu_ds uint16
- fpu_rsrv3 uint16
- fpu_mxcsr uint32
- fpu_mxcsrmask uint32
- fpu_stmm0 regmmst
- fpu_stmm1 regmmst
- fpu_stmm2 regmmst
- fpu_stmm3 regmmst
- fpu_stmm4 regmmst
- fpu_stmm5 regmmst
- fpu_stmm6 regmmst
- fpu_stmm7 regmmst
- fpu_xmm0 regxmm
- fpu_xmm1 regxmm
- fpu_xmm2 regxmm
- fpu_xmm3 regxmm
- fpu_xmm4 regxmm
- fpu_xmm5 regxmm
- fpu_xmm6 regxmm
- fpu_xmm7 regxmm
- fpu_rsrv4 [224]int8
- fpu_reserved1 int32
-}
-
-type exceptionstate32 struct {
- trapno uint16
- cpu uint16
- err uint32
- faultvaddr uint32
-}
-
-type mcontext32 struct {
- es exceptionstate32
- ss regs32
- fs floatstate32
-}
-
-type ucontext struct {
- uc_onstack int32
- uc_sigmask uint32
- uc_stack stackt
- uc_link *ucontext
- uc_mcsize uint64
- uc_mcontext *mcontext64
-}
-
-type keventt struct {
- ident uint64
- filter int16
- flags uint16
- fflags uint32
- data int64
- udata *byte
-}
-
-type pthread uintptr
-type pthreadattr struct {
- X__sig int64
- X__opaque [56]int8
-}
-type pthreadmutex struct {
- X__sig int64
- X__opaque [56]int8
-}
-type pthreadmutexattr struct {
- X__sig int64
- X__opaque [8]int8
-}
-type pthreadcond struct {
- X__sig int64
- X__opaque [40]int8
-}
-type pthreadcondattr struct {
- X__sig int64
- X__opaque [8]int8
-}
-
-type machTimebaseInfo struct {
- numer uint32
- denom uint32
-}
diff --git a/contrib/go/_std_1.20/src/runtime/defs_linux_amd64.go b/contrib/go/_std_1.20/src/runtime/defs_linux_amd64.go
deleted file mode 100644
index 298f3ebf7c..0000000000
--- a/contrib/go/_std_1.20/src/runtime/defs_linux_amd64.go
+++ /dev/null
@@ -1,288 +0,0 @@
-// created by cgo -cdefs and then converted to Go
-// cgo -cdefs defs_linux.go defs1_linux.go
-
-package runtime
-
-import "unsafe"
-
-const (
- _EINTR = 0x4
- _EAGAIN = 0xb
- _ENOMEM = 0xc
-
- _PROT_NONE = 0x0
- _PROT_READ = 0x1
- _PROT_WRITE = 0x2
- _PROT_EXEC = 0x4
-
- _MAP_ANON = 0x20
- _MAP_PRIVATE = 0x2
- _MAP_FIXED = 0x10
-
- _MADV_DONTNEED = 0x4
- _MADV_FREE = 0x8
- _MADV_HUGEPAGE = 0xe
- _MADV_NOHUGEPAGE = 0xf
-
- _SA_RESTART = 0x10000000
- _SA_ONSTACK = 0x8000000
- _SA_RESTORER = 0x4000000
- _SA_SIGINFO = 0x4
-
- _SI_KERNEL = 0x80
- _SI_TIMER = -0x2
-
- _SIGHUP = 0x1
- _SIGINT = 0x2
- _SIGQUIT = 0x3
- _SIGILL = 0x4
- _SIGTRAP = 0x5
- _SIGABRT = 0x6
- _SIGBUS = 0x7
- _SIGFPE = 0x8
- _SIGKILL = 0x9
- _SIGUSR1 = 0xa
- _SIGSEGV = 0xb
- _SIGUSR2 = 0xc
- _SIGPIPE = 0xd
- _SIGALRM = 0xe
- _SIGSTKFLT = 0x10
- _SIGCHLD = 0x11
- _SIGCONT = 0x12
- _SIGSTOP = 0x13
- _SIGTSTP = 0x14
- _SIGTTIN = 0x15
- _SIGTTOU = 0x16
- _SIGURG = 0x17
- _SIGXCPU = 0x18
- _SIGXFSZ = 0x19
- _SIGVTALRM = 0x1a
- _SIGPROF = 0x1b
- _SIGWINCH = 0x1c
- _SIGIO = 0x1d
- _SIGPWR = 0x1e
- _SIGSYS = 0x1f
-
- _SIGRTMIN = 0x20
-
- _FPE_INTDIV = 0x1
- _FPE_INTOVF = 0x2
- _FPE_FLTDIV = 0x3
- _FPE_FLTOVF = 0x4
- _FPE_FLTUND = 0x5
- _FPE_FLTRES = 0x6
- _FPE_FLTINV = 0x7
- _FPE_FLTSUB = 0x8
-
- _BUS_ADRALN = 0x1
- _BUS_ADRERR = 0x2
- _BUS_OBJERR = 0x3
-
- _SEGV_MAPERR = 0x1
- _SEGV_ACCERR = 0x2
-
- _ITIMER_REAL = 0x0
- _ITIMER_VIRTUAL = 0x1
- _ITIMER_PROF = 0x2
-
- _CLOCK_THREAD_CPUTIME_ID = 0x3
-
- _SIGEV_THREAD_ID = 0x4
-
- _AF_UNIX = 0x1
- _SOCK_DGRAM = 0x2
-)
-
-type timespec struct {
- tv_sec int64
- tv_nsec int64
-}
-
-//go:nosplit
-func (ts *timespec) setNsec(ns int64) {
- ts.tv_sec = ns / 1e9
- ts.tv_nsec = ns % 1e9
-}
-
-type timeval struct {
- tv_sec int64
- tv_usec int64
-}
-
-func (tv *timeval) set_usec(x int32) {
- tv.tv_usec = int64(x)
-}
-
-type sigactiont struct {
- sa_handler uintptr
- sa_flags uint64
- sa_restorer uintptr
- sa_mask uint64
-}
-
-type siginfoFields struct {
- si_signo int32
- si_errno int32
- si_code int32
- // below here is a union; si_addr is the only field we use
- si_addr uint64
-}
-
-type siginfo struct {
- siginfoFields
-
- // Pad struct to the max size in the kernel.
- _ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
-}
-
-type itimerspec struct {
- it_interval timespec
- it_value timespec
-}
-
-type itimerval struct {
- it_interval timeval
- it_value timeval
-}
-
-type sigeventFields struct {
- value uintptr
- signo int32
- notify int32
- // below here is a union; sigev_notify_thread_id is the only field we use
- sigev_notify_thread_id int32
-}
-
-type sigevent struct {
- sigeventFields
-
- // Pad struct to the max size in the kernel.
- _ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
-}
-
-// created by cgo -cdefs and then converted to Go
-// cgo -cdefs defs_linux.go defs1_linux.go
-
-const (
- _O_RDONLY = 0x0
- _O_WRONLY = 0x1
- _O_CREAT = 0x40
- _O_TRUNC = 0x200
- _O_NONBLOCK = 0x800
- _O_CLOEXEC = 0x80000
-)
-
-type usigset struct {
- __val [16]uint64
-}
-
-type fpxreg struct {
- significand [4]uint16
- exponent uint16
- padding [3]uint16
-}
-
-type xmmreg struct {
- element [4]uint32
-}
-
-type fpstate struct {
- cwd uint16
- swd uint16
- ftw uint16
- fop uint16
- rip uint64
- rdp uint64
- mxcsr uint32
- mxcr_mask uint32
- _st [8]fpxreg
- _xmm [16]xmmreg
- padding [24]uint32
-}
-
-type fpxreg1 struct {
- significand [4]uint16
- exponent uint16
- padding [3]uint16
-}
-
-type xmmreg1 struct {
- element [4]uint32
-}
-
-type fpstate1 struct {
- cwd uint16
- swd uint16
- ftw uint16
- fop uint16
- rip uint64
- rdp uint64
- mxcsr uint32
- mxcr_mask uint32
- _st [8]fpxreg1
- _xmm [16]xmmreg1
- padding [24]uint32
-}
-
-type fpreg1 struct {
- significand [4]uint16
- exponent uint16
-}
-
-type stackt struct {
- ss_sp *byte
- ss_flags int32
- pad_cgo_0 [4]byte
- ss_size uintptr
-}
-
-type mcontext struct {
- gregs [23]uint64
- fpregs *fpstate
- __reserved1 [8]uint64
-}
-
-type ucontext struct {
- uc_flags uint64
- uc_link *ucontext
- uc_stack stackt
- uc_mcontext mcontext
- uc_sigmask usigset
- __fpregs_mem fpstate
-}
-
-type sigcontext struct {
- r8 uint64
- r9 uint64
- r10 uint64
- r11 uint64
- r12 uint64
- r13 uint64
- r14 uint64
- r15 uint64
- rdi uint64
- rsi uint64
- rbp uint64
- rbx uint64
- rdx uint64
- rax uint64
- rcx uint64
- rsp uint64
- rip uint64
- eflags uint64
- cs uint16
- gs uint16
- fs uint16
- __pad0 uint16
- err uint64
- trapno uint64
- oldmask uint64
- cr2 uint64
- fpstate *fpstate1
- __reserved1 [8]uint64
-}
-
-type sockaddr_un struct {
- family uint16
- path [108]byte
-}
diff --git a/contrib/go/_std_1.20/src/runtime/defs_linux_arm64.go b/contrib/go/_std_1.20/src/runtime/defs_linux_arm64.go
deleted file mode 100644
index 0216096301..0000000000
--- a/contrib/go/_std_1.20/src/runtime/defs_linux_arm64.go
+++ /dev/null
@@ -1,210 +0,0 @@
-// Created by cgo -cdefs and converted (by hand) to Go
-// ../cmd/cgo/cgo -cdefs defs_linux.go defs1_linux.go defs2_linux.go
-
-package runtime
-
-import "unsafe"
-
-const (
- _EINTR = 0x4
- _EAGAIN = 0xb
- _ENOMEM = 0xc
-
- _PROT_NONE = 0x0
- _PROT_READ = 0x1
- _PROT_WRITE = 0x2
- _PROT_EXEC = 0x4
-
- _MAP_ANON = 0x20
- _MAP_PRIVATE = 0x2
- _MAP_FIXED = 0x10
-
- _MADV_DONTNEED = 0x4
- _MADV_FREE = 0x8
- _MADV_HUGEPAGE = 0xe
- _MADV_NOHUGEPAGE = 0xf
-
- _SA_RESTART = 0x10000000
- _SA_ONSTACK = 0x8000000
- _SA_RESTORER = 0x0 // Only used on intel
- _SA_SIGINFO = 0x4
-
- _SI_KERNEL = 0x80
- _SI_TIMER = -0x2
-
- _SIGHUP = 0x1
- _SIGINT = 0x2
- _SIGQUIT = 0x3
- _SIGILL = 0x4
- _SIGTRAP = 0x5
- _SIGABRT = 0x6
- _SIGBUS = 0x7
- _SIGFPE = 0x8
- _SIGKILL = 0x9
- _SIGUSR1 = 0xa
- _SIGSEGV = 0xb
- _SIGUSR2 = 0xc
- _SIGPIPE = 0xd
- _SIGALRM = 0xe
- _SIGSTKFLT = 0x10
- _SIGCHLD = 0x11
- _SIGCONT = 0x12
- _SIGSTOP = 0x13
- _SIGTSTP = 0x14
- _SIGTTIN = 0x15
- _SIGTTOU = 0x16
- _SIGURG = 0x17
- _SIGXCPU = 0x18
- _SIGXFSZ = 0x19
- _SIGVTALRM = 0x1a
- _SIGPROF = 0x1b
- _SIGWINCH = 0x1c
- _SIGIO = 0x1d
- _SIGPWR = 0x1e
- _SIGSYS = 0x1f
-
- _SIGRTMIN = 0x20
-
- _FPE_INTDIV = 0x1
- _FPE_INTOVF = 0x2
- _FPE_FLTDIV = 0x3
- _FPE_FLTOVF = 0x4
- _FPE_FLTUND = 0x5
- _FPE_FLTRES = 0x6
- _FPE_FLTINV = 0x7
- _FPE_FLTSUB = 0x8
-
- _BUS_ADRALN = 0x1
- _BUS_ADRERR = 0x2
- _BUS_OBJERR = 0x3
-
- _SEGV_MAPERR = 0x1
- _SEGV_ACCERR = 0x2
-
- _ITIMER_REAL = 0x0
- _ITIMER_VIRTUAL = 0x1
- _ITIMER_PROF = 0x2
-
- _CLOCK_THREAD_CPUTIME_ID = 0x3
-
- _SIGEV_THREAD_ID = 0x4
-
- _AF_UNIX = 0x1
- _SOCK_DGRAM = 0x2
-)
-
-type timespec struct {
- tv_sec int64
- tv_nsec int64
-}
-
-//go:nosplit
-func (ts *timespec) setNsec(ns int64) {
- ts.tv_sec = ns / 1e9
- ts.tv_nsec = ns % 1e9
-}
-
-type timeval struct {
- tv_sec int64
- tv_usec int64
-}
-
-func (tv *timeval) set_usec(x int32) {
- tv.tv_usec = int64(x)
-}
-
-type sigactiont struct {
- sa_handler uintptr
- sa_flags uint64
- sa_restorer uintptr
- sa_mask uint64
-}
-
-type siginfoFields struct {
- si_signo int32
- si_errno int32
- si_code int32
- // below here is a union; si_addr is the only field we use
- si_addr uint64
-}
-
-type siginfo struct {
- siginfoFields
-
- // Pad struct to the max size in the kernel.
- _ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
-}
-
-type itimerspec struct {
- it_interval timespec
- it_value timespec
-}
-
-type itimerval struct {
- it_interval timeval
- it_value timeval
-}
-
-type sigeventFields struct {
- value uintptr
- signo int32
- notify int32
- // below here is a union; sigev_notify_thread_id is the only field we use
- sigev_notify_thread_id int32
-}
-
-type sigevent struct {
- sigeventFields
-
- // Pad struct to the max size in the kernel.
- _ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
-}
-
-// Created by cgo -cdefs and then converted to Go by hand
-// ../cmd/cgo/cgo -cdefs defs_linux.go defs1_linux.go defs2_linux.go
-
-const (
- _O_RDONLY = 0x0
- _O_WRONLY = 0x1
- _O_CREAT = 0x40
- _O_TRUNC = 0x200
- _O_NONBLOCK = 0x800
- _O_CLOEXEC = 0x80000
-)
-
-type usigset struct {
- __val [16]uint64
-}
-
-type stackt struct {
- ss_sp *byte
- ss_flags int32
- pad_cgo_0 [4]byte
- ss_size uintptr
-}
-
-type sigcontext struct {
- fault_address uint64
- /* AArch64 registers */
- regs [31]uint64
- sp uint64
- pc uint64
- pstate uint64
- _pad [8]byte // __attribute__((__aligned__(16)))
- __reserved [4096]byte
-}
-
-type sockaddr_un struct {
- family uint16
- path [108]byte
-}
-
-type ucontext struct {
- uc_flags uint64
- uc_link *ucontext
- uc_stack stackt
- uc_sigmask uint64
- _pad [(1024 - 64) / 8]byte
- _pad2 [8]byte // sigcontext must be aligned to 16-byte
- uc_mcontext sigcontext
-}
diff --git a/contrib/go/_std_1.20/src/runtime/defs_windows.go b/contrib/go/_std_1.20/src/runtime/defs_windows.go
deleted file mode 100644
index 8d4e38120e..0000000000
--- a/contrib/go/_std_1.20/src/runtime/defs_windows.go
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2009 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.
-
-// Windows architecture-independent definitions.
-
-package runtime
-
-const (
- _PROT_NONE = 0
- _PROT_READ = 1
- _PROT_WRITE = 2
- _PROT_EXEC = 4
-
- _MAP_ANON = 1
- _MAP_PRIVATE = 2
-
- _DUPLICATE_SAME_ACCESS = 0x2
- _THREAD_PRIORITY_HIGHEST = 0x2
-
- _SIGINT = 0x2
- _SIGTERM = 0xF
- _CTRL_C_EVENT = 0x0
- _CTRL_BREAK_EVENT = 0x1
- _CTRL_CLOSE_EVENT = 0x2
- _CTRL_LOGOFF_EVENT = 0x5
- _CTRL_SHUTDOWN_EVENT = 0x6
-
- _EXCEPTION_ACCESS_VIOLATION = 0xc0000005
- _EXCEPTION_BREAKPOINT = 0x80000003
- _EXCEPTION_ILLEGAL_INSTRUCTION = 0xc000001d
- _EXCEPTION_FLT_DENORMAL_OPERAND = 0xc000008d
- _EXCEPTION_FLT_DIVIDE_BY_ZERO = 0xc000008e
- _EXCEPTION_FLT_INEXACT_RESULT = 0xc000008f
- _EXCEPTION_FLT_OVERFLOW = 0xc0000091
- _EXCEPTION_FLT_UNDERFLOW = 0xc0000093
- _EXCEPTION_INT_DIVIDE_BY_ZERO = 0xc0000094
- _EXCEPTION_INT_OVERFLOW = 0xc0000095
-
- _INFINITE = 0xffffffff
- _WAIT_TIMEOUT = 0x102
-
- _EXCEPTION_CONTINUE_EXECUTION = -0x1
- _EXCEPTION_CONTINUE_SEARCH = 0x0
-)
-
-type systeminfo struct {
- anon0 [4]byte
- dwpagesize uint32
- lpminimumapplicationaddress *byte
- lpmaximumapplicationaddress *byte
- dwactiveprocessormask uintptr
- dwnumberofprocessors uint32
- dwprocessortype uint32
- dwallocationgranularity uint32
- wprocessorlevel uint16
- wprocessorrevision uint16
-}
-
-type exceptionrecord struct {
- exceptioncode uint32
- exceptionflags uint32
- exceptionrecord *exceptionrecord
- exceptionaddress *byte
- numberparameters uint32
- exceptioninformation [15]uintptr
-}
-
-type overlapped struct {
- internal uintptr
- internalhigh uintptr
- anon0 [8]byte
- hevent *byte
-}
-
-type memoryBasicInformation struct {
- baseAddress uintptr
- allocationBase uintptr
- allocationProtect uint32
- regionSize uintptr
- state uint32
- protect uint32
- type_ uint32
-}
diff --git a/contrib/go/_std_1.20/src/runtime/defs_windows_amd64.go b/contrib/go/_std_1.20/src/runtime/defs_windows_amd64.go
deleted file mode 100644
index ac636a68ec..0000000000
--- a/contrib/go/_std_1.20/src/runtime/defs_windows_amd64.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2009 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 runtime
-
-const _CONTEXT_CONTROL = 0x100001
-
-type m128a struct {
- low uint64
- high int64
-}
-
-type context struct {
- p1home uint64
- p2home uint64
- p3home uint64
- p4home uint64
- p5home uint64
- p6home uint64
- contextflags uint32
- mxcsr uint32
- segcs uint16
- segds uint16
- seges uint16
- segfs uint16
- seggs uint16
- segss uint16
- eflags uint32
- dr0 uint64
- dr1 uint64
- dr2 uint64
- dr3 uint64
- dr6 uint64
- dr7 uint64
- rax uint64
- rcx uint64
- rdx uint64
- rbx uint64
- rsp uint64
- rbp uint64
- rsi uint64
- rdi uint64
- r8 uint64
- r9 uint64
- r10 uint64
- r11 uint64
- r12 uint64
- r13 uint64
- r14 uint64
- r15 uint64
- rip uint64
- anon0 [512]byte
- vectorregister [26]m128a
- vectorcontrol uint64
- debugcontrol uint64
- lastbranchtorip uint64
- lastbranchfromrip uint64
- lastexceptiontorip uint64
- lastexceptionfromrip uint64
-}
-
-func (c *context) ip() uintptr { return uintptr(c.rip) }
-func (c *context) sp() uintptr { return uintptr(c.rsp) }
-
-// AMD64 does not have link register, so this returns 0.
-func (c *context) lr() uintptr { return 0 }
-func (c *context) set_lr(x uintptr) {}
-
-func (c *context) set_ip(x uintptr) { c.rip = uint64(x) }
-func (c *context) set_sp(x uintptr) { c.rsp = uint64(x) }
-
-func dumpregs(r *context) {
- print("rax ", hex(r.rax), "\n")
- print("rbx ", hex(r.rbx), "\n")
- print("rcx ", hex(r.rcx), "\n")
- print("rdi ", hex(r.rdi), "\n")
- print("rsi ", hex(r.rsi), "\n")
- print("rbp ", hex(r.rbp), "\n")
- print("rsp ", hex(r.rsp), "\n")
- print("r8 ", hex(r.r8), "\n")
- print("r9 ", hex(r.r9), "\n")
- print("r10 ", hex(r.r10), "\n")
- print("r11 ", hex(r.r11), "\n")
- print("r12 ", hex(r.r12), "\n")
- print("r13 ", hex(r.r13), "\n")
- print("r14 ", hex(r.r14), "\n")
- print("r15 ", hex(r.r15), "\n")
- print("rip ", hex(r.rip), "\n")
- print("rflags ", hex(r.eflags), "\n")
- print("cs ", hex(r.segcs), "\n")
- print("fs ", hex(r.segfs), "\n")
- print("gs ", hex(r.seggs), "\n")
-}
diff --git a/contrib/go/_std_1.20/src/runtime/duff_amd64.s b/contrib/go/_std_1.20/src/runtime/duff_amd64.s
deleted file mode 100644
index df010f5853..0000000000
--- a/contrib/go/_std_1.20/src/runtime/duff_amd64.s
+++ /dev/null
@@ -1,427 +0,0 @@
-// Code generated by mkduff.go; DO NOT EDIT.
-// Run go generate from src/runtime to update.
-// See mkduff.go for comments.
-
-#include "textflag.h"
-
-TEXT runtime·duffzero<ABIInternal>(SB), NOSPLIT, $0-0
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- MOVUPS X15,(DI)
- MOVUPS X15,16(DI)
- MOVUPS X15,32(DI)
- MOVUPS X15,48(DI)
- LEAQ 64(DI),DI
-
- RET
-
-TEXT runtime·duffcopy<ABIInternal>(SB), NOSPLIT, $0-0
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- MOVUPS (SI), X0
- ADDQ $16, SI
- MOVUPS X0, (DI)
- ADDQ $16, DI
-
- RET
diff --git a/contrib/go/_std_1.20/src/runtime/error.go b/contrib/go/_std_1.20/src/runtime/error.go
deleted file mode 100644
index a211fbf515..0000000000
--- a/contrib/go/_std_1.20/src/runtime/error.go
+++ /dev/null
@@ -1,330 +0,0 @@
-// Copyright 2010 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 runtime
-
-import "internal/bytealg"
-
-// The Error interface identifies a run time error.
-type Error interface {
- error
-
- // RuntimeError is a no-op function but
- // serves to distinguish types that are run time
- // errors from ordinary errors: a type is a
- // run time error if it has a RuntimeError method.
- RuntimeError()
-}
-
-// A TypeAssertionError explains a failed type assertion.
-type TypeAssertionError struct {
- _interface *_type
- concrete *_type
- asserted *_type
- missingMethod string // one method needed by Interface, missing from Concrete
-}
-
-func (*TypeAssertionError) RuntimeError() {}
-
-func (e *TypeAssertionError) Error() string {
- inter := "interface"
- if e._interface != nil {
- inter = e._interface.string()
- }
- as := e.asserted.string()
- if e.concrete == nil {
- return "interface conversion: " + inter + " is nil, not " + as
- }
- cs := e.concrete.string()
- if e.missingMethod == "" {
- msg := "interface conversion: " + inter + " is " + cs + ", not " + as
- if cs == as {
- // provide slightly clearer error message
- if e.concrete.pkgpath() != e.asserted.pkgpath() {
- msg += " (types from different packages)"
- } else {
- msg += " (types from different scopes)"
- }
- }
- return msg
- }
- return "interface conversion: " + cs + " is not " + as +
- ": missing method " + e.missingMethod
-}
-
-// itoa converts val to a decimal representation. The result is
-// written somewhere within buf and the location of the result is returned.
-// buf must be at least 20 bytes.
-//
-//go:nosplit
-func itoa(buf []byte, val uint64) []byte {
- i := len(buf) - 1
- for val >= 10 {
- buf[i] = byte(val%10 + '0')
- i--
- val /= 10
- }
- buf[i] = byte(val + '0')
- return buf[i:]
-}
-
-// An errorString represents a runtime error described by a single string.
-type errorString string
-
-func (e errorString) RuntimeError() {}
-
-func (e errorString) Error() string {
- return "runtime error: " + string(e)
-}
-
-type errorAddressString struct {
- msg string // error message
- addr uintptr // memory address where the error occurred
-}
-
-func (e errorAddressString) RuntimeError() {}
-
-func (e errorAddressString) Error() string {
- return "runtime error: " + e.msg
-}
-
-// Addr returns the memory address where a fault occurred.
-// The address provided is best-effort.
-// The veracity of the result may depend on the platform.
-// Errors providing this method will only be returned as
-// a result of using runtime/debug.SetPanicOnFault.
-func (e errorAddressString) Addr() uintptr {
- return e.addr
-}
-
-// plainError represents a runtime error described a string without
-// the prefix "runtime error: " after invoking errorString.Error().
-// See Issue #14965.
-type plainError string
-
-func (e plainError) RuntimeError() {}
-
-func (e plainError) Error() string {
- return string(e)
-}
-
-// A boundsError represents an indexing or slicing operation gone wrong.
-type boundsError struct {
- x int64
- y int
- // Values in an index or slice expression can be signed or unsigned.
- // That means we'd need 65 bits to encode all possible indexes, from -2^63 to 2^64-1.
- // Instead, we keep track of whether x should be interpreted as signed or unsigned.
- // y is known to be nonnegative and to fit in an int.
- signed bool
- code boundsErrorCode
-}
-
-type boundsErrorCode uint8
-
-const (
- boundsIndex boundsErrorCode = iota // s[x], 0 <= x < len(s) failed
-
- boundsSliceAlen // s[?:x], 0 <= x <= len(s) failed
- boundsSliceAcap // s[?:x], 0 <= x <= cap(s) failed
- boundsSliceB // s[x:y], 0 <= x <= y failed (but boundsSliceA didn't happen)
-
- boundsSlice3Alen // s[?:?:x], 0 <= x <= len(s) failed
- boundsSlice3Acap // s[?:?:x], 0 <= x <= cap(s) failed
- boundsSlice3B // s[?:x:y], 0 <= x <= y failed (but boundsSlice3A didn't happen)
- boundsSlice3C // s[x:y:?], 0 <= x <= y failed (but boundsSlice3A/B didn't happen)
-
- boundsConvert // (*[x]T)(s), 0 <= x <= len(s) failed
- // Note: in the above, len(s) and cap(s) are stored in y
-)
-
-// boundsErrorFmts provide error text for various out-of-bounds panics.
-// Note: if you change these strings, you should adjust the size of the buffer
-// in boundsError.Error below as well.
-var boundsErrorFmts = [...]string{
- boundsIndex: "index out of range [%x] with length %y",
- boundsSliceAlen: "slice bounds out of range [:%x] with length %y",
- boundsSliceAcap: "slice bounds out of range [:%x] with capacity %y",
- boundsSliceB: "slice bounds out of range [%x:%y]",
- boundsSlice3Alen: "slice bounds out of range [::%x] with length %y",
- boundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",
- boundsSlice3B: "slice bounds out of range [:%x:%y]",
- boundsSlice3C: "slice bounds out of range [%x:%y:]",
- boundsConvert: "cannot convert slice with length %y to array or pointer to array with length %x",
-}
-
-// boundsNegErrorFmts are overriding formats if x is negative. In this case there's no need to report y.
-var boundsNegErrorFmts = [...]string{
- boundsIndex: "index out of range [%x]",
- boundsSliceAlen: "slice bounds out of range [:%x]",
- boundsSliceAcap: "slice bounds out of range [:%x]",
- boundsSliceB: "slice bounds out of range [%x:]",
- boundsSlice3Alen: "slice bounds out of range [::%x]",
- boundsSlice3Acap: "slice bounds out of range [::%x]",
- boundsSlice3B: "slice bounds out of range [:%x:]",
- boundsSlice3C: "slice bounds out of range [%x::]",
-}
-
-func (e boundsError) RuntimeError() {}
-
-func appendIntStr(b []byte, v int64, signed bool) []byte {
- if signed && v < 0 {
- b = append(b, '-')
- v = -v
- }
- var buf [20]byte
- b = append(b, itoa(buf[:], uint64(v))...)
- return b
-}
-
-func (e boundsError) Error() string {
- fmt := boundsErrorFmts[e.code]
- if e.signed && e.x < 0 {
- fmt = boundsNegErrorFmts[e.code]
- }
- // max message length is 99: "runtime error: slice bounds out of range [::%x] with capacity %y"
- // x can be at most 20 characters. y can be at most 19.
- b := make([]byte, 0, 100)
- b = append(b, "runtime error: "...)
- for i := 0; i < len(fmt); i++ {
- c := fmt[i]
- if c != '%' {
- b = append(b, c)
- continue
- }
- i++
- switch fmt[i] {
- case 'x':
- b = appendIntStr(b, e.x, e.signed)
- case 'y':
- b = appendIntStr(b, int64(e.y), true)
- }
- }
- return string(b)
-}
-
-type stringer interface {
- String() string
-}
-
-// printany prints an argument passed to panic.
-// If panic is called with a value that has a String or Error method,
-// it has already been converted into a string by preprintpanics.
-func printany(i any) {
- switch v := i.(type) {
- case nil:
- print("nil")
- case bool:
- print(v)
- case int:
- print(v)
- case int8:
- print(v)
- case int16:
- print(v)
- case int32:
- print(v)
- case int64:
- print(v)
- case uint:
- print(v)
- case uint8:
- print(v)
- case uint16:
- print(v)
- case uint32:
- print(v)
- case uint64:
- print(v)
- case uintptr:
- print(v)
- case float32:
- print(v)
- case float64:
- print(v)
- case complex64:
- print(v)
- case complex128:
- print(v)
- case string:
- print(v)
- default:
- printanycustomtype(i)
- }
-}
-
-func printanycustomtype(i any) {
- eface := efaceOf(&i)
- typestring := eface._type.string()
-
- switch eface._type.kind {
- case kindString:
- print(typestring, `("`, *(*string)(eface.data), `")`)
- case kindBool:
- print(typestring, "(", *(*bool)(eface.data), ")")
- case kindInt:
- print(typestring, "(", *(*int)(eface.data), ")")
- case kindInt8:
- print(typestring, "(", *(*int8)(eface.data), ")")
- case kindInt16:
- print(typestring, "(", *(*int16)(eface.data), ")")
- case kindInt32:
- print(typestring, "(", *(*int32)(eface.data), ")")
- case kindInt64:
- print(typestring, "(", *(*int64)(eface.data), ")")
- case kindUint:
- print(typestring, "(", *(*uint)(eface.data), ")")
- case kindUint8:
- print(typestring, "(", *(*uint8)(eface.data), ")")
- case kindUint16:
- print(typestring, "(", *(*uint16)(eface.data), ")")
- case kindUint32:
- print(typestring, "(", *(*uint32)(eface.data), ")")
- case kindUint64:
- print(typestring, "(", *(*uint64)(eface.data), ")")
- case kindUintptr:
- print(typestring, "(", *(*uintptr)(eface.data), ")")
- case kindFloat32:
- print(typestring, "(", *(*float32)(eface.data), ")")
- case kindFloat64:
- print(typestring, "(", *(*float64)(eface.data), ")")
- case kindComplex64:
- print(typestring, *(*complex64)(eface.data))
- case kindComplex128:
- print(typestring, *(*complex128)(eface.data))
- default:
- print("(", typestring, ") ", eface.data)
- }
-}
-
-// panicwrap generates a panic for a call to a wrapped value method
-// with a nil pointer receiver.
-//
-// It is called from the generated wrapper code.
-func panicwrap() {
- pc := getcallerpc()
- name := funcname(findfunc(pc))
- // name is something like "main.(*T).F".
- // We want to extract pkg ("main"), typ ("T"), and meth ("F").
- // Do it by finding the parens.
- i := bytealg.IndexByteString(name, '(')
- if i < 0 {
- throw("panicwrap: no ( in " + name)
- }
- pkg := name[:i-1]
- if i+2 >= len(name) || name[i-1:i+2] != ".(*" {
- throw("panicwrap: unexpected string after package name: " + name)
- }
- name = name[i+2:]
- i = bytealg.IndexByteString(name, ')')
- if i < 0 {
- throw("panicwrap: no ) in " + name)
- }
- if i+2 >= len(name) || name[i:i+2] != ")." {
- throw("panicwrap: unexpected string after type name: " + name)
- }
- typ := name[:i]
- meth := name[i+2:]
- panic(plainError("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer"))
-}
diff --git a/contrib/go/_std_1.20/src/runtime/exithook.go b/contrib/go/_std_1.20/src/runtime/exithook.go
deleted file mode 100644
index bb29a94724..0000000000
--- a/contrib/go/_std_1.20/src/runtime/exithook.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2022 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 runtime
-
-// addExitHook registers the specified function 'f' to be run at
-// program termination (e.g. when someone invokes os.Exit(), or when
-// main.main returns). Hooks are run in reverse order of registration:
-// first hook added is the last one run.
-//
-// CAREFUL: the expectation is that addExitHook should only be called
-// from a safe context (e.g. not an error/panic path or signal
-// handler, preemption enabled, allocation allowed, write barriers
-// allowed, etc), and that the exit function 'f' will be invoked under
-// similar circumstances. That is the say, we are expecting that 'f'
-// uses normal / high-level Go code as opposed to one of the more
-// restricted dialects used for the trickier parts of the runtime.
-func addExitHook(f func(), runOnNonZeroExit bool) {
- exitHooks.hooks = append(exitHooks.hooks, exitHook{f: f, runOnNonZeroExit: runOnNonZeroExit})
-}
-
-// exitHook stores a function to be run on program exit, registered
-// by the utility runtime.addExitHook.
-type exitHook struct {
- f func() // func to run
- runOnNonZeroExit bool // whether to run on non-zero exit code
-}
-
-// exitHooks stores state related to hook functions registered to
-// run when program execution terminates.
-var exitHooks struct {
- hooks []exitHook
- runningExitHooks bool
-}
-
-// runExitHooks runs any registered exit hook functions (funcs
-// previously registered using runtime.addExitHook). Here 'exitCode'
-// is the status code being passed to os.Exit, or zero if the program
-// is terminating normally without calling os.Exit).
-func runExitHooks(exitCode int) {
- if exitHooks.runningExitHooks {
- throw("internal error: exit hook invoked exit")
- }
- exitHooks.runningExitHooks = true
-
- runExitHook := func(f func()) (caughtPanic bool) {
- defer func() {
- if x := recover(); x != nil {
- caughtPanic = true
- }
- }()
- f()
- return
- }
-
- finishPageTrace()
- for i := range exitHooks.hooks {
- h := exitHooks.hooks[len(exitHooks.hooks)-i-1]
- if exitCode != 0 && !h.runOnNonZeroExit {
- continue
- }
- if caughtPanic := runExitHook(h.f); caughtPanic {
- throw("internal error: exit hook invoked panic")
- }
- }
- exitHooks.hooks = nil
- exitHooks.runningExitHooks = false
-}
diff --git a/contrib/go/_std_1.20/src/runtime/extern.go b/contrib/go/_std_1.20/src/runtime/extern.go
deleted file mode 100644
index afadc3d17e..0000000000
--- a/contrib/go/_std_1.20/src/runtime/extern.go
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2009 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 runtime contains operations that interact with Go's runtime system,
-such as functions to control goroutines. It also includes the low-level type information
-used by the reflect package; see reflect's documentation for the programmable
-interface to the run-time type system.
-
-# Environment Variables
-
-The following environment variables ($name or %name%, depending on the host
-operating system) control the run-time behavior of Go programs. The meanings
-and use may change from release to release.
-
-The GOGC variable sets the initial garbage collection target percentage.
-A collection is triggered when the ratio of freshly allocated data to live data
-remaining after the previous collection reaches this percentage. The default
-is GOGC=100. Setting GOGC=off disables the garbage collector entirely.
-[runtime/debug.SetGCPercent] allows changing this percentage at run time.
-
-The GOMEMLIMIT variable sets a soft memory limit for the runtime. This memory limit
-includes the Go heap and all other memory managed by the runtime, and excludes
-external memory sources such as mappings of the binary itself, memory managed in
-other languages, and memory held by the operating system on behalf of the Go
-program. GOMEMLIMIT is a numeric value in bytes with an optional unit suffix.
-The supported suffixes include B, KiB, MiB, GiB, and TiB. These suffixes
-represent quantities of bytes as defined by the IEC 80000-13 standard. That is,
-they are based on powers of two: KiB means 2^10 bytes, MiB means 2^20 bytes,
-and so on. The default setting is math.MaxInt64, which effectively disables the
-memory limit. [runtime/debug.SetMemoryLimit] allows changing this limit at run
-time.
-
-The GODEBUG variable controls debugging variables within the runtime.
-It is a comma-separated list of name=val pairs setting these named variables:
-
- allocfreetrace: setting allocfreetrace=1 causes every allocation to be
- profiled and a stack trace printed on each object's allocation and free.
-
- clobberfree: setting clobberfree=1 causes the garbage collector to
- clobber the memory content of an object with bad content when it frees
- the object.
-
- cpu.*: cpu.all=off disables the use of all optional instruction set extensions.
- cpu.extension=off disables use of instructions from the specified instruction set extension.
- extension is the lower case name for the instruction set extension such as sse41 or avx
- as listed in internal/cpu package. As an example cpu.avx=off disables runtime detection
- and thereby use of AVX instructions.
-
- cgocheck: setting cgocheck=0 disables all checks for packages
- using cgo to incorrectly pass Go pointers to non-Go code.
- Setting cgocheck=1 (the default) enables relatively cheap
- checks that may miss some errors. Setting cgocheck=2 enables
- expensive checks that should not miss any errors, but will
- cause your program to run slower.
-
- efence: setting efence=1 causes the allocator to run in a mode
- where each object is allocated on a unique page and addresses are
- never recycled.
-
- gccheckmark: setting gccheckmark=1 enables verification of the
- garbage collector's concurrent mark phase by performing a
- second mark pass while the world is stopped. If the second
- pass finds a reachable object that was not found by concurrent
- mark, the garbage collector will panic.
-
- gcpacertrace: setting gcpacertrace=1 causes the garbage collector to
- print information about the internal state of the concurrent pacer.
-
- gcshrinkstackoff: setting gcshrinkstackoff=1 disables moving goroutines
- onto smaller stacks. In this mode, a goroutine's stack can only grow.
-
- gcstoptheworld: setting gcstoptheworld=1 disables concurrent garbage collection,
- making every garbage collection a stop-the-world event. Setting gcstoptheworld=2
- also disables concurrent sweeping after the garbage collection finishes.
-
- gctrace: setting gctrace=1 causes the garbage collector to emit a single line to standard
- error at each collection, summarizing the amount of memory collected and the
- length of the pause. The format of this line is subject to change.
- Currently, it is:
- gc # @#s #%: #+#+# ms clock, #+#/#/#+# ms cpu, #->#-># MB, # MB goal, # MB stacks, #MB globals, # P
- where the fields are as follows:
- gc # the GC number, incremented at each GC
- @#s time in seconds since program start
- #% percentage of time spent in GC since program start
- #+...+# wall-clock/CPU times for the phases of the GC
- #->#-># MB heap size at GC start, at GC end, and live heap
- # MB goal goal heap size
- # MB stacks estimated scannable stack size
- # MB globals scannable global size
- # P number of processors used
- The phases are stop-the-world (STW) sweep termination, concurrent
- mark and scan, and STW mark termination. The CPU times
- for mark/scan are broken down in to assist time (GC performed in
- line with allocation), background GC time, and idle GC time.
- If the line ends with "(forced)", this GC was forced by a
- runtime.GC() call.
-
- harddecommit: setting harddecommit=1 causes memory that is returned to the OS to
- also have protections removed on it. This is the only mode of operation on Windows,
- but is helpful in debugging scavenger-related issues on other platforms. Currently,
- only supported on Linux.
-
- inittrace: setting inittrace=1 causes the runtime to emit a single line to standard
- error for each package with init work, summarizing the execution time and memory
- allocation. No information is printed for inits executed as part of plugin loading
- and for packages without both user defined and compiler generated init work.
- The format of this line is subject to change. Currently, it is:
- init # @#ms, # ms clock, # bytes, # allocs
- where the fields are as follows:
- init # the package name
- @# ms time in milliseconds when the init started since program start
- # clock wall-clock time for package initialization work
- # bytes memory allocated on the heap
- # allocs number of heap allocations
-
- madvdontneed: setting madvdontneed=0 will use MADV_FREE
- instead of MADV_DONTNEED on Linux when returning memory to the
- kernel. This is more efficient, but means RSS numbers will
- drop only when the OS is under memory pressure. On the BSDs and
- Illumos/Solaris, setting madvdontneed=1 will use MADV_DONTNEED instead
- of MADV_FREE. This is less efficient, but causes RSS numbers to drop
- more quickly.
-
- memprofilerate: setting memprofilerate=X will update the value of runtime.MemProfileRate.
- When set to 0 memory profiling is disabled. Refer to the description of
- MemProfileRate for the default value.
-
- pagetrace: setting pagetrace=/path/to/file will write out a trace of page events
- that can be viewed, analyzed, and visualized using the x/debug/cmd/pagetrace tool.
- Build your program with GOEXPERIMENT=pagetrace to enable this functionality. Do not
- enable this functionality if your program is a setuid binary as it introduces a security
- risk in that scenario. Currently not supported on Windows, plan9 or js/wasm. Setting this
- option for some applications can produce large traces, so use with care.
-
- invalidptr: invalidptr=1 (the default) causes the garbage collector and stack
- copier to crash the program if an invalid pointer value (for example, 1)
- is found in a pointer-typed location. Setting invalidptr=0 disables this check.
- This should only be used as a temporary workaround to diagnose buggy code.
- The real fix is to not store integers in pointer-typed locations.
-
- sbrk: setting sbrk=1 replaces the memory allocator and garbage collector
- with a trivial allocator that obtains memory from the operating system and
- never reclaims any memory.
-
- scavtrace: setting scavtrace=1 causes the runtime to emit a single line to standard
- error, roughly once per GC cycle, summarizing the amount of work done by the
- scavenger as well as the total amount of memory returned to the operating system
- and an estimate of physical memory utilization. The format of this line is subject
- to change, but currently it is:
- scav # KiB work, # KiB total, #% util
- where the fields are as follows:
- # KiB work the amount of memory returned to the OS since the last line
- # KiB total the total amount of memory returned to the OS
- #% util the fraction of all unscavenged memory which is in-use
- If the line ends with "(forced)", then scavenging was forced by a
- debug.FreeOSMemory() call.
-
- scheddetail: setting schedtrace=X and scheddetail=1 causes the scheduler to emit
- detailed multiline info every X milliseconds, describing state of the scheduler,
- processors, threads and goroutines.
-
- schedtrace: setting schedtrace=X causes the scheduler to emit a single line to standard
- error every X milliseconds, summarizing the scheduler state.
-
- tracebackancestors: setting tracebackancestors=N extends tracebacks with the stacks at
- which goroutines were created, where N limits the number of ancestor goroutines to
- report. This also extends the information returned by runtime.Stack. Ancestor's goroutine
- IDs will refer to the ID of the goroutine at the time of creation; it's possible for this
- ID to be reused for another goroutine. Setting N to 0 will report no ancestry information.
-
- asyncpreemptoff: asyncpreemptoff=1 disables signal-based
- asynchronous goroutine preemption. This makes some loops
- non-preemptible for long periods, which may delay GC and
- goroutine scheduling. This is useful for debugging GC issues
- because it also disables the conservative stack scanning used
- for asynchronously preempted goroutines.
-
-The net and net/http packages also refer to debugging variables in GODEBUG.
-See the documentation for those packages for details.
-
-The GOMAXPROCS variable limits the number of operating system threads that
-can execute user-level Go code simultaneously. There is no limit to the number of threads
-that can be blocked in system calls on behalf of Go code; those do not count against
-the GOMAXPROCS limit. This package's GOMAXPROCS function queries and changes
-the limit.
-
-The GORACE variable configures the race detector, for programs built using -race.
-See https://golang.org/doc/articles/race_detector.html for details.
-
-The GOTRACEBACK variable controls the amount of output generated when a Go
-program fails due to an unrecovered panic or an unexpected runtime condition.
-By default, a failure prints a stack trace for the current goroutine,
-eliding functions internal to the run-time system, and then exits with exit code 2.
-The failure prints stack traces for all goroutines if there is no current goroutine
-or the failure is internal to the run-time.
-GOTRACEBACK=none omits the goroutine stack traces entirely.
-GOTRACEBACK=single (the default) behaves as described above.
-GOTRACEBACK=all adds stack traces for all user-created goroutines.
-GOTRACEBACK=system is like “all” but adds stack frames for run-time functions
-and shows goroutines created internally by the run-time.
-GOTRACEBACK=crash is like “system” but crashes in an operating system-specific
-manner instead of exiting. For example, on Unix systems, the crash raises
-SIGABRT to trigger a core dump.
-For historical reasons, the GOTRACEBACK settings 0, 1, and 2 are synonyms for
-none, all, and system, respectively.
-The runtime/debug package's SetTraceback function allows increasing the
-amount of output at run time, but it cannot reduce the amount below that
-specified by the environment variable.
-See https://golang.org/pkg/runtime/debug/#SetTraceback.
-
-The GOARCH, GOOS, GOPATH, and GOROOT environment variables complete
-the set of Go environment variables. They influence the building of Go programs
-(see https://golang.org/cmd/go and https://golang.org/pkg/go/build).
-GOARCH, GOOS, and GOROOT are recorded at compile time and made available by
-constants or functions in this package, but they do not influence the execution
-of the run-time system.
-
-# Security
-
-On Unix platforms, Go's runtime system behaves slightly differently when a
-binary is setuid/setgid or executed with setuid/setgid-like properties, in order
-to prevent dangerous behaviors. On Linux this is determined by checking for the
-AT_SECURE flag in the auxiliary vector, on the BSDs and Solaris/Illumos it is
-determined by checking the issetugid syscall, and on AIX it is determined by
-checking if the uid/gid match the effective uid/gid.
-
-When the runtime determines the binary is setuid/setgid-like, it does three main
-things:
- - The standard input/output file descriptors (0, 1, 2) are checked to be open.
- If any of them are closed, they are opened pointing at /dev/null.
- - The value of the GOTRACEBACK environment variable is set to 'none'.
- - When a signal is received that terminates the program, or the program
- encounters an unrecoverable panic that would otherwise override the value
- of GOTRACEBACK, the goroutine stack, registers, and other memory related
- information are omitted.
-*/
-package runtime
-
-import (
- "internal/goarch"
- "internal/goos"
-)
-
-// Caller reports file and line number information about function invocations on
-// the calling goroutine's stack. The argument skip is the number of stack frames
-// to ascend, with 0 identifying the caller of Caller. (For historical reasons the
-// meaning of skip differs between Caller and Callers.) The return values report the
-// program counter, file name, and line number within the file of the corresponding
-// call. The boolean ok is false if it was not possible to recover the information.
-func Caller(skip int) (pc uintptr, file string, line int, ok bool) {
- rpc := make([]uintptr, 1)
- n := callers(skip+1, rpc[:])
- if n < 1 {
- return
- }
- frame, _ := CallersFrames(rpc).Next()
- return frame.PC, frame.File, frame.Line, frame.PC != 0
-}
-
-// Callers fills the slice pc with the return program counters of function invocations
-// on the calling goroutine's stack. The argument skip is the number of stack frames
-// to skip before recording in pc, with 0 identifying the frame for Callers itself and
-// 1 identifying the caller of Callers.
-// It returns the number of entries written to pc.
-//
-// To translate these PCs into symbolic information such as function
-// names and line numbers, use CallersFrames. CallersFrames accounts
-// for inlined functions and adjusts the return program counters into
-// call program counters. Iterating over the returned slice of PCs
-// directly is discouraged, as is using FuncForPC on any of the
-// returned PCs, since these cannot account for inlining or return
-// program counter adjustment.
-func Callers(skip int, pc []uintptr) int {
- // runtime.callers uses pc.array==nil as a signal
- // to print a stack trace. Pick off 0-length pc here
- // so that we don't let a nil pc slice get to it.
- if len(pc) == 0 {
- return 0
- }
- return callers(skip, pc)
-}
-
-var defaultGOROOT string // set by cmd/link
-
-// GOROOT returns the root of the Go tree. It uses the
-// GOROOT environment variable, if set at process start,
-// or else the root used during the Go build.
-func GOROOT() string {
- s := gogetenv("GOROOT")
- if s != "" {
- return s
- }
- return defaultGOROOT
-}
-
-// buildVersion is the Go tree's version string at build time.
-//
-// If any GOEXPERIMENTs are set to non-default values, it will include
-// "X:<GOEXPERIMENT>".
-//
-// This is set by the linker.
-//
-// This is accessed by "go version <binary>".
-var buildVersion string
-
-// Version returns the Go tree's version string.
-// It is either the commit hash and date at the time of the build or,
-// when possible, a release tag like "go1.3".
-func Version() string {
- return buildVersion
-}
-
-// GOOS is the running program's operating system target:
-// one of darwin, freebsd, linux, and so on.
-// To view possible combinations of GOOS and GOARCH, run "go tool dist list".
-const GOOS string = goos.GOOS
-
-// GOARCH is the running program's architecture target:
-// one of 386, amd64, arm, s390x, and so on.
-const GOARCH string = goarch.GOARCH
diff --git a/contrib/go/_std_1.20/src/runtime/funcdata.h b/contrib/go/_std_1.20/src/runtime/funcdata.h
deleted file mode 100644
index 2e2bb30446..0000000000
--- a/contrib/go/_std_1.20/src/runtime/funcdata.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2013 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.
-
-// This file defines the IDs for PCDATA and FUNCDATA instructions
-// in Go binaries. It is included by assembly sources, so it must
-// be written using #defines.
-//
-// These must agree with symtab.go and ../cmd/internal/objabi/funcdata.go.
-
-#define PCDATA_UnsafePoint 0
-#define PCDATA_StackMapIndex 1
-#define PCDATA_InlTreeIndex 2
-#define PCDATA_ArgLiveIndex 3
-
-#define FUNCDATA_ArgsPointerMaps 0 /* garbage collector blocks */
-#define FUNCDATA_LocalsPointerMaps 1
-#define FUNCDATA_StackObjects 2
-#define FUNCDATA_InlTree 3
-#define FUNCDATA_OpenCodedDeferInfo 4 /* info for func with open-coded defers */
-#define FUNCDATA_ArgInfo 5
-#define FUNCDATA_ArgLiveInfo 6
-#define FUNCDATA_WrapInfo 7
-
-// Pseudo-assembly statements.
-
-// GO_ARGS, GO_RESULTS_INITIALIZED, and NO_LOCAL_POINTERS are macros
-// that communicate to the runtime information about the location and liveness
-// of pointers in an assembly function's arguments, results, and stack frame.
-// This communication is only required in assembly functions that make calls
-// to other functions that might be preempted or grow the stack.
-// NOSPLIT functions that make no calls do not need to use these macros.
-
-// GO_ARGS indicates that the Go prototype for this assembly function
-// defines the pointer map for the function's arguments.
-// GO_ARGS should be the first instruction in a function that uses it.
-// It can be omitted if there are no arguments at all.
-// GO_ARGS is inserted implicitly by the linker for any function whose
-// name starts with a middle-dot and that also has a Go prototype; it
-// is therefore usually not necessary to write explicitly.
-#define GO_ARGS FUNCDATA $FUNCDATA_ArgsPointerMaps, go_args_stackmap(SB)
-
-// GO_RESULTS_INITIALIZED indicates that the assembly function
-// has initialized the stack space for its results and that those results
-// should be considered live for the remainder of the function.
-#define GO_RESULTS_INITIALIZED PCDATA $PCDATA_StackMapIndex, $1
-
-// NO_LOCAL_POINTERS indicates that the assembly function stores
-// no pointers to heap objects in its local stack variables.
-#define NO_LOCAL_POINTERS FUNCDATA $FUNCDATA_LocalsPointerMaps, no_pointers_stackmap(SB)
-
-// ArgsSizeUnknown is set in Func.argsize to mark all functions
-// whose argument size is unknown (C vararg functions, and
-// assembly code without an explicit specification).
-// This value is generated by the compiler, assembler, or linker.
-#define ArgsSizeUnknown 0x80000000
diff --git a/contrib/go/_std_1.20/src/runtime/heapdump.go b/contrib/go/_std_1.20/src/runtime/heapdump.go
deleted file mode 100644
index f57a1a1e17..0000000000
--- a/contrib/go/_std_1.20/src/runtime/heapdump.go
+++ /dev/null
@@ -1,748 +0,0 @@
-// Copyright 2014 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.
-
-// Implementation of runtime/debug.WriteHeapDump. Writes all
-// objects in the heap plus additional info (roots, threads,
-// finalizers, etc.) to a file.
-
-// The format of the dumped file is described at
-// https://golang.org/s/go15heapdump.
-
-package runtime
-
-import (
- "internal/goarch"
- "unsafe"
-)
-
-//go:linkname runtime_debug_WriteHeapDump runtime/debug.WriteHeapDump
-func runtime_debug_WriteHeapDump(fd uintptr) {
- stopTheWorld("write heap dump")
-
- // Keep m on this G's stack instead of the system stack.
- // Both readmemstats_m and writeheapdump_m have pretty large
- // peak stack depths and we risk blowing the system stack.
- // This is safe because the world is stopped, so we don't
- // need to worry about anyone shrinking and therefore moving
- // our stack.
- var m MemStats
- systemstack(func() {
- // Call readmemstats_m here instead of deeper in
- // writeheapdump_m because we might blow the system stack
- // otherwise.
- readmemstats_m(&m)
- writeheapdump_m(fd, &m)
- })
-
- startTheWorld()
-}
-
-const (
- fieldKindEol = 0
- fieldKindPtr = 1
- fieldKindIface = 2
- fieldKindEface = 3
- tagEOF = 0
- tagObject = 1
- tagOtherRoot = 2
- tagType = 3
- tagGoroutine = 4
- tagStackFrame = 5
- tagParams = 6
- tagFinalizer = 7
- tagItab = 8
- tagOSThread = 9
- tagMemStats = 10
- tagQueuedFinalizer = 11
- tagData = 12
- tagBSS = 13
- tagDefer = 14
- tagPanic = 15
- tagMemProf = 16
- tagAllocSample = 17
-)
-
-var dumpfd uintptr // fd to write the dump to.
-var tmpbuf []byte
-
-// buffer of pending write data
-const (
- bufSize = 4096
-)
-
-var buf [bufSize]byte
-var nbuf uintptr
-
-func dwrite(data unsafe.Pointer, len uintptr) {
- if len == 0 {
- return
- }
- if nbuf+len <= bufSize {
- copy(buf[nbuf:], (*[bufSize]byte)(data)[:len])
- nbuf += len
- return
- }
-
- write(dumpfd, unsafe.Pointer(&buf), int32(nbuf))
- if len >= bufSize {
- write(dumpfd, data, int32(len))
- nbuf = 0
- } else {
- copy(buf[:], (*[bufSize]byte)(data)[:len])
- nbuf = len
- }
-}
-
-func dwritebyte(b byte) {
- dwrite(unsafe.Pointer(&b), 1)
-}
-
-func flush() {
- write(dumpfd, unsafe.Pointer(&buf), int32(nbuf))
- nbuf = 0
-}
-
-// Cache of types that have been serialized already.
-// We use a type's hash field to pick a bucket.
-// Inside a bucket, we keep a list of types that
-// have been serialized so far, most recently used first.
-// Note: when a bucket overflows we may end up
-// serializing a type more than once. That's ok.
-const (
- typeCacheBuckets = 256
- typeCacheAssoc = 4
-)
-
-type typeCacheBucket struct {
- t [typeCacheAssoc]*_type
-}
-
-var typecache [typeCacheBuckets]typeCacheBucket
-
-// dump a uint64 in a varint format parseable by encoding/binary.
-func dumpint(v uint64) {
- var buf [10]byte
- var n int
- for v >= 0x80 {
- buf[n] = byte(v | 0x80)
- n++
- v >>= 7
- }
- buf[n] = byte(v)
- n++
- dwrite(unsafe.Pointer(&buf), uintptr(n))
-}
-
-func dumpbool(b bool) {
- if b {
- dumpint(1)
- } else {
- dumpint(0)
- }
-}
-
-// dump varint uint64 length followed by memory contents.
-func dumpmemrange(data unsafe.Pointer, len uintptr) {
- dumpint(uint64(len))
- dwrite(data, len)
-}
-
-func dumpslice(b []byte) {
- dumpint(uint64(len(b)))
- if len(b) > 0 {
- dwrite(unsafe.Pointer(&b[0]), uintptr(len(b)))
- }
-}
-
-func dumpstr(s string) {
- dumpmemrange(unsafe.Pointer(unsafe.StringData(s)), uintptr(len(s)))
-}
-
-// dump information for a type.
-func dumptype(t *_type) {
- if t == nil {
- return
- }
-
- // If we've definitely serialized the type before,
- // no need to do it again.
- b := &typecache[t.hash&(typeCacheBuckets-1)]
- if t == b.t[0] {
- return
- }
- for i := 1; i < typeCacheAssoc; i++ {
- if t == b.t[i] {
- // Move-to-front
- for j := i; j > 0; j-- {
- b.t[j] = b.t[j-1]
- }
- b.t[0] = t
- return
- }
- }
-
- // Might not have been dumped yet. Dump it and
- // remember we did so.
- for j := typeCacheAssoc - 1; j > 0; j-- {
- b.t[j] = b.t[j-1]
- }
- b.t[0] = t
-
- // dump the type
- dumpint(tagType)
- dumpint(uint64(uintptr(unsafe.Pointer(t))))
- dumpint(uint64(t.size))
- if x := t.uncommon(); x == nil || t.nameOff(x.pkgpath).name() == "" {
- dumpstr(t.string())
- } else {
- pkgpath := t.nameOff(x.pkgpath).name()
- name := t.name()
- dumpint(uint64(uintptr(len(pkgpath)) + 1 + uintptr(len(name))))
- dwrite(unsafe.Pointer(unsafe.StringData(pkgpath)), uintptr(len(pkgpath)))
- dwritebyte('.')
- dwrite(unsafe.Pointer(unsafe.StringData(name)), uintptr(len(name)))
- }
- dumpbool(t.kind&kindDirectIface == 0 || t.ptrdata != 0)
-}
-
-// dump an object.
-func dumpobj(obj unsafe.Pointer, size uintptr, bv bitvector) {
- dumpint(tagObject)
- dumpint(uint64(uintptr(obj)))
- dumpmemrange(obj, size)
- dumpfields(bv)
-}
-
-func dumpotherroot(description string, to unsafe.Pointer) {
- dumpint(tagOtherRoot)
- dumpstr(description)
- dumpint(uint64(uintptr(to)))
-}
-
-func dumpfinalizer(obj unsafe.Pointer, fn *funcval, fint *_type, ot *ptrtype) {
- dumpint(tagFinalizer)
- dumpint(uint64(uintptr(obj)))
- dumpint(uint64(uintptr(unsafe.Pointer(fn))))
- dumpint(uint64(uintptr(unsafe.Pointer(fn.fn))))
- dumpint(uint64(uintptr(unsafe.Pointer(fint))))
- dumpint(uint64(uintptr(unsafe.Pointer(ot))))
-}
-
-type childInfo struct {
- // Information passed up from the callee frame about
- // the layout of the outargs region.
- argoff uintptr // where the arguments start in the frame
- arglen uintptr // size of args region
- args bitvector // if args.n >= 0, pointer map of args region
- sp *uint8 // callee sp
- depth uintptr // depth in call stack (0 == most recent)
-}
-
-// dump kinds & offsets of interesting fields in bv.
-func dumpbv(cbv *bitvector, offset uintptr) {
- for i := uintptr(0); i < uintptr(cbv.n); i++ {
- if cbv.ptrbit(i) == 1 {
- dumpint(fieldKindPtr)
- dumpint(uint64(offset + i*goarch.PtrSize))
- }
- }
-}
-
-func dumpframe(s *stkframe, arg unsafe.Pointer) bool {
- child := (*childInfo)(arg)
- f := s.fn
-
- // Figure out what we can about our stack map
- pc := s.pc
- pcdata := int32(-1) // Use the entry map at function entry
- if pc != f.entry() {
- pc--
- pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, pc, nil)
- }
- if pcdata == -1 {
- // We do not have a valid pcdata value but there might be a
- // stackmap for this function. It is likely that we are looking
- // at the function prologue, assume so and hope for the best.
- pcdata = 0
- }
- stkmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
-
- var bv bitvector
- if stkmap != nil && stkmap.n > 0 {
- bv = stackmapdata(stkmap, pcdata)
- } else {
- bv.n = -1
- }
-
- // Dump main body of stack frame.
- dumpint(tagStackFrame)
- dumpint(uint64(s.sp)) // lowest address in frame
- dumpint(uint64(child.depth)) // # of frames deep on the stack
- dumpint(uint64(uintptr(unsafe.Pointer(child.sp)))) // sp of child, or 0 if bottom of stack
- dumpmemrange(unsafe.Pointer(s.sp), s.fp-s.sp) // frame contents
- dumpint(uint64(f.entry()))
- dumpint(uint64(s.pc))
- dumpint(uint64(s.continpc))
- name := funcname(f)
- if name == "" {
- name = "unknown function"
- }
- dumpstr(name)
-
- // Dump fields in the outargs section
- if child.args.n >= 0 {
- dumpbv(&child.args, child.argoff)
- } else {
- // conservative - everything might be a pointer
- for off := child.argoff; off < child.argoff+child.arglen; off += goarch.PtrSize {
- dumpint(fieldKindPtr)
- dumpint(uint64(off))
- }
- }
-
- // Dump fields in the local vars section
- if stkmap == nil {
- // No locals information, dump everything.
- for off := child.arglen; off < s.varp-s.sp; off += goarch.PtrSize {
- dumpint(fieldKindPtr)
- dumpint(uint64(off))
- }
- } else if stkmap.n < 0 {
- // Locals size information, dump just the locals.
- size := uintptr(-stkmap.n)
- for off := s.varp - size - s.sp; off < s.varp-s.sp; off += goarch.PtrSize {
- dumpint(fieldKindPtr)
- dumpint(uint64(off))
- }
- } else if stkmap.n > 0 {
- // Locals bitmap information, scan just the pointers in
- // locals.
- dumpbv(&bv, s.varp-uintptr(bv.n)*goarch.PtrSize-s.sp)
- }
- dumpint(fieldKindEol)
-
- // Record arg info for parent.
- child.argoff = s.argp - s.fp
- child.arglen = s.argBytes()
- child.sp = (*uint8)(unsafe.Pointer(s.sp))
- child.depth++
- stkmap = (*stackmap)(funcdata(f, _FUNCDATA_ArgsPointerMaps))
- if stkmap != nil {
- child.args = stackmapdata(stkmap, pcdata)
- } else {
- child.args.n = -1
- }
- return true
-}
-
-func dumpgoroutine(gp *g) {
- var sp, pc, lr uintptr
- if gp.syscallsp != 0 {
- sp = gp.syscallsp
- pc = gp.syscallpc
- lr = 0
- } else {
- sp = gp.sched.sp
- pc = gp.sched.pc
- lr = gp.sched.lr
- }
-
- dumpint(tagGoroutine)
- dumpint(uint64(uintptr(unsafe.Pointer(gp))))
- dumpint(uint64(sp))
- dumpint(gp.goid)
- dumpint(uint64(gp.gopc))
- dumpint(uint64(readgstatus(gp)))
- dumpbool(isSystemGoroutine(gp, false))
- dumpbool(false) // isbackground
- dumpint(uint64(gp.waitsince))
- dumpstr(gp.waitreason.String())
- dumpint(uint64(uintptr(gp.sched.ctxt)))
- dumpint(uint64(uintptr(unsafe.Pointer(gp.m))))
- dumpint(uint64(uintptr(unsafe.Pointer(gp._defer))))
- dumpint(uint64(uintptr(unsafe.Pointer(gp._panic))))
-
- // dump stack
- var child childInfo
- child.args.n = -1
- child.arglen = 0
- child.sp = nil
- child.depth = 0
- gentraceback(pc, sp, lr, gp, 0, nil, 0x7fffffff, dumpframe, noescape(unsafe.Pointer(&child)), 0)
-
- // dump defer & panic records
- for d := gp._defer; d != nil; d = d.link {
- dumpint(tagDefer)
- dumpint(uint64(uintptr(unsafe.Pointer(d))))
- dumpint(uint64(uintptr(unsafe.Pointer(gp))))
- dumpint(uint64(d.sp))
- dumpint(uint64(d.pc))
- fn := *(**funcval)(unsafe.Pointer(&d.fn))
- dumpint(uint64(uintptr(unsafe.Pointer(fn))))
- if d.fn == nil {
- // d.fn can be nil for open-coded defers
- dumpint(uint64(0))
- } else {
- dumpint(uint64(uintptr(unsafe.Pointer(fn.fn))))
- }
- dumpint(uint64(uintptr(unsafe.Pointer(d.link))))
- }
- for p := gp._panic; p != nil; p = p.link {
- dumpint(tagPanic)
- dumpint(uint64(uintptr(unsafe.Pointer(p))))
- dumpint(uint64(uintptr(unsafe.Pointer(gp))))
- eface := efaceOf(&p.arg)
- dumpint(uint64(uintptr(unsafe.Pointer(eface._type))))
- dumpint(uint64(uintptr(unsafe.Pointer(eface.data))))
- dumpint(0) // was p->defer, no longer recorded
- dumpint(uint64(uintptr(unsafe.Pointer(p.link))))
- }
-}
-
-func dumpgs() {
- assertWorldStopped()
-
- // goroutines & stacks
- forEachG(func(gp *g) {
- status := readgstatus(gp) // The world is stopped so gp will not be in a scan state.
- switch status {
- default:
- print("runtime: unexpected G.status ", hex(status), "\n")
- throw("dumpgs in STW - bad status")
- case _Gdead:
- // ok
- case _Grunnable,
- _Gsyscall,
- _Gwaiting:
- dumpgoroutine(gp)
- }
- })
-}
-
-func finq_callback(fn *funcval, obj unsafe.Pointer, nret uintptr, fint *_type, ot *ptrtype) {
- dumpint(tagQueuedFinalizer)
- dumpint(uint64(uintptr(obj)))
- dumpint(uint64(uintptr(unsafe.Pointer(fn))))
- dumpint(uint64(uintptr(unsafe.Pointer(fn.fn))))
- dumpint(uint64(uintptr(unsafe.Pointer(fint))))
- dumpint(uint64(uintptr(unsafe.Pointer(ot))))
-}
-
-func dumproots() {
- // To protect mheap_.allspans.
- assertWorldStopped()
-
- // TODO(mwhudson): dump datamask etc from all objects
- // data segment
- dumpint(tagData)
- dumpint(uint64(firstmoduledata.data))
- dumpmemrange(unsafe.Pointer(firstmoduledata.data), firstmoduledata.edata-firstmoduledata.data)
- dumpfields(firstmoduledata.gcdatamask)
-
- // bss segment
- dumpint(tagBSS)
- dumpint(uint64(firstmoduledata.bss))
- dumpmemrange(unsafe.Pointer(firstmoduledata.bss), firstmoduledata.ebss-firstmoduledata.bss)
- dumpfields(firstmoduledata.gcbssmask)
-
- // mspan.types
- for _, s := range mheap_.allspans {
- if s.state.get() == mSpanInUse {
- // Finalizers
- for sp := s.specials; sp != nil; sp = sp.next {
- if sp.kind != _KindSpecialFinalizer {
- continue
- }
- spf := (*specialfinalizer)(unsafe.Pointer(sp))
- p := unsafe.Pointer(s.base() + uintptr(spf.special.offset))
- dumpfinalizer(p, spf.fn, spf.fint, spf.ot)
- }
- }
- }
-
- // Finalizer queue
- iterate_finq(finq_callback)
-}
-
-// Bit vector of free marks.
-// Needs to be as big as the largest number of objects per span.
-var freemark [_PageSize / 8]bool
-
-func dumpobjs() {
- // To protect mheap_.allspans.
- assertWorldStopped()
-
- for _, s := range mheap_.allspans {
- if s.state.get() != mSpanInUse {
- continue
- }
- p := s.base()
- size := s.elemsize
- n := (s.npages << _PageShift) / size
- if n > uintptr(len(freemark)) {
- throw("freemark array doesn't have enough entries")
- }
-
- for freeIndex := uintptr(0); freeIndex < s.nelems; freeIndex++ {
- if s.isFree(freeIndex) {
- freemark[freeIndex] = true
- }
- }
-
- for j := uintptr(0); j < n; j, p = j+1, p+size {
- if freemark[j] {
- freemark[j] = false
- continue
- }
- dumpobj(unsafe.Pointer(p), size, makeheapobjbv(p, size))
- }
- }
-}
-
-func dumpparams() {
- dumpint(tagParams)
- x := uintptr(1)
- if *(*byte)(unsafe.Pointer(&x)) == 1 {
- dumpbool(false) // little-endian ptrs
- } else {
- dumpbool(true) // big-endian ptrs
- }
- dumpint(goarch.PtrSize)
- var arenaStart, arenaEnd uintptr
- for i1 := range mheap_.arenas {
- if mheap_.arenas[i1] == nil {
- continue
- }
- for i, ha := range mheap_.arenas[i1] {
- if ha == nil {
- continue
- }
- base := arenaBase(arenaIdx(i1)<<arenaL1Shift | arenaIdx(i))
- if arenaStart == 0 || base < arenaStart {
- arenaStart = base
- }
- if base+heapArenaBytes > arenaEnd {
- arenaEnd = base + heapArenaBytes
- }
- }
- }
- dumpint(uint64(arenaStart))
- dumpint(uint64(arenaEnd))
- dumpstr(goarch.GOARCH)
- dumpstr(buildVersion)
- dumpint(uint64(ncpu))
-}
-
-func itab_callback(tab *itab) {
- t := tab._type
- dumptype(t)
- dumpint(tagItab)
- dumpint(uint64(uintptr(unsafe.Pointer(tab))))
- dumpint(uint64(uintptr(unsafe.Pointer(t))))
-}
-
-func dumpitabs() {
- iterate_itabs(itab_callback)
-}
-
-func dumpms() {
- for mp := allm; mp != nil; mp = mp.alllink {
- dumpint(tagOSThread)
- dumpint(uint64(uintptr(unsafe.Pointer(mp))))
- dumpint(uint64(mp.id))
- dumpint(mp.procid)
- }
-}
-
-//go:systemstack
-func dumpmemstats(m *MemStats) {
- assertWorldStopped()
-
- // These ints should be identical to the exported
- // MemStats structure and should be ordered the same
- // way too.
- dumpint(tagMemStats)
- dumpint(m.Alloc)
- dumpint(m.TotalAlloc)
- dumpint(m.Sys)
- dumpint(m.Lookups)
- dumpint(m.Mallocs)
- dumpint(m.Frees)
- dumpint(m.HeapAlloc)
- dumpint(m.HeapSys)
- dumpint(m.HeapIdle)
- dumpint(m.HeapInuse)
- dumpint(m.HeapReleased)
- dumpint(m.HeapObjects)
- dumpint(m.StackInuse)
- dumpint(m.StackSys)
- dumpint(m.MSpanInuse)
- dumpint(m.MSpanSys)
- dumpint(m.MCacheInuse)
- dumpint(m.MCacheSys)
- dumpint(m.BuckHashSys)
- dumpint(m.GCSys)
- dumpint(m.OtherSys)
- dumpint(m.NextGC)
- dumpint(m.LastGC)
- dumpint(m.PauseTotalNs)
- for i := 0; i < 256; i++ {
- dumpint(m.PauseNs[i])
- }
- dumpint(uint64(m.NumGC))
-}
-
-func dumpmemprof_callback(b *bucket, nstk uintptr, pstk *uintptr, size, allocs, frees uintptr) {
- stk := (*[100000]uintptr)(unsafe.Pointer(pstk))
- dumpint(tagMemProf)
- dumpint(uint64(uintptr(unsafe.Pointer(b))))
- dumpint(uint64(size))
- dumpint(uint64(nstk))
- for i := uintptr(0); i < nstk; i++ {
- pc := stk[i]
- f := findfunc(pc)
- if !f.valid() {
- var buf [64]byte
- n := len(buf)
- n--
- buf[n] = ')'
- if pc == 0 {
- n--
- buf[n] = '0'
- } else {
- for pc > 0 {
- n--
- buf[n] = "0123456789abcdef"[pc&15]
- pc >>= 4
- }
- }
- n--
- buf[n] = 'x'
- n--
- buf[n] = '0'
- n--
- buf[n] = '('
- dumpslice(buf[n:])
- dumpstr("?")
- dumpint(0)
- } else {
- dumpstr(funcname(f))
- if i > 0 && pc > f.entry() {
- pc--
- }
- file, line := funcline(f, pc)
- dumpstr(file)
- dumpint(uint64(line))
- }
- }
- dumpint(uint64(allocs))
- dumpint(uint64(frees))
-}
-
-func dumpmemprof() {
- // To protect mheap_.allspans.
- assertWorldStopped()
-
- iterate_memprof(dumpmemprof_callback)
- for _, s := range mheap_.allspans {
- if s.state.get() != mSpanInUse {
- continue
- }
- for sp := s.specials; sp != nil; sp = sp.next {
- if sp.kind != _KindSpecialProfile {
- continue
- }
- spp := (*specialprofile)(unsafe.Pointer(sp))
- p := s.base() + uintptr(spp.special.offset)
- dumpint(tagAllocSample)
- dumpint(uint64(p))
- dumpint(uint64(uintptr(unsafe.Pointer(spp.b))))
- }
- }
-}
-
-var dumphdr = []byte("go1.7 heap dump\n")
-
-func mdump(m *MemStats) {
- assertWorldStopped()
-
- // make sure we're done sweeping
- for _, s := range mheap_.allspans {
- if s.state.get() == mSpanInUse {
- s.ensureSwept()
- }
- }
- memclrNoHeapPointers(unsafe.Pointer(&typecache), unsafe.Sizeof(typecache))
- dwrite(unsafe.Pointer(&dumphdr[0]), uintptr(len(dumphdr)))
- dumpparams()
- dumpitabs()
- dumpobjs()
- dumpgs()
- dumpms()
- dumproots()
- dumpmemstats(m)
- dumpmemprof()
- dumpint(tagEOF)
- flush()
-}
-
-func writeheapdump_m(fd uintptr, m *MemStats) {
- assertWorldStopped()
-
- gp := getg()
- casGToWaiting(gp.m.curg, _Grunning, waitReasonDumpingHeap)
-
- // Set dump file.
- dumpfd = fd
-
- // Call dump routine.
- mdump(m)
-
- // Reset dump file.
- dumpfd = 0
- if tmpbuf != nil {
- sysFree(unsafe.Pointer(&tmpbuf[0]), uintptr(len(tmpbuf)), &memstats.other_sys)
- tmpbuf = nil
- }
-
- casgstatus(gp.m.curg, _Gwaiting, _Grunning)
-}
-
-// dumpint() the kind & offset of each field in an object.
-func dumpfields(bv bitvector) {
- dumpbv(&bv, 0)
- dumpint(fieldKindEol)
-}
-
-func makeheapobjbv(p uintptr, size uintptr) bitvector {
- // Extend the temp buffer if necessary.
- nptr := size / goarch.PtrSize
- if uintptr(len(tmpbuf)) < nptr/8+1 {
- if tmpbuf != nil {
- sysFree(unsafe.Pointer(&tmpbuf[0]), uintptr(len(tmpbuf)), &memstats.other_sys)
- }
- n := nptr/8 + 1
- p := sysAlloc(n, &memstats.other_sys)
- if p == nil {
- throw("heapdump: out of memory")
- }
- tmpbuf = (*[1 << 30]byte)(p)[:n]
- }
- // Convert heap bitmap to pointer bitmap.
- for i := uintptr(0); i < nptr/8+1; i++ {
- tmpbuf[i] = 0
- }
-
- hbits := heapBitsForAddr(p, size)
- for {
- var addr uintptr
- hbits, addr = hbits.next()
- if addr == 0 {
- break
- }
- i := (addr - p) / goarch.PtrSize
- tmpbuf[i/8] |= 1 << (i % 8)
- }
- return bitvector{int32(nptr), &tmpbuf[0]}
-}
diff --git a/contrib/go/_std_1.20/src/runtime/iface.go b/contrib/go/_std_1.20/src/runtime/iface.go
deleted file mode 100644
index a4d56dd33b..0000000000
--- a/contrib/go/_std_1.20/src/runtime/iface.go
+++ /dev/null
@@ -1,533 +0,0 @@
-// Copyright 2014 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 runtime
-
-import (
- "internal/abi"
- "internal/goarch"
- "runtime/internal/atomic"
- "unsafe"
-)
-
-const itabInitSize = 512
-
-var (
- itabLock mutex // lock for accessing itab table
- itabTable = &itabTableInit // pointer to current table
- itabTableInit = itabTableType{size: itabInitSize} // starter table
-)
-
-// Note: change the formula in the mallocgc call in itabAdd if you change these fields.
-type itabTableType struct {
- size uintptr // length of entries array. Always a power of 2.
- count uintptr // current number of filled entries.
- entries [itabInitSize]*itab // really [size] large
-}
-
-func itabHashFunc(inter *interfacetype, typ *_type) uintptr {
- // compiler has provided some good hash codes for us.
- return uintptr(inter.typ.hash ^ typ.hash)
-}
-
-func getitab(inter *interfacetype, typ *_type, canfail bool) *itab {
- if len(inter.mhdr) == 0 {
- throw("internal error - misuse of itab")
- }
-
- // easy case
- if typ.tflag&tflagUncommon == 0 {
- if canfail {
- return nil
- }
- name := inter.typ.nameOff(inter.mhdr[0].name)
- panic(&TypeAssertionError{nil, typ, &inter.typ, name.name()})
- }
-
- var m *itab
-
- // First, look in the existing table to see if we can find the itab we need.
- // This is by far the most common case, so do it without locks.
- // Use atomic to ensure we see any previous writes done by the thread
- // that updates the itabTable field (with atomic.Storep in itabAdd).
- t := (*itabTableType)(atomic.Loadp(unsafe.Pointer(&itabTable)))
- if m = t.find(inter, typ); m != nil {
- goto finish
- }
-
- // Not found. Grab the lock and try again.
- lock(&itabLock)
- if m = itabTable.find(inter, typ); m != nil {
- unlock(&itabLock)
- goto finish
- }
-
- // Entry doesn't exist yet. Make a new entry & add it.
- m = (*itab)(persistentalloc(unsafe.Sizeof(itab{})+uintptr(len(inter.mhdr)-1)*goarch.PtrSize, 0, &memstats.other_sys))
- m.inter = inter
- m._type = typ
- // The hash is used in type switches. However, compiler statically generates itab's
- // for all interface/type pairs used in switches (which are added to itabTable
- // in itabsinit). The dynamically-generated itab's never participate in type switches,
- // and thus the hash is irrelevant.
- // Note: m.hash is _not_ the hash used for the runtime itabTable hash table.
- m.hash = 0
- m.init()
- itabAdd(m)
- unlock(&itabLock)
-finish:
- if m.fun[0] != 0 {
- return m
- }
- if canfail {
- return nil
- }
- // this can only happen if the conversion
- // was already done once using the , ok form
- // and we have a cached negative result.
- // The cached result doesn't record which
- // interface function was missing, so initialize
- // the itab again to get the missing function name.
- panic(&TypeAssertionError{concrete: typ, asserted: &inter.typ, missingMethod: m.init()})
-}
-
-// find finds the given interface/type pair in t.
-// Returns nil if the given interface/type pair isn't present.
-func (t *itabTableType) find(inter *interfacetype, typ *_type) *itab {
- // Implemented using quadratic probing.
- // Probe sequence is h(i) = h0 + i*(i+1)/2 mod 2^k.
- // We're guaranteed to hit all table entries using this probe sequence.
- mask := t.size - 1
- h := itabHashFunc(inter, typ) & mask
- for i := uintptr(1); ; i++ {
- p := (**itab)(add(unsafe.Pointer(&t.entries), h*goarch.PtrSize))
- // Use atomic read here so if we see m != nil, we also see
- // the initializations of the fields of m.
- // m := *p
- m := (*itab)(atomic.Loadp(unsafe.Pointer(p)))
- if m == nil {
- return nil
- }
- if m.inter == inter && m._type == typ {
- return m
- }
- h += i
- h &= mask
- }
-}
-
-// itabAdd adds the given itab to the itab hash table.
-// itabLock must be held.
-func itabAdd(m *itab) {
- // Bugs can lead to calling this while mallocing is set,
- // typically because this is called while panicing.
- // Crash reliably, rather than only when we need to grow
- // the hash table.
- if getg().m.mallocing != 0 {
- throw("malloc deadlock")
- }
-
- t := itabTable
- if t.count >= 3*(t.size/4) { // 75% load factor
- // Grow hash table.
- // t2 = new(itabTableType) + some additional entries
- // We lie and tell malloc we want pointer-free memory because
- // all the pointed-to values are not in the heap.
- t2 := (*itabTableType)(mallocgc((2+2*t.size)*goarch.PtrSize, nil, true))
- t2.size = t.size * 2
-
- // Copy over entries.
- // Note: while copying, other threads may look for an itab and
- // fail to find it. That's ok, they will then try to get the itab lock
- // and as a consequence wait until this copying is complete.
- iterate_itabs(t2.add)
- if t2.count != t.count {
- throw("mismatched count during itab table copy")
- }
- // Publish new hash table. Use an atomic write: see comment in getitab.
- atomicstorep(unsafe.Pointer(&itabTable), unsafe.Pointer(t2))
- // Adopt the new table as our own.
- t = itabTable
- // Note: the old table can be GC'ed here.
- }
- t.add(m)
-}
-
-// add adds the given itab to itab table t.
-// itabLock must be held.
-func (t *itabTableType) add(m *itab) {
- // See comment in find about the probe sequence.
- // Insert new itab in the first empty spot in the probe sequence.
- mask := t.size - 1
- h := itabHashFunc(m.inter, m._type) & mask
- for i := uintptr(1); ; i++ {
- p := (**itab)(add(unsafe.Pointer(&t.entries), h*goarch.PtrSize))
- m2 := *p
- if m2 == m {
- // A given itab may be used in more than one module
- // and thanks to the way global symbol resolution works, the
- // pointed-to itab may already have been inserted into the
- // global 'hash'.
- return
- }
- if m2 == nil {
- // Use atomic write here so if a reader sees m, it also
- // sees the correctly initialized fields of m.
- // NoWB is ok because m is not in heap memory.
- // *p = m
- atomic.StorepNoWB(unsafe.Pointer(p), unsafe.Pointer(m))
- t.count++
- return
- }
- h += i
- h &= mask
- }
-}
-
-// init fills in the m.fun array with all the code pointers for
-// the m.inter/m._type pair. If the type does not implement the interface,
-// it sets m.fun[0] to 0 and returns the name of an interface function that is missing.
-// It is ok to call this multiple times on the same m, even concurrently.
-func (m *itab) init() string {
- inter := m.inter
- typ := m._type
- x := typ.uncommon()
-
- // both inter and typ have method sorted by name,
- // and interface names are unique,
- // so can iterate over both in lock step;
- // the loop is O(ni+nt) not O(ni*nt).
- ni := len(inter.mhdr)
- nt := int(x.mcount)
- xmhdr := (*[1 << 16]method)(add(unsafe.Pointer(x), uintptr(x.moff)))[:nt:nt]
- j := 0
- methods := (*[1 << 16]unsafe.Pointer)(unsafe.Pointer(&m.fun[0]))[:ni:ni]
- var fun0 unsafe.Pointer
-imethods:
- for k := 0; k < ni; k++ {
- i := &inter.mhdr[k]
- itype := inter.typ.typeOff(i.ityp)
- name := inter.typ.nameOff(i.name)
- iname := name.name()
- ipkg := name.pkgPath()
- if ipkg == "" {
- ipkg = inter.pkgpath.name()
- }
- for ; j < nt; j++ {
- t := &xmhdr[j]
- tname := typ.nameOff(t.name)
- if typ.typeOff(t.mtyp) == itype && tname.name() == iname {
- pkgPath := tname.pkgPath()
- if pkgPath == "" {
- pkgPath = typ.nameOff(x.pkgpath).name()
- }
- if tname.isExported() || pkgPath == ipkg {
- if m != nil {
- ifn := typ.textOff(t.ifn)
- if k == 0 {
- fun0 = ifn // we'll set m.fun[0] at the end
- } else {
- methods[k] = ifn
- }
- }
- continue imethods
- }
- }
- }
- // didn't find method
- m.fun[0] = 0
- return iname
- }
- m.fun[0] = uintptr(fun0)
- return ""
-}
-
-func itabsinit() {
- lockInit(&itabLock, lockRankItab)
- lock(&itabLock)
- for _, md := range activeModules() {
- for _, i := range md.itablinks {
- itabAdd(i)
- }
- }
- unlock(&itabLock)
-}
-
-// panicdottypeE is called when doing an e.(T) conversion and the conversion fails.
-// have = the dynamic type we have.
-// want = the static type we're trying to convert to.
-// iface = the static type we're converting from.
-func panicdottypeE(have, want, iface *_type) {
- panic(&TypeAssertionError{iface, have, want, ""})
-}
-
-// panicdottypeI is called when doing an i.(T) conversion and the conversion fails.
-// Same args as panicdottypeE, but "have" is the dynamic itab we have.
-func panicdottypeI(have *itab, want, iface *_type) {
- var t *_type
- if have != nil {
- t = have._type
- }
- panicdottypeE(t, want, iface)
-}
-
-// panicnildottype is called when doing a i.(T) conversion and the interface i is nil.
-// want = the static type we're trying to convert to.
-func panicnildottype(want *_type) {
- panic(&TypeAssertionError{nil, nil, want, ""})
- // TODO: Add the static type we're converting from as well.
- // It might generate a better error message.
- // Just to match other nil conversion errors, we don't for now.
-}
-
-// The specialized convTx routines need a type descriptor to use when calling mallocgc.
-// We don't need the type to be exact, just to have the correct size, alignment, and pointer-ness.
-// However, when debugging, it'd be nice to have some indication in mallocgc where the types came from,
-// so we use named types here.
-// We then construct interface values of these types,
-// and then extract the type word to use as needed.
-type (
- uint16InterfacePtr uint16
- uint32InterfacePtr uint32
- uint64InterfacePtr uint64
- stringInterfacePtr string
- sliceInterfacePtr []byte
-)
-
-var (
- uint16Eface any = uint16InterfacePtr(0)
- uint32Eface any = uint32InterfacePtr(0)
- uint64Eface any = uint64InterfacePtr(0)
- stringEface any = stringInterfacePtr("")
- sliceEface any = sliceInterfacePtr(nil)
-
- uint16Type *_type = efaceOf(&uint16Eface)._type
- uint32Type *_type = efaceOf(&uint32Eface)._type
- uint64Type *_type = efaceOf(&uint64Eface)._type
- stringType *_type = efaceOf(&stringEface)._type
- sliceType *_type = efaceOf(&sliceEface)._type
-)
-
-// The conv and assert functions below do very similar things.
-// The convXXX functions are guaranteed by the compiler to succeed.
-// The assertXXX functions may fail (either panicking or returning false,
-// depending on whether they are 1-result or 2-result).
-// The convXXX functions succeed on a nil input, whereas the assertXXX
-// functions fail on a nil input.
-
-// convT converts a value of type t, which is pointed to by v, to a pointer that can
-// be used as the second word of an interface value.
-func convT(t *_type, v unsafe.Pointer) unsafe.Pointer {
- if raceenabled {
- raceReadObjectPC(t, v, getcallerpc(), abi.FuncPCABIInternal(convT))
- }
- if msanenabled {
- msanread(v, t.size)
- }
- if asanenabled {
- asanread(v, t.size)
- }
- x := mallocgc(t.size, t, true)
- typedmemmove(t, x, v)
- return x
-}
-func convTnoptr(t *_type, v unsafe.Pointer) unsafe.Pointer {
- // TODO: maybe take size instead of type?
- if raceenabled {
- raceReadObjectPC(t, v, getcallerpc(), abi.FuncPCABIInternal(convTnoptr))
- }
- if msanenabled {
- msanread(v, t.size)
- }
- if asanenabled {
- asanread(v, t.size)
- }
-
- x := mallocgc(t.size, t, false)
- memmove(x, v, t.size)
- return x
-}
-
-func convT16(val uint16) (x unsafe.Pointer) {
- if val < uint16(len(staticuint64s)) {
- x = unsafe.Pointer(&staticuint64s[val])
- if goarch.BigEndian {
- x = add(x, 6)
- }
- } else {
- x = mallocgc(2, uint16Type, false)
- *(*uint16)(x) = val
- }
- return
-}
-
-func convT32(val uint32) (x unsafe.Pointer) {
- if val < uint32(len(staticuint64s)) {
- x = unsafe.Pointer(&staticuint64s[val])
- if goarch.BigEndian {
- x = add(x, 4)
- }
- } else {
- x = mallocgc(4, uint32Type, false)
- *(*uint32)(x) = val
- }
- return
-}
-
-func convT64(val uint64) (x unsafe.Pointer) {
- if val < uint64(len(staticuint64s)) {
- x = unsafe.Pointer(&staticuint64s[val])
- } else {
- x = mallocgc(8, uint64Type, false)
- *(*uint64)(x) = val
- }
- return
-}
-
-func convTstring(val string) (x unsafe.Pointer) {
- if val == "" {
- x = unsafe.Pointer(&zeroVal[0])
- } else {
- x = mallocgc(unsafe.Sizeof(val), stringType, true)
- *(*string)(x) = val
- }
- return
-}
-
-func convTslice(val []byte) (x unsafe.Pointer) {
- // Note: this must work for any element type, not just byte.
- if (*slice)(unsafe.Pointer(&val)).array == nil {
- x = unsafe.Pointer(&zeroVal[0])
- } else {
- x = mallocgc(unsafe.Sizeof(val), sliceType, true)
- *(*[]byte)(x) = val
- }
- return
-}
-
-// convI2I returns the new itab to be used for the destination value
-// when converting a value with itab src to the dst interface.
-func convI2I(dst *interfacetype, src *itab) *itab {
- if src == nil {
- return nil
- }
- if src.inter == dst {
- return src
- }
- return getitab(dst, src._type, false)
-}
-
-func assertI2I(inter *interfacetype, tab *itab) *itab {
- if tab == nil {
- // explicit conversions require non-nil interface value.
- panic(&TypeAssertionError{nil, nil, &inter.typ, ""})
- }
- if tab.inter == inter {
- return tab
- }
- return getitab(inter, tab._type, false)
-}
-
-func assertI2I2(inter *interfacetype, i iface) (r iface) {
- tab := i.tab
- if tab == nil {
- return
- }
- if tab.inter != inter {
- tab = getitab(inter, tab._type, true)
- if tab == nil {
- return
- }
- }
- r.tab = tab
- r.data = i.data
- return
-}
-
-func assertE2I(inter *interfacetype, t *_type) *itab {
- if t == nil {
- // explicit conversions require non-nil interface value.
- panic(&TypeAssertionError{nil, nil, &inter.typ, ""})
- }
- return getitab(inter, t, false)
-}
-
-func assertE2I2(inter *interfacetype, e eface) (r iface) {
- t := e._type
- if t == nil {
- return
- }
- tab := getitab(inter, t, true)
- if tab == nil {
- return
- }
- r.tab = tab
- r.data = e.data
- return
-}
-
-//go:linkname reflect_ifaceE2I reflect.ifaceE2I
-func reflect_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
- *dst = iface{assertE2I(inter, e._type), e.data}
-}
-
-//go:linkname reflectlite_ifaceE2I internal/reflectlite.ifaceE2I
-func reflectlite_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
- *dst = iface{assertE2I(inter, e._type), e.data}
-}
-
-func iterate_itabs(fn func(*itab)) {
- // Note: only runs during stop the world or with itabLock held,
- // so no other locks/atomics needed.
- t := itabTable
- for i := uintptr(0); i < t.size; i++ {
- m := *(**itab)(add(unsafe.Pointer(&t.entries), i*goarch.PtrSize))
- if m != nil {
- fn(m)
- }
- }
-}
-
-// staticuint64s is used to avoid allocating in convTx for small integer values.
-var staticuint64s = [...]uint64{
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
- 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
- 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
- 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
- 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
- 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
- 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
- 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
- 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
- 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
- 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
- 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
- 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
- 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
- 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
- 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
- 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
-}
-
-// The linker redirects a reference of a method that it determined
-// unreachable to a reference to this function, so it will throw if
-// ever called.
-func unreachableMethod() {
- throw("unreachable method called. linker bug?")
-}
diff --git a/contrib/go/_std_1.20/src/runtime/internal/atomic/ya.make b/contrib/go/_std_1.20/src/runtime/internal/atomic/ya.make
deleted file mode 100644
index 8dcbfba8f2..0000000000
--- a/contrib/go/_std_1.20/src/runtime/internal/atomic/ya.make
+++ /dev/null
@@ -1,25 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- doc.go
- stubs.go
- types.go
- types_64bit.go
- unaligned.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- atomic_arm64.go
- atomic_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- atomic_amd64.go
- atomic_amd64.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/runtime/internal/math/ya.make b/contrib/go/_std_1.20/src/runtime/internal/math/ya.make
deleted file mode 100644
index cc28532d20..0000000000
--- a/contrib/go/_std_1.20/src/runtime/internal/math/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- math.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/runtime/internal/sys/intrinsics.go b/contrib/go/_std_1.20/src/runtime/internal/sys/intrinsics.go
deleted file mode 100644
index 902d893178..0000000000
--- a/contrib/go/_std_1.20/src/runtime/internal/sys/intrinsics.go
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2016 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.
-
-//go:build !386
-
-// TODO finish intrinsifying 386, deadcode the assembly, remove build tags, merge w/ intrinsics_common
-
-package sys
-
-// Copied from math/bits to avoid dependence.
-
-var deBruijn32tab = [32]byte{
- 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
- 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9,
-}
-
-const deBruijn32 = 0x077CB531
-
-var deBruijn64tab = [64]byte{
- 0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
- 62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
- 63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
- 54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
-}
-
-const deBruijn64 = 0x03f79d71b4ca8b09
-
-const ntz8tab = "" +
- "\x08\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x06\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x07\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x06\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
- "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00"
-
-// TrailingZeros32 returns the number of trailing zero bits in x; the result is 32 for x == 0.
-func TrailingZeros32(x uint32) int {
- if x == 0 {
- return 32
- }
- // see comment in TrailingZeros64
- return int(deBruijn32tab[(x&-x)*deBruijn32>>(32-5)])
-}
-
-// TrailingZeros64 returns the number of trailing zero bits in x; the result is 64 for x == 0.
-func TrailingZeros64(x uint64) int {
- if x == 0 {
- return 64
- }
- // If popcount is fast, replace code below with return popcount(^x & (x - 1)).
- //
- // x & -x leaves only the right-most bit set in the word. Let k be the
- // index of that bit. Since only a single bit is set, the value is two
- // to the power of k. Multiplying by a power of two is equivalent to
- // left shifting, in this case by k bits. The de Bruijn (64 bit) constant
- // is such that all six bit, consecutive substrings are distinct.
- // Therefore, if we have a left shifted version of this constant we can
- // find by how many bits it was shifted by looking at which six bit
- // substring ended up at the top of the word.
- // (Knuth, volume 4, section 7.3.1)
- return int(deBruijn64tab[(x&-x)*deBruijn64>>(64-6)])
-}
-
-// TrailingZeros8 returns the number of trailing zero bits in x; the result is 8 for x == 0.
-func TrailingZeros8(x uint8) int {
- return int(ntz8tab[x])
-}
-
-// Bswap64 returns its input with byte order reversed
-// 0x0102030405060708 -> 0x0807060504030201
-func Bswap64(x uint64) uint64 {
- c8 := uint64(0x00ff00ff00ff00ff)
- a := x >> 8 & c8
- b := (x & c8) << 8
- x = a | b
- c16 := uint64(0x0000ffff0000ffff)
- a = x >> 16 & c16
- b = (x & c16) << 16
- x = a | b
- c32 := uint64(0x00000000ffffffff)
- a = x >> 32 & c32
- b = (x & c32) << 32
- x = a | b
- return x
-}
-
-// Bswap32 returns its input with byte order reversed
-// 0x01020304 -> 0x04030201
-func Bswap32(x uint32) uint32 {
- c8 := uint32(0x00ff00ff)
- a := x >> 8 & c8
- b := (x & c8) << 8
- x = a | b
- c16 := uint32(0x0000ffff)
- a = x >> 16 & c16
- b = (x & c16) << 16
- x = a | b
- return x
-}
diff --git a/contrib/go/_std_1.20/src/runtime/internal/sys/intrinsics_common.go b/contrib/go/_std_1.20/src/runtime/internal/sys/intrinsics_common.go
deleted file mode 100644
index 1461551dda..0000000000
--- a/contrib/go/_std_1.20/src/runtime/internal/sys/intrinsics_common.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sys
-
-// Copied from math/bits to avoid dependence.
-
-const len8tab = "" +
- "\x00\x01\x02\x02\x03\x03\x03\x03\x04\x04\x04\x04\x04\x04\x04\x04" +
- "\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05" +
- "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06" +
- "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06" +
- "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
- "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
- "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
- "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
- "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
- "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
- "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
- "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
- "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
- "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
- "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
- "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"
-
-// Len64 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
-//
-// nosplit because this is used in src/runtime/histogram.go, which make run in sensitive contexts.
-//
-//go:nosplit
-func Len64(x uint64) (n int) {
- if x >= 1<<32 {
- x >>= 32
- n = 32
- }
- if x >= 1<<16 {
- x >>= 16
- n += 16
- }
- if x >= 1<<8 {
- x >>= 8
- n += 8
- }
- return n + int(len8tab[x])
-}
-
-// --- OnesCount ---
-
-const m0 = 0x5555555555555555 // 01010101 ...
-const m1 = 0x3333333333333333 // 00110011 ...
-const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ...
-
-// OnesCount64 returns the number of one bits ("population count") in x.
-func OnesCount64(x uint64) int {
- // Implementation: Parallel summing of adjacent bits.
- // See "Hacker's Delight", Chap. 5: Counting Bits.
- // The following pattern shows the general approach:
- //
- // x = x>>1&(m0&m) + x&(m0&m)
- // x = x>>2&(m1&m) + x&(m1&m)
- // x = x>>4&(m2&m) + x&(m2&m)
- // x = x>>8&(m3&m) + x&(m3&m)
- // x = x>>16&(m4&m) + x&(m4&m)
- // x = x>>32&(m5&m) + x&(m5&m)
- // return int(x)
- //
- // Masking (& operations) can be left away when there's no
- // danger that a field's sum will carry over into the next
- // field: Since the result cannot be > 64, 8 bits is enough
- // and we can ignore the masks for the shifts by 8 and up.
- // Per "Hacker's Delight", the first line can be simplified
- // more, but it saves at best one instruction, so we leave
- // it alone for clarity.
- const m = 1<<64 - 1
- x = x>>1&(m0&m) + x&(m0&m)
- x = x>>2&(m1&m) + x&(m1&m)
- x = (x>>4 + x) & (m2 & m)
- x += x >> 8
- x += x >> 16
- x += x >> 32
- return int(x) & (1<<7 - 1)
-}
-
-// LeadingZeros64 returns the number of leading zero bits in x; the result is 64 for x == 0.
-func LeadingZeros64(x uint64) int { return 64 - Len64(x) }
-
-// LeadingZeros8 returns the number of leading zero bits in x; the result is 8 for x == 0.
-func LeadingZeros8(x uint8) int { return 8 - Len8(x) }
-
-// Len8 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
-func Len8(x uint8) int {
- return int(len8tab[x])
-}
-
-// Prefetch prefetches data from memory addr to cache
-//
-// AMD64: Produce PREFETCHT0 instruction
-//
-// ARM64: Produce PRFM instruction with PLDL1KEEP option
-func Prefetch(addr uintptr) {}
-
-// PrefetchStreamed prefetches data from memory addr, with a hint that this data is being streamed.
-// That is, it is likely to be accessed very soon, but only once. If possible, this will avoid polluting the cache.
-//
-// AMD64: Produce PREFETCHNTA instruction
-//
-// ARM64: Produce PRFM instruction with PLDL1STRM option
-func PrefetchStreamed(addr uintptr) {}
diff --git a/contrib/go/_std_1.20/src/runtime/internal/sys/ya.make b/contrib/go/_std_1.20/src/runtime/internal/sys/ya.make
deleted file mode 100644
index a9ace4e75c..0000000000
--- a/contrib/go/_std_1.20/src/runtime/internal/sys/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- consts.go
- consts_norace.go
- intrinsics.go
- intrinsics_common.go
- nih.go
- sys.go
- zversion.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/runtime/internal/syscall/defs_linux.go b/contrib/go/_std_1.20/src/runtime/internal/syscall/defs_linux.go
deleted file mode 100644
index 71f1fa1453..0000000000
--- a/contrib/go/_std_1.20/src/runtime/internal/syscall/defs_linux.go
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2022 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 syscall
-
-const (
- F_SETFD = 2
- FD_CLOEXEC = 1
-)
diff --git a/contrib/go/_std_1.20/src/runtime/internal/syscall/syscall_linux.go b/contrib/go/_std_1.20/src/runtime/internal/syscall/syscall_linux.go
deleted file mode 100644
index a103d318c4..0000000000
--- a/contrib/go/_std_1.20/src/runtime/internal/syscall/syscall_linux.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2022 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 syscall provides the syscall primitives required for the runtime.
-package syscall
-
-import (
- "unsafe"
-)
-
-// TODO(https://go.dev/issue/51087): This package is incomplete and currently
-// only contains very minimal support for Linux.
-
-// Syscall6 calls system call number 'num' with arguments a1-6.
-func Syscall6(num, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr)
-
-// syscall_RawSyscall6 is a push linkname to export Syscall6 as
-// syscall.RawSyscall6.
-//
-// //go:uintptrkeepalive because the uintptr argument may be converted pointers
-// that need to be kept alive in the caller (this is implied for Syscall6 since
-// it has no body).
-//
-// //go:nosplit because stack copying does not account for uintptrkeepalive, so
-// the stack must not grow. Stack copying cannot blindly assume that all
-// uintptr arguments are pointers, because some values may look like pointers,
-// but not really be pointers, and adjusting their value would break the call.
-//
-// This is a separate wrapper because we can't export one function as two
-// names. The assembly implementations name themselves Syscall6 would not be
-// affected by a linkname.
-//
-//go:uintptrkeepalive
-//go:nosplit
-//go:linkname syscall_RawSyscall6 syscall.RawSyscall6
-func syscall_RawSyscall6(num, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr) {
- return Syscall6(num, a1, a2, a3, a4, a5, a6)
-}
-
-func EpollCreate1(flags int32) (fd int32, errno uintptr) {
- r1, _, e := Syscall6(SYS_EPOLL_CREATE1, uintptr(flags), 0, 0, 0, 0, 0)
- return int32(r1), e
-}
-
-var _zero uintptr
-
-func EpollWait(epfd int32, events []EpollEvent, maxev, waitms int32) (n int32, errno uintptr) {
- var ev unsafe.Pointer
- if len(events) > 0 {
- ev = unsafe.Pointer(&events[0])
- } else {
- ev = unsafe.Pointer(&_zero)
- }
- r1, _, e := Syscall6(SYS_EPOLL_PWAIT, uintptr(epfd), uintptr(ev), uintptr(maxev), uintptr(waitms), 0, 0)
- return int32(r1), e
-}
-
-func EpollCtl(epfd, op, fd int32, event *EpollEvent) (errno uintptr) {
- _, _, e := Syscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
- return e
-}
-
-func CloseOnExec(fd int32) {
- Syscall6(SYS_FCNTL, uintptr(fd), F_SETFD, FD_CLOEXEC, 0, 0, 0)
-}
diff --git a/contrib/go/_std_1.20/src/runtime/internal/syscall/ya.make b/contrib/go/_std_1.20/src/runtime/internal/syscall/ya.make
deleted file mode 100644
index a9c2ffc002..0000000000
--- a/contrib/go/_std_1.20/src/runtime/internal/syscall/ya.make
+++ /dev/null
@@ -1,26 +0,0 @@
-GO_LIBRARY()
-
-BUILD_ONLY_IF(WARNING OS_LINUX)
-
-IF (OS_LINUX)
- SRCS(
- defs_linux.go
- syscall_linux.go
- )
-
- IF (ARCH_ARM64)
- SRCS(
- asm_linux_arm64.s
- defs_linux_arm64.go
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- asm_linux_amd64.s
- defs_linux_amd64.go
- )
- ENDIF()
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/runtime/internal/ya.make b/contrib/go/_std_1.20/src/runtime/internal/ya.make
deleted file mode 100644
index f820a4ace4..0000000000
--- a/contrib/go/_std_1.20/src/runtime/internal/ya.make
+++ /dev/null
@@ -1,17 +0,0 @@
-RECURSE(
- atomic
- math
- sys
-)
-
-IF (ARCH_X86_64)
- RECURSE(
- startlinetest
- )
-ENDIF()
-
-IF (OS_LINUX)
- RECURSE(
- syscall
- )
-ENDIF()
diff --git a/contrib/go/_std_1.20/src/runtime/lfstack.go b/contrib/go/_std_1.20/src/runtime/lfstack.go
deleted file mode 100644
index 306a8e888a..0000000000
--- a/contrib/go/_std_1.20/src/runtime/lfstack.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2012 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.
-
-// Lock-free stack.
-
-package runtime
-
-import (
- "runtime/internal/atomic"
- "unsafe"
-)
-
-// lfstack is the head of a lock-free stack.
-//
-// The zero value of lfstack is an empty list.
-//
-// This stack is intrusive. Nodes must embed lfnode as the first field.
-//
-// The stack does not keep GC-visible pointers to nodes, so the caller
-// must ensure the nodes are allocated outside the Go heap.
-type lfstack uint64
-
-func (head *lfstack) push(node *lfnode) {
- node.pushcnt++
- new := lfstackPack(node, node.pushcnt)
- if node1 := lfstackUnpack(new); node1 != node {
- print("runtime: lfstack.push invalid packing: node=", node, " cnt=", hex(node.pushcnt), " packed=", hex(new), " -> node=", node1, "\n")
- throw("lfstack.push")
- }
- for {
- old := atomic.Load64((*uint64)(head))
- node.next = old
- if atomic.Cas64((*uint64)(head), old, new) {
- break
- }
- }
-}
-
-func (head *lfstack) pop() unsafe.Pointer {
- for {
- old := atomic.Load64((*uint64)(head))
- if old == 0 {
- return nil
- }
- node := lfstackUnpack(old)
- next := atomic.Load64(&node.next)
- if atomic.Cas64((*uint64)(head), old, next) {
- return unsafe.Pointer(node)
- }
- }
-}
-
-func (head *lfstack) empty() bool {
- return atomic.Load64((*uint64)(head)) == 0
-}
-
-// lfnodeValidate panics if node is not a valid address for use with
-// lfstack.push. This only needs to be called when node is allocated.
-func lfnodeValidate(node *lfnode) {
- if base, _, _ := findObject(uintptr(unsafe.Pointer(node)), 0, 0); base != 0 {
- throw("lfstack node allocated from the heap")
- }
- if lfstackUnpack(lfstackPack(node, ^uintptr(0))) != node {
- printlock()
- println("runtime: bad lfnode address", hex(uintptr(unsafe.Pointer(node))))
- throw("bad lfnode address")
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/lfstack_64bit.go b/contrib/go/_std_1.20/src/runtime/lfstack_64bit.go
deleted file mode 100644
index 88cbd3bcc7..0000000000
--- a/contrib/go/_std_1.20/src/runtime/lfstack_64bit.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2014 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.
-
-//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm
-
-package runtime
-
-import "unsafe"
-
-const (
- // addrBits is the number of bits needed to represent a virtual address.
- //
- // See heapAddrBits for a table of address space sizes on
- // various architectures. 48 bits is enough for all
- // architectures except s390x.
- //
- // On AMD64, virtual addresses are 48-bit (or 57-bit) numbers sign extended to 64.
- // We shift the address left 16 to eliminate the sign extended part and make
- // room in the bottom for the count.
- //
- // On s390x, virtual addresses are 64-bit. There's not much we
- // can do about this, so we just hope that the kernel doesn't
- // get to really high addresses and panic if it does.
- addrBits = 48
-
- // In addition to the 16 bits taken from the top, we can take 3 from the
- // bottom, because node must be pointer-aligned, giving a total of 19 bits
- // of count.
- cntBits = 64 - addrBits + 3
-
- // On AIX, 64-bit addresses are split into 36-bit segment number and 28-bit
- // offset in segment. Segment numbers in the range 0x0A0000000-0x0AFFFFFFF(LSA)
- // are available for mmap.
- // We assume all lfnode addresses are from memory allocated with mmap.
- // We use one bit to distinguish between the two ranges.
- aixAddrBits = 57
- aixCntBits = 64 - aixAddrBits + 3
-
- // riscv64 SV57 mode gives 56 bits of userspace VA.
- // lfstack code supports it, but broader support for SV57 mode is incomplete,
- // and there may be other issues (see #54104).
- riscv64AddrBits = 56
- riscv64CntBits = 64 - riscv64AddrBits + 3
-)
-
-func lfstackPack(node *lfnode, cnt uintptr) uint64 {
- if GOARCH == "ppc64" && GOOS == "aix" {
- return uint64(uintptr(unsafe.Pointer(node)))<<(64-aixAddrBits) | uint64(cnt&(1<<aixCntBits-1))
- }
- if GOARCH == "riscv64" {
- return uint64(uintptr(unsafe.Pointer(node)))<<(64-riscv64AddrBits) | uint64(cnt&(1<<riscv64CntBits-1))
- }
- return uint64(uintptr(unsafe.Pointer(node)))<<(64-addrBits) | uint64(cnt&(1<<cntBits-1))
-}
-
-func lfstackUnpack(val uint64) *lfnode {
- if GOARCH == "amd64" {
- // amd64 systems can place the stack above the VA hole, so we need to sign extend
- // val before unpacking.
- return (*lfnode)(unsafe.Pointer(uintptr(int64(val) >> cntBits << 3)))
- }
- if GOARCH == "ppc64" && GOOS == "aix" {
- return (*lfnode)(unsafe.Pointer(uintptr((val >> aixCntBits << 3) | 0xa<<56)))
- }
- if GOARCH == "riscv64" {
- return (*lfnode)(unsafe.Pointer(uintptr(val >> riscv64CntBits << 3)))
- }
- return (*lfnode)(unsafe.Pointer(uintptr(val >> cntBits << 3)))
-}
diff --git a/contrib/go/_std_1.20/src/runtime/lockrank.go b/contrib/go/_std_1.20/src/runtime/lockrank.go
deleted file mode 100644
index 284a61e336..0000000000
--- a/contrib/go/_std_1.20/src/runtime/lockrank.go
+++ /dev/null
@@ -1,184 +0,0 @@
-// Code generated by mklockrank.go; DO NOT EDIT.
-
-package runtime
-
-type lockRank int
-
-// Constants representing the ranks of all non-leaf runtime locks, in rank order.
-// Locks with lower rank must be taken before locks with higher rank,
-// in addition to satisfying the partial order in lockPartialOrder.
-// A few ranks allow self-cycles, which are specified in lockPartialOrder.
-const (
- lockRankUnknown lockRank = iota
-
- lockRankSysmon
- lockRankScavenge
- lockRankForcegc
- lockRankDefer
- lockRankSweepWaiters
- lockRankAssistQueue
- lockRankSweep
- lockRankPollDesc
- lockRankCpuprof
- lockRankSched
- lockRankAllg
- lockRankAllp
- lockRankTimers
- lockRankNetpollInit
- lockRankHchan
- lockRankNotifyList
- lockRankSudog
- lockRankRwmutexW
- lockRankRwmutexR
- lockRankRoot
- lockRankItab
- lockRankReflectOffs
- lockRankUserArenaState
- // TRACEGLOBAL
- lockRankTraceBuf
- lockRankTraceStrings
- // MALLOC
- lockRankFin
- lockRankGcBitsArenas
- lockRankMheapSpecial
- lockRankMspanSpecial
- lockRankSpanSetSpine
- // MPROF
- lockRankProfInsert
- lockRankProfBlock
- lockRankProfMemActive
- lockRankProfMemFuture
- // STACKGROW
- lockRankGscan
- lockRankStackpool
- lockRankStackLarge
- lockRankHchanLeaf
- // WB
- lockRankWbufSpans
- lockRankMheap
- lockRankGlobalAlloc
- // TRACE
- lockRankTrace
- lockRankTraceStackTab
- lockRankPanic
- lockRankDeadlock
-)
-
-// lockRankLeafRank is the rank of lock that does not have a declared rank,
-// and hence is a leaf lock.
-const lockRankLeafRank lockRank = 1000
-
-// lockNames gives the names associated with each of the above ranks.
-var lockNames = []string{
- lockRankSysmon: "sysmon",
- lockRankScavenge: "scavenge",
- lockRankForcegc: "forcegc",
- lockRankDefer: "defer",
- lockRankSweepWaiters: "sweepWaiters",
- lockRankAssistQueue: "assistQueue",
- lockRankSweep: "sweep",
- lockRankPollDesc: "pollDesc",
- lockRankCpuprof: "cpuprof",
- lockRankSched: "sched",
- lockRankAllg: "allg",
- lockRankAllp: "allp",
- lockRankTimers: "timers",
- lockRankNetpollInit: "netpollInit",
- lockRankHchan: "hchan",
- lockRankNotifyList: "notifyList",
- lockRankSudog: "sudog",
- lockRankRwmutexW: "rwmutexW",
- lockRankRwmutexR: "rwmutexR",
- lockRankRoot: "root",
- lockRankItab: "itab",
- lockRankReflectOffs: "reflectOffs",
- lockRankUserArenaState: "userArenaState",
- lockRankTraceBuf: "traceBuf",
- lockRankTraceStrings: "traceStrings",
- lockRankFin: "fin",
- lockRankGcBitsArenas: "gcBitsArenas",
- lockRankMheapSpecial: "mheapSpecial",
- lockRankMspanSpecial: "mspanSpecial",
- lockRankSpanSetSpine: "spanSetSpine",
- lockRankProfInsert: "profInsert",
- lockRankProfBlock: "profBlock",
- lockRankProfMemActive: "profMemActive",
- lockRankProfMemFuture: "profMemFuture",
- lockRankGscan: "gscan",
- lockRankStackpool: "stackpool",
- lockRankStackLarge: "stackLarge",
- lockRankHchanLeaf: "hchanLeaf",
- lockRankWbufSpans: "wbufSpans",
- lockRankMheap: "mheap",
- lockRankGlobalAlloc: "globalAlloc",
- lockRankTrace: "trace",
- lockRankTraceStackTab: "traceStackTab",
- lockRankPanic: "panic",
- lockRankDeadlock: "deadlock",
-}
-
-func (rank lockRank) String() string {
- if rank == 0 {
- return "UNKNOWN"
- }
- if rank == lockRankLeafRank {
- return "LEAF"
- }
- if rank < 0 || int(rank) >= len(lockNames) {
- return "BAD RANK"
- }
- return lockNames[rank]
-}
-
-// lockPartialOrder is the transitive closure of the lock rank graph.
-// An entry for rank X lists all of the ranks that can already be held
-// when rank X is acquired.
-//
-// Lock ranks that allow self-cycles list themselves.
-var lockPartialOrder [][]lockRank = [][]lockRank{
- lockRankSysmon: {},
- lockRankScavenge: {lockRankSysmon},
- lockRankForcegc: {lockRankSysmon},
- lockRankDefer: {},
- lockRankSweepWaiters: {},
- lockRankAssistQueue: {},
- lockRankSweep: {},
- lockRankPollDesc: {},
- lockRankCpuprof: {},
- lockRankSched: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof},
- lockRankAllg: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched},
- lockRankAllp: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched},
- lockRankTimers: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllp, lockRankTimers},
- lockRankNetpollInit: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllp, lockRankTimers},
- lockRankHchan: {lockRankSysmon, lockRankScavenge, lockRankSweep, lockRankHchan},
- lockRankNotifyList: {},
- lockRankSudog: {lockRankSysmon, lockRankScavenge, lockRankSweep, lockRankHchan, lockRankNotifyList},
- lockRankRwmutexW: {},
- lockRankRwmutexR: {lockRankSysmon, lockRankRwmutexW},
- lockRankRoot: {},
- lockRankItab: {},
- lockRankReflectOffs: {lockRankItab},
- lockRankUserArenaState: {},
- lockRankTraceBuf: {lockRankSysmon, lockRankScavenge},
- lockRankTraceStrings: {lockRankSysmon, lockRankScavenge, lockRankTraceBuf},
- lockRankFin: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
- lockRankGcBitsArenas: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
- lockRankMheapSpecial: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
- lockRankMspanSpecial: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
- lockRankSpanSetSpine: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
- lockRankProfInsert: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
- lockRankProfBlock: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
- lockRankProfMemActive: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
- lockRankProfMemFuture: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankProfMemActive},
- lockRankGscan: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture},
- lockRankStackpool: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan},
- lockRankStackLarge: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan},
- lockRankHchanLeaf: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankHchanLeaf},
- lockRankWbufSpans: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan},
- lockRankMheap: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans},
- lockRankGlobalAlloc: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMheapSpecial, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap},
- lockRankTrace: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap},
- lockRankTraceStackTab: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankGcBitsArenas, lockRankMspanSpecial, lockRankSpanSetSpine, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap, lockRankTrace},
- lockRankPanic: {},
- lockRankDeadlock: {lockRankPanic, lockRankDeadlock},
-}
diff --git a/contrib/go/_std_1.20/src/runtime/lockrank_off.go b/contrib/go/_std_1.20/src/runtime/lockrank_off.go
deleted file mode 100644
index bf046a1041..0000000000
--- a/contrib/go/_std_1.20/src/runtime/lockrank_off.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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.
-
-//go:build !goexperiment.staticlockranking
-
-package runtime
-
-// // lockRankStruct is embedded in mutex, but is empty when staticklockranking is
-// disabled (the default)
-type lockRankStruct struct {
-}
-
-func lockInit(l *mutex, rank lockRank) {
-}
-
-func getLockRank(l *mutex) lockRank {
- return 0
-}
-
-func lockWithRank(l *mutex, rank lockRank) {
- lock2(l)
-}
-
-// This function may be called in nosplit context and thus must be nosplit.
-//
-//go:nosplit
-func acquireLockRank(rank lockRank) {
-}
-
-func unlockWithRank(l *mutex) {
- unlock2(l)
-}
-
-// This function may be called in nosplit context and thus must be nosplit.
-//
-//go:nosplit
-func releaseLockRank(rank lockRank) {
-}
-
-func lockWithRankMayAcquire(l *mutex, rank lockRank) {
-}
-
-//go:nosplit
-func assertLockHeld(l *mutex) {
-}
-
-//go:nosplit
-func assertRankHeld(r lockRank) {
-}
-
-//go:nosplit
-func worldStopped() {
-}
-
-//go:nosplit
-func worldStarted() {
-}
-
-//go:nosplit
-func assertWorldStopped() {
-}
-
-//go:nosplit
-func assertWorldStoppedOrLockHeld(l *mutex) {
-}
diff --git a/contrib/go/_std_1.20/src/runtime/malloc.go b/contrib/go/_std_1.20/src/runtime/malloc.go
deleted file mode 100644
index 7ff2190876..0000000000
--- a/contrib/go/_std_1.20/src/runtime/malloc.go
+++ /dev/null
@@ -1,1562 +0,0 @@
-// Copyright 2014 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.
-
-// Memory allocator.
-//
-// This was originally based on tcmalloc, but has diverged quite a bit.
-// http://goog-perftools.sourceforge.net/doc/tcmalloc.html
-
-// The main allocator works in runs of pages.
-// Small allocation sizes (up to and including 32 kB) are
-// rounded to one of about 70 size classes, each of which
-// has its own free set of objects of exactly that size.
-// Any free page of memory can be split into a set of objects
-// of one size class, which are then managed using a free bitmap.
-//
-// The allocator's data structures are:
-//
-// fixalloc: a free-list allocator for fixed-size off-heap objects,
-// used to manage storage used by the allocator.
-// mheap: the malloc heap, managed at page (8192-byte) granularity.
-// mspan: a run of in-use pages managed by the mheap.
-// mcentral: collects all spans of a given size class.
-// mcache: a per-P cache of mspans with free space.
-// mstats: allocation statistics.
-//
-// Allocating a small object proceeds up a hierarchy of caches:
-//
-// 1. Round the size up to one of the small size classes
-// and look in the corresponding mspan in this P's mcache.
-// Scan the mspan's free bitmap to find a free slot.
-// If there is a free slot, allocate it.
-// This can all be done without acquiring a lock.
-//
-// 2. If the mspan has no free slots, obtain a new mspan
-// from the mcentral's list of mspans of the required size
-// class that have free space.
-// Obtaining a whole span amortizes the cost of locking
-// the mcentral.
-//
-// 3. If the mcentral's mspan list is empty, obtain a run
-// of pages from the mheap to use for the mspan.
-//
-// 4. If the mheap is empty or has no page runs large enough,
-// allocate a new group of pages (at least 1MB) from the
-// operating system. Allocating a large run of pages
-// amortizes the cost of talking to the operating system.
-//
-// Sweeping an mspan and freeing objects on it proceeds up a similar
-// hierarchy:
-//
-// 1. If the mspan is being swept in response to allocation, it
-// is returned to the mcache to satisfy the allocation.
-//
-// 2. Otherwise, if the mspan still has allocated objects in it,
-// it is placed on the mcentral free list for the mspan's size
-// class.
-//
-// 3. Otherwise, if all objects in the mspan are free, the mspan's
-// pages are returned to the mheap and the mspan is now dead.
-//
-// Allocating and freeing a large object uses the mheap
-// directly, bypassing the mcache and mcentral.
-//
-// If mspan.needzero is false, then free object slots in the mspan are
-// already zeroed. Otherwise if needzero is true, objects are zeroed as
-// they are allocated. There are various benefits to delaying zeroing
-// this way:
-//
-// 1. Stack frame allocation can avoid zeroing altogether.
-//
-// 2. It exhibits better temporal locality, since the program is
-// probably about to write to the memory.
-//
-// 3. We don't zero pages that never get reused.
-
-// Virtual memory layout
-//
-// The heap consists of a set of arenas, which are 64MB on 64-bit and
-// 4MB on 32-bit (heapArenaBytes). Each arena's start address is also
-// aligned to the arena size.
-//
-// Each arena has an associated heapArena object that stores the
-// metadata for that arena: the heap bitmap for all words in the arena
-// and the span map for all pages in the arena. heapArena objects are
-// themselves allocated off-heap.
-//
-// Since arenas are aligned, the address space can be viewed as a
-// series of arena frames. The arena map (mheap_.arenas) maps from
-// arena frame number to *heapArena, or nil for parts of the address
-// space not backed by the Go heap. The arena map is structured as a
-// two-level array consisting of a "L1" arena map and many "L2" arena
-// maps; however, since arenas are large, on many architectures, the
-// arena map consists of a single, large L2 map.
-//
-// The arena map covers the entire possible address space, allowing
-// the Go heap to use any part of the address space. The allocator
-// attempts to keep arenas contiguous so that large spans (and hence
-// large objects) can cross arenas.
-
-package runtime
-
-import (
- "internal/goarch"
- "internal/goos"
- "runtime/internal/atomic"
- "runtime/internal/math"
- "runtime/internal/sys"
- "unsafe"
-)
-
-const (
- maxTinySize = _TinySize
- tinySizeClass = _TinySizeClass
- maxSmallSize = _MaxSmallSize
-
- pageShift = _PageShift
- pageSize = _PageSize
-
- concurrentSweep = _ConcurrentSweep
-
- _PageSize = 1 << _PageShift
- _PageMask = _PageSize - 1
-
- // _64bit = 1 on 64-bit systems, 0 on 32-bit systems
- _64bit = 1 << (^uintptr(0) >> 63) / 2
-
- // Tiny allocator parameters, see "Tiny allocator" comment in malloc.go.
- _TinySize = 16
- _TinySizeClass = int8(2)
-
- _FixAllocChunk = 16 << 10 // Chunk size for FixAlloc
-
- // Per-P, per order stack segment cache size.
- _StackCacheSize = 32 * 1024
-
- // Number of orders that get caching. Order 0 is FixedStack
- // and each successive order is twice as large.
- // We want to cache 2KB, 4KB, 8KB, and 16KB stacks. Larger stacks
- // will be allocated directly.
- // Since FixedStack is different on different systems, we
- // must vary NumStackOrders to keep the same maximum cached size.
- // OS | FixedStack | NumStackOrders
- // -----------------+------------+---------------
- // linux/darwin/bsd | 2KB | 4
- // windows/32 | 4KB | 3
- // windows/64 | 8KB | 2
- // plan9 | 4KB | 3
- _NumStackOrders = 4 - goarch.PtrSize/4*goos.IsWindows - 1*goos.IsPlan9
-
- // heapAddrBits is the number of bits in a heap address. On
- // amd64, addresses are sign-extended beyond heapAddrBits. On
- // other arches, they are zero-extended.
- //
- // On most 64-bit platforms, we limit this to 48 bits based on a
- // combination of hardware and OS limitations.
- //
- // amd64 hardware limits addresses to 48 bits, sign-extended
- // to 64 bits. Addresses where the top 16 bits are not either
- // all 0 or all 1 are "non-canonical" and invalid. Because of
- // these "negative" addresses, we offset addresses by 1<<47
- // (arenaBaseOffset) on amd64 before computing indexes into
- // the heap arenas index. In 2017, amd64 hardware added
- // support for 57 bit addresses; however, currently only Linux
- // supports this extension and the kernel will never choose an
- // address above 1<<47 unless mmap is called with a hint
- // address above 1<<47 (which we never do).
- //
- // arm64 hardware (as of ARMv8) limits user addresses to 48
- // bits, in the range [0, 1<<48).
- //
- // ppc64, mips64, and s390x support arbitrary 64 bit addresses
- // in hardware. On Linux, Go leans on stricter OS limits. Based
- // on Linux's processor.h, the user address space is limited as
- // follows on 64-bit architectures:
- //
- // Architecture Name Maximum Value (exclusive)
- // ---------------------------------------------------------------------
- // amd64 TASK_SIZE_MAX 0x007ffffffff000 (47 bit addresses)
- // arm64 TASK_SIZE_64 0x01000000000000 (48 bit addresses)
- // ppc64{,le} TASK_SIZE_USER64 0x00400000000000 (46 bit addresses)
- // mips64{,le} TASK_SIZE64 0x00010000000000 (40 bit addresses)
- // s390x TASK_SIZE 1<<64 (64 bit addresses)
- //
- // These limits may increase over time, but are currently at
- // most 48 bits except on s390x. On all architectures, Linux
- // starts placing mmap'd regions at addresses that are
- // significantly below 48 bits, so even if it's possible to
- // exceed Go's 48 bit limit, it's extremely unlikely in
- // practice.
- //
- // On 32-bit platforms, we accept the full 32-bit address
- // space because doing so is cheap.
- // mips32 only has access to the low 2GB of virtual memory, so
- // we further limit it to 31 bits.
- //
- // On ios/arm64, although 64-bit pointers are presumably
- // available, pointers are truncated to 33 bits in iOS <14.
- // Furthermore, only the top 4 GiB of the address space are
- // actually available to the application. In iOS >=14, more
- // of the address space is available, and the OS can now
- // provide addresses outside of those 33 bits. Pick 40 bits
- // as a reasonable balance between address space usage by the
- // page allocator, and flexibility for what mmap'd regions
- // we'll accept for the heap. We can't just move to the full
- // 48 bits because this uses too much address space for older
- // iOS versions.
- // TODO(mknyszek): Once iOS <14 is deprecated, promote ios/arm64
- // to a 48-bit address space like every other arm64 platform.
- //
- // WebAssembly currently has a limit of 4GB linear memory.
- heapAddrBits = (_64bit*(1-goarch.IsWasm)*(1-goos.IsIos*goarch.IsArm64))*48 + (1-_64bit+goarch.IsWasm)*(32-(goarch.IsMips+goarch.IsMipsle)) + 40*goos.IsIos*goarch.IsArm64
-
- // maxAlloc is the maximum size of an allocation. On 64-bit,
- // it's theoretically possible to allocate 1<<heapAddrBits bytes. On
- // 32-bit, however, this is one less than 1<<32 because the
- // number of bytes in the address space doesn't actually fit
- // in a uintptr.
- maxAlloc = (1 << heapAddrBits) - (1-_64bit)*1
-
- // The number of bits in a heap address, the size of heap
- // arenas, and the L1 and L2 arena map sizes are related by
- //
- // (1 << addr bits) = arena size * L1 entries * L2 entries
- //
- // Currently, we balance these as follows:
- //
- // Platform Addr bits Arena size L1 entries L2 entries
- // -------------- --------- ---------- ---------- -----------
- // */64-bit 48 64MB 1 4M (32MB)
- // windows/64-bit 48 4MB 64 1M (8MB)
- // ios/arm64 33 4MB 1 2048 (8KB)
- // */32-bit 32 4MB 1 1024 (4KB)
- // */mips(le) 31 4MB 1 512 (2KB)
-
- // heapArenaBytes is the size of a heap arena. The heap
- // consists of mappings of size heapArenaBytes, aligned to
- // heapArenaBytes. The initial heap mapping is one arena.
- //
- // This is currently 64MB on 64-bit non-Windows and 4MB on
- // 32-bit and on Windows. We use smaller arenas on Windows
- // because all committed memory is charged to the process,
- // even if it's not touched. Hence, for processes with small
- // heaps, the mapped arena space needs to be commensurate.
- // This is particularly important with the race detector,
- // since it significantly amplifies the cost of committed
- // memory.
- heapArenaBytes = 1 << logHeapArenaBytes
-
- heapArenaWords = heapArenaBytes / goarch.PtrSize
-
- // logHeapArenaBytes is log_2 of heapArenaBytes. For clarity,
- // prefer using heapArenaBytes where possible (we need the
- // constant to compute some other constants).
- logHeapArenaBytes = (6+20)*(_64bit*(1-goos.IsWindows)*(1-goarch.IsWasm)*(1-goos.IsIos*goarch.IsArm64)) + (2+20)*(_64bit*goos.IsWindows) + (2+20)*(1-_64bit) + (2+20)*goarch.IsWasm + (2+20)*goos.IsIos*goarch.IsArm64
-
- // heapArenaBitmapWords is the size of each heap arena's bitmap in uintptrs.
- heapArenaBitmapWords = heapArenaWords / (8 * goarch.PtrSize)
-
- pagesPerArena = heapArenaBytes / pageSize
-
- // arenaL1Bits is the number of bits of the arena number
- // covered by the first level arena map.
- //
- // This number should be small, since the first level arena
- // map requires PtrSize*(1<<arenaL1Bits) of space in the
- // binary's BSS. It can be zero, in which case the first level
- // index is effectively unused. There is a performance benefit
- // to this, since the generated code can be more efficient,
- // but comes at the cost of having a large L2 mapping.
- //
- // We use the L1 map on 64-bit Windows because the arena size
- // is small, but the address space is still 48 bits, and
- // there's a high cost to having a large L2.
- arenaL1Bits = 6 * (_64bit * goos.IsWindows)
-
- // arenaL2Bits is the number of bits of the arena number
- // covered by the second level arena index.
- //
- // The size of each arena map allocation is proportional to
- // 1<<arenaL2Bits, so it's important that this not be too
- // large. 48 bits leads to 32MB arena index allocations, which
- // is about the practical threshold.
- arenaL2Bits = heapAddrBits - logHeapArenaBytes - arenaL1Bits
-
- // arenaL1Shift is the number of bits to shift an arena frame
- // number by to compute an index into the first level arena map.
- arenaL1Shift = arenaL2Bits
-
- // arenaBits is the total bits in a combined arena map index.
- // This is split between the index into the L1 arena map and
- // the L2 arena map.
- arenaBits = arenaL1Bits + arenaL2Bits
-
- // arenaBaseOffset is the pointer value that corresponds to
- // index 0 in the heap arena map.
- //
- // On amd64, the address space is 48 bits, sign extended to 64
- // bits. This offset lets us handle "negative" addresses (or
- // high addresses if viewed as unsigned).
- //
- // On aix/ppc64, this offset allows to keep the heapAddrBits to
- // 48. Otherwise, it would be 60 in order to handle mmap addresses
- // (in range 0x0a00000000000000 - 0x0afffffffffffff). But in this
- // case, the memory reserved in (s *pageAlloc).init for chunks
- // is causing important slowdowns.
- //
- // On other platforms, the user address space is contiguous
- // and starts at 0, so no offset is necessary.
- arenaBaseOffset = 0xffff800000000000*goarch.IsAmd64 + 0x0a00000000000000*goos.IsAix
- // A typed version of this constant that will make it into DWARF (for viewcore).
- arenaBaseOffsetUintptr = uintptr(arenaBaseOffset)
-
- // Max number of threads to run garbage collection.
- // 2, 3, and 4 are all plausible maximums depending
- // on the hardware details of the machine. The garbage
- // collector scales well to 32 cpus.
- _MaxGcproc = 32
-
- // minLegalPointer is the smallest possible legal pointer.
- // This is the smallest possible architectural page size,
- // since we assume that the first page is never mapped.
- //
- // This should agree with minZeroPage in the compiler.
- minLegalPointer uintptr = 4096
-)
-
-// physPageSize is the size in bytes of the OS's physical pages.
-// Mapping and unmapping operations must be done at multiples of
-// physPageSize.
-//
-// This must be set by the OS init code (typically in osinit) before
-// mallocinit.
-var physPageSize uintptr
-
-// physHugePageSize is the size in bytes of the OS's default physical huge
-// page size whose allocation is opaque to the application. It is assumed
-// and verified to be a power of two.
-//
-// If set, this must be set by the OS init code (typically in osinit) before
-// mallocinit. However, setting it at all is optional, and leaving the default
-// value is always safe (though potentially less efficient).
-//
-// Since physHugePageSize is always assumed to be a power of two,
-// physHugePageShift is defined as physHugePageSize == 1 << physHugePageShift.
-// The purpose of physHugePageShift is to avoid doing divisions in
-// performance critical functions.
-var (
- physHugePageSize uintptr
- physHugePageShift uint
-)
-
-func mallocinit() {
- if class_to_size[_TinySizeClass] != _TinySize {
- throw("bad TinySizeClass")
- }
-
- if heapArenaBitmapWords&(heapArenaBitmapWords-1) != 0 {
- // heapBits expects modular arithmetic on bitmap
- // addresses to work.
- throw("heapArenaBitmapWords not a power of 2")
- }
-
- // Check physPageSize.
- if physPageSize == 0 {
- // The OS init code failed to fetch the physical page size.
- throw("failed to get system page size")
- }
- if physPageSize > maxPhysPageSize {
- print("system page size (", physPageSize, ") is larger than maximum page size (", maxPhysPageSize, ")\n")
- throw("bad system page size")
- }
- if physPageSize < minPhysPageSize {
- print("system page size (", physPageSize, ") is smaller than minimum page size (", minPhysPageSize, ")\n")
- throw("bad system page size")
- }
- if physPageSize&(physPageSize-1) != 0 {
- print("system page size (", physPageSize, ") must be a power of 2\n")
- throw("bad system page size")
- }
- if physHugePageSize&(physHugePageSize-1) != 0 {
- print("system huge page size (", physHugePageSize, ") must be a power of 2\n")
- throw("bad system huge page size")
- }
- if physHugePageSize > maxPhysHugePageSize {
- // physHugePageSize is greater than the maximum supported huge page size.
- // Don't throw here, like in the other cases, since a system configured
- // in this way isn't wrong, we just don't have the code to support them.
- // Instead, silently set the huge page size to zero.
- physHugePageSize = 0
- }
- if physHugePageSize != 0 {
- // Since physHugePageSize is a power of 2, it suffices to increase
- // physHugePageShift until 1<<physHugePageShift == physHugePageSize.
- for 1<<physHugePageShift != physHugePageSize {
- physHugePageShift++
- }
- }
- if pagesPerArena%pagesPerSpanRoot != 0 {
- print("pagesPerArena (", pagesPerArena, ") is not divisible by pagesPerSpanRoot (", pagesPerSpanRoot, ")\n")
- throw("bad pagesPerSpanRoot")
- }
- if pagesPerArena%pagesPerReclaimerChunk != 0 {
- print("pagesPerArena (", pagesPerArena, ") is not divisible by pagesPerReclaimerChunk (", pagesPerReclaimerChunk, ")\n")
- throw("bad pagesPerReclaimerChunk")
- }
-
- // Initialize the heap.
- mheap_.init()
- mcache0 = allocmcache()
- lockInit(&gcBitsArenas.lock, lockRankGcBitsArenas)
- lockInit(&profInsertLock, lockRankProfInsert)
- lockInit(&profBlockLock, lockRankProfBlock)
- lockInit(&profMemActiveLock, lockRankProfMemActive)
- for i := range profMemFutureLock {
- lockInit(&profMemFutureLock[i], lockRankProfMemFuture)
- }
- lockInit(&globalAlloc.mutex, lockRankGlobalAlloc)
-
- // Create initial arena growth hints.
- if goarch.PtrSize == 8 {
- // On a 64-bit machine, we pick the following hints
- // because:
- //
- // 1. Starting from the middle of the address space
- // makes it easier to grow out a contiguous range
- // without running in to some other mapping.
- //
- // 2. This makes Go heap addresses more easily
- // recognizable when debugging.
- //
- // 3. Stack scanning in gccgo is still conservative,
- // so it's important that addresses be distinguishable
- // from other data.
- //
- // Starting at 0x00c0 means that the valid memory addresses
- // will begin 0x00c0, 0x00c1, ...
- // In little-endian, that's c0 00, c1 00, ... None of those are valid
- // UTF-8 sequences, and they are otherwise as far away from
- // ff (likely a common byte) as possible. If that fails, we try other 0xXXc0
- // addresses. An earlier attempt to use 0x11f8 caused out of memory errors
- // on OS X during thread allocations. 0x00c0 causes conflicts with
- // AddressSanitizer which reserves all memory up to 0x0100.
- // These choices reduce the odds of a conservative garbage collector
- // not collecting memory because some non-pointer block of memory
- // had a bit pattern that matched a memory address.
- //
- // However, on arm64, we ignore all this advice above and slam the
- // allocation at 0x40 << 32 because when using 4k pages with 3-level
- // translation buffers, the user address space is limited to 39 bits
- // On ios/arm64, the address space is even smaller.
- //
- // On AIX, mmaps starts at 0x0A00000000000000 for 64-bit.
- // processes.
- //
- // Space mapped for user arenas comes immediately after the range
- // originally reserved for the regular heap when race mode is not
- // enabled because user arena chunks can never be used for regular heap
- // allocations and we want to avoid fragmenting the address space.
- //
- // In race mode we have no choice but to just use the same hints because
- // the race detector requires that the heap be mapped contiguously.
- for i := 0x7f; i >= 0; i-- {
- var p uintptr
- switch {
- case raceenabled:
- // The TSAN runtime requires the heap
- // to be in the range [0x00c000000000,
- // 0x00e000000000).
- p = uintptr(i)<<32 | uintptrMask&(0x00c0<<32)
- if p >= uintptrMask&0x00e000000000 {
- continue
- }
- case GOARCH == "arm64" && GOOS == "ios":
- p = uintptr(i)<<40 | uintptrMask&(0x0013<<28)
- case GOARCH == "arm64":
- p = uintptr(i)<<40 | uintptrMask&(0x0040<<32)
- case GOOS == "aix":
- if i == 0 {
- // We don't use addresses directly after 0x0A00000000000000
- // to avoid collisions with others mmaps done by non-go programs.
- continue
- }
- p = uintptr(i)<<40 | uintptrMask&(0xa0<<52)
- default:
- p = uintptr(i)<<40 | uintptrMask&(0x00c0<<32)
- }
- // Switch to generating hints for user arenas if we've gone
- // through about half the hints. In race mode, take only about
- // a quarter; we don't have very much space to work with.
- hintList := &mheap_.arenaHints
- if (!raceenabled && i > 0x3f) || (raceenabled && i > 0x5f) {
- hintList = &mheap_.userArena.arenaHints
- }
- hint := (*arenaHint)(mheap_.arenaHintAlloc.alloc())
- hint.addr = p
- hint.next, *hintList = *hintList, hint
- }
- } else {
- // On a 32-bit machine, we're much more concerned
- // about keeping the usable heap contiguous.
- // Hence:
- //
- // 1. We reserve space for all heapArenas up front so
- // they don't get interleaved with the heap. They're
- // ~258MB, so this isn't too bad. (We could reserve a
- // smaller amount of space up front if this is a
- // problem.)
- //
- // 2. We hint the heap to start right above the end of
- // the binary so we have the best chance of keeping it
- // contiguous.
- //
- // 3. We try to stake out a reasonably large initial
- // heap reservation.
-
- const arenaMetaSize = (1 << arenaBits) * unsafe.Sizeof(heapArena{})
- meta := uintptr(sysReserve(nil, arenaMetaSize))
- if meta != 0 {
- mheap_.heapArenaAlloc.init(meta, arenaMetaSize, true)
- }
-
- // We want to start the arena low, but if we're linked
- // against C code, it's possible global constructors
- // have called malloc and adjusted the process' brk.
- // Query the brk so we can avoid trying to map the
- // region over it (which will cause the kernel to put
- // the region somewhere else, likely at a high
- // address).
- procBrk := sbrk0()
-
- // If we ask for the end of the data segment but the
- // operating system requires a little more space
- // before we can start allocating, it will give out a
- // slightly higher pointer. Except QEMU, which is
- // buggy, as usual: it won't adjust the pointer
- // upward. So adjust it upward a little bit ourselves:
- // 1/4 MB to get away from the running binary image.
- p := firstmoduledata.end
- if p < procBrk {
- p = procBrk
- }
- if mheap_.heapArenaAlloc.next <= p && p < mheap_.heapArenaAlloc.end {
- p = mheap_.heapArenaAlloc.end
- }
- p = alignUp(p+(256<<10), heapArenaBytes)
- // Because we're worried about fragmentation on
- // 32-bit, we try to make a large initial reservation.
- arenaSizes := []uintptr{
- 512 << 20,
- 256 << 20,
- 128 << 20,
- }
- for _, arenaSize := range arenaSizes {
- a, size := sysReserveAligned(unsafe.Pointer(p), arenaSize, heapArenaBytes)
- if a != nil {
- mheap_.arena.init(uintptr(a), size, false)
- p = mheap_.arena.end // For hint below
- break
- }
- }
- hint := (*arenaHint)(mheap_.arenaHintAlloc.alloc())
- hint.addr = p
- hint.next, mheap_.arenaHints = mheap_.arenaHints, hint
-
- // Place the hint for user arenas just after the large reservation.
- //
- // While this potentially competes with the hint above, in practice we probably
- // aren't going to be getting this far anyway on 32-bit platforms.
- userArenaHint := (*arenaHint)(mheap_.arenaHintAlloc.alloc())
- userArenaHint.addr = p
- userArenaHint.next, mheap_.userArena.arenaHints = mheap_.userArena.arenaHints, userArenaHint
- }
-}
-
-// sysAlloc allocates heap arena space for at least n bytes. The
-// returned pointer is always heapArenaBytes-aligned and backed by
-// h.arenas metadata. The returned size is always a multiple of
-// heapArenaBytes. sysAlloc returns nil on failure.
-// There is no corresponding free function.
-//
-// hintList is a list of hint addresses for where to allocate new
-// heap arenas. It must be non-nil.
-//
-// register indicates whether the heap arena should be registered
-// in allArenas.
-//
-// sysAlloc returns a memory region in the Reserved state. This region must
-// be transitioned to Prepared and then Ready before use.
-//
-// h must be locked.
-func (h *mheap) sysAlloc(n uintptr, hintList **arenaHint, register bool) (v unsafe.Pointer, size uintptr) {
- assertLockHeld(&h.lock)
-
- n = alignUp(n, heapArenaBytes)
-
- if hintList == &h.arenaHints {
- // First, try the arena pre-reservation.
- // Newly-used mappings are considered released.
- //
- // Only do this if we're using the regular heap arena hints.
- // This behavior is only for the heap.
- v = h.arena.alloc(n, heapArenaBytes, &gcController.heapReleased)
- if v != nil {
- size = n
- goto mapped
- }
- }
-
- // Try to grow the heap at a hint address.
- for *hintList != nil {
- hint := *hintList
- p := hint.addr
- if hint.down {
- p -= n
- }
- if p+n < p {
- // We can't use this, so don't ask.
- v = nil
- } else if arenaIndex(p+n-1) >= 1<<arenaBits {
- // Outside addressable heap. Can't use.
- v = nil
- } else {
- v = sysReserve(unsafe.Pointer(p), n)
- }
- if p == uintptr(v) {
- // Success. Update the hint.
- if !hint.down {
- p += n
- }
- hint.addr = p
- size = n
- break
- }
- // Failed. Discard this hint and try the next.
- //
- // TODO: This would be cleaner if sysReserve could be
- // told to only return the requested address. In
- // particular, this is already how Windows behaves, so
- // it would simplify things there.
- if v != nil {
- sysFreeOS(v, n)
- }
- *hintList = hint.next
- h.arenaHintAlloc.free(unsafe.Pointer(hint))
- }
-
- if size == 0 {
- if raceenabled {
- // The race detector assumes the heap lives in
- // [0x00c000000000, 0x00e000000000), but we
- // just ran out of hints in this region. Give
- // a nice failure.
- throw("too many address space collisions for -race mode")
- }
-
- // All of the hints failed, so we'll take any
- // (sufficiently aligned) address the kernel will give
- // us.
- v, size = sysReserveAligned(nil, n, heapArenaBytes)
- if v == nil {
- return nil, 0
- }
-
- // Create new hints for extending this region.
- hint := (*arenaHint)(h.arenaHintAlloc.alloc())
- hint.addr, hint.down = uintptr(v), true
- hint.next, mheap_.arenaHints = mheap_.arenaHints, hint
- hint = (*arenaHint)(h.arenaHintAlloc.alloc())
- hint.addr = uintptr(v) + size
- hint.next, mheap_.arenaHints = mheap_.arenaHints, hint
- }
-
- // Check for bad pointers or pointers we can't use.
- {
- var bad string
- p := uintptr(v)
- if p+size < p {
- bad = "region exceeds uintptr range"
- } else if arenaIndex(p) >= 1<<arenaBits {
- bad = "base outside usable address space"
- } else if arenaIndex(p+size-1) >= 1<<arenaBits {
- bad = "end outside usable address space"
- }
- if bad != "" {
- // This should be impossible on most architectures,
- // but it would be really confusing to debug.
- print("runtime: memory allocated by OS [", hex(p), ", ", hex(p+size), ") not in usable address space: ", bad, "\n")
- throw("memory reservation exceeds address space limit")
- }
- }
-
- if uintptr(v)&(heapArenaBytes-1) != 0 {
- throw("misrounded allocation in sysAlloc")
- }
-
-mapped:
- // Create arena metadata.
- for ri := arenaIndex(uintptr(v)); ri <= arenaIndex(uintptr(v)+size-1); ri++ {
- l2 := h.arenas[ri.l1()]
- if l2 == nil {
- // Allocate an L2 arena map.
- //
- // Use sysAllocOS instead of sysAlloc or persistentalloc because there's no
- // statistic we can comfortably account for this space in. With this structure,
- // we rely on demand paging to avoid large overheads, but tracking which memory
- // is paged in is too expensive. Trying to account for the whole region means
- // that it will appear like an enormous memory overhead in statistics, even though
- // it is not.
- l2 = (*[1 << arenaL2Bits]*heapArena)(sysAllocOS(unsafe.Sizeof(*l2)))
- if l2 == nil {
- throw("out of memory allocating heap arena map")
- }
- atomic.StorepNoWB(unsafe.Pointer(&h.arenas[ri.l1()]), unsafe.Pointer(l2))
- }
-
- if l2[ri.l2()] != nil {
- throw("arena already initialized")
- }
- var r *heapArena
- r = (*heapArena)(h.heapArenaAlloc.alloc(unsafe.Sizeof(*r), goarch.PtrSize, &memstats.gcMiscSys))
- if r == nil {
- r = (*heapArena)(persistentalloc(unsafe.Sizeof(*r), goarch.PtrSize, &memstats.gcMiscSys))
- if r == nil {
- throw("out of memory allocating heap arena metadata")
- }
- }
-
- // Register the arena in allArenas if requested.
- if register {
- if len(h.allArenas) == cap(h.allArenas) {
- size := 2 * uintptr(cap(h.allArenas)) * goarch.PtrSize
- if size == 0 {
- size = physPageSize
- }
- newArray := (*notInHeap)(persistentalloc(size, goarch.PtrSize, &memstats.gcMiscSys))
- if newArray == nil {
- throw("out of memory allocating allArenas")
- }
- oldSlice := h.allArenas
- *(*notInHeapSlice)(unsafe.Pointer(&h.allArenas)) = notInHeapSlice{newArray, len(h.allArenas), int(size / goarch.PtrSize)}
- copy(h.allArenas, oldSlice)
- // Do not free the old backing array because
- // there may be concurrent readers. Since we
- // double the array each time, this can lead
- // to at most 2x waste.
- }
- h.allArenas = h.allArenas[:len(h.allArenas)+1]
- h.allArenas[len(h.allArenas)-1] = ri
- }
-
- // Store atomically just in case an object from the
- // new heap arena becomes visible before the heap lock
- // is released (which shouldn't happen, but there's
- // little downside to this).
- atomic.StorepNoWB(unsafe.Pointer(&l2[ri.l2()]), unsafe.Pointer(r))
- }
-
- // Tell the race detector about the new heap memory.
- if raceenabled {
- racemapshadow(v, size)
- }
-
- return
-}
-
-// sysReserveAligned is like sysReserve, but the returned pointer is
-// aligned to align bytes. It may reserve either n or n+align bytes,
-// so it returns the size that was reserved.
-func sysReserveAligned(v unsafe.Pointer, size, align uintptr) (unsafe.Pointer, uintptr) {
- // Since the alignment is rather large in uses of this
- // function, we're not likely to get it by chance, so we ask
- // for a larger region and remove the parts we don't need.
- retries := 0
-retry:
- p := uintptr(sysReserve(v, size+align))
- switch {
- case p == 0:
- return nil, 0
- case p&(align-1) == 0:
- return unsafe.Pointer(p), size + align
- case GOOS == "windows":
- // On Windows we can't release pieces of a
- // reservation, so we release the whole thing and
- // re-reserve the aligned sub-region. This may race,
- // so we may have to try again.
- sysFreeOS(unsafe.Pointer(p), size+align)
- p = alignUp(p, align)
- p2 := sysReserve(unsafe.Pointer(p), size)
- if p != uintptr(p2) {
- // Must have raced. Try again.
- sysFreeOS(p2, size)
- if retries++; retries == 100 {
- throw("failed to allocate aligned heap memory; too many retries")
- }
- goto retry
- }
- // Success.
- return p2, size
- default:
- // Trim off the unaligned parts.
- pAligned := alignUp(p, align)
- sysFreeOS(unsafe.Pointer(p), pAligned-p)
- end := pAligned + size
- endLen := (p + size + align) - end
- if endLen > 0 {
- sysFreeOS(unsafe.Pointer(end), endLen)
- }
- return unsafe.Pointer(pAligned), size
- }
-}
-
-// base address for all 0-byte allocations
-var zerobase uintptr
-
-// nextFreeFast returns the next free object if one is quickly available.
-// Otherwise it returns 0.
-func nextFreeFast(s *mspan) gclinkptr {
- theBit := sys.TrailingZeros64(s.allocCache) // Is there a free object in the allocCache?
- if theBit < 64 {
- result := s.freeindex + uintptr(theBit)
- if result < s.nelems {
- freeidx := result + 1
- if freeidx%64 == 0 && freeidx != s.nelems {
- return 0
- }
- s.allocCache >>= uint(theBit + 1)
- s.freeindex = freeidx
- s.allocCount++
- return gclinkptr(result*s.elemsize + s.base())
- }
- }
- return 0
-}
-
-// nextFree returns the next free object from the cached span if one is available.
-// Otherwise it refills the cache with a span with an available object and
-// returns that object along with a flag indicating that this was a heavy
-// weight allocation. If it is a heavy weight allocation the caller must
-// determine whether a new GC cycle needs to be started or if the GC is active
-// whether this goroutine needs to assist the GC.
-//
-// Must run in a non-preemptible context since otherwise the owner of
-// c could change.
-func (c *mcache) nextFree(spc spanClass) (v gclinkptr, s *mspan, shouldhelpgc bool) {
- s = c.alloc[spc]
- shouldhelpgc = false
- freeIndex := s.nextFreeIndex()
- if freeIndex == s.nelems {
- // The span is full.
- if uintptr(s.allocCount) != s.nelems {
- println("runtime: s.allocCount=", s.allocCount, "s.nelems=", s.nelems)
- throw("s.allocCount != s.nelems && freeIndex == s.nelems")
- }
- c.refill(spc)
- shouldhelpgc = true
- s = c.alloc[spc]
-
- freeIndex = s.nextFreeIndex()
- }
-
- if freeIndex >= s.nelems {
- throw("freeIndex is not valid")
- }
-
- v = gclinkptr(freeIndex*s.elemsize + s.base())
- s.allocCount++
- if uintptr(s.allocCount) > s.nelems {
- println("s.allocCount=", s.allocCount, "s.nelems=", s.nelems)
- throw("s.allocCount > s.nelems")
- }
- return
-}
-
-// Allocate an object of size bytes.
-// Small objects are allocated from the per-P cache's free lists.
-// Large objects (> 32 kB) are allocated straight from the heap.
-func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
- if gcphase == _GCmarktermination {
- throw("mallocgc called with gcphase == _GCmarktermination")
- }
-
- if size == 0 {
- return unsafe.Pointer(&zerobase)
- }
-
- // It's possible for any malloc to trigger sweeping, which may in
- // turn queue finalizers. Record this dynamic lock edge.
- lockRankMayQueueFinalizer()
-
- userSize := size
- if asanenabled {
- // Refer to ASAN runtime library, the malloc() function allocates extra memory,
- // the redzone, around the user requested memory region. And the redzones are marked
- // as unaddressable. We perform the same operations in Go to detect the overflows or
- // underflows.
- size += computeRZlog(size)
- }
-
- if debug.malloc {
- if debug.sbrk != 0 {
- align := uintptr(16)
- if typ != nil {
- // TODO(austin): This should be just
- // align = uintptr(typ.align)
- // but that's only 4 on 32-bit platforms,
- // even if there's a uint64 field in typ (see #599).
- // This causes 64-bit atomic accesses to panic.
- // Hence, we use stricter alignment that matches
- // the normal allocator better.
- if size&7 == 0 {
- align = 8
- } else if size&3 == 0 {
- align = 4
- } else if size&1 == 0 {
- align = 2
- } else {
- align = 1
- }
- }
- return persistentalloc(size, align, &memstats.other_sys)
- }
-
- if inittrace.active && inittrace.id == getg().goid {
- // Init functions are executed sequentially in a single goroutine.
- inittrace.allocs += 1
- }
- }
-
- // assistG is the G to charge for this allocation, or nil if
- // GC is not currently active.
- assistG := deductAssistCredit(size)
-
- // Set mp.mallocing to keep from being preempted by GC.
- mp := acquirem()
- if mp.mallocing != 0 {
- throw("malloc deadlock")
- }
- if mp.gsignal == getg() {
- throw("malloc during signal")
- }
- mp.mallocing = 1
-
- shouldhelpgc := false
- dataSize := userSize
- c := getMCache(mp)
- if c == nil {
- throw("mallocgc called without a P or outside bootstrapping")
- }
- var span *mspan
- var x unsafe.Pointer
- noscan := typ == nil || typ.ptrdata == 0
- // In some cases block zeroing can profitably (for latency reduction purposes)
- // be delayed till preemption is possible; delayedZeroing tracks that state.
- delayedZeroing := false
- if size <= maxSmallSize {
- if noscan && size < maxTinySize {
- // Tiny allocator.
- //
- // Tiny allocator combines several tiny allocation requests
- // into a single memory block. The resulting memory block
- // is freed when all subobjects are unreachable. The subobjects
- // must be noscan (don't have pointers), this ensures that
- // the amount of potentially wasted memory is bounded.
- //
- // Size of the memory block used for combining (maxTinySize) is tunable.
- // Current setting is 16 bytes, which relates to 2x worst case memory
- // wastage (when all but one subobjects are unreachable).
- // 8 bytes would result in no wastage at all, but provides less
- // opportunities for combining.
- // 32 bytes provides more opportunities for combining,
- // but can lead to 4x worst case wastage.
- // The best case winning is 8x regardless of block size.
- //
- // Objects obtained from tiny allocator must not be freed explicitly.
- // So when an object will be freed explicitly, we ensure that
- // its size >= maxTinySize.
- //
- // SetFinalizer has a special case for objects potentially coming
- // from tiny allocator, it such case it allows to set finalizers
- // for an inner byte of a memory block.
- //
- // The main targets of tiny allocator are small strings and
- // standalone escaping variables. On a json benchmark
- // the allocator reduces number of allocations by ~12% and
- // reduces heap size by ~20%.
- off := c.tinyoffset
- // Align tiny pointer for required (conservative) alignment.
- if size&7 == 0 {
- off = alignUp(off, 8)
- } else if goarch.PtrSize == 4 && size == 12 {
- // Conservatively align 12-byte objects to 8 bytes on 32-bit
- // systems so that objects whose first field is a 64-bit
- // value is aligned to 8 bytes and does not cause a fault on
- // atomic access. See issue 37262.
- // TODO(mknyszek): Remove this workaround if/when issue 36606
- // is resolved.
- off = alignUp(off, 8)
- } else if size&3 == 0 {
- off = alignUp(off, 4)
- } else if size&1 == 0 {
- off = alignUp(off, 2)
- }
- if off+size <= maxTinySize && c.tiny != 0 {
- // The object fits into existing tiny block.
- x = unsafe.Pointer(c.tiny + off)
- c.tinyoffset = off + size
- c.tinyAllocs++
- mp.mallocing = 0
- releasem(mp)
- return x
- }
- // Allocate a new maxTinySize block.
- span = c.alloc[tinySpanClass]
- v := nextFreeFast(span)
- if v == 0 {
- v, span, shouldhelpgc = c.nextFree(tinySpanClass)
- }
- x = unsafe.Pointer(v)
- (*[2]uint64)(x)[0] = 0
- (*[2]uint64)(x)[1] = 0
- // See if we need to replace the existing tiny block with the new one
- // based on amount of remaining free space.
- if !raceenabled && (size < c.tinyoffset || c.tiny == 0) {
- // Note: disabled when race detector is on, see comment near end of this function.
- c.tiny = uintptr(x)
- c.tinyoffset = size
- }
- size = maxTinySize
- } else {
- var sizeclass uint8
- if size <= smallSizeMax-8 {
- sizeclass = size_to_class8[divRoundUp(size, smallSizeDiv)]
- } else {
- sizeclass = size_to_class128[divRoundUp(size-smallSizeMax, largeSizeDiv)]
- }
- size = uintptr(class_to_size[sizeclass])
- spc := makeSpanClass(sizeclass, noscan)
- span = c.alloc[spc]
- v := nextFreeFast(span)
- if v == 0 {
- v, span, shouldhelpgc = c.nextFree(spc)
- }
- x = unsafe.Pointer(v)
- if needzero && span.needzero != 0 {
- memclrNoHeapPointers(x, size)
- }
- }
- } else {
- shouldhelpgc = true
- // For large allocations, keep track of zeroed state so that
- // bulk zeroing can be happen later in a preemptible context.
- span = c.allocLarge(size, noscan)
- span.freeindex = 1
- span.allocCount = 1
- size = span.elemsize
- x = unsafe.Pointer(span.base())
- if needzero && span.needzero != 0 {
- if noscan {
- delayedZeroing = true
- } else {
- memclrNoHeapPointers(x, size)
- // We've in theory cleared almost the whole span here,
- // and could take the extra step of actually clearing
- // the whole thing. However, don't. Any GC bits for the
- // uncleared parts will be zero, and it's just going to
- // be needzero = 1 once freed anyway.
- }
- }
- }
-
- if !noscan {
- var scanSize uintptr
- heapBitsSetType(uintptr(x), size, dataSize, typ)
- if dataSize > typ.size {
- // Array allocation. If there are any
- // pointers, GC has to scan to the last
- // element.
- if typ.ptrdata != 0 {
- scanSize = dataSize - typ.size + typ.ptrdata
- }
- } else {
- scanSize = typ.ptrdata
- }
- c.scanAlloc += scanSize
- }
-
- // Ensure that the stores above that initialize x to
- // type-safe memory and set the heap bits occur before
- // the caller can make x observable to the garbage
- // collector. Otherwise, on weakly ordered machines,
- // the garbage collector could follow a pointer to x,
- // but see uninitialized memory or stale heap bits.
- publicationBarrier()
- // As x and the heap bits are initialized, update
- // freeIndexForScan now so x is seen by the GC
- // (including convervative scan) as an allocated object.
- // While this pointer can't escape into user code as a
- // _live_ pointer until we return, conservative scanning
- // may find a dead pointer that happens to point into this
- // object. Delaying this update until now ensures that
- // conservative scanning considers this pointer dead until
- // this point.
- span.freeIndexForScan = span.freeindex
-
- // Allocate black during GC.
- // All slots hold nil so no scanning is needed.
- // This may be racing with GC so do it atomically if there can be
- // a race marking the bit.
- if gcphase != _GCoff {
- gcmarknewobject(span, uintptr(x), size)
- }
-
- if raceenabled {
- racemalloc(x, size)
- }
-
- if msanenabled {
- msanmalloc(x, size)
- }
-
- if asanenabled {
- // We should only read/write the memory with the size asked by the user.
- // The rest of the allocated memory should be poisoned, so that we can report
- // errors when accessing poisoned memory.
- // The allocated memory is larger than required userSize, it will also include
- // redzone and some other padding bytes.
- rzBeg := unsafe.Add(x, userSize)
- asanpoison(rzBeg, size-userSize)
- asanunpoison(x, userSize)
- }
-
- if rate := MemProfileRate; rate > 0 {
- // Note cache c only valid while m acquired; see #47302
- if rate != 1 && size < c.nextSample {
- c.nextSample -= size
- } else {
- profilealloc(mp, x, size)
- }
- }
- mp.mallocing = 0
- releasem(mp)
-
- // Pointerfree data can be zeroed late in a context where preemption can occur.
- // x will keep the memory alive.
- if delayedZeroing {
- if !noscan {
- throw("delayed zeroing on data that may contain pointers")
- }
- memclrNoHeapPointersChunked(size, x) // This is a possible preemption point: see #47302
- }
-
- if debug.malloc {
- if debug.allocfreetrace != 0 {
- tracealloc(x, size, typ)
- }
-
- if inittrace.active && inittrace.id == getg().goid {
- // Init functions are executed sequentially in a single goroutine.
- inittrace.bytes += uint64(size)
- }
- }
-
- if assistG != nil {
- // Account for internal fragmentation in the assist
- // debt now that we know it.
- assistG.gcAssistBytes -= int64(size - dataSize)
- }
-
- if shouldhelpgc {
- if t := (gcTrigger{kind: gcTriggerHeap}); t.test() {
- gcStart(t)
- }
- }
-
- if raceenabled && noscan && dataSize < maxTinySize {
- // Pad tinysize allocations so they are aligned with the end
- // of the tinyalloc region. This ensures that any arithmetic
- // that goes off the top end of the object will be detectable
- // by checkptr (issue 38872).
- // Note that we disable tinyalloc when raceenabled for this to work.
- // TODO: This padding is only performed when the race detector
- // is enabled. It would be nice to enable it if any package
- // was compiled with checkptr, but there's no easy way to
- // detect that (especially at compile time).
- // TODO: enable this padding for all allocations, not just
- // tinyalloc ones. It's tricky because of pointer maps.
- // Maybe just all noscan objects?
- x = add(x, size-dataSize)
- }
-
- return x
-}
-
-// deductAssistCredit reduces the current G's assist credit
-// by size bytes, and assists the GC if necessary.
-//
-// Caller must be preemptible.
-//
-// Returns the G for which the assist credit was accounted.
-func deductAssistCredit(size uintptr) *g {
- var assistG *g
- if gcBlackenEnabled != 0 {
- // Charge the current user G for this allocation.
- assistG = getg()
- if assistG.m.curg != nil {
- assistG = assistG.m.curg
- }
- // Charge the allocation against the G. We'll account
- // for internal fragmentation at the end of mallocgc.
- assistG.gcAssistBytes -= int64(size)
-
- if assistG.gcAssistBytes < 0 {
- // This G is in debt. Assist the GC to correct
- // this before allocating. This must happen
- // before disabling preemption.
- gcAssistAlloc(assistG)
- }
- }
- return assistG
-}
-
-// memclrNoHeapPointersChunked repeatedly calls memclrNoHeapPointers
-// on chunks of the buffer to be zeroed, with opportunities for preemption
-// along the way. memclrNoHeapPointers contains no safepoints and also
-// cannot be preemptively scheduled, so this provides a still-efficient
-// block copy that can also be preempted on a reasonable granularity.
-//
-// Use this with care; if the data being cleared is tagged to contain
-// pointers, this allows the GC to run before it is all cleared.
-func memclrNoHeapPointersChunked(size uintptr, x unsafe.Pointer) {
- v := uintptr(x)
- // got this from benchmarking. 128k is too small, 512k is too large.
- const chunkBytes = 256 * 1024
- vsize := v + size
- for voff := v; voff < vsize; voff = voff + chunkBytes {
- if getg().preempt {
- // may hold locks, e.g., profiling
- goschedguarded()
- }
- // clear min(avail, lump) bytes
- n := vsize - voff
- if n > chunkBytes {
- n = chunkBytes
- }
- memclrNoHeapPointers(unsafe.Pointer(voff), n)
- }
-}
-
-// implementation of new builtin
-// compiler (both frontend and SSA backend) knows the signature
-// of this function.
-func newobject(typ *_type) unsafe.Pointer {
- return mallocgc(typ.size, typ, true)
-}
-
-//go:linkname reflect_unsafe_New reflect.unsafe_New
-func reflect_unsafe_New(typ *_type) unsafe.Pointer {
- return mallocgc(typ.size, typ, true)
-}
-
-//go:linkname reflectlite_unsafe_New internal/reflectlite.unsafe_New
-func reflectlite_unsafe_New(typ *_type) unsafe.Pointer {
- return mallocgc(typ.size, typ, true)
-}
-
-// newarray allocates an array of n elements of type typ.
-func newarray(typ *_type, n int) unsafe.Pointer {
- if n == 1 {
- return mallocgc(typ.size, typ, true)
- }
- mem, overflow := math.MulUintptr(typ.size, uintptr(n))
- if overflow || mem > maxAlloc || n < 0 {
- panic(plainError("runtime: allocation size out of range"))
- }
- return mallocgc(mem, typ, true)
-}
-
-//go:linkname reflect_unsafe_NewArray reflect.unsafe_NewArray
-func reflect_unsafe_NewArray(typ *_type, n int) unsafe.Pointer {
- return newarray(typ, n)
-}
-
-func profilealloc(mp *m, x unsafe.Pointer, size uintptr) {
- c := getMCache(mp)
- if c == nil {
- throw("profilealloc called without a P or outside bootstrapping")
- }
- c.nextSample = nextSample()
- mProf_Malloc(x, size)
-}
-
-// nextSample returns the next sampling point for heap profiling. The goal is
-// to sample allocations on average every MemProfileRate bytes, but with a
-// completely random distribution over the allocation timeline; this
-// corresponds to a Poisson process with parameter MemProfileRate. In Poisson
-// processes, the distance between two samples follows the exponential
-// distribution (exp(MemProfileRate)), so the best return value is a random
-// number taken from an exponential distribution whose mean is MemProfileRate.
-func nextSample() uintptr {
- if MemProfileRate == 1 {
- // Callers assign our return value to
- // mcache.next_sample, but next_sample is not used
- // when the rate is 1. So avoid the math below and
- // just return something.
- return 0
- }
- if GOOS == "plan9" {
- // Plan 9 doesn't support floating point in note handler.
- if gp := getg(); gp == gp.m.gsignal {
- return nextSampleNoFP()
- }
- }
-
- return uintptr(fastexprand(MemProfileRate))
-}
-
-// fastexprand returns a random number from an exponential distribution with
-// the specified mean.
-func fastexprand(mean int) int32 {
- // Avoid overflow. Maximum possible step is
- // -ln(1/(1<<randomBitCount)) * mean, approximately 20 * mean.
- switch {
- case mean > 0x7000000:
- mean = 0x7000000
- case mean == 0:
- return 0
- }
-
- // Take a random sample of the exponential distribution exp(-mean*x).
- // The probability distribution function is mean*exp(-mean*x), so the CDF is
- // p = 1 - exp(-mean*x), so
- // q = 1 - p == exp(-mean*x)
- // log_e(q) = -mean*x
- // -log_e(q)/mean = x
- // x = -log_e(q) * mean
- // x = log_2(q) * (-log_e(2)) * mean ; Using log_2 for efficiency
- const randomBitCount = 26
- q := fastrandn(1<<randomBitCount) + 1
- qlog := fastlog2(float64(q)) - randomBitCount
- if qlog > 0 {
- qlog = 0
- }
- const minusLog2 = -0.6931471805599453 // -ln(2)
- return int32(qlog*(minusLog2*float64(mean))) + 1
-}
-
-// nextSampleNoFP is similar to nextSample, but uses older,
-// simpler code to avoid floating point.
-func nextSampleNoFP() uintptr {
- // Set first allocation sample size.
- rate := MemProfileRate
- if rate > 0x3fffffff { // make 2*rate not overflow
- rate = 0x3fffffff
- }
- if rate != 0 {
- return uintptr(fastrandn(uint32(2 * rate)))
- }
- return 0
-}
-
-type persistentAlloc struct {
- base *notInHeap
- off uintptr
-}
-
-var globalAlloc struct {
- mutex
- persistentAlloc
-}
-
-// persistentChunkSize is the number of bytes we allocate when we grow
-// a persistentAlloc.
-const persistentChunkSize = 256 << 10
-
-// persistentChunks is a list of all the persistent chunks we have
-// allocated. The list is maintained through the first word in the
-// persistent chunk. This is updated atomically.
-var persistentChunks *notInHeap
-
-// Wrapper around sysAlloc that can allocate small chunks.
-// There is no associated free operation.
-// Intended for things like function/type/debug-related persistent data.
-// If align is 0, uses default align (currently 8).
-// The returned memory will be zeroed.
-// sysStat must be non-nil.
-//
-// Consider marking persistentalloc'd types not in heap by embedding
-// runtime/internal/sys.NotInHeap.
-func persistentalloc(size, align uintptr, sysStat *sysMemStat) unsafe.Pointer {
- var p *notInHeap
- systemstack(func() {
- p = persistentalloc1(size, align, sysStat)
- })
- return unsafe.Pointer(p)
-}
-
-// Must run on system stack because stack growth can (re)invoke it.
-// See issue 9174.
-//
-//go:systemstack
-func persistentalloc1(size, align uintptr, sysStat *sysMemStat) *notInHeap {
- const (
- maxBlock = 64 << 10 // VM reservation granularity is 64K on windows
- )
-
- if size == 0 {
- throw("persistentalloc: size == 0")
- }
- if align != 0 {
- if align&(align-1) != 0 {
- throw("persistentalloc: align is not a power of 2")
- }
- if align > _PageSize {
- throw("persistentalloc: align is too large")
- }
- } else {
- align = 8
- }
-
- if size >= maxBlock {
- return (*notInHeap)(sysAlloc(size, sysStat))
- }
-
- mp := acquirem()
- var persistent *persistentAlloc
- if mp != nil && mp.p != 0 {
- persistent = &mp.p.ptr().palloc
- } else {
- lock(&globalAlloc.mutex)
- persistent = &globalAlloc.persistentAlloc
- }
- persistent.off = alignUp(persistent.off, align)
- if persistent.off+size > persistentChunkSize || persistent.base == nil {
- persistent.base = (*notInHeap)(sysAlloc(persistentChunkSize, &memstats.other_sys))
- if persistent.base == nil {
- if persistent == &globalAlloc.persistentAlloc {
- unlock(&globalAlloc.mutex)
- }
- throw("runtime: cannot allocate memory")
- }
-
- // Add the new chunk to the persistentChunks list.
- for {
- chunks := uintptr(unsafe.Pointer(persistentChunks))
- *(*uintptr)(unsafe.Pointer(persistent.base)) = chunks
- if atomic.Casuintptr((*uintptr)(unsafe.Pointer(&persistentChunks)), chunks, uintptr(unsafe.Pointer(persistent.base))) {
- break
- }
- }
- persistent.off = alignUp(goarch.PtrSize, align)
- }
- p := persistent.base.add(persistent.off)
- persistent.off += size
- releasem(mp)
- if persistent == &globalAlloc.persistentAlloc {
- unlock(&globalAlloc.mutex)
- }
-
- if sysStat != &memstats.other_sys {
- sysStat.add(int64(size))
- memstats.other_sys.add(-int64(size))
- }
- return p
-}
-
-// inPersistentAlloc reports whether p points to memory allocated by
-// persistentalloc. This must be nosplit because it is called by the
-// cgo checker code, which is called by the write barrier code.
-//
-//go:nosplit
-func inPersistentAlloc(p uintptr) bool {
- chunk := atomic.Loaduintptr((*uintptr)(unsafe.Pointer(&persistentChunks)))
- for chunk != 0 {
- if p >= chunk && p < chunk+persistentChunkSize {
- return true
- }
- chunk = *(*uintptr)(unsafe.Pointer(chunk))
- }
- return false
-}
-
-// linearAlloc is a simple linear allocator that pre-reserves a region
-// of memory and then optionally maps that region into the Ready state
-// as needed.
-//
-// The caller is responsible for locking.
-type linearAlloc struct {
- next uintptr // next free byte
- mapped uintptr // one byte past end of mapped space
- end uintptr // end of reserved space
-
- mapMemory bool // transition memory from Reserved to Ready if true
-}
-
-func (l *linearAlloc) init(base, size uintptr, mapMemory bool) {
- if base+size < base {
- // Chop off the last byte. The runtime isn't prepared
- // to deal with situations where the bounds could overflow.
- // Leave that memory reserved, though, so we don't map it
- // later.
- size -= 1
- }
- l.next, l.mapped = base, base
- l.end = base + size
- l.mapMemory = mapMemory
-}
-
-func (l *linearAlloc) alloc(size, align uintptr, sysStat *sysMemStat) unsafe.Pointer {
- p := alignUp(l.next, align)
- if p+size > l.end {
- return nil
- }
- l.next = p + size
- if pEnd := alignUp(l.next-1, physPageSize); pEnd > l.mapped {
- if l.mapMemory {
- // Transition from Reserved to Prepared to Ready.
- n := pEnd - l.mapped
- sysMap(unsafe.Pointer(l.mapped), n, sysStat)
- sysUsed(unsafe.Pointer(l.mapped), n, n)
- }
- l.mapped = pEnd
- }
- return unsafe.Pointer(p)
-}
-
-// notInHeap is off-heap memory allocated by a lower-level allocator
-// like sysAlloc or persistentAlloc.
-//
-// In general, it's better to use real types which embed
-// runtime/internal/sys.NotInHeap, but this serves as a generic type
-// for situations where that isn't possible (like in the allocators).
-//
-// TODO: Use this as the return type of sysAlloc, persistentAlloc, etc?
-type notInHeap struct{ _ sys.NotInHeap }
-
-func (p *notInHeap) add(bytes uintptr) *notInHeap {
- return (*notInHeap)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + bytes))
-}
-
-// computeRZlog computes the size of the redzone.
-// Refer to the implementation of the compiler-rt.
-func computeRZlog(userSize uintptr) uintptr {
- switch {
- case userSize <= (64 - 16):
- return 16 << 0
- case userSize <= (128 - 32):
- return 16 << 1
- case userSize <= (512 - 64):
- return 16 << 2
- case userSize <= (4096 - 128):
- return 16 << 3
- case userSize <= (1<<14)-256:
- return 16 << 4
- case userSize <= (1<<15)-512:
- return 16 << 5
- case userSize <= (1<<16)-1024:
- return 16 << 6
- default:
- return 16 << 7
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/map.go b/contrib/go/_std_1.20/src/runtime/map.go
deleted file mode 100644
index f546ce8609..0000000000
--- a/contrib/go/_std_1.20/src/runtime/map.go
+++ /dev/null
@@ -1,1418 +0,0 @@
-// Copyright 2014 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 runtime
-
-// This file contains the implementation of Go's map type.
-//
-// A map is just a hash table. The data is arranged
-// into an array of buckets. Each bucket contains up to
-// 8 key/elem pairs. The low-order bits of the hash are
-// used to select a bucket. Each bucket contains a few
-// high-order bits of each hash to distinguish the entries
-// within a single bucket.
-//
-// If more than 8 keys hash to a bucket, we chain on
-// extra buckets.
-//
-// When the hashtable grows, we allocate a new array
-// of buckets twice as big. Buckets are incrementally
-// copied from the old bucket array to the new bucket array.
-//
-// Map iterators walk through the array of buckets and
-// return the keys in walk order (bucket #, then overflow
-// chain order, then bucket index). To maintain iteration
-// semantics, we never move keys within their bucket (if
-// we did, keys might be returned 0 or 2 times). When
-// growing the table, iterators remain iterating through the
-// old table and must check the new table if the bucket
-// they are iterating through has been moved ("evacuated")
-// to the new table.
-
-// Picking loadFactor: too large and we have lots of overflow
-// buckets, too small and we waste a lot of space. I wrote
-// a simple program to check some stats for different loads:
-// (64-bit, 8 byte keys and elems)
-// loadFactor %overflow bytes/entry hitprobe missprobe
-// 4.00 2.13 20.77 3.00 4.00
-// 4.50 4.05 17.30 3.25 4.50
-// 5.00 6.85 14.77 3.50 5.00
-// 5.50 10.55 12.94 3.75 5.50
-// 6.00 15.27 11.67 4.00 6.00
-// 6.50 20.90 10.79 4.25 6.50
-// 7.00 27.14 10.15 4.50 7.00
-// 7.50 34.03 9.73 4.75 7.50
-// 8.00 41.10 9.40 5.00 8.00
-//
-// %overflow = percentage of buckets which have an overflow bucket
-// bytes/entry = overhead bytes used per key/elem pair
-// hitprobe = # of entries to check when looking up a present key
-// missprobe = # of entries to check when looking up an absent key
-//
-// Keep in mind this data is for maximally loaded tables, i.e. just
-// before the table grows. Typical tables will be somewhat less loaded.
-
-import (
- "internal/abi"
- "internal/goarch"
- "runtime/internal/atomic"
- "runtime/internal/math"
- "unsafe"
-)
-
-const (
- // Maximum number of key/elem pairs a bucket can hold.
- bucketCntBits = 3
- bucketCnt = 1 << bucketCntBits
-
- // Maximum average load of a bucket that triggers growth is 6.5.
- // Represent as loadFactorNum/loadFactorDen, to allow integer math.
- loadFactorNum = 13
- loadFactorDen = 2
-
- // Maximum key or elem size to keep inline (instead of mallocing per element).
- // Must fit in a uint8.
- // Fast versions cannot handle big elems - the cutoff size for
- // fast versions in cmd/compile/internal/gc/walk.go must be at most this elem.
- maxKeySize = 128
- maxElemSize = 128
-
- // data offset should be the size of the bmap struct, but needs to be
- // aligned correctly. For amd64p32 this means 64-bit alignment
- // even though pointers are 32 bit.
- dataOffset = unsafe.Offsetof(struct {
- b bmap
- v int64
- }{}.v)
-
- // Possible tophash values. We reserve a few possibilities for special marks.
- // Each bucket (including its overflow buckets, if any) will have either all or none of its
- // entries in the evacuated* states (except during the evacuate() method, which only happens
- // during map writes and thus no one else can observe the map during that time).
- emptyRest = 0 // this cell is empty, and there are no more non-empty cells at higher indexes or overflows.
- emptyOne = 1 // this cell is empty
- evacuatedX = 2 // key/elem is valid. Entry has been evacuated to first half of larger table.
- evacuatedY = 3 // same as above, but evacuated to second half of larger table.
- evacuatedEmpty = 4 // cell is empty, bucket is evacuated.
- minTopHash = 5 // minimum tophash for a normal filled cell.
-
- // flags
- iterator = 1 // there may be an iterator using buckets
- oldIterator = 2 // there may be an iterator using oldbuckets
- hashWriting = 4 // a goroutine is writing to the map
- sameSizeGrow = 8 // the current map growth is to a new map of the same size
-
- // sentinel bucket ID for iterator checks
- noCheck = 1<<(8*goarch.PtrSize) - 1
-)
-
-// isEmpty reports whether the given tophash array entry represents an empty bucket entry.
-func isEmpty(x uint8) bool {
- return x <= emptyOne
-}
-
-// A header for a Go map.
-type hmap struct {
- // Note: the format of the hmap is also encoded in cmd/compile/internal/reflectdata/reflect.go.
- // Make sure this stays in sync with the compiler's definition.
- count int // # live cells == size of map. Must be first (used by len() builtin)
- flags uint8
- B uint8 // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
- noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
- hash0 uint32 // hash seed
-
- buckets unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
- oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
- nevacuate uintptr // progress counter for evacuation (buckets less than this have been evacuated)
-
- extra *mapextra // optional fields
-}
-
-// mapextra holds fields that are not present on all maps.
-type mapextra struct {
- // If both key and elem do not contain pointers and are inline, then we mark bucket
- // type as containing no pointers. This avoids scanning such maps.
- // However, bmap.overflow is a pointer. In order to keep overflow buckets
- // alive, we store pointers to all overflow buckets in hmap.extra.overflow and hmap.extra.oldoverflow.
- // overflow and oldoverflow are only used if key and elem do not contain pointers.
- // overflow contains overflow buckets for hmap.buckets.
- // oldoverflow contains overflow buckets for hmap.oldbuckets.
- // The indirection allows to store a pointer to the slice in hiter.
- overflow *[]*bmap
- oldoverflow *[]*bmap
-
- // nextOverflow holds a pointer to a free overflow bucket.
- nextOverflow *bmap
-}
-
-// A bucket for a Go map.
-type bmap struct {
- // tophash generally contains the top byte of the hash value
- // for each key in this bucket. If tophash[0] < minTopHash,
- // tophash[0] is a bucket evacuation state instead.
- tophash [bucketCnt]uint8
- // Followed by bucketCnt keys and then bucketCnt elems.
- // NOTE: packing all the keys together and then all the elems together makes the
- // code a bit more complicated than alternating key/elem/key/elem/... but it allows
- // us to eliminate padding which would be needed for, e.g., map[int64]int8.
- // Followed by an overflow pointer.
-}
-
-// A hash iteration structure.
-// If you modify hiter, also change cmd/compile/internal/reflectdata/reflect.go
-// and reflect/value.go to match the layout of this structure.
-type hiter struct {
- key unsafe.Pointer // Must be in first position. Write nil to indicate iteration end (see cmd/compile/internal/walk/range.go).
- elem unsafe.Pointer // Must be in second position (see cmd/compile/internal/walk/range.go).
- t *maptype
- h *hmap
- buckets unsafe.Pointer // bucket ptr at hash_iter initialization time
- bptr *bmap // current bucket
- overflow *[]*bmap // keeps overflow buckets of hmap.buckets alive
- oldoverflow *[]*bmap // keeps overflow buckets of hmap.oldbuckets alive
- startBucket uintptr // bucket iteration started at
- offset uint8 // intra-bucket offset to start from during iteration (should be big enough to hold bucketCnt-1)
- wrapped bool // already wrapped around from end of bucket array to beginning
- B uint8
- i uint8
- bucket uintptr
- checkBucket uintptr
-}
-
-// bucketShift returns 1<<b, optimized for code generation.
-func bucketShift(b uint8) uintptr {
- // Masking the shift amount allows overflow checks to be elided.
- return uintptr(1) << (b & (goarch.PtrSize*8 - 1))
-}
-
-// bucketMask returns 1<<b - 1, optimized for code generation.
-func bucketMask(b uint8) uintptr {
- return bucketShift(b) - 1
-}
-
-// tophash calculates the tophash value for hash.
-func tophash(hash uintptr) uint8 {
- top := uint8(hash >> (goarch.PtrSize*8 - 8))
- if top < minTopHash {
- top += minTopHash
- }
- return top
-}
-
-func evacuated(b *bmap) bool {
- h := b.tophash[0]
- return h > emptyOne && h < minTopHash
-}
-
-func (b *bmap) overflow(t *maptype) *bmap {
- return *(**bmap)(add(unsafe.Pointer(b), uintptr(t.bucketsize)-goarch.PtrSize))
-}
-
-func (b *bmap) setoverflow(t *maptype, ovf *bmap) {
- *(**bmap)(add(unsafe.Pointer(b), uintptr(t.bucketsize)-goarch.PtrSize)) = ovf
-}
-
-func (b *bmap) keys() unsafe.Pointer {
- return add(unsafe.Pointer(b), dataOffset)
-}
-
-// incrnoverflow increments h.noverflow.
-// noverflow counts the number of overflow buckets.
-// This is used to trigger same-size map growth.
-// See also tooManyOverflowBuckets.
-// To keep hmap small, noverflow is a uint16.
-// When there are few buckets, noverflow is an exact count.
-// When there are many buckets, noverflow is an approximate count.
-func (h *hmap) incrnoverflow() {
- // We trigger same-size map growth if there are
- // as many overflow buckets as buckets.
- // We need to be able to count to 1<<h.B.
- if h.B < 16 {
- h.noverflow++
- return
- }
- // Increment with probability 1/(1<<(h.B-15)).
- // When we reach 1<<15 - 1, we will have approximately
- // as many overflow buckets as buckets.
- mask := uint32(1)<<(h.B-15) - 1
- // Example: if h.B == 18, then mask == 7,
- // and fastrand & 7 == 0 with probability 1/8.
- if fastrand()&mask == 0 {
- h.noverflow++
- }
-}
-
-func (h *hmap) newoverflow(t *maptype, b *bmap) *bmap {
- var ovf *bmap
- if h.extra != nil && h.extra.nextOverflow != nil {
- // We have preallocated overflow buckets available.
- // See makeBucketArray for more details.
- ovf = h.extra.nextOverflow
- if ovf.overflow(t) == nil {
- // We're not at the end of the preallocated overflow buckets. Bump the pointer.
- h.extra.nextOverflow = (*bmap)(add(unsafe.Pointer(ovf), uintptr(t.bucketsize)))
- } else {
- // This is the last preallocated overflow bucket.
- // Reset the overflow pointer on this bucket,
- // which was set to a non-nil sentinel value.
- ovf.setoverflow(t, nil)
- h.extra.nextOverflow = nil
- }
- } else {
- ovf = (*bmap)(newobject(t.bucket))
- }
- h.incrnoverflow()
- if t.bucket.ptrdata == 0 {
- h.createOverflow()
- *h.extra.overflow = append(*h.extra.overflow, ovf)
- }
- b.setoverflow(t, ovf)
- return ovf
-}
-
-func (h *hmap) createOverflow() {
- if h.extra == nil {
- h.extra = new(mapextra)
- }
- if h.extra.overflow == nil {
- h.extra.overflow = new([]*bmap)
- }
-}
-
-func makemap64(t *maptype, hint int64, h *hmap) *hmap {
- if int64(int(hint)) != hint {
- hint = 0
- }
- return makemap(t, int(hint), h)
-}
-
-// makemap_small implements Go map creation for make(map[k]v) and
-// make(map[k]v, hint) when hint is known to be at most bucketCnt
-// at compile time and the map needs to be allocated on the heap.
-func makemap_small() *hmap {
- h := new(hmap)
- h.hash0 = fastrand()
- return h
-}
-
-// makemap implements Go map creation for make(map[k]v, hint).
-// If the compiler has determined that the map or the first bucket
-// can be created on the stack, h and/or bucket may be non-nil.
-// If h != nil, the map can be created directly in h.
-// If h.buckets != nil, bucket pointed to can be used as the first bucket.
-func makemap(t *maptype, hint int, h *hmap) *hmap {
- mem, overflow := math.MulUintptr(uintptr(hint), t.bucket.size)
- if overflow || mem > maxAlloc {
- hint = 0
- }
-
- // initialize Hmap
- if h == nil {
- h = new(hmap)
- }
- h.hash0 = fastrand()
-
- // Find the size parameter B which will hold the requested # of elements.
- // For hint < 0 overLoadFactor returns false since hint < bucketCnt.
- B := uint8(0)
- for overLoadFactor(hint, B) {
- B++
- }
- h.B = B
-
- // allocate initial hash table
- // if B == 0, the buckets field is allocated lazily later (in mapassign)
- // If hint is large zeroing this memory could take a while.
- if h.B != 0 {
- var nextOverflow *bmap
- h.buckets, nextOverflow = makeBucketArray(t, h.B, nil)
- if nextOverflow != nil {
- h.extra = new(mapextra)
- h.extra.nextOverflow = nextOverflow
- }
- }
-
- return h
-}
-
-// makeBucketArray initializes a backing array for map buckets.
-// 1<<b is the minimum number of buckets to allocate.
-// dirtyalloc should either be nil or a bucket array previously
-// allocated by makeBucketArray with the same t and b parameters.
-// If dirtyalloc is nil a new backing array will be alloced and
-// otherwise dirtyalloc will be cleared and reused as backing array.
-func makeBucketArray(t *maptype, b uint8, dirtyalloc unsafe.Pointer) (buckets unsafe.Pointer, nextOverflow *bmap) {
- base := bucketShift(b)
- nbuckets := base
- // For small b, overflow buckets are unlikely.
- // Avoid the overhead of the calculation.
- if b >= 4 {
- // Add on the estimated number of overflow buckets
- // required to insert the median number of elements
- // used with this value of b.
- nbuckets += bucketShift(b - 4)
- sz := t.bucket.size * nbuckets
- up := roundupsize(sz)
- if up != sz {
- nbuckets = up / t.bucket.size
- }
- }
-
- if dirtyalloc == nil {
- buckets = newarray(t.bucket, int(nbuckets))
- } else {
- // dirtyalloc was previously generated by
- // the above newarray(t.bucket, int(nbuckets))
- // but may not be empty.
- buckets = dirtyalloc
- size := t.bucket.size * nbuckets
- if t.bucket.ptrdata != 0 {
- memclrHasPointers(buckets, size)
- } else {
- memclrNoHeapPointers(buckets, size)
- }
- }
-
- if base != nbuckets {
- // We preallocated some overflow buckets.
- // To keep the overhead of tracking these overflow buckets to a minimum,
- // we use the convention that if a preallocated overflow bucket's overflow
- // pointer is nil, then there are more available by bumping the pointer.
- // We need a safe non-nil pointer for the last overflow bucket; just use buckets.
- nextOverflow = (*bmap)(add(buckets, base*uintptr(t.bucketsize)))
- last := (*bmap)(add(buckets, (nbuckets-1)*uintptr(t.bucketsize)))
- last.setoverflow(t, (*bmap)(buckets))
- }
- return buckets, nextOverflow
-}
-
-// mapaccess1 returns a pointer to h[key]. Never returns nil, instead
-// it will return a reference to the zero object for the elem type if
-// the key is not in the map.
-// NOTE: The returned pointer may keep the whole map live, so don't
-// hold onto it for very long.
-func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- pc := abi.FuncPCABIInternal(mapaccess1)
- racereadpc(unsafe.Pointer(h), callerpc, pc)
- raceReadObjectPC(t.key, key, callerpc, pc)
- }
- if msanenabled && h != nil {
- msanread(key, t.key.size)
- }
- if asanenabled && h != nil {
- asanread(key, t.key.size)
- }
- if h == nil || h.count == 0 {
- if t.hashMightPanic() {
- t.hasher(key, 0) // see issue 23734
- }
- return unsafe.Pointer(&zeroVal[0])
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map read and map write")
- }
- hash := t.hasher(key, uintptr(h.hash0))
- m := bucketMask(h.B)
- b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
- if c := h.oldbuckets; c != nil {
- if !h.sameSizeGrow() {
- // There used to be half as many buckets; mask down one more power of two.
- m >>= 1
- }
- oldb := (*bmap)(add(c, (hash&m)*uintptr(t.bucketsize)))
- if !evacuated(oldb) {
- b = oldb
- }
- }
- top := tophash(hash)
-bucketloop:
- for ; b != nil; b = b.overflow(t) {
- for i := uintptr(0); i < bucketCnt; i++ {
- if b.tophash[i] != top {
- if b.tophash[i] == emptyRest {
- break bucketloop
- }
- continue
- }
- k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
- if t.indirectkey() {
- k = *((*unsafe.Pointer)(k))
- }
- if t.key.equal(key, k) {
- e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.elemsize))
- if t.indirectelem() {
- e = *((*unsafe.Pointer)(e))
- }
- return e
- }
- }
- }
- return unsafe.Pointer(&zeroVal[0])
-}
-
-func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- pc := abi.FuncPCABIInternal(mapaccess2)
- racereadpc(unsafe.Pointer(h), callerpc, pc)
- raceReadObjectPC(t.key, key, callerpc, pc)
- }
- if msanenabled && h != nil {
- msanread(key, t.key.size)
- }
- if asanenabled && h != nil {
- asanread(key, t.key.size)
- }
- if h == nil || h.count == 0 {
- if t.hashMightPanic() {
- t.hasher(key, 0) // see issue 23734
- }
- return unsafe.Pointer(&zeroVal[0]), false
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map read and map write")
- }
- hash := t.hasher(key, uintptr(h.hash0))
- m := bucketMask(h.B)
- b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
- if c := h.oldbuckets; c != nil {
- if !h.sameSizeGrow() {
- // There used to be half as many buckets; mask down one more power of two.
- m >>= 1
- }
- oldb := (*bmap)(add(c, (hash&m)*uintptr(t.bucketsize)))
- if !evacuated(oldb) {
- b = oldb
- }
- }
- top := tophash(hash)
-bucketloop:
- for ; b != nil; b = b.overflow(t) {
- for i := uintptr(0); i < bucketCnt; i++ {
- if b.tophash[i] != top {
- if b.tophash[i] == emptyRest {
- break bucketloop
- }
- continue
- }
- k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
- if t.indirectkey() {
- k = *((*unsafe.Pointer)(k))
- }
- if t.key.equal(key, k) {
- e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.elemsize))
- if t.indirectelem() {
- e = *((*unsafe.Pointer)(e))
- }
- return e, true
- }
- }
- }
- return unsafe.Pointer(&zeroVal[0]), false
-}
-
-// returns both key and elem. Used by map iterator.
-func mapaccessK(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, unsafe.Pointer) {
- if h == nil || h.count == 0 {
- return nil, nil
- }
- hash := t.hasher(key, uintptr(h.hash0))
- m := bucketMask(h.B)
- b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
- if c := h.oldbuckets; c != nil {
- if !h.sameSizeGrow() {
- // There used to be half as many buckets; mask down one more power of two.
- m >>= 1
- }
- oldb := (*bmap)(add(c, (hash&m)*uintptr(t.bucketsize)))
- if !evacuated(oldb) {
- b = oldb
- }
- }
- top := tophash(hash)
-bucketloop:
- for ; b != nil; b = b.overflow(t) {
- for i := uintptr(0); i < bucketCnt; i++ {
- if b.tophash[i] != top {
- if b.tophash[i] == emptyRest {
- break bucketloop
- }
- continue
- }
- k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
- if t.indirectkey() {
- k = *((*unsafe.Pointer)(k))
- }
- if t.key.equal(key, k) {
- e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.elemsize))
- if t.indirectelem() {
- e = *((*unsafe.Pointer)(e))
- }
- return k, e
- }
- }
- }
- return nil, nil
-}
-
-func mapaccess1_fat(t *maptype, h *hmap, key, zero unsafe.Pointer) unsafe.Pointer {
- e := mapaccess1(t, h, key)
- if e == unsafe.Pointer(&zeroVal[0]) {
- return zero
- }
- return e
-}
-
-func mapaccess2_fat(t *maptype, h *hmap, key, zero unsafe.Pointer) (unsafe.Pointer, bool) {
- e := mapaccess1(t, h, key)
- if e == unsafe.Pointer(&zeroVal[0]) {
- return zero, false
- }
- return e, true
-}
-
-// Like mapaccess, but allocates a slot for the key if it is not present in the map.
-func mapassign(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
- if h == nil {
- panic(plainError("assignment to entry in nil map"))
- }
- if raceenabled {
- callerpc := getcallerpc()
- pc := abi.FuncPCABIInternal(mapassign)
- racewritepc(unsafe.Pointer(h), callerpc, pc)
- raceReadObjectPC(t.key, key, callerpc, pc)
- }
- if msanenabled {
- msanread(key, t.key.size)
- }
- if asanenabled {
- asanread(key, t.key.size)
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map writes")
- }
- hash := t.hasher(key, uintptr(h.hash0))
-
- // Set hashWriting after calling t.hasher, since t.hasher may panic,
- // in which case we have not actually done a write.
- h.flags ^= hashWriting
-
- if h.buckets == nil {
- h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
- }
-
-again:
- bucket := hash & bucketMask(h.B)
- if h.growing() {
- growWork(t, h, bucket)
- }
- b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
- top := tophash(hash)
-
- var inserti *uint8
- var insertk unsafe.Pointer
- var elem unsafe.Pointer
-bucketloop:
- for {
- for i := uintptr(0); i < bucketCnt; i++ {
- if b.tophash[i] != top {
- if isEmpty(b.tophash[i]) && inserti == nil {
- inserti = &b.tophash[i]
- insertk = add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
- elem = add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.elemsize))
- }
- if b.tophash[i] == emptyRest {
- break bucketloop
- }
- continue
- }
- k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
- if t.indirectkey() {
- k = *((*unsafe.Pointer)(k))
- }
- if !t.key.equal(key, k) {
- continue
- }
- // already have a mapping for key. Update it.
- if t.needkeyupdate() {
- typedmemmove(t.key, k, key)
- }
- elem = add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.elemsize))
- goto done
- }
- ovf := b.overflow(t)
- if ovf == nil {
- break
- }
- b = ovf
- }
-
- // Did not find mapping for key. Allocate new cell & add entry.
-
- // If we hit the max load factor or we have too many overflow buckets,
- // and we're not already in the middle of growing, start growing.
- if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
- hashGrow(t, h)
- goto again // Growing the table invalidates everything, so try again
- }
-
- if inserti == nil {
- // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
- newb := h.newoverflow(t, b)
- inserti = &newb.tophash[0]
- insertk = add(unsafe.Pointer(newb), dataOffset)
- elem = add(insertk, bucketCnt*uintptr(t.keysize))
- }
-
- // store new key/elem at insert position
- if t.indirectkey() {
- kmem := newobject(t.key)
- *(*unsafe.Pointer)(insertk) = kmem
- insertk = kmem
- }
- if t.indirectelem() {
- vmem := newobject(t.elem)
- *(*unsafe.Pointer)(elem) = vmem
- }
- typedmemmove(t.key, insertk, key)
- *inserti = top
- h.count++
-
-done:
- if h.flags&hashWriting == 0 {
- fatal("concurrent map writes")
- }
- h.flags &^= hashWriting
- if t.indirectelem() {
- elem = *((*unsafe.Pointer)(elem))
- }
- return elem
-}
-
-func mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- pc := abi.FuncPCABIInternal(mapdelete)
- racewritepc(unsafe.Pointer(h), callerpc, pc)
- raceReadObjectPC(t.key, key, callerpc, pc)
- }
- if msanenabled && h != nil {
- msanread(key, t.key.size)
- }
- if asanenabled && h != nil {
- asanread(key, t.key.size)
- }
- if h == nil || h.count == 0 {
- if t.hashMightPanic() {
- t.hasher(key, 0) // see issue 23734
- }
- return
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map writes")
- }
-
- hash := t.hasher(key, uintptr(h.hash0))
-
- // Set hashWriting after calling t.hasher, since t.hasher may panic,
- // in which case we have not actually done a write (delete).
- h.flags ^= hashWriting
-
- bucket := hash & bucketMask(h.B)
- if h.growing() {
- growWork(t, h, bucket)
- }
- b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
- bOrig := b
- top := tophash(hash)
-search:
- for ; b != nil; b = b.overflow(t) {
- for i := uintptr(0); i < bucketCnt; i++ {
- if b.tophash[i] != top {
- if b.tophash[i] == emptyRest {
- break search
- }
- continue
- }
- k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
- k2 := k
- if t.indirectkey() {
- k2 = *((*unsafe.Pointer)(k2))
- }
- if !t.key.equal(key, k2) {
- continue
- }
- // Only clear key if there are pointers in it.
- if t.indirectkey() {
- *(*unsafe.Pointer)(k) = nil
- } else if t.key.ptrdata != 0 {
- memclrHasPointers(k, t.key.size)
- }
- e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.elemsize))
- if t.indirectelem() {
- *(*unsafe.Pointer)(e) = nil
- } else if t.elem.ptrdata != 0 {
- memclrHasPointers(e, t.elem.size)
- } else {
- memclrNoHeapPointers(e, t.elem.size)
- }
- b.tophash[i] = emptyOne
- // If the bucket now ends in a bunch of emptyOne states,
- // change those to emptyRest states.
- // It would be nice to make this a separate function, but
- // for loops are not currently inlineable.
- if i == bucketCnt-1 {
- if b.overflow(t) != nil && b.overflow(t).tophash[0] != emptyRest {
- goto notLast
- }
- } else {
- if b.tophash[i+1] != emptyRest {
- goto notLast
- }
- }
- for {
- b.tophash[i] = emptyRest
- if i == 0 {
- if b == bOrig {
- break // beginning of initial bucket, we're done.
- }
- // Find previous bucket, continue at its last entry.
- c := b
- for b = bOrig; b.overflow(t) != c; b = b.overflow(t) {
- }
- i = bucketCnt - 1
- } else {
- i--
- }
- if b.tophash[i] != emptyOne {
- break
- }
- }
- notLast:
- h.count--
- // Reset the hash seed to make it more difficult for attackers to
- // repeatedly trigger hash collisions. See issue 25237.
- if h.count == 0 {
- h.hash0 = fastrand()
- }
- break search
- }
- }
-
- if h.flags&hashWriting == 0 {
- fatal("concurrent map writes")
- }
- h.flags &^= hashWriting
-}
-
-// mapiterinit initializes the hiter struct used for ranging over maps.
-// The hiter struct pointed to by 'it' is allocated on the stack
-// by the compilers order pass or on the heap by reflect_mapiterinit.
-// Both need to have zeroed hiter since the struct contains pointers.
-func mapiterinit(t *maptype, h *hmap, it *hiter) {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapiterinit))
- }
-
- it.t = t
- if h == nil || h.count == 0 {
- return
- }
-
- if unsafe.Sizeof(hiter{})/goarch.PtrSize != 12 {
- throw("hash_iter size incorrect") // see cmd/compile/internal/reflectdata/reflect.go
- }
- it.h = h
-
- // grab snapshot of bucket state
- it.B = h.B
- it.buckets = h.buckets
- if t.bucket.ptrdata == 0 {
- // Allocate the current slice and remember pointers to both current and old.
- // This preserves all relevant overflow buckets alive even if
- // the table grows and/or overflow buckets are added to the table
- // while we are iterating.
- h.createOverflow()
- it.overflow = h.extra.overflow
- it.oldoverflow = h.extra.oldoverflow
- }
-
- // decide where to start
- var r uintptr
- if h.B > 31-bucketCntBits {
- r = uintptr(fastrand64())
- } else {
- r = uintptr(fastrand())
- }
- it.startBucket = r & bucketMask(h.B)
- it.offset = uint8(r >> h.B & (bucketCnt - 1))
-
- // iterator state
- it.bucket = it.startBucket
-
- // Remember we have an iterator.
- // Can run concurrently with another mapiterinit().
- if old := h.flags; old&(iterator|oldIterator) != iterator|oldIterator {
- atomic.Or8(&h.flags, iterator|oldIterator)
- }
-
- mapiternext(it)
-}
-
-func mapiternext(it *hiter) {
- h := it.h
- if raceenabled {
- callerpc := getcallerpc()
- racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapiternext))
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map iteration and map write")
- }
- t := it.t
- bucket := it.bucket
- b := it.bptr
- i := it.i
- checkBucket := it.checkBucket
-
-next:
- if b == nil {
- if bucket == it.startBucket && it.wrapped {
- // end of iteration
- it.key = nil
- it.elem = nil
- return
- }
- if h.growing() && it.B == h.B {
- // Iterator was started in the middle of a grow, and the grow isn't done yet.
- // If the bucket we're looking at hasn't been filled in yet (i.e. the old
- // bucket hasn't been evacuated) then we need to iterate through the old
- // bucket and only return the ones that will be migrated to this bucket.
- oldbucket := bucket & it.h.oldbucketmask()
- b = (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
- if !evacuated(b) {
- checkBucket = bucket
- } else {
- b = (*bmap)(add(it.buckets, bucket*uintptr(t.bucketsize)))
- checkBucket = noCheck
- }
- } else {
- b = (*bmap)(add(it.buckets, bucket*uintptr(t.bucketsize)))
- checkBucket = noCheck
- }
- bucket++
- if bucket == bucketShift(it.B) {
- bucket = 0
- it.wrapped = true
- }
- i = 0
- }
- for ; i < bucketCnt; i++ {
- offi := (i + it.offset) & (bucketCnt - 1)
- if isEmpty(b.tophash[offi]) || b.tophash[offi] == evacuatedEmpty {
- // TODO: emptyRest is hard to use here, as we start iterating
- // in the middle of a bucket. It's feasible, just tricky.
- continue
- }
- k := add(unsafe.Pointer(b), dataOffset+uintptr(offi)*uintptr(t.keysize))
- if t.indirectkey() {
- k = *((*unsafe.Pointer)(k))
- }
- e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+uintptr(offi)*uintptr(t.elemsize))
- if checkBucket != noCheck && !h.sameSizeGrow() {
- // Special case: iterator was started during a grow to a larger size
- // and the grow is not done yet. We're working on a bucket whose
- // oldbucket has not been evacuated yet. Or at least, it wasn't
- // evacuated when we started the bucket. So we're iterating
- // through the oldbucket, skipping any keys that will go
- // to the other new bucket (each oldbucket expands to two
- // buckets during a grow).
- if t.reflexivekey() || t.key.equal(k, k) {
- // If the item in the oldbucket is not destined for
- // the current new bucket in the iteration, skip it.
- hash := t.hasher(k, uintptr(h.hash0))
- if hash&bucketMask(it.B) != checkBucket {
- continue
- }
- } else {
- // Hash isn't repeatable if k != k (NaNs). We need a
- // repeatable and randomish choice of which direction
- // to send NaNs during evacuation. We'll use the low
- // bit of tophash to decide which way NaNs go.
- // NOTE: this case is why we need two evacuate tophash
- // values, evacuatedX and evacuatedY, that differ in
- // their low bit.
- if checkBucket>>(it.B-1) != uintptr(b.tophash[offi]&1) {
- continue
- }
- }
- }
- if (b.tophash[offi] != evacuatedX && b.tophash[offi] != evacuatedY) ||
- !(t.reflexivekey() || t.key.equal(k, k)) {
- // This is the golden data, we can return it.
- // OR
- // key!=key, so the entry can't be deleted or updated, so we can just return it.
- // That's lucky for us because when key!=key we can't look it up successfully.
- it.key = k
- if t.indirectelem() {
- e = *((*unsafe.Pointer)(e))
- }
- it.elem = e
- } else {
- // The hash table has grown since the iterator was started.
- // The golden data for this key is now somewhere else.
- // Check the current hash table for the data.
- // This code handles the case where the key
- // has been deleted, updated, or deleted and reinserted.
- // NOTE: we need to regrab the key as it has potentially been
- // updated to an equal() but not identical key (e.g. +0.0 vs -0.0).
- rk, re := mapaccessK(t, h, k)
- if rk == nil {
- continue // key has been deleted
- }
- it.key = rk
- it.elem = re
- }
- it.bucket = bucket
- if it.bptr != b { // avoid unnecessary write barrier; see issue 14921
- it.bptr = b
- }
- it.i = i + 1
- it.checkBucket = checkBucket
- return
- }
- b = b.overflow(t)
- i = 0
- goto next
-}
-
-// mapclear deletes all keys from a map.
-func mapclear(t *maptype, h *hmap) {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- pc := abi.FuncPCABIInternal(mapclear)
- racewritepc(unsafe.Pointer(h), callerpc, pc)
- }
-
- if h == nil || h.count == 0 {
- return
- }
-
- if h.flags&hashWriting != 0 {
- fatal("concurrent map writes")
- }
-
- h.flags ^= hashWriting
-
- h.flags &^= sameSizeGrow
- h.oldbuckets = nil
- h.nevacuate = 0
- h.noverflow = 0
- h.count = 0
-
- // Reset the hash seed to make it more difficult for attackers to
- // repeatedly trigger hash collisions. See issue 25237.
- h.hash0 = fastrand()
-
- // Keep the mapextra allocation but clear any extra information.
- if h.extra != nil {
- *h.extra = mapextra{}
- }
-
- // makeBucketArray clears the memory pointed to by h.buckets
- // and recovers any overflow buckets by generating them
- // as if h.buckets was newly alloced.
- _, nextOverflow := makeBucketArray(t, h.B, h.buckets)
- if nextOverflow != nil {
- // If overflow buckets are created then h.extra
- // will have been allocated during initial bucket creation.
- h.extra.nextOverflow = nextOverflow
- }
-
- if h.flags&hashWriting == 0 {
- fatal("concurrent map writes")
- }
- h.flags &^= hashWriting
-}
-
-func hashGrow(t *maptype, h *hmap) {
- // If we've hit the load factor, get bigger.
- // Otherwise, there are too many overflow buckets,
- // so keep the same number of buckets and "grow" laterally.
- bigger := uint8(1)
- if !overLoadFactor(h.count+1, h.B) {
- bigger = 0
- h.flags |= sameSizeGrow
- }
- oldbuckets := h.buckets
- newbuckets, nextOverflow := makeBucketArray(t, h.B+bigger, nil)
-
- flags := h.flags &^ (iterator | oldIterator)
- if h.flags&iterator != 0 {
- flags |= oldIterator
- }
- // commit the grow (atomic wrt gc)
- h.B += bigger
- h.flags = flags
- h.oldbuckets = oldbuckets
- h.buckets = newbuckets
- h.nevacuate = 0
- h.noverflow = 0
-
- if h.extra != nil && h.extra.overflow != nil {
- // Promote current overflow buckets to the old generation.
- if h.extra.oldoverflow != nil {
- throw("oldoverflow is not nil")
- }
- h.extra.oldoverflow = h.extra.overflow
- h.extra.overflow = nil
- }
- if nextOverflow != nil {
- if h.extra == nil {
- h.extra = new(mapextra)
- }
- h.extra.nextOverflow = nextOverflow
- }
-
- // the actual copying of the hash table data is done incrementally
- // by growWork() and evacuate().
-}
-
-// overLoadFactor reports whether count items placed in 1<<B buckets is over loadFactor.
-func overLoadFactor(count int, B uint8) bool {
- return count > bucketCnt && uintptr(count) > loadFactorNum*(bucketShift(B)/loadFactorDen)
-}
-
-// tooManyOverflowBuckets reports whether noverflow buckets is too many for a map with 1<<B buckets.
-// Note that most of these overflow buckets must be in sparse use;
-// if use was dense, then we'd have already triggered regular map growth.
-func tooManyOverflowBuckets(noverflow uint16, B uint8) bool {
- // If the threshold is too low, we do extraneous work.
- // If the threshold is too high, maps that grow and shrink can hold on to lots of unused memory.
- // "too many" means (approximately) as many overflow buckets as regular buckets.
- // See incrnoverflow for more details.
- if B > 15 {
- B = 15
- }
- // The compiler doesn't see here that B < 16; mask B to generate shorter shift code.
- return noverflow >= uint16(1)<<(B&15)
-}
-
-// growing reports whether h is growing. The growth may be to the same size or bigger.
-func (h *hmap) growing() bool {
- return h.oldbuckets != nil
-}
-
-// sameSizeGrow reports whether the current growth is to a map of the same size.
-func (h *hmap) sameSizeGrow() bool {
- return h.flags&sameSizeGrow != 0
-}
-
-// noldbuckets calculates the number of buckets prior to the current map growth.
-func (h *hmap) noldbuckets() uintptr {
- oldB := h.B
- if !h.sameSizeGrow() {
- oldB--
- }
- return bucketShift(oldB)
-}
-
-// oldbucketmask provides a mask that can be applied to calculate n % noldbuckets().
-func (h *hmap) oldbucketmask() uintptr {
- return h.noldbuckets() - 1
-}
-
-func growWork(t *maptype, h *hmap, bucket uintptr) {
- // make sure we evacuate the oldbucket corresponding
- // to the bucket we're about to use
- evacuate(t, h, bucket&h.oldbucketmask())
-
- // evacuate one more oldbucket to make progress on growing
- if h.growing() {
- evacuate(t, h, h.nevacuate)
- }
-}
-
-func bucketEvacuated(t *maptype, h *hmap, bucket uintptr) bool {
- b := (*bmap)(add(h.oldbuckets, bucket*uintptr(t.bucketsize)))
- return evacuated(b)
-}
-
-// evacDst is an evacuation destination.
-type evacDst struct {
- b *bmap // current destination bucket
- i int // key/elem index into b
- k unsafe.Pointer // pointer to current key storage
- e unsafe.Pointer // pointer to current elem storage
-}
-
-func evacuate(t *maptype, h *hmap, oldbucket uintptr) {
- b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
- newbit := h.noldbuckets()
- if !evacuated(b) {
- // TODO: reuse overflow buckets instead of using new ones, if there
- // is no iterator using the old buckets. (If !oldIterator.)
-
- // xy contains the x and y (low and high) evacuation destinations.
- var xy [2]evacDst
- x := &xy[0]
- x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.bucketsize)))
- x.k = add(unsafe.Pointer(x.b), dataOffset)
- x.e = add(x.k, bucketCnt*uintptr(t.keysize))
-
- if !h.sameSizeGrow() {
- // Only calculate y pointers if we're growing bigger.
- // Otherwise GC can see bad pointers.
- y := &xy[1]
- y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.bucketsize)))
- y.k = add(unsafe.Pointer(y.b), dataOffset)
- y.e = add(y.k, bucketCnt*uintptr(t.keysize))
- }
-
- for ; b != nil; b = b.overflow(t) {
- k := add(unsafe.Pointer(b), dataOffset)
- e := add(k, bucketCnt*uintptr(t.keysize))
- for i := 0; i < bucketCnt; i, k, e = i+1, add(k, uintptr(t.keysize)), add(e, uintptr(t.elemsize)) {
- top := b.tophash[i]
- if isEmpty(top) {
- b.tophash[i] = evacuatedEmpty
- continue
- }
- if top < minTopHash {
- throw("bad map state")
- }
- k2 := k
- if t.indirectkey() {
- k2 = *((*unsafe.Pointer)(k2))
- }
- var useY uint8
- if !h.sameSizeGrow() {
- // Compute hash to make our evacuation decision (whether we need
- // to send this key/elem to bucket x or bucket y).
- hash := t.hasher(k2, uintptr(h.hash0))
- if h.flags&iterator != 0 && !t.reflexivekey() && !t.key.equal(k2, k2) {
- // If key != key (NaNs), then the hash could be (and probably
- // will be) entirely different from the old hash. Moreover,
- // it isn't reproducible. Reproducibility is required in the
- // presence of iterators, as our evacuation decision must
- // match whatever decision the iterator made.
- // Fortunately, we have the freedom to send these keys either
- // way. Also, tophash is meaningless for these kinds of keys.
- // We let the low bit of tophash drive the evacuation decision.
- // We recompute a new random tophash for the next level so
- // these keys will get evenly distributed across all buckets
- // after multiple grows.
- useY = top & 1
- top = tophash(hash)
- } else {
- if hash&newbit != 0 {
- useY = 1
- }
- }
- }
-
- if evacuatedX+1 != evacuatedY || evacuatedX^1 != evacuatedY {
- throw("bad evacuatedN")
- }
-
- b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY
- dst := &xy[useY] // evacuation destination
-
- if dst.i == bucketCnt {
- dst.b = h.newoverflow(t, dst.b)
- dst.i = 0
- dst.k = add(unsafe.Pointer(dst.b), dataOffset)
- dst.e = add(dst.k, bucketCnt*uintptr(t.keysize))
- }
- dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
- if t.indirectkey() {
- *(*unsafe.Pointer)(dst.k) = k2 // copy pointer
- } else {
- typedmemmove(t.key, dst.k, k) // copy elem
- }
- if t.indirectelem() {
- *(*unsafe.Pointer)(dst.e) = *(*unsafe.Pointer)(e)
- } else {
- typedmemmove(t.elem, dst.e, e)
- }
- dst.i++
- // These updates might push these pointers past the end of the
- // key or elem arrays. That's ok, as we have the overflow pointer
- // at the end of the bucket to protect against pointing past the
- // end of the bucket.
- dst.k = add(dst.k, uintptr(t.keysize))
- dst.e = add(dst.e, uintptr(t.elemsize))
- }
- }
- // Unlink the overflow buckets & clear key/elem to help GC.
- if h.flags&oldIterator == 0 && t.bucket.ptrdata != 0 {
- b := add(h.oldbuckets, oldbucket*uintptr(t.bucketsize))
- // Preserve b.tophash because the evacuation
- // state is maintained there.
- ptr := add(b, dataOffset)
- n := uintptr(t.bucketsize) - dataOffset
- memclrHasPointers(ptr, n)
- }
- }
-
- if oldbucket == h.nevacuate {
- advanceEvacuationMark(h, t, newbit)
- }
-}
-
-func advanceEvacuationMark(h *hmap, t *maptype, newbit uintptr) {
- h.nevacuate++
- // Experiments suggest that 1024 is overkill by at least an order of magnitude.
- // Put it in there as a safeguard anyway, to ensure O(1) behavior.
- stop := h.nevacuate + 1024
- if stop > newbit {
- stop = newbit
- }
- for h.nevacuate != stop && bucketEvacuated(t, h, h.nevacuate) {
- h.nevacuate++
- }
- if h.nevacuate == newbit { // newbit == # of oldbuckets
- // Growing is all done. Free old main bucket array.
- h.oldbuckets = nil
- // Can discard old overflow buckets as well.
- // If they are still referenced by an iterator,
- // then the iterator holds a pointers to the slice.
- if h.extra != nil {
- h.extra.oldoverflow = nil
- }
- h.flags &^= sameSizeGrow
- }
-}
-
-// Reflect stubs. Called from ../reflect/asm_*.s
-
-//go:linkname reflect_makemap reflect.makemap
-func reflect_makemap(t *maptype, cap int) *hmap {
- // Check invariants and reflects math.
- if t.key.equal == nil {
- throw("runtime.reflect_makemap: unsupported map key type")
- }
- if t.key.size > maxKeySize && (!t.indirectkey() || t.keysize != uint8(goarch.PtrSize)) ||
- t.key.size <= maxKeySize && (t.indirectkey() || t.keysize != uint8(t.key.size)) {
- throw("key size wrong")
- }
- if t.elem.size > maxElemSize && (!t.indirectelem() || t.elemsize != uint8(goarch.PtrSize)) ||
- t.elem.size <= maxElemSize && (t.indirectelem() || t.elemsize != uint8(t.elem.size)) {
- throw("elem size wrong")
- }
- if t.key.align > bucketCnt {
- throw("key align too big")
- }
- if t.elem.align > bucketCnt {
- throw("elem align too big")
- }
- if t.key.size%uintptr(t.key.align) != 0 {
- throw("key size not a multiple of key align")
- }
- if t.elem.size%uintptr(t.elem.align) != 0 {
- throw("elem size not a multiple of elem align")
- }
- if bucketCnt < 8 {
- throw("bucketsize too small for proper alignment")
- }
- if dataOffset%uintptr(t.key.align) != 0 {
- throw("need padding in bucket (key)")
- }
- if dataOffset%uintptr(t.elem.align) != 0 {
- throw("need padding in bucket (elem)")
- }
-
- return makemap(t, cap, nil)
-}
-
-//go:linkname reflect_mapaccess reflect.mapaccess
-func reflect_mapaccess(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
- elem, ok := mapaccess2(t, h, key)
- if !ok {
- // reflect wants nil for a missing element
- elem = nil
- }
- return elem
-}
-
-//go:linkname reflect_mapaccess_faststr reflect.mapaccess_faststr
-func reflect_mapaccess_faststr(t *maptype, h *hmap, key string) unsafe.Pointer {
- elem, ok := mapaccess2_faststr(t, h, key)
- if !ok {
- // reflect wants nil for a missing element
- elem = nil
- }
- return elem
-}
-
-//go:linkname reflect_mapassign reflect.mapassign
-func reflect_mapassign(t *maptype, h *hmap, key unsafe.Pointer, elem unsafe.Pointer) {
- p := mapassign(t, h, key)
- typedmemmove(t.elem, p, elem)
-}
-
-//go:linkname reflect_mapassign_faststr reflect.mapassign_faststr
-func reflect_mapassign_faststr(t *maptype, h *hmap, key string, elem unsafe.Pointer) {
- p := mapassign_faststr(t, h, key)
- typedmemmove(t.elem, p, elem)
-}
-
-//go:linkname reflect_mapdelete reflect.mapdelete
-func reflect_mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
- mapdelete(t, h, key)
-}
-
-//go:linkname reflect_mapdelete_faststr reflect.mapdelete_faststr
-func reflect_mapdelete_faststr(t *maptype, h *hmap, key string) {
- mapdelete_faststr(t, h, key)
-}
-
-//go:linkname reflect_mapiterinit reflect.mapiterinit
-func reflect_mapiterinit(t *maptype, h *hmap, it *hiter) {
- mapiterinit(t, h, it)
-}
-
-//go:linkname reflect_mapiternext reflect.mapiternext
-func reflect_mapiternext(it *hiter) {
- mapiternext(it)
-}
-
-//go:linkname reflect_mapiterkey reflect.mapiterkey
-func reflect_mapiterkey(it *hiter) unsafe.Pointer {
- return it.key
-}
-
-//go:linkname reflect_mapiterelem reflect.mapiterelem
-func reflect_mapiterelem(it *hiter) unsafe.Pointer {
- return it.elem
-}
-
-//go:linkname reflect_maplen reflect.maplen
-func reflect_maplen(h *hmap) int {
- if h == nil {
- return 0
- }
- if raceenabled {
- callerpc := getcallerpc()
- racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(reflect_maplen))
- }
- return h.count
-}
-
-//go:linkname reflectlite_maplen internal/reflectlite.maplen
-func reflectlite_maplen(h *hmap) int {
- if h == nil {
- return 0
- }
- if raceenabled {
- callerpc := getcallerpc()
- racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(reflect_maplen))
- }
- return h.count
-}
-
-const maxZero = 1024 // must match value in reflect/value.go:maxZero cmd/compile/internal/gc/walk.go:zeroValSize
-var zeroVal [maxZero]byte
diff --git a/contrib/go/_std_1.20/src/runtime/map_fast32.go b/contrib/go/_std_1.20/src/runtime/map_fast32.go
deleted file mode 100644
index 01ea330950..0000000000
--- a/contrib/go/_std_1.20/src/runtime/map_fast32.go
+++ /dev/null
@@ -1,462 +0,0 @@
-// Copyright 2018 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 runtime
-
-import (
- "internal/abi"
- "internal/goarch"
- "unsafe"
-)
-
-func mapaccess1_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess1_fast32))
- }
- if h == nil || h.count == 0 {
- return unsafe.Pointer(&zeroVal[0])
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map read and map write")
- }
- var b *bmap
- if h.B == 0 {
- // One-bucket table. No need to hash.
- b = (*bmap)(h.buckets)
- } else {
- hash := t.hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
- m := bucketMask(h.B)
- b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
- if c := h.oldbuckets; c != nil {
- if !h.sameSizeGrow() {
- // There used to be half as many buckets; mask down one more power of two.
- m >>= 1
- }
- oldb := (*bmap)(add(c, (hash&m)*uintptr(t.bucketsize)))
- if !evacuated(oldb) {
- b = oldb
- }
- }
- }
- for ; b != nil; b = b.overflow(t) {
- for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 4) {
- if *(*uint32)(k) == key && !isEmpty(b.tophash[i]) {
- return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.elemsize))
- }
- }
- }
- return unsafe.Pointer(&zeroVal[0])
-}
-
-func mapaccess2_fast32(t *maptype, h *hmap, key uint32) (unsafe.Pointer, bool) {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess2_fast32))
- }
- if h == nil || h.count == 0 {
- return unsafe.Pointer(&zeroVal[0]), false
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map read and map write")
- }
- var b *bmap
- if h.B == 0 {
- // One-bucket table. No need to hash.
- b = (*bmap)(h.buckets)
- } else {
- hash := t.hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
- m := bucketMask(h.B)
- b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
- if c := h.oldbuckets; c != nil {
- if !h.sameSizeGrow() {
- // There used to be half as many buckets; mask down one more power of two.
- m >>= 1
- }
- oldb := (*bmap)(add(c, (hash&m)*uintptr(t.bucketsize)))
- if !evacuated(oldb) {
- b = oldb
- }
- }
- }
- for ; b != nil; b = b.overflow(t) {
- for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 4) {
- if *(*uint32)(k) == key && !isEmpty(b.tophash[i]) {
- return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.elemsize)), true
- }
- }
- }
- return unsafe.Pointer(&zeroVal[0]), false
-}
-
-func mapassign_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer {
- if h == nil {
- panic(plainError("assignment to entry in nil map"))
- }
- if raceenabled {
- callerpc := getcallerpc()
- racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapassign_fast32))
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map writes")
- }
- hash := t.hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
-
- // Set hashWriting after calling t.hasher for consistency with mapassign.
- h.flags ^= hashWriting
-
- if h.buckets == nil {
- h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
- }
-
-again:
- bucket := hash & bucketMask(h.B)
- if h.growing() {
- growWork_fast32(t, h, bucket)
- }
- b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
-
- var insertb *bmap
- var inserti uintptr
- var insertk unsafe.Pointer
-
-bucketloop:
- for {
- for i := uintptr(0); i < bucketCnt; i++ {
- if isEmpty(b.tophash[i]) {
- if insertb == nil {
- inserti = i
- insertb = b
- }
- if b.tophash[i] == emptyRest {
- break bucketloop
- }
- continue
- }
- k := *((*uint32)(add(unsafe.Pointer(b), dataOffset+i*4)))
- if k != key {
- continue
- }
- inserti = i
- insertb = b
- goto done
- }
- ovf := b.overflow(t)
- if ovf == nil {
- break
- }
- b = ovf
- }
-
- // Did not find mapping for key. Allocate new cell & add entry.
-
- // If we hit the max load factor or we have too many overflow buckets,
- // and we're not already in the middle of growing, start growing.
- if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
- hashGrow(t, h)
- goto again // Growing the table invalidates everything, so try again
- }
-
- if insertb == nil {
- // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
- insertb = h.newoverflow(t, b)
- inserti = 0 // not necessary, but avoids needlessly spilling inserti
- }
- insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks
-
- insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*4)
- // store new key at insert position
- *(*uint32)(insertk) = key
-
- h.count++
-
-done:
- elem := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*4+inserti*uintptr(t.elemsize))
- if h.flags&hashWriting == 0 {
- fatal("concurrent map writes")
- }
- h.flags &^= hashWriting
- return elem
-}
-
-func mapassign_fast32ptr(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
- if h == nil {
- panic(plainError("assignment to entry in nil map"))
- }
- if raceenabled {
- callerpc := getcallerpc()
- racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapassign_fast32))
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map writes")
- }
- hash := t.hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
-
- // Set hashWriting after calling t.hasher for consistency with mapassign.
- h.flags ^= hashWriting
-
- if h.buckets == nil {
- h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
- }
-
-again:
- bucket := hash & bucketMask(h.B)
- if h.growing() {
- growWork_fast32(t, h, bucket)
- }
- b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
-
- var insertb *bmap
- var inserti uintptr
- var insertk unsafe.Pointer
-
-bucketloop:
- for {
- for i := uintptr(0); i < bucketCnt; i++ {
- if isEmpty(b.tophash[i]) {
- if insertb == nil {
- inserti = i
- insertb = b
- }
- if b.tophash[i] == emptyRest {
- break bucketloop
- }
- continue
- }
- k := *((*unsafe.Pointer)(add(unsafe.Pointer(b), dataOffset+i*4)))
- if k != key {
- continue
- }
- inserti = i
- insertb = b
- goto done
- }
- ovf := b.overflow(t)
- if ovf == nil {
- break
- }
- b = ovf
- }
-
- // Did not find mapping for key. Allocate new cell & add entry.
-
- // If we hit the max load factor or we have too many overflow buckets,
- // and we're not already in the middle of growing, start growing.
- if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
- hashGrow(t, h)
- goto again // Growing the table invalidates everything, so try again
- }
-
- if insertb == nil {
- // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
- insertb = h.newoverflow(t, b)
- inserti = 0 // not necessary, but avoids needlessly spilling inserti
- }
- insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks
-
- insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*4)
- // store new key at insert position
- *(*unsafe.Pointer)(insertk) = key
-
- h.count++
-
-done:
- elem := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*4+inserti*uintptr(t.elemsize))
- if h.flags&hashWriting == 0 {
- fatal("concurrent map writes")
- }
- h.flags &^= hashWriting
- return elem
-}
-
-func mapdelete_fast32(t *maptype, h *hmap, key uint32) {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapdelete_fast32))
- }
- if h == nil || h.count == 0 {
- return
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map writes")
- }
-
- hash := t.hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
-
- // Set hashWriting after calling t.hasher for consistency with mapdelete
- h.flags ^= hashWriting
-
- bucket := hash & bucketMask(h.B)
- if h.growing() {
- growWork_fast32(t, h, bucket)
- }
- b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
- bOrig := b
-search:
- for ; b != nil; b = b.overflow(t) {
- for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 4) {
- if key != *(*uint32)(k) || isEmpty(b.tophash[i]) {
- continue
- }
- // Only clear key if there are pointers in it.
- // This can only happen if pointers are 32 bit
- // wide as 64 bit pointers do not fit into a 32 bit key.
- if goarch.PtrSize == 4 && t.key.ptrdata != 0 {
- // The key must be a pointer as we checked pointers are
- // 32 bits wide and the key is 32 bits wide also.
- *(*unsafe.Pointer)(k) = nil
- }
- e := add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.elemsize))
- if t.elem.ptrdata != 0 {
- memclrHasPointers(e, t.elem.size)
- } else {
- memclrNoHeapPointers(e, t.elem.size)
- }
- b.tophash[i] = emptyOne
- // If the bucket now ends in a bunch of emptyOne states,
- // change those to emptyRest states.
- if i == bucketCnt-1 {
- if b.overflow(t) != nil && b.overflow(t).tophash[0] != emptyRest {
- goto notLast
- }
- } else {
- if b.tophash[i+1] != emptyRest {
- goto notLast
- }
- }
- for {
- b.tophash[i] = emptyRest
- if i == 0 {
- if b == bOrig {
- break // beginning of initial bucket, we're done.
- }
- // Find previous bucket, continue at its last entry.
- c := b
- for b = bOrig; b.overflow(t) != c; b = b.overflow(t) {
- }
- i = bucketCnt - 1
- } else {
- i--
- }
- if b.tophash[i] != emptyOne {
- break
- }
- }
- notLast:
- h.count--
- // Reset the hash seed to make it more difficult for attackers to
- // repeatedly trigger hash collisions. See issue 25237.
- if h.count == 0 {
- h.hash0 = fastrand()
- }
- break search
- }
- }
-
- if h.flags&hashWriting == 0 {
- fatal("concurrent map writes")
- }
- h.flags &^= hashWriting
-}
-
-func growWork_fast32(t *maptype, h *hmap, bucket uintptr) {
- // make sure we evacuate the oldbucket corresponding
- // to the bucket we're about to use
- evacuate_fast32(t, h, bucket&h.oldbucketmask())
-
- // evacuate one more oldbucket to make progress on growing
- if h.growing() {
- evacuate_fast32(t, h, h.nevacuate)
- }
-}
-
-func evacuate_fast32(t *maptype, h *hmap, oldbucket uintptr) {
- b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
- newbit := h.noldbuckets()
- if !evacuated(b) {
- // TODO: reuse overflow buckets instead of using new ones, if there
- // is no iterator using the old buckets. (If !oldIterator.)
-
- // xy contains the x and y (low and high) evacuation destinations.
- var xy [2]evacDst
- x := &xy[0]
- x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.bucketsize)))
- x.k = add(unsafe.Pointer(x.b), dataOffset)
- x.e = add(x.k, bucketCnt*4)
-
- if !h.sameSizeGrow() {
- // Only calculate y pointers if we're growing bigger.
- // Otherwise GC can see bad pointers.
- y := &xy[1]
- y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.bucketsize)))
- y.k = add(unsafe.Pointer(y.b), dataOffset)
- y.e = add(y.k, bucketCnt*4)
- }
-
- for ; b != nil; b = b.overflow(t) {
- k := add(unsafe.Pointer(b), dataOffset)
- e := add(k, bucketCnt*4)
- for i := 0; i < bucketCnt; i, k, e = i+1, add(k, 4), add(e, uintptr(t.elemsize)) {
- top := b.tophash[i]
- if isEmpty(top) {
- b.tophash[i] = evacuatedEmpty
- continue
- }
- if top < minTopHash {
- throw("bad map state")
- }
- var useY uint8
- if !h.sameSizeGrow() {
- // Compute hash to make our evacuation decision (whether we need
- // to send this key/elem to bucket x or bucket y).
- hash := t.hasher(k, uintptr(h.hash0))
- if hash&newbit != 0 {
- useY = 1
- }
- }
-
- b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY, enforced in makemap
- dst := &xy[useY] // evacuation destination
-
- if dst.i == bucketCnt {
- dst.b = h.newoverflow(t, dst.b)
- dst.i = 0
- dst.k = add(unsafe.Pointer(dst.b), dataOffset)
- dst.e = add(dst.k, bucketCnt*4)
- }
- dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
-
- // Copy key.
- if goarch.PtrSize == 4 && t.key.ptrdata != 0 && writeBarrier.enabled {
- // Write with a write barrier.
- *(*unsafe.Pointer)(dst.k) = *(*unsafe.Pointer)(k)
- } else {
- *(*uint32)(dst.k) = *(*uint32)(k)
- }
-
- typedmemmove(t.elem, dst.e, e)
- dst.i++
- // These updates might push these pointers past the end of the
- // key or elem arrays. That's ok, as we have the overflow pointer
- // at the end of the bucket to protect against pointing past the
- // end of the bucket.
- dst.k = add(dst.k, 4)
- dst.e = add(dst.e, uintptr(t.elemsize))
- }
- }
- // Unlink the overflow buckets & clear key/elem to help GC.
- if h.flags&oldIterator == 0 && t.bucket.ptrdata != 0 {
- b := add(h.oldbuckets, oldbucket*uintptr(t.bucketsize))
- // Preserve b.tophash because the evacuation
- // state is maintained there.
- ptr := add(b, dataOffset)
- n := uintptr(t.bucketsize) - dataOffset
- memclrHasPointers(ptr, n)
- }
- }
-
- if oldbucket == h.nevacuate {
- advanceEvacuationMark(h, t, newbit)
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/map_fast64.go b/contrib/go/_std_1.20/src/runtime/map_fast64.go
deleted file mode 100644
index 2967360b76..0000000000
--- a/contrib/go/_std_1.20/src/runtime/map_fast64.go
+++ /dev/null
@@ -1,470 +0,0 @@
-// Copyright 2018 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 runtime
-
-import (
- "internal/abi"
- "internal/goarch"
- "unsafe"
-)
-
-func mapaccess1_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess1_fast64))
- }
- if h == nil || h.count == 0 {
- return unsafe.Pointer(&zeroVal[0])
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map read and map write")
- }
- var b *bmap
- if h.B == 0 {
- // One-bucket table. No need to hash.
- b = (*bmap)(h.buckets)
- } else {
- hash := t.hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
- m := bucketMask(h.B)
- b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
- if c := h.oldbuckets; c != nil {
- if !h.sameSizeGrow() {
- // There used to be half as many buckets; mask down one more power of two.
- m >>= 1
- }
- oldb := (*bmap)(add(c, (hash&m)*uintptr(t.bucketsize)))
- if !evacuated(oldb) {
- b = oldb
- }
- }
- }
- for ; b != nil; b = b.overflow(t) {
- for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 8) {
- if *(*uint64)(k) == key && !isEmpty(b.tophash[i]) {
- return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.elemsize))
- }
- }
- }
- return unsafe.Pointer(&zeroVal[0])
-}
-
-func mapaccess2_fast64(t *maptype, h *hmap, key uint64) (unsafe.Pointer, bool) {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess2_fast64))
- }
- if h == nil || h.count == 0 {
- return unsafe.Pointer(&zeroVal[0]), false
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map read and map write")
- }
- var b *bmap
- if h.B == 0 {
- // One-bucket table. No need to hash.
- b = (*bmap)(h.buckets)
- } else {
- hash := t.hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
- m := bucketMask(h.B)
- b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
- if c := h.oldbuckets; c != nil {
- if !h.sameSizeGrow() {
- // There used to be half as many buckets; mask down one more power of two.
- m >>= 1
- }
- oldb := (*bmap)(add(c, (hash&m)*uintptr(t.bucketsize)))
- if !evacuated(oldb) {
- b = oldb
- }
- }
- }
- for ; b != nil; b = b.overflow(t) {
- for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 8) {
- if *(*uint64)(k) == key && !isEmpty(b.tophash[i]) {
- return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.elemsize)), true
- }
- }
- }
- return unsafe.Pointer(&zeroVal[0]), false
-}
-
-func mapassign_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer {
- if h == nil {
- panic(plainError("assignment to entry in nil map"))
- }
- if raceenabled {
- callerpc := getcallerpc()
- racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapassign_fast64))
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map writes")
- }
- hash := t.hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
-
- // Set hashWriting after calling t.hasher for consistency with mapassign.
- h.flags ^= hashWriting
-
- if h.buckets == nil {
- h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
- }
-
-again:
- bucket := hash & bucketMask(h.B)
- if h.growing() {
- growWork_fast64(t, h, bucket)
- }
- b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
-
- var insertb *bmap
- var inserti uintptr
- var insertk unsafe.Pointer
-
-bucketloop:
- for {
- for i := uintptr(0); i < bucketCnt; i++ {
- if isEmpty(b.tophash[i]) {
- if insertb == nil {
- insertb = b
- inserti = i
- }
- if b.tophash[i] == emptyRest {
- break bucketloop
- }
- continue
- }
- k := *((*uint64)(add(unsafe.Pointer(b), dataOffset+i*8)))
- if k != key {
- continue
- }
- insertb = b
- inserti = i
- goto done
- }
- ovf := b.overflow(t)
- if ovf == nil {
- break
- }
- b = ovf
- }
-
- // Did not find mapping for key. Allocate new cell & add entry.
-
- // If we hit the max load factor or we have too many overflow buckets,
- // and we're not already in the middle of growing, start growing.
- if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
- hashGrow(t, h)
- goto again // Growing the table invalidates everything, so try again
- }
-
- if insertb == nil {
- // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
- insertb = h.newoverflow(t, b)
- inserti = 0 // not necessary, but avoids needlessly spilling inserti
- }
- insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks
-
- insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*8)
- // store new key at insert position
- *(*uint64)(insertk) = key
-
- h.count++
-
-done:
- elem := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*8+inserti*uintptr(t.elemsize))
- if h.flags&hashWriting == 0 {
- fatal("concurrent map writes")
- }
- h.flags &^= hashWriting
- return elem
-}
-
-func mapassign_fast64ptr(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
- if h == nil {
- panic(plainError("assignment to entry in nil map"))
- }
- if raceenabled {
- callerpc := getcallerpc()
- racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapassign_fast64))
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map writes")
- }
- hash := t.hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
-
- // Set hashWriting after calling t.hasher for consistency with mapassign.
- h.flags ^= hashWriting
-
- if h.buckets == nil {
- h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
- }
-
-again:
- bucket := hash & bucketMask(h.B)
- if h.growing() {
- growWork_fast64(t, h, bucket)
- }
- b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
-
- var insertb *bmap
- var inserti uintptr
- var insertk unsafe.Pointer
-
-bucketloop:
- for {
- for i := uintptr(0); i < bucketCnt; i++ {
- if isEmpty(b.tophash[i]) {
- if insertb == nil {
- insertb = b
- inserti = i
- }
- if b.tophash[i] == emptyRest {
- break bucketloop
- }
- continue
- }
- k := *((*unsafe.Pointer)(add(unsafe.Pointer(b), dataOffset+i*8)))
- if k != key {
- continue
- }
- insertb = b
- inserti = i
- goto done
- }
- ovf := b.overflow(t)
- if ovf == nil {
- break
- }
- b = ovf
- }
-
- // Did not find mapping for key. Allocate new cell & add entry.
-
- // If we hit the max load factor or we have too many overflow buckets,
- // and we're not already in the middle of growing, start growing.
- if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
- hashGrow(t, h)
- goto again // Growing the table invalidates everything, so try again
- }
-
- if insertb == nil {
- // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
- insertb = h.newoverflow(t, b)
- inserti = 0 // not necessary, but avoids needlessly spilling inserti
- }
- insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks
-
- insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*8)
- // store new key at insert position
- *(*unsafe.Pointer)(insertk) = key
-
- h.count++
-
-done:
- elem := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*8+inserti*uintptr(t.elemsize))
- if h.flags&hashWriting == 0 {
- fatal("concurrent map writes")
- }
- h.flags &^= hashWriting
- return elem
-}
-
-func mapdelete_fast64(t *maptype, h *hmap, key uint64) {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapdelete_fast64))
- }
- if h == nil || h.count == 0 {
- return
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map writes")
- }
-
- hash := t.hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
-
- // Set hashWriting after calling t.hasher for consistency with mapdelete
- h.flags ^= hashWriting
-
- bucket := hash & bucketMask(h.B)
- if h.growing() {
- growWork_fast64(t, h, bucket)
- }
- b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
- bOrig := b
-search:
- for ; b != nil; b = b.overflow(t) {
- for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 8) {
- if key != *(*uint64)(k) || isEmpty(b.tophash[i]) {
- continue
- }
- // Only clear key if there are pointers in it.
- if t.key.ptrdata != 0 {
- if goarch.PtrSize == 8 {
- *(*unsafe.Pointer)(k) = nil
- } else {
- // There are three ways to squeeze at one ore more 32 bit pointers into 64 bits.
- // Just call memclrHasPointers instead of trying to handle all cases here.
- memclrHasPointers(k, 8)
- }
- }
- e := add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.elemsize))
- if t.elem.ptrdata != 0 {
- memclrHasPointers(e, t.elem.size)
- } else {
- memclrNoHeapPointers(e, t.elem.size)
- }
- b.tophash[i] = emptyOne
- // If the bucket now ends in a bunch of emptyOne states,
- // change those to emptyRest states.
- if i == bucketCnt-1 {
- if b.overflow(t) != nil && b.overflow(t).tophash[0] != emptyRest {
- goto notLast
- }
- } else {
- if b.tophash[i+1] != emptyRest {
- goto notLast
- }
- }
- for {
- b.tophash[i] = emptyRest
- if i == 0 {
- if b == bOrig {
- break // beginning of initial bucket, we're done.
- }
- // Find previous bucket, continue at its last entry.
- c := b
- for b = bOrig; b.overflow(t) != c; b = b.overflow(t) {
- }
- i = bucketCnt - 1
- } else {
- i--
- }
- if b.tophash[i] != emptyOne {
- break
- }
- }
- notLast:
- h.count--
- // Reset the hash seed to make it more difficult for attackers to
- // repeatedly trigger hash collisions. See issue 25237.
- if h.count == 0 {
- h.hash0 = fastrand()
- }
- break search
- }
- }
-
- if h.flags&hashWriting == 0 {
- fatal("concurrent map writes")
- }
- h.flags &^= hashWriting
-}
-
-func growWork_fast64(t *maptype, h *hmap, bucket uintptr) {
- // make sure we evacuate the oldbucket corresponding
- // to the bucket we're about to use
- evacuate_fast64(t, h, bucket&h.oldbucketmask())
-
- // evacuate one more oldbucket to make progress on growing
- if h.growing() {
- evacuate_fast64(t, h, h.nevacuate)
- }
-}
-
-func evacuate_fast64(t *maptype, h *hmap, oldbucket uintptr) {
- b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
- newbit := h.noldbuckets()
- if !evacuated(b) {
- // TODO: reuse overflow buckets instead of using new ones, if there
- // is no iterator using the old buckets. (If !oldIterator.)
-
- // xy contains the x and y (low and high) evacuation destinations.
- var xy [2]evacDst
- x := &xy[0]
- x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.bucketsize)))
- x.k = add(unsafe.Pointer(x.b), dataOffset)
- x.e = add(x.k, bucketCnt*8)
-
- if !h.sameSizeGrow() {
- // Only calculate y pointers if we're growing bigger.
- // Otherwise GC can see bad pointers.
- y := &xy[1]
- y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.bucketsize)))
- y.k = add(unsafe.Pointer(y.b), dataOffset)
- y.e = add(y.k, bucketCnt*8)
- }
-
- for ; b != nil; b = b.overflow(t) {
- k := add(unsafe.Pointer(b), dataOffset)
- e := add(k, bucketCnt*8)
- for i := 0; i < bucketCnt; i, k, e = i+1, add(k, 8), add(e, uintptr(t.elemsize)) {
- top := b.tophash[i]
- if isEmpty(top) {
- b.tophash[i] = evacuatedEmpty
- continue
- }
- if top < minTopHash {
- throw("bad map state")
- }
- var useY uint8
- if !h.sameSizeGrow() {
- // Compute hash to make our evacuation decision (whether we need
- // to send this key/elem to bucket x or bucket y).
- hash := t.hasher(k, uintptr(h.hash0))
- if hash&newbit != 0 {
- useY = 1
- }
- }
-
- b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY, enforced in makemap
- dst := &xy[useY] // evacuation destination
-
- if dst.i == bucketCnt {
- dst.b = h.newoverflow(t, dst.b)
- dst.i = 0
- dst.k = add(unsafe.Pointer(dst.b), dataOffset)
- dst.e = add(dst.k, bucketCnt*8)
- }
- dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
-
- // Copy key.
- if t.key.ptrdata != 0 && writeBarrier.enabled {
- if goarch.PtrSize == 8 {
- // Write with a write barrier.
- *(*unsafe.Pointer)(dst.k) = *(*unsafe.Pointer)(k)
- } else {
- // There are three ways to squeeze at least one 32 bit pointer into 64 bits.
- // Give up and call typedmemmove.
- typedmemmove(t.key, dst.k, k)
- }
- } else {
- *(*uint64)(dst.k) = *(*uint64)(k)
- }
-
- typedmemmove(t.elem, dst.e, e)
- dst.i++
- // These updates might push these pointers past the end of the
- // key or elem arrays. That's ok, as we have the overflow pointer
- // at the end of the bucket to protect against pointing past the
- // end of the bucket.
- dst.k = add(dst.k, 8)
- dst.e = add(dst.e, uintptr(t.elemsize))
- }
- }
- // Unlink the overflow buckets & clear key/elem to help GC.
- if h.flags&oldIterator == 0 && t.bucket.ptrdata != 0 {
- b := add(h.oldbuckets, oldbucket*uintptr(t.bucketsize))
- // Preserve b.tophash because the evacuation
- // state is maintained there.
- ptr := add(b, dataOffset)
- n := uintptr(t.bucketsize) - dataOffset
- memclrHasPointers(ptr, n)
- }
- }
-
- if oldbucket == h.nevacuate {
- advanceEvacuationMark(h, t, newbit)
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/map_faststr.go b/contrib/go/_std_1.20/src/runtime/map_faststr.go
deleted file mode 100644
index 006c24cee2..0000000000
--- a/contrib/go/_std_1.20/src/runtime/map_faststr.go
+++ /dev/null
@@ -1,485 +0,0 @@
-// Copyright 2018 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 runtime
-
-import (
- "internal/abi"
- "internal/goarch"
- "unsafe"
-)
-
-func mapaccess1_faststr(t *maptype, h *hmap, ky string) unsafe.Pointer {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess1_faststr))
- }
- if h == nil || h.count == 0 {
- return unsafe.Pointer(&zeroVal[0])
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map read and map write")
- }
- key := stringStructOf(&ky)
- if h.B == 0 {
- // One-bucket table.
- b := (*bmap)(h.buckets)
- if key.len < 32 {
- // short key, doing lots of comparisons is ok
- for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
- k := (*stringStruct)(kptr)
- if k.len != key.len || isEmpty(b.tophash[i]) {
- if b.tophash[i] == emptyRest {
- break
- }
- continue
- }
- if k.str == key.str || memequal(k.str, key.str, uintptr(key.len)) {
- return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.elemsize))
- }
- }
- return unsafe.Pointer(&zeroVal[0])
- }
- // long key, try not to do more comparisons than necessary
- keymaybe := uintptr(bucketCnt)
- for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
- k := (*stringStruct)(kptr)
- if k.len != key.len || isEmpty(b.tophash[i]) {
- if b.tophash[i] == emptyRest {
- break
- }
- continue
- }
- if k.str == key.str {
- return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.elemsize))
- }
- // check first 4 bytes
- if *((*[4]byte)(key.str)) != *((*[4]byte)(k.str)) {
- continue
- }
- // check last 4 bytes
- if *((*[4]byte)(add(key.str, uintptr(key.len)-4))) != *((*[4]byte)(add(k.str, uintptr(key.len)-4))) {
- continue
- }
- if keymaybe != bucketCnt {
- // Two keys are potential matches. Use hash to distinguish them.
- goto dohash
- }
- keymaybe = i
- }
- if keymaybe != bucketCnt {
- k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+keymaybe*2*goarch.PtrSize))
- if memequal(k.str, key.str, uintptr(key.len)) {
- return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+keymaybe*uintptr(t.elemsize))
- }
- }
- return unsafe.Pointer(&zeroVal[0])
- }
-dohash:
- hash := t.hasher(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0))
- m := bucketMask(h.B)
- b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
- if c := h.oldbuckets; c != nil {
- if !h.sameSizeGrow() {
- // There used to be half as many buckets; mask down one more power of two.
- m >>= 1
- }
- oldb := (*bmap)(add(c, (hash&m)*uintptr(t.bucketsize)))
- if !evacuated(oldb) {
- b = oldb
- }
- }
- top := tophash(hash)
- for ; b != nil; b = b.overflow(t) {
- for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
- k := (*stringStruct)(kptr)
- if k.len != key.len || b.tophash[i] != top {
- continue
- }
- if k.str == key.str || memequal(k.str, key.str, uintptr(key.len)) {
- return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.elemsize))
- }
- }
- }
- return unsafe.Pointer(&zeroVal[0])
-}
-
-func mapaccess2_faststr(t *maptype, h *hmap, ky string) (unsafe.Pointer, bool) {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess2_faststr))
- }
- if h == nil || h.count == 0 {
- return unsafe.Pointer(&zeroVal[0]), false
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map read and map write")
- }
- key := stringStructOf(&ky)
- if h.B == 0 {
- // One-bucket table.
- b := (*bmap)(h.buckets)
- if key.len < 32 {
- // short key, doing lots of comparisons is ok
- for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
- k := (*stringStruct)(kptr)
- if k.len != key.len || isEmpty(b.tophash[i]) {
- if b.tophash[i] == emptyRest {
- break
- }
- continue
- }
- if k.str == key.str || memequal(k.str, key.str, uintptr(key.len)) {
- return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.elemsize)), true
- }
- }
- return unsafe.Pointer(&zeroVal[0]), false
- }
- // long key, try not to do more comparisons than necessary
- keymaybe := uintptr(bucketCnt)
- for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
- k := (*stringStruct)(kptr)
- if k.len != key.len || isEmpty(b.tophash[i]) {
- if b.tophash[i] == emptyRest {
- break
- }
- continue
- }
- if k.str == key.str {
- return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.elemsize)), true
- }
- // check first 4 bytes
- if *((*[4]byte)(key.str)) != *((*[4]byte)(k.str)) {
- continue
- }
- // check last 4 bytes
- if *((*[4]byte)(add(key.str, uintptr(key.len)-4))) != *((*[4]byte)(add(k.str, uintptr(key.len)-4))) {
- continue
- }
- if keymaybe != bucketCnt {
- // Two keys are potential matches. Use hash to distinguish them.
- goto dohash
- }
- keymaybe = i
- }
- if keymaybe != bucketCnt {
- k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+keymaybe*2*goarch.PtrSize))
- if memequal(k.str, key.str, uintptr(key.len)) {
- return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+keymaybe*uintptr(t.elemsize)), true
- }
- }
- return unsafe.Pointer(&zeroVal[0]), false
- }
-dohash:
- hash := t.hasher(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0))
- m := bucketMask(h.B)
- b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
- if c := h.oldbuckets; c != nil {
- if !h.sameSizeGrow() {
- // There used to be half as many buckets; mask down one more power of two.
- m >>= 1
- }
- oldb := (*bmap)(add(c, (hash&m)*uintptr(t.bucketsize)))
- if !evacuated(oldb) {
- b = oldb
- }
- }
- top := tophash(hash)
- for ; b != nil; b = b.overflow(t) {
- for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
- k := (*stringStruct)(kptr)
- if k.len != key.len || b.tophash[i] != top {
- continue
- }
- if k.str == key.str || memequal(k.str, key.str, uintptr(key.len)) {
- return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.elemsize)), true
- }
- }
- }
- return unsafe.Pointer(&zeroVal[0]), false
-}
-
-func mapassign_faststr(t *maptype, h *hmap, s string) unsafe.Pointer {
- if h == nil {
- panic(plainError("assignment to entry in nil map"))
- }
- if raceenabled {
- callerpc := getcallerpc()
- racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapassign_faststr))
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map writes")
- }
- key := stringStructOf(&s)
- hash := t.hasher(noescape(unsafe.Pointer(&s)), uintptr(h.hash0))
-
- // Set hashWriting after calling t.hasher for consistency with mapassign.
- h.flags ^= hashWriting
-
- if h.buckets == nil {
- h.buckets = newobject(t.bucket) // newarray(t.bucket, 1)
- }
-
-again:
- bucket := hash & bucketMask(h.B)
- if h.growing() {
- growWork_faststr(t, h, bucket)
- }
- b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
- top := tophash(hash)
-
- var insertb *bmap
- var inserti uintptr
- var insertk unsafe.Pointer
-
-bucketloop:
- for {
- for i := uintptr(0); i < bucketCnt; i++ {
- if b.tophash[i] != top {
- if isEmpty(b.tophash[i]) && insertb == nil {
- insertb = b
- inserti = i
- }
- if b.tophash[i] == emptyRest {
- break bucketloop
- }
- continue
- }
- k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*goarch.PtrSize))
- if k.len != key.len {
- continue
- }
- if k.str != key.str && !memequal(k.str, key.str, uintptr(key.len)) {
- continue
- }
- // already have a mapping for key. Update it.
- inserti = i
- insertb = b
- // Overwrite existing key, so it can be garbage collected.
- // The size is already guaranteed to be set correctly.
- k.str = key.str
- goto done
- }
- ovf := b.overflow(t)
- if ovf == nil {
- break
- }
- b = ovf
- }
-
- // Did not find mapping for key. Allocate new cell & add entry.
-
- // If we hit the max load factor or we have too many overflow buckets,
- // and we're not already in the middle of growing, start growing.
- if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
- hashGrow(t, h)
- goto again // Growing the table invalidates everything, so try again
- }
-
- if insertb == nil {
- // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
- insertb = h.newoverflow(t, b)
- inserti = 0 // not necessary, but avoids needlessly spilling inserti
- }
- insertb.tophash[inserti&(bucketCnt-1)] = top // mask inserti to avoid bounds checks
-
- insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*2*goarch.PtrSize)
- // store new key at insert position
- *((*stringStruct)(insertk)) = *key
- h.count++
-
-done:
- elem := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*2*goarch.PtrSize+inserti*uintptr(t.elemsize))
- if h.flags&hashWriting == 0 {
- fatal("concurrent map writes")
- }
- h.flags &^= hashWriting
- return elem
-}
-
-func mapdelete_faststr(t *maptype, h *hmap, ky string) {
- if raceenabled && h != nil {
- callerpc := getcallerpc()
- racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapdelete_faststr))
- }
- if h == nil || h.count == 0 {
- return
- }
- if h.flags&hashWriting != 0 {
- fatal("concurrent map writes")
- }
-
- key := stringStructOf(&ky)
- hash := t.hasher(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0))
-
- // Set hashWriting after calling t.hasher for consistency with mapdelete
- h.flags ^= hashWriting
-
- bucket := hash & bucketMask(h.B)
- if h.growing() {
- growWork_faststr(t, h, bucket)
- }
- b := (*bmap)(add(h.buckets, bucket*uintptr(t.bucketsize)))
- bOrig := b
- top := tophash(hash)
-search:
- for ; b != nil; b = b.overflow(t) {
- for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
- k := (*stringStruct)(kptr)
- if k.len != key.len || b.tophash[i] != top {
- continue
- }
- if k.str != key.str && !memequal(k.str, key.str, uintptr(key.len)) {
- continue
- }
- // Clear key's pointer.
- k.str = nil
- e := add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.elemsize))
- if t.elem.ptrdata != 0 {
- memclrHasPointers(e, t.elem.size)
- } else {
- memclrNoHeapPointers(e, t.elem.size)
- }
- b.tophash[i] = emptyOne
- // If the bucket now ends in a bunch of emptyOne states,
- // change those to emptyRest states.
- if i == bucketCnt-1 {
- if b.overflow(t) != nil && b.overflow(t).tophash[0] != emptyRest {
- goto notLast
- }
- } else {
- if b.tophash[i+1] != emptyRest {
- goto notLast
- }
- }
- for {
- b.tophash[i] = emptyRest
- if i == 0 {
- if b == bOrig {
- break // beginning of initial bucket, we're done.
- }
- // Find previous bucket, continue at its last entry.
- c := b
- for b = bOrig; b.overflow(t) != c; b = b.overflow(t) {
- }
- i = bucketCnt - 1
- } else {
- i--
- }
- if b.tophash[i] != emptyOne {
- break
- }
- }
- notLast:
- h.count--
- // Reset the hash seed to make it more difficult for attackers to
- // repeatedly trigger hash collisions. See issue 25237.
- if h.count == 0 {
- h.hash0 = fastrand()
- }
- break search
- }
- }
-
- if h.flags&hashWriting == 0 {
- fatal("concurrent map writes")
- }
- h.flags &^= hashWriting
-}
-
-func growWork_faststr(t *maptype, h *hmap, bucket uintptr) {
- // make sure we evacuate the oldbucket corresponding
- // to the bucket we're about to use
- evacuate_faststr(t, h, bucket&h.oldbucketmask())
-
- // evacuate one more oldbucket to make progress on growing
- if h.growing() {
- evacuate_faststr(t, h, h.nevacuate)
- }
-}
-
-func evacuate_faststr(t *maptype, h *hmap, oldbucket uintptr) {
- b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
- newbit := h.noldbuckets()
- if !evacuated(b) {
- // TODO: reuse overflow buckets instead of using new ones, if there
- // is no iterator using the old buckets. (If !oldIterator.)
-
- // xy contains the x and y (low and high) evacuation destinations.
- var xy [2]evacDst
- x := &xy[0]
- x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.bucketsize)))
- x.k = add(unsafe.Pointer(x.b), dataOffset)
- x.e = add(x.k, bucketCnt*2*goarch.PtrSize)
-
- if !h.sameSizeGrow() {
- // Only calculate y pointers if we're growing bigger.
- // Otherwise GC can see bad pointers.
- y := &xy[1]
- y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.bucketsize)))
- y.k = add(unsafe.Pointer(y.b), dataOffset)
- y.e = add(y.k, bucketCnt*2*goarch.PtrSize)
- }
-
- for ; b != nil; b = b.overflow(t) {
- k := add(unsafe.Pointer(b), dataOffset)
- e := add(k, bucketCnt*2*goarch.PtrSize)
- for i := 0; i < bucketCnt; i, k, e = i+1, add(k, 2*goarch.PtrSize), add(e, uintptr(t.elemsize)) {
- top := b.tophash[i]
- if isEmpty(top) {
- b.tophash[i] = evacuatedEmpty
- continue
- }
- if top < minTopHash {
- throw("bad map state")
- }
- var useY uint8
- if !h.sameSizeGrow() {
- // Compute hash to make our evacuation decision (whether we need
- // to send this key/elem to bucket x or bucket y).
- hash := t.hasher(k, uintptr(h.hash0))
- if hash&newbit != 0 {
- useY = 1
- }
- }
-
- b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY, enforced in makemap
- dst := &xy[useY] // evacuation destination
-
- if dst.i == bucketCnt {
- dst.b = h.newoverflow(t, dst.b)
- dst.i = 0
- dst.k = add(unsafe.Pointer(dst.b), dataOffset)
- dst.e = add(dst.k, bucketCnt*2*goarch.PtrSize)
- }
- dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
-
- // Copy key.
- *(*string)(dst.k) = *(*string)(k)
-
- typedmemmove(t.elem, dst.e, e)
- dst.i++
- // These updates might push these pointers past the end of the
- // key or elem arrays. That's ok, as we have the overflow pointer
- // at the end of the bucket to protect against pointing past the
- // end of the bucket.
- dst.k = add(dst.k, 2*goarch.PtrSize)
- dst.e = add(dst.e, uintptr(t.elemsize))
- }
- }
- // Unlink the overflow buckets & clear key/elem to help GC.
- if h.flags&oldIterator == 0 && t.bucket.ptrdata != 0 {
- b := add(h.oldbuckets, oldbucket*uintptr(t.bucketsize))
- // Preserve b.tophash because the evacuation
- // state is maintained there.
- ptr := add(b, dataOffset)
- n := uintptr(t.bucketsize) - dataOffset
- memclrHasPointers(ptr, n)
- }
- }
-
- if oldbucket == h.nevacuate {
- advanceEvacuationMark(h, t, newbit)
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mbarrier.go b/contrib/go/_std_1.20/src/runtime/mbarrier.go
deleted file mode 100644
index 46ef42f74d..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mbarrier.go
+++ /dev/null
@@ -1,346 +0,0 @@
-// Copyright 2015 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.
-
-// Garbage collector: write barriers.
-//
-// For the concurrent garbage collector, the Go compiler implements
-// updates to pointer-valued fields that may be in heap objects by
-// emitting calls to write barriers. The main write barrier for
-// individual pointer writes is gcWriteBarrier and is implemented in
-// assembly. This file contains write barrier entry points for bulk
-// operations. See also mwbbuf.go.
-
-package runtime
-
-import (
- "internal/abi"
- "internal/goarch"
- "unsafe"
-)
-
-// Go uses a hybrid barrier that combines a Yuasa-style deletion
-// barrier—which shades the object whose reference is being
-// overwritten—with Dijkstra insertion barrier—which shades the object
-// whose reference is being written. The insertion part of the barrier
-// is necessary while the calling goroutine's stack is grey. In
-// pseudocode, the barrier is:
-//
-// writePointer(slot, ptr):
-// shade(*slot)
-// if current stack is grey:
-// shade(ptr)
-// *slot = ptr
-//
-// slot is the destination in Go code.
-// ptr is the value that goes into the slot in Go code.
-//
-// Shade indicates that it has seen a white pointer by adding the referent
-// to wbuf as well as marking it.
-//
-// The two shades and the condition work together to prevent a mutator
-// from hiding an object from the garbage collector:
-//
-// 1. shade(*slot) prevents a mutator from hiding an object by moving
-// the sole pointer to it from the heap to its stack. If it attempts
-// to unlink an object from the heap, this will shade it.
-//
-// 2. shade(ptr) prevents a mutator from hiding an object by moving
-// the sole pointer to it from its stack into a black object in the
-// heap. If it attempts to install the pointer into a black object,
-// this will shade it.
-//
-// 3. Once a goroutine's stack is black, the shade(ptr) becomes
-// unnecessary. shade(ptr) prevents hiding an object by moving it from
-// the stack to the heap, but this requires first having a pointer
-// hidden on the stack. Immediately after a stack is scanned, it only
-// points to shaded objects, so it's not hiding anything, and the
-// shade(*slot) prevents it from hiding any other pointers on its
-// stack.
-//
-// For a detailed description of this barrier and proof of
-// correctness, see https://github.com/golang/proposal/blob/master/design/17503-eliminate-rescan.md
-//
-//
-//
-// Dealing with memory ordering:
-//
-// Both the Yuasa and Dijkstra barriers can be made conditional on the
-// color of the object containing the slot. We chose not to make these
-// conditional because the cost of ensuring that the object holding
-// the slot doesn't concurrently change color without the mutator
-// noticing seems prohibitive.
-//
-// Consider the following example where the mutator writes into
-// a slot and then loads the slot's mark bit while the GC thread
-// writes to the slot's mark bit and then as part of scanning reads
-// the slot.
-//
-// Initially both [slot] and [slotmark] are 0 (nil)
-// Mutator thread GC thread
-// st [slot], ptr st [slotmark], 1
-//
-// ld r1, [slotmark] ld r2, [slot]
-//
-// Without an expensive memory barrier between the st and the ld, the final
-// result on most HW (including 386/amd64) can be r1==r2==0. This is a classic
-// example of what can happen when loads are allowed to be reordered with older
-// stores (avoiding such reorderings lies at the heart of the classic
-// Peterson/Dekker algorithms for mutual exclusion). Rather than require memory
-// barriers, which will slow down both the mutator and the GC, we always grey
-// the ptr object regardless of the slot's color.
-//
-// Another place where we intentionally omit memory barriers is when
-// accessing mheap_.arena_used to check if a pointer points into the
-// heap. On relaxed memory machines, it's possible for a mutator to
-// extend the size of the heap by updating arena_used, allocate an
-// object from this new region, and publish a pointer to that object,
-// but for tracing running on another processor to observe the pointer
-// but use the old value of arena_used. In this case, tracing will not
-// mark the object, even though it's reachable. However, the mutator
-// is guaranteed to execute a write barrier when it publishes the
-// pointer, so it will take care of marking the object. A general
-// consequence of this is that the garbage collector may cache the
-// value of mheap_.arena_used. (See issue #9984.)
-//
-//
-// Stack writes:
-//
-// The compiler omits write barriers for writes to the current frame,
-// but if a stack pointer has been passed down the call stack, the
-// compiler will generate a write barrier for writes through that
-// pointer (because it doesn't know it's not a heap pointer).
-//
-// One might be tempted to ignore the write barrier if slot points
-// into to the stack. Don't do it! Mark termination only re-scans
-// frames that have potentially been active since the concurrent scan,
-// so it depends on write barriers to track changes to pointers in
-// stack frames that have not been active.
-//
-//
-// Global writes:
-//
-// The Go garbage collector requires write barriers when heap pointers
-// are stored in globals. Many garbage collectors ignore writes to
-// globals and instead pick up global -> heap pointers during
-// termination. This increases pause time, so we instead rely on write
-// barriers for writes to globals so that we don't have to rescan
-// global during mark termination.
-//
-//
-// Publication ordering:
-//
-// The write barrier is *pre-publication*, meaning that the write
-// barrier happens prior to the *slot = ptr write that may make ptr
-// reachable by some goroutine that currently cannot reach it.
-//
-//
-// Signal handler pointer writes:
-//
-// In general, the signal handler cannot safely invoke the write
-// barrier because it may run without a P or even during the write
-// barrier.
-//
-// There is exactly one exception: profbuf.go omits a barrier during
-// signal handler profile logging. That's safe only because of the
-// deletion barrier. See profbuf.go for a detailed argument. If we
-// remove the deletion barrier, we'll have to work out a new way to
-// handle the profile logging.
-
-// typedmemmove copies a value of type typ to dst from src.
-// Must be nosplit, see #16026.
-//
-// TODO: Perfect for go:nosplitrec since we can't have a safe point
-// anywhere in the bulk barrier or memmove.
-//
-//go:nosplit
-func typedmemmove(typ *_type, dst, src unsafe.Pointer) {
- if dst == src {
- return
- }
- if writeBarrier.needed && typ.ptrdata != 0 {
- bulkBarrierPreWrite(uintptr(dst), uintptr(src), typ.ptrdata)
- }
- // There's a race here: if some other goroutine can write to
- // src, it may change some pointer in src after we've
- // performed the write barrier but before we perform the
- // memory copy. This safe because the write performed by that
- // other goroutine must also be accompanied by a write
- // barrier, so at worst we've unnecessarily greyed the old
- // pointer that was in src.
- memmove(dst, src, typ.size)
- if writeBarrier.cgo {
- cgoCheckMemmove(typ, dst, src, 0, typ.size)
- }
-}
-
-//go:linkname reflect_typedmemmove reflect.typedmemmove
-func reflect_typedmemmove(typ *_type, dst, src unsafe.Pointer) {
- if raceenabled {
- raceWriteObjectPC(typ, dst, getcallerpc(), abi.FuncPCABIInternal(reflect_typedmemmove))
- raceReadObjectPC(typ, src, getcallerpc(), abi.FuncPCABIInternal(reflect_typedmemmove))
- }
- if msanenabled {
- msanwrite(dst, typ.size)
- msanread(src, typ.size)
- }
- if asanenabled {
- asanwrite(dst, typ.size)
- asanread(src, typ.size)
- }
- typedmemmove(typ, dst, src)
-}
-
-//go:linkname reflectlite_typedmemmove internal/reflectlite.typedmemmove
-func reflectlite_typedmemmove(typ *_type, dst, src unsafe.Pointer) {
- reflect_typedmemmove(typ, dst, src)
-}
-
-// reflect_typedmemmovepartial is like typedmemmove but assumes that
-// dst and src point off bytes into the value and only copies size bytes.
-// off must be a multiple of goarch.PtrSize.
-//
-//go:linkname reflect_typedmemmovepartial reflect.typedmemmovepartial
-func reflect_typedmemmovepartial(typ *_type, dst, src unsafe.Pointer, off, size uintptr) {
- if writeBarrier.needed && typ.ptrdata > off && size >= goarch.PtrSize {
- if off&(goarch.PtrSize-1) != 0 {
- panic("reflect: internal error: misaligned offset")
- }
- pwsize := alignDown(size, goarch.PtrSize)
- if poff := typ.ptrdata - off; pwsize > poff {
- pwsize = poff
- }
- bulkBarrierPreWrite(uintptr(dst), uintptr(src), pwsize)
- }
-
- memmove(dst, src, size)
- if writeBarrier.cgo {
- cgoCheckMemmove(typ, dst, src, off, size)
- }
-}
-
-// reflectcallmove is invoked by reflectcall to copy the return values
-// out of the stack and into the heap, invoking the necessary write
-// barriers. dst, src, and size describe the return value area to
-// copy. typ describes the entire frame (not just the return values).
-// typ may be nil, which indicates write barriers are not needed.
-//
-// It must be nosplit and must only call nosplit functions because the
-// stack map of reflectcall is wrong.
-//
-//go:nosplit
-func reflectcallmove(typ *_type, dst, src unsafe.Pointer, size uintptr, regs *abi.RegArgs) {
- if writeBarrier.needed && typ != nil && typ.ptrdata != 0 && size >= goarch.PtrSize {
- bulkBarrierPreWrite(uintptr(dst), uintptr(src), size)
- }
- memmove(dst, src, size)
-
- // Move pointers returned in registers to a place where the GC can see them.
- for i := range regs.Ints {
- if regs.ReturnIsPtr.Get(i) {
- regs.Ptrs[i] = unsafe.Pointer(regs.Ints[i])
- }
- }
-}
-
-//go:nosplit
-func typedslicecopy(typ *_type, dstPtr unsafe.Pointer, dstLen int, srcPtr unsafe.Pointer, srcLen int) int {
- n := dstLen
- if n > srcLen {
- n = srcLen
- }
- if n == 0 {
- return 0
- }
-
- // The compiler emits calls to typedslicecopy before
- // instrumentation runs, so unlike the other copying and
- // assignment operations, it's not instrumented in the calling
- // code and needs its own instrumentation.
- if raceenabled {
- callerpc := getcallerpc()
- pc := abi.FuncPCABIInternal(slicecopy)
- racewriterangepc(dstPtr, uintptr(n)*typ.size, callerpc, pc)
- racereadrangepc(srcPtr, uintptr(n)*typ.size, callerpc, pc)
- }
- if msanenabled {
- msanwrite(dstPtr, uintptr(n)*typ.size)
- msanread(srcPtr, uintptr(n)*typ.size)
- }
- if asanenabled {
- asanwrite(dstPtr, uintptr(n)*typ.size)
- asanread(srcPtr, uintptr(n)*typ.size)
- }
-
- if writeBarrier.cgo {
- cgoCheckSliceCopy(typ, dstPtr, srcPtr, n)
- }
-
- if dstPtr == srcPtr {
- return n
- }
-
- // Note: No point in checking typ.ptrdata here:
- // compiler only emits calls to typedslicecopy for types with pointers,
- // and growslice and reflect_typedslicecopy check for pointers
- // before calling typedslicecopy.
- size := uintptr(n) * typ.size
- if writeBarrier.needed {
- pwsize := size - typ.size + typ.ptrdata
- bulkBarrierPreWrite(uintptr(dstPtr), uintptr(srcPtr), pwsize)
- }
- // See typedmemmove for a discussion of the race between the
- // barrier and memmove.
- memmove(dstPtr, srcPtr, size)
- return n
-}
-
-//go:linkname reflect_typedslicecopy reflect.typedslicecopy
-func reflect_typedslicecopy(elemType *_type, dst, src slice) int {
- if elemType.ptrdata == 0 {
- return slicecopy(dst.array, dst.len, src.array, src.len, elemType.size)
- }
- return typedslicecopy(elemType, dst.array, dst.len, src.array, src.len)
-}
-
-// typedmemclr clears the typed memory at ptr with type typ. The
-// memory at ptr must already be initialized (and hence in type-safe
-// state). If the memory is being initialized for the first time, see
-// memclrNoHeapPointers.
-//
-// If the caller knows that typ has pointers, it can alternatively
-// call memclrHasPointers.
-//
-// TODO: A "go:nosplitrec" annotation would be perfect for this.
-//
-//go:nosplit
-func typedmemclr(typ *_type, ptr unsafe.Pointer) {
- if writeBarrier.needed && typ.ptrdata != 0 {
- bulkBarrierPreWrite(uintptr(ptr), 0, typ.ptrdata)
- }
- memclrNoHeapPointers(ptr, typ.size)
-}
-
-//go:linkname reflect_typedmemclr reflect.typedmemclr
-func reflect_typedmemclr(typ *_type, ptr unsafe.Pointer) {
- typedmemclr(typ, ptr)
-}
-
-//go:linkname reflect_typedmemclrpartial reflect.typedmemclrpartial
-func reflect_typedmemclrpartial(typ *_type, ptr unsafe.Pointer, off, size uintptr) {
- if writeBarrier.needed && typ.ptrdata != 0 {
- bulkBarrierPreWrite(uintptr(ptr), 0, size)
- }
- memclrNoHeapPointers(ptr, size)
-}
-
-// memclrHasPointers clears n bytes of typed memory starting at ptr.
-// The caller must ensure that the type of the object at ptr has
-// pointers, usually by checking typ.ptrdata. However, ptr
-// does not have to point to the start of the allocation.
-//
-//go:nosplit
-func memclrHasPointers(ptr unsafe.Pointer, n uintptr) {
- bulkBarrierPreWrite(uintptr(ptr), 0, n)
- memclrNoHeapPointers(ptr, n)
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mbitmap.go b/contrib/go/_std_1.20/src/runtime/mbitmap.go
deleted file mode 100644
index 088b566729..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mbitmap.go
+++ /dev/null
@@ -1,1501 +0,0 @@
-// Copyright 2009 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.
-
-// Garbage collector: type and heap bitmaps.
-//
-// Stack, data, and bss bitmaps
-//
-// Stack frames and global variables in the data and bss sections are
-// described by bitmaps with 1 bit per pointer-sized word. A "1" bit
-// means the word is a live pointer to be visited by the GC (referred to
-// as "pointer"). A "0" bit means the word should be ignored by GC
-// (referred to as "scalar", though it could be a dead pointer value).
-//
-// Heap bitmap
-//
-// The heap bitmap comprises 1 bit for each pointer-sized word in the heap,
-// recording whether a pointer is stored in that word or not. This bitmap
-// is stored in the heapArena metadata backing each heap arena.
-// That is, if ha is the heapArena for the arena starting at "start",
-// then ha.bitmap[0] holds the 64 bits for the 64 words "start"
-// through start+63*ptrSize, ha.bitmap[1] holds the entries for
-// start+64*ptrSize through start+127*ptrSize, and so on.
-// Bits correspond to words in little-endian order. ha.bitmap[0]&1 represents
-// the word at "start", ha.bitmap[0]>>1&1 represents the word at start+8, etc.
-// (For 32-bit platforms, s/64/32/.)
-//
-// We also keep a noMorePtrs bitmap which allows us to stop scanning
-// the heap bitmap early in certain situations. If ha.noMorePtrs[i]>>j&1
-// is 1, then the object containing the last word described by ha.bitmap[8*i+j]
-// has no more pointers beyond those described by ha.bitmap[8*i+j].
-// If ha.noMorePtrs[i]>>j&1 is set, the entries in ha.bitmap[8*i+j+1] and
-// beyond must all be zero until the start of the next object.
-//
-// The bitmap for noscan spans is set to all zero at span allocation time.
-//
-// The bitmap for unallocated objects in scannable spans is not maintained
-// (can be junk).
-
-package runtime
-
-import (
- "internal/goarch"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// addb returns the byte pointer p+n.
-//
-//go:nowritebarrier
-//go:nosplit
-func addb(p *byte, n uintptr) *byte {
- // Note: wrote out full expression instead of calling add(p, n)
- // to reduce the number of temporaries generated by the
- // compiler for this trivial expression during inlining.
- return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + n))
-}
-
-// subtractb returns the byte pointer p-n.
-//
-//go:nowritebarrier
-//go:nosplit
-func subtractb(p *byte, n uintptr) *byte {
- // Note: wrote out full expression instead of calling add(p, -n)
- // to reduce the number of temporaries generated by the
- // compiler for this trivial expression during inlining.
- return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) - n))
-}
-
-// add1 returns the byte pointer p+1.
-//
-//go:nowritebarrier
-//go:nosplit
-func add1(p *byte) *byte {
- // Note: wrote out full expression instead of calling addb(p, 1)
- // to reduce the number of temporaries generated by the
- // compiler for this trivial expression during inlining.
- return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + 1))
-}
-
-// subtract1 returns the byte pointer p-1.
-//
-// nosplit because it is used during write barriers and must not be preempted.
-//
-//go:nowritebarrier
-//go:nosplit
-func subtract1(p *byte) *byte {
- // Note: wrote out full expression instead of calling subtractb(p, 1)
- // to reduce the number of temporaries generated by the
- // compiler for this trivial expression during inlining.
- return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) - 1))
-}
-
-// markBits provides access to the mark bit for an object in the heap.
-// bytep points to the byte holding the mark bit.
-// mask is a byte with a single bit set that can be &ed with *bytep
-// to see if the bit has been set.
-// *m.byte&m.mask != 0 indicates the mark bit is set.
-// index can be used along with span information to generate
-// the address of the object in the heap.
-// We maintain one set of mark bits for allocation and one for
-// marking purposes.
-type markBits struct {
- bytep *uint8
- mask uint8
- index uintptr
-}
-
-//go:nosplit
-func (s *mspan) allocBitsForIndex(allocBitIndex uintptr) markBits {
- bytep, mask := s.allocBits.bitp(allocBitIndex)
- return markBits{bytep, mask, allocBitIndex}
-}
-
-// refillAllocCache takes 8 bytes s.allocBits starting at whichByte
-// and negates them so that ctz (count trailing zeros) instructions
-// can be used. It then places these 8 bytes into the cached 64 bit
-// s.allocCache.
-func (s *mspan) refillAllocCache(whichByte uintptr) {
- bytes := (*[8]uint8)(unsafe.Pointer(s.allocBits.bytep(whichByte)))
- aCache := uint64(0)
- aCache |= uint64(bytes[0])
- aCache |= uint64(bytes[1]) << (1 * 8)
- aCache |= uint64(bytes[2]) << (2 * 8)
- aCache |= uint64(bytes[3]) << (3 * 8)
- aCache |= uint64(bytes[4]) << (4 * 8)
- aCache |= uint64(bytes[5]) << (5 * 8)
- aCache |= uint64(bytes[6]) << (6 * 8)
- aCache |= uint64(bytes[7]) << (7 * 8)
- s.allocCache = ^aCache
-}
-
-// nextFreeIndex returns the index of the next free object in s at
-// or after s.freeindex.
-// There are hardware instructions that can be used to make this
-// faster if profiling warrants it.
-func (s *mspan) nextFreeIndex() uintptr {
- sfreeindex := s.freeindex
- snelems := s.nelems
- if sfreeindex == snelems {
- return sfreeindex
- }
- if sfreeindex > snelems {
- throw("s.freeindex > s.nelems")
- }
-
- aCache := s.allocCache
-
- bitIndex := sys.TrailingZeros64(aCache)
- for bitIndex == 64 {
- // Move index to start of next cached bits.
- sfreeindex = (sfreeindex + 64) &^ (64 - 1)
- if sfreeindex >= snelems {
- s.freeindex = snelems
- return snelems
- }
- whichByte := sfreeindex / 8
- // Refill s.allocCache with the next 64 alloc bits.
- s.refillAllocCache(whichByte)
- aCache = s.allocCache
- bitIndex = sys.TrailingZeros64(aCache)
- // nothing available in cached bits
- // grab the next 8 bytes and try again.
- }
- result := sfreeindex + uintptr(bitIndex)
- if result >= snelems {
- s.freeindex = snelems
- return snelems
- }
-
- s.allocCache >>= uint(bitIndex + 1)
- sfreeindex = result + 1
-
- if sfreeindex%64 == 0 && sfreeindex != snelems {
- // We just incremented s.freeindex so it isn't 0.
- // As each 1 in s.allocCache was encountered and used for allocation
- // it was shifted away. At this point s.allocCache contains all 0s.
- // Refill s.allocCache so that it corresponds
- // to the bits at s.allocBits starting at s.freeindex.
- whichByte := sfreeindex / 8
- s.refillAllocCache(whichByte)
- }
- s.freeindex = sfreeindex
- return result
-}
-
-// isFree reports whether the index'th object in s is unallocated.
-//
-// The caller must ensure s.state is mSpanInUse, and there must have
-// been no preemption points since ensuring this (which could allow a
-// GC transition, which would allow the state to change).
-func (s *mspan) isFree(index uintptr) bool {
- if index < s.freeIndexForScan {
- return false
- }
- bytep, mask := s.allocBits.bitp(index)
- return *bytep&mask == 0
-}
-
-// divideByElemSize returns n/s.elemsize.
-// n must be within [0, s.npages*_PageSize),
-// or may be exactly s.npages*_PageSize
-// if s.elemsize is from sizeclasses.go.
-func (s *mspan) divideByElemSize(n uintptr) uintptr {
- const doubleCheck = false
-
- // See explanation in mksizeclasses.go's computeDivMagic.
- q := uintptr((uint64(n) * uint64(s.divMul)) >> 32)
-
- if doubleCheck && q != n/s.elemsize {
- println(n, "/", s.elemsize, "should be", n/s.elemsize, "but got", q)
- throw("bad magic division")
- }
- return q
-}
-
-func (s *mspan) objIndex(p uintptr) uintptr {
- return s.divideByElemSize(p - s.base())
-}
-
-func markBitsForAddr(p uintptr) markBits {
- s := spanOf(p)
- objIndex := s.objIndex(p)
- return s.markBitsForIndex(objIndex)
-}
-
-func (s *mspan) markBitsForIndex(objIndex uintptr) markBits {
- bytep, mask := s.gcmarkBits.bitp(objIndex)
- return markBits{bytep, mask, objIndex}
-}
-
-func (s *mspan) markBitsForBase() markBits {
- return markBits{&s.gcmarkBits.x, uint8(1), 0}
-}
-
-// isMarked reports whether mark bit m is set.
-func (m markBits) isMarked() bool {
- return *m.bytep&m.mask != 0
-}
-
-// setMarked sets the marked bit in the markbits, atomically.
-func (m markBits) setMarked() {
- // Might be racing with other updates, so use atomic update always.
- // We used to be clever here and use a non-atomic update in certain
- // cases, but it's not worth the risk.
- atomic.Or8(m.bytep, m.mask)
-}
-
-// setMarkedNonAtomic sets the marked bit in the markbits, non-atomically.
-func (m markBits) setMarkedNonAtomic() {
- *m.bytep |= m.mask
-}
-
-// clearMarked clears the marked bit in the markbits, atomically.
-func (m markBits) clearMarked() {
- // Might be racing with other updates, so use atomic update always.
- // We used to be clever here and use a non-atomic update in certain
- // cases, but it's not worth the risk.
- atomic.And8(m.bytep, ^m.mask)
-}
-
-// markBitsForSpan returns the markBits for the span base address base.
-func markBitsForSpan(base uintptr) (mbits markBits) {
- mbits = markBitsForAddr(base)
- if mbits.mask != 1 {
- throw("markBitsForSpan: unaligned start")
- }
- return mbits
-}
-
-// advance advances the markBits to the next object in the span.
-func (m *markBits) advance() {
- if m.mask == 1<<7 {
- m.bytep = (*uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(m.bytep)) + 1))
- m.mask = 1
- } else {
- m.mask = m.mask << 1
- }
- m.index++
-}
-
-// clobberdeadPtr is a special value that is used by the compiler to
-// clobber dead stack slots, when -clobberdead flag is set.
-const clobberdeadPtr = uintptr(0xdeaddead | 0xdeaddead<<((^uintptr(0)>>63)*32))
-
-// badPointer throws bad pointer in heap panic.
-func badPointer(s *mspan, p, refBase, refOff uintptr) {
- // Typically this indicates an incorrect use
- // of unsafe or cgo to store a bad pointer in
- // the Go heap. It may also indicate a runtime
- // bug.
- //
- // TODO(austin): We could be more aggressive
- // and detect pointers to unallocated objects
- // in allocated spans.
- printlock()
- print("runtime: pointer ", hex(p))
- if s != nil {
- state := s.state.get()
- if state != mSpanInUse {
- print(" to unallocated span")
- } else {
- print(" to unused region of span")
- }
- print(" span.base()=", hex(s.base()), " span.limit=", hex(s.limit), " span.state=", state)
- }
- print("\n")
- if refBase != 0 {
- print("runtime: found in object at *(", hex(refBase), "+", hex(refOff), ")\n")
- gcDumpObject("object", refBase, refOff)
- }
- getg().m.traceback = 2
- throw("found bad pointer in Go heap (incorrect use of unsafe or cgo?)")
-}
-
-// findObject returns the base address for the heap object containing
-// the address p, the object's span, and the index of the object in s.
-// If p does not point into a heap object, it returns base == 0.
-//
-// If p points is an invalid heap pointer and debug.invalidptr != 0,
-// findObject panics.
-//
-// refBase and refOff optionally give the base address of the object
-// in which the pointer p was found and the byte offset at which it
-// was found. These are used for error reporting.
-//
-// It is nosplit so it is safe for p to be a pointer to the current goroutine's stack.
-// Since p is a uintptr, it would not be adjusted if the stack were to move.
-//
-//go:nosplit
-func findObject(p, refBase, refOff uintptr) (base uintptr, s *mspan, objIndex uintptr) {
- s = spanOf(p)
- // If s is nil, the virtual address has never been part of the heap.
- // This pointer may be to some mmap'd region, so we allow it.
- if s == nil {
- if (GOARCH == "amd64" || GOARCH == "arm64") && p == clobberdeadPtr && debug.invalidptr != 0 {
- // Crash if clobberdeadPtr is seen. Only on AMD64 and ARM64 for now,
- // as they are the only platform where compiler's clobberdead mode is
- // implemented. On these platforms clobberdeadPtr cannot be a valid address.
- badPointer(s, p, refBase, refOff)
- }
- return
- }
- // If p is a bad pointer, it may not be in s's bounds.
- //
- // Check s.state to synchronize with span initialization
- // before checking other fields. See also spanOfHeap.
- if state := s.state.get(); state != mSpanInUse || p < s.base() || p >= s.limit {
- // Pointers into stacks are also ok, the runtime manages these explicitly.
- if state == mSpanManual {
- return
- }
- // The following ensures that we are rigorous about what data
- // structures hold valid pointers.
- if debug.invalidptr != 0 {
- badPointer(s, p, refBase, refOff)
- }
- return
- }
-
- objIndex = s.objIndex(p)
- base = s.base() + objIndex*s.elemsize
- return
-}
-
-// reflect_verifyNotInHeapPtr reports whether converting the not-in-heap pointer into a unsafe.Pointer is ok.
-//
-//go:linkname reflect_verifyNotInHeapPtr reflect.verifyNotInHeapPtr
-func reflect_verifyNotInHeapPtr(p uintptr) bool {
- // Conversion to a pointer is ok as long as findObject above does not call badPointer.
- // Since we're already promised that p doesn't point into the heap, just disallow heap
- // pointers and the special clobbered pointer.
- return spanOf(p) == nil && p != clobberdeadPtr
-}
-
-const ptrBits = 8 * goarch.PtrSize
-
-// heapBits provides access to the bitmap bits for a single heap word.
-// The methods on heapBits take value receivers so that the compiler
-// can more easily inline calls to those methods and registerize the
-// struct fields independently.
-type heapBits struct {
- // heapBits will report on pointers in the range [addr,addr+size).
- // The low bit of mask contains the pointerness of the word at addr
- // (assuming valid>0).
- addr, size uintptr
-
- // The next few pointer bits representing words starting at addr.
- // Those bits already returned by next() are zeroed.
- mask uintptr
- // Number of bits in mask that are valid. mask is always less than 1<<valid.
- valid uintptr
-}
-
-// heapBitsForAddr returns the heapBits for the address addr.
-// The caller must ensure [addr,addr+size) is in an allocated span.
-// In particular, be careful not to point past the end of an object.
-//
-// nosplit because it is used during write barriers and must not be preempted.
-//
-//go:nosplit
-func heapBitsForAddr(addr, size uintptr) heapBits {
- // Find arena
- ai := arenaIndex(addr)
- ha := mheap_.arenas[ai.l1()][ai.l2()]
-
- // Word index in arena.
- word := addr / goarch.PtrSize % heapArenaWords
-
- // Word index and bit offset in bitmap array.
- idx := word / ptrBits
- off := word % ptrBits
-
- // Grab relevant bits of bitmap.
- mask := ha.bitmap[idx] >> off
- valid := ptrBits - off
-
- // Process depending on where the object ends.
- nptr := size / goarch.PtrSize
- if nptr < valid {
- // Bits for this object end before the end of this bitmap word.
- // Squash bits for the following objects.
- mask &= 1<<(nptr&(ptrBits-1)) - 1
- valid = nptr
- } else if nptr == valid {
- // Bits for this object end at exactly the end of this bitmap word.
- // All good.
- } else {
- // Bits for this object extend into the next bitmap word. See if there
- // may be any pointers recorded there.
- if uintptr(ha.noMorePtrs[idx/8])>>(idx%8)&1 != 0 {
- // No more pointers in this object after this bitmap word.
- // Update size so we know not to look there.
- size = valid * goarch.PtrSize
- }
- }
-
- return heapBits{addr: addr, size: size, mask: mask, valid: valid}
-}
-
-// Returns the (absolute) address of the next known pointer and
-// a heapBits iterator representing any remaining pointers.
-// If there are no more pointers, returns address 0.
-// Note that next does not modify h. The caller must record the result.
-//
-// nosplit because it is used during write barriers and must not be preempted.
-//
-//go:nosplit
-func (h heapBits) next() (heapBits, uintptr) {
- for {
- if h.mask != 0 {
- var i int
- if goarch.PtrSize == 8 {
- i = sys.TrailingZeros64(uint64(h.mask))
- } else {
- i = sys.TrailingZeros32(uint32(h.mask))
- }
- h.mask ^= uintptr(1) << (i & (ptrBits - 1))
- return h, h.addr + uintptr(i)*goarch.PtrSize
- }
-
- // Skip words that we've already processed.
- h.addr += h.valid * goarch.PtrSize
- h.size -= h.valid * goarch.PtrSize
- if h.size == 0 {
- return h, 0 // no more pointers
- }
-
- // Grab more bits and try again.
- h = heapBitsForAddr(h.addr, h.size)
- }
-}
-
-// nextFast is like next, but can return 0 even when there are more pointers
-// to be found. Callers should call next if nextFast returns 0 as its second
-// return value.
-//
-// if addr, h = h.nextFast(); addr == 0 {
-// if addr, h = h.next(); addr == 0 {
-// ... no more pointers ...
-// }
-// }
-// ... process pointer at addr ...
-//
-// nextFast is designed to be inlineable.
-//
-//go:nosplit
-func (h heapBits) nextFast() (heapBits, uintptr) {
- // TESTQ/JEQ
- if h.mask == 0 {
- return h, 0
- }
- // BSFQ
- var i int
- if goarch.PtrSize == 8 {
- i = sys.TrailingZeros64(uint64(h.mask))
- } else {
- i = sys.TrailingZeros32(uint32(h.mask))
- }
- // BTCQ
- h.mask ^= uintptr(1) << (i & (ptrBits - 1))
- // LEAQ (XX)(XX*8)
- return h, h.addr + uintptr(i)*goarch.PtrSize
-}
-
-// bulkBarrierPreWrite executes a write barrier
-// for every pointer slot in the memory range [src, src+size),
-// using pointer/scalar information from [dst, dst+size).
-// This executes the write barriers necessary before a memmove.
-// src, dst, and size must be pointer-aligned.
-// The range [dst, dst+size) must lie within a single object.
-// It does not perform the actual writes.
-//
-// As a special case, src == 0 indicates that this is being used for a
-// memclr. bulkBarrierPreWrite will pass 0 for the src of each write
-// barrier.
-//
-// Callers should call bulkBarrierPreWrite immediately before
-// calling memmove(dst, src, size). This function is marked nosplit
-// to avoid being preempted; the GC must not stop the goroutine
-// between the memmove and the execution of the barriers.
-// The caller is also responsible for cgo pointer checks if this
-// may be writing Go pointers into non-Go memory.
-//
-// The pointer bitmap is not maintained for allocations containing
-// no pointers at all; any caller of bulkBarrierPreWrite must first
-// make sure the underlying allocation contains pointers, usually
-// by checking typ.ptrdata.
-//
-// Callers must perform cgo checks if writeBarrier.cgo.
-//
-//go:nosplit
-func bulkBarrierPreWrite(dst, src, size uintptr) {
- if (dst|src|size)&(goarch.PtrSize-1) != 0 {
- throw("bulkBarrierPreWrite: unaligned arguments")
- }
- if !writeBarrier.needed {
- return
- }
- if s := spanOf(dst); s == nil {
- // If dst is a global, use the data or BSS bitmaps to
- // execute write barriers.
- for _, datap := range activeModules() {
- if datap.data <= dst && dst < datap.edata {
- bulkBarrierBitmap(dst, src, size, dst-datap.data, datap.gcdatamask.bytedata)
- return
- }
- }
- for _, datap := range activeModules() {
- if datap.bss <= dst && dst < datap.ebss {
- bulkBarrierBitmap(dst, src, size, dst-datap.bss, datap.gcbssmask.bytedata)
- return
- }
- }
- return
- } else if s.state.get() != mSpanInUse || dst < s.base() || s.limit <= dst {
- // dst was heap memory at some point, but isn't now.
- // It can't be a global. It must be either our stack,
- // or in the case of direct channel sends, it could be
- // another stack. Either way, no need for barriers.
- // This will also catch if dst is in a freed span,
- // though that should never have.
- return
- }
-
- buf := &getg().m.p.ptr().wbBuf
- h := heapBitsForAddr(dst, size)
- if src == 0 {
- for {
- var addr uintptr
- if h, addr = h.next(); addr == 0 {
- break
- }
- dstx := (*uintptr)(unsafe.Pointer(addr))
- if !buf.putFast(*dstx, 0) {
- wbBufFlush(nil, 0)
- }
- }
- } else {
- for {
- var addr uintptr
- if h, addr = h.next(); addr == 0 {
- break
- }
- dstx := (*uintptr)(unsafe.Pointer(addr))
- srcx := (*uintptr)(unsafe.Pointer(src + (addr - dst)))
- if !buf.putFast(*dstx, *srcx) {
- wbBufFlush(nil, 0)
- }
- }
- }
-}
-
-// bulkBarrierPreWriteSrcOnly is like bulkBarrierPreWrite but
-// does not execute write barriers for [dst, dst+size).
-//
-// In addition to the requirements of bulkBarrierPreWrite
-// callers need to ensure [dst, dst+size) is zeroed.
-//
-// This is used for special cases where e.g. dst was just
-// created and zeroed with malloc.
-//
-//go:nosplit
-func bulkBarrierPreWriteSrcOnly(dst, src, size uintptr) {
- if (dst|src|size)&(goarch.PtrSize-1) != 0 {
- throw("bulkBarrierPreWrite: unaligned arguments")
- }
- if !writeBarrier.needed {
- return
- }
- buf := &getg().m.p.ptr().wbBuf
- h := heapBitsForAddr(dst, size)
- for {
- var addr uintptr
- if h, addr = h.next(); addr == 0 {
- break
- }
- srcx := (*uintptr)(unsafe.Pointer(addr - dst + src))
- if !buf.putFast(0, *srcx) {
- wbBufFlush(nil, 0)
- }
- }
-}
-
-// bulkBarrierBitmap executes write barriers for copying from [src,
-// src+size) to [dst, dst+size) using a 1-bit pointer bitmap. src is
-// assumed to start maskOffset bytes into the data covered by the
-// bitmap in bits (which may not be a multiple of 8).
-//
-// This is used by bulkBarrierPreWrite for writes to data and BSS.
-//
-//go:nosplit
-func bulkBarrierBitmap(dst, src, size, maskOffset uintptr, bits *uint8) {
- word := maskOffset / goarch.PtrSize
- bits = addb(bits, word/8)
- mask := uint8(1) << (word % 8)
-
- buf := &getg().m.p.ptr().wbBuf
- for i := uintptr(0); i < size; i += goarch.PtrSize {
- if mask == 0 {
- bits = addb(bits, 1)
- if *bits == 0 {
- // Skip 8 words.
- i += 7 * goarch.PtrSize
- continue
- }
- mask = 1
- }
- if *bits&mask != 0 {
- dstx := (*uintptr)(unsafe.Pointer(dst + i))
- if src == 0 {
- if !buf.putFast(*dstx, 0) {
- wbBufFlush(nil, 0)
- }
- } else {
- srcx := (*uintptr)(unsafe.Pointer(src + i))
- if !buf.putFast(*dstx, *srcx) {
- wbBufFlush(nil, 0)
- }
- }
- }
- mask <<= 1
- }
-}
-
-// typeBitsBulkBarrier executes a write barrier for every
-// pointer that would be copied from [src, src+size) to [dst,
-// dst+size) by a memmove using the type bitmap to locate those
-// pointer slots.
-//
-// The type typ must correspond exactly to [src, src+size) and [dst, dst+size).
-// dst, src, and size must be pointer-aligned.
-// The type typ must have a plain bitmap, not a GC program.
-// The only use of this function is in channel sends, and the
-// 64 kB channel element limit takes care of this for us.
-//
-// Must not be preempted because it typically runs right before memmove,
-// and the GC must observe them as an atomic action.
-//
-// Callers must perform cgo checks if writeBarrier.cgo.
-//
-//go:nosplit
-func typeBitsBulkBarrier(typ *_type, dst, src, size uintptr) {
- if typ == nil {
- throw("runtime: typeBitsBulkBarrier without type")
- }
- if typ.size != size {
- println("runtime: typeBitsBulkBarrier with type ", typ.string(), " of size ", typ.size, " but memory size", size)
- throw("runtime: invalid typeBitsBulkBarrier")
- }
- if typ.kind&kindGCProg != 0 {
- println("runtime: typeBitsBulkBarrier with type ", typ.string(), " with GC prog")
- throw("runtime: invalid typeBitsBulkBarrier")
- }
- if !writeBarrier.needed {
- return
- }
- ptrmask := typ.gcdata
- buf := &getg().m.p.ptr().wbBuf
- var bits uint32
- for i := uintptr(0); i < typ.ptrdata; i += goarch.PtrSize {
- if i&(goarch.PtrSize*8-1) == 0 {
- bits = uint32(*ptrmask)
- ptrmask = addb(ptrmask, 1)
- } else {
- bits = bits >> 1
- }
- if bits&1 != 0 {
- dstx := (*uintptr)(unsafe.Pointer(dst + i))
- srcx := (*uintptr)(unsafe.Pointer(src + i))
- if !buf.putFast(*dstx, *srcx) {
- wbBufFlush(nil, 0)
- }
- }
- }
-}
-
-// initHeapBits initializes the heap bitmap for a span.
-// If this is a span of single pointer allocations, it initializes all
-// words to pointer. If force is true, clears all bits.
-func (s *mspan) initHeapBits(forceClear bool) {
- if forceClear || s.spanclass.noscan() {
- // Set all the pointer bits to zero. We do this once
- // when the span is allocated so we don't have to do it
- // for each object allocation.
- base := s.base()
- size := s.npages * pageSize
- h := writeHeapBitsForAddr(base)
- h.flush(base, size)
- return
- }
- isPtrs := goarch.PtrSize == 8 && s.elemsize == goarch.PtrSize
- if !isPtrs {
- return // nothing to do
- }
- h := writeHeapBitsForAddr(s.base())
- size := s.npages * pageSize
- nptrs := size / goarch.PtrSize
- for i := uintptr(0); i < nptrs; i += ptrBits {
- h = h.write(^uintptr(0), ptrBits)
- }
- h.flush(s.base(), size)
-}
-
-// countAlloc returns the number of objects allocated in span s by
-// scanning the allocation bitmap.
-func (s *mspan) countAlloc() int {
- count := 0
- bytes := divRoundUp(s.nelems, 8)
- // Iterate over each 8-byte chunk and count allocations
- // with an intrinsic. Note that newMarkBits guarantees that
- // gcmarkBits will be 8-byte aligned, so we don't have to
- // worry about edge cases, irrelevant bits will simply be zero.
- for i := uintptr(0); i < bytes; i += 8 {
- // Extract 64 bits from the byte pointer and get a OnesCount.
- // Note that the unsafe cast here doesn't preserve endianness,
- // but that's OK. We only care about how many bits are 1, not
- // about the order we discover them in.
- mrkBits := *(*uint64)(unsafe.Pointer(s.gcmarkBits.bytep(i)))
- count += sys.OnesCount64(mrkBits)
- }
- return count
-}
-
-type writeHeapBits struct {
- addr uintptr // address that the low bit of mask represents the pointer state of.
- mask uintptr // some pointer bits starting at the address addr.
- valid uintptr // number of bits in buf that are valid (including low)
- low uintptr // number of low-order bits to not overwrite
-}
-
-func writeHeapBitsForAddr(addr uintptr) (h writeHeapBits) {
- // We start writing bits maybe in the middle of a heap bitmap word.
- // Remember how many bits into the word we started, so we can be sure
- // not to overwrite the previous bits.
- h.low = addr / goarch.PtrSize % ptrBits
-
- // round down to heap word that starts the bitmap word.
- h.addr = addr - h.low*goarch.PtrSize
-
- // We don't have any bits yet.
- h.mask = 0
- h.valid = h.low
-
- return
-}
-
-// write appends the pointerness of the next valid pointer slots
-// using the low valid bits of bits. 1=pointer, 0=scalar.
-func (h writeHeapBits) write(bits, valid uintptr) writeHeapBits {
- if h.valid+valid <= ptrBits {
- // Fast path - just accumulate the bits.
- h.mask |= bits << h.valid
- h.valid += valid
- return h
- }
- // Too many bits to fit in this word. Write the current word
- // out and move on to the next word.
-
- data := h.mask | bits<<h.valid // mask for this word
- h.mask = bits >> (ptrBits - h.valid) // leftover for next word
- h.valid += valid - ptrBits // have h.valid+valid bits, writing ptrBits of them
-
- // Flush mask to the memory bitmap.
- // TODO: figure out how to cache arena lookup.
- ai := arenaIndex(h.addr)
- ha := mheap_.arenas[ai.l1()][ai.l2()]
- idx := h.addr / (ptrBits * goarch.PtrSize) % heapArenaBitmapWords
- m := uintptr(1)<<h.low - 1
- ha.bitmap[idx] = ha.bitmap[idx]&m | data
- // Note: no synchronization required for this write because
- // the allocator has exclusive access to the page, and the bitmap
- // entries are all for a single page. Also, visibility of these
- // writes is guaranteed by the publication barrier in mallocgc.
-
- // Clear noMorePtrs bit, since we're going to be writing bits
- // into the following word.
- ha.noMorePtrs[idx/8] &^= uint8(1) << (idx % 8)
- // Note: same as above
-
- // Move to next word of bitmap.
- h.addr += ptrBits * goarch.PtrSize
- h.low = 0
- return h
-}
-
-// Add padding of size bytes.
-func (h writeHeapBits) pad(size uintptr) writeHeapBits {
- if size == 0 {
- return h
- }
- words := size / goarch.PtrSize
- for words > ptrBits {
- h = h.write(0, ptrBits)
- words -= ptrBits
- }
- return h.write(0, words)
-}
-
-// Flush the bits that have been written, and add zeros as needed
-// to cover the full object [addr, addr+size).
-func (h writeHeapBits) flush(addr, size uintptr) {
- // zeros counts the number of bits needed to represent the object minus the
- // number of bits we've already written. This is the number of 0 bits
- // that need to be added.
- zeros := (addr+size-h.addr)/goarch.PtrSize - h.valid
-
- // Add zero bits up to the bitmap word boundary
- if zeros > 0 {
- z := ptrBits - h.valid
- if z > zeros {
- z = zeros
- }
- h.valid += z
- zeros -= z
- }
-
- // Find word in bitmap that we're going to write.
- ai := arenaIndex(h.addr)
- ha := mheap_.arenas[ai.l1()][ai.l2()]
- idx := h.addr / (ptrBits * goarch.PtrSize) % heapArenaBitmapWords
-
- // Write remaining bits.
- if h.valid != h.low {
- m := uintptr(1)<<h.low - 1 // don't clear existing bits below "low"
- m |= ^(uintptr(1)<<h.valid - 1) // don't clear existing bits above "valid"
- ha.bitmap[idx] = ha.bitmap[idx]&m | h.mask
- }
- if zeros == 0 {
- return
- }
-
- // Record in the noMorePtrs map that there won't be any more 1 bits,
- // so readers can stop early.
- ha.noMorePtrs[idx/8] |= uint8(1) << (idx % 8)
-
- // Advance to next bitmap word.
- h.addr += ptrBits * goarch.PtrSize
-
- // Continue on writing zeros for the rest of the object.
- // For standard use of the ptr bits this is not required, as
- // the bits are read from the beginning of the object. Some uses,
- // like noscan spans, oblets, bulk write barriers, and cgocheck, might
- // start mid-object, so these writes are still required.
- for {
- // Write zero bits.
- ai := arenaIndex(h.addr)
- ha := mheap_.arenas[ai.l1()][ai.l2()]
- idx := h.addr / (ptrBits * goarch.PtrSize) % heapArenaBitmapWords
- if zeros < ptrBits {
- ha.bitmap[idx] &^= uintptr(1)<<zeros - 1
- break
- } else if zeros == ptrBits {
- ha.bitmap[idx] = 0
- break
- } else {
- ha.bitmap[idx] = 0
- zeros -= ptrBits
- }
- ha.noMorePtrs[idx/8] |= uint8(1) << (idx % 8)
- h.addr += ptrBits * goarch.PtrSize
- }
-}
-
-// Read the bytes starting at the aligned pointer p into a uintptr.
-// Read is little-endian.
-func readUintptr(p *byte) uintptr {
- x := *(*uintptr)(unsafe.Pointer(p))
- if goarch.BigEndian {
- if goarch.PtrSize == 8 {
- return uintptr(sys.Bswap64(uint64(x)))
- }
- return uintptr(sys.Bswap32(uint32(x)))
- }
- return x
-}
-
-// heapBitsSetType records that the new allocation [x, x+size)
-// holds in [x, x+dataSize) one or more values of type typ.
-// (The number of values is given by dataSize / typ.size.)
-// If dataSize < size, the fragment [x+dataSize, x+size) is
-// recorded as non-pointer data.
-// It is known that the type has pointers somewhere;
-// malloc does not call heapBitsSetType when there are no pointers,
-// because all free objects are marked as noscan during
-// heapBitsSweepSpan.
-//
-// There can only be one allocation from a given span active at a time,
-// and the bitmap for a span always falls on word boundaries,
-// so there are no write-write races for access to the heap bitmap.
-// Hence, heapBitsSetType can access the bitmap without atomics.
-//
-// There can be read-write races between heapBitsSetType and things
-// that read the heap bitmap like scanobject. However, since
-// heapBitsSetType is only used for objects that have not yet been
-// made reachable, readers will ignore bits being modified by this
-// function. This does mean this function cannot transiently modify
-// bits that belong to neighboring objects. Also, on weakly-ordered
-// machines, callers must execute a store/store (publication) barrier
-// between calling this function and making the object reachable.
-func heapBitsSetType(x, size, dataSize uintptr, typ *_type) {
- const doubleCheck = false // slow but helpful; enable to test modifications to this code
-
- if doubleCheck && dataSize%typ.size != 0 {
- throw("heapBitsSetType: dataSize not a multiple of typ.size")
- }
-
- if goarch.PtrSize == 8 && size == goarch.PtrSize {
- // It's one word and it has pointers, it must be a pointer.
- // Since all allocated one-word objects are pointers
- // (non-pointers are aggregated into tinySize allocations),
- // (*mspan).initHeapBits sets the pointer bits for us.
- // Nothing to do here.
- if doubleCheck {
- h, addr := heapBitsForAddr(x, size).next()
- if addr != x {
- throw("heapBitsSetType: pointer bit missing")
- }
- _, addr = h.next()
- if addr != 0 {
- throw("heapBitsSetType: second pointer bit found")
- }
- }
- return
- }
-
- h := writeHeapBitsForAddr(x)
-
- // Handle GC program.
- if typ.kind&kindGCProg != 0 {
- // Expand the gc program into the storage we're going to use for the actual object.
- obj := (*uint8)(unsafe.Pointer(x))
- n := runGCProg(addb(typ.gcdata, 4), obj)
- // Use the expanded program to set the heap bits.
- for i := uintptr(0); true; i += typ.size {
- // Copy expanded program to heap bitmap.
- p := obj
- j := n
- for j > 8 {
- h = h.write(uintptr(*p), 8)
- p = add1(p)
- j -= 8
- }
- h = h.write(uintptr(*p), j)
-
- if i+typ.size == dataSize {
- break // no padding after last element
- }
-
- // Pad with zeros to the start of the next element.
- h = h.pad(typ.size - n*goarch.PtrSize)
- }
-
- h.flush(x, size)
-
- // Erase the expanded GC program.
- memclrNoHeapPointers(unsafe.Pointer(obj), (n+7)/8)
- return
- }
-
- // Note about sizes:
- //
- // typ.size is the number of words in the object,
- // and typ.ptrdata is the number of words in the prefix
- // of the object that contains pointers. That is, the final
- // typ.size - typ.ptrdata words contain no pointers.
- // This allows optimization of a common pattern where
- // an object has a small header followed by a large scalar
- // buffer. If we know the pointers are over, we don't have
- // to scan the buffer's heap bitmap at all.
- // The 1-bit ptrmasks are sized to contain only bits for
- // the typ.ptrdata prefix, zero padded out to a full byte
- // of bitmap. If there is more room in the allocated object,
- // that space is pointerless. The noMorePtrs bitmap will prevent
- // scanning large pointerless tails of an object.
- //
- // Replicated copies are not as nice: if there is an array of
- // objects with scalar tails, all but the last tail does have to
- // be initialized, because there is no way to say "skip forward".
-
- ptrs := typ.ptrdata / goarch.PtrSize
- if typ.size == dataSize { // Single element
- if ptrs <= ptrBits { // Single small element
- m := readUintptr(typ.gcdata)
- h = h.write(m, ptrs)
- } else { // Single large element
- p := typ.gcdata
- for {
- h = h.write(readUintptr(p), ptrBits)
- p = addb(p, ptrBits/8)
- ptrs -= ptrBits
- if ptrs <= ptrBits {
- break
- }
- }
- m := readUintptr(p)
- h = h.write(m, ptrs)
- }
- } else { // Repeated element
- words := typ.size / goarch.PtrSize // total words, including scalar tail
- if words <= ptrBits { // Repeated small element
- n := dataSize / typ.size
- m := readUintptr(typ.gcdata)
- // Make larger unit to repeat
- for words <= ptrBits/2 {
- if n&1 != 0 {
- h = h.write(m, words)
- }
- n /= 2
- m |= m << words
- ptrs += words
- words *= 2
- if n == 1 {
- break
- }
- }
- for n > 1 {
- h = h.write(m, words)
- n--
- }
- h = h.write(m, ptrs)
- } else { // Repeated large element
- for i := uintptr(0); true; i += typ.size {
- p := typ.gcdata
- j := ptrs
- for j > ptrBits {
- h = h.write(readUintptr(p), ptrBits)
- p = addb(p, ptrBits/8)
- j -= ptrBits
- }
- m := readUintptr(p)
- h = h.write(m, j)
- if i+typ.size == dataSize {
- break // don't need the trailing nonptr bits on the last element.
- }
- // Pad with zeros to the start of the next element.
- h = h.pad(typ.size - typ.ptrdata)
- }
- }
- }
- h.flush(x, size)
-
- if doubleCheck {
- h := heapBitsForAddr(x, size)
- for i := uintptr(0); i < size; i += goarch.PtrSize {
- // Compute the pointer bit we want at offset i.
- want := false
- if i < dataSize {
- off := i % typ.size
- if off < typ.ptrdata {
- j := off / goarch.PtrSize
- want = *addb(typ.gcdata, j/8)>>(j%8)&1 != 0
- }
- }
- if want {
- var addr uintptr
- h, addr = h.next()
- if addr != x+i {
- throw("heapBitsSetType: pointer entry not correct")
- }
- }
- }
- if _, addr := h.next(); addr != 0 {
- throw("heapBitsSetType: extra pointer")
- }
- }
-}
-
-var debugPtrmask struct {
- lock mutex
- data *byte
-}
-
-// progToPointerMask returns the 1-bit pointer mask output by the GC program prog.
-// size the size of the region described by prog, in bytes.
-// The resulting bitvector will have no more than size/goarch.PtrSize bits.
-func progToPointerMask(prog *byte, size uintptr) bitvector {
- n := (size/goarch.PtrSize + 7) / 8
- x := (*[1 << 30]byte)(persistentalloc(n+1, 1, &memstats.buckhash_sys))[:n+1]
- x[len(x)-1] = 0xa1 // overflow check sentinel
- n = runGCProg(prog, &x[0])
- if x[len(x)-1] != 0xa1 {
- throw("progToPointerMask: overflow")
- }
- return bitvector{int32(n), &x[0]}
-}
-
-// Packed GC pointer bitmaps, aka GC programs.
-//
-// For large types containing arrays, the type information has a
-// natural repetition that can be encoded to save space in the
-// binary and in the memory representation of the type information.
-//
-// The encoding is a simple Lempel-Ziv style bytecode machine
-// with the following instructions:
-//
-// 00000000: stop
-// 0nnnnnnn: emit n bits copied from the next (n+7)/8 bytes
-// 10000000 n c: repeat the previous n bits c times; n, c are varints
-// 1nnnnnnn c: repeat the previous n bits c times; c is a varint
-
-// runGCProg returns the number of 1-bit entries written to memory.
-func runGCProg(prog, dst *byte) uintptr {
- dstStart := dst
-
- // Bits waiting to be written to memory.
- var bits uintptr
- var nbits uintptr
-
- p := prog
-Run:
- for {
- // Flush accumulated full bytes.
- // The rest of the loop assumes that nbits <= 7.
- for ; nbits >= 8; nbits -= 8 {
- *dst = uint8(bits)
- dst = add1(dst)
- bits >>= 8
- }
-
- // Process one instruction.
- inst := uintptr(*p)
- p = add1(p)
- n := inst & 0x7F
- if inst&0x80 == 0 {
- // Literal bits; n == 0 means end of program.
- if n == 0 {
- // Program is over.
- break Run
- }
- nbyte := n / 8
- for i := uintptr(0); i < nbyte; i++ {
- bits |= uintptr(*p) << nbits
- p = add1(p)
- *dst = uint8(bits)
- dst = add1(dst)
- bits >>= 8
- }
- if n %= 8; n > 0 {
- bits |= uintptr(*p) << nbits
- p = add1(p)
- nbits += n
- }
- continue Run
- }
-
- // Repeat. If n == 0, it is encoded in a varint in the next bytes.
- if n == 0 {
- for off := uint(0); ; off += 7 {
- x := uintptr(*p)
- p = add1(p)
- n |= (x & 0x7F) << off
- if x&0x80 == 0 {
- break
- }
- }
- }
-
- // Count is encoded in a varint in the next bytes.
- c := uintptr(0)
- for off := uint(0); ; off += 7 {
- x := uintptr(*p)
- p = add1(p)
- c |= (x & 0x7F) << off
- if x&0x80 == 0 {
- break
- }
- }
- c *= n // now total number of bits to copy
-
- // If the number of bits being repeated is small, load them
- // into a register and use that register for the entire loop
- // instead of repeatedly reading from memory.
- // Handling fewer than 8 bits here makes the general loop simpler.
- // The cutoff is goarch.PtrSize*8 - 7 to guarantee that when we add
- // the pattern to a bit buffer holding at most 7 bits (a partial byte)
- // it will not overflow.
- src := dst
- const maxBits = goarch.PtrSize*8 - 7
- if n <= maxBits {
- // Start with bits in output buffer.
- pattern := bits
- npattern := nbits
-
- // If we need more bits, fetch them from memory.
- src = subtract1(src)
- for npattern < n {
- pattern <<= 8
- pattern |= uintptr(*src)
- src = subtract1(src)
- npattern += 8
- }
-
- // We started with the whole bit output buffer,
- // and then we loaded bits from whole bytes.
- // Either way, we might now have too many instead of too few.
- // Discard the extra.
- if npattern > n {
- pattern >>= npattern - n
- npattern = n
- }
-
- // Replicate pattern to at most maxBits.
- if npattern == 1 {
- // One bit being repeated.
- // If the bit is 1, make the pattern all 1s.
- // If the bit is 0, the pattern is already all 0s,
- // but we can claim that the number of bits
- // in the word is equal to the number we need (c),
- // because right shift of bits will zero fill.
- if pattern == 1 {
- pattern = 1<<maxBits - 1
- npattern = maxBits
- } else {
- npattern = c
- }
- } else {
- b := pattern
- nb := npattern
- if nb+nb <= maxBits {
- // Double pattern until the whole uintptr is filled.
- for nb <= goarch.PtrSize*8 {
- b |= b << nb
- nb += nb
- }
- // Trim away incomplete copy of original pattern in high bits.
- // TODO(rsc): Replace with table lookup or loop on systems without divide?
- nb = maxBits / npattern * npattern
- b &= 1<<nb - 1
- pattern = b
- npattern = nb
- }
- }
-
- // Add pattern to bit buffer and flush bit buffer, c/npattern times.
- // Since pattern contains >8 bits, there will be full bytes to flush
- // on each iteration.
- for ; c >= npattern; c -= npattern {
- bits |= pattern << nbits
- nbits += npattern
- for nbits >= 8 {
- *dst = uint8(bits)
- dst = add1(dst)
- bits >>= 8
- nbits -= 8
- }
- }
-
- // Add final fragment to bit buffer.
- if c > 0 {
- pattern &= 1<<c - 1
- bits |= pattern << nbits
- nbits += c
- }
- continue Run
- }
-
- // Repeat; n too large to fit in a register.
- // Since nbits <= 7, we know the first few bytes of repeated data
- // are already written to memory.
- off := n - nbits // n > nbits because n > maxBits and nbits <= 7
- // Leading src fragment.
- src = subtractb(src, (off+7)/8)
- if frag := off & 7; frag != 0 {
- bits |= uintptr(*src) >> (8 - frag) << nbits
- src = add1(src)
- nbits += frag
- c -= frag
- }
- // Main loop: load one byte, write another.
- // The bits are rotating through the bit buffer.
- for i := c / 8; i > 0; i-- {
- bits |= uintptr(*src) << nbits
- src = add1(src)
- *dst = uint8(bits)
- dst = add1(dst)
- bits >>= 8
- }
- // Final src fragment.
- if c %= 8; c > 0 {
- bits |= (uintptr(*src) & (1<<c - 1)) << nbits
- nbits += c
- }
- }
-
- // Write any final bits out, using full-byte writes, even for the final byte.
- totalBits := (uintptr(unsafe.Pointer(dst))-uintptr(unsafe.Pointer(dstStart)))*8 + nbits
- nbits += -nbits & 7
- for ; nbits > 0; nbits -= 8 {
- *dst = uint8(bits)
- dst = add1(dst)
- bits >>= 8
- }
- return totalBits
-}
-
-// materializeGCProg allocates space for the (1-bit) pointer bitmask
-// for an object of size ptrdata. Then it fills that space with the
-// pointer bitmask specified by the program prog.
-// The bitmask starts at s.startAddr.
-// The result must be deallocated with dematerializeGCProg.
-func materializeGCProg(ptrdata uintptr, prog *byte) *mspan {
- // Each word of ptrdata needs one bit in the bitmap.
- bitmapBytes := divRoundUp(ptrdata, 8*goarch.PtrSize)
- // Compute the number of pages needed for bitmapBytes.
- pages := divRoundUp(bitmapBytes, pageSize)
- s := mheap_.allocManual(pages, spanAllocPtrScalarBits)
- runGCProg(addb(prog, 4), (*byte)(unsafe.Pointer(s.startAddr)))
- return s
-}
-func dematerializeGCProg(s *mspan) {
- mheap_.freeManual(s, spanAllocPtrScalarBits)
-}
-
-func dumpGCProg(p *byte) {
- nptr := 0
- for {
- x := *p
- p = add1(p)
- if x == 0 {
- print("\t", nptr, " end\n")
- break
- }
- if x&0x80 == 0 {
- print("\t", nptr, " lit ", x, ":")
- n := int(x+7) / 8
- for i := 0; i < n; i++ {
- print(" ", hex(*p))
- p = add1(p)
- }
- print("\n")
- nptr += int(x)
- } else {
- nbit := int(x &^ 0x80)
- if nbit == 0 {
- for nb := uint(0); ; nb += 7 {
- x := *p
- p = add1(p)
- nbit |= int(x&0x7f) << nb
- if x&0x80 == 0 {
- break
- }
- }
- }
- count := 0
- for nb := uint(0); ; nb += 7 {
- x := *p
- p = add1(p)
- count |= int(x&0x7f) << nb
- if x&0x80 == 0 {
- break
- }
- }
- print("\t", nptr, " repeat ", nbit, " × ", count, "\n")
- nptr += nbit * count
- }
- }
-}
-
-// Testing.
-
-func getgcmaskcb(frame *stkframe, ctxt unsafe.Pointer) bool {
- target := (*stkframe)(ctxt)
- if frame.sp <= target.sp && target.sp < frame.varp {
- *target = *frame
- return false
- }
- return true
-}
-
-// reflect_gcbits returns the GC type info for x, for testing.
-// The result is the bitmap entries (0 or 1), one entry per byte.
-//
-//go:linkname reflect_gcbits reflect.gcbits
-func reflect_gcbits(x any) []byte {
- return getgcmask(x)
-}
-
-// Returns GC type info for the pointer stored in ep for testing.
-// If ep points to the stack, only static live information will be returned
-// (i.e. not for objects which are only dynamically live stack objects).
-func getgcmask(ep any) (mask []byte) {
- e := *efaceOf(&ep)
- p := e.data
- t := e._type
- // data or bss
- for _, datap := range activeModules() {
- // data
- if datap.data <= uintptr(p) && uintptr(p) < datap.edata {
- bitmap := datap.gcdatamask.bytedata
- n := (*ptrtype)(unsafe.Pointer(t)).elem.size
- mask = make([]byte, n/goarch.PtrSize)
- for i := uintptr(0); i < n; i += goarch.PtrSize {
- off := (uintptr(p) + i - datap.data) / goarch.PtrSize
- mask[i/goarch.PtrSize] = (*addb(bitmap, off/8) >> (off % 8)) & 1
- }
- return
- }
-
- // bss
- if datap.bss <= uintptr(p) && uintptr(p) < datap.ebss {
- bitmap := datap.gcbssmask.bytedata
- n := (*ptrtype)(unsafe.Pointer(t)).elem.size
- mask = make([]byte, n/goarch.PtrSize)
- for i := uintptr(0); i < n; i += goarch.PtrSize {
- off := (uintptr(p) + i - datap.bss) / goarch.PtrSize
- mask[i/goarch.PtrSize] = (*addb(bitmap, off/8) >> (off % 8)) & 1
- }
- return
- }
- }
-
- // heap
- if base, s, _ := findObject(uintptr(p), 0, 0); base != 0 {
- if s.spanclass.noscan() {
- return nil
- }
- n := s.elemsize
- hbits := heapBitsForAddr(base, n)
- mask = make([]byte, n/goarch.PtrSize)
- for {
- var addr uintptr
- if hbits, addr = hbits.next(); addr == 0 {
- break
- }
- mask[(addr-base)/goarch.PtrSize] = 1
- }
- // Callers expect this mask to end at the last pointer.
- for len(mask) > 0 && mask[len(mask)-1] == 0 {
- mask = mask[:len(mask)-1]
- }
- return
- }
-
- // stack
- if gp := getg(); gp.m.curg.stack.lo <= uintptr(p) && uintptr(p) < gp.m.curg.stack.hi {
- var frame stkframe
- frame.sp = uintptr(p)
- gentraceback(gp.m.curg.sched.pc, gp.m.curg.sched.sp, 0, gp.m.curg, 0, nil, 1000, getgcmaskcb, noescape(unsafe.Pointer(&frame)), 0)
- if frame.fn.valid() {
- locals, _, _ := frame.getStackMap(nil, false)
- if locals.n == 0 {
- return
- }
- size := uintptr(locals.n) * goarch.PtrSize
- n := (*ptrtype)(unsafe.Pointer(t)).elem.size
- mask = make([]byte, n/goarch.PtrSize)
- for i := uintptr(0); i < n; i += goarch.PtrSize {
- off := (uintptr(p) + i - frame.varp + size) / goarch.PtrSize
- mask[i/goarch.PtrSize] = locals.ptrbit(off)
- }
- }
- return
- }
-
- // otherwise, not something the GC knows about.
- // possibly read-only data, like malloc(0).
- // must not have pointers
- return
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mcentral.go b/contrib/go/_std_1.20/src/runtime/mcentral.go
deleted file mode 100644
index 3382c54e7f..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mcentral.go
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright 2009 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.
-
-// Central free lists.
-//
-// See malloc.go for an overview.
-//
-// The mcentral doesn't actually contain the list of free objects; the mspan does.
-// Each mcentral is two lists of mspans: those with free objects (c->nonempty)
-// and those that are completely allocated (c->empty).
-
-package runtime
-
-import (
- "runtime/internal/atomic"
- "runtime/internal/sys"
-)
-
-// Central list of free objects of a given size.
-type mcentral struct {
- _ sys.NotInHeap
- spanclass spanClass
-
- // partial and full contain two mspan sets: one of swept in-use
- // spans, and one of unswept in-use spans. These two trade
- // roles on each GC cycle. The unswept set is drained either by
- // allocation or by the background sweeper in every GC cycle,
- // so only two roles are necessary.
- //
- // sweepgen is increased by 2 on each GC cycle, so the swept
- // spans are in partial[sweepgen/2%2] and the unswept spans are in
- // partial[1-sweepgen/2%2]. Sweeping pops spans from the
- // unswept set and pushes spans that are still in-use on the
- // swept set. Likewise, allocating an in-use span pushes it
- // on the swept set.
- //
- // Some parts of the sweeper can sweep arbitrary spans, and hence
- // can't remove them from the unswept set, but will add the span
- // to the appropriate swept list. As a result, the parts of the
- // sweeper and mcentral that do consume from the unswept list may
- // encounter swept spans, and these should be ignored.
- partial [2]spanSet // list of spans with a free object
- full [2]spanSet // list of spans with no free objects
-}
-
-// Initialize a single central free list.
-func (c *mcentral) init(spc spanClass) {
- c.spanclass = spc
- lockInit(&c.partial[0].spineLock, lockRankSpanSetSpine)
- lockInit(&c.partial[1].spineLock, lockRankSpanSetSpine)
- lockInit(&c.full[0].spineLock, lockRankSpanSetSpine)
- lockInit(&c.full[1].spineLock, lockRankSpanSetSpine)
-}
-
-// partialUnswept returns the spanSet which holds partially-filled
-// unswept spans for this sweepgen.
-func (c *mcentral) partialUnswept(sweepgen uint32) *spanSet {
- return &c.partial[1-sweepgen/2%2]
-}
-
-// partialSwept returns the spanSet which holds partially-filled
-// swept spans for this sweepgen.
-func (c *mcentral) partialSwept(sweepgen uint32) *spanSet {
- return &c.partial[sweepgen/2%2]
-}
-
-// fullUnswept returns the spanSet which holds unswept spans without any
-// free slots for this sweepgen.
-func (c *mcentral) fullUnswept(sweepgen uint32) *spanSet {
- return &c.full[1-sweepgen/2%2]
-}
-
-// fullSwept returns the spanSet which holds swept spans without any
-// free slots for this sweepgen.
-func (c *mcentral) fullSwept(sweepgen uint32) *spanSet {
- return &c.full[sweepgen/2%2]
-}
-
-// Allocate a span to use in an mcache.
-func (c *mcentral) cacheSpan() *mspan {
- // Deduct credit for this span allocation and sweep if necessary.
- spanBytes := uintptr(class_to_allocnpages[c.spanclass.sizeclass()]) * _PageSize
- deductSweepCredit(spanBytes, 0)
-
- traceDone := false
- if trace.enabled {
- traceGCSweepStart()
- }
-
- // If we sweep spanBudget spans without finding any free
- // space, just allocate a fresh span. This limits the amount
- // of time we can spend trying to find free space and
- // amortizes the cost of small object sweeping over the
- // benefit of having a full free span to allocate from. By
- // setting this to 100, we limit the space overhead to 1%.
- //
- // TODO(austin,mknyszek): This still has bad worst-case
- // throughput. For example, this could find just one free slot
- // on the 100th swept span. That limits allocation latency, but
- // still has very poor throughput. We could instead keep a
- // running free-to-used budget and switch to fresh span
- // allocation if the budget runs low.
- spanBudget := 100
-
- var s *mspan
- var sl sweepLocker
-
- // Try partial swept spans first.
- sg := mheap_.sweepgen
- if s = c.partialSwept(sg).pop(); s != nil {
- goto havespan
- }
-
- sl = sweep.active.begin()
- if sl.valid {
- // Now try partial unswept spans.
- for ; spanBudget >= 0; spanBudget-- {
- s = c.partialUnswept(sg).pop()
- if s == nil {
- break
- }
- if s, ok := sl.tryAcquire(s); ok {
- // We got ownership of the span, so let's sweep it and use it.
- s.sweep(true)
- sweep.active.end(sl)
- goto havespan
- }
- // We failed to get ownership of the span, which means it's being or
- // has been swept by an asynchronous sweeper that just couldn't remove it
- // from the unswept list. That sweeper took ownership of the span and
- // responsibility for either freeing it to the heap or putting it on the
- // right swept list. Either way, we should just ignore it (and it's unsafe
- // for us to do anything else).
- }
- // Now try full unswept spans, sweeping them and putting them into the
- // right list if we fail to get a span.
- for ; spanBudget >= 0; spanBudget-- {
- s = c.fullUnswept(sg).pop()
- if s == nil {
- break
- }
- if s, ok := sl.tryAcquire(s); ok {
- // We got ownership of the span, so let's sweep it.
- s.sweep(true)
- // Check if there's any free space.
- freeIndex := s.nextFreeIndex()
- if freeIndex != s.nelems {
- s.freeindex = freeIndex
- sweep.active.end(sl)
- goto havespan
- }
- // Add it to the swept list, because sweeping didn't give us any free space.
- c.fullSwept(sg).push(s.mspan)
- }
- // See comment for partial unswept spans.
- }
- sweep.active.end(sl)
- }
- if trace.enabled {
- traceGCSweepDone()
- traceDone = true
- }
-
- // We failed to get a span from the mcentral so get one from mheap.
- s = c.grow()
- if s == nil {
- return nil
- }
-
- // At this point s is a span that should have free slots.
-havespan:
- if trace.enabled && !traceDone {
- traceGCSweepDone()
- }
- n := int(s.nelems) - int(s.allocCount)
- if n == 0 || s.freeindex == s.nelems || uintptr(s.allocCount) == s.nelems {
- throw("span has no free objects")
- }
- freeByteBase := s.freeindex &^ (64 - 1)
- whichByte := freeByteBase / 8
- // Init alloc bits cache.
- s.refillAllocCache(whichByte)
-
- // Adjust the allocCache so that s.freeindex corresponds to the low bit in
- // s.allocCache.
- s.allocCache >>= s.freeindex % 64
-
- return s
-}
-
-// Return span from an mcache.
-//
-// s must have a span class corresponding to this
-// mcentral and it must not be empty.
-func (c *mcentral) uncacheSpan(s *mspan) {
- if s.allocCount == 0 {
- throw("uncaching span but s.allocCount == 0")
- }
-
- sg := mheap_.sweepgen
- stale := s.sweepgen == sg+1
-
- // Fix up sweepgen.
- if stale {
- // Span was cached before sweep began. It's our
- // responsibility to sweep it.
- //
- // Set sweepgen to indicate it's not cached but needs
- // sweeping and can't be allocated from. sweep will
- // set s.sweepgen to indicate s is swept.
- atomic.Store(&s.sweepgen, sg-1)
- } else {
- // Indicate that s is no longer cached.
- atomic.Store(&s.sweepgen, sg)
- }
-
- // Put the span in the appropriate place.
- if stale {
- // It's stale, so just sweep it. Sweeping will put it on
- // the right list.
- //
- // We don't use a sweepLocker here. Stale cached spans
- // aren't in the global sweep lists, so mark termination
- // itself holds up sweep completion until all mcaches
- // have been swept.
- ss := sweepLocked{s}
- ss.sweep(false)
- } else {
- if int(s.nelems)-int(s.allocCount) > 0 {
- // Put it back on the partial swept list.
- c.partialSwept(sg).push(s)
- } else {
- // There's no free space and it's not stale, so put it on the
- // full swept list.
- c.fullSwept(sg).push(s)
- }
- }
-}
-
-// grow allocates a new empty span from the heap and initializes it for c's size class.
-func (c *mcentral) grow() *mspan {
- npages := uintptr(class_to_allocnpages[c.spanclass.sizeclass()])
- size := uintptr(class_to_size[c.spanclass.sizeclass()])
-
- s := mheap_.alloc(npages, c.spanclass)
- if s == nil {
- return nil
- }
-
- // Use division by multiplication and shifts to quickly compute:
- // n := (npages << _PageShift) / size
- n := s.divideByElemSize(npages << _PageShift)
- s.limit = s.base() + size*n
- s.initHeapBits(false)
- return s
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mem.go b/contrib/go/_std_1.20/src/runtime/mem.go
deleted file mode 100644
index 0ca933b25b..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mem.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2022 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 runtime
-
-import "unsafe"
-
-// OS memory management abstraction layer
-//
-// Regions of the address space managed by the runtime may be in one of four
-// states at any given time:
-// 1) None - Unreserved and unmapped, the default state of any region.
-// 2) Reserved - Owned by the runtime, but accessing it would cause a fault.
-// Does not count against the process' memory footprint.
-// 3) Prepared - Reserved, intended not to be backed by physical memory (though
-// an OS may implement this lazily). Can transition efficiently to
-// Ready. Accessing memory in such a region is undefined (may
-// fault, may give back unexpected zeroes, etc.).
-// 4) Ready - may be accessed safely.
-//
-// This set of states is more than is strictly necessary to support all the
-// currently supported platforms. One could get by with just None, Reserved, and
-// Ready. However, the Prepared state gives us flexibility for performance
-// purposes. For example, on POSIX-y operating systems, Reserved is usually a
-// private anonymous mmap'd region with PROT_NONE set, and to transition
-// to Ready would require setting PROT_READ|PROT_WRITE. However the
-// underspecification of Prepared lets us use just MADV_FREE to transition from
-// Ready to Prepared. Thus with the Prepared state we can set the permission
-// bits just once early on, we can efficiently tell the OS that it's free to
-// take pages away from us when we don't strictly need them.
-//
-// This file defines a cross-OS interface for a common set of helpers
-// that transition memory regions between these states. The helpers call into
-// OS-specific implementations that handle errors, while the interface boundary
-// implements cross-OS functionality, like updating runtime accounting.
-
-// sysAlloc transitions an OS-chosen region of memory from None to Ready.
-// More specifically, it obtains a large chunk of zeroed memory from the
-// operating system, typically on the order of a hundred kilobytes
-// or a megabyte. This memory is always immediately available for use.
-//
-// sysStat must be non-nil.
-//
-// Don't split the stack as this function may be invoked without a valid G,
-// which prevents us from allocating more stack.
-//
-//go:nosplit
-func sysAlloc(n uintptr, sysStat *sysMemStat) unsafe.Pointer {
- sysStat.add(int64(n))
- gcController.mappedReady.Add(int64(n))
- return sysAllocOS(n)
-}
-
-// sysUnused transitions a memory region from Ready to Prepared. It notifies the
-// operating system that the physical pages backing this memory region are no
-// longer needed and can be reused for other purposes. The contents of a
-// sysUnused memory region are considered forfeit and the region must not be
-// accessed again until sysUsed is called.
-func sysUnused(v unsafe.Pointer, n uintptr) {
- gcController.mappedReady.Add(-int64(n))
- sysUnusedOS(v, n)
-}
-
-// sysUsed transitions a memory region from Prepared to Ready. It notifies the
-// operating system that the memory region is needed and ensures that the region
-// may be safely accessed. This is typically a no-op on systems that don't have
-// an explicit commit step and hard over-commit limits, but is critical on
-// Windows, for example.
-//
-// This operation is idempotent for memory already in the Prepared state, so
-// it is safe to refer, with v and n, to a range of memory that includes both
-// Prepared and Ready memory. However, the caller must provide the exact amount
-// of Prepared memory for accounting purposes.
-func sysUsed(v unsafe.Pointer, n, prepared uintptr) {
- gcController.mappedReady.Add(int64(prepared))
- sysUsedOS(v, n)
-}
-
-// sysHugePage does not transition memory regions, but instead provides a
-// hint to the OS that it would be more efficient to back this memory region
-// with pages of a larger size transparently.
-func sysHugePage(v unsafe.Pointer, n uintptr) {
- sysHugePageOS(v, n)
-}
-
-// sysFree transitions a memory region from any state to None. Therefore, it
-// returns memory unconditionally. It is used if an out-of-memory error has been
-// detected midway through an allocation or to carve out an aligned section of
-// the address space. It is okay if sysFree is a no-op only if sysReserve always
-// returns a memory region aligned to the heap allocator's alignment
-// restrictions.
-//
-// sysStat must be non-nil.
-//
-// Don't split the stack as this function may be invoked without a valid G,
-// which prevents us from allocating more stack.
-//
-//go:nosplit
-func sysFree(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {
- sysStat.add(-int64(n))
- gcController.mappedReady.Add(-int64(n))
- sysFreeOS(v, n)
-}
-
-// sysFault transitions a memory region from Ready to Reserved. It
-// marks a region such that it will always fault if accessed. Used only for
-// debugging the runtime.
-//
-// TODO(mknyszek): Currently it's true that all uses of sysFault transition
-// memory from Ready to Reserved, but this may not be true in the future
-// since on every platform the operation is much more general than that.
-// If a transition from Prepared is ever introduced, create a new function
-// that elides the Ready state accounting.
-func sysFault(v unsafe.Pointer, n uintptr) {
- gcController.mappedReady.Add(-int64(n))
- sysFaultOS(v, n)
-}
-
-// sysReserve transitions a memory region from None to Reserved. It reserves
-// address space in such a way that it would cause a fatal fault upon access
-// (either via permissions or not committing the memory). Such a reservation is
-// thus never backed by physical memory.
-//
-// If the pointer passed to it is non-nil, the caller wants the
-// reservation there, but sysReserve can still choose another
-// location if that one is unavailable.
-//
-// NOTE: sysReserve returns OS-aligned memory, but the heap allocator
-// may use larger alignment, so the caller must be careful to realign the
-// memory obtained by sysReserve.
-func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer {
- return sysReserveOS(v, n)
-}
-
-// sysMap transitions a memory region from Reserved to Prepared. It ensures the
-// memory region can be efficiently transitioned to Ready.
-//
-// sysStat must be non-nil.
-func sysMap(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {
- sysStat.add(int64(n))
- sysMapOS(v, n)
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mem_darwin.go b/contrib/go/_std_1.20/src/runtime/mem_darwin.go
deleted file mode 100644
index 25862cf161..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mem_darwin.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2018 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 runtime
-
-import (
- "unsafe"
-)
-
-// Don't split the stack as this function may be invoked without a valid G,
-// which prevents us from allocating more stack.
-//
-//go:nosplit
-func sysAllocOS(n uintptr) unsafe.Pointer {
- v, err := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
- if err != 0 {
- return nil
- }
- return v
-}
-
-func sysUnusedOS(v unsafe.Pointer, n uintptr) {
- // MADV_FREE_REUSABLE is like MADV_FREE except it also propagates
- // accounting information about the process to task_info.
- madvise(v, n, _MADV_FREE_REUSABLE)
-}
-
-func sysUsedOS(v unsafe.Pointer, n uintptr) {
- // MADV_FREE_REUSE is necessary to keep the kernel's accounting
- // accurate. If called on any memory region that hasn't been
- // MADV_FREE_REUSABLE'd, it's a no-op.
- madvise(v, n, _MADV_FREE_REUSE)
-}
-
-func sysHugePageOS(v unsafe.Pointer, n uintptr) {
-}
-
-// Don't split the stack as this function may be invoked without a valid G,
-// which prevents us from allocating more stack.
-//
-//go:nosplit
-func sysFreeOS(v unsafe.Pointer, n uintptr) {
- munmap(v, n)
-}
-
-func sysFaultOS(v unsafe.Pointer, n uintptr) {
- mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE|_MAP_FIXED, -1, 0)
-}
-
-func sysReserveOS(v unsafe.Pointer, n uintptr) unsafe.Pointer {
- p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
- if err != 0 {
- return nil
- }
- return p
-}
-
-const _ENOMEM = 12
-
-func sysMapOS(v unsafe.Pointer, n uintptr) {
- p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
- if err == _ENOMEM {
- throw("runtime: out of memory")
- }
- if p != v || err != 0 {
- print("runtime: mmap(", v, ", ", n, ") returned ", p, ", ", err, "\n")
- throw("runtime: cannot map pages in arena address space")
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mem_linux.go b/contrib/go/_std_1.20/src/runtime/mem_linux.go
deleted file mode 100644
index 1630664cff..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mem_linux.go
+++ /dev/null
@@ -1,193 +0,0 @@
-// Copyright 2010 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 runtime
-
-import (
- "runtime/internal/atomic"
- "unsafe"
-)
-
-const (
- _EACCES = 13
- _EINVAL = 22
-)
-
-// Don't split the stack as this method may be invoked without a valid G, which
-// prevents us from allocating more stack.
-//
-//go:nosplit
-func sysAllocOS(n uintptr) unsafe.Pointer {
- p, err := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
- if err != 0 {
- if err == _EACCES {
- print("runtime: mmap: access denied\n")
- exit(2)
- }
- if err == _EAGAIN {
- print("runtime: mmap: too much locked memory (check 'ulimit -l').\n")
- exit(2)
- }
- return nil
- }
- return p
-}
-
-var adviseUnused = uint32(_MADV_FREE)
-
-func sysUnusedOS(v unsafe.Pointer, n uintptr) {
- // By default, Linux's "transparent huge page" support will
- // merge pages into a huge page if there's even a single
- // present regular page, undoing the effects of madvise(adviseUnused)
- // below. On amd64, that means khugepaged can turn a single
- // 4KB page to 2MB, bloating the process's RSS by as much as
- // 512X. (See issue #8832 and Linux kernel bug
- // https://bugzilla.kernel.org/show_bug.cgi?id=93111)
- //
- // To work around this, we explicitly disable transparent huge
- // pages when we release pages of the heap. However, we have
- // to do this carefully because changing this flag tends to
- // split the VMA (memory mapping) containing v in to three
- // VMAs in order to track the different values of the
- // MADV_NOHUGEPAGE flag in the different regions. There's a
- // default limit of 65530 VMAs per address space (sysctl
- // vm.max_map_count), so we must be careful not to create too
- // many VMAs (see issue #12233).
- //
- // Since huge pages are huge, there's little use in adjusting
- // the MADV_NOHUGEPAGE flag on a fine granularity, so we avoid
- // exploding the number of VMAs by only adjusting the
- // MADV_NOHUGEPAGE flag on a large granularity. This still
- // gets most of the benefit of huge pages while keeping the
- // number of VMAs under control. With hugePageSize = 2MB, even
- // a pessimal heap can reach 128GB before running out of VMAs.
- if physHugePageSize != 0 {
- // If it's a large allocation, we want to leave huge
- // pages enabled. Hence, we only adjust the huge page
- // flag on the huge pages containing v and v+n-1, and
- // only if those aren't aligned.
- var head, tail uintptr
- if uintptr(v)&(physHugePageSize-1) != 0 {
- // Compute huge page containing v.
- head = alignDown(uintptr(v), physHugePageSize)
- }
- if (uintptr(v)+n)&(physHugePageSize-1) != 0 {
- // Compute huge page containing v+n-1.
- tail = alignDown(uintptr(v)+n-1, physHugePageSize)
- }
-
- // Note that madvise will return EINVAL if the flag is
- // already set, which is quite likely. We ignore
- // errors.
- if head != 0 && head+physHugePageSize == tail {
- // head and tail are different but adjacent,
- // so do this in one call.
- madvise(unsafe.Pointer(head), 2*physHugePageSize, _MADV_NOHUGEPAGE)
- } else {
- // Advise the huge pages containing v and v+n-1.
- if head != 0 {
- madvise(unsafe.Pointer(head), physHugePageSize, _MADV_NOHUGEPAGE)
- }
- if tail != 0 && tail != head {
- madvise(unsafe.Pointer(tail), physHugePageSize, _MADV_NOHUGEPAGE)
- }
- }
- }
-
- if uintptr(v)&(physPageSize-1) != 0 || n&(physPageSize-1) != 0 {
- // madvise will round this to any physical page
- // *covered* by this range, so an unaligned madvise
- // will release more memory than intended.
- throw("unaligned sysUnused")
- }
-
- var advise uint32
- if debug.madvdontneed != 0 {
- advise = _MADV_DONTNEED
- } else {
- advise = atomic.Load(&adviseUnused)
- }
- if errno := madvise(v, n, int32(advise)); advise == _MADV_FREE && errno != 0 {
- // MADV_FREE was added in Linux 4.5. Fall back to MADV_DONTNEED if it is
- // not supported.
- atomic.Store(&adviseUnused, _MADV_DONTNEED)
- madvise(v, n, _MADV_DONTNEED)
- }
-
- if debug.harddecommit > 0 {
- p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
- if p != v || err != 0 {
- throw("runtime: cannot disable permissions in address space")
- }
- }
-}
-
-func sysUsedOS(v unsafe.Pointer, n uintptr) {
- if debug.harddecommit > 0 {
- p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
- if err == _ENOMEM {
- throw("runtime: out of memory")
- }
- if p != v || err != 0 {
- throw("runtime: cannot remap pages in address space")
- }
- return
-
- // Don't do the sysHugePage optimization in hard decommit mode.
- // We're breaking up pages everywhere, there's no point.
- }
- // Partially undo the NOHUGEPAGE marks from sysUnused
- // for whole huge pages between v and v+n. This may
- // leave huge pages off at the end points v and v+n
- // even though allocations may cover these entire huge
- // pages. We could detect this and undo NOHUGEPAGE on
- // the end points as well, but it's probably not worth
- // the cost because when neighboring allocations are
- // freed sysUnused will just set NOHUGEPAGE again.
- sysHugePageOS(v, n)
-}
-
-func sysHugePageOS(v unsafe.Pointer, n uintptr) {
- if physHugePageSize != 0 {
- // Round v up to a huge page boundary.
- beg := alignUp(uintptr(v), physHugePageSize)
- // Round v+n down to a huge page boundary.
- end := alignDown(uintptr(v)+n, physHugePageSize)
-
- if beg < end {
- madvise(unsafe.Pointer(beg), end-beg, _MADV_HUGEPAGE)
- }
- }
-}
-
-// Don't split the stack as this function may be invoked without a valid G,
-// which prevents us from allocating more stack.
-//
-//go:nosplit
-func sysFreeOS(v unsafe.Pointer, n uintptr) {
- munmap(v, n)
-}
-
-func sysFaultOS(v unsafe.Pointer, n uintptr) {
- mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE|_MAP_FIXED, -1, 0)
-}
-
-func sysReserveOS(v unsafe.Pointer, n uintptr) unsafe.Pointer {
- p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
- if err != 0 {
- return nil
- }
- return p
-}
-
-func sysMapOS(v unsafe.Pointer, n uintptr) {
- p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
- if err == _ENOMEM {
- throw("runtime: out of memory")
- }
- if p != v || err != 0 {
- print("runtime: mmap(", v, ", ", n, ") returned ", p, ", ", err, "\n")
- throw("runtime: cannot map pages in arena address space")
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mem_windows.go b/contrib/go/_std_1.20/src/runtime/mem_windows.go
deleted file mode 100644
index b1292fc725..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mem_windows.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2010 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 runtime
-
-import (
- "unsafe"
-)
-
-const (
- _MEM_COMMIT = 0x1000
- _MEM_RESERVE = 0x2000
- _MEM_DECOMMIT = 0x4000
- _MEM_RELEASE = 0x8000
-
- _PAGE_READWRITE = 0x0004
- _PAGE_NOACCESS = 0x0001
-
- _ERROR_NOT_ENOUGH_MEMORY = 8
- _ERROR_COMMITMENT_LIMIT = 1455
-)
-
-// Don't split the stack as this function may be invoked without a valid G,
-// which prevents us from allocating more stack.
-//
-//go:nosplit
-func sysAllocOS(n uintptr) unsafe.Pointer {
- return unsafe.Pointer(stdcall4(_VirtualAlloc, 0, n, _MEM_COMMIT|_MEM_RESERVE, _PAGE_READWRITE))
-}
-
-func sysUnusedOS(v unsafe.Pointer, n uintptr) {
- r := stdcall3(_VirtualFree, uintptr(v), n, _MEM_DECOMMIT)
- if r != 0 {
- return
- }
-
- // Decommit failed. Usual reason is that we've merged memory from two different
- // VirtualAlloc calls, and Windows will only let each VirtualFree handle pages from
- // a single VirtualAlloc. It is okay to specify a subset of the pages from a single alloc,
- // just not pages from multiple allocs. This is a rare case, arising only when we're
- // trying to give memory back to the operating system, which happens on a time
- // scale of minutes. It doesn't have to be terribly fast. Instead of extra bookkeeping
- // on all our VirtualAlloc calls, try freeing successively smaller pieces until
- // we manage to free something, and then repeat. This ends up being O(n log n)
- // in the worst case, but that's fast enough.
- for n > 0 {
- small := n
- for small >= 4096 && stdcall3(_VirtualFree, uintptr(v), small, _MEM_DECOMMIT) == 0 {
- small /= 2
- small &^= 4096 - 1
- }
- if small < 4096 {
- print("runtime: VirtualFree of ", small, " bytes failed with errno=", getlasterror(), "\n")
- throw("runtime: failed to decommit pages")
- }
- v = add(v, small)
- n -= small
- }
-}
-
-func sysUsedOS(v unsafe.Pointer, n uintptr) {
- p := stdcall4(_VirtualAlloc, uintptr(v), n, _MEM_COMMIT, _PAGE_READWRITE)
- if p == uintptr(v) {
- return
- }
-
- // Commit failed. See SysUnused.
- // Hold on to n here so we can give back a better error message
- // for certain cases.
- k := n
- for k > 0 {
- small := k
- for small >= 4096 && stdcall4(_VirtualAlloc, uintptr(v), small, _MEM_COMMIT, _PAGE_READWRITE) == 0 {
- small /= 2
- small &^= 4096 - 1
- }
- if small < 4096 {
- errno := getlasterror()
- switch errno {
- case _ERROR_NOT_ENOUGH_MEMORY, _ERROR_COMMITMENT_LIMIT:
- print("runtime: VirtualAlloc of ", n, " bytes failed with errno=", errno, "\n")
- throw("out of memory")
- default:
- print("runtime: VirtualAlloc of ", small, " bytes failed with errno=", errno, "\n")
- throw("runtime: failed to commit pages")
- }
- }
- v = add(v, small)
- k -= small
- }
-}
-
-func sysHugePageOS(v unsafe.Pointer, n uintptr) {
-}
-
-// Don't split the stack as this function may be invoked without a valid G,
-// which prevents us from allocating more stack.
-//
-//go:nosplit
-func sysFreeOS(v unsafe.Pointer, n uintptr) {
- r := stdcall3(_VirtualFree, uintptr(v), 0, _MEM_RELEASE)
- if r == 0 {
- print("runtime: VirtualFree of ", n, " bytes failed with errno=", getlasterror(), "\n")
- throw("runtime: failed to release pages")
- }
-}
-
-func sysFaultOS(v unsafe.Pointer, n uintptr) {
- // SysUnused makes the memory inaccessible and prevents its reuse
- sysUnusedOS(v, n)
-}
-
-func sysReserveOS(v unsafe.Pointer, n uintptr) unsafe.Pointer {
- // v is just a hint.
- // First try at v.
- // This will fail if any of [v, v+n) is already reserved.
- v = unsafe.Pointer(stdcall4(_VirtualAlloc, uintptr(v), n, _MEM_RESERVE, _PAGE_READWRITE))
- if v != nil {
- return v
- }
-
- // Next let the kernel choose the address.
- return unsafe.Pointer(stdcall4(_VirtualAlloc, 0, n, _MEM_RESERVE, _PAGE_READWRITE))
-}
-
-func sysMapOS(v unsafe.Pointer, n uintptr) {
-}
diff --git a/contrib/go/_std_1.20/src/runtime/metrics.go b/contrib/go/_std_1.20/src/runtime/metrics.go
deleted file mode 100644
index 2061dc0cf0..0000000000
--- a/contrib/go/_std_1.20/src/runtime/metrics.go
+++ /dev/null
@@ -1,723 +0,0 @@
-// 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 runtime
-
-// Metrics implementation exported to runtime/metrics.
-
-import (
- "unsafe"
-)
-
-var (
- // metrics is a map of runtime/metrics keys to data used by the runtime
- // to sample each metric's value. metricsInit indicates it has been
- // initialized.
- //
- // These fields are protected by metricsSema which should be
- // locked/unlocked with metricsLock() / metricsUnlock().
- metricsSema uint32 = 1
- metricsInit bool
- metrics map[string]metricData
-
- sizeClassBuckets []float64
- timeHistBuckets []float64
-)
-
-type metricData struct {
- // deps is the set of runtime statistics that this metric
- // depends on. Before compute is called, the statAggregate
- // which will be passed must ensure() these dependencies.
- deps statDepSet
-
- // compute is a function that populates a metricValue
- // given a populated statAggregate structure.
- compute func(in *statAggregate, out *metricValue)
-}
-
-func metricsLock() {
- // Acquire the metricsSema but with handoff. Operations are typically
- // expensive enough that queueing up goroutines and handing off between
- // them will be noticeably better-behaved.
- semacquire1(&metricsSema, true, 0, 0, waitReasonSemacquire)
- if raceenabled {
- raceacquire(unsafe.Pointer(&metricsSema))
- }
-}
-
-func metricsUnlock() {
- if raceenabled {
- racerelease(unsafe.Pointer(&metricsSema))
- }
- semrelease(&metricsSema)
-}
-
-// initMetrics initializes the metrics map if it hasn't been yet.
-//
-// metricsSema must be held.
-func initMetrics() {
- if metricsInit {
- return
- }
-
- sizeClassBuckets = make([]float64, _NumSizeClasses, _NumSizeClasses+1)
- // Skip size class 0 which is a stand-in for large objects, but large
- // objects are tracked separately (and they actually get placed in
- // the last bucket, not the first).
- sizeClassBuckets[0] = 1 // The smallest allocation is 1 byte in size.
- for i := 1; i < _NumSizeClasses; i++ {
- // Size classes have an inclusive upper-bound
- // and exclusive lower bound (e.g. 48-byte size class is
- // (32, 48]) whereas we want and inclusive lower-bound
- // and exclusive upper-bound (e.g. 48-byte size class is
- // [33, 49). We can achieve this by shifting all bucket
- // boundaries up by 1.
- //
- // Also, a float64 can precisely represent integers with
- // value up to 2^53 and size classes are relatively small
- // (nowhere near 2^48 even) so this will give us exact
- // boundaries.
- sizeClassBuckets[i] = float64(class_to_size[i] + 1)
- }
- sizeClassBuckets = append(sizeClassBuckets, float64Inf())
-
- timeHistBuckets = timeHistogramMetricsBuckets()
- metrics = map[string]metricData{
- "/cgo/go-to-c-calls:calls": {
- compute: func(_ *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = uint64(NumCgoCall())
- },
- },
- "/cpu/classes/gc/mark/assist:cpu-seconds": {
- deps: makeStatDepSet(cpuStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindFloat64
- out.scalar = float64bits(nsToSec(in.cpuStats.gcAssistTime))
- },
- },
- "/cpu/classes/gc/mark/dedicated:cpu-seconds": {
- deps: makeStatDepSet(cpuStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindFloat64
- out.scalar = float64bits(nsToSec(in.cpuStats.gcDedicatedTime))
- },
- },
- "/cpu/classes/gc/mark/idle:cpu-seconds": {
- deps: makeStatDepSet(cpuStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindFloat64
- out.scalar = float64bits(nsToSec(in.cpuStats.gcIdleTime))
- },
- },
- "/cpu/classes/gc/pause:cpu-seconds": {
- deps: makeStatDepSet(cpuStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindFloat64
- out.scalar = float64bits(nsToSec(in.cpuStats.gcPauseTime))
- },
- },
- "/cpu/classes/gc/total:cpu-seconds": {
- deps: makeStatDepSet(cpuStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindFloat64
- out.scalar = float64bits(nsToSec(in.cpuStats.gcTotalTime))
- },
- },
- "/cpu/classes/idle:cpu-seconds": {
- deps: makeStatDepSet(cpuStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindFloat64
- out.scalar = float64bits(nsToSec(in.cpuStats.idleTime))
- },
- },
- "/cpu/classes/scavenge/assist:cpu-seconds": {
- deps: makeStatDepSet(cpuStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindFloat64
- out.scalar = float64bits(nsToSec(in.cpuStats.scavengeAssistTime))
- },
- },
- "/cpu/classes/scavenge/background:cpu-seconds": {
- deps: makeStatDepSet(cpuStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindFloat64
- out.scalar = float64bits(nsToSec(in.cpuStats.scavengeBgTime))
- },
- },
- "/cpu/classes/scavenge/total:cpu-seconds": {
- deps: makeStatDepSet(cpuStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindFloat64
- out.scalar = float64bits(nsToSec(in.cpuStats.scavengeTotalTime))
- },
- },
- "/cpu/classes/total:cpu-seconds": {
- deps: makeStatDepSet(cpuStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindFloat64
- out.scalar = float64bits(nsToSec(in.cpuStats.totalTime))
- },
- },
- "/cpu/classes/user:cpu-seconds": {
- deps: makeStatDepSet(cpuStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindFloat64
- out.scalar = float64bits(nsToSec(in.cpuStats.userTime))
- },
- },
- "/gc/cycles/automatic:gc-cycles": {
- deps: makeStatDepSet(sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.sysStats.gcCyclesDone - in.sysStats.gcCyclesForced
- },
- },
- "/gc/cycles/forced:gc-cycles": {
- deps: makeStatDepSet(sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.sysStats.gcCyclesForced
- },
- },
- "/gc/cycles/total:gc-cycles": {
- deps: makeStatDepSet(sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.sysStats.gcCyclesDone
- },
- },
- "/gc/heap/allocs-by-size:bytes": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- hist := out.float64HistOrInit(sizeClassBuckets)
- hist.counts[len(hist.counts)-1] = uint64(in.heapStats.largeAllocCount)
- // Cut off the first index which is ostensibly for size class 0,
- // but large objects are tracked separately so it's actually unused.
- for i, count := range in.heapStats.smallAllocCount[1:] {
- hist.counts[i] = uint64(count)
- }
- },
- },
- "/gc/heap/allocs:bytes": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.heapStats.totalAllocated
- },
- },
- "/gc/heap/allocs:objects": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.heapStats.totalAllocs
- },
- },
- "/gc/heap/frees-by-size:bytes": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- hist := out.float64HistOrInit(sizeClassBuckets)
- hist.counts[len(hist.counts)-1] = uint64(in.heapStats.largeFreeCount)
- // Cut off the first index which is ostensibly for size class 0,
- // but large objects are tracked separately so it's actually unused.
- for i, count := range in.heapStats.smallFreeCount[1:] {
- hist.counts[i] = uint64(count)
- }
- },
- },
- "/gc/heap/frees:bytes": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.heapStats.totalFreed
- },
- },
- "/gc/heap/frees:objects": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.heapStats.totalFrees
- },
- },
- "/gc/heap/goal:bytes": {
- deps: makeStatDepSet(sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.sysStats.heapGoal
- },
- },
- "/gc/heap/objects:objects": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.heapStats.numObjects
- },
- },
- "/gc/heap/tiny/allocs:objects": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = uint64(in.heapStats.tinyAllocCount)
- },
- },
- "/gc/limiter/last-enabled:gc-cycle": {
- compute: func(_ *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = uint64(gcCPULimiter.lastEnabledCycle.Load())
- },
- },
- "/gc/pauses:seconds": {
- compute: func(_ *statAggregate, out *metricValue) {
- hist := out.float64HistOrInit(timeHistBuckets)
- // The bottom-most bucket, containing negative values, is tracked
- // as a separately as underflow, so fill that in manually and then
- // iterate over the rest.
- hist.counts[0] = memstats.gcPauseDist.underflow.Load()
- for i := range memstats.gcPauseDist.counts {
- hist.counts[i+1] = memstats.gcPauseDist.counts[i].Load()
- }
- hist.counts[len(hist.counts)-1] = memstats.gcPauseDist.overflow.Load()
- },
- },
- "/gc/stack/starting-size:bytes": {
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = uint64(startingStackSize)
- },
- },
- "/memory/classes/heap/free:bytes": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = uint64(in.heapStats.committed - in.heapStats.inHeap -
- in.heapStats.inStacks - in.heapStats.inWorkBufs -
- in.heapStats.inPtrScalarBits)
- },
- },
- "/memory/classes/heap/objects:bytes": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.heapStats.inObjects
- },
- },
- "/memory/classes/heap/released:bytes": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = uint64(in.heapStats.released)
- },
- },
- "/memory/classes/heap/stacks:bytes": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = uint64(in.heapStats.inStacks)
- },
- },
- "/memory/classes/heap/unused:bytes": {
- deps: makeStatDepSet(heapStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = uint64(in.heapStats.inHeap) - in.heapStats.inObjects
- },
- },
- "/memory/classes/metadata/mcache/free:bytes": {
- deps: makeStatDepSet(sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.sysStats.mCacheSys - in.sysStats.mCacheInUse
- },
- },
- "/memory/classes/metadata/mcache/inuse:bytes": {
- deps: makeStatDepSet(sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.sysStats.mCacheInUse
- },
- },
- "/memory/classes/metadata/mspan/free:bytes": {
- deps: makeStatDepSet(sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.sysStats.mSpanSys - in.sysStats.mSpanInUse
- },
- },
- "/memory/classes/metadata/mspan/inuse:bytes": {
- deps: makeStatDepSet(sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.sysStats.mSpanInUse
- },
- },
- "/memory/classes/metadata/other:bytes": {
- deps: makeStatDepSet(heapStatsDep, sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = uint64(in.heapStats.inWorkBufs+in.heapStats.inPtrScalarBits) + in.sysStats.gcMiscSys
- },
- },
- "/memory/classes/os-stacks:bytes": {
- deps: makeStatDepSet(sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.sysStats.stacksSys
- },
- },
- "/memory/classes/other:bytes": {
- deps: makeStatDepSet(sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.sysStats.otherSys
- },
- },
- "/memory/classes/profiling/buckets:bytes": {
- deps: makeStatDepSet(sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = in.sysStats.buckHashSys
- },
- },
- "/memory/classes/total:bytes": {
- deps: makeStatDepSet(heapStatsDep, sysStatsDep),
- compute: func(in *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = uint64(in.heapStats.committed+in.heapStats.released) +
- in.sysStats.stacksSys + in.sysStats.mSpanSys +
- in.sysStats.mCacheSys + in.sysStats.buckHashSys +
- in.sysStats.gcMiscSys + in.sysStats.otherSys
- },
- },
- "/sched/gomaxprocs:threads": {
- compute: func(_ *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = uint64(gomaxprocs)
- },
- },
- "/sched/goroutines:goroutines": {
- compute: func(_ *statAggregate, out *metricValue) {
- out.kind = metricKindUint64
- out.scalar = uint64(gcount())
- },
- },
- "/sched/latencies:seconds": {
- compute: func(_ *statAggregate, out *metricValue) {
- hist := out.float64HistOrInit(timeHistBuckets)
- hist.counts[0] = sched.timeToRun.underflow.Load()
- for i := range sched.timeToRun.counts {
- hist.counts[i+1] = sched.timeToRun.counts[i].Load()
- }
- hist.counts[len(hist.counts)-1] = sched.timeToRun.overflow.Load()
- },
- },
- "/sync/mutex/wait/total:seconds": {
- compute: func(_ *statAggregate, out *metricValue) {
- out.kind = metricKindFloat64
- out.scalar = float64bits(nsToSec(sched.totalMutexWaitTime.Load()))
- },
- },
- }
- metricsInit = true
-}
-
-// statDep is a dependency on a group of statistics
-// that a metric might have.
-type statDep uint
-
-const (
- heapStatsDep statDep = iota // corresponds to heapStatsAggregate
- sysStatsDep // corresponds to sysStatsAggregate
- cpuStatsDep // corresponds to cpuStatsAggregate
- numStatsDeps
-)
-
-// statDepSet represents a set of statDeps.
-//
-// Under the hood, it's a bitmap.
-type statDepSet [1]uint64
-
-// makeStatDepSet creates a new statDepSet from a list of statDeps.
-func makeStatDepSet(deps ...statDep) statDepSet {
- var s statDepSet
- for _, d := range deps {
- s[d/64] |= 1 << (d % 64)
- }
- return s
-}
-
-// differennce returns set difference of s from b as a new set.
-func (s statDepSet) difference(b statDepSet) statDepSet {
- var c statDepSet
- for i := range s {
- c[i] = s[i] &^ b[i]
- }
- return c
-}
-
-// union returns the union of the two sets as a new set.
-func (s statDepSet) union(b statDepSet) statDepSet {
- var c statDepSet
- for i := range s {
- c[i] = s[i] | b[i]
- }
- return c
-}
-
-// empty returns true if there are no dependencies in the set.
-func (s *statDepSet) empty() bool {
- for _, c := range s {
- if c != 0 {
- return false
- }
- }
- return true
-}
-
-// has returns true if the set contains a given statDep.
-func (s *statDepSet) has(d statDep) bool {
- return s[d/64]&(1<<(d%64)) != 0
-}
-
-// heapStatsAggregate represents memory stats obtained from the
-// runtime. This set of stats is grouped together because they
-// depend on each other in some way to make sense of the runtime's
-// current heap memory use. They're also sharded across Ps, so it
-// makes sense to grab them all at once.
-type heapStatsAggregate struct {
- heapStatsDelta
-
- // Derived from values in heapStatsDelta.
-
- // inObjects is the bytes of memory occupied by objects,
- inObjects uint64
-
- // numObjects is the number of live objects in the heap.
- numObjects uint64
-
- // totalAllocated is the total bytes of heap objects allocated
- // over the lifetime of the program.
- totalAllocated uint64
-
- // totalFreed is the total bytes of heap objects freed
- // over the lifetime of the program.
- totalFreed uint64
-
- // totalAllocs is the number of heap objects allocated over
- // the lifetime of the program.
- totalAllocs uint64
-
- // totalFrees is the number of heap objects freed over
- // the lifetime of the program.
- totalFrees uint64
-}
-
-// compute populates the heapStatsAggregate with values from the runtime.
-func (a *heapStatsAggregate) compute() {
- memstats.heapStats.read(&a.heapStatsDelta)
-
- // Calculate derived stats.
- a.totalAllocs = a.largeAllocCount
- a.totalFrees = a.largeFreeCount
- a.totalAllocated = a.largeAlloc
- a.totalFreed = a.largeFree
- for i := range a.smallAllocCount {
- na := a.smallAllocCount[i]
- nf := a.smallFreeCount[i]
- a.totalAllocs += na
- a.totalFrees += nf
- a.totalAllocated += na * uint64(class_to_size[i])
- a.totalFreed += nf * uint64(class_to_size[i])
- }
- a.inObjects = a.totalAllocated - a.totalFreed
- a.numObjects = a.totalAllocs - a.totalFrees
-}
-
-// sysStatsAggregate represents system memory stats obtained
-// from the runtime. This set of stats is grouped together because
-// they're all relatively cheap to acquire and generally independent
-// of one another and other runtime memory stats. The fact that they
-// may be acquired at different times, especially with respect to
-// heapStatsAggregate, means there could be some skew, but because of
-// these stats are independent, there's no real consistency issue here.
-type sysStatsAggregate struct {
- stacksSys uint64
- mSpanSys uint64
- mSpanInUse uint64
- mCacheSys uint64
- mCacheInUse uint64
- buckHashSys uint64
- gcMiscSys uint64
- otherSys uint64
- heapGoal uint64
- gcCyclesDone uint64
- gcCyclesForced uint64
-}
-
-// compute populates the sysStatsAggregate with values from the runtime.
-func (a *sysStatsAggregate) compute() {
- a.stacksSys = memstats.stacks_sys.load()
- a.buckHashSys = memstats.buckhash_sys.load()
- a.gcMiscSys = memstats.gcMiscSys.load()
- a.otherSys = memstats.other_sys.load()
- a.heapGoal = gcController.heapGoal()
- a.gcCyclesDone = uint64(memstats.numgc)
- a.gcCyclesForced = uint64(memstats.numforcedgc)
-
- systemstack(func() {
- lock(&mheap_.lock)
- a.mSpanSys = memstats.mspan_sys.load()
- a.mSpanInUse = uint64(mheap_.spanalloc.inuse)
- a.mCacheSys = memstats.mcache_sys.load()
- a.mCacheInUse = uint64(mheap_.cachealloc.inuse)
- unlock(&mheap_.lock)
- })
-}
-
-// cpuStatsAggregate represents CPU stats obtained from the runtime
-// acquired together to avoid skew and inconsistencies.
-type cpuStatsAggregate struct {
- cpuStats
-}
-
-// compute populates the cpuStatsAggregate with values from the runtime.
-func (a *cpuStatsAggregate) compute() {
- a.cpuStats = work.cpuStats
-}
-
-// nsToSec takes a duration in nanoseconds and converts it to seconds as
-// a float64.
-func nsToSec(ns int64) float64 {
- return float64(ns) / 1e9
-}
-
-// statAggregate is the main driver of the metrics implementation.
-//
-// It contains multiple aggregates of runtime statistics, as well
-// as a set of these aggregates that it has populated. The aggergates
-// are populated lazily by its ensure method.
-type statAggregate struct {
- ensured statDepSet
- heapStats heapStatsAggregate
- sysStats sysStatsAggregate
- cpuStats cpuStatsAggregate
-}
-
-// ensure populates statistics aggregates determined by deps if they
-// haven't yet been populated.
-func (a *statAggregate) ensure(deps *statDepSet) {
- missing := deps.difference(a.ensured)
- if missing.empty() {
- return
- }
- for i := statDep(0); i < numStatsDeps; i++ {
- if !missing.has(i) {
- continue
- }
- switch i {
- case heapStatsDep:
- a.heapStats.compute()
- case sysStatsDep:
- a.sysStats.compute()
- case cpuStatsDep:
- a.cpuStats.compute()
- }
- }
- a.ensured = a.ensured.union(missing)
-}
-
-// metricKind is a runtime copy of runtime/metrics.ValueKind and
-// must be kept structurally identical to that type.
-type metricKind int
-
-const (
- // These values must be kept identical to their corresponding Kind* values
- // in the runtime/metrics package.
- metricKindBad metricKind = iota
- metricKindUint64
- metricKindFloat64
- metricKindFloat64Histogram
-)
-
-// metricSample is a runtime copy of runtime/metrics.Sample and
-// must be kept structurally identical to that type.
-type metricSample struct {
- name string
- value metricValue
-}
-
-// metricValue is a runtime copy of runtime/metrics.Sample and
-// must be kept structurally identical to that type.
-type metricValue struct {
- kind metricKind
- scalar uint64 // contains scalar values for scalar Kinds.
- pointer unsafe.Pointer // contains non-scalar values.
-}
-
-// float64HistOrInit tries to pull out an existing float64Histogram
-// from the value, but if none exists, then it allocates one with
-// the given buckets.
-func (v *metricValue) float64HistOrInit(buckets []float64) *metricFloat64Histogram {
- var hist *metricFloat64Histogram
- if v.kind == metricKindFloat64Histogram && v.pointer != nil {
- hist = (*metricFloat64Histogram)(v.pointer)
- } else {
- v.kind = metricKindFloat64Histogram
- hist = new(metricFloat64Histogram)
- v.pointer = unsafe.Pointer(hist)
- }
- hist.buckets = buckets
- if len(hist.counts) != len(hist.buckets)-1 {
- hist.counts = make([]uint64, len(buckets)-1)
- }
- return hist
-}
-
-// metricFloat64Histogram is a runtime copy of runtime/metrics.Float64Histogram
-// and must be kept structurally identical to that type.
-type metricFloat64Histogram struct {
- counts []uint64
- buckets []float64
-}
-
-// agg is used by readMetrics, and is protected by metricsSema.
-//
-// Managed as a global variable because its pointer will be
-// an argument to a dynamically-defined function, and we'd
-// like to avoid it escaping to the heap.
-var agg statAggregate
-
-// readMetrics is the implementation of runtime/metrics.Read.
-//
-//go:linkname readMetrics runtime/metrics.runtime_readMetrics
-func readMetrics(samplesp unsafe.Pointer, len int, cap int) {
- // Construct a slice from the args.
- sl := slice{samplesp, len, cap}
- samples := *(*[]metricSample)(unsafe.Pointer(&sl))
-
- metricsLock()
-
- // Ensure the map is initialized.
- initMetrics()
-
- // Clear agg defensively.
- agg = statAggregate{}
-
- // Sample.
- for i := range samples {
- sample := &samples[i]
- data, ok := metrics[sample.name]
- if !ok {
- sample.value.kind = metricKindBad
- continue
- }
- // Ensure we have all the stats we need.
- // agg is populated lazily.
- agg.ensure(&data.deps)
-
- // Compute the value based on the stats we have.
- data.compute(&agg, &sample.value)
- }
-
- metricsUnlock()
-}
diff --git a/contrib/go/_std_1.20/src/runtime/metrics/description.go b/contrib/go/_std_1.20/src/runtime/metrics/description.go
deleted file mode 100644
index dcfe01e67c..0000000000
--- a/contrib/go/_std_1.20/src/runtime/metrics/description.go
+++ /dev/null
@@ -1,380 +0,0 @@
-// 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 metrics
-
-// Description describes a runtime metric.
-type Description struct {
- // Name is the full name of the metric which includes the unit.
- //
- // The format of the metric may be described by the following regular expression.
- //
- // ^(?P<name>/[^:]+):(?P<unit>[^:*/]+(?:[*/][^:*/]+)*)$
- //
- // The format splits the name into two components, separated by a colon: a path which always
- // starts with a /, and a machine-parseable unit. The name may contain any valid Unicode
- // codepoint in between / characters, but by convention will try to stick to lowercase
- // characters and hyphens. An example of such a path might be "/memory/heap/free".
- //
- // The unit is by convention a series of lowercase English unit names (singular or plural)
- // without prefixes delimited by '*' or '/'. The unit names may contain any valid Unicode
- // codepoint that is not a delimiter.
- // Examples of units might be "seconds", "bytes", "bytes/second", "cpu-seconds",
- // "byte*cpu-seconds", and "bytes/second/second".
- //
- // For histograms, multiple units may apply. For instance, the units of the buckets and
- // the count. By convention, for histograms, the units of the count are always "samples"
- // with the type of sample evident by the metric's name, while the unit in the name
- // specifies the buckets' unit.
- //
- // A complete name might look like "/memory/heap/free:bytes".
- Name string
-
- // Description is an English language sentence describing the metric.
- Description string
-
- // Kind is the kind of value for this metric.
- //
- // The purpose of this field is to allow users to filter out metrics whose values are
- // types which their application may not understand.
- Kind ValueKind
-
- // Cumulative is whether or not the metric is cumulative. If a cumulative metric is just
- // a single number, then it increases monotonically. If the metric is a distribution,
- // then each bucket count increases monotonically.
- //
- // This flag thus indicates whether or not it's useful to compute a rate from this value.
- Cumulative bool
-}
-
-// The English language descriptions below must be kept in sync with the
-// descriptions of each metric in doc.go.
-var allDesc = []Description{
- {
- Name: "/cgo/go-to-c-calls:calls",
- Description: "Count of calls made from Go to C by the current process.",
- Kind: KindUint64,
- Cumulative: true,
- },
- {
- Name: "/cpu/classes/gc/mark/assist:cpu-seconds",
- Description: "Estimated total CPU time goroutines spent performing GC tasks " +
- "to assist the GC and prevent it from falling behind the application. " +
- "This metric is an overestimate, and not directly comparable to " +
- "system CPU time measurements. Compare only with other /cpu/classes " +
- "metrics.",
- Kind: KindFloat64,
- Cumulative: true,
- },
- {
- Name: "/cpu/classes/gc/mark/dedicated:cpu-seconds",
- Description: "Estimated total CPU time spent performing GC tasks on " +
- "processors (as defined by GOMAXPROCS) dedicated to those tasks. " +
- "This includes time spent with the world stopped due to the GC. " +
- "This metric is an overestimate, and not directly comparable to " +
- "system CPU time measurements. Compare only with other /cpu/classes " +
- "metrics.",
- Kind: KindFloat64,
- Cumulative: true,
- },
- {
- Name: "/cpu/classes/gc/mark/idle:cpu-seconds",
- Description: "Estimated total CPU time spent performing GC tasks on " +
- "spare CPU resources that the Go scheduler could not otherwise find " +
- "a use for. This should be subtracted from the total GC CPU time to " +
- "obtain a measure of compulsory GC CPU time. " +
- "This metric is an overestimate, and not directly comparable to " +
- "system CPU time measurements. Compare only with other /cpu/classes " +
- "metrics.",
- Kind: KindFloat64,
- Cumulative: true,
- },
- {
- Name: "/cpu/classes/gc/pause:cpu-seconds",
- Description: "Estimated total CPU time spent with the application paused by " +
- "the GC. Even if only one thread is running during the pause, this is " +
- "computed as GOMAXPROCS times the pause latency because nothing else " +
- "can be executing. This is the exact sum of samples in /gc/pause:seconds " +
- "if each sample is multiplied by GOMAXPROCS at the time it is taken. " +
- "This metric is an overestimate, and not directly comparable to " +
- "system CPU time measurements. Compare only with other /cpu/classes " +
- "metrics.",
- Kind: KindFloat64,
- Cumulative: true,
- },
- {
- Name: "/cpu/classes/gc/total:cpu-seconds",
- Description: "Estimated total CPU time spent performing GC tasks. " +
- "This metric is an overestimate, and not directly comparable to " +
- "system CPU time measurements. Compare only with other /cpu/classes " +
- "metrics. Sum of all metrics in /cpu/classes/gc.",
- Kind: KindFloat64,
- Cumulative: true,
- },
- {
- Name: "/cpu/classes/idle:cpu-seconds",
- Description: "Estimated total available CPU time not spent executing any Go or Go runtime code. " +
- "In other words, the part of /cpu/classes/total:cpu-seconds that was unused. " +
- "This metric is an overestimate, and not directly comparable to " +
- "system CPU time measurements. Compare only with other /cpu/classes " +
- "metrics.",
- Kind: KindFloat64,
- Cumulative: true,
- },
- {
- Name: "/cpu/classes/scavenge/assist:cpu-seconds",
- Description: "Estimated total CPU time spent returning unused memory to the " +
- "underlying platform in response eagerly in response to memory pressure. " +
- "This metric is an overestimate, and not directly comparable to " +
- "system CPU time measurements. Compare only with other /cpu/classes " +
- "metrics.",
- Kind: KindFloat64,
- Cumulative: true,
- },
- {
- Name: "/cpu/classes/scavenge/background:cpu-seconds",
- Description: "Estimated total CPU time spent performing background tasks " +
- "to return unused memory to the underlying platform. " +
- "This metric is an overestimate, and not directly comparable to " +
- "system CPU time measurements. Compare only with other /cpu/classes " +
- "metrics.",
- Kind: KindFloat64,
- Cumulative: true,
- },
- {
- Name: "/cpu/classes/scavenge/total:cpu-seconds",
- Description: "Estimated total CPU time spent performing tasks that return " +
- "unused memory to the underlying platform. " +
- "This metric is an overestimate, and not directly comparable to " +
- "system CPU time measurements. Compare only with other /cpu/classes " +
- "metrics. Sum of all metrics in /cpu/classes/scavenge.",
- Kind: KindFloat64,
- Cumulative: true,
- },
- {
- Name: "/cpu/classes/total:cpu-seconds",
- Description: "Estimated total available CPU time for user Go code " +
- "or the Go runtime, as defined by GOMAXPROCS. In other words, GOMAXPROCS " +
- "integrated over the wall-clock duration this process has been executing for. " +
- "This metric is an overestimate, and not directly comparable to " +
- "system CPU time measurements. Compare only with other /cpu/classes " +
- "metrics. Sum of all metrics in /cpu/classes.",
- Kind: KindFloat64,
- Cumulative: true,
- },
- {
- Name: "/cpu/classes/user:cpu-seconds",
- Description: "Estimated total CPU time spent running user Go code. This may " +
- "also include some small amount of time spent in the Go runtime. " +
- "This metric is an overestimate, and not directly comparable to " +
- "system CPU time measurements. Compare only with other /cpu/classes " +
- "metrics.",
- Kind: KindFloat64,
- Cumulative: true,
- },
- {
- Name: "/gc/cycles/automatic:gc-cycles",
- Description: "Count of completed GC cycles generated by the Go runtime.",
- Kind: KindUint64,
- Cumulative: true,
- },
- {
- Name: "/gc/cycles/forced:gc-cycles",
- Description: "Count of completed GC cycles forced by the application.",
- Kind: KindUint64,
- Cumulative: true,
- },
- {
- Name: "/gc/cycles/total:gc-cycles",
- Description: "Count of all completed GC cycles.",
- Kind: KindUint64,
- Cumulative: true,
- },
- {
- Name: "/gc/heap/allocs-by-size:bytes",
- Description: "Distribution of heap allocations by approximate size. " +
- "Note that this does not include tiny objects as defined by " +
- "/gc/heap/tiny/allocs:objects, only tiny blocks.",
- Kind: KindFloat64Histogram,
- Cumulative: true,
- },
- {
- Name: "/gc/heap/allocs:bytes",
- Description: "Cumulative sum of memory allocated to the heap by the application.",
- Kind: KindUint64,
- Cumulative: true,
- },
- {
- Name: "/gc/heap/allocs:objects",
- Description: "Cumulative count of heap allocations triggered by the application. " +
- "Note that this does not include tiny objects as defined by " +
- "/gc/heap/tiny/allocs:objects, only tiny blocks.",
- Kind: KindUint64,
- Cumulative: true,
- },
- {
- Name: "/gc/heap/frees-by-size:bytes",
- Description: "Distribution of freed heap allocations by approximate size. " +
- "Note that this does not include tiny objects as defined by " +
- "/gc/heap/tiny/allocs:objects, only tiny blocks.",
- Kind: KindFloat64Histogram,
- Cumulative: true,
- },
- {
- Name: "/gc/heap/frees:bytes",
- Description: "Cumulative sum of heap memory freed by the garbage collector.",
- Kind: KindUint64,
- Cumulative: true,
- },
- {
- Name: "/gc/heap/frees:objects",
- Description: "Cumulative count of heap allocations whose storage was freed " +
- "by the garbage collector. " +
- "Note that this does not include tiny objects as defined by " +
- "/gc/heap/tiny/allocs:objects, only tiny blocks.",
- Kind: KindUint64,
- Cumulative: true,
- },
- {
- Name: "/gc/heap/goal:bytes",
- Description: "Heap size target for the end of the GC cycle.",
- Kind: KindUint64,
- },
- {
- Name: "/gc/heap/objects:objects",
- Description: "Number of objects, live or unswept, occupying heap memory.",
- Kind: KindUint64,
- },
- {
- Name: "/gc/heap/tiny/allocs:objects",
- Description: "Count of small allocations that are packed together into blocks. " +
- "These allocations are counted separately from other allocations " +
- "because each individual allocation is not tracked by the runtime, " +
- "only their block. Each block is already accounted for in " +
- "allocs-by-size and frees-by-size.",
- Kind: KindUint64,
- Cumulative: true,
- },
- {
- Name: "/gc/limiter/last-enabled:gc-cycle",
- Description: "GC cycle the last time the GC CPU limiter was enabled. " +
- "This metric is useful for diagnosing the root cause of an out-of-memory " +
- "error, because the limiter trades memory for CPU time when the GC's CPU " +
- "time gets too high. This is most likely to occur with use of SetMemoryLimit. " +
- "The first GC cycle is cycle 1, so a value of 0 indicates that it was never enabled.",
- Kind: KindUint64,
- },
- {
- Name: "/gc/pauses:seconds",
- Description: "Distribution individual GC-related stop-the-world pause latencies.",
- Kind: KindFloat64Histogram,
- Cumulative: true,
- },
- {
- Name: "/gc/stack/starting-size:bytes",
- Description: "The stack size of new goroutines.",
- Kind: KindUint64,
- Cumulative: false,
- },
- {
- Name: "/memory/classes/heap/free:bytes",
- Description: "Memory that is completely free and eligible to be returned to the underlying system, " +
- "but has not been. This metric is the runtime's estimate of free address space that is backed by " +
- "physical memory.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/heap/objects:bytes",
- Description: "Memory occupied by live objects and dead objects that have not yet been marked free by the garbage collector.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/heap/released:bytes",
- Description: "Memory that is completely free and has been returned to the underlying system. This " +
- "metric is the runtime's estimate of free address space that is still mapped into the process, " +
- "but is not backed by physical memory.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/heap/stacks:bytes",
- Description: "Memory allocated from the heap that is reserved for stack space, whether or not it is currently in-use.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/heap/unused:bytes",
- Description: "Memory that is reserved for heap objects but is not currently used to hold heap objects.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/metadata/mcache/free:bytes",
- Description: "Memory that is reserved for runtime mcache structures, but not in-use.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/metadata/mcache/inuse:bytes",
- Description: "Memory that is occupied by runtime mcache structures that are currently being used.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/metadata/mspan/free:bytes",
- Description: "Memory that is reserved for runtime mspan structures, but not in-use.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/metadata/mspan/inuse:bytes",
- Description: "Memory that is occupied by runtime mspan structures that are currently being used.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/metadata/other:bytes",
- Description: "Memory that is reserved for or used to hold runtime metadata.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/os-stacks:bytes",
- Description: "Stack memory allocated by the underlying operating system.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/other:bytes",
- Description: "Memory used by execution trace buffers, structures for debugging the runtime, finalizer and profiler specials, and more.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/profiling/buckets:bytes",
- Description: "Memory that is used by the stack trace hash map used for profiling.",
- Kind: KindUint64,
- },
- {
- Name: "/memory/classes/total:bytes",
- Description: "All memory mapped by the Go runtime into the current process as read-write. Note that this does not include memory mapped by code called via cgo or via the syscall package. Sum of all metrics in /memory/classes.",
- Kind: KindUint64,
- },
- {
- Name: "/sched/gomaxprocs:threads",
- Description: "The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously.",
- Kind: KindUint64,
- },
- {
- Name: "/sched/goroutines:goroutines",
- Description: "Count of live goroutines.",
- Kind: KindUint64,
- },
- {
- Name: "/sched/latencies:seconds",
- Description: "Distribution of the time goroutines have spent in the scheduler in a runnable state before actually running.",
- Kind: KindFloat64Histogram,
- },
- {
- Name: "/sync/mutex/wait/total:seconds",
- Description: "Approximate cumulative time goroutines have spent blocked on a sync.Mutex or sync.RWMutex. This metric is useful for identifying global changes in lock contention. Collect a mutex or block profile using the runtime/pprof package for more detailed contention data.",
- Kind: KindFloat64,
- Cumulative: true,
- },
-}
-
-// All returns a slice of containing metric descriptions for all supported metrics.
-func All() []Description {
- return allDesc
-}
diff --git a/contrib/go/_std_1.20/src/runtime/metrics/doc.go b/contrib/go/_std_1.20/src/runtime/metrics/doc.go
deleted file mode 100644
index b593d8d812..0000000000
--- a/contrib/go/_std_1.20/src/runtime/metrics/doc.go
+++ /dev/null
@@ -1,283 +0,0 @@
-// 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 metrics provides a stable interface to access implementation-defined
-metrics exported by the Go runtime. This package is similar to existing functions
-like runtime.ReadMemStats and debug.ReadGCStats, but significantly more general.
-
-The set of metrics defined by this package may evolve as the runtime itself
-evolves, and also enables variation across Go implementations, whose relevant
-metric sets may not intersect.
-
-# Interface
-
-Metrics are designated by a string key, rather than, for example, a field name in
-a struct. The full list of supported metrics is always available in the slice of
-Descriptions returned by All. Each Description also includes useful information
-about the metric.
-
-Thus, users of this API are encouraged to sample supported metrics defined by the
-slice returned by All to remain compatible across Go versions. Of course, situations
-arise where reading specific metrics is critical. For these cases, users are
-encouraged to use build tags, and although metrics may be deprecated and removed,
-users should consider this to be an exceptional and rare event, coinciding with a
-very large change in a particular Go implementation.
-
-Each metric key also has a "kind" that describes the format of the metric's value.
-In the interest of not breaking users of this package, the "kind" for a given metric
-is guaranteed not to change. If it must change, then a new metric will be introduced
-with a new key and a new "kind."
-
-# Metric key format
-
-As mentioned earlier, metric keys are strings. Their format is simple and well-defined,
-designed to be both human and machine readable. It is split into two components,
-separated by a colon: a rooted path and a unit. The choice to include the unit in
-the key is motivated by compatibility: if a metric's unit changes, its semantics likely
-did also, and a new key should be introduced.
-
-For more details on the precise definition of the metric key's path and unit formats, see
-the documentation of the Name field of the Description struct.
-
-# A note about floats
-
-This package supports metrics whose values have a floating-point representation. In
-order to improve ease-of-use, this package promises to never produce the following
-classes of floating-point values: NaN, infinity.
-
-# Supported metrics
-
-Below is the full list of supported metrics, ordered lexicographically.
-
- /cgo/go-to-c-calls:calls
- Count of calls made from Go to C by the current process.
-
- /cpu/classes/gc/mark/assist:cpu-seconds
- Estimated total CPU time goroutines spent performing GC tasks
- to assist the GC and prevent it from falling behind the application.
- This metric is an overestimate, and not directly comparable to
- system CPU time measurements. Compare only with other /cpu/classes
- metrics.
-
- /cpu/classes/gc/mark/dedicated:cpu-seconds
- Estimated total CPU time spent performing GC tasks on
- processors (as defined by GOMAXPROCS) dedicated to those tasks.
- This includes time spent with the world stopped due to the GC.
- This metric is an overestimate, and not directly comparable to
- system CPU time measurements. Compare only with other /cpu/classes
- metrics.
-
- /cpu/classes/gc/mark/idle:cpu-seconds
- Estimated total CPU time spent performing GC tasks on
- spare CPU resources that the Go scheduler could not otherwise find
- a use for. This should be subtracted from the total GC CPU time to
- obtain a measure of compulsory GC CPU time.
- This metric is an overestimate, and not directly comparable to
- system CPU time measurements. Compare only with other /cpu/classes
- metrics.
-
- /cpu/classes/gc/pause:cpu-seconds
- Estimated total CPU time spent with the application paused by
- the GC. Even if only one thread is running during the pause, this is
- computed as GOMAXPROCS times the pause latency because nothing else
- can be executing. This is the exact sum of samples in /gc/pause:seconds
- if each sample is multiplied by GOMAXPROCS at the time it is taken.
- This metric is an overestimate, and not directly comparable to
- system CPU time measurements. Compare only with other /cpu/classes
- metrics.
-
- /cpu/classes/gc/total:cpu-seconds
- Estimated total CPU time spent performing GC tasks.
- This metric is an overestimate, and not directly comparable to
- system CPU time measurements. Compare only with other /cpu/classes
- metrics. Sum of all metrics in /cpu/classes/gc.
-
- /cpu/classes/idle:cpu-seconds
- Estimated total available CPU time not spent executing any Go or Go
- runtime code. In other words, the part of /cpu/classes/total:cpu-seconds
- that was unused.
- This metric is an overestimate, and not directly comparable to
- system CPU time measurements. Compare only with other /cpu/classes
- metrics.
-
- /cpu/classes/scavenge/assist:cpu-seconds
- Estimated total CPU time spent returning unused memory to the
- underlying platform in response eagerly in response to memory pressure.
- This metric is an overestimate, and not directly comparable to
- system CPU time measurements. Compare only with other /cpu/classes
- metrics.
-
- /cpu/classes/scavenge/background:cpu-seconds
- Estimated total CPU time spent performing background tasks
- to return unused memory to the underlying platform.
- This metric is an overestimate, and not directly comparable to
- system CPU time measurements. Compare only with other /cpu/classes
- metrics.
-
- /cpu/classes/scavenge/total:cpu-seconds
- Estimated total CPU time spent performing tasks that return
- unused memory to the underlying platform.
- This metric is an overestimate, and not directly comparable to
- system CPU time measurements. Compare only with other /cpu/classes
- metrics. Sum of all metrics in /cpu/classes/scavenge.
-
- /cpu/classes/total:cpu-seconds
- Estimated total available CPU time for user Go code or the Go runtime, as
- defined by GOMAXPROCS. In other words, GOMAXPROCS integrated over the
- wall-clock duration this process has been executing for.
- This metric is an overestimate, and not directly comparable to
- system CPU time measurements. Compare only with other /cpu/classes
- metrics. Sum of all metrics in /cpu/classes.
-
- /cpu/classes/user:cpu-seconds
- Estimated total CPU time spent running user Go code. This may
- also include some small amount of time spent in the Go runtime.
- This metric is an overestimate, and not directly comparable to
- system CPU time measurements. Compare only with other /cpu/classes
- metrics.
-
- /gc/cycles/automatic:gc-cycles
- Count of completed GC cycles generated by the Go runtime.
-
- /gc/cycles/forced:gc-cycles
- Count of completed GC cycles forced by the application.
-
- /gc/cycles/total:gc-cycles
- Count of all completed GC cycles.
-
- /gc/heap/allocs-by-size:bytes
- Distribution of heap allocations by approximate size.
- Note that this does not include tiny objects as defined by /gc/heap/tiny/allocs:objects,
- only tiny blocks.
-
- /gc/heap/allocs:bytes
- Cumulative sum of memory allocated to the heap by the application.
-
- /gc/heap/allocs:objects
- Cumulative count of heap allocations triggered by the application.
- Note that this does not include tiny objects as defined by /gc/heap/tiny/allocs:objects,
- only tiny blocks.
-
- /gc/heap/frees-by-size:bytes
- Distribution of freed heap allocations by approximate size.
- Note that this does not include tiny objects as defined by /gc/heap/tiny/allocs:objects,
- only tiny blocks.
-
- /gc/heap/frees:bytes
- Cumulative sum of heap memory freed by the garbage collector.
-
- /gc/heap/frees:objects
- Cumulative count of heap allocations whose storage was freed by the garbage collector.
- Note that this does not include tiny objects as defined by /gc/heap/tiny/allocs:objects,
- only tiny blocks.
-
- /gc/heap/goal:bytes
- Heap size target for the end of the GC cycle.
-
- /gc/heap/objects:objects
- Number of objects, live or unswept, occupying heap memory.
-
- /gc/heap/tiny/allocs:objects
- Count of small allocations that are packed together into blocks.
- These allocations are counted separately from other allocations
- because each individual allocation is not tracked by the runtime,
- only their block. Each block is already accounted for in
- allocs-by-size and frees-by-size.
-
- /gc/limiter/last-enabled:gc-cycle
- GC cycle the last time the GC CPU limiter was enabled.
- This metric is useful for diagnosing the root cause of an out-of-memory
- error, because the limiter trades memory for CPU time when the GC's CPU
- time gets too high. This is most likely to occur with use of SetMemoryLimit.
- The first GC cycle is cycle 1, so a value of 0 indicates that it was never enabled.
-
- /gc/pauses:seconds
- Distribution individual GC-related stop-the-world pause latencies.
-
- /gc/stack/starting-size:bytes
- The stack size of new goroutines.
-
- /memory/classes/heap/free:bytes
- Memory that is completely free and eligible to be returned to
- the underlying system, but has not been. This metric is the
- runtime's estimate of free address space that is backed by
- physical memory.
-
- /memory/classes/heap/objects:bytes
- Memory occupied by live objects and dead objects that have
- not yet been marked free by the garbage collector.
-
- /memory/classes/heap/released:bytes
- Memory that is completely free and has been returned to
- the underlying system. This metric is the runtime's estimate of
- free address space that is still mapped into the process, but
- is not backed by physical memory.
-
- /memory/classes/heap/stacks:bytes
- Memory allocated from the heap that is reserved for stack
- space, whether or not it is currently in-use.
-
- /memory/classes/heap/unused:bytes
- Memory that is reserved for heap objects but is not currently
- used to hold heap objects.
-
- /memory/classes/metadata/mcache/free:bytes
- Memory that is reserved for runtime mcache structures, but
- not in-use.
-
- /memory/classes/metadata/mcache/inuse:bytes
- Memory that is occupied by runtime mcache structures that
- are currently being used.
-
- /memory/classes/metadata/mspan/free:bytes
- Memory that is reserved for runtime mspan structures, but
- not in-use.
-
- /memory/classes/metadata/mspan/inuse:bytes
- Memory that is occupied by runtime mspan structures that are
- currently being used.
-
- /memory/classes/metadata/other:bytes
- Memory that is reserved for or used to hold runtime
- metadata.
-
- /memory/classes/os-stacks:bytes
- Stack memory allocated by the underlying operating system.
-
- /memory/classes/other:bytes
- Memory used by execution trace buffers, structures for
- debugging the runtime, finalizer and profiler specials, and
- more.
-
- /memory/classes/profiling/buckets:bytes
- Memory that is used by the stack trace hash map used for
- profiling.
-
- /memory/classes/total:bytes
- All memory mapped by the Go runtime into the current process
- as read-write. Note that this does not include memory mapped
- by code called via cgo or via the syscall package.
- Sum of all metrics in /memory/classes.
-
- /sched/gomaxprocs:threads
- The current runtime.GOMAXPROCS setting, or the number of
- operating system threads that can execute user-level Go code
- simultaneously.
-
- /sched/goroutines:goroutines
- Count of live goroutines.
-
- /sched/latencies:seconds
- Distribution of the time goroutines have spent in the scheduler
- in a runnable state before actually running.
-
- /sync/mutex/wait/total:seconds
- Approximate cumulative time goroutines have spent blocked on a
- sync.Mutex or sync.RWMutex. This metric is useful for identifying
- global changes in lock contention. Collect a mutex or block
- profile using the runtime/pprof package for more detailed
- contention data.
-*/
-package metrics
diff --git a/contrib/go/_std_1.20/src/runtime/metrics/ya.make b/contrib/go/_std_1.20/src/runtime/metrics/ya.make
deleted file mode 100644
index 38d182e461..0000000000
--- a/contrib/go/_std_1.20/src/runtime/metrics/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- description.go
- doc.go
- histogram.go
- sample.go
- value.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/runtime/mfinal.go b/contrib/go/_std_1.20/src/runtime/mfinal.go
deleted file mode 100644
index d4d4f1f302..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mfinal.go
+++ /dev/null
@@ -1,518 +0,0 @@
-// Copyright 2009 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.
-
-// Garbage collector: finalizers and block profiling.
-
-package runtime
-
-import (
- "internal/abi"
- "internal/goarch"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// finblock is an array of finalizers to be executed. finblocks are
-// arranged in a linked list for the finalizer queue.
-//
-// finblock is allocated from non-GC'd memory, so any heap pointers
-// must be specially handled. GC currently assumes that the finalizer
-// queue does not grow during marking (but it can shrink).
-type finblock struct {
- _ sys.NotInHeap
- alllink *finblock
- next *finblock
- cnt uint32
- _ int32
- fin [(_FinBlockSize - 2*goarch.PtrSize - 2*4) / unsafe.Sizeof(finalizer{})]finalizer
-}
-
-var fingStatus atomic.Uint32
-
-// finalizer goroutine status.
-const (
- fingUninitialized uint32 = iota
- fingCreated uint32 = 1 << (iota - 1)
- fingRunningFinalizer
- fingWait
- fingWake
-)
-
-var finlock mutex // protects the following variables
-var fing *g // goroutine that runs finalizers
-var finq *finblock // list of finalizers that are to be executed
-var finc *finblock // cache of free blocks
-var finptrmask [_FinBlockSize / goarch.PtrSize / 8]byte
-
-var allfin *finblock // list of all blocks
-
-// NOTE: Layout known to queuefinalizer.
-type finalizer struct {
- fn *funcval // function to call (may be a heap pointer)
- arg unsafe.Pointer // ptr to object (may be a heap pointer)
- nret uintptr // bytes of return values from fn
- fint *_type // type of first argument of fn
- ot *ptrtype // type of ptr to object (may be a heap pointer)
-}
-
-var finalizer1 = [...]byte{
- // Each Finalizer is 5 words, ptr ptr INT ptr ptr (INT = uintptr here)
- // Each byte describes 8 words.
- // Need 8 Finalizers described by 5 bytes before pattern repeats:
- // ptr ptr INT ptr ptr
- // ptr ptr INT ptr ptr
- // ptr ptr INT ptr ptr
- // ptr ptr INT ptr ptr
- // ptr ptr INT ptr ptr
- // ptr ptr INT ptr ptr
- // ptr ptr INT ptr ptr
- // ptr ptr INT ptr ptr
- // aka
- //
- // ptr ptr INT ptr ptr ptr ptr INT
- // ptr ptr ptr ptr INT ptr ptr ptr
- // ptr INT ptr ptr ptr ptr INT ptr
- // ptr ptr ptr INT ptr ptr ptr ptr
- // INT ptr ptr ptr ptr INT ptr ptr
- //
- // Assumptions about Finalizer layout checked below.
- 1<<0 | 1<<1 | 0<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 0<<7,
- 1<<0 | 1<<1 | 1<<2 | 1<<3 | 0<<4 | 1<<5 | 1<<6 | 1<<7,
- 1<<0 | 0<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 0<<6 | 1<<7,
- 1<<0 | 1<<1 | 1<<2 | 0<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7,
- 0<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 0<<5 | 1<<6 | 1<<7,
-}
-
-// lockRankMayQueueFinalizer records the lock ranking effects of a
-// function that may call queuefinalizer.
-func lockRankMayQueueFinalizer() {
- lockWithRankMayAcquire(&finlock, getLockRank(&finlock))
-}
-
-func queuefinalizer(p unsafe.Pointer, fn *funcval, nret uintptr, fint *_type, ot *ptrtype) {
- if gcphase != _GCoff {
- // Currently we assume that the finalizer queue won't
- // grow during marking so we don't have to rescan it
- // during mark termination. If we ever need to lift
- // this assumption, we can do it by adding the
- // necessary barriers to queuefinalizer (which it may
- // have automatically).
- throw("queuefinalizer during GC")
- }
-
- lock(&finlock)
- if finq == nil || finq.cnt == uint32(len(finq.fin)) {
- if finc == nil {
- finc = (*finblock)(persistentalloc(_FinBlockSize, 0, &memstats.gcMiscSys))
- finc.alllink = allfin
- allfin = finc
- if finptrmask[0] == 0 {
- // Build pointer mask for Finalizer array in block.
- // Check assumptions made in finalizer1 array above.
- if (unsafe.Sizeof(finalizer{}) != 5*goarch.PtrSize ||
- unsafe.Offsetof(finalizer{}.fn) != 0 ||
- unsafe.Offsetof(finalizer{}.arg) != goarch.PtrSize ||
- unsafe.Offsetof(finalizer{}.nret) != 2*goarch.PtrSize ||
- unsafe.Offsetof(finalizer{}.fint) != 3*goarch.PtrSize ||
- unsafe.Offsetof(finalizer{}.ot) != 4*goarch.PtrSize) {
- throw("finalizer out of sync")
- }
- for i := range finptrmask {
- finptrmask[i] = finalizer1[i%len(finalizer1)]
- }
- }
- }
- block := finc
- finc = block.next
- block.next = finq
- finq = block
- }
- f := &finq.fin[finq.cnt]
- atomic.Xadd(&finq.cnt, +1) // Sync with markroots
- f.fn = fn
- f.nret = nret
- f.fint = fint
- f.ot = ot
- f.arg = p
- unlock(&finlock)
- fingStatus.Or(fingWake)
-}
-
-//go:nowritebarrier
-func iterate_finq(callback func(*funcval, unsafe.Pointer, uintptr, *_type, *ptrtype)) {
- for fb := allfin; fb != nil; fb = fb.alllink {
- for i := uint32(0); i < fb.cnt; i++ {
- f := &fb.fin[i]
- callback(f.fn, f.arg, f.nret, f.fint, f.ot)
- }
- }
-}
-
-func wakefing() *g {
- if ok := fingStatus.CompareAndSwap(fingCreated|fingWait|fingWake, fingCreated); ok {
- return fing
- }
- return nil
-}
-
-func createfing() {
- // start the finalizer goroutine exactly once
- if fingStatus.Load() == fingUninitialized && fingStatus.CompareAndSwap(fingUninitialized, fingCreated) {
- go runfinq()
- }
-}
-
-func finalizercommit(gp *g, lock unsafe.Pointer) bool {
- unlock((*mutex)(lock))
- // fingStatus should be modified after fing is put into a waiting state
- // to avoid waking fing in running state, even if it is about to be parked.
- fingStatus.Or(fingWait)
- return true
-}
-
-// This is the goroutine that runs all of the finalizers.
-func runfinq() {
- var (
- frame unsafe.Pointer
- framecap uintptr
- argRegs int
- )
-
- gp := getg()
- lock(&finlock)
- fing = gp
- unlock(&finlock)
-
- for {
- lock(&finlock)
- fb := finq
- finq = nil
- if fb == nil {
- gopark(finalizercommit, unsafe.Pointer(&finlock), waitReasonFinalizerWait, traceEvGoBlock, 1)
- continue
- }
- argRegs = intArgRegs
- unlock(&finlock)
- if raceenabled {
- racefingo()
- }
- for fb != nil {
- for i := fb.cnt; i > 0; i-- {
- f := &fb.fin[i-1]
-
- var regs abi.RegArgs
- // The args may be passed in registers or on stack. Even for
- // the register case, we still need the spill slots.
- // TODO: revisit if we remove spill slots.
- //
- // Unfortunately because we can have an arbitrary
- // amount of returns and it would be complex to try and
- // figure out how many of those can get passed in registers,
- // just conservatively assume none of them do.
- framesz := unsafe.Sizeof((any)(nil)) + f.nret
- if framecap < framesz {
- // The frame does not contain pointers interesting for GC,
- // all not yet finalized objects are stored in finq.
- // If we do not mark it as FlagNoScan,
- // the last finalized object is not collected.
- frame = mallocgc(framesz, nil, true)
- framecap = framesz
- }
-
- if f.fint == nil {
- throw("missing type in runfinq")
- }
- r := frame
- if argRegs > 0 {
- r = unsafe.Pointer(&regs.Ints)
- } else {
- // frame is effectively uninitialized
- // memory. That means we have to clear
- // it before writing to it to avoid
- // confusing the write barrier.
- *(*[2]uintptr)(frame) = [2]uintptr{}
- }
- switch f.fint.kind & kindMask {
- case kindPtr:
- // direct use of pointer
- *(*unsafe.Pointer)(r) = f.arg
- case kindInterface:
- ityp := (*interfacetype)(unsafe.Pointer(f.fint))
- // set up with empty interface
- (*eface)(r)._type = &f.ot.typ
- (*eface)(r).data = f.arg
- if len(ityp.mhdr) != 0 {
- // convert to interface with methods
- // this conversion is guaranteed to succeed - we checked in SetFinalizer
- (*iface)(r).tab = assertE2I(ityp, (*eface)(r)._type)
- }
- default:
- throw("bad kind in runfinq")
- }
- fingStatus.Or(fingRunningFinalizer)
- reflectcall(nil, unsafe.Pointer(f.fn), frame, uint32(framesz), uint32(framesz), uint32(framesz), &regs)
- fingStatus.And(^fingRunningFinalizer)
-
- // Drop finalizer queue heap references
- // before hiding them from markroot.
- // This also ensures these will be
- // clear if we reuse the finalizer.
- f.fn = nil
- f.arg = nil
- f.ot = nil
- atomic.Store(&fb.cnt, i-1)
- }
- next := fb.next
- lock(&finlock)
- fb.next = finc
- finc = fb
- unlock(&finlock)
- fb = next
- }
- }
-}
-
-// SetFinalizer sets the finalizer associated with obj to the provided
-// finalizer function. When the garbage collector finds an unreachable block
-// with an associated finalizer, it clears the association and runs
-// finalizer(obj) in a separate goroutine. This makes obj reachable again,
-// but now without an associated finalizer. Assuming that SetFinalizer
-// is not called again, the next time the garbage collector sees
-// that obj is unreachable, it will free obj.
-//
-// SetFinalizer(obj, nil) clears any finalizer associated with obj.
-//
-// The argument obj must be a pointer to an object allocated by calling
-// new, by taking the address of a composite literal, or by taking the
-// address of a local variable.
-// The argument finalizer must be a function that takes a single argument
-// to which obj's type can be assigned, and can have arbitrary ignored return
-// values. If either of these is not true, SetFinalizer may abort the
-// program.
-//
-// Finalizers are run in dependency order: if A points at B, both have
-// finalizers, and they are otherwise unreachable, only the finalizer
-// for A runs; once A is freed, the finalizer for B can run.
-// If a cyclic structure includes a block with a finalizer, that
-// cycle is not guaranteed to be garbage collected and the finalizer
-// is not guaranteed to run, because there is no ordering that
-// respects the dependencies.
-//
-// The finalizer is scheduled to run at some arbitrary time after the
-// program can no longer reach the object to which obj points.
-// There is no guarantee that finalizers will run before a program exits,
-// so typically they are useful only for releasing non-memory resources
-// associated with an object during a long-running program.
-// For example, an os.File object could use a finalizer to close the
-// associated operating system file descriptor when a program discards
-// an os.File without calling Close, but it would be a mistake
-// to depend on a finalizer to flush an in-memory I/O buffer such as a
-// bufio.Writer, because the buffer would not be flushed at program exit.
-//
-// It is not guaranteed that a finalizer will run if the size of *obj is
-// zero bytes, because it may share same address with other zero-size
-// objects in memory. See https://go.dev/ref/spec#Size_and_alignment_guarantees.
-//
-// It is not guaranteed that a finalizer will run for objects allocated
-// in initializers for package-level variables. Such objects may be
-// linker-allocated, not heap-allocated.
-//
-// Note that because finalizers may execute arbitrarily far into the future
-// after an object is no longer referenced, the runtime is allowed to perform
-// a space-saving optimization that batches objects together in a single
-// allocation slot. The finalizer for an unreferenced object in such an
-// allocation may never run if it always exists in the same batch as a
-// referenced object. Typically, this batching only happens for tiny
-// (on the order of 16 bytes or less) and pointer-free objects.
-//
-// A finalizer may run as soon as an object becomes unreachable.
-// In order to use finalizers correctly, the program must ensure that
-// the object is reachable until it is no longer required.
-// Objects stored in global variables, or that can be found by tracing
-// pointers from a global variable, are reachable. For other objects,
-// pass the object to a call of the KeepAlive function to mark the
-// last point in the function where the object must be reachable.
-//
-// For example, if p points to a struct, such as os.File, that contains
-// a file descriptor d, and p has a finalizer that closes that file
-// descriptor, and if the last use of p in a function is a call to
-// syscall.Write(p.d, buf, size), then p may be unreachable as soon as
-// the program enters syscall.Write. The finalizer may run at that moment,
-// closing p.d, causing syscall.Write to fail because it is writing to
-// a closed file descriptor (or, worse, to an entirely different
-// file descriptor opened by a different goroutine). To avoid this problem,
-// call KeepAlive(p) after the call to syscall.Write.
-//
-// A single goroutine runs all finalizers for a program, sequentially.
-// If a finalizer must run for a long time, it should do so by starting
-// a new goroutine.
-//
-// In the terminology of the Go memory model, a call
-// SetFinalizer(x, f) “synchronizes before” the finalization call f(x).
-// However, there is no guarantee that KeepAlive(x) or any other use of x
-// “synchronizes before” f(x), so in general a finalizer should use a mutex
-// or other synchronization mechanism if it needs to access mutable state in x.
-// For example, consider a finalizer that inspects a mutable field in x
-// that is modified from time to time in the main program before x
-// becomes unreachable and the finalizer is invoked.
-// The modifications in the main program and the inspection in the finalizer
-// need to use appropriate synchronization, such as mutexes or atomic updates,
-// to avoid read-write races.
-func SetFinalizer(obj any, finalizer any) {
- if debug.sbrk != 0 {
- // debug.sbrk never frees memory, so no finalizers run
- // (and we don't have the data structures to record them).
- return
- }
- e := efaceOf(&obj)
- etyp := e._type
- if etyp == nil {
- throw("runtime.SetFinalizer: first argument is nil")
- }
- if etyp.kind&kindMask != kindPtr {
- throw("runtime.SetFinalizer: first argument is " + etyp.string() + ", not pointer")
- }
- ot := (*ptrtype)(unsafe.Pointer(etyp))
- if ot.elem == nil {
- throw("nil elem type!")
- }
-
- if inUserArenaChunk(uintptr(e.data)) {
- // Arena-allocated objects are not eligible for finalizers.
- throw("runtime.SetFinalizer: first argument was allocated into an arena")
- }
-
- // find the containing object
- base, _, _ := findObject(uintptr(e.data), 0, 0)
-
- if base == 0 {
- // 0-length objects are okay.
- if e.data == unsafe.Pointer(&zerobase) {
- return
- }
-
- // Global initializers might be linker-allocated.
- // var Foo = &Object{}
- // func main() {
- // runtime.SetFinalizer(Foo, nil)
- // }
- // The relevant segments are: noptrdata, data, bss, noptrbss.
- // We cannot assume they are in any order or even contiguous,
- // due to external linking.
- for datap := &firstmoduledata; datap != nil; datap = datap.next {
- if datap.noptrdata <= uintptr(e.data) && uintptr(e.data) < datap.enoptrdata ||
- datap.data <= uintptr(e.data) && uintptr(e.data) < datap.edata ||
- datap.bss <= uintptr(e.data) && uintptr(e.data) < datap.ebss ||
- datap.noptrbss <= uintptr(e.data) && uintptr(e.data) < datap.enoptrbss {
- return
- }
- }
- throw("runtime.SetFinalizer: pointer not in allocated block")
- }
-
- if uintptr(e.data) != base {
- // As an implementation detail we allow to set finalizers for an inner byte
- // of an object if it could come from tiny alloc (see mallocgc for details).
- if ot.elem == nil || ot.elem.ptrdata != 0 || ot.elem.size >= maxTinySize {
- throw("runtime.SetFinalizer: pointer not at beginning of allocated block")
- }
- }
-
- f := efaceOf(&finalizer)
- ftyp := f._type
- if ftyp == nil {
- // switch to system stack and remove finalizer
- systemstack(func() {
- removefinalizer(e.data)
- })
- return
- }
-
- if ftyp.kind&kindMask != kindFunc {
- throw("runtime.SetFinalizer: second argument is " + ftyp.string() + ", not a function")
- }
- ft := (*functype)(unsafe.Pointer(ftyp))
- if ft.dotdotdot() {
- throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string() + " because dotdotdot")
- }
- if ft.inCount != 1 {
- throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string())
- }
- fint := ft.in()[0]
- switch {
- case fint == etyp:
- // ok - same type
- goto okarg
- case fint.kind&kindMask == kindPtr:
- if (fint.uncommon() == nil || etyp.uncommon() == nil) && (*ptrtype)(unsafe.Pointer(fint)).elem == ot.elem {
- // ok - not same type, but both pointers,
- // one or the other is unnamed, and same element type, so assignable.
- goto okarg
- }
- case fint.kind&kindMask == kindInterface:
- ityp := (*interfacetype)(unsafe.Pointer(fint))
- if len(ityp.mhdr) == 0 {
- // ok - satisfies empty interface
- goto okarg
- }
- if iface := assertE2I2(ityp, *efaceOf(&obj)); iface.tab != nil {
- goto okarg
- }
- }
- throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string())
-okarg:
- // compute size needed for return parameters
- nret := uintptr(0)
- for _, t := range ft.out() {
- nret = alignUp(nret, uintptr(t.align)) + uintptr(t.size)
- }
- nret = alignUp(nret, goarch.PtrSize)
-
- // make sure we have a finalizer goroutine
- createfing()
-
- systemstack(func() {
- if !addfinalizer(e.data, (*funcval)(f.data), nret, fint, ot) {
- throw("runtime.SetFinalizer: finalizer already set")
- }
- })
-}
-
-// Mark KeepAlive as noinline so that it is easily detectable as an intrinsic.
-//
-//go:noinline
-
-// KeepAlive marks its argument as currently reachable.
-// This ensures that the object is not freed, and its finalizer is not run,
-// before the point in the program where KeepAlive is called.
-//
-// A very simplified example showing where KeepAlive is required:
-//
-// type File struct { d int }
-// d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0)
-// // ... do something if err != nil ...
-// p := &File{d}
-// runtime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) })
-// var buf [10]byte
-// n, err := syscall.Read(p.d, buf[:])
-// // Ensure p is not finalized until Read returns.
-// runtime.KeepAlive(p)
-// // No more uses of p after this point.
-//
-// Without the KeepAlive call, the finalizer could run at the start of
-// syscall.Read, closing the file descriptor before syscall.Read makes
-// the actual system call.
-//
-// Note: KeepAlive should only be used to prevent finalizers from
-// running prematurely. In particular, when used with unsafe.Pointer,
-// the rules for valid uses of unsafe.Pointer still apply.
-func KeepAlive(x any) {
- // Introduce a use of x that the compiler can't eliminate.
- // This makes sure x is alive on entry. We need x to be alive
- // on entry for "defer runtime.KeepAlive(x)"; see issue 21402.
- if cgoAlwaysFalse {
- println(x)
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mfixalloc.go b/contrib/go/_std_1.20/src/runtime/mfixalloc.go
deleted file mode 100644
index 8788d95c00..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mfixalloc.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2009 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.
-
-// Fixed-size object allocator. Returned memory is not zeroed.
-//
-// See malloc.go for overview.
-
-package runtime
-
-import (
- "runtime/internal/sys"
- "unsafe"
-)
-
-// FixAlloc is a simple free-list allocator for fixed size objects.
-// Malloc uses a FixAlloc wrapped around sysAlloc to manage its
-// mcache and mspan objects.
-//
-// Memory returned by fixalloc.alloc is zeroed by default, but the
-// caller may take responsibility for zeroing allocations by setting
-// the zero flag to false. This is only safe if the memory never
-// contains heap pointers.
-//
-// The caller is responsible for locking around FixAlloc calls.
-// Callers can keep state in the object but the first word is
-// smashed by freeing and reallocating.
-//
-// Consider marking fixalloc'd types not in heap by embedding
-// runtime/internal/sys.NotInHeap.
-type fixalloc struct {
- size uintptr
- first func(arg, p unsafe.Pointer) // called first time p is returned
- arg unsafe.Pointer
- list *mlink
- chunk uintptr // use uintptr instead of unsafe.Pointer to avoid write barriers
- nchunk uint32 // bytes remaining in current chunk
- nalloc uint32 // size of new chunks in bytes
- inuse uintptr // in-use bytes now
- stat *sysMemStat
- zero bool // zero allocations
-}
-
-// A generic linked list of blocks. (Typically the block is bigger than sizeof(MLink).)
-// Since assignments to mlink.next will result in a write barrier being performed
-// this cannot be used by some of the internal GC structures. For example when
-// the sweeper is placing an unmarked object on the free list it does not want the
-// write barrier to be called since that could result in the object being reachable.
-type mlink struct {
- _ sys.NotInHeap
- next *mlink
-}
-
-// Initialize f to allocate objects of the given size,
-// using the allocator to obtain chunks of memory.
-func (f *fixalloc) init(size uintptr, first func(arg, p unsafe.Pointer), arg unsafe.Pointer, stat *sysMemStat) {
- if size > _FixAllocChunk {
- throw("runtime: fixalloc size too large")
- }
- if min := unsafe.Sizeof(mlink{}); size < min {
- size = min
- }
-
- f.size = size
- f.first = first
- f.arg = arg
- f.list = nil
- f.chunk = 0
- f.nchunk = 0
- f.nalloc = uint32(_FixAllocChunk / size * size) // Round _FixAllocChunk down to an exact multiple of size to eliminate tail waste
- f.inuse = 0
- f.stat = stat
- f.zero = true
-}
-
-func (f *fixalloc) alloc() unsafe.Pointer {
- if f.size == 0 {
- print("runtime: use of FixAlloc_Alloc before FixAlloc_Init\n")
- throw("runtime: internal error")
- }
-
- if f.list != nil {
- v := unsafe.Pointer(f.list)
- f.list = f.list.next
- f.inuse += f.size
- if f.zero {
- memclrNoHeapPointers(v, f.size)
- }
- return v
- }
- if uintptr(f.nchunk) < f.size {
- f.chunk = uintptr(persistentalloc(uintptr(f.nalloc), 0, f.stat))
- f.nchunk = f.nalloc
- }
-
- v := unsafe.Pointer(f.chunk)
- if f.first != nil {
- f.first(f.arg, v)
- }
- f.chunk = f.chunk + f.size
- f.nchunk -= uint32(f.size)
- f.inuse += f.size
- return v
-}
-
-func (f *fixalloc) free(p unsafe.Pointer) {
- f.inuse -= f.size
- v := (*mlink)(p)
- v.next = f.list
- f.list = v
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mgc.go b/contrib/go/_std_1.20/src/runtime/mgc.go
deleted file mode 100644
index 1b057070aa..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mgc.go
+++ /dev/null
@@ -1,1801 +0,0 @@
-// Copyright 2009 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.
-
-// Garbage collector (GC).
-//
-// The GC runs concurrently with mutator threads, is type accurate (aka precise), allows multiple
-// GC thread to run in parallel. It is a concurrent mark and sweep that uses a write barrier. It is
-// non-generational and non-compacting. Allocation is done using size segregated per P allocation
-// areas to minimize fragmentation while eliminating locks in the common case.
-//
-// The algorithm decomposes into several steps.
-// This is a high level description of the algorithm being used. For an overview of GC a good
-// place to start is Richard Jones' gchandbook.org.
-//
-// The algorithm's intellectual heritage includes Dijkstra's on-the-fly algorithm, see
-// Edsger W. Dijkstra, Leslie Lamport, A. J. Martin, C. S. Scholten, and E. F. M. Steffens. 1978.
-// On-the-fly garbage collection: an exercise in cooperation. Commun. ACM 21, 11 (November 1978),
-// 966-975.
-// For journal quality proofs that these steps are complete, correct, and terminate see
-// Hudson, R., and Moss, J.E.B. Copying Garbage Collection without stopping the world.
-// Concurrency and Computation: Practice and Experience 15(3-5), 2003.
-//
-// 1. GC performs sweep termination.
-//
-// a. Stop the world. This causes all Ps to reach a GC safe-point.
-//
-// b. Sweep any unswept spans. There will only be unswept spans if
-// this GC cycle was forced before the expected time.
-//
-// 2. GC performs the mark phase.
-//
-// a. Prepare for the mark phase by setting gcphase to _GCmark
-// (from _GCoff), enabling the write barrier, enabling mutator
-// assists, and enqueueing root mark jobs. No objects may be
-// scanned until all Ps have enabled the write barrier, which is
-// accomplished using STW.
-//
-// b. Start the world. From this point, GC work is done by mark
-// workers started by the scheduler and by assists performed as
-// part of allocation. The write barrier shades both the
-// overwritten pointer and the new pointer value for any pointer
-// writes (see mbarrier.go for details). Newly allocated objects
-// are immediately marked black.
-//
-// c. GC performs root marking jobs. This includes scanning all
-// stacks, shading all globals, and shading any heap pointers in
-// off-heap runtime data structures. Scanning a stack stops a
-// goroutine, shades any pointers found on its stack, and then
-// resumes the goroutine.
-//
-// d. GC drains the work queue of grey objects, scanning each grey
-// object to black and shading all pointers found in the object
-// (which in turn may add those pointers to the work queue).
-//
-// e. Because GC work is spread across local caches, GC uses a
-// distributed termination algorithm to detect when there are no
-// more root marking jobs or grey objects (see gcMarkDone). At this
-// point, GC transitions to mark termination.
-//
-// 3. GC performs mark termination.
-//
-// a. Stop the world.
-//
-// b. Set gcphase to _GCmarktermination, and disable workers and
-// assists.
-//
-// c. Perform housekeeping like flushing mcaches.
-//
-// 4. GC performs the sweep phase.
-//
-// a. Prepare for the sweep phase by setting gcphase to _GCoff,
-// setting up sweep state and disabling the write barrier.
-//
-// b. Start the world. From this point on, newly allocated objects
-// are white, and allocating sweeps spans before use if necessary.
-//
-// c. GC does concurrent sweeping in the background and in response
-// to allocation. See description below.
-//
-// 5. When sufficient allocation has taken place, replay the sequence
-// starting with 1 above. See discussion of GC rate below.
-
-// Concurrent sweep.
-//
-// The sweep phase proceeds concurrently with normal program execution.
-// The heap is swept span-by-span both lazily (when a goroutine needs another span)
-// and concurrently in a background goroutine (this helps programs that are not CPU bound).
-// At the end of STW mark termination all spans are marked as "needs sweeping".
-//
-// The background sweeper goroutine simply sweeps spans one-by-one.
-//
-// To avoid requesting more OS memory while there are unswept spans, when a
-// goroutine needs another span, it first attempts to reclaim that much memory
-// by sweeping. When a goroutine needs to allocate a new small-object span, it
-// sweeps small-object spans for the same object size until it frees at least
-// one object. When a goroutine needs to allocate large-object span from heap,
-// it sweeps spans until it frees at least that many pages into heap. There is
-// one case where this may not suffice: if a goroutine sweeps and frees two
-// nonadjacent one-page spans to the heap, it will allocate a new two-page
-// span, but there can still be other one-page unswept spans which could be
-// combined into a two-page span.
-//
-// It's critical to ensure that no operations proceed on unswept spans (that would corrupt
-// mark bits in GC bitmap). During GC all mcaches are flushed into the central cache,
-// so they are empty. When a goroutine grabs a new span into mcache, it sweeps it.
-// When a goroutine explicitly frees an object or sets a finalizer, it ensures that
-// the span is swept (either by sweeping it, or by waiting for the concurrent sweep to finish).
-// The finalizer goroutine is kicked off only when all spans are swept.
-// When the next GC starts, it sweeps all not-yet-swept spans (if any).
-
-// GC rate.
-// Next GC is after we've allocated an extra amount of memory proportional to
-// the amount already in use. The proportion is controlled by GOGC environment variable
-// (100 by default). If GOGC=100 and we're using 4M, we'll GC again when we get to 8M
-// (this mark is computed by the gcController.heapGoal method). This keeps the GC cost in
-// linear proportion to the allocation cost. Adjusting GOGC just changes the linear constant
-// (and also the amount of extra memory used).
-
-// Oblets
-//
-// In order to prevent long pauses while scanning large objects and to
-// improve parallelism, the garbage collector breaks up scan jobs for
-// objects larger than maxObletBytes into "oblets" of at most
-// maxObletBytes. When scanning encounters the beginning of a large
-// object, it scans only the first oblet and enqueues the remaining
-// oblets as new scan jobs.
-
-package runtime
-
-import (
- "internal/cpu"
- "runtime/internal/atomic"
- "unsafe"
-)
-
-const (
- _DebugGC = 0
- _ConcurrentSweep = true
- _FinBlockSize = 4 * 1024
-
- // debugScanConservative enables debug logging for stack
- // frames that are scanned conservatively.
- debugScanConservative = false
-
- // sweepMinHeapDistance is a lower bound on the heap distance
- // (in bytes) reserved for concurrent sweeping between GC
- // cycles.
- sweepMinHeapDistance = 1024 * 1024
-)
-
-func gcinit() {
- if unsafe.Sizeof(workbuf{}) != _WorkbufSize {
- throw("size of Workbuf is suboptimal")
- }
- // No sweep on the first cycle.
- sweep.active.state.Store(sweepDrainedMask)
-
- // Initialize GC pacer state.
- // Use the environment variable GOGC for the initial gcPercent value.
- // Use the environment variable GOMEMLIMIT for the initial memoryLimit value.
- gcController.init(readGOGC(), readGOMEMLIMIT())
-
- work.startSema = 1
- work.markDoneSema = 1
- lockInit(&work.sweepWaiters.lock, lockRankSweepWaiters)
- lockInit(&work.assistQueue.lock, lockRankAssistQueue)
- lockInit(&work.wbufSpans.lock, lockRankWbufSpans)
-}
-
-// gcenable is called after the bulk of the runtime initialization,
-// just before we're about to start letting user code run.
-// It kicks off the background sweeper goroutine, the background
-// scavenger goroutine, and enables GC.
-func gcenable() {
- // Kick off sweeping and scavenging.
- c := make(chan int, 2)
- go bgsweep(c)
- go bgscavenge(c)
- <-c
- <-c
- memstats.enablegc = true // now that runtime is initialized, GC is okay
-}
-
-// Garbage collector phase.
-// Indicates to write barrier and synchronization task to perform.
-var gcphase uint32
-
-// The compiler knows about this variable.
-// If you change it, you must change builtin/runtime.go, too.
-// If you change the first four bytes, you must also change the write
-// barrier insertion code.
-var writeBarrier struct {
- enabled bool // compiler emits a check of this before calling write barrier
- pad [3]byte // compiler uses 32-bit load for "enabled" field
- needed bool // whether we need a write barrier for current GC phase
- cgo bool // whether we need a write barrier for a cgo check
- alignme uint64 // guarantee alignment so that compiler can use a 32 or 64-bit load
-}
-
-// gcBlackenEnabled is 1 if mutator assists and background mark
-// workers are allowed to blacken objects. This must only be set when
-// gcphase == _GCmark.
-var gcBlackenEnabled uint32
-
-const (
- _GCoff = iota // GC not running; sweeping in background, write barrier disabled
- _GCmark // GC marking roots and workbufs: allocate black, write barrier ENABLED
- _GCmarktermination // GC mark termination: allocate black, P's help GC, write barrier ENABLED
-)
-
-//go:nosplit
-func setGCPhase(x uint32) {
- atomic.Store(&gcphase, x)
- writeBarrier.needed = gcphase == _GCmark || gcphase == _GCmarktermination
- writeBarrier.enabled = writeBarrier.needed || writeBarrier.cgo
-}
-
-// gcMarkWorkerMode represents the mode that a concurrent mark worker
-// should operate in.
-//
-// Concurrent marking happens through four different mechanisms. One
-// is mutator assists, which happen in response to allocations and are
-// not scheduled. The other three are variations in the per-P mark
-// workers and are distinguished by gcMarkWorkerMode.
-type gcMarkWorkerMode int
-
-const (
- // gcMarkWorkerNotWorker indicates that the next scheduled G is not
- // starting work and the mode should be ignored.
- gcMarkWorkerNotWorker gcMarkWorkerMode = iota
-
- // gcMarkWorkerDedicatedMode indicates that the P of a mark
- // worker is dedicated to running that mark worker. The mark
- // worker should run without preemption.
- gcMarkWorkerDedicatedMode
-
- // gcMarkWorkerFractionalMode indicates that a P is currently
- // running the "fractional" mark worker. The fractional worker
- // is necessary when GOMAXPROCS*gcBackgroundUtilization is not
- // an integer and using only dedicated workers would result in
- // utilization too far from the target of gcBackgroundUtilization.
- // The fractional worker should run until it is preempted and
- // will be scheduled to pick up the fractional part of
- // GOMAXPROCS*gcBackgroundUtilization.
- gcMarkWorkerFractionalMode
-
- // gcMarkWorkerIdleMode indicates that a P is running the mark
- // worker because it has nothing else to do. The idle worker
- // should run until it is preempted and account its time
- // against gcController.idleMarkTime.
- gcMarkWorkerIdleMode
-)
-
-// gcMarkWorkerModeStrings are the strings labels of gcMarkWorkerModes
-// to use in execution traces.
-var gcMarkWorkerModeStrings = [...]string{
- "Not worker",
- "GC (dedicated)",
- "GC (fractional)",
- "GC (idle)",
-}
-
-// pollFractionalWorkerExit reports whether a fractional mark worker
-// should self-preempt. It assumes it is called from the fractional
-// worker.
-func pollFractionalWorkerExit() bool {
- // This should be kept in sync with the fractional worker
- // scheduler logic in findRunnableGCWorker.
- now := nanotime()
- delta := now - gcController.markStartTime
- if delta <= 0 {
- return true
- }
- p := getg().m.p.ptr()
- selfTime := p.gcFractionalMarkTime + (now - p.gcMarkWorkerStartTime)
- // Add some slack to the utilization goal so that the
- // fractional worker isn't behind again the instant it exits.
- return float64(selfTime)/float64(delta) > 1.2*gcController.fractionalUtilizationGoal
-}
-
-var work workType
-
-type workType struct {
- full lfstack // lock-free list of full blocks workbuf
- empty lfstack // lock-free list of empty blocks workbuf
- pad0 cpu.CacheLinePad // prevents false-sharing between full/empty and nproc/nwait
-
- wbufSpans struct {
- lock mutex
- // free is a list of spans dedicated to workbufs, but
- // that don't currently contain any workbufs.
- free mSpanList
- // busy is a list of all spans containing workbufs on
- // one of the workbuf lists.
- busy mSpanList
- }
-
- // Restore 64-bit alignment on 32-bit.
- _ uint32
-
- // bytesMarked is the number of bytes marked this cycle. This
- // includes bytes blackened in scanned objects, noscan objects
- // that go straight to black, and permagrey objects scanned by
- // markroot during the concurrent scan phase. This is updated
- // atomically during the cycle. Updates may be batched
- // arbitrarily, since the value is only read at the end of the
- // cycle.
- //
- // Because of benign races during marking, this number may not
- // be the exact number of marked bytes, but it should be very
- // close.
- //
- // Put this field here because it needs 64-bit atomic access
- // (and thus 8-byte alignment even on 32-bit architectures).
- bytesMarked uint64
-
- markrootNext uint32 // next markroot job
- markrootJobs uint32 // number of markroot jobs
-
- nproc uint32
- tstart int64
- nwait uint32
-
- // Number of roots of various root types. Set by gcMarkRootPrepare.
- //
- // nStackRoots == len(stackRoots), but we have nStackRoots for
- // consistency.
- nDataRoots, nBSSRoots, nSpanRoots, nStackRoots int
-
- // Base indexes of each root type. Set by gcMarkRootPrepare.
- baseData, baseBSS, baseSpans, baseStacks, baseEnd uint32
-
- // stackRoots is a snapshot of all of the Gs that existed
- // before the beginning of concurrent marking. The backing
- // store of this must not be modified because it might be
- // shared with allgs.
- stackRoots []*g
-
- // Each type of GC state transition is protected by a lock.
- // Since multiple threads can simultaneously detect the state
- // transition condition, any thread that detects a transition
- // condition must acquire the appropriate transition lock,
- // re-check the transition condition and return if it no
- // longer holds or perform the transition if it does.
- // Likewise, any transition must invalidate the transition
- // condition before releasing the lock. This ensures that each
- // transition is performed by exactly one thread and threads
- // that need the transition to happen block until it has
- // happened.
- //
- // startSema protects the transition from "off" to mark or
- // mark termination.
- startSema uint32
- // markDoneSema protects transitions from mark to mark termination.
- markDoneSema uint32
-
- bgMarkReady note // signal background mark worker has started
- bgMarkDone uint32 // cas to 1 when at a background mark completion point
- // Background mark completion signaling
-
- // mode is the concurrency mode of the current GC cycle.
- mode gcMode
-
- // userForced indicates the current GC cycle was forced by an
- // explicit user call.
- userForced bool
-
- // initialHeapLive is the value of gcController.heapLive at the
- // beginning of this GC cycle.
- initialHeapLive uint64
-
- // assistQueue is a queue of assists that are blocked because
- // there was neither enough credit to steal or enough work to
- // do.
- assistQueue struct {
- lock mutex
- q gQueue
- }
-
- // sweepWaiters is a list of blocked goroutines to wake when
- // we transition from mark termination to sweep.
- sweepWaiters struct {
- lock mutex
- list gList
- }
-
- // cycles is the number of completed GC cycles, where a GC
- // cycle is sweep termination, mark, mark termination, and
- // sweep. This differs from memstats.numgc, which is
- // incremented at mark termination.
- cycles atomic.Uint32
-
- // Timing/utilization stats for this cycle.
- stwprocs, maxprocs int32
- tSweepTerm, tMark, tMarkTerm, tEnd int64 // nanotime() of phase start
-
- pauseNS int64 // total STW time this cycle
- pauseStart int64 // nanotime() of last STW
-
- // debug.gctrace heap sizes for this cycle.
- heap0, heap1, heap2 uint64
-
- // Cumulative estimated CPU usage.
- cpuStats
-}
-
-// GC runs a garbage collection and blocks the caller until the
-// garbage collection is complete. It may also block the entire
-// program.
-func GC() {
- // We consider a cycle to be: sweep termination, mark, mark
- // termination, and sweep. This function shouldn't return
- // until a full cycle has been completed, from beginning to
- // end. Hence, we always want to finish up the current cycle
- // and start a new one. That means:
- //
- // 1. In sweep termination, mark, or mark termination of cycle
- // N, wait until mark termination N completes and transitions
- // to sweep N.
- //
- // 2. In sweep N, help with sweep N.
- //
- // At this point we can begin a full cycle N+1.
- //
- // 3. Trigger cycle N+1 by starting sweep termination N+1.
- //
- // 4. Wait for mark termination N+1 to complete.
- //
- // 5. Help with sweep N+1 until it's done.
- //
- // This all has to be written to deal with the fact that the
- // GC may move ahead on its own. For example, when we block
- // until mark termination N, we may wake up in cycle N+2.
-
- // Wait until the current sweep termination, mark, and mark
- // termination complete.
- n := work.cycles.Load()
- gcWaitOnMark(n)
-
- // We're now in sweep N or later. Trigger GC cycle N+1, which
- // will first finish sweep N if necessary and then enter sweep
- // termination N+1.
- gcStart(gcTrigger{kind: gcTriggerCycle, n: n + 1})
-
- // Wait for mark termination N+1 to complete.
- gcWaitOnMark(n + 1)
-
- // Finish sweep N+1 before returning. We do this both to
- // complete the cycle and because runtime.GC() is often used
- // as part of tests and benchmarks to get the system into a
- // relatively stable and isolated state.
- for work.cycles.Load() == n+1 && sweepone() != ^uintptr(0) {
- sweep.nbgsweep++
- Gosched()
- }
-
- // Callers may assume that the heap profile reflects the
- // just-completed cycle when this returns (historically this
- // happened because this was a STW GC), but right now the
- // profile still reflects mark termination N, not N+1.
- //
- // As soon as all of the sweep frees from cycle N+1 are done,
- // we can go ahead and publish the heap profile.
- //
- // First, wait for sweeping to finish. (We know there are no
- // more spans on the sweep queue, but we may be concurrently
- // sweeping spans, so we have to wait.)
- for work.cycles.Load() == n+1 && !isSweepDone() {
- Gosched()
- }
-
- // Now we're really done with sweeping, so we can publish the
- // stable heap profile. Only do this if we haven't already hit
- // another mark termination.
- mp := acquirem()
- cycle := work.cycles.Load()
- if cycle == n+1 || (gcphase == _GCmark && cycle == n+2) {
- mProf_PostSweep()
- }
- releasem(mp)
-}
-
-// gcWaitOnMark blocks until GC finishes the Nth mark phase. If GC has
-// already completed this mark phase, it returns immediately.
-func gcWaitOnMark(n uint32) {
- for {
- // Disable phase transitions.
- lock(&work.sweepWaiters.lock)
- nMarks := work.cycles.Load()
- if gcphase != _GCmark {
- // We've already completed this cycle's mark.
- nMarks++
- }
- if nMarks > n {
- // We're done.
- unlock(&work.sweepWaiters.lock)
- return
- }
-
- // Wait until sweep termination, mark, and mark
- // termination of cycle N complete.
- work.sweepWaiters.list.push(getg())
- goparkunlock(&work.sweepWaiters.lock, waitReasonWaitForGCCycle, traceEvGoBlock, 1)
- }
-}
-
-// gcMode indicates how concurrent a GC cycle should be.
-type gcMode int
-
-const (
- gcBackgroundMode gcMode = iota // concurrent GC and sweep
- gcForceMode // stop-the-world GC now, concurrent sweep
- gcForceBlockMode // stop-the-world GC now and STW sweep (forced by user)
-)
-
-// A gcTrigger is a predicate for starting a GC cycle. Specifically,
-// it is an exit condition for the _GCoff phase.
-type gcTrigger struct {
- kind gcTriggerKind
- now int64 // gcTriggerTime: current time
- n uint32 // gcTriggerCycle: cycle number to start
-}
-
-type gcTriggerKind int
-
-const (
- // gcTriggerHeap indicates that a cycle should be started when
- // the heap size reaches the trigger heap size computed by the
- // controller.
- gcTriggerHeap gcTriggerKind = iota
-
- // gcTriggerTime indicates that a cycle should be started when
- // it's been more than forcegcperiod nanoseconds since the
- // previous GC cycle.
- gcTriggerTime
-
- // gcTriggerCycle indicates that a cycle should be started if
- // we have not yet started cycle number gcTrigger.n (relative
- // to work.cycles).
- gcTriggerCycle
-)
-
-// test reports whether the trigger condition is satisfied, meaning
-// that the exit condition for the _GCoff phase has been met. The exit
-// condition should be tested when allocating.
-func (t gcTrigger) test() bool {
- if !memstats.enablegc || panicking.Load() != 0 || gcphase != _GCoff {
- return false
- }
- switch t.kind {
- case gcTriggerHeap:
- // Non-atomic access to gcController.heapLive for performance. If
- // we are going to trigger on this, this thread just
- // atomically wrote gcController.heapLive anyway and we'll see our
- // own write.
- trigger, _ := gcController.trigger()
- return gcController.heapLive.Load() >= trigger
- case gcTriggerTime:
- if gcController.gcPercent.Load() < 0 {
- return false
- }
- lastgc := int64(atomic.Load64(&memstats.last_gc_nanotime))
- return lastgc != 0 && t.now-lastgc > forcegcperiod
- case gcTriggerCycle:
- // t.n > work.cycles, but accounting for wraparound.
- return int32(t.n-work.cycles.Load()) > 0
- }
- return true
-}
-
-// gcStart starts the GC. It transitions from _GCoff to _GCmark (if
-// debug.gcstoptheworld == 0) or performs all of GC (if
-// debug.gcstoptheworld != 0).
-//
-// This may return without performing this transition in some cases,
-// such as when called on a system stack or with locks held.
-func gcStart(trigger gcTrigger) {
- // Since this is called from malloc and malloc is called in
- // the guts of a number of libraries that might be holding
- // locks, don't attempt to start GC in non-preemptible or
- // potentially unstable situations.
- mp := acquirem()
- if gp := getg(); gp == mp.g0 || mp.locks > 1 || mp.preemptoff != "" {
- releasem(mp)
- return
- }
- releasem(mp)
- mp = nil
-
- // Pick up the remaining unswept/not being swept spans concurrently
- //
- // This shouldn't happen if we're being invoked in background
- // mode since proportional sweep should have just finished
- // sweeping everything, but rounding errors, etc, may leave a
- // few spans unswept. In forced mode, this is necessary since
- // GC can be forced at any point in the sweeping cycle.
- //
- // We check the transition condition continuously here in case
- // this G gets delayed in to the next GC cycle.
- for trigger.test() && sweepone() != ^uintptr(0) {
- sweep.nbgsweep++
- }
-
- // Perform GC initialization and the sweep termination
- // transition.
- semacquire(&work.startSema)
- // Re-check transition condition under transition lock.
- if !trigger.test() {
- semrelease(&work.startSema)
- return
- }
-
- // In gcstoptheworld debug mode, upgrade the mode accordingly.
- // We do this after re-checking the transition condition so
- // that multiple goroutines that detect the heap trigger don't
- // start multiple STW GCs.
- mode := gcBackgroundMode
- if debug.gcstoptheworld == 1 {
- mode = gcForceMode
- } else if debug.gcstoptheworld == 2 {
- mode = gcForceBlockMode
- }
-
- // Ok, we're doing it! Stop everybody else
- semacquire(&gcsema)
- semacquire(&worldsema)
-
- // For stats, check if this GC was forced by the user.
- // Update it under gcsema to avoid gctrace getting wrong values.
- work.userForced = trigger.kind == gcTriggerCycle
-
- if trace.enabled {
- traceGCStart()
- }
-
- // Check that all Ps have finished deferred mcache flushes.
- for _, p := range allp {
- if fg := p.mcache.flushGen.Load(); fg != mheap_.sweepgen {
- println("runtime: p", p.id, "flushGen", fg, "!= sweepgen", mheap_.sweepgen)
- throw("p mcache not flushed")
- }
- }
-
- gcBgMarkStartWorkers()
-
- systemstack(gcResetMarkState)
-
- work.stwprocs, work.maxprocs = gomaxprocs, gomaxprocs
- if work.stwprocs > ncpu {
- // This is used to compute CPU time of the STW phases,
- // so it can't be more than ncpu, even if GOMAXPROCS is.
- work.stwprocs = ncpu
- }
- work.heap0 = gcController.heapLive.Load()
- work.pauseNS = 0
- work.mode = mode
-
- now := nanotime()
- work.tSweepTerm = now
- work.pauseStart = now
- if trace.enabled {
- traceGCSTWStart(1)
- }
- systemstack(stopTheWorldWithSema)
- // Finish sweep before we start concurrent scan.
- systemstack(func() {
- finishsweep_m()
- })
-
- // clearpools before we start the GC. If we wait they memory will not be
- // reclaimed until the next GC cycle.
- clearpools()
-
- work.cycles.Add(1)
-
- // Assists and workers can start the moment we start
- // the world.
- gcController.startCycle(now, int(gomaxprocs), trigger)
-
- // Notify the CPU limiter that assists may begin.
- gcCPULimiter.startGCTransition(true, now)
-
- // In STW mode, disable scheduling of user Gs. This may also
- // disable scheduling of this goroutine, so it may block as
- // soon as we start the world again.
- if mode != gcBackgroundMode {
- schedEnableUser(false)
- }
-
- // Enter concurrent mark phase and enable
- // write barriers.
- //
- // Because the world is stopped, all Ps will
- // observe that write barriers are enabled by
- // the time we start the world and begin
- // scanning.
- //
- // Write barriers must be enabled before assists are
- // enabled because they must be enabled before
- // any non-leaf heap objects are marked. Since
- // allocations are blocked until assists can
- // happen, we want enable assists as early as
- // possible.
- setGCPhase(_GCmark)
-
- gcBgMarkPrepare() // Must happen before assist enable.
- gcMarkRootPrepare()
-
- // Mark all active tinyalloc blocks. Since we're
- // allocating from these, they need to be black like
- // other allocations. The alternative is to blacken
- // the tiny block on every allocation from it, which
- // would slow down the tiny allocator.
- gcMarkTinyAllocs()
-
- // At this point all Ps have enabled the write
- // barrier, thus maintaining the no white to
- // black invariant. Enable mutator assists to
- // put back-pressure on fast allocating
- // mutators.
- atomic.Store(&gcBlackenEnabled, 1)
-
- // In STW mode, we could block the instant systemstack
- // returns, so make sure we're not preemptible.
- mp = acquirem()
-
- // Concurrent mark.
- systemstack(func() {
- now = startTheWorldWithSema(trace.enabled)
- work.pauseNS += now - work.pauseStart
- work.tMark = now
- memstats.gcPauseDist.record(now - work.pauseStart)
-
- // Release the CPU limiter.
- gcCPULimiter.finishGCTransition(now)
- })
-
- // Release the world sema before Gosched() in STW mode
- // because we will need to reacquire it later but before
- // this goroutine becomes runnable again, and we could
- // self-deadlock otherwise.
- semrelease(&worldsema)
- releasem(mp)
-
- // Make sure we block instead of returning to user code
- // in STW mode.
- if mode != gcBackgroundMode {
- Gosched()
- }
-
- semrelease(&work.startSema)
-}
-
-// gcMarkDoneFlushed counts the number of P's with flushed work.
-//
-// Ideally this would be a captured local in gcMarkDone, but forEachP
-// escapes its callback closure, so it can't capture anything.
-//
-// This is protected by markDoneSema.
-var gcMarkDoneFlushed uint32
-
-// gcMarkDone transitions the GC from mark to mark termination if all
-// reachable objects have been marked (that is, there are no grey
-// objects and can be no more in the future). Otherwise, it flushes
-// all local work to the global queues where it can be discovered by
-// other workers.
-//
-// This should be called when all local mark work has been drained and
-// there are no remaining workers. Specifically, when
-//
-// work.nwait == work.nproc && !gcMarkWorkAvailable(p)
-//
-// The calling context must be preemptible.
-//
-// Flushing local work is important because idle Ps may have local
-// work queued. This is the only way to make that work visible and
-// drive GC to completion.
-//
-// It is explicitly okay to have write barriers in this function. If
-// it does transition to mark termination, then all reachable objects
-// have been marked, so the write barrier cannot shade any more
-// objects.
-func gcMarkDone() {
- // Ensure only one thread is running the ragged barrier at a
- // time.
- semacquire(&work.markDoneSema)
-
-top:
- // Re-check transition condition under transition lock.
- //
- // It's critical that this checks the global work queues are
- // empty before performing the ragged barrier. Otherwise,
- // there could be global work that a P could take after the P
- // has passed the ragged barrier.
- if !(gcphase == _GCmark && work.nwait == work.nproc && !gcMarkWorkAvailable(nil)) {
- semrelease(&work.markDoneSema)
- return
- }
-
- // forEachP needs worldsema to execute, and we'll need it to
- // stop the world later, so acquire worldsema now.
- semacquire(&worldsema)
-
- // Flush all local buffers and collect flushedWork flags.
- gcMarkDoneFlushed = 0
- systemstack(func() {
- gp := getg().m.curg
- // Mark the user stack as preemptible so that it may be scanned.
- // Otherwise, our attempt to force all P's to a safepoint could
- // result in a deadlock as we attempt to preempt a worker that's
- // trying to preempt us (e.g. for a stack scan).
- casGToWaiting(gp, _Grunning, waitReasonGCMarkTermination)
- forEachP(func(pp *p) {
- // Flush the write barrier buffer, since this may add
- // work to the gcWork.
- wbBufFlush1(pp)
-
- // Flush the gcWork, since this may create global work
- // and set the flushedWork flag.
- //
- // TODO(austin): Break up these workbufs to
- // better distribute work.
- pp.gcw.dispose()
- // Collect the flushedWork flag.
- if pp.gcw.flushedWork {
- atomic.Xadd(&gcMarkDoneFlushed, 1)
- pp.gcw.flushedWork = false
- }
- })
- casgstatus(gp, _Gwaiting, _Grunning)
- })
-
- if gcMarkDoneFlushed != 0 {
- // More grey objects were discovered since the
- // previous termination check, so there may be more
- // work to do. Keep going. It's possible the
- // transition condition became true again during the
- // ragged barrier, so re-check it.
- semrelease(&worldsema)
- goto top
- }
-
- // There was no global work, no local work, and no Ps
- // communicated work since we took markDoneSema. Therefore
- // there are no grey objects and no more objects can be
- // shaded. Transition to mark termination.
- now := nanotime()
- work.tMarkTerm = now
- work.pauseStart = now
- getg().m.preemptoff = "gcing"
- if trace.enabled {
- traceGCSTWStart(0)
- }
- systemstack(stopTheWorldWithSema)
- // The gcphase is _GCmark, it will transition to _GCmarktermination
- // below. The important thing is that the wb remains active until
- // all marking is complete. This includes writes made by the GC.
-
- // There is sometimes work left over when we enter mark termination due
- // to write barriers performed after the completion barrier above.
- // Detect this and resume concurrent mark. This is obviously
- // unfortunate.
- //
- // See issue #27993 for details.
- //
- // Switch to the system stack to call wbBufFlush1, though in this case
- // it doesn't matter because we're non-preemptible anyway.
- restart := false
- systemstack(func() {
- for _, p := range allp {
- wbBufFlush1(p)
- if !p.gcw.empty() {
- restart = true
- break
- }
- }
- })
- if restart {
- getg().m.preemptoff = ""
- systemstack(func() {
- now := startTheWorldWithSema(trace.enabled)
- work.pauseNS += now - work.pauseStart
- memstats.gcPauseDist.record(now - work.pauseStart)
- })
- semrelease(&worldsema)
- goto top
- }
-
- gcComputeStartingStackSize()
-
- // Disable assists and background workers. We must do
- // this before waking blocked assists.
- atomic.Store(&gcBlackenEnabled, 0)
-
- // Notify the CPU limiter that GC assists will now cease.
- gcCPULimiter.startGCTransition(false, now)
-
- // Wake all blocked assists. These will run when we
- // start the world again.
- gcWakeAllAssists()
-
- // Likewise, release the transition lock. Blocked
- // workers and assists will run when we start the
- // world again.
- semrelease(&work.markDoneSema)
-
- // In STW mode, re-enable user goroutines. These will be
- // queued to run after we start the world.
- schedEnableUser(true)
-
- // endCycle depends on all gcWork cache stats being flushed.
- // The termination algorithm above ensured that up to
- // allocations since the ragged barrier.
- gcController.endCycle(now, int(gomaxprocs), work.userForced)
-
- // Perform mark termination. This will restart the world.
- gcMarkTermination()
-}
-
-// World must be stopped and mark assists and background workers must be
-// disabled.
-func gcMarkTermination() {
- // Start marktermination (write barrier remains enabled for now).
- setGCPhase(_GCmarktermination)
-
- work.heap1 = gcController.heapLive.Load()
- startTime := nanotime()
-
- mp := acquirem()
- mp.preemptoff = "gcing"
- mp.traceback = 2
- curgp := mp.curg
- casGToWaiting(curgp, _Grunning, waitReasonGarbageCollection)
-
- // Run gc on the g0 stack. We do this so that the g stack
- // we're currently running on will no longer change. Cuts
- // the root set down a bit (g0 stacks are not scanned, and
- // we don't need to scan gc's internal state). We also
- // need to switch to g0 so we can shrink the stack.
- systemstack(func() {
- gcMark(startTime)
- // Must return immediately.
- // The outer function's stack may have moved
- // during gcMark (it shrinks stacks, including the
- // outer function's stack), so we must not refer
- // to any of its variables. Return back to the
- // non-system stack to pick up the new addresses
- // before continuing.
- })
-
- systemstack(func() {
- work.heap2 = work.bytesMarked
- if debug.gccheckmark > 0 {
- // Run a full non-parallel, stop-the-world
- // mark using checkmark bits, to check that we
- // didn't forget to mark anything during the
- // concurrent mark process.
- startCheckmarks()
- gcResetMarkState()
- gcw := &getg().m.p.ptr().gcw
- gcDrain(gcw, 0)
- wbBufFlush1(getg().m.p.ptr())
- gcw.dispose()
- endCheckmarks()
- }
-
- // marking is complete so we can turn the write barrier off
- setGCPhase(_GCoff)
- gcSweep(work.mode)
- })
-
- mp.traceback = 0
- casgstatus(curgp, _Gwaiting, _Grunning)
-
- if trace.enabled {
- traceGCDone()
- }
-
- // all done
- mp.preemptoff = ""
-
- if gcphase != _GCoff {
- throw("gc done but gcphase != _GCoff")
- }
-
- // Record heapInUse for scavenger.
- memstats.lastHeapInUse = gcController.heapInUse.load()
-
- // Update GC trigger and pacing, as well as downstream consumers
- // of this pacing information, for the next cycle.
- systemstack(gcControllerCommit)
-
- // Update timing memstats
- now := nanotime()
- sec, nsec, _ := time_now()
- unixNow := sec*1e9 + int64(nsec)
- work.pauseNS += now - work.pauseStart
- work.tEnd = now
- memstats.gcPauseDist.record(now - work.pauseStart)
- atomic.Store64(&memstats.last_gc_unix, uint64(unixNow)) // must be Unix time to make sense to user
- atomic.Store64(&memstats.last_gc_nanotime, uint64(now)) // monotonic time for us
- memstats.pause_ns[memstats.numgc%uint32(len(memstats.pause_ns))] = uint64(work.pauseNS)
- memstats.pause_end[memstats.numgc%uint32(len(memstats.pause_end))] = uint64(unixNow)
- memstats.pause_total_ns += uint64(work.pauseNS)
-
- sweepTermCpu := int64(work.stwprocs) * (work.tMark - work.tSweepTerm)
- // We report idle marking time below, but omit it from the
- // overall utilization here since it's "free".
- markAssistCpu := gcController.assistTime.Load()
- markDedicatedCpu := gcController.dedicatedMarkTime.Load()
- markFractionalCpu := gcController.fractionalMarkTime.Load()
- markIdleCpu := gcController.idleMarkTime.Load()
- markTermCpu := int64(work.stwprocs) * (work.tEnd - work.tMarkTerm)
- scavAssistCpu := scavenge.assistTime.Load()
- scavBgCpu := scavenge.backgroundTime.Load()
-
- // Update cumulative GC CPU stats.
- work.cpuStats.gcAssistTime += markAssistCpu
- work.cpuStats.gcDedicatedTime += markDedicatedCpu + markFractionalCpu
- work.cpuStats.gcIdleTime += markIdleCpu
- work.cpuStats.gcPauseTime += sweepTermCpu + markTermCpu
- work.cpuStats.gcTotalTime += sweepTermCpu + markAssistCpu + markDedicatedCpu + markFractionalCpu + markIdleCpu + markTermCpu
-
- // Update cumulative scavenge CPU stats.
- work.cpuStats.scavengeAssistTime += scavAssistCpu
- work.cpuStats.scavengeBgTime += scavBgCpu
- work.cpuStats.scavengeTotalTime += scavAssistCpu + scavBgCpu
-
- // Update total CPU.
- work.cpuStats.totalTime = sched.totaltime + (now-sched.procresizetime)*int64(gomaxprocs)
- work.cpuStats.idleTime += sched.idleTime.Load()
-
- // Compute userTime. We compute this indirectly as everything that's not the above.
- //
- // Since time spent in _Pgcstop is covered by gcPauseTime, and time spent in _Pidle
- // is covered by idleTime, what we're left with is time spent in _Prunning and _Psyscall,
- // the latter of which is fine because the P will either go idle or get used for something
- // else via sysmon. Meanwhile if we subtract GC time from whatever's left, we get non-GC
- // _Prunning time. Note that this still leaves time spent in sweeping and in the scheduler,
- // but that's fine. The overwhelming majority of this time will be actual user time.
- work.cpuStats.userTime = work.cpuStats.totalTime - (work.cpuStats.gcTotalTime +
- work.cpuStats.scavengeTotalTime + work.cpuStats.idleTime)
-
- // Compute overall GC CPU utilization.
- // Omit idle marking time from the overall utilization here since it's "free".
- memstats.gc_cpu_fraction = float64(work.cpuStats.gcTotalTime-work.cpuStats.gcIdleTime) / float64(work.cpuStats.totalTime)
-
- // Reset assist time and background time stats.
- //
- // Do this now, instead of at the start of the next GC cycle, because
- // these two may keep accumulating even if the GC is not active.
- scavenge.assistTime.Store(0)
- scavenge.backgroundTime.Store(0)
-
- // Reset idle time stat.
- sched.idleTime.Store(0)
-
- // Reset sweep state.
- sweep.nbgsweep = 0
- sweep.npausesweep = 0
-
- if work.userForced {
- memstats.numforcedgc++
- }
-
- // Bump GC cycle count and wake goroutines waiting on sweep.
- lock(&work.sweepWaiters.lock)
- memstats.numgc++
- injectglist(&work.sweepWaiters.list)
- unlock(&work.sweepWaiters.lock)
-
- // Release the CPU limiter.
- gcCPULimiter.finishGCTransition(now)
-
- // Finish the current heap profiling cycle and start a new
- // heap profiling cycle. We do this before starting the world
- // so events don't leak into the wrong cycle.
- mProf_NextCycle()
-
- // There may be stale spans in mcaches that need to be swept.
- // Those aren't tracked in any sweep lists, so we need to
- // count them against sweep completion until we ensure all
- // those spans have been forced out.
- sl := sweep.active.begin()
- if !sl.valid {
- throw("failed to set sweep barrier")
- }
-
- systemstack(func() { startTheWorldWithSema(trace.enabled) })
-
- // Flush the heap profile so we can start a new cycle next GC.
- // This is relatively expensive, so we don't do it with the
- // world stopped.
- mProf_Flush()
-
- // Prepare workbufs for freeing by the sweeper. We do this
- // asynchronously because it can take non-trivial time.
- prepareFreeWorkbufs()
-
- // Free stack spans. This must be done between GC cycles.
- systemstack(freeStackSpans)
-
- // Ensure all mcaches are flushed. Each P will flush its own
- // mcache before allocating, but idle Ps may not. Since this
- // is necessary to sweep all spans, we need to ensure all
- // mcaches are flushed before we start the next GC cycle.
- systemstack(func() {
- forEachP(func(pp *p) {
- pp.mcache.prepareForSweep()
- })
- })
- // Now that we've swept stale spans in mcaches, they don't
- // count against unswept spans.
- sweep.active.end(sl)
-
- // Print gctrace before dropping worldsema. As soon as we drop
- // worldsema another cycle could start and smash the stats
- // we're trying to print.
- if debug.gctrace > 0 {
- util := int(memstats.gc_cpu_fraction * 100)
-
- var sbuf [24]byte
- printlock()
- print("gc ", memstats.numgc,
- " @", string(itoaDiv(sbuf[:], uint64(work.tSweepTerm-runtimeInitTime)/1e6, 3)), "s ",
- util, "%: ")
- prev := work.tSweepTerm
- for i, ns := range []int64{work.tMark, work.tMarkTerm, work.tEnd} {
- if i != 0 {
- print("+")
- }
- print(string(fmtNSAsMS(sbuf[:], uint64(ns-prev))))
- prev = ns
- }
- print(" ms clock, ")
- for i, ns := range []int64{
- sweepTermCpu,
- gcController.assistTime.Load(),
- gcController.dedicatedMarkTime.Load() + gcController.fractionalMarkTime.Load(),
- gcController.idleMarkTime.Load(),
- markTermCpu,
- } {
- if i == 2 || i == 3 {
- // Separate mark time components with /.
- print("/")
- } else if i != 0 {
- print("+")
- }
- print(string(fmtNSAsMS(sbuf[:], uint64(ns))))
- }
- print(" ms cpu, ",
- work.heap0>>20, "->", work.heap1>>20, "->", work.heap2>>20, " MB, ",
- gcController.lastHeapGoal>>20, " MB goal, ",
- gcController.lastStackScan.Load()>>20, " MB stacks, ",
- gcController.globalsScan.Load()>>20, " MB globals, ",
- work.maxprocs, " P")
- if work.userForced {
- print(" (forced)")
- }
- print("\n")
- printunlock()
- }
-
- // Set any arena chunks that were deferred to fault.
- lock(&userArenaState.lock)
- faultList := userArenaState.fault
- userArenaState.fault = nil
- unlock(&userArenaState.lock)
- for _, lc := range faultList {
- lc.mspan.setUserArenaChunkToFault()
- }
-
- semrelease(&worldsema)
- semrelease(&gcsema)
- // Careful: another GC cycle may start now.
-
- releasem(mp)
- mp = nil
-
- // now that gc is done, kick off finalizer thread if needed
- if !concurrentSweep {
- // give the queued finalizers, if any, a chance to run
- Gosched()
- }
-}
-
-// gcBgMarkStartWorkers prepares background mark worker goroutines. These
-// goroutines will not run until the mark phase, but they must be started while
-// the work is not stopped and from a regular G stack. The caller must hold
-// worldsema.
-func gcBgMarkStartWorkers() {
- // Background marking is performed by per-P G's. Ensure that each P has
- // a background GC G.
- //
- // Worker Gs don't exit if gomaxprocs is reduced. If it is raised
- // again, we can reuse the old workers; no need to create new workers.
- for gcBgMarkWorkerCount < gomaxprocs {
- go gcBgMarkWorker()
-
- notetsleepg(&work.bgMarkReady, -1)
- noteclear(&work.bgMarkReady)
- // The worker is now guaranteed to be added to the pool before
- // its P's next findRunnableGCWorker.
-
- gcBgMarkWorkerCount++
- }
-}
-
-// gcBgMarkPrepare sets up state for background marking.
-// Mutator assists must not yet be enabled.
-func gcBgMarkPrepare() {
- // Background marking will stop when the work queues are empty
- // and there are no more workers (note that, since this is
- // concurrent, this may be a transient state, but mark
- // termination will clean it up). Between background workers
- // and assists, we don't really know how many workers there
- // will be, so we pretend to have an arbitrarily large number
- // of workers, almost all of which are "waiting". While a
- // worker is working it decrements nwait. If nproc == nwait,
- // there are no workers.
- work.nproc = ^uint32(0)
- work.nwait = ^uint32(0)
-}
-
-// gcBgMarkWorkerNode is an entry in the gcBgMarkWorkerPool. It points to a single
-// gcBgMarkWorker goroutine.
-type gcBgMarkWorkerNode struct {
- // Unused workers are managed in a lock-free stack. This field must be first.
- node lfnode
-
- // The g of this worker.
- gp guintptr
-
- // Release this m on park. This is used to communicate with the unlock
- // function, which cannot access the G's stack. It is unused outside of
- // gcBgMarkWorker().
- m muintptr
-}
-
-func gcBgMarkWorker() {
- gp := getg()
-
- // We pass node to a gopark unlock function, so it can't be on
- // the stack (see gopark). Prevent deadlock from recursively
- // starting GC by disabling preemption.
- gp.m.preemptoff = "GC worker init"
- node := new(gcBgMarkWorkerNode)
- gp.m.preemptoff = ""
-
- node.gp.set(gp)
-
- node.m.set(acquirem())
- notewakeup(&work.bgMarkReady)
- // After this point, the background mark worker is generally scheduled
- // cooperatively by gcController.findRunnableGCWorker. While performing
- // work on the P, preemption is disabled because we are working on
- // P-local work buffers. When the preempt flag is set, this puts itself
- // into _Gwaiting to be woken up by gcController.findRunnableGCWorker
- // at the appropriate time.
- //
- // When preemption is enabled (e.g., while in gcMarkDone), this worker
- // may be preempted and schedule as a _Grunnable G from a runq. That is
- // fine; it will eventually gopark again for further scheduling via
- // findRunnableGCWorker.
- //
- // Since we disable preemption before notifying bgMarkReady, we
- // guarantee that this G will be in the worker pool for the next
- // findRunnableGCWorker. This isn't strictly necessary, but it reduces
- // latency between _GCmark starting and the workers starting.
-
- for {
- // Go to sleep until woken by
- // gcController.findRunnableGCWorker.
- gopark(func(g *g, nodep unsafe.Pointer) bool {
- node := (*gcBgMarkWorkerNode)(nodep)
-
- if mp := node.m.ptr(); mp != nil {
- // The worker G is no longer running; release
- // the M.
- //
- // N.B. it is _safe_ to release the M as soon
- // as we are no longer performing P-local mark
- // work.
- //
- // However, since we cooperatively stop work
- // when gp.preempt is set, if we releasem in
- // the loop then the following call to gopark
- // would immediately preempt the G. This is
- // also safe, but inefficient: the G must
- // schedule again only to enter gopark and park
- // again. Thus, we defer the release until
- // after parking the G.
- releasem(mp)
- }
-
- // Release this G to the pool.
- gcBgMarkWorkerPool.push(&node.node)
- // Note that at this point, the G may immediately be
- // rescheduled and may be running.
- return true
- }, unsafe.Pointer(node), waitReasonGCWorkerIdle, traceEvGoBlock, 0)
-
- // Preemption must not occur here, or another G might see
- // p.gcMarkWorkerMode.
-
- // Disable preemption so we can use the gcw. If the
- // scheduler wants to preempt us, we'll stop draining,
- // dispose the gcw, and then preempt.
- node.m.set(acquirem())
- pp := gp.m.p.ptr() // P can't change with preemption disabled.
-
- if gcBlackenEnabled == 0 {
- println("worker mode", pp.gcMarkWorkerMode)
- throw("gcBgMarkWorker: blackening not enabled")
- }
-
- if pp.gcMarkWorkerMode == gcMarkWorkerNotWorker {
- throw("gcBgMarkWorker: mode not set")
- }
-
- startTime := nanotime()
- pp.gcMarkWorkerStartTime = startTime
- var trackLimiterEvent bool
- if pp.gcMarkWorkerMode == gcMarkWorkerIdleMode {
- trackLimiterEvent = pp.limiterEvent.start(limiterEventIdleMarkWork, startTime)
- }
-
- decnwait := atomic.Xadd(&work.nwait, -1)
- if decnwait == work.nproc {
- println("runtime: work.nwait=", decnwait, "work.nproc=", work.nproc)
- throw("work.nwait was > work.nproc")
- }
-
- systemstack(func() {
- // Mark our goroutine preemptible so its stack
- // can be scanned. This lets two mark workers
- // scan each other (otherwise, they would
- // deadlock). We must not modify anything on
- // the G stack. However, stack shrinking is
- // disabled for mark workers, so it is safe to
- // read from the G stack.
- casGToWaiting(gp, _Grunning, waitReasonGCWorkerActive)
- switch pp.gcMarkWorkerMode {
- default:
- throw("gcBgMarkWorker: unexpected gcMarkWorkerMode")
- case gcMarkWorkerDedicatedMode:
- gcDrain(&pp.gcw, gcDrainUntilPreempt|gcDrainFlushBgCredit)
- if gp.preempt {
- // We were preempted. This is
- // a useful signal to kick
- // everything out of the run
- // queue so it can run
- // somewhere else.
- if drainQ, n := runqdrain(pp); n > 0 {
- lock(&sched.lock)
- globrunqputbatch(&drainQ, int32(n))
- unlock(&sched.lock)
- }
- }
- // Go back to draining, this time
- // without preemption.
- gcDrain(&pp.gcw, gcDrainFlushBgCredit)
- case gcMarkWorkerFractionalMode:
- gcDrain(&pp.gcw, gcDrainFractional|gcDrainUntilPreempt|gcDrainFlushBgCredit)
- case gcMarkWorkerIdleMode:
- gcDrain(&pp.gcw, gcDrainIdle|gcDrainUntilPreempt|gcDrainFlushBgCredit)
- }
- casgstatus(gp, _Gwaiting, _Grunning)
- })
-
- // Account for time and mark us as stopped.
- now := nanotime()
- duration := now - startTime
- gcController.markWorkerStop(pp.gcMarkWorkerMode, duration)
- if trackLimiterEvent {
- pp.limiterEvent.stop(limiterEventIdleMarkWork, now)
- }
- if pp.gcMarkWorkerMode == gcMarkWorkerFractionalMode {
- atomic.Xaddint64(&pp.gcFractionalMarkTime, duration)
- }
-
- // Was this the last worker and did we run out
- // of work?
- incnwait := atomic.Xadd(&work.nwait, +1)
- if incnwait > work.nproc {
- println("runtime: p.gcMarkWorkerMode=", pp.gcMarkWorkerMode,
- "work.nwait=", incnwait, "work.nproc=", work.nproc)
- throw("work.nwait > work.nproc")
- }
-
- // We'll releasem after this point and thus this P may run
- // something else. We must clear the worker mode to avoid
- // attributing the mode to a different (non-worker) G in
- // traceGoStart.
- pp.gcMarkWorkerMode = gcMarkWorkerNotWorker
-
- // If this worker reached a background mark completion
- // point, signal the main GC goroutine.
- if incnwait == work.nproc && !gcMarkWorkAvailable(nil) {
- // We don't need the P-local buffers here, allow
- // preemption because we may schedule like a regular
- // goroutine in gcMarkDone (block on locks, etc).
- releasem(node.m.ptr())
- node.m.set(nil)
-
- gcMarkDone()
- }
- }
-}
-
-// gcMarkWorkAvailable reports whether executing a mark worker
-// on p is potentially useful. p may be nil, in which case it only
-// checks the global sources of work.
-func gcMarkWorkAvailable(p *p) bool {
- if p != nil && !p.gcw.empty() {
- return true
- }
- if !work.full.empty() {
- return true // global work available
- }
- if work.markrootNext < work.markrootJobs {
- return true // root scan work available
- }
- return false
-}
-
-// gcMark runs the mark (or, for concurrent GC, mark termination)
-// All gcWork caches must be empty.
-// STW is in effect at this point.
-func gcMark(startTime int64) {
- if debug.allocfreetrace > 0 {
- tracegc()
- }
-
- if gcphase != _GCmarktermination {
- throw("in gcMark expecting to see gcphase as _GCmarktermination")
- }
- work.tstart = startTime
-
- // Check that there's no marking work remaining.
- if work.full != 0 || work.markrootNext < work.markrootJobs {
- print("runtime: full=", hex(work.full), " next=", work.markrootNext, " jobs=", work.markrootJobs, " nDataRoots=", work.nDataRoots, " nBSSRoots=", work.nBSSRoots, " nSpanRoots=", work.nSpanRoots, " nStackRoots=", work.nStackRoots, "\n")
- panic("non-empty mark queue after concurrent mark")
- }
-
- if debug.gccheckmark > 0 {
- // This is expensive when there's a large number of
- // Gs, so only do it if checkmark is also enabled.
- gcMarkRootCheck()
- }
- if work.full != 0 {
- throw("work.full != 0")
- }
-
- // Drop allg snapshot. allgs may have grown, in which case
- // this is the only reference to the old backing store and
- // there's no need to keep it around.
- work.stackRoots = nil
-
- // Clear out buffers and double-check that all gcWork caches
- // are empty. This should be ensured by gcMarkDone before we
- // enter mark termination.
- //
- // TODO: We could clear out buffers just before mark if this
- // has a non-negligible impact on STW time.
- for _, p := range allp {
- // The write barrier may have buffered pointers since
- // the gcMarkDone barrier. However, since the barrier
- // ensured all reachable objects were marked, all of
- // these must be pointers to black objects. Hence we
- // can just discard the write barrier buffer.
- if debug.gccheckmark > 0 {
- // For debugging, flush the buffer and make
- // sure it really was all marked.
- wbBufFlush1(p)
- } else {
- p.wbBuf.reset()
- }
-
- gcw := &p.gcw
- if !gcw.empty() {
- printlock()
- print("runtime: P ", p.id, " flushedWork ", gcw.flushedWork)
- if gcw.wbuf1 == nil {
- print(" wbuf1=<nil>")
- } else {
- print(" wbuf1.n=", gcw.wbuf1.nobj)
- }
- if gcw.wbuf2 == nil {
- print(" wbuf2=<nil>")
- } else {
- print(" wbuf2.n=", gcw.wbuf2.nobj)
- }
- print("\n")
- throw("P has cached GC work at end of mark termination")
- }
- // There may still be cached empty buffers, which we
- // need to flush since we're going to free them. Also,
- // there may be non-zero stats because we allocated
- // black after the gcMarkDone barrier.
- gcw.dispose()
- }
-
- // Flush scanAlloc from each mcache since we're about to modify
- // heapScan directly. If we were to flush this later, then scanAlloc
- // might have incorrect information.
- //
- // Note that it's not important to retain this information; we know
- // exactly what heapScan is at this point via scanWork.
- for _, p := range allp {
- c := p.mcache
- if c == nil {
- continue
- }
- c.scanAlloc = 0
- }
-
- // Reset controller state.
- gcController.resetLive(work.bytesMarked)
-}
-
-// gcSweep must be called on the system stack because it acquires the heap
-// lock. See mheap for details.
-//
-// The world must be stopped.
-//
-//go:systemstack
-func gcSweep(mode gcMode) {
- assertWorldStopped()
-
- if gcphase != _GCoff {
- throw("gcSweep being done but phase is not GCoff")
- }
-
- lock(&mheap_.lock)
- mheap_.sweepgen += 2
- sweep.active.reset()
- mheap_.pagesSwept.Store(0)
- mheap_.sweepArenas = mheap_.allArenas
- mheap_.reclaimIndex.Store(0)
- mheap_.reclaimCredit.Store(0)
- unlock(&mheap_.lock)
-
- sweep.centralIndex.clear()
-
- if !_ConcurrentSweep || mode == gcForceBlockMode {
- // Special case synchronous sweep.
- // Record that no proportional sweeping has to happen.
- lock(&mheap_.lock)
- mheap_.sweepPagesPerByte = 0
- unlock(&mheap_.lock)
- // Sweep all spans eagerly.
- for sweepone() != ^uintptr(0) {
- sweep.npausesweep++
- }
- // Free workbufs eagerly.
- prepareFreeWorkbufs()
- for freeSomeWbufs(false) {
- }
- // All "free" events for this mark/sweep cycle have
- // now happened, so we can make this profile cycle
- // available immediately.
- mProf_NextCycle()
- mProf_Flush()
- return
- }
-
- // Background sweep.
- lock(&sweep.lock)
- if sweep.parked {
- sweep.parked = false
- ready(sweep.g, 0, true)
- }
- unlock(&sweep.lock)
-}
-
-// gcResetMarkState resets global state prior to marking (concurrent
-// or STW) and resets the stack scan state of all Gs.
-//
-// This is safe to do without the world stopped because any Gs created
-// during or after this will start out in the reset state.
-//
-// gcResetMarkState must be called on the system stack because it acquires
-// the heap lock. See mheap for details.
-//
-//go:systemstack
-func gcResetMarkState() {
- // This may be called during a concurrent phase, so lock to make sure
- // allgs doesn't change.
- forEachG(func(gp *g) {
- gp.gcscandone = false // set to true in gcphasework
- gp.gcAssistBytes = 0
- })
-
- // Clear page marks. This is just 1MB per 64GB of heap, so the
- // time here is pretty trivial.
- lock(&mheap_.lock)
- arenas := mheap_.allArenas
- unlock(&mheap_.lock)
- for _, ai := range arenas {
- ha := mheap_.arenas[ai.l1()][ai.l2()]
- for i := range ha.pageMarks {
- ha.pageMarks[i] = 0
- }
- }
-
- work.bytesMarked = 0
- work.initialHeapLive = gcController.heapLive.Load()
-}
-
-// Hooks for other packages
-
-var poolcleanup func()
-var boringCaches []unsafe.Pointer // for crypto/internal/boring
-
-//go:linkname sync_runtime_registerPoolCleanup sync.runtime_registerPoolCleanup
-func sync_runtime_registerPoolCleanup(f func()) {
- poolcleanup = f
-}
-
-//go:linkname boring_registerCache crypto/internal/boring/bcache.registerCache
-func boring_registerCache(p unsafe.Pointer) {
- boringCaches = append(boringCaches, p)
-}
-
-func clearpools() {
- // clear sync.Pools
- if poolcleanup != nil {
- poolcleanup()
- }
-
- // clear boringcrypto caches
- for _, p := range boringCaches {
- atomicstorep(p, nil)
- }
-
- // Clear central sudog cache.
- // Leave per-P caches alone, they have strictly bounded size.
- // Disconnect cached list before dropping it on the floor,
- // so that a dangling ref to one entry does not pin all of them.
- lock(&sched.sudoglock)
- var sg, sgnext *sudog
- for sg = sched.sudogcache; sg != nil; sg = sgnext {
- sgnext = sg.next
- sg.next = nil
- }
- sched.sudogcache = nil
- unlock(&sched.sudoglock)
-
- // Clear central defer pool.
- // Leave per-P pools alone, they have strictly bounded size.
- lock(&sched.deferlock)
- // disconnect cached list before dropping it on the floor,
- // so that a dangling ref to one entry does not pin all of them.
- var d, dlink *_defer
- for d = sched.deferpool; d != nil; d = dlink {
- dlink = d.link
- d.link = nil
- }
- sched.deferpool = nil
- unlock(&sched.deferlock)
-}
-
-// Timing
-
-// itoaDiv formats val/(10**dec) into buf.
-func itoaDiv(buf []byte, val uint64, dec int) []byte {
- i := len(buf) - 1
- idec := i - dec
- for val >= 10 || i >= idec {
- buf[i] = byte(val%10 + '0')
- i--
- if i == idec {
- buf[i] = '.'
- i--
- }
- val /= 10
- }
- buf[i] = byte(val + '0')
- return buf[i:]
-}
-
-// fmtNSAsMS nicely formats ns nanoseconds as milliseconds.
-func fmtNSAsMS(buf []byte, ns uint64) []byte {
- if ns >= 10e6 {
- // Format as whole milliseconds.
- return itoaDiv(buf, ns/1e6, 0)
- }
- // Format two digits of precision, with at most three decimal places.
- x := ns / 1e3
- if x == 0 {
- buf[0] = '0'
- return buf[:1]
- }
- dec := 3
- for x >= 100 {
- x /= 10
- dec--
- }
- return itoaDiv(buf, x, dec)
-}
-
-// Helpers for testing GC.
-
-// gcTestMoveStackOnNextCall causes the stack to be moved on a call
-// immediately following the call to this. It may not work correctly
-// if any other work appears after this call (such as returning).
-// Typically the following call should be marked go:noinline so it
-// performs a stack check.
-//
-// In rare cases this may not cause the stack to move, specifically if
-// there's a preemption between this call and the next.
-func gcTestMoveStackOnNextCall() {
- gp := getg()
- gp.stackguard0 = stackForceMove
-}
-
-// gcTestIsReachable performs a GC and returns a bit set where bit i
-// is set if ptrs[i] is reachable.
-func gcTestIsReachable(ptrs ...unsafe.Pointer) (mask uint64) {
- // This takes the pointers as unsafe.Pointers in order to keep
- // them live long enough for us to attach specials. After
- // that, we drop our references to them.
-
- if len(ptrs) > 64 {
- panic("too many pointers for uint64 mask")
- }
-
- // Block GC while we attach specials and drop our references
- // to ptrs. Otherwise, if a GC is in progress, it could mark
- // them reachable via this function before we have a chance to
- // drop them.
- semacquire(&gcsema)
-
- // Create reachability specials for ptrs.
- specials := make([]*specialReachable, len(ptrs))
- for i, p := range ptrs {
- lock(&mheap_.speciallock)
- s := (*specialReachable)(mheap_.specialReachableAlloc.alloc())
- unlock(&mheap_.speciallock)
- s.special.kind = _KindSpecialReachable
- if !addspecial(p, &s.special) {
- throw("already have a reachable special (duplicate pointer?)")
- }
- specials[i] = s
- // Make sure we don't retain ptrs.
- ptrs[i] = nil
- }
-
- semrelease(&gcsema)
-
- // Force a full GC and sweep.
- GC()
-
- // Process specials.
- for i, s := range specials {
- if !s.done {
- printlock()
- println("runtime: object", i, "was not swept")
- throw("IsReachable failed")
- }
- if s.reachable {
- mask |= 1 << i
- }
- lock(&mheap_.speciallock)
- mheap_.specialReachableAlloc.free(unsafe.Pointer(s))
- unlock(&mheap_.speciallock)
- }
-
- return mask
-}
-
-// gcTestPointerClass returns the category of what p points to, one of:
-// "heap", "stack", "data", "bss", "other". This is useful for checking
-// that a test is doing what it's intended to do.
-//
-// This is nosplit simply to avoid extra pointer shuffling that may
-// complicate a test.
-//
-//go:nosplit
-func gcTestPointerClass(p unsafe.Pointer) string {
- p2 := uintptr(noescape(p))
- gp := getg()
- if gp.stack.lo <= p2 && p2 < gp.stack.hi {
- return "stack"
- }
- if base, _, _ := findObject(p2, 0, 0); base != 0 {
- return "heap"
- }
- for _, datap := range activeModules() {
- if datap.data <= p2 && p2 < datap.edata || datap.noptrdata <= p2 && p2 < datap.enoptrdata {
- return "data"
- }
- if datap.bss <= p2 && p2 < datap.ebss || datap.noptrbss <= p2 && p2 <= datap.enoptrbss {
- return "bss"
- }
- }
- KeepAlive(p)
- return "other"
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mgclimit.go b/contrib/go/_std_1.20/src/runtime/mgclimit.go
deleted file mode 100644
index bcbe7f88a0..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mgclimit.go
+++ /dev/null
@@ -1,483 +0,0 @@
-// Copyright 2022 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 runtime
-
-import "runtime/internal/atomic"
-
-// gcCPULimiter is a mechanism to limit GC CPU utilization in situations
-// where it might become excessive and inhibit application progress (e.g.
-// a death spiral).
-//
-// The core of the limiter is a leaky bucket mechanism that fills with GC
-// CPU time and drains with mutator time. Because the bucket fills and
-// drains with time directly (i.e. without any weighting), this effectively
-// sets a very conservative limit of 50%. This limit could be enforced directly,
-// however, but the purpose of the bucket is to accommodate spikes in GC CPU
-// utilization without hurting throughput.
-//
-// Note that the bucket in the leaky bucket mechanism can never go negative,
-// so the GC never gets credit for a lot of CPU time spent without the GC
-// running. This is intentional, as an application that stays idle for, say,
-// an entire day, could build up enough credit to fail to prevent a death
-// spiral the following day. The bucket's capacity is the GC's only leeway.
-//
-// The capacity thus also sets the window the limiter considers. For example,
-// if the capacity of the bucket is 1 cpu-second, then the limiter will not
-// kick in until at least 1 full cpu-second in the last 2 cpu-second window
-// is spent on GC CPU time.
-var gcCPULimiter gcCPULimiterState
-
-type gcCPULimiterState struct {
- lock atomic.Uint32
-
- enabled atomic.Bool
- bucket struct {
- // Invariants:
- // - fill >= 0
- // - capacity >= 0
- // - fill <= capacity
- fill, capacity uint64
- }
- // overflow is the cumulative amount of GC CPU time that we tried to fill the
- // bucket with but exceeded its capacity.
- overflow uint64
-
- // gcEnabled is an internal copy of gcBlackenEnabled that determines
- // whether the limiter tracks total assist time.
- //
- // gcBlackenEnabled isn't used directly so as to keep this structure
- // unit-testable.
- gcEnabled bool
-
- // transitioning is true when the GC is in a STW and transitioning between
- // the mark and sweep phases.
- transitioning bool
-
- // assistTimePool is the accumulated assist time since the last update.
- assistTimePool atomic.Int64
-
- // idleMarkTimePool is the accumulated idle mark time since the last update.
- idleMarkTimePool atomic.Int64
-
- // idleTimePool is the accumulated time Ps spent on the idle list since the last update.
- idleTimePool atomic.Int64
-
- // lastUpdate is the nanotime timestamp of the last time update was called.
- //
- // Updated under lock, but may be read concurrently.
- lastUpdate atomic.Int64
-
- // lastEnabledCycle is the GC cycle that last had the limiter enabled.
- lastEnabledCycle atomic.Uint32
-
- // nprocs is an internal copy of gomaxprocs, used to determine total available
- // CPU time.
- //
- // gomaxprocs isn't used directly so as to keep this structure unit-testable.
- nprocs int32
-
- // test indicates whether this instance of the struct was made for testing purposes.
- test bool
-}
-
-// limiting returns true if the CPU limiter is currently enabled, meaning the Go GC
-// should take action to limit CPU utilization.
-//
-// It is safe to call concurrently with other operations.
-func (l *gcCPULimiterState) limiting() bool {
- return l.enabled.Load()
-}
-
-// startGCTransition notifies the limiter of a GC transition.
-//
-// This call takes ownership of the limiter and disables all other means of
-// updating the limiter. Release ownership by calling finishGCTransition.
-//
-// It is safe to call concurrently with other operations.
-func (l *gcCPULimiterState) startGCTransition(enableGC bool, now int64) {
- if !l.tryLock() {
- // This must happen during a STW, so we can't fail to acquire the lock.
- // If we did, something went wrong. Throw.
- throw("failed to acquire lock to start a GC transition")
- }
- if l.gcEnabled == enableGC {
- throw("transitioning GC to the same state as before?")
- }
- // Flush whatever was left between the last update and now.
- l.updateLocked(now)
- l.gcEnabled = enableGC
- l.transitioning = true
- // N.B. finishGCTransition releases the lock.
- //
- // We don't release here to increase the chance that if there's a failure
- // to finish the transition, that we throw on failing to acquire the lock.
-}
-
-// finishGCTransition notifies the limiter that the GC transition is complete
-// and releases ownership of it. It also accumulates STW time in the bucket.
-// now must be the timestamp from the end of the STW pause.
-func (l *gcCPULimiterState) finishGCTransition(now int64) {
- if !l.transitioning {
- throw("finishGCTransition called without starting one?")
- }
- // Count the full nprocs set of CPU time because the world is stopped
- // between startGCTransition and finishGCTransition. Even though the GC
- // isn't running on all CPUs, it is preventing user code from doing so,
- // so it might as well be.
- if lastUpdate := l.lastUpdate.Load(); now >= lastUpdate {
- l.accumulate(0, (now-lastUpdate)*int64(l.nprocs))
- }
- l.lastUpdate.Store(now)
- l.transitioning = false
- l.unlock()
-}
-
-// gcCPULimiterUpdatePeriod dictates the maximum amount of wall-clock time
-// we can go before updating the limiter.
-const gcCPULimiterUpdatePeriod = 10e6 // 10ms
-
-// needUpdate returns true if the limiter's maximum update period has been
-// exceeded, and so would benefit from an update.
-func (l *gcCPULimiterState) needUpdate(now int64) bool {
- return now-l.lastUpdate.Load() > gcCPULimiterUpdatePeriod
-}
-
-// addAssistTime notifies the limiter of additional assist time. It will be
-// included in the next update.
-func (l *gcCPULimiterState) addAssistTime(t int64) {
- l.assistTimePool.Add(t)
-}
-
-// addIdleTime notifies the limiter of additional time a P spent on the idle list. It will be
-// subtracted from the total CPU time in the next update.
-func (l *gcCPULimiterState) addIdleTime(t int64) {
- l.idleTimePool.Add(t)
-}
-
-// update updates the bucket given runtime-specific information. now is the
-// current monotonic time in nanoseconds.
-//
-// This is safe to call concurrently with other operations, except *GCTransition.
-func (l *gcCPULimiterState) update(now int64) {
- if !l.tryLock() {
- // We failed to acquire the lock, which means something else is currently
- // updating. Just drop our update, the next one to update will include
- // our total assist time.
- return
- }
- if l.transitioning {
- throw("update during transition")
- }
- l.updateLocked(now)
- l.unlock()
-}
-
-// updatedLocked is the implementation of update. l.lock must be held.
-func (l *gcCPULimiterState) updateLocked(now int64) {
- lastUpdate := l.lastUpdate.Load()
- if now < lastUpdate {
- // Defensively avoid overflow. This isn't even the latest update anyway.
- return
- }
- windowTotalTime := (now - lastUpdate) * int64(l.nprocs)
- l.lastUpdate.Store(now)
-
- // Drain the pool of assist time.
- assistTime := l.assistTimePool.Load()
- if assistTime != 0 {
- l.assistTimePool.Add(-assistTime)
- }
-
- // Drain the pool of idle time.
- idleTime := l.idleTimePool.Load()
- if idleTime != 0 {
- l.idleTimePool.Add(-idleTime)
- }
-
- if !l.test {
- // Consume time from in-flight events. Make sure we're not preemptible so allp can't change.
- //
- // The reason we do this instead of just waiting for those events to finish and push updates
- // is to ensure that all the time we're accounting for happened sometime between lastUpdate
- // and now. This dramatically simplifies reasoning about the limiter because we're not at
- // risk of extra time being accounted for in this window than actually happened in this window,
- // leading to all sorts of weird transient behavior.
- mp := acquirem()
- for _, pp := range allp {
- typ, duration := pp.limiterEvent.consume(now)
- switch typ {
- case limiterEventIdleMarkWork:
- fallthrough
- case limiterEventIdle:
- idleTime += duration
- case limiterEventMarkAssist:
- fallthrough
- case limiterEventScavengeAssist:
- assistTime += duration
- case limiterEventNone:
- break
- default:
- throw("invalid limiter event type found")
- }
- }
- releasem(mp)
- }
-
- // Compute total GC time.
- windowGCTime := assistTime
- if l.gcEnabled {
- windowGCTime += int64(float64(windowTotalTime) * gcBackgroundUtilization)
- }
-
- // Subtract out all idle time from the total time. Do this after computing
- // GC time, because the background utilization is dependent on the *real*
- // total time, not the total time after idle time is subtracted.
- //
- // Idle time is counted as any time that a P is on the P idle list plus idle mark
- // time. Idle mark workers soak up time that the application spends idle.
- //
- // On a heavily undersubscribed system, any additional idle time can skew GC CPU
- // utilization, because the GC might be executing continuously and thrashing,
- // yet the CPU utilization with respect to GOMAXPROCS will be quite low, so
- // the limiter fails to turn on. By subtracting idle time, we're removing time that
- // we know the application was idle giving a more accurate picture of whether
- // the GC is thrashing.
- //
- // Note that this can cause the limiter to turn on even if it's not needed. For
- // instance, on a system with 32 Ps but only 1 running goroutine, each GC will have
- // 8 dedicated GC workers. Assuming the GC cycle is half mark phase and half sweep
- // phase, then the GC CPU utilization over that cycle, with idle time removed, will
- // be 8/(8+2) = 80%. Even though the limiter turns on, though, assist should be
- // unnecessary, as the GC has way more CPU time to outpace the 1 goroutine that's
- // running.
- windowTotalTime -= idleTime
-
- l.accumulate(windowTotalTime-windowGCTime, windowGCTime)
-}
-
-// accumulate adds time to the bucket and signals whether the limiter is enabled.
-//
-// This is an internal function that deals just with the bucket. Prefer update.
-// l.lock must be held.
-func (l *gcCPULimiterState) accumulate(mutatorTime, gcTime int64) {
- headroom := l.bucket.capacity - l.bucket.fill
- enabled := headroom == 0
-
- // Let's be careful about three things here:
- // 1. The addition and subtraction, for the invariants.
- // 2. Overflow.
- // 3. Excessive mutation of l.enabled, which is accessed
- // by all assists, potentially more than once.
- change := gcTime - mutatorTime
-
- // Handle limiting case.
- if change > 0 && headroom <= uint64(change) {
- l.overflow += uint64(change) - headroom
- l.bucket.fill = l.bucket.capacity
- if !enabled {
- l.enabled.Store(true)
- l.lastEnabledCycle.Store(memstats.numgc + 1)
- }
- return
- }
-
- // Handle non-limiting cases.
- if change < 0 && l.bucket.fill <= uint64(-change) {
- // Bucket emptied.
- l.bucket.fill = 0
- } else {
- // All other cases.
- l.bucket.fill -= uint64(-change)
- }
- if change != 0 && enabled {
- l.enabled.Store(false)
- }
-}
-
-// tryLock attempts to lock l. Returns true on success.
-func (l *gcCPULimiterState) tryLock() bool {
- return l.lock.CompareAndSwap(0, 1)
-}
-
-// unlock releases the lock on l. Must be called if tryLock returns true.
-func (l *gcCPULimiterState) unlock() {
- old := l.lock.Swap(0)
- if old != 1 {
- throw("double unlock")
- }
-}
-
-// capacityPerProc is the limiter's bucket capacity for each P in GOMAXPROCS.
-const capacityPerProc = 1e9 // 1 second in nanoseconds
-
-// resetCapacity updates the capacity based on GOMAXPROCS. Must not be called
-// while the GC is enabled.
-//
-// It is safe to call concurrently with other operations.
-func (l *gcCPULimiterState) resetCapacity(now int64, nprocs int32) {
- if !l.tryLock() {
- // This must happen during a STW, so we can't fail to acquire the lock.
- // If we did, something went wrong. Throw.
- throw("failed to acquire lock to reset capacity")
- }
- // Flush the rest of the time for this period.
- l.updateLocked(now)
- l.nprocs = nprocs
-
- l.bucket.capacity = uint64(nprocs) * capacityPerProc
- if l.bucket.fill > l.bucket.capacity {
- l.bucket.fill = l.bucket.capacity
- l.enabled.Store(true)
- l.lastEnabledCycle.Store(memstats.numgc + 1)
- } else if l.bucket.fill < l.bucket.capacity {
- l.enabled.Store(false)
- }
- l.unlock()
-}
-
-// limiterEventType indicates the type of an event occurring on some P.
-//
-// These events represent the full set of events that the GC CPU limiter tracks
-// to execute its function.
-//
-// This type may use no more than limiterEventBits bits of information.
-type limiterEventType uint8
-
-const (
- limiterEventNone limiterEventType = iota // None of the following events.
- limiterEventIdleMarkWork // Refers to an idle mark worker (see gcMarkWorkerMode).
- limiterEventMarkAssist // Refers to mark assist (see gcAssistAlloc).
- limiterEventScavengeAssist // Refers to a scavenge assist (see allocSpan).
- limiterEventIdle // Refers to time a P spent on the idle list.
-
- limiterEventBits = 3
-)
-
-// limiterEventTypeMask is a mask for the bits in p.limiterEventStart that represent
-// the event type. The rest of the bits of that field represent a timestamp.
-const (
- limiterEventTypeMask = uint64((1<<limiterEventBits)-1) << (64 - limiterEventBits)
- limiterEventStampNone = limiterEventStamp(0)
-)
-
-// limiterEventStamp is a nanotime timestamp packed with a limiterEventType.
-type limiterEventStamp uint64
-
-// makeLimiterEventStamp creates a new stamp from the event type and the current timestamp.
-func makeLimiterEventStamp(typ limiterEventType, now int64) limiterEventStamp {
- return limiterEventStamp(uint64(typ)<<(64-limiterEventBits) | (uint64(now) &^ limiterEventTypeMask))
-}
-
-// duration computes the difference between now and the start time stored in the stamp.
-//
-// Returns 0 if the difference is negative, which may happen if now is stale or if the
-// before and after timestamps cross a 2^(64-limiterEventBits) boundary.
-func (s limiterEventStamp) duration(now int64) int64 {
- // The top limiterEventBits bits of the timestamp are derived from the current time
- // when computing a duration.
- start := int64((uint64(now) & limiterEventTypeMask) | (uint64(s) &^ limiterEventTypeMask))
- if now < start {
- return 0
- }
- return now - start
-}
-
-// type extracts the event type from the stamp.
-func (s limiterEventStamp) typ() limiterEventType {
- return limiterEventType(s >> (64 - limiterEventBits))
-}
-
-// limiterEvent represents tracking state for an event tracked by the GC CPU limiter.
-type limiterEvent struct {
- stamp atomic.Uint64 // Stores a limiterEventStamp.
-}
-
-// start begins tracking a new limiter event of the current type. If an event
-// is already in flight, then a new event cannot begin because the current time is
-// already being attributed to that event. In this case, this function returns false.
-// Otherwise, it returns true.
-//
-// The caller must be non-preemptible until at least stop is called or this function
-// returns false. Because this is trying to measure "on-CPU" time of some event, getting
-// scheduled away during it can mean that whatever we're measuring isn't a reflection
-// of "on-CPU" time. The OS could deschedule us at any time, but we want to maintain as
-// close of an approximation as we can.
-func (e *limiterEvent) start(typ limiterEventType, now int64) bool {
- if limiterEventStamp(e.stamp.Load()).typ() != limiterEventNone {
- return false
- }
- e.stamp.Store(uint64(makeLimiterEventStamp(typ, now)))
- return true
-}
-
-// consume acquires the partial event CPU time from any in-flight event.
-// It achieves this by storing the current time as the new event time.
-//
-// Returns the type of the in-flight event, as well as how long it's currently been
-// executing for. Returns limiterEventNone if no event is active.
-func (e *limiterEvent) consume(now int64) (typ limiterEventType, duration int64) {
- // Read the limiter event timestamp and update it to now.
- for {
- old := limiterEventStamp(e.stamp.Load())
- typ = old.typ()
- if typ == limiterEventNone {
- // There's no in-flight event, so just push that up.
- return
- }
- duration = old.duration(now)
- if duration == 0 {
- // We might have a stale now value, or this crossed the
- // 2^(64-limiterEventBits) boundary in the clock readings.
- // Just ignore it.
- return limiterEventNone, 0
- }
- new := makeLimiterEventStamp(typ, now)
- if e.stamp.CompareAndSwap(uint64(old), uint64(new)) {
- break
- }
- }
- return
-}
-
-// stop stops the active limiter event. Throws if the
-//
-// The caller must be non-preemptible across the event. See start as to why.
-func (e *limiterEvent) stop(typ limiterEventType, now int64) {
- var stamp limiterEventStamp
- for {
- stamp = limiterEventStamp(e.stamp.Load())
- if stamp.typ() != typ {
- print("runtime: want=", typ, " got=", stamp.typ(), "\n")
- throw("limiterEvent.stop: found wrong event in p's limiter event slot")
- }
- if e.stamp.CompareAndSwap(uint64(stamp), uint64(limiterEventStampNone)) {
- break
- }
- }
- duration := stamp.duration(now)
- if duration == 0 {
- // It's possible that we're missing time because we crossed a
- // 2^(64-limiterEventBits) boundary between the start and end.
- // In this case, we're dropping that information. This is OK because
- // at worst it'll cause a transient hiccup that will quickly resolve
- // itself as all new timestamps begin on the other side of the boundary.
- // Such a hiccup should be incredibly rare.
- return
- }
- // Account for the event.
- switch typ {
- case limiterEventIdleMarkWork:
- gcCPULimiter.addIdleTime(duration)
- case limiterEventIdle:
- gcCPULimiter.addIdleTime(duration)
- sched.idleTime.Add(duration)
- case limiterEventMarkAssist:
- fallthrough
- case limiterEventScavengeAssist:
- gcCPULimiter.addAssistTime(duration)
- default:
- throw("limiterEvent.stop: invalid limiter event type found")
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mgcmark.go b/contrib/go/_std_1.20/src/runtime/mgcmark.go
deleted file mode 100644
index cfda7064cd..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mgcmark.go
+++ /dev/null
@@ -1,1598 +0,0 @@
-// Copyright 2009 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.
-
-// Garbage collector: marking and scanning
-
-package runtime
-
-import (
- "internal/goarch"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-const (
- fixedRootFinalizers = iota
- fixedRootFreeGStacks
- fixedRootCount
-
- // rootBlockBytes is the number of bytes to scan per data or
- // BSS root.
- rootBlockBytes = 256 << 10
-
- // maxObletBytes is the maximum bytes of an object to scan at
- // once. Larger objects will be split up into "oblets" of at
- // most this size. Since we can scan 1–2 MB/ms, 128 KB bounds
- // scan preemption at ~100 µs.
- //
- // This must be > _MaxSmallSize so that the object base is the
- // span base.
- maxObletBytes = 128 << 10
-
- // drainCheckThreshold specifies how many units of work to do
- // between self-preemption checks in gcDrain. Assuming a scan
- // rate of 1 MB/ms, this is ~100 µs. Lower values have higher
- // overhead in the scan loop (the scheduler check may perform
- // a syscall, so its overhead is nontrivial). Higher values
- // make the system less responsive to incoming work.
- drainCheckThreshold = 100000
-
- // pagesPerSpanRoot indicates how many pages to scan from a span root
- // at a time. Used by special root marking.
- //
- // Higher values improve throughput by increasing locality, but
- // increase the minimum latency of a marking operation.
- //
- // Must be a multiple of the pageInUse bitmap element size and
- // must also evenly divide pagesPerArena.
- pagesPerSpanRoot = 512
-)
-
-// gcMarkRootPrepare queues root scanning jobs (stacks, globals, and
-// some miscellany) and initializes scanning-related state.
-//
-// The world must be stopped.
-func gcMarkRootPrepare() {
- assertWorldStopped()
-
- // Compute how many data and BSS root blocks there are.
- nBlocks := func(bytes uintptr) int {
- return int(divRoundUp(bytes, rootBlockBytes))
- }
-
- work.nDataRoots = 0
- work.nBSSRoots = 0
-
- // Scan globals.
- for _, datap := range activeModules() {
- nDataRoots := nBlocks(datap.edata - datap.data)
- if nDataRoots > work.nDataRoots {
- work.nDataRoots = nDataRoots
- }
- }
-
- for _, datap := range activeModules() {
- nBSSRoots := nBlocks(datap.ebss - datap.bss)
- if nBSSRoots > work.nBSSRoots {
- work.nBSSRoots = nBSSRoots
- }
- }
-
- // Scan span roots for finalizer specials.
- //
- // We depend on addfinalizer to mark objects that get
- // finalizers after root marking.
- //
- // We're going to scan the whole heap (that was available at the time the
- // mark phase started, i.e. markArenas) for in-use spans which have specials.
- //
- // Break up the work into arenas, and further into chunks.
- //
- // Snapshot allArenas as markArenas. This snapshot is safe because allArenas
- // is append-only.
- mheap_.markArenas = mheap_.allArenas[:len(mheap_.allArenas):len(mheap_.allArenas)]
- work.nSpanRoots = len(mheap_.markArenas) * (pagesPerArena / pagesPerSpanRoot)
-
- // Scan stacks.
- //
- // Gs may be created after this point, but it's okay that we
- // ignore them because they begin life without any roots, so
- // there's nothing to scan, and any roots they create during
- // the concurrent phase will be caught by the write barrier.
- work.stackRoots = allGsSnapshot()
- work.nStackRoots = len(work.stackRoots)
-
- work.markrootNext = 0
- work.markrootJobs = uint32(fixedRootCount + work.nDataRoots + work.nBSSRoots + work.nSpanRoots + work.nStackRoots)
-
- // Calculate base indexes of each root type
- work.baseData = uint32(fixedRootCount)
- work.baseBSS = work.baseData + uint32(work.nDataRoots)
- work.baseSpans = work.baseBSS + uint32(work.nBSSRoots)
- work.baseStacks = work.baseSpans + uint32(work.nSpanRoots)
- work.baseEnd = work.baseStacks + uint32(work.nStackRoots)
-}
-
-// gcMarkRootCheck checks that all roots have been scanned. It is
-// purely for debugging.
-func gcMarkRootCheck() {
- if work.markrootNext < work.markrootJobs {
- print(work.markrootNext, " of ", work.markrootJobs, " markroot jobs done\n")
- throw("left over markroot jobs")
- }
-
- // Check that stacks have been scanned.
- //
- // We only check the first nStackRoots Gs that we should have scanned.
- // Since we don't care about newer Gs (see comment in
- // gcMarkRootPrepare), no locking is required.
- i := 0
- forEachGRace(func(gp *g) {
- if i >= work.nStackRoots {
- return
- }
-
- if !gp.gcscandone {
- println("gp", gp, "goid", gp.goid,
- "status", readgstatus(gp),
- "gcscandone", gp.gcscandone)
- throw("scan missed a g")
- }
-
- i++
- })
-}
-
-// ptrmask for an allocation containing a single pointer.
-var oneptrmask = [...]uint8{1}
-
-// markroot scans the i'th root.
-//
-// Preemption must be disabled (because this uses a gcWork).
-//
-// Returns the amount of GC work credit produced by the operation.
-// If flushBgCredit is true, then that credit is also flushed
-// to the background credit pool.
-//
-// nowritebarrier is only advisory here.
-//
-//go:nowritebarrier
-func markroot(gcw *gcWork, i uint32, flushBgCredit bool) int64 {
- // Note: if you add a case here, please also update heapdump.go:dumproots.
- var workDone int64
- var workCounter *atomic.Int64
- switch {
- case work.baseData <= i && i < work.baseBSS:
- workCounter = &gcController.globalsScanWork
- for _, datap := range activeModules() {
- workDone += markrootBlock(datap.data, datap.edata-datap.data, datap.gcdatamask.bytedata, gcw, int(i-work.baseData))
- }
-
- case work.baseBSS <= i && i < work.baseSpans:
- workCounter = &gcController.globalsScanWork
- for _, datap := range activeModules() {
- workDone += markrootBlock(datap.bss, datap.ebss-datap.bss, datap.gcbssmask.bytedata, gcw, int(i-work.baseBSS))
- }
-
- case i == fixedRootFinalizers:
- for fb := allfin; fb != nil; fb = fb.alllink {
- cnt := uintptr(atomic.Load(&fb.cnt))
- scanblock(uintptr(unsafe.Pointer(&fb.fin[0])), cnt*unsafe.Sizeof(fb.fin[0]), &finptrmask[0], gcw, nil)
- }
-
- case i == fixedRootFreeGStacks:
- // Switch to the system stack so we can call
- // stackfree.
- systemstack(markrootFreeGStacks)
-
- case work.baseSpans <= i && i < work.baseStacks:
- // mark mspan.specials
- markrootSpans(gcw, int(i-work.baseSpans))
-
- default:
- // the rest is scanning goroutine stacks
- workCounter = &gcController.stackScanWork
- if i < work.baseStacks || work.baseEnd <= i {
- printlock()
- print("runtime: markroot index ", i, " not in stack roots range [", work.baseStacks, ", ", work.baseEnd, ")\n")
- throw("markroot: bad index")
- }
- gp := work.stackRoots[i-work.baseStacks]
-
- // remember when we've first observed the G blocked
- // needed only to output in traceback
- status := readgstatus(gp) // We are not in a scan state
- if (status == _Gwaiting || status == _Gsyscall) && gp.waitsince == 0 {
- gp.waitsince = work.tstart
- }
-
- // scanstack must be done on the system stack in case
- // we're trying to scan our own stack.
- systemstack(func() {
- // If this is a self-scan, put the user G in
- // _Gwaiting to prevent self-deadlock. It may
- // already be in _Gwaiting if this is a mark
- // worker or we're in mark termination.
- userG := getg().m.curg
- selfScan := gp == userG && readgstatus(userG) == _Grunning
- if selfScan {
- casGToWaiting(userG, _Grunning, waitReasonGarbageCollectionScan)
- }
-
- // TODO: suspendG blocks (and spins) until gp
- // stops, which may take a while for
- // running goroutines. Consider doing this in
- // two phases where the first is non-blocking:
- // we scan the stacks we can and ask running
- // goroutines to scan themselves; and the
- // second blocks.
- stopped := suspendG(gp)
- if stopped.dead {
- gp.gcscandone = true
- return
- }
- if gp.gcscandone {
- throw("g already scanned")
- }
- workDone += scanstack(gp, gcw)
- gp.gcscandone = true
- resumeG(stopped)
-
- if selfScan {
- casgstatus(userG, _Gwaiting, _Grunning)
- }
- })
- }
- if workCounter != nil && workDone != 0 {
- workCounter.Add(workDone)
- if flushBgCredit {
- gcFlushBgCredit(workDone)
- }
- }
- return workDone
-}
-
-// markrootBlock scans the shard'th shard of the block of memory [b0,
-// b0+n0), with the given pointer mask.
-//
-// Returns the amount of work done.
-//
-//go:nowritebarrier
-func markrootBlock(b0, n0 uintptr, ptrmask0 *uint8, gcw *gcWork, shard int) int64 {
- if rootBlockBytes%(8*goarch.PtrSize) != 0 {
- // This is necessary to pick byte offsets in ptrmask0.
- throw("rootBlockBytes must be a multiple of 8*ptrSize")
- }
-
- // Note that if b0 is toward the end of the address space,
- // then b0 + rootBlockBytes might wrap around.
- // These tests are written to avoid any possible overflow.
- off := uintptr(shard) * rootBlockBytes
- if off >= n0 {
- return 0
- }
- b := b0 + off
- ptrmask := (*uint8)(add(unsafe.Pointer(ptrmask0), uintptr(shard)*(rootBlockBytes/(8*goarch.PtrSize))))
- n := uintptr(rootBlockBytes)
- if off+n > n0 {
- n = n0 - off
- }
-
- // Scan this shard.
- scanblock(b, n, ptrmask, gcw, nil)
- return int64(n)
-}
-
-// markrootFreeGStacks frees stacks of dead Gs.
-//
-// This does not free stacks of dead Gs cached on Ps, but having a few
-// cached stacks around isn't a problem.
-func markrootFreeGStacks() {
- // Take list of dead Gs with stacks.
- lock(&sched.gFree.lock)
- list := sched.gFree.stack
- sched.gFree.stack = gList{}
- unlock(&sched.gFree.lock)
- if list.empty() {
- return
- }
-
- // Free stacks.
- q := gQueue{list.head, list.head}
- for gp := list.head.ptr(); gp != nil; gp = gp.schedlink.ptr() {
- stackfree(gp.stack)
- gp.stack.lo = 0
- gp.stack.hi = 0
- // Manipulate the queue directly since the Gs are
- // already all linked the right way.
- q.tail.set(gp)
- }
-
- // Put Gs back on the free list.
- lock(&sched.gFree.lock)
- sched.gFree.noStack.pushAll(q)
- unlock(&sched.gFree.lock)
-}
-
-// markrootSpans marks roots for one shard of markArenas.
-//
-//go:nowritebarrier
-func markrootSpans(gcw *gcWork, shard int) {
- // Objects with finalizers have two GC-related invariants:
- //
- // 1) Everything reachable from the object must be marked.
- // This ensures that when we pass the object to its finalizer,
- // everything the finalizer can reach will be retained.
- //
- // 2) Finalizer specials (which are not in the garbage
- // collected heap) are roots. In practice, this means the fn
- // field must be scanned.
- sg := mheap_.sweepgen
-
- // Find the arena and page index into that arena for this shard.
- ai := mheap_.markArenas[shard/(pagesPerArena/pagesPerSpanRoot)]
- ha := mheap_.arenas[ai.l1()][ai.l2()]
- arenaPage := uint(uintptr(shard) * pagesPerSpanRoot % pagesPerArena)
-
- // Construct slice of bitmap which we'll iterate over.
- specialsbits := ha.pageSpecials[arenaPage/8:]
- specialsbits = specialsbits[:pagesPerSpanRoot/8]
- for i := range specialsbits {
- // Find set bits, which correspond to spans with specials.
- specials := atomic.Load8(&specialsbits[i])
- if specials == 0 {
- continue
- }
- for j := uint(0); j < 8; j++ {
- if specials&(1<<j) == 0 {
- continue
- }
- // Find the span for this bit.
- //
- // This value is guaranteed to be non-nil because having
- // specials implies that the span is in-use, and since we're
- // currently marking we can be sure that we don't have to worry
- // about the span being freed and re-used.
- s := ha.spans[arenaPage+uint(i)*8+j]
-
- // The state must be mSpanInUse if the specials bit is set, so
- // sanity check that.
- if state := s.state.get(); state != mSpanInUse {
- print("s.state = ", state, "\n")
- throw("non in-use span found with specials bit set")
- }
- // Check that this span was swept (it may be cached or uncached).
- if !useCheckmark && !(s.sweepgen == sg || s.sweepgen == sg+3) {
- // sweepgen was updated (+2) during non-checkmark GC pass
- print("sweep ", s.sweepgen, " ", sg, "\n")
- throw("gc: unswept span")
- }
-
- // Lock the specials to prevent a special from being
- // removed from the list while we're traversing it.
- lock(&s.speciallock)
- for sp := s.specials; sp != nil; sp = sp.next {
- if sp.kind != _KindSpecialFinalizer {
- continue
- }
- // don't mark finalized object, but scan it so we
- // retain everything it points to.
- spf := (*specialfinalizer)(unsafe.Pointer(sp))
- // A finalizer can be set for an inner byte of an object, find object beginning.
- p := s.base() + uintptr(spf.special.offset)/s.elemsize*s.elemsize
-
- // Mark everything that can be reached from
- // the object (but *not* the object itself or
- // we'll never collect it).
- if !s.spanclass.noscan() {
- scanobject(p, gcw)
- }
-
- // The special itself is a root.
- scanblock(uintptr(unsafe.Pointer(&spf.fn)), goarch.PtrSize, &oneptrmask[0], gcw, nil)
- }
- unlock(&s.speciallock)
- }
- }
-}
-
-// gcAssistAlloc performs GC work to make gp's assist debt positive.
-// gp must be the calling user goroutine.
-//
-// This must be called with preemption enabled.
-func gcAssistAlloc(gp *g) {
- // Don't assist in non-preemptible contexts. These are
- // generally fragile and won't allow the assist to block.
- if getg() == gp.m.g0 {
- return
- }
- if mp := getg().m; mp.locks > 0 || mp.preemptoff != "" {
- return
- }
-
- traced := false
-retry:
- if go119MemoryLimitSupport && gcCPULimiter.limiting() {
- // If the CPU limiter is enabled, intentionally don't
- // assist to reduce the amount of CPU time spent in the GC.
- if traced {
- traceGCMarkAssistDone()
- }
- return
- }
- // Compute the amount of scan work we need to do to make the
- // balance positive. When the required amount of work is low,
- // we over-assist to build up credit for future allocations
- // and amortize the cost of assisting.
- assistWorkPerByte := gcController.assistWorkPerByte.Load()
- assistBytesPerWork := gcController.assistBytesPerWork.Load()
- debtBytes := -gp.gcAssistBytes
- scanWork := int64(assistWorkPerByte * float64(debtBytes))
- if scanWork < gcOverAssistWork {
- scanWork = gcOverAssistWork
- debtBytes = int64(assistBytesPerWork * float64(scanWork))
- }
-
- // Steal as much credit as we can from the background GC's
- // scan credit. This is racy and may drop the background
- // credit below 0 if two mutators steal at the same time. This
- // will just cause steals to fail until credit is accumulated
- // again, so in the long run it doesn't really matter, but we
- // do have to handle the negative credit case.
- bgScanCredit := gcController.bgScanCredit.Load()
- stolen := int64(0)
- if bgScanCredit > 0 {
- if bgScanCredit < scanWork {
- stolen = bgScanCredit
- gp.gcAssistBytes += 1 + int64(assistBytesPerWork*float64(stolen))
- } else {
- stolen = scanWork
- gp.gcAssistBytes += debtBytes
- }
- gcController.bgScanCredit.Add(-stolen)
-
- scanWork -= stolen
-
- if scanWork == 0 {
- // We were able to steal all of the credit we
- // needed.
- if traced {
- traceGCMarkAssistDone()
- }
- return
- }
- }
-
- if trace.enabled && !traced {
- traced = true
- traceGCMarkAssistStart()
- }
-
- // Perform assist work
- systemstack(func() {
- gcAssistAlloc1(gp, scanWork)
- // The user stack may have moved, so this can't touch
- // anything on it until it returns from systemstack.
- })
-
- completed := gp.param != nil
- gp.param = nil
- if completed {
- gcMarkDone()
- }
-
- if gp.gcAssistBytes < 0 {
- // We were unable steal enough credit or perform
- // enough work to pay off the assist debt. We need to
- // do one of these before letting the mutator allocate
- // more to prevent over-allocation.
- //
- // If this is because we were preempted, reschedule
- // and try some more.
- if gp.preempt {
- Gosched()
- goto retry
- }
-
- // Add this G to an assist queue and park. When the GC
- // has more background credit, it will satisfy queued
- // assists before flushing to the global credit pool.
- //
- // Note that this does *not* get woken up when more
- // work is added to the work list. The theory is that
- // there wasn't enough work to do anyway, so we might
- // as well let background marking take care of the
- // work that is available.
- if !gcParkAssist() {
- goto retry
- }
-
- // At this point either background GC has satisfied
- // this G's assist debt, or the GC cycle is over.
- }
- if traced {
- traceGCMarkAssistDone()
- }
-}
-
-// gcAssistAlloc1 is the part of gcAssistAlloc that runs on the system
-// stack. This is a separate function to make it easier to see that
-// we're not capturing anything from the user stack, since the user
-// stack may move while we're in this function.
-//
-// gcAssistAlloc1 indicates whether this assist completed the mark
-// phase by setting gp.param to non-nil. This can't be communicated on
-// the stack since it may move.
-//
-//go:systemstack
-func gcAssistAlloc1(gp *g, scanWork int64) {
- // Clear the flag indicating that this assist completed the
- // mark phase.
- gp.param = nil
-
- if atomic.Load(&gcBlackenEnabled) == 0 {
- // The gcBlackenEnabled check in malloc races with the
- // store that clears it but an atomic check in every malloc
- // would be a performance hit.
- // Instead we recheck it here on the non-preemptable system
- // stack to determine if we should perform an assist.
-
- // GC is done, so ignore any remaining debt.
- gp.gcAssistBytes = 0
- return
- }
- // Track time spent in this assist. Since we're on the
- // system stack, this is non-preemptible, so we can
- // just measure start and end time.
- //
- // Limiter event tracking might be disabled if we end up here
- // while on a mark worker.
- startTime := nanotime()
- trackLimiterEvent := gp.m.p.ptr().limiterEvent.start(limiterEventMarkAssist, startTime)
-
- decnwait := atomic.Xadd(&work.nwait, -1)
- if decnwait == work.nproc {
- println("runtime: work.nwait =", decnwait, "work.nproc=", work.nproc)
- throw("nwait > work.nprocs")
- }
-
- // gcDrainN requires the caller to be preemptible.
- casGToWaiting(gp, _Grunning, waitReasonGCAssistMarking)
-
- // drain own cached work first in the hopes that it
- // will be more cache friendly.
- gcw := &getg().m.p.ptr().gcw
- workDone := gcDrainN(gcw, scanWork)
-
- casgstatus(gp, _Gwaiting, _Grunning)
-
- // Record that we did this much scan work.
- //
- // Back out the number of bytes of assist credit that
- // this scan work counts for. The "1+" is a poor man's
- // round-up, to ensure this adds credit even if
- // assistBytesPerWork is very low.
- assistBytesPerWork := gcController.assistBytesPerWork.Load()
- gp.gcAssistBytes += 1 + int64(assistBytesPerWork*float64(workDone))
-
- // If this is the last worker and we ran out of work,
- // signal a completion point.
- incnwait := atomic.Xadd(&work.nwait, +1)
- if incnwait > work.nproc {
- println("runtime: work.nwait=", incnwait,
- "work.nproc=", work.nproc)
- throw("work.nwait > work.nproc")
- }
-
- if incnwait == work.nproc && !gcMarkWorkAvailable(nil) {
- // This has reached a background completion point. Set
- // gp.param to a non-nil value to indicate this. It
- // doesn't matter what we set it to (it just has to be
- // a valid pointer).
- gp.param = unsafe.Pointer(gp)
- }
- now := nanotime()
- duration := now - startTime
- pp := gp.m.p.ptr()
- pp.gcAssistTime += duration
- if trackLimiterEvent {
- pp.limiterEvent.stop(limiterEventMarkAssist, now)
- }
- if pp.gcAssistTime > gcAssistTimeSlack {
- gcController.assistTime.Add(pp.gcAssistTime)
- gcCPULimiter.update(now)
- pp.gcAssistTime = 0
- }
-}
-
-// gcWakeAllAssists wakes all currently blocked assists. This is used
-// at the end of a GC cycle. gcBlackenEnabled must be false to prevent
-// new assists from going to sleep after this point.
-func gcWakeAllAssists() {
- lock(&work.assistQueue.lock)
- list := work.assistQueue.q.popList()
- injectglist(&list)
- unlock(&work.assistQueue.lock)
-}
-
-// gcParkAssist puts the current goroutine on the assist queue and parks.
-//
-// gcParkAssist reports whether the assist is now satisfied. If it
-// returns false, the caller must retry the assist.
-func gcParkAssist() bool {
- lock(&work.assistQueue.lock)
- // If the GC cycle finished while we were getting the lock,
- // exit the assist. The cycle can't finish while we hold the
- // lock.
- if atomic.Load(&gcBlackenEnabled) == 0 {
- unlock(&work.assistQueue.lock)
- return true
- }
-
- gp := getg()
- oldList := work.assistQueue.q
- work.assistQueue.q.pushBack(gp)
-
- // Recheck for background credit now that this G is in
- // the queue, but can still back out. This avoids a
- // race in case background marking has flushed more
- // credit since we checked above.
- if gcController.bgScanCredit.Load() > 0 {
- work.assistQueue.q = oldList
- if oldList.tail != 0 {
- oldList.tail.ptr().schedlink.set(nil)
- }
- unlock(&work.assistQueue.lock)
- return false
- }
- // Park.
- goparkunlock(&work.assistQueue.lock, waitReasonGCAssistWait, traceEvGoBlockGC, 2)
- return true
-}
-
-// gcFlushBgCredit flushes scanWork units of background scan work
-// credit. This first satisfies blocked assists on the
-// work.assistQueue and then flushes any remaining credit to
-// gcController.bgScanCredit.
-//
-// Write barriers are disallowed because this is used by gcDrain after
-// it has ensured that all work is drained and this must preserve that
-// condition.
-//
-//go:nowritebarrierrec
-func gcFlushBgCredit(scanWork int64) {
- if work.assistQueue.q.empty() {
- // Fast path; there are no blocked assists. There's a
- // small window here where an assist may add itself to
- // the blocked queue and park. If that happens, we'll
- // just get it on the next flush.
- gcController.bgScanCredit.Add(scanWork)
- return
- }
-
- assistBytesPerWork := gcController.assistBytesPerWork.Load()
- scanBytes := int64(float64(scanWork) * assistBytesPerWork)
-
- lock(&work.assistQueue.lock)
- for !work.assistQueue.q.empty() && scanBytes > 0 {
- gp := work.assistQueue.q.pop()
- // Note that gp.gcAssistBytes is negative because gp
- // is in debt. Think carefully about the signs below.
- if scanBytes+gp.gcAssistBytes >= 0 {
- // Satisfy this entire assist debt.
- scanBytes += gp.gcAssistBytes
- gp.gcAssistBytes = 0
- // It's important that we *not* put gp in
- // runnext. Otherwise, it's possible for user
- // code to exploit the GC worker's high
- // scheduler priority to get itself always run
- // before other goroutines and always in the
- // fresh quantum started by GC.
- ready(gp, 0, false)
- } else {
- // Partially satisfy this assist.
- gp.gcAssistBytes += scanBytes
- scanBytes = 0
- // As a heuristic, we move this assist to the
- // back of the queue so that large assists
- // can't clog up the assist queue and
- // substantially delay small assists.
- work.assistQueue.q.pushBack(gp)
- break
- }
- }
-
- if scanBytes > 0 {
- // Convert from scan bytes back to work.
- assistWorkPerByte := gcController.assistWorkPerByte.Load()
- scanWork = int64(float64(scanBytes) * assistWorkPerByte)
- gcController.bgScanCredit.Add(scanWork)
- }
- unlock(&work.assistQueue.lock)
-}
-
-// scanstack scans gp's stack, greying all pointers found on the stack.
-//
-// Returns the amount of scan work performed, but doesn't update
-// gcController.stackScanWork or flush any credit. Any background credit produced
-// by this function should be flushed by its caller. scanstack itself can't
-// safely flush because it may result in trying to wake up a goroutine that
-// was just scanned, resulting in a self-deadlock.
-//
-// scanstack will also shrink the stack if it is safe to do so. If it
-// is not, it schedules a stack shrink for the next synchronous safe
-// point.
-//
-// scanstack is marked go:systemstack because it must not be preempted
-// while using a workbuf.
-//
-//go:nowritebarrier
-//go:systemstack
-func scanstack(gp *g, gcw *gcWork) int64 {
- if readgstatus(gp)&_Gscan == 0 {
- print("runtime:scanstack: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", hex(readgstatus(gp)), "\n")
- throw("scanstack - bad status")
- }
-
- switch readgstatus(gp) &^ _Gscan {
- default:
- print("runtime: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n")
- throw("mark - bad status")
- case _Gdead:
- return 0
- case _Grunning:
- print("runtime: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n")
- throw("scanstack: goroutine not stopped")
- case _Grunnable, _Gsyscall, _Gwaiting:
- // ok
- }
-
- if gp == getg() {
- throw("can't scan our own stack")
- }
-
- // scannedSize is the amount of work we'll be reporting.
- //
- // It is less than the allocated size (which is hi-lo).
- var sp uintptr
- if gp.syscallsp != 0 {
- sp = gp.syscallsp // If in a system call this is the stack pointer (gp.sched.sp can be 0 in this case on Windows).
- } else {
- sp = gp.sched.sp
- }
- scannedSize := gp.stack.hi - sp
-
- // Keep statistics for initial stack size calculation.
- // Note that this accumulates the scanned size, not the allocated size.
- p := getg().m.p.ptr()
- p.scannedStackSize += uint64(scannedSize)
- p.scannedStacks++
-
- if isShrinkStackSafe(gp) {
- // Shrink the stack if not much of it is being used.
- shrinkstack(gp)
- } else {
- // Otherwise, shrink the stack at the next sync safe point.
- gp.preemptShrink = true
- }
-
- var state stackScanState
- state.stack = gp.stack
-
- if stackTraceDebug {
- println("stack trace goroutine", gp.goid)
- }
-
- if debugScanConservative && gp.asyncSafePoint {
- print("scanning async preempted goroutine ", gp.goid, " stack [", hex(gp.stack.lo), ",", hex(gp.stack.hi), ")\n")
- }
-
- // Scan the saved context register. This is effectively a live
- // register that gets moved back and forth between the
- // register and sched.ctxt without a write barrier.
- if gp.sched.ctxt != nil {
- scanblock(uintptr(unsafe.Pointer(&gp.sched.ctxt)), goarch.PtrSize, &oneptrmask[0], gcw, &state)
- }
-
- // Scan the stack. Accumulate a list of stack objects.
- scanframe := func(frame *stkframe, unused unsafe.Pointer) bool {
- scanframeworker(frame, &state, gcw)
- return true
- }
- gentraceback(^uintptr(0), ^uintptr(0), 0, gp, 0, nil, 0x7fffffff, scanframe, nil, 0)
-
- // Find additional pointers that point into the stack from the heap.
- // Currently this includes defers and panics. See also function copystack.
-
- // Find and trace other pointers in defer records.
- for d := gp._defer; d != nil; d = d.link {
- if d.fn != nil {
- // Scan the func value, which could be a stack allocated closure.
- // See issue 30453.
- scanblock(uintptr(unsafe.Pointer(&d.fn)), goarch.PtrSize, &oneptrmask[0], gcw, &state)
- }
- if d.link != nil {
- // The link field of a stack-allocated defer record might point
- // to a heap-allocated defer record. Keep that heap record live.
- scanblock(uintptr(unsafe.Pointer(&d.link)), goarch.PtrSize, &oneptrmask[0], gcw, &state)
- }
- // Retain defers records themselves.
- // Defer records might not be reachable from the G through regular heap
- // tracing because the defer linked list might weave between the stack and the heap.
- if d.heap {
- scanblock(uintptr(unsafe.Pointer(&d)), goarch.PtrSize, &oneptrmask[0], gcw, &state)
- }
- }
- if gp._panic != nil {
- // Panics are always stack allocated.
- state.putPtr(uintptr(unsafe.Pointer(gp._panic)), false)
- }
-
- // Find and scan all reachable stack objects.
- //
- // The state's pointer queue prioritizes precise pointers over
- // conservative pointers so that we'll prefer scanning stack
- // objects precisely.
- state.buildIndex()
- for {
- p, conservative := state.getPtr()
- if p == 0 {
- break
- }
- obj := state.findObject(p)
- if obj == nil {
- continue
- }
- r := obj.r
- if r == nil {
- // We've already scanned this object.
- continue
- }
- obj.setRecord(nil) // Don't scan it again.
- if stackTraceDebug {
- printlock()
- print(" live stkobj at", hex(state.stack.lo+uintptr(obj.off)), "of size", obj.size)
- if conservative {
- print(" (conservative)")
- }
- println()
- printunlock()
- }
- gcdata := r.gcdata()
- var s *mspan
- if r.useGCProg() {
- // This path is pretty unlikely, an object large enough
- // to have a GC program allocated on the stack.
- // We need some space to unpack the program into a straight
- // bitmask, which we allocate/free here.
- // TODO: it would be nice if there were a way to run a GC
- // program without having to store all its bits. We'd have
- // to change from a Lempel-Ziv style program to something else.
- // Or we can forbid putting objects on stacks if they require
- // a gc program (see issue 27447).
- s = materializeGCProg(r.ptrdata(), gcdata)
- gcdata = (*byte)(unsafe.Pointer(s.startAddr))
- }
-
- b := state.stack.lo + uintptr(obj.off)
- if conservative {
- scanConservative(b, r.ptrdata(), gcdata, gcw, &state)
- } else {
- scanblock(b, r.ptrdata(), gcdata, gcw, &state)
- }
-
- if s != nil {
- dematerializeGCProg(s)
- }
- }
-
- // Deallocate object buffers.
- // (Pointer buffers were all deallocated in the loop above.)
- for state.head != nil {
- x := state.head
- state.head = x.next
- if stackTraceDebug {
- for i := 0; i < x.nobj; i++ {
- obj := &x.obj[i]
- if obj.r == nil { // reachable
- continue
- }
- println(" dead stkobj at", hex(gp.stack.lo+uintptr(obj.off)), "of size", obj.r.size)
- // Note: not necessarily really dead - only reachable-from-ptr dead.
- }
- }
- x.nobj = 0
- putempty((*workbuf)(unsafe.Pointer(x)))
- }
- if state.buf != nil || state.cbuf != nil || state.freeBuf != nil {
- throw("remaining pointer buffers")
- }
- return int64(scannedSize)
-}
-
-// Scan a stack frame: local variables and function arguments/results.
-//
-//go:nowritebarrier
-func scanframeworker(frame *stkframe, state *stackScanState, gcw *gcWork) {
- if _DebugGC > 1 && frame.continpc != 0 {
- print("scanframe ", funcname(frame.fn), "\n")
- }
-
- isAsyncPreempt := frame.fn.valid() && frame.fn.funcID == funcID_asyncPreempt
- isDebugCall := frame.fn.valid() && frame.fn.funcID == funcID_debugCallV2
- if state.conservative || isAsyncPreempt || isDebugCall {
- if debugScanConservative {
- println("conservatively scanning function", funcname(frame.fn), "at PC", hex(frame.continpc))
- }
-
- // Conservatively scan the frame. Unlike the precise
- // case, this includes the outgoing argument space
- // since we may have stopped while this function was
- // setting up a call.
- //
- // TODO: We could narrow this down if the compiler
- // produced a single map per function of stack slots
- // and registers that ever contain a pointer.
- if frame.varp != 0 {
- size := frame.varp - frame.sp
- if size > 0 {
- scanConservative(frame.sp, size, nil, gcw, state)
- }
- }
-
- // Scan arguments to this frame.
- if n := frame.argBytes(); n != 0 {
- // TODO: We could pass the entry argument map
- // to narrow this down further.
- scanConservative(frame.argp, n, nil, gcw, state)
- }
-
- if isAsyncPreempt || isDebugCall {
- // This function's frame contained the
- // registers for the asynchronously stopped
- // parent frame. Scan the parent
- // conservatively.
- state.conservative = true
- } else {
- // We only wanted to scan those two frames
- // conservatively. Clear the flag for future
- // frames.
- state.conservative = false
- }
- return
- }
-
- locals, args, objs := frame.getStackMap(&state.cache, false)
-
- // Scan local variables if stack frame has been allocated.
- if locals.n > 0 {
- size := uintptr(locals.n) * goarch.PtrSize
- scanblock(frame.varp-size, size, locals.bytedata, gcw, state)
- }
-
- // Scan arguments.
- if args.n > 0 {
- scanblock(frame.argp, uintptr(args.n)*goarch.PtrSize, args.bytedata, gcw, state)
- }
-
- // Add all stack objects to the stack object list.
- if frame.varp != 0 {
- // varp is 0 for defers, where there are no locals.
- // In that case, there can't be a pointer to its args, either.
- // (And all args would be scanned above anyway.)
- for i := range objs {
- obj := &objs[i]
- off := obj.off
- base := frame.varp // locals base pointer
- if off >= 0 {
- base = frame.argp // arguments and return values base pointer
- }
- ptr := base + uintptr(off)
- if ptr < frame.sp {
- // object hasn't been allocated in the frame yet.
- continue
- }
- if stackTraceDebug {
- println("stkobj at", hex(ptr), "of size", obj.size)
- }
- state.addObject(ptr, obj)
- }
- }
-}
-
-type gcDrainFlags int
-
-const (
- gcDrainUntilPreempt gcDrainFlags = 1 << iota
- gcDrainFlushBgCredit
- gcDrainIdle
- gcDrainFractional
-)
-
-// gcDrain scans roots and objects in work buffers, blackening grey
-// objects until it is unable to get more work. It may return before
-// GC is done; it's the caller's responsibility to balance work from
-// other Ps.
-//
-// If flags&gcDrainUntilPreempt != 0, gcDrain returns when g.preempt
-// is set.
-//
-// If flags&gcDrainIdle != 0, gcDrain returns when there is other work
-// to do.
-//
-// If flags&gcDrainFractional != 0, gcDrain self-preempts when
-// pollFractionalWorkerExit() returns true. This implies
-// gcDrainNoBlock.
-//
-// If flags&gcDrainFlushBgCredit != 0, gcDrain flushes scan work
-// credit to gcController.bgScanCredit every gcCreditSlack units of
-// scan work.
-//
-// gcDrain will always return if there is a pending STW.
-//
-//go:nowritebarrier
-func gcDrain(gcw *gcWork, flags gcDrainFlags) {
- if !writeBarrier.needed {
- throw("gcDrain phase incorrect")
- }
-
- gp := getg().m.curg
- preemptible := flags&gcDrainUntilPreempt != 0
- flushBgCredit := flags&gcDrainFlushBgCredit != 0
- idle := flags&gcDrainIdle != 0
-
- initScanWork := gcw.heapScanWork
-
- // checkWork is the scan work before performing the next
- // self-preempt check.
- checkWork := int64(1<<63 - 1)
- var check func() bool
- if flags&(gcDrainIdle|gcDrainFractional) != 0 {
- checkWork = initScanWork + drainCheckThreshold
- if idle {
- check = pollWork
- } else if flags&gcDrainFractional != 0 {
- check = pollFractionalWorkerExit
- }
- }
-
- // Drain root marking jobs.
- if work.markrootNext < work.markrootJobs {
- // Stop if we're preemptible or if someone wants to STW.
- for !(gp.preempt && (preemptible || sched.gcwaiting.Load())) {
- job := atomic.Xadd(&work.markrootNext, +1) - 1
- if job >= work.markrootJobs {
- break
- }
- markroot(gcw, job, flushBgCredit)
- if check != nil && check() {
- goto done
- }
- }
- }
-
- // Drain heap marking jobs.
- // Stop if we're preemptible or if someone wants to STW.
- for !(gp.preempt && (preemptible || sched.gcwaiting.Load())) {
- // Try to keep work available on the global queue. We used to
- // check if there were waiting workers, but it's better to
- // just keep work available than to make workers wait. In the
- // worst case, we'll do O(log(_WorkbufSize)) unnecessary
- // balances.
- if work.full == 0 {
- gcw.balance()
- }
-
- b := gcw.tryGetFast()
- if b == 0 {
- b = gcw.tryGet()
- if b == 0 {
- // Flush the write barrier
- // buffer; this may create
- // more work.
- wbBufFlush(nil, 0)
- b = gcw.tryGet()
- }
- }
- if b == 0 {
- // Unable to get work.
- break
- }
- scanobject(b, gcw)
-
- // Flush background scan work credit to the global
- // account if we've accumulated enough locally so
- // mutator assists can draw on it.
- if gcw.heapScanWork >= gcCreditSlack {
- gcController.heapScanWork.Add(gcw.heapScanWork)
- if flushBgCredit {
- gcFlushBgCredit(gcw.heapScanWork - initScanWork)
- initScanWork = 0
- }
- checkWork -= gcw.heapScanWork
- gcw.heapScanWork = 0
-
- if checkWork <= 0 {
- checkWork += drainCheckThreshold
- if check != nil && check() {
- break
- }
- }
- }
- }
-
-done:
- // Flush remaining scan work credit.
- if gcw.heapScanWork > 0 {
- gcController.heapScanWork.Add(gcw.heapScanWork)
- if flushBgCredit {
- gcFlushBgCredit(gcw.heapScanWork - initScanWork)
- }
- gcw.heapScanWork = 0
- }
-}
-
-// gcDrainN blackens grey objects until it has performed roughly
-// scanWork units of scan work or the G is preempted. This is
-// best-effort, so it may perform less work if it fails to get a work
-// buffer. Otherwise, it will perform at least n units of work, but
-// may perform more because scanning is always done in whole object
-// increments. It returns the amount of scan work performed.
-//
-// The caller goroutine must be in a preemptible state (e.g.,
-// _Gwaiting) to prevent deadlocks during stack scanning. As a
-// consequence, this must be called on the system stack.
-//
-//go:nowritebarrier
-//go:systemstack
-func gcDrainN(gcw *gcWork, scanWork int64) int64 {
- if !writeBarrier.needed {
- throw("gcDrainN phase incorrect")
- }
-
- // There may already be scan work on the gcw, which we don't
- // want to claim was done by this call.
- workFlushed := -gcw.heapScanWork
-
- // In addition to backing out because of a preemption, back out
- // if the GC CPU limiter is enabled.
- gp := getg().m.curg
- for !gp.preempt && !gcCPULimiter.limiting() && workFlushed+gcw.heapScanWork < scanWork {
- // See gcDrain comment.
- if work.full == 0 {
- gcw.balance()
- }
-
- b := gcw.tryGetFast()
- if b == 0 {
- b = gcw.tryGet()
- if b == 0 {
- // Flush the write barrier buffer;
- // this may create more work.
- wbBufFlush(nil, 0)
- b = gcw.tryGet()
- }
- }
-
- if b == 0 {
- // Try to do a root job.
- if work.markrootNext < work.markrootJobs {
- job := atomic.Xadd(&work.markrootNext, +1) - 1
- if job < work.markrootJobs {
- workFlushed += markroot(gcw, job, false)
- continue
- }
- }
- // No heap or root jobs.
- break
- }
-
- scanobject(b, gcw)
-
- // Flush background scan work credit.
- if gcw.heapScanWork >= gcCreditSlack {
- gcController.heapScanWork.Add(gcw.heapScanWork)
- workFlushed += gcw.heapScanWork
- gcw.heapScanWork = 0
- }
- }
-
- // Unlike gcDrain, there's no need to flush remaining work
- // here because this never flushes to bgScanCredit and
- // gcw.dispose will flush any remaining work to scanWork.
-
- return workFlushed + gcw.heapScanWork
-}
-
-// scanblock scans b as scanobject would, but using an explicit
-// pointer bitmap instead of the heap bitmap.
-//
-// This is used to scan non-heap roots, so it does not update
-// gcw.bytesMarked or gcw.heapScanWork.
-//
-// If stk != nil, possible stack pointers are also reported to stk.putPtr.
-//
-//go:nowritebarrier
-func scanblock(b0, n0 uintptr, ptrmask *uint8, gcw *gcWork, stk *stackScanState) {
- // Use local copies of original parameters, so that a stack trace
- // due to one of the throws below shows the original block
- // base and extent.
- b := b0
- n := n0
-
- for i := uintptr(0); i < n; {
- // Find bits for the next word.
- bits := uint32(*addb(ptrmask, i/(goarch.PtrSize*8)))
- if bits == 0 {
- i += goarch.PtrSize * 8
- continue
- }
- for j := 0; j < 8 && i < n; j++ {
- if bits&1 != 0 {
- // Same work as in scanobject; see comments there.
- p := *(*uintptr)(unsafe.Pointer(b + i))
- if p != 0 {
- if obj, span, objIndex := findObject(p, b, i); obj != 0 {
- greyobject(obj, b, i, span, gcw, objIndex)
- } else if stk != nil && p >= stk.stack.lo && p < stk.stack.hi {
- stk.putPtr(p, false)
- }
- }
- }
- bits >>= 1
- i += goarch.PtrSize
- }
- }
-}
-
-// scanobject scans the object starting at b, adding pointers to gcw.
-// b must point to the beginning of a heap object or an oblet.
-// scanobject consults the GC bitmap for the pointer mask and the
-// spans for the size of the object.
-//
-//go:nowritebarrier
-func scanobject(b uintptr, gcw *gcWork) {
- // Prefetch object before we scan it.
- //
- // This will overlap fetching the beginning of the object with initial
- // setup before we start scanning the object.
- sys.Prefetch(b)
-
- // Find the bits for b and the size of the object at b.
- //
- // b is either the beginning of an object, in which case this
- // is the size of the object to scan, or it points to an
- // oblet, in which case we compute the size to scan below.
- s := spanOfUnchecked(b)
- n := s.elemsize
- if n == 0 {
- throw("scanobject n == 0")
- }
- if s.spanclass.noscan() {
- // Correctness-wise this is ok, but it's inefficient
- // if noscan objects reach here.
- throw("scanobject of a noscan object")
- }
-
- if n > maxObletBytes {
- // Large object. Break into oblets for better
- // parallelism and lower latency.
- if b == s.base() {
- // Enqueue the other oblets to scan later.
- // Some oblets may be in b's scalar tail, but
- // these will be marked as "no more pointers",
- // so we'll drop out immediately when we go to
- // scan those.
- for oblet := b + maxObletBytes; oblet < s.base()+s.elemsize; oblet += maxObletBytes {
- if !gcw.putFast(oblet) {
- gcw.put(oblet)
- }
- }
- }
-
- // Compute the size of the oblet. Since this object
- // must be a large object, s.base() is the beginning
- // of the object.
- n = s.base() + s.elemsize - b
- if n > maxObletBytes {
- n = maxObletBytes
- }
- }
-
- hbits := heapBitsForAddr(b, n)
- var scanSize uintptr
- for {
- var addr uintptr
- if hbits, addr = hbits.nextFast(); addr == 0 {
- if hbits, addr = hbits.next(); addr == 0 {
- break
- }
- }
-
- // Keep track of farthest pointer we found, so we can
- // update heapScanWork. TODO: is there a better metric,
- // now that we can skip scalar portions pretty efficiently?
- scanSize = addr - b + goarch.PtrSize
-
- // Work here is duplicated in scanblock and above.
- // If you make changes here, make changes there too.
- obj := *(*uintptr)(unsafe.Pointer(addr))
-
- // At this point we have extracted the next potential pointer.
- // Quickly filter out nil and pointers back to the current object.
- if obj != 0 && obj-b >= n {
- // Test if obj points into the Go heap and, if so,
- // mark the object.
- //
- // Note that it's possible for findObject to
- // fail if obj points to a just-allocated heap
- // object because of a race with growing the
- // heap. In this case, we know the object was
- // just allocated and hence will be marked by
- // allocation itself.
- if obj, span, objIndex := findObject(obj, b, addr-b); obj != 0 {
- greyobject(obj, b, addr-b, span, gcw, objIndex)
- }
- }
- }
- gcw.bytesMarked += uint64(n)
- gcw.heapScanWork += int64(scanSize)
-}
-
-// scanConservative scans block [b, b+n) conservatively, treating any
-// pointer-like value in the block as a pointer.
-//
-// If ptrmask != nil, only words that are marked in ptrmask are
-// considered as potential pointers.
-//
-// If state != nil, it's assumed that [b, b+n) is a block in the stack
-// and may contain pointers to stack objects.
-func scanConservative(b, n uintptr, ptrmask *uint8, gcw *gcWork, state *stackScanState) {
- if debugScanConservative {
- printlock()
- print("conservatively scanning [", hex(b), ",", hex(b+n), ")\n")
- hexdumpWords(b, b+n, func(p uintptr) byte {
- if ptrmask != nil {
- word := (p - b) / goarch.PtrSize
- bits := *addb(ptrmask, word/8)
- if (bits>>(word%8))&1 == 0 {
- return '$'
- }
- }
-
- val := *(*uintptr)(unsafe.Pointer(p))
- if state != nil && state.stack.lo <= val && val < state.stack.hi {
- return '@'
- }
-
- span := spanOfHeap(val)
- if span == nil {
- return ' '
- }
- idx := span.objIndex(val)
- if span.isFree(idx) {
- return ' '
- }
- return '*'
- })
- printunlock()
- }
-
- for i := uintptr(0); i < n; i += goarch.PtrSize {
- if ptrmask != nil {
- word := i / goarch.PtrSize
- bits := *addb(ptrmask, word/8)
- if bits == 0 {
- // Skip 8 words (the loop increment will do the 8th)
- //
- // This must be the first time we've
- // seen this word of ptrmask, so i
- // must be 8-word-aligned, but check
- // our reasoning just in case.
- if i%(goarch.PtrSize*8) != 0 {
- throw("misaligned mask")
- }
- i += goarch.PtrSize*8 - goarch.PtrSize
- continue
- }
- if (bits>>(word%8))&1 == 0 {
- continue
- }
- }
-
- val := *(*uintptr)(unsafe.Pointer(b + i))
-
- // Check if val points into the stack.
- if state != nil && state.stack.lo <= val && val < state.stack.hi {
- // val may point to a stack object. This
- // object may be dead from last cycle and
- // hence may contain pointers to unallocated
- // objects, but unlike heap objects we can't
- // tell if it's already dead. Hence, if all
- // pointers to this object are from
- // conservative scanning, we have to scan it
- // defensively, too.
- state.putPtr(val, true)
- continue
- }
-
- // Check if val points to a heap span.
- span := spanOfHeap(val)
- if span == nil {
- continue
- }
-
- // Check if val points to an allocated object.
- idx := span.objIndex(val)
- if span.isFree(idx) {
- continue
- }
-
- // val points to an allocated object. Mark it.
- obj := span.base() + idx*span.elemsize
- greyobject(obj, b, i, span, gcw, idx)
- }
-}
-
-// Shade the object if it isn't already.
-// The object is not nil and known to be in the heap.
-// Preemption must be disabled.
-//
-//go:nowritebarrier
-func shade(b uintptr) {
- if obj, span, objIndex := findObject(b, 0, 0); obj != 0 {
- gcw := &getg().m.p.ptr().gcw
- greyobject(obj, 0, 0, span, gcw, objIndex)
- }
-}
-
-// obj is the start of an object with mark mbits.
-// If it isn't already marked, mark it and enqueue into gcw.
-// base and off are for debugging only and could be removed.
-//
-// See also wbBufFlush1, which partially duplicates this logic.
-//
-//go:nowritebarrierrec
-func greyobject(obj, base, off uintptr, span *mspan, gcw *gcWork, objIndex uintptr) {
- // obj should be start of allocation, and so must be at least pointer-aligned.
- if obj&(goarch.PtrSize-1) != 0 {
- throw("greyobject: obj not pointer-aligned")
- }
- mbits := span.markBitsForIndex(objIndex)
-
- if useCheckmark {
- if setCheckmark(obj, base, off, mbits) {
- // Already marked.
- return
- }
- } else {
- if debug.gccheckmark > 0 && span.isFree(objIndex) {
- print("runtime: marking free object ", hex(obj), " found at *(", hex(base), "+", hex(off), ")\n")
- gcDumpObject("base", base, off)
- gcDumpObject("obj", obj, ^uintptr(0))
- getg().m.traceback = 2
- throw("marking free object")
- }
-
- // If marked we have nothing to do.
- if mbits.isMarked() {
- return
- }
- mbits.setMarked()
-
- // Mark span.
- arena, pageIdx, pageMask := pageIndexOf(span.base())
- if arena.pageMarks[pageIdx]&pageMask == 0 {
- atomic.Or8(&arena.pageMarks[pageIdx], pageMask)
- }
-
- // If this is a noscan object, fast-track it to black
- // instead of greying it.
- if span.spanclass.noscan() {
- gcw.bytesMarked += uint64(span.elemsize)
- return
- }
- }
-
- // We're adding obj to P's local workbuf, so it's likely
- // this object will be processed soon by the same P.
- // Even if the workbuf gets flushed, there will likely still be
- // some benefit on platforms with inclusive shared caches.
- sys.Prefetch(obj)
- // Queue the obj for scanning.
- if !gcw.putFast(obj) {
- gcw.put(obj)
- }
-}
-
-// gcDumpObject dumps the contents of obj for debugging and marks the
-// field at byte offset off in obj.
-func gcDumpObject(label string, obj, off uintptr) {
- s := spanOf(obj)
- print(label, "=", hex(obj))
- if s == nil {
- print(" s=nil\n")
- return
- }
- print(" s.base()=", hex(s.base()), " s.limit=", hex(s.limit), " s.spanclass=", s.spanclass, " s.elemsize=", s.elemsize, " s.state=")
- if state := s.state.get(); 0 <= state && int(state) < len(mSpanStateNames) {
- print(mSpanStateNames[state], "\n")
- } else {
- print("unknown(", state, ")\n")
- }
-
- skipped := false
- size := s.elemsize
- if s.state.get() == mSpanManual && size == 0 {
- // We're printing something from a stack frame. We
- // don't know how big it is, so just show up to an
- // including off.
- size = off + goarch.PtrSize
- }
- for i := uintptr(0); i < size; i += goarch.PtrSize {
- // For big objects, just print the beginning (because
- // that usually hints at the object's type) and the
- // fields around off.
- if !(i < 128*goarch.PtrSize || off-16*goarch.PtrSize < i && i < off+16*goarch.PtrSize) {
- skipped = true
- continue
- }
- if skipped {
- print(" ...\n")
- skipped = false
- }
- print(" *(", label, "+", i, ") = ", hex(*(*uintptr)(unsafe.Pointer(obj + i))))
- if i == off {
- print(" <==")
- }
- print("\n")
- }
- if skipped {
- print(" ...\n")
- }
-}
-
-// gcmarknewobject marks a newly allocated object black. obj must
-// not contain any non-nil pointers.
-//
-// This is nosplit so it can manipulate a gcWork without preemption.
-//
-//go:nowritebarrier
-//go:nosplit
-func gcmarknewobject(span *mspan, obj, size uintptr) {
- if useCheckmark { // The world should be stopped so this should not happen.
- throw("gcmarknewobject called while doing checkmark")
- }
-
- // Mark object.
- objIndex := span.objIndex(obj)
- span.markBitsForIndex(objIndex).setMarked()
-
- // Mark span.
- arena, pageIdx, pageMask := pageIndexOf(span.base())
- if arena.pageMarks[pageIdx]&pageMask == 0 {
- atomic.Or8(&arena.pageMarks[pageIdx], pageMask)
- }
-
- gcw := &getg().m.p.ptr().gcw
- gcw.bytesMarked += uint64(size)
-}
-
-// gcMarkTinyAllocs greys all active tiny alloc blocks.
-//
-// The world must be stopped.
-func gcMarkTinyAllocs() {
- assertWorldStopped()
-
- for _, p := range allp {
- c := p.mcache
- if c == nil || c.tiny == 0 {
- continue
- }
- _, span, objIndex := findObject(c.tiny, 0, 0)
- gcw := &p.gcw
- greyobject(c.tiny, 0, 0, span, gcw, objIndex)
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mgcpacer.go b/contrib/go/_std_1.20/src/runtime/mgcpacer.go
deleted file mode 100644
index d909586957..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mgcpacer.go
+++ /dev/null
@@ -1,1427 +0,0 @@
-// 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 runtime
-
-import (
- "internal/cpu"
- "internal/goexperiment"
- "runtime/internal/atomic"
- _ "unsafe" // for go:linkname
-
-)
-
-// go119MemoryLimitSupport is a feature flag for a number of changes
-// related to the memory limit feature (#48409). Disabling this flag
-// disables those features, as well as the memory limit mechanism,
-// which becomes a no-op.
-const go119MemoryLimitSupport = true
-
-const (
- // gcGoalUtilization is the goal CPU utilization for
- // marking as a fraction of GOMAXPROCS.
- //
- // Increasing the goal utilization will shorten GC cycles as the GC
- // has more resources behind it, lessening costs from the write barrier,
- // but comes at the cost of increasing mutator latency.
- gcGoalUtilization = gcBackgroundUtilization
-
- // gcBackgroundUtilization is the fixed CPU utilization for background
- // marking. It must be <= gcGoalUtilization. The difference between
- // gcGoalUtilization and gcBackgroundUtilization will be made up by
- // mark assists. The scheduler will aim to use within 50% of this
- // goal.
- //
- // As a general rule, there's little reason to set gcBackgroundUtilization
- // < gcGoalUtilization. One reason might be in mostly idle applications,
- // where goroutines are unlikely to assist at all, so the actual
- // utilization will be lower than the goal. But this is moot point
- // because the idle mark workers already soak up idle CPU resources.
- // These two values are still kept separate however because they are
- // distinct conceptually, and in previous iterations of the pacer the
- // distinction was more important.
- gcBackgroundUtilization = 0.25
-
- // gcCreditSlack is the amount of scan work credit that can
- // accumulate locally before updating gcController.heapScanWork and,
- // optionally, gcController.bgScanCredit. Lower values give a more
- // accurate assist ratio and make it more likely that assists will
- // successfully steal background credit. Higher values reduce memory
- // contention.
- gcCreditSlack = 2000
-
- // gcAssistTimeSlack is the nanoseconds of mutator assist time that
- // can accumulate on a P before updating gcController.assistTime.
- gcAssistTimeSlack = 5000
-
- // gcOverAssistWork determines how many extra units of scan work a GC
- // assist does when an assist happens. This amortizes the cost of an
- // assist by pre-paying for this many bytes of future allocations.
- gcOverAssistWork = 64 << 10
-
- // defaultHeapMinimum is the value of heapMinimum for GOGC==100.
- defaultHeapMinimum = (goexperiment.HeapMinimum512KiBInt)*(512<<10) +
- (1-goexperiment.HeapMinimum512KiBInt)*(4<<20)
-
- // maxStackScanSlack is the bytes of stack space allocated or freed
- // that can accumulate on a P before updating gcController.stackSize.
- maxStackScanSlack = 8 << 10
-
- // memoryLimitHeapGoalHeadroom is the amount of headroom the pacer gives to
- // the heap goal when operating in the memory-limited regime. That is,
- // it'll reduce the heap goal by this many extra bytes off of the base
- // calculation.
- memoryLimitHeapGoalHeadroom = 1 << 20
-)
-
-// gcController implements the GC pacing controller that determines
-// when to trigger concurrent garbage collection and how much marking
-// work to do in mutator assists and background marking.
-//
-// It calculates the ratio between the allocation rate (in terms of CPU
-// time) and the GC scan throughput to determine the heap size at which to
-// trigger a GC cycle such that no GC assists are required to finish on time.
-// This algorithm thus optimizes GC CPU utilization to the dedicated background
-// mark utilization of 25% of GOMAXPROCS by minimizing GC assists.
-// GOMAXPROCS. The high-level design of this algorithm is documented
-// at https://github.com/golang/proposal/blob/master/design/44167-gc-pacer-redesign.md.
-// See https://golang.org/s/go15gcpacing for additional historical context.
-var gcController gcControllerState
-
-type gcControllerState struct {
- // Initialized from GOGC. GOGC=off means no GC.
- gcPercent atomic.Int32
-
- // memoryLimit is the soft memory limit in bytes.
- //
- // Initialized from GOMEMLIMIT. GOMEMLIMIT=off is equivalent to MaxInt64
- // which means no soft memory limit in practice.
- //
- // This is an int64 instead of a uint64 to more easily maintain parity with
- // the SetMemoryLimit API, which sets a maximum at MaxInt64. This value
- // should never be negative.
- memoryLimit atomic.Int64
-
- // heapMinimum is the minimum heap size at which to trigger GC.
- // For small heaps, this overrides the usual GOGC*live set rule.
- //
- // When there is a very small live set but a lot of allocation, simply
- // collecting when the heap reaches GOGC*live results in many GC
- // cycles and high total per-GC overhead. This minimum amortizes this
- // per-GC overhead while keeping the heap reasonably small.
- //
- // During initialization this is set to 4MB*GOGC/100. In the case of
- // GOGC==0, this will set heapMinimum to 0, resulting in constant
- // collection even when the heap size is small, which is useful for
- // debugging.
- heapMinimum uint64
-
- // runway is the amount of runway in heap bytes allocated by the
- // application that we want to give the GC once it starts.
- //
- // This is computed from consMark during mark termination.
- runway atomic.Uint64
-
- // consMark is the estimated per-CPU consMark ratio for the application.
- //
- // It represents the ratio between the application's allocation
- // rate, as bytes allocated per CPU-time, and the GC's scan rate,
- // as bytes scanned per CPU-time.
- // The units of this ratio are (B / cpu-ns) / (B / cpu-ns).
- //
- // At a high level, this value is computed as the bytes of memory
- // allocated (cons) per unit of scan work completed (mark) in a GC
- // cycle, divided by the CPU time spent on each activity.
- //
- // Updated at the end of each GC cycle, in endCycle.
- consMark float64
-
- // lastConsMark is the computed cons/mark value for the previous GC
- // cycle. Note that this is *not* the last value of cons/mark, but the
- // actual computed value. See endCycle for details.
- lastConsMark float64
-
- // gcPercentHeapGoal is the goal heapLive for when next GC ends derived
- // from gcPercent.
- //
- // Set to ^uint64(0) if gcPercent is disabled.
- gcPercentHeapGoal atomic.Uint64
-
- // sweepDistMinTrigger is the minimum trigger to ensure a minimum
- // sweep distance.
- //
- // This bound is also special because it applies to both the trigger
- // *and* the goal (all other trigger bounds must be based *on* the goal).
- //
- // It is computed ahead of time, at commit time. The theory is that,
- // absent a sudden change to a parameter like gcPercent, the trigger
- // will be chosen to always give the sweeper enough headroom. However,
- // such a change might dramatically and suddenly move up the trigger,
- // in which case we need to ensure the sweeper still has enough headroom.
- sweepDistMinTrigger atomic.Uint64
-
- // triggered is the point at which the current GC cycle actually triggered.
- // Only valid during the mark phase of a GC cycle, otherwise set to ^uint64(0).
- //
- // Updated while the world is stopped.
- triggered uint64
-
- // lastHeapGoal is the value of heapGoal at the moment the last GC
- // ended. Note that this is distinct from the last value heapGoal had,
- // because it could change if e.g. gcPercent changes.
- //
- // Read and written with the world stopped or with mheap_.lock held.
- lastHeapGoal uint64
-
- // heapLive is the number of bytes considered live by the GC.
- // That is: retained by the most recent GC plus allocated
- // since then. heapLive ≤ memstats.totalAlloc-memstats.totalFree, since
- // heapAlloc includes unmarked objects that have not yet been swept (and
- // hence goes up as we allocate and down as we sweep) while heapLive
- // excludes these objects (and hence only goes up between GCs).
- //
- // To reduce contention, this is updated only when obtaining a span
- // from an mcentral and at this point it counts all of the unallocated
- // slots in that span (which will be allocated before that mcache
- // obtains another span from that mcentral). Hence, it slightly
- // overestimates the "true" live heap size. It's better to overestimate
- // than to underestimate because 1) this triggers the GC earlier than
- // necessary rather than potentially too late and 2) this leads to a
- // conservative GC rate rather than a GC rate that is potentially too
- // low.
- //
- // Whenever this is updated, call traceHeapAlloc() and
- // this gcControllerState's revise() method.
- heapLive atomic.Uint64
-
- // heapScan is the number of bytes of "scannable" heap. This is the
- // live heap (as counted by heapLive), but omitting no-scan objects and
- // no-scan tails of objects.
- //
- // This value is fixed at the start of a GC cycle. It represents the
- // maximum scannable heap.
- heapScan atomic.Uint64
-
- // lastHeapScan is the number of bytes of heap that were scanned
- // last GC cycle. It is the same as heapMarked, but only
- // includes the "scannable" parts of objects.
- //
- // Updated when the world is stopped.
- lastHeapScan uint64
-
- // lastStackScan is the number of bytes of stack that were scanned
- // last GC cycle.
- lastStackScan atomic.Uint64
-
- // maxStackScan is the amount of allocated goroutine stack space in
- // use by goroutines.
- //
- // This number tracks allocated goroutine stack space rather than used
- // goroutine stack space (i.e. what is actually scanned) because used
- // goroutine stack space is much harder to measure cheaply. By using
- // allocated space, we make an overestimate; this is OK, it's better
- // to conservatively overcount than undercount.
- maxStackScan atomic.Uint64
-
- // globalsScan is the total amount of global variable space
- // that is scannable.
- globalsScan atomic.Uint64
-
- // heapMarked is the number of bytes marked by the previous
- // GC. After mark termination, heapLive == heapMarked, but
- // unlike heapLive, heapMarked does not change until the
- // next mark termination.
- heapMarked uint64
-
- // heapScanWork is the total heap scan work performed this cycle.
- // stackScanWork is the total stack scan work performed this cycle.
- // globalsScanWork is the total globals scan work performed this cycle.
- //
- // These are updated atomically during the cycle. Updates occur in
- // bounded batches, since they are both written and read
- // throughout the cycle. At the end of the cycle, heapScanWork is how
- // much of the retained heap is scannable.
- //
- // Currently these are measured in bytes. For most uses, this is an
- // opaque unit of work, but for estimation the definition is important.
- //
- // Note that stackScanWork includes only stack space scanned, not all
- // of the allocated stack.
- heapScanWork atomic.Int64
- stackScanWork atomic.Int64
- globalsScanWork atomic.Int64
-
- // bgScanCredit is the scan work credit accumulated by the concurrent
- // background scan. This credit is accumulated by the background scan
- // and stolen by mutator assists. Updates occur in bounded batches,
- // since it is both written and read throughout the cycle.
- bgScanCredit atomic.Int64
-
- // assistTime is the nanoseconds spent in mutator assists
- // during this cycle. This is updated atomically, and must also
- // be updated atomically even during a STW, because it is read
- // by sysmon. Updates occur in bounded batches, since it is both
- // written and read throughout the cycle.
- assistTime atomic.Int64
-
- // dedicatedMarkTime is the nanoseconds spent in dedicated mark workers
- // during this cycle. This is updated at the end of the concurrent mark
- // phase.
- dedicatedMarkTime atomic.Int64
-
- // fractionalMarkTime is the nanoseconds spent in the fractional mark
- // worker during this cycle. This is updated throughout the cycle and
- // will be up-to-date if the fractional mark worker is not currently
- // running.
- fractionalMarkTime atomic.Int64
-
- // idleMarkTime is the nanoseconds spent in idle marking during this
- // cycle. This is updated throughout the cycle.
- idleMarkTime atomic.Int64
-
- // markStartTime is the absolute start time in nanoseconds
- // that assists and background mark workers started.
- markStartTime int64
-
- // dedicatedMarkWorkersNeeded is the number of dedicated mark workers
- // that need to be started. This is computed at the beginning of each
- // cycle and decremented as dedicated mark workers get started.
- dedicatedMarkWorkersNeeded atomic.Int64
-
- // idleMarkWorkers is two packed int32 values in a single uint64.
- // These two values are always updated simultaneously.
- //
- // The bottom int32 is the current number of idle mark workers executing.
- //
- // The top int32 is the maximum number of idle mark workers allowed to
- // execute concurrently. Normally, this number is just gomaxprocs. However,
- // during periodic GC cycles it is set to 0 because the system is idle
- // anyway; there's no need to go full blast on all of GOMAXPROCS.
- //
- // The maximum number of idle mark workers is used to prevent new workers
- // from starting, but it is not a hard maximum. It is possible (but
- // exceedingly rare) for the current number of idle mark workers to
- // transiently exceed the maximum. This could happen if the maximum changes
- // just after a GC ends, and an M with no P.
- //
- // Note that if we have no dedicated mark workers, we set this value to
- // 1 in this case we only have fractional GC workers which aren't scheduled
- // strictly enough to ensure GC progress. As a result, idle-priority mark
- // workers are vital to GC progress in these situations.
- //
- // For example, consider a situation in which goroutines block on the GC
- // (such as via runtime.GOMAXPROCS) and only fractional mark workers are
- // scheduled (e.g. GOMAXPROCS=1). Without idle-priority mark workers, the
- // last running M might skip scheduling a fractional mark worker if its
- // utilization goal is met, such that once it goes to sleep (because there's
- // nothing to do), there will be nothing else to spin up a new M for the
- // fractional worker in the future, stalling GC progress and causing a
- // deadlock. However, idle-priority workers will *always* run when there is
- // nothing left to do, ensuring the GC makes progress.
- //
- // See github.com/golang/go/issues/44163 for more details.
- idleMarkWorkers atomic.Uint64
-
- // assistWorkPerByte is the ratio of scan work to allocated
- // bytes that should be performed by mutator assists. This is
- // computed at the beginning of each cycle and updated every
- // time heapScan is updated.
- assistWorkPerByte atomic.Float64
-
- // assistBytesPerWork is 1/assistWorkPerByte.
- //
- // Note that because this is read and written independently
- // from assistWorkPerByte users may notice a skew between
- // the two values, and such a state should be safe.
- assistBytesPerWork atomic.Float64
-
- // fractionalUtilizationGoal is the fraction of wall clock
- // time that should be spent in the fractional mark worker on
- // each P that isn't running a dedicated worker.
- //
- // For example, if the utilization goal is 25% and there are
- // no dedicated workers, this will be 0.25. If the goal is
- // 25%, there is one dedicated worker, and GOMAXPROCS is 5,
- // this will be 0.05 to make up the missing 5%.
- //
- // If this is zero, no fractional workers are needed.
- fractionalUtilizationGoal float64
-
- // These memory stats are effectively duplicates of fields from
- // memstats.heapStats but are updated atomically or with the world
- // stopped and don't provide the same consistency guarantees.
- //
- // Because the runtime is responsible for managing a memory limit, it's
- // useful to couple these stats more tightly to the gcController, which
- // is intimately connected to how that memory limit is maintained.
- heapInUse sysMemStat // bytes in mSpanInUse spans
- heapReleased sysMemStat // bytes released to the OS
- heapFree sysMemStat // bytes not in any span, but not released to the OS
- totalAlloc atomic.Uint64 // total bytes allocated
- totalFree atomic.Uint64 // total bytes freed
- mappedReady atomic.Uint64 // total virtual memory in the Ready state (see mem.go).
-
- // test indicates that this is a test-only copy of gcControllerState.
- test bool
-
- _ cpu.CacheLinePad
-}
-
-func (c *gcControllerState) init(gcPercent int32, memoryLimit int64) {
- c.heapMinimum = defaultHeapMinimum
- c.triggered = ^uint64(0)
- c.setGCPercent(gcPercent)
- c.setMemoryLimit(memoryLimit)
- c.commit(true) // No sweep phase in the first GC cycle.
- // N.B. Don't bother calling traceHeapGoal. Tracing is never enabled at
- // initialization time.
- // N.B. No need to call revise; there's no GC enabled during
- // initialization.
-}
-
-// startCycle resets the GC controller's state and computes estimates
-// for a new GC cycle. The caller must hold worldsema and the world
-// must be stopped.
-func (c *gcControllerState) startCycle(markStartTime int64, procs int, trigger gcTrigger) {
- c.heapScanWork.Store(0)
- c.stackScanWork.Store(0)
- c.globalsScanWork.Store(0)
- c.bgScanCredit.Store(0)
- c.assistTime.Store(0)
- c.dedicatedMarkTime.Store(0)
- c.fractionalMarkTime.Store(0)
- c.idleMarkTime.Store(0)
- c.markStartTime = markStartTime
- c.triggered = c.heapLive.Load()
-
- // Compute the background mark utilization goal. In general,
- // this may not come out exactly. We round the number of
- // dedicated workers so that the utilization is closest to
- // 25%. For small GOMAXPROCS, this would introduce too much
- // error, so we add fractional workers in that case.
- totalUtilizationGoal := float64(procs) * gcBackgroundUtilization
- dedicatedMarkWorkersNeeded := int64(totalUtilizationGoal + 0.5)
- utilError := float64(dedicatedMarkWorkersNeeded)/totalUtilizationGoal - 1
- const maxUtilError = 0.3
- if utilError < -maxUtilError || utilError > maxUtilError {
- // Rounding put us more than 30% off our goal. With
- // gcBackgroundUtilization of 25%, this happens for
- // GOMAXPROCS<=3 or GOMAXPROCS=6. Enable fractional
- // workers to compensate.
- if float64(dedicatedMarkWorkersNeeded) > totalUtilizationGoal {
- // Too many dedicated workers.
- dedicatedMarkWorkersNeeded--
- }
- c.fractionalUtilizationGoal = (totalUtilizationGoal - float64(dedicatedMarkWorkersNeeded)) / float64(procs)
- } else {
- c.fractionalUtilizationGoal = 0
- }
-
- // In STW mode, we just want dedicated workers.
- if debug.gcstoptheworld > 0 {
- dedicatedMarkWorkersNeeded = int64(procs)
- c.fractionalUtilizationGoal = 0
- }
-
- // Clear per-P state
- for _, p := range allp {
- p.gcAssistTime = 0
- p.gcFractionalMarkTime = 0
- }
-
- if trigger.kind == gcTriggerTime {
- // During a periodic GC cycle, reduce the number of idle mark workers
- // required. However, we need at least one dedicated mark worker or
- // idle GC worker to ensure GC progress in some scenarios (see comment
- // on maxIdleMarkWorkers).
- if dedicatedMarkWorkersNeeded > 0 {
- c.setMaxIdleMarkWorkers(0)
- } else {
- // TODO(mknyszek): The fundamental reason why we need this is because
- // we can't count on the fractional mark worker to get scheduled.
- // Fix that by ensuring it gets scheduled according to its quota even
- // if the rest of the application is idle.
- c.setMaxIdleMarkWorkers(1)
- }
- } else {
- // N.B. gomaxprocs and dedicatedMarkWorkersNeeded are guaranteed not to
- // change during a GC cycle.
- c.setMaxIdleMarkWorkers(int32(procs) - int32(dedicatedMarkWorkersNeeded))
- }
-
- // Compute initial values for controls that are updated
- // throughout the cycle.
- c.dedicatedMarkWorkersNeeded.Store(dedicatedMarkWorkersNeeded)
- c.revise()
-
- if debug.gcpacertrace > 0 {
- heapGoal := c.heapGoal()
- assistRatio := c.assistWorkPerByte.Load()
- print("pacer: assist ratio=", assistRatio,
- " (scan ", gcController.heapScan.Load()>>20, " MB in ",
- work.initialHeapLive>>20, "->",
- heapGoal>>20, " MB)",
- " workers=", dedicatedMarkWorkersNeeded,
- "+", c.fractionalUtilizationGoal, "\n")
- }
-}
-
-// revise updates the assist ratio during the GC cycle to account for
-// improved estimates. This should be called whenever gcController.heapScan,
-// gcController.heapLive, or if any inputs to gcController.heapGoal are
-// updated. It is safe to call concurrently, but it may race with other
-// calls to revise.
-//
-// The result of this race is that the two assist ratio values may not line
-// up or may be stale. In practice this is OK because the assist ratio
-// moves slowly throughout a GC cycle, and the assist ratio is a best-effort
-// heuristic anyway. Furthermore, no part of the heuristic depends on
-// the two assist ratio values being exact reciprocals of one another, since
-// the two values are used to convert values from different sources.
-//
-// The worst case result of this raciness is that we may miss a larger shift
-// in the ratio (say, if we decide to pace more aggressively against the
-// hard heap goal) but even this "hard goal" is best-effort (see #40460).
-// The dedicated GC should ensure we don't exceed the hard goal by too much
-// in the rare case we do exceed it.
-//
-// It should only be called when gcBlackenEnabled != 0 (because this
-// is when assists are enabled and the necessary statistics are
-// available).
-func (c *gcControllerState) revise() {
- gcPercent := c.gcPercent.Load()
- if gcPercent < 0 {
- // If GC is disabled but we're running a forced GC,
- // act like GOGC is huge for the below calculations.
- gcPercent = 100000
- }
- live := c.heapLive.Load()
- scan := c.heapScan.Load()
- work := c.heapScanWork.Load() + c.stackScanWork.Load() + c.globalsScanWork.Load()
-
- // Assume we're under the soft goal. Pace GC to complete at
- // heapGoal assuming the heap is in steady-state.
- heapGoal := int64(c.heapGoal())
-
- // The expected scan work is computed as the amount of bytes scanned last
- // GC cycle (both heap and stack), plus our estimate of globals work for this cycle.
- scanWorkExpected := int64(c.lastHeapScan + c.lastStackScan.Load() + c.globalsScan.Load())
-
- // maxScanWork is a worst-case estimate of the amount of scan work that
- // needs to be performed in this GC cycle. Specifically, it represents
- // the case where *all* scannable memory turns out to be live, and
- // *all* allocated stack space is scannable.
- maxStackScan := c.maxStackScan.Load()
- maxScanWork := int64(scan + maxStackScan + c.globalsScan.Load())
- if work > scanWorkExpected {
- // We've already done more scan work than expected. Because our expectation
- // is based on a steady-state scannable heap size, we assume this means our
- // heap is growing. Compute a new heap goal that takes our existing runway
- // computed for scanWorkExpected and extrapolates it to maxScanWork, the worst-case
- // scan work. This keeps our assist ratio stable if the heap continues to grow.
- //
- // The effect of this mechanism is that assists stay flat in the face of heap
- // growths. It's OK to use more memory this cycle to scan all the live heap,
- // because the next GC cycle is inevitably going to use *at least* that much
- // memory anyway.
- extHeapGoal := int64(float64(heapGoal-int64(c.triggered))/float64(scanWorkExpected)*float64(maxScanWork)) + int64(c.triggered)
- scanWorkExpected = maxScanWork
-
- // hardGoal is a hard limit on the amount that we're willing to push back the
- // heap goal, and that's twice the heap goal (i.e. if GOGC=100 and the heap and/or
- // stacks and/or globals grow to twice their size, this limits the current GC cycle's
- // growth to 4x the original live heap's size).
- //
- // This maintains the invariant that we use no more memory than the next GC cycle
- // will anyway.
- hardGoal := int64((1.0 + float64(gcPercent)/100.0) * float64(heapGoal))
- if extHeapGoal > hardGoal {
- extHeapGoal = hardGoal
- }
- heapGoal = extHeapGoal
- }
- if int64(live) > heapGoal {
- // We're already past our heap goal, even the extrapolated one.
- // Leave ourselves some extra runway, so in the worst case we
- // finish by that point.
- const maxOvershoot = 1.1
- heapGoal = int64(float64(heapGoal) * maxOvershoot)
-
- // Compute the upper bound on the scan work remaining.
- scanWorkExpected = maxScanWork
- }
-
- // Compute the remaining scan work estimate.
- //
- // Note that we currently count allocations during GC as both
- // scannable heap (heapScan) and scan work completed
- // (scanWork), so allocation will change this difference
- // slowly in the soft regime and not at all in the hard
- // regime.
- scanWorkRemaining := scanWorkExpected - work
- if scanWorkRemaining < 1000 {
- // We set a somewhat arbitrary lower bound on
- // remaining scan work since if we aim a little high,
- // we can miss by a little.
- //
- // We *do* need to enforce that this is at least 1,
- // since marking is racy and double-scanning objects
- // may legitimately make the remaining scan work
- // negative, even in the hard goal regime.
- scanWorkRemaining = 1000
- }
-
- // Compute the heap distance remaining.
- heapRemaining := heapGoal - int64(live)
- if heapRemaining <= 0 {
- // This shouldn't happen, but if it does, avoid
- // dividing by zero or setting the assist negative.
- heapRemaining = 1
- }
-
- // Compute the mutator assist ratio so by the time the mutator
- // allocates the remaining heap bytes up to heapGoal, it will
- // have done (or stolen) the remaining amount of scan work.
- // Note that the assist ratio values are updated atomically
- // but not together. This means there may be some degree of
- // skew between the two values. This is generally OK as the
- // values shift relatively slowly over the course of a GC
- // cycle.
- assistWorkPerByte := float64(scanWorkRemaining) / float64(heapRemaining)
- assistBytesPerWork := float64(heapRemaining) / float64(scanWorkRemaining)
- c.assistWorkPerByte.Store(assistWorkPerByte)
- c.assistBytesPerWork.Store(assistBytesPerWork)
-}
-
-// endCycle computes the consMark estimate for the next cycle.
-// userForced indicates whether the current GC cycle was forced
-// by the application.
-func (c *gcControllerState) endCycle(now int64, procs int, userForced bool) {
- // Record last heap goal for the scavenger.
- // We'll be updating the heap goal soon.
- gcController.lastHeapGoal = c.heapGoal()
-
- // Compute the duration of time for which assists were turned on.
- assistDuration := now - c.markStartTime
-
- // Assume background mark hit its utilization goal.
- utilization := gcBackgroundUtilization
- // Add assist utilization; avoid divide by zero.
- if assistDuration > 0 {
- utilization += float64(c.assistTime.Load()) / float64(assistDuration*int64(procs))
- }
-
- if c.heapLive.Load() <= c.triggered {
- // Shouldn't happen, but let's be very safe about this in case the
- // GC is somehow extremely short.
- //
- // In this case though, the only reasonable value for c.heapLive-c.triggered
- // would be 0, which isn't really all that useful, i.e. the GC was so short
- // that it didn't matter.
- //
- // Ignore this case and don't update anything.
- return
- }
- idleUtilization := 0.0
- if assistDuration > 0 {
- idleUtilization = float64(c.idleMarkTime.Load()) / float64(assistDuration*int64(procs))
- }
- // Determine the cons/mark ratio.
- //
- // The units we want for the numerator and denominator are both B / cpu-ns.
- // We get this by taking the bytes allocated or scanned, and divide by the amount of
- // CPU time it took for those operations. For allocations, that CPU time is
- //
- // assistDuration * procs * (1 - utilization)
- //
- // Where utilization includes just background GC workers and assists. It does *not*
- // include idle GC work time, because in theory the mutator is free to take that at
- // any point.
- //
- // For scanning, that CPU time is
- //
- // assistDuration * procs * (utilization + idleUtilization)
- //
- // In this case, we *include* idle utilization, because that is additional CPU time that
- // the GC had available to it.
- //
- // In effect, idle GC time is sort of double-counted here, but it's very weird compared
- // to other kinds of GC work, because of how fluid it is. Namely, because the mutator is
- // *always* free to take it.
- //
- // So this calculation is really:
- // (heapLive-trigger) / (assistDuration * procs * (1-utilization)) /
- // (scanWork) / (assistDuration * procs * (utilization+idleUtilization)
- //
- // Note that because we only care about the ratio, assistDuration and procs cancel out.
- scanWork := c.heapScanWork.Load() + c.stackScanWork.Load() + c.globalsScanWork.Load()
- currentConsMark := (float64(c.heapLive.Load()-c.triggered) * (utilization + idleUtilization)) /
- (float64(scanWork) * (1 - utilization))
-
- // Update our cons/mark estimate. This is the raw value above, but averaged over 2 GC cycles
- // because it tends to be jittery, even in the steady-state. The smoothing helps the GC to
- // maintain much more stable cycle-by-cycle behavior.
- oldConsMark := c.consMark
- c.consMark = (currentConsMark + c.lastConsMark) / 2
- c.lastConsMark = currentConsMark
-
- if debug.gcpacertrace > 0 {
- printlock()
- goal := gcGoalUtilization * 100
- print("pacer: ", int(utilization*100), "% CPU (", int(goal), " exp.) for ")
- print(c.heapScanWork.Load(), "+", c.stackScanWork.Load(), "+", c.globalsScanWork.Load(), " B work (", c.lastHeapScan+c.lastStackScan.Load()+c.globalsScan.Load(), " B exp.) ")
- live := c.heapLive.Load()
- print("in ", c.triggered, " B -> ", live, " B (∆goal ", int64(live)-int64(c.lastHeapGoal), ", cons/mark ", oldConsMark, ")")
- println()
- printunlock()
- }
-}
-
-// enlistWorker encourages another dedicated mark worker to start on
-// another P if there are spare worker slots. It is used by putfull
-// when more work is made available.
-//
-//go:nowritebarrier
-func (c *gcControllerState) enlistWorker() {
- // If there are idle Ps, wake one so it will run an idle worker.
- // NOTE: This is suspected of causing deadlocks. See golang.org/issue/19112.
- //
- // if sched.npidle.Load() != 0 && sched.nmspinning.Load() == 0 {
- // wakep()
- // return
- // }
-
- // There are no idle Ps. If we need more dedicated workers,
- // try to preempt a running P so it will switch to a worker.
- if c.dedicatedMarkWorkersNeeded.Load() <= 0 {
- return
- }
- // Pick a random other P to preempt.
- if gomaxprocs <= 1 {
- return
- }
- gp := getg()
- if gp == nil || gp.m == nil || gp.m.p == 0 {
- return
- }
- myID := gp.m.p.ptr().id
- for tries := 0; tries < 5; tries++ {
- id := int32(fastrandn(uint32(gomaxprocs - 1)))
- if id >= myID {
- id++
- }
- p := allp[id]
- if p.status != _Prunning {
- continue
- }
- if preemptone(p) {
- return
- }
- }
-}
-
-// findRunnableGCWorker returns a background mark worker for pp if it
-// should be run. This must only be called when gcBlackenEnabled != 0.
-func (c *gcControllerState) findRunnableGCWorker(pp *p, now int64) (*g, int64) {
- if gcBlackenEnabled == 0 {
- throw("gcControllerState.findRunnable: blackening not enabled")
- }
-
- // Since we have the current time, check if the GC CPU limiter
- // hasn't had an update in a while. This check is necessary in
- // case the limiter is on but hasn't been checked in a while and
- // so may have left sufficient headroom to turn off again.
- if now == 0 {
- now = nanotime()
- }
- if gcCPULimiter.needUpdate(now) {
- gcCPULimiter.update(now)
- }
-
- if !gcMarkWorkAvailable(pp) {
- // No work to be done right now. This can happen at
- // the end of the mark phase when there are still
- // assists tapering off. Don't bother running a worker
- // now because it'll just return immediately.
- return nil, now
- }
-
- // Grab a worker before we commit to running below.
- node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
- if node == nil {
- // There is at least one worker per P, so normally there are
- // enough workers to run on all Ps, if necessary. However, once
- // a worker enters gcMarkDone it may park without rejoining the
- // pool, thus freeing a P with no corresponding worker.
- // gcMarkDone never depends on another worker doing work, so it
- // is safe to simply do nothing here.
- //
- // If gcMarkDone bails out without completing the mark phase,
- // it will always do so with queued global work. Thus, that P
- // will be immediately eligible to re-run the worker G it was
- // just using, ensuring work can complete.
- return nil, now
- }
-
- decIfPositive := func(val *atomic.Int64) bool {
- for {
- v := val.Load()
- if v <= 0 {
- return false
- }
-
- if val.CompareAndSwap(v, v-1) {
- return true
- }
- }
- }
-
- if decIfPositive(&c.dedicatedMarkWorkersNeeded) {
- // This P is now dedicated to marking until the end of
- // the concurrent mark phase.
- pp.gcMarkWorkerMode = gcMarkWorkerDedicatedMode
- } else if c.fractionalUtilizationGoal == 0 {
- // No need for fractional workers.
- gcBgMarkWorkerPool.push(&node.node)
- return nil, now
- } else {
- // Is this P behind on the fractional utilization
- // goal?
- //
- // This should be kept in sync with pollFractionalWorkerExit.
- delta := now - c.markStartTime
- if delta > 0 && float64(pp.gcFractionalMarkTime)/float64(delta) > c.fractionalUtilizationGoal {
- // Nope. No need to run a fractional worker.
- gcBgMarkWorkerPool.push(&node.node)
- return nil, now
- }
- // Run a fractional worker.
- pp.gcMarkWorkerMode = gcMarkWorkerFractionalMode
- }
-
- // Run the background mark worker.
- gp := node.gp.ptr()
- casgstatus(gp, _Gwaiting, _Grunnable)
- if trace.enabled {
- traceGoUnpark(gp, 0)
- }
- return gp, now
-}
-
-// resetLive sets up the controller state for the next mark phase after the end
-// of the previous one. Must be called after endCycle and before commit, before
-// the world is started.
-//
-// The world must be stopped.
-func (c *gcControllerState) resetLive(bytesMarked uint64) {
- c.heapMarked = bytesMarked
- c.heapLive.Store(bytesMarked)
- c.heapScan.Store(uint64(c.heapScanWork.Load()))
- c.lastHeapScan = uint64(c.heapScanWork.Load())
- c.lastStackScan.Store(uint64(c.stackScanWork.Load()))
- c.triggered = ^uint64(0) // Reset triggered.
-
- // heapLive was updated, so emit a trace event.
- if trace.enabled {
- traceHeapAlloc(bytesMarked)
- }
-}
-
-// markWorkerStop must be called whenever a mark worker stops executing.
-//
-// It updates mark work accounting in the controller by a duration of
-// work in nanoseconds and other bookkeeping.
-//
-// Safe to execute at any time.
-func (c *gcControllerState) markWorkerStop(mode gcMarkWorkerMode, duration int64) {
- switch mode {
- case gcMarkWorkerDedicatedMode:
- c.dedicatedMarkTime.Add(duration)
- c.dedicatedMarkWorkersNeeded.Add(1)
- case gcMarkWorkerFractionalMode:
- c.fractionalMarkTime.Add(duration)
- case gcMarkWorkerIdleMode:
- c.idleMarkTime.Add(duration)
- c.removeIdleMarkWorker()
- default:
- throw("markWorkerStop: unknown mark worker mode")
- }
-}
-
-func (c *gcControllerState) update(dHeapLive, dHeapScan int64) {
- if dHeapLive != 0 {
- live := gcController.heapLive.Add(dHeapLive)
- if trace.enabled {
- // gcController.heapLive changed.
- traceHeapAlloc(live)
- }
- }
- if gcBlackenEnabled == 0 {
- // Update heapScan when we're not in a current GC. It is fixed
- // at the beginning of a cycle.
- if dHeapScan != 0 {
- gcController.heapScan.Add(dHeapScan)
- }
- } else {
- // gcController.heapLive changed.
- c.revise()
- }
-}
-
-func (c *gcControllerState) addScannableStack(pp *p, amount int64) {
- if pp == nil {
- c.maxStackScan.Add(amount)
- return
- }
- pp.maxStackScanDelta += amount
- if pp.maxStackScanDelta >= maxStackScanSlack || pp.maxStackScanDelta <= -maxStackScanSlack {
- c.maxStackScan.Add(pp.maxStackScanDelta)
- pp.maxStackScanDelta = 0
- }
-}
-
-func (c *gcControllerState) addGlobals(amount int64) {
- c.globalsScan.Add(amount)
-}
-
-// heapGoal returns the current heap goal.
-func (c *gcControllerState) heapGoal() uint64 {
- goal, _ := c.heapGoalInternal()
- return goal
-}
-
-// heapGoalInternal is the implementation of heapGoal which returns additional
-// information that is necessary for computing the trigger.
-//
-// The returned minTrigger is always <= goal.
-func (c *gcControllerState) heapGoalInternal() (goal, minTrigger uint64) {
- // Start with the goal calculated for gcPercent.
- goal = c.gcPercentHeapGoal.Load()
-
- // Check if the memory-limit-based goal is smaller, and if so, pick that.
- if newGoal := c.memoryLimitHeapGoal(); go119MemoryLimitSupport && newGoal < goal {
- goal = newGoal
- } else {
- // We're not limited by the memory limit goal, so perform a series of
- // adjustments that might move the goal forward in a variety of circumstances.
-
- sweepDistTrigger := c.sweepDistMinTrigger.Load()
- if sweepDistTrigger > goal {
- // Set the goal to maintain a minimum sweep distance since
- // the last call to commit. Note that we never want to do this
- // if we're in the memory limit regime, because it could push
- // the goal up.
- goal = sweepDistTrigger
- }
- // Since we ignore the sweep distance trigger in the memory
- // limit regime, we need to ensure we don't propagate it to
- // the trigger, because it could cause a violation of the
- // invariant that the trigger < goal.
- minTrigger = sweepDistTrigger
-
- // Ensure that the heap goal is at least a little larger than
- // the point at which we triggered. This may not be the case if GC
- // start is delayed or if the allocation that pushed gcController.heapLive
- // over trigger is large or if the trigger is really close to
- // GOGC. Assist is proportional to this distance, so enforce a
- // minimum distance, even if it means going over the GOGC goal
- // by a tiny bit.
- //
- // Ignore this if we're in the memory limit regime: we'd prefer to
- // have the GC respond hard about how close we are to the goal than to
- // push the goal back in such a manner that it could cause us to exceed
- // the memory limit.
- const minRunway = 64 << 10
- if c.triggered != ^uint64(0) && goal < c.triggered+minRunway {
- goal = c.triggered + minRunway
- }
- }
- return
-}
-
-// memoryLimitHeapGoal returns a heap goal derived from memoryLimit.
-func (c *gcControllerState) memoryLimitHeapGoal() uint64 {
- // Start by pulling out some values we'll need. Be careful about overflow.
- var heapFree, heapAlloc, mappedReady uint64
- for {
- heapFree = c.heapFree.load() // Free and unscavenged memory.
- heapAlloc = c.totalAlloc.Load() - c.totalFree.Load() // Heap object bytes in use.
- mappedReady = c.mappedReady.Load() // Total unreleased mapped memory.
- if heapFree+heapAlloc <= mappedReady {
- break
- }
- // It is impossible for total unreleased mapped memory to exceed heap memory, but
- // because these stats are updated independently, we may observe a partial update
- // including only some values. Thus, we appear to break the invariant. However,
- // this condition is necessarily transient, so just try again. In the case of a
- // persistent accounting error, we'll deadlock here.
- }
-
- // Below we compute a goal from memoryLimit. There are a few things to be aware of.
- // Firstly, the memoryLimit does not easily compare to the heap goal: the former
- // is total mapped memory by the runtime that hasn't been released, while the latter is
- // only heap object memory. Intuitively, the way we convert from one to the other is to
- // subtract everything from memoryLimit that both contributes to the memory limit (so,
- // ignore scavenged memory) and doesn't contain heap objects. This isn't quite what
- // lines up with reality, but it's a good starting point.
- //
- // In practice this computation looks like the following:
- //
- // memoryLimit - ((mappedReady - heapFree - heapAlloc) + max(mappedReady - memoryLimit, 0)) - memoryLimitHeapGoalHeadroom
- // ^1 ^2 ^3
- //
- // Let's break this down.
- //
- // The first term (marker 1) is everything that contributes to the memory limit and isn't
- // or couldn't become heap objects. It represents, broadly speaking, non-heap overheads.
- // One oddity you may have noticed is that we also subtract out heapFree, i.e. unscavenged
- // memory that may contain heap objects in the future.
- //
- // Let's take a step back. In an ideal world, this term would look something like just
- // the heap goal. That is, we "reserve" enough space for the heap to grow to the heap
- // goal, and subtract out everything else. This is of course impossible; the definition
- // is circular! However, this impossible definition contains a key insight: the amount
- // we're *going* to use matters just as much as whatever we're currently using.
- //
- // Consider if the heap shrinks to 1/10th its size, leaving behind lots of free and
- // unscavenged memory. mappedReady - heapAlloc will be quite large, because of that free
- // and unscavenged memory, pushing the goal down significantly.
- //
- // heapFree is also safe to exclude from the memory limit because in the steady-state, it's
- // just a pool of memory for future heap allocations, and making new allocations from heapFree
- // memory doesn't increase overall memory use. In transient states, the scavenger and the
- // allocator actively manage the pool of heapFree memory to maintain the memory limit.
- //
- // The second term (marker 2) is the amount of memory we've exceeded the limit by, and is
- // intended to help recover from such a situation. By pushing the heap goal down, we also
- // push the trigger down, triggering and finishing a GC sooner in order to make room for
- // other memory sources. Note that since we're effectively reducing the heap goal by X bytes,
- // we're actually giving more than X bytes of headroom back, because the heap goal is in
- // terms of heap objects, but it takes more than X bytes (e.g. due to fragmentation) to store
- // X bytes worth of objects.
- //
- // The third term (marker 3) subtracts an additional memoryLimitHeapGoalHeadroom bytes from the
- // heap goal. As the name implies, this is to provide additional headroom in the face of pacing
- // inaccuracies. This is a fixed number of bytes because these inaccuracies disproportionately
- // affect small heaps: as heaps get smaller, the pacer's inputs get fuzzier. Shorter GC cycles
- // and less GC work means noisy external factors like the OS scheduler have a greater impact.
-
- memoryLimit := uint64(c.memoryLimit.Load())
-
- // Compute term 1.
- nonHeapMemory := mappedReady - heapFree - heapAlloc
-
- // Compute term 2.
- var overage uint64
- if mappedReady > memoryLimit {
- overage = mappedReady - memoryLimit
- }
-
- if nonHeapMemory+overage >= memoryLimit {
- // We're at a point where non-heap memory exceeds the memory limit on its own.
- // There's honestly not much we can do here but just trigger GCs continuously
- // and let the CPU limiter reign that in. Something has to give at this point.
- // Set it to heapMarked, the lowest possible goal.
- return c.heapMarked
- }
-
- // Compute the goal.
- goal := memoryLimit - (nonHeapMemory + overage)
-
- // Apply some headroom to the goal to account for pacing inaccuracies.
- // Be careful about small limits.
- if goal < memoryLimitHeapGoalHeadroom || goal-memoryLimitHeapGoalHeadroom < memoryLimitHeapGoalHeadroom {
- goal = memoryLimitHeapGoalHeadroom
- } else {
- goal = goal - memoryLimitHeapGoalHeadroom
- }
- // Don't let us go below the live heap. A heap goal below the live heap doesn't make sense.
- if goal < c.heapMarked {
- goal = c.heapMarked
- }
- return goal
-}
-
-const (
- // These constants determine the bounds on the GC trigger as a fraction
- // of heap bytes allocated between the start of a GC (heapLive == heapMarked)
- // and the end of a GC (heapLive == heapGoal).
- //
- // The constants are obscured in this way for efficiency. The denominator
- // of the fraction is always a power-of-two for a quick division, so that
- // the numerator is a single constant integer multiplication.
- triggerRatioDen = 64
-
- // The minimum trigger constant was chosen empirically: given a sufficiently
- // fast/scalable allocator with 48 Ps that could drive the trigger ratio
- // to <0.05, this constant causes applications to retain the same peak
- // RSS compared to not having this allocator.
- minTriggerRatioNum = 45 // ~0.7
-
- // The maximum trigger constant is chosen somewhat arbitrarily, but the
- // current constant has served us well over the years.
- maxTriggerRatioNum = 61 // ~0.95
-)
-
-// trigger returns the current point at which a GC should trigger along with
-// the heap goal.
-//
-// The returned value may be compared against heapLive to determine whether
-// the GC should trigger. Thus, the GC trigger condition should be (but may
-// not be, in the case of small movements for efficiency) checked whenever
-// the heap goal may change.
-func (c *gcControllerState) trigger() (uint64, uint64) {
- goal, minTrigger := c.heapGoalInternal()
-
- // Invariant: the trigger must always be less than the heap goal.
- //
- // Note that the memory limit sets a hard maximum on our heap goal,
- // but the live heap may grow beyond it.
-
- if c.heapMarked >= goal {
- // The goal should never be smaller than heapMarked, but let's be
- // defensive about it. The only reasonable trigger here is one that
- // causes a continuous GC cycle at heapMarked, but respect the goal
- // if it came out as smaller than that.
- return goal, goal
- }
-
- // Below this point, c.heapMarked < goal.
-
- // heapMarked is our absolute minimum, and it's possible the trigger
- // bound we get from heapGoalinternal is less than that.
- if minTrigger < c.heapMarked {
- minTrigger = c.heapMarked
- }
-
- // If we let the trigger go too low, then if the application
- // is allocating very rapidly we might end up in a situation
- // where we're allocating black during a nearly always-on GC.
- // The result of this is a growing heap and ultimately an
- // increase in RSS. By capping us at a point >0, we're essentially
- // saying that we're OK using more CPU during the GC to prevent
- // this growth in RSS.
- triggerLowerBound := uint64(((goal-c.heapMarked)/triggerRatioDen)*minTriggerRatioNum) + c.heapMarked
- if minTrigger < triggerLowerBound {
- minTrigger = triggerLowerBound
- }
-
- // For small heaps, set the max trigger point at maxTriggerRatio of the way
- // from the live heap to the heap goal. This ensures we always have *some*
- // headroom when the GC actually starts. For larger heaps, set the max trigger
- // point at the goal, minus the minimum heap size.
- //
- // This choice follows from the fact that the minimum heap size is chosen
- // to reflect the costs of a GC with no work to do. With a large heap but
- // very little scan work to perform, this gives us exactly as much runway
- // as we would need, in the worst case.
- maxTrigger := uint64(((goal-c.heapMarked)/triggerRatioDen)*maxTriggerRatioNum) + c.heapMarked
- if goal > defaultHeapMinimum && goal-defaultHeapMinimum > maxTrigger {
- maxTrigger = goal - defaultHeapMinimum
- }
- if maxTrigger < minTrigger {
- maxTrigger = minTrigger
- }
-
- // Compute the trigger from our bounds and the runway stored by commit.
- var trigger uint64
- runway := c.runway.Load()
- if runway > goal {
- trigger = minTrigger
- } else {
- trigger = goal - runway
- }
- if trigger < minTrigger {
- trigger = minTrigger
- }
- if trigger > maxTrigger {
- trigger = maxTrigger
- }
- if trigger > goal {
- print("trigger=", trigger, " heapGoal=", goal, "\n")
- print("minTrigger=", minTrigger, " maxTrigger=", maxTrigger, "\n")
- throw("produced a trigger greater than the heap goal")
- }
- return trigger, goal
-}
-
-// commit recomputes all pacing parameters needed to derive the
-// trigger and the heap goal. Namely, the gcPercent-based heap goal,
-// and the amount of runway we want to give the GC this cycle.
-//
-// This can be called any time. If GC is the in the middle of a
-// concurrent phase, it will adjust the pacing of that phase.
-//
-// isSweepDone should be the result of calling isSweepDone(),
-// unless we're testing or we know we're executing during a GC cycle.
-//
-// This depends on gcPercent, gcController.heapMarked, and
-// gcController.heapLive. These must be up to date.
-//
-// Callers must call gcControllerState.revise after calling this
-// function if the GC is enabled.
-//
-// mheap_.lock must be held or the world must be stopped.
-func (c *gcControllerState) commit(isSweepDone bool) {
- if !c.test {
- assertWorldStoppedOrLockHeld(&mheap_.lock)
- }
-
- if isSweepDone {
- // The sweep is done, so there aren't any restrictions on the trigger
- // we need to think about.
- c.sweepDistMinTrigger.Store(0)
- } else {
- // Concurrent sweep happens in the heap growth
- // from gcController.heapLive to trigger. Make sure we
- // give the sweeper some runway if it doesn't have enough.
- c.sweepDistMinTrigger.Store(c.heapLive.Load() + sweepMinHeapDistance)
- }
-
- // Compute the next GC goal, which is when the allocated heap
- // has grown by GOGC/100 over where it started the last cycle,
- // plus additional runway for non-heap sources of GC work.
- gcPercentHeapGoal := ^uint64(0)
- if gcPercent := c.gcPercent.Load(); gcPercent >= 0 {
- gcPercentHeapGoal = c.heapMarked + (c.heapMarked+c.lastStackScan.Load()+c.globalsScan.Load())*uint64(gcPercent)/100
- }
- // Apply the minimum heap size here. It's defined in terms of gcPercent
- // and is only updated by functions that call commit.
- if gcPercentHeapGoal < c.heapMinimum {
- gcPercentHeapGoal = c.heapMinimum
- }
- c.gcPercentHeapGoal.Store(gcPercentHeapGoal)
-
- // Compute the amount of runway we want the GC to have by using our
- // estimate of the cons/mark ratio.
- //
- // The idea is to take our expected scan work, and multiply it by
- // the cons/mark ratio to determine how long it'll take to complete
- // that scan work in terms of bytes allocated. This gives us our GC's
- // runway.
- //
- // However, the cons/mark ratio is a ratio of rates per CPU-second, but
- // here we care about the relative rates for some division of CPU
- // resources among the mutator and the GC.
- //
- // To summarize, we have B / cpu-ns, and we want B / ns. We get that
- // by multiplying by our desired division of CPU resources. We choose
- // to express CPU resources as GOMAPROCS*fraction. Note that because
- // we're working with a ratio here, we can omit the number of CPU cores,
- // because they'll appear in the numerator and denominator and cancel out.
- // As a result, this is basically just "weighing" the cons/mark ratio by
- // our desired division of resources.
- //
- // Furthermore, by setting the runway so that CPU resources are divided
- // this way, assuming that the cons/mark ratio is correct, we make that
- // division a reality.
- c.runway.Store(uint64((c.consMark * (1 - gcGoalUtilization) / (gcGoalUtilization)) * float64(c.lastHeapScan+c.lastStackScan.Load()+c.globalsScan.Load())))
-}
-
-// setGCPercent updates gcPercent. commit must be called after.
-// Returns the old value of gcPercent.
-//
-// The world must be stopped, or mheap_.lock must be held.
-func (c *gcControllerState) setGCPercent(in int32) int32 {
- if !c.test {
- assertWorldStoppedOrLockHeld(&mheap_.lock)
- }
-
- out := c.gcPercent.Load()
- if in < 0 {
- in = -1
- }
- c.heapMinimum = defaultHeapMinimum * uint64(in) / 100
- c.gcPercent.Store(in)
-
- return out
-}
-
-//go:linkname setGCPercent runtime/debug.setGCPercent
-func setGCPercent(in int32) (out int32) {
- // Run on the system stack since we grab the heap lock.
- systemstack(func() {
- lock(&mheap_.lock)
- out = gcController.setGCPercent(in)
- gcControllerCommit()
- unlock(&mheap_.lock)
- })
-
- // If we just disabled GC, wait for any concurrent GC mark to
- // finish so we always return with no GC running.
- if in < 0 {
- gcWaitOnMark(work.cycles.Load())
- }
-
- return out
-}
-
-func readGOGC() int32 {
- p := gogetenv("GOGC")
- if p == "off" {
- return -1
- }
- if n, ok := atoi32(p); ok {
- return n
- }
- return 100
-}
-
-// setMemoryLimit updates memoryLimit. commit must be called after
-// Returns the old value of memoryLimit.
-//
-// The world must be stopped, or mheap_.lock must be held.
-func (c *gcControllerState) setMemoryLimit(in int64) int64 {
- if !c.test {
- assertWorldStoppedOrLockHeld(&mheap_.lock)
- }
-
- out := c.memoryLimit.Load()
- if in >= 0 {
- c.memoryLimit.Store(in)
- }
-
- return out
-}
-
-//go:linkname setMemoryLimit runtime/debug.setMemoryLimit
-func setMemoryLimit(in int64) (out int64) {
- // Run on the system stack since we grab the heap lock.
- systemstack(func() {
- lock(&mheap_.lock)
- out = gcController.setMemoryLimit(in)
- if in < 0 || out == in {
- // If we're just checking the value or not changing
- // it, there's no point in doing the rest.
- unlock(&mheap_.lock)
- return
- }
- gcControllerCommit()
- unlock(&mheap_.lock)
- })
- return out
-}
-
-func readGOMEMLIMIT() int64 {
- p := gogetenv("GOMEMLIMIT")
- if p == "" || p == "off" {
- return maxInt64
- }
- n, ok := parseByteCount(p)
- if !ok {
- print("GOMEMLIMIT=", p, "\n")
- throw("malformed GOMEMLIMIT; see `go doc runtime/debug.SetMemoryLimit`")
- }
- return n
-}
-
-// addIdleMarkWorker attempts to add a new idle mark worker.
-//
-// If this returns true, the caller must become an idle mark worker unless
-// there's no background mark worker goroutines in the pool. This case is
-// harmless because there are already background mark workers running.
-// If this returns false, the caller must NOT become an idle mark worker.
-//
-// nosplit because it may be called without a P.
-//
-//go:nosplit
-func (c *gcControllerState) addIdleMarkWorker() bool {
- for {
- old := c.idleMarkWorkers.Load()
- n, max := int32(old&uint64(^uint32(0))), int32(old>>32)
- if n >= max {
- // See the comment on idleMarkWorkers for why
- // n > max is tolerated.
- return false
- }
- if n < 0 {
- print("n=", n, " max=", max, "\n")
- throw("negative idle mark workers")
- }
- new := uint64(uint32(n+1)) | (uint64(max) << 32)
- if c.idleMarkWorkers.CompareAndSwap(old, new) {
- return true
- }
- }
-}
-
-// needIdleMarkWorker is a hint as to whether another idle mark worker is needed.
-//
-// The caller must still call addIdleMarkWorker to become one. This is mainly
-// useful for a quick check before an expensive operation.
-//
-// nosplit because it may be called without a P.
-//
-//go:nosplit
-func (c *gcControllerState) needIdleMarkWorker() bool {
- p := c.idleMarkWorkers.Load()
- n, max := int32(p&uint64(^uint32(0))), int32(p>>32)
- return n < max
-}
-
-// removeIdleMarkWorker must be called when an new idle mark worker stops executing.
-func (c *gcControllerState) removeIdleMarkWorker() {
- for {
- old := c.idleMarkWorkers.Load()
- n, max := int32(old&uint64(^uint32(0))), int32(old>>32)
- if n-1 < 0 {
- print("n=", n, " max=", max, "\n")
- throw("negative idle mark workers")
- }
- new := uint64(uint32(n-1)) | (uint64(max) << 32)
- if c.idleMarkWorkers.CompareAndSwap(old, new) {
- return
- }
- }
-}
-
-// setMaxIdleMarkWorkers sets the maximum number of idle mark workers allowed.
-//
-// This method is optimistic in that it does not wait for the number of
-// idle mark workers to reduce to max before returning; it assumes the workers
-// will deschedule themselves.
-func (c *gcControllerState) setMaxIdleMarkWorkers(max int32) {
- for {
- old := c.idleMarkWorkers.Load()
- n := int32(old & uint64(^uint32(0)))
- if n < 0 {
- print("n=", n, " max=", max, "\n")
- throw("negative idle mark workers")
- }
- new := uint64(uint32(n)) | (uint64(max) << 32)
- if c.idleMarkWorkers.CompareAndSwap(old, new) {
- return
- }
- }
-}
-
-// gcControllerCommit is gcController.commit, but passes arguments from live
-// (non-test) data. It also updates any consumers of the GC pacing, such as
-// sweep pacing and the background scavenger.
-//
-// Calls gcController.commit.
-//
-// The heap lock must be held, so this must be executed on the system stack.
-//
-//go:systemstack
-func gcControllerCommit() {
- assertWorldStoppedOrLockHeld(&mheap_.lock)
-
- gcController.commit(isSweepDone())
-
- // Update mark pacing.
- if gcphase != _GCoff {
- gcController.revise()
- }
-
- // TODO(mknyszek): This isn't really accurate any longer because the heap
- // goal is computed dynamically. Still useful to snapshot, but not as useful.
- if trace.enabled {
- traceHeapGoal()
- }
-
- trigger, heapGoal := gcController.trigger()
- gcPaceSweeper(trigger)
- gcPaceScavenger(gcController.memoryLimit.Load(), heapGoal, gcController.lastHeapGoal)
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mgcscavenge.go b/contrib/go/_std_1.20/src/runtime/mgcscavenge.go
deleted file mode 100644
index e59340ec7c..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mgcscavenge.go
+++ /dev/null
@@ -1,1186 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Scavenging free pages.
-//
-// This file implements scavenging (the release of physical pages backing mapped
-// memory) of free and unused pages in the heap as a way to deal with page-level
-// fragmentation and reduce the RSS of Go applications.
-//
-// Scavenging in Go happens on two fronts: there's the background
-// (asynchronous) scavenger and the heap-growth (synchronous) scavenger.
-//
-// The former happens on a goroutine much like the background sweeper which is
-// soft-capped at using scavengePercent of the mutator's time, based on
-// order-of-magnitude estimates of the costs of scavenging. The background
-// scavenger's primary goal is to bring the estimated heap RSS of the
-// application down to a goal.
-//
-// Before we consider what this looks like, we need to split the world into two
-// halves. One in which a memory limit is not set, and one in which it is.
-//
-// For the former, the goal is defined as:
-// (retainExtraPercent+100) / 100 * (heapGoal / lastHeapGoal) * lastHeapInUse
-//
-// Essentially, we wish to have the application's RSS track the heap goal, but
-// the heap goal is defined in terms of bytes of objects, rather than pages like
-// RSS. As a result, we need to take into account for fragmentation internal to
-// spans. heapGoal / lastHeapGoal defines the ratio between the current heap goal
-// and the last heap goal, which tells us by how much the heap is growing and
-// shrinking. We estimate what the heap will grow to in terms of pages by taking
-// this ratio and multiplying it by heapInUse at the end of the last GC, which
-// allows us to account for this additional fragmentation. Note that this
-// procedure makes the assumption that the degree of fragmentation won't change
-// dramatically over the next GC cycle. Overestimating the amount of
-// fragmentation simply results in higher memory use, which will be accounted
-// for by the next pacing up date. Underestimating the fragmentation however
-// could lead to performance degradation. Handling this case is not within the
-// scope of the scavenger. Situations where the amount of fragmentation balloons
-// over the course of a single GC cycle should be considered pathologies,
-// flagged as bugs, and fixed appropriately.
-//
-// An additional factor of retainExtraPercent is added as a buffer to help ensure
-// that there's more unscavenged memory to allocate out of, since each allocation
-// out of scavenged memory incurs a potentially expensive page fault.
-//
-// If a memory limit is set, then we wish to pick a scavenge goal that maintains
-// that memory limit. For that, we look at total memory that has been committed
-// (memstats.mappedReady) and try to bring that down below the limit. In this case,
-// we want to give buffer space in the *opposite* direction. When the application
-// is close to the limit, we want to make sure we push harder to keep it under, so
-// if we target below the memory limit, we ensure that the background scavenger is
-// giving the situation the urgency it deserves.
-//
-// In this case, the goal is defined as:
-// (100-reduceExtraPercent) / 100 * memoryLimit
-//
-// We compute both of these goals, and check whether either of them have been met.
-// The background scavenger continues operating as long as either one of the goals
-// has not been met.
-//
-// The goals are updated after each GC.
-//
-// The synchronous heap-growth scavenging happens whenever the heap grows in
-// size, for some definition of heap-growth. The intuition behind this is that
-// the application had to grow the heap because existing fragments were
-// not sufficiently large to satisfy a page-level memory allocation, so we
-// scavenge those fragments eagerly to offset the growth in RSS that results.
-
-package runtime
-
-import (
- "internal/goos"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-const (
- // The background scavenger is paced according to these parameters.
- //
- // scavengePercent represents the portion of mutator time we're willing
- // to spend on scavenging in percent.
- scavengePercent = 1 // 1%
-
- // retainExtraPercent represents the amount of memory over the heap goal
- // that the scavenger should keep as a buffer space for the allocator.
- // This constant is used when we do not have a memory limit set.
- //
- // The purpose of maintaining this overhead is to have a greater pool of
- // unscavenged memory available for allocation (since using scavenged memory
- // incurs an additional cost), to account for heap fragmentation and
- // the ever-changing layout of the heap.
- retainExtraPercent = 10
-
- // reduceExtraPercent represents the amount of memory under the limit
- // that the scavenger should target. For example, 5 means we target 95%
- // of the limit.
- //
- // The purpose of shooting lower than the limit is to ensure that, once
- // close to the limit, the scavenger is working hard to maintain it. If
- // we have a memory limit set but are far away from it, there's no harm
- // in leaving up to 100-retainExtraPercent live, and it's more efficient
- // anyway, for the same reasons that retainExtraPercent exists.
- reduceExtraPercent = 5
-
- // maxPagesPerPhysPage is the maximum number of supported runtime pages per
- // physical page, based on maxPhysPageSize.
- maxPagesPerPhysPage = maxPhysPageSize / pageSize
-
- // scavengeCostRatio is the approximate ratio between the costs of using previously
- // scavenged memory and scavenging memory.
- //
- // For most systems the cost of scavenging greatly outweighs the costs
- // associated with using scavenged memory, making this constant 0. On other systems
- // (especially ones where "sysUsed" is not just a no-op) this cost is non-trivial.
- //
- // This ratio is used as part of multiplicative factor to help the scavenger account
- // for the additional costs of using scavenged memory in its pacing.
- scavengeCostRatio = 0.7 * (goos.IsDarwin + goos.IsIos)
-)
-
-// heapRetained returns an estimate of the current heap RSS.
-func heapRetained() uint64 {
- return gcController.heapInUse.load() + gcController.heapFree.load()
-}
-
-// gcPaceScavenger updates the scavenger's pacing, particularly
-// its rate and RSS goal. For this, it requires the current heapGoal,
-// and the heapGoal for the previous GC cycle.
-//
-// The RSS goal is based on the current heap goal with a small overhead
-// to accommodate non-determinism in the allocator.
-//
-// The pacing is based on scavengePageRate, which applies to both regular and
-// huge pages. See that constant for more information.
-//
-// Must be called whenever GC pacing is updated.
-//
-// mheap_.lock must be held or the world must be stopped.
-func gcPaceScavenger(memoryLimit int64, heapGoal, lastHeapGoal uint64) {
- assertWorldStoppedOrLockHeld(&mheap_.lock)
-
- // As described at the top of this file, there are two scavenge goals here: one
- // for gcPercent and one for memoryLimit. Let's handle the latter first because
- // it's simpler.
-
- // We want to target retaining (100-reduceExtraPercent)% of the heap.
- memoryLimitGoal := uint64(float64(memoryLimit) * (100.0 - reduceExtraPercent))
-
- // mappedReady is comparable to memoryLimit, and represents how much total memory
- // the Go runtime has committed now (estimated).
- mappedReady := gcController.mappedReady.Load()
-
- // If we're below the goal already indicate that we don't need the background
- // scavenger for the memory limit. This may seems worrisome at first, but note
- // that the allocator will assist the background scavenger in the face of a memory
- // limit, so we'll be safe even if we stop the scavenger when we shouldn't have.
- if mappedReady <= memoryLimitGoal {
- scavenge.memoryLimitGoal.Store(^uint64(0))
- } else {
- scavenge.memoryLimitGoal.Store(memoryLimitGoal)
- }
-
- // Now handle the gcPercent goal.
-
- // If we're called before the first GC completed, disable scavenging.
- // We never scavenge before the 2nd GC cycle anyway (we don't have enough
- // information about the heap yet) so this is fine, and avoids a fault
- // or garbage data later.
- if lastHeapGoal == 0 {
- scavenge.gcPercentGoal.Store(^uint64(0))
- return
- }
- // Compute our scavenging goal.
- goalRatio := float64(heapGoal) / float64(lastHeapGoal)
- gcPercentGoal := uint64(float64(memstats.lastHeapInUse) * goalRatio)
- // Add retainExtraPercent overhead to retainedGoal. This calculation
- // looks strange but the purpose is to arrive at an integer division
- // (e.g. if retainExtraPercent = 12.5, then we get a divisor of 8)
- // that also avoids the overflow from a multiplication.
- gcPercentGoal += gcPercentGoal / (1.0 / (retainExtraPercent / 100.0))
- // Align it to a physical page boundary to make the following calculations
- // a bit more exact.
- gcPercentGoal = (gcPercentGoal + uint64(physPageSize) - 1) &^ (uint64(physPageSize) - 1)
-
- // Represents where we are now in the heap's contribution to RSS in bytes.
- //
- // Guaranteed to always be a multiple of physPageSize on systems where
- // physPageSize <= pageSize since we map new heap memory at a size larger than
- // any physPageSize and released memory in multiples of the physPageSize.
- //
- // However, certain functions recategorize heap memory as other stats (e.g.
- // stacks) and this happens in multiples of pageSize, so on systems
- // where physPageSize > pageSize the calculations below will not be exact.
- // Generally this is OK since we'll be off by at most one regular
- // physical page.
- heapRetainedNow := heapRetained()
-
- // If we're already below our goal, or within one page of our goal, then indicate
- // that we don't need the background scavenger for maintaining a memory overhead
- // proportional to the heap goal.
- if heapRetainedNow <= gcPercentGoal || heapRetainedNow-gcPercentGoal < uint64(physPageSize) {
- scavenge.gcPercentGoal.Store(^uint64(0))
- } else {
- scavenge.gcPercentGoal.Store(gcPercentGoal)
- }
-}
-
-var scavenge struct {
- // gcPercentGoal is the amount of retained heap memory (measured by
- // heapRetained) that the runtime will try to maintain by returning
- // memory to the OS. This goal is derived from gcController.gcPercent
- // by choosing to retain enough memory to allocate heap memory up to
- // the heap goal.
- gcPercentGoal atomic.Uint64
-
- // memoryLimitGoal is the amount of memory retained by the runtime (
- // measured by gcController.mappedReady) that the runtime will try to
- // maintain by returning memory to the OS. This goal is derived from
- // gcController.memoryLimit by choosing to target the memory limit or
- // some lower target to keep the scavenger working.
- memoryLimitGoal atomic.Uint64
-
- // assistTime is the time spent by the allocator scavenging in the last GC cycle.
- //
- // This is reset once a GC cycle ends.
- assistTime atomic.Int64
-
- // backgroundTime is the time spent by the background scavenger in the last GC cycle.
- //
- // This is reset once a GC cycle ends.
- backgroundTime atomic.Int64
-}
-
-const (
- // It doesn't really matter what value we start at, but we can't be zero, because
- // that'll cause divide-by-zero issues. Pick something conservative which we'll
- // also use as a fallback.
- startingScavSleepRatio = 0.001
-
- // Spend at least 1 ms scavenging, otherwise the corresponding
- // sleep time to maintain our desired utilization is too low to
- // be reliable.
- minScavWorkTime = 1e6
-)
-
-// Sleep/wait state of the background scavenger.
-var scavenger scavengerState
-
-type scavengerState struct {
- // lock protects all fields below.
- lock mutex
-
- // g is the goroutine the scavenger is bound to.
- g *g
-
- // parked is whether or not the scavenger is parked.
- parked bool
-
- // timer is the timer used for the scavenger to sleep.
- timer *timer
-
- // sysmonWake signals to sysmon that it should wake the scavenger.
- sysmonWake atomic.Uint32
-
- // targetCPUFraction is the target CPU overhead for the scavenger.
- targetCPUFraction float64
-
- // sleepRatio is the ratio of time spent doing scavenging work to
- // time spent sleeping. This is used to decide how long the scavenger
- // should sleep for in between batches of work. It is set by
- // critSleepController in order to maintain a CPU overhead of
- // targetCPUFraction.
- //
- // Lower means more sleep, higher means more aggressive scavenging.
- sleepRatio float64
-
- // sleepController controls sleepRatio.
- //
- // See sleepRatio for more details.
- sleepController piController
-
- // cooldown is the time left in nanoseconds during which we avoid
- // using the controller and we hold sleepRatio at a conservative
- // value. Used if the controller's assumptions fail to hold.
- controllerCooldown int64
-
- // printControllerReset instructs printScavTrace to signal that
- // the controller was reset.
- printControllerReset bool
-
- // sleepStub is a stub used for testing to avoid actually having
- // the scavenger sleep.
- //
- // Unlike the other stubs, this is not populated if left nil
- // Instead, it is called when non-nil because any valid implementation
- // of this function basically requires closing over this scavenger
- // state, and allocating a closure is not allowed in the runtime as
- // a matter of policy.
- sleepStub func(n int64) int64
-
- // scavenge is a function that scavenges n bytes of memory.
- // Returns how many bytes of memory it actually scavenged, as
- // well as the time it took in nanoseconds. Usually mheap.pages.scavenge
- // with nanotime called around it, but stubbed out for testing.
- // Like mheap.pages.scavenge, if it scavenges less than n bytes of
- // memory, the caller may assume the heap is exhausted of scavengable
- // memory for now.
- //
- // If this is nil, it is populated with the real thing in init.
- scavenge func(n uintptr) (uintptr, int64)
-
- // shouldStop is a callback called in the work loop and provides a
- // point that can force the scavenger to stop early, for example because
- // the scavenge policy dictates too much has been scavenged already.
- //
- // If this is nil, it is populated with the real thing in init.
- shouldStop func() bool
-
- // gomaxprocs returns the current value of gomaxprocs. Stub for testing.
- //
- // If this is nil, it is populated with the real thing in init.
- gomaxprocs func() int32
-}
-
-// init initializes a scavenger state and wires to the current G.
-//
-// Must be called from a regular goroutine that can allocate.
-func (s *scavengerState) init() {
- if s.g != nil {
- throw("scavenger state is already wired")
- }
- lockInit(&s.lock, lockRankScavenge)
- s.g = getg()
-
- s.timer = new(timer)
- s.timer.arg = s
- s.timer.f = func(s any, _ uintptr) {
- s.(*scavengerState).wake()
- }
-
- // input: fraction of CPU time actually used.
- // setpoint: ideal CPU fraction.
- // output: ratio of time worked to time slept (determines sleep time).
- //
- // The output of this controller is somewhat indirect to what we actually
- // want to achieve: how much time to sleep for. The reason for this definition
- // is to ensure that the controller's outputs have a direct relationship with
- // its inputs (as opposed to an inverse relationship), making it somewhat
- // easier to reason about for tuning purposes.
- s.sleepController = piController{
- // Tuned loosely via Ziegler-Nichols process.
- kp: 0.3375,
- ti: 3.2e6,
- tt: 1e9, // 1 second reset time.
-
- // These ranges seem wide, but we want to give the controller plenty of
- // room to hunt for the optimal value.
- min: 0.001, // 1:1000
- max: 1000.0, // 1000:1
- }
- s.sleepRatio = startingScavSleepRatio
-
- // Install real functions if stubs aren't present.
- if s.scavenge == nil {
- s.scavenge = func(n uintptr) (uintptr, int64) {
- start := nanotime()
- r := mheap_.pages.scavenge(n, nil)
- end := nanotime()
- if start >= end {
- return r, 0
- }
- scavenge.backgroundTime.Add(end - start)
- return r, end - start
- }
- }
- if s.shouldStop == nil {
- s.shouldStop = func() bool {
- // If background scavenging is disabled or if there's no work to do just stop.
- return heapRetained() <= scavenge.gcPercentGoal.Load() &&
- (!go119MemoryLimitSupport ||
- gcController.mappedReady.Load() <= scavenge.memoryLimitGoal.Load())
- }
- }
- if s.gomaxprocs == nil {
- s.gomaxprocs = func() int32 {
- return gomaxprocs
- }
- }
-}
-
-// park parks the scavenger goroutine.
-func (s *scavengerState) park() {
- lock(&s.lock)
- if getg() != s.g {
- throw("tried to park scavenger from another goroutine")
- }
- s.parked = true
- goparkunlock(&s.lock, waitReasonGCScavengeWait, traceEvGoBlock, 2)
-}
-
-// ready signals to sysmon that the scavenger should be awoken.
-func (s *scavengerState) ready() {
- s.sysmonWake.Store(1)
-}
-
-// wake immediately unparks the scavenger if necessary.
-//
-// Safe to run without a P.
-func (s *scavengerState) wake() {
- lock(&s.lock)
- if s.parked {
- // Unset sysmonWake, since the scavenger is now being awoken.
- s.sysmonWake.Store(0)
-
- // s.parked is unset to prevent a double wake-up.
- s.parked = false
-
- // Ready the goroutine by injecting it. We use injectglist instead
- // of ready or goready in order to allow us to run this function
- // without a P. injectglist also avoids placing the goroutine in
- // the current P's runnext slot, which is desirable to prevent
- // the scavenger from interfering with user goroutine scheduling
- // too much.
- var list gList
- list.push(s.g)
- injectglist(&list)
- }
- unlock(&s.lock)
-}
-
-// sleep puts the scavenger to sleep based on the amount of time that it worked
-// in nanoseconds.
-//
-// Note that this function should only be called by the scavenger.
-//
-// The scavenger may be woken up earlier by a pacing change, and it may not go
-// to sleep at all if there's a pending pacing change.
-func (s *scavengerState) sleep(worked float64) {
- lock(&s.lock)
- if getg() != s.g {
- throw("tried to sleep scavenger from another goroutine")
- }
-
- if worked < minScavWorkTime {
- // This means there wasn't enough work to actually fill up minScavWorkTime.
- // That's fine; we shouldn't try to do anything with this information
- // because it's going result in a short enough sleep request that things
- // will get messy. Just assume we did at least this much work.
- // All this means is that we'll sleep longer than we otherwise would have.
- worked = minScavWorkTime
- }
-
- // Multiply the critical time by 1 + the ratio of the costs of using
- // scavenged memory vs. scavenging memory. This forces us to pay down
- // the cost of reusing this memory eagerly by sleeping for a longer period
- // of time and scavenging less frequently. More concretely, we avoid situations
- // where we end up scavenging so often that we hurt allocation performance
- // because of the additional overheads of using scavenged memory.
- worked *= 1 + scavengeCostRatio
-
- // sleepTime is the amount of time we're going to sleep, based on the amount
- // of time we worked, and the sleepRatio.
- sleepTime := int64(worked / s.sleepRatio)
-
- var slept int64
- if s.sleepStub == nil {
- // Set the timer.
- //
- // This must happen here instead of inside gopark
- // because we can't close over any variables without
- // failing escape analysis.
- start := nanotime()
- resetTimer(s.timer, start+sleepTime)
-
- // Mark ourselves as asleep and go to sleep.
- s.parked = true
- goparkunlock(&s.lock, waitReasonSleep, traceEvGoSleep, 2)
-
- // How long we actually slept for.
- slept = nanotime() - start
-
- lock(&s.lock)
- // Stop the timer here because s.wake is unable to do it for us.
- // We don't really care if we succeed in stopping the timer. One
- // reason we might fail is that we've already woken up, but the timer
- // might be in the process of firing on some other P; essentially we're
- // racing with it. That's totally OK. Double wake-ups are perfectly safe.
- stopTimer(s.timer)
- unlock(&s.lock)
- } else {
- unlock(&s.lock)
- slept = s.sleepStub(sleepTime)
- }
-
- // Stop here if we're cooling down from the controller.
- if s.controllerCooldown > 0 {
- // worked and slept aren't exact measures of time, but it's OK to be a bit
- // sloppy here. We're just hoping we're avoiding some transient bad behavior.
- t := slept + int64(worked)
- if t > s.controllerCooldown {
- s.controllerCooldown = 0
- } else {
- s.controllerCooldown -= t
- }
- return
- }
-
- // idealFraction is the ideal % of overall application CPU time that we
- // spend scavenging.
- idealFraction := float64(scavengePercent) / 100.0
-
- // Calculate the CPU time spent.
- //
- // This may be slightly inaccurate with respect to GOMAXPROCS, but we're
- // recomputing this often enough relative to GOMAXPROCS changes in general
- // (it only changes when the world is stopped, and not during a GC) that
- // that small inaccuracy is in the noise.
- cpuFraction := worked / ((float64(slept) + worked) * float64(s.gomaxprocs()))
-
- // Update the critSleepRatio, adjusting until we reach our ideal fraction.
- var ok bool
- s.sleepRatio, ok = s.sleepController.next(cpuFraction, idealFraction, float64(slept)+worked)
- if !ok {
- // The core assumption of the controller, that we can get a proportional
- // response, broke down. This may be transient, so temporarily switch to
- // sleeping a fixed, conservative amount.
- s.sleepRatio = startingScavSleepRatio
- s.controllerCooldown = 5e9 // 5 seconds.
-
- // Signal the scav trace printer to output this.
- s.controllerFailed()
- }
-}
-
-// controllerFailed indicates that the scavenger's scheduling
-// controller failed.
-func (s *scavengerState) controllerFailed() {
- lock(&s.lock)
- s.printControllerReset = true
- unlock(&s.lock)
-}
-
-// run is the body of the main scavenging loop.
-//
-// Returns the number of bytes released and the estimated time spent
-// releasing those bytes.
-//
-// Must be run on the scavenger goroutine.
-func (s *scavengerState) run() (released uintptr, worked float64) {
- lock(&s.lock)
- if getg() != s.g {
- throw("tried to run scavenger from another goroutine")
- }
- unlock(&s.lock)
-
- for worked < minScavWorkTime {
- // If something from outside tells us to stop early, stop.
- if s.shouldStop() {
- break
- }
-
- // scavengeQuantum is the amount of memory we try to scavenge
- // in one go. A smaller value means the scavenger is more responsive
- // to the scheduler in case of e.g. preemption. A larger value means
- // that the overheads of scavenging are better amortized, so better
- // scavenging throughput.
- //
- // The current value is chosen assuming a cost of ~10µs/physical page
- // (this is somewhat pessimistic), which implies a worst-case latency of
- // about 160µs for 4 KiB physical pages. The current value is biased
- // toward latency over throughput.
- const scavengeQuantum = 64 << 10
-
- // Accumulate the amount of time spent scavenging.
- r, duration := s.scavenge(scavengeQuantum)
-
- // On some platforms we may see end >= start if the time it takes to scavenge
- // memory is less than the minimum granularity of its clock (e.g. Windows) or
- // due to clock bugs.
- //
- // In this case, just assume scavenging takes 10 µs per regular physical page
- // (determined empirically), and conservatively ignore the impact of huge pages
- // on timing.
- const approxWorkedNSPerPhysicalPage = 10e3
- if duration == 0 {
- worked += approxWorkedNSPerPhysicalPage * float64(r/physPageSize)
- } else {
- // TODO(mknyszek): If duration is small compared to worked, it could be
- // rounded down to zero. Probably not a problem in practice because the
- // values are all within a few orders of magnitude of each other but maybe
- // worth worrying about.
- worked += float64(duration)
- }
- released += r
-
- // scavenge does not return until it either finds the requisite amount of
- // memory to scavenge, or exhausts the heap. If we haven't found enough
- // to scavenge, then the heap must be exhausted.
- if r < scavengeQuantum {
- break
- }
- // When using fake time just do one loop.
- if faketime != 0 {
- break
- }
- }
- if released > 0 && released < physPageSize {
- // If this happens, it means that we may have attempted to release part
- // of a physical page, but the likely effect of that is that it released
- // the whole physical page, some of which may have still been in-use.
- // This could lead to memory corruption. Throw.
- throw("released less than one physical page of memory")
- }
- return
-}
-
-// Background scavenger.
-//
-// The background scavenger maintains the RSS of the application below
-// the line described by the proportional scavenging statistics in
-// the mheap struct.
-func bgscavenge(c chan int) {
- scavenger.init()
-
- c <- 1
- scavenger.park()
-
- for {
- released, workTime := scavenger.run()
- if released == 0 {
- scavenger.park()
- continue
- }
- atomic.Xadduintptr(&mheap_.pages.scav.released, released)
- scavenger.sleep(workTime)
- }
-}
-
-// scavenge scavenges nbytes worth of free pages, starting with the
-// highest address first. Successive calls continue from where it left
-// off until the heap is exhausted. Call scavengeStartGen to bring it
-// back to the top of the heap.
-//
-// Returns the amount of memory scavenged in bytes.
-//
-// scavenge always tries to scavenge nbytes worth of memory, and will
-// only fail to do so if the heap is exhausted for now.
-func (p *pageAlloc) scavenge(nbytes uintptr, shouldStop func() bool) uintptr {
- released := uintptr(0)
- for released < nbytes {
- ci, pageIdx := p.scav.index.find()
- if ci == 0 {
- break
- }
- systemstack(func() {
- released += p.scavengeOne(ci, pageIdx, nbytes-released)
- })
- if shouldStop != nil && shouldStop() {
- break
- }
- }
- return released
-}
-
-// printScavTrace prints a scavenge trace line to standard error.
-//
-// released should be the amount of memory released since the last time this
-// was called, and forced indicates whether the scavenge was forced by the
-// application.
-//
-// scavenger.lock must be held.
-func printScavTrace(released uintptr, forced bool) {
- assertLockHeld(&scavenger.lock)
-
- printlock()
- print("scav ",
- released>>10, " KiB work, ",
- gcController.heapReleased.load()>>10, " KiB total, ",
- (gcController.heapInUse.load()*100)/heapRetained(), "% util",
- )
- if forced {
- print(" (forced)")
- } else if scavenger.printControllerReset {
- print(" [controller reset]")
- scavenger.printControllerReset = false
- }
- println()
- printunlock()
-}
-
-// scavengeOne walks over the chunk at chunk index ci and searches for
-// a contiguous run of pages to scavenge. It will try to scavenge
-// at most max bytes at once, but may scavenge more to avoid
-// breaking huge pages. Once it scavenges some memory it returns
-// how much it scavenged in bytes.
-//
-// searchIdx is the page index to start searching from in ci.
-//
-// Returns the number of bytes scavenged.
-//
-// Must run on the systemstack because it acquires p.mheapLock.
-//
-//go:systemstack
-func (p *pageAlloc) scavengeOne(ci chunkIdx, searchIdx uint, max uintptr) uintptr {
- // Calculate the maximum number of pages to scavenge.
- //
- // This should be alignUp(max, pageSize) / pageSize but max can and will
- // be ^uintptr(0), so we need to be very careful not to overflow here.
- // Rather than use alignUp, calculate the number of pages rounded down
- // first, then add back one if necessary.
- maxPages := max / pageSize
- if max%pageSize != 0 {
- maxPages++
- }
-
- // Calculate the minimum number of pages we can scavenge.
- //
- // Because we can only scavenge whole physical pages, we must
- // ensure that we scavenge at least minPages each time, aligned
- // to minPages*pageSize.
- minPages := physPageSize / pageSize
- if minPages < 1 {
- minPages = 1
- }
-
- lock(p.mheapLock)
- if p.summary[len(p.summary)-1][ci].max() >= uint(minPages) {
- // We only bother looking for a candidate if there at least
- // minPages free pages at all.
- base, npages := p.chunkOf(ci).findScavengeCandidate(searchIdx, minPages, maxPages)
-
- // If we found something, scavenge it and return!
- if npages != 0 {
- // Compute the full address for the start of the range.
- addr := chunkBase(ci) + uintptr(base)*pageSize
-
- // Mark the range we're about to scavenge as allocated, because
- // we don't want any allocating goroutines to grab it while
- // the scavenging is in progress.
- if scav := p.allocRange(addr, uintptr(npages)); scav != 0 {
- throw("double scavenge")
- }
-
- // With that done, it's safe to unlock.
- unlock(p.mheapLock)
-
- if !p.test {
- pageTraceScav(getg().m.p.ptr(), 0, addr, uintptr(npages))
-
- // Only perform the actual scavenging if we're not in a test.
- // It's dangerous to do so otherwise.
- sysUnused(unsafe.Pointer(addr), uintptr(npages)*pageSize)
-
- // Update global accounting only when not in test, otherwise
- // the runtime's accounting will be wrong.
- nbytes := int64(npages) * pageSize
- gcController.heapReleased.add(nbytes)
- gcController.heapFree.add(-nbytes)
-
- stats := memstats.heapStats.acquire()
- atomic.Xaddint64(&stats.committed, -nbytes)
- atomic.Xaddint64(&stats.released, nbytes)
- memstats.heapStats.release()
- }
-
- // Relock the heap, because now we need to make these pages
- // available allocation. Free them back to the page allocator.
- lock(p.mheapLock)
- p.free(addr, uintptr(npages), true)
-
- // Mark the range as scavenged.
- p.chunkOf(ci).scavenged.setRange(base, npages)
- unlock(p.mheapLock)
-
- return uintptr(npages) * pageSize
- }
- }
- // Mark this chunk as having no free pages.
- p.scav.index.clear(ci)
- unlock(p.mheapLock)
-
- return 0
-}
-
-// fillAligned returns x but with all zeroes in m-aligned
-// groups of m bits set to 1 if any bit in the group is non-zero.
-//
-// For example, fillAligned(0x0100a3, 8) == 0xff00ff.
-//
-// Note that if m == 1, this is a no-op.
-//
-// m must be a power of 2 <= maxPagesPerPhysPage.
-func fillAligned(x uint64, m uint) uint64 {
- apply := func(x uint64, c uint64) uint64 {
- // The technique used it here is derived from
- // https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
- // and extended for more than just bytes (like nibbles
- // and uint16s) by using an appropriate constant.
- //
- // To summarize the technique, quoting from that page:
- // "[It] works by first zeroing the high bits of the [8]
- // bytes in the word. Subsequently, it adds a number that
- // will result in an overflow to the high bit of a byte if
- // any of the low bits were initially set. Next the high
- // bits of the original word are ORed with these values;
- // thus, the high bit of a byte is set iff any bit in the
- // byte was set. Finally, we determine if any of these high
- // bits are zero by ORing with ones everywhere except the
- // high bits and inverting the result."
- return ^((((x & c) + c) | x) | c)
- }
- // Transform x to contain a 1 bit at the top of each m-aligned
- // group of m zero bits.
- switch m {
- case 1:
- return x
- case 2:
- x = apply(x, 0x5555555555555555)
- case 4:
- x = apply(x, 0x7777777777777777)
- case 8:
- x = apply(x, 0x7f7f7f7f7f7f7f7f)
- case 16:
- x = apply(x, 0x7fff7fff7fff7fff)
- case 32:
- x = apply(x, 0x7fffffff7fffffff)
- case 64: // == maxPagesPerPhysPage
- x = apply(x, 0x7fffffffffffffff)
- default:
- throw("bad m value")
- }
- // Now, the top bit of each m-aligned group in x is set
- // that group was all zero in the original x.
-
- // From each group of m bits subtract 1.
- // Because we know only the top bits of each
- // m-aligned group are set, we know this will
- // set each group to have all the bits set except
- // the top bit, so just OR with the original
- // result to set all the bits.
- return ^((x - (x >> (m - 1))) | x)
-}
-
-// findScavengeCandidate returns a start index and a size for this pallocData
-// segment which represents a contiguous region of free and unscavenged memory.
-//
-// searchIdx indicates the page index within this chunk to start the search, but
-// note that findScavengeCandidate searches backwards through the pallocData. As a
-// a result, it will return the highest scavenge candidate in address order.
-//
-// min indicates a hard minimum size and alignment for runs of pages. That is,
-// findScavengeCandidate will not return a region smaller than min pages in size,
-// or that is min pages or greater in size but not aligned to min. min must be
-// a non-zero power of 2 <= maxPagesPerPhysPage.
-//
-// max is a hint for how big of a region is desired. If max >= pallocChunkPages, then
-// findScavengeCandidate effectively returns entire free and unscavenged regions.
-// If max < pallocChunkPages, it may truncate the returned region such that size is
-// max. However, findScavengeCandidate may still return a larger region if, for
-// example, it chooses to preserve huge pages, or if max is not aligned to min (it
-// will round up). That is, even if max is small, the returned size is not guaranteed
-// to be equal to max. max is allowed to be less than min, in which case it is as if
-// max == min.
-func (m *pallocData) findScavengeCandidate(searchIdx uint, min, max uintptr) (uint, uint) {
- if min&(min-1) != 0 || min == 0 {
- print("runtime: min = ", min, "\n")
- throw("min must be a non-zero power of 2")
- } else if min > maxPagesPerPhysPage {
- print("runtime: min = ", min, "\n")
- throw("min too large")
- }
- // max may not be min-aligned, so we might accidentally truncate to
- // a max value which causes us to return a non-min-aligned value.
- // To prevent this, align max up to a multiple of min (which is always
- // a power of 2). This also prevents max from ever being less than
- // min, unless it's zero, so handle that explicitly.
- if max == 0 {
- max = min
- } else {
- max = alignUp(max, min)
- }
-
- i := int(searchIdx / 64)
- // Start by quickly skipping over blocks of non-free or scavenged pages.
- for ; i >= 0; i-- {
- // 1s are scavenged OR non-free => 0s are unscavenged AND free
- x := fillAligned(m.scavenged[i]|m.pallocBits[i], uint(min))
- if x != ^uint64(0) {
- break
- }
- }
- if i < 0 {
- // Failed to find any free/unscavenged pages.
- return 0, 0
- }
- // We have something in the 64-bit chunk at i, but it could
- // extend further. Loop until we find the extent of it.
-
- // 1s are scavenged OR non-free => 0s are unscavenged AND free
- x := fillAligned(m.scavenged[i]|m.pallocBits[i], uint(min))
- z1 := uint(sys.LeadingZeros64(^x))
- run, end := uint(0), uint(i)*64+(64-z1)
- if x<<z1 != 0 {
- // After shifting out z1 bits, we still have 1s,
- // so the run ends inside this word.
- run = uint(sys.LeadingZeros64(x << z1))
- } else {
- // After shifting out z1 bits, we have no more 1s.
- // This means the run extends to the bottom of the
- // word so it may extend into further words.
- run = 64 - z1
- for j := i - 1; j >= 0; j-- {
- x := fillAligned(m.scavenged[j]|m.pallocBits[j], uint(min))
- run += uint(sys.LeadingZeros64(x))
- if x != 0 {
- // The run stopped in this word.
- break
- }
- }
- }
-
- // Split the run we found if it's larger than max but hold on to
- // our original length, since we may need it later.
- size := run
- if size > uint(max) {
- size = uint(max)
- }
- start := end - size
-
- // Each huge page is guaranteed to fit in a single palloc chunk.
- //
- // TODO(mknyszek): Support larger huge page sizes.
- // TODO(mknyszek): Consider taking pages-per-huge-page as a parameter
- // so we can write tests for this.
- if physHugePageSize > pageSize && physHugePageSize > physPageSize {
- // We have huge pages, so let's ensure we don't break one by scavenging
- // over a huge page boundary. If the range [start, start+size) overlaps with
- // a free-and-unscavenged huge page, we want to grow the region we scavenge
- // to include that huge page.
-
- // Compute the huge page boundary above our candidate.
- pagesPerHugePage := uintptr(physHugePageSize / pageSize)
- hugePageAbove := uint(alignUp(uintptr(start), pagesPerHugePage))
-
- // If that boundary is within our current candidate, then we may be breaking
- // a huge page.
- if hugePageAbove <= end {
- // Compute the huge page boundary below our candidate.
- hugePageBelow := uint(alignDown(uintptr(start), pagesPerHugePage))
-
- if hugePageBelow >= end-run {
- // We're in danger of breaking apart a huge page since start+size crosses
- // a huge page boundary and rounding down start to the nearest huge
- // page boundary is included in the full run we found. Include the entire
- // huge page in the bound by rounding down to the huge page size.
- size = size + (start - hugePageBelow)
- start = hugePageBelow
- }
- }
- }
- return start, size
-}
-
-// scavengeIndex is a structure for efficiently managing which pageAlloc chunks have
-// memory available to scavenge.
-type scavengeIndex struct {
- // chunks is a bitmap representing the entire address space. Each bit represents
- // a single chunk, and a 1 value indicates the presence of pages available for
- // scavenging. Updates to the bitmap are serialized by the pageAlloc lock.
- //
- // The underlying storage of chunks is platform dependent and may not even be
- // totally mapped read/write. min and max reflect the extent that is safe to access.
- // min is inclusive, max is exclusive.
- //
- // searchAddr is the maximum address (in the offset address space, so we have a linear
- // view of the address space; see mranges.go:offAddr) containing memory available to
- // scavenge. It is a hint to the find operation to avoid O(n^2) behavior in repeated lookups.
- //
- // searchAddr is always inclusive and should be the base address of the highest runtime
- // page available for scavenging.
- //
- // searchAddr is managed by both find and mark.
- //
- // Normally, find monotonically decreases searchAddr as it finds no more free pages to
- // scavenge. However, mark, when marking a new chunk at an index greater than the current
- // searchAddr, sets searchAddr to the *negative* index into chunks of that page. The trick here
- // is that concurrent calls to find will fail to monotonically decrease searchAddr, and so they
- // won't barge over new memory becoming available to scavenge. Furthermore, this ensures
- // that some future caller of find *must* observe the new high index. That caller
- // (or any other racing with it), then makes searchAddr positive before continuing, bringing
- // us back to our monotonically decreasing steady-state.
- //
- // A pageAlloc lock serializes updates between min, max, and searchAddr, so abs(searchAddr)
- // is always guaranteed to be >= min and < max (converted to heap addresses).
- //
- // TODO(mknyszek): Ideally we would use something bigger than a uint8 for faster
- // iteration like uint32, but we lack the bit twiddling intrinsics. We'd need to either
- // copy them from math/bits or fix the fact that we can't import math/bits' code from
- // the runtime due to compiler instrumentation.
- searchAddr atomicOffAddr
- chunks []atomic.Uint8
- minHeapIdx atomic.Int32
- min, max atomic.Int32
-}
-
-// find returns the highest chunk index that may contain pages available to scavenge.
-// It also returns an offset to start searching in the highest chunk.
-func (s *scavengeIndex) find() (chunkIdx, uint) {
- searchAddr, marked := s.searchAddr.Load()
- if searchAddr == minOffAddr.addr() {
- // We got a cleared search addr.
- return 0, 0
- }
-
- // Starting from searchAddr's chunk, and moving down to minHeapIdx,
- // iterate until we find a chunk with pages to scavenge.
- min := s.minHeapIdx.Load()
- searchChunk := chunkIndex(uintptr(searchAddr))
- start := int32(searchChunk / 8)
- for i := start; i >= min; i-- {
- // Skip over irrelevant address space.
- chunks := s.chunks[i].Load()
- if chunks == 0 {
- continue
- }
- // Note that we can't have 8 leading zeroes here because
- // we necessarily skipped that case. So, what's left is
- // an index. If there are no zeroes, we want the 7th
- // index, if 1 zero, the 6th, and so on.
- n := 7 - sys.LeadingZeros8(chunks)
- ci := chunkIdx(uint(i)*8 + uint(n))
- if searchChunk == ci {
- return ci, chunkPageIndex(uintptr(searchAddr))
- }
- // Try to reduce searchAddr to newSearchAddr.
- newSearchAddr := chunkBase(ci) + pallocChunkBytes - pageSize
- if marked {
- // Attempt to be the first one to decrease the searchAddr
- // after an increase. If we fail, that means there was another
- // increase, or somebody else got to it before us. Either way,
- // it doesn't matter. We may lose some performance having an
- // incorrect search address, but it's far more important that
- // we don't miss updates.
- s.searchAddr.StoreUnmark(searchAddr, newSearchAddr)
- } else {
- // Decrease searchAddr.
- s.searchAddr.StoreMin(newSearchAddr)
- }
- return ci, pallocChunkPages - 1
- }
- // Clear searchAddr, because we've exhausted the heap.
- s.searchAddr.Clear()
- return 0, 0
-}
-
-// mark sets the inclusive range of chunks between indices start and end as
-// containing pages available to scavenge.
-//
-// Must be serialized with other mark, markRange, and clear calls.
-func (s *scavengeIndex) mark(base, limit uintptr) {
- start, end := chunkIndex(base), chunkIndex(limit-pageSize)
- if start == end {
- // Within a chunk.
- mask := uint8(1 << (start % 8))
- s.chunks[start/8].Or(mask)
- } else if start/8 == end/8 {
- // Within the same byte in the index.
- mask := uint8(uint16(1<<(end-start+1))-1) << (start % 8)
- s.chunks[start/8].Or(mask)
- } else {
- // Crosses multiple bytes in the index.
- startAligned := chunkIdx(alignUp(uintptr(start), 8))
- endAligned := chunkIdx(alignDown(uintptr(end), 8))
-
- // Do the end of the first byte first.
- if width := startAligned - start; width > 0 {
- mask := uint8(uint16(1<<width)-1) << (start % 8)
- s.chunks[start/8].Or(mask)
- }
- // Do the middle aligned sections that take up a whole
- // byte.
- for ci := startAligned; ci < endAligned; ci += 8 {
- s.chunks[ci/8].Store(^uint8(0))
- }
- // Do the end of the last byte.
- //
- // This width check doesn't match the one above
- // for start because aligning down into the endAligned
- // block means we always have at least one chunk in this
- // block (note that end is *inclusive*). This also means
- // that if end == endAligned+n, then what we really want
- // is to fill n+1 chunks, i.e. width n+1. By induction,
- // this is true for all n.
- if width := end - endAligned + 1; width > 0 {
- mask := uint8(uint16(1<<width) - 1)
- s.chunks[end/8].Or(mask)
- }
- }
- newSearchAddr := limit - pageSize
- searchAddr, _ := s.searchAddr.Load()
- // N.B. Because mark is serialized, it's not necessary to do a
- // full CAS here. mark only ever increases searchAddr, while
- // find only ever decreases it. Since we only ever race with
- // decreases, even if the value we loaded is stale, the actual
- // value will never be larger.
- if (offAddr{searchAddr}).lessThan(offAddr{newSearchAddr}) {
- s.searchAddr.StoreMarked(newSearchAddr)
- }
-}
-
-// clear sets the chunk at index ci as not containing pages available to scavenge.
-//
-// Must be serialized with other mark, markRange, and clear calls.
-func (s *scavengeIndex) clear(ci chunkIdx) {
- s.chunks[ci/8].And(^uint8(1 << (ci % 8)))
-}
-
-type piController struct {
- kp float64 // Proportional constant.
- ti float64 // Integral time constant.
- tt float64 // Reset time.
-
- min, max float64 // Output boundaries.
-
- // PI controller state.
-
- errIntegral float64 // Integral of the error from t=0 to now.
-
- // Error flags.
- errOverflow bool // Set if errIntegral ever overflowed.
- inputOverflow bool // Set if an operation with the input overflowed.
-}
-
-// next provides a new sample to the controller.
-//
-// input is the sample, setpoint is the desired point, and period is how much
-// time (in whatever unit makes the most sense) has passed since the last sample.
-//
-// Returns a new value for the variable it's controlling, and whether the operation
-// completed successfully. One reason this might fail is if error has been growing
-// in an unbounded manner, to the point of overflow.
-//
-// In the specific case of an error overflow occurs, the errOverflow field will be
-// set and the rest of the controller's internal state will be fully reset.
-func (c *piController) next(input, setpoint, period float64) (float64, bool) {
- // Compute the raw output value.
- prop := c.kp * (setpoint - input)
- rawOutput := prop + c.errIntegral
-
- // Clamp rawOutput into output.
- output := rawOutput
- if isInf(output) || isNaN(output) {
- // The input had a large enough magnitude that either it was already
- // overflowed, or some operation with it overflowed.
- // Set a flag and reset. That's the safest thing to do.
- c.reset()
- c.inputOverflow = true
- return c.min, false
- }
- if output < c.min {
- output = c.min
- } else if output > c.max {
- output = c.max
- }
-
- // Update the controller's state.
- if c.ti != 0 && c.tt != 0 {
- c.errIntegral += (c.kp*period/c.ti)*(setpoint-input) + (period/c.tt)*(output-rawOutput)
- if isInf(c.errIntegral) || isNaN(c.errIntegral) {
- // So much error has accumulated that we managed to overflow.
- // The assumptions around the controller have likely broken down.
- // Set a flag and reset. That's the safest thing to do.
- c.reset()
- c.errOverflow = true
- return c.min, false
- }
- }
- return output, true
-}
-
-// reset resets the controller state, except for controller error flags.
-func (c *piController) reset() {
- c.errIntegral = 0
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mgcsweep.go b/contrib/go/_std_1.20/src/runtime/mgcsweep.go
deleted file mode 100644
index 6ccf090ac5..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mgcsweep.go
+++ /dev/null
@@ -1,967 +0,0 @@
-// Copyright 2009 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.
-
-// Garbage collector: sweeping
-
-// The sweeper consists of two different algorithms:
-//
-// * The object reclaimer finds and frees unmarked slots in spans. It
-// can free a whole span if none of the objects are marked, but that
-// isn't its goal. This can be driven either synchronously by
-// mcentral.cacheSpan for mcentral spans, or asynchronously by
-// sweepone, which looks at all the mcentral lists.
-//
-// * The span reclaimer looks for spans that contain no marked objects
-// and frees whole spans. This is a separate algorithm because
-// freeing whole spans is the hardest task for the object reclaimer,
-// but is critical when allocating new spans. The entry point for
-// this is mheap_.reclaim and it's driven by a sequential scan of
-// the page marks bitmap in the heap arenas.
-//
-// Both algorithms ultimately call mspan.sweep, which sweeps a single
-// heap span.
-
-package runtime
-
-import (
- "runtime/internal/atomic"
- "unsafe"
-)
-
-var sweep sweepdata
-
-// State of background sweep.
-type sweepdata struct {
- lock mutex
- g *g
- parked bool
-
- nbgsweep uint32
- npausesweep uint32
-
- // active tracks outstanding sweepers and the sweep
- // termination condition.
- active activeSweep
-
- // centralIndex is the current unswept span class.
- // It represents an index into the mcentral span
- // sets. Accessed and updated via its load and
- // update methods. Not protected by a lock.
- //
- // Reset at mark termination.
- // Used by mheap.nextSpanForSweep.
- centralIndex sweepClass
-}
-
-// sweepClass is a spanClass and one bit to represent whether we're currently
-// sweeping partial or full spans.
-type sweepClass uint32
-
-const (
- numSweepClasses = numSpanClasses * 2
- sweepClassDone sweepClass = sweepClass(^uint32(0))
-)
-
-func (s *sweepClass) load() sweepClass {
- return sweepClass(atomic.Load((*uint32)(s)))
-}
-
-func (s *sweepClass) update(sNew sweepClass) {
- // Only update *s if its current value is less than sNew,
- // since *s increases monotonically.
- sOld := s.load()
- for sOld < sNew && !atomic.Cas((*uint32)(s), uint32(sOld), uint32(sNew)) {
- sOld = s.load()
- }
- // TODO(mknyszek): This isn't the only place we have
- // an atomic monotonically increasing counter. It would
- // be nice to have an "atomic max" which is just implemented
- // as the above on most architectures. Some architectures
- // like RISC-V however have native support for an atomic max.
-}
-
-func (s *sweepClass) clear() {
- atomic.Store((*uint32)(s), 0)
-}
-
-// split returns the underlying span class as well as
-// whether we're interested in the full or partial
-// unswept lists for that class, indicated as a boolean
-// (true means "full").
-func (s sweepClass) split() (spc spanClass, full bool) {
- return spanClass(s >> 1), s&1 == 0
-}
-
-// nextSpanForSweep finds and pops the next span for sweeping from the
-// central sweep buffers. It returns ownership of the span to the caller.
-// Returns nil if no such span exists.
-func (h *mheap) nextSpanForSweep() *mspan {
- sg := h.sweepgen
- for sc := sweep.centralIndex.load(); sc < numSweepClasses; sc++ {
- spc, full := sc.split()
- c := &h.central[spc].mcentral
- var s *mspan
- if full {
- s = c.fullUnswept(sg).pop()
- } else {
- s = c.partialUnswept(sg).pop()
- }
- if s != nil {
- // Write down that we found something so future sweepers
- // can start from here.
- sweep.centralIndex.update(sc)
- return s
- }
- }
- // Write down that we found nothing.
- sweep.centralIndex.update(sweepClassDone)
- return nil
-}
-
-const sweepDrainedMask = 1 << 31
-
-// activeSweep is a type that captures whether sweeping
-// is done, and whether there are any outstanding sweepers.
-//
-// Every potential sweeper must call begin() before they look
-// for work, and end() after they've finished sweeping.
-type activeSweep struct {
- // state is divided into two parts.
- //
- // The top bit (masked by sweepDrainedMask) is a boolean
- // value indicating whether all the sweep work has been
- // drained from the queue.
- //
- // The rest of the bits are a counter, indicating the
- // number of outstanding concurrent sweepers.
- state atomic.Uint32
-}
-
-// begin registers a new sweeper. Returns a sweepLocker
-// for acquiring spans for sweeping. Any outstanding sweeper blocks
-// sweep termination.
-//
-// If the sweepLocker is invalid, the caller can be sure that all
-// outstanding sweep work has been drained, so there is nothing left
-// to sweep. Note that there may be sweepers currently running, so
-// this does not indicate that all sweeping has completed.
-//
-// Even if the sweepLocker is invalid, its sweepGen is always valid.
-func (a *activeSweep) begin() sweepLocker {
- for {
- state := a.state.Load()
- if state&sweepDrainedMask != 0 {
- return sweepLocker{mheap_.sweepgen, false}
- }
- if a.state.CompareAndSwap(state, state+1) {
- return sweepLocker{mheap_.sweepgen, true}
- }
- }
-}
-
-// end deregisters a sweeper. Must be called once for each time
-// begin is called if the sweepLocker is valid.
-func (a *activeSweep) end(sl sweepLocker) {
- if sl.sweepGen != mheap_.sweepgen {
- throw("sweeper left outstanding across sweep generations")
- }
- for {
- state := a.state.Load()
- if (state&^sweepDrainedMask)-1 >= sweepDrainedMask {
- throw("mismatched begin/end of activeSweep")
- }
- if a.state.CompareAndSwap(state, state-1) {
- if state != sweepDrainedMask {
- return
- }
- if debug.gcpacertrace > 0 {
- live := gcController.heapLive.Load()
- print("pacer: sweep done at heap size ", live>>20, "MB; allocated ", (live-mheap_.sweepHeapLiveBasis)>>20, "MB during sweep; swept ", mheap_.pagesSwept.Load(), " pages at ", mheap_.sweepPagesPerByte, " pages/byte\n")
- }
- return
- }
- }
-}
-
-// markDrained marks the active sweep cycle as having drained
-// all remaining work. This is safe to be called concurrently
-// with all other methods of activeSweep, though may race.
-//
-// Returns true if this call was the one that actually performed
-// the mark.
-func (a *activeSweep) markDrained() bool {
- for {
- state := a.state.Load()
- if state&sweepDrainedMask != 0 {
- return false
- }
- if a.state.CompareAndSwap(state, state|sweepDrainedMask) {
- return true
- }
- }
-}
-
-// sweepers returns the current number of active sweepers.
-func (a *activeSweep) sweepers() uint32 {
- return a.state.Load() &^ sweepDrainedMask
-}
-
-// isDone returns true if all sweep work has been drained and no more
-// outstanding sweepers exist. That is, when the sweep phase is
-// completely done.
-func (a *activeSweep) isDone() bool {
- return a.state.Load() == sweepDrainedMask
-}
-
-// reset sets up the activeSweep for the next sweep cycle.
-//
-// The world must be stopped.
-func (a *activeSweep) reset() {
- assertWorldStopped()
- a.state.Store(0)
-}
-
-// finishsweep_m ensures that all spans are swept.
-//
-// The world must be stopped. This ensures there are no sweeps in
-// progress.
-//
-//go:nowritebarrier
-func finishsweep_m() {
- assertWorldStopped()
-
- // Sweeping must be complete before marking commences, so
- // sweep any unswept spans. If this is a concurrent GC, there
- // shouldn't be any spans left to sweep, so this should finish
- // instantly. If GC was forced before the concurrent sweep
- // finished, there may be spans to sweep.
- for sweepone() != ^uintptr(0) {
- sweep.npausesweep++
- }
-
- // Make sure there aren't any outstanding sweepers left.
- // At this point, with the world stopped, it means one of two
- // things. Either we were able to preempt a sweeper, or that
- // a sweeper didn't call sweep.active.end when it should have.
- // Both cases indicate a bug, so throw.
- if sweep.active.sweepers() != 0 {
- throw("active sweepers found at start of mark phase")
- }
-
- // Reset all the unswept buffers, which should be empty.
- // Do this in sweep termination as opposed to mark termination
- // so that we can catch unswept spans and reclaim blocks as
- // soon as possible.
- sg := mheap_.sweepgen
- for i := range mheap_.central {
- c := &mheap_.central[i].mcentral
- c.partialUnswept(sg).reset()
- c.fullUnswept(sg).reset()
- }
-
- // Sweeping is done, so if the scavenger isn't already awake,
- // wake it up. There's definitely work for it to do at this
- // point.
- scavenger.wake()
-
- nextMarkBitArenaEpoch()
-}
-
-func bgsweep(c chan int) {
- sweep.g = getg()
-
- lockInit(&sweep.lock, lockRankSweep)
- lock(&sweep.lock)
- sweep.parked = true
- c <- 1
- goparkunlock(&sweep.lock, waitReasonGCSweepWait, traceEvGoBlock, 1)
-
- for {
- // bgsweep attempts to be a "low priority" goroutine by intentionally
- // yielding time. It's OK if it doesn't run, because goroutines allocating
- // memory will sweep and ensure that all spans are swept before the next
- // GC cycle. We really only want to run when we're idle.
- //
- // However, calling Gosched after each span swept produces a tremendous
- // amount of tracing events, sometimes up to 50% of events in a trace. It's
- // also inefficient to call into the scheduler so much because sweeping a
- // single span is in general a very fast operation, taking as little as 30 ns
- // on modern hardware. (See #54767.)
- //
- // As a result, bgsweep sweeps in batches, and only calls into the scheduler
- // at the end of every batch. Furthermore, it only yields its time if there
- // isn't spare idle time available on other cores. If there's available idle
- // time, helping to sweep can reduce allocation latencies by getting ahead of
- // the proportional sweeper and having spans ready to go for allocation.
- const sweepBatchSize = 10
- nSwept := 0
- for sweepone() != ^uintptr(0) {
- sweep.nbgsweep++
- nSwept++
- if nSwept%sweepBatchSize == 0 {
- goschedIfBusy()
- }
- }
- for freeSomeWbufs(true) {
- // N.B. freeSomeWbufs is already batched internally.
- goschedIfBusy()
- }
- lock(&sweep.lock)
- if !isSweepDone() {
- // This can happen if a GC runs between
- // gosweepone returning ^0 above
- // and the lock being acquired.
- unlock(&sweep.lock)
- continue
- }
- sweep.parked = true
- goparkunlock(&sweep.lock, waitReasonGCSweepWait, traceEvGoBlock, 1)
- }
-}
-
-// sweepLocker acquires sweep ownership of spans.
-type sweepLocker struct {
- // sweepGen is the sweep generation of the heap.
- sweepGen uint32
- valid bool
-}
-
-// sweepLocked represents sweep ownership of a span.
-type sweepLocked struct {
- *mspan
-}
-
-// tryAcquire attempts to acquire sweep ownership of span s. If it
-// successfully acquires ownership, it blocks sweep completion.
-func (l *sweepLocker) tryAcquire(s *mspan) (sweepLocked, bool) {
- if !l.valid {
- throw("use of invalid sweepLocker")
- }
- // Check before attempting to CAS.
- if atomic.Load(&s.sweepgen) != l.sweepGen-2 {
- return sweepLocked{}, false
- }
- // Attempt to acquire sweep ownership of s.
- if !atomic.Cas(&s.sweepgen, l.sweepGen-2, l.sweepGen-1) {
- return sweepLocked{}, false
- }
- return sweepLocked{s}, true
-}
-
-// sweepone sweeps some unswept heap span and returns the number of pages returned
-// to the heap, or ^uintptr(0) if there was nothing to sweep.
-func sweepone() uintptr {
- gp := getg()
-
- // Increment locks to ensure that the goroutine is not preempted
- // in the middle of sweep thus leaving the span in an inconsistent state for next GC
- gp.m.locks++
-
- // TODO(austin): sweepone is almost always called in a loop;
- // lift the sweepLocker into its callers.
- sl := sweep.active.begin()
- if !sl.valid {
- gp.m.locks--
- return ^uintptr(0)
- }
-
- // Find a span to sweep.
- npages := ^uintptr(0)
- var noMoreWork bool
- for {
- s := mheap_.nextSpanForSweep()
- if s == nil {
- noMoreWork = sweep.active.markDrained()
- break
- }
- if state := s.state.get(); state != mSpanInUse {
- // This can happen if direct sweeping already
- // swept this span, but in that case the sweep
- // generation should always be up-to-date.
- if !(s.sweepgen == sl.sweepGen || s.sweepgen == sl.sweepGen+3) {
- print("runtime: bad span s.state=", state, " s.sweepgen=", s.sweepgen, " sweepgen=", sl.sweepGen, "\n")
- throw("non in-use span in unswept list")
- }
- continue
- }
- if s, ok := sl.tryAcquire(s); ok {
- // Sweep the span we found.
- npages = s.npages
- if s.sweep(false) {
- // Whole span was freed. Count it toward the
- // page reclaimer credit since these pages can
- // now be used for span allocation.
- mheap_.reclaimCredit.Add(npages)
- } else {
- // Span is still in-use, so this returned no
- // pages to the heap and the span needs to
- // move to the swept in-use list.
- npages = 0
- }
- break
- }
- }
- sweep.active.end(sl)
-
- if noMoreWork {
- // The sweep list is empty. There may still be
- // concurrent sweeps running, but we're at least very
- // close to done sweeping.
-
- // Move the scavenge gen forward (signaling
- // that there's new work to do) and wake the scavenger.
- //
- // The scavenger is signaled by the last sweeper because once
- // sweeping is done, we will definitely have useful work for
- // the scavenger to do, since the scavenger only runs over the
- // heap once per GC cycle. This update is not done during sweep
- // termination because in some cases there may be a long delay
- // between sweep done and sweep termination (e.g. not enough
- // allocations to trigger a GC) which would be nice to fill in
- // with scavenging work.
- if debug.scavtrace > 0 {
- systemstack(func() {
- lock(&mheap_.lock)
- released := atomic.Loaduintptr(&mheap_.pages.scav.released)
- printScavTrace(released, false)
- atomic.Storeuintptr(&mheap_.pages.scav.released, 0)
- unlock(&mheap_.lock)
- })
- }
- scavenger.ready()
- }
-
- gp.m.locks--
- return npages
-}
-
-// isSweepDone reports whether all spans are swept.
-//
-// Note that this condition may transition from false to true at any
-// time as the sweeper runs. It may transition from true to false if a
-// GC runs; to prevent that the caller must be non-preemptible or must
-// somehow block GC progress.
-func isSweepDone() bool {
- return sweep.active.isDone()
-}
-
-// Returns only when span s has been swept.
-//
-//go:nowritebarrier
-func (s *mspan) ensureSwept() {
- // Caller must disable preemption.
- // Otherwise when this function returns the span can become unswept again
- // (if GC is triggered on another goroutine).
- gp := getg()
- if gp.m.locks == 0 && gp.m.mallocing == 0 && gp != gp.m.g0 {
- throw("mspan.ensureSwept: m is not locked")
- }
-
- // If this operation fails, then that means that there are
- // no more spans to be swept. In this case, either s has already
- // been swept, or is about to be acquired for sweeping and swept.
- sl := sweep.active.begin()
- if sl.valid {
- // The caller must be sure that the span is a mSpanInUse span.
- if s, ok := sl.tryAcquire(s); ok {
- s.sweep(false)
- sweep.active.end(sl)
- return
- }
- sweep.active.end(sl)
- }
-
- // Unfortunately we can't sweep the span ourselves. Somebody else
- // got to it first. We don't have efficient means to wait, but that's
- // OK, it will be swept fairly soon.
- for {
- spangen := atomic.Load(&s.sweepgen)
- if spangen == sl.sweepGen || spangen == sl.sweepGen+3 {
- break
- }
- osyield()
- }
-}
-
-// Sweep frees or collects finalizers for blocks not marked in the mark phase.
-// It clears the mark bits in preparation for the next GC round.
-// Returns true if the span was returned to heap.
-// If preserve=true, don't return it to heap nor relink in mcentral lists;
-// caller takes care of it.
-func (sl *sweepLocked) sweep(preserve bool) bool {
- // It's critical that we enter this function with preemption disabled,
- // GC must not start while we are in the middle of this function.
- gp := getg()
- if gp.m.locks == 0 && gp.m.mallocing == 0 && gp != gp.m.g0 {
- throw("mspan.sweep: m is not locked")
- }
-
- s := sl.mspan
- if !preserve {
- // We'll release ownership of this span. Nil it out to
- // prevent the caller from accidentally using it.
- sl.mspan = nil
- }
-
- sweepgen := mheap_.sweepgen
- if state := s.state.get(); state != mSpanInUse || s.sweepgen != sweepgen-1 {
- print("mspan.sweep: state=", state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n")
- throw("mspan.sweep: bad span state")
- }
-
- if trace.enabled {
- traceGCSweepSpan(s.npages * _PageSize)
- }
-
- mheap_.pagesSwept.Add(int64(s.npages))
-
- spc := s.spanclass
- size := s.elemsize
-
- // The allocBits indicate which unmarked objects don't need to be
- // processed since they were free at the end of the last GC cycle
- // and were not allocated since then.
- // If the allocBits index is >= s.freeindex and the bit
- // is not marked then the object remains unallocated
- // since the last GC.
- // This situation is analogous to being on a freelist.
-
- // Unlink & free special records for any objects we're about to free.
- // Two complications here:
- // 1. An object can have both finalizer and profile special records.
- // In such case we need to queue finalizer for execution,
- // mark the object as live and preserve the profile special.
- // 2. A tiny object can have several finalizers setup for different offsets.
- // If such object is not marked, we need to queue all finalizers at once.
- // Both 1 and 2 are possible at the same time.
- hadSpecials := s.specials != nil
- siter := newSpecialsIter(s)
- for siter.valid() {
- // A finalizer can be set for an inner byte of an object, find object beginning.
- objIndex := uintptr(siter.s.offset) / size
- p := s.base() + objIndex*size
- mbits := s.markBitsForIndex(objIndex)
- if !mbits.isMarked() {
- // This object is not marked and has at least one special record.
- // Pass 1: see if it has at least one finalizer.
- hasFin := false
- endOffset := p - s.base() + size
- for tmp := siter.s; tmp != nil && uintptr(tmp.offset) < endOffset; tmp = tmp.next {
- if tmp.kind == _KindSpecialFinalizer {
- // Stop freeing of object if it has a finalizer.
- mbits.setMarkedNonAtomic()
- hasFin = true
- break
- }
- }
- // Pass 2: queue all finalizers _or_ handle profile record.
- for siter.valid() && uintptr(siter.s.offset) < endOffset {
- // Find the exact byte for which the special was setup
- // (as opposed to object beginning).
- special := siter.s
- p := s.base() + uintptr(special.offset)
- if special.kind == _KindSpecialFinalizer || !hasFin {
- siter.unlinkAndNext()
- freeSpecial(special, unsafe.Pointer(p), size)
- } else {
- // The object has finalizers, so we're keeping it alive.
- // All other specials only apply when an object is freed,
- // so just keep the special record.
- siter.next()
- }
- }
- } else {
- // object is still live
- if siter.s.kind == _KindSpecialReachable {
- special := siter.unlinkAndNext()
- (*specialReachable)(unsafe.Pointer(special)).reachable = true
- freeSpecial(special, unsafe.Pointer(p), size)
- } else {
- // keep special record
- siter.next()
- }
- }
- }
- if hadSpecials && s.specials == nil {
- spanHasNoSpecials(s)
- }
-
- if debug.allocfreetrace != 0 || debug.clobberfree != 0 || raceenabled || msanenabled || asanenabled {
- // Find all newly freed objects. This doesn't have to
- // efficient; allocfreetrace has massive overhead.
- mbits := s.markBitsForBase()
- abits := s.allocBitsForIndex(0)
- for i := uintptr(0); i < s.nelems; i++ {
- if !mbits.isMarked() && (abits.index < s.freeindex || abits.isMarked()) {
- x := s.base() + i*s.elemsize
- if debug.allocfreetrace != 0 {
- tracefree(unsafe.Pointer(x), size)
- }
- if debug.clobberfree != 0 {
- clobberfree(unsafe.Pointer(x), size)
- }
- // User arenas are handled on explicit free.
- if raceenabled && !s.isUserArenaChunk {
- racefree(unsafe.Pointer(x), size)
- }
- if msanenabled && !s.isUserArenaChunk {
- msanfree(unsafe.Pointer(x), size)
- }
- if asanenabled && !s.isUserArenaChunk {
- asanpoison(unsafe.Pointer(x), size)
- }
- }
- mbits.advance()
- abits.advance()
- }
- }
-
- // Check for zombie objects.
- if s.freeindex < s.nelems {
- // Everything < freeindex is allocated and hence
- // cannot be zombies.
- //
- // Check the first bitmap byte, where we have to be
- // careful with freeindex.
- obj := s.freeindex
- if (*s.gcmarkBits.bytep(obj / 8)&^*s.allocBits.bytep(obj / 8))>>(obj%8) != 0 {
- s.reportZombies()
- }
- // Check remaining bytes.
- for i := obj/8 + 1; i < divRoundUp(s.nelems, 8); i++ {
- if *s.gcmarkBits.bytep(i)&^*s.allocBits.bytep(i) != 0 {
- s.reportZombies()
- }
- }
- }
-
- // Count the number of free objects in this span.
- nalloc := uint16(s.countAlloc())
- nfreed := s.allocCount - nalloc
- if nalloc > s.allocCount {
- // The zombie check above should have caught this in
- // more detail.
- print("runtime: nelems=", s.nelems, " nalloc=", nalloc, " previous allocCount=", s.allocCount, " nfreed=", nfreed, "\n")
- throw("sweep increased allocation count")
- }
-
- s.allocCount = nalloc
- s.freeindex = 0 // reset allocation index to start of span.
- s.freeIndexForScan = 0
- if trace.enabled {
- getg().m.p.ptr().traceReclaimed += uintptr(nfreed) * s.elemsize
- }
-
- // gcmarkBits becomes the allocBits.
- // get a fresh cleared gcmarkBits in preparation for next GC
- s.allocBits = s.gcmarkBits
- s.gcmarkBits = newMarkBits(s.nelems)
-
- // Initialize alloc bits cache.
- s.refillAllocCache(0)
-
- // The span must be in our exclusive ownership until we update sweepgen,
- // check for potential races.
- if state := s.state.get(); state != mSpanInUse || s.sweepgen != sweepgen-1 {
- print("mspan.sweep: state=", state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n")
- throw("mspan.sweep: bad span state after sweep")
- }
- if s.sweepgen == sweepgen+1 || s.sweepgen == sweepgen+3 {
- throw("swept cached span")
- }
-
- // We need to set s.sweepgen = h.sweepgen only when all blocks are swept,
- // because of the potential for a concurrent free/SetFinalizer.
- //
- // But we need to set it before we make the span available for allocation
- // (return it to heap or mcentral), because allocation code assumes that a
- // span is already swept if available for allocation.
- //
- // Serialization point.
- // At this point the mark bits are cleared and allocation ready
- // to go so release the span.
- atomic.Store(&s.sweepgen, sweepgen)
-
- if s.isUserArenaChunk {
- if preserve {
- // This is a case that should never be handled by a sweeper that
- // preserves the span for reuse.
- throw("sweep: tried to preserve a user arena span")
- }
- if nalloc > 0 {
- // There still exist pointers into the span or the span hasn't been
- // freed yet. It's not ready to be reused. Put it back on the
- // full swept list for the next cycle.
- mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s)
- return false
- }
-
- // It's only at this point that the sweeper doesn't actually need to look
- // at this arena anymore, so subtract from pagesInUse now.
- mheap_.pagesInUse.Add(-s.npages)
- s.state.set(mSpanDead)
-
- // The arena is ready to be recycled. Remove it from the quarantine list
- // and place it on the ready list. Don't add it back to any sweep lists.
- systemstack(func() {
- // It's the arena code's responsibility to get the chunk on the quarantine
- // list by the time all references to the chunk are gone.
- if s.list != &mheap_.userArena.quarantineList {
- throw("user arena span is on the wrong list")
- }
- lock(&mheap_.lock)
- mheap_.userArena.quarantineList.remove(s)
- mheap_.userArena.readyList.insert(s)
- unlock(&mheap_.lock)
- })
- return false
- }
-
- if spc.sizeclass() != 0 {
- // Handle spans for small objects.
- if nfreed > 0 {
- // Only mark the span as needing zeroing if we've freed any
- // objects, because a fresh span that had been allocated into,
- // wasn't totally filled, but then swept, still has all of its
- // free slots zeroed.
- s.needzero = 1
- stats := memstats.heapStats.acquire()
- atomic.Xadd64(&stats.smallFreeCount[spc.sizeclass()], int64(nfreed))
- memstats.heapStats.release()
-
- // Count the frees in the inconsistent, internal stats.
- gcController.totalFree.Add(int64(nfreed) * int64(s.elemsize))
- }
- if !preserve {
- // The caller may not have removed this span from whatever
- // unswept set its on but taken ownership of the span for
- // sweeping by updating sweepgen. If this span still is in
- // an unswept set, then the mcentral will pop it off the
- // set, check its sweepgen, and ignore it.
- if nalloc == 0 {
- // Free totally free span directly back to the heap.
- mheap_.freeSpan(s)
- return true
- }
- // Return span back to the right mcentral list.
- if uintptr(nalloc) == s.nelems {
- mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s)
- } else {
- mheap_.central[spc].mcentral.partialSwept(sweepgen).push(s)
- }
- }
- } else if !preserve {
- // Handle spans for large objects.
- if nfreed != 0 {
- // Free large object span to heap.
-
- // NOTE(rsc,dvyukov): The original implementation of efence
- // in CL 22060046 used sysFree instead of sysFault, so that
- // the operating system would eventually give the memory
- // back to us again, so that an efence program could run
- // longer without running out of memory. Unfortunately,
- // calling sysFree here without any kind of adjustment of the
- // heap data structures means that when the memory does
- // come back to us, we have the wrong metadata for it, either in
- // the mspan structures or in the garbage collection bitmap.
- // Using sysFault here means that the program will run out of
- // memory fairly quickly in efence mode, but at least it won't
- // have mysterious crashes due to confused memory reuse.
- // It should be possible to switch back to sysFree if we also
- // implement and then call some kind of mheap.deleteSpan.
- if debug.efence > 0 {
- s.limit = 0 // prevent mlookup from finding this span
- sysFault(unsafe.Pointer(s.base()), size)
- } else {
- mheap_.freeSpan(s)
- }
-
- // Count the free in the consistent, external stats.
- stats := memstats.heapStats.acquire()
- atomic.Xadd64(&stats.largeFreeCount, 1)
- atomic.Xadd64(&stats.largeFree, int64(size))
- memstats.heapStats.release()
-
- // Count the free in the inconsistent, internal stats.
- gcController.totalFree.Add(int64(size))
-
- return true
- }
-
- // Add a large span directly onto the full+swept list.
- mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s)
- }
- return false
-}
-
-// reportZombies reports any marked but free objects in s and throws.
-//
-// This generally means one of the following:
-//
-// 1. User code converted a pointer to a uintptr and then back
-// unsafely, and a GC ran while the uintptr was the only reference to
-// an object.
-//
-// 2. User code (or a compiler bug) constructed a bad pointer that
-// points to a free slot, often a past-the-end pointer.
-//
-// 3. The GC two cycles ago missed a pointer and freed a live object,
-// but it was still live in the last cycle, so this GC cycle found a
-// pointer to that object and marked it.
-func (s *mspan) reportZombies() {
- printlock()
- print("runtime: marked free object in span ", s, ", elemsize=", s.elemsize, " freeindex=", s.freeindex, " (bad use of unsafe.Pointer? try -d=checkptr)\n")
- mbits := s.markBitsForBase()
- abits := s.allocBitsForIndex(0)
- for i := uintptr(0); i < s.nelems; i++ {
- addr := s.base() + i*s.elemsize
- print(hex(addr))
- alloc := i < s.freeindex || abits.isMarked()
- if alloc {
- print(" alloc")
- } else {
- print(" free ")
- }
- if mbits.isMarked() {
- print(" marked ")
- } else {
- print(" unmarked")
- }
- zombie := mbits.isMarked() && !alloc
- if zombie {
- print(" zombie")
- }
- print("\n")
- if zombie {
- length := s.elemsize
- if length > 1024 {
- length = 1024
- }
- hexdumpWords(addr, addr+length, nil)
- }
- mbits.advance()
- abits.advance()
- }
- throw("found pointer to free object")
-}
-
-// deductSweepCredit deducts sweep credit for allocating a span of
-// size spanBytes. This must be performed *before* the span is
-// allocated to ensure the system has enough credit. If necessary, it
-// performs sweeping to prevent going in to debt. If the caller will
-// also sweep pages (e.g., for a large allocation), it can pass a
-// non-zero callerSweepPages to leave that many pages unswept.
-//
-// deductSweepCredit makes a worst-case assumption that all spanBytes
-// bytes of the ultimately allocated span will be available for object
-// allocation.
-//
-// deductSweepCredit is the core of the "proportional sweep" system.
-// It uses statistics gathered by the garbage collector to perform
-// enough sweeping so that all pages are swept during the concurrent
-// sweep phase between GC cycles.
-//
-// mheap_ must NOT be locked.
-func deductSweepCredit(spanBytes uintptr, callerSweepPages uintptr) {
- if mheap_.sweepPagesPerByte == 0 {
- // Proportional sweep is done or disabled.
- return
- }
-
- if trace.enabled {
- traceGCSweepStart()
- }
-
- // Fix debt if necessary.
-retry:
- sweptBasis := mheap_.pagesSweptBasis.Load()
- live := gcController.heapLive.Load()
- liveBasis := mheap_.sweepHeapLiveBasis
- newHeapLive := spanBytes
- if liveBasis < live {
- // Only do this subtraction when we don't overflow. Otherwise, pagesTarget
- // might be computed as something really huge, causing us to get stuck
- // sweeping here until the next mark phase.
- //
- // Overflow can happen here if gcPaceSweeper is called concurrently with
- // sweeping (i.e. not during a STW, like it usually is) because this code
- // is intentionally racy. A concurrent call to gcPaceSweeper can happen
- // if a GC tuning parameter is modified and we read an older value of
- // heapLive than what was used to set the basis.
- //
- // This state should be transient, so it's fine to just let newHeapLive
- // be a relatively small number. We'll probably just skip this attempt to
- // sweep.
- //
- // See issue #57523.
- newHeapLive += uintptr(live - liveBasis)
- }
- pagesTarget := int64(mheap_.sweepPagesPerByte*float64(newHeapLive)) - int64(callerSweepPages)
- for pagesTarget > int64(mheap_.pagesSwept.Load()-sweptBasis) {
- if sweepone() == ^uintptr(0) {
- mheap_.sweepPagesPerByte = 0
- break
- }
- if mheap_.pagesSweptBasis.Load() != sweptBasis {
- // Sweep pacing changed. Recompute debt.
- goto retry
- }
- }
-
- if trace.enabled {
- traceGCSweepDone()
- }
-}
-
-// clobberfree sets the memory content at x to bad content, for debugging
-// purposes.
-func clobberfree(x unsafe.Pointer, size uintptr) {
- // size (span.elemsize) is always a multiple of 4.
- for i := uintptr(0); i < size; i += 4 {
- *(*uint32)(add(x, i)) = 0xdeadbeef
- }
-}
-
-// gcPaceSweeper updates the sweeper's pacing parameters.
-//
-// Must be called whenever the GC's pacing is updated.
-//
-// The world must be stopped, or mheap_.lock must be held.
-func gcPaceSweeper(trigger uint64) {
- assertWorldStoppedOrLockHeld(&mheap_.lock)
-
- // Update sweep pacing.
- if isSweepDone() {
- mheap_.sweepPagesPerByte = 0
- } else {
- // Concurrent sweep needs to sweep all of the in-use
- // pages by the time the allocated heap reaches the GC
- // trigger. Compute the ratio of in-use pages to sweep
- // per byte allocated, accounting for the fact that
- // some might already be swept.
- heapLiveBasis := gcController.heapLive.Load()
- heapDistance := int64(trigger) - int64(heapLiveBasis)
- // Add a little margin so rounding errors and
- // concurrent sweep are less likely to leave pages
- // unswept when GC starts.
- heapDistance -= 1024 * 1024
- if heapDistance < _PageSize {
- // Avoid setting the sweep ratio extremely high
- heapDistance = _PageSize
- }
- pagesSwept := mheap_.pagesSwept.Load()
- pagesInUse := mheap_.pagesInUse.Load()
- sweepDistancePages := int64(pagesInUse) - int64(pagesSwept)
- if sweepDistancePages <= 0 {
- mheap_.sweepPagesPerByte = 0
- } else {
- mheap_.sweepPagesPerByte = float64(sweepDistancePages) / float64(heapDistance)
- mheap_.sweepHeapLiveBasis = heapLiveBasis
- // Write pagesSweptBasis last, since this
- // signals concurrent sweeps to recompute
- // their debt.
- mheap_.pagesSweptBasis.Store(pagesSwept)
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mheap.go b/contrib/go/_std_1.20/src/runtime/mheap.go
deleted file mode 100644
index 1401e92f4e..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mheap.go
+++ /dev/null
@@ -1,2228 +0,0 @@
-// Copyright 2009 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.
-
-// Page heap.
-//
-// See malloc.go for overview.
-
-package runtime
-
-import (
- "internal/cpu"
- "internal/goarch"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-const (
- // minPhysPageSize is a lower-bound on the physical page size. The
- // true physical page size may be larger than this. In contrast,
- // sys.PhysPageSize is an upper-bound on the physical page size.
- minPhysPageSize = 4096
-
- // maxPhysPageSize is the maximum page size the runtime supports.
- maxPhysPageSize = 512 << 10
-
- // maxPhysHugePageSize sets an upper-bound on the maximum huge page size
- // that the runtime supports.
- maxPhysHugePageSize = pallocChunkBytes
-
- // pagesPerReclaimerChunk indicates how many pages to scan from the
- // pageInUse bitmap at a time. Used by the page reclaimer.
- //
- // Higher values reduce contention on scanning indexes (such as
- // h.reclaimIndex), but increase the minimum latency of the
- // operation.
- //
- // The time required to scan this many pages can vary a lot depending
- // on how many spans are actually freed. Experimentally, it can
- // scan for pages at ~300 GB/ms on a 2.6GHz Core i7, but can only
- // free spans at ~32 MB/ms. Using 512 pages bounds this at
- // roughly 100µs.
- //
- // Must be a multiple of the pageInUse bitmap element size and
- // must also evenly divide pagesPerArena.
- pagesPerReclaimerChunk = 512
-
- // physPageAlignedStacks indicates whether stack allocations must be
- // physical page aligned. This is a requirement for MAP_STACK on
- // OpenBSD.
- physPageAlignedStacks = GOOS == "openbsd"
-)
-
-// Main malloc heap.
-// The heap itself is the "free" and "scav" treaps,
-// but all the other global data is here too.
-//
-// mheap must not be heap-allocated because it contains mSpanLists,
-// which must not be heap-allocated.
-type mheap struct {
- _ sys.NotInHeap
-
- // lock must only be acquired on the system stack, otherwise a g
- // could self-deadlock if its stack grows with the lock held.
- lock mutex
-
- pages pageAlloc // page allocation data structure
-
- sweepgen uint32 // sweep generation, see comment in mspan; written during STW
-
- // allspans is a slice of all mspans ever created. Each mspan
- // appears exactly once.
- //
- // The memory for allspans is manually managed and can be
- // reallocated and move as the heap grows.
- //
- // In general, allspans is protected by mheap_.lock, which
- // prevents concurrent access as well as freeing the backing
- // store. Accesses during STW might not hold the lock, but
- // must ensure that allocation cannot happen around the
- // access (since that may free the backing store).
- allspans []*mspan // all spans out there
-
- // Proportional sweep
- //
- // These parameters represent a linear function from gcController.heapLive
- // to page sweep count. The proportional sweep system works to
- // stay in the black by keeping the current page sweep count
- // above this line at the current gcController.heapLive.
- //
- // The line has slope sweepPagesPerByte and passes through a
- // basis point at (sweepHeapLiveBasis, pagesSweptBasis). At
- // any given time, the system is at (gcController.heapLive,
- // pagesSwept) in this space.
- //
- // It is important that the line pass through a point we
- // control rather than simply starting at a 0,0 origin
- // because that lets us adjust sweep pacing at any time while
- // accounting for current progress. If we could only adjust
- // the slope, it would create a discontinuity in debt if any
- // progress has already been made.
- pagesInUse atomic.Uintptr // pages of spans in stats mSpanInUse
- pagesSwept atomic.Uint64 // pages swept this cycle
- pagesSweptBasis atomic.Uint64 // pagesSwept to use as the origin of the sweep ratio
- sweepHeapLiveBasis uint64 // value of gcController.heapLive to use as the origin of sweep ratio; written with lock, read without
- sweepPagesPerByte float64 // proportional sweep ratio; written with lock, read without
-
- // Page reclaimer state
-
- // reclaimIndex is the page index in allArenas of next page to
- // reclaim. Specifically, it refers to page (i %
- // pagesPerArena) of arena allArenas[i / pagesPerArena].
- //
- // If this is >= 1<<63, the page reclaimer is done scanning
- // the page marks.
- reclaimIndex atomic.Uint64
-
- // reclaimCredit is spare credit for extra pages swept. Since
- // the page reclaimer works in large chunks, it may reclaim
- // more than requested. Any spare pages released go to this
- // credit pool.
- reclaimCredit atomic.Uintptr
-
- // arenas is the heap arena map. It points to the metadata for
- // the heap for every arena frame of the entire usable virtual
- // address space.
- //
- // Use arenaIndex to compute indexes into this array.
- //
- // For regions of the address space that are not backed by the
- // Go heap, the arena map contains nil.
- //
- // Modifications are protected by mheap_.lock. Reads can be
- // performed without locking; however, a given entry can
- // transition from nil to non-nil at any time when the lock
- // isn't held. (Entries never transitions back to nil.)
- //
- // In general, this is a two-level mapping consisting of an L1
- // map and possibly many L2 maps. This saves space when there
- // are a huge number of arena frames. However, on many
- // platforms (even 64-bit), arenaL1Bits is 0, making this
- // effectively a single-level map. In this case, arenas[0]
- // will never be nil.
- arenas [1 << arenaL1Bits]*[1 << arenaL2Bits]*heapArena
-
- // heapArenaAlloc is pre-reserved space for allocating heapArena
- // objects. This is only used on 32-bit, where we pre-reserve
- // this space to avoid interleaving it with the heap itself.
- heapArenaAlloc linearAlloc
-
- // arenaHints is a list of addresses at which to attempt to
- // add more heap arenas. This is initially populated with a
- // set of general hint addresses, and grown with the bounds of
- // actual heap arena ranges.
- arenaHints *arenaHint
-
- // arena is a pre-reserved space for allocating heap arenas
- // (the actual arenas). This is only used on 32-bit.
- arena linearAlloc
-
- // allArenas is the arenaIndex of every mapped arena. This can
- // be used to iterate through the address space.
- //
- // Access is protected by mheap_.lock. However, since this is
- // append-only and old backing arrays are never freed, it is
- // safe to acquire mheap_.lock, copy the slice header, and
- // then release mheap_.lock.
- allArenas []arenaIdx
-
- // sweepArenas is a snapshot of allArenas taken at the
- // beginning of the sweep cycle. This can be read safely by
- // simply blocking GC (by disabling preemption).
- sweepArenas []arenaIdx
-
- // markArenas is a snapshot of allArenas taken at the beginning
- // of the mark cycle. Because allArenas is append-only, neither
- // this slice nor its contents will change during the mark, so
- // it can be read safely.
- markArenas []arenaIdx
-
- // curArena is the arena that the heap is currently growing
- // into. This should always be physPageSize-aligned.
- curArena struct {
- base, end uintptr
- }
-
- // central free lists for small size classes.
- // the padding makes sure that the mcentrals are
- // spaced CacheLinePadSize bytes apart, so that each mcentral.lock
- // gets its own cache line.
- // central is indexed by spanClass.
- central [numSpanClasses]struct {
- mcentral mcentral
- pad [(cpu.CacheLinePadSize - unsafe.Sizeof(mcentral{})%cpu.CacheLinePadSize) % cpu.CacheLinePadSize]byte
- }
-
- spanalloc fixalloc // allocator for span*
- cachealloc fixalloc // allocator for mcache*
- specialfinalizeralloc fixalloc // allocator for specialfinalizer*
- specialprofilealloc fixalloc // allocator for specialprofile*
- specialReachableAlloc fixalloc // allocator for specialReachable
- speciallock mutex // lock for special record allocators.
- arenaHintAlloc fixalloc // allocator for arenaHints
-
- // User arena state.
- //
- // Protected by mheap_.lock.
- userArena struct {
- // arenaHints is a list of addresses at which to attempt to
- // add more heap arenas for user arena chunks. This is initially
- // populated with a set of general hint addresses, and grown with
- // the bounds of actual heap arena ranges.
- arenaHints *arenaHint
-
- // quarantineList is a list of user arena spans that have been set to fault, but
- // are waiting for all pointers into them to go away. Sweeping handles
- // identifying when this is true, and moves the span to the ready list.
- quarantineList mSpanList
-
- // readyList is a list of empty user arena spans that are ready for reuse.
- readyList mSpanList
- }
-
- unused *specialfinalizer // never set, just here to force the specialfinalizer type into DWARF
-}
-
-var mheap_ mheap
-
-// A heapArena stores metadata for a heap arena. heapArenas are stored
-// outside of the Go heap and accessed via the mheap_.arenas index.
-type heapArena struct {
- _ sys.NotInHeap
-
- // bitmap stores the pointer/scalar bitmap for the words in
- // this arena. See mbitmap.go for a description.
- // This array uses 1 bit per word of heap, or 1.6% of the heap size (for 64-bit).
- bitmap [heapArenaBitmapWords]uintptr
-
- // If the ith bit of noMorePtrs is true, then there are no more
- // pointers for the object containing the word described by the
- // high bit of bitmap[i].
- // In that case, bitmap[i+1], ... must be zero until the start
- // of the next object.
- // We never operate on these entries using bit-parallel techniques,
- // so it is ok if they are small. Also, they can't be bigger than
- // uint16 because at that size a single noMorePtrs entry
- // represents 8K of memory, the minimum size of a span. Any larger
- // and we'd have to worry about concurrent updates.
- // This array uses 1 bit per word of bitmap, or .024% of the heap size (for 64-bit).
- noMorePtrs [heapArenaBitmapWords / 8]uint8
-
- // spans maps from virtual address page ID within this arena to *mspan.
- // For allocated spans, their pages map to the span itself.
- // For free spans, only the lowest and highest pages map to the span itself.
- // Internal pages map to an arbitrary span.
- // For pages that have never been allocated, spans entries are nil.
- //
- // Modifications are protected by mheap.lock. Reads can be
- // performed without locking, but ONLY from indexes that are
- // known to contain in-use or stack spans. This means there
- // must not be a safe-point between establishing that an
- // address is live and looking it up in the spans array.
- spans [pagesPerArena]*mspan
-
- // pageInUse is a bitmap that indicates which spans are in
- // state mSpanInUse. This bitmap is indexed by page number,
- // but only the bit corresponding to the first page in each
- // span is used.
- //
- // Reads and writes are atomic.
- pageInUse [pagesPerArena / 8]uint8
-
- // pageMarks is a bitmap that indicates which spans have any
- // marked objects on them. Like pageInUse, only the bit
- // corresponding to the first page in each span is used.
- //
- // Writes are done atomically during marking. Reads are
- // non-atomic and lock-free since they only occur during
- // sweeping (and hence never race with writes).
- //
- // This is used to quickly find whole spans that can be freed.
- //
- // TODO(austin): It would be nice if this was uint64 for
- // faster scanning, but we don't have 64-bit atomic bit
- // operations.
- pageMarks [pagesPerArena / 8]uint8
-
- // pageSpecials is a bitmap that indicates which spans have
- // specials (finalizers or other). Like pageInUse, only the bit
- // corresponding to the first page in each span is used.
- //
- // Writes are done atomically whenever a special is added to
- // a span and whenever the last special is removed from a span.
- // Reads are done atomically to find spans containing specials
- // during marking.
- pageSpecials [pagesPerArena / 8]uint8
-
- // checkmarks stores the debug.gccheckmark state. It is only
- // used if debug.gccheckmark > 0.
- checkmarks *checkmarksMap
-
- // zeroedBase marks the first byte of the first page in this
- // arena which hasn't been used yet and is therefore already
- // zero. zeroedBase is relative to the arena base.
- // Increases monotonically until it hits heapArenaBytes.
- //
- // This field is sufficient to determine if an allocation
- // needs to be zeroed because the page allocator follows an
- // address-ordered first-fit policy.
- //
- // Read atomically and written with an atomic CAS.
- zeroedBase uintptr
-}
-
-// arenaHint is a hint for where to grow the heap arenas. See
-// mheap_.arenaHints.
-type arenaHint struct {
- _ sys.NotInHeap
- addr uintptr
- down bool
- next *arenaHint
-}
-
-// An mspan is a run of pages.
-//
-// When a mspan is in the heap free treap, state == mSpanFree
-// and heapmap(s->start) == span, heapmap(s->start+s->npages-1) == span.
-// If the mspan is in the heap scav treap, then in addition to the
-// above scavenged == true. scavenged == false in all other cases.
-//
-// When a mspan is allocated, state == mSpanInUse or mSpanManual
-// and heapmap(i) == span for all s->start <= i < s->start+s->npages.
-
-// Every mspan is in one doubly-linked list, either in the mheap's
-// busy list or one of the mcentral's span lists.
-
-// An mspan representing actual memory has state mSpanInUse,
-// mSpanManual, or mSpanFree. Transitions between these states are
-// constrained as follows:
-//
-// - A span may transition from free to in-use or manual during any GC
-// phase.
-//
-// - During sweeping (gcphase == _GCoff), a span may transition from
-// in-use to free (as a result of sweeping) or manual to free (as a
-// result of stacks being freed).
-//
-// - During GC (gcphase != _GCoff), a span *must not* transition from
-// manual or in-use to free. Because concurrent GC may read a pointer
-// and then look up its span, the span state must be monotonic.
-//
-// Setting mspan.state to mSpanInUse or mSpanManual must be done
-// atomically and only after all other span fields are valid.
-// Likewise, if inspecting a span is contingent on it being
-// mSpanInUse, the state should be loaded atomically and checked
-// before depending on other fields. This allows the garbage collector
-// to safely deal with potentially invalid pointers, since resolving
-// such pointers may race with a span being allocated.
-type mSpanState uint8
-
-const (
- mSpanDead mSpanState = iota
- mSpanInUse // allocated for garbage collected heap
- mSpanManual // allocated for manual management (e.g., stack allocator)
-)
-
-// mSpanStateNames are the names of the span states, indexed by
-// mSpanState.
-var mSpanStateNames = []string{
- "mSpanDead",
- "mSpanInUse",
- "mSpanManual",
-}
-
-// mSpanStateBox holds an atomic.Uint8 to provide atomic operations on
-// an mSpanState. This is a separate type to disallow accidental comparison
-// or assignment with mSpanState.
-type mSpanStateBox struct {
- s atomic.Uint8
-}
-
-// It is nosplit to match get, below.
-
-//go:nosplit
-func (b *mSpanStateBox) set(s mSpanState) {
- b.s.Store(uint8(s))
-}
-
-// It is nosplit because it's called indirectly by typedmemclr,
-// which must not be preempted.
-
-//go:nosplit
-func (b *mSpanStateBox) get() mSpanState {
- return mSpanState(b.s.Load())
-}
-
-// mSpanList heads a linked list of spans.
-type mSpanList struct {
- _ sys.NotInHeap
- first *mspan // first span in list, or nil if none
- last *mspan // last span in list, or nil if none
-}
-
-type mspan struct {
- _ sys.NotInHeap
- next *mspan // next span in list, or nil if none
- prev *mspan // previous span in list, or nil if none
- list *mSpanList // For debugging. TODO: Remove.
-
- startAddr uintptr // address of first byte of span aka s.base()
- npages uintptr // number of pages in span
-
- manualFreeList gclinkptr // list of free objects in mSpanManual spans
-
- // freeindex is the slot index between 0 and nelems at which to begin scanning
- // for the next free object in this span.
- // Each allocation scans allocBits starting at freeindex until it encounters a 0
- // indicating a free object. freeindex is then adjusted so that subsequent scans begin
- // just past the newly discovered free object.
- //
- // If freeindex == nelem, this span has no free objects.
- //
- // allocBits is a bitmap of objects in this span.
- // If n >= freeindex and allocBits[n/8] & (1<<(n%8)) is 0
- // then object n is free;
- // otherwise, object n is allocated. Bits starting at nelem are
- // undefined and should never be referenced.
- //
- // Object n starts at address n*elemsize + (start << pageShift).
- freeindex uintptr
- // TODO: Look up nelems from sizeclass and remove this field if it
- // helps performance.
- nelems uintptr // number of object in the span.
-
- // Cache of the allocBits at freeindex. allocCache is shifted
- // such that the lowest bit corresponds to the bit freeindex.
- // allocCache holds the complement of allocBits, thus allowing
- // ctz (count trailing zero) to use it directly.
- // allocCache may contain bits beyond s.nelems; the caller must ignore
- // these.
- allocCache uint64
-
- // allocBits and gcmarkBits hold pointers to a span's mark and
- // allocation bits. The pointers are 8 byte aligned.
- // There are three arenas where this data is held.
- // free: Dirty arenas that are no longer accessed
- // and can be reused.
- // next: Holds information to be used in the next GC cycle.
- // current: Information being used during this GC cycle.
- // previous: Information being used during the last GC cycle.
- // A new GC cycle starts with the call to finishsweep_m.
- // finishsweep_m moves the previous arena to the free arena,
- // the current arena to the previous arena, and
- // the next arena to the current arena.
- // The next arena is populated as the spans request
- // memory to hold gcmarkBits for the next GC cycle as well
- // as allocBits for newly allocated spans.
- //
- // The pointer arithmetic is done "by hand" instead of using
- // arrays to avoid bounds checks along critical performance
- // paths.
- // The sweep will free the old allocBits and set allocBits to the
- // gcmarkBits. The gcmarkBits are replaced with a fresh zeroed
- // out memory.
- allocBits *gcBits
- gcmarkBits *gcBits
-
- // sweep generation:
- // if sweepgen == h->sweepgen - 2, the span needs sweeping
- // if sweepgen == h->sweepgen - 1, the span is currently being swept
- // if sweepgen == h->sweepgen, the span is swept and ready to use
- // if sweepgen == h->sweepgen + 1, the span was cached before sweep began and is still cached, and needs sweeping
- // if sweepgen == h->sweepgen + 3, the span was swept and then cached and is still cached
- // h->sweepgen is incremented by 2 after every GC
-
- sweepgen uint32
- divMul uint32 // for divide by elemsize
- allocCount uint16 // number of allocated objects
- spanclass spanClass // size class and noscan (uint8)
- state mSpanStateBox // mSpanInUse etc; accessed atomically (get/set methods)
- needzero uint8 // needs to be zeroed before allocation
- isUserArenaChunk bool // whether or not this span represents a user arena
- allocCountBeforeCache uint16 // a copy of allocCount that is stored just before this span is cached
- elemsize uintptr // computed from sizeclass or from npages
- limit uintptr // end of data in span
- speciallock mutex // guards specials list
- specials *special // linked list of special records sorted by offset.
- userArenaChunkFree addrRange // interval for managing chunk allocation
-
- // freeIndexForScan is like freeindex, except that freeindex is
- // used by the allocator whereas freeIndexForScan is used by the
- // GC scanner. They are two fields so that the GC sees the object
- // is allocated only when the object and the heap bits are
- // initialized (see also the assignment of freeIndexForScan in
- // mallocgc, and issue 54596).
- freeIndexForScan uintptr
-}
-
-func (s *mspan) base() uintptr {
- return s.startAddr
-}
-
-func (s *mspan) layout() (size, n, total uintptr) {
- total = s.npages << _PageShift
- size = s.elemsize
- if size > 0 {
- n = total / size
- }
- return
-}
-
-// recordspan adds a newly allocated span to h.allspans.
-//
-// This only happens the first time a span is allocated from
-// mheap.spanalloc (it is not called when a span is reused).
-//
-// Write barriers are disallowed here because it can be called from
-// gcWork when allocating new workbufs. However, because it's an
-// indirect call from the fixalloc initializer, the compiler can't see
-// this.
-//
-// The heap lock must be held.
-//
-//go:nowritebarrierrec
-func recordspan(vh unsafe.Pointer, p unsafe.Pointer) {
- h := (*mheap)(vh)
- s := (*mspan)(p)
-
- assertLockHeld(&h.lock)
-
- if len(h.allspans) >= cap(h.allspans) {
- n := 64 * 1024 / goarch.PtrSize
- if n < cap(h.allspans)*3/2 {
- n = cap(h.allspans) * 3 / 2
- }
- var new []*mspan
- sp := (*slice)(unsafe.Pointer(&new))
- sp.array = sysAlloc(uintptr(n)*goarch.PtrSize, &memstats.other_sys)
- if sp.array == nil {
- throw("runtime: cannot allocate memory")
- }
- sp.len = len(h.allspans)
- sp.cap = n
- if len(h.allspans) > 0 {
- copy(new, h.allspans)
- }
- oldAllspans := h.allspans
- *(*notInHeapSlice)(unsafe.Pointer(&h.allspans)) = *(*notInHeapSlice)(unsafe.Pointer(&new))
- if len(oldAllspans) != 0 {
- sysFree(unsafe.Pointer(&oldAllspans[0]), uintptr(cap(oldAllspans))*unsafe.Sizeof(oldAllspans[0]), &memstats.other_sys)
- }
- }
- h.allspans = h.allspans[:len(h.allspans)+1]
- h.allspans[len(h.allspans)-1] = s
-}
-
-// A spanClass represents the size class and noscan-ness of a span.
-//
-// Each size class has a noscan spanClass and a scan spanClass. The
-// noscan spanClass contains only noscan objects, which do not contain
-// pointers and thus do not need to be scanned by the garbage
-// collector.
-type spanClass uint8
-
-const (
- numSpanClasses = _NumSizeClasses << 1
- tinySpanClass = spanClass(tinySizeClass<<1 | 1)
-)
-
-func makeSpanClass(sizeclass uint8, noscan bool) spanClass {
- return spanClass(sizeclass<<1) | spanClass(bool2int(noscan))
-}
-
-func (sc spanClass) sizeclass() int8 {
- return int8(sc >> 1)
-}
-
-func (sc spanClass) noscan() bool {
- return sc&1 != 0
-}
-
-// arenaIndex returns the index into mheap_.arenas of the arena
-// containing metadata for p. This index combines of an index into the
-// L1 map and an index into the L2 map and should be used as
-// mheap_.arenas[ai.l1()][ai.l2()].
-//
-// If p is outside the range of valid heap addresses, either l1() or
-// l2() will be out of bounds.
-//
-// It is nosplit because it's called by spanOf and several other
-// nosplit functions.
-//
-//go:nosplit
-func arenaIndex(p uintptr) arenaIdx {
- return arenaIdx((p - arenaBaseOffset) / heapArenaBytes)
-}
-
-// arenaBase returns the low address of the region covered by heap
-// arena i.
-func arenaBase(i arenaIdx) uintptr {
- return uintptr(i)*heapArenaBytes + arenaBaseOffset
-}
-
-type arenaIdx uint
-
-// l1 returns the "l1" portion of an arenaIdx.
-//
-// Marked nosplit because it's called by spanOf and other nosplit
-// functions.
-//
-//go:nosplit
-func (i arenaIdx) l1() uint {
- if arenaL1Bits == 0 {
- // Let the compiler optimize this away if there's no
- // L1 map.
- return 0
- } else {
- return uint(i) >> arenaL1Shift
- }
-}
-
-// l2 returns the "l2" portion of an arenaIdx.
-//
-// Marked nosplit because it's called by spanOf and other nosplit funcs.
-// functions.
-//
-//go:nosplit
-func (i arenaIdx) l2() uint {
- if arenaL1Bits == 0 {
- return uint(i)
- } else {
- return uint(i) & (1<<arenaL2Bits - 1)
- }
-}
-
-// inheap reports whether b is a pointer into a (potentially dead) heap object.
-// It returns false for pointers into mSpanManual spans.
-// Non-preemptible because it is used by write barriers.
-//
-//go:nowritebarrier
-//go:nosplit
-func inheap(b uintptr) bool {
- return spanOfHeap(b) != nil
-}
-
-// inHeapOrStack is a variant of inheap that returns true for pointers
-// into any allocated heap span.
-//
-//go:nowritebarrier
-//go:nosplit
-func inHeapOrStack(b uintptr) bool {
- s := spanOf(b)
- if s == nil || b < s.base() {
- return false
- }
- switch s.state.get() {
- case mSpanInUse, mSpanManual:
- return b < s.limit
- default:
- return false
- }
-}
-
-// spanOf returns the span of p. If p does not point into the heap
-// arena or no span has ever contained p, spanOf returns nil.
-//
-// If p does not point to allocated memory, this may return a non-nil
-// span that does *not* contain p. If this is a possibility, the
-// caller should either call spanOfHeap or check the span bounds
-// explicitly.
-//
-// Must be nosplit because it has callers that are nosplit.
-//
-//go:nosplit
-func spanOf(p uintptr) *mspan {
- // This function looks big, but we use a lot of constant
- // folding around arenaL1Bits to get it under the inlining
- // budget. Also, many of the checks here are safety checks
- // that Go needs to do anyway, so the generated code is quite
- // short.
- ri := arenaIndex(p)
- if arenaL1Bits == 0 {
- // If there's no L1, then ri.l1() can't be out of bounds but ri.l2() can.
- if ri.l2() >= uint(len(mheap_.arenas[0])) {
- return nil
- }
- } else {
- // If there's an L1, then ri.l1() can be out of bounds but ri.l2() can't.
- if ri.l1() >= uint(len(mheap_.arenas)) {
- return nil
- }
- }
- l2 := mheap_.arenas[ri.l1()]
- if arenaL1Bits != 0 && l2 == nil { // Should never happen if there's no L1.
- return nil
- }
- ha := l2[ri.l2()]
- if ha == nil {
- return nil
- }
- return ha.spans[(p/pageSize)%pagesPerArena]
-}
-
-// spanOfUnchecked is equivalent to spanOf, but the caller must ensure
-// that p points into an allocated heap arena.
-//
-// Must be nosplit because it has callers that are nosplit.
-//
-//go:nosplit
-func spanOfUnchecked(p uintptr) *mspan {
- ai := arenaIndex(p)
- return mheap_.arenas[ai.l1()][ai.l2()].spans[(p/pageSize)%pagesPerArena]
-}
-
-// spanOfHeap is like spanOf, but returns nil if p does not point to a
-// heap object.
-//
-// Must be nosplit because it has callers that are nosplit.
-//
-//go:nosplit
-func spanOfHeap(p uintptr) *mspan {
- s := spanOf(p)
- // s is nil if it's never been allocated. Otherwise, we check
- // its state first because we don't trust this pointer, so we
- // have to synchronize with span initialization. Then, it's
- // still possible we picked up a stale span pointer, so we
- // have to check the span's bounds.
- if s == nil || s.state.get() != mSpanInUse || p < s.base() || p >= s.limit {
- return nil
- }
- return s
-}
-
-// pageIndexOf returns the arena, page index, and page mask for pointer p.
-// The caller must ensure p is in the heap.
-func pageIndexOf(p uintptr) (arena *heapArena, pageIdx uintptr, pageMask uint8) {
- ai := arenaIndex(p)
- arena = mheap_.arenas[ai.l1()][ai.l2()]
- pageIdx = ((p / pageSize) / 8) % uintptr(len(arena.pageInUse))
- pageMask = byte(1 << ((p / pageSize) % 8))
- return
-}
-
-// Initialize the heap.
-func (h *mheap) init() {
- lockInit(&h.lock, lockRankMheap)
- lockInit(&h.speciallock, lockRankMheapSpecial)
-
- h.spanalloc.init(unsafe.Sizeof(mspan{}), recordspan, unsafe.Pointer(h), &memstats.mspan_sys)
- h.cachealloc.init(unsafe.Sizeof(mcache{}), nil, nil, &memstats.mcache_sys)
- h.specialfinalizeralloc.init(unsafe.Sizeof(specialfinalizer{}), nil, nil, &memstats.other_sys)
- h.specialprofilealloc.init(unsafe.Sizeof(specialprofile{}), nil, nil, &memstats.other_sys)
- h.specialReachableAlloc.init(unsafe.Sizeof(specialReachable{}), nil, nil, &memstats.other_sys)
- h.arenaHintAlloc.init(unsafe.Sizeof(arenaHint{}), nil, nil, &memstats.other_sys)
-
- // Don't zero mspan allocations. Background sweeping can
- // inspect a span concurrently with allocating it, so it's
- // important that the span's sweepgen survive across freeing
- // and re-allocating a span to prevent background sweeping
- // from improperly cas'ing it from 0.
- //
- // This is safe because mspan contains no heap pointers.
- h.spanalloc.zero = false
-
- // h->mapcache needs no init
-
- for i := range h.central {
- h.central[i].mcentral.init(spanClass(i))
- }
-
- h.pages.init(&h.lock, &memstats.gcMiscSys)
-}
-
-// reclaim sweeps and reclaims at least npage pages into the heap.
-// It is called before allocating npage pages to keep growth in check.
-//
-// reclaim implements the page-reclaimer half of the sweeper.
-//
-// h.lock must NOT be held.
-func (h *mheap) reclaim(npage uintptr) {
- // TODO(austin): Half of the time spent freeing spans is in
- // locking/unlocking the heap (even with low contention). We
- // could make the slow path here several times faster by
- // batching heap frees.
-
- // Bail early if there's no more reclaim work.
- if h.reclaimIndex.Load() >= 1<<63 {
- return
- }
-
- // Disable preemption so the GC can't start while we're
- // sweeping, so we can read h.sweepArenas, and so
- // traceGCSweepStart/Done pair on the P.
- mp := acquirem()
-
- if trace.enabled {
- traceGCSweepStart()
- }
-
- arenas := h.sweepArenas
- locked := false
- for npage > 0 {
- // Pull from accumulated credit first.
- if credit := h.reclaimCredit.Load(); credit > 0 {
- take := credit
- if take > npage {
- // Take only what we need.
- take = npage
- }
- if h.reclaimCredit.CompareAndSwap(credit, credit-take) {
- npage -= take
- }
- continue
- }
-
- // Claim a chunk of work.
- idx := uintptr(h.reclaimIndex.Add(pagesPerReclaimerChunk) - pagesPerReclaimerChunk)
- if idx/pagesPerArena >= uintptr(len(arenas)) {
- // Page reclaiming is done.
- h.reclaimIndex.Store(1 << 63)
- break
- }
-
- if !locked {
- // Lock the heap for reclaimChunk.
- lock(&h.lock)
- locked = true
- }
-
- // Scan this chunk.
- nfound := h.reclaimChunk(arenas, idx, pagesPerReclaimerChunk)
- if nfound <= npage {
- npage -= nfound
- } else {
- // Put spare pages toward global credit.
- h.reclaimCredit.Add(nfound - npage)
- npage = 0
- }
- }
- if locked {
- unlock(&h.lock)
- }
-
- if trace.enabled {
- traceGCSweepDone()
- }
- releasem(mp)
-}
-
-// reclaimChunk sweeps unmarked spans that start at page indexes [pageIdx, pageIdx+n).
-// It returns the number of pages returned to the heap.
-//
-// h.lock must be held and the caller must be non-preemptible. Note: h.lock may be
-// temporarily unlocked and re-locked in order to do sweeping or if tracing is
-// enabled.
-func (h *mheap) reclaimChunk(arenas []arenaIdx, pageIdx, n uintptr) uintptr {
- // The heap lock must be held because this accesses the
- // heapArena.spans arrays using potentially non-live pointers.
- // In particular, if a span were freed and merged concurrently
- // with this probing heapArena.spans, it would be possible to
- // observe arbitrary, stale span pointers.
- assertLockHeld(&h.lock)
-
- n0 := n
- var nFreed uintptr
- sl := sweep.active.begin()
- if !sl.valid {
- return 0
- }
- for n > 0 {
- ai := arenas[pageIdx/pagesPerArena]
- ha := h.arenas[ai.l1()][ai.l2()]
-
- // Get a chunk of the bitmap to work on.
- arenaPage := uint(pageIdx % pagesPerArena)
- inUse := ha.pageInUse[arenaPage/8:]
- marked := ha.pageMarks[arenaPage/8:]
- if uintptr(len(inUse)) > n/8 {
- inUse = inUse[:n/8]
- marked = marked[:n/8]
- }
-
- // Scan this bitmap chunk for spans that are in-use
- // but have no marked objects on them.
- for i := range inUse {
- inUseUnmarked := atomic.Load8(&inUse[i]) &^ marked[i]
- if inUseUnmarked == 0 {
- continue
- }
-
- for j := uint(0); j < 8; j++ {
- if inUseUnmarked&(1<<j) != 0 {
- s := ha.spans[arenaPage+uint(i)*8+j]
- if s, ok := sl.tryAcquire(s); ok {
- npages := s.npages
- unlock(&h.lock)
- if s.sweep(false) {
- nFreed += npages
- }
- lock(&h.lock)
- // Reload inUse. It's possible nearby
- // spans were freed when we dropped the
- // lock and we don't want to get stale
- // pointers from the spans array.
- inUseUnmarked = atomic.Load8(&inUse[i]) &^ marked[i]
- }
- }
- }
- }
-
- // Advance.
- pageIdx += uintptr(len(inUse) * 8)
- n -= uintptr(len(inUse) * 8)
- }
- sweep.active.end(sl)
- if trace.enabled {
- unlock(&h.lock)
- // Account for pages scanned but not reclaimed.
- traceGCSweepSpan((n0 - nFreed) * pageSize)
- lock(&h.lock)
- }
-
- assertLockHeld(&h.lock) // Must be locked on return.
- return nFreed
-}
-
-// spanAllocType represents the type of allocation to make, or
-// the type of allocation to be freed.
-type spanAllocType uint8
-
-const (
- spanAllocHeap spanAllocType = iota // heap span
- spanAllocStack // stack span
- spanAllocPtrScalarBits // unrolled GC prog bitmap span
- spanAllocWorkBuf // work buf span
-)
-
-// manual returns true if the span allocation is manually managed.
-func (s spanAllocType) manual() bool {
- return s != spanAllocHeap
-}
-
-// alloc allocates a new span of npage pages from the GC'd heap.
-//
-// spanclass indicates the span's size class and scannability.
-//
-// Returns a span that has been fully initialized. span.needzero indicates
-// whether the span has been zeroed. Note that it may not be.
-func (h *mheap) alloc(npages uintptr, spanclass spanClass) *mspan {
- // Don't do any operations that lock the heap on the G stack.
- // It might trigger stack growth, and the stack growth code needs
- // to be able to allocate heap.
- var s *mspan
- systemstack(func() {
- // To prevent excessive heap growth, before allocating n pages
- // we need to sweep and reclaim at least n pages.
- if !isSweepDone() {
- h.reclaim(npages)
- }
- s = h.allocSpan(npages, spanAllocHeap, spanclass)
- })
- return s
-}
-
-// allocManual allocates a manually-managed span of npage pages.
-// allocManual returns nil if allocation fails.
-//
-// allocManual adds the bytes used to *stat, which should be a
-// memstats in-use field. Unlike allocations in the GC'd heap, the
-// allocation does *not* count toward heapInUse.
-//
-// The memory backing the returned span may not be zeroed if
-// span.needzero is set.
-//
-// allocManual must be called on the system stack because it may
-// acquire the heap lock via allocSpan. See mheap for details.
-//
-// If new code is written to call allocManual, do NOT use an
-// existing spanAllocType value and instead declare a new one.
-//
-//go:systemstack
-func (h *mheap) allocManual(npages uintptr, typ spanAllocType) *mspan {
- if !typ.manual() {
- throw("manual span allocation called with non-manually-managed type")
- }
- return h.allocSpan(npages, typ, 0)
-}
-
-// setSpans modifies the span map so [spanOf(base), spanOf(base+npage*pageSize))
-// is s.
-func (h *mheap) setSpans(base, npage uintptr, s *mspan) {
- p := base / pageSize
- ai := arenaIndex(base)
- ha := h.arenas[ai.l1()][ai.l2()]
- for n := uintptr(0); n < npage; n++ {
- i := (p + n) % pagesPerArena
- if i == 0 {
- ai = arenaIndex(base + n*pageSize)
- ha = h.arenas[ai.l1()][ai.l2()]
- }
- ha.spans[i] = s
- }
-}
-
-// allocNeedsZero checks if the region of address space [base, base+npage*pageSize),
-// assumed to be allocated, needs to be zeroed, updating heap arena metadata for
-// future allocations.
-//
-// This must be called each time pages are allocated from the heap, even if the page
-// allocator can otherwise prove the memory it's allocating is already zero because
-// they're fresh from the operating system. It updates heapArena metadata that is
-// critical for future page allocations.
-//
-// There are no locking constraints on this method.
-func (h *mheap) allocNeedsZero(base, npage uintptr) (needZero bool) {
- for npage > 0 {
- ai := arenaIndex(base)
- ha := h.arenas[ai.l1()][ai.l2()]
-
- zeroedBase := atomic.Loaduintptr(&ha.zeroedBase)
- arenaBase := base % heapArenaBytes
- if arenaBase < zeroedBase {
- // We extended into the non-zeroed part of the
- // arena, so this region needs to be zeroed before use.
- //
- // zeroedBase is monotonically increasing, so if we see this now then
- // we can be sure we need to zero this memory region.
- //
- // We still need to update zeroedBase for this arena, and
- // potentially more arenas.
- needZero = true
- }
- // We may observe arenaBase > zeroedBase if we're racing with one or more
- // allocations which are acquiring memory directly before us in the address
- // space. But, because we know no one else is acquiring *this* memory, it's
- // still safe to not zero.
-
- // Compute how far into the arena we extend into, capped
- // at heapArenaBytes.
- arenaLimit := arenaBase + npage*pageSize
- if arenaLimit > heapArenaBytes {
- arenaLimit = heapArenaBytes
- }
- // Increase ha.zeroedBase so it's >= arenaLimit.
- // We may be racing with other updates.
- for arenaLimit > zeroedBase {
- if atomic.Casuintptr(&ha.zeroedBase, zeroedBase, arenaLimit) {
- break
- }
- zeroedBase = atomic.Loaduintptr(&ha.zeroedBase)
- // Double check basic conditions of zeroedBase.
- if zeroedBase <= arenaLimit && zeroedBase > arenaBase {
- // The zeroedBase moved into the space we were trying to
- // claim. That's very bad, and indicates someone allocated
- // the same region we did.
- throw("potentially overlapping in-use allocations detected")
- }
- }
-
- // Move base forward and subtract from npage to move into
- // the next arena, or finish.
- base += arenaLimit - arenaBase
- npage -= (arenaLimit - arenaBase) / pageSize
- }
- return
-}
-
-// tryAllocMSpan attempts to allocate an mspan object from
-// the P-local cache, but may fail.
-//
-// h.lock need not be held.
-//
-// This caller must ensure that its P won't change underneath
-// it during this function. Currently to ensure that we enforce
-// that the function is run on the system stack, because that's
-// the only place it is used now. In the future, this requirement
-// may be relaxed if its use is necessary elsewhere.
-//
-//go:systemstack
-func (h *mheap) tryAllocMSpan() *mspan {
- pp := getg().m.p.ptr()
- // If we don't have a p or the cache is empty, we can't do
- // anything here.
- if pp == nil || pp.mspancache.len == 0 {
- return nil
- }
- // Pull off the last entry in the cache.
- s := pp.mspancache.buf[pp.mspancache.len-1]
- pp.mspancache.len--
- return s
-}
-
-// allocMSpanLocked allocates an mspan object.
-//
-// h.lock must be held.
-//
-// allocMSpanLocked must be called on the system stack because
-// its caller holds the heap lock. See mheap for details.
-// Running on the system stack also ensures that we won't
-// switch Ps during this function. See tryAllocMSpan for details.
-//
-//go:systemstack
-func (h *mheap) allocMSpanLocked() *mspan {
- assertLockHeld(&h.lock)
-
- pp := getg().m.p.ptr()
- if pp == nil {
- // We don't have a p so just do the normal thing.
- return (*mspan)(h.spanalloc.alloc())
- }
- // Refill the cache if necessary.
- if pp.mspancache.len == 0 {
- const refillCount = len(pp.mspancache.buf) / 2
- for i := 0; i < refillCount; i++ {
- pp.mspancache.buf[i] = (*mspan)(h.spanalloc.alloc())
- }
- pp.mspancache.len = refillCount
- }
- // Pull off the last entry in the cache.
- s := pp.mspancache.buf[pp.mspancache.len-1]
- pp.mspancache.len--
- return s
-}
-
-// freeMSpanLocked free an mspan object.
-//
-// h.lock must be held.
-//
-// freeMSpanLocked must be called on the system stack because
-// its caller holds the heap lock. See mheap for details.
-// Running on the system stack also ensures that we won't
-// switch Ps during this function. See tryAllocMSpan for details.
-//
-//go:systemstack
-func (h *mheap) freeMSpanLocked(s *mspan) {
- assertLockHeld(&h.lock)
-
- pp := getg().m.p.ptr()
- // First try to free the mspan directly to the cache.
- if pp != nil && pp.mspancache.len < len(pp.mspancache.buf) {
- pp.mspancache.buf[pp.mspancache.len] = s
- pp.mspancache.len++
- return
- }
- // Failing that (or if we don't have a p), just free it to
- // the heap.
- h.spanalloc.free(unsafe.Pointer(s))
-}
-
-// allocSpan allocates an mspan which owns npages worth of memory.
-//
-// If typ.manual() == false, allocSpan allocates a heap span of class spanclass
-// and updates heap accounting. If manual == true, allocSpan allocates a
-// manually-managed span (spanclass is ignored), and the caller is
-// responsible for any accounting related to its use of the span. Either
-// way, allocSpan will atomically add the bytes in the newly allocated
-// span to *sysStat.
-//
-// The returned span is fully initialized.
-//
-// h.lock must not be held.
-//
-// allocSpan must be called on the system stack both because it acquires
-// the heap lock and because it must block GC transitions.
-//
-//go:systemstack
-func (h *mheap) allocSpan(npages uintptr, typ spanAllocType, spanclass spanClass) (s *mspan) {
- // Function-global state.
- gp := getg()
- base, scav := uintptr(0), uintptr(0)
- growth := uintptr(0)
-
- // On some platforms we need to provide physical page aligned stack
- // allocations. Where the page size is less than the physical page
- // size, we already manage to do this by default.
- needPhysPageAlign := physPageAlignedStacks && typ == spanAllocStack && pageSize < physPageSize
-
- // If the allocation is small enough, try the page cache!
- // The page cache does not support aligned allocations, so we cannot use
- // it if we need to provide a physical page aligned stack allocation.
- pp := gp.m.p.ptr()
- if !needPhysPageAlign && pp != nil && npages < pageCachePages/4 {
- c := &pp.pcache
-
- // If the cache is empty, refill it.
- if c.empty() {
- lock(&h.lock)
- *c = h.pages.allocToCache()
- unlock(&h.lock)
- }
-
- // Try to allocate from the cache.
- base, scav = c.alloc(npages)
- if base != 0 {
- s = h.tryAllocMSpan()
- if s != nil {
- goto HaveSpan
- }
- // We have a base but no mspan, so we need
- // to lock the heap.
- }
- }
-
- // For one reason or another, we couldn't get the
- // whole job done without the heap lock.
- lock(&h.lock)
-
- if needPhysPageAlign {
- // Overallocate by a physical page to allow for later alignment.
- extraPages := physPageSize / pageSize
-
- // Find a big enough region first, but then only allocate the
- // aligned portion. We can't just allocate and then free the
- // edges because we need to account for scavenged memory, and
- // that's difficult with alloc.
- //
- // Note that we skip updates to searchAddr here. It's OK if
- // it's stale and higher than normal; it'll operate correctly,
- // just come with a performance cost.
- base, _ = h.pages.find(npages + extraPages)
- if base == 0 {
- var ok bool
- growth, ok = h.grow(npages + extraPages)
- if !ok {
- unlock(&h.lock)
- return nil
- }
- base, _ = h.pages.find(npages + extraPages)
- if base == 0 {
- throw("grew heap, but no adequate free space found")
- }
- }
- base = alignUp(base, physPageSize)
- scav = h.pages.allocRange(base, npages)
- }
-
- if base == 0 {
- // Try to acquire a base address.
- base, scav = h.pages.alloc(npages)
- if base == 0 {
- var ok bool
- growth, ok = h.grow(npages)
- if !ok {
- unlock(&h.lock)
- return nil
- }
- base, scav = h.pages.alloc(npages)
- if base == 0 {
- throw("grew heap, but no adequate free space found")
- }
- }
- }
- if s == nil {
- // We failed to get an mspan earlier, so grab
- // one now that we have the heap lock.
- s = h.allocMSpanLocked()
- }
- unlock(&h.lock)
-
-HaveSpan:
- // Decide if we need to scavenge in response to what we just allocated.
- // Specifically, we track the maximum amount of memory to scavenge of all
- // the alternatives below, assuming that the maximum satisfies *all*
- // conditions we check (e.g. if we need to scavenge X to satisfy the
- // memory limit and Y to satisfy heap-growth scavenging, and Y > X, then
- // it's fine to pick Y, because the memory limit is still satisfied).
- //
- // It's fine to do this after allocating because we expect any scavenged
- // pages not to get touched until we return. Simultaneously, it's important
- // to do this before calling sysUsed because that may commit address space.
- bytesToScavenge := uintptr(0)
- if limit := gcController.memoryLimit.Load(); go119MemoryLimitSupport && !gcCPULimiter.limiting() {
- // Assist with scavenging to maintain the memory limit by the amount
- // that we expect to page in.
- inuse := gcController.mappedReady.Load()
- // Be careful about overflow, especially with uintptrs. Even on 32-bit platforms
- // someone can set a really big memory limit that isn't maxInt64.
- if uint64(scav)+inuse > uint64(limit) {
- bytesToScavenge = uintptr(uint64(scav) + inuse - uint64(limit))
- }
- }
- if goal := scavenge.gcPercentGoal.Load(); goal != ^uint64(0) && growth > 0 {
- // We just caused a heap growth, so scavenge down what will soon be used.
- // By scavenging inline we deal with the failure to allocate out of
- // memory fragments by scavenging the memory fragments that are least
- // likely to be re-used.
- //
- // Only bother with this because we're not using a memory limit. We don't
- // care about heap growths as long as we're under the memory limit, and the
- // previous check for scaving already handles that.
- if retained := heapRetained(); retained+uint64(growth) > goal {
- // The scavenging algorithm requires the heap lock to be dropped so it
- // can acquire it only sparingly. This is a potentially expensive operation
- // so it frees up other goroutines to allocate in the meanwhile. In fact,
- // they can make use of the growth we just created.
- todo := growth
- if overage := uintptr(retained + uint64(growth) - goal); todo > overage {
- todo = overage
- }
- if todo > bytesToScavenge {
- bytesToScavenge = todo
- }
- }
- }
- // There are a few very limited cirumstances where we won't have a P here.
- // It's OK to simply skip scavenging in these cases. Something else will notice
- // and pick up the tab.
- var now int64
- if pp != nil && bytesToScavenge > 0 {
- // Measure how long we spent scavenging and add that measurement to the assist
- // time so we can track it for the GC CPU limiter.
- //
- // Limiter event tracking might be disabled if we end up here
- // while on a mark worker.
- start := nanotime()
- track := pp.limiterEvent.start(limiterEventScavengeAssist, start)
-
- // Scavenge, but back out if the limiter turns on.
- h.pages.scavenge(bytesToScavenge, func() bool {
- return gcCPULimiter.limiting()
- })
-
- // Finish up accounting.
- now = nanotime()
- if track {
- pp.limiterEvent.stop(limiterEventScavengeAssist, now)
- }
- scavenge.assistTime.Add(now - start)
- }
-
- // Initialize the span.
- h.initSpan(s, typ, spanclass, base, npages)
-
- // Commit and account for any scavenged memory that the span now owns.
- nbytes := npages * pageSize
- if scav != 0 {
- // sysUsed all the pages that are actually available
- // in the span since some of them might be scavenged.
- sysUsed(unsafe.Pointer(base), nbytes, scav)
- gcController.heapReleased.add(-int64(scav))
- }
- // Update stats.
- gcController.heapFree.add(-int64(nbytes - scav))
- if typ == spanAllocHeap {
- gcController.heapInUse.add(int64(nbytes))
- }
- // Update consistent stats.
- stats := memstats.heapStats.acquire()
- atomic.Xaddint64(&stats.committed, int64(scav))
- atomic.Xaddint64(&stats.released, -int64(scav))
- switch typ {
- case spanAllocHeap:
- atomic.Xaddint64(&stats.inHeap, int64(nbytes))
- case spanAllocStack:
- atomic.Xaddint64(&stats.inStacks, int64(nbytes))
- case spanAllocPtrScalarBits:
- atomic.Xaddint64(&stats.inPtrScalarBits, int64(nbytes))
- case spanAllocWorkBuf:
- atomic.Xaddint64(&stats.inWorkBufs, int64(nbytes))
- }
- memstats.heapStats.release()
-
- pageTraceAlloc(pp, now, base, npages)
- return s
-}
-
-// initSpan initializes a blank span s which will represent the range
-// [base, base+npages*pageSize). typ is the type of span being allocated.
-func (h *mheap) initSpan(s *mspan, typ spanAllocType, spanclass spanClass, base, npages uintptr) {
- // At this point, both s != nil and base != 0, and the heap
- // lock is no longer held. Initialize the span.
- s.init(base, npages)
- if h.allocNeedsZero(base, npages) {
- s.needzero = 1
- }
- nbytes := npages * pageSize
- if typ.manual() {
- s.manualFreeList = 0
- s.nelems = 0
- s.limit = s.base() + s.npages*pageSize
- s.state.set(mSpanManual)
- } else {
- // We must set span properties before the span is published anywhere
- // since we're not holding the heap lock.
- s.spanclass = spanclass
- if sizeclass := spanclass.sizeclass(); sizeclass == 0 {
- s.elemsize = nbytes
- s.nelems = 1
- s.divMul = 0
- } else {
- s.elemsize = uintptr(class_to_size[sizeclass])
- s.nelems = nbytes / s.elemsize
- s.divMul = class_to_divmagic[sizeclass]
- }
-
- // Initialize mark and allocation structures.
- s.freeindex = 0
- s.freeIndexForScan = 0
- s.allocCache = ^uint64(0) // all 1s indicating all free.
- s.gcmarkBits = newMarkBits(s.nelems)
- s.allocBits = newAllocBits(s.nelems)
-
- // It's safe to access h.sweepgen without the heap lock because it's
- // only ever updated with the world stopped and we run on the
- // systemstack which blocks a STW transition.
- atomic.Store(&s.sweepgen, h.sweepgen)
-
- // Now that the span is filled in, set its state. This
- // is a publication barrier for the other fields in
- // the span. While valid pointers into this span
- // should never be visible until the span is returned,
- // if the garbage collector finds an invalid pointer,
- // access to the span may race with initialization of
- // the span. We resolve this race by atomically
- // setting the state after the span is fully
- // initialized, and atomically checking the state in
- // any situation where a pointer is suspect.
- s.state.set(mSpanInUse)
- }
-
- // Publish the span in various locations.
-
- // This is safe to call without the lock held because the slots
- // related to this span will only ever be read or modified by
- // this thread until pointers into the span are published (and
- // we execute a publication barrier at the end of this function
- // before that happens) or pageInUse is updated.
- h.setSpans(s.base(), npages, s)
-
- if !typ.manual() {
- // Mark in-use span in arena page bitmap.
- //
- // This publishes the span to the page sweeper, so
- // it's imperative that the span be completely initialized
- // prior to this line.
- arena, pageIdx, pageMask := pageIndexOf(s.base())
- atomic.Or8(&arena.pageInUse[pageIdx], pageMask)
-
- // Update related page sweeper stats.
- h.pagesInUse.Add(npages)
- }
-
- // Make sure the newly allocated span will be observed
- // by the GC before pointers into the span are published.
- publicationBarrier()
-}
-
-// Try to add at least npage pages of memory to the heap,
-// returning how much the heap grew by and whether it worked.
-//
-// h.lock must be held.
-func (h *mheap) grow(npage uintptr) (uintptr, bool) {
- assertLockHeld(&h.lock)
-
- // We must grow the heap in whole palloc chunks.
- // We call sysMap below but note that because we
- // round up to pallocChunkPages which is on the order
- // of MiB (generally >= to the huge page size) we
- // won't be calling it too much.
- ask := alignUp(npage, pallocChunkPages) * pageSize
-
- totalGrowth := uintptr(0)
- // This may overflow because ask could be very large
- // and is otherwise unrelated to h.curArena.base.
- end := h.curArena.base + ask
- nBase := alignUp(end, physPageSize)
- if nBase > h.curArena.end || /* overflow */ end < h.curArena.base {
- // Not enough room in the current arena. Allocate more
- // arena space. This may not be contiguous with the
- // current arena, so we have to request the full ask.
- av, asize := h.sysAlloc(ask, &h.arenaHints, true)
- if av == nil {
- inUse := gcController.heapFree.load() + gcController.heapReleased.load() + gcController.heapInUse.load()
- print("runtime: out of memory: cannot allocate ", ask, "-byte block (", inUse, " in use)\n")
- return 0, false
- }
-
- if uintptr(av) == h.curArena.end {
- // The new space is contiguous with the old
- // space, so just extend the current space.
- h.curArena.end = uintptr(av) + asize
- } else {
- // The new space is discontiguous. Track what
- // remains of the current space and switch to
- // the new space. This should be rare.
- if size := h.curArena.end - h.curArena.base; size != 0 {
- // Transition this space from Reserved to Prepared and mark it
- // as released since we'll be able to start using it after updating
- // the page allocator and releasing the lock at any time.
- sysMap(unsafe.Pointer(h.curArena.base), size, &gcController.heapReleased)
- // Update stats.
- stats := memstats.heapStats.acquire()
- atomic.Xaddint64(&stats.released, int64(size))
- memstats.heapStats.release()
- // Update the page allocator's structures to make this
- // space ready for allocation.
- h.pages.grow(h.curArena.base, size)
- totalGrowth += size
- }
- // Switch to the new space.
- h.curArena.base = uintptr(av)
- h.curArena.end = uintptr(av) + asize
- }
-
- // Recalculate nBase.
- // We know this won't overflow, because sysAlloc returned
- // a valid region starting at h.curArena.base which is at
- // least ask bytes in size.
- nBase = alignUp(h.curArena.base+ask, physPageSize)
- }
-
- // Grow into the current arena.
- v := h.curArena.base
- h.curArena.base = nBase
-
- // Transition the space we're going to use from Reserved to Prepared.
- //
- // The allocation is always aligned to the heap arena
- // size which is always > physPageSize, so its safe to
- // just add directly to heapReleased.
- sysMap(unsafe.Pointer(v), nBase-v, &gcController.heapReleased)
-
- // The memory just allocated counts as both released
- // and idle, even though it's not yet backed by spans.
- stats := memstats.heapStats.acquire()
- atomic.Xaddint64(&stats.released, int64(nBase-v))
- memstats.heapStats.release()
-
- // Update the page allocator's structures to make this
- // space ready for allocation.
- h.pages.grow(v, nBase-v)
- totalGrowth += nBase - v
- return totalGrowth, true
-}
-
-// Free the span back into the heap.
-func (h *mheap) freeSpan(s *mspan) {
- systemstack(func() {
- pageTraceFree(getg().m.p.ptr(), 0, s.base(), s.npages)
-
- lock(&h.lock)
- if msanenabled {
- // Tell msan that this entire span is no longer in use.
- base := unsafe.Pointer(s.base())
- bytes := s.npages << _PageShift
- msanfree(base, bytes)
- }
- if asanenabled {
- // Tell asan that this entire span is no longer in use.
- base := unsafe.Pointer(s.base())
- bytes := s.npages << _PageShift
- asanpoison(base, bytes)
- }
- h.freeSpanLocked(s, spanAllocHeap)
- unlock(&h.lock)
- })
-}
-
-// freeManual frees a manually-managed span returned by allocManual.
-// typ must be the same as the spanAllocType passed to the allocManual that
-// allocated s.
-//
-// This must only be called when gcphase == _GCoff. See mSpanState for
-// an explanation.
-//
-// freeManual must be called on the system stack because it acquires
-// the heap lock. See mheap for details.
-//
-//go:systemstack
-func (h *mheap) freeManual(s *mspan, typ spanAllocType) {
- pageTraceFree(getg().m.p.ptr(), 0, s.base(), s.npages)
-
- s.needzero = 1
- lock(&h.lock)
- h.freeSpanLocked(s, typ)
- unlock(&h.lock)
-}
-
-func (h *mheap) freeSpanLocked(s *mspan, typ spanAllocType) {
- assertLockHeld(&h.lock)
-
- switch s.state.get() {
- case mSpanManual:
- if s.allocCount != 0 {
- throw("mheap.freeSpanLocked - invalid stack free")
- }
- case mSpanInUse:
- if s.isUserArenaChunk {
- throw("mheap.freeSpanLocked - invalid free of user arena chunk")
- }
- if s.allocCount != 0 || s.sweepgen != h.sweepgen {
- print("mheap.freeSpanLocked - span ", s, " ptr ", hex(s.base()), " allocCount ", s.allocCount, " sweepgen ", s.sweepgen, "/", h.sweepgen, "\n")
- throw("mheap.freeSpanLocked - invalid free")
- }
- h.pagesInUse.Add(-s.npages)
-
- // Clear in-use bit in arena page bitmap.
- arena, pageIdx, pageMask := pageIndexOf(s.base())
- atomic.And8(&arena.pageInUse[pageIdx], ^pageMask)
- default:
- throw("mheap.freeSpanLocked - invalid span state")
- }
-
- // Update stats.
- //
- // Mirrors the code in allocSpan.
- nbytes := s.npages * pageSize
- gcController.heapFree.add(int64(nbytes))
- if typ == spanAllocHeap {
- gcController.heapInUse.add(-int64(nbytes))
- }
- // Update consistent stats.
- stats := memstats.heapStats.acquire()
- switch typ {
- case spanAllocHeap:
- atomic.Xaddint64(&stats.inHeap, -int64(nbytes))
- case spanAllocStack:
- atomic.Xaddint64(&stats.inStacks, -int64(nbytes))
- case spanAllocPtrScalarBits:
- atomic.Xaddint64(&stats.inPtrScalarBits, -int64(nbytes))
- case spanAllocWorkBuf:
- atomic.Xaddint64(&stats.inWorkBufs, -int64(nbytes))
- }
- memstats.heapStats.release()
-
- // Mark the space as free.
- h.pages.free(s.base(), s.npages, false)
-
- // Free the span structure. We no longer have a use for it.
- s.state.set(mSpanDead)
- h.freeMSpanLocked(s)
-}
-
-// scavengeAll acquires the heap lock (blocking any additional
-// manipulation of the page allocator) and iterates over the whole
-// heap, scavenging every free page available.
-func (h *mheap) scavengeAll() {
- // Disallow malloc or panic while holding the heap lock. We do
- // this here because this is a non-mallocgc entry-point to
- // the mheap API.
- gp := getg()
- gp.m.mallocing++
-
- released := h.pages.scavenge(^uintptr(0), nil)
-
- gp.m.mallocing--
-
- if debug.scavtrace > 0 {
- printScavTrace(released, true)
- }
-}
-
-//go:linkname runtime_debug_freeOSMemory runtime/debug.freeOSMemory
-func runtime_debug_freeOSMemory() {
- GC()
- systemstack(func() { mheap_.scavengeAll() })
-}
-
-// Initialize a new span with the given start and npages.
-func (span *mspan) init(base uintptr, npages uintptr) {
- // span is *not* zeroed.
- span.next = nil
- span.prev = nil
- span.list = nil
- span.startAddr = base
- span.npages = npages
- span.allocCount = 0
- span.spanclass = 0
- span.elemsize = 0
- span.speciallock.key = 0
- span.specials = nil
- span.needzero = 0
- span.freeindex = 0
- span.freeIndexForScan = 0
- span.allocBits = nil
- span.gcmarkBits = nil
- span.state.set(mSpanDead)
- lockInit(&span.speciallock, lockRankMspanSpecial)
-}
-
-func (span *mspan) inList() bool {
- return span.list != nil
-}
-
-// Initialize an empty doubly-linked list.
-func (list *mSpanList) init() {
- list.first = nil
- list.last = nil
-}
-
-func (list *mSpanList) remove(span *mspan) {
- if span.list != list {
- print("runtime: failed mSpanList.remove span.npages=", span.npages,
- " span=", span, " prev=", span.prev, " span.list=", span.list, " list=", list, "\n")
- throw("mSpanList.remove")
- }
- if list.first == span {
- list.first = span.next
- } else {
- span.prev.next = span.next
- }
- if list.last == span {
- list.last = span.prev
- } else {
- span.next.prev = span.prev
- }
- span.next = nil
- span.prev = nil
- span.list = nil
-}
-
-func (list *mSpanList) isEmpty() bool {
- return list.first == nil
-}
-
-func (list *mSpanList) insert(span *mspan) {
- if span.next != nil || span.prev != nil || span.list != nil {
- println("runtime: failed mSpanList.insert", span, span.next, span.prev, span.list)
- throw("mSpanList.insert")
- }
- span.next = list.first
- if list.first != nil {
- // The list contains at least one span; link it in.
- // The last span in the list doesn't change.
- list.first.prev = span
- } else {
- // The list contains no spans, so this is also the last span.
- list.last = span
- }
- list.first = span
- span.list = list
-}
-
-func (list *mSpanList) insertBack(span *mspan) {
- if span.next != nil || span.prev != nil || span.list != nil {
- println("runtime: failed mSpanList.insertBack", span, span.next, span.prev, span.list)
- throw("mSpanList.insertBack")
- }
- span.prev = list.last
- if list.last != nil {
- // The list contains at least one span.
- list.last.next = span
- } else {
- // The list contains no spans, so this is also the first span.
- list.first = span
- }
- list.last = span
- span.list = list
-}
-
-// takeAll removes all spans from other and inserts them at the front
-// of list.
-func (list *mSpanList) takeAll(other *mSpanList) {
- if other.isEmpty() {
- return
- }
-
- // Reparent everything in other to list.
- for s := other.first; s != nil; s = s.next {
- s.list = list
- }
-
- // Concatenate the lists.
- if list.isEmpty() {
- *list = *other
- } else {
- // Neither list is empty. Put other before list.
- other.last.next = list.first
- list.first.prev = other.last
- list.first = other.first
- }
-
- other.first, other.last = nil, nil
-}
-
-const (
- _KindSpecialFinalizer = 1
- _KindSpecialProfile = 2
- // _KindSpecialReachable is a special used for tracking
- // reachability during testing.
- _KindSpecialReachable = 3
- // Note: The finalizer special must be first because if we're freeing
- // an object, a finalizer special will cause the freeing operation
- // to abort, and we want to keep the other special records around
- // if that happens.
-)
-
-type special struct {
- _ sys.NotInHeap
- next *special // linked list in span
- offset uint16 // span offset of object
- kind byte // kind of special
-}
-
-// spanHasSpecials marks a span as having specials in the arena bitmap.
-func spanHasSpecials(s *mspan) {
- arenaPage := (s.base() / pageSize) % pagesPerArena
- ai := arenaIndex(s.base())
- ha := mheap_.arenas[ai.l1()][ai.l2()]
- atomic.Or8(&ha.pageSpecials[arenaPage/8], uint8(1)<<(arenaPage%8))
-}
-
-// spanHasNoSpecials marks a span as having no specials in the arena bitmap.
-func spanHasNoSpecials(s *mspan) {
- arenaPage := (s.base() / pageSize) % pagesPerArena
- ai := arenaIndex(s.base())
- ha := mheap_.arenas[ai.l1()][ai.l2()]
- atomic.And8(&ha.pageSpecials[arenaPage/8], ^(uint8(1) << (arenaPage % 8)))
-}
-
-// Adds the special record s to the list of special records for
-// the object p. All fields of s should be filled in except for
-// offset & next, which this routine will fill in.
-// Returns true if the special was successfully added, false otherwise.
-// (The add will fail only if a record with the same p and s->kind
-// already exists.)
-func addspecial(p unsafe.Pointer, s *special) bool {
- span := spanOfHeap(uintptr(p))
- if span == nil {
- throw("addspecial on invalid pointer")
- }
-
- // Ensure that the span is swept.
- // Sweeping accesses the specials list w/o locks, so we have
- // to synchronize with it. And it's just much safer.
- mp := acquirem()
- span.ensureSwept()
-
- offset := uintptr(p) - span.base()
- kind := s.kind
-
- lock(&span.speciallock)
-
- // Find splice point, check for existing record.
- t := &span.specials
- for {
- x := *t
- if x == nil {
- break
- }
- if offset == uintptr(x.offset) && kind == x.kind {
- unlock(&span.speciallock)
- releasem(mp)
- return false // already exists
- }
- if offset < uintptr(x.offset) || (offset == uintptr(x.offset) && kind < x.kind) {
- break
- }
- t = &x.next
- }
-
- // Splice in record, fill in offset.
- s.offset = uint16(offset)
- s.next = *t
- *t = s
- spanHasSpecials(span)
- unlock(&span.speciallock)
- releasem(mp)
-
- return true
-}
-
-// Removes the Special record of the given kind for the object p.
-// Returns the record if the record existed, nil otherwise.
-// The caller must FixAlloc_Free the result.
-func removespecial(p unsafe.Pointer, kind uint8) *special {
- span := spanOfHeap(uintptr(p))
- if span == nil {
- throw("removespecial on invalid pointer")
- }
-
- // Ensure that the span is swept.
- // Sweeping accesses the specials list w/o locks, so we have
- // to synchronize with it. And it's just much safer.
- mp := acquirem()
- span.ensureSwept()
-
- offset := uintptr(p) - span.base()
-
- var result *special
- lock(&span.speciallock)
- t := &span.specials
- for {
- s := *t
- if s == nil {
- break
- }
- // This function is used for finalizers only, so we don't check for
- // "interior" specials (p must be exactly equal to s->offset).
- if offset == uintptr(s.offset) && kind == s.kind {
- *t = s.next
- result = s
- break
- }
- t = &s.next
- }
- if span.specials == nil {
- spanHasNoSpecials(span)
- }
- unlock(&span.speciallock)
- releasem(mp)
- return result
-}
-
-// The described object has a finalizer set for it.
-//
-// specialfinalizer is allocated from non-GC'd memory, so any heap
-// pointers must be specially handled.
-type specialfinalizer struct {
- _ sys.NotInHeap
- special special
- fn *funcval // May be a heap pointer.
- nret uintptr
- fint *_type // May be a heap pointer, but always live.
- ot *ptrtype // May be a heap pointer, but always live.
-}
-
-// Adds a finalizer to the object p. Returns true if it succeeded.
-func addfinalizer(p unsafe.Pointer, f *funcval, nret uintptr, fint *_type, ot *ptrtype) bool {
- lock(&mheap_.speciallock)
- s := (*specialfinalizer)(mheap_.specialfinalizeralloc.alloc())
- unlock(&mheap_.speciallock)
- s.special.kind = _KindSpecialFinalizer
- s.fn = f
- s.nret = nret
- s.fint = fint
- s.ot = ot
- if addspecial(p, &s.special) {
- // This is responsible for maintaining the same
- // GC-related invariants as markrootSpans in any
- // situation where it's possible that markrootSpans
- // has already run but mark termination hasn't yet.
- if gcphase != _GCoff {
- base, span, _ := findObject(uintptr(p), 0, 0)
- mp := acquirem()
- gcw := &mp.p.ptr().gcw
- // Mark everything reachable from the object
- // so it's retained for the finalizer.
- if !span.spanclass.noscan() {
- scanobject(base, gcw)
- }
- // Mark the finalizer itself, since the
- // special isn't part of the GC'd heap.
- scanblock(uintptr(unsafe.Pointer(&s.fn)), goarch.PtrSize, &oneptrmask[0], gcw, nil)
- releasem(mp)
- }
- return true
- }
-
- // There was an old finalizer
- lock(&mheap_.speciallock)
- mheap_.specialfinalizeralloc.free(unsafe.Pointer(s))
- unlock(&mheap_.speciallock)
- return false
-}
-
-// Removes the finalizer (if any) from the object p.
-func removefinalizer(p unsafe.Pointer) {
- s := (*specialfinalizer)(unsafe.Pointer(removespecial(p, _KindSpecialFinalizer)))
- if s == nil {
- return // there wasn't a finalizer to remove
- }
- lock(&mheap_.speciallock)
- mheap_.specialfinalizeralloc.free(unsafe.Pointer(s))
- unlock(&mheap_.speciallock)
-}
-
-// The described object is being heap profiled.
-type specialprofile struct {
- _ sys.NotInHeap
- special special
- b *bucket
-}
-
-// Set the heap profile bucket associated with addr to b.
-func setprofilebucket(p unsafe.Pointer, b *bucket) {
- lock(&mheap_.speciallock)
- s := (*specialprofile)(mheap_.specialprofilealloc.alloc())
- unlock(&mheap_.speciallock)
- s.special.kind = _KindSpecialProfile
- s.b = b
- if !addspecial(p, &s.special) {
- throw("setprofilebucket: profile already set")
- }
-}
-
-// specialReachable tracks whether an object is reachable on the next
-// GC cycle. This is used by testing.
-type specialReachable struct {
- special special
- done bool
- reachable bool
-}
-
-// specialsIter helps iterate over specials lists.
-type specialsIter struct {
- pprev **special
- s *special
-}
-
-func newSpecialsIter(span *mspan) specialsIter {
- return specialsIter{&span.specials, span.specials}
-}
-
-func (i *specialsIter) valid() bool {
- return i.s != nil
-}
-
-func (i *specialsIter) next() {
- i.pprev = &i.s.next
- i.s = *i.pprev
-}
-
-// unlinkAndNext removes the current special from the list and moves
-// the iterator to the next special. It returns the unlinked special.
-func (i *specialsIter) unlinkAndNext() *special {
- cur := i.s
- i.s = cur.next
- *i.pprev = i.s
- return cur
-}
-
-// freeSpecial performs any cleanup on special s and deallocates it.
-// s must already be unlinked from the specials list.
-func freeSpecial(s *special, p unsafe.Pointer, size uintptr) {
- switch s.kind {
- case _KindSpecialFinalizer:
- sf := (*specialfinalizer)(unsafe.Pointer(s))
- queuefinalizer(p, sf.fn, sf.nret, sf.fint, sf.ot)
- lock(&mheap_.speciallock)
- mheap_.specialfinalizeralloc.free(unsafe.Pointer(sf))
- unlock(&mheap_.speciallock)
- case _KindSpecialProfile:
- sp := (*specialprofile)(unsafe.Pointer(s))
- mProf_Free(sp.b, size)
- lock(&mheap_.speciallock)
- mheap_.specialprofilealloc.free(unsafe.Pointer(sp))
- unlock(&mheap_.speciallock)
- case _KindSpecialReachable:
- sp := (*specialReachable)(unsafe.Pointer(s))
- sp.done = true
- // The creator frees these.
- default:
- throw("bad special kind")
- panic("not reached")
- }
-}
-
-// gcBits is an alloc/mark bitmap. This is always used as gcBits.x.
-type gcBits struct {
- _ sys.NotInHeap
- x uint8
-}
-
-// bytep returns a pointer to the n'th byte of b.
-func (b *gcBits) bytep(n uintptr) *uint8 {
- return addb(&b.x, n)
-}
-
-// bitp returns a pointer to the byte containing bit n and a mask for
-// selecting that bit from *bytep.
-func (b *gcBits) bitp(n uintptr) (bytep *uint8, mask uint8) {
- return b.bytep(n / 8), 1 << (n % 8)
-}
-
-const gcBitsChunkBytes = uintptr(64 << 10)
-const gcBitsHeaderBytes = unsafe.Sizeof(gcBitsHeader{})
-
-type gcBitsHeader struct {
- free uintptr // free is the index into bits of the next free byte.
- next uintptr // *gcBits triggers recursive type bug. (issue 14620)
-}
-
-type gcBitsArena struct {
- _ sys.NotInHeap
- // gcBitsHeader // side step recursive type bug (issue 14620) by including fields by hand.
- free uintptr // free is the index into bits of the next free byte; read/write atomically
- next *gcBitsArena
- bits [gcBitsChunkBytes - gcBitsHeaderBytes]gcBits
-}
-
-var gcBitsArenas struct {
- lock mutex
- free *gcBitsArena
- next *gcBitsArena // Read atomically. Write atomically under lock.
- current *gcBitsArena
- previous *gcBitsArena
-}
-
-// tryAlloc allocates from b or returns nil if b does not have enough room.
-// This is safe to call concurrently.
-func (b *gcBitsArena) tryAlloc(bytes uintptr) *gcBits {
- if b == nil || atomic.Loaduintptr(&b.free)+bytes > uintptr(len(b.bits)) {
- return nil
- }
- // Try to allocate from this block.
- end := atomic.Xadduintptr(&b.free, bytes)
- if end > uintptr(len(b.bits)) {
- return nil
- }
- // There was enough room.
- start := end - bytes
- return &b.bits[start]
-}
-
-// newMarkBits returns a pointer to 8 byte aligned bytes
-// to be used for a span's mark bits.
-func newMarkBits(nelems uintptr) *gcBits {
- blocksNeeded := uintptr((nelems + 63) / 64)
- bytesNeeded := blocksNeeded * 8
-
- // Try directly allocating from the current head arena.
- head := (*gcBitsArena)(atomic.Loadp(unsafe.Pointer(&gcBitsArenas.next)))
- if p := head.tryAlloc(bytesNeeded); p != nil {
- return p
- }
-
- // There's not enough room in the head arena. We may need to
- // allocate a new arena.
- lock(&gcBitsArenas.lock)
- // Try the head arena again, since it may have changed. Now
- // that we hold the lock, the list head can't change, but its
- // free position still can.
- if p := gcBitsArenas.next.tryAlloc(bytesNeeded); p != nil {
- unlock(&gcBitsArenas.lock)
- return p
- }
-
- // Allocate a new arena. This may temporarily drop the lock.
- fresh := newArenaMayUnlock()
- // If newArenaMayUnlock dropped the lock, another thread may
- // have put a fresh arena on the "next" list. Try allocating
- // from next again.
- if p := gcBitsArenas.next.tryAlloc(bytesNeeded); p != nil {
- // Put fresh back on the free list.
- // TODO: Mark it "already zeroed"
- fresh.next = gcBitsArenas.free
- gcBitsArenas.free = fresh
- unlock(&gcBitsArenas.lock)
- return p
- }
-
- // Allocate from the fresh arena. We haven't linked it in yet, so
- // this cannot race and is guaranteed to succeed.
- p := fresh.tryAlloc(bytesNeeded)
- if p == nil {
- throw("markBits overflow")
- }
-
- // Add the fresh arena to the "next" list.
- fresh.next = gcBitsArenas.next
- atomic.StorepNoWB(unsafe.Pointer(&gcBitsArenas.next), unsafe.Pointer(fresh))
-
- unlock(&gcBitsArenas.lock)
- return p
-}
-
-// newAllocBits returns a pointer to 8 byte aligned bytes
-// to be used for this span's alloc bits.
-// newAllocBits is used to provide newly initialized spans
-// allocation bits. For spans not being initialized the
-// mark bits are repurposed as allocation bits when
-// the span is swept.
-func newAllocBits(nelems uintptr) *gcBits {
- return newMarkBits(nelems)
-}
-
-// nextMarkBitArenaEpoch establishes a new epoch for the arenas
-// holding the mark bits. The arenas are named relative to the
-// current GC cycle which is demarcated by the call to finishweep_m.
-//
-// All current spans have been swept.
-// During that sweep each span allocated room for its gcmarkBits in
-// gcBitsArenas.next block. gcBitsArenas.next becomes the gcBitsArenas.current
-// where the GC will mark objects and after each span is swept these bits
-// will be used to allocate objects.
-// gcBitsArenas.current becomes gcBitsArenas.previous where the span's
-// gcAllocBits live until all the spans have been swept during this GC cycle.
-// The span's sweep extinguishes all the references to gcBitsArenas.previous
-// by pointing gcAllocBits into the gcBitsArenas.current.
-// The gcBitsArenas.previous is released to the gcBitsArenas.free list.
-func nextMarkBitArenaEpoch() {
- lock(&gcBitsArenas.lock)
- if gcBitsArenas.previous != nil {
- if gcBitsArenas.free == nil {
- gcBitsArenas.free = gcBitsArenas.previous
- } else {
- // Find end of previous arenas.
- last := gcBitsArenas.previous
- for last = gcBitsArenas.previous; last.next != nil; last = last.next {
- }
- last.next = gcBitsArenas.free
- gcBitsArenas.free = gcBitsArenas.previous
- }
- }
- gcBitsArenas.previous = gcBitsArenas.current
- gcBitsArenas.current = gcBitsArenas.next
- atomic.StorepNoWB(unsafe.Pointer(&gcBitsArenas.next), nil) // newMarkBits calls newArena when needed
- unlock(&gcBitsArenas.lock)
-}
-
-// newArenaMayUnlock allocates and zeroes a gcBits arena.
-// The caller must hold gcBitsArena.lock. This may temporarily release it.
-func newArenaMayUnlock() *gcBitsArena {
- var result *gcBitsArena
- if gcBitsArenas.free == nil {
- unlock(&gcBitsArenas.lock)
- result = (*gcBitsArena)(sysAlloc(gcBitsChunkBytes, &memstats.gcMiscSys))
- if result == nil {
- throw("runtime: cannot allocate memory")
- }
- lock(&gcBitsArenas.lock)
- } else {
- result = gcBitsArenas.free
- gcBitsArenas.free = gcBitsArenas.free.next
- memclrNoHeapPointers(unsafe.Pointer(result), gcBitsChunkBytes)
- }
- result.next = nil
- // If result.bits is not 8 byte aligned adjust index so
- // that &result.bits[result.free] is 8 byte aligned.
- if uintptr(unsafe.Offsetof(gcBitsArena{}.bits))&7 == 0 {
- result.free = 0
- } else {
- result.free = 8 - (uintptr(unsafe.Pointer(&result.bits[0])) & 7)
- }
- return result
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mpagealloc.go b/contrib/go/_std_1.20/src/runtime/mpagealloc.go
deleted file mode 100644
index 35b2a019a3..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mpagealloc.go
+++ /dev/null
@@ -1,1002 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Page allocator.
-//
-// The page allocator manages mapped pages (defined by pageSize, NOT
-// physPageSize) for allocation and re-use. It is embedded into mheap.
-//
-// Pages are managed using a bitmap that is sharded into chunks.
-// In the bitmap, 1 means in-use, and 0 means free. The bitmap spans the
-// process's address space. Chunks are managed in a sparse-array-style structure
-// similar to mheap.arenas, since the bitmap may be large on some systems.
-//
-// The bitmap is efficiently searched by using a radix tree in combination
-// with fast bit-wise intrinsics. Allocation is performed using an address-ordered
-// first-fit approach.
-//
-// Each entry in the radix tree is a summary that describes three properties of
-// a particular region of the address space: the number of contiguous free pages
-// at the start and end of the region it represents, and the maximum number of
-// contiguous free pages found anywhere in that region.
-//
-// Each level of the radix tree is stored as one contiguous array, which represents
-// a different granularity of subdivision of the processes' address space. Thus, this
-// radix tree is actually implicit in these large arrays, as opposed to having explicit
-// dynamically-allocated pointer-based node structures. Naturally, these arrays may be
-// quite large for system with large address spaces, so in these cases they are mapped
-// into memory as needed. The leaf summaries of the tree correspond to a bitmap chunk.
-//
-// The root level (referred to as L0 and index 0 in pageAlloc.summary) has each
-// summary represent the largest section of address space (16 GiB on 64-bit systems),
-// with each subsequent level representing successively smaller subsections until we
-// reach the finest granularity at the leaves, a chunk.
-//
-// More specifically, each summary in each level (except for leaf summaries)
-// represents some number of entries in the following level. For example, each
-// summary in the root level may represent a 16 GiB region of address space,
-// and in the next level there could be 8 corresponding entries which represent 2
-// GiB subsections of that 16 GiB region, each of which could correspond to 8
-// entries in the next level which each represent 256 MiB regions, and so on.
-//
-// Thus, this design only scales to heaps so large, but can always be extended to
-// larger heaps by simply adding levels to the radix tree, which mostly costs
-// additional virtual address space. The choice of managing large arrays also means
-// that a large amount of virtual address space may be reserved by the runtime.
-
-package runtime
-
-import (
- "unsafe"
-)
-
-const (
- // The size of a bitmap chunk, i.e. the amount of bits (that is, pages) to consider
- // in the bitmap at once.
- pallocChunkPages = 1 << logPallocChunkPages
- pallocChunkBytes = pallocChunkPages * pageSize
- logPallocChunkPages = 9
- logPallocChunkBytes = logPallocChunkPages + pageShift
-
- // The number of radix bits for each level.
- //
- // The value of 3 is chosen such that the block of summaries we need to scan at
- // each level fits in 64 bytes (2^3 summaries * 8 bytes per summary), which is
- // close to the L1 cache line width on many systems. Also, a value of 3 fits 4 tree
- // levels perfectly into the 21-bit pallocBits summary field at the root level.
- //
- // The following equation explains how each of the constants relate:
- // summaryL0Bits + (summaryLevels-1)*summaryLevelBits + logPallocChunkBytes = heapAddrBits
- //
- // summaryLevels is an architecture-dependent value defined in mpagealloc_*.go.
- summaryLevelBits = 3
- summaryL0Bits = heapAddrBits - logPallocChunkBytes - (summaryLevels-1)*summaryLevelBits
-
- // pallocChunksL2Bits is the number of bits of the chunk index number
- // covered by the second level of the chunks map.
- //
- // See (*pageAlloc).chunks for more details. Update the documentation
- // there should this change.
- pallocChunksL2Bits = heapAddrBits - logPallocChunkBytes - pallocChunksL1Bits
- pallocChunksL1Shift = pallocChunksL2Bits
-)
-
-// maxSearchAddr returns the maximum searchAddr value, which indicates
-// that the heap has no free space.
-//
-// This function exists just to make it clear that this is the maximum address
-// for the page allocator's search space. See maxOffAddr for details.
-//
-// It's a function (rather than a variable) because it needs to be
-// usable before package runtime's dynamic initialization is complete.
-// See #51913 for details.
-func maxSearchAddr() offAddr { return maxOffAddr }
-
-// Global chunk index.
-//
-// Represents an index into the leaf level of the radix tree.
-// Similar to arenaIndex, except instead of arenas, it divides the address
-// space into chunks.
-type chunkIdx uint
-
-// chunkIndex returns the global index of the palloc chunk containing the
-// pointer p.
-func chunkIndex(p uintptr) chunkIdx {
- return chunkIdx((p - arenaBaseOffset) / pallocChunkBytes)
-}
-
-// chunkBase returns the base address of the palloc chunk at index ci.
-func chunkBase(ci chunkIdx) uintptr {
- return uintptr(ci)*pallocChunkBytes + arenaBaseOffset
-}
-
-// chunkPageIndex computes the index of the page that contains p,
-// relative to the chunk which contains p.
-func chunkPageIndex(p uintptr) uint {
- return uint(p % pallocChunkBytes / pageSize)
-}
-
-// l1 returns the index into the first level of (*pageAlloc).chunks.
-func (i chunkIdx) l1() uint {
- if pallocChunksL1Bits == 0 {
- // Let the compiler optimize this away if there's no
- // L1 map.
- return 0
- } else {
- return uint(i) >> pallocChunksL1Shift
- }
-}
-
-// l2 returns the index into the second level of (*pageAlloc).chunks.
-func (i chunkIdx) l2() uint {
- if pallocChunksL1Bits == 0 {
- return uint(i)
- } else {
- return uint(i) & (1<<pallocChunksL2Bits - 1)
- }
-}
-
-// offAddrToLevelIndex converts an address in the offset address space
-// to the index into summary[level] containing addr.
-func offAddrToLevelIndex(level int, addr offAddr) int {
- return int((addr.a - arenaBaseOffset) >> levelShift[level])
-}
-
-// levelIndexToOffAddr converts an index into summary[level] into
-// the corresponding address in the offset address space.
-func levelIndexToOffAddr(level, idx int) offAddr {
- return offAddr{(uintptr(idx) << levelShift[level]) + arenaBaseOffset}
-}
-
-// addrsToSummaryRange converts base and limit pointers into a range
-// of entries for the given summary level.
-//
-// The returned range is inclusive on the lower bound and exclusive on
-// the upper bound.
-func addrsToSummaryRange(level int, base, limit uintptr) (lo int, hi int) {
- // This is slightly more nuanced than just a shift for the exclusive
- // upper-bound. Note that the exclusive upper bound may be within a
- // summary at this level, meaning if we just do the obvious computation
- // hi will end up being an inclusive upper bound. Unfortunately, just
- // adding 1 to that is too broad since we might be on the very edge
- // of a summary's max page count boundary for this level
- // (1 << levelLogPages[level]). So, make limit an inclusive upper bound
- // then shift, then add 1, so we get an exclusive upper bound at the end.
- lo = int((base - arenaBaseOffset) >> levelShift[level])
- hi = int(((limit-1)-arenaBaseOffset)>>levelShift[level]) + 1
- return
-}
-
-// blockAlignSummaryRange aligns indices into the given level to that
-// level's block width (1 << levelBits[level]). It assumes lo is inclusive
-// and hi is exclusive, and so aligns them down and up respectively.
-func blockAlignSummaryRange(level int, lo, hi int) (int, int) {
- e := uintptr(1) << levelBits[level]
- return int(alignDown(uintptr(lo), e)), int(alignUp(uintptr(hi), e))
-}
-
-type pageAlloc struct {
- // Radix tree of summaries.
- //
- // Each slice's cap represents the whole memory reservation.
- // Each slice's len reflects the allocator's maximum known
- // mapped heap address for that level.
- //
- // The backing store of each summary level is reserved in init
- // and may or may not be committed in grow (small address spaces
- // may commit all the memory in init).
- //
- // The purpose of keeping len <= cap is to enforce bounds checks
- // on the top end of the slice so that instead of an unknown
- // runtime segmentation fault, we get a much friendlier out-of-bounds
- // error.
- //
- // To iterate over a summary level, use inUse to determine which ranges
- // are currently available. Otherwise one might try to access
- // memory which is only Reserved which may result in a hard fault.
- //
- // We may still get segmentation faults < len since some of that
- // memory may not be committed yet.
- summary [summaryLevels][]pallocSum
-
- // chunks is a slice of bitmap chunks.
- //
- // The total size of chunks is quite large on most 64-bit platforms
- // (O(GiB) or more) if flattened, so rather than making one large mapping
- // (which has problems on some platforms, even when PROT_NONE) we use a
- // two-level sparse array approach similar to the arena index in mheap.
- //
- // To find the chunk containing a memory address `a`, do:
- // chunkOf(chunkIndex(a))
- //
- // Below is a table describing the configuration for chunks for various
- // heapAddrBits supported by the runtime.
- //
- // heapAddrBits | L1 Bits | L2 Bits | L2 Entry Size
- // ------------------------------------------------
- // 32 | 0 | 10 | 128 KiB
- // 33 (iOS) | 0 | 11 | 256 KiB
- // 48 | 13 | 13 | 1 MiB
- //
- // There's no reason to use the L1 part of chunks on 32-bit, the
- // address space is small so the L2 is small. For platforms with a
- // 48-bit address space, we pick the L1 such that the L2 is 1 MiB
- // in size, which is a good balance between low granularity without
- // making the impact on BSS too high (note the L1 is stored directly
- // in pageAlloc).
- //
- // To iterate over the bitmap, use inUse to determine which ranges
- // are currently available. Otherwise one might iterate over unused
- // ranges.
- //
- // Protected by mheapLock.
- //
- // TODO(mknyszek): Consider changing the definition of the bitmap
- // such that 1 means free and 0 means in-use so that summaries and
- // the bitmaps align better on zero-values.
- chunks [1 << pallocChunksL1Bits]*[1 << pallocChunksL2Bits]pallocData
-
- // The address to start an allocation search with. It must never
- // point to any memory that is not contained in inUse, i.e.
- // inUse.contains(searchAddr.addr()) must always be true. The one
- // exception to this rule is that it may take on the value of
- // maxOffAddr to indicate that the heap is exhausted.
- //
- // We guarantee that all valid heap addresses below this value
- // are allocated and not worth searching.
- searchAddr offAddr
-
- // start and end represent the chunk indices
- // which pageAlloc knows about. It assumes
- // chunks in the range [start, end) are
- // currently ready to use.
- start, end chunkIdx
-
- // inUse is a slice of ranges of address space which are
- // known by the page allocator to be currently in-use (passed
- // to grow).
- //
- // This field is currently unused on 32-bit architectures but
- // is harmless to track. We care much more about having a
- // contiguous heap in these cases and take additional measures
- // to ensure that, so in nearly all cases this should have just
- // 1 element.
- //
- // All access is protected by the mheapLock.
- inUse addrRanges
-
- // scav stores the scavenger state.
- scav struct {
- // index is an efficient index of chunks that have pages available to
- // scavenge.
- index scavengeIndex
-
- // released is the amount of memory released this scavenge cycle.
- //
- // Updated atomically.
- released uintptr
- }
-
- // mheap_.lock. This level of indirection makes it possible
- // to test pageAlloc indepedently of the runtime allocator.
- mheapLock *mutex
-
- // sysStat is the runtime memstat to update when new system
- // memory is committed by the pageAlloc for allocation metadata.
- sysStat *sysMemStat
-
- // summaryMappedReady is the number of bytes mapped in the Ready state
- // in the summary structure. Used only for testing currently.
- //
- // Protected by mheapLock.
- summaryMappedReady uintptr
-
- // Whether or not this struct is being used in tests.
- test bool
-}
-
-func (p *pageAlloc) init(mheapLock *mutex, sysStat *sysMemStat) {
- if levelLogPages[0] > logMaxPackedValue {
- // We can't represent 1<<levelLogPages[0] pages, the maximum number
- // of pages we need to represent at the root level, in a summary, which
- // is a big problem. Throw.
- print("runtime: root level max pages = ", 1<<levelLogPages[0], "\n")
- print("runtime: summary max pages = ", maxPackedValue, "\n")
- throw("root level max pages doesn't fit in summary")
- }
- p.sysStat = sysStat
-
- // Initialize p.inUse.
- p.inUse.init(sysStat)
-
- // System-dependent initialization.
- p.sysInit()
-
- // Start with the searchAddr in a state indicating there's no free memory.
- p.searchAddr = maxSearchAddr()
-
- // Set the mheapLock.
- p.mheapLock = mheapLock
-}
-
-// tryChunkOf returns the bitmap data for the given chunk.
-//
-// Returns nil if the chunk data has not been mapped.
-func (p *pageAlloc) tryChunkOf(ci chunkIdx) *pallocData {
- l2 := p.chunks[ci.l1()]
- if l2 == nil {
- return nil
- }
- return &l2[ci.l2()]
-}
-
-// chunkOf returns the chunk at the given chunk index.
-//
-// The chunk index must be valid or this method may throw.
-func (p *pageAlloc) chunkOf(ci chunkIdx) *pallocData {
- return &p.chunks[ci.l1()][ci.l2()]
-}
-
-// grow sets up the metadata for the address range [base, base+size).
-// It may allocate metadata, in which case *p.sysStat will be updated.
-//
-// p.mheapLock must be held.
-func (p *pageAlloc) grow(base, size uintptr) {
- assertLockHeld(p.mheapLock)
-
- // Round up to chunks, since we can't deal with increments smaller
- // than chunks. Also, sysGrow expects aligned values.
- limit := alignUp(base+size, pallocChunkBytes)
- base = alignDown(base, pallocChunkBytes)
-
- // Grow the summary levels in a system-dependent manner.
- // We just update a bunch of additional metadata here.
- p.sysGrow(base, limit)
-
- // Update p.start and p.end.
- // If no growth happened yet, start == 0. This is generally
- // safe since the zero page is unmapped.
- firstGrowth := p.start == 0
- start, end := chunkIndex(base), chunkIndex(limit)
- if firstGrowth || start < p.start {
- p.start = start
- }
- if end > p.end {
- p.end = end
- }
- // Note that [base, limit) will never overlap with any existing
- // range inUse because grow only ever adds never-used memory
- // regions to the page allocator.
- p.inUse.add(makeAddrRange(base, limit))
-
- // A grow operation is a lot like a free operation, so if our
- // chunk ends up below p.searchAddr, update p.searchAddr to the
- // new address, just like in free.
- if b := (offAddr{base}); b.lessThan(p.searchAddr) {
- p.searchAddr = b
- }
-
- // Add entries into chunks, which is sparse, if needed. Then,
- // initialize the bitmap.
- //
- // Newly-grown memory is always considered scavenged.
- // Set all the bits in the scavenged bitmaps high.
- for c := chunkIndex(base); c < chunkIndex(limit); c++ {
- if p.chunks[c.l1()] == nil {
- // Create the necessary l2 entry.
- r := sysAlloc(unsafe.Sizeof(*p.chunks[0]), p.sysStat)
- if r == nil {
- throw("pageAlloc: out of memory")
- }
- // Store the new chunk block but avoid a write barrier.
- // grow is used in call chains that disallow write barriers.
- *(*uintptr)(unsafe.Pointer(&p.chunks[c.l1()])) = uintptr(r)
- }
- p.chunkOf(c).scavenged.setRange(0, pallocChunkPages)
- }
-
- // Update summaries accordingly. The grow acts like a free, so
- // we need to ensure this newly-free memory is visible in the
- // summaries.
- p.update(base, size/pageSize, true, false)
-}
-
-// update updates heap metadata. It must be called each time the bitmap
-// is updated.
-//
-// If contig is true, update does some optimizations assuming that there was
-// a contiguous allocation or free between addr and addr+npages. alloc indicates
-// whether the operation performed was an allocation or a free.
-//
-// p.mheapLock must be held.
-func (p *pageAlloc) update(base, npages uintptr, contig, alloc bool) {
- assertLockHeld(p.mheapLock)
-
- // base, limit, start, and end are inclusive.
- limit := base + npages*pageSize - 1
- sc, ec := chunkIndex(base), chunkIndex(limit)
-
- // Handle updating the lowest level first.
- if sc == ec {
- // Fast path: the allocation doesn't span more than one chunk,
- // so update this one and if the summary didn't change, return.
- x := p.summary[len(p.summary)-1][sc]
- y := p.chunkOf(sc).summarize()
- if x == y {
- return
- }
- p.summary[len(p.summary)-1][sc] = y
- } else if contig {
- // Slow contiguous path: the allocation spans more than one chunk
- // and at least one summary is guaranteed to change.
- summary := p.summary[len(p.summary)-1]
-
- // Update the summary for chunk sc.
- summary[sc] = p.chunkOf(sc).summarize()
-
- // Update the summaries for chunks in between, which are
- // either totally allocated or freed.
- whole := p.summary[len(p.summary)-1][sc+1 : ec]
- if alloc {
- // Should optimize into a memclr.
- for i := range whole {
- whole[i] = 0
- }
- } else {
- for i := range whole {
- whole[i] = freeChunkSum
- }
- }
-
- // Update the summary for chunk ec.
- summary[ec] = p.chunkOf(ec).summarize()
- } else {
- // Slow general path: the allocation spans more than one chunk
- // and at least one summary is guaranteed to change.
- //
- // We can't assume a contiguous allocation happened, so walk over
- // every chunk in the range and manually recompute the summary.
- summary := p.summary[len(p.summary)-1]
- for c := sc; c <= ec; c++ {
- summary[c] = p.chunkOf(c).summarize()
- }
- }
-
- // Walk up the radix tree and update the summaries appropriately.
- changed := true
- for l := len(p.summary) - 2; l >= 0 && changed; l-- {
- // Update summaries at level l from summaries at level l+1.
- changed = false
-
- // "Constants" for the previous level which we
- // need to compute the summary from that level.
- logEntriesPerBlock := levelBits[l+1]
- logMaxPages := levelLogPages[l+1]
-
- // lo and hi describe all the parts of the level we need to look at.
- lo, hi := addrsToSummaryRange(l, base, limit+1)
-
- // Iterate over each block, updating the corresponding summary in the less-granular level.
- for i := lo; i < hi; i++ {
- children := p.summary[l+1][i<<logEntriesPerBlock : (i+1)<<logEntriesPerBlock]
- sum := mergeSummaries(children, logMaxPages)
- old := p.summary[l][i]
- if old != sum {
- changed = true
- p.summary[l][i] = sum
- }
- }
- }
-}
-
-// allocRange marks the range of memory [base, base+npages*pageSize) as
-// allocated. It also updates the summaries to reflect the newly-updated
-// bitmap.
-//
-// Returns the amount of scavenged memory in bytes present in the
-// allocated range.
-//
-// p.mheapLock must be held.
-func (p *pageAlloc) allocRange(base, npages uintptr) uintptr {
- assertLockHeld(p.mheapLock)
-
- limit := base + npages*pageSize - 1
- sc, ec := chunkIndex(base), chunkIndex(limit)
- si, ei := chunkPageIndex(base), chunkPageIndex(limit)
-
- scav := uint(0)
- if sc == ec {
- // The range doesn't cross any chunk boundaries.
- chunk := p.chunkOf(sc)
- scav += chunk.scavenged.popcntRange(si, ei+1-si)
- chunk.allocRange(si, ei+1-si)
- } else {
- // The range crosses at least one chunk boundary.
- chunk := p.chunkOf(sc)
- scav += chunk.scavenged.popcntRange(si, pallocChunkPages-si)
- chunk.allocRange(si, pallocChunkPages-si)
- for c := sc + 1; c < ec; c++ {
- chunk := p.chunkOf(c)
- scav += chunk.scavenged.popcntRange(0, pallocChunkPages)
- chunk.allocAll()
- }
- chunk = p.chunkOf(ec)
- scav += chunk.scavenged.popcntRange(0, ei+1)
- chunk.allocRange(0, ei+1)
- }
- p.update(base, npages, true, true)
- return uintptr(scav) * pageSize
-}
-
-// findMappedAddr returns the smallest mapped offAddr that is
-// >= addr. That is, if addr refers to mapped memory, then it is
-// returned. If addr is higher than any mapped region, then
-// it returns maxOffAddr.
-//
-// p.mheapLock must be held.
-func (p *pageAlloc) findMappedAddr(addr offAddr) offAddr {
- assertLockHeld(p.mheapLock)
-
- // If we're not in a test, validate first by checking mheap_.arenas.
- // This is a fast path which is only safe to use outside of testing.
- ai := arenaIndex(addr.addr())
- if p.test || mheap_.arenas[ai.l1()] == nil || mheap_.arenas[ai.l1()][ai.l2()] == nil {
- vAddr, ok := p.inUse.findAddrGreaterEqual(addr.addr())
- if ok {
- return offAddr{vAddr}
- } else {
- // The candidate search address is greater than any
- // known address, which means we definitely have no
- // free memory left.
- return maxOffAddr
- }
- }
- return addr
-}
-
-// find searches for the first (address-ordered) contiguous free region of
-// npages in size and returns a base address for that region.
-//
-// It uses p.searchAddr to prune its search and assumes that no palloc chunks
-// below chunkIndex(p.searchAddr) contain any free memory at all.
-//
-// find also computes and returns a candidate p.searchAddr, which may or
-// may not prune more of the address space than p.searchAddr already does.
-// This candidate is always a valid p.searchAddr.
-//
-// find represents the slow path and the full radix tree search.
-//
-// Returns a base address of 0 on failure, in which case the candidate
-// searchAddr returned is invalid and must be ignored.
-//
-// p.mheapLock must be held.
-func (p *pageAlloc) find(npages uintptr) (uintptr, offAddr) {
- assertLockHeld(p.mheapLock)
-
- // Search algorithm.
- //
- // This algorithm walks each level l of the radix tree from the root level
- // to the leaf level. It iterates over at most 1 << levelBits[l] of entries
- // in a given level in the radix tree, and uses the summary information to
- // find either:
- // 1) That a given subtree contains a large enough contiguous region, at
- // which point it continues iterating on the next level, or
- // 2) That there are enough contiguous boundary-crossing bits to satisfy
- // the allocation, at which point it knows exactly where to start
- // allocating from.
- //
- // i tracks the index into the current level l's structure for the
- // contiguous 1 << levelBits[l] entries we're actually interested in.
- //
- // NOTE: Technically this search could allocate a region which crosses
- // the arenaBaseOffset boundary, which when arenaBaseOffset != 0, is
- // a discontinuity. However, the only way this could happen is if the
- // page at the zero address is mapped, and this is impossible on
- // every system we support where arenaBaseOffset != 0. So, the
- // discontinuity is already encoded in the fact that the OS will never
- // map the zero page for us, and this function doesn't try to handle
- // this case in any way.
-
- // i is the beginning of the block of entries we're searching at the
- // current level.
- i := 0
-
- // firstFree is the region of address space that we are certain to
- // find the first free page in the heap. base and bound are the inclusive
- // bounds of this window, and both are addresses in the linearized, contiguous
- // view of the address space (with arenaBaseOffset pre-added). At each level,
- // this window is narrowed as we find the memory region containing the
- // first free page of memory. To begin with, the range reflects the
- // full process address space.
- //
- // firstFree is updated by calling foundFree each time free space in the
- // heap is discovered.
- //
- // At the end of the search, base.addr() is the best new
- // searchAddr we could deduce in this search.
- firstFree := struct {
- base, bound offAddr
- }{
- base: minOffAddr,
- bound: maxOffAddr,
- }
- // foundFree takes the given address range [addr, addr+size) and
- // updates firstFree if it is a narrower range. The input range must
- // either be fully contained within firstFree or not overlap with it
- // at all.
- //
- // This way, we'll record the first summary we find with any free
- // pages on the root level and narrow that down if we descend into
- // that summary. But as soon as we need to iterate beyond that summary
- // in a level to find a large enough range, we'll stop narrowing.
- foundFree := func(addr offAddr, size uintptr) {
- if firstFree.base.lessEqual(addr) && addr.add(size-1).lessEqual(firstFree.bound) {
- // This range fits within the current firstFree window, so narrow
- // down the firstFree window to the base and bound of this range.
- firstFree.base = addr
- firstFree.bound = addr.add(size - 1)
- } else if !(addr.add(size-1).lessThan(firstFree.base) || firstFree.bound.lessThan(addr)) {
- // This range only partially overlaps with the firstFree range,
- // so throw.
- print("runtime: addr = ", hex(addr.addr()), ", size = ", size, "\n")
- print("runtime: base = ", hex(firstFree.base.addr()), ", bound = ", hex(firstFree.bound.addr()), "\n")
- throw("range partially overlaps")
- }
- }
-
- // lastSum is the summary which we saw on the previous level that made us
- // move on to the next level. Used to print additional information in the
- // case of a catastrophic failure.
- // lastSumIdx is that summary's index in the previous level.
- lastSum := packPallocSum(0, 0, 0)
- lastSumIdx := -1
-
-nextLevel:
- for l := 0; l < len(p.summary); l++ {
- // For the root level, entriesPerBlock is the whole level.
- entriesPerBlock := 1 << levelBits[l]
- logMaxPages := levelLogPages[l]
-
- // We've moved into a new level, so let's update i to our new
- // starting index. This is a no-op for level 0.
- i <<= levelBits[l]
-
- // Slice out the block of entries we care about.
- entries := p.summary[l][i : i+entriesPerBlock]
-
- // Determine j0, the first index we should start iterating from.
- // The searchAddr may help us eliminate iterations if we followed the
- // searchAddr on the previous level or we're on the root level, in which
- // case the searchAddr should be the same as i after levelShift.
- j0 := 0
- if searchIdx := offAddrToLevelIndex(l, p.searchAddr); searchIdx&^(entriesPerBlock-1) == i {
- j0 = searchIdx & (entriesPerBlock - 1)
- }
-
- // Run over the level entries looking for
- // a contiguous run of at least npages either
- // within an entry or across entries.
- //
- // base contains the page index (relative to
- // the first entry's first page) of the currently
- // considered run of consecutive pages.
- //
- // size contains the size of the currently considered
- // run of consecutive pages.
- var base, size uint
- for j := j0; j < len(entries); j++ {
- sum := entries[j]
- if sum == 0 {
- // A full entry means we broke any streak and
- // that we should skip it altogether.
- size = 0
- continue
- }
-
- // We've encountered a non-zero summary which means
- // free memory, so update firstFree.
- foundFree(levelIndexToOffAddr(l, i+j), (uintptr(1)<<logMaxPages)*pageSize)
-
- s := sum.start()
- if size+s >= uint(npages) {
- // If size == 0 we don't have a run yet,
- // which means base isn't valid. So, set
- // base to the first page in this block.
- if size == 0 {
- base = uint(j) << logMaxPages
- }
- // We hit npages; we're done!
- size += s
- break
- }
- if sum.max() >= uint(npages) {
- // The entry itself contains npages contiguous
- // free pages, so continue on the next level
- // to find that run.
- i += j
- lastSumIdx = i
- lastSum = sum
- continue nextLevel
- }
- if size == 0 || s < 1<<logMaxPages {
- // We either don't have a current run started, or this entry
- // isn't totally free (meaning we can't continue the current
- // one), so try to begin a new run by setting size and base
- // based on sum.end.
- size = sum.end()
- base = uint(j+1)<<logMaxPages - size
- continue
- }
- // The entry is completely free, so continue the run.
- size += 1 << logMaxPages
- }
- if size >= uint(npages) {
- // We found a sufficiently large run of free pages straddling
- // some boundary, so compute the address and return it.
- addr := levelIndexToOffAddr(l, i).add(uintptr(base) * pageSize).addr()
- return addr, p.findMappedAddr(firstFree.base)
- }
- if l == 0 {
- // We're at level zero, so that means we've exhausted our search.
- return 0, maxSearchAddr()
- }
-
- // We're not at level zero, and we exhausted the level we were looking in.
- // This means that either our calculations were wrong or the level above
- // lied to us. In either case, dump some useful state and throw.
- print("runtime: summary[", l-1, "][", lastSumIdx, "] = ", lastSum.start(), ", ", lastSum.max(), ", ", lastSum.end(), "\n")
- print("runtime: level = ", l, ", npages = ", npages, ", j0 = ", j0, "\n")
- print("runtime: p.searchAddr = ", hex(p.searchAddr.addr()), ", i = ", i, "\n")
- print("runtime: levelShift[level] = ", levelShift[l], ", levelBits[level] = ", levelBits[l], "\n")
- for j := 0; j < len(entries); j++ {
- sum := entries[j]
- print("runtime: summary[", l, "][", i+j, "] = (", sum.start(), ", ", sum.max(), ", ", sum.end(), ")\n")
- }
- throw("bad summary data")
- }
-
- // Since we've gotten to this point, that means we haven't found a
- // sufficiently-sized free region straddling some boundary (chunk or larger).
- // This means the last summary we inspected must have had a large enough "max"
- // value, so look inside the chunk to find a suitable run.
- //
- // After iterating over all levels, i must contain a chunk index which
- // is what the final level represents.
- ci := chunkIdx(i)
- j, searchIdx := p.chunkOf(ci).find(npages, 0)
- if j == ^uint(0) {
- // We couldn't find any space in this chunk despite the summaries telling
- // us it should be there. There's likely a bug, so dump some state and throw.
- sum := p.summary[len(p.summary)-1][i]
- print("runtime: summary[", len(p.summary)-1, "][", i, "] = (", sum.start(), ", ", sum.max(), ", ", sum.end(), ")\n")
- print("runtime: npages = ", npages, "\n")
- throw("bad summary data")
- }
-
- // Compute the address at which the free space starts.
- addr := chunkBase(ci) + uintptr(j)*pageSize
-
- // Since we actually searched the chunk, we may have
- // found an even narrower free window.
- searchAddr := chunkBase(ci) + uintptr(searchIdx)*pageSize
- foundFree(offAddr{searchAddr}, chunkBase(ci+1)-searchAddr)
- return addr, p.findMappedAddr(firstFree.base)
-}
-
-// alloc allocates npages worth of memory from the page heap, returning the base
-// address for the allocation and the amount of scavenged memory in bytes
-// contained in the region [base address, base address + npages*pageSize).
-//
-// Returns a 0 base address on failure, in which case other returned values
-// should be ignored.
-//
-// p.mheapLock must be held.
-//
-// Must run on the system stack because p.mheapLock must be held.
-//
-//go:systemstack
-func (p *pageAlloc) alloc(npages uintptr) (addr uintptr, scav uintptr) {
- assertLockHeld(p.mheapLock)
-
- // If the searchAddr refers to a region which has a higher address than
- // any known chunk, then we know we're out of memory.
- if chunkIndex(p.searchAddr.addr()) >= p.end {
- return 0, 0
- }
-
- // If npages has a chance of fitting in the chunk where the searchAddr is,
- // search it directly.
- searchAddr := minOffAddr
- if pallocChunkPages-chunkPageIndex(p.searchAddr.addr()) >= uint(npages) {
- // npages is guaranteed to be no greater than pallocChunkPages here.
- i := chunkIndex(p.searchAddr.addr())
- if max := p.summary[len(p.summary)-1][i].max(); max >= uint(npages) {
- j, searchIdx := p.chunkOf(i).find(npages, chunkPageIndex(p.searchAddr.addr()))
- if j == ^uint(0) {
- print("runtime: max = ", max, ", npages = ", npages, "\n")
- print("runtime: searchIdx = ", chunkPageIndex(p.searchAddr.addr()), ", p.searchAddr = ", hex(p.searchAddr.addr()), "\n")
- throw("bad summary data")
- }
- addr = chunkBase(i) + uintptr(j)*pageSize
- searchAddr = offAddr{chunkBase(i) + uintptr(searchIdx)*pageSize}
- goto Found
- }
- }
- // We failed to use a searchAddr for one reason or another, so try
- // the slow path.
- addr, searchAddr = p.find(npages)
- if addr == 0 {
- if npages == 1 {
- // We failed to find a single free page, the smallest unit
- // of allocation. This means we know the heap is completely
- // exhausted. Otherwise, the heap still might have free
- // space in it, just not enough contiguous space to
- // accommodate npages.
- p.searchAddr = maxSearchAddr()
- }
- return 0, 0
- }
-Found:
- // Go ahead and actually mark the bits now that we have an address.
- scav = p.allocRange(addr, npages)
-
- // If we found a higher searchAddr, we know that all the
- // heap memory before that searchAddr in an offset address space is
- // allocated, so bump p.searchAddr up to the new one.
- if p.searchAddr.lessThan(searchAddr) {
- p.searchAddr = searchAddr
- }
- return addr, scav
-}
-
-// free returns npages worth of memory starting at base back to the page heap.
-//
-// p.mheapLock must be held.
-//
-// Must run on the system stack because p.mheapLock must be held.
-//
-//go:systemstack
-func (p *pageAlloc) free(base, npages uintptr, scavenged bool) {
- assertLockHeld(p.mheapLock)
-
- // If we're freeing pages below the p.searchAddr, update searchAddr.
- if b := (offAddr{base}); b.lessThan(p.searchAddr) {
- p.searchAddr = b
- }
- limit := base + npages*pageSize - 1
- if !scavenged {
- p.scav.index.mark(base, limit+1)
- }
- if npages == 1 {
- // Fast path: we're clearing a single bit, and we know exactly
- // where it is, so mark it directly.
- i := chunkIndex(base)
- p.chunkOf(i).free1(chunkPageIndex(base))
- } else {
- // Slow path: we're clearing more bits so we may need to iterate.
- sc, ec := chunkIndex(base), chunkIndex(limit)
- si, ei := chunkPageIndex(base), chunkPageIndex(limit)
-
- if sc == ec {
- // The range doesn't cross any chunk boundaries.
- p.chunkOf(sc).free(si, ei+1-si)
- } else {
- // The range crosses at least one chunk boundary.
- p.chunkOf(sc).free(si, pallocChunkPages-si)
- for c := sc + 1; c < ec; c++ {
- p.chunkOf(c).freeAll()
- }
- p.chunkOf(ec).free(0, ei+1)
- }
- }
- p.update(base, npages, true, false)
-}
-
-const (
- pallocSumBytes = unsafe.Sizeof(pallocSum(0))
-
- // maxPackedValue is the maximum value that any of the three fields in
- // the pallocSum may take on.
- maxPackedValue = 1 << logMaxPackedValue
- logMaxPackedValue = logPallocChunkPages + (summaryLevels-1)*summaryLevelBits
-
- freeChunkSum = pallocSum(uint64(pallocChunkPages) |
- uint64(pallocChunkPages<<logMaxPackedValue) |
- uint64(pallocChunkPages<<(2*logMaxPackedValue)))
-)
-
-// pallocSum is a packed summary type which packs three numbers: start, max,
-// and end into a single 8-byte value. Each of these values are a summary of
-// a bitmap and are thus counts, each of which may have a maximum value of
-// 2^21 - 1, or all three may be equal to 2^21. The latter case is represented
-// by just setting the 64th bit.
-type pallocSum uint64
-
-// packPallocSum takes a start, max, and end value and produces a pallocSum.
-func packPallocSum(start, max, end uint) pallocSum {
- if max == maxPackedValue {
- return pallocSum(uint64(1 << 63))
- }
- return pallocSum((uint64(start) & (maxPackedValue - 1)) |
- ((uint64(max) & (maxPackedValue - 1)) << logMaxPackedValue) |
- ((uint64(end) & (maxPackedValue - 1)) << (2 * logMaxPackedValue)))
-}
-
-// start extracts the start value from a packed sum.
-func (p pallocSum) start() uint {
- if uint64(p)&uint64(1<<63) != 0 {
- return maxPackedValue
- }
- return uint(uint64(p) & (maxPackedValue - 1))
-}
-
-// max extracts the max value from a packed sum.
-func (p pallocSum) max() uint {
- if uint64(p)&uint64(1<<63) != 0 {
- return maxPackedValue
- }
- return uint((uint64(p) >> logMaxPackedValue) & (maxPackedValue - 1))
-}
-
-// end extracts the end value from a packed sum.
-func (p pallocSum) end() uint {
- if uint64(p)&uint64(1<<63) != 0 {
- return maxPackedValue
- }
- return uint((uint64(p) >> (2 * logMaxPackedValue)) & (maxPackedValue - 1))
-}
-
-// unpack unpacks all three values from the summary.
-func (p pallocSum) unpack() (uint, uint, uint) {
- if uint64(p)&uint64(1<<63) != 0 {
- return maxPackedValue, maxPackedValue, maxPackedValue
- }
- return uint(uint64(p) & (maxPackedValue - 1)),
- uint((uint64(p) >> logMaxPackedValue) & (maxPackedValue - 1)),
- uint((uint64(p) >> (2 * logMaxPackedValue)) & (maxPackedValue - 1))
-}
-
-// mergeSummaries merges consecutive summaries which may each represent at
-// most 1 << logMaxPagesPerSum pages each together into one.
-func mergeSummaries(sums []pallocSum, logMaxPagesPerSum uint) pallocSum {
- // Merge the summaries in sums into one.
- //
- // We do this by keeping a running summary representing the merged
- // summaries of sums[:i] in start, max, and end.
- start, max, end := sums[0].unpack()
- for i := 1; i < len(sums); i++ {
- // Merge in sums[i].
- si, mi, ei := sums[i].unpack()
-
- // Merge in sums[i].start only if the running summary is
- // completely free, otherwise this summary's start
- // plays no role in the combined sum.
- if start == uint(i)<<logMaxPagesPerSum {
- start += si
- }
-
- // Recompute the max value of the running sum by looking
- // across the boundary between the running sum and sums[i]
- // and at the max sums[i], taking the greatest of those two
- // and the max of the running sum.
- if end+si > max {
- max = end + si
- }
- if mi > max {
- max = mi
- }
-
- // Merge in end by checking if this new summary is totally
- // free. If it is, then we want to extend the running sum's
- // end by the new summary. If not, then we have some alloc'd
- // pages in there and we just want to take the end value in
- // sums[i].
- if ei == 1<<logMaxPagesPerSum {
- end += 1 << logMaxPagesPerSum
- } else {
- end = ei
- }
- }
- return packPallocSum(start, max, end)
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mpagealloc_64bit.go b/contrib/go/_std_1.20/src/runtime/mpagealloc_64bit.go
deleted file mode 100644
index 371c1fb31c..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mpagealloc_64bit.go
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x
-
-package runtime
-
-import (
- "runtime/internal/atomic"
- "unsafe"
-)
-
-const (
- // The number of levels in the radix tree.
- summaryLevels = 5
-
- // Constants for testing.
- pageAlloc32Bit = 0
- pageAlloc64Bit = 1
-
- // Number of bits needed to represent all indices into the L1 of the
- // chunks map.
- //
- // See (*pageAlloc).chunks for more details. Update the documentation
- // there should this number change.
- pallocChunksL1Bits = 13
-)
-
-// levelBits is the number of bits in the radix for a given level in the super summary
-// structure.
-//
-// The sum of all the entries of levelBits should equal heapAddrBits.
-var levelBits = [summaryLevels]uint{
- summaryL0Bits,
- summaryLevelBits,
- summaryLevelBits,
- summaryLevelBits,
- summaryLevelBits,
-}
-
-// levelShift is the number of bits to shift to acquire the radix for a given level
-// in the super summary structure.
-//
-// With levelShift, one can compute the index of the summary at level l related to a
-// pointer p by doing:
-//
-// p >> levelShift[l]
-var levelShift = [summaryLevels]uint{
- heapAddrBits - summaryL0Bits,
- heapAddrBits - summaryL0Bits - 1*summaryLevelBits,
- heapAddrBits - summaryL0Bits - 2*summaryLevelBits,
- heapAddrBits - summaryL0Bits - 3*summaryLevelBits,
- heapAddrBits - summaryL0Bits - 4*summaryLevelBits,
-}
-
-// levelLogPages is log2 the maximum number of runtime pages in the address space
-// a summary in the given level represents.
-//
-// The leaf level always represents exactly log2 of 1 chunk's worth of pages.
-var levelLogPages = [summaryLevels]uint{
- logPallocChunkPages + 4*summaryLevelBits,
- logPallocChunkPages + 3*summaryLevelBits,
- logPallocChunkPages + 2*summaryLevelBits,
- logPallocChunkPages + 1*summaryLevelBits,
- logPallocChunkPages,
-}
-
-// sysInit performs architecture-dependent initialization of fields
-// in pageAlloc. pageAlloc should be uninitialized except for sysStat
-// if any runtime statistic should be updated.
-func (p *pageAlloc) sysInit() {
- // Reserve memory for each level. This will get mapped in
- // as R/W by setArenas.
- for l, shift := range levelShift {
- entries := 1 << (heapAddrBits - shift)
-
- // Reserve b bytes of memory anywhere in the address space.
- b := alignUp(uintptr(entries)*pallocSumBytes, physPageSize)
- r := sysReserve(nil, b)
- if r == nil {
- throw("failed to reserve page summary memory")
- }
-
- // Put this reservation into a slice.
- sl := notInHeapSlice{(*notInHeap)(r), 0, entries}
- p.summary[l] = *(*[]pallocSum)(unsafe.Pointer(&sl))
- }
-
- // Set up the scavenge index.
- nbytes := uintptr(1<<heapAddrBits) / pallocChunkBytes / 8
- r := sysReserve(nil, nbytes)
- sl := notInHeapSlice{(*notInHeap)(r), int(nbytes), int(nbytes)}
- p.scav.index.chunks = *(*[]atomic.Uint8)(unsafe.Pointer(&sl))
-}
-
-// sysGrow performs architecture-dependent operations on heap
-// growth for the page allocator, such as mapping in new memory
-// for summaries. It also updates the length of the slices in
-// [.summary.
-//
-// base is the base of the newly-added heap memory and limit is
-// the first address past the end of the newly-added heap memory.
-// Both must be aligned to pallocChunkBytes.
-//
-// The caller must update p.start and p.end after calling sysGrow.
-func (p *pageAlloc) sysGrow(base, limit uintptr) {
- if base%pallocChunkBytes != 0 || limit%pallocChunkBytes != 0 {
- print("runtime: base = ", hex(base), ", limit = ", hex(limit), "\n")
- throw("sysGrow bounds not aligned to pallocChunkBytes")
- }
-
- // addrRangeToSummaryRange converts a range of addresses into a range
- // of summary indices which must be mapped to support those addresses
- // in the summary range.
- addrRangeToSummaryRange := func(level int, r addrRange) (int, int) {
- sumIdxBase, sumIdxLimit := addrsToSummaryRange(level, r.base.addr(), r.limit.addr())
- return blockAlignSummaryRange(level, sumIdxBase, sumIdxLimit)
- }
-
- // summaryRangeToSumAddrRange converts a range of indices in any
- // level of p.summary into page-aligned addresses which cover that
- // range of indices.
- summaryRangeToSumAddrRange := func(level, sumIdxBase, sumIdxLimit int) addrRange {
- baseOffset := alignDown(uintptr(sumIdxBase)*pallocSumBytes, physPageSize)
- limitOffset := alignUp(uintptr(sumIdxLimit)*pallocSumBytes, physPageSize)
- base := unsafe.Pointer(&p.summary[level][0])
- return addrRange{
- offAddr{uintptr(add(base, baseOffset))},
- offAddr{uintptr(add(base, limitOffset))},
- }
- }
-
- // addrRangeToSumAddrRange is a convienience function that converts
- // an address range r to the address range of the given summary level
- // that stores the summaries for r.
- addrRangeToSumAddrRange := func(level int, r addrRange) addrRange {
- sumIdxBase, sumIdxLimit := addrRangeToSummaryRange(level, r)
- return summaryRangeToSumAddrRange(level, sumIdxBase, sumIdxLimit)
- }
-
- // Find the first inUse index which is strictly greater than base.
- //
- // Because this function will never be asked remap the same memory
- // twice, this index is effectively the index at which we would insert
- // this new growth, and base will never overlap/be contained within
- // any existing range.
- //
- // This will be used to look at what memory in the summary array is already
- // mapped before and after this new range.
- inUseIndex := p.inUse.findSucc(base)
-
- // Walk up the radix tree and map summaries in as needed.
- for l := range p.summary {
- // Figure out what part of the summary array this new address space needs.
- needIdxBase, needIdxLimit := addrRangeToSummaryRange(l, makeAddrRange(base, limit))
-
- // Update the summary slices with a new upper-bound. This ensures
- // we get tight bounds checks on at least the top bound.
- //
- // We must do this regardless of whether we map new memory.
- if needIdxLimit > len(p.summary[l]) {
- p.summary[l] = p.summary[l][:needIdxLimit]
- }
-
- // Compute the needed address range in the summary array for level l.
- need := summaryRangeToSumAddrRange(l, needIdxBase, needIdxLimit)
-
- // Prune need down to what needs to be newly mapped. Some parts of it may
- // already be mapped by what inUse describes due to page alignment requirements
- // for mapping. prune's invariants are guaranteed by the fact that this
- // function will never be asked to remap the same memory twice.
- if inUseIndex > 0 {
- need = need.subtract(addrRangeToSumAddrRange(l, p.inUse.ranges[inUseIndex-1]))
- }
- if inUseIndex < len(p.inUse.ranges) {
- need = need.subtract(addrRangeToSumAddrRange(l, p.inUse.ranges[inUseIndex]))
- }
- // It's possible that after our pruning above, there's nothing new to map.
- if need.size() == 0 {
- continue
- }
-
- // Map and commit need.
- sysMap(unsafe.Pointer(need.base.addr()), need.size(), p.sysStat)
- sysUsed(unsafe.Pointer(need.base.addr()), need.size(), need.size())
- p.summaryMappedReady += need.size()
- }
-
- // Update the scavenge index.
- p.summaryMappedReady += p.scav.index.grow(base, limit, p.sysStat)
-}
-
-// grow increases the index's backing store in response to a heap growth.
-//
-// Returns the amount of memory added to sysStat.
-func (s *scavengeIndex) grow(base, limit uintptr, sysStat *sysMemStat) uintptr {
- if base%pallocChunkBytes != 0 || limit%pallocChunkBytes != 0 {
- print("runtime: base = ", hex(base), ", limit = ", hex(limit), "\n")
- throw("sysGrow bounds not aligned to pallocChunkBytes")
- }
- // Map and commit the pieces of chunks that we need.
- //
- // We always map the full range of the minimum heap address to the
- // maximum heap address. We don't do this for the summary structure
- // because it's quite large and a discontiguous heap could cause a
- // lot of memory to be used. In this situation, the worst case overhead
- // is in the single-digit MiB if we map the whole thing.
- //
- // The base address of the backing store is always page-aligned,
- // because it comes from the OS, so it's sufficient to align the
- // index.
- haveMin := s.min.Load()
- haveMax := s.max.Load()
- needMin := int32(alignDown(uintptr(chunkIndex(base)/8), physPageSize))
- needMax := int32(alignUp(uintptr((chunkIndex(limit)+7)/8), physPageSize))
- // Extend the range down to what we have, if there's no overlap.
- if needMax < haveMin {
- needMax = haveMin
- }
- if needMin > haveMax {
- needMin = haveMax
- }
- have := makeAddrRange(
- // Avoid a panic from indexing one past the last element.
- uintptr(unsafe.Pointer(&s.chunks[0]))+uintptr(haveMin),
- uintptr(unsafe.Pointer(&s.chunks[0]))+uintptr(haveMax),
- )
- need := makeAddrRange(
- // Avoid a panic from indexing one past the last element.
- uintptr(unsafe.Pointer(&s.chunks[0]))+uintptr(needMin),
- uintptr(unsafe.Pointer(&s.chunks[0]))+uintptr(needMax),
- )
- // Subtract any overlap from rounding. We can't re-map memory because
- // it'll be zeroed.
- need = need.subtract(have)
-
- // If we've got something to map, map it, and update the slice bounds.
- if need.size() != 0 {
- sysMap(unsafe.Pointer(need.base.addr()), need.size(), sysStat)
- sysUsed(unsafe.Pointer(need.base.addr()), need.size(), need.size())
- // Update the indices only after the new memory is valid.
- if haveMin == 0 || needMin < haveMin {
- s.min.Store(needMin)
- }
- if haveMax == 0 || needMax > haveMax {
- s.max.Store(needMax)
- }
- }
- // Update minHeapIdx. Note that even if there's no mapping work to do,
- // we may still have a new, lower minimum heap address.
- minHeapIdx := s.minHeapIdx.Load()
- if baseIdx := int32(chunkIndex(base) / 8); minHeapIdx == 0 || baseIdx < minHeapIdx {
- s.minHeapIdx.Store(baseIdx)
- }
- return need.size()
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mpagecache.go b/contrib/go/_std_1.20/src/runtime/mpagecache.go
deleted file mode 100644
index 5bc9c84408..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mpagecache.go
+++ /dev/null
@@ -1,176 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-import (
- "runtime/internal/sys"
- "unsafe"
-)
-
-const pageCachePages = 8 * unsafe.Sizeof(pageCache{}.cache)
-
-// pageCache represents a per-p cache of pages the allocator can
-// allocate from without a lock. More specifically, it represents
-// a pageCachePages*pageSize chunk of memory with 0 or more free
-// pages in it.
-type pageCache struct {
- base uintptr // base address of the chunk
- cache uint64 // 64-bit bitmap representing free pages (1 means free)
- scav uint64 // 64-bit bitmap representing scavenged pages (1 means scavenged)
-}
-
-// empty reports whether the page cache has no free pages.
-func (c *pageCache) empty() bool {
- return c.cache == 0
-}
-
-// alloc allocates npages from the page cache and is the main entry
-// point for allocation.
-//
-// Returns a base address and the amount of scavenged memory in the
-// allocated region in bytes.
-//
-// Returns a base address of zero on failure, in which case the
-// amount of scavenged memory should be ignored.
-func (c *pageCache) alloc(npages uintptr) (uintptr, uintptr) {
- if c.cache == 0 {
- return 0, 0
- }
- if npages == 1 {
- i := uintptr(sys.TrailingZeros64(c.cache))
- scav := (c.scav >> i) & 1
- c.cache &^= 1 << i // set bit to mark in-use
- c.scav &^= 1 << i // clear bit to mark unscavenged
- return c.base + i*pageSize, uintptr(scav) * pageSize
- }
- return c.allocN(npages)
-}
-
-// allocN is a helper which attempts to allocate npages worth of pages
-// from the cache. It represents the general case for allocating from
-// the page cache.
-//
-// Returns a base address and the amount of scavenged memory in the
-// allocated region in bytes.
-func (c *pageCache) allocN(npages uintptr) (uintptr, uintptr) {
- i := findBitRange64(c.cache, uint(npages))
- if i >= 64 {
- return 0, 0
- }
- mask := ((uint64(1) << npages) - 1) << i
- scav := sys.OnesCount64(c.scav & mask)
- c.cache &^= mask // mark in-use bits
- c.scav &^= mask // clear scavenged bits
- return c.base + uintptr(i*pageSize), uintptr(scav) * pageSize
-}
-
-// flush empties out unallocated free pages in the given cache
-// into s. Then, it clears the cache, such that empty returns
-// true.
-//
-// p.mheapLock must be held.
-//
-// Must run on the system stack because p.mheapLock must be held.
-//
-//go:systemstack
-func (c *pageCache) flush(p *pageAlloc) {
- assertLockHeld(p.mheapLock)
-
- if c.empty() {
- return
- }
- ci := chunkIndex(c.base)
- pi := chunkPageIndex(c.base)
-
- // This method is called very infrequently, so just do the
- // slower, safer thing by iterating over each bit individually.
- for i := uint(0); i < 64; i++ {
- if c.cache&(1<<i) != 0 {
- p.chunkOf(ci).free1(pi + i)
- }
- if c.scav&(1<<i) != 0 {
- p.chunkOf(ci).scavenged.setRange(pi+i, 1)
- }
- }
- // Since this is a lot like a free, we need to make sure
- // we update the searchAddr just like free does.
- if b := (offAddr{c.base}); b.lessThan(p.searchAddr) {
- p.searchAddr = b
- }
- p.update(c.base, pageCachePages, false, false)
- *c = pageCache{}
-}
-
-// allocToCache acquires a pageCachePages-aligned chunk of free pages which
-// may not be contiguous, and returns a pageCache structure which owns the
-// chunk.
-//
-// p.mheapLock must be held.
-//
-// Must run on the system stack because p.mheapLock must be held.
-//
-//go:systemstack
-func (p *pageAlloc) allocToCache() pageCache {
- assertLockHeld(p.mheapLock)
-
- // If the searchAddr refers to a region which has a higher address than
- // any known chunk, then we know we're out of memory.
- if chunkIndex(p.searchAddr.addr()) >= p.end {
- return pageCache{}
- }
- c := pageCache{}
- ci := chunkIndex(p.searchAddr.addr()) // chunk index
- var chunk *pallocData
- if p.summary[len(p.summary)-1][ci] != 0 {
- // Fast path: there's free pages at or near the searchAddr address.
- chunk = p.chunkOf(ci)
- j, _ := chunk.find(1, chunkPageIndex(p.searchAddr.addr()))
- if j == ^uint(0) {
- throw("bad summary data")
- }
- c = pageCache{
- base: chunkBase(ci) + alignDown(uintptr(j), 64)*pageSize,
- cache: ^chunk.pages64(j),
- scav: chunk.scavenged.block64(j),
- }
- } else {
- // Slow path: the searchAddr address had nothing there, so go find
- // the first free page the slow way.
- addr, _ := p.find(1)
- if addr == 0 {
- // We failed to find adequate free space, so mark the searchAddr as OoM
- // and return an empty pageCache.
- p.searchAddr = maxSearchAddr()
- return pageCache{}
- }
- ci := chunkIndex(addr)
- chunk = p.chunkOf(ci)
- c = pageCache{
- base: alignDown(addr, 64*pageSize),
- cache: ^chunk.pages64(chunkPageIndex(addr)),
- scav: chunk.scavenged.block64(chunkPageIndex(addr)),
- }
- }
-
- // Set the page bits as allocated and clear the scavenged bits, but
- // be careful to only set and clear the relevant bits.
- cpi := chunkPageIndex(c.base)
- chunk.allocPages64(cpi, c.cache)
- chunk.scavenged.clearBlock64(cpi, c.cache&c.scav /* free and scavenged */)
-
- // Update as an allocation, but note that it's not contiguous.
- p.update(c.base, pageCachePages, false, true)
-
- // Set the search address to the last page represented by the cache.
- // Since all of the pages in this block are going to the cache, and we
- // searched for the first free page, we can confidently start at the
- // next page.
- //
- // However, p.searchAddr is not allowed to point into unmapped heap memory
- // unless it is maxSearchAddr, so make it the last page as opposed to
- // the page after.
- p.searchAddr = offAddr{c.base + pageSize*(pageCachePages-1)}
- return c
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mpallocbits.go b/contrib/go/_std_1.20/src/runtime/mpallocbits.go
deleted file mode 100644
index f63164becd..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mpallocbits.go
+++ /dev/null
@@ -1,446 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-import (
- "runtime/internal/sys"
-)
-
-// pageBits is a bitmap representing one bit per page in a palloc chunk.
-type pageBits [pallocChunkPages / 64]uint64
-
-// get returns the value of the i'th bit in the bitmap.
-func (b *pageBits) get(i uint) uint {
- return uint((b[i/64] >> (i % 64)) & 1)
-}
-
-// block64 returns the 64-bit aligned block of bits containing the i'th bit.
-func (b *pageBits) block64(i uint) uint64 {
- return b[i/64]
-}
-
-// set sets bit i of pageBits.
-func (b *pageBits) set(i uint) {
- b[i/64] |= 1 << (i % 64)
-}
-
-// setRange sets bits in the range [i, i+n).
-func (b *pageBits) setRange(i, n uint) {
- _ = b[i/64]
- if n == 1 {
- // Fast path for the n == 1 case.
- b.set(i)
- return
- }
- // Set bits [i, j].
- j := i + n - 1
- if i/64 == j/64 {
- b[i/64] |= ((uint64(1) << n) - 1) << (i % 64)
- return
- }
- _ = b[j/64]
- // Set leading bits.
- b[i/64] |= ^uint64(0) << (i % 64)
- for k := i/64 + 1; k < j/64; k++ {
- b[k] = ^uint64(0)
- }
- // Set trailing bits.
- b[j/64] |= (uint64(1) << (j%64 + 1)) - 1
-}
-
-// setAll sets all the bits of b.
-func (b *pageBits) setAll() {
- for i := range b {
- b[i] = ^uint64(0)
- }
-}
-
-// setBlock64 sets the 64-bit aligned block of bits containing the i'th bit that
-// are set in v.
-func (b *pageBits) setBlock64(i uint, v uint64) {
- b[i/64] |= v
-}
-
-// clear clears bit i of pageBits.
-func (b *pageBits) clear(i uint) {
- b[i/64] &^= 1 << (i % 64)
-}
-
-// clearRange clears bits in the range [i, i+n).
-func (b *pageBits) clearRange(i, n uint) {
- _ = b[i/64]
- if n == 1 {
- // Fast path for the n == 1 case.
- b.clear(i)
- return
- }
- // Clear bits [i, j].
- j := i + n - 1
- if i/64 == j/64 {
- b[i/64] &^= ((uint64(1) << n) - 1) << (i % 64)
- return
- }
- _ = b[j/64]
- // Clear leading bits.
- b[i/64] &^= ^uint64(0) << (i % 64)
- for k := i/64 + 1; k < j/64; k++ {
- b[k] = 0
- }
- // Clear trailing bits.
- b[j/64] &^= (uint64(1) << (j%64 + 1)) - 1
-}
-
-// clearAll frees all the bits of b.
-func (b *pageBits) clearAll() {
- for i := range b {
- b[i] = 0
- }
-}
-
-// clearBlock64 clears the 64-bit aligned block of bits containing the i'th bit that
-// are set in v.
-func (b *pageBits) clearBlock64(i uint, v uint64) {
- b[i/64] &^= v
-}
-
-// popcntRange counts the number of set bits in the
-// range [i, i+n).
-func (b *pageBits) popcntRange(i, n uint) (s uint) {
- if n == 1 {
- return uint((b[i/64] >> (i % 64)) & 1)
- }
- _ = b[i/64]
- j := i + n - 1
- if i/64 == j/64 {
- return uint(sys.OnesCount64((b[i/64] >> (i % 64)) & ((1 << n) - 1)))
- }
- _ = b[j/64]
- s += uint(sys.OnesCount64(b[i/64] >> (i % 64)))
- for k := i/64 + 1; k < j/64; k++ {
- s += uint(sys.OnesCount64(b[k]))
- }
- s += uint(sys.OnesCount64(b[j/64] & ((1 << (j%64 + 1)) - 1)))
- return
-}
-
-// pallocBits is a bitmap that tracks page allocations for at most one
-// palloc chunk.
-//
-// The precise representation is an implementation detail, but for the
-// sake of documentation, 0s are free pages and 1s are allocated pages.
-type pallocBits pageBits
-
-// summarize returns a packed summary of the bitmap in pallocBits.
-func (b *pallocBits) summarize() pallocSum {
- var start, max, cur uint
- const notSetYet = ^uint(0) // sentinel for start value
- start = notSetYet
- for i := 0; i < len(b); i++ {
- x := b[i]
- if x == 0 {
- cur += 64
- continue
- }
- t := uint(sys.TrailingZeros64(x))
- l := uint(sys.LeadingZeros64(x))
-
- // Finish any region spanning the uint64s
- cur += t
- if start == notSetYet {
- start = cur
- }
- if cur > max {
- max = cur
- }
- // Final region that might span to next uint64
- cur = l
- }
- if start == notSetYet {
- // Made it all the way through without finding a single 1 bit.
- const n = uint(64 * len(b))
- return packPallocSum(n, n, n)
- }
- if cur > max {
- max = cur
- }
- if max >= 64-2 {
- // There is no way an internal run of zeros could beat max.
- return packPallocSum(start, max, cur)
- }
- // Now look inside each uint64 for runs of zeros.
- // All uint64s must be nonzero, or we would have aborted above.
-outer:
- for i := 0; i < len(b); i++ {
- x := b[i]
-
- // Look inside this uint64. We have a pattern like
- // 000000 1xxxxx1 000000
- // We need to look inside the 1xxxxx1 for any contiguous
- // region of zeros.
-
- // We already know the trailing zeros are no larger than max. Remove them.
- x >>= sys.TrailingZeros64(x) & 63
- if x&(x+1) == 0 { // no more zeros (except at the top).
- continue
- }
-
- // Strategy: shrink all runs of zeros by max. If any runs of zero
- // remain, then we've identified a larger maxiumum zero run.
- p := max // number of zeros we still need to shrink by.
- k := uint(1) // current minimum length of runs of ones in x.
- for {
- // Shrink all runs of zeros by p places (except the top zeros).
- for p > 0 {
- if p <= k {
- // Shift p ones down into the top of each run of zeros.
- x |= x >> (p & 63)
- if x&(x+1) == 0 { // no more zeros (except at the top).
- continue outer
- }
- break
- }
- // Shift k ones down into the top of each run of zeros.
- x |= x >> (k & 63)
- if x&(x+1) == 0 { // no more zeros (except at the top).
- continue outer
- }
- p -= k
- // We've just doubled the minimum length of 1-runs.
- // This allows us to shift farther in the next iteration.
- k *= 2
- }
-
- // The length of the lowest-order zero run is an increment to our maximum.
- j := uint(sys.TrailingZeros64(^x)) // count contiguous trailing ones
- x >>= j & 63 // remove trailing ones
- j = uint(sys.TrailingZeros64(x)) // count contiguous trailing zeros
- x >>= j & 63 // remove zeros
- max += j // we have a new maximum!
- if x&(x+1) == 0 { // no more zeros (except at the top).
- continue outer
- }
- p = j // remove j more zeros from each zero run.
- }
- }
- return packPallocSum(start, max, cur)
-}
-
-// find searches for npages contiguous free pages in pallocBits and returns
-// the index where that run starts, as well as the index of the first free page
-// it found in the search. searchIdx represents the first known free page and
-// where to begin the next search from.
-//
-// If find fails to find any free space, it returns an index of ^uint(0) and
-// the new searchIdx should be ignored.
-//
-// Note that if npages == 1, the two returned values will always be identical.
-func (b *pallocBits) find(npages uintptr, searchIdx uint) (uint, uint) {
- if npages == 1 {
- addr := b.find1(searchIdx)
- return addr, addr
- } else if npages <= 64 {
- return b.findSmallN(npages, searchIdx)
- }
- return b.findLargeN(npages, searchIdx)
-}
-
-// find1 is a helper for find which searches for a single free page
-// in the pallocBits and returns the index.
-//
-// See find for an explanation of the searchIdx parameter.
-func (b *pallocBits) find1(searchIdx uint) uint {
- _ = b[0] // lift nil check out of loop
- for i := searchIdx / 64; i < uint(len(b)); i++ {
- x := b[i]
- if ^x == 0 {
- continue
- }
- return i*64 + uint(sys.TrailingZeros64(^x))
- }
- return ^uint(0)
-}
-
-// findSmallN is a helper for find which searches for npages contiguous free pages
-// in this pallocBits and returns the index where that run of contiguous pages
-// starts as well as the index of the first free page it finds in its search.
-//
-// See find for an explanation of the searchIdx parameter.
-//
-// Returns a ^uint(0) index on failure and the new searchIdx should be ignored.
-//
-// findSmallN assumes npages <= 64, where any such contiguous run of pages
-// crosses at most one aligned 64-bit boundary in the bits.
-func (b *pallocBits) findSmallN(npages uintptr, searchIdx uint) (uint, uint) {
- end, newSearchIdx := uint(0), ^uint(0)
- for i := searchIdx / 64; i < uint(len(b)); i++ {
- bi := b[i]
- if ^bi == 0 {
- end = 0
- continue
- }
- // First see if we can pack our allocation in the trailing
- // zeros plus the end of the last 64 bits.
- if newSearchIdx == ^uint(0) {
- // The new searchIdx is going to be at these 64 bits after any
- // 1s we file, so count trailing 1s.
- newSearchIdx = i*64 + uint(sys.TrailingZeros64(^bi))
- }
- start := uint(sys.TrailingZeros64(bi))
- if end+start >= uint(npages) {
- return i*64 - end, newSearchIdx
- }
- // Next, check the interior of the 64-bit chunk.
- j := findBitRange64(^bi, uint(npages))
- if j < 64 {
- return i*64 + j, newSearchIdx
- }
- end = uint(sys.LeadingZeros64(bi))
- }
- return ^uint(0), newSearchIdx
-}
-
-// findLargeN is a helper for find which searches for npages contiguous free pages
-// in this pallocBits and returns the index where that run starts, as well as the
-// index of the first free page it found it its search.
-//
-// See alloc for an explanation of the searchIdx parameter.
-//
-// Returns a ^uint(0) index on failure and the new searchIdx should be ignored.
-//
-// findLargeN assumes npages > 64, where any such run of free pages
-// crosses at least one aligned 64-bit boundary in the bits.
-func (b *pallocBits) findLargeN(npages uintptr, searchIdx uint) (uint, uint) {
- start, size, newSearchIdx := ^uint(0), uint(0), ^uint(0)
- for i := searchIdx / 64; i < uint(len(b)); i++ {
- x := b[i]
- if x == ^uint64(0) {
- size = 0
- continue
- }
- if newSearchIdx == ^uint(0) {
- // The new searchIdx is going to be at these 64 bits after any
- // 1s we file, so count trailing 1s.
- newSearchIdx = i*64 + uint(sys.TrailingZeros64(^x))
- }
- if size == 0 {
- size = uint(sys.LeadingZeros64(x))
- start = i*64 + 64 - size
- continue
- }
- s := uint(sys.TrailingZeros64(x))
- if s+size >= uint(npages) {
- size += s
- return start, newSearchIdx
- }
- if s < 64 {
- size = uint(sys.LeadingZeros64(x))
- start = i*64 + 64 - size
- continue
- }
- size += 64
- }
- if size < uint(npages) {
- return ^uint(0), newSearchIdx
- }
- return start, newSearchIdx
-}
-
-// allocRange allocates the range [i, i+n).
-func (b *pallocBits) allocRange(i, n uint) {
- (*pageBits)(b).setRange(i, n)
-}
-
-// allocAll allocates all the bits of b.
-func (b *pallocBits) allocAll() {
- (*pageBits)(b).setAll()
-}
-
-// free1 frees a single page in the pallocBits at i.
-func (b *pallocBits) free1(i uint) {
- (*pageBits)(b).clear(i)
-}
-
-// free frees the range [i, i+n) of pages in the pallocBits.
-func (b *pallocBits) free(i, n uint) {
- (*pageBits)(b).clearRange(i, n)
-}
-
-// freeAll frees all the bits of b.
-func (b *pallocBits) freeAll() {
- (*pageBits)(b).clearAll()
-}
-
-// pages64 returns a 64-bit bitmap representing a block of 64 pages aligned
-// to 64 pages. The returned block of pages is the one containing the i'th
-// page in this pallocBits. Each bit represents whether the page is in-use.
-func (b *pallocBits) pages64(i uint) uint64 {
- return (*pageBits)(b).block64(i)
-}
-
-// allocPages64 allocates a 64-bit block of 64 pages aligned to 64 pages according
-// to the bits set in alloc. The block set is the one containing the i'th page.
-func (b *pallocBits) allocPages64(i uint, alloc uint64) {
- (*pageBits)(b).setBlock64(i, alloc)
-}
-
-// findBitRange64 returns the bit index of the first set of
-// n consecutive 1 bits. If no consecutive set of 1 bits of
-// size n may be found in c, then it returns an integer >= 64.
-// n must be > 0.
-func findBitRange64(c uint64, n uint) uint {
- // This implementation is based on shrinking the length of
- // runs of contiguous 1 bits. We remove the top n-1 1 bits
- // from each run of 1s, then look for the first remaining 1 bit.
- p := n - 1 // number of 1s we want to remove.
- k := uint(1) // current minimum width of runs of 0 in c.
- for p > 0 {
- if p <= k {
- // Shift p 0s down into the top of each run of 1s.
- c &= c >> (p & 63)
- break
- }
- // Shift k 0s down into the top of each run of 1s.
- c &= c >> (k & 63)
- if c == 0 {
- return 64
- }
- p -= k
- // We've just doubled the minimum length of 0-runs.
- // This allows us to shift farther in the next iteration.
- k *= 2
- }
- // Find first remaining 1.
- // Since we shrunk from the top down, the first 1 is in
- // its correct original position.
- return uint(sys.TrailingZeros64(c))
-}
-
-// pallocData encapsulates pallocBits and a bitmap for
-// whether or not a given page is scavenged in a single
-// structure. It's effectively a pallocBits with
-// additional functionality.
-//
-// Update the comment on (*pageAlloc).chunks should this
-// structure change.
-type pallocData struct {
- pallocBits
- scavenged pageBits
-}
-
-// allocRange sets bits [i, i+n) in the bitmap to 1 and
-// updates the scavenged bits appropriately.
-func (m *pallocData) allocRange(i, n uint) {
- // Clear the scavenged bits when we alloc the range.
- m.pallocBits.allocRange(i, n)
- m.scavenged.clearRange(i, n)
-}
-
-// allocAll sets every bit in the bitmap to 1 and updates
-// the scavenged bits appropriately.
-func (m *pallocData) allocAll() {
- // Clear the scavenged bits when we alloc the range.
- m.pallocBits.allocAll()
- m.scavenged.clearAll()
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mprof.go b/contrib/go/_std_1.20/src/runtime/mprof.go
deleted file mode 100644
index 24f88897d7..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mprof.go
+++ /dev/null
@@ -1,1281 +0,0 @@
-// Copyright 2009 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.
-
-// Malloc profiling.
-// Patterned after tcmalloc's algorithms; shorter code.
-
-package runtime
-
-import (
- "internal/abi"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// NOTE(rsc): Everything here could use cas if contention became an issue.
-var (
- // profInsertLock protects changes to the start of all *bucket linked lists
- profInsertLock mutex
- // profBlockLock protects the contents of every blockRecord struct
- profBlockLock mutex
- // profMemActiveLock protects the active field of every memRecord struct
- profMemActiveLock mutex
- // profMemFutureLock is a set of locks that protect the respective elements
- // of the future array of every memRecord struct
- profMemFutureLock [len(memRecord{}.future)]mutex
-)
-
-// All memory allocations are local and do not escape outside of the profiler.
-// The profiler is forbidden from referring to garbage-collected memory.
-
-const (
- // profile types
- memProfile bucketType = 1 + iota
- blockProfile
- mutexProfile
-
- // size of bucket hash table
- buckHashSize = 179999
-
- // max depth of stack to record in bucket
- maxStack = 32
-)
-
-type bucketType int
-
-// A bucket holds per-call-stack profiling information.
-// The representation is a bit sleazy, inherited from C.
-// This struct defines the bucket header. It is followed in
-// memory by the stack words and then the actual record
-// data, either a memRecord or a blockRecord.
-//
-// Per-call-stack profiling information.
-// Lookup by hashing call stack into a linked-list hash table.
-//
-// None of the fields in this bucket header are modified after
-// creation, including its next and allnext links.
-//
-// No heap pointers.
-type bucket struct {
- _ sys.NotInHeap
- next *bucket
- allnext *bucket
- typ bucketType // memBucket or blockBucket (includes mutexProfile)
- hash uintptr
- size uintptr
- nstk uintptr
-}
-
-// A memRecord is the bucket data for a bucket of type memProfile,
-// part of the memory profile.
-type memRecord struct {
- // The following complex 3-stage scheme of stats accumulation
- // is required to obtain a consistent picture of mallocs and frees
- // for some point in time.
- // The problem is that mallocs come in real time, while frees
- // come only after a GC during concurrent sweeping. So if we would
- // naively count them, we would get a skew toward mallocs.
- //
- // Hence, we delay information to get consistent snapshots as
- // of mark termination. Allocations count toward the next mark
- // termination's snapshot, while sweep frees count toward the
- // previous mark termination's snapshot:
- //
- // MT MT MT MT
- // .·| .·| .·| .·|
- // .·˙ | .·˙ | .·˙ | .·˙ |
- // .·˙ | .·˙ | .·˙ | .·˙ |
- // .·˙ |.·˙ |.·˙ |.·˙ |
- //
- // alloc → ▲ ← free
- // ┠┅┅┅┅┅┅┅┅┅┅┅P
- // C+2 → C+1 → C
- //
- // alloc → ▲ ← free
- // ┠┅┅┅┅┅┅┅┅┅┅┅P
- // C+2 → C+1 → C
- //
- // Since we can't publish a consistent snapshot until all of
- // the sweep frees are accounted for, we wait until the next
- // mark termination ("MT" above) to publish the previous mark
- // termination's snapshot ("P" above). To do this, allocation
- // and free events are accounted to *future* heap profile
- // cycles ("C+n" above) and we only publish a cycle once all
- // of the events from that cycle must be done. Specifically:
- //
- // Mallocs are accounted to cycle C+2.
- // Explicit frees are accounted to cycle C+2.
- // GC frees (done during sweeping) are accounted to cycle C+1.
- //
- // After mark termination, we increment the global heap
- // profile cycle counter and accumulate the stats from cycle C
- // into the active profile.
-
- // active is the currently published profile. A profiling
- // cycle can be accumulated into active once its complete.
- active memRecordCycle
-
- // future records the profile events we're counting for cycles
- // that have not yet been published. This is ring buffer
- // indexed by the global heap profile cycle C and stores
- // cycles C, C+1, and C+2. Unlike active, these counts are
- // only for a single cycle; they are not cumulative across
- // cycles.
- //
- // We store cycle C here because there's a window between when
- // C becomes the active cycle and when we've flushed it to
- // active.
- future [3]memRecordCycle
-}
-
-// memRecordCycle
-type memRecordCycle struct {
- allocs, frees uintptr
- alloc_bytes, free_bytes uintptr
-}
-
-// add accumulates b into a. It does not zero b.
-func (a *memRecordCycle) add(b *memRecordCycle) {
- a.allocs += b.allocs
- a.frees += b.frees
- a.alloc_bytes += b.alloc_bytes
- a.free_bytes += b.free_bytes
-}
-
-// A blockRecord is the bucket data for a bucket of type blockProfile,
-// which is used in blocking and mutex profiles.
-type blockRecord struct {
- count float64
- cycles int64
-}
-
-var (
- mbuckets atomic.UnsafePointer // *bucket, memory profile buckets
- bbuckets atomic.UnsafePointer // *bucket, blocking profile buckets
- xbuckets atomic.UnsafePointer // *bucket, mutex profile buckets
- buckhash atomic.UnsafePointer // *buckhashArray
-
- mProfCycle mProfCycleHolder
-)
-
-type buckhashArray [buckHashSize]atomic.UnsafePointer // *bucket
-
-const mProfCycleWrap = uint32(len(memRecord{}.future)) * (2 << 24)
-
-// mProfCycleHolder holds the global heap profile cycle number (wrapped at
-// mProfCycleWrap, stored starting at bit 1), and a flag (stored at bit 0) to
-// indicate whether future[cycle] in all buckets has been queued to flush into
-// the active profile.
-type mProfCycleHolder struct {
- value atomic.Uint32
-}
-
-// read returns the current cycle count.
-func (c *mProfCycleHolder) read() (cycle uint32) {
- v := c.value.Load()
- cycle = v >> 1
- return cycle
-}
-
-// setFlushed sets the flushed flag. It returns the current cycle count and the
-// previous value of the flushed flag.
-func (c *mProfCycleHolder) setFlushed() (cycle uint32, alreadyFlushed bool) {
- for {
- prev := c.value.Load()
- cycle = prev >> 1
- alreadyFlushed = (prev & 0x1) != 0
- next := prev | 0x1
- if c.value.CompareAndSwap(prev, next) {
- return cycle, alreadyFlushed
- }
- }
-}
-
-// increment increases the cycle count by one, wrapping the value at
-// mProfCycleWrap. It clears the flushed flag.
-func (c *mProfCycleHolder) increment() {
- // We explicitly wrap mProfCycle rather than depending on
- // uint wraparound because the memRecord.future ring does not
- // itself wrap at a power of two.
- for {
- prev := c.value.Load()
- cycle := prev >> 1
- cycle = (cycle + 1) % mProfCycleWrap
- next := cycle << 1
- if c.value.CompareAndSwap(prev, next) {
- break
- }
- }
-}
-
-// newBucket allocates a bucket with the given type and number of stack entries.
-func newBucket(typ bucketType, nstk int) *bucket {
- size := unsafe.Sizeof(bucket{}) + uintptr(nstk)*unsafe.Sizeof(uintptr(0))
- switch typ {
- default:
- throw("invalid profile bucket type")
- case memProfile:
- size += unsafe.Sizeof(memRecord{})
- case blockProfile, mutexProfile:
- size += unsafe.Sizeof(blockRecord{})
- }
-
- b := (*bucket)(persistentalloc(size, 0, &memstats.buckhash_sys))
- b.typ = typ
- b.nstk = uintptr(nstk)
- return b
-}
-
-// stk returns the slice in b holding the stack.
-func (b *bucket) stk() []uintptr {
- stk := (*[maxStack]uintptr)(add(unsafe.Pointer(b), unsafe.Sizeof(*b)))
- return stk[:b.nstk:b.nstk]
-}
-
-// mp returns the memRecord associated with the memProfile bucket b.
-func (b *bucket) mp() *memRecord {
- if b.typ != memProfile {
- throw("bad use of bucket.mp")
- }
- data := add(unsafe.Pointer(b), unsafe.Sizeof(*b)+b.nstk*unsafe.Sizeof(uintptr(0)))
- return (*memRecord)(data)
-}
-
-// bp returns the blockRecord associated with the blockProfile bucket b.
-func (b *bucket) bp() *blockRecord {
- if b.typ != blockProfile && b.typ != mutexProfile {
- throw("bad use of bucket.bp")
- }
- data := add(unsafe.Pointer(b), unsafe.Sizeof(*b)+b.nstk*unsafe.Sizeof(uintptr(0)))
- return (*blockRecord)(data)
-}
-
-// Return the bucket for stk[0:nstk], allocating new bucket if needed.
-func stkbucket(typ bucketType, size uintptr, stk []uintptr, alloc bool) *bucket {
- bh := (*buckhashArray)(buckhash.Load())
- if bh == nil {
- lock(&profInsertLock)
- // check again under the lock
- bh = (*buckhashArray)(buckhash.Load())
- if bh == nil {
- bh = (*buckhashArray)(sysAlloc(unsafe.Sizeof(buckhashArray{}), &memstats.buckhash_sys))
- if bh == nil {
- throw("runtime: cannot allocate memory")
- }
- buckhash.StoreNoWB(unsafe.Pointer(bh))
- }
- unlock(&profInsertLock)
- }
-
- // Hash stack.
- var h uintptr
- for _, pc := range stk {
- h += pc
- h += h << 10
- h ^= h >> 6
- }
- // hash in size
- h += size
- h += h << 10
- h ^= h >> 6
- // finalize
- h += h << 3
- h ^= h >> 11
-
- i := int(h % buckHashSize)
- // first check optimistically, without the lock
- for b := (*bucket)(bh[i].Load()); b != nil; b = b.next {
- if b.typ == typ && b.hash == h && b.size == size && eqslice(b.stk(), stk) {
- return b
- }
- }
-
- if !alloc {
- return nil
- }
-
- lock(&profInsertLock)
- // check again under the insertion lock
- for b := (*bucket)(bh[i].Load()); b != nil; b = b.next {
- if b.typ == typ && b.hash == h && b.size == size && eqslice(b.stk(), stk) {
- unlock(&profInsertLock)
- return b
- }
- }
-
- // Create new bucket.
- b := newBucket(typ, len(stk))
- copy(b.stk(), stk)
- b.hash = h
- b.size = size
-
- var allnext *atomic.UnsafePointer
- if typ == memProfile {
- allnext = &mbuckets
- } else if typ == mutexProfile {
- allnext = &xbuckets
- } else {
- allnext = &bbuckets
- }
-
- b.next = (*bucket)(bh[i].Load())
- b.allnext = (*bucket)(allnext.Load())
-
- bh[i].StoreNoWB(unsafe.Pointer(b))
- allnext.StoreNoWB(unsafe.Pointer(b))
-
- unlock(&profInsertLock)
- return b
-}
-
-func eqslice(x, y []uintptr) bool {
- if len(x) != len(y) {
- return false
- }
- for i, xi := range x {
- if xi != y[i] {
- return false
- }
- }
- return true
-}
-
-// mProf_NextCycle publishes the next heap profile cycle and creates a
-// fresh heap profile cycle. This operation is fast and can be done
-// during STW. The caller must call mProf_Flush before calling
-// mProf_NextCycle again.
-//
-// This is called by mark termination during STW so allocations and
-// frees after the world is started again count towards a new heap
-// profiling cycle.
-func mProf_NextCycle() {
- mProfCycle.increment()
-}
-
-// mProf_Flush flushes the events from the current heap profiling
-// cycle into the active profile. After this it is safe to start a new
-// heap profiling cycle with mProf_NextCycle.
-//
-// This is called by GC after mark termination starts the world. In
-// contrast with mProf_NextCycle, this is somewhat expensive, but safe
-// to do concurrently.
-func mProf_Flush() {
- cycle, alreadyFlushed := mProfCycle.setFlushed()
- if alreadyFlushed {
- return
- }
-
- index := cycle % uint32(len(memRecord{}.future))
- lock(&profMemActiveLock)
- lock(&profMemFutureLock[index])
- mProf_FlushLocked(index)
- unlock(&profMemFutureLock[index])
- unlock(&profMemActiveLock)
-}
-
-// mProf_FlushLocked flushes the events from the heap profiling cycle at index
-// into the active profile. The caller must hold the lock for the active profile
-// (profMemActiveLock) and for the profiling cycle at index
-// (profMemFutureLock[index]).
-func mProf_FlushLocked(index uint32) {
- assertLockHeld(&profMemActiveLock)
- assertLockHeld(&profMemFutureLock[index])
- head := (*bucket)(mbuckets.Load())
- for b := head; b != nil; b = b.allnext {
- mp := b.mp()
-
- // Flush cycle C into the published profile and clear
- // it for reuse.
- mpc := &mp.future[index]
- mp.active.add(mpc)
- *mpc = memRecordCycle{}
- }
-}
-
-// mProf_PostSweep records that all sweep frees for this GC cycle have
-// completed. This has the effect of publishing the heap profile
-// snapshot as of the last mark termination without advancing the heap
-// profile cycle.
-func mProf_PostSweep() {
- // Flush cycle C+1 to the active profile so everything as of
- // the last mark termination becomes visible. *Don't* advance
- // the cycle, since we're still accumulating allocs in cycle
- // C+2, which have to become C+1 in the next mark termination
- // and so on.
- cycle := mProfCycle.read() + 1
-
- index := cycle % uint32(len(memRecord{}.future))
- lock(&profMemActiveLock)
- lock(&profMemFutureLock[index])
- mProf_FlushLocked(index)
- unlock(&profMemFutureLock[index])
- unlock(&profMemActiveLock)
-}
-
-// Called by malloc to record a profiled block.
-func mProf_Malloc(p unsafe.Pointer, size uintptr) {
- var stk [maxStack]uintptr
- nstk := callers(4, stk[:])
-
- index := (mProfCycle.read() + 2) % uint32(len(memRecord{}.future))
-
- b := stkbucket(memProfile, size, stk[:nstk], true)
- mp := b.mp()
- mpc := &mp.future[index]
-
- lock(&profMemFutureLock[index])
- mpc.allocs++
- mpc.alloc_bytes += size
- unlock(&profMemFutureLock[index])
-
- // Setprofilebucket locks a bunch of other mutexes, so we call it outside of
- // the profiler locks. This reduces potential contention and chances of
- // deadlocks. Since the object must be alive during the call to
- // mProf_Malloc, it's fine to do this non-atomically.
- systemstack(func() {
- setprofilebucket(p, b)
- })
-}
-
-// Called when freeing a profiled block.
-func mProf_Free(b *bucket, size uintptr) {
- index := (mProfCycle.read() + 1) % uint32(len(memRecord{}.future))
-
- mp := b.mp()
- mpc := &mp.future[index]
-
- lock(&profMemFutureLock[index])
- mpc.frees++
- mpc.free_bytes += size
- unlock(&profMemFutureLock[index])
-}
-
-var blockprofilerate uint64 // in CPU ticks
-
-// SetBlockProfileRate controls the fraction of goroutine blocking events
-// that are reported in the blocking profile. The profiler aims to sample
-// an average of one blocking event per rate nanoseconds spent blocked.
-//
-// To include every blocking event in the profile, pass rate = 1.
-// To turn off profiling entirely, pass rate <= 0.
-func SetBlockProfileRate(rate int) {
- var r int64
- if rate <= 0 {
- r = 0 // disable profiling
- } else if rate == 1 {
- r = 1 // profile everything
- } else {
- // convert ns to cycles, use float64 to prevent overflow during multiplication
- r = int64(float64(rate) * float64(tickspersecond()) / (1000 * 1000 * 1000))
- if r == 0 {
- r = 1
- }
- }
-
- atomic.Store64(&blockprofilerate, uint64(r))
-}
-
-func blockevent(cycles int64, skip int) {
- if cycles <= 0 {
- cycles = 1
- }
-
- rate := int64(atomic.Load64(&blockprofilerate))
- if blocksampled(cycles, rate) {
- saveblockevent(cycles, rate, skip+1, blockProfile)
- }
-}
-
-// blocksampled returns true for all events where cycles >= rate. Shorter
-// events have a cycles/rate random chance of returning true.
-func blocksampled(cycles, rate int64) bool {
- if rate <= 0 || (rate > cycles && int64(fastrand())%rate > cycles) {
- return false
- }
- return true
-}
-
-func saveblockevent(cycles, rate int64, skip int, which bucketType) {
- gp := getg()
- var nstk int
- var stk [maxStack]uintptr
- if gp.m.curg == nil || gp.m.curg == gp {
- nstk = callers(skip, stk[:])
- } else {
- nstk = gcallers(gp.m.curg, skip, stk[:])
- }
- b := stkbucket(which, 0, stk[:nstk], true)
- bp := b.bp()
-
- lock(&profBlockLock)
- // We want to up-scale the count and cycles according to the
- // probability that the event was sampled. For block profile events,
- // the sample probability is 1 if cycles >= rate, and cycles / rate
- // otherwise. For mutex profile events, the sample probability is 1 / rate.
- // We scale the events by 1 / (probability the event was sampled).
- if which == blockProfile && cycles < rate {
- // Remove sampling bias, see discussion on http://golang.org/cl/299991.
- bp.count += float64(rate) / float64(cycles)
- bp.cycles += rate
- } else if which == mutexProfile {
- bp.count += float64(rate)
- bp.cycles += rate * cycles
- } else {
- bp.count++
- bp.cycles += cycles
- }
- unlock(&profBlockLock)
-}
-
-var mutexprofilerate uint64 // fraction sampled
-
-// SetMutexProfileFraction controls the fraction of mutex contention events
-// that are reported in the mutex profile. On average 1/rate events are
-// reported. The previous rate is returned.
-//
-// To turn off profiling entirely, pass rate 0.
-// To just read the current rate, pass rate < 0.
-// (For n>1 the details of sampling may change.)
-func SetMutexProfileFraction(rate int) int {
- if rate < 0 {
- return int(mutexprofilerate)
- }
- old := mutexprofilerate
- atomic.Store64(&mutexprofilerate, uint64(rate))
- return int(old)
-}
-
-//go:linkname mutexevent sync.event
-func mutexevent(cycles int64, skip int) {
- if cycles < 0 {
- cycles = 0
- }
- rate := int64(atomic.Load64(&mutexprofilerate))
- // TODO(pjw): measure impact of always calling fastrand vs using something
- // like malloc.go:nextSample()
- if rate > 0 && int64(fastrand())%rate == 0 {
- saveblockevent(cycles, rate, skip+1, mutexProfile)
- }
-}
-
-// Go interface to profile data.
-
-// A StackRecord describes a single execution stack.
-type StackRecord struct {
- Stack0 [32]uintptr // stack trace for this record; ends at first 0 entry
-}
-
-// Stack returns the stack trace associated with the record,
-// a prefix of r.Stack0.
-func (r *StackRecord) Stack() []uintptr {
- for i, v := range r.Stack0 {
- if v == 0 {
- return r.Stack0[0:i]
- }
- }
- return r.Stack0[0:]
-}
-
-// MemProfileRate controls the fraction of memory allocations
-// that are recorded and reported in the memory profile.
-// The profiler aims to sample an average of
-// one allocation per MemProfileRate bytes allocated.
-//
-// To include every allocated block in the profile, set MemProfileRate to 1.
-// To turn off profiling entirely, set MemProfileRate to 0.
-//
-// The tools that process the memory profiles assume that the
-// profile rate is constant across the lifetime of the program
-// and equal to the current value. Programs that change the
-// memory profiling rate should do so just once, as early as
-// possible in the execution of the program (for example,
-// at the beginning of main).
-var MemProfileRate int = 512 * 1024
-
-// disableMemoryProfiling is set by the linker if runtime.MemProfile
-// is not used and the link type guarantees nobody else could use it
-// elsewhere.
-var disableMemoryProfiling bool
-
-// A MemProfileRecord describes the live objects allocated
-// by a particular call sequence (stack trace).
-type MemProfileRecord struct {
- AllocBytes, FreeBytes int64 // number of bytes allocated, freed
- AllocObjects, FreeObjects int64 // number of objects allocated, freed
- Stack0 [32]uintptr // stack trace for this record; ends at first 0 entry
-}
-
-// InUseBytes returns the number of bytes in use (AllocBytes - FreeBytes).
-func (r *MemProfileRecord) InUseBytes() int64 { return r.AllocBytes - r.FreeBytes }
-
-// InUseObjects returns the number of objects in use (AllocObjects - FreeObjects).
-func (r *MemProfileRecord) InUseObjects() int64 {
- return r.AllocObjects - r.FreeObjects
-}
-
-// Stack returns the stack trace associated with the record,
-// a prefix of r.Stack0.
-func (r *MemProfileRecord) Stack() []uintptr {
- for i, v := range r.Stack0 {
- if v == 0 {
- return r.Stack0[0:i]
- }
- }
- return r.Stack0[0:]
-}
-
-// MemProfile returns a profile of memory allocated and freed per allocation
-// site.
-//
-// MemProfile returns n, the number of records in the current memory profile.
-// If len(p) >= n, MemProfile copies the profile into p and returns n, true.
-// If len(p) < n, MemProfile does not change p and returns n, false.
-//
-// If inuseZero is true, the profile includes allocation records
-// where r.AllocBytes > 0 but r.AllocBytes == r.FreeBytes.
-// These are sites where memory was allocated, but it has all
-// been released back to the runtime.
-//
-// The returned profile may be up to two garbage collection cycles old.
-// This is to avoid skewing the profile toward allocations; because
-// allocations happen in real time but frees are delayed until the garbage
-// collector performs sweeping, the profile only accounts for allocations
-// that have had a chance to be freed by the garbage collector.
-//
-// Most clients should use the runtime/pprof package or
-// the testing package's -test.memprofile flag instead
-// of calling MemProfile directly.
-func MemProfile(p []MemProfileRecord, inuseZero bool) (n int, ok bool) {
- cycle := mProfCycle.read()
- // If we're between mProf_NextCycle and mProf_Flush, take care
- // of flushing to the active profile so we only have to look
- // at the active profile below.
- index := cycle % uint32(len(memRecord{}.future))
- lock(&profMemActiveLock)
- lock(&profMemFutureLock[index])
- mProf_FlushLocked(index)
- unlock(&profMemFutureLock[index])
- clear := true
- head := (*bucket)(mbuckets.Load())
- for b := head; b != nil; b = b.allnext {
- mp := b.mp()
- if inuseZero || mp.active.alloc_bytes != mp.active.free_bytes {
- n++
- }
- if mp.active.allocs != 0 || mp.active.frees != 0 {
- clear = false
- }
- }
- if clear {
- // Absolutely no data, suggesting that a garbage collection
- // has not yet happened. In order to allow profiling when
- // garbage collection is disabled from the beginning of execution,
- // accumulate all of the cycles, and recount buckets.
- n = 0
- for b := head; b != nil; b = b.allnext {
- mp := b.mp()
- for c := range mp.future {
- lock(&profMemFutureLock[c])
- mp.active.add(&mp.future[c])
- mp.future[c] = memRecordCycle{}
- unlock(&profMemFutureLock[c])
- }
- if inuseZero || mp.active.alloc_bytes != mp.active.free_bytes {
- n++
- }
- }
- }
- if n <= len(p) {
- ok = true
- idx := 0
- for b := head; b != nil; b = b.allnext {
- mp := b.mp()
- if inuseZero || mp.active.alloc_bytes != mp.active.free_bytes {
- record(&p[idx], b)
- idx++
- }
- }
- }
- unlock(&profMemActiveLock)
- return
-}
-
-// Write b's data to r.
-func record(r *MemProfileRecord, b *bucket) {
- mp := b.mp()
- r.AllocBytes = int64(mp.active.alloc_bytes)
- r.FreeBytes = int64(mp.active.free_bytes)
- r.AllocObjects = int64(mp.active.allocs)
- r.FreeObjects = int64(mp.active.frees)
- if raceenabled {
- racewriterangepc(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0), getcallerpc(), abi.FuncPCABIInternal(MemProfile))
- }
- if msanenabled {
- msanwrite(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0))
- }
- if asanenabled {
- asanwrite(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0))
- }
- copy(r.Stack0[:], b.stk())
- for i := int(b.nstk); i < len(r.Stack0); i++ {
- r.Stack0[i] = 0
- }
-}
-
-func iterate_memprof(fn func(*bucket, uintptr, *uintptr, uintptr, uintptr, uintptr)) {
- lock(&profMemActiveLock)
- head := (*bucket)(mbuckets.Load())
- for b := head; b != nil; b = b.allnext {
- mp := b.mp()
- fn(b, b.nstk, &b.stk()[0], b.size, mp.active.allocs, mp.active.frees)
- }
- unlock(&profMemActiveLock)
-}
-
-// BlockProfileRecord describes blocking events originated
-// at a particular call sequence (stack trace).
-type BlockProfileRecord struct {
- Count int64
- Cycles int64
- StackRecord
-}
-
-// BlockProfile returns n, the number of records in the current blocking profile.
-// If len(p) >= n, BlockProfile copies the profile into p and returns n, true.
-// If len(p) < n, BlockProfile does not change p and returns n, false.
-//
-// Most clients should use the runtime/pprof package or
-// the testing package's -test.blockprofile flag instead
-// of calling BlockProfile directly.
-func BlockProfile(p []BlockProfileRecord) (n int, ok bool) {
- lock(&profBlockLock)
- head := (*bucket)(bbuckets.Load())
- for b := head; b != nil; b = b.allnext {
- n++
- }
- if n <= len(p) {
- ok = true
- for b := head; b != nil; b = b.allnext {
- bp := b.bp()
- r := &p[0]
- r.Count = int64(bp.count)
- // Prevent callers from having to worry about division by zero errors.
- // See discussion on http://golang.org/cl/299991.
- if r.Count == 0 {
- r.Count = 1
- }
- r.Cycles = bp.cycles
- if raceenabled {
- racewriterangepc(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0), getcallerpc(), abi.FuncPCABIInternal(BlockProfile))
- }
- if msanenabled {
- msanwrite(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0))
- }
- if asanenabled {
- asanwrite(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0))
- }
- i := copy(r.Stack0[:], b.stk())
- for ; i < len(r.Stack0); i++ {
- r.Stack0[i] = 0
- }
- p = p[1:]
- }
- }
- unlock(&profBlockLock)
- return
-}
-
-// MutexProfile returns n, the number of records in the current mutex profile.
-// If len(p) >= n, MutexProfile copies the profile into p and returns n, true.
-// Otherwise, MutexProfile does not change p, and returns n, false.
-//
-// Most clients should use the runtime/pprof package
-// instead of calling MutexProfile directly.
-func MutexProfile(p []BlockProfileRecord) (n int, ok bool) {
- lock(&profBlockLock)
- head := (*bucket)(xbuckets.Load())
- for b := head; b != nil; b = b.allnext {
- n++
- }
- if n <= len(p) {
- ok = true
- for b := head; b != nil; b = b.allnext {
- bp := b.bp()
- r := &p[0]
- r.Count = int64(bp.count)
- r.Cycles = bp.cycles
- i := copy(r.Stack0[:], b.stk())
- for ; i < len(r.Stack0); i++ {
- r.Stack0[i] = 0
- }
- p = p[1:]
- }
- }
- unlock(&profBlockLock)
- return
-}
-
-// ThreadCreateProfile returns n, the number of records in the thread creation profile.
-// If len(p) >= n, ThreadCreateProfile copies the profile into p and returns n, true.
-// If len(p) < n, ThreadCreateProfile does not change p and returns n, false.
-//
-// Most clients should use the runtime/pprof package instead
-// of calling ThreadCreateProfile directly.
-func ThreadCreateProfile(p []StackRecord) (n int, ok bool) {
- first := (*m)(atomic.Loadp(unsafe.Pointer(&allm)))
- for mp := first; mp != nil; mp = mp.alllink {
- n++
- }
- if n <= len(p) {
- ok = true
- i := 0
- for mp := first; mp != nil; mp = mp.alllink {
- p[i].Stack0 = mp.createstack
- i++
- }
- }
- return
-}
-
-//go:linkname runtime_goroutineProfileWithLabels runtime/pprof.runtime_goroutineProfileWithLabels
-func runtime_goroutineProfileWithLabels(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
- return goroutineProfileWithLabels(p, labels)
-}
-
-const go119ConcurrentGoroutineProfile = true
-
-// labels may be nil. If labels is non-nil, it must have the same length as p.
-func goroutineProfileWithLabels(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
- if labels != nil && len(labels) != len(p) {
- labels = nil
- }
-
- if go119ConcurrentGoroutineProfile {
- return goroutineProfileWithLabelsConcurrent(p, labels)
- }
- return goroutineProfileWithLabelsSync(p, labels)
-}
-
-var goroutineProfile = struct {
- sema uint32
- active bool
- offset atomic.Int64
- records []StackRecord
- labels []unsafe.Pointer
-}{
- sema: 1,
-}
-
-// goroutineProfileState indicates the status of a goroutine's stack for the
-// current in-progress goroutine profile. Goroutines' stacks are initially
-// "Absent" from the profile, and end up "Satisfied" by the time the profile is
-// complete. While a goroutine's stack is being captured, its
-// goroutineProfileState will be "InProgress" and it will not be able to run
-// until the capture completes and the state moves to "Satisfied".
-//
-// Some goroutines (the finalizer goroutine, which at various times can be
-// either a "system" or a "user" goroutine, and the goroutine that is
-// coordinating the profile, any goroutines created during the profile) move
-// directly to the "Satisfied" state.
-type goroutineProfileState uint32
-
-const (
- goroutineProfileAbsent goroutineProfileState = iota
- goroutineProfileInProgress
- goroutineProfileSatisfied
-)
-
-type goroutineProfileStateHolder atomic.Uint32
-
-func (p *goroutineProfileStateHolder) Load() goroutineProfileState {
- return goroutineProfileState((*atomic.Uint32)(p).Load())
-}
-
-func (p *goroutineProfileStateHolder) Store(value goroutineProfileState) {
- (*atomic.Uint32)(p).Store(uint32(value))
-}
-
-func (p *goroutineProfileStateHolder) CompareAndSwap(old, new goroutineProfileState) bool {
- return (*atomic.Uint32)(p).CompareAndSwap(uint32(old), uint32(new))
-}
-
-func goroutineProfileWithLabelsConcurrent(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
- semacquire(&goroutineProfile.sema)
-
- ourg := getg()
-
- stopTheWorld("profile")
- // Using gcount while the world is stopped should give us a consistent view
- // of the number of live goroutines, minus the number of goroutines that are
- // alive and permanently marked as "system". But to make this count agree
- // with what we'd get from isSystemGoroutine, we need special handling for
- // goroutines that can vary between user and system to ensure that the count
- // doesn't change during the collection. So, check the finalizer goroutine
- // in particular.
- n = int(gcount())
- if fingStatus.Load()&fingRunningFinalizer != 0 {
- n++
- }
-
- if n > len(p) {
- // There's not enough space in p to store the whole profile, so (per the
- // contract of runtime.GoroutineProfile) we're not allowed to write to p
- // at all and must return n, false.
- startTheWorld()
- semrelease(&goroutineProfile.sema)
- return n, false
- }
-
- // Save current goroutine.
- sp := getcallersp()
- pc := getcallerpc()
- systemstack(func() {
- saveg(pc, sp, ourg, &p[0])
- })
- ourg.goroutineProfiled.Store(goroutineProfileSatisfied)
- goroutineProfile.offset.Store(1)
-
- // Prepare for all other goroutines to enter the profile. Aside from ourg,
- // every goroutine struct in the allgs list has its goroutineProfiled field
- // cleared. Any goroutine created from this point on (while
- // goroutineProfile.active is set) will start with its goroutineProfiled
- // field set to goroutineProfileSatisfied.
- goroutineProfile.active = true
- goroutineProfile.records = p
- goroutineProfile.labels = labels
- // The finalizer goroutine needs special handling because it can vary over
- // time between being a user goroutine (eligible for this profile) and a
- // system goroutine (to be excluded). Pick one before restarting the world.
- if fing != nil {
- fing.goroutineProfiled.Store(goroutineProfileSatisfied)
- if readgstatus(fing) != _Gdead && !isSystemGoroutine(fing, false) {
- doRecordGoroutineProfile(fing)
- }
- }
- startTheWorld()
-
- // Visit each goroutine that existed as of the startTheWorld call above.
- //
- // New goroutines may not be in this list, but we didn't want to know about
- // them anyway. If they do appear in this list (via reusing a dead goroutine
- // struct, or racing to launch between the world restarting and us getting
- // the list), they will already have their goroutineProfiled field set to
- // goroutineProfileSatisfied before their state transitions out of _Gdead.
- //
- // Any goroutine that the scheduler tries to execute concurrently with this
- // call will start by adding itself to the profile (before the act of
- // executing can cause any changes in its stack).
- forEachGRace(func(gp1 *g) {
- tryRecordGoroutineProfile(gp1, Gosched)
- })
-
- stopTheWorld("profile cleanup")
- endOffset := goroutineProfile.offset.Swap(0)
- goroutineProfile.active = false
- goroutineProfile.records = nil
- goroutineProfile.labels = nil
- startTheWorld()
-
- // Restore the invariant that every goroutine struct in allgs has its
- // goroutineProfiled field cleared.
- forEachGRace(func(gp1 *g) {
- gp1.goroutineProfiled.Store(goroutineProfileAbsent)
- })
-
- if raceenabled {
- raceacquire(unsafe.Pointer(&labelSync))
- }
-
- if n != int(endOffset) {
- // It's a big surprise that the number of goroutines changed while we
- // were collecting the profile. But probably better to return a
- // truncated profile than to crash the whole process.
- //
- // For instance, needm moves a goroutine out of the _Gdead state and so
- // might be able to change the goroutine count without interacting with
- // the scheduler. For code like that, the race windows are small and the
- // combination of features is uncommon, so it's hard to be (and remain)
- // sure we've caught them all.
- }
-
- semrelease(&goroutineProfile.sema)
- return n, true
-}
-
-// tryRecordGoroutineProfileWB asserts that write barriers are allowed and calls
-// tryRecordGoroutineProfile.
-//
-//go:yeswritebarrierrec
-func tryRecordGoroutineProfileWB(gp1 *g) {
- if getg().m.p.ptr() == nil {
- throw("no P available, write barriers are forbidden")
- }
- tryRecordGoroutineProfile(gp1, osyield)
-}
-
-// tryRecordGoroutineProfile ensures that gp1 has the appropriate representation
-// in the current goroutine profile: either that it should not be profiled, or
-// that a snapshot of its call stack and labels are now in the profile.
-func tryRecordGoroutineProfile(gp1 *g, yield func()) {
- if readgstatus(gp1) == _Gdead {
- // Dead goroutines should not appear in the profile. Goroutines that
- // start while profile collection is active will get goroutineProfiled
- // set to goroutineProfileSatisfied before transitioning out of _Gdead,
- // so here we check _Gdead first.
- return
- }
- if isSystemGoroutine(gp1, true) {
- // System goroutines should not appear in the profile. (The finalizer
- // goroutine is marked as "already profiled".)
- return
- }
-
- for {
- prev := gp1.goroutineProfiled.Load()
- if prev == goroutineProfileSatisfied {
- // This goroutine is already in the profile (or is new since the
- // start of collection, so shouldn't appear in the profile).
- break
- }
- if prev == goroutineProfileInProgress {
- // Something else is adding gp1 to the goroutine profile right now.
- // Give that a moment to finish.
- yield()
- continue
- }
-
- // While we have gp1.goroutineProfiled set to
- // goroutineProfileInProgress, gp1 may appear _Grunnable but will not
- // actually be able to run. Disable preemption for ourselves, to make
- // sure we finish profiling gp1 right away instead of leaving it stuck
- // in this limbo.
- mp := acquirem()
- if gp1.goroutineProfiled.CompareAndSwap(goroutineProfileAbsent, goroutineProfileInProgress) {
- doRecordGoroutineProfile(gp1)
- gp1.goroutineProfiled.Store(goroutineProfileSatisfied)
- }
- releasem(mp)
- }
-}
-
-// doRecordGoroutineProfile writes gp1's call stack and labels to an in-progress
-// goroutine profile. Preemption is disabled.
-//
-// This may be called via tryRecordGoroutineProfile in two ways: by the
-// goroutine that is coordinating the goroutine profile (running on its own
-// stack), or from the scheduler in preparation to execute gp1 (running on the
-// system stack).
-func doRecordGoroutineProfile(gp1 *g) {
- if readgstatus(gp1) == _Grunning {
- print("doRecordGoroutineProfile gp1=", gp1.goid, "\n")
- throw("cannot read stack of running goroutine")
- }
-
- offset := int(goroutineProfile.offset.Add(1)) - 1
-
- if offset >= len(goroutineProfile.records) {
- // Should be impossible, but better to return a truncated profile than
- // to crash the entire process at this point. Instead, deal with it in
- // goroutineProfileWithLabelsConcurrent where we have more context.
- return
- }
-
- // saveg calls gentraceback, which may call cgo traceback functions. When
- // called from the scheduler, this is on the system stack already so
- // traceback.go:cgoContextPCs will avoid calling back into the scheduler.
- //
- // When called from the goroutine coordinating the profile, we still have
- // set gp1.goroutineProfiled to goroutineProfileInProgress and so are still
- // preventing it from being truly _Grunnable. So we'll use the system stack
- // to avoid schedule delays.
- systemstack(func() { saveg(^uintptr(0), ^uintptr(0), gp1, &goroutineProfile.records[offset]) })
-
- if goroutineProfile.labels != nil {
- goroutineProfile.labels[offset] = gp1.labels
- }
-}
-
-func goroutineProfileWithLabelsSync(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
- gp := getg()
-
- isOK := func(gp1 *g) bool {
- // Checking isSystemGoroutine here makes GoroutineProfile
- // consistent with both NumGoroutine and Stack.
- return gp1 != gp && readgstatus(gp1) != _Gdead && !isSystemGoroutine(gp1, false)
- }
-
- stopTheWorld("profile")
-
- // World is stopped, no locking required.
- n = 1
- forEachGRace(func(gp1 *g) {
- if isOK(gp1) {
- n++
- }
- })
-
- if n <= len(p) {
- ok = true
- r, lbl := p, labels
-
- // Save current goroutine.
- sp := getcallersp()
- pc := getcallerpc()
- systemstack(func() {
- saveg(pc, sp, gp, &r[0])
- })
- r = r[1:]
-
- // If we have a place to put our goroutine labelmap, insert it there.
- if labels != nil {
- lbl[0] = gp.labels
- lbl = lbl[1:]
- }
-
- // Save other goroutines.
- forEachGRace(func(gp1 *g) {
- if !isOK(gp1) {
- return
- }
-
- if len(r) == 0 {
- // Should be impossible, but better to return a
- // truncated profile than to crash the entire process.
- return
- }
- // saveg calls gentraceback, which may call cgo traceback functions.
- // The world is stopped, so it cannot use cgocall (which will be
- // blocked at exitsyscall). Do it on the system stack so it won't
- // call into the schedular (see traceback.go:cgoContextPCs).
- systemstack(func() { saveg(^uintptr(0), ^uintptr(0), gp1, &r[0]) })
- if labels != nil {
- lbl[0] = gp1.labels
- lbl = lbl[1:]
- }
- r = r[1:]
- })
- }
-
- if raceenabled {
- raceacquire(unsafe.Pointer(&labelSync))
- }
-
- startTheWorld()
- return n, ok
-}
-
-// GoroutineProfile returns n, the number of records in the active goroutine stack profile.
-// If len(p) >= n, GoroutineProfile copies the profile into p and returns n, true.
-// If len(p) < n, GoroutineProfile does not change p and returns n, false.
-//
-// Most clients should use the runtime/pprof package instead
-// of calling GoroutineProfile directly.
-func GoroutineProfile(p []StackRecord) (n int, ok bool) {
-
- return goroutineProfileWithLabels(p, nil)
-}
-
-func saveg(pc, sp uintptr, gp *g, r *StackRecord) {
- n := gentraceback(pc, sp, 0, gp, 0, &r.Stack0[0], len(r.Stack0), nil, nil, 0)
- if n < len(r.Stack0) {
- r.Stack0[n] = 0
- }
-}
-
-// Stack formats a stack trace of the calling goroutine into buf
-// and returns the number of bytes written to buf.
-// If all is true, Stack formats stack traces of all other goroutines
-// into buf after the trace for the current goroutine.
-func Stack(buf []byte, all bool) int {
- if all {
- stopTheWorld("stack trace")
- }
-
- n := 0
- if len(buf) > 0 {
- gp := getg()
- sp := getcallersp()
- pc := getcallerpc()
- systemstack(func() {
- g0 := getg()
- // Force traceback=1 to override GOTRACEBACK setting,
- // so that Stack's results are consistent.
- // GOTRACEBACK is only about crash dumps.
- g0.m.traceback = 1
- g0.writebuf = buf[0:0:len(buf)]
- goroutineheader(gp)
- traceback(pc, sp, 0, gp)
- if all {
- tracebackothers(gp)
- }
- g0.m.traceback = 0
- n = len(g0.writebuf)
- g0.writebuf = nil
- })
- }
-
- if all {
- startTheWorld()
- }
- return n
-}
-
-// Tracing of alloc/free/gc.
-
-var tracelock mutex
-
-func tracealloc(p unsafe.Pointer, size uintptr, typ *_type) {
- lock(&tracelock)
- gp := getg()
- gp.m.traceback = 2
- if typ == nil {
- print("tracealloc(", p, ", ", hex(size), ")\n")
- } else {
- print("tracealloc(", p, ", ", hex(size), ", ", typ.string(), ")\n")
- }
- if gp.m.curg == nil || gp == gp.m.curg {
- goroutineheader(gp)
- pc := getcallerpc()
- sp := getcallersp()
- systemstack(func() {
- traceback(pc, sp, 0, gp)
- })
- } else {
- goroutineheader(gp.m.curg)
- traceback(^uintptr(0), ^uintptr(0), 0, gp.m.curg)
- }
- print("\n")
- gp.m.traceback = 0
- unlock(&tracelock)
-}
-
-func tracefree(p unsafe.Pointer, size uintptr) {
- lock(&tracelock)
- gp := getg()
- gp.m.traceback = 2
- print("tracefree(", p, ", ", hex(size), ")\n")
- goroutineheader(gp)
- pc := getcallerpc()
- sp := getcallersp()
- systemstack(func() {
- traceback(pc, sp, 0, gp)
- })
- print("\n")
- gp.m.traceback = 0
- unlock(&tracelock)
-}
-
-func tracegc() {
- lock(&tracelock)
- gp := getg()
- gp.m.traceback = 2
- print("tracegc()\n")
- // running on m->g0 stack; show all non-g0 goroutines
- tracebackothers(gp)
- print("end tracegc\n")
- print("\n")
- gp.m.traceback = 0
- unlock(&tracelock)
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mspanset.go b/contrib/go/_std_1.20/src/runtime/mspanset.go
deleted file mode 100644
index abbd4501b1..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mspanset.go
+++ /dev/null
@@ -1,404 +0,0 @@
-// 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 runtime
-
-import (
- "internal/cpu"
- "internal/goarch"
- "runtime/internal/atomic"
- "unsafe"
-)
-
-// A spanSet is a set of *mspans.
-//
-// spanSet is safe for concurrent push and pop operations.
-type spanSet struct {
- // A spanSet is a two-level data structure consisting of a
- // growable spine that points to fixed-sized blocks. The spine
- // can be accessed without locks, but adding a block or
- // growing it requires taking the spine lock.
- //
- // Because each mspan covers at least 8K of heap and takes at
- // most 8 bytes in the spanSet, the growth of the spine is
- // quite limited.
- //
- // The spine and all blocks are allocated off-heap, which
- // allows this to be used in the memory manager and avoids the
- // need for write barriers on all of these. spanSetBlocks are
- // managed in a pool, though never freed back to the operating
- // system. We never release spine memory because there could be
- // concurrent lock-free access and we're likely to reuse it
- // anyway. (In principle, we could do this during STW.)
-
- spineLock mutex
- spine atomicSpanSetSpinePointer // *[N]atomic.Pointer[spanSetBlock]
- spineLen atomic.Uintptr // Spine array length
- spineCap uintptr // Spine array cap, accessed under spineLock
-
- // index is the head and tail of the spanSet in a single field.
- // The head and the tail both represent an index into the logical
- // concatenation of all blocks, with the head always behind or
- // equal to the tail (indicating an empty set). This field is
- // always accessed atomically.
- //
- // The head and the tail are only 32 bits wide, which means we
- // can only support up to 2^32 pushes before a reset. If every
- // span in the heap were stored in this set, and each span were
- // the minimum size (1 runtime page, 8 KiB), then roughly the
- // smallest heap which would be unrepresentable is 32 TiB in size.
- index atomicHeadTailIndex
-}
-
-const (
- spanSetBlockEntries = 512 // 4KB on 64-bit
- spanSetInitSpineCap = 256 // Enough for 1GB heap on 64-bit
-)
-
-type spanSetBlock struct {
- // Free spanSetBlocks are managed via a lock-free stack.
- lfnode
-
- // popped is the number of pop operations that have occurred on
- // this block. This number is used to help determine when a block
- // may be safely recycled.
- popped atomic.Uint32
-
- // spans is the set of spans in this block.
- spans [spanSetBlockEntries]atomicMSpanPointer
-}
-
-// push adds span s to buffer b. push is safe to call concurrently
-// with other push and pop operations.
-func (b *spanSet) push(s *mspan) {
- // Obtain our slot.
- cursor := uintptr(b.index.incTail().tail() - 1)
- top, bottom := cursor/spanSetBlockEntries, cursor%spanSetBlockEntries
-
- // Do we need to add a block?
- spineLen := b.spineLen.Load()
- var block *spanSetBlock
-retry:
- if top < spineLen {
- block = b.spine.Load().lookup(top).Load()
- } else {
- // Add a new block to the spine, potentially growing
- // the spine.
- lock(&b.spineLock)
- // spineLen cannot change until we release the lock,
- // but may have changed while we were waiting.
- spineLen = b.spineLen.Load()
- if top < spineLen {
- unlock(&b.spineLock)
- goto retry
- }
-
- spine := b.spine.Load()
- if spineLen == b.spineCap {
- // Grow the spine.
- newCap := b.spineCap * 2
- if newCap == 0 {
- newCap = spanSetInitSpineCap
- }
- newSpine := persistentalloc(newCap*goarch.PtrSize, cpu.CacheLineSize, &memstats.gcMiscSys)
- if b.spineCap != 0 {
- // Blocks are allocated off-heap, so
- // no write barriers.
- memmove(newSpine, spine.p, b.spineCap*goarch.PtrSize)
- }
- spine = spanSetSpinePointer{newSpine}
-
- // Spine is allocated off-heap, so no write barrier.
- b.spine.StoreNoWB(spine)
- b.spineCap = newCap
- // We can't immediately free the old spine
- // since a concurrent push with a lower index
- // could still be reading from it. We let it
- // leak because even a 1TB heap would waste
- // less than 2MB of memory on old spines. If
- // this is a problem, we could free old spines
- // during STW.
- }
-
- // Allocate a new block from the pool.
- block = spanSetBlockPool.alloc()
-
- // Add it to the spine.
- // Blocks are allocated off-heap, so no write barrier.
- spine.lookup(top).StoreNoWB(block)
- b.spineLen.Store(spineLen + 1)
- unlock(&b.spineLock)
- }
-
- // We have a block. Insert the span atomically, since there may be
- // concurrent readers via the block API.
- block.spans[bottom].StoreNoWB(s)
-}
-
-// pop removes and returns a span from buffer b, or nil if b is empty.
-// pop is safe to call concurrently with other pop and push operations.
-func (b *spanSet) pop() *mspan {
- var head, tail uint32
-claimLoop:
- for {
- headtail := b.index.load()
- head, tail = headtail.split()
- if head >= tail {
- // The buf is empty, as far as we can tell.
- return nil
- }
- // Check if the head position we want to claim is actually
- // backed by a block.
- spineLen := b.spineLen.Load()
- if spineLen <= uintptr(head)/spanSetBlockEntries {
- // We're racing with a spine growth and the allocation of
- // a new block (and maybe a new spine!), and trying to grab
- // the span at the index which is currently being pushed.
- // Instead of spinning, let's just notify the caller that
- // there's nothing currently here. Spinning on this is
- // almost definitely not worth it.
- return nil
- }
- // Try to claim the current head by CASing in an updated head.
- // This may fail transiently due to a push which modifies the
- // tail, so keep trying while the head isn't changing.
- want := head
- for want == head {
- if b.index.cas(headtail, makeHeadTailIndex(want+1, tail)) {
- break claimLoop
- }
- headtail = b.index.load()
- head, tail = headtail.split()
- }
- // We failed to claim the spot we were after and the head changed,
- // meaning a popper got ahead of us. Try again from the top because
- // the buf may not be empty.
- }
- top, bottom := head/spanSetBlockEntries, head%spanSetBlockEntries
-
- // We may be reading a stale spine pointer, but because the length
- // grows monotonically and we've already verified it, we'll definitely
- // be reading from a valid block.
- blockp := b.spine.Load().lookup(uintptr(top))
-
- // Given that the spine length is correct, we know we will never
- // see a nil block here, since the length is always updated after
- // the block is set.
- block := blockp.Load()
- s := block.spans[bottom].Load()
- for s == nil {
- // We raced with the span actually being set, but given that we
- // know a block for this span exists, the race window here is
- // extremely small. Try again.
- s = block.spans[bottom].Load()
- }
- // Clear the pointer. This isn't strictly necessary, but defensively
- // avoids accidentally re-using blocks which could lead to memory
- // corruption. This way, we'll get a nil pointer access instead.
- block.spans[bottom].StoreNoWB(nil)
-
- // Increase the popped count. If we are the last possible popper
- // in the block (note that bottom need not equal spanSetBlockEntries-1
- // due to races) then it's our responsibility to free the block.
- //
- // If we increment popped to spanSetBlockEntries, we can be sure that
- // we're the last popper for this block, and it's thus safe to free it.
- // Every other popper must have crossed this barrier (and thus finished
- // popping its corresponding mspan) by the time we get here. Because
- // we're the last popper, we also don't have to worry about concurrent
- // pushers (there can't be any). Note that we may not be the popper
- // which claimed the last slot in the block, we're just the last one
- // to finish popping.
- if block.popped.Add(1) == spanSetBlockEntries {
- // Clear the block's pointer.
- blockp.StoreNoWB(nil)
-
- // Return the block to the block pool.
- spanSetBlockPool.free(block)
- }
- return s
-}
-
-// reset resets a spanSet which is empty. It will also clean up
-// any left over blocks.
-//
-// Throws if the buf is not empty.
-//
-// reset may not be called concurrently with any other operations
-// on the span set.
-func (b *spanSet) reset() {
- head, tail := b.index.load().split()
- if head < tail {
- print("head = ", head, ", tail = ", tail, "\n")
- throw("attempt to clear non-empty span set")
- }
- top := head / spanSetBlockEntries
- if uintptr(top) < b.spineLen.Load() {
- // If the head catches up to the tail and the set is empty,
- // we may not clean up the block containing the head and tail
- // since it may be pushed into again. In order to avoid leaking
- // memory since we're going to reset the head and tail, clean
- // up such a block now, if it exists.
- blockp := b.spine.Load().lookup(uintptr(top))
- block := blockp.Load()
- if block != nil {
- // Check the popped value.
- if block.popped.Load() == 0 {
- // popped should never be zero because that means we have
- // pushed at least one value but not yet popped if this
- // block pointer is not nil.
- throw("span set block with unpopped elements found in reset")
- }
- if block.popped.Load() == spanSetBlockEntries {
- // popped should also never be equal to spanSetBlockEntries
- // because the last popper should have made the block pointer
- // in this slot nil.
- throw("fully empty unfreed span set block found in reset")
- }
-
- // Clear the pointer to the block.
- blockp.StoreNoWB(nil)
-
- // Return the block to the block pool.
- spanSetBlockPool.free(block)
- }
- }
- b.index.reset()
- b.spineLen.Store(0)
-}
-
-// atomicSpanSetSpinePointer is an atomically-accessed spanSetSpinePointer.
-//
-// It has the same semantics as atomic.UnsafePointer.
-type atomicSpanSetSpinePointer struct {
- a atomic.UnsafePointer
-}
-
-// Loads the spanSetSpinePointer and returns it.
-//
-// It has the same semantics as atomic.UnsafePointer.
-func (s *atomicSpanSetSpinePointer) Load() spanSetSpinePointer {
- return spanSetSpinePointer{s.a.Load()}
-}
-
-// Stores the spanSetSpinePointer.
-//
-// It has the same semantics as atomic.UnsafePointer.
-func (s *atomicSpanSetSpinePointer) StoreNoWB(p spanSetSpinePointer) {
- s.a.StoreNoWB(p.p)
-}
-
-// spanSetSpinePointer represents a pointer to a contiguous block of atomic.Pointer[spanSetBlock].
-type spanSetSpinePointer struct {
- p unsafe.Pointer
-}
-
-// lookup returns &s[idx].
-func (s spanSetSpinePointer) lookup(idx uintptr) *atomic.Pointer[spanSetBlock] {
- return (*atomic.Pointer[spanSetBlock])(add(unsafe.Pointer(s.p), goarch.PtrSize*idx))
-}
-
-// spanSetBlockPool is a global pool of spanSetBlocks.
-var spanSetBlockPool spanSetBlockAlloc
-
-// spanSetBlockAlloc represents a concurrent pool of spanSetBlocks.
-type spanSetBlockAlloc struct {
- stack lfstack
-}
-
-// alloc tries to grab a spanSetBlock out of the pool, and if it fails
-// persistentallocs a new one and returns it.
-func (p *spanSetBlockAlloc) alloc() *spanSetBlock {
- if s := (*spanSetBlock)(p.stack.pop()); s != nil {
- return s
- }
- return (*spanSetBlock)(persistentalloc(unsafe.Sizeof(spanSetBlock{}), cpu.CacheLineSize, &memstats.gcMiscSys))
-}
-
-// free returns a spanSetBlock back to the pool.
-func (p *spanSetBlockAlloc) free(block *spanSetBlock) {
- block.popped.Store(0)
- p.stack.push(&block.lfnode)
-}
-
-// haidTailIndex represents a combined 32-bit head and 32-bit tail
-// of a queue into a single 64-bit value.
-type headTailIndex uint64
-
-// makeHeadTailIndex creates a headTailIndex value from a separate
-// head and tail.
-func makeHeadTailIndex(head, tail uint32) headTailIndex {
- return headTailIndex(uint64(head)<<32 | uint64(tail))
-}
-
-// head returns the head of a headTailIndex value.
-func (h headTailIndex) head() uint32 {
- return uint32(h >> 32)
-}
-
-// tail returns the tail of a headTailIndex value.
-func (h headTailIndex) tail() uint32 {
- return uint32(h)
-}
-
-// split splits the headTailIndex value into its parts.
-func (h headTailIndex) split() (head uint32, tail uint32) {
- return h.head(), h.tail()
-}
-
-// atomicHeadTailIndex is an atomically-accessed headTailIndex.
-type atomicHeadTailIndex struct {
- u atomic.Uint64
-}
-
-// load atomically reads a headTailIndex value.
-func (h *atomicHeadTailIndex) load() headTailIndex {
- return headTailIndex(h.u.Load())
-}
-
-// cas atomically compares-and-swaps a headTailIndex value.
-func (h *atomicHeadTailIndex) cas(old, new headTailIndex) bool {
- return h.u.CompareAndSwap(uint64(old), uint64(new))
-}
-
-// incHead atomically increments the head of a headTailIndex.
-func (h *atomicHeadTailIndex) incHead() headTailIndex {
- return headTailIndex(h.u.Add(1 << 32))
-}
-
-// decHead atomically decrements the head of a headTailIndex.
-func (h *atomicHeadTailIndex) decHead() headTailIndex {
- return headTailIndex(h.u.Add(-(1 << 32)))
-}
-
-// incTail atomically increments the tail of a headTailIndex.
-func (h *atomicHeadTailIndex) incTail() headTailIndex {
- ht := headTailIndex(h.u.Add(1))
- // Check for overflow.
- if ht.tail() == 0 {
- print("runtime: head = ", ht.head(), ", tail = ", ht.tail(), "\n")
- throw("headTailIndex overflow")
- }
- return ht
-}
-
-// reset clears the headTailIndex to (0, 0).
-func (h *atomicHeadTailIndex) reset() {
- h.u.Store(0)
-}
-
-// atomicMSpanPointer is an atomic.Pointer[mspan]. Can't use generics because it's NotInHeap.
-type atomicMSpanPointer struct {
- p atomic.UnsafePointer
-}
-
-// Load returns the *mspan.
-func (p *atomicMSpanPointer) Load() *mspan {
- return (*mspan)(p.p.Load())
-}
-
-// Store stores an *mspan.
-func (p *atomicMSpanPointer) StoreNoWB(s *mspan) {
- p.p.StoreNoWB(unsafe.Pointer(s))
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mstats.go b/contrib/go/_std_1.20/src/runtime/mstats.go
deleted file mode 100644
index 3a5273f361..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mstats.go
+++ /dev/null
@@ -1,903 +0,0 @@
-// Copyright 2009 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.
-
-// Memory statistics
-
-package runtime
-
-import (
- "runtime/internal/atomic"
- "unsafe"
-)
-
-type mstats struct {
- // Statistics about malloc heap.
- heapStats consistentHeapStats
-
- // Statistics about stacks.
- stacks_sys sysMemStat // only counts newosproc0 stack in mstats; differs from MemStats.StackSys
-
- // Statistics about allocation of low-level fixed-size structures.
- mspan_sys sysMemStat
- mcache_sys sysMemStat
- buckhash_sys sysMemStat // profiling bucket hash table
-
- // Statistics about GC overhead.
- gcMiscSys sysMemStat // updated atomically or during STW
-
- // Miscellaneous statistics.
- other_sys sysMemStat // updated atomically or during STW
-
- // Statistics about the garbage collector.
-
- // Protected by mheap or stopping the world during GC.
- last_gc_unix uint64 // last gc (in unix time)
- pause_total_ns uint64
- pause_ns [256]uint64 // circular buffer of recent gc pause lengths
- pause_end [256]uint64 // circular buffer of recent gc end times (nanoseconds since 1970)
- numgc uint32
- numforcedgc uint32 // number of user-forced GCs
- gc_cpu_fraction float64 // fraction of CPU time used by GC
-
- last_gc_nanotime uint64 // last gc (monotonic time)
- lastHeapInUse uint64 // heapInUse at mark termination of the previous GC
-
- enablegc bool
-
- // gcPauseDist represents the distribution of all GC-related
- // application pauses in the runtime.
- //
- // Each individual pause is counted separately, unlike pause_ns.
- gcPauseDist timeHistogram
-}
-
-var memstats mstats
-
-// A MemStats records statistics about the memory allocator.
-type MemStats struct {
- // General statistics.
-
- // Alloc is bytes of allocated heap objects.
- //
- // This is the same as HeapAlloc (see below).
- Alloc uint64
-
- // TotalAlloc is cumulative bytes allocated for heap objects.
- //
- // TotalAlloc increases as heap objects are allocated, but
- // unlike Alloc and HeapAlloc, it does not decrease when
- // objects are freed.
- TotalAlloc uint64
-
- // Sys is the total bytes of memory obtained from the OS.
- //
- // Sys is the sum of the XSys fields below. Sys measures the
- // virtual address space reserved by the Go runtime for the
- // heap, stacks, and other internal data structures. It's
- // likely that not all of the virtual address space is backed
- // by physical memory at any given moment, though in general
- // it all was at some point.
- Sys uint64
-
- // Lookups is the number of pointer lookups performed by the
- // runtime.
- //
- // This is primarily useful for debugging runtime internals.
- Lookups uint64
-
- // Mallocs is the cumulative count of heap objects allocated.
- // The number of live objects is Mallocs - Frees.
- Mallocs uint64
-
- // Frees is the cumulative count of heap objects freed.
- Frees uint64
-
- // Heap memory statistics.
- //
- // Interpreting the heap statistics requires some knowledge of
- // how Go organizes memory. Go divides the virtual address
- // space of the heap into "spans", which are contiguous
- // regions of memory 8K or larger. A span may be in one of
- // three states:
- //
- // An "idle" span contains no objects or other data. The
- // physical memory backing an idle span can be released back
- // to the OS (but the virtual address space never is), or it
- // can be converted into an "in use" or "stack" span.
- //
- // An "in use" span contains at least one heap object and may
- // have free space available to allocate more heap objects.
- //
- // A "stack" span is used for goroutine stacks. Stack spans
- // are not considered part of the heap. A span can change
- // between heap and stack memory; it is never used for both
- // simultaneously.
-
- // HeapAlloc is bytes of allocated heap objects.
- //
- // "Allocated" heap objects include all reachable objects, as
- // well as unreachable objects that the garbage collector has
- // not yet freed. Specifically, HeapAlloc increases as heap
- // objects are allocated and decreases as the heap is swept
- // and unreachable objects are freed. Sweeping occurs
- // incrementally between GC cycles, so these two processes
- // occur simultaneously, and as a result HeapAlloc tends to
- // change smoothly (in contrast with the sawtooth that is
- // typical of stop-the-world garbage collectors).
- HeapAlloc uint64
-
- // HeapSys is bytes of heap memory obtained from the OS.
- //
- // HeapSys measures the amount of virtual address space
- // reserved for the heap. This includes virtual address space
- // that has been reserved but not yet used, which consumes no
- // physical memory, but tends to be small, as well as virtual
- // address space for which the physical memory has been
- // returned to the OS after it became unused (see HeapReleased
- // for a measure of the latter).
- //
- // HeapSys estimates the largest size the heap has had.
- HeapSys uint64
-
- // HeapIdle is bytes in idle (unused) spans.
- //
- // Idle spans have no objects in them. These spans could be
- // (and may already have been) returned to the OS, or they can
- // be reused for heap allocations, or they can be reused as
- // stack memory.
- //
- // HeapIdle minus HeapReleased estimates the amount of memory
- // that could be returned to the OS, but is being retained by
- // the runtime so it can grow the heap without requesting more
- // memory from the OS. If this difference is significantly
- // larger than the heap size, it indicates there was a recent
- // transient spike in live heap size.
- HeapIdle uint64
-
- // HeapInuse is bytes in in-use spans.
- //
- // In-use spans have at least one object in them. These spans
- // can only be used for other objects of roughly the same
- // size.
- //
- // HeapInuse minus HeapAlloc estimates the amount of memory
- // that has been dedicated to particular size classes, but is
- // not currently being used. This is an upper bound on
- // fragmentation, but in general this memory can be reused
- // efficiently.
- HeapInuse uint64
-
- // HeapReleased is bytes of physical memory returned to the OS.
- //
- // This counts heap memory from idle spans that was returned
- // to the OS and has not yet been reacquired for the heap.
- HeapReleased uint64
-
- // HeapObjects is the number of allocated heap objects.
- //
- // Like HeapAlloc, this increases as objects are allocated and
- // decreases as the heap is swept and unreachable objects are
- // freed.
- HeapObjects uint64
-
- // Stack memory statistics.
- //
- // Stacks are not considered part of the heap, but the runtime
- // can reuse a span of heap memory for stack memory, and
- // vice-versa.
-
- // StackInuse is bytes in stack spans.
- //
- // In-use stack spans have at least one stack in them. These
- // spans can only be used for other stacks of the same size.
- //
- // There is no StackIdle because unused stack spans are
- // returned to the heap (and hence counted toward HeapIdle).
- StackInuse uint64
-
- // StackSys is bytes of stack memory obtained from the OS.
- //
- // StackSys is StackInuse, plus any memory obtained directly
- // from the OS for OS thread stacks (which should be minimal).
- StackSys uint64
-
- // Off-heap memory statistics.
- //
- // The following statistics measure runtime-internal
- // structures that are not allocated from heap memory (usually
- // because they are part of implementing the heap). Unlike
- // heap or stack memory, any memory allocated to these
- // structures is dedicated to these structures.
- //
- // These are primarily useful for debugging runtime memory
- // overheads.
-
- // MSpanInuse is bytes of allocated mspan structures.
- MSpanInuse uint64
-
- // MSpanSys is bytes of memory obtained from the OS for mspan
- // structures.
- MSpanSys uint64
-
- // MCacheInuse is bytes of allocated mcache structures.
- MCacheInuse uint64
-
- // MCacheSys is bytes of memory obtained from the OS for
- // mcache structures.
- MCacheSys uint64
-
- // BuckHashSys is bytes of memory in profiling bucket hash tables.
- BuckHashSys uint64
-
- // GCSys is bytes of memory in garbage collection metadata.
- GCSys uint64
-
- // OtherSys is bytes of memory in miscellaneous off-heap
- // runtime allocations.
- OtherSys uint64
-
- // Garbage collector statistics.
-
- // NextGC is the target heap size of the next GC cycle.
- //
- // The garbage collector's goal is to keep HeapAlloc ≤ NextGC.
- // At the end of each GC cycle, the target for the next cycle
- // is computed based on the amount of reachable data and the
- // value of GOGC.
- NextGC uint64
-
- // LastGC is the time the last garbage collection finished, as
- // nanoseconds since 1970 (the UNIX epoch).
- LastGC uint64
-
- // PauseTotalNs is the cumulative nanoseconds in GC
- // stop-the-world pauses since the program started.
- //
- // During a stop-the-world pause, all goroutines are paused
- // and only the garbage collector can run.
- PauseTotalNs uint64
-
- // PauseNs is a circular buffer of recent GC stop-the-world
- // pause times in nanoseconds.
- //
- // The most recent pause is at PauseNs[(NumGC+255)%256]. In
- // general, PauseNs[N%256] records the time paused in the most
- // recent N%256th GC cycle. There may be multiple pauses per
- // GC cycle; this is the sum of all pauses during a cycle.
- PauseNs [256]uint64
-
- // PauseEnd is a circular buffer of recent GC pause end times,
- // as nanoseconds since 1970 (the UNIX epoch).
- //
- // This buffer is filled the same way as PauseNs. There may be
- // multiple pauses per GC cycle; this records the end of the
- // last pause in a cycle.
- PauseEnd [256]uint64
-
- // NumGC is the number of completed GC cycles.
- NumGC uint32
-
- // NumForcedGC is the number of GC cycles that were forced by
- // the application calling the GC function.
- NumForcedGC uint32
-
- // GCCPUFraction is the fraction of this program's available
- // CPU time used by the GC since the program started.
- //
- // GCCPUFraction is expressed as a number between 0 and 1,
- // where 0 means GC has consumed none of this program's CPU. A
- // program's available CPU time is defined as the integral of
- // GOMAXPROCS since the program started. That is, if
- // GOMAXPROCS is 2 and a program has been running for 10
- // seconds, its "available CPU" is 20 seconds. GCCPUFraction
- // does not include CPU time used for write barrier activity.
- //
- // This is the same as the fraction of CPU reported by
- // GODEBUG=gctrace=1.
- GCCPUFraction float64
-
- // EnableGC indicates that GC is enabled. It is always true,
- // even if GOGC=off.
- EnableGC bool
-
- // DebugGC is currently unused.
- DebugGC bool
-
- // BySize reports per-size class allocation statistics.
- //
- // BySize[N] gives statistics for allocations of size S where
- // BySize[N-1].Size < S ≤ BySize[N].Size.
- //
- // This does not report allocations larger than BySize[60].Size.
- BySize [61]struct {
- // Size is the maximum byte size of an object in this
- // size class.
- Size uint32
-
- // Mallocs is the cumulative count of heap objects
- // allocated in this size class. The cumulative bytes
- // of allocation is Size*Mallocs. The number of live
- // objects in this size class is Mallocs - Frees.
- Mallocs uint64
-
- // Frees is the cumulative count of heap objects freed
- // in this size class.
- Frees uint64
- }
-}
-
-func init() {
- if offset := unsafe.Offsetof(memstats.heapStats); offset%8 != 0 {
- println(offset)
- throw("memstats.heapStats not aligned to 8 bytes")
- }
- // Ensure the size of heapStatsDelta causes adjacent fields/slots (e.g.
- // [3]heapStatsDelta) to be 8-byte aligned.
- if size := unsafe.Sizeof(heapStatsDelta{}); size%8 != 0 {
- println(size)
- throw("heapStatsDelta not a multiple of 8 bytes in size")
- }
-}
-
-// ReadMemStats populates m with memory allocator statistics.
-//
-// The returned memory allocator statistics are up to date as of the
-// call to ReadMemStats. This is in contrast with a heap profile,
-// which is a snapshot as of the most recently completed garbage
-// collection cycle.
-func ReadMemStats(m *MemStats) {
- stopTheWorld("read mem stats")
-
- systemstack(func() {
- readmemstats_m(m)
- })
-
- startTheWorld()
-}
-
-// readmemstats_m populates stats for internal runtime values.
-//
-// The world must be stopped.
-func readmemstats_m(stats *MemStats) {
- assertWorldStopped()
-
- // Flush mcaches to mcentral before doing anything else.
- //
- // Flushing to the mcentral may in general cause stats to
- // change as mcentral data structures are manipulated.
- systemstack(flushallmcaches)
-
- // Calculate memory allocator stats.
- // During program execution we only count number of frees and amount of freed memory.
- // Current number of alive objects in the heap and amount of alive heap memory
- // are calculated by scanning all spans.
- // Total number of mallocs is calculated as number of frees plus number of alive objects.
- // Similarly, total amount of allocated memory is calculated as amount of freed memory
- // plus amount of alive heap memory.
-
- // Collect consistent stats, which are the source-of-truth in some cases.
- var consStats heapStatsDelta
- memstats.heapStats.unsafeRead(&consStats)
-
- // Collect large allocation stats.
- totalAlloc := consStats.largeAlloc
- nMalloc := consStats.largeAllocCount
- totalFree := consStats.largeFree
- nFree := consStats.largeFreeCount
-
- // Collect per-sizeclass stats.
- var bySize [_NumSizeClasses]struct {
- Size uint32
- Mallocs uint64
- Frees uint64
- }
- for i := range bySize {
- bySize[i].Size = uint32(class_to_size[i])
-
- // Malloc stats.
- a := consStats.smallAllocCount[i]
- totalAlloc += a * uint64(class_to_size[i])
- nMalloc += a
- bySize[i].Mallocs = a
-
- // Free stats.
- f := consStats.smallFreeCount[i]
- totalFree += f * uint64(class_to_size[i])
- nFree += f
- bySize[i].Frees = f
- }
-
- // Account for tiny allocations.
- // For historical reasons, MemStats includes tiny allocations
- // in both the total free and total alloc count. This double-counts
- // memory in some sense because their tiny allocation block is also
- // counted. Tracking the lifetime of individual tiny allocations is
- // currently not done because it would be too expensive.
- nFree += consStats.tinyAllocCount
- nMalloc += consStats.tinyAllocCount
-
- // Calculate derived stats.
-
- stackInUse := uint64(consStats.inStacks)
- gcWorkBufInUse := uint64(consStats.inWorkBufs)
- gcProgPtrScalarBitsInUse := uint64(consStats.inPtrScalarBits)
-
- totalMapped := gcController.heapInUse.load() + gcController.heapFree.load() + gcController.heapReleased.load() +
- memstats.stacks_sys.load() + memstats.mspan_sys.load() + memstats.mcache_sys.load() +
- memstats.buckhash_sys.load() + memstats.gcMiscSys.load() + memstats.other_sys.load() +
- stackInUse + gcWorkBufInUse + gcProgPtrScalarBitsInUse
-
- heapGoal := gcController.heapGoal()
-
- // The world is stopped, so the consistent stats (after aggregation)
- // should be identical to some combination of memstats. In particular:
- //
- // * memstats.heapInUse == inHeap
- // * memstats.heapReleased == released
- // * memstats.heapInUse + memstats.heapFree == committed - inStacks - inWorkBufs - inPtrScalarBits
- // * memstats.totalAlloc == totalAlloc
- // * memstats.totalFree == totalFree
- //
- // Check if that's actually true.
- //
- // TODO(mknyszek): Maybe don't throw here. It would be bad if a
- // bug in otherwise benign accounting caused the whole application
- // to crash.
- if gcController.heapInUse.load() != uint64(consStats.inHeap) {
- print("runtime: heapInUse=", gcController.heapInUse.load(), "\n")
- print("runtime: consistent value=", consStats.inHeap, "\n")
- throw("heapInUse and consistent stats are not equal")
- }
- if gcController.heapReleased.load() != uint64(consStats.released) {
- print("runtime: heapReleased=", gcController.heapReleased.load(), "\n")
- print("runtime: consistent value=", consStats.released, "\n")
- throw("heapReleased and consistent stats are not equal")
- }
- heapRetained := gcController.heapInUse.load() + gcController.heapFree.load()
- consRetained := uint64(consStats.committed - consStats.inStacks - consStats.inWorkBufs - consStats.inPtrScalarBits)
- if heapRetained != consRetained {
- print("runtime: global value=", heapRetained, "\n")
- print("runtime: consistent value=", consRetained, "\n")
- throw("measures of the retained heap are not equal")
- }
- if gcController.totalAlloc.Load() != totalAlloc {
- print("runtime: totalAlloc=", gcController.totalAlloc.Load(), "\n")
- print("runtime: consistent value=", totalAlloc, "\n")
- throw("totalAlloc and consistent stats are not equal")
- }
- if gcController.totalFree.Load() != totalFree {
- print("runtime: totalFree=", gcController.totalFree.Load(), "\n")
- print("runtime: consistent value=", totalFree, "\n")
- throw("totalFree and consistent stats are not equal")
- }
- // Also check that mappedReady lines up with totalMapped - released.
- // This isn't really the same type of "make sure consistent stats line up" situation,
- // but this is an opportune time to check.
- if gcController.mappedReady.Load() != totalMapped-uint64(consStats.released) {
- print("runtime: mappedReady=", gcController.mappedReady.Load(), "\n")
- print("runtime: totalMapped=", totalMapped, "\n")
- print("runtime: released=", uint64(consStats.released), "\n")
- print("runtime: totalMapped-released=", totalMapped-uint64(consStats.released), "\n")
- throw("mappedReady and other memstats are not equal")
- }
-
- // We've calculated all the values we need. Now, populate stats.
-
- stats.Alloc = totalAlloc - totalFree
- stats.TotalAlloc = totalAlloc
- stats.Sys = totalMapped
- stats.Mallocs = nMalloc
- stats.Frees = nFree
- stats.HeapAlloc = totalAlloc - totalFree
- stats.HeapSys = gcController.heapInUse.load() + gcController.heapFree.load() + gcController.heapReleased.load()
- // By definition, HeapIdle is memory that was mapped
- // for the heap but is not currently used to hold heap
- // objects. It also specifically is memory that can be
- // used for other purposes, like stacks, but this memory
- // is subtracted out of HeapSys before it makes that
- // transition. Put another way:
- //
- // HeapSys = bytes allocated from the OS for the heap - bytes ultimately used for non-heap purposes
- // HeapIdle = bytes allocated from the OS for the heap - bytes ultimately used for any purpose
- //
- // or
- //
- // HeapSys = sys - stacks_inuse - gcWorkBufInUse - gcProgPtrScalarBitsInUse
- // HeapIdle = sys - stacks_inuse - gcWorkBufInUse - gcProgPtrScalarBitsInUse - heapInUse
- //
- // => HeapIdle = HeapSys - heapInUse = heapFree + heapReleased
- stats.HeapIdle = gcController.heapFree.load() + gcController.heapReleased.load()
- stats.HeapInuse = gcController.heapInUse.load()
- stats.HeapReleased = gcController.heapReleased.load()
- stats.HeapObjects = nMalloc - nFree
- stats.StackInuse = stackInUse
- // memstats.stacks_sys is only memory mapped directly for OS stacks.
- // Add in heap-allocated stack memory for user consumption.
- stats.StackSys = stackInUse + memstats.stacks_sys.load()
- stats.MSpanInuse = uint64(mheap_.spanalloc.inuse)
- stats.MSpanSys = memstats.mspan_sys.load()
- stats.MCacheInuse = uint64(mheap_.cachealloc.inuse)
- stats.MCacheSys = memstats.mcache_sys.load()
- stats.BuckHashSys = memstats.buckhash_sys.load()
- // MemStats defines GCSys as an aggregate of all memory related
- // to the memory management system, but we track this memory
- // at a more granular level in the runtime.
- stats.GCSys = memstats.gcMiscSys.load() + gcWorkBufInUse + gcProgPtrScalarBitsInUse
- stats.OtherSys = memstats.other_sys.load()
- stats.NextGC = heapGoal
- stats.LastGC = memstats.last_gc_unix
- stats.PauseTotalNs = memstats.pause_total_ns
- stats.PauseNs = memstats.pause_ns
- stats.PauseEnd = memstats.pause_end
- stats.NumGC = memstats.numgc
- stats.NumForcedGC = memstats.numforcedgc
- stats.GCCPUFraction = memstats.gc_cpu_fraction
- stats.EnableGC = true
-
- // stats.BySize and bySize might not match in length.
- // That's OK, stats.BySize cannot change due to backwards
- // compatibility issues. copy will copy the minimum amount
- // of values between the two of them.
- copy(stats.BySize[:], bySize[:])
-}
-
-//go:linkname readGCStats runtime/debug.readGCStats
-func readGCStats(pauses *[]uint64) {
- systemstack(func() {
- readGCStats_m(pauses)
- })
-}
-
-// readGCStats_m must be called on the system stack because it acquires the heap
-// lock. See mheap for details.
-//
-//go:systemstack
-func readGCStats_m(pauses *[]uint64) {
- p := *pauses
- // Calling code in runtime/debug should make the slice large enough.
- if cap(p) < len(memstats.pause_ns)+3 {
- throw("short slice passed to readGCStats")
- }
-
- // Pass back: pauses, pause ends, last gc (absolute time), number of gc, total pause ns.
- lock(&mheap_.lock)
-
- n := memstats.numgc
- if n > uint32(len(memstats.pause_ns)) {
- n = uint32(len(memstats.pause_ns))
- }
-
- // The pause buffer is circular. The most recent pause is at
- // pause_ns[(numgc-1)%len(pause_ns)], and then backward
- // from there to go back farther in time. We deliver the times
- // most recent first (in p[0]).
- p = p[:cap(p)]
- for i := uint32(0); i < n; i++ {
- j := (memstats.numgc - 1 - i) % uint32(len(memstats.pause_ns))
- p[i] = memstats.pause_ns[j]
- p[n+i] = memstats.pause_end[j]
- }
-
- p[n+n] = memstats.last_gc_unix
- p[n+n+1] = uint64(memstats.numgc)
- p[n+n+2] = memstats.pause_total_ns
- unlock(&mheap_.lock)
- *pauses = p[:n+n+3]
-}
-
-// flushmcache flushes the mcache of allp[i].
-//
-// The world must be stopped.
-//
-//go:nowritebarrier
-func flushmcache(i int) {
- assertWorldStopped()
-
- p := allp[i]
- c := p.mcache
- if c == nil {
- return
- }
- c.releaseAll()
- stackcache_clear(c)
-}
-
-// flushallmcaches flushes the mcaches of all Ps.
-//
-// The world must be stopped.
-//
-//go:nowritebarrier
-func flushallmcaches() {
- assertWorldStopped()
-
- for i := 0; i < int(gomaxprocs); i++ {
- flushmcache(i)
- }
-}
-
-// sysMemStat represents a global system statistic that is managed atomically.
-//
-// This type must structurally be a uint64 so that mstats aligns with MemStats.
-type sysMemStat uint64
-
-// load atomically reads the value of the stat.
-//
-// Must be nosplit as it is called in runtime initialization, e.g. newosproc0.
-//
-//go:nosplit
-func (s *sysMemStat) load() uint64 {
- return atomic.Load64((*uint64)(s))
-}
-
-// add atomically adds the sysMemStat by n.
-//
-// Must be nosplit as it is called in runtime initialization, e.g. newosproc0.
-//
-//go:nosplit
-func (s *sysMemStat) add(n int64) {
- val := atomic.Xadd64((*uint64)(s), n)
- if (n > 0 && int64(val) < n) || (n < 0 && int64(val)+n < n) {
- print("runtime: val=", val, " n=", n, "\n")
- throw("sysMemStat overflow")
- }
-}
-
-// heapStatsDelta contains deltas of various runtime memory statistics
-// that need to be updated together in order for them to be kept
-// consistent with one another.
-type heapStatsDelta struct {
- // Memory stats.
- committed int64 // byte delta of memory committed
- released int64 // byte delta of released memory generated
- inHeap int64 // byte delta of memory placed in the heap
- inStacks int64 // byte delta of memory reserved for stacks
- inWorkBufs int64 // byte delta of memory reserved for work bufs
- inPtrScalarBits int64 // byte delta of memory reserved for unrolled GC prog bits
-
- // Allocator stats.
- //
- // These are all uint64 because they're cumulative, and could quickly wrap
- // around otherwise.
- tinyAllocCount uint64 // number of tiny allocations
- largeAlloc uint64 // bytes allocated for large objects
- largeAllocCount uint64 // number of large object allocations
- smallAllocCount [_NumSizeClasses]uint64 // number of allocs for small objects
- largeFree uint64 // bytes freed for large objects (>maxSmallSize)
- largeFreeCount uint64 // number of frees for large objects (>maxSmallSize)
- smallFreeCount [_NumSizeClasses]uint64 // number of frees for small objects (<=maxSmallSize)
-
- // NOTE: This struct must be a multiple of 8 bytes in size because it
- // is stored in an array. If it's not, atomic accesses to the above
- // fields may be unaligned and fail on 32-bit platforms.
-}
-
-// merge adds in the deltas from b into a.
-func (a *heapStatsDelta) merge(b *heapStatsDelta) {
- a.committed += b.committed
- a.released += b.released
- a.inHeap += b.inHeap
- a.inStacks += b.inStacks
- a.inWorkBufs += b.inWorkBufs
- a.inPtrScalarBits += b.inPtrScalarBits
-
- a.tinyAllocCount += b.tinyAllocCount
- a.largeAlloc += b.largeAlloc
- a.largeAllocCount += b.largeAllocCount
- for i := range b.smallAllocCount {
- a.smallAllocCount[i] += b.smallAllocCount[i]
- }
- a.largeFree += b.largeFree
- a.largeFreeCount += b.largeFreeCount
- for i := range b.smallFreeCount {
- a.smallFreeCount[i] += b.smallFreeCount[i]
- }
-}
-
-// consistentHeapStats represents a set of various memory statistics
-// whose updates must be viewed completely to get a consistent
-// state of the world.
-//
-// To write updates to memory stats use the acquire and release
-// methods. To obtain a consistent global snapshot of these statistics,
-// use read.
-type consistentHeapStats struct {
- // stats is a ring buffer of heapStatsDelta values.
- // Writers always atomically update the delta at index gen.
- //
- // Readers operate by rotating gen (0 -> 1 -> 2 -> 0 -> ...)
- // and synchronizing with writers by observing each P's
- // statsSeq field. If the reader observes a P not writing,
- // it can be sure that it will pick up the new gen value the
- // next time it writes.
- //
- // The reader then takes responsibility by clearing space
- // in the ring buffer for the next reader to rotate gen to
- // that space (i.e. it merges in values from index (gen-2) mod 3
- // to index (gen-1) mod 3, then clears the former).
- //
- // Note that this means only one reader can be reading at a time.
- // There is no way for readers to synchronize.
- //
- // This process is why we need a ring buffer of size 3 instead
- // of 2: one is for the writers, one contains the most recent
- // data, and the last one is clear so writers can begin writing
- // to it the moment gen is updated.
- stats [3]heapStatsDelta
-
- // gen represents the current index into which writers
- // are writing, and can take on the value of 0, 1, or 2.
- gen atomic.Uint32
-
- // noPLock is intended to provide mutual exclusion for updating
- // stats when no P is available. It does not block other writers
- // with a P, only other writers without a P and the reader. Because
- // stats are usually updated when a P is available, contention on
- // this lock should be minimal.
- noPLock mutex
-}
-
-// acquire returns a heapStatsDelta to be updated. In effect,
-// it acquires the shard for writing. release must be called
-// as soon as the relevant deltas are updated.
-//
-// The returned heapStatsDelta must be updated atomically.
-//
-// The caller's P must not change between acquire and
-// release. This also means that the caller should not
-// acquire a P or release its P in between. A P also must
-// not acquire a given consistentHeapStats if it hasn't
-// yet released it.
-//
-// nosplit because a stack growth in this function could
-// lead to a stack allocation that could reenter the
-// function.
-//
-//go:nosplit
-func (m *consistentHeapStats) acquire() *heapStatsDelta {
- if pp := getg().m.p.ptr(); pp != nil {
- seq := pp.statsSeq.Add(1)
- if seq%2 == 0 {
- // Should have been incremented to odd.
- print("runtime: seq=", seq, "\n")
- throw("bad sequence number")
- }
- } else {
- lock(&m.noPLock)
- }
- gen := m.gen.Load() % 3
- return &m.stats[gen]
-}
-
-// release indicates that the writer is done modifying
-// the delta. The value returned by the corresponding
-// acquire must no longer be accessed or modified after
-// release is called.
-//
-// The caller's P must not change between acquire and
-// release. This also means that the caller should not
-// acquire a P or release its P in between.
-//
-// nosplit because a stack growth in this function could
-// lead to a stack allocation that causes another acquire
-// before this operation has completed.
-//
-//go:nosplit
-func (m *consistentHeapStats) release() {
- if pp := getg().m.p.ptr(); pp != nil {
- seq := pp.statsSeq.Add(1)
- if seq%2 != 0 {
- // Should have been incremented to even.
- print("runtime: seq=", seq, "\n")
- throw("bad sequence number")
- }
- } else {
- unlock(&m.noPLock)
- }
-}
-
-// unsafeRead aggregates the delta for this shard into out.
-//
-// Unsafe because it does so without any synchronization. The
-// world must be stopped.
-func (m *consistentHeapStats) unsafeRead(out *heapStatsDelta) {
- assertWorldStopped()
-
- for i := range m.stats {
- out.merge(&m.stats[i])
- }
-}
-
-// unsafeClear clears the shard.
-//
-// Unsafe because the world must be stopped and values should
-// be donated elsewhere before clearing.
-func (m *consistentHeapStats) unsafeClear() {
- assertWorldStopped()
-
- for i := range m.stats {
- m.stats[i] = heapStatsDelta{}
- }
-}
-
-// read takes a globally consistent snapshot of m
-// and puts the aggregated value in out. Even though out is a
-// heapStatsDelta, the resulting values should be complete and
-// valid statistic values.
-//
-// Not safe to call concurrently. The world must be stopped
-// or metricsSema must be held.
-func (m *consistentHeapStats) read(out *heapStatsDelta) {
- // Getting preempted after this point is not safe because
- // we read allp. We need to make sure a STW can't happen
- // so it doesn't change out from under us.
- mp := acquirem()
-
- // Get the current generation. We can be confident that this
- // will not change since read is serialized and is the only
- // one that modifies currGen.
- currGen := m.gen.Load()
- prevGen := currGen - 1
- if currGen == 0 {
- prevGen = 2
- }
-
- // Prevent writers without a P from writing while we update gen.
- lock(&m.noPLock)
-
- // Rotate gen, effectively taking a snapshot of the state of
- // these statistics at the point of the exchange by moving
- // writers to the next set of deltas.
- //
- // This exchange is safe to do because we won't race
- // with anyone else trying to update this value.
- m.gen.Swap((currGen + 1) % 3)
-
- // Allow P-less writers to continue. They'll be writing to the
- // next generation now.
- unlock(&m.noPLock)
-
- for _, p := range allp {
- // Spin until there are no more writers.
- for p.statsSeq.Load()%2 != 0 {
- }
- }
-
- // At this point we've observed that each sequence
- // number is even, so any future writers will observe
- // the new gen value. That means it's safe to read from
- // the other deltas in the stats buffer.
-
- // Perform our responsibilities and free up
- // stats[prevGen] for the next time we want to take
- // a snapshot.
- m.stats[currGen].merge(&m.stats[prevGen])
- m.stats[prevGen] = heapStatsDelta{}
-
- // Finally, copy out the complete delta.
- *out = m.stats[currGen]
-
- releasem(mp)
-}
-
-type cpuStats struct {
- // All fields are CPU time in nanoseconds computed by comparing
- // calls of nanotime. This means they're all overestimates, because
- // they don't accurately compute on-CPU time (so some of the time
- // could be spent scheduled away by the OS).
-
- gcAssistTime int64 // GC assists
- gcDedicatedTime int64 // GC dedicated mark workers + pauses
- gcIdleTime int64 // GC idle mark workers
- gcPauseTime int64 // GC pauses (all GOMAXPROCS, even if just 1 is running)
- gcTotalTime int64
-
- scavengeAssistTime int64 // background scavenger
- scavengeBgTime int64 // scavenge assists
- scavengeTotalTime int64
-
- idleTime int64 // Time Ps spent in _Pidle.
- userTime int64 // Time Ps spent in _Prunning or _Psyscall that's not any of the above.
-
- totalTime int64 // GOMAXPROCS * (monotonic wall clock time elapsed)
-}
diff --git a/contrib/go/_std_1.20/src/runtime/mwbbuf.go b/contrib/go/_std_1.20/src/runtime/mwbbuf.go
deleted file mode 100644
index 3b7cbf8f1f..0000000000
--- a/contrib/go/_std_1.20/src/runtime/mwbbuf.go
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright 2017 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.
-
-// This implements the write barrier buffer. The write barrier itself
-// is gcWriteBarrier and is implemented in assembly.
-//
-// See mbarrier.go for algorithmic details on the write barrier. This
-// file deals only with the buffer.
-//
-// The write barrier has a fast path and a slow path. The fast path
-// simply enqueues to a per-P write barrier buffer. It's written in
-// assembly and doesn't clobber any general purpose registers, so it
-// doesn't have the usual overheads of a Go call.
-//
-// When the buffer fills up, the write barrier invokes the slow path
-// (wbBufFlush) to flush the buffer to the GC work queues. In this
-// path, since the compiler didn't spill registers, we spill *all*
-// registers and disallow any GC safe points that could observe the
-// stack frame (since we don't know the types of the spilled
-// registers).
-
-package runtime
-
-import (
- "internal/goarch"
- "runtime/internal/atomic"
- "unsafe"
-)
-
-// testSmallBuf forces a small write barrier buffer to stress write
-// barrier flushing.
-const testSmallBuf = false
-
-// wbBuf is a per-P buffer of pointers queued by the write barrier.
-// This buffer is flushed to the GC workbufs when it fills up and on
-// various GC transitions.
-//
-// This is closely related to a "sequential store buffer" (SSB),
-// except that SSBs are usually used for maintaining remembered sets,
-// while this is used for marking.
-type wbBuf struct {
- // next points to the next slot in buf. It must not be a
- // pointer type because it can point past the end of buf and
- // must be updated without write barriers.
- //
- // This is a pointer rather than an index to optimize the
- // write barrier assembly.
- next uintptr
-
- // end points to just past the end of buf. It must not be a
- // pointer type because it points past the end of buf and must
- // be updated without write barriers.
- end uintptr
-
- // buf stores a series of pointers to execute write barriers
- // on. This must be a multiple of wbBufEntryPointers because
- // the write barrier only checks for overflow once per entry.
- buf [wbBufEntryPointers * wbBufEntries]uintptr
-}
-
-const (
- // wbBufEntries is the number of write barriers between
- // flushes of the write barrier buffer.
- //
- // This trades latency for throughput amortization. Higher
- // values amortize flushing overhead more, but increase the
- // latency of flushing. Higher values also increase the cache
- // footprint of the buffer.
- //
- // TODO: What is the latency cost of this? Tune this value.
- wbBufEntries = 256
-
- // wbBufEntryPointers is the number of pointers added to the
- // buffer by each write barrier.
- wbBufEntryPointers = 2
-)
-
-// reset empties b by resetting its next and end pointers.
-func (b *wbBuf) reset() {
- start := uintptr(unsafe.Pointer(&b.buf[0]))
- b.next = start
- if writeBarrier.cgo {
- // Effectively disable the buffer by forcing a flush
- // on every barrier.
- b.end = uintptr(unsafe.Pointer(&b.buf[wbBufEntryPointers]))
- } else if testSmallBuf {
- // For testing, allow two barriers in the buffer. If
- // we only did one, then barriers of non-heap pointers
- // would be no-ops. This lets us combine a buffered
- // barrier with a flush at a later time.
- b.end = uintptr(unsafe.Pointer(&b.buf[2*wbBufEntryPointers]))
- } else {
- b.end = start + uintptr(len(b.buf))*unsafe.Sizeof(b.buf[0])
- }
-
- if (b.end-b.next)%(wbBufEntryPointers*unsafe.Sizeof(b.buf[0])) != 0 {
- throw("bad write barrier buffer bounds")
- }
-}
-
-// discard resets b's next pointer, but not its end pointer.
-//
-// This must be nosplit because it's called by wbBufFlush.
-//
-//go:nosplit
-func (b *wbBuf) discard() {
- b.next = uintptr(unsafe.Pointer(&b.buf[0]))
-}
-
-// empty reports whether b contains no pointers.
-func (b *wbBuf) empty() bool {
- return b.next == uintptr(unsafe.Pointer(&b.buf[0]))
-}
-
-// putFast adds old and new to the write barrier buffer and returns
-// false if a flush is necessary. Callers should use this as:
-//
-// buf := &getg().m.p.ptr().wbBuf
-// if !buf.putFast(old, new) {
-// wbBufFlush(...)
-// }
-// ... actual memory write ...
-//
-// The arguments to wbBufFlush depend on whether the caller is doing
-// its own cgo pointer checks. If it is, then this can be
-// wbBufFlush(nil, 0). Otherwise, it must pass the slot address and
-// new.
-//
-// The caller must ensure there are no preemption points during the
-// above sequence. There must be no preemption points while buf is in
-// use because it is a per-P resource. There must be no preemption
-// points between the buffer put and the write to memory because this
-// could allow a GC phase change, which could result in missed write
-// barriers.
-//
-// putFast must be nowritebarrierrec to because write barriers here would
-// corrupt the write barrier buffer. It (and everything it calls, if
-// it called anything) has to be nosplit to avoid scheduling on to a
-// different P and a different buffer.
-//
-//go:nowritebarrierrec
-//go:nosplit
-func (b *wbBuf) putFast(old, new uintptr) bool {
- p := (*[2]uintptr)(unsafe.Pointer(b.next))
- p[0] = old
- p[1] = new
- b.next += 2 * goarch.PtrSize
- return b.next != b.end
-}
-
-// wbBufFlush flushes the current P's write barrier buffer to the GC
-// workbufs. It is passed the slot and value of the write barrier that
-// caused the flush so that it can implement cgocheck.
-//
-// This must not have write barriers because it is part of the write
-// barrier implementation.
-//
-// This and everything it calls must be nosplit because 1) the stack
-// contains untyped slots from gcWriteBarrier and 2) there must not be
-// a GC safe point between the write barrier test in the caller and
-// flushing the buffer.
-//
-// TODO: A "go:nosplitrec" annotation would be perfect for this.
-//
-//go:nowritebarrierrec
-//go:nosplit
-func wbBufFlush(dst *uintptr, src uintptr) {
- // Note: Every possible return from this function must reset
- // the buffer's next pointer to prevent buffer overflow.
-
- // This *must not* modify its arguments because this
- // function's argument slots do double duty in gcWriteBarrier
- // as register spill slots. Currently, not modifying the
- // arguments is sufficient to keep the spill slots unmodified
- // (which seems unlikely to change since it costs little and
- // helps with debugging).
-
- if getg().m.dying > 0 {
- // We're going down. Not much point in write barriers
- // and this way we can allow write barriers in the
- // panic path.
- getg().m.p.ptr().wbBuf.discard()
- return
- }
-
- if writeBarrier.cgo && dst != nil {
- // This must be called from the stack that did the
- // write. It's nosplit all the way down.
- cgoCheckWriteBarrier(dst, src)
- if !writeBarrier.needed {
- // We were only called for cgocheck.
- getg().m.p.ptr().wbBuf.discard()
- return
- }
- }
-
- // Switch to the system stack so we don't have to worry about
- // the untyped stack slots or safe points.
- systemstack(func() {
- wbBufFlush1(getg().m.p.ptr())
- })
-}
-
-// wbBufFlush1 flushes p's write barrier buffer to the GC work queue.
-//
-// This must not have write barriers because it is part of the write
-// barrier implementation, so this may lead to infinite loops or
-// buffer corruption.
-//
-// This must be non-preemptible because it uses the P's workbuf.
-//
-//go:nowritebarrierrec
-//go:systemstack
-func wbBufFlush1(pp *p) {
- // Get the buffered pointers.
- start := uintptr(unsafe.Pointer(&pp.wbBuf.buf[0]))
- n := (pp.wbBuf.next - start) / unsafe.Sizeof(pp.wbBuf.buf[0])
- ptrs := pp.wbBuf.buf[:n]
-
- // Poison the buffer to make extra sure nothing is enqueued
- // while we're processing the buffer.
- pp.wbBuf.next = 0
-
- if useCheckmark {
- // Slow path for checkmark mode.
- for _, ptr := range ptrs {
- shade(ptr)
- }
- pp.wbBuf.reset()
- return
- }
-
- // Mark all of the pointers in the buffer and record only the
- // pointers we greyed. We use the buffer itself to temporarily
- // record greyed pointers.
- //
- // TODO: Should scanobject/scanblock just stuff pointers into
- // the wbBuf? Then this would become the sole greying path.
- //
- // TODO: We could avoid shading any of the "new" pointers in
- // the buffer if the stack has been shaded, or even avoid
- // putting them in the buffer at all (which would double its
- // capacity). This is slightly complicated with the buffer; we
- // could track whether any un-shaded goroutine has used the
- // buffer, or just track globally whether there are any
- // un-shaded stacks and flush after each stack scan.
- gcw := &pp.gcw
- pos := 0
- for _, ptr := range ptrs {
- if ptr < minLegalPointer {
- // nil pointers are very common, especially
- // for the "old" values. Filter out these and
- // other "obvious" non-heap pointers ASAP.
- //
- // TODO: Should we filter out nils in the fast
- // path to reduce the rate of flushes?
- continue
- }
- obj, span, objIndex := findObject(ptr, 0, 0)
- if obj == 0 {
- continue
- }
- // TODO: Consider making two passes where the first
- // just prefetches the mark bits.
- mbits := span.markBitsForIndex(objIndex)
- if mbits.isMarked() {
- continue
- }
- mbits.setMarked()
-
- // Mark span.
- arena, pageIdx, pageMask := pageIndexOf(span.base())
- if arena.pageMarks[pageIdx]&pageMask == 0 {
- atomic.Or8(&arena.pageMarks[pageIdx], pageMask)
- }
-
- if span.spanclass.noscan() {
- gcw.bytesMarked += uint64(span.elemsize)
- continue
- }
- ptrs[pos] = obj
- pos++
- }
-
- // Enqueue the greyed objects.
- gcw.putBatch(ptrs[:pos])
-
- pp.wbBuf.reset()
-}
diff --git a/contrib/go/_std_1.20/src/runtime/netpoll.go b/contrib/go/_std_1.20/src/runtime/netpoll.go
deleted file mode 100644
index 5ac1f37048..0000000000
--- a/contrib/go/_std_1.20/src/runtime/netpoll.go
+++ /dev/null
@@ -1,657 +0,0 @@
-// Copyright 2013 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.
-
-//go:build unix || (js && wasm) || windows
-
-package runtime
-
-import (
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// Integrated network poller (platform-independent part).
-// A particular implementation (epoll/kqueue/port/AIX/Windows)
-// must define the following functions:
-//
-// func netpollinit()
-// Initialize the poller. Only called once.
-//
-// func netpollopen(fd uintptr, pd *pollDesc) int32
-// Arm edge-triggered notifications for fd. The pd argument is to pass
-// back to netpollready when fd is ready. Return an errno value.
-//
-// func netpollclose(fd uintptr) int32
-// Disable notifications for fd. Return an errno value.
-//
-// func netpoll(delta int64) gList
-// Poll the network. If delta < 0, block indefinitely. If delta == 0,
-// poll without blocking. If delta > 0, block for up to delta nanoseconds.
-// Return a list of goroutines built by calling netpollready.
-//
-// func netpollBreak()
-// Wake up the network poller, assumed to be blocked in netpoll.
-//
-// func netpollIsPollDescriptor(fd uintptr) bool
-// Reports whether fd is a file descriptor used by the poller.
-
-// Error codes returned by runtime_pollReset and runtime_pollWait.
-// These must match the values in internal/poll/fd_poll_runtime.go.
-const (
- pollNoError = 0 // no error
- pollErrClosing = 1 // descriptor is closed
- pollErrTimeout = 2 // I/O timeout
- pollErrNotPollable = 3 // general error polling descriptor
-)
-
-// pollDesc contains 2 binary semaphores, rg and wg, to park reader and writer
-// goroutines respectively. The semaphore can be in the following states:
-//
-// pdReady - io readiness notification is pending;
-// a goroutine consumes the notification by changing the state to pdNil.
-// pdWait - a goroutine prepares to park on the semaphore, but not yet parked;
-// the goroutine commits to park by changing the state to G pointer,
-// or, alternatively, concurrent io notification changes the state to pdReady,
-// or, alternatively, concurrent timeout/close changes the state to pdNil.
-// G pointer - the goroutine is blocked on the semaphore;
-// io notification or timeout/close changes the state to pdReady or pdNil respectively
-// and unparks the goroutine.
-// pdNil - none of the above.
-const (
- pdNil uintptr = 0
- pdReady uintptr = 1
- pdWait uintptr = 2
-)
-
-const pollBlockSize = 4 * 1024
-
-// Network poller descriptor.
-//
-// No heap pointers.
-type pollDesc struct {
- _ sys.NotInHeap
- link *pollDesc // in pollcache, protected by pollcache.lock
- fd uintptr // constant for pollDesc usage lifetime
-
- // atomicInfo holds bits from closing, rd, and wd,
- // which are only ever written while holding the lock,
- // summarized for use by netpollcheckerr,
- // which cannot acquire the lock.
- // After writing these fields under lock in a way that
- // might change the summary, code must call publishInfo
- // before releasing the lock.
- // Code that changes fields and then calls netpollunblock
- // (while still holding the lock) must call publishInfo
- // before calling netpollunblock, because publishInfo is what
- // stops netpollblock from blocking anew
- // (by changing the result of netpollcheckerr).
- // atomicInfo also holds the eventErr bit,
- // recording whether a poll event on the fd got an error;
- // atomicInfo is the only source of truth for that bit.
- atomicInfo atomic.Uint32 // atomic pollInfo
-
- // rg, wg are accessed atomically and hold g pointers.
- // (Using atomic.Uintptr here is similar to using guintptr elsewhere.)
- rg atomic.Uintptr // pdReady, pdWait, G waiting for read or pdNil
- wg atomic.Uintptr // pdReady, pdWait, G waiting for write or pdNil
-
- lock mutex // protects the following fields
- closing bool
- user uint32 // user settable cookie
- rseq uintptr // protects from stale read timers
- rt timer // read deadline timer (set if rt.f != nil)
- rd int64 // read deadline (a nanotime in the future, -1 when expired)
- wseq uintptr // protects from stale write timers
- wt timer // write deadline timer
- wd int64 // write deadline (a nanotime in the future, -1 when expired)
- self *pollDesc // storage for indirect interface. See (*pollDesc).makeArg.
-}
-
-// pollInfo is the bits needed by netpollcheckerr, stored atomically,
-// mostly duplicating state that is manipulated under lock in pollDesc.
-// The one exception is the pollEventErr bit, which is maintained only
-// in the pollInfo.
-type pollInfo uint32
-
-const (
- pollClosing = 1 << iota
- pollEventErr
- pollExpiredReadDeadline
- pollExpiredWriteDeadline
-)
-
-func (i pollInfo) closing() bool { return i&pollClosing != 0 }
-func (i pollInfo) eventErr() bool { return i&pollEventErr != 0 }
-func (i pollInfo) expiredReadDeadline() bool { return i&pollExpiredReadDeadline != 0 }
-func (i pollInfo) expiredWriteDeadline() bool { return i&pollExpiredWriteDeadline != 0 }
-
-// info returns the pollInfo corresponding to pd.
-func (pd *pollDesc) info() pollInfo {
- return pollInfo(pd.atomicInfo.Load())
-}
-
-// publishInfo updates pd.atomicInfo (returned by pd.info)
-// using the other values in pd.
-// It must be called while holding pd.lock,
-// and it must be called after changing anything
-// that might affect the info bits.
-// In practice this means after changing closing
-// or changing rd or wd from < 0 to >= 0.
-func (pd *pollDesc) publishInfo() {
- var info uint32
- if pd.closing {
- info |= pollClosing
- }
- if pd.rd < 0 {
- info |= pollExpiredReadDeadline
- }
- if pd.wd < 0 {
- info |= pollExpiredWriteDeadline
- }
-
- // Set all of x except the pollEventErr bit.
- x := pd.atomicInfo.Load()
- for !pd.atomicInfo.CompareAndSwap(x, (x&pollEventErr)|info) {
- x = pd.atomicInfo.Load()
- }
-}
-
-// setEventErr sets the result of pd.info().eventErr() to b.
-func (pd *pollDesc) setEventErr(b bool) {
- x := pd.atomicInfo.Load()
- for (x&pollEventErr != 0) != b && !pd.atomicInfo.CompareAndSwap(x, x^pollEventErr) {
- x = pd.atomicInfo.Load()
- }
-}
-
-type pollCache struct {
- lock mutex
- first *pollDesc
- // PollDesc objects must be type-stable,
- // because we can get ready notification from epoll/kqueue
- // after the descriptor is closed/reused.
- // Stale notifications are detected using seq variable,
- // seq is incremented when deadlines are changed or descriptor is reused.
-}
-
-var (
- netpollInitLock mutex
- netpollInited atomic.Uint32
-
- pollcache pollCache
- netpollWaiters atomic.Uint32
-)
-
-//go:linkname poll_runtime_pollServerInit internal/poll.runtime_pollServerInit
-func poll_runtime_pollServerInit() {
- netpollGenericInit()
-}
-
-func netpollGenericInit() {
- if netpollInited.Load() == 0 {
- lockInit(&netpollInitLock, lockRankNetpollInit)
- lock(&netpollInitLock)
- if netpollInited.Load() == 0 {
- netpollinit()
- netpollInited.Store(1)
- }
- unlock(&netpollInitLock)
- }
-}
-
-func netpollinited() bool {
- return netpollInited.Load() != 0
-}
-
-//go:linkname poll_runtime_isPollServerDescriptor internal/poll.runtime_isPollServerDescriptor
-
-// poll_runtime_isPollServerDescriptor reports whether fd is a
-// descriptor being used by netpoll.
-func poll_runtime_isPollServerDescriptor(fd uintptr) bool {
- return netpollIsPollDescriptor(fd)
-}
-
-//go:linkname poll_runtime_pollOpen internal/poll.runtime_pollOpen
-func poll_runtime_pollOpen(fd uintptr) (*pollDesc, int) {
- pd := pollcache.alloc()
- lock(&pd.lock)
- wg := pd.wg.Load()
- if wg != pdNil && wg != pdReady {
- throw("runtime: blocked write on free polldesc")
- }
- rg := pd.rg.Load()
- if rg != pdNil && rg != pdReady {
- throw("runtime: blocked read on free polldesc")
- }
- pd.fd = fd
- pd.closing = false
- pd.setEventErr(false)
- pd.rseq++
- pd.rg.Store(pdNil)
- pd.rd = 0
- pd.wseq++
- pd.wg.Store(pdNil)
- pd.wd = 0
- pd.self = pd
- pd.publishInfo()
- unlock(&pd.lock)
-
- errno := netpollopen(fd, pd)
- if errno != 0 {
- pollcache.free(pd)
- return nil, int(errno)
- }
- return pd, 0
-}
-
-//go:linkname poll_runtime_pollClose internal/poll.runtime_pollClose
-func poll_runtime_pollClose(pd *pollDesc) {
- if !pd.closing {
- throw("runtime: close polldesc w/o unblock")
- }
- wg := pd.wg.Load()
- if wg != pdNil && wg != pdReady {
- throw("runtime: blocked write on closing polldesc")
- }
- rg := pd.rg.Load()
- if rg != pdNil && rg != pdReady {
- throw("runtime: blocked read on closing polldesc")
- }
- netpollclose(pd.fd)
- pollcache.free(pd)
-}
-
-func (c *pollCache) free(pd *pollDesc) {
- lock(&c.lock)
- pd.link = c.first
- c.first = pd
- unlock(&c.lock)
-}
-
-// poll_runtime_pollReset, which is internal/poll.runtime_pollReset,
-// prepares a descriptor for polling in mode, which is 'r' or 'w'.
-// This returns an error code; the codes are defined above.
-//
-//go:linkname poll_runtime_pollReset internal/poll.runtime_pollReset
-func poll_runtime_pollReset(pd *pollDesc, mode int) int {
- errcode := netpollcheckerr(pd, int32(mode))
- if errcode != pollNoError {
- return errcode
- }
- if mode == 'r' {
- pd.rg.Store(pdNil)
- } else if mode == 'w' {
- pd.wg.Store(pdNil)
- }
- return pollNoError
-}
-
-// poll_runtime_pollWait, which is internal/poll.runtime_pollWait,
-// waits for a descriptor to be ready for reading or writing,
-// according to mode, which is 'r' or 'w'.
-// This returns an error code; the codes are defined above.
-//
-//go:linkname poll_runtime_pollWait internal/poll.runtime_pollWait
-func poll_runtime_pollWait(pd *pollDesc, mode int) int {
- errcode := netpollcheckerr(pd, int32(mode))
- if errcode != pollNoError {
- return errcode
- }
- // As for now only Solaris, illumos, and AIX use level-triggered IO.
- if GOOS == "solaris" || GOOS == "illumos" || GOOS == "aix" {
- netpollarm(pd, mode)
- }
- for !netpollblock(pd, int32(mode), false) {
- errcode = netpollcheckerr(pd, int32(mode))
- if errcode != pollNoError {
- return errcode
- }
- // Can happen if timeout has fired and unblocked us,
- // but before we had a chance to run, timeout has been reset.
- // Pretend it has not happened and retry.
- }
- return pollNoError
-}
-
-//go:linkname poll_runtime_pollWaitCanceled internal/poll.runtime_pollWaitCanceled
-func poll_runtime_pollWaitCanceled(pd *pollDesc, mode int) {
- // This function is used only on windows after a failed attempt to cancel
- // a pending async IO operation. Wait for ioready, ignore closing or timeouts.
- for !netpollblock(pd, int32(mode), true) {
- }
-}
-
-//go:linkname poll_runtime_pollSetDeadline internal/poll.runtime_pollSetDeadline
-func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) {
- lock(&pd.lock)
- if pd.closing {
- unlock(&pd.lock)
- return
- }
- rd0, wd0 := pd.rd, pd.wd
- combo0 := rd0 > 0 && rd0 == wd0
- if d > 0 {
- d += nanotime()
- if d <= 0 {
- // If the user has a deadline in the future, but the delay calculation
- // overflows, then set the deadline to the maximum possible value.
- d = 1<<63 - 1
- }
- }
- if mode == 'r' || mode == 'r'+'w' {
- pd.rd = d
- }
- if mode == 'w' || mode == 'r'+'w' {
- pd.wd = d
- }
- pd.publishInfo()
- combo := pd.rd > 0 && pd.rd == pd.wd
- rtf := netpollReadDeadline
- if combo {
- rtf = netpollDeadline
- }
- if pd.rt.f == nil {
- if pd.rd > 0 {
- pd.rt.f = rtf
- // Copy current seq into the timer arg.
- // Timer func will check the seq against current descriptor seq,
- // if they differ the descriptor was reused or timers were reset.
- pd.rt.arg = pd.makeArg()
- pd.rt.seq = pd.rseq
- resettimer(&pd.rt, pd.rd)
- }
- } else if pd.rd != rd0 || combo != combo0 {
- pd.rseq++ // invalidate current timers
- if pd.rd > 0 {
- modtimer(&pd.rt, pd.rd, 0, rtf, pd.makeArg(), pd.rseq)
- } else {
- deltimer(&pd.rt)
- pd.rt.f = nil
- }
- }
- if pd.wt.f == nil {
- if pd.wd > 0 && !combo {
- pd.wt.f = netpollWriteDeadline
- pd.wt.arg = pd.makeArg()
- pd.wt.seq = pd.wseq
- resettimer(&pd.wt, pd.wd)
- }
- } else if pd.wd != wd0 || combo != combo0 {
- pd.wseq++ // invalidate current timers
- if pd.wd > 0 && !combo {
- modtimer(&pd.wt, pd.wd, 0, netpollWriteDeadline, pd.makeArg(), pd.wseq)
- } else {
- deltimer(&pd.wt)
- pd.wt.f = nil
- }
- }
- // If we set the new deadline in the past, unblock currently pending IO if any.
- // Note that pd.publishInfo has already been called, above, immediately after modifying rd and wd.
- var rg, wg *g
- if pd.rd < 0 {
- rg = netpollunblock(pd, 'r', false)
- }
- if pd.wd < 0 {
- wg = netpollunblock(pd, 'w', false)
- }
- unlock(&pd.lock)
- if rg != nil {
- netpollgoready(rg, 3)
- }
- if wg != nil {
- netpollgoready(wg, 3)
- }
-}
-
-//go:linkname poll_runtime_pollUnblock internal/poll.runtime_pollUnblock
-func poll_runtime_pollUnblock(pd *pollDesc) {
- lock(&pd.lock)
- if pd.closing {
- throw("runtime: unblock on closing polldesc")
- }
- pd.closing = true
- pd.rseq++
- pd.wseq++
- var rg, wg *g
- pd.publishInfo()
- rg = netpollunblock(pd, 'r', false)
- wg = netpollunblock(pd, 'w', false)
- if pd.rt.f != nil {
- deltimer(&pd.rt)
- pd.rt.f = nil
- }
- if pd.wt.f != nil {
- deltimer(&pd.wt)
- pd.wt.f = nil
- }
- unlock(&pd.lock)
- if rg != nil {
- netpollgoready(rg, 3)
- }
- if wg != nil {
- netpollgoready(wg, 3)
- }
-}
-
-// netpollready is called by the platform-specific netpoll function.
-// It declares that the fd associated with pd is ready for I/O.
-// The toRun argument is used to build a list of goroutines to return
-// from netpoll. The mode argument is 'r', 'w', or 'r'+'w' to indicate
-// whether the fd is ready for reading or writing or both.
-//
-// This may run while the world is stopped, so write barriers are not allowed.
-//
-//go:nowritebarrier
-func netpollready(toRun *gList, pd *pollDesc, mode int32) {
- var rg, wg *g
- if mode == 'r' || mode == 'r'+'w' {
- rg = netpollunblock(pd, 'r', true)
- }
- if mode == 'w' || mode == 'r'+'w' {
- wg = netpollunblock(pd, 'w', true)
- }
- if rg != nil {
- toRun.push(rg)
- }
- if wg != nil {
- toRun.push(wg)
- }
-}
-
-func netpollcheckerr(pd *pollDesc, mode int32) int {
- info := pd.info()
- if info.closing() {
- return pollErrClosing
- }
- if (mode == 'r' && info.expiredReadDeadline()) || (mode == 'w' && info.expiredWriteDeadline()) {
- return pollErrTimeout
- }
- // Report an event scanning error only on a read event.
- // An error on a write event will be captured in a subsequent
- // write call that is able to report a more specific error.
- if mode == 'r' && info.eventErr() {
- return pollErrNotPollable
- }
- return pollNoError
-}
-
-func netpollblockcommit(gp *g, gpp unsafe.Pointer) bool {
- r := atomic.Casuintptr((*uintptr)(gpp), pdWait, uintptr(unsafe.Pointer(gp)))
- if r {
- // Bump the count of goroutines waiting for the poller.
- // The scheduler uses this to decide whether to block
- // waiting for the poller if there is nothing else to do.
- netpollWaiters.Add(1)
- }
- return r
-}
-
-func netpollgoready(gp *g, traceskip int) {
- netpollWaiters.Add(-1)
- goready(gp, traceskip+1)
-}
-
-// returns true if IO is ready, or false if timed out or closed
-// waitio - wait only for completed IO, ignore errors
-// Concurrent calls to netpollblock in the same mode are forbidden, as pollDesc
-// can hold only a single waiting goroutine for each mode.
-func netpollblock(pd *pollDesc, mode int32, waitio bool) bool {
- gpp := &pd.rg
- if mode == 'w' {
- gpp = &pd.wg
- }
-
- // set the gpp semaphore to pdWait
- for {
- // Consume notification if already ready.
- if gpp.CompareAndSwap(pdReady, pdNil) {
- return true
- }
- if gpp.CompareAndSwap(pdNil, pdWait) {
- break
- }
-
- // Double check that this isn't corrupt; otherwise we'd loop
- // forever.
- if v := gpp.Load(); v != pdReady && v != pdNil {
- throw("runtime: double wait")
- }
- }
-
- // need to recheck error states after setting gpp to pdWait
- // this is necessary because runtime_pollUnblock/runtime_pollSetDeadline/deadlineimpl
- // do the opposite: store to closing/rd/wd, publishInfo, load of rg/wg
- if waitio || netpollcheckerr(pd, mode) == pollNoError {
- gopark(netpollblockcommit, unsafe.Pointer(gpp), waitReasonIOWait, traceEvGoBlockNet, 5)
- }
- // be careful to not lose concurrent pdReady notification
- old := gpp.Swap(pdNil)
- if old > pdWait {
- throw("runtime: corrupted polldesc")
- }
- return old == pdReady
-}
-
-func netpollunblock(pd *pollDesc, mode int32, ioready bool) *g {
- gpp := &pd.rg
- if mode == 'w' {
- gpp = &pd.wg
- }
-
- for {
- old := gpp.Load()
- if old == pdReady {
- return nil
- }
- if old == pdNil && !ioready {
- // Only set pdReady for ioready. runtime_pollWait
- // will check for timeout/cancel before waiting.
- return nil
- }
- var new uintptr
- if ioready {
- new = pdReady
- }
- if gpp.CompareAndSwap(old, new) {
- if old == pdWait {
- old = pdNil
- }
- return (*g)(unsafe.Pointer(old))
- }
- }
-}
-
-func netpolldeadlineimpl(pd *pollDesc, seq uintptr, read, write bool) {
- lock(&pd.lock)
- // Seq arg is seq when the timer was set.
- // If it's stale, ignore the timer event.
- currentSeq := pd.rseq
- if !read {
- currentSeq = pd.wseq
- }
- if seq != currentSeq {
- // The descriptor was reused or timers were reset.
- unlock(&pd.lock)
- return
- }
- var rg *g
- if read {
- if pd.rd <= 0 || pd.rt.f == nil {
- throw("runtime: inconsistent read deadline")
- }
- pd.rd = -1
- pd.publishInfo()
- rg = netpollunblock(pd, 'r', false)
- }
- var wg *g
- if write {
- if pd.wd <= 0 || pd.wt.f == nil && !read {
- throw("runtime: inconsistent write deadline")
- }
- pd.wd = -1
- pd.publishInfo()
- wg = netpollunblock(pd, 'w', false)
- }
- unlock(&pd.lock)
- if rg != nil {
- netpollgoready(rg, 0)
- }
- if wg != nil {
- netpollgoready(wg, 0)
- }
-}
-
-func netpollDeadline(arg any, seq uintptr) {
- netpolldeadlineimpl(arg.(*pollDesc), seq, true, true)
-}
-
-func netpollReadDeadline(arg any, seq uintptr) {
- netpolldeadlineimpl(arg.(*pollDesc), seq, true, false)
-}
-
-func netpollWriteDeadline(arg any, seq uintptr) {
- netpolldeadlineimpl(arg.(*pollDesc), seq, false, true)
-}
-
-func (c *pollCache) alloc() *pollDesc {
- lock(&c.lock)
- if c.first == nil {
- const pdSize = unsafe.Sizeof(pollDesc{})
- n := pollBlockSize / pdSize
- if n == 0 {
- n = 1
- }
- // Must be in non-GC memory because can be referenced
- // only from epoll/kqueue internals.
- mem := persistentalloc(n*pdSize, 0, &memstats.other_sys)
- for i := uintptr(0); i < n; i++ {
- pd := (*pollDesc)(add(mem, i*pdSize))
- pd.link = c.first
- c.first = pd
- }
- }
- pd := c.first
- c.first = pd.link
- lockInit(&pd.lock, lockRankPollDesc)
- unlock(&c.lock)
- return pd
-}
-
-// makeArg converts pd to an interface{}.
-// makeArg does not do any allocation. Normally, such
-// a conversion requires an allocation because pointers to
-// types which embed runtime/internal/sys.NotInHeap (which pollDesc is)
-// must be stored in interfaces indirectly. See issue 42076.
-func (pd *pollDesc) makeArg() (i any) {
- x := (*eface)(unsafe.Pointer(&i))
- x._type = pdType
- x.data = unsafe.Pointer(&pd.self)
- return
-}
-
-var (
- pdEface any = (*pollDesc)(nil)
- pdType *_type = efaceOf(&pdEface)._type
-)
diff --git a/contrib/go/_std_1.20/src/runtime/netpoll_epoll.go b/contrib/go/_std_1.20/src/runtime/netpoll_epoll.go
deleted file mode 100644
index 7164a59551..0000000000
--- a/contrib/go/_std_1.20/src/runtime/netpoll_epoll.go
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2013 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.
-
-//go:build linux
-
-package runtime
-
-import (
- "runtime/internal/atomic"
- "runtime/internal/syscall"
- "unsafe"
-)
-
-var (
- epfd int32 = -1 // epoll descriptor
-
- netpollBreakRd, netpollBreakWr uintptr // for netpollBreak
-
- netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
-)
-
-func netpollinit() {
- var errno uintptr
- epfd, errno = syscall.EpollCreate1(syscall.EPOLL_CLOEXEC)
- if errno != 0 {
- println("runtime: epollcreate failed with", errno)
- throw("runtime: netpollinit failed")
- }
- r, w, errpipe := nonblockingPipe()
- if errpipe != 0 {
- println("runtime: pipe failed with", -errpipe)
- throw("runtime: pipe failed")
- }
- ev := syscall.EpollEvent{
- Events: syscall.EPOLLIN,
- }
- *(**uintptr)(unsafe.Pointer(&ev.Data)) = &netpollBreakRd
- errno = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, r, &ev)
- if errno != 0 {
- println("runtime: epollctl failed with", errno)
- throw("runtime: epollctl failed")
- }
- netpollBreakRd = uintptr(r)
- netpollBreakWr = uintptr(w)
-}
-
-func netpollIsPollDescriptor(fd uintptr) bool {
- return fd == uintptr(epfd) || fd == netpollBreakRd || fd == netpollBreakWr
-}
-
-func netpollopen(fd uintptr, pd *pollDesc) uintptr {
- var ev syscall.EpollEvent
- ev.Events = syscall.EPOLLIN | syscall.EPOLLOUT | syscall.EPOLLRDHUP | syscall.EPOLLET
- *(**pollDesc)(unsafe.Pointer(&ev.Data)) = pd
- return syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, int32(fd), &ev)
-}
-
-func netpollclose(fd uintptr) uintptr {
- var ev syscall.EpollEvent
- return syscall.EpollCtl(epfd, syscall.EPOLL_CTL_DEL, int32(fd), &ev)
-}
-
-func netpollarm(pd *pollDesc, mode int) {
- throw("runtime: unused")
-}
-
-// netpollBreak interrupts an epollwait.
-func netpollBreak() {
- // Failing to cas indicates there is an in-flight wakeup, so we're done here.
- if !netpollWakeSig.CompareAndSwap(0, 1) {
- return
- }
-
- for {
- var b byte
- n := write(netpollBreakWr, unsafe.Pointer(&b), 1)
- if n == 1 {
- break
- }
- if n == -_EINTR {
- continue
- }
- if n == -_EAGAIN {
- return
- }
- println("runtime: netpollBreak write failed with", -n)
- throw("runtime: netpollBreak write failed")
- }
-}
-
-// netpoll checks for ready network connections.
-// Returns list of goroutines that become runnable.
-// delay < 0: blocks indefinitely
-// delay == 0: does not block, just polls
-// delay > 0: block for up to that many nanoseconds
-func netpoll(delay int64) gList {
- if epfd == -1 {
- return gList{}
- }
- var waitms int32
- if delay < 0 {
- waitms = -1
- } else if delay == 0 {
- waitms = 0
- } else if delay < 1e6 {
- waitms = 1
- } else if delay < 1e15 {
- waitms = int32(delay / 1e6)
- } else {
- // An arbitrary cap on how long to wait for a timer.
- // 1e9 ms == ~11.5 days.
- waitms = 1e9
- }
- var events [128]syscall.EpollEvent
-retry:
- n, errno := syscall.EpollWait(epfd, events[:], int32(len(events)), waitms)
- if errno != 0 {
- if errno != _EINTR {
- println("runtime: epollwait on fd", epfd, "failed with", errno)
- throw("runtime: netpoll failed")
- }
- // If a timed sleep was interrupted, just return to
- // recalculate how long we should sleep now.
- if waitms > 0 {
- return gList{}
- }
- goto retry
- }
- var toRun gList
- for i := int32(0); i < n; i++ {
- ev := events[i]
- if ev.Events == 0 {
- continue
- }
-
- if *(**uintptr)(unsafe.Pointer(&ev.Data)) == &netpollBreakRd {
- if ev.Events != syscall.EPOLLIN {
- println("runtime: netpoll: break fd ready for", ev.Events)
- throw("runtime: netpoll: break fd ready for something unexpected")
- }
- if delay != 0 {
- // netpollBreak could be picked up by a
- // nonblocking poll. Only read the byte
- // if blocking.
- var tmp [16]byte
- read(int32(netpollBreakRd), noescape(unsafe.Pointer(&tmp[0])), int32(len(tmp)))
- netpollWakeSig.Store(0)
- }
- continue
- }
-
- var mode int32
- if ev.Events&(syscall.EPOLLIN|syscall.EPOLLRDHUP|syscall.EPOLLHUP|syscall.EPOLLERR) != 0 {
- mode += 'r'
- }
- if ev.Events&(syscall.EPOLLOUT|syscall.EPOLLHUP|syscall.EPOLLERR) != 0 {
- mode += 'w'
- }
- if mode != 0 {
- pd := *(**pollDesc)(unsafe.Pointer(&ev.Data))
- pd.setEventErr(ev.Events == syscall.EPOLLERR)
- netpollready(&toRun, pd, mode)
- }
- }
- return toRun
-}
diff --git a/contrib/go/_std_1.20/src/runtime/netpoll_kqueue.go b/contrib/go/_std_1.20/src/runtime/netpoll_kqueue.go
deleted file mode 100644
index 5ae77b57f2..0000000000
--- a/contrib/go/_std_1.20/src/runtime/netpoll_kqueue.go
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2013 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.
-
-//go:build darwin || dragonfly || freebsd || netbsd || openbsd
-
-package runtime
-
-// Integrated network poller (kqueue-based implementation).
-
-import (
- "runtime/internal/atomic"
- "unsafe"
-)
-
-var (
- kq int32 = -1
-
- netpollBreakRd, netpollBreakWr uintptr // for netpollBreak
-
- netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
-)
-
-func netpollinit() {
- kq = kqueue()
- if kq < 0 {
- println("runtime: kqueue failed with", -kq)
- throw("runtime: netpollinit failed")
- }
- closeonexec(kq)
- r, w, errno := nonblockingPipe()
- if errno != 0 {
- println("runtime: pipe failed with", -errno)
- throw("runtime: pipe failed")
- }
- ev := keventt{
- filter: _EVFILT_READ,
- flags: _EV_ADD,
- }
- *(*uintptr)(unsafe.Pointer(&ev.ident)) = uintptr(r)
- n := kevent(kq, &ev, 1, nil, 0, nil)
- if n < 0 {
- println("runtime: kevent failed with", -n)
- throw("runtime: kevent failed")
- }
- netpollBreakRd = uintptr(r)
- netpollBreakWr = uintptr(w)
-}
-
-func netpollIsPollDescriptor(fd uintptr) bool {
- return fd == uintptr(kq) || fd == netpollBreakRd || fd == netpollBreakWr
-}
-
-func netpollopen(fd uintptr, pd *pollDesc) int32 {
- // Arm both EVFILT_READ and EVFILT_WRITE in edge-triggered mode (EV_CLEAR)
- // for the whole fd lifetime. The notifications are automatically unregistered
- // when fd is closed.
- var ev [2]keventt
- *(*uintptr)(unsafe.Pointer(&ev[0].ident)) = fd
- ev[0].filter = _EVFILT_READ
- ev[0].flags = _EV_ADD | _EV_CLEAR
- ev[0].fflags = 0
- ev[0].data = 0
- ev[0].udata = (*byte)(unsafe.Pointer(pd))
- ev[1] = ev[0]
- ev[1].filter = _EVFILT_WRITE
- n := kevent(kq, &ev[0], 2, nil, 0, nil)
- if n < 0 {
- return -n
- }
- return 0
-}
-
-func netpollclose(fd uintptr) int32 {
- // Don't need to unregister because calling close()
- // on fd will remove any kevents that reference the descriptor.
- return 0
-}
-
-func netpollarm(pd *pollDesc, mode int) {
- throw("runtime: unused")
-}
-
-// netpollBreak interrupts a kevent.
-func netpollBreak() {
- // Failing to cas indicates there is an in-flight wakeup, so we're done here.
- if !netpollWakeSig.CompareAndSwap(0, 1) {
- return
- }
-
- for {
- var b byte
- n := write(netpollBreakWr, unsafe.Pointer(&b), 1)
- if n == 1 || n == -_EAGAIN {
- break
- }
- if n == -_EINTR {
- continue
- }
- println("runtime: netpollBreak write failed with", -n)
- throw("runtime: netpollBreak write failed")
- }
-}
-
-// netpoll checks for ready network connections.
-// Returns list of goroutines that become runnable.
-// delay < 0: blocks indefinitely
-// delay == 0: does not block, just polls
-// delay > 0: block for up to that many nanoseconds
-func netpoll(delay int64) gList {
- if kq == -1 {
- return gList{}
- }
- var tp *timespec
- var ts timespec
- if delay < 0 {
- tp = nil
- } else if delay == 0 {
- tp = &ts
- } else {
- ts.setNsec(delay)
- if ts.tv_sec > 1e6 {
- // Darwin returns EINVAL if the sleep time is too long.
- ts.tv_sec = 1e6
- }
- tp = &ts
- }
- var events [64]keventt
-retry:
- n := kevent(kq, nil, 0, &events[0], int32(len(events)), tp)
- if n < 0 {
- if n != -_EINTR {
- println("runtime: kevent on fd", kq, "failed with", -n)
- throw("runtime: netpoll failed")
- }
- // If a timed sleep was interrupted, just return to
- // recalculate how long we should sleep now.
- if delay > 0 {
- return gList{}
- }
- goto retry
- }
- var toRun gList
- for i := 0; i < int(n); i++ {
- ev := &events[i]
-
- if uintptr(ev.ident) == netpollBreakRd {
- if ev.filter != _EVFILT_READ {
- println("runtime: netpoll: break fd ready for", ev.filter)
- throw("runtime: netpoll: break fd ready for something unexpected")
- }
- if delay != 0 {
- // netpollBreak could be picked up by a
- // nonblocking poll. Only read the byte
- // if blocking.
- var tmp [16]byte
- read(int32(netpollBreakRd), noescape(unsafe.Pointer(&tmp[0])), int32(len(tmp)))
- netpollWakeSig.Store(0)
- }
- continue
- }
-
- var mode int32
- switch ev.filter {
- case _EVFILT_READ:
- mode += 'r'
-
- // On some systems when the read end of a pipe
- // is closed the write end will not get a
- // _EVFILT_WRITE event, but will get a
- // _EVFILT_READ event with EV_EOF set.
- // Note that setting 'w' here just means that we
- // will wake up a goroutine waiting to write;
- // that goroutine will try the write again,
- // and the appropriate thing will happen based
- // on what that write returns (success, EPIPE, EAGAIN).
- if ev.flags&_EV_EOF != 0 {
- mode += 'w'
- }
- case _EVFILT_WRITE:
- mode += 'w'
- }
- if mode != 0 {
- pd := (*pollDesc)(unsafe.Pointer(ev.udata))
- pd.setEventErr(ev.flags == _EV_ERROR)
- netpollready(&toRun, pd, mode)
- }
- }
- return toRun
-}
diff --git a/contrib/go/_std_1.20/src/runtime/netpoll_windows.go b/contrib/go/_std_1.20/src/runtime/netpoll_windows.go
deleted file mode 100644
index 796bf1dd19..0000000000
--- a/contrib/go/_std_1.20/src/runtime/netpoll_windows.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2013 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 runtime
-
-import (
- "runtime/internal/atomic"
- "unsafe"
-)
-
-const _DWORD_MAX = 0xffffffff
-
-const _INVALID_HANDLE_VALUE = ^uintptr(0)
-
-// net_op must be the same as beginning of internal/poll.operation.
-// Keep these in sync.
-type net_op struct {
- // used by windows
- o overlapped
- // used by netpoll
- pd *pollDesc
- mode int32
- errno int32
- qty uint32
-}
-
-type overlappedEntry struct {
- key uintptr
- op *net_op // In reality it's *overlapped, but we cast it to *net_op anyway.
- internal uintptr
- qty uint32
-}
-
-var (
- iocphandle uintptr = _INVALID_HANDLE_VALUE // completion port io handle
-
- netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
-)
-
-func netpollinit() {
- iocphandle = stdcall4(_CreateIoCompletionPort, _INVALID_HANDLE_VALUE, 0, 0, _DWORD_MAX)
- if iocphandle == 0 {
- println("runtime: CreateIoCompletionPort failed (errno=", getlasterror(), ")")
- throw("runtime: netpollinit failed")
- }
-}
-
-func netpollIsPollDescriptor(fd uintptr) bool {
- return fd == iocphandle
-}
-
-func netpollopen(fd uintptr, pd *pollDesc) int32 {
- if stdcall4(_CreateIoCompletionPort, fd, iocphandle, 0, 0) == 0 {
- return int32(getlasterror())
- }
- return 0
-}
-
-func netpollclose(fd uintptr) int32 {
- // nothing to do
- return 0
-}
-
-func netpollarm(pd *pollDesc, mode int) {
- throw("runtime: unused")
-}
-
-func netpollBreak() {
- // Failing to cas indicates there is an in-flight wakeup, so we're done here.
- if !netpollWakeSig.CompareAndSwap(0, 1) {
- return
- }
-
- if stdcall4(_PostQueuedCompletionStatus, iocphandle, 0, 0, 0) == 0 {
- println("runtime: netpoll: PostQueuedCompletionStatus failed (errno=", getlasterror(), ")")
- throw("runtime: netpoll: PostQueuedCompletionStatus failed")
- }
-}
-
-// netpoll checks for ready network connections.
-// Returns list of goroutines that become runnable.
-// delay < 0: blocks indefinitely
-// delay == 0: does not block, just polls
-// delay > 0: block for up to that many nanoseconds
-func netpoll(delay int64) gList {
- var entries [64]overlappedEntry
- var wait, qty, flags, n, i uint32
- var errno int32
- var op *net_op
- var toRun gList
-
- mp := getg().m
-
- if iocphandle == _INVALID_HANDLE_VALUE {
- return gList{}
- }
- if delay < 0 {
- wait = _INFINITE
- } else if delay == 0 {
- wait = 0
- } else if delay < 1e6 {
- wait = 1
- } else if delay < 1e15 {
- wait = uint32(delay / 1e6)
- } else {
- // An arbitrary cap on how long to wait for a timer.
- // 1e9 ms == ~11.5 days.
- wait = 1e9
- }
-
- n = uint32(len(entries) / int(gomaxprocs))
- if n < 8 {
- n = 8
- }
- if delay != 0 {
- mp.blocked = true
- }
- if stdcall6(_GetQueuedCompletionStatusEx, iocphandle, uintptr(unsafe.Pointer(&entries[0])), uintptr(n), uintptr(unsafe.Pointer(&n)), uintptr(wait), 0) == 0 {
- mp.blocked = false
- errno = int32(getlasterror())
- if errno == _WAIT_TIMEOUT {
- return gList{}
- }
- println("runtime: GetQueuedCompletionStatusEx failed (errno=", errno, ")")
- throw("runtime: netpoll failed")
- }
- mp.blocked = false
- for i = 0; i < n; i++ {
- op = entries[i].op
- if op != nil {
- errno = 0
- qty = 0
- if stdcall5(_WSAGetOverlappedResult, op.pd.fd, uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 {
- errno = int32(getlasterror())
- }
- handlecompletion(&toRun, op, errno, qty)
- } else {
- netpollWakeSig.Store(0)
- if delay == 0 {
- // Forward the notification to the
- // blocked poller.
- netpollBreak()
- }
- }
- }
- return toRun
-}
-
-func handlecompletion(toRun *gList, op *net_op, errno int32, qty uint32) {
- mode := op.mode
- if mode != 'r' && mode != 'w' {
- println("runtime: GetQueuedCompletionStatusEx returned invalid mode=", mode)
- throw("runtime: netpoll failed")
- }
- op.errno = errno
- op.qty = qty
- netpollready(toRun, op.pd, mode)
-}
diff --git a/contrib/go/_std_1.20/src/runtime/os_darwin.go b/contrib/go/_std_1.20/src/runtime/os_darwin.go
deleted file mode 100644
index c4f3bb6a81..0000000000
--- a/contrib/go/_std_1.20/src/runtime/os_darwin.go
+++ /dev/null
@@ -1,475 +0,0 @@
-// Copyright 2009 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 runtime
-
-import (
- "internal/abi"
- "unsafe"
-)
-
-type mOS struct {
- initialized bool
- mutex pthreadmutex
- cond pthreadcond
- count int
-}
-
-func unimplemented(name string) {
- println(name, "not implemented")
- *(*int)(unsafe.Pointer(uintptr(1231))) = 1231
-}
-
-//go:nosplit
-func semacreate(mp *m) {
- if mp.initialized {
- return
- }
- mp.initialized = true
- if err := pthread_mutex_init(&mp.mutex, nil); err != 0 {
- throw("pthread_mutex_init")
- }
- if err := pthread_cond_init(&mp.cond, nil); err != 0 {
- throw("pthread_cond_init")
- }
-}
-
-//go:nosplit
-func semasleep(ns int64) int32 {
- var start int64
- if ns >= 0 {
- start = nanotime()
- }
- mp := getg().m
- pthread_mutex_lock(&mp.mutex)
- for {
- if mp.count > 0 {
- mp.count--
- pthread_mutex_unlock(&mp.mutex)
- return 0
- }
- if ns >= 0 {
- spent := nanotime() - start
- if spent >= ns {
- pthread_mutex_unlock(&mp.mutex)
- return -1
- }
- var t timespec
- t.setNsec(ns - spent)
- err := pthread_cond_timedwait_relative_np(&mp.cond, &mp.mutex, &t)
- if err == _ETIMEDOUT {
- pthread_mutex_unlock(&mp.mutex)
- return -1
- }
- } else {
- pthread_cond_wait(&mp.cond, &mp.mutex)
- }
- }
-}
-
-//go:nosplit
-func semawakeup(mp *m) {
- pthread_mutex_lock(&mp.mutex)
- mp.count++
- if mp.count > 0 {
- pthread_cond_signal(&mp.cond)
- }
- pthread_mutex_unlock(&mp.mutex)
-}
-
-// The read and write file descriptors used by the sigNote functions.
-var sigNoteRead, sigNoteWrite int32
-
-// sigNoteSetup initializes an async-signal-safe note.
-//
-// The current implementation of notes on Darwin is not async-signal-safe,
-// because the functions pthread_mutex_lock, pthread_cond_signal, and
-// pthread_mutex_unlock, called by semawakeup, are not async-signal-safe.
-// There is only one case where we need to wake up a note from a signal
-// handler: the sigsend function. The signal handler code does not require
-// all the features of notes: it does not need to do a timed wait.
-// This is a separate implementation of notes, based on a pipe, that does
-// not support timed waits but is async-signal-safe.
-func sigNoteSetup(*note) {
- if sigNoteRead != 0 || sigNoteWrite != 0 {
- throw("duplicate sigNoteSetup")
- }
- var errno int32
- sigNoteRead, sigNoteWrite, errno = pipe()
- if errno != 0 {
- throw("pipe failed")
- }
- closeonexec(sigNoteRead)
- closeonexec(sigNoteWrite)
-
- // Make the write end of the pipe non-blocking, so that if the pipe
- // buffer is somehow full we will not block in the signal handler.
- // Leave the read end of the pipe blocking so that we will block
- // in sigNoteSleep.
- setNonblock(sigNoteWrite)
-}
-
-// sigNoteWakeup wakes up a thread sleeping on a note created by sigNoteSetup.
-func sigNoteWakeup(*note) {
- var b byte
- write(uintptr(sigNoteWrite), unsafe.Pointer(&b), 1)
-}
-
-// sigNoteSleep waits for a note created by sigNoteSetup to be woken.
-func sigNoteSleep(*note) {
- for {
- var b byte
- entersyscallblock()
- n := read(sigNoteRead, unsafe.Pointer(&b), 1)
- exitsyscall()
- if n != -_EINTR {
- return
- }
- }
-}
-
-// BSD interface for threading.
-func osinit() {
- // pthread_create delayed until end of goenvs so that we
- // can look at the environment first.
-
- ncpu = getncpu()
- physPageSize = getPageSize()
-
- osinit_hack()
-}
-
-func sysctlbynameInt32(name []byte) (int32, int32) {
- out := int32(0)
- nout := unsafe.Sizeof(out)
- ret := sysctlbyname(&name[0], (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
- return ret, out
-}
-
-//go:linkname internal_cpu_getsysctlbyname internal/cpu.getsysctlbyname
-func internal_cpu_getsysctlbyname(name []byte) (int32, int32) {
- return sysctlbynameInt32(name)
-}
-
-const (
- _CTL_HW = 6
- _HW_NCPU = 3
- _HW_PAGESIZE = 7
-)
-
-func getncpu() int32 {
- // Use sysctl to fetch hw.ncpu.
- mib := [2]uint32{_CTL_HW, _HW_NCPU}
- out := uint32(0)
- nout := unsafe.Sizeof(out)
- ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
- if ret >= 0 && int32(out) > 0 {
- return int32(out)
- }
- return 1
-}
-
-func getPageSize() uintptr {
- // Use sysctl to fetch hw.pagesize.
- mib := [2]uint32{_CTL_HW, _HW_PAGESIZE}
- out := uint32(0)
- nout := unsafe.Sizeof(out)
- ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
- if ret >= 0 && int32(out) > 0 {
- return uintptr(out)
- }
- return 0
-}
-
-var urandom_dev = []byte("/dev/urandom\x00")
-
-//go:nosplit
-func getRandomData(r []byte) {
- fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
- n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
- closefd(fd)
- extendRandom(r, int(n))
-}
-
-func goenvs() {
- goenvs_unix()
-}
-
-// May run with m.p==nil, so write barriers are not allowed.
-//
-//go:nowritebarrierrec
-func newosproc(mp *m) {
- stk := unsafe.Pointer(mp.g0.stack.hi)
- if false {
- print("newosproc stk=", stk, " m=", mp, " g=", mp.g0, " id=", mp.id, " ostk=", &mp, "\n")
- }
-
- // Initialize an attribute object.
- var attr pthreadattr
- var err int32
- err = pthread_attr_init(&attr)
- if err != 0 {
- writeErrStr(failthreadcreate)
- exit(1)
- }
-
- // Find out OS stack size for our own stack guard.
- var stacksize uintptr
- if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
- writeErrStr(failthreadcreate)
- exit(1)
- }
- mp.g0.stack.hi = stacksize // for mstart
-
- // Tell the pthread library we won't join with this thread.
- if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
- writeErrStr(failthreadcreate)
- exit(1)
- }
-
- // Finally, create the thread. It starts at mstart_stub, which does some low-level
- // setup and then calls mstart.
- var oset sigset
- sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
- err = retryOnEAGAIN(func() int32 {
- return pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
- })
- sigprocmask(_SIG_SETMASK, &oset, nil)
- if err != 0 {
- writeErrStr(failthreadcreate)
- exit(1)
- }
-}
-
-// glue code to call mstart from pthread_create.
-func mstart_stub()
-
-// newosproc0 is a version of newosproc that can be called before the runtime
-// is initialized.
-//
-// This function is not safe to use after initialization as it does not pass an M as fnarg.
-//
-//go:nosplit
-func newosproc0(stacksize uintptr, fn uintptr) {
- // Initialize an attribute object.
- var attr pthreadattr
- var err int32
- err = pthread_attr_init(&attr)
- if err != 0 {
- writeErrStr(failthreadcreate)
- exit(1)
- }
-
- // The caller passes in a suggested stack size,
- // from when we allocated the stack and thread ourselves,
- // without libpthread. Now that we're using libpthread,
- // we use the OS default stack size instead of the suggestion.
- // Find out that stack size for our own stack guard.
- if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
- writeErrStr(failthreadcreate)
- exit(1)
- }
- g0.stack.hi = stacksize // for mstart
- memstats.stacks_sys.add(int64(stacksize))
-
- // Tell the pthread library we won't join with this thread.
- if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
- writeErrStr(failthreadcreate)
- exit(1)
- }
-
- // Finally, create the thread. It starts at mstart_stub, which does some low-level
- // setup and then calls mstart.
- var oset sigset
- sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
- err = pthread_create(&attr, fn, nil)
- sigprocmask(_SIG_SETMASK, &oset, nil)
- if err != 0 {
- writeErrStr(failthreadcreate)
- exit(1)
- }
-}
-
-// Called to do synchronous initialization of Go code built with
-// -buildmode=c-archive or -buildmode=c-shared.
-// None of the Go runtime is initialized.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func libpreinit() {
- initsig(true)
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-func mpreinit(mp *m) {
- mp.gsignal = malg(32 * 1024) // OS X wants >= 8K
- mp.gsignal.m = mp
- if GOOS == "darwin" && GOARCH == "arm64" {
- // mlock the signal stack to work around a kernel bug where it may
- // SIGILL when the signal stack is not faulted in while a signal
- // arrives. See issue 42774.
- mlock(unsafe.Pointer(mp.gsignal.stack.hi-physPageSize), physPageSize)
- }
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, cannot allocate memory.
-func minit() {
- // iOS does not support alternate signal stack.
- // The signal handler handles it directly.
- if !(GOOS == "ios" && GOARCH == "arm64") {
- minitSignalStack()
- }
- minitSignalMask()
- getg().m.procid = uint64(pthread_self())
-}
-
-// Called from dropm to undo the effect of an minit.
-//
-//go:nosplit
-func unminit() {
- // iOS does not support alternate signal stack.
- // See minit.
- if !(GOOS == "ios" && GOARCH == "arm64") {
- unminitSignals()
- }
-}
-
-// Called from exitm, but not from drop, to undo the effect of thread-owned
-// resources in minit, semacreate, or elsewhere. Do not take locks after calling this.
-func mdestroy(mp *m) {
-}
-
-//go:nosplit
-func osyield_no_g() {
- usleep_no_g(1)
-}
-
-//go:nosplit
-func osyield() {
- usleep(1)
-}
-
-const (
- _NSIG = 32
- _SI_USER = 0 /* empirically true, but not what headers say */
- _SIG_BLOCK = 1
- _SIG_UNBLOCK = 2
- _SIG_SETMASK = 3
- _SS_DISABLE = 4
-)
-
-//extern SigTabTT runtime·sigtab[];
-
-type sigset uint32
-
-var sigset_all = ^sigset(0)
-
-//go:nosplit
-//go:nowritebarrierrec
-func setsig(i uint32, fn uintptr) {
- var sa usigactiont
- sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
- sa.sa_mask = ^uint32(0)
- if fn == abi.FuncPCABIInternal(sighandler) { // abi.FuncPCABIInternal(sighandler) matches the callers in signal_unix.go
- if iscgo {
- fn = abi.FuncPCABI0(cgoSigtramp)
- } else {
- fn = abi.FuncPCABI0(sigtramp)
- }
- }
- *(*uintptr)(unsafe.Pointer(&sa.__sigaction_u)) = fn
- sigaction(i, &sa, nil)
-}
-
-// sigtramp is the callback from libc when a signal is received.
-// It is called with the C calling convention.
-func sigtramp()
-func cgoSigtramp()
-
-//go:nosplit
-//go:nowritebarrierrec
-func setsigstack(i uint32) {
- var osa usigactiont
- sigaction(i, nil, &osa)
- handler := *(*uintptr)(unsafe.Pointer(&osa.__sigaction_u))
- if osa.sa_flags&_SA_ONSTACK != 0 {
- return
- }
- var sa usigactiont
- *(*uintptr)(unsafe.Pointer(&sa.__sigaction_u)) = handler
- sa.sa_mask = osa.sa_mask
- sa.sa_flags = osa.sa_flags | _SA_ONSTACK
- sigaction(i, &sa, nil)
-}
-
-//go:nosplit
-//go:nowritebarrierrec
-func getsig(i uint32) uintptr {
- var sa usigactiont
- sigaction(i, nil, &sa)
- return *(*uintptr)(unsafe.Pointer(&sa.__sigaction_u))
-}
-
-// setSignalstackSP sets the ss_sp field of a stackt.
-//
-//go:nosplit
-func setSignalstackSP(s *stackt, sp uintptr) {
- *(*uintptr)(unsafe.Pointer(&s.ss_sp)) = sp
-}
-
-//go:nosplit
-//go:nowritebarrierrec
-func sigaddset(mask *sigset, i int) {
- *mask |= 1 << (uint32(i) - 1)
-}
-
-func sigdelset(mask *sigset, i int) {
- *mask &^= 1 << (uint32(i) - 1)
-}
-
-func setProcessCPUProfiler(hz int32) {
- setProcessCPUProfilerTimer(hz)
-}
-
-func setThreadCPUProfiler(hz int32) {
- setThreadCPUProfilerHz(hz)
-}
-
-//go:nosplit
-func validSIGPROF(mp *m, c *sigctxt) bool {
- return true
-}
-
-//go:linkname executablePath os.executablePath
-var executablePath string
-
-func sysargs(argc int32, argv **byte) {
- // skip over argv, envv and the first string will be the path
- n := argc + 1
- for argv_index(argv, n) != nil {
- n++
- }
- executablePath = gostringnocopy(argv_index(argv, n+1))
-
- // strip "executable_path=" prefix if available, it's added after OS X 10.11.
- const prefix = "executable_path="
- if len(executablePath) > len(prefix) && executablePath[:len(prefix)] == prefix {
- executablePath = executablePath[len(prefix):]
- }
-}
-
-func signalM(mp *m, sig int) {
- pthread_kill(pthread(mp.procid), uint32(sig))
-}
-
-// sigPerThreadSyscall is only used on linux, so we assign a bogus signal
-// number.
-const sigPerThreadSyscall = 1 << 31
-
-//go:nosplit
-func runPerThreadSyscall() {
- throw("runPerThreadSyscall only valid on linux")
-}
diff --git a/contrib/go/_std_1.20/src/runtime/os_linux.go b/contrib/go/_std_1.20/src/runtime/os_linux.go
deleted file mode 100644
index 26db4a0cd9..0000000000
--- a/contrib/go/_std_1.20/src/runtime/os_linux.go
+++ /dev/null
@@ -1,920 +0,0 @@
-// Copyright 2009 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 runtime
-
-import (
- "internal/abi"
- "internal/goarch"
- "runtime/internal/atomic"
- "runtime/internal/syscall"
- "unsafe"
-)
-
-// sigPerThreadSyscall is the same signal (SIGSETXID) used by glibc for
-// per-thread syscalls on Linux. We use it for the same purpose in non-cgo
-// binaries.
-const sigPerThreadSyscall = _SIGRTMIN + 1
-
-type mOS struct {
- // profileTimer holds the ID of the POSIX interval timer for profiling CPU
- // usage on this thread.
- //
- // It is valid when the profileTimerValid field is true. A thread
- // creates and manages its own timer, and these fields are read and written
- // only by this thread. But because some of the reads on profileTimerValid
- // are in signal handling code, this field should be atomic type.
- profileTimer int32
- profileTimerValid atomic.Bool
-
- // needPerThreadSyscall indicates that a per-thread syscall is required
- // for doAllThreadsSyscall.
- needPerThreadSyscall atomic.Uint8
-}
-
-//go:noescape
-func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer, val3 uint32) int32
-
-// Linux futex.
-//
-// futexsleep(uint32 *addr, uint32 val)
-// futexwakeup(uint32 *addr)
-//
-// Futexsleep atomically checks if *addr == val and if so, sleeps on addr.
-// Futexwakeup wakes up threads sleeping on addr.
-// Futexsleep is allowed to wake up spuriously.
-
-const (
- _FUTEX_PRIVATE_FLAG = 128
- _FUTEX_WAIT_PRIVATE = 0 | _FUTEX_PRIVATE_FLAG
- _FUTEX_WAKE_PRIVATE = 1 | _FUTEX_PRIVATE_FLAG
-)
-
-// Atomically,
-//
-// if(*addr == val) sleep
-//
-// Might be woken up spuriously; that's allowed.
-// Don't sleep longer than ns; ns < 0 means forever.
-//
-//go:nosplit
-func futexsleep(addr *uint32, val uint32, ns int64) {
- // Some Linux kernels have a bug where futex of
- // FUTEX_WAIT returns an internal error code
- // as an errno. Libpthread ignores the return value
- // here, and so can we: as it says a few lines up,
- // spurious wakeups are allowed.
- if ns < 0 {
- futex(unsafe.Pointer(addr), _FUTEX_WAIT_PRIVATE, val, nil, nil, 0)
- return
- }
-
- var ts timespec
- ts.setNsec(ns)
- futex(unsafe.Pointer(addr), _FUTEX_WAIT_PRIVATE, val, unsafe.Pointer(&ts), nil, 0)
-}
-
-// If any procs are sleeping on addr, wake up at most cnt.
-//
-//go:nosplit
-func futexwakeup(addr *uint32, cnt uint32) {
- ret := futex(unsafe.Pointer(addr), _FUTEX_WAKE_PRIVATE, cnt, nil, nil, 0)
- if ret >= 0 {
- return
- }
-
- // I don't know that futex wakeup can return
- // EAGAIN or EINTR, but if it does, it would be
- // safe to loop and call futex again.
- systemstack(func() {
- print("futexwakeup addr=", addr, " returned ", ret, "\n")
- })
-
- *(*int32)(unsafe.Pointer(uintptr(0x1006))) = 0x1006
-}
-
-func getproccount() int32 {
- // This buffer is huge (8 kB) but we are on the system stack
- // and there should be plenty of space (64 kB).
- // Also this is a leaf, so we're not holding up the memory for long.
- // See golang.org/issue/11823.
- // The suggested behavior here is to keep trying with ever-larger
- // buffers, but we don't have a dynamic memory allocator at the
- // moment, so that's a bit tricky and seems like overkill.
- const maxCPUs = 64 * 1024
- var buf [maxCPUs / 8]byte
- r := sched_getaffinity(0, unsafe.Sizeof(buf), &buf[0])
- if r < 0 {
- return 1
- }
- n := int32(0)
- for _, v := range buf[:r] {
- for v != 0 {
- n += int32(v & 1)
- v >>= 1
- }
- }
- if n == 0 {
- n = 1
- }
- return n
-}
-
-// Clone, the Linux rfork.
-const (
- _CLONE_VM = 0x100
- _CLONE_FS = 0x200
- _CLONE_FILES = 0x400
- _CLONE_SIGHAND = 0x800
- _CLONE_PTRACE = 0x2000
- _CLONE_VFORK = 0x4000
- _CLONE_PARENT = 0x8000
- _CLONE_THREAD = 0x10000
- _CLONE_NEWNS = 0x20000
- _CLONE_SYSVSEM = 0x40000
- _CLONE_SETTLS = 0x80000
- _CLONE_PARENT_SETTID = 0x100000
- _CLONE_CHILD_CLEARTID = 0x200000
- _CLONE_UNTRACED = 0x800000
- _CLONE_CHILD_SETTID = 0x1000000
- _CLONE_STOPPED = 0x2000000
- _CLONE_NEWUTS = 0x4000000
- _CLONE_NEWIPC = 0x8000000
-
- // As of QEMU 2.8.0 (5ea2fc84d), user emulation requires all six of these
- // flags to be set when creating a thread; attempts to share the other
- // five but leave SYSVSEM unshared will fail with -EINVAL.
- //
- // In non-QEMU environments CLONE_SYSVSEM is inconsequential as we do not
- // use System V semaphores.
-
- cloneFlags = _CLONE_VM | /* share memory */
- _CLONE_FS | /* share cwd, etc */
- _CLONE_FILES | /* share fd table */
- _CLONE_SIGHAND | /* share sig handler table */
- _CLONE_SYSVSEM | /* share SysV semaphore undo lists (see issue #20763) */
- _CLONE_THREAD /* revisit - okay for now */
-)
-
-//go:noescape
-func clone(flags int32, stk, mp, gp, fn unsafe.Pointer) int32
-
-// May run with m.p==nil, so write barriers are not allowed.
-//
-//go:nowritebarrier
-func newosproc(mp *m) {
- stk := unsafe.Pointer(mp.g0.stack.hi)
- /*
- * note: strace gets confused if we use CLONE_PTRACE here.
- */
- if false {
- print("newosproc stk=", stk, " m=", mp, " g=", mp.g0, " clone=", abi.FuncPCABI0(clone), " id=", mp.id, " ostk=", &mp, "\n")
- }
-
- // Disable signals during clone, so that the new thread starts
- // with signals disabled. It will enable them in minit.
- var oset sigset
- sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
- ret := retryOnEAGAIN(func() int32 {
- r := clone(cloneFlags, stk, unsafe.Pointer(mp), unsafe.Pointer(mp.g0), unsafe.Pointer(abi.FuncPCABI0(mstart)))
- // clone returns positive TID, negative errno.
- // We don't care about the TID.
- if r >= 0 {
- return 0
- }
- return -r
- })
- sigprocmask(_SIG_SETMASK, &oset, nil)
-
- if ret != 0 {
- print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
- if ret == _EAGAIN {
- println("runtime: may need to increase max user processes (ulimit -u)")
- }
- throw("newosproc")
- }
-}
-
-// Version of newosproc that doesn't require a valid G.
-//
-//go:nosplit
-func newosproc0(stacksize uintptr, fn unsafe.Pointer) {
- stack := sysAlloc(stacksize, &memstats.stacks_sys)
- if stack == nil {
- writeErrStr(failallocatestack)
- exit(1)
- }
- ret := clone(cloneFlags, unsafe.Pointer(uintptr(stack)+stacksize), nil, nil, fn)
- if ret < 0 {
- writeErrStr(failthreadcreate)
- exit(1)
- }
-}
-
-const (
- _AT_NULL = 0 // End of vector
- _AT_PAGESZ = 6 // System physical page size
- _AT_HWCAP = 16 // hardware capability bit vector
- _AT_SECURE = 23 // secure mode boolean
- _AT_RANDOM = 25 // introduced in 2.6.29
- _AT_HWCAP2 = 26 // hardware capability bit vector 2
-)
-
-var procAuxv = []byte("/proc/self/auxv\x00")
-
-var addrspace_vec [1]byte
-
-func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
-
-func sysargs(argc int32, argv **byte) {
- n := argc + 1
-
- // skip over argv, envp to get to auxv
- for argv_index(argv, n) != nil {
- n++
- }
-
- // skip NULL separator
- n++
-
- // now argv+n is auxv
- auxv := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*goarch.PtrSize))
- if sysauxv(auxv[:]) != 0 {
- return
- }
- // In some situations we don't get a loader-provided
- // auxv, such as when loaded as a library on Android.
- // Fall back to /proc/self/auxv.
- fd := open(&procAuxv[0], 0 /* O_RDONLY */, 0)
- if fd < 0 {
- // On Android, /proc/self/auxv might be unreadable (issue 9229), so we fallback to
- // try using mincore to detect the physical page size.
- // mincore should return EINVAL when address is not a multiple of system page size.
- const size = 256 << 10 // size of memory region to allocate
- p, err := mmap(nil, size, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
- if err != 0 {
- return
- }
- var n uintptr
- for n = 4 << 10; n < size; n <<= 1 {
- err := mincore(unsafe.Pointer(uintptr(p)+n), 1, &addrspace_vec[0])
- if err == 0 {
- physPageSize = n
- break
- }
- }
- if physPageSize == 0 {
- physPageSize = size
- }
- munmap(p, size)
- return
- }
- var buf [128]uintptr
- n = read(fd, noescape(unsafe.Pointer(&buf[0])), int32(unsafe.Sizeof(buf)))
- closefd(fd)
- if n < 0 {
- return
- }
- // Make sure buf is terminated, even if we didn't read
- // the whole file.
- buf[len(buf)-2] = _AT_NULL
- sysauxv(buf[:])
-}
-
-// startupRandomData holds random bytes initialized at startup. These come from
-// the ELF AT_RANDOM auxiliary vector.
-var startupRandomData []byte
-
-// secureMode holds the value of AT_SECURE passed in the auxiliary vector.
-var secureMode bool
-
-func sysauxv(auxv []uintptr) int {
- var i int
- for ; auxv[i] != _AT_NULL; i += 2 {
- tag, val := auxv[i], auxv[i+1]
- switch tag {
- case _AT_RANDOM:
- // The kernel provides a pointer to 16-bytes
- // worth of random data.
- startupRandomData = (*[16]byte)(unsafe.Pointer(val))[:]
-
- case _AT_PAGESZ:
- physPageSize = val
-
- case _AT_SECURE:
- secureMode = val == 1
- }
-
- archauxv(tag, val)
- vdsoauxv(tag, val)
- }
- return i / 2
-}
-
-var sysTHPSizePath = []byte("/sys/kernel/mm/transparent_hugepage/hpage_pmd_size\x00")
-
-func getHugePageSize() uintptr {
- var numbuf [20]byte
- fd := open(&sysTHPSizePath[0], 0 /* O_RDONLY */, 0)
- if fd < 0 {
- return 0
- }
- ptr := noescape(unsafe.Pointer(&numbuf[0]))
- n := read(fd, ptr, int32(len(numbuf)))
- closefd(fd)
- if n <= 0 {
- return 0
- }
- n-- // remove trailing newline
- v, ok := atoi(slicebytetostringtmp((*byte)(ptr), int(n)))
- if !ok || v < 0 {
- v = 0
- }
- if v&(v-1) != 0 {
- // v is not a power of 2
- return 0
- }
- return uintptr(v)
-}
-
-func osinit() {
- ncpu = getproccount()
- physHugePageSize = getHugePageSize()
- if iscgo {
- // #42494 glibc and musl reserve some signals for
- // internal use and require they not be blocked by
- // the rest of a normal C runtime. When the go runtime
- // blocks...unblocks signals, temporarily, the blocked
- // interval of time is generally very short. As such,
- // these expectations of *libc code are mostly met by
- // the combined go+cgo system of threads. However,
- // when go causes a thread to exit, via a return from
- // mstart(), the combined runtime can deadlock if
- // these signals are blocked. Thus, don't block these
- // signals when exiting threads.
- // - glibc: SIGCANCEL (32), SIGSETXID (33)
- // - musl: SIGTIMER (32), SIGCANCEL (33), SIGSYNCCALL (34)
- sigdelset(&sigsetAllExiting, 32)
- sigdelset(&sigsetAllExiting, 33)
- sigdelset(&sigsetAllExiting, 34)
- }
- osArchInit()
-}
-
-var urandom_dev = []byte("/dev/urandom\x00")
-
-func getRandomData(r []byte) {
- if startupRandomData != nil {
- n := copy(r, startupRandomData)
- extendRandom(r, n)
- return
- }
- fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
- n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
- closefd(fd)
- extendRandom(r, int(n))
-}
-
-func goenvs() {
- goenvs_unix()
-}
-
-// Called to do synchronous initialization of Go code built with
-// -buildmode=c-archive or -buildmode=c-shared.
-// None of the Go runtime is initialized.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func libpreinit() {
- initsig(true)
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-func mpreinit(mp *m) {
- mp.gsignal = malg(32 * 1024) // Linux wants >= 2K
- mp.gsignal.m = mp
-}
-
-func gettid() uint32
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, cannot allocate memory.
-func minit() {
- minitSignals()
-
- // Cgo-created threads and the bootstrap m are missing a
- // procid. We need this for asynchronous preemption and it's
- // useful in debuggers.
- getg().m.procid = uint64(gettid())
-}
-
-// Called from dropm to undo the effect of an minit.
-//
-//go:nosplit
-func unminit() {
- unminitSignals()
-}
-
-// Called from exitm, but not from drop, to undo the effect of thread-owned
-// resources in minit, semacreate, or elsewhere. Do not take locks after calling this.
-func mdestroy(mp *m) {
-}
-
-//#ifdef GOARCH_386
-//#define sa_handler k_sa_handler
-//#endif
-
-func sigreturn()
-func sigtramp() // Called via C ABI
-func cgoSigtramp()
-
-//go:noescape
-func sigaltstack(new, old *stackt)
-
-//go:noescape
-func setitimer(mode int32, new, old *itimerval)
-
-//go:noescape
-func timer_create(clockid int32, sevp *sigevent, timerid *int32) int32
-
-//go:noescape
-func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32
-
-//go:noescape
-func timer_delete(timerid int32) int32
-
-//go:noescape
-func rtsigprocmask(how int32, new, old *sigset, size int32)
-
-//go:nosplit
-//go:nowritebarrierrec
-func sigprocmask(how int32, new, old *sigset) {
- rtsigprocmask(how, new, old, int32(unsafe.Sizeof(*new)))
-}
-
-func raise(sig uint32)
-func raiseproc(sig uint32)
-
-//go:noescape
-func sched_getaffinity(pid, len uintptr, buf *byte) int32
-func osyield()
-
-//go:nosplit
-func osyield_no_g() {
- osyield()
-}
-
-func pipe2(flags int32) (r, w int32, errno int32)
-
-//go:nosplit
-func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
- r, _, err := syscall.Syscall6(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
- return int32(r), int32(err)
-}
-
-const (
- _si_max_size = 128
- _sigev_max_size = 64
-)
-
-//go:nosplit
-//go:nowritebarrierrec
-func setsig(i uint32, fn uintptr) {
- var sa sigactiont
- sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTORER | _SA_RESTART
- sigfillset(&sa.sa_mask)
- // Although Linux manpage says "sa_restorer element is obsolete and
- // should not be used". x86_64 kernel requires it. Only use it on
- // x86.
- if GOARCH == "386" || GOARCH == "amd64" {
- sa.sa_restorer = abi.FuncPCABI0(sigreturn)
- }
- if fn == abi.FuncPCABIInternal(sighandler) { // abi.FuncPCABIInternal(sighandler) matches the callers in signal_unix.go
- if iscgo {
- fn = abi.FuncPCABI0(cgoSigtramp)
- } else {
- fn = abi.FuncPCABI0(sigtramp)
- }
- }
- sa.sa_handler = fn
- sigaction(i, &sa, nil)
-}
-
-//go:nosplit
-//go:nowritebarrierrec
-func setsigstack(i uint32) {
- var sa sigactiont
- sigaction(i, nil, &sa)
- if sa.sa_flags&_SA_ONSTACK != 0 {
- return
- }
- sa.sa_flags |= _SA_ONSTACK
- sigaction(i, &sa, nil)
-}
-
-//go:nosplit
-//go:nowritebarrierrec
-func getsig(i uint32) uintptr {
- var sa sigactiont
- sigaction(i, nil, &sa)
- return sa.sa_handler
-}
-
-// setSignalstackSP sets the ss_sp field of a stackt.
-//
-//go:nosplit
-func setSignalstackSP(s *stackt, sp uintptr) {
- *(*uintptr)(unsafe.Pointer(&s.ss_sp)) = sp
-}
-
-//go:nosplit
-func (c *sigctxt) fixsigcode(sig uint32) {
-}
-
-// sysSigaction calls the rt_sigaction system call.
-//
-//go:nosplit
-func sysSigaction(sig uint32, new, old *sigactiont) {
- if rt_sigaction(uintptr(sig), new, old, unsafe.Sizeof(sigactiont{}.sa_mask)) != 0 {
- // Workaround for bugs in QEMU user mode emulation.
- //
- // QEMU turns calls to the sigaction system call into
- // calls to the C library sigaction call; the C
- // library call rejects attempts to call sigaction for
- // SIGCANCEL (32) or SIGSETXID (33).
- //
- // QEMU rejects calling sigaction on SIGRTMAX (64).
- //
- // Just ignore the error in these case. There isn't
- // anything we can do about it anyhow.
- if sig != 32 && sig != 33 && sig != 64 {
- // Use system stack to avoid split stack overflow on ppc64/ppc64le.
- systemstack(func() {
- throw("sigaction failed")
- })
- }
- }
-}
-
-// rt_sigaction is implemented in assembly.
-//
-//go:noescape
-func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32
-
-func getpid() int
-func tgkill(tgid, tid, sig int)
-
-// signalM sends a signal to mp.
-func signalM(mp *m, sig int) {
- tgkill(getpid(), int(mp.procid), sig)
-}
-
-// go118UseTimerCreateProfiler enables the per-thread CPU profiler.
-const go118UseTimerCreateProfiler = true
-
-// validSIGPROF compares this signal delivery's code against the signal sources
-// that the profiler uses, returning whether the delivery should be processed.
-// To be processed, a signal delivery from a known profiling mechanism should
-// correspond to the best profiling mechanism available to this thread. Signals
-// from other sources are always considered valid.
-//
-//go:nosplit
-func validSIGPROF(mp *m, c *sigctxt) bool {
- code := int32(c.sigcode())
- setitimer := code == _SI_KERNEL
- timer_create := code == _SI_TIMER
-
- if !(setitimer || timer_create) {
- // The signal doesn't correspond to a profiling mechanism that the
- // runtime enables itself. There's no reason to process it, but there's
- // no reason to ignore it either.
- return true
- }
-
- if mp == nil {
- // Since we don't have an M, we can't check if there's an active
- // per-thread timer for this thread. We don't know how long this thread
- // has been around, and if it happened to interact with the Go scheduler
- // at a time when profiling was active (causing it to have a per-thread
- // timer). But it may have never interacted with the Go scheduler, or
- // never while profiling was active. To avoid double-counting, process
- // only signals from setitimer.
- //
- // When a custom cgo traceback function has been registered (on
- // platforms that support runtime.SetCgoTraceback), SIGPROF signals
- // delivered to a thread that cannot find a matching M do this check in
- // the assembly implementations of runtime.cgoSigtramp.
- return setitimer
- }
-
- // Having an M means the thread interacts with the Go scheduler, and we can
- // check whether there's an active per-thread timer for this thread.
- if mp.profileTimerValid.Load() {
- // If this M has its own per-thread CPU profiling interval timer, we
- // should track the SIGPROF signals that come from that timer (for
- // accurate reporting of its CPU usage; see issue 35057) and ignore any
- // that it gets from the process-wide setitimer (to not over-count its
- // CPU consumption).
- return timer_create
- }
-
- // No active per-thread timer means the only valid profiler is setitimer.
- return setitimer
-}
-
-func setProcessCPUProfiler(hz int32) {
- setProcessCPUProfilerTimer(hz)
-}
-
-func setThreadCPUProfiler(hz int32) {
- mp := getg().m
- mp.profilehz = hz
-
- if !go118UseTimerCreateProfiler {
- return
- }
-
- // destroy any active timer
- if mp.profileTimerValid.Load() {
- timerid := mp.profileTimer
- mp.profileTimerValid.Store(false)
- mp.profileTimer = 0
-
- ret := timer_delete(timerid)
- if ret != 0 {
- print("runtime: failed to disable profiling timer; timer_delete(", timerid, ") errno=", -ret, "\n")
- throw("timer_delete")
- }
- }
-
- if hz == 0 {
- // If the goal was to disable profiling for this thread, then the job's done.
- return
- }
-
- // The period of the timer should be 1/Hz. For every "1/Hz" of additional
- // work, the user should expect one additional sample in the profile.
- //
- // But to scale down to very small amounts of application work, to observe
- // even CPU usage of "one tenth" of the requested period, set the initial
- // timing delay in a different way: So that "one tenth" of a period of CPU
- // spend shows up as a 10% chance of one sample (for an expected value of
- // 0.1 samples), and so that "two and six tenths" periods of CPU spend show
- // up as a 60% chance of 3 samples and a 40% chance of 2 samples (for an
- // expected value of 2.6). Set the initial delay to a value in the unifom
- // random distribution between 0 and the desired period. And because "0"
- // means "disable timer", add 1 so the half-open interval [0,period) turns
- // into (0,period].
- //
- // Otherwise, this would show up as a bias away from short-lived threads and
- // from threads that are only occasionally active: for example, when the
- // garbage collector runs on a mostly-idle system, the additional threads it
- // activates may do a couple milliseconds of GC-related work and nothing
- // else in the few seconds that the profiler observes.
- spec := new(itimerspec)
- spec.it_value.setNsec(1 + int64(fastrandn(uint32(1e9/hz))))
- spec.it_interval.setNsec(1e9 / int64(hz))
-
- var timerid int32
- var sevp sigevent
- sevp.notify = _SIGEV_THREAD_ID
- sevp.signo = _SIGPROF
- sevp.sigev_notify_thread_id = int32(mp.procid)
- ret := timer_create(_CLOCK_THREAD_CPUTIME_ID, &sevp, &timerid)
- if ret != 0 {
- // If we cannot create a timer for this M, leave profileTimerValid false
- // to fall back to the process-wide setitimer profiler.
- return
- }
-
- ret = timer_settime(timerid, 0, spec, nil)
- if ret != 0 {
- print("runtime: failed to configure profiling timer; timer_settime(", timerid,
- ", 0, {interval: {",
- spec.it_interval.tv_sec, "s + ", spec.it_interval.tv_nsec, "ns} value: {",
- spec.it_value.tv_sec, "s + ", spec.it_value.tv_nsec, "ns}}, nil) errno=", -ret, "\n")
- throw("timer_settime")
- }
-
- mp.profileTimer = timerid
- mp.profileTimerValid.Store(true)
-}
-
-// perThreadSyscallArgs contains the system call number, arguments, and
-// expected return values for a system call to be executed on all threads.
-type perThreadSyscallArgs struct {
- trap uintptr
- a1 uintptr
- a2 uintptr
- a3 uintptr
- a4 uintptr
- a5 uintptr
- a6 uintptr
- r1 uintptr
- r2 uintptr
-}
-
-// perThreadSyscall is the system call to execute for the ongoing
-// doAllThreadsSyscall.
-//
-// perThreadSyscall may only be written while mp.needPerThreadSyscall == 0 on
-// all Ms.
-var perThreadSyscall perThreadSyscallArgs
-
-// syscall_runtime_doAllThreadsSyscall and executes a specified system call on
-// all Ms.
-//
-// The system call is expected to succeed and return the same value on every
-// thread. If any threads do not match, the runtime throws.
-//
-//go:linkname syscall_runtime_doAllThreadsSyscall syscall.runtime_doAllThreadsSyscall
-//go:uintptrescapes
-func syscall_runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
- if iscgo {
- // In cgo, we are not aware of threads created in C, so this approach will not work.
- panic("doAllThreadsSyscall not supported with cgo enabled")
- }
-
- // STW to guarantee that user goroutines see an atomic change to thread
- // state. Without STW, goroutines could migrate Ms while change is in
- // progress and e.g., see state old -> new -> old -> new.
- //
- // N.B. Internally, this function does not depend on STW to
- // successfully change every thread. It is only needed for user
- // expectations, per above.
- stopTheWorld("doAllThreadsSyscall")
-
- // This function depends on several properties:
- //
- // 1. All OS threads that already exist are associated with an M in
- // allm. i.e., we won't miss any pre-existing threads.
- // 2. All Ms listed in allm will eventually have an OS thread exist.
- // i.e., they will set procid and be able to receive signals.
- // 3. OS threads created after we read allm will clone from a thread
- // that has executed the system call. i.e., they inherit the
- // modified state.
- //
- // We achieve these through different mechanisms:
- //
- // 1. Addition of new Ms to allm in allocm happens before clone of its
- // OS thread later in newm.
- // 2. newm does acquirem to avoid being preempted, ensuring that new Ms
- // created in allocm will eventually reach OS thread clone later in
- // newm.
- // 3. We take allocmLock for write here to prevent allocation of new Ms
- // while this function runs. Per (1), this prevents clone of OS
- // threads that are not yet in allm.
- allocmLock.lock()
-
- // Disable preemption, preventing us from changing Ms, as we handle
- // this M specially.
- //
- // N.B. STW and lock() above do this as well, this is added for extra
- // clarity.
- acquirem()
-
- // N.B. allocmLock also prevents concurrent execution of this function,
- // serializing use of perThreadSyscall, mp.needPerThreadSyscall, and
- // ensuring all threads execute system calls from multiple calls in the
- // same order.
-
- r1, r2, errno := syscall.Syscall6(trap, a1, a2, a3, a4, a5, a6)
- if GOARCH == "ppc64" || GOARCH == "ppc64le" {
- // TODO(https://go.dev/issue/51192 ): ppc64 doesn't use r2.
- r2 = 0
- }
- if errno != 0 {
- releasem(getg().m)
- allocmLock.unlock()
- startTheWorld()
- return r1, r2, errno
- }
-
- perThreadSyscall = perThreadSyscallArgs{
- trap: trap,
- a1: a1,
- a2: a2,
- a3: a3,
- a4: a4,
- a5: a5,
- a6: a6,
- r1: r1,
- r2: r2,
- }
-
- // Wait for all threads to start.
- //
- // As described above, some Ms have been added to allm prior to
- // allocmLock, but not yet completed OS clone and set procid.
- //
- // At minimum we must wait for a thread to set procid before we can
- // send it a signal.
- //
- // We take this one step further and wait for all threads to start
- // before sending any signals. This prevents system calls from getting
- // applied twice: once in the parent and once in the child, like so:
- //
- // A B C
- // add C to allm
- // doAllThreadsSyscall
- // allocmLock.lock()
- // signal B
- // <receive signal>
- // execute syscall
- // <signal return>
- // clone C
- // <thread start>
- // set procid
- // signal C
- // <receive signal>
- // execute syscall
- // <signal return>
- //
- // In this case, thread C inherited the syscall-modified state from
- // thread B and did not need to execute the syscall, but did anyway
- // because doAllThreadsSyscall could not be sure whether it was
- // required.
- //
- // Some system calls may not be idempotent, so we ensure each thread
- // executes the system call exactly once.
- for mp := allm; mp != nil; mp = mp.alllink {
- for atomic.Load64(&mp.procid) == 0 {
- // Thread is starting.
- osyield()
- }
- }
-
- // Signal every other thread, where they will execute perThreadSyscall
- // from the signal handler.
- gp := getg()
- tid := gp.m.procid
- for mp := allm; mp != nil; mp = mp.alllink {
- if atomic.Load64(&mp.procid) == tid {
- // Our thread already performed the syscall.
- continue
- }
- mp.needPerThreadSyscall.Store(1)
- signalM(mp, sigPerThreadSyscall)
- }
-
- // Wait for all threads to complete.
- for mp := allm; mp != nil; mp = mp.alllink {
- if mp.procid == tid {
- continue
- }
- for mp.needPerThreadSyscall.Load() != 0 {
- osyield()
- }
- }
-
- perThreadSyscall = perThreadSyscallArgs{}
-
- releasem(getg().m)
- allocmLock.unlock()
- startTheWorld()
-
- return r1, r2, errno
-}
-
-// runPerThreadSyscall runs perThreadSyscall for this M if required.
-//
-// This function throws if the system call returns with anything other than the
-// expected values.
-//
-//go:nosplit
-func runPerThreadSyscall() {
- gp := getg()
- if gp.m.needPerThreadSyscall.Load() == 0 {
- return
- }
-
- args := perThreadSyscall
- r1, r2, errno := syscall.Syscall6(args.trap, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6)
- if GOARCH == "ppc64" || GOARCH == "ppc64le" {
- // TODO(https://go.dev/issue/51192 ): ppc64 doesn't use r2.
- r2 = 0
- }
- if errno != 0 || r1 != args.r1 || r2 != args.r2 {
- print("trap:", args.trap, ", a123456=[", args.a1, ",", args.a2, ",", args.a3, ",", args.a4, ",", args.a5, ",", args.a6, "]\n")
- print("results: got {r1=", r1, ",r2=", r2, ",errno=", errno, "}, want {r1=", args.r1, ",r2=", args.r2, ",errno=0}\n")
- fatal("AllThreadsSyscall6 results differ between threads; runtime corrupted")
- }
-
- gp.m.needPerThreadSyscall.Store(0)
-}
-
-const (
- _SI_USER = 0
- _SI_TKILL = -6
-)
-
-// sigFromUser reports whether the signal was sent because of a call
-// to kill or tgkill.
-//
-//go:nosplit
-func (c *sigctxt) sigFromUser() bool {
- code := int32(c.sigcode())
- return code == _SI_USER || code == _SI_TKILL
-}
diff --git a/contrib/go/_std_1.20/src/runtime/os_windows.go b/contrib/go/_std_1.20/src/runtime/os_windows.go
deleted file mode 100644
index 44718f1d21..0000000000
--- a/contrib/go/_std_1.20/src/runtime/os_windows.go
+++ /dev/null
@@ -1,1470 +0,0 @@
-// Copyright 2009 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 runtime
-
-import (
- "internal/abi"
- "internal/goarch"
- "runtime/internal/atomic"
- "unsafe"
-)
-
-// TODO(brainman): should not need those
-const (
- _NSIG = 65
-)
-
-//go:cgo_import_dynamic runtime._AddVectoredExceptionHandler AddVectoredExceptionHandler%2 "kernel32.dll"
-//go:cgo_import_dynamic runtime._CloseHandle CloseHandle%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._CreateEventA CreateEventA%4 "kernel32.dll"
-//go:cgo_import_dynamic runtime._CreateFileA CreateFileA%7 "kernel32.dll"
-//go:cgo_import_dynamic runtime._CreateIoCompletionPort CreateIoCompletionPort%4 "kernel32.dll"
-//go:cgo_import_dynamic runtime._CreateThread CreateThread%6 "kernel32.dll"
-//go:cgo_import_dynamic runtime._CreateWaitableTimerA CreateWaitableTimerA%3 "kernel32.dll"
-//go:cgo_import_dynamic runtime._CreateWaitableTimerExW CreateWaitableTimerExW%4 "kernel32.dll"
-//go:cgo_import_dynamic runtime._DuplicateHandle DuplicateHandle%7 "kernel32.dll"
-//go:cgo_import_dynamic runtime._ExitProcess ExitProcess%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._FreeEnvironmentStringsW FreeEnvironmentStringsW%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._GetConsoleMode GetConsoleMode%2 "kernel32.dll"
-//go:cgo_import_dynamic runtime._GetEnvironmentStringsW GetEnvironmentStringsW%0 "kernel32.dll"
-//go:cgo_import_dynamic runtime._GetProcAddress GetProcAddress%2 "kernel32.dll"
-//go:cgo_import_dynamic runtime._GetProcessAffinityMask GetProcessAffinityMask%3 "kernel32.dll"
-//go:cgo_import_dynamic runtime._GetQueuedCompletionStatusEx GetQueuedCompletionStatusEx%6 "kernel32.dll"
-//go:cgo_import_dynamic runtime._GetStdHandle GetStdHandle%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._GetSystemDirectoryA GetSystemDirectoryA%2 "kernel32.dll"
-//go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll"
-//go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll"
-//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll"
-//go:cgo_import_dynamic runtime._ResumeThread ResumeThread%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._SetConsoleCtrlHandler SetConsoleCtrlHandler%2 "kernel32.dll"
-//go:cgo_import_dynamic runtime._SetErrorMode SetErrorMode%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._SetEvent SetEvent%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._SetProcessPriorityBoost SetProcessPriorityBoost%2 "kernel32.dll"
-//go:cgo_import_dynamic runtime._SetThreadPriority SetThreadPriority%2 "kernel32.dll"
-//go:cgo_import_dynamic runtime._SetUnhandledExceptionFilter SetUnhandledExceptionFilter%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._SetWaitableTimer SetWaitableTimer%6 "kernel32.dll"
-//go:cgo_import_dynamic runtime._Sleep Sleep%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._SuspendThread SuspendThread%1 "kernel32.dll"
-//go:cgo_import_dynamic runtime._SwitchToThread SwitchToThread%0 "kernel32.dll"
-//go:cgo_import_dynamic runtime._TlsAlloc TlsAlloc%0 "kernel32.dll"
-//go:cgo_import_dynamic runtime._VirtualAlloc VirtualAlloc%4 "kernel32.dll"
-//go:cgo_import_dynamic runtime._VirtualFree VirtualFree%3 "kernel32.dll"
-//go:cgo_import_dynamic runtime._VirtualQuery VirtualQuery%3 "kernel32.dll"
-//go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject%2 "kernel32.dll"
-//go:cgo_import_dynamic runtime._WaitForMultipleObjects WaitForMultipleObjects%4 "kernel32.dll"
-//go:cgo_import_dynamic runtime._WriteConsoleW WriteConsoleW%5 "kernel32.dll"
-//go:cgo_import_dynamic runtime._WriteFile WriteFile%5 "kernel32.dll"
-
-type stdFunction unsafe.Pointer
-
-var (
- // Following syscalls are available on every Windows PC.
- // All these variables are set by the Windows executable
- // loader before the Go program starts.
- _AddVectoredExceptionHandler,
- _CloseHandle,
- _CreateEventA,
- _CreateFileA,
- _CreateIoCompletionPort,
- _CreateThread,
- _CreateWaitableTimerA,
- _CreateWaitableTimerExW,
- _DuplicateHandle,
- _ExitProcess,
- _FreeEnvironmentStringsW,
- _GetConsoleMode,
- _GetEnvironmentStringsW,
- _GetProcAddress,
- _GetProcessAffinityMask,
- _GetQueuedCompletionStatusEx,
- _GetStdHandle,
- _GetSystemDirectoryA,
- _GetSystemInfo,
- _GetSystemTimeAsFileTime,
- _GetThreadContext,
- _SetThreadContext,
- _LoadLibraryW,
- _LoadLibraryA,
- _PostQueuedCompletionStatus,
- _QueryPerformanceCounter,
- _QueryPerformanceFrequency,
- _ResumeThread,
- _SetConsoleCtrlHandler,
- _SetErrorMode,
- _SetEvent,
- _SetProcessPriorityBoost,
- _SetThreadPriority,
- _SetUnhandledExceptionFilter,
- _SetWaitableTimer,
- _Sleep,
- _SuspendThread,
- _SwitchToThread,
- _TlsAlloc,
- _VirtualAlloc,
- _VirtualFree,
- _VirtualQuery,
- _WaitForSingleObject,
- _WaitForMultipleObjects,
- _WriteConsoleW,
- _WriteFile,
- _ stdFunction
-
- // Following syscalls are only available on some Windows PCs.
- // We will load syscalls, if available, before using them.
- _AddDllDirectory,
- _AddVectoredContinueHandler,
- _LoadLibraryExA,
- _LoadLibraryExW,
- _ stdFunction
-
- // Use RtlGenRandom to generate cryptographically random data.
- // This approach has been recommended by Microsoft (see issue
- // 15589 for details).
- // The RtlGenRandom is not listed in advapi32.dll, instead
- // RtlGenRandom function can be found by searching for SystemFunction036.
- // Also some versions of Mingw cannot link to SystemFunction036
- // when building executable as Cgo. So load SystemFunction036
- // manually during runtime startup.
- _RtlGenRandom stdFunction
-
- // Load ntdll.dll manually during startup, otherwise Mingw
- // links wrong printf function to cgo executable (see issue
- // 12030 for details).
- _NtWaitForSingleObject stdFunction
- _RtlGetCurrentPeb stdFunction
- _RtlGetNtVersionNumbers stdFunction
-
- // These are from non-kernel32.dll, so we prefer to LoadLibraryEx them.
- _timeBeginPeriod,
- _timeEndPeriod,
- _WSAGetOverlappedResult,
- _ stdFunction
-)
-
-// Function to be called by windows CreateThread
-// to start new os thread.
-func tstart_stdcall(newm *m)
-
-// Init-time helper
-func wintls()
-
-type mOS struct {
- threadLock mutex // protects "thread" and prevents closing
- thread uintptr // thread handle
-
- waitsema uintptr // semaphore for parking on locks
- resumesema uintptr // semaphore to indicate suspend/resume
-
- highResTimer uintptr // high resolution timer handle used in usleep
-
- // preemptExtLock synchronizes preemptM with entry/exit from
- // external C code.
- //
- // This protects against races between preemptM calling
- // SuspendThread and external code on this thread calling
- // ExitProcess. If these happen concurrently, it's possible to
- // exit the suspending thread and suspend the exiting thread,
- // leading to deadlock.
- //
- // 0 indicates this M is not being preempted or in external
- // code. Entering external code CASes this from 0 to 1. If
- // this fails, a preemption is in progress, so the thread must
- // wait for the preemption. preemptM also CASes this from 0 to
- // 1. If this fails, the preemption fails (as it would if the
- // PC weren't in Go code). The value is reset to 0 when
- // returning from external code or after a preemption is
- // complete.
- //
- // TODO(austin): We may not need this if preemption were more
- // tightly synchronized on the G/P status and preemption
- // blocked transition into _Gsyscall/_Psyscall.
- preemptExtLock uint32
-}
-
-//go:linkname os_sigpipe os.sigpipe
-func os_sigpipe() {
- throw("too many writes on closed pipe")
-}
-
-// Stubs so tests can link correctly. These should never be called.
-func open(name *byte, mode, perm int32) int32 {
- throw("unimplemented")
- return -1
-}
-func closefd(fd int32) int32 {
- throw("unimplemented")
- return -1
-}
-func read(fd int32, p unsafe.Pointer, n int32) int32 {
- throw("unimplemented")
- return -1
-}
-
-type sigset struct{}
-
-// Call a Windows function with stdcall conventions,
-// and switch to os stack during the call.
-func asmstdcall(fn unsafe.Pointer)
-
-var asmstdcallAddr unsafe.Pointer
-
-func windowsFindfunc(lib uintptr, name []byte) stdFunction {
- if name[len(name)-1] != 0 {
- throw("usage")
- }
- f := stdcall2(_GetProcAddress, lib, uintptr(unsafe.Pointer(&name[0])))
- return stdFunction(unsafe.Pointer(f))
-}
-
-const _MAX_PATH = 260 // https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
-var sysDirectory [_MAX_PATH + 1]byte
-var sysDirectoryLen uintptr
-
-func windowsLoadSystemLib(name []byte) uintptr {
- if sysDirectoryLen == 0 {
- l := stdcall2(_GetSystemDirectoryA, uintptr(unsafe.Pointer(&sysDirectory[0])), uintptr(len(sysDirectory)-1))
- if l == 0 || l > uintptr(len(sysDirectory)-1) {
- throw("Unable to determine system directory")
- }
- sysDirectory[l] = '\\'
- sysDirectoryLen = l + 1
- }
- if useLoadLibraryEx {
- return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32)
- } else {
- absName := append(sysDirectory[:sysDirectoryLen], name...)
- return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0])))
- }
-}
-
-const haveCputicksAsm = GOARCH == "386" || GOARCH == "amd64"
-
-func loadOptionalSyscalls() {
- var kernel32dll = []byte("kernel32.dll\000")
- k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0])))
- if k32 == 0 {
- throw("kernel32.dll not found")
- }
- _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000"))
- _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000"))
- _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000"))
- _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000"))
- useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil)
-
- var advapi32dll = []byte("advapi32.dll\000")
- a32 := windowsLoadSystemLib(advapi32dll)
- if a32 == 0 {
- throw("advapi32.dll not found")
- }
- _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000"))
-
- var ntdll = []byte("ntdll.dll\000")
- n32 := windowsLoadSystemLib(ntdll)
- if n32 == 0 {
- throw("ntdll.dll not found")
- }
- _NtWaitForSingleObject = windowsFindfunc(n32, []byte("NtWaitForSingleObject\000"))
- _RtlGetCurrentPeb = windowsFindfunc(n32, []byte("RtlGetCurrentPeb\000"))
- _RtlGetNtVersionNumbers = windowsFindfunc(n32, []byte("RtlGetNtVersionNumbers\000"))
-
- if !haveCputicksAsm {
- _QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
- if _QueryPerformanceCounter == nil {
- throw("could not find QPC syscalls")
- }
- }
-
- var winmmdll = []byte("winmm.dll\000")
- m32 := windowsLoadSystemLib(winmmdll)
- if m32 == 0 {
- throw("winmm.dll not found")
- }
- _timeBeginPeriod = windowsFindfunc(m32, []byte("timeBeginPeriod\000"))
- _timeEndPeriod = windowsFindfunc(m32, []byte("timeEndPeriod\000"))
- if _timeBeginPeriod == nil || _timeEndPeriod == nil {
- throw("timeBegin/EndPeriod not found")
- }
-
- var ws232dll = []byte("ws2_32.dll\000")
- ws232 := windowsLoadSystemLib(ws232dll)
- if ws232 == 0 {
- throw("ws2_32.dll not found")
- }
- _WSAGetOverlappedResult = windowsFindfunc(ws232, []byte("WSAGetOverlappedResult\000"))
- if _WSAGetOverlappedResult == nil {
- throw("WSAGetOverlappedResult not found")
- }
-
- if windowsFindfunc(n32, []byte("wine_get_version\000")) != nil {
- // running on Wine
- initWine(k32)
- }
-}
-
-func monitorSuspendResume() {
- const (
- _DEVICE_NOTIFY_CALLBACK = 2
- )
- type _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS struct {
- callback uintptr
- context uintptr
- }
-
- powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000"))
- if powrprof == 0 {
- return // Running on Windows 7, where we don't need it anyway.
- }
- powerRegisterSuspendResumeNotification := windowsFindfunc(powrprof, []byte("PowerRegisterSuspendResumeNotification\000"))
- if powerRegisterSuspendResumeNotification == nil {
- return // Running on Windows 7, where we don't need it anyway.
- }
- var fn any = func(context uintptr, changeType uint32, setting uintptr) uintptr {
- for mp := (*m)(atomic.Loadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink {
- if mp.resumesema != 0 {
- stdcall1(_SetEvent, mp.resumesema)
- }
- }
- return 0
- }
- params := _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS{
- callback: compileCallback(*efaceOf(&fn), true),
- }
- handle := uintptr(0)
- stdcall3(powerRegisterSuspendResumeNotification, _DEVICE_NOTIFY_CALLBACK,
- uintptr(unsafe.Pointer(&params)), uintptr(unsafe.Pointer(&handle)))
-}
-
-//go:nosplit
-func getLoadLibrary() uintptr {
- return uintptr(unsafe.Pointer(_LoadLibraryW))
-}
-
-//go:nosplit
-func getLoadLibraryEx() uintptr {
- return uintptr(unsafe.Pointer(_LoadLibraryExW))
-}
-
-//go:nosplit
-func getGetProcAddress() uintptr {
- return uintptr(unsafe.Pointer(_GetProcAddress))
-}
-
-func getproccount() int32 {
- var mask, sysmask uintptr
- ret := stdcall3(_GetProcessAffinityMask, currentProcess, uintptr(unsafe.Pointer(&mask)), uintptr(unsafe.Pointer(&sysmask)))
- if ret != 0 {
- n := 0
- maskbits := int(unsafe.Sizeof(mask) * 8)
- for i := 0; i < maskbits; i++ {
- if mask&(1<<uint(i)) != 0 {
- n++
- }
- }
- if n != 0 {
- return int32(n)
- }
- }
- // use GetSystemInfo if GetProcessAffinityMask fails
- var info systeminfo
- stdcall1(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
- return int32(info.dwnumberofprocessors)
-}
-
-func getPageSize() uintptr {
- var info systeminfo
- stdcall1(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
- return uintptr(info.dwpagesize)
-}
-
-const (
- currentProcess = ^uintptr(0) // -1 = current process
- currentThread = ^uintptr(1) // -2 = current thread
-)
-
-// in sys_windows_386.s and sys_windows_amd64.s:
-func getlasterror() uint32
-
-// When loading DLLs, we prefer to use LoadLibraryEx with
-// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not
-// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_*
-// flags are not available on some versions of Windows without a
-// security patch.
-//
-// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says:
-// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows
-// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on
-// systems that have KB2533623 installed. To determine whether the
-// flags are available, use GetProcAddress to get the address of the
-// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories
-// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_*
-// flags can be used with LoadLibraryEx."
-var useLoadLibraryEx bool
-
-var timeBeginPeriodRetValue uint32
-
-// osRelaxMinNS indicates that sysmon shouldn't osRelax if the next
-// timer is less than 60 ms from now. Since osRelaxing may reduce
-// timer resolution to 15.6 ms, this keeps timer error under roughly 1
-// part in 4.
-const osRelaxMinNS = 60 * 1e6
-
-// osRelax is called by the scheduler when transitioning to and from
-// all Ps being idle.
-//
-// Some versions of Windows have high resolution timer. For those
-// versions osRelax is noop.
-// For Windows versions without high resolution timer, osRelax
-// adjusts the system-wide timer resolution. Go needs a
-// high resolution timer while running and there's little extra cost
-// if we're already using the CPU, but if all Ps are idle there's no
-// need to consume extra power to drive the high-res timer.
-func osRelax(relax bool) uint32 {
- if haveHighResTimer {
- // If the high resolution timer is available, the runtime uses the timer
- // to sleep for short durations. This means there's no need to adjust
- // the global clock frequency.
- return 0
- }
-
- if relax {
- return uint32(stdcall1(_timeEndPeriod, 1))
- } else {
- return uint32(stdcall1(_timeBeginPeriod, 1))
- }
-}
-
-// haveHighResTimer indicates that the CreateWaitableTimerEx
-// CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag is available.
-var haveHighResTimer = false
-
-// createHighResTimer calls CreateWaitableTimerEx with
-// CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag to create high
-// resolution timer. createHighResTimer returns new timer
-// handle or 0, if CreateWaitableTimerEx failed.
-func createHighResTimer() uintptr {
- const (
- // As per @jstarks, see
- // https://github.com/golang/go/issues/8687#issuecomment-656259353
- _CREATE_WAITABLE_TIMER_HIGH_RESOLUTION = 0x00000002
-
- _SYNCHRONIZE = 0x00100000
- _TIMER_QUERY_STATE = 0x0001
- _TIMER_MODIFY_STATE = 0x0002
- )
- return stdcall4(_CreateWaitableTimerExW, 0, 0,
- _CREATE_WAITABLE_TIMER_HIGH_RESOLUTION,
- _SYNCHRONIZE|_TIMER_QUERY_STATE|_TIMER_MODIFY_STATE)
-}
-
-const highResTimerSupported = GOARCH == "386" || GOARCH == "amd64"
-
-func initHighResTimer() {
- if !highResTimerSupported {
- // TODO: Not yet implemented.
- return
- }
- h := createHighResTimer()
- if h != 0 {
- haveHighResTimer = true
- stdcall1(_CloseHandle, h)
- }
-}
-
-//go:linkname canUseLongPaths os.canUseLongPaths
-var canUseLongPaths bool
-
-// We want this to be large enough to hold the contents of sysDirectory, *plus*
-// a slash and another component that itself is greater than MAX_PATH.
-var longFileName [(_MAX_PATH+1)*2 + 1]byte
-
-// initLongPathSupport initializes the canUseLongPaths variable, which is
-// linked into os.canUseLongPaths for determining whether or not long paths
-// need to be fixed up. In the best case, this function is running on newer
-// Windows 10 builds, which have a bit field member of the PEB called
-// "IsLongPathAwareProcess." When this is set, we don't need to go through the
-// error-prone fixup function in order to access long paths. So this init
-// function first checks the Windows build number, sets the flag, and then
-// tests to see if it's actually working. If everything checks out, then
-// canUseLongPaths is set to true, and later when called, os.fixLongPath
-// returns early without doing work.
-func initLongPathSupport() {
- const (
- IsLongPathAwareProcess = 0x80
- PebBitFieldOffset = 3
- OPEN_EXISTING = 3
- ERROR_PATH_NOT_FOUND = 3
- )
-
- // Check that we're ≥ 10.0.15063.
- var maj, min, build uint32
- stdcall3(_RtlGetNtVersionNumbers, uintptr(unsafe.Pointer(&maj)), uintptr(unsafe.Pointer(&min)), uintptr(unsafe.Pointer(&build)))
- if maj < 10 || (maj == 10 && min == 0 && build&0xffff < 15063) {
- return
- }
-
- // Set the IsLongPathAwareProcess flag of the PEB's bit field.
- bitField := (*byte)(unsafe.Pointer(stdcall0(_RtlGetCurrentPeb) + PebBitFieldOffset))
- originalBitField := *bitField
- *bitField |= IsLongPathAwareProcess
-
- // Check that this actually has an effect, by constructing a large file
- // path and seeing whether we get ERROR_PATH_NOT_FOUND, rather than
- // some other error, which would indicate the path is too long, and
- // hence long path support is not successful. This whole section is NOT
- // strictly necessary, but is a nice validity check for the near to
- // medium term, when this functionality is still relatively new in
- // Windows.
- getRandomData(longFileName[len(longFileName)-33 : len(longFileName)-1])
- start := copy(longFileName[:], sysDirectory[:sysDirectoryLen])
- const dig = "0123456789abcdef"
- for i := 0; i < 32; i++ {
- longFileName[start+i*2] = dig[longFileName[len(longFileName)-33+i]>>4]
- longFileName[start+i*2+1] = dig[longFileName[len(longFileName)-33+i]&0xf]
- }
- start += 64
- for i := start; i < len(longFileName)-1; i++ {
- longFileName[i] = 'A'
- }
- stdcall7(_CreateFileA, uintptr(unsafe.Pointer(&longFileName[0])), 0, 0, 0, OPEN_EXISTING, 0, 0)
- // The ERROR_PATH_NOT_FOUND error value is distinct from
- // ERROR_FILE_NOT_FOUND or ERROR_INVALID_NAME, the latter of which we
- // expect here due to the final component being too long.
- if getlasterror() == ERROR_PATH_NOT_FOUND {
- *bitField = originalBitField
- println("runtime: warning: IsLongPathAwareProcess failed to enable long paths; proceeding in fixup mode")
- return
- }
-
- canUseLongPaths = true
-}
-
-func osinit() {
- asmstdcallAddr = unsafe.Pointer(abi.FuncPCABI0(asmstdcall))
-
- setBadSignalMsg()
-
- loadOptionalSyscalls()
-
- disableWER()
-
- initExceptionHandler()
-
- initHighResTimer()
- timeBeginPeriodRetValue = osRelax(false)
-
- initLongPathSupport()
-
- ncpu = getproccount()
-
- physPageSize = getPageSize()
-
- // Windows dynamic priority boosting assumes that a process has different types
- // of dedicated threads -- GUI, IO, computational, etc. Go processes use
- // equivalent threads that all do a mix of GUI, IO, computations, etc.
- // In such context dynamic priority boosting does nothing but harm, so we turn it off.
- stdcall2(_SetProcessPriorityBoost, currentProcess, 1)
-}
-
-// useQPCTime controls whether time.now and nanotime use QueryPerformanceCounter.
-// This is only set to 1 when running under Wine.
-var useQPCTime uint8
-
-var qpcStartCounter int64
-var qpcMultiplier int64
-
-//go:nosplit
-func nanotimeQPC() int64 {
- var counter int64 = 0
- stdcall1(_QueryPerformanceCounter, uintptr(unsafe.Pointer(&counter)))
-
- // returns number of nanoseconds
- return (counter - qpcStartCounter) * qpcMultiplier
-}
-
-//go:nosplit
-func nowQPC() (sec int64, nsec int32, mono int64) {
- var ft int64
- stdcall1(_GetSystemTimeAsFileTime, uintptr(unsafe.Pointer(&ft)))
-
- t := (ft - 116444736000000000) * 100
-
- sec = t / 1000000000
- nsec = int32(t - sec*1000000000)
-
- mono = nanotimeQPC()
- return
-}
-
-func initWine(k32 uintptr) {
- _GetSystemTimeAsFileTime = windowsFindfunc(k32, []byte("GetSystemTimeAsFileTime\000"))
- if _GetSystemTimeAsFileTime == nil {
- throw("could not find GetSystemTimeAsFileTime() syscall")
- }
-
- _QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
- _QueryPerformanceFrequency = windowsFindfunc(k32, []byte("QueryPerformanceFrequency\000"))
- if _QueryPerformanceCounter == nil || _QueryPerformanceFrequency == nil {
- throw("could not find QPC syscalls")
- }
-
- // We can not simply fallback to GetSystemTimeAsFileTime() syscall, since its time is not monotonic,
- // instead we use QueryPerformanceCounter family of syscalls to implement monotonic timer
- // https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
-
- var tmp int64
- stdcall1(_QueryPerformanceFrequency, uintptr(unsafe.Pointer(&tmp)))
- if tmp == 0 {
- throw("QueryPerformanceFrequency syscall returned zero, running on unsupported hardware")
- }
-
- // This should not overflow, it is a number of ticks of the performance counter per second,
- // its resolution is at most 10 per usecond (on Wine, even smaller on real hardware), so it will be at most 10 millions here,
- // panic if overflows.
- if tmp > (1<<31 - 1) {
- throw("QueryPerformanceFrequency overflow 32 bit divider, check nosplit discussion to proceed")
- }
- qpcFrequency := int32(tmp)
- stdcall1(_QueryPerformanceCounter, uintptr(unsafe.Pointer(&qpcStartCounter)))
-
- // Since we are supposed to run this time calls only on Wine, it does not lose precision,
- // since Wine's timer is kind of emulated at 10 Mhz, so it will be a nice round multiplier of 100
- // but for general purpose system (like 3.3 Mhz timer on i7) it will not be very precise.
- // We have to do it this way (or similar), since multiplying QPC counter by 100 millions overflows
- // int64 and resulted time will always be invalid.
- qpcMultiplier = int64(timediv(1000000000, qpcFrequency, nil))
-
- useQPCTime = 1
-}
-
-//go:nosplit
-func getRandomData(r []byte) {
- n := 0
- if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 {
- n = len(r)
- }
- extendRandom(r, n)
-}
-
-func goenvs() {
- // strings is a pointer to environment variable pairs in the form:
- // "envA=valA\x00envB=valB\x00\x00" (in UTF-16)
- // Two consecutive zero bytes end the list.
- strings := unsafe.Pointer(stdcall0(_GetEnvironmentStringsW))
- p := (*[1 << 24]uint16)(strings)[:]
-
- n := 0
- for from, i := 0, 0; true; i++ {
- if p[i] == 0 {
- // empty string marks the end
- if i == from {
- break
- }
- from = i + 1
- n++
- }
- }
- envs = make([]string, n)
-
- for i := range envs {
- envs[i] = gostringw(&p[0])
- for p[0] != 0 {
- p = p[1:]
- }
- p = p[1:] // skip nil byte
- }
-
- stdcall1(_FreeEnvironmentStringsW, uintptr(strings))
-
- // We call these all the way here, late in init, so that malloc works
- // for the callback functions these generate.
- var fn any = ctrlHandler
- ctrlHandlerPC := compileCallback(*efaceOf(&fn), true)
- stdcall2(_SetConsoleCtrlHandler, ctrlHandlerPC, 1)
-
- monitorSuspendResume()
-}
-
-// exiting is set to non-zero when the process is exiting.
-var exiting uint32
-
-//go:nosplit
-func exit(code int32) {
- // Disallow thread suspension for preemption. Otherwise,
- // ExitProcess and SuspendThread can race: SuspendThread
- // queues a suspension request for this thread, ExitProcess
- // kills the suspending thread, and then this thread suspends.
- lock(&suspendLock)
- atomic.Store(&exiting, 1)
- stdcall1(_ExitProcess, uintptr(code))
-}
-
-// write1 must be nosplit because it's used as a last resort in
-// functions like badmorestackg0. In such cases, we'll always take the
-// ASCII path.
-//
-//go:nosplit
-func write1(fd uintptr, buf unsafe.Pointer, n int32) int32 {
- const (
- _STD_OUTPUT_HANDLE = ^uintptr(10) // -11
- _STD_ERROR_HANDLE = ^uintptr(11) // -12
- )
- var handle uintptr
- switch fd {
- case 1:
- handle = stdcall1(_GetStdHandle, _STD_OUTPUT_HANDLE)
- case 2:
- handle = stdcall1(_GetStdHandle, _STD_ERROR_HANDLE)
- default:
- // assume fd is real windows handle.
- handle = fd
- }
- isASCII := true
- b := (*[1 << 30]byte)(buf)[:n]
- for _, x := range b {
- if x >= 0x80 {
- isASCII = false
- break
- }
- }
-
- if !isASCII {
- var m uint32
- isConsole := stdcall2(_GetConsoleMode, handle, uintptr(unsafe.Pointer(&m))) != 0
- // If this is a console output, various non-unicode code pages can be in use.
- // Use the dedicated WriteConsole call to ensure unicode is printed correctly.
- if isConsole {
- return int32(writeConsole(handle, buf, n))
- }
- }
- var written uint32
- stdcall5(_WriteFile, handle, uintptr(buf), uintptr(n), uintptr(unsafe.Pointer(&written)), 0)
- return int32(written)
-}
-
-var (
- utf16ConsoleBack [1000]uint16
- utf16ConsoleBackLock mutex
-)
-
-// writeConsole writes bufLen bytes from buf to the console File.
-// It returns the number of bytes written.
-func writeConsole(handle uintptr, buf unsafe.Pointer, bufLen int32) int {
- const surr2 = (surrogateMin + surrogateMax + 1) / 2
-
- // Do not use defer for unlock. May cause issues when printing a panic.
- lock(&utf16ConsoleBackLock)
-
- b := (*[1 << 30]byte)(buf)[:bufLen]
- s := *(*string)(unsafe.Pointer(&b))
-
- utf16tmp := utf16ConsoleBack[:]
-
- total := len(s)
- w := 0
- for _, r := range s {
- if w >= len(utf16tmp)-2 {
- writeConsoleUTF16(handle, utf16tmp[:w])
- w = 0
- }
- if r < 0x10000 {
- utf16tmp[w] = uint16(r)
- w++
- } else {
- r -= 0x10000
- utf16tmp[w] = surrogateMin + uint16(r>>10)&0x3ff
- utf16tmp[w+1] = surr2 + uint16(r)&0x3ff
- w += 2
- }
- }
- writeConsoleUTF16(handle, utf16tmp[:w])
- unlock(&utf16ConsoleBackLock)
- return total
-}
-
-// writeConsoleUTF16 is the dedicated windows calls that correctly prints
-// to the console regardless of the current code page. Input is utf-16 code points.
-// The handle must be a console handle.
-func writeConsoleUTF16(handle uintptr, b []uint16) {
- l := uint32(len(b))
- if l == 0 {
- return
- }
- var written uint32
- stdcall5(_WriteConsoleW,
- handle,
- uintptr(unsafe.Pointer(&b[0])),
- uintptr(l),
- uintptr(unsafe.Pointer(&written)),
- 0,
- )
- return
-}
-
-//go:nosplit
-func semasleep(ns int64) int32 {
- const (
- _WAIT_ABANDONED = 0x00000080
- _WAIT_OBJECT_0 = 0x00000000
- _WAIT_TIMEOUT = 0x00000102
- _WAIT_FAILED = 0xFFFFFFFF
- )
-
- var result uintptr
- if ns < 0 {
- result = stdcall2(_WaitForSingleObject, getg().m.waitsema, uintptr(_INFINITE))
- } else {
- start := nanotime()
- elapsed := int64(0)
- for {
- ms := int64(timediv(ns-elapsed, 1000000, nil))
- if ms == 0 {
- ms = 1
- }
- result = stdcall4(_WaitForMultipleObjects, 2,
- uintptr(unsafe.Pointer(&[2]uintptr{getg().m.waitsema, getg().m.resumesema})),
- 0, uintptr(ms))
- if result != _WAIT_OBJECT_0+1 {
- // Not a suspend/resume event
- break
- }
- elapsed = nanotime() - start
- if elapsed >= ns {
- return -1
- }
- }
- }
- switch result {
- case _WAIT_OBJECT_0: // Signaled
- return 0
-
- case _WAIT_TIMEOUT:
- return -1
-
- case _WAIT_ABANDONED:
- systemstack(func() {
- throw("runtime.semasleep wait_abandoned")
- })
-
- case _WAIT_FAILED:
- systemstack(func() {
- print("runtime: waitforsingleobject wait_failed; errno=", getlasterror(), "\n")
- throw("runtime.semasleep wait_failed")
- })
-
- default:
- systemstack(func() {
- print("runtime: waitforsingleobject unexpected; result=", result, "\n")
- throw("runtime.semasleep unexpected")
- })
- }
-
- return -1 // unreachable
-}
-
-//go:nosplit
-func semawakeup(mp *m) {
- if stdcall1(_SetEvent, mp.waitsema) == 0 {
- systemstack(func() {
- print("runtime: setevent failed; errno=", getlasterror(), "\n")
- throw("runtime.semawakeup")
- })
- }
-}
-
-//go:nosplit
-func semacreate(mp *m) {
- if mp.waitsema != 0 {
- return
- }
- mp.waitsema = stdcall4(_CreateEventA, 0, 0, 0, 0)
- if mp.waitsema == 0 {
- systemstack(func() {
- print("runtime: createevent failed; errno=", getlasterror(), "\n")
- throw("runtime.semacreate")
- })
- }
- mp.resumesema = stdcall4(_CreateEventA, 0, 0, 0, 0)
- if mp.resumesema == 0 {
- systemstack(func() {
- print("runtime: createevent failed; errno=", getlasterror(), "\n")
- throw("runtime.semacreate")
- })
- stdcall1(_CloseHandle, mp.waitsema)
- mp.waitsema = 0
- }
-}
-
-// May run with m.p==nil, so write barriers are not allowed. This
-// function is called by newosproc0, so it is also required to
-// operate without stack guards.
-//
-//go:nowritebarrierrec
-//go:nosplit
-func newosproc(mp *m) {
- // We pass 0 for the stack size to use the default for this binary.
- thandle := stdcall6(_CreateThread, 0, 0,
- abi.FuncPCABI0(tstart_stdcall), uintptr(unsafe.Pointer(mp)),
- 0, 0)
-
- if thandle == 0 {
- if atomic.Load(&exiting) != 0 {
- // CreateThread may fail if called
- // concurrently with ExitProcess. If this
- // happens, just freeze this thread and let
- // the process exit. See issue #18253.
- lock(&deadlock)
- lock(&deadlock)
- }
- print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", getlasterror(), ")\n")
- throw("runtime.newosproc")
- }
-
- // Close thandle to avoid leaking the thread object if it exits.
- stdcall1(_CloseHandle, thandle)
-}
-
-// Used by the C library build mode. On Linux this function would allocate a
-// stack, but that's not necessary for Windows. No stack guards are present
-// and the GC has not been initialized, so write barriers will fail.
-//
-//go:nowritebarrierrec
-//go:nosplit
-func newosproc0(mp *m, stk unsafe.Pointer) {
- // TODO: this is completely broken. The args passed to newosproc0 (in asm_amd64.s)
- // are stacksize and function, not *m and stack.
- // Check os_linux.go for an implementation that might actually work.
- throw("bad newosproc0")
-}
-
-func exitThread(wait *atomic.Uint32) {
- // We should never reach exitThread on Windows because we let
- // the OS clean up threads.
- throw("exitThread")
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-func mpreinit(mp *m) {
-}
-
-//go:nosplit
-func sigsave(p *sigset) {
-}
-
-//go:nosplit
-func msigrestore(sigmask sigset) {
-}
-
-//go:nosplit
-//go:nowritebarrierrec
-func clearSignalHandlers() {
-}
-
-//go:nosplit
-func sigblock(exiting bool) {
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, cannot allocate memory.
-func minit() {
- var thandle uintptr
- if stdcall7(_DuplicateHandle, currentProcess, currentThread, currentProcess, uintptr(unsafe.Pointer(&thandle)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
- print("runtime.minit: duplicatehandle failed; errno=", getlasterror(), "\n")
- throw("runtime.minit: duplicatehandle failed")
- }
-
- mp := getg().m
- lock(&mp.threadLock)
- mp.thread = thandle
-
- // Configure usleep timer, if possible.
- if mp.highResTimer == 0 && haveHighResTimer {
- mp.highResTimer = createHighResTimer()
- if mp.highResTimer == 0 {
- print("runtime: CreateWaitableTimerEx failed; errno=", getlasterror(), "\n")
- throw("CreateWaitableTimerEx when creating timer failed")
- }
- }
- unlock(&mp.threadLock)
-
- // Query the true stack base from the OS. Currently we're
- // running on a small assumed stack.
- var mbi memoryBasicInformation
- res := stdcall3(_VirtualQuery, uintptr(unsafe.Pointer(&mbi)), uintptr(unsafe.Pointer(&mbi)), unsafe.Sizeof(mbi))
- if res == 0 {
- print("runtime: VirtualQuery failed; errno=", getlasterror(), "\n")
- throw("VirtualQuery for stack base failed")
- }
- // The system leaves an 8K PAGE_GUARD region at the bottom of
- // the stack (in theory VirtualQuery isn't supposed to include
- // that, but it does). Add an additional 8K of slop for
- // calling C functions that don't have stack checks and for
- // lastcontinuehandler. We shouldn't be anywhere near this
- // bound anyway.
- base := mbi.allocationBase + 16<<10
- // Sanity check the stack bounds.
- g0 := getg()
- if base > g0.stack.hi || g0.stack.hi-base > 64<<20 {
- print("runtime: g0 stack [", hex(base), ",", hex(g0.stack.hi), ")\n")
- throw("bad g0 stack")
- }
- g0.stack.lo = base
- g0.stackguard0 = g0.stack.lo + _StackGuard
- g0.stackguard1 = g0.stackguard0
- // Sanity check the SP.
- stackcheck()
-}
-
-// Called from dropm to undo the effect of an minit.
-//
-//go:nosplit
-func unminit() {
- mp := getg().m
- lock(&mp.threadLock)
- if mp.thread != 0 {
- stdcall1(_CloseHandle, mp.thread)
- mp.thread = 0
- }
- unlock(&mp.threadLock)
-}
-
-// Called from exitm, but not from drop, to undo the effect of thread-owned
-// resources in minit, semacreate, or elsewhere. Do not take locks after calling this.
-//
-//go:nosplit
-func mdestroy(mp *m) {
- if mp.highResTimer != 0 {
- stdcall1(_CloseHandle, mp.highResTimer)
- mp.highResTimer = 0
- }
- if mp.waitsema != 0 {
- stdcall1(_CloseHandle, mp.waitsema)
- mp.waitsema = 0
- }
- if mp.resumesema != 0 {
- stdcall1(_CloseHandle, mp.resumesema)
- mp.resumesema = 0
- }
-}
-
-// Calling stdcall on os stack.
-// May run during STW, so write barriers are not allowed.
-//
-//go:nowritebarrier
-//go:nosplit
-func stdcall(fn stdFunction) uintptr {
- gp := getg()
- mp := gp.m
- mp.libcall.fn = uintptr(unsafe.Pointer(fn))
- resetLibcall := false
- if mp.profilehz != 0 && mp.libcallsp == 0 {
- // leave pc/sp for cpu profiler
- mp.libcallg.set(gp)
- mp.libcallpc = getcallerpc()
- // sp must be the last, because once async cpu profiler finds
- // all three values to be non-zero, it will use them
- mp.libcallsp = getcallersp()
- resetLibcall = true // See comment in sys_darwin.go:libcCall
- }
- asmcgocall(asmstdcallAddr, unsafe.Pointer(&mp.libcall))
- if resetLibcall {
- mp.libcallsp = 0
- }
- return mp.libcall.r1
-}
-
-//go:nosplit
-func stdcall0(fn stdFunction) uintptr {
- mp := getg().m
- mp.libcall.n = 0
- mp.libcall.args = uintptr(noescape(unsafe.Pointer(&fn))) // it's unused but must be non-nil, otherwise crashes
- return stdcall(fn)
-}
-
-//go:nosplit
-//go:cgo_unsafe_args
-func stdcall1(fn stdFunction, a0 uintptr) uintptr {
- mp := getg().m
- mp.libcall.n = 1
- mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
- return stdcall(fn)
-}
-
-//go:nosplit
-//go:cgo_unsafe_args
-func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr {
- mp := getg().m
- mp.libcall.n = 2
- mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
- return stdcall(fn)
-}
-
-//go:nosplit
-//go:cgo_unsafe_args
-func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr {
- mp := getg().m
- mp.libcall.n = 3
- mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
- return stdcall(fn)
-}
-
-//go:nosplit
-//go:cgo_unsafe_args
-func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr {
- mp := getg().m
- mp.libcall.n = 4
- mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
- return stdcall(fn)
-}
-
-//go:nosplit
-//go:cgo_unsafe_args
-func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr {
- mp := getg().m
- mp.libcall.n = 5
- mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
- return stdcall(fn)
-}
-
-//go:nosplit
-//go:cgo_unsafe_args
-func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr {
- mp := getg().m
- mp.libcall.n = 6
- mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
- return stdcall(fn)
-}
-
-//go:nosplit
-//go:cgo_unsafe_args
-func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
- mp := getg().m
- mp.libcall.n = 7
- mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
- return stdcall(fn)
-}
-
-// These must run on the system stack only.
-func usleep2(dt int32)
-func usleep2HighRes(dt int32)
-func switchtothread()
-
-//go:nosplit
-func osyield_no_g() {
- switchtothread()
-}
-
-//go:nosplit
-func osyield() {
- systemstack(switchtothread)
-}
-
-//go:nosplit
-func usleep_no_g(us uint32) {
- dt := -10 * int32(us) // relative sleep (negative), 100ns units
- usleep2(dt)
-}
-
-//go:nosplit
-func usleep(us uint32) {
- systemstack(func() {
- dt := -10 * int32(us) // relative sleep (negative), 100ns units
- // If the high-res timer is available and its handle has been allocated for this m, use it.
- // Otherwise fall back to the low-res one, which doesn't need a handle.
- if haveHighResTimer && getg().m.highResTimer != 0 {
- usleep2HighRes(dt)
- } else {
- usleep2(dt)
- }
- })
-}
-
-func ctrlHandler(_type uint32) uintptr {
- var s uint32
-
- switch _type {
- case _CTRL_C_EVENT, _CTRL_BREAK_EVENT:
- s = _SIGINT
- case _CTRL_CLOSE_EVENT, _CTRL_LOGOFF_EVENT, _CTRL_SHUTDOWN_EVENT:
- s = _SIGTERM
- default:
- return 0
- }
-
- if sigsend(s) {
- if s == _SIGTERM {
- // Windows terminates the process after this handler returns.
- // Block indefinitely to give signal handlers a chance to clean up,
- // but make sure to be properly parked first, so the rest of the
- // program can continue executing.
- block()
- }
- return 1
- }
- return 0
-}
-
-// called from zcallback_windows_*.s to sys_windows_*.s
-func callbackasm1()
-
-var profiletimer uintptr
-
-func profilem(mp *m, thread uintptr) {
- // Align Context to 16 bytes.
- var c *context
- var cbuf [unsafe.Sizeof(*c) + 15]byte
- c = (*context)(unsafe.Pointer((uintptr(unsafe.Pointer(&cbuf[15]))) &^ 15))
-
- c.contextflags = _CONTEXT_CONTROL
- stdcall2(_GetThreadContext, thread, uintptr(unsafe.Pointer(c)))
-
- gp := gFromSP(mp, c.sp())
-
- sigprof(c.ip(), c.sp(), c.lr(), gp, mp)
-}
-
-func gFromSP(mp *m, sp uintptr) *g {
- if gp := mp.g0; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
- return gp
- }
- if gp := mp.gsignal; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
- return gp
- }
- if gp := mp.curg; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
- return gp
- }
- return nil
-}
-
-func profileLoop() {
- stdcall2(_SetThreadPriority, currentThread, _THREAD_PRIORITY_HIGHEST)
-
- for {
- stdcall2(_WaitForSingleObject, profiletimer, _INFINITE)
- first := (*m)(atomic.Loadp(unsafe.Pointer(&allm)))
- for mp := first; mp != nil; mp = mp.alllink {
- if mp == getg().m {
- // Don't profile ourselves.
- continue
- }
-
- lock(&mp.threadLock)
- // Do not profile threads blocked on Notes,
- // this includes idle worker threads,
- // idle timer thread, idle heap scavenger, etc.
- if mp.thread == 0 || mp.profilehz == 0 || mp.blocked {
- unlock(&mp.threadLock)
- continue
- }
- // Acquire our own handle to the thread.
- var thread uintptr
- if stdcall7(_DuplicateHandle, currentProcess, mp.thread, currentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
- print("runtime: duplicatehandle failed; errno=", getlasterror(), "\n")
- throw("duplicatehandle failed")
- }
- unlock(&mp.threadLock)
-
- // mp may exit between the DuplicateHandle
- // above and the SuspendThread. The handle
- // will remain valid, but SuspendThread may
- // fail.
- if int32(stdcall1(_SuspendThread, thread)) == -1 {
- // The thread no longer exists.
- stdcall1(_CloseHandle, thread)
- continue
- }
- if mp.profilehz != 0 && !mp.blocked {
- // Pass the thread handle in case mp
- // was in the process of shutting down.
- profilem(mp, thread)
- }
- stdcall1(_ResumeThread, thread)
- stdcall1(_CloseHandle, thread)
- }
- }
-}
-
-func setProcessCPUProfiler(hz int32) {
- if profiletimer == 0 {
- timer := stdcall3(_CreateWaitableTimerA, 0, 0, 0)
- atomic.Storeuintptr(&profiletimer, timer)
- newm(profileLoop, nil, -1)
- }
-}
-
-func setThreadCPUProfiler(hz int32) {
- ms := int32(0)
- due := ^int64(^uint64(1 << 63))
- if hz > 0 {
- ms = 1000 / hz
- if ms == 0 {
- ms = 1
- }
- due = int64(ms) * -10000
- }
- stdcall6(_SetWaitableTimer, profiletimer, uintptr(unsafe.Pointer(&due)), uintptr(ms), 0, 0, 0)
- atomic.Store((*uint32)(unsafe.Pointer(&getg().m.profilehz)), uint32(hz))
-}
-
-const preemptMSupported = true
-
-// suspendLock protects simultaneous SuspendThread operations from
-// suspending each other.
-var suspendLock mutex
-
-func preemptM(mp *m) {
- if mp == getg().m {
- throw("self-preempt")
- }
-
- // Synchronize with external code that may try to ExitProcess.
- if !atomic.Cas(&mp.preemptExtLock, 0, 1) {
- // External code is running. Fail the preemption
- // attempt.
- mp.preemptGen.Add(1)
- return
- }
-
- // Acquire our own handle to mp's thread.
- lock(&mp.threadLock)
- if mp.thread == 0 {
- // The M hasn't been minit'd yet (or was just unminit'd).
- unlock(&mp.threadLock)
- atomic.Store(&mp.preemptExtLock, 0)
- mp.preemptGen.Add(1)
- return
- }
- var thread uintptr
- if stdcall7(_DuplicateHandle, currentProcess, mp.thread, currentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
- print("runtime.preemptM: duplicatehandle failed; errno=", getlasterror(), "\n")
- throw("runtime.preemptM: duplicatehandle failed")
- }
- unlock(&mp.threadLock)
-
- // Prepare thread context buffer. This must be aligned to 16 bytes.
- var c *context
- var cbuf [unsafe.Sizeof(*c) + 15]byte
- c = (*context)(unsafe.Pointer((uintptr(unsafe.Pointer(&cbuf[15]))) &^ 15))
- c.contextflags = _CONTEXT_CONTROL
-
- // Serialize thread suspension. SuspendThread is asynchronous,
- // so it's otherwise possible for two threads to suspend each
- // other and deadlock. We must hold this lock until after
- // GetThreadContext, since that blocks until the thread is
- // actually suspended.
- lock(&suspendLock)
-
- // Suspend the thread.
- if int32(stdcall1(_SuspendThread, thread)) == -1 {
- unlock(&suspendLock)
- stdcall1(_CloseHandle, thread)
- atomic.Store(&mp.preemptExtLock, 0)
- // The thread no longer exists. This shouldn't be
- // possible, but just acknowledge the request.
- mp.preemptGen.Add(1)
- return
- }
-
- // We have to be very careful between this point and once
- // we've shown mp is at an async safe-point. This is like a
- // signal handler in the sense that mp could have been doing
- // anything when we stopped it, including holding arbitrary
- // locks.
-
- // We have to get the thread context before inspecting the M
- // because SuspendThread only requests a suspend.
- // GetThreadContext actually blocks until it's suspended.
- stdcall2(_GetThreadContext, thread, uintptr(unsafe.Pointer(c)))
-
- unlock(&suspendLock)
-
- // Does it want a preemption and is it safe to preempt?
- gp := gFromSP(mp, c.sp())
- if gp != nil && wantAsyncPreempt(gp) {
- if ok, newpc := isAsyncSafePoint(gp, c.ip(), c.sp(), c.lr()); ok {
- // Inject call to asyncPreempt
- targetPC := abi.FuncPCABI0(asyncPreempt)
- switch GOARCH {
- default:
- throw("unsupported architecture")
- case "386", "amd64":
- // Make it look like the thread called targetPC.
- sp := c.sp()
- sp -= goarch.PtrSize
- *(*uintptr)(unsafe.Pointer(sp)) = newpc
- c.set_sp(sp)
- c.set_ip(targetPC)
-
- case "arm":
- // Push LR. The injected call is responsible
- // for restoring LR. gentraceback is aware of
- // this extra slot. See sigctxt.pushCall in
- // signal_arm.go, which is similar except we
- // subtract 1 from IP here.
- sp := c.sp()
- sp -= goarch.PtrSize
- c.set_sp(sp)
- *(*uint32)(unsafe.Pointer(sp)) = uint32(c.lr())
- c.set_lr(newpc - 1)
- c.set_ip(targetPC)
-
- case "arm64":
- // Push LR. The injected call is responsible
- // for restoring LR. gentraceback is aware of
- // this extra slot. See sigctxt.pushCall in
- // signal_arm64.go.
- sp := c.sp() - 16 // SP needs 16-byte alignment
- c.set_sp(sp)
- *(*uint64)(unsafe.Pointer(sp)) = uint64(c.lr())
- c.set_lr(newpc)
- c.set_ip(targetPC)
- }
- stdcall2(_SetThreadContext, thread, uintptr(unsafe.Pointer(c)))
- }
- }
-
- atomic.Store(&mp.preemptExtLock, 0)
-
- // Acknowledge the preemption.
- mp.preemptGen.Add(1)
-
- stdcall1(_ResumeThread, thread)
- stdcall1(_CloseHandle, thread)
-}
-
-// osPreemptExtEnter is called before entering external code that may
-// call ExitProcess.
-//
-// This must be nosplit because it may be called from a syscall with
-// untyped stack slots, so the stack must not be grown or scanned.
-//
-//go:nosplit
-func osPreemptExtEnter(mp *m) {
- for !atomic.Cas(&mp.preemptExtLock, 0, 1) {
- // An asynchronous preemption is in progress. It's not
- // safe to enter external code because it may call
- // ExitProcess and deadlock with SuspendThread.
- // Ideally we would do the preemption ourselves, but
- // can't since there may be untyped syscall arguments
- // on the stack. Instead, just wait and encourage the
- // SuspendThread APC to run. The preemption should be
- // done shortly.
- osyield()
- }
- // Asynchronous preemption is now blocked.
-}
-
-// osPreemptExtExit is called after returning from external code that
-// may call ExitProcess.
-//
-// See osPreemptExtEnter for why this is nosplit.
-//
-//go:nosplit
-func osPreemptExtExit(mp *m) {
- atomic.Store(&mp.preemptExtLock, 0)
-}
diff --git a/contrib/go/_std_1.20/src/runtime/panic.go b/contrib/go/_std_1.20/src/runtime/panic.go
deleted file mode 100644
index 6a6437de24..0000000000
--- a/contrib/go/_std_1.20/src/runtime/panic.go
+++ /dev/null
@@ -1,1376 +0,0 @@
-// Copyright 2014 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 runtime
-
-import (
- "internal/goarch"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// throwType indicates the current type of ongoing throw, which affects the
-// amount of detail printed to stderr. Higher values include more detail.
-type throwType uint32
-
-const (
- // throwTypeNone means that we are not throwing.
- throwTypeNone throwType = iota
-
- // throwTypeUser is a throw due to a problem with the application.
- //
- // These throws do not include runtime frames, system goroutines, or
- // frame metadata.
- throwTypeUser
-
- // throwTypeRuntime is a throw due to a problem with Go itself.
- //
- // These throws include as much information as possible to aid in
- // debugging the runtime, including runtime frames, system goroutines,
- // and frame metadata.
- throwTypeRuntime
-)
-
-// We have two different ways of doing defers. The older way involves creating a
-// defer record at the time that a defer statement is executing and adding it to a
-// defer chain. This chain is inspected by the deferreturn call at all function
-// exits in order to run the appropriate defer calls. A cheaper way (which we call
-// open-coded defers) is used for functions in which no defer statements occur in
-// loops. In that case, we simply store the defer function/arg information into
-// specific stack slots at the point of each defer statement, as well as setting a
-// bit in a bitmask. At each function exit, we add inline code to directly make
-// the appropriate defer calls based on the bitmask and fn/arg information stored
-// on the stack. During panic/Goexit processing, the appropriate defer calls are
-// made using extra funcdata info that indicates the exact stack slots that
-// contain the bitmask and defer fn/args.
-
-// Check to make sure we can really generate a panic. If the panic
-// was generated from the runtime, or from inside malloc, then convert
-// to a throw of msg.
-// pc should be the program counter of the compiler-generated code that
-// triggered this panic.
-func panicCheck1(pc uintptr, msg string) {
- if goarch.IsWasm == 0 && hasPrefix(funcname(findfunc(pc)), "runtime.") {
- // Note: wasm can't tail call, so we can't get the original caller's pc.
- throw(msg)
- }
- // TODO: is this redundant? How could we be in malloc
- // but not in the runtime? runtime/internal/*, maybe?
- gp := getg()
- if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
- throw(msg)
- }
-}
-
-// Same as above, but calling from the runtime is allowed.
-//
-// Using this function is necessary for any panic that may be
-// generated by runtime.sigpanic, since those are always called by the
-// runtime.
-func panicCheck2(err string) {
- // panic allocates, so to avoid recursive malloc, turn panics
- // during malloc into throws.
- gp := getg()
- if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
- throw(err)
- }
-}
-
-// Many of the following panic entry-points turn into throws when they
-// happen in various runtime contexts. These should never happen in
-// the runtime, and if they do, they indicate a serious issue and
-// should not be caught by user code.
-//
-// The panic{Index,Slice,divide,shift} functions are called by
-// code generated by the compiler for out of bounds index expressions,
-// out of bounds slice expressions, division by zero, and shift by negative.
-// The panicdivide (again), panicoverflow, panicfloat, and panicmem
-// functions are called by the signal handler when a signal occurs
-// indicating the respective problem.
-//
-// Since panic{Index,Slice,shift} are never called directly, and
-// since the runtime package should never have an out of bounds slice
-// or array reference or negative shift, if we see those functions called from the
-// runtime package we turn the panic into a throw. That will dump the
-// entire runtime stack for easier debugging.
-//
-// The entry points called by the signal handler will be called from
-// runtime.sigpanic, so we can't disallow calls from the runtime to
-// these (they always look like they're called from the runtime).
-// Hence, for these, we just check for clearly bad runtime conditions.
-//
-// The panic{Index,Slice} functions are implemented in assembly and tail call
-// to the goPanic{Index,Slice} functions below. This is done so we can use
-// a space-minimal register calling convention.
-
-// failures in the comparisons for s[x], 0 <= x < y (y == len(s))
-//
-//go:yeswritebarrierrec
-func goPanicIndex(x int, y int) {
- panicCheck1(getcallerpc(), "index out of range")
- panic(boundsError{x: int64(x), signed: true, y: y, code: boundsIndex})
-}
-
-//go:yeswritebarrierrec
-func goPanicIndexU(x uint, y int) {
- panicCheck1(getcallerpc(), "index out of range")
- panic(boundsError{x: int64(x), signed: false, y: y, code: boundsIndex})
-}
-
-// failures in the comparisons for s[:x], 0 <= x <= y (y == len(s) or cap(s))
-//
-//go:yeswritebarrierrec
-func goPanicSliceAlen(x int, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceAlen})
-}
-
-//go:yeswritebarrierrec
-func goPanicSliceAlenU(x uint, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceAlen})
-}
-
-//go:yeswritebarrierrec
-func goPanicSliceAcap(x int, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceAcap})
-}
-
-//go:yeswritebarrierrec
-func goPanicSliceAcapU(x uint, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceAcap})
-}
-
-// failures in the comparisons for s[x:y], 0 <= x <= y
-//
-//go:yeswritebarrierrec
-func goPanicSliceB(x int, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceB})
-}
-
-//go:yeswritebarrierrec
-func goPanicSliceBU(x uint, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceB})
-}
-
-// failures in the comparisons for s[::x], 0 <= x <= y (y == len(s) or cap(s))
-func goPanicSlice3Alen(x int, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3Alen})
-}
-func goPanicSlice3AlenU(x uint, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3Alen})
-}
-func goPanicSlice3Acap(x int, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3Acap})
-}
-func goPanicSlice3AcapU(x uint, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3Acap})
-}
-
-// failures in the comparisons for s[:x:y], 0 <= x <= y
-func goPanicSlice3B(x int, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3B})
-}
-func goPanicSlice3BU(x uint, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3B})
-}
-
-// failures in the comparisons for s[x:y:], 0 <= x <= y
-func goPanicSlice3C(x int, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3C})
-}
-func goPanicSlice3CU(x uint, y int) {
- panicCheck1(getcallerpc(), "slice bounds out of range")
- panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3C})
-}
-
-// failures in the conversion ([x]T)(s) or (*[x]T)(s), 0 <= x <= y, y == len(s)
-func goPanicSliceConvert(x int, y int) {
- panicCheck1(getcallerpc(), "slice length too short to convert to array or pointer to array")
- panic(boundsError{x: int64(x), signed: true, y: y, code: boundsConvert})
-}
-
-// Implemented in assembly, as they take arguments in registers.
-// Declared here to mark them as ABIInternal.
-func panicIndex(x int, y int)
-func panicIndexU(x uint, y int)
-func panicSliceAlen(x int, y int)
-func panicSliceAlenU(x uint, y int)
-func panicSliceAcap(x int, y int)
-func panicSliceAcapU(x uint, y int)
-func panicSliceB(x int, y int)
-func panicSliceBU(x uint, y int)
-func panicSlice3Alen(x int, y int)
-func panicSlice3AlenU(x uint, y int)
-func panicSlice3Acap(x int, y int)
-func panicSlice3AcapU(x uint, y int)
-func panicSlice3B(x int, y int)
-func panicSlice3BU(x uint, y int)
-func panicSlice3C(x int, y int)
-func panicSlice3CU(x uint, y int)
-func panicSliceConvert(x int, y int)
-
-var shiftError = error(errorString("negative shift amount"))
-
-//go:yeswritebarrierrec
-func panicshift() {
- panicCheck1(getcallerpc(), "negative shift amount")
- panic(shiftError)
-}
-
-var divideError = error(errorString("integer divide by zero"))
-
-//go:yeswritebarrierrec
-func panicdivide() {
- panicCheck2("integer divide by zero")
- panic(divideError)
-}
-
-var overflowError = error(errorString("integer overflow"))
-
-func panicoverflow() {
- panicCheck2("integer overflow")
- panic(overflowError)
-}
-
-var floatError = error(errorString("floating point error"))
-
-func panicfloat() {
- panicCheck2("floating point error")
- panic(floatError)
-}
-
-var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
-
-func panicmem() {
- panicCheck2("invalid memory address or nil pointer dereference")
- panic(memoryError)
-}
-
-func panicmemAddr(addr uintptr) {
- panicCheck2("invalid memory address or nil pointer dereference")
- panic(errorAddressString{msg: "invalid memory address or nil pointer dereference", addr: addr})
-}
-
-// Create a new deferred function fn, which has no arguments and results.
-// The compiler turns a defer statement into a call to this.
-func deferproc(fn func()) {
- gp := getg()
- if gp.m.curg != gp {
- // go code on the system stack can't defer
- throw("defer on system stack")
- }
-
- d := newdefer()
- if d._panic != nil {
- throw("deferproc: d.panic != nil after newdefer")
- }
- d.link = gp._defer
- gp._defer = d
- d.fn = fn
- d.pc = getcallerpc()
- // We must not be preempted between calling getcallersp and
- // storing it to d.sp because getcallersp's result is a
- // uintptr stack pointer.
- d.sp = getcallersp()
-
- // deferproc returns 0 normally.
- // a deferred func that stops a panic
- // makes the deferproc return 1.
- // the code the compiler generates always
- // checks the return value and jumps to the
- // end of the function if deferproc returns != 0.
- return0()
- // No code can go here - the C return register has
- // been set and must not be clobbered.
-}
-
-// deferprocStack queues a new deferred function with a defer record on the stack.
-// The defer record must have its fn field initialized.
-// All other fields can contain junk.
-// Nosplit because of the uninitialized pointer fields on the stack.
-//
-//go:nosplit
-func deferprocStack(d *_defer) {
- gp := getg()
- if gp.m.curg != gp {
- // go code on the system stack can't defer
- throw("defer on system stack")
- }
- // fn is already set.
- // The other fields are junk on entry to deferprocStack and
- // are initialized here.
- d.started = false
- d.heap = false
- d.openDefer = false
- d.sp = getcallersp()
- d.pc = getcallerpc()
- d.framepc = 0
- d.varp = 0
- // The lines below implement:
- // d.panic = nil
- // d.fd = nil
- // d.link = gp._defer
- // gp._defer = d
- // But without write barriers. The first three are writes to
- // the stack so they don't need a write barrier, and furthermore
- // are to uninitialized memory, so they must not use a write barrier.
- // The fourth write does not require a write barrier because we
- // explicitly mark all the defer structures, so we don't need to
- // keep track of pointers to them with a write barrier.
- *(*uintptr)(unsafe.Pointer(&d._panic)) = 0
- *(*uintptr)(unsafe.Pointer(&d.fd)) = 0
- *(*uintptr)(unsafe.Pointer(&d.link)) = uintptr(unsafe.Pointer(gp._defer))
- *(*uintptr)(unsafe.Pointer(&gp._defer)) = uintptr(unsafe.Pointer(d))
-
- return0()
- // No code can go here - the C return register has
- // been set and must not be clobbered.
-}
-
-// Each P holds a pool for defers.
-
-// Allocate a Defer, usually using per-P pool.
-// Each defer must be released with freedefer. The defer is not
-// added to any defer chain yet.
-func newdefer() *_defer {
- var d *_defer
- mp := acquirem()
- pp := mp.p.ptr()
- if len(pp.deferpool) == 0 && sched.deferpool != nil {
- lock(&sched.deferlock)
- for len(pp.deferpool) < cap(pp.deferpool)/2 && sched.deferpool != nil {
- d := sched.deferpool
- sched.deferpool = d.link
- d.link = nil
- pp.deferpool = append(pp.deferpool, d)
- }
- unlock(&sched.deferlock)
- }
- if n := len(pp.deferpool); n > 0 {
- d = pp.deferpool[n-1]
- pp.deferpool[n-1] = nil
- pp.deferpool = pp.deferpool[:n-1]
- }
- releasem(mp)
- mp, pp = nil, nil
-
- if d == nil {
- // Allocate new defer.
- d = new(_defer)
- }
- d.heap = true
- return d
-}
-
-// Free the given defer.
-// The defer cannot be used after this call.
-//
-// This is nosplit because the incoming defer is in a perilous state.
-// It's not on any defer list, so stack copying won't adjust stack
-// pointers in it (namely, d.link). Hence, if we were to copy the
-// stack, d could then contain a stale pointer.
-//
-//go:nosplit
-func freedefer(d *_defer) {
- d.link = nil
- // After this point we can copy the stack.
-
- if d._panic != nil {
- freedeferpanic()
- }
- if d.fn != nil {
- freedeferfn()
- }
- if !d.heap {
- return
- }
-
- mp := acquirem()
- pp := mp.p.ptr()
- if len(pp.deferpool) == cap(pp.deferpool) {
- // Transfer half of local cache to the central cache.
- var first, last *_defer
- for len(pp.deferpool) > cap(pp.deferpool)/2 {
- n := len(pp.deferpool)
- d := pp.deferpool[n-1]
- pp.deferpool[n-1] = nil
- pp.deferpool = pp.deferpool[:n-1]
- if first == nil {
- first = d
- } else {
- last.link = d
- }
- last = d
- }
- lock(&sched.deferlock)
- last.link = sched.deferpool
- sched.deferpool = first
- unlock(&sched.deferlock)
- }
-
- *d = _defer{}
-
- pp.deferpool = append(pp.deferpool, d)
-
- releasem(mp)
- mp, pp = nil, nil
-}
-
-// Separate function so that it can split stack.
-// Windows otherwise runs out of stack space.
-func freedeferpanic() {
- // _panic must be cleared before d is unlinked from gp.
- throw("freedefer with d._panic != nil")
-}
-
-func freedeferfn() {
- // fn must be cleared before d is unlinked from gp.
- throw("freedefer with d.fn != nil")
-}
-
-// deferreturn runs deferred functions for the caller's frame.
-// The compiler inserts a call to this at the end of any
-// function which calls defer.
-func deferreturn() {
- gp := getg()
- for {
- d := gp._defer
- if d == nil {
- return
- }
- sp := getcallersp()
- if d.sp != sp {
- return
- }
- if d.openDefer {
- done := runOpenDeferFrame(d)
- if !done {
- throw("unfinished open-coded defers in deferreturn")
- }
- gp._defer = d.link
- freedefer(d)
- // If this frame uses open defers, then this
- // must be the only defer record for the
- // frame, so we can just return.
- return
- }
-
- fn := d.fn
- d.fn = nil
- gp._defer = d.link
- freedefer(d)
- fn()
- }
-}
-
-// Goexit terminates the goroutine that calls it. No other goroutine is affected.
-// Goexit runs all deferred calls before terminating the goroutine. Because Goexit
-// is not a panic, any recover calls in those deferred functions will return nil.
-//
-// Calling Goexit from the main goroutine terminates that goroutine
-// without func main returning. Since func main has not returned,
-// the program continues execution of other goroutines.
-// If all other goroutines exit, the program crashes.
-func Goexit() {
- // Run all deferred functions for the current goroutine.
- // This code is similar to gopanic, see that implementation
- // for detailed comments.
- gp := getg()
-
- // Create a panic object for Goexit, so we can recognize when it might be
- // bypassed by a recover().
- var p _panic
- p.goexit = true
- p.link = gp._panic
- gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
-
- addOneOpenDeferFrame(gp, getcallerpc(), unsafe.Pointer(getcallersp()))
- for {
- d := gp._defer
- if d == nil {
- break
- }
- if d.started {
- if d._panic != nil {
- d._panic.aborted = true
- d._panic = nil
- }
- if !d.openDefer {
- d.fn = nil
- gp._defer = d.link
- freedefer(d)
- continue
- }
- }
- d.started = true
- d._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
- if d.openDefer {
- done := runOpenDeferFrame(d)
- if !done {
- // We should always run all defers in the frame,
- // since there is no panic associated with this
- // defer that can be recovered.
- throw("unfinished open-coded defers in Goexit")
- }
- if p.aborted {
- // Since our current defer caused a panic and may
- // have been already freed, just restart scanning
- // for open-coded defers from this frame again.
- addOneOpenDeferFrame(gp, getcallerpc(), unsafe.Pointer(getcallersp()))
- } else {
- addOneOpenDeferFrame(gp, 0, nil)
- }
- } else {
- // Save the pc/sp in deferCallSave(), so we can "recover" back to this
- // loop if necessary.
- deferCallSave(&p, d.fn)
- }
- if p.aborted {
- // We had a recursive panic in the defer d we started, and
- // then did a recover in a defer that was further down the
- // defer chain than d. In the case of an outstanding Goexit,
- // we force the recover to return back to this loop. d will
- // have already been freed if completed, so just continue
- // immediately to the next defer on the chain.
- p.aborted = false
- continue
- }
- if gp._defer != d {
- throw("bad defer entry in Goexit")
- }
- d._panic = nil
- d.fn = nil
- gp._defer = d.link
- freedefer(d)
- // Note: we ignore recovers here because Goexit isn't a panic
- }
- goexit1()
-}
-
-// Call all Error and String methods before freezing the world.
-// Used when crashing with panicking.
-func preprintpanics(p *_panic) {
- defer func() {
- text := "panic while printing panic value"
- switch r := recover().(type) {
- case nil:
- // nothing to do
- case string:
- throw(text + ": " + r)
- default:
- throw(text + ": type " + efaceOf(&r)._type.string())
- }
- }()
- for p != nil {
- switch v := p.arg.(type) {
- case error:
- p.arg = v.Error()
- case stringer:
- p.arg = v.String()
- }
- p = p.link
- }
-}
-
-// Print all currently active panics. Used when crashing.
-// Should only be called after preprintpanics.
-func printpanics(p *_panic) {
- if p.link != nil {
- printpanics(p.link)
- if !p.link.goexit {
- print("\t")
- }
- }
- if p.goexit {
- return
- }
- print("panic: ")
- printany(p.arg)
- if p.recovered {
- print(" [recovered]")
- }
- print("\n")
-}
-
-// addOneOpenDeferFrame scans the stack (in gentraceback order, from inner frames to
-// outer frames) for the first frame (if any) with open-coded defers. If it finds
-// one, it adds a single entry to the defer chain for that frame. The entry added
-// represents all the defers in the associated open defer frame, and is sorted in
-// order with respect to any non-open-coded defers.
-//
-// addOneOpenDeferFrame stops (possibly without adding a new entry) if it encounters
-// an in-progress open defer entry. An in-progress open defer entry means there has
-// been a new panic because of a defer in the associated frame. addOneOpenDeferFrame
-// does not add an open defer entry past a started entry, because that started entry
-// still needs to finished, and addOneOpenDeferFrame will be called when that started
-// entry is completed. The defer removal loop in gopanic() similarly stops at an
-// in-progress defer entry. Together, addOneOpenDeferFrame and the defer removal loop
-// ensure the invariant that there is no open defer entry further up the stack than
-// an in-progress defer, and also that the defer removal loop is guaranteed to remove
-// all not-in-progress open defer entries from the defer chain.
-//
-// If sp is non-nil, addOneOpenDeferFrame starts the stack scan from the frame
-// specified by sp. If sp is nil, it uses the sp from the current defer record (which
-// has just been finished). Hence, it continues the stack scan from the frame of the
-// defer that just finished. It skips any frame that already has a (not-in-progress)
-// open-coded _defer record in the defer chain.
-//
-// Note: All entries of the defer chain (including this new open-coded entry) have
-// their pointers (including sp) adjusted properly if the stack moves while
-// running deferred functions. Also, it is safe to pass in the sp arg (which is
-// the direct result of calling getcallersp()), because all pointer variables
-// (including arguments) are adjusted as needed during stack copies.
-func addOneOpenDeferFrame(gp *g, pc uintptr, sp unsafe.Pointer) {
- var prevDefer *_defer
- if sp == nil {
- prevDefer = gp._defer
- pc = prevDefer.framepc
- sp = unsafe.Pointer(prevDefer.sp)
- }
- systemstack(func() {
- gentraceback(pc, uintptr(sp), 0, gp, 0, nil, 0x7fffffff,
- func(frame *stkframe, unused unsafe.Pointer) bool {
- if prevDefer != nil && prevDefer.sp == frame.sp {
- // Skip the frame for the previous defer that
- // we just finished (and was used to set
- // where we restarted the stack scan)
- return true
- }
- f := frame.fn
- fd := funcdata(f, _FUNCDATA_OpenCodedDeferInfo)
- if fd == nil {
- return true
- }
- // Insert the open defer record in the
- // chain, in order sorted by sp.
- d := gp._defer
- var prev *_defer
- for d != nil {
- dsp := d.sp
- if frame.sp < dsp {
- break
- }
- if frame.sp == dsp {
- if !d.openDefer {
- throw("duplicated defer entry")
- }
- // Don't add any record past an
- // in-progress defer entry. We don't
- // need it, and more importantly, we
- // want to keep the invariant that
- // there is no open defer entry
- // passed an in-progress entry (see
- // header comment).
- if d.started {
- return false
- }
- return true
- }
- prev = d
- d = d.link
- }
- if frame.fn.deferreturn == 0 {
- throw("missing deferreturn")
- }
-
- d1 := newdefer()
- d1.openDefer = true
- d1._panic = nil
- // These are the pc/sp to set after we've
- // run a defer in this frame that did a
- // recover. We return to a special
- // deferreturn that runs any remaining
- // defers and then returns from the
- // function.
- d1.pc = frame.fn.entry() + uintptr(frame.fn.deferreturn)
- d1.varp = frame.varp
- d1.fd = fd
- // Save the SP/PC associated with current frame,
- // so we can continue stack trace later if needed.
- d1.framepc = frame.pc
- d1.sp = frame.sp
- d1.link = d
- if prev == nil {
- gp._defer = d1
- } else {
- prev.link = d1
- }
- // Stop stack scanning after adding one open defer record
- return false
- },
- nil, 0)
- })
-}
-
-// readvarintUnsafe reads the uint32 in varint format starting at fd, and returns the
-// uint32 and a pointer to the byte following the varint.
-//
-// There is a similar function runtime.readvarint, which takes a slice of bytes,
-// rather than an unsafe pointer. These functions are duplicated, because one of
-// the two use cases for the functions would get slower if the functions were
-// combined.
-func readvarintUnsafe(fd unsafe.Pointer) (uint32, unsafe.Pointer) {
- var r uint32
- var shift int
- for {
- b := *(*uint8)((unsafe.Pointer(fd)))
- fd = add(fd, unsafe.Sizeof(b))
- if b < 128 {
- return r + uint32(b)<<shift, fd
- }
- r += ((uint32(b) &^ 128) << shift)
- shift += 7
- if shift > 28 {
- panic("Bad varint")
- }
- }
-}
-
-// runOpenDeferFrame runs the active open-coded defers in the frame specified by
-// d. It normally processes all active defers in the frame, but stops immediately
-// if a defer does a successful recover. It returns true if there are no
-// remaining defers to run in the frame.
-func runOpenDeferFrame(d *_defer) bool {
- done := true
- fd := d.fd
-
- deferBitsOffset, fd := readvarintUnsafe(fd)
- nDefers, fd := readvarintUnsafe(fd)
- deferBits := *(*uint8)(unsafe.Pointer(d.varp - uintptr(deferBitsOffset)))
-
- for i := int(nDefers) - 1; i >= 0; i-- {
- // read the funcdata info for this defer
- var closureOffset uint32
- closureOffset, fd = readvarintUnsafe(fd)
- if deferBits&(1<<i) == 0 {
- continue
- }
- closure := *(*func())(unsafe.Pointer(d.varp - uintptr(closureOffset)))
- d.fn = closure
- deferBits = deferBits &^ (1 << i)
- *(*uint8)(unsafe.Pointer(d.varp - uintptr(deferBitsOffset))) = deferBits
- p := d._panic
- // Call the defer. Note that this can change d.varp if
- // the stack moves.
- deferCallSave(p, d.fn)
- if p != nil && p.aborted {
- break
- }
- d.fn = nil
- if d._panic != nil && d._panic.recovered {
- done = deferBits == 0
- break
- }
- }
-
- return done
-}
-
-// deferCallSave calls fn() after saving the caller's pc and sp in the
-// panic record. This allows the runtime to return to the Goexit defer
-// processing loop, in the unusual case where the Goexit may be
-// bypassed by a successful recover.
-//
-// This is marked as a wrapper by the compiler so it doesn't appear in
-// tracebacks.
-func deferCallSave(p *_panic, fn func()) {
- if p != nil {
- p.argp = unsafe.Pointer(getargp())
- p.pc = getcallerpc()
- p.sp = unsafe.Pointer(getcallersp())
- }
- fn()
- if p != nil {
- p.pc = 0
- p.sp = unsafe.Pointer(nil)
- }
-}
-
-// The implementation of the predeclared function panic.
-func gopanic(e any) {
- gp := getg()
- if gp.m.curg != gp {
- print("panic: ")
- printany(e)
- print("\n")
- throw("panic on system stack")
- }
-
- if gp.m.mallocing != 0 {
- print("panic: ")
- printany(e)
- print("\n")
- throw("panic during malloc")
- }
- if gp.m.preemptoff != "" {
- print("panic: ")
- printany(e)
- print("\n")
- print("preempt off reason: ")
- print(gp.m.preemptoff)
- print("\n")
- throw("panic during preemptoff")
- }
- if gp.m.locks != 0 {
- print("panic: ")
- printany(e)
- print("\n")
- throw("panic holding locks")
- }
-
- var p _panic
- p.arg = e
- p.link = gp._panic
- gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
-
- runningPanicDefers.Add(1)
-
- // By calculating getcallerpc/getcallersp here, we avoid scanning the
- // gopanic frame (stack scanning is slow...)
- addOneOpenDeferFrame(gp, getcallerpc(), unsafe.Pointer(getcallersp()))
-
- for {
- d := gp._defer
- if d == nil {
- break
- }
-
- // If defer was started by earlier panic or Goexit (and, since we're back here, that triggered a new panic),
- // take defer off list. An earlier panic will not continue running, but we will make sure below that an
- // earlier Goexit does continue running.
- if d.started {
- if d._panic != nil {
- d._panic.aborted = true
- }
- d._panic = nil
- if !d.openDefer {
- // For open-coded defers, we need to process the
- // defer again, in case there are any other defers
- // to call in the frame (not including the defer
- // call that caused the panic).
- d.fn = nil
- gp._defer = d.link
- freedefer(d)
- continue
- }
- }
-
- // Mark defer as started, but keep on list, so that traceback
- // can find and update the defer's argument frame if stack growth
- // or a garbage collection happens before executing d.fn.
- d.started = true
-
- // Record the panic that is running the defer.
- // If there is a new panic during the deferred call, that panic
- // will find d in the list and will mark d._panic (this panic) aborted.
- d._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
-
- done := true
- if d.openDefer {
- done = runOpenDeferFrame(d)
- if done && !d._panic.recovered {
- addOneOpenDeferFrame(gp, 0, nil)
- }
- } else {
- p.argp = unsafe.Pointer(getargp())
- d.fn()
- }
- p.argp = nil
-
- // Deferred function did not panic. Remove d.
- if gp._defer != d {
- throw("bad defer entry in panic")
- }
- d._panic = nil
-
- // trigger shrinkage to test stack copy. See stack_test.go:TestStackPanic
- //GC()
-
- pc := d.pc
- sp := unsafe.Pointer(d.sp) // must be pointer so it gets adjusted during stack copy
- if done {
- d.fn = nil
- gp._defer = d.link
- freedefer(d)
- }
- if p.recovered {
- gp._panic = p.link
- if gp._panic != nil && gp._panic.goexit && gp._panic.aborted {
- // A normal recover would bypass/abort the Goexit. Instead,
- // we return to the processing loop of the Goexit.
- gp.sigcode0 = uintptr(gp._panic.sp)
- gp.sigcode1 = uintptr(gp._panic.pc)
- mcall(recovery)
- throw("bypassed recovery failed") // mcall should not return
- }
- runningPanicDefers.Add(-1)
-
- // After a recover, remove any remaining non-started,
- // open-coded defer entries, since the corresponding defers
- // will be executed normally (inline). Any such entry will
- // become stale once we run the corresponding defers inline
- // and exit the associated stack frame. We only remove up to
- // the first started (in-progress) open defer entry, not
- // including the current frame, since any higher entries will
- // be from a higher panic in progress, and will still be
- // needed.
- d := gp._defer
- var prev *_defer
- if !done {
- // Skip our current frame, if not done. It is
- // needed to complete any remaining defers in
- // deferreturn()
- prev = d
- d = d.link
- }
- for d != nil {
- if d.started {
- // This defer is started but we
- // are in the middle of a
- // defer-panic-recover inside of
- // it, so don't remove it or any
- // further defer entries
- break
- }
- if d.openDefer {
- if prev == nil {
- gp._defer = d.link
- } else {
- prev.link = d.link
- }
- newd := d.link
- freedefer(d)
- d = newd
- } else {
- prev = d
- d = d.link
- }
- }
-
- gp._panic = p.link
- // Aborted panics are marked but remain on the g.panic list.
- // Remove them from the list.
- for gp._panic != nil && gp._panic.aborted {
- gp._panic = gp._panic.link
- }
- if gp._panic == nil { // must be done with signal
- gp.sig = 0
- }
- // Pass information about recovering frame to recovery.
- gp.sigcode0 = uintptr(sp)
- gp.sigcode1 = pc
- mcall(recovery)
- throw("recovery failed") // mcall should not return
- }
- }
-
- // ran out of deferred calls - old-school panic now
- // Because it is unsafe to call arbitrary user code after freezing
- // the world, we call preprintpanics to invoke all necessary Error
- // and String methods to prepare the panic strings before startpanic.
- preprintpanics(gp._panic)
-
- fatalpanic(gp._panic) // should not return
- *(*int)(nil) = 0 // not reached
-}
-
-// getargp returns the location where the caller
-// writes outgoing function call arguments.
-//
-//go:nosplit
-//go:noinline
-func getargp() uintptr {
- return getcallersp() + sys.MinFrameSize
-}
-
-// The implementation of the predeclared function recover.
-// Cannot split the stack because it needs to reliably
-// find the stack segment of its caller.
-//
-// TODO(rsc): Once we commit to CopyStackAlways,
-// this doesn't need to be nosplit.
-//
-//go:nosplit
-func gorecover(argp uintptr) any {
- // Must be in a function running as part of a deferred call during the panic.
- // Must be called from the topmost function of the call
- // (the function used in the defer statement).
- // p.argp is the argument pointer of that topmost deferred function call.
- // Compare against argp reported by caller.
- // If they match, the caller is the one who can recover.
- gp := getg()
- p := gp._panic
- if p != nil && !p.goexit && !p.recovered && argp == uintptr(p.argp) {
- p.recovered = true
- return p.arg
- }
- return nil
-}
-
-//go:linkname sync_throw sync.throw
-func sync_throw(s string) {
- throw(s)
-}
-
-//go:linkname sync_fatal sync.fatal
-func sync_fatal(s string) {
- fatal(s)
-}
-
-// throw triggers a fatal error that dumps a stack trace and exits.
-//
-// throw should be used for runtime-internal fatal errors where Go itself,
-// rather than user code, may be at fault for the failure.
-//
-//go:nosplit
-func throw(s string) {
- // Everything throw does should be recursively nosplit so it
- // can be called even when it's unsafe to grow the stack.
- systemstack(func() {
- print("fatal error: ", s, "\n")
- })
-
- fatalthrow(throwTypeRuntime)
-}
-
-// fatal triggers a fatal error that dumps a stack trace and exits.
-//
-// fatal is equivalent to throw, but is used when user code is expected to be
-// at fault for the failure, such as racing map writes.
-//
-// fatal does not include runtime frames, system goroutines, or frame metadata
-// (fp, sp, pc) in the stack trace unless GOTRACEBACK=system or higher.
-//
-//go:nosplit
-func fatal(s string) {
- // Everything fatal does should be recursively nosplit so it
- // can be called even when it's unsafe to grow the stack.
- systemstack(func() {
- print("fatal error: ", s, "\n")
- })
-
- fatalthrow(throwTypeUser)
-}
-
-// runningPanicDefers is non-zero while running deferred functions for panic.
-// This is used to try hard to get a panic stack trace out when exiting.
-var runningPanicDefers atomic.Uint32
-
-// panicking is non-zero when crashing the program for an unrecovered panic.
-var panicking atomic.Uint32
-
-// paniclk is held while printing the panic information and stack trace,
-// so that two concurrent panics don't overlap their output.
-var paniclk mutex
-
-// Unwind the stack after a deferred function calls recover
-// after a panic. Then arrange to continue running as though
-// the caller of the deferred function returned normally.
-func recovery(gp *g) {
- // Info about defer passed in G struct.
- sp := gp.sigcode0
- pc := gp.sigcode1
-
- // d's arguments need to be in the stack.
- if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) {
- print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
- throw("bad recovery")
- }
-
- // Make the deferproc for this d return again,
- // this time returning 1. The calling function will
- // jump to the standard return epilogue.
- gp.sched.sp = sp
- gp.sched.pc = pc
- gp.sched.lr = 0
- gp.sched.ret = 1
- gogo(&gp.sched)
-}
-
-// fatalthrow implements an unrecoverable runtime throw. It freezes the
-// system, prints stack traces starting from its caller, and terminates the
-// process.
-//
-//go:nosplit
-func fatalthrow(t throwType) {
- pc := getcallerpc()
- sp := getcallersp()
- gp := getg()
-
- if gp.m.throwing == throwTypeNone {
- gp.m.throwing = t
- }
-
- // Switch to the system stack to avoid any stack growth, which may make
- // things worse if the runtime is in a bad state.
- systemstack(func() {
- if isSecureMode() {
- exit(2)
- }
-
- startpanic_m()
-
- if dopanic_m(gp, pc, sp) {
- // crash uses a decent amount of nosplit stack and we're already
- // low on stack in throw, so crash on the system stack (unlike
- // fatalpanic).
- crash()
- }
-
- exit(2)
- })
-
- *(*int)(nil) = 0 // not reached
-}
-
-// fatalpanic implements an unrecoverable panic. It is like fatalthrow, except
-// that if msgs != nil, fatalpanic also prints panic messages and decrements
-// runningPanicDefers once main is blocked from exiting.
-//
-//go:nosplit
-func fatalpanic(msgs *_panic) {
- pc := getcallerpc()
- sp := getcallersp()
- gp := getg()
- var docrash bool
- // Switch to the system stack to avoid any stack growth, which
- // may make things worse if the runtime is in a bad state.
- systemstack(func() {
- if startpanic_m() && msgs != nil {
- // There were panic messages and startpanic_m
- // says it's okay to try to print them.
-
- // startpanic_m set panicking, which will
- // block main from exiting, so now OK to
- // decrement runningPanicDefers.
- runningPanicDefers.Add(-1)
-
- printpanics(msgs)
- }
-
- docrash = dopanic_m(gp, pc, sp)
- })
-
- if docrash {
- // By crashing outside the above systemstack call, debuggers
- // will not be confused when generating a backtrace.
- // Function crash is marked nosplit to avoid stack growth.
- crash()
- }
-
- systemstack(func() {
- exit(2)
- })
-
- *(*int)(nil) = 0 // not reached
-}
-
-// startpanic_m prepares for an unrecoverable panic.
-//
-// It returns true if panic messages should be printed, or false if
-// the runtime is in bad shape and should just print stacks.
-//
-// It must not have write barriers even though the write barrier
-// explicitly ignores writes once dying > 0. Write barriers still
-// assume that g.m.p != nil, and this function may not have P
-// in some contexts (e.g. a panic in a signal handler for a signal
-// sent to an M with no P).
-//
-//go:nowritebarrierrec
-func startpanic_m() bool {
- gp := getg()
- if mheap_.cachealloc.size == 0 { // very early
- print("runtime: panic before malloc heap initialized\n")
- }
- // Disallow malloc during an unrecoverable panic. A panic
- // could happen in a signal handler, or in a throw, or inside
- // malloc itself. We want to catch if an allocation ever does
- // happen (even if we're not in one of these situations).
- gp.m.mallocing++
-
- // If we're dying because of a bad lock count, set it to a
- // good lock count so we don't recursively panic below.
- if gp.m.locks < 0 {
- gp.m.locks = 1
- }
-
- switch gp.m.dying {
- case 0:
- // Setting dying >0 has the side-effect of disabling this G's writebuf.
- gp.m.dying = 1
- panicking.Add(1)
- lock(&paniclk)
- if debug.schedtrace > 0 || debug.scheddetail > 0 {
- schedtrace(true)
- }
- freezetheworld()
- return true
- case 1:
- // Something failed while panicking.
- // Just print a stack trace and exit.
- gp.m.dying = 2
- print("panic during panic\n")
- return false
- case 2:
- // This is a genuine bug in the runtime, we couldn't even
- // print the stack trace successfully.
- gp.m.dying = 3
- print("stack trace unavailable\n")
- exit(4)
- fallthrough
- default:
- // Can't even print! Just exit.
- exit(5)
- return false // Need to return something.
- }
-}
-
-var didothers bool
-var deadlock mutex
-
-// gp is the crashing g running on this M, but may be a user G, while getg() is
-// always g0.
-func dopanic_m(gp *g, pc, sp uintptr) bool {
- if gp.sig != 0 {
- signame := signame(gp.sig)
- if signame != "" {
- print("[signal ", signame)
- } else {
- print("[signal ", hex(gp.sig))
- }
- print(" code=", hex(gp.sigcode0), " addr=", hex(gp.sigcode1), " pc=", hex(gp.sigpc), "]\n")
- }
-
- level, all, docrash := gotraceback()
- if level > 0 {
- if gp != gp.m.curg {
- all = true
- }
- if gp != gp.m.g0 {
- print("\n")
- goroutineheader(gp)
- traceback(pc, sp, 0, gp)
- } else if level >= 2 || gp.m.throwing >= throwTypeRuntime {
- print("\nruntime stack:\n")
- traceback(pc, sp, 0, gp)
- }
- if !didothers && all {
- didothers = true
- tracebackothers(gp)
- }
- }
- unlock(&paniclk)
-
- if panicking.Add(-1) != 0 {
- // Some other m is panicking too.
- // Let it print what it needs to print.
- // Wait forever without chewing up cpu.
- // It will exit when it's done.
- lock(&deadlock)
- lock(&deadlock)
- }
-
- printDebugLog()
-
- return docrash
-}
-
-// canpanic returns false if a signal should throw instead of
-// panicking.
-//
-//go:nosplit
-func canpanic() bool {
- gp := getg()
- mp := acquirem()
-
- // Is it okay for gp to panic instead of crashing the program?
- // Yes, as long as it is running Go code, not runtime code,
- // and not stuck in a system call.
- if gp != mp.curg {
- releasem(mp)
- return false
- }
- // N.B. mp.locks != 1 instead of 0 to account for acquirem.
- if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 {
- releasem(mp)
- return false
- }
- status := readgstatus(gp)
- if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
- releasem(mp)
- return false
- }
- if GOOS == "windows" && mp.libcallsp != 0 {
- releasem(mp)
- return false
- }
- releasem(mp)
- return true
-}
-
-// shouldPushSigpanic reports whether pc should be used as sigpanic's
-// return PC (pushing a frame for the call). Otherwise, it should be
-// left alone so that LR is used as sigpanic's return PC, effectively
-// replacing the top-most frame with sigpanic. This is used by
-// preparePanic.
-func shouldPushSigpanic(gp *g, pc, lr uintptr) bool {
- if pc == 0 {
- // Probably a call to a nil func. The old LR is more
- // useful in the stack trace. Not pushing the frame
- // will make the trace look like a call to sigpanic
- // instead. (Otherwise the trace will end at sigpanic
- // and we won't get to see who faulted.)
- return false
- }
- // If we don't recognize the PC as code, but we do recognize
- // the link register as code, then this assumes the panic was
- // caused by a call to non-code. In this case, we want to
- // ignore this call to make unwinding show the context.
- //
- // If we running C code, we're not going to recognize pc as a
- // Go function, so just assume it's good. Otherwise, traceback
- // may try to read a stale LR that looks like a Go code
- // pointer and wander into the woods.
- if gp.m.incgo || findfunc(pc).valid() {
- // This wasn't a bad call, so use PC as sigpanic's
- // return PC.
- return true
- }
- if findfunc(lr).valid() {
- // This was a bad call, but the LR is good, so use the
- // LR as sigpanic's return PC.
- return false
- }
- // Neither the PC or LR is good. Hopefully pushing a frame
- // will work.
- return true
-}
-
-// isAbortPC reports whether pc is the program counter at which
-// runtime.abort raises a signal.
-//
-// It is nosplit because it's part of the isgoexception
-// implementation.
-//
-//go:nosplit
-func isAbortPC(pc uintptr) bool {
- f := findfunc(pc)
- if !f.valid() {
- return false
- }
- return f.funcID == funcID_abort
-}
diff --git a/contrib/go/_std_1.20/src/runtime/plugin.go b/contrib/go/_std_1.20/src/runtime/plugin.go
deleted file mode 100644
index a61dcc3b5d..0000000000
--- a/contrib/go/_std_1.20/src/runtime/plugin.go
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2016 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 runtime
-
-import "unsafe"
-
-//go:linkname plugin_lastmoduleinit plugin.lastmoduleinit
-func plugin_lastmoduleinit() (path string, syms map[string]any, errstr string) {
- var md *moduledata
- for pmd := firstmoduledata.next; pmd != nil; pmd = pmd.next {
- if pmd.bad {
- md = nil // we only want the last module
- continue
- }
- md = pmd
- }
- if md == nil {
- throw("runtime: no plugin module data")
- }
- if md.pluginpath == "" {
- throw("runtime: plugin has empty pluginpath")
- }
- if md.typemap != nil {
- return "", nil, "plugin already loaded"
- }
-
- for _, pmd := range activeModules() {
- if pmd.pluginpath == md.pluginpath {
- md.bad = true
- return "", nil, "plugin already loaded"
- }
-
- if inRange(pmd.text, pmd.etext, md.text, md.etext) ||
- inRange(pmd.bss, pmd.ebss, md.bss, md.ebss) ||
- inRange(pmd.data, pmd.edata, md.data, md.edata) ||
- inRange(pmd.types, pmd.etypes, md.types, md.etypes) {
- println("plugin: new module data overlaps with previous moduledata")
- println("\tpmd.text-etext=", hex(pmd.text), "-", hex(pmd.etext))
- println("\tpmd.bss-ebss=", hex(pmd.bss), "-", hex(pmd.ebss))
- println("\tpmd.data-edata=", hex(pmd.data), "-", hex(pmd.edata))
- println("\tpmd.types-etypes=", hex(pmd.types), "-", hex(pmd.etypes))
- println("\tmd.text-etext=", hex(md.text), "-", hex(md.etext))
- println("\tmd.bss-ebss=", hex(md.bss), "-", hex(md.ebss))
- println("\tmd.data-edata=", hex(md.data), "-", hex(md.edata))
- println("\tmd.types-etypes=", hex(md.types), "-", hex(md.etypes))
- throw("plugin: new module data overlaps with previous moduledata")
- }
- }
- for _, pkghash := range md.pkghashes {
- if pkghash.linktimehash != *pkghash.runtimehash {
- md.bad = true
- return "", nil, "plugin was built with a different version of package " + pkghash.modulename
- }
- }
-
- // Initialize the freshly loaded module.
- modulesinit()
- typelinksinit()
-
- pluginftabverify(md)
- moduledataverify1(md)
-
- lock(&itabLock)
- for _, i := range md.itablinks {
- itabAdd(i)
- }
- unlock(&itabLock)
-
- // Build a map of symbol names to symbols. Here in the runtime
- // we fill out the first word of the interface, the type. We
- // pass these zero value interfaces to the plugin package,
- // where the symbol value is filled in (usually via cgo).
- //
- // Because functions are handled specially in the plugin package,
- // function symbol names are prefixed here with '.' to avoid
- // a dependency on the reflect package.
- syms = make(map[string]any, len(md.ptab))
- for _, ptab := range md.ptab {
- symName := resolveNameOff(unsafe.Pointer(md.types), ptab.name)
- t := (*_type)(unsafe.Pointer(md.types)).typeOff(ptab.typ)
- var val any
- valp := (*[2]unsafe.Pointer)(unsafe.Pointer(&val))
- (*valp)[0] = unsafe.Pointer(t)
-
- name := symName.name()
- if t.kind&kindMask == kindFunc {
- name = "." + name
- }
- syms[name] = val
- }
- return md.pluginpath, syms, ""
-}
-
-func pluginftabverify(md *moduledata) {
- badtable := false
- for i := 0; i < len(md.ftab); i++ {
- entry := md.textAddr(md.ftab[i].entryoff)
- if md.minpc <= entry && entry <= md.maxpc {
- continue
- }
-
- f := funcInfo{(*_func)(unsafe.Pointer(&md.pclntable[md.ftab[i].funcoff])), md}
- name := funcname(f)
-
- // A common bug is f.entry has a relocation to a duplicate
- // function symbol, meaning if we search for its PC we get
- // a valid entry with a name that is useful for debugging.
- name2 := "none"
- entry2 := uintptr(0)
- f2 := findfunc(entry)
- if f2.valid() {
- name2 = funcname(f2)
- entry2 = f2.entry()
- }
- badtable = true
- println("ftab entry", hex(entry), "/", hex(entry2), ": ",
- name, "/", name2, "outside pc range:[", hex(md.minpc), ",", hex(md.maxpc), "], modulename=", md.modulename, ", pluginpath=", md.pluginpath)
- }
- if badtable {
- throw("runtime: plugin has bad symbol table")
- }
-}
-
-// inRange reports whether v0 or v1 are in the range [r0, r1].
-func inRange(r0, r1, v0, v1 uintptr) bool {
- return (v0 >= r0 && v0 <= r1) || (v1 >= r0 && v1 <= r1)
-}
-
-// A ptabEntry is generated by the compiler for each exported function
-// and global variable in the main package of a plugin. It is used to
-// initialize the plugin module's symbol map.
-type ptabEntry struct {
- name nameOff
- typ typeOff
-}
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/proto.go b/contrib/go/_std_1.20/src/runtime/pprof/proto.go
deleted file mode 100644
index b68f30d923..0000000000
--- a/contrib/go/_std_1.20/src/runtime/pprof/proto.go
+++ /dev/null
@@ -1,761 +0,0 @@
-// Copyright 2016 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 pprof
-
-import (
- "bytes"
- "compress/gzip"
- "fmt"
- "internal/abi"
- "io"
- "runtime"
- "strconv"
- "strings"
- "time"
- "unsafe"
-)
-
-// lostProfileEvent is the function to which lost profiling
-// events are attributed.
-// (The name shows up in the pprof graphs.)
-func lostProfileEvent() { lostProfileEvent() }
-
-// A profileBuilder writes a profile incrementally from a
-// stream of profile samples delivered by the runtime.
-type profileBuilder struct {
- start time.Time
- end time.Time
- havePeriod bool
- period int64
- m profMap
-
- // encoding state
- w io.Writer
- zw *gzip.Writer
- pb protobuf
- strings []string
- stringMap map[string]int
- locs map[uintptr]locInfo // list of locInfo starting with the given PC.
- funcs map[string]int // Package path-qualified function name to Function.ID
- mem []memMap
- deck pcDeck
-}
-
-type memMap struct {
- // initialized as reading mapping
- start uintptr // Address at which the binary (or DLL) is loaded into memory.
- end uintptr // The limit of the address range occupied by this mapping.
- offset uint64 // Offset in the binary that corresponds to the first mapped address.
- file string // The object this entry is loaded from.
- buildID string // A string that uniquely identifies a particular program version with high probability.
-
- funcs symbolizeFlag
- fake bool // map entry was faked; /proc/self/maps wasn't available
-}
-
-// symbolizeFlag keeps track of symbolization result.
-//
-// 0 : no symbol lookup was performed
-// 1<<0 (lookupTried) : symbol lookup was performed
-// 1<<1 (lookupFailed): symbol lookup was performed but failed
-type symbolizeFlag uint8
-
-const (
- lookupTried symbolizeFlag = 1 << iota
- lookupFailed symbolizeFlag = 1 << iota
-)
-
-const (
- // message Profile
- tagProfile_SampleType = 1 // repeated ValueType
- tagProfile_Sample = 2 // repeated Sample
- tagProfile_Mapping = 3 // repeated Mapping
- tagProfile_Location = 4 // repeated Location
- tagProfile_Function = 5 // repeated Function
- tagProfile_StringTable = 6 // repeated string
- tagProfile_DropFrames = 7 // int64 (string table index)
- tagProfile_KeepFrames = 8 // int64 (string table index)
- tagProfile_TimeNanos = 9 // int64
- tagProfile_DurationNanos = 10 // int64
- tagProfile_PeriodType = 11 // ValueType (really optional string???)
- tagProfile_Period = 12 // int64
- tagProfile_Comment = 13 // repeated int64
- tagProfile_DefaultSampleType = 14 // int64
-
- // message ValueType
- tagValueType_Type = 1 // int64 (string table index)
- tagValueType_Unit = 2 // int64 (string table index)
-
- // message Sample
- tagSample_Location = 1 // repeated uint64
- tagSample_Value = 2 // repeated int64
- tagSample_Label = 3 // repeated Label
-
- // message Label
- tagLabel_Key = 1 // int64 (string table index)
- tagLabel_Str = 2 // int64 (string table index)
- tagLabel_Num = 3 // int64
-
- // message Mapping
- tagMapping_ID = 1 // uint64
- tagMapping_Start = 2 // uint64
- tagMapping_Limit = 3 // uint64
- tagMapping_Offset = 4 // uint64
- tagMapping_Filename = 5 // int64 (string table index)
- tagMapping_BuildID = 6 // int64 (string table index)
- tagMapping_HasFunctions = 7 // bool
- tagMapping_HasFilenames = 8 // bool
- tagMapping_HasLineNumbers = 9 // bool
- tagMapping_HasInlineFrames = 10 // bool
-
- // message Location
- tagLocation_ID = 1 // uint64
- tagLocation_MappingID = 2 // uint64
- tagLocation_Address = 3 // uint64
- tagLocation_Line = 4 // repeated Line
-
- // message Line
- tagLine_FunctionID = 1 // uint64
- tagLine_Line = 2 // int64
-
- // message Function
- tagFunction_ID = 1 // uint64
- tagFunction_Name = 2 // int64 (string table index)
- tagFunction_SystemName = 3 // int64 (string table index)
- tagFunction_Filename = 4 // int64 (string table index)
- tagFunction_StartLine = 5 // int64
-)
-
-// stringIndex adds s to the string table if not already present
-// and returns the index of s in the string table.
-func (b *profileBuilder) stringIndex(s string) int64 {
- id, ok := b.stringMap[s]
- if !ok {
- id = len(b.strings)
- b.strings = append(b.strings, s)
- b.stringMap[s] = id
- }
- return int64(id)
-}
-
-func (b *profileBuilder) flush() {
- const dataFlush = 4096
- if b.pb.nest == 0 && len(b.pb.data) > dataFlush {
- b.zw.Write(b.pb.data)
- b.pb.data = b.pb.data[:0]
- }
-}
-
-// pbValueType encodes a ValueType message to b.pb.
-func (b *profileBuilder) pbValueType(tag int, typ, unit string) {
- start := b.pb.startMessage()
- b.pb.int64(tagValueType_Type, b.stringIndex(typ))
- b.pb.int64(tagValueType_Unit, b.stringIndex(unit))
- b.pb.endMessage(tag, start)
-}
-
-// pbSample encodes a Sample message to b.pb.
-func (b *profileBuilder) pbSample(values []int64, locs []uint64, labels func()) {
- start := b.pb.startMessage()
- b.pb.int64s(tagSample_Value, values)
- b.pb.uint64s(tagSample_Location, locs)
- if labels != nil {
- labels()
- }
- b.pb.endMessage(tagProfile_Sample, start)
- b.flush()
-}
-
-// pbLabel encodes a Label message to b.pb.
-func (b *profileBuilder) pbLabel(tag int, key, str string, num int64) {
- start := b.pb.startMessage()
- b.pb.int64Opt(tagLabel_Key, b.stringIndex(key))
- b.pb.int64Opt(tagLabel_Str, b.stringIndex(str))
- b.pb.int64Opt(tagLabel_Num, num)
- b.pb.endMessage(tag, start)
-}
-
-// pbLine encodes a Line message to b.pb.
-func (b *profileBuilder) pbLine(tag int, funcID uint64, line int64) {
- start := b.pb.startMessage()
- b.pb.uint64Opt(tagLine_FunctionID, funcID)
- b.pb.int64Opt(tagLine_Line, line)
- b.pb.endMessage(tag, start)
-}
-
-// pbMapping encodes a Mapping message to b.pb.
-func (b *profileBuilder) pbMapping(tag int, id, base, limit, offset uint64, file, buildID string, hasFuncs bool) {
- start := b.pb.startMessage()
- b.pb.uint64Opt(tagMapping_ID, id)
- b.pb.uint64Opt(tagMapping_Start, base)
- b.pb.uint64Opt(tagMapping_Limit, limit)
- b.pb.uint64Opt(tagMapping_Offset, offset)
- b.pb.int64Opt(tagMapping_Filename, b.stringIndex(file))
- b.pb.int64Opt(tagMapping_BuildID, b.stringIndex(buildID))
- // TODO: we set HasFunctions if all symbols from samples were symbolized (hasFuncs).
- // Decide what to do about HasInlineFrames and HasLineNumbers.
- // Also, another approach to handle the mapping entry with
- // incomplete symbolization results is to dupliace the mapping
- // entry (but with different Has* fields values) and use
- // different entries for symbolized locations and unsymbolized locations.
- if hasFuncs {
- b.pb.bool(tagMapping_HasFunctions, true)
- }
- b.pb.endMessage(tag, start)
-}
-
-func allFrames(addr uintptr) ([]runtime.Frame, symbolizeFlag) {
- // Expand this one address using CallersFrames so we can cache
- // each expansion. In general, CallersFrames takes a whole
- // stack, but in this case we know there will be no skips in
- // the stack and we have return PCs anyway.
- frames := runtime.CallersFrames([]uintptr{addr})
- frame, more := frames.Next()
- if frame.Function == "runtime.goexit" {
- // Short-circuit if we see runtime.goexit so the loop
- // below doesn't allocate a useless empty location.
- return nil, 0
- }
-
- symbolizeResult := lookupTried
- if frame.PC == 0 || frame.Function == "" || frame.File == "" || frame.Line == 0 {
- symbolizeResult |= lookupFailed
- }
-
- if frame.PC == 0 {
- // If we failed to resolve the frame, at least make up
- // a reasonable call PC. This mostly happens in tests.
- frame.PC = addr - 1
- }
- ret := []runtime.Frame{frame}
- for frame.Function != "runtime.goexit" && more {
- frame, more = frames.Next()
- ret = append(ret, frame)
- }
- return ret, symbolizeResult
-}
-
-type locInfo struct {
- // location id assigned by the profileBuilder
- id uint64
-
- // sequence of PCs, including the fake PCs returned by the traceback
- // to represent inlined functions
- // https://github.com/golang/go/blob/d6f2f833c93a41ec1c68e49804b8387a06b131c5/src/runtime/traceback.go#L347-L368
- pcs []uintptr
-
- // firstPCFrames and firstPCSymbolizeResult hold the results of the
- // allFrames call for the first (leaf-most) PC this locInfo represents
- firstPCFrames []runtime.Frame
- firstPCSymbolizeResult symbolizeFlag
-}
-
-// newProfileBuilder returns a new profileBuilder.
-// CPU profiling data obtained from the runtime can be added
-// by calling b.addCPUData, and then the eventual profile
-// can be obtained by calling b.finish.
-func newProfileBuilder(w io.Writer) *profileBuilder {
- zw, _ := gzip.NewWriterLevel(w, gzip.BestSpeed)
- b := &profileBuilder{
- w: w,
- zw: zw,
- start: time.Now(),
- strings: []string{""},
- stringMap: map[string]int{"": 0},
- locs: map[uintptr]locInfo{},
- funcs: map[string]int{},
- }
- b.readMapping()
- return b
-}
-
-// addCPUData adds the CPU profiling data to the profile.
-//
-// The data must be a whole number of records, as delivered by the runtime.
-// len(tags) must be equal to the number of records in data.
-func (b *profileBuilder) addCPUData(data []uint64, tags []unsafe.Pointer) error {
- if !b.havePeriod {
- // first record is period
- if len(data) < 3 {
- return fmt.Errorf("truncated profile")
- }
- if data[0] != 3 || data[2] == 0 {
- return fmt.Errorf("malformed profile")
- }
- // data[2] is sampling rate in Hz. Convert to sampling
- // period in nanoseconds.
- b.period = 1e9 / int64(data[2])
- b.havePeriod = true
- data = data[3:]
- // Consume tag slot. Note that there isn't a meaningful tag
- // value for this record.
- tags = tags[1:]
- }
-
- // Parse CPU samples from the profile.
- // Each sample is 3+n uint64s:
- // data[0] = 3+n
- // data[1] = time stamp (ignored)
- // data[2] = count
- // data[3:3+n] = stack
- // If the count is 0 and the stack has length 1,
- // that's an overflow record inserted by the runtime
- // to indicate that stack[0] samples were lost.
- // Otherwise the count is usually 1,
- // but in a few special cases like lost non-Go samples
- // there can be larger counts.
- // Because many samples with the same stack arrive,
- // we want to deduplicate immediately, which we do
- // using the b.m profMap.
- for len(data) > 0 {
- if len(data) < 3 || data[0] > uint64(len(data)) {
- return fmt.Errorf("truncated profile")
- }
- if data[0] < 3 || tags != nil && len(tags) < 1 {
- return fmt.Errorf("malformed profile")
- }
- if len(tags) < 1 {
- return fmt.Errorf("mismatched profile records and tags")
- }
- count := data[2]
- stk := data[3:data[0]]
- data = data[data[0]:]
- tag := tags[0]
- tags = tags[1:]
-
- if count == 0 && len(stk) == 1 {
- // overflow record
- count = uint64(stk[0])
- stk = []uint64{
- // gentraceback guarantees that PCs in the
- // stack can be unconditionally decremented and
- // still be valid, so we must do the same.
- uint64(abi.FuncPCABIInternal(lostProfileEvent) + 1),
- }
- }
- b.m.lookup(stk, tag).count += int64(count)
- }
-
- if len(tags) != 0 {
- return fmt.Errorf("mismatched profile records and tags")
- }
- return nil
-}
-
-// build completes and returns the constructed profile.
-func (b *profileBuilder) build() {
- b.end = time.Now()
-
- b.pb.int64Opt(tagProfile_TimeNanos, b.start.UnixNano())
- if b.havePeriod { // must be CPU profile
- b.pbValueType(tagProfile_SampleType, "samples", "count")
- b.pbValueType(tagProfile_SampleType, "cpu", "nanoseconds")
- b.pb.int64Opt(tagProfile_DurationNanos, b.end.Sub(b.start).Nanoseconds())
- b.pbValueType(tagProfile_PeriodType, "cpu", "nanoseconds")
- b.pb.int64Opt(tagProfile_Period, b.period)
- }
-
- values := []int64{0, 0}
- var locs []uint64
-
- for e := b.m.all; e != nil; e = e.nextAll {
- values[0] = e.count
- values[1] = e.count * b.period
-
- var labels func()
- if e.tag != nil {
- labels = func() {
- for k, v := range *(*labelMap)(e.tag) {
- b.pbLabel(tagSample_Label, k, v, 0)
- }
- }
- }
-
- locs = b.appendLocsForStack(locs[:0], e.stk)
-
- b.pbSample(values, locs, labels)
- }
-
- for i, m := range b.mem {
- hasFunctions := m.funcs == lookupTried // lookupTried but not lookupFailed
- b.pbMapping(tagProfile_Mapping, uint64(i+1), uint64(m.start), uint64(m.end), m.offset, m.file, m.buildID, hasFunctions)
- }
-
- // TODO: Anything for tagProfile_DropFrames?
- // TODO: Anything for tagProfile_KeepFrames?
-
- b.pb.strings(tagProfile_StringTable, b.strings)
- b.zw.Write(b.pb.data)
- b.zw.Close()
-}
-
-// appendLocsForStack appends the location IDs for the given stack trace to the given
-// location ID slice, locs. The addresses in the stack are return PCs or 1 + the PC of
-// an inline marker as the runtime traceback function returns.
-//
-// It may return an empty slice even if locs is non-empty, for example if locs consists
-// solely of runtime.goexit. We still count these empty stacks in profiles in order to
-// get the right cumulative sample count.
-//
-// It may emit to b.pb, so there must be no message encoding in progress.
-func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) (newLocs []uint64) {
- b.deck.reset()
-
- // The last frame might be truncated. Recover lost inline frames.
- stk = runtime_expandFinalInlineFrame(stk)
-
- for len(stk) > 0 {
- addr := stk[0]
- if l, ok := b.locs[addr]; ok {
- // When generating code for an inlined function, the compiler adds
- // NOP instructions to the outermost function as a placeholder for
- // each layer of inlining. When the runtime generates tracebacks for
- // stacks that include inlined functions, it uses the addresses of
- // those NOPs as "fake" PCs on the stack as if they were regular
- // function call sites. But if a profiling signal arrives while the
- // CPU is executing one of those NOPs, its PC will show up as a leaf
- // in the profile with its own Location entry. So, always check
- // whether addr is a "fake" PC in the context of the current call
- // stack by trying to add it to the inlining deck before assuming
- // that the deck is complete.
- if len(b.deck.pcs) > 0 {
- if added := b.deck.tryAdd(addr, l.firstPCFrames, l.firstPCSymbolizeResult); added {
- stk = stk[1:]
- continue
- }
- }
-
- // first record the location if there is any pending accumulated info.
- if id := b.emitLocation(); id > 0 {
- locs = append(locs, id)
- }
-
- // then, record the cached location.
- locs = append(locs, l.id)
-
- // Skip the matching pcs.
- //
- // Even if stk was truncated due to the stack depth
- // limit, expandFinalInlineFrame above has already
- // fixed the truncation, ensuring it is long enough.
- stk = stk[len(l.pcs):]
- continue
- }
-
- frames, symbolizeResult := allFrames(addr)
- if len(frames) == 0 { // runtime.goexit.
- if id := b.emitLocation(); id > 0 {
- locs = append(locs, id)
- }
- stk = stk[1:]
- continue
- }
-
- if added := b.deck.tryAdd(addr, frames, symbolizeResult); added {
- stk = stk[1:]
- continue
- }
- // add failed because this addr is not inlined with the
- // existing PCs in the deck. Flush the deck and retry handling
- // this pc.
- if id := b.emitLocation(); id > 0 {
- locs = append(locs, id)
- }
-
- // check cache again - previous emitLocation added a new entry
- if l, ok := b.locs[addr]; ok {
- locs = append(locs, l.id)
- stk = stk[len(l.pcs):] // skip the matching pcs.
- } else {
- b.deck.tryAdd(addr, frames, symbolizeResult) // must succeed.
- stk = stk[1:]
- }
- }
- if id := b.emitLocation(); id > 0 { // emit remaining location.
- locs = append(locs, id)
- }
- return locs
-}
-
-// Here's an example of how Go 1.17 writes out inlined functions, compiled for
-// linux/amd64. The disassembly of main.main shows two levels of inlining: main
-// calls b, b calls a, a does some work.
-//
-// inline.go:9 0x4553ec 90 NOPL // func main() { b(v) }
-// inline.go:6 0x4553ed 90 NOPL // func b(v *int) { a(v) }
-// inline.go:5 0x4553ee 48c7002a000000 MOVQ $0x2a, 0(AX) // func a(v *int) { *v = 42 }
-//
-// If a profiling signal arrives while executing the MOVQ at 0x4553ee (for line
-// 5), the runtime will report the stack as the MOVQ frame being called by the
-// NOPL at 0x4553ed (for line 6) being called by the NOPL at 0x4553ec (for line
-// 9).
-//
-// The role of pcDeck is to collapse those three frames back into a single
-// location at 0x4553ee, with file/line/function symbolization info representing
-// the three layers of calls. It does that via sequential calls to pcDeck.tryAdd
-// starting with the leaf-most address. The fourth call to pcDeck.tryAdd will be
-// for the caller of main.main. Because main.main was not inlined in its caller,
-// the deck will reject the addition, and the fourth PC on the stack will get
-// its own location.
-
-// pcDeck is a helper to detect a sequence of inlined functions from
-// a stack trace returned by the runtime.
-//
-// The stack traces returned by runtime's trackback functions are fully
-// expanded (at least for Go functions) and include the fake pcs representing
-// inlined functions. The profile proto expects the inlined functions to be
-// encoded in one Location message.
-// https://github.com/google/pprof/blob/5e965273ee43930341d897407202dd5e10e952cb/proto/profile.proto#L177-L184
-//
-// Runtime does not directly expose whether a frame is for an inlined function
-// and looking up debug info is not ideal, so we use a heuristic to filter
-// the fake pcs and restore the inlined and entry functions. Inlined functions
-// have the following properties:
-//
-// Frame's Func is nil (note: also true for non-Go functions), and
-// Frame's Entry matches its entry function frame's Entry (note: could also be true for recursive calls and non-Go functions), and
-// Frame's Name does not match its entry function frame's name (note: inlined functions cannot be directly recursive).
-//
-// As reading and processing the pcs in a stack trace one by one (from leaf to the root),
-// we use pcDeck to temporarily hold the observed pcs and their expanded frames
-// until we observe the entry function frame.
-type pcDeck struct {
- pcs []uintptr
- frames []runtime.Frame
- symbolizeResult symbolizeFlag
-
- // firstPCFrames indicates the number of frames associated with the first
- // (leaf-most) PC in the deck
- firstPCFrames int
- // firstPCSymbolizeResult holds the results of the allFrames call for the
- // first (leaf-most) PC in the deck
- firstPCSymbolizeResult symbolizeFlag
-}
-
-func (d *pcDeck) reset() {
- d.pcs = d.pcs[:0]
- d.frames = d.frames[:0]
- d.symbolizeResult = 0
- d.firstPCFrames = 0
- d.firstPCSymbolizeResult = 0
-}
-
-// tryAdd tries to add the pc and Frames expanded from it (most likely one,
-// since the stack trace is already fully expanded) and the symbolizeResult
-// to the deck. If it fails the caller needs to flush the deck and retry.
-func (d *pcDeck) tryAdd(pc uintptr, frames []runtime.Frame, symbolizeResult symbolizeFlag) (success bool) {
- if existing := len(d.frames); existing > 0 {
- // 'd.frames' are all expanded from one 'pc' and represent all
- // inlined functions so we check only the last one.
- newFrame := frames[0]
- last := d.frames[existing-1]
- if last.Func != nil { // the last frame can't be inlined. Flush.
- return false
- }
- if last.Entry == 0 || newFrame.Entry == 0 { // Possibly not a Go function. Don't try to merge.
- return false
- }
-
- if last.Entry != newFrame.Entry { // newFrame is for a different function.
- return false
- }
- if last.Function == newFrame.Function { // maybe recursion.
- return false
- }
- }
- d.pcs = append(d.pcs, pc)
- d.frames = append(d.frames, frames...)
- d.symbolizeResult |= symbolizeResult
- if len(d.pcs) == 1 {
- d.firstPCFrames = len(d.frames)
- d.firstPCSymbolizeResult = symbolizeResult
- }
- return true
-}
-
-// emitLocation emits the new location and function information recorded in the deck
-// and returns the location ID encoded in the profile protobuf.
-// It emits to b.pb, so there must be no message encoding in progress.
-// It resets the deck.
-func (b *profileBuilder) emitLocation() uint64 {
- if len(b.deck.pcs) == 0 {
- return 0
- }
- defer b.deck.reset()
-
- addr := b.deck.pcs[0]
- firstFrame := b.deck.frames[0]
-
- // We can't write out functions while in the middle of the
- // Location message, so record new functions we encounter and
- // write them out after the Location.
- type newFunc struct {
- id uint64
- name, file string
- startLine int64
- }
- newFuncs := make([]newFunc, 0, 8)
-
- id := uint64(len(b.locs)) + 1
- b.locs[addr] = locInfo{
- id: id,
- pcs: append([]uintptr{}, b.deck.pcs...),
- firstPCSymbolizeResult: b.deck.firstPCSymbolizeResult,
- firstPCFrames: append([]runtime.Frame{}, b.deck.frames[:b.deck.firstPCFrames]...),
- }
-
- start := b.pb.startMessage()
- b.pb.uint64Opt(tagLocation_ID, id)
- b.pb.uint64Opt(tagLocation_Address, uint64(firstFrame.PC))
- for _, frame := range b.deck.frames {
- // Write out each line in frame expansion.
- funcID := uint64(b.funcs[frame.Function])
- if funcID == 0 {
- funcID = uint64(len(b.funcs)) + 1
- b.funcs[frame.Function] = int(funcID)
- newFuncs = append(newFuncs, newFunc{
- id: funcID,
- name: frame.Function,
- file: frame.File,
- startLine: int64(runtime_FrameStartLine(&frame)),
- })
- }
- b.pbLine(tagLocation_Line, funcID, int64(frame.Line))
- }
- for i := range b.mem {
- if b.mem[i].start <= addr && addr < b.mem[i].end || b.mem[i].fake {
- b.pb.uint64Opt(tagLocation_MappingID, uint64(i+1))
-
- m := b.mem[i]
- m.funcs |= b.deck.symbolizeResult
- b.mem[i] = m
- break
- }
- }
- b.pb.endMessage(tagProfile_Location, start)
-
- // Write out functions we found during frame expansion.
- for _, fn := range newFuncs {
- start := b.pb.startMessage()
- b.pb.uint64Opt(tagFunction_ID, fn.id)
- b.pb.int64Opt(tagFunction_Name, b.stringIndex(fn.name))
- b.pb.int64Opt(tagFunction_SystemName, b.stringIndex(fn.name))
- b.pb.int64Opt(tagFunction_Filename, b.stringIndex(fn.file))
- b.pb.int64Opt(tagFunction_StartLine, fn.startLine)
- b.pb.endMessage(tagProfile_Function, start)
- }
-
- b.flush()
- return id
-}
-
-var space = []byte(" ")
-var newline = []byte("\n")
-
-func parseProcSelfMaps(data []byte, addMapping func(lo, hi, offset uint64, file, buildID string)) {
- // $ cat /proc/self/maps
- // 00400000-0040b000 r-xp 00000000 fc:01 787766 /bin/cat
- // 0060a000-0060b000 r--p 0000a000 fc:01 787766 /bin/cat
- // 0060b000-0060c000 rw-p 0000b000 fc:01 787766 /bin/cat
- // 014ab000-014cc000 rw-p 00000000 00:00 0 [heap]
- // 7f7d76af8000-7f7d7797c000 r--p 00000000 fc:01 1318064 /usr/lib/locale/locale-archive
- // 7f7d7797c000-7f7d77b36000 r-xp 00000000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
- // 7f7d77b36000-7f7d77d36000 ---p 001ba000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
- // 7f7d77d36000-7f7d77d3a000 r--p 001ba000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
- // 7f7d77d3a000-7f7d77d3c000 rw-p 001be000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
- // 7f7d77d3c000-7f7d77d41000 rw-p 00000000 00:00 0
- // 7f7d77d41000-7f7d77d64000 r-xp 00000000 fc:01 1180217 /lib/x86_64-linux-gnu/ld-2.19.so
- // 7f7d77f3f000-7f7d77f42000 rw-p 00000000 00:00 0
- // 7f7d77f61000-7f7d77f63000 rw-p 00000000 00:00 0
- // 7f7d77f63000-7f7d77f64000 r--p 00022000 fc:01 1180217 /lib/x86_64-linux-gnu/ld-2.19.so
- // 7f7d77f64000-7f7d77f65000 rw-p 00023000 fc:01 1180217 /lib/x86_64-linux-gnu/ld-2.19.so
- // 7f7d77f65000-7f7d77f66000 rw-p 00000000 00:00 0
- // 7ffc342a2000-7ffc342c3000 rw-p 00000000 00:00 0 [stack]
- // 7ffc34343000-7ffc34345000 r-xp 00000000 00:00 0 [vdso]
- // ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
-
- var line []byte
- // next removes and returns the next field in the line.
- // It also removes from line any spaces following the field.
- next := func() []byte {
- var f []byte
- f, line, _ = bytes.Cut(line, space)
- line = bytes.TrimLeft(line, " ")
- return f
- }
-
- for len(data) > 0 {
- line, data, _ = bytes.Cut(data, newline)
- addr := next()
- loStr, hiStr, ok := strings.Cut(string(addr), "-")
- if !ok {
- continue
- }
- lo, err := strconv.ParseUint(loStr, 16, 64)
- if err != nil {
- continue
- }
- hi, err := strconv.ParseUint(hiStr, 16, 64)
- if err != nil {
- continue
- }
- perm := next()
- if len(perm) < 4 || perm[2] != 'x' {
- // Only interested in executable mappings.
- continue
- }
- offset, err := strconv.ParseUint(string(next()), 16, 64)
- if err != nil {
- continue
- }
- next() // dev
- inode := next() // inode
- if line == nil {
- continue
- }
- file := string(line)
-
- // Trim deleted file marker.
- deletedStr := " (deleted)"
- deletedLen := len(deletedStr)
- if len(file) >= deletedLen && file[len(file)-deletedLen:] == deletedStr {
- file = file[:len(file)-deletedLen]
- }
-
- if len(inode) == 1 && inode[0] == '0' && file == "" {
- // Huge-page text mappings list the initial fragment of
- // mapped but unpopulated memory as being inode 0.
- // Don't report that part.
- // But [vdso] and [vsyscall] are inode 0, so let non-empty file names through.
- continue
- }
-
- // TODO: pprof's remapMappingIDs makes one adjustment:
- // 1. If there is an /anon_hugepage mapping first and it is
- // consecutive to a next mapping, drop the /anon_hugepage.
- // There's no indication why this is needed.
- // Let's try not doing this and see what breaks.
- // If we do need it, it would go here, before we
- // enter the mappings into b.mem in the first place.
-
- buildID, _ := elfBuildID(file)
- addMapping(lo, hi, offset, file, buildID)
- }
-}
-
-func (b *profileBuilder) addMapping(lo, hi, offset uint64, file, buildID string) {
- b.addMappingEntry(lo, hi, offset, file, buildID, false)
-}
-
-func (b *profileBuilder) addMappingEntry(lo, hi, offset uint64, file, buildID string, fake bool) {
- b.mem = append(b.mem, memMap{
- start: uintptr(lo),
- end: uintptr(hi),
- offset: offset,
- file: file,
- buildID: buildID,
- fake: fake,
- })
-}
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/runtime.go b/contrib/go/_std_1.20/src/runtime/pprof/runtime.go
deleted file mode 100644
index 57e9ca480b..0000000000
--- a/contrib/go/_std_1.20/src/runtime/pprof/runtime.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 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 pprof
-
-import (
- "context"
- "runtime"
- "unsafe"
-)
-
-// runtime_FrameStartLine is defined in runtime/symtab.go.
-func runtime_FrameStartLine(f *runtime.Frame) int
-
-// runtime_expandFinalInlineFrame is defined in runtime/symtab.go.
-func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr
-
-// runtime_setProfLabel is defined in runtime/proflabel.go.
-func runtime_setProfLabel(labels unsafe.Pointer)
-
-// runtime_getProfLabel is defined in runtime/proflabel.go.
-func runtime_getProfLabel() unsafe.Pointer
-
-// SetGoroutineLabels sets the current goroutine's labels to match ctx.
-// A new goroutine inherits the labels of the goroutine that created it.
-// This is a lower-level API than Do, which should be used instead when possible.
-func SetGoroutineLabels(ctx context.Context) {
- ctxLabels, _ := ctx.Value(labelContextKey{}).(*labelMap)
- runtime_setProfLabel(unsafe.Pointer(ctxLabels))
-}
-
-// Do calls f with a copy of the parent context with the
-// given labels added to the parent's label map.
-// Goroutines spawned while executing f will inherit the augmented label-set.
-// Each key/value pair in labels is inserted into the label map in the
-// order provided, overriding any previous value for the same key.
-// The augmented label map will be set for the duration of the call to f
-// and restored once f returns.
-func Do(ctx context.Context, labels LabelSet, f func(context.Context)) {
- defer SetGoroutineLabels(ctx)
- ctx = WithLabels(ctx, labels)
- SetGoroutineLabels(ctx)
- f(ctx)
-}
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/ya.make b/contrib/go/_std_1.20/src/runtime/pprof/ya.make
deleted file mode 100644
index 9ae65b38fa..0000000000
--- a/contrib/go/_std_1.20/src/runtime/pprof/ya.make
+++ /dev/null
@@ -1,36 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- elf.go
- label.go
- map.go
- pe.go
- pprof.go
- proto.go
- protobuf.go
- protomem.go
- runtime.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- pprof_rusage.go
- proto_other.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- pprof_rusage.go
- proto_other.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- pprof_windows.go
- proto_windows.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/runtime/preempt.go b/contrib/go/_std_1.20/src/runtime/preempt.go
deleted file mode 100644
index 4f62fc628b..0000000000
--- a/contrib/go/_std_1.20/src/runtime/preempt.go
+++ /dev/null
@@ -1,452 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Goroutine preemption
-//
-// A goroutine can be preempted at any safe-point. Currently, there
-// are a few categories of safe-points:
-//
-// 1. A blocked safe-point occurs for the duration that a goroutine is
-// descheduled, blocked on synchronization, or in a system call.
-//
-// 2. Synchronous safe-points occur when a running goroutine checks
-// for a preemption request.
-//
-// 3. Asynchronous safe-points occur at any instruction in user code
-// where the goroutine can be safely paused and a conservative
-// stack and register scan can find stack roots. The runtime can
-// stop a goroutine at an async safe-point using a signal.
-//
-// At both blocked and synchronous safe-points, a goroutine's CPU
-// state is minimal and the garbage collector has complete information
-// about its entire stack. This makes it possible to deschedule a
-// goroutine with minimal space, and to precisely scan a goroutine's
-// stack.
-//
-// Synchronous safe-points are implemented by overloading the stack
-// bound check in function prologues. To preempt a goroutine at the
-// next synchronous safe-point, the runtime poisons the goroutine's
-// stack bound to a value that will cause the next stack bound check
-// to fail and enter the stack growth implementation, which will
-// detect that it was actually a preemption and redirect to preemption
-// handling.
-//
-// Preemption at asynchronous safe-points is implemented by suspending
-// the thread using an OS mechanism (e.g., signals) and inspecting its
-// state to determine if the goroutine was at an asynchronous
-// safe-point. Since the thread suspension itself is generally
-// asynchronous, it also checks if the running goroutine wants to be
-// preempted, since this could have changed. If all conditions are
-// satisfied, it adjusts the signal context to make it look like the
-// signaled thread just called asyncPreempt and resumes the thread.
-// asyncPreempt spills all registers and enters the scheduler.
-//
-// (An alternative would be to preempt in the signal handler itself.
-// This would let the OS save and restore the register state and the
-// runtime would only need to know how to extract potentially
-// pointer-containing registers from the signal context. However, this
-// would consume an M for every preempted G, and the scheduler itself
-// is not designed to run from a signal handler, as it tends to
-// allocate memory and start threads in the preemption path.)
-
-package runtime
-
-import (
- "internal/abi"
- "internal/goarch"
-)
-
-type suspendGState struct {
- g *g
-
- // dead indicates the goroutine was not suspended because it
- // is dead. This goroutine could be reused after the dead
- // state was observed, so the caller must not assume that it
- // remains dead.
- dead bool
-
- // stopped indicates that this suspendG transitioned the G to
- // _Gwaiting via g.preemptStop and thus is responsible for
- // readying it when done.
- stopped bool
-}
-
-// suspendG suspends goroutine gp at a safe-point and returns the
-// state of the suspended goroutine. The caller gets read access to
-// the goroutine until it calls resumeG.
-//
-// It is safe for multiple callers to attempt to suspend the same
-// goroutine at the same time. The goroutine may execute between
-// subsequent successful suspend operations. The current
-// implementation grants exclusive access to the goroutine, and hence
-// multiple callers will serialize. However, the intent is to grant
-// shared read access, so please don't depend on exclusive access.
-//
-// This must be called from the system stack and the user goroutine on
-// the current M (if any) must be in a preemptible state. This
-// prevents deadlocks where two goroutines attempt to suspend each
-// other and both are in non-preemptible states. There are other ways
-// to resolve this deadlock, but this seems simplest.
-//
-// TODO(austin): What if we instead required this to be called from a
-// user goroutine? Then we could deschedule the goroutine while
-// waiting instead of blocking the thread. If two goroutines tried to
-// suspend each other, one of them would win and the other wouldn't
-// complete the suspend until it was resumed. We would have to be
-// careful that they couldn't actually queue up suspend for each other
-// and then both be suspended. This would also avoid the need for a
-// kernel context switch in the synchronous case because we could just
-// directly schedule the waiter. The context switch is unavoidable in
-// the signal case.
-//
-//go:systemstack
-func suspendG(gp *g) suspendGState {
- if mp := getg().m; mp.curg != nil && readgstatus(mp.curg) == _Grunning {
- // Since we're on the system stack of this M, the user
- // G is stuck at an unsafe point. If another goroutine
- // were to try to preempt m.curg, it could deadlock.
- throw("suspendG from non-preemptible goroutine")
- }
-
- // See https://golang.org/cl/21503 for justification of the yield delay.
- const yieldDelay = 10 * 1000
- var nextYield int64
-
- // Drive the goroutine to a preemption point.
- stopped := false
- var asyncM *m
- var asyncGen uint32
- var nextPreemptM int64
- for i := 0; ; i++ {
- switch s := readgstatus(gp); s {
- default:
- if s&_Gscan != 0 {
- // Someone else is suspending it. Wait
- // for them to finish.
- //
- // TODO: It would be nicer if we could
- // coalesce suspends.
- break
- }
-
- dumpgstatus(gp)
- throw("invalid g status")
-
- case _Gdead:
- // Nothing to suspend.
- //
- // preemptStop may need to be cleared, but
- // doing that here could race with goroutine
- // reuse. Instead, goexit0 clears it.
- return suspendGState{dead: true}
-
- case _Gcopystack:
- // The stack is being copied. We need to wait
- // until this is done.
-
- case _Gpreempted:
- // We (or someone else) suspended the G. Claim
- // ownership of it by transitioning it to
- // _Gwaiting.
- if !casGFromPreempted(gp, _Gpreempted, _Gwaiting) {
- break
- }
-
- // We stopped the G, so we have to ready it later.
- stopped = true
-
- s = _Gwaiting
- fallthrough
-
- case _Grunnable, _Gsyscall, _Gwaiting:
- // Claim goroutine by setting scan bit.
- // This may race with execution or readying of gp.
- // The scan bit keeps it from transition state.
- if !castogscanstatus(gp, s, s|_Gscan) {
- break
- }
-
- // Clear the preemption request. It's safe to
- // reset the stack guard because we hold the
- // _Gscan bit and thus own the stack.
- gp.preemptStop = false
- gp.preempt = false
- gp.stackguard0 = gp.stack.lo + _StackGuard
-
- // The goroutine was already at a safe-point
- // and we've now locked that in.
- //
- // TODO: It would be much better if we didn't
- // leave it in _Gscan, but instead gently
- // prevented its scheduling until resumption.
- // Maybe we only use this to bump a suspended
- // count and the scheduler skips suspended
- // goroutines? That wouldn't be enough for
- // {_Gsyscall,_Gwaiting} -> _Grunning. Maybe
- // for all those transitions we need to check
- // suspended and deschedule?
- return suspendGState{g: gp, stopped: stopped}
-
- case _Grunning:
- // Optimization: if there is already a pending preemption request
- // (from the previous loop iteration), don't bother with the atomics.
- if gp.preemptStop && gp.preempt && gp.stackguard0 == stackPreempt && asyncM == gp.m && asyncM.preemptGen.Load() == asyncGen {
- break
- }
-
- // Temporarily block state transitions.
- if !castogscanstatus(gp, _Grunning, _Gscanrunning) {
- break
- }
-
- // Request synchronous preemption.
- gp.preemptStop = true
- gp.preempt = true
- gp.stackguard0 = stackPreempt
-
- // Prepare for asynchronous preemption.
- asyncM2 := gp.m
- asyncGen2 := asyncM2.preemptGen.Load()
- needAsync := asyncM != asyncM2 || asyncGen != asyncGen2
- asyncM = asyncM2
- asyncGen = asyncGen2
-
- casfrom_Gscanstatus(gp, _Gscanrunning, _Grunning)
-
- // Send asynchronous preemption. We do this
- // after CASing the G back to _Grunning
- // because preemptM may be synchronous and we
- // don't want to catch the G just spinning on
- // its status.
- if preemptMSupported && debug.asyncpreemptoff == 0 && needAsync {
- // Rate limit preemptM calls. This is
- // particularly important on Windows
- // where preemptM is actually
- // synchronous and the spin loop here
- // can lead to live-lock.
- now := nanotime()
- if now >= nextPreemptM {
- nextPreemptM = now + yieldDelay/2
- preemptM(asyncM)
- }
- }
- }
-
- // TODO: Don't busy wait. This loop should really only
- // be a simple read/decide/CAS loop that only fails if
- // there's an active race. Once the CAS succeeds, we
- // should queue up the preemption (which will require
- // it to be reliable in the _Grunning case, not
- // best-effort) and then sleep until we're notified
- // that the goroutine is suspended.
- if i == 0 {
- nextYield = nanotime() + yieldDelay
- }
- if nanotime() < nextYield {
- procyield(10)
- } else {
- osyield()
- nextYield = nanotime() + yieldDelay/2
- }
- }
-}
-
-// resumeG undoes the effects of suspendG, allowing the suspended
-// goroutine to continue from its current safe-point.
-func resumeG(state suspendGState) {
- if state.dead {
- // We didn't actually stop anything.
- return
- }
-
- gp := state.g
- switch s := readgstatus(gp); s {
- default:
- dumpgstatus(gp)
- throw("unexpected g status")
-
- case _Grunnable | _Gscan,
- _Gwaiting | _Gscan,
- _Gsyscall | _Gscan:
- casfrom_Gscanstatus(gp, s, s&^_Gscan)
- }
-
- if state.stopped {
- // We stopped it, so we need to re-schedule it.
- ready(gp, 0, true)
- }
-}
-
-// canPreemptM reports whether mp is in a state that is safe to preempt.
-//
-// It is nosplit because it has nosplit callers.
-//
-//go:nosplit
-func canPreemptM(mp *m) bool {
- return mp.locks == 0 && mp.mallocing == 0 && mp.preemptoff == "" && mp.p.ptr().status == _Prunning
-}
-
-//go:generate go run mkpreempt.go
-
-// asyncPreempt saves all user registers and calls asyncPreempt2.
-//
-// When stack scanning encounters an asyncPreempt frame, it scans that
-// frame and its parent frame conservatively.
-//
-// asyncPreempt is implemented in assembly.
-func asyncPreempt()
-
-//go:nosplit
-func asyncPreempt2() {
- gp := getg()
- gp.asyncSafePoint = true
- if gp.preemptStop {
- mcall(preemptPark)
- } else {
- mcall(gopreempt_m)
- }
- gp.asyncSafePoint = false
-}
-
-// asyncPreemptStack is the bytes of stack space required to inject an
-// asyncPreempt call.
-var asyncPreemptStack = ^uintptr(0)
-
-func init() {
- f := findfunc(abi.FuncPCABI0(asyncPreempt))
- total := funcMaxSPDelta(f)
- f = findfunc(abi.FuncPCABIInternal(asyncPreempt2))
- total += funcMaxSPDelta(f)
- // Add some overhead for return PCs, etc.
- asyncPreemptStack = uintptr(total) + 8*goarch.PtrSize
- if asyncPreemptStack > _StackLimit {
- // We need more than the nosplit limit. This isn't
- // unsafe, but it may limit asynchronous preemption.
- //
- // This may be a problem if we start using more
- // registers. In that case, we should store registers
- // in a context object. If we pre-allocate one per P,
- // asyncPreempt can spill just a few registers to the
- // stack, then grab its context object and spill into
- // it. When it enters the runtime, it would allocate a
- // new context for the P.
- print("runtime: asyncPreemptStack=", asyncPreemptStack, "\n")
- throw("async stack too large")
- }
-}
-
-// wantAsyncPreempt returns whether an asynchronous preemption is
-// queued for gp.
-func wantAsyncPreempt(gp *g) bool {
- // Check both the G and the P.
- return (gp.preempt || gp.m.p != 0 && gp.m.p.ptr().preempt) && readgstatus(gp)&^_Gscan == _Grunning
-}
-
-// isAsyncSafePoint reports whether gp at instruction PC is an
-// asynchronous safe point. This indicates that:
-//
-// 1. It's safe to suspend gp and conservatively scan its stack and
-// registers. There are no potentially hidden pointer values and it's
-// not in the middle of an atomic sequence like a write barrier.
-//
-// 2. gp has enough stack space to inject the asyncPreempt call.
-//
-// 3. It's generally safe to interact with the runtime, even if we're
-// in a signal handler stopped here. For example, there are no runtime
-// locks held, so acquiring a runtime lock won't self-deadlock.
-//
-// In some cases the PC is safe for asynchronous preemption but it
-// also needs to adjust the resumption PC. The new PC is returned in
-// the second result.
-func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) (bool, uintptr) {
- mp := gp.m
-
- // Only user Gs can have safe-points. We check this first
- // because it's extremely common that we'll catch mp in the
- // scheduler processing this G preemption.
- if mp.curg != gp {
- return false, 0
- }
-
- // Check M state.
- if mp.p == 0 || !canPreemptM(mp) {
- return false, 0
- }
-
- // Check stack space.
- if sp < gp.stack.lo || sp-gp.stack.lo < asyncPreemptStack {
- return false, 0
- }
-
- // Check if PC is an unsafe-point.
- f := findfunc(pc)
- if !f.valid() {
- // Not Go code.
- return false, 0
- }
- if (GOARCH == "mips" || GOARCH == "mipsle" || GOARCH == "mips64" || GOARCH == "mips64le") && lr == pc+8 && funcspdelta(f, pc, nil) == 0 {
- // We probably stopped at a half-executed CALL instruction,
- // where the LR is updated but the PC has not. If we preempt
- // here we'll see a seemingly self-recursive call, which is in
- // fact not.
- // This is normally ok, as we use the return address saved on
- // stack for unwinding, not the LR value. But if this is a
- // call to morestack, we haven't created the frame, and we'll
- // use the LR for unwinding, which will be bad.
- return false, 0
- }
- up, startpc := pcdatavalue2(f, _PCDATA_UnsafePoint, pc)
- if up == _PCDATA_UnsafePointUnsafe {
- // Unsafe-point marked by compiler. This includes
- // atomic sequences (e.g., write barrier) and nosplit
- // functions (except at calls).
- return false, 0
- }
- if fd := funcdata(f, _FUNCDATA_LocalsPointerMaps); fd == nil || f.flag&funcFlag_ASM != 0 {
- // This is assembly code. Don't assume it's well-formed.
- // TODO: Empirically we still need the fd == nil check. Why?
- //
- // TODO: Are there cases that are safe but don't have a
- // locals pointer map, like empty frame functions?
- // It might be possible to preempt any assembly functions
- // except the ones that have funcFlag_SPWRITE set in f.flag.
- return false, 0
- }
- name := funcname(f)
- if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil {
- inltree := (*[1 << 20]inlinedCall)(inldata)
- ix := pcdatavalue(f, _PCDATA_InlTreeIndex, pc, nil)
- if ix >= 0 {
- name = funcnameFromNameOff(f, inltree[ix].nameOff)
- }
- }
- if hasPrefix(name, "runtime.") ||
- hasPrefix(name, "runtime/internal/") ||
- hasPrefix(name, "reflect.") {
- // For now we never async preempt the runtime or
- // anything closely tied to the runtime. Known issues
- // include: various points in the scheduler ("don't
- // preempt between here and here"), much of the defer
- // implementation (untyped info on stack), bulk write
- // barriers (write barrier check),
- // reflect.{makeFuncStub,methodValueCall}.
- //
- // TODO(austin): We should improve this, or opt things
- // in incrementally.
- return false, 0
- }
- switch up {
- case _PCDATA_Restart1, _PCDATA_Restart2:
- // Restartable instruction sequence. Back off PC to
- // the start PC.
- if startpc == 0 || startpc > pc || pc-startpc > 20 {
- throw("bad restart PC")
- }
- return true, startpc
- case _PCDATA_RestartAtEntry:
- // Restart from the function entry at resumption.
- return true, f.entry()
- }
- return true, pc
-}
diff --git a/contrib/go/_std_1.20/src/runtime/print.go b/contrib/go/_std_1.20/src/runtime/print.go
deleted file mode 100644
index a1e0b8e134..0000000000
--- a/contrib/go/_std_1.20/src/runtime/print.go
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright 2009 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 runtime
-
-import (
- "internal/goarch"
- "unsafe"
-)
-
-// The compiler knows that a print of a value of this type
-// should use printhex instead of printuint (decimal).
-type hex uint64
-
-func bytes(s string) (ret []byte) {
- rp := (*slice)(unsafe.Pointer(&ret))
- sp := stringStructOf(&s)
- rp.array = sp.str
- rp.len = sp.len
- rp.cap = sp.len
- return
-}
-
-var (
- // printBacklog is a circular buffer of messages written with the builtin
- // print* functions, for use in postmortem analysis of core dumps.
- printBacklog [512]byte
- printBacklogIndex int
-)
-
-// recordForPanic maintains a circular buffer of messages written by the
-// runtime leading up to a process crash, allowing the messages to be
-// extracted from a core dump.
-//
-// The text written during a process crash (following "panic" or "fatal
-// error") is not saved, since the goroutine stacks will generally be readable
-// from the runtime datastructures in the core file.
-func recordForPanic(b []byte) {
- printlock()
-
- if panicking.Load() == 0 {
- // Not actively crashing: maintain circular buffer of print output.
- for i := 0; i < len(b); {
- n := copy(printBacklog[printBacklogIndex:], b[i:])
- i += n
- printBacklogIndex += n
- printBacklogIndex %= len(printBacklog)
- }
- }
-
- printunlock()
-}
-
-var debuglock mutex
-
-// The compiler emits calls to printlock and printunlock around
-// the multiple calls that implement a single Go print or println
-// statement. Some of the print helpers (printslice, for example)
-// call print recursively. There is also the problem of a crash
-// happening during the print routines and needing to acquire
-// the print lock to print information about the crash.
-// For both these reasons, let a thread acquire the printlock 'recursively'.
-
-func printlock() {
- mp := getg().m
- mp.locks++ // do not reschedule between printlock++ and lock(&debuglock).
- mp.printlock++
- if mp.printlock == 1 {
- lock(&debuglock)
- }
- mp.locks-- // now we know debuglock is held and holding up mp.locks for us.
-}
-
-func printunlock() {
- mp := getg().m
- mp.printlock--
- if mp.printlock == 0 {
- unlock(&debuglock)
- }
-}
-
-// write to goroutine-local buffer if diverting output,
-// or else standard error.
-func gwrite(b []byte) {
- if len(b) == 0 {
- return
- }
- recordForPanic(b)
- gp := getg()
- // Don't use the writebuf if gp.m is dying. We want anything
- // written through gwrite to appear in the terminal rather
- // than be written to in some buffer, if we're in a panicking state.
- // Note that we can't just clear writebuf in the gp.m.dying case
- // because a panic isn't allowed to have any write barriers.
- if gp == nil || gp.writebuf == nil || gp.m.dying > 0 {
- writeErr(b)
- return
- }
-
- n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
- gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
-}
-
-func printsp() {
- printstring(" ")
-}
-
-func printnl() {
- printstring("\n")
-}
-
-func printbool(v bool) {
- if v {
- printstring("true")
- } else {
- printstring("false")
- }
-}
-
-func printfloat(v float64) {
- switch {
- case v != v:
- printstring("NaN")
- return
- case v+v == v && v > 0:
- printstring("+Inf")
- return
- case v+v == v && v < 0:
- printstring("-Inf")
- return
- }
-
- const n = 7 // digits printed
- var buf [n + 7]byte
- buf[0] = '+'
- e := 0 // exp
- if v == 0 {
- if 1/v < 0 {
- buf[0] = '-'
- }
- } else {
- if v < 0 {
- v = -v
- buf[0] = '-'
- }
-
- // normalize
- for v >= 10 {
- e++
- v /= 10
- }
- for v < 1 {
- e--
- v *= 10
- }
-
- // round
- h := 5.0
- for i := 0; i < n; i++ {
- h /= 10
- }
- v += h
- if v >= 10 {
- e++
- v /= 10
- }
- }
-
- // format +d.dddd+edd
- for i := 0; i < n; i++ {
- s := int(v)
- buf[i+2] = byte(s + '0')
- v -= float64(s)
- v *= 10
- }
- buf[1] = buf[2]
- buf[2] = '.'
-
- buf[n+2] = 'e'
- buf[n+3] = '+'
- if e < 0 {
- e = -e
- buf[n+3] = '-'
- }
-
- buf[n+4] = byte(e/100) + '0'
- buf[n+5] = byte(e/10)%10 + '0'
- buf[n+6] = byte(e%10) + '0'
- gwrite(buf[:])
-}
-
-func printcomplex(c complex128) {
- print("(", real(c), imag(c), "i)")
-}
-
-func printuint(v uint64) {
- var buf [100]byte
- i := len(buf)
- for i--; i > 0; i-- {
- buf[i] = byte(v%10 + '0')
- if v < 10 {
- break
- }
- v /= 10
- }
- gwrite(buf[i:])
-}
-
-func printint(v int64) {
- if v < 0 {
- printstring("-")
- v = -v
- }
- printuint(uint64(v))
-}
-
-var minhexdigits = 0 // protected by printlock
-
-func printhex(v uint64) {
- const dig = "0123456789abcdef"
- var buf [100]byte
- i := len(buf)
- for i--; i > 0; i-- {
- buf[i] = dig[v%16]
- if v < 16 && len(buf)-i >= minhexdigits {
- break
- }
- v /= 16
- }
- i--
- buf[i] = 'x'
- i--
- buf[i] = '0'
- gwrite(buf[i:])
-}
-
-func printpointer(p unsafe.Pointer) {
- printhex(uint64(uintptr(p)))
-}
-func printuintptr(p uintptr) {
- printhex(uint64(p))
-}
-
-func printstring(s string) {
- gwrite(bytes(s))
-}
-
-func printslice(s []byte) {
- sp := (*slice)(unsafe.Pointer(&s))
- print("[", len(s), "/", cap(s), "]")
- printpointer(sp.array)
-}
-
-func printeface(e eface) {
- print("(", e._type, ",", e.data, ")")
-}
-
-func printiface(i iface) {
- print("(", i.tab, ",", i.data, ")")
-}
-
-// hexdumpWords prints a word-oriented hex dump of [p, end).
-//
-// If mark != nil, it will be called with each printed word's address
-// and should return a character mark to appear just before that
-// word's value. It can return 0 to indicate no mark.
-func hexdumpWords(p, end uintptr, mark func(uintptr) byte) {
- printlock()
- var markbuf [1]byte
- markbuf[0] = ' '
- minhexdigits = int(unsafe.Sizeof(uintptr(0)) * 2)
- for i := uintptr(0); p+i < end; i += goarch.PtrSize {
- if i%16 == 0 {
- if i != 0 {
- println()
- }
- print(hex(p+i), ": ")
- }
-
- if mark != nil {
- markbuf[0] = mark(p + i)
- if markbuf[0] == 0 {
- markbuf[0] = ' '
- }
- }
- gwrite(markbuf[:])
- val := *(*uintptr)(unsafe.Pointer(p + i))
- print(hex(val))
- print(" ")
-
- // Can we symbolize val?
- fn := findfunc(val)
- if fn.valid() {
- print("<", funcname(fn), "+", hex(val-fn.entry()), "> ")
- }
- }
- minhexdigits = 0
- println()
- printunlock()
-}
diff --git a/contrib/go/_std_1.20/src/runtime/proc.go b/contrib/go/_std_1.20/src/runtime/proc.go
deleted file mode 100644
index 96908fc6a5..0000000000
--- a/contrib/go/_std_1.20/src/runtime/proc.go
+++ /dev/null
@@ -1,6547 +0,0 @@
-// Copyright 2014 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 runtime
-
-import (
- "internal/abi"
- "internal/cpu"
- "internal/goarch"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// set using cmd/go/internal/modload.ModInfoProg
-var modinfo string
-
-// Goroutine scheduler
-// The scheduler's job is to distribute ready-to-run goroutines over worker threads.
-//
-// The main concepts are:
-// G - goroutine.
-// M - worker thread, or machine.
-// P - processor, a resource that is required to execute Go code.
-// M must have an associated P to execute Go code, however it can be
-// blocked or in a syscall w/o an associated P.
-//
-// Design doc at https://golang.org/s/go11sched.
-
-// Worker thread parking/unparking.
-// We need to balance between keeping enough running worker threads to utilize
-// available hardware parallelism and parking excessive running worker threads
-// to conserve CPU resources and power. This is not simple for two reasons:
-// (1) scheduler state is intentionally distributed (in particular, per-P work
-// queues), so it is not possible to compute global predicates on fast paths;
-// (2) for optimal thread management we would need to know the future (don't park
-// a worker thread when a new goroutine will be readied in near future).
-//
-// Three rejected approaches that would work badly:
-// 1. Centralize all scheduler state (would inhibit scalability).
-// 2. Direct goroutine handoff. That is, when we ready a new goroutine and there
-// is a spare P, unpark a thread and handoff it the thread and the goroutine.
-// This would lead to thread state thrashing, as the thread that readied the
-// goroutine can be out of work the very next moment, we will need to park it.
-// Also, it would destroy locality of computation as we want to preserve
-// dependent goroutines on the same thread; and introduce additional latency.
-// 3. Unpark an additional thread whenever we ready a goroutine and there is an
-// idle P, but don't do handoff. This would lead to excessive thread parking/
-// unparking as the additional threads will instantly park without discovering
-// any work to do.
-//
-// The current approach:
-//
-// This approach applies to three primary sources of potential work: readying a
-// goroutine, new/modified-earlier timers, and idle-priority GC. See below for
-// additional details.
-//
-// We unpark an additional thread when we submit work if (this is wakep()):
-// 1. There is an idle P, and
-// 2. There are no "spinning" worker threads.
-//
-// A worker thread is considered spinning if it is out of local work and did
-// not find work in the global run queue or netpoller; the spinning state is
-// denoted in m.spinning and in sched.nmspinning. Threads unparked this way are
-// also considered spinning; we don't do goroutine handoff so such threads are
-// out of work initially. Spinning threads spin on looking for work in per-P
-// run queues and timer heaps or from the GC before parking. If a spinning
-// thread finds work it takes itself out of the spinning state and proceeds to
-// execution. If it does not find work it takes itself out of the spinning
-// state and then parks.
-//
-// If there is at least one spinning thread (sched.nmspinning>1), we don't
-// unpark new threads when submitting work. To compensate for that, if the last
-// spinning thread finds work and stops spinning, it must unpark a new spinning
-// thread. This approach smooths out unjustified spikes of thread unparking,
-// but at the same time guarantees eventual maximal CPU parallelism
-// utilization.
-//
-// The main implementation complication is that we need to be very careful
-// during spinning->non-spinning thread transition. This transition can race
-// with submission of new work, and either one part or another needs to unpark
-// another worker thread. If they both fail to do that, we can end up with
-// semi-persistent CPU underutilization.
-//
-// The general pattern for submission is:
-// 1. Submit work to the local run queue, timer heap, or GC state.
-// 2. #StoreLoad-style memory barrier.
-// 3. Check sched.nmspinning.
-//
-// The general pattern for spinning->non-spinning transition is:
-// 1. Decrement nmspinning.
-// 2. #StoreLoad-style memory barrier.
-// 3. Check all per-P work queues and GC for new work.
-//
-// Note that all this complexity does not apply to global run queue as we are
-// not sloppy about thread unparking when submitting to global queue. Also see
-// comments for nmspinning manipulation.
-//
-// How these different sources of work behave varies, though it doesn't affect
-// the synchronization approach:
-// * Ready goroutine: this is an obvious source of work; the goroutine is
-// immediately ready and must run on some thread eventually.
-// * New/modified-earlier timer: The current timer implementation (see time.go)
-// uses netpoll in a thread with no work available to wait for the soonest
-// timer. If there is no thread waiting, we want a new spinning thread to go
-// wait.
-// * Idle-priority GC: The GC wakes a stopped idle thread to contribute to
-// background GC work (note: currently disabled per golang.org/issue/19112).
-// Also see golang.org/issue/44313, as this should be extended to all GC
-// workers.
-
-var (
- m0 m
- g0 g
- mcache0 *mcache
- raceprocctx0 uintptr
-)
-
-//go:linkname runtime_inittask runtime..inittask
-var runtime_inittask initTask
-
-//go:linkname main_inittask main..inittask
-var main_inittask initTask
-
-// main_init_done is a signal used by cgocallbackg that initialization
-// has been completed. It is made before _cgo_notify_runtime_init_done,
-// so all cgo calls can rely on it existing. When main_init is complete,
-// it is closed, meaning cgocallbackg can reliably receive from it.
-var main_init_done chan bool
-
-//go:linkname main_main main.main
-func main_main()
-
-// mainStarted indicates that the main M has started.
-var mainStarted bool
-
-// runtimeInitTime is the nanotime() at which the runtime started.
-var runtimeInitTime int64
-
-// Value to use for signal mask for newly created M's.
-var initSigmask sigset
-
-// The main goroutine.
-func main() {
- mp := getg().m
-
- // Racectx of m0->g0 is used only as the parent of the main goroutine.
- // It must not be used for anything else.
- mp.g0.racectx = 0
-
- // Max stack size is 1 GB on 64-bit, 250 MB on 32-bit.
- // Using decimal instead of binary GB and MB because
- // they look nicer in the stack overflow failure message.
- if goarch.PtrSize == 8 {
- maxstacksize = 1000000000
- } else {
- maxstacksize = 250000000
- }
-
- // An upper limit for max stack size. Used to avoid random crashes
- // after calling SetMaxStack and trying to allocate a stack that is too big,
- // since stackalloc works with 32-bit sizes.
- maxstackceiling = 2 * maxstacksize
-
- // Allow newproc to start new Ms.
- mainStarted = true
-
- if GOARCH != "wasm" { // no threads on wasm yet, so no sysmon
- systemstack(func() {
- newm(sysmon, nil, -1)
- })
- }
-
- // Lock the main goroutine onto this, the main OS thread,
- // during initialization. Most programs won't care, but a few
- // do require certain calls to be made by the main thread.
- // Those can arrange for main.main to run in the main thread
- // by calling runtime.LockOSThread during initialization
- // to preserve the lock.
- lockOSThread()
-
- if mp != &m0 {
- throw("runtime.main not on m0")
- }
-
- // Record when the world started.
- // Must be before doInit for tracing init.
- runtimeInitTime = nanotime()
- if runtimeInitTime == 0 {
- throw("nanotime returning zero")
- }
-
- if debug.inittrace != 0 {
- inittrace.id = getg().goid
- inittrace.active = true
- }
-
- doInit(&runtime_inittask) // Must be before defer.
-
- // Defer unlock so that runtime.Goexit during init does the unlock too.
- needUnlock := true
- defer func() {
- if needUnlock {
- unlockOSThread()
- }
- }()
-
- gcenable()
-
- main_init_done = make(chan bool)
- if iscgo {
- if _cgo_thread_start == nil {
- throw("_cgo_thread_start missing")
- }
- if GOOS != "windows" {
- if _cgo_setenv == nil {
- throw("_cgo_setenv missing")
- }
- if _cgo_unsetenv == nil {
- throw("_cgo_unsetenv missing")
- }
- }
- if _cgo_notify_runtime_init_done == nil {
- throw("_cgo_notify_runtime_init_done missing")
- }
- // Start the template thread in case we enter Go from
- // a C-created thread and need to create a new thread.
- startTemplateThread()
- cgocall(_cgo_notify_runtime_init_done, nil)
- }
-
- doInit(&main_inittask)
-
- // Disable init tracing after main init done to avoid overhead
- // of collecting statistics in malloc and newproc
- inittrace.active = false
-
- close(main_init_done)
-
- needUnlock = false
- unlockOSThread()
-
- if isarchive || islibrary {
- // A program compiled with -buildmode=c-archive or c-shared
- // has a main, but it is not executed.
- return
- }
- fn := main_main // make an indirect call, as the linker doesn't know the address of the main package when laying down the runtime
- fn()
- if raceenabled {
- runExitHooks(0) // run hooks now, since racefini does not return
- racefini()
- }
-
- // Make racy client program work: if panicking on
- // another goroutine at the same time as main returns,
- // let the other goroutine finish printing the panic trace.
- // Once it does, it will exit. See issues 3934 and 20018.
- if runningPanicDefers.Load() != 0 {
- // Running deferred functions should not take long.
- for c := 0; c < 1000; c++ {
- if runningPanicDefers.Load() == 0 {
- break
- }
- Gosched()
- }
- }
- if panicking.Load() != 0 {
- gopark(nil, nil, waitReasonPanicWait, traceEvGoStop, 1)
- }
- runExitHooks(0)
-
- exit(0)
- for {
- var x *int32
- *x = 0
- }
-}
-
-// os_beforeExit is called from os.Exit(0).
-//
-//go:linkname os_beforeExit os.runtime_beforeExit
-func os_beforeExit(exitCode int) {
- runExitHooks(exitCode)
- if exitCode == 0 && raceenabled {
- racefini()
- }
-}
-
-// start forcegc helper goroutine
-func init() {
- go forcegchelper()
-}
-
-func forcegchelper() {
- forcegc.g = getg()
- lockInit(&forcegc.lock, lockRankForcegc)
- for {
- lock(&forcegc.lock)
- if forcegc.idle.Load() {
- throw("forcegc: phase error")
- }
- forcegc.idle.Store(true)
- goparkunlock(&forcegc.lock, waitReasonForceGCIdle, traceEvGoBlock, 1)
- // this goroutine is explicitly resumed by sysmon
- if debug.gctrace > 0 {
- println("GC forced")
- }
- // Time-triggered, fully concurrent.
- gcStart(gcTrigger{kind: gcTriggerTime, now: nanotime()})
- }
-}
-
-//go:nosplit
-
-// Gosched yields the processor, allowing other goroutines to run. It does not
-// suspend the current goroutine, so execution resumes automatically.
-func Gosched() {
- checkTimeouts()
- mcall(gosched_m)
-}
-
-// goschedguarded yields the processor like gosched, but also checks
-// for forbidden states and opts out of the yield in those cases.
-//
-//go:nosplit
-func goschedguarded() {
- mcall(goschedguarded_m)
-}
-
-// goschedIfBusy yields the processor like gosched, but only does so if
-// there are no idle Ps or if we're on the only P and there's nothing in
-// the run queue. In both cases, there is freely available idle time.
-//
-//go:nosplit
-func goschedIfBusy() {
- gp := getg()
- // Call gosched if gp.preempt is set; we may be in a tight loop that
- // doesn't otherwise yield.
- if !gp.preempt && sched.npidle.Load() > 0 {
- return
- }
- mcall(gosched_m)
-}
-
-// Puts the current goroutine into a waiting state and calls unlockf on the
-// system stack.
-//
-// If unlockf returns false, the goroutine is resumed.
-//
-// unlockf must not access this G's stack, as it may be moved between
-// the call to gopark and the call to unlockf.
-//
-// Note that because unlockf is called after putting the G into a waiting
-// state, the G may have already been readied by the time unlockf is called
-// unless there is external synchronization preventing the G from being
-// readied. If unlockf returns false, it must guarantee that the G cannot be
-// externally readied.
-//
-// Reason explains why the goroutine has been parked. It is displayed in stack
-// traces and heap dumps. Reasons should be unique and descriptive. Do not
-// re-use reasons, add new ones.
-func gopark(unlockf func(*g, unsafe.Pointer) bool, lock unsafe.Pointer, reason waitReason, traceEv byte, traceskip int) {
- if reason != waitReasonSleep {
- checkTimeouts() // timeouts may expire while two goroutines keep the scheduler busy
- }
- mp := acquirem()
- gp := mp.curg
- status := readgstatus(gp)
- if status != _Grunning && status != _Gscanrunning {
- throw("gopark: bad g status")
- }
- mp.waitlock = lock
- mp.waitunlockf = unlockf
- gp.waitreason = reason
- mp.waittraceev = traceEv
- mp.waittraceskip = traceskip
- releasem(mp)
- // can't do anything that might move the G between Ms here.
- mcall(park_m)
-}
-
-// Puts the current goroutine into a waiting state and unlocks the lock.
-// The goroutine can be made runnable again by calling goready(gp).
-func goparkunlock(lock *mutex, reason waitReason, traceEv byte, traceskip int) {
- gopark(parkunlock_c, unsafe.Pointer(lock), reason, traceEv, traceskip)
-}
-
-func goready(gp *g, traceskip int) {
- systemstack(func() {
- ready(gp, traceskip, true)
- })
-}
-
-//go:nosplit
-func acquireSudog() *sudog {
- // Delicate dance: the semaphore implementation calls
- // acquireSudog, acquireSudog calls new(sudog),
- // new calls malloc, malloc can call the garbage collector,
- // and the garbage collector calls the semaphore implementation
- // in stopTheWorld.
- // Break the cycle by doing acquirem/releasem around new(sudog).
- // The acquirem/releasem increments m.locks during new(sudog),
- // which keeps the garbage collector from being invoked.
- mp := acquirem()
- pp := mp.p.ptr()
- if len(pp.sudogcache) == 0 {
- lock(&sched.sudoglock)
- // First, try to grab a batch from central cache.
- for len(pp.sudogcache) < cap(pp.sudogcache)/2 && sched.sudogcache != nil {
- s := sched.sudogcache
- sched.sudogcache = s.next
- s.next = nil
- pp.sudogcache = append(pp.sudogcache, s)
- }
- unlock(&sched.sudoglock)
- // If the central cache is empty, allocate a new one.
- if len(pp.sudogcache) == 0 {
- pp.sudogcache = append(pp.sudogcache, new(sudog))
- }
- }
- n := len(pp.sudogcache)
- s := pp.sudogcache[n-1]
- pp.sudogcache[n-1] = nil
- pp.sudogcache = pp.sudogcache[:n-1]
- if s.elem != nil {
- throw("acquireSudog: found s.elem != nil in cache")
- }
- releasem(mp)
- return s
-}
-
-//go:nosplit
-func releaseSudog(s *sudog) {
- if s.elem != nil {
- throw("runtime: sudog with non-nil elem")
- }
- if s.isSelect {
- throw("runtime: sudog with non-false isSelect")
- }
- if s.next != nil {
- throw("runtime: sudog with non-nil next")
- }
- if s.prev != nil {
- throw("runtime: sudog with non-nil prev")
- }
- if s.waitlink != nil {
- throw("runtime: sudog with non-nil waitlink")
- }
- if s.c != nil {
- throw("runtime: sudog with non-nil c")
- }
- gp := getg()
- if gp.param != nil {
- throw("runtime: releaseSudog with non-nil gp.param")
- }
- mp := acquirem() // avoid rescheduling to another P
- pp := mp.p.ptr()
- if len(pp.sudogcache) == cap(pp.sudogcache) {
- // Transfer half of local cache to the central cache.
- var first, last *sudog
- for len(pp.sudogcache) > cap(pp.sudogcache)/2 {
- n := len(pp.sudogcache)
- p := pp.sudogcache[n-1]
- pp.sudogcache[n-1] = nil
- pp.sudogcache = pp.sudogcache[:n-1]
- if first == nil {
- first = p
- } else {
- last.next = p
- }
- last = p
- }
- lock(&sched.sudoglock)
- last.next = sched.sudogcache
- sched.sudogcache = first
- unlock(&sched.sudoglock)
- }
- pp.sudogcache = append(pp.sudogcache, s)
- releasem(mp)
-}
-
-// called from assembly.
-func badmcall(fn func(*g)) {
- throw("runtime: mcall called on m->g0 stack")
-}
-
-func badmcall2(fn func(*g)) {
- throw("runtime: mcall function returned")
-}
-
-func badreflectcall() {
- panic(plainError("arg size to reflect.call more than 1GB"))
-}
-
-//go:nosplit
-//go:nowritebarrierrec
-func badmorestackg0() {
- writeErrStr("fatal: morestack on g0\n")
-}
-
-//go:nosplit
-//go:nowritebarrierrec
-func badmorestackgsignal() {
- writeErrStr("fatal: morestack on gsignal\n")
-}
-
-//go:nosplit
-func badctxt() {
- throw("ctxt != 0")
-}
-
-func lockedOSThread() bool {
- gp := getg()
- return gp.lockedm != 0 && gp.m.lockedg != 0
-}
-
-var (
- // allgs contains all Gs ever created (including dead Gs), and thus
- // never shrinks.
- //
- // Access via the slice is protected by allglock or stop-the-world.
- // Readers that cannot take the lock may (carefully!) use the atomic
- // variables below.
- allglock mutex
- allgs []*g
-
- // allglen and allgptr are atomic variables that contain len(allgs) and
- // &allgs[0] respectively. Proper ordering depends on totally-ordered
- // loads and stores. Writes are protected by allglock.
- //
- // allgptr is updated before allglen. Readers should read allglen
- // before allgptr to ensure that allglen is always <= len(allgptr). New
- // Gs appended during the race can be missed. For a consistent view of
- // all Gs, allglock must be held.
- //
- // allgptr copies should always be stored as a concrete type or
- // unsafe.Pointer, not uintptr, to ensure that GC can still reach it
- // even if it points to a stale array.
- allglen uintptr
- allgptr **g
-)
-
-func allgadd(gp *g) {
- if readgstatus(gp) == _Gidle {
- throw("allgadd: bad status Gidle")
- }
-
- lock(&allglock)
- allgs = append(allgs, gp)
- if &allgs[0] != allgptr {
- atomicstorep(unsafe.Pointer(&allgptr), unsafe.Pointer(&allgs[0]))
- }
- atomic.Storeuintptr(&allglen, uintptr(len(allgs)))
- unlock(&allglock)
-}
-
-// allGsSnapshot returns a snapshot of the slice of all Gs.
-//
-// The world must be stopped or allglock must be held.
-func allGsSnapshot() []*g {
- assertWorldStoppedOrLockHeld(&allglock)
-
- // Because the world is stopped or allglock is held, allgadd
- // cannot happen concurrently with this. allgs grows
- // monotonically and existing entries never change, so we can
- // simply return a copy of the slice header. For added safety,
- // we trim everything past len because that can still change.
- return allgs[:len(allgs):len(allgs)]
-}
-
-// atomicAllG returns &allgs[0] and len(allgs) for use with atomicAllGIndex.
-func atomicAllG() (**g, uintptr) {
- length := atomic.Loaduintptr(&allglen)
- ptr := (**g)(atomic.Loadp(unsafe.Pointer(&allgptr)))
- return ptr, length
-}
-
-// atomicAllGIndex returns ptr[i] with the allgptr returned from atomicAllG.
-func atomicAllGIndex(ptr **g, i uintptr) *g {
- return *(**g)(add(unsafe.Pointer(ptr), i*goarch.PtrSize))
-}
-
-// forEachG calls fn on every G from allgs.
-//
-// forEachG takes a lock to exclude concurrent addition of new Gs.
-func forEachG(fn func(gp *g)) {
- lock(&allglock)
- for _, gp := range allgs {
- fn(gp)
- }
- unlock(&allglock)
-}
-
-// forEachGRace calls fn on every G from allgs.
-//
-// forEachGRace avoids locking, but does not exclude addition of new Gs during
-// execution, which may be missed.
-func forEachGRace(fn func(gp *g)) {
- ptr, length := atomicAllG()
- for i := uintptr(0); i < length; i++ {
- gp := atomicAllGIndex(ptr, i)
- fn(gp)
- }
- return
-}
-
-const (
- // Number of goroutine ids to grab from sched.goidgen to local per-P cache at once.
- // 16 seems to provide enough amortization, but other than that it's mostly arbitrary number.
- _GoidCacheBatch = 16
-)
-
-// cpuinit sets up CPU feature flags and calls internal/cpu.Initialize. env should be the complete
-// value of the GODEBUG environment variable.
-func cpuinit(env string) {
- switch GOOS {
- case "aix", "darwin", "ios", "dragonfly", "freebsd", "netbsd", "openbsd", "illumos", "solaris", "linux":
- cpu.DebugOptions = true
- }
- cpu.Initialize(env)
-
- // Support cpu feature variables are used in code generated by the compiler
- // to guard execution of instructions that can not be assumed to be always supported.
- switch GOARCH {
- case "386", "amd64":
- x86HasPOPCNT = cpu.X86.HasPOPCNT
- x86HasSSE41 = cpu.X86.HasSSE41
- x86HasFMA = cpu.X86.HasFMA
-
- case "arm":
- armHasVFPv4 = cpu.ARM.HasVFPv4
-
- case "arm64":
- arm64HasATOMICS = cpu.ARM64.HasATOMICS
- }
-}
-
-// getGodebugEarly extracts the environment variable GODEBUG from the environment on
-// Unix-like operating systems and returns it. This function exists to extract GODEBUG
-// early before much of the runtime is initialized.
-func getGodebugEarly() string {
- const prefix = "GODEBUG="
- var env string
- switch GOOS {
- case "aix", "darwin", "ios", "dragonfly", "freebsd", "netbsd", "openbsd", "illumos", "solaris", "linux":
- // Similar to goenv_unix but extracts the environment value for
- // GODEBUG directly.
- // TODO(moehrmann): remove when general goenvs() can be called before cpuinit()
- n := int32(0)
- for argv_index(argv, argc+1+n) != nil {
- n++
- }
-
- for i := int32(0); i < n; i++ {
- p := argv_index(argv, argc+1+i)
- s := unsafe.String(p, findnull(p))
-
- if hasPrefix(s, prefix) {
- env = gostring(p)[len(prefix):]
- break
- }
- }
- }
- return env
-}
-
-// The bootstrap sequence is:
-//
-// call osinit
-// call schedinit
-// make & queue new G
-// call runtime·mstart
-//
-// The new G calls runtime·main.
-func schedinit() {
- lockInit(&sched.lock, lockRankSched)
- lockInit(&sched.sysmonlock, lockRankSysmon)
- lockInit(&sched.deferlock, lockRankDefer)
- lockInit(&sched.sudoglock, lockRankSudog)
- lockInit(&deadlock, lockRankDeadlock)
- lockInit(&paniclk, lockRankPanic)
- lockInit(&allglock, lockRankAllg)
- lockInit(&allpLock, lockRankAllp)
- lockInit(&reflectOffs.lock, lockRankReflectOffs)
- lockInit(&finlock, lockRankFin)
- lockInit(&trace.bufLock, lockRankTraceBuf)
- lockInit(&trace.stringsLock, lockRankTraceStrings)
- lockInit(&trace.lock, lockRankTrace)
- lockInit(&cpuprof.lock, lockRankCpuprof)
- lockInit(&trace.stackTab.lock, lockRankTraceStackTab)
- // Enforce that this lock is always a leaf lock.
- // All of this lock's critical sections should be
- // extremely short.
- lockInit(&memstats.heapStats.noPLock, lockRankLeafRank)
-
- // raceinit must be the first call to race detector.
- // In particular, it must be done before mallocinit below calls racemapshadow.
- gp := getg()
- if raceenabled {
- gp.racectx, raceprocctx0 = raceinit()
- }
-
- sched.maxmcount = 10000
-
- // The world starts stopped.
- worldStopped()
-
- moduledataverify()
- stackinit()
- mallocinit()
- godebug := getGodebugEarly()
- initPageTrace(godebug) // must run after mallocinit but before anything allocates
- cpuinit(godebug) // must run before alginit
- alginit() // maps, hash, fastrand must not be used before this call
- fastrandinit() // must run before mcommoninit
- mcommoninit(gp.m, -1)
- modulesinit() // provides activeModules
- typelinksinit() // uses maps, activeModules
- itabsinit() // uses activeModules
- stkobjinit() // must run before GC starts
-
- sigsave(&gp.m.sigmask)
- initSigmask = gp.m.sigmask
-
- goargs()
- goenvs()
- secure()
- parsedebugvars()
- gcinit()
-
- // if disableMemoryProfiling is set, update MemProfileRate to 0 to turn off memprofile.
- // Note: parsedebugvars may update MemProfileRate, but when disableMemoryProfiling is
- // set to true by the linker, it means that nothing is consuming the profile, it is
- // safe to set MemProfileRate to 0.
- if disableMemoryProfiling {
- MemProfileRate = 0
- }
-
- lock(&sched.lock)
- sched.lastpoll.Store(nanotime())
- procs := ncpu
- if n, ok := atoi32(gogetenv("GOMAXPROCS")); ok && n > 0 {
- procs = n
- }
- if procresize(procs) != nil {
- throw("unknown runnable goroutine during bootstrap")
- }
- unlock(&sched.lock)
-
- // World is effectively started now, as P's can run.
- worldStarted()
-
- // For cgocheck > 1, we turn on the write barrier at all times
- // and check all pointer writes. We can't do this until after
- // procresize because the write barrier needs a P.
- if debug.cgocheck > 1 {
- writeBarrier.cgo = true
- writeBarrier.enabled = true
- for _, pp := range allp {
- pp.wbBuf.reset()
- }
- }
-
- if buildVersion == "" {
- // Condition should never trigger. This code just serves
- // to ensure runtime·buildVersion is kept in the resulting binary.
- buildVersion = "unknown"
- }
- if len(modinfo) == 1 {
- // Condition should never trigger. This code just serves
- // to ensure runtime·modinfo is kept in the resulting binary.
- modinfo = ""
- }
-}
-
-func dumpgstatus(gp *g) {
- thisg := getg()
- print("runtime: gp: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n")
- print("runtime: getg: g=", thisg, ", goid=", thisg.goid, ", g->atomicstatus=", readgstatus(thisg), "\n")
-}
-
-// sched.lock must be held.
-func checkmcount() {
- assertLockHeld(&sched.lock)
-
- if mcount() > sched.maxmcount {
- print("runtime: program exceeds ", sched.maxmcount, "-thread limit\n")
- throw("thread exhaustion")
- }
-}
-
-// mReserveID returns the next ID to use for a new m. This new m is immediately
-// considered 'running' by checkdead.
-//
-// sched.lock must be held.
-func mReserveID() int64 {
- assertLockHeld(&sched.lock)
-
- if sched.mnext+1 < sched.mnext {
- throw("runtime: thread ID overflow")
- }
- id := sched.mnext
- sched.mnext++
- checkmcount()
- return id
-}
-
-// Pre-allocated ID may be passed as 'id', or omitted by passing -1.
-func mcommoninit(mp *m, id int64) {
- gp := getg()
-
- // g0 stack won't make sense for user (and is not necessary unwindable).
- if gp != gp.m.g0 {
- callers(1, mp.createstack[:])
- }
-
- lock(&sched.lock)
-
- if id >= 0 {
- mp.id = id
- } else {
- mp.id = mReserveID()
- }
-
- lo := uint32(int64Hash(uint64(mp.id), fastrandseed))
- hi := uint32(int64Hash(uint64(cputicks()), ^fastrandseed))
- if lo|hi == 0 {
- hi = 1
- }
- // Same behavior as for 1.17.
- // TODO: Simplify ths.
- if goarch.BigEndian {
- mp.fastrand = uint64(lo)<<32 | uint64(hi)
- } else {
- mp.fastrand = uint64(hi)<<32 | uint64(lo)
- }
-
- mpreinit(mp)
- if mp.gsignal != nil {
- mp.gsignal.stackguard1 = mp.gsignal.stack.lo + _StackGuard
- }
-
- // Add to allm so garbage collector doesn't free g->m
- // when it is just in a register or thread-local storage.
- mp.alllink = allm
-
- // NumCgoCall() iterates over allm w/o schedlock,
- // so we need to publish it safely.
- atomicstorep(unsafe.Pointer(&allm), unsafe.Pointer(mp))
- unlock(&sched.lock)
-
- // Allocate memory to hold a cgo traceback if the cgo call crashes.
- if iscgo || GOOS == "solaris" || GOOS == "illumos" || GOOS == "windows" {
- mp.cgoCallers = new(cgoCallers)
- }
-}
-
-func (mp *m) becomeSpinning() {
- mp.spinning = true
- sched.nmspinning.Add(1)
- sched.needspinning.Store(0)
-}
-
-var fastrandseed uintptr
-
-func fastrandinit() {
- s := (*[unsafe.Sizeof(fastrandseed)]byte)(unsafe.Pointer(&fastrandseed))[:]
- getRandomData(s)
-}
-
-// Mark gp ready to run.
-func ready(gp *g, traceskip int, next bool) {
- if trace.enabled {
- traceGoUnpark(gp, traceskip)
- }
-
- status := readgstatus(gp)
-
- // Mark runnable.
- mp := acquirem() // disable preemption because it can be holding p in a local var
- if status&^_Gscan != _Gwaiting {
- dumpgstatus(gp)
- throw("bad g->status in ready")
- }
-
- // status is Gwaiting or Gscanwaiting, make Grunnable and put on runq
- casgstatus(gp, _Gwaiting, _Grunnable)
- runqput(mp.p.ptr(), gp, next)
- wakep()
- releasem(mp)
-}
-
-// freezeStopWait is a large value that freezetheworld sets
-// sched.stopwait to in order to request that all Gs permanently stop.
-const freezeStopWait = 0x7fffffff
-
-// freezing is set to non-zero if the runtime is trying to freeze the
-// world.
-var freezing atomic.Bool
-
-// Similar to stopTheWorld but best-effort and can be called several times.
-// There is no reverse operation, used during crashing.
-// This function must not lock any mutexes.
-func freezetheworld() {
- freezing.Store(true)
- // stopwait and preemption requests can be lost
- // due to races with concurrently executing threads,
- // so try several times
- for i := 0; i < 5; i++ {
- // this should tell the scheduler to not start any new goroutines
- sched.stopwait = freezeStopWait
- sched.gcwaiting.Store(true)
- // this should stop running goroutines
- if !preemptall() {
- break // no running goroutines
- }
- usleep(1000)
- }
- // to be sure
- usleep(1000)
- preemptall()
- usleep(1000)
-}
-
-// All reads and writes of g's status go through readgstatus, casgstatus
-// castogscanstatus, casfrom_Gscanstatus.
-//
-//go:nosplit
-func readgstatus(gp *g) uint32 {
- return gp.atomicstatus.Load()
-}
-
-// The Gscanstatuses are acting like locks and this releases them.
-// If it proves to be a performance hit we should be able to make these
-// simple atomic stores but for now we are going to throw if
-// we see an inconsistent state.
-func casfrom_Gscanstatus(gp *g, oldval, newval uint32) {
- success := false
-
- // Check that transition is valid.
- switch oldval {
- default:
- print("runtime: casfrom_Gscanstatus bad oldval gp=", gp, ", oldval=", hex(oldval), ", newval=", hex(newval), "\n")
- dumpgstatus(gp)
- throw("casfrom_Gscanstatus:top gp->status is not in scan state")
- case _Gscanrunnable,
- _Gscanwaiting,
- _Gscanrunning,
- _Gscansyscall,
- _Gscanpreempted:
- if newval == oldval&^_Gscan {
- success = gp.atomicstatus.CompareAndSwap(oldval, newval)
- }
- }
- if !success {
- print("runtime: casfrom_Gscanstatus failed gp=", gp, ", oldval=", hex(oldval), ", newval=", hex(newval), "\n")
- dumpgstatus(gp)
- throw("casfrom_Gscanstatus: gp->status is not in scan state")
- }
- releaseLockRank(lockRankGscan)
-}
-
-// This will return false if the gp is not in the expected status and the cas fails.
-// This acts like a lock acquire while the casfromgstatus acts like a lock release.
-func castogscanstatus(gp *g, oldval, newval uint32) bool {
- switch oldval {
- case _Grunnable,
- _Grunning,
- _Gwaiting,
- _Gsyscall:
- if newval == oldval|_Gscan {
- r := gp.atomicstatus.CompareAndSwap(oldval, newval)
- if r {
- acquireLockRank(lockRankGscan)
- }
- return r
-
- }
- }
- print("runtime: castogscanstatus oldval=", hex(oldval), " newval=", hex(newval), "\n")
- throw("castogscanstatus")
- panic("not reached")
-}
-
-// casgstatusAlwaysTrack is a debug flag that causes casgstatus to always track
-// various latencies on every transition instead of sampling them.
-var casgstatusAlwaysTrack = false
-
-// If asked to move to or from a Gscanstatus this will throw. Use the castogscanstatus
-// and casfrom_Gscanstatus instead.
-// casgstatus will loop if the g->atomicstatus is in a Gscan status until the routine that
-// put it in the Gscan state is finished.
-//
-//go:nosplit
-func casgstatus(gp *g, oldval, newval uint32) {
- if (oldval&_Gscan != 0) || (newval&_Gscan != 0) || oldval == newval {
- systemstack(func() {
- print("runtime: casgstatus: oldval=", hex(oldval), " newval=", hex(newval), "\n")
- throw("casgstatus: bad incoming values")
- })
- }
-
- acquireLockRank(lockRankGscan)
- releaseLockRank(lockRankGscan)
-
- // See https://golang.org/cl/21503 for justification of the yield delay.
- const yieldDelay = 5 * 1000
- var nextYield int64
-
- // loop if gp->atomicstatus is in a scan state giving
- // GC time to finish and change the state to oldval.
- for i := 0; !gp.atomicstatus.CompareAndSwap(oldval, newval); i++ {
- if oldval == _Gwaiting && gp.atomicstatus.Load() == _Grunnable {
- throw("casgstatus: waiting for Gwaiting but is Grunnable")
- }
- if i == 0 {
- nextYield = nanotime() + yieldDelay
- }
- if nanotime() < nextYield {
- for x := 0; x < 10 && gp.atomicstatus.Load() != oldval; x++ {
- procyield(1)
- }
- } else {
- osyield()
- nextYield = nanotime() + yieldDelay/2
- }
- }
-
- if oldval == _Grunning {
- // Track every gTrackingPeriod time a goroutine transitions out of running.
- if casgstatusAlwaysTrack || gp.trackingSeq%gTrackingPeriod == 0 {
- gp.tracking = true
- }
- gp.trackingSeq++
- }
- if !gp.tracking {
- return
- }
-
- // Handle various kinds of tracking.
- //
- // Currently:
- // - Time spent in runnable.
- // - Time spent blocked on a sync.Mutex or sync.RWMutex.
- switch oldval {
- case _Grunnable:
- // We transitioned out of runnable, so measure how much
- // time we spent in this state and add it to
- // runnableTime.
- now := nanotime()
- gp.runnableTime += now - gp.trackingStamp
- gp.trackingStamp = 0
- case _Gwaiting:
- if !gp.waitreason.isMutexWait() {
- // Not blocking on a lock.
- break
- }
- // Blocking on a lock, measure it. Note that because we're
- // sampling, we have to multiply by our sampling period to get
- // a more representative estimate of the absolute value.
- // gTrackingPeriod also represents an accurate sampling period
- // because we can only enter this state from _Grunning.
- now := nanotime()
- sched.totalMutexWaitTime.Add((now - gp.trackingStamp) * gTrackingPeriod)
- gp.trackingStamp = 0
- }
- switch newval {
- case _Gwaiting:
- if !gp.waitreason.isMutexWait() {
- // Not blocking on a lock.
- break
- }
- // Blocking on a lock. Write down the timestamp.
- now := nanotime()
- gp.trackingStamp = now
- case _Grunnable:
- // We just transitioned into runnable, so record what
- // time that happened.
- now := nanotime()
- gp.trackingStamp = now
- case _Grunning:
- // We're transitioning into running, so turn off
- // tracking and record how much time we spent in
- // runnable.
- gp.tracking = false
- sched.timeToRun.record(gp.runnableTime)
- gp.runnableTime = 0
- }
-}
-
-// casGToWaiting transitions gp from old to _Gwaiting, and sets the wait reason.
-//
-// Use this over casgstatus when possible to ensure that a waitreason is set.
-func casGToWaiting(gp *g, old uint32, reason waitReason) {
- // Set the wait reason before calling casgstatus, because casgstatus will use it.
- gp.waitreason = reason
- casgstatus(gp, old, _Gwaiting)
-}
-
-// casgstatus(gp, oldstatus, Gcopystack), assuming oldstatus is Gwaiting or Grunnable.
-// Returns old status. Cannot call casgstatus directly, because we are racing with an
-// async wakeup that might come in from netpoll. If we see Gwaiting from the readgstatus,
-// it might have become Grunnable by the time we get to the cas. If we called casgstatus,
-// it would loop waiting for the status to go back to Gwaiting, which it never will.
-//
-//go:nosplit
-func casgcopystack(gp *g) uint32 {
- for {
- oldstatus := readgstatus(gp) &^ _Gscan
- if oldstatus != _Gwaiting && oldstatus != _Grunnable {
- throw("copystack: bad status, not Gwaiting or Grunnable")
- }
- if gp.atomicstatus.CompareAndSwap(oldstatus, _Gcopystack) {
- return oldstatus
- }
- }
-}
-
-// casGToPreemptScan transitions gp from _Grunning to _Gscan|_Gpreempted.
-//
-// TODO(austin): This is the only status operation that both changes
-// the status and locks the _Gscan bit. Rethink this.
-func casGToPreemptScan(gp *g, old, new uint32) {
- if old != _Grunning || new != _Gscan|_Gpreempted {
- throw("bad g transition")
- }
- acquireLockRank(lockRankGscan)
- for !gp.atomicstatus.CompareAndSwap(_Grunning, _Gscan|_Gpreempted) {
- }
-}
-
-// casGFromPreempted attempts to transition gp from _Gpreempted to
-// _Gwaiting. If successful, the caller is responsible for
-// re-scheduling gp.
-func casGFromPreempted(gp *g, old, new uint32) bool {
- if old != _Gpreempted || new != _Gwaiting {
- throw("bad g transition")
- }
- gp.waitreason = waitReasonPreempted
- return gp.atomicstatus.CompareAndSwap(_Gpreempted, _Gwaiting)
-}
-
-// stopTheWorld stops all P's from executing goroutines, interrupting
-// all goroutines at GC safe points and records reason as the reason
-// for the stop. On return, only the current goroutine's P is running.
-// stopTheWorld must not be called from a system stack and the caller
-// must not hold worldsema. The caller must call startTheWorld when
-// other P's should resume execution.
-//
-// stopTheWorld is safe for multiple goroutines to call at the
-// same time. Each will execute its own stop, and the stops will
-// be serialized.
-//
-// This is also used by routines that do stack dumps. If the system is
-// in panic or being exited, this may not reliably stop all
-// goroutines.
-func stopTheWorld(reason string) {
- semacquire(&worldsema)
- gp := getg()
- gp.m.preemptoff = reason
- systemstack(func() {
- // Mark the goroutine which called stopTheWorld preemptible so its
- // stack may be scanned.
- // This lets a mark worker scan us while we try to stop the world
- // since otherwise we could get in a mutual preemption deadlock.
- // We must not modify anything on the G stack because a stack shrink
- // may occur. A stack shrink is otherwise OK though because in order
- // to return from this function (and to leave the system stack) we
- // must have preempted all goroutines, including any attempting
- // to scan our stack, in which case, any stack shrinking will
- // have already completed by the time we exit.
- // Don't provide a wait reason because we're still executing.
- casGToWaiting(gp, _Grunning, waitReasonStoppingTheWorld)
- stopTheWorldWithSema()
- casgstatus(gp, _Gwaiting, _Grunning)
- })
-}
-
-// startTheWorld undoes the effects of stopTheWorld.
-func startTheWorld() {
- systemstack(func() { startTheWorldWithSema(false) })
-
- // worldsema must be held over startTheWorldWithSema to ensure
- // gomaxprocs cannot change while worldsema is held.
- //
- // Release worldsema with direct handoff to the next waiter, but
- // acquirem so that semrelease1 doesn't try to yield our time.
- //
- // Otherwise if e.g. ReadMemStats is being called in a loop,
- // it might stomp on other attempts to stop the world, such as
- // for starting or ending GC. The operation this blocks is
- // so heavy-weight that we should just try to be as fair as
- // possible here.
- //
- // We don't want to just allow us to get preempted between now
- // and releasing the semaphore because then we keep everyone
- // (including, for example, GCs) waiting longer.
- mp := acquirem()
- mp.preemptoff = ""
- semrelease1(&worldsema, true, 0)
- releasem(mp)
-}
-
-// stopTheWorldGC has the same effect as stopTheWorld, but blocks
-// until the GC is not running. It also blocks a GC from starting
-// until startTheWorldGC is called.
-func stopTheWorldGC(reason string) {
- semacquire(&gcsema)
- stopTheWorld(reason)
-}
-
-// startTheWorldGC undoes the effects of stopTheWorldGC.
-func startTheWorldGC() {
- startTheWorld()
- semrelease(&gcsema)
-}
-
-// Holding worldsema grants an M the right to try to stop the world.
-var worldsema uint32 = 1
-
-// Holding gcsema grants the M the right to block a GC, and blocks
-// until the current GC is done. In particular, it prevents gomaxprocs
-// from changing concurrently.
-//
-// TODO(mknyszek): Once gomaxprocs and the execution tracer can handle
-// being changed/enabled during a GC, remove this.
-var gcsema uint32 = 1
-
-// stopTheWorldWithSema is the core implementation of stopTheWorld.
-// The caller is responsible for acquiring worldsema and disabling
-// preemption first and then should stopTheWorldWithSema on the system
-// stack:
-//
-// semacquire(&worldsema, 0)
-// m.preemptoff = "reason"
-// systemstack(stopTheWorldWithSema)
-//
-// When finished, the caller must either call startTheWorld or undo
-// these three operations separately:
-//
-// m.preemptoff = ""
-// systemstack(startTheWorldWithSema)
-// semrelease(&worldsema)
-//
-// It is allowed to acquire worldsema once and then execute multiple
-// startTheWorldWithSema/stopTheWorldWithSema pairs.
-// Other P's are able to execute between successive calls to
-// startTheWorldWithSema and stopTheWorldWithSema.
-// Holding worldsema causes any other goroutines invoking
-// stopTheWorld to block.
-func stopTheWorldWithSema() {
- gp := getg()
-
- // If we hold a lock, then we won't be able to stop another M
- // that is blocked trying to acquire the lock.
- if gp.m.locks > 0 {
- throw("stopTheWorld: holding locks")
- }
-
- lock(&sched.lock)
- sched.stopwait = gomaxprocs
- sched.gcwaiting.Store(true)
- preemptall()
- // stop current P
- gp.m.p.ptr().status = _Pgcstop // Pgcstop is only diagnostic.
- sched.stopwait--
- // try to retake all P's in Psyscall status
- for _, pp := range allp {
- s := pp.status
- if s == _Psyscall && atomic.Cas(&pp.status, s, _Pgcstop) {
- if trace.enabled {
- traceGoSysBlock(pp)
- traceProcStop(pp)
- }
- pp.syscalltick++
- sched.stopwait--
- }
- }
- // stop idle P's
- now := nanotime()
- for {
- pp, _ := pidleget(now)
- if pp == nil {
- break
- }
- pp.status = _Pgcstop
- sched.stopwait--
- }
- wait := sched.stopwait > 0
- unlock(&sched.lock)
-
- // wait for remaining P's to stop voluntarily
- if wait {
- for {
- // wait for 100us, then try to re-preempt in case of any races
- if notetsleep(&sched.stopnote, 100*1000) {
- noteclear(&sched.stopnote)
- break
- }
- preemptall()
- }
- }
-
- // sanity checks
- bad := ""
- if sched.stopwait != 0 {
- bad = "stopTheWorld: not stopped (stopwait != 0)"
- } else {
- for _, pp := range allp {
- if pp.status != _Pgcstop {
- bad = "stopTheWorld: not stopped (status != _Pgcstop)"
- }
- }
- }
- if freezing.Load() {
- // Some other thread is panicking. This can cause the
- // sanity checks above to fail if the panic happens in
- // the signal handler on a stopped thread. Either way,
- // we should halt this thread.
- lock(&deadlock)
- lock(&deadlock)
- }
- if bad != "" {
- throw(bad)
- }
-
- worldStopped()
-}
-
-func startTheWorldWithSema(emitTraceEvent bool) int64 {
- assertWorldStopped()
-
- mp := acquirem() // disable preemption because it can be holding p in a local var
- if netpollinited() {
- list := netpoll(0) // non-blocking
- injectglist(&list)
- }
- lock(&sched.lock)
-
- procs := gomaxprocs
- if newprocs != 0 {
- procs = newprocs
- newprocs = 0
- }
- p1 := procresize(procs)
- sched.gcwaiting.Store(false)
- if sched.sysmonwait.Load() {
- sched.sysmonwait.Store(false)
- notewakeup(&sched.sysmonnote)
- }
- unlock(&sched.lock)
-
- worldStarted()
-
- for p1 != nil {
- p := p1
- p1 = p1.link.ptr()
- if p.m != 0 {
- mp := p.m.ptr()
- p.m = 0
- if mp.nextp != 0 {
- throw("startTheWorld: inconsistent mp->nextp")
- }
- mp.nextp.set(p)
- notewakeup(&mp.park)
- } else {
- // Start M to run P. Do not start another M below.
- newm(nil, p, -1)
- }
- }
-
- // Capture start-the-world time before doing clean-up tasks.
- startTime := nanotime()
- if emitTraceEvent {
- traceGCSTWDone()
- }
-
- // Wakeup an additional proc in case we have excessive runnable goroutines
- // in local queues or in the global queue. If we don't, the proc will park itself.
- // If we have lots of excessive work, resetspinning will unpark additional procs as necessary.
- wakep()
-
- releasem(mp)
-
- return startTime
-}
-
-// usesLibcall indicates whether this runtime performs system calls
-// via libcall.
-func usesLibcall() bool {
- switch GOOS {
- case "aix", "darwin", "illumos", "ios", "solaris", "windows":
- return true
- case "openbsd":
- return GOARCH == "386" || GOARCH == "amd64" || GOARCH == "arm" || GOARCH == "arm64"
- }
- return false
-}
-
-// mStackIsSystemAllocated indicates whether this runtime starts on a
-// system-allocated stack.
-func mStackIsSystemAllocated() bool {
- switch GOOS {
- case "aix", "darwin", "plan9", "illumos", "ios", "solaris", "windows":
- return true
- case "openbsd":
- switch GOARCH {
- case "386", "amd64", "arm", "arm64":
- return true
- }
- }
- return false
-}
-
-// mstart is the entry-point for new Ms.
-// It is written in assembly, uses ABI0, is marked TOPFRAME, and calls mstart0.
-func mstart()
-
-// mstart0 is the Go entry-point for new Ms.
-// This must not split the stack because we may not even have stack
-// bounds set up yet.
-//
-// May run during STW (because it doesn't have a P yet), so write
-// barriers are not allowed.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func mstart0() {
- gp := getg()
-
- osStack := gp.stack.lo == 0
- if osStack {
- // Initialize stack bounds from system stack.
- // Cgo may have left stack size in stack.hi.
- // minit may update the stack bounds.
- //
- // Note: these bounds may not be very accurate.
- // We set hi to &size, but there are things above
- // it. The 1024 is supposed to compensate this,
- // but is somewhat arbitrary.
- size := gp.stack.hi
- if size == 0 {
- size = 8192 * sys.StackGuardMultiplier
- }
- gp.stack.hi = uintptr(noescape(unsafe.Pointer(&size)))
- gp.stack.lo = gp.stack.hi - size + 1024
- }
- // Initialize stack guard so that we can start calling regular
- // Go code.
- gp.stackguard0 = gp.stack.lo + _StackGuard
- // This is the g0, so we can also call go:systemstack
- // functions, which check stackguard1.
- gp.stackguard1 = gp.stackguard0
- mstart1()
-
- // Exit this thread.
- if mStackIsSystemAllocated() {
- // Windows, Solaris, illumos, Darwin, AIX and Plan 9 always system-allocate
- // the stack, but put it in gp.stack before mstart,
- // so the logic above hasn't set osStack yet.
- osStack = true
- }
- mexit(osStack)
-}
-
-// The go:noinline is to guarantee the getcallerpc/getcallersp below are safe,
-// so that we can set up g0.sched to return to the call of mstart1 above.
-//
-//go:noinline
-func mstart1() {
- gp := getg()
-
- if gp != gp.m.g0 {
- throw("bad runtime·mstart")
- }
-
- // Set up m.g0.sched as a label returning to just
- // after the mstart1 call in mstart0 above, for use by goexit0 and mcall.
- // We're never coming back to mstart1 after we call schedule,
- // so other calls can reuse the current frame.
- // And goexit0 does a gogo that needs to return from mstart1
- // and let mstart0 exit the thread.
- gp.sched.g = guintptr(unsafe.Pointer(gp))
- gp.sched.pc = getcallerpc()
- gp.sched.sp = getcallersp()
-
- asminit()
- minit()
-
- // Install signal handlers; after minit so that minit can
- // prepare the thread to be able to handle the signals.
- if gp.m == &m0 {
- mstartm0()
- }
-
- if fn := gp.m.mstartfn; fn != nil {
- fn()
- }
-
- if gp.m != &m0 {
- acquirep(gp.m.nextp.ptr())
- gp.m.nextp = 0
- }
- schedule()
-}
-
-// mstartm0 implements part of mstart1 that only runs on the m0.
-//
-// Write barriers are allowed here because we know the GC can't be
-// running yet, so they'll be no-ops.
-//
-//go:yeswritebarrierrec
-func mstartm0() {
- // Create an extra M for callbacks on threads not created by Go.
- // An extra M is also needed on Windows for callbacks created by
- // syscall.NewCallback. See issue #6751 for details.
- if (iscgo || GOOS == "windows") && !cgoHasExtraM {
- cgoHasExtraM = true
- newextram()
- }
- initsig(false)
-}
-
-// mPark causes a thread to park itself, returning once woken.
-//
-//go:nosplit
-func mPark() {
- gp := getg()
- notesleep(&gp.m.park)
- noteclear(&gp.m.park)
-}
-
-// mexit tears down and exits the current thread.
-//
-// Don't call this directly to exit the thread, since it must run at
-// the top of the thread stack. Instead, use gogo(&gp.m.g0.sched) to
-// unwind the stack to the point that exits the thread.
-//
-// It is entered with m.p != nil, so write barriers are allowed. It
-// will release the P before exiting.
-//
-//go:yeswritebarrierrec
-func mexit(osStack bool) {
- mp := getg().m
-
- if mp == &m0 {
- // This is the main thread. Just wedge it.
- //
- // On Linux, exiting the main thread puts the process
- // into a non-waitable zombie state. On Plan 9,
- // exiting the main thread unblocks wait even though
- // other threads are still running. On Solaris we can
- // neither exitThread nor return from mstart. Other
- // bad things probably happen on other platforms.
- //
- // We could try to clean up this M more before wedging
- // it, but that complicates signal handling.
- handoffp(releasep())
- lock(&sched.lock)
- sched.nmfreed++
- checkdead()
- unlock(&sched.lock)
- mPark()
- throw("locked m0 woke up")
- }
-
- sigblock(true)
- unminit()
-
- // Free the gsignal stack.
- if mp.gsignal != nil {
- stackfree(mp.gsignal.stack)
- // On some platforms, when calling into VDSO (e.g. nanotime)
- // we store our g on the gsignal stack, if there is one.
- // Now the stack is freed, unlink it from the m, so we
- // won't write to it when calling VDSO code.
- mp.gsignal = nil
- }
-
- // Remove m from allm.
- lock(&sched.lock)
- for pprev := &allm; *pprev != nil; pprev = &(*pprev).alllink {
- if *pprev == mp {
- *pprev = mp.alllink
- goto found
- }
- }
- throw("m not found in allm")
-found:
- // Delay reaping m until it's done with the stack.
- //
- // Put mp on the free list, though it will not be reaped while freeWait
- // is freeMWait. mp is no longer reachable via allm, so even if it is
- // on an OS stack, we must keep a reference to mp alive so that the GC
- // doesn't free mp while we are still using it.
- //
- // Note that the free list must not be linked through alllink because
- // some functions walk allm without locking, so may be using alllink.
- mp.freeWait.Store(freeMWait)
- mp.freelink = sched.freem
- sched.freem = mp
- unlock(&sched.lock)
-
- atomic.Xadd64(&ncgocall, int64(mp.ncgocall))
-
- // Release the P.
- handoffp(releasep())
- // After this point we must not have write barriers.
-
- // Invoke the deadlock detector. This must happen after
- // handoffp because it may have started a new M to take our
- // P's work.
- lock(&sched.lock)
- sched.nmfreed++
- checkdead()
- unlock(&sched.lock)
-
- if GOOS == "darwin" || GOOS == "ios" {
- // Make sure pendingPreemptSignals is correct when an M exits.
- // For #41702.
- if mp.signalPending.Load() != 0 {
- pendingPreemptSignals.Add(-1)
- }
- }
-
- // Destroy all allocated resources. After this is called, we may no
- // longer take any locks.
- mdestroy(mp)
-
- if osStack {
- // No more uses of mp, so it is safe to drop the reference.
- mp.freeWait.Store(freeMRef)
-
- // Return from mstart and let the system thread
- // library free the g0 stack and terminate the thread.
- return
- }
-
- // mstart is the thread's entry point, so there's nothing to
- // return to. Exit the thread directly. exitThread will clear
- // m.freeWait when it's done with the stack and the m can be
- // reaped.
- exitThread(&mp.freeWait)
-}
-
-// forEachP calls fn(p) for every P p when p reaches a GC safe point.
-// If a P is currently executing code, this will bring the P to a GC
-// safe point and execute fn on that P. If the P is not executing code
-// (it is idle or in a syscall), this will call fn(p) directly while
-// preventing the P from exiting its state. This does not ensure that
-// fn will run on every CPU executing Go code, but it acts as a global
-// memory barrier. GC uses this as a "ragged barrier."
-//
-// The caller must hold worldsema.
-//
-//go:systemstack
-func forEachP(fn func(*p)) {
- mp := acquirem()
- pp := getg().m.p.ptr()
-
- lock(&sched.lock)
- if sched.safePointWait != 0 {
- throw("forEachP: sched.safePointWait != 0")
- }
- sched.safePointWait = gomaxprocs - 1
- sched.safePointFn = fn
-
- // Ask all Ps to run the safe point function.
- for _, p2 := range allp {
- if p2 != pp {
- atomic.Store(&p2.runSafePointFn, 1)
- }
- }
- preemptall()
-
- // Any P entering _Pidle or _Psyscall from now on will observe
- // p.runSafePointFn == 1 and will call runSafePointFn when
- // changing its status to _Pidle/_Psyscall.
-
- // Run safe point function for all idle Ps. sched.pidle will
- // not change because we hold sched.lock.
- for p := sched.pidle.ptr(); p != nil; p = p.link.ptr() {
- if atomic.Cas(&p.runSafePointFn, 1, 0) {
- fn(p)
- sched.safePointWait--
- }
- }
-
- wait := sched.safePointWait > 0
- unlock(&sched.lock)
-
- // Run fn for the current P.
- fn(pp)
-
- // Force Ps currently in _Psyscall into _Pidle and hand them
- // off to induce safe point function execution.
- for _, p2 := range allp {
- s := p2.status
- if s == _Psyscall && p2.runSafePointFn == 1 && atomic.Cas(&p2.status, s, _Pidle) {
- if trace.enabled {
- traceGoSysBlock(p2)
- traceProcStop(p2)
- }
- p2.syscalltick++
- handoffp(p2)
- }
- }
-
- // Wait for remaining Ps to run fn.
- if wait {
- for {
- // Wait for 100us, then try to re-preempt in
- // case of any races.
- //
- // Requires system stack.
- if notetsleep(&sched.safePointNote, 100*1000) {
- noteclear(&sched.safePointNote)
- break
- }
- preemptall()
- }
- }
- if sched.safePointWait != 0 {
- throw("forEachP: not done")
- }
- for _, p2 := range allp {
- if p2.runSafePointFn != 0 {
- throw("forEachP: P did not run fn")
- }
- }
-
- lock(&sched.lock)
- sched.safePointFn = nil
- unlock(&sched.lock)
- releasem(mp)
-}
-
-// runSafePointFn runs the safe point function, if any, for this P.
-// This should be called like
-//
-// if getg().m.p.runSafePointFn != 0 {
-// runSafePointFn()
-// }
-//
-// runSafePointFn must be checked on any transition in to _Pidle or
-// _Psyscall to avoid a race where forEachP sees that the P is running
-// just before the P goes into _Pidle/_Psyscall and neither forEachP
-// nor the P run the safe-point function.
-func runSafePointFn() {
- p := getg().m.p.ptr()
- // Resolve the race between forEachP running the safe-point
- // function on this P's behalf and this P running the
- // safe-point function directly.
- if !atomic.Cas(&p.runSafePointFn, 1, 0) {
- return
- }
- sched.safePointFn(p)
- lock(&sched.lock)
- sched.safePointWait--
- if sched.safePointWait == 0 {
- notewakeup(&sched.safePointNote)
- }
- unlock(&sched.lock)
-}
-
-// When running with cgo, we call _cgo_thread_start
-// to start threads for us so that we can play nicely with
-// foreign code.
-var cgoThreadStart unsafe.Pointer
-
-type cgothreadstart struct {
- g guintptr
- tls *uint64
- fn unsafe.Pointer
-}
-
-// Allocate a new m unassociated with any thread.
-// Can use p for allocation context if needed.
-// fn is recorded as the new m's m.mstartfn.
-// id is optional pre-allocated m ID. Omit by passing -1.
-//
-// This function is allowed to have write barriers even if the caller
-// isn't because it borrows pp.
-//
-//go:yeswritebarrierrec
-func allocm(pp *p, fn func(), id int64) *m {
- allocmLock.rlock()
-
- // The caller owns pp, but we may borrow (i.e., acquirep) it. We must
- // disable preemption to ensure it is not stolen, which would make the
- // caller lose ownership.
- acquirem()
-
- gp := getg()
- if gp.m.p == 0 {
- acquirep(pp) // temporarily borrow p for mallocs in this function
- }
-
- // Release the free M list. We need to do this somewhere and
- // this may free up a stack we can use.
- if sched.freem != nil {
- lock(&sched.lock)
- var newList *m
- for freem := sched.freem; freem != nil; {
- wait := freem.freeWait.Load()
- if wait == freeMWait {
- next := freem.freelink
- freem.freelink = newList
- newList = freem
- freem = next
- continue
- }
- // Free the stack if needed. For freeMRef, there is
- // nothing to do except drop freem from the sched.freem
- // list.
- if wait == freeMStack {
- // stackfree must be on the system stack, but allocm is
- // reachable off the system stack transitively from
- // startm.
- systemstack(func() {
- stackfree(freem.g0.stack)
- })
- }
- freem = freem.freelink
- }
- sched.freem = newList
- unlock(&sched.lock)
- }
-
- mp := new(m)
- mp.mstartfn = fn
- mcommoninit(mp, id)
-
- // In case of cgo or Solaris or illumos or Darwin, pthread_create will make us a stack.
- // Windows and Plan 9 will layout sched stack on OS stack.
- if iscgo || mStackIsSystemAllocated() {
- mp.g0 = malg(-1)
- } else {
- mp.g0 = malg(8192 * sys.StackGuardMultiplier)
- }
- mp.g0.m = mp
-
- if pp == gp.m.p.ptr() {
- releasep()
- }
-
- releasem(gp.m)
- allocmLock.runlock()
- return mp
-}
-
-// needm is called when a cgo callback happens on a
-// thread without an m (a thread not created by Go).
-// In this case, needm is expected to find an m to use
-// and return with m, g initialized correctly.
-// Since m and g are not set now (likely nil, but see below)
-// needm is limited in what routines it can call. In particular
-// it can only call nosplit functions (textflag 7) and cannot
-// do any scheduling that requires an m.
-//
-// In order to avoid needing heavy lifting here, we adopt
-// the following strategy: there is a stack of available m's
-// that can be stolen. Using compare-and-swap
-// to pop from the stack has ABA races, so we simulate
-// a lock by doing an exchange (via Casuintptr) to steal the stack
-// head and replace the top pointer with MLOCKED (1).
-// This serves as a simple spin lock that we can use even
-// without an m. The thread that locks the stack in this way
-// unlocks the stack by storing a valid stack head pointer.
-//
-// In order to make sure that there is always an m structure
-// available to be stolen, we maintain the invariant that there
-// is always one more than needed. At the beginning of the
-// program (if cgo is in use) the list is seeded with a single m.
-// If needm finds that it has taken the last m off the list, its job
-// is - once it has installed its own m so that it can do things like
-// allocate memory - to create a spare m and put it on the list.
-//
-// Each of these extra m's also has a g0 and a curg that are
-// pressed into service as the scheduling stack and current
-// goroutine for the duration of the cgo callback.
-//
-// When the callback is done with the m, it calls dropm to
-// put the m back on the list.
-//
-//go:nosplit
-func needm() {
- if (iscgo || GOOS == "windows") && !cgoHasExtraM {
- // Can happen if C/C++ code calls Go from a global ctor.
- // Can also happen on Windows if a global ctor uses a
- // callback created by syscall.NewCallback. See issue #6751
- // for details.
- //
- // Can not throw, because scheduler is not initialized yet.
- writeErrStr("fatal error: cgo callback before cgo call\n")
- exit(1)
- }
-
- // Save and block signals before getting an M.
- // The signal handler may call needm itself,
- // and we must avoid a deadlock. Also, once g is installed,
- // any incoming signals will try to execute,
- // but we won't have the sigaltstack settings and other data
- // set up appropriately until the end of minit, which will
- // unblock the signals. This is the same dance as when
- // starting a new m to run Go code via newosproc.
- var sigmask sigset
- sigsave(&sigmask)
- sigblock(false)
-
- // Lock extra list, take head, unlock popped list.
- // nilokay=false is safe here because of the invariant above,
- // that the extra list always contains or will soon contain
- // at least one m.
- mp := lockextra(false)
-
- // Set needextram when we've just emptied the list,
- // so that the eventual call into cgocallbackg will
- // allocate a new m for the extra list. We delay the
- // allocation until then so that it can be done
- // after exitsyscall makes sure it is okay to be
- // running at all (that is, there's no garbage collection
- // running right now).
- mp.needextram = mp.schedlink == 0
- extraMCount--
- unlockextra(mp.schedlink.ptr())
-
- // Store the original signal mask for use by minit.
- mp.sigmask = sigmask
-
- // Install TLS on some platforms (previously setg
- // would do this if necessary).
- osSetupTLS(mp)
-
- // Install g (= m->g0) and set the stack bounds
- // to match the current stack. We don't actually know
- // how big the stack is, like we don't know how big any
- // scheduling stack is, but we assume there's at least 32 kB,
- // which is more than enough for us.
- setg(mp.g0)
- gp := getg()
- gp.stack.hi = getcallersp() + 1024
- gp.stack.lo = getcallersp() - 32*1024
- gp.stackguard0 = gp.stack.lo + _StackGuard
-
- // Initialize this thread to use the m.
- asminit()
- minit()
-
- // mp.curg is now a real goroutine.
- casgstatus(mp.curg, _Gdead, _Gsyscall)
- sched.ngsys.Add(-1)
-}
-
-// newextram allocates m's and puts them on the extra list.
-// It is called with a working local m, so that it can do things
-// like call schedlock and allocate.
-func newextram() {
- c := extraMWaiters.Swap(0)
- if c > 0 {
- for i := uint32(0); i < c; i++ {
- oneNewExtraM()
- }
- } else {
- // Make sure there is at least one extra M.
- mp := lockextra(true)
- unlockextra(mp)
- if mp == nil {
- oneNewExtraM()
- }
- }
-}
-
-// oneNewExtraM allocates an m and puts it on the extra list.
-func oneNewExtraM() {
- // Create extra goroutine locked to extra m.
- // The goroutine is the context in which the cgo callback will run.
- // The sched.pc will never be returned to, but setting it to
- // goexit makes clear to the traceback routines where
- // the goroutine stack ends.
- mp := allocm(nil, nil, -1)
- gp := malg(4096)
- gp.sched.pc = abi.FuncPCABI0(goexit) + sys.PCQuantum
- gp.sched.sp = gp.stack.hi
- gp.sched.sp -= 4 * goarch.PtrSize // extra space in case of reads slightly beyond frame
- gp.sched.lr = 0
- gp.sched.g = guintptr(unsafe.Pointer(gp))
- gp.syscallpc = gp.sched.pc
- gp.syscallsp = gp.sched.sp
- gp.stktopsp = gp.sched.sp
- // malg returns status as _Gidle. Change to _Gdead before
- // adding to allg where GC can see it. We use _Gdead to hide
- // this from tracebacks and stack scans since it isn't a
- // "real" goroutine until needm grabs it.
- casgstatus(gp, _Gidle, _Gdead)
- gp.m = mp
- mp.curg = gp
- mp.isextra = true
- mp.lockedInt++
- mp.lockedg.set(gp)
- gp.lockedm.set(mp)
- gp.goid = sched.goidgen.Add(1)
- gp.sysblocktraced = true
- if raceenabled {
- gp.racectx = racegostart(abi.FuncPCABIInternal(newextram) + sys.PCQuantum)
- }
- if trace.enabled {
- // Trigger two trace events for the locked g in the extra m,
- // since the next event of the g will be traceEvGoSysExit in exitsyscall,
- // while calling from C thread to Go.
- traceGoCreate(gp, 0) // no start pc
- gp.traceseq++
- traceEvent(traceEvGoInSyscall, -1, gp.goid)
- }
- // put on allg for garbage collector
- allgadd(gp)
-
- // gp is now on the allg list, but we don't want it to be
- // counted by gcount. It would be more "proper" to increment
- // sched.ngfree, but that requires locking. Incrementing ngsys
- // has the same effect.
- sched.ngsys.Add(1)
-
- // Add m to the extra list.
- mnext := lockextra(true)
- mp.schedlink.set(mnext)
- extraMCount++
- unlockextra(mp)
-}
-
-// dropm is called when a cgo callback has called needm but is now
-// done with the callback and returning back into the non-Go thread.
-// It puts the current m back onto the extra list.
-//
-// The main expense here is the call to signalstack to release the
-// m's signal stack, and then the call to needm on the next callback
-// from this thread. It is tempting to try to save the m for next time,
-// which would eliminate both these costs, but there might not be
-// a next time: the current thread (which Go does not control) might exit.
-// If we saved the m for that thread, there would be an m leak each time
-// such a thread exited. Instead, we acquire and release an m on each
-// call. These should typically not be scheduling operations, just a few
-// atomics, so the cost should be small.
-//
-// TODO(rsc): An alternative would be to allocate a dummy pthread per-thread
-// variable using pthread_key_create. Unlike the pthread keys we already use
-// on OS X, this dummy key would never be read by Go code. It would exist
-// only so that we could register at thread-exit-time destructor.
-// That destructor would put the m back onto the extra list.
-// This is purely a performance optimization. The current version,
-// in which dropm happens on each cgo call, is still correct too.
-// We may have to keep the current version on systems with cgo
-// but without pthreads, like Windows.
-func dropm() {
- // Clear m and g, and return m to the extra list.
- // After the call to setg we can only call nosplit functions
- // with no pointer manipulation.
- mp := getg().m
-
- // Return mp.curg to dead state.
- casgstatus(mp.curg, _Gsyscall, _Gdead)
- mp.curg.preemptStop = false
- sched.ngsys.Add(1)
-
- // Block signals before unminit.
- // Unminit unregisters the signal handling stack (but needs g on some systems).
- // Setg(nil) clears g, which is the signal handler's cue not to run Go handlers.
- // It's important not to try to handle a signal between those two steps.
- sigmask := mp.sigmask
- sigblock(false)
- unminit()
-
- mnext := lockextra(true)
- extraMCount++
- mp.schedlink.set(mnext)
-
- setg(nil)
-
- // Commit the release of mp.
- unlockextra(mp)
-
- msigrestore(sigmask)
-}
-
-// A helper function for EnsureDropM.
-func getm() uintptr {
- return uintptr(unsafe.Pointer(getg().m))
-}
-
-var extram atomic.Uintptr
-var extraMCount uint32 // Protected by lockextra
-var extraMWaiters atomic.Uint32
-
-// lockextra locks the extra list and returns the list head.
-// The caller must unlock the list by storing a new list head
-// to extram. If nilokay is true, then lockextra will
-// return a nil list head if that's what it finds. If nilokay is false,
-// lockextra will keep waiting until the list head is no longer nil.
-//
-//go:nosplit
-func lockextra(nilokay bool) *m {
- const locked = 1
-
- incr := false
- for {
- old := extram.Load()
- if old == locked {
- osyield_no_g()
- continue
- }
- if old == 0 && !nilokay {
- if !incr {
- // Add 1 to the number of threads
- // waiting for an M.
- // This is cleared by newextram.
- extraMWaiters.Add(1)
- incr = true
- }
- usleep_no_g(1)
- continue
- }
- if extram.CompareAndSwap(old, locked) {
- return (*m)(unsafe.Pointer(old))
- }
- osyield_no_g()
- continue
- }
-}
-
-//go:nosplit
-func unlockextra(mp *m) {
- extram.Store(uintptr(unsafe.Pointer(mp)))
-}
-
-var (
- // allocmLock is locked for read when creating new Ms in allocm and their
- // addition to allm. Thus acquiring this lock for write blocks the
- // creation of new Ms.
- allocmLock rwmutex
-
- // execLock serializes exec and clone to avoid bugs or unspecified
- // behaviour around exec'ing while creating/destroying threads. See
- // issue #19546.
- execLock rwmutex
-)
-
-// These errors are reported (via writeErrStr) by some OS-specific
-// versions of newosproc and newosproc0.
-const (
- failthreadcreate = "runtime: failed to create new OS thread\n"
- failallocatestack = "runtime: failed to allocate stack for the new OS thread\n"
-)
-
-// newmHandoff contains a list of m structures that need new OS threads.
-// This is used by newm in situations where newm itself can't safely
-// start an OS thread.
-var newmHandoff struct {
- lock mutex
-
- // newm points to a list of M structures that need new OS
- // threads. The list is linked through m.schedlink.
- newm muintptr
-
- // waiting indicates that wake needs to be notified when an m
- // is put on the list.
- waiting bool
- wake note
-
- // haveTemplateThread indicates that the templateThread has
- // been started. This is not protected by lock. Use cas to set
- // to 1.
- haveTemplateThread uint32
-}
-
-// Create a new m. It will start off with a call to fn, or else the scheduler.
-// fn needs to be static and not a heap allocated closure.
-// May run with m.p==nil, so write barriers are not allowed.
-//
-// id is optional pre-allocated m ID. Omit by passing -1.
-//
-//go:nowritebarrierrec
-func newm(fn func(), pp *p, id int64) {
- // allocm adds a new M to allm, but they do not start until created by
- // the OS in newm1 or the template thread.
- //
- // doAllThreadsSyscall requires that every M in allm will eventually
- // start and be signal-able, even with a STW.
- //
- // Disable preemption here until we start the thread to ensure that
- // newm is not preempted between allocm and starting the new thread,
- // ensuring that anything added to allm is guaranteed to eventually
- // start.
- acquirem()
-
- mp := allocm(pp, fn, id)
- mp.nextp.set(pp)
- mp.sigmask = initSigmask
- if gp := getg(); gp != nil && gp.m != nil && (gp.m.lockedExt != 0 || gp.m.incgo) && GOOS != "plan9" {
- // We're on a locked M or a thread that may have been
- // started by C. The kernel state of this thread may
- // be strange (the user may have locked it for that
- // purpose). We don't want to clone that into another
- // thread. Instead, ask a known-good thread to create
- // the thread for us.
- //
- // This is disabled on Plan 9. See golang.org/issue/22227.
- //
- // TODO: This may be unnecessary on Windows, which
- // doesn't model thread creation off fork.
- lock(&newmHandoff.lock)
- if newmHandoff.haveTemplateThread == 0 {
- throw("on a locked thread with no template thread")
- }
- mp.schedlink = newmHandoff.newm
- newmHandoff.newm.set(mp)
- if newmHandoff.waiting {
- newmHandoff.waiting = false
- notewakeup(&newmHandoff.wake)
- }
- unlock(&newmHandoff.lock)
- // The M has not started yet, but the template thread does not
- // participate in STW, so it will always process queued Ms and
- // it is safe to releasem.
- releasem(getg().m)
- return
- }
- newm1(mp)
- releasem(getg().m)
-}
-
-func newm1(mp *m) {
- if iscgo {
- var ts cgothreadstart
- if _cgo_thread_start == nil {
- throw("_cgo_thread_start missing")
- }
- ts.g.set(mp.g0)
- ts.tls = (*uint64)(unsafe.Pointer(&mp.tls[0]))
- ts.fn = unsafe.Pointer(abi.FuncPCABI0(mstart))
- if msanenabled {
- msanwrite(unsafe.Pointer(&ts), unsafe.Sizeof(ts))
- }
- if asanenabled {
- asanwrite(unsafe.Pointer(&ts), unsafe.Sizeof(ts))
- }
- execLock.rlock() // Prevent process clone.
- asmcgocall(_cgo_thread_start, unsafe.Pointer(&ts))
- execLock.runlock()
- return
- }
- execLock.rlock() // Prevent process clone.
- newosproc(mp)
- execLock.runlock()
-}
-
-// startTemplateThread starts the template thread if it is not already
-// running.
-//
-// The calling thread must itself be in a known-good state.
-func startTemplateThread() {
- if GOARCH == "wasm" { // no threads on wasm yet
- return
- }
-
- // Disable preemption to guarantee that the template thread will be
- // created before a park once haveTemplateThread is set.
- mp := acquirem()
- if !atomic.Cas(&newmHandoff.haveTemplateThread, 0, 1) {
- releasem(mp)
- return
- }
- newm(templateThread, nil, -1)
- releasem(mp)
-}
-
-// templateThread is a thread in a known-good state that exists solely
-// to start new threads in known-good states when the calling thread
-// may not be in a good state.
-//
-// Many programs never need this, so templateThread is started lazily
-// when we first enter a state that might lead to running on a thread
-// in an unknown state.
-//
-// templateThread runs on an M without a P, so it must not have write
-// barriers.
-//
-//go:nowritebarrierrec
-func templateThread() {
- lock(&sched.lock)
- sched.nmsys++
- checkdead()
- unlock(&sched.lock)
-
- for {
- lock(&newmHandoff.lock)
- for newmHandoff.newm != 0 {
- newm := newmHandoff.newm.ptr()
- newmHandoff.newm = 0
- unlock(&newmHandoff.lock)
- for newm != nil {
- next := newm.schedlink.ptr()
- newm.schedlink = 0
- newm1(newm)
- newm = next
- }
- lock(&newmHandoff.lock)
- }
- newmHandoff.waiting = true
- noteclear(&newmHandoff.wake)
- unlock(&newmHandoff.lock)
- notesleep(&newmHandoff.wake)
- }
-}
-
-// Stops execution of the current m until new work is available.
-// Returns with acquired P.
-func stopm() {
- gp := getg()
-
- if gp.m.locks != 0 {
- throw("stopm holding locks")
- }
- if gp.m.p != 0 {
- throw("stopm holding p")
- }
- if gp.m.spinning {
- throw("stopm spinning")
- }
-
- lock(&sched.lock)
- mput(gp.m)
- unlock(&sched.lock)
- mPark()
- acquirep(gp.m.nextp.ptr())
- gp.m.nextp = 0
-}
-
-func mspinning() {
- // startm's caller incremented nmspinning. Set the new M's spinning.
- getg().m.spinning = true
-}
-
-// Schedules some M to run the p (creates an M if necessary).
-// If p==nil, tries to get an idle P, if no idle P's does nothing.
-// May run with m.p==nil, so write barriers are not allowed.
-// If spinning is set, the caller has incremented nmspinning and must provide a
-// P. startm will set m.spinning in the newly started M.
-//
-// Callers passing a non-nil P must call from a non-preemptible context. See
-// comment on acquirem below.
-//
-// Argument lockheld indicates whether the caller already acquired the
-// scheduler lock. Callers holding the lock when making the call must pass
-// true. The lock might be temporarily dropped, but will be reacquired before
-// returning.
-//
-// Must not have write barriers because this may be called without a P.
-//
-//go:nowritebarrierrec
-func startm(pp *p, spinning, lockheld bool) {
- // Disable preemption.
- //
- // Every owned P must have an owner that will eventually stop it in the
- // event of a GC stop request. startm takes transient ownership of a P
- // (either from argument or pidleget below) and transfers ownership to
- // a started M, which will be responsible for performing the stop.
- //
- // Preemption must be disabled during this transient ownership,
- // otherwise the P this is running on may enter GC stop while still
- // holding the transient P, leaving that P in limbo and deadlocking the
- // STW.
- //
- // Callers passing a non-nil P must already be in non-preemptible
- // context, otherwise such preemption could occur on function entry to
- // startm. Callers passing a nil P may be preemptible, so we must
- // disable preemption before acquiring a P from pidleget below.
- mp := acquirem()
- if !lockheld {
- lock(&sched.lock)
- }
- if pp == nil {
- if spinning {
- // TODO(prattmic): All remaining calls to this function
- // with _p_ == nil could be cleaned up to find a P
- // before calling startm.
- throw("startm: P required for spinning=true")
- }
- pp, _ = pidleget(0)
- if pp == nil {
- if !lockheld {
- unlock(&sched.lock)
- }
- releasem(mp)
- return
- }
- }
- nmp := mget()
- if nmp == nil {
- // No M is available, we must drop sched.lock and call newm.
- // However, we already own a P to assign to the M.
- //
- // Once sched.lock is released, another G (e.g., in a syscall),
- // could find no idle P while checkdead finds a runnable G but
- // no running M's because this new M hasn't started yet, thus
- // throwing in an apparent deadlock.
- // This apparent deadlock is possible when startm is called
- // from sysmon, which doesn't count as a running M.
- //
- // Avoid this situation by pre-allocating the ID for the new M,
- // thus marking it as 'running' before we drop sched.lock. This
- // new M will eventually run the scheduler to execute any
- // queued G's.
- id := mReserveID()
- unlock(&sched.lock)
-
- var fn func()
- if spinning {
- // The caller incremented nmspinning, so set m.spinning in the new M.
- fn = mspinning
- }
- newm(fn, pp, id)
-
- if lockheld {
- lock(&sched.lock)
- }
- // Ownership transfer of pp committed by start in newm.
- // Preemption is now safe.
- releasem(mp)
- return
- }
- if !lockheld {
- unlock(&sched.lock)
- }
- if nmp.spinning {
- throw("startm: m is spinning")
- }
- if nmp.nextp != 0 {
- throw("startm: m has p")
- }
- if spinning && !runqempty(pp) {
- throw("startm: p has runnable gs")
- }
- // The caller incremented nmspinning, so set m.spinning in the new M.
- nmp.spinning = spinning
- nmp.nextp.set(pp)
- notewakeup(&nmp.park)
- // Ownership transfer of pp committed by wakeup. Preemption is now
- // safe.
- releasem(mp)
-}
-
-// Hands off P from syscall or locked M.
-// Always runs without a P, so write barriers are not allowed.
-//
-//go:nowritebarrierrec
-func handoffp(pp *p) {
- // handoffp must start an M in any situation where
- // findrunnable would return a G to run on pp.
-
- // if it has local work, start it straight away
- if !runqempty(pp) || sched.runqsize != 0 {
- startm(pp, false, false)
- return
- }
- // if there's trace work to do, start it straight away
- if (trace.enabled || trace.shutdown) && traceReaderAvailable() != nil {
- startm(pp, false, false)
- return
- }
- // if it has GC work, start it straight away
- if gcBlackenEnabled != 0 && gcMarkWorkAvailable(pp) {
- startm(pp, false, false)
- return
- }
- // no local work, check that there are no spinning/idle M's,
- // otherwise our help is not required
- if sched.nmspinning.Load()+sched.npidle.Load() == 0 && sched.nmspinning.CompareAndSwap(0, 1) { // TODO: fast atomic
- sched.needspinning.Store(0)
- startm(pp, true, false)
- return
- }
- lock(&sched.lock)
- if sched.gcwaiting.Load() {
- pp.status = _Pgcstop
- sched.stopwait--
- if sched.stopwait == 0 {
- notewakeup(&sched.stopnote)
- }
- unlock(&sched.lock)
- return
- }
- if pp.runSafePointFn != 0 && atomic.Cas(&pp.runSafePointFn, 1, 0) {
- sched.safePointFn(pp)
- sched.safePointWait--
- if sched.safePointWait == 0 {
- notewakeup(&sched.safePointNote)
- }
- }
- if sched.runqsize != 0 {
- unlock(&sched.lock)
- startm(pp, false, false)
- return
- }
- // If this is the last running P and nobody is polling network,
- // need to wakeup another M to poll network.
- if sched.npidle.Load() == gomaxprocs-1 && sched.lastpoll.Load() != 0 {
- unlock(&sched.lock)
- startm(pp, false, false)
- return
- }
-
- // The scheduler lock cannot be held when calling wakeNetPoller below
- // because wakeNetPoller may call wakep which may call startm.
- when := nobarrierWakeTime(pp)
- pidleput(pp, 0)
- unlock(&sched.lock)
-
- if when != 0 {
- wakeNetPoller(when)
- }
-}
-
-// Tries to add one more P to execute G's.
-// Called when a G is made runnable (newproc, ready).
-// Must be called with a P.
-func wakep() {
- // Be conservative about spinning threads, only start one if none exist
- // already.
- if sched.nmspinning.Load() != 0 || !sched.nmspinning.CompareAndSwap(0, 1) {
- return
- }
-
- // Disable preemption until ownership of pp transfers to the next M in
- // startm. Otherwise preemption here would leave pp stuck waiting to
- // enter _Pgcstop.
- //
- // See preemption comment on acquirem in startm for more details.
- mp := acquirem()
-
- var pp *p
- lock(&sched.lock)
- pp, _ = pidlegetSpinning(0)
- if pp == nil {
- if sched.nmspinning.Add(-1) < 0 {
- throw("wakep: negative nmspinning")
- }
- unlock(&sched.lock)
- releasem(mp)
- return
- }
- // Since we always have a P, the race in the "No M is available"
- // comment in startm doesn't apply during the small window between the
- // unlock here and lock in startm. A checkdead in between will always
- // see at least one running M (ours).
- unlock(&sched.lock)
-
- startm(pp, true, false)
-
- releasem(mp)
-}
-
-// Stops execution of the current m that is locked to a g until the g is runnable again.
-// Returns with acquired P.
-func stoplockedm() {
- gp := getg()
-
- if gp.m.lockedg == 0 || gp.m.lockedg.ptr().lockedm.ptr() != gp.m {
- throw("stoplockedm: inconsistent locking")
- }
- if gp.m.p != 0 {
- // Schedule another M to run this p.
- pp := releasep()
- handoffp(pp)
- }
- incidlelocked(1)
- // Wait until another thread schedules lockedg again.
- mPark()
- status := readgstatus(gp.m.lockedg.ptr())
- if status&^_Gscan != _Grunnable {
- print("runtime:stoplockedm: lockedg (atomicstatus=", status, ") is not Grunnable or Gscanrunnable\n")
- dumpgstatus(gp.m.lockedg.ptr())
- throw("stoplockedm: not runnable")
- }
- acquirep(gp.m.nextp.ptr())
- gp.m.nextp = 0
-}
-
-// Schedules the locked m to run the locked gp.
-// May run during STW, so write barriers are not allowed.
-//
-//go:nowritebarrierrec
-func startlockedm(gp *g) {
- mp := gp.lockedm.ptr()
- if mp == getg().m {
- throw("startlockedm: locked to me")
- }
- if mp.nextp != 0 {
- throw("startlockedm: m has p")
- }
- // directly handoff current P to the locked m
- incidlelocked(-1)
- pp := releasep()
- mp.nextp.set(pp)
- notewakeup(&mp.park)
- stopm()
-}
-
-// Stops the current m for stopTheWorld.
-// Returns when the world is restarted.
-func gcstopm() {
- gp := getg()
-
- if !sched.gcwaiting.Load() {
- throw("gcstopm: not waiting for gc")
- }
- if gp.m.spinning {
- gp.m.spinning = false
- // OK to just drop nmspinning here,
- // startTheWorld will unpark threads as necessary.
- if sched.nmspinning.Add(-1) < 0 {
- throw("gcstopm: negative nmspinning")
- }
- }
- pp := releasep()
- lock(&sched.lock)
- pp.status = _Pgcstop
- sched.stopwait--
- if sched.stopwait == 0 {
- notewakeup(&sched.stopnote)
- }
- unlock(&sched.lock)
- stopm()
-}
-
-// Schedules gp to run on the current M.
-// If inheritTime is true, gp inherits the remaining time in the
-// current time slice. Otherwise, it starts a new time slice.
-// Never returns.
-//
-// Write barriers are allowed because this is called immediately after
-// acquiring a P in several places.
-//
-//go:yeswritebarrierrec
-func execute(gp *g, inheritTime bool) {
- mp := getg().m
-
- if goroutineProfile.active {
- // Make sure that gp has had its stack written out to the goroutine
- // profile, exactly as it was when the goroutine profiler first stopped
- // the world.
- tryRecordGoroutineProfile(gp, osyield)
- }
-
- // Assign gp.m before entering _Grunning so running Gs have an
- // M.
- mp.curg = gp
- gp.m = mp
- casgstatus(gp, _Grunnable, _Grunning)
- gp.waitsince = 0
- gp.preempt = false
- gp.stackguard0 = gp.stack.lo + _StackGuard
- if !inheritTime {
- mp.p.ptr().schedtick++
- }
-
- // Check whether the profiler needs to be turned on or off.
- hz := sched.profilehz
- if mp.profilehz != hz {
- setThreadCPUProfiler(hz)
- }
-
- if trace.enabled {
- // GoSysExit has to happen when we have a P, but before GoStart.
- // So we emit it here.
- if gp.syscallsp != 0 && gp.sysblocktraced {
- traceGoSysExit(gp.sysexitticks)
- }
- traceGoStart()
- }
-
- gogo(&gp.sched)
-}
-
-// Finds a runnable goroutine to execute.
-// Tries to steal from other P's, get g from local or global queue, poll network.
-// tryWakeP indicates that the returned goroutine is not normal (GC worker, trace
-// reader) so the caller should try to wake a P.
-func findRunnable() (gp *g, inheritTime, tryWakeP bool) {
- mp := getg().m
-
- // The conditions here and in handoffp must agree: if
- // findrunnable would return a G to run, handoffp must start
- // an M.
-
-top:
- pp := mp.p.ptr()
- if sched.gcwaiting.Load() {
- gcstopm()
- goto top
- }
- if pp.runSafePointFn != 0 {
- runSafePointFn()
- }
-
- // now and pollUntil are saved for work stealing later,
- // which may steal timers. It's important that between now
- // and then, nothing blocks, so these numbers remain mostly
- // relevant.
- now, pollUntil, _ := checkTimers(pp, 0)
-
- // Try to schedule the trace reader.
- if trace.enabled || trace.shutdown {
- gp := traceReader()
- if gp != nil {
- casgstatus(gp, _Gwaiting, _Grunnable)
- traceGoUnpark(gp, 0)
- return gp, false, true
- }
- }
-
- // Try to schedule a GC worker.
- if gcBlackenEnabled != 0 {
- gp, tnow := gcController.findRunnableGCWorker(pp, now)
- if gp != nil {
- return gp, false, true
- }
- now = tnow
- }
-
- // Check the global runnable queue once in a while to ensure fairness.
- // Otherwise two goroutines can completely occupy the local runqueue
- // by constantly respawning each other.
- if pp.schedtick%61 == 0 && sched.runqsize > 0 {
- lock(&sched.lock)
- gp := globrunqget(pp, 1)
- unlock(&sched.lock)
- if gp != nil {
- return gp, false, false
- }
- }
-
- // Wake up the finalizer G.
- if fingStatus.Load()&(fingWait|fingWake) == fingWait|fingWake {
- if gp := wakefing(); gp != nil {
- ready(gp, 0, true)
- }
- }
- if *cgo_yield != nil {
- asmcgocall(*cgo_yield, nil)
- }
-
- // local runq
- if gp, inheritTime := runqget(pp); gp != nil {
- return gp, inheritTime, false
- }
-
- // global runq
- if sched.runqsize != 0 {
- lock(&sched.lock)
- gp := globrunqget(pp, 0)
- unlock(&sched.lock)
- if gp != nil {
- return gp, false, false
- }
- }
-
- // Poll network.
- // This netpoll is only an optimization before we resort to stealing.
- // We can safely skip it if there are no waiters or a thread is blocked
- // in netpoll already. If there is any kind of logical race with that
- // blocked thread (e.g. it has already returned from netpoll, but does
- // not set lastpoll yet), this thread will do blocking netpoll below
- // anyway.
- if netpollinited() && netpollWaiters.Load() > 0 && sched.lastpoll.Load() != 0 {
- if list := netpoll(0); !list.empty() { // non-blocking
- gp := list.pop()
- injectglist(&list)
- casgstatus(gp, _Gwaiting, _Grunnable)
- if trace.enabled {
- traceGoUnpark(gp, 0)
- }
- return gp, false, false
- }
- }
-
- // Spinning Ms: steal work from other Ps.
- //
- // Limit the number of spinning Ms to half the number of busy Ps.
- // This is necessary to prevent excessive CPU consumption when
- // GOMAXPROCS>>1 but the program parallelism is low.
- if mp.spinning || 2*sched.nmspinning.Load() < gomaxprocs-sched.npidle.Load() {
- if !mp.spinning {
- mp.becomeSpinning()
- }
-
- gp, inheritTime, tnow, w, newWork := stealWork(now)
- if gp != nil {
- // Successfully stole.
- return gp, inheritTime, false
- }
- if newWork {
- // There may be new timer or GC work; restart to
- // discover.
- goto top
- }
-
- now = tnow
- if w != 0 && (pollUntil == 0 || w < pollUntil) {
- // Earlier timer to wait for.
- pollUntil = w
- }
- }
-
- // We have nothing to do.
- //
- // If we're in the GC mark phase, can safely scan and blacken objects,
- // and have work to do, run idle-time marking rather than give up the P.
- if gcBlackenEnabled != 0 && gcMarkWorkAvailable(pp) && gcController.addIdleMarkWorker() {
- node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
- if node != nil {
- pp.gcMarkWorkerMode = gcMarkWorkerIdleMode
- gp := node.gp.ptr()
- casgstatus(gp, _Gwaiting, _Grunnable)
- if trace.enabled {
- traceGoUnpark(gp, 0)
- }
- return gp, false, false
- }
- gcController.removeIdleMarkWorker()
- }
-
- // wasm only:
- // If a callback returned and no other goroutine is awake,
- // then wake event handler goroutine which pauses execution
- // until a callback was triggered.
- gp, otherReady := beforeIdle(now, pollUntil)
- if gp != nil {
- casgstatus(gp, _Gwaiting, _Grunnable)
- if trace.enabled {
- traceGoUnpark(gp, 0)
- }
- return gp, false, false
- }
- if otherReady {
- goto top
- }
-
- // Before we drop our P, make a snapshot of the allp slice,
- // which can change underfoot once we no longer block
- // safe-points. We don't need to snapshot the contents because
- // everything up to cap(allp) is immutable.
- allpSnapshot := allp
- // Also snapshot masks. Value changes are OK, but we can't allow
- // len to change out from under us.
- idlepMaskSnapshot := idlepMask
- timerpMaskSnapshot := timerpMask
-
- // return P and block
- lock(&sched.lock)
- if sched.gcwaiting.Load() || pp.runSafePointFn != 0 {
- unlock(&sched.lock)
- goto top
- }
- if sched.runqsize != 0 {
- gp := globrunqget(pp, 0)
- unlock(&sched.lock)
- return gp, false, false
- }
- if !mp.spinning && sched.needspinning.Load() == 1 {
- // See "Delicate dance" comment below.
- mp.becomeSpinning()
- unlock(&sched.lock)
- goto top
- }
- if releasep() != pp {
- throw("findrunnable: wrong p")
- }
- now = pidleput(pp, now)
- unlock(&sched.lock)
-
- // Delicate dance: thread transitions from spinning to non-spinning
- // state, potentially concurrently with submission of new work. We must
- // drop nmspinning first and then check all sources again (with
- // #StoreLoad memory barrier in between). If we do it the other way
- // around, another thread can submit work after we've checked all
- // sources but before we drop nmspinning; as a result nobody will
- // unpark a thread to run the work.
- //
- // This applies to the following sources of work:
- //
- // * Goroutines added to a per-P run queue.
- // * New/modified-earlier timers on a per-P timer heap.
- // * Idle-priority GC work (barring golang.org/issue/19112).
- //
- // If we discover new work below, we need to restore m.spinning as a
- // signal for resetspinning to unpark a new worker thread (because
- // there can be more than one starving goroutine).
- //
- // However, if after discovering new work we also observe no idle Ps
- // (either here or in resetspinning), we have a problem. We may be
- // racing with a non-spinning M in the block above, having found no
- // work and preparing to release its P and park. Allowing that P to go
- // idle will result in loss of work conservation (idle P while there is
- // runnable work). This could result in complete deadlock in the
- // unlikely event that we discover new work (from netpoll) right as we
- // are racing with _all_ other Ps going idle.
- //
- // We use sched.needspinning to synchronize with non-spinning Ms going
- // idle. If needspinning is set when they are about to drop their P,
- // they abort the drop and instead become a new spinning M on our
- // behalf. If we are not racing and the system is truly fully loaded
- // then no spinning threads are required, and the next thread to
- // naturally become spinning will clear the flag.
- //
- // Also see "Worker thread parking/unparking" comment at the top of the
- // file.
- wasSpinning := mp.spinning
- if mp.spinning {
- mp.spinning = false
- if sched.nmspinning.Add(-1) < 0 {
- throw("findrunnable: negative nmspinning")
- }
-
- // Note the for correctness, only the last M transitioning from
- // spinning to non-spinning must perform these rechecks to
- // ensure no missed work. However, the runtime has some cases
- // of transient increments of nmspinning that are decremented
- // without going through this path, so we must be conservative
- // and perform the check on all spinning Ms.
- //
- // See https://go.dev/issue/43997.
-
- // Check all runqueues once again.
- pp := checkRunqsNoP(allpSnapshot, idlepMaskSnapshot)
- if pp != nil {
- acquirep(pp)
- mp.becomeSpinning()
- goto top
- }
-
- // Check for idle-priority GC work again.
- pp, gp := checkIdleGCNoP()
- if pp != nil {
- acquirep(pp)
- mp.becomeSpinning()
-
- // Run the idle worker.
- pp.gcMarkWorkerMode = gcMarkWorkerIdleMode
- casgstatus(gp, _Gwaiting, _Grunnable)
- if trace.enabled {
- traceGoUnpark(gp, 0)
- }
- return gp, false, false
- }
-
- // Finally, check for timer creation or expiry concurrently with
- // transitioning from spinning to non-spinning.
- //
- // Note that we cannot use checkTimers here because it calls
- // adjusttimers which may need to allocate memory, and that isn't
- // allowed when we don't have an active P.
- pollUntil = checkTimersNoP(allpSnapshot, timerpMaskSnapshot, pollUntil)
- }
-
- // Poll network until next timer.
- if netpollinited() && (netpollWaiters.Load() > 0 || pollUntil != 0) && sched.lastpoll.Swap(0) != 0 {
- sched.pollUntil.Store(pollUntil)
- if mp.p != 0 {
- throw("findrunnable: netpoll with p")
- }
- if mp.spinning {
- throw("findrunnable: netpoll with spinning")
- }
- // Refresh now.
- now = nanotime()
- delay := int64(-1)
- if pollUntil != 0 {
- delay = pollUntil - now
- if delay < 0 {
- delay = 0
- }
- }
- if faketime != 0 {
- // When using fake time, just poll.
- delay = 0
- }
- list := netpoll(delay) // block until new work is available
- sched.pollUntil.Store(0)
- sched.lastpoll.Store(now)
- if faketime != 0 && list.empty() {
- // Using fake time and nothing is ready; stop M.
- // When all M's stop, checkdead will call timejump.
- stopm()
- goto top
- }
- lock(&sched.lock)
- pp, _ := pidleget(now)
- unlock(&sched.lock)
- if pp == nil {
- injectglist(&list)
- } else {
- acquirep(pp)
- if !list.empty() {
- gp := list.pop()
- injectglist(&list)
- casgstatus(gp, _Gwaiting, _Grunnable)
- if trace.enabled {
- traceGoUnpark(gp, 0)
- }
- return gp, false, false
- }
- if wasSpinning {
- mp.becomeSpinning()
- }
- goto top
- }
- } else if pollUntil != 0 && netpollinited() {
- pollerPollUntil := sched.pollUntil.Load()
- if pollerPollUntil == 0 || pollerPollUntil > pollUntil {
- netpollBreak()
- }
- }
- stopm()
- goto top
-}
-
-// pollWork reports whether there is non-background work this P could
-// be doing. This is a fairly lightweight check to be used for
-// background work loops, like idle GC. It checks a subset of the
-// conditions checked by the actual scheduler.
-func pollWork() bool {
- if sched.runqsize != 0 {
- return true
- }
- p := getg().m.p.ptr()
- if !runqempty(p) {
- return true
- }
- if netpollinited() && netpollWaiters.Load() > 0 && sched.lastpoll.Load() != 0 {
- if list := netpoll(0); !list.empty() {
- injectglist(&list)
- return true
- }
- }
- return false
-}
-
-// stealWork attempts to steal a runnable goroutine or timer from any P.
-//
-// If newWork is true, new work may have been readied.
-//
-// If now is not 0 it is the current time. stealWork returns the passed time or
-// the current time if now was passed as 0.
-func stealWork(now int64) (gp *g, inheritTime bool, rnow, pollUntil int64, newWork bool) {
- pp := getg().m.p.ptr()
-
- ranTimer := false
-
- const stealTries = 4
- for i := 0; i < stealTries; i++ {
- stealTimersOrRunNextG := i == stealTries-1
-
- for enum := stealOrder.start(fastrand()); !enum.done(); enum.next() {
- if sched.gcwaiting.Load() {
- // GC work may be available.
- return nil, false, now, pollUntil, true
- }
- p2 := allp[enum.position()]
- if pp == p2 {
- continue
- }
-
- // Steal timers from p2. This call to checkTimers is the only place
- // where we might hold a lock on a different P's timers. We do this
- // once on the last pass before checking runnext because stealing
- // from the other P's runnext should be the last resort, so if there
- // are timers to steal do that first.
- //
- // We only check timers on one of the stealing iterations because
- // the time stored in now doesn't change in this loop and checking
- // the timers for each P more than once with the same value of now
- // is probably a waste of time.
- //
- // timerpMask tells us whether the P may have timers at all. If it
- // can't, no need to check at all.
- if stealTimersOrRunNextG && timerpMask.read(enum.position()) {
- tnow, w, ran := checkTimers(p2, now)
- now = tnow
- if w != 0 && (pollUntil == 0 || w < pollUntil) {
- pollUntil = w
- }
- if ran {
- // Running the timers may have
- // made an arbitrary number of G's
- // ready and added them to this P's
- // local run queue. That invalidates
- // the assumption of runqsteal
- // that it always has room to add
- // stolen G's. So check now if there
- // is a local G to run.
- if gp, inheritTime := runqget(pp); gp != nil {
- return gp, inheritTime, now, pollUntil, ranTimer
- }
- ranTimer = true
- }
- }
-
- // Don't bother to attempt to steal if p2 is idle.
- if !idlepMask.read(enum.position()) {
- if gp := runqsteal(pp, p2, stealTimersOrRunNextG); gp != nil {
- return gp, false, now, pollUntil, ranTimer
- }
- }
- }
- }
-
- // No goroutines found to steal. Regardless, running a timer may have
- // made some goroutine ready that we missed. Indicate the next timer to
- // wait for.
- return nil, false, now, pollUntil, ranTimer
-}
-
-// Check all Ps for a runnable G to steal.
-//
-// On entry we have no P. If a G is available to steal and a P is available,
-// the P is returned which the caller should acquire and attempt to steal the
-// work to.
-func checkRunqsNoP(allpSnapshot []*p, idlepMaskSnapshot pMask) *p {
- for id, p2 := range allpSnapshot {
- if !idlepMaskSnapshot.read(uint32(id)) && !runqempty(p2) {
- lock(&sched.lock)
- pp, _ := pidlegetSpinning(0)
- if pp == nil {
- // Can't get a P, don't bother checking remaining Ps.
- unlock(&sched.lock)
- return nil
- }
- unlock(&sched.lock)
- return pp
- }
- }
-
- // No work available.
- return nil
-}
-
-// Check all Ps for a timer expiring sooner than pollUntil.
-//
-// Returns updated pollUntil value.
-func checkTimersNoP(allpSnapshot []*p, timerpMaskSnapshot pMask, pollUntil int64) int64 {
- for id, p2 := range allpSnapshot {
- if timerpMaskSnapshot.read(uint32(id)) {
- w := nobarrierWakeTime(p2)
- if w != 0 && (pollUntil == 0 || w < pollUntil) {
- pollUntil = w
- }
- }
- }
-
- return pollUntil
-}
-
-// Check for idle-priority GC, without a P on entry.
-//
-// If some GC work, a P, and a worker G are all available, the P and G will be
-// returned. The returned P has not been wired yet.
-func checkIdleGCNoP() (*p, *g) {
- // N.B. Since we have no P, gcBlackenEnabled may change at any time; we
- // must check again after acquiring a P. As an optimization, we also check
- // if an idle mark worker is needed at all. This is OK here, because if we
- // observe that one isn't needed, at least one is currently running. Even if
- // it stops running, its own journey into the scheduler should schedule it
- // again, if need be (at which point, this check will pass, if relevant).
- if atomic.Load(&gcBlackenEnabled) == 0 || !gcController.needIdleMarkWorker() {
- return nil, nil
- }
- if !gcMarkWorkAvailable(nil) {
- return nil, nil
- }
-
- // Work is available; we can start an idle GC worker only if there is
- // an available P and available worker G.
- //
- // We can attempt to acquire these in either order, though both have
- // synchronization concerns (see below). Workers are almost always
- // available (see comment in findRunnableGCWorker for the one case
- // there may be none). Since we're slightly less likely to find a P,
- // check for that first.
- //
- // Synchronization: note that we must hold sched.lock until we are
- // committed to keeping it. Otherwise we cannot put the unnecessary P
- // back in sched.pidle without performing the full set of idle
- // transition checks.
- //
- // If we were to check gcBgMarkWorkerPool first, we must somehow handle
- // the assumption in gcControllerState.findRunnableGCWorker that an
- // empty gcBgMarkWorkerPool is only possible if gcMarkDone is running.
- lock(&sched.lock)
- pp, now := pidlegetSpinning(0)
- if pp == nil {
- unlock(&sched.lock)
- return nil, nil
- }
-
- // Now that we own a P, gcBlackenEnabled can't change (as it requires STW).
- if gcBlackenEnabled == 0 || !gcController.addIdleMarkWorker() {
- pidleput(pp, now)
- unlock(&sched.lock)
- return nil, nil
- }
-
- node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
- if node == nil {
- pidleput(pp, now)
- unlock(&sched.lock)
- gcController.removeIdleMarkWorker()
- return nil, nil
- }
-
- unlock(&sched.lock)
-
- return pp, node.gp.ptr()
-}
-
-// wakeNetPoller wakes up the thread sleeping in the network poller if it isn't
-// going to wake up before the when argument; or it wakes an idle P to service
-// timers and the network poller if there isn't one already.
-func wakeNetPoller(when int64) {
- if sched.lastpoll.Load() == 0 {
- // In findrunnable we ensure that when polling the pollUntil
- // field is either zero or the time to which the current
- // poll is expected to run. This can have a spurious wakeup
- // but should never miss a wakeup.
- pollerPollUntil := sched.pollUntil.Load()
- if pollerPollUntil == 0 || pollerPollUntil > when {
- netpollBreak()
- }
- } else {
- // There are no threads in the network poller, try to get
- // one there so it can handle new timers.
- if GOOS != "plan9" { // Temporary workaround - see issue #42303.
- wakep()
- }
- }
-}
-
-func resetspinning() {
- gp := getg()
- if !gp.m.spinning {
- throw("resetspinning: not a spinning m")
- }
- gp.m.spinning = false
- nmspinning := sched.nmspinning.Add(-1)
- if nmspinning < 0 {
- throw("findrunnable: negative nmspinning")
- }
- // M wakeup policy is deliberately somewhat conservative, so check if we
- // need to wakeup another P here. See "Worker thread parking/unparking"
- // comment at the top of the file for details.
- wakep()
-}
-
-// injectglist adds each runnable G on the list to some run queue,
-// and clears glist. If there is no current P, they are added to the
-// global queue, and up to npidle M's are started to run them.
-// Otherwise, for each idle P, this adds a G to the global queue
-// and starts an M. Any remaining G's are added to the current P's
-// local run queue.
-// This may temporarily acquire sched.lock.
-// Can run concurrently with GC.
-func injectglist(glist *gList) {
- if glist.empty() {
- return
- }
- if trace.enabled {
- for gp := glist.head.ptr(); gp != nil; gp = gp.schedlink.ptr() {
- traceGoUnpark(gp, 0)
- }
- }
-
- // Mark all the goroutines as runnable before we put them
- // on the run queues.
- head := glist.head.ptr()
- var tail *g
- qsize := 0
- for gp := head; gp != nil; gp = gp.schedlink.ptr() {
- tail = gp
- qsize++
- casgstatus(gp, _Gwaiting, _Grunnable)
- }
-
- // Turn the gList into a gQueue.
- var q gQueue
- q.head.set(head)
- q.tail.set(tail)
- *glist = gList{}
-
- startIdle := func(n int) {
- for i := 0; i < n; i++ {
- mp := acquirem() // See comment in startm.
- lock(&sched.lock)
-
- pp, _ := pidlegetSpinning(0)
- if pp == nil {
- unlock(&sched.lock)
- releasem(mp)
- break
- }
-
- startm(pp, false, true)
- unlock(&sched.lock)
- releasem(mp)
- }
- }
-
- pp := getg().m.p.ptr()
- if pp == nil {
- lock(&sched.lock)
- globrunqputbatch(&q, int32(qsize))
- unlock(&sched.lock)
- startIdle(qsize)
- return
- }
-
- npidle := int(sched.npidle.Load())
- var globq gQueue
- var n int
- for n = 0; n < npidle && !q.empty(); n++ {
- g := q.pop()
- globq.pushBack(g)
- }
- if n > 0 {
- lock(&sched.lock)
- globrunqputbatch(&globq, int32(n))
- unlock(&sched.lock)
- startIdle(n)
- qsize -= n
- }
-
- if !q.empty() {
- runqputbatch(pp, &q, qsize)
- }
-}
-
-// One round of scheduler: find a runnable goroutine and execute it.
-// Never returns.
-func schedule() {
- mp := getg().m
-
- if mp.locks != 0 {
- throw("schedule: holding locks")
- }
-
- if mp.lockedg != 0 {
- stoplockedm()
- execute(mp.lockedg.ptr(), false) // Never returns.
- }
-
- // We should not schedule away from a g that is executing a cgo call,
- // since the cgo call is using the m's g0 stack.
- if mp.incgo {
- throw("schedule: in cgo")
- }
-
-top:
- pp := mp.p.ptr()
- pp.preempt = false
-
- // Safety check: if we are spinning, the run queue should be empty.
- // Check this before calling checkTimers, as that might call
- // goready to put a ready goroutine on the local run queue.
- if mp.spinning && (pp.runnext != 0 || pp.runqhead != pp.runqtail) {
- throw("schedule: spinning with local work")
- }
-
- gp, inheritTime, tryWakeP := findRunnable() // blocks until work is available
-
- // This thread is going to run a goroutine and is not spinning anymore,
- // so if it was marked as spinning we need to reset it now and potentially
- // start a new spinning M.
- if mp.spinning {
- resetspinning()
- }
-
- if sched.disable.user && !schedEnabled(gp) {
- // Scheduling of this goroutine is disabled. Put it on
- // the list of pending runnable goroutines for when we
- // re-enable user scheduling and look again.
- lock(&sched.lock)
- if schedEnabled(gp) {
- // Something re-enabled scheduling while we
- // were acquiring the lock.
- unlock(&sched.lock)
- } else {
- sched.disable.runnable.pushBack(gp)
- sched.disable.n++
- unlock(&sched.lock)
- goto top
- }
- }
-
- // If about to schedule a not-normal goroutine (a GCworker or tracereader),
- // wake a P if there is one.
- if tryWakeP {
- wakep()
- }
- if gp.lockedm != 0 {
- // Hands off own p to the locked m,
- // then blocks waiting for a new p.
- startlockedm(gp)
- goto top
- }
-
- execute(gp, inheritTime)
-}
-
-// dropg removes the association between m and the current goroutine m->curg (gp for short).
-// Typically a caller sets gp's status away from Grunning and then
-// immediately calls dropg to finish the job. The caller is also responsible
-// for arranging that gp will be restarted using ready at an
-// appropriate time. After calling dropg and arranging for gp to be
-// readied later, the caller can do other work but eventually should
-// call schedule to restart the scheduling of goroutines on this m.
-func dropg() {
- gp := getg()
-
- setMNoWB(&gp.m.curg.m, nil)
- setGNoWB(&gp.m.curg, nil)
-}
-
-// checkTimers runs any timers for the P that are ready.
-// If now is not 0 it is the current time.
-// It returns the passed time or the current time if now was passed as 0.
-// and the time when the next timer should run or 0 if there is no next timer,
-// and reports whether it ran any timers.
-// If the time when the next timer should run is not 0,
-// it is always larger than the returned time.
-// We pass now in and out to avoid extra calls of nanotime.
-//
-//go:yeswritebarrierrec
-func checkTimers(pp *p, now int64) (rnow, pollUntil int64, ran bool) {
- // If it's not yet time for the first timer, or the first adjusted
- // timer, then there is nothing to do.
- next := pp.timer0When.Load()
- nextAdj := pp.timerModifiedEarliest.Load()
- if next == 0 || (nextAdj != 0 && nextAdj < next) {
- next = nextAdj
- }
-
- if next == 0 {
- // No timers to run or adjust.
- return now, 0, false
- }
-
- if now == 0 {
- now = nanotime()
- }
- if now < next {
- // Next timer is not ready to run, but keep going
- // if we would clear deleted timers.
- // This corresponds to the condition below where
- // we decide whether to call clearDeletedTimers.
- if pp != getg().m.p.ptr() || int(pp.deletedTimers.Load()) <= int(pp.numTimers.Load()/4) {
- return now, next, false
- }
- }
-
- lock(&pp.timersLock)
-
- if len(pp.timers) > 0 {
- adjusttimers(pp, now)
- for len(pp.timers) > 0 {
- // Note that runtimer may temporarily unlock
- // pp.timersLock.
- if tw := runtimer(pp, now); tw != 0 {
- if tw > 0 {
- pollUntil = tw
- }
- break
- }
- ran = true
- }
- }
-
- // If this is the local P, and there are a lot of deleted timers,
- // clear them out. We only do this for the local P to reduce
- // lock contention on timersLock.
- if pp == getg().m.p.ptr() && int(pp.deletedTimers.Load()) > len(pp.timers)/4 {
- clearDeletedTimers(pp)
- }
-
- unlock(&pp.timersLock)
-
- return now, pollUntil, ran
-}
-
-func parkunlock_c(gp *g, lock unsafe.Pointer) bool {
- unlock((*mutex)(lock))
- return true
-}
-
-// park continuation on g0.
-func park_m(gp *g) {
- mp := getg().m
-
- if trace.enabled {
- traceGoPark(mp.waittraceev, mp.waittraceskip)
- }
-
- // N.B. Not using casGToWaiting here because the waitreason is
- // set by park_m's caller.
- casgstatus(gp, _Grunning, _Gwaiting)
- dropg()
-
- if fn := mp.waitunlockf; fn != nil {
- ok := fn(gp, mp.waitlock)
- mp.waitunlockf = nil
- mp.waitlock = nil
- if !ok {
- if trace.enabled {
- traceGoUnpark(gp, 2)
- }
- casgstatus(gp, _Gwaiting, _Grunnable)
- execute(gp, true) // Schedule it back, never returns.
- }
- }
- schedule()
-}
-
-func goschedImpl(gp *g) {
- status := readgstatus(gp)
- if status&^_Gscan != _Grunning {
- dumpgstatus(gp)
- throw("bad g status")
- }
- casgstatus(gp, _Grunning, _Grunnable)
- dropg()
- lock(&sched.lock)
- globrunqput(gp)
- unlock(&sched.lock)
-
- schedule()
-}
-
-// Gosched continuation on g0.
-func gosched_m(gp *g) {
- if trace.enabled {
- traceGoSched()
- }
- goschedImpl(gp)
-}
-
-// goschedguarded is a forbidden-states-avoided version of gosched_m.
-func goschedguarded_m(gp *g) {
-
- if !canPreemptM(gp.m) {
- gogo(&gp.sched) // never return
- }
-
- if trace.enabled {
- traceGoSched()
- }
- goschedImpl(gp)
-}
-
-func gopreempt_m(gp *g) {
- if trace.enabled {
- traceGoPreempt()
- }
- goschedImpl(gp)
-}
-
-// preemptPark parks gp and puts it in _Gpreempted.
-//
-//go:systemstack
-func preemptPark(gp *g) {
- if trace.enabled {
- traceGoPark(traceEvGoBlock, 0)
- }
- status := readgstatus(gp)
- if status&^_Gscan != _Grunning {
- dumpgstatus(gp)
- throw("bad g status")
- }
-
- if gp.asyncSafePoint {
- // Double-check that async preemption does not
- // happen in SPWRITE assembly functions.
- // isAsyncSafePoint must exclude this case.
- f := findfunc(gp.sched.pc)
- if !f.valid() {
- throw("preempt at unknown pc")
- }
- if f.flag&funcFlag_SPWRITE != 0 {
- println("runtime: unexpected SPWRITE function", funcname(f), "in async preempt")
- throw("preempt SPWRITE")
- }
- }
-
- // Transition from _Grunning to _Gscan|_Gpreempted. We can't
- // be in _Grunning when we dropg because then we'd be running
- // without an M, but the moment we're in _Gpreempted,
- // something could claim this G before we've fully cleaned it
- // up. Hence, we set the scan bit to lock down further
- // transitions until we can dropg.
- casGToPreemptScan(gp, _Grunning, _Gscan|_Gpreempted)
- dropg()
- casfrom_Gscanstatus(gp, _Gscan|_Gpreempted, _Gpreempted)
- schedule()
-}
-
-// goyield is like Gosched, but it:
-// - emits a GoPreempt trace event instead of a GoSched trace event
-// - puts the current G on the runq of the current P instead of the globrunq
-func goyield() {
- checkTimeouts()
- mcall(goyield_m)
-}
-
-func goyield_m(gp *g) {
- if trace.enabled {
- traceGoPreempt()
- }
- pp := gp.m.p.ptr()
- casgstatus(gp, _Grunning, _Grunnable)
- dropg()
- runqput(pp, gp, false)
- schedule()
-}
-
-// Finishes execution of the current goroutine.
-func goexit1() {
- if raceenabled {
- racegoend()
- }
- if trace.enabled {
- traceGoEnd()
- }
- mcall(goexit0)
-}
-
-// goexit continuation on g0.
-func goexit0(gp *g) {
- mp := getg().m
- pp := mp.p.ptr()
-
- casgstatus(gp, _Grunning, _Gdead)
- gcController.addScannableStack(pp, -int64(gp.stack.hi-gp.stack.lo))
- if isSystemGoroutine(gp, false) {
- sched.ngsys.Add(-1)
- }
- gp.m = nil
- locked := gp.lockedm != 0
- gp.lockedm = 0
- mp.lockedg = 0
- gp.preemptStop = false
- gp.paniconfault = false
- gp._defer = nil // should be true already but just in case.
- gp._panic = nil // non-nil for Goexit during panic. points at stack-allocated data.
- gp.writebuf = nil
- gp.waitreason = waitReasonZero
- gp.param = nil
- gp.labels = nil
- gp.timer = nil
-
- if gcBlackenEnabled != 0 && gp.gcAssistBytes > 0 {
- // Flush assist credit to the global pool. This gives
- // better information to pacing if the application is
- // rapidly creating an exiting goroutines.
- assistWorkPerByte := gcController.assistWorkPerByte.Load()
- scanCredit := int64(assistWorkPerByte * float64(gp.gcAssistBytes))
- gcController.bgScanCredit.Add(scanCredit)
- gp.gcAssistBytes = 0
- }
-
- dropg()
-
- if GOARCH == "wasm" { // no threads yet on wasm
- gfput(pp, gp)
- schedule() // never returns
- }
-
- if mp.lockedInt != 0 {
- print("invalid m->lockedInt = ", mp.lockedInt, "\n")
- throw("internal lockOSThread error")
- }
- gfput(pp, gp)
- if locked {
- // The goroutine may have locked this thread because
- // it put it in an unusual kernel state. Kill it
- // rather than returning it to the thread pool.
-
- // Return to mstart, which will release the P and exit
- // the thread.
- if GOOS != "plan9" { // See golang.org/issue/22227.
- gogo(&mp.g0.sched)
- } else {
- // Clear lockedExt on plan9 since we may end up re-using
- // this thread.
- mp.lockedExt = 0
- }
- }
- schedule()
-}
-
-// save updates getg().sched to refer to pc and sp so that a following
-// gogo will restore pc and sp.
-//
-// save must not have write barriers because invoking a write barrier
-// can clobber getg().sched.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func save(pc, sp uintptr) {
- gp := getg()
-
- if gp == gp.m.g0 || gp == gp.m.gsignal {
- // m.g0.sched is special and must describe the context
- // for exiting the thread. mstart1 writes to it directly.
- // m.gsignal.sched should not be used at all.
- // This check makes sure save calls do not accidentally
- // run in contexts where they'd write to system g's.
- throw("save on system g not allowed")
- }
-
- gp.sched.pc = pc
- gp.sched.sp = sp
- gp.sched.lr = 0
- gp.sched.ret = 0
- // We need to ensure ctxt is zero, but can't have a write
- // barrier here. However, it should always already be zero.
- // Assert that.
- if gp.sched.ctxt != nil {
- badctxt()
- }
-}
-
-// The goroutine g is about to enter a system call.
-// Record that it's not using the cpu anymore.
-// This is called only from the go syscall library and cgocall,
-// not from the low-level system calls used by the runtime.
-//
-// Entersyscall cannot split the stack: the save must
-// make g->sched refer to the caller's stack segment, because
-// entersyscall is going to return immediately after.
-//
-// Nothing entersyscall calls can split the stack either.
-// We cannot safely move the stack during an active call to syscall,
-// because we do not know which of the uintptr arguments are
-// really pointers (back into the stack).
-// In practice, this means that we make the fast path run through
-// entersyscall doing no-split things, and the slow path has to use systemstack
-// to run bigger things on the system stack.
-//
-// reentersyscall is the entry point used by cgo callbacks, where explicitly
-// saved SP and PC are restored. This is needed when exitsyscall will be called
-// from a function further up in the call stack than the parent, as g->syscallsp
-// must always point to a valid stack frame. entersyscall below is the normal
-// entry point for syscalls, which obtains the SP and PC from the caller.
-//
-// Syscall tracing:
-// At the start of a syscall we emit traceGoSysCall to capture the stack trace.
-// If the syscall does not block, that is it, we do not emit any other events.
-// If the syscall blocks (that is, P is retaken), retaker emits traceGoSysBlock;
-// when syscall returns we emit traceGoSysExit and when the goroutine starts running
-// (potentially instantly, if exitsyscallfast returns true) we emit traceGoStart.
-// To ensure that traceGoSysExit is emitted strictly after traceGoSysBlock,
-// we remember current value of syscalltick in m (gp.m.syscalltick = gp.m.p.ptr().syscalltick),
-// whoever emits traceGoSysBlock increments p.syscalltick afterwards;
-// and we wait for the increment before emitting traceGoSysExit.
-// Note that the increment is done even if tracing is not enabled,
-// because tracing can be enabled in the middle of syscall. We don't want the wait to hang.
-//
-//go:nosplit
-func reentersyscall(pc, sp uintptr) {
- gp := getg()
-
- // Disable preemption because during this function g is in Gsyscall status,
- // but can have inconsistent g->sched, do not let GC observe it.
- gp.m.locks++
-
- // Entersyscall must not call any function that might split/grow the stack.
- // (See details in comment above.)
- // Catch calls that might, by replacing the stack guard with something that
- // will trip any stack check and leaving a flag to tell newstack to die.
- gp.stackguard0 = stackPreempt
- gp.throwsplit = true
-
- // Leave SP around for GC and traceback.
- save(pc, sp)
- gp.syscallsp = sp
- gp.syscallpc = pc
- casgstatus(gp, _Grunning, _Gsyscall)
- if gp.syscallsp < gp.stack.lo || gp.stack.hi < gp.syscallsp {
- systemstack(func() {
- print("entersyscall inconsistent ", hex(gp.syscallsp), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n")
- throw("entersyscall")
- })
- }
-
- if trace.enabled {
- systemstack(traceGoSysCall)
- // systemstack itself clobbers g.sched.{pc,sp} and we might
- // need them later when the G is genuinely blocked in a
- // syscall
- save(pc, sp)
- }
-
- if sched.sysmonwait.Load() {
- systemstack(entersyscall_sysmon)
- save(pc, sp)
- }
-
- if gp.m.p.ptr().runSafePointFn != 0 {
- // runSafePointFn may stack split if run on this stack
- systemstack(runSafePointFn)
- save(pc, sp)
- }
-
- gp.m.syscalltick = gp.m.p.ptr().syscalltick
- gp.sysblocktraced = true
- pp := gp.m.p.ptr()
- pp.m = 0
- gp.m.oldp.set(pp)
- gp.m.p = 0
- atomic.Store(&pp.status, _Psyscall)
- if sched.gcwaiting.Load() {
- systemstack(entersyscall_gcwait)
- save(pc, sp)
- }
-
- gp.m.locks--
-}
-
-// Standard syscall entry used by the go syscall library and normal cgo calls.
-//
-// This is exported via linkname to assembly in the syscall package and x/sys.
-//
-//go:nosplit
-//go:linkname entersyscall
-func entersyscall() {
- reentersyscall(getcallerpc(), getcallersp())
-}
-
-func entersyscall_sysmon() {
- lock(&sched.lock)
- if sched.sysmonwait.Load() {
- sched.sysmonwait.Store(false)
- notewakeup(&sched.sysmonnote)
- }
- unlock(&sched.lock)
-}
-
-func entersyscall_gcwait() {
- gp := getg()
- pp := gp.m.oldp.ptr()
-
- lock(&sched.lock)
- if sched.stopwait > 0 && atomic.Cas(&pp.status, _Psyscall, _Pgcstop) {
- if trace.enabled {
- traceGoSysBlock(pp)
- traceProcStop(pp)
- }
- pp.syscalltick++
- if sched.stopwait--; sched.stopwait == 0 {
- notewakeup(&sched.stopnote)
- }
- }
- unlock(&sched.lock)
-}
-
-// The same as entersyscall(), but with a hint that the syscall is blocking.
-//
-//go:nosplit
-func entersyscallblock() {
- gp := getg()
-
- gp.m.locks++ // see comment in entersyscall
- gp.throwsplit = true
- gp.stackguard0 = stackPreempt // see comment in entersyscall
- gp.m.syscalltick = gp.m.p.ptr().syscalltick
- gp.sysblocktraced = true
- gp.m.p.ptr().syscalltick++
-
- // Leave SP around for GC and traceback.
- pc := getcallerpc()
- sp := getcallersp()
- save(pc, sp)
- gp.syscallsp = gp.sched.sp
- gp.syscallpc = gp.sched.pc
- if gp.syscallsp < gp.stack.lo || gp.stack.hi < gp.syscallsp {
- sp1 := sp
- sp2 := gp.sched.sp
- sp3 := gp.syscallsp
- systemstack(func() {
- print("entersyscallblock inconsistent ", hex(sp1), " ", hex(sp2), " ", hex(sp3), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n")
- throw("entersyscallblock")
- })
- }
- casgstatus(gp, _Grunning, _Gsyscall)
- if gp.syscallsp < gp.stack.lo || gp.stack.hi < gp.syscallsp {
- systemstack(func() {
- print("entersyscallblock inconsistent ", hex(sp), " ", hex(gp.sched.sp), " ", hex(gp.syscallsp), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n")
- throw("entersyscallblock")
- })
- }
-
- systemstack(entersyscallblock_handoff)
-
- // Resave for traceback during blocked call.
- save(getcallerpc(), getcallersp())
-
- gp.m.locks--
-}
-
-func entersyscallblock_handoff() {
- if trace.enabled {
- traceGoSysCall()
- traceGoSysBlock(getg().m.p.ptr())
- }
- handoffp(releasep())
-}
-
-// The goroutine g exited its system call.
-// Arrange for it to run on a cpu again.
-// This is called only from the go syscall library, not
-// from the low-level system calls used by the runtime.
-//
-// Write barriers are not allowed because our P may have been stolen.
-//
-// This is exported via linkname to assembly in the syscall package.
-//
-//go:nosplit
-//go:nowritebarrierrec
-//go:linkname exitsyscall
-func exitsyscall() {
- gp := getg()
-
- gp.m.locks++ // see comment in entersyscall
- if getcallersp() > gp.syscallsp {
- throw("exitsyscall: syscall frame is no longer valid")
- }
-
- gp.waitsince = 0
- oldp := gp.m.oldp.ptr()
- gp.m.oldp = 0
- if exitsyscallfast(oldp) {
- // When exitsyscallfast returns success, we have a P so can now use
- // write barriers
- if goroutineProfile.active {
- // Make sure that gp has had its stack written out to the goroutine
- // profile, exactly as it was when the goroutine profiler first
- // stopped the world.
- systemstack(func() {
- tryRecordGoroutineProfileWB(gp)
- })
- }
- if trace.enabled {
- if oldp != gp.m.p.ptr() || gp.m.syscalltick != gp.m.p.ptr().syscalltick {
- systemstack(traceGoStart)
- }
- }
- // There's a cpu for us, so we can run.
- gp.m.p.ptr().syscalltick++
- // We need to cas the status and scan before resuming...
- casgstatus(gp, _Gsyscall, _Grunning)
-
- // Garbage collector isn't running (since we are),
- // so okay to clear syscallsp.
- gp.syscallsp = 0
- gp.m.locks--
- if gp.preempt {
- // restore the preemption request in case we've cleared it in newstack
- gp.stackguard0 = stackPreempt
- } else {
- // otherwise restore the real _StackGuard, we've spoiled it in entersyscall/entersyscallblock
- gp.stackguard0 = gp.stack.lo + _StackGuard
- }
- gp.throwsplit = false
-
- if sched.disable.user && !schedEnabled(gp) {
- // Scheduling of this goroutine is disabled.
- Gosched()
- }
-
- return
- }
-
- gp.sysexitticks = 0
- if trace.enabled {
- // Wait till traceGoSysBlock event is emitted.
- // This ensures consistency of the trace (the goroutine is started after it is blocked).
- for oldp != nil && oldp.syscalltick == gp.m.syscalltick {
- osyield()
- }
- // We can't trace syscall exit right now because we don't have a P.
- // Tracing code can invoke write barriers that cannot run without a P.
- // So instead we remember the syscall exit time and emit the event
- // in execute when we have a P.
- gp.sysexitticks = cputicks()
- }
-
- gp.m.locks--
-
- // Call the scheduler.
- mcall(exitsyscall0)
-
- // Scheduler returned, so we're allowed to run now.
- // Delete the syscallsp information that we left for
- // the garbage collector during the system call.
- // Must wait until now because until gosched returns
- // we don't know for sure that the garbage collector
- // is not running.
- gp.syscallsp = 0
- gp.m.p.ptr().syscalltick++
- gp.throwsplit = false
-}
-
-//go:nosplit
-func exitsyscallfast(oldp *p) bool {
- gp := getg()
-
- // Freezetheworld sets stopwait but does not retake P's.
- if sched.stopwait == freezeStopWait {
- return false
- }
-
- // Try to re-acquire the last P.
- if oldp != nil && oldp.status == _Psyscall && atomic.Cas(&oldp.status, _Psyscall, _Pidle) {
- // There's a cpu for us, so we can run.
- wirep(oldp)
- exitsyscallfast_reacquired()
- return true
- }
-
- // Try to get any other idle P.
- if sched.pidle != 0 {
- var ok bool
- systemstack(func() {
- ok = exitsyscallfast_pidle()
- if ok && trace.enabled {
- if oldp != nil {
- // Wait till traceGoSysBlock event is emitted.
- // This ensures consistency of the trace (the goroutine is started after it is blocked).
- for oldp.syscalltick == gp.m.syscalltick {
- osyield()
- }
- }
- traceGoSysExit(0)
- }
- })
- if ok {
- return true
- }
- }
- return false
-}
-
-// exitsyscallfast_reacquired is the exitsyscall path on which this G
-// has successfully reacquired the P it was running on before the
-// syscall.
-//
-//go:nosplit
-func exitsyscallfast_reacquired() {
- gp := getg()
- if gp.m.syscalltick != gp.m.p.ptr().syscalltick {
- if trace.enabled {
- // The p was retaken and then enter into syscall again (since gp.m.syscalltick has changed).
- // traceGoSysBlock for this syscall was already emitted,
- // but here we effectively retake the p from the new syscall running on the same p.
- systemstack(func() {
- // Denote blocking of the new syscall.
- traceGoSysBlock(gp.m.p.ptr())
- // Denote completion of the current syscall.
- traceGoSysExit(0)
- })
- }
- gp.m.p.ptr().syscalltick++
- }
-}
-
-func exitsyscallfast_pidle() bool {
- lock(&sched.lock)
- pp, _ := pidleget(0)
- if pp != nil && sched.sysmonwait.Load() {
- sched.sysmonwait.Store(false)
- notewakeup(&sched.sysmonnote)
- }
- unlock(&sched.lock)
- if pp != nil {
- acquirep(pp)
- return true
- }
- return false
-}
-
-// exitsyscall slow path on g0.
-// Failed to acquire P, enqueue gp as runnable.
-//
-// Called via mcall, so gp is the calling g from this M.
-//
-//go:nowritebarrierrec
-func exitsyscall0(gp *g) {
- casgstatus(gp, _Gsyscall, _Grunnable)
- dropg()
- lock(&sched.lock)
- var pp *p
- if schedEnabled(gp) {
- pp, _ = pidleget(0)
- }
- var locked bool
- if pp == nil {
- globrunqput(gp)
-
- // Below, we stoplockedm if gp is locked. globrunqput releases
- // ownership of gp, so we must check if gp is locked prior to
- // committing the release by unlocking sched.lock, otherwise we
- // could race with another M transitioning gp from unlocked to
- // locked.
- locked = gp.lockedm != 0
- } else if sched.sysmonwait.Load() {
- sched.sysmonwait.Store(false)
- notewakeup(&sched.sysmonnote)
- }
- unlock(&sched.lock)
- if pp != nil {
- acquirep(pp)
- execute(gp, false) // Never returns.
- }
- if locked {
- // Wait until another thread schedules gp and so m again.
- //
- // N.B. lockedm must be this M, as this g was running on this M
- // before entersyscall.
- stoplockedm()
- execute(gp, false) // Never returns.
- }
- stopm()
- schedule() // Never returns.
-}
-
-// Called from syscall package before fork.
-//
-//go:linkname syscall_runtime_BeforeFork syscall.runtime_BeforeFork
-//go:nosplit
-func syscall_runtime_BeforeFork() {
- gp := getg().m.curg
-
- // Block signals during a fork, so that the child does not run
- // a signal handler before exec if a signal is sent to the process
- // group. See issue #18600.
- gp.m.locks++
- sigsave(&gp.m.sigmask)
- sigblock(false)
-
- // This function is called before fork in syscall package.
- // Code between fork and exec must not allocate memory nor even try to grow stack.
- // Here we spoil g->_StackGuard to reliably detect any attempts to grow stack.
- // runtime_AfterFork will undo this in parent process, but not in child.
- gp.stackguard0 = stackFork
-}
-
-// Called from syscall package after fork in parent.
-//
-//go:linkname syscall_runtime_AfterFork syscall.runtime_AfterFork
-//go:nosplit
-func syscall_runtime_AfterFork() {
- gp := getg().m.curg
-
- // See the comments in beforefork.
- gp.stackguard0 = gp.stack.lo + _StackGuard
-
- msigrestore(gp.m.sigmask)
-
- gp.m.locks--
-}
-
-// inForkedChild is true while manipulating signals in the child process.
-// This is used to avoid calling libc functions in case we are using vfork.
-var inForkedChild bool
-
-// Called from syscall package after fork in child.
-// It resets non-sigignored signals to the default handler, and
-// restores the signal mask in preparation for the exec.
-//
-// Because this might be called during a vfork, and therefore may be
-// temporarily sharing address space with the parent process, this must
-// not change any global variables or calling into C code that may do so.
-//
-//go:linkname syscall_runtime_AfterForkInChild syscall.runtime_AfterForkInChild
-//go:nosplit
-//go:nowritebarrierrec
-func syscall_runtime_AfterForkInChild() {
- // It's OK to change the global variable inForkedChild here
- // because we are going to change it back. There is no race here,
- // because if we are sharing address space with the parent process,
- // then the parent process can not be running concurrently.
- inForkedChild = true
-
- clearSignalHandlers()
-
- // When we are the child we are the only thread running,
- // so we know that nothing else has changed gp.m.sigmask.
- msigrestore(getg().m.sigmask)
-
- inForkedChild = false
-}
-
-// pendingPreemptSignals is the number of preemption signals
-// that have been sent but not received. This is only used on Darwin.
-// For #41702.
-var pendingPreemptSignals atomic.Int32
-
-// Called from syscall package before Exec.
-//
-//go:linkname syscall_runtime_BeforeExec syscall.runtime_BeforeExec
-func syscall_runtime_BeforeExec() {
- // Prevent thread creation during exec.
- execLock.lock()
-
- // On Darwin, wait for all pending preemption signals to
- // be received. See issue #41702.
- if GOOS == "darwin" || GOOS == "ios" {
- for pendingPreemptSignals.Load() > 0 {
- osyield()
- }
- }
-}
-
-// Called from syscall package after Exec.
-//
-//go:linkname syscall_runtime_AfterExec syscall.runtime_AfterExec
-func syscall_runtime_AfterExec() {
- execLock.unlock()
-}
-
-// Allocate a new g, with a stack big enough for stacksize bytes.
-func malg(stacksize int32) *g {
- newg := new(g)
- if stacksize >= 0 {
- stacksize = round2(_StackSystem + stacksize)
- systemstack(func() {
- newg.stack = stackalloc(uint32(stacksize))
- })
- newg.stackguard0 = newg.stack.lo + _StackGuard
- newg.stackguard1 = ^uintptr(0)
- // Clear the bottom word of the stack. We record g
- // there on gsignal stack during VDSO on ARM and ARM64.
- *(*uintptr)(unsafe.Pointer(newg.stack.lo)) = 0
- }
- return newg
-}
-
-// Create a new g running fn.
-// Put it on the queue of g's waiting to run.
-// The compiler turns a go statement into a call to this.
-func newproc(fn *funcval) {
- gp := getg()
- pc := getcallerpc()
- systemstack(func() {
- newg := newproc1(fn, gp, pc)
-
- pp := getg().m.p.ptr()
- runqput(pp, newg, true)
-
- if mainStarted {
- wakep()
- }
- })
-}
-
-// Create a new g in state _Grunnable, starting at fn. callerpc is the
-// address of the go statement that created this. The caller is responsible
-// for adding the new g to the scheduler.
-func newproc1(fn *funcval, callergp *g, callerpc uintptr) *g {
- if fn == nil {
- fatal("go of nil func value")
- }
-
- mp := acquirem() // disable preemption because we hold M and P in local vars.
- pp := mp.p.ptr()
- newg := gfget(pp)
- if newg == nil {
- newg = malg(_StackMin)
- casgstatus(newg, _Gidle, _Gdead)
- allgadd(newg) // publishes with a g->status of Gdead so GC scanner doesn't look at uninitialized stack.
- }
- if newg.stack.hi == 0 {
- throw("newproc1: newg missing stack")
- }
-
- if readgstatus(newg) != _Gdead {
- throw("newproc1: new g is not Gdead")
- }
-
- totalSize := uintptr(4*goarch.PtrSize + sys.MinFrameSize) // extra space in case of reads slightly beyond frame
- totalSize = alignUp(totalSize, sys.StackAlign)
- sp := newg.stack.hi - totalSize
- spArg := sp
- if usesLR {
- // caller's LR
- *(*uintptr)(unsafe.Pointer(sp)) = 0
- prepGoExitFrame(sp)
- spArg += sys.MinFrameSize
- }
-
- memclrNoHeapPointers(unsafe.Pointer(&newg.sched), unsafe.Sizeof(newg.sched))
- newg.sched.sp = sp
- newg.stktopsp = sp
- newg.sched.pc = abi.FuncPCABI0(goexit) + sys.PCQuantum // +PCQuantum so that previous instruction is in same function
- newg.sched.g = guintptr(unsafe.Pointer(newg))
- gostartcallfn(&newg.sched, fn)
- newg.gopc = callerpc
- newg.ancestors = saveAncestors(callergp)
- newg.startpc = fn.fn
- if isSystemGoroutine(newg, false) {
- sched.ngsys.Add(1)
- } else {
- // Only user goroutines inherit pprof labels.
- if mp.curg != nil {
- newg.labels = mp.curg.labels
- }
- if goroutineProfile.active {
- // A concurrent goroutine profile is running. It should include
- // exactly the set of goroutines that were alive when the goroutine
- // profiler first stopped the world. That does not include newg, so
- // mark it as not needing a profile before transitioning it from
- // _Gdead.
- newg.goroutineProfiled.Store(goroutineProfileSatisfied)
- }
- }
- // Track initial transition?
- newg.trackingSeq = uint8(fastrand())
- if newg.trackingSeq%gTrackingPeriod == 0 {
- newg.tracking = true
- }
- casgstatus(newg, _Gdead, _Grunnable)
- gcController.addScannableStack(pp, int64(newg.stack.hi-newg.stack.lo))
-
- if pp.goidcache == pp.goidcacheend {
- // Sched.goidgen is the last allocated id,
- // this batch must be [sched.goidgen+1, sched.goidgen+GoidCacheBatch].
- // At startup sched.goidgen=0, so main goroutine receives goid=1.
- pp.goidcache = sched.goidgen.Add(_GoidCacheBatch)
- pp.goidcache -= _GoidCacheBatch - 1
- pp.goidcacheend = pp.goidcache + _GoidCacheBatch
- }
- newg.goid = pp.goidcache
- pp.goidcache++
- if raceenabled {
- newg.racectx = racegostart(callerpc)
- newg.raceignore = 0
- if newg.labels != nil {
- // See note in proflabel.go on labelSync's role in synchronizing
- // with the reads in the signal handler.
- racereleasemergeg(newg, unsafe.Pointer(&labelSync))
- }
- }
- if trace.enabled {
- traceGoCreate(newg, newg.startpc)
- }
- releasem(mp)
-
- return newg
-}
-
-// saveAncestors copies previous ancestors of the given caller g and
-// includes infor for the current caller into a new set of tracebacks for
-// a g being created.
-func saveAncestors(callergp *g) *[]ancestorInfo {
- // Copy all prior info, except for the root goroutine (goid 0).
- if debug.tracebackancestors <= 0 || callergp.goid == 0 {
- return nil
- }
- var callerAncestors []ancestorInfo
- if callergp.ancestors != nil {
- callerAncestors = *callergp.ancestors
- }
- n := int32(len(callerAncestors)) + 1
- if n > debug.tracebackancestors {
- n = debug.tracebackancestors
- }
- ancestors := make([]ancestorInfo, n)
- copy(ancestors[1:], callerAncestors)
-
- var pcs [_TracebackMaxFrames]uintptr
- npcs := gcallers(callergp, 0, pcs[:])
- ipcs := make([]uintptr, npcs)
- copy(ipcs, pcs[:])
- ancestors[0] = ancestorInfo{
- pcs: ipcs,
- goid: callergp.goid,
- gopc: callergp.gopc,
- }
-
- ancestorsp := new([]ancestorInfo)
- *ancestorsp = ancestors
- return ancestorsp
-}
-
-// Put on gfree list.
-// If local list is too long, transfer a batch to the global list.
-func gfput(pp *p, gp *g) {
- if readgstatus(gp) != _Gdead {
- throw("gfput: bad status (not Gdead)")
- }
-
- stksize := gp.stack.hi - gp.stack.lo
-
- if stksize != uintptr(startingStackSize) {
- // non-standard stack size - free it.
- stackfree(gp.stack)
- gp.stack.lo = 0
- gp.stack.hi = 0
- gp.stackguard0 = 0
- }
-
- pp.gFree.push(gp)
- pp.gFree.n++
- if pp.gFree.n >= 64 {
- var (
- inc int32
- stackQ gQueue
- noStackQ gQueue
- )
- for pp.gFree.n >= 32 {
- gp := pp.gFree.pop()
- pp.gFree.n--
- if gp.stack.lo == 0 {
- noStackQ.push(gp)
- } else {
- stackQ.push(gp)
- }
- inc++
- }
- lock(&sched.gFree.lock)
- sched.gFree.noStack.pushAll(noStackQ)
- sched.gFree.stack.pushAll(stackQ)
- sched.gFree.n += inc
- unlock(&sched.gFree.lock)
- }
-}
-
-// Get from gfree list.
-// If local list is empty, grab a batch from global list.
-func gfget(pp *p) *g {
-retry:
- if pp.gFree.empty() && (!sched.gFree.stack.empty() || !sched.gFree.noStack.empty()) {
- lock(&sched.gFree.lock)
- // Move a batch of free Gs to the P.
- for pp.gFree.n < 32 {
- // Prefer Gs with stacks.
- gp := sched.gFree.stack.pop()
- if gp == nil {
- gp = sched.gFree.noStack.pop()
- if gp == nil {
- break
- }
- }
- sched.gFree.n--
- pp.gFree.push(gp)
- pp.gFree.n++
- }
- unlock(&sched.gFree.lock)
- goto retry
- }
- gp := pp.gFree.pop()
- if gp == nil {
- return nil
- }
- pp.gFree.n--
- if gp.stack.lo != 0 && gp.stack.hi-gp.stack.lo != uintptr(startingStackSize) {
- // Deallocate old stack. We kept it in gfput because it was the
- // right size when the goroutine was put on the free list, but
- // the right size has changed since then.
- systemstack(func() {
- stackfree(gp.stack)
- gp.stack.lo = 0
- gp.stack.hi = 0
- gp.stackguard0 = 0
- })
- }
- if gp.stack.lo == 0 {
- // Stack was deallocated in gfput or just above. Allocate a new one.
- systemstack(func() {
- gp.stack = stackalloc(startingStackSize)
- })
- gp.stackguard0 = gp.stack.lo + _StackGuard
- } else {
- if raceenabled {
- racemalloc(unsafe.Pointer(gp.stack.lo), gp.stack.hi-gp.stack.lo)
- }
- if msanenabled {
- msanmalloc(unsafe.Pointer(gp.stack.lo), gp.stack.hi-gp.stack.lo)
- }
- if asanenabled {
- asanunpoison(unsafe.Pointer(gp.stack.lo), gp.stack.hi-gp.stack.lo)
- }
- }
- return gp
-}
-
-// Purge all cached G's from gfree list to the global list.
-func gfpurge(pp *p) {
- var (
- inc int32
- stackQ gQueue
- noStackQ gQueue
- )
- for !pp.gFree.empty() {
- gp := pp.gFree.pop()
- pp.gFree.n--
- if gp.stack.lo == 0 {
- noStackQ.push(gp)
- } else {
- stackQ.push(gp)
- }
- inc++
- }
- lock(&sched.gFree.lock)
- sched.gFree.noStack.pushAll(noStackQ)
- sched.gFree.stack.pushAll(stackQ)
- sched.gFree.n += inc
- unlock(&sched.gFree.lock)
-}
-
-// Breakpoint executes a breakpoint trap.
-func Breakpoint() {
- breakpoint()
-}
-
-// dolockOSThread is called by LockOSThread and lockOSThread below
-// after they modify m.locked. Do not allow preemption during this call,
-// or else the m might be different in this function than in the caller.
-//
-//go:nosplit
-func dolockOSThread() {
- if GOARCH == "wasm" {
- return // no threads on wasm yet
- }
- gp := getg()
- gp.m.lockedg.set(gp)
- gp.lockedm.set(gp.m)
-}
-
-//go:nosplit
-
-// LockOSThread wires the calling goroutine to its current operating system thread.
-// The calling goroutine will always execute in that thread,
-// and no other goroutine will execute in it,
-// until the calling goroutine has made as many calls to
-// UnlockOSThread as to LockOSThread.
-// If the calling goroutine exits without unlocking the thread,
-// the thread will be terminated.
-//
-// All init functions are run on the startup thread. Calling LockOSThread
-// from an init function will cause the main function to be invoked on
-// that thread.
-//
-// A goroutine should call LockOSThread before calling OS services or
-// non-Go library functions that depend on per-thread state.
-func LockOSThread() {
- if atomic.Load(&newmHandoff.haveTemplateThread) == 0 && GOOS != "plan9" {
- // If we need to start a new thread from the locked
- // thread, we need the template thread. Start it now
- // while we're in a known-good state.
- startTemplateThread()
- }
- gp := getg()
- gp.m.lockedExt++
- if gp.m.lockedExt == 0 {
- gp.m.lockedExt--
- panic("LockOSThread nesting overflow")
- }
- dolockOSThread()
-}
-
-//go:nosplit
-func lockOSThread() {
- getg().m.lockedInt++
- dolockOSThread()
-}
-
-// dounlockOSThread is called by UnlockOSThread and unlockOSThread below
-// after they update m->locked. Do not allow preemption during this call,
-// or else the m might be in different in this function than in the caller.
-//
-//go:nosplit
-func dounlockOSThread() {
- if GOARCH == "wasm" {
- return // no threads on wasm yet
- }
- gp := getg()
- if gp.m.lockedInt != 0 || gp.m.lockedExt != 0 {
- return
- }
- gp.m.lockedg = 0
- gp.lockedm = 0
-}
-
-//go:nosplit
-
-// UnlockOSThread undoes an earlier call to LockOSThread.
-// If this drops the number of active LockOSThread calls on the
-// calling goroutine to zero, it unwires the calling goroutine from
-// its fixed operating system thread.
-// If there are no active LockOSThread calls, this is a no-op.
-//
-// Before calling UnlockOSThread, the caller must ensure that the OS
-// thread is suitable for running other goroutines. If the caller made
-// any permanent changes to the state of the thread that would affect
-// other goroutines, it should not call this function and thus leave
-// the goroutine locked to the OS thread until the goroutine (and
-// hence the thread) exits.
-func UnlockOSThread() {
- gp := getg()
- if gp.m.lockedExt == 0 {
- return
- }
- gp.m.lockedExt--
- dounlockOSThread()
-}
-
-//go:nosplit
-func unlockOSThread() {
- gp := getg()
- if gp.m.lockedInt == 0 {
- systemstack(badunlockosthread)
- }
- gp.m.lockedInt--
- dounlockOSThread()
-}
-
-func badunlockosthread() {
- throw("runtime: internal error: misuse of lockOSThread/unlockOSThread")
-}
-
-func gcount() int32 {
- n := int32(atomic.Loaduintptr(&allglen)) - sched.gFree.n - sched.ngsys.Load()
- for _, pp := range allp {
- n -= pp.gFree.n
- }
-
- // All these variables can be changed concurrently, so the result can be inconsistent.
- // But at least the current goroutine is running.
- if n < 1 {
- n = 1
- }
- return n
-}
-
-func mcount() int32 {
- return int32(sched.mnext - sched.nmfreed)
-}
-
-var prof struct {
- signalLock atomic.Uint32
-
- // Must hold signalLock to write. Reads may be lock-free, but
- // signalLock should be taken to synchronize with changes.
- hz atomic.Int32
-}
-
-func _System() { _System() }
-func _ExternalCode() { _ExternalCode() }
-func _LostExternalCode() { _LostExternalCode() }
-func _GC() { _GC() }
-func _LostSIGPROFDuringAtomic64() { _LostSIGPROFDuringAtomic64() }
-func _VDSO() { _VDSO() }
-
-// Called if we receive a SIGPROF signal.
-// Called by the signal handler, may run during STW.
-//
-//go:nowritebarrierrec
-func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
- if prof.hz.Load() == 0 {
- return
- }
-
- // If mp.profilehz is 0, then profiling is not enabled for this thread.
- // We must check this to avoid a deadlock between setcpuprofilerate
- // and the call to cpuprof.add, below.
- if mp != nil && mp.profilehz == 0 {
- return
- }
-
- // On mips{,le}/arm, 64bit atomics are emulated with spinlocks, in
- // runtime/internal/atomic. If SIGPROF arrives while the program is inside
- // the critical section, it creates a deadlock (when writing the sample).
- // As a workaround, create a counter of SIGPROFs while in critical section
- // to store the count, and pass it to sigprof.add() later when SIGPROF is
- // received from somewhere else (with _LostSIGPROFDuringAtomic64 as pc).
- if GOARCH == "mips" || GOARCH == "mipsle" || GOARCH == "arm" {
- if f := findfunc(pc); f.valid() {
- if hasPrefix(funcname(f), "runtime/internal/atomic") {
- cpuprof.lostAtomic++
- return
- }
- }
- if GOARCH == "arm" && goarm < 7 && GOOS == "linux" && pc&0xffff0000 == 0xffff0000 {
- // runtime/internal/atomic functions call into kernel
- // helpers on arm < 7. See
- // runtime/internal/atomic/sys_linux_arm.s.
- cpuprof.lostAtomic++
- return
- }
- }
-
- // Profiling runs concurrently with GC, so it must not allocate.
- // Set a trap in case the code does allocate.
- // Note that on windows, one thread takes profiles of all the
- // other threads, so mp is usually not getg().m.
- // In fact mp may not even be stopped.
- // See golang.org/issue/17165.
- getg().m.mallocing++
-
- var stk [maxCPUProfStack]uintptr
- n := 0
- if mp.ncgo > 0 && mp.curg != nil && mp.curg.syscallpc != 0 && mp.curg.syscallsp != 0 {
- cgoOff := 0
- // Check cgoCallersUse to make sure that we are not
- // interrupting other code that is fiddling with
- // cgoCallers. We are running in a signal handler
- // with all signals blocked, so we don't have to worry
- // about any other code interrupting us.
- if mp.cgoCallersUse.Load() == 0 && mp.cgoCallers != nil && mp.cgoCallers[0] != 0 {
- for cgoOff < len(mp.cgoCallers) && mp.cgoCallers[cgoOff] != 0 {
- cgoOff++
- }
- copy(stk[:], mp.cgoCallers[:cgoOff])
- mp.cgoCallers[0] = 0
- }
-
- // Collect Go stack that leads to the cgo call.
- n = gentraceback(mp.curg.syscallpc, mp.curg.syscallsp, 0, mp.curg, 0, &stk[cgoOff], len(stk)-cgoOff, nil, nil, 0)
- if n > 0 {
- n += cgoOff
- }
- } else if usesLibcall() && mp.libcallg != 0 && mp.libcallpc != 0 && mp.libcallsp != 0 {
- // Libcall, i.e. runtime syscall on windows.
- // Collect Go stack that leads to the call.
- n = gentraceback(mp.libcallpc, mp.libcallsp, 0, mp.libcallg.ptr(), 0, &stk[n], len(stk[n:]), nil, nil, 0)
- } else if mp != nil && mp.vdsoSP != 0 {
- // VDSO call, e.g. nanotime1 on Linux.
- // Collect Go stack that leads to the call.
- n = gentraceback(mp.vdsoPC, mp.vdsoSP, 0, gp, 0, &stk[n], len(stk[n:]), nil, nil, _TraceJumpStack)
- } else {
- n = gentraceback(pc, sp, lr, gp, 0, &stk[0], len(stk), nil, nil, _TraceTrap|_TraceJumpStack)
- }
-
- if n <= 0 {
- // Normal traceback is impossible or has failed.
- // Account it against abstract "System" or "GC".
- n = 2
- if inVDSOPage(pc) {
- pc = abi.FuncPCABIInternal(_VDSO) + sys.PCQuantum
- } else if pc > firstmoduledata.etext {
- // "ExternalCode" is better than "etext".
- pc = abi.FuncPCABIInternal(_ExternalCode) + sys.PCQuantum
- }
- stk[0] = pc
- if mp.preemptoff != "" {
- stk[1] = abi.FuncPCABIInternal(_GC) + sys.PCQuantum
- } else {
- stk[1] = abi.FuncPCABIInternal(_System) + sys.PCQuantum
- }
- }
-
- if prof.hz.Load() != 0 {
- // Note: it can happen on Windows that we interrupted a system thread
- // with no g, so gp could nil. The other nil checks are done out of
- // caution, but not expected to be nil in practice.
- var tagPtr *unsafe.Pointer
- if gp != nil && gp.m != nil && gp.m.curg != nil {
- tagPtr = &gp.m.curg.labels
- }
- cpuprof.add(tagPtr, stk[:n])
-
- gprof := gp
- var pp *p
- if gp != nil && gp.m != nil {
- if gp.m.curg != nil {
- gprof = gp.m.curg
- }
- pp = gp.m.p.ptr()
- }
- traceCPUSample(gprof, pp, stk[:n])
- }
- getg().m.mallocing--
-}
-
-// setcpuprofilerate sets the CPU profiling rate to hz times per second.
-// If hz <= 0, setcpuprofilerate turns off CPU profiling.
-func setcpuprofilerate(hz int32) {
- // Force sane arguments.
- if hz < 0 {
- hz = 0
- }
-
- // Disable preemption, otherwise we can be rescheduled to another thread
- // that has profiling enabled.
- gp := getg()
- gp.m.locks++
-
- // Stop profiler on this thread so that it is safe to lock prof.
- // if a profiling signal came in while we had prof locked,
- // it would deadlock.
- setThreadCPUProfiler(0)
-
- for !prof.signalLock.CompareAndSwap(0, 1) {
- osyield()
- }
- if prof.hz.Load() != hz {
- setProcessCPUProfiler(hz)
- prof.hz.Store(hz)
- }
- prof.signalLock.Store(0)
-
- lock(&sched.lock)
- sched.profilehz = hz
- unlock(&sched.lock)
-
- if hz != 0 {
- setThreadCPUProfiler(hz)
- }
-
- gp.m.locks--
-}
-
-// init initializes pp, which may be a freshly allocated p or a
-// previously destroyed p, and transitions it to status _Pgcstop.
-func (pp *p) init(id int32) {
- pp.id = id
- pp.status = _Pgcstop
- pp.sudogcache = pp.sudogbuf[:0]
- pp.deferpool = pp.deferpoolbuf[:0]
- pp.wbBuf.reset()
- if pp.mcache == nil {
- if id == 0 {
- if mcache0 == nil {
- throw("missing mcache?")
- }
- // Use the bootstrap mcache0. Only one P will get
- // mcache0: the one with ID 0.
- pp.mcache = mcache0
- } else {
- pp.mcache = allocmcache()
- }
- }
- if raceenabled && pp.raceprocctx == 0 {
- if id == 0 {
- pp.raceprocctx = raceprocctx0
- raceprocctx0 = 0 // bootstrap
- } else {
- pp.raceprocctx = raceproccreate()
- }
- }
- lockInit(&pp.timersLock, lockRankTimers)
-
- // This P may get timers when it starts running. Set the mask here
- // since the P may not go through pidleget (notably P 0 on startup).
- timerpMask.set(id)
- // Similarly, we may not go through pidleget before this P starts
- // running if it is P 0 on startup.
- idlepMask.clear(id)
-}
-
-// destroy releases all of the resources associated with pp and
-// transitions it to status _Pdead.
-//
-// sched.lock must be held and the world must be stopped.
-func (pp *p) destroy() {
- assertLockHeld(&sched.lock)
- assertWorldStopped()
-
- // Move all runnable goroutines to the global queue
- for pp.runqhead != pp.runqtail {
- // Pop from tail of local queue
- pp.runqtail--
- gp := pp.runq[pp.runqtail%uint32(len(pp.runq))].ptr()
- // Push onto head of global queue
- globrunqputhead(gp)
- }
- if pp.runnext != 0 {
- globrunqputhead(pp.runnext.ptr())
- pp.runnext = 0
- }
- if len(pp.timers) > 0 {
- plocal := getg().m.p.ptr()
- // The world is stopped, but we acquire timersLock to
- // protect against sysmon calling timeSleepUntil.
- // This is the only case where we hold the timersLock of
- // more than one P, so there are no deadlock concerns.
- lock(&plocal.timersLock)
- lock(&pp.timersLock)
- moveTimers(plocal, pp.timers)
- pp.timers = nil
- pp.numTimers.Store(0)
- pp.deletedTimers.Store(0)
- pp.timer0When.Store(0)
- unlock(&pp.timersLock)
- unlock(&plocal.timersLock)
- }
- // Flush p's write barrier buffer.
- if gcphase != _GCoff {
- wbBufFlush1(pp)
- pp.gcw.dispose()
- }
- for i := range pp.sudogbuf {
- pp.sudogbuf[i] = nil
- }
- pp.sudogcache = pp.sudogbuf[:0]
- for j := range pp.deferpoolbuf {
- pp.deferpoolbuf[j] = nil
- }
- pp.deferpool = pp.deferpoolbuf[:0]
- systemstack(func() {
- for i := 0; i < pp.mspancache.len; i++ {
- // Safe to call since the world is stopped.
- mheap_.spanalloc.free(unsafe.Pointer(pp.mspancache.buf[i]))
- }
- pp.mspancache.len = 0
- lock(&mheap_.lock)
- pp.pcache.flush(&mheap_.pages)
- unlock(&mheap_.lock)
- })
- freemcache(pp.mcache)
- pp.mcache = nil
- gfpurge(pp)
- traceProcFree(pp)
- if raceenabled {
- if pp.timerRaceCtx != 0 {
- // The race detector code uses a callback to fetch
- // the proc context, so arrange for that callback
- // to see the right thing.
- // This hack only works because we are the only
- // thread running.
- mp := getg().m
- phold := mp.p.ptr()
- mp.p.set(pp)
-
- racectxend(pp.timerRaceCtx)
- pp.timerRaceCtx = 0
-
- mp.p.set(phold)
- }
- raceprocdestroy(pp.raceprocctx)
- pp.raceprocctx = 0
- }
- pp.gcAssistTime = 0
- pp.status = _Pdead
-}
-
-// Change number of processors.
-//
-// sched.lock must be held, and the world must be stopped.
-//
-// gcworkbufs must not be being modified by either the GC or the write barrier
-// code, so the GC must not be running if the number of Ps actually changes.
-//
-// Returns list of Ps with local work, they need to be scheduled by the caller.
-func procresize(nprocs int32) *p {
- assertLockHeld(&sched.lock)
- assertWorldStopped()
-
- old := gomaxprocs
- if old < 0 || nprocs <= 0 {
- throw("procresize: invalid arg")
- }
- if trace.enabled {
- traceGomaxprocs(nprocs)
- }
-
- // update statistics
- now := nanotime()
- if sched.procresizetime != 0 {
- sched.totaltime += int64(old) * (now - sched.procresizetime)
- }
- sched.procresizetime = now
-
- maskWords := (nprocs + 31) / 32
-
- // Grow allp if necessary.
- if nprocs > int32(len(allp)) {
- // Synchronize with retake, which could be running
- // concurrently since it doesn't run on a P.
- lock(&allpLock)
- if nprocs <= int32(cap(allp)) {
- allp = allp[:nprocs]
- } else {
- nallp := make([]*p, nprocs)
- // Copy everything up to allp's cap so we
- // never lose old allocated Ps.
- copy(nallp, allp[:cap(allp)])
- allp = nallp
- }
-
- if maskWords <= int32(cap(idlepMask)) {
- idlepMask = idlepMask[:maskWords]
- timerpMask = timerpMask[:maskWords]
- } else {
- nidlepMask := make([]uint32, maskWords)
- // No need to copy beyond len, old Ps are irrelevant.
- copy(nidlepMask, idlepMask)
- idlepMask = nidlepMask
-
- ntimerpMask := make([]uint32, maskWords)
- copy(ntimerpMask, timerpMask)
- timerpMask = ntimerpMask
- }
- unlock(&allpLock)
- }
-
- // initialize new P's
- for i := old; i < nprocs; i++ {
- pp := allp[i]
- if pp == nil {
- pp = new(p)
- }
- pp.init(i)
- atomicstorep(unsafe.Pointer(&allp[i]), unsafe.Pointer(pp))
- }
-
- gp := getg()
- if gp.m.p != 0 && gp.m.p.ptr().id < nprocs {
- // continue to use the current P
- gp.m.p.ptr().status = _Prunning
- gp.m.p.ptr().mcache.prepareForSweep()
- } else {
- // release the current P and acquire allp[0].
- //
- // We must do this before destroying our current P
- // because p.destroy itself has write barriers, so we
- // need to do that from a valid P.
- if gp.m.p != 0 {
- if trace.enabled {
- // Pretend that we were descheduled
- // and then scheduled again to keep
- // the trace sane.
- traceGoSched()
- traceProcStop(gp.m.p.ptr())
- }
- gp.m.p.ptr().m = 0
- }
- gp.m.p = 0
- pp := allp[0]
- pp.m = 0
- pp.status = _Pidle
- acquirep(pp)
- if trace.enabled {
- traceGoStart()
- }
- }
-
- // g.m.p is now set, so we no longer need mcache0 for bootstrapping.
- mcache0 = nil
-
- // release resources from unused P's
- for i := nprocs; i < old; i++ {
- pp := allp[i]
- pp.destroy()
- // can't free P itself because it can be referenced by an M in syscall
- }
-
- // Trim allp.
- if int32(len(allp)) != nprocs {
- lock(&allpLock)
- allp = allp[:nprocs]
- idlepMask = idlepMask[:maskWords]
- timerpMask = timerpMask[:maskWords]
- unlock(&allpLock)
- }
-
- var runnablePs *p
- for i := nprocs - 1; i >= 0; i-- {
- pp := allp[i]
- if gp.m.p.ptr() == pp {
- continue
- }
- pp.status = _Pidle
- if runqempty(pp) {
- pidleput(pp, now)
- } else {
- pp.m.set(mget())
- pp.link.set(runnablePs)
- runnablePs = pp
- }
- }
- stealOrder.reset(uint32(nprocs))
- var int32p *int32 = &gomaxprocs // make compiler check that gomaxprocs is an int32
- atomic.Store((*uint32)(unsafe.Pointer(int32p)), uint32(nprocs))
- if old != nprocs {
- // Notify the limiter that the amount of procs has changed.
- gcCPULimiter.resetCapacity(now, nprocs)
- }
- return runnablePs
-}
-
-// Associate p and the current m.
-//
-// This function is allowed to have write barriers even if the caller
-// isn't because it immediately acquires pp.
-//
-//go:yeswritebarrierrec
-func acquirep(pp *p) {
- // Do the part that isn't allowed to have write barriers.
- wirep(pp)
-
- // Have p; write barriers now allowed.
-
- // Perform deferred mcache flush before this P can allocate
- // from a potentially stale mcache.
- pp.mcache.prepareForSweep()
-
- if trace.enabled {
- traceProcStart()
- }
-}
-
-// wirep is the first step of acquirep, which actually associates the
-// current M to pp. This is broken out so we can disallow write
-// barriers for this part, since we don't yet have a P.
-//
-//go:nowritebarrierrec
-//go:nosplit
-func wirep(pp *p) {
- gp := getg()
-
- if gp.m.p != 0 {
- throw("wirep: already in go")
- }
- if pp.m != 0 || pp.status != _Pidle {
- id := int64(0)
- if pp.m != 0 {
- id = pp.m.ptr().id
- }
- print("wirep: p->m=", pp.m, "(", id, ") p->status=", pp.status, "\n")
- throw("wirep: invalid p state")
- }
- gp.m.p.set(pp)
- pp.m.set(gp.m)
- pp.status = _Prunning
-}
-
-// Disassociate p and the current m.
-func releasep() *p {
- gp := getg()
-
- if gp.m.p == 0 {
- throw("releasep: invalid arg")
- }
- pp := gp.m.p.ptr()
- if pp.m.ptr() != gp.m || pp.status != _Prunning {
- print("releasep: m=", gp.m, " m->p=", gp.m.p.ptr(), " p->m=", hex(pp.m), " p->status=", pp.status, "\n")
- throw("releasep: invalid p state")
- }
- if trace.enabled {
- traceProcStop(gp.m.p.ptr())
- }
- gp.m.p = 0
- pp.m = 0
- pp.status = _Pidle
- return pp
-}
-
-func incidlelocked(v int32) {
- lock(&sched.lock)
- sched.nmidlelocked += v
- if v > 0 {
- checkdead()
- }
- unlock(&sched.lock)
-}
-
-// Check for deadlock situation.
-// The check is based on number of running M's, if 0 -> deadlock.
-// sched.lock must be held.
-func checkdead() {
- assertLockHeld(&sched.lock)
-
- // For -buildmode=c-shared or -buildmode=c-archive it's OK if
- // there are no running goroutines. The calling program is
- // assumed to be running.
- if islibrary || isarchive {
- return
- }
-
- // If we are dying because of a signal caught on an already idle thread,
- // freezetheworld will cause all running threads to block.
- // And runtime will essentially enter into deadlock state,
- // except that there is a thread that will call exit soon.
- if panicking.Load() > 0 {
- return
- }
-
- // If we are not running under cgo, but we have an extra M then account
- // for it. (It is possible to have an extra M on Windows without cgo to
- // accommodate callbacks created by syscall.NewCallback. See issue #6751
- // for details.)
- var run0 int32
- if !iscgo && cgoHasExtraM {
- mp := lockextra(true)
- haveExtraM := extraMCount > 0
- unlockextra(mp)
- if haveExtraM {
- run0 = 1
- }
- }
-
- run := mcount() - sched.nmidle - sched.nmidlelocked - sched.nmsys
- if run > run0 {
- return
- }
- if run < 0 {
- print("runtime: checkdead: nmidle=", sched.nmidle, " nmidlelocked=", sched.nmidlelocked, " mcount=", mcount(), " nmsys=", sched.nmsys, "\n")
- throw("checkdead: inconsistent counts")
- }
-
- grunning := 0
- forEachG(func(gp *g) {
- if isSystemGoroutine(gp, false) {
- return
- }
- s := readgstatus(gp)
- switch s &^ _Gscan {
- case _Gwaiting,
- _Gpreempted:
- grunning++
- case _Grunnable,
- _Grunning,
- _Gsyscall:
- print("runtime: checkdead: find g ", gp.goid, " in status ", s, "\n")
- throw("checkdead: runnable g")
- }
- })
- if grunning == 0 { // possible if main goroutine calls runtime·Goexit()
- unlock(&sched.lock) // unlock so that GODEBUG=scheddetail=1 doesn't hang
- fatal("no goroutines (main called runtime.Goexit) - deadlock!")
- }
-
- // Maybe jump time forward for playground.
- if faketime != 0 {
- if when := timeSleepUntil(); when < maxWhen {
- faketime = when
-
- // Start an M to steal the timer.
- pp, _ := pidleget(faketime)
- if pp == nil {
- // There should always be a free P since
- // nothing is running.
- throw("checkdead: no p for timer")
- }
- mp := mget()
- if mp == nil {
- // There should always be a free M since
- // nothing is running.
- throw("checkdead: no m for timer")
- }
- // M must be spinning to steal. We set this to be
- // explicit, but since this is the only M it would
- // become spinning on its own anyways.
- sched.nmspinning.Add(1)
- mp.spinning = true
- mp.nextp.set(pp)
- notewakeup(&mp.park)
- return
- }
- }
-
- // There are no goroutines running, so we can look at the P's.
- for _, pp := range allp {
- if len(pp.timers) > 0 {
- return
- }
- }
-
- unlock(&sched.lock) // unlock so that GODEBUG=scheddetail=1 doesn't hang
- fatal("all goroutines are asleep - deadlock!")
-}
-
-// forcegcperiod is the maximum time in nanoseconds between garbage
-// collections. If we go this long without a garbage collection, one
-// is forced to run.
-//
-// This is a variable for testing purposes. It normally doesn't change.
-var forcegcperiod int64 = 2 * 60 * 1e9
-
-// needSysmonWorkaround is true if the workaround for
-// golang.org/issue/42515 is needed on NetBSD.
-var needSysmonWorkaround bool = false
-
-// Always runs without a P, so write barriers are not allowed.
-//
-//go:nowritebarrierrec
-func sysmon() {
- lock(&sched.lock)
- sched.nmsys++
- checkdead()
- unlock(&sched.lock)
-
- lasttrace := int64(0)
- idle := 0 // how many cycles in succession we had not wokeup somebody
- delay := uint32(0)
-
- for {
- if idle == 0 { // start with 20us sleep...
- delay = 20
- } else if idle > 50 { // start doubling the sleep after 1ms...
- delay *= 2
- }
- if delay > 10*1000 { // up to 10ms
- delay = 10 * 1000
- }
- usleep(delay)
-
- // sysmon should not enter deep sleep if schedtrace is enabled so that
- // it can print that information at the right time.
- //
- // It should also not enter deep sleep if there are any active P's so
- // that it can retake P's from syscalls, preempt long running G's, and
- // poll the network if all P's are busy for long stretches.
- //
- // It should wakeup from deep sleep if any P's become active either due
- // to exiting a syscall or waking up due to a timer expiring so that it
- // can resume performing those duties. If it wakes from a syscall it
- // resets idle and delay as a bet that since it had retaken a P from a
- // syscall before, it may need to do it again shortly after the
- // application starts work again. It does not reset idle when waking
- // from a timer to avoid adding system load to applications that spend
- // most of their time sleeping.
- now := nanotime()
- if debug.schedtrace <= 0 && (sched.gcwaiting.Load() || sched.npidle.Load() == gomaxprocs) {
- lock(&sched.lock)
- if sched.gcwaiting.Load() || sched.npidle.Load() == gomaxprocs {
- syscallWake := false
- next := timeSleepUntil()
- if next > now {
- sched.sysmonwait.Store(true)
- unlock(&sched.lock)
- // Make wake-up period small enough
- // for the sampling to be correct.
- sleep := forcegcperiod / 2
- if next-now < sleep {
- sleep = next - now
- }
- shouldRelax := sleep >= osRelaxMinNS
- if shouldRelax {
- osRelax(true)
- }
- syscallWake = notetsleep(&sched.sysmonnote, sleep)
- if shouldRelax {
- osRelax(false)
- }
- lock(&sched.lock)
- sched.sysmonwait.Store(false)
- noteclear(&sched.sysmonnote)
- }
- if syscallWake {
- idle = 0
- delay = 20
- }
- }
- unlock(&sched.lock)
- }
-
- lock(&sched.sysmonlock)
- // Update now in case we blocked on sysmonnote or spent a long time
- // blocked on schedlock or sysmonlock above.
- now = nanotime()
-
- // trigger libc interceptors if needed
- if *cgo_yield != nil {
- asmcgocall(*cgo_yield, nil)
- }
- // poll network if not polled for more than 10ms
- lastpoll := sched.lastpoll.Load()
- if netpollinited() && lastpoll != 0 && lastpoll+10*1000*1000 < now {
- sched.lastpoll.CompareAndSwap(lastpoll, now)
- list := netpoll(0) // non-blocking - returns list of goroutines
- if !list.empty() {
- // Need to decrement number of idle locked M's
- // (pretending that one more is running) before injectglist.
- // Otherwise it can lead to the following situation:
- // injectglist grabs all P's but before it starts M's to run the P's,
- // another M returns from syscall, finishes running its G,
- // observes that there is no work to do and no other running M's
- // and reports deadlock.
- incidlelocked(-1)
- injectglist(&list)
- incidlelocked(1)
- }
- }
- if GOOS == "netbsd" && needSysmonWorkaround {
- // netpoll is responsible for waiting for timer
- // expiration, so we typically don't have to worry
- // about starting an M to service timers. (Note that
- // sleep for timeSleepUntil above simply ensures sysmon
- // starts running again when that timer expiration may
- // cause Go code to run again).
- //
- // However, netbsd has a kernel bug that sometimes
- // misses netpollBreak wake-ups, which can lead to
- // unbounded delays servicing timers. If we detect this
- // overrun, then startm to get something to handle the
- // timer.
- //
- // See issue 42515 and
- // https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=50094.
- if next := timeSleepUntil(); next < now {
- startm(nil, false, false)
- }
- }
- if scavenger.sysmonWake.Load() != 0 {
- // Kick the scavenger awake if someone requested it.
- scavenger.wake()
- }
- // retake P's blocked in syscalls
- // and preempt long running G's
- if retake(now) != 0 {
- idle = 0
- } else {
- idle++
- }
- // check if we need to force a GC
- if t := (gcTrigger{kind: gcTriggerTime, now: now}); t.test() && forcegc.idle.Load() {
- lock(&forcegc.lock)
- forcegc.idle.Store(false)
- var list gList
- list.push(forcegc.g)
- injectglist(&list)
- unlock(&forcegc.lock)
- }
- if debug.schedtrace > 0 && lasttrace+int64(debug.schedtrace)*1000000 <= now {
- lasttrace = now
- schedtrace(debug.scheddetail > 0)
- }
- unlock(&sched.sysmonlock)
- }
-}
-
-type sysmontick struct {
- schedtick uint32
- schedwhen int64
- syscalltick uint32
- syscallwhen int64
-}
-
-// forcePreemptNS is the time slice given to a G before it is
-// preempted.
-const forcePreemptNS = 10 * 1000 * 1000 // 10ms
-
-func retake(now int64) uint32 {
- n := 0
- // Prevent allp slice changes. This lock will be completely
- // uncontended unless we're already stopping the world.
- lock(&allpLock)
- // We can't use a range loop over allp because we may
- // temporarily drop the allpLock. Hence, we need to re-fetch
- // allp each time around the loop.
- for i := 0; i < len(allp); i++ {
- pp := allp[i]
- if pp == nil {
- // This can happen if procresize has grown
- // allp but not yet created new Ps.
- continue
- }
- pd := &pp.sysmontick
- s := pp.status
- sysretake := false
- if s == _Prunning || s == _Psyscall {
- // Preempt G if it's running for too long.
- t := int64(pp.schedtick)
- if int64(pd.schedtick) != t {
- pd.schedtick = uint32(t)
- pd.schedwhen = now
- } else if pd.schedwhen+forcePreemptNS <= now {
- preemptone(pp)
- // In case of syscall, preemptone() doesn't
- // work, because there is no M wired to P.
- sysretake = true
- }
- }
- if s == _Psyscall {
- // Retake P from syscall if it's there for more than 1 sysmon tick (at least 20us).
- t := int64(pp.syscalltick)
- if !sysretake && int64(pd.syscalltick) != t {
- pd.syscalltick = uint32(t)
- pd.syscallwhen = now
- continue
- }
- // On the one hand we don't want to retake Ps if there is no other work to do,
- // but on the other hand we want to retake them eventually
- // because they can prevent the sysmon thread from deep sleep.
- if runqempty(pp) && sched.nmspinning.Load()+sched.npidle.Load() > 0 && pd.syscallwhen+10*1000*1000 > now {
- continue
- }
- // Drop allpLock so we can take sched.lock.
- unlock(&allpLock)
- // Need to decrement number of idle locked M's
- // (pretending that one more is running) before the CAS.
- // Otherwise the M from which we retake can exit the syscall,
- // increment nmidle and report deadlock.
- incidlelocked(-1)
- if atomic.Cas(&pp.status, s, _Pidle) {
- if trace.enabled {
- traceGoSysBlock(pp)
- traceProcStop(pp)
- }
- n++
- pp.syscalltick++
- handoffp(pp)
- }
- incidlelocked(1)
- lock(&allpLock)
- }
- }
- unlock(&allpLock)
- return uint32(n)
-}
-
-// Tell all goroutines that they have been preempted and they should stop.
-// This function is purely best-effort. It can fail to inform a goroutine if a
-// processor just started running it.
-// No locks need to be held.
-// Returns true if preemption request was issued to at least one goroutine.
-func preemptall() bool {
- res := false
- for _, pp := range allp {
- if pp.status != _Prunning {
- continue
- }
- if preemptone(pp) {
- res = true
- }
- }
- return res
-}
-
-// Tell the goroutine running on processor P to stop.
-// This function is purely best-effort. It can incorrectly fail to inform the
-// goroutine. It can inform the wrong goroutine. Even if it informs the
-// correct goroutine, that goroutine might ignore the request if it is
-// simultaneously executing newstack.
-// No lock needs to be held.
-// Returns true if preemption request was issued.
-// The actual preemption will happen at some point in the future
-// and will be indicated by the gp->status no longer being
-// Grunning
-func preemptone(pp *p) bool {
- mp := pp.m.ptr()
- if mp == nil || mp == getg().m {
- return false
- }
- gp := mp.curg
- if gp == nil || gp == mp.g0 {
- return false
- }
-
- gp.preempt = true
-
- // Every call in a goroutine checks for stack overflow by
- // comparing the current stack pointer to gp->stackguard0.
- // Setting gp->stackguard0 to StackPreempt folds
- // preemption into the normal stack overflow check.
- gp.stackguard0 = stackPreempt
-
- // Request an async preemption of this P.
- if preemptMSupported && debug.asyncpreemptoff == 0 {
- pp.preempt = true
- preemptM(mp)
- }
-
- return true
-}
-
-var starttime int64
-
-func schedtrace(detailed bool) {
- now := nanotime()
- if starttime == 0 {
- starttime = now
- }
-
- lock(&sched.lock)
- print("SCHED ", (now-starttime)/1e6, "ms: gomaxprocs=", gomaxprocs, " idleprocs=", sched.npidle.Load(), " threads=", mcount(), " spinningthreads=", sched.nmspinning.Load(), " needspinning=", sched.needspinning.Load(), " idlethreads=", sched.nmidle, " runqueue=", sched.runqsize)
- if detailed {
- print(" gcwaiting=", sched.gcwaiting.Load(), " nmidlelocked=", sched.nmidlelocked, " stopwait=", sched.stopwait, " sysmonwait=", sched.sysmonwait.Load(), "\n")
- }
- // We must be careful while reading data from P's, M's and G's.
- // Even if we hold schedlock, most data can be changed concurrently.
- // E.g. (p->m ? p->m->id : -1) can crash if p->m changes from non-nil to nil.
- for i, pp := range allp {
- mp := pp.m.ptr()
- h := atomic.Load(&pp.runqhead)
- t := atomic.Load(&pp.runqtail)
- if detailed {
- print(" P", i, ": status=", pp.status, " schedtick=", pp.schedtick, " syscalltick=", pp.syscalltick, " m=")
- if mp != nil {
- print(mp.id)
- } else {
- print("nil")
- }
- print(" runqsize=", t-h, " gfreecnt=", pp.gFree.n, " timerslen=", len(pp.timers), "\n")
- } else {
- // In non-detailed mode format lengths of per-P run queues as:
- // [len1 len2 len3 len4]
- print(" ")
- if i == 0 {
- print("[")
- }
- print(t - h)
- if i == len(allp)-1 {
- print("]\n")
- }
- }
- }
-
- if !detailed {
- unlock(&sched.lock)
- return
- }
-
- for mp := allm; mp != nil; mp = mp.alllink {
- pp := mp.p.ptr()
- print(" M", mp.id, ": p=")
- if pp != nil {
- print(pp.id)
- } else {
- print("nil")
- }
- print(" curg=")
- if mp.curg != nil {
- print(mp.curg.goid)
- } else {
- print("nil")
- }
- print(" mallocing=", mp.mallocing, " throwing=", mp.throwing, " preemptoff=", mp.preemptoff, " locks=", mp.locks, " dying=", mp.dying, " spinning=", mp.spinning, " blocked=", mp.blocked, " lockedg=")
- if lockedg := mp.lockedg.ptr(); lockedg != nil {
- print(lockedg.goid)
- } else {
- print("nil")
- }
- print("\n")
- }
-
- forEachG(func(gp *g) {
- print(" G", gp.goid, ": status=", readgstatus(gp), "(", gp.waitreason.String(), ") m=")
- if gp.m != nil {
- print(gp.m.id)
- } else {
- print("nil")
- }
- print(" lockedm=")
- if lockedm := gp.lockedm.ptr(); lockedm != nil {
- print(lockedm.id)
- } else {
- print("nil")
- }
- print("\n")
- })
- unlock(&sched.lock)
-}
-
-// schedEnableUser enables or disables the scheduling of user
-// goroutines.
-//
-// This does not stop already running user goroutines, so the caller
-// should first stop the world when disabling user goroutines.
-func schedEnableUser(enable bool) {
- lock(&sched.lock)
- if sched.disable.user == !enable {
- unlock(&sched.lock)
- return
- }
- sched.disable.user = !enable
- if enable {
- n := sched.disable.n
- sched.disable.n = 0
- globrunqputbatch(&sched.disable.runnable, n)
- unlock(&sched.lock)
- for ; n != 0 && sched.npidle.Load() != 0; n-- {
- startm(nil, false, false)
- }
- } else {
- unlock(&sched.lock)
- }
-}
-
-// schedEnabled reports whether gp should be scheduled. It returns
-// false is scheduling of gp is disabled.
-//
-// sched.lock must be held.
-func schedEnabled(gp *g) bool {
- assertLockHeld(&sched.lock)
-
- if sched.disable.user {
- return isSystemGoroutine(gp, true)
- }
- return true
-}
-
-// Put mp on midle list.
-// sched.lock must be held.
-// May run during STW, so write barriers are not allowed.
-//
-//go:nowritebarrierrec
-func mput(mp *m) {
- assertLockHeld(&sched.lock)
-
- mp.schedlink = sched.midle
- sched.midle.set(mp)
- sched.nmidle++
- checkdead()
-}
-
-// Try to get an m from midle list.
-// sched.lock must be held.
-// May run during STW, so write barriers are not allowed.
-//
-//go:nowritebarrierrec
-func mget() *m {
- assertLockHeld(&sched.lock)
-
- mp := sched.midle.ptr()
- if mp != nil {
- sched.midle = mp.schedlink
- sched.nmidle--
- }
- return mp
-}
-
-// Put gp on the global runnable queue.
-// sched.lock must be held.
-// May run during STW, so write barriers are not allowed.
-//
-//go:nowritebarrierrec
-func globrunqput(gp *g) {
- assertLockHeld(&sched.lock)
-
- sched.runq.pushBack(gp)
- sched.runqsize++
-}
-
-// Put gp at the head of the global runnable queue.
-// sched.lock must be held.
-// May run during STW, so write barriers are not allowed.
-//
-//go:nowritebarrierrec
-func globrunqputhead(gp *g) {
- assertLockHeld(&sched.lock)
-
- sched.runq.push(gp)
- sched.runqsize++
-}
-
-// Put a batch of runnable goroutines on the global runnable queue.
-// This clears *batch.
-// sched.lock must be held.
-// May run during STW, so write barriers are not allowed.
-//
-//go:nowritebarrierrec
-func globrunqputbatch(batch *gQueue, n int32) {
- assertLockHeld(&sched.lock)
-
- sched.runq.pushBackAll(*batch)
- sched.runqsize += n
- *batch = gQueue{}
-}
-
-// Try get a batch of G's from the global runnable queue.
-// sched.lock must be held.
-func globrunqget(pp *p, max int32) *g {
- assertLockHeld(&sched.lock)
-
- if sched.runqsize == 0 {
- return nil
- }
-
- n := sched.runqsize/gomaxprocs + 1
- if n > sched.runqsize {
- n = sched.runqsize
- }
- if max > 0 && n > max {
- n = max
- }
- if n > int32(len(pp.runq))/2 {
- n = int32(len(pp.runq)) / 2
- }
-
- sched.runqsize -= n
-
- gp := sched.runq.pop()
- n--
- for ; n > 0; n-- {
- gp1 := sched.runq.pop()
- runqput(pp, gp1, false)
- }
- return gp
-}
-
-// pMask is an atomic bitstring with one bit per P.
-type pMask []uint32
-
-// read returns true if P id's bit is set.
-func (p pMask) read(id uint32) bool {
- word := id / 32
- mask := uint32(1) << (id % 32)
- return (atomic.Load(&p[word]) & mask) != 0
-}
-
-// set sets P id's bit.
-func (p pMask) set(id int32) {
- word := id / 32
- mask := uint32(1) << (id % 32)
- atomic.Or(&p[word], mask)
-}
-
-// clear clears P id's bit.
-func (p pMask) clear(id int32) {
- word := id / 32
- mask := uint32(1) << (id % 32)
- atomic.And(&p[word], ^mask)
-}
-
-// updateTimerPMask clears pp's timer mask if it has no timers on its heap.
-//
-// Ideally, the timer mask would be kept immediately consistent on any timer
-// operations. Unfortunately, updating a shared global data structure in the
-// timer hot path adds too much overhead in applications frequently switching
-// between no timers and some timers.
-//
-// As a compromise, the timer mask is updated only on pidleget / pidleput. A
-// running P (returned by pidleget) may add a timer at any time, so its mask
-// must be set. An idle P (passed to pidleput) cannot add new timers while
-// idle, so if it has no timers at that time, its mask may be cleared.
-//
-// Thus, we get the following effects on timer-stealing in findrunnable:
-//
-// - Idle Ps with no timers when they go idle are never checked in findrunnable
-// (for work- or timer-stealing; this is the ideal case).
-// - Running Ps must always be checked.
-// - Idle Ps whose timers are stolen must continue to be checked until they run
-// again, even after timer expiration.
-//
-// When the P starts running again, the mask should be set, as a timer may be
-// added at any time.
-//
-// TODO(prattmic): Additional targeted updates may improve the above cases.
-// e.g., updating the mask when stealing a timer.
-func updateTimerPMask(pp *p) {
- if pp.numTimers.Load() > 0 {
- return
- }
-
- // Looks like there are no timers, however another P may transiently
- // decrement numTimers when handling a timerModified timer in
- // checkTimers. We must take timersLock to serialize with these changes.
- lock(&pp.timersLock)
- if pp.numTimers.Load() == 0 {
- timerpMask.clear(pp.id)
- }
- unlock(&pp.timersLock)
-}
-
-// pidleput puts p on the _Pidle list. now must be a relatively recent call
-// to nanotime or zero. Returns now or the current time if now was zero.
-//
-// This releases ownership of p. Once sched.lock is released it is no longer
-// safe to use p.
-//
-// sched.lock must be held.
-//
-// May run during STW, so write barriers are not allowed.
-//
-//go:nowritebarrierrec
-func pidleput(pp *p, now int64) int64 {
- assertLockHeld(&sched.lock)
-
- if !runqempty(pp) {
- throw("pidleput: P has non-empty run queue")
- }
- if now == 0 {
- now = nanotime()
- }
- updateTimerPMask(pp) // clear if there are no timers.
- idlepMask.set(pp.id)
- pp.link = sched.pidle
- sched.pidle.set(pp)
- sched.npidle.Add(1)
- if !pp.limiterEvent.start(limiterEventIdle, now) {
- throw("must be able to track idle limiter event")
- }
- return now
-}
-
-// pidleget tries to get a p from the _Pidle list, acquiring ownership.
-//
-// sched.lock must be held.
-//
-// May run during STW, so write barriers are not allowed.
-//
-//go:nowritebarrierrec
-func pidleget(now int64) (*p, int64) {
- assertLockHeld(&sched.lock)
-
- pp := sched.pidle.ptr()
- if pp != nil {
- // Timer may get added at any time now.
- if now == 0 {
- now = nanotime()
- }
- timerpMask.set(pp.id)
- idlepMask.clear(pp.id)
- sched.pidle = pp.link
- sched.npidle.Add(-1)
- pp.limiterEvent.stop(limiterEventIdle, now)
- }
- return pp, now
-}
-
-// pidlegetSpinning tries to get a p from the _Pidle list, acquiring ownership.
-// This is called by spinning Ms (or callers than need a spinning M) that have
-// found work. If no P is available, this must synchronized with non-spinning
-// Ms that may be preparing to drop their P without discovering this work.
-//
-// sched.lock must be held.
-//
-// May run during STW, so write barriers are not allowed.
-//
-//go:nowritebarrierrec
-func pidlegetSpinning(now int64) (*p, int64) {
- assertLockHeld(&sched.lock)
-
- pp, now := pidleget(now)
- if pp == nil {
- // See "Delicate dance" comment in findrunnable. We found work
- // that we cannot take, we must synchronize with non-spinning
- // Ms that may be preparing to drop their P.
- sched.needspinning.Store(1)
- return nil, now
- }
-
- return pp, now
-}
-
-// runqempty reports whether pp has no Gs on its local run queue.
-// It never returns true spuriously.
-func runqempty(pp *p) bool {
- // Defend against a race where 1) pp has G1 in runqnext but runqhead == runqtail,
- // 2) runqput on pp kicks G1 to the runq, 3) runqget on pp empties runqnext.
- // Simply observing that runqhead == runqtail and then observing that runqnext == nil
- // does not mean the queue is empty.
- for {
- head := atomic.Load(&pp.runqhead)
- tail := atomic.Load(&pp.runqtail)
- runnext := atomic.Loaduintptr((*uintptr)(unsafe.Pointer(&pp.runnext)))
- if tail == atomic.Load(&pp.runqtail) {
- return head == tail && runnext == 0
- }
- }
-}
-
-// To shake out latent assumptions about scheduling order,
-// we introduce some randomness into scheduling decisions
-// when running with the race detector.
-// The need for this was made obvious by changing the
-// (deterministic) scheduling order in Go 1.5 and breaking
-// many poorly-written tests.
-// With the randomness here, as long as the tests pass
-// consistently with -race, they shouldn't have latent scheduling
-// assumptions.
-const randomizeScheduler = raceenabled
-
-// runqput tries to put g on the local runnable queue.
-// If next is false, runqput adds g to the tail of the runnable queue.
-// If next is true, runqput puts g in the pp.runnext slot.
-// If the run queue is full, runnext puts g on the global queue.
-// Executed only by the owner P.
-func runqput(pp *p, gp *g, next bool) {
- if randomizeScheduler && next && fastrandn(2) == 0 {
- next = false
- }
-
- if next {
- retryNext:
- oldnext := pp.runnext
- if !pp.runnext.cas(oldnext, guintptr(unsafe.Pointer(gp))) {
- goto retryNext
- }
- if oldnext == 0 {
- return
- }
- // Kick the old runnext out to the regular run queue.
- gp = oldnext.ptr()
- }
-
-retry:
- h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with consumers
- t := pp.runqtail
- if t-h < uint32(len(pp.runq)) {
- pp.runq[t%uint32(len(pp.runq))].set(gp)
- atomic.StoreRel(&pp.runqtail, t+1) // store-release, makes the item available for consumption
- return
- }
- if runqputslow(pp, gp, h, t) {
- return
- }
- // the queue is not full, now the put above must succeed
- goto retry
-}
-
-// Put g and a batch of work from local runnable queue on global queue.
-// Executed only by the owner P.
-func runqputslow(pp *p, gp *g, h, t uint32) bool {
- var batch [len(pp.runq)/2 + 1]*g
-
- // First, grab a batch from local queue.
- n := t - h
- n = n / 2
- if n != uint32(len(pp.runq)/2) {
- throw("runqputslow: queue is not full")
- }
- for i := uint32(0); i < n; i++ {
- batch[i] = pp.runq[(h+i)%uint32(len(pp.runq))].ptr()
- }
- if !atomic.CasRel(&pp.runqhead, h, h+n) { // cas-release, commits consume
- return false
- }
- batch[n] = gp
-
- if randomizeScheduler {
- for i := uint32(1); i <= n; i++ {
- j := fastrandn(i + 1)
- batch[i], batch[j] = batch[j], batch[i]
- }
- }
-
- // Link the goroutines.
- for i := uint32(0); i < n; i++ {
- batch[i].schedlink.set(batch[i+1])
- }
- var q gQueue
- q.head.set(batch[0])
- q.tail.set(batch[n])
-
- // Now put the batch on global queue.
- lock(&sched.lock)
- globrunqputbatch(&q, int32(n+1))
- unlock(&sched.lock)
- return true
-}
-
-// runqputbatch tries to put all the G's on q on the local runnable queue.
-// If the queue is full, they are put on the global queue; in that case
-// this will temporarily acquire the scheduler lock.
-// Executed only by the owner P.
-func runqputbatch(pp *p, q *gQueue, qsize int) {
- h := atomic.LoadAcq(&pp.runqhead)
- t := pp.runqtail
- n := uint32(0)
- for !q.empty() && t-h < uint32(len(pp.runq)) {
- gp := q.pop()
- pp.runq[t%uint32(len(pp.runq))].set(gp)
- t++
- n++
- }
- qsize -= int(n)
-
- if randomizeScheduler {
- off := func(o uint32) uint32 {
- return (pp.runqtail + o) % uint32(len(pp.runq))
- }
- for i := uint32(1); i < n; i++ {
- j := fastrandn(i + 1)
- pp.runq[off(i)], pp.runq[off(j)] = pp.runq[off(j)], pp.runq[off(i)]
- }
- }
-
- atomic.StoreRel(&pp.runqtail, t)
- if !q.empty() {
- lock(&sched.lock)
- globrunqputbatch(q, int32(qsize))
- unlock(&sched.lock)
- }
-}
-
-// Get g from local runnable queue.
-// If inheritTime is true, gp should inherit the remaining time in the
-// current time slice. Otherwise, it should start a new time slice.
-// Executed only by the owner P.
-func runqget(pp *p) (gp *g, inheritTime bool) {
- // If there's a runnext, it's the next G to run.
- next := pp.runnext
- // If the runnext is non-0 and the CAS fails, it could only have been stolen by another P,
- // because other Ps can race to set runnext to 0, but only the current P can set it to non-0.
- // Hence, there's no need to retry this CAS if it fails.
- if next != 0 && pp.runnext.cas(next, 0) {
- return next.ptr(), true
- }
-
- for {
- h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with other consumers
- t := pp.runqtail
- if t == h {
- return nil, false
- }
- gp := pp.runq[h%uint32(len(pp.runq))].ptr()
- if atomic.CasRel(&pp.runqhead, h, h+1) { // cas-release, commits consume
- return gp, false
- }
- }
-}
-
-// runqdrain drains the local runnable queue of pp and returns all goroutines in it.
-// Executed only by the owner P.
-func runqdrain(pp *p) (drainQ gQueue, n uint32) {
- oldNext := pp.runnext
- if oldNext != 0 && pp.runnext.cas(oldNext, 0) {
- drainQ.pushBack(oldNext.ptr())
- n++
- }
-
-retry:
- h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with other consumers
- t := pp.runqtail
- qn := t - h
- if qn == 0 {
- return
- }
- if qn > uint32(len(pp.runq)) { // read inconsistent h and t
- goto retry
- }
-
- if !atomic.CasRel(&pp.runqhead, h, h+qn) { // cas-release, commits consume
- goto retry
- }
-
- // We've inverted the order in which it gets G's from the local P's runnable queue
- // and then advances the head pointer because we don't want to mess up the statuses of G's
- // while runqdrain() and runqsteal() are running in parallel.
- // Thus we should advance the head pointer before draining the local P into a gQueue,
- // so that we can update any gp.schedlink only after we take the full ownership of G,
- // meanwhile, other P's can't access to all G's in local P's runnable queue and steal them.
- // See https://groups.google.com/g/golang-dev/c/0pTKxEKhHSc/m/6Q85QjdVBQAJ for more details.
- for i := uint32(0); i < qn; i++ {
- gp := pp.runq[(h+i)%uint32(len(pp.runq))].ptr()
- drainQ.pushBack(gp)
- n++
- }
- return
-}
-
-// Grabs a batch of goroutines from pp's runnable queue into batch.
-// Batch is a ring buffer starting at batchHead.
-// Returns number of grabbed goroutines.
-// Can be executed by any P.
-func runqgrab(pp *p, batch *[256]guintptr, batchHead uint32, stealRunNextG bool) uint32 {
- for {
- h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with other consumers
- t := atomic.LoadAcq(&pp.runqtail) // load-acquire, synchronize with the producer
- n := t - h
- n = n - n/2
- if n == 0 {
- if stealRunNextG {
- // Try to steal from pp.runnext.
- if next := pp.runnext; next != 0 {
- if pp.status == _Prunning {
- // Sleep to ensure that pp isn't about to run the g
- // we are about to steal.
- // The important use case here is when the g running
- // on pp ready()s another g and then almost
- // immediately blocks. Instead of stealing runnext
- // in this window, back off to give pp a chance to
- // schedule runnext. This will avoid thrashing gs
- // between different Ps.
- // A sync chan send/recv takes ~50ns as of time of
- // writing, so 3us gives ~50x overshoot.
- if GOOS != "windows" && GOOS != "openbsd" && GOOS != "netbsd" {
- usleep(3)
- } else {
- // On some platforms system timer granularity is
- // 1-15ms, which is way too much for this
- // optimization. So just yield.
- osyield()
- }
- }
- if !pp.runnext.cas(next, 0) {
- continue
- }
- batch[batchHead%uint32(len(batch))] = next
- return 1
- }
- }
- return 0
- }
- if n > uint32(len(pp.runq)/2) { // read inconsistent h and t
- continue
- }
- for i := uint32(0); i < n; i++ {
- g := pp.runq[(h+i)%uint32(len(pp.runq))]
- batch[(batchHead+i)%uint32(len(batch))] = g
- }
- if atomic.CasRel(&pp.runqhead, h, h+n) { // cas-release, commits consume
- return n
- }
- }
-}
-
-// Steal half of elements from local runnable queue of p2
-// and put onto local runnable queue of p.
-// Returns one of the stolen elements (or nil if failed).
-func runqsteal(pp, p2 *p, stealRunNextG bool) *g {
- t := pp.runqtail
- n := runqgrab(p2, &pp.runq, t, stealRunNextG)
- if n == 0 {
- return nil
- }
- n--
- gp := pp.runq[(t+n)%uint32(len(pp.runq))].ptr()
- if n == 0 {
- return gp
- }
- h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with consumers
- if t-h+n >= uint32(len(pp.runq)) {
- throw("runqsteal: runq overflow")
- }
- atomic.StoreRel(&pp.runqtail, t+n) // store-release, makes the item available for consumption
- return gp
-}
-
-// A gQueue is a dequeue of Gs linked through g.schedlink. A G can only
-// be on one gQueue or gList at a time.
-type gQueue struct {
- head guintptr
- tail guintptr
-}
-
-// empty reports whether q is empty.
-func (q *gQueue) empty() bool {
- return q.head == 0
-}
-
-// push adds gp to the head of q.
-func (q *gQueue) push(gp *g) {
- gp.schedlink = q.head
- q.head.set(gp)
- if q.tail == 0 {
- q.tail.set(gp)
- }
-}
-
-// pushBack adds gp to the tail of q.
-func (q *gQueue) pushBack(gp *g) {
- gp.schedlink = 0
- if q.tail != 0 {
- q.tail.ptr().schedlink.set(gp)
- } else {
- q.head.set(gp)
- }
- q.tail.set(gp)
-}
-
-// pushBackAll adds all Gs in q2 to the tail of q. After this q2 must
-// not be used.
-func (q *gQueue) pushBackAll(q2 gQueue) {
- if q2.tail == 0 {
- return
- }
- q2.tail.ptr().schedlink = 0
- if q.tail != 0 {
- q.tail.ptr().schedlink = q2.head
- } else {
- q.head = q2.head
- }
- q.tail = q2.tail
-}
-
-// pop removes and returns the head of queue q. It returns nil if
-// q is empty.
-func (q *gQueue) pop() *g {
- gp := q.head.ptr()
- if gp != nil {
- q.head = gp.schedlink
- if q.head == 0 {
- q.tail = 0
- }
- }
- return gp
-}
-
-// popList takes all Gs in q and returns them as a gList.
-func (q *gQueue) popList() gList {
- stack := gList{q.head}
- *q = gQueue{}
- return stack
-}
-
-// A gList is a list of Gs linked through g.schedlink. A G can only be
-// on one gQueue or gList at a time.
-type gList struct {
- head guintptr
-}
-
-// empty reports whether l is empty.
-func (l *gList) empty() bool {
- return l.head == 0
-}
-
-// push adds gp to the head of l.
-func (l *gList) push(gp *g) {
- gp.schedlink = l.head
- l.head.set(gp)
-}
-
-// pushAll prepends all Gs in q to l.
-func (l *gList) pushAll(q gQueue) {
- if !q.empty() {
- q.tail.ptr().schedlink = l.head
- l.head = q.head
- }
-}
-
-// pop removes and returns the head of l. If l is empty, it returns nil.
-func (l *gList) pop() *g {
- gp := l.head.ptr()
- if gp != nil {
- l.head = gp.schedlink
- }
- return gp
-}
-
-//go:linkname setMaxThreads runtime/debug.setMaxThreads
-func setMaxThreads(in int) (out int) {
- lock(&sched.lock)
- out = int(sched.maxmcount)
- if in > 0x7fffffff { // MaxInt32
- sched.maxmcount = 0x7fffffff
- } else {
- sched.maxmcount = int32(in)
- }
- checkmcount()
- unlock(&sched.lock)
- return
-}
-
-//go:nosplit
-func procPin() int {
- gp := getg()
- mp := gp.m
-
- mp.locks++
- return int(mp.p.ptr().id)
-}
-
-//go:nosplit
-func procUnpin() {
- gp := getg()
- gp.m.locks--
-}
-
-//go:linkname sync_runtime_procPin sync.runtime_procPin
-//go:nosplit
-func sync_runtime_procPin() int {
- return procPin()
-}
-
-//go:linkname sync_runtime_procUnpin sync.runtime_procUnpin
-//go:nosplit
-func sync_runtime_procUnpin() {
- procUnpin()
-}
-
-//go:linkname sync_atomic_runtime_procPin sync/atomic.runtime_procPin
-//go:nosplit
-func sync_atomic_runtime_procPin() int {
- return procPin()
-}
-
-//go:linkname sync_atomic_runtime_procUnpin sync/atomic.runtime_procUnpin
-//go:nosplit
-func sync_atomic_runtime_procUnpin() {
- procUnpin()
-}
-
-// Active spinning for sync.Mutex.
-//
-//go:linkname sync_runtime_canSpin sync.runtime_canSpin
-//go:nosplit
-func sync_runtime_canSpin(i int) bool {
- // sync.Mutex is cooperative, so we are conservative with spinning.
- // Spin only few times and only if running on a multicore machine and
- // GOMAXPROCS>1 and there is at least one other running P and local runq is empty.
- // As opposed to runtime mutex we don't do passive spinning here,
- // because there can be work on global runq or on other Ps.
- if i >= active_spin || ncpu <= 1 || gomaxprocs <= sched.npidle.Load()+sched.nmspinning.Load()+1 {
- return false
- }
- if p := getg().m.p.ptr(); !runqempty(p) {
- return false
- }
- return true
-}
-
-//go:linkname sync_runtime_doSpin sync.runtime_doSpin
-//go:nosplit
-func sync_runtime_doSpin() {
- procyield(active_spin_cnt)
-}
-
-var stealOrder randomOrder
-
-// randomOrder/randomEnum are helper types for randomized work stealing.
-// They allow to enumerate all Ps in different pseudo-random orders without repetitions.
-// The algorithm is based on the fact that if we have X such that X and GOMAXPROCS
-// are coprime, then a sequences of (i + X) % GOMAXPROCS gives the required enumeration.
-type randomOrder struct {
- count uint32
- coprimes []uint32
-}
-
-type randomEnum struct {
- i uint32
- count uint32
- pos uint32
- inc uint32
-}
-
-func (ord *randomOrder) reset(count uint32) {
- ord.count = count
- ord.coprimes = ord.coprimes[:0]
- for i := uint32(1); i <= count; i++ {
- if gcd(i, count) == 1 {
- ord.coprimes = append(ord.coprimes, i)
- }
- }
-}
-
-func (ord *randomOrder) start(i uint32) randomEnum {
- return randomEnum{
- count: ord.count,
- pos: i % ord.count,
- inc: ord.coprimes[i/ord.count%uint32(len(ord.coprimes))],
- }
-}
-
-func (enum *randomEnum) done() bool {
- return enum.i == enum.count
-}
-
-func (enum *randomEnum) next() {
- enum.i++
- enum.pos = (enum.pos + enum.inc) % enum.count
-}
-
-func (enum *randomEnum) position() uint32 {
- return enum.pos
-}
-
-func gcd(a, b uint32) uint32 {
- for b != 0 {
- a, b = b, a%b
- }
- return a
-}
-
-// An initTask represents the set of initializations that need to be done for a package.
-// Keep in sync with ../../test/initempty.go:initTask
-type initTask struct {
- // TODO: pack the first 3 fields more tightly?
- state uintptr // 0 = uninitialized, 1 = in progress, 2 = done
- ndeps uintptr
- nfns uintptr
- // followed by ndeps instances of an *initTask, one per package depended on
- // followed by nfns pcs, one per init function to run
-}
-
-// inittrace stores statistics for init functions which are
-// updated by malloc and newproc when active is true.
-var inittrace tracestat
-
-type tracestat struct {
- active bool // init tracing activation status
- id uint64 // init goroutine id
- allocs uint64 // heap allocations
- bytes uint64 // heap allocated bytes
-}
-
-func doInit(t *initTask) {
- switch t.state {
- case 2: // fully initialized
- return
- case 1: // initialization in progress
- throw("recursive call during initialization - linker skew")
- default: // not initialized yet
- t.state = 1 // initialization in progress
-
- for i := uintptr(0); i < t.ndeps; i++ {
- p := add(unsafe.Pointer(t), (3+i)*goarch.PtrSize)
- t2 := *(**initTask)(p)
- doInit(t2)
- }
-
- if t.nfns == 0 {
- t.state = 2 // initialization done
- return
- }
-
- var (
- start int64
- before tracestat
- )
-
- if inittrace.active {
- start = nanotime()
- // Load stats non-atomically since tracinit is updated only by this init goroutine.
- before = inittrace
- }
-
- firstFunc := add(unsafe.Pointer(t), (3+t.ndeps)*goarch.PtrSize)
- for i := uintptr(0); i < t.nfns; i++ {
- p := add(firstFunc, i*goarch.PtrSize)
- f := *(*func())(unsafe.Pointer(&p))
- f()
- }
-
- if inittrace.active {
- end := nanotime()
- // Load stats non-atomically since tracinit is updated only by this init goroutine.
- after := inittrace
-
- f := *(*func())(unsafe.Pointer(&firstFunc))
- pkg := funcpkgpath(findfunc(abi.FuncPCABIInternal(f)))
-
- var sbuf [24]byte
- print("init ", pkg, " @")
- print(string(fmtNSAsMS(sbuf[:], uint64(start-runtimeInitTime))), " ms, ")
- print(string(fmtNSAsMS(sbuf[:], uint64(end-start))), " ms clock, ")
- print(string(itoa(sbuf[:], after.bytes-before.bytes)), " bytes, ")
- print(string(itoa(sbuf[:], after.allocs-before.allocs)), " allocs")
- print("\n")
- }
-
- t.state = 2 // initialization done
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/profbuf.go b/contrib/go/_std_1.20/src/runtime/profbuf.go
deleted file mode 100644
index c579f21488..0000000000
--- a/contrib/go/_std_1.20/src/runtime/profbuf.go
+++ /dev/null
@@ -1,560 +0,0 @@
-// Copyright 2017 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 runtime
-
-import (
- "runtime/internal/atomic"
- "unsafe"
-)
-
-// A profBuf is a lock-free buffer for profiling events,
-// safe for concurrent use by one reader and one writer.
-// The writer may be a signal handler running without a user g.
-// The reader is assumed to be a user g.
-//
-// Each logged event corresponds to a fixed size header, a list of
-// uintptrs (typically a stack), and exactly one unsafe.Pointer tag.
-// The header and uintptrs are stored in the circular buffer data and the
-// tag is stored in a circular buffer tags, running in parallel.
-// In the circular buffer data, each event takes 2+hdrsize+len(stk)
-// words: the value 2+hdrsize+len(stk), then the time of the event, then
-// hdrsize words giving the fixed-size header, and then len(stk) words
-// for the stack.
-//
-// The current effective offsets into the tags and data circular buffers
-// for reading and writing are stored in the high 30 and low 32 bits of r and w.
-// The bottom bits of the high 32 are additional flag bits in w, unused in r.
-// "Effective" offsets means the total number of reads or writes, mod 2^length.
-// The offset in the buffer is the effective offset mod the length of the buffer.
-// To make wraparound mod 2^length match wraparound mod length of the buffer,
-// the length of the buffer must be a power of two.
-//
-// If the reader catches up to the writer, a flag passed to read controls
-// whether the read blocks until more data is available. A read returns a
-// pointer to the buffer data itself; the caller is assumed to be done with
-// that data at the next read. The read offset rNext tracks the next offset to
-// be returned by read. By definition, r ≤ rNext ≤ w (before wraparound),
-// and rNext is only used by the reader, so it can be accessed without atomics.
-//
-// If the writer gets ahead of the reader, so that the buffer fills,
-// future writes are discarded and replaced in the output stream by an
-// overflow entry, which has size 2+hdrsize+1, time set to the time of
-// the first discarded write, a header of all zeroed words, and a "stack"
-// containing one word, the number of discarded writes.
-//
-// Between the time the buffer fills and the buffer becomes empty enough
-// to hold more data, the overflow entry is stored as a pending overflow
-// entry in the fields overflow and overflowTime. The pending overflow
-// entry can be turned into a real record by either the writer or the
-// reader. If the writer is called to write a new record and finds that
-// the output buffer has room for both the pending overflow entry and the
-// new record, the writer emits the pending overflow entry and the new
-// record into the buffer. If the reader is called to read data and finds
-// that the output buffer is empty but that there is a pending overflow
-// entry, the reader will return a synthesized record for the pending
-// overflow entry.
-//
-// Only the writer can create or add to a pending overflow entry, but
-// either the reader or the writer can clear the pending overflow entry.
-// A pending overflow entry is indicated by the low 32 bits of 'overflow'
-// holding the number of discarded writes, and overflowTime holding the
-// time of the first discarded write. The high 32 bits of 'overflow'
-// increment each time the low 32 bits transition from zero to non-zero
-// or vice versa. This sequence number avoids ABA problems in the use of
-// compare-and-swap to coordinate between reader and writer.
-// The overflowTime is only written when the low 32 bits of overflow are
-// zero, that is, only when there is no pending overflow entry, in
-// preparation for creating a new one. The reader can therefore fetch and
-// clear the entry atomically using
-//
-// for {
-// overflow = load(&b.overflow)
-// if uint32(overflow) == 0 {
-// // no pending entry
-// break
-// }
-// time = load(&b.overflowTime)
-// if cas(&b.overflow, overflow, ((overflow>>32)+1)<<32) {
-// // pending entry cleared
-// break
-// }
-// }
-// if uint32(overflow) > 0 {
-// emit entry for uint32(overflow), time
-// }
-type profBuf struct {
- // accessed atomically
- r, w profAtomic
- overflow atomic.Uint64
- overflowTime atomic.Uint64
- eof atomic.Uint32
-
- // immutable (excluding slice content)
- hdrsize uintptr
- data []uint64
- tags []unsafe.Pointer
-
- // owned by reader
- rNext profIndex
- overflowBuf []uint64 // for use by reader to return overflow record
- wait note
-}
-
-// A profAtomic is the atomically-accessed word holding a profIndex.
-type profAtomic uint64
-
-// A profIndex is the packet tag and data counts and flags bits, described above.
-type profIndex uint64
-
-const (
- profReaderSleeping profIndex = 1 << 32 // reader is sleeping and must be woken up
- profWriteExtra profIndex = 1 << 33 // overflow or eof waiting
-)
-
-func (x *profAtomic) load() profIndex {
- return profIndex(atomic.Load64((*uint64)(x)))
-}
-
-func (x *profAtomic) store(new profIndex) {
- atomic.Store64((*uint64)(x), uint64(new))
-}
-
-func (x *profAtomic) cas(old, new profIndex) bool {
- return atomic.Cas64((*uint64)(x), uint64(old), uint64(new))
-}
-
-func (x profIndex) dataCount() uint32 {
- return uint32(x)
-}
-
-func (x profIndex) tagCount() uint32 {
- return uint32(x >> 34)
-}
-
-// countSub subtracts two counts obtained from profIndex.dataCount or profIndex.tagCount,
-// assuming that they are no more than 2^29 apart (guaranteed since they are never more than
-// len(data) or len(tags) apart, respectively).
-// tagCount wraps at 2^30, while dataCount wraps at 2^32.
-// This function works for both.
-func countSub(x, y uint32) int {
- // x-y is 32-bit signed or 30-bit signed; sign-extend to 32 bits and convert to int.
- return int(int32(x-y) << 2 >> 2)
-}
-
-// addCountsAndClearFlags returns the packed form of "x + (data, tag) - all flags".
-func (x profIndex) addCountsAndClearFlags(data, tag int) profIndex {
- return profIndex((uint64(x)>>34+uint64(uint32(tag)<<2>>2))<<34 | uint64(uint32(x)+uint32(data)))
-}
-
-// hasOverflow reports whether b has any overflow records pending.
-func (b *profBuf) hasOverflow() bool {
- return uint32(b.overflow.Load()) > 0
-}
-
-// takeOverflow consumes the pending overflow records, returning the overflow count
-// and the time of the first overflow.
-// When called by the reader, it is racing against incrementOverflow.
-func (b *profBuf) takeOverflow() (count uint32, time uint64) {
- overflow := b.overflow.Load()
- time = b.overflowTime.Load()
- for {
- count = uint32(overflow)
- if count == 0 {
- time = 0
- break
- }
- // Increment generation, clear overflow count in low bits.
- if b.overflow.CompareAndSwap(overflow, ((overflow>>32)+1)<<32) {
- break
- }
- overflow = b.overflow.Load()
- time = b.overflowTime.Load()
- }
- return uint32(overflow), time
-}
-
-// incrementOverflow records a single overflow at time now.
-// It is racing against a possible takeOverflow in the reader.
-func (b *profBuf) incrementOverflow(now int64) {
- for {
- overflow := b.overflow.Load()
-
- // Once we see b.overflow reach 0, it's stable: no one else is changing it underfoot.
- // We need to set overflowTime if we're incrementing b.overflow from 0.
- if uint32(overflow) == 0 {
- // Store overflowTime first so it's always available when overflow != 0.
- b.overflowTime.Store(uint64(now))
- b.overflow.Store((((overflow >> 32) + 1) << 32) + 1)
- break
- }
- // Otherwise we're racing to increment against reader
- // who wants to set b.overflow to 0.
- // Out of paranoia, leave 2³²-1 a sticky overflow value,
- // to avoid wrapping around. Extremely unlikely.
- if int32(overflow) == -1 {
- break
- }
- if b.overflow.CompareAndSwap(overflow, overflow+1) {
- break
- }
- }
-}
-
-// newProfBuf returns a new profiling buffer with room for
-// a header of hdrsize words and a buffer of at least bufwords words.
-func newProfBuf(hdrsize, bufwords, tags int) *profBuf {
- if min := 2 + hdrsize + 1; bufwords < min {
- bufwords = min
- }
-
- // Buffer sizes must be power of two, so that we don't have to
- // worry about uint32 wraparound changing the effective position
- // within the buffers. We store 30 bits of count; limiting to 28
- // gives us some room for intermediate calculations.
- if bufwords >= 1<<28 || tags >= 1<<28 {
- throw("newProfBuf: buffer too large")
- }
- var i int
- for i = 1; i < bufwords; i <<= 1 {
- }
- bufwords = i
- for i = 1; i < tags; i <<= 1 {
- }
- tags = i
-
- b := new(profBuf)
- b.hdrsize = uintptr(hdrsize)
- b.data = make([]uint64, bufwords)
- b.tags = make([]unsafe.Pointer, tags)
- b.overflowBuf = make([]uint64, 2+b.hdrsize+1)
- return b
-}
-
-// canWriteRecord reports whether the buffer has room
-// for a single contiguous record with a stack of length nstk.
-func (b *profBuf) canWriteRecord(nstk int) bool {
- br := b.r.load()
- bw := b.w.load()
-
- // room for tag?
- if countSub(br.tagCount(), bw.tagCount())+len(b.tags) < 1 {
- return false
- }
-
- // room for data?
- nd := countSub(br.dataCount(), bw.dataCount()) + len(b.data)
- want := 2 + int(b.hdrsize) + nstk
- i := int(bw.dataCount() % uint32(len(b.data)))
- if i+want > len(b.data) {
- // Can't fit in trailing fragment of slice.
- // Skip over that and start over at beginning of slice.
- nd -= len(b.data) - i
- }
- return nd >= want
-}
-
-// canWriteTwoRecords reports whether the buffer has room
-// for two records with stack lengths nstk1, nstk2, in that order.
-// Each record must be contiguous on its own, but the two
-// records need not be contiguous (one can be at the end of the buffer
-// and the other can wrap around and start at the beginning of the buffer).
-func (b *profBuf) canWriteTwoRecords(nstk1, nstk2 int) bool {
- br := b.r.load()
- bw := b.w.load()
-
- // room for tag?
- if countSub(br.tagCount(), bw.tagCount())+len(b.tags) < 2 {
- return false
- }
-
- // room for data?
- nd := countSub(br.dataCount(), bw.dataCount()) + len(b.data)
-
- // first record
- want := 2 + int(b.hdrsize) + nstk1
- i := int(bw.dataCount() % uint32(len(b.data)))
- if i+want > len(b.data) {
- // Can't fit in trailing fragment of slice.
- // Skip over that and start over at beginning of slice.
- nd -= len(b.data) - i
- i = 0
- }
- i += want
- nd -= want
-
- // second record
- want = 2 + int(b.hdrsize) + nstk2
- if i+want > len(b.data) {
- // Can't fit in trailing fragment of slice.
- // Skip over that and start over at beginning of slice.
- nd -= len(b.data) - i
- i = 0
- }
- return nd >= want
-}
-
-// write writes an entry to the profiling buffer b.
-// The entry begins with a fixed hdr, which must have
-// length b.hdrsize, followed by a variable-sized stack
-// and a single tag pointer *tagPtr (or nil if tagPtr is nil).
-// No write barriers allowed because this might be called from a signal handler.
-func (b *profBuf) write(tagPtr *unsafe.Pointer, now int64, hdr []uint64, stk []uintptr) {
- if b == nil {
- return
- }
- if len(hdr) > int(b.hdrsize) {
- throw("misuse of profBuf.write")
- }
-
- if hasOverflow := b.hasOverflow(); hasOverflow && b.canWriteTwoRecords(1, len(stk)) {
- // Room for both an overflow record and the one being written.
- // Write the overflow record if the reader hasn't gotten to it yet.
- // Only racing against reader, not other writers.
- count, time := b.takeOverflow()
- if count > 0 {
- var stk [1]uintptr
- stk[0] = uintptr(count)
- b.write(nil, int64(time), nil, stk[:])
- }
- } else if hasOverflow || !b.canWriteRecord(len(stk)) {
- // Pending overflow without room to write overflow and new records
- // or no overflow but also no room for new record.
- b.incrementOverflow(now)
- b.wakeupExtra()
- return
- }
-
- // There's room: write the record.
- br := b.r.load()
- bw := b.w.load()
-
- // Profiling tag
- //
- // The tag is a pointer, but we can't run a write barrier here.
- // We have interrupted the OS-level execution of gp, but the
- // runtime still sees gp as executing. In effect, we are running
- // in place of the real gp. Since gp is the only goroutine that
- // can overwrite gp.labels, the value of gp.labels is stable during
- // this signal handler: it will still be reachable from gp when
- // we finish executing. If a GC is in progress right now, it must
- // keep gp.labels alive, because gp.labels is reachable from gp.
- // If gp were to overwrite gp.labels, the deletion barrier would
- // still shade that pointer, which would preserve it for the
- // in-progress GC, so all is well. Any future GC will see the
- // value we copied when scanning b.tags (heap-allocated).
- // We arrange that the store here is always overwriting a nil,
- // so there is no need for a deletion barrier on b.tags[wt].
- wt := int(bw.tagCount() % uint32(len(b.tags)))
- if tagPtr != nil {
- *(*uintptr)(unsafe.Pointer(&b.tags[wt])) = uintptr(unsafe.Pointer(*tagPtr))
- }
-
- // Main record.
- // It has to fit in a contiguous section of the slice, so if it doesn't fit at the end,
- // leave a rewind marker (0) and start over at the beginning of the slice.
- wd := int(bw.dataCount() % uint32(len(b.data)))
- nd := countSub(br.dataCount(), bw.dataCount()) + len(b.data)
- skip := 0
- if wd+2+int(b.hdrsize)+len(stk) > len(b.data) {
- b.data[wd] = 0
- skip = len(b.data) - wd
- nd -= skip
- wd = 0
- }
- data := b.data[wd:]
- data[0] = uint64(2 + b.hdrsize + uintptr(len(stk))) // length
- data[1] = uint64(now) // time stamp
- // header, zero-padded
- i := uintptr(copy(data[2:2+b.hdrsize], hdr))
- for ; i < b.hdrsize; i++ {
- data[2+i] = 0
- }
- for i, pc := range stk {
- data[2+b.hdrsize+uintptr(i)] = uint64(pc)
- }
-
- for {
- // Commit write.
- // Racing with reader setting flag bits in b.w, to avoid lost wakeups.
- old := b.w.load()
- new := old.addCountsAndClearFlags(skip+2+len(stk)+int(b.hdrsize), 1)
- if !b.w.cas(old, new) {
- continue
- }
- // If there was a reader, wake it up.
- if old&profReaderSleeping != 0 {
- notewakeup(&b.wait)
- }
- break
- }
-}
-
-// close signals that there will be no more writes on the buffer.
-// Once all the data has been read from the buffer, reads will return eof=true.
-func (b *profBuf) close() {
- if b.eof.Load() > 0 {
- throw("runtime: profBuf already closed")
- }
- b.eof.Store(1)
- b.wakeupExtra()
-}
-
-// wakeupExtra must be called after setting one of the "extra"
-// atomic fields b.overflow or b.eof.
-// It records the change in b.w and wakes up the reader if needed.
-func (b *profBuf) wakeupExtra() {
- for {
- old := b.w.load()
- new := old | profWriteExtra
- if !b.w.cas(old, new) {
- continue
- }
- if old&profReaderSleeping != 0 {
- notewakeup(&b.wait)
- }
- break
- }
-}
-
-// profBufReadMode specifies whether to block when no data is available to read.
-type profBufReadMode int
-
-const (
- profBufBlocking profBufReadMode = iota
- profBufNonBlocking
-)
-
-var overflowTag [1]unsafe.Pointer // always nil
-
-func (b *profBuf) read(mode profBufReadMode) (data []uint64, tags []unsafe.Pointer, eof bool) {
- if b == nil {
- return nil, nil, true
- }
-
- br := b.rNext
-
- // Commit previous read, returning that part of the ring to the writer.
- // First clear tags that have now been read, both to avoid holding
- // up the memory they point at for longer than necessary
- // and so that b.write can assume it is always overwriting
- // nil tag entries (see comment in b.write).
- rPrev := b.r.load()
- if rPrev != br {
- ntag := countSub(br.tagCount(), rPrev.tagCount())
- ti := int(rPrev.tagCount() % uint32(len(b.tags)))
- for i := 0; i < ntag; i++ {
- b.tags[ti] = nil
- if ti++; ti == len(b.tags) {
- ti = 0
- }
- }
- b.r.store(br)
- }
-
-Read:
- bw := b.w.load()
- numData := countSub(bw.dataCount(), br.dataCount())
- if numData == 0 {
- if b.hasOverflow() {
- // No data to read, but there is overflow to report.
- // Racing with writer flushing b.overflow into a real record.
- count, time := b.takeOverflow()
- if count == 0 {
- // Lost the race, go around again.
- goto Read
- }
- // Won the race, report overflow.
- dst := b.overflowBuf
- dst[0] = uint64(2 + b.hdrsize + 1)
- dst[1] = uint64(time)
- for i := uintptr(0); i < b.hdrsize; i++ {
- dst[2+i] = 0
- }
- dst[2+b.hdrsize] = uint64(count)
- return dst[:2+b.hdrsize+1], overflowTag[:1], false
- }
- if b.eof.Load() > 0 {
- // No data, no overflow, EOF set: done.
- return nil, nil, true
- }
- if bw&profWriteExtra != 0 {
- // Writer claims to have published extra information (overflow or eof).
- // Attempt to clear notification and then check again.
- // If we fail to clear the notification it means b.w changed,
- // so we still need to check again.
- b.w.cas(bw, bw&^profWriteExtra)
- goto Read
- }
-
- // Nothing to read right now.
- // Return or sleep according to mode.
- if mode == profBufNonBlocking {
- return nil, nil, false
- }
- if !b.w.cas(bw, bw|profReaderSleeping) {
- goto Read
- }
- // Committed to sleeping.
- notetsleepg(&b.wait, -1)
- noteclear(&b.wait)
- goto Read
- }
- data = b.data[br.dataCount()%uint32(len(b.data)):]
- if len(data) > numData {
- data = data[:numData]
- } else {
- numData -= len(data) // available in case of wraparound
- }
- skip := 0
- if data[0] == 0 {
- // Wraparound record. Go back to the beginning of the ring.
- skip = len(data)
- data = b.data
- if len(data) > numData {
- data = data[:numData]
- }
- }
-
- ntag := countSub(bw.tagCount(), br.tagCount())
- if ntag == 0 {
- throw("runtime: malformed profBuf buffer - tag and data out of sync")
- }
- tags = b.tags[br.tagCount()%uint32(len(b.tags)):]
- if len(tags) > ntag {
- tags = tags[:ntag]
- }
-
- // Count out whole data records until either data or tags is done.
- // They are always in sync in the buffer, but due to an end-of-slice
- // wraparound we might need to stop early and return the rest
- // in the next call.
- di := 0
- ti := 0
- for di < len(data) && data[di] != 0 && ti < len(tags) {
- if uintptr(di)+uintptr(data[di]) > uintptr(len(data)) {
- throw("runtime: malformed profBuf buffer - invalid size")
- }
- di += int(data[di])
- ti++
- }
-
- // Remember how much we returned, to commit read on next call.
- b.rNext = br.addCountsAndClearFlags(skip+di, ti)
-
- if raceenabled {
- // Match racereleasemerge in runtime_setProfLabel,
- // so that the setting of the labels in runtime_setProfLabel
- // is treated as happening before any use of the labels
- // by our caller. The synchronization on labelSync itself is a fiction
- // for the race detector. The actual synchronization is handled
- // by the fact that the signal handler only reads from the current
- // goroutine and uses atomics to write the updated queue indices,
- // and then the read-out from the signal handler buffer uses
- // atomics to read those queue indices.
- raceacquire(unsafe.Pointer(&labelSync))
- }
-
- return data[:di], tags[:ti], false
-}
diff --git a/contrib/go/_std_1.20/src/runtime/race/ya.make b/contrib/go/_std_1.20/src/runtime/race/ya.make
deleted file mode 100644
index c482c985d0..0000000000
--- a/contrib/go/_std_1.20/src/runtime/race/ya.make
+++ /dev/null
@@ -1,52 +0,0 @@
-GO_LIBRARY()
-
-NO_COMPILER_WARNINGS()
-
-SRCS(
- doc.go
-)
-
-IF (ARCH_X86_64)
- SRCS(
- race_v1_amd64.go
- )
-ENDIF()
-
-IF (OS_DARWIN)
- IF (ARCH_X86_64)
- SRCS(
- race_darwin_amd64.go
- )
- ENDIF()
- IF (ARCH_ARM64)
- SRCS(
- race_darwin_arm64.go
- race_darwin_arm64.syso
- )
- ENDIF()
-ENDIF()
-
-IF (OS_LINUX)
- IF (ARCH_ARM64)
- SRCS(
- race_linux_arm64.syso
- )
- ENDIF()
-ENDIF()
-
-IF (RACE)
- IF (CGO_ENABLED OR OS_DARWIN)
- CGO_SRCS(
- race.go
- )
- ENDIF()
-ENDIF()
-
-END()
-
-
-IF (ARCH_X86_64)
- RECURSE(
- internal
- )
-ENDIF()
diff --git a/contrib/go/_std_1.20/src/runtime/relax_stub.go b/contrib/go/_std_1.20/src/runtime/relax_stub.go
deleted file mode 100644
index e507702fc1..0000000000
--- a/contrib/go/_std_1.20/src/runtime/relax_stub.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2017 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.
-
-//go:build !windows
-
-package runtime
-
-// osRelaxMinNS is the number of nanoseconds of idleness to tolerate
-// without performing an osRelax. Since osRelax may reduce the
-// precision of timers, this should be enough larger than the relaxed
-// timer precision to keep the timer error acceptable.
-const osRelaxMinNS = 0
-
-// osRelax is called by the scheduler when transitioning to and from
-// all Ps being idle.
-func osRelax(relax bool) {}
diff --git a/contrib/go/_std_1.20/src/runtime/rt0_windows_amd64.s b/contrib/go/_std_1.20/src/runtime/rt0_windows_amd64.s
deleted file mode 100644
index e60bf4c86d..0000000000
--- a/contrib/go/_std_1.20/src/runtime/rt0_windows_amd64.s
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2011 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.
-
-#include "go_asm.h"
-#include "go_tls.h"
-#include "textflag.h"
-
-TEXT _rt0_amd64_windows(SB),NOSPLIT,$-8
- JMP _rt0_amd64(SB)
-
-// When building with -buildmode=(c-shared or c-archive), this
-// symbol is called. For dynamic libraries it is called when the
-// library is loaded. For static libraries it is called when the
-// final executable starts, during the C runtime initialization
-// phase.
-// Leave space for four pointers on the stack as required
-// by the Windows amd64 calling convention.
-TEXT _rt0_amd64_windows_lib(SB),NOSPLIT,$0x20
- // Create a new thread to do the runtime initialization and return.
- MOVQ _cgo_sys_thread_create(SB), AX
- MOVQ $_rt0_amd64_windows_lib_go(SB), CX
- MOVQ $0, DX
- CALL AX
- RET
-
-TEXT _rt0_amd64_windows_lib_go(SB),NOSPLIT,$0
- MOVQ $0, DI
- MOVQ $0, SI
- MOVQ $runtime·rt0_go(SB), AX
- JMP AX
diff --git a/contrib/go/_std_1.20/src/runtime/runtime.go b/contrib/go/_std_1.20/src/runtime/runtime.go
deleted file mode 100644
index 9f68738aa7..0000000000
--- a/contrib/go/_std_1.20/src/runtime/runtime.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2009 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 runtime
-
-import (
- "runtime/internal/atomic"
- "unsafe"
-)
-
-//go:generate go run wincallback.go
-//go:generate go run mkduff.go
-//go:generate go run mkfastlog2table.go
-//go:generate go run mklockrank.go -o lockrank.go
-
-var ticks ticksType
-
-type ticksType struct {
- lock mutex
- val atomic.Int64
-}
-
-// Note: Called by runtime/pprof in addition to runtime code.
-func tickspersecond() int64 {
- r := ticks.val.Load()
- if r != 0 {
- return r
- }
- lock(&ticks.lock)
- r = ticks.val.Load()
- if r == 0 {
- t0 := nanotime()
- c0 := cputicks()
- usleep(100 * 1000)
- t1 := nanotime()
- c1 := cputicks()
- if t1 == t0 {
- t1++
- }
- r = (c1 - c0) * 1000 * 1000 * 1000 / (t1 - t0)
- if r == 0 {
- r++
- }
- ticks.val.Store(r)
- }
- unlock(&ticks.lock)
- return r
-}
-
-var envs []string
-var argslice []string
-
-//go:linkname syscall_runtime_envs syscall.runtime_envs
-func syscall_runtime_envs() []string { return append([]string{}, envs...) }
-
-//go:linkname syscall_Getpagesize syscall.Getpagesize
-func syscall_Getpagesize() int { return int(physPageSize) }
-
-//go:linkname os_runtime_args os.runtime_args
-func os_runtime_args() []string { return append([]string{}, argslice...) }
-
-//go:linkname syscall_Exit syscall.Exit
-//go:nosplit
-func syscall_Exit(code int) {
- exit(int32(code))
-}
-
-var godebugDefault string
-var godebugUpdate atomic.Pointer[func(string, string)]
-var godebugEnv atomic.Pointer[string] // set by parsedebugvars
-
-//go:linkname godebug_setUpdate internal/godebug.setUpdate
-func godebug_setUpdate(update func(string, string)) {
- p := new(func(string, string))
- *p = update
- godebugUpdate.Store(p)
- godebugNotify()
-}
-
-func godebugNotify() {
- if update := godebugUpdate.Load(); update != nil {
- var env string
- if p := godebugEnv.Load(); p != nil {
- env = *p
- }
- (*update)(godebugDefault, env)
- }
-}
-
-//go:linkname syscall_runtimeSetenv syscall.runtimeSetenv
-func syscall_runtimeSetenv(key, value string) {
- setenv_c(key, value)
- if key == "GODEBUG" {
- p := new(string)
- *p = value
- godebugEnv.Store(p)
- godebugNotify()
- }
-}
-
-//go:linkname syscall_runtimeUnsetenv syscall.runtimeUnsetenv
-func syscall_runtimeUnsetenv(key string) {
- unsetenv_c(key)
- if key == "GODEBUG" {
- godebugEnv.Store(nil)
- godebugNotify()
- }
-}
-
-// writeErrStr writes a string to descriptor 2.
-//
-//go:nosplit
-func writeErrStr(s string) {
- write(2, unsafe.Pointer(unsafe.StringData(s)), int32(len(s)))
-}
diff --git a/contrib/go/_std_1.20/src/runtime/runtime1.go b/contrib/go/_std_1.20/src/runtime/runtime1.go
deleted file mode 100644
index 277f18a5a6..0000000000
--- a/contrib/go/_std_1.20/src/runtime/runtime1.go
+++ /dev/null
@@ -1,563 +0,0 @@
-// Copyright 2009 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 runtime
-
-import (
- "internal/bytealg"
- "internal/goarch"
- "runtime/internal/atomic"
- "unsafe"
-)
-
-// Keep a cached value to make gotraceback fast,
-// since we call it on every call to gentraceback.
-// The cached value is a uint32 in which the low bits
-// are the "crash" and "all" settings and the remaining
-// bits are the traceback value (0 off, 1 on, 2 include system).
-const (
- tracebackCrash = 1 << iota
- tracebackAll
- tracebackShift = iota
-)
-
-var traceback_cache uint32 = 2 << tracebackShift
-var traceback_env uint32
-
-// gotraceback returns the current traceback settings.
-//
-// If level is 0, suppress all tracebacks.
-// If level is 1, show tracebacks, but exclude runtime frames.
-// If level is 2, show tracebacks including runtime frames.
-// If all is set, print all goroutine stacks. Otherwise, print just the current goroutine.
-// If crash is set, crash (core dump, etc) after tracebacking.
-//
-//go:nosplit
-func gotraceback() (level int32, all, crash bool) {
- gp := getg()
- t := atomic.Load(&traceback_cache)
- crash = t&tracebackCrash != 0
- all = gp.m.throwing >= throwTypeUser || t&tracebackAll != 0
- if gp.m.traceback != 0 {
- level = int32(gp.m.traceback)
- } else if gp.m.throwing >= throwTypeRuntime {
- // Always include runtime frames in runtime throws unless
- // otherwise overridden by m.traceback.
- level = 2
- } else {
- level = int32(t >> tracebackShift)
- }
- return
-}
-
-var (
- argc int32
- argv **byte
-)
-
-// nosplit for use in linux startup sysargs.
-//
-//go:nosplit
-func argv_index(argv **byte, i int32) *byte {
- return *(**byte)(add(unsafe.Pointer(argv), uintptr(i)*goarch.PtrSize))
-}
-
-func args(c int32, v **byte) {
- argc = c
- argv = v
- sysargs(c, v)
-}
-
-func goargs() {
- if GOOS == "windows" {
- return
- }
- argslice = make([]string, argc)
- for i := int32(0); i < argc; i++ {
- argslice[i] = gostringnocopy(argv_index(argv, i))
- }
-}
-
-func goenvs_unix() {
- // TODO(austin): ppc64 in dynamic linking mode doesn't
- // guarantee env[] will immediately follow argv. Might cause
- // problems.
- n := int32(0)
- for argv_index(argv, argc+1+n) != nil {
- n++
- }
-
- envs = make([]string, n)
- for i := int32(0); i < n; i++ {
- envs[i] = gostring(argv_index(argv, argc+1+i))
- }
-}
-
-func environ() []string {
- return envs
-}
-
-// TODO: These should be locals in testAtomic64, but we don't 8-byte
-// align stack variables on 386.
-var test_z64, test_x64 uint64
-
-func testAtomic64() {
- test_z64 = 42
- test_x64 = 0
- if atomic.Cas64(&test_z64, test_x64, 1) {
- throw("cas64 failed")
- }
- if test_x64 != 0 {
- throw("cas64 failed")
- }
- test_x64 = 42
- if !atomic.Cas64(&test_z64, test_x64, 1) {
- throw("cas64 failed")
- }
- if test_x64 != 42 || test_z64 != 1 {
- throw("cas64 failed")
- }
- if atomic.Load64(&test_z64) != 1 {
- throw("load64 failed")
- }
- atomic.Store64(&test_z64, (1<<40)+1)
- if atomic.Load64(&test_z64) != (1<<40)+1 {
- throw("store64 failed")
- }
- if atomic.Xadd64(&test_z64, (1<<40)+1) != (2<<40)+2 {
- throw("xadd64 failed")
- }
- if atomic.Load64(&test_z64) != (2<<40)+2 {
- throw("xadd64 failed")
- }
- if atomic.Xchg64(&test_z64, (3<<40)+3) != (2<<40)+2 {
- throw("xchg64 failed")
- }
- if atomic.Load64(&test_z64) != (3<<40)+3 {
- throw("xchg64 failed")
- }
-}
-
-func check() {
- var (
- a int8
- b uint8
- c int16
- d uint16
- e int32
- f uint32
- g int64
- h uint64
- i, i1 float32
- j, j1 float64
- k unsafe.Pointer
- l *uint16
- m [4]byte
- )
- type x1t struct {
- x uint8
- }
- type y1t struct {
- x1 x1t
- y uint8
- }
- var x1 x1t
- var y1 y1t
-
- if unsafe.Sizeof(a) != 1 {
- throw("bad a")
- }
- if unsafe.Sizeof(b) != 1 {
- throw("bad b")
- }
- if unsafe.Sizeof(c) != 2 {
- throw("bad c")
- }
- if unsafe.Sizeof(d) != 2 {
- throw("bad d")
- }
- if unsafe.Sizeof(e) != 4 {
- throw("bad e")
- }
- if unsafe.Sizeof(f) != 4 {
- throw("bad f")
- }
- if unsafe.Sizeof(g) != 8 {
- throw("bad g")
- }
- if unsafe.Sizeof(h) != 8 {
- throw("bad h")
- }
- if unsafe.Sizeof(i) != 4 {
- throw("bad i")
- }
- if unsafe.Sizeof(j) != 8 {
- throw("bad j")
- }
- if unsafe.Sizeof(k) != goarch.PtrSize {
- throw("bad k")
- }
- if unsafe.Sizeof(l) != goarch.PtrSize {
- throw("bad l")
- }
- if unsafe.Sizeof(x1) != 1 {
- throw("bad unsafe.Sizeof x1")
- }
- if unsafe.Offsetof(y1.y) != 1 {
- throw("bad offsetof y1.y")
- }
- if unsafe.Sizeof(y1) != 2 {
- throw("bad unsafe.Sizeof y1")
- }
-
- if timediv(12345*1000000000+54321, 1000000000, &e) != 12345 || e != 54321 {
- throw("bad timediv")
- }
-
- var z uint32
- z = 1
- if !atomic.Cas(&z, 1, 2) {
- throw("cas1")
- }
- if z != 2 {
- throw("cas2")
- }
-
- z = 4
- if atomic.Cas(&z, 5, 6) {
- throw("cas3")
- }
- if z != 4 {
- throw("cas4")
- }
-
- z = 0xffffffff
- if !atomic.Cas(&z, 0xffffffff, 0xfffffffe) {
- throw("cas5")
- }
- if z != 0xfffffffe {
- throw("cas6")
- }
-
- m = [4]byte{1, 1, 1, 1}
- atomic.Or8(&m[1], 0xf0)
- if m[0] != 1 || m[1] != 0xf1 || m[2] != 1 || m[3] != 1 {
- throw("atomicor8")
- }
-
- m = [4]byte{0xff, 0xff, 0xff, 0xff}
- atomic.And8(&m[1], 0x1)
- if m[0] != 0xff || m[1] != 0x1 || m[2] != 0xff || m[3] != 0xff {
- throw("atomicand8")
- }
-
- *(*uint64)(unsafe.Pointer(&j)) = ^uint64(0)
- if j == j {
- throw("float64nan")
- }
- if !(j != j) {
- throw("float64nan1")
- }
-
- *(*uint64)(unsafe.Pointer(&j1)) = ^uint64(1)
- if j == j1 {
- throw("float64nan2")
- }
- if !(j != j1) {
- throw("float64nan3")
- }
-
- *(*uint32)(unsafe.Pointer(&i)) = ^uint32(0)
- if i == i {
- throw("float32nan")
- }
- if i == i {
- throw("float32nan1")
- }
-
- *(*uint32)(unsafe.Pointer(&i1)) = ^uint32(1)
- if i == i1 {
- throw("float32nan2")
- }
- if i == i1 {
- throw("float32nan3")
- }
-
- testAtomic64()
-
- if _FixedStack != round2(_FixedStack) {
- throw("FixedStack is not power-of-2")
- }
-
- if !checkASM() {
- throw("assembly checks failed")
- }
-}
-
-type dbgVar struct {
- name string
- value *int32
-}
-
-// Holds variables parsed from GODEBUG env var,
-// except for "memprofilerate" since there is an
-// existing int var for that value, which may
-// already have an initial value.
-var debug struct {
- cgocheck int32
- clobberfree int32
- efence int32
- gccheckmark int32
- gcpacertrace int32
- gcshrinkstackoff int32
- gcstoptheworld int32
- gctrace int32
- invalidptr int32
- madvdontneed int32 // for Linux; issue 28466
- scavtrace int32
- scheddetail int32
- schedtrace int32
- tracebackancestors int32
- asyncpreemptoff int32
- harddecommit int32
- adaptivestackstart int32
-
- // debug.malloc is used as a combined debug check
- // in the malloc function and should be set
- // if any of the below debug options is != 0.
- malloc bool
- allocfreetrace int32
- inittrace int32
- sbrk int32
-}
-
-var dbgvars = []dbgVar{
- {"allocfreetrace", &debug.allocfreetrace},
- {"clobberfree", &debug.clobberfree},
- {"cgocheck", &debug.cgocheck},
- {"efence", &debug.efence},
- {"gccheckmark", &debug.gccheckmark},
- {"gcpacertrace", &debug.gcpacertrace},
- {"gcshrinkstackoff", &debug.gcshrinkstackoff},
- {"gcstoptheworld", &debug.gcstoptheworld},
- {"gctrace", &debug.gctrace},
- {"invalidptr", &debug.invalidptr},
- {"madvdontneed", &debug.madvdontneed},
- {"sbrk", &debug.sbrk},
- {"scavtrace", &debug.scavtrace},
- {"scheddetail", &debug.scheddetail},
- {"schedtrace", &debug.schedtrace},
- {"tracebackancestors", &debug.tracebackancestors},
- {"asyncpreemptoff", &debug.asyncpreemptoff},
- {"inittrace", &debug.inittrace},
- {"harddecommit", &debug.harddecommit},
- {"adaptivestackstart", &debug.adaptivestackstart},
-}
-
-var globalGODEBUG string
-
-func parsedebugvars() {
- // defaults
- debug.cgocheck = 1
- debug.invalidptr = 1
- debug.adaptivestackstart = 1 // go119 - set this to 0 to turn larger initial goroutine stacks off
- if GOOS == "linux" {
- // On Linux, MADV_FREE is faster than MADV_DONTNEED,
- // but doesn't affect many of the statistics that
- // MADV_DONTNEED does until the memory is actually
- // reclaimed. This generally leads to poor user
- // experience, like confusing stats in top and other
- // monitoring tools; and bad integration with
- // management systems that respond to memory usage.
- // Hence, default to MADV_DONTNEED.
- debug.madvdontneed = 1
- }
-
- globalGODEBUG = gogetenv("GODEBUG")
- godebugEnv.StoreNoWB(&globalGODEBUG)
- for p := globalGODEBUG; p != ""; {
- field := ""
- i := bytealg.IndexByteString(p, ',')
- if i < 0 {
- field, p = p, ""
- } else {
- field, p = p[:i], p[i+1:]
- }
- i = bytealg.IndexByteString(field, '=')
- if i < 0 {
- continue
- }
- key, value := field[:i], field[i+1:]
-
- // Update MemProfileRate directly here since it
- // is int, not int32, and should only be updated
- // if specified in GODEBUG.
- if key == "memprofilerate" {
- if n, ok := atoi(value); ok {
- MemProfileRate = n
- }
- } else {
- for _, v := range dbgvars {
- if v.name == key {
- if n, ok := atoi32(value); ok {
- *v.value = n
- }
- }
- }
- }
- }
-
- debug.malloc = (debug.allocfreetrace | debug.inittrace | debug.sbrk) != 0
-
- setTraceback(gogetenv("GOTRACEBACK"))
- traceback_env = traceback_cache
-}
-
-//go:linkname setTraceback runtime/debug.SetTraceback
-func setTraceback(level string) {
- var t uint32
- switch level {
- case "none":
- t = 0
- case "single", "":
- t = 1 << tracebackShift
- case "all":
- t = 1<<tracebackShift | tracebackAll
- case "system":
- t = 2<<tracebackShift | tracebackAll
- case "crash":
- t = 2<<tracebackShift | tracebackAll | tracebackCrash
- default:
- t = tracebackAll
- if n, ok := atoi(level); ok && n == int(uint32(n)) {
- t |= uint32(n) << tracebackShift
- }
- }
- // when C owns the process, simply exit'ing the process on fatal errors
- // and panics is surprising. Be louder and abort instead.
- if islibrary || isarchive {
- t |= tracebackCrash
- }
-
- t |= traceback_env
-
- atomic.Store(&traceback_cache, t)
-}
-
-// Poor mans 64-bit division.
-// This is a very special function, do not use it if you are not sure what you are doing.
-// int64 division is lowered into _divv() call on 386, which does not fit into nosplit functions.
-// Handles overflow in a time-specific manner.
-// This keeps us within no-split stack limits on 32-bit processors.
-//
-//go:nosplit
-func timediv(v int64, div int32, rem *int32) int32 {
- res := int32(0)
- for bit := 30; bit >= 0; bit-- {
- if v >= int64(div)<<uint(bit) {
- v = v - (int64(div) << uint(bit))
- // Before this for loop, res was 0, thus all these
- // power of 2 increments are now just bitsets.
- res |= 1 << uint(bit)
- }
- }
- if v >= int64(div) {
- if rem != nil {
- *rem = 0
- }
- return 0x7fffffff
- }
- if rem != nil {
- *rem = int32(v)
- }
- return res
-}
-
-// Helpers for Go. Must be NOSPLIT, must only call NOSPLIT functions, and must not block.
-
-//go:nosplit
-func acquirem() *m {
- gp := getg()
- gp.m.locks++
- return gp.m
-}
-
-//go:nosplit
-func releasem(mp *m) {
- gp := getg()
- mp.locks--
- if mp.locks == 0 && gp.preempt {
- // restore the preemption request in case we've cleared it in newstack
- gp.stackguard0 = stackPreempt
- }
-}
-
-//go:linkname reflect_typelinks reflect.typelinks
-func reflect_typelinks() ([]unsafe.Pointer, [][]int32) {
- modules := activeModules()
- sections := []unsafe.Pointer{unsafe.Pointer(modules[0].types)}
- ret := [][]int32{modules[0].typelinks}
- for _, md := range modules[1:] {
- sections = append(sections, unsafe.Pointer(md.types))
- ret = append(ret, md.typelinks)
- }
- return sections, ret
-}
-
-// reflect_resolveNameOff resolves a name offset from a base pointer.
-//
-//go:linkname reflect_resolveNameOff reflect.resolveNameOff
-func reflect_resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer {
- return unsafe.Pointer(resolveNameOff(ptrInModule, nameOff(off)).bytes)
-}
-
-// reflect_resolveTypeOff resolves an *rtype offset from a base type.
-//
-//go:linkname reflect_resolveTypeOff reflect.resolveTypeOff
-func reflect_resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
- return unsafe.Pointer((*_type)(rtype).typeOff(typeOff(off)))
-}
-
-// reflect_resolveTextOff resolves a function pointer offset from a base type.
-//
-//go:linkname reflect_resolveTextOff reflect.resolveTextOff
-func reflect_resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
- return (*_type)(rtype).textOff(textOff(off))
-
-}
-
-// reflectlite_resolveNameOff resolves a name offset from a base pointer.
-//
-//go:linkname reflectlite_resolveNameOff internal/reflectlite.resolveNameOff
-func reflectlite_resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer {
- return unsafe.Pointer(resolveNameOff(ptrInModule, nameOff(off)).bytes)
-}
-
-// reflectlite_resolveTypeOff resolves an *rtype offset from a base type.
-//
-//go:linkname reflectlite_resolveTypeOff internal/reflectlite.resolveTypeOff
-func reflectlite_resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
- return unsafe.Pointer((*_type)(rtype).typeOff(typeOff(off)))
-}
-
-// reflect_addReflectOff adds a pointer to the reflection offset lookup map.
-//
-//go:linkname reflect_addReflectOff reflect.addReflectOff
-func reflect_addReflectOff(ptr unsafe.Pointer) int32 {
- reflectOffsLock()
- if reflectOffs.m == nil {
- reflectOffs.m = make(map[int32]unsafe.Pointer)
- reflectOffs.minv = make(map[unsafe.Pointer]int32)
- reflectOffs.next = -1
- }
- id, found := reflectOffs.minv[ptr]
- if !found {
- id = reflectOffs.next
- reflectOffs.next-- // use negative offsets as IDs to aid debugging
- reflectOffs.m[id] = ptr
- reflectOffs.minv[ptr] = id
- }
- reflectOffsUnlock()
- return id
-}
diff --git a/contrib/go/_std_1.20/src/runtime/runtime2.go b/contrib/go/_std_1.20/src/runtime/runtime2.go
deleted file mode 100644
index 9381d1e3f7..0000000000
--- a/contrib/go/_std_1.20/src/runtime/runtime2.go
+++ /dev/null
@@ -1,1190 +0,0 @@
-// Copyright 2009 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 runtime
-
-import (
- "internal/goarch"
- "runtime/internal/atomic"
- "unsafe"
-)
-
-// defined constants
-const (
- // G status
- //
- // Beyond indicating the general state of a G, the G status
- // acts like a lock on the goroutine's stack (and hence its
- // ability to execute user code).
- //
- // If you add to this list, add to the list
- // of "okay during garbage collection" status
- // in mgcmark.go too.
- //
- // TODO(austin): The _Gscan bit could be much lighter-weight.
- // For example, we could choose not to run _Gscanrunnable
- // goroutines found in the run queue, rather than CAS-looping
- // until they become _Grunnable. And transitions like
- // _Gscanwaiting -> _Gscanrunnable are actually okay because
- // they don't affect stack ownership.
-
- // _Gidle means this goroutine was just allocated and has not
- // yet been initialized.
- _Gidle = iota // 0
-
- // _Grunnable means this goroutine is on a run queue. It is
- // not currently executing user code. The stack is not owned.
- _Grunnable // 1
-
- // _Grunning means this goroutine may execute user code. The
- // stack is owned by this goroutine. It is not on a run queue.
- // It is assigned an M and a P (g.m and g.m.p are valid).
- _Grunning // 2
-
- // _Gsyscall means this goroutine is executing a system call.
- // It is not executing user code. The stack is owned by this
- // goroutine. It is not on a run queue. It is assigned an M.
- _Gsyscall // 3
-
- // _Gwaiting means this goroutine is blocked in the runtime.
- // It is not executing user code. It is not on a run queue,
- // but should be recorded somewhere (e.g., a channel wait
- // queue) so it can be ready()d when necessary. The stack is
- // not owned *except* that a channel operation may read or
- // write parts of the stack under the appropriate channel
- // lock. Otherwise, it is not safe to access the stack after a
- // goroutine enters _Gwaiting (e.g., it may get moved).
- _Gwaiting // 4
-
- // _Gmoribund_unused is currently unused, but hardcoded in gdb
- // scripts.
- _Gmoribund_unused // 5
-
- // _Gdead means this goroutine is currently unused. It may be
- // just exited, on a free list, or just being initialized. It
- // is not executing user code. It may or may not have a stack
- // allocated. The G and its stack (if any) are owned by the M
- // that is exiting the G or that obtained the G from the free
- // list.
- _Gdead // 6
-
- // _Genqueue_unused is currently unused.
- _Genqueue_unused // 7
-
- // _Gcopystack means this goroutine's stack is being moved. It
- // is not executing user code and is not on a run queue. The
- // stack is owned by the goroutine that put it in _Gcopystack.
- _Gcopystack // 8
-
- // _Gpreempted means this goroutine stopped itself for a
- // suspendG preemption. It is like _Gwaiting, but nothing is
- // yet responsible for ready()ing it. Some suspendG must CAS
- // the status to _Gwaiting to take responsibility for
- // ready()ing this G.
- _Gpreempted // 9
-
- // _Gscan combined with one of the above states other than
- // _Grunning indicates that GC is scanning the stack. The
- // goroutine is not executing user code and the stack is owned
- // by the goroutine that set the _Gscan bit.
- //
- // _Gscanrunning is different: it is used to briefly block
- // state transitions while GC signals the G to scan its own
- // stack. This is otherwise like _Grunning.
- //
- // atomicstatus&~Gscan gives the state the goroutine will
- // return to when the scan completes.
- _Gscan = 0x1000
- _Gscanrunnable = _Gscan + _Grunnable // 0x1001
- _Gscanrunning = _Gscan + _Grunning // 0x1002
- _Gscansyscall = _Gscan + _Gsyscall // 0x1003
- _Gscanwaiting = _Gscan + _Gwaiting // 0x1004
- _Gscanpreempted = _Gscan + _Gpreempted // 0x1009
-)
-
-const (
- // P status
-
- // _Pidle means a P is not being used to run user code or the
- // scheduler. Typically, it's on the idle P list and available
- // to the scheduler, but it may just be transitioning between
- // other states.
- //
- // The P is owned by the idle list or by whatever is
- // transitioning its state. Its run queue is empty.
- _Pidle = iota
-
- // _Prunning means a P is owned by an M and is being used to
- // run user code or the scheduler. Only the M that owns this P
- // is allowed to change the P's status from _Prunning. The M
- // may transition the P to _Pidle (if it has no more work to
- // do), _Psyscall (when entering a syscall), or _Pgcstop (to
- // halt for the GC). The M may also hand ownership of the P
- // off directly to another M (e.g., to schedule a locked G).
- _Prunning
-
- // _Psyscall means a P is not running user code. It has
- // affinity to an M in a syscall but is not owned by it and
- // may be stolen by another M. This is similar to _Pidle but
- // uses lightweight transitions and maintains M affinity.
- //
- // Leaving _Psyscall must be done with a CAS, either to steal
- // or retake the P. Note that there's an ABA hazard: even if
- // an M successfully CASes its original P back to _Prunning
- // after a syscall, it must understand the P may have been
- // used by another M in the interim.
- _Psyscall
-
- // _Pgcstop means a P is halted for STW and owned by the M
- // that stopped the world. The M that stopped the world
- // continues to use its P, even in _Pgcstop. Transitioning
- // from _Prunning to _Pgcstop causes an M to release its P and
- // park.
- //
- // The P retains its run queue and startTheWorld will restart
- // the scheduler on Ps with non-empty run queues.
- _Pgcstop
-
- // _Pdead means a P is no longer used (GOMAXPROCS shrank). We
- // reuse Ps if GOMAXPROCS increases. A dead P is mostly
- // stripped of its resources, though a few things remain
- // (e.g., trace buffers).
- _Pdead
-)
-
-// Mutual exclusion locks. In the uncontended case,
-// as fast as spin locks (just a few user-level instructions),
-// but on the contention path they sleep in the kernel.
-// A zeroed Mutex is unlocked (no need to initialize each lock).
-// Initialization is helpful for static lock ranking, but not required.
-type mutex struct {
- // Empty struct if lock ranking is disabled, otherwise includes the lock rank
- lockRankStruct
- // Futex-based impl treats it as uint32 key,
- // while sema-based impl as M* waitm.
- // Used to be a union, but unions break precise GC.
- key uintptr
-}
-
-// sleep and wakeup on one-time events.
-// before any calls to notesleep or notewakeup,
-// must call noteclear to initialize the Note.
-// then, exactly one thread can call notesleep
-// and exactly one thread can call notewakeup (once).
-// once notewakeup has been called, the notesleep
-// will return. future notesleep will return immediately.
-// subsequent noteclear must be called only after
-// previous notesleep has returned, e.g. it's disallowed
-// to call noteclear straight after notewakeup.
-//
-// notetsleep is like notesleep but wakes up after
-// a given number of nanoseconds even if the event
-// has not yet happened. if a goroutine uses notetsleep to
-// wake up early, it must wait to call noteclear until it
-// can be sure that no other goroutine is calling
-// notewakeup.
-//
-// notesleep/notetsleep are generally called on g0,
-// notetsleepg is similar to notetsleep but is called on user g.
-type note struct {
- // Futex-based impl treats it as uint32 key,
- // while sema-based impl as M* waitm.
- // Used to be a union, but unions break precise GC.
- key uintptr
-}
-
-type funcval struct {
- fn uintptr
- // variable-size, fn-specific data here
-}
-
-type iface struct {
- tab *itab
- data unsafe.Pointer
-}
-
-type eface struct {
- _type *_type
- data unsafe.Pointer
-}
-
-func efaceOf(ep *any) *eface {
- return (*eface)(unsafe.Pointer(ep))
-}
-
-// The guintptr, muintptr, and puintptr are all used to bypass write barriers.
-// It is particularly important to avoid write barriers when the current P has
-// been released, because the GC thinks the world is stopped, and an
-// unexpected write barrier would not be synchronized with the GC,
-// which can lead to a half-executed write barrier that has marked the object
-// but not queued it. If the GC skips the object and completes before the
-// queuing can occur, it will incorrectly free the object.
-//
-// We tried using special assignment functions invoked only when not
-// holding a running P, but then some updates to a particular memory
-// word went through write barriers and some did not. This breaks the
-// write barrier shadow checking mode, and it is also scary: better to have
-// a word that is completely ignored by the GC than to have one for which
-// only a few updates are ignored.
-//
-// Gs and Ps are always reachable via true pointers in the
-// allgs and allp lists or (during allocation before they reach those lists)
-// from stack variables.
-//
-// Ms are always reachable via true pointers either from allm or
-// freem. Unlike Gs and Ps we do free Ms, so it's important that
-// nothing ever hold an muintptr across a safe point.
-
-// A guintptr holds a goroutine pointer, but typed as a uintptr
-// to bypass write barriers. It is used in the Gobuf goroutine state
-// and in scheduling lists that are manipulated without a P.
-//
-// The Gobuf.g goroutine pointer is almost always updated by assembly code.
-// In one of the few places it is updated by Go code - func save - it must be
-// treated as a uintptr to avoid a write barrier being emitted at a bad time.
-// Instead of figuring out how to emit the write barriers missing in the
-// assembly manipulation, we change the type of the field to uintptr,
-// so that it does not require write barriers at all.
-//
-// Goroutine structs are published in the allg list and never freed.
-// That will keep the goroutine structs from being collected.
-// There is never a time that Gobuf.g's contain the only references
-// to a goroutine: the publishing of the goroutine in allg comes first.
-// Goroutine pointers are also kept in non-GC-visible places like TLS,
-// so I can't see them ever moving. If we did want to start moving data
-// in the GC, we'd need to allocate the goroutine structs from an
-// alternate arena. Using guintptr doesn't make that problem any worse.
-// Note that pollDesc.rg, pollDesc.wg also store g in uintptr form,
-// so they would need to be updated too if g's start moving.
-type guintptr uintptr
-
-//go:nosplit
-func (gp guintptr) ptr() *g { return (*g)(unsafe.Pointer(gp)) }
-
-//go:nosplit
-func (gp *guintptr) set(g *g) { *gp = guintptr(unsafe.Pointer(g)) }
-
-//go:nosplit
-func (gp *guintptr) cas(old, new guintptr) bool {
- return atomic.Casuintptr((*uintptr)(unsafe.Pointer(gp)), uintptr(old), uintptr(new))
-}
-
-// setGNoWB performs *gp = new without a write barrier.
-// For times when it's impractical to use a guintptr.
-//
-//go:nosplit
-//go:nowritebarrier
-func setGNoWB(gp **g, new *g) {
- (*guintptr)(unsafe.Pointer(gp)).set(new)
-}
-
-type puintptr uintptr
-
-//go:nosplit
-func (pp puintptr) ptr() *p { return (*p)(unsafe.Pointer(pp)) }
-
-//go:nosplit
-func (pp *puintptr) set(p *p) { *pp = puintptr(unsafe.Pointer(p)) }
-
-// muintptr is a *m that is not tracked by the garbage collector.
-//
-// Because we do free Ms, there are some additional constrains on
-// muintptrs:
-//
-// 1. Never hold an muintptr locally across a safe point.
-//
-// 2. Any muintptr in the heap must be owned by the M itself so it can
-// ensure it is not in use when the last true *m is released.
-type muintptr uintptr
-
-//go:nosplit
-func (mp muintptr) ptr() *m { return (*m)(unsafe.Pointer(mp)) }
-
-//go:nosplit
-func (mp *muintptr) set(m *m) { *mp = muintptr(unsafe.Pointer(m)) }
-
-// setMNoWB performs *mp = new without a write barrier.
-// For times when it's impractical to use an muintptr.
-//
-//go:nosplit
-//go:nowritebarrier
-func setMNoWB(mp **m, new *m) {
- (*muintptr)(unsafe.Pointer(mp)).set(new)
-}
-
-type gobuf struct {
- // The offsets of sp, pc, and g are known to (hard-coded in) libmach.
- //
- // ctxt is unusual with respect to GC: it may be a
- // heap-allocated funcval, so GC needs to track it, but it
- // needs to be set and cleared from assembly, where it's
- // difficult to have write barriers. However, ctxt is really a
- // saved, live register, and we only ever exchange it between
- // the real register and the gobuf. Hence, we treat it as a
- // root during stack scanning, which means assembly that saves
- // and restores it doesn't need write barriers. It's still
- // typed as a pointer so that any other writes from Go get
- // write barriers.
- sp uintptr
- pc uintptr
- g guintptr
- ctxt unsafe.Pointer
- ret uintptr
- lr uintptr
- bp uintptr // for framepointer-enabled architectures
-}
-
-// sudog represents a g in a wait list, such as for sending/receiving
-// on a channel.
-//
-// sudog is necessary because the g ↔ synchronization object relation
-// is many-to-many. A g can be on many wait lists, so there may be
-// many sudogs for one g; and many gs may be waiting on the same
-// synchronization object, so there may be many sudogs for one object.
-//
-// sudogs are allocated from a special pool. Use acquireSudog and
-// releaseSudog to allocate and free them.
-type sudog struct {
- // The following fields are protected by the hchan.lock of the
- // channel this sudog is blocking on. shrinkstack depends on
- // this for sudogs involved in channel ops.
-
- g *g
-
- next *sudog
- prev *sudog
- elem unsafe.Pointer // data element (may point to stack)
-
- // The following fields are never accessed concurrently.
- // For channels, waitlink is only accessed by g.
- // For semaphores, all fields (including the ones above)
- // are only accessed when holding a semaRoot lock.
-
- acquiretime int64
- releasetime int64
- ticket uint32
-
- // isSelect indicates g is participating in a select, so
- // g.selectDone must be CAS'd to win the wake-up race.
- isSelect bool
-
- // success indicates whether communication over channel c
- // succeeded. It is true if the goroutine was awoken because a
- // value was delivered over channel c, and false if awoken
- // because c was closed.
- success bool
-
- parent *sudog // semaRoot binary tree
- waitlink *sudog // g.waiting list or semaRoot
- waittail *sudog // semaRoot
- c *hchan // channel
-}
-
-type libcall struct {
- fn uintptr
- n uintptr // number of parameters
- args uintptr // parameters
- r1 uintptr // return values
- r2 uintptr
- err uintptr // error number
-}
-
-// Stack describes a Go execution stack.
-// The bounds of the stack are exactly [lo, hi),
-// with no implicit data structures on either side.
-type stack struct {
- lo uintptr
- hi uintptr
-}
-
-// heldLockInfo gives info on a held lock and the rank of that lock
-type heldLockInfo struct {
- lockAddr uintptr
- rank lockRank
-}
-
-type g struct {
- // Stack parameters.
- // stack describes the actual stack memory: [stack.lo, stack.hi).
- // stackguard0 is the stack pointer compared in the Go stack growth prologue.
- // It is stack.lo+StackGuard normally, but can be StackPreempt to trigger a preemption.
- // stackguard1 is the stack pointer compared in the C stack growth prologue.
- // It is stack.lo+StackGuard on g0 and gsignal stacks.
- // It is ~0 on other goroutine stacks, to trigger a call to morestackc (and crash).
- stack stack // offset known to runtime/cgo
- stackguard0 uintptr // offset known to liblink
- stackguard1 uintptr // offset known to liblink
-
- _panic *_panic // innermost panic - offset known to liblink
- _defer *_defer // innermost defer
- m *m // current m; offset known to arm liblink
- sched gobuf
- syscallsp uintptr // if status==Gsyscall, syscallsp = sched.sp to use during gc
- syscallpc uintptr // if status==Gsyscall, syscallpc = sched.pc to use during gc
- stktopsp uintptr // expected sp at top of stack, to check in traceback
- // param is a generic pointer parameter field used to pass
- // values in particular contexts where other storage for the
- // parameter would be difficult to find. It is currently used
- // in three ways:
- // 1. When a channel operation wakes up a blocked goroutine, it sets param to
- // point to the sudog of the completed blocking operation.
- // 2. By gcAssistAlloc1 to signal back to its caller that the goroutine completed
- // the GC cycle. It is unsafe to do so in any other way, because the goroutine's
- // stack may have moved in the meantime.
- // 3. By debugCallWrap to pass parameters to a new goroutine because allocating a
- // closure in the runtime is forbidden.
- param unsafe.Pointer
- atomicstatus atomic.Uint32
- stackLock uint32 // sigprof/scang lock; TODO: fold in to atomicstatus
- goid uint64
- schedlink guintptr
- waitsince int64 // approx time when the g become blocked
- waitreason waitReason // if status==Gwaiting
-
- preempt bool // preemption signal, duplicates stackguard0 = stackpreempt
- preemptStop bool // transition to _Gpreempted on preemption; otherwise, just deschedule
- preemptShrink bool // shrink stack at synchronous safe point
-
- // asyncSafePoint is set if g is stopped at an asynchronous
- // safe point. This means there are frames on the stack
- // without precise pointer information.
- asyncSafePoint bool
-
- paniconfault bool // panic (instead of crash) on unexpected fault address
- gcscandone bool // g has scanned stack; protected by _Gscan bit in status
- throwsplit bool // must not split stack
- // activeStackChans indicates that there are unlocked channels
- // pointing into this goroutine's stack. If true, stack
- // copying needs to acquire channel locks to protect these
- // areas of the stack.
- activeStackChans bool
- // parkingOnChan indicates that the goroutine is about to
- // park on a chansend or chanrecv. Used to signal an unsafe point
- // for stack shrinking.
- parkingOnChan atomic.Bool
-
- raceignore int8 // ignore race detection events
- sysblocktraced bool // StartTrace has emitted EvGoInSyscall about this goroutine
- tracking bool // whether we're tracking this G for sched latency statistics
- trackingSeq uint8 // used to decide whether to track this G
- trackingStamp int64 // timestamp of when the G last started being tracked
- runnableTime int64 // the amount of time spent runnable, cleared when running, only used when tracking
- sysexitticks int64 // cputicks when syscall has returned (for tracing)
- traceseq uint64 // trace event sequencer
- tracelastp puintptr // last P emitted an event for this goroutine
- lockedm muintptr
- sig uint32
- writebuf []byte
- sigcode0 uintptr
- sigcode1 uintptr
- sigpc uintptr
- gopc uintptr // pc of go statement that created this goroutine
- ancestors *[]ancestorInfo // ancestor information goroutine(s) that created this goroutine (only used if debug.tracebackancestors)
- startpc uintptr // pc of goroutine function
- racectx uintptr
- waiting *sudog // sudog structures this g is waiting on (that have a valid elem ptr); in lock order
- cgoCtxt []uintptr // cgo traceback context
- labels unsafe.Pointer // profiler labels
- timer *timer // cached timer for time.Sleep
- selectDone atomic.Uint32 // are we participating in a select and did someone win the race?
-
- // goroutineProfiled indicates the status of this goroutine's stack for the
- // current in-progress goroutine profile
- goroutineProfiled goroutineProfileStateHolder
-
- // Per-G GC state
-
- // gcAssistBytes is this G's GC assist credit in terms of
- // bytes allocated. If this is positive, then the G has credit
- // to allocate gcAssistBytes bytes without assisting. If this
- // is negative, then the G must correct this by performing
- // scan work. We track this in bytes to make it fast to update
- // and check for debt in the malloc hot path. The assist ratio
- // determines how this corresponds to scan work debt.
- gcAssistBytes int64
-}
-
-// gTrackingPeriod is the number of transitions out of _Grunning between
-// latency tracking runs.
-const gTrackingPeriod = 8
-
-const (
- // tlsSlots is the number of pointer-sized slots reserved for TLS on some platforms,
- // like Windows.
- tlsSlots = 6
- tlsSize = tlsSlots * goarch.PtrSize
-)
-
-// Values for m.freeWait.
-const (
- freeMStack = 0 // M done, free stack and reference.
- freeMRef = 1 // M done, free reference.
- freeMWait = 2 // M still in use.
-)
-
-type m struct {
- g0 *g // goroutine with scheduling stack
- morebuf gobuf // gobuf arg to morestack
- divmod uint32 // div/mod denominator for arm - known to liblink
- _ uint32 // align next field to 8 bytes
-
- // Fields not known to debuggers.
- procid uint64 // for debuggers, but offset not hard-coded
- gsignal *g // signal-handling g
- goSigStack gsignalStack // Go-allocated signal handling stack
- sigmask sigset // storage for saved signal mask
- tls [tlsSlots]uintptr // thread-local storage (for x86 extern register)
- mstartfn func()
- curg *g // current running goroutine
- caughtsig guintptr // goroutine running during fatal signal
- p puintptr // attached p for executing go code (nil if not executing go code)
- nextp puintptr
- oldp puintptr // the p that was attached before executing a syscall
- id int64
- mallocing int32
- throwing throwType
- preemptoff string // if != "", keep curg running on this m
- locks int32
- dying int32
- profilehz int32
- spinning bool // m is out of work and is actively looking for work
- blocked bool // m is blocked on a note
- newSigstack bool // minit on C thread called sigaltstack
- printlock int8
- incgo bool // m is executing a cgo call
- isextra bool // m is an extra m
- freeWait atomic.Uint32 // Whether it is safe to free g0 and delete m (one of freeMRef, freeMStack, freeMWait)
- fastrand uint64
- needextram bool
- traceback uint8
- ncgocall uint64 // number of cgo calls in total
- ncgo int32 // number of cgo calls currently in progress
- cgoCallersUse atomic.Uint32 // if non-zero, cgoCallers in use temporarily
- cgoCallers *cgoCallers // cgo traceback if crashing in cgo call
- park note
- alllink *m // on allm
- schedlink muintptr
- lockedg guintptr
- createstack [32]uintptr // stack that created this thread.
- lockedExt uint32 // tracking for external LockOSThread
- lockedInt uint32 // tracking for internal lockOSThread
- nextwaitm muintptr // next m waiting for lock
- waitunlockf func(*g, unsafe.Pointer) bool
- waitlock unsafe.Pointer
- waittraceev byte
- waittraceskip int
- startingtrace bool
- syscalltick uint32
- freelink *m // on sched.freem
-
- // these are here because they are too large to be on the stack
- // of low-level NOSPLIT functions.
- libcall libcall
- libcallpc uintptr // for cpu profiler
- libcallsp uintptr
- libcallg guintptr
- syscall libcall // stores syscall parameters on windows
-
- vdsoSP uintptr // SP for traceback while in VDSO call (0 if not in call)
- vdsoPC uintptr // PC for traceback while in VDSO call
-
- // preemptGen counts the number of completed preemption
- // signals. This is used to detect when a preemption is
- // requested, but fails.
- preemptGen atomic.Uint32
-
- // Whether this is a pending preemption signal on this M.
- signalPending atomic.Uint32
-
- dlogPerM
-
- mOS
-
- // Up to 10 locks held by this m, maintained by the lock ranking code.
- locksHeldLen int
- locksHeld [10]heldLockInfo
-}
-
-type p struct {
- id int32
- status uint32 // one of pidle/prunning/...
- link puintptr
- schedtick uint32 // incremented on every scheduler call
- syscalltick uint32 // incremented on every system call
- sysmontick sysmontick // last tick observed by sysmon
- m muintptr // back-link to associated m (nil if idle)
- mcache *mcache
- pcache pageCache
- raceprocctx uintptr
-
- deferpool []*_defer // pool of available defer structs (see panic.go)
- deferpoolbuf [32]*_defer
-
- // Cache of goroutine ids, amortizes accesses to runtime·sched.goidgen.
- goidcache uint64
- goidcacheend uint64
-
- // Queue of runnable goroutines. Accessed without lock.
- runqhead uint32
- runqtail uint32
- runq [256]guintptr
- // runnext, if non-nil, is a runnable G that was ready'd by
- // the current G and should be run next instead of what's in
- // runq if there's time remaining in the running G's time
- // slice. It will inherit the time left in the current time
- // slice. If a set of goroutines is locked in a
- // communicate-and-wait pattern, this schedules that set as a
- // unit and eliminates the (potentially large) scheduling
- // latency that otherwise arises from adding the ready'd
- // goroutines to the end of the run queue.
- //
- // Note that while other P's may atomically CAS this to zero,
- // only the owner P can CAS it to a valid G.
- runnext guintptr
-
- // Available G's (status == Gdead)
- gFree struct {
- gList
- n int32
- }
-
- sudogcache []*sudog
- sudogbuf [128]*sudog
-
- // Cache of mspan objects from the heap.
- mspancache struct {
- // We need an explicit length here because this field is used
- // in allocation codepaths where write barriers are not allowed,
- // and eliminating the write barrier/keeping it eliminated from
- // slice updates is tricky, moreso than just managing the length
- // ourselves.
- len int
- buf [128]*mspan
- }
-
- tracebuf traceBufPtr
-
- // traceSweep indicates the sweep events should be traced.
- // This is used to defer the sweep start event until a span
- // has actually been swept.
- traceSweep bool
- // traceSwept and traceReclaimed track the number of bytes
- // swept and reclaimed by sweeping in the current sweep loop.
- traceSwept, traceReclaimed uintptr
-
- palloc persistentAlloc // per-P to avoid mutex
-
- // The when field of the first entry on the timer heap.
- // This is 0 if the timer heap is empty.
- timer0When atomic.Int64
-
- // The earliest known nextwhen field of a timer with
- // timerModifiedEarlier status. Because the timer may have been
- // modified again, there need not be any timer with this value.
- // This is 0 if there are no timerModifiedEarlier timers.
- timerModifiedEarliest atomic.Int64
-
- // Per-P GC state
- gcAssistTime int64 // Nanoseconds in assistAlloc
- gcFractionalMarkTime int64 // Nanoseconds in fractional mark worker (atomic)
-
- // limiterEvent tracks events for the GC CPU limiter.
- limiterEvent limiterEvent
-
- // gcMarkWorkerMode is the mode for the next mark worker to run in.
- // That is, this is used to communicate with the worker goroutine
- // selected for immediate execution by
- // gcController.findRunnableGCWorker. When scheduling other goroutines,
- // this field must be set to gcMarkWorkerNotWorker.
- gcMarkWorkerMode gcMarkWorkerMode
- // gcMarkWorkerStartTime is the nanotime() at which the most recent
- // mark worker started.
- gcMarkWorkerStartTime int64
-
- // gcw is this P's GC work buffer cache. The work buffer is
- // filled by write barriers, drained by mutator assists, and
- // disposed on certain GC state transitions.
- gcw gcWork
-
- // wbBuf is this P's GC write barrier buffer.
- //
- // TODO: Consider caching this in the running G.
- wbBuf wbBuf
-
- runSafePointFn uint32 // if 1, run sched.safePointFn at next safe point
-
- // statsSeq is a counter indicating whether this P is currently
- // writing any stats. Its value is even when not, odd when it is.
- statsSeq atomic.Uint32
-
- // Lock for timers. We normally access the timers while running
- // on this P, but the scheduler can also do it from a different P.
- timersLock mutex
-
- // Actions to take at some time. This is used to implement the
- // standard library's time package.
- // Must hold timersLock to access.
- timers []*timer
-
- // Number of timers in P's heap.
- numTimers atomic.Uint32
-
- // Number of timerDeleted timers in P's heap.
- deletedTimers atomic.Uint32
-
- // Race context used while executing timer functions.
- timerRaceCtx uintptr
-
- // maxStackScanDelta accumulates the amount of stack space held by
- // live goroutines (i.e. those eligible for stack scanning).
- // Flushed to gcController.maxStackScan once maxStackScanSlack
- // or -maxStackScanSlack is reached.
- maxStackScanDelta int64
-
- // gc-time statistics about current goroutines
- // Note that this differs from maxStackScan in that this
- // accumulates the actual stack observed to be used at GC time (hi - sp),
- // not an instantaneous measure of the total stack size that might need
- // to be scanned (hi - lo).
- scannedStackSize uint64 // stack size of goroutines scanned by this P
- scannedStacks uint64 // number of goroutines scanned by this P
-
- // preempt is set to indicate that this P should be enter the
- // scheduler ASAP (regardless of what G is running on it).
- preempt bool
-
- // pageTraceBuf is a buffer for writing out page allocation/free/scavenge traces.
- //
- // Used only if GOEXPERIMENT=pagetrace.
- pageTraceBuf pageTraceBuf
-
- // Padding is no longer needed. False sharing is now not a worry because p is large enough
- // that its size class is an integer multiple of the cache line size (for any of our architectures).
-}
-
-type schedt struct {
- goidgen atomic.Uint64
- lastpoll atomic.Int64 // time of last network poll, 0 if currently polling
- pollUntil atomic.Int64 // time to which current poll is sleeping
-
- lock mutex
-
- // When increasing nmidle, nmidlelocked, nmsys, or nmfreed, be
- // sure to call checkdead().
-
- midle muintptr // idle m's waiting for work
- nmidle int32 // number of idle m's waiting for work
- nmidlelocked int32 // number of locked m's waiting for work
- mnext int64 // number of m's that have been created and next M ID
- maxmcount int32 // maximum number of m's allowed (or die)
- nmsys int32 // number of system m's not counted for deadlock
- nmfreed int64 // cumulative number of freed m's
-
- ngsys atomic.Int32 // number of system goroutines
-
- pidle puintptr // idle p's
- npidle atomic.Int32
- nmspinning atomic.Int32 // See "Worker thread parking/unparking" comment in proc.go.
- needspinning atomic.Uint32 // See "Delicate dance" comment in proc.go. Boolean. Must hold sched.lock to set to 1.
-
- // Global runnable queue.
- runq gQueue
- runqsize int32
-
- // disable controls selective disabling of the scheduler.
- //
- // Use schedEnableUser to control this.
- //
- // disable is protected by sched.lock.
- disable struct {
- // user disables scheduling of user goroutines.
- user bool
- runnable gQueue // pending runnable Gs
- n int32 // length of runnable
- }
-
- // Global cache of dead G's.
- gFree struct {
- lock mutex
- stack gList // Gs with stacks
- noStack gList // Gs without stacks
- n int32
- }
-
- // Central cache of sudog structs.
- sudoglock mutex
- sudogcache *sudog
-
- // Central pool of available defer structs.
- deferlock mutex
- deferpool *_defer
-
- // freem is the list of m's waiting to be freed when their
- // m.exited is set. Linked through m.freelink.
- freem *m
-
- gcwaiting atomic.Bool // gc is waiting to run
- stopwait int32
- stopnote note
- sysmonwait atomic.Bool
- sysmonnote note
-
- // safepointFn should be called on each P at the next GC
- // safepoint if p.runSafePointFn is set.
- safePointFn func(*p)
- safePointWait int32
- safePointNote note
-
- profilehz int32 // cpu profiling rate
-
- procresizetime int64 // nanotime() of last change to gomaxprocs
- totaltime int64 // ∫gomaxprocs dt up to procresizetime
-
- // sysmonlock protects sysmon's actions on the runtime.
- //
- // Acquire and hold this mutex to block sysmon from interacting
- // with the rest of the runtime.
- sysmonlock mutex
-
- // timeToRun is a distribution of scheduling latencies, defined
- // as the sum of time a G spends in the _Grunnable state before
- // it transitions to _Grunning.
- timeToRun timeHistogram
-
- // idleTime is the total CPU time Ps have "spent" idle.
- //
- // Reset on each GC cycle.
- idleTime atomic.Int64
-
- // totalMutexWaitTime is the sum of time goroutines have spent in _Gwaiting
- // with a waitreason of the form waitReasonSync{RW,}Mutex{R,}Lock.
- totalMutexWaitTime atomic.Int64
-}
-
-// Values for the flags field of a sigTabT.
-const (
- _SigNotify = 1 << iota // let signal.Notify have signal, even if from kernel
- _SigKill // if signal.Notify doesn't take it, exit quietly
- _SigThrow // if signal.Notify doesn't take it, exit loudly
- _SigPanic // if the signal is from the kernel, panic
- _SigDefault // if the signal isn't explicitly requested, don't monitor it
- _SigGoExit // cause all runtime procs to exit (only used on Plan 9).
- _SigSetStack // Don't explicitly install handler, but add SA_ONSTACK to existing libc handler
- _SigUnblock // always unblock; see blockableSig
- _SigIgn // _SIG_DFL action is to ignore the signal
-)
-
-// Layout of in-memory per-function information prepared by linker
-// See https://golang.org/s/go12symtab.
-// Keep in sync with linker (../cmd/link/internal/ld/pcln.go:/pclntab)
-// and with package debug/gosym and with symtab.go in package runtime.
-type _func struct {
- entryOff uint32 // start pc, as offset from moduledata.text/pcHeader.textStart
- nameOff int32 // function name, as index into moduledata.funcnametab.
-
- args int32 // in/out args size
- deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any.
-
- pcsp uint32
- pcfile uint32
- pcln uint32
- npcdata uint32
- cuOffset uint32 // runtime.cutab offset of this function's CU
- startLine int32 // line number of start of function (func keyword/TEXT directive)
- funcID funcID // set for certain special runtime functions
- flag funcFlag
- _ [1]byte // pad
- nfuncdata uint8 // must be last, must end on a uint32-aligned boundary
-
- // The end of the struct is followed immediately by two variable-length
- // arrays that reference the pcdata and funcdata locations for this
- // function.
-
- // pcdata contains the offset into moduledata.pctab for the start of
- // that index's table. e.g.,
- // &moduledata.pctab[_func.pcdata[_PCDATA_UnsafePoint]] is the start of
- // the unsafe point table.
- //
- // An offset of 0 indicates that there is no table.
- //
- // pcdata [npcdata]uint32
-
- // funcdata contains the offset past moduledata.gofunc which contains a
- // pointer to that index's funcdata. e.g.,
- // *(moduledata.gofunc + _func.funcdata[_FUNCDATA_ArgsPointerMaps]) is
- // the argument pointer map.
- //
- // An offset of ^uint32(0) indicates that there is no entry.
- //
- // funcdata [nfuncdata]uint32
-}
-
-// Pseudo-Func that is returned for PCs that occur in inlined code.
-// A *Func can be either a *_func or a *funcinl, and they are distinguished
-// by the first uintptr.
-type funcinl struct {
- ones uint32 // set to ^0 to distinguish from _func
- entry uintptr // entry of the real (the "outermost") frame
- name string
- file string
- line int32
- startLine int32
-}
-
-// layout of Itab known to compilers
-// allocated in non-garbage-collected memory
-// Needs to be in sync with
-// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs.
-type itab struct {
- inter *interfacetype
- _type *_type
- hash uint32 // copy of _type.hash. Used for type switches.
- _ [4]byte
- fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
-}
-
-// Lock-free stack node.
-// Also known to export_test.go.
-type lfnode struct {
- next uint64
- pushcnt uintptr
-}
-
-type forcegcstate struct {
- lock mutex
- g *g
- idle atomic.Bool
-}
-
-// extendRandom extends the random numbers in r[:n] to the whole slice r.
-// Treats n<0 as n==0.
-func extendRandom(r []byte, n int) {
- if n < 0 {
- n = 0
- }
- for n < len(r) {
- // Extend random bits using hash function & time seed
- w := n
- if w > 16 {
- w = 16
- }
- h := memhash(unsafe.Pointer(&r[n-w]), uintptr(nanotime()), uintptr(w))
- for i := 0; i < goarch.PtrSize && n < len(r); i++ {
- r[n] = byte(h)
- n++
- h >>= 8
- }
- }
-}
-
-// A _defer holds an entry on the list of deferred calls.
-// If you add a field here, add code to clear it in deferProcStack.
-// This struct must match the code in cmd/compile/internal/ssagen/ssa.go:deferstruct
-// and cmd/compile/internal/ssagen/ssa.go:(*state).call.
-// Some defers will be allocated on the stack and some on the heap.
-// All defers are logically part of the stack, so write barriers to
-// initialize them are not required. All defers must be manually scanned,
-// and for heap defers, marked.
-type _defer struct {
- started bool
- heap bool
- // openDefer indicates that this _defer is for a frame with open-coded
- // defers. We have only one defer record for the entire frame (which may
- // currently have 0, 1, or more defers active).
- openDefer bool
- sp uintptr // sp at time of defer
- pc uintptr // pc at time of defer
- fn func() // can be nil for open-coded defers
- _panic *_panic // panic that is running defer
- link *_defer // next defer on G; can point to either heap or stack!
-
- // If openDefer is true, the fields below record values about the stack
- // frame and associated function that has the open-coded defer(s). sp
- // above will be the sp for the frame, and pc will be address of the
- // deferreturn call in the function.
- fd unsafe.Pointer // funcdata for the function associated with the frame
- varp uintptr // value of varp for the stack frame
- // framepc is the current pc associated with the stack frame. Together,
- // with sp above (which is the sp associated with the stack frame),
- // framepc/sp can be used as pc/sp pair to continue a stack trace via
- // gentraceback().
- framepc uintptr
-}
-
-// A _panic holds information about an active panic.
-//
-// A _panic value must only ever live on the stack.
-//
-// The argp and link fields are stack pointers, but don't need special
-// handling during stack growth: because they are pointer-typed and
-// _panic values only live on the stack, regular stack pointer
-// adjustment takes care of them.
-type _panic struct {
- argp unsafe.Pointer // pointer to arguments of deferred call run during panic; cannot move - known to liblink
- arg any // argument to panic
- link *_panic // link to earlier panic
- pc uintptr // where to return to in runtime if this panic is bypassed
- sp unsafe.Pointer // where to return to in runtime if this panic is bypassed
- recovered bool // whether this panic is over
- aborted bool // the panic was aborted
- goexit bool
-}
-
-// ancestorInfo records details of where a goroutine was started.
-type ancestorInfo struct {
- pcs []uintptr // pcs from the stack of this goroutine
- goid uint64 // goroutine id of this goroutine; original goroutine possibly dead
- gopc uintptr // pc of go statement that created this goroutine
-}
-
-const (
- _TraceRuntimeFrames = 1 << iota // include frames for internal runtime functions.
- _TraceTrap // the initial PC, SP are from a trap, not a return PC from a call
- _TraceJumpStack // if traceback is on a systemstack, resume trace at g that called into it
-)
-
-// The maximum number of frames we print for a traceback
-const _TracebackMaxFrames = 100
-
-// A waitReason explains why a goroutine has been stopped.
-// See gopark. Do not re-use waitReasons, add new ones.
-type waitReason uint8
-
-const (
- waitReasonZero waitReason = iota // ""
- waitReasonGCAssistMarking // "GC assist marking"
- waitReasonIOWait // "IO wait"
- waitReasonChanReceiveNilChan // "chan receive (nil chan)"
- waitReasonChanSendNilChan // "chan send (nil chan)"
- waitReasonDumpingHeap // "dumping heap"
- waitReasonGarbageCollection // "garbage collection"
- waitReasonGarbageCollectionScan // "garbage collection scan"
- waitReasonPanicWait // "panicwait"
- waitReasonSelect // "select"
- waitReasonSelectNoCases // "select (no cases)"
- waitReasonGCAssistWait // "GC assist wait"
- waitReasonGCSweepWait // "GC sweep wait"
- waitReasonGCScavengeWait // "GC scavenge wait"
- waitReasonChanReceive // "chan receive"
- waitReasonChanSend // "chan send"
- waitReasonFinalizerWait // "finalizer wait"
- waitReasonForceGCIdle // "force gc (idle)"
- waitReasonSemacquire // "semacquire"
- waitReasonSleep // "sleep"
- waitReasonSyncCondWait // "sync.Cond.Wait"
- waitReasonSyncMutexLock // "sync.Mutex.Lock"
- waitReasonSyncRWMutexRLock // "sync.RWMutex.RLock"
- waitReasonSyncRWMutexLock // "sync.RWMutex.Lock"
- waitReasonTraceReaderBlocked // "trace reader (blocked)"
- waitReasonWaitForGCCycle // "wait for GC cycle"
- waitReasonGCWorkerIdle // "GC worker (idle)"
- waitReasonGCWorkerActive // "GC worker (active)"
- waitReasonPreempted // "preempted"
- waitReasonDebugCall // "debug call"
- waitReasonGCMarkTermination // "GC mark termination"
- waitReasonStoppingTheWorld // "stopping the world"
-)
-
-var waitReasonStrings = [...]string{
- waitReasonZero: "",
- waitReasonGCAssistMarking: "GC assist marking",
- waitReasonIOWait: "IO wait",
- waitReasonChanReceiveNilChan: "chan receive (nil chan)",
- waitReasonChanSendNilChan: "chan send (nil chan)",
- waitReasonDumpingHeap: "dumping heap",
- waitReasonGarbageCollection: "garbage collection",
- waitReasonGarbageCollectionScan: "garbage collection scan",
- waitReasonPanicWait: "panicwait",
- waitReasonSelect: "select",
- waitReasonSelectNoCases: "select (no cases)",
- waitReasonGCAssistWait: "GC assist wait",
- waitReasonGCSweepWait: "GC sweep wait",
- waitReasonGCScavengeWait: "GC scavenge wait",
- waitReasonChanReceive: "chan receive",
- waitReasonChanSend: "chan send",
- waitReasonFinalizerWait: "finalizer wait",
- waitReasonForceGCIdle: "force gc (idle)",
- waitReasonSemacquire: "semacquire",
- waitReasonSleep: "sleep",
- waitReasonSyncCondWait: "sync.Cond.Wait",
- waitReasonSyncMutexLock: "sync.Mutex.Lock",
- waitReasonSyncRWMutexRLock: "sync.RWMutex.RLock",
- waitReasonSyncRWMutexLock: "sync.RWMutex.Lock",
- waitReasonTraceReaderBlocked: "trace reader (blocked)",
- waitReasonWaitForGCCycle: "wait for GC cycle",
- waitReasonGCWorkerIdle: "GC worker (idle)",
- waitReasonGCWorkerActive: "GC worker (active)",
- waitReasonPreempted: "preempted",
- waitReasonDebugCall: "debug call",
- waitReasonGCMarkTermination: "GC mark termination",
- waitReasonStoppingTheWorld: "stopping the world",
-}
-
-func (w waitReason) String() string {
- if w < 0 || w >= waitReason(len(waitReasonStrings)) {
- return "unknown wait reason"
- }
- return waitReasonStrings[w]
-}
-
-func (w waitReason) isMutexWait() bool {
- return w == waitReasonSyncMutexLock ||
- w == waitReasonSyncRWMutexRLock ||
- w == waitReasonSyncRWMutexLock
-}
-
-var (
- allm *m
- gomaxprocs int32
- ncpu int32
- forcegc forcegcstate
- sched schedt
- newprocs int32
-
- // allpLock protects P-less reads and size changes of allp, idlepMask,
- // and timerpMask, and all writes to allp.
- allpLock mutex
- // len(allp) == gomaxprocs; may change at safe points, otherwise
- // immutable.
- allp []*p
- // Bitmask of Ps in _Pidle list, one bit per P. Reads and writes must
- // be atomic. Length may change at safe points.
- //
- // Each P must update only its own bit. In order to maintain
- // consistency, a P going idle must the idle mask simultaneously with
- // updates to the idle P list under the sched.lock, otherwise a racing
- // pidleget may clear the mask before pidleput sets the mask,
- // corrupting the bitmap.
- //
- // N.B., procresize takes ownership of all Ps in stopTheWorldWithSema.
- idlepMask pMask
- // Bitmask of Ps that may have a timer, one bit per P. Reads and writes
- // must be atomic. Length may change at safe points.
- timerpMask pMask
-
- // Pool of GC parked background workers. Entries are type
- // *gcBgMarkWorkerNode.
- gcBgMarkWorkerPool lfstack
-
- // Total number of gcBgMarkWorker goroutines. Protected by worldsema.
- gcBgMarkWorkerCount int32
-
- // Information about what cpu features are available.
- // Packages outside the runtime should not use these
- // as they are not an external api.
- // Set on startup in asm_{386,amd64}.s
- processorVersionInfo uint32
- isIntel bool
-
- goarm uint8 // set by cmd/link on arm systems
-)
-
-// Set by the linker so the runtime can determine the buildmode.
-var (
- islibrary bool // -buildmode=c-shared
- isarchive bool // -buildmode=c-archive
-)
-
-// Must agree with internal/buildcfg.FramePointerEnabled.
-const framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64"
diff --git a/contrib/go/_std_1.20/src/runtime/select.go b/contrib/go/_std_1.20/src/runtime/select.go
deleted file mode 100644
index 1072465365..0000000000
--- a/contrib/go/_std_1.20/src/runtime/select.go
+++ /dev/null
@@ -1,632 +0,0 @@
-// Copyright 2009 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 runtime
-
-// This file contains the implementation of Go select statements.
-
-import (
- "internal/abi"
- "unsafe"
-)
-
-const debugSelect = false
-
-// Select case descriptor.
-// Known to compiler.
-// Changes here must also be made in src/cmd/compile/internal/walk/select.go's scasetype.
-type scase struct {
- c *hchan // chan
- elem unsafe.Pointer // data element
-}
-
-var (
- chansendpc = abi.FuncPCABIInternal(chansend)
- chanrecvpc = abi.FuncPCABIInternal(chanrecv)
-)
-
-func selectsetpc(pc *uintptr) {
- *pc = getcallerpc()
-}
-
-func sellock(scases []scase, lockorder []uint16) {
- var c *hchan
- for _, o := range lockorder {
- c0 := scases[o].c
- if c0 != c {
- c = c0
- lock(&c.lock)
- }
- }
-}
-
-func selunlock(scases []scase, lockorder []uint16) {
- // We must be very careful here to not touch sel after we have unlocked
- // the last lock, because sel can be freed right after the last unlock.
- // Consider the following situation.
- // First M calls runtime·park() in runtime·selectgo() passing the sel.
- // Once runtime·park() has unlocked the last lock, another M makes
- // the G that calls select runnable again and schedules it for execution.
- // When the G runs on another M, it locks all the locks and frees sel.
- // Now if the first M touches sel, it will access freed memory.
- for i := len(lockorder) - 1; i >= 0; i-- {
- c := scases[lockorder[i]].c
- if i > 0 && c == scases[lockorder[i-1]].c {
- continue // will unlock it on the next iteration
- }
- unlock(&c.lock)
- }
-}
-
-func selparkcommit(gp *g, _ unsafe.Pointer) bool {
- // There are unlocked sudogs that point into gp's stack. Stack
- // copying must lock the channels of those sudogs.
- // Set activeStackChans here instead of before we try parking
- // because we could self-deadlock in stack growth on a
- // channel lock.
- gp.activeStackChans = true
- // Mark that it's safe for stack shrinking to occur now,
- // because any thread acquiring this G's stack for shrinking
- // is guaranteed to observe activeStackChans after this store.
- gp.parkingOnChan.Store(false)
- // Make sure we unlock after setting activeStackChans and
- // unsetting parkingOnChan. The moment we unlock any of the
- // channel locks we risk gp getting readied by a channel operation
- // and so gp could continue running before everything before the
- // unlock is visible (even to gp itself).
-
- // This must not access gp's stack (see gopark). In
- // particular, it must not access the *hselect. That's okay,
- // because by the time this is called, gp.waiting has all
- // channels in lock order.
- var lastc *hchan
- for sg := gp.waiting; sg != nil; sg = sg.waitlink {
- if sg.c != lastc && lastc != nil {
- // As soon as we unlock the channel, fields in
- // any sudog with that channel may change,
- // including c and waitlink. Since multiple
- // sudogs may have the same channel, we unlock
- // only after we've passed the last instance
- // of a channel.
- unlock(&lastc.lock)
- }
- lastc = sg.c
- }
- if lastc != nil {
- unlock(&lastc.lock)
- }
- return true
-}
-
-func block() {
- gopark(nil, nil, waitReasonSelectNoCases, traceEvGoStop, 1) // forever
-}
-
-// selectgo implements the select statement.
-//
-// cas0 points to an array of type [ncases]scase, and order0 points to
-// an array of type [2*ncases]uint16 where ncases must be <= 65536.
-// Both reside on the goroutine's stack (regardless of any escaping in
-// selectgo).
-//
-// For race detector builds, pc0 points to an array of type
-// [ncases]uintptr (also on the stack); for other builds, it's set to
-// nil.
-//
-// selectgo returns the index of the chosen scase, which matches the
-// ordinal position of its respective select{recv,send,default} call.
-// Also, if the chosen scase was a receive operation, it reports whether
-// a value was received.
-func selectgo(cas0 *scase, order0 *uint16, pc0 *uintptr, nsends, nrecvs int, block bool) (int, bool) {
- if debugSelect {
- print("select: cas0=", cas0, "\n")
- }
-
- // NOTE: In order to maintain a lean stack size, the number of scases
- // is capped at 65536.
- cas1 := (*[1 << 16]scase)(unsafe.Pointer(cas0))
- order1 := (*[1 << 17]uint16)(unsafe.Pointer(order0))
-
- ncases := nsends + nrecvs
- scases := cas1[:ncases:ncases]
- pollorder := order1[:ncases:ncases]
- lockorder := order1[ncases:][:ncases:ncases]
- // NOTE: pollorder/lockorder's underlying array was not zero-initialized by compiler.
-
- // Even when raceenabled is true, there might be select
- // statements in packages compiled without -race (e.g.,
- // ensureSigM in runtime/signal_unix.go).
- var pcs []uintptr
- if raceenabled && pc0 != nil {
- pc1 := (*[1 << 16]uintptr)(unsafe.Pointer(pc0))
- pcs = pc1[:ncases:ncases]
- }
- casePC := func(casi int) uintptr {
- if pcs == nil {
- return 0
- }
- return pcs[casi]
- }
-
- var t0 int64
- if blockprofilerate > 0 {
- t0 = cputicks()
- }
-
- // The compiler rewrites selects that statically have
- // only 0 or 1 cases plus default into simpler constructs.
- // The only way we can end up with such small sel.ncase
- // values here is for a larger select in which most channels
- // have been nilled out. The general code handles those
- // cases correctly, and they are rare enough not to bother
- // optimizing (and needing to test).
-
- // generate permuted order
- norder := 0
- for i := range scases {
- cas := &scases[i]
-
- // Omit cases without channels from the poll and lock orders.
- if cas.c == nil {
- cas.elem = nil // allow GC
- continue
- }
-
- j := fastrandn(uint32(norder + 1))
- pollorder[norder] = pollorder[j]
- pollorder[j] = uint16(i)
- norder++
- }
- pollorder = pollorder[:norder]
- lockorder = lockorder[:norder]
-
- // sort the cases by Hchan address to get the locking order.
- // simple heap sort, to guarantee n log n time and constant stack footprint.
- for i := range lockorder {
- j := i
- // Start with the pollorder to permute cases on the same channel.
- c := scases[pollorder[i]].c
- for j > 0 && scases[lockorder[(j-1)/2]].c.sortkey() < c.sortkey() {
- k := (j - 1) / 2
- lockorder[j] = lockorder[k]
- j = k
- }
- lockorder[j] = pollorder[i]
- }
- for i := len(lockorder) - 1; i >= 0; i-- {
- o := lockorder[i]
- c := scases[o].c
- lockorder[i] = lockorder[0]
- j := 0
- for {
- k := j*2 + 1
- if k >= i {
- break
- }
- if k+1 < i && scases[lockorder[k]].c.sortkey() < scases[lockorder[k+1]].c.sortkey() {
- k++
- }
- if c.sortkey() < scases[lockorder[k]].c.sortkey() {
- lockorder[j] = lockorder[k]
- j = k
- continue
- }
- break
- }
- lockorder[j] = o
- }
-
- if debugSelect {
- for i := 0; i+1 < len(lockorder); i++ {
- if scases[lockorder[i]].c.sortkey() > scases[lockorder[i+1]].c.sortkey() {
- print("i=", i, " x=", lockorder[i], " y=", lockorder[i+1], "\n")
- throw("select: broken sort")
- }
- }
- }
-
- // lock all the channels involved in the select
- sellock(scases, lockorder)
-
- var (
- gp *g
- sg *sudog
- c *hchan
- k *scase
- sglist *sudog
- sgnext *sudog
- qp unsafe.Pointer
- nextp **sudog
- )
-
- // pass 1 - look for something already waiting
- var casi int
- var cas *scase
- var caseSuccess bool
- var caseReleaseTime int64 = -1
- var recvOK bool
- for _, casei := range pollorder {
- casi = int(casei)
- cas = &scases[casi]
- c = cas.c
-
- if casi >= nsends {
- sg = c.sendq.dequeue()
- if sg != nil {
- goto recv
- }
- if c.qcount > 0 {
- goto bufrecv
- }
- if c.closed != 0 {
- goto rclose
- }
- } else {
- if raceenabled {
- racereadpc(c.raceaddr(), casePC(casi), chansendpc)
- }
- if c.closed != 0 {
- goto sclose
- }
- sg = c.recvq.dequeue()
- if sg != nil {
- goto send
- }
- if c.qcount < c.dataqsiz {
- goto bufsend
- }
- }
- }
-
- if !block {
- selunlock(scases, lockorder)
- casi = -1
- goto retc
- }
-
- // pass 2 - enqueue on all chans
- gp = getg()
- if gp.waiting != nil {
- throw("gp.waiting != nil")
- }
- nextp = &gp.waiting
- for _, casei := range lockorder {
- casi = int(casei)
- cas = &scases[casi]
- c = cas.c
- sg := acquireSudog()
- sg.g = gp
- sg.isSelect = true
- // No stack splits between assigning elem and enqueuing
- // sg on gp.waiting where copystack can find it.
- sg.elem = cas.elem
- sg.releasetime = 0
- if t0 != 0 {
- sg.releasetime = -1
- }
- sg.c = c
- // Construct waiting list in lock order.
- *nextp = sg
- nextp = &sg.waitlink
-
- if casi < nsends {
- c.sendq.enqueue(sg)
- } else {
- c.recvq.enqueue(sg)
- }
- }
-
- // wait for someone to wake us up
- gp.param = nil
- // Signal to anyone trying to shrink our stack that we're about
- // to park on a channel. The window between when this G's status
- // changes and when we set gp.activeStackChans is not safe for
- // stack shrinking.
- gp.parkingOnChan.Store(true)
- gopark(selparkcommit, nil, waitReasonSelect, traceEvGoBlockSelect, 1)
- gp.activeStackChans = false
-
- sellock(scases, lockorder)
-
- gp.selectDone.Store(0)
- sg = (*sudog)(gp.param)
- gp.param = nil
-
- // pass 3 - dequeue from unsuccessful chans
- // otherwise they stack up on quiet channels
- // record the successful case, if any.
- // We singly-linked up the SudoGs in lock order.
- casi = -1
- cas = nil
- caseSuccess = false
- sglist = gp.waiting
- // Clear all elem before unlinking from gp.waiting.
- for sg1 := gp.waiting; sg1 != nil; sg1 = sg1.waitlink {
- sg1.isSelect = false
- sg1.elem = nil
- sg1.c = nil
- }
- gp.waiting = nil
-
- for _, casei := range lockorder {
- k = &scases[casei]
- if sg == sglist {
- // sg has already been dequeued by the G that woke us up.
- casi = int(casei)
- cas = k
- caseSuccess = sglist.success
- if sglist.releasetime > 0 {
- caseReleaseTime = sglist.releasetime
- }
- } else {
- c = k.c
- if int(casei) < nsends {
- c.sendq.dequeueSudoG(sglist)
- } else {
- c.recvq.dequeueSudoG(sglist)
- }
- }
- sgnext = sglist.waitlink
- sglist.waitlink = nil
- releaseSudog(sglist)
- sglist = sgnext
- }
-
- if cas == nil {
- throw("selectgo: bad wakeup")
- }
-
- c = cas.c
-
- if debugSelect {
- print("wait-return: cas0=", cas0, " c=", c, " cas=", cas, " send=", casi < nsends, "\n")
- }
-
- if casi < nsends {
- if !caseSuccess {
- goto sclose
- }
- } else {
- recvOK = caseSuccess
- }
-
- if raceenabled {
- if casi < nsends {
- raceReadObjectPC(c.elemtype, cas.elem, casePC(casi), chansendpc)
- } else if cas.elem != nil {
- raceWriteObjectPC(c.elemtype, cas.elem, casePC(casi), chanrecvpc)
- }
- }
- if msanenabled {
- if casi < nsends {
- msanread(cas.elem, c.elemtype.size)
- } else if cas.elem != nil {
- msanwrite(cas.elem, c.elemtype.size)
- }
- }
- if asanenabled {
- if casi < nsends {
- asanread(cas.elem, c.elemtype.size)
- } else if cas.elem != nil {
- asanwrite(cas.elem, c.elemtype.size)
- }
- }
-
- selunlock(scases, lockorder)
- goto retc
-
-bufrecv:
- // can receive from buffer
- if raceenabled {
- if cas.elem != nil {
- raceWriteObjectPC(c.elemtype, cas.elem, casePC(casi), chanrecvpc)
- }
- racenotify(c, c.recvx, nil)
- }
- if msanenabled && cas.elem != nil {
- msanwrite(cas.elem, c.elemtype.size)
- }
- if asanenabled && cas.elem != nil {
- asanwrite(cas.elem, c.elemtype.size)
- }
- recvOK = true
- qp = chanbuf(c, c.recvx)
- if cas.elem != nil {
- typedmemmove(c.elemtype, cas.elem, qp)
- }
- typedmemclr(c.elemtype, qp)
- c.recvx++
- if c.recvx == c.dataqsiz {
- c.recvx = 0
- }
- c.qcount--
- selunlock(scases, lockorder)
- goto retc
-
-bufsend:
- // can send to buffer
- if raceenabled {
- racenotify(c, c.sendx, nil)
- raceReadObjectPC(c.elemtype, cas.elem, casePC(casi), chansendpc)
- }
- if msanenabled {
- msanread(cas.elem, c.elemtype.size)
- }
- if asanenabled {
- asanread(cas.elem, c.elemtype.size)
- }
- typedmemmove(c.elemtype, chanbuf(c, c.sendx), cas.elem)
- c.sendx++
- if c.sendx == c.dataqsiz {
- c.sendx = 0
- }
- c.qcount++
- selunlock(scases, lockorder)
- goto retc
-
-recv:
- // can receive from sleeping sender (sg)
- recv(c, sg, cas.elem, func() { selunlock(scases, lockorder) }, 2)
- if debugSelect {
- print("syncrecv: cas0=", cas0, " c=", c, "\n")
- }
- recvOK = true
- goto retc
-
-rclose:
- // read at end of closed channel
- selunlock(scases, lockorder)
- recvOK = false
- if cas.elem != nil {
- typedmemclr(c.elemtype, cas.elem)
- }
- if raceenabled {
- raceacquire(c.raceaddr())
- }
- goto retc
-
-send:
- // can send to a sleeping receiver (sg)
- if raceenabled {
- raceReadObjectPC(c.elemtype, cas.elem, casePC(casi), chansendpc)
- }
- if msanenabled {
- msanread(cas.elem, c.elemtype.size)
- }
- if asanenabled {
- asanread(cas.elem, c.elemtype.size)
- }
- send(c, sg, cas.elem, func() { selunlock(scases, lockorder) }, 2)
- if debugSelect {
- print("syncsend: cas0=", cas0, " c=", c, "\n")
- }
- goto retc
-
-retc:
- if caseReleaseTime > 0 {
- blockevent(caseReleaseTime-t0, 1)
- }
- return casi, recvOK
-
-sclose:
- // send on closed channel
- selunlock(scases, lockorder)
- panic(plainError("send on closed channel"))
-}
-
-func (c *hchan) sortkey() uintptr {
- return uintptr(unsafe.Pointer(c))
-}
-
-// A runtimeSelect is a single case passed to rselect.
-// This must match ../reflect/value.go:/runtimeSelect
-type runtimeSelect struct {
- dir selectDir
- typ unsafe.Pointer // channel type (not used here)
- ch *hchan // channel
- val unsafe.Pointer // ptr to data (SendDir) or ptr to receive buffer (RecvDir)
-}
-
-// These values must match ../reflect/value.go:/SelectDir.
-type selectDir int
-
-const (
- _ selectDir = iota
- selectSend // case Chan <- Send
- selectRecv // case <-Chan:
- selectDefault // default
-)
-
-//go:linkname reflect_rselect reflect.rselect
-func reflect_rselect(cases []runtimeSelect) (int, bool) {
- if len(cases) == 0 {
- block()
- }
- sel := make([]scase, len(cases))
- orig := make([]int, len(cases))
- nsends, nrecvs := 0, 0
- dflt := -1
- for i, rc := range cases {
- var j int
- switch rc.dir {
- case selectDefault:
- dflt = i
- continue
- case selectSend:
- j = nsends
- nsends++
- case selectRecv:
- nrecvs++
- j = len(cases) - nrecvs
- }
-
- sel[j] = scase{c: rc.ch, elem: rc.val}
- orig[j] = i
- }
-
- // Only a default case.
- if nsends+nrecvs == 0 {
- return dflt, false
- }
-
- // Compact sel and orig if necessary.
- if nsends+nrecvs < len(cases) {
- copy(sel[nsends:], sel[len(cases)-nrecvs:])
- copy(orig[nsends:], orig[len(cases)-nrecvs:])
- }
-
- order := make([]uint16, 2*(nsends+nrecvs))
- var pc0 *uintptr
- if raceenabled {
- pcs := make([]uintptr, nsends+nrecvs)
- for i := range pcs {
- selectsetpc(&pcs[i])
- }
- pc0 = &pcs[0]
- }
-
- chosen, recvOK := selectgo(&sel[0], &order[0], pc0, nsends, nrecvs, dflt == -1)
-
- // Translate chosen back to caller's ordering.
- if chosen < 0 {
- chosen = dflt
- } else {
- chosen = orig[chosen]
- }
- return chosen, recvOK
-}
-
-func (q *waitq) dequeueSudoG(sgp *sudog) {
- x := sgp.prev
- y := sgp.next
- if x != nil {
- if y != nil {
- // middle of queue
- x.next = y
- y.prev = x
- sgp.next = nil
- sgp.prev = nil
- return
- }
- // end of queue
- x.next = nil
- q.last = x
- sgp.prev = nil
- return
- }
- if y != nil {
- // start of queue
- y.prev = nil
- q.first = y
- sgp.next = nil
- return
- }
-
- // x==y==nil. Either sgp is the only element in the queue,
- // or it has already been removed. Use q.first to disambiguate.
- if q.first == sgp {
- q.first = nil
- q.last = nil
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/sema.go b/contrib/go/_std_1.20/src/runtime/sema.go
deleted file mode 100644
index bc23a85e34..0000000000
--- a/contrib/go/_std_1.20/src/runtime/sema.go
+++ /dev/null
@@ -1,633 +0,0 @@
-// Copyright 2009 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.
-
-// Semaphore implementation exposed to Go.
-// Intended use is provide a sleep and wakeup
-// primitive that can be used in the contended case
-// of other synchronization primitives.
-// Thus it targets the same goal as Linux's futex,
-// but it has much simpler semantics.
-//
-// That is, don't think of these as semaphores.
-// Think of them as a way to implement sleep and wakeup
-// such that every sleep is paired with a single wakeup,
-// even if, due to races, the wakeup happens before the sleep.
-//
-// See Mullender and Cox, ``Semaphores in Plan 9,''
-// https://swtch.com/semaphore.pdf
-
-package runtime
-
-import (
- "internal/cpu"
- "runtime/internal/atomic"
- "unsafe"
-)
-
-// Asynchronous semaphore for sync.Mutex.
-
-// A semaRoot holds a balanced tree of sudog with distinct addresses (s.elem).
-// Each of those sudog may in turn point (through s.waitlink) to a list
-// of other sudogs waiting on the same address.
-// The operations on the inner lists of sudogs with the same address
-// are all O(1). The scanning of the top-level semaRoot list is O(log n),
-// where n is the number of distinct addresses with goroutines blocked
-// on them that hash to the given semaRoot.
-// See golang.org/issue/17953 for a program that worked badly
-// before we introduced the second level of list, and
-// BenchmarkSemTable/OneAddrCollision/* for a benchmark that exercises this.
-type semaRoot struct {
- lock mutex
- treap *sudog // root of balanced tree of unique waiters.
- nwait atomic.Uint32 // Number of waiters. Read w/o the lock.
-}
-
-var semtable semTable
-
-// Prime to not correlate with any user patterns.
-const semTabSize = 251
-
-type semTable [semTabSize]struct {
- root semaRoot
- pad [cpu.CacheLinePadSize - unsafe.Sizeof(semaRoot{})]byte
-}
-
-func (t *semTable) rootFor(addr *uint32) *semaRoot {
- return &t[(uintptr(unsafe.Pointer(addr))>>3)%semTabSize].root
-}
-
-//go:linkname sync_runtime_Semacquire sync.runtime_Semacquire
-func sync_runtime_Semacquire(addr *uint32) {
- semacquire1(addr, false, semaBlockProfile, 0, waitReasonSemacquire)
-}
-
-//go:linkname poll_runtime_Semacquire internal/poll.runtime_Semacquire
-func poll_runtime_Semacquire(addr *uint32) {
- semacquire1(addr, false, semaBlockProfile, 0, waitReasonSemacquire)
-}
-
-//go:linkname sync_runtime_Semrelease sync.runtime_Semrelease
-func sync_runtime_Semrelease(addr *uint32, handoff bool, skipframes int) {
- semrelease1(addr, handoff, skipframes)
-}
-
-//go:linkname sync_runtime_SemacquireMutex sync.runtime_SemacquireMutex
-func sync_runtime_SemacquireMutex(addr *uint32, lifo bool, skipframes int) {
- semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes, waitReasonSyncMutexLock)
-}
-
-//go:linkname sync_runtime_SemacquireRWMutexR sync.runtime_SemacquireRWMutexR
-func sync_runtime_SemacquireRWMutexR(addr *uint32, lifo bool, skipframes int) {
- semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes, waitReasonSyncRWMutexRLock)
-}
-
-//go:linkname sync_runtime_SemacquireRWMutex sync.runtime_SemacquireRWMutex
-func sync_runtime_SemacquireRWMutex(addr *uint32, lifo bool, skipframes int) {
- semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes, waitReasonSyncRWMutexLock)
-}
-
-//go:linkname poll_runtime_Semrelease internal/poll.runtime_Semrelease
-func poll_runtime_Semrelease(addr *uint32) {
- semrelease(addr)
-}
-
-func readyWithTime(s *sudog, traceskip int) {
- if s.releasetime != 0 {
- s.releasetime = cputicks()
- }
- goready(s.g, traceskip)
-}
-
-type semaProfileFlags int
-
-const (
- semaBlockProfile semaProfileFlags = 1 << iota
- semaMutexProfile
-)
-
-// Called from runtime.
-func semacquire(addr *uint32) {
- semacquire1(addr, false, 0, 0, waitReasonSemacquire)
-}
-
-func semacquire1(addr *uint32, lifo bool, profile semaProfileFlags, skipframes int, reason waitReason) {
- gp := getg()
- if gp != gp.m.curg {
- throw("semacquire not on the G stack")
- }
-
- // Easy case.
- if cansemacquire(addr) {
- return
- }
-
- // Harder case:
- // increment waiter count
- // try cansemacquire one more time, return if succeeded
- // enqueue itself as a waiter
- // sleep
- // (waiter descriptor is dequeued by signaler)
- s := acquireSudog()
- root := semtable.rootFor(addr)
- t0 := int64(0)
- s.releasetime = 0
- s.acquiretime = 0
- s.ticket = 0
- if profile&semaBlockProfile != 0 && blockprofilerate > 0 {
- t0 = cputicks()
- s.releasetime = -1
- }
- if profile&semaMutexProfile != 0 && mutexprofilerate > 0 {
- if t0 == 0 {
- t0 = cputicks()
- }
- s.acquiretime = t0
- }
- for {
- lockWithRank(&root.lock, lockRankRoot)
- // Add ourselves to nwait to disable "easy case" in semrelease.
- root.nwait.Add(1)
- // Check cansemacquire to avoid missed wakeup.
- if cansemacquire(addr) {
- root.nwait.Add(-1)
- unlock(&root.lock)
- break
- }
- // Any semrelease after the cansemacquire knows we're waiting
- // (we set nwait above), so go to sleep.
- root.queue(addr, s, lifo)
- goparkunlock(&root.lock, reason, traceEvGoBlockSync, 4+skipframes)
- if s.ticket != 0 || cansemacquire(addr) {
- break
- }
- }
- if s.releasetime > 0 {
- blockevent(s.releasetime-t0, 3+skipframes)
- }
- releaseSudog(s)
-}
-
-func semrelease(addr *uint32) {
- semrelease1(addr, false, 0)
-}
-
-func semrelease1(addr *uint32, handoff bool, skipframes int) {
- root := semtable.rootFor(addr)
- atomic.Xadd(addr, 1)
-
- // Easy case: no waiters?
- // This check must happen after the xadd, to avoid a missed wakeup
- // (see loop in semacquire).
- if root.nwait.Load() == 0 {
- return
- }
-
- // Harder case: search for a waiter and wake it.
- lockWithRank(&root.lock, lockRankRoot)
- if root.nwait.Load() == 0 {
- // The count is already consumed by another goroutine,
- // so no need to wake up another goroutine.
- unlock(&root.lock)
- return
- }
- s, t0 := root.dequeue(addr)
- if s != nil {
- root.nwait.Add(-1)
- }
- unlock(&root.lock)
- if s != nil { // May be slow or even yield, so unlock first
- acquiretime := s.acquiretime
- if acquiretime != 0 {
- mutexevent(t0-acquiretime, 3+skipframes)
- }
- if s.ticket != 0 {
- throw("corrupted semaphore ticket")
- }
- if handoff && cansemacquire(addr) {
- s.ticket = 1
- }
- readyWithTime(s, 5+skipframes)
- if s.ticket == 1 && getg().m.locks == 0 {
- // Direct G handoff
- // readyWithTime has added the waiter G as runnext in the
- // current P; we now call the scheduler so that we start running
- // the waiter G immediately.
- // Note that waiter inherits our time slice: this is desirable
- // to avoid having a highly contended semaphore hog the P
- // indefinitely. goyield is like Gosched, but it emits a
- // "preempted" trace event instead and, more importantly, puts
- // the current G on the local runq instead of the global one.
- // We only do this in the starving regime (handoff=true), as in
- // the non-starving case it is possible for a different waiter
- // to acquire the semaphore while we are yielding/scheduling,
- // and this would be wasteful. We wait instead to enter starving
- // regime, and then we start to do direct handoffs of ticket and
- // P.
- // See issue 33747 for discussion.
- goyield()
- }
- }
-}
-
-func cansemacquire(addr *uint32) bool {
- for {
- v := atomic.Load(addr)
- if v == 0 {
- return false
- }
- if atomic.Cas(addr, v, v-1) {
- return true
- }
- }
-}
-
-// queue adds s to the blocked goroutines in semaRoot.
-func (root *semaRoot) queue(addr *uint32, s *sudog, lifo bool) {
- s.g = getg()
- s.elem = unsafe.Pointer(addr)
- s.next = nil
- s.prev = nil
-
- var last *sudog
- pt := &root.treap
- for t := *pt; t != nil; t = *pt {
- if t.elem == unsafe.Pointer(addr) {
- // Already have addr in list.
- if lifo {
- // Substitute s in t's place in treap.
- *pt = s
- s.ticket = t.ticket
- s.acquiretime = t.acquiretime
- s.parent = t.parent
- s.prev = t.prev
- s.next = t.next
- if s.prev != nil {
- s.prev.parent = s
- }
- if s.next != nil {
- s.next.parent = s
- }
- // Add t first in s's wait list.
- s.waitlink = t
- s.waittail = t.waittail
- if s.waittail == nil {
- s.waittail = t
- }
- t.parent = nil
- t.prev = nil
- t.next = nil
- t.waittail = nil
- } else {
- // Add s to end of t's wait list.
- if t.waittail == nil {
- t.waitlink = s
- } else {
- t.waittail.waitlink = s
- }
- t.waittail = s
- s.waitlink = nil
- }
- return
- }
- last = t
- if uintptr(unsafe.Pointer(addr)) < uintptr(t.elem) {
- pt = &t.prev
- } else {
- pt = &t.next
- }
- }
-
- // Add s as new leaf in tree of unique addrs.
- // The balanced tree is a treap using ticket as the random heap priority.
- // That is, it is a binary tree ordered according to the elem addresses,
- // but then among the space of possible binary trees respecting those
- // addresses, it is kept balanced on average by maintaining a heap ordering
- // on the ticket: s.ticket <= both s.prev.ticket and s.next.ticket.
- // https://en.wikipedia.org/wiki/Treap
- // https://faculty.washington.edu/aragon/pubs/rst89.pdf
- //
- // s.ticket compared with zero in couple of places, therefore set lowest bit.
- // It will not affect treap's quality noticeably.
- s.ticket = fastrand() | 1
- s.parent = last
- *pt = s
-
- // Rotate up into tree according to ticket (priority).
- for s.parent != nil && s.parent.ticket > s.ticket {
- if s.parent.prev == s {
- root.rotateRight(s.parent)
- } else {
- if s.parent.next != s {
- panic("semaRoot queue")
- }
- root.rotateLeft(s.parent)
- }
- }
-}
-
-// dequeue searches for and finds the first goroutine
-// in semaRoot blocked on addr.
-// If the sudog was being profiled, dequeue returns the time
-// at which it was woken up as now. Otherwise now is 0.
-func (root *semaRoot) dequeue(addr *uint32) (found *sudog, now int64) {
- ps := &root.treap
- s := *ps
- for ; s != nil; s = *ps {
- if s.elem == unsafe.Pointer(addr) {
- goto Found
- }
- if uintptr(unsafe.Pointer(addr)) < uintptr(s.elem) {
- ps = &s.prev
- } else {
- ps = &s.next
- }
- }
- return nil, 0
-
-Found:
- now = int64(0)
- if s.acquiretime != 0 {
- now = cputicks()
- }
- if t := s.waitlink; t != nil {
- // Substitute t, also waiting on addr, for s in root tree of unique addrs.
- *ps = t
- t.ticket = s.ticket
- t.parent = s.parent
- t.prev = s.prev
- if t.prev != nil {
- t.prev.parent = t
- }
- t.next = s.next
- if t.next != nil {
- t.next.parent = t
- }
- if t.waitlink != nil {
- t.waittail = s.waittail
- } else {
- t.waittail = nil
- }
- t.acquiretime = now
- s.waitlink = nil
- s.waittail = nil
- } else {
- // Rotate s down to be leaf of tree for removal, respecting priorities.
- for s.next != nil || s.prev != nil {
- if s.next == nil || s.prev != nil && s.prev.ticket < s.next.ticket {
- root.rotateRight(s)
- } else {
- root.rotateLeft(s)
- }
- }
- // Remove s, now a leaf.
- if s.parent != nil {
- if s.parent.prev == s {
- s.parent.prev = nil
- } else {
- s.parent.next = nil
- }
- } else {
- root.treap = nil
- }
- }
- s.parent = nil
- s.elem = nil
- s.next = nil
- s.prev = nil
- s.ticket = 0
- return s, now
-}
-
-// rotateLeft rotates the tree rooted at node x.
-// turning (x a (y b c)) into (y (x a b) c).
-func (root *semaRoot) rotateLeft(x *sudog) {
- // p -> (x a (y b c))
- p := x.parent
- y := x.next
- b := y.prev
-
- y.prev = x
- x.parent = y
- x.next = b
- if b != nil {
- b.parent = x
- }
-
- y.parent = p
- if p == nil {
- root.treap = y
- } else if p.prev == x {
- p.prev = y
- } else {
- if p.next != x {
- throw("semaRoot rotateLeft")
- }
- p.next = y
- }
-}
-
-// rotateRight rotates the tree rooted at node y.
-// turning (y (x a b) c) into (x a (y b c)).
-func (root *semaRoot) rotateRight(y *sudog) {
- // p -> (y (x a b) c)
- p := y.parent
- x := y.prev
- b := x.next
-
- x.next = y
- y.parent = x
- y.prev = b
- if b != nil {
- b.parent = y
- }
-
- x.parent = p
- if p == nil {
- root.treap = x
- } else if p.prev == y {
- p.prev = x
- } else {
- if p.next != y {
- throw("semaRoot rotateRight")
- }
- p.next = x
- }
-}
-
-// notifyList is a ticket-based notification list used to implement sync.Cond.
-//
-// It must be kept in sync with the sync package.
-type notifyList struct {
- // wait is the ticket number of the next waiter. It is atomically
- // incremented outside the lock.
- wait atomic.Uint32
-
- // notify is the ticket number of the next waiter to be notified. It can
- // be read outside the lock, but is only written to with lock held.
- //
- // Both wait & notify can wrap around, and such cases will be correctly
- // handled as long as their "unwrapped" difference is bounded by 2^31.
- // For this not to be the case, we'd need to have 2^31+ goroutines
- // blocked on the same condvar, which is currently not possible.
- notify uint32
-
- // List of parked waiters.
- lock mutex
- head *sudog
- tail *sudog
-}
-
-// less checks if a < b, considering a & b running counts that may overflow the
-// 32-bit range, and that their "unwrapped" difference is always less than 2^31.
-func less(a, b uint32) bool {
- return int32(a-b) < 0
-}
-
-// notifyListAdd adds the caller to a notify list such that it can receive
-// notifications. The caller must eventually call notifyListWait to wait for
-// such a notification, passing the returned ticket number.
-//
-//go:linkname notifyListAdd sync.runtime_notifyListAdd
-func notifyListAdd(l *notifyList) uint32 {
- // This may be called concurrently, for example, when called from
- // sync.Cond.Wait while holding a RWMutex in read mode.
- return l.wait.Add(1) - 1
-}
-
-// notifyListWait waits for a notification. If one has been sent since
-// notifyListAdd was called, it returns immediately. Otherwise, it blocks.
-//
-//go:linkname notifyListWait sync.runtime_notifyListWait
-func notifyListWait(l *notifyList, t uint32) {
- lockWithRank(&l.lock, lockRankNotifyList)
-
- // Return right away if this ticket has already been notified.
- if less(t, l.notify) {
- unlock(&l.lock)
- return
- }
-
- // Enqueue itself.
- s := acquireSudog()
- s.g = getg()
- s.ticket = t
- s.releasetime = 0
- t0 := int64(0)
- if blockprofilerate > 0 {
- t0 = cputicks()
- s.releasetime = -1
- }
- if l.tail == nil {
- l.head = s
- } else {
- l.tail.next = s
- }
- l.tail = s
- goparkunlock(&l.lock, waitReasonSyncCondWait, traceEvGoBlockCond, 3)
- if t0 != 0 {
- blockevent(s.releasetime-t0, 2)
- }
- releaseSudog(s)
-}
-
-// notifyListNotifyAll notifies all entries in the list.
-//
-//go:linkname notifyListNotifyAll sync.runtime_notifyListNotifyAll
-func notifyListNotifyAll(l *notifyList) {
- // Fast-path: if there are no new waiters since the last notification
- // we don't need to acquire the lock.
- if l.wait.Load() == atomic.Load(&l.notify) {
- return
- }
-
- // Pull the list out into a local variable, waiters will be readied
- // outside the lock.
- lockWithRank(&l.lock, lockRankNotifyList)
- s := l.head
- l.head = nil
- l.tail = nil
-
- // Update the next ticket to be notified. We can set it to the current
- // value of wait because any previous waiters are already in the list
- // or will notice that they have already been notified when trying to
- // add themselves to the list.
- atomic.Store(&l.notify, l.wait.Load())
- unlock(&l.lock)
-
- // Go through the local list and ready all waiters.
- for s != nil {
- next := s.next
- s.next = nil
- readyWithTime(s, 4)
- s = next
- }
-}
-
-// notifyListNotifyOne notifies one entry in the list.
-//
-//go:linkname notifyListNotifyOne sync.runtime_notifyListNotifyOne
-func notifyListNotifyOne(l *notifyList) {
- // Fast-path: if there are no new waiters since the last notification
- // we don't need to acquire the lock at all.
- if l.wait.Load() == atomic.Load(&l.notify) {
- return
- }
-
- lockWithRank(&l.lock, lockRankNotifyList)
-
- // Re-check under the lock if we need to do anything.
- t := l.notify
- if t == l.wait.Load() {
- unlock(&l.lock)
- return
- }
-
- // Update the next notify ticket number.
- atomic.Store(&l.notify, t+1)
-
- // Try to find the g that needs to be notified.
- // If it hasn't made it to the list yet we won't find it,
- // but it won't park itself once it sees the new notify number.
- //
- // This scan looks linear but essentially always stops quickly.
- // Because g's queue separately from taking numbers,
- // there may be minor reorderings in the list, but we
- // expect the g we're looking for to be near the front.
- // The g has others in front of it on the list only to the
- // extent that it lost the race, so the iteration will not
- // be too long. This applies even when the g is missing:
- // it hasn't yet gotten to sleep and has lost the race to
- // the (few) other g's that we find on the list.
- for p, s := (*sudog)(nil), l.head; s != nil; p, s = s, s.next {
- if s.ticket == t {
- n := s.next
- if p != nil {
- p.next = n
- } else {
- l.head = n
- }
- if n == nil {
- l.tail = p
- }
- unlock(&l.lock)
- s.next = nil
- readyWithTime(s, 4)
- return
- }
- }
- unlock(&l.lock)
-}
-
-//go:linkname notifyListCheck sync.runtime_notifyListCheck
-func notifyListCheck(sz uintptr) {
- if sz != unsafe.Sizeof(notifyList{}) {
- print("runtime: bad notifyList size - sync=", sz, " runtime=", unsafe.Sizeof(notifyList{}), "\n")
- throw("bad notifyList size")
- }
-}
-
-//go:linkname sync_nanotime sync.runtime_nanotime
-func sync_nanotime() int64 {
- return nanotime()
-}
diff --git a/contrib/go/_std_1.20/src/runtime/signal_arm64.go b/contrib/go/_std_1.20/src/runtime/signal_arm64.go
deleted file mode 100644
index c8b87817b4..0000000000
--- a/contrib/go/_std_1.20/src/runtime/signal_arm64.go
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2014 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.
-
-//go:build darwin || freebsd || linux || netbsd || openbsd
-
-package runtime
-
-import (
- "internal/abi"
- "runtime/internal/sys"
- "unsafe"
-)
-
-func dumpregs(c *sigctxt) {
- print("r0 ", hex(c.r0()), "\n")
- print("r1 ", hex(c.r1()), "\n")
- print("r2 ", hex(c.r2()), "\n")
- print("r3 ", hex(c.r3()), "\n")
- print("r4 ", hex(c.r4()), "\n")
- print("r5 ", hex(c.r5()), "\n")
- print("r6 ", hex(c.r6()), "\n")
- print("r7 ", hex(c.r7()), "\n")
- print("r8 ", hex(c.r8()), "\n")
- print("r9 ", hex(c.r9()), "\n")
- print("r10 ", hex(c.r10()), "\n")
- print("r11 ", hex(c.r11()), "\n")
- print("r12 ", hex(c.r12()), "\n")
- print("r13 ", hex(c.r13()), "\n")
- print("r14 ", hex(c.r14()), "\n")
- print("r15 ", hex(c.r15()), "\n")
- print("r16 ", hex(c.r16()), "\n")
- print("r17 ", hex(c.r17()), "\n")
- print("r18 ", hex(c.r18()), "\n")
- print("r19 ", hex(c.r19()), "\n")
- print("r20 ", hex(c.r20()), "\n")
- print("r21 ", hex(c.r21()), "\n")
- print("r22 ", hex(c.r22()), "\n")
- print("r23 ", hex(c.r23()), "\n")
- print("r24 ", hex(c.r24()), "\n")
- print("r25 ", hex(c.r25()), "\n")
- print("r26 ", hex(c.r26()), "\n")
- print("r27 ", hex(c.r27()), "\n")
- print("r28 ", hex(c.r28()), "\n")
- print("r29 ", hex(c.r29()), "\n")
- print("lr ", hex(c.lr()), "\n")
- print("sp ", hex(c.sp()), "\n")
- print("pc ", hex(c.pc()), "\n")
- print("fault ", hex(c.fault()), "\n")
-}
-
-//go:nosplit
-//go:nowritebarrierrec
-func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) }
-
-func (c *sigctxt) setsigpc(x uint64) { c.set_pc(x) }
-func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) }
-func (c *sigctxt) siglr() uintptr { return uintptr(c.lr()) }
-
-// preparePanic sets up the stack to look like a call to sigpanic.
-func (c *sigctxt) preparePanic(sig uint32, gp *g) {
- // We arrange lr, and pc to pretend the panicking
- // function calls sigpanic directly.
- // Always save LR to stack so that panics in leaf
- // functions are correctly handled. This smashes
- // the stack frame but we're not going back there
- // anyway.
- sp := c.sp() - sys.StackAlign // needs only sizeof uint64, but must align the stack
- c.set_sp(sp)
- *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.lr()
-
- pc := gp.sigpc
-
- if shouldPushSigpanic(gp, pc, uintptr(c.lr())) {
- // Make it look the like faulting PC called sigpanic.
- c.set_lr(uint64(pc))
- }
-
- // In case we are panicking from external C code
- c.set_r28(uint64(uintptr(unsafe.Pointer(gp))))
- c.set_pc(uint64(abi.FuncPCABIInternal(sigpanic)))
-}
-
-func (c *sigctxt) pushCall(targetPC, resumePC uintptr) {
- // Push the LR to stack, as we'll clobber it in order to
- // push the call. The function being pushed is responsible
- // for restoring the LR and setting the SP back.
- // This extra space is known to gentraceback.
- sp := c.sp() - 16 // SP needs 16-byte alignment
- c.set_sp(sp)
- *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.lr()
- // Set up PC and LR to pretend the function being signaled
- // calls targetPC at resumePC.
- c.set_lr(uint64(resumePC))
- c.set_pc(uint64(targetPC))
-}
diff --git a/contrib/go/_std_1.20/src/runtime/signal_unix.go b/contrib/go/_std_1.20/src/runtime/signal_unix.go
deleted file mode 100644
index c1abe62cb3..0000000000
--- a/contrib/go/_std_1.20/src/runtime/signal_unix.go
+++ /dev/null
@@ -1,1358 +0,0 @@
-// Copyright 2012 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.
-
-//go:build unix
-
-package runtime
-
-import (
- "internal/abi"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// sigTabT is the type of an entry in the global sigtable array.
-// sigtable is inherently system dependent, and appears in OS-specific files,
-// but sigTabT is the same for all Unixy systems.
-// The sigtable array is indexed by a system signal number to get the flags
-// and printable name of each signal.
-type sigTabT struct {
- flags int32
- name string
-}
-
-//go:linkname os_sigpipe os.sigpipe
-func os_sigpipe() {
- systemstack(sigpipe)
-}
-
-func signame(sig uint32) string {
- if sig >= uint32(len(sigtable)) {
- return ""
- }
- return sigtable[sig].name
-}
-
-const (
- _SIG_DFL uintptr = 0
- _SIG_IGN uintptr = 1
-)
-
-// sigPreempt is the signal used for non-cooperative preemption.
-//
-// There's no good way to choose this signal, but there are some
-// heuristics:
-//
-// 1. It should be a signal that's passed-through by debuggers by
-// default. On Linux, this is SIGALRM, SIGURG, SIGCHLD, SIGIO,
-// SIGVTALRM, SIGPROF, and SIGWINCH, plus some glibc-internal signals.
-//
-// 2. It shouldn't be used internally by libc in mixed Go/C binaries
-// because libc may assume it's the only thing that can handle these
-// signals. For example SIGCANCEL or SIGSETXID.
-//
-// 3. It should be a signal that can happen spuriously without
-// consequences. For example, SIGALRM is a bad choice because the
-// signal handler can't tell if it was caused by the real process
-// alarm or not (arguably this means the signal is broken, but I
-// digress). SIGUSR1 and SIGUSR2 are also bad because those are often
-// used in meaningful ways by applications.
-//
-// 4. We need to deal with platforms without real-time signals (like
-// macOS), so those are out.
-//
-// We use SIGURG because it meets all of these criteria, is extremely
-// unlikely to be used by an application for its "real" meaning (both
-// because out-of-band data is basically unused and because SIGURG
-// doesn't report which socket has the condition, making it pretty
-// useless), and even if it is, the application has to be ready for
-// spurious SIGURG. SIGIO wouldn't be a bad choice either, but is more
-// likely to be used for real.
-const sigPreempt = _SIGURG
-
-// Stores the signal handlers registered before Go installed its own.
-// These signal handlers will be invoked in cases where Go doesn't want to
-// handle a particular signal (e.g., signal occurred on a non-Go thread).
-// See sigfwdgo for more information on when the signals are forwarded.
-//
-// This is read by the signal handler; accesses should use
-// atomic.Loaduintptr and atomic.Storeuintptr.
-var fwdSig [_NSIG]uintptr
-
-// handlingSig is indexed by signal number and is non-zero if we are
-// currently handling the signal. Or, to put it another way, whether
-// the signal handler is currently set to the Go signal handler or not.
-// This is uint32 rather than bool so that we can use atomic instructions.
-var handlingSig [_NSIG]uint32
-
-// channels for synchronizing signal mask updates with the signal mask
-// thread
-var (
- disableSigChan chan uint32
- enableSigChan chan uint32
- maskUpdatedChan chan struct{}
-)
-
-func init() {
- // _NSIG is the number of signals on this operating system.
- // sigtable should describe what to do for all the possible signals.
- if len(sigtable) != _NSIG {
- print("runtime: len(sigtable)=", len(sigtable), " _NSIG=", _NSIG, "\n")
- throw("bad sigtable len")
- }
-}
-
-var signalsOK bool
-
-// Initialize signals.
-// Called by libpreinit so runtime may not be initialized.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func initsig(preinit bool) {
- if !preinit {
- // It's now OK for signal handlers to run.
- signalsOK = true
- }
-
- // For c-archive/c-shared this is called by libpreinit with
- // preinit == true.
- if (isarchive || islibrary) && !preinit {
- return
- }
-
- for i := uint32(0); i < _NSIG; i++ {
- t := &sigtable[i]
- if t.flags == 0 || t.flags&_SigDefault != 0 {
- continue
- }
-
- // We don't need to use atomic operations here because
- // there shouldn't be any other goroutines running yet.
- fwdSig[i] = getsig(i)
-
- if !sigInstallGoHandler(i) {
- // Even if we are not installing a signal handler,
- // set SA_ONSTACK if necessary.
- if fwdSig[i] != _SIG_DFL && fwdSig[i] != _SIG_IGN {
- setsigstack(i)
- } else if fwdSig[i] == _SIG_IGN {
- sigInitIgnored(i)
- }
- continue
- }
-
- handlingSig[i] = 1
- setsig(i, abi.FuncPCABIInternal(sighandler))
- }
-}
-
-//go:nosplit
-//go:nowritebarrierrec
-func sigInstallGoHandler(sig uint32) bool {
- // For some signals, we respect an inherited SIG_IGN handler
- // rather than insist on installing our own default handler.
- // Even these signals can be fetched using the os/signal package.
- switch sig {
- case _SIGHUP, _SIGINT:
- if atomic.Loaduintptr(&fwdSig[sig]) == _SIG_IGN {
- return false
- }
- }
-
- if (GOOS == "linux" || GOOS == "android") && !iscgo && sig == sigPerThreadSyscall {
- // sigPerThreadSyscall is the same signal used by glibc for
- // per-thread syscalls on Linux. We use it for the same purpose
- // in non-cgo binaries.
- return true
- }
-
- t := &sigtable[sig]
- if t.flags&_SigSetStack != 0 {
- return false
- }
-
- // When built using c-archive or c-shared, only install signal
- // handlers for synchronous signals and SIGPIPE and sigPreempt.
- if (isarchive || islibrary) && t.flags&_SigPanic == 0 && sig != _SIGPIPE && sig != sigPreempt {
- return false
- }
-
- return true
-}
-
-// sigenable enables the Go signal handler to catch the signal sig.
-// It is only called while holding the os/signal.handlers lock,
-// via os/signal.enableSignal and signal_enable.
-func sigenable(sig uint32) {
- if sig >= uint32(len(sigtable)) {
- return
- }
-
- // SIGPROF is handled specially for profiling.
- if sig == _SIGPROF {
- return
- }
-
- t := &sigtable[sig]
- if t.flags&_SigNotify != 0 {
- ensureSigM()
- enableSigChan <- sig
- <-maskUpdatedChan
- if atomic.Cas(&handlingSig[sig], 0, 1) {
- atomic.Storeuintptr(&fwdSig[sig], getsig(sig))
- setsig(sig, abi.FuncPCABIInternal(sighandler))
- }
- }
-}
-
-// sigdisable disables the Go signal handler for the signal sig.
-// It is only called while holding the os/signal.handlers lock,
-// via os/signal.disableSignal and signal_disable.
-func sigdisable(sig uint32) {
- if sig >= uint32(len(sigtable)) {
- return
- }
-
- // SIGPROF is handled specially for profiling.
- if sig == _SIGPROF {
- return
- }
-
- t := &sigtable[sig]
- if t.flags&_SigNotify != 0 {
- ensureSigM()
- disableSigChan <- sig
- <-maskUpdatedChan
-
- // If initsig does not install a signal handler for a
- // signal, then to go back to the state before Notify
- // we should remove the one we installed.
- if !sigInstallGoHandler(sig) {
- atomic.Store(&handlingSig[sig], 0)
- setsig(sig, atomic.Loaduintptr(&fwdSig[sig]))
- }
- }
-}
-
-// sigignore ignores the signal sig.
-// It is only called while holding the os/signal.handlers lock,
-// via os/signal.ignoreSignal and signal_ignore.
-func sigignore(sig uint32) {
- if sig >= uint32(len(sigtable)) {
- return
- }
-
- // SIGPROF is handled specially for profiling.
- if sig == _SIGPROF {
- return
- }
-
- t := &sigtable[sig]
- if t.flags&_SigNotify != 0 {
- atomic.Store(&handlingSig[sig], 0)
- setsig(sig, _SIG_IGN)
- }
-}
-
-// clearSignalHandlers clears all signal handlers that are not ignored
-// back to the default. This is called by the child after a fork, so that
-// we can enable the signal mask for the exec without worrying about
-// running a signal handler in the child.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func clearSignalHandlers() {
- for i := uint32(0); i < _NSIG; i++ {
- if atomic.Load(&handlingSig[i]) != 0 {
- setsig(i, _SIG_DFL)
- }
- }
-}
-
-// setProcessCPUProfilerTimer is called when the profiling timer changes.
-// It is called with prof.signalLock held. hz is the new timer, and is 0 if
-// profiling is being disabled. Enable or disable the signal as
-// required for -buildmode=c-archive.
-func setProcessCPUProfilerTimer(hz int32) {
- if hz != 0 {
- // Enable the Go signal handler if not enabled.
- if atomic.Cas(&handlingSig[_SIGPROF], 0, 1) {
- h := getsig(_SIGPROF)
- // If no signal handler was installed before, then we record
- // _SIG_IGN here. When we turn off profiling (below) we'll start
- // ignoring SIGPROF signals. We do this, rather than change
- // to SIG_DFL, because there may be a pending SIGPROF
- // signal that has not yet been delivered to some other thread.
- // If we change to SIG_DFL when turning off profiling, the
- // program will crash when that SIGPROF is delivered. We assume
- // that programs that use profiling don't want to crash on a
- // stray SIGPROF. See issue 19320.
- // We do the change here instead of when turning off profiling,
- // because there we may race with a signal handler running
- // concurrently, in particular, sigfwdgo may observe _SIG_DFL and
- // die. See issue 43828.
- if h == _SIG_DFL {
- h = _SIG_IGN
- }
- atomic.Storeuintptr(&fwdSig[_SIGPROF], h)
- setsig(_SIGPROF, abi.FuncPCABIInternal(sighandler))
- }
-
- var it itimerval
- it.it_interval.tv_sec = 0
- it.it_interval.set_usec(1000000 / hz)
- it.it_value = it.it_interval
- setitimer(_ITIMER_PROF, &it, nil)
- } else {
- setitimer(_ITIMER_PROF, &itimerval{}, nil)
-
- // If the Go signal handler should be disabled by default,
- // switch back to the signal handler that was installed
- // when we enabled profiling. We don't try to handle the case
- // of a program that changes the SIGPROF handler while Go
- // profiling is enabled.
- if !sigInstallGoHandler(_SIGPROF) {
- if atomic.Cas(&handlingSig[_SIGPROF], 1, 0) {
- h := atomic.Loaduintptr(&fwdSig[_SIGPROF])
- setsig(_SIGPROF, h)
- }
- }
- }
-}
-
-// setThreadCPUProfilerHz makes any thread-specific changes required to
-// implement profiling at a rate of hz.
-// No changes required on Unix systems when using setitimer.
-func setThreadCPUProfilerHz(hz int32) {
- getg().m.profilehz = hz
-}
-
-func sigpipe() {
- if signal_ignored(_SIGPIPE) || sigsend(_SIGPIPE) {
- return
- }
- dieFromSignal(_SIGPIPE)
-}
-
-// doSigPreempt handles a preemption signal on gp.
-func doSigPreempt(gp *g, ctxt *sigctxt) {
- // Check if this G wants to be preempted and is safe to
- // preempt.
- if wantAsyncPreempt(gp) {
- if ok, newpc := isAsyncSafePoint(gp, ctxt.sigpc(), ctxt.sigsp(), ctxt.siglr()); ok {
- // Adjust the PC and inject a call to asyncPreempt.
- ctxt.pushCall(abi.FuncPCABI0(asyncPreempt), newpc)
- }
- }
-
- // Acknowledge the preemption.
- gp.m.preemptGen.Add(1)
- gp.m.signalPending.Store(0)
-
- if GOOS == "darwin" || GOOS == "ios" {
- pendingPreemptSignals.Add(-1)
- }
-}
-
-const preemptMSupported = true
-
-// preemptM sends a preemption request to mp. This request may be
-// handled asynchronously and may be coalesced with other requests to
-// the M. When the request is received, if the running G or P are
-// marked for preemption and the goroutine is at an asynchronous
-// safe-point, it will preempt the goroutine. It always atomically
-// increments mp.preemptGen after handling a preemption request.
-func preemptM(mp *m) {
- // On Darwin, don't try to preempt threads during exec.
- // Issue #41702.
- if GOOS == "darwin" || GOOS == "ios" {
- execLock.rlock()
- }
-
- if mp.signalPending.CompareAndSwap(0, 1) {
- if GOOS == "darwin" || GOOS == "ios" {
- pendingPreemptSignals.Add(1)
- }
-
- // If multiple threads are preempting the same M, it may send many
- // signals to the same M such that it hardly make progress, causing
- // live-lock problem. Apparently this could happen on darwin. See
- // issue #37741.
- // Only send a signal if there isn't already one pending.
- signalM(mp, sigPreempt)
- }
-
- if GOOS == "darwin" || GOOS == "ios" {
- execLock.runlock()
- }
-}
-
-// sigFetchG fetches the value of G safely when running in a signal handler.
-// On some architectures, the g value may be clobbered when running in a VDSO.
-// See issue #32912.
-//
-//go:nosplit
-func sigFetchG(c *sigctxt) *g {
- switch GOARCH {
- case "arm", "arm64", "ppc64", "ppc64le", "riscv64", "s390x":
- if !iscgo && inVDSOPage(c.sigpc()) {
- // When using cgo, we save the g on TLS and load it from there
- // in sigtramp. Just use that.
- // Otherwise, before making a VDSO call we save the g to the
- // bottom of the signal stack. Fetch from there.
- // TODO: in efence mode, stack is sysAlloc'd, so this wouldn't
- // work.
- sp := getcallersp()
- s := spanOf(sp)
- if s != nil && s.state.get() == mSpanManual && s.base() < sp && sp < s.limit {
- gp := *(**g)(unsafe.Pointer(s.base()))
- return gp
- }
- return nil
- }
- }
- return getg()
-}
-
-// sigtrampgo is called from the signal handler function, sigtramp,
-// written in assembly code.
-// This is called by the signal handler, and the world may be stopped.
-//
-// It must be nosplit because getg() is still the G that was running
-// (if any) when the signal was delivered, but it's (usually) called
-// on the gsignal stack. Until this switches the G to gsignal, the
-// stack bounds check won't work.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
- if sigfwdgo(sig, info, ctx) {
- return
- }
- c := &sigctxt{info, ctx}
- gp := sigFetchG(c)
- setg(gp)
- if gp == nil {
- if sig == _SIGPROF {
- // Some platforms (Linux) have per-thread timers, which we use in
- // combination with the process-wide timer. Avoid double-counting.
- if validSIGPROF(nil, c) {
- sigprofNonGoPC(c.sigpc())
- }
- return
- }
- if sig == sigPreempt && preemptMSupported && debug.asyncpreemptoff == 0 {
- // This is probably a signal from preemptM sent
- // while executing Go code but received while
- // executing non-Go code.
- // We got past sigfwdgo, so we know that there is
- // no non-Go signal handler for sigPreempt.
- // The default behavior for sigPreempt is to ignore
- // the signal, so badsignal will be a no-op anyway.
- if GOOS == "darwin" || GOOS == "ios" {
- pendingPreemptSignals.Add(-1)
- }
- return
- }
- c.fixsigcode(sig)
- badsignal(uintptr(sig), c)
- return
- }
-
- setg(gp.m.gsignal)
-
- // If some non-Go code called sigaltstack, adjust.
- var gsignalStack gsignalStack
- setStack := adjustSignalStack(sig, gp.m, &gsignalStack)
- if setStack {
- gp.m.gsignal.stktopsp = getcallersp()
- }
-
- if gp.stackguard0 == stackFork {
- signalDuringFork(sig)
- }
-
- c.fixsigcode(sig)
- sighandler(sig, info, ctx, gp)
- setg(gp)
- if setStack {
- restoreGsignalStack(&gsignalStack)
- }
-}
-
-// If the signal handler receives a SIGPROF signal on a non-Go thread,
-// it tries to collect a traceback into sigprofCallers.
-// sigprofCallersUse is set to non-zero while sigprofCallers holds a traceback.
-var sigprofCallers cgoCallers
-var sigprofCallersUse uint32
-
-// sigprofNonGo is called if we receive a SIGPROF signal on a non-Go thread,
-// and the signal handler collected a stack trace in sigprofCallers.
-// When this is called, sigprofCallersUse will be non-zero.
-// g is nil, and what we can do is very limited.
-//
-// It is called from the signal handling functions written in assembly code that
-// are active for cgo programs, cgoSigtramp and sigprofNonGoWrapper, which have
-// not verified that the SIGPROF delivery corresponds to the best available
-// profiling source for this thread.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func sigprofNonGo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
- if prof.hz.Load() != 0 {
- c := &sigctxt{info, ctx}
- // Some platforms (Linux) have per-thread timers, which we use in
- // combination with the process-wide timer. Avoid double-counting.
- if validSIGPROF(nil, c) {
- n := 0
- for n < len(sigprofCallers) && sigprofCallers[n] != 0 {
- n++
- }
- cpuprof.addNonGo(sigprofCallers[:n])
- }
- }
-
- atomic.Store(&sigprofCallersUse, 0)
-}
-
-// sigprofNonGoPC is called when a profiling signal arrived on a
-// non-Go thread and we have a single PC value, not a stack trace.
-// g is nil, and what we can do is very limited.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func sigprofNonGoPC(pc uintptr) {
- if prof.hz.Load() != 0 {
- stk := []uintptr{
- pc,
- abi.FuncPCABIInternal(_ExternalCode) + sys.PCQuantum,
- }
- cpuprof.addNonGo(stk)
- }
-}
-
-// adjustSignalStack adjusts the current stack guard based on the
-// stack pointer that is actually in use while handling a signal.
-// We do this in case some non-Go code called sigaltstack.
-// This reports whether the stack was adjusted, and if so stores the old
-// signal stack in *gsigstack.
-//
-//go:nosplit
-func adjustSignalStack(sig uint32, mp *m, gsigStack *gsignalStack) bool {
- sp := uintptr(unsafe.Pointer(&sig))
- if sp >= mp.gsignal.stack.lo && sp < mp.gsignal.stack.hi {
- return false
- }
-
- var st stackt
- sigaltstack(nil, &st)
- stsp := uintptr(unsafe.Pointer(st.ss_sp))
- if st.ss_flags&_SS_DISABLE == 0 && sp >= stsp && sp < stsp+st.ss_size {
- setGsignalStack(&st, gsigStack)
- return true
- }
-
- if sp >= mp.g0.stack.lo && sp < mp.g0.stack.hi {
- // The signal was delivered on the g0 stack.
- // This can happen when linked with C code
- // using the thread sanitizer, which collects
- // signals then delivers them itself by calling
- // the signal handler directly when C code,
- // including C code called via cgo, calls a
- // TSAN-intercepted function such as malloc.
- //
- // We check this condition last as g0.stack.lo
- // may be not very accurate (see mstart).
- st := stackt{ss_size: mp.g0.stack.hi - mp.g0.stack.lo}
- setSignalstackSP(&st, mp.g0.stack.lo)
- setGsignalStack(&st, gsigStack)
- return true
- }
-
- // sp is not within gsignal stack, g0 stack, or sigaltstack. Bad.
- setg(nil)
- needm()
- if st.ss_flags&_SS_DISABLE != 0 {
- noSignalStack(sig)
- } else {
- sigNotOnStack(sig)
- }
- dropm()
- return false
-}
-
-// crashing is the number of m's we have waited for when implementing
-// GOTRACEBACK=crash when a signal is received.
-var crashing int32
-
-// testSigtrap and testSigusr1 are used by the runtime tests. If
-// non-nil, it is called on SIGTRAP/SIGUSR1. If it returns true, the
-// normal behavior on this signal is suppressed.
-var testSigtrap func(info *siginfo, ctxt *sigctxt, gp *g) bool
-var testSigusr1 func(gp *g) bool
-
-// sighandler is invoked when a signal occurs. The global g will be
-// set to a gsignal goroutine and we will be running on the alternate
-// signal stack. The parameter gp will be the value of the global g
-// when the signal occurred. The sig, info, and ctxt parameters are
-// from the system signal handler: they are the parameters passed when
-// the SA is passed to the sigaction system call.
-//
-// The garbage collector may have stopped the world, so write barriers
-// are not allowed.
-//
-//go:nowritebarrierrec
-func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
- // The g executing the signal handler. This is almost always
- // mp.gsignal. See delayedSignal for an exception.
- gsignal := getg()
- mp := gsignal.m
- c := &sigctxt{info, ctxt}
-
- // Cgo TSAN (not the Go race detector) intercepts signals and calls the
- // signal handler at a later time. When the signal handler is called, the
- // memory may have changed, but the signal context remains old. The
- // unmatched signal context and memory makes it unsafe to unwind or inspect
- // the stack. So we ignore delayed non-fatal signals that will cause a stack
- // inspection (profiling signal and preemption signal).
- // cgo_yield is only non-nil for TSAN, and is specifically used to trigger
- // signal delivery. We use that as an indicator of delayed signals.
- // For delayed signals, the handler is called on the g0 stack (see
- // adjustSignalStack).
- delayedSignal := *cgo_yield != nil && mp != nil && gsignal.stack == mp.g0.stack
-
- if sig == _SIGPROF {
- // Some platforms (Linux) have per-thread timers, which we use in
- // combination with the process-wide timer. Avoid double-counting.
- if !delayedSignal && validSIGPROF(mp, c) {
- sigprof(c.sigpc(), c.sigsp(), c.siglr(), gp, mp)
- }
- return
- }
-
- if sig == _SIGTRAP && testSigtrap != nil && testSigtrap(info, (*sigctxt)(noescape(unsafe.Pointer(c))), gp) {
- return
- }
-
- if sig == _SIGUSR1 && testSigusr1 != nil && testSigusr1(gp) {
- return
- }
-
- if (GOOS == "linux" || GOOS == "android") && sig == sigPerThreadSyscall {
- // sigPerThreadSyscall is the same signal used by glibc for
- // per-thread syscalls on Linux. We use it for the same purpose
- // in non-cgo binaries. Since this signal is not _SigNotify,
- // there is nothing more to do once we run the syscall.
- runPerThreadSyscall()
- return
- }
-
- if sig == sigPreempt && debug.asyncpreemptoff == 0 && !delayedSignal {
- // Might be a preemption signal.
- doSigPreempt(gp, c)
- // Even if this was definitely a preemption signal, it
- // may have been coalesced with another signal, so we
- // still let it through to the application.
- }
-
- flags := int32(_SigThrow)
- if sig < uint32(len(sigtable)) {
- flags = sigtable[sig].flags
- }
- if !c.sigFromUser() && flags&_SigPanic != 0 && gp.throwsplit {
- // We can't safely sigpanic because it may grow the
- // stack. Abort in the signal handler instead.
- flags = _SigThrow
- }
- if isAbortPC(c.sigpc()) {
- // On many architectures, the abort function just
- // causes a memory fault. Don't turn that into a panic.
- flags = _SigThrow
- }
- if !c.sigFromUser() && flags&_SigPanic != 0 {
- // The signal is going to cause a panic.
- // Arrange the stack so that it looks like the point
- // where the signal occurred made a call to the
- // function sigpanic. Then set the PC to sigpanic.
-
- // Have to pass arguments out of band since
- // augmenting the stack frame would break
- // the unwinding code.
- gp.sig = sig
- gp.sigcode0 = uintptr(c.sigcode())
- gp.sigcode1 = uintptr(c.fault())
- gp.sigpc = c.sigpc()
-
- c.preparePanic(sig, gp)
- return
- }
-
- if c.sigFromUser() || flags&_SigNotify != 0 {
- if sigsend(sig) {
- return
- }
- }
-
- if c.sigFromUser() && signal_ignored(sig) {
- return
- }
-
- if flags&_SigKill != 0 {
- dieFromSignal(sig)
- }
-
- // _SigThrow means that we should exit now.
- // If we get here with _SigPanic, it means that the signal
- // was sent to us by a program (c.sigFromUser() is true);
- // in that case, if we didn't handle it in sigsend, we exit now.
- if flags&(_SigThrow|_SigPanic) == 0 {
- return
- }
-
- mp.throwing = throwTypeRuntime
- mp.caughtsig.set(gp)
-
- if crashing == 0 {
- startpanic_m()
- }
-
- if sig < uint32(len(sigtable)) {
- print(sigtable[sig].name, "\n")
- } else {
- print("Signal ", sig, "\n")
- }
-
- if isSecureMode() {
- exit(2)
- }
-
- print("PC=", hex(c.sigpc()), " m=", mp.id, " sigcode=", c.sigcode(), "\n")
- if mp.incgo && gp == mp.g0 && mp.curg != nil {
- print("signal arrived during cgo execution\n")
- // Switch to curg so that we get a traceback of the Go code
- // leading up to the cgocall, which switched from curg to g0.
- gp = mp.curg
- }
- if sig == _SIGILL || sig == _SIGFPE {
- // It would be nice to know how long the instruction is.
- // Unfortunately, that's complicated to do in general (mostly for x86
- // and s930x, but other archs have non-standard instruction lengths also).
- // Opt to print 16 bytes, which covers most instructions.
- const maxN = 16
- n := uintptr(maxN)
- // We have to be careful, though. If we're near the end of
- // a page and the following page isn't mapped, we could
- // segfault. So make sure we don't straddle a page (even though
- // that could lead to printing an incomplete instruction).
- // We're assuming here we can read at least the page containing the PC.
- // I suppose it is possible that the page is mapped executable but not readable?
- pc := c.sigpc()
- if n > physPageSize-pc%physPageSize {
- n = physPageSize - pc%physPageSize
- }
- print("instruction bytes:")
- b := (*[maxN]byte)(unsafe.Pointer(pc))
- for i := uintptr(0); i < n; i++ {
- print(" ", hex(b[i]))
- }
- println()
- }
- print("\n")
-
- level, _, docrash := gotraceback()
- if level > 0 {
- goroutineheader(gp)
- tracebacktrap(c.sigpc(), c.sigsp(), c.siglr(), gp)
- if crashing > 0 && gp != mp.curg && mp.curg != nil && readgstatus(mp.curg)&^_Gscan == _Grunning {
- // tracebackothers on original m skipped this one; trace it now.
- goroutineheader(mp.curg)
- traceback(^uintptr(0), ^uintptr(0), 0, mp.curg)
- } else if crashing == 0 {
- tracebackothers(gp)
- print("\n")
- }
- dumpregs(c)
- }
-
- if docrash {
- crashing++
- if crashing < mcount()-int32(extraMCount) {
- // There are other m's that need to dump their stacks.
- // Relay SIGQUIT to the next m by sending it to the current process.
- // All m's that have already received SIGQUIT have signal masks blocking
- // receipt of any signals, so the SIGQUIT will go to an m that hasn't seen it yet.
- // When the last m receives the SIGQUIT, it will fall through to the call to
- // crash below. Just in case the relaying gets botched, each m involved in
- // the relay sleeps for 5 seconds and then does the crash/exit itself.
- // In expected operation, the last m has received the SIGQUIT and run
- // crash/exit and the process is gone, all long before any of the
- // 5-second sleeps have finished.
- print("\n-----\n\n")
- raiseproc(_SIGQUIT)
- usleep(5 * 1000 * 1000)
- }
- crash()
- }
-
- printDebugLog()
-
- exit(2)
-}
-
-// sigpanic turns a synchronous signal into a run-time panic.
-// If the signal handler sees a synchronous panic, it arranges the
-// stack to look like the function where the signal occurred called
-// sigpanic, sets the signal's PC value to sigpanic, and returns from
-// the signal handler. The effect is that the program will act as
-// though the function that got the signal simply called sigpanic
-// instead.
-//
-// This must NOT be nosplit because the linker doesn't know where
-// sigpanic calls can be injected.
-//
-// The signal handler must not inject a call to sigpanic if
-// getg().throwsplit, since sigpanic may need to grow the stack.
-//
-// This is exported via linkname to assembly in runtime/cgo.
-//
-//go:linkname sigpanic
-func sigpanic() {
- gp := getg()
- if !canpanic() {
- throw("unexpected signal during runtime execution")
- }
-
- switch gp.sig {
- case _SIGBUS:
- if gp.sigcode0 == _BUS_ADRERR && gp.sigcode1 < 0x1000 {
- panicmem()
- }
- // Support runtime/debug.SetPanicOnFault.
- if gp.paniconfault {
- panicmemAddr(gp.sigcode1)
- }
- print("unexpected fault address ", hex(gp.sigcode1), "\n")
- throw("fault")
- case _SIGSEGV:
- if (gp.sigcode0 == 0 || gp.sigcode0 == _SEGV_MAPERR || gp.sigcode0 == _SEGV_ACCERR) && gp.sigcode1 < 0x1000 {
- panicmem()
- }
- // Support runtime/debug.SetPanicOnFault.
- if gp.paniconfault {
- panicmemAddr(gp.sigcode1)
- }
- if inUserArenaChunk(gp.sigcode1) {
- // We could check that the arena chunk is explicitly set to fault,
- // but the fact that we faulted on accessing it is enough to prove
- // that it is.
- print("accessed data from freed user arena ", hex(gp.sigcode1), "\n")
- } else {
- print("unexpected fault address ", hex(gp.sigcode1), "\n")
- }
- throw("fault")
- case _SIGFPE:
- switch gp.sigcode0 {
- case _FPE_INTDIV:
- panicdivide()
- case _FPE_INTOVF:
- panicoverflow()
- }
- panicfloat()
- }
-
- if gp.sig >= uint32(len(sigtable)) {
- // can't happen: we looked up gp.sig in sigtable to decide to call sigpanic
- throw("unexpected signal value")
- }
- panic(errorString(sigtable[gp.sig].name))
-}
-
-// dieFromSignal kills the program with a signal.
-// This provides the expected exit status for the shell.
-// This is only called with fatal signals expected to kill the process.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func dieFromSignal(sig uint32) {
- unblocksig(sig)
- // Mark the signal as unhandled to ensure it is forwarded.
- atomic.Store(&handlingSig[sig], 0)
- raise(sig)
-
- // That should have killed us. On some systems, though, raise
- // sends the signal to the whole process rather than to just
- // the current thread, which means that the signal may not yet
- // have been delivered. Give other threads a chance to run and
- // pick up the signal.
- osyield()
- osyield()
- osyield()
-
- // If that didn't work, try _SIG_DFL.
- setsig(sig, _SIG_DFL)
- raise(sig)
-
- osyield()
- osyield()
- osyield()
-
- // If we are still somehow running, just exit with the wrong status.
- exit(2)
-}
-
-// raisebadsignal is called when a signal is received on a non-Go
-// thread, and the Go program does not want to handle it (that is, the
-// program has not called os/signal.Notify for the signal).
-func raisebadsignal(sig uint32, c *sigctxt) {
- if sig == _SIGPROF {
- // Ignore profiling signals that arrive on non-Go threads.
- return
- }
-
- var handler uintptr
- if sig >= _NSIG {
- handler = _SIG_DFL
- } else {
- handler = atomic.Loaduintptr(&fwdSig[sig])
- }
-
- // Reset the signal handler and raise the signal.
- // We are currently running inside a signal handler, so the
- // signal is blocked. We need to unblock it before raising the
- // signal, or the signal we raise will be ignored until we return
- // from the signal handler. We know that the signal was unblocked
- // before entering the handler, or else we would not have received
- // it. That means that we don't have to worry about blocking it
- // again.
- unblocksig(sig)
- setsig(sig, handler)
-
- // If we're linked into a non-Go program we want to try to
- // avoid modifying the original context in which the signal
- // was raised. If the handler is the default, we know it
- // is non-recoverable, so we don't have to worry about
- // re-installing sighandler. At this point we can just
- // return and the signal will be re-raised and caught by
- // the default handler with the correct context.
- //
- // On FreeBSD, the libthr sigaction code prevents
- // this from working so we fall through to raise.
- if GOOS != "freebsd" && (isarchive || islibrary) && handler == _SIG_DFL && !c.sigFromUser() {
- return
- }
-
- raise(sig)
-
- // Give the signal a chance to be delivered.
- // In almost all real cases the program is about to crash,
- // so sleeping here is not a waste of time.
- usleep(1000)
-
- // If the signal didn't cause the program to exit, restore the
- // Go signal handler and carry on.
- //
- // We may receive another instance of the signal before we
- // restore the Go handler, but that is not so bad: we know
- // that the Go program has been ignoring the signal.
- setsig(sig, abi.FuncPCABIInternal(sighandler))
-}
-
-//go:nosplit
-func crash() {
- // OS X core dumps are linear dumps of the mapped memory,
- // from the first virtual byte to the last, with zeros in the gaps.
- // Because of the way we arrange the address space on 64-bit systems,
- // this means the OS X core file will be >128 GB and even on a zippy
- // workstation can take OS X well over an hour to write (uninterruptible).
- // Save users from making that mistake.
- if GOOS == "darwin" && GOARCH == "amd64" {
- return
- }
-
- dieFromSignal(_SIGABRT)
-}
-
-// ensureSigM starts one global, sleeping thread to make sure at least one thread
-// is available to catch signals enabled for os/signal.
-func ensureSigM() {
- if maskUpdatedChan != nil {
- return
- }
- maskUpdatedChan = make(chan struct{})
- disableSigChan = make(chan uint32)
- enableSigChan = make(chan uint32)
- go func() {
- // Signal masks are per-thread, so make sure this goroutine stays on one
- // thread.
- LockOSThread()
- defer UnlockOSThread()
- // The sigBlocked mask contains the signals not active for os/signal,
- // initially all signals except the essential. When signal.Notify()/Stop is called,
- // sigenable/sigdisable in turn notify this thread to update its signal
- // mask accordingly.
- sigBlocked := sigset_all
- for i := range sigtable {
- if !blockableSig(uint32(i)) {
- sigdelset(&sigBlocked, i)
- }
- }
- sigprocmask(_SIG_SETMASK, &sigBlocked, nil)
- for {
- select {
- case sig := <-enableSigChan:
- if sig > 0 {
- sigdelset(&sigBlocked, int(sig))
- }
- case sig := <-disableSigChan:
- if sig > 0 && blockableSig(sig) {
- sigaddset(&sigBlocked, int(sig))
- }
- }
- sigprocmask(_SIG_SETMASK, &sigBlocked, nil)
- maskUpdatedChan <- struct{}{}
- }
- }()
-}
-
-// This is called when we receive a signal when there is no signal stack.
-// This can only happen if non-Go code calls sigaltstack to disable the
-// signal stack.
-func noSignalStack(sig uint32) {
- println("signal", sig, "received on thread with no signal stack")
- throw("non-Go code disabled sigaltstack")
-}
-
-// This is called if we receive a signal when there is a signal stack
-// but we are not on it. This can only happen if non-Go code called
-// sigaction without setting the SS_ONSTACK flag.
-func sigNotOnStack(sig uint32) {
- println("signal", sig, "received but handler not on signal stack")
- throw("non-Go code set up signal handler without SA_ONSTACK flag")
-}
-
-// signalDuringFork is called if we receive a signal while doing a fork.
-// We do not want signals at that time, as a signal sent to the process
-// group may be delivered to the child process, causing confusion.
-// This should never be called, because we block signals across the fork;
-// this function is just a safety check. See issue 18600 for background.
-func signalDuringFork(sig uint32) {
- println("signal", sig, "received during fork")
- throw("signal received during fork")
-}
-
-// This runs on a foreign stack, without an m or a g. No stack split.
-//
-//go:nosplit
-//go:norace
-//go:nowritebarrierrec
-func badsignal(sig uintptr, c *sigctxt) {
- if !iscgo && !cgoHasExtraM {
- // There is no extra M. needm will not be able to grab
- // an M. Instead of hanging, just crash.
- // Cannot call split-stack function as there is no G.
- writeErrStr("fatal: bad g in signal handler\n")
- exit(2)
- *(*uintptr)(unsafe.Pointer(uintptr(123))) = 2
- }
- needm()
- if !sigsend(uint32(sig)) {
- // A foreign thread received the signal sig, and the
- // Go code does not want to handle it.
- raisebadsignal(uint32(sig), c)
- }
- dropm()
-}
-
-//go:noescape
-func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
-
-// Determines if the signal should be handled by Go and if not, forwards the
-// signal to the handler that was installed before Go's. Returns whether the
-// signal was forwarded.
-// This is called by the signal handler, and the world may be stopped.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool {
- if sig >= uint32(len(sigtable)) {
- return false
- }
- fwdFn := atomic.Loaduintptr(&fwdSig[sig])
- flags := sigtable[sig].flags
-
- // If we aren't handling the signal, forward it.
- if atomic.Load(&handlingSig[sig]) == 0 || !signalsOK {
- // If the signal is ignored, doing nothing is the same as forwarding.
- if fwdFn == _SIG_IGN || (fwdFn == _SIG_DFL && flags&_SigIgn != 0) {
- return true
- }
- // We are not handling the signal and there is no other handler to forward to.
- // Crash with the default behavior.
- if fwdFn == _SIG_DFL {
- setsig(sig, _SIG_DFL)
- dieFromSignal(sig)
- return false
- }
-
- sigfwd(fwdFn, sig, info, ctx)
- return true
- }
-
- // This function and its caller sigtrampgo assumes SIGPIPE is delivered on the
- // originating thread. This property does not hold on macOS (golang.org/issue/33384),
- // so we have no choice but to ignore SIGPIPE.
- if (GOOS == "darwin" || GOOS == "ios") && sig == _SIGPIPE {
- return true
- }
-
- // If there is no handler to forward to, no need to forward.
- if fwdFn == _SIG_DFL {
- return false
- }
-
- c := &sigctxt{info, ctx}
- // Only forward synchronous signals and SIGPIPE.
- // Unfortunately, user generated SIGPIPEs will also be forwarded, because si_code
- // is set to _SI_USER even for a SIGPIPE raised from a write to a closed socket
- // or pipe.
- if (c.sigFromUser() || flags&_SigPanic == 0) && sig != _SIGPIPE {
- return false
- }
- // Determine if the signal occurred inside Go code. We test that:
- // (1) we weren't in VDSO page,
- // (2) we were in a goroutine (i.e., m.curg != nil), and
- // (3) we weren't in CGO.
- gp := sigFetchG(c)
- if gp != nil && gp.m != nil && gp.m.curg != nil && !gp.m.incgo {
- return false
- }
-
- // Signal not handled by Go, forward it.
- if fwdFn != _SIG_IGN {
- sigfwd(fwdFn, sig, info, ctx)
- }
-
- return true
-}
-
-// sigsave saves the current thread's signal mask into *p.
-// This is used to preserve the non-Go signal mask when a non-Go
-// thread calls a Go function.
-// This is nosplit and nowritebarrierrec because it is called by needm
-// which may be called on a non-Go thread with no g available.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func sigsave(p *sigset) {
- sigprocmask(_SIG_SETMASK, nil, p)
-}
-
-// msigrestore sets the current thread's signal mask to sigmask.
-// This is used to restore the non-Go signal mask when a non-Go thread
-// calls a Go function.
-// This is nosplit and nowritebarrierrec because it is called by dropm
-// after g has been cleared.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func msigrestore(sigmask sigset) {
- sigprocmask(_SIG_SETMASK, &sigmask, nil)
-}
-
-// sigsetAllExiting is used by sigblock(true) when a thread is
-// exiting. sigset_all is defined in OS specific code, and per GOOS
-// behavior may override this default for sigsetAllExiting: see
-// osinit().
-var sigsetAllExiting = sigset_all
-
-// sigblock blocks signals in the current thread's signal mask.
-// This is used to block signals while setting up and tearing down g
-// when a non-Go thread calls a Go function. When a thread is exiting
-// we use the sigsetAllExiting value, otherwise the OS specific
-// definition of sigset_all is used.
-// This is nosplit and nowritebarrierrec because it is called by needm
-// which may be called on a non-Go thread with no g available.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func sigblock(exiting bool) {
- if exiting {
- sigprocmask(_SIG_SETMASK, &sigsetAllExiting, nil)
- return
- }
- sigprocmask(_SIG_SETMASK, &sigset_all, nil)
-}
-
-// unblocksig removes sig from the current thread's signal mask.
-// This is nosplit and nowritebarrierrec because it is called from
-// dieFromSignal, which can be called by sigfwdgo while running in the
-// signal handler, on the signal stack, with no g available.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func unblocksig(sig uint32) {
- var set sigset
- sigaddset(&set, int(sig))
- sigprocmask(_SIG_UNBLOCK, &set, nil)
-}
-
-// minitSignals is called when initializing a new m to set the
-// thread's alternate signal stack and signal mask.
-func minitSignals() {
- minitSignalStack()
- minitSignalMask()
-}
-
-// minitSignalStack is called when initializing a new m to set the
-// alternate signal stack. If the alternate signal stack is not set
-// for the thread (the normal case) then set the alternate signal
-// stack to the gsignal stack. If the alternate signal stack is set
-// for the thread (the case when a non-Go thread sets the alternate
-// signal stack and then calls a Go function) then set the gsignal
-// stack to the alternate signal stack. We also set the alternate
-// signal stack to the gsignal stack if cgo is not used (regardless
-// of whether it is already set). Record which choice was made in
-// newSigstack, so that it can be undone in unminit.
-func minitSignalStack() {
- mp := getg().m
- var st stackt
- sigaltstack(nil, &st)
- if st.ss_flags&_SS_DISABLE != 0 || !iscgo {
- signalstack(&mp.gsignal.stack)
- mp.newSigstack = true
- } else {
- setGsignalStack(&st, &mp.goSigStack)
- mp.newSigstack = false
- }
-}
-
-// minitSignalMask is called when initializing a new m to set the
-// thread's signal mask. When this is called all signals have been
-// blocked for the thread. This starts with m.sigmask, which was set
-// either from initSigmask for a newly created thread or by calling
-// sigsave if this is a non-Go thread calling a Go function. It
-// removes all essential signals from the mask, thus causing those
-// signals to not be blocked. Then it sets the thread's signal mask.
-// After this is called the thread can receive signals.
-func minitSignalMask() {
- nmask := getg().m.sigmask
- for i := range sigtable {
- if !blockableSig(uint32(i)) {
- sigdelset(&nmask, i)
- }
- }
- sigprocmask(_SIG_SETMASK, &nmask, nil)
-}
-
-// unminitSignals is called from dropm, via unminit, to undo the
-// effect of calling minit on a non-Go thread.
-//
-//go:nosplit
-func unminitSignals() {
- if getg().m.newSigstack {
- st := stackt{ss_flags: _SS_DISABLE}
- sigaltstack(&st, nil)
- } else {
- // We got the signal stack from someone else. Restore
- // the Go-allocated stack in case this M gets reused
- // for another thread (e.g., it's an extram). Also, on
- // Android, libc allocates a signal stack for all
- // threads, so it's important to restore the Go stack
- // even on Go-created threads so we can free it.
- restoreGsignalStack(&getg().m.goSigStack)
- }
-}
-
-// blockableSig reports whether sig may be blocked by the signal mask.
-// We never want to block the signals marked _SigUnblock;
-// these are the synchronous signals that turn into a Go panic.
-// We never want to block the preemption signal if it is being used.
-// In a Go program--not a c-archive/c-shared--we never want to block
-// the signals marked _SigKill or _SigThrow, as otherwise it's possible
-// for all running threads to block them and delay their delivery until
-// we start a new thread. When linked into a C program we let the C code
-// decide on the disposition of those signals.
-func blockableSig(sig uint32) bool {
- flags := sigtable[sig].flags
- if flags&_SigUnblock != 0 {
- return false
- }
- if sig == sigPreempt && preemptMSupported && debug.asyncpreemptoff == 0 {
- return false
- }
- if isarchive || islibrary {
- return true
- }
- return flags&(_SigKill|_SigThrow) == 0
-}
-
-// gsignalStack saves the fields of the gsignal stack changed by
-// setGsignalStack.
-type gsignalStack struct {
- stack stack
- stackguard0 uintptr
- stackguard1 uintptr
- stktopsp uintptr
-}
-
-// setGsignalStack sets the gsignal stack of the current m to an
-// alternate signal stack returned from the sigaltstack system call.
-// It saves the old values in *old for use by restoreGsignalStack.
-// This is used when handling a signal if non-Go code has set the
-// alternate signal stack.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func setGsignalStack(st *stackt, old *gsignalStack) {
- gp := getg()
- if old != nil {
- old.stack = gp.m.gsignal.stack
- old.stackguard0 = gp.m.gsignal.stackguard0
- old.stackguard1 = gp.m.gsignal.stackguard1
- old.stktopsp = gp.m.gsignal.stktopsp
- }
- stsp := uintptr(unsafe.Pointer(st.ss_sp))
- gp.m.gsignal.stack.lo = stsp
- gp.m.gsignal.stack.hi = stsp + st.ss_size
- gp.m.gsignal.stackguard0 = stsp + _StackGuard
- gp.m.gsignal.stackguard1 = stsp + _StackGuard
-}
-
-// restoreGsignalStack restores the gsignal stack to the value it had
-// before entering the signal handler.
-//
-//go:nosplit
-//go:nowritebarrierrec
-func restoreGsignalStack(st *gsignalStack) {
- gp := getg().m.gsignal
- gp.stack = st.stack
- gp.stackguard0 = st.stackguard0
- gp.stackguard1 = st.stackguard1
- gp.stktopsp = st.stktopsp
-}
-
-// signalstack sets the current thread's alternate signal stack to s.
-//
-//go:nosplit
-func signalstack(s *stack) {
- st := stackt{ss_size: s.hi - s.lo}
- setSignalstackSP(&st, s.lo)
- sigaltstack(&st, nil)
-}
-
-// setsigsegv is used on darwin/arm64 to fake a segmentation fault.
-//
-// This is exported via linkname to assembly in runtime/cgo.
-//
-//go:nosplit
-//go:linkname setsigsegv
-func setsigsegv(pc uintptr) {
- gp := getg()
- gp.sig = _SIGSEGV
- gp.sigpc = pc
- gp.sigcode0 = _SEGV_MAPERR
- gp.sigcode1 = 0 // TODO: emulate si_addr
-}
diff --git a/contrib/go/_std_1.20/src/runtime/signal_windows.go b/contrib/go/_std_1.20/src/runtime/signal_windows.go
deleted file mode 100644
index 37986cd6b5..0000000000
--- a/contrib/go/_std_1.20/src/runtime/signal_windows.go
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright 2011 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 runtime
-
-import (
- "internal/abi"
- "runtime/internal/sys"
- "unsafe"
-)
-
-func disableWER() {
- // do not display Windows Error Reporting dialogue
- const (
- SEM_FAILCRITICALERRORS = 0x0001
- SEM_NOGPFAULTERRORBOX = 0x0002
- SEM_NOALIGNMENTFAULTEXCEPT = 0x0004
- SEM_NOOPENFILEERRORBOX = 0x8000
- )
- errormode := uint32(stdcall1(_SetErrorMode, SEM_NOGPFAULTERRORBOX))
- stdcall1(_SetErrorMode, uintptr(errormode)|SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX)
-}
-
-// in sys_windows_386.s and sys_windows_amd64.s
-func exceptiontramp()
-func firstcontinuetramp()
-func lastcontinuetramp()
-
-func initExceptionHandler() {
- stdcall2(_AddVectoredExceptionHandler, 1, abi.FuncPCABI0(exceptiontramp))
- if _AddVectoredContinueHandler == nil || GOARCH == "386" {
- // use SetUnhandledExceptionFilter for windows-386 or
- // if VectoredContinueHandler is unavailable.
- // note: SetUnhandledExceptionFilter handler won't be called, if debugging.
- stdcall1(_SetUnhandledExceptionFilter, abi.FuncPCABI0(lastcontinuetramp))
- } else {
- stdcall2(_AddVectoredContinueHandler, 1, abi.FuncPCABI0(firstcontinuetramp))
- stdcall2(_AddVectoredContinueHandler, 0, abi.FuncPCABI0(lastcontinuetramp))
- }
-}
-
-// isAbort returns true, if context r describes exception raised
-// by calling runtime.abort function.
-//
-//go:nosplit
-func isAbort(r *context) bool {
- pc := r.ip()
- if GOARCH == "386" || GOARCH == "amd64" || GOARCH == "arm" {
- // In the case of an abort, the exception IP is one byte after
- // the INT3 (this differs from UNIX OSes). Note that on ARM,
- // this means that the exception IP is no longer aligned.
- pc--
- }
- return isAbortPC(pc)
-}
-
-// isgoexception reports whether this exception should be translated
-// into a Go panic or throw.
-//
-// It is nosplit to avoid growing the stack in case we're aborting
-// because of a stack overflow.
-//
-//go:nosplit
-func isgoexception(info *exceptionrecord, r *context) bool {
- // Only handle exception if executing instructions in Go binary
- // (not Windows library code).
- // TODO(mwhudson): needs to loop to support shared libs
- if r.ip() < firstmoduledata.text || firstmoduledata.etext < r.ip() {
- return false
- }
-
- // Go will only handle some exceptions.
- switch info.exceptioncode {
- default:
- return false
- case _EXCEPTION_ACCESS_VIOLATION:
- case _EXCEPTION_INT_DIVIDE_BY_ZERO:
- case _EXCEPTION_INT_OVERFLOW:
- case _EXCEPTION_FLT_DENORMAL_OPERAND:
- case _EXCEPTION_FLT_DIVIDE_BY_ZERO:
- case _EXCEPTION_FLT_INEXACT_RESULT:
- case _EXCEPTION_FLT_OVERFLOW:
- case _EXCEPTION_FLT_UNDERFLOW:
- case _EXCEPTION_BREAKPOINT:
- case _EXCEPTION_ILLEGAL_INSTRUCTION: // breakpoint arrives this way on arm64
- }
- return true
-}
-
-// Called by sigtramp from Windows VEH handler.
-// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
-// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
-//
-// This is the first entry into Go code for exception handling. This
-// is nosplit to avoid growing the stack until we've checked for
-// _EXCEPTION_BREAKPOINT, which is raised if we overflow the g0 stack,
-//
-//go:nosplit
-func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
- if !isgoexception(info, r) {
- return _EXCEPTION_CONTINUE_SEARCH
- }
-
- if gp.throwsplit || isAbort(r) {
- // We can't safely sigpanic because it may grow the stack.
- // Or this is a call to abort.
- // Don't go through any more of the Windows handler chain.
- // Crash now.
- winthrow(info, r, gp)
- }
-
- // After this point, it is safe to grow the stack.
-
- // Make it look like a call to the signal func.
- // Have to pass arguments out of band since
- // augmenting the stack frame would break
- // the unwinding code.
- gp.sig = info.exceptioncode
- gp.sigcode0 = info.exceptioninformation[0]
- gp.sigcode1 = info.exceptioninformation[1]
- gp.sigpc = r.ip()
-
- // Only push runtime·sigpanic if r.ip() != 0.
- // If r.ip() == 0, probably panicked because of a
- // call to a nil func. Not pushing that onto sp will
- // make the trace look like a call to runtime·sigpanic instead.
- // (Otherwise the trace will end at runtime·sigpanic and we
- // won't get to see who faulted.)
- // Also don't push a sigpanic frame if the faulting PC
- // is the entry of asyncPreempt. In this case, we suspended
- // the thread right between the fault and the exception handler
- // starting to run, and we have pushed an asyncPreempt call.
- // The exception is not from asyncPreempt, so not to push a
- // sigpanic call to make it look like that. Instead, just
- // overwrite the PC. (See issue #35773)
- if r.ip() != 0 && r.ip() != abi.FuncPCABI0(asyncPreempt) {
- sp := unsafe.Pointer(r.sp())
- delta := uintptr(sys.StackAlign)
- sp = add(sp, -delta)
- r.set_sp(uintptr(sp))
- if usesLR {
- *((*uintptr)(sp)) = r.lr()
- r.set_lr(r.ip())
- } else {
- *((*uintptr)(sp)) = r.ip()
- }
- }
- r.set_ip(abi.FuncPCABI0(sigpanic0))
- return _EXCEPTION_CONTINUE_EXECUTION
-}
-
-// It seems Windows searches ContinueHandler's list even
-// if ExceptionHandler returns EXCEPTION_CONTINUE_EXECUTION.
-// firstcontinuehandler will stop that search,
-// if exceptionhandler did the same earlier.
-//
-// It is nosplit for the same reason as exceptionhandler.
-//
-//go:nosplit
-func firstcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
- if !isgoexception(info, r) {
- return _EXCEPTION_CONTINUE_SEARCH
- }
- return _EXCEPTION_CONTINUE_EXECUTION
-}
-
-var testingWER bool
-
-// lastcontinuehandler is reached, because runtime cannot handle
-// current exception. lastcontinuehandler will print crash info and exit.
-//
-// It is nosplit for the same reason as exceptionhandler.
-//
-//go:nosplit
-func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
- if islibrary || isarchive {
- // Go DLL/archive has been loaded in a non-go program.
- // If the exception does not originate from go, the go runtime
- // should not take responsibility of crashing the process.
- return _EXCEPTION_CONTINUE_SEARCH
- }
- if testingWER {
- return _EXCEPTION_CONTINUE_SEARCH
- }
-
- // VEH is called before SEH, but arm64 MSVC DLLs use SEH to trap
- // illegal instructions during runtime initialization to determine
- // CPU features, so if we make it to the last handler and we're
- // arm64 and it's an illegal instruction and this is coming from
- // non-Go code, then assume it's this runtime probing happen, and
- // pass that onward to SEH.
- if GOARCH == "arm64" && info.exceptioncode == _EXCEPTION_ILLEGAL_INSTRUCTION &&
- (r.ip() < firstmoduledata.text || firstmoduledata.etext < r.ip()) {
- return _EXCEPTION_CONTINUE_SEARCH
- }
-
- winthrow(info, r, gp)
- return 0 // not reached
-}
-
-// Always called on g0. gp is the G where the exception occurred.
-//
-//go:nosplit
-func winthrow(info *exceptionrecord, r *context, gp *g) {
- g0 := getg()
-
- if panicking.Load() != 0 { // traceback already printed
- exit(2)
- }
- panicking.Store(1)
-
- // In case we're handling a g0 stack overflow, blow away the
- // g0 stack bounds so we have room to print the traceback. If
- // this somehow overflows the stack, the OS will trap it.
- g0.stack.lo = 0
- g0.stackguard0 = g0.stack.lo + _StackGuard
- g0.stackguard1 = g0.stackguard0
-
- print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.ip()), "\n")
-
- print("PC=", hex(r.ip()), "\n")
- if g0.m.incgo && gp == g0.m.g0 && g0.m.curg != nil {
- if iscgo {
- print("signal arrived during external code execution\n")
- }
- gp = g0.m.curg
- }
- print("\n")
-
- g0.m.throwing = throwTypeRuntime
- g0.m.caughtsig.set(gp)
-
- level, _, docrash := gotraceback()
- if level > 0 {
- tracebacktrap(r.ip(), r.sp(), r.lr(), gp)
- tracebackothers(gp)
- dumpregs(r)
- }
-
- if docrash {
- crash()
- }
-
- exit(2)
-}
-
-func sigpanic() {
- gp := getg()
- if !canpanic() {
- throw("unexpected signal during runtime execution")
- }
-
- switch gp.sig {
- case _EXCEPTION_ACCESS_VIOLATION:
- if gp.sigcode1 < 0x1000 {
- panicmem()
- }
- if gp.paniconfault {
- panicmemAddr(gp.sigcode1)
- }
- if inUserArenaChunk(gp.sigcode1) {
- // We could check that the arena chunk is explicitly set to fault,
- // but the fact that we faulted on accessing it is enough to prove
- // that it is.
- print("accessed data from freed user arena ", hex(gp.sigcode1), "\n")
- } else {
- print("unexpected fault address ", hex(gp.sigcode1), "\n")
- }
- throw("fault")
- case _EXCEPTION_INT_DIVIDE_BY_ZERO:
- panicdivide()
- case _EXCEPTION_INT_OVERFLOW:
- panicoverflow()
- case _EXCEPTION_FLT_DENORMAL_OPERAND,
- _EXCEPTION_FLT_DIVIDE_BY_ZERO,
- _EXCEPTION_FLT_INEXACT_RESULT,
- _EXCEPTION_FLT_OVERFLOW,
- _EXCEPTION_FLT_UNDERFLOW:
- panicfloat()
- }
- throw("fault")
-}
-
-var (
- badsignalmsg [100]byte
- badsignallen int32
-)
-
-func setBadSignalMsg() {
- const msg = "runtime: signal received on thread not created by Go.\n"
- for i, c := range msg {
- badsignalmsg[i] = byte(c)
- badsignallen++
- }
-}
-
-// Following are not implemented.
-
-func initsig(preinit bool) {
-}
-
-func sigenable(sig uint32) {
-}
-
-func sigdisable(sig uint32) {
-}
-
-func sigignore(sig uint32) {
-}
-
-func badsignal2()
-
-func raisebadsignal(sig uint32) {
- badsignal2()
-}
-
-func signame(sig uint32) string {
- return ""
-}
-
-//go:nosplit
-func crash() {
- // TODO: This routine should do whatever is needed
- // to make the Windows program abort/crash as it
- // would if Go was not intercepting signals.
- // On Unix the routine would remove the custom signal
- // handler and then raise a signal (like SIGABRT).
- // Something like that should happen here.
- // It's okay to leave this empty for now: if crash returns
- // the ordinary exit-after-panic happens.
-}
-
-// gsignalStack is unused on Windows.
-type gsignalStack struct{}
diff --git a/contrib/go/_std_1.20/src/runtime/sizeclasses.go b/contrib/go/_std_1.20/src/runtime/sizeclasses.go
deleted file mode 100644
index 067871eaf3..0000000000
--- a/contrib/go/_std_1.20/src/runtime/sizeclasses.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Code generated by mksizeclasses.go; DO NOT EDIT.
-//go:generate go run mksizeclasses.go
-
-package runtime
-
-// class bytes/obj bytes/span objects tail waste max waste min align
-// 1 8 8192 1024 0 87.50% 8
-// 2 16 8192 512 0 43.75% 16
-// 3 24 8192 341 8 29.24% 8
-// 4 32 8192 256 0 21.88% 32
-// 5 48 8192 170 32 31.52% 16
-// 6 64 8192 128 0 23.44% 64
-// 7 80 8192 102 32 19.07% 16
-// 8 96 8192 85 32 15.95% 32
-// 9 112 8192 73 16 13.56% 16
-// 10 128 8192 64 0 11.72% 128
-// 11 144 8192 56 128 11.82% 16
-// 12 160 8192 51 32 9.73% 32
-// 13 176 8192 46 96 9.59% 16
-// 14 192 8192 42 128 9.25% 64
-// 15 208 8192 39 80 8.12% 16
-// 16 224 8192 36 128 8.15% 32
-// 17 240 8192 34 32 6.62% 16
-// 18 256 8192 32 0 5.86% 256
-// 19 288 8192 28 128 12.16% 32
-// 20 320 8192 25 192 11.80% 64
-// 21 352 8192 23 96 9.88% 32
-// 22 384 8192 21 128 9.51% 128
-// 23 416 8192 19 288 10.71% 32
-// 24 448 8192 18 128 8.37% 64
-// 25 480 8192 17 32 6.82% 32
-// 26 512 8192 16 0 6.05% 512
-// 27 576 8192 14 128 12.33% 64
-// 28 640 8192 12 512 15.48% 128
-// 29 704 8192 11 448 13.93% 64
-// 30 768 8192 10 512 13.94% 256
-// 31 896 8192 9 128 15.52% 128
-// 32 1024 8192 8 0 12.40% 1024
-// 33 1152 8192 7 128 12.41% 128
-// 34 1280 8192 6 512 15.55% 256
-// 35 1408 16384 11 896 14.00% 128
-// 36 1536 8192 5 512 14.00% 512
-// 37 1792 16384 9 256 15.57% 256
-// 38 2048 8192 4 0 12.45% 2048
-// 39 2304 16384 7 256 12.46% 256
-// 40 2688 8192 3 128 15.59% 128
-// 41 3072 24576 8 0 12.47% 1024
-// 42 3200 16384 5 384 6.22% 128
-// 43 3456 24576 7 384 8.83% 128
-// 44 4096 8192 2 0 15.60% 4096
-// 45 4864 24576 5 256 16.65% 256
-// 46 5376 16384 3 256 10.92% 256
-// 47 6144 24576 4 0 12.48% 2048
-// 48 6528 32768 5 128 6.23% 128
-// 49 6784 40960 6 256 4.36% 128
-// 50 6912 49152 7 768 3.37% 256
-// 51 8192 8192 1 0 15.61% 8192
-// 52 9472 57344 6 512 14.28% 256
-// 53 9728 49152 5 512 3.64% 512
-// 54 10240 40960 4 0 4.99% 2048
-// 55 10880 32768 3 128 6.24% 128
-// 56 12288 24576 2 0 11.45% 4096
-// 57 13568 40960 3 256 9.99% 256
-// 58 14336 57344 4 0 5.35% 2048
-// 59 16384 16384 1 0 12.49% 8192
-// 60 18432 73728 4 0 11.11% 2048
-// 61 19072 57344 3 128 3.57% 128
-// 62 20480 40960 2 0 6.87% 4096
-// 63 21760 65536 3 256 6.25% 256
-// 64 24576 24576 1 0 11.45% 8192
-// 65 27264 81920 3 128 10.00% 128
-// 66 28672 57344 2 0 4.91% 4096
-// 67 32768 32768 1 0 12.50% 8192
-
-// alignment bits min obj size
-// 8 3 8
-// 16 4 32
-// 32 5 256
-// 64 6 512
-// 128 7 768
-// 4096 12 28672
-// 8192 13 32768
-
-const (
- _MaxSmallSize = 32768
- smallSizeDiv = 8
- smallSizeMax = 1024
- largeSizeDiv = 128
- _NumSizeClasses = 68
- _PageShift = 13
-)
-
-var class_to_size = [_NumSizeClasses]uint16{0, 8, 16, 24, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896, 1024, 1152, 1280, 1408, 1536, 1792, 2048, 2304, 2688, 3072, 3200, 3456, 4096, 4864, 5376, 6144, 6528, 6784, 6912, 8192, 9472, 9728, 10240, 10880, 12288, 13568, 14336, 16384, 18432, 19072, 20480, 21760, 24576, 27264, 28672, 32768}
-var class_to_allocnpages = [_NumSizeClasses]uint8{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 2, 3, 1, 3, 2, 3, 4, 5, 6, 1, 7, 6, 5, 4, 3, 5, 7, 2, 9, 7, 5, 8, 3, 10, 7, 4}
-var class_to_divmagic = [_NumSizeClasses]uint32{0, ^uint32(0)/8 + 1, ^uint32(0)/16 + 1, ^uint32(0)/24 + 1, ^uint32(0)/32 + 1, ^uint32(0)/48 + 1, ^uint32(0)/64 + 1, ^uint32(0)/80 + 1, ^uint32(0)/96 + 1, ^uint32(0)/112 + 1, ^uint32(0)/128 + 1, ^uint32(0)/144 + 1, ^uint32(0)/160 + 1, ^uint32(0)/176 + 1, ^uint32(0)/192 + 1, ^uint32(0)/208 + 1, ^uint32(0)/224 + 1, ^uint32(0)/240 + 1, ^uint32(0)/256 + 1, ^uint32(0)/288 + 1, ^uint32(0)/320 + 1, ^uint32(0)/352 + 1, ^uint32(0)/384 + 1, ^uint32(0)/416 + 1, ^uint32(0)/448 + 1, ^uint32(0)/480 + 1, ^uint32(0)/512 + 1, ^uint32(0)/576 + 1, ^uint32(0)/640 + 1, ^uint32(0)/704 + 1, ^uint32(0)/768 + 1, ^uint32(0)/896 + 1, ^uint32(0)/1024 + 1, ^uint32(0)/1152 + 1, ^uint32(0)/1280 + 1, ^uint32(0)/1408 + 1, ^uint32(0)/1536 + 1, ^uint32(0)/1792 + 1, ^uint32(0)/2048 + 1, ^uint32(0)/2304 + 1, ^uint32(0)/2688 + 1, ^uint32(0)/3072 + 1, ^uint32(0)/3200 + 1, ^uint32(0)/3456 + 1, ^uint32(0)/4096 + 1, ^uint32(0)/4864 + 1, ^uint32(0)/5376 + 1, ^uint32(0)/6144 + 1, ^uint32(0)/6528 + 1, ^uint32(0)/6784 + 1, ^uint32(0)/6912 + 1, ^uint32(0)/8192 + 1, ^uint32(0)/9472 + 1, ^uint32(0)/9728 + 1, ^uint32(0)/10240 + 1, ^uint32(0)/10880 + 1, ^uint32(0)/12288 + 1, ^uint32(0)/13568 + 1, ^uint32(0)/14336 + 1, ^uint32(0)/16384 + 1, ^uint32(0)/18432 + 1, ^uint32(0)/19072 + 1, ^uint32(0)/20480 + 1, ^uint32(0)/21760 + 1, ^uint32(0)/24576 + 1, ^uint32(0)/27264 + 1, ^uint32(0)/28672 + 1, ^uint32(0)/32768 + 1}
-var size_to_class8 = [smallSizeMax/smallSizeDiv + 1]uint8{0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}
-var size_to_class128 = [(_MaxSmallSize-smallSizeMax)/largeSizeDiv + 1]uint8{32, 33, 34, 35, 36, 37, 37, 38, 38, 39, 39, 40, 40, 40, 41, 41, 41, 42, 43, 43, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 48, 48, 49, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67}
diff --git a/contrib/go/_std_1.20/src/runtime/slice.go b/contrib/go/_std_1.20/src/runtime/slice.go
deleted file mode 100644
index 459dc8891e..0000000000
--- a/contrib/go/_std_1.20/src/runtime/slice.go
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright 2009 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 runtime
-
-import (
- "internal/abi"
- "internal/goarch"
- "runtime/internal/math"
- "runtime/internal/sys"
- "unsafe"
-)
-
-type slice struct {
- array unsafe.Pointer
- len int
- cap int
-}
-
-// A notInHeapSlice is a slice backed by runtime/internal/sys.NotInHeap memory.
-type notInHeapSlice struct {
- array *notInHeap
- len int
- cap int
-}
-
-func panicmakeslicelen() {
- panic(errorString("makeslice: len out of range"))
-}
-
-func panicmakeslicecap() {
- panic(errorString("makeslice: cap out of range"))
-}
-
-// makeslicecopy allocates a slice of "tolen" elements of type "et",
-// then copies "fromlen" elements of type "et" into that new allocation from "from".
-func makeslicecopy(et *_type, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer {
- var tomem, copymem uintptr
- if uintptr(tolen) > uintptr(fromlen) {
- var overflow bool
- tomem, overflow = math.MulUintptr(et.size, uintptr(tolen))
- if overflow || tomem > maxAlloc || tolen < 0 {
- panicmakeslicelen()
- }
- copymem = et.size * uintptr(fromlen)
- } else {
- // fromlen is a known good length providing and equal or greater than tolen,
- // thereby making tolen a good slice length too as from and to slices have the
- // same element width.
- tomem = et.size * uintptr(tolen)
- copymem = tomem
- }
-
- var to unsafe.Pointer
- if et.ptrdata == 0 {
- to = mallocgc(tomem, nil, false)
- if copymem < tomem {
- memclrNoHeapPointers(add(to, copymem), tomem-copymem)
- }
- } else {
- // Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory.
- to = mallocgc(tomem, et, true)
- if copymem > 0 && writeBarrier.enabled {
- // Only shade the pointers in old.array since we know the destination slice to
- // only contains nil pointers because it has been cleared during alloc.
- bulkBarrierPreWriteSrcOnly(uintptr(to), uintptr(from), copymem)
- }
- }
-
- if raceenabled {
- callerpc := getcallerpc()
- pc := abi.FuncPCABIInternal(makeslicecopy)
- racereadrangepc(from, copymem, callerpc, pc)
- }
- if msanenabled {
- msanread(from, copymem)
- }
- if asanenabled {
- asanread(from, copymem)
- }
-
- memmove(to, from, copymem)
-
- return to
-}
-
-func makeslice(et *_type, len, cap int) unsafe.Pointer {
- mem, overflow := math.MulUintptr(et.size, uintptr(cap))
- if overflow || mem > maxAlloc || len < 0 || len > cap {
- // NOTE: Produce a 'len out of range' error instead of a
- // 'cap out of range' error when someone does make([]T, bignumber).
- // 'cap out of range' is true too, but since the cap is only being
- // supplied implicitly, saying len is clearer.
- // See golang.org/issue/4085.
- mem, overflow := math.MulUintptr(et.size, uintptr(len))
- if overflow || mem > maxAlloc || len < 0 {
- panicmakeslicelen()
- }
- panicmakeslicecap()
- }
-
- return mallocgc(mem, et, true)
-}
-
-func makeslice64(et *_type, len64, cap64 int64) unsafe.Pointer {
- len := int(len64)
- if int64(len) != len64 {
- panicmakeslicelen()
- }
-
- cap := int(cap64)
- if int64(cap) != cap64 {
- panicmakeslicecap()
- }
-
- return makeslice(et, len, cap)
-}
-
-// This is a wrapper over runtime/internal/math.MulUintptr,
-// so the compiler can recognize and treat it as an intrinsic.
-func mulUintptr(a, b uintptr) (uintptr, bool) {
- return math.MulUintptr(a, b)
-}
-
-// growslice allocates new backing store for a slice.
-//
-// arguments:
-//
-// oldPtr = pointer to the slice's backing array
-// newLen = new length (= oldLen + num)
-// oldCap = original slice's capacity.
-// num = number of elements being added
-// et = element type
-//
-// return values:
-//
-// newPtr = pointer to the new backing store
-// newLen = same value as the argument
-// newCap = capacity of the new backing store
-//
-// Requires that uint(newLen) > uint(oldCap).
-// Assumes the original slice length is newLen - num
-//
-// A new backing store is allocated with space for at least newLen elements.
-// Existing entries [0, oldLen) are copied over to the new backing store.
-// Added entries [oldLen, newLen) are not initialized by growslice
-// (although for pointer-containing element types, they are zeroed). They
-// must be initialized by the caller.
-// Trailing entries [newLen, newCap) are zeroed.
-//
-// growslice's odd calling convention makes the generated code that calls
-// this function simpler. In particular, it accepts and returns the
-// new length so that the old length is not live (does not need to be
-// spilled/restored) and the new length is returned (also does not need
-// to be spilled/restored).
-func growslice(oldPtr unsafe.Pointer, newLen, oldCap, num int, et *_type) slice {
- oldLen := newLen - num
- if raceenabled {
- callerpc := getcallerpc()
- racereadrangepc(oldPtr, uintptr(oldLen*int(et.size)), callerpc, abi.FuncPCABIInternal(growslice))
- }
- if msanenabled {
- msanread(oldPtr, uintptr(oldLen*int(et.size)))
- }
- if asanenabled {
- asanread(oldPtr, uintptr(oldLen*int(et.size)))
- }
-
- if newLen < 0 {
- panic(errorString("growslice: len out of range"))
- }
-
- if et.size == 0 {
- // append should not create a slice with nil pointer but non-zero len.
- // We assume that append doesn't need to preserve oldPtr in this case.
- return slice{unsafe.Pointer(&zerobase), newLen, newLen}
- }
-
- newcap := oldCap
- doublecap := newcap + newcap
- if newLen > doublecap {
- newcap = newLen
- } else {
- const threshold = 256
- if oldCap < threshold {
- newcap = doublecap
- } else {
- // Check 0 < newcap to detect overflow
- // and prevent an infinite loop.
- for 0 < newcap && newcap < newLen {
- // Transition from growing 2x for small slices
- // to growing 1.25x for large slices. This formula
- // gives a smooth-ish transition between the two.
- newcap += (newcap + 3*threshold) / 4
- }
- // Set newcap to the requested cap when
- // the newcap calculation overflowed.
- if newcap <= 0 {
- newcap = newLen
- }
- }
- }
-
- var overflow bool
- var lenmem, newlenmem, capmem uintptr
- // Specialize for common values of et.size.
- // For 1 we don't need any division/multiplication.
- // For goarch.PtrSize, compiler will optimize division/multiplication into a shift by a constant.
- // For powers of 2, use a variable shift.
- switch {
- case et.size == 1:
- lenmem = uintptr(oldLen)
- newlenmem = uintptr(newLen)
- capmem = roundupsize(uintptr(newcap))
- overflow = uintptr(newcap) > maxAlloc
- newcap = int(capmem)
- case et.size == goarch.PtrSize:
- lenmem = uintptr(oldLen) * goarch.PtrSize
- newlenmem = uintptr(newLen) * goarch.PtrSize
- capmem = roundupsize(uintptr(newcap) * goarch.PtrSize)
- overflow = uintptr(newcap) > maxAlloc/goarch.PtrSize
- newcap = int(capmem / goarch.PtrSize)
- case isPowerOfTwo(et.size):
- var shift uintptr
- if goarch.PtrSize == 8 {
- // Mask shift for better code generation.
- shift = uintptr(sys.TrailingZeros64(uint64(et.size))) & 63
- } else {
- shift = uintptr(sys.TrailingZeros32(uint32(et.size))) & 31
- }
- lenmem = uintptr(oldLen) << shift
- newlenmem = uintptr(newLen) << shift
- capmem = roundupsize(uintptr(newcap) << shift)
- overflow = uintptr(newcap) > (maxAlloc >> shift)
- newcap = int(capmem >> shift)
- capmem = uintptr(newcap) << shift
- default:
- lenmem = uintptr(oldLen) * et.size
- newlenmem = uintptr(newLen) * et.size
- capmem, overflow = math.MulUintptr(et.size, uintptr(newcap))
- capmem = roundupsize(capmem)
- newcap = int(capmem / et.size)
- capmem = uintptr(newcap) * et.size
- }
-
- // The check of overflow in addition to capmem > maxAlloc is needed
- // to prevent an overflow which can be used to trigger a segfault
- // on 32bit architectures with this example program:
- //
- // type T [1<<27 + 1]int64
- //
- // var d T
- // var s []T
- //
- // func main() {
- // s = append(s, d, d, d, d)
- // print(len(s), "\n")
- // }
- if overflow || capmem > maxAlloc {
- panic(errorString("growslice: len out of range"))
- }
-
- var p unsafe.Pointer
- if et.ptrdata == 0 {
- p = mallocgc(capmem, nil, false)
- // The append() that calls growslice is going to overwrite from oldLen to newLen.
- // Only clear the part that will not be overwritten.
- // The reflect_growslice() that calls growslice will manually clear
- // the region not cleared here.
- memclrNoHeapPointers(add(p, newlenmem), capmem-newlenmem)
- } else {
- // Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory.
- p = mallocgc(capmem, et, true)
- if lenmem > 0 && writeBarrier.enabled {
- // Only shade the pointers in oldPtr since we know the destination slice p
- // only contains nil pointers because it has been cleared during alloc.
- bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(oldPtr), lenmem-et.size+et.ptrdata)
- }
- }
- memmove(p, oldPtr, lenmem)
-
- return slice{p, newLen, newcap}
-}
-
-//go:linkname reflect_growslice reflect.growslice
-func reflect_growslice(et *_type, old slice, num int) slice {
- // Semantically equivalent to slices.Grow, except that the caller
- // is responsible for ensuring that old.len+num > old.cap.
- num -= old.cap - old.len // preserve memory of old[old.len:old.cap]
- new := growslice(old.array, old.cap+num, old.cap, num, et)
- // growslice does not zero out new[old.cap:new.len] since it assumes that
- // the memory will be overwritten by an append() that called growslice.
- // Since the caller of reflect_growslice is not append(),
- // zero out this region before returning the slice to the reflect package.
- if et.ptrdata == 0 {
- oldcapmem := uintptr(old.cap) * et.size
- newlenmem := uintptr(new.len) * et.size
- memclrNoHeapPointers(add(new.array, oldcapmem), newlenmem-oldcapmem)
- }
- new.len = old.len // preserve the old length
- return new
-}
-
-func isPowerOfTwo(x uintptr) bool {
- return x&(x-1) == 0
-}
-
-// slicecopy is used to copy from a string or slice of pointerless elements into a slice.
-func slicecopy(toPtr unsafe.Pointer, toLen int, fromPtr unsafe.Pointer, fromLen int, width uintptr) int {
- if fromLen == 0 || toLen == 0 {
- return 0
- }
-
- n := fromLen
- if toLen < n {
- n = toLen
- }
-
- if width == 0 {
- return n
- }
-
- size := uintptr(n) * width
- if raceenabled {
- callerpc := getcallerpc()
- pc := abi.FuncPCABIInternal(slicecopy)
- racereadrangepc(fromPtr, size, callerpc, pc)
- racewriterangepc(toPtr, size, callerpc, pc)
- }
- if msanenabled {
- msanread(fromPtr, size)
- msanwrite(toPtr, size)
- }
- if asanenabled {
- asanread(fromPtr, size)
- asanwrite(toPtr, size)
- }
-
- if size == 1 { // common case worth about 2x to do here
- // TODO: is this still worth it with new memmove impl?
- *(*byte)(toPtr) = *(*byte)(fromPtr) // known to be a byte pointer
- } else {
- memmove(toPtr, fromPtr, size)
- }
- return n
-}
diff --git a/contrib/go/_std_1.20/src/runtime/stack.go b/contrib/go/_std_1.20/src/runtime/stack.go
deleted file mode 100644
index d5e587a209..0000000000
--- a/contrib/go/_std_1.20/src/runtime/stack.go
+++ /dev/null
@@ -1,1345 +0,0 @@
-// Copyright 2013 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 runtime
-
-import (
- "internal/abi"
- "internal/cpu"
- "internal/goarch"
- "internal/goos"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-/*
-Stack layout parameters.
-Included both by runtime (compiled via 6c) and linkers (compiled via gcc).
-
-The per-goroutine g->stackguard is set to point StackGuard bytes
-above the bottom of the stack. Each function compares its stack
-pointer against g->stackguard to check for overflow. To cut one
-instruction from the check sequence for functions with tiny frames,
-the stack is allowed to protrude StackSmall bytes below the stack
-guard. Functions with large frames don't bother with the check and
-always call morestack. The sequences are (for amd64, others are
-similar):
-
- guard = g->stackguard
- frame = function's stack frame size
- argsize = size of function arguments (call + return)
-
- stack frame size <= StackSmall:
- CMPQ guard, SP
- JHI 3(PC)
- MOVQ m->morearg, $(argsize << 32)
- CALL morestack(SB)
-
- stack frame size > StackSmall but < StackBig
- LEAQ (frame-StackSmall)(SP), R0
- CMPQ guard, R0
- JHI 3(PC)
- MOVQ m->morearg, $(argsize << 32)
- CALL morestack(SB)
-
- stack frame size >= StackBig:
- MOVQ m->morearg, $((argsize << 32) | frame)
- CALL morestack(SB)
-
-The bottom StackGuard - StackSmall bytes are important: there has
-to be enough room to execute functions that refuse to check for
-stack overflow, either because they need to be adjacent to the
-actual caller's frame (deferproc) or because they handle the imminent
-stack overflow (morestack).
-
-For example, deferproc might call malloc, which does one of the
-above checks (without allocating a full frame), which might trigger
-a call to morestack. This sequence needs to fit in the bottom
-section of the stack. On amd64, morestack's frame is 40 bytes, and
-deferproc's frame is 56 bytes. That fits well within the
-StackGuard - StackSmall bytes at the bottom.
-The linkers explore all possible call traces involving non-splitting
-functions to make sure that this limit cannot be violated.
-*/
-
-const (
- // StackSystem is a number of additional bytes to add
- // to each stack below the usual guard area for OS-specific
- // purposes like signal handling. Used on Windows, Plan 9,
- // and iOS because they do not use a separate stack.
- _StackSystem = goos.IsWindows*512*goarch.PtrSize + goos.IsPlan9*512 + goos.IsIos*goarch.IsArm64*1024
-
- // The minimum size of stack used by Go code
- _StackMin = 2048
-
- // The minimum stack size to allocate.
- // The hackery here rounds FixedStack0 up to a power of 2.
- _FixedStack0 = _StackMin + _StackSystem
- _FixedStack1 = _FixedStack0 - 1
- _FixedStack2 = _FixedStack1 | (_FixedStack1 >> 1)
- _FixedStack3 = _FixedStack2 | (_FixedStack2 >> 2)
- _FixedStack4 = _FixedStack3 | (_FixedStack3 >> 4)
- _FixedStack5 = _FixedStack4 | (_FixedStack4 >> 8)
- _FixedStack6 = _FixedStack5 | (_FixedStack5 >> 16)
- _FixedStack = _FixedStack6 + 1
-
- // Functions that need frames bigger than this use an extra
- // instruction to do the stack split check, to avoid overflow
- // in case SP - framesize wraps below zero.
- // This value can be no bigger than the size of the unmapped
- // space at zero.
- _StackBig = 4096
-
- // The stack guard is a pointer this many bytes above the
- // bottom of the stack.
- //
- // The guard leaves enough room for one _StackSmall frame plus
- // a _StackLimit chain of NOSPLIT calls plus _StackSystem
- // bytes for the OS.
- // This arithmetic must match that in cmd/internal/objabi/stack.go:StackLimit.
- _StackGuard = 928*sys.StackGuardMultiplier + _StackSystem
-
- // After a stack split check the SP is allowed to be this
- // many bytes below the stack guard. This saves an instruction
- // in the checking sequence for tiny frames.
- _StackSmall = 128
-
- // The maximum number of bytes that a chain of NOSPLIT
- // functions can use.
- // This arithmetic must match that in cmd/internal/objabi/stack.go:StackLimit.
- _StackLimit = _StackGuard - _StackSystem - _StackSmall
-)
-
-const (
- // stackDebug == 0: no logging
- // == 1: logging of per-stack operations
- // == 2: logging of per-frame operations
- // == 3: logging of per-word updates
- // == 4: logging of per-word reads
- stackDebug = 0
- stackFromSystem = 0 // allocate stacks from system memory instead of the heap
- stackFaultOnFree = 0 // old stacks are mapped noaccess to detect use after free
- stackPoisonCopy = 0 // fill stack that should not be accessed with garbage, to detect bad dereferences during copy
- stackNoCache = 0 // disable per-P small stack caches
-
- // check the BP links during traceback.
- debugCheckBP = false
-)
-
-const (
- uintptrMask = 1<<(8*goarch.PtrSize) - 1
-
- // The values below can be stored to g.stackguard0 to force
- // the next stack check to fail.
- // These are all larger than any real SP.
-
- // Goroutine preemption request.
- // 0xfffffade in hex.
- stackPreempt = uintptrMask & -1314
-
- // Thread is forking. Causes a split stack check failure.
- // 0xfffffb2e in hex.
- stackFork = uintptrMask & -1234
-
- // Force a stack movement. Used for debugging.
- // 0xfffffeed in hex.
- stackForceMove = uintptrMask & -275
-
- // stackPoisonMin is the lowest allowed stack poison value.
- stackPoisonMin = uintptrMask & -4096
-)
-
-// Global pool of spans that have free stacks.
-// Stacks are assigned an order according to size.
-//
-// order = log_2(size/FixedStack)
-//
-// There is a free list for each order.
-var stackpool [_NumStackOrders]struct {
- item stackpoolItem
- _ [(cpu.CacheLinePadSize - unsafe.Sizeof(stackpoolItem{})%cpu.CacheLinePadSize) % cpu.CacheLinePadSize]byte
-}
-
-type stackpoolItem struct {
- _ sys.NotInHeap
- mu mutex
- span mSpanList
-}
-
-// Global pool of large stack spans.
-var stackLarge struct {
- lock mutex
- free [heapAddrBits - pageShift]mSpanList // free lists by log_2(s.npages)
-}
-
-func stackinit() {
- if _StackCacheSize&_PageMask != 0 {
- throw("cache size must be a multiple of page size")
- }
- for i := range stackpool {
- stackpool[i].item.span.init()
- lockInit(&stackpool[i].item.mu, lockRankStackpool)
- }
- for i := range stackLarge.free {
- stackLarge.free[i].init()
- lockInit(&stackLarge.lock, lockRankStackLarge)
- }
-}
-
-// stacklog2 returns ⌊log_2(n)⌋.
-func stacklog2(n uintptr) int {
- log2 := 0
- for n > 1 {
- n >>= 1
- log2++
- }
- return log2
-}
-
-// Allocates a stack from the free pool. Must be called with
-// stackpool[order].item.mu held.
-func stackpoolalloc(order uint8) gclinkptr {
- list := &stackpool[order].item.span
- s := list.first
- lockWithRankMayAcquire(&mheap_.lock, lockRankMheap)
- if s == nil {
- // no free stacks. Allocate another span worth.
- s = mheap_.allocManual(_StackCacheSize>>_PageShift, spanAllocStack)
- if s == nil {
- throw("out of memory")
- }
- if s.allocCount != 0 {
- throw("bad allocCount")
- }
- if s.manualFreeList.ptr() != nil {
- throw("bad manualFreeList")
- }
- osStackAlloc(s)
- s.elemsize = _FixedStack << order
- for i := uintptr(0); i < _StackCacheSize; i += s.elemsize {
- x := gclinkptr(s.base() + i)
- x.ptr().next = s.manualFreeList
- s.manualFreeList = x
- }
- list.insert(s)
- }
- x := s.manualFreeList
- if x.ptr() == nil {
- throw("span has no free stacks")
- }
- s.manualFreeList = x.ptr().next
- s.allocCount++
- if s.manualFreeList.ptr() == nil {
- // all stacks in s are allocated.
- list.remove(s)
- }
- return x
-}
-
-// Adds stack x to the free pool. Must be called with stackpool[order].item.mu held.
-func stackpoolfree(x gclinkptr, order uint8) {
- s := spanOfUnchecked(uintptr(x))
- if s.state.get() != mSpanManual {
- throw("freeing stack not in a stack span")
- }
- if s.manualFreeList.ptr() == nil {
- // s will now have a free stack
- stackpool[order].item.span.insert(s)
- }
- x.ptr().next = s.manualFreeList
- s.manualFreeList = x
- s.allocCount--
- if gcphase == _GCoff && s.allocCount == 0 {
- // Span is completely free. Return it to the heap
- // immediately if we're sweeping.
- //
- // If GC is active, we delay the free until the end of
- // GC to avoid the following type of situation:
- //
- // 1) GC starts, scans a SudoG but does not yet mark the SudoG.elem pointer
- // 2) The stack that pointer points to is copied
- // 3) The old stack is freed
- // 4) The containing span is marked free
- // 5) GC attempts to mark the SudoG.elem pointer. The
- // marking fails because the pointer looks like a
- // pointer into a free span.
- //
- // By not freeing, we prevent step #4 until GC is done.
- stackpool[order].item.span.remove(s)
- s.manualFreeList = 0
- osStackFree(s)
- mheap_.freeManual(s, spanAllocStack)
- }
-}
-
-// stackcacherefill/stackcacherelease implement a global pool of stack segments.
-// The pool is required to prevent unlimited growth of per-thread caches.
-//
-//go:systemstack
-func stackcacherefill(c *mcache, order uint8) {
- if stackDebug >= 1 {
- print("stackcacherefill order=", order, "\n")
- }
-
- // Grab some stacks from the global cache.
- // Grab half of the allowed capacity (to prevent thrashing).
- var list gclinkptr
- var size uintptr
- lock(&stackpool[order].item.mu)
- for size < _StackCacheSize/2 {
- x := stackpoolalloc(order)
- x.ptr().next = list
- list = x
- size += _FixedStack << order
- }
- unlock(&stackpool[order].item.mu)
- c.stackcache[order].list = list
- c.stackcache[order].size = size
-}
-
-//go:systemstack
-func stackcacherelease(c *mcache, order uint8) {
- if stackDebug >= 1 {
- print("stackcacherelease order=", order, "\n")
- }
- x := c.stackcache[order].list
- size := c.stackcache[order].size
- lock(&stackpool[order].item.mu)
- for size > _StackCacheSize/2 {
- y := x.ptr().next
- stackpoolfree(x, order)
- x = y
- size -= _FixedStack << order
- }
- unlock(&stackpool[order].item.mu)
- c.stackcache[order].list = x
- c.stackcache[order].size = size
-}
-
-//go:systemstack
-func stackcache_clear(c *mcache) {
- if stackDebug >= 1 {
- print("stackcache clear\n")
- }
- for order := uint8(0); order < _NumStackOrders; order++ {
- lock(&stackpool[order].item.mu)
- x := c.stackcache[order].list
- for x.ptr() != nil {
- y := x.ptr().next
- stackpoolfree(x, order)
- x = y
- }
- c.stackcache[order].list = 0
- c.stackcache[order].size = 0
- unlock(&stackpool[order].item.mu)
- }
-}
-
-// stackalloc allocates an n byte stack.
-//
-// stackalloc must run on the system stack because it uses per-P
-// resources and must not split the stack.
-//
-//go:systemstack
-func stackalloc(n uint32) stack {
- // Stackalloc must be called on scheduler stack, so that we
- // never try to grow the stack during the code that stackalloc runs.
- // Doing so would cause a deadlock (issue 1547).
- thisg := getg()
- if thisg != thisg.m.g0 {
- throw("stackalloc not on scheduler stack")
- }
- if n&(n-1) != 0 {
- throw("stack size not a power of 2")
- }
- if stackDebug >= 1 {
- print("stackalloc ", n, "\n")
- }
-
- if debug.efence != 0 || stackFromSystem != 0 {
- n = uint32(alignUp(uintptr(n), physPageSize))
- v := sysAlloc(uintptr(n), &memstats.stacks_sys)
- if v == nil {
- throw("out of memory (stackalloc)")
- }
- return stack{uintptr(v), uintptr(v) + uintptr(n)}
- }
-
- // Small stacks are allocated with a fixed-size free-list allocator.
- // If we need a stack of a bigger size, we fall back on allocating
- // a dedicated span.
- var v unsafe.Pointer
- if n < _FixedStack<<_NumStackOrders && n < _StackCacheSize {
- order := uint8(0)
- n2 := n
- for n2 > _FixedStack {
- order++
- n2 >>= 1
- }
- var x gclinkptr
- if stackNoCache != 0 || thisg.m.p == 0 || thisg.m.preemptoff != "" {
- // thisg.m.p == 0 can happen in the guts of exitsyscall
- // or procresize. Just get a stack from the global pool.
- // Also don't touch stackcache during gc
- // as it's flushed concurrently.
- lock(&stackpool[order].item.mu)
- x = stackpoolalloc(order)
- unlock(&stackpool[order].item.mu)
- } else {
- c := thisg.m.p.ptr().mcache
- x = c.stackcache[order].list
- if x.ptr() == nil {
- stackcacherefill(c, order)
- x = c.stackcache[order].list
- }
- c.stackcache[order].list = x.ptr().next
- c.stackcache[order].size -= uintptr(n)
- }
- v = unsafe.Pointer(x)
- } else {
- var s *mspan
- npage := uintptr(n) >> _PageShift
- log2npage := stacklog2(npage)
-
- // Try to get a stack from the large stack cache.
- lock(&stackLarge.lock)
- if !stackLarge.free[log2npage].isEmpty() {
- s = stackLarge.free[log2npage].first
- stackLarge.free[log2npage].remove(s)
- }
- unlock(&stackLarge.lock)
-
- lockWithRankMayAcquire(&mheap_.lock, lockRankMheap)
-
- if s == nil {
- // Allocate a new stack from the heap.
- s = mheap_.allocManual(npage, spanAllocStack)
- if s == nil {
- throw("out of memory")
- }
- osStackAlloc(s)
- s.elemsize = uintptr(n)
- }
- v = unsafe.Pointer(s.base())
- }
-
- if raceenabled {
- racemalloc(v, uintptr(n))
- }
- if msanenabled {
- msanmalloc(v, uintptr(n))
- }
- if asanenabled {
- asanunpoison(v, uintptr(n))
- }
- if stackDebug >= 1 {
- print(" allocated ", v, "\n")
- }
- return stack{uintptr(v), uintptr(v) + uintptr(n)}
-}
-
-// stackfree frees an n byte stack allocation at stk.
-//
-// stackfree must run on the system stack because it uses per-P
-// resources and must not split the stack.
-//
-//go:systemstack
-func stackfree(stk stack) {
- gp := getg()
- v := unsafe.Pointer(stk.lo)
- n := stk.hi - stk.lo
- if n&(n-1) != 0 {
- throw("stack not a power of 2")
- }
- if stk.lo+n < stk.hi {
- throw("bad stack size")
- }
- if stackDebug >= 1 {
- println("stackfree", v, n)
- memclrNoHeapPointers(v, n) // for testing, clobber stack data
- }
- if debug.efence != 0 || stackFromSystem != 0 {
- if debug.efence != 0 || stackFaultOnFree != 0 {
- sysFault(v, n)
- } else {
- sysFree(v, n, &memstats.stacks_sys)
- }
- return
- }
- if msanenabled {
- msanfree(v, n)
- }
- if asanenabled {
- asanpoison(v, n)
- }
- if n < _FixedStack<<_NumStackOrders && n < _StackCacheSize {
- order := uint8(0)
- n2 := n
- for n2 > _FixedStack {
- order++
- n2 >>= 1
- }
- x := gclinkptr(v)
- if stackNoCache != 0 || gp.m.p == 0 || gp.m.preemptoff != "" {
- lock(&stackpool[order].item.mu)
- stackpoolfree(x, order)
- unlock(&stackpool[order].item.mu)
- } else {
- c := gp.m.p.ptr().mcache
- if c.stackcache[order].size >= _StackCacheSize {
- stackcacherelease(c, order)
- }
- x.ptr().next = c.stackcache[order].list
- c.stackcache[order].list = x
- c.stackcache[order].size += n
- }
- } else {
- s := spanOfUnchecked(uintptr(v))
- if s.state.get() != mSpanManual {
- println(hex(s.base()), v)
- throw("bad span state")
- }
- if gcphase == _GCoff {
- // Free the stack immediately if we're
- // sweeping.
- osStackFree(s)
- mheap_.freeManual(s, spanAllocStack)
- } else {
- // If the GC is running, we can't return a
- // stack span to the heap because it could be
- // reused as a heap span, and this state
- // change would race with GC. Add it to the
- // large stack cache instead.
- log2npage := stacklog2(s.npages)
- lock(&stackLarge.lock)
- stackLarge.free[log2npage].insert(s)
- unlock(&stackLarge.lock)
- }
- }
-}
-
-var maxstacksize uintptr = 1 << 20 // enough until runtime.main sets it for real
-
-var maxstackceiling = maxstacksize
-
-var ptrnames = []string{
- 0: "scalar",
- 1: "ptr",
-}
-
-// Stack frame layout
-//
-// (x86)
-// +------------------+
-// | args from caller |
-// +------------------+ <- frame->argp
-// | return address |
-// +------------------+
-// | caller's BP (*) | (*) if framepointer_enabled && varp < sp
-// +------------------+ <- frame->varp
-// | locals |
-// +------------------+
-// | args to callee |
-// +------------------+ <- frame->sp
-//
-// (arm)
-// +------------------+
-// | args from caller |
-// +------------------+ <- frame->argp
-// | caller's retaddr |
-// +------------------+ <- frame->varp
-// | locals |
-// +------------------+
-// | args to callee |
-// +------------------+
-// | return address |
-// +------------------+ <- frame->sp
-
-type adjustinfo struct {
- old stack
- delta uintptr // ptr distance from old to new stack (newbase - oldbase)
- cache pcvalueCache
-
- // sghi is the highest sudog.elem on the stack.
- sghi uintptr
-}
-
-// adjustpointer checks whether *vpp is in the old stack described by adjinfo.
-// If so, it rewrites *vpp to point into the new stack.
-func adjustpointer(adjinfo *adjustinfo, vpp unsafe.Pointer) {
- pp := (*uintptr)(vpp)
- p := *pp
- if stackDebug >= 4 {
- print(" ", pp, ":", hex(p), "\n")
- }
- if adjinfo.old.lo <= p && p < adjinfo.old.hi {
- *pp = p + adjinfo.delta
- if stackDebug >= 3 {
- print(" adjust ptr ", pp, ":", hex(p), " -> ", hex(*pp), "\n")
- }
- }
-}
-
-// Information from the compiler about the layout of stack frames.
-// Note: this type must agree with reflect.bitVector.
-type bitvector struct {
- n int32 // # of bits
- bytedata *uint8
-}
-
-// ptrbit returns the i'th bit in bv.
-// ptrbit is less efficient than iterating directly over bitvector bits,
-// and should only be used in non-performance-critical code.
-// See adjustpointers for an example of a high-efficiency walk of a bitvector.
-func (bv *bitvector) ptrbit(i uintptr) uint8 {
- b := *(addb(bv.bytedata, i/8))
- return (b >> (i % 8)) & 1
-}
-
-// bv describes the memory starting at address scanp.
-// Adjust any pointers contained therein.
-func adjustpointers(scanp unsafe.Pointer, bv *bitvector, adjinfo *adjustinfo, f funcInfo) {
- minp := adjinfo.old.lo
- maxp := adjinfo.old.hi
- delta := adjinfo.delta
- num := uintptr(bv.n)
- // If this frame might contain channel receive slots, use CAS
- // to adjust pointers. If the slot hasn't been received into
- // yet, it may contain stack pointers and a concurrent send
- // could race with adjusting those pointers. (The sent value
- // itself can never contain stack pointers.)
- useCAS := uintptr(scanp) < adjinfo.sghi
- for i := uintptr(0); i < num; i += 8 {
- if stackDebug >= 4 {
- for j := uintptr(0); j < 8; j++ {
- print(" ", add(scanp, (i+j)*goarch.PtrSize), ":", ptrnames[bv.ptrbit(i+j)], ":", hex(*(*uintptr)(add(scanp, (i+j)*goarch.PtrSize))), " # ", i, " ", *addb(bv.bytedata, i/8), "\n")
- }
- }
- b := *(addb(bv.bytedata, i/8))
- for b != 0 {
- j := uintptr(sys.TrailingZeros8(b))
- b &= b - 1
- pp := (*uintptr)(add(scanp, (i+j)*goarch.PtrSize))
- retry:
- p := *pp
- if f.valid() && 0 < p && p < minLegalPointer && debug.invalidptr != 0 {
- // Looks like a junk value in a pointer slot.
- // Live analysis wrong?
- getg().m.traceback = 2
- print("runtime: bad pointer in frame ", funcname(f), " at ", pp, ": ", hex(p), "\n")
- throw("invalid pointer found on stack")
- }
- if minp <= p && p < maxp {
- if stackDebug >= 3 {
- print("adjust ptr ", hex(p), " ", funcname(f), "\n")
- }
- if useCAS {
- ppu := (*unsafe.Pointer)(unsafe.Pointer(pp))
- if !atomic.Casp1(ppu, unsafe.Pointer(p), unsafe.Pointer(p+delta)) {
- goto retry
- }
- } else {
- *pp = p + delta
- }
- }
- }
- }
-}
-
-// Note: the argument/return area is adjusted by the callee.
-func adjustframe(frame *stkframe, arg unsafe.Pointer) bool {
- adjinfo := (*adjustinfo)(arg)
- if frame.continpc == 0 {
- // Frame is dead.
- return true
- }
- f := frame.fn
- if stackDebug >= 2 {
- print(" adjusting ", funcname(f), " frame=[", hex(frame.sp), ",", hex(frame.fp), "] pc=", hex(frame.pc), " continpc=", hex(frame.continpc), "\n")
- }
- if f.funcID == funcID_systemstack_switch {
- // A special routine at the bottom of stack of a goroutine that does a systemstack call.
- // We will allow it to be copied even though we don't
- // have full GC info for it (because it is written in asm).
- return true
- }
-
- locals, args, objs := frame.getStackMap(&adjinfo.cache, true)
-
- // Adjust local variables if stack frame has been allocated.
- if locals.n > 0 {
- size := uintptr(locals.n) * goarch.PtrSize
- adjustpointers(unsafe.Pointer(frame.varp-size), &locals, adjinfo, f)
- }
-
- // Adjust saved base pointer if there is one.
- // TODO what about arm64 frame pointer adjustment?
- if goarch.ArchFamily == goarch.AMD64 && frame.argp-frame.varp == 2*goarch.PtrSize {
- if stackDebug >= 3 {
- print(" saved bp\n")
- }
- if debugCheckBP {
- // Frame pointers should always point to the next higher frame on
- // the Go stack (or be nil, for the top frame on the stack).
- bp := *(*uintptr)(unsafe.Pointer(frame.varp))
- if bp != 0 && (bp < adjinfo.old.lo || bp >= adjinfo.old.hi) {
- println("runtime: found invalid frame pointer")
- print("bp=", hex(bp), " min=", hex(adjinfo.old.lo), " max=", hex(adjinfo.old.hi), "\n")
- throw("bad frame pointer")
- }
- }
- adjustpointer(adjinfo, unsafe.Pointer(frame.varp))
- }
-
- // Adjust arguments.
- if args.n > 0 {
- if stackDebug >= 3 {
- print(" args\n")
- }
- adjustpointers(unsafe.Pointer(frame.argp), &args, adjinfo, funcInfo{})
- }
-
- // Adjust pointers in all stack objects (whether they are live or not).
- // See comments in mgcmark.go:scanframeworker.
- if frame.varp != 0 {
- for i := range objs {
- obj := &objs[i]
- off := obj.off
- base := frame.varp // locals base pointer
- if off >= 0 {
- base = frame.argp // arguments and return values base pointer
- }
- p := base + uintptr(off)
- if p < frame.sp {
- // Object hasn't been allocated in the frame yet.
- // (Happens when the stack bounds check fails and
- // we call into morestack.)
- continue
- }
- ptrdata := obj.ptrdata()
- gcdata := obj.gcdata()
- var s *mspan
- if obj.useGCProg() {
- // See comments in mgcmark.go:scanstack
- s = materializeGCProg(ptrdata, gcdata)
- gcdata = (*byte)(unsafe.Pointer(s.startAddr))
- }
- for i := uintptr(0); i < ptrdata; i += goarch.PtrSize {
- if *addb(gcdata, i/(8*goarch.PtrSize))>>(i/goarch.PtrSize&7)&1 != 0 {
- adjustpointer(adjinfo, unsafe.Pointer(p+i))
- }
- }
- if s != nil {
- dematerializeGCProg(s)
- }
- }
- }
-
- return true
-}
-
-func adjustctxt(gp *g, adjinfo *adjustinfo) {
- adjustpointer(adjinfo, unsafe.Pointer(&gp.sched.ctxt))
- if !framepointer_enabled {
- return
- }
- if debugCheckBP {
- bp := gp.sched.bp
- if bp != 0 && (bp < adjinfo.old.lo || bp >= adjinfo.old.hi) {
- println("runtime: found invalid top frame pointer")
- print("bp=", hex(bp), " min=", hex(adjinfo.old.lo), " max=", hex(adjinfo.old.hi), "\n")
- throw("bad top frame pointer")
- }
- }
- adjustpointer(adjinfo, unsafe.Pointer(&gp.sched.bp))
-}
-
-func adjustdefers(gp *g, adjinfo *adjustinfo) {
- // Adjust pointers in the Defer structs.
- // We need to do this first because we need to adjust the
- // defer.link fields so we always work on the new stack.
- adjustpointer(adjinfo, unsafe.Pointer(&gp._defer))
- for d := gp._defer; d != nil; d = d.link {
- adjustpointer(adjinfo, unsafe.Pointer(&d.fn))
- adjustpointer(adjinfo, unsafe.Pointer(&d.sp))
- adjustpointer(adjinfo, unsafe.Pointer(&d._panic))
- adjustpointer(adjinfo, unsafe.Pointer(&d.link))
- adjustpointer(adjinfo, unsafe.Pointer(&d.varp))
- adjustpointer(adjinfo, unsafe.Pointer(&d.fd))
- }
-}
-
-func adjustpanics(gp *g, adjinfo *adjustinfo) {
- // Panics are on stack and already adjusted.
- // Update pointer to head of list in G.
- adjustpointer(adjinfo, unsafe.Pointer(&gp._panic))
-}
-
-func adjustsudogs(gp *g, adjinfo *adjustinfo) {
- // the data elements pointed to by a SudoG structure
- // might be in the stack.
- for s := gp.waiting; s != nil; s = s.waitlink {
- adjustpointer(adjinfo, unsafe.Pointer(&s.elem))
- }
-}
-
-func fillstack(stk stack, b byte) {
- for p := stk.lo; p < stk.hi; p++ {
- *(*byte)(unsafe.Pointer(p)) = b
- }
-}
-
-func findsghi(gp *g, stk stack) uintptr {
- var sghi uintptr
- for sg := gp.waiting; sg != nil; sg = sg.waitlink {
- p := uintptr(sg.elem) + uintptr(sg.c.elemsize)
- if stk.lo <= p && p < stk.hi && p > sghi {
- sghi = p
- }
- }
- return sghi
-}
-
-// syncadjustsudogs adjusts gp's sudogs and copies the part of gp's
-// stack they refer to while synchronizing with concurrent channel
-// operations. It returns the number of bytes of stack copied.
-func syncadjustsudogs(gp *g, used uintptr, adjinfo *adjustinfo) uintptr {
- if gp.waiting == nil {
- return 0
- }
-
- // Lock channels to prevent concurrent send/receive.
- var lastc *hchan
- for sg := gp.waiting; sg != nil; sg = sg.waitlink {
- if sg.c != lastc {
- // There is a ranking cycle here between gscan bit and
- // hchan locks. Normally, we only allow acquiring hchan
- // locks and then getting a gscan bit. In this case, we
- // already have the gscan bit. We allow acquiring hchan
- // locks here as a special case, since a deadlock can't
- // happen because the G involved must already be
- // suspended. So, we get a special hchan lock rank here
- // that is lower than gscan, but doesn't allow acquiring
- // any other locks other than hchan.
- lockWithRank(&sg.c.lock, lockRankHchanLeaf)
- }
- lastc = sg.c
- }
-
- // Adjust sudogs.
- adjustsudogs(gp, adjinfo)
-
- // Copy the part of the stack the sudogs point in to
- // while holding the lock to prevent races on
- // send/receive slots.
- var sgsize uintptr
- if adjinfo.sghi != 0 {
- oldBot := adjinfo.old.hi - used
- newBot := oldBot + adjinfo.delta
- sgsize = adjinfo.sghi - oldBot
- memmove(unsafe.Pointer(newBot), unsafe.Pointer(oldBot), sgsize)
- }
-
- // Unlock channels.
- lastc = nil
- for sg := gp.waiting; sg != nil; sg = sg.waitlink {
- if sg.c != lastc {
- unlock(&sg.c.lock)
- }
- lastc = sg.c
- }
-
- return sgsize
-}
-
-// Copies gp's stack to a new stack of a different size.
-// Caller must have changed gp status to Gcopystack.
-func copystack(gp *g, newsize uintptr) {
- if gp.syscallsp != 0 {
- throw("stack growth not allowed in system call")
- }
- old := gp.stack
- if old.lo == 0 {
- throw("nil stackbase")
- }
- used := old.hi - gp.sched.sp
- // Add just the difference to gcController.addScannableStack.
- // g0 stacks never move, so this will never account for them.
- // It's also fine if we have no P, addScannableStack can deal with
- // that case.
- gcController.addScannableStack(getg().m.p.ptr(), int64(newsize)-int64(old.hi-old.lo))
-
- // allocate new stack
- new := stackalloc(uint32(newsize))
- if stackPoisonCopy != 0 {
- fillstack(new, 0xfd)
- }
- if stackDebug >= 1 {
- print("copystack gp=", gp, " [", hex(old.lo), " ", hex(old.hi-used), " ", hex(old.hi), "]", " -> [", hex(new.lo), " ", hex(new.hi-used), " ", hex(new.hi), "]/", newsize, "\n")
- }
-
- // Compute adjustment.
- var adjinfo adjustinfo
- adjinfo.old = old
- adjinfo.delta = new.hi - old.hi
-
- // Adjust sudogs, synchronizing with channel ops if necessary.
- ncopy := used
- if !gp.activeStackChans {
- if newsize < old.hi-old.lo && gp.parkingOnChan.Load() {
- // It's not safe for someone to shrink this stack while we're actively
- // parking on a channel, but it is safe to grow since we do that
- // ourselves and explicitly don't want to synchronize with channels
- // since we could self-deadlock.
- throw("racy sudog adjustment due to parking on channel")
- }
- adjustsudogs(gp, &adjinfo)
- } else {
- // sudogs may be pointing in to the stack and gp has
- // released channel locks, so other goroutines could
- // be writing to gp's stack. Find the highest such
- // pointer so we can handle everything there and below
- // carefully. (This shouldn't be far from the bottom
- // of the stack, so there's little cost in handling
- // everything below it carefully.)
- adjinfo.sghi = findsghi(gp, old)
-
- // Synchronize with channel ops and copy the part of
- // the stack they may interact with.
- ncopy -= syncadjustsudogs(gp, used, &adjinfo)
- }
-
- // Copy the stack (or the rest of it) to the new location
- memmove(unsafe.Pointer(new.hi-ncopy), unsafe.Pointer(old.hi-ncopy), ncopy)
-
- // Adjust remaining structures that have pointers into stacks.
- // We have to do most of these before we traceback the new
- // stack because gentraceback uses them.
- adjustctxt(gp, &adjinfo)
- adjustdefers(gp, &adjinfo)
- adjustpanics(gp, &adjinfo)
- if adjinfo.sghi != 0 {
- adjinfo.sghi += adjinfo.delta
- }
-
- // Swap out old stack for new one
- gp.stack = new
- gp.stackguard0 = new.lo + _StackGuard // NOTE: might clobber a preempt request
- gp.sched.sp = new.hi - used
- gp.stktopsp += adjinfo.delta
-
- // Adjust pointers in the new stack.
- gentraceback(^uintptr(0), ^uintptr(0), 0, gp, 0, nil, 0x7fffffff, adjustframe, noescape(unsafe.Pointer(&adjinfo)), 0)
-
- // free old stack
- if stackPoisonCopy != 0 {
- fillstack(old, 0xfc)
- }
- stackfree(old)
-}
-
-// round x up to a power of 2.
-func round2(x int32) int32 {
- s := uint(0)
- for 1<<s < x {
- s++
- }
- return 1 << s
-}
-
-// Called from runtime·morestack when more stack is needed.
-// Allocate larger stack and relocate to new stack.
-// Stack growth is multiplicative, for constant amortized cost.
-//
-// g->atomicstatus will be Grunning or Gscanrunning upon entry.
-// If the scheduler is trying to stop this g, then it will set preemptStop.
-//
-// This must be nowritebarrierrec because it can be called as part of
-// stack growth from other nowritebarrierrec functions, but the
-// compiler doesn't check this.
-//
-//go:nowritebarrierrec
-func newstack() {
- thisg := getg()
- // TODO: double check all gp. shouldn't be getg().
- if thisg.m.morebuf.g.ptr().stackguard0 == stackFork {
- throw("stack growth after fork")
- }
- if thisg.m.morebuf.g.ptr() != thisg.m.curg {
- print("runtime: newstack called from g=", hex(thisg.m.morebuf.g), "\n"+"\tm=", thisg.m, " m->curg=", thisg.m.curg, " m->g0=", thisg.m.g0, " m->gsignal=", thisg.m.gsignal, "\n")
- morebuf := thisg.m.morebuf
- traceback(morebuf.pc, morebuf.sp, morebuf.lr, morebuf.g.ptr())
- throw("runtime: wrong goroutine in newstack")
- }
-
- gp := thisg.m.curg
-
- if thisg.m.curg.throwsplit {
- // Update syscallsp, syscallpc in case traceback uses them.
- morebuf := thisg.m.morebuf
- gp.syscallsp = morebuf.sp
- gp.syscallpc = morebuf.pc
- pcname, pcoff := "(unknown)", uintptr(0)
- f := findfunc(gp.sched.pc)
- if f.valid() {
- pcname = funcname(f)
- pcoff = gp.sched.pc - f.entry()
- }
- print("runtime: newstack at ", pcname, "+", hex(pcoff),
- " sp=", hex(gp.sched.sp), " stack=[", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n",
- "\tmorebuf={pc:", hex(morebuf.pc), " sp:", hex(morebuf.sp), " lr:", hex(morebuf.lr), "}\n",
- "\tsched={pc:", hex(gp.sched.pc), " sp:", hex(gp.sched.sp), " lr:", hex(gp.sched.lr), " ctxt:", gp.sched.ctxt, "}\n")
-
- thisg.m.traceback = 2 // Include runtime frames
- traceback(morebuf.pc, morebuf.sp, morebuf.lr, gp)
- throw("runtime: stack split at bad time")
- }
-
- morebuf := thisg.m.morebuf
- thisg.m.morebuf.pc = 0
- thisg.m.morebuf.lr = 0
- thisg.m.morebuf.sp = 0
- thisg.m.morebuf.g = 0
-
- // NOTE: stackguard0 may change underfoot, if another thread
- // is about to try to preempt gp. Read it just once and use that same
- // value now and below.
- stackguard0 := atomic.Loaduintptr(&gp.stackguard0)
-
- // Be conservative about where we preempt.
- // We are interested in preempting user Go code, not runtime code.
- // If we're holding locks, mallocing, or preemption is disabled, don't
- // preempt.
- // This check is very early in newstack so that even the status change
- // from Grunning to Gwaiting and back doesn't happen in this case.
- // That status change by itself can be viewed as a small preemption,
- // because the GC might change Gwaiting to Gscanwaiting, and then
- // this goroutine has to wait for the GC to finish before continuing.
- // If the GC is in some way dependent on this goroutine (for example,
- // it needs a lock held by the goroutine), that small preemption turns
- // into a real deadlock.
- preempt := stackguard0 == stackPreempt
- if preempt {
- if !canPreemptM(thisg.m) {
- // Let the goroutine keep running for now.
- // gp->preempt is set, so it will be preempted next time.
- gp.stackguard0 = gp.stack.lo + _StackGuard
- gogo(&gp.sched) // never return
- }
- }
-
- if gp.stack.lo == 0 {
- throw("missing stack in newstack")
- }
- sp := gp.sched.sp
- if goarch.ArchFamily == goarch.AMD64 || goarch.ArchFamily == goarch.I386 || goarch.ArchFamily == goarch.WASM {
- // The call to morestack cost a word.
- sp -= goarch.PtrSize
- }
- if stackDebug >= 1 || sp < gp.stack.lo {
- print("runtime: newstack sp=", hex(sp), " stack=[", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n",
- "\tmorebuf={pc:", hex(morebuf.pc), " sp:", hex(morebuf.sp), " lr:", hex(morebuf.lr), "}\n",
- "\tsched={pc:", hex(gp.sched.pc), " sp:", hex(gp.sched.sp), " lr:", hex(gp.sched.lr), " ctxt:", gp.sched.ctxt, "}\n")
- }
- if sp < gp.stack.lo {
- print("runtime: gp=", gp, ", goid=", gp.goid, ", gp->status=", hex(readgstatus(gp)), "\n ")
- print("runtime: split stack overflow: ", hex(sp), " < ", hex(gp.stack.lo), "\n")
- throw("runtime: split stack overflow")
- }
-
- if preempt {
- if gp == thisg.m.g0 {
- throw("runtime: preempt g0")
- }
- if thisg.m.p == 0 && thisg.m.locks == 0 {
- throw("runtime: g is running but p is not")
- }
-
- if gp.preemptShrink {
- // We're at a synchronous safe point now, so
- // do the pending stack shrink.
- gp.preemptShrink = false
- shrinkstack(gp)
- }
-
- if gp.preemptStop {
- preemptPark(gp) // never returns
- }
-
- // Act like goroutine called runtime.Gosched.
- gopreempt_m(gp) // never return
- }
-
- // Allocate a bigger segment and move the stack.
- oldsize := gp.stack.hi - gp.stack.lo
- newsize := oldsize * 2
-
- // Make sure we grow at least as much as needed to fit the new frame.
- // (This is just an optimization - the caller of morestack will
- // recheck the bounds on return.)
- if f := findfunc(gp.sched.pc); f.valid() {
- max := uintptr(funcMaxSPDelta(f))
- needed := max + _StackGuard
- used := gp.stack.hi - gp.sched.sp
- for newsize-used < needed {
- newsize *= 2
- }
- }
-
- if stackguard0 == stackForceMove {
- // Forced stack movement used for debugging.
- // Don't double the stack (or we may quickly run out
- // if this is done repeatedly).
- newsize = oldsize
- }
-
- if newsize > maxstacksize || newsize > maxstackceiling {
- if maxstacksize < maxstackceiling {
- print("runtime: goroutine stack exceeds ", maxstacksize, "-byte limit\n")
- } else {
- print("runtime: goroutine stack exceeds ", maxstackceiling, "-byte limit\n")
- }
- print("runtime: sp=", hex(sp), " stack=[", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
- throw("stack overflow")
- }
-
- // The goroutine must be executing in order to call newstack,
- // so it must be Grunning (or Gscanrunning).
- casgstatus(gp, _Grunning, _Gcopystack)
-
- // The concurrent GC will not scan the stack while we are doing the copy since
- // the gp is in a Gcopystack status.
- copystack(gp, newsize)
- if stackDebug >= 1 {
- print("stack grow done\n")
- }
- casgstatus(gp, _Gcopystack, _Grunning)
- gogo(&gp.sched)
-}
-
-//go:nosplit
-func nilfunc() {
- *(*uint8)(nil) = 0
-}
-
-// adjust Gobuf as if it executed a call to fn
-// and then stopped before the first instruction in fn.
-func gostartcallfn(gobuf *gobuf, fv *funcval) {
- var fn unsafe.Pointer
- if fv != nil {
- fn = unsafe.Pointer(fv.fn)
- } else {
- fn = unsafe.Pointer(abi.FuncPCABIInternal(nilfunc))
- }
- gostartcall(gobuf, fn, unsafe.Pointer(fv))
-}
-
-// isShrinkStackSafe returns whether it's safe to attempt to shrink
-// gp's stack. Shrinking the stack is only safe when we have precise
-// pointer maps for all frames on the stack.
-func isShrinkStackSafe(gp *g) bool {
- // We can't copy the stack if we're in a syscall.
- // The syscall might have pointers into the stack and
- // often we don't have precise pointer maps for the innermost
- // frames.
- //
- // We also can't copy the stack if we're at an asynchronous
- // safe-point because we don't have precise pointer maps for
- // all frames.
- //
- // We also can't *shrink* the stack in the window between the
- // goroutine calling gopark to park on a channel and
- // gp.activeStackChans being set.
- return gp.syscallsp == 0 && !gp.asyncSafePoint && !gp.parkingOnChan.Load()
-}
-
-// Maybe shrink the stack being used by gp.
-//
-// gp must be stopped and we must own its stack. It may be in
-// _Grunning, but only if this is our own user G.
-func shrinkstack(gp *g) {
- if gp.stack.lo == 0 {
- throw("missing stack in shrinkstack")
- }
- if s := readgstatus(gp); s&_Gscan == 0 {
- // We don't own the stack via _Gscan. We could still
- // own it if this is our own user G and we're on the
- // system stack.
- if !(gp == getg().m.curg && getg() != getg().m.curg && s == _Grunning) {
- // We don't own the stack.
- throw("bad status in shrinkstack")
- }
- }
- if !isShrinkStackSafe(gp) {
- throw("shrinkstack at bad time")
- }
- // Check for self-shrinks while in a libcall. These may have
- // pointers into the stack disguised as uintptrs, but these
- // code paths should all be nosplit.
- if gp == getg().m.curg && gp.m.libcallsp != 0 {
- throw("shrinking stack in libcall")
- }
-
- if debug.gcshrinkstackoff > 0 {
- return
- }
- f := findfunc(gp.startpc)
- if f.valid() && f.funcID == funcID_gcBgMarkWorker {
- // We're not allowed to shrink the gcBgMarkWorker
- // stack (see gcBgMarkWorker for explanation).
- return
- }
-
- oldsize := gp.stack.hi - gp.stack.lo
- newsize := oldsize / 2
- // Don't shrink the allocation below the minimum-sized stack
- // allocation.
- if newsize < _FixedStack {
- return
- }
- // Compute how much of the stack is currently in use and only
- // shrink the stack if gp is using less than a quarter of its
- // current stack. The currently used stack includes everything
- // down to the SP plus the stack guard space that ensures
- // there's room for nosplit functions.
- avail := gp.stack.hi - gp.stack.lo
- if used := gp.stack.hi - gp.sched.sp + _StackLimit; used >= avail/4 {
- return
- }
-
- if stackDebug > 0 {
- print("shrinking stack ", oldsize, "->", newsize, "\n")
- }
-
- copystack(gp, newsize)
-}
-
-// freeStackSpans frees unused stack spans at the end of GC.
-func freeStackSpans() {
- // Scan stack pools for empty stack spans.
- for order := range stackpool {
- lock(&stackpool[order].item.mu)
- list := &stackpool[order].item.span
- for s := list.first; s != nil; {
- next := s.next
- if s.allocCount == 0 {
- list.remove(s)
- s.manualFreeList = 0
- osStackFree(s)
- mheap_.freeManual(s, spanAllocStack)
- }
- s = next
- }
- unlock(&stackpool[order].item.mu)
- }
-
- // Free large stack spans.
- lock(&stackLarge.lock)
- for i := range stackLarge.free {
- for s := stackLarge.free[i].first; s != nil; {
- next := s.next
- stackLarge.free[i].remove(s)
- osStackFree(s)
- mheap_.freeManual(s, spanAllocStack)
- s = next
- }
- }
- unlock(&stackLarge.lock)
-}
-
-// A stackObjectRecord is generated by the compiler for each stack object in a stack frame.
-// This record must match the generator code in cmd/compile/internal/liveness/plive.go:emitStackObjects.
-type stackObjectRecord struct {
- // offset in frame
- // if negative, offset from varp
- // if non-negative, offset from argp
- off int32
- size int32
- _ptrdata int32 // ptrdata, or -ptrdata is GC prog is used
- gcdataoff uint32 // offset to gcdata from moduledata.rodata
-}
-
-func (r *stackObjectRecord) useGCProg() bool {
- return r._ptrdata < 0
-}
-
-func (r *stackObjectRecord) ptrdata() uintptr {
- x := r._ptrdata
- if x < 0 {
- return uintptr(-x)
- }
- return uintptr(x)
-}
-
-// gcdata returns pointer map or GC prog of the type.
-func (r *stackObjectRecord) gcdata() *byte {
- ptr := uintptr(unsafe.Pointer(r))
- var mod *moduledata
- for datap := &firstmoduledata; datap != nil; datap = datap.next {
- if datap.gofunc <= ptr && ptr < datap.end {
- mod = datap
- break
- }
- }
- // If you get a panic here due to a nil mod,
- // you may have made a copy of a stackObjectRecord.
- // You must use the original pointer.
- res := mod.rodata + uintptr(r.gcdataoff)
- return (*byte)(unsafe.Pointer(res))
-}
-
-// This is exported as ABI0 via linkname so obj can call it.
-//
-//go:nosplit
-//go:linkname morestackc
-func morestackc() {
- throw("attempt to execute system stack code on user stack")
-}
-
-// startingStackSize is the amount of stack that new goroutines start with.
-// It is a power of 2, and between _FixedStack and maxstacksize, inclusive.
-// startingStackSize is updated every GC by tracking the average size of
-// stacks scanned during the GC.
-var startingStackSize uint32 = _FixedStack
-
-func gcComputeStartingStackSize() {
- if debug.adaptivestackstart == 0 {
- return
- }
- // For details, see the design doc at
- // https://docs.google.com/document/d/1YDlGIdVTPnmUiTAavlZxBI1d9pwGQgZT7IKFKlIXohQ/edit?usp=sharing
- // The basic algorithm is to track the average size of stacks
- // and start goroutines with stack equal to that average size.
- // Starting at the average size uses at most 2x the space that
- // an ideal algorithm would have used.
- // This is just a heuristic to avoid excessive stack growth work
- // early in a goroutine's lifetime. See issue 18138. Stacks that
- // are allocated too small can still grow, and stacks allocated
- // too large can still shrink.
- var scannedStackSize uint64
- var scannedStacks uint64
- for _, p := range allp {
- scannedStackSize += p.scannedStackSize
- scannedStacks += p.scannedStacks
- // Reset for next time
- p.scannedStackSize = 0
- p.scannedStacks = 0
- }
- if scannedStacks == 0 {
- startingStackSize = _FixedStack
- return
- }
- avg := scannedStackSize/scannedStacks + _StackGuard
- // Note: we add _StackGuard to ensure that a goroutine that
- // uses the average space will not trigger a growth.
- if avg > uint64(maxstacksize) {
- avg = uint64(maxstacksize)
- }
- if avg < _FixedStack {
- avg = _FixedStack
- }
- // Note: maxstacksize fits in 30 bits, so avg also does.
- startingStackSize = uint32(round2(int32(avg)))
-}
diff --git a/contrib/go/_std_1.20/src/runtime/stkframe.go b/contrib/go/_std_1.20/src/runtime/stkframe.go
deleted file mode 100644
index 3ecf3a828c..0000000000
--- a/contrib/go/_std_1.20/src/runtime/stkframe.go
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2022 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 runtime
-
-import (
- "internal/abi"
- "internal/goarch"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// A stkframe holds information about a single physical stack frame.
-type stkframe struct {
- // fn is the function being run in this frame. If there is
- // inlining, this is the outermost function.
- fn funcInfo
-
- // pc is the program counter within fn.
- //
- // The meaning of this is subtle:
- //
- // - Typically, this frame performed a regular function call
- // and this is the return PC (just after the CALL
- // instruction). In this case, pc-1 reflects the CALL
- // instruction itself and is the correct source of symbolic
- // information.
- //
- // - If this frame "called" sigpanic, then pc is the
- // instruction that panicked, and pc is the correct address
- // to use for symbolic information.
- //
- // - If this is the innermost frame, then PC is where
- // execution will continue, but it may not be the
- // instruction following a CALL. This may be from
- // cooperative preemption, in which case this is the
- // instruction after the call to morestack. Or this may be
- // from a signal or an un-started goroutine, in which case
- // PC could be any instruction, including the first
- // instruction in a function. Conventionally, we use pc-1
- // for symbolic information, unless pc == fn.entry(), in
- // which case we use pc.
- pc uintptr
-
- // continpc is the PC where execution will continue in fn, or
- // 0 if execution will not continue in this frame.
- //
- // This is usually the same as pc, unless this frame "called"
- // sigpanic, in which case it's either the address of
- // deferreturn or 0 if this frame will never execute again.
- //
- // This is the PC to use to look up GC liveness for this frame.
- continpc uintptr
-
- lr uintptr // program counter at caller aka link register
- sp uintptr // stack pointer at pc
- fp uintptr // stack pointer at caller aka frame pointer
- varp uintptr // top of local variables
- argp uintptr // pointer to function arguments
-}
-
-// reflectMethodValue is a partial duplicate of reflect.makeFuncImpl
-// and reflect.methodValue.
-type reflectMethodValue struct {
- fn uintptr
- stack *bitvector // ptrmap for both args and results
- argLen uintptr // just args
-}
-
-// argBytes returns the argument frame size for a call to frame.fn.
-func (frame *stkframe) argBytes() uintptr {
- if frame.fn.args != _ArgsSizeUnknown {
- return uintptr(frame.fn.args)
- }
- // This is an uncommon and complicated case. Fall back to fully
- // fetching the argument map to compute its size.
- argMap, _ := frame.argMapInternal()
- return uintptr(argMap.n) * goarch.PtrSize
-}
-
-// argMapInternal is used internally by stkframe to fetch special
-// argument maps.
-//
-// argMap.n is always populated with the size of the argument map.
-//
-// argMap.bytedata is only populated for dynamic argument maps (used
-// by reflect). If the caller requires the argument map, it should use
-// this if non-nil, and otherwise fetch the argument map using the
-// current PC.
-//
-// hasReflectStackObj indicates that this frame also has a reflect
-// function stack object, which the caller must synthesize.
-func (frame *stkframe) argMapInternal() (argMap bitvector, hasReflectStackObj bool) {
- f := frame.fn
- if f.args != _ArgsSizeUnknown {
- argMap.n = f.args / goarch.PtrSize
- return
- }
- // Extract argument bitmaps for reflect stubs from the calls they made to reflect.
- switch funcname(f) {
- case "reflect.makeFuncStub", "reflect.methodValueCall":
- // These take a *reflect.methodValue as their
- // context register and immediately save it to 0(SP).
- // Get the methodValue from 0(SP).
- arg0 := frame.sp + sys.MinFrameSize
-
- minSP := frame.fp
- if !usesLR {
- // The CALL itself pushes a word.
- // Undo that adjustment.
- minSP -= goarch.PtrSize
- }
- if arg0 >= minSP {
- // The function hasn't started yet.
- // This only happens if f was the
- // start function of a new goroutine
- // that hasn't run yet *and* f takes
- // no arguments and has no results
- // (otherwise it will get wrapped in a
- // closure). In this case, we can't
- // reach into its locals because it
- // doesn't have locals yet, but we
- // also know its argument map is
- // empty.
- if frame.pc != f.entry() {
- print("runtime: confused by ", funcname(f), ": no frame (sp=", hex(frame.sp), " fp=", hex(frame.fp), ") at entry+", hex(frame.pc-f.entry()), "\n")
- throw("reflect mismatch")
- }
- return bitvector{}, false // No locals, so also no stack objects
- }
- hasReflectStackObj = true
- mv := *(**reflectMethodValue)(unsafe.Pointer(arg0))
- // Figure out whether the return values are valid.
- // Reflect will update this value after it copies
- // in the return values.
- retValid := *(*bool)(unsafe.Pointer(arg0 + 4*goarch.PtrSize))
- if mv.fn != f.entry() {
- print("runtime: confused by ", funcname(f), "\n")
- throw("reflect mismatch")
- }
- argMap = *mv.stack
- if !retValid {
- // argMap.n includes the results, but
- // those aren't valid, so drop them.
- n := int32((uintptr(mv.argLen) &^ (goarch.PtrSize - 1)) / goarch.PtrSize)
- if n < argMap.n {
- argMap.n = n
- }
- }
- }
- return
-}
-
-// getStackMap returns the locals and arguments live pointer maps, and
-// stack object list for frame.
-func (frame *stkframe) getStackMap(cache *pcvalueCache, debug bool) (locals, args bitvector, objs []stackObjectRecord) {
- targetpc := frame.continpc
- if targetpc == 0 {
- // Frame is dead. Return empty bitvectors.
- return
- }
-
- f := frame.fn
- pcdata := int32(-1)
- if targetpc != f.entry() {
- // Back up to the CALL. If we're at the function entry
- // point, we want to use the entry map (-1), even if
- // the first instruction of the function changes the
- // stack map.
- targetpc--
- pcdata = pcdatavalue(f, _PCDATA_StackMapIndex, targetpc, cache)
- }
- if pcdata == -1 {
- // We do not have a valid pcdata value but there might be a
- // stackmap for this function. It is likely that we are looking
- // at the function prologue, assume so and hope for the best.
- pcdata = 0
- }
-
- // Local variables.
- size := frame.varp - frame.sp
- var minsize uintptr
- switch goarch.ArchFamily {
- case goarch.ARM64:
- minsize = sys.StackAlign
- default:
- minsize = sys.MinFrameSize
- }
- if size > minsize {
- stackid := pcdata
- stkmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
- if stkmap == nil || stkmap.n <= 0 {
- print("runtime: frame ", funcname(f), " untyped locals ", hex(frame.varp-size), "+", hex(size), "\n")
- throw("missing stackmap")
- }
- // If nbit == 0, there's no work to do.
- if stkmap.nbit > 0 {
- if stackid < 0 || stackid >= stkmap.n {
- // don't know where we are
- print("runtime: pcdata is ", stackid, " and ", stkmap.n, " locals stack map entries for ", funcname(f), " (targetpc=", hex(targetpc), ")\n")
- throw("bad symbol table")
- }
- locals = stackmapdata(stkmap, stackid)
- if stackDebug >= 3 && debug {
- print(" locals ", stackid, "/", stkmap.n, " ", locals.n, " words ", locals.bytedata, "\n")
- }
- } else if stackDebug >= 3 && debug {
- print(" no locals to adjust\n")
- }
- }
-
- // Arguments. First fetch frame size and special-case argument maps.
- var isReflect bool
- args, isReflect = frame.argMapInternal()
- if args.n > 0 && args.bytedata == nil {
- // Non-empty argument frame, but not a special map.
- // Fetch the argument map at pcdata.
- stackmap := (*stackmap)(funcdata(f, _FUNCDATA_ArgsPointerMaps))
- if stackmap == nil || stackmap.n <= 0 {
- print("runtime: frame ", funcname(f), " untyped args ", hex(frame.argp), "+", hex(args.n*goarch.PtrSize), "\n")
- throw("missing stackmap")
- }
- if pcdata < 0 || pcdata >= stackmap.n {
- // don't know where we are
- print("runtime: pcdata is ", pcdata, " and ", stackmap.n, " args stack map entries for ", funcname(f), " (targetpc=", hex(targetpc), ")\n")
- throw("bad symbol table")
- }
- if stackmap.nbit == 0 {
- args.n = 0
- } else {
- args = stackmapdata(stackmap, pcdata)
- }
- }
-
- // stack objects.
- if (GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64") &&
- unsafe.Sizeof(abi.RegArgs{}) > 0 && isReflect {
- // For reflect.makeFuncStub and reflect.methodValueCall,
- // we need to fake the stack object record.
- // These frames contain an internal/abi.RegArgs at a hard-coded offset.
- // This offset matches the assembly code on amd64 and arm64.
- objs = methodValueCallFrameObjs[:]
- } else {
- p := funcdata(f, _FUNCDATA_StackObjects)
- if p != nil {
- n := *(*uintptr)(p)
- p = add(p, goarch.PtrSize)
- r0 := (*stackObjectRecord)(noescape(p))
- objs = unsafe.Slice(r0, int(n))
- // Note: the noescape above is needed to keep
- // getStackMap from "leaking param content:
- // frame". That leak propagates up to getgcmask, then
- // GCMask, then verifyGCInfo, which converts the stack
- // gcinfo tests into heap gcinfo tests :(
- }
- }
-
- return
-}
-
-var methodValueCallFrameObjs [1]stackObjectRecord // initialized in stackobjectinit
-
-func stkobjinit() {
- var abiRegArgsEface any = abi.RegArgs{}
- abiRegArgsType := efaceOf(&abiRegArgsEface)._type
- if abiRegArgsType.kind&kindGCProg != 0 {
- throw("abiRegArgsType needs GC Prog, update methodValueCallFrameObjs")
- }
- // Set methodValueCallFrameObjs[0].gcdataoff so that
- // stackObjectRecord.gcdata() will work correctly with it.
- ptr := uintptr(unsafe.Pointer(&methodValueCallFrameObjs[0]))
- var mod *moduledata
- for datap := &firstmoduledata; datap != nil; datap = datap.next {
- if datap.gofunc <= ptr && ptr < datap.end {
- mod = datap
- break
- }
- }
- if mod == nil {
- throw("methodValueCallFrameObjs is not in a module")
- }
- methodValueCallFrameObjs[0] = stackObjectRecord{
- off: -int32(alignUp(abiRegArgsType.size, 8)), // It's always the highest address local.
- size: int32(abiRegArgsType.size),
- _ptrdata: int32(abiRegArgsType.ptrdata),
- gcdataoff: uint32(uintptr(unsafe.Pointer(abiRegArgsType.gcdata)) - mod.rodata),
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/string.go b/contrib/go/_std_1.20/src/runtime/string.go
deleted file mode 100644
index a00976be59..0000000000
--- a/contrib/go/_std_1.20/src/runtime/string.go
+++ /dev/null
@@ -1,584 +0,0 @@
-// Copyright 2014 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 runtime
-
-import (
- "internal/abi"
- "internal/bytealg"
- "internal/goarch"
- "unsafe"
-)
-
-// The constant is known to the compiler.
-// There is no fundamental theory behind this number.
-const tmpStringBufSize = 32
-
-type tmpBuf [tmpStringBufSize]byte
-
-// concatstrings implements a Go string concatenation x+y+z+...
-// The operands are passed in the slice a.
-// If buf != nil, the compiler has determined that the result does not
-// escape the calling function, so the string data can be stored in buf
-// if small enough.
-func concatstrings(buf *tmpBuf, a []string) string {
- idx := 0
- l := 0
- count := 0
- for i, x := range a {
- n := len(x)
- if n == 0 {
- continue
- }
- if l+n < l {
- throw("string concatenation too long")
- }
- l += n
- count++
- idx = i
- }
- if count == 0 {
- return ""
- }
-
- // If there is just one string and either it is not on the stack
- // or our result does not escape the calling frame (buf != nil),
- // then we can return that string directly.
- if count == 1 && (buf != nil || !stringDataOnStack(a[idx])) {
- return a[idx]
- }
- s, b := rawstringtmp(buf, l)
- for _, x := range a {
- copy(b, x)
- b = b[len(x):]
- }
- return s
-}
-
-func concatstring2(buf *tmpBuf, a0, a1 string) string {
- return concatstrings(buf, []string{a0, a1})
-}
-
-func concatstring3(buf *tmpBuf, a0, a1, a2 string) string {
- return concatstrings(buf, []string{a0, a1, a2})
-}
-
-func concatstring4(buf *tmpBuf, a0, a1, a2, a3 string) string {
- return concatstrings(buf, []string{a0, a1, a2, a3})
-}
-
-func concatstring5(buf *tmpBuf, a0, a1, a2, a3, a4 string) string {
- return concatstrings(buf, []string{a0, a1, a2, a3, a4})
-}
-
-// slicebytetostring converts a byte slice to a string.
-// It is inserted by the compiler into generated code.
-// ptr is a pointer to the first element of the slice;
-// n is the length of the slice.
-// Buf is a fixed-size buffer for the result,
-// it is not nil if the result does not escape.
-func slicebytetostring(buf *tmpBuf, ptr *byte, n int) string {
- if n == 0 {
- // Turns out to be a relatively common case.
- // Consider that you want to parse out data between parens in "foo()bar",
- // you find the indices and convert the subslice to string.
- return ""
- }
- if raceenabled {
- racereadrangepc(unsafe.Pointer(ptr),
- uintptr(n),
- getcallerpc(),
- abi.FuncPCABIInternal(slicebytetostring))
- }
- if msanenabled {
- msanread(unsafe.Pointer(ptr), uintptr(n))
- }
- if asanenabled {
- asanread(unsafe.Pointer(ptr), uintptr(n))
- }
- if n == 1 {
- p := unsafe.Pointer(&staticuint64s[*ptr])
- if goarch.BigEndian {
- p = add(p, 7)
- }
- return unsafe.String((*byte)(p), 1)
- }
-
- var p unsafe.Pointer
- if buf != nil && n <= len(buf) {
- p = unsafe.Pointer(buf)
- } else {
- p = mallocgc(uintptr(n), nil, false)
- }
- memmove(p, unsafe.Pointer(ptr), uintptr(n))
- return unsafe.String((*byte)(p), n)
-}
-
-// stringDataOnStack reports whether the string's data is
-// stored on the current goroutine's stack.
-func stringDataOnStack(s string) bool {
- ptr := uintptr(unsafe.Pointer(unsafe.StringData(s)))
- stk := getg().stack
- return stk.lo <= ptr && ptr < stk.hi
-}
-
-func rawstringtmp(buf *tmpBuf, l int) (s string, b []byte) {
- if buf != nil && l <= len(buf) {
- b = buf[:l]
- s = slicebytetostringtmp(&b[0], len(b))
- } else {
- s, b = rawstring(l)
- }
- return
-}
-
-// slicebytetostringtmp returns a "string" referring to the actual []byte bytes.
-//
-// Callers need to ensure that the returned string will not be used after
-// the calling goroutine modifies the original slice or synchronizes with
-// another goroutine.
-//
-// The function is only called when instrumenting
-// and otherwise intrinsified by the compiler.
-//
-// Some internal compiler optimizations use this function.
-// - Used for m[T1{... Tn{..., string(k), ...} ...}] and m[string(k)]
-// where k is []byte, T1 to Tn is a nesting of struct and array literals.
-// - Used for "<"+string(b)+">" concatenation where b is []byte.
-// - Used for string(b)=="foo" comparison where b is []byte.
-func slicebytetostringtmp(ptr *byte, n int) string {
- if raceenabled && n > 0 {
- racereadrangepc(unsafe.Pointer(ptr),
- uintptr(n),
- getcallerpc(),
- abi.FuncPCABIInternal(slicebytetostringtmp))
- }
- if msanenabled && n > 0 {
- msanread(unsafe.Pointer(ptr), uintptr(n))
- }
- if asanenabled && n > 0 {
- asanread(unsafe.Pointer(ptr), uintptr(n))
- }
- return unsafe.String(ptr, n)
-}
-
-func stringtoslicebyte(buf *tmpBuf, s string) []byte {
- var b []byte
- if buf != nil && len(s) <= len(buf) {
- *buf = tmpBuf{}
- b = buf[:len(s)]
- } else {
- b = rawbyteslice(len(s))
- }
- copy(b, s)
- return b
-}
-
-func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune {
- // two passes.
- // unlike slicerunetostring, no race because strings are immutable.
- n := 0
- for range s {
- n++
- }
-
- var a []rune
- if buf != nil && n <= len(buf) {
- *buf = [tmpStringBufSize]rune{}
- a = buf[:n]
- } else {
- a = rawruneslice(n)
- }
-
- n = 0
- for _, r := range s {
- a[n] = r
- n++
- }
- return a
-}
-
-func slicerunetostring(buf *tmpBuf, a []rune) string {
- if raceenabled && len(a) > 0 {
- racereadrangepc(unsafe.Pointer(&a[0]),
- uintptr(len(a))*unsafe.Sizeof(a[0]),
- getcallerpc(),
- abi.FuncPCABIInternal(slicerunetostring))
- }
- if msanenabled && len(a) > 0 {
- msanread(unsafe.Pointer(&a[0]), uintptr(len(a))*unsafe.Sizeof(a[0]))
- }
- if asanenabled && len(a) > 0 {
- asanread(unsafe.Pointer(&a[0]), uintptr(len(a))*unsafe.Sizeof(a[0]))
- }
- var dum [4]byte
- size1 := 0
- for _, r := range a {
- size1 += encoderune(dum[:], r)
- }
- s, b := rawstringtmp(buf, size1+3)
- size2 := 0
- for _, r := range a {
- // check for race
- if size2 >= size1 {
- break
- }
- size2 += encoderune(b[size2:], r)
- }
- return s[:size2]
-}
-
-type stringStruct struct {
- str unsafe.Pointer
- len int
-}
-
-// Variant with *byte pointer type for DWARF debugging.
-type stringStructDWARF struct {
- str *byte
- len int
-}
-
-func stringStructOf(sp *string) *stringStruct {
- return (*stringStruct)(unsafe.Pointer(sp))
-}
-
-func intstring(buf *[4]byte, v int64) (s string) {
- var b []byte
- if buf != nil {
- b = buf[:]
- s = slicebytetostringtmp(&b[0], len(b))
- } else {
- s, b = rawstring(4)
- }
- if int64(rune(v)) != v {
- v = runeError
- }
- n := encoderune(b, rune(v))
- return s[:n]
-}
-
-// rawstring allocates storage for a new string. The returned
-// string and byte slice both refer to the same storage.
-// The storage is not zeroed. Callers should use
-// b to set the string contents and then drop b.
-func rawstring(size int) (s string, b []byte) {
- p := mallocgc(uintptr(size), nil, false)
- return unsafe.String((*byte)(p), size), unsafe.Slice((*byte)(p), size)
-}
-
-// rawbyteslice allocates a new byte slice. The byte slice is not zeroed.
-func rawbyteslice(size int) (b []byte) {
- cap := roundupsize(uintptr(size))
- p := mallocgc(cap, nil, false)
- if cap != uintptr(size) {
- memclrNoHeapPointers(add(p, uintptr(size)), cap-uintptr(size))
- }
-
- *(*slice)(unsafe.Pointer(&b)) = slice{p, size, int(cap)}
- return
-}
-
-// rawruneslice allocates a new rune slice. The rune slice is not zeroed.
-func rawruneslice(size int) (b []rune) {
- if uintptr(size) > maxAlloc/4 {
- throw("out of memory")
- }
- mem := roundupsize(uintptr(size) * 4)
- p := mallocgc(mem, nil, false)
- if mem != uintptr(size)*4 {
- memclrNoHeapPointers(add(p, uintptr(size)*4), mem-uintptr(size)*4)
- }
-
- *(*slice)(unsafe.Pointer(&b)) = slice{p, size, int(mem / 4)}
- return
-}
-
-// used by cmd/cgo
-func gobytes(p *byte, n int) (b []byte) {
- if n == 0 {
- return make([]byte, 0)
- }
-
- if n < 0 || uintptr(n) > maxAlloc {
- panic(errorString("gobytes: length out of range"))
- }
-
- bp := mallocgc(uintptr(n), nil, false)
- memmove(bp, unsafe.Pointer(p), uintptr(n))
-
- *(*slice)(unsafe.Pointer(&b)) = slice{bp, n, n}
- return
-}
-
-// This is exported via linkname to assembly in syscall (for Plan9).
-//
-//go:linkname gostring
-func gostring(p *byte) string {
- l := findnull(p)
- if l == 0 {
- return ""
- }
- s, b := rawstring(l)
- memmove(unsafe.Pointer(&b[0]), unsafe.Pointer(p), uintptr(l))
- return s
-}
-
-// internal_syscall_gostring is a version of gostring for internal/syscall/unix.
-//
-//go:linkname internal_syscall_gostring internal/syscall/unix.gostring
-func internal_syscall_gostring(p *byte) string {
- return gostring(p)
-}
-
-func gostringn(p *byte, l int) string {
- if l == 0 {
- return ""
- }
- s, b := rawstring(l)
- memmove(unsafe.Pointer(&b[0]), unsafe.Pointer(p), uintptr(l))
- return s
-}
-
-func hasPrefix(s, prefix string) bool {
- return len(s) >= len(prefix) && s[:len(prefix)] == prefix
-}
-
-const (
- maxUint64 = ^uint64(0)
- maxInt64 = int64(maxUint64 >> 1)
-)
-
-// atoi64 parses an int64 from a string s.
-// The bool result reports whether s is a number
-// representable by a value of type int64.
-func atoi64(s string) (int64, bool) {
- if s == "" {
- return 0, false
- }
-
- neg := false
- if s[0] == '-' {
- neg = true
- s = s[1:]
- }
-
- un := uint64(0)
- for i := 0; i < len(s); i++ {
- c := s[i]
- if c < '0' || c > '9' {
- return 0, false
- }
- if un > maxUint64/10 {
- // overflow
- return 0, false
- }
- un *= 10
- un1 := un + uint64(c) - '0'
- if un1 < un {
- // overflow
- return 0, false
- }
- un = un1
- }
-
- if !neg && un > uint64(maxInt64) {
- return 0, false
- }
- if neg && un > uint64(maxInt64)+1 {
- return 0, false
- }
-
- n := int64(un)
- if neg {
- n = -n
- }
-
- return n, true
-}
-
-// atoi is like atoi64 but for integers
-// that fit into an int.
-func atoi(s string) (int, bool) {
- if n, ok := atoi64(s); n == int64(int(n)) {
- return int(n), ok
- }
- return 0, false
-}
-
-// atoi32 is like atoi but for integers
-// that fit into an int32.
-func atoi32(s string) (int32, bool) {
- if n, ok := atoi64(s); n == int64(int32(n)) {
- return int32(n), ok
- }
- return 0, false
-}
-
-// parseByteCount parses a string that represents a count of bytes.
-//
-// s must match the following regular expression:
-//
-// ^[0-9]+(([KMGT]i)?B)?$
-//
-// In other words, an integer byte count with an optional unit
-// suffix. Acceptable suffixes include one of
-// - KiB, MiB, GiB, TiB which represent binary IEC/ISO 80000 units, or
-// - B, which just represents bytes.
-//
-// Returns an int64 because that's what its callers want and receive,
-// but the result is always non-negative.
-func parseByteCount(s string) (int64, bool) {
- // The empty string is not valid.
- if s == "" {
- return 0, false
- }
- // Handle the easy non-suffix case.
- last := s[len(s)-1]
- if last >= '0' && last <= '9' {
- n, ok := atoi64(s)
- if !ok || n < 0 {
- return 0, false
- }
- return n, ok
- }
- // Failing a trailing digit, this must always end in 'B'.
- // Also at this point there must be at least one digit before
- // that B.
- if last != 'B' || len(s) < 2 {
- return 0, false
- }
- // The one before that must always be a digit or 'i'.
- if c := s[len(s)-2]; c >= '0' && c <= '9' {
- // Trivial 'B' suffix.
- n, ok := atoi64(s[:len(s)-1])
- if !ok || n < 0 {
- return 0, false
- }
- return n, ok
- } else if c != 'i' {
- return 0, false
- }
- // Finally, we need at least 4 characters now, for the unit
- // prefix and at least one digit.
- if len(s) < 4 {
- return 0, false
- }
- power := 0
- switch s[len(s)-3] {
- case 'K':
- power = 1
- case 'M':
- power = 2
- case 'G':
- power = 3
- case 'T':
- power = 4
- default:
- // Invalid suffix.
- return 0, false
- }
- m := uint64(1)
- for i := 0; i < power; i++ {
- m *= 1024
- }
- n, ok := atoi64(s[:len(s)-3])
- if !ok || n < 0 {
- return 0, false
- }
- un := uint64(n)
- if un > maxUint64/m {
- // Overflow.
- return 0, false
- }
- un *= m
- if un > uint64(maxInt64) {
- // Overflow.
- return 0, false
- }
- return int64(un), true
-}
-
-//go:nosplit
-func findnull(s *byte) int {
- if s == nil {
- return 0
- }
-
- // Avoid IndexByteString on Plan 9 because it uses SSE instructions
- // on x86 machines, and those are classified as floating point instructions,
- // which are illegal in a note handler.
- if GOOS == "plan9" {
- p := (*[maxAlloc/2 - 1]byte)(unsafe.Pointer(s))
- l := 0
- for p[l] != 0 {
- l++
- }
- return l
- }
-
- // pageSize is the unit we scan at a time looking for NULL.
- // It must be the minimum page size for any architecture Go
- // runs on. It's okay (just a minor performance loss) if the
- // actual system page size is larger than this value.
- const pageSize = 4096
-
- offset := 0
- ptr := unsafe.Pointer(s)
- // IndexByteString uses wide reads, so we need to be careful
- // with page boundaries. Call IndexByteString on
- // [ptr, endOfPage) interval.
- safeLen := int(pageSize - uintptr(ptr)%pageSize)
-
- for {
- t := *(*string)(unsafe.Pointer(&stringStruct{ptr, safeLen}))
- // Check one page at a time.
- if i := bytealg.IndexByteString(t, 0); i != -1 {
- return offset + i
- }
- // Move to next page
- ptr = unsafe.Pointer(uintptr(ptr) + uintptr(safeLen))
- offset += safeLen
- safeLen = pageSize
- }
-}
-
-func findnullw(s *uint16) int {
- if s == nil {
- return 0
- }
- p := (*[maxAlloc/2/2 - 1]uint16)(unsafe.Pointer(s))
- l := 0
- for p[l] != 0 {
- l++
- }
- return l
-}
-
-//go:nosplit
-func gostringnocopy(str *byte) string {
- ss := stringStruct{str: unsafe.Pointer(str), len: findnull(str)}
- s := *(*string)(unsafe.Pointer(&ss))
- return s
-}
-
-func gostringw(strw *uint16) string {
- var buf [8]byte
- str := (*[maxAlloc/2/2 - 1]uint16)(unsafe.Pointer(strw))
- n1 := 0
- for i := 0; str[i] != 0; i++ {
- n1 += encoderune(buf[:], rune(str[i]))
- }
- s, b := rawstring(n1 + 4)
- n2 := 0
- for i := 0; str[i] != 0; i++ {
- // check for race
- if n2 >= n1 {
- break
- }
- n2 += encoderune(b[n2:], rune(str[i]))
- }
- b[n2] = 0 // for luck
- return s[:n2]
-}
diff --git a/contrib/go/_std_1.20/src/runtime/stubs.go b/contrib/go/_std_1.20/src/runtime/stubs.go
deleted file mode 100644
index 42c2612e68..0000000000
--- a/contrib/go/_std_1.20/src/runtime/stubs.go
+++ /dev/null
@@ -1,480 +0,0 @@
-// Copyright 2014 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 runtime
-
-import (
- "internal/abi"
- "internal/goarch"
- "runtime/internal/math"
- "unsafe"
-)
-
-// Should be a built-in for unsafe.Pointer?
-//
-//go:nosplit
-func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
- return unsafe.Pointer(uintptr(p) + x)
-}
-
-// getg returns the pointer to the current g.
-// The compiler rewrites calls to this function into instructions
-// that fetch the g directly (from TLS or from the dedicated register).
-func getg() *g
-
-// mcall switches from the g to the g0 stack and invokes fn(g),
-// where g is the goroutine that made the call.
-// mcall saves g's current PC/SP in g->sched so that it can be restored later.
-// It is up to fn to arrange for that later execution, typically by recording
-// g in a data structure, causing something to call ready(g) later.
-// mcall returns to the original goroutine g later, when g has been rescheduled.
-// fn must not return at all; typically it ends by calling schedule, to let the m
-// run other goroutines.
-//
-// mcall can only be called from g stacks (not g0, not gsignal).
-//
-// This must NOT be go:noescape: if fn is a stack-allocated closure,
-// fn puts g on a run queue, and g executes before fn returns, the
-// closure will be invalidated while it is still executing.
-func mcall(fn func(*g))
-
-// systemstack runs fn on a system stack.
-// If systemstack is called from the per-OS-thread (g0) stack, or
-// if systemstack is called from the signal handling (gsignal) stack,
-// systemstack calls fn directly and returns.
-// Otherwise, systemstack is being called from the limited stack
-// of an ordinary goroutine. In this case, systemstack switches
-// to the per-OS-thread stack, calls fn, and switches back.
-// It is common to use a func literal as the argument, in order
-// to share inputs and outputs with the code around the call
-// to system stack:
-//
-// ... set up y ...
-// systemstack(func() {
-// x = bigcall(y)
-// })
-// ... use x ...
-//
-//go:noescape
-func systemstack(fn func())
-
-//go:nosplit
-//go:nowritebarrierrec
-func badsystemstack() {
- writeErrStr("fatal: systemstack called from unexpected goroutine")
-}
-
-// memclrNoHeapPointers clears n bytes starting at ptr.
-//
-// Usually you should use typedmemclr. memclrNoHeapPointers should be
-// used only when the caller knows that *ptr contains no heap pointers
-// because either:
-//
-// *ptr is initialized memory and its type is pointer-free, or
-//
-// *ptr is uninitialized memory (e.g., memory that's being reused
-// for a new allocation) and hence contains only "junk".
-//
-// memclrNoHeapPointers ensures that if ptr is pointer-aligned, and n
-// is a multiple of the pointer size, then any pointer-aligned,
-// pointer-sized portion is cleared atomically. Despite the function
-// name, this is necessary because this function is the underlying
-// implementation of typedmemclr and memclrHasPointers. See the doc of
-// memmove for more details.
-//
-// The (CPU-specific) implementations of this function are in memclr_*.s.
-//
-//go:noescape
-func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
-
-//go:linkname reflect_memclrNoHeapPointers reflect.memclrNoHeapPointers
-func reflect_memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr) {
- memclrNoHeapPointers(ptr, n)
-}
-
-// memmove copies n bytes from "from" to "to".
-//
-// memmove ensures that any pointer in "from" is written to "to" with
-// an indivisible write, so that racy reads cannot observe a
-// half-written pointer. This is necessary to prevent the garbage
-// collector from observing invalid pointers, and differs from memmove
-// in unmanaged languages. However, memmove is only required to do
-// this if "from" and "to" may contain pointers, which can only be the
-// case if "from", "to", and "n" are all be word-aligned.
-//
-// Implementations are in memmove_*.s.
-//
-//go:noescape
-func memmove(to, from unsafe.Pointer, n uintptr)
-
-// Outside assembly calls memmove. Make sure it has ABI wrappers.
-//
-//go:linkname memmove
-
-//go:linkname reflect_memmove reflect.memmove
-func reflect_memmove(to, from unsafe.Pointer, n uintptr) {
- memmove(to, from, n)
-}
-
-// exported value for testing
-const hashLoad = float32(loadFactorNum) / float32(loadFactorDen)
-
-//go:nosplit
-func fastrand() uint32 {
- mp := getg().m
- // Implement wyrand: https://github.com/wangyi-fudan/wyhash
- // Only the platform that math.Mul64 can be lowered
- // by the compiler should be in this list.
- if goarch.IsAmd64|goarch.IsArm64|goarch.IsPpc64|
- goarch.IsPpc64le|goarch.IsMips64|goarch.IsMips64le|
- goarch.IsS390x|goarch.IsRiscv64|goarch.IsLoong64 == 1 {
- mp.fastrand += 0xa0761d6478bd642f
- hi, lo := math.Mul64(mp.fastrand, mp.fastrand^0xe7037ed1a0b428db)
- return uint32(hi ^ lo)
- }
-
- // Implement xorshift64+: 2 32-bit xorshift sequences added together.
- // Shift triplet [17,7,16] was calculated as indicated in Marsaglia's
- // Xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
- // This generator passes the SmallCrush suite, part of TestU01 framework:
- // http://simul.iro.umontreal.ca/testu01/tu01.html
- t := (*[2]uint32)(unsafe.Pointer(&mp.fastrand))
- s1, s0 := t[0], t[1]
- s1 ^= s1 << 17
- s1 = s1 ^ s0 ^ s1>>7 ^ s0>>16
- t[0], t[1] = s0, s1
- return s0 + s1
-}
-
-//go:nosplit
-func fastrandn(n uint32) uint32 {
- // This is similar to fastrand() % n, but faster.
- // See https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
- return uint32(uint64(fastrand()) * uint64(n) >> 32)
-}
-
-func fastrand64() uint64 {
- mp := getg().m
- // Implement wyrand: https://github.com/wangyi-fudan/wyhash
- // Only the platform that math.Mul64 can be lowered
- // by the compiler should be in this list.
- if goarch.IsAmd64|goarch.IsArm64|goarch.IsPpc64|
- goarch.IsPpc64le|goarch.IsMips64|goarch.IsMips64le|
- goarch.IsS390x|goarch.IsRiscv64 == 1 {
- mp.fastrand += 0xa0761d6478bd642f
- hi, lo := math.Mul64(mp.fastrand, mp.fastrand^0xe7037ed1a0b428db)
- return hi ^ lo
- }
-
- // Implement xorshift64+: 2 32-bit xorshift sequences added together.
- // Xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
- // This generator passes the SmallCrush suite, part of TestU01 framework:
- // http://simul.iro.umontreal.ca/testu01/tu01.html
- t := (*[2]uint32)(unsafe.Pointer(&mp.fastrand))
- s1, s0 := t[0], t[1]
- s1 ^= s1 << 17
- s1 = s1 ^ s0 ^ s1>>7 ^ s0>>16
- r := uint64(s0 + s1)
-
- s0, s1 = s1, s0
- s1 ^= s1 << 17
- s1 = s1 ^ s0 ^ s1>>7 ^ s0>>16
- r += uint64(s0+s1) << 32
-
- t[0], t[1] = s0, s1
- return r
-}
-
-func fastrandu() uint {
- if goarch.PtrSize == 4 {
- return uint(fastrand())
- }
- return uint(fastrand64())
-}
-
-//go:linkname rand_fastrand64 math/rand.fastrand64
-func rand_fastrand64() uint64 { return fastrand64() }
-
-//go:linkname sync_fastrandn sync.fastrandn
-func sync_fastrandn(n uint32) uint32 { return fastrandn(n) }
-
-//go:linkname net_fastrandu net.fastrandu
-func net_fastrandu() uint { return fastrandu() }
-
-//go:linkname os_fastrand os.fastrand
-func os_fastrand() uint32 { return fastrand() }
-
-// in internal/bytealg/equal_*.s
-//
-//go:noescape
-func memequal(a, b unsafe.Pointer, size uintptr) bool
-
-// noescape hides a pointer from escape analysis. noescape is
-// the identity function but escape analysis doesn't think the
-// output depends on the input. noescape is inlined and currently
-// compiles down to zero instructions.
-// USE CAREFULLY!
-//
-//go:nosplit
-func noescape(p unsafe.Pointer) unsafe.Pointer {
- x := uintptr(p)
- return unsafe.Pointer(x ^ 0)
-}
-
-// Not all cgocallback frames are actually cgocallback,
-// so not all have these arguments. Mark them uintptr so that the GC
-// does not misinterpret memory when the arguments are not present.
-// cgocallback is not called from Go, only from crosscall2.
-// This in turn calls cgocallbackg, which is where we'll find
-// pointer-declared arguments.
-func cgocallback(fn, frame, ctxt uintptr)
-
-func gogo(buf *gobuf)
-
-func asminit()
-func setg(gg *g)
-func breakpoint()
-
-// reflectcall calls fn with arguments described by stackArgs, stackArgsSize,
-// frameSize, and regArgs.
-//
-// Arguments passed on the stack and space for return values passed on the stack
-// must be laid out at the space pointed to by stackArgs (with total length
-// stackArgsSize) according to the ABI.
-//
-// stackRetOffset must be some value <= stackArgsSize that indicates the
-// offset within stackArgs where the return value space begins.
-//
-// frameSize is the total size of the argument frame at stackArgs and must
-// therefore be >= stackArgsSize. It must include additional space for spilling
-// register arguments for stack growth and preemption.
-//
-// TODO(mknyszek): Once we don't need the additional spill space, remove frameSize,
-// since frameSize will be redundant with stackArgsSize.
-//
-// Arguments passed in registers must be laid out in regArgs according to the ABI.
-// regArgs will hold any return values passed in registers after the call.
-//
-// reflectcall copies stack arguments from stackArgs to the goroutine stack, and
-// then copies back stackArgsSize-stackRetOffset bytes back to the return space
-// in stackArgs once fn has completed. It also "unspills" argument registers from
-// regArgs before calling fn, and spills them back into regArgs immediately
-// following the call to fn. If there are results being returned on the stack,
-// the caller should pass the argument frame type as stackArgsType so that
-// reflectcall can execute appropriate write barriers during the copy.
-//
-// reflectcall expects regArgs.ReturnIsPtr to be populated indicating which
-// registers on the return path will contain Go pointers. It will then store
-// these pointers in regArgs.Ptrs such that they are visible to the GC.
-//
-// Package reflect passes a frame type. In package runtime, there is only
-// one call that copies results back, in callbackWrap in syscall_windows.go, and it
-// does NOT pass a frame type, meaning there are no write barriers invoked. See that
-// call site for justification.
-//
-// Package reflect accesses this symbol through a linkname.
-//
-// Arguments passed through to reflectcall do not escape. The type is used
-// only in a very limited callee of reflectcall, the stackArgs are copied, and
-// regArgs is only used in the reflectcall frame.
-//
-//go:noescape
-func reflectcall(stackArgsType *_type, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-
-func procyield(cycles uint32)
-
-type neverCallThisFunction struct{}
-
-// goexit is the return stub at the top of every goroutine call stack.
-// Each goroutine stack is constructed as if goexit called the
-// goroutine's entry point function, so that when the entry point
-// function returns, it will return to goexit, which will call goexit1
-// to perform the actual exit.
-//
-// This function must never be called directly. Call goexit1 instead.
-// gentraceback assumes that goexit terminates the stack. A direct
-// call on the stack will cause gentraceback to stop walking the stack
-// prematurely and if there is leftover state it may panic.
-func goexit(neverCallThisFunction)
-
-// publicationBarrier performs a store/store barrier (a "publication"
-// or "export" barrier). Some form of synchronization is required
-// between initializing an object and making that object accessible to
-// another processor. Without synchronization, the initialization
-// writes and the "publication" write may be reordered, allowing the
-// other processor to follow the pointer and observe an uninitialized
-// object. In general, higher-level synchronization should be used,
-// such as locking or an atomic pointer write. publicationBarrier is
-// for when those aren't an option, such as in the implementation of
-// the memory manager.
-//
-// There's no corresponding barrier for the read side because the read
-// side naturally has a data dependency order. All architectures that
-// Go supports or seems likely to ever support automatically enforce
-// data dependency ordering.
-func publicationBarrier()
-
-// getcallerpc returns the program counter (PC) of its caller's caller.
-// getcallersp returns the stack pointer (SP) of its caller's caller.
-// The implementation may be a compiler intrinsic; there is not
-// necessarily code implementing this on every platform.
-//
-// For example:
-//
-// func f(arg1, arg2, arg3 int) {
-// pc := getcallerpc()
-// sp := getcallersp()
-// }
-//
-// These two lines find the PC and SP immediately following
-// the call to f (where f will return).
-//
-// The call to getcallerpc and getcallersp must be done in the
-// frame being asked about.
-//
-// The result of getcallersp is correct at the time of the return,
-// but it may be invalidated by any subsequent call to a function
-// that might relocate the stack in order to grow or shrink it.
-// A general rule is that the result of getcallersp should be used
-// immediately and can only be passed to nosplit functions.
-
-//go:noescape
-func getcallerpc() uintptr
-
-//go:noescape
-func getcallersp() uintptr // implemented as an intrinsic on all platforms
-
-// getclosureptr returns the pointer to the current closure.
-// getclosureptr can only be used in an assignment statement
-// at the entry of a function. Moreover, go:nosplit directive
-// must be specified at the declaration of caller function,
-// so that the function prolog does not clobber the closure register.
-// for example:
-//
-// //go:nosplit
-// func f(arg1, arg2, arg3 int) {
-// dx := getclosureptr()
-// }
-//
-// The compiler rewrites calls to this function into instructions that fetch the
-// pointer from a well-known register (DX on x86 architecture, etc.) directly.
-func getclosureptr() uintptr
-
-//go:noescape
-func asmcgocall(fn, arg unsafe.Pointer) int32
-
-func morestack()
-func morestack_noctxt()
-func rt0_go()
-
-// return0 is a stub used to return 0 from deferproc.
-// It is called at the very end of deferproc to signal
-// the calling Go function that it should not jump
-// to deferreturn.
-// in asm_*.s
-func return0()
-
-// in asm_*.s
-// not called directly; definitions here supply type information for traceback.
-// These must have the same signature (arg pointer map) as reflectcall.
-func call16(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call32(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call64(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call128(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call256(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call512(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call1024(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call2048(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call4096(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call8192(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call16384(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call32768(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call65536(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call131072(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call262144(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call524288(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call1048576(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call2097152(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call4194304(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call8388608(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call16777216(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call33554432(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call67108864(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call134217728(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call268435456(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call536870912(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-func call1073741824(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
-
-func systemstack_switch()
-
-// alignUp rounds n up to a multiple of a. a must be a power of 2.
-func alignUp(n, a uintptr) uintptr {
- return (n + a - 1) &^ (a - 1)
-}
-
-// alignDown rounds n down to a multiple of a. a must be a power of 2.
-func alignDown(n, a uintptr) uintptr {
- return n &^ (a - 1)
-}
-
-// divRoundUp returns ceil(n / a).
-func divRoundUp(n, a uintptr) uintptr {
- // a is generally a power of two. This will get inlined and
- // the compiler will optimize the division.
- return (n + a - 1) / a
-}
-
-// checkASM reports whether assembly runtime checks have passed.
-func checkASM() bool
-
-func memequal_varlen(a, b unsafe.Pointer) bool
-
-// bool2int returns 0 if x is false or 1 if x is true.
-func bool2int(x bool) int {
- // Avoid branches. In the SSA compiler, this compiles to
- // exactly what you would want it to.
- return int(uint8(*(*uint8)(unsafe.Pointer(&x))))
-}
-
-// abort crashes the runtime in situations where even throw might not
-// work. In general it should do something a debugger will recognize
-// (e.g., an INT3 on x86). A crash in abort is recognized by the
-// signal handler, which will attempt to tear down the runtime
-// immediately.
-func abort()
-
-// Called from compiled code; declared for vet; do NOT call from Go.
-func gcWriteBarrier()
-func duffzero()
-func duffcopy()
-
-// Called from linker-generated .initarray; declared for go vet; do NOT call from Go.
-func addmoduledata()
-
-// Injected by the signal handler for panicking signals.
-// Initializes any registers that have fixed meaning at calls but
-// are scratch in bodies and calls sigpanic.
-// On many platforms it just jumps to sigpanic.
-func sigpanic0()
-
-// intArgRegs is used by the various register assignment
-// algorithm implementations in the runtime. These include:.
-// - Finalizers (mfinal.go)
-// - Windows callbacks (syscall_windows.go)
-//
-// Both are stripped-down versions of the algorithm since they
-// only have to deal with a subset of cases (finalizers only
-// take a pointer or interface argument, Go Windows callbacks
-// don't support floating point).
-//
-// It should be modified with care and are generally only
-// modified when testing this package.
-//
-// It should never be set higher than its internal/abi
-// constant counterparts, because the system relies on a
-// structure that is at least large enough to hold the
-// registers the system supports.
-//
-// Protected by finlock.
-var intArgRegs = abi.IntArgRegs
diff --git a/contrib/go/_std_1.20/src/runtime/stubs2.go b/contrib/go/_std_1.20/src/runtime/stubs2.go
deleted file mode 100644
index 0d83deb2af..0000000000
--- a/contrib/go/_std_1.20/src/runtime/stubs2.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2014 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.
-
-//go:build !aix && !darwin && !js && !openbsd && !plan9 && !solaris && !windows
-
-package runtime
-
-import (
- "runtime/internal/atomic"
- "unsafe"
-)
-
-// read calls the read system call.
-// It returns a non-negative number of bytes written or a negative errno value.
-func read(fd int32, p unsafe.Pointer, n int32) int32
-
-func closefd(fd int32) int32
-
-func exit(code int32)
-func usleep(usec uint32)
-
-//go:nosplit
-func usleep_no_g(usec uint32) {
- usleep(usec)
-}
-
-// write1 calls the write system call.
-// It returns a non-negative number of bytes written or a negative errno value.
-//
-//go:noescape
-func write1(fd uintptr, p unsafe.Pointer, n int32) int32
-
-//go:noescape
-func open(name *byte, mode, perm int32) int32
-
-// return value is only set on linux to be used in osinit().
-func madvise(addr unsafe.Pointer, n uintptr, flags int32) int32
-
-// exitThread terminates the current thread, writing *wait = freeMStack when
-// the stack is safe to reclaim.
-//
-//go:noescape
-func exitThread(wait *atomic.Uint32)
diff --git a/contrib/go/_std_1.20/src/runtime/stubs3.go b/contrib/go/_std_1.20/src/runtime/stubs3.go
deleted file mode 100644
index 891663b110..0000000000
--- a/contrib/go/_std_1.20/src/runtime/stubs3.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2018 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.
-
-//go:build !aix && !darwin && !freebsd && !openbsd && !plan9 && !solaris
-
-package runtime
-
-func nanotime1() int64
diff --git a/contrib/go/_std_1.20/src/runtime/stubs_amd64.go b/contrib/go/_std_1.20/src/runtime/stubs_amd64.go
deleted file mode 100644
index 687a506cdd..0000000000
--- a/contrib/go/_std_1.20/src/runtime/stubs_amd64.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2018 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 runtime
-
-import "unsafe"
-
-// Called from compiled code; declared for vet; do NOT call from Go.
-func gcWriteBarrierCX()
-func gcWriteBarrierDX()
-func gcWriteBarrierBX()
-func gcWriteBarrierBP()
-func gcWriteBarrierSI()
-func gcWriteBarrierR8()
-func gcWriteBarrierR9()
-
-// stackcheck checks that SP is in range [g->stack.lo, g->stack.hi).
-func stackcheck()
-
-// Called from assembly only; declared for go vet.
-func settls() // argument in DI
-
-// Retpolines, used by -spectre=ret flag in cmd/asm, cmd/compile.
-func retpolineAX()
-func retpolineCX()
-func retpolineDX()
-func retpolineBX()
-func retpolineBP()
-func retpolineSI()
-func retpolineDI()
-func retpolineR8()
-func retpolineR9()
-func retpolineR10()
-func retpolineR11()
-func retpolineR12()
-func retpolineR13()
-func retpolineR14()
-func retpolineR15()
-
-//go:noescape
-func asmcgocall_no_g(fn, arg unsafe.Pointer)
-
-// Used by reflectcall and the reflect package.
-//
-// Spills/loads arguments in registers to/from an internal/abi.RegArgs
-// respectively. Does not follow the Go ABI.
-func spillArgs()
-func unspillArgs()
diff --git a/contrib/go/_std_1.20/src/runtime/stubs_arm64.go b/contrib/go/_std_1.20/src/runtime/stubs_arm64.go
deleted file mode 100644
index bd0533d158..0000000000
--- a/contrib/go/_std_1.20/src/runtime/stubs_arm64.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-import "unsafe"
-
-// Called from assembly only; declared for go vet.
-func load_g()
-func save_g()
-
-//go:noescape
-func asmcgocall_no_g(fn, arg unsafe.Pointer)
-
-func emptyfunc()
-
-// Used by reflectcall and the reflect package.
-//
-// Spills/loads arguments in registers to/from an internal/abi.RegArgs
-// respectively. Does not follow the Go ABI.
-func spillArgs()
-func unspillArgs()
diff --git a/contrib/go/_std_1.20/src/runtime/symtab.go b/contrib/go/_std_1.20/src/runtime/symtab.go
deleted file mode 100644
index dead27e5f2..0000000000
--- a/contrib/go/_std_1.20/src/runtime/symtab.go
+++ /dev/null
@@ -1,1214 +0,0 @@
-// Copyright 2014 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 runtime
-
-import (
- "internal/goarch"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// Frames may be used to get function/file/line information for a
-// slice of PC values returned by Callers.
-type Frames struct {
- // callers is a slice of PCs that have not yet been expanded to frames.
- callers []uintptr
-
- // frames is a slice of Frames that have yet to be returned.
- frames []Frame
- frameStore [2]Frame
-}
-
-// Frame is the information returned by Frames for each call frame.
-type Frame struct {
- // PC is the program counter for the location in this frame.
- // For a frame that calls another frame, this will be the
- // program counter of a call instruction. Because of inlining,
- // multiple frames may have the same PC value, but different
- // symbolic information.
- PC uintptr
-
- // Func is the Func value of this call frame. This may be nil
- // for non-Go code or fully inlined functions.
- Func *Func
-
- // Function is the package path-qualified function name of
- // this call frame. If non-empty, this string uniquely
- // identifies a single function in the program.
- // This may be the empty string if not known.
- // If Func is not nil then Function == Func.Name().
- Function string
-
- // File and Line are the file name and line number of the
- // location in this frame. For non-leaf frames, this will be
- // the location of a call. These may be the empty string and
- // zero, respectively, if not known.
- File string
- Line int
-
- // startLine is the line number of the beginning of the function in
- // this frame. Specifically, it is the line number of the func keyword
- // for Go functions. Note that //line directives can change the
- // filename and/or line number arbitrarily within a function, meaning
- // that the Line - startLine offset is not always meaningful.
- //
- // This may be zero if not known.
- startLine int
-
- // Entry point program counter for the function; may be zero
- // if not known. If Func is not nil then Entry ==
- // Func.Entry().
- Entry uintptr
-
- // The runtime's internal view of the function. This field
- // is set (funcInfo.valid() returns true) only for Go functions,
- // not for C functions.
- funcInfo funcInfo
-}
-
-// CallersFrames takes a slice of PC values returned by Callers and
-// prepares to return function/file/line information.
-// Do not change the slice until you are done with the Frames.
-func CallersFrames(callers []uintptr) *Frames {
- f := &Frames{callers: callers}
- f.frames = f.frameStore[:0]
- return f
-}
-
-// Next returns a Frame representing the next call frame in the slice
-// of PC values. If it has already returned all call frames, Next
-// returns a zero Frame.
-//
-// The more result indicates whether the next call to Next will return
-// a valid Frame. It does not necessarily indicate whether this call
-// returned one.
-//
-// See the Frames example for idiomatic usage.
-func (ci *Frames) Next() (frame Frame, more bool) {
- for len(ci.frames) < 2 {
- // Find the next frame.
- // We need to look for 2 frames so we know what
- // to return for the "more" result.
- if len(ci.callers) == 0 {
- break
- }
- pc := ci.callers[0]
- ci.callers = ci.callers[1:]
- funcInfo := findfunc(pc)
- if !funcInfo.valid() {
- if cgoSymbolizer != nil {
- // Pre-expand cgo frames. We could do this
- // incrementally, too, but there's no way to
- // avoid allocation in this case anyway.
- ci.frames = append(ci.frames, expandCgoFrames(pc)...)
- }
- continue
- }
- f := funcInfo._Func()
- entry := f.Entry()
- if pc > entry {
- // We store the pc of the start of the instruction following
- // the instruction in question (the call or the inline mark).
- // This is done for historical reasons, and to make FuncForPC
- // work correctly for entries in the result of runtime.Callers.
- pc--
- }
- name := funcname(funcInfo)
- startLine := f.startLine()
- if inldata := funcdata(funcInfo, _FUNCDATA_InlTree); inldata != nil {
- inltree := (*[1 << 20]inlinedCall)(inldata)
- // 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
- ic := inltree[ix]
- name = funcnameFromNameOff(funcInfo, ic.nameOff)
- startLine = ic.startLine
- // File/line from funcline1 below are already correct.
- }
- }
- ci.frames = append(ci.frames, Frame{
- PC: pc,
- Func: f,
- Function: name,
- Entry: entry,
- startLine: int(startLine),
- funcInfo: funcInfo,
- // Note: File,Line set below
- })
- }
-
- // Pop one frame from the frame list. Keep the rest.
- // Avoid allocation in the common case, which is 1 or 2 frames.
- switch len(ci.frames) {
- case 0: // In the rare case when there are no frames at all, we return Frame{}.
- return
- case 1:
- frame = ci.frames[0]
- ci.frames = ci.frameStore[:0]
- case 2:
- frame = ci.frames[0]
- ci.frameStore[0] = ci.frames[1]
- ci.frames = ci.frameStore[:1]
- default:
- frame = ci.frames[0]
- ci.frames = ci.frames[1:]
- }
- more = len(ci.frames) > 0
- if frame.funcInfo.valid() {
- // Compute file/line just before we need to return it,
- // as it can be expensive. This avoids computing file/line
- // for the Frame we find but don't return. See issue 32093.
- file, line := funcline1(frame.funcInfo, frame.PC, false)
- frame.File, frame.Line = file, int(line)
- }
- return
-}
-
-// runtime_FrameStartLine returns the start line of the function in a Frame.
-//
-//go:linkname runtime_FrameStartLine runtime/pprof.runtime_FrameStartLine
-func runtime_FrameStartLine(f *Frame) int {
- return f.startLine
-}
-
-// runtime_expandFinalInlineFrame expands the final pc in stk to include all
-// "callers" if pc is inline.
-//
-//go:linkname runtime_expandFinalInlineFrame runtime/pprof.runtime_expandFinalInlineFrame
-func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr {
- if len(stk) == 0 {
- return stk
- }
- pc := stk[len(stk)-1]
- tracepc := pc - 1
-
- f := findfunc(tracepc)
- if !f.valid() {
- // Not a Go function.
- return stk
- }
-
- inldata := funcdata(f, _FUNCDATA_InlTree)
- if inldata == nil {
- // Nothing inline in f.
- return stk
- }
-
- // Treat the previous func as normal. We haven't actually checked, but
- // since this pc was included in the stack, we know it shouldn't be
- // elided.
- lastFuncID := funcID_normal
-
- // Remove pc from stk; we'll re-add it below.
- stk = stk[:len(stk)-1]
-
- // See inline expansion in gentraceback.
- var cache pcvalueCache
- inltree := (*[1 << 20]inlinedCall)(inldata)
- for {
- // 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
- }
- if inltree[ix].funcID == funcID_wrapper && elideWrapperCalling(lastFuncID) {
- // ignore wrappers
- } else {
- stk = append(stk, pc)
- }
- lastFuncID = inltree[ix].funcID
- // Back up to an instruction in the "caller".
- tracepc = f.entry() + uintptr(inltree[ix].parentPc)
- pc = tracepc + 1
- }
-
- // N.B. we want to keep the last parentPC which is not inline.
- stk = append(stk, pc)
-
- return stk
-}
-
-// expandCgoFrames expands frame information for pc, known to be
-// a non-Go function, using the cgoSymbolizer hook. expandCgoFrames
-// returns nil if pc could not be expanded.
-func expandCgoFrames(pc uintptr) []Frame {
- arg := cgoSymbolizerArg{pc: pc}
- callCgoSymbolizer(&arg)
-
- if arg.file == nil && arg.funcName == nil {
- // No useful information from symbolizer.
- return nil
- }
-
- var frames []Frame
- for {
- frames = append(frames, Frame{
- PC: pc,
- Func: nil,
- Function: gostring(arg.funcName),
- File: gostring(arg.file),
- Line: int(arg.lineno),
- Entry: arg.entry,
- // funcInfo is zero, which implies !funcInfo.valid().
- // That ensures that we use the File/Line info given here.
- })
- if arg.more == 0 {
- break
- }
- callCgoSymbolizer(&arg)
- }
-
- // No more frames for this PC. Tell the symbolizer we are done.
- // We don't try to maintain a single cgoSymbolizerArg for the
- // whole use of Frames, because there would be no good way to tell
- // the symbolizer when we are done.
- arg.pc = 0
- callCgoSymbolizer(&arg)
-
- return frames
-}
-
-// NOTE: Func does not expose the actual unexported fields, because we return *Func
-// values to users, and we want to keep them from being able to overwrite the data
-// with (say) *f = Func{}.
-// All code operating on a *Func must call raw() to get the *_func
-// or funcInfo() to get the funcInfo instead.
-
-// A Func represents a Go function in the running binary.
-type Func struct {
- opaque struct{} // unexported field to disallow conversions
-}
-
-func (f *Func) raw() *_func {
- return (*_func)(unsafe.Pointer(f))
-}
-
-func (f *Func) funcInfo() funcInfo {
- return f.raw().funcInfo()
-}
-
-func (f *_func) funcInfo() funcInfo {
- // Find the module containing fn. fn is located in the pclntable.
- // The unsafe.Pointer to uintptr conversions and arithmetic
- // are safe because we are working with module addresses.
- ptr := uintptr(unsafe.Pointer(f))
- var mod *moduledata
- for datap := &firstmoduledata; datap != nil; datap = datap.next {
- if len(datap.pclntable) == 0 {
- continue
- }
- base := uintptr(unsafe.Pointer(&datap.pclntable[0]))
- if base <= ptr && ptr < base+uintptr(len(datap.pclntable)) {
- mod = datap
- break
- }
- }
- return funcInfo{f, mod}
-}
-
-// PCDATA and FUNCDATA table indexes.
-//
-// See funcdata.h and ../cmd/internal/objabi/funcdata.go.
-const (
- _PCDATA_UnsafePoint = 0
- _PCDATA_StackMapIndex = 1
- _PCDATA_InlTreeIndex = 2
- _PCDATA_ArgLiveIndex = 3
-
- _FUNCDATA_ArgsPointerMaps = 0
- _FUNCDATA_LocalsPointerMaps = 1
- _FUNCDATA_StackObjects = 2
- _FUNCDATA_InlTree = 3
- _FUNCDATA_OpenCodedDeferInfo = 4
- _FUNCDATA_ArgInfo = 5
- _FUNCDATA_ArgLiveInfo = 6
- _FUNCDATA_WrapInfo = 7
-
- _ArgsSizeUnknown = -0x80000000
-)
-
-const (
- // PCDATA_UnsafePoint values.
- _PCDATA_UnsafePointSafe = -1 // Safe for async preemption
- _PCDATA_UnsafePointUnsafe = -2 // Unsafe for async preemption
-
- // _PCDATA_Restart1(2) apply on a sequence of instructions, within
- // which if an async preemption happens, we should back off the PC
- // to the start of the sequence when resume.
- // We need two so we can distinguish the start/end of the sequence
- // in case that two sequences are next to each other.
- _PCDATA_Restart1 = -3
- _PCDATA_Restart2 = -4
-
- // Like _PCDATA_RestartAtEntry, but back to function entry if async
- // preempted.
- _PCDATA_RestartAtEntry = -5
-)
-
-// A FuncID identifies particular functions that need to be treated
-// specially by the runtime.
-// Note that in some situations involving plugins, there may be multiple
-// copies of a particular special runtime function.
-// Note: this list must match the list in cmd/internal/objabi/funcid.go.
-type funcID uint8
-
-const (
- funcID_normal funcID = iota // not a special function
- funcID_abort
- funcID_asmcgocall
- funcID_asyncPreempt
- funcID_cgocallback
- funcID_debugCallV2
- funcID_gcBgMarkWorker
- funcID_goexit
- funcID_gogo
- funcID_gopanic
- funcID_handleAsyncEvent
- funcID_mcall
- funcID_morestack
- funcID_mstart
- funcID_panicwrap
- funcID_rt0_go
- funcID_runfinq
- funcID_runtime_main
- funcID_sigpanic
- funcID_systemstack
- funcID_systemstack_switch
- funcID_wrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.)
-)
-
-// A FuncFlag holds bits about a function.
-// This list must match the list in cmd/internal/objabi/funcid.go.
-type funcFlag uint8
-
-const (
- // TOPFRAME indicates a function that appears at the top of its stack.
- // The traceback routine stop at such a function and consider that a
- // successful, complete traversal of the stack.
- // Examples of TOPFRAME functions include goexit, which appears
- // at the top of a user goroutine stack, and mstart, which appears
- // at the top of a system goroutine stack.
- funcFlag_TOPFRAME funcFlag = 1 << iota
-
- // SPWRITE indicates a function that writes an arbitrary value to SP
- // (any write other than adding or subtracting a constant amount).
- // The traceback routines cannot encode such changes into the
- // pcsp tables, so the function traceback cannot safely unwind past
- // SPWRITE functions. Stopping at an SPWRITE function is considered
- // to be an incomplete unwinding of the stack. In certain contexts
- // (in particular garbage collector stack scans) that is a fatal error.
- funcFlag_SPWRITE
-
- // ASM indicates that a function was implemented in assembly.
- funcFlag_ASM
-)
-
-// pcHeader holds data used by the pclntab lookups.
-type pcHeader struct {
- magic uint32 // 0xFFFFFFF1
- pad1, pad2 uint8 // 0,0
- minLC uint8 // min instruction size
- ptrSize uint8 // size of a ptr in bytes
- nfunc int // number of functions in the module
- nfiles uint // number of entries in the file tab
- textStart uintptr // base for function entry PC offsets in this module, equal to moduledata.text
- funcnameOffset uintptr // offset to the funcnametab variable from pcHeader
- cuOffset uintptr // offset to the cutab variable from pcHeader
- filetabOffset uintptr // offset to the filetab variable from pcHeader
- pctabOffset uintptr // offset to the pctab variable from pcHeader
- pclnOffset uintptr // offset to the pclntab variable from pcHeader
-}
-
-// moduledata records information about the layout of the executable
-// image. It is written by the linker. Any changes here must be
-// matched changes to the code in cmd/link/internal/ld/symtab.go:symtab.
-// moduledata is stored in statically allocated non-pointer memory;
-// none of the pointers here are visible to the garbage collector.
-type moduledata struct {
- pcHeader *pcHeader
- funcnametab []byte
- cutab []uint32
- filetab []byte
- pctab []byte
- pclntable []byte
- ftab []functab
- findfunctab uintptr
- minpc, maxpc uintptr
-
- text, etext uintptr
- noptrdata, enoptrdata uintptr
- data, edata uintptr
- bss, ebss uintptr
- noptrbss, enoptrbss uintptr
- covctrs, ecovctrs uintptr
- end, gcdata, gcbss uintptr
- types, etypes uintptr
- rodata uintptr
- gofunc uintptr // go.func.*
-
- textsectmap []textsect
- typelinks []int32 // offsets from types
- itablinks []*itab
-
- ptab []ptabEntry
-
- pluginpath string
- pkghashes []modulehash
-
- modulename string
- modulehashes []modulehash
-
- hasmain uint8 // 1 if module contains the main function, 0 otherwise
-
- gcdatamask, gcbssmask bitvector
-
- typemap map[typeOff]*_type // offset to *_rtype in previous module
-
- bad bool // module failed to load and should be ignored
-
- next *moduledata
-}
-
-// A modulehash is used to compare the ABI of a new module or a
-// package in a new module with the loaded program.
-//
-// For each shared library a module links against, the linker creates an entry in the
-// moduledata.modulehashes slice containing the name of the module, the abi hash seen
-// at link time and a pointer to the runtime abi hash. These are checked in
-// moduledataverify1 below.
-//
-// For each loaded plugin, the pkghashes slice has a modulehash of the
-// newly loaded package that can be used to check the plugin's version of
-// a package against any previously loaded version of the package.
-// This is done in plugin.lastmoduleinit.
-type modulehash struct {
- modulename string
- linktimehash string
- runtimehash *string
-}
-
-// pinnedTypemaps are the map[typeOff]*_type from the moduledata objects.
-//
-// These typemap objects are allocated at run time on the heap, but the
-// only direct reference to them is in the moduledata, created by the
-// linker and marked SNOPTRDATA so it is ignored by the GC.
-//
-// To make sure the map isn't collected, we keep a second reference here.
-var pinnedTypemaps []map[typeOff]*_type
-
-var firstmoduledata moduledata // linker symbol
-var lastmoduledatap *moduledata // linker symbol
-var modulesSlice *[]*moduledata // see activeModules
-
-// activeModules returns a slice of active modules.
-//
-// A module is active once its gcdatamask and gcbssmask have been
-// assembled and it is usable by the GC.
-//
-// This is nosplit/nowritebarrier because it is called by the
-// cgo pointer checking code.
-//
-//go:nosplit
-//go:nowritebarrier
-func activeModules() []*moduledata {
- p := (*[]*moduledata)(atomic.Loadp(unsafe.Pointer(&modulesSlice)))
- if p == nil {
- return nil
- }
- return *p
-}
-
-// modulesinit creates the active modules slice out of all loaded modules.
-//
-// When a module is first loaded by the dynamic linker, an .init_array
-// function (written by cmd/link) is invoked to call addmoduledata,
-// appending to the module to the linked list that starts with
-// firstmoduledata.
-//
-// There are two times this can happen in the lifecycle of a Go
-// program. First, if compiled with -linkshared, a number of modules
-// built with -buildmode=shared can be loaded at program initialization.
-// Second, a Go program can load a module while running that was built
-// with -buildmode=plugin.
-//
-// After loading, this function is called which initializes the
-// moduledata so it is usable by the GC and creates a new activeModules
-// list.
-//
-// Only one goroutine may call modulesinit at a time.
-func modulesinit() {
- modules := new([]*moduledata)
- for md := &firstmoduledata; md != nil; md = md.next {
- if md.bad {
- continue
- }
- *modules = append(*modules, md)
- if md.gcdatamask == (bitvector{}) {
- scanDataSize := md.edata - md.data
- md.gcdatamask = progToPointerMask((*byte)(unsafe.Pointer(md.gcdata)), scanDataSize)
- scanBSSSize := md.ebss - md.bss
- md.gcbssmask = progToPointerMask((*byte)(unsafe.Pointer(md.gcbss)), scanBSSSize)
- gcController.addGlobals(int64(scanDataSize + scanBSSSize))
- }
- }
-
- // Modules appear in the moduledata linked list in the order they are
- // loaded by the dynamic loader, with one exception: the
- // firstmoduledata itself the module that contains the runtime. This
- // is not always the first module (when using -buildmode=shared, it
- // is typically libstd.so, the second module). The order matters for
- // typelinksinit, so we swap the first module with whatever module
- // contains the main function.
- //
- // See Issue #18729.
- for i, md := range *modules {
- if md.hasmain != 0 {
- (*modules)[0] = md
- (*modules)[i] = &firstmoduledata
- break
- }
- }
-
- atomicstorep(unsafe.Pointer(&modulesSlice), unsafe.Pointer(modules))
-}
-
-type functab struct {
- entryoff uint32 // relative to runtime.text
- funcoff uint32
-}
-
-// Mapping information for secondary text sections
-
-type textsect struct {
- vaddr uintptr // prelinked section vaddr
- end uintptr // vaddr + section length
- baseaddr uintptr // relocated section address
-}
-
-const minfunc = 16 // minimum function size
-const pcbucketsize = 256 * minfunc // size of bucket in the pc->func lookup table
-
-// findfuncbucket is an array of these structures.
-// Each bucket represents 4096 bytes of the text segment.
-// Each subbucket represents 256 bytes of the text segment.
-// To find a function given a pc, locate the bucket and subbucket for
-// that pc. Add together the idx and subbucket value to obtain a
-// function index. Then scan the functab array starting at that
-// index to find the target function.
-// This table uses 20 bytes for every 4096 bytes of code, or ~0.5% overhead.
-type findfuncbucket struct {
- idx uint32
- subbuckets [16]byte
-}
-
-func moduledataverify() {
- for datap := &firstmoduledata; datap != nil; datap = datap.next {
- moduledataverify1(datap)
- }
-}
-
-const debugPcln = false
-
-func moduledataverify1(datap *moduledata) {
- // Check that the pclntab's format is valid.
- hdr := datap.pcHeader
- if hdr.magic != 0xfffffff1 || hdr.pad1 != 0 || hdr.pad2 != 0 ||
- hdr.minLC != sys.PCQuantum || hdr.ptrSize != goarch.PtrSize || hdr.textStart != datap.text {
- println("runtime: pcHeader: magic=", hex(hdr.magic), "pad1=", hdr.pad1, "pad2=", hdr.pad2,
- "minLC=", hdr.minLC, "ptrSize=", hdr.ptrSize, "pcHeader.textStart=", hex(hdr.textStart),
- "text=", hex(datap.text), "pluginpath=", datap.pluginpath)
- throw("invalid function symbol table")
- }
-
- // ftab is lookup table for function by program counter.
- nftab := len(datap.ftab) - 1
- for i := 0; i < nftab; i++ {
- // NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
- if datap.ftab[i].entryoff > datap.ftab[i+1].entryoff {
- f1 := funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i].funcoff])), datap}
- f2 := funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i+1].funcoff])), datap}
- f2name := "end"
- if i+1 < nftab {
- f2name = funcname(f2)
- }
- println("function symbol table not sorted by PC offset:", hex(datap.ftab[i].entryoff), funcname(f1), ">", hex(datap.ftab[i+1].entryoff), f2name, ", plugin:", datap.pluginpath)
- for j := 0; j <= i; j++ {
- println("\t", hex(datap.ftab[j].entryoff), funcname(funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[j].funcoff])), datap}))
- }
- if GOOS == "aix" && isarchive {
- println("-Wl,-bnoobjreorder is mandatory on aix/ppc64 with c-archive")
- }
- throw("invalid runtime symbol table")
- }
- }
-
- min := datap.textAddr(datap.ftab[0].entryoff)
- max := datap.textAddr(datap.ftab[nftab].entryoff)
- if datap.minpc != min || datap.maxpc != max {
- println("minpc=", hex(datap.minpc), "min=", hex(min), "maxpc=", hex(datap.maxpc), "max=", hex(max))
- throw("minpc or maxpc invalid")
- }
-
- for _, modulehash := range datap.modulehashes {
- if modulehash.linktimehash != *modulehash.runtimehash {
- println("abi mismatch detected between", datap.modulename, "and", modulehash.modulename)
- throw("abi mismatch")
- }
- }
-}
-
-// textAddr returns md.text + off, with special handling for multiple text sections.
-// off is a (virtual) offset computed at internal linking time,
-// before the external linker adjusts the sections' base addresses.
-//
-// The text, or instruction stream is generated as one large buffer.
-// The off (offset) for a function is its offset within this buffer.
-// If the total text size gets too large, there can be issues on platforms like ppc64
-// if the target of calls are too far for the call instruction.
-// To resolve the large text issue, the text is split into multiple text sections
-// to allow the linker to generate long calls when necessary.
-// When this happens, the vaddr for each text section is set to its offset within the text.
-// Each function's offset is compared against the section vaddrs and ends to determine the containing section.
-// Then the section relative offset is added to the section's
-// relocated baseaddr to compute the function address.
-//
-// It is nosplit because it is part of the findfunc implementation.
-//
-//go:nosplit
-func (md *moduledata) textAddr(off32 uint32) uintptr {
- off := uintptr(off32)
- res := md.text + off
- if len(md.textsectmap) > 1 {
- for i, sect := range md.textsectmap {
- // For the last section, include the end address (etext), as it is included in the functab.
- if off >= sect.vaddr && off < sect.end || (i == len(md.textsectmap)-1 && off == sect.end) {
- res = sect.baseaddr + off - sect.vaddr
- break
- }
- }
- if res > md.etext && GOARCH != "wasm" { // on wasm, functions do not live in the same address space as the linear memory
- println("runtime: textAddr", hex(res), "out of range", hex(md.text), "-", hex(md.etext))
- throw("runtime: text offset out of range")
- }
- }
- return res
-}
-
-// textOff is the opposite of textAddr. It converts a PC to a (virtual) offset
-// to md.text, and returns if the PC is in any Go text section.
-//
-// It is nosplit because it is part of the findfunc implementation.
-//
-//go:nosplit
-func (md *moduledata) textOff(pc uintptr) (uint32, bool) {
- res := uint32(pc - md.text)
- if len(md.textsectmap) > 1 {
- for i, sect := range md.textsectmap {
- if sect.baseaddr > pc {
- // pc is not in any section.
- return 0, false
- }
- end := sect.baseaddr + (sect.end - sect.vaddr)
- // For the last section, include the end address (etext), as it is included in the functab.
- if i == len(md.textsectmap) {
- end++
- }
- if pc < end {
- res = uint32(pc - sect.baseaddr + sect.vaddr)
- break
- }
- }
- }
- return res, true
-}
-
-// FuncForPC returns a *Func describing the function that contains the
-// given program counter address, or else nil.
-//
-// If pc represents multiple functions because of inlining, it returns
-// the *Func describing the innermost function, but with an entry of
-// the outermost function.
-func FuncForPC(pc uintptr) *Func {
- f := findfunc(pc)
- if !f.valid() {
- return nil
- }
- if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil {
- // Note: strict=false so bad PCs (those between functions) don't crash the runtime.
- // We just report the preceding function in that situation. See issue 29735.
- // TODO: Perhaps we should report no function at all in that case.
- // The runtime currently doesn't have function end info, alas.
- if ix := pcdatavalue1(f, _PCDATA_InlTreeIndex, pc, nil, false); ix >= 0 {
- inltree := (*[1 << 20]inlinedCall)(inldata)
- ic := inltree[ix]
- name := funcnameFromNameOff(f, ic.nameOff)
- file, line := funcline(f, pc)
- fi := &funcinl{
- ones: ^uint32(0),
- entry: f.entry(), // entry of the real (the outermost) function.
- name: name,
- file: file,
- line: line,
- startLine: ic.startLine,
- }
- return (*Func)(unsafe.Pointer(fi))
- }
- }
- return f._Func()
-}
-
-// Name returns the name of the function.
-func (f *Func) Name() string {
- if f == nil {
- return ""
- }
- fn := f.raw()
- if fn.isInlined() { // inlined version
- fi := (*funcinl)(unsafe.Pointer(fn))
- return fi.name
- }
- return funcname(f.funcInfo())
-}
-
-// Entry returns the entry address of the function.
-func (f *Func) Entry() uintptr {
- fn := f.raw()
- if fn.isInlined() { // inlined version
- fi := (*funcinl)(unsafe.Pointer(fn))
- return fi.entry
- }
- return fn.funcInfo().entry()
-}
-
-// FileLine returns the file name and line number of the
-// source code corresponding to the program counter pc.
-// The result will not be accurate if pc is not a program
-// counter within f.
-func (f *Func) FileLine(pc uintptr) (file string, line int) {
- fn := f.raw()
- if fn.isInlined() { // inlined version
- fi := (*funcinl)(unsafe.Pointer(fn))
- return fi.file, int(fi.line)
- }
- // Pass strict=false here, because anyone can call this function,
- // and they might just be wrong about targetpc belonging to f.
- file, line32 := funcline1(f.funcInfo(), pc, false)
- return file, int(line32)
-}
-
-// startLine returns the starting line number of the function. i.e., the line
-// number of the func keyword.
-func (f *Func) startLine() int32 {
- fn := f.raw()
- if fn.isInlined() { // inlined version
- fi := (*funcinl)(unsafe.Pointer(fn))
- return fi.startLine
- }
- return fn.funcInfo().startLine
-}
-
-// findmoduledatap looks up the moduledata for a PC.
-//
-// It is nosplit because it's part of the isgoexception
-// implementation.
-//
-//go:nosplit
-func findmoduledatap(pc uintptr) *moduledata {
- for datap := &firstmoduledata; datap != nil; datap = datap.next {
- if datap.minpc <= pc && pc < datap.maxpc {
- return datap
- }
- }
- return nil
-}
-
-type funcInfo struct {
- *_func
- datap *moduledata
-}
-
-func (f funcInfo) valid() bool {
- return f._func != nil
-}
-
-func (f funcInfo) _Func() *Func {
- return (*Func)(unsafe.Pointer(f._func))
-}
-
-// isInlined reports whether f should be re-interpreted as a *funcinl.
-func (f *_func) isInlined() bool {
- return f.entryOff == ^uint32(0) // see comment for funcinl.ones
-}
-
-// entry returns the entry PC for f.
-func (f funcInfo) entry() uintptr {
- return f.datap.textAddr(f.entryOff)
-}
-
-// findfunc looks up function metadata for a PC.
-//
-// It is nosplit because it's part of the isgoexception
-// implementation.
-//
-//go:nosplit
-func findfunc(pc uintptr) funcInfo {
- datap := findmoduledatap(pc)
- if datap == nil {
- return funcInfo{}
- }
- const nsub = uintptr(len(findfuncbucket{}.subbuckets))
-
- pcOff, ok := datap.textOff(pc)
- if !ok {
- return funcInfo{}
- }
-
- x := uintptr(pcOff) + datap.text - datap.minpc // TODO: are datap.text and datap.minpc always equal?
- b := x / pcbucketsize
- i := x % pcbucketsize / (pcbucketsize / nsub)
-
- ffb := (*findfuncbucket)(add(unsafe.Pointer(datap.findfunctab), b*unsafe.Sizeof(findfuncbucket{})))
- idx := ffb.idx + uint32(ffb.subbuckets[i])
-
- // Find the ftab entry.
- for datap.ftab[idx+1].entryoff <= pcOff {
- idx++
- }
-
- funcoff := datap.ftab[idx].funcoff
- return funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[funcoff])), datap}
-}
-
-type pcvalueCache struct {
- entries [2][8]pcvalueCacheEnt
-}
-
-type pcvalueCacheEnt struct {
- // targetpc and off together are the key of this cache entry.
- targetpc uintptr
- off uint32
- // val is the value of this cached pcvalue entry.
- val int32
-}
-
-// pcvalueCacheKey returns the outermost index in a pcvalueCache to use for targetpc.
-// It must be very cheap to calculate.
-// For now, align to goarch.PtrSize and reduce mod the number of entries.
-// In practice, this appears to be fairly randomly and evenly distributed.
-func pcvalueCacheKey(targetpc uintptr) uintptr {
- return (targetpc / goarch.PtrSize) % uintptr(len(pcvalueCache{}.entries))
-}
-
-// Returns the PCData value, and the PC where this value starts.
-// TODO: the start PC is returned only when cache is nil.
-func pcvalue(f funcInfo, off uint32, targetpc uintptr, cache *pcvalueCache, strict bool) (int32, uintptr) {
- if off == 0 {
- return -1, 0
- }
-
- // Check the cache. This speeds up walks of deep stacks, which
- // tend to have the same recursive functions over and over.
- //
- // This cache is small enough that full associativity is
- // cheaper than doing the hashing for a less associative
- // cache.
- if cache != nil {
- x := pcvalueCacheKey(targetpc)
- for i := range cache.entries[x] {
- // We check off first because we're more
- // likely to have multiple entries with
- // different offsets for the same targetpc
- // than the other way around, so we'll usually
- // fail in the first clause.
- ent := &cache.entries[x][i]
- if ent.off == off && ent.targetpc == targetpc {
- return ent.val, 0
- }
- }
- }
-
- if !f.valid() {
- if strict && panicking.Load() == 0 {
- println("runtime: no module data for", hex(f.entry()))
- throw("no module data")
- }
- return -1, 0
- }
- datap := f.datap
- p := datap.pctab[off:]
- pc := f.entry()
- prevpc := pc
- val := int32(-1)
- for {
- var ok bool
- p, ok = step(p, &pc, &val, pc == f.entry())
- if !ok {
- break
- }
- if targetpc < pc {
- // Replace a random entry in the cache. Random
- // replacement prevents a performance cliff if
- // a recursive stack's cycle is slightly
- // larger than the cache.
- // Put the new element at the beginning,
- // since it is the most likely to be newly used.
- if cache != nil {
- x := pcvalueCacheKey(targetpc)
- e := &cache.entries[x]
- ci := fastrandn(uint32(len(cache.entries[x])))
- e[ci] = e[0]
- e[0] = pcvalueCacheEnt{
- targetpc: targetpc,
- off: off,
- val: val,
- }
- }
-
- return val, prevpc
- }
- prevpc = pc
- }
-
- // If there was a table, it should have covered all program counters.
- // If not, something is wrong.
- if panicking.Load() != 0 || !strict {
- return -1, 0
- }
-
- print("runtime: invalid pc-encoded table f=", funcname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")
-
- p = datap.pctab[off:]
- pc = f.entry()
- val = -1
- for {
- var ok bool
- p, ok = step(p, &pc, &val, pc == f.entry())
- if !ok {
- break
- }
- print("\tvalue=", val, " until pc=", hex(pc), "\n")
- }
-
- throw("invalid runtime symbol table")
- return -1, 0
-}
-
-func cfuncname(f funcInfo) *byte {
- if !f.valid() || f.nameOff == 0 {
- return nil
- }
- return &f.datap.funcnametab[f.nameOff]
-}
-
-func funcname(f funcInfo) string {
- return gostringnocopy(cfuncname(f))
-}
-
-func funcpkgpath(f funcInfo) string {
- name := funcname(f)
- i := len(name) - 1
- for ; i > 0; i-- {
- if name[i] == '/' {
- break
- }
- }
- for ; i < len(name); i++ {
- if name[i] == '.' {
- break
- }
- }
- return name[:i]
-}
-
-func cfuncnameFromNameOff(f funcInfo, nameOff int32) *byte {
- if !f.valid() {
- return nil
- }
- return &f.datap.funcnametab[nameOff]
-}
-
-func funcnameFromNameOff(f funcInfo, nameOff int32) string {
- return gostringnocopy(cfuncnameFromNameOff(f, nameOff))
-}
-
-func funcfile(f funcInfo, fileno int32) string {
- datap := f.datap
- if !f.valid() {
- return "?"
- }
- // Make sure the cu index and file offset are valid
- if fileoff := datap.cutab[f.cuOffset+uint32(fileno)]; fileoff != ^uint32(0) {
- return gostringnocopy(&datap.filetab[fileoff])
- }
- // pcln section is corrupt.
- return "?"
-}
-
-func funcline1(f funcInfo, targetpc uintptr, strict bool) (file string, line int32) {
- datap := f.datap
- if !f.valid() {
- return "?", 0
- }
- fileno, _ := pcvalue(f, f.pcfile, targetpc, nil, strict)
- line, _ = pcvalue(f, f.pcln, targetpc, nil, strict)
- if fileno == -1 || line == -1 || int(fileno) >= len(datap.filetab) {
- // print("looking for ", hex(targetpc), " in ", funcname(f), " got file=", fileno, " line=", lineno, "\n")
- return "?", 0
- }
- file = funcfile(f, fileno)
- return
-}
-
-func funcline(f funcInfo, targetpc uintptr) (file string, line int32) {
- return funcline1(f, targetpc, true)
-}
-
-func funcspdelta(f funcInfo, targetpc uintptr, cache *pcvalueCache) int32 {
- x, _ := pcvalue(f, f.pcsp, targetpc, cache, true)
- if debugPcln && x&(goarch.PtrSize-1) != 0 {
- print("invalid spdelta ", funcname(f), " ", hex(f.entry()), " ", hex(targetpc), " ", hex(f.pcsp), " ", x, "\n")
- throw("bad spdelta")
- }
- return x
-}
-
-// funcMaxSPDelta returns the maximum spdelta at any point in f.
-func funcMaxSPDelta(f funcInfo) int32 {
- datap := f.datap
- p := datap.pctab[f.pcsp:]
- pc := f.entry()
- val := int32(-1)
- max := int32(0)
- for {
- var ok bool
- p, ok = step(p, &pc, &val, pc == f.entry())
- if !ok {
- return max
- }
- if val > max {
- max = val
- }
- }
-}
-
-func pcdatastart(f funcInfo, table uint32) uint32 {
- return *(*uint32)(add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(table)*4))
-}
-
-func pcdatavalue(f funcInfo, table uint32, targetpc uintptr, cache *pcvalueCache) int32 {
- if table >= f.npcdata {
- return -1
- }
- r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, true)
- return r
-}
-
-func pcdatavalue1(f funcInfo, table uint32, targetpc uintptr, cache *pcvalueCache, strict bool) int32 {
- if table >= f.npcdata {
- return -1
- }
- r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, strict)
- return r
-}
-
-// Like pcdatavalue, but also return the start PC of this PCData value.
-// It doesn't take a cache.
-func pcdatavalue2(f funcInfo, table uint32, targetpc uintptr) (int32, uintptr) {
- if table >= f.npcdata {
- return -1, 0
- }
- return pcvalue(f, pcdatastart(f, table), targetpc, nil, true)
-}
-
-// funcdata returns a pointer to the ith funcdata for f.
-// funcdata should be kept in sync with cmd/link:writeFuncs.
-func funcdata(f funcInfo, i uint8) unsafe.Pointer {
- if i < 0 || i >= f.nfuncdata {
- return nil
- }
- base := f.datap.gofunc // load gofunc address early so that we calculate during cache misses
- p := uintptr(unsafe.Pointer(&f.nfuncdata)) + unsafe.Sizeof(f.nfuncdata) + uintptr(f.npcdata)*4 + uintptr(i)*4
- off := *(*uint32)(unsafe.Pointer(p))
- // Return off == ^uint32(0) ? 0 : f.datap.gofunc + uintptr(off), but without branches.
- // The compiler calculates mask on most architectures using conditional assignment.
- var mask uintptr
- if off == ^uint32(0) {
- mask = 1
- }
- mask--
- raw := base + uintptr(off)
- return unsafe.Pointer(raw & mask)
-}
-
-// step advances to the next pc, value pair in the encoded table.
-func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) {
- // For both uvdelta and pcdelta, the common case (~70%)
- // is that they are a single byte. If so, avoid calling readvarint.
- uvdelta := uint32(p[0])
- if uvdelta == 0 && !first {
- return nil, false
- }
- n := uint32(1)
- if uvdelta&0x80 != 0 {
- n, uvdelta = readvarint(p)
- }
- *val += int32(-(uvdelta & 1) ^ (uvdelta >> 1))
- p = p[n:]
-
- pcdelta := uint32(p[0])
- n = 1
- if pcdelta&0x80 != 0 {
- n, pcdelta = readvarint(p)
- }
- p = p[n:]
- *pc += uintptr(pcdelta * sys.PCQuantum)
- return p, true
-}
-
-// readvarint reads a varint from p.
-func readvarint(p []byte) (read uint32, val uint32) {
- var v, shift, n uint32
- for {
- b := p[n]
- n++
- v |= uint32(b&0x7F) << (shift & 31)
- if b&0x80 == 0 {
- break
- }
- shift += 7
- }
- return n, v
-}
-
-type stackmap struct {
- n int32 // number of bitmaps
- nbit int32 // number of bits in each bitmap
- bytedata [1]byte // bitmaps, each starting on a byte boundary
-}
-
-//go:nowritebarrier
-func stackmapdata(stkmap *stackmap, n int32) bitvector {
- // Check this invariant only when stackDebug is on at all.
- // The invariant is already checked by many of stackmapdata's callers,
- // and disabling it by default allows stackmapdata to be inlined.
- if stackDebug > 0 && (n < 0 || n >= stkmap.n) {
- throw("stackmapdata: index out of range")
- }
- return bitvector{stkmap.nbit, addb(&stkmap.bytedata[0], uintptr(n*((stkmap.nbit+7)>>3)))}
-}
-
-// inlinedCall is the encoding of entries in the FUNCDATA_InlTree table.
-type inlinedCall struct {
- funcID funcID // type of the called function
- _ [3]byte
- nameOff int32 // offset into pclntab for name of called function
- parentPc int32 // position of an instruction whose source position is the call site (offset from entry)
- startLine int32 // line number of start of function (func keyword/TEXT directive)
-}
diff --git a/contrib/go/_std_1.20/src/runtime/sys_darwin.go b/contrib/go/_std_1.20/src/runtime/sys_darwin.go
deleted file mode 100644
index 64d7523f24..0000000000
--- a/contrib/go/_std_1.20/src/runtime/sys_darwin.go
+++ /dev/null
@@ -1,608 +0,0 @@
-// Copyright 2018 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 runtime
-
-import (
- "internal/abi"
- "runtime/internal/atomic"
- "unsafe"
-)
-
-// The X versions of syscall expect the libc call to return a 64-bit result.
-// Otherwise (the non-X version) expects a 32-bit result.
-// This distinction is required because an error is indicated by returning -1,
-// and we need to know whether to check 32 or 64 bits of the result.
-// (Some libc functions that return 32 bits put junk in the upper 32 bits of AX.)
-
-//go:linkname syscall_syscall syscall.syscall
-//go:nosplit
-func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err}
- entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&args))
- exitsyscall()
- return args.r1, args.r2, args.err
-}
-func syscall()
-
-//go:linkname syscall_syscallX syscall.syscallX
-//go:nosplit
-func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err}
- entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallX)), unsafe.Pointer(&args))
- exitsyscall()
- return args.r1, args.r2, args.err
-}
-func syscallX()
-
-//go:linkname syscall_syscall6 syscall.syscall6
-//go:nosplit
-func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2, err}
- entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&args))
- exitsyscall()
- return args.r1, args.r2, args.err
-}
-func syscall6()
-
-//go:linkname syscall_syscall9 syscall.syscall9
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
- entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall9)), unsafe.Pointer(&fn))
- exitsyscall()
- return
-}
-func syscall9()
-
-//go:linkname syscall_syscall6X syscall.syscall6X
-//go:nosplit
-func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2, err}
- entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6X)), unsafe.Pointer(&args))
- exitsyscall()
- return args.r1, args.r2, args.err
-}
-func syscall6X()
-
-//go:linkname syscall_syscallPtr syscall.syscallPtr
-//go:nosplit
-func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err}
- entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallPtr)), unsafe.Pointer(&args))
- exitsyscall()
- return args.r1, args.r2, args.err
-}
-func syscallPtr()
-
-//go:linkname syscall_rawSyscall syscall.rawSyscall
-//go:nosplit
-func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err}
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&args))
- return args.r1, args.r2, args.err
-}
-
-//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
-//go:nosplit
-func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
- args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2, err}
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&args))
- return args.r1, args.r2, args.err
-}
-
-// crypto_x509_syscall is used in crypto/x509/internal/macos to call into Security.framework and CF.
-
-//go:linkname crypto_x509_syscall crypto/x509/internal/macos.syscall
-//go:nosplit
-func crypto_x509_syscall(fn, a1, a2, a3, a4, a5 uintptr, f1 float64) (r1 uintptr) {
- args := struct {
- fn, a1, a2, a3, a4, a5 uintptr
- f1 float64
- r1 uintptr
- }{fn, a1, a2, a3, a4, a5, f1, r1}
- entersyscall()
- libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall_x509)), unsafe.Pointer(&args))
- exitsyscall()
- return args.r1
-}
-func syscall_x509()
-
-// The *_trampoline functions convert from the Go calling convention to the C calling convention
-// and then call the underlying libc function. They are defined in sys_darwin_$ARCH.s.
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_attr_init(attr *pthreadattr) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
- KeepAlive(attr)
- return ret
-}
-func pthread_attr_init_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_attr_getstacksize(attr *pthreadattr, size *uintptr) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
- KeepAlive(attr)
- KeepAlive(size)
- return ret
-}
-func pthread_attr_getstacksize_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_attr_setdetachstate(attr *pthreadattr, state int) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
- KeepAlive(attr)
- return ret
-}
-func pthread_attr_setdetachstate_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_create(attr *pthreadattr, start uintptr, arg unsafe.Pointer) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_create_trampoline)), unsafe.Pointer(&attr))
- KeepAlive(attr)
- KeepAlive(arg) // Just for consistency. Arg of course needs to be kept alive for the start function.
- return ret
-}
-func pthread_create_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func raise(sig uint32) {
- libcCall(unsafe.Pointer(abi.FuncPCABI0(raise_trampoline)), unsafe.Pointer(&sig))
-}
-func raise_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_self() (t pthread) {
- libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_self_trampoline)), unsafe.Pointer(&t))
- return
-}
-func pthread_self_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_kill(t pthread, sig uint32) {
- libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_kill_trampoline)), unsafe.Pointer(&t))
- return
-}
-func pthread_kill_trampoline()
-
-// osinit_hack is a clumsy hack to work around Apple libc bugs
-// causing fork+exec to hang in the child process intermittently.
-// See go.dev/issue/33565 and go.dev/issue/56784 for a few reports.
-//
-// The stacks obtained from the hung child processes are in
-// libSystem_atfork_child, which is supposed to reinitialize various
-// parts of the C library in the new process.
-//
-// One common stack dies in _notify_fork_child calling _notify_globals
-// (inlined) calling _os_alloc_once, because _os_alloc_once detects that
-// the once lock is held by the parent process and then calls
-// _os_once_gate_corruption_abort. The allocation is setting up the
-// globals for the notification subsystem. See the source code at [1].
-// To work around this, we can allocate the globals earlier in the Go
-// program's lifetime, before any execs are involved, by calling any
-// notify routine that is exported, calls _notify_globals, and doesn't do
-// anything too expensive otherwise. notify_is_valid_token(0) fits the bill.
-//
-// The other common stack dies in xpc_atfork_child calling
-// _objc_msgSend_uncached which ends up in
-// WAITING_FOR_ANOTHER_THREAD_TO_FINISH_CALLING_+initialize. Of course,
-// whatever thread the child is waiting for is in the parent process and
-// is not going to finish anything in the child process. There is no
-// public source code for these routines, so it is unclear exactly what
-// the problem is. An Apple engineer suggests using xpc_date_create_from_current,
-// which empirically does fix the problem.
-//
-// So osinit_hack_trampoline (in sys_darwin_$GOARCH.s) calls
-// notify_is_valid_token(0) and xpc_date_create_from_current(), which makes the
-// fork+exec hangs stop happening. If Apple fixes the libc bug in
-// some future version of macOS, then we can remove this awful code.
-//
-//go:nosplit
-func osinit_hack() {
- if GOOS == "darwin" { // not ios
- libcCall(unsafe.Pointer(abi.FuncPCABI0(osinit_hack_trampoline)), nil)
- }
- return
-}
-func osinit_hack_trampoline()
-
-// mmap is used to do low-level memory allocation via mmap. Don't allow stack
-// splits, since this function (used by sysAlloc) is called in a lot of low-level
-// parts of the runtime and callers often assume it won't acquire any locks.
-//
-//go:nosplit
-func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
- args := struct {
- addr unsafe.Pointer
- n uintptr
- prot, flags, fd int32
- off uint32
- ret1 unsafe.Pointer
- ret2 int
- }{addr, n, prot, flags, fd, off, nil, 0}
- libcCall(unsafe.Pointer(abi.FuncPCABI0(mmap_trampoline)), unsafe.Pointer(&args))
- return args.ret1, args.ret2
-}
-func mmap_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func munmap(addr unsafe.Pointer, n uintptr) {
- libcCall(unsafe.Pointer(abi.FuncPCABI0(munmap_trampoline)), unsafe.Pointer(&addr))
- KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
-}
-func munmap_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
- libcCall(unsafe.Pointer(abi.FuncPCABI0(madvise_trampoline)), unsafe.Pointer(&addr))
- KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
-}
-func madvise_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func mlock(addr unsafe.Pointer, n uintptr) {
- libcCall(unsafe.Pointer(abi.FuncPCABI0(mlock_trampoline)), unsafe.Pointer(&addr))
- KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
-}
-func mlock_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func read(fd int32, p unsafe.Pointer, n int32) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(read_trampoline)), unsafe.Pointer(&fd))
- KeepAlive(p)
- return ret
-}
-func read_trampoline()
-
-func pipe() (r, w int32, errno int32) {
- var p [2]int32
- errno = libcCall(unsafe.Pointer(abi.FuncPCABI0(pipe_trampoline)), noescape(unsafe.Pointer(&p)))
- return p[0], p[1], errno
-}
-func pipe_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func closefd(fd int32) int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(close_trampoline)), unsafe.Pointer(&fd))
-}
-func close_trampoline()
-
-// This is exported via linkname to assembly in runtime/cgo.
-//
-//go:nosplit
-//go:cgo_unsafe_args
-//go:linkname exit
-func exit(code int32) {
- libcCall(unsafe.Pointer(abi.FuncPCABI0(exit_trampoline)), unsafe.Pointer(&code))
-}
-func exit_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func usleep(usec uint32) {
- libcCall(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec))
-}
-func usleep_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func usleep_no_g(usec uint32) {
- asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec))
-}
-
-//go:nosplit
-//go:cgo_unsafe_args
-func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(write_trampoline)), unsafe.Pointer(&fd))
- KeepAlive(p)
- return ret
-}
-func write_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func open(name *byte, mode, perm int32) (ret int32) {
- ret = libcCall(unsafe.Pointer(abi.FuncPCABI0(open_trampoline)), unsafe.Pointer(&name))
- KeepAlive(name)
- return
-}
-func open_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func nanotime1() int64 {
- var r struct {
- t int64 // raw timer
- numer, denom uint32 // conversion factors. nanoseconds = t * numer / denom.
- }
- libcCall(unsafe.Pointer(abi.FuncPCABI0(nanotime_trampoline)), unsafe.Pointer(&r))
- // Note: Apple seems unconcerned about overflow here. See
- // https://developer.apple.com/library/content/qa/qa1398/_index.html
- // Note also, numer == denom == 1 is common.
- t := r.t
- if r.numer != 1 {
- t *= int64(r.numer)
- }
- if r.denom != 1 {
- t /= int64(r.denom)
- }
- return t
-}
-func nanotime_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func walltime() (int64, int32) {
- var t timespec
- libcCall(unsafe.Pointer(abi.FuncPCABI0(walltime_trampoline)), unsafe.Pointer(&t))
- return t.tv_sec, int32(t.tv_nsec)
-}
-func walltime_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func sigaction(sig uint32, new *usigactiont, old *usigactiont) {
- libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaction_trampoline)), unsafe.Pointer(&sig))
- KeepAlive(new)
- KeepAlive(old)
-}
-func sigaction_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func sigprocmask(how uint32, new *sigset, old *sigset) {
- libcCall(unsafe.Pointer(abi.FuncPCABI0(sigprocmask_trampoline)), unsafe.Pointer(&how))
- KeepAlive(new)
- KeepAlive(old)
-}
-func sigprocmask_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func sigaltstack(new *stackt, old *stackt) {
- if new != nil && new.ss_flags&_SS_DISABLE != 0 && new.ss_size == 0 {
- // Despite the fact that Darwin's sigaltstack man page says it ignores the size
- // when SS_DISABLE is set, it doesn't. sigaltstack returns ENOMEM
- // if we don't give it a reasonable size.
- // ref: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20140421/214296.html
- new.ss_size = 32768
- }
- libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaltstack_trampoline)), unsafe.Pointer(&new))
- KeepAlive(new)
- KeepAlive(old)
-}
-func sigaltstack_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func raiseproc(sig uint32) {
- libcCall(unsafe.Pointer(abi.FuncPCABI0(raiseproc_trampoline)), unsafe.Pointer(&sig))
-}
-func raiseproc_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func setitimer(mode int32, new, old *itimerval) {
- libcCall(unsafe.Pointer(abi.FuncPCABI0(setitimer_trampoline)), unsafe.Pointer(&mode))
- KeepAlive(new)
- KeepAlive(old)
-}
-func setitimer_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func sysctl(mib *uint32, miblen uint32, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctl_trampoline)), unsafe.Pointer(&mib))
- KeepAlive(mib)
- KeepAlive(oldp)
- KeepAlive(oldlenp)
- KeepAlive(newp)
- return ret
-}
-func sysctl_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func sysctlbyname(name *byte, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctlbyname_trampoline)), unsafe.Pointer(&name))
- KeepAlive(name)
- KeepAlive(oldp)
- KeepAlive(oldlenp)
- KeepAlive(newp)
- return ret
-}
-func sysctlbyname_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
- args := struct {
- fd, cmd, arg int32
- ret, errno int32
- }{fd, cmd, arg, 0, 0}
- libcCall(unsafe.Pointer(abi.FuncPCABI0(fcntl_trampoline)), unsafe.Pointer(&args))
- return args.ret, args.errno
-}
-func fcntl_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func kqueue() int32 {
- v := libcCall(unsafe.Pointer(abi.FuncPCABI0(kqueue_trampoline)), nil)
- return v
-}
-func kqueue_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(kevent_trampoline)), unsafe.Pointer(&kq))
- KeepAlive(ch)
- KeepAlive(ev)
- KeepAlive(ts)
- return ret
-}
-func kevent_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_mutex_init(m *pthreadmutex, attr *pthreadmutexattr) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_init_trampoline)), unsafe.Pointer(&m))
- KeepAlive(m)
- KeepAlive(attr)
- return ret
-}
-func pthread_mutex_init_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_mutex_lock(m *pthreadmutex) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_lock_trampoline)), unsafe.Pointer(&m))
- KeepAlive(m)
- return ret
-}
-func pthread_mutex_lock_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_mutex_unlock(m *pthreadmutex) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_unlock_trampoline)), unsafe.Pointer(&m))
- KeepAlive(m)
- return ret
-}
-func pthread_mutex_unlock_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_cond_init(c *pthreadcond, attr *pthreadcondattr) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_init_trampoline)), unsafe.Pointer(&c))
- KeepAlive(c)
- KeepAlive(attr)
- return ret
-}
-func pthread_cond_init_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_cond_wait(c *pthreadcond, m *pthreadmutex) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_wait_trampoline)), unsafe.Pointer(&c))
- KeepAlive(c)
- KeepAlive(m)
- return ret
-}
-func pthread_cond_wait_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_cond_timedwait_relative_np(c *pthreadcond, m *pthreadmutex, t *timespec) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_timedwait_relative_np_trampoline)), unsafe.Pointer(&c))
- KeepAlive(c)
- KeepAlive(m)
- KeepAlive(t)
- return ret
-}
-func pthread_cond_timedwait_relative_np_trampoline()
-
-//go:nosplit
-//go:cgo_unsafe_args
-func pthread_cond_signal(c *pthreadcond) int32 {
- ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_signal_trampoline)), unsafe.Pointer(&c))
- KeepAlive(c)
- return ret
-}
-func pthread_cond_signal_trampoline()
-
-// Not used on Darwin, but must be defined.
-func exitThread(wait *atomic.Uint32) {
- throw("exitThread")
-}
-
-//go:nosplit
-func closeonexec(fd int32) {
- fcntl(fd, _F_SETFD, _FD_CLOEXEC)
-}
-
-//go:nosplit
-func setNonblock(fd int32) {
- flags, _ := fcntl(fd, _F_GETFL, 0)
- if flags != -1 {
- fcntl(fd, _F_SETFL, flags|_O_NONBLOCK)
- }
-}
-
-func issetugid() int32 {
- return libcCall(unsafe.Pointer(abi.FuncPCABI0(issetugid_trampoline)), nil)
-}
-func issetugid_trampoline()
-
-// Tell the linker that the libc_* functions are to be found
-// in a system library, with the libc_ prefix missing.
-
-//go:cgo_import_dynamic libc_pthread_attr_init pthread_attr_init "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_attr_getstacksize pthread_attr_getstacksize "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_attr_setdetachstate pthread_attr_setdetachstate "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_create pthread_create "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_self pthread_self "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_kill pthread_kill "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_exit _exit "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_raise raise "/usr/lib/libSystem.B.dylib"
-
-//go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib"
-
-//go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_error __error "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_usleep usleep "/usr/lib/libSystem.B.dylib"
-
-//go:cgo_import_dynamic libc_mach_timebase_info mach_timebase_info "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_mach_absolute_time mach_absolute_time "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_sigaction sigaction "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_sigmask pthread_sigmask "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_sigaltstack sigaltstack "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_setitimer setitimer "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_sysctlbyname sysctlbyname "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib"
-
-//go:cgo_import_dynamic libc_pthread_mutex_init pthread_mutex_init "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_mutex_lock pthread_mutex_lock "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_mutex_unlock pthread_mutex_unlock "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_cond_init pthread_cond_init "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_cond_wait pthread_cond_wait "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_cond_timedwait_relative_np pthread_cond_timedwait_relative_np "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_pthread_cond_signal pthread_cond_signal "/usr/lib/libSystem.B.dylib"
-
-//go:cgo_import_dynamic libc_notify_is_valid_token notify_is_valid_token "/usr/lib/libSystem.B.dylib"
-//go:cgo_import_dynamic libc_xpc_date_create_from_current xpc_date_create_from_current "/usr/lib/libSystem.B.dylib"
-
-//go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib"
diff --git a/contrib/go/_std_1.20/src/runtime/sys_darwin_amd64.s b/contrib/go/_std_1.20/src/runtime/sys_darwin_amd64.s
deleted file mode 100644
index de7ecdfc95..0000000000
--- a/contrib/go/_std_1.20/src/runtime/sys_darwin_amd64.s
+++ /dev/null
@@ -1,952 +0,0 @@
-// Copyright 2009 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.
-
-// System calls and other sys.stuff for AMD64, Darwin
-// System calls are implemented in libSystem, this file contains
-// trampolines that convert from Go to C calling convention.
-
-#include "go_asm.h"
-#include "go_tls.h"
-#include "textflag.h"
-#include "cgo/abi_amd64.h"
-
-#define CLOCK_REALTIME 0
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVL 0(DI), DI // arg 1 exit status
- CALL libc_exit(SB)
- MOVL $0xf1, 0xf1 // crash
- POPQ BP
- RET
-
-TEXT runtime·open_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVL 8(DI), SI // arg 2 flags
- MOVL 12(DI), DX // arg 3 mode
- MOVQ 0(DI), DI // arg 1 pathname
- XORL AX, AX // vararg: say "no float args"
- CALL libc_open(SB)
- POPQ BP
- RET
-
-TEXT runtime·close_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVL 0(DI), DI // arg 1 fd
- CALL libc_close(SB)
- POPQ BP
- RET
-
-TEXT runtime·read_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 buf
- MOVL 16(DI), DX // arg 3 count
- MOVL 0(DI), DI // arg 1 fd
- CALL libc_read(SB)
- TESTL AX, AX
- JGE noerr
- CALL libc_error(SB)
- MOVL (AX), AX
- NEGL AX // caller expects negative errno value
-noerr:
- POPQ BP
- RET
-
-TEXT runtime·write_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 buf
- MOVL 16(DI), DX // arg 3 count
- MOVQ 0(DI), DI // arg 1 fd
- CALL libc_write(SB)
- TESTL AX, AX
- JGE noerr
- CALL libc_error(SB)
- MOVL (AX), AX
- NEGL AX // caller expects negative errno value
-noerr:
- POPQ BP
- RET
-
-TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- CALL libc_pipe(SB) // pointer already in DI
- TESTL AX, AX
- JEQ 3(PC)
- CALL libc_error(SB) // return negative errno value
- NEGL AX
- POPQ BP
- RET
-
-TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 new
- MOVQ 16(DI), DX // arg 3 old
- MOVL 0(DI), DI // arg 1 which
- CALL libc_setitimer(SB)
- POPQ BP
- RET
-
-TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 len
- MOVL 16(DI), DX // arg 3 advice
- MOVQ 0(DI), DI // arg 1 addr
- CALL libc_madvise(SB)
- // ignore failure - maybe pages are locked
- POPQ BP
- RET
-
-TEXT runtime·mlock_trampoline(SB), NOSPLIT, $0
- UNDEF // unimplemented
-
-GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
-
-TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ DI, BX
- CALL libc_mach_absolute_time(SB)
- MOVQ AX, 0(BX)
- MOVL timebase<>+machTimebaseInfo_numer(SB), SI
- MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
- TESTL DI, DI
- JNE initialized
-
- SUBQ $(machTimebaseInfo__size+15)/16*16, SP
- MOVQ SP, DI
- CALL libc_mach_timebase_info(SB)
- MOVL machTimebaseInfo_numer(SP), SI
- MOVL machTimebaseInfo_denom(SP), DI
- ADDQ $(machTimebaseInfo__size+15)/16*16, SP
-
- MOVL SI, timebase<>+machTimebaseInfo_numer(SB)
- MOVL DI, AX
- XCHGL AX, timebase<>+machTimebaseInfo_denom(SB) // atomic write
-
-initialized:
- MOVL SI, 8(BX)
- MOVL DI, 12(BX)
- MOVQ BP, SP
- POPQ BP
- RET
-
-TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0
- PUSHQ BP // make a frame; keep stack aligned
- MOVQ SP, BP
- MOVQ DI, SI // arg 2 timespec
- MOVL $CLOCK_REALTIME, DI // arg 1 clock_id
- CALL libc_clock_gettime(SB)
- POPQ BP
- RET
-
-TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 new
- MOVQ 16(DI), DX // arg 3 old
- MOVL 0(DI), DI // arg 1 sig
- CALL libc_sigaction(SB)
- TESTL AX, AX
- JEQ 2(PC)
- MOVL $0xf1, 0xf1 // crash
- POPQ BP
- RET
-
-TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 new
- MOVQ 16(DI), DX // arg 3 old
- MOVL 0(DI), DI // arg 1 how
- CALL libc_pthread_sigmask(SB)
- TESTL AX, AX
- JEQ 2(PC)
- MOVL $0xf1, 0xf1 // crash
- POPQ BP
- RET
-
-TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 old
- MOVQ 0(DI), DI // arg 1 new
- CALL libc_sigaltstack(SB)
- TESTQ AX, AX
- JEQ 2(PC)
- MOVL $0xf1, 0xf1 // crash
- POPQ BP
- RET
-
-TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVL 0(DI), BX // signal
- CALL libc_getpid(SB)
- MOVL AX, DI // arg 1 pid
- MOVL BX, SI // arg 2 signal
- CALL libc_kill(SB)
- POPQ BP
- RET
-
-TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
- MOVQ fn+0(FP), AX
- MOVL sig+8(FP), DI
- MOVQ info+16(FP), SI
- MOVQ ctx+24(FP), DX
- PUSHQ BP
- MOVQ SP, BP
- ANDQ $~15, SP // alignment for x86_64 ABI
- CALL AX
- MOVQ BP, SP
- POPQ BP
- RET
-
-// This is the function registered during sigaction and is invoked when
-// a signal is received. It just redirects to the Go function sigtrampgo.
-// Called using C ABI.
-TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$0
- // Transition from C ABI to Go ABI.
- PUSH_REGS_HOST_TO_ABI0()
-
- // Set up ABIInternal environment: g in R14, cleared X15.
- get_tls(R12)
- MOVQ g(R12), R14
- PXOR X15, X15
-
- // Reserve space for spill slots.
- NOP SP // disable vet stack checking
- ADJSP $24
-
- // Call into the Go signal handler
- MOVQ DI, AX // sig
- MOVQ SI, BX // info
- MOVQ DX, CX // ctx
- CALL ·sigtrampgo<ABIInternal>(SB)
-
- ADJSP $-24
-
- POP_REGS_HOST_TO_ABI0()
- RET
-
-// Called using C ABI.
-TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
- // Transition from C ABI to Go ABI.
- PUSH_REGS_HOST_TO_ABI0()
-
- // Call into the Go signal handler
- NOP SP // disable vet stack checking
- ADJSP $24
- MOVL DI, 0(SP) // sig
- MOVQ SI, 8(SP) // info
- MOVQ DX, 16(SP) // ctx
- CALL ·sigprofNonGo(SB)
- ADJSP $-24
-
- POP_REGS_HOST_TO_ABI0()
- RET
-
-// Used instead of sigtramp in programs that use cgo.
-// Arguments from kernel are in DI, SI, DX.
-TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
- // If no traceback function, do usual sigtramp.
- MOVQ runtime·cgoTraceback(SB), AX
- TESTQ AX, AX
- JZ sigtramp
-
- // If no traceback support function, which means that
- // runtime/cgo was not linked in, do usual sigtramp.
- MOVQ _cgo_callers(SB), AX
- TESTQ AX, AX
- JZ sigtramp
-
- // Figure out if we are currently in a cgo call.
- // If not, just do usual sigtramp.
- get_tls(CX)
- MOVQ g(CX),AX
- TESTQ AX, AX
- JZ sigtrampnog // g == nil
- MOVQ g_m(AX), AX
- TESTQ AX, AX
- JZ sigtramp // g.m == nil
- MOVL m_ncgo(AX), CX
- TESTL CX, CX
- JZ sigtramp // g.m.ncgo == 0
- MOVQ m_curg(AX), CX
- TESTQ CX, CX
- JZ sigtramp // g.m.curg == nil
- MOVQ g_syscallsp(CX), CX
- TESTQ CX, CX
- JZ sigtramp // g.m.curg.syscallsp == 0
- MOVQ m_cgoCallers(AX), R8
- TESTQ R8, R8
- JZ sigtramp // g.m.cgoCallers == nil
- MOVL m_cgoCallersUse(AX), CX
- TESTL CX, CX
- JNZ sigtramp // g.m.cgoCallersUse != 0
-
- // Jump to a function in runtime/cgo.
- // That function, written in C, will call the user's traceback
- // function with proper unwind info, and will then call back here.
- // The first three arguments, and the fifth, are already in registers.
- // Set the two remaining arguments now.
- MOVQ runtime·cgoTraceback(SB), CX
- MOVQ $runtime·sigtramp(SB), R9
- MOVQ _cgo_callers(SB), AX
- JMP AX
-
-sigtramp:
- JMP runtime·sigtramp(SB)
-
-sigtrampnog:
- // Signal arrived on a non-Go thread. If this is SIGPROF, get a
- // stack trace.
- CMPL DI, $27 // 27 == SIGPROF
- JNZ sigtramp
-
- // Lock sigprofCallersUse.
- MOVL $0, AX
- MOVL $1, CX
- MOVQ $runtime·sigprofCallersUse(SB), R11
- LOCK
- CMPXCHGL CX, 0(R11)
- JNZ sigtramp // Skip stack trace if already locked.
-
- // Jump to the traceback function in runtime/cgo.
- // It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
- // the arguments to the Go calling convention.
- // First three arguments to traceback function are in registers already.
- MOVQ runtime·cgoTraceback(SB), CX
- MOVQ $runtime·sigprofCallers(SB), R8
- MOVQ $runtime·sigprofNonGoWrapper<>(SB), R9
- MOVQ _cgo_callers(SB), AX
- JMP AX
-
-TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
- PUSHQ BP // make a frame; keep stack aligned
- MOVQ SP, BP
- MOVQ DI, BX
- MOVQ 0(BX), DI // arg 1 addr
- MOVQ 8(BX), SI // arg 2 len
- MOVL 16(BX), DX // arg 3 prot
- MOVL 20(BX), CX // arg 4 flags
- MOVL 24(BX), R8 // arg 5 fid
- MOVL 28(BX), R9 // arg 6 offset
- CALL libc_mmap(SB)
- XORL DX, DX
- CMPQ AX, $-1
- JNE ok
- CALL libc_error(SB)
- MOVLQSX (AX), DX // errno
- XORL AX, AX
-ok:
- MOVQ AX, 32(BX)
- MOVQ DX, 40(BX)
- POPQ BP
- RET
-
-TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 len
- MOVQ 0(DI), DI // arg 1 addr
- CALL libc_munmap(SB)
- TESTQ AX, AX
- JEQ 2(PC)
- MOVL $0xf1, 0xf1 // crash
- POPQ BP
- RET
-
-TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVL 0(DI), DI // arg 1 usec
- CALL libc_usleep(SB)
- POPQ BP
- RET
-
-TEXT runtime·settls(SB),NOSPLIT,$32
- // Nothing to do on Darwin, pthread already set thread-local storage up.
- RET
-
-TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVL 8(DI), SI // arg 2 miblen
- MOVQ 16(DI), DX // arg 3 oldp
- MOVQ 24(DI), CX // arg 4 oldlenp
- MOVQ 32(DI), R8 // arg 5 newp
- MOVQ 40(DI), R9 // arg 6 newlen
- MOVQ 0(DI), DI // arg 1 mib
- CALL libc_sysctl(SB)
- POPQ BP
- RET
-
-TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 oldp
- MOVQ 16(DI), DX // arg 3 oldlenp
- MOVQ 24(DI), CX // arg 4 newp
- MOVQ 32(DI), R8 // arg 5 newlen
- MOVQ 0(DI), DI // arg 1 name
- CALL libc_sysctlbyname(SB)
- POPQ BP
- RET
-
-TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- CALL libc_kqueue(SB)
- POPQ BP
- RET
-
-TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 keventt
- MOVL 16(DI), DX // arg 3 nch
- MOVQ 24(DI), CX // arg 4 ev
- MOVL 32(DI), R8 // arg 5 nev
- MOVQ 40(DI), R9 // arg 6 ts
- MOVL 0(DI), DI // arg 1 kq
- CALL libc_kevent(SB)
- CMPL AX, $-1
- JNE ok
- CALL libc_error(SB)
- MOVLQSX (AX), AX // errno
- NEGQ AX // caller wants it as a negative error code
-ok:
- POPQ BP
- RET
-
-TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ DI, BX
- MOVL 0(BX), DI // arg 1 fd
- MOVL 4(BX), SI // arg 2 cmd
- MOVL 8(BX), DX // arg 3 arg
- XORL AX, AX // vararg: say "no float args"
- CALL libc_fcntl(SB)
- XORL DX, DX
- CMPQ AX, $-1
- JNE noerr
- CALL libc_error(SB)
- MOVL (AX), DX
- MOVL $-1, AX
-noerr:
- MOVL AX, 12(BX)
- MOVL DX, 16(BX)
- POPQ BP
- RET
-
-// mstart_stub is the first function executed on a new thread started by pthread_create.
-// It just does some low-level setup and then calls mstart.
-// Note: called with the C calling convention.
-TEXT runtime·mstart_stub(SB),NOSPLIT,$0
- // DI points to the m.
- // We are already on m's g0 stack.
-
- // Transition from C ABI to Go ABI.
- PUSH_REGS_HOST_TO_ABI0()
-
- MOVQ m_g0(DI), DX // g
-
- // Initialize TLS entry.
- // See cmd/link/internal/ld/sym.go:computeTLSOffset.
- MOVQ DX, 0x30(GS)
-
- CALL runtime·mstart(SB)
-
- POP_REGS_HOST_TO_ABI0()
-
- // Go is all done with this OS thread.
- // Tell pthread everything is ok (we never join with this thread, so
- // the value here doesn't really matter).
- XORL AX, AX
- RET
-
-// These trampolines help convert from Go calling convention to C calling convention.
-// They should be called with asmcgocall.
-// A pointer to the arguments is passed in DI.
-// A single int32 result is returned in AX.
-// (For more results, make an args/results structure.)
-TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
- PUSHQ BP // make frame, keep stack 16-byte aligned.
- MOVQ SP, BP
- MOVQ 0(DI), DI // arg 1 attr
- CALL libc_pthread_attr_init(SB)
- POPQ BP
- RET
-
-TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 size
- MOVQ 0(DI), DI // arg 1 attr
- CALL libc_pthread_attr_getstacksize(SB)
- POPQ BP
- RET
-
-TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 state
- MOVQ 0(DI), DI // arg 1 attr
- CALL libc_pthread_attr_setdetachstate(SB)
- POPQ BP
- RET
-
-TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- SUBQ $16, SP
- MOVQ 0(DI), SI // arg 2 attr
- MOVQ 8(DI), DX // arg 3 start
- MOVQ 16(DI), CX // arg 4 arg
- MOVQ SP, DI // arg 1 &threadid (which we throw away)
- CALL libc_pthread_create(SB)
- MOVQ BP, SP
- POPQ BP
- RET
-
-TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVL 0(DI), DI // arg 1 signal
- CALL libc_raise(SB)
- POPQ BP
- RET
-
-TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 attr
- MOVQ 0(DI), DI // arg 1 mutex
- CALL libc_pthread_mutex_init(SB)
- POPQ BP
- RET
-
-TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 0(DI), DI // arg 1 mutex
- CALL libc_pthread_mutex_lock(SB)
- POPQ BP
- RET
-
-TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 0(DI), DI // arg 1 mutex
- CALL libc_pthread_mutex_unlock(SB)
- POPQ BP
- RET
-
-TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 attr
- MOVQ 0(DI), DI // arg 1 cond
- CALL libc_pthread_cond_init(SB)
- POPQ BP
- RET
-
-TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 mutex
- MOVQ 0(DI), DI // arg 1 cond
- CALL libc_pthread_cond_wait(SB)
- POPQ BP
- RET
-
-TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 mutex
- MOVQ 16(DI), DX // arg 3 timeout
- MOVQ 0(DI), DI // arg 1 cond
- CALL libc_pthread_cond_timedwait_relative_np(SB)
- POPQ BP
- RET
-
-TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 0(DI), DI // arg 1 cond
- CALL libc_pthread_cond_signal(SB)
- POPQ BP
- RET
-
-TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ DI, BX // BX is caller-save
- CALL libc_pthread_self(SB)
- MOVQ AX, 0(BX) // return value
- POPQ BP
- RET
-
-TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ 8(DI), SI // arg 2 sig
- MOVQ 0(DI), DI // arg 1 thread
- CALL libc_pthread_kill(SB)
- POPQ BP
- RET
-
-TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- MOVQ $0, DI // arg 1 val
- CALL libc_notify_is_valid_token(SB)
- CALL libc_xpc_date_create_from_current(SB)
- POPQ BP
- RET
-
-// syscall calls a function in libc on behalf of the syscall package.
-// syscall takes a pointer to a struct like:
-// struct {
-// fn uintptr
-// a1 uintptr
-// a2 uintptr
-// a3 uintptr
-// r1 uintptr
-// r2 uintptr
-// err uintptr
-// }
-// syscall must be called on the g0 stack with the
-// C calling convention (use libcCall).
-//
-// syscall expects a 32-bit result and tests for 32-bit -1
-// to decide there was an error.
-TEXT runtime·syscall(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- SUBQ $16, SP
- MOVQ (0*8)(DI), CX // fn
- MOVQ (2*8)(DI), SI // a2
- MOVQ (3*8)(DI), DX // a3
- MOVQ DI, (SP)
- MOVQ (1*8)(DI), DI // a1
- XORL AX, AX // vararg: say "no float args"
-
- CALL CX
-
- MOVQ (SP), DI
- MOVQ AX, (4*8)(DI) // r1
- MOVQ DX, (5*8)(DI) // r2
-
- // Standard libc functions return -1 on error
- // and set errno.
- CMPL AX, $-1 // Note: high 32 bits are junk
- JNE ok
-
- // Get error code from libc.
- CALL libc_error(SB)
- MOVLQSX (AX), AX
- MOVQ (SP), DI
- MOVQ AX, (6*8)(DI) // err
-
-ok:
- XORL AX, AX // no error (it's ignored anyway)
- MOVQ BP, SP
- POPQ BP
- RET
-
-// syscallX calls a function in libc on behalf of the syscall package.
-// syscallX takes a pointer to a struct like:
-// struct {
-// fn uintptr
-// a1 uintptr
-// a2 uintptr
-// a3 uintptr
-// r1 uintptr
-// r2 uintptr
-// err uintptr
-// }
-// syscallX must be called on the g0 stack with the
-// C calling convention (use libcCall).
-//
-// syscallX is like syscall but expects a 64-bit result
-// and tests for 64-bit -1 to decide there was an error.
-TEXT runtime·syscallX(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- SUBQ $16, SP
- MOVQ (0*8)(DI), CX // fn
- MOVQ (2*8)(DI), SI // a2
- MOVQ (3*8)(DI), DX // a3
- MOVQ DI, (SP)
- MOVQ (1*8)(DI), DI // a1
- XORL AX, AX // vararg: say "no float args"
-
- CALL CX
-
- MOVQ (SP), DI
- MOVQ AX, (4*8)(DI) // r1
- MOVQ DX, (5*8)(DI) // r2
-
- // Standard libc functions return -1 on error
- // and set errno.
- CMPQ AX, $-1
- JNE ok
-
- // Get error code from libc.
- CALL libc_error(SB)
- MOVLQSX (AX), AX
- MOVQ (SP), DI
- MOVQ AX, (6*8)(DI) // err
-
-ok:
- XORL AX, AX // no error (it's ignored anyway)
- MOVQ BP, SP
- POPQ BP
- RET
-
-// syscallPtr is like syscallX except that the libc function reports an
-// error by returning NULL and setting errno.
-TEXT runtime·syscallPtr(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- SUBQ $16, SP
- MOVQ (0*8)(DI), CX // fn
- MOVQ (2*8)(DI), SI // a2
- MOVQ (3*8)(DI), DX // a3
- MOVQ DI, (SP)
- MOVQ (1*8)(DI), DI // a1
- XORL AX, AX // vararg: say "no float args"
-
- CALL CX
-
- MOVQ (SP), DI
- MOVQ AX, (4*8)(DI) // r1
- MOVQ DX, (5*8)(DI) // r2
-
- // syscallPtr libc functions return NULL on error
- // and set errno.
- TESTQ AX, AX
- JNE ok
-
- // Get error code from libc.
- CALL libc_error(SB)
- MOVLQSX (AX), AX
- MOVQ (SP), DI
- MOVQ AX, (6*8)(DI) // err
-
-ok:
- XORL AX, AX // no error (it's ignored anyway)
- MOVQ BP, SP
- POPQ BP
- RET
-
-// syscall6 calls a function in libc on behalf of the syscall package.
-// syscall6 takes a pointer to a struct like:
-// struct {
-// fn uintptr
-// a1 uintptr
-// a2 uintptr
-// a3 uintptr
-// a4 uintptr
-// a5 uintptr
-// a6 uintptr
-// r1 uintptr
-// r2 uintptr
-// err uintptr
-// }
-// syscall6 must be called on the g0 stack with the
-// C calling convention (use libcCall).
-//
-// syscall6 expects a 32-bit result and tests for 32-bit -1
-// to decide there was an error.
-TEXT runtime·syscall6(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- SUBQ $16, SP
- MOVQ (0*8)(DI), R11// fn
- MOVQ (2*8)(DI), SI // a2
- MOVQ (3*8)(DI), DX // a3
- MOVQ (4*8)(DI), CX // a4
- MOVQ (5*8)(DI), R8 // a5
- MOVQ (6*8)(DI), R9 // a6
- MOVQ DI, (SP)
- MOVQ (1*8)(DI), DI // a1
- XORL AX, AX // vararg: say "no float args"
-
- CALL R11
-
- MOVQ (SP), DI
- MOVQ AX, (7*8)(DI) // r1
- MOVQ DX, (8*8)(DI) // r2
-
- CMPL AX, $-1
- JNE ok
-
- CALL libc_error(SB)
- MOVLQSX (AX), AX
- MOVQ (SP), DI
- MOVQ AX, (9*8)(DI) // err
-
-ok:
- XORL AX, AX // no error (it's ignored anyway)
- MOVQ BP, SP
- POPQ BP
- RET
-
-// syscall6X calls a function in libc on behalf of the syscall package.
-// syscall6X takes a pointer to a struct like:
-// struct {
-// fn uintptr
-// a1 uintptr
-// a2 uintptr
-// a3 uintptr
-// a4 uintptr
-// a5 uintptr
-// a6 uintptr
-// r1 uintptr
-// r2 uintptr
-// err uintptr
-// }
-// syscall6X must be called on the g0 stack with the
-// C calling convention (use libcCall).
-//
-// syscall6X is like syscall6 but expects a 64-bit result
-// and tests for 64-bit -1 to decide there was an error.
-TEXT runtime·syscall6X(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- SUBQ $16, SP
- MOVQ (0*8)(DI), R11// fn
- MOVQ (2*8)(DI), SI // a2
- MOVQ (3*8)(DI), DX // a3
- MOVQ (4*8)(DI), CX // a4
- MOVQ (5*8)(DI), R8 // a5
- MOVQ (6*8)(DI), R9 // a6
- MOVQ DI, (SP)
- MOVQ (1*8)(DI), DI // a1
- XORL AX, AX // vararg: say "no float args"
-
- CALL R11
-
- MOVQ (SP), DI
- MOVQ AX, (7*8)(DI) // r1
- MOVQ DX, (8*8)(DI) // r2
-
- CMPQ AX, $-1
- JNE ok
-
- CALL libc_error(SB)
- MOVLQSX (AX), AX
- MOVQ (SP), DI
- MOVQ AX, (9*8)(DI) // err
-
-ok:
- XORL AX, AX // no error (it's ignored anyway)
- MOVQ BP, SP
- POPQ BP
- RET
-
-// syscall9 calls a function in libc on behalf of the syscall package.
-// syscall9 takes a pointer to a struct like:
-// struct {
-// fn uintptr
-// a1 uintptr
-// a2 uintptr
-// a3 uintptr
-// a4 uintptr
-// a5 uintptr
-// a6 uintptr
-// a7 uintptr
-// a8 uintptr
-// a9 uintptr
-// r1 uintptr
-// r2 uintptr
-// err uintptr
-// }
-// syscall9 must be called on the g0 stack with the
-// C calling convention (use libcCall).
-//
-// syscall9 expects a 32-bit result and tests for 32-bit -1
-// to decide there was an error.
-TEXT runtime·syscall9(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- SUBQ $16, SP
- MOVQ (0*8)(DI), R13// fn
- MOVQ (2*8)(DI), SI // a2
- MOVQ (3*8)(DI), DX // a3
- MOVQ (4*8)(DI), CX // a4
- MOVQ (5*8)(DI), R8 // a5
- MOVQ (6*8)(DI), R9 // a6
- MOVQ (7*8)(DI), R10 // a7
- MOVQ (8*8)(DI), R11 // a8
- MOVQ (9*8)(DI), R12 // a9
- MOVQ DI, (SP)
- MOVQ (1*8)(DI), DI // a1
- XORL AX, AX // vararg: say "no float args"
-
- CALL R13
-
- MOVQ (SP), DI
- MOVQ AX, (10*8)(DI) // r1
- MOVQ DX, (11*8)(DI) // r2
-
- CMPL AX, $-1
- JNE ok
-
- CALL libc_error(SB)
- MOVLQSX (AX), AX
- MOVQ (SP), DI
- MOVQ AX, (12*8)(DI) // err
-
-ok:
- XORL AX, AX // no error (it's ignored anyway)
- MOVQ BP, SP
- POPQ BP
- RET
-
-// syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
-// takes 5 uintptrs and 1 float64, and only returns one value,
-// for use with standard C ABI functions.
-TEXT runtime·syscall_x509(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- SUBQ $16, SP
- MOVQ (0*8)(DI), R11// fn
- MOVQ (2*8)(DI), SI // a2
- MOVQ (3*8)(DI), DX // a3
- MOVQ (4*8)(DI), CX // a4
- MOVQ (5*8)(DI), R8 // a5
- MOVQ (6*8)(DI), X0 // f1
- MOVQ DI, (SP)
- MOVQ (1*8)(DI), DI // a1
- XORL AX, AX // vararg: say "no float args"
-
- CALL R11
-
- MOVQ (SP), DI
- MOVQ AX, (7*8)(DI) // r1
-
- XORL AX, AX // no error (it's ignored anyway)
- MOVQ BP, SP
- POPQ BP
- RET
-
-TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0
- PUSHQ BP
- MOVQ SP, BP
- CALL libc_issetugid(SB)
- POPQ BP
- RET
diff --git a/contrib/go/_std_1.20/src/runtime/sys_linux_amd64.s b/contrib/go/_std_1.20/src/runtime/sys_linux_amd64.s
deleted file mode 100644
index c7a89ba536..0000000000
--- a/contrib/go/_std_1.20/src/runtime/sys_linux_amd64.s
+++ /dev/null
@@ -1,703 +0,0 @@
-// Copyright 2009 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.
-
-//
-// System calls and other sys.stuff for AMD64, Linux
-//
-
-#include "go_asm.h"
-#include "go_tls.h"
-#include "textflag.h"
-#include "cgo/abi_amd64.h"
-
-#define AT_FDCWD -100
-
-#define SYS_read 0
-#define SYS_write 1
-#define SYS_close 3
-#define SYS_mmap 9
-#define SYS_munmap 11
-#define SYS_brk 12
-#define SYS_rt_sigaction 13
-#define SYS_rt_sigprocmask 14
-#define SYS_rt_sigreturn 15
-#define SYS_sched_yield 24
-#define SYS_mincore 27
-#define SYS_madvise 28
-#define SYS_nanosleep 35
-#define SYS_setittimer 38
-#define SYS_getpid 39
-#define SYS_socket 41
-#define SYS_connect 42
-#define SYS_clone 56
-#define SYS_exit 60
-#define SYS_kill 62
-#define SYS_sigaltstack 131
-#define SYS_arch_prctl 158
-#define SYS_gettid 186
-#define SYS_futex 202
-#define SYS_sched_getaffinity 204
-#define SYS_timer_create 222
-#define SYS_timer_settime 223
-#define SYS_timer_delete 226
-#define SYS_clock_gettime 228
-#define SYS_exit_group 231
-#define SYS_tgkill 234
-#define SYS_openat 257
-#define SYS_faccessat 269
-#define SYS_pipe2 293
-
-TEXT runtime·exit(SB),NOSPLIT,$0-4
- MOVL code+0(FP), DI
- MOVL $SYS_exit_group, AX
- SYSCALL
- RET
-
-// func exitThread(wait *atomic.Uint32)
-TEXT runtime·exitThread(SB),NOSPLIT,$0-8
- MOVQ wait+0(FP), AX
- // We're done using the stack.
- MOVL $0, (AX)
- MOVL $0, DI // exit code
- MOVL $SYS_exit, AX
- SYSCALL
- // We may not even have a stack any more.
- INT $3
- JMP 0(PC)
-
-TEXT runtime·open(SB),NOSPLIT,$0-20
- // This uses openat instead of open, because Android O blocks open.
- MOVL $AT_FDCWD, DI // AT_FDCWD, so this acts like open
- MOVQ name+0(FP), SI
- MOVL mode+8(FP), DX
- MOVL perm+12(FP), R10
- MOVL $SYS_openat, AX
- SYSCALL
- CMPQ AX, $0xfffffffffffff001
- JLS 2(PC)
- MOVL $-1, AX
- MOVL AX, ret+16(FP)
- RET
-
-TEXT runtime·closefd(SB),NOSPLIT,$0-12
- MOVL fd+0(FP), DI
- MOVL $SYS_close, AX
- SYSCALL
- CMPQ AX, $0xfffffffffffff001
- JLS 2(PC)
- MOVL $-1, AX
- MOVL AX, ret+8(FP)
- RET
-
-TEXT runtime·write1(SB),NOSPLIT,$0-28
- MOVQ fd+0(FP), DI
- MOVQ p+8(FP), SI
- MOVL n+16(FP), DX
- MOVL $SYS_write, AX
- SYSCALL
- MOVL AX, ret+24(FP)
- RET
-
-TEXT runtime·read(SB),NOSPLIT,$0-28
- MOVL fd+0(FP), DI
- MOVQ p+8(FP), SI
- MOVL n+16(FP), DX
- MOVL $SYS_read, AX
- SYSCALL
- MOVL AX, ret+24(FP)
- RET
-
-// func pipe2(flags int32) (r, w int32, errno int32)
-TEXT runtime·pipe2(SB),NOSPLIT,$0-20
- LEAQ r+8(FP), DI
- MOVL flags+0(FP), SI
- MOVL $SYS_pipe2, AX
- SYSCALL
- MOVL AX, errno+16(FP)
- RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$16
- MOVL $0, DX
- MOVL usec+0(FP), AX
- MOVL $1000000, CX
- DIVL CX
- MOVQ AX, 0(SP)
- MOVL $1000, AX // usec to nsec
- MULL DX
- MOVQ AX, 8(SP)
-
- // nanosleep(&ts, 0)
- MOVQ SP, DI
- MOVL $0, SI
- MOVL $SYS_nanosleep, AX
- SYSCALL
- RET
-
-TEXT runtime·gettid(SB),NOSPLIT,$0-4
- MOVL $SYS_gettid, AX
- SYSCALL
- MOVL AX, ret+0(FP)
- RET
-
-TEXT runtime·raise(SB),NOSPLIT,$0
- MOVL $SYS_getpid, AX
- SYSCALL
- MOVL AX, R12
- MOVL $SYS_gettid, AX
- SYSCALL
- MOVL AX, SI // arg 2 tid
- MOVL R12, DI // arg 1 pid
- MOVL sig+0(FP), DX // arg 3
- MOVL $SYS_tgkill, AX
- SYSCALL
- RET
-
-TEXT runtime·raiseproc(SB),NOSPLIT,$0
- MOVL $SYS_getpid, AX
- SYSCALL
- MOVL AX, DI // arg 1 pid
- MOVL sig+0(FP), SI // arg 2
- MOVL $SYS_kill, AX
- SYSCALL
- RET
-
-TEXT ·getpid(SB),NOSPLIT,$0-8
- MOVL $SYS_getpid, AX
- SYSCALL
- MOVQ AX, ret+0(FP)
- RET
-
-TEXT ·tgkill(SB),NOSPLIT,$0
- MOVQ tgid+0(FP), DI
- MOVQ tid+8(FP), SI
- MOVQ sig+16(FP), DX
- MOVL $SYS_tgkill, AX
- SYSCALL
- RET
-
-TEXT runtime·setitimer(SB),NOSPLIT,$0-24
- MOVL mode+0(FP), DI
- MOVQ new+8(FP), SI
- MOVQ old+16(FP), DX
- MOVL $SYS_setittimer, AX
- SYSCALL
- RET
-
-TEXT runtime·timer_create(SB),NOSPLIT,$0-28
- MOVL clockid+0(FP), DI
- MOVQ sevp+8(FP), SI
- MOVQ timerid+16(FP), DX
- MOVL $SYS_timer_create, AX
- SYSCALL
- MOVL AX, ret+24(FP)
- RET
-
-TEXT runtime·timer_settime(SB),NOSPLIT,$0-28
- MOVL timerid+0(FP), DI
- MOVL flags+4(FP), SI
- MOVQ new+8(FP), DX
- MOVQ old+16(FP), R10
- MOVL $SYS_timer_settime, AX
- SYSCALL
- MOVL AX, ret+24(FP)
- RET
-
-TEXT runtime·timer_delete(SB),NOSPLIT,$0-12
- MOVL timerid+0(FP), DI
- MOVL $SYS_timer_delete, AX
- SYSCALL
- MOVL AX, ret+8(FP)
- RET
-
-TEXT runtime·mincore(SB),NOSPLIT,$0-28
- MOVQ addr+0(FP), DI
- MOVQ n+8(FP), SI
- MOVQ dst+16(FP), DX
- MOVL $SYS_mincore, AX
- SYSCALL
- MOVL AX, ret+24(FP)
- RET
-
-// func nanotime1() int64
-TEXT runtime·nanotime1(SB),NOSPLIT,$16-8
- // We don't know how much stack space the VDSO code will need,
- // so switch to g0.
- // In particular, a kernel configured with CONFIG_OPTIMIZE_INLINING=n
- // and hardening can use a full page of stack space in gettime_sym
- // due to stack probes inserted to avoid stack/heap collisions.
- // See issue #20427.
-
- MOVQ SP, R12 // Save old SP; R12 unchanged by C code.
-
- MOVQ g_m(R14), BX // BX unchanged by C code.
-
- // Set vdsoPC and vdsoSP for SIGPROF traceback.
- // Save the old values on stack and restore them on exit,
- // so this function is reentrant.
- MOVQ m_vdsoPC(BX), CX
- MOVQ m_vdsoSP(BX), DX
- MOVQ CX, 0(SP)
- MOVQ DX, 8(SP)
-
- LEAQ ret+0(FP), DX
- MOVQ -8(DX), CX
- MOVQ CX, m_vdsoPC(BX)
- MOVQ DX, m_vdsoSP(BX)
-
- CMPQ R14, m_curg(BX) // Only switch if on curg.
- JNE noswitch
-
- MOVQ m_g0(BX), DX
- MOVQ (g_sched+gobuf_sp)(DX), SP // Set SP to g0 stack
-
-noswitch:
- SUBQ $16, SP // Space for results
- ANDQ $~15, SP // Align for C code
-
- MOVL $1, DI // CLOCK_MONOTONIC
- LEAQ 0(SP), SI
- MOVQ runtime·vdsoClockgettimeSym(SB), AX
- CMPQ AX, $0
- JEQ fallback
- CALL AX
-ret:
- MOVQ 0(SP), AX // sec
- MOVQ 8(SP), DX // nsec
- MOVQ R12, SP // Restore real SP
- // Restore vdsoPC, vdsoSP
- // We don't worry about being signaled between the two stores.
- // If we are not in a signal handler, we'll restore vdsoSP to 0,
- // and no one will care about vdsoPC. If we are in a signal handler,
- // we cannot receive another signal.
- MOVQ 8(SP), CX
- MOVQ CX, m_vdsoSP(BX)
- MOVQ 0(SP), CX
- MOVQ CX, m_vdsoPC(BX)
- // sec is in AX, nsec in DX
- // return nsec in AX
- IMULQ $1000000000, AX
- ADDQ DX, AX
- MOVQ AX, ret+0(FP)
- RET
-fallback:
- MOVQ $SYS_clock_gettime, AX
- SYSCALL
- JMP ret
-
-TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-28
- MOVL how+0(FP), DI
- MOVQ new+8(FP), SI
- MOVQ old+16(FP), DX
- MOVL size+24(FP), R10
- MOVL $SYS_rt_sigprocmask, AX
- SYSCALL
- CMPQ AX, $0xfffffffffffff001
- JLS 2(PC)
- MOVL $0xf1, 0xf1 // crash
- RET
-
-TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-36
- MOVQ sig+0(FP), DI
- MOVQ new+8(FP), SI
- MOVQ old+16(FP), DX
- MOVQ size+24(FP), R10
- MOVL $SYS_rt_sigaction, AX
- SYSCALL
- MOVL AX, ret+32(FP)
- RET
-
-// Call the function stored in _cgo_sigaction using the GCC calling convention.
-TEXT runtime·callCgoSigaction(SB),NOSPLIT,$16
- MOVQ sig+0(FP), DI
- MOVQ new+8(FP), SI
- MOVQ old+16(FP), DX
- MOVQ _cgo_sigaction(SB), AX
- MOVQ SP, BX // callee-saved
- ANDQ $~15, SP // alignment as per amd64 psABI
- CALL AX
- MOVQ BX, SP
- MOVL AX, ret+24(FP)
- RET
-
-TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
- MOVQ fn+0(FP), AX
- MOVL sig+8(FP), DI
- MOVQ info+16(FP), SI
- MOVQ ctx+24(FP), DX
- PUSHQ BP
- MOVQ SP, BP
- ANDQ $~15, SP // alignment for x86_64 ABI
- CALL AX
- MOVQ BP, SP
- POPQ BP
- RET
-
-// Called using C ABI.
-TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$0
- // Transition from C ABI to Go ABI.
- PUSH_REGS_HOST_TO_ABI0()
-
- // Set up ABIInternal environment: g in R14, cleared X15.
- get_tls(R12)
- MOVQ g(R12), R14
- PXOR X15, X15
-
- // Reserve space for spill slots.
- NOP SP // disable vet stack checking
- ADJSP $24
-
- // Call into the Go signal handler
- MOVQ DI, AX // sig
- MOVQ SI, BX // info
- MOVQ DX, CX // ctx
- CALL ·sigtrampgo<ABIInternal>(SB)
-
- ADJSP $-24
-
- POP_REGS_HOST_TO_ABI0()
- RET
-
-// Called using C ABI.
-TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0
- // Transition from C ABI to Go ABI.
- PUSH_REGS_HOST_TO_ABI0()
-
- // Set up ABIInternal environment: g in R14, cleared X15.
- get_tls(R12)
- MOVQ g(R12), R14
- PXOR X15, X15
-
- // Reserve space for spill slots.
- NOP SP // disable vet stack checking
- ADJSP $24
-
- // Call into the Go signal handler
- MOVQ DI, AX // sig
- MOVQ SI, BX // info
- MOVQ DX, CX // ctx
- CALL ·sigprofNonGo<ABIInternal>(SB)
-
- ADJSP $-24
-
- POP_REGS_HOST_TO_ABI0()
- RET
-
-// Used instead of sigtramp in programs that use cgo.
-// Arguments from kernel are in DI, SI, DX.
-TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
- // If no traceback function, do usual sigtramp.
- MOVQ runtime·cgoTraceback(SB), AX
- TESTQ AX, AX
- JZ sigtramp
-
- // If no traceback support function, which means that
- // runtime/cgo was not linked in, do usual sigtramp.
- MOVQ _cgo_callers(SB), AX
- TESTQ AX, AX
- JZ sigtramp
-
- // Figure out if we are currently in a cgo call.
- // If not, just do usual sigtramp.
- get_tls(CX)
- MOVQ g(CX),AX
- TESTQ AX, AX
- JZ sigtrampnog // g == nil
- MOVQ g_m(AX), AX
- TESTQ AX, AX
- JZ sigtramp // g.m == nil
- MOVL m_ncgo(AX), CX
- TESTL CX, CX
- JZ sigtramp // g.m.ncgo == 0
- MOVQ m_curg(AX), CX
- TESTQ CX, CX
- JZ sigtramp // g.m.curg == nil
- MOVQ g_syscallsp(CX), CX
- TESTQ CX, CX
- JZ sigtramp // g.m.curg.syscallsp == 0
- MOVQ m_cgoCallers(AX), R8
- TESTQ R8, R8
- JZ sigtramp // g.m.cgoCallers == nil
- MOVL m_cgoCallersUse(AX), CX
- TESTL CX, CX
- JNZ sigtramp // g.m.cgoCallersUse != 0
-
- // Jump to a function in runtime/cgo.
- // That function, written in C, will call the user's traceback
- // function with proper unwind info, and will then call back here.
- // The first three arguments, and the fifth, are already in registers.
- // Set the two remaining arguments now.
- MOVQ runtime·cgoTraceback(SB), CX
- MOVQ $runtime·sigtramp(SB), R9
- MOVQ _cgo_callers(SB), AX
- JMP AX
-
-sigtramp:
- JMP runtime·sigtramp(SB)
-
-sigtrampnog:
- // Signal arrived on a non-Go thread. If this is SIGPROF, get a
- // stack trace.
- CMPL DI, $27 // 27 == SIGPROF
- JNZ sigtramp
-
- // Lock sigprofCallersUse.
- MOVL $0, AX
- MOVL $1, CX
- MOVQ $runtime·sigprofCallersUse(SB), R11
- LOCK
- CMPXCHGL CX, 0(R11)
- JNZ sigtramp // Skip stack trace if already locked.
-
- // Jump to the traceback function in runtime/cgo.
- // It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
- // the arguments to the Go calling convention.
- // First three arguments to traceback function are in registers already.
- MOVQ runtime·cgoTraceback(SB), CX
- MOVQ $runtime·sigprofCallers(SB), R8
- MOVQ $runtime·sigprofNonGoWrapper<>(SB), R9
- MOVQ _cgo_callers(SB), AX
- JMP AX
-
-// For cgo unwinding to work, this function must look precisely like
-// the one in glibc. The glibc source code is:
-// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86_64/sigaction.c
-// The code that cares about the precise instructions used is:
-// https://gcc.gnu.org/viewcvs/gcc/trunk/libgcc/config/i386/linux-unwind.h?revision=219188&view=markup
-TEXT runtime·sigreturn(SB),NOSPLIT,$0
- MOVQ $SYS_rt_sigreturn, AX
- SYSCALL
- INT $3 // not reached
-
-TEXT runtime·sysMmap(SB),NOSPLIT,$0
- MOVQ addr+0(FP), DI
- MOVQ n+8(FP), SI
- MOVL prot+16(FP), DX
- MOVL flags+20(FP), R10
- MOVL fd+24(FP), R8
- MOVL off+28(FP), R9
-
- MOVL $SYS_mmap, AX
- SYSCALL
- CMPQ AX, $0xfffffffffffff001
- JLS ok
- NOTQ AX
- INCQ AX
- MOVQ $0, p+32(FP)
- MOVQ AX, err+40(FP)
- RET
-ok:
- MOVQ AX, p+32(FP)
- MOVQ $0, err+40(FP)
- RET
-
-// Call the function stored in _cgo_mmap using the GCC calling convention.
-// This must be called on the system stack.
-TEXT runtime·callCgoMmap(SB),NOSPLIT,$16
- MOVQ addr+0(FP), DI
- MOVQ n+8(FP), SI
- MOVL prot+16(FP), DX
- MOVL flags+20(FP), CX
- MOVL fd+24(FP), R8
- MOVL off+28(FP), R9
- MOVQ _cgo_mmap(SB), AX
- MOVQ SP, BX
- ANDQ $~15, SP // alignment as per amd64 psABI
- MOVQ BX, 0(SP)
- CALL AX
- MOVQ 0(SP), SP
- MOVQ AX, ret+32(FP)
- RET
-
-TEXT runtime·sysMunmap(SB),NOSPLIT,$0
- MOVQ addr+0(FP), DI
- MOVQ n+8(FP), SI
- MOVQ $SYS_munmap, AX
- SYSCALL
- CMPQ AX, $0xfffffffffffff001
- JLS 2(PC)
- MOVL $0xf1, 0xf1 // crash
- RET
-
-// Call the function stored in _cgo_munmap using the GCC calling convention.
-// This must be called on the system stack.
-TEXT runtime·callCgoMunmap(SB),NOSPLIT,$16-16
- MOVQ addr+0(FP), DI
- MOVQ n+8(FP), SI
- MOVQ _cgo_munmap(SB), AX
- MOVQ SP, BX
- ANDQ $~15, SP // alignment as per amd64 psABI
- MOVQ BX, 0(SP)
- CALL AX
- MOVQ 0(SP), SP
- RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$0
- MOVQ addr+0(FP), DI
- MOVQ n+8(FP), SI
- MOVL flags+16(FP), DX
- MOVQ $SYS_madvise, AX
- SYSCALL
- MOVL AX, ret+24(FP)
- RET
-
-// int64 futex(int32 *uaddr, int32 op, int32 val,
-// struct timespec *timeout, int32 *uaddr2, int32 val2);
-TEXT runtime·futex(SB),NOSPLIT,$0
- MOVQ addr+0(FP), DI
- MOVL op+8(FP), SI
- MOVL val+12(FP), DX
- MOVQ ts+16(FP), R10
- MOVQ addr2+24(FP), R8
- MOVL val3+32(FP), R9
- MOVL $SYS_futex, AX
- SYSCALL
- MOVL AX, ret+40(FP)
- RET
-
-// int32 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
-TEXT runtime·clone(SB),NOSPLIT,$0
- MOVL flags+0(FP), DI
- MOVQ stk+8(FP), SI
- MOVQ $0, DX
- MOVQ $0, R10
- MOVQ $0, R8
- // Copy mp, gp, fn off parent stack for use by child.
- // Careful: Linux system call clobbers CX and R11.
- MOVQ mp+16(FP), R13
- MOVQ gp+24(FP), R9
- MOVQ fn+32(FP), R12
- CMPQ R13, $0 // m
- JEQ nog1
- CMPQ R9, $0 // g
- JEQ nog1
- LEAQ m_tls(R13), R8
-#ifdef GOOS_android
- // Android stores the TLS offset in runtime·tls_g.
- SUBQ runtime·tls_g(SB), R8
-#else
- ADDQ $8, R8 // ELF wants to use -8(FS)
-#endif
- ORQ $0x00080000, DI //add flag CLONE_SETTLS(0x00080000) to call clone
-nog1:
- MOVL $SYS_clone, AX
- SYSCALL
-
- // In parent, return.
- CMPQ AX, $0
- JEQ 3(PC)
- MOVL AX, ret+40(FP)
- RET
-
- // In child, on new stack.
- MOVQ SI, SP
-
- // If g or m are nil, skip Go-related setup.
- CMPQ R13, $0 // m
- JEQ nog2
- CMPQ R9, $0 // g
- JEQ nog2
-
- // Initialize m->procid to Linux tid
- MOVL $SYS_gettid, AX
- SYSCALL
- MOVQ AX, m_procid(R13)
-
- // In child, set up new stack
- get_tls(CX)
- MOVQ R13, g_m(R9)
- MOVQ R9, g(CX)
- MOVQ R9, R14 // set g register
- CALL runtime·stackcheck(SB)
-
-nog2:
- // Call fn. This is the PC of an ABI0 function.
- CALL R12
-
- // It shouldn't return. If it does, exit that thread.
- MOVL $111, DI
- MOVL $SYS_exit, AX
- SYSCALL
- JMP -3(PC) // keep exiting
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
- MOVQ new+0(FP), DI
- MOVQ old+8(FP), SI
- MOVQ $SYS_sigaltstack, AX
- SYSCALL
- CMPQ AX, $0xfffffffffffff001
- JLS 2(PC)
- MOVL $0xf1, 0xf1 // crash
- RET
-
-// set tls base to DI
-TEXT runtime·settls(SB),NOSPLIT,$32
-#ifdef GOOS_android
- // Android stores the TLS offset in runtime·tls_g.
- SUBQ runtime·tls_g(SB), DI
-#else
- ADDQ $8, DI // ELF wants to use -8(FS)
-#endif
- MOVQ DI, SI
- MOVQ $0x1002, DI // ARCH_SET_FS
- MOVQ $SYS_arch_prctl, AX
- SYSCALL
- CMPQ AX, $0xfffffffffffff001
- JLS 2(PC)
- MOVL $0xf1, 0xf1 // crash
- RET
-
-TEXT runtime·osyield(SB),NOSPLIT,$0
- MOVL $SYS_sched_yield, AX
- SYSCALL
- RET
-
-TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
- MOVQ pid+0(FP), DI
- MOVQ len+8(FP), SI
- MOVQ buf+16(FP), DX
- MOVL $SYS_sched_getaffinity, AX
- SYSCALL
- MOVL AX, ret+24(FP)
- RET
-
-// int access(const char *name, int mode)
-TEXT runtime·access(SB),NOSPLIT,$0
- // This uses faccessat instead of access, because Android O blocks access.
- MOVL $AT_FDCWD, DI // AT_FDCWD, so this acts like access
- MOVQ name+0(FP), SI
- MOVL mode+8(FP), DX
- MOVL $0, R10
- MOVL $SYS_faccessat, AX
- SYSCALL
- MOVL AX, ret+16(FP)
- RET
-
-// int connect(int fd, const struct sockaddr *addr, socklen_t addrlen)
-TEXT runtime·connect(SB),NOSPLIT,$0-28
- MOVL fd+0(FP), DI
- MOVQ addr+8(FP), SI
- MOVL len+16(FP), DX
- MOVL $SYS_connect, AX
- SYSCALL
- MOVL AX, ret+24(FP)
- RET
-
-// int socket(int domain, int type, int protocol)
-TEXT runtime·socket(SB),NOSPLIT,$0-20
- MOVL domain+0(FP), DI
- MOVL typ+4(FP), SI
- MOVL prot+8(FP), DX
- MOVL $SYS_socket, AX
- SYSCALL
- MOVL AX, ret+16(FP)
- RET
-
-// func sbrk0() uintptr
-TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
- // Implemented as brk(NULL).
- MOVQ $0, DI
- MOVL $SYS_brk, AX
- SYSCALL
- MOVQ AX, ret+0(FP)
- RET
diff --git a/contrib/go/_std_1.20/src/runtime/sys_linux_arm64.s b/contrib/go/_std_1.20/src/runtime/sys_linux_arm64.s
deleted file mode 100644
index 38ff6ac330..0000000000
--- a/contrib/go/_std_1.20/src/runtime/sys_linux_arm64.s
+++ /dev/null
@@ -1,801 +0,0 @@
-// Copyright 2014 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.
-
-//
-// System calls and other sys.stuff for arm64, Linux
-//
-
-#include "go_asm.h"
-#include "go_tls.h"
-#include "textflag.h"
-#include "cgo/abi_arm64.h"
-
-#define AT_FDCWD -100
-
-#define CLOCK_REALTIME 0
-#define CLOCK_MONOTONIC 1
-
-#define SYS_exit 93
-#define SYS_read 63
-#define SYS_write 64
-#define SYS_openat 56
-#define SYS_close 57
-#define SYS_pipe2 59
-#define SYS_nanosleep 101
-#define SYS_mmap 222
-#define SYS_munmap 215
-#define SYS_setitimer 103
-#define SYS_clone 220
-#define SYS_sched_yield 124
-#define SYS_rt_sigreturn 139
-#define SYS_rt_sigaction 134
-#define SYS_rt_sigprocmask 135
-#define SYS_sigaltstack 132
-#define SYS_madvise 233
-#define SYS_mincore 232
-#define SYS_getpid 172
-#define SYS_gettid 178
-#define SYS_kill 129
-#define SYS_tgkill 131
-#define SYS_futex 98
-#define SYS_sched_getaffinity 123
-#define SYS_exit_group 94
-#define SYS_clock_gettime 113
-#define SYS_faccessat 48
-#define SYS_socket 198
-#define SYS_connect 203
-#define SYS_brk 214
-#define SYS_timer_create 107
-#define SYS_timer_settime 110
-#define SYS_timer_delete 111
-
-TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
- MOVW code+0(FP), R0
- MOVD $SYS_exit_group, R8
- SVC
- RET
-
-// func exitThread(wait *atomic.Uint32)
-TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
- MOVD wait+0(FP), R0
- // We're done using the stack.
- MOVW $0, R1
- STLRW R1, (R0)
- MOVW $0, R0 // exit code
- MOVD $SYS_exit, R8
- SVC
- JMP 0(PC)
-
-TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
- MOVD $AT_FDCWD, R0
- MOVD name+0(FP), R1
- MOVW mode+8(FP), R2
- MOVW perm+12(FP), R3
- MOVD $SYS_openat, R8
- SVC
- CMN $4095, R0
- BCC done
- MOVW $-1, R0
-done:
- MOVW R0, ret+16(FP)
- RET
-
-TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
- MOVW fd+0(FP), R0
- MOVD $SYS_close, R8
- SVC
- CMN $4095, R0
- BCC done
- MOVW $-1, R0
-done:
- MOVW R0, ret+8(FP)
- RET
-
-TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
- MOVD fd+0(FP), R0
- MOVD p+8(FP), R1
- MOVW n+16(FP), R2
- MOVD $SYS_write, R8
- SVC
- MOVW R0, ret+24(FP)
- RET
-
-TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
- MOVW fd+0(FP), R0
- MOVD p+8(FP), R1
- MOVW n+16(FP), R2
- MOVD $SYS_read, R8
- SVC
- MOVW R0, ret+24(FP)
- RET
-
-// func pipe2(flags int32) (r, w int32, errno int32)
-TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
- MOVD $r+8(FP), R0
- MOVW flags+0(FP), R1
- MOVW $SYS_pipe2, R8
- SVC
- MOVW R0, errno+16(FP)
- RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$24-4
- MOVWU usec+0(FP), R3
- MOVD R3, R5
- MOVW $1000000, R4
- UDIV R4, R3
- MOVD R3, 8(RSP)
- MUL R3, R4
- SUB R4, R5
- MOVW $1000, R4
- MUL R4, R5
- MOVD R5, 16(RSP)
-
- // nanosleep(&ts, 0)
- ADD $8, RSP, R0
- MOVD $0, R1
- MOVD $SYS_nanosleep, R8
- SVC
- RET
-
-TEXT runtime·gettid(SB),NOSPLIT,$0-4
- MOVD $SYS_gettid, R8
- SVC
- MOVW R0, ret+0(FP)
- RET
-
-TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
- MOVD $SYS_getpid, R8
- SVC
- MOVW R0, R19
- MOVD $SYS_gettid, R8
- SVC
- MOVW R0, R1 // arg 2 tid
- MOVW R19, R0 // arg 1 pid
- MOVW sig+0(FP), R2 // arg 3
- MOVD $SYS_tgkill, R8
- SVC
- RET
-
-TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
- MOVD $SYS_getpid, R8
- SVC
- MOVW R0, R0 // arg 1 pid
- MOVW sig+0(FP), R1 // arg 2
- MOVD $SYS_kill, R8
- SVC
- RET
-
-TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
- MOVD $SYS_getpid, R8
- SVC
- MOVD R0, ret+0(FP)
- RET
-
-TEXT ·tgkill(SB),NOSPLIT,$0-24
- MOVD tgid+0(FP), R0
- MOVD tid+8(FP), R1
- MOVD sig+16(FP), R2
- MOVD $SYS_tgkill, R8
- SVC
- RET
-
-TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
- MOVW mode+0(FP), R0
- MOVD new+8(FP), R1
- MOVD old+16(FP), R2
- MOVD $SYS_setitimer, R8
- SVC
- RET
-
-TEXT runtime·timer_create(SB),NOSPLIT,$0-28
- MOVW clockid+0(FP), R0
- MOVD sevp+8(FP), R1
- MOVD timerid+16(FP), R2
- MOVD $SYS_timer_create, R8
- SVC
- MOVW R0, ret+24(FP)
- RET
-
-TEXT runtime·timer_settime(SB),NOSPLIT,$0-28
- MOVW timerid+0(FP), R0
- MOVW flags+4(FP), R1
- MOVD new+8(FP), R2
- MOVD old+16(FP), R3
- MOVD $SYS_timer_settime, R8
- SVC
- MOVW R0, ret+24(FP)
- RET
-
-TEXT runtime·timer_delete(SB),NOSPLIT,$0-12
- MOVW timerid+0(FP), R0
- MOVD $SYS_timer_delete, R8
- SVC
- MOVW R0, ret+8(FP)
- RET
-
-TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
- MOVD addr+0(FP), R0
- MOVD n+8(FP), R1
- MOVD dst+16(FP), R2
- MOVD $SYS_mincore, R8
- SVC
- MOVW R0, ret+24(FP)
- RET
-
-// func walltime() (sec int64, nsec int32)
-TEXT runtime·walltime(SB),NOSPLIT,$24-12
- MOVD RSP, R20 // R20 is unchanged by C code
- MOVD RSP, R1
-
- MOVD g_m(g), R21 // R21 = m
-
- // Set vdsoPC and vdsoSP for SIGPROF traceback.
- // Save the old values on stack and restore them on exit,
- // so this function is reentrant.
- MOVD m_vdsoPC(R21), R2
- MOVD m_vdsoSP(R21), R3
- MOVD R2, 8(RSP)
- MOVD R3, 16(RSP)
-
- MOVD $ret-8(FP), R2 // caller's SP
- MOVD LR, m_vdsoPC(R21)
- MOVD R2, m_vdsoSP(R21)
-
- MOVD m_curg(R21), R0
- CMP g, R0
- BNE noswitch
-
- MOVD m_g0(R21), R3
- MOVD (g_sched+gobuf_sp)(R3), R1 // Set RSP to g0 stack
-
-noswitch:
- SUB $16, R1
- BIC $15, R1 // Align for C code
- MOVD R1, RSP
-
- MOVW $CLOCK_REALTIME, R0
- MOVD runtime·vdsoClockgettimeSym(SB), R2
- CBZ R2, fallback
-
- // Store g on gsignal's stack, so if we receive a signal
- // during VDSO code we can find the g.
- // If we don't have a signal stack, we won't receive signal,
- // so don't bother saving g.
- // When using cgo, we already saved g on TLS, also don't save
- // g here.
- // Also don't save g if we are already on the signal stack.
- // We won't get a nested signal.
- MOVBU runtime·iscgo(SB), R22
- CBNZ R22, nosaveg
- MOVD m_gsignal(R21), R22 // g.m.gsignal
- CBZ R22, nosaveg
- CMP g, R22
- BEQ nosaveg
- MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
- MOVD g, (R22)
-
- BL (R2)
-
- MOVD ZR, (R22) // clear g slot, R22 is unchanged by C code
-
- B finish
-
-nosaveg:
- BL (R2)
- B finish
-
-fallback:
- MOVD $SYS_clock_gettime, R8
- SVC
-
-finish:
- MOVD 0(RSP), R3 // sec
- MOVD 8(RSP), R5 // nsec
-
- MOVD R20, RSP // restore SP
- // Restore vdsoPC, vdsoSP
- // We don't worry about being signaled between the two stores.
- // If we are not in a signal handler, we'll restore vdsoSP to 0,
- // and no one will care about vdsoPC. If we are in a signal handler,
- // we cannot receive another signal.
- MOVD 16(RSP), R1
- MOVD R1, m_vdsoSP(R21)
- MOVD 8(RSP), R1
- MOVD R1, m_vdsoPC(R21)
-
- MOVD R3, sec+0(FP)
- MOVW R5, nsec+8(FP)
- RET
-
-TEXT runtime·nanotime1(SB),NOSPLIT,$24-8
- MOVD RSP, R20 // R20 is unchanged by C code
- MOVD RSP, R1
-
- MOVD g_m(g), R21 // R21 = m
-
- // Set vdsoPC and vdsoSP for SIGPROF traceback.
- // Save the old values on stack and restore them on exit,
- // so this function is reentrant.
- MOVD m_vdsoPC(R21), R2
- MOVD m_vdsoSP(R21), R3
- MOVD R2, 8(RSP)
- MOVD R3, 16(RSP)
-
- MOVD $ret-8(FP), R2 // caller's SP
- MOVD LR, m_vdsoPC(R21)
- MOVD R2, m_vdsoSP(R21)
-
- MOVD m_curg(R21), R0
- CMP g, R0
- BNE noswitch
-
- MOVD m_g0(R21), R3
- MOVD (g_sched+gobuf_sp)(R3), R1 // Set RSP to g0 stack
-
-noswitch:
- SUB $32, R1
- BIC $15, R1
- MOVD R1, RSP
-
- MOVW $CLOCK_MONOTONIC, R0
- MOVD runtime·vdsoClockgettimeSym(SB), R2
- CBZ R2, fallback
-
- // Store g on gsignal's stack, so if we receive a signal
- // during VDSO code we can find the g.
- // If we don't have a signal stack, we won't receive signal,
- // so don't bother saving g.
- // When using cgo, we already saved g on TLS, also don't save
- // g here.
- // Also don't save g if we are already on the signal stack.
- // We won't get a nested signal.
- MOVBU runtime·iscgo(SB), R22
- CBNZ R22, nosaveg
- MOVD m_gsignal(R21), R22 // g.m.gsignal
- CBZ R22, nosaveg
- CMP g, R22
- BEQ nosaveg
- MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
- MOVD g, (R22)
-
- BL (R2)
-
- MOVD ZR, (R22) // clear g slot, R22 is unchanged by C code
-
- B finish
-
-nosaveg:
- BL (R2)
- B finish
-
-fallback:
- MOVD $SYS_clock_gettime, R8
- SVC
-
-finish:
- MOVD 0(RSP), R3 // sec
- MOVD 8(RSP), R5 // nsec
-
- MOVD R20, RSP // restore SP
- // Restore vdsoPC, vdsoSP
- // We don't worry about being signaled between the two stores.
- // If we are not in a signal handler, we'll restore vdsoSP to 0,
- // and no one will care about vdsoPC. If we are in a signal handler,
- // we cannot receive another signal.
- MOVD 16(RSP), R1
- MOVD R1, m_vdsoSP(R21)
- MOVD 8(RSP), R1
- MOVD R1, m_vdsoPC(R21)
-
- // sec is in R3, nsec in R5
- // return nsec in R3
- MOVD $1000000000, R4
- MUL R4, R3
- ADD R5, R3
- MOVD R3, ret+0(FP)
- RET
-
-TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
- MOVW how+0(FP), R0
- MOVD new+8(FP), R1
- MOVD old+16(FP), R2
- MOVW size+24(FP), R3
- MOVD $SYS_rt_sigprocmask, R8
- SVC
- CMN $4095, R0
- BCC done
- MOVD $0, R0
- MOVD R0, (R0) // crash
-done:
- RET
-
-TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
- MOVD sig+0(FP), R0
- MOVD new+8(FP), R1
- MOVD old+16(FP), R2
- MOVD size+24(FP), R3
- MOVD $SYS_rt_sigaction, R8
- SVC
- MOVW R0, ret+32(FP)
- RET
-
-// Call the function stored in _cgo_sigaction using the GCC calling convention.
-TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0
- MOVD sig+0(FP), R0
- MOVD new+8(FP), R1
- MOVD old+16(FP), R2
- MOVD _cgo_sigaction(SB), R3
- SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
- BL R3
- ADD $16, RSP
- MOVW R0, ret+24(FP)
- RET
-
-TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
- MOVW sig+8(FP), R0
- MOVD info+16(FP), R1
- MOVD ctx+24(FP), R2
- MOVD fn+0(FP), R11
- BL (R11)
- RET
-
-// Called from c-abi, R0: sig, R1: info, R2: cxt
-TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$176
- // Save callee-save registers in the case of signal forwarding.
- // Please refer to https://golang.org/issue/31827 .
- SAVE_R19_TO_R28(8*4)
- SAVE_F8_TO_F15(8*14)
-
- // this might be called in external code context,
- // where g is not set.
- // first save R0, because runtime·load_g will clobber it
- MOVW R0, 8(RSP)
- MOVBU runtime·iscgo(SB), R0
- CBZ R0, 2(PC)
- BL runtime·load_g(SB)
-
-#ifdef GOEXPERIMENT_regabiargs
- // Restore signum to R0.
- MOVW 8(RSP), R0
- // R1 and R2 already contain info and ctx, respectively.
-#else
- MOVD R1, 16(RSP)
- MOVD R2, 24(RSP)
-#endif
- MOVD $runtime·sigtrampgo<ABIInternal>(SB), R3
- BL (R3)
-
- // Restore callee-save registers.
- RESTORE_R19_TO_R28(8*4)
- RESTORE_F8_TO_F15(8*14)
-
- RET
-
-// Called from c-abi, R0: sig, R1: info, R2: cxt
-TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$176
- // Save callee-save registers because it's a callback from c code.
- SAVE_R19_TO_R28(8*4)
- SAVE_F8_TO_F15(8*14)
-
-#ifdef GOEXPERIMENT_regabiargs
- // R0, R1 and R2 already contain sig, info and ctx, respectively.
-#else
- MOVW R0, 8(RSP) // sig
- MOVD R1, 16(RSP) // info
- MOVD R2, 24(RSP) // ctx
-#endif
- CALL runtime·sigprofNonGo<ABIInternal>(SB)
-
- // Restore callee-save registers.
- RESTORE_R19_TO_R28(8*4)
- RESTORE_F8_TO_F15(8*14)
- RET
-
-// Called from c-abi, R0: sig, R1: info, R2: cxt
-TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
- // The stack unwinder, presumably written in C, may not be able to
- // handle Go frame correctly. So, this function is NOFRAME, and we
- // save/restore LR manually.
- MOVD LR, R10
- // Save R27, g because they will be clobbered,
- // we need to restore them before jump to sigtramp.
- MOVD R27, R11
- MOVD g, R12
-
- // If no traceback function, do usual sigtramp.
- MOVD runtime·cgoTraceback(SB), R6
- CBZ R6, sigtramp
-
- // If no traceback support function, which means that
- // runtime/cgo was not linked in, do usual sigtramp.
- MOVD _cgo_callers(SB), R7
- CBZ R7, sigtramp
-
- // Figure out if we are currently in a cgo call.
- // If not, just do usual sigtramp.
- // first save R0, because runtime·load_g will clobber it.
- MOVD R0, R8
- // Set up g register.
- CALL runtime·load_g(SB)
- MOVD R8, R0
-
- CBZ g, sigtrampnog // g == nil
- MOVD g_m(g), R6
- CBZ R6, sigtramp // g.m == nil
- MOVW m_ncgo(R6), R7
- CBZW R7, sigtramp // g.m.ncgo = 0
- MOVD m_curg(R6), R8
- CBZ R8, sigtramp // g.m.curg == nil
- MOVD g_syscallsp(R8), R7
- CBZ R7, sigtramp // g.m.curg.syscallsp == 0
- MOVD m_cgoCallers(R6), R4 // R4 is the fifth arg in C calling convention.
- CBZ R4, sigtramp // g.m.cgoCallers == nil
- MOVW m_cgoCallersUse(R6), R8
- CBNZW R8, sigtramp // g.m.cgoCallersUse != 0
-
- // Jump to a function in runtime/cgo.
- // That function, written in C, will call the user's traceback
- // function with proper unwind info, and will then call back here.
- // The first three arguments, and the fifth, are already in registers.
- // Set the two remaining arguments now.
- MOVD runtime·cgoTraceback(SB), R3
- MOVD $runtime·sigtramp(SB), R5
- MOVD _cgo_callers(SB), R13
- MOVD R10, LR // restore
- MOVD R11, R27
- MOVD R12, g
- B (R13)
-
-sigtramp:
- MOVD R10, LR // restore
- MOVD R11, R27
- MOVD R12, g
- B runtime·sigtramp(SB)
-
-sigtrampnog:
- // Signal arrived on a non-Go thread. If this is SIGPROF, get a
- // stack trace.
- CMPW $27, R0 // 27 == SIGPROF
- BNE sigtramp
-
- // Lock sigprofCallersUse (cas from 0 to 1).
- MOVW $1, R7
- MOVD $runtime·sigprofCallersUse(SB), R8
-load_store_loop:
- LDAXRW (R8), R9
- CBNZW R9, sigtramp // Skip stack trace if already locked.
- STLXRW R7, (R8), R9
- CBNZ R9, load_store_loop
-
- // Jump to the traceback function in runtime/cgo.
- // It will call back to sigprofNonGo, which will ignore the
- // arguments passed in registers.
- // First three arguments to traceback function are in registers already.
- MOVD runtime·cgoTraceback(SB), R3
- MOVD $runtime·sigprofCallers(SB), R4
- MOVD $runtime·sigprofNonGoWrapper<>(SB), R5
- MOVD _cgo_callers(SB), R13
- MOVD R10, LR // restore
- MOVD R11, R27
- MOVD R12, g
- B (R13)
-
-TEXT runtime·sysMmap(SB),NOSPLIT|NOFRAME,$0
- MOVD addr+0(FP), R0
- MOVD n+8(FP), R1
- MOVW prot+16(FP), R2
- MOVW flags+20(FP), R3
- MOVW fd+24(FP), R4
- MOVW off+28(FP), R5
-
- MOVD $SYS_mmap, R8
- SVC
- CMN $4095, R0
- BCC ok
- NEG R0,R0
- MOVD $0, p+32(FP)
- MOVD R0, err+40(FP)
- RET
-ok:
- MOVD R0, p+32(FP)
- MOVD $0, err+40(FP)
- RET
-
-// Call the function stored in _cgo_mmap using the GCC calling convention.
-// This must be called on the system stack.
-TEXT runtime·callCgoMmap(SB),NOSPLIT,$0
- MOVD addr+0(FP), R0
- MOVD n+8(FP), R1
- MOVW prot+16(FP), R2
- MOVW flags+20(FP), R3
- MOVW fd+24(FP), R4
- MOVW off+28(FP), R5
- MOVD _cgo_mmap(SB), R9
- SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
- BL R9
- ADD $16, RSP
- MOVD R0, ret+32(FP)
- RET
-
-TEXT runtime·sysMunmap(SB),NOSPLIT|NOFRAME,$0
- MOVD addr+0(FP), R0
- MOVD n+8(FP), R1
- MOVD $SYS_munmap, R8
- SVC
- CMN $4095, R0
- BCC cool
- MOVD R0, 0xf0(R0)
-cool:
- RET
-
-// Call the function stored in _cgo_munmap using the GCC calling convention.
-// This must be called on the system stack.
-TEXT runtime·callCgoMunmap(SB),NOSPLIT,$0
- MOVD addr+0(FP), R0
- MOVD n+8(FP), R1
- MOVD _cgo_munmap(SB), R9
- SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
- BL R9
- ADD $16, RSP
- RET
-
-TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
- MOVD addr+0(FP), R0
- MOVD n+8(FP), R1
- MOVW flags+16(FP), R2
- MOVD $SYS_madvise, R8
- SVC
- MOVW R0, ret+24(FP)
- RET
-
-// int64 futex(int32 *uaddr, int32 op, int32 val,
-// struct timespec *timeout, int32 *uaddr2, int32 val2);
-TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
- MOVD addr+0(FP), R0
- MOVW op+8(FP), R1
- MOVW val+12(FP), R2
- MOVD ts+16(FP), R3
- MOVD addr2+24(FP), R4
- MOVW val3+32(FP), R5
- MOVD $SYS_futex, R8
- SVC
- MOVW R0, ret+40(FP)
- RET
-
-// int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
-TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
- MOVW flags+0(FP), R0
- MOVD stk+8(FP), R1
-
- // Copy mp, gp, fn off parent stack for use by child.
- MOVD mp+16(FP), R10
- MOVD gp+24(FP), R11
- MOVD fn+32(FP), R12
-
- MOVD R10, -8(R1)
- MOVD R11, -16(R1)
- MOVD R12, -24(R1)
- MOVD $1234, R10
- MOVD R10, -32(R1)
-
- MOVD $SYS_clone, R8
- SVC
-
- // In parent, return.
- CMP ZR, R0
- BEQ child
- MOVW R0, ret+40(FP)
- RET
-child:
-
- // In child, on new stack.
- MOVD -32(RSP), R10
- MOVD $1234, R0
- CMP R0, R10
- BEQ good
- MOVD $0, R0
- MOVD R0, (R0) // crash
-
-good:
- // Initialize m->procid to Linux tid
- MOVD $SYS_gettid, R8
- SVC
-
- MOVD -24(RSP), R12 // fn
- MOVD -16(RSP), R11 // g
- MOVD -8(RSP), R10 // m
-
- CMP $0, R10
- BEQ nog
- CMP $0, R11
- BEQ nog
-
- MOVD R0, m_procid(R10)
-
- // TODO: setup TLS.
-
- // In child, set up new stack
- MOVD R10, g_m(R11)
- MOVD R11, g
- //CALL runtime·stackcheck(SB)
-
-nog:
- // Call fn
- MOVD R12, R0
- BL (R0)
-
- // It shouldn't return. If it does, exit that thread.
- MOVW $111, R0
-again:
- MOVD $SYS_exit, R8
- SVC
- B again // keep exiting
-
-TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
- MOVD new+0(FP), R0
- MOVD old+8(FP), R1
- MOVD $SYS_sigaltstack, R8
- SVC
- CMN $4095, R0
- BCC ok
- MOVD $0, R0
- MOVD R0, (R0) // crash
-ok:
- RET
-
-TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
- MOVD $SYS_sched_yield, R8
- SVC
- RET
-
-TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
- MOVD pid+0(FP), R0
- MOVD len+8(FP), R1
- MOVD buf+16(FP), R2
- MOVD $SYS_sched_getaffinity, R8
- SVC
- MOVW R0, ret+24(FP)
- RET
-
-// int access(const char *name, int mode)
-TEXT runtime·access(SB),NOSPLIT,$0-20
- MOVD $AT_FDCWD, R0
- MOVD name+0(FP), R1
- MOVW mode+8(FP), R2
- MOVD $SYS_faccessat, R8
- SVC
- MOVW R0, ret+16(FP)
- RET
-
-// int connect(int fd, const struct sockaddr *addr, socklen_t len)
-TEXT runtime·connect(SB),NOSPLIT,$0-28
- MOVW fd+0(FP), R0
- MOVD addr+8(FP), R1
- MOVW len+16(FP), R2
- MOVD $SYS_connect, R8
- SVC
- MOVW R0, ret+24(FP)
- RET
-
-// int socket(int domain, int typ, int prot)
-TEXT runtime·socket(SB),NOSPLIT,$0-20
- MOVW domain+0(FP), R0
- MOVW typ+4(FP), R1
- MOVW prot+8(FP), R2
- MOVD $SYS_socket, R8
- SVC
- MOVW R0, ret+16(FP)
- RET
-
-// func sbrk0() uintptr
-TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
- // Implemented as brk(NULL).
- MOVD $0, R0
- MOVD $SYS_brk, R8
- SVC
- MOVD R0, ret+0(FP)
- RET
-
-TEXT runtime·sigreturn(SB),NOSPLIT,$0-0
- RET
diff --git a/contrib/go/_std_1.20/src/runtime/sys_windows_amd64.s b/contrib/go/_std_1.20/src/runtime/sys_windows_amd64.s
deleted file mode 100644
index 4027770087..0000000000
--- a/contrib/go/_std_1.20/src/runtime/sys_windows_amd64.s
+++ /dev/null
@@ -1,445 +0,0 @@
-// Copyright 2011 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.
-
-#include "go_asm.h"
-#include "go_tls.h"
-#include "textflag.h"
-#include "time_windows.h"
-#include "cgo/abi_amd64.h"
-
-// Offsets into Thread Environment Block (pointer in GS)
-#define TEB_TlsSlots 0x1480
-#define TEB_ArbitraryPtr 0x28
-
-// void runtime·asmstdcall(void *c);
-TEXT runtime·asmstdcall(SB),NOSPLIT|NOFRAME,$0
- // asmcgocall will put first argument into CX.
- PUSHQ CX // save for later
- MOVQ libcall_fn(CX), AX
- MOVQ libcall_args(CX), SI
- MOVQ libcall_n(CX), CX
-
- // SetLastError(0).
- MOVQ 0x30(GS), DI
- MOVL $0, 0x68(DI)
-
- SUBQ $(const_maxArgs*8), SP // room for args
-
- // Fast version, do not store args on the stack.
- CMPL CX, $4
- JLE loadregs
-
- // Check we have enough room for args.
- CMPL CX, $const_maxArgs
- JLE 2(PC)
- INT $3 // not enough room -> crash
-
- // Copy args to the stack.
- MOVQ SP, DI
- CLD
- REP; MOVSQ
- MOVQ SP, SI
-
-loadregs:
- // Load first 4 args into correspondent registers.
- MOVQ 0(SI), CX
- MOVQ 8(SI), DX
- MOVQ 16(SI), R8
- MOVQ 24(SI), R9
- // Floating point arguments are passed in the XMM
- // registers. Set them here in case any of the arguments
- // are floating point values. For details see
- // https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
- MOVQ CX, X0
- MOVQ DX, X1
- MOVQ R8, X2
- MOVQ R9, X3
-
- // Call stdcall function.
- CALL AX
-
- ADDQ $(const_maxArgs*8), SP
-
- // Return result.
- POPQ CX
- MOVQ AX, libcall_r1(CX)
- // Floating point return values are returned in XMM0. Setting r2 to this
- // value in case this call returned a floating point value. For details,
- // see https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention
- MOVQ X0, libcall_r2(CX)
-
- // GetLastError().
- MOVQ 0x30(GS), DI
- MOVL 0x68(DI), AX
- MOVQ AX, libcall_err(CX)
-
- RET
-
-TEXT runtime·badsignal2(SB),NOSPLIT|NOFRAME,$48
- // stderr
- MOVQ $-12, CX // stderr
- MOVQ CX, 0(SP)
- MOVQ runtime·_GetStdHandle(SB), AX
- CALL AX
-
- MOVQ AX, CX // handle
- MOVQ CX, 0(SP)
- MOVQ $runtime·badsignalmsg(SB), DX // pointer
- MOVQ DX, 8(SP)
- MOVL $runtime·badsignallen(SB), R8 // count
- MOVQ R8, 16(SP)
- LEAQ 40(SP), R9 // written count
- MOVQ $0, 0(R9)
- MOVQ R9, 24(SP)
- MOVQ $0, 32(SP) // overlapped
- MOVQ runtime·_WriteFile(SB), AX
- CALL AX
-
- // Does not return.
- CALL runtime·abort(SB)
- RET
-
-// faster get/set last error
-TEXT runtime·getlasterror(SB),NOSPLIT,$0
- MOVQ 0x30(GS), AX
- MOVL 0x68(AX), AX
- MOVL AX, ret+0(FP)
- RET
-
-// Called by Windows as a Vectored Exception Handler (VEH).
-// First argument is pointer to struct containing
-// exception record and context pointers.
-// Handler function is stored in AX.
-// Return 0 for 'not handled', -1 for handled.
-TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0-0
- // CX: PEXCEPTION_POINTERS ExceptionInfo
-
- // Switch from the host ABI to the Go ABI.
- PUSH_REGS_HOST_TO_ABI0()
- // Make stack space for the rest of the function.
- ADJSP $48
-
- MOVQ CX, R13 // save exception address
- MOVQ AX, R15 // save handler address
-
- // find g
- get_tls(DX)
- CMPQ DX, $0
- JNE 3(PC)
- MOVQ $0, AX // continue
- JMP done
- MOVQ g(DX), DX
- CMPQ DX, $0
- JNE 2(PC)
- CALL runtime·badsignal2(SB)
-
- // save g and SP in case of stack switch
- MOVQ DX, 32(SP) // g
- MOVQ SP, 40(SP)
-
- // do we need to switch to the g0 stack?
- MOVQ g_m(DX), BX
- MOVQ m_g0(BX), BX
- CMPQ DX, BX
- JEQ g0
-
- // switch to g0 stack
- get_tls(BP)
- MOVQ BX, g(BP)
- MOVQ (g_sched+gobuf_sp)(BX), DI
- // make room for sighandler arguments
- // and re-save old SP for restoring later.
- // Adjust g0 stack by the space we're using and
- // save SP at the same place on the g0 stack.
- // The 40(DI) here must match the 40(SP) above.
- SUBQ $(REGS_HOST_TO_ABI0_STACK + 48), DI
- MOVQ SP, 40(DI)
- MOVQ DI, SP
-
-g0:
- MOVQ 0(R13), BX // ExceptionRecord*
- MOVQ 8(R13), CX // Context*
- MOVQ BX, 0(SP)
- MOVQ CX, 8(SP)
- MOVQ DX, 16(SP)
- CALL R15 // call handler
- // AX is set to report result back to Windows
- MOVL 24(SP), AX
-
- MOVQ SP, DI // save g0 SP
-
- // switch back to original stack and g
- // no-op if we never left.
- MOVQ 40(SP), SP
- MOVQ 32(SP), DX
- get_tls(BP)
- MOVQ DX, g(BP)
-
- // if return value is CONTINUE_SEARCH, do not set up control
- // flow guard workaround.
- CMPQ AX, $0
- JEQ done
-
- // Check if we need to set up the control flow guard workaround.
- // On Windows, the stack pointer in the context must lie within
- // system stack limits when we resume from exception.
- // Store the resume SP and PC in alternate registers
- // and return to sigresume on the g0 stack.
- // sigresume makes no use of the stack at all,
- // loading SP from R8 and jumping to R9.
- // Note that smashing R8 and R9 is only safe because we know sigpanic
- // will not actually return to the original frame, so the registers
- // are effectively dead. But this does mean we can't use the
- // same mechanism for async preemption.
- MOVQ 8(R13), CX
- MOVQ $sigresume<>(SB), BX
- CMPQ BX, context_rip(CX)
- JEQ done // do not clobber saved SP/PC
-
- // Save resume SP and PC into R8, R9.
- MOVQ context_rsp(CX), BX
- MOVQ BX, context_r8(CX)
- MOVQ context_rip(CX), BX
- MOVQ BX, context_r9(CX)
-
- // Set up context record to return to sigresume on g0 stack
- MOVD DI, BX
- MOVD BX, context_rsp(CX)
- MOVD $sigresume<>(SB), BX
- MOVD BX, context_rip(CX)
-
-done:
- ADJSP $-48
- POP_REGS_HOST_TO_ABI0()
-
- RET
-
-// Trampoline to resume execution from exception handler.
-// This is part of the control flow guard workaround.
-// It switches stacks and jumps to the continuation address.
-// R8 and R9 are set above at the end of sigtramp<>
-// in the context that starts executing at sigresume<>.
-TEXT sigresume<>(SB),NOSPLIT|NOFRAME,$0
- MOVQ R8, SP
- JMP R9
-
-TEXT runtime·exceptiontramp(SB),NOSPLIT|NOFRAME,$0
- MOVQ $runtime·exceptionhandler(SB), AX
- JMP sigtramp<>(SB)
-
-TEXT runtime·firstcontinuetramp(SB),NOSPLIT|NOFRAME,$0-0
- MOVQ $runtime·firstcontinuehandler(SB), AX
- JMP sigtramp<>(SB)
-
-TEXT runtime·lastcontinuetramp(SB),NOSPLIT|NOFRAME,$0-0
- MOVQ $runtime·lastcontinuehandler(SB), AX
- JMP sigtramp<>(SB)
-
-GLOBL runtime·cbctxts(SB), NOPTR, $8
-
-TEXT runtime·callbackasm1(SB),NOSPLIT,$0
- // Construct args vector for cgocallback().
- // By windows/amd64 calling convention first 4 args are in CX, DX, R8, R9
- // args from the 5th on are on the stack.
- // In any case, even if function has 0,1,2,3,4 args, there is reserved
- // but uninitialized "shadow space" for the first 4 args.
- // The values are in registers.
- MOVQ CX, (16+0)(SP)
- MOVQ DX, (16+8)(SP)
- MOVQ R8, (16+16)(SP)
- MOVQ R9, (16+24)(SP)
- // R8 = address of args vector
- LEAQ (16+0)(SP), R8
-
- // remove return address from stack, we are not returning to callbackasm, but to its caller.
- MOVQ 0(SP), AX
- ADDQ $8, SP
-
- // determine index into runtime·cbs table
- MOVQ $runtime·callbackasm(SB), DX
- SUBQ DX, AX
- MOVQ $0, DX
- MOVQ $5, CX // divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
- DIVL CX
- SUBQ $1, AX // subtract 1 because return PC is to the next slot
-
- // Switch from the host ABI to the Go ABI.
- PUSH_REGS_HOST_TO_ABI0()
-
- // Create a struct callbackArgs on our stack to be passed as
- // the "frame" to cgocallback and on to callbackWrap.
- SUBQ $(24+callbackArgs__size), SP
- MOVQ AX, (24+callbackArgs_index)(SP) // callback index
- MOVQ R8, (24+callbackArgs_args)(SP) // address of args vector
- MOVQ $0, (24+callbackArgs_result)(SP) // result
- LEAQ 24(SP), AX
- // Call cgocallback, which will call callbackWrap(frame).
- MOVQ $0, 16(SP) // context
- MOVQ AX, 8(SP) // frame (address of callbackArgs)
- LEAQ ·callbackWrap<ABIInternal>(SB), BX // cgocallback takes an ABIInternal entry-point
- MOVQ BX, 0(SP) // PC of function value to call (callbackWrap)
- CALL ·cgocallback(SB)
- // Get callback result.
- MOVQ (24+callbackArgs_result)(SP), AX
- ADDQ $(24+callbackArgs__size), SP
-
- POP_REGS_HOST_TO_ABI0()
-
- // The return value was placed in AX above.
- RET
-
-// uint32 tstart_stdcall(M *newm);
-TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
- // Switch from the host ABI to the Go ABI.
- PUSH_REGS_HOST_TO_ABI0()
-
- // CX contains first arg newm
- MOVQ m_g0(CX), DX // g
-
- // Layout new m scheduler stack on os stack.
- MOVQ SP, AX
- MOVQ AX, (g_stack+stack_hi)(DX)
- SUBQ $(64*1024), AX // initial stack size (adjusted later)
- MOVQ AX, (g_stack+stack_lo)(DX)
- ADDQ $const__StackGuard, AX
- MOVQ AX, g_stackguard0(DX)
- MOVQ AX, g_stackguard1(DX)
-
- // Set up tls.
- LEAQ m_tls(CX), DI
- MOVQ CX, g_m(DX)
- MOVQ DX, g(DI)
- CALL runtime·settls(SB) // clobbers CX
-
- CALL runtime·stackcheck(SB) // clobbers AX,CX
- CALL runtime·mstart(SB)
-
- POP_REGS_HOST_TO_ABI0()
-
- XORL AX, AX // return 0 == success
- RET
-
-// set tls base to DI
-TEXT runtime·settls(SB),NOSPLIT,$0
- MOVQ runtime·tls_g(SB), CX
- MOVQ DI, 0(CX)(GS)
- RET
-
-// Runs on OS stack.
-// duration (in -100ns units) is in dt+0(FP).
-// g may be nil.
-// The function leaves room for 4 syscall parameters
-// (as per windows amd64 calling convention).
-TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$48-4
- MOVLQSX dt+0(FP), BX
- MOVQ SP, AX
- ANDQ $~15, SP // alignment as per Windows requirement
- MOVQ AX, 40(SP)
- LEAQ 32(SP), R8 // ptime
- MOVQ BX, (R8)
- MOVQ $-1, CX // handle
- MOVQ $0, DX // alertable
- MOVQ runtime·_NtWaitForSingleObject(SB), AX
- CALL AX
- MOVQ 40(SP), SP
- RET
-
-// Runs on OS stack. duration (in -100ns units) is in dt+0(FP).
-// g is valid.
-TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$72-4
- MOVLQSX dt+0(FP), BX
- get_tls(CX)
-
- MOVQ SP, AX
- ANDQ $~15, SP // alignment as per Windows requirement
- MOVQ AX, 64(SP)
-
- MOVQ g(CX), CX
- MOVQ g_m(CX), CX
- MOVQ (m_mOS+mOS_highResTimer)(CX), CX // hTimer
- MOVQ CX, 48(SP) // save hTimer for later
- LEAQ 56(SP), DX // lpDueTime
- MOVQ BX, (DX)
- MOVQ $0, R8 // lPeriod
- MOVQ $0, R9 // pfnCompletionRoutine
- MOVQ $0, AX
- MOVQ AX, 32(SP) // lpArgToCompletionRoutine
- MOVQ AX, 40(SP) // fResume
- MOVQ runtime·_SetWaitableTimer(SB), AX
- CALL AX
-
- MOVQ 48(SP), CX // handle
- MOVQ $0, DX // alertable
- MOVQ $0, R8 // ptime
- MOVQ runtime·_NtWaitForSingleObject(SB), AX
- CALL AX
-
- MOVQ 64(SP), SP
- RET
-
-// Runs on OS stack.
-TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
- MOVQ SP, AX
- ANDQ $~15, SP // alignment as per Windows requirement
- SUBQ $(48), SP // room for SP and 4 args as per Windows requirement
- // plus one extra word to keep stack 16 bytes aligned
- MOVQ AX, 32(SP)
- MOVQ runtime·_SwitchToThread(SB), AX
- CALL AX
- MOVQ 32(SP), SP
- RET
-
-TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
- CMPB runtime·useQPCTime(SB), $0
- JNE useQPC
- MOVQ $_INTERRUPT_TIME, DI
- MOVQ time_lo(DI), AX
- IMULQ $100, AX
- MOVQ AX, ret+0(FP)
- RET
-useQPC:
- JMP runtime·nanotimeQPC(SB)
- RET
-
-// func osSetupTLS(mp *m)
-// Setup TLS. for use by needm on Windows.
-TEXT runtime·osSetupTLS(SB),NOSPLIT,$0-8
- MOVQ mp+0(FP), AX
- LEAQ m_tls(AX), DI
- CALL runtime·settls(SB)
- RET
-
-// This is called from rt0_go, which runs on the system stack
-// using the initial stack allocated by the OS.
-TEXT runtime·wintls(SB),NOSPLIT|NOFRAME,$0
- // Allocate a TLS slot to hold g across calls to external code
- MOVQ SP, AX
- ANDQ $~15, SP // alignment as per Windows requirement
- SUBQ $48, SP // room for SP and 4 args as per Windows requirement
- // plus one extra word to keep stack 16 bytes aligned
- MOVQ AX, 32(SP)
- MOVQ runtime·_TlsAlloc(SB), AX
- CALL AX
- MOVQ 32(SP), SP
-
- MOVQ AX, CX // TLS index
-
- // Assert that slot is less than 64 so we can use _TEB->TlsSlots
- CMPQ CX, $64
- JB ok
-
- // Fallback to the TEB arbitrary pointer.
- // TODO: don't use the arbitrary pointer (see go.dev/issue/59824)
- MOVQ $TEB_ArbitraryPtr, CX
- JMP settls
-ok:
- // Convert the TLS index at CX into
- // an offset from TEB_TlsSlots.
- SHLQ $3, CX
-
- // Save offset from TLS into tls_g.
- ADDQ $TEB_TlsSlots, CX
-settls:
- MOVQ CX, runtime·tls_g(SB)
- RET
diff --git a/contrib/go/_std_1.20/src/runtime/syscall_windows.go b/contrib/go/_std_1.20/src/runtime/syscall_windows.go
deleted file mode 100644
index 76036ad098..0000000000
--- a/contrib/go/_std_1.20/src/runtime/syscall_windows.go
+++ /dev/null
@@ -1,559 +0,0 @@
-// Copyright 2014 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 runtime
-
-import (
- "internal/abi"
- "internal/goarch"
- "unsafe"
-)
-
-// cbs stores all registered Go callbacks.
-var cbs struct {
- lock mutex // use cbsLock / cbsUnlock for race instrumentation.
- ctxt [cb_max]winCallback
- index map[winCallbackKey]int
- n int
-}
-
-func cbsLock() {
- lock(&cbs.lock)
- // compileCallback is used by goenvs prior to completion of schedinit.
- // raceacquire involves a racecallback to get the proc, which is not
- // safe prior to scheduler initialization. Thus avoid instrumentation
- // until then.
- if raceenabled && mainStarted {
- raceacquire(unsafe.Pointer(&cbs.lock))
- }
-}
-
-func cbsUnlock() {
- if raceenabled && mainStarted {
- racerelease(unsafe.Pointer(&cbs.lock))
- }
- unlock(&cbs.lock)
-}
-
-// winCallback records information about a registered Go callback.
-type winCallback struct {
- fn *funcval // Go function
- retPop uintptr // For 386 cdecl, how many bytes to pop on return
- abiMap abiDesc
-}
-
-// abiPartKind is the action an abiPart should take.
-type abiPartKind int
-
-const (
- abiPartBad abiPartKind = iota
- abiPartStack // Move a value from memory to the stack.
- abiPartReg // Move a value from memory to a register.
-)
-
-// abiPart encodes a step in translating between calling ABIs.
-type abiPart struct {
- kind abiPartKind
- srcStackOffset uintptr
- dstStackOffset uintptr // used if kind == abiPartStack
- dstRegister int // used if kind == abiPartReg
- len uintptr
-}
-
-func (a *abiPart) tryMerge(b abiPart) bool {
- if a.kind != abiPartStack || b.kind != abiPartStack {
- return false
- }
- if a.srcStackOffset+a.len == b.srcStackOffset && a.dstStackOffset+a.len == b.dstStackOffset {
- a.len += b.len
- return true
- }
- return false
-}
-
-// abiDesc specifies how to translate from a C frame to a Go
-// frame. This does not specify how to translate back because
-// the result is always a uintptr. If the C ABI is fastcall,
-// this assumes the four fastcall registers were first spilled
-// to the shadow space.
-type abiDesc struct {
- parts []abiPart
-
- srcStackSize uintptr // stdcall/fastcall stack space tracking
- dstStackSize uintptr // Go stack space used
- dstSpill uintptr // Extra stack space for argument spill slots
- dstRegisters int // Go ABI int argument registers used
-
- // retOffset is the offset of the uintptr-sized result in the Go
- // frame.
- retOffset uintptr
-}
-
-func (p *abiDesc) assignArg(t *_type) {
- if t.size > goarch.PtrSize {
- // We don't support this right now. In
- // stdcall/cdecl, 64-bit ints and doubles are
- // passed as two words (little endian); and
- // structs are pushed on the stack. In
- // fastcall, arguments larger than the word
- // size are passed by reference. On arm,
- // 8-byte aligned arguments round up to the
- // next even register and can be split across
- // registers and the stack.
- panic("compileCallback: argument size is larger than uintptr")
- }
- if k := t.kind & kindMask; GOARCH != "386" && (k == kindFloat32 || k == kindFloat64) {
- // In fastcall, floating-point arguments in
- // the first four positions are passed in
- // floating-point registers, which we don't
- // currently spill. arm passes floating-point
- // arguments in VFP registers, which we also
- // don't support.
- // So basically we only support 386.
- panic("compileCallback: float arguments not supported")
- }
-
- if t.size == 0 {
- // The Go ABI aligns for zero-sized types.
- p.dstStackSize = alignUp(p.dstStackSize, uintptr(t.align))
- return
- }
-
- // In the C ABI, we're already on a word boundary.
- // Also, sub-word-sized fastcall register arguments
- // are stored to the least-significant bytes of the
- // argument word and all supported Windows
- // architectures are little endian, so srcStackOffset
- // is already pointing to the right place for smaller
- // arguments. The same is true on arm.
-
- oldParts := p.parts
- if p.tryRegAssignArg(t, 0) {
- // Account for spill space.
- //
- // TODO(mknyszek): Remove this when we no longer have
- // caller reserved spill space.
- p.dstSpill = alignUp(p.dstSpill, uintptr(t.align))
- p.dstSpill += t.size
- } else {
- // Register assignment failed.
- // Undo the work and stack assign.
- p.parts = oldParts
-
- // The Go ABI aligns arguments.
- p.dstStackSize = alignUp(p.dstStackSize, uintptr(t.align))
-
- // Copy just the size of the argument. Note that this
- // could be a small by-value struct, but C and Go
- // struct layouts are compatible, so we can copy these
- // directly, too.
- part := abiPart{
- kind: abiPartStack,
- srcStackOffset: p.srcStackSize,
- dstStackOffset: p.dstStackSize,
- len: t.size,
- }
- // Add this step to the adapter.
- if len(p.parts) == 0 || !p.parts[len(p.parts)-1].tryMerge(part) {
- p.parts = append(p.parts, part)
- }
- // The Go ABI packs arguments.
- p.dstStackSize += t.size
- }
-
- // cdecl, stdcall, fastcall, and arm pad arguments to word size.
- // TODO(rsc): On arm and arm64 do we need to skip the caller's saved LR?
- p.srcStackSize += goarch.PtrSize
-}
-
-// tryRegAssignArg tries to register-assign a value of type t.
-// If this type is nested in an aggregate type, then offset is the
-// offset of this type within its parent type.
-// Assumes t.size <= goarch.PtrSize and t.size != 0.
-//
-// Returns whether the assignment succeeded.
-func (p *abiDesc) tryRegAssignArg(t *_type, offset uintptr) bool {
- switch k := t.kind & kindMask; k {
- case kindBool, kindInt, kindInt8, kindInt16, kindInt32, kindUint, kindUint8, kindUint16, kindUint32, kindUintptr, kindPtr, kindUnsafePointer:
- // Assign a register for all these types.
- return p.assignReg(t.size, offset)
- case kindInt64, kindUint64:
- // Only register-assign if the registers are big enough.
- if goarch.PtrSize == 8 {
- return p.assignReg(t.size, offset)
- }
- case kindArray:
- at := (*arraytype)(unsafe.Pointer(t))
- if at.len == 1 {
- return p.tryRegAssignArg(at.elem, offset)
- }
- case kindStruct:
- st := (*structtype)(unsafe.Pointer(t))
- for i := range st.fields {
- f := &st.fields[i]
- if !p.tryRegAssignArg(f.typ, offset+f.offset) {
- return false
- }
- }
- return true
- }
- // Pointer-sized types such as maps and channels are currently
- // not supported.
- panic("compileCallabck: type " + t.string() + " is currently not supported for use in system callbacks")
-}
-
-// assignReg attempts to assign a single register for an
-// argument with the given size, at the given offset into the
-// value in the C ABI space.
-//
-// Returns whether the assignment was successful.
-func (p *abiDesc) assignReg(size, offset uintptr) bool {
- if p.dstRegisters >= intArgRegs {
- return false
- }
- p.parts = append(p.parts, abiPart{
- kind: abiPartReg,
- srcStackOffset: p.srcStackSize + offset,
- dstRegister: p.dstRegisters,
- len: size,
- })
- p.dstRegisters++
- return true
-}
-
-type winCallbackKey struct {
- fn *funcval
- cdecl bool
-}
-
-func callbackasm()
-
-// callbackasmAddr returns address of runtime.callbackasm
-// function adjusted by i.
-// On x86 and amd64, runtime.callbackasm is a series of CALL instructions,
-// and we want callback to arrive at
-// correspondent call instruction instead of start of
-// runtime.callbackasm.
-// On ARM, runtime.callbackasm is a series of mov and branch instructions.
-// R12 is loaded with the callback index. Each entry is two instructions,
-// hence 8 bytes.
-func callbackasmAddr(i int) uintptr {
- var entrySize int
- switch GOARCH {
- default:
- panic("unsupported architecture")
- case "386", "amd64":
- entrySize = 5
- case "arm", "arm64":
- // On ARM and ARM64, each entry is a MOV instruction
- // followed by a branch instruction
- entrySize = 8
- }
- return abi.FuncPCABI0(callbackasm) + uintptr(i*entrySize)
-}
-
-const callbackMaxFrame = 64 * goarch.PtrSize
-
-// compileCallback converts a Go function fn into a C function pointer
-// that can be passed to Windows APIs.
-//
-// On 386, if cdecl is true, the returned C function will use the
-// cdecl calling convention; otherwise, it will use stdcall. On amd64,
-// it always uses fastcall. On arm, it always uses the ARM convention.
-//
-//go:linkname compileCallback syscall.compileCallback
-func compileCallback(fn eface, cdecl bool) (code uintptr) {
- if GOARCH != "386" {
- // cdecl is only meaningful on 386.
- cdecl = false
- }
-
- if fn._type == nil || (fn._type.kind&kindMask) != kindFunc {
- panic("compileCallback: expected function with one uintptr-sized result")
- }
- ft := (*functype)(unsafe.Pointer(fn._type))
-
- // Check arguments and construct ABI translation.
- var abiMap abiDesc
- for _, t := range ft.in() {
- abiMap.assignArg(t)
- }
- // The Go ABI aligns the result to the word size. src is
- // already aligned.
- abiMap.dstStackSize = alignUp(abiMap.dstStackSize, goarch.PtrSize)
- abiMap.retOffset = abiMap.dstStackSize
-
- if len(ft.out()) != 1 {
- panic("compileCallback: expected function with one uintptr-sized result")
- }
- if ft.out()[0].size != goarch.PtrSize {
- panic("compileCallback: expected function with one uintptr-sized result")
- }
- if k := ft.out()[0].kind & kindMask; k == kindFloat32 || k == kindFloat64 {
- // In cdecl and stdcall, float results are returned in
- // ST(0). In fastcall, they're returned in XMM0.
- // Either way, it's not AX.
- panic("compileCallback: float results not supported")
- }
- if intArgRegs == 0 {
- // Make room for the uintptr-sized result.
- // If there are argument registers, the return value will
- // be passed in the first register.
- abiMap.dstStackSize += goarch.PtrSize
- }
-
- // TODO(mknyszek): Remove dstSpill from this calculation when we no longer have
- // caller reserved spill space.
- frameSize := alignUp(abiMap.dstStackSize, goarch.PtrSize)
- frameSize += abiMap.dstSpill
- if frameSize > callbackMaxFrame {
- panic("compileCallback: function argument frame too large")
- }
-
- // For cdecl, the callee is responsible for popping its
- // arguments from the C stack.
- var retPop uintptr
- if cdecl {
- retPop = abiMap.srcStackSize
- }
-
- key := winCallbackKey{(*funcval)(fn.data), cdecl}
-
- cbsLock()
-
- // Check if this callback is already registered.
- if n, ok := cbs.index[key]; ok {
- cbsUnlock()
- return callbackasmAddr(n)
- }
-
- // Register the callback.
- if cbs.index == nil {
- cbs.index = make(map[winCallbackKey]int)
- }
- n := cbs.n
- if n >= len(cbs.ctxt) {
- cbsUnlock()
- throw("too many callback functions")
- }
- c := winCallback{key.fn, retPop, abiMap}
- cbs.ctxt[n] = c
- cbs.index[key] = n
- cbs.n++
-
- cbsUnlock()
- return callbackasmAddr(n)
-}
-
-type callbackArgs struct {
- index uintptr
- // args points to the argument block.
- //
- // For cdecl and stdcall, all arguments are on the stack.
- //
- // For fastcall, the trampoline spills register arguments to
- // the reserved spill slots below the stack arguments,
- // resulting in a layout equivalent to stdcall.
- //
- // For arm, the trampoline stores the register arguments just
- // below the stack arguments, so again we can treat it as one
- // big stack arguments frame.
- args unsafe.Pointer
- // Below are out-args from callbackWrap
- result uintptr
- retPop uintptr // For 386 cdecl, how many bytes to pop on return
-}
-
-// callbackWrap is called by callbackasm to invoke a registered C callback.
-func callbackWrap(a *callbackArgs) {
- c := cbs.ctxt[a.index]
- a.retPop = c.retPop
-
- // Convert from C to Go ABI.
- var regs abi.RegArgs
- var frame [callbackMaxFrame]byte
- goArgs := unsafe.Pointer(&frame)
- for _, part := range c.abiMap.parts {
- switch part.kind {
- case abiPartStack:
- memmove(add(goArgs, part.dstStackOffset), add(a.args, part.srcStackOffset), part.len)
- case abiPartReg:
- goReg := unsafe.Pointer(&regs.Ints[part.dstRegister])
- memmove(goReg, add(a.args, part.srcStackOffset), part.len)
- default:
- panic("bad ABI description")
- }
- }
-
- // TODO(mknyszek): Remove this when we no longer have
- // caller reserved spill space.
- frameSize := alignUp(c.abiMap.dstStackSize, goarch.PtrSize)
- frameSize += c.abiMap.dstSpill
-
- // Even though this is copying back results, we can pass a nil
- // type because those results must not require write barriers.
- reflectcall(nil, unsafe.Pointer(c.fn), noescape(goArgs), uint32(c.abiMap.dstStackSize), uint32(c.abiMap.retOffset), uint32(frameSize), &regs)
-
- // Extract the result.
- //
- // There's always exactly one return value, one pointer in size.
- // If it's on the stack, then we will have reserved space for it
- // at the end of the frame, otherwise it was passed in a register.
- if c.abiMap.dstStackSize != c.abiMap.retOffset {
- a.result = *(*uintptr)(unsafe.Pointer(&frame[c.abiMap.retOffset]))
- } else {
- var zero int
- // On architectures with no registers, Ints[0] would be a compile error,
- // so we use a dynamic index. These architectures will never take this
- // branch, so this won't cause a runtime panic.
- a.result = regs.Ints[zero]
- }
-}
-
-const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
-
-// When available, this function will use LoadLibraryEx with the filename
-// parameter and the important SEARCH_SYSTEM32 argument. But on systems that
-// do not have that option, absoluteFilepath should contain a fallback
-// to the full path inside of system32 for use with vanilla LoadLibrary.
-//
-//go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) {
- lockOSThread()
- c := &getg().m.syscall
-
- if useLoadLibraryEx {
- c.fn = getLoadLibraryEx()
- c.n = 3
- args := struct {
- lpFileName *uint16
- hFile uintptr // always 0
- flags uint32
- }{filename, 0, _LOAD_LIBRARY_SEARCH_SYSTEM32}
- c.args = uintptr(noescape(unsafe.Pointer(&args)))
- } else {
- c.fn = getLoadLibrary()
- c.n = 1
- c.args = uintptr(noescape(unsafe.Pointer(&absoluteFilepath)))
- }
-
- cgocall(asmstdcallAddr, unsafe.Pointer(c))
- KeepAlive(filename)
- KeepAlive(absoluteFilepath)
- handle = c.r1
- if handle == 0 {
- err = c.err
- }
- unlockOSThread() // not defer'd after the lockOSThread above to save stack frame size.
- return
-}
-
-//go:linkname syscall_loadlibrary syscall.loadlibrary
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
- lockOSThread()
- defer unlockOSThread()
- c := &getg().m.syscall
- c.fn = getLoadLibrary()
- c.n = 1
- c.args = uintptr(noescape(unsafe.Pointer(&filename)))
- cgocall(asmstdcallAddr, unsafe.Pointer(c))
- KeepAlive(filename)
- handle = c.r1
- if handle == 0 {
- err = c.err
- }
- return
-}
-
-//go:linkname syscall_getprocaddress syscall.getprocaddress
-//go:nosplit
-//go:cgo_unsafe_args
-func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
- lockOSThread()
- defer unlockOSThread()
- c := &getg().m.syscall
- c.fn = getGetProcAddress()
- c.n = 2
- c.args = uintptr(noescape(unsafe.Pointer(&handle)))
- cgocall(asmstdcallAddr, unsafe.Pointer(c))
- KeepAlive(procname)
- outhandle = c.r1
- if outhandle == 0 {
- err = c.err
- }
- return
-}
-
-//go:linkname syscall_Syscall syscall.Syscall
-//go:nosplit
-func syscall_Syscall(fn, nargs, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
- return syscall_SyscallN(fn, a1, a2, a3)
-}
-
-//go:linkname syscall_Syscall6 syscall.Syscall6
-//go:nosplit
-func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
- return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6)
-}
-
-//go:linkname syscall_Syscall9 syscall.Syscall9
-//go:nosplit
-func syscall_Syscall9(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
- return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9)
-}
-
-//go:linkname syscall_Syscall12 syscall.Syscall12
-//go:nosplit
-func syscall_Syscall12(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2, err uintptr) {
- return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
-}
-
-//go:linkname syscall_Syscall15 syscall.Syscall15
-//go:nosplit
-func syscall_Syscall15(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) {
- return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
-}
-
-//go:linkname syscall_Syscall18 syscall.Syscall18
-//go:nosplit
-func syscall_Syscall18(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 uintptr) (r1, r2, err uintptr) {
- return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18)
-}
-
-// maxArgs should be divisible by 2, as Windows stack
-// must be kept 16-byte aligned on syscall entry.
-//
-// Although it only permits maximum 42 parameters, it
-// is arguably large enough.
-const maxArgs = 42
-
-//go:linkname syscall_SyscallN syscall.SyscallN
-//go:nosplit
-func syscall_SyscallN(trap uintptr, args ...uintptr) (r1, r2, err uintptr) {
- nargs := len(args)
-
- // asmstdcall expects it can access the first 4 arguments
- // to load them into registers.
- var tmp [4]uintptr
- switch {
- case nargs < 4:
- copy(tmp[:], args)
- args = tmp[:]
- case nargs > maxArgs:
- panic("runtime: SyscallN has too many arguments")
- }
-
- lockOSThread()
- defer unlockOSThread()
- c := &getg().m.syscall
- c.fn = trap
- c.n = uintptr(nargs)
- c.args = uintptr(noescape(unsafe.Pointer(&args[0])))
- cgocall(asmstdcallAddr, unsafe.Pointer(c))
- return c.r1, c.r2, c.err
-}
diff --git a/contrib/go/_std_1.20/src/runtime/textflag.h b/contrib/go/_std_1.20/src/runtime/textflag.h
deleted file mode 100644
index 214075e360..0000000000
--- a/contrib/go/_std_1.20/src/runtime/textflag.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2013 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.
-
-// This file defines flags attached to various functions
-// and data objects. The compilers, assemblers, and linker must
-// all agree on these values.
-//
-// Keep in sync with src/cmd/internal/obj/textflag.go.
-
-// Don't profile the marked routine. This flag is deprecated.
-#define NOPROF 1
-// It is ok for the linker to get multiple of these symbols. It will
-// pick one of the duplicates to use.
-#define DUPOK 2
-// Don't insert stack check preamble.
-#define NOSPLIT 4
-// Put this data in a read-only section.
-#define RODATA 8
-// This data contains no pointers.
-#define NOPTR 16
-// This is a wrapper function and should not count as disabling 'recover'.
-#define WRAPPER 32
-// This function uses its incoming context register.
-#define NEEDCTXT 64
-// Allocate a word of thread local storage and store the offset from the
-// thread local base to the thread local storage in this variable.
-#define TLSBSS 256
-// Do not insert instructions to allocate a stack frame for this function.
-// Only valid on functions that declare a frame size of 0.
-// TODO(mwhudson): only implemented for ppc64x at present.
-#define NOFRAME 512
-// Function can call reflect.Type.Method or reflect.Type.MethodByName.
-#define REFLECTMETHOD 1024
-// Function is the outermost frame of the call stack. Call stack unwinders
-// should stop at this function.
-#define TOPFRAME 2048
-// Function is an ABI wrapper.
-#define ABIWRAPPER 4096
diff --git a/contrib/go/_std_1.20/src/runtime/time.go b/contrib/go/_std_1.20/src/runtime/time.go
deleted file mode 100644
index 6cd70b7aed..0000000000
--- a/contrib/go/_std_1.20/src/runtime/time.go
+++ /dev/null
@@ -1,1144 +0,0 @@
-// Copyright 2009 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.
-
-// Time-related runtime and pieces of package time.
-
-package runtime
-
-import (
- "internal/abi"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// Package time knows the layout of this structure.
-// If this struct changes, adjust ../time/sleep.go:/runtimeTimer.
-type timer struct {
- // If this timer is on a heap, which P's heap it is on.
- // puintptr rather than *p to match uintptr in the versions
- // of this struct defined in other packages.
- pp puintptr
-
- // Timer wakes up at when, and then at when+period, ... (period > 0 only)
- // each time calling f(arg, now) in the timer goroutine, so f must be
- // a well-behaved function and not block.
- //
- // when must be positive on an active timer.
- when int64
- period int64
- f func(any, uintptr)
- arg any
- seq uintptr
-
- // What to set the when field to in timerModifiedXX status.
- nextwhen int64
-
- // The status field holds one of the values below.
- status atomic.Uint32
-}
-
-// Code outside this file has to be careful in using a timer value.
-//
-// The pp, status, and nextwhen fields may only be used by code in this file.
-//
-// Code that creates a new timer value can set the when, period, f,
-// arg, and seq fields.
-// A new timer value may be passed to addtimer (called by time.startTimer).
-// After doing that no fields may be touched.
-//
-// An active timer (one that has been passed to addtimer) may be
-// passed to deltimer (time.stopTimer), after which it is no longer an
-// active timer. It is an inactive timer.
-// In an inactive timer the period, f, arg, and seq fields may be modified,
-// but not the when field.
-// It's OK to just drop an inactive timer and let the GC collect it.
-// It's not OK to pass an inactive timer to addtimer.
-// Only newly allocated timer values may be passed to addtimer.
-//
-// An active timer may be passed to modtimer. No fields may be touched.
-// It remains an active timer.
-//
-// An inactive timer may be passed to resettimer to turn into an
-// active timer with an updated when field.
-// It's OK to pass a newly allocated timer value to resettimer.
-//
-// Timer operations are addtimer, deltimer, modtimer, resettimer,
-// cleantimers, adjusttimers, and runtimer.
-//
-// We don't permit calling addtimer/deltimer/modtimer/resettimer simultaneously,
-// but adjusttimers and runtimer can be called at the same time as any of those.
-//
-// Active timers live in heaps attached to P, in the timers field.
-// Inactive timers live there too temporarily, until they are removed.
-//
-// addtimer:
-// timerNoStatus -> timerWaiting
-// anything else -> panic: invalid value
-// deltimer:
-// timerWaiting -> timerModifying -> timerDeleted
-// timerModifiedEarlier -> timerModifying -> timerDeleted
-// timerModifiedLater -> timerModifying -> timerDeleted
-// timerNoStatus -> do nothing
-// timerDeleted -> do nothing
-// timerRemoving -> do nothing
-// timerRemoved -> do nothing
-// timerRunning -> wait until status changes
-// timerMoving -> wait until status changes
-// timerModifying -> wait until status changes
-// modtimer:
-// timerWaiting -> timerModifying -> timerModifiedXX
-// timerModifiedXX -> timerModifying -> timerModifiedYY
-// timerNoStatus -> timerModifying -> timerWaiting
-// timerRemoved -> timerModifying -> timerWaiting
-// timerDeleted -> timerModifying -> timerModifiedXX
-// timerRunning -> wait until status changes
-// timerMoving -> wait until status changes
-// timerRemoving -> wait until status changes
-// timerModifying -> wait until status changes
-// cleantimers (looks in P's timer heap):
-// timerDeleted -> timerRemoving -> timerRemoved
-// timerModifiedXX -> timerMoving -> timerWaiting
-// adjusttimers (looks in P's timer heap):
-// timerDeleted -> timerRemoving -> timerRemoved
-// timerModifiedXX -> timerMoving -> timerWaiting
-// runtimer (looks in P's timer heap):
-// timerNoStatus -> panic: uninitialized timer
-// timerWaiting -> timerWaiting or
-// timerWaiting -> timerRunning -> timerNoStatus or
-// timerWaiting -> timerRunning -> timerWaiting
-// timerModifying -> wait until status changes
-// timerModifiedXX -> timerMoving -> timerWaiting
-// timerDeleted -> timerRemoving -> timerRemoved
-// timerRunning -> panic: concurrent runtimer calls
-// timerRemoved -> panic: inconsistent timer heap
-// timerRemoving -> panic: inconsistent timer heap
-// timerMoving -> panic: inconsistent timer heap
-
-// Values for the timer status field.
-const (
- // Timer has no status set yet.
- timerNoStatus = iota
-
- // Waiting for timer to fire.
- // The timer is in some P's heap.
- timerWaiting
-
- // Running the timer function.
- // A timer will only have this status briefly.
- timerRunning
-
- // The timer is deleted and should be removed.
- // It should not be run, but it is still in some P's heap.
- timerDeleted
-
- // The timer is being removed.
- // The timer will only have this status briefly.
- timerRemoving
-
- // The timer has been stopped.
- // It is not in any P's heap.
- timerRemoved
-
- // The timer is being modified.
- // The timer will only have this status briefly.
- timerModifying
-
- // The timer has been modified to an earlier time.
- // The new when value is in the nextwhen field.
- // The timer is in some P's heap, possibly in the wrong place.
- timerModifiedEarlier
-
- // The timer has been modified to the same or a later time.
- // The new when value is in the nextwhen field.
- // The timer is in some P's heap, possibly in the wrong place.
- timerModifiedLater
-
- // The timer has been modified and is being moved.
- // The timer will only have this status briefly.
- timerMoving
-)
-
-// maxWhen is the maximum value for timer's when field.
-const maxWhen = 1<<63 - 1
-
-// verifyTimers can be set to true to add debugging checks that the
-// timer heaps are valid.
-const verifyTimers = false
-
-// Package time APIs.
-// Godoc uses the comments in package time, not these.
-
-// time.now is implemented in assembly.
-
-// timeSleep puts the current goroutine to sleep for at least ns nanoseconds.
-//
-//go:linkname timeSleep time.Sleep
-func timeSleep(ns int64) {
- if ns <= 0 {
- return
- }
-
- gp := getg()
- t := gp.timer
- if t == nil {
- t = new(timer)
- gp.timer = t
- }
- t.f = goroutineReady
- t.arg = gp
- t.nextwhen = nanotime() + ns
- if t.nextwhen < 0 { // check for overflow.
- t.nextwhen = maxWhen
- }
- gopark(resetForSleep, unsafe.Pointer(t), waitReasonSleep, traceEvGoSleep, 1)
-}
-
-// resetForSleep is called after the goroutine is parked for timeSleep.
-// We can't call resettimer in timeSleep itself because if this is a short
-// sleep and there are many goroutines then the P can wind up running the
-// timer function, goroutineReady, before the goroutine has been parked.
-func resetForSleep(gp *g, ut unsafe.Pointer) bool {
- t := (*timer)(ut)
- resettimer(t, t.nextwhen)
- return true
-}
-
-// startTimer adds t to the timer heap.
-//
-//go:linkname startTimer time.startTimer
-func startTimer(t *timer) {
- if raceenabled {
- racerelease(unsafe.Pointer(t))
- }
- addtimer(t)
-}
-
-// stopTimer stops a timer.
-// It reports whether t was stopped before being run.
-//
-//go:linkname stopTimer time.stopTimer
-func stopTimer(t *timer) bool {
- return deltimer(t)
-}
-
-// resetTimer resets an inactive timer, adding it to the heap.
-//
-// Reports whether the timer was modified before it was run.
-//
-//go:linkname resetTimer time.resetTimer
-func resetTimer(t *timer, when int64) bool {
- if raceenabled {
- racerelease(unsafe.Pointer(t))
- }
- return resettimer(t, when)
-}
-
-// modTimer modifies an existing timer.
-//
-//go:linkname modTimer time.modTimer
-func modTimer(t *timer, when, period int64, f func(any, uintptr), arg any, seq uintptr) {
- modtimer(t, when, period, f, arg, seq)
-}
-
-// Go runtime.
-
-// Ready the goroutine arg.
-func goroutineReady(arg any, seq uintptr) {
- goready(arg.(*g), 0)
-}
-
-// Note: this changes some unsynchronized operations to synchronized operations
-// addtimer adds a timer to the current P.
-// This should only be called with a newly created timer.
-// That avoids the risk of changing the when field of a timer in some P's heap,
-// which could cause the heap to become unsorted.
-func addtimer(t *timer) {
- // when must be positive. A negative value will cause runtimer to
- // overflow during its delta calculation and never expire other runtime
- // timers. Zero will cause checkTimers to fail to notice the timer.
- if t.when <= 0 {
- throw("timer when must be positive")
- }
- if t.period < 0 {
- throw("timer period must be non-negative")
- }
- if t.status.Load() != timerNoStatus {
- throw("addtimer called with initialized timer")
- }
- t.status.Store(timerWaiting)
-
- 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)
- doaddtimer(pp, t)
- unlock(&pp.timersLock)
-
- wakeNetPoller(when)
-
- releasem(mp)
-}
-
-// doaddtimer adds t to the current P's heap.
-// The caller must have locked the timers for pp.
-func doaddtimer(pp *p, t *timer) {
- // Timers rely on the network poller, so make sure the poller
- // has started.
- if netpollInited.Load() == 0 {
- netpollGenericInit()
- }
-
- if t.pp != 0 {
- throw("doaddtimer: P already set in timer")
- }
- t.pp.set(pp)
- i := len(pp.timers)
- pp.timers = append(pp.timers, t)
- siftupTimer(pp.timers, i)
- if t == pp.timers[0] {
- pp.timer0When.Store(t.when)
- }
- pp.numTimers.Add(1)
-}
-
-// deltimer deletes the timer t. It may be on some other P, so we can't
-// actually remove it from the timers heap. We can only mark it as deleted.
-// It will be removed in due course by the P whose heap it is on.
-// Reports whether the timer was removed before it was run.
-func deltimer(t *timer) bool {
- for {
- switch s := t.status.Load(); s {
- case timerWaiting, timerModifiedLater:
- // Prevent preemption while the timer is in timerModifying.
- // This could lead to a self-deadlock. See #38070.
- mp := acquirem()
- if t.status.CompareAndSwap(s, timerModifying) {
- // Must fetch t.pp before changing status,
- // as cleantimers in another goroutine
- // can clear t.pp of a timerDeleted timer.
- tpp := t.pp.ptr()
- if !t.status.CompareAndSwap(timerModifying, timerDeleted) {
- badTimer()
- }
- releasem(mp)
- tpp.deletedTimers.Add(1)
- // Timer was not yet run.
- return true
- } else {
- releasem(mp)
- }
- case timerModifiedEarlier:
- // Prevent preemption while the timer is in timerModifying.
- // This could lead to a self-deadlock. See #38070.
- mp := acquirem()
- if t.status.CompareAndSwap(s, timerModifying) {
- // Must fetch t.pp before setting status
- // to timerDeleted.
- tpp := t.pp.ptr()
- if !t.status.CompareAndSwap(timerModifying, timerDeleted) {
- badTimer()
- }
- releasem(mp)
- tpp.deletedTimers.Add(1)
- // Timer was not yet run.
- return true
- } else {
- releasem(mp)
- }
- case timerDeleted, timerRemoving, timerRemoved:
- // Timer was already run.
- return false
- case timerRunning, timerMoving:
- // The timer is being run or moved, by a different P.
- // Wait for it to complete.
- osyield()
- case timerNoStatus:
- // Removing timer that was never added or
- // has already been run. Also see issue 21874.
- return false
- case timerModifying:
- // Simultaneous calls to deltimer and modtimer.
- // Wait for the other call to complete.
- osyield()
- default:
- badTimer()
- }
- }
-}
-
-// dodeltimer removes timer i from the current P's heap.
-// We are locked on the P when this is called.
-// It returns the smallest changed index in pp.timers.
-// The caller must have locked the timers for pp.
-func dodeltimer(pp *p, i int) int {
- if t := pp.timers[i]; t.pp.ptr() != pp {
- throw("dodeltimer: wrong P")
- } else {
- t.pp = 0
- }
- last := len(pp.timers) - 1
- if i != last {
- pp.timers[i] = pp.timers[last]
- }
- pp.timers[last] = nil
- pp.timers = pp.timers[:last]
- smallestChanged := i
- if i != last {
- // Moving to i may have moved the last timer to a new parent,
- // so sift up to preserve the heap guarantee.
- smallestChanged = siftupTimer(pp.timers, i)
- siftdownTimer(pp.timers, i)
- }
- if i == 0 {
- updateTimer0When(pp)
- }
- n := pp.numTimers.Add(-1)
- if n == 0 {
- // If there are no timers, then clearly none are modified.
- pp.timerModifiedEarliest.Store(0)
- }
- return smallestChanged
-}
-
-// dodeltimer0 removes timer 0 from the current P's heap.
-// We are locked on the P when this is called.
-// It reports whether it saw no problems due to races.
-// The caller must have locked the timers for pp.
-func dodeltimer0(pp *p) {
- if t := pp.timers[0]; t.pp.ptr() != pp {
- throw("dodeltimer0: wrong P")
- } else {
- t.pp = 0
- }
- last := len(pp.timers) - 1
- if last > 0 {
- pp.timers[0] = pp.timers[last]
- }
- pp.timers[last] = nil
- pp.timers = pp.timers[:last]
- if last > 0 {
- siftdownTimer(pp.timers, 0)
- }
- updateTimer0When(pp)
- n := pp.numTimers.Add(-1)
- if n == 0 {
- // If there are no timers, then clearly none are modified.
- pp.timerModifiedEarliest.Store(0)
- }
-}
-
-// modtimer modifies an existing timer.
-// This is called by the netpoll code or time.Ticker.Reset or time.Timer.Reset.
-// Reports whether the timer was modified before it was run.
-func modtimer(t *timer, when, period int64, f func(any, uintptr), arg any, seq uintptr) bool {
- if when <= 0 {
- throw("timer when must be positive")
- }
- if period < 0 {
- throw("timer period must be non-negative")
- }
-
- status := uint32(timerNoStatus)
- wasRemoved := false
- var pending bool
- var mp *m
-loop:
- for {
- switch status = t.status.Load(); status {
- case timerWaiting, timerModifiedEarlier, timerModifiedLater:
- // Prevent preemption while the timer is in timerModifying.
- // This could lead to a self-deadlock. See #38070.
- mp = acquirem()
- if t.status.CompareAndSwap(status, timerModifying) {
- pending = true // timer not yet run
- break loop
- }
- releasem(mp)
- case timerNoStatus, timerRemoved:
- // Prevent preemption while the timer is in timerModifying.
- // This could lead to a self-deadlock. See #38070.
- mp = acquirem()
-
- // Timer was already run and t is no longer in a heap.
- // Act like addtimer.
- if t.status.CompareAndSwap(status, timerModifying) {
- wasRemoved = true
- pending = false // timer already run or stopped
- break loop
- }
- releasem(mp)
- case timerDeleted:
- // Prevent preemption while the timer is in timerModifying.
- // This could lead to a self-deadlock. See #38070.
- mp = acquirem()
- if t.status.CompareAndSwap(status, timerModifying) {
- t.pp.ptr().deletedTimers.Add(-1)
- pending = false // timer already stopped
- break loop
- }
- releasem(mp)
- case timerRunning, timerRemoving, timerMoving:
- // The timer is being run or moved, by a different P.
- // Wait for it to complete.
- osyield()
- case timerModifying:
- // Multiple simultaneous calls to modtimer.
- // Wait for the other call to complete.
- osyield()
- default:
- badTimer()
- }
- }
-
- t.period = period
- t.f = f
- t.arg = arg
- t.seq = seq
-
- if wasRemoved {
- t.when = when
- pp := getg().m.p.ptr()
- lock(&pp.timersLock)
- doaddtimer(pp, t)
- unlock(&pp.timersLock)
- if !t.status.CompareAndSwap(timerModifying, timerWaiting) {
- badTimer()
- }
- releasem(mp)
- wakeNetPoller(when)
- } else {
- // The timer is in some other P's heap, so we can't change
- // the when field. If we did, the other P's heap would
- // be out of order. So we put the new when value in the
- // nextwhen field, and let the other P set the when field
- // when it is prepared to resort the heap.
- t.nextwhen = when
-
- newStatus := uint32(timerModifiedLater)
- if when < t.when {
- newStatus = timerModifiedEarlier
- }
-
- tpp := t.pp.ptr()
-
- if newStatus == timerModifiedEarlier {
- updateTimerModifiedEarliest(tpp, when)
- }
-
- // Set the new status of the timer.
- if !t.status.CompareAndSwap(timerModifying, newStatus) {
- badTimer()
- }
- releasem(mp)
-
- // If the new status is earlier, wake up the poller.
- if newStatus == timerModifiedEarlier {
- wakeNetPoller(when)
- }
- }
-
- return pending
-}
-
-// resettimer resets the time when a timer should fire.
-// If used for an inactive timer, the timer will become active.
-// This should be called instead of addtimer if the timer value has been,
-// or may have been, used previously.
-// Reports whether the timer was modified before it was run.
-func resettimer(t *timer, when int64) bool {
- return modtimer(t, when, t.period, t.f, t.arg, t.seq)
-}
-
-// cleantimers cleans up the head of the timer queue. This speeds up
-// programs that create and delete timers; leaving them in the heap
-// slows down addtimer. Reports whether no timer problems were found.
-// The caller must have locked the timers for pp.
-func cleantimers(pp *p) {
- gp := getg()
- for {
- if len(pp.timers) == 0 {
- return
- }
-
- // This loop can theoretically run for a while, and because
- // it is holding timersLock it cannot be preempted.
- // If someone is trying to preempt us, just return.
- // We can clean the timers later.
- if gp.preemptStop {
- return
- }
-
- t := pp.timers[0]
- if t.pp.ptr() != pp {
- throw("cleantimers: bad p")
- }
- switch s := t.status.Load(); s {
- case timerDeleted:
- if !t.status.CompareAndSwap(s, timerRemoving) {
- continue
- }
- dodeltimer0(pp)
- if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
- badTimer()
- }
- pp.deletedTimers.Add(-1)
- case timerModifiedEarlier, timerModifiedLater:
- if !t.status.CompareAndSwap(s, timerMoving) {
- continue
- }
- // Now we can change the when field.
- t.when = t.nextwhen
- // Move t to the right position.
- dodeltimer0(pp)
- doaddtimer(pp, t)
- if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
- badTimer()
- }
- default:
- // Head of timers does not need adjustment.
- return
- }
- }
-}
-
-// moveTimers moves a slice of timers to pp. The slice has been taken
-// from a different P.
-// This is currently called when the world is stopped, but the caller
-// is expected to have locked the timers for pp.
-func moveTimers(pp *p, timers []*timer) {
- for _, t := range timers {
- loop:
- for {
- switch s := t.status.Load(); s {
- case timerWaiting:
- if !t.status.CompareAndSwap(s, timerMoving) {
- continue
- }
- t.pp = 0
- doaddtimer(pp, t)
- if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
- badTimer()
- }
- break loop
- case timerModifiedEarlier, timerModifiedLater:
- if !t.status.CompareAndSwap(s, timerMoving) {
- continue
- }
- t.when = t.nextwhen
- t.pp = 0
- doaddtimer(pp, t)
- if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
- badTimer()
- }
- break loop
- case timerDeleted:
- if !t.status.CompareAndSwap(s, timerRemoved) {
- continue
- }
- t.pp = 0
- // We no longer need this timer in the heap.
- break loop
- case timerModifying:
- // Loop until the modification is complete.
- osyield()
- case timerNoStatus, timerRemoved:
- // We should not see these status values in a timers heap.
- badTimer()
- case timerRunning, timerRemoving, timerMoving:
- // Some other P thinks it owns this timer,
- // which should not happen.
- badTimer()
- default:
- badTimer()
- }
- }
- }
-}
-
-// adjusttimers looks through the timers in the current P's heap for
-// any timers that have been modified to run earlier, and puts them in
-// the correct place in the heap. While looking for those timers,
-// it also moves timers that have been modified to run later,
-// and removes deleted timers. The caller must have locked the timers for pp.
-func adjusttimers(pp *p, now int64) {
- // If we haven't yet reached the time of the first timerModifiedEarlier
- // timer, don't do anything. This speeds up programs that adjust
- // a lot of timers back and forth if the timers rarely expire.
- // We'll postpone looking through all the adjusted timers until
- // one would actually expire.
- first := pp.timerModifiedEarliest.Load()
- if first == 0 || first > now {
- if verifyTimers {
- verifyTimerHeap(pp)
- }
- return
- }
-
- // We are going to clear all timerModifiedEarlier timers.
- pp.timerModifiedEarliest.Store(0)
-
- var moved []*timer
- for i := 0; i < len(pp.timers); i++ {
- t := pp.timers[i]
- if t.pp.ptr() != pp {
- throw("adjusttimers: bad p")
- }
- switch s := t.status.Load(); s {
- case timerDeleted:
- if t.status.CompareAndSwap(s, timerRemoving) {
- changed := dodeltimer(pp, i)
- if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
- badTimer()
- }
- pp.deletedTimers.Add(-1)
- // Go back to the earliest changed heap entry.
- // "- 1" because the loop will add 1.
- i = changed - 1
- }
- case timerModifiedEarlier, timerModifiedLater:
- if t.status.CompareAndSwap(s, timerMoving) {
- // Now we can change the when field.
- t.when = t.nextwhen
- // Take t off the heap, and hold onto it.
- // We don't add it back yet because the
- // heap manipulation could cause our
- // loop to skip some other timer.
- changed := dodeltimer(pp, i)
- moved = append(moved, t)
- // Go back to the earliest changed heap entry.
- // "- 1" because the loop will add 1.
- i = changed - 1
- }
- case timerNoStatus, timerRunning, timerRemoving, timerRemoved, timerMoving:
- badTimer()
- case timerWaiting:
- // OK, nothing to do.
- case timerModifying:
- // Check again after modification is complete.
- osyield()
- i--
- default:
- badTimer()
- }
- }
-
- if len(moved) > 0 {
- addAdjustedTimers(pp, moved)
- }
-
- if verifyTimers {
- verifyTimerHeap(pp)
- }
-}
-
-// addAdjustedTimers adds any timers we adjusted in adjusttimers
-// back to the timer heap.
-func addAdjustedTimers(pp *p, moved []*timer) {
- for _, t := range moved {
- doaddtimer(pp, t)
- if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
- badTimer()
- }
- }
-}
-
-// nobarrierWakeTime looks at P's timers and returns the time when we
-// should wake up the netpoller. It returns 0 if there are no timers.
-// This function is invoked when dropping a P, and must run without
-// any write barriers.
-//
-//go:nowritebarrierrec
-func nobarrierWakeTime(pp *p) int64 {
- next := pp.timer0When.Load()
- nextAdj := pp.timerModifiedEarliest.Load()
- if next == 0 || (nextAdj != 0 && nextAdj < next) {
- next = nextAdj
- }
- return next
-}
-
-// runtimer examines the first timer in timers. If it is ready based on now,
-// it runs the timer and removes or updates it.
-// Returns 0 if it ran a timer, -1 if there are no more timers, or the time
-// when the first timer should run.
-// The caller must have locked the timers for pp.
-// If a timer is run, this will temporarily unlock the timers.
-//
-//go:systemstack
-func runtimer(pp *p, now int64) int64 {
- for {
- t := pp.timers[0]
- if t.pp.ptr() != pp {
- throw("runtimer: bad p")
- }
- switch s := t.status.Load(); s {
- case timerWaiting:
- if t.when > now {
- // Not ready to run.
- return t.when
- }
-
- if !t.status.CompareAndSwap(s, timerRunning) {
- continue
- }
- // Note that runOneTimer may temporarily unlock
- // pp.timersLock.
- runOneTimer(pp, t, now)
- return 0
-
- case timerDeleted:
- if !t.status.CompareAndSwap(s, timerRemoving) {
- continue
- }
- dodeltimer0(pp)
- if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
- badTimer()
- }
- pp.deletedTimers.Add(-1)
- if len(pp.timers) == 0 {
- return -1
- }
-
- case timerModifiedEarlier, timerModifiedLater:
- if !t.status.CompareAndSwap(s, timerMoving) {
- continue
- }
- t.when = t.nextwhen
- dodeltimer0(pp)
- doaddtimer(pp, t)
- if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
- badTimer()
- }
-
- case timerModifying:
- // Wait for modification to complete.
- osyield()
-
- case timerNoStatus, timerRemoved:
- // Should not see a new or inactive timer on the heap.
- badTimer()
- case timerRunning, timerRemoving, timerMoving:
- // These should only be set when timers are locked,
- // and we didn't do it.
- badTimer()
- default:
- badTimer()
- }
- }
-}
-
-// runOneTimer runs a single timer.
-// The caller must have locked the timers for pp.
-// This will temporarily unlock the timers while running the timer function.
-//
-//go:systemstack
-func runOneTimer(pp *p, t *timer, now int64) {
- if raceenabled {
- ppcur := getg().m.p.ptr()
- if ppcur.timerRaceCtx == 0 {
- ppcur.timerRaceCtx = racegostart(abi.FuncPCABIInternal(runtimer) + sys.PCQuantum)
- }
- raceacquirectx(ppcur.timerRaceCtx, unsafe.Pointer(t))
- }
-
- f := t.f
- arg := t.arg
- seq := t.seq
-
- if t.period > 0 {
- // Leave in heap but adjust next time to fire.
- delta := t.when - now
- t.when += t.period * (1 + -delta/t.period)
- if t.when < 0 { // check for overflow.
- t.when = maxWhen
- }
- siftdownTimer(pp.timers, 0)
- if !t.status.CompareAndSwap(timerRunning, timerWaiting) {
- badTimer()
- }
- updateTimer0When(pp)
- } else {
- // Remove from heap.
- dodeltimer0(pp)
- if !t.status.CompareAndSwap(timerRunning, timerNoStatus) {
- badTimer()
- }
- }
-
- if raceenabled {
- // Temporarily use the current P's racectx for g0.
- gp := getg()
- if gp.racectx != 0 {
- throw("runOneTimer: unexpected racectx")
- }
- gp.racectx = gp.m.p.ptr().timerRaceCtx
- }
-
- unlock(&pp.timersLock)
-
- f(arg, seq)
-
- lock(&pp.timersLock)
-
- if raceenabled {
- gp := getg()
- gp.racectx = 0
- }
-}
-
-// clearDeletedTimers removes all deleted timers from the P's timer heap.
-// This is used to avoid clogging up the heap if the program
-// starts a lot of long-running timers and then stops them.
-// For example, this can happen via context.WithTimeout.
-//
-// This is the only function that walks through the entire timer heap,
-// other than moveTimers which only runs when the world is stopped.
-//
-// The caller must have locked the timers for pp.
-func clearDeletedTimers(pp *p) {
- // We are going to clear all timerModifiedEarlier timers.
- // Do this now in case new ones show up while we are looping.
- pp.timerModifiedEarliest.Store(0)
-
- cdel := int32(0)
- to := 0
- changedHeap := false
- timers := pp.timers
-nextTimer:
- for _, t := range timers {
- for {
- switch s := t.status.Load(); s {
- case timerWaiting:
- if changedHeap {
- timers[to] = t
- siftupTimer(timers, to)
- }
- to++
- continue nextTimer
- case timerModifiedEarlier, timerModifiedLater:
- if t.status.CompareAndSwap(s, timerMoving) {
- t.when = t.nextwhen
- timers[to] = t
- siftupTimer(timers, to)
- to++
- changedHeap = true
- if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
- badTimer()
- }
- continue nextTimer
- }
- case timerDeleted:
- if t.status.CompareAndSwap(s, timerRemoving) {
- t.pp = 0
- cdel++
- if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
- badTimer()
- }
- changedHeap = true
- continue nextTimer
- }
- case timerModifying:
- // Loop until modification complete.
- osyield()
- case timerNoStatus, timerRemoved:
- // We should not see these status values in a timer heap.
- badTimer()
- case timerRunning, timerRemoving, timerMoving:
- // Some other P thinks it owns this timer,
- // which should not happen.
- badTimer()
- default:
- badTimer()
- }
- }
- }
-
- // Set remaining slots in timers slice to nil,
- // so that the timer values can be garbage collected.
- for i := to; i < len(timers); i++ {
- timers[i] = nil
- }
-
- pp.deletedTimers.Add(-cdel)
- pp.numTimers.Add(-cdel)
-
- timers = timers[:to]
- pp.timers = timers
- updateTimer0When(pp)
-
- if verifyTimers {
- verifyTimerHeap(pp)
- }
-}
-
-// verifyTimerHeap verifies that the timer heap is in a valid state.
-// This is only for debugging, and is only called if verifyTimers is true.
-// The caller must have locked the timers.
-func verifyTimerHeap(pp *p) {
- for i, t := range pp.timers {
- if i == 0 {
- // First timer has no parent.
- continue
- }
-
- // The heap is 4-ary. See siftupTimer and siftdownTimer.
- p := (i - 1) / 4
- if t.when < pp.timers[p].when {
- print("bad timer heap at ", i, ": ", p, ": ", pp.timers[p].when, ", ", i, ": ", t.when, "\n")
- throw("bad timer heap")
- }
- }
- if numTimers := int(pp.numTimers.Load()); len(pp.timers) != numTimers {
- println("timer heap len", len(pp.timers), "!= numTimers", numTimers)
- throw("bad timer heap len")
- }
-}
-
-// updateTimer0When sets the P's timer0When field.
-// The caller must have locked the timers for pp.
-func updateTimer0When(pp *p) {
- if len(pp.timers) == 0 {
- pp.timer0When.Store(0)
- } else {
- pp.timer0When.Store(pp.timers[0].when)
- }
-}
-
-// updateTimerModifiedEarliest updates the recorded nextwhen field of the
-// earlier timerModifiedEarier value.
-// The timers for pp will not be locked.
-func updateTimerModifiedEarliest(pp *p, nextwhen int64) {
- for {
- old := pp.timerModifiedEarliest.Load()
- if old != 0 && int64(old) < nextwhen {
- return
- }
-
- if pp.timerModifiedEarliest.CompareAndSwap(old, nextwhen) {
- return
- }
- }
-}
-
-// timeSleepUntil returns the time when the next timer should fire. Returns
-// maxWhen if there are no timers.
-// This is only called by sysmon and checkdead.
-func timeSleepUntil() int64 {
- next := int64(maxWhen)
-
- // Prevent allp slice changes. This is like retake.
- lock(&allpLock)
- for _, pp := range allp {
- if pp == nil {
- // This can happen if procresize has grown
- // allp but not yet created new Ps.
- continue
- }
-
- w := pp.timer0When.Load()
- if w != 0 && w < next {
- next = w
- }
-
- w = pp.timerModifiedEarliest.Load()
- if w != 0 && w < next {
- next = w
- }
- }
- unlock(&allpLock)
-
- return next
-}
-
-// Heap maintenance algorithms.
-// These algorithms check for slice index errors manually.
-// Slice index error can happen if the program is using racy
-// access to timers. We don't want to panic here, because
-// it will cause the program to crash with a mysterious
-// "panic holding locks" message. Instead, we panic while not
-// holding a lock.
-
-// siftupTimer puts the timer at position i in the right place
-// in the heap by moving it up toward the top of the heap.
-// It returns the smallest changed index.
-func siftupTimer(t []*timer, i int) int {
- if i >= len(t) {
- badTimer()
- }
- when := t[i].when
- if when <= 0 {
- badTimer()
- }
- tmp := t[i]
- for i > 0 {
- p := (i - 1) / 4 // parent
- if when >= t[p].when {
- break
- }
- t[i] = t[p]
- i = p
- }
- if tmp != t[i] {
- t[i] = tmp
- }
- return i
-}
-
-// siftdownTimer puts the timer at position i in the right place
-// in the heap by moving it down toward the bottom of the heap.
-func siftdownTimer(t []*timer, i int) {
- n := len(t)
- if i >= n {
- badTimer()
- }
- when := t[i].when
- if when <= 0 {
- badTimer()
- }
- tmp := t[i]
- for {
- c := i*4 + 1 // left child
- c3 := c + 2 // mid child
- if c >= n {
- break
- }
- w := t[c].when
- if c+1 < n && t[c+1].when < w {
- w = t[c+1].when
- c++
- }
- if c3 < n {
- w3 := t[c3].when
- if c3+1 < n && t[c3+1].when < w3 {
- w3 = t[c3+1].when
- c3++
- }
- if w3 < w {
- w = w3
- c = c3
- }
- }
- if w >= when {
- break
- }
- t[i] = t[c]
- i = c
- }
- if tmp != t[i] {
- t[i] = tmp
- }
-}
-
-// badTimer is called if the timer data structures have been corrupted,
-// presumably due to racy use by the program. We panic here rather than
-// panicing due to invalid slice access while holding locks.
-// See issue #25686.
-func badTimer() {
- throw("timer data corruption")
-}
diff --git a/contrib/go/_std_1.20/src/runtime/timestub2.go b/contrib/go/_std_1.20/src/runtime/timestub2.go
deleted file mode 100644
index b9a5cc6345..0000000000
--- a/contrib/go/_std_1.20/src/runtime/timestub2.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2018 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.
-
-//go:build !aix && !darwin && !freebsd && !openbsd && !solaris && !windows && !(linux && amd64)
-
-package runtime
-
-func walltime() (sec int64, nsec int32)
diff --git a/contrib/go/_std_1.20/src/runtime/trace.go b/contrib/go/_std_1.20/src/runtime/trace.go
deleted file mode 100644
index e7dfab11f3..0000000000
--- a/contrib/go/_std_1.20/src/runtime/trace.go
+++ /dev/null
@@ -1,1579 +0,0 @@
-// Copyright 2014 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.
-
-// Go execution tracer.
-// The tracer captures a wide range of execution events like goroutine
-// creation/blocking/unblocking, syscall enter/exit/block, GC-related events,
-// changes of heap size, processor start/stop, etc and writes them to a buffer
-// in a compact form. A precise nanosecond-precision timestamp and a stack
-// trace is captured for most events.
-// See https://golang.org/s/go15trace for more info.
-
-package runtime
-
-import (
- "internal/goarch"
- "runtime/internal/atomic"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// Event types in the trace, args are given in square brackets.
-const (
- traceEvNone = 0 // unused
- traceEvBatch = 1 // start of per-P batch of events [pid, timestamp]
- traceEvFrequency = 2 // contains tracer timer frequency [frequency (ticks per second)]
- traceEvStack = 3 // stack [stack id, number of PCs, array of {PC, func string ID, file string ID, line}]
- traceEvGomaxprocs = 4 // current value of GOMAXPROCS [timestamp, GOMAXPROCS, stack id]
- traceEvProcStart = 5 // start of P [timestamp, thread id]
- traceEvProcStop = 6 // stop of P [timestamp]
- traceEvGCStart = 7 // GC start [timestamp, seq, stack id]
- traceEvGCDone = 8 // GC done [timestamp]
- traceEvGCSTWStart = 9 // GC STW start [timestamp, kind]
- traceEvGCSTWDone = 10 // GC STW done [timestamp]
- traceEvGCSweepStart = 11 // GC sweep start [timestamp, stack id]
- traceEvGCSweepDone = 12 // GC sweep done [timestamp, swept, reclaimed]
- traceEvGoCreate = 13 // goroutine creation [timestamp, new goroutine id, new stack id, stack id]
- traceEvGoStart = 14 // goroutine starts running [timestamp, goroutine id, seq]
- traceEvGoEnd = 15 // goroutine ends [timestamp]
- traceEvGoStop = 16 // goroutine stops (like in select{}) [timestamp, stack]
- traceEvGoSched = 17 // goroutine calls Gosched [timestamp, stack]
- traceEvGoPreempt = 18 // goroutine is preempted [timestamp, stack]
- traceEvGoSleep = 19 // goroutine calls Sleep [timestamp, stack]
- traceEvGoBlock = 20 // goroutine blocks [timestamp, stack]
- traceEvGoUnblock = 21 // goroutine is unblocked [timestamp, goroutine id, seq, stack]
- traceEvGoBlockSend = 22 // goroutine blocks on chan send [timestamp, stack]
- traceEvGoBlockRecv = 23 // goroutine blocks on chan recv [timestamp, stack]
- traceEvGoBlockSelect = 24 // goroutine blocks on select [timestamp, stack]
- traceEvGoBlockSync = 25 // goroutine blocks on Mutex/RWMutex [timestamp, stack]
- traceEvGoBlockCond = 26 // goroutine blocks on Cond [timestamp, stack]
- traceEvGoBlockNet = 27 // goroutine blocks on network [timestamp, stack]
- traceEvGoSysCall = 28 // syscall enter [timestamp, stack]
- traceEvGoSysExit = 29 // syscall exit [timestamp, goroutine id, seq, real timestamp]
- traceEvGoSysBlock = 30 // syscall blocks [timestamp]
- traceEvGoWaiting = 31 // denotes that goroutine is blocked when tracing starts [timestamp, goroutine id]
- traceEvGoInSyscall = 32 // denotes that goroutine is in syscall when tracing starts [timestamp, goroutine id]
- traceEvHeapAlloc = 33 // gcController.heapLive change [timestamp, heap_alloc]
- traceEvHeapGoal = 34 // gcController.heapGoal() (formerly next_gc) change [timestamp, heap goal in bytes]
- traceEvTimerGoroutine = 35 // not currently used; previously denoted timer goroutine [timer goroutine id]
- traceEvFutileWakeup = 36 // denotes that the previous wakeup of this goroutine was futile [timestamp]
- traceEvString = 37 // string dictionary entry [ID, length, string]
- traceEvGoStartLocal = 38 // goroutine starts running on the same P as the last event [timestamp, goroutine id]
- traceEvGoUnblockLocal = 39 // goroutine is unblocked on the same P as the last event [timestamp, goroutine id, stack]
- traceEvGoSysExitLocal = 40 // syscall exit on the same P as the last event [timestamp, goroutine id, real timestamp]
- traceEvGoStartLabel = 41 // goroutine starts running with label [timestamp, goroutine id, seq, label string id]
- traceEvGoBlockGC = 42 // goroutine blocks on GC assist [timestamp, stack]
- traceEvGCMarkAssistStart = 43 // GC mark assist start [timestamp, stack]
- traceEvGCMarkAssistDone = 44 // GC mark assist done [timestamp]
- traceEvUserTaskCreate = 45 // trace.NewContext [timestamp, internal task id, internal parent task id, stack, name string]
- traceEvUserTaskEnd = 46 // end of a task [timestamp, internal task id, stack]
- traceEvUserRegion = 47 // trace.WithRegion [timestamp, internal task id, mode(0:start, 1:end), stack, name string]
- traceEvUserLog = 48 // trace.Log [timestamp, internal task id, key string id, stack, value string]
- traceEvCPUSample = 49 // CPU profiling sample [timestamp, stack, real timestamp, real P id (-1 when absent), goroutine id]
- traceEvCount = 50
- // Byte is used but only 6 bits are available for event type.
- // The remaining 2 bits are used to specify the number of arguments.
- // That means, the max event type value is 63.
-)
-
-const (
- // Timestamps in trace are cputicks/traceTickDiv.
- // This makes absolute values of timestamp diffs smaller,
- // and so they are encoded in less number of bytes.
- // 64 on x86 is somewhat arbitrary (one tick is ~20ns on a 3GHz machine).
- // The suggested increment frequency for PowerPC's time base register is
- // 512 MHz according to Power ISA v2.07 section 6.2, so we use 16 on ppc64
- // and ppc64le.
- // Tracing won't work reliably for architectures where cputicks is emulated
- // by nanotime, so the value doesn't matter for those architectures.
- traceTickDiv = 16 + 48*(goarch.Is386|goarch.IsAmd64)
- // Maximum number of PCs in a single stack trace.
- // Since events contain only stack id rather than whole stack trace,
- // we can allow quite large values here.
- traceStackSize = 128
- // Identifier of a fake P that is used when we trace without a real P.
- traceGlobProc = -1
- // Maximum number of bytes to encode uint64 in base-128.
- traceBytesPerNumber = 10
- // Shift of the number of arguments in the first event byte.
- traceArgCountShift = 6
- // Flag passed to traceGoPark to denote that the previous wakeup of this
- // goroutine was futile. For example, a goroutine was unblocked on a mutex,
- // but another goroutine got ahead and acquired the mutex before the first
- // goroutine is scheduled, so the first goroutine has to block again.
- // Such wakeups happen on buffered channels and sync.Mutex,
- // but are generally not interesting for end user.
- traceFutileWakeup byte = 128
-)
-
-// trace is global tracing context.
-var trace struct {
- // trace.lock must only be acquired on the system stack where
- // stack splits cannot happen while it is held.
- lock mutex // protects the following members
- lockOwner *g // to avoid deadlocks during recursive lock locks
- enabled bool // when set runtime traces events
- shutdown bool // set when we are waiting for trace reader to finish after setting enabled to false
- headerWritten bool // whether ReadTrace has emitted trace header
- footerWritten bool // whether ReadTrace has emitted trace footer
- shutdownSema uint32 // used to wait for ReadTrace completion
- seqStart uint64 // sequence number when tracing was started
- ticksStart int64 // cputicks when tracing was started
- ticksEnd int64 // cputicks when tracing was stopped
- timeStart int64 // nanotime when tracing was started
- timeEnd int64 // nanotime when tracing was stopped
- seqGC uint64 // GC start/done sequencer
- reading traceBufPtr // buffer currently handed off to user
- empty traceBufPtr // stack of empty buffers
- fullHead traceBufPtr // queue of full buffers
- fullTail traceBufPtr
- stackTab traceStackTable // maps stack traces to unique ids
- // cpuLogRead accepts CPU profile samples from the signal handler where
- // they're generated. It uses a two-word header to hold the IDs of the P and
- // G (respectively) that were active at the time of the sample. Because
- // profBuf uses a record with all zeros in its header to indicate overflow,
- // we make sure to make the P field always non-zero: The ID of a real P will
- // start at bit 1, and bit 0 will be set. Samples that arrive while no P is
- // running (such as near syscalls) will set the first header field to 0b10.
- // This careful handling of the first header field allows us to store ID of
- // the active G directly in the second field, even though that will be 0
- // when sampling g0.
- cpuLogRead *profBuf
- // cpuLogBuf is a trace buffer to hold events corresponding to CPU profile
- // samples, which arrive out of band and not directly connected to a
- // specific P.
- cpuLogBuf traceBufPtr
-
- reader atomic.Pointer[g] // goroutine that called ReadTrace, or nil
-
- signalLock atomic.Uint32 // protects use of the following member, only usable in signal handlers
- cpuLogWrite *profBuf // copy of cpuLogRead for use in signal handlers, set without signalLock
-
- // Dictionary for traceEvString.
- //
- // TODO: central lock to access the map is not ideal.
- // option: pre-assign ids to all user annotation region names and tags
- // option: per-P cache
- // option: sync.Map like data structure
- stringsLock mutex
- strings map[string]uint64
- stringSeq uint64
-
- // markWorkerLabels maps gcMarkWorkerMode to string ID.
- markWorkerLabels [len(gcMarkWorkerModeStrings)]uint64
-
- bufLock mutex // protects buf
- buf traceBufPtr // global trace buffer, used when running without a p
-}
-
-// traceBufHeader is per-P tracing buffer.
-type traceBufHeader struct {
- link traceBufPtr // in trace.empty/full
- lastTicks uint64 // when we wrote the last event
- pos int // next write offset in arr
- stk [traceStackSize]uintptr // scratch buffer for traceback
-}
-
-// traceBuf is per-P tracing buffer.
-type traceBuf struct {
- _ sys.NotInHeap
- traceBufHeader
- arr [64<<10 - unsafe.Sizeof(traceBufHeader{})]byte // underlying buffer for traceBufHeader.buf
-}
-
-// traceBufPtr is a *traceBuf that is not traced by the garbage
-// collector and doesn't have write barriers. traceBufs are not
-// allocated from the GC'd heap, so this is safe, and are often
-// manipulated in contexts where write barriers are not allowed, so
-// this is necessary.
-//
-// TODO: Since traceBuf is now embedded runtime/internal/sys.NotInHeap, this isn't necessary.
-type traceBufPtr uintptr
-
-func (tp traceBufPtr) ptr() *traceBuf { return (*traceBuf)(unsafe.Pointer(tp)) }
-func (tp *traceBufPtr) set(b *traceBuf) { *tp = traceBufPtr(unsafe.Pointer(b)) }
-func traceBufPtrOf(b *traceBuf) traceBufPtr {
- return traceBufPtr(unsafe.Pointer(b))
-}
-
-// StartTrace enables tracing for the current process.
-// While tracing, the data will be buffered and available via ReadTrace.
-// StartTrace returns an error if tracing is already enabled.
-// Most clients should use the runtime/trace package or the testing package's
-// -test.trace flag instead of calling StartTrace directly.
-func StartTrace() error {
- // Stop the world so that we can take a consistent snapshot
- // of all goroutines at the beginning of the trace.
- // Do not stop the world during GC so we ensure we always see
- // a consistent view of GC-related events (e.g. a start is always
- // paired with an end).
- stopTheWorldGC("start tracing")
-
- // Prevent sysmon from running any code that could generate events.
- lock(&sched.sysmonlock)
-
- // We are in stop-the-world, but syscalls can finish and write to trace concurrently.
- // Exitsyscall could check trace.enabled long before and then suddenly wake up
- // and decide to write to trace at a random point in time.
- // However, such syscall will use the global trace.buf buffer, because we've
- // acquired all p's by doing stop-the-world. So this protects us from such races.
- lock(&trace.bufLock)
-
- if trace.enabled || trace.shutdown {
- unlock(&trace.bufLock)
- unlock(&sched.sysmonlock)
- startTheWorldGC()
- return errorString("tracing is already enabled")
- }
-
- // Can't set trace.enabled yet. While the world is stopped, exitsyscall could
- // already emit a delayed event (see exitTicks in exitsyscall) if we set trace.enabled here.
- // That would lead to an inconsistent trace:
- // - either GoSysExit appears before EvGoInSyscall,
- // - or GoSysExit appears for a goroutine for which we don't emit EvGoInSyscall below.
- // To instruct traceEvent that it must not ignore events below, we set startingtrace.
- // trace.enabled is set afterwards once we have emitted all preliminary events.
- mp := getg().m
- mp.startingtrace = true
-
- // Obtain current stack ID to use in all traceEvGoCreate events below.
- stkBuf := make([]uintptr, traceStackSize)
- stackID := traceStackID(mp, stkBuf, 2)
-
- profBuf := newProfBuf(2, profBufWordCount, profBufTagCount) // after the timestamp, header is [pp.id, gp.goid]
- trace.cpuLogRead = profBuf
-
- // We must not acquire trace.signalLock outside of a signal handler: a
- // profiling signal may arrive at any time and try to acquire it, leading to
- // deadlock. Because we can't use that lock to protect updates to
- // trace.cpuLogWrite (only use of the structure it references), reads and
- // writes of the pointer must be atomic. (And although this field is never
- // the sole pointer to the profBuf value, it's best to allow a write barrier
- // here.)
- atomicstorep(unsafe.Pointer(&trace.cpuLogWrite), unsafe.Pointer(profBuf))
-
- // World is stopped, no need to lock.
- forEachGRace(func(gp *g) {
- status := readgstatus(gp)
- if status != _Gdead {
- gp.traceseq = 0
- gp.tracelastp = getg().m.p
- // +PCQuantum because traceFrameForPC expects return PCs and subtracts PCQuantum.
- id := trace.stackTab.put([]uintptr{startPCforTrace(gp.startpc) + sys.PCQuantum})
- traceEvent(traceEvGoCreate, -1, gp.goid, uint64(id), stackID)
- }
- if status == _Gwaiting {
- // traceEvGoWaiting is implied to have seq=1.
- gp.traceseq++
- traceEvent(traceEvGoWaiting, -1, gp.goid)
- }
- if status == _Gsyscall {
- gp.traceseq++
- traceEvent(traceEvGoInSyscall, -1, gp.goid)
- } else if status == _Gdead && gp.m != nil && gp.m.isextra {
- // Trigger two trace events for the dead g in the extra m,
- // since the next event of the g will be traceEvGoSysExit in exitsyscall,
- // while calling from C thread to Go.
- gp.traceseq = 0
- gp.tracelastp = getg().m.p
- // +PCQuantum because traceFrameForPC expects return PCs and subtracts PCQuantum.
- id := trace.stackTab.put([]uintptr{startPCforTrace(0) + sys.PCQuantum}) // no start pc
- traceEvent(traceEvGoCreate, -1, gp.goid, uint64(id), stackID)
- gp.traceseq++
- traceEvent(traceEvGoInSyscall, -1, gp.goid)
- } else {
- gp.sysblocktraced = false
- }
- })
- traceProcStart()
- traceGoStart()
- // Note: ticksStart needs to be set after we emit traceEvGoInSyscall events.
- // If we do it the other way around, it is possible that exitsyscall will
- // query sysexitticks after ticksStart but before traceEvGoInSyscall timestamp.
- // It will lead to a false conclusion that cputicks is broken.
- trace.ticksStart = cputicks()
- trace.timeStart = nanotime()
- trace.headerWritten = false
- trace.footerWritten = false
-
- // string to id mapping
- // 0 : reserved for an empty string
- // remaining: other strings registered by traceString
- trace.stringSeq = 0
- trace.strings = make(map[string]uint64)
-
- trace.seqGC = 0
- mp.startingtrace = false
- trace.enabled = true
-
- // Register runtime goroutine labels.
- _, pid, bufp := traceAcquireBuffer()
- for i, label := range gcMarkWorkerModeStrings[:] {
- trace.markWorkerLabels[i], bufp = traceString(bufp, pid, label)
- }
- traceReleaseBuffer(pid)
-
- unlock(&trace.bufLock)
-
- unlock(&sched.sysmonlock)
-
- startTheWorldGC()
- return nil
-}
-
-// StopTrace stops tracing, if it was previously enabled.
-// StopTrace only returns after all the reads for the trace have completed.
-func StopTrace() {
- // Stop the world so that we can collect the trace buffers from all p's below,
- // and also to avoid races with traceEvent.
- stopTheWorldGC("stop tracing")
-
- // See the comment in StartTrace.
- lock(&sched.sysmonlock)
-
- // See the comment in StartTrace.
- lock(&trace.bufLock)
-
- if !trace.enabled {
- unlock(&trace.bufLock)
- unlock(&sched.sysmonlock)
- startTheWorldGC()
- return
- }
-
- traceGoSched()
-
- atomicstorep(unsafe.Pointer(&trace.cpuLogWrite), nil)
- trace.cpuLogRead.close()
- traceReadCPU()
-
- // Loop over all allocated Ps because dead Ps may still have
- // trace buffers.
- for _, p := range allp[:cap(allp)] {
- buf := p.tracebuf
- if buf != 0 {
- traceFullQueue(buf)
- p.tracebuf = 0
- }
- }
- if trace.buf != 0 {
- buf := trace.buf
- trace.buf = 0
- if buf.ptr().pos != 0 {
- traceFullQueue(buf)
- }
- }
- if trace.cpuLogBuf != 0 {
- buf := trace.cpuLogBuf
- trace.cpuLogBuf = 0
- if buf.ptr().pos != 0 {
- traceFullQueue(buf)
- }
- }
-
- for {
- trace.ticksEnd = cputicks()
- trace.timeEnd = nanotime()
- // Windows time can tick only every 15ms, wait for at least one tick.
- if trace.timeEnd != trace.timeStart {
- break
- }
- osyield()
- }
-
- trace.enabled = false
- trace.shutdown = true
- unlock(&trace.bufLock)
-
- unlock(&sched.sysmonlock)
-
- startTheWorldGC()
-
- // The world is started but we've set trace.shutdown, so new tracing can't start.
- // Wait for the trace reader to flush pending buffers and stop.
- semacquire(&trace.shutdownSema)
- if raceenabled {
- raceacquire(unsafe.Pointer(&trace.shutdownSema))
- }
-
- systemstack(func() {
- // The lock protects us from races with StartTrace/StopTrace because they do stop-the-world.
- lock(&trace.lock)
- for _, p := range allp[:cap(allp)] {
- if p.tracebuf != 0 {
- throw("trace: non-empty trace buffer in proc")
- }
- }
- if trace.buf != 0 {
- throw("trace: non-empty global trace buffer")
- }
- if trace.fullHead != 0 || trace.fullTail != 0 {
- throw("trace: non-empty full trace buffer")
- }
- if trace.reading != 0 || trace.reader.Load() != nil {
- throw("trace: reading after shutdown")
- }
- for trace.empty != 0 {
- buf := trace.empty
- trace.empty = buf.ptr().link
- sysFree(unsafe.Pointer(buf), unsafe.Sizeof(*buf.ptr()), &memstats.other_sys)
- }
- trace.strings = nil
- trace.shutdown = false
- trace.cpuLogRead = nil
- unlock(&trace.lock)
- })
-}
-
-// ReadTrace returns the next chunk of binary tracing data, blocking until data
-// is available. If tracing is turned off and all the data accumulated while it
-// was on has been returned, ReadTrace returns nil. The caller must copy the
-// returned data before calling ReadTrace again.
-// ReadTrace must be called from one goroutine at a time.
-func ReadTrace() []byte {
-top:
- var buf []byte
- var park bool
- systemstack(func() {
- buf, park = readTrace0()
- })
- if park {
- gopark(func(gp *g, _ unsafe.Pointer) bool {
- if !trace.reader.CompareAndSwapNoWB(nil, gp) {
- // We're racing with another reader.
- // Wake up and handle this case.
- return false
- }
-
- if g2 := traceReader(); gp == g2 {
- // New data arrived between unlocking
- // and the CAS and we won the wake-up
- // race, so wake up directly.
- return false
- } else if g2 != nil {
- printlock()
- println("runtime: got trace reader", g2, g2.goid)
- throw("unexpected trace reader")
- }
-
- return true
- }, nil, waitReasonTraceReaderBlocked, traceEvGoBlock, 2)
- goto top
- }
-
- return buf
-}
-
-// readTrace0 is ReadTrace's continuation on g0. This must run on the
-// system stack because it acquires trace.lock.
-//
-//go:systemstack
-func readTrace0() (buf []byte, park bool) {
- if raceenabled {
- // g0 doesn't have a race context. Borrow the user G's.
- if getg().racectx != 0 {
- throw("expected racectx == 0")
- }
- getg().racectx = getg().m.curg.racectx
- // (This defer should get open-coded, which is safe on
- // the system stack.)
- defer func() { getg().racectx = 0 }()
- }
-
- // This function may need to lock trace.lock recursively
- // (goparkunlock -> traceGoPark -> traceEvent -> traceFlush).
- // To allow this we use trace.lockOwner.
- // Also this function must not allocate while holding trace.lock:
- // allocation can call heap allocate, which will try to emit a trace
- // event while holding heap lock.
- lock(&trace.lock)
- trace.lockOwner = getg().m.curg
-
- if trace.reader.Load() != nil {
- // More than one goroutine reads trace. This is bad.
- // But we rather do not crash the program because of tracing,
- // because tracing can be enabled at runtime on prod servers.
- trace.lockOwner = nil
- unlock(&trace.lock)
- println("runtime: ReadTrace called from multiple goroutines simultaneously")
- return nil, false
- }
- // Recycle the old buffer.
- if buf := trace.reading; buf != 0 {
- buf.ptr().link = trace.empty
- trace.empty = buf
- trace.reading = 0
- }
- // Write trace header.
- if !trace.headerWritten {
- trace.headerWritten = true
- trace.lockOwner = nil
- unlock(&trace.lock)
- return []byte("go 1.19 trace\x00\x00\x00"), false
- }
- // Optimistically look for CPU profile samples. This may write new stack
- // records, and may write new tracing buffers.
- if !trace.footerWritten && !trace.shutdown {
- traceReadCPU()
- }
- // Wait for new data.
- if trace.fullHead == 0 && !trace.shutdown {
- // We don't simply use a note because the scheduler
- // executes this goroutine directly when it wakes up
- // (also a note would consume an M).
- trace.lockOwner = nil
- unlock(&trace.lock)
- return nil, true
- }
-newFull:
- assertLockHeld(&trace.lock)
- // Write a buffer.
- if trace.fullHead != 0 {
- buf := traceFullDequeue()
- trace.reading = buf
- trace.lockOwner = nil
- unlock(&trace.lock)
- return buf.ptr().arr[:buf.ptr().pos], false
- }
-
- // Write footer with timer frequency.
- if !trace.footerWritten {
- trace.footerWritten = true
- // Use float64 because (trace.ticksEnd - trace.ticksStart) * 1e9 can overflow int64.
- freq := float64(trace.ticksEnd-trace.ticksStart) * 1e9 / float64(trace.timeEnd-trace.timeStart) / traceTickDiv
- if freq <= 0 {
- throw("trace: ReadTrace got invalid frequency")
- }
- trace.lockOwner = nil
- unlock(&trace.lock)
-
- // Write frequency event.
- bufp := traceFlush(0, 0)
- buf := bufp.ptr()
- buf.byte(traceEvFrequency | 0<<traceArgCountShift)
- buf.varint(uint64(freq))
-
- // Dump stack table.
- // This will emit a bunch of full buffers, we will pick them up
- // on the next iteration.
- bufp = trace.stackTab.dump(bufp)
-
- // Flush final buffer.
- lock(&trace.lock)
- traceFullQueue(bufp)
- goto newFull // trace.lock should be held at newFull
- }
- // Done.
- if trace.shutdown {
- trace.lockOwner = nil
- unlock(&trace.lock)
- if raceenabled {
- // Model synchronization on trace.shutdownSema, which race
- // detector does not see. This is required to avoid false
- // race reports on writer passed to trace.Start.
- racerelease(unsafe.Pointer(&trace.shutdownSema))
- }
- // trace.enabled is already reset, so can call traceable functions.
- semrelease(&trace.shutdownSema)
- return nil, false
- }
- // Also bad, but see the comment above.
- trace.lockOwner = nil
- unlock(&trace.lock)
- println("runtime: spurious wakeup of trace reader")
- return nil, false
-}
-
-// traceReader returns the trace reader that should be woken up, if any.
-// Callers should first check that trace.enabled or trace.shutdown is set.
-//
-// This must run on the system stack because it acquires trace.lock.
-//
-//go:systemstack
-func traceReader() *g {
- // Optimistic check first
- if traceReaderAvailable() == nil {
- return nil
- }
- lock(&trace.lock)
- gp := traceReaderAvailable()
- if gp == nil || !trace.reader.CompareAndSwapNoWB(gp, nil) {
- unlock(&trace.lock)
- return nil
- }
- unlock(&trace.lock)
- return gp
-}
-
-// traceReaderAvailable returns the trace reader if it is not currently
-// scheduled and should be. Callers should first check that trace.enabled
-// or trace.shutdown is set.
-func traceReaderAvailable() *g {
- if trace.fullHead != 0 || trace.shutdown {
- return trace.reader.Load()
- }
- return nil
-}
-
-// traceProcFree frees trace buffer associated with pp.
-//
-// This must run on the system stack because it acquires trace.lock.
-//
-//go:systemstack
-func traceProcFree(pp *p) {
- buf := pp.tracebuf
- pp.tracebuf = 0
- if buf == 0 {
- return
- }
- lock(&trace.lock)
- traceFullQueue(buf)
- unlock(&trace.lock)
-}
-
-// traceFullQueue queues buf into queue of full buffers.
-func traceFullQueue(buf traceBufPtr) {
- buf.ptr().link = 0
- if trace.fullHead == 0 {
- trace.fullHead = buf
- } else {
- trace.fullTail.ptr().link = buf
- }
- trace.fullTail = buf
-}
-
-// traceFullDequeue dequeues from queue of full buffers.
-func traceFullDequeue() traceBufPtr {
- buf := trace.fullHead
- if buf == 0 {
- return 0
- }
- trace.fullHead = buf.ptr().link
- if trace.fullHead == 0 {
- trace.fullTail = 0
- }
- buf.ptr().link = 0
- return buf
-}
-
-// traceEvent writes a single event to trace buffer, flushing the buffer if necessary.
-// ev is event type.
-// If skip > 0, write current stack id as the last argument (skipping skip top frames).
-// If skip = 0, this event type should contain a stack, but we don't want
-// to collect and remember it for this particular call.
-func traceEvent(ev byte, skip int, args ...uint64) {
- mp, pid, bufp := traceAcquireBuffer()
- // Double-check trace.enabled now that we've done m.locks++ and acquired bufLock.
- // This protects from races between traceEvent and StartTrace/StopTrace.
-
- // The caller checked that trace.enabled == true, but trace.enabled might have been
- // turned off between the check and now. Check again. traceLockBuffer did mp.locks++,
- // StopTrace does stopTheWorld, and stopTheWorld waits for mp.locks to go back to zero,
- // so if we see trace.enabled == true now, we know it's true for the rest of the function.
- // Exitsyscall can run even during stopTheWorld. The race with StartTrace/StopTrace
- // during tracing in exitsyscall is resolved by locking trace.bufLock in traceLockBuffer.
- //
- // Note trace_userTaskCreate runs the same check.
- if !trace.enabled && !mp.startingtrace {
- traceReleaseBuffer(pid)
- return
- }
-
- if skip > 0 {
- if getg() == mp.curg {
- skip++ // +1 because stack is captured in traceEventLocked.
- }
- }
- traceEventLocked(0, mp, pid, bufp, ev, 0, skip, args...)
- traceReleaseBuffer(pid)
-}
-
-// traceEventLocked writes a single event of type ev to the trace buffer bufp,
-// flushing the buffer if necessary. pid is the id of the current P, or
-// traceGlobProc if we're tracing without a real P.
-//
-// Preemption is disabled, and if running without a real P the global tracing
-// buffer is locked.
-//
-// Events types that do not include a stack set skip to -1. Event types that
-// include a stack may explicitly reference a stackID from the trace.stackTab
-// (obtained by an earlier call to traceStackID). Without an explicit stackID,
-// this function will automatically capture the stack of the goroutine currently
-// running on mp, skipping skip top frames or, if skip is 0, writing out an
-// empty stack record.
-//
-// It records the event's args to the traceBuf, and also makes an effort to
-// reserve extraBytes bytes of additional space immediately following the event,
-// in the same traceBuf.
-func traceEventLocked(extraBytes int, mp *m, pid int32, bufp *traceBufPtr, ev byte, stackID uint32, skip int, args ...uint64) {
- buf := bufp.ptr()
- // TODO: test on non-zero extraBytes param.
- maxSize := 2 + 5*traceBytesPerNumber + extraBytes // event type, length, sequence, timestamp, stack id and two add params
- if buf == nil || len(buf.arr)-buf.pos < maxSize {
- systemstack(func() {
- buf = traceFlush(traceBufPtrOf(buf), pid).ptr()
- })
- bufp.set(buf)
- }
-
- // NOTE: ticks might be same after tick division, although the real cputicks is
- // linear growth.
- ticks := uint64(cputicks()) / traceTickDiv
- tickDiff := ticks - buf.lastTicks
- if tickDiff == 0 {
- ticks = buf.lastTicks + 1
- tickDiff = 1
- }
-
- buf.lastTicks = ticks
- narg := byte(len(args))
- if stackID != 0 || skip >= 0 {
- narg++
- }
- // We have only 2 bits for number of arguments.
- // If number is >= 3, then the event type is followed by event length in bytes.
- if narg > 3 {
- narg = 3
- }
- startPos := buf.pos
- buf.byte(ev | narg<<traceArgCountShift)
- var lenp *byte
- if narg == 3 {
- // Reserve the byte for length assuming that length < 128.
- buf.varint(0)
- lenp = &buf.arr[buf.pos-1]
- }
- buf.varint(tickDiff)
- for _, a := range args {
- buf.varint(a)
- }
- if stackID != 0 {
- buf.varint(uint64(stackID))
- } else if skip == 0 {
- buf.varint(0)
- } else if skip > 0 {
- buf.varint(traceStackID(mp, buf.stk[:], skip))
- }
- evSize := buf.pos - startPos
- if evSize > maxSize {
- throw("invalid length of trace event")
- }
- if lenp != nil {
- // Fill in actual length.
- *lenp = byte(evSize - 2)
- }
-}
-
-// traceCPUSample writes a CPU profile sample stack to the execution tracer's
-// profiling buffer. It is called from a signal handler, so is limited in what
-// it can do.
-func traceCPUSample(gp *g, pp *p, stk []uintptr) {
- if !trace.enabled {
- // Tracing is usually turned off; don't spend time acquiring the signal
- // lock unless it's active.
- return
- }
-
- // Match the clock used in traceEventLocked
- now := cputicks()
- // The "header" here is the ID of the P that was running the profiled code,
- // followed by the ID of the goroutine. (For normal CPU profiling, it's
- // usually the number of samples with the given stack.) Near syscalls, pp
- // may be nil. Reporting goid of 0 is fine for either g0 or a nil gp.
- var hdr [2]uint64
- if pp != nil {
- // Overflow records in profBuf have all header values set to zero. Make
- // sure that real headers have at least one bit set.
- hdr[0] = uint64(pp.id)<<1 | 0b1
- } else {
- hdr[0] = 0b10
- }
- if gp != nil {
- hdr[1] = gp.goid
- }
-
- // Allow only one writer at a time
- for !trace.signalLock.CompareAndSwap(0, 1) {
- // TODO: Is it safe to osyield here? https://go.dev/issue/52672
- osyield()
- }
-
- if log := (*profBuf)(atomic.Loadp(unsafe.Pointer(&trace.cpuLogWrite))); log != nil {
- // Note: we don't pass a tag pointer here (how should profiling tags
- // interact with the execution tracer?), but if we did we'd need to be
- // careful about write barriers. See the long comment in profBuf.write.
- log.write(nil, now, hdr[:], stk)
- }
-
- trace.signalLock.Store(0)
-}
-
-func traceReadCPU() {
- bufp := &trace.cpuLogBuf
-
- for {
- data, tags, _ := trace.cpuLogRead.read(profBufNonBlocking)
- if len(data) == 0 {
- break
- }
- for len(data) > 0 {
- if len(data) < 4 || data[0] > uint64(len(data)) {
- break // truncated profile
- }
- if data[0] < 4 || tags != nil && len(tags) < 1 {
- break // malformed profile
- }
- if len(tags) < 1 {
- break // mismatched profile records and tags
- }
- timestamp := data[1]
- ppid := data[2] >> 1
- if hasP := (data[2] & 0b1) != 0; !hasP {
- ppid = ^uint64(0)
- }
- goid := data[3]
- stk := data[4:data[0]]
- empty := len(stk) == 1 && data[2] == 0 && data[3] == 0
- data = data[data[0]:]
- // No support here for reporting goroutine tags at the moment; if
- // that information is to be part of the execution trace, we'd
- // probably want to see when the tags are applied and when they
- // change, instead of only seeing them when we get a CPU sample.
- tags = tags[1:]
-
- if empty {
- // Looks like an overflow record from the profBuf. Not much to
- // do here, we only want to report full records.
- //
- // TODO: should we start a goroutine to drain the profBuf,
- // rather than relying on a high-enough volume of tracing events
- // to keep ReadTrace busy? https://go.dev/issue/52674
- continue
- }
-
- buf := bufp.ptr()
- if buf == nil {
- systemstack(func() {
- *bufp = traceFlush(*bufp, 0)
- })
- buf = bufp.ptr()
- }
- for i := range stk {
- if i >= len(buf.stk) {
- break
- }
- buf.stk[i] = uintptr(stk[i])
- }
- stackID := trace.stackTab.put(buf.stk[:len(stk)])
-
- traceEventLocked(0, nil, 0, bufp, traceEvCPUSample, stackID, 1, timestamp/traceTickDiv, ppid, goid)
- }
- }
-}
-
-func traceStackID(mp *m, buf []uintptr, skip int) uint64 {
- gp := getg()
- curgp := mp.curg
- var nstk int
- if curgp == gp {
- nstk = callers(skip+1, buf)
- } else if curgp != nil {
- nstk = gcallers(curgp, skip, buf)
- }
- if nstk > 0 {
- nstk-- // skip runtime.goexit
- }
- if nstk > 0 && curgp.goid == 1 {
- nstk-- // skip runtime.main
- }
- id := trace.stackTab.put(buf[:nstk])
- return uint64(id)
-}
-
-// traceAcquireBuffer returns trace buffer to use and, if necessary, locks it.
-func traceAcquireBuffer() (mp *m, pid int32, bufp *traceBufPtr) {
- // Any time we acquire a buffer, we may end up flushing it,
- // but flushes are rare. Record the lock edge even if it
- // doesn't happen this time.
- lockRankMayTraceFlush()
-
- mp = acquirem()
- if p := mp.p.ptr(); p != nil {
- return mp, p.id, &p.tracebuf
- }
- lock(&trace.bufLock)
- return mp, traceGlobProc, &trace.buf
-}
-
-// traceReleaseBuffer releases a buffer previously acquired with traceAcquireBuffer.
-func traceReleaseBuffer(pid int32) {
- if pid == traceGlobProc {
- unlock(&trace.bufLock)
- }
- releasem(getg().m)
-}
-
-// lockRankMayTraceFlush records the lock ranking effects of a
-// potential call to traceFlush.
-func lockRankMayTraceFlush() {
- owner := trace.lockOwner
- dolock := owner == nil || owner != getg().m.curg
- if dolock {
- lockWithRankMayAcquire(&trace.lock, getLockRank(&trace.lock))
- }
-}
-
-// traceFlush puts buf onto stack of full buffers and returns an empty buffer.
-//
-// This must run on the system stack because it acquires trace.lock.
-//
-//go:systemstack
-func traceFlush(buf traceBufPtr, pid int32) traceBufPtr {
- owner := trace.lockOwner
- dolock := owner == nil || owner != getg().m.curg
- if dolock {
- lock(&trace.lock)
- }
- if buf != 0 {
- traceFullQueue(buf)
- }
- if trace.empty != 0 {
- buf = trace.empty
- trace.empty = buf.ptr().link
- } else {
- buf = traceBufPtr(sysAlloc(unsafe.Sizeof(traceBuf{}), &memstats.other_sys))
- if buf == 0 {
- throw("trace: out of memory")
- }
- }
- bufp := buf.ptr()
- bufp.link.set(nil)
- bufp.pos = 0
-
- // initialize the buffer for a new batch
- ticks := uint64(cputicks()) / traceTickDiv
- if ticks == bufp.lastTicks {
- ticks = bufp.lastTicks + 1
- }
- bufp.lastTicks = ticks
- bufp.byte(traceEvBatch | 1<<traceArgCountShift)
- bufp.varint(uint64(pid))
- bufp.varint(ticks)
-
- if dolock {
- unlock(&trace.lock)
- }
- return buf
-}
-
-// traceString adds a string to the trace.strings and returns the id.
-func traceString(bufp *traceBufPtr, pid int32, s string) (uint64, *traceBufPtr) {
- if s == "" {
- return 0, bufp
- }
-
- lock(&trace.stringsLock)
- if raceenabled {
- // raceacquire is necessary because the map access
- // below is race annotated.
- raceacquire(unsafe.Pointer(&trace.stringsLock))
- }
-
- if id, ok := trace.strings[s]; ok {
- if raceenabled {
- racerelease(unsafe.Pointer(&trace.stringsLock))
- }
- unlock(&trace.stringsLock)
-
- return id, bufp
- }
-
- trace.stringSeq++
- id := trace.stringSeq
- trace.strings[s] = id
-
- if raceenabled {
- racerelease(unsafe.Pointer(&trace.stringsLock))
- }
- unlock(&trace.stringsLock)
-
- // memory allocation in above may trigger tracing and
- // cause *bufp changes. Following code now works with *bufp,
- // so there must be no memory allocation or any activities
- // that causes tracing after this point.
-
- buf := bufp.ptr()
- size := 1 + 2*traceBytesPerNumber + len(s)
- if buf == nil || len(buf.arr)-buf.pos < size {
- systemstack(func() {
- buf = traceFlush(traceBufPtrOf(buf), pid).ptr()
- bufp.set(buf)
- })
- }
- buf.byte(traceEvString)
- buf.varint(id)
-
- // double-check the string and the length can fit.
- // Otherwise, truncate the string.
- slen := len(s)
- if room := len(buf.arr) - buf.pos; room < slen+traceBytesPerNumber {
- slen = room
- }
-
- buf.varint(uint64(slen))
- buf.pos += copy(buf.arr[buf.pos:], s[:slen])
-
- bufp.set(buf)
- return id, bufp
-}
-
-// varint appends v to buf in little-endian-base-128 encoding.
-func (buf *traceBuf) varint(v uint64) {
- pos := buf.pos
- for ; v >= 0x80; v >>= 7 {
- buf.arr[pos] = 0x80 | byte(v)
- pos++
- }
- buf.arr[pos] = byte(v)
- pos++
- buf.pos = pos
-}
-
-// varintAt writes varint v at byte position pos in buf. This always
-// consumes traceBytesPerNumber bytes. This is intended for when the
-// caller needs to reserve space for a varint but can't populate it
-// until later.
-func (buf *traceBuf) varintAt(pos int, v uint64) {
- for i := 0; i < traceBytesPerNumber; i++ {
- if i < traceBytesPerNumber-1 {
- buf.arr[pos] = 0x80 | byte(v)
- } else {
- buf.arr[pos] = byte(v)
- }
- v >>= 7
- pos++
- }
-}
-
-// byte appends v to buf.
-func (buf *traceBuf) byte(v byte) {
- buf.arr[buf.pos] = v
- buf.pos++
-}
-
-// traceStackTable maps stack traces (arrays of PC's) to unique uint32 ids.
-// It is lock-free for reading.
-type traceStackTable struct {
- lock mutex // Must be acquired on the system stack
- seq uint32
- mem traceAlloc
- tab [1 << 13]traceStackPtr
-}
-
-// traceStack is a single stack in traceStackTable.
-type traceStack struct {
- link traceStackPtr
- hash uintptr
- id uint32
- n int
- stk [0]uintptr // real type [n]uintptr
-}
-
-type traceStackPtr uintptr
-
-func (tp traceStackPtr) ptr() *traceStack { return (*traceStack)(unsafe.Pointer(tp)) }
-
-// stack returns slice of PCs.
-func (ts *traceStack) stack() []uintptr {
- return (*[traceStackSize]uintptr)(unsafe.Pointer(&ts.stk))[:ts.n]
-}
-
-// put returns a unique id for the stack trace pcs and caches it in the table,
-// if it sees the trace for the first time.
-func (tab *traceStackTable) put(pcs []uintptr) uint32 {
- if len(pcs) == 0 {
- return 0
- }
- hash := memhash(unsafe.Pointer(&pcs[0]), 0, uintptr(len(pcs))*unsafe.Sizeof(pcs[0]))
- // First, search the hashtable w/o the mutex.
- if id := tab.find(pcs, hash); id != 0 {
- return id
- }
- // Now, double check under the mutex.
- // Switch to the system stack so we can acquire tab.lock
- var id uint32
- systemstack(func() {
- lock(&tab.lock)
- if id = tab.find(pcs, hash); id != 0 {
- unlock(&tab.lock)
- return
- }
- // Create new record.
- tab.seq++
- stk := tab.newStack(len(pcs))
- stk.hash = hash
- stk.id = tab.seq
- id = stk.id
- stk.n = len(pcs)
- stkpc := stk.stack()
- for i, pc := range pcs {
- stkpc[i] = pc
- }
- part := int(hash % uintptr(len(tab.tab)))
- stk.link = tab.tab[part]
- atomicstorep(unsafe.Pointer(&tab.tab[part]), unsafe.Pointer(stk))
- unlock(&tab.lock)
- })
- return id
-}
-
-// find checks if the stack trace pcs is already present in the table.
-func (tab *traceStackTable) find(pcs []uintptr, hash uintptr) uint32 {
- part := int(hash % uintptr(len(tab.tab)))
-Search:
- for stk := tab.tab[part].ptr(); stk != nil; stk = stk.link.ptr() {
- if stk.hash == hash && stk.n == len(pcs) {
- for i, stkpc := range stk.stack() {
- if stkpc != pcs[i] {
- continue Search
- }
- }
- return stk.id
- }
- }
- return 0
-}
-
-// newStack allocates a new stack of size n.
-func (tab *traceStackTable) newStack(n int) *traceStack {
- return (*traceStack)(tab.mem.alloc(unsafe.Sizeof(traceStack{}) + uintptr(n)*goarch.PtrSize))
-}
-
-// traceFrames returns the frames corresponding to pcs. It may
-// allocate and may emit trace events.
-func traceFrames(bufp traceBufPtr, pcs []uintptr) ([]traceFrame, traceBufPtr) {
- frames := make([]traceFrame, 0, len(pcs))
- ci := CallersFrames(pcs)
- for {
- var frame traceFrame
- f, more := ci.Next()
- frame, bufp = traceFrameForPC(bufp, 0, f)
- frames = append(frames, frame)
- if !more {
- return frames, bufp
- }
- }
-}
-
-// dump writes all previously cached stacks to trace buffers,
-// releases all memory and resets state.
-//
-// This must run on the system stack because it calls traceFlush.
-//
-//go:systemstack
-func (tab *traceStackTable) dump(bufp traceBufPtr) traceBufPtr {
- for i := range tab.tab {
- stk := tab.tab[i].ptr()
- for ; stk != nil; stk = stk.link.ptr() {
- var frames []traceFrame
- frames, bufp = traceFrames(bufp, stk.stack())
-
- // Estimate the size of this record. This
- // bound is pretty loose, but avoids counting
- // lots of varint sizes.
- maxSize := 1 + traceBytesPerNumber + (2+4*len(frames))*traceBytesPerNumber
- // Make sure we have enough buffer space.
- if buf := bufp.ptr(); len(buf.arr)-buf.pos < maxSize {
- bufp = traceFlush(bufp, 0)
- }
-
- // Emit header, with space reserved for length.
- buf := bufp.ptr()
- buf.byte(traceEvStack | 3<<traceArgCountShift)
- lenPos := buf.pos
- buf.pos += traceBytesPerNumber
-
- // Emit body.
- recPos := buf.pos
- buf.varint(uint64(stk.id))
- buf.varint(uint64(len(frames)))
- for _, frame := range frames {
- buf.varint(uint64(frame.PC))
- buf.varint(frame.funcID)
- buf.varint(frame.fileID)
- buf.varint(frame.line)
- }
-
- // Fill in size header.
- buf.varintAt(lenPos, uint64(buf.pos-recPos))
- }
- }
-
- tab.mem.drop()
- *tab = traceStackTable{}
- lockInit(&((*tab).lock), lockRankTraceStackTab)
-
- return bufp
-}
-
-type traceFrame struct {
- PC uintptr
- funcID uint64
- fileID uint64
- line uint64
-}
-
-// traceFrameForPC records the frame information.
-// It may allocate memory.
-func traceFrameForPC(buf traceBufPtr, pid int32, f Frame) (traceFrame, traceBufPtr) {
- bufp := &buf
- var frame traceFrame
- frame.PC = f.PC
-
- fn := f.Function
- const maxLen = 1 << 10
- if len(fn) > maxLen {
- fn = fn[len(fn)-maxLen:]
- }
- frame.funcID, bufp = traceString(bufp, pid, fn)
- frame.line = uint64(f.Line)
- file := f.File
- if len(file) > maxLen {
- file = file[len(file)-maxLen:]
- }
- frame.fileID, bufp = traceString(bufp, pid, file)
- return frame, (*bufp)
-}
-
-// traceAlloc is a non-thread-safe region allocator.
-// It holds a linked list of traceAllocBlock.
-type traceAlloc struct {
- head traceAllocBlockPtr
- off uintptr
-}
-
-// traceAllocBlock is a block in traceAlloc.
-//
-// traceAllocBlock is allocated from non-GC'd memory, so it must not
-// contain heap pointers. Writes to pointers to traceAllocBlocks do
-// not need write barriers.
-type traceAllocBlock struct {
- _ sys.NotInHeap
- next traceAllocBlockPtr
- data [64<<10 - goarch.PtrSize]byte
-}
-
-// TODO: Since traceAllocBlock is now embedded runtime/internal/sys.NotInHeap, this isn't necessary.
-type traceAllocBlockPtr uintptr
-
-func (p traceAllocBlockPtr) ptr() *traceAllocBlock { return (*traceAllocBlock)(unsafe.Pointer(p)) }
-func (p *traceAllocBlockPtr) set(x *traceAllocBlock) { *p = traceAllocBlockPtr(unsafe.Pointer(x)) }
-
-// alloc allocates n-byte block.
-func (a *traceAlloc) alloc(n uintptr) unsafe.Pointer {
- n = alignUp(n, goarch.PtrSize)
- if a.head == 0 || a.off+n > uintptr(len(a.head.ptr().data)) {
- if n > uintptr(len(a.head.ptr().data)) {
- throw("trace: alloc too large")
- }
- block := (*traceAllocBlock)(sysAlloc(unsafe.Sizeof(traceAllocBlock{}), &memstats.other_sys))
- if block == nil {
- throw("trace: out of memory")
- }
- block.next.set(a.head.ptr())
- a.head.set(block)
- a.off = 0
- }
- p := &a.head.ptr().data[a.off]
- a.off += n
- return unsafe.Pointer(p)
-}
-
-// drop frees all previously allocated memory and resets the allocator.
-func (a *traceAlloc) drop() {
- for a.head != 0 {
- block := a.head.ptr()
- a.head.set(block.next.ptr())
- sysFree(unsafe.Pointer(block), unsafe.Sizeof(traceAllocBlock{}), &memstats.other_sys)
- }
-}
-
-// The following functions write specific events to trace.
-
-func traceGomaxprocs(procs int32) {
- traceEvent(traceEvGomaxprocs, 1, uint64(procs))
-}
-
-func traceProcStart() {
- traceEvent(traceEvProcStart, -1, uint64(getg().m.id))
-}
-
-func traceProcStop(pp *p) {
- // Sysmon and stopTheWorld can stop Ps blocked in syscalls,
- // to handle this we temporary employ the P.
- mp := acquirem()
- oldp := mp.p
- mp.p.set(pp)
- traceEvent(traceEvProcStop, -1)
- mp.p = oldp
- releasem(mp)
-}
-
-func traceGCStart() {
- traceEvent(traceEvGCStart, 3, trace.seqGC)
- trace.seqGC++
-}
-
-func traceGCDone() {
- traceEvent(traceEvGCDone, -1)
-}
-
-func traceGCSTWStart(kind int) {
- traceEvent(traceEvGCSTWStart, -1, uint64(kind))
-}
-
-func traceGCSTWDone() {
- traceEvent(traceEvGCSTWDone, -1)
-}
-
-// traceGCSweepStart prepares to trace a sweep loop. This does not
-// emit any events until traceGCSweepSpan is called.
-//
-// traceGCSweepStart must be paired with traceGCSweepDone and there
-// must be no preemption points between these two calls.
-func traceGCSweepStart() {
- // Delay the actual GCSweepStart event until the first span
- // sweep. If we don't sweep anything, don't emit any events.
- pp := getg().m.p.ptr()
- if pp.traceSweep {
- throw("double traceGCSweepStart")
- }
- pp.traceSweep, pp.traceSwept, pp.traceReclaimed = true, 0, 0
-}
-
-// traceGCSweepSpan traces the sweep of a single page.
-//
-// This may be called outside a traceGCSweepStart/traceGCSweepDone
-// pair; however, it will not emit any trace events in this case.
-func traceGCSweepSpan(bytesSwept uintptr) {
- pp := getg().m.p.ptr()
- if pp.traceSweep {
- if pp.traceSwept == 0 {
- traceEvent(traceEvGCSweepStart, 1)
- }
- pp.traceSwept += bytesSwept
- }
-}
-
-func traceGCSweepDone() {
- pp := getg().m.p.ptr()
- if !pp.traceSweep {
- throw("missing traceGCSweepStart")
- }
- if pp.traceSwept != 0 {
- traceEvent(traceEvGCSweepDone, -1, uint64(pp.traceSwept), uint64(pp.traceReclaimed))
- }
- pp.traceSweep = false
-}
-
-func traceGCMarkAssistStart() {
- traceEvent(traceEvGCMarkAssistStart, 1)
-}
-
-func traceGCMarkAssistDone() {
- traceEvent(traceEvGCMarkAssistDone, -1)
-}
-
-func traceGoCreate(newg *g, pc uintptr) {
- newg.traceseq = 0
- newg.tracelastp = getg().m.p
- // +PCQuantum because traceFrameForPC expects return PCs and subtracts PCQuantum.
- id := trace.stackTab.put([]uintptr{startPCforTrace(pc) + sys.PCQuantum})
- traceEvent(traceEvGoCreate, 2, newg.goid, uint64(id))
-}
-
-func traceGoStart() {
- gp := getg().m.curg
- pp := gp.m.p
- gp.traceseq++
- if pp.ptr().gcMarkWorkerMode != gcMarkWorkerNotWorker {
- traceEvent(traceEvGoStartLabel, -1, gp.goid, gp.traceseq, trace.markWorkerLabels[pp.ptr().gcMarkWorkerMode])
- } else if gp.tracelastp == pp {
- traceEvent(traceEvGoStartLocal, -1, gp.goid)
- } else {
- gp.tracelastp = pp
- traceEvent(traceEvGoStart, -1, gp.goid, gp.traceseq)
- }
-}
-
-func traceGoEnd() {
- traceEvent(traceEvGoEnd, -1)
-}
-
-func traceGoSched() {
- gp := getg()
- gp.tracelastp = gp.m.p
- traceEvent(traceEvGoSched, 1)
-}
-
-func traceGoPreempt() {
- gp := getg()
- gp.tracelastp = gp.m.p
- traceEvent(traceEvGoPreempt, 1)
-}
-
-func traceGoPark(traceEv byte, skip int) {
- if traceEv&traceFutileWakeup != 0 {
- traceEvent(traceEvFutileWakeup, -1)
- }
- traceEvent(traceEv & ^traceFutileWakeup, skip)
-}
-
-func traceGoUnpark(gp *g, skip int) {
- pp := getg().m.p
- gp.traceseq++
- if gp.tracelastp == pp {
- traceEvent(traceEvGoUnblockLocal, skip, gp.goid)
- } else {
- gp.tracelastp = pp
- traceEvent(traceEvGoUnblock, skip, gp.goid, gp.traceseq)
- }
-}
-
-func traceGoSysCall() {
- traceEvent(traceEvGoSysCall, 1)
-}
-
-func traceGoSysExit(ts int64) {
- if ts != 0 && ts < trace.ticksStart {
- // There is a race between the code that initializes sysexitticks
- // (in exitsyscall, which runs without a P, and therefore is not
- // stopped with the rest of the world) and the code that initializes
- // a new trace. The recorded sysexitticks must therefore be treated
- // as "best effort". If they are valid for this trace, then great,
- // use them for greater accuracy. But if they're not valid for this
- // trace, assume that the trace was started after the actual syscall
- // exit (but before we actually managed to start the goroutine,
- // aka right now), and assign a fresh time stamp to keep the log consistent.
- ts = 0
- }
- gp := getg().m.curg
- gp.traceseq++
- gp.tracelastp = gp.m.p
- traceEvent(traceEvGoSysExit, -1, gp.goid, gp.traceseq, uint64(ts)/traceTickDiv)
-}
-
-func traceGoSysBlock(pp *p) {
- // Sysmon and stopTheWorld can declare syscalls running on remote Ps as blocked,
- // to handle this we temporary employ the P.
- mp := acquirem()
- oldp := mp.p
- mp.p.set(pp)
- traceEvent(traceEvGoSysBlock, -1)
- mp.p = oldp
- releasem(mp)
-}
-
-func traceHeapAlloc(live uint64) {
- traceEvent(traceEvHeapAlloc, -1, live)
-}
-
-func traceHeapGoal() {
- heapGoal := gcController.heapGoal()
- if heapGoal == ^uint64(0) {
- // Heap-based triggering is disabled.
- traceEvent(traceEvHeapGoal, -1, 0)
- } else {
- traceEvent(traceEvHeapGoal, -1, heapGoal)
- }
-}
-
-// To access runtime functions from runtime/trace.
-// See runtime/trace/annotation.go
-
-//go:linkname trace_userTaskCreate runtime/trace.userTaskCreate
-func trace_userTaskCreate(id, parentID uint64, taskType string) {
- if !trace.enabled {
- return
- }
-
- // Same as in traceEvent.
- mp, pid, bufp := traceAcquireBuffer()
- if !trace.enabled && !mp.startingtrace {
- traceReleaseBuffer(pid)
- return
- }
-
- typeStringID, bufp := traceString(bufp, pid, taskType)
- traceEventLocked(0, mp, pid, bufp, traceEvUserTaskCreate, 0, 3, id, parentID, typeStringID)
- traceReleaseBuffer(pid)
-}
-
-//go:linkname trace_userTaskEnd runtime/trace.userTaskEnd
-func trace_userTaskEnd(id uint64) {
- traceEvent(traceEvUserTaskEnd, 2, id)
-}
-
-//go:linkname trace_userRegion runtime/trace.userRegion
-func trace_userRegion(id, mode uint64, name string) {
- if !trace.enabled {
- return
- }
-
- mp, pid, bufp := traceAcquireBuffer()
- if !trace.enabled && !mp.startingtrace {
- traceReleaseBuffer(pid)
- return
- }
-
- nameStringID, bufp := traceString(bufp, pid, name)
- traceEventLocked(0, mp, pid, bufp, traceEvUserRegion, 0, 3, id, mode, nameStringID)
- traceReleaseBuffer(pid)
-}
-
-//go:linkname trace_userLog runtime/trace.userLog
-func trace_userLog(id uint64, category, message string) {
- if !trace.enabled {
- return
- }
-
- mp, pid, bufp := traceAcquireBuffer()
- if !trace.enabled && !mp.startingtrace {
- traceReleaseBuffer(pid)
- return
- }
-
- categoryID, bufp := traceString(bufp, pid, category)
-
- extraSpace := traceBytesPerNumber + len(message) // extraSpace for the value string
- traceEventLocked(extraSpace, mp, pid, bufp, traceEvUserLog, 0, 3, id, categoryID)
- // traceEventLocked reserved extra space for val and len(val)
- // in buf, so buf now has room for the following.
- buf := bufp.ptr()
-
- // double-check the message and its length can fit.
- // Otherwise, truncate the message.
- slen := len(message)
- if room := len(buf.arr) - buf.pos; room < slen+traceBytesPerNumber {
- slen = room
- }
- buf.varint(uint64(slen))
- buf.pos += copy(buf.arr[buf.pos:], message[:slen])
-
- traceReleaseBuffer(pid)
-}
-
-// the start PC of a goroutine for tracing purposes. If pc is a wrapper,
-// it returns the PC of the wrapped function. Otherwise it returns pc.
-func startPCforTrace(pc uintptr) uintptr {
- f := findfunc(pc)
- if !f.valid() {
- return pc // may happen for locked g in extra M since its pc is 0.
- }
- w := funcdata(f, _FUNCDATA_WrapInfo)
- if w == nil {
- return pc // not a wrapper
- }
- return f.datap.textAddr(*(*uint32)(w))
-}
diff --git a/contrib/go/_std_1.20/src/runtime/trace/annotation.go b/contrib/go/_std_1.20/src/runtime/trace/annotation.go
deleted file mode 100644
index d47cb8573c..0000000000
--- a/contrib/go/_std_1.20/src/runtime/trace/annotation.go
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2018 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 trace
-
-import (
- "context"
- "fmt"
- "sync/atomic"
- _ "unsafe"
-)
-
-type traceContextKey struct{}
-
-// NewTask creates a task instance with the type taskType and returns
-// it along with a Context that carries the task.
-// If the input context contains a task, the new task is its subtask.
-//
-// The taskType is used to classify task instances. Analysis tools
-// like the Go execution tracer may assume there are only a bounded
-// number of unique task types in the system.
-//
-// The returned end function is used to mark the task's end.
-// The trace tool measures task latency as the time between task creation
-// and when the end function is called, and provides the latency
-// distribution per task type.
-// If the end function is called multiple times, only the first
-// call is used in the latency measurement.
-//
-// ctx, task := trace.NewTask(ctx, "awesomeTask")
-// trace.WithRegion(ctx, "preparation", prepWork)
-// // preparation of the task
-// go func() { // continue processing the task in a separate goroutine.
-// defer task.End()
-// trace.WithRegion(ctx, "remainingWork", remainingWork)
-// }()
-func NewTask(pctx context.Context, taskType string) (ctx context.Context, task *Task) {
- pid := fromContext(pctx).id
- id := newID()
- userTaskCreate(id, pid, taskType)
- s := &Task{id: id}
- return context.WithValue(pctx, traceContextKey{}, s), s
-
- // We allocate a new task and the end function even when
- // the tracing is disabled because the context and the detach
- // function can be used across trace enable/disable boundaries,
- // which complicates the problem.
- //
- // For example, consider the following scenario:
- // - trace is enabled.
- // - trace.WithRegion is called, so a new context ctx
- // with a new region is created.
- // - trace is disabled.
- // - trace is enabled again.
- // - trace APIs with the ctx is called. Is the ID in the task
- // a valid one to use?
- //
- // TODO(hyangah): reduce the overhead at least when
- // tracing is disabled. Maybe the id can embed a tracing
- // round number and ignore ids generated from previous
- // tracing round.
-}
-
-func fromContext(ctx context.Context) *Task {
- if s, ok := ctx.Value(traceContextKey{}).(*Task); ok {
- return s
- }
- return &bgTask
-}
-
-// Task is a data type for tracing a user-defined, logical operation.
-type Task struct {
- id uint64
- // TODO(hyangah): record parent id?
-}
-
-// End marks the end of the operation represented by the Task.
-func (t *Task) End() {
- userTaskEnd(t.id)
-}
-
-var lastTaskID uint64 = 0 // task id issued last time
-
-func newID() uint64 {
- // TODO(hyangah): use per-P cache
- return atomic.AddUint64(&lastTaskID, 1)
-}
-
-var bgTask = Task{id: uint64(0)}
-
-// Log emits a one-off event with the given category and message.
-// Category can be empty and the API assumes there are only a handful of
-// unique categories in the system.
-func Log(ctx context.Context, category, message string) {
- id := fromContext(ctx).id
- userLog(id, category, message)
-}
-
-// Logf is like Log, but the value is formatted using the specified format spec.
-func Logf(ctx context.Context, category, format string, args ...any) {
- if IsEnabled() {
- // Ideally this should be just Log, but that will
- // add one more frame in the stack trace.
- id := fromContext(ctx).id
- userLog(id, category, fmt.Sprintf(format, args...))
- }
-}
-
-const (
- regionStartCode = uint64(0)
- regionEndCode = uint64(1)
-)
-
-// WithRegion starts a region associated with its calling goroutine, runs fn,
-// and then ends the region. If the context carries a task, the region is
-// associated with the task. Otherwise, the region is attached to the background
-// task.
-//
-// The regionType is used to classify regions, so there should be only a
-// handful of unique region types.
-func WithRegion(ctx context.Context, regionType string, fn func()) {
- // NOTE:
- // WithRegion helps avoiding misuse of the API but in practice,
- // this is very restrictive:
- // - Use of WithRegion makes the stack traces captured from
- // region start and end are identical.
- // - Refactoring the existing code to use WithRegion is sometimes
- // hard and makes the code less readable.
- // e.g. code block nested deep in the loop with various
- // exit point with return values
- // - Refactoring the code to use this API with closure can
- // cause different GC behavior such as retaining some parameters
- // longer.
- // This causes more churns in code than I hoped, and sometimes
- // makes the code less readable.
-
- id := fromContext(ctx).id
- userRegion(id, regionStartCode, regionType)
- defer userRegion(id, regionEndCode, regionType)
- fn()
-}
-
-// StartRegion starts a region and returns a function for marking the
-// end of the region. The returned Region's End function must be called
-// from the same goroutine where the region was started.
-// Within each goroutine, regions must nest. That is, regions started
-// after this region must be ended before this region can be ended.
-// Recommended usage is
-//
-// defer trace.StartRegion(ctx, "myTracedRegion").End()
-func StartRegion(ctx context.Context, regionType string) *Region {
- if !IsEnabled() {
- return noopRegion
- }
- id := fromContext(ctx).id
- userRegion(id, regionStartCode, regionType)
- return &Region{id, regionType}
-}
-
-// Region is a region of code whose execution time interval is traced.
-type Region struct {
- id uint64
- regionType string
-}
-
-var noopRegion = &Region{}
-
-// End marks the end of the traced code region.
-func (r *Region) End() {
- if r == noopRegion {
- return
- }
- userRegion(r.id, regionEndCode, r.regionType)
-}
-
-// IsEnabled reports whether tracing is enabled.
-// The information is advisory only. The tracing status
-// may have changed by the time this function returns.
-func IsEnabled() bool {
- return tracing.enabled.Load()
-}
-
-//
-// Function bodies are defined in runtime/trace.go
-//
-
-// emits UserTaskCreate event.
-func userTaskCreate(id, parentID uint64, taskType string)
-
-// emits UserTaskEnd event.
-func userTaskEnd(id uint64)
-
-// emits UserRegion event.
-func userRegion(id, mode uint64, regionType string)
-
-// emits UserLog event.
-func userLog(id uint64, category, message string)
diff --git a/contrib/go/_std_1.20/src/runtime/trace/trace.go b/contrib/go/_std_1.20/src/runtime/trace/trace.go
deleted file mode 100644
index 86c97e2a11..0000000000
--- a/contrib/go/_std_1.20/src/runtime/trace/trace.go
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2015 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 trace contains facilities for programs to generate traces
-// for the Go execution tracer.
-//
-// # Tracing runtime activities
-//
-// The execution trace captures a wide range of execution events such as
-// goroutine creation/blocking/unblocking, syscall enter/exit/block,
-// GC-related events, changes of heap size, processor start/stop, etc.
-// When CPU profiling is active, the execution tracer makes an effort to
-// include those samples as well.
-// A precise nanosecond-precision timestamp and a stack trace is
-// captured for most events. The generated trace can be interpreted
-// using `go tool trace`.
-//
-// Support for tracing tests and benchmarks built with the standard
-// testing package is built into `go test`. For example, the following
-// command runs the test in the current directory and writes the trace
-// file (trace.out).
-//
-// go test -trace=trace.out
-//
-// This runtime/trace package provides APIs to add equivalent tracing
-// support to a standalone program. See the Example that demonstrates
-// how to use this API to enable tracing.
-//
-// There is also a standard HTTP interface to trace data. Adding the
-// following line will install a handler under the /debug/pprof/trace URL
-// to download a live trace:
-//
-// import _ "net/http/pprof"
-//
-// See the net/http/pprof package for more details about all of the
-// debug endpoints installed by this import.
-//
-// # User annotation
-//
-// Package trace provides user annotation APIs that can be used to
-// log interesting events during execution.
-//
-// There are three types of user annotations: log messages, regions,
-// and tasks.
-//
-// Log emits a timestamped message to the execution trace along with
-// additional information such as the category of the message and
-// which goroutine called Log. The execution tracer provides UIs to filter
-// and group goroutines using the log category and the message supplied
-// in Log.
-//
-// A region is for logging a time interval during a goroutine's execution.
-// By definition, a region starts and ends in the same goroutine.
-// Regions can be nested to represent subintervals.
-// For example, the following code records four regions in the execution
-// trace to trace the durations of sequential steps in a cappuccino making
-// operation.
-//
-// trace.WithRegion(ctx, "makeCappuccino", func() {
-//
-// // orderID allows to identify a specific order
-// // among many cappuccino order region records.
-// trace.Log(ctx, "orderID", orderID)
-//
-// trace.WithRegion(ctx, "steamMilk", steamMilk)
-// trace.WithRegion(ctx, "extractCoffee", extractCoffee)
-// trace.WithRegion(ctx, "mixMilkCoffee", mixMilkCoffee)
-// })
-//
-// A task is a higher-level component that aids tracing of logical
-// operations such as an RPC request, an HTTP request, or an
-// interesting local operation which may require multiple goroutines
-// working together. Since tasks can involve multiple goroutines,
-// they are tracked via a context.Context object. NewTask creates
-// a new task and embeds it in the returned context.Context object.
-// Log messages and regions are attached to the task, if any, in the
-// Context passed to Log and WithRegion.
-//
-// For example, assume that we decided to froth milk, extract coffee,
-// and mix milk and coffee in separate goroutines. With a task,
-// the trace tool can identify the goroutines involved in a specific
-// cappuccino order.
-//
-// ctx, task := trace.NewTask(ctx, "makeCappuccino")
-// trace.Log(ctx, "orderID", orderID)
-//
-// milk := make(chan bool)
-// espresso := make(chan bool)
-//
-// go func() {
-// trace.WithRegion(ctx, "steamMilk", steamMilk)
-// milk <- true
-// }()
-// go func() {
-// trace.WithRegion(ctx, "extractCoffee", extractCoffee)
-// espresso <- true
-// }()
-// go func() {
-// defer task.End() // When assemble is done, the order is complete.
-// <-espresso
-// <-milk
-// trace.WithRegion(ctx, "mixMilkCoffee", mixMilkCoffee)
-// }()
-//
-// The trace tool computes the latency of a task by measuring the
-// time between the task creation and the task end and provides
-// latency distributions for each task type found in the trace.
-package trace
-
-import (
- "io"
- "runtime"
- "sync"
- "sync/atomic"
-)
-
-// Start enables tracing for the current program.
-// While tracing, the trace will be buffered and written to w.
-// Start returns an error if tracing is already enabled.
-func Start(w io.Writer) error {
- tracing.Lock()
- defer tracing.Unlock()
-
- if err := runtime.StartTrace(); err != nil {
- return err
- }
- go func() {
- for {
- data := runtime.ReadTrace()
- if data == nil {
- break
- }
- w.Write(data)
- }
- }()
- tracing.enabled.Store(true)
- return nil
-}
-
-// Stop stops the current tracing, if any.
-// Stop only returns after all the writes for the trace have completed.
-func Stop() {
- tracing.Lock()
- defer tracing.Unlock()
- tracing.enabled.Store(false)
-
- runtime.StopTrace()
-}
-
-var tracing struct {
- sync.Mutex // gate mutators (Start, Stop)
- enabled atomic.Bool
-}
diff --git a/contrib/go/_std_1.20/src/runtime/trace/ya.make b/contrib/go/_std_1.20/src/runtime/trace/ya.make
deleted file mode 100644
index 410dec4d3e..0000000000
--- a/contrib/go/_std_1.20/src/runtime/trace/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- annotation.go
- trace.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/runtime/traceback.go b/contrib/go/_std_1.20/src/runtime/traceback.go
deleted file mode 100644
index 37f35d5637..0000000000
--- a/contrib/go/_std_1.20/src/runtime/traceback.go
+++ /dev/null
@@ -1,1377 +0,0 @@
-// Copyright 2009 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 runtime
-
-import (
- "internal/bytealg"
- "internal/goarch"
- "runtime/internal/sys"
- "unsafe"
-)
-
-// The code in this file implements stack trace walking for all architectures.
-// The most important fact about a given architecture is whether it uses a link register.
-// On systems with link registers, the prologue for a non-leaf function stores the
-// incoming value of LR at the bottom of the newly allocated stack frame.
-// On systems without link registers (x86), the architecture pushes a return PC during
-// the call instruction, so the return PC ends up above the stack frame.
-// In this file, the return PC is always called LR, no matter how it was found.
-
-const usesLR = sys.MinFrameSize > 0
-
-// Generic traceback. Handles runtime stack prints (pcbuf == nil),
-// the runtime.Callers function (pcbuf != nil), as well as the garbage
-// collector (callback != nil). A little clunky to merge these, but avoids
-// duplicating the code and all its subtlety.
-//
-// The skip argument is only valid with pcbuf != nil and counts the number
-// of logical frames to skip rather than physical frames (with inlining, a
-// PC in pcbuf can represent multiple calls).
-func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max int, callback func(*stkframe, unsafe.Pointer) bool, v unsafe.Pointer, flags uint) int {
- if skip > 0 && callback != nil {
- throw("gentraceback callback cannot be used with non-zero skip")
- }
-
- // Don't call this "g"; it's too easy get "g" and "gp" confused.
- if ourg := getg(); ourg == gp && ourg == ourg.m.curg {
- // The starting sp has been passed in as a uintptr, and the caller may
- // have other uintptr-typed stack references as well.
- // If during one of the calls that got us here or during one of the
- // callbacks below the stack must be grown, all these uintptr references
- // to the stack will not be updated, and gentraceback will continue
- // to inspect the old stack memory, which may no longer be valid.
- // Even if all the variables were updated correctly, it is not clear that
- // we want to expose a traceback that begins on one stack and ends
- // on another stack. That could confuse callers quite a bit.
- // Instead, we require that gentraceback and any other function that
- // accepts an sp for the current goroutine (typically obtained by
- // calling getcallersp) must not run on that goroutine's stack but
- // instead on the g0 stack.
- throw("gentraceback cannot trace user goroutine on its own stack")
- }
- level, _, _ := gotraceback()
-
- if pc0 == ^uintptr(0) && sp0 == ^uintptr(0) { // Signal to fetch saved values from gp.
- if gp.syscallsp != 0 {
- pc0 = gp.syscallpc
- sp0 = gp.syscallsp
- if usesLR {
- lr0 = 0
- }
- } else {
- pc0 = gp.sched.pc
- sp0 = gp.sched.sp
- if usesLR {
- lr0 = gp.sched.lr
- }
- }
- }
-
- nprint := 0
- var frame stkframe
- frame.pc = pc0
- frame.sp = sp0
- if usesLR {
- frame.lr = lr0
- }
- waspanic := false
- cgoCtxt := gp.cgoCtxt
- stack := gp.stack
- printing := pcbuf == nil && callback == nil
-
- // If the PC is zero, it's likely a nil function call.
- // Start in the caller's frame.
- if frame.pc == 0 {
- if usesLR {
- frame.pc = *(*uintptr)(unsafe.Pointer(frame.sp))
- frame.lr = 0
- } else {
- frame.pc = uintptr(*(*uintptr)(unsafe.Pointer(frame.sp)))
- frame.sp += goarch.PtrSize
- }
- }
-
- // runtime/internal/atomic functions call into kernel helpers on
- // arm < 7. See runtime/internal/atomic/sys_linux_arm.s.
- //
- // Start in the caller's frame.
- if GOARCH == "arm" && goarm < 7 && GOOS == "linux" && frame.pc&0xffff0000 == 0xffff0000 {
- // Note that the calls are simple BL without pushing the return
- // address, so we use LR directly.
- //
- // The kernel helpers are frameless leaf functions, so SP and
- // LR are not touched.
- frame.pc = frame.lr
- frame.lr = 0
- }
-
- f := findfunc(frame.pc)
- if !f.valid() {
- if callback != nil || printing {
- print("runtime: g ", gp.goid, ": unknown pc ", hex(frame.pc), "\n")
- tracebackHexdump(stack, &frame, 0)
- }
- if callback != nil {
- throw("unknown pc")
- }
- return 0
- }
- frame.fn = f
-
- var cache pcvalueCache
-
- lastFuncID := funcID_normal
- n := 0
- for n < max {
- // Typically:
- // pc is the PC of the running function.
- // sp is the stack pointer at that program counter.
- // fp is the frame pointer (caller's stack pointer) at that program counter, or nil if unknown.
- // stk is the stack containing sp.
- // The caller's program counter is lr, unless lr is zero, in which case it is *(uintptr*)sp.
- f = frame.fn
- if f.pcsp == 0 {
- // No frame information, must be external function, like race support.
- // See golang.org/issue/13568.
- break
- }
-
- // Compute function info flags.
- flag := f.flag
- if f.funcID == funcID_cgocallback {
- // cgocallback does write SP to switch from the g0 to the curg stack,
- // but it carefully arranges that during the transition BOTH stacks
- // have cgocallback frame valid for unwinding through.
- // So we don't need to exclude it with the other SP-writing functions.
- flag &^= funcFlag_SPWRITE
- }
- if frame.pc == pc0 && frame.sp == sp0 && pc0 == gp.syscallpc && sp0 == gp.syscallsp {
- // Some Syscall functions write to SP, but they do so only after
- // saving the entry PC/SP using entersyscall.
- // Since we are using the entry PC/SP, the later SP write doesn't matter.
- flag &^= funcFlag_SPWRITE
- }
-
- // Found an actual function.
- // Derive frame pointer and link register.
- if frame.fp == 0 {
- // Jump over system stack transitions. If we're on g0 and there's a user
- // goroutine, try to jump. Otherwise this is a regular call.
- // We also defensively check that this won't switch M's on us,
- // which could happen at critical points in the scheduler.
- // This ensures gp.m doesn't change from a stack jump.
- if flags&_TraceJumpStack != 0 && gp == gp.m.g0 && gp.m.curg != nil && gp.m.curg.m == gp.m {
- switch f.funcID {
- case funcID_morestack:
- // morestack does not return normally -- newstack()
- // gogo's to curg.sched. Match that.
- // This keeps morestack() from showing up in the backtrace,
- // but that makes some sense since it'll never be returned
- // to.
- gp = gp.m.curg
- frame.pc = gp.sched.pc
- frame.fn = findfunc(frame.pc)
- f = frame.fn
- flag = f.flag
- frame.lr = gp.sched.lr
- frame.sp = gp.sched.sp
- stack = gp.stack
- cgoCtxt = gp.cgoCtxt
- case funcID_systemstack:
- // systemstack returns normally, so just follow the
- // stack transition.
- if usesLR && funcspdelta(f, frame.pc, &cache) == 0 {
- // We're at the function prologue and the stack
- // switch hasn't happened, or epilogue where we're
- // about to return. Just unwind normally.
- // Do this only on LR machines because on x86
- // systemstack doesn't have an SP delta (the CALL
- // instruction opens the frame), therefore no way
- // to check.
- flag &^= funcFlag_SPWRITE
- break
- }
- gp = gp.m.curg
- frame.sp = gp.sched.sp
- stack = gp.stack
- cgoCtxt = gp.cgoCtxt
- flag &^= funcFlag_SPWRITE
- }
- }
- frame.fp = frame.sp + uintptr(funcspdelta(f, frame.pc, &cache))
- if !usesLR {
- // On x86, call instruction pushes return PC before entering new function.
- frame.fp += goarch.PtrSize
- }
- }
- var flr funcInfo
- if flag&funcFlag_TOPFRAME != 0 {
- // This function marks the top of the stack. Stop the traceback.
- frame.lr = 0
- flr = funcInfo{}
- } else if flag&funcFlag_SPWRITE != 0 && (callback == nil || n > 0) {
- // The function we are in does a write to SP that we don't know
- // how to encode in the spdelta table. Examples include context
- // switch routines like runtime.gogo but also any code that switches
- // to the g0 stack to run host C code. Since we can't reliably unwind
- // the SP (we might not even be on the stack we think we are),
- // we stop the traceback here.
- // This only applies for profiling signals (callback == nil).
- //
- // For a GC stack traversal (callback != nil), we should only see
- // a function when it has voluntarily preempted itself on entry
- // during the stack growth check. In that case, the function has
- // not yet had a chance to do any writes to SP and is safe to unwind.
- // isAsyncSafePoint does not allow assembly functions to be async preempted,
- // and preemptPark double-checks that SPWRITE functions are not async preempted.
- // So for GC stack traversal we leave things alone (this if body does not execute for n == 0)
- // at the bottom frame of the stack. But farther up the stack we'd better not
- // find any.
- if callback != nil {
- println("traceback: unexpected SPWRITE function", funcname(f))
- throw("traceback")
- }
- frame.lr = 0
- flr = funcInfo{}
- } else {
- var lrPtr uintptr
- if usesLR {
- if n == 0 && frame.sp < frame.fp || frame.lr == 0 {
- lrPtr = frame.sp
- frame.lr = *(*uintptr)(unsafe.Pointer(lrPtr))
- }
- } else {
- if frame.lr == 0 {
- lrPtr = frame.fp - goarch.PtrSize
- frame.lr = uintptr(*(*uintptr)(unsafe.Pointer(lrPtr)))
- }
- }
- flr = findfunc(frame.lr)
- if !flr.valid() {
- // This happens if you get a profiling interrupt at just the wrong time.
- // In that context it is okay to stop early.
- // But if callback is set, we're doing a garbage collection and must
- // get everything, so crash loudly.
- doPrint := printing
- if doPrint && gp.m.incgo && f.funcID == funcID_sigpanic {
- // We can inject sigpanic
- // calls directly into C code,
- // in which case we'll see a C
- // return PC. Don't complain.
- doPrint = false
- }
- if callback != nil || doPrint {
- print("runtime: g ", gp.goid, ": unexpected return pc for ", funcname(f), " called from ", hex(frame.lr), "\n")
- tracebackHexdump(stack, &frame, lrPtr)
- }
- if callback != nil {
- throw("unknown caller pc")
- }
- }
- }
-
- frame.varp = frame.fp
- if !usesLR {
- // On x86, call instruction pushes return PC before entering new function.
- frame.varp -= goarch.PtrSize
- }
-
- // For architectures with frame pointers, if there's
- // a frame, then there's a saved frame pointer here.
- //
- // NOTE: This code is not as general as it looks.
- // On x86, the ABI is to save the frame pointer word at the
- // top of the stack frame, so we have to back down over it.
- // On arm64, the frame pointer should be at the bottom of
- // the stack (with R29 (aka FP) = RSP), in which case we would
- // not want to do the subtraction here. But we started out without
- // any frame pointer, and when we wanted to add it, we didn't
- // want to break all the assembly doing direct writes to 8(RSP)
- // to set the first parameter to a called function.
- // So we decided to write the FP link *below* the stack pointer
- // (with R29 = RSP - 8 in Go functions).
- // This is technically ABI-compatible but not standard.
- // And it happens to end up mimicking the x86 layout.
- // Other architectures may make different decisions.
- if frame.varp > frame.sp && framepointer_enabled {
- frame.varp -= goarch.PtrSize
- }
-
- frame.argp = frame.fp + sys.MinFrameSize
-
- // Determine frame's 'continuation PC', where it can continue.
- // Normally this is the return address on the stack, but if sigpanic
- // is immediately below this function on the stack, then the frame
- // stopped executing due to a trap, and frame.pc is probably not
- // a safe point for looking up liveness information. In this panicking case,
- // the function either doesn't return at all (if it has no defers or if the
- // defers do not recover) or it returns from one of the calls to
- // deferproc a second time (if the corresponding deferred func recovers).
- // In the latter case, use a deferreturn call site as the continuation pc.
- frame.continpc = frame.pc
- if waspanic {
- if frame.fn.deferreturn != 0 {
- frame.continpc = frame.fn.entry() + uintptr(frame.fn.deferreturn) + 1
- // Note: this may perhaps keep return variables alive longer than
- // strictly necessary, as we are using "function has a defer statement"
- // as a proxy for "function actually deferred something". It seems
- // to be a minor drawback. (We used to actually look through the
- // gp._defer for a defer corresponding to this function, but that
- // is hard to do with defer records on the stack during a stack copy.)
- // Note: the +1 is to offset the -1 that
- // stack.go:getStackMap does to back up a return
- // address make sure the pc is in the CALL instruction.
- } else {
- frame.continpc = 0
- }
- }
-
- if callback != nil {
- if !callback((*stkframe)(noescape(unsafe.Pointer(&frame))), v) {
- return n
- }
- }
-
- if pcbuf != nil {
- pc := frame.pc
- // backup to CALL instruction to read inlining info (same logic as below)
- tracepc := pc
- // Normally, pc is a return address. In that case, we want to look up
- // file/line information using pc-1, because that is the pc of the
- // call instruction (more precisely, the last byte of the call instruction).
- // Callers expect the pc buffer to contain return addresses and do the
- // same -1 themselves, so we keep pc unchanged.
- // When the pc is from a signal (e.g. profiler or segv) then we want
- // to look up file/line information using pc, and we store pc+1 in the
- // pc buffer so callers can unconditionally subtract 1 before looking up.
- // See issue 34123.
- // The pc can be at function entry when the frame is initialized without
- // actually running code, like runtime.mstart.
- if (n == 0 && flags&_TraceTrap != 0) || waspanic || pc == f.entry() {
- pc++
- } else {
- tracepc--
- }
-
- // If there is inlining info, record the inner frames.
- if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil {
- inltree := (*[1 << 20]inlinedCall)(inldata)
- for {
- ix := pcdatavalue(f, _PCDATA_InlTreeIndex, tracepc, &cache)
- if ix < 0 {
- break
- }
- if inltree[ix].funcID == funcID_wrapper && elideWrapperCalling(lastFuncID) {
- // ignore wrappers
- } else if skip > 0 {
- skip--
- } else if n < max {
- (*[1 << 20]uintptr)(unsafe.Pointer(pcbuf))[n] = pc
- n++
- }
- lastFuncID = inltree[ix].funcID
- // Back up to an instruction in the "caller".
- tracepc = frame.fn.entry() + uintptr(inltree[ix].parentPc)
- pc = tracepc + 1
- }
- }
- // Record the main frame.
- if f.funcID == funcID_wrapper && elideWrapperCalling(lastFuncID) {
- // Ignore wrapper functions (except when they trigger panics).
- } else if skip > 0 {
- skip--
- } else if n < max {
- (*[1 << 20]uintptr)(unsafe.Pointer(pcbuf))[n] = pc
- n++
- }
- lastFuncID = f.funcID
- n-- // offset n++ below
- }
-
- if printing {
- // assume skip=0 for printing.
- //
- // Never elide wrappers if we haven't printed
- // any frames. And don't elide wrappers that
- // called panic rather than the wrapped
- // function. Otherwise, leave them out.
-
- // backup to CALL instruction to read inlining info (same logic as below)
- tracepc := frame.pc
- if (n > 0 || flags&_TraceTrap == 0) && frame.pc > f.entry() && !waspanic {
- tracepc--
- }
- // If there is inlining info, print the inner frames.
- if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil {
- inltree := (*[1 << 20]inlinedCall)(inldata)
- var inlFunc _func
- inlFuncInfo := funcInfo{&inlFunc, f.datap}
- for {
- ix := pcdatavalue(f, _PCDATA_InlTreeIndex, tracepc, nil)
- if ix < 0 {
- break
- }
-
- // Create a fake _func for the
- // inlined function.
- inlFunc.nameOff = inltree[ix].nameOff
- inlFunc.funcID = inltree[ix].funcID
- inlFunc.startLine = inltree[ix].startLine
-
- if (flags&_TraceRuntimeFrames) != 0 || showframe(inlFuncInfo, gp, nprint == 0, inlFuncInfo.funcID, lastFuncID) {
- name := funcname(inlFuncInfo)
- file, line := funcline(f, tracepc)
- print(name, "(...)\n")
- print("\t", file, ":", line, "\n")
- nprint++
- }
- lastFuncID = inltree[ix].funcID
- // Back up to an instruction in the "caller".
- tracepc = frame.fn.entry() + uintptr(inltree[ix].parentPc)
- }
- }
- if (flags&_TraceRuntimeFrames) != 0 || showframe(f, gp, nprint == 0, f.funcID, lastFuncID) {
- // Print during crash.
- // main(0x1, 0x2, 0x3)
- // /home/rsc/go/src/runtime/x.go:23 +0xf
- //
- name := funcname(f)
- file, line := funcline(f, tracepc)
- if name == "runtime.gopanic" {
- name = "panic"
- }
- print(name, "(")
- argp := unsafe.Pointer(frame.argp)
- printArgs(f, argp, tracepc)
- print(")\n")
- print("\t", file, ":", line)
- if frame.pc > f.entry() {
- print(" +", hex(frame.pc-f.entry()))
- }
- if gp.m != nil && gp.m.throwing >= throwTypeRuntime && gp == gp.m.curg || level >= 2 {
- print(" fp=", hex(frame.fp), " sp=", hex(frame.sp), " pc=", hex(frame.pc))
- }
- print("\n")
- nprint++
- }
- lastFuncID = f.funcID
- }
- n++
-
- if f.funcID == funcID_cgocallback && len(cgoCtxt) > 0 {
- ctxt := cgoCtxt[len(cgoCtxt)-1]
- cgoCtxt = cgoCtxt[:len(cgoCtxt)-1]
-
- // skip only applies to Go frames.
- // callback != nil only used when we only care
- // about Go frames.
- if skip == 0 && callback == nil {
- n = tracebackCgoContext(pcbuf, printing, ctxt, n, max)
- }
- }
-
- waspanic = f.funcID == funcID_sigpanic
- injectedCall := waspanic || f.funcID == funcID_asyncPreempt || f.funcID == funcID_debugCallV2
-
- // Do not unwind past the bottom of the stack.
- if !flr.valid() {
- break
- }
-
- if frame.pc == frame.lr && frame.sp == frame.fp {
- // If the next frame is identical to the current frame, we cannot make progress.
- print("runtime: traceback stuck. pc=", hex(frame.pc), " sp=", hex(frame.sp), "\n")
- tracebackHexdump(stack, &frame, frame.sp)
- throw("traceback stuck")
- }
-
- // Unwind to next frame.
- frame.fn = flr
- frame.pc = frame.lr
- frame.lr = 0
- frame.sp = frame.fp
- frame.fp = 0
-
- // On link register architectures, sighandler saves the LR on stack
- // before faking a call.
- if usesLR && injectedCall {
- x := *(*uintptr)(unsafe.Pointer(frame.sp))
- frame.sp += alignUp(sys.MinFrameSize, sys.StackAlign)
- f = findfunc(frame.pc)
- frame.fn = f
- if !f.valid() {
- frame.pc = x
- } else if funcspdelta(f, frame.pc, &cache) == 0 {
- frame.lr = x
- }
- }
- }
-
- if printing {
- n = nprint
- }
-
- // Note that panic != nil is okay here: there can be leftover panics,
- // because the defers on the panic stack do not nest in frame order as
- // they do on the defer stack. If you have:
- //
- // frame 1 defers d1
- // frame 2 defers d2
- // frame 3 defers d3
- // frame 4 panics
- // frame 4's panic starts running defers
- // frame 5, running d3, defers d4
- // frame 5 panics
- // frame 5's panic starts running defers
- // frame 6, running d4, garbage collects
- // frame 6, running d2, garbage collects
- //
- // During the execution of d4, the panic stack is d4 -> d3, which
- // is nested properly, and we'll treat frame 3 as resumable, because we
- // can find d3. (And in fact frame 3 is resumable. If d4 recovers
- // and frame 5 continues running, d3, d3 can recover and we'll
- // resume execution in (returning from) frame 3.)
- //
- // During the execution of d2, however, the panic stack is d2 -> d3,
- // which is inverted. The scan will match d2 to frame 2 but having
- // d2 on the stack until then means it will not match d3 to frame 3.
- // This is okay: if we're running d2, then all the defers after d2 have
- // completed and their corresponding frames are dead. Not finding d3
- // for frame 3 means we'll set frame 3's continpc == 0, which is correct
- // (frame 3 is dead). At the end of the walk the panic stack can thus
- // contain defers (d3 in this case) for dead frames. The inversion here
- // always indicates a dead frame, and the effect of the inversion on the
- // scan is to hide those dead frames, so the scan is still okay:
- // what's left on the panic stack are exactly (and only) the dead frames.
- //
- // We require callback != nil here because only when callback != nil
- // do we know that gentraceback is being called in a "must be correct"
- // context as opposed to a "best effort" context. The tracebacks with
- // callbacks only happen when everything is stopped nicely.
- // At other times, such as when gathering a stack for a profiling signal
- // or when printing a traceback during a crash, everything may not be
- // stopped nicely, and the stack walk may not be able to complete.
- if callback != nil && n < max && frame.sp != gp.stktopsp {
- print("runtime: g", gp.goid, ": frame.sp=", hex(frame.sp), " top=", hex(gp.stktopsp), "\n")
- print("\tstack=[", hex(gp.stack.lo), "-", hex(gp.stack.hi), "] n=", n, " max=", max, "\n")
- throw("traceback did not unwind completely")
- }
-
- return n
-}
-
-// printArgs prints function arguments in traceback.
-func printArgs(f funcInfo, argp unsafe.Pointer, pc uintptr) {
- // The "instruction" of argument printing is encoded in _FUNCDATA_ArgInfo.
- // See cmd/compile/internal/ssagen.emitArgInfo for the description of the
- // encoding.
- // These constants need to be in sync with the compiler.
- const (
- _endSeq = 0xff
- _startAgg = 0xfe
- _endAgg = 0xfd
- _dotdotdot = 0xfc
- _offsetTooLarge = 0xfb
- )
-
- const (
- limit = 10 // print no more than 10 args/components
- maxDepth = 5 // no more than 5 layers of nesting
- maxLen = (maxDepth*3+2)*limit + 1 // max length of _FUNCDATA_ArgInfo (see the compiler side for reasoning)
- )
-
- p := (*[maxLen]uint8)(funcdata(f, _FUNCDATA_ArgInfo))
- if p == nil {
- return
- }
-
- liveInfo := funcdata(f, _FUNCDATA_ArgLiveInfo)
- liveIdx := pcdatavalue(f, _PCDATA_ArgLiveIndex, pc, nil)
- startOffset := uint8(0xff) // smallest offset that needs liveness info (slots with a lower offset is always live)
- if liveInfo != nil {
- startOffset = *(*uint8)(liveInfo)
- }
-
- isLive := func(off, slotIdx uint8) bool {
- if liveInfo == nil || liveIdx <= 0 {
- return true // no liveness info, always live
- }
- if off < startOffset {
- return true
- }
- bits := *(*uint8)(add(liveInfo, uintptr(liveIdx)+uintptr(slotIdx/8)))
- return bits&(1<<(slotIdx%8)) != 0
- }
-
- print1 := func(off, sz, slotIdx uint8) {
- x := readUnaligned64(add(argp, uintptr(off)))
- // mask out irrelevant bits
- if sz < 8 {
- shift := 64 - sz*8
- if goarch.BigEndian {
- x = x >> shift
- } else {
- x = x << shift >> shift
- }
- }
- print(hex(x))
- if !isLive(off, slotIdx) {
- print("?")
- }
- }
-
- start := true
- printcomma := func() {
- if !start {
- print(", ")
- }
- }
- pi := 0
- slotIdx := uint8(0) // register arg spill slot index
-printloop:
- for {
- o := p[pi]
- pi++
- switch o {
- case _endSeq:
- break printloop
- case _startAgg:
- printcomma()
- print("{")
- start = true
- continue
- case _endAgg:
- print("}")
- case _dotdotdot:
- printcomma()
- print("...")
- case _offsetTooLarge:
- printcomma()
- print("_")
- default:
- printcomma()
- sz := p[pi]
- pi++
- print1(o, sz, slotIdx)
- if o >= startOffset {
- slotIdx++
- }
- }
- start = false
- }
-}
-
-// tracebackCgoContext handles tracing back a cgo context value, from
-// the context argument to setCgoTraceback, for the gentraceback
-// function. It returns the new value of n.
-func tracebackCgoContext(pcbuf *uintptr, printing bool, ctxt uintptr, n, max int) int {
- var cgoPCs [32]uintptr
- cgoContextPCs(ctxt, cgoPCs[:])
- var arg cgoSymbolizerArg
- anySymbolized := false
- for _, pc := range cgoPCs {
- if pc == 0 || n >= max {
- break
- }
- if pcbuf != nil {
- (*[1 << 20]uintptr)(unsafe.Pointer(pcbuf))[n] = pc
- }
- if printing {
- if cgoSymbolizer == nil {
- print("non-Go function at pc=", hex(pc), "\n")
- } else {
- c := printOneCgoTraceback(pc, max-n, &arg)
- n += c - 1 // +1 a few lines down
- anySymbolized = true
- }
- }
- n++
- }
- if anySymbolized {
- arg.pc = 0
- callCgoSymbolizer(&arg)
- }
- return n
-}
-
-func printcreatedby(gp *g) {
- // Show what created goroutine, except main goroutine (goid 1).
- pc := gp.gopc
- f := findfunc(pc)
- if f.valid() && showframe(f, gp, false, funcID_normal, funcID_normal) && gp.goid != 1 {
- printcreatedby1(f, pc)
- }
-}
-
-func printcreatedby1(f funcInfo, pc uintptr) {
- print("created by ", funcname(f), "\n")
- tracepc := pc // back up to CALL instruction for funcline.
- if pc > f.entry() {
- tracepc -= sys.PCQuantum
- }
- file, line := funcline(f, tracepc)
- print("\t", file, ":", line)
- if pc > f.entry() {
- print(" +", hex(pc-f.entry()))
- }
- print("\n")
-}
-
-func traceback(pc, sp, lr uintptr, gp *g) {
- traceback1(pc, sp, lr, gp, 0)
-}
-
-// tracebacktrap is like traceback but expects that the PC and SP were obtained
-// from a trap, not from gp->sched or gp->syscallpc/gp->syscallsp or getcallerpc/getcallersp.
-// Because they are from a trap instead of from a saved pair,
-// the initial PC must not be rewound to the previous instruction.
-// (All the saved pairs record a PC that is a return address, so we
-// rewind it into the CALL instruction.)
-// If gp.m.libcall{g,pc,sp} information is available, it uses that information in preference to
-// the pc/sp/lr passed in.
-func tracebacktrap(pc, sp, lr uintptr, gp *g) {
- if gp.m.libcallsp != 0 {
- // We're in C code somewhere, traceback from the saved position.
- traceback1(gp.m.libcallpc, gp.m.libcallsp, 0, gp.m.libcallg.ptr(), 0)
- return
- }
- traceback1(pc, sp, lr, gp, _TraceTrap)
-}
-
-func traceback1(pc, sp, lr uintptr, gp *g, flags uint) {
- // If the goroutine is in cgo, and we have a cgo traceback, print that.
- if iscgo && gp.m != nil && gp.m.ncgo > 0 && gp.syscallsp != 0 && gp.m.cgoCallers != nil && gp.m.cgoCallers[0] != 0 {
- // Lock cgoCallers so that a signal handler won't
- // change it, copy the array, reset it, unlock it.
- // We are locked to the thread and are not running
- // concurrently with a signal handler.
- // We just have to stop a signal handler from interrupting
- // in the middle of our copy.
- gp.m.cgoCallersUse.Store(1)
- cgoCallers := *gp.m.cgoCallers
- gp.m.cgoCallers[0] = 0
- gp.m.cgoCallersUse.Store(0)
-
- printCgoTraceback(&cgoCallers)
- }
-
- if readgstatus(gp)&^_Gscan == _Gsyscall {
- // Override registers if blocked in system call.
- pc = gp.syscallpc
- sp = gp.syscallsp
- flags &^= _TraceTrap
- }
- if gp.m != nil && gp.m.vdsoSP != 0 {
- // Override registers if running in VDSO. This comes after the
- // _Gsyscall check to cover VDSO calls after entersyscall.
- pc = gp.m.vdsoPC
- sp = gp.m.vdsoSP
- flags &^= _TraceTrap
- }
-
- // Print traceback. By default, omits runtime frames.
- // If that means we print nothing at all, repeat forcing all frames printed.
- n := gentraceback(pc, sp, lr, gp, 0, nil, _TracebackMaxFrames, nil, nil, flags)
- if n == 0 && (flags&_TraceRuntimeFrames) == 0 {
- n = gentraceback(pc, sp, lr, gp, 0, nil, _TracebackMaxFrames, nil, nil, flags|_TraceRuntimeFrames)
- }
- if n == _TracebackMaxFrames {
- print("...additional frames elided...\n")
- }
- printcreatedby(gp)
-
- if gp.ancestors == nil {
- return
- }
- for _, ancestor := range *gp.ancestors {
- printAncestorTraceback(ancestor)
- }
-}
-
-// printAncestorTraceback prints the traceback of the given ancestor.
-// TODO: Unify this with gentraceback and CallersFrames.
-func printAncestorTraceback(ancestor ancestorInfo) {
- print("[originating from goroutine ", ancestor.goid, "]:\n")
- for fidx, pc := range ancestor.pcs {
- f := findfunc(pc) // f previously validated
- if showfuncinfo(f, fidx == 0, funcID_normal, funcID_normal) {
- printAncestorTracebackFuncInfo(f, pc)
- }
- }
- if len(ancestor.pcs) == _TracebackMaxFrames {
- print("...additional frames elided...\n")
- }
- // Show what created goroutine, except main goroutine (goid 1).
- f := findfunc(ancestor.gopc)
- if f.valid() && showfuncinfo(f, false, funcID_normal, funcID_normal) && ancestor.goid != 1 {
- printcreatedby1(f, ancestor.gopc)
- }
-}
-
-// printAncestorTracebackFuncInfo prints the given function info at a given pc
-// within an ancestor traceback. The precision of this info is reduced
-// due to only have access to the pcs at the time of the caller
-// goroutine being created.
-func printAncestorTracebackFuncInfo(f funcInfo, pc uintptr) {
- name := funcname(f)
- if inldata := funcdata(f, _FUNCDATA_InlTree); inldata != nil {
- inltree := (*[1 << 20]inlinedCall)(inldata)
- ix := pcdatavalue(f, _PCDATA_InlTreeIndex, pc, nil)
- if ix >= 0 {
- name = funcnameFromNameOff(f, inltree[ix].nameOff)
- }
- }
- file, line := funcline(f, pc)
- if name == "runtime.gopanic" {
- name = "panic"
- }
- print(name, "(...)\n")
- print("\t", file, ":", line)
- if pc > f.entry() {
- print(" +", hex(pc-f.entry()))
- }
- print("\n")
-}
-
-func callers(skip int, pcbuf []uintptr) int {
- sp := getcallersp()
- pc := getcallerpc()
- gp := getg()
- var n int
- systemstack(func() {
- n = gentraceback(pc, sp, 0, gp, skip, &pcbuf[0], len(pcbuf), nil, nil, 0)
- })
- return n
-}
-
-func gcallers(gp *g, skip int, pcbuf []uintptr) int {
- return gentraceback(^uintptr(0), ^uintptr(0), 0, gp, skip, &pcbuf[0], len(pcbuf), nil, nil, 0)
-}
-
-// showframe reports whether the frame with the given characteristics should
-// be printed during a traceback.
-func showframe(f funcInfo, gp *g, firstFrame bool, funcID, childID funcID) bool {
- mp := getg().m
- if mp.throwing >= throwTypeRuntime && gp != nil && (gp == mp.curg || gp == mp.caughtsig.ptr()) {
- return true
- }
- return showfuncinfo(f, firstFrame, funcID, childID)
-}
-
-// showfuncinfo reports whether a function with the given characteristics should
-// be printed during a traceback.
-func showfuncinfo(f funcInfo, firstFrame bool, funcID, childID funcID) bool {
- // Note that f may be a synthesized funcInfo for an inlined
- // function, in which case only nameOff and funcID are set.
-
- level, _, _ := gotraceback()
- if level > 1 {
- // Show all frames.
- return true
- }
-
- if !f.valid() {
- return false
- }
-
- if funcID == funcID_wrapper && elideWrapperCalling(childID) {
- return false
- }
-
- name := funcname(f)
-
- // Special case: always show runtime.gopanic frame
- // in the middle of a stack trace, so that we can
- // see the boundary between ordinary code and
- // panic-induced deferred code.
- // See golang.org/issue/5832.
- if name == "runtime.gopanic" && !firstFrame {
- return true
- }
-
- return bytealg.IndexByteString(name, '.') >= 0 && (!hasPrefix(name, "runtime.") || isExportedRuntime(name))
-}
-
-// isExportedRuntime reports whether name is an exported runtime function.
-// It is only for runtime functions, so ASCII A-Z is fine.
-func isExportedRuntime(name string) bool {
- const n = len("runtime.")
- return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z'
-}
-
-// elideWrapperCalling reports whether a wrapper function that called
-// function id should be elided from stack traces.
-func elideWrapperCalling(id funcID) bool {
- // If the wrapper called a panic function instead of the
- // wrapped function, we want to include it in stacks.
- return !(id == funcID_gopanic || id == funcID_sigpanic || id == funcID_panicwrap)
-}
-
-var gStatusStrings = [...]string{
- _Gidle: "idle",
- _Grunnable: "runnable",
- _Grunning: "running",
- _Gsyscall: "syscall",
- _Gwaiting: "waiting",
- _Gdead: "dead",
- _Gcopystack: "copystack",
- _Gpreempted: "preempted",
-}
-
-func goroutineheader(gp *g) {
- gpstatus := readgstatus(gp)
-
- isScan := gpstatus&_Gscan != 0
- gpstatus &^= _Gscan // drop the scan bit
-
- // Basic string status
- var status string
- if 0 <= gpstatus && gpstatus < uint32(len(gStatusStrings)) {
- status = gStatusStrings[gpstatus]
- } else {
- status = "???"
- }
-
- // Override.
- if gpstatus == _Gwaiting && gp.waitreason != waitReasonZero {
- status = gp.waitreason.String()
- }
-
- // approx time the G is blocked, in minutes
- var waitfor int64
- if (gpstatus == _Gwaiting || gpstatus == _Gsyscall) && gp.waitsince != 0 {
- waitfor = (nanotime() - gp.waitsince) / 60e9
- }
- print("goroutine ", gp.goid, " [", status)
- if isScan {
- print(" (scan)")
- }
- if waitfor >= 1 {
- print(", ", waitfor, " minutes")
- }
- if gp.lockedm != 0 {
- print(", locked to thread")
- }
- print("]:\n")
-}
-
-func tracebackothers(me *g) {
- level, _, _ := gotraceback()
-
- // Show the current goroutine first, if we haven't already.
- curgp := getg().m.curg
- if curgp != nil && curgp != me {
- print("\n")
- goroutineheader(curgp)
- traceback(^uintptr(0), ^uintptr(0), 0, curgp)
- }
-
- // We can't call locking forEachG here because this may be during fatal
- // throw/panic, where locking could be out-of-order or a direct
- // deadlock.
- //
- // Instead, use forEachGRace, which requires no locking. We don't lock
- // against concurrent creation of new Gs, but even with allglock we may
- // miss Gs created after this loop.
- forEachGRace(func(gp *g) {
- if gp == me || gp == curgp || readgstatus(gp) == _Gdead || isSystemGoroutine(gp, false) && level < 2 {
- return
- }
- print("\n")
- goroutineheader(gp)
- // Note: gp.m == getg().m occurs when tracebackothers is called
- // from a signal handler initiated during a systemstack call.
- // The original G is still in the running state, and we want to
- // print its stack.
- if gp.m != getg().m && readgstatus(gp)&^_Gscan == _Grunning {
- print("\tgoroutine running on other thread; stack unavailable\n")
- printcreatedby(gp)
- } else {
- traceback(^uintptr(0), ^uintptr(0), 0, gp)
- }
- })
-}
-
-// tracebackHexdump hexdumps part of stk around frame.sp and frame.fp
-// for debugging purposes. If the address bad is included in the
-// hexdumped range, it will mark it as well.
-func tracebackHexdump(stk stack, frame *stkframe, bad uintptr) {
- const expand = 32 * goarch.PtrSize
- const maxExpand = 256 * goarch.PtrSize
- // Start around frame.sp.
- lo, hi := frame.sp, frame.sp
- // Expand to include frame.fp.
- if frame.fp != 0 && frame.fp < lo {
- lo = frame.fp
- }
- if frame.fp != 0 && frame.fp > hi {
- hi = frame.fp
- }
- // Expand a bit more.
- lo, hi = lo-expand, hi+expand
- // But don't go too far from frame.sp.
- if lo < frame.sp-maxExpand {
- lo = frame.sp - maxExpand
- }
- if hi > frame.sp+maxExpand {
- hi = frame.sp + maxExpand
- }
- // And don't go outside the stack bounds.
- if lo < stk.lo {
- lo = stk.lo
- }
- if hi > stk.hi {
- hi = stk.hi
- }
-
- // Print the hex dump.
- print("stack: frame={sp:", hex(frame.sp), ", fp:", hex(frame.fp), "} stack=[", hex(stk.lo), ",", hex(stk.hi), ")\n")
- hexdumpWords(lo, hi, func(p uintptr) byte {
- switch p {
- case frame.fp:
- return '>'
- case frame.sp:
- return '<'
- case bad:
- return '!'
- }
- return 0
- })
-}
-
-// isSystemGoroutine reports whether the goroutine g must be omitted
-// in stack dumps and deadlock detector. This is any goroutine that
-// starts at a runtime.* entry point, except for runtime.main,
-// runtime.handleAsyncEvent (wasm only) and sometimes runtime.runfinq.
-//
-// If fixed is true, any goroutine that can vary between user and
-// system (that is, the finalizer goroutine) is considered a user
-// goroutine.
-func isSystemGoroutine(gp *g, fixed bool) bool {
- // Keep this in sync with internal/trace.IsSystemGoroutine.
- f := findfunc(gp.startpc)
- if !f.valid() {
- return false
- }
- if f.funcID == funcID_runtime_main || f.funcID == funcID_handleAsyncEvent {
- return false
- }
- if f.funcID == funcID_runfinq {
- // We include the finalizer goroutine if it's calling
- // back into user code.
- if fixed {
- // This goroutine can vary. In fixed mode,
- // always consider it a user goroutine.
- return false
- }
- return fingStatus.Load()&fingRunningFinalizer == 0
- }
- return hasPrefix(funcname(f), "runtime.")
-}
-
-// SetCgoTraceback records three C functions to use to gather
-// traceback information from C code and to convert that traceback
-// information into symbolic information. These are used when printing
-// stack traces for a program that uses cgo.
-//
-// The traceback and context functions may be called from a signal
-// handler, and must therefore use only async-signal safe functions.
-// The symbolizer function may be called while the program is
-// crashing, and so must be cautious about using memory. None of the
-// functions may call back into Go.
-//
-// The context function will be called with a single argument, a
-// pointer to a struct:
-//
-// struct {
-// Context uintptr
-// }
-//
-// In C syntax, this struct will be
-//
-// struct {
-// uintptr_t Context;
-// };
-//
-// If the Context field is 0, the context function is being called to
-// record the current traceback context. It should record in the
-// Context field whatever information is needed about the current
-// point of execution to later produce a stack trace, probably the
-// stack pointer and PC. In this case the context function will be
-// called from C code.
-//
-// If the Context field is not 0, then it is a value returned by a
-// previous call to the context function. This case is called when the
-// context is no longer needed; that is, when the Go code is returning
-// to its C code caller. This permits the context function to release
-// any associated resources.
-//
-// While it would be correct for the context function to record a
-// complete a stack trace whenever it is called, and simply copy that
-// out in the traceback function, in a typical program the context
-// function will be called many times without ever recording a
-// traceback for that context. Recording a complete stack trace in a
-// call to the context function is likely to be inefficient.
-//
-// The traceback function will be called with a single argument, a
-// pointer to a struct:
-//
-// struct {
-// Context uintptr
-// SigContext uintptr
-// Buf *uintptr
-// Max uintptr
-// }
-//
-// In C syntax, this struct will be
-//
-// struct {
-// uintptr_t Context;
-// uintptr_t SigContext;
-// uintptr_t* Buf;
-// uintptr_t Max;
-// };
-//
-// The Context field will be zero to gather a traceback from the
-// current program execution point. In this case, the traceback
-// function will be called from C code.
-//
-// Otherwise Context will be a value previously returned by a call to
-// the context function. The traceback function should gather a stack
-// trace from that saved point in the program execution. The traceback
-// function may be called from an execution thread other than the one
-// that recorded the context, but only when the context is known to be
-// valid and unchanging. The traceback function may also be called
-// deeper in the call stack on the same thread that recorded the
-// context. The traceback function may be called multiple times with
-// the same Context value; it will usually be appropriate to cache the
-// result, if possible, the first time this is called for a specific
-// context value.
-//
-// If the traceback function is called from a signal handler on a Unix
-// system, SigContext will be the signal context argument passed to
-// the signal handler (a C ucontext_t* cast to uintptr_t). This may be
-// used to start tracing at the point where the signal occurred. If
-// the traceback function is not called from a signal handler,
-// SigContext will be zero.
-//
-// Buf is where the traceback information should be stored. It should
-// be PC values, such that Buf[0] is the PC of the caller, Buf[1] is
-// the PC of that function's caller, and so on. Max is the maximum
-// number of entries to store. The function should store a zero to
-// indicate the top of the stack, or that the caller is on a different
-// stack, presumably a Go stack.
-//
-// Unlike runtime.Callers, the PC values returned should, when passed
-// to the symbolizer function, return the file/line of the call
-// instruction. No additional subtraction is required or appropriate.
-//
-// On all platforms, the traceback function is invoked when a call from
-// Go to C to Go requests a stack trace. On linux/amd64, linux/ppc64le,
-// linux/arm64, and freebsd/amd64, the traceback function is also invoked
-// when a signal is received by a thread that is executing a cgo call.
-// The traceback function should not make assumptions about when it is
-// called, as future versions of Go may make additional calls.
-//
-// The symbolizer function will be called with a single argument, a
-// pointer to a struct:
-//
-// struct {
-// PC uintptr // program counter to fetch information for
-// File *byte // file name (NUL terminated)
-// Lineno uintptr // line number
-// Func *byte // function name (NUL terminated)
-// Entry uintptr // function entry point
-// More uintptr // set non-zero if more info for this PC
-// Data uintptr // unused by runtime, available for function
-// }
-//
-// In C syntax, this struct will be
-//
-// struct {
-// uintptr_t PC;
-// char* File;
-// uintptr_t Lineno;
-// char* Func;
-// uintptr_t Entry;
-// uintptr_t More;
-// uintptr_t Data;
-// };
-//
-// The PC field will be a value returned by a call to the traceback
-// function.
-//
-// The first time the function is called for a particular traceback,
-// all the fields except PC will be 0. The function should fill in the
-// other fields if possible, setting them to 0/nil if the information
-// is not available. The Data field may be used to store any useful
-// information across calls. The More field should be set to non-zero
-// if there is more information for this PC, zero otherwise. If More
-// is set non-zero, the function will be called again with the same
-// PC, and may return different information (this is intended for use
-// with inlined functions). If More is zero, the function will be
-// called with the next PC value in the traceback. When the traceback
-// is complete, the function will be called once more with PC set to
-// zero; this may be used to free any information. Each call will
-// leave the fields of the struct set to the same values they had upon
-// return, except for the PC field when the More field is zero. The
-// function must not keep a copy of the struct pointer between calls.
-//
-// When calling SetCgoTraceback, the version argument is the version
-// number of the structs that the functions expect to receive.
-// Currently this must be zero.
-//
-// The symbolizer function may be nil, in which case the results of
-// the traceback function will be displayed as numbers. If the
-// traceback function is nil, the symbolizer function will never be
-// called. The context function may be nil, in which case the
-// traceback function will only be called with the context field set
-// to zero. If the context function is nil, then calls from Go to C
-// to Go will not show a traceback for the C portion of the call stack.
-//
-// SetCgoTraceback should be called only once, ideally from an init function.
-func SetCgoTraceback(version int, traceback, context, symbolizer unsafe.Pointer) {
- if version != 0 {
- panic("unsupported version")
- }
-
- if cgoTraceback != nil && cgoTraceback != traceback ||
- cgoContext != nil && cgoContext != context ||
- cgoSymbolizer != nil && cgoSymbolizer != symbolizer {
- panic("call SetCgoTraceback only once")
- }
-
- cgoTraceback = traceback
- cgoContext = context
- cgoSymbolizer = symbolizer
-
- // The context function is called when a C function calls a Go
- // function. As such it is only called by C code in runtime/cgo.
- if _cgo_set_context_function != nil {
- cgocall(_cgo_set_context_function, context)
- }
-}
-
-var cgoTraceback unsafe.Pointer
-var cgoContext unsafe.Pointer
-var cgoSymbolizer unsafe.Pointer
-
-// cgoTracebackArg is the type passed to cgoTraceback.
-type cgoTracebackArg struct {
- context uintptr
- sigContext uintptr
- buf *uintptr
- max uintptr
-}
-
-// cgoContextArg is the type passed to the context function.
-type cgoContextArg struct {
- context uintptr
-}
-
-// cgoSymbolizerArg is the type passed to cgoSymbolizer.
-type cgoSymbolizerArg struct {
- pc uintptr
- file *byte
- lineno uintptr
- funcName *byte
- entry uintptr
- more uintptr
- data uintptr
-}
-
-// printCgoTraceback prints a traceback of callers.
-func printCgoTraceback(callers *cgoCallers) {
- if cgoSymbolizer == nil {
- for _, c := range callers {
- if c == 0 {
- break
- }
- print("non-Go function at pc=", hex(c), "\n")
- }
- return
- }
-
- var arg cgoSymbolizerArg
- for _, c := range callers {
- if c == 0 {
- break
- }
- printOneCgoTraceback(c, 0x7fffffff, &arg)
- }
- arg.pc = 0
- callCgoSymbolizer(&arg)
-}
-
-// printOneCgoTraceback prints the traceback of a single cgo caller.
-// This can print more than one line because of inlining.
-// Returns the number of frames printed.
-func printOneCgoTraceback(pc uintptr, max int, arg *cgoSymbolizerArg) int {
- c := 0
- arg.pc = pc
- for c <= max {
- callCgoSymbolizer(arg)
- if arg.funcName != nil {
- // Note that we don't print any argument
- // information here, not even parentheses.
- // The symbolizer must add that if appropriate.
- println(gostringnocopy(arg.funcName))
- } else {
- println("non-Go function")
- }
- print("\t")
- if arg.file != nil {
- print(gostringnocopy(arg.file), ":", arg.lineno, " ")
- }
- print("pc=", hex(pc), "\n")
- c++
- if arg.more == 0 {
- break
- }
- }
- return c
-}
-
-// callCgoSymbolizer calls the cgoSymbolizer function.
-func callCgoSymbolizer(arg *cgoSymbolizerArg) {
- call := cgocall
- if panicking.Load() > 0 || getg().m.curg != getg() {
- // We do not want to call into the scheduler when panicking
- // or when on the system stack.
- call = asmcgocall
- }
- if msanenabled {
- msanwrite(unsafe.Pointer(arg), unsafe.Sizeof(cgoSymbolizerArg{}))
- }
- if asanenabled {
- asanwrite(unsafe.Pointer(arg), unsafe.Sizeof(cgoSymbolizerArg{}))
- }
- call(cgoSymbolizer, noescape(unsafe.Pointer(arg)))
-}
-
-// cgoContextPCs gets the PC values from a cgo traceback.
-func cgoContextPCs(ctxt uintptr, buf []uintptr) {
- if cgoTraceback == nil {
- return
- }
- call := cgocall
- if panicking.Load() > 0 || getg().m.curg != getg() {
- // We do not want to call into the scheduler when panicking
- // or when on the system stack.
- call = asmcgocall
- }
- arg := cgoTracebackArg{
- context: ctxt,
- buf: (*uintptr)(noescape(unsafe.Pointer(&buf[0]))),
- max: uintptr(len(buf)),
- }
- if msanenabled {
- msanwrite(unsafe.Pointer(&arg), unsafe.Sizeof(arg))
- }
- if asanenabled {
- asanwrite(unsafe.Pointer(&arg), unsafe.Sizeof(arg))
- }
- call(cgoTraceback, noescape(unsafe.Pointer(&arg)))
-}
diff --git a/contrib/go/_std_1.20/src/runtime/type.go b/contrib/go/_std_1.20/src/runtime/type.go
deleted file mode 100644
index 1c6103e6ed..0000000000
--- a/contrib/go/_std_1.20/src/runtime/type.go
+++ /dev/null
@@ -1,713 +0,0 @@
-// Copyright 2009 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.
-
-// Runtime type representation.
-
-package runtime
-
-import (
- "internal/abi"
- "unsafe"
-)
-
-// tflag is documented in reflect/type.go.
-//
-// tflag values must be kept in sync with copies in:
-//
-// cmd/compile/internal/reflectdata/reflect.go
-// cmd/link/internal/ld/decodesym.go
-// reflect/type.go
-// internal/reflectlite/type.go
-type tflag uint8
-
-const (
- tflagUncommon tflag = 1 << 0
- tflagExtraStar tflag = 1 << 1
- tflagNamed tflag = 1 << 2
- tflagRegularMemory tflag = 1 << 3 // equal and hash can treat values of this type as a single region of t.size bytes
-)
-
-// Needs to be in sync with ../cmd/link/internal/ld/decodesym.go:/^func.commonsize,
-// ../cmd/compile/internal/reflectdata/reflect.go:/^func.dcommontype and
-// ../reflect/type.go:/^type.rtype.
-// ../internal/reflectlite/type.go:/^type.rtype.
-type _type struct {
- size uintptr
- ptrdata uintptr // size of memory prefix holding all pointers
- hash uint32
- tflag tflag
- align uint8
- fieldAlign uint8
- kind uint8
- // function for comparing objects of this type
- // (ptr to object A, ptr to object B) -> ==?
- equal func(unsafe.Pointer, unsafe.Pointer) bool
- // gcdata stores the GC type data for the garbage collector.
- // If the KindGCProg bit is set in kind, gcdata is a GC program.
- // Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
- gcdata *byte
- str nameOff
- ptrToThis typeOff
-}
-
-func (t *_type) string() string {
- s := t.nameOff(t.str).name()
- if t.tflag&tflagExtraStar != 0 {
- return s[1:]
- }
- return s
-}
-
-func (t *_type) uncommon() *uncommontype {
- if t.tflag&tflagUncommon == 0 {
- return nil
- }
- switch t.kind & kindMask {
- case kindStruct:
- type u struct {
- structtype
- u uncommontype
- }
- return &(*u)(unsafe.Pointer(t)).u
- case kindPtr:
- type u struct {
- ptrtype
- u uncommontype
- }
- return &(*u)(unsafe.Pointer(t)).u
- case kindFunc:
- type u struct {
- functype
- u uncommontype
- }
- return &(*u)(unsafe.Pointer(t)).u
- case kindSlice:
- type u struct {
- slicetype
- u uncommontype
- }
- return &(*u)(unsafe.Pointer(t)).u
- case kindArray:
- type u struct {
- arraytype
- u uncommontype
- }
- return &(*u)(unsafe.Pointer(t)).u
- case kindChan:
- type u struct {
- chantype
- u uncommontype
- }
- return &(*u)(unsafe.Pointer(t)).u
- case kindMap:
- type u struct {
- maptype
- u uncommontype
- }
- return &(*u)(unsafe.Pointer(t)).u
- case kindInterface:
- type u struct {
- interfacetype
- u uncommontype
- }
- return &(*u)(unsafe.Pointer(t)).u
- default:
- type u struct {
- _type
- u uncommontype
- }
- return &(*u)(unsafe.Pointer(t)).u
- }
-}
-
-func (t *_type) name() string {
- if t.tflag&tflagNamed == 0 {
- return ""
- }
- s := t.string()
- i := len(s) - 1
- sqBrackets := 0
- for i >= 0 && (s[i] != '.' || sqBrackets != 0) {
- switch s[i] {
- case ']':
- sqBrackets++
- case '[':
- sqBrackets--
- }
- i--
- }
- return s[i+1:]
-}
-
-// pkgpath returns the path of the package where t was defined, if
-// available. This is not the same as the reflect package's PkgPath
-// method, in that it returns the package path for struct and interface
-// types, not just named types.
-func (t *_type) pkgpath() string {
- if u := t.uncommon(); u != nil {
- return t.nameOff(u.pkgpath).name()
- }
- switch t.kind & kindMask {
- case kindStruct:
- st := (*structtype)(unsafe.Pointer(t))
- return st.pkgPath.name()
- case kindInterface:
- it := (*interfacetype)(unsafe.Pointer(t))
- return it.pkgpath.name()
- }
- return ""
-}
-
-// reflectOffs holds type offsets defined at run time by the reflect package.
-//
-// When a type is defined at run time, its *rtype data lives on the heap.
-// There are a wide range of possible addresses the heap may use, that
-// may not be representable as a 32-bit offset. Moreover the GC may
-// one day start moving heap memory, in which case there is no stable
-// offset that can be defined.
-//
-// To provide stable offsets, we add pin *rtype objects in a global map
-// and treat the offset as an identifier. We use negative offsets that
-// do not overlap with any compile-time module offsets.
-//
-// Entries are created by reflect.addReflectOff.
-var reflectOffs struct {
- lock mutex
- next int32
- m map[int32]unsafe.Pointer
- minv map[unsafe.Pointer]int32
-}
-
-func reflectOffsLock() {
- lock(&reflectOffs.lock)
- if raceenabled {
- raceacquire(unsafe.Pointer(&reflectOffs.lock))
- }
-}
-
-func reflectOffsUnlock() {
- if raceenabled {
- racerelease(unsafe.Pointer(&reflectOffs.lock))
- }
- unlock(&reflectOffs.lock)
-}
-
-func resolveNameOff(ptrInModule unsafe.Pointer, off nameOff) name {
- if off == 0 {
- return name{}
- }
- base := uintptr(ptrInModule)
- for md := &firstmoduledata; md != nil; md = md.next {
- if base >= md.types && base < md.etypes {
- res := md.types + uintptr(off)
- if res > md.etypes {
- println("runtime: nameOff", hex(off), "out of range", hex(md.types), "-", hex(md.etypes))
- throw("runtime: name offset out of range")
- }
- return name{(*byte)(unsafe.Pointer(res))}
- }
- }
-
- // No module found. see if it is a run time name.
- reflectOffsLock()
- res, found := reflectOffs.m[int32(off)]
- reflectOffsUnlock()
- if !found {
- println("runtime: nameOff", hex(off), "base", hex(base), "not in ranges:")
- for next := &firstmoduledata; next != nil; next = next.next {
- println("\ttypes", hex(next.types), "etypes", hex(next.etypes))
- }
- throw("runtime: name offset base pointer out of range")
- }
- return name{(*byte)(res)}
-}
-
-func (t *_type) nameOff(off nameOff) name {
- return resolveNameOff(unsafe.Pointer(t), off)
-}
-
-func resolveTypeOff(ptrInModule unsafe.Pointer, off typeOff) *_type {
- if off == 0 || off == -1 {
- // -1 is the sentinel value for unreachable code.
- // See cmd/link/internal/ld/data.go:relocsym.
- return nil
- }
- base := uintptr(ptrInModule)
- var md *moduledata
- for next := &firstmoduledata; next != nil; next = next.next {
- if base >= next.types && base < next.etypes {
- md = next
- break
- }
- }
- if md == nil {
- reflectOffsLock()
- res := reflectOffs.m[int32(off)]
- reflectOffsUnlock()
- if res == nil {
- println("runtime: typeOff", hex(off), "base", hex(base), "not in ranges:")
- for next := &firstmoduledata; next != nil; next = next.next {
- println("\ttypes", hex(next.types), "etypes", hex(next.etypes))
- }
- throw("runtime: type offset base pointer out of range")
- }
- return (*_type)(res)
- }
- if t := md.typemap[off]; t != nil {
- return t
- }
- res := md.types + uintptr(off)
- if res > md.etypes {
- println("runtime: typeOff", hex(off), "out of range", hex(md.types), "-", hex(md.etypes))
- throw("runtime: type offset out of range")
- }
- return (*_type)(unsafe.Pointer(res))
-}
-
-func (t *_type) typeOff(off typeOff) *_type {
- return resolveTypeOff(unsafe.Pointer(t), off)
-}
-
-func (t *_type) textOff(off textOff) unsafe.Pointer {
- if off == -1 {
- // -1 is the sentinel value for unreachable code.
- // See cmd/link/internal/ld/data.go:relocsym.
- return unsafe.Pointer(abi.FuncPCABIInternal(unreachableMethod))
- }
- base := uintptr(unsafe.Pointer(t))
- var md *moduledata
- for next := &firstmoduledata; next != nil; next = next.next {
- if base >= next.types && base < next.etypes {
- md = next
- break
- }
- }
- if md == nil {
- reflectOffsLock()
- res := reflectOffs.m[int32(off)]
- reflectOffsUnlock()
- if res == nil {
- println("runtime: textOff", hex(off), "base", hex(base), "not in ranges:")
- for next := &firstmoduledata; next != nil; next = next.next {
- println("\ttypes", hex(next.types), "etypes", hex(next.etypes))
- }
- throw("runtime: text offset base pointer out of range")
- }
- return res
- }
- res := md.textAddr(uint32(off))
- return unsafe.Pointer(res)
-}
-
-func (t *functype) in() []*_type {
- // See funcType in reflect/type.go for details on data layout.
- uadd := uintptr(unsafe.Sizeof(functype{}))
- if t.typ.tflag&tflagUncommon != 0 {
- uadd += unsafe.Sizeof(uncommontype{})
- }
- return (*[1 << 20]*_type)(add(unsafe.Pointer(t), uadd))[:t.inCount]
-}
-
-func (t *functype) out() []*_type {
- // See funcType in reflect/type.go for details on data layout.
- uadd := uintptr(unsafe.Sizeof(functype{}))
- if t.typ.tflag&tflagUncommon != 0 {
- uadd += unsafe.Sizeof(uncommontype{})
- }
- outCount := t.outCount & (1<<15 - 1)
- return (*[1 << 20]*_type)(add(unsafe.Pointer(t), uadd))[t.inCount : t.inCount+outCount]
-}
-
-func (t *functype) dotdotdot() bool {
- return t.outCount&(1<<15) != 0
-}
-
-type nameOff int32
-type typeOff int32
-type textOff int32
-
-type method struct {
- name nameOff
- mtyp typeOff
- ifn textOff
- tfn textOff
-}
-
-type uncommontype struct {
- pkgpath nameOff
- mcount uint16 // number of methods
- xcount uint16 // number of exported methods
- moff uint32 // offset from this uncommontype to [mcount]method
- _ uint32 // unused
-}
-
-type imethod struct {
- name nameOff
- ityp typeOff
-}
-
-type interfacetype struct {
- typ _type
- pkgpath name
- mhdr []imethod
-}
-
-type maptype struct {
- typ _type
- key *_type
- elem *_type
- bucket *_type // internal type representing a hash bucket
- // function for hashing keys (ptr to key, seed) -> hash
- hasher func(unsafe.Pointer, uintptr) uintptr
- keysize uint8 // size of key slot
- elemsize uint8 // size of elem slot
- bucketsize uint16 // size of bucket
- flags uint32
-}
-
-// Note: flag values must match those used in the TMAP case
-// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
-func (mt *maptype) indirectkey() bool { // store ptr to key instead of key itself
- return mt.flags&1 != 0
-}
-func (mt *maptype) indirectelem() bool { // store ptr to elem instead of elem itself
- return mt.flags&2 != 0
-}
-func (mt *maptype) reflexivekey() bool { // true if k==k for all keys
- return mt.flags&4 != 0
-}
-func (mt *maptype) needkeyupdate() bool { // true if we need to update key on an overwrite
- return mt.flags&8 != 0
-}
-func (mt *maptype) hashMightPanic() bool { // true if hash function might panic
- return mt.flags&16 != 0
-}
-
-type arraytype struct {
- typ _type
- elem *_type
- slice *_type
- len uintptr
-}
-
-type chantype struct {
- typ _type
- elem *_type
- dir uintptr
-}
-
-type slicetype struct {
- typ _type
- elem *_type
-}
-
-type functype struct {
- typ _type
- inCount uint16
- outCount uint16
-}
-
-type ptrtype struct {
- typ _type
- elem *_type
-}
-
-type structfield struct {
- name name
- typ *_type
- offset uintptr
-}
-
-type structtype struct {
- typ _type
- pkgPath name
- fields []structfield
-}
-
-// name is an encoded type name with optional extra data.
-// See reflect/type.go for details.
-type name struct {
- bytes *byte
-}
-
-func (n name) data(off int) *byte {
- return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off)))
-}
-
-func (n name) isExported() bool {
- return (*n.bytes)&(1<<0) != 0
-}
-
-func (n name) isEmbedded() bool {
- return (*n.bytes)&(1<<3) != 0
-}
-
-func (n name) readvarint(off int) (int, int) {
- v := 0
- for i := 0; ; i++ {
- x := *n.data(off + i)
- v += int(x&0x7f) << (7 * i)
- if x&0x80 == 0 {
- return i + 1, v
- }
- }
-}
-
-func (n name) name() string {
- if n.bytes == nil {
- return ""
- }
- i, l := n.readvarint(1)
- if l == 0 {
- return ""
- }
- return unsafe.String(n.data(1+i), l)
-}
-
-func (n name) tag() string {
- if *n.data(0)&(1<<1) == 0 {
- return ""
- }
- i, l := n.readvarint(1)
- i2, l2 := n.readvarint(1 + i + l)
- return unsafe.String(n.data(1+i+l+i2), l2)
-}
-
-func (n name) pkgPath() string {
- if n.bytes == nil || *n.data(0)&(1<<2) == 0 {
- return ""
- }
- i, l := n.readvarint(1)
- off := 1 + i + l
- if *n.data(0)&(1<<1) != 0 {
- i2, l2 := n.readvarint(off)
- off += i2 + l2
- }
- var nameOff nameOff
- copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.data(off)))[:])
- pkgPathName := resolveNameOff(unsafe.Pointer(n.bytes), nameOff)
- return pkgPathName.name()
-}
-
-func (n name) isBlank() bool {
- if n.bytes == nil {
- return false
- }
- _, l := n.readvarint(1)
- return l == 1 && *n.data(2) == '_'
-}
-
-// typelinksinit scans the types from extra modules and builds the
-// moduledata typemap used to de-duplicate type pointers.
-func typelinksinit() {
- if firstmoduledata.next == nil {
- return
- }
- typehash := make(map[uint32][]*_type, len(firstmoduledata.typelinks))
-
- modules := activeModules()
- prev := modules[0]
- for _, md := range modules[1:] {
- // Collect types from the previous module into typehash.
- collect:
- for _, tl := range prev.typelinks {
- var t *_type
- if prev.typemap == nil {
- t = (*_type)(unsafe.Pointer(prev.types + uintptr(tl)))
- } else {
- t = prev.typemap[typeOff(tl)]
- }
- // Add to typehash if not seen before.
- tlist := typehash[t.hash]
- for _, tcur := range tlist {
- if tcur == t {
- continue collect
- }
- }
- typehash[t.hash] = append(tlist, t)
- }
-
- if md.typemap == nil {
- // If any of this module's typelinks match a type from a
- // prior module, prefer that prior type by adding the offset
- // to this module's typemap.
- tm := make(map[typeOff]*_type, len(md.typelinks))
- pinnedTypemaps = append(pinnedTypemaps, tm)
- md.typemap = tm
- for _, tl := range md.typelinks {
- t := (*_type)(unsafe.Pointer(md.types + uintptr(tl)))
- for _, candidate := range typehash[t.hash] {
- seen := map[_typePair]struct{}{}
- if typesEqual(t, candidate, seen) {
- t = candidate
- break
- }
- }
- md.typemap[typeOff(tl)] = t
- }
- }
-
- prev = md
- }
-}
-
-type _typePair struct {
- t1 *_type
- t2 *_type
-}
-
-// typesEqual reports whether two types are equal.
-//
-// Everywhere in the runtime and reflect packages, it is assumed that
-// there is exactly one *_type per Go type, so that pointer equality
-// can be used to test if types are equal. There is one place that
-// breaks this assumption: buildmode=shared. In this case a type can
-// appear as two different pieces of memory. This is hidden from the
-// runtime and reflect package by the per-module typemap built in
-// typelinksinit. It uses typesEqual to map types from later modules
-// back into earlier ones.
-//
-// Only typelinksinit needs this function.
-func typesEqual(t, v *_type, seen map[_typePair]struct{}) bool {
- tp := _typePair{t, v}
- if _, ok := seen[tp]; ok {
- return true
- }
-
- // mark these types as seen, and thus equivalent which prevents an infinite loop if
- // the two types are identical, but recursively defined and loaded from
- // different modules
- seen[tp] = struct{}{}
-
- if t == v {
- return true
- }
- kind := t.kind & kindMask
- if kind != v.kind&kindMask {
- return false
- }
- if t.string() != v.string() {
- return false
- }
- ut := t.uncommon()
- uv := v.uncommon()
- if ut != nil || uv != nil {
- if ut == nil || uv == nil {
- return false
- }
- pkgpatht := t.nameOff(ut.pkgpath).name()
- pkgpathv := v.nameOff(uv.pkgpath).name()
- if pkgpatht != pkgpathv {
- return false
- }
- }
- if kindBool <= kind && kind <= kindComplex128 {
- return true
- }
- switch kind {
- case kindString, kindUnsafePointer:
- return true
- case kindArray:
- at := (*arraytype)(unsafe.Pointer(t))
- av := (*arraytype)(unsafe.Pointer(v))
- return typesEqual(at.elem, av.elem, seen) && at.len == av.len
- case kindChan:
- ct := (*chantype)(unsafe.Pointer(t))
- cv := (*chantype)(unsafe.Pointer(v))
- return ct.dir == cv.dir && typesEqual(ct.elem, cv.elem, seen)
- case kindFunc:
- ft := (*functype)(unsafe.Pointer(t))
- fv := (*functype)(unsafe.Pointer(v))
- if ft.outCount != fv.outCount || ft.inCount != fv.inCount {
- return false
- }
- tin, vin := ft.in(), fv.in()
- for i := 0; i < len(tin); i++ {
- if !typesEqual(tin[i], vin[i], seen) {
- return false
- }
- }
- tout, vout := ft.out(), fv.out()
- for i := 0; i < len(tout); i++ {
- if !typesEqual(tout[i], vout[i], seen) {
- return false
- }
- }
- return true
- case kindInterface:
- it := (*interfacetype)(unsafe.Pointer(t))
- iv := (*interfacetype)(unsafe.Pointer(v))
- if it.pkgpath.name() != iv.pkgpath.name() {
- return false
- }
- if len(it.mhdr) != len(iv.mhdr) {
- return false
- }
- for i := range it.mhdr {
- tm := &it.mhdr[i]
- vm := &iv.mhdr[i]
- // Note the mhdr array can be relocated from
- // another module. See #17724.
- tname := resolveNameOff(unsafe.Pointer(tm), tm.name)
- vname := resolveNameOff(unsafe.Pointer(vm), vm.name)
- if tname.name() != vname.name() {
- return false
- }
- if tname.pkgPath() != vname.pkgPath() {
- return false
- }
- tityp := resolveTypeOff(unsafe.Pointer(tm), tm.ityp)
- vityp := resolveTypeOff(unsafe.Pointer(vm), vm.ityp)
- if !typesEqual(tityp, vityp, seen) {
- return false
- }
- }
- return true
- case kindMap:
- mt := (*maptype)(unsafe.Pointer(t))
- mv := (*maptype)(unsafe.Pointer(v))
- return typesEqual(mt.key, mv.key, seen) && typesEqual(mt.elem, mv.elem, seen)
- case kindPtr:
- pt := (*ptrtype)(unsafe.Pointer(t))
- pv := (*ptrtype)(unsafe.Pointer(v))
- return typesEqual(pt.elem, pv.elem, seen)
- case kindSlice:
- st := (*slicetype)(unsafe.Pointer(t))
- sv := (*slicetype)(unsafe.Pointer(v))
- return typesEqual(st.elem, sv.elem, seen)
- case kindStruct:
- st := (*structtype)(unsafe.Pointer(t))
- sv := (*structtype)(unsafe.Pointer(v))
- if len(st.fields) != len(sv.fields) {
- return false
- }
- if st.pkgPath.name() != sv.pkgPath.name() {
- return false
- }
- for i := range st.fields {
- tf := &st.fields[i]
- vf := &sv.fields[i]
- if tf.name.name() != vf.name.name() {
- return false
- }
- if !typesEqual(tf.typ, vf.typ, seen) {
- return false
- }
- if tf.name.tag() != vf.name.tag() {
- return false
- }
- if tf.offset != vf.offset {
- return false
- }
- if tf.name.isEmbedded() != vf.name.isEmbedded() {
- return false
- }
- }
- return true
- default:
- println("runtime: impossible type kind", kind)
- throw("runtime: impossible type kind")
- return false
- }
-}
diff --git a/contrib/go/_std_1.20/src/runtime/typekind.go b/contrib/go/_std_1.20/src/runtime/typekind.go
deleted file mode 100644
index 7087a9b046..0000000000
--- a/contrib/go/_std_1.20/src/runtime/typekind.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2014 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 runtime
-
-const (
- kindBool = 1 + iota
- kindInt
- kindInt8
- kindInt16
- kindInt32
- kindInt64
- kindUint
- kindUint8
- kindUint16
- kindUint32
- kindUint64
- kindUintptr
- kindFloat32
- kindFloat64
- kindComplex64
- kindComplex128
- kindArray
- kindChan
- kindFunc
- kindInterface
- kindMap
- kindPtr
- kindSlice
- kindString
- kindStruct
- kindUnsafePointer
-
- kindDirectIface = 1 << 5
- kindGCProg = 1 << 6
- kindMask = (1 << 5) - 1
-)
-
-// isDirectIface reports whether t is stored directly in an interface value.
-func isDirectIface(t *_type) bool {
- return t.kind&kindDirectIface != 0
-}
diff --git a/contrib/go/_std_1.20/src/runtime/unsafe.go b/contrib/go/_std_1.20/src/runtime/unsafe.go
deleted file mode 100644
index 54649e8ff5..0000000000
--- a/contrib/go/_std_1.20/src/runtime/unsafe.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2022 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 runtime
-
-import (
- "runtime/internal/math"
- "unsafe"
-)
-
-func unsafestring(ptr unsafe.Pointer, len int) {
- if len < 0 {
- panicunsafestringlen()
- }
-
- if uintptr(len) > -uintptr(ptr) {
- if ptr == nil {
- panicunsafestringnilptr()
- }
- panicunsafestringlen()
- }
-}
-
-// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeString
-func unsafestring64(ptr unsafe.Pointer, len64 int64) {
- len := int(len64)
- if int64(len) != len64 {
- panicunsafestringlen()
- }
- unsafestring(ptr, len)
-}
-
-func unsafestringcheckptr(ptr unsafe.Pointer, len64 int64) {
- unsafestring64(ptr, len64)
-
- // Check that underlying array doesn't straddle multiple heap objects.
- // unsafestring64 has already checked for overflow.
- if checkptrStraddles(ptr, uintptr(len64)) {
- throw("checkptr: unsafe.String result straddles multiple allocations")
- }
-}
-
-func panicunsafestringlen() {
- panic(errorString("unsafe.String: len out of range"))
-}
-
-func panicunsafestringnilptr() {
- panic(errorString("unsafe.String: ptr is nil and len is not zero"))
-}
-
-// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
-func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
- if len < 0 {
- panicunsafeslicelen()
- }
-
- if et.size == 0 {
- if ptr == nil && len > 0 {
- panicunsafeslicenilptr()
- }
- }
-
- mem, overflow := math.MulUintptr(et.size, uintptr(len))
- if overflow || mem > -uintptr(ptr) {
- if ptr == nil {
- panicunsafeslicenilptr()
- }
- panicunsafeslicelen()
- }
-}
-
-// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
-func unsafeslice64(et *_type, ptr unsafe.Pointer, len64 int64) {
- len := int(len64)
- if int64(len) != len64 {
- panicunsafeslicelen()
- }
- unsafeslice(et, ptr, len)
-}
-
-func unsafeslicecheckptr(et *_type, ptr unsafe.Pointer, len64 int64) {
- unsafeslice64(et, ptr, len64)
-
- // Check that underlying array doesn't straddle multiple heap objects.
- // unsafeslice64 has already checked for overflow.
- if checkptrStraddles(ptr, uintptr(len64)*et.size) {
- throw("checkptr: unsafe.Slice result straddles multiple allocations")
- }
-}
-
-func panicunsafeslicelen() {
- panic(errorString("unsafe.Slice: len out of range"))
-}
-
-func panicunsafeslicenilptr() {
- panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
-}
diff --git a/contrib/go/_std_1.20/src/runtime/ya.make b/contrib/go/_std_1.20/src/runtime/ya.make
deleted file mode 100644
index e209a0819b..0000000000
--- a/contrib/go/_std_1.20/src/runtime/ya.make
+++ /dev/null
@@ -1,342 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- alg.go
- arena.go
- asan0.go
- asm.s
- asm_ppc64x.h
- atomic_pointer.go
- cgo.go
- cgocall.go
- cgocallback.go
- cgocheck.go
- chan.go
- checkptr.go
- compiler.go
- complex.go
- covercounter.go
- covermeta.go
- cpuflags.go
- cpuprof.go
- debug.go
- debugcall.go
- debuglog.go
- debuglog_off.go
- env_posix.go
- error.go
- exithook.go
- extern.go
- fastlog2.go
- fastlog2table.go
- float.go
- funcdata.h
- go_tls.h
- hash64.go
- heapdump.go
- histogram.go
- iface.go
- lfstack.go
- lfstack_64bit.go
- lockrank.go
- lockrank_off.go
- malloc.go
- map.go
- map_fast32.go
- map_fast64.go
- map_faststr.go
- mbarrier.go
- mbitmap.go
- mcache.go
- mcentral.go
- mcheckmark.go
- mem.go
- metrics.go
- mfinal.go
- mfixalloc.go
- mgc.go
- mgclimit.go
- mgcmark.go
- mgcpacer.go
- mgcscavenge.go
- mgcstack.go
- mgcsweep.go
- mgcwork.go
- mheap.go
- mpagealloc.go
- mpagealloc_64bit.go
- mpagecache.go
- mpallocbits.go
- mprof.go
- mranges.go
- msan0.go
- msize.go
- mspanset.go
- mstats.go
- mwbbuf.go
- netpoll.go
- os_nonopenbsd.go
- pagetrace_off.go
- panic.go
- plugin.go
- preempt.go
- print.go
- proc.go
- profbuf.go
- proflabel.go
- rdebug.go
- runtime.go
- runtime1.go
- runtime2.go
- runtime_boring.go
- rwmutex.go
- select.go
- sema.go
- sigqueue.go
- sizeclasses.go
- slice.go
- softfloat64.go
- stack.go
- stkframe.go
- string.go
- stubs.go
- symtab.go
- sys_nonppc64x.go
- textflag.h
- time.go
- time_nofake.go
- trace.go
- traceback.go
- type.go
- typekind.go
- unsafe.go
- utf8.go
- write_err.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- asm_arm64.s
- atomic_arm64.s
- cpuflags_arm64.go
- duff_arm64.s
- memclr_arm64.s
- memmove_arm64.s
- preempt_arm64.s
- stubs_arm64.go
- sys_arm64.go
- tls_arm64.h
- tls_arm64.s
- tls_stub.go
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- asm_amd64.h
- asm_amd64.s
- cpuflags_amd64.go
- cputicks.go
- duff_amd64.s
- memclr_amd64.s
- memmove_amd64.s
- preempt_amd64.s
- stubs_amd64.go
- sys_x86.go
- )
-ENDIF()
-
-IF (OS_DARWIN)
- SRCS(
- create_file_unix.go
- lock_sema.go
- mem_darwin.go
- nbpipe_pipe.go
- netpoll_kqueue.go
- os_darwin.go
- os_unix_nonlinux.go
- preempt_nonwindows.go
- relax_stub.go
- retry.go
- security_issetugid.go
- security_unix.go
- signal_darwin.go
- signal_unix.go
- stubs_nonlinux.go
- sys_darwin.go
- sys_libc.go
- timestub.go
- vdso_in_none.go
- )
-
- IF (ARCH_ARM64)
- SRCS(
- defs_darwin_arm64.go
- os_darwin_arm64.go
- rt0_darwin_arm64.s
- signal_arm64.go
- signal_darwin_arm64.go
- sys_darwin_arm64.go
- sys_darwin_arm64.s
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- defs_darwin_amd64.go
- rt0_darwin_amd64.s
- signal_amd64.go
- signal_darwin_amd64.go
- sys_darwin_amd64.s
- tls_stub.go
- )
- ENDIF()
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- cgo_mmap.go
- cgo_sigaction.go
- create_file_unix.go
- lock_futex.go
- mem_linux.go
- nbpipe_pipe2.go
- netpoll_epoll.go
- os_linux.go
- os_linux_generic.go
- preempt_nonwindows.go
- relax_stub.go
- retry.go
- security_linux.go
- security_unix.go
- signal_unix.go
- sigqueue_note.go
- sigtab_linux_generic.go
- stubs2.go
- stubs3.go
- stubs_linux.go
- vdso_elf64.go
- vdso_linux.go
- )
-
- IF (ARCH_ARM64)
- SRCS(
- defs_linux_arm64.go
- os_linux_arm64.go
- rt0_linux_arm64.s
- signal_arm64.go
- signal_linux_arm64.go
- sys_linux_arm64.s
- timestub.go
- timestub2.go
- vdso_linux_arm64.go
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- defs_linux_amd64.go
- os_linux_noauxv.go
- os_linux_x86.go
- rt0_linux_amd64.s
- signal_amd64.go
- signal_linux_amd64.go
- sys_linux_amd64.s
- time_linux_amd64.s
- timeasm.go
- tls_stub.go
- vdso_linux_amd64.go
- )
- ENDIF()
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- auxv_none.go
- create_file_nounix.go
- defs_windows.go
- lock_sema.go
- mem_windows.go
- netpoll_windows.go
- os_windows.go
- security_nonunix.go
- signal_windows.go
- sigqueue_note.go
- stubs3.go
- stubs_nonlinux.go
- syscall_windows.go
- time_windows.h
- timeasm.go
- vdso_in_none.go
- zcallback_windows.go
- )
-
- IF (ARCH_ARM64)
- SRCS(
- defs_windows_arm64.go
- os_windows_arm64.go
- rt0_windows_arm64.s
- sys_windows_arm64.s
- time_windows_arm64.s
- zcallback_windows_arm64.s
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- defs_windows_amd64.go
- rt0_windows_amd64.s
- sys_windows_amd64.s
- time_windows_amd64.s
- tls_windows_amd64.go
- zcallback_windows.s
- )
- ENDIF()
-ENDIF()
-
-IF (CGO_ENABLED OR OS_DARWIN)
- IF (RACE)
- SRCS(
- race.go
- )
-
- IF (ARCH_ARM64)
- SRCS(
- race_arm64.s
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- race_amd64.s
- )
- ENDIF()
- ELSE()
- SRCS(
- race0.go
- )
- ENDIF()
-ELSE()
- SRCS(
- race0.go
- )
-ENDIF()
-
-END()
-
-
-IF (CGO_ENABLED)
- RECURSE(
- cgo
- )
-ENDIF()
-
-RECURSE(
- coverage
- debug
- internal
- metrics
- pprof
- race
- trace
-)
diff --git a/contrib/go/_std_1.20/src/runtime/zcallback_windows.s b/contrib/go/_std_1.20/src/runtime/zcallback_windows.s
deleted file mode 100644
index bd23d71333..0000000000
--- a/contrib/go/_std_1.20/src/runtime/zcallback_windows.s
+++ /dev/null
@@ -1,2013 +0,0 @@
-// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
-
-//go:build 386 || amd64
-
-// runtime·callbackasm is called by external code to
-// execute Go implemented callback function. It is not
-// called from the start, instead runtime·compilecallback
-// always returns address into runtime·callbackasm offset
-// appropriately so different callbacks start with different
-// CALL instruction in runtime·callbackasm. This determines
-// which Go callback function is executed later on.
-
-TEXT runtime·callbackasm(SB),7,$0
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
- CALL runtime·callbackasm1(SB)
diff --git a/contrib/go/_std_1.20/src/sort/sort.go b/contrib/go/_std_1.20/src/sort/sort.go
deleted file mode 100644
index 68e2f0d082..0000000000
--- a/contrib/go/_std_1.20/src/sort/sort.go
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2009 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.
-
-//go:generate go run gen_sort_variants.go
-
-// Package sort provides primitives for sorting slices and user-defined collections.
-package sort
-
-import "math/bits"
-
-// An implementation of Interface can be sorted by the routines in this package.
-// The methods refer to elements of the underlying collection by integer index.
-type Interface interface {
- // Len is the number of elements in the collection.
- Len() int
-
- // Less reports whether the element with index i
- // must sort before the element with index j.
- //
- // If both Less(i, j) and Less(j, i) are false,
- // then the elements at index i and j are considered equal.
- // Sort may place equal elements in any order in the final result,
- // while Stable preserves the original input order of equal elements.
- //
- // Less must describe a transitive ordering:
- // - if both Less(i, j) and Less(j, k) are true, then Less(i, k) must be true as well.
- // - if both Less(i, j) and Less(j, k) are false, then Less(i, k) must be false as well.
- //
- // Note that floating-point comparison (the < operator on float32 or float64 values)
- // is not a transitive ordering when not-a-number (NaN) values are involved.
- // See Float64Slice.Less for a correct implementation for floating-point values.
- Less(i, j int) bool
-
- // Swap swaps the elements with indexes i and j.
- Swap(i, j int)
-}
-
-// Sort sorts data in ascending order as determined by the Less method.
-// It makes one call to data.Len to determine n and O(n*log(n)) calls to
-// data.Less and data.Swap. The sort is not guaranteed to be stable.
-func Sort(data Interface) {
- n := data.Len()
- if n <= 1 {
- return
- }
- limit := bits.Len(uint(n))
- pdqsort(data, 0, n, limit)
-}
-
-type sortedHint int // hint for pdqsort when choosing the pivot
-
-const (
- unknownHint sortedHint = iota
- increasingHint
- decreasingHint
-)
-
-// xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
-type xorshift uint64
-
-func (r *xorshift) Next() uint64 {
- *r ^= *r << 13
- *r ^= *r >> 17
- *r ^= *r << 5
- return uint64(*r)
-}
-
-func nextPowerOfTwo(length int) uint {
- shift := uint(bits.Len(uint(length)))
- return uint(1 << shift)
-}
-
-// lessSwap is a pair of Less and Swap function for use with the
-// auto-generated func-optimized variant of sort.go in
-// zfuncversion.go.
-type lessSwap struct {
- Less func(i, j int) bool
- Swap func(i, j int)
-}
-
-type reverse struct {
- // This embedded Interface permits Reverse to use the methods of
- // another Interface implementation.
- Interface
-}
-
-// Less returns the opposite of the embedded implementation's Less method.
-func (r reverse) Less(i, j int) bool {
- return r.Interface.Less(j, i)
-}
-
-// Reverse returns the reverse order for data.
-func Reverse(data Interface) Interface {
- return &reverse{data}
-}
-
-// IsSorted reports whether data is sorted.
-func IsSorted(data Interface) bool {
- n := data.Len()
- for i := n - 1; i > 0; i-- {
- if data.Less(i, i-1) {
- return false
- }
- }
- return true
-}
-
-// Convenience types for common cases
-
-// IntSlice attaches the methods of Interface to []int, sorting in increasing order.
-type IntSlice []int
-
-func (x IntSlice) Len() int { return len(x) }
-func (x IntSlice) Less(i, j int) bool { return x[i] < x[j] }
-func (x IntSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-// Sort is a convenience method: x.Sort() calls Sort(x).
-func (x IntSlice) Sort() { Sort(x) }
-
-// Float64Slice implements Interface for a []float64, sorting in increasing order,
-// with not-a-number (NaN) values ordered before other values.
-type Float64Slice []float64
-
-func (x Float64Slice) Len() int { return len(x) }
-
-// Less reports whether x[i] should be ordered before x[j], as required by the sort Interface.
-// Note that floating-point comparison by itself is not a transitive relation: it does not
-// report a consistent ordering for not-a-number (NaN) values.
-// This implementation of Less places NaN values before any others, by using:
-//
-// x[i] < x[j] || (math.IsNaN(x[i]) && !math.IsNaN(x[j]))
-func (x Float64Slice) Less(i, j int) bool { return x[i] < x[j] || (isNaN(x[i]) && !isNaN(x[j])) }
-func (x Float64Slice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-// isNaN is a copy of math.IsNaN to avoid a dependency on the math package.
-func isNaN(f float64) bool {
- return f != f
-}
-
-// Sort is a convenience method: x.Sort() calls Sort(x).
-func (x Float64Slice) Sort() { Sort(x) }
-
-// StringSlice attaches the methods of Interface to []string, sorting in increasing order.
-type StringSlice []string
-
-func (x StringSlice) Len() int { return len(x) }
-func (x StringSlice) Less(i, j int) bool { return x[i] < x[j] }
-func (x StringSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-// Sort is a convenience method: x.Sort() calls Sort(x).
-func (x StringSlice) Sort() { Sort(x) }
-
-// Convenience wrappers for common cases
-
-// Ints sorts a slice of ints in increasing order.
-func Ints(x []int) { Sort(IntSlice(x)) }
-
-// Float64s sorts a slice of float64s in increasing order.
-// Not-a-number (NaN) values are ordered before other values.
-func Float64s(x []float64) { Sort(Float64Slice(x)) }
-
-// Strings sorts a slice of strings in increasing order.
-func Strings(x []string) { Sort(StringSlice(x)) }
-
-// IntsAreSorted reports whether the slice x is sorted in increasing order.
-func IntsAreSorted(x []int) bool { return IsSorted(IntSlice(x)) }
-
-// Float64sAreSorted reports whether the slice x is sorted in increasing order,
-// with not-a-number (NaN) values before any other values.
-func Float64sAreSorted(x []float64) bool { return IsSorted(Float64Slice(x)) }
-
-// StringsAreSorted reports whether the slice x is sorted in increasing order.
-func StringsAreSorted(x []string) bool { return IsSorted(StringSlice(x)) }
-
-// Notes on stable sorting:
-// The used algorithms are simple and provable correct on all input and use
-// only logarithmic additional stack space. They perform well if compared
-// experimentally to other stable in-place sorting algorithms.
-//
-// Remarks on other algorithms evaluated:
-// - GCC's 4.6.3 stable_sort with merge_without_buffer from libstdc++:
-// Not faster.
-// - GCC's __rotate for block rotations: Not faster.
-// - "Practical in-place mergesort" from Jyrki Katajainen, Tomi A. Pasanen
-// and Jukka Teuhola; Nordic Journal of Computing 3,1 (1996), 27-40:
-// The given algorithms are in-place, number of Swap and Assignments
-// grow as n log n but the algorithm is not stable.
-// - "Fast Stable In-Place Sorting with O(n) Data Moves" J.I. Munro and
-// V. Raman in Algorithmica (1996) 16, 115-160:
-// This algorithm either needs additional 2n bits or works only if there
-// are enough different elements available to encode some permutations
-// which have to be undone later (so not stable on any input).
-// - All the optimal in-place sorting/merging algorithms I found are either
-// unstable or rely on enough different elements in each step to encode the
-// performed block rearrangements. See also "In-Place Merging Algorithms",
-// Denham Coates-Evely, Department of Computer Science, Kings College,
-// January 2004 and the references in there.
-// - Often "optimal" algorithms are optimal in the number of assignments
-// but Interface has only Swap as operation.
-
-// Stable sorts data in ascending order as determined by the Less method,
-// while keeping the original order of equal elements.
-//
-// It makes one call to data.Len to determine n, O(n*log(n)) calls to
-// data.Less and O(n*log(n)*log(n)) calls to data.Swap.
-func Stable(data Interface) {
- stable(data, data.Len())
-}
-
-/*
-Complexity of Stable Sorting
-
-
-Complexity of block swapping rotation
-
-Each Swap puts one new element into its correct, final position.
-Elements which reach their final position are no longer moved.
-Thus block swapping rotation needs |u|+|v| calls to Swaps.
-This is best possible as each element might need a move.
-
-Pay attention when comparing to other optimal algorithms which
-typically count the number of assignments instead of swaps:
-E.g. the optimal algorithm of Dudzinski and Dydek for in-place
-rotations uses O(u + v + gcd(u,v)) assignments which is
-better than our O(3 * (u+v)) as gcd(u,v) <= u.
-
-
-Stable sorting by SymMerge and BlockSwap rotations
-
-SymMerg complexity for same size input M = N:
-Calls to Less: O(M*log(N/M+1)) = O(N*log(2)) = O(N)
-Calls to Swap: O((M+N)*log(M)) = O(2*N*log(N)) = O(N*log(N))
-
-(The following argument does not fuzz over a missing -1 or
-other stuff which does not impact the final result).
-
-Let n = data.Len(). Assume n = 2^k.
-
-Plain merge sort performs log(n) = k iterations.
-On iteration i the algorithm merges 2^(k-i) blocks, each of size 2^i.
-
-Thus iteration i of merge sort performs:
-Calls to Less O(2^(k-i) * 2^i) = O(2^k) = O(2^log(n)) = O(n)
-Calls to Swap O(2^(k-i) * 2^i * log(2^i)) = O(2^k * i) = O(n*i)
-
-In total k = log(n) iterations are performed; so in total:
-Calls to Less O(log(n) * n)
-Calls to Swap O(n + 2*n + 3*n + ... + (k-1)*n + k*n)
- = O((k/2) * k * n) = O(n * k^2) = O(n * log^2(n))
-
-
-Above results should generalize to arbitrary n = 2^k + p
-and should not be influenced by the initial insertion sort phase:
-Insertion sort is O(n^2) on Swap and Less, thus O(bs^2) per block of
-size bs at n/bs blocks: O(bs*n) Swaps and Less during insertion sort.
-Merge sort iterations start at i = log(bs). With t = log(bs) constant:
-Calls to Less O((log(n)-t) * n + bs*n) = O(log(n)*n + (bs-t)*n)
- = O(n * log(n))
-Calls to Swap O(n * log^2(n) - (t^2+t)/2*n) = O(n * log^2(n))
-
-*/
diff --git a/contrib/go/_std_1.20/src/sort/ya.make b/contrib/go/_std_1.20/src/sort/ya.make
deleted file mode 100644
index 55775fdff7..0000000000
--- a/contrib/go/_std_1.20/src/sort/ya.make
+++ /dev/null
@@ -1,11 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- search.go
- slice.go
- sort.go
- zsortfunc.go
- zsortinterface.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/strconv/doc.go b/contrib/go/_std_1.20/src/strconv/doc.go
deleted file mode 100644
index 769ecd9a21..0000000000
--- a/contrib/go/_std_1.20/src/strconv/doc.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2015 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 strconv implements conversions to and from string representations
-// of basic data types.
-//
-// # Numeric Conversions
-//
-// The most common numeric conversions are Atoi (string to int) and Itoa (int to string).
-//
-// i, err := strconv.Atoi("-42")
-// s := strconv.Itoa(-42)
-//
-// These assume decimal and the Go int type.
-//
-// ParseBool, ParseFloat, ParseInt, and ParseUint convert strings to values:
-//
-// b, err := strconv.ParseBool("true")
-// f, err := strconv.ParseFloat("3.1415", 64)
-// i, err := strconv.ParseInt("-42", 10, 64)
-// u, err := strconv.ParseUint("42", 10, 64)
-//
-// The parse functions return the widest type (float64, int64, and uint64),
-// but if the size argument specifies a narrower width the result can be
-// converted to that narrower type without data loss:
-//
-// s := "2147483647" // biggest int32
-// i64, err := strconv.ParseInt(s, 10, 32)
-// ...
-// i := int32(i64)
-//
-// FormatBool, FormatFloat, FormatInt, and FormatUint convert values to strings:
-//
-// s := strconv.FormatBool(true)
-// s := strconv.FormatFloat(3.1415, 'E', -1, 64)
-// s := strconv.FormatInt(-42, 16)
-// s := strconv.FormatUint(42, 16)
-//
-// AppendBool, AppendFloat, AppendInt, and AppendUint are similar but
-// append the formatted value to a destination slice.
-//
-// # String Conversions
-//
-// Quote and QuoteToASCII convert strings to quoted Go string literals.
-// The latter guarantees that the result is an ASCII string, by escaping
-// any non-ASCII Unicode with \u:
-//
-// q := strconv.Quote("Hello, 世界")
-// q := strconv.QuoteToASCII("Hello, 世界")
-//
-// QuoteRune and QuoteRuneToASCII are similar but accept runes and
-// return quoted Go rune literals.
-//
-// Unquote and UnquoteChar unquote Go string and rune literals.
-package strconv
diff --git a/contrib/go/_std_1.20/src/strconv/isprint.go b/contrib/go/_std_1.20/src/strconv/isprint.go
deleted file mode 100644
index 994a8e423c..0000000000
--- a/contrib/go/_std_1.20/src/strconv/isprint.go
+++ /dev/null
@@ -1,719 +0,0 @@
-// Copyright 2013 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.
-
-// Code generated by go run makeisprint.go -output isprint.go; DO NOT EDIT.
-
-package strconv
-
-// (434+132+95)*2 + (468)*4 = 3194 bytes
-
-var isPrint16 = []uint16{
- 0x0020, 0x007e,
- 0x00a1, 0x0377,
- 0x037a, 0x037f,
- 0x0384, 0x0556,
- 0x0559, 0x058a,
- 0x058d, 0x05c7,
- 0x05d0, 0x05ea,
- 0x05ef, 0x05f4,
- 0x0606, 0x061b,
- 0x061e, 0x070d,
- 0x0710, 0x074a,
- 0x074d, 0x07b1,
- 0x07c0, 0x07fa,
- 0x07fd, 0x082d,
- 0x0830, 0x085b,
- 0x085e, 0x086a,
- 0x08a0, 0x08c7,
- 0x08d3, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09ce,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09e3,
- 0x09e6, 0x09fe,
- 0x0a01, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a39,
- 0x0a3c, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a51, 0x0a51,
- 0x0a59, 0x0a5e,
- 0x0a66, 0x0a76,
- 0x0a81, 0x0ab9,
- 0x0abc, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0af1,
- 0x0af9, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b39,
- 0x0b3c, 0x0b44,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b55, 0x0b57,
- 0x0b5c, 0x0b63,
- 0x0b66, 0x0b77,
- 0x0b82, 0x0b8a,
- 0x0b8e, 0x0b95,
- 0x0b99, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bcd,
- 0x0bd0, 0x0bd0,
- 0x0bd7, 0x0bd7,
- 0x0be6, 0x0bfa,
- 0x0c00, 0x0c39,
- 0x0c3d, 0x0c4d,
- 0x0c55, 0x0c5a,
- 0x0c60, 0x0c63,
- 0x0c66, 0x0c6f,
- 0x0c77, 0x0cb9,
- 0x0cbc, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0ce3,
- 0x0ce6, 0x0cf2,
- 0x0d00, 0x0d4f,
- 0x0d54, 0x0d63,
- 0x0d66, 0x0d96,
- 0x0d9a, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0ddf,
- 0x0de6, 0x0def,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0ebd,
- 0x0ec0, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edf,
- 0x0f00, 0x0f6c,
- 0x0f71, 0x0fda,
- 0x1000, 0x10c7,
- 0x10cd, 0x10cd,
- 0x10d0, 0x124d,
- 0x1250, 0x125d,
- 0x1260, 0x128d,
- 0x1290, 0x12b5,
- 0x12b8, 0x12c5,
- 0x12c8, 0x1315,
- 0x1318, 0x135a,
- 0x135d, 0x137c,
- 0x1380, 0x1399,
- 0x13a0, 0x13f5,
- 0x13f8, 0x13fd,
- 0x1400, 0x169c,
- 0x16a0, 0x16f8,
- 0x1700, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180d,
- 0x1810, 0x1819,
- 0x1820, 0x1878,
- 0x1880, 0x18aa,
- 0x18b0, 0x18f5,
- 0x1900, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x1980, 0x19ab,
- 0x19b0, 0x19c9,
- 0x19d0, 0x19da,
- 0x19de, 0x1a1b,
- 0x1a1e, 0x1a7c,
- 0x1a7f, 0x1a89,
- 0x1a90, 0x1a99,
- 0x1aa0, 0x1aad,
- 0x1ab0, 0x1ac0,
- 0x1b00, 0x1b4b,
- 0x1b50, 0x1b7c,
- 0x1b80, 0x1bf3,
- 0x1bfc, 0x1c37,
- 0x1c3b, 0x1c49,
- 0x1c4d, 0x1c88,
- 0x1c90, 0x1cba,
- 0x1cbd, 0x1cc7,
- 0x1cd0, 0x1cfa,
- 0x1d00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f7d,
- 0x1f80, 0x1fd3,
- 0x1fd6, 0x1fef,
- 0x1ff2, 0x1ffe,
- 0x2010, 0x2027,
- 0x2030, 0x205e,
- 0x2070, 0x2071,
- 0x2074, 0x209c,
- 0x20a0, 0x20bf,
- 0x20d0, 0x20f0,
- 0x2100, 0x218b,
- 0x2190, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x2b73,
- 0x2b76, 0x2cf3,
- 0x2cf9, 0x2d27,
- 0x2d2d, 0x2d2d,
- 0x2d30, 0x2d67,
- 0x2d6f, 0x2d70,
- 0x2d7f, 0x2d96,
- 0x2da0, 0x2e52,
- 0x2e80, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3001, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x31e3,
- 0x31f0, 0x9ffc,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xa4d0, 0xa62b,
- 0xa640, 0xa6f7,
- 0xa700, 0xa7bf,
- 0xa7c2, 0xa7ca,
- 0xa7f5, 0xa82c,
- 0xa830, 0xa839,
- 0xa840, 0xa877,
- 0xa880, 0xa8c5,
- 0xa8ce, 0xa8d9,
- 0xa8e0, 0xa953,
- 0xa95f, 0xa97c,
- 0xa980, 0xa9d9,
- 0xa9de, 0xaa36,
- 0xaa40, 0xaa4d,
- 0xaa50, 0xaa59,
- 0xaa5c, 0xaac2,
- 0xaadb, 0xaaf6,
- 0xab01, 0xab06,
- 0xab09, 0xab0e,
- 0xab11, 0xab16,
- 0xab20, 0xab6b,
- 0xab70, 0xabed,
- 0xabf0, 0xabf9,
- 0xac00, 0xd7a3,
- 0xd7b0, 0xd7c6,
- 0xd7cb, 0xd7fb,
- 0xf900, 0xfa6d,
- 0xfa70, 0xfad9,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfbc1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfd,
- 0xfe00, 0xfe19,
- 0xfe20, 0xfe6b,
- 0xfe70, 0xfefc,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffee,
- 0xfffc, 0xfffd,
-}
-
-var isNotPrint16 = []uint16{
- 0x00ad,
- 0x038b,
- 0x038d,
- 0x03a2,
- 0x0530,
- 0x0590,
- 0x06dd,
- 0x083f,
- 0x085f,
- 0x08b5,
- 0x08e2,
- 0x0984,
- 0x09a9,
- 0x09b1,
- 0x09de,
- 0x0a04,
- 0x0a29,
- 0x0a31,
- 0x0a34,
- 0x0a37,
- 0x0a3d,
- 0x0a5d,
- 0x0a84,
- 0x0a8e,
- 0x0a92,
- 0x0aa9,
- 0x0ab1,
- 0x0ab4,
- 0x0ac6,
- 0x0aca,
- 0x0b00,
- 0x0b04,
- 0x0b29,
- 0x0b31,
- 0x0b34,
- 0x0b5e,
- 0x0b84,
- 0x0b91,
- 0x0b9b,
- 0x0b9d,
- 0x0bc9,
- 0x0c0d,
- 0x0c11,
- 0x0c29,
- 0x0c45,
- 0x0c49,
- 0x0c57,
- 0x0c8d,
- 0x0c91,
- 0x0ca9,
- 0x0cb4,
- 0x0cc5,
- 0x0cc9,
- 0x0cdf,
- 0x0cf0,
- 0x0d0d,
- 0x0d11,
- 0x0d45,
- 0x0d49,
- 0x0d80,
- 0x0d84,
- 0x0db2,
- 0x0dbc,
- 0x0dd5,
- 0x0dd7,
- 0x0e83,
- 0x0e85,
- 0x0e8b,
- 0x0ea4,
- 0x0ea6,
- 0x0ec5,
- 0x0ec7,
- 0x0f48,
- 0x0f98,
- 0x0fbd,
- 0x0fcd,
- 0x10c6,
- 0x1249,
- 0x1257,
- 0x1259,
- 0x1289,
- 0x12b1,
- 0x12bf,
- 0x12c1,
- 0x12d7,
- 0x1311,
- 0x1680,
- 0x170d,
- 0x176d,
- 0x1771,
- 0x191f,
- 0x1a5f,
- 0x1dfa,
- 0x1f58,
- 0x1f5a,
- 0x1f5c,
- 0x1f5e,
- 0x1fb5,
- 0x1fc5,
- 0x1fdc,
- 0x1ff5,
- 0x208f,
- 0x2b96,
- 0x2c2f,
- 0x2c5f,
- 0x2d26,
- 0x2da7,
- 0x2daf,
- 0x2db7,
- 0x2dbf,
- 0x2dc7,
- 0x2dcf,
- 0x2dd7,
- 0x2ddf,
- 0x2e9a,
- 0x3040,
- 0x3130,
- 0x318f,
- 0x321f,
- 0xa9ce,
- 0xa9ff,
- 0xab27,
- 0xab2f,
- 0xfb37,
- 0xfb3d,
- 0xfb3f,
- 0xfb42,
- 0xfb45,
- 0xfe53,
- 0xfe67,
- 0xfe75,
- 0xffe7,
-}
-
-var isPrint32 = []uint32{
- 0x010000, 0x01004d,
- 0x010050, 0x01005d,
- 0x010080, 0x0100fa,
- 0x010100, 0x010102,
- 0x010107, 0x010133,
- 0x010137, 0x01019c,
- 0x0101a0, 0x0101a0,
- 0x0101d0, 0x0101fd,
- 0x010280, 0x01029c,
- 0x0102a0, 0x0102d0,
- 0x0102e0, 0x0102fb,
- 0x010300, 0x010323,
- 0x01032d, 0x01034a,
- 0x010350, 0x01037a,
- 0x010380, 0x0103c3,
- 0x0103c8, 0x0103d5,
- 0x010400, 0x01049d,
- 0x0104a0, 0x0104a9,
- 0x0104b0, 0x0104d3,
- 0x0104d8, 0x0104fb,
- 0x010500, 0x010527,
- 0x010530, 0x010563,
- 0x01056f, 0x01056f,
- 0x010600, 0x010736,
- 0x010740, 0x010755,
- 0x010760, 0x010767,
- 0x010800, 0x010805,
- 0x010808, 0x010838,
- 0x01083c, 0x01083c,
- 0x01083f, 0x01089e,
- 0x0108a7, 0x0108af,
- 0x0108e0, 0x0108f5,
- 0x0108fb, 0x01091b,
- 0x01091f, 0x010939,
- 0x01093f, 0x01093f,
- 0x010980, 0x0109b7,
- 0x0109bc, 0x0109cf,
- 0x0109d2, 0x010a06,
- 0x010a0c, 0x010a35,
- 0x010a38, 0x010a3a,
- 0x010a3f, 0x010a48,
- 0x010a50, 0x010a58,
- 0x010a60, 0x010a9f,
- 0x010ac0, 0x010ae6,
- 0x010aeb, 0x010af6,
- 0x010b00, 0x010b35,
- 0x010b39, 0x010b55,
- 0x010b58, 0x010b72,
- 0x010b78, 0x010b91,
- 0x010b99, 0x010b9c,
- 0x010ba9, 0x010baf,
- 0x010c00, 0x010c48,
- 0x010c80, 0x010cb2,
- 0x010cc0, 0x010cf2,
- 0x010cfa, 0x010d27,
- 0x010d30, 0x010d39,
- 0x010e60, 0x010ead,
- 0x010eb0, 0x010eb1,
- 0x010f00, 0x010f27,
- 0x010f30, 0x010f59,
- 0x010fb0, 0x010fcb,
- 0x010fe0, 0x010ff6,
- 0x011000, 0x01104d,
- 0x011052, 0x01106f,
- 0x01107f, 0x0110c1,
- 0x0110d0, 0x0110e8,
- 0x0110f0, 0x0110f9,
- 0x011100, 0x011147,
- 0x011150, 0x011176,
- 0x011180, 0x0111f4,
- 0x011200, 0x01123e,
- 0x011280, 0x0112a9,
- 0x0112b0, 0x0112ea,
- 0x0112f0, 0x0112f9,
- 0x011300, 0x01130c,
- 0x01130f, 0x011310,
- 0x011313, 0x011344,
- 0x011347, 0x011348,
- 0x01134b, 0x01134d,
- 0x011350, 0x011350,
- 0x011357, 0x011357,
- 0x01135d, 0x011363,
- 0x011366, 0x01136c,
- 0x011370, 0x011374,
- 0x011400, 0x011461,
- 0x011480, 0x0114c7,
- 0x0114d0, 0x0114d9,
- 0x011580, 0x0115b5,
- 0x0115b8, 0x0115dd,
- 0x011600, 0x011644,
- 0x011650, 0x011659,
- 0x011660, 0x01166c,
- 0x011680, 0x0116b8,
- 0x0116c0, 0x0116c9,
- 0x011700, 0x01171a,
- 0x01171d, 0x01172b,
- 0x011730, 0x01173f,
- 0x011800, 0x01183b,
- 0x0118a0, 0x0118f2,
- 0x0118ff, 0x011906,
- 0x011909, 0x011909,
- 0x01190c, 0x011938,
- 0x01193b, 0x011946,
- 0x011950, 0x011959,
- 0x0119a0, 0x0119a7,
- 0x0119aa, 0x0119d7,
- 0x0119da, 0x0119e4,
- 0x011a00, 0x011a47,
- 0x011a50, 0x011aa2,
- 0x011ac0, 0x011af8,
- 0x011c00, 0x011c45,
- 0x011c50, 0x011c6c,
- 0x011c70, 0x011c8f,
- 0x011c92, 0x011cb6,
- 0x011d00, 0x011d36,
- 0x011d3a, 0x011d47,
- 0x011d50, 0x011d59,
- 0x011d60, 0x011d98,
- 0x011da0, 0x011da9,
- 0x011ee0, 0x011ef8,
- 0x011fb0, 0x011fb0,
- 0x011fc0, 0x011ff1,
- 0x011fff, 0x012399,
- 0x012400, 0x012474,
- 0x012480, 0x012543,
- 0x013000, 0x01342e,
- 0x014400, 0x014646,
- 0x016800, 0x016a38,
- 0x016a40, 0x016a69,
- 0x016a6e, 0x016a6f,
- 0x016ad0, 0x016aed,
- 0x016af0, 0x016af5,
- 0x016b00, 0x016b45,
- 0x016b50, 0x016b77,
- 0x016b7d, 0x016b8f,
- 0x016e40, 0x016e9a,
- 0x016f00, 0x016f4a,
- 0x016f4f, 0x016f87,
- 0x016f8f, 0x016f9f,
- 0x016fe0, 0x016fe4,
- 0x016ff0, 0x016ff1,
- 0x017000, 0x0187f7,
- 0x018800, 0x018cd5,
- 0x018d00, 0x018d08,
- 0x01b000, 0x01b11e,
- 0x01b150, 0x01b152,
- 0x01b164, 0x01b167,
- 0x01b170, 0x01b2fb,
- 0x01bc00, 0x01bc6a,
- 0x01bc70, 0x01bc7c,
- 0x01bc80, 0x01bc88,
- 0x01bc90, 0x01bc99,
- 0x01bc9c, 0x01bc9f,
- 0x01d000, 0x01d0f5,
- 0x01d100, 0x01d126,
- 0x01d129, 0x01d172,
- 0x01d17b, 0x01d1e8,
- 0x01d200, 0x01d245,
- 0x01d2e0, 0x01d2f3,
- 0x01d300, 0x01d356,
- 0x01d360, 0x01d378,
- 0x01d400, 0x01d49f,
- 0x01d4a2, 0x01d4a2,
- 0x01d4a5, 0x01d4a6,
- 0x01d4a9, 0x01d50a,
- 0x01d50d, 0x01d546,
- 0x01d54a, 0x01d6a5,
- 0x01d6a8, 0x01d7cb,
- 0x01d7ce, 0x01da8b,
- 0x01da9b, 0x01daaf,
- 0x01e000, 0x01e018,
- 0x01e01b, 0x01e02a,
- 0x01e100, 0x01e12c,
- 0x01e130, 0x01e13d,
- 0x01e140, 0x01e149,
- 0x01e14e, 0x01e14f,
- 0x01e2c0, 0x01e2f9,
- 0x01e2ff, 0x01e2ff,
- 0x01e800, 0x01e8c4,
- 0x01e8c7, 0x01e8d6,
- 0x01e900, 0x01e94b,
- 0x01e950, 0x01e959,
- 0x01e95e, 0x01e95f,
- 0x01ec71, 0x01ecb4,
- 0x01ed01, 0x01ed3d,
- 0x01ee00, 0x01ee24,
- 0x01ee27, 0x01ee3b,
- 0x01ee42, 0x01ee42,
- 0x01ee47, 0x01ee54,
- 0x01ee57, 0x01ee64,
- 0x01ee67, 0x01ee9b,
- 0x01eea1, 0x01eebb,
- 0x01eef0, 0x01eef1,
- 0x01f000, 0x01f02b,
- 0x01f030, 0x01f093,
- 0x01f0a0, 0x01f0ae,
- 0x01f0b1, 0x01f0f5,
- 0x01f100, 0x01f1ad,
- 0x01f1e6, 0x01f202,
- 0x01f210, 0x01f23b,
- 0x01f240, 0x01f248,
- 0x01f250, 0x01f251,
- 0x01f260, 0x01f265,
- 0x01f300, 0x01f6d7,
- 0x01f6e0, 0x01f6ec,
- 0x01f6f0, 0x01f6fc,
- 0x01f700, 0x01f773,
- 0x01f780, 0x01f7d8,
- 0x01f7e0, 0x01f7eb,
- 0x01f800, 0x01f80b,
- 0x01f810, 0x01f847,
- 0x01f850, 0x01f859,
- 0x01f860, 0x01f887,
- 0x01f890, 0x01f8ad,
- 0x01f8b0, 0x01f8b1,
- 0x01f900, 0x01fa53,
- 0x01fa60, 0x01fa6d,
- 0x01fa70, 0x01fa74,
- 0x01fa78, 0x01fa7a,
- 0x01fa80, 0x01fa86,
- 0x01fa90, 0x01faa8,
- 0x01fab0, 0x01fab6,
- 0x01fac0, 0x01fac2,
- 0x01fad0, 0x01fad6,
- 0x01fb00, 0x01fbca,
- 0x01fbf0, 0x01fbf9,
- 0x020000, 0x02a6dd,
- 0x02a700, 0x02b734,
- 0x02b740, 0x02b81d,
- 0x02b820, 0x02cea1,
- 0x02ceb0, 0x02ebe0,
- 0x02f800, 0x02fa1d,
- 0x030000, 0x03134a,
- 0x0e0100, 0x0e01ef,
-}
-
-var isNotPrint32 = []uint16{ // add 0x10000 to each entry
- 0x000c,
- 0x0027,
- 0x003b,
- 0x003e,
- 0x018f,
- 0x039e,
- 0x0809,
- 0x0836,
- 0x0856,
- 0x08f3,
- 0x0a04,
- 0x0a14,
- 0x0a18,
- 0x0e7f,
- 0x0eaa,
- 0x10bd,
- 0x1135,
- 0x11e0,
- 0x1212,
- 0x1287,
- 0x1289,
- 0x128e,
- 0x129e,
- 0x1304,
- 0x1329,
- 0x1331,
- 0x1334,
- 0x133a,
- 0x145c,
- 0x1914,
- 0x1917,
- 0x1936,
- 0x1c09,
- 0x1c37,
- 0x1ca8,
- 0x1d07,
- 0x1d0a,
- 0x1d3b,
- 0x1d3e,
- 0x1d66,
- 0x1d69,
- 0x1d8f,
- 0x1d92,
- 0x246f,
- 0x6a5f,
- 0x6b5a,
- 0x6b62,
- 0xd455,
- 0xd49d,
- 0xd4ad,
- 0xd4ba,
- 0xd4bc,
- 0xd4c4,
- 0xd506,
- 0xd515,
- 0xd51d,
- 0xd53a,
- 0xd53f,
- 0xd545,
- 0xd551,
- 0xdaa0,
- 0xe007,
- 0xe022,
- 0xe025,
- 0xee04,
- 0xee20,
- 0xee23,
- 0xee28,
- 0xee33,
- 0xee38,
- 0xee3a,
- 0xee48,
- 0xee4a,
- 0xee4c,
- 0xee50,
- 0xee53,
- 0xee58,
- 0xee5a,
- 0xee5c,
- 0xee5e,
- 0xee60,
- 0xee63,
- 0xee6b,
- 0xee73,
- 0xee78,
- 0xee7d,
- 0xee7f,
- 0xee8a,
- 0xeea4,
- 0xeeaa,
- 0xf0c0,
- 0xf0d0,
- 0xf979,
- 0xf9cc,
- 0xfb93,
-}
-
-// isGraphic lists the graphic runes not matched by IsPrint.
-var isGraphic = []uint16{
- 0x00a0,
- 0x1680,
- 0x2000,
- 0x2001,
- 0x2002,
- 0x2003,
- 0x2004,
- 0x2005,
- 0x2006,
- 0x2007,
- 0x2008,
- 0x2009,
- 0x200a,
- 0x202f,
- 0x205f,
- 0x3000,
-}
diff --git a/contrib/go/_std_1.20/src/strconv/ya.make b/contrib/go/_std_1.20/src/strconv/ya.make
deleted file mode 100644
index 75e8532a4a..0000000000
--- a/contrib/go/_std_1.20/src/strconv/ya.make
+++ /dev/null
@@ -1,20 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- atob.go
- atoc.go
- atof.go
- atoi.go
- bytealg.go
- ctoa.go
- decimal.go
- doc.go
- eisel_lemire.go
- ftoa.go
- ftoaryu.go
- isprint.go
- itoa.go
- quote.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/strings/builder.go b/contrib/go/_std_1.20/src/strings/builder.go
deleted file mode 100644
index 7710464a0d..0000000000
--- a/contrib/go/_std_1.20/src/strings/builder.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2017 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 strings
-
-import (
- "unicode/utf8"
- "unsafe"
-)
-
-// A Builder is used to efficiently build a string using Write methods.
-// It minimizes memory copying. The zero value is ready to use.
-// Do not copy a non-zero Builder.
-type Builder struct {
- addr *Builder // of receiver, to detect copies by value
- buf []byte
-}
-
-// noescape hides a pointer from escape analysis. It is the identity function
-// but escape analysis doesn't think the output depends on the input.
-// noescape is inlined and currently compiles down to zero instructions.
-// USE CAREFULLY!
-// This was copied from the runtime; see issues 23382 and 7921.
-//
-//go:nosplit
-//go:nocheckptr
-func noescape(p unsafe.Pointer) unsafe.Pointer {
- x := uintptr(p)
- return unsafe.Pointer(x ^ 0)
-}
-
-func (b *Builder) copyCheck() {
- if b.addr == nil {
- // This hack works around a failing of Go's escape analysis
- // that was causing b to escape and be heap allocated.
- // See issue 23382.
- // TODO: once issue 7921 is fixed, this should be reverted to
- // just "b.addr = b".
- b.addr = (*Builder)(noescape(unsafe.Pointer(b)))
- } else if b.addr != b {
- panic("strings: illegal use of non-zero Builder copied by value")
- }
-}
-
-// String returns the accumulated string.
-func (b *Builder) String() string {
- return unsafe.String(unsafe.SliceData(b.buf), len(b.buf))
-}
-
-// Len returns the number of accumulated bytes; b.Len() == len(b.String()).
-func (b *Builder) Len() int { return len(b.buf) }
-
-// Cap returns the capacity of the builder's underlying byte slice. It is the
-// total space allocated for the string being built and includes any bytes
-// already written.
-func (b *Builder) Cap() int { return cap(b.buf) }
-
-// Reset resets the Builder to be empty.
-func (b *Builder) Reset() {
- b.addr = nil
- b.buf = nil
-}
-
-// grow copies the buffer to a new, larger buffer so that there are at least n
-// bytes of capacity beyond len(b.buf).
-func (b *Builder) grow(n int) {
- buf := make([]byte, len(b.buf), 2*cap(b.buf)+n)
- copy(buf, b.buf)
- b.buf = buf
-}
-
-// Grow grows b's capacity, if necessary, to guarantee space for
-// another n bytes. After Grow(n), at least n bytes can be written to b
-// without another allocation. If n is negative, Grow panics.
-func (b *Builder) Grow(n int) {
- b.copyCheck()
- if n < 0 {
- panic("strings.Builder.Grow: negative count")
- }
- if cap(b.buf)-len(b.buf) < n {
- b.grow(n)
- }
-}
-
-// Write appends the contents of p to b's buffer.
-// Write always returns len(p), nil.
-func (b *Builder) Write(p []byte) (int, error) {
- b.copyCheck()
- b.buf = append(b.buf, p...)
- return len(p), nil
-}
-
-// WriteByte appends the byte c to b's buffer.
-// The returned error is always nil.
-func (b *Builder) WriteByte(c byte) error {
- b.copyCheck()
- b.buf = append(b.buf, c)
- return nil
-}
-
-// WriteRune appends the UTF-8 encoding of Unicode code point r to b's buffer.
-// It returns the length of r and a nil error.
-func (b *Builder) WriteRune(r rune) (int, error) {
- b.copyCheck()
- n := len(b.buf)
- b.buf = utf8.AppendRune(b.buf, r)
- return len(b.buf) - n, nil
-}
-
-// WriteString appends the contents of s to b's buffer.
-// It returns the length of s and a nil error.
-func (b *Builder) WriteString(s string) (int, error) {
- b.copyCheck()
- b.buf = append(b.buf, s...)
- return len(s), nil
-}
diff --git a/contrib/go/_std_1.20/src/strings/reader.go b/contrib/go/_std_1.20/src/strings/reader.go
deleted file mode 100644
index 6f069a62ca..0000000000
--- a/contrib/go/_std_1.20/src/strings/reader.go
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2009 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 strings
-
-import (
- "errors"
- "io"
- "unicode/utf8"
-)
-
-// A Reader implements the io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner,
-// io.RuneReader, io.RuneScanner, io.Seeker, and io.WriterTo interfaces by reading
-// from a string.
-// The zero value for Reader operates like a Reader of an empty string.
-type Reader struct {
- s string
- i int64 // current reading index
- prevRune int // index of previous rune; or < 0
-}
-
-// Len returns the number of bytes of the unread portion of the
-// string.
-func (r *Reader) Len() int {
- if r.i >= int64(len(r.s)) {
- return 0
- }
- return int(int64(len(r.s)) - r.i)
-}
-
-// Size returns the original length of the underlying string.
-// Size is the number of bytes available for reading via ReadAt.
-// The returned value is always the same and is not affected by calls
-// to any other method.
-func (r *Reader) Size() int64 { return int64(len(r.s)) }
-
-// Read implements the io.Reader interface.
-func (r *Reader) Read(b []byte) (n int, err error) {
- if r.i >= int64(len(r.s)) {
- return 0, io.EOF
- }
- r.prevRune = -1
- n = copy(b, r.s[r.i:])
- r.i += int64(n)
- return
-}
-
-// ReadAt implements the io.ReaderAt interface.
-func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
- // cannot modify state - see io.ReaderAt
- if off < 0 {
- return 0, errors.New("strings.Reader.ReadAt: negative offset")
- }
- if off >= int64(len(r.s)) {
- return 0, io.EOF
- }
- n = copy(b, r.s[off:])
- if n < len(b) {
- err = io.EOF
- }
- return
-}
-
-// ReadByte implements the io.ByteReader interface.
-func (r *Reader) ReadByte() (byte, error) {
- r.prevRune = -1
- if r.i >= int64(len(r.s)) {
- return 0, io.EOF
- }
- b := r.s[r.i]
- r.i++
- return b, nil
-}
-
-// UnreadByte implements the io.ByteScanner interface.
-func (r *Reader) UnreadByte() error {
- if r.i <= 0 {
- return errors.New("strings.Reader.UnreadByte: at beginning of string")
- }
- r.prevRune = -1
- r.i--
- return nil
-}
-
-// ReadRune implements the io.RuneReader interface.
-func (r *Reader) ReadRune() (ch rune, size int, err error) {
- if r.i >= int64(len(r.s)) {
- r.prevRune = -1
- return 0, 0, io.EOF
- }
- r.prevRune = int(r.i)
- if c := r.s[r.i]; c < utf8.RuneSelf {
- r.i++
- return rune(c), 1, nil
- }
- ch, size = utf8.DecodeRuneInString(r.s[r.i:])
- r.i += int64(size)
- return
-}
-
-// UnreadRune implements the io.RuneScanner interface.
-func (r *Reader) UnreadRune() error {
- if r.i <= 0 {
- return errors.New("strings.Reader.UnreadRune: at beginning of string")
- }
- if r.prevRune < 0 {
- return errors.New("strings.Reader.UnreadRune: previous operation was not ReadRune")
- }
- r.i = int64(r.prevRune)
- r.prevRune = -1
- return nil
-}
-
-// Seek implements the io.Seeker interface.
-func (r *Reader) Seek(offset int64, whence int) (int64, error) {
- r.prevRune = -1
- var abs int64
- switch whence {
- case io.SeekStart:
- abs = offset
- case io.SeekCurrent:
- abs = r.i + offset
- case io.SeekEnd:
- abs = int64(len(r.s)) + offset
- default:
- return 0, errors.New("strings.Reader.Seek: invalid whence")
- }
- if abs < 0 {
- return 0, errors.New("strings.Reader.Seek: negative position")
- }
- r.i = abs
- return abs, nil
-}
-
-// WriteTo implements the io.WriterTo interface.
-func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
- r.prevRune = -1
- if r.i >= int64(len(r.s)) {
- return 0, nil
- }
- s := r.s[r.i:]
- m, err := io.WriteString(w, s)
- if m > len(s) {
- panic("strings.Reader.WriteTo: invalid WriteString count")
- }
- r.i += int64(m)
- n = int64(m)
- if m != len(s) && err == nil {
- err = io.ErrShortWrite
- }
- return
-}
-
-// Reset resets the Reader to be reading from s.
-func (r *Reader) Reset(s string) { *r = Reader{s, 0, -1} }
-
-// NewReader returns a new Reader reading from s.
-// It is similar to bytes.NewBufferString but more efficient and read-only.
-func NewReader(s string) *Reader { return &Reader{s, 0, -1} }
diff --git a/contrib/go/_std_1.20/src/strings/strings.go b/contrib/go/_std_1.20/src/strings/strings.go
deleted file mode 100644
index 646161fdda..0000000000
--- a/contrib/go/_std_1.20/src/strings/strings.go
+++ /dev/null
@@ -1,1289 +0,0 @@
-// Copyright 2009 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 strings implements simple functions to manipulate UTF-8 encoded strings.
-//
-// For information about UTF-8 strings in Go, see https://blog.golang.org/strings.
-package strings
-
-import (
- "internal/bytealg"
- "unicode"
- "unicode/utf8"
-)
-
-// explode splits s into a slice of UTF-8 strings,
-// one string per Unicode character up to a maximum of n (n < 0 means no limit).
-// Invalid UTF-8 bytes are sliced individually.
-func explode(s string, n int) []string {
- l := utf8.RuneCountInString(s)
- if n < 0 || n > l {
- n = l
- }
- a := make([]string, n)
- for i := 0; i < n-1; i++ {
- _, size := utf8.DecodeRuneInString(s)
- a[i] = s[:size]
- s = s[size:]
- }
- if n > 0 {
- a[n-1] = s
- }
- return a
-}
-
-// Count counts the number of non-overlapping instances of substr in s.
-// If substr is an empty string, Count returns 1 + the number of Unicode code points in s.
-func Count(s, substr string) int {
- // special case
- if len(substr) == 0 {
- return utf8.RuneCountInString(s) + 1
- }
- if len(substr) == 1 {
- return bytealg.CountString(s, substr[0])
- }
- n := 0
- for {
- i := Index(s, substr)
- if i == -1 {
- return n
- }
- n++
- s = s[i+len(substr):]
- }
-}
-
-// Contains reports whether substr is within s.
-func Contains(s, substr string) bool {
- return Index(s, substr) >= 0
-}
-
-// ContainsAny reports whether any Unicode code points in chars are within s.
-func ContainsAny(s, chars string) bool {
- return IndexAny(s, chars) >= 0
-}
-
-// ContainsRune reports whether the Unicode code point r is within s.
-func ContainsRune(s string, r rune) bool {
- return IndexRune(s, r) >= 0
-}
-
-// LastIndex returns the index of the last instance of substr in s, or -1 if substr is not present in s.
-func LastIndex(s, substr string) int {
- n := len(substr)
- switch {
- case n == 0:
- return len(s)
- case n == 1:
- return LastIndexByte(s, substr[0])
- case n == len(s):
- if substr == s {
- return 0
- }
- return -1
- case n > len(s):
- return -1
- }
- // Rabin-Karp search from the end of the string
- hashss, pow := bytealg.HashStrRev(substr)
- last := len(s) - n
- var h uint32
- for i := len(s) - 1; i >= last; i-- {
- h = h*bytealg.PrimeRK + uint32(s[i])
- }
- if h == hashss && s[last:] == substr {
- return last
- }
- for i := last - 1; i >= 0; i-- {
- h *= bytealg.PrimeRK
- h += uint32(s[i])
- h -= pow * uint32(s[i+n])
- if h == hashss && s[i:i+n] == substr {
- return i
- }
- }
- return -1
-}
-
-// IndexByte returns the index of the first instance of c in s, or -1 if c is not present in s.
-func IndexByte(s string, c byte) int {
- return bytealg.IndexByteString(s, c)
-}
-
-// IndexRune returns the index of the first instance of the Unicode code point
-// r, or -1 if rune is not present in s.
-// If r is utf8.RuneError, it returns the first instance of any
-// invalid UTF-8 byte sequence.
-func IndexRune(s string, r rune) int {
- switch {
- case 0 <= r && r < utf8.RuneSelf:
- return IndexByte(s, byte(r))
- case r == utf8.RuneError:
- for i, r := range s {
- if r == utf8.RuneError {
- return i
- }
- }
- return -1
- case !utf8.ValidRune(r):
- return -1
- default:
- return Index(s, string(r))
- }
-}
-
-// IndexAny returns the index of the first instance of any Unicode code point
-// from chars in s, or -1 if no Unicode code point from chars is present in s.
-func IndexAny(s, chars string) int {
- if chars == "" {
- // Avoid scanning all of s.
- return -1
- }
- if len(chars) == 1 {
- // Avoid scanning all of s.
- r := rune(chars[0])
- if r >= utf8.RuneSelf {
- r = utf8.RuneError
- }
- return IndexRune(s, r)
- }
- if len(s) > 8 {
- if as, isASCII := makeASCIISet(chars); isASCII {
- for i := 0; i < len(s); i++ {
- if as.contains(s[i]) {
- return i
- }
- }
- return -1
- }
- }
- for i, c := range s {
- if IndexRune(chars, c) >= 0 {
- return i
- }
- }
- return -1
-}
-
-// LastIndexAny returns the index of the last instance of any Unicode code
-// point from chars in s, or -1 if no Unicode code point from chars is
-// present in s.
-func LastIndexAny(s, chars string) int {
- if chars == "" {
- // Avoid scanning all of s.
- return -1
- }
- if len(s) == 1 {
- rc := rune(s[0])
- if rc >= utf8.RuneSelf {
- rc = utf8.RuneError
- }
- if IndexRune(chars, rc) >= 0 {
- return 0
- }
- return -1
- }
- if len(s) > 8 {
- if as, isASCII := makeASCIISet(chars); isASCII {
- for i := len(s) - 1; i >= 0; i-- {
- if as.contains(s[i]) {
- return i
- }
- }
- return -1
- }
- }
- if len(chars) == 1 {
- rc := rune(chars[0])
- if rc >= utf8.RuneSelf {
- rc = utf8.RuneError
- }
- for i := len(s); i > 0; {
- r, size := utf8.DecodeLastRuneInString(s[:i])
- i -= size
- if rc == r {
- return i
- }
- }
- return -1
- }
- for i := len(s); i > 0; {
- r, size := utf8.DecodeLastRuneInString(s[:i])
- i -= size
- if IndexRune(chars, r) >= 0 {
- return i
- }
- }
- return -1
-}
-
-// LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
-func LastIndexByte(s string, c byte) int {
- for i := len(s) - 1; i >= 0; i-- {
- if s[i] == c {
- return i
- }
- }
- return -1
-}
-
-// Generic split: splits after each instance of sep,
-// including sepSave bytes of sep in the subarrays.
-func genSplit(s, sep string, sepSave, n int) []string {
- if n == 0 {
- return nil
- }
- if sep == "" {
- return explode(s, n)
- }
- if n < 0 {
- n = Count(s, sep) + 1
- }
-
- if n > len(s)+1 {
- n = len(s) + 1
- }
- a := make([]string, n)
- n--
- i := 0
- for i < n {
- m := Index(s, sep)
- if m < 0 {
- break
- }
- a[i] = s[:m+sepSave]
- s = s[m+len(sep):]
- i++
- }
- a[i] = s
- return a[:i+1]
-}
-
-// SplitN slices s into substrings separated by sep and returns a slice of
-// the substrings between those separators.
-//
-// The count determines the number of substrings to return:
-//
-// n > 0: at most n substrings; the last substring will be the unsplit remainder.
-// n == 0: the result is nil (zero substrings)
-// n < 0: all substrings
-//
-// Edge cases for s and sep (for example, empty strings) are handled
-// as described in the documentation for Split.
-//
-// To split around the first instance of a separator, see Cut.
-func SplitN(s, sep string, n int) []string { return genSplit(s, sep, 0, n) }
-
-// SplitAfterN slices s into substrings after each instance of sep and
-// returns a slice of those substrings.
-//
-// The count determines the number of substrings to return:
-//
-// n > 0: at most n substrings; the last substring will be the unsplit remainder.
-// n == 0: the result is nil (zero substrings)
-// n < 0: all substrings
-//
-// Edge cases for s and sep (for example, empty strings) are handled
-// as described in the documentation for SplitAfter.
-func SplitAfterN(s, sep string, n int) []string {
- return genSplit(s, sep, len(sep), n)
-}
-
-// Split slices s into all substrings separated by sep and returns a slice of
-// the substrings between those separators.
-//
-// If s does not contain sep and sep is not empty, Split returns a
-// slice of length 1 whose only element is s.
-//
-// If sep is empty, Split splits after each UTF-8 sequence. If both s
-// and sep are empty, Split returns an empty slice.
-//
-// It is equivalent to SplitN with a count of -1.
-//
-// To split around the first instance of a separator, see Cut.
-func Split(s, sep string) []string { return genSplit(s, sep, 0, -1) }
-
-// SplitAfter slices s into all substrings after each instance of sep and
-// returns a slice of those substrings.
-//
-// If s does not contain sep and sep is not empty, SplitAfter returns
-// a slice of length 1 whose only element is s.
-//
-// If sep is empty, SplitAfter splits after each UTF-8 sequence. If
-// both s and sep are empty, SplitAfter returns an empty slice.
-//
-// It is equivalent to SplitAfterN with a count of -1.
-func SplitAfter(s, sep string) []string {
- return genSplit(s, sep, len(sep), -1)
-}
-
-var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
-
-// Fields splits the string s around each instance of one or more consecutive white space
-// characters, as defined by unicode.IsSpace, returning a slice of substrings of s or an
-// empty slice if s contains only white space.
-func Fields(s string) []string {
- // First count the fields.
- // This is an exact count if s is ASCII, otherwise it is an approximation.
- n := 0
- wasSpace := 1
- // setBits is used to track which bits are set in the bytes of s.
- setBits := uint8(0)
- for i := 0; i < len(s); i++ {
- r := s[i]
- setBits |= r
- isSpace := int(asciiSpace[r])
- n += wasSpace & ^isSpace
- wasSpace = isSpace
- }
-
- if setBits >= utf8.RuneSelf {
- // Some runes in the input string are not ASCII.
- return FieldsFunc(s, unicode.IsSpace)
- }
- // ASCII fast path
- a := make([]string, n)
- na := 0
- fieldStart := 0
- i := 0
- // Skip spaces in the front of the input.
- for i < len(s) && asciiSpace[s[i]] != 0 {
- i++
- }
- fieldStart = i
- for i < len(s) {
- if asciiSpace[s[i]] == 0 {
- i++
- continue
- }
- a[na] = s[fieldStart:i]
- na++
- i++
- // Skip spaces in between fields.
- for i < len(s) && asciiSpace[s[i]] != 0 {
- i++
- }
- fieldStart = i
- }
- if fieldStart < len(s) { // Last field might end at EOF.
- a[na] = s[fieldStart:]
- }
- return a
-}
-
-// FieldsFunc splits the string s at each run of Unicode code points c satisfying f(c)
-// and returns an array of slices of s. If all code points in s satisfy f(c) or the
-// string is empty, an empty slice is returned.
-//
-// FieldsFunc makes no guarantees about the order in which it calls f(c)
-// and assumes that f always returns the same value for a given c.
-func FieldsFunc(s string, f func(rune) bool) []string {
- // A span is used to record a slice of s of the form s[start:end].
- // The start index is inclusive and the end index is exclusive.
- type span struct {
- start int
- end int
- }
- spans := make([]span, 0, 32)
-
- // Find the field start and end indices.
- // Doing this in a separate pass (rather than slicing the string s
- // and collecting the result substrings right away) is significantly
- // more efficient, possibly due to cache effects.
- start := -1 // valid span start if >= 0
- for end, rune := range s {
- if f(rune) {
- if start >= 0 {
- spans = append(spans, span{start, end})
- // Set start to a negative value.
- // Note: using -1 here consistently and reproducibly
- // slows down this code by a several percent on amd64.
- start = ^start
- }
- } else {
- if start < 0 {
- start = end
- }
- }
- }
-
- // Last field might end at EOF.
- if start >= 0 {
- spans = append(spans, span{start, len(s)})
- }
-
- // Create strings from recorded field indices.
- a := make([]string, len(spans))
- for i, span := range spans {
- a[i] = s[span.start:span.end]
- }
-
- return a
-}
-
-// Join concatenates the elements of its first argument to create a single string. The separator
-// string sep is placed between elements in the resulting string.
-func Join(elems []string, sep string) string {
- switch len(elems) {
- case 0:
- return ""
- case 1:
- return elems[0]
- }
- n := len(sep) * (len(elems) - 1)
- for i := 0; i < len(elems); i++ {
- n += len(elems[i])
- }
-
- var b Builder
- b.Grow(n)
- b.WriteString(elems[0])
- for _, s := range elems[1:] {
- b.WriteString(sep)
- b.WriteString(s)
- }
- return b.String()
-}
-
-// HasPrefix tests whether the string s begins with prefix.
-func HasPrefix(s, prefix string) bool {
- return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
-}
-
-// HasSuffix tests whether the string s ends with suffix.
-func HasSuffix(s, suffix string) bool {
- return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
-}
-
-// Map returns a copy of the string s with all its characters modified
-// according to the mapping function. If mapping returns a negative value, the character is
-// dropped from the string with no replacement.
-func Map(mapping func(rune) rune, s string) string {
- // In the worst case, the string can grow when mapped, making
- // things unpleasant. But it's so rare we barge in assuming it's
- // fine. It could also shrink but that falls out naturally.
-
- // The output buffer b is initialized on demand, the first
- // time a character differs.
- var b Builder
-
- for i, c := range s {
- r := mapping(c)
- if r == c && c != utf8.RuneError {
- continue
- }
-
- var width int
- if c == utf8.RuneError {
- c, width = utf8.DecodeRuneInString(s[i:])
- if width != 1 && r == c {
- continue
- }
- } else {
- width = utf8.RuneLen(c)
- }
-
- b.Grow(len(s) + utf8.UTFMax)
- b.WriteString(s[:i])
- if r >= 0 {
- b.WriteRune(r)
- }
-
- s = s[i+width:]
- break
- }
-
- // Fast path for unchanged input
- if b.Cap() == 0 { // didn't call b.Grow above
- return s
- }
-
- for _, c := range s {
- r := mapping(c)
-
- if r >= 0 {
- // common case
- // Due to inlining, it is more performant to determine if WriteByte should be
- // invoked rather than always call WriteRune
- if r < utf8.RuneSelf {
- b.WriteByte(byte(r))
- } else {
- // r is not a ASCII rune.
- b.WriteRune(r)
- }
- }
- }
-
- return b.String()
-}
-
-// Repeat returns a new string consisting of count copies of the string s.
-//
-// It panics if count is negative or if the result of (len(s) * count)
-// overflows.
-func Repeat(s string, count int) string {
- switch count {
- case 0:
- return ""
- case 1:
- return s
- }
-
- // Since we cannot return an error on overflow,
- // we should panic if the repeat will generate
- // an overflow.
- // See golang.org/issue/16237.
- if count < 0 {
- panic("strings: negative Repeat count")
- } else if len(s)*count/count != len(s) {
- panic("strings: Repeat count causes overflow")
- }
-
- if len(s) == 0 {
- return ""
- }
-
- n := len(s) * count
-
- // Past a certain chunk size it is counterproductive to use
- // larger chunks as the source of the write, as when the source
- // is too large we are basically just thrashing the CPU D-cache.
- // So if the result length is larger than an empirically-found
- // limit (8KB), we stop growing the source string once the limit
- // is reached and keep reusing the same source string - that
- // should therefore be always resident in the L1 cache - until we
- // have completed the construction of the result.
- // This yields significant speedups (up to +100%) in cases where
- // the result length is large (roughly, over L2 cache size).
- const chunkLimit = 8 * 1024
- chunkMax := n
- if n > chunkLimit {
- chunkMax = chunkLimit / len(s) * len(s)
- if chunkMax == 0 {
- chunkMax = len(s)
- }
- }
-
- var b Builder
- b.Grow(n)
- b.WriteString(s)
- for b.Len() < n {
- chunk := n - b.Len()
- if chunk > b.Len() {
- chunk = b.Len()
- }
- if chunk > chunkMax {
- chunk = chunkMax
- }
- b.WriteString(b.String()[:chunk])
- }
- return b.String()
-}
-
-// ToUpper returns s with all Unicode letters mapped to their upper case.
-func ToUpper(s string) string {
- isASCII, hasLower := true, false
- for i := 0; i < len(s); i++ {
- c := s[i]
- if c >= utf8.RuneSelf {
- isASCII = false
- break
- }
- hasLower = hasLower || ('a' <= c && c <= 'z')
- }
-
- if isASCII { // optimize for ASCII-only strings.
- if !hasLower {
- return s
- }
- var (
- b Builder
- pos int
- )
- b.Grow(len(s))
- for i := 0; i < len(s); i++ {
- c := s[i]
- if 'a' <= c && c <= 'z' {
- c -= 'a' - 'A'
- if pos < i {
- b.WriteString(s[pos:i])
- }
- b.WriteByte(c)
- pos = i + 1
- }
- }
- if pos < len(s) {
- b.WriteString(s[pos:])
- }
- return b.String()
- }
- return Map(unicode.ToUpper, s)
-}
-
-// ToLower returns s with all Unicode letters mapped to their lower case.
-func ToLower(s string) string {
- isASCII, hasUpper := true, false
- for i := 0; i < len(s); i++ {
- c := s[i]
- if c >= utf8.RuneSelf {
- isASCII = false
- break
- }
- hasUpper = hasUpper || ('A' <= c && c <= 'Z')
- }
-
- if isASCII { // optimize for ASCII-only strings.
- if !hasUpper {
- return s
- }
- var (
- b Builder
- pos int
- )
- b.Grow(len(s))
- for i := 0; i < len(s); i++ {
- c := s[i]
- if 'A' <= c && c <= 'Z' {
- c += 'a' - 'A'
- if pos < i {
- b.WriteString(s[pos:i])
- }
- b.WriteByte(c)
- pos = i + 1
- }
- }
- if pos < len(s) {
- b.WriteString(s[pos:])
- }
- return b.String()
- }
- return Map(unicode.ToLower, s)
-}
-
-// ToTitle returns a copy of the string s with all Unicode letters mapped to
-// their Unicode title case.
-func ToTitle(s string) string { return Map(unicode.ToTitle, s) }
-
-// ToUpperSpecial returns a copy of the string s with all Unicode letters mapped to their
-// upper case using the case mapping specified by c.
-func ToUpperSpecial(c unicode.SpecialCase, s string) string {
- return Map(c.ToUpper, s)
-}
-
-// ToLowerSpecial returns a copy of the string s with all Unicode letters mapped to their
-// lower case using the case mapping specified by c.
-func ToLowerSpecial(c unicode.SpecialCase, s string) string {
- return Map(c.ToLower, s)
-}
-
-// ToTitleSpecial returns a copy of the string s with all Unicode letters mapped to their
-// Unicode title case, giving priority to the special casing rules.
-func ToTitleSpecial(c unicode.SpecialCase, s string) string {
- return Map(c.ToTitle, s)
-}
-
-// ToValidUTF8 returns a copy of the string s with each run of invalid UTF-8 byte sequences
-// replaced by the replacement string, which may be empty.
-func ToValidUTF8(s, replacement string) string {
- var b Builder
-
- for i, c := range s {
- if c != utf8.RuneError {
- continue
- }
-
- _, wid := utf8.DecodeRuneInString(s[i:])
- if wid == 1 {
- b.Grow(len(s) + len(replacement))
- b.WriteString(s[:i])
- s = s[i:]
- break
- }
- }
-
- // Fast path for unchanged input
- if b.Cap() == 0 { // didn't call b.Grow above
- return s
- }
-
- invalid := false // previous byte was from an invalid UTF-8 sequence
- for i := 0; i < len(s); {
- c := s[i]
- if c < utf8.RuneSelf {
- i++
- invalid = false
- b.WriteByte(c)
- continue
- }
- _, wid := utf8.DecodeRuneInString(s[i:])
- if wid == 1 {
- i++
- if !invalid {
- invalid = true
- b.WriteString(replacement)
- }
- continue
- }
- invalid = false
- b.WriteString(s[i : i+wid])
- i += wid
- }
-
- return b.String()
-}
-
-// isSeparator reports whether the rune could mark a word boundary.
-// TODO: update when package unicode captures more of the properties.
-func isSeparator(r rune) bool {
- // ASCII alphanumerics and underscore are not separators
- if r <= 0x7F {
- switch {
- case '0' <= r && r <= '9':
- return false
- case 'a' <= r && r <= 'z':
- return false
- case 'A' <= r && r <= 'Z':
- return false
- case r == '_':
- return false
- }
- return true
- }
- // Letters and digits are not separators
- if unicode.IsLetter(r) || unicode.IsDigit(r) {
- return false
- }
- // Otherwise, all we can do for now is treat spaces as separators.
- return unicode.IsSpace(r)
-}
-
-// Title returns a copy of the string s with all Unicode letters that begin words
-// mapped to their Unicode title case.
-//
-// Deprecated: The rule Title uses for word boundaries does not handle Unicode
-// punctuation properly. Use golang.org/x/text/cases instead.
-func Title(s string) string {
- // Use a closure here to remember state.
- // Hackish but effective. Depends on Map scanning in order and calling
- // the closure once per rune.
- prev := ' '
- return Map(
- func(r rune) rune {
- if isSeparator(prev) {
- prev = r
- return unicode.ToTitle(r)
- }
- prev = r
- return r
- },
- s)
-}
-
-// TrimLeftFunc returns a slice of the string s with all leading
-// Unicode code points c satisfying f(c) removed.
-func TrimLeftFunc(s string, f func(rune) bool) string {
- i := indexFunc(s, f, false)
- if i == -1 {
- return ""
- }
- return s[i:]
-}
-
-// TrimRightFunc returns a slice of the string s with all trailing
-// Unicode code points c satisfying f(c) removed.
-func TrimRightFunc(s string, f func(rune) bool) string {
- i := lastIndexFunc(s, f, false)
- if i >= 0 && s[i] >= utf8.RuneSelf {
- _, wid := utf8.DecodeRuneInString(s[i:])
- i += wid
- } else {
- i++
- }
- return s[0:i]
-}
-
-// TrimFunc returns a slice of the string s with all leading
-// and trailing Unicode code points c satisfying f(c) removed.
-func TrimFunc(s string, f func(rune) bool) string {
- return TrimRightFunc(TrimLeftFunc(s, f), f)
-}
-
-// IndexFunc returns the index into s of the first Unicode
-// code point satisfying f(c), or -1 if none do.
-func IndexFunc(s string, f func(rune) bool) int {
- return indexFunc(s, f, true)
-}
-
-// LastIndexFunc returns the index into s of the last
-// Unicode code point satisfying f(c), or -1 if none do.
-func LastIndexFunc(s string, f func(rune) bool) int {
- return lastIndexFunc(s, f, true)
-}
-
-// indexFunc is the same as IndexFunc except that if
-// truth==false, the sense of the predicate function is
-// inverted.
-func indexFunc(s string, f func(rune) bool, truth bool) int {
- for i, r := range s {
- if f(r) == truth {
- return i
- }
- }
- return -1
-}
-
-// lastIndexFunc is the same as LastIndexFunc except that if
-// truth==false, the sense of the predicate function is
-// inverted.
-func lastIndexFunc(s string, f func(rune) bool, truth bool) int {
- for i := len(s); i > 0; {
- r, size := utf8.DecodeLastRuneInString(s[0:i])
- i -= size
- if f(r) == truth {
- return i
- }
- }
- return -1
-}
-
-// asciiSet is a 32-byte value, where each bit represents the presence of a
-// given ASCII character in the set. The 128-bits of the lower 16 bytes,
-// starting with the least-significant bit of the lowest word to the
-// most-significant bit of the highest word, map to the full range of all
-// 128 ASCII characters. The 128-bits of the upper 16 bytes will be zeroed,
-// ensuring that any non-ASCII character will be reported as not in the set.
-// This allocates a total of 32 bytes even though the upper half
-// is unused to avoid bounds checks in asciiSet.contains.
-type asciiSet [8]uint32
-
-// makeASCIISet creates a set of ASCII characters and reports whether all
-// characters in chars are ASCII.
-func makeASCIISet(chars string) (as asciiSet, ok bool) {
- for i := 0; i < len(chars); i++ {
- c := chars[i]
- if c >= utf8.RuneSelf {
- return as, false
- }
- as[c/32] |= 1 << (c % 32)
- }
- return as, true
-}
-
-// contains reports whether c is inside the set.
-func (as *asciiSet) contains(c byte) bool {
- return (as[c/32] & (1 << (c % 32))) != 0
-}
-
-// Trim returns a slice of the string s with all leading and
-// trailing Unicode code points contained in cutset removed.
-func Trim(s, cutset string) string {
- if s == "" || cutset == "" {
- return s
- }
- if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
- return trimLeftByte(trimRightByte(s, cutset[0]), cutset[0])
- }
- if as, ok := makeASCIISet(cutset); ok {
- return trimLeftASCII(trimRightASCII(s, &as), &as)
- }
- return trimLeftUnicode(trimRightUnicode(s, cutset), cutset)
-}
-
-// TrimLeft returns a slice of the string s with all leading
-// Unicode code points contained in cutset removed.
-//
-// To remove a prefix, use TrimPrefix instead.
-func TrimLeft(s, cutset string) string {
- if s == "" || cutset == "" {
- return s
- }
- if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
- return trimLeftByte(s, cutset[0])
- }
- if as, ok := makeASCIISet(cutset); ok {
- return trimLeftASCII(s, &as)
- }
- return trimLeftUnicode(s, cutset)
-}
-
-func trimLeftByte(s string, c byte) string {
- for len(s) > 0 && s[0] == c {
- s = s[1:]
- }
- return s
-}
-
-func trimLeftASCII(s string, as *asciiSet) string {
- for len(s) > 0 {
- if !as.contains(s[0]) {
- break
- }
- s = s[1:]
- }
- return s
-}
-
-func trimLeftUnicode(s, cutset string) string {
- for len(s) > 0 {
- r, n := rune(s[0]), 1
- if r >= utf8.RuneSelf {
- r, n = utf8.DecodeRuneInString(s)
- }
- if !ContainsRune(cutset, r) {
- break
- }
- s = s[n:]
- }
- return s
-}
-
-// TrimRight returns a slice of the string s, with all trailing
-// Unicode code points contained in cutset removed.
-//
-// To remove a suffix, use TrimSuffix instead.
-func TrimRight(s, cutset string) string {
- if s == "" || cutset == "" {
- return s
- }
- if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
- return trimRightByte(s, cutset[0])
- }
- if as, ok := makeASCIISet(cutset); ok {
- return trimRightASCII(s, &as)
- }
- return trimRightUnicode(s, cutset)
-}
-
-func trimRightByte(s string, c byte) string {
- for len(s) > 0 && s[len(s)-1] == c {
- s = s[:len(s)-1]
- }
- return s
-}
-
-func trimRightASCII(s string, as *asciiSet) string {
- for len(s) > 0 {
- if !as.contains(s[len(s)-1]) {
- break
- }
- s = s[:len(s)-1]
- }
- return s
-}
-
-func trimRightUnicode(s, cutset string) string {
- for len(s) > 0 {
- r, n := rune(s[len(s)-1]), 1
- if r >= utf8.RuneSelf {
- r, n = utf8.DecodeLastRuneInString(s)
- }
- if !ContainsRune(cutset, r) {
- break
- }
- s = s[:len(s)-n]
- }
- return s
-}
-
-// TrimSpace returns a slice of the string s, with all leading
-// and trailing white space removed, as defined by Unicode.
-func TrimSpace(s string) string {
- // Fast path for ASCII: look for the first ASCII non-space byte
- start := 0
- for ; start < len(s); start++ {
- c := s[start]
- if c >= utf8.RuneSelf {
- // If we run into a non-ASCII byte, fall back to the
- // slower unicode-aware method on the remaining bytes
- return TrimFunc(s[start:], unicode.IsSpace)
- }
- if asciiSpace[c] == 0 {
- break
- }
- }
-
- // Now look for the first ASCII non-space byte from the end
- stop := len(s)
- for ; stop > start; stop-- {
- c := s[stop-1]
- if c >= utf8.RuneSelf {
- // start has been already trimmed above, should trim end only
- return TrimRightFunc(s[start:stop], unicode.IsSpace)
- }
- if asciiSpace[c] == 0 {
- break
- }
- }
-
- // At this point s[start:stop] starts and ends with an ASCII
- // non-space bytes, so we're done. Non-ASCII cases have already
- // been handled above.
- return s[start:stop]
-}
-
-// TrimPrefix returns s without the provided leading prefix string.
-// If s doesn't start with prefix, s is returned unchanged.
-func TrimPrefix(s, prefix string) string {
- if HasPrefix(s, prefix) {
- return s[len(prefix):]
- }
- return s
-}
-
-// TrimSuffix returns s without the provided trailing suffix string.
-// If s doesn't end with suffix, s is returned unchanged.
-func TrimSuffix(s, suffix string) string {
- if HasSuffix(s, suffix) {
- return s[:len(s)-len(suffix)]
- }
- return s
-}
-
-// Replace returns a copy of the string s with the first n
-// non-overlapping instances of old replaced by new.
-// If old is empty, it matches at the beginning of the string
-// and after each UTF-8 sequence, yielding up to k+1 replacements
-// for a k-rune string.
-// If n < 0, there is no limit on the number of replacements.
-func Replace(s, old, new string, n int) string {
- if old == new || n == 0 {
- return s // avoid allocation
- }
-
- // Compute number of replacements.
- if m := Count(s, old); m == 0 {
- return s // avoid allocation
- } else if n < 0 || m < n {
- n = m
- }
-
- // Apply replacements to buffer.
- var b Builder
- b.Grow(len(s) + n*(len(new)-len(old)))
- start := 0
- for i := 0; i < n; i++ {
- j := start
- if len(old) == 0 {
- if i > 0 {
- _, wid := utf8.DecodeRuneInString(s[start:])
- j += wid
- }
- } else {
- j += Index(s[start:], old)
- }
- b.WriteString(s[start:j])
- b.WriteString(new)
- start = j + len(old)
- }
- b.WriteString(s[start:])
- return b.String()
-}
-
-// ReplaceAll returns a copy of the string s with all
-// non-overlapping instances of old replaced by new.
-// If old is empty, it matches at the beginning of the string
-// and after each UTF-8 sequence, yielding up to k+1 replacements
-// for a k-rune string.
-func ReplaceAll(s, old, new string) string {
- return Replace(s, old, new, -1)
-}
-
-// EqualFold reports whether s and t, interpreted as UTF-8 strings,
-// are equal under simple Unicode case-folding, which is a more general
-// form of case-insensitivity.
-func EqualFold(s, t string) bool {
- // ASCII fast path
- i := 0
- for ; i < len(s) && i < len(t); i++ {
- sr := s[i]
- tr := t[i]
- if sr|tr >= utf8.RuneSelf {
- goto hasUnicode
- }
-
- // Easy case.
- if tr == sr {
- continue
- }
-
- // Make sr < tr to simplify what follows.
- if tr < sr {
- tr, sr = sr, tr
- }
- // ASCII only, sr/tr must be upper/lower case
- if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
- continue
- }
- return false
- }
- // Check if we've exhausted both strings.
- return len(s) == len(t)
-
-hasUnicode:
- s = s[i:]
- t = t[i:]
- for _, sr := range s {
- // If t is exhausted the strings are not equal.
- if len(t) == 0 {
- return false
- }
-
- // Extract first rune from second string.
- var tr rune
- if t[0] < utf8.RuneSelf {
- tr, t = rune(t[0]), t[1:]
- } else {
- r, size := utf8.DecodeRuneInString(t)
- tr, t = r, t[size:]
- }
-
- // If they match, keep going; if not, return false.
-
- // Easy case.
- if tr == sr {
- continue
- }
-
- // Make sr < tr to simplify what follows.
- if tr < sr {
- tr, sr = sr, tr
- }
- // Fast check for ASCII.
- if tr < utf8.RuneSelf {
- // ASCII only, sr/tr must be upper/lower case
- if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
- continue
- }
- return false
- }
-
- // General case. SimpleFold(x) returns the next equivalent rune > x
- // or wraps around to smaller values.
- r := unicode.SimpleFold(sr)
- for r != sr && r < tr {
- r = unicode.SimpleFold(r)
- }
- if r == tr {
- continue
- }
- return false
- }
-
- // First string is empty, so check if the second one is also empty.
- return len(t) == 0
-}
-
-// Index returns the index of the first instance of substr in s, or -1 if substr is not present in s.
-func Index(s, substr string) int {
- n := len(substr)
- switch {
- case n == 0:
- return 0
- case n == 1:
- return IndexByte(s, substr[0])
- case n == len(s):
- if substr == s {
- return 0
- }
- return -1
- case n > len(s):
- return -1
- case n <= bytealg.MaxLen:
- // Use brute force when s and substr both are small
- if len(s) <= bytealg.MaxBruteForce {
- return bytealg.IndexString(s, substr)
- }
- c0 := substr[0]
- c1 := substr[1]
- i := 0
- t := len(s) - n + 1
- fails := 0
- for i < t {
- if s[i] != c0 {
- // IndexByte is faster than bytealg.IndexString, so use it as long as
- // we're not getting lots of false positives.
- o := IndexByte(s[i+1:t], c0)
- if o < 0 {
- return -1
- }
- i += o + 1
- }
- if s[i+1] == c1 && s[i:i+n] == substr {
- return i
- }
- fails++
- i++
- // Switch to bytealg.IndexString when IndexByte produces too many false positives.
- if fails > bytealg.Cutover(i) {
- r := bytealg.IndexString(s[i:], substr)
- if r >= 0 {
- return r + i
- }
- return -1
- }
- }
- return -1
- }
- c0 := substr[0]
- c1 := substr[1]
- i := 0
- t := len(s) - n + 1
- fails := 0
- for i < t {
- if s[i] != c0 {
- o := IndexByte(s[i+1:t], c0)
- if o < 0 {
- return -1
- }
- i += o + 1
- }
- if s[i+1] == c1 && s[i:i+n] == substr {
- return i
- }
- i++
- fails++
- if fails >= 4+i>>4 && i < t {
- // See comment in ../bytes/bytes.go.
- j := bytealg.IndexRabinKarp(s[i:], substr)
- if j < 0 {
- return -1
- }
- return i + j
- }
- }
- return -1
-}
-
-// Cut slices s around the first instance of sep,
-// returning the text before and after sep.
-// The found result reports whether sep appears in s.
-// If sep does not appear in s, cut returns s, "", false.
-func Cut(s, sep string) (before, after string, found bool) {
- if i := Index(s, sep); i >= 0 {
- return s[:i], s[i+len(sep):], true
- }
- return s, "", false
-}
-
-// CutPrefix returns s without the provided leading prefix string
-// and reports whether it found the prefix.
-// If s doesn't start with prefix, CutPrefix returns s, false.
-// If prefix is the empty string, CutPrefix returns s, true.
-func CutPrefix(s, prefix string) (after string, found bool) {
- if !HasPrefix(s, prefix) {
- return s, false
- }
- return s[len(prefix):], true
-}
-
-// CutSuffix returns s without the provided ending suffix string
-// and reports whether it found the suffix.
-// If s doesn't end with suffix, CutSuffix returns s, false.
-// If suffix is the empty string, CutSuffix returns s, true.
-func CutSuffix(s, suffix string) (before string, found bool) {
- if !HasSuffix(s, suffix) {
- return s, false
- }
- return s[:len(s)-len(suffix)], true
-}
diff --git a/contrib/go/_std_1.20/src/strings/ya.make b/contrib/go/_std_1.20/src/strings/ya.make
deleted file mode 100644
index 56d0536fd0..0000000000
--- a/contrib/go/_std_1.20/src/strings/ya.make
+++ /dev/null
@@ -1,13 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- builder.go
- clone.go
- compare.go
- reader.go
- replace.go
- search.go
- strings.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/sync/atomic/doc.go b/contrib/go/_std_1.20/src/sync/atomic/doc.go
deleted file mode 100644
index 472ab9df04..0000000000
--- a/contrib/go/_std_1.20/src/sync/atomic/doc.go
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2011 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 atomic provides low-level atomic memory primitives
-// useful for implementing synchronization algorithms.
-//
-// These functions require great care to be used correctly.
-// Except for special, low-level applications, synchronization is better
-// done with channels or the facilities of the sync package.
-// Share memory by communicating;
-// don't communicate by sharing memory.
-//
-// The swap operation, implemented by the SwapT functions, is the atomic
-// equivalent of:
-//
-// old = *addr
-// *addr = new
-// return old
-//
-// The compare-and-swap operation, implemented by the CompareAndSwapT
-// functions, is the atomic equivalent of:
-//
-// if *addr == old {
-// *addr = new
-// return true
-// }
-// return false
-//
-// The add operation, implemented by the AddT functions, is the atomic
-// equivalent of:
-//
-// *addr += delta
-// return *addr
-//
-// The load and store operations, implemented by the LoadT and StoreT
-// functions, are the atomic equivalents of "return *addr" and
-// "*addr = val".
-//
-// In the terminology of the Go memory model, if the effect of
-// an atomic operation A is observed by atomic operation B,
-// then A “synchronizes before” B.
-// Additionally, all the atomic operations executed in a program
-// behave as though executed in some sequentially consistent order.
-// This definition provides the same semantics as
-// C++'s sequentially consistent atomics and Java's volatile variables.
-package atomic
-
-import (
- "unsafe"
-)
-
-// BUG(rsc): On 386, the 64-bit functions use instructions unavailable before the Pentium MMX.
-//
-// On non-Linux ARM, the 64-bit functions use instructions unavailable before the ARMv6k core.
-//
-// On ARM, 386, and 32-bit MIPS, it is the caller's responsibility to arrange
-// for 64-bit alignment of 64-bit words accessed atomically via the primitive
-// atomic functions (types [Int64] and [Uint64] are automatically aligned).
-// The first word in an allocated struct, array, or slice; in a global
-// variable; or in a local variable (because the subject of all atomic operations
-// will escape to the heap) can be relied upon to be 64-bit aligned.
-
-// SwapInt32 atomically stores new into *addr and returns the previous *addr value.
-// Consider using the more ergonomic and less error-prone [Int32.Swap] instead.
-func SwapInt32(addr *int32, new int32) (old int32)
-
-// SwapInt64 atomically stores new into *addr and returns the previous *addr value.
-// Consider using the more ergonomic and less error-prone [Int64.Swap] instead
-// (particularly if you target 32-bit platforms; see the bugs section).
-func SwapInt64(addr *int64, new int64) (old int64)
-
-// SwapUint32 atomically stores new into *addr and returns the previous *addr value.
-// Consider using the more ergonomic and less error-prone [Uint32.Swap] instead.
-func SwapUint32(addr *uint32, new uint32) (old uint32)
-
-// SwapUint64 atomically stores new into *addr and returns the previous *addr value.
-// Consider using the more ergonomic and less error-prone [Uint64.Swap] instead
-// (particularly if you target 32-bit platforms; see the bugs section).
-func SwapUint64(addr *uint64, new uint64) (old uint64)
-
-// SwapUintptr atomically stores new into *addr and returns the previous *addr value.
-// Consider using the more ergonomic and less error-prone [Uintptr.Swap] instead.
-func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)
-
-// SwapPointer atomically stores new into *addr and returns the previous *addr value.
-// Consider using the more ergonomic and less error-prone [Pointer.Swap] instead.
-func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)
-
-// CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value.
-// Consider using the more ergonomic and less error-prone [Int32.CompareAndSwap] instead.
-func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
-
-// CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value.
-// Consider using the more ergonomic and less error-prone [Int64.CompareAndSwap] instead
-// (particularly if you target 32-bit platforms; see the bugs section).
-func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
-
-// CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value.
-// Consider using the more ergonomic and less error-prone [Uint32.CompareAndSwap] instead.
-func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
-
-// CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value.
-// Consider using the more ergonomic and less error-prone [Uint64.CompareAndSwap] instead
-// (particularly if you target 32-bit platforms; see the bugs section).
-func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
-
-// CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value.
-// Consider using the more ergonomic and less error-prone [Uintptr.CompareAndSwap] instead.
-func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)
-
-// CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value.
-// Consider using the more ergonomic and less error-prone [Pointer.CompareAndSwap] instead.
-func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)
-
-// AddInt32 atomically adds delta to *addr and returns the new value.
-// Consider using the more ergonomic and less error-prone [Int32.Add] instead.
-func AddInt32(addr *int32, delta int32) (new int32)
-
-// AddUint32 atomically adds delta to *addr and returns the new value.
-// To subtract a signed positive constant value c from x, do AddUint32(&x, ^uint32(c-1)).
-// In particular, to decrement x, do AddUint32(&x, ^uint32(0)).
-// Consider using the more ergonomic and less error-prone [Uint32.Add] instead.
-func AddUint32(addr *uint32, delta uint32) (new uint32)
-
-// AddInt64 atomically adds delta to *addr and returns the new value.
-// Consider using the more ergonomic and less error-prone [Int64.Add] instead
-// (particularly if you target 32-bit platforms; see the bugs section).
-func AddInt64(addr *int64, delta int64) (new int64)
-
-// AddUint64 atomically adds delta to *addr and returns the new value.
-// To subtract a signed positive constant value c from x, do AddUint64(&x, ^uint64(c-1)).
-// In particular, to decrement x, do AddUint64(&x, ^uint64(0)).
-// Consider using the more ergonomic and less error-prone [Uint64.Add] instead
-// (particularly if you target 32-bit platforms; see the bugs section).
-func AddUint64(addr *uint64, delta uint64) (new uint64)
-
-// AddUintptr atomically adds delta to *addr and returns the new value.
-// Consider using the more ergonomic and less error-prone [Uintptr.Add] instead.
-func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
-
-// LoadInt32 atomically loads *addr.
-// Consider using the more ergonomic and less error-prone [Int32.Load] instead.
-func LoadInt32(addr *int32) (val int32)
-
-// LoadInt64 atomically loads *addr.
-// Consider using the more ergonomic and less error-prone [Int64.Load] instead
-// (particularly if you target 32-bit platforms; see the bugs section).
-func LoadInt64(addr *int64) (val int64)
-
-// LoadUint32 atomically loads *addr.
-// Consider using the more ergonomic and less error-prone [Uint32.Load] instead.
-func LoadUint32(addr *uint32) (val uint32)
-
-// LoadUint64 atomically loads *addr.
-// Consider using the more ergonomic and less error-prone [Uint64.Load] instead
-// (particularly if you target 32-bit platforms; see the bugs section).
-func LoadUint64(addr *uint64) (val uint64)
-
-// LoadUintptr atomically loads *addr.
-// Consider using the more ergonomic and less error-prone [Uintptr.Load] instead.
-func LoadUintptr(addr *uintptr) (val uintptr)
-
-// LoadPointer atomically loads *addr.
-// Consider using the more ergonomic and less error-prone [Pointer.Load] instead.
-func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
-
-// StoreInt32 atomically stores val into *addr.
-// Consider using the more ergonomic and less error-prone [Int32.Store] instead.
-func StoreInt32(addr *int32, val int32)
-
-// StoreInt64 atomically stores val into *addr.
-// Consider using the more ergonomic and less error-prone [Int64.Store] instead
-// (particularly if you target 32-bit platforms; see the bugs section).
-func StoreInt64(addr *int64, val int64)
-
-// StoreUint32 atomically stores val into *addr.
-// Consider using the more ergonomic and less error-prone [Uint32.Store] instead.
-func StoreUint32(addr *uint32, val uint32)
-
-// StoreUint64 atomically stores val into *addr.
-// Consider using the more ergonomic and less error-prone [Uint64.Store] instead
-// (particularly if you target 32-bit platforms; see the bugs section).
-func StoreUint64(addr *uint64, val uint64)
-
-// StoreUintptr atomically stores val into *addr.
-// Consider using the more ergonomic and less error-prone [Uintptr.Store] instead.
-func StoreUintptr(addr *uintptr, val uintptr)
-
-// StorePointer atomically stores val into *addr.
-// Consider using the more ergonomic and less error-prone [Pointer.Store] instead.
-func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)
diff --git a/contrib/go/_std_1.20/src/sync/atomic/type.go b/contrib/go/_std_1.20/src/sync/atomic/type.go
deleted file mode 100644
index cc016833d1..0000000000
--- a/contrib/go/_std_1.20/src/sync/atomic/type.go
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2022 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 atomic
-
-import "unsafe"
-
-// A Bool is an atomic boolean value.
-// The zero value is false.
-type Bool struct {
- _ noCopy
- v uint32
-}
-
-// Load atomically loads and returns the value stored in x.
-func (x *Bool) Load() bool { return LoadUint32(&x.v) != 0 }
-
-// Store atomically stores val into x.
-func (x *Bool) Store(val bool) { StoreUint32(&x.v, b32(val)) }
-
-// Swap atomically stores new into x and returns the previous value.
-func (x *Bool) Swap(new bool) (old bool) { return SwapUint32(&x.v, b32(new)) != 0 }
-
-// CompareAndSwap executes the compare-and-swap operation for the boolean value x.
-func (x *Bool) CompareAndSwap(old, new bool) (swapped bool) {
- return CompareAndSwapUint32(&x.v, b32(old), b32(new))
-}
-
-// b32 returns a uint32 0 or 1 representing b.
-func b32(b bool) uint32 {
- if b {
- return 1
- }
- return 0
-}
-
-// For testing *Pointer[T]'s methods can be inlined.
-// Keep in sync with cmd/compile/internal/test/inl_test.go:TestIntendedInlining.
-var _ = &Pointer[int]{}
-
-// A Pointer is an atomic pointer of type *T. The zero value is a nil *T.
-type Pointer[T any] struct {
- // Mention *T in a field to disallow conversion between Pointer types.
- // See go.dev/issue/56603 for more details.
- // Use *T, not T, to avoid spurious recursive type definition errors.
- _ [0]*T
-
- _ noCopy
- v unsafe.Pointer
-}
-
-// Load atomically loads and returns the value stored in x.
-func (x *Pointer[T]) Load() *T { return (*T)(LoadPointer(&x.v)) }
-
-// Store atomically stores val into x.
-func (x *Pointer[T]) Store(val *T) { StorePointer(&x.v, unsafe.Pointer(val)) }
-
-// Swap atomically stores new into x and returns the previous value.
-func (x *Pointer[T]) Swap(new *T) (old *T) { return (*T)(SwapPointer(&x.v, unsafe.Pointer(new))) }
-
-// CompareAndSwap executes the compare-and-swap operation for x.
-func (x *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) {
- return CompareAndSwapPointer(&x.v, unsafe.Pointer(old), unsafe.Pointer(new))
-}
-
-// An Int32 is an atomic int32. The zero value is zero.
-type Int32 struct {
- _ noCopy
- v int32
-}
-
-// Load atomically loads and returns the value stored in x.
-func (x *Int32) Load() int32 { return LoadInt32(&x.v) }
-
-// Store atomically stores val into x.
-func (x *Int32) Store(val int32) { StoreInt32(&x.v, val) }
-
-// Swap atomically stores new into x and returns the previous value.
-func (x *Int32) Swap(new int32) (old int32) { return SwapInt32(&x.v, new) }
-
-// CompareAndSwap executes the compare-and-swap operation for x.
-func (x *Int32) CompareAndSwap(old, new int32) (swapped bool) {
- return CompareAndSwapInt32(&x.v, old, new)
-}
-
-// Add atomically adds delta to x and returns the new value.
-func (x *Int32) Add(delta int32) (new int32) { return AddInt32(&x.v, delta) }
-
-// An Int64 is an atomic int64. The zero value is zero.
-type Int64 struct {
- _ noCopy
- _ align64
- v int64
-}
-
-// Load atomically loads and returns the value stored in x.
-func (x *Int64) Load() int64 { return LoadInt64(&x.v) }
-
-// Store atomically stores val into x.
-func (x *Int64) Store(val int64) { StoreInt64(&x.v, val) }
-
-// Swap atomically stores new into x and returns the previous value.
-func (x *Int64) Swap(new int64) (old int64) { return SwapInt64(&x.v, new) }
-
-// CompareAndSwap executes the compare-and-swap operation for x.
-func (x *Int64) CompareAndSwap(old, new int64) (swapped bool) {
- return CompareAndSwapInt64(&x.v, old, new)
-}
-
-// Add atomically adds delta to x and returns the new value.
-func (x *Int64) Add(delta int64) (new int64) { return AddInt64(&x.v, delta) }
-
-// An Uint32 is an atomic uint32. The zero value is zero.
-type Uint32 struct {
- _ noCopy
- v uint32
-}
-
-// Load atomically loads and returns the value stored in x.
-func (x *Uint32) Load() uint32 { return LoadUint32(&x.v) }
-
-// Store atomically stores val into x.
-func (x *Uint32) Store(val uint32) { StoreUint32(&x.v, val) }
-
-// Swap atomically stores new into x and returns the previous value.
-func (x *Uint32) Swap(new uint32) (old uint32) { return SwapUint32(&x.v, new) }
-
-// CompareAndSwap executes the compare-and-swap operation for x.
-func (x *Uint32) CompareAndSwap(old, new uint32) (swapped bool) {
- return CompareAndSwapUint32(&x.v, old, new)
-}
-
-// Add atomically adds delta to x and returns the new value.
-func (x *Uint32) Add(delta uint32) (new uint32) { return AddUint32(&x.v, delta) }
-
-// An Uint64 is an atomic uint64. The zero value is zero.
-type Uint64 struct {
- _ noCopy
- _ align64
- v uint64
-}
-
-// Load atomically loads and returns the value stored in x.
-func (x *Uint64) Load() uint64 { return LoadUint64(&x.v) }
-
-// Store atomically stores val into x.
-func (x *Uint64) Store(val uint64) { StoreUint64(&x.v, val) }
-
-// Swap atomically stores new into x and returns the previous value.
-func (x *Uint64) Swap(new uint64) (old uint64) { return SwapUint64(&x.v, new) }
-
-// CompareAndSwap executes the compare-and-swap operation for x.
-func (x *Uint64) CompareAndSwap(old, new uint64) (swapped bool) {
- return CompareAndSwapUint64(&x.v, old, new)
-}
-
-// Add atomically adds delta to x and returns the new value.
-func (x *Uint64) Add(delta uint64) (new uint64) { return AddUint64(&x.v, delta) }
-
-// An Uintptr is an atomic uintptr. The zero value is zero.
-type Uintptr struct {
- _ noCopy
- v uintptr
-}
-
-// Load atomically loads and returns the value stored in x.
-func (x *Uintptr) Load() uintptr { return LoadUintptr(&x.v) }
-
-// Store atomically stores val into x.
-func (x *Uintptr) Store(val uintptr) { StoreUintptr(&x.v, val) }
-
-// Swap atomically stores new into x and returns the previous value.
-func (x *Uintptr) Swap(new uintptr) (old uintptr) { return SwapUintptr(&x.v, new) }
-
-// CompareAndSwap executes the compare-and-swap operation for x.
-func (x *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) {
- return CompareAndSwapUintptr(&x.v, old, new)
-}
-
-// Add atomically adds delta to x and returns the new value.
-func (x *Uintptr) Add(delta uintptr) (new uintptr) { return AddUintptr(&x.v, delta) }
-
-// noCopy may be added to structs which must not be copied
-// after the first use.
-//
-// See https://golang.org/issues/8005#issuecomment-190753527
-// for details.
-//
-// Note that it must not be embedded, due to the Lock and Unlock methods.
-type noCopy struct{}
-
-// Lock is a no-op used by -copylocks checker from `go vet`.
-func (*noCopy) Lock() {}
-func (*noCopy) Unlock() {}
-
-// align64 may be added to structs that must be 64-bit aligned.
-// This struct is recognized by a special case in the compiler
-// and will not work if copied to any other package.
-type align64 struct{}
diff --git a/contrib/go/_std_1.20/src/sync/atomic/ya.make b/contrib/go/_std_1.20/src/sync/atomic/ya.make
deleted file mode 100644
index bc80c285d4..0000000000
--- a/contrib/go/_std_1.20/src/sync/atomic/ya.make
+++ /dev/null
@@ -1,19 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- doc.go
- type.go
- value.go
-)
-
-IF (RACE)
- SRCS(
- race.s
- )
-ELSE()
- SRCS(
- asm.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/sync/rwmutex.go b/contrib/go/_std_1.20/src/sync/rwmutex.go
deleted file mode 100644
index ad52951311..0000000000
--- a/contrib/go/_std_1.20/src/sync/rwmutex.go
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2009 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 sync
-
-import (
- "internal/race"
- "sync/atomic"
- "unsafe"
-)
-
-// There is a modified copy of this file in runtime/rwmutex.go.
-// If you make any changes here, see if you should make them there.
-
-// A RWMutex is a reader/writer mutual exclusion lock.
-// The lock can be held by an arbitrary number of readers or a single writer.
-// The zero value for a RWMutex is an unlocked mutex.
-//
-// A RWMutex must not be copied after first use.
-//
-// If a goroutine holds a RWMutex for reading and another goroutine might
-// call Lock, no goroutine should expect to be able to acquire a read lock
-// until the initial read lock is released. In particular, this prohibits
-// recursive read locking. This is to ensure that the lock eventually becomes
-// available; a blocked Lock call excludes new readers from acquiring the
-// lock.
-//
-// In the terminology of the Go memory model,
-// the n'th call to Unlock “synchronizes before” the m'th call to Lock
-// for any n < m, just as for Mutex.
-// For any call to RLock, there exists an n such that
-// the n'th call to Unlock “synchronizes before” that call to RLock,
-// and the corresponding call to RUnlock “synchronizes before”
-// the n+1'th call to Lock.
-type RWMutex struct {
- w Mutex // held if there are pending writers
- writerSem uint32 // semaphore for writers to wait for completing readers
- readerSem uint32 // semaphore for readers to wait for completing writers
- readerCount atomic.Int32 // number of pending readers
- readerWait atomic.Int32 // number of departing readers
-}
-
-const rwmutexMaxReaders = 1 << 30
-
-// Happens-before relationships are indicated to the race detector via:
-// - Unlock -> Lock: readerSem
-// - Unlock -> RLock: readerSem
-// - RUnlock -> Lock: writerSem
-//
-// The methods below temporarily disable handling of race synchronization
-// events in order to provide the more precise model above to the race
-// detector.
-//
-// For example, atomic.AddInt32 in RLock should not appear to provide
-// acquire-release semantics, which would incorrectly synchronize racing
-// readers, thus potentially missing races.
-
-// RLock locks rw for reading.
-//
-// It should not be used for recursive read locking; a blocked Lock
-// call excludes new readers from acquiring the lock. See the
-// documentation on the RWMutex type.
-func (rw *RWMutex) RLock() {
- if race.Enabled {
- _ = rw.w.state
- race.Disable()
- }
- if rw.readerCount.Add(1) < 0 {
- // A writer is pending, wait for it.
- runtime_SemacquireRWMutexR(&rw.readerSem, false, 0)
- }
- if race.Enabled {
- race.Enable()
- race.Acquire(unsafe.Pointer(&rw.readerSem))
- }
-}
-
-// TryRLock tries to lock rw for reading and reports whether it succeeded.
-//
-// Note that while correct uses of TryRLock do exist, they are rare,
-// and use of TryRLock is often a sign of a deeper problem
-// in a particular use of mutexes.
-func (rw *RWMutex) TryRLock() bool {
- if race.Enabled {
- _ = rw.w.state
- race.Disable()
- }
- for {
- c := rw.readerCount.Load()
- if c < 0 {
- if race.Enabled {
- race.Enable()
- }
- return false
- }
- if rw.readerCount.CompareAndSwap(c, c+1) {
- if race.Enabled {
- race.Enable()
- race.Acquire(unsafe.Pointer(&rw.readerSem))
- }
- return true
- }
- }
-}
-
-// RUnlock undoes a single RLock call;
-// it does not affect other simultaneous readers.
-// It is a run-time error if rw is not locked for reading
-// on entry to RUnlock.
-func (rw *RWMutex) RUnlock() {
- if race.Enabled {
- _ = rw.w.state
- race.ReleaseMerge(unsafe.Pointer(&rw.writerSem))
- race.Disable()
- }
- if r := rw.readerCount.Add(-1); r < 0 {
- // Outlined slow-path to allow the fast-path to be inlined
- rw.rUnlockSlow(r)
- }
- if race.Enabled {
- race.Enable()
- }
-}
-
-func (rw *RWMutex) rUnlockSlow(r int32) {
- if r+1 == 0 || r+1 == -rwmutexMaxReaders {
- race.Enable()
- fatal("sync: RUnlock of unlocked RWMutex")
- }
- // A writer is pending.
- if rw.readerWait.Add(-1) == 0 {
- // The last reader unblocks the writer.
- runtime_Semrelease(&rw.writerSem, false, 1)
- }
-}
-
-// Lock locks rw for writing.
-// If the lock is already locked for reading or writing,
-// Lock blocks until the lock is available.
-func (rw *RWMutex) Lock() {
- if race.Enabled {
- _ = rw.w.state
- race.Disable()
- }
- // First, resolve competition with other writers.
- rw.w.Lock()
- // Announce to readers there is a pending writer.
- r := rw.readerCount.Add(-rwmutexMaxReaders) + rwmutexMaxReaders
- // Wait for active readers.
- if r != 0 && rw.readerWait.Add(r) != 0 {
- runtime_SemacquireRWMutex(&rw.writerSem, false, 0)
- }
- if race.Enabled {
- race.Enable()
- race.Acquire(unsafe.Pointer(&rw.readerSem))
- race.Acquire(unsafe.Pointer(&rw.writerSem))
- }
-}
-
-// TryLock tries to lock rw for writing and reports whether it succeeded.
-//
-// Note that while correct uses of TryLock do exist, they are rare,
-// and use of TryLock is often a sign of a deeper problem
-// in a particular use of mutexes.
-func (rw *RWMutex) TryLock() bool {
- if race.Enabled {
- _ = rw.w.state
- race.Disable()
- }
- if !rw.w.TryLock() {
- if race.Enabled {
- race.Enable()
- }
- return false
- }
- if !rw.readerCount.CompareAndSwap(0, -rwmutexMaxReaders) {
- rw.w.Unlock()
- if race.Enabled {
- race.Enable()
- }
- return false
- }
- if race.Enabled {
- race.Enable()
- race.Acquire(unsafe.Pointer(&rw.readerSem))
- race.Acquire(unsafe.Pointer(&rw.writerSem))
- }
- return true
-}
-
-// Unlock unlocks rw for writing. It is a run-time error if rw is
-// not locked for writing on entry to Unlock.
-//
-// As with Mutexes, a locked RWMutex is not associated with a particular
-// goroutine. One goroutine may RLock (Lock) a RWMutex and then
-// arrange for another goroutine to RUnlock (Unlock) it.
-func (rw *RWMutex) Unlock() {
- if race.Enabled {
- _ = rw.w.state
- race.Release(unsafe.Pointer(&rw.readerSem))
- race.Disable()
- }
-
- // Announce to readers there is no active writer.
- r := rw.readerCount.Add(rwmutexMaxReaders)
- if r >= rwmutexMaxReaders {
- race.Enable()
- fatal("sync: Unlock of unlocked RWMutex")
- }
- // Unblock blocked readers, if any.
- for i := 0; i < int(r); i++ {
- runtime_Semrelease(&rw.readerSem, false, 0)
- }
- // Allow other writers to proceed.
- rw.w.Unlock()
- if race.Enabled {
- race.Enable()
- }
-}
-
-// RLocker returns a Locker interface that implements
-// the Lock and Unlock methods by calling rw.RLock and rw.RUnlock.
-func (rw *RWMutex) RLocker() Locker {
- return (*rlocker)(rw)
-}
-
-type rlocker RWMutex
-
-func (r *rlocker) Lock() { (*RWMutex)(r).RLock() }
-func (r *rlocker) Unlock() { (*RWMutex)(r).RUnlock() }
diff --git a/contrib/go/_std_1.20/src/sync/ya.make b/contrib/go/_std_1.20/src/sync/ya.make
deleted file mode 100644
index 4df945f2e2..0000000000
--- a/contrib/go/_std_1.20/src/sync/ya.make
+++ /dev/null
@@ -1,20 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- cond.go
- map.go
- mutex.go
- once.go
- pool.go
- poolqueue.go
- runtime.go
- runtime2.go
- rwmutex.go
- waitgroup.go
-)
-
-END()
-
-RECURSE(
- atomic
-)
diff --git a/contrib/go/_std_1.20/src/syscall/dirent.go b/contrib/go/_std_1.20/src/syscall/dirent.go
deleted file mode 100644
index b10608a662..0000000000
--- a/contrib/go/_std_1.20/src/syscall/dirent.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix || (js && wasm)
-
-package syscall
-
-import "unsafe"
-
-// readInt returns the size-bytes unsigned integer in native byte order at offset off.
-func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
- if len(b) < int(off+size) {
- return 0, false
- }
- if isBigEndian {
- return readIntBE(b[off:], size), true
- }
- return readIntLE(b[off:], size), true
-}
-
-func readIntBE(b []byte, size uintptr) uint64 {
- switch size {
- case 1:
- return uint64(b[0])
- case 2:
- _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[1]) | uint64(b[0])<<8
- case 4:
- _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24
- case 8:
- _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
- uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
- default:
- panic("syscall: readInt with unsupported size")
- }
-}
-
-func readIntLE(b []byte, size uintptr) uint64 {
- switch size {
- case 1:
- return uint64(b[0])
- case 2:
- _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[0]) | uint64(b[1])<<8
- case 4:
- _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
- case 8:
- _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
- return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
- uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
- default:
- panic("syscall: readInt with unsupported size")
- }
-}
-
-// ParseDirent parses up to max directory entries in buf,
-// appending the names to names. It returns the number of
-// bytes consumed from buf, the number of entries added
-// to names, and the new names slice.
-func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
- origlen := len(buf)
- count = 0
- for max != 0 && len(buf) > 0 {
- reclen, ok := direntReclen(buf)
- if !ok || reclen > uint64(len(buf)) {
- return origlen, count, names
- }
- rec := buf[:reclen]
- buf = buf[reclen:]
- ino, ok := direntIno(rec)
- if !ok {
- break
- }
- if ino == 0 { // File absent in directory.
- continue
- }
- const namoff = uint64(unsafe.Offsetof(Dirent{}.Name))
- namlen, ok := direntNamlen(rec)
- if !ok || namoff+namlen > uint64(len(rec)) {
- break
- }
- name := rec[namoff : namoff+namlen]
- for i, c := range name {
- if c == 0 {
- name = name[:i]
- break
- }
- }
- // Check for useless names before allocating a string.
- if string(name) == "." || string(name) == ".." {
- continue
- }
- max--
- count++
- names = append(names, string(name))
- }
- return origlen - len(buf), count, names
-}
diff --git a/contrib/go/_std_1.20/src/syscall/dll_windows.go b/contrib/go/_std_1.20/src/syscall/dll_windows.go
deleted file mode 100644
index 34b481d6e6..0000000000
--- a/contrib/go/_std_1.20/src/syscall/dll_windows.go
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2011 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 syscall
-
-import (
- "internal/syscall/windows/sysdll"
- "sync"
- "sync/atomic"
- "unsafe"
-)
-
-// DLLError describes reasons for DLL load failures.
-type DLLError struct {
- Err error
- ObjName string
- Msg string
-}
-
-func (e *DLLError) Error() string { return e.Msg }
-
-func (e *DLLError) Unwrap() error { return e.Err }
-
-// Implemented in ../runtime/syscall_windows.go.
-
-// Deprecated: Use SyscallN instead.
-func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
-
-// Deprecated: Use SyscallN instead.
-func Syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
-
-// Deprecated: Use SyscallN instead.
-func Syscall9(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
-
-// Deprecated: Use SyscallN instead.
-func Syscall12(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2 uintptr, err Errno)
-
-// Deprecated: Use SyscallN instead.
-func Syscall15(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2 uintptr, err Errno)
-
-// Deprecated: Use SyscallN instead.
-func Syscall18(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 uintptr) (r1, r2 uintptr, err Errno)
-
-func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno)
-func loadlibrary(filename *uint16) (handle uintptr, err Errno)
-func loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle uintptr, err Errno)
-func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno)
-
-// A DLL implements access to a single DLL.
-type DLL struct {
- Name string
- Handle Handle
-}
-
-// We use this for computing the absolute path for system DLLs on systems
-// where SEARCH_SYSTEM32 is not available.
-var systemDirectoryPrefix string
-
-func init() {
- n := uint32(MAX_PATH)
- for {
- b := make([]uint16, n)
- l, e := getSystemDirectory(&b[0], n)
- if e != nil {
- panic("Unable to determine system directory: " + e.Error())
- }
- if l <= n {
- systemDirectoryPrefix = UTF16ToString(b[:l]) + "\\"
- break
- }
- n = l
- }
-}
-
-// LoadDLL loads the named DLL file into memory.
-//
-// If name is not an absolute path and is not a known system DLL used by
-// Go, Windows will search for the named DLL in many locations, causing
-// potential DLL preloading attacks.
-//
-// Use LazyDLL in golang.org/x/sys/windows for a secure way to
-// load system DLLs.
-func LoadDLL(name string) (*DLL, error) {
- namep, err := UTF16PtrFromString(name)
- if err != nil {
- return nil, err
- }
- var h uintptr
- var e Errno
- if sysdll.IsSystemDLL[name] {
- absoluteFilepathp, err := UTF16PtrFromString(systemDirectoryPrefix + name)
- if err != nil {
- return nil, err
- }
- h, e = loadsystemlibrary(namep, absoluteFilepathp)
- } else {
- h, e = loadlibrary(namep)
- }
- if e != 0 {
- return nil, &DLLError{
- Err: e,
- ObjName: name,
- Msg: "Failed to load " + name + ": " + e.Error(),
- }
- }
- d := &DLL{
- Name: name,
- Handle: Handle(h),
- }
- return d, nil
-}
-
-// MustLoadDLL is like LoadDLL but panics if load operation fails.
-func MustLoadDLL(name string) *DLL {
- d, e := LoadDLL(name)
- if e != nil {
- panic(e)
- }
- return d
-}
-
-// FindProc searches DLL d for procedure named name and returns *Proc
-// if found. It returns an error if search fails.
-func (d *DLL) FindProc(name string) (proc *Proc, err error) {
- namep, err := BytePtrFromString(name)
- if err != nil {
- return nil, err
- }
- a, e := getprocaddress(uintptr(d.Handle), namep)
- if e != 0 {
- return nil, &DLLError{
- Err: e,
- ObjName: name,
- Msg: "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
- }
- }
- p := &Proc{
- Dll: d,
- Name: name,
- addr: a,
- }
- return p, nil
-}
-
-// MustFindProc is like FindProc but panics if search fails.
-func (d *DLL) MustFindProc(name string) *Proc {
- p, e := d.FindProc(name)
- if e != nil {
- panic(e)
- }
- return p
-}
-
-// Release unloads DLL d from memory.
-func (d *DLL) Release() (err error) {
- return FreeLibrary(d.Handle)
-}
-
-// A Proc implements access to a procedure inside a DLL.
-type Proc struct {
- Dll *DLL
- Name string
- addr uintptr
-}
-
-// Addr returns the address of the procedure represented by p.
-// The return value can be passed to Syscall to run the procedure.
-func (p *Proc) Addr() uintptr {
- return p.addr
-}
-
-//go:uintptrescapes
-
-// Call executes procedure p with arguments a.
-//
-// The returned error is always non-nil, constructed from the result of GetLastError.
-// Callers must inspect the primary return value to decide whether an error occurred
-// (according to the semantics of the specific function being called) before consulting
-// the error. The error always has type syscall.Errno.
-//
-// On amd64, Call can pass and return floating-point values. To pass
-// an argument x with C type "float", use
-// uintptr(math.Float32bits(x)). To pass an argument with C type
-// "double", use uintptr(math.Float64bits(x)). Floating-point return
-// values are returned in r2. The return value for C type "float" is
-// math.Float32frombits(uint32(r2)). For C type "double", it is
-// math.Float64frombits(uint64(r2)).
-func (p *Proc) Call(a ...uintptr) (uintptr, uintptr, error) {
- return SyscallN(p.Addr(), a...)
-}
-
-// A LazyDLL implements access to a single DLL.
-// It will delay the load of the DLL until the first
-// call to its Handle method or to one of its
-// LazyProc's Addr method.
-//
-// LazyDLL is subject to the same DLL preloading attacks as documented
-// on LoadDLL.
-//
-// Use LazyDLL in golang.org/x/sys/windows for a secure way to
-// load system DLLs.
-type LazyDLL struct {
- mu sync.Mutex
- dll *DLL // non nil once DLL is loaded
- Name string
-}
-
-// Load loads DLL file d.Name into memory. It returns an error if fails.
-// Load will not try to load DLL, if it is already loaded into memory.
-func (d *LazyDLL) Load() error {
- // Non-racy version of:
- // if d.dll == nil {
- if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) == nil {
- d.mu.Lock()
- defer d.mu.Unlock()
- if d.dll == nil {
- dll, e := LoadDLL(d.Name)
- if e != nil {
- return e
- }
- // Non-racy version of:
- // d.dll = dll
- atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll))
- }
- }
- return nil
-}
-
-// mustLoad is like Load but panics if search fails.
-func (d *LazyDLL) mustLoad() {
- e := d.Load()
- if e != nil {
- panic(e)
- }
-}
-
-// Handle returns d's module handle.
-func (d *LazyDLL) Handle() uintptr {
- d.mustLoad()
- return uintptr(d.dll.Handle)
-}
-
-// NewProc returns a LazyProc for accessing the named procedure in the DLL d.
-func (d *LazyDLL) NewProc(name string) *LazyProc {
- return &LazyProc{l: d, Name: name}
-}
-
-// NewLazyDLL creates new LazyDLL associated with DLL file.
-func NewLazyDLL(name string) *LazyDLL {
- return &LazyDLL{Name: name}
-}
-
-// A LazyProc implements access to a procedure inside a LazyDLL.
-// It delays the lookup until the Addr, Call, or Find method is called.
-type LazyProc struct {
- mu sync.Mutex
- Name string
- l *LazyDLL
- proc *Proc
-}
-
-// Find searches DLL for procedure named p.Name. It returns
-// an error if search fails. Find will not search procedure,
-// if it is already found and loaded into memory.
-func (p *LazyProc) Find() error {
- // Non-racy version of:
- // if p.proc == nil {
- if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil {
- p.mu.Lock()
- defer p.mu.Unlock()
- if p.proc == nil {
- e := p.l.Load()
- if e != nil {
- return e
- }
- proc, e := p.l.dll.FindProc(p.Name)
- if e != nil {
- return e
- }
- // Non-racy version of:
- // p.proc = proc
- atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc))
- }
- }
- return nil
-}
-
-// mustFind is like Find but panics if search fails.
-func (p *LazyProc) mustFind() {
- e := p.Find()
- if e != nil {
- panic(e)
- }
-}
-
-// Addr returns the address of the procedure represented by p.
-// The return value can be passed to Syscall to run the procedure.
-func (p *LazyProc) Addr() uintptr {
- p.mustFind()
- return p.proc.Addr()
-}
-
-//go:uintptrescapes
-
-// Call executes procedure p with arguments a. See the documentation of
-// Proc.Call for more information.
-func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
- p.mustFind()
- return p.proc.Call(a...)
-}
diff --git a/contrib/go/_std_1.20/src/syscall/env_unix.go b/contrib/go/_std_1.20/src/syscall/env_unix.go
deleted file mode 100644
index 6d917da208..0000000000
--- a/contrib/go/_std_1.20/src/syscall/env_unix.go
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2010 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.
-
-//go:build unix || (js && wasm) || plan9
-
-// Unix environment variables.
-
-package syscall
-
-import (
- "runtime"
- "sync"
-)
-
-var (
- // envOnce guards initialization by copyenv, which populates env.
- envOnce sync.Once
-
- // envLock guards env and envs.
- envLock sync.RWMutex
-
- // env maps from an environment variable to its first occurrence in envs.
- env map[string]int
-
- // envs is provided by the runtime. elements are expected to
- // be of the form "key=value". An empty string means deleted
- // (or a duplicate to be ignored).
- envs []string = runtime_envs()
-)
-
-func runtime_envs() []string // in package runtime
-
-func copyenv() {
- env = make(map[string]int)
- for i, s := range envs {
- for j := 0; j < len(s); j++ {
- if s[j] == '=' {
- key := s[:j]
- if _, ok := env[key]; !ok {
- env[key] = i // first mention of key
- } else {
- // Clear duplicate keys. This permits Unsetenv to
- // safely delete only the first item without
- // worrying about unshadowing a later one,
- // which might be a security problem.
- envs[i] = ""
- }
- break
- }
- }
- }
-}
-
-func Unsetenv(key string) error {
- envOnce.Do(copyenv)
-
- envLock.Lock()
- defer envLock.Unlock()
-
- if i, ok := env[key]; ok {
- envs[i] = ""
- delete(env, key)
- }
- runtimeUnsetenv(key)
- return nil
-}
-
-func Getenv(key string) (value string, found bool) {
- envOnce.Do(copyenv)
- if len(key) == 0 {
- return "", false
- }
-
- envLock.RLock()
- defer envLock.RUnlock()
-
- i, ok := env[key]
- if !ok {
- return "", false
- }
- s := envs[i]
- for i := 0; i < len(s); i++ {
- if s[i] == '=' {
- return s[i+1:], true
- }
- }
- return "", false
-}
-
-func Setenv(key, value string) error {
- envOnce.Do(copyenv)
- if len(key) == 0 {
- return EINVAL
- }
- for i := 0; i < len(key); i++ {
- if key[i] == '=' || key[i] == 0 {
- return EINVAL
- }
- }
- // On Plan 9, null is used as a separator, eg in $path.
- if runtime.GOOS != "plan9" {
- for i := 0; i < len(value); i++ {
- if value[i] == 0 {
- return EINVAL
- }
- }
- }
-
- envLock.Lock()
- defer envLock.Unlock()
-
- i, ok := env[key]
- kv := key + "=" + value
- if ok {
- envs[i] = kv
- } else {
- i = len(envs)
- envs = append(envs, kv)
- }
- env[key] = i
- runtimeSetenv(key, value)
- return nil
-}
-
-func Clearenv() {
- envOnce.Do(copyenv) // prevent copyenv in Getenv/Setenv
-
- envLock.Lock()
- defer envLock.Unlock()
-
- for k := range env {
- runtimeUnsetenv(k)
- }
- env = make(map[string]int)
- envs = []string{}
-}
-
-func Environ() []string {
- envOnce.Do(copyenv)
- envLock.RLock()
- defer envLock.RUnlock()
- a := make([]string, 0, len(envs))
- for _, env := range envs {
- if env != "" {
- a = append(a, env)
- }
- }
- return a
-}
diff --git a/contrib/go/_std_1.20/src/syscall/env_windows.go b/contrib/go/_std_1.20/src/syscall/env_windows.go
deleted file mode 100644
index 94364f930c..0000000000
--- a/contrib/go/_std_1.20/src/syscall/env_windows.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2010 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.
-
-// Windows environment variables.
-
-package syscall
-
-import (
- "unicode/utf16"
- "unsafe"
-)
-
-func Getenv(key string) (value string, found bool) {
- keyp, err := UTF16PtrFromString(key)
- if err != nil {
- return "", false
- }
- n := uint32(100)
- for {
- b := make([]uint16, n)
- n, err = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
- if n == 0 && err == ERROR_ENVVAR_NOT_FOUND {
- return "", false
- }
- if n <= uint32(len(b)) {
- return string(utf16.Decode(b[:n])), true
- }
- }
-}
-
-func Setenv(key, value string) error {
- v, err := UTF16PtrFromString(value)
- if err != nil {
- return err
- }
- keyp, err := UTF16PtrFromString(key)
- if err != nil {
- return err
- }
- e := SetEnvironmentVariable(keyp, v)
- if e != nil {
- return e
- }
- runtimeSetenv(key, value)
- return nil
-}
-
-func Unsetenv(key string) error {
- keyp, err := UTF16PtrFromString(key)
- if err != nil {
- return err
- }
- e := SetEnvironmentVariable(keyp, nil)
- if e != nil {
- return e
- }
- runtimeUnsetenv(key)
- return nil
-}
-
-func Clearenv() {
- for _, s := range Environ() {
- // Environment variables can begin with =
- // so start looking for the separator = at j=1.
- // https://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx
- for j := 1; j < len(s); j++ {
- if s[j] == '=' {
- Unsetenv(s[0:j])
- break
- }
- }
- }
-}
-
-func Environ() []string {
- envp, e := GetEnvironmentStrings()
- if e != nil {
- return nil
- }
- defer FreeEnvironmentStrings(envp)
-
- r := make([]string, 0, 50) // Empty with room to grow.
- const size = unsafe.Sizeof(*envp)
- for *envp != 0 { // environment block ends with empty string
- // find NUL terminator
- end := unsafe.Pointer(envp)
- for *(*uint16)(end) != 0 {
- end = unsafe.Add(end, size)
- }
-
- entry := unsafe.Slice(envp, (uintptr(end)-uintptr(unsafe.Pointer(envp)))/size)
- r = append(r, string(utf16.Decode(entry)))
- envp = (*uint16)(unsafe.Add(end, size))
- }
- return r
-}
diff --git a/contrib/go/_std_1.20/src/syscall/exec_libc2.go b/contrib/go/_std_1.20/src/syscall/exec_libc2.go
deleted file mode 100644
index 88d3b60b4d..0000000000
--- a/contrib/go/_std_1.20/src/syscall/exec_libc2.go
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright 2011 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.
-
-//go:build darwin || (openbsd && !mips64)
-
-package syscall
-
-import (
- "internal/abi"
- "runtime"
- "unsafe"
-)
-
-type SysProcAttr struct {
- Chroot string // Chroot.
- Credential *Credential // Credential.
- Ptrace bool // Enable tracing.
- Setsid bool // Create session.
- // Setpgid sets the process group ID of the child to Pgid,
- // or, if Pgid == 0, to the new child's process ID.
- Setpgid bool
- // Setctty sets the controlling terminal of the child to
- // file descriptor Ctty. Ctty must be a descriptor number
- // in the child process: an index into ProcAttr.Files.
- // This is only meaningful if Setsid is true.
- Setctty bool
- Noctty bool // Detach fd 0 from controlling terminal
- Ctty int // Controlling TTY fd
- // Foreground places the child process group in the foreground.
- // This implies Setpgid. The Ctty field must be set to
- // the descriptor of the controlling TTY.
- // Unlike Setctty, in this case Ctty must be a descriptor
- // number in the parent process.
- Foreground bool
- Pgid int // Child's process group ID if Setpgid.
-}
-
-// Implemented in runtime package.
-func runtime_BeforeFork()
-func runtime_AfterFork()
-func runtime_AfterForkInChild()
-
-// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
-// If a dup or exec fails, write the errno error to pipe.
-// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
-// In the child, this function must not acquire any locks, because
-// they might have been locked at the time of the fork. This means
-// no rescheduling, no malloc calls, and no new stack segments.
-// For the same reason compiler does not race instrument it.
-// The calls to rawSyscall are okay because they are assembly
-// functions that do not grow the stack.
-//
-//go:norace
-func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
- // Declare all variables at top in case any
- // declarations require heap allocation (e.g., err1).
- var (
- r1 uintptr
- err1 Errno
- nextfd int
- i int
- )
-
- rlim, rlimOK := origRlimitNofile.Load().(Rlimit)
-
- // guard against side effects of shuffling fds below.
- // Make sure that nextfd is beyond any currently open files so
- // that we can't run the risk of overwriting any of them.
- fd := make([]int, len(attr.Files))
- nextfd = len(attr.Files)
- for i, ufd := range attr.Files {
- if nextfd < int(ufd) {
- nextfd = int(ufd)
- }
- fd[i] = int(ufd)
- }
- nextfd++
-
- // About to call fork.
- // No more allocation or calls of non-assembly functions.
- runtime_BeforeFork()
- r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
- if err1 != 0 {
- runtime_AfterFork()
- return 0, err1
- }
-
- if r1 != 0 {
- // parent; return PID
- runtime_AfterFork()
- return int(r1), 0
- }
-
- // Fork succeeded, now in child.
-
- // Enable tracing if requested.
- if sys.Ptrace {
- if err := ptrace(PTRACE_TRACEME, 0, 0, 0); err != nil {
- err1 = err.(Errno)
- goto childerror
- }
- }
-
- // Session ID
- if sys.Setsid {
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Set process group
- if sys.Setpgid || sys.Foreground {
- // Place child in process group.
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), 0, uintptr(sys.Pgid), 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- if sys.Foreground {
- // This should really be pid_t, however _C_int (aka int32) is
- // generally equivalent.
- pgrp := _C_int(sys.Pgid)
- if pgrp == 0 {
- r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
- if err1 != 0 {
- goto childerror
- }
- pgrp = _C_int(r1)
- }
-
- // Place process group in foreground.
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSPGRP), uintptr(unsafe.Pointer(&pgrp)))
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Restore the signal mask. We do this after TIOCSPGRP to avoid
- // having the kernel send a SIGTTOU signal to the process group.
- runtime_AfterForkInChild()
-
- // Chroot
- if chroot != nil {
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(chroot)), 0, 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // User and groups
- if cred := sys.Credential; cred != nil {
- ngroups := uintptr(len(cred.Groups))
- groups := uintptr(0)
- if ngroups > 0 {
- groups = uintptr(unsafe.Pointer(&cred.Groups[0]))
- }
- if !cred.NoSetGroups {
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), ngroups, groups, 0)
- if err1 != 0 {
- goto childerror
- }
- }
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(cred.Gid), 0, 0)
- if err1 != 0 {
- goto childerror
- }
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(cred.Uid), 0, 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Chdir
- if dir != nil {
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(dir)), 0, 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Pass 1: look for fd[i] < i and move those up above len(fd)
- // so that pass 2 won't stomp on an fd it needs later.
- if pipe < nextfd {
- if runtime.GOOS == "openbsd" {
- _, _, err1 = rawSyscall(dupTrampoline, uintptr(pipe), uintptr(nextfd), O_CLOEXEC)
- } else {
- _, _, err1 = rawSyscall(dupTrampoline, uintptr(pipe), uintptr(nextfd), 0)
- if err1 != 0 {
- goto childerror
- }
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
- }
- if err1 != 0 {
- goto childerror
- }
- pipe = nextfd
- nextfd++
- }
- for i = 0; i < len(fd); i++ {
- if fd[i] >= 0 && fd[i] < i {
- if nextfd == pipe { // don't stomp on pipe
- nextfd++
- }
- if runtime.GOOS == "openbsd" {
- _, _, err1 = rawSyscall(dupTrampoline, uintptr(fd[i]), uintptr(nextfd), O_CLOEXEC)
- } else {
- _, _, err1 = rawSyscall(dupTrampoline, uintptr(fd[i]), uintptr(nextfd), 0)
- if err1 != 0 {
- goto childerror
- }
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
- }
- if err1 != 0 {
- goto childerror
- }
- fd[i] = nextfd
- nextfd++
- }
- }
-
- // Pass 2: dup fd[i] down onto i.
- for i = 0; i < len(fd); i++ {
- if fd[i] == -1 {
- rawSyscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(i), 0, 0)
- continue
- }
- if fd[i] == i {
- // dup2(i, i) won't clear close-on-exec flag on Linux,
- // probably not elsewhere either.
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd[i]), F_SETFD, 0)
- if err1 != 0 {
- goto childerror
- }
- continue
- }
- // The new fd is created NOT close-on-exec,
- // which is exactly what we want.
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(fd[i]), uintptr(i), 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // By convention, we don't close-on-exec the fds we are
- // started with, so if len(fd) < 3, close 0, 1, 2 as needed.
- // Programs that know they inherit fds >= 3 will need
- // to set them close-on-exec.
- for i = len(fd); i < 3; i++ {
- rawSyscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(i), 0, 0)
- }
-
- // Detach fd 0 from tty
- if sys.Noctty {
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), 0, uintptr(TIOCNOTTY), 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Set the controlling TTY to Ctty
- if sys.Setctty {
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Restore original rlimit.
- if rlimOK && rlim.Cur != 0 {
- rawSyscall(abi.FuncPCABI0(libc_setrlimit_trampoline), uintptr(RLIMIT_NOFILE), uintptr(unsafe.Pointer(&rlim)), 0)
- }
-
- // Time to exec.
- _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_execve_trampoline),
- uintptr(unsafe.Pointer(argv0)),
- uintptr(unsafe.Pointer(&argv[0])),
- uintptr(unsafe.Pointer(&envv[0])))
-
-childerror:
- // send error code on pipe
- rawSyscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
- for {
- rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), 253, 0, 0)
- }
-}
diff --git a/contrib/go/_std_1.20/src/syscall/exec_linux.go b/contrib/go/_std_1.20/src/syscall/exec_linux.go
deleted file mode 100644
index dcb3d51b5f..0000000000
--- a/contrib/go/_std_1.20/src/syscall/exec_linux.go
+++ /dev/null
@@ -1,706 +0,0 @@
-// Copyright 2011 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.
-
-//go:build linux
-
-package syscall
-
-import (
- "internal/itoa"
- "runtime"
- "unsafe"
-)
-
-// Linux unshare/clone/clone2/clone3 flags, architecture-independent,
-// copied from linux/sched.h.
-const (
- CLONE_VM = 0x00000100 // set if VM shared between processes
- CLONE_FS = 0x00000200 // set if fs info shared between processes
- CLONE_FILES = 0x00000400 // set if open files shared between processes
- CLONE_SIGHAND = 0x00000800 // set if signal handlers and blocked signals shared
- CLONE_PIDFD = 0x00001000 // set if a pidfd should be placed in parent
- CLONE_PTRACE = 0x00002000 // set if we want to let tracing continue on the child too
- CLONE_VFORK = 0x00004000 // set if the parent wants the child to wake it up on mm_release
- CLONE_PARENT = 0x00008000 // set if we want to have the same parent as the cloner
- CLONE_THREAD = 0x00010000 // Same thread group?
- CLONE_NEWNS = 0x00020000 // New mount namespace group
- CLONE_SYSVSEM = 0x00040000 // share system V SEM_UNDO semantics
- CLONE_SETTLS = 0x00080000 // create a new TLS for the child
- CLONE_PARENT_SETTID = 0x00100000 // set the TID in the parent
- CLONE_CHILD_CLEARTID = 0x00200000 // clear the TID in the child
- CLONE_DETACHED = 0x00400000 // Unused, ignored
- CLONE_UNTRACED = 0x00800000 // set if the tracing process can't force CLONE_PTRACE on this clone
- CLONE_CHILD_SETTID = 0x01000000 // set the TID in the child
- CLONE_NEWCGROUP = 0x02000000 // New cgroup namespace
- CLONE_NEWUTS = 0x04000000 // New utsname namespace
- CLONE_NEWIPC = 0x08000000 // New ipc namespace
- CLONE_NEWUSER = 0x10000000 // New user namespace
- CLONE_NEWPID = 0x20000000 // New pid namespace
- CLONE_NEWNET = 0x40000000 // New network namespace
- CLONE_IO = 0x80000000 // Clone io context
-
- // Flags for the clone3() syscall.
-
- CLONE_CLEAR_SIGHAND = 0x100000000 // Clear any signal handler and reset to SIG_DFL.
- CLONE_INTO_CGROUP = 0x200000000 // Clone into a specific cgroup given the right permissions.
-
- // Cloning flags intersect with CSIGNAL so can be used with unshare and clone3
- // syscalls only:
-
- CLONE_NEWTIME = 0x00000080 // New time namespace
-)
-
-// SysProcIDMap holds Container ID to Host ID mappings used for User Namespaces in Linux.
-// See user_namespaces(7).
-type SysProcIDMap struct {
- ContainerID int // Container ID.
- HostID int // Host ID.
- Size int // Size.
-}
-
-type SysProcAttr struct {
- Chroot string // Chroot.
- Credential *Credential // Credential.
- // Ptrace tells the child to call ptrace(PTRACE_TRACEME).
- // Call runtime.LockOSThread before starting a process with this set,
- // and don't call UnlockOSThread until done with PtraceSyscall calls.
- Ptrace bool
- Setsid bool // Create session.
- // Setpgid sets the process group ID of the child to Pgid,
- // or, if Pgid == 0, to the new child's process ID.
- Setpgid bool
- // Setctty sets the controlling terminal of the child to
- // file descriptor Ctty. Ctty must be a descriptor number
- // in the child process: an index into ProcAttr.Files.
- // This is only meaningful if Setsid is true.
- Setctty bool
- Noctty bool // Detach fd 0 from controlling terminal
- Ctty int // Controlling TTY fd
- // Foreground places the child process group in the foreground.
- // This implies Setpgid. The Ctty field must be set to
- // the descriptor of the controlling TTY.
- // Unlike Setctty, in this case Ctty must be a descriptor
- // number in the parent process.
- Foreground bool
- Pgid int // Child's process group ID if Setpgid.
- // Pdeathsig, if non-zero, is a signal that the kernel will send to
- // the child process when the creating thread dies. Note that the signal
- // is sent on thread termination, which may happen before process termination.
- // There are more details at https://go.dev/issue/27505.
- Pdeathsig Signal
- Cloneflags uintptr // Flags for clone calls (Linux only)
- Unshareflags uintptr // Flags for unshare calls (Linux only)
- UidMappings []SysProcIDMap // User ID mappings for user namespaces.
- GidMappings []SysProcIDMap // Group ID mappings for user namespaces.
- // GidMappingsEnableSetgroups enabling setgroups syscall.
- // If false, then setgroups syscall will be disabled for the child process.
- // This parameter is no-op if GidMappings == nil. Otherwise for unprivileged
- // users this should be set to false for mappings work.
- GidMappingsEnableSetgroups bool
- AmbientCaps []uintptr // Ambient capabilities (Linux only)
- UseCgroupFD bool // Whether to make use of the CgroupFD field.
- CgroupFD int // File descriptor of a cgroup to put the new process into.
-}
-
-var (
- none = [...]byte{'n', 'o', 'n', 'e', 0}
- slash = [...]byte{'/', 0}
-)
-
-// Implemented in runtime package.
-func runtime_BeforeFork()
-func runtime_AfterFork()
-func runtime_AfterForkInChild()
-
-// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
-// If a dup or exec fails, write the errno error to pipe.
-// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
-// In the child, this function must not acquire any locks, because
-// they might have been locked at the time of the fork. This means
-// no rescheduling, no malloc calls, and no new stack segments.
-// For the same reason compiler does not race instrument it.
-// The calls to RawSyscall are okay because they are assembly
-// functions that do not grow the stack.
-//
-//go:norace
-func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
- // Set up and fork. This returns immediately in the parent or
- // if there's an error.
- r1, err1, p, locked := forkAndExecInChild1(argv0, argv, envv, chroot, dir, attr, sys, pipe)
- if locked {
- runtime_AfterFork()
- }
- if err1 != 0 {
- return 0, err1
- }
-
- // parent; return PID
- pid = int(r1)
-
- if sys.UidMappings != nil || sys.GidMappings != nil {
- Close(p[0])
- var err2 Errno
- // uid/gid mappings will be written after fork and unshare(2) for user
- // namespaces.
- if sys.Unshareflags&CLONE_NEWUSER == 0 {
- if err := writeUidGidMappings(pid, sys); err != nil {
- err2 = err.(Errno)
- }
- }
- RawSyscall(SYS_WRITE, uintptr(p[1]), uintptr(unsafe.Pointer(&err2)), unsafe.Sizeof(err2))
- Close(p[1])
- }
-
- return pid, 0
-}
-
-const _LINUX_CAPABILITY_VERSION_3 = 0x20080522
-
-type capHeader struct {
- version uint32
- pid int32
-}
-
-type capData struct {
- effective uint32
- permitted uint32
- inheritable uint32
-}
-type caps struct {
- hdr capHeader
- data [2]capData
-}
-
-// See CAP_TO_INDEX in linux/capability.h:
-func capToIndex(cap uintptr) uintptr { return cap >> 5 }
-
-// See CAP_TO_MASK in linux/capability.h:
-func capToMask(cap uintptr) uint32 { return 1 << uint(cap&31) }
-
-// cloneArgs holds arguments for clone3 Linux syscall.
-type cloneArgs struct {
- flags uint64 // Flags bit mask
- pidFD uint64 // Where to store PID file descriptor (int *)
- childTID uint64 // Where to store child TID, in child's memory (pid_t *)
- parentTID uint64 // Where to store child TID, in parent's memory (pid_t *)
- exitSignal uint64 // Signal to deliver to parent on child termination
- stack uint64 // Pointer to lowest byte of stack
- stackSize uint64 // Size of stack
- tls uint64 // Location of new TLS
- setTID uint64 // Pointer to a pid_t array (since Linux 5.5)
- setTIDSize uint64 // Number of elements in set_tid (since Linux 5.5)
- cgroup uint64 // File descriptor for target cgroup of child (since Linux 5.7)
-}
-
-// forkAndExecInChild1 implements the body of forkAndExecInChild up to
-// the parent's post-fork path. This is a separate function so we can
-// separate the child's and parent's stack frames if we're using
-// vfork.
-//
-// This is go:noinline because the point is to keep the stack frames
-// of this and forkAndExecInChild separate.
-//
-//go:noinline
-//go:norace
-func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (r1 uintptr, err1 Errno, p [2]int, locked bool) {
- // Defined in linux/prctl.h starting with Linux 4.3.
- const (
- PR_CAP_AMBIENT = 0x2f
- PR_CAP_AMBIENT_RAISE = 0x2
- )
-
- // vfork requires that the child not touch any of the parent's
- // active stack frames. Hence, the child does all post-fork
- // processing in this stack frame and never returns, while the
- // parent returns immediately from this frame and does all
- // post-fork processing in the outer frame.
- // Declare all variables at top in case any
- // declarations require heap allocation (e.g., err1).
- var (
- err2 Errno
- nextfd int
- i int
- caps caps
- fd1, flags uintptr
- puid, psetgroups, pgid []byte
- uidmap, setgroups, gidmap []byte
- clone3 *cloneArgs
- )
-
- rlim, rlimOK := origRlimitNofile.Load().(Rlimit)
-
- if sys.UidMappings != nil {
- puid = []byte("/proc/self/uid_map\000")
- uidmap = formatIDMappings(sys.UidMappings)
- }
-
- if sys.GidMappings != nil {
- psetgroups = []byte("/proc/self/setgroups\000")
- pgid = []byte("/proc/self/gid_map\000")
-
- if sys.GidMappingsEnableSetgroups {
- setgroups = []byte("allow\000")
- } else {
- setgroups = []byte("deny\000")
- }
- gidmap = formatIDMappings(sys.GidMappings)
- }
-
- // Record parent PID so child can test if it has died.
- ppid, _ := rawSyscallNoError(SYS_GETPID, 0, 0, 0)
-
- // Guard against side effects of shuffling fds below.
- // Make sure that nextfd is beyond any currently open files so
- // that we can't run the risk of overwriting any of them.
- fd := make([]int, len(attr.Files))
- nextfd = len(attr.Files)
- for i, ufd := range attr.Files {
- if nextfd < int(ufd) {
- nextfd = int(ufd)
- }
- fd[i] = int(ufd)
- }
- nextfd++
-
- // Allocate another pipe for parent to child communication for
- // synchronizing writing of User ID/Group ID mappings.
- if sys.UidMappings != nil || sys.GidMappings != nil {
- if err := forkExecPipe(p[:]); err != nil {
- err1 = err.(Errno)
- return
- }
- }
-
- flags = sys.Cloneflags
- if sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0 {
- flags |= CLONE_VFORK | CLONE_VM
- }
- // Whether to use clone3.
- if sys.UseCgroupFD {
- clone3 = &cloneArgs{
- flags: uint64(flags) | CLONE_INTO_CGROUP,
- exitSignal: uint64(SIGCHLD),
- cgroup: uint64(sys.CgroupFD),
- }
- }
-
- // About to call fork.
- // No more allocation or calls of non-assembly functions.
- runtime_BeforeFork()
- locked = true
- if clone3 != nil {
- r1, err1 = rawVforkSyscall(_SYS_clone3, uintptr(unsafe.Pointer(clone3)), unsafe.Sizeof(*clone3))
- } else {
- flags |= uintptr(SIGCHLD)
- if runtime.GOARCH == "s390x" {
- // On Linux/s390, the first two arguments of clone(2) are swapped.
- r1, err1 = rawVforkSyscall(SYS_CLONE, 0, flags)
- } else {
- r1, err1 = rawVforkSyscall(SYS_CLONE, flags, 0)
- }
- }
- if err1 != 0 || r1 != 0 {
- // If we're in the parent, we must return immediately
- // so we're not in the same stack frame as the child.
- // This can at most use the return PC, which the child
- // will not modify, and the results of
- // rawVforkSyscall, which must have been written after
- // the child was replaced.
- return
- }
-
- // Fork succeeded, now in child.
-
- // Enable the "keep capabilities" flag to set ambient capabilities later.
- if len(sys.AmbientCaps) > 0 {
- _, _, err1 = RawSyscall6(SYS_PRCTL, PR_SET_KEEPCAPS, 1, 0, 0, 0, 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Wait for User ID/Group ID mappings to be written.
- if sys.UidMappings != nil || sys.GidMappings != nil {
- if _, _, err1 = RawSyscall(SYS_CLOSE, uintptr(p[1]), 0, 0); err1 != 0 {
- goto childerror
- }
- r1, _, err1 = RawSyscall(SYS_READ, uintptr(p[0]), uintptr(unsafe.Pointer(&err2)), unsafe.Sizeof(err2))
- if err1 != 0 {
- goto childerror
- }
- if r1 != unsafe.Sizeof(err2) {
- err1 = EINVAL
- goto childerror
- }
- if err2 != 0 {
- err1 = err2
- goto childerror
- }
- }
-
- // Session ID
- if sys.Setsid {
- _, _, err1 = RawSyscall(SYS_SETSID, 0, 0, 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Set process group
- if sys.Setpgid || sys.Foreground {
- // Place child in process group.
- _, _, err1 = RawSyscall(SYS_SETPGID, 0, uintptr(sys.Pgid), 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- if sys.Foreground {
- pgrp := int32(sys.Pgid)
- if pgrp == 0 {
- r1, _ = rawSyscallNoError(SYS_GETPID, 0, 0, 0)
-
- pgrp = int32(r1)
- }
-
- // Place process group in foreground.
- _, _, err1 = RawSyscall(SYS_IOCTL, uintptr(sys.Ctty), uintptr(TIOCSPGRP), uintptr(unsafe.Pointer(&pgrp)))
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Restore the signal mask. We do this after TIOCSPGRP to avoid
- // having the kernel send a SIGTTOU signal to the process group.
- runtime_AfterForkInChild()
-
- // Unshare
- if sys.Unshareflags != 0 {
- _, _, err1 = RawSyscall(SYS_UNSHARE, sys.Unshareflags, 0, 0)
- if err1 != 0 {
- goto childerror
- }
-
- if sys.Unshareflags&CLONE_NEWUSER != 0 && sys.GidMappings != nil {
- dirfd := int(_AT_FDCWD)
- if fd1, _, err1 = RawSyscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(&psetgroups[0])), uintptr(O_WRONLY), 0, 0, 0); err1 != 0 {
- goto childerror
- }
- r1, _, err1 = RawSyscall(SYS_WRITE, uintptr(fd1), uintptr(unsafe.Pointer(&setgroups[0])), uintptr(len(setgroups)))
- if err1 != 0 {
- goto childerror
- }
- if _, _, err1 = RawSyscall(SYS_CLOSE, uintptr(fd1), 0, 0); err1 != 0 {
- goto childerror
- }
-
- if fd1, _, err1 = RawSyscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(&pgid[0])), uintptr(O_WRONLY), 0, 0, 0); err1 != 0 {
- goto childerror
- }
- r1, _, err1 = RawSyscall(SYS_WRITE, uintptr(fd1), uintptr(unsafe.Pointer(&gidmap[0])), uintptr(len(gidmap)))
- if err1 != 0 {
- goto childerror
- }
- if _, _, err1 = RawSyscall(SYS_CLOSE, uintptr(fd1), 0, 0); err1 != 0 {
- goto childerror
- }
- }
-
- if sys.Unshareflags&CLONE_NEWUSER != 0 && sys.UidMappings != nil {
- dirfd := int(_AT_FDCWD)
- if fd1, _, err1 = RawSyscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(&puid[0])), uintptr(O_WRONLY), 0, 0, 0); err1 != 0 {
- goto childerror
- }
- r1, _, err1 = RawSyscall(SYS_WRITE, uintptr(fd1), uintptr(unsafe.Pointer(&uidmap[0])), uintptr(len(uidmap)))
- if err1 != 0 {
- goto childerror
- }
- if _, _, err1 = RawSyscall(SYS_CLOSE, uintptr(fd1), 0, 0); err1 != 0 {
- goto childerror
- }
- }
-
- // The unshare system call in Linux doesn't unshare mount points
- // mounted with --shared. Systemd mounts / with --shared. For a
- // long discussion of the pros and cons of this see debian bug 739593.
- // The Go model of unsharing is more like Plan 9, where you ask
- // to unshare and the namespaces are unconditionally unshared.
- // To make this model work we must further mark / as MS_PRIVATE.
- // This is what the standard unshare command does.
- if sys.Unshareflags&CLONE_NEWNS == CLONE_NEWNS {
- _, _, err1 = RawSyscall6(SYS_MOUNT, uintptr(unsafe.Pointer(&none[0])), uintptr(unsafe.Pointer(&slash[0])), 0, MS_REC|MS_PRIVATE, 0, 0)
- if err1 != 0 {
- goto childerror
- }
- }
- }
-
- // Chroot
- if chroot != nil {
- _, _, err1 = RawSyscall(SYS_CHROOT, uintptr(unsafe.Pointer(chroot)), 0, 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // User and groups
- if cred := sys.Credential; cred != nil {
- ngroups := uintptr(len(cred.Groups))
- groups := uintptr(0)
- if ngroups > 0 {
- groups = uintptr(unsafe.Pointer(&cred.Groups[0]))
- }
- if !(sys.GidMappings != nil && !sys.GidMappingsEnableSetgroups && ngroups == 0) && !cred.NoSetGroups {
- _, _, err1 = RawSyscall(_SYS_setgroups, ngroups, groups, 0)
- if err1 != 0 {
- goto childerror
- }
- }
- _, _, err1 = RawSyscall(sys_SETGID, uintptr(cred.Gid), 0, 0)
- if err1 != 0 {
- goto childerror
- }
- _, _, err1 = RawSyscall(sys_SETUID, uintptr(cred.Uid), 0, 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- if len(sys.AmbientCaps) != 0 {
- // Ambient capabilities were added in the 4.3 kernel,
- // so it is safe to always use _LINUX_CAPABILITY_VERSION_3.
- caps.hdr.version = _LINUX_CAPABILITY_VERSION_3
-
- if _, _, err1 = RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&caps.hdr)), uintptr(unsafe.Pointer(&caps.data[0])), 0); err1 != 0 {
- goto childerror
- }
-
- for _, c := range sys.AmbientCaps {
- // Add the c capability to the permitted and inheritable capability mask,
- // otherwise we will not be able to add it to the ambient capability mask.
- caps.data[capToIndex(c)].permitted |= capToMask(c)
- caps.data[capToIndex(c)].inheritable |= capToMask(c)
- }
-
- if _, _, err1 = RawSyscall(SYS_CAPSET, uintptr(unsafe.Pointer(&caps.hdr)), uintptr(unsafe.Pointer(&caps.data[0])), 0); err1 != 0 {
- goto childerror
- }
-
- for _, c := range sys.AmbientCaps {
- _, _, err1 = RawSyscall6(SYS_PRCTL, PR_CAP_AMBIENT, uintptr(PR_CAP_AMBIENT_RAISE), c, 0, 0, 0)
- if err1 != 0 {
- goto childerror
- }
- }
- }
-
- // Chdir
- if dir != nil {
- _, _, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)), 0, 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Parent death signal
- if sys.Pdeathsig != 0 {
- _, _, err1 = RawSyscall6(SYS_PRCTL, PR_SET_PDEATHSIG, uintptr(sys.Pdeathsig), 0, 0, 0, 0)
- if err1 != 0 {
- goto childerror
- }
-
- // Signal self if parent is already dead. This might cause a
- // duplicate signal in rare cases, but it won't matter when
- // using SIGKILL.
- r1, _ = rawSyscallNoError(SYS_GETPPID, 0, 0, 0)
- if r1 != ppid {
- pid, _ := rawSyscallNoError(SYS_GETPID, 0, 0, 0)
- _, _, err1 = RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0)
- if err1 != 0 {
- goto childerror
- }
- }
- }
-
- // Pass 1: look for fd[i] < i and move those up above len(fd)
- // so that pass 2 won't stomp on an fd it needs later.
- if pipe < nextfd {
- _, _, err1 = RawSyscall(SYS_DUP3, uintptr(pipe), uintptr(nextfd), O_CLOEXEC)
- if err1 != 0 {
- goto childerror
- }
- pipe = nextfd
- nextfd++
- }
- for i = 0; i < len(fd); i++ {
- if fd[i] >= 0 && fd[i] < i {
- if nextfd == pipe { // don't stomp on pipe
- nextfd++
- }
- _, _, err1 = RawSyscall(SYS_DUP3, uintptr(fd[i]), uintptr(nextfd), O_CLOEXEC)
- if err1 != 0 {
- goto childerror
- }
- fd[i] = nextfd
- nextfd++
- }
- }
-
- // Pass 2: dup fd[i] down onto i.
- for i = 0; i < len(fd); i++ {
- if fd[i] == -1 {
- RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
- continue
- }
- if fd[i] == i {
- // dup2(i, i) won't clear close-on-exec flag on Linux,
- // probably not elsewhere either.
- _, _, err1 = RawSyscall(fcntl64Syscall, uintptr(fd[i]), F_SETFD, 0)
- if err1 != 0 {
- goto childerror
- }
- continue
- }
- // The new fd is created NOT close-on-exec,
- // which is exactly what we want.
- _, _, err1 = RawSyscall(SYS_DUP3, uintptr(fd[i]), uintptr(i), 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // By convention, we don't close-on-exec the fds we are
- // started with, so if len(fd) < 3, close 0, 1, 2 as needed.
- // Programs that know they inherit fds >= 3 will need
- // to set them close-on-exec.
- for i = len(fd); i < 3; i++ {
- RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
- }
-
- // Detach fd 0 from tty
- if sys.Noctty {
- _, _, err1 = RawSyscall(SYS_IOCTL, 0, uintptr(TIOCNOTTY), 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Set the controlling TTY to Ctty
- if sys.Setctty {
- _, _, err1 = RawSyscall(SYS_IOCTL, uintptr(sys.Ctty), uintptr(TIOCSCTTY), 1)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Restore original rlimit.
- if rlimOK && rlim.Cur != 0 {
- rawSetrlimit(RLIMIT_NOFILE, &rlim)
- }
-
- // Enable tracing if requested.
- // Do this right before exec so that we don't unnecessarily trace the runtime
- // setting up after the fork. See issue #21428.
- if sys.Ptrace {
- _, _, err1 = RawSyscall(SYS_PTRACE, uintptr(PTRACE_TRACEME), 0, 0)
- if err1 != 0 {
- goto childerror
- }
- }
-
- // Time to exec.
- _, _, err1 = RawSyscall(SYS_EXECVE,
- uintptr(unsafe.Pointer(argv0)),
- uintptr(unsafe.Pointer(&argv[0])),
- uintptr(unsafe.Pointer(&envv[0])))
-
-childerror:
- // send error code on pipe
- RawSyscall(SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
- for {
- RawSyscall(SYS_EXIT, 253, 0, 0)
- }
-}
-
-// Try to open a pipe with O_CLOEXEC set on both file descriptors.
-func forkExecPipe(p []int) (err error) {
- return Pipe2(p, O_CLOEXEC)
-}
-
-func formatIDMappings(idMap []SysProcIDMap) []byte {
- var data []byte
- for _, im := range idMap {
- data = append(data, itoa.Itoa(im.ContainerID)+" "+itoa.Itoa(im.HostID)+" "+itoa.Itoa(im.Size)+"\n"...)
- }
- return data
-}
-
-// writeIDMappings writes the user namespace User ID or Group ID mappings to the specified path.
-func writeIDMappings(path string, idMap []SysProcIDMap) error {
- fd, err := Open(path, O_RDWR, 0)
- if err != nil {
- return err
- }
-
- if _, err := Write(fd, formatIDMappings(idMap)); err != nil {
- Close(fd)
- return err
- }
-
- if err := Close(fd); err != nil {
- return err
- }
-
- return nil
-}
-
-// writeSetgroups writes to /proc/PID/setgroups "deny" if enable is false
-// and "allow" if enable is true.
-// This is needed since kernel 3.19, because you can't write gid_map without
-// disabling setgroups() system call.
-func writeSetgroups(pid int, enable bool) error {
- sgf := "/proc/" + itoa.Itoa(pid) + "/setgroups"
- fd, err := Open(sgf, O_RDWR, 0)
- if err != nil {
- return err
- }
-
- var data []byte
- if enable {
- data = []byte("allow")
- } else {
- data = []byte("deny")
- }
-
- if _, err := Write(fd, data); err != nil {
- Close(fd)
- return err
- }
-
- return Close(fd)
-}
-
-// writeUidGidMappings writes User ID and Group ID mappings for user namespaces
-// for a process and it is called from the parent process.
-func writeUidGidMappings(pid int, sys *SysProcAttr) error {
- if sys.UidMappings != nil {
- uidf := "/proc/" + itoa.Itoa(pid) + "/uid_map"
- if err := writeIDMappings(uidf, sys.UidMappings); err != nil {
- return err
- }
- }
-
- if sys.GidMappings != nil {
- // If the kernel is too old to support /proc/PID/setgroups, writeSetGroups will return ENOENT; this is OK.
- if err := writeSetgroups(pid, sys.GidMappingsEnableSetgroups); err != nil && err != ENOENT {
- return err
- }
- gidf := "/proc/" + itoa.Itoa(pid) + "/gid_map"
- if err := writeIDMappings(gidf, sys.GidMappings); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/syscall/exec_unix.go b/contrib/go/_std_1.20/src/syscall/exec_unix.go
deleted file mode 100644
index 40e9b9feda..0000000000
--- a/contrib/go/_std_1.20/src/syscall/exec_unix.go
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix
-
-// Fork, exec, wait, etc.
-
-package syscall
-
-import (
- errorspkg "errors"
- "internal/bytealg"
- "runtime"
- "sync"
- "unsafe"
-)
-
-// Lock synchronizing creation of new file descriptors with fork.
-//
-// We want the child in a fork/exec sequence to inherit only the
-// file descriptors we intend. To do that, we mark all file
-// descriptors close-on-exec and then, in the child, explicitly
-// unmark the ones we want the exec'ed program to keep.
-// Unix doesn't make this easy: there is, in general, no way to
-// allocate a new file descriptor close-on-exec. Instead you
-// have to allocate the descriptor and then mark it close-on-exec.
-// If a fork happens between those two events, the child's exec
-// will inherit an unwanted file descriptor.
-//
-// This lock solves that race: the create new fd/mark close-on-exec
-// operation is done holding ForkLock for reading, and the fork itself
-// is done holding ForkLock for writing. At least, that's the idea.
-// There are some complications.
-//
-// Some system calls that create new file descriptors can block
-// for arbitrarily long times: open on a hung NFS server or named
-// pipe, accept on a socket, and so on. We can't reasonably grab
-// the lock across those operations.
-//
-// It is worse to inherit some file descriptors than others.
-// If a non-malicious child accidentally inherits an open ordinary file,
-// that's not a big deal. On the other hand, if a long-lived child
-// accidentally inherits the write end of a pipe, then the reader
-// of that pipe will not see EOF until that child exits, potentially
-// causing the parent program to hang. This is a common problem
-// in threaded C programs that use popen.
-//
-// Luckily, the file descriptors that are most important not to
-// inherit are not the ones that can take an arbitrarily long time
-// to create: pipe returns instantly, and the net package uses
-// non-blocking I/O to accept on a listening socket.
-// The rules for which file descriptor-creating operations use the
-// ForkLock are as follows:
-//
-// 1) Pipe. Does not block. Use the ForkLock.
-// 2) Socket. Does not block. Use the ForkLock.
-// 3) Accept. If using non-blocking mode, use the ForkLock.
-// Otherwise, live with the race.
-// 4) Open. Can block. Use O_CLOEXEC if available (Linux).
-// Otherwise, live with the race.
-// 5) Dup. Does not block. Use the ForkLock.
-// On Linux, could use fcntl F_DUPFD_CLOEXEC
-// instead of the ForkLock, but only for dup(fd, -1).
-
-var ForkLock sync.RWMutex
-
-// StringSlicePtr converts a slice of strings to a slice of pointers
-// to NUL-terminated byte arrays. If any string contains a NUL byte
-// this function panics instead of returning an error.
-//
-// Deprecated: Use SlicePtrFromStrings instead.
-func StringSlicePtr(ss []string) []*byte {
- bb := make([]*byte, len(ss)+1)
- for i := 0; i < len(ss); i++ {
- bb[i] = StringBytePtr(ss[i])
- }
- bb[len(ss)] = nil
- return bb
-}
-
-// SlicePtrFromStrings converts a slice of strings to a slice of
-// pointers to NUL-terminated byte arrays. If any string contains
-// a NUL byte, it returns (nil, EINVAL).
-func SlicePtrFromStrings(ss []string) ([]*byte, error) {
- n := 0
- for _, s := range ss {
- if bytealg.IndexByteString(s, 0) != -1 {
- return nil, EINVAL
- }
- n += len(s) + 1 // +1 for NUL
- }
- bb := make([]*byte, len(ss)+1)
- b := make([]byte, n)
- n = 0
- for i, s := range ss {
- bb[i] = &b[n]
- copy(b[n:], s)
- n += len(s) + 1
- }
- return bb, nil
-}
-
-func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
-
-func SetNonblock(fd int, nonblocking bool) (err error) {
- flag, err := fcntl(fd, F_GETFL, 0)
- if err != nil {
- return err
- }
- if nonblocking {
- flag |= O_NONBLOCK
- } else {
- flag &^= O_NONBLOCK
- }
- _, err = fcntl(fd, F_SETFL, flag)
- return err
-}
-
-// Credential holds user and group identities to be assumed
-// by a child process started by StartProcess.
-type Credential struct {
- Uid uint32 // User ID.
- Gid uint32 // Group ID.
- Groups []uint32 // Supplementary group IDs.
- NoSetGroups bool // If true, don't set supplementary groups
-}
-
-// ProcAttr holds attributes that will be applied to a new process started
-// by StartProcess.
-type ProcAttr struct {
- Dir string // Current working directory.
- Env []string // Environment.
- Files []uintptr // File descriptors.
- Sys *SysProcAttr
-}
-
-var zeroProcAttr ProcAttr
-var zeroSysProcAttr SysProcAttr
-
-func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
- var p [2]int
- var n int
- var err1 Errno
- var wstatus WaitStatus
-
- if attr == nil {
- attr = &zeroProcAttr
- }
- sys := attr.Sys
- if sys == nil {
- sys = &zeroSysProcAttr
- }
-
- // Convert args to C form.
- argv0p, err := BytePtrFromString(argv0)
- if err != nil {
- return 0, err
- }
- argvp, err := SlicePtrFromStrings(argv)
- if err != nil {
- return 0, err
- }
- envvp, err := SlicePtrFromStrings(attr.Env)
- if err != nil {
- return 0, err
- }
-
- if (runtime.GOOS == "freebsd" || runtime.GOOS == "dragonfly") && len(argv[0]) > len(argv0) {
- argvp[0] = argv0p
- }
-
- var chroot *byte
- if sys.Chroot != "" {
- chroot, err = BytePtrFromString(sys.Chroot)
- if err != nil {
- return 0, err
- }
- }
- var dir *byte
- if attr.Dir != "" {
- dir, err = BytePtrFromString(attr.Dir)
- if err != nil {
- return 0, err
- }
- }
-
- // Both Setctty and Foreground use the Ctty field,
- // but they give it slightly different meanings.
- if sys.Setctty && sys.Foreground {
- return 0, errorspkg.New("both Setctty and Foreground set in SysProcAttr")
- }
- if sys.Setctty && sys.Ctty >= len(attr.Files) {
- return 0, errorspkg.New("Setctty set but Ctty not valid in child")
- }
-
- // Acquire the fork lock so that no other threads
- // create new fds that are not yet close-on-exec
- // before we fork.
- ForkLock.Lock()
-
- // Allocate child status pipe close on exec.
- if err = forkExecPipe(p[:]); err != nil {
- ForkLock.Unlock()
- return 0, err
- }
-
- // Kick off child.
- pid, err1 = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1])
- if err1 != 0 {
- Close(p[0])
- Close(p[1])
- ForkLock.Unlock()
- return 0, Errno(err1)
- }
- ForkLock.Unlock()
-
- // Read child error status from pipe.
- Close(p[1])
- for {
- n, err = readlen(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
- if err != EINTR {
- break
- }
- }
- Close(p[0])
- if err != nil || n != 0 {
- if n == int(unsafe.Sizeof(err1)) {
- err = Errno(err1)
- }
- if err == nil {
- err = EPIPE
- }
-
- // Child failed; wait for it to exit, to make sure
- // the zombies don't accumulate.
- _, err1 := Wait4(pid, &wstatus, 0, nil)
- for err1 == EINTR {
- _, err1 = Wait4(pid, &wstatus, 0, nil)
- }
- return 0, err
- }
-
- // Read got EOF, so pipe closed on exec, so exec succeeded.
- return pid, nil
-}
-
-// Combination of fork and exec, careful to be thread safe.
-func ForkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
- return forkExec(argv0, argv, attr)
-}
-
-// StartProcess wraps ForkExec for package os.
-func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
- pid, err = forkExec(argv0, argv, attr)
- return pid, 0, err
-}
-
-// Implemented in runtime package.
-func runtime_BeforeExec()
-func runtime_AfterExec()
-
-// execveLibc is non-nil on OS using libc syscall, set to execve in exec_libc.go; this
-// avoids a build dependency for other platforms.
-var execveLibc func(path uintptr, argv uintptr, envp uintptr) Errno
-var execveDarwin func(path *byte, argv **byte, envp **byte) error
-var execveOpenBSD func(path *byte, argv **byte, envp **byte) error
-
-// Exec invokes the execve(2) system call.
-func Exec(argv0 string, argv []string, envv []string) (err error) {
- argv0p, err := BytePtrFromString(argv0)
- if err != nil {
- return err
- }
- argvp, err := SlicePtrFromStrings(argv)
- if err != nil {
- return err
- }
- envvp, err := SlicePtrFromStrings(envv)
- if err != nil {
- return err
- }
- runtime_BeforeExec()
-
- rlim, rlimOK := origRlimitNofile.Load().(Rlimit)
- if rlimOK && rlim.Cur != 0 {
- Setrlimit(RLIMIT_NOFILE, &rlim)
- }
-
- var err1 error
- if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" || runtime.GOOS == "aix" {
- // RawSyscall should never be used on Solaris, illumos, or AIX.
- err1 = execveLibc(
- uintptr(unsafe.Pointer(argv0p)),
- uintptr(unsafe.Pointer(&argvp[0])),
- uintptr(unsafe.Pointer(&envvp[0])))
- } else if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
- // Similarly on Darwin.
- err1 = execveDarwin(argv0p, &argvp[0], &envvp[0])
- } else if runtime.GOOS == "openbsd" && (runtime.GOARCH == "386" || runtime.GOARCH == "amd64" || runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
- // Similarly on OpenBSD.
- err1 = execveOpenBSD(argv0p, &argvp[0], &envvp[0])
- } else {
- _, _, err1 = RawSyscall(SYS_EXECVE,
- uintptr(unsafe.Pointer(argv0p)),
- uintptr(unsafe.Pointer(&argvp[0])),
- uintptr(unsafe.Pointer(&envvp[0])))
- }
- runtime_AfterExec()
- return err1
-}
diff --git a/contrib/go/_std_1.20/src/syscall/exec_windows.go b/contrib/go/_std_1.20/src/syscall/exec_windows.go
deleted file mode 100644
index 45295dedff..0000000000
--- a/contrib/go/_std_1.20/src/syscall/exec_windows.go
+++ /dev/null
@@ -1,432 +0,0 @@
-// Copyright 2009 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.
-
-// Fork, exec, wait, etc.
-
-package syscall
-
-import (
- "internal/bytealg"
- "runtime"
- "sync"
- "unicode/utf16"
- "unsafe"
-)
-
-var ForkLock sync.RWMutex
-
-// EscapeArg rewrites command line argument s as prescribed
-// in https://msdn.microsoft.com/en-us/library/ms880421.
-// This function returns "" (2 double quotes) if s is empty.
-// Alternatively, these transformations are done:
-// - every back slash (\) is doubled, but only if immediately
-// followed by double quote (");
-// - every double quote (") is escaped by back slash (\);
-// - finally, s is wrapped with double quotes (arg -> "arg"),
-// but only if there is space or tab inside s.
-func EscapeArg(s string) string {
- if len(s) == 0 {
- return `""`
- }
- for i := 0; i < len(s); i++ {
- switch s[i] {
- case '"', '\\', ' ', '\t':
- // Some escaping required.
- b := make([]byte, 0, len(s)+2)
- b = appendEscapeArg(b, s)
- return string(b)
- }
- }
- return s
-}
-
-// appendEscapeArg escapes the string s, as per escapeArg,
-// appends the result to b, and returns the updated slice.
-func appendEscapeArg(b []byte, s string) []byte {
- if len(s) == 0 {
- return append(b, `""`...)
- }
-
- needsBackslash := false
- hasSpace := false
- for i := 0; i < len(s); i++ {
- switch s[i] {
- case '"', '\\':
- needsBackslash = true
- case ' ', '\t':
- hasSpace = true
- }
- }
-
- if !needsBackslash && !hasSpace {
- // No special handling required; normal case.
- return append(b, s...)
- }
- if !needsBackslash {
- // hasSpace is true, so we need to quote the string.
- b = append(b, '"')
- b = append(b, s...)
- return append(b, '"')
- }
-
- if hasSpace {
- b = append(b, '"')
- }
- slashes := 0
- for i := 0; i < len(s); i++ {
- c := s[i]
- switch c {
- default:
- slashes = 0
- case '\\':
- slashes++
- case '"':
- for ; slashes > 0; slashes-- {
- b = append(b, '\\')
- }
- b = append(b, '\\')
- }
- b = append(b, c)
- }
- if hasSpace {
- for ; slashes > 0; slashes-- {
- b = append(b, '\\')
- }
- b = append(b, '"')
- }
-
- return b
-}
-
-// makeCmdLine builds a command line out of args by escaping "special"
-// characters and joining the arguments with spaces.
-func makeCmdLine(args []string) string {
- var b []byte
- for _, v := range args {
- if len(b) > 0 {
- b = append(b, ' ')
- }
- b = appendEscapeArg(b, v)
- }
- return string(b)
-}
-
-// createEnvBlock converts an array of environment strings into
-// the representation required by CreateProcess: a sequence of NUL
-// terminated strings followed by a nil.
-// Last bytes are two UCS-2 NULs, or four NUL bytes.
-// If any string contains a NUL, it returns (nil, EINVAL).
-func createEnvBlock(envv []string) (*uint16, error) {
- if len(envv) == 0 {
- return &utf16.Encode([]rune("\x00\x00"))[0], nil
- }
- length := 0
- for _, s := range envv {
- if bytealg.IndexByteString(s, 0) != -1 {
- return nil, EINVAL
- }
- length += len(s) + 1
- }
- length += 1
-
- b := make([]byte, length)
- i := 0
- for _, s := range envv {
- l := len(s)
- copy(b[i:i+l], []byte(s))
- copy(b[i+l:i+l+1], []byte{0})
- i = i + l + 1
- }
- copy(b[i:i+1], []byte{0})
-
- return &utf16.Encode([]rune(string(b)))[0], nil
-}
-
-func CloseOnExec(fd Handle) {
- SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
-}
-
-func SetNonblock(fd Handle, nonblocking bool) (err error) {
- return nil
-}
-
-// FullPath retrieves the full path of the specified file.
-func FullPath(name string) (path string, err error) {
- p, err := UTF16PtrFromString(name)
- if err != nil {
- return "", err
- }
- n := uint32(100)
- for {
- buf := make([]uint16, n)
- n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
- if err != nil {
- return "", err
- }
- if n <= uint32(len(buf)) {
- return UTF16ToString(buf[:n]), nil
- }
- }
-}
-
-func isSlash(c uint8) bool {
- return c == '\\' || c == '/'
-}
-
-func normalizeDir(dir string) (name string, err error) {
- ndir, err := FullPath(dir)
- if err != nil {
- return "", err
- }
- if len(ndir) > 2 && isSlash(ndir[0]) && isSlash(ndir[1]) {
- // dir cannot have \\server\share\path form
- return "", EINVAL
- }
- return ndir, nil
-}
-
-func volToUpper(ch int) int {
- if 'a' <= ch && ch <= 'z' {
- ch += 'A' - 'a'
- }
- return ch
-}
-
-func joinExeDirAndFName(dir, p string) (name string, err error) {
- if len(p) == 0 {
- return "", EINVAL
- }
- if len(p) > 2 && isSlash(p[0]) && isSlash(p[1]) {
- // \\server\share\path form
- return p, nil
- }
- if len(p) > 1 && p[1] == ':' {
- // has drive letter
- if len(p) == 2 {
- return "", EINVAL
- }
- if isSlash(p[2]) {
- return p, nil
- } else {
- d, err := normalizeDir(dir)
- if err != nil {
- return "", err
- }
- if volToUpper(int(p[0])) == volToUpper(int(d[0])) {
- return FullPath(d + "\\" + p[2:])
- } else {
- return FullPath(p)
- }
- }
- } else {
- // no drive letter
- d, err := normalizeDir(dir)
- if err != nil {
- return "", err
- }
- if isSlash(p[0]) {
- return FullPath(d[:2] + p)
- } else {
- return FullPath(d + "\\" + p)
- }
- }
-}
-
-type ProcAttr struct {
- Dir string
- Env []string
- Files []uintptr
- Sys *SysProcAttr
-}
-
-type SysProcAttr struct {
- HideWindow bool
- CmdLine string // used if non-empty, else the windows command line is built by escaping the arguments passed to StartProcess
- CreationFlags uint32
- Token Token // if set, runs new process in the security context represented by the token
- ProcessAttributes *SecurityAttributes // if set, applies these security attributes as the descriptor for the new process
- ThreadAttributes *SecurityAttributes // if set, applies these security attributes as the descriptor for the main thread of the new process
- NoInheritHandles bool // if set, each inheritable handle in the calling process is not inherited by the new process
- AdditionalInheritedHandles []Handle // a list of additional handles, already marked as inheritable, that will be inherited by the new process
- ParentProcess Handle // if non-zero, the new process regards the process given by this handle as its parent process, and AdditionalInheritedHandles, if set, should exist in this parent process
-}
-
-var zeroProcAttr ProcAttr
-var zeroSysProcAttr SysProcAttr
-
-func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
- if len(argv0) == 0 {
- return 0, 0, EWINDOWS
- }
- if attr == nil {
- attr = &zeroProcAttr
- }
- sys := attr.Sys
- if sys == nil {
- sys = &zeroSysProcAttr
- }
-
- if len(attr.Files) > 3 {
- return 0, 0, EWINDOWS
- }
- if len(attr.Files) < 3 {
- return 0, 0, EINVAL
- }
-
- if len(attr.Dir) != 0 {
- // StartProcess assumes that argv0 is relative to attr.Dir,
- // because it implies Chdir(attr.Dir) before executing argv0.
- // Windows CreateProcess assumes the opposite: it looks for
- // argv0 relative to the current directory, and, only once the new
- // process is started, it does Chdir(attr.Dir). We are adjusting
- // for that difference here by making argv0 absolute.
- var err error
- argv0, err = joinExeDirAndFName(attr.Dir, argv0)
- if err != nil {
- return 0, 0, err
- }
- }
- argv0p, err := UTF16PtrFromString(argv0)
- if err != nil {
- return 0, 0, err
- }
-
- var cmdline string
- // Windows CreateProcess takes the command line as a single string:
- // use attr.CmdLine if set, else build the command line by escaping
- // and joining each argument with spaces
- if sys.CmdLine != "" {
- cmdline = sys.CmdLine
- } else {
- cmdline = makeCmdLine(argv)
- }
-
- var argvp *uint16
- if len(cmdline) != 0 {
- argvp, err = UTF16PtrFromString(cmdline)
- if err != nil {
- return 0, 0, err
- }
- }
-
- var dirp *uint16
- if len(attr.Dir) != 0 {
- dirp, err = UTF16PtrFromString(attr.Dir)
- if err != nil {
- return 0, 0, err
- }
- }
-
- var maj, min, build uint32
- rtlGetNtVersionNumbers(&maj, &min, &build)
- isWin7 := maj < 6 || (maj == 6 && min <= 1)
- // NT kernel handles are divisible by 4, with the bottom 3 bits left as
- // a tag. The fully set tag correlates with the types of handles we're
- // concerned about here. Except, the kernel will interpret some
- // special handle values, like -1, -2, and so forth, so kernelbase.dll
- // checks to see that those bottom three bits are checked, but that top
- // bit is not checked.
- isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 }
-
- p, _ := GetCurrentProcess()
- parentProcess := p
- if sys.ParentProcess != 0 {
- parentProcess = sys.ParentProcess
- }
- fd := make([]Handle, len(attr.Files))
- for i := range attr.Files {
- if attr.Files[i] > 0 {
- destinationProcessHandle := parentProcess
-
- // On Windows 7, console handles aren't real handles, and can only be duplicated
- // into the current process, not a parent one, which amounts to the same thing.
- if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) {
- destinationProcessHandle = p
- }
-
- err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS)
- if err != nil {
- return 0, 0, err
- }
- defer DuplicateHandle(parentProcess, fd[i], 0, nil, 0, false, DUPLICATE_CLOSE_SOURCE)
- }
- }
- si := new(_STARTUPINFOEXW)
- si.ProcThreadAttributeList, err = newProcThreadAttributeList(2)
- if err != nil {
- return 0, 0, err
- }
- defer deleteProcThreadAttributeList(si.ProcThreadAttributeList)
- si.Cb = uint32(unsafe.Sizeof(*si))
- si.Flags = STARTF_USESTDHANDLES
- if sys.HideWindow {
- si.Flags |= STARTF_USESHOWWINDOW
- si.ShowWindow = SW_HIDE
- }
- if sys.ParentProcess != 0 {
- err = updateProcThreadAttribute(si.ProcThreadAttributeList, 0, _PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, unsafe.Pointer(&sys.ParentProcess), unsafe.Sizeof(sys.ParentProcess), nil, nil)
- if err != nil {
- return 0, 0, err
- }
- }
- si.StdInput = fd[0]
- si.StdOutput = fd[1]
- si.StdErr = fd[2]
-
- fd = append(fd, sys.AdditionalInheritedHandles...)
-
- // On Windows 7, console handles aren't real handles, so don't pass them
- // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST.
- for i := range fd {
- if isLegacyWin7ConsoleHandle(fd[i]) {
- fd[i] = 0
- }
- }
-
- // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST
- // to treat the entire list as empty, so remove NULL handles.
- j := 0
- for i := range fd {
- if fd[i] != 0 {
- fd[j] = fd[i]
- j++
- }
- }
- fd = fd[:j]
-
- willInheritHandles := len(fd) > 0 && !sys.NoInheritHandles
-
- // Do not accidentally inherit more than these handles.
- if willInheritHandles {
- err = updateProcThreadAttribute(si.ProcThreadAttributeList, 0, _PROC_THREAD_ATTRIBUTE_HANDLE_LIST, unsafe.Pointer(&fd[0]), uintptr(len(fd))*unsafe.Sizeof(fd[0]), nil, nil)
- if err != nil {
- return 0, 0, err
- }
- }
-
- envBlock, err := createEnvBlock(attr.Env)
- if err != nil {
- return 0, 0, err
- }
-
- pi := new(ProcessInformation)
- flags := sys.CreationFlags | CREATE_UNICODE_ENVIRONMENT | _EXTENDED_STARTUPINFO_PRESENT
- if sys.Token != 0 {
- err = CreateProcessAsUser(sys.Token, argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, willInheritHandles, flags, envBlock, dirp, &si.StartupInfo, pi)
- } else {
- err = CreateProcess(argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, willInheritHandles, flags, envBlock, dirp, &si.StartupInfo, pi)
- }
- if err != nil {
- return 0, 0, err
- }
- defer CloseHandle(Handle(pi.Thread))
- runtime.KeepAlive(fd)
- runtime.KeepAlive(sys)
-
- return int(pi.ProcessId), uintptr(pi.Process), nil
-}
-
-func Exec(argv0 string, argv []string, envv []string) (err error) {
- return EWINDOWS
-}
diff --git a/contrib/go/_std_1.20/src/syscall/forkpipe.go b/contrib/go/_std_1.20/src/syscall/forkpipe.go
deleted file mode 100644
index 5082abc41c..0000000000
--- a/contrib/go/_std_1.20/src/syscall/forkpipe.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2011 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.
-
-//go:build aix || darwin
-
-package syscall
-
-// Try to open a pipe with O_CLOEXEC set on both file descriptors.
-func forkExecPipe(p []int) error {
- err := Pipe(p)
- if err != nil {
- return err
- }
- _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC)
- if err != nil {
- return err
- }
- _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
- return err
-}
diff --git a/contrib/go/_std_1.20/src/syscall/netlink_linux.go b/contrib/go/_std_1.20/src/syscall/netlink_linux.go
deleted file mode 100644
index e976c70ef1..0000000000
--- a/contrib/go/_std_1.20/src/syscall/netlink_linux.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2011 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.
-
-// Netlink sockets and messages
-
-package syscall
-
-import "unsafe"
-
-// Round the length of a netlink message up to align it properly.
-func nlmAlignOf(msglen int) int {
- return (msglen + NLMSG_ALIGNTO - 1) & ^(NLMSG_ALIGNTO - 1)
-}
-
-// Round the length of a netlink route attribute up to align it
-// properly.
-func rtaAlignOf(attrlen int) int {
- return (attrlen + RTA_ALIGNTO - 1) & ^(RTA_ALIGNTO - 1)
-}
-
-// NetlinkRouteRequest represents a request message to receive routing
-// and link states from the kernel.
-type NetlinkRouteRequest struct {
- Header NlMsghdr
- Data RtGenmsg
-}
-
-func (rr *NetlinkRouteRequest) toWireFormat() []byte {
- b := make([]byte, rr.Header.Len)
- *(*uint32)(unsafe.Pointer(&b[0:4][0])) = rr.Header.Len
- *(*uint16)(unsafe.Pointer(&b[4:6][0])) = rr.Header.Type
- *(*uint16)(unsafe.Pointer(&b[6:8][0])) = rr.Header.Flags
- *(*uint32)(unsafe.Pointer(&b[8:12][0])) = rr.Header.Seq
- *(*uint32)(unsafe.Pointer(&b[12:16][0])) = rr.Header.Pid
- b[16] = byte(rr.Data.Family)
- return b
-}
-
-func newNetlinkRouteRequest(proto, seq, family int) []byte {
- rr := &NetlinkRouteRequest{}
- rr.Header.Len = uint32(NLMSG_HDRLEN + SizeofRtGenmsg)
- rr.Header.Type = uint16(proto)
- rr.Header.Flags = NLM_F_DUMP | NLM_F_REQUEST
- rr.Header.Seq = uint32(seq)
- rr.Data.Family = uint8(family)
- return rr.toWireFormat()
-}
-
-// NetlinkRIB returns routing information base, as known as RIB, which
-// consists of network facility information, states and parameters.
-func NetlinkRIB(proto, family int) ([]byte, error) {
- s, err := Socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE)
- if err != nil {
- return nil, err
- }
- defer Close(s)
- sa := &SockaddrNetlink{Family: AF_NETLINK}
- if err := Bind(s, sa); err != nil {
- return nil, err
- }
- wb := newNetlinkRouteRequest(proto, 1, family)
- if err := Sendto(s, wb, 0, sa); err != nil {
- return nil, err
- }
- lsa, err := Getsockname(s)
- if err != nil {
- return nil, err
- }
- lsanl, ok := lsa.(*SockaddrNetlink)
- if !ok {
- return nil, EINVAL
- }
- var tab []byte
- rbNew := make([]byte, Getpagesize())
-done:
- for {
- rb := rbNew
- nr, _, err := Recvfrom(s, rb, 0)
- if err != nil {
- return nil, err
- }
- if nr < NLMSG_HDRLEN {
- return nil, EINVAL
- }
- rb = rb[:nr]
- tab = append(tab, rb...)
- msgs, err := ParseNetlinkMessage(rb)
- if err != nil {
- return nil, err
- }
- for _, m := range msgs {
- if m.Header.Seq != 1 || m.Header.Pid != lsanl.Pid {
- return nil, EINVAL
- }
- if m.Header.Type == NLMSG_DONE {
- break done
- }
- if m.Header.Type == NLMSG_ERROR {
- return nil, EINVAL
- }
- }
- }
- return tab, nil
-}
-
-// NetlinkMessage represents a netlink message.
-type NetlinkMessage struct {
- Header NlMsghdr
- Data []byte
-}
-
-// ParseNetlinkMessage parses b as an array of netlink messages and
-// returns the slice containing the NetlinkMessage structures.
-func ParseNetlinkMessage(b []byte) ([]NetlinkMessage, error) {
- var msgs []NetlinkMessage
- for len(b) >= NLMSG_HDRLEN {
- h, dbuf, dlen, err := netlinkMessageHeaderAndData(b)
- if err != nil {
- return nil, err
- }
- m := NetlinkMessage{Header: *h, Data: dbuf[:int(h.Len)-NLMSG_HDRLEN]}
- msgs = append(msgs, m)
- b = b[dlen:]
- }
- return msgs, nil
-}
-
-func netlinkMessageHeaderAndData(b []byte) (*NlMsghdr, []byte, int, error) {
- h := (*NlMsghdr)(unsafe.Pointer(&b[0]))
- l := nlmAlignOf(int(h.Len))
- if int(h.Len) < NLMSG_HDRLEN || l > len(b) {
- return nil, nil, 0, EINVAL
- }
- return h, b[NLMSG_HDRLEN:], l, nil
-}
-
-// NetlinkRouteAttr represents a netlink route attribute.
-type NetlinkRouteAttr struct {
- Attr RtAttr
- Value []byte
-}
-
-// ParseNetlinkRouteAttr parses m's payload as an array of netlink
-// route attributes and returns the slice containing the
-// NetlinkRouteAttr structures.
-func ParseNetlinkRouteAttr(m *NetlinkMessage) ([]NetlinkRouteAttr, error) {
- var b []byte
- switch m.Header.Type {
- case RTM_NEWLINK, RTM_DELLINK:
- b = m.Data[SizeofIfInfomsg:]
- case RTM_NEWADDR, RTM_DELADDR:
- b = m.Data[SizeofIfAddrmsg:]
- case RTM_NEWROUTE, RTM_DELROUTE:
- b = m.Data[SizeofRtMsg:]
- default:
- return nil, EINVAL
- }
- var attrs []NetlinkRouteAttr
- for len(b) >= SizeofRtAttr {
- a, vbuf, alen, err := netlinkRouteAttrAndValue(b)
- if err != nil {
- return nil, err
- }
- ra := NetlinkRouteAttr{Attr: *a, Value: vbuf[:int(a.Len)-SizeofRtAttr]}
- attrs = append(attrs, ra)
- b = b[alen:]
- }
- return attrs, nil
-}
-
-func netlinkRouteAttrAndValue(b []byte) (*RtAttr, []byte, int, error) {
- a := (*RtAttr)(unsafe.Pointer(&b[0]))
- if int(a.Len) < SizeofRtAttr || int(a.Len) > len(b) {
- return nil, nil, 0, EINVAL
- }
- return a, b[SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil
-}
diff --git a/contrib/go/_std_1.20/src/syscall/ptrace_darwin.go b/contrib/go/_std_1.20/src/syscall/ptrace_darwin.go
deleted file mode 100644
index 519e451c73..0000000000
--- a/contrib/go/_std_1.20/src/syscall/ptrace_darwin.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.
-
-//go:build !ios
-
-package syscall
-
-// Nosplit because it is called from forkAndExecInChild.
-//
-//go:nosplit
-func ptrace(request int, pid int, addr uintptr, data uintptr) error {
- return ptrace1(request, pid, addr, data)
-}
diff --git a/contrib/go/_std_1.20/src/syscall/security_windows.go b/contrib/go/_std_1.20/src/syscall/security_windows.go
deleted file mode 100644
index 67102b6929..0000000000
--- a/contrib/go/_std_1.20/src/syscall/security_windows.go
+++ /dev/null
@@ -1,379 +0,0 @@
-// Copyright 2012 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 syscall
-
-import (
- "unsafe"
-)
-
-const (
- STANDARD_RIGHTS_REQUIRED = 0xf0000
- STANDARD_RIGHTS_READ = 0x20000
- STANDARD_RIGHTS_WRITE = 0x20000
- STANDARD_RIGHTS_EXECUTE = 0x20000
- STANDARD_RIGHTS_ALL = 0x1F0000
-)
-
-const (
- NameUnknown = 0
- NameFullyQualifiedDN = 1
- NameSamCompatible = 2
- NameDisplay = 3
- NameUniqueId = 6
- NameCanonical = 7
- NameUserPrincipal = 8
- NameCanonicalEx = 9
- NameServicePrincipal = 10
- NameDnsDomain = 12
-)
-
-// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
-// https://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
-//sys TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
-//sys GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
-
-// TranslateAccountName converts a directory service
-// object name from one format to another.
-func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
- u, e := UTF16PtrFromString(username)
- if e != nil {
- return "", e
- }
- n := uint32(50)
- for {
- b := make([]uint16, n)
- e = TranslateName(u, from, to, &b[0], &n)
- if e == nil {
- return UTF16ToString(b[:n]), nil
- }
- if e != ERROR_INSUFFICIENT_BUFFER {
- return "", e
- }
- if n <= uint32(len(b)) {
- return "", e
- }
- }
-}
-
-const (
- // do not reorder
- NetSetupUnknownStatus = iota
- NetSetupUnjoined
- NetSetupWorkgroupName
- NetSetupDomainName
-)
-
-type UserInfo10 struct {
- Name *uint16
- Comment *uint16
- UsrComment *uint16
- FullName *uint16
-}
-
-//sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
-//sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
-//sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
-
-const (
- // do not reorder
- SidTypeUser = 1 + iota
- SidTypeGroup
- SidTypeDomain
- SidTypeAlias
- SidTypeWellKnownGroup
- SidTypeDeletedAccount
- SidTypeInvalid
- SidTypeUnknown
- SidTypeComputer
- SidTypeLabel
-)
-
-//sys LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
-//sys LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
-//sys ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
-//sys ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
-//sys GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
-//sys CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
-
-// The security identifier (SID) structure is a variable-length
-// structure used to uniquely identify users or groups.
-type SID struct{}
-
-// StringToSid converts a string-format security identifier
-// sid into a valid, functional sid.
-func StringToSid(s string) (*SID, error) {
- var sid *SID
- p, e := UTF16PtrFromString(s)
- if e != nil {
- return nil, e
- }
- e = ConvertStringSidToSid(p, &sid)
- if e != nil {
- return nil, e
- }
- defer LocalFree((Handle)(unsafe.Pointer(sid)))
- return sid.Copy()
-}
-
-// LookupSID retrieves a security identifier sid for the account
-// and the name of the domain on which the account was found.
-// System specify target computer to search.
-func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
- if len(account) == 0 {
- return nil, "", 0, EINVAL
- }
- acc, e := UTF16PtrFromString(account)
- if e != nil {
- return nil, "", 0, e
- }
- var sys *uint16
- if len(system) > 0 {
- sys, e = UTF16PtrFromString(system)
- if e != nil {
- return nil, "", 0, e
- }
- }
- n := uint32(50)
- dn := uint32(50)
- for {
- b := make([]byte, n)
- db := make([]uint16, dn)
- sid = (*SID)(unsafe.Pointer(&b[0]))
- e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
- if e == nil {
- return sid, UTF16ToString(db), accType, nil
- }
- if e != ERROR_INSUFFICIENT_BUFFER {
- return nil, "", 0, e
- }
- if n <= uint32(len(b)) {
- return nil, "", 0, e
- }
- }
-}
-
-// String converts sid to a string format
-// suitable for display, storage, or transmission.
-func (sid *SID) String() (string, error) {
- var s *uint16
- e := ConvertSidToStringSid(sid, &s)
- if e != nil {
- return "", e
- }
- defer LocalFree((Handle)(unsafe.Pointer(s)))
- return utf16PtrToString(s), nil
-}
-
-// Len returns the length, in bytes, of a valid security identifier sid.
-func (sid *SID) Len() int {
- return int(GetLengthSid(sid))
-}
-
-// Copy creates a duplicate of security identifier sid.
-func (sid *SID) Copy() (*SID, error) {
- b := make([]byte, sid.Len())
- sid2 := (*SID)(unsafe.Pointer(&b[0]))
- e := CopySid(uint32(len(b)), sid2, sid)
- if e != nil {
- return nil, e
- }
- return sid2, nil
-}
-
-// LookupAccount retrieves the name of the account for this sid
-// and the name of the first domain on which this sid is found.
-// System specify target computer to search for.
-func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
- var sys *uint16
- if len(system) > 0 {
- sys, err = UTF16PtrFromString(system)
- if err != nil {
- return "", "", 0, err
- }
- }
- n := uint32(50)
- dn := uint32(50)
- for {
- b := make([]uint16, n)
- db := make([]uint16, dn)
- e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
- if e == nil {
- return UTF16ToString(b), UTF16ToString(db), accType, nil
- }
- if e != ERROR_INSUFFICIENT_BUFFER {
- return "", "", 0, e
- }
- if n <= uint32(len(b)) {
- return "", "", 0, e
- }
- }
-}
-
-const (
- // do not reorder
- TOKEN_ASSIGN_PRIMARY = 1 << iota
- TOKEN_DUPLICATE
- TOKEN_IMPERSONATE
- TOKEN_QUERY
- TOKEN_QUERY_SOURCE
- TOKEN_ADJUST_PRIVILEGES
- TOKEN_ADJUST_GROUPS
- TOKEN_ADJUST_DEFAULT
- TOKEN_ADJUST_SESSIONID
-
- TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
- TOKEN_ASSIGN_PRIMARY |
- TOKEN_DUPLICATE |
- TOKEN_IMPERSONATE |
- TOKEN_QUERY |
- TOKEN_QUERY_SOURCE |
- TOKEN_ADJUST_PRIVILEGES |
- TOKEN_ADJUST_GROUPS |
- TOKEN_ADJUST_DEFAULT |
- TOKEN_ADJUST_SESSIONID
- TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY
- TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
- TOKEN_ADJUST_PRIVILEGES |
- TOKEN_ADJUST_GROUPS |
- TOKEN_ADJUST_DEFAULT
- TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
-)
-
-const (
- // do not reorder
- TokenUser = 1 + iota
- TokenGroups
- TokenPrivileges
- TokenOwner
- TokenPrimaryGroup
- TokenDefaultDacl
- TokenSource
- TokenType
- TokenImpersonationLevel
- TokenStatistics
- TokenRestrictedSids
- TokenSessionId
- TokenGroupsAndPrivileges
- TokenSessionReference
- TokenSandBoxInert
- TokenAuditPolicy
- TokenOrigin
- TokenElevationType
- TokenLinkedToken
- TokenElevation
- TokenHasRestrictions
- TokenAccessInformation
- TokenVirtualizationAllowed
- TokenVirtualizationEnabled
- TokenIntegrityLevel
- TokenUIAccess
- TokenMandatoryPolicy
- TokenLogonSid
- MaxTokenInfoClass
-)
-
-type SIDAndAttributes struct {
- Sid *SID
- Attributes uint32
-}
-
-type Tokenuser struct {
- User SIDAndAttributes
-}
-
-type Tokenprimarygroup struct {
- PrimaryGroup *SID
-}
-
-//sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
-//sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
-//sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
-//sys getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW
-
-// An access token contains the security information for a logon session.
-// The system creates an access token when a user logs on, and every
-// process executed on behalf of the user has a copy of the token.
-// The token identifies the user, the user's groups, and the user's
-// privileges. The system uses the token to control access to securable
-// objects and to control the ability of the user to perform various
-// system-related operations on the local computer.
-type Token Handle
-
-// OpenCurrentProcessToken opens the access token
-// associated with current process.
-func OpenCurrentProcessToken() (Token, error) {
- p, e := GetCurrentProcess()
- if e != nil {
- return 0, e
- }
- var t Token
- e = OpenProcessToken(p, TOKEN_QUERY, &t)
- if e != nil {
- return 0, e
- }
- return t, nil
-}
-
-// Close releases access to access token.
-func (t Token) Close() error {
- return CloseHandle(Handle(t))
-}
-
-// getInfo retrieves a specified type of information about an access token.
-func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
- n := uint32(initSize)
- for {
- b := make([]byte, n)
- e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
- if e == nil {
- return unsafe.Pointer(&b[0]), nil
- }
- if e != ERROR_INSUFFICIENT_BUFFER {
- return nil, e
- }
- if n <= uint32(len(b)) {
- return nil, e
- }
- }
-}
-
-// GetTokenUser retrieves access token t user account information.
-func (t Token) GetTokenUser() (*Tokenuser, error) {
- i, e := t.getInfo(TokenUser, 50)
- if e != nil {
- return nil, e
- }
- return (*Tokenuser)(i), nil
-}
-
-// GetTokenPrimaryGroup retrieves access token t primary group information.
-// A pointer to a SID structure representing a group that will become
-// the primary group of any objects created by a process using this access token.
-func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
- i, e := t.getInfo(TokenPrimaryGroup, 50)
- if e != nil {
- return nil, e
- }
- return (*Tokenprimarygroup)(i), nil
-}
-
-// GetUserProfileDirectory retrieves path to the
-// root directory of the access token t user's profile.
-func (t Token) GetUserProfileDirectory() (string, error) {
- n := uint32(100)
- for {
- b := make([]uint16, n)
- e := GetUserProfileDirectory(t, &b[0], &n)
- if e == nil {
- return UTF16ToString(b), nil
- }
- if e != ERROR_INSUFFICIENT_BUFFER {
- return "", e
- }
- if n <= uint32(len(b)) {
- return "", e
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/syscall/syscall_bsd.go b/contrib/go/_std_1.20/src/syscall/syscall_bsd.go
deleted file mode 100644
index c7a7d786dc..0000000000
--- a/contrib/go/_std_1.20/src/syscall/syscall_bsd.go
+++ /dev/null
@@ -1,532 +0,0 @@
-// Copyright 2009 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.
-
-//go:build darwin || dragonfly || freebsd || netbsd || openbsd
-
-// BSD system call wrappers shared by *BSD based systems
-// including OS X (Darwin) and FreeBSD. Like the other
-// syscall_*.go files it is compiled as Go code but also
-// used as input to mksyscall which parses the //sys
-// lines and generates system call stubs.
-
-package syscall
-
-import (
- "runtime"
- "unsafe"
-)
-
-const ImplementsGetwd = true
-
-func Getwd() (string, error) {
- var buf [pathMax]byte
- _, err := getcwd(buf[:])
- if err != nil {
- return "", err
- }
- n := clen(buf[:])
- if n < 1 {
- return "", EINVAL
- }
- return string(buf[:n]), nil
-}
-
-/*
- * Wrapped
- */
-
-//sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error)
-//sysnb setgroups(ngid int, gid *_Gid_t) (err error)
-
-func Getgroups() (gids []int, err error) {
- n, err := getgroups(0, nil)
- if err != nil {
- return nil, err
- }
- if n == 0 {
- return nil, nil
- }
-
- // Sanity check group count. Max is 16 on BSD.
- if n < 0 || n > 1000 {
- return nil, EINVAL
- }
-
- a := make([]_Gid_t, n)
- n, err = getgroups(n, &a[0])
- if err != nil {
- return nil, err
- }
- gids = make([]int, n)
- for i, v := range a[0:n] {
- gids[i] = int(v)
- }
- return
-}
-
-func Setgroups(gids []int) (err error) {
- if len(gids) == 0 {
- return setgroups(0, nil)
- }
-
- a := make([]_Gid_t, len(gids))
- for i, v := range gids {
- a[i] = _Gid_t(v)
- }
- return setgroups(len(a), &a[0])
-}
-
-func ReadDirent(fd int, buf []byte) (n int, err error) {
- // Final argument is (basep *uintptr) and the syscall doesn't take nil.
- // 64 bits should be enough. (32 bits isn't even on 386). Since the
- // actual system call is getdirentries64, 64 is a good guess.
- // TODO(rsc): Can we use a single global basep for all calls?
- var base = (*uintptr)(unsafe.Pointer(new(uint64)))
- return Getdirentries(fd, buf, base)
-}
-
-// Wait status is 7 bits at bottom, either 0 (exited),
-// 0x7F (stopped), or a signal number that caused an exit.
-// The 0x80 bit is whether there was a core dump.
-// An extra number (exit code, signal causing a stop)
-// is in the high bits.
-
-type WaitStatus uint32
-
-const (
- mask = 0x7F
- core = 0x80
- shift = 8
-
- exited = 0
- stopped = 0x7F
-)
-
-func (w WaitStatus) Exited() bool { return w&mask == exited }
-
-func (w WaitStatus) ExitStatus() int {
- if w&mask != exited {
- return -1
- }
- return int(w >> shift)
-}
-
-func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
-
-func (w WaitStatus) Signal() Signal {
- sig := Signal(w & mask)
- if sig == stopped || sig == 0 {
- return -1
- }
- return sig
-}
-
-func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
-
-func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP }
-
-func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP }
-
-func (w WaitStatus) StopSignal() Signal {
- if !w.Stopped() {
- return -1
- }
- return Signal(w>>shift) & 0xFF
-}
-
-func (w WaitStatus) TrapCause() int { return -1 }
-
-//sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
-
-func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
- var status _C_int
- wpid, err = wait4(pid, &status, options, rusage)
- if wstatus != nil {
- *wstatus = WaitStatus(status)
- }
- return
-}
-
-//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
-//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
-//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
-//sysnb socket(domain int, typ int, proto int) (fd int, err error)
-//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
-//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
-//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
-//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
-//sys Shutdown(s int, how int) (err error)
-
-func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
- if sa.Port < 0 || sa.Port > 0xFFFF {
- return nil, 0, EINVAL
- }
- sa.raw.Len = SizeofSockaddrInet4
- sa.raw.Family = AF_INET
- p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
- p[0] = byte(sa.Port >> 8)
- p[1] = byte(sa.Port)
- sa.raw.Addr = sa.Addr
- return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
-}
-
-func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
- if sa.Port < 0 || sa.Port > 0xFFFF {
- return nil, 0, EINVAL
- }
- sa.raw.Len = SizeofSockaddrInet6
- sa.raw.Family = AF_INET6
- p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
- p[0] = byte(sa.Port >> 8)
- p[1] = byte(sa.Port)
- sa.raw.Scope_id = sa.ZoneId
- sa.raw.Addr = sa.Addr
- return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
-}
-
-func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
- name := sa.Name
- n := len(name)
- if n >= len(sa.raw.Path) || n == 0 {
- return nil, 0, EINVAL
- }
- sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
- sa.raw.Family = AF_UNIX
- for i := 0; i < n; i++ {
- sa.raw.Path[i] = int8(name[i])
- }
- return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
-}
-
-func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
- if sa.Index == 0 {
- return nil, 0, EINVAL
- }
- sa.raw.Len = sa.Len
- sa.raw.Family = AF_LINK
- sa.raw.Index = sa.Index
- sa.raw.Type = sa.Type
- sa.raw.Nlen = sa.Nlen
- sa.raw.Alen = sa.Alen
- sa.raw.Slen = sa.Slen
- sa.raw.Data = sa.Data
- return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
-}
-
-func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
- switch rsa.Addr.Family {
- case AF_LINK:
- pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
- sa := new(SockaddrDatalink)
- sa.Len = pp.Len
- sa.Family = pp.Family
- sa.Index = pp.Index
- sa.Type = pp.Type
- sa.Nlen = pp.Nlen
- sa.Alen = pp.Alen
- sa.Slen = pp.Slen
- sa.Data = pp.Data
- return sa, nil
-
- case AF_UNIX:
- pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
- if pp.Len < 2 || pp.Len > SizeofSockaddrUnix {
- return nil, EINVAL
- }
- sa := new(SockaddrUnix)
-
- // Some BSDs include the trailing NUL in the length, whereas
- // others do not. Work around this by subtracting the leading
- // family and len. The path is then scanned to see if a NUL
- // terminator still exists within the length.
- n := int(pp.Len) - 2 // subtract leading Family, Len
- for i := 0; i < n; i++ {
- if pp.Path[i] == 0 {
- // found early NUL; assume Len included the NUL
- // or was overestimating.
- n = i
- break
- }
- }
- bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
- sa.Name = string(bytes)
- return sa, nil
-
- case AF_INET:
- pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
- sa := new(SockaddrInet4)
- p := (*[2]byte)(unsafe.Pointer(&pp.Port))
- sa.Port = int(p[0])<<8 + int(p[1])
- sa.Addr = pp.Addr
- return sa, nil
-
- case AF_INET6:
- pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
- sa := new(SockaddrInet6)
- p := (*[2]byte)(unsafe.Pointer(&pp.Port))
- sa.Port = int(p[0])<<8 + int(p[1])
- sa.ZoneId = pp.Scope_id
- sa.Addr = pp.Addr
- return sa, nil
- }
- return nil, EAFNOSUPPORT
-}
-
-func Accept(fd int) (nfd int, sa Sockaddr, err error) {
- var rsa RawSockaddrAny
- var len _Socklen = SizeofSockaddrAny
- nfd, err = accept(fd, &rsa, &len)
- if err != nil {
- return
- }
- if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && len == 0 {
- // Accepted socket has no address.
- // This is likely due to a bug in xnu kernels,
- // where instead of ECONNABORTED error socket
- // is accepted, but has no address.
- Close(nfd)
- return 0, nil, ECONNABORTED
- }
- sa, err = anyToSockaddr(&rsa)
- if err != nil {
- Close(nfd)
- nfd = 0
- }
- return
-}
-
-func Getsockname(fd int) (sa Sockaddr, err error) {
- var rsa RawSockaddrAny
- var len _Socklen = SizeofSockaddrAny
- if err = getsockname(fd, &rsa, &len); err != nil {
- return
- }
- // TODO(jsing): DragonFly has a "bug" (see issue 3349), which should be
- // reported upstream.
- if runtime.GOOS == "dragonfly" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 {
- rsa.Addr.Family = AF_UNIX
- rsa.Addr.Len = SizeofSockaddrUnix
- }
- return anyToSockaddr(&rsa)
-}
-
-//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
-
-func GetsockoptByte(fd, level, opt int) (value byte, err error) {
- var n byte
- vallen := _Socklen(1)
- err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
- return n, err
-}
-
-func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
- vallen := _Socklen(4)
- err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
- return value, err
-}
-
-func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
- var value IPMreq
- vallen := _Socklen(SizeofIPMreq)
- err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
- return &value, err
-}
-
-func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
- var value IPv6Mreq
- vallen := _Socklen(SizeofIPv6Mreq)
- err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
- return &value, err
-}
-
-func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
- var value IPv6MTUInfo
- vallen := _Socklen(SizeofIPv6MTUInfo)
- err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
- return &value, err
-}
-
-func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
- var value ICMPv6Filter
- vallen := _Socklen(SizeofICMPv6Filter)
- err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
- return &value, err
-}
-
-//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
-//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
-//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
-
-func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
- var msg Msghdr
- msg.Name = (*byte)(unsafe.Pointer(rsa))
- msg.Namelen = uint32(SizeofSockaddrAny)
- var iov Iovec
- if len(p) > 0 {
- iov.Base = &p[0]
- iov.SetLen(len(p))
- }
- var dummy byte
- if len(oob) > 0 {
- // receive at least one normal byte
- if len(p) == 0 {
- iov.Base = &dummy
- iov.SetLen(1)
- }
- msg.Control = &oob[0]
- msg.SetControllen(len(oob))
- }
- msg.Iov = &iov
- msg.Iovlen = 1
- if n, err = recvmsg(fd, &msg, flags); err != nil {
- return
- }
- oobn = int(msg.Controllen)
- recvflags = int(msg.Flags)
- return
-}
-
-//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
-
-func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
- var msg Msghdr
- msg.Name = (*byte)(ptr)
- msg.Namelen = uint32(salen)
- var iov Iovec
- if len(p) > 0 {
- iov.Base = &p[0]
- iov.SetLen(len(p))
- }
- var dummy byte
- if len(oob) > 0 {
- // send at least one normal byte
- if len(p) == 0 {
- iov.Base = &dummy
- iov.SetLen(1)
- }
- msg.Control = &oob[0]
- msg.SetControllen(len(oob))
- }
- msg.Iov = &iov
- msg.Iovlen = 1
- if n, err = sendmsg(fd, &msg, flags); err != nil {
- return 0, err
- }
- if len(oob) > 0 && len(p) == 0 {
- n = 0
- }
- return n, nil
-}
-
-//sys kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error)
-
-func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err error) {
- var change, event unsafe.Pointer
- if len(changes) > 0 {
- change = unsafe.Pointer(&changes[0])
- }
- if len(events) > 0 {
- event = unsafe.Pointer(&events[0])
- }
- return kevent(kq, change, len(changes), event, len(events), timeout)
-}
-
-func Sysctl(name string) (value string, err error) {
- // Translate name to mib number.
- mib, err := nametomib(name)
- if err != nil {
- return "", err
- }
-
- // Find size.
- n := uintptr(0)
- if err = sysctl(mib, nil, &n, nil, 0); err != nil {
- return "", err
- }
- if n == 0 {
- return "", nil
- }
-
- // Read into buffer of that size.
- buf := make([]byte, n)
- if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil {
- return "", err
- }
-
- // Throw away terminating NUL.
- if n > 0 && buf[n-1] == '\x00' {
- n--
- }
- return string(buf[0:n]), nil
-}
-
-func SysctlUint32(name string) (value uint32, err error) {
- // Translate name to mib number.
- mib, err := nametomib(name)
- if err != nil {
- return 0, err
- }
-
- // Read into buffer of that size.
- n := uintptr(4)
- buf := make([]byte, 4)
- if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil {
- return 0, err
- }
- if n != 4 {
- return 0, EIO
- }
- return *(*uint32)(unsafe.Pointer(&buf[0])), nil
-}
-
-//sys utimes(path string, timeval *[2]Timeval) (err error)
-
-func Utimes(path string, tv []Timeval) (err error) {
- if len(tv) != 2 {
- return EINVAL
- }
- return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
-}
-
-func UtimesNano(path string, ts []Timespec) error {
- if len(ts) != 2 {
- return EINVAL
- }
- err := utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
- if err != ENOSYS {
- return err
- }
- // Not as efficient as it could be because Timespec and
- // Timeval have different types in the different OSes
- tv := [2]Timeval{
- NsecToTimeval(TimespecToNsec(ts[0])),
- NsecToTimeval(TimespecToNsec(ts[1])),
- }
- return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
-}
-
-//sys futimes(fd int, timeval *[2]Timeval) (err error)
-
-func Futimes(fd int, tv []Timeval) (err error) {
- if len(tv) != 2 {
- return EINVAL
- }
- return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
-}
-
-//sys fcntl(fd int, cmd int, arg int) (val int, err error)
-
-var mapper = &mmapper{
- active: make(map[*byte][]byte),
- mmap: mmap,
- munmap: munmap,
-}
-
-func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
- return mapper.Mmap(fd, offset, length, prot, flags)
-}
-
-func Munmap(b []byte) (err error) {
- return mapper.Munmap(b)
-}
diff --git a/contrib/go/_std_1.20/src/syscall/syscall_darwin_amd64.go b/contrib/go/_std_1.20/src/syscall/syscall_darwin_amd64.go
deleted file mode 100644
index ef3c1998aa..0000000000
--- a/contrib/go/_std_1.20/src/syscall/syscall_darwin_amd64.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2009 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 syscall
-
-import (
- "internal/abi"
- "unsafe"
-)
-
-func setTimespec(sec, nsec int64) Timespec {
- return Timespec{Sec: sec, Nsec: nsec}
-}
-
-func setTimeval(sec, usec int64) Timeval {
- return Timeval{Sec: sec, Usec: int32(usec)}
-}
-
-//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_fstat64
-//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_fstatfs64
-//sysnb Gettimeofday(tp *Timeval) (err error)
-//sys Lstat(path string, stat *Stat_t) (err error) = SYS_lstat64
-//sys Stat(path string, stat *Stat_t) (err error) = SYS_stat64
-//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_statfs64
-//sys fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_fstatat64
-//sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace
-
-func SetKevent(k *Kevent_t, fd, mode, flags int) {
- k.Ident = uint64(fd)
- k.Filter = int16(mode)
- k.Flags = uint16(flags)
-}
-
-func (iov *Iovec) SetLen(length int) {
- iov.Len = uint64(length)
-}
-
-func (msghdr *Msghdr) SetControllen(length int) {
- msghdr.Controllen = uint32(length)
-}
-
-func (cmsg *Cmsghdr) SetLen(length int) {
- cmsg.Len = uint32(length)
-}
-
-func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
- var length = uint64(count)
-
- _, _, e1 := syscall6(abi.FuncPCABI0(libc_sendfile_trampoline), uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0)
-
- written = int(length)
-
- if e1 != 0 {
- err = e1
- }
- return
-}
-
-func libc_sendfile_trampoline()
-
-//go:cgo_import_dynamic libc_sendfile sendfile "/usr/lib/libSystem.B.dylib"
-
-// Implemented in the runtime package (runtime/sys_darwin_64.go)
-func syscallX(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
-
-func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
diff --git a/contrib/go/_std_1.20/src/syscall/syscall_linux.go b/contrib/go/_std_1.20/src/syscall/syscall_linux.go
deleted file mode 100644
index d1c981a9b3..0000000000
--- a/contrib/go/_std_1.20/src/syscall/syscall_linux.go
+++ /dev/null
@@ -1,1274 +0,0 @@
-// Copyright 2009 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.
-
-// Linux system calls.
-// This file is compiled as ordinary Go code,
-// but it is also input to mksyscall,
-// which parses the //sys lines and generates system call stubs.
-// Note that sometimes we use a lowercase //sys name and
-// wrap it in our own nicer implementation.
-
-package syscall
-
-import (
- "internal/itoa"
- "runtime"
- "unsafe"
-)
-
-// N.B. RawSyscall6 is provided via linkname by runtime/internal/syscall.
-//
-// Errno is uintptr and thus compatible with the runtime/internal/syscall
-// definition.
-
-func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
-
-// Pull in entersyscall/exitsyscall for Syscall/Syscall6.
-//
-// Note that this can't be a push linkname because the runtime already has a
-// nameless linkname to export to assembly here and in x/sys. Additionally,
-// entersyscall fetches the caller PC and SP and thus can't have a wrapper
-// inbetween.
-
-//go:linkname runtime_entersyscall runtime.entersyscall
-func runtime_entersyscall()
-
-//go:linkname runtime_exitsyscall runtime.exitsyscall
-func runtime_exitsyscall()
-
-// N.B. For the Syscall functions below:
-//
-// //go:uintptrkeepalive because the uintptr argument may be converted pointers
-// that need to be kept alive in the caller (this is implied for RawSyscall6
-// since it has no body).
-//
-// //go:nosplit because stack copying does not account for uintptrkeepalive, so
-// the stack must not grow. Stack copying cannot blindly assume that all
-// uintptr arguments are pointers, because some values may look like pointers,
-// but not really be pointers, and adjusting their value would break the call.
-//
-// //go:norace, on RawSyscall, to avoid race instrumentation if RawSyscall is
-// called after fork, or from a signal handler.
-//
-// //go:linkname to ensure ABI wrappers are generated for external callers
-// (notably x/sys/unix assembly).
-
-//go:uintptrkeepalive
-//go:nosplit
-//go:norace
-//go:linkname RawSyscall
-func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
- return RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
-}
-
-//go:uintptrkeepalive
-//go:nosplit
-//go:linkname Syscall
-func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
- runtime_entersyscall()
- // N.B. Calling RawSyscall here is unsafe with atomic coverage
- // instrumentation and race mode.
- //
- // Coverage instrumentation will add a sync/atomic call to RawSyscall.
- // Race mode will add race instrumentation to sync/atomic. Race
- // instrumentation requires a P, which we no longer have.
- //
- // RawSyscall6 is fine because it is implemented in assembly and thus
- // has no coverage instrumentation.
- //
- // This is typically not a problem in the runtime because cmd/go avoids
- // adding coverage instrumentation to the runtime in race mode.
- r1, r2, err = RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
- runtime_exitsyscall()
- return
-}
-
-//go:uintptrkeepalive
-//go:nosplit
-//go:linkname Syscall6
-func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
- runtime_entersyscall()
- r1, r2, err = RawSyscall6(trap, a1, a2, a3, a4, a5, a6)
- runtime_exitsyscall()
- return
-}
-
-func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
-func rawVforkSyscall(trap, a1, a2 uintptr) (r1 uintptr, err Errno)
-
-/*
- * Wrapped
- */
-
-func Access(path string, mode uint32) (err error) {
- return Faccessat(_AT_FDCWD, path, mode, 0)
-}
-
-func Chmod(path string, mode uint32) (err error) {
- return Fchmodat(_AT_FDCWD, path, mode, 0)
-}
-
-func Chown(path string, uid int, gid int) (err error) {
- return Fchownat(_AT_FDCWD, path, uid, gid, 0)
-}
-
-func Creat(path string, mode uint32) (fd int, err error) {
- return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
-}
-
-func EpollCreate(size int) (fd int, err error) {
- if size <= 0 {
- return -1, EINVAL
- }
- return EpollCreate1(0)
-}
-
-func isGroupMember(gid int) bool {
- groups, err := Getgroups()
- if err != nil {
- return false
- }
-
- for _, g := range groups {
- if g == gid {
- return true
- }
- }
- return false
-}
-
-func isCapDacOverrideSet() bool {
- const _CAP_DAC_OVERRIDE = 1
- var c caps
- c.hdr.version = _LINUX_CAPABILITY_VERSION_3
-
- _, _, err := RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&c.hdr)), uintptr(unsafe.Pointer(&c.data[0])), 0)
-
- return err == 0 && c.data[0].effective&capToMask(_CAP_DAC_OVERRIDE) != 0
-}
-
-//sys faccessat(dirfd int, path string, mode uint32) (err error)
-//sys faccessat2(dirfd int, path string, mode uint32, flags int) (err error) = _SYS_faccessat2
-
-func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
- if flags == 0 {
- return faccessat(dirfd, path, mode)
- }
-
- // Attempt to use the newer faccessat2, which supports flags directly,
- // falling back if it doesn't exist.
- //
- // Don't attempt on Android, which does not allow faccessat2 through
- // its seccomp policy [1] on any version of Android as of 2022-12-20.
- //
- // [1] https://cs.android.com/android/platform/superproject/+/master:bionic/libc/SECCOMP_BLOCKLIST_APP.TXT;l=4;drc=dbb8670dfdcc677f7e3b9262e93800fa14c4e417
- if runtime.GOOS != "android" {
- if err := faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
- return err
- }
- }
-
- // The Linux kernel faccessat system call does not take any flags.
- // The glibc faccessat implements the flags itself; see
- // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD
- // Because people naturally expect syscall.Faccessat to act
- // like C faccessat, we do the same.
-
- if flags & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 {
- return EINVAL
- }
-
- var st Stat_t
- if err := fstatat(dirfd, path, &st, flags&_AT_SYMLINK_NOFOLLOW); err != nil {
- return err
- }
-
- mode &= 7
- if mode == 0 {
- return nil
- }
-
- // Fallback to checking permission bits.
- var uid int
- if flags&_AT_EACCESS != 0 {
- uid = Geteuid()
- if uid != 0 && isCapDacOverrideSet() {
- // If CAP_DAC_OVERRIDE is set, file access check is
- // done by the kernel in the same way as for root
- // (see generic_permission() in the Linux sources).
- uid = 0
- }
- } else {
- uid = Getuid()
- }
-
- if uid == 0 {
- if mode&1 == 0 {
- // Root can read and write any file.
- return nil
- }
- if st.Mode&0111 != 0 {
- // Root can execute any file that anybody can execute.
- return nil
- }
- return EACCES
- }
-
- var fmode uint32
- if uint32(uid) == st.Uid {
- fmode = (st.Mode >> 6) & 7
- } else {
- var gid int
- if flags&_AT_EACCESS != 0 {
- gid = Getegid()
- } else {
- gid = Getgid()
- }
-
- if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
- fmode = (st.Mode >> 3) & 7
- } else {
- fmode = st.Mode & 7
- }
- }
-
- if fmode&mode == mode {
- return nil
- }
-
- return EACCES
-}
-
-//sys fchmodat(dirfd int, path string, mode uint32) (err error)
-
-func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
- // Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior
- // and check the flags. Otherwise the mode would be applied to the symlink
- // destination which is not what the user expects.
- if flags&^_AT_SYMLINK_NOFOLLOW != 0 {
- return EINVAL
- } else if flags&_AT_SYMLINK_NOFOLLOW != 0 {
- return EOPNOTSUPP
- }
- return fchmodat(dirfd, path, mode)
-}
-
-//sys linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
-
-func Link(oldpath string, newpath string) (err error) {
- return linkat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath, 0)
-}
-
-func Mkdir(path string, mode uint32) (err error) {
- return Mkdirat(_AT_FDCWD, path, mode)
-}
-
-func Mknod(path string, mode uint32, dev int) (err error) {
- return Mknodat(_AT_FDCWD, path, mode, dev)
-}
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
- return openat(_AT_FDCWD, path, mode|O_LARGEFILE, perm)
-}
-
-//sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
-
-func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
- return openat(dirfd, path, flags|O_LARGEFILE, mode)
-}
-
-func Pipe(p []int) error {
- return Pipe2(p, 0)
-}
-
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
-
-func Pipe2(p []int, flags int) error {
- if len(p) != 2 {
- return EINVAL
- }
- var pp [2]_C_int
- err := pipe2(&pp, flags)
- if err == nil {
- p[0] = int(pp[0])
- p[1] = int(pp[1])
- }
- return err
-}
-
-//sys readlinkat(dirfd int, path string, buf []byte) (n int, err error)
-
-func Readlink(path string, buf []byte) (n int, err error) {
- return readlinkat(_AT_FDCWD, path, buf)
-}
-
-func Rename(oldpath string, newpath string) (err error) {
- return Renameat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath)
-}
-
-func Rmdir(path string) error {
- return unlinkat(_AT_FDCWD, path, _AT_REMOVEDIR)
-}
-
-//sys symlinkat(oldpath string, newdirfd int, newpath string) (err error)
-
-func Symlink(oldpath string, newpath string) (err error) {
- return symlinkat(oldpath, _AT_FDCWD, newpath)
-}
-
-func Unlink(path string) error {
- return unlinkat(_AT_FDCWD, path, 0)
-}
-
-//sys unlinkat(dirfd int, path string, flags int) (err error)
-
-func Unlinkat(dirfd int, path string) error {
- return unlinkat(dirfd, path, 0)
-}
-
-func Utimes(path string, tv []Timeval) (err error) {
- if len(tv) != 2 {
- return EINVAL
- }
- return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
-}
-
-//sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
-
-func UtimesNano(path string, ts []Timespec) (err error) {
- if len(ts) != 2 {
- return EINVAL
- }
- return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
-}
-
-func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
- if len(tv) != 2 {
- return EINVAL
- }
- return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
-}
-
-func Futimes(fd int, tv []Timeval) (err error) {
- // Believe it or not, this is the best we can do on Linux
- // (and is what glibc does).
- return Utimes("/proc/self/fd/"+itoa.Itoa(fd), tv)
-}
-
-const ImplementsGetwd = true
-
-//sys Getcwd(buf []byte) (n int, err error)
-
-func Getwd() (wd string, err error) {
- var buf [PathMax]byte
- n, err := Getcwd(buf[0:])
- if err != nil {
- return "", err
- }
- // Getcwd returns the number of bytes written to buf, including the NUL.
- if n < 1 || n > len(buf) || buf[n-1] != 0 {
- return "", EINVAL
- }
- // In some cases, Linux can return a path that starts with the
- // "(unreachable)" prefix, which can potentially be a valid relative
- // path. To work around that, return ENOENT if path is not absolute.
- if buf[0] != '/' {
- return "", ENOENT
- }
-
- return string(buf[0 : n-1]), nil
-}
-
-func Getgroups() (gids []int, err error) {
- n, err := getgroups(0, nil)
- if err != nil {
- return nil, err
- }
- if n == 0 {
- return nil, nil
- }
-
- // Sanity check group count. Max is 1<<16 on Linux.
- if n < 0 || n > 1<<20 {
- return nil, EINVAL
- }
-
- a := make([]_Gid_t, n)
- n, err = getgroups(n, &a[0])
- if err != nil {
- return nil, err
- }
- gids = make([]int, n)
- for i, v := range a[0:n] {
- gids[i] = int(v)
- }
- return
-}
-
-var cgo_libc_setgroups unsafe.Pointer // non-nil if cgo linked.
-
-func Setgroups(gids []int) (err error) {
- n := uintptr(len(gids))
- if n == 0 {
- if cgo_libc_setgroups == nil {
- if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, 0, 0, 0); e1 != 0 {
- err = errnoErr(e1)
- }
- return
- }
- if ret := cgocaller(cgo_libc_setgroups, 0, 0); ret != 0 {
- err = errnoErr(Errno(ret))
- }
- return
- }
-
- a := make([]_Gid_t, len(gids))
- for i, v := range gids {
- a[i] = _Gid_t(v)
- }
- if cgo_libc_setgroups == nil {
- if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, n, uintptr(unsafe.Pointer(&a[0])), 0); e1 != 0 {
- err = errnoErr(e1)
- }
- return
- }
- if ret := cgocaller(cgo_libc_setgroups, n, uintptr(unsafe.Pointer(&a[0]))); ret != 0 {
- err = errnoErr(Errno(ret))
- }
- return
-}
-
-type WaitStatus uint32
-
-// Wait status is 7 bits at bottom, either 0 (exited),
-// 0x7F (stopped), or a signal number that caused an exit.
-// The 0x80 bit is whether there was a core dump.
-// An extra number (exit code, signal causing a stop)
-// is in the high bits. At least that's the idea.
-// There are various irregularities. For example, the
-// "continued" status is 0xFFFF, distinguishing itself
-// from stopped via the core dump bit.
-
-const (
- mask = 0x7F
- core = 0x80
- exited = 0x00
- stopped = 0x7F
- shift = 8
-)
-
-func (w WaitStatus) Exited() bool { return w&mask == exited }
-
-func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
-
-func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
-
-func (w WaitStatus) Continued() bool { return w == 0xFFFF }
-
-func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
-
-func (w WaitStatus) ExitStatus() int {
- if !w.Exited() {
- return -1
- }
- return int(w>>shift) & 0xFF
-}
-
-func (w WaitStatus) Signal() Signal {
- if !w.Signaled() {
- return -1
- }
- return Signal(w & mask)
-}
-
-func (w WaitStatus) StopSignal() Signal {
- if !w.Stopped() {
- return -1
- }
- return Signal(w>>shift) & 0xFF
-}
-
-func (w WaitStatus) TrapCause() int {
- if w.StopSignal() != SIGTRAP {
- return -1
- }
- return int(w>>shift) >> 8
-}
-
-//sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
-
-func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
- var status _C_int
- wpid, err = wait4(pid, &status, options, rusage)
- if wstatus != nil {
- *wstatus = WaitStatus(status)
- }
- return
-}
-
-func Mkfifo(path string, mode uint32) (err error) {
- return Mknod(path, mode|S_IFIFO, 0)
-}
-
-func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
- if sa.Port < 0 || sa.Port > 0xFFFF {
- return nil, 0, EINVAL
- }
- sa.raw.Family = AF_INET
- p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
- p[0] = byte(sa.Port >> 8)
- p[1] = byte(sa.Port)
- sa.raw.Addr = sa.Addr
- return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
-}
-
-func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
- if sa.Port < 0 || sa.Port > 0xFFFF {
- return nil, 0, EINVAL
- }
- sa.raw.Family = AF_INET6
- p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
- p[0] = byte(sa.Port >> 8)
- p[1] = byte(sa.Port)
- sa.raw.Scope_id = sa.ZoneId
- sa.raw.Addr = sa.Addr
- return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
-}
-
-func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
- name := sa.Name
- n := len(name)
- if n > len(sa.raw.Path) {
- return nil, 0, EINVAL
- }
- if n == len(sa.raw.Path) && name[0] != '@' {
- return nil, 0, EINVAL
- }
- sa.raw.Family = AF_UNIX
- for i := 0; i < n; i++ {
- sa.raw.Path[i] = int8(name[i])
- }
- // length is family (uint16), name, NUL.
- sl := _Socklen(2)
- if n > 0 {
- sl += _Socklen(n) + 1
- }
- if sa.raw.Path[0] == '@' {
- sa.raw.Path[0] = 0
- // Don't count trailing NUL for abstract address.
- sl--
- }
-
- return unsafe.Pointer(&sa.raw), sl, nil
-}
-
-type SockaddrLinklayer struct {
- Protocol uint16
- Ifindex int
- Hatype uint16
- Pkttype uint8
- Halen uint8
- Addr [8]byte
- raw RawSockaddrLinklayer
-}
-
-func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
- if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
- return nil, 0, EINVAL
- }
- sa.raw.Family = AF_PACKET
- sa.raw.Protocol = sa.Protocol
- sa.raw.Ifindex = int32(sa.Ifindex)
- sa.raw.Hatype = sa.Hatype
- sa.raw.Pkttype = sa.Pkttype
- sa.raw.Halen = sa.Halen
- sa.raw.Addr = sa.Addr
- return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
-}
-
-type SockaddrNetlink struct {
- Family uint16
- Pad uint16
- Pid uint32
- Groups uint32
- raw RawSockaddrNetlink
-}
-
-func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
- sa.raw.Family = AF_NETLINK
- sa.raw.Pad = sa.Pad
- sa.raw.Pid = sa.Pid
- sa.raw.Groups = sa.Groups
- return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
-}
-
-func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
- switch rsa.Addr.Family {
- case AF_NETLINK:
- pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
- sa := new(SockaddrNetlink)
- sa.Family = pp.Family
- sa.Pad = pp.Pad
- sa.Pid = pp.Pid
- sa.Groups = pp.Groups
- return sa, nil
-
- case AF_PACKET:
- pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
- sa := new(SockaddrLinklayer)
- sa.Protocol = pp.Protocol
- sa.Ifindex = int(pp.Ifindex)
- sa.Hatype = pp.Hatype
- sa.Pkttype = pp.Pkttype
- sa.Halen = pp.Halen
- sa.Addr = pp.Addr
- return sa, nil
-
- case AF_UNIX:
- pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
- sa := new(SockaddrUnix)
- if pp.Path[0] == 0 {
- // "Abstract" Unix domain socket.
- // Rewrite leading NUL as @ for textual display.
- // (This is the standard convention.)
- // Not friendly to overwrite in place,
- // but the callers below don't care.
- pp.Path[0] = '@'
- }
-
- // Assume path ends at NUL.
- // This is not technically the Linux semantics for
- // abstract Unix domain sockets--they are supposed
- // to be uninterpreted fixed-size binary blobs--but
- // everyone uses this convention.
- n := 0
- for n < len(pp.Path) && pp.Path[n] != 0 {
- n++
- }
- bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
- sa.Name = string(bytes)
- return sa, nil
-
- case AF_INET:
- pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
- sa := new(SockaddrInet4)
- p := (*[2]byte)(unsafe.Pointer(&pp.Port))
- sa.Port = int(p[0])<<8 + int(p[1])
- sa.Addr = pp.Addr
- return sa, nil
-
- case AF_INET6:
- pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
- sa := new(SockaddrInet6)
- p := (*[2]byte)(unsafe.Pointer(&pp.Port))
- sa.Port = int(p[0])<<8 + int(p[1])
- sa.ZoneId = pp.Scope_id
- sa.Addr = pp.Addr
- return sa, nil
- }
- return nil, EAFNOSUPPORT
-}
-
-func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
- var rsa RawSockaddrAny
- var len _Socklen = SizeofSockaddrAny
- nfd, err = accept4(fd, &rsa, &len, flags)
- if err != nil {
- return
- }
- if len > SizeofSockaddrAny {
- panic("RawSockaddrAny too small")
- }
- sa, err = anyToSockaddr(&rsa)
- if err != nil {
- Close(nfd)
- nfd = 0
- }
- return
-}
-
-func Getsockname(fd int) (sa Sockaddr, err error) {
- var rsa RawSockaddrAny
- var len _Socklen = SizeofSockaddrAny
- if err = getsockname(fd, &rsa, &len); err != nil {
- return
- }
- return anyToSockaddr(&rsa)
-}
-
-func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
- vallen := _Socklen(4)
- err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
- return value, err
-}
-
-func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
- var value IPMreq
- vallen := _Socklen(SizeofIPMreq)
- err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
- return &value, err
-}
-
-func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
- var value IPMreqn
- vallen := _Socklen(SizeofIPMreqn)
- err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
- return &value, err
-}
-
-func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
- var value IPv6Mreq
- vallen := _Socklen(SizeofIPv6Mreq)
- err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
- return &value, err
-}
-
-func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
- var value IPv6MTUInfo
- vallen := _Socklen(SizeofIPv6MTUInfo)
- err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
- return &value, err
-}
-
-func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
- var value ICMPv6Filter
- vallen := _Socklen(SizeofICMPv6Filter)
- err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
- return &value, err
-}
-
-func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
- var value Ucred
- vallen := _Socklen(SizeofUcred)
- err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
- return &value, err
-}
-
-func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
- return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
-}
-
-func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
- var msg Msghdr
- msg.Name = (*byte)(unsafe.Pointer(rsa))
- msg.Namelen = uint32(SizeofSockaddrAny)
- var iov Iovec
- if len(p) > 0 {
- iov.Base = &p[0]
- iov.SetLen(len(p))
- }
- var dummy byte
- if len(oob) > 0 {
- if len(p) == 0 {
- var sockType int
- sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
- if err != nil {
- return
- }
- // receive at least one normal byte
- if sockType != SOCK_DGRAM {
- iov.Base = &dummy
- iov.SetLen(1)
- }
- }
- msg.Control = &oob[0]
- msg.SetControllen(len(oob))
- }
- msg.Iov = &iov
- msg.Iovlen = 1
- if n, err = recvmsg(fd, &msg, flags); err != nil {
- return
- }
- oobn = int(msg.Controllen)
- recvflags = int(msg.Flags)
- return
-}
-
-func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
- var msg Msghdr
- msg.Name = (*byte)(ptr)
- msg.Namelen = uint32(salen)
- var iov Iovec
- if len(p) > 0 {
- iov.Base = &p[0]
- iov.SetLen(len(p))
- }
- var dummy byte
- if len(oob) > 0 {
- if len(p) == 0 {
- var sockType int
- sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
- if err != nil {
- return 0, err
- }
- // send at least one normal byte
- if sockType != SOCK_DGRAM {
- iov.Base = &dummy
- iov.SetLen(1)
- }
- }
- msg.Control = &oob[0]
- msg.SetControllen(len(oob))
- }
- msg.Iov = &iov
- msg.Iovlen = 1
- if n, err = sendmsg(fd, &msg, flags); err != nil {
- return 0, err
- }
- if len(oob) > 0 && len(p) == 0 {
- n = 0
- }
- return n, nil
-}
-
-// BindToDevice binds the socket associated with fd to device.
-func BindToDevice(fd int, device string) (err error) {
- return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
-}
-
-//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
-
-func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
- // The peek requests are machine-size oriented, so we wrap it
- // to retrieve arbitrary-length data.
-
- // The ptrace syscall differs from glibc's ptrace.
- // Peeks returns the word in *data, not as the return value.
-
- var buf [sizeofPtr]byte
-
- // Leading edge. PEEKTEXT/PEEKDATA don't require aligned
- // access (PEEKUSER warns that it might), but if we don't
- // align our reads, we might straddle an unmapped page
- // boundary and not get the bytes leading up to the page
- // boundary.
- n := 0
- if addr%sizeofPtr != 0 {
- err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
- if err != nil {
- return 0, err
- }
- n += copy(out, buf[addr%sizeofPtr:])
- out = out[n:]
- }
-
- // Remainder.
- for len(out) > 0 {
- // We use an internal buffer to guarantee alignment.
- // It's not documented if this is necessary, but we're paranoid.
- err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
- if err != nil {
- return n, err
- }
- copied := copy(out, buf[0:])
- n += copied
- out = out[copied:]
- }
-
- return n, nil
-}
-
-func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
- return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
-}
-
-func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
- return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
-}
-
-func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
- // As for ptracePeek, we need to align our accesses to deal
- // with the possibility of straddling an invalid page.
-
- // Leading edge.
- n := 0
- if addr%sizeofPtr != 0 {
- var buf [sizeofPtr]byte
- err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
- if err != nil {
- return 0, err
- }
- n += copy(buf[addr%sizeofPtr:], data)
- word := *((*uintptr)(unsafe.Pointer(&buf[0])))
- err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
- if err != nil {
- return 0, err
- }
- data = data[n:]
- }
-
- // Interior.
- for len(data) > sizeofPtr {
- word := *((*uintptr)(unsafe.Pointer(&data[0])))
- err = ptrace(pokeReq, pid, addr+uintptr(n), word)
- if err != nil {
- return n, err
- }
- n += sizeofPtr
- data = data[sizeofPtr:]
- }
-
- // Trailing edge.
- if len(data) > 0 {
- var buf [sizeofPtr]byte
- err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
- if err != nil {
- return n, err
- }
- copy(buf[0:], data)
- word := *((*uintptr)(unsafe.Pointer(&buf[0])))
- err = ptrace(pokeReq, pid, addr+uintptr(n), word)
- if err != nil {
- return n, err
- }
- n += len(data)
- }
-
- return n, nil
-}
-
-func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
- return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
-}
-
-func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
- return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
-}
-
-func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
- return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
-}
-
-func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
- return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
-}
-
-func PtraceSetOptions(pid int, options int) (err error) {
- return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
-}
-
-func PtraceGetEventMsg(pid int) (msg uint, err error) {
- var data _C_long
- err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
- msg = uint(data)
- return
-}
-
-func PtraceCont(pid int, signal int) (err error) {
- return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
-}
-
-func PtraceSyscall(pid int, signal int) (err error) {
- return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
-}
-
-func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
-
-func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
-
-func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
-
-//sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
-
-func Reboot(cmd int) (err error) {
- return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
-}
-
-func ReadDirent(fd int, buf []byte) (n int, err error) {
- return Getdents(fd, buf)
-}
-
-func direntIno(buf []byte) (uint64, bool) {
- return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
-}
-
-func direntReclen(buf []byte) (uint64, bool) {
- return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
-}
-
-func direntNamlen(buf []byte) (uint64, bool) {
- reclen, ok := direntReclen(buf)
- if !ok {
- return 0, false
- }
- return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
-}
-
-//sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
-
-func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
- // Certain file systems get rather angry and EINVAL if you give
- // them an empty string of data, rather than NULL.
- if data == "" {
- return mount(source, target, fstype, flags, nil)
- }
- datap, err := BytePtrFromString(data)
- if err != nil {
- return err
- }
- return mount(source, target, fstype, flags, datap)
-}
-
-// Sendto
-// Recvfrom
-// Socketpair
-
-/*
- * Direct access
- */
-//sys Acct(path string) (err error)
-//sys Adjtimex(buf *Timex) (state int, err error)
-//sys Chdir(path string) (err error)
-//sys Chroot(path string) (err error)
-//sys Close(fd int) (err error)
-//sys Dup(oldfd int) (fd int, err error)
-//sys Dup3(oldfd int, newfd int, flags int) (err error)
-//sysnb EpollCreate1(flag int) (fd int, err error)
-//sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
-//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)
-//sys Fchdir(fd int) (err error)
-//sys Fchmod(fd int, mode uint32) (err error)
-//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
-//sys fcntl(fd int, cmd int, arg int) (val int, err error)
-//sys Fdatasync(fd int) (err error)
-//sys Flock(fd int, how int) (err error)
-//sys Fsync(fd int) (err error)
-//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
-//sysnb Getpgid(pid int) (pgid int, err error)
-
-func Getpgrp() (pid int) {
- pid, _ = Getpgid(0)
- return
-}
-
-//sysnb Getpid() (pid int)
-//sysnb Getppid() (ppid int)
-//sys Getpriority(which int, who int) (prio int, err error)
-//sysnb Getrusage(who int, rusage *Rusage) (err error)
-//sysnb Gettid() (tid int)
-//sys Getxattr(path string, attr string, dest []byte) (sz int, err error)
-//sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
-//sysnb InotifyInit1(flags int) (fd int, err error)
-//sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
-//sysnb Kill(pid int, sig Signal) (err error)
-//sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
-//sys Listxattr(path string, dest []byte) (sz int, err error)
-//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
-//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
-//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
-//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
-//sysnb prlimit1(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
-//sys read(fd int, p []byte) (n int, err error)
-//sys Removexattr(path string, attr string) (err error)
-//sys Setdomainname(p []byte) (err error)
-//sys Sethostname(p []byte) (err error)
-//sysnb Setpgid(pid int, pgid int) (err error)
-//sysnb Setsid() (pid int, err error)
-//sysnb Settimeofday(tv *Timeval) (err error)
-
-// Provided by runtime.syscall_runtime_doAllThreadsSyscall which stops the
-// world and invokes the syscall on each OS thread. Once this function returns,
-// all threads are in sync.
-//
-//go:uintptrescapes
-func runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
-
-// AllThreadsSyscall performs a syscall on each OS thread of the Go
-// runtime. It first invokes the syscall on one thread. Should that
-// invocation fail, it returns immediately with the error status.
-// Otherwise, it invokes the syscall on all of the remaining threads
-// in parallel. It will terminate the program if it observes any
-// invoked syscall's return value differs from that of the first
-// invocation.
-//
-// AllThreadsSyscall is intended for emulating simultaneous
-// process-wide state changes that require consistently modifying
-// per-thread state of the Go runtime.
-//
-// AllThreadsSyscall is unaware of any threads that are launched
-// explicitly by cgo linked code, so the function always returns
-// ENOTSUP in binaries that use cgo.
-//
-//go:uintptrescapes
-func AllThreadsSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
- if cgo_libc_setegid != nil {
- return minus1, minus1, ENOTSUP
- }
- r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, 0, 0, 0)
- return r1, r2, Errno(errno)
-}
-
-// AllThreadsSyscall6 is like AllThreadsSyscall, but extended to six
-// arguments.
-//
-//go:uintptrescapes
-func AllThreadsSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
- if cgo_libc_setegid != nil {
- return minus1, minus1, ENOTSUP
- }
- r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6)
- return r1, r2, Errno(errno)
-}
-
-// linked by runtime.cgocall.go
-//
-//go:uintptrescapes
-func cgocaller(unsafe.Pointer, ...uintptr) uintptr
-
-var cgo_libc_setegid unsafe.Pointer // non-nil if cgo linked.
-
-const minus1 = ^uintptr(0)
-
-func Setegid(egid int) (err error) {
- if cgo_libc_setegid == nil {
- if _, _, e1 := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(egid), minus1); e1 != 0 {
- err = errnoErr(e1)
- }
- } else if ret := cgocaller(cgo_libc_setegid, uintptr(egid)); ret != 0 {
- err = errnoErr(Errno(ret))
- }
- return
-}
-
-var cgo_libc_seteuid unsafe.Pointer // non-nil if cgo linked.
-
-func Seteuid(euid int) (err error) {
- if cgo_libc_seteuid == nil {
- if _, _, e1 := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(euid), minus1); e1 != 0 {
- err = errnoErr(e1)
- }
- } else if ret := cgocaller(cgo_libc_seteuid, uintptr(euid)); ret != 0 {
- err = errnoErr(Errno(ret))
- }
- return
-}
-
-var cgo_libc_setgid unsafe.Pointer // non-nil if cgo linked.
-
-func Setgid(gid int) (err error) {
- if cgo_libc_setgid == nil {
- if _, _, e1 := AllThreadsSyscall(sys_SETGID, uintptr(gid), 0, 0); e1 != 0 {
- err = errnoErr(e1)
- }
- } else if ret := cgocaller(cgo_libc_setgid, uintptr(gid)); ret != 0 {
- err = errnoErr(Errno(ret))
- }
- return
-}
-
-var cgo_libc_setregid unsafe.Pointer // non-nil if cgo linked.
-
-func Setregid(rgid, egid int) (err error) {
- if cgo_libc_setregid == nil {
- if _, _, e1 := AllThreadsSyscall(sys_SETREGID, uintptr(rgid), uintptr(egid), 0); e1 != 0 {
- err = errnoErr(e1)
- }
- } else if ret := cgocaller(cgo_libc_setregid, uintptr(rgid), uintptr(egid)); ret != 0 {
- err = errnoErr(Errno(ret))
- }
- return
-}
-
-var cgo_libc_setresgid unsafe.Pointer // non-nil if cgo linked.
-
-func Setresgid(rgid, egid, sgid int) (err error) {
- if cgo_libc_setresgid == nil {
- if _, _, e1 := AllThreadsSyscall(sys_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)); e1 != 0 {
- err = errnoErr(e1)
- }
- } else if ret := cgocaller(cgo_libc_setresgid, uintptr(rgid), uintptr(egid), uintptr(sgid)); ret != 0 {
- err = errnoErr(Errno(ret))
- }
- return
-}
-
-var cgo_libc_setresuid unsafe.Pointer // non-nil if cgo linked.
-
-func Setresuid(ruid, euid, suid int) (err error) {
- if cgo_libc_setresuid == nil {
- if _, _, e1 := AllThreadsSyscall(sys_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)); e1 != 0 {
- err = errnoErr(e1)
- }
- } else if ret := cgocaller(cgo_libc_setresuid, uintptr(ruid), uintptr(euid), uintptr(suid)); ret != 0 {
- err = errnoErr(Errno(ret))
- }
- return
-}
-
-var cgo_libc_setreuid unsafe.Pointer // non-nil if cgo linked.
-
-func Setreuid(ruid, euid int) (err error) {
- if cgo_libc_setreuid == nil {
- if _, _, e1 := AllThreadsSyscall(sys_SETREUID, uintptr(ruid), uintptr(euid), 0); e1 != 0 {
- err = errnoErr(e1)
- }
- } else if ret := cgocaller(cgo_libc_setreuid, uintptr(ruid), uintptr(euid)); ret != 0 {
- err = errnoErr(Errno(ret))
- }
- return
-}
-
-var cgo_libc_setuid unsafe.Pointer // non-nil if cgo linked.
-
-func Setuid(uid int) (err error) {
- if cgo_libc_setuid == nil {
- if _, _, e1 := AllThreadsSyscall(sys_SETUID, uintptr(uid), 0, 0); e1 != 0 {
- err = errnoErr(e1)
- }
- } else if ret := cgocaller(cgo_libc_setuid, uintptr(uid)); ret != 0 {
- err = errnoErr(Errno(ret))
- }
- return
-}
-
-//sys Setpriority(which int, who int, prio int) (err error)
-//sys Setxattr(path string, attr string, data []byte, flags int) (err error)
-//sys Sync()
-//sysnb Sysinfo(info *Sysinfo_t) (err error)
-//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
-//sysnb Tgkill(tgid int, tid int, sig Signal) (err error)
-//sysnb Times(tms *Tms) (ticks uintptr, err error)
-//sysnb Umask(mask int) (oldmask int)
-//sysnb Uname(buf *Utsname) (err error)
-//sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2
-//sys Unshare(flags int) (err error)
-//sys write(fd int, p []byte) (n int, err error)
-//sys exitThread(code int) (err error) = SYS_EXIT
-//sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
-//sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE
-
-// mmap varies by architecture; see syscall_linux_*.go.
-//sys munmap(addr uintptr, length uintptr) (err error)
-
-var mapper = &mmapper{
- active: make(map[*byte][]byte),
- mmap: mmap,
- munmap: munmap,
-}
-
-func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
- return mapper.Mmap(fd, offset, length, prot, flags)
-}
-
-func Munmap(b []byte) (err error) {
- return mapper.Munmap(b)
-}
-
-//sys Madvise(b []byte, advice int) (err error)
-//sys Mprotect(b []byte, prot int) (err error)
-//sys Mlock(b []byte) (err error)
-//sys Munlock(b []byte) (err error)
-//sys Mlockall(flags int) (err error)
-//sys Munlockall() (err error)
-
-// prlimit changes a resource limit. We use a single definition so that
-// we can tell StartProcess to not restore the original NOFILE limit.
-// This is unexported but can be called from x/sys/unix.
-func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
- err = prlimit1(pid, resource, newlimit, old)
- if err == nil && newlimit != nil && resource == RLIMIT_NOFILE {
- origRlimitNofile.Store(Rlimit{0, 0})
- }
- return err
-}
diff --git a/contrib/go/_std_1.20/src/syscall/syscall_unix.go b/contrib/go/_std_1.20/src/syscall/syscall_unix.go
deleted file mode 100644
index c59d4fcf95..0000000000
--- a/contrib/go/_std_1.20/src/syscall/syscall_unix.go
+++ /dev/null
@@ -1,519 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix
-
-package syscall
-
-import (
- "internal/bytealg"
- "internal/itoa"
- "internal/oserror"
- "internal/race"
- "runtime"
- "sync"
- "unsafe"
-)
-
-var (
- Stdin = 0
- Stdout = 1
- Stderr = 2
-)
-
-const (
- darwin64Bit = (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && sizeofPtr == 8
- netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
-)
-
-// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
-func clen(n []byte) int {
- if i := bytealg.IndexByte(n, 0); i != -1 {
- return i
- }
- return len(n)
-}
-
-// Mmap manager, for use by operating system-specific implementations.
-
-type mmapper struct {
- sync.Mutex
- active map[*byte][]byte // active mappings; key is last byte in mapping
- mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
- munmap func(addr uintptr, length uintptr) error
-}
-
-func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
- if length <= 0 {
- return nil, EINVAL
- }
-
- // Map the requested memory.
- addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
- if errno != nil {
- return nil, errno
- }
-
- // Use unsafe to turn addr into a []byte.
- b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
-
- // Register mapping in m and return it.
- p := &b[cap(b)-1]
- m.Lock()
- defer m.Unlock()
- m.active[p] = b
- return b, nil
-}
-
-func (m *mmapper) Munmap(data []byte) (err error) {
- if len(data) == 0 || len(data) != cap(data) {
- return EINVAL
- }
-
- // Find the base of the mapping.
- p := &data[cap(data)-1]
- m.Lock()
- defer m.Unlock()
- b := m.active[p]
- if b == nil || &b[0] != &data[0] {
- return EINVAL
- }
-
- // Unmap the memory and update m.
- if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
- return errno
- }
- delete(m.active, p)
- return nil
-}
-
-// An Errno is an unsigned number describing an error condition.
-// It implements the error interface. The zero Errno is by convention
-// a non-error, so code to convert from Errno to error should use:
-//
-// err = nil
-// if errno != 0 {
-// err = errno
-// }
-//
-// Errno values can be tested against error values from the os package
-// using errors.Is. For example:
-//
-// _, _, err := syscall.Syscall(...)
-// if errors.Is(err, fs.ErrNotExist) ...
-type Errno uintptr
-
-func (e Errno) Error() string {
- if 0 <= int(e) && int(e) < len(errors) {
- s := errors[e]
- if s != "" {
- return s
- }
- }
- return "errno " + itoa.Itoa(int(e))
-}
-
-func (e Errno) Is(target error) bool {
- switch target {
- case oserror.ErrPermission:
- return e == EACCES || e == EPERM
- case oserror.ErrExist:
- return e == EEXIST || e == ENOTEMPTY
- case oserror.ErrNotExist:
- return e == ENOENT
- }
- return false
-}
-
-func (e Errno) Temporary() bool {
- return e == EINTR || e == EMFILE || e == ENFILE || e.Timeout()
-}
-
-func (e Errno) Timeout() bool {
- return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
-}
-
-// Do the interface allocations only once for common
-// Errno values.
-var (
- errEAGAIN error = EAGAIN
- errEINVAL error = EINVAL
- errENOENT error = ENOENT
-)
-
-// errnoErr returns common boxed Errno values, to prevent
-// allocations at runtime.
-func errnoErr(e Errno) error {
- switch e {
- case 0:
- return nil
- case EAGAIN:
- return errEAGAIN
- case EINVAL:
- return errEINVAL
- case ENOENT:
- return errENOENT
- }
- return e
-}
-
-// A Signal is a number describing a process signal.
-// It implements the os.Signal interface.
-type Signal int
-
-func (s Signal) Signal() {}
-
-func (s Signal) String() string {
- if 0 <= s && int(s) < len(signals) {
- str := signals[s]
- if str != "" {
- return str
- }
- }
- return "signal " + itoa.Itoa(int(s))
-}
-
-func Read(fd int, p []byte) (n int, err error) {
- n, err = read(fd, p)
- if race.Enabled {
- if n > 0 {
- race.WriteRange(unsafe.Pointer(&p[0]), n)
- }
- if err == nil {
- race.Acquire(unsafe.Pointer(&ioSync))
- }
- }
- if msanenabled && n > 0 {
- msanWrite(unsafe.Pointer(&p[0]), n)
- }
- if asanenabled && n > 0 {
- asanWrite(unsafe.Pointer(&p[0]), n)
- }
- return
-}
-
-func Write(fd int, p []byte) (n int, err error) {
- if race.Enabled {
- race.ReleaseMerge(unsafe.Pointer(&ioSync))
- }
- if faketime && (fd == 1 || fd == 2) {
- n = faketimeWrite(fd, p)
- if n < 0 {
- n, err = 0, errnoErr(Errno(-n))
- }
- } else {
- n, err = write(fd, p)
- }
- if race.Enabled && n > 0 {
- race.ReadRange(unsafe.Pointer(&p[0]), n)
- }
- if msanenabled && n > 0 {
- msanRead(unsafe.Pointer(&p[0]), n)
- }
- if asanenabled && n > 0 {
- asanRead(unsafe.Pointer(&p[0]), n)
- }
- return
-}
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
- n, err = pread(fd, p, offset)
- if race.Enabled {
- if n > 0 {
- race.WriteRange(unsafe.Pointer(&p[0]), n)
- }
- if err == nil {
- race.Acquire(unsafe.Pointer(&ioSync))
- }
- }
- if msanenabled && n > 0 {
- msanWrite(unsafe.Pointer(&p[0]), n)
- }
- if asanenabled && n > 0 {
- asanWrite(unsafe.Pointer(&p[0]), n)
- }
- return
-}
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
- if race.Enabled {
- race.ReleaseMerge(unsafe.Pointer(&ioSync))
- }
- n, err = pwrite(fd, p, offset)
- if race.Enabled && n > 0 {
- race.ReadRange(unsafe.Pointer(&p[0]), n)
- }
- if msanenabled && n > 0 {
- msanRead(unsafe.Pointer(&p[0]), n)
- }
- if asanenabled && n > 0 {
- asanRead(unsafe.Pointer(&p[0]), n)
- }
- return
-}
-
-// For testing: clients can set this flag to force
-// creation of IPv6 sockets to return EAFNOSUPPORT.
-var SocketDisableIPv6 bool
-
-type Sockaddr interface {
- sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
-}
-
-type SockaddrInet4 struct {
- Port int
- Addr [4]byte
- raw RawSockaddrInet4
-}
-
-type SockaddrInet6 struct {
- Port int
- ZoneId uint32
- Addr [16]byte
- raw RawSockaddrInet6
-}
-
-type SockaddrUnix struct {
- Name string
- raw RawSockaddrUnix
-}
-
-func Bind(fd int, sa Sockaddr) (err error) {
- ptr, n, err := sa.sockaddr()
- if err != nil {
- return err
- }
- return bind(fd, ptr, n)
-}
-
-func Connect(fd int, sa Sockaddr) (err error) {
- ptr, n, err := sa.sockaddr()
- if err != nil {
- return err
- }
- return connect(fd, ptr, n)
-}
-
-func Getpeername(fd int) (sa Sockaddr, err error) {
- var rsa RawSockaddrAny
- var len _Socklen = SizeofSockaddrAny
- if err = getpeername(fd, &rsa, &len); err != nil {
- return
- }
- return anyToSockaddr(&rsa)
-}
-
-func GetsockoptInt(fd, level, opt int) (value int, err error) {
- var n int32
- vallen := _Socklen(4)
- err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
- return int(n), err
-}
-
-func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
- var rsa RawSockaddrAny
- var len _Socklen = SizeofSockaddrAny
- if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
- return
- }
- if rsa.Addr.Family != AF_UNSPEC {
- from, err = anyToSockaddr(&rsa)
- }
- return
-}
-
-func recvfromInet4(fd int, p []byte, flags int, from *SockaddrInet4) (n int, err error) {
- var rsa RawSockaddrAny
- var socklen _Socklen = SizeofSockaddrAny
- if n, err = recvfrom(fd, p, flags, &rsa, &socklen); err != nil {
- return
- }
- pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
- port := (*[2]byte)(unsafe.Pointer(&pp.Port))
- from.Port = int(port[0])<<8 + int(port[1])
- from.Addr = pp.Addr
- return
-}
-
-func recvfromInet6(fd int, p []byte, flags int, from *SockaddrInet6) (n int, err error) {
- var rsa RawSockaddrAny
- var socklen _Socklen = SizeofSockaddrAny
- if n, err = recvfrom(fd, p, flags, &rsa, &socklen); err != nil {
- return
- }
- pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa))
- port := (*[2]byte)(unsafe.Pointer(&pp.Port))
- from.Port = int(port[0])<<8 + int(port[1])
- from.ZoneId = pp.Scope_id
- from.Addr = pp.Addr
- return
-}
-
-func recvmsgInet4(fd int, p, oob []byte, flags int, from *SockaddrInet4) (n, oobn int, recvflags int, err error) {
- var rsa RawSockaddrAny
- n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
- if err != nil {
- return
- }
- pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
- port := (*[2]byte)(unsafe.Pointer(&pp.Port))
- from.Port = int(port[0])<<8 + int(port[1])
- from.Addr = pp.Addr
- return
-}
-
-func recvmsgInet6(fd int, p, oob []byte, flags int, from *SockaddrInet6) (n, oobn int, recvflags int, err error) {
- var rsa RawSockaddrAny
- n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
- if err != nil {
- return
- }
- pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa))
- port := (*[2]byte)(unsafe.Pointer(&pp.Port))
- from.Port = int(port[0])<<8 + int(port[1])
- from.ZoneId = pp.Scope_id
- from.Addr = pp.Addr
- return
-}
-
-func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
- var rsa RawSockaddrAny
- n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
- // source address is only specified if the socket is unconnected
- if rsa.Addr.Family != AF_UNSPEC {
- from, err = anyToSockaddr(&rsa)
- }
- return
-}
-
-func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
- _, err = SendmsgN(fd, p, oob, to, flags)
- return
-}
-
-func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
- var ptr unsafe.Pointer
- var salen _Socklen
- if to != nil {
- ptr, salen, err = to.sockaddr()
- if err != nil {
- return 0, err
- }
- }
- return sendmsgN(fd, p, oob, ptr, salen, flags)
-}
-
-func sendmsgNInet4(fd int, p, oob []byte, to *SockaddrInet4, flags int) (n int, err error) {
- ptr, salen, err := to.sockaddr()
- if err != nil {
- return 0, err
- }
- return sendmsgN(fd, p, oob, ptr, salen, flags)
-}
-
-func sendmsgNInet6(fd int, p, oob []byte, to *SockaddrInet6, flags int) (n int, err error) {
- ptr, salen, err := to.sockaddr()
- if err != nil {
- return 0, err
- }
- return sendmsgN(fd, p, oob, ptr, salen, flags)
-}
-
-func sendtoInet4(fd int, p []byte, flags int, to *SockaddrInet4) (err error) {
- ptr, n, err := to.sockaddr()
- if err != nil {
- return err
- }
- return sendto(fd, p, flags, ptr, n)
-}
-
-func sendtoInet6(fd int, p []byte, flags int, to *SockaddrInet6) (err error) {
- ptr, n, err := to.sockaddr()
- if err != nil {
- return err
- }
- return sendto(fd, p, flags, ptr, n)
-}
-
-func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
- var (
- ptr unsafe.Pointer
- salen _Socklen
- )
- if to != nil {
- ptr, salen, err = to.sockaddr()
- if err != nil {
- return err
- }
- }
- return sendto(fd, p, flags, ptr, salen)
-}
-
-func SetsockoptByte(fd, level, opt int, value byte) (err error) {
- return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
-}
-
-func SetsockoptInt(fd, level, opt int, value int) (err error) {
- var n = int32(value)
- return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
-}
-
-func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
- return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
-}
-
-func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
- return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
-}
-
-func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
- return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
-}
-
-func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
- return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
-}
-
-func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
- return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
-}
-
-func SetsockoptString(fd, level, opt int, s string) (err error) {
- var p unsafe.Pointer
- if len(s) > 0 {
- p = unsafe.Pointer(&[]byte(s)[0])
- }
- return setsockopt(fd, level, opt, p, uintptr(len(s)))
-}
-
-func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
- return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
-}
-
-func Socket(domain, typ, proto int) (fd int, err error) {
- if domain == AF_INET6 && SocketDisableIPv6 {
- return -1, EAFNOSUPPORT
- }
- fd, err = socket(domain, typ, proto)
- return
-}
-
-func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
- var fdx [2]int32
- err = socketpair(domain, typ, proto, &fdx)
- if err == nil {
- fd[0] = int(fdx[0])
- fd[1] = int(fdx[1])
- }
- return
-}
-
-func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
- if race.Enabled {
- race.ReleaseMerge(unsafe.Pointer(&ioSync))
- }
- return sendfile(outfd, infd, offset, count)
-}
-
-var ioSync int64
diff --git a/contrib/go/_std_1.20/src/syscall/syscall_windows.go b/contrib/go/_std_1.20/src/syscall/syscall_windows.go
deleted file mode 100644
index 4fbcdcd3ff..0000000000
--- a/contrib/go/_std_1.20/src/syscall/syscall_windows.go
+++ /dev/null
@@ -1,1347 +0,0 @@
-// Copyright 2009 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.
-
-// Windows system calls.
-
-package syscall
-
-import (
- errorspkg "errors"
- "internal/bytealg"
- "internal/itoa"
- "internal/oserror"
- "internal/race"
- "runtime"
- "sync"
- "unicode/utf16"
- "unsafe"
-)
-
-type Handle uintptr
-
-const InvalidHandle = ^Handle(0)
-
-// StringToUTF16 returns the UTF-16 encoding of the UTF-8 string s,
-// with a terminating NUL added. If s contains a NUL byte this
-// function panics instead of returning an error.
-//
-// Deprecated: Use UTF16FromString instead.
-func StringToUTF16(s string) []uint16 {
- a, err := UTF16FromString(s)
- if err != nil {
- panic("syscall: string with NUL passed to StringToUTF16")
- }
- return a
-}
-
-// UTF16FromString returns the UTF-16 encoding of the UTF-8 string
-// s, with a terminating NUL added. If s contains a NUL byte at any
-// location, it returns (nil, EINVAL).
-func UTF16FromString(s string) ([]uint16, error) {
- if bytealg.IndexByteString(s, 0) != -1 {
- return nil, EINVAL
- }
- // In the worst case all characters require two uint16.
- // Also account for the terminating NULL character.
- buf := make([]uint16, 0, len(s)*2+1)
- for _, r := range s {
- buf = utf16.AppendRune(buf, r)
- }
- return utf16.AppendRune(buf, '\x00'), nil
-}
-
-// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s,
-// with a terminating NUL removed.
-func UTF16ToString(s []uint16) string {
- for i, v := range s {
- if v == 0 {
- s = s[0:i]
- break
- }
- }
- return string(utf16.Decode(s))
-}
-
-// utf16PtrToString is like UTF16ToString, but takes *uint16
-// as a parameter instead of []uint16.
-func utf16PtrToString(p *uint16) string {
- if p == nil {
- return ""
- }
- // Find NUL terminator.
- end := unsafe.Pointer(p)
- n := 0
- for *(*uint16)(end) != 0 {
- end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p))
- n++
- }
- // Turn *uint16 into []uint16.
- s := unsafe.Slice(p, n)
- // Decode []uint16 into string.
- return string(utf16.Decode(s))
-}
-
-// StringToUTF16Ptr returns pointer to the UTF-16 encoding of
-// the UTF-8 string s, with a terminating NUL added. If s
-// contains a NUL byte this function panics instead of
-// returning an error.
-//
-// Deprecated: Use UTF16PtrFromString instead.
-func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] }
-
-// UTF16PtrFromString returns pointer to the UTF-16 encoding of
-// the UTF-8 string s, with a terminating NUL added. If s
-// contains a NUL byte at any location, it returns (nil, EINVAL).
-func UTF16PtrFromString(s string) (*uint16, error) {
- a, err := UTF16FromString(s)
- if err != nil {
- return nil, err
- }
- return &a[0], nil
-}
-
-// Errno is the Windows error number.
-//
-// Errno values can be tested against error values from the os package
-// using errors.Is. For example:
-//
-// _, _, err := syscall.Syscall(...)
-// if errors.Is(err, fs.ErrNotExist) ...
-type Errno uintptr
-
-func langid(pri, sub uint16) uint32 { return uint32(sub)<<10 | uint32(pri) }
-
-// FormatMessage is deprecated (msgsrc should be uintptr, not uint32, but can
-// not be changed due to the Go 1 compatibility guarantee).
-//
-// Deprecated: Use FormatMessage from golang.org/x/sys/windows instead.
-func FormatMessage(flags uint32, msgsrc uint32, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) {
- return formatMessage(flags, uintptr(msgsrc), msgid, langid, buf, args)
-}
-
-func (e Errno) Error() string {
- // deal with special go errors
- idx := int(e - APPLICATION_ERROR)
- if 0 <= idx && idx < len(errors) {
- return errors[idx]
- }
- // ask windows for the remaining errors
- var flags uint32 = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_IGNORE_INSERTS
- b := make([]uint16, 300)
- n, err := formatMessage(flags, 0, uint32(e), langid(LANG_ENGLISH, SUBLANG_ENGLISH_US), b, nil)
- if err != nil {
- n, err = formatMessage(flags, 0, uint32(e), 0, b, nil)
- if err != nil {
- return "winapi error #" + itoa.Itoa(int(e))
- }
- }
- // trim terminating \r and \n
- for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- {
- }
- return string(utf16.Decode(b[:n]))
-}
-
-const _ERROR_BAD_NETPATH = Errno(53)
-
-func (e Errno) Is(target error) bool {
- switch target {
- case oserror.ErrPermission:
- return e == ERROR_ACCESS_DENIED
- case oserror.ErrExist:
- return e == ERROR_ALREADY_EXISTS ||
- e == ERROR_DIR_NOT_EMPTY ||
- e == ERROR_FILE_EXISTS
- case oserror.ErrNotExist:
- return e == ERROR_FILE_NOT_FOUND ||
- e == _ERROR_BAD_NETPATH ||
- e == ERROR_PATH_NOT_FOUND
- }
- return false
-}
-
-func (e Errno) Temporary() bool {
- return e == EINTR || e == EMFILE || e.Timeout()
-}
-
-func (e Errno) Timeout() bool {
- return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
-}
-
-// Implemented in runtime/syscall_windows.go.
-func compileCallback(fn any, cleanstack bool) uintptr
-
-// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention.
-// This is useful when interoperating with Windows code requiring callbacks.
-// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
-// Only a limited number of callbacks may be created in a single Go process, and any memory allocated
-// for these callbacks is never released.
-// Between NewCallback and NewCallbackCDecl, at least 1024 callbacks can always be created.
-func NewCallback(fn any) uintptr {
- return compileCallback(fn, true)
-}
-
-// NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention.
-// This is useful when interoperating with Windows code requiring callbacks.
-// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
-// Only a limited number of callbacks may be created in a single Go process, and any memory allocated
-// for these callbacks is never released.
-// Between NewCallback and NewCallbackCDecl, at least 1024 callbacks can always be created.
-func NewCallbackCDecl(fn any) uintptr {
- return compileCallback(fn, false)
-}
-
-// windows api calls
-
-//sys GetLastError() (lasterr error)
-//sys LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW
-//sys FreeLibrary(handle Handle) (err error)
-//sys GetProcAddress(module Handle, procname string) (proc uintptr, err error)
-//sys GetVersion() (ver uint32, err error)
-//sys rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) = ntdll.RtlGetNtVersionNumbers
-//sys formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
-//sys ExitProcess(exitcode uint32)
-//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
-//sys readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = ReadFile
-//sys writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = WriteFile
-//sys SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff]
-//sys CloseHandle(handle Handle) (err error)
-//sys GetStdHandle(stdhandle int) (handle Handle, err error) [failretval==InvalidHandle]
-//sys findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW
-//sys findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW
-//sys FindClose(handle Handle) (err error)
-//sys GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error)
-//sys GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW
-//sys SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW
-//sys CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW
-//sys RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW
-//sys DeleteFile(path *uint16) (err error) = DeleteFileW
-//sys MoveFile(from *uint16, to *uint16) (err error) = MoveFileW
-//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
-//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 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
-//sys CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = advapi32.CreateProcessAsUserW
-//sys OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error)
-//sys TerminateProcess(handle Handle, exitcode uint32) (err error)
-//sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
-//sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW
-//sys GetCurrentProcess() (pseudoHandle Handle, err error)
-//sys GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error)
-//sys DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error)
-//sys WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff]
-//sys GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW
-//sys CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error)
-//sys GetFileType(filehandle Handle) (n uint32, err error)
-//sys CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW
-//sys CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext
-//sys CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom
-//sys GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW
-//sys FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW
-//sys GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW
-//sys SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW
-//sys SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
-//sys GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW
-//sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW
-//sys GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW
-//sys GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW
-//sys CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW
-//sys LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0]
-//sys SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error)
-//sys FlushFileBuffers(handle Handle) (err error)
-//sys GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW
-//sys GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW
-//sys GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW
-//sys CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW
-//sys MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error)
-//sys UnmapViewOfFile(addr uintptr) (err error)
-//sys FlushViewOfFile(addr uintptr, length uintptr) (err error)
-//sys VirtualLock(addr uintptr, length uintptr) (err error)
-//sys VirtualUnlock(addr uintptr, length uintptr) (err error)
-//sys TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile
-//sys ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW
-//sys CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW
-//sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) = crypt32.CertOpenStore
-//sys CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore
-//sys CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore
-//sys CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore
-//sys CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain
-//sys CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain
-//sys CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext
-//sys CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext
-//sys CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy
-//sys RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW
-//sys RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey
-//sys RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW
-//sys regEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW
-//sys RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW
-//sys getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId
-//sys GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode
-//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
-//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
-//sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot
-//sys Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW
-//sys Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW
-//sys DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error)
-// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
-//sys CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW
-//sys CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW
-//sys initializeProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, attrcount uint32, flags uint32, size *uintptr) (err error) = InitializeProcThreadAttributeList
-//sys deleteProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST) = DeleteProcThreadAttributeList
-//sys updateProcThreadAttribute(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) = UpdateProcThreadAttribute
-
-// syscall interface implementation for other packages
-
-func makeInheritSa() *SecurityAttributes {
- var sa SecurityAttributes
- sa.Length = uint32(unsafe.Sizeof(sa))
- sa.InheritHandle = 1
- return &sa
-}
-
-func Open(path string, mode int, perm uint32) (fd Handle, err error) {
- if len(path) == 0 {
- return InvalidHandle, ERROR_FILE_NOT_FOUND
- }
- pathp, err := UTF16PtrFromString(path)
- if err != nil {
- return InvalidHandle, err
- }
- var access uint32
- switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
- case O_RDONLY:
- access = GENERIC_READ
- case O_WRONLY:
- access = GENERIC_WRITE
- case O_RDWR:
- access = GENERIC_READ | GENERIC_WRITE
- }
- if mode&O_CREAT != 0 {
- access |= GENERIC_WRITE
- }
- if mode&O_APPEND != 0 {
- access &^= GENERIC_WRITE
- access |= FILE_APPEND_DATA
- }
- sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE)
- var sa *SecurityAttributes
- if mode&O_CLOEXEC == 0 {
- sa = makeInheritSa()
- }
- var createmode uint32
- switch {
- case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
- createmode = CREATE_NEW
- case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
- createmode = CREATE_ALWAYS
- case mode&O_CREAT == O_CREAT:
- createmode = OPEN_ALWAYS
- case mode&O_TRUNC == O_TRUNC:
- createmode = TRUNCATE_EXISTING
- default:
- createmode = OPEN_EXISTING
- }
- var attrs uint32 = FILE_ATTRIBUTE_NORMAL
- if perm&S_IWRITE == 0 {
- attrs = FILE_ATTRIBUTE_READONLY
- if createmode == CREATE_ALWAYS {
- // We have been asked to create a read-only file.
- // If the file already exists, the semantics of
- // the Unix open system call is to preserve the
- // existing permissions. If we pass CREATE_ALWAYS
- // and FILE_ATTRIBUTE_READONLY to CreateFile,
- // and the file already exists, CreateFile will
- // change the file permissions.
- // Avoid that to preserve the Unix semantics.
- h, e := CreateFile(pathp, access, sharemode, sa, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
- switch e {
- case ERROR_FILE_NOT_FOUND, _ERROR_BAD_NETPATH, ERROR_PATH_NOT_FOUND:
- // File does not exist. These are the same
- // errors as Errno.Is checks for ErrNotExist.
- // Carry on to create the file.
- default:
- // Success or some different error.
- return h, e
- }
- }
- }
- if createmode == OPEN_EXISTING && access == GENERIC_READ {
- // Necessary for opening directory handles.
- attrs |= FILE_FLAG_BACKUP_SEMANTICS
- }
- return CreateFile(pathp, access, sharemode, sa, createmode, attrs, 0)
-}
-
-func Read(fd Handle, p []byte) (n int, err error) {
- var done uint32
- e := ReadFile(fd, p, &done, nil)
- if e != nil {
- if e == ERROR_BROKEN_PIPE {
- // NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin
- return 0, nil
- }
- return 0, e
- }
- return int(done), nil
-}
-
-func Write(fd Handle, p []byte) (n int, err error) {
- var done uint32
- e := WriteFile(fd, p, &done, nil)
- if e != nil {
- return 0, e
- }
- return int(done), nil
-}
-
-func ReadFile(fd Handle, p []byte, done *uint32, overlapped *Overlapped) error {
- err := readFile(fd, p, done, overlapped)
- if race.Enabled {
- if *done > 0 {
- race.WriteRange(unsafe.Pointer(&p[0]), int(*done))
- }
- race.Acquire(unsafe.Pointer(&ioSync))
- }
- if msanenabled && *done > 0 {
- msanWrite(unsafe.Pointer(&p[0]), int(*done))
- }
- if asanenabled && *done > 0 {
- asanWrite(unsafe.Pointer(&p[0]), int(*done))
- }
- return err
-}
-
-func WriteFile(fd Handle, p []byte, done *uint32, overlapped *Overlapped) error {
- if race.Enabled {
- race.ReleaseMerge(unsafe.Pointer(&ioSync))
- }
- err := writeFile(fd, p, done, overlapped)
- if race.Enabled && *done > 0 {
- race.ReadRange(unsafe.Pointer(&p[0]), int(*done))
- }
- if msanenabled && *done > 0 {
- msanRead(unsafe.Pointer(&p[0]), int(*done))
- }
- if asanenabled && *done > 0 {
- asanRead(unsafe.Pointer(&p[0]), int(*done))
- }
- return err
-}
-
-var ioSync int64
-
-var procSetFilePointerEx = modkernel32.NewProc("SetFilePointerEx")
-
-const ptrSize = unsafe.Sizeof(uintptr(0))
-
-// setFilePointerEx calls SetFilePointerEx.
-// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365542(v=vs.85).aspx
-func setFilePointerEx(handle Handle, distToMove int64, newFilePointer *int64, whence uint32) error {
- var e1 Errno
- if unsafe.Sizeof(uintptr(0)) == 8 {
- _, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 4, uintptr(handle), uintptr(distToMove), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0, 0)
- } else {
- // Different 32-bit systems disgaree about whether distToMove starts 8-byte aligned.
- switch runtime.GOARCH {
- default:
- panic("unsupported 32-bit architecture")
- case "386":
- // distToMove is a LARGE_INTEGER, which is 64 bits.
- _, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 5, uintptr(handle), uintptr(distToMove), uintptr(distToMove>>32), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0)
- case "arm":
- // distToMove must be 8-byte aligned per ARM calling convention
- // https://docs.microsoft.com/en-us/cpp/build/overview-of-arm-abi-conventions#stage-c-assignment-of-arguments-to-registers-and-stack
- _, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 6, uintptr(handle), 0, uintptr(distToMove), uintptr(distToMove>>32), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence))
- }
- }
- if e1 != 0 {
- return errnoErr(e1)
- }
- return nil
-}
-
-func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
- var w uint32
- switch whence {
- case 0:
- w = FILE_BEGIN
- case 1:
- w = FILE_CURRENT
- case 2:
- w = FILE_END
- }
- // use GetFileType to check pipe, pipe can't do seek
- ft, _ := GetFileType(fd)
- if ft == FILE_TYPE_PIPE {
- return 0, ESPIPE
- }
- err = setFilePointerEx(fd, offset, &newoffset, w)
- return
-}
-
-func Close(fd Handle) (err error) {
- return CloseHandle(fd)
-}
-
-var (
- Stdin = getStdHandle(STD_INPUT_HANDLE)
- Stdout = getStdHandle(STD_OUTPUT_HANDLE)
- Stderr = getStdHandle(STD_ERROR_HANDLE)
-)
-
-func getStdHandle(h int) (fd Handle) {
- r, _ := GetStdHandle(h)
- return r
-}
-
-const ImplementsGetwd = true
-
-func Getwd() (wd string, err error) {
- b := make([]uint16, 300)
- n, e := GetCurrentDirectory(uint32(len(b)), &b[0])
- if e != nil {
- return "", e
- }
- return string(utf16.Decode(b[0:n])), nil
-}
-
-func Chdir(path string) (err error) {
- pathp, err := UTF16PtrFromString(path)
- if err != nil {
- return err
- }
- return SetCurrentDirectory(pathp)
-}
-
-func Mkdir(path string, mode uint32) (err error) {
- pathp, err := UTF16PtrFromString(path)
- if err != nil {
- return err
- }
- return CreateDirectory(pathp, nil)
-}
-
-func Rmdir(path string) (err error) {
- pathp, err := UTF16PtrFromString(path)
- if err != nil {
- return err
- }
- return RemoveDirectory(pathp)
-}
-
-func Unlink(path string) (err error) {
- pathp, err := UTF16PtrFromString(path)
- if err != nil {
- return err
- }
- return DeleteFile(pathp)
-}
-
-func Rename(oldpath, newpath string) (err error) {
- from, err := UTF16PtrFromString(oldpath)
- if err != nil {
- return err
- }
- to, err := UTF16PtrFromString(newpath)
- if err != nil {
- return err
- }
- return MoveFile(from, to)
-}
-
-func ComputerName() (name string, err error) {
- var n uint32 = MAX_COMPUTERNAME_LENGTH + 1
- b := make([]uint16, n)
- e := GetComputerName(&b[0], &n)
- if e != nil {
- return "", e
- }
- return string(utf16.Decode(b[0:n])), nil
-}
-
-func Ftruncate(fd Handle, length int64) (err error) {
- curoffset, e := Seek(fd, 0, 1)
- if e != nil {
- return e
- }
- defer Seek(fd, curoffset, 0)
- _, e = Seek(fd, length, 0)
- if e != nil {
- return e
- }
- e = SetEndOfFile(fd)
- if e != nil {
- return e
- }
- return nil
-}
-
-func Gettimeofday(tv *Timeval) (err error) {
- var ft Filetime
- GetSystemTimeAsFileTime(&ft)
- *tv = NsecToTimeval(ft.Nanoseconds())
- return nil
-}
-
-func Pipe(p []Handle) (err error) {
- if len(p) != 2 {
- return EINVAL
- }
- var r, w Handle
- e := CreatePipe(&r, &w, makeInheritSa(), 0)
- if e != nil {
- return e
- }
- p[0] = r
- p[1] = w
- return nil
-}
-
-func Utimes(path string, tv []Timeval) (err error) {
- if len(tv) != 2 {
- return EINVAL
- }
- pathp, e := UTF16PtrFromString(path)
- if e != nil {
- return e
- }
- h, e := CreateFile(pathp,
- FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
- OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
- if e != nil {
- return e
- }
- defer Close(h)
- a := NsecToFiletime(tv[0].Nanoseconds())
- w := NsecToFiletime(tv[1].Nanoseconds())
- return SetFileTime(h, nil, &a, &w)
-}
-
-func UtimesNano(path string, ts []Timespec) (err error) {
- if len(ts) != 2 {
- return EINVAL
- }
- pathp, e := UTF16PtrFromString(path)
- if e != nil {
- return e
- }
- h, e := CreateFile(pathp,
- FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
- OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
- if e != nil {
- return e
- }
- defer Close(h)
- a := NsecToFiletime(TimespecToNsec(ts[0]))
- w := NsecToFiletime(TimespecToNsec(ts[1]))
- return SetFileTime(h, nil, &a, &w)
-}
-
-func Fsync(fd Handle) (err error) {
- return FlushFileBuffers(fd)
-}
-
-func Chmod(path string, mode uint32) (err error) {
- p, e := UTF16PtrFromString(path)
- if e != nil {
- return e
- }
- attrs, e := GetFileAttributes(p)
- if e != nil {
- return e
- }
- if mode&S_IWRITE != 0 {
- attrs &^= FILE_ATTRIBUTE_READONLY
- } else {
- attrs |= FILE_ATTRIBUTE_READONLY
- }
- return SetFileAttributes(p, attrs)
-}
-
-func LoadCancelIoEx() error {
- return procCancelIoEx.Find()
-}
-
-func LoadSetFileCompletionNotificationModes() error {
- return procSetFileCompletionNotificationModes.Find()
-}
-
-// net api calls
-
-const socket_error = uintptr(^uint32(0))
-
-//sys WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup
-//sys WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup
-//sys WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==socket_error] = ws2_32.WSAIoctl
-//sys socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket
-//sys Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt
-//sys Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt
-//sys bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind
-//sys connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect
-//sys getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname
-//sys getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername
-//sys listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen
-//sys shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown
-//sys Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket
-//sys AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx
-//sys GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs
-//sys WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv
-//sys WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend
-//sys WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom
-//sys WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo
-//sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname
-//sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname
-//sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
-//sys GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname
-//sys DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W
-//sys DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree
-//sys DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W
-//sys GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW
-//sys FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW
-//sys GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry
-//sys GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo
-//sys SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes
-//sys WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW
-
-// For testing: clients can set this flag to force
-// creation of IPv6 sockets to return EAFNOSUPPORT.
-var SocketDisableIPv6 bool
-
-type RawSockaddrInet4 struct {
- Family uint16
- Port uint16
- Addr [4]byte /* in_addr */
- Zero [8]uint8
-}
-
-type RawSockaddrInet6 struct {
- Family uint16
- Port uint16
- Flowinfo uint32
- Addr [16]byte /* in6_addr */
- Scope_id uint32
-}
-
-type RawSockaddr struct {
- Family uint16
- Data [14]int8
-}
-
-type RawSockaddrAny struct {
- Addr RawSockaddr
- Pad [100]int8
-}
-
-type Sockaddr interface {
- sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs
-}
-
-type SockaddrInet4 struct {
- Port int
- Addr [4]byte
- raw RawSockaddrInet4
-}
-
-func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) {
- if sa.Port < 0 || sa.Port > 0xFFFF {
- return nil, 0, EINVAL
- }
- sa.raw.Family = AF_INET
- p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
- p[0] = byte(sa.Port >> 8)
- p[1] = byte(sa.Port)
- sa.raw.Addr = sa.Addr
- return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
-}
-
-type SockaddrInet6 struct {
- Port int
- ZoneId uint32
- Addr [16]byte
- raw RawSockaddrInet6
-}
-
-func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) {
- if sa.Port < 0 || sa.Port > 0xFFFF {
- return nil, 0, EINVAL
- }
- sa.raw.Family = AF_INET6
- p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
- p[0] = byte(sa.Port >> 8)
- p[1] = byte(sa.Port)
- sa.raw.Scope_id = sa.ZoneId
- sa.raw.Addr = sa.Addr
- return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
-}
-
-type RawSockaddrUnix struct {
- Family uint16
- Path [UNIX_PATH_MAX]int8
-}
-
-type SockaddrUnix struct {
- Name string
- raw RawSockaddrUnix
-}
-
-func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
- name := sa.Name
- n := len(name)
- if n > len(sa.raw.Path) {
- return nil, 0, EINVAL
- }
- if n == len(sa.raw.Path) && name[0] != '@' {
- return nil, 0, EINVAL
- }
- sa.raw.Family = AF_UNIX
- for i := 0; i < n; i++ {
- sa.raw.Path[i] = int8(name[i])
- }
- // length is family (uint16), name, NUL.
- sl := int32(2)
- if n > 0 {
- sl += int32(n) + 1
- }
- if sa.raw.Path[0] == '@' {
- sa.raw.Path[0] = 0
- // Don't count trailing NUL for abstract address.
- sl--
- }
-
- return unsafe.Pointer(&sa.raw), sl, nil
-}
-
-func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
- switch rsa.Addr.Family {
- case AF_UNIX:
- pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
- sa := new(SockaddrUnix)
- if pp.Path[0] == 0 {
- // "Abstract" Unix domain socket.
- // Rewrite leading NUL as @ for textual display.
- // (This is the standard convention.)
- // Not friendly to overwrite in place,
- // but the callers below don't care.
- pp.Path[0] = '@'
- }
-
- // Assume path ends at NUL.
- // This is not technically the Linux semantics for
- // abstract Unix domain sockets--they are supposed
- // to be uninterpreted fixed-size binary blobs--but
- // everyone uses this convention.
- n := 0
- for n < len(pp.Path) && pp.Path[n] != 0 {
- n++
- }
- bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n:n]
- sa.Name = string(bytes)
- return sa, nil
-
- case AF_INET:
- pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
- sa := new(SockaddrInet4)
- p := (*[2]byte)(unsafe.Pointer(&pp.Port))
- sa.Port = int(p[0])<<8 + int(p[1])
- sa.Addr = pp.Addr
- return sa, nil
-
- case AF_INET6:
- pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
- sa := new(SockaddrInet6)
- p := (*[2]byte)(unsafe.Pointer(&pp.Port))
- sa.Port = int(p[0])<<8 + int(p[1])
- sa.ZoneId = pp.Scope_id
- sa.Addr = pp.Addr
- return sa, nil
- }
- return nil, EAFNOSUPPORT
-}
-
-func Socket(domain, typ, proto int) (fd Handle, err error) {
- if domain == AF_INET6 && SocketDisableIPv6 {
- return InvalidHandle, EAFNOSUPPORT
- }
- return socket(int32(domain), int32(typ), int32(proto))
-}
-
-func SetsockoptInt(fd Handle, level, opt int, value int) (err error) {
- v := int32(value)
- return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v)))
-}
-
-func Bind(fd Handle, sa Sockaddr) (err error) {
- ptr, n, err := sa.sockaddr()
- if err != nil {
- return err
- }
- return bind(fd, ptr, n)
-}
-
-func Connect(fd Handle, sa Sockaddr) (err error) {
- ptr, n, err := sa.sockaddr()
- if err != nil {
- return err
- }
- return connect(fd, ptr, n)
-}
-
-func Getsockname(fd Handle) (sa Sockaddr, err error) {
- var rsa RawSockaddrAny
- l := int32(unsafe.Sizeof(rsa))
- if err = getsockname(fd, &rsa, &l); err != nil {
- return
- }
- return rsa.Sockaddr()
-}
-
-func Getpeername(fd Handle) (sa Sockaddr, err error) {
- var rsa RawSockaddrAny
- l := int32(unsafe.Sizeof(rsa))
- if err = getpeername(fd, &rsa, &l); err != nil {
- return
- }
- return rsa.Sockaddr()
-}
-
-func Listen(s Handle, n int) (err error) {
- return listen(s, int32(n))
-}
-
-func Shutdown(fd Handle, how int) (err error) {
- return shutdown(fd, int32(how))
-}
-
-func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) {
- var rsa unsafe.Pointer
- var len int32
- if to != nil {
- rsa, len, err = to.sockaddr()
- if err != nil {
- return err
- }
- }
- r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(rsa)), uintptr(len), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
- if r1 == socket_error {
- if e1 != 0 {
- err = errnoErr(e1)
- } else {
- err = EINVAL
- }
- }
- return err
-}
-
-func wsaSendtoInet4(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *SockaddrInet4, overlapped *Overlapped, croutine *byte) (err error) {
- rsa, len, err := to.sockaddr()
- if err != nil {
- return err
- }
- r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(rsa)), uintptr(len), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
- if r1 == socket_error {
- if e1 != 0 {
- err = errnoErr(e1)
- } else {
- err = EINVAL
- }
- }
- return err
-}
-
-func wsaSendtoInet6(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *SockaddrInet6, overlapped *Overlapped, croutine *byte) (err error) {
- rsa, len, err := to.sockaddr()
- if err != nil {
- return err
- }
- r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(rsa)), uintptr(len), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
- if r1 == socket_error {
- if e1 != 0 {
- err = errnoErr(e1)
- } else {
- err = EINVAL
- }
- }
- return err
-}
-
-func LoadGetAddrInfo() error {
- return procGetAddrInfoW.Find()
-}
-
-var connectExFunc struct {
- once sync.Once
- addr uintptr
- err error
-}
-
-func LoadConnectEx() error {
- connectExFunc.once.Do(func() {
- var s Handle
- s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
- if connectExFunc.err != nil {
- return
- }
- defer CloseHandle(s)
- var n uint32
- connectExFunc.err = WSAIoctl(s,
- SIO_GET_EXTENSION_FUNCTION_POINTER,
- (*byte)(unsafe.Pointer(&WSAID_CONNECTEX)),
- uint32(unsafe.Sizeof(WSAID_CONNECTEX)),
- (*byte)(unsafe.Pointer(&connectExFunc.addr)),
- uint32(unsafe.Sizeof(connectExFunc.addr)),
- &n, nil, 0)
- })
- return connectExFunc.err
-}
-
-func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) {
- r1, _, e1 := Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0)
- if r1 == 0 {
- if e1 != 0 {
- err = error(e1)
- } else {
- err = EINVAL
- }
- }
- return
-}
-
-func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error {
- err := LoadConnectEx()
- if err != nil {
- return errorspkg.New("failed to find ConnectEx: " + err.Error())
- }
- ptr, n, err := sa.sockaddr()
- if err != nil {
- return err
- }
- return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
-}
-
-// Invented structures to support what package os expects.
-type Rusage struct {
- CreationTime Filetime
- ExitTime Filetime
- KernelTime Filetime
- UserTime Filetime
-}
-
-type WaitStatus struct {
- ExitCode uint32
-}
-
-func (w WaitStatus) Exited() bool { return true }
-
-func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) }
-
-func (w WaitStatus) Signal() Signal { return -1 }
-
-func (w WaitStatus) CoreDump() bool { return false }
-
-func (w WaitStatus) Stopped() bool { return false }
-
-func (w WaitStatus) Continued() bool { return false }
-
-func (w WaitStatus) StopSignal() Signal { return -1 }
-
-func (w WaitStatus) Signaled() bool { return false }
-
-func (w WaitStatus) TrapCause() int { return -1 }
-
-// Timespec is an invented structure on Windows, but here for
-// consistency with the syscall package for other operating systems.
-type Timespec struct {
- Sec int64
- Nsec int64
-}
-
-func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
-
-func NsecToTimespec(nsec int64) (ts Timespec) {
- ts.Sec = nsec / 1e9
- ts.Nsec = nsec % 1e9
- return
-}
-
-// TODO(brainman): fix all needed for net
-
-func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, EWINDOWS }
-func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) {
- return 0, nil, EWINDOWS
-}
-func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error) { return EWINDOWS }
-func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return EWINDOWS }
-
-// The Linger struct is wrong but we only noticed after Go 1.
-// sysLinger is the real system call structure.
-
-// BUG(brainman): The definition of Linger is not appropriate for direct use
-// with Setsockopt and Getsockopt.
-// Use SetsockoptLinger instead.
-
-type Linger struct {
- Onoff int32
- Linger int32
-}
-
-type sysLinger struct {
- Onoff uint16
- Linger uint16
-}
-
-type IPMreq struct {
- Multiaddr [4]byte /* in_addr */
- Interface [4]byte /* in_addr */
-}
-
-type IPv6Mreq struct {
- Multiaddr [16]byte /* in6_addr */
- Interface uint32
-}
-
-func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, EWINDOWS }
-
-func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
- sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)}
- return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys)))
-}
-
-func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
- return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
-}
-func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
- return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
-}
-func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { return EWINDOWS }
-
-func Getpid() (pid int) { return int(getCurrentProcessId()) }
-
-func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) {
- // NOTE(rsc): The Win32finddata struct is wrong for the system call:
- // the two paths are each one uint16 short. Use the correct struct,
- // a win32finddata1, and then copy the results out.
- // There is no loss of expressivity here, because the final
- // uint16, if it is used, is supposed to be a NUL, and Go doesn't need that.
- // For Go 1.1, we might avoid the allocation of win32finddata1 here
- // by adding a final Bug [2]uint16 field to the struct and then
- // adjusting the fields in the result directly.
- var data1 win32finddata1
- handle, err = findFirstFile1(name, &data1)
- if err == nil {
- copyFindData(data, &data1)
- }
- return
-}
-
-func FindNextFile(handle Handle, data *Win32finddata) (err error) {
- var data1 win32finddata1
- err = findNextFile1(handle, &data1)
- if err == nil {
- copyFindData(data, &data1)
- }
- return
-}
-
-func getProcessEntry(pid int) (*ProcessEntry32, error) {
- snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
- if err != nil {
- return nil, err
- }
- defer CloseHandle(snapshot)
- var procEntry ProcessEntry32
- procEntry.Size = uint32(unsafe.Sizeof(procEntry))
- if err = Process32First(snapshot, &procEntry); err != nil {
- return nil, err
- }
- for {
- if procEntry.ProcessID == uint32(pid) {
- return &procEntry, nil
- }
- err = Process32Next(snapshot, &procEntry)
- if err != nil {
- return nil, err
- }
- }
-}
-
-func Getppid() (ppid int) {
- pe, err := getProcessEntry(Getpid())
- if err != nil {
- return -1
- }
- return int(pe.ParentProcessID)
-}
-
-// TODO(brainman): fix all needed for os
-func Fchdir(fd Handle) (err error) { return EWINDOWS }
-func Link(oldpath, newpath string) (err error) { return EWINDOWS }
-func Symlink(path, link string) (err error) { return EWINDOWS }
-
-func Fchmod(fd Handle, mode uint32) (err error) { return EWINDOWS }
-func Chown(path string, uid int, gid int) (err error) { return EWINDOWS }
-func Lchown(path string, uid int, gid int) (err error) { return EWINDOWS }
-func Fchown(fd Handle, uid int, gid int) (err error) { return EWINDOWS }
-
-func Getuid() (uid int) { return -1 }
-func Geteuid() (euid int) { return -1 }
-func Getgid() (gid int) { return -1 }
-func Getegid() (egid int) { return -1 }
-func Getgroups() (gids []int, err error) { return nil, EWINDOWS }
-
-type Signal int
-
-func (s Signal) Signal() {}
-
-func (s Signal) String() string {
- if 0 <= s && int(s) < len(signals) {
- str := signals[s]
- if str != "" {
- return str
- }
- }
- return "signal " + itoa.Itoa(int(s))
-}
-
-func LoadCreateSymbolicLink() error {
- return procCreateSymbolicLinkW.Find()
-}
-
-// Readlink returns the destination of the named symbolic link.
-func Readlink(path string, buf []byte) (n int, err error) {
- fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING,
- FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0)
- if err != nil {
- return -1, err
- }
- defer CloseHandle(fd)
-
- rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
- var bytesReturned uint32
- err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
- if err != nil {
- return -1, err
- }
-
- rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
- var s string
- switch rdb.ReparseTag {
- case IO_REPARSE_TAG_SYMLINK:
- data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
- p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
- s = UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2])
- if data.Flags&_SYMLINK_FLAG_RELATIVE == 0 {
- if len(s) >= 4 && s[:4] == `\??\` {
- s = s[4:]
- switch {
- case len(s) >= 2 && s[1] == ':': // \??\C:\foo\bar
- // do nothing
- case len(s) >= 4 && s[:4] == `UNC\`: // \??\UNC\foo\bar
- s = `\\` + s[4:]
- default:
- // unexpected; do nothing
- }
- } else {
- // unexpected; do nothing
- }
- }
- case _IO_REPARSE_TAG_MOUNT_POINT:
- data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
- p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
- s = UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2])
- if len(s) >= 4 && s[:4] == `\??\` { // \??\C:\foo\bar
- s = s[4:]
- } else {
- // unexpected; do nothing
- }
- default:
- // the path is not a symlink or junction but another type of reparse
- // point
- return -1, ENOENT
- }
- n = copy(buf, []byte(s))
-
- 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)
-}
-
-// newProcThreadAttributeList allocates new PROC_THREAD_ATTRIBUTE_LIST, with
-// the requested maximum number of attributes, which must be cleaned up by
-// deleteProcThreadAttributeList.
-func newProcThreadAttributeList(maxAttrCount uint32) (*_PROC_THREAD_ATTRIBUTE_LIST, error) {
- var size uintptr
- err := initializeProcThreadAttributeList(nil, maxAttrCount, 0, &size)
- if err != ERROR_INSUFFICIENT_BUFFER {
- if err == nil {
- return nil, errorspkg.New("unable to query buffer size from InitializeProcThreadAttributeList")
- }
- return nil, err
- }
- // size is guaranteed to be ≥1 by initializeProcThreadAttributeList.
- al := (*_PROC_THREAD_ATTRIBUTE_LIST)(unsafe.Pointer(&make([]byte, size)[0]))
- err = initializeProcThreadAttributeList(al, maxAttrCount, 0, &size)
- if err != nil {
- return nil, err
- }
- return al, nil
-}
-
-// RegEnumKeyEx enumerates the subkeys of an open registry key.
-// Each call retrieves information about one subkey. name is
-// a buffer that should be large enough to hold the name of the
-// subkey plus a null terminating character. nameLen is its
-// length. On return, nameLen will contain the actual length of the
-// subkey.
-//
-// Should name not be large enough to hold the subkey, this function
-// will return ERROR_MORE_DATA, and must be called again with an
-// appropriately sized buffer.
-//
-// reserved must be nil. class and classLen behave like name and nameLen
-// but for the class of the subkey, except that they are optional.
-// lastWriteTime, if not nil, will be populated with the time the subkey
-// was last written.
-//
-// The caller must enumerate all subkeys in order. That is
-// RegEnumKeyEx must be called with index starting at 0, incrementing
-// the index until the function returns ERROR_NO_MORE_ITEMS, or with
-// the index of the last subkey (obtainable from RegQueryInfoKey),
-// decrementing until index 0 is enumerated.
-//
-// Successive calls to this API must happen on the same OS thread,
-// so call runtime.LockOSThread before calling this function.
-func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) {
- return regEnumKeyEx(key, index, name, nameLen, reserved, class, classLen, lastWriteTime)
-}
diff --git a/contrib/go/_std_1.20/src/syscall/timestruct.go b/contrib/go/_std_1.20/src/syscall/timestruct.go
deleted file mode 100644
index 8a03171ee5..0000000000
--- a/contrib/go/_std_1.20/src/syscall/timestruct.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2016 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.
-
-//go:build unix || (js && wasm)
-
-package syscall
-
-// TimespecToNSec returns the time stored in ts as nanoseconds.
-func TimespecToNsec(ts Timespec) int64 { return ts.Nano() }
-
-// NsecToTimespec converts a number of nanoseconds into a Timespec.
-func NsecToTimespec(nsec int64) Timespec {
- sec := nsec / 1e9
- nsec = nsec % 1e9
- if nsec < 0 {
- nsec += 1e9
- sec--
- }
- return setTimespec(sec, nsec)
-}
-
-// TimevalToNsec returns the time stored in tv as nanoseconds.
-func TimevalToNsec(tv Timeval) int64 { return tv.Nano() }
-
-// NsecToTimeval converts a number of nanoseconds into a Timeval.
-func NsecToTimeval(nsec int64) Timeval {
- nsec += 999 // round up to microsecond
- usec := nsec % 1e9 / 1e3
- sec := nsec / 1e9
- if usec < 0 {
- usec += 1e6
- sec--
- }
- return setTimeval(sec, usec)
-}
diff --git a/contrib/go/_std_1.20/src/syscall/ya.make b/contrib/go/_std_1.20/src/syscall/ya.make
deleted file mode 100644
index e165b55f07..0000000000
--- a/contrib/go/_std_1.20/src/syscall/ya.make
+++ /dev/null
@@ -1,128 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- asan0.go
- endian_little.go
- msan0.go
- net.go
- syscall.go
- time_nofake.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- bpf_darwin.go
- dirent.go
- env_unix.go
- exec_libc2.go
- exec_unix.go
- flock_darwin.go
- forkpipe.go
- ptrace_darwin.go
- rlimit.go
- rlimit_darwin.go
- route_bsd.go
- route_darwin.go
- sockcmsg_unix.go
- sockcmsg_unix_other.go
- syscall_bsd.go
- syscall_darwin.go
- syscall_unix.go
- timestruct.go
- )
-
- IF (ARCH_ARM64)
- SRCS(
- asm_darwin_arm64.s
- syscall_darwin_arm64.go
- zerrors_darwin_arm64.go
- zsyscall_darwin_arm64.go
- zsyscall_darwin_arm64.s
- zsysnum_darwin_arm64.go
- ztypes_darwin_arm64.go
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- asm_darwin_amd64.s
- syscall_darwin_amd64.go
- zerrors_darwin_amd64.go
- zsyscall_darwin_amd64.go
- zsyscall_darwin_amd64.s
- zsysnum_darwin_amd64.go
- ztypes_darwin_amd64.go
- )
- ENDIF()
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- dirent.go
- env_unix.go
- exec_linux.go
- exec_unix.go
- flock.go
- lsf_linux.go
- netlink_linux.go
- rlimit.go
- rlimit_stub.go
- setuidgid_linux.go
- sockcmsg_linux.go
- sockcmsg_unix.go
- sockcmsg_unix_other.go
- syscall_linux.go
- syscall_linux_accept4.go
- syscall_unix.go
- timestruct.go
- )
-
- IF (ARCH_ARM64)
- SRCS(
- asm_linux_arm64.s
- syscall_linux_arm64.go
- zerrors_linux_arm64.go
- zsyscall_linux_arm64.go
- zsysnum_linux_arm64.go
- ztypes_linux_arm64.go
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- asm_linux_amd64.s
- syscall_linux_amd64.go
- zerrors_linux_amd64.go
- zsyscall_linux_amd64.go
- zsysnum_linux_amd64.go
- ztypes_linux_amd64.go
- )
- ENDIF()
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- dll_windows.go
- env_windows.go
- exec_windows.go
- security_windows.go
- syscall_windows.go
- types_windows.go
- zerrors_windows.go
- zsyscall_windows.go
- )
-
- IF (ARCH_ARM64)
- SRCS(
- types_windows_arm64.go
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- types_windows_amd64.go
- )
- ENDIF()
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/syscall/zsyscall_darwin_amd64.go b/contrib/go/_std_1.20/src/syscall/zsyscall_darwin_amd64.go
deleted file mode 100644
index 161bb4443a..0000000000
--- a/contrib/go/_std_1.20/src/syscall/zsyscall_darwin_amd64.go
+++ /dev/null
@@ -1,2024 +0,0 @@
-// mksyscall.pl -darwin -tags darwin,amd64 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go
-// Code generated by the command above; DO NOT EDIT.
-
-//go:build darwin && amd64
-
-package syscall
-
-import "unsafe"
-import "internal/abi"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
- r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_getgroups_trampoline()
-
-//go:cgo_import_dynamic libc_getgroups getgroups "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setgroups_trampoline()
-
-//go:cgo_import_dynamic libc_setgroups setgroups "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
- r0, _, e1 := syscall6(abi.FuncPCABI0(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
- wpid = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_wait4_trampoline()
-
-//go:cgo_import_dynamic libc_wait4 wait4 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_accept_trampoline()
-
-//go:cgo_import_dynamic libc_accept accept "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_bind_trampoline()
-
-//go:cgo_import_dynamic libc_bind bind "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_connect_trampoline()
-
-//go:cgo_import_dynamic libc_connect connect "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
- r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_socket_trampoline()
-
-//go:cgo_import_dynamic libc_socket socket "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
- _, _, e1 := syscall6(abi.FuncPCABI0(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_getsockopt_trampoline()
-
-//go:cgo_import_dynamic libc_getsockopt getsockopt "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
- _, _, e1 := syscall6(abi.FuncPCABI0(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setsockopt_trampoline()
-
-//go:cgo_import_dynamic libc_setsockopt setsockopt "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_getpeername_trampoline()
-
-//go:cgo_import_dynamic libc_getpeername getpeername "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_getsockname_trampoline()
-
-//go:cgo_import_dynamic libc_getsockname getsockname "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_shutdown_trampoline()
-
-//go:cgo_import_dynamic libc_shutdown shutdown "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
- _, _, e1 := rawSyscall6(abi.FuncPCABI0(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_socketpair_trampoline()
-
-//go:cgo_import_dynamic libc_socketpair socketpair "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := syscall6(abi.FuncPCABI0(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_recvfrom_trampoline()
-
-//go:cgo_import_dynamic libc_recvfrom recvfrom "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
- var _p0 unsafe.Pointer
- if len(buf) > 0 {
- _p0 = unsafe.Pointer(&buf[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := syscall6(abi.FuncPCABI0(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_sendto_trampoline()
-
-//go:cgo_import_dynamic libc_sendto sendto "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_recvmsg_trampoline()
-
-//go:cgo_import_dynamic libc_recvmsg recvmsg "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_sendmsg_trampoline()
-
-//go:cgo_import_dynamic libc_sendmsg sendmsg "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
- r0, _, e1 := syscall6(abi.FuncPCABI0(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_kevent_trampoline()
-
-//go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_utimes_trampoline()
-
-//go:cgo_import_dynamic libc_utimes utimes "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_futimes_trampoline()
-
-//go:cgo_import_dynamic libc_futimes futimes "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
- val = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_fcntl_trampoline()
-
-//go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe(p *[2]int32) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_pipe_trampoline), uintptr(unsafe.Pointer(p)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_pipe_trampoline()
-
-//go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall6(abi.FuncPCABI0(libc_utimensat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_utimensat_trampoline()
-
-//go:cgo_import_dynamic libc_utimensat utimensat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kill(pid int, signum int, posix int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_kill_trampoline), uintptr(pid), uintptr(signum), uintptr(posix))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_kill_trampoline()
-
-//go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_access_trampoline()
-
-//go:cgo_import_dynamic libc_access access "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_adjtime_trampoline()
-
-//go:cgo_import_dynamic libc_adjtime adjtime "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_chdir_trampoline()
-
-//go:cgo_import_dynamic libc_chdir chdir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_chflags_trampoline()
-
-//go:cgo_import_dynamic libc_chflags chflags "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_chmod_trampoline()
-
-//go:cgo_import_dynamic libc_chmod chmod "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_chown_trampoline()
-
-//go:cgo_import_dynamic libc_chown chown "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_chroot_trampoline()
-
-//go:cgo_import_dynamic libc_chroot chroot "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(fd), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_close_trampoline()
-
-//go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func closedir(dir uintptr) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_closedir_trampoline), uintptr(dir), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_closedir_trampoline()
-
-//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_dup_trampoline), uintptr(fd), 0, 0)
- nfd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_dup_trampoline()
-
-//go:cgo_import_dynamic libc_dup dup "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_dup2_trampoline()
-
-//go:cgo_import_dynamic libc_dup2 dup2 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exchangedata(path1 string, path2 string, options int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path1)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(path2)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_exchangedata_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_exchangedata_trampoline()
-
-//go:cgo_import_dynamic libc_exchangedata exchangedata "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_fchdir_trampoline), uintptr(fd), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_fchdir_trampoline()
-
-//go:cgo_import_dynamic libc_fchdir fchdir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_fchflags_trampoline()
-
-//go:cgo_import_dynamic libc_fchflags fchflags "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_fchmod_trampoline()
-
-//go:cgo_import_dynamic libc_fchmod fchmod "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_fchown_trampoline()
-
-//go:cgo_import_dynamic libc_fchown fchown "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_flock_trampoline()
-
-//go:cgo_import_dynamic libc_flock flock "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
- val = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_fpathconf_trampoline()
-
-//go:cgo_import_dynamic libc_fpathconf fpathconf "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_fsync_trampoline), uintptr(fd), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_fsync_trampoline()
-
-//go:cgo_import_dynamic libc_fsync fsync "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_ftruncate_trampoline()
-
-//go:cgo_import_dynamic libc_ftruncate ftruncate "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdtablesize() (size int) {
- r0, _, _ := syscall(abi.FuncPCABI0(libc_getdtablesize_trampoline), 0, 0, 0)
- size = int(r0)
- return
-}
-
-func libc_getdtablesize_trampoline()
-
-//go:cgo_import_dynamic libc_getdtablesize getdtablesize "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
- r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getegid_trampoline), 0, 0, 0)
- egid = int(r0)
- return
-}
-
-func libc_getegid_trampoline()
-
-//go:cgo_import_dynamic libc_getegid getegid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
- r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_geteuid_trampoline), 0, 0, 0)
- uid = int(r0)
- return
-}
-
-func libc_geteuid_trampoline()
-
-//go:cgo_import_dynamic libc_geteuid geteuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
- r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getgid_trampoline), 0, 0, 0)
- gid = int(r0)
- return
-}
-
-func libc_getgid_trampoline()
-
-//go:cgo_import_dynamic libc_getgid getgid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
- r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpgid_trampoline), uintptr(pid), 0, 0)
- pgid = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_getpgid_trampoline()
-
-//go:cgo_import_dynamic libc_getpgid getpgid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
- r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpgrp_trampoline), 0, 0, 0)
- pgrp = int(r0)
- return
-}
-
-func libc_getpgrp_trampoline()
-
-//go:cgo_import_dynamic libc_getpgrp getpgrp "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
- r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
- pid = int(r0)
- return
-}
-
-func libc_getpid_trampoline()
-
-//go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
- r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getppid_trampoline), 0, 0, 0)
- ppid = int(r0)
- return
-}
-
-func libc_getppid_trampoline()
-
-//go:cgo_import_dynamic libc_getppid getppid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
- prio = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_getpriority_trampoline()
-
-//go:cgo_import_dynamic libc_getpriority getpriority "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_getrlimit_trampoline()
-
-//go:cgo_import_dynamic libc_getrlimit getrlimit "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_getrusage_trampoline()
-
-//go:cgo_import_dynamic libc_getrusage getrusage "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
- r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsid_trampoline), uintptr(pid), 0, 0)
- sid = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_getsid_trampoline()
-
-//go:cgo_import_dynamic libc_getsid getsid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
- r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getuid_trampoline), 0, 0, 0)
- uid = int(r0)
- return
-}
-
-func libc_getuid_trampoline()
-
-//go:cgo_import_dynamic libc_getuid getuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
- r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_issetugid_trampoline), 0, 0, 0)
- tainted = bool(r0 != 0)
- return
-}
-
-func libc_issetugid_trampoline()
-
-//go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_kqueue_trampoline), 0, 0, 0)
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_kqueue_trampoline()
-
-//go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_lchown_trampoline()
-
-//go:cgo_import_dynamic libc_lchown lchown "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(link)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_link_trampoline()
-
-//go:cgo_import_dynamic libc_link link "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_listen_trampoline()
-
-//go:cgo_import_dynamic libc_listen listen "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_mkdir_trampoline()
-
-//go:cgo_import_dynamic libc_mkdir mkdir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_mkfifo_trampoline()
-
-//go:cgo_import_dynamic libc_mkfifo mkfifo "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_mknod_trampoline()
-
-//go:cgo_import_dynamic libc_mknod mknod "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlock(b []byte) (err error) {
- var _p0 unsafe.Pointer
- if len(b) > 0 {
- _p0 = unsafe.Pointer(&b[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_mlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_mlock_trampoline()
-
-//go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_mlockall_trampoline), uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_mlockall_trampoline()
-
-//go:cgo_import_dynamic libc_mlockall mlockall "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
- var _p0 unsafe.Pointer
- if len(b) > 0 {
- _p0 = unsafe.Pointer(&b[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_mprotect_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(prot))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_mprotect_trampoline()
-
-//go:cgo_import_dynamic libc_mprotect mprotect "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func msync(b []byte, flags int) (err error) {
- var _p0 unsafe.Pointer
- if len(b) > 0 {
- _p0 = unsafe.Pointer(&b[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_msync_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(flags))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_msync_trampoline()
-
-//go:cgo_import_dynamic libc_msync msync "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
- var _p0 unsafe.Pointer
- if len(b) > 0 {
- _p0 = unsafe.Pointer(&b[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_munlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_munlock_trampoline()
-
-//go:cgo_import_dynamic libc_munlock munlock "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_munlockall_trampoline), 0, 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_munlockall_trampoline()
-
-//go:cgo_import_dynamic libc_munlockall munlockall "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_open_trampoline()
-
-//go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
- val = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_pathconf_trampoline()
-
-//go:cgo_import_dynamic libc_pathconf pathconf "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pread(fd int, p []byte, offset int64) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_pread_trampoline()
-
-//go:cgo_import_dynamic libc_pread pread "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pwrite(fd int, p []byte, offset int64) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_pwrite_trampoline()
-
-//go:cgo_import_dynamic libc_pwrite pwrite "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_read_trampoline()
-
-//go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
- r0, _, _ := syscall(abi.FuncPCABI0(libc_readdir_r_trampoline), uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
- res = Errno(r0)
- return
-}
-
-func libc_readdir_r_trampoline()
-
-//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 unsafe.Pointer
- if len(buf) > 0 {
- _p1 = unsafe.Pointer(&buf[0])
- } else {
- _p1 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_readlink_trampoline()
-
-//go:cgo_import_dynamic libc_readlink readlink "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(from)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(to)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_rename_trampoline()
-
-//go:cgo_import_dynamic libc_rename rename "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_revoke_trampoline()
-
-//go:cgo_import_dynamic libc_revoke revoke "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_rmdir_trampoline()
-
-//go:cgo_import_dynamic libc_rmdir rmdir "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
- r0, _, e1 := syscallX(abi.FuncPCABI0(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(whence))
- newoffset = int64(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_lseek_trampoline()
-
-//go:cgo_import_dynamic libc_lseek lseek "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
- _, _, e1 := syscall6(abi.FuncPCABI0(libc_select_trampoline), uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_select_trampoline()
-
-//go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_setegid_trampoline), uintptr(egid), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setegid_trampoline()
-
-//go:cgo_import_dynamic libc_setegid setegid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_seteuid_trampoline), uintptr(euid), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_seteuid_trampoline()
-
-//go:cgo_import_dynamic libc_seteuid seteuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(gid), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setgid_trampoline()
-
-//go:cgo_import_dynamic libc_setgid setgid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setlogin(name string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(name)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setlogin_trampoline()
-
-//go:cgo_import_dynamic libc_setlogin setlogin "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setpgid_trampoline()
-
-//go:cgo_import_dynamic libc_setpgid setpgid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setpriority_trampoline()
-
-//go:cgo_import_dynamic libc_setpriority setpriority "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setprivexec(flag int) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_setprivexec_trampoline), uintptr(flag), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setprivexec_trampoline()
-
-//go:cgo_import_dynamic libc_setprivexec setprivexec "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setregid_trampoline()
-
-//go:cgo_import_dynamic libc_setregid setregid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setreuid_trampoline()
-
-//go:cgo_import_dynamic libc_setreuid setreuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setrlimit(which int, lim *Rlimit) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setrlimit_trampoline()
-
-//go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
- r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
- pid = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setsid_trampoline()
-
-//go:cgo_import_dynamic libc_setsid setsid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_settimeofday_trampoline()
-
-//go:cgo_import_dynamic libc_settimeofday settimeofday "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(uid), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_setuid_trampoline()
-
-//go:cgo_import_dynamic libc_setuid setuid "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(link)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_symlink_trampoline()
-
-//go:cgo_import_dynamic libc_symlink symlink "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_sync_trampoline), 0, 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_sync_trampoline()
-
-//go:cgo_import_dynamic libc_sync sync "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_truncate_trampoline()
-
-//go:cgo_import_dynamic libc_truncate truncate "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
- r0, _, _ := syscall(abi.FuncPCABI0(libc_umask_trampoline), uintptr(newmask), 0, 0)
- oldmask = int(r0)
- return
-}
-
-func libc_umask_trampoline()
-
-//go:cgo_import_dynamic libc_umask umask "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Undelete(path string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_undelete_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_undelete_trampoline()
-
-//go:cgo_import_dynamic libc_undelete undelete "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_unlink_trampoline()
-
-//go:cgo_import_dynamic libc_unlink unlink "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_unmount_trampoline()
-
-//go:cgo_import_dynamic libc_unmount unmount "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_write_trampoline()
-
-//go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writev(fd int, iovecs []Iovec) (cnt uintptr, err error) {
- var _p0 unsafe.Pointer
- if len(iovecs) > 0 {
- _p0 = unsafe.Pointer(&iovecs[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := syscallX(abi.FuncPCABI0(libc_writev_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
- cnt = uintptr(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_writev_trampoline()
-
-//go:cgo_import_dynamic libc_writev writev "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
- r0, _, e1 := syscall6X(abi.FuncPCABI0(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
- ret = uintptr(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_mmap_trampoline()
-
-//go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_munmap_trampoline()
-
-//go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fork() (pid int, err error) {
- r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
- pid = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_fork_trampoline()
-
-//go:cgo_import_dynamic libc_fork fork "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ioctl(fd int, req int, arg int) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_ioctl_trampoline()
-
-//go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func execve(path *byte, argv **byte, envp **byte) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_execve_trampoline), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(argv)), uintptr(unsafe.Pointer(envp)))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_execve_trampoline()
-
-//go:cgo_import_dynamic libc_execve execve "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func exit(res int) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), uintptr(res), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_exit_trampoline()
-
-//go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
- var _p0 unsafe.Pointer
- if len(mib) > 0 {
- _p0 = unsafe.Pointer(&mib[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := syscall6(abi.FuncPCABI0(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_sysctl_trampoline()
-
-//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) {
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
- val = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func unlinkat(fd int, path string, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_unlinkat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_unlinkat_trampoline()
-
-//go:cgo_import_dynamic libc_unlinkat unlinkat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func openat(fd int, path string, flags int, perm uint32) (fdret int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- r0, _, e1 := syscall6(abi.FuncPCABI0(libc_openat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(perm), 0, 0)
- fdret = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_openat_trampoline()
-
-//go:cgo_import_dynamic libc_openat openat "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getcwd(buf []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(buf) > 0 {
- _p0 = unsafe.Pointer(&buf[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := syscall(abi.FuncPCABI0(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_getcwd_trampoline()
-
-//go:cgo_import_dynamic libc_getcwd getcwd "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_fstat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_fstat64_trampoline()
-
-//go:cgo_import_dynamic libc_fstat64 fstat64 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
- _, _, e1 := syscall(abi.FuncPCABI0(libc_fstatfs64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_fstatfs64_trampoline()
-
-//go:cgo_import_dynamic libc_fstatfs64 fstatfs64 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tp *Timeval) (err error) {
- _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_gettimeofday_trampoline()
-
-//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_lstat64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_lstat64_trampoline()
-
-//go:cgo_import_dynamic libc_lstat64 lstat64 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_stat64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_stat64_trampoline()
-
-//go:cgo_import_dynamic libc_stat64 stat64 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, stat *Statfs_t) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall(abi.FuncPCABI0(libc_statfs64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_statfs64_trampoline()
-
-//go:cgo_import_dynamic libc_statfs64 statfs64 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := syscall6(abi.FuncPCABI0(libc_fstatat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_fstatat64_trampoline()
-
-//go:cgo_import_dynamic libc_fstatat64 fstatat64 "/usr/lib/libSystem.B.dylib"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-//go:nosplit
-func ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) {
- _, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func libc_ptrace_trampoline()
-
-//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
diff --git a/contrib/go/_std_1.20/src/syscall/zsyscall_linux_amd64.go b/contrib/go/_std_1.20/src/syscall/zsyscall_linux_amd64.go
deleted file mode 100644
index f2faef4433..0000000000
--- a/contrib/go/_std_1.20/src/syscall/zsyscall_linux_amd64.go
+++ /dev/null
@@ -1,1648 +0,0 @@
-// mksyscall.pl -tags linux,amd64 syscall_linux.go syscall_linux_amd64.go
-// Code generated by the command above; DO NOT EDIT.
-
-//go:build linux && amd64
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func faccessat(dirfd int, path string, mode uint32) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fchmodat(dirfd int, path string, mode uint32) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(oldpath)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(newpath)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_LINKAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0)
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe2(p *[2]_C_int, flags int) (err error) {
- _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 unsafe.Pointer
- if len(buf) > 0 {
- _p1 = unsafe.Pointer(&buf[0])
- } else {
- _p1 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(oldpath)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(newpath)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func unlinkat(dirfd int, path string, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getcwd(buf []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(buf) > 0 {
- _p0 = unsafe.Pointer(&buf[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
- r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
- wpid = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
- _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(arg)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(source)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(target)
- if err != nil {
- return
- }
- var _p2 *byte
- _p2, err = BytePtrFromString(fstype)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Acct(path string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtimex(buf *Timex) (state int, err error) {
- r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0)
- state = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
- _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(oldfd int) (fd int, err error) {
- r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup3(oldfd int, newfd int, flags int) (err error) {
- _, _, e1 := Syscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCreate1(flag int) (fd int, err error) {
- r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0)
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
- _, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
- _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
- _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
- _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
- r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
- val = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fdatasync(fd int) (err error) {
- _, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
- _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
- _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdents(fd int, buf []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(buf) > 0 {
- _p0 = unsafe.Pointer(&buf[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
- r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
- pgid = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
- r0, _ := rawSyscallNoError(SYS_GETPID, 0, 0, 0)
- pid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
- r0, _ := rawSyscallNoError(SYS_GETPPID, 0, 0, 0)
- ppid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
- r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
- prio = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
- _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettid() (tid int) {
- r0, _ := rawSyscallNoError(SYS_GETTID, 0, 0, 0)
- tid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(attr)
- if err != nil {
- return
- }
- var _p2 unsafe.Pointer
- if len(dest) > 0 {
- _p2 = unsafe.Pointer(&dest[0])
- } else {
- _p2 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0)
- sz = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(pathname)
- if err != nil {
- return
- }
- r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
- watchdesc = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyInit1(flags int) (fd int, err error) {
- r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0)
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
- r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0)
- success = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, sig Signal) (err error) {
- _, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Klogctl(typ int, buf []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(buf) > 0 {
- _p0 = unsafe.Pointer(&buf[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listxattr(path string, dest []byte) (sz int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 unsafe.Pointer
- if len(dest) > 0 {
- _p1 = unsafe.Pointer(&dest[0])
- } else {
- _p1 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
- sz = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdirat(dirfd int, path string, mode uint32) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
- _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func PivotRoot(newroot string, putold string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(newroot)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(putold)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func prlimit1(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
- _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Removexattr(path string, attr string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(attr)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setdomainname(p []byte) (err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sethostname(p []byte) (err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
- _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
- r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
- pid = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tv *Timeval) (err error) {
- _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
- _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setxattr(path string, attr string, data []byte, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(attr)
- if err != nil {
- return
- }
- var _p2 unsafe.Pointer
- if len(data) > 0 {
- _p2 = unsafe.Pointer(&data[0])
- } else {
- _p2 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() {
- Syscall(SYS_SYNC, 0, 0, 0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sysinfo(info *Sysinfo_t) (err error) {
- _, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
- r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
- n = int64(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Tgkill(tgid int, tid int, sig Signal) (err error) {
- _, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Times(tms *Tms) (ticks uintptr, err error) {
- r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
- ticks = uintptr(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(mask int) (oldmask int) {
- r0, _ := rawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0)
- oldmask = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Uname(buf *Utsname) (err error) {
- _, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(target string, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(target)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unshare(flags int) (err error) {
- _, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func exitThread(code int) (err error) {
- _, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, p *byte, np int) (n int, err error) {
- r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, p *byte, np int) (n int, err error) {
- r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
- _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Madvise(b []byte, advice int) (err error) {
- var _p0 unsafe.Pointer
- if len(b) > 0 {
- _p0 = unsafe.Pointer(&b[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
- var _p0 unsafe.Pointer
- if len(b) > 0 {
- _p0 = unsafe.Pointer(&b[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlock(b []byte) (err error) {
- var _p0 unsafe.Pointer
- if len(b) > 0 {
- _p0 = unsafe.Pointer(&b[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
- var _p0 unsafe.Pointer
- if len(b) > 0 {
- _p0 = unsafe.Pointer(&b[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
- _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
- _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(oldfd int, newfd int) (err error) {
- _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
- _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
- _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, buf *Statfs_t) (err error) {
- _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
- _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
- r0, _ := rawSyscallNoError(SYS_GETEGID, 0, 0, 0)
- egid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (euid int) {
- r0, _ := rawSyscallNoError(SYS_GETEUID, 0, 0, 0)
- euid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
- r0, _ := rawSyscallNoError(SYS_GETGID, 0, 0, 0)
- gid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(resource int, rlim *Rlimit) (err error) {
- _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
- r0, _ := rawSyscallNoError(SYS_GETUID, 0, 0, 0)
- uid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyInit() (fd int, err error) {
- r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT, 0, 0, 0)
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ioperm(from int, num int, on int) (err error) {
- _, _, e1 := Syscall(SYS_IOPERM, uintptr(from), uintptr(num), uintptr(on))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Iopl(level int) (err error) {
- _, _, e1 := Syscall(SYS_IOPL, uintptr(level), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, n int) (err error) {
- _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pause() (err error) {
- _, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pread(fd int, p []byte, offset int64) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pwrite(fd int, p []byte, offset int64) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(oldpath)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(newpath)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (off int64, err error) {
- r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
- off = int64(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
- r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
- r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
- written = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setfsgid(gid int) (err error) {
- _, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setfsuid(uid int) (err error) {
- _, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setrlimit(resource int, rlim *Rlimit) (err error) {
- _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(fd int, how int) (err error) {
- _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
- r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
- n = int64(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, buf *Statfs_t) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func SyncFileRange(fd int, off int64, n int64, flags int) (err error) {
- _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ustat(dev int, ubuf *Ustat_t) (err error) {
- _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
- r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
- _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
- _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(n int, list *_Gid_t) (nn int, err error) {
- r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
- nn = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
- _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
- _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
- r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
- _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
- _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
- _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
- var _p0 unsafe.Pointer
- if len(buf) > 0 {
- _p0 = unsafe.Pointer(&buf[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
- r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
- r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
- r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset))
- xaddr = uintptr(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(events) > 0 {
- _p0 = unsafe.Pointer(&events[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimesat(dirfd int, path string, times *[2]Timeval) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Utime(path string, buf *Utimbuf) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, times *[2]Timeval) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/contrib/go/_std_1.20/src/syscall/zsyscall_linux_arm64.go b/contrib/go/_std_1.20/src/syscall/zsyscall_linux_arm64.go
deleted file mode 100644
index 48eef85233..0000000000
--- a/contrib/go/_std_1.20/src/syscall/zsyscall_linux_arm64.go
+++ /dev/null
@@ -1,1563 +0,0 @@
-// mksyscall.pl -tags linux,arm64 syscall_linux.go syscall_linux_arm64.go
-// Code generated by the command above; DO NOT EDIT.
-
-//go:build linux && arm64
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func faccessat(dirfd int, path string, mode uint32) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fchmodat(dirfd int, path string, mode uint32) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(oldpath)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(newpath)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_LINKAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0)
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe2(p *[2]_C_int, flags int) (err error) {
- _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 unsafe.Pointer
- if len(buf) > 0 {
- _p1 = unsafe.Pointer(&buf[0])
- } else {
- _p1 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(oldpath)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(newpath)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func unlinkat(dirfd int, path string, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getcwd(buf []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(buf) > 0 {
- _p0 = unsafe.Pointer(&buf[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
- r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
- wpid = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
- _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(arg)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(source)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(target)
- if err != nil {
- return
- }
- var _p2 *byte
- _p2, err = BytePtrFromString(fstype)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Acct(path string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtimex(buf *Timex) (state int, err error) {
- r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0)
- state = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
- _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(oldfd int) (fd int, err error) {
- r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup3(oldfd int, newfd int, flags int) (err error) {
- _, _, e1 := Syscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCreate1(flag int) (fd int, err error) {
- r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0)
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
- _, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
- _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
- _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
- _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
- r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
- val = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fdatasync(fd int) (err error) {
- _, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
- _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
- _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdents(fd int, buf []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(buf) > 0 {
- _p0 = unsafe.Pointer(&buf[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
- r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
- pgid = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
- r0, _ := rawSyscallNoError(SYS_GETPID, 0, 0, 0)
- pid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
- r0, _ := rawSyscallNoError(SYS_GETPPID, 0, 0, 0)
- ppid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
- r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
- prio = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
- _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettid() (tid int) {
- r0, _ := rawSyscallNoError(SYS_GETTID, 0, 0, 0)
- tid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(attr)
- if err != nil {
- return
- }
- var _p2 unsafe.Pointer
- if len(dest) > 0 {
- _p2 = unsafe.Pointer(&dest[0])
- } else {
- _p2 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0)
- sz = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(pathname)
- if err != nil {
- return
- }
- r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
- watchdesc = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyInit1(flags int) (fd int, err error) {
- r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0)
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
- r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0)
- success = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, sig Signal) (err error) {
- _, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Klogctl(typ int, buf []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(buf) > 0 {
- _p0 = unsafe.Pointer(&buf[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listxattr(path string, dest []byte) (sz int, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 unsafe.Pointer
- if len(dest) > 0 {
- _p1 = unsafe.Pointer(&dest[0])
- } else {
- _p1 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
- sz = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdirat(dirfd int, path string, mode uint32) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
- _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func PivotRoot(newroot string, putold string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(newroot)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(putold)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func prlimit1(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
- _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Removexattr(path string, attr string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(attr)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setdomainname(p []byte) (err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sethostname(p []byte) (err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
- _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
- r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
- pid = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tv *Timeval) (err error) {
- _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
- _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setxattr(path string, attr string, data []byte, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(attr)
- if err != nil {
- return
- }
- var _p2 unsafe.Pointer
- if len(data) > 0 {
- _p2 = unsafe.Pointer(&data[0])
- } else {
- _p2 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() {
- Syscall(SYS_SYNC, 0, 0, 0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sysinfo(info *Sysinfo_t) (err error) {
- _, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
- r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
- n = int64(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Tgkill(tgid int, tid int, sig Signal) (err error) {
- _, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Times(tms *Tms) (ticks uintptr, err error) {
- r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
- ticks = uintptr(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(mask int) (oldmask int) {
- r0, _ := rawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0)
- oldmask = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Uname(buf *Utsname) (err error) {
- _, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(target string, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(target)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unshare(flags int) (err error) {
- _, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func exitThread(code int) (err error) {
- _, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, p *byte, np int) (n int, err error) {
- r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, p *byte, np int) (n int, err error) {
- r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
- _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Madvise(b []byte, advice int) (err error) {
- var _p0 unsafe.Pointer
- if len(b) > 0 {
- _p0 = unsafe.Pointer(&b[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
- var _p0 unsafe.Pointer
- if len(b) > 0 {
- _p0 = unsafe.Pointer(&b[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlock(b []byte) (err error) {
- var _p0 unsafe.Pointer
- if len(b) > 0 {
- _p0 = unsafe.Pointer(&b[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
- var _p0 unsafe.Pointer
- if len(b) > 0 {
- _p0 = unsafe.Pointer(&b[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
- _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
- _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(events) > 0 {
- _p0 = unsafe.Pointer(&events[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall6(SYS_EPOLL_PWAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
- _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
- _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, buf *Statfs_t) (err error) {
- _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
- _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
- r0, _ := rawSyscallNoError(SYS_GETEGID, 0, 0, 0)
- egid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (euid int) {
- r0, _ := rawSyscallNoError(SYS_GETEUID, 0, 0, 0)
- euid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
- r0, _ := rawSyscallNoError(SYS_GETGID, 0, 0, 0)
- gid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getrlimit(resource int, rlim *Rlimit) (err error) {
- _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
- r0, _ := rawSyscallNoError(SYS_GETUID, 0, 0, 0)
- uid = int(r0)
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, n int) (err error) {
- _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pread(fd int, p []byte, offset int64) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pwrite(fd int, p []byte, offset int64) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(oldpath)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(newpath)
- if err != nil {
- return
- }
- _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (off int64, err error) {
- r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
- off = int64(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
- r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
- written = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setfsgid(gid int) (err error) {
- _, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setfsuid(uid int) (err error) {
- _, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setrlimit1(resource int, rlim *Rlimit) (err error) {
- _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(fd int, how int) (err error) {
- _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
- r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
- n = int64(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, buf *Statfs_t) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func SyncFileRange(fd int, off int64, n int64, flags int) (err error) {
- _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(path)
- if err != nil {
- return
- }
- _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
- r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
- _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
- _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(n int, list *_Gid_t) (nn int, err error) {
- r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
- nn = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
- _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
- _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
- r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
- fd = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
- _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
- _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
- _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
- var _p0 unsafe.Pointer
- if len(p) > 0 {
- _p0 = unsafe.Pointer(&p[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
- var _p0 unsafe.Pointer
- if len(buf) > 0 {
- _p0 = unsafe.Pointer(&buf[0])
- } else {
- _p0 = unsafe.Pointer(&_zero)
- }
- _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
- r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
- r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
- r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset))
- xaddr = uintptr(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_t) (n int, err error) {
- r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)))
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
- _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ppoll(fds *pollFd, nfds int, timeout *Timespec, sigmask *sigset_t) (n int, err error) {
- r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
- n = int(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/contrib/go/_std_1.20/src/syscall/zsyscall_windows.go b/contrib/go/_std_1.20/src/syscall/zsyscall_windows.go
deleted file mode 100644
index 61d89f1460..0000000000
--- a/contrib/go/_std_1.20/src/syscall/zsyscall_windows.go
+++ /dev/null
@@ -1,1478 +0,0 @@
-// Code generated by 'go generate'; DO NOT EDIT.
-
-package syscall
-
-import (
- "internal/syscall/windows/sysdll"
- "unsafe"
-)
-
-var _ unsafe.Pointer
-
-// Do the interface allocations only once for common
-// Errno values.
-const (
- errnoERROR_IO_PENDING = 997
-)
-
-var (
- errERROR_IO_PENDING error = Errno(errnoERROR_IO_PENDING)
- errERROR_EINVAL error = EINVAL
-)
-
-// errnoErr returns common boxed Errno values, to prevent
-// allocations at runtime.
-func errnoErr(e Errno) error {
- switch e {
- case 0:
- return errERROR_EINVAL
- case errnoERROR_IO_PENDING:
- return errERROR_IO_PENDING
- }
- // TODO: add more here, after collecting data on the common
- // error values see on Windows. (perhaps when running
- // all.bat?)
- return e
-}
-
-var (
- modadvapi32 = NewLazyDLL(sysdll.Add("advapi32.dll"))
- modcrypt32 = NewLazyDLL(sysdll.Add("crypt32.dll"))
- moddnsapi = NewLazyDLL(sysdll.Add("dnsapi.dll"))
- modiphlpapi = NewLazyDLL(sysdll.Add("iphlpapi.dll"))
- modkernel32 = NewLazyDLL(sysdll.Add("kernel32.dll"))
- modmswsock = NewLazyDLL(sysdll.Add("mswsock.dll"))
- modnetapi32 = NewLazyDLL(sysdll.Add("netapi32.dll"))
- modntdll = NewLazyDLL(sysdll.Add("ntdll.dll"))
- modsecur32 = NewLazyDLL(sysdll.Add("secur32.dll"))
- modshell32 = NewLazyDLL(sysdll.Add("shell32.dll"))
- moduserenv = NewLazyDLL(sysdll.Add("userenv.dll"))
- modws2_32 = NewLazyDLL(sysdll.Add("ws2_32.dll"))
-
- procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
- procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW")
- procCopySid = modadvapi32.NewProc("CopySid")
- procCreateProcessAsUserW = modadvapi32.NewProc("CreateProcessAsUserW")
- procCryptAcquireContextW = modadvapi32.NewProc("CryptAcquireContextW")
- procCryptGenRandom = modadvapi32.NewProc("CryptGenRandom")
- procCryptReleaseContext = modadvapi32.NewProc("CryptReleaseContext")
- procGetLengthSid = modadvapi32.NewProc("GetLengthSid")
- procGetTokenInformation = modadvapi32.NewProc("GetTokenInformation")
- procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
- procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW")
- procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken")
- procRegCloseKey = modadvapi32.NewProc("RegCloseKey")
- procRegEnumKeyExW = modadvapi32.NewProc("RegEnumKeyExW")
- procRegOpenKeyExW = modadvapi32.NewProc("RegOpenKeyExW")
- procRegQueryInfoKeyW = modadvapi32.NewProc("RegQueryInfoKeyW")
- procRegQueryValueExW = modadvapi32.NewProc("RegQueryValueExW")
- procCertAddCertificateContextToStore = modcrypt32.NewProc("CertAddCertificateContextToStore")
- procCertCloseStore = modcrypt32.NewProc("CertCloseStore")
- procCertCreateCertificateContext = modcrypt32.NewProc("CertCreateCertificateContext")
- procCertEnumCertificatesInStore = modcrypt32.NewProc("CertEnumCertificatesInStore")
- procCertFreeCertificateChain = modcrypt32.NewProc("CertFreeCertificateChain")
- procCertFreeCertificateContext = modcrypt32.NewProc("CertFreeCertificateContext")
- procCertGetCertificateChain = modcrypt32.NewProc("CertGetCertificateChain")
- procCertOpenStore = modcrypt32.NewProc("CertOpenStore")
- procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW")
- procCertVerifyCertificateChainPolicy = modcrypt32.NewProc("CertVerifyCertificateChainPolicy")
- procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W")
- procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W")
- procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree")
- procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo")
- procGetIfEntry = modiphlpapi.NewProc("GetIfEntry")
- procCancelIo = modkernel32.NewProc("CancelIo")
- procCancelIoEx = modkernel32.NewProc("CancelIoEx")
- procCloseHandle = modkernel32.NewProc("CloseHandle")
- procCreateDirectoryW = modkernel32.NewProc("CreateDirectoryW")
- procCreateFileMappingW = modkernel32.NewProc("CreateFileMappingW")
- procCreateFileW = modkernel32.NewProc("CreateFileW")
- procCreateHardLinkW = modkernel32.NewProc("CreateHardLinkW")
- procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
- procCreatePipe = modkernel32.NewProc("CreatePipe")
- procCreateProcessW = modkernel32.NewProc("CreateProcessW")
- procCreateSymbolicLinkW = modkernel32.NewProc("CreateSymbolicLinkW")
- procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot")
- procDeleteFileW = modkernel32.NewProc("DeleteFileW")
- procDeleteProcThreadAttributeList = modkernel32.NewProc("DeleteProcThreadAttributeList")
- procDeviceIoControl = modkernel32.NewProc("DeviceIoControl")
- procDuplicateHandle = modkernel32.NewProc("DuplicateHandle")
- procExitProcess = modkernel32.NewProc("ExitProcess")
- procFindClose = modkernel32.NewProc("FindClose")
- procFindFirstFileW = modkernel32.NewProc("FindFirstFileW")
- procFindNextFileW = modkernel32.NewProc("FindNextFileW")
- procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers")
- procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile")
- procFormatMessageW = modkernel32.NewProc("FormatMessageW")
- procFreeEnvironmentStringsW = modkernel32.NewProc("FreeEnvironmentStringsW")
- procFreeLibrary = modkernel32.NewProc("FreeLibrary")
- procGetCommandLineW = modkernel32.NewProc("GetCommandLineW")
- procGetComputerNameW = modkernel32.NewProc("GetComputerNameW")
- procGetConsoleMode = modkernel32.NewProc("GetConsoleMode")
- procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW")
- procGetCurrentProcess = modkernel32.NewProc("GetCurrentProcess")
- procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId")
- procGetEnvironmentStringsW = modkernel32.NewProc("GetEnvironmentStringsW")
- procGetEnvironmentVariableW = modkernel32.NewProc("GetEnvironmentVariableW")
- procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess")
- procGetFileAttributesExW = modkernel32.NewProc("GetFileAttributesExW")
- procGetFileAttributesW = modkernel32.NewProc("GetFileAttributesW")
- procGetFileInformationByHandle = modkernel32.NewProc("GetFileInformationByHandle")
- procGetFileType = modkernel32.NewProc("GetFileType")
- procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW")
- procGetLastError = modkernel32.NewProc("GetLastError")
- procGetLongPathNameW = modkernel32.NewProc("GetLongPathNameW")
- procGetProcAddress = modkernel32.NewProc("GetProcAddress")
- procGetProcessTimes = modkernel32.NewProc("GetProcessTimes")
- procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
- procGetShortPathNameW = modkernel32.NewProc("GetShortPathNameW")
- procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW")
- procGetStdHandle = modkernel32.NewProc("GetStdHandle")
- procGetSystemDirectoryW = modkernel32.NewProc("GetSystemDirectoryW")
- procGetSystemTimeAsFileTime = modkernel32.NewProc("GetSystemTimeAsFileTime")
- procGetTempPathW = modkernel32.NewProc("GetTempPathW")
- procGetTimeZoneInformation = modkernel32.NewProc("GetTimeZoneInformation")
- procGetVersion = modkernel32.NewProc("GetVersion")
- procInitializeProcThreadAttributeList = modkernel32.NewProc("InitializeProcThreadAttributeList")
- procLoadLibraryW = modkernel32.NewProc("LoadLibraryW")
- procLocalFree = modkernel32.NewProc("LocalFree")
- procMapViewOfFile = modkernel32.NewProc("MapViewOfFile")
- procMoveFileW = modkernel32.NewProc("MoveFileW")
- procOpenProcess = modkernel32.NewProc("OpenProcess")
- procPostQueuedCompletionStatus = modkernel32.NewProc("PostQueuedCompletionStatus")
- procProcess32FirstW = modkernel32.NewProc("Process32FirstW")
- procProcess32NextW = modkernel32.NewProc("Process32NextW")
- procReadConsoleW = modkernel32.NewProc("ReadConsoleW")
- procReadDirectoryChangesW = modkernel32.NewProc("ReadDirectoryChangesW")
- procReadFile = modkernel32.NewProc("ReadFile")
- procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW")
- procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW")
- procSetEndOfFile = modkernel32.NewProc("SetEndOfFile")
- procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW")
- procSetFileAttributesW = modkernel32.NewProc("SetFileAttributesW")
- procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
- procSetFilePointer = modkernel32.NewProc("SetFilePointer")
- procSetFileTime = modkernel32.NewProc("SetFileTime")
- procSetHandleInformation = modkernel32.NewProc("SetHandleInformation")
- procTerminateProcess = modkernel32.NewProc("TerminateProcess")
- procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile")
- procUpdateProcThreadAttribute = modkernel32.NewProc("UpdateProcThreadAttribute")
- procVirtualLock = modkernel32.NewProc("VirtualLock")
- procVirtualUnlock = modkernel32.NewProc("VirtualUnlock")
- procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject")
- procWriteConsoleW = modkernel32.NewProc("WriteConsoleW")
- procWriteFile = modkernel32.NewProc("WriteFile")
- procAcceptEx = modmswsock.NewProc("AcceptEx")
- procGetAcceptExSockaddrs = modmswsock.NewProc("GetAcceptExSockaddrs")
- procTransmitFile = modmswsock.NewProc("TransmitFile")
- procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree")
- procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation")
- procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo")
- procRtlGetNtVersionNumbers = modntdll.NewProc("RtlGetNtVersionNumbers")
- procGetUserNameExW = modsecur32.NewProc("GetUserNameExW")
- procTranslateNameW = modsecur32.NewProc("TranslateNameW")
- procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW")
- procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW")
- procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW")
- procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW")
- procWSACleanup = modws2_32.NewProc("WSACleanup")
- procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW")
- procWSAIoctl = modws2_32.NewProc("WSAIoctl")
- procWSARecv = modws2_32.NewProc("WSARecv")
- procWSARecvFrom = modws2_32.NewProc("WSARecvFrom")
- procWSASend = modws2_32.NewProc("WSASend")
- procWSASendTo = modws2_32.NewProc("WSASendTo")
- procWSAStartup = modws2_32.NewProc("WSAStartup")
- procbind = modws2_32.NewProc("bind")
- procclosesocket = modws2_32.NewProc("closesocket")
- procconnect = modws2_32.NewProc("connect")
- procgethostbyname = modws2_32.NewProc("gethostbyname")
- procgetpeername = modws2_32.NewProc("getpeername")
- procgetprotobyname = modws2_32.NewProc("getprotobyname")
- procgetservbyname = modws2_32.NewProc("getservbyname")
- procgetsockname = modws2_32.NewProc("getsockname")
- procgetsockopt = modws2_32.NewProc("getsockopt")
- proclisten = modws2_32.NewProc("listen")
- procntohs = modws2_32.NewProc("ntohs")
- procsetsockopt = modws2_32.NewProc("setsockopt")
- procshutdown = modws2_32.NewProc("shutdown")
- procsocket = modws2_32.NewProc("socket")
-)
-
-func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) {
- r1, _, e1 := Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) {
- r1, _, e1 := Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) {
- r1, _, e1 := Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid)))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) {
- var _p0 uint32
- if inheritHandles {
- _p0 = 1
- }
- r1, _, e1 := Syscall12(procCreateProcessAsUserW.Addr(), 11, uintptr(token), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) {
- r1, _, e1 := Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) {
- r1, _, e1 := Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf)))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CryptReleaseContext(provhandle Handle, flags uint32) (err error) {
- r1, _, e1 := Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetLengthSid(sid *SID) (len uint32) {
- r0, _, _ := Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
- len = uint32(r0)
- return
-}
-
-func GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) {
- r1, _, e1 := Syscall6(procGetTokenInformation.Addr(), 5, uintptr(t), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
- r1, _, e1 := Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
- r1, _, e1 := Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func OpenProcessToken(h Handle, access uint32, token *Token) (err error) {
- r1, _, e1 := Syscall(procOpenProcessToken.Addr(), 3, uintptr(h), uintptr(access), uintptr(unsafe.Pointer(token)))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func RegCloseKey(key Handle) (regerrno error) {
- r0, _, _ := Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0)
- if r0 != 0 {
- regerrno = Errno(r0)
- }
- return
-}
-
-func regEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) {
- r0, _, _ := Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0)
- if r0 != 0 {
- regerrno = Errno(r0)
- }
- return
-}
-
-func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) {
- r0, _, _ := Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0)
- if r0 != 0 {
- regerrno = Errno(r0)
- }
- return
-}
-
-func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) {
- r0, _, _ := Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime)))
- if r0 != 0 {
- regerrno = Errno(r0)
- }
- return
-}
-
-func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
- r0, _, _ := Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)))
- if r0 != 0 {
- regerrno = Errno(r0)
- }
- return
-}
-
-func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) {
- r1, _, e1 := Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CertCloseStore(store Handle, flags uint32) (err error) {
- r1, _, e1 := Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) {
- r0, _, e1 := Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen))
- context = (*CertContext)(unsafe.Pointer(r0))
- if context == nil {
- err = errnoErr(e1)
- }
- return
-}
-
-func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) {
- r0, _, e1 := Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0)
- context = (*CertContext)(unsafe.Pointer(r0))
- if context == nil {
- err = errnoErr(e1)
- }
- return
-}
-
-func CertFreeCertificateChain(ctx *CertChainContext) {
- Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
- return
-}
-
-func CertFreeCertificateContext(ctx *CertContext) (err error) {
- r1, _, e1 := Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) {
- r1, _, e1 := Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) {
- r0, _, e1 := Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0)
- handle = Handle(r0)
- if handle == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) {
- r0, _, e1 := Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0)
- store = Handle(r0)
- if store == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) {
- r1, _, e1 := Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) {
- r0, _, _ := Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0)
- same = r0 != 0
- return
-}
-
-func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
- var _p0 *uint16
- _p0, status = UTF16PtrFromString(name)
- if status != nil {
- return
- }
- return _DnsQuery(_p0, qtype, options, extra, qrs, pr)
-}
-
-func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
- r0, _, _ := Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
- if r0 != 0 {
- status = Errno(r0)
- }
- return
-}
-
-func DnsRecordListFree(rl *DNSRecord, freetype uint32) {
- Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0)
- return
-}
-
-func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) {
- r0, _, _ := Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0)
- if r0 != 0 {
- errcode = Errno(r0)
- }
- return
-}
-
-func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
- r0, _, _ := Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0)
- if r0 != 0 {
- errcode = Errno(r0)
- }
- return
-}
-
-func CancelIo(s Handle) (err error) {
- r1, _, e1 := Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CancelIoEx(s Handle, o *Overlapped) (err error) {
- r1, _, e1 := Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CloseHandle(handle Handle) (err error) {
- r1, _, e1 := Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) {
- r1, _, e1 := Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
- r0, _, e1 := Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
- handle = Handle(r0)
- if handle == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) {
- r0, _, e1 := Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
- handle = Handle(r0)
- if handle == InvalidHandle {
- err = errnoErr(e1)
- }
- return
-}
-
-func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) {
- r1, _, e1 := Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved))
- if r1&0xff == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-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 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) {
- r1, _, e1 := Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) {
- var _p0 uint32
- if inheritHandles {
- _p0 = 1
- }
- r1, _, e1 := Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) {
- r1, _, e1 := Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags))
- if r1&0xff == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) {
- r0, _, e1 := Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0)
- handle = Handle(r0)
- if handle == InvalidHandle {
- err = errnoErr(e1)
- }
- return
-}
-
-func DeleteFile(path *uint16) (err error) {
- r1, _, e1 := Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func deleteProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST) {
- Syscall(procDeleteProcThreadAttributeList.Addr(), 1, uintptr(unsafe.Pointer(attrlist)), 0, 0)
- return
-}
-
-func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) {
- r1, _, e1 := Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
- var _p0 uint32
- if bInheritHandle {
- _p0 = 1
- }
- r1, _, e1 := Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func ExitProcess(exitcode uint32) {
- Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0)
- return
-}
-
-func FindClose(handle Handle) (err error) {
- r1, _, e1 := Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) {
- r0, _, e1 := Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0)
- handle = Handle(r0)
- if handle == InvalidHandle {
- err = errnoErr(e1)
- }
- return
-}
-
-func findNextFile1(handle Handle, data *win32finddata1) (err error) {
- r1, _, e1 := Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func FlushFileBuffers(handle Handle) (err error) {
- r1, _, e1 := Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func FlushViewOfFile(addr uintptr, length uintptr) (err error) {
- r1, _, e1 := Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) {
- var _p0 *uint16
- if len(buf) > 0 {
- _p0 = &buf[0]
- }
- r0, _, e1 := Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0)
- n = uint32(r0)
- if n == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func FreeEnvironmentStrings(envs *uint16) (err error) {
- r1, _, e1 := Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func FreeLibrary(handle Handle) (err error) {
- r1, _, e1 := Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetCommandLine() (cmd *uint16) {
- r0, _, _ := Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0)
- cmd = (*uint16)(unsafe.Pointer(r0))
- return
-}
-
-func GetComputerName(buf *uint16, n *uint32) (err error) {
- r1, _, e1 := Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetConsoleMode(console Handle, mode *uint32) (err error) {
- r1, _, e1 := Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) {
- r0, _, e1 := Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
- n = uint32(r0)
- if n == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetCurrentProcess() (pseudoHandle Handle, err error) {
- r0, _, e1 := Syscall(procGetCurrentProcess.Addr(), 0, 0, 0, 0)
- pseudoHandle = Handle(r0)
- if pseudoHandle == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func getCurrentProcessId() (pid uint32) {
- r0, _, _ := Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0)
- pid = uint32(r0)
- return
-}
-
-func GetEnvironmentStrings() (envs *uint16, err error) {
- r0, _, e1 := Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0)
- envs = (*uint16)(unsafe.Pointer(r0))
- if envs == nil {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) {
- r0, _, e1 := Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size))
- n = uint32(r0)
- if n == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) {
- r1, _, e1 := Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) {
- r1, _, e1 := Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info)))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetFileAttributes(name *uint16) (attrs uint32, err error) {
- r0, _, e1 := Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
- attrs = uint32(r0)
- if attrs == INVALID_FILE_ATTRIBUTES {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) {
- r1, _, e1 := Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetFileType(filehandle Handle) (n uint32, err error) {
- r0, _, e1 := Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0)
- n = uint32(r0)
- if n == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) {
- r0, _, e1 := Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0)
- n = uint32(r0)
- if n == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetLastError() (lasterr error) {
- r0, _, _ := Syscall(procGetLastError.Addr(), 0, 0, 0, 0)
- if r0 != 0 {
- lasterr = Errno(r0)
- }
- return
-}
-
-func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) {
- r0, _, e1 := Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen))
- n = uint32(r0)
- if n == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetProcAddress(module Handle, procname string) (proc uintptr, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(procname)
- if err != nil {
- return
- }
- return _GetProcAddress(module, _p0)
-}
-
-func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) {
- r0, _, e1 := Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0)
- proc = uintptr(r0)
- if proc == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) {
- r1, _, e1 := Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-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 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) {
- r0, _, e1 := Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen))
- n = uint32(r0)
- if n == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetStartupInfo(startupInfo *StartupInfo) (err error) {
- r1, _, e1 := Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetStdHandle(stdhandle int) (handle Handle, err error) {
- r0, _, e1 := Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0)
- handle = Handle(r0)
- if handle == InvalidHandle {
- err = errnoErr(e1)
- }
- return
-}
-
-func getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) {
- r0, _, e1 := Syscall(procGetSystemDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(dirLen), 0)
- len = uint32(r0)
- if len == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetSystemTimeAsFileTime(time *Filetime) {
- Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0)
- return
-}
-
-func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) {
- r0, _, e1 := Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
- n = uint32(r0)
- if n == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) {
- r0, _, e1 := Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0)
- rc = uint32(r0)
- if rc == 0xffffffff {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetVersion() (ver uint32, err error) {
- r0, _, e1 := Syscall(procGetVersion.Addr(), 0, 0, 0, 0)
- ver = uint32(r0)
- if ver == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func initializeProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, attrcount uint32, flags uint32, size *uintptr) (err error) {
- r1, _, e1 := Syscall6(procInitializeProcThreadAttributeList.Addr(), 4, uintptr(unsafe.Pointer(attrlist)), uintptr(attrcount), uintptr(flags), uintptr(unsafe.Pointer(size)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func LoadLibrary(libname string) (handle Handle, err error) {
- var _p0 *uint16
- _p0, err = UTF16PtrFromString(libname)
- if err != nil {
- return
- }
- return _LoadLibrary(_p0)
-}
-
-func _LoadLibrary(libname *uint16) (handle Handle, err error) {
- r0, _, e1 := Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0)
- handle = Handle(r0)
- if handle == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func LocalFree(hmem Handle) (handle Handle, err error) {
- r0, _, e1 := Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0)
- handle = Handle(r0)
- if handle != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) {
- r0, _, e1 := Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0)
- addr = uintptr(r0)
- if addr == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func MoveFile(from *uint16, to *uint16) (err error) {
- r1, _, e1 := Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) {
- var _p0 uint32
- if inheritHandle {
- _p0 = 1
- }
- r0, _, e1 := Syscall(procOpenProcess.Addr(), 3, uintptr(da), uintptr(_p0), uintptr(pid))
- handle = Handle(r0)
- if handle == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-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 {
- err = errnoErr(e1)
- }
- return
-}
-
-func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) {
- r1, _, e1 := Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) {
- r1, _, e1 := Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) {
- r1, _, e1 := Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
- var _p0 uint32
- if watchSubTree {
- _p0 = 1
- }
- r1, _, e1 := Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
- var _p0 *byte
- if len(buf) > 0 {
- _p0 = &buf[0]
- }
- r1, _, e1 := Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func RemoveDirectory(path *uint16) (err error) {
- r1, _, e1 := Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func SetCurrentDirectory(path *uint16) (err error) {
- r1, _, e1 := Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func SetEndOfFile(handle Handle) (err error) {
- r1, _, e1 := Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func SetEnvironmentVariable(name *uint16, value *uint16) (err error) {
- r1, _, e1 := Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func SetFileAttributes(name *uint16, attrs uint32) (err error) {
- r1, _, e1 := Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) {
- r1, _, e1 := Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) {
- r0, _, e1 := Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0)
- newlowoffset = uint32(r0)
- if newlowoffset == 0xffffffff {
- err = errnoErr(e1)
- }
- return
-}
-
-func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) {
- r1, _, e1 := Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) {
- r1, _, e1 := Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func TerminateProcess(handle Handle, exitcode uint32) (err error) {
- r1, _, e1 := Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func UnmapViewOfFile(addr uintptr) (err error) {
- r1, _, e1 := Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func updateProcThreadAttribute(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) {
- r1, _, e1 := Syscall9(procUpdateProcThreadAttribute.Addr(), 7, uintptr(unsafe.Pointer(attrlist)), uintptr(flags), uintptr(attr), uintptr(value), uintptr(size), uintptr(prevvalue), uintptr(unsafe.Pointer(returnedsize)), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func VirtualLock(addr uintptr, length uintptr) (err error) {
- r1, _, e1 := Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func VirtualUnlock(addr uintptr, length uintptr) (err error) {
- r1, _, e1 := Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) {
- r0, _, e1 := Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0)
- event = uint32(r0)
- if event == 0xffffffff {
- err = errnoErr(e1)
- }
- return
-}
-
-func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) {
- r1, _, e1 := Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
- var _p0 *byte
- if len(buf) > 0 {
- _p0 = &buf[0]
- }
- r1, _, e1 := Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) {
- r1, _, e1 := Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) {
- Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0)
- return
-}
-
-func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) {
- r1, _, e1 := Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0)
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func NetApiBufferFree(buf *byte) (neterr error) {
- r0, _, _ := Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0)
- if r0 != 0 {
- neterr = Errno(r0)
- }
- return
-}
-
-func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) {
- r0, _, _ := Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType)))
- if r0 != 0 {
- neterr = Errno(r0)
- }
- return
-}
-
-func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
- r0, _, _ := Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
- if r0 != 0 {
- neterr = Errno(r0)
- }
- return
-}
-
-func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) {
- Syscall(procRtlGetNtVersionNumbers.Addr(), 3, uintptr(unsafe.Pointer(majorVersion)), uintptr(unsafe.Pointer(minorVersion)), uintptr(unsafe.Pointer(buildNumber)))
- return
-}
-
-func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) {
- r1, _, e1 := Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize)))
- if r1&0xff == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) {
- r1, _, e1 := Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0)
- if r1&0xff == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) {
- r0, _, e1 := Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0)
- argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0))
- if argv == nil {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) {
- r1, _, e1 := Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)))
- if r1 == 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-func FreeAddrInfoW(addrinfo *AddrinfoW) {
- Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0)
- return
-}
-
-func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) {
- r0, _, _ := Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0)
- if r0 != 0 {
- sockerr = Errno(r0)
- }
- return
-}
-
-func WSACleanup() (err error) {
- r1, _, e1 := Syscall(procWSACleanup.Addr(), 0, 0, 0, 0)
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) {
- r0, _, e1 := Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength)))
- n = int32(r0)
- if n == -1 {
- err = errnoErr(e1)
- }
- return
-}
-
-func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
- r1, _, e1 := Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine))
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) {
- r1, _, e1 := Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) {
- r1, _, e1 := Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) {
- r1, _, e1 := Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) {
- r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func WSAStartup(verreq uint32, data *WSAData) (sockerr error) {
- r0, _, _ := Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
- if r0 != 0 {
- sockerr = Errno(r0)
- }
- return
-}
-
-func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) {
- r1, _, e1 := Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func Closesocket(s Handle) (err error) {
- r1, _, e1 := Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0)
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) {
- r1, _, e1 := Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetHostByName(name string) (h *Hostent, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(name)
- if err != nil {
- return
- }
- return _GetHostByName(_p0)
-}
-
-func _GetHostByName(name *byte) (h *Hostent, err error) {
- r0, _, e1 := Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
- h = (*Hostent)(unsafe.Pointer(r0))
- if h == nil {
- err = errnoErr(e1)
- }
- return
-}
-
-func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
- r1, _, e1 := Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetProtoByName(name string) (p *Protoent, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(name)
- if err != nil {
- return
- }
- return _GetProtoByName(_p0)
-}
-
-func _GetProtoByName(name *byte) (p *Protoent, err error) {
- r0, _, e1 := Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
- p = (*Protoent)(unsafe.Pointer(r0))
- if p == nil {
- err = errnoErr(e1)
- }
- return
-}
-
-func GetServByName(name string, proto string) (s *Servent, err error) {
- var _p0 *byte
- _p0, err = BytePtrFromString(name)
- if err != nil {
- return
- }
- var _p1 *byte
- _p1, err = BytePtrFromString(proto)
- if err != nil {
- return
- }
- return _GetServByName(_p0, _p1)
-}
-
-func _GetServByName(name *byte, proto *byte) (s *Servent, err error) {
- r0, _, e1 := Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0)
- s = (*Servent)(unsafe.Pointer(r0))
- if s == nil {
- err = errnoErr(e1)
- }
- return
-}
-
-func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
- r1, _, e1 := Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) {
- r1, _, e1 := Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0)
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func listen(s Handle, backlog int32) (err error) {
- r1, _, e1 := Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0)
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func Ntohs(netshort uint16) (u uint16) {
- r0, _, _ := Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0)
- u = uint16(r0)
- return
-}
-
-func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) {
- r1, _, e1 := Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0)
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func shutdown(s Handle, how int32) (err error) {
- r1, _, e1 := Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0)
- if r1 == socket_error {
- err = errnoErr(e1)
- }
- return
-}
-
-func socket(af int32, typ int32, protocol int32) (handle Handle, err error) {
- r0, _, e1 := Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol))
- handle = Handle(r0)
- if handle == InvalidHandle {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/contrib/go/_std_1.20/src/testing/cover.go b/contrib/go/_std_1.20/src/testing/cover.go
deleted file mode 100644
index b52e53a926..0000000000
--- a/contrib/go/_std_1.20/src/testing/cover.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2013 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.
-
-// Support for test coverage.
-
-package testing
-
-import (
- "fmt"
- "internal/goexperiment"
- "os"
- "sync/atomic"
-)
-
-// CoverBlock records the coverage data for a single basic block.
-// The fields are 1-indexed, as in an editor: The opening line of
-// the file is number 1, for example. Columns are measured
-// in bytes.
-// NOTE: This struct is internal to the testing infrastructure and may change.
-// It is not covered (yet) by the Go 1 compatibility guidelines.
-type CoverBlock struct {
- Line0 uint32 // Line number for block start.
- Col0 uint16 // Column number for block start.
- Line1 uint32 // Line number for block end.
- Col1 uint16 // Column number for block end.
- Stmts uint16 // Number of statements included in this block.
-}
-
-var cover Cover
-
-// Cover records information about test coverage checking.
-// NOTE: This struct is internal to the testing infrastructure and may change.
-// It is not covered (yet) by the Go 1 compatibility guidelines.
-type Cover struct {
- Mode string
- Counters map[string][]uint32
- Blocks map[string][]CoverBlock
- CoveredPackages string
-}
-
-// Coverage reports the current code coverage as a fraction in the range [0, 1].
-// If coverage is not enabled, Coverage returns 0.
-//
-// When running a large set of sequential test cases, checking Coverage after each one
-// can be useful for identifying which test cases exercise new code paths.
-// It is not a replacement for the reports generated by 'go test -cover' and
-// 'go tool cover'.
-func Coverage() float64 {
- var n, d int64
- for _, counters := range cover.Counters {
- for i := range counters {
- if atomic.LoadUint32(&counters[i]) > 0 {
- n++
- }
- d++
- }
- }
- if d == 0 {
- return 0
- }
- return float64(n) / float64(d)
-}
-
-// RegisterCover records the coverage data accumulators for the tests.
-// NOTE: This function is internal to the testing infrastructure and may change.
-// It is not covered (yet) by the Go 1 compatibility guidelines.
-func RegisterCover(c Cover) {
- cover = c
-}
-
-// mustBeNil checks the error and, if present, reports it and exits.
-func mustBeNil(err error) {
- if err != nil {
- fmt.Fprintf(os.Stderr, "testing: %s\n", err)
- os.Exit(2)
- }
-}
-
-// coverReport reports the coverage percentage and writes a coverage profile if requested.
-func coverReport() {
- if goexperiment.CoverageRedesign {
- coverReport2()
- return
- }
- var f *os.File
- var err error
- if *coverProfile != "" {
- f, err = os.Create(toOutputDir(*coverProfile))
- mustBeNil(err)
- fmt.Fprintf(f, "mode: %s\n", cover.Mode)
- defer func() { mustBeNil(f.Close()) }()
- }
-
- var active, total int64
- var count uint32
- for name, counts := range cover.Counters {
- blocks := cover.Blocks[name]
- for i := range counts {
- stmts := int64(blocks[i].Stmts)
- total += stmts
- count = atomic.LoadUint32(&counts[i]) // For -mode=atomic.
- if count > 0 {
- active += stmts
- }
- if f != nil {
- _, err := fmt.Fprintf(f, "%s:%d.%d,%d.%d %d %d\n", name,
- blocks[i].Line0, blocks[i].Col0,
- blocks[i].Line1, blocks[i].Col1,
- stmts,
- count)
- mustBeNil(err)
- }
- }
- }
- if total == 0 {
- fmt.Println("coverage: [no statements]")
- return
- }
- fmt.Printf("coverage: %.1f%% of statements%s\n", 100*float64(active)/float64(total), cover.CoveredPackages)
-}
diff --git a/contrib/go/_std_1.20/src/testing/example.go b/contrib/go/_std_1.20/src/testing/example.go
deleted file mode 100644
index f618b06de1..0000000000
--- a/contrib/go/_std_1.20/src/testing/example.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2009 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 testing
-
-import (
- "fmt"
- "os"
- "sort"
- "strings"
- "time"
-)
-
-type InternalExample struct {
- Name string
- F func()
- Output string
- Unordered bool
-}
-
-// RunExamples is an internal function but exported because it is cross-package;
-// it is part of the implementation of the "go test" command.
-func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) {
- _, ok = runExamples(matchString, examples)
- return ok
-}
-
-func runExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ran, ok bool) {
- ok = true
-
- var eg InternalExample
-
- for _, eg = range examples {
- matched, err := matchString(*match, eg.Name)
- if err != nil {
- fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
- os.Exit(1)
- }
- if !matched {
- continue
- }
- ran = true
- if !runExample(eg) {
- ok = false
- }
- }
-
- return ran, ok
-}
-
-func sortLines(output string) string {
- lines := strings.Split(output, "\n")
- sort.Strings(lines)
- return strings.Join(lines, "\n")
-}
-
-// processRunResult computes a summary and status of the result of running an example test.
-// stdout is the captured output from stdout of the test.
-// recovered is the result of invoking recover after running the test, in case it panicked.
-//
-// If stdout doesn't match the expected output or if recovered is non-nil, it'll print the cause of failure to stdout.
-// If the test is chatty/verbose, it'll print a success message to stdout.
-// If recovered is non-nil, it'll panic with that value.
-// If the test panicked with nil, or invoked runtime.Goexit, it'll be
-// made to fail and panic with errNilPanicOrGoexit
-func (eg *InternalExample) processRunResult(stdout string, timeSpent time.Duration, finished bool, recovered any) (passed bool) {
- passed = true
- dstr := fmtDuration(timeSpent)
- var fail string
- got := strings.TrimSpace(stdout)
- want := strings.TrimSpace(eg.Output)
- if eg.Unordered {
- if sortLines(got) != sortLines(want) && recovered == nil {
- fail = fmt.Sprintf("got:\n%s\nwant (unordered):\n%s\n", stdout, eg.Output)
- }
- } else {
- if got != want && recovered == nil {
- fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", got, want)
- }
- }
- if fail != "" || !finished || recovered != nil {
- fmt.Printf("%s--- FAIL: %s (%s)\n%s", chatty.prefix(), eg.Name, dstr, fail)
- passed = false
- } else if chatty.on {
- fmt.Printf("%s--- PASS: %s (%s)\n", chatty.prefix(), eg.Name, dstr)
- }
-
- if chatty.on && chatty.json {
- fmt.Printf("%s=== NAME %s\n", chatty.prefix(), "")
- }
-
- if recovered != nil {
- // Propagate the previously recovered result, by panicking.
- panic(recovered)
- }
- if !finished && recovered == nil {
- panic(errNilPanicOrGoexit)
- }
-
- return
-}
diff --git a/contrib/go/_std_1.20/src/testing/fstest/mapfs.go b/contrib/go/_std_1.20/src/testing/fstest/mapfs.go
deleted file mode 100644
index 4595b7313d..0000000000
--- a/contrib/go/_std_1.20/src/testing/fstest/mapfs.go
+++ /dev/null
@@ -1,240 +0,0 @@
-// 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 fstest
-
-import (
- "io"
- "io/fs"
- "path"
- "sort"
- "strings"
- "time"
-)
-
-// A MapFS is a simple in-memory file system for use in tests,
-// represented as a map from path names (arguments to Open)
-// to information about the files or directories they represent.
-//
-// The map need not include parent directories for files contained
-// in the map; those will be synthesized if needed.
-// But a directory can still be included by setting the MapFile.Mode's ModeDir bit;
-// this may be necessary for detailed control over the directory's FileInfo
-// or to create an empty directory.
-//
-// File system operations read directly from the map,
-// so that the file system can be changed by editing the map as needed.
-// An implication is that file system operations must not run concurrently
-// with changes to the map, which would be a race.
-// Another implication is that opening or reading a directory requires
-// iterating over the entire map, so a MapFS should typically be used with not more
-// than a few hundred entries or directory reads.
-type MapFS map[string]*MapFile
-
-// A MapFile describes a single file in a MapFS.
-type MapFile struct {
- Data []byte // file content
- Mode fs.FileMode // FileInfo.Mode
- ModTime time.Time // FileInfo.ModTime
- Sys any // FileInfo.Sys
-}
-
-var _ fs.FS = MapFS(nil)
-var _ fs.File = (*openMapFile)(nil)
-
-// Open opens the named file.
-func (fsys MapFS) Open(name string) (fs.File, error) {
- if !fs.ValidPath(name) {
- return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
- }
- file := fsys[name]
- if file != nil && file.Mode&fs.ModeDir == 0 {
- // Ordinary file
- return &openMapFile{name, mapFileInfo{path.Base(name), file}, 0}, nil
- }
-
- // Directory, possibly synthesized.
- // Note that file can be nil here: the map need not contain explicit parent directories for all its files.
- // But file can also be non-nil, in case the user wants to set metadata for the directory explicitly.
- // Either way, we need to construct the list of children of this directory.
- var list []mapFileInfo
- var elem string
- var need = make(map[string]bool)
- if name == "." {
- elem = "."
- for fname, f := range fsys {
- i := strings.Index(fname, "/")
- if i < 0 {
- if fname != "." {
- list = append(list, mapFileInfo{fname, f})
- }
- } else {
- need[fname[:i]] = true
- }
- }
- } else {
- elem = name[strings.LastIndex(name, "/")+1:]
- prefix := name + "/"
- for fname, f := range fsys {
- if strings.HasPrefix(fname, prefix) {
- felem := fname[len(prefix):]
- i := strings.Index(felem, "/")
- if i < 0 {
- list = append(list, mapFileInfo{felem, f})
- } else {
- need[fname[len(prefix):len(prefix)+i]] = true
- }
- }
- }
- // If the directory name is not in the map,
- // and there are no children of the name in the map,
- // then the directory is treated as not existing.
- if file == nil && list == nil && len(need) == 0 {
- return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
- }
- }
- for _, fi := range list {
- delete(need, fi.name)
- }
- for name := range need {
- list = append(list, mapFileInfo{name, &MapFile{Mode: fs.ModeDir}})
- }
- sort.Slice(list, func(i, j int) bool {
- return list[i].name < list[j].name
- })
-
- if file == nil {
- file = &MapFile{Mode: fs.ModeDir}
- }
- return &mapDir{name, mapFileInfo{elem, file}, list, 0}, nil
-}
-
-// fsOnly is a wrapper that hides all but the fs.FS methods,
-// to avoid an infinite recursion when implementing special
-// methods in terms of helpers that would use them.
-// (In general, implementing these methods using the package fs helpers
-// is redundant and unnecessary, but having the methods may make
-// MapFS exercise more code paths when used in tests.)
-type fsOnly struct{ fs.FS }
-
-func (fsys MapFS) ReadFile(name string) ([]byte, error) {
- return fs.ReadFile(fsOnly{fsys}, name)
-}
-
-func (fsys MapFS) Stat(name string) (fs.FileInfo, error) {
- return fs.Stat(fsOnly{fsys}, name)
-}
-
-func (fsys MapFS) ReadDir(name string) ([]fs.DirEntry, error) {
- return fs.ReadDir(fsOnly{fsys}, name)
-}
-
-func (fsys MapFS) Glob(pattern string) ([]string, error) {
- return fs.Glob(fsOnly{fsys}, pattern)
-}
-
-type noSub struct {
- MapFS
-}
-
-func (noSub) Sub() {} // not the fs.SubFS signature
-
-func (fsys MapFS) Sub(dir string) (fs.FS, error) {
- return fs.Sub(noSub{fsys}, dir)
-}
-
-// A mapFileInfo implements fs.FileInfo and fs.DirEntry for a given map file.
-type mapFileInfo struct {
- name string
- f *MapFile
-}
-
-func (i *mapFileInfo) Name() string { return i.name }
-func (i *mapFileInfo) Size() int64 { return int64(len(i.f.Data)) }
-func (i *mapFileInfo) Mode() fs.FileMode { return i.f.Mode }
-func (i *mapFileInfo) Type() fs.FileMode { return i.f.Mode.Type() }
-func (i *mapFileInfo) ModTime() time.Time { return i.f.ModTime }
-func (i *mapFileInfo) IsDir() bool { return i.f.Mode&fs.ModeDir != 0 }
-func (i *mapFileInfo) Sys() any { return i.f.Sys }
-func (i *mapFileInfo) Info() (fs.FileInfo, error) { return i, nil }
-
-// An openMapFile is a regular (non-directory) fs.File open for reading.
-type openMapFile struct {
- path string
- mapFileInfo
- offset int64
-}
-
-func (f *openMapFile) Stat() (fs.FileInfo, error) { return &f.mapFileInfo, nil }
-
-func (f *openMapFile) Close() error { return nil }
-
-func (f *openMapFile) Read(b []byte) (int, error) {
- if f.offset >= int64(len(f.f.Data)) {
- return 0, io.EOF
- }
- if f.offset < 0 {
- return 0, &fs.PathError{Op: "read", Path: f.path, Err: fs.ErrInvalid}
- }
- n := copy(b, f.f.Data[f.offset:])
- f.offset += int64(n)
- return n, nil
-}
-
-func (f *openMapFile) Seek(offset int64, whence int) (int64, error) {
- switch whence {
- case 0:
- // offset += 0
- case 1:
- offset += f.offset
- case 2:
- offset += int64(len(f.f.Data))
- }
- if offset < 0 || offset > int64(len(f.f.Data)) {
- return 0, &fs.PathError{Op: "seek", Path: f.path, Err: fs.ErrInvalid}
- }
- f.offset = offset
- return offset, nil
-}
-
-func (f *openMapFile) ReadAt(b []byte, offset int64) (int, error) {
- if offset < 0 || offset > int64(len(f.f.Data)) {
- return 0, &fs.PathError{Op: "read", Path: f.path, Err: fs.ErrInvalid}
- }
- n := copy(b, f.f.Data[offset:])
- if n < len(b) {
- return n, io.EOF
- }
- return n, nil
-}
-
-// A mapDir is a directory fs.File (so also an fs.ReadDirFile) open for reading.
-type mapDir struct {
- path string
- mapFileInfo
- entry []mapFileInfo
- offset int
-}
-
-func (d *mapDir) Stat() (fs.FileInfo, error) { return &d.mapFileInfo, nil }
-func (d *mapDir) Close() error { return nil }
-func (d *mapDir) Read(b []byte) (int, error) {
- return 0, &fs.PathError{Op: "read", Path: d.path, Err: fs.ErrInvalid}
-}
-
-func (d *mapDir) ReadDir(count int) ([]fs.DirEntry, error) {
- n := len(d.entry) - d.offset
- if n == 0 && count > 0 {
- return nil, io.EOF
- }
- if count > 0 && n > count {
- n = count
- }
- list := make([]fs.DirEntry, n)
- for i := range list {
- list[i] = &d.entry[d.offset+i]
- }
- d.offset += n
- return list, nil
-}
diff --git a/contrib/go/_std_1.20/src/testing/fstest/testfs.go b/contrib/go/_std_1.20/src/testing/fstest/testfs.go
deleted file mode 100644
index ddb6080882..0000000000
--- a/contrib/go/_std_1.20/src/testing/fstest/testfs.go
+++ /dev/null
@@ -1,624 +0,0 @@
-// 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 fstest implements support for testing implementations and users of file systems.
-package fstest
-
-import (
- "errors"
- "fmt"
- "io"
- "io/fs"
- "path"
- "reflect"
- "sort"
- "strings"
- "testing/iotest"
-)
-
-// TestFS tests a file system implementation.
-// It walks the entire tree of files in fsys,
-// opening and checking that each file behaves correctly.
-// It also checks that the file system contains at least the expected files.
-// As a special case, if no expected files are listed, fsys must be empty.
-// Otherwise, fsys must contain at least the listed files; it can also contain others.
-// The contents of fsys must not change concurrently with TestFS.
-//
-// If TestFS finds any misbehaviors, it returns an error reporting all of them.
-// The error text spans multiple lines, one per detected misbehavior.
-//
-// Typical usage inside a test is:
-//
-// if err := fstest.TestFS(myFS, "file/that/should/be/present"); err != nil {
-// t.Fatal(err)
-// }
-func TestFS(fsys fs.FS, expected ...string) error {
- if err := testFS(fsys, expected...); err != nil {
- return err
- }
- for _, name := range expected {
- if i := strings.Index(name, "/"); i >= 0 {
- dir, dirSlash := name[:i], name[:i+1]
- var subExpected []string
- for _, name := range expected {
- if strings.HasPrefix(name, dirSlash) {
- subExpected = append(subExpected, name[len(dirSlash):])
- }
- }
- sub, err := fs.Sub(fsys, dir)
- if err != nil {
- return err
- }
- if err := testFS(sub, subExpected...); err != nil {
- return fmt.Errorf("testing fs.Sub(fsys, %s): %v", dir, err)
- }
- break // one sub-test is enough
- }
- }
- return nil
-}
-
-func testFS(fsys fs.FS, expected ...string) error {
- t := fsTester{fsys: fsys}
- t.checkDir(".")
- t.checkOpen(".")
- found := make(map[string]bool)
- for _, dir := range t.dirs {
- found[dir] = true
- }
- for _, file := range t.files {
- found[file] = true
- }
- delete(found, ".")
- if len(expected) == 0 && len(found) > 0 {
- var list []string
- for k := range found {
- if k != "." {
- list = append(list, k)
- }
- }
- sort.Strings(list)
- if len(list) > 15 {
- list = append(list[:10], "...")
- }
- t.errorf("expected empty file system but found files:\n%s", strings.Join(list, "\n"))
- }
- for _, name := range expected {
- if !found[name] {
- t.errorf("expected but not found: %s", name)
- }
- }
- if len(t.errText) == 0 {
- return nil
- }
- return errors.New("TestFS found errors:\n" + string(t.errText))
-}
-
-// An fsTester holds state for running the test.
-type fsTester struct {
- fsys fs.FS
- errText []byte
- dirs []string
- files []string
-}
-
-// errorf adds an error line to errText.
-func (t *fsTester) errorf(format string, args ...any) {
- if len(t.errText) > 0 {
- t.errText = append(t.errText, '\n')
- }
- t.errText = append(t.errText, fmt.Sprintf(format, args...)...)
-}
-
-func (t *fsTester) openDir(dir string) fs.ReadDirFile {
- f, err := t.fsys.Open(dir)
- if err != nil {
- t.errorf("%s: Open: %v", dir, err)
- return nil
- }
- d, ok := f.(fs.ReadDirFile)
- if !ok {
- f.Close()
- t.errorf("%s: Open returned File type %T, not a fs.ReadDirFile", dir, f)
- return nil
- }
- return d
-}
-
-// checkDir checks the directory dir, which is expected to exist
-// (it is either the root or was found in a directory listing with IsDir true).
-func (t *fsTester) checkDir(dir string) {
- // Read entire directory.
- t.dirs = append(t.dirs, dir)
- d := t.openDir(dir)
- if d == nil {
- return
- }
- list, err := d.ReadDir(-1)
- if err != nil {
- d.Close()
- t.errorf("%s: ReadDir(-1): %v", dir, err)
- return
- }
-
- // Check all children.
- var prefix string
- if dir == "." {
- prefix = ""
- } else {
- prefix = dir + "/"
- }
- for _, info := range list {
- name := info.Name()
- switch {
- case name == ".", name == "..", name == "":
- t.errorf("%s: ReadDir: child has invalid name: %#q", dir, name)
- continue
- case strings.Contains(name, "/"):
- t.errorf("%s: ReadDir: child name contains slash: %#q", dir, name)
- continue
- case strings.Contains(name, `\`):
- t.errorf("%s: ReadDir: child name contains backslash: %#q", dir, name)
- continue
- }
- path := prefix + name
- t.checkStat(path, info)
- t.checkOpen(path)
- if info.IsDir() {
- t.checkDir(path)
- } else {
- t.checkFile(path)
- }
- }
-
- // Check ReadDir(-1) at EOF.
- list2, err := d.ReadDir(-1)
- if len(list2) > 0 || err != nil {
- d.Close()
- t.errorf("%s: ReadDir(-1) at EOF = %d entries, %v, wanted 0 entries, nil", dir, len(list2), err)
- return
- }
-
- // Check ReadDir(1) at EOF (different results).
- list2, err = d.ReadDir(1)
- if len(list2) > 0 || err != io.EOF {
- d.Close()
- t.errorf("%s: ReadDir(1) at EOF = %d entries, %v, wanted 0 entries, EOF", dir, len(list2), err)
- return
- }
-
- // Check that close does not report an error.
- if err := d.Close(); err != nil {
- t.errorf("%s: Close: %v", dir, err)
- }
-
- // Check that closing twice doesn't crash.
- // The return value doesn't matter.
- d.Close()
-
- // Reopen directory, read a second time, make sure contents match.
- if d = t.openDir(dir); d == nil {
- return
- }
- defer d.Close()
- list2, err = d.ReadDir(-1)
- if err != nil {
- t.errorf("%s: second Open+ReadDir(-1): %v", dir, err)
- return
- }
- t.checkDirList(dir, "first Open+ReadDir(-1) vs second Open+ReadDir(-1)", list, list2)
-
- // Reopen directory, read a third time in pieces, make sure contents match.
- if d = t.openDir(dir); d == nil {
- return
- }
- defer d.Close()
- list2 = nil
- for {
- n := 1
- if len(list2) > 0 {
- n = 2
- }
- frag, err := d.ReadDir(n)
- if len(frag) > n {
- t.errorf("%s: third Open: ReadDir(%d) after %d: %d entries (too many)", dir, n, len(list2), len(frag))
- return
- }
- list2 = append(list2, frag...)
- if err == io.EOF {
- break
- }
- if err != nil {
- t.errorf("%s: third Open: ReadDir(%d) after %d: %v", dir, n, len(list2), err)
- return
- }
- if n == 0 {
- t.errorf("%s: third Open: ReadDir(%d) after %d: 0 entries but nil error", dir, n, len(list2))
- return
- }
- }
- t.checkDirList(dir, "first Open+ReadDir(-1) vs third Open+ReadDir(1,2) loop", list, list2)
-
- // If fsys has ReadDir, check that it matches and is sorted.
- if fsys, ok := t.fsys.(fs.ReadDirFS); ok {
- list2, err := fsys.ReadDir(dir)
- if err != nil {
- t.errorf("%s: fsys.ReadDir: %v", dir, err)
- return
- }
- t.checkDirList(dir, "first Open+ReadDir(-1) vs fsys.ReadDir", list, list2)
-
- for i := 0; i+1 < len(list2); i++ {
- if list2[i].Name() >= list2[i+1].Name() {
- t.errorf("%s: fsys.ReadDir: list not sorted: %s before %s", dir, list2[i].Name(), list2[i+1].Name())
- }
- }
- }
-
- // Check fs.ReadDir as well.
- list2, err = fs.ReadDir(t.fsys, dir)
- if err != nil {
- t.errorf("%s: fs.ReadDir: %v", dir, err)
- return
- }
- t.checkDirList(dir, "first Open+ReadDir(-1) vs fs.ReadDir", list, list2)
-
- for i := 0; i+1 < len(list2); i++ {
- if list2[i].Name() >= list2[i+1].Name() {
- t.errorf("%s: fs.ReadDir: list not sorted: %s before %s", dir, list2[i].Name(), list2[i+1].Name())
- }
- }
-
- t.checkGlob(dir, list)
-}
-
-// formatEntry formats an fs.DirEntry into a string for error messages and comparison.
-func formatEntry(entry fs.DirEntry) string {
- return fmt.Sprintf("%s IsDir=%v Type=%v", entry.Name(), entry.IsDir(), entry.Type())
-}
-
-// formatInfoEntry formats an fs.FileInfo into a string like the result of formatEntry, for error messages and comparison.
-func formatInfoEntry(info fs.FileInfo) string {
- return fmt.Sprintf("%s IsDir=%v Type=%v", info.Name(), info.IsDir(), info.Mode().Type())
-}
-
-// formatInfo formats an fs.FileInfo into a string for error messages and comparison.
-func formatInfo(info fs.FileInfo) string {
- return fmt.Sprintf("%s IsDir=%v Mode=%v Size=%d ModTime=%v", info.Name(), info.IsDir(), info.Mode(), info.Size(), info.ModTime())
-}
-
-// checkGlob checks that various glob patterns work if the file system implements GlobFS.
-func (t *fsTester) checkGlob(dir string, list []fs.DirEntry) {
- if _, ok := t.fsys.(fs.GlobFS); !ok {
- return
- }
-
- // Make a complex glob pattern prefix that only matches dir.
- var glob string
- if dir != "." {
- elem := strings.Split(dir, "/")
- for i, e := range elem {
- var pattern []rune
- for j, r := range e {
- if r == '*' || r == '?' || r == '\\' || r == '[' || r == '-' {
- pattern = append(pattern, '\\', r)
- continue
- }
- switch (i + j) % 5 {
- case 0:
- pattern = append(pattern, r)
- case 1:
- pattern = append(pattern, '[', r, ']')
- case 2:
- pattern = append(pattern, '[', r, '-', r, ']')
- case 3:
- pattern = append(pattern, '[', '\\', r, ']')
- case 4:
- pattern = append(pattern, '[', '\\', r, '-', '\\', r, ']')
- }
- }
- elem[i] = string(pattern)
- }
- glob = strings.Join(elem, "/") + "/"
- }
-
- // Test that malformed patterns are detected.
- // The error is likely path.ErrBadPattern but need not be.
- if _, err := t.fsys.(fs.GlobFS).Glob(glob + "nonexist/[]"); err == nil {
- t.errorf("%s: Glob(%#q): bad pattern not detected", dir, glob+"nonexist/[]")
- }
-
- // Try to find a letter that appears in only some of the final names.
- c := rune('a')
- for ; c <= 'z'; c++ {
- have, haveNot := false, false
- for _, d := range list {
- if strings.ContainsRune(d.Name(), c) {
- have = true
- } else {
- haveNot = true
- }
- }
- if have && haveNot {
- break
- }
- }
- if c > 'z' {
- c = 'a'
- }
- glob += "*" + string(c) + "*"
-
- var want []string
- for _, d := range list {
- if strings.ContainsRune(d.Name(), c) {
- want = append(want, path.Join(dir, d.Name()))
- }
- }
-
- names, err := t.fsys.(fs.GlobFS).Glob(glob)
- if err != nil {
- t.errorf("%s: Glob(%#q): %v", dir, glob, err)
- return
- }
- if reflect.DeepEqual(want, names) {
- return
- }
-
- if !sort.StringsAreSorted(names) {
- t.errorf("%s: Glob(%#q): unsorted output:\n%s", dir, glob, strings.Join(names, "\n"))
- sort.Strings(names)
- }
-
- var problems []string
- for len(want) > 0 || len(names) > 0 {
- switch {
- case len(want) > 0 && len(names) > 0 && want[0] == names[0]:
- want, names = want[1:], names[1:]
- case len(want) > 0 && (len(names) == 0 || want[0] < names[0]):
- problems = append(problems, "missing: "+want[0])
- want = want[1:]
- default:
- problems = append(problems, "extra: "+names[0])
- names = names[1:]
- }
- }
- t.errorf("%s: Glob(%#q): wrong output:\n%s", dir, glob, strings.Join(problems, "\n"))
-}
-
-// checkStat checks that a direct stat of path matches entry,
-// which was found in the parent's directory listing.
-func (t *fsTester) checkStat(path string, entry fs.DirEntry) {
- file, err := t.fsys.Open(path)
- if err != nil {
- t.errorf("%s: Open: %v", path, err)
- return
- }
- info, err := file.Stat()
- file.Close()
- if err != nil {
- t.errorf("%s: Stat: %v", path, err)
- return
- }
- fentry := formatEntry(entry)
- fientry := formatInfoEntry(info)
- // Note: mismatch here is OK for symlink, because Open dereferences symlink.
- if fentry != fientry && entry.Type()&fs.ModeSymlink == 0 {
- t.errorf("%s: mismatch:\n\tentry = %s\n\tfile.Stat() = %s", path, fentry, fientry)
- }
-
- einfo, err := entry.Info()
- if err != nil {
- t.errorf("%s: entry.Info: %v", path, err)
- return
- }
- finfo := formatInfo(info)
- if entry.Type()&fs.ModeSymlink != 0 {
- // For symlink, just check that entry.Info matches entry on common fields.
- // Open deferences symlink, so info itself may differ.
- feentry := formatInfoEntry(einfo)
- if fentry != feentry {
- t.errorf("%s: mismatch\n\tentry = %s\n\tentry.Info() = %s\n", path, fentry, feentry)
- }
- } else {
- feinfo := formatInfo(einfo)
- if feinfo != finfo {
- t.errorf("%s: mismatch:\n\tentry.Info() = %s\n\tfile.Stat() = %s\n", path, feinfo, finfo)
- }
- }
-
- // Stat should be the same as Open+Stat, even for symlinks.
- info2, err := fs.Stat(t.fsys, path)
- if err != nil {
- t.errorf("%s: fs.Stat: %v", path, err)
- return
- }
- finfo2 := formatInfo(info2)
- if finfo2 != finfo {
- t.errorf("%s: fs.Stat(...) = %s\n\twant %s", path, finfo2, finfo)
- }
-
- if fsys, ok := t.fsys.(fs.StatFS); ok {
- info2, err := fsys.Stat(path)
- if err != nil {
- t.errorf("%s: fsys.Stat: %v", path, err)
- return
- }
- finfo2 := formatInfo(info2)
- if finfo2 != finfo {
- t.errorf("%s: fsys.Stat(...) = %s\n\twant %s", path, finfo2, finfo)
- }
- }
-}
-
-// checkDirList checks that two directory lists contain the same files and file info.
-// The order of the lists need not match.
-func (t *fsTester) checkDirList(dir, desc string, list1, list2 []fs.DirEntry) {
- old := make(map[string]fs.DirEntry)
- checkMode := func(entry fs.DirEntry) {
- if entry.IsDir() != (entry.Type()&fs.ModeDir != 0) {
- if entry.IsDir() {
- t.errorf("%s: ReadDir returned %s with IsDir() = true, Type() & ModeDir = 0", dir, entry.Name())
- } else {
- t.errorf("%s: ReadDir returned %s with IsDir() = false, Type() & ModeDir = ModeDir", dir, entry.Name())
- }
- }
- }
-
- for _, entry1 := range list1 {
- old[entry1.Name()] = entry1
- checkMode(entry1)
- }
-
- var diffs []string
- for _, entry2 := range list2 {
- entry1 := old[entry2.Name()]
- if entry1 == nil {
- checkMode(entry2)
- diffs = append(diffs, "+ "+formatEntry(entry2))
- continue
- }
- if formatEntry(entry1) != formatEntry(entry2) {
- diffs = append(diffs, "- "+formatEntry(entry1), "+ "+formatEntry(entry2))
- }
- delete(old, entry2.Name())
- }
- for _, entry1 := range old {
- diffs = append(diffs, "- "+formatEntry(entry1))
- }
-
- if len(diffs) == 0 {
- return
- }
-
- sort.Slice(diffs, func(i, j int) bool {
- fi := strings.Fields(diffs[i])
- fj := strings.Fields(diffs[j])
- // sort by name (i < j) and then +/- (j < i, because + < -)
- return fi[1]+" "+fj[0] < fj[1]+" "+fi[0]
- })
-
- t.errorf("%s: diff %s:\n\t%s", dir, desc, strings.Join(diffs, "\n\t"))
-}
-
-// checkFile checks that basic file reading works correctly.
-func (t *fsTester) checkFile(file string) {
- t.files = append(t.files, file)
-
- // Read entire file.
- f, err := t.fsys.Open(file)
- if err != nil {
- t.errorf("%s: Open: %v", file, err)
- return
- }
-
- data, err := io.ReadAll(f)
- if err != nil {
- f.Close()
- t.errorf("%s: Open+ReadAll: %v", file, err)
- return
- }
-
- if err := f.Close(); err != nil {
- t.errorf("%s: Close: %v", file, err)
- }
-
- // Check that closing twice doesn't crash.
- // The return value doesn't matter.
- f.Close()
-
- // Check that ReadFile works if present.
- if fsys, ok := t.fsys.(fs.ReadFileFS); ok {
- data2, err := fsys.ReadFile(file)
- if err != nil {
- t.errorf("%s: fsys.ReadFile: %v", file, err)
- return
- }
- t.checkFileRead(file, "ReadAll vs fsys.ReadFile", data, data2)
-
- // Modify the data and check it again. Modifying the
- // returned byte slice should not affect the next call.
- for i := range data2 {
- data2[i]++
- }
- data2, err = fsys.ReadFile(file)
- if err != nil {
- t.errorf("%s: second call to fsys.ReadFile: %v", file, err)
- return
- }
- t.checkFileRead(file, "Readall vs second fsys.ReadFile", data, data2)
-
- t.checkBadPath(file, "ReadFile",
- func(name string) error { _, err := fsys.ReadFile(name); return err })
- }
-
- // Check that fs.ReadFile works with t.fsys.
- data2, err := fs.ReadFile(t.fsys, file)
- if err != nil {
- t.errorf("%s: fs.ReadFile: %v", file, err)
- return
- }
- t.checkFileRead(file, "ReadAll vs fs.ReadFile", data, data2)
-
- // Use iotest.TestReader to check small reads, Seek, ReadAt.
- f, err = t.fsys.Open(file)
- if err != nil {
- t.errorf("%s: second Open: %v", file, err)
- return
- }
- defer f.Close()
- if err := iotest.TestReader(f, data); err != nil {
- t.errorf("%s: failed TestReader:\n\t%s", file, strings.ReplaceAll(err.Error(), "\n", "\n\t"))
- }
-}
-
-func (t *fsTester) checkFileRead(file, desc string, data1, data2 []byte) {
- if string(data1) != string(data2) {
- t.errorf("%s: %s: different data returned\n\t%q\n\t%q", file, desc, data1, data2)
- return
- }
-}
-
-// checkBadPath checks that various invalid forms of file's name cannot be opened using t.fsys.Open.
-func (t *fsTester) checkOpen(file string) {
- t.checkBadPath(file, "Open", func(file string) error {
- f, err := t.fsys.Open(file)
- if err == nil {
- f.Close()
- }
- return err
- })
-}
-
-// checkBadPath checks that various invalid forms of file's name cannot be opened using open.
-func (t *fsTester) checkBadPath(file string, desc string, open func(string) error) {
- bad := []string{
- "/" + file,
- file + "/.",
- }
- if file == "." {
- bad = append(bad, "/")
- }
- if i := strings.Index(file, "/"); i >= 0 {
- bad = append(bad,
- file[:i]+"//"+file[i+1:],
- file[:i]+"/./"+file[i+1:],
- file[:i]+`\`+file[i+1:],
- file[:i]+"/../"+file,
- )
- }
- if i := strings.LastIndex(file, "/"); i >= 0 {
- bad = append(bad,
- file[:i]+"//"+file[i+1:],
- file[:i]+"/./"+file[i+1:],
- file[:i]+`\`+file[i+1:],
- file+"/../"+file[i+1:],
- )
- }
-
- for _, b := range bad {
- if err := open(b); err == nil {
- t.errorf("%s: %s(%s) succeeded, want error", file, desc, b)
- }
- }
-}
diff --git a/contrib/go/_std_1.20/src/testing/fstest/ya.make b/contrib/go/_std_1.20/src/testing/fstest/ya.make
deleted file mode 100644
index 4c5d70fc5a..0000000000
--- a/contrib/go/_std_1.20/src/testing/fstest/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- mapfs.go
- testfs.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/testing/iotest/ya.make b/contrib/go/_std_1.20/src/testing/iotest/ya.make
deleted file mode 100644
index 1ad494e5f8..0000000000
--- a/contrib/go/_std_1.20/src/testing/iotest/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- logger.go
- reader.go
- writer.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/testing/newcover.go b/contrib/go/_std_1.20/src/testing/newcover.go
deleted file mode 100644
index 1805f791e6..0000000000
--- a/contrib/go/_std_1.20/src/testing/newcover.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2022 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.
-
-// Support for test coverage with redesigned coverage implementation.
-
-package testing
-
-import (
- "fmt"
- "internal/goexperiment"
- "os"
-)
-
-// cover2 variable stores the current coverage mode and a
-// tear-down function to be called at the end of the testing run.
-var cover2 struct {
- mode string
- tearDown func(coverprofile string, gocoverdir string) (string, error)
-}
-
-// registerCover2 is invoked during "go test -cover" runs by the test harness
-// code in _testmain.go; it is used to record a 'tear down' function
-// (to be called when the test is complete) and the coverage mode.
-func registerCover2(mode string, tearDown func(coverprofile string, gocoverdir string) (string, error)) {
- cover2.mode = mode
- cover2.tearDown = tearDown
-}
-
-// coverReport2 invokes a callback in _testmain.go that will
-// emit coverage data at the point where test execution is complete,
-// for "go test -cover" runs.
-func coverReport2() {
- if !goexperiment.CoverageRedesign {
- panic("unexpected")
- }
- if errmsg, err := cover2.tearDown(*coverProfile, *gocoverdir); err != nil {
- fmt.Fprintf(os.Stderr, "%s: %v\n", errmsg, err)
- os.Exit(2)
- }
-}
-
-// testGoCoverDir returns the value passed to the -test.gocoverdir
-// flag by the Go command, if goexperiment.CoverageRedesign is
-// in effect.
-func testGoCoverDir() string {
- return *gocoverdir
-}
diff --git a/contrib/go/_std_1.20/src/testing/quick/quick.go b/contrib/go/_std_1.20/src/testing/quick/quick.go
deleted file mode 100644
index 95a635bade..0000000000
--- a/contrib/go/_std_1.20/src/testing/quick/quick.go
+++ /dev/null
@@ -1,385 +0,0 @@
-// Copyright 2009 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 quick implements utility functions to help with black box testing.
-//
-// The testing/quick package is frozen and is not accepting new features.
-package quick
-
-import (
- "flag"
- "fmt"
- "math"
- "math/rand"
- "reflect"
- "strings"
- "time"
-)
-
-var defaultMaxCount *int = flag.Int("quickchecks", 100, "The default number of iterations for each check")
-
-// A Generator can generate random values of its own type.
-type Generator interface {
- // Generate returns a random instance of the type on which it is a
- // method using the size as a size hint.
- Generate(rand *rand.Rand, size int) reflect.Value
-}
-
-// randFloat32 generates a random float taking the full range of a float32.
-func randFloat32(rand *rand.Rand) float32 {
- f := rand.Float64() * math.MaxFloat32
- if rand.Int()&1 == 1 {
- f = -f
- }
- return float32(f)
-}
-
-// randFloat64 generates a random float taking the full range of a float64.
-func randFloat64(rand *rand.Rand) float64 {
- f := rand.Float64() * math.MaxFloat64
- if rand.Int()&1 == 1 {
- f = -f
- }
- return f
-}
-
-// randInt64 returns a random int64.
-func randInt64(rand *rand.Rand) int64 {
- return int64(rand.Uint64())
-}
-
-// complexSize is the maximum length of arbitrary values that contain other
-// values.
-const complexSize = 50
-
-// Value returns an arbitrary value of the given type.
-// If the type implements the Generator interface, that will be used.
-// Note: To create arbitrary values for structs, all the fields must be exported.
-func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) {
- return sizedValue(t, rand, complexSize)
-}
-
-// sizedValue returns an arbitrary value of the given type. The size
-// hint is used for shrinking as a function of indirection level so
-// that recursive data structures will terminate.
-func sizedValue(t reflect.Type, rand *rand.Rand, size int) (value reflect.Value, ok bool) {
- if m, ok := reflect.Zero(t).Interface().(Generator); ok {
- return m.Generate(rand, size), true
- }
-
- v := reflect.New(t).Elem()
- switch concrete := t; concrete.Kind() {
- case reflect.Bool:
- v.SetBool(rand.Int()&1 == 0)
- case reflect.Float32:
- v.SetFloat(float64(randFloat32(rand)))
- case reflect.Float64:
- v.SetFloat(randFloat64(rand))
- case reflect.Complex64:
- v.SetComplex(complex(float64(randFloat32(rand)), float64(randFloat32(rand))))
- case reflect.Complex128:
- v.SetComplex(complex(randFloat64(rand), randFloat64(rand)))
- case reflect.Int16:
- v.SetInt(randInt64(rand))
- case reflect.Int32:
- v.SetInt(randInt64(rand))
- case reflect.Int64:
- v.SetInt(randInt64(rand))
- case reflect.Int8:
- v.SetInt(randInt64(rand))
- case reflect.Int:
- v.SetInt(randInt64(rand))
- case reflect.Uint16:
- v.SetUint(uint64(randInt64(rand)))
- case reflect.Uint32:
- v.SetUint(uint64(randInt64(rand)))
- case reflect.Uint64:
- v.SetUint(uint64(randInt64(rand)))
- case reflect.Uint8:
- v.SetUint(uint64(randInt64(rand)))
- case reflect.Uint:
- v.SetUint(uint64(randInt64(rand)))
- case reflect.Uintptr:
- v.SetUint(uint64(randInt64(rand)))
- case reflect.Map:
- numElems := rand.Intn(size)
- v.Set(reflect.MakeMap(concrete))
- for i := 0; i < numElems; i++ {
- key, ok1 := sizedValue(concrete.Key(), rand, size)
- value, ok2 := sizedValue(concrete.Elem(), rand, size)
- if !ok1 || !ok2 {
- return reflect.Value{}, false
- }
- v.SetMapIndex(key, value)
- }
- case reflect.Pointer:
- if rand.Intn(size) == 0 {
- v.Set(reflect.Zero(concrete)) // Generate nil pointer.
- } else {
- elem, ok := sizedValue(concrete.Elem(), rand, size)
- if !ok {
- return reflect.Value{}, false
- }
- v.Set(reflect.New(concrete.Elem()))
- v.Elem().Set(elem)
- }
- case reflect.Slice:
- numElems := rand.Intn(size)
- sizeLeft := size - numElems
- v.Set(reflect.MakeSlice(concrete, numElems, numElems))
- for i := 0; i < numElems; i++ {
- elem, ok := sizedValue(concrete.Elem(), rand, sizeLeft)
- if !ok {
- return reflect.Value{}, false
- }
- v.Index(i).Set(elem)
- }
- case reflect.Array:
- for i := 0; i < v.Len(); i++ {
- elem, ok := sizedValue(concrete.Elem(), rand, size)
- if !ok {
- return reflect.Value{}, false
- }
- v.Index(i).Set(elem)
- }
- case reflect.String:
- numChars := rand.Intn(complexSize)
- codePoints := make([]rune, numChars)
- for i := 0; i < numChars; i++ {
- codePoints[i] = rune(rand.Intn(0x10ffff))
- }
- v.SetString(string(codePoints))
- case reflect.Struct:
- n := v.NumField()
- // Divide sizeLeft evenly among the struct fields.
- sizeLeft := size
- if n > sizeLeft {
- sizeLeft = 1
- } else if n > 0 {
- sizeLeft /= n
- }
- for i := 0; i < n; i++ {
- elem, ok := sizedValue(concrete.Field(i).Type, rand, sizeLeft)
- if !ok {
- return reflect.Value{}, false
- }
- v.Field(i).Set(elem)
- }
- default:
- return reflect.Value{}, false
- }
-
- return v, true
-}
-
-// A Config structure contains options for running a test.
-type Config struct {
- // MaxCount sets the maximum number of iterations.
- // If zero, MaxCountScale is used.
- MaxCount int
- // MaxCountScale is a non-negative scale factor applied to the
- // default maximum.
- // A count of zero implies the default, which is usually 100
- // but can be set by the -quickchecks flag.
- MaxCountScale float64
- // Rand specifies a source of random numbers.
- // If nil, a default pseudo-random source will be used.
- Rand *rand.Rand
- // Values specifies a function to generate a slice of
- // arbitrary reflect.Values that are congruent with the
- // arguments to the function being tested.
- // If nil, the top-level Value function is used to generate them.
- Values func([]reflect.Value, *rand.Rand)
-}
-
-var defaultConfig Config
-
-// getRand returns the *rand.Rand to use for a given Config.
-func (c *Config) getRand() *rand.Rand {
- if c.Rand == nil {
- return rand.New(rand.NewSource(time.Now().UnixNano()))
- }
- return c.Rand
-}
-
-// getMaxCount returns the maximum number of iterations to run for a given
-// Config.
-func (c *Config) getMaxCount() (maxCount int) {
- maxCount = c.MaxCount
- if maxCount == 0 {
- if c.MaxCountScale != 0 {
- maxCount = int(c.MaxCountScale * float64(*defaultMaxCount))
- } else {
- maxCount = *defaultMaxCount
- }
- }
-
- return
-}
-
-// A SetupError is the result of an error in the way that check is being
-// used, independent of the functions being tested.
-type SetupError string
-
-func (s SetupError) Error() string { return string(s) }
-
-// A CheckError is the result of Check finding an error.
-type CheckError struct {
- Count int
- In []any
-}
-
-func (s *CheckError) Error() string {
- return fmt.Sprintf("#%d: failed on input %s", s.Count, toString(s.In))
-}
-
-// A CheckEqualError is the result CheckEqual finding an error.
-type CheckEqualError struct {
- CheckError
- Out1 []any
- Out2 []any
-}
-
-func (s *CheckEqualError) Error() string {
- return fmt.Sprintf("#%d: failed on input %s. Output 1: %s. Output 2: %s", s.Count, toString(s.In), toString(s.Out1), toString(s.Out2))
-}
-
-// Check looks for an input to f, any function that returns bool,
-// such that f returns false. It calls f repeatedly, with arbitrary
-// values for each argument. If f returns false on a given input,
-// Check returns that input as a *CheckError.
-// For example:
-//
-// func TestOddMultipleOfThree(t *testing.T) {
-// f := func(x int) bool {
-// y := OddMultipleOfThree(x)
-// return y%2 == 1 && y%3 == 0
-// }
-// if err := quick.Check(f, nil); err != nil {
-// t.Error(err)
-// }
-// }
-func Check(f any, config *Config) error {
- if config == nil {
- config = &defaultConfig
- }
-
- fVal, fType, ok := functionAndType(f)
- if !ok {
- return SetupError("argument is not a function")
- }
-
- if fType.NumOut() != 1 {
- return SetupError("function does not return one value")
- }
- if fType.Out(0).Kind() != reflect.Bool {
- return SetupError("function does not return a bool")
- }
-
- arguments := make([]reflect.Value, fType.NumIn())
- rand := config.getRand()
- maxCount := config.getMaxCount()
-
- for i := 0; i < maxCount; i++ {
- err := arbitraryValues(arguments, fType, config, rand)
- if err != nil {
- return err
- }
-
- if !fVal.Call(arguments)[0].Bool() {
- return &CheckError{i + 1, toInterfaces(arguments)}
- }
- }
-
- return nil
-}
-
-// CheckEqual looks for an input on which f and g return different results.
-// It calls f and g repeatedly with arbitrary values for each argument.
-// If f and g return different answers, CheckEqual returns a *CheckEqualError
-// describing the input and the outputs.
-func CheckEqual(f, g any, config *Config) error {
- if config == nil {
- config = &defaultConfig
- }
-
- x, xType, ok := functionAndType(f)
- if !ok {
- return SetupError("f is not a function")
- }
- y, yType, ok := functionAndType(g)
- if !ok {
- return SetupError("g is not a function")
- }
-
- if xType != yType {
- return SetupError("functions have different types")
- }
-
- arguments := make([]reflect.Value, xType.NumIn())
- rand := config.getRand()
- maxCount := config.getMaxCount()
-
- for i := 0; i < maxCount; i++ {
- err := arbitraryValues(arguments, xType, config, rand)
- if err != nil {
- return err
- }
-
- xOut := toInterfaces(x.Call(arguments))
- yOut := toInterfaces(y.Call(arguments))
-
- if !reflect.DeepEqual(xOut, yOut) {
- return &CheckEqualError{CheckError{i + 1, toInterfaces(arguments)}, xOut, yOut}
- }
- }
-
- return nil
-}
-
-// arbitraryValues writes Values to args such that args contains Values
-// suitable for calling f.
-func arbitraryValues(args []reflect.Value, f reflect.Type, config *Config, rand *rand.Rand) (err error) {
- if config.Values != nil {
- config.Values(args, rand)
- return
- }
-
- for j := 0; j < len(args); j++ {
- var ok bool
- args[j], ok = Value(f.In(j), rand)
- if !ok {
- err = SetupError(fmt.Sprintf("cannot create arbitrary value of type %s for argument %d", f.In(j), j))
- return
- }
- }
-
- return
-}
-
-func functionAndType(f any) (v reflect.Value, t reflect.Type, ok bool) {
- v = reflect.ValueOf(f)
- ok = v.Kind() == reflect.Func
- if !ok {
- return
- }
- t = v.Type()
- return
-}
-
-func toInterfaces(values []reflect.Value) []any {
- ret := make([]any, len(values))
- for i, v := range values {
- ret[i] = v.Interface()
- }
- return ret
-}
-
-func toString(interfaces []any) string {
- s := make([]string, len(interfaces))
- for i, v := range interfaces {
- s[i] = fmt.Sprintf("%#v", v)
- }
- return strings.Join(s, ", ")
-}
diff --git a/contrib/go/_std_1.20/src/testing/quick/ya.make b/contrib/go/_std_1.20/src/testing/quick/ya.make
deleted file mode 100644
index fd6eadeec0..0000000000
--- a/contrib/go/_std_1.20/src/testing/quick/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- quick.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/testing/run_example.go b/contrib/go/_std_1.20/src/testing/run_example.go
deleted file mode 100644
index 776fbffc7e..0000000000
--- a/contrib/go/_std_1.20/src/testing/run_example.go
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !js
-
-// TODO(@musiol, @odeke-em): re-unify this entire file back into
-// example.go when js/wasm gets an os.Pipe implementation
-// and no longer needs this separation.
-
-package testing
-
-import (
- "fmt"
- "io"
- "os"
- "strings"
- "time"
-)
-
-func runExample(eg InternalExample) (ok bool) {
- if chatty.on {
- fmt.Printf("%s=== RUN %s\n", chatty.prefix(), eg.Name)
- }
-
- // Capture stdout.
- stdout := os.Stdout
- r, w, err := os.Pipe()
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- os.Stdout = w
- outC := make(chan string)
- go func() {
- var buf strings.Builder
- _, err := io.Copy(&buf, r)
- r.Close()
- if err != nil {
- fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
- os.Exit(1)
- }
- outC <- buf.String()
- }()
-
- finished := false
- start := time.Now()
-
- // Clean up in a deferred call so we can recover if the example panics.
- defer func() {
- timeSpent := time.Since(start)
-
- // Close pipe, restore stdout, get output.
- w.Close()
- os.Stdout = stdout
- out := <-outC
-
- err := recover()
- ok = eg.processRunResult(out, timeSpent, finished, err)
- }()
-
- // Run example.
- eg.F()
- finished = true
- return
-}
diff --git a/contrib/go/_std_1.20/src/testing/testing.go b/contrib/go/_std_1.20/src/testing/testing.go
deleted file mode 100644
index fc34cbf28b..0000000000
--- a/contrib/go/_std_1.20/src/testing/testing.go
+++ /dev/null
@@ -1,2284 +0,0 @@
-// Copyright 2009 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 testing provides support for automated testing of Go packages.
-// It is intended to be used in concert with the "go test" command, which automates
-// execution of any function of the form
-//
-// func TestXxx(*testing.T)
-//
-// where Xxx does not start with a lowercase letter. The function name
-// serves to identify the test routine.
-//
-// Within these functions, use the Error, Fail or related methods to signal failure.
-//
-// To write a new test suite, create a file that
-// contains the TestXxx functions as described here,
-// and give that file a name ending in "_test.go".
-// The file will be excluded from regular
-// package builds but will be included when the "go test" command is run.
-//
-// The test file can be in the same package as the one being tested,
-// or in a corresponding package with the suffix "_test".
-//
-// If the test file is in the same package, it may refer to unexported
-// identifiers within the package, as in this example:
-//
-// package abs
-//
-// import "testing"
-//
-// func TestAbs(t *testing.T) {
-// got := Abs(-1)
-// if got != 1 {
-// t.Errorf("Abs(-1) = %d; want 1", got)
-// }
-// }
-//
-// If the file is in a separate "_test" package, the package being tested
-// must be imported explicitly and only its exported identifiers may be used.
-// This is known as "black box" testing.
-//
-// package abs_test
-//
-// import (
-// "testing"
-//
-// "path_to_pkg/abs"
-// )
-//
-// func TestAbs(t *testing.T) {
-// got := abs.Abs(-1)
-// if got != 1 {
-// t.Errorf("Abs(-1) = %d; want 1", got)
-// }
-// }
-//
-// For more detail, run "go help test" and "go help testflag".
-//
-// # Benchmarks
-//
-// Functions of the form
-//
-// func BenchmarkXxx(*testing.B)
-//
-// are considered benchmarks, and are executed by the "go test" command when
-// its -bench flag is provided. Benchmarks are run sequentially.
-//
-// For a description of the testing flags, see
-// https://golang.org/cmd/go/#hdr-Testing_flags.
-//
-// A sample benchmark function looks like this:
-//
-// func BenchmarkRandInt(b *testing.B) {
-// for i := 0; i < b.N; i++ {
-// rand.Int()
-// }
-// }
-//
-// The benchmark function must run the target code b.N times.
-// During benchmark execution, b.N is adjusted until the benchmark function lasts
-// long enough to be timed reliably. The output
-//
-// BenchmarkRandInt-8 68453040 17.8 ns/op
-//
-// means that the loop ran 68453040 times at a speed of 17.8 ns per loop.
-//
-// If a benchmark needs some expensive setup before running, the timer
-// may be reset:
-//
-// func BenchmarkBigLen(b *testing.B) {
-// big := NewBig()
-// b.ResetTimer()
-// for i := 0; i < b.N; i++ {
-// big.Len()
-// }
-// }
-//
-// If a benchmark needs to test performance in a parallel setting, it may use
-// the RunParallel helper function; such benchmarks are intended to be used with
-// the go test -cpu flag:
-//
-// func BenchmarkTemplateParallel(b *testing.B) {
-// templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
-// b.RunParallel(func(pb *testing.PB) {
-// var buf bytes.Buffer
-// for pb.Next() {
-// buf.Reset()
-// templ.Execute(&buf, "World")
-// }
-// })
-// }
-//
-// A detailed specification of the benchmark results format is given
-// in https://golang.org/design/14313-benchmark-format.
-//
-// There are standard tools for working with benchmark results at
-// https://golang.org/x/perf/cmd.
-// In particular, https://golang.org/x/perf/cmd/benchstat performs
-// statistically robust A/B comparisons.
-//
-// # Examples
-//
-// The package also runs and verifies example code. Example functions may
-// include a concluding line comment that begins with "Output:" and is compared with
-// the standard output of the function when the tests are run. (The comparison
-// ignores leading and trailing space.) These are examples of an example:
-//
-// func ExampleHello() {
-// fmt.Println("hello")
-// // Output: hello
-// }
-//
-// func ExampleSalutations() {
-// fmt.Println("hello, and")
-// fmt.Println("goodbye")
-// // Output:
-// // hello, and
-// // goodbye
-// }
-//
-// The comment prefix "Unordered output:" is like "Output:", but matches any
-// line order:
-//
-// func ExamplePerm() {
-// for _, value := range Perm(5) {
-// fmt.Println(value)
-// }
-// // Unordered output: 4
-// // 2
-// // 1
-// // 3
-// // 0
-// }
-//
-// Example functions without output comments are compiled but not executed.
-//
-// The naming convention to declare examples for the package, a function F, a type T and
-// method M on type T are:
-//
-// func Example() { ... }
-// func ExampleF() { ... }
-// func ExampleT() { ... }
-// func ExampleT_M() { ... }
-//
-// Multiple example functions for a package/type/function/method may be provided by
-// appending a distinct suffix to the name. The suffix must start with a
-// lower-case letter.
-//
-// func Example_suffix() { ... }
-// func ExampleF_suffix() { ... }
-// func ExampleT_suffix() { ... }
-// func ExampleT_M_suffix() { ... }
-//
-// The entire test file is presented as the example when it contains a single
-// example function, at least one other function, type, variable, or constant
-// declaration, and no test or benchmark functions.
-//
-// # Fuzzing
-//
-// 'go test' and the testing package support fuzzing, a testing technique where
-// a function is called with randomly generated inputs to find bugs not
-// anticipated by unit tests.
-//
-// Functions of the form
-//
-// func FuzzXxx(*testing.F)
-//
-// are considered fuzz tests.
-//
-// For example:
-//
-// func FuzzHex(f *testing.F) {
-// for _, seed := range [][]byte{{}, {0}, {9}, {0xa}, {0xf}, {1, 2, 3, 4}} {
-// f.Add(seed)
-// }
-// f.Fuzz(func(t *testing.T, in []byte) {
-// enc := hex.EncodeToString(in)
-// out, err := hex.DecodeString(enc)
-// if err != nil {
-// t.Fatalf("%v: decode: %v", in, err)
-// }
-// if !bytes.Equal(in, out) {
-// t.Fatalf("%v: not equal after round trip: %v", in, out)
-// }
-// })
-// }
-//
-// A fuzz test maintains a seed corpus, or a set of inputs which are run by
-// default, and can seed input generation. Seed inputs may be registered by
-// calling (*F).Add or by storing files in the directory testdata/fuzz/<Name>
-// (where <Name> is the name of the fuzz test) within the package containing
-// the fuzz test. Seed inputs are optional, but the fuzzing engine may find
-// bugs more efficiently when provided with a set of small seed inputs with good
-// code coverage. These seed inputs can also serve as regression tests for bugs
-// identified through fuzzing.
-//
-// The function passed to (*F).Fuzz within the fuzz test is considered the fuzz
-// target. A fuzz target must accept a *T parameter, followed by one or more
-// parameters for random inputs. The types of arguments passed to (*F).Add must
-// be identical to the types of these parameters. The fuzz target may signal
-// that it's found a problem the same way tests do: by calling T.Fail (or any
-// method that calls it like T.Error or T.Fatal) or by panicking.
-//
-// When fuzzing is enabled (by setting the -fuzz flag to a regular expression
-// that matches a specific fuzz test), the fuzz target is called with arguments
-// generated by repeatedly making random changes to the seed inputs. On
-// supported platforms, 'go test' compiles the test executable with fuzzing
-// coverage instrumentation. The fuzzing engine uses that instrumentation to
-// find and cache inputs that expand coverage, increasing the likelihood of
-// finding bugs. If the fuzz target fails for a given input, the fuzzing engine
-// writes the inputs that caused the failure to a file in the directory
-// testdata/fuzz/<Name> within the package directory. This file later serves as
-// a seed input. If the file can't be written at that location (for example,
-// because the directory is read-only), the fuzzing engine writes the file to
-// the fuzz cache directory within the build cache instead.
-//
-// When fuzzing is disabled, the fuzz target is called with the seed inputs
-// registered with F.Add and seed inputs from testdata/fuzz/<Name>. In this
-// mode, the fuzz test acts much like a regular test, with subtests started
-// with F.Fuzz instead of T.Run.
-//
-// See https://go.dev/doc/fuzz for documentation about fuzzing.
-//
-// # Skipping
-//
-// Tests or benchmarks may be skipped at run time with a call to
-// the Skip method of *T or *B:
-//
-// func TestTimeConsuming(t *testing.T) {
-// if testing.Short() {
-// t.Skip("skipping test in short mode.")
-// }
-// ...
-// }
-//
-// The Skip method of *T can be used in a fuzz target if the input is invalid,
-// but should not be considered a failing input. For example:
-//
-// func FuzzJSONMarshaling(f *testing.F) {
-// f.Fuzz(func(t *testing.T, b []byte) {
-// var v interface{}
-// if err := json.Unmarshal(b, &v); err != nil {
-// t.Skip()
-// }
-// if _, err := json.Marshal(v); err != nil {
-// t.Errorf("Marshal: %v", err)
-// }
-// })
-// }
-//
-// # Subtests and Sub-benchmarks
-//
-// The Run methods of T and B allow defining subtests and sub-benchmarks,
-// without having to define separate functions for each. This enables uses
-// like table-driven benchmarks and creating hierarchical tests.
-// It also provides a way to share common setup and tear-down code:
-//
-// func TestFoo(t *testing.T) {
-// // <setup code>
-// t.Run("A=1", func(t *testing.T) { ... })
-// t.Run("A=2", func(t *testing.T) { ... })
-// t.Run("B=1", func(t *testing.T) { ... })
-// // <tear-down code>
-// }
-//
-// Each subtest and sub-benchmark has a unique name: the combination of the name
-// of the top-level test and the sequence of names passed to Run, separated by
-// slashes, with an optional trailing sequence number for disambiguation.
-//
-// The argument to the -run, -bench, and -fuzz command-line flags is an unanchored regular
-// expression that matches the test's name. For tests with multiple slash-separated
-// elements, such as subtests, the argument is itself slash-separated, with
-// expressions matching each name element in turn. Because it is unanchored, an
-// empty expression matches any string.
-// For example, using "matching" to mean "whose name contains":
-//
-// go test -run '' # Run all tests.
-// go test -run Foo # Run top-level tests matching "Foo", such as "TestFooBar".
-// go test -run Foo/A= # For top-level tests matching "Foo", run subtests matching "A=".
-// go test -run /A=1 # For all top-level tests, run subtests matching "A=1".
-// go test -fuzz FuzzFoo # Fuzz the target matching "FuzzFoo"
-//
-// The -run argument can also be used to run a specific value in the seed
-// corpus, for debugging. For example:
-//
-// go test -run=FuzzFoo/9ddb952d9814
-//
-// The -fuzz and -run flags can both be set, in order to fuzz a target but
-// skip the execution of all other tests.
-//
-// Subtests can also be used to control parallelism. A parent test will only
-// complete once all of its subtests complete. In this example, all tests are
-// run in parallel with each other, and only with each other, regardless of
-// other top-level tests that may be defined:
-//
-// func TestGroupedParallel(t *testing.T) {
-// for _, tc := range tests {
-// tc := tc // capture range variable
-// t.Run(tc.Name, func(t *testing.T) {
-// t.Parallel()
-// ...
-// })
-// }
-// }
-//
-// Run does not return until parallel subtests have completed, providing a way
-// to clean up after a group of parallel tests:
-//
-// func TestTeardownParallel(t *testing.T) {
-// // This Run will not return until the parallel tests finish.
-// t.Run("group", func(t *testing.T) {
-// t.Run("Test1", parallelTest1)
-// t.Run("Test2", parallelTest2)
-// t.Run("Test3", parallelTest3)
-// })
-// // <tear-down code>
-// }
-//
-// # Main
-//
-// It is sometimes necessary for a test or benchmark program to do extra setup or teardown
-// before or after it executes. It is also sometimes necessary to control
-// which code runs on the main thread. To support these and other cases,
-// if a test file contains a function:
-//
-// func TestMain(m *testing.M)
-//
-// then the generated test will call TestMain(m) instead of running the tests or benchmarks
-// directly. TestMain runs in the main goroutine and can do whatever setup
-// and teardown is necessary around a call to m.Run. m.Run will return an exit
-// code that may be passed to os.Exit. If TestMain returns, the test wrapper
-// will pass the result of m.Run to os.Exit itself.
-//
-// When TestMain is called, flag.Parse has not been run. If TestMain depends on
-// command-line flags, including those of the testing package, it should call
-// flag.Parse explicitly. Command line flags are always parsed by the time test
-// or benchmark functions run.
-//
-// A simple implementation of TestMain is:
-//
-// func TestMain(m *testing.M) {
-// // call flag.Parse() here if TestMain uses flags
-// os.Exit(m.Run())
-// }
-//
-// TestMain is a low-level primitive and should not be necessary for casual
-// testing needs, where ordinary test functions suffice.
-package testing
-
-import (
- "bytes"
- "errors"
- "flag"
- "fmt"
- "internal/goexperiment"
- "internal/race"
- "io"
- "math/rand"
- "os"
- "reflect"
- "runtime"
- "runtime/debug"
- "runtime/trace"
- "sort"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
- "time"
- "unicode"
- "unicode/utf8"
-)
-
-var initRan bool
-
-// Init registers testing flags. These flags are automatically registered by
-// the "go test" command before running test functions, so Init is only needed
-// when calling functions such as Benchmark without using "go test".
-//
-// Init has no effect if it was already called.
-func Init() {
- if initRan {
- return
- }
- initRan = true
- // The short flag requests that tests run more quickly, but its functionality
- // is provided by test writers themselves. The testing package is just its
- // home. The all.bash installation script sets it to make installation more
- // efficient, but by default the flag is off so a plain "go test" will do a
- // full test of the package.
- short = flag.Bool("test.short", false, "run smaller test suite to save time")
-
- // The failfast flag requests that test execution stop after the first test failure.
- failFast = flag.Bool("test.failfast", false, "do not start new tests after the first test failure")
-
- // The directory in which to create profile files and the like. When run from
- // "go test", the binary always runs in the source directory for the package;
- // this flag lets "go test" tell the binary to write the files in the directory where
- // the "go test" command is run.
- outputDir = flag.String("test.outputdir", "", "write profiles to `dir`")
- // Report as tests are run; default is silent for success.
- flag.Var(&chatty, "test.v", "verbose: print additional output")
- count = flag.Uint("test.count", 1, "run tests and benchmarks `n` times")
- coverProfile = flag.String("test.coverprofile", "", "write a coverage profile to `file`")
- gocoverdir = flag.String("test.gocoverdir", "", "write coverage intermediate files to this directory")
- matchList = flag.String("test.list", "", "list tests, examples, and benchmarks matching `regexp` then exit")
- match = flag.String("test.run", "", "run only tests and examples matching `regexp`")
- skip = flag.String("test.skip", "", "do not list or run tests matching `regexp`")
- memProfile = flag.String("test.memprofile", "", "write an allocation profile to `file`")
- memProfileRate = flag.Int("test.memprofilerate", 0, "set memory allocation profiling `rate` (see runtime.MemProfileRate)")
- cpuProfile = flag.String("test.cpuprofile", "", "write a cpu profile to `file`")
- blockProfile = flag.String("test.blockprofile", "", "write a goroutine blocking profile to `file`")
- blockProfileRate = flag.Int("test.blockprofilerate", 1, "set blocking profile `rate` (see runtime.SetBlockProfileRate)")
- mutexProfile = flag.String("test.mutexprofile", "", "write a mutex contention profile to the named file after execution")
- mutexProfileFraction = flag.Int("test.mutexprofilefraction", 1, "if >= 0, calls runtime.SetMutexProfileFraction()")
- panicOnExit0 = flag.Bool("test.paniconexit0", false, "panic on call to os.Exit(0)")
- traceFile = flag.String("test.trace", "", "write an execution trace to `file`")
- timeout = flag.Duration("test.timeout", 0, "panic test binary after duration `d` (default 0, timeout disabled)")
- cpuListStr = flag.String("test.cpu", "", "comma-separated `list` of cpu counts to run each test with")
- parallel = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "run at most `n` tests in parallel")
- testlog = flag.String("test.testlogfile", "", "write test action log to `file` (for use only by cmd/go)")
- shuffle = flag.String("test.shuffle", "off", "randomize the execution order of tests and benchmarks")
-
- initBenchmarkFlags()
- initFuzzFlags()
-}
-
-var (
- // Flags, registered during Init.
- short *bool
- failFast *bool
- outputDir *string
- chatty chattyFlag
- count *uint
- coverProfile *string
- gocoverdir *string
- matchList *string
- match *string
- skip *string
- memProfile *string
- memProfileRate *int
- cpuProfile *string
- blockProfile *string
- blockProfileRate *int
- mutexProfile *string
- mutexProfileFraction *int
- panicOnExit0 *bool
- traceFile *string
- timeout *time.Duration
- cpuListStr *string
- parallel *int
- shuffle *string
- testlog *string
-
- haveExamples bool // are there examples?
-
- cpuList []int
- testlogFile *os.File
-
- numFailed atomic.Uint32 // number of test failures
-
- running sync.Map // map[string]time.Time of running, unpaused tests
-)
-
-type chattyFlag struct {
- on bool // -v is set in some form
- json bool // -v=test2json is set, to make output better for test2json
-}
-
-func (*chattyFlag) IsBoolFlag() bool { return true }
-
-func (f *chattyFlag) Set(arg string) error {
- switch arg {
- default:
- return fmt.Errorf("invalid flag -test.v=%s", arg)
- case "true", "test2json":
- f.on = true
- f.json = arg == "test2json"
- case "false":
- f.on = false
- f.json = false
- }
- return nil
-}
-
-func (f *chattyFlag) String() string {
- if f.json {
- return "test2json"
- }
- if f.on {
- return "true"
- }
- return "false"
-}
-
-func (f *chattyFlag) Get() any {
- if f.json {
- return "test2json"
- }
- return f.on
-}
-
-const marker = byte(0x16) // ^V for framing
-
-func (f *chattyFlag) prefix() string {
- if f.json {
- return string(marker)
- }
- return ""
-}
-
-type chattyPrinter struct {
- w io.Writer
- lastNameMu sync.Mutex // guards lastName
- lastName string // last printed test name in chatty mode
- json bool // -v=json output mode
-}
-
-func newChattyPrinter(w io.Writer) *chattyPrinter {
- return &chattyPrinter{w: w, json: chatty.json}
-}
-
-// prefix is like chatty.prefix but using p.json instead of chatty.json.
-// Using p.json allows tests to check the json behavior without modifying
-// the global variable. For convenience, we allow p == nil and treat
-// that as not in json mode (because it's not chatty at all).
-func (p *chattyPrinter) prefix() string {
- if p != nil && p.json {
- return string(marker)
- }
- return ""
-}
-
-// Updatef prints a message about the status of the named test to w.
-//
-// The formatted message must include the test name itself.
-func (p *chattyPrinter) Updatef(testName, format string, args ...any) {
- p.lastNameMu.Lock()
- defer p.lastNameMu.Unlock()
-
- // Since the message already implies an association with a specific new test,
- // we don't need to check what the old test name was or log an extra NAME line
- // for it. (We're updating it anyway, and the current message already includes
- // the test name.)
- p.lastName = testName
- fmt.Fprintf(p.w, p.prefix()+format, args...)
-}
-
-// Printf prints a message, generated by the named test, that does not
-// necessarily mention that tests's name itself.
-func (p *chattyPrinter) Printf(testName, format string, args ...any) {
- p.lastNameMu.Lock()
- defer p.lastNameMu.Unlock()
-
- if p.lastName == "" {
- p.lastName = testName
- } else if p.lastName != testName {
- fmt.Fprintf(p.w, "%s=== NAME %s\n", p.prefix(), testName)
- p.lastName = testName
- }
-
- fmt.Fprintf(p.w, format, args...)
-}
-
-// The maximum number of stack frames to go through when skipping helper functions for
-// the purpose of decorating log messages.
-const maxStackLen = 50
-
-// common holds the elements common between T and B and
-// captures common methods such as Errorf.
-type common struct {
- mu sync.RWMutex // guards this group of fields
- output []byte // Output generated by test or benchmark.
- w io.Writer // For flushToParent.
- ran bool // Test or benchmark (or one of its subtests) was executed.
- failed bool // Test or benchmark has failed.
- skipped bool // Test or benchmark has been skipped.
- done bool // Test is finished and all subtests have completed.
- helperPCs map[uintptr]struct{} // functions to be skipped when writing file/line info
- helperNames map[string]struct{} // helperPCs converted to function names
- cleanups []func() // optional functions to be called at the end of the test
- cleanupName string // Name of the cleanup function.
- cleanupPc []uintptr // The stack trace at the point where Cleanup was called.
- finished bool // Test function has completed.
- inFuzzFn bool // Whether the fuzz target, if this is one, is running.
-
- chatty *chattyPrinter // A copy of chattyPrinter, if the chatty flag is set.
- bench bool // Whether the current test is a benchmark.
- hasSub atomic.Bool // whether there are sub-benchmarks.
- cleanupStarted atomic.Bool // Registered cleanup callbacks have started to execute
- raceErrors int // Number of races detected during test.
- runner string // Function name of tRunner running the test.
- isParallel bool // Whether the test is parallel.
-
- parent *common
- level int // Nesting depth of test or benchmark.
- creator []uintptr // If level > 0, the stack trace at the point where the parent called t.Run.
- name string // Name of test or benchmark.
- start time.Time // Time test or benchmark started
- duration time.Duration
- barrier chan bool // To signal parallel subtests they may start. Nil when T.Parallel is not present (B) or not usable (when fuzzing).
- signal chan bool // To signal a test is done.
- sub []*T // Queue of subtests to be run in parallel.
-
- tempDirMu sync.Mutex
- tempDir string
- tempDirErr error
- tempDirSeq int32
-}
-
-// Short reports whether the -test.short flag is set.
-func Short() bool {
- if short == nil {
- panic("testing: Short called before Init")
- }
- // Catch code that calls this from TestMain without first calling flag.Parse.
- if !flag.Parsed() {
- panic("testing: Short called before Parse")
- }
-
- return *short
-}
-
-// CoverMode reports what the test coverage mode is set to. The
-// values are "set", "count", or "atomic". The return value will be
-// empty if test coverage is not enabled.
-func CoverMode() string {
- if goexperiment.CoverageRedesign {
- return cover2.mode
- }
- return cover.Mode
-}
-
-// Verbose reports whether the -test.v flag is set.
-func Verbose() bool {
- // Same as in Short.
- if !flag.Parsed() {
- panic("testing: Verbose called before Parse")
- }
- return chatty.on
-}
-
-func (c *common) checkFuzzFn(name string) {
- if c.inFuzzFn {
- panic(fmt.Sprintf("testing: f.%s was called inside the fuzz target, use t.%s instead", name, name))
- }
-}
-
-// frameSkip searches, starting after skip frames, for the first caller frame
-// in a function not marked as a helper and returns that frame.
-// The search stops if it finds a tRunner function that
-// was the entry point into the test and the test is not a subtest.
-// This function must be called with c.mu held.
-func (c *common) frameSkip(skip int) runtime.Frame {
- // If the search continues into the parent test, we'll have to hold
- // its mu temporarily. If we then return, we need to unlock it.
- shouldUnlock := false
- defer func() {
- if shouldUnlock {
- c.mu.Unlock()
- }
- }()
- var pc [maxStackLen]uintptr
- // Skip two extra frames to account for this function
- // and runtime.Callers itself.
- n := runtime.Callers(skip+2, pc[:])
- if n == 0 {
- panic("testing: zero callers found")
- }
- frames := runtime.CallersFrames(pc[:n])
- var firstFrame, prevFrame, frame runtime.Frame
- for more := true; more; prevFrame = frame {
- frame, more = frames.Next()
- if frame.Function == "runtime.gopanic" {
- continue
- }
- if frame.Function == c.cleanupName {
- frames = runtime.CallersFrames(c.cleanupPc)
- continue
- }
- if firstFrame.PC == 0 {
- firstFrame = frame
- }
- if frame.Function == c.runner {
- // We've gone up all the way to the tRunner calling
- // the test function (so the user must have
- // called tb.Helper from inside that test function).
- // If this is a top-level test, only skip up to the test function itself.
- // If we're in a subtest, continue searching in the parent test,
- // starting from the point of the call to Run which created this subtest.
- if c.level > 1 {
- frames = runtime.CallersFrames(c.creator)
- parent := c.parent
- // We're no longer looking at the current c after this point,
- // so we should unlock its mu, unless it's the original receiver,
- // in which case our caller doesn't expect us to do that.
- if shouldUnlock {
- c.mu.Unlock()
- }
- c = parent
- // Remember to unlock c.mu when we no longer need it, either
- // because we went up another nesting level, or because we
- // returned.
- shouldUnlock = true
- c.mu.Lock()
- continue
- }
- return prevFrame
- }
- // If more helper PCs have been added since we last did the conversion
- if c.helperNames == nil {
- c.helperNames = make(map[string]struct{})
- for pc := range c.helperPCs {
- c.helperNames[pcToName(pc)] = struct{}{}
- }
- }
- if _, ok := c.helperNames[frame.Function]; !ok {
- // Found a frame that wasn't inside a helper function.
- return frame
- }
- }
- return firstFrame
-}
-
-// decorate prefixes the string with the file and line of the call site
-// and inserts the final newline if needed and indentation spaces for formatting.
-// This function must be called with c.mu held.
-func (c *common) decorate(s string, skip int) string {
- frame := c.frameSkip(skip)
- file := frame.File
- line := frame.Line
- if file != "" {
- // Truncate file name at last file name separator.
- if index := strings.LastIndex(file, "/"); index >= 0 {
- file = file[index+1:]
- } else if index = strings.LastIndex(file, "\\"); index >= 0 {
- file = file[index+1:]
- }
- } else {
- file = "???"
- }
- if line == 0 {
- line = 1
- }
- buf := new(strings.Builder)
- // Every line is indented at least 4 spaces.
- buf.WriteString(" ")
- fmt.Fprintf(buf, "%s:%d: ", file, line)
- lines := strings.Split(s, "\n")
- if l := len(lines); l > 1 && lines[l-1] == "" {
- lines = lines[:l-1]
- }
- for i, line := range lines {
- if i > 0 {
- // Second and subsequent lines are indented an additional 4 spaces.
- buf.WriteString("\n ")
- }
- buf.WriteString(line)
- }
- buf.WriteByte('\n')
- return buf.String()
-}
-
-// flushToParent writes c.output to the parent after first writing the header
-// with the given format and arguments.
-func (c *common) flushToParent(testName, format string, args ...any) {
- p := c.parent
- p.mu.Lock()
- defer p.mu.Unlock()
-
- c.mu.Lock()
- defer c.mu.Unlock()
-
- if len(c.output) > 0 {
- // Add the current c.output to the print,
- // and then arrange for the print to replace c.output.
- // (This displays the logged output after the --- FAIL line.)
- format += "%s"
- args = append(args[:len(args):len(args)], c.output)
- c.output = c.output[:0]
- }
-
- if c.chatty != nil && (p.w == c.chatty.w || c.chatty.json) {
- // We're flushing to the actual output, so track that this output is
- // associated with a specific test (and, specifically, that the next output
- // is *not* associated with that test).
- //
- // Moreover, if c.output is non-empty it is important that this write be
- // atomic with respect to the output of other tests, so that we don't end up
- // with confusing '=== NAME' lines in the middle of our '--- PASS' block.
- // Neither humans nor cmd/test2json can parse those easily.
- // (See https://go.dev/issue/40771.)
- //
- // If test2json is used, we never flush to parent tests,
- // so that the json stream shows subtests as they finish.
- // (See https://go.dev/issue/29811.)
- c.chatty.Updatef(testName, format, args...)
- } else {
- // We're flushing to the output buffer of the parent test, which will
- // itself follow a test-name header when it is finally flushed to stdout.
- fmt.Fprintf(p.w, c.chatty.prefix()+format, args...)
- }
-}
-
-type indenter struct {
- c *common
-}
-
-func (w indenter) Write(b []byte) (n int, err error) {
- n = len(b)
- for len(b) > 0 {
- end := bytes.IndexByte(b, '\n')
- if end == -1 {
- end = len(b)
- } else {
- end++
- }
- // An indent of 4 spaces will neatly align the dashes with the status
- // indicator of the parent.
- line := b[:end]
- if line[0] == marker {
- w.c.output = append(w.c.output, marker)
- line = line[1:]
- }
- const indent = " "
- w.c.output = append(w.c.output, indent...)
- w.c.output = append(w.c.output, line...)
- b = b[end:]
- }
- return
-}
-
-// fmtDuration returns a string representing d in the form "87.00s".
-func fmtDuration(d time.Duration) string {
- return fmt.Sprintf("%.2fs", d.Seconds())
-}
-
-// TB is the interface common to T, B, and F.
-type TB interface {
- Cleanup(func())
- Error(args ...any)
- Errorf(format string, args ...any)
- Fail()
- FailNow()
- Failed() bool
- Fatal(args ...any)
- Fatalf(format string, args ...any)
- Helper()
- Log(args ...any)
- Logf(format string, args ...any)
- Name() string
- Setenv(key, value string)
- Skip(args ...any)
- SkipNow()
- Skipf(format string, args ...any)
- Skipped() bool
- TempDir() string
-
- // A private method to prevent users implementing the
- // interface and so future additions to it will not
- // violate Go 1 compatibility.
- private()
-}
-
-var _ TB = (*T)(nil)
-var _ TB = (*B)(nil)
-
-// T is a type passed to Test functions to manage test state and support formatted test logs.
-//
-// A test ends when its Test function returns or calls any of the methods
-// FailNow, Fatal, Fatalf, SkipNow, Skip, or Skipf. Those methods, as well as
-// the Parallel method, must be called only from the goroutine running the
-// Test function.
-//
-// The other reporting methods, such as the variations of Log and Error,
-// may be called simultaneously from multiple goroutines.
-type T struct {
- common
- isEnvSet bool
- context *testContext // For running tests and subtests.
-}
-
-func (c *common) private() {}
-
-// Name returns the name of the running (sub-) test or benchmark.
-//
-// The name will include the name of the test along with the names of
-// any nested sub-tests. If two sibling sub-tests have the same name,
-// Name will append a suffix to guarantee the returned name is unique.
-func (c *common) Name() string {
- return c.name
-}
-
-func (c *common) setRan() {
- if c.parent != nil {
- c.parent.setRan()
- }
- c.mu.Lock()
- defer c.mu.Unlock()
- c.ran = true
-}
-
-// Fail marks the function as having failed but continues execution.
-func (c *common) Fail() {
- if c.parent != nil {
- c.parent.Fail()
- }
- c.mu.Lock()
- defer c.mu.Unlock()
- // c.done needs to be locked to synchronize checks to c.done in parent tests.
- if c.done {
- panic("Fail in goroutine after " + c.name + " has completed")
- }
- c.failed = true
-}
-
-// Failed reports whether the function has failed.
-func (c *common) Failed() bool {
- c.mu.RLock()
- failed := c.failed
- c.mu.RUnlock()
- return failed || c.raceErrors+race.Errors() > 0
-}
-
-// FailNow marks the function as having failed and stops its execution
-// by calling runtime.Goexit (which then runs all deferred calls in the
-// current goroutine).
-// Execution will continue at the next test or benchmark.
-// FailNow must be called from the goroutine running the
-// test or benchmark function, not from other goroutines
-// created during the test. Calling FailNow does not stop
-// those other goroutines.
-func (c *common) FailNow() {
- c.checkFuzzFn("FailNow")
- c.Fail()
-
- // Calling runtime.Goexit will exit the goroutine, which
- // will run the deferred functions in this goroutine,
- // which will eventually run the deferred lines in tRunner,
- // which will signal to the test loop that this test is done.
- //
- // A previous version of this code said:
- //
- // c.duration = ...
- // c.signal <- c.self
- // runtime.Goexit()
- //
- // This previous version duplicated code (those lines are in
- // tRunner no matter what), but worse the goroutine teardown
- // implicit in runtime.Goexit was not guaranteed to complete
- // before the test exited. If a test deferred an important cleanup
- // function (like removing temporary files), there was no guarantee
- // it would run on a test failure. Because we send on c.signal during
- // a top-of-stack deferred function now, we know that the send
- // only happens after any other stacked defers have completed.
- c.mu.Lock()
- c.finished = true
- c.mu.Unlock()
- runtime.Goexit()
-}
-
-// log generates the output. It's always at the same stack depth.
-func (c *common) log(s string) {
- c.logDepth(s, 3) // logDepth + log + public function
-}
-
-// logDepth generates the output at an arbitrary stack depth.
-func (c *common) logDepth(s string, depth int) {
- c.mu.Lock()
- defer c.mu.Unlock()
- if c.done {
- // This test has already finished. Try and log this message
- // with our parent. If we don't have a parent, panic.
- for parent := c.parent; parent != nil; parent = parent.parent {
- parent.mu.Lock()
- defer parent.mu.Unlock()
- if !parent.done {
- parent.output = append(parent.output, parent.decorate(s, depth+1)...)
- return
- }
- }
- panic("Log in goroutine after " + c.name + " has completed: " + s)
- } else {
- if c.chatty != nil {
- if c.bench {
- // Benchmarks don't print === CONT, so we should skip the test
- // printer and just print straight to stdout.
- fmt.Print(c.decorate(s, depth+1))
- } else {
- c.chatty.Printf(c.name, "%s", c.decorate(s, depth+1))
- }
-
- return
- }
- c.output = append(c.output, c.decorate(s, depth+1)...)
- }
-}
-
-// Log formats its arguments using default formatting, analogous to Println,
-// and records the text in the error log. For tests, the text will be printed only if
-// the test fails or the -test.v flag is set. For benchmarks, the text is always
-// printed to avoid having performance depend on the value of the -test.v flag.
-func (c *common) Log(args ...any) {
- c.checkFuzzFn("Log")
- c.log(fmt.Sprintln(args...))
-}
-
-// Logf formats its arguments according to the format, analogous to Printf, and
-// records the text in the error log. A final newline is added if not provided. For
-// tests, the text will be printed only if the test fails or the -test.v flag is
-// set. For benchmarks, the text is always printed to avoid having performance
-// depend on the value of the -test.v flag.
-func (c *common) Logf(format string, args ...any) {
- c.checkFuzzFn("Logf")
- c.log(fmt.Sprintf(format, args...))
-}
-
-// Error is equivalent to Log followed by Fail.
-func (c *common) Error(args ...any) {
- c.checkFuzzFn("Error")
- c.log(fmt.Sprintln(args...))
- c.Fail()
-}
-
-// Errorf is equivalent to Logf followed by Fail.
-func (c *common) Errorf(format string, args ...any) {
- c.checkFuzzFn("Errorf")
- c.log(fmt.Sprintf(format, args...))
- c.Fail()
-}
-
-// Fatal is equivalent to Log followed by FailNow.
-func (c *common) Fatal(args ...any) {
- c.checkFuzzFn("Fatal")
- c.log(fmt.Sprintln(args...))
- c.FailNow()
-}
-
-// Fatalf is equivalent to Logf followed by FailNow.
-func (c *common) Fatalf(format string, args ...any) {
- c.checkFuzzFn("Fatalf")
- c.log(fmt.Sprintf(format, args...))
- c.FailNow()
-}
-
-// Skip is equivalent to Log followed by SkipNow.
-func (c *common) Skip(args ...any) {
- c.checkFuzzFn("Skip")
- c.log(fmt.Sprintln(args...))
- c.SkipNow()
-}
-
-// Skipf is equivalent to Logf followed by SkipNow.
-func (c *common) Skipf(format string, args ...any) {
- c.checkFuzzFn("Skipf")
- c.log(fmt.Sprintf(format, args...))
- c.SkipNow()
-}
-
-// SkipNow marks the test as having been skipped and stops its execution
-// by calling runtime.Goexit.
-// If a test fails (see Error, Errorf, Fail) and is then skipped,
-// it is still considered to have failed.
-// Execution will continue at the next test or benchmark. See also FailNow.
-// SkipNow must be called from the goroutine running the test, not from
-// other goroutines created during the test. Calling SkipNow does not stop
-// those other goroutines.
-func (c *common) SkipNow() {
- c.checkFuzzFn("SkipNow")
- c.mu.Lock()
- c.skipped = true
- c.finished = true
- c.mu.Unlock()
- runtime.Goexit()
-}
-
-// Skipped reports whether the test was skipped.
-func (c *common) Skipped() bool {
- c.mu.RLock()
- defer c.mu.RUnlock()
- return c.skipped
-}
-
-// Helper marks the calling function as a test helper function.
-// When printing file and line information, that function will be skipped.
-// Helper may be called simultaneously from multiple goroutines.
-func (c *common) Helper() {
- c.mu.Lock()
- defer c.mu.Unlock()
- if c.helperPCs == nil {
- c.helperPCs = make(map[uintptr]struct{})
- }
- // repeating code from callerName here to save walking a stack frame
- var pc [1]uintptr
- n := runtime.Callers(2, pc[:]) // skip runtime.Callers + Helper
- if n == 0 {
- panic("testing: zero callers found")
- }
- if _, found := c.helperPCs[pc[0]]; !found {
- c.helperPCs[pc[0]] = struct{}{}
- c.helperNames = nil // map will be recreated next time it is needed
- }
-}
-
-// Cleanup registers a function to be called when the test (or subtest) and all its
-// subtests complete. Cleanup functions will be called in last added,
-// first called order.
-func (c *common) Cleanup(f func()) {
- c.checkFuzzFn("Cleanup")
- var pc [maxStackLen]uintptr
- // Skip two extra frames to account for this function and runtime.Callers itself.
- n := runtime.Callers(2, pc[:])
- cleanupPc := pc[:n]
-
- fn := func() {
- defer func() {
- c.mu.Lock()
- defer c.mu.Unlock()
- c.cleanupName = ""
- c.cleanupPc = nil
- }()
-
- name := callerName(0)
- c.mu.Lock()
- c.cleanupName = name
- c.cleanupPc = cleanupPc
- c.mu.Unlock()
-
- f()
- }
-
- c.mu.Lock()
- defer c.mu.Unlock()
- c.cleanups = append(c.cleanups, fn)
-}
-
-// TempDir returns a temporary directory for the test to use.
-// The directory is automatically removed by Cleanup when the test and
-// all its subtests complete.
-// Each subsequent call to t.TempDir returns a unique directory;
-// if the directory creation fails, TempDir terminates the test by calling Fatal.
-func (c *common) TempDir() string {
- c.checkFuzzFn("TempDir")
- // Use a single parent directory for all the temporary directories
- // created by a test, each numbered sequentially.
- c.tempDirMu.Lock()
- var nonExistent bool
- if c.tempDir == "" { // Usually the case with js/wasm
- nonExistent = true
- } else {
- _, err := os.Stat(c.tempDir)
- nonExistent = os.IsNotExist(err)
- if err != nil && !nonExistent {
- c.Fatalf("TempDir: %v", err)
- }
- }
-
- if nonExistent {
- c.Helper()
-
- // Drop unusual characters (such as path separators or
- // characters interacting with globs) from the directory name to
- // avoid surprising os.MkdirTemp behavior.
- mapper := func(r rune) rune {
- if r < utf8.RuneSelf {
- const allowed = "!#$%&()+,-.=@^_{}~ "
- if '0' <= r && r <= '9' ||
- 'a' <= r && r <= 'z' ||
- 'A' <= r && r <= 'Z' {
- return r
- }
- if strings.ContainsRune(allowed, r) {
- return r
- }
- } else if unicode.IsLetter(r) || unicode.IsNumber(r) {
- return r
- }
- return -1
- }
- pattern := strings.Map(mapper, c.Name())
- c.tempDir, c.tempDirErr = os.MkdirTemp("", pattern)
- if c.tempDirErr == nil {
- c.Cleanup(func() {
- if err := removeAll(c.tempDir); err != nil {
- c.Errorf("TempDir RemoveAll cleanup: %v", err)
- }
- })
- }
- }
-
- if c.tempDirErr == nil {
- c.tempDirSeq++
- }
- seq := c.tempDirSeq
- c.tempDirMu.Unlock()
-
- if c.tempDirErr != nil {
- c.Fatalf("TempDir: %v", c.tempDirErr)
- }
-
- dir := fmt.Sprintf("%s%c%03d", c.tempDir, os.PathSeparator, seq)
- if err := os.Mkdir(dir, 0777); err != nil {
- c.Fatalf("TempDir: %v", err)
- }
- return dir
-}
-
-// removeAll is like os.RemoveAll, but retries Windows "Access is denied."
-// errors up to an arbitrary timeout.
-//
-// Those errors have been known to occur spuriously on at least the
-// windows-amd64-2012 builder (https://go.dev/issue/50051), and can only occur
-// legitimately if the test leaves behind a temp file that either is still open
-// or the test otherwise lacks permission to delete. In the case of legitimate
-// failures, a failing test may take a bit longer to fail, but once the test is
-// fixed the extra latency will go away.
-func removeAll(path string) error {
- const arbitraryTimeout = 2 * time.Second
- var (
- start time.Time
- nextSleep = 1 * time.Millisecond
- )
- for {
- err := os.RemoveAll(path)
- if !isWindowsRetryable(err) {
- return err
- }
- if start.IsZero() {
- start = time.Now()
- } else if d := time.Since(start) + nextSleep; d >= arbitraryTimeout {
- return err
- }
- time.Sleep(nextSleep)
- nextSleep += time.Duration(rand.Int63n(int64(nextSleep)))
- }
-}
-
-// Setenv calls os.Setenv(key, value) and uses Cleanup to
-// restore the environment variable to its original value
-// after the test.
-//
-// Because Setenv affects the whole process, it cannot be used
-// in parallel tests or tests with parallel ancestors.
-func (c *common) Setenv(key, value string) {
- c.checkFuzzFn("Setenv")
- prevValue, ok := os.LookupEnv(key)
-
- if err := os.Setenv(key, value); err != nil {
- c.Fatalf("cannot set environment variable: %v", err)
- }
-
- if ok {
- c.Cleanup(func() {
- os.Setenv(key, prevValue)
- })
- } else {
- c.Cleanup(func() {
- os.Unsetenv(key)
- })
- }
-}
-
-// panicHanding is an argument to runCleanup.
-type panicHandling int
-
-const (
- normalPanic panicHandling = iota
- recoverAndReturnPanic
-)
-
-// runCleanup is called at the end of the test.
-// If catchPanic is true, this will catch panics, and return the recovered
-// value if any.
-func (c *common) runCleanup(ph panicHandling) (panicVal any) {
- c.cleanupStarted.Store(true)
- defer c.cleanupStarted.Store(false)
-
- if ph == recoverAndReturnPanic {
- defer func() {
- panicVal = recover()
- }()
- }
-
- // Make sure that if a cleanup function panics,
- // we still run the remaining cleanup functions.
- defer func() {
- c.mu.Lock()
- recur := len(c.cleanups) > 0
- c.mu.Unlock()
- if recur {
- c.runCleanup(normalPanic)
- }
- }()
-
- for {
- var cleanup func()
- c.mu.Lock()
- if len(c.cleanups) > 0 {
- last := len(c.cleanups) - 1
- cleanup = c.cleanups[last]
- c.cleanups = c.cleanups[:last]
- }
- c.mu.Unlock()
- if cleanup == nil {
- return nil
- }
- cleanup()
- }
-}
-
-// callerName gives the function name (qualified with a package path)
-// for the caller after skip frames (where 0 means the current function).
-func callerName(skip int) string {
- var pc [1]uintptr
- n := runtime.Callers(skip+2, pc[:]) // skip + runtime.Callers + callerName
- if n == 0 {
- panic("testing: zero callers found")
- }
- return pcToName(pc[0])
-}
-
-func pcToName(pc uintptr) string {
- pcs := []uintptr{pc}
- frames := runtime.CallersFrames(pcs)
- frame, _ := frames.Next()
- return frame.Function
-}
-
-// Parallel signals that this test is to be run in parallel with (and only with)
-// other parallel tests. When a test is run multiple times due to use of
-// -test.count or -test.cpu, multiple instances of a single test never run in
-// parallel with each other.
-func (t *T) Parallel() {
- if t.isParallel {
- panic("testing: t.Parallel called multiple times")
- }
- if t.isEnvSet {
- panic("testing: t.Parallel called after t.Setenv; cannot set environment variables in parallel tests")
- }
- t.isParallel = true
- if t.parent.barrier == nil {
- // T.Parallel has no effect when fuzzing.
- // Multiple processes may run in parallel, but only one input can run at a
- // time per process so we can attribute crashes to specific inputs.
- return
- }
-
- // We don't want to include the time we spend waiting for serial tests
- // in the test duration. Record the elapsed time thus far and reset the
- // timer afterwards.
- t.duration += time.Since(t.start)
-
- // Add to the list of tests to be released by the parent.
- t.parent.sub = append(t.parent.sub, t)
- t.raceErrors += race.Errors()
-
- if t.chatty != nil {
- t.chatty.Updatef(t.name, "=== PAUSE %s\n", t.name)
- }
- running.Delete(t.name)
-
- t.signal <- true // Release calling test.
- <-t.parent.barrier // Wait for the parent test to complete.
- t.context.waitParallel()
-
- if t.chatty != nil {
- t.chatty.Updatef(t.name, "=== CONT %s\n", t.name)
- }
- running.Store(t.name, time.Now())
-
- t.start = time.Now()
- t.raceErrors += -race.Errors()
-}
-
-// Setenv calls os.Setenv(key, value) and uses Cleanup to
-// restore the environment variable to its original value
-// after the test.
-//
-// Because Setenv affects the whole process, it cannot be used
-// in parallel tests or tests with parallel ancestors.
-func (t *T) Setenv(key, value string) {
- // Non-parallel subtests that have parallel ancestors may still
- // run in parallel with other tests: they are only non-parallel
- // with respect to the other subtests of the same parent.
- // Since SetEnv affects the whole process, we need to disallow it
- // if the current test or any parent is parallel.
- isParallel := false
- for c := &t.common; c != nil; c = c.parent {
- if c.isParallel {
- isParallel = true
- break
- }
- }
- if isParallel {
- panic("testing: t.Setenv called after t.Parallel; cannot set environment variables in parallel tests")
- }
-
- t.isEnvSet = true
-
- t.common.Setenv(key, value)
-}
-
-// InternalTest is an internal type but exported because it is cross-package;
-// it is part of the implementation of the "go test" command.
-type InternalTest struct {
- Name string
- F func(*T)
-}
-
-var errNilPanicOrGoexit = errors.New("test executed panic(nil) or runtime.Goexit")
-
-func tRunner(t *T, fn func(t *T)) {
- t.runner = callerName(0)
-
- // When this goroutine is done, either because fn(t)
- // returned normally or because a test failure triggered
- // a call to runtime.Goexit, record the duration and send
- // a signal saying that the test is done.
- defer func() {
- if t.Failed() {
- numFailed.Add(1)
- }
-
- if t.raceErrors+race.Errors() > 0 {
- t.Errorf("race detected during execution of test")
- }
-
- // Check if the test panicked or Goexited inappropriately.
- //
- // If this happens in a normal test, print output but continue panicking.
- // tRunner is called in its own goroutine, so this terminates the process.
- //
- // If this happens while fuzzing, recover from the panic and treat it like a
- // normal failure. It's important that the process keeps running in order to
- // find short inputs that cause panics.
- err := recover()
- signal := true
-
- t.mu.RLock()
- finished := t.finished
- t.mu.RUnlock()
- if !finished && err == nil {
- err = errNilPanicOrGoexit
- for p := t.parent; p != nil; p = p.parent {
- p.mu.RLock()
- finished = p.finished
- p.mu.RUnlock()
- if finished {
- if !t.isParallel {
- t.Errorf("%v: subtest may have called FailNow on a parent test", err)
- err = nil
- }
- signal = false
- break
- }
- }
- }
-
- if err != nil && t.context.isFuzzing {
- prefix := "panic: "
- if err == errNilPanicOrGoexit {
- prefix = ""
- }
- t.Errorf("%s%s\n%s\n", prefix, err, string(debug.Stack()))
- t.mu.Lock()
- t.finished = true
- t.mu.Unlock()
- err = nil
- }
-
- // Use a deferred call to ensure that we report that the test is
- // complete even if a cleanup function calls t.FailNow. See issue 41355.
- didPanic := false
- defer func() {
- // Only report that the test is complete if it doesn't panic,
- // as otherwise the test binary can exit before the panic is
- // reported to the user. See issue 41479.
- if didPanic {
- return
- }
- if err != nil {
- panic(err)
- }
- running.Delete(t.name)
- t.signal <- signal
- }()
-
- doPanic := func(err any) {
- t.Fail()
- if r := t.runCleanup(recoverAndReturnPanic); r != nil {
- t.Logf("cleanup panicked with %v", r)
- }
- // Flush the output log up to the root before dying.
- for root := &t.common; root.parent != nil; root = root.parent {
- root.mu.Lock()
- root.duration += time.Since(root.start)
- d := root.duration
- root.mu.Unlock()
- root.flushToParent(root.name, "--- FAIL: %s (%s)\n", root.name, fmtDuration(d))
- if r := root.parent.runCleanup(recoverAndReturnPanic); r != nil {
- fmt.Fprintf(root.parent.w, "cleanup panicked with %v", r)
- }
- }
- didPanic = true
- panic(err)
- }
- if err != nil {
- doPanic(err)
- }
-
- t.duration += time.Since(t.start)
-
- if len(t.sub) > 0 {
- // Run parallel subtests.
- // Decrease the running count for this test.
- t.context.release()
- // Release the parallel subtests.
- close(t.barrier)
- // Wait for subtests to complete.
- for _, sub := range t.sub {
- <-sub.signal
- }
- cleanupStart := time.Now()
- err := t.runCleanup(recoverAndReturnPanic)
- t.duration += time.Since(cleanupStart)
- if err != nil {
- doPanic(err)
- }
- if !t.isParallel {
- // Reacquire the count for sequential tests. See comment in Run.
- t.context.waitParallel()
- }
- } else if t.isParallel {
- // Only release the count for this test if it was run as a parallel
- // test. See comment in Run method.
- t.context.release()
- }
- t.report() // Report after all subtests have finished.
-
- // Do not lock t.done to allow race detector to detect race in case
- // the user does not appropriately synchronize a goroutine.
- t.done = true
- if t.parent != nil && !t.hasSub.Load() {
- t.setRan()
- }
- }()
- defer func() {
- if len(t.sub) == 0 {
- t.runCleanup(normalPanic)
- }
- }()
-
- t.start = time.Now()
- t.raceErrors = -race.Errors()
- fn(t)
-
- // code beyond here will not be executed when FailNow is invoked
- t.mu.Lock()
- t.finished = true
- t.mu.Unlock()
-}
-
-// Run runs f as a subtest of t called name. It runs f in a separate goroutine
-// and blocks until f returns or calls t.Parallel to become a parallel test.
-// Run reports whether f succeeded (or at least did not fail before calling t.Parallel).
-//
-// Run may be called simultaneously from multiple goroutines, but all such calls
-// must return before the outer test function for t returns.
-func (t *T) Run(name string, f func(t *T)) bool {
- if t.cleanupStarted.Load() {
- panic("testing: t.Run called during t.Cleanup")
- }
-
- t.hasSub.Store(true)
- testName, ok, _ := t.context.match.fullName(&t.common, name)
- if !ok || shouldFailFast() {
- return true
- }
- // Record the stack trace at the point of this call so that if the subtest
- // function - which runs in a separate stack - is marked as a helper, we can
- // continue walking the stack into the parent test.
- var pc [maxStackLen]uintptr
- n := runtime.Callers(2, pc[:])
- t = &T{
- common: common{
- barrier: make(chan bool),
- signal: make(chan bool, 1),
- name: testName,
- parent: &t.common,
- level: t.level + 1,
- creator: pc[:n],
- chatty: t.chatty,
- },
- context: t.context,
- }
- t.w = indenter{&t.common}
-
- if t.chatty != nil {
- t.chatty.Updatef(t.name, "=== RUN %s\n", t.name)
- }
- running.Store(t.name, time.Now())
-
- // Instead of reducing the running count of this test before calling the
- // tRunner and increasing it afterwards, we rely on tRunner keeping the
- // count correct. This ensures that a sequence of sequential tests runs
- // without being preempted, even when their parent is a parallel test. This
- // may especially reduce surprises if *parallel == 1.
- go tRunner(t, f)
- if !<-t.signal {
- // At this point, it is likely that FailNow was called on one of the
- // parent tests by one of the subtests. Continue aborting up the chain.
- runtime.Goexit()
- }
- if t.chatty != nil && t.chatty.json {
- t.chatty.Updatef(t.parent.name, "=== NAME %s\n", t.parent.name)
- }
- return !t.failed
-}
-
-// Deadline reports the time at which the test binary will have
-// exceeded the timeout specified by the -timeout flag.
-//
-// The ok result is false if the -timeout flag indicates “no timeout” (0).
-func (t *T) Deadline() (deadline time.Time, ok bool) {
- deadline = t.context.deadline
- return deadline, !deadline.IsZero()
-}
-
-// testContext holds all fields that are common to all tests. This includes
-// synchronization primitives to run at most *parallel tests.
-type testContext struct {
- match *matcher
- deadline time.Time
-
- // isFuzzing is true in the context used when generating random inputs
- // for fuzz targets. isFuzzing is false when running normal tests and
- // when running fuzz tests as unit tests (without -fuzz or when -fuzz
- // does not match).
- isFuzzing bool
-
- mu sync.Mutex
-
- // Channel used to signal tests that are ready to be run in parallel.
- startParallel chan bool
-
- // running is the number of tests currently running in parallel.
- // This does not include tests that are waiting for subtests to complete.
- running int
-
- // numWaiting is the number tests waiting to be run in parallel.
- numWaiting int
-
- // maxParallel is a copy of the parallel flag.
- maxParallel int
-}
-
-func newTestContext(maxParallel int, m *matcher) *testContext {
- return &testContext{
- match: m,
- startParallel: make(chan bool),
- maxParallel: maxParallel,
- running: 1, // Set the count to 1 for the main (sequential) test.
- }
-}
-
-func (c *testContext) waitParallel() {
- c.mu.Lock()
- if c.running < c.maxParallel {
- c.running++
- c.mu.Unlock()
- return
- }
- c.numWaiting++
- c.mu.Unlock()
- <-c.startParallel
-}
-
-func (c *testContext) release() {
- c.mu.Lock()
- if c.numWaiting == 0 {
- c.running--
- c.mu.Unlock()
- return
- }
- c.numWaiting--
- c.mu.Unlock()
- c.startParallel <- true // Pick a waiting test to be run.
-}
-
-// No one should be using func Main anymore.
-// See the doc comment on func Main and use MainStart instead.
-var errMain = errors.New("testing: unexpected use of func Main")
-
-type matchStringOnly func(pat, str string) (bool, error)
-
-func (f matchStringOnly) MatchString(pat, str string) (bool, error) { return f(pat, str) }
-func (f matchStringOnly) StartCPUProfile(w io.Writer) error { return errMain }
-func (f matchStringOnly) StopCPUProfile() {}
-func (f matchStringOnly) WriteProfileTo(string, io.Writer, int) error { return errMain }
-func (f matchStringOnly) ImportPath() string { return "" }
-func (f matchStringOnly) StartTestLog(io.Writer) {}
-func (f matchStringOnly) StopTestLog() error { return errMain }
-func (f matchStringOnly) SetPanicOnExit0(bool) {}
-func (f matchStringOnly) CoordinateFuzzing(time.Duration, int64, time.Duration, int64, int, []corpusEntry, []reflect.Type, string, string) error {
- return errMain
-}
-func (f matchStringOnly) RunFuzzWorker(func(corpusEntry) error) error { return errMain }
-func (f matchStringOnly) ReadCorpus(string, []reflect.Type) ([]corpusEntry, error) {
- return nil, errMain
-}
-func (f matchStringOnly) CheckCorpus([]any, []reflect.Type) error { return nil }
-func (f matchStringOnly) ResetCoverage() {}
-func (f matchStringOnly) SnapshotCoverage() {}
-
-// Main is an internal function, part of the implementation of the "go test" command.
-// It was exported because it is cross-package and predates "internal" packages.
-// It is no longer used by "go test" but preserved, as much as possible, for other
-// systems that simulate "go test" using Main, but Main sometimes cannot be updated as
-// new functionality is added to the testing package.
-// Systems simulating "go test" should be updated to use MainStart.
-func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) {
- os.Exit(MainStart(matchStringOnly(matchString), tests, benchmarks, nil, examples).Run())
-}
-
-// M is a type passed to a TestMain function to run the actual tests.
-type M struct {
- deps testDeps
- tests []InternalTest
- benchmarks []InternalBenchmark
- fuzzTargets []InternalFuzzTarget
- examples []InternalExample
-
- timer *time.Timer
- afterOnce sync.Once
-
- numRun int
-
- // value to pass to os.Exit, the outer test func main
- // harness calls os.Exit with this code. See #34129.
- exitCode int
-}
-
-// testDeps is an internal interface of functionality that is
-// passed into this package by a test's generated main package.
-// The canonical implementation of this interface is
-// testing/internal/testdeps's TestDeps.
-type testDeps interface {
- ImportPath() string
- MatchString(pat, str string) (bool, error)
- SetPanicOnExit0(bool)
- StartCPUProfile(io.Writer) error
- StopCPUProfile()
- StartTestLog(io.Writer)
- StopTestLog() error
- WriteProfileTo(string, io.Writer, int) error
- CoordinateFuzzing(time.Duration, int64, time.Duration, int64, int, []corpusEntry, []reflect.Type, string, string) error
- RunFuzzWorker(func(corpusEntry) error) error
- ReadCorpus(string, []reflect.Type) ([]corpusEntry, error)
- CheckCorpus([]any, []reflect.Type) error
- ResetCoverage()
- SnapshotCoverage()
-}
-
-// MainStart is meant for use by tests generated by 'go test'.
-// It is not meant to be called directly and is not subject to the Go 1 compatibility document.
-// It may change signature from release to release.
-func MainStart(deps testDeps, tests []InternalTest, benchmarks []InternalBenchmark, fuzzTargets []InternalFuzzTarget, examples []InternalExample) *M {
- Init()
- return &M{
- deps: deps,
- tests: tests,
- benchmarks: benchmarks,
- fuzzTargets: fuzzTargets,
- examples: examples,
- }
-}
-
-var testingTesting bool
-var realStderr *os.File
-
-// Run runs the tests. It returns an exit code to pass to os.Exit.
-func (m *M) Run() (code int) {
- defer func() {
- code = m.exitCode
- }()
-
- // Count the number of calls to m.Run.
- // We only ever expected 1, but we didn't enforce that,
- // and now there are tests in the wild that call m.Run multiple times.
- // Sigh. go.dev/issue/23129.
- m.numRun++
-
- // TestMain may have already called flag.Parse.
- if !flag.Parsed() {
- flag.Parse()
- }
-
- if chatty.json {
- // With -v=json, stdout and stderr are pointing to the same pipe,
- // which is leading into test2json. In general, operating systems
- // do a good job of ensuring that writes to the same pipe through
- // different file descriptors are delivered whole, so that writing
- // AAA to stdout and BBB to stderr simultaneously produces
- // AAABBB or BBBAAA on the pipe, not something like AABBBA.
- // However, the exception to this is when the pipe fills: in that
- // case, Go's use of non-blocking I/O means that writing AAA
- // or BBB might be split across multiple system calls, making it
- // entirely possible to get output like AABBBA. The same problem
- // happens inside the operating system kernel if we switch to
- // blocking I/O on the pipe. This interleaved output can do things
- // like print unrelated messages in the middle of a TestFoo line,
- // which confuses test2json. Setting os.Stderr = os.Stdout will make
- // them share a single pfd, which will hold a lock for each program
- // write, preventing any interleaving.
- //
- // It might be nice to set Stderr = Stdout always, or perhaps if
- // we can tell they are the same file, but for now -v=json is
- // a very clear signal. Making the two files the same may cause
- // surprises if programs close os.Stdout but expect to be able
- // to continue to write to os.Stderr, but it's hard to see why a
- // test would think it could take over global state that way.
- //
- // This fix only helps programs where the output is coming directly
- // from Go code. It does not help programs in which a subprocess is
- // writing to stderr or stdout at the same time that a Go test is writing output.
- // It also does not help when the output is coming from the runtime,
- // such as when using the print/println functions, since that code writes
- // directly to fd 2 without any locking.
- // We keep realStderr around to prevent fd 2 from being closed.
- //
- // See go.dev/issue/33419.
- realStderr = os.Stderr
- os.Stderr = os.Stdout
- }
-
- if *parallel < 1 {
- fmt.Fprintln(os.Stderr, "testing: -parallel can only be given a positive integer")
- flag.Usage()
- m.exitCode = 2
- return
- }
- if *matchFuzz != "" && *fuzzCacheDir == "" {
- fmt.Fprintln(os.Stderr, "testing: -test.fuzzcachedir must be set if -test.fuzz is set")
- flag.Usage()
- m.exitCode = 2
- return
- }
-
- if *matchList != "" {
- listTests(m.deps.MatchString, m.tests, m.benchmarks, m.fuzzTargets, m.examples)
- m.exitCode = 0
- return
- }
-
- if *shuffle != "off" {
- var n int64
- var err error
- if *shuffle == "on" {
- n = time.Now().UnixNano()
- } else {
- n, err = strconv.ParseInt(*shuffle, 10, 64)
- if err != nil {
- fmt.Fprintln(os.Stderr, `testing: -shuffle should be "off", "on", or a valid integer:`, err)
- m.exitCode = 2
- return
- }
- }
- fmt.Println("-test.shuffle", n)
- rng := rand.New(rand.NewSource(n))
- rng.Shuffle(len(m.tests), func(i, j int) { m.tests[i], m.tests[j] = m.tests[j], m.tests[i] })
- rng.Shuffle(len(m.benchmarks), func(i, j int) { m.benchmarks[i], m.benchmarks[j] = m.benchmarks[j], m.benchmarks[i] })
- }
-
- parseCpuList()
-
- m.before()
- defer m.after()
-
- // Run tests, examples, and benchmarks unless this is a fuzz worker process.
- // Workers start after this is done by their parent process, and they should
- // not repeat this work.
- if !*isFuzzWorker {
- deadline := m.startAlarm()
- haveExamples = len(m.examples) > 0
- testRan, testOk := runTests(m.deps.MatchString, m.tests, deadline)
- fuzzTargetsRan, fuzzTargetsOk := runFuzzTests(m.deps, m.fuzzTargets, deadline)
- exampleRan, exampleOk := runExamples(m.deps.MatchString, m.examples)
- m.stopAlarm()
- if !testRan && !exampleRan && !fuzzTargetsRan && *matchBenchmarks == "" && *matchFuzz == "" {
- fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
- if testingTesting && *match != "^$" {
- // If this happens during testing of package testing it could be that
- // package testing's own logic for when to run a test is broken,
- // in which case every test will run nothing and succeed,
- // with no obvious way to detect this problem (since no tests are running).
- // So make 'no tests to run' a hard failure when testing package testing itself.
- // The compile-only builders use -run=^$ to run no tests, so allow that.
- fmt.Print(chatty.prefix(), "FAIL: package testing must run tests\n")
- testOk = false
- }
- }
- if !testOk || !exampleOk || !fuzzTargetsOk || !runBenchmarks(m.deps.ImportPath(), m.deps.MatchString, m.benchmarks) || race.Errors() > 0 {
- fmt.Print(chatty.prefix(), "FAIL\n")
- m.exitCode = 1
- return
- }
- }
-
- fuzzingOk := runFuzzing(m.deps, m.fuzzTargets)
- if !fuzzingOk {
- fmt.Print(chatty.prefix(), "FAIL\n")
- if *isFuzzWorker {
- m.exitCode = fuzzWorkerExitCode
- } else {
- m.exitCode = 1
- }
- return
- }
-
- m.exitCode = 0
- if !*isFuzzWorker {
- fmt.Print(chatty.prefix(), "PASS\n")
- }
- return
-}
-
-func (t *T) report() {
- if t.parent == nil {
- return
- }
- dstr := fmtDuration(t.duration)
- format := "--- %s: %s (%s)\n"
- if t.Failed() {
- t.flushToParent(t.name, format, "FAIL", t.name, dstr)
- } else if t.chatty != nil {
- if t.Skipped() {
- t.flushToParent(t.name, format, "SKIP", t.name, dstr)
- } else {
- t.flushToParent(t.name, format, "PASS", t.name, dstr)
- }
- }
-}
-
-func listTests(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, fuzzTargets []InternalFuzzTarget, examples []InternalExample) {
- if _, err := matchString(*matchList, "non-empty"); err != nil {
- fmt.Fprintf(os.Stderr, "testing: invalid regexp in -test.list (%q): %s\n", *matchList, err)
- os.Exit(1)
- }
-
- for _, test := range tests {
- if ok, _ := matchString(*matchList, test.Name); ok {
- fmt.Println(test.Name)
- }
- }
- for _, bench := range benchmarks {
- if ok, _ := matchString(*matchList, bench.Name); ok {
- fmt.Println(bench.Name)
- }
- }
- for _, fuzzTarget := range fuzzTargets {
- if ok, _ := matchString(*matchList, fuzzTarget.Name); ok {
- fmt.Println(fuzzTarget.Name)
- }
- }
- for _, example := range examples {
- if ok, _ := matchString(*matchList, example.Name); ok {
- fmt.Println(example.Name)
- }
- }
-}
-
-// RunTests is an internal function but exported because it is cross-package;
-// it is part of the implementation of the "go test" command.
-func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) {
- var deadline time.Time
- if *timeout > 0 {
- deadline = time.Now().Add(*timeout)
- }
- ran, ok := runTests(matchString, tests, deadline)
- if !ran && !haveExamples {
- fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
- }
- return ok
-}
-
-func runTests(matchString func(pat, str string) (bool, error), tests []InternalTest, deadline time.Time) (ran, ok bool) {
- ok = true
- for _, procs := range cpuList {
- runtime.GOMAXPROCS(procs)
- for i := uint(0); i < *count; i++ {
- if shouldFailFast() {
- break
- }
- if i > 0 && !ran {
- // There were no tests to run on the first
- // iteration. This won't change, so no reason
- // to keep trying.
- break
- }
- ctx := newTestContext(*parallel, newMatcher(matchString, *match, "-test.run", *skip))
- ctx.deadline = deadline
- t := &T{
- common: common{
- signal: make(chan bool, 1),
- barrier: make(chan bool),
- w: os.Stdout,
- },
- context: ctx,
- }
- if Verbose() {
- t.chatty = newChattyPrinter(t.w)
- }
- tRunner(t, func(t *T) {
- for _, test := range tests {
- t.Run(test.Name, test.F)
- }
- })
- select {
- case <-t.signal:
- default:
- panic("internal error: tRunner exited without sending on t.signal")
- }
- ok = ok && !t.Failed()
- ran = ran || t.ran
- }
- }
- return ran, ok
-}
-
-// before runs before all testing.
-func (m *M) before() {
- if *memProfileRate > 0 {
- runtime.MemProfileRate = *memProfileRate
- }
- if *cpuProfile != "" {
- f, err := os.Create(toOutputDir(*cpuProfile))
- if err != nil {
- fmt.Fprintf(os.Stderr, "testing: %s\n", err)
- return
- }
- if err := m.deps.StartCPUProfile(f); err != nil {
- fmt.Fprintf(os.Stderr, "testing: can't start cpu profile: %s\n", err)
- f.Close()
- return
- }
- // Could save f so after can call f.Close; not worth the effort.
- }
- if *traceFile != "" {
- f, err := os.Create(toOutputDir(*traceFile))
- if err != nil {
- fmt.Fprintf(os.Stderr, "testing: %s\n", err)
- return
- }
- if err := trace.Start(f); err != nil {
- fmt.Fprintf(os.Stderr, "testing: can't start tracing: %s\n", err)
- f.Close()
- return
- }
- // Could save f so after can call f.Close; not worth the effort.
- }
- if *blockProfile != "" && *blockProfileRate >= 0 {
- runtime.SetBlockProfileRate(*blockProfileRate)
- }
- if *mutexProfile != "" && *mutexProfileFraction >= 0 {
- runtime.SetMutexProfileFraction(*mutexProfileFraction)
- }
- if *coverProfile != "" && CoverMode() == "" {
- fmt.Fprintf(os.Stderr, "testing: cannot use -test.coverprofile because test binary was not built with coverage enabled\n")
- os.Exit(2)
- }
- if *gocoverdir != "" && CoverMode() == "" {
- fmt.Fprintf(os.Stderr, "testing: cannot use -test.gocoverdir because test binary was not built with coverage enabled\n")
- os.Exit(2)
- }
- if *testlog != "" {
- // Note: Not using toOutputDir.
- // This file is for use by cmd/go, not users.
- var f *os.File
- var err error
- if m.numRun == 1 {
- f, err = os.Create(*testlog)
- } else {
- f, err = os.OpenFile(*testlog, os.O_WRONLY, 0)
- if err == nil {
- f.Seek(0, io.SeekEnd)
- }
- }
- if err != nil {
- fmt.Fprintf(os.Stderr, "testing: %s\n", err)
- os.Exit(2)
- }
- m.deps.StartTestLog(f)
- testlogFile = f
- }
- if *panicOnExit0 {
- m.deps.SetPanicOnExit0(true)
- }
-}
-
-// after runs after all testing.
-func (m *M) after() {
- m.afterOnce.Do(func() {
- m.writeProfiles()
- })
-
- // Restore PanicOnExit0 after every run, because we set it to true before
- // every run. Otherwise, if m.Run is called multiple times the behavior of
- // os.Exit(0) will not be restored after the second run.
- if *panicOnExit0 {
- m.deps.SetPanicOnExit0(false)
- }
-}
-
-func (m *M) writeProfiles() {
- if *testlog != "" {
- if err := m.deps.StopTestLog(); err != nil {
- fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *testlog, err)
- os.Exit(2)
- }
- if err := testlogFile.Close(); err != nil {
- fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *testlog, err)
- os.Exit(2)
- }
- }
- if *cpuProfile != "" {
- m.deps.StopCPUProfile() // flushes profile to disk
- }
- if *traceFile != "" {
- trace.Stop() // flushes trace to disk
- }
- if *memProfile != "" {
- f, err := os.Create(toOutputDir(*memProfile))
- if err != nil {
- fmt.Fprintf(os.Stderr, "testing: %s\n", err)
- os.Exit(2)
- }
- runtime.GC() // materialize all statistics
- if err = m.deps.WriteProfileTo("allocs", f, 0); err != nil {
- fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *memProfile, err)
- os.Exit(2)
- }
- f.Close()
- }
- if *blockProfile != "" && *blockProfileRate >= 0 {
- f, err := os.Create(toOutputDir(*blockProfile))
- if err != nil {
- fmt.Fprintf(os.Stderr, "testing: %s\n", err)
- os.Exit(2)
- }
- if err = m.deps.WriteProfileTo("block", f, 0); err != nil {
- fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *blockProfile, err)
- os.Exit(2)
- }
- f.Close()
- }
- if *mutexProfile != "" && *mutexProfileFraction >= 0 {
- f, err := os.Create(toOutputDir(*mutexProfile))
- if err != nil {
- fmt.Fprintf(os.Stderr, "testing: %s\n", err)
- os.Exit(2)
- }
- if err = m.deps.WriteProfileTo("mutex", f, 0); err != nil {
- fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *mutexProfile, err)
- os.Exit(2)
- }
- f.Close()
- }
- if CoverMode() != "" {
- coverReport()
- }
-}
-
-// toOutputDir returns the file name relocated, if required, to outputDir.
-// Simple implementation to avoid pulling in path/filepath.
-func toOutputDir(path string) string {
- if *outputDir == "" || path == "" {
- return path
- }
- // On Windows, it's clumsy, but we can be almost always correct
- // by just looking for a drive letter and a colon.
- // Absolute paths always have a drive letter (ignoring UNC).
- // Problem: if path == "C:A" and outputdir == "C:\Go" it's unclear
- // what to do, but even then path/filepath doesn't help.
- // TODO: Worth doing better? Probably not, because we're here only
- // under the management of go test.
- if runtime.GOOS == "windows" && len(path) >= 2 {
- letter, colon := path[0], path[1]
- if ('a' <= letter && letter <= 'z' || 'A' <= letter && letter <= 'Z') && colon == ':' {
- // If path starts with a drive letter we're stuck with it regardless.
- return path
- }
- }
- if os.IsPathSeparator(path[0]) {
- return path
- }
- return fmt.Sprintf("%s%c%s", *outputDir, os.PathSeparator, path)
-}
-
-// startAlarm starts an alarm if requested.
-func (m *M) startAlarm() time.Time {
- if *timeout <= 0 {
- return time.Time{}
- }
-
- deadline := time.Now().Add(*timeout)
- m.timer = time.AfterFunc(*timeout, func() {
- m.after()
- debug.SetTraceback("all")
- extra := ""
-
- if list := runningList(); len(list) > 0 {
- var b strings.Builder
- b.WriteString("\nrunning tests:")
- for _, name := range list {
- b.WriteString("\n\t")
- b.WriteString(name)
- }
- extra = b.String()
- }
- panic(fmt.Sprintf("test timed out after %v%s", *timeout, extra))
- })
- return deadline
-}
-
-// runningList returns the list of running tests.
-func runningList() []string {
- var list []string
- running.Range(func(k, v any) bool {
- list = append(list, fmt.Sprintf("%s (%v)", k.(string), time.Since(v.(time.Time)).Round(time.Second)))
- return true
- })
- sort.Strings(list)
- return list
-}
-
-// stopAlarm turns off the alarm.
-func (m *M) stopAlarm() {
- if *timeout > 0 {
- m.timer.Stop()
- }
-}
-
-func parseCpuList() {
- for _, val := range strings.Split(*cpuListStr, ",") {
- val = strings.TrimSpace(val)
- if val == "" {
- continue
- }
- cpu, err := strconv.Atoi(val)
- if err != nil || cpu <= 0 {
- fmt.Fprintf(os.Stderr, "testing: invalid value %q for -test.cpu\n", val)
- os.Exit(1)
- }
- cpuList = append(cpuList, cpu)
- }
- if cpuList == nil {
- cpuList = append(cpuList, runtime.GOMAXPROCS(-1))
- }
-}
-
-func shouldFailFast() bool {
- return *failFast && numFailed.Load() > 0
-}
diff --git a/contrib/go/_std_1.20/src/testing/ya.make b/contrib/go/_std_1.20/src/testing/ya.make
deleted file mode 100644
index b28ae6aff8..0000000000
--- a/contrib/go/_std_1.20/src/testing/ya.make
+++ /dev/null
@@ -1,40 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- allocs.go
- benchmark.go
- cover.go
- example.go
- fuzz.go
- match.go
- newcover.go
- run_example.go
- testing.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- testing_other.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- testing_other.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- testing_windows.go
- )
-ENDIF()
-
-END()
-
-RECURSE(
- fstest
- internal
- iotest
- quick
-)
diff --git a/contrib/go/_std_1.20/src/text/scanner/ya.make b/contrib/go/_std_1.20/src/text/scanner/ya.make
deleted file mode 100644
index 93f384c3eb..0000000000
--- a/contrib/go/_std_1.20/src/text/scanner/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- scanner.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/text/tabwriter/ya.make b/contrib/go/_std_1.20/src/text/tabwriter/ya.make
deleted file mode 100644
index a83d70acae..0000000000
--- a/contrib/go/_std_1.20/src/text/tabwriter/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- tabwriter.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/text/template/doc.go b/contrib/go/_std_1.20/src/text/template/doc.go
deleted file mode 100644
index 7817a17b96..0000000000
--- a/contrib/go/_std_1.20/src/text/template/doc.go
+++ /dev/null
@@ -1,464 +0,0 @@
-// Copyright 2011 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 template implements data-driven templates for generating textual output.
-
-To generate HTML output, see package html/template, which has the same interface
-as this package but automatically secures HTML output against certain attacks.
-
-Templates are executed by applying them to a data structure. Annotations in the
-template refer to elements of the data structure (typically a field of a struct
-or a key in a map) to control execution and derive values to be displayed.
-Execution of the template walks the structure and sets the cursor, represented
-by a period '.' and called "dot", to the value at the current location in the
-structure as execution proceeds.
-
-The input text for a template is UTF-8-encoded text in any format.
-"Actions"--data evaluations or control structures--are delimited by
-"{{" and "}}"; all text outside actions is copied to the output unchanged.
-
-Once parsed, a template may be executed safely in parallel, although if parallel
-executions share a Writer the output may be interleaved.
-
-Here is a trivial example that prints "17 items are made of wool".
-
- type Inventory struct {
- Material string
- Count uint
- }
- sweaters := Inventory{"wool", 17}
- tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}")
- if err != nil { panic(err) }
- err = tmpl.Execute(os.Stdout, sweaters)
- if err != nil { panic(err) }
-
-More intricate examples appear below.
-
-Text and spaces
-
-By default, all text between actions is copied verbatim when the template is
-executed. For example, the string " items are made of " in the example above
-appears on standard output when the program is run.
-
-However, to aid in formatting template source code, if an action's left
-delimiter (by default "{{") is followed immediately by a minus sign and white
-space, all trailing white space is trimmed from the immediately preceding text.
-Similarly, if the right delimiter ("}}") is preceded by white space and a minus
-sign, all leading white space is trimmed from the immediately following text.
-In these trim markers, the white space must be present:
-"{{- 3}}" is like "{{3}}" but trims the immediately preceding text, while
-"{{-3}}" parses as an action containing the number -3.
-
-For instance, when executing the template whose source is
-
- "{{23 -}} < {{- 45}}"
-
-the generated output would be
-
- "23<45"
-
-For this trimming, the definition of white space characters is the same as in Go:
-space, horizontal tab, carriage return, and newline.
-
-Actions
-
-Here is the list of actions. "Arguments" and "pipelines" are evaluations of
-data, defined in detail in the corresponding sections that follow.
-
-*/
-// {{/* a comment */}}
-// {{- /* a comment with white space trimmed from preceding and following text */ -}}
-// A comment; discarded. May contain newlines.
-// Comments do not nest and must start and end at the
-// delimiters, as shown here.
-/*
-
- {{pipeline}}
- The default textual representation (the same as would be
- printed by fmt.Print) of the value of the pipeline is copied
- to the output.
-
- {{if pipeline}} T1 {{end}}
- If the value of the pipeline is empty, no output is generated;
- otherwise, T1 is executed. The empty values are false, 0, any
- nil pointer or interface value, and any array, slice, map, or
- string of length zero.
- Dot is unaffected.
-
- {{if pipeline}} T1 {{else}} T0 {{end}}
- If the value of the pipeline is empty, T0 is executed;
- otherwise, T1 is executed. Dot is unaffected.
-
- {{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
- To simplify the appearance of if-else chains, the else action
- of an if may include another if directly; the effect is exactly
- the same as writing
- {{if pipeline}} T1 {{else}}{{if pipeline}} T0 {{end}}{{end}}
-
- {{range pipeline}} T1 {{end}}
- The value of the pipeline must be an array, slice, map, or channel.
- If the value of the pipeline has length zero, nothing is output;
- otherwise, dot is set to the successive elements of the array,
- slice, or map and T1 is executed. If the value is a map and the
- keys are of basic type with a defined order, the elements will be
- visited in sorted key order.
-
- {{range pipeline}} T1 {{else}} T0 {{end}}
- The value of the pipeline must be an array, slice, map, or channel.
- If the value of the pipeline has length zero, dot is unaffected and
- T0 is executed; otherwise, dot is set to the successive elements
- of the array, slice, or map and T1 is executed.
-
- {{break}}
- The innermost {{range pipeline}} loop is ended early, stopping the
- current iteration and bypassing all remaining iterations.
-
- {{continue}}
- The current iteration of the innermost {{range pipeline}} loop is
- stopped, and the loop starts the next iteration.
-
- {{template "name"}}
- The template with the specified name is executed with nil data.
-
- {{template "name" pipeline}}
- The template with the specified name is executed with dot set
- to the value of the pipeline.
-
- {{block "name" pipeline}} T1 {{end}}
- A block is shorthand for defining a template
- {{define "name"}} T1 {{end}}
- and then executing it in place
- {{template "name" pipeline}}
- The typical use is to define a set of root templates that are
- then customized by redefining the block templates within.
-
- {{with pipeline}} T1 {{end}}
- If the value of the pipeline is empty, no output is generated;
- otherwise, dot is set to the value of the pipeline and T1 is
- executed.
-
- {{with pipeline}} T1 {{else}} T0 {{end}}
- If the value of the pipeline is empty, dot is unaffected and T0
- is executed; otherwise, dot is set to the value of the pipeline
- and T1 is executed.
-
-Arguments
-
-An argument is a simple value, denoted by one of the following.
-
- - A boolean, string, character, integer, floating-point, imaginary
- or complex constant in Go syntax. These behave like Go's untyped
- constants. Note that, as in Go, whether a large integer constant
- overflows when assigned or passed to a function can depend on whether
- the host machine's ints are 32 or 64 bits.
- - The keyword nil, representing an untyped Go nil.
- - The character '.' (period):
- .
- The result is the value of dot.
- - A variable name, which is a (possibly empty) alphanumeric string
- preceded by a dollar sign, such as
- $piOver2
- or
- $
- The result is the value of the variable.
- Variables are described below.
- - The name of a field of the data, which must be a struct, preceded
- by a period, such as
- .Field
- The result is the value of the field. Field invocations may be
- chained:
- .Field1.Field2
- Fields can also be evaluated on variables, including chaining:
- $x.Field1.Field2
- - The name of a key of the data, which must be a map, preceded
- by a period, such as
- .Key
- The result is the map element value indexed by the key.
- Key invocations may be chained and combined with fields to any
- depth:
- .Field1.Key1.Field2.Key2
- Although the key must be an alphanumeric identifier, unlike with
- field names they do not need to start with an upper case letter.
- Keys can also be evaluated on variables, including chaining:
- $x.key1.key2
- - The name of a niladic method of the data, preceded by a period,
- such as
- .Method
- The result is the value of invoking the method with dot as the
- receiver, dot.Method(). Such a method must have one return value (of
- any type) or two return values, the second of which is an error.
- If it has two and the returned error is non-nil, execution terminates
- and an error is returned to the caller as the value of Execute.
- Method invocations may be chained and combined with fields and keys
- to any depth:
- .Field1.Key1.Method1.Field2.Key2.Method2
- Methods can also be evaluated on variables, including chaining:
- $x.Method1.Field
- - The name of a niladic function, such as
- fun
- The result is the value of invoking the function, fun(). The return
- types and values behave as in methods. Functions and function
- names are described below.
- - A parenthesized instance of one the above, for grouping. The result
- may be accessed by a field or map key invocation.
- print (.F1 arg1) (.F2 arg2)
- (.StructValuedMethod "arg").Field
-
-Arguments may evaluate to any type; if they are pointers the implementation
-automatically indirects to the base type when required.
-If an evaluation yields a function value, such as a function-valued
-field of a struct, the function is not invoked automatically, but it
-can be used as a truth value for an if action and the like. To invoke
-it, use the call function, defined below.
-
-Pipelines
-
-A pipeline is a possibly chained sequence of "commands". A command is a simple
-value (argument) or a function or method call, possibly with multiple arguments:
-
- Argument
- The result is the value of evaluating the argument.
- .Method [Argument...]
- The method can be alone or the last element of a chain but,
- unlike methods in the middle of a chain, it can take arguments.
- The result is the value of calling the method with the
- arguments:
- dot.Method(Argument1, etc.)
- functionName [Argument...]
- The result is the value of calling the function associated
- with the name:
- function(Argument1, etc.)
- Functions and function names are described below.
-
-A pipeline may be "chained" by separating a sequence of commands with pipeline
-characters '|'. In a chained pipeline, the result of each command is
-passed as the last argument of the following command. The output of the final
-command in the pipeline is the value of the pipeline.
-
-The output of a command will be either one value or two values, the second of
-which has type error. If that second value is present and evaluates to
-non-nil, execution terminates and the error is returned to the caller of
-Execute.
-
-Variables
-
-A pipeline inside an action may initialize a variable to capture the result.
-The initialization has syntax
-
- $variable := pipeline
-
-where $variable is the name of the variable. An action that declares a
-variable produces no output.
-
-Variables previously declared can also be assigned, using the syntax
-
- $variable = pipeline
-
-If a "range" action initializes a variable, the variable is set to the
-successive elements of the iteration. Also, a "range" may declare two
-variables, separated by a comma:
-
- range $index, $element := pipeline
-
-in which case $index and $element are set to the successive values of the
-array/slice index or map key and element, respectively. Note that if there is
-only one variable, it is assigned the element; this is opposite to the
-convention in Go range clauses.
-
-A variable's scope extends to the "end" action of the control structure ("if",
-"with", or "range") in which it is declared, or to the end of the template if
-there is no such control structure. A template invocation does not inherit
-variables from the point of its invocation.
-
-When execution begins, $ is set to the data argument passed to Execute, that is,
-to the starting value of dot.
-
-Examples
-
-Here are some example one-line templates demonstrating pipelines and variables.
-All produce the quoted word "output":
-
- {{"\"output\""}}
- A string constant.
- {{`"output"`}}
- A raw string constant.
- {{printf "%q" "output"}}
- A function call.
- {{"output" | printf "%q"}}
- A function call whose final argument comes from the previous
- command.
- {{printf "%q" (print "out" "put")}}
- A parenthesized argument.
- {{"put" | printf "%s%s" "out" | printf "%q"}}
- A more elaborate call.
- {{"output" | printf "%s" | printf "%q"}}
- A longer chain.
- {{with "output"}}{{printf "%q" .}}{{end}}
- A with action using dot.
- {{with $x := "output" | printf "%q"}}{{$x}}{{end}}
- A with action that creates and uses a variable.
- {{with $x := "output"}}{{printf "%q" $x}}{{end}}
- A with action that uses the variable in another action.
- {{with $x := "output"}}{{$x | printf "%q"}}{{end}}
- The same, but pipelined.
-
-Functions
-
-During execution functions are found in two function maps: first in the
-template, then in the global function map. By default, no functions are defined
-in the template but the Funcs method can be used to add them.
-
-Predefined global functions are named as follows.
-
- and
- Returns the boolean AND of its arguments by returning the
- first empty argument or the last argument. That is,
- "and x y" behaves as "if x then y else x."
- Evaluation proceeds through the arguments left to right
- and returns when the result is determined.
- call
- Returns the result of calling the first argument, which
- must be a function, with the remaining arguments as parameters.
- Thus "call .X.Y 1 2" is, in Go notation, dot.X.Y(1, 2) where
- Y is a func-valued field, map entry, or the like.
- The first argument must be the result of an evaluation
- that yields a value of function type (as distinct from
- a predefined function such as print). The function must
- return either one or two result values, the second of which
- is of type error. If the arguments don't match the function
- or the returned error value is non-nil, execution stops.
- html
- Returns the escaped HTML equivalent of the textual
- representation of its arguments. This function is unavailable
- in html/template, with a few exceptions.
- index
- Returns the result of indexing its first argument by the
- following arguments. Thus "index x 1 2 3" is, in Go syntax,
- x[1][2][3]. Each indexed item must be a map, slice, or array.
- slice
- slice returns the result of slicing its first argument by the
- remaining arguments. Thus "slice x 1 2" is, in Go syntax, x[1:2],
- while "slice x" is x[:], "slice x 1" is x[1:], and "slice x 1 2 3"
- is x[1:2:3]. The first argument must be a string, slice, or array.
- js
- Returns the escaped JavaScript equivalent of the textual
- representation of its arguments.
- len
- Returns the integer length of its argument.
- not
- Returns the boolean negation of its single argument.
- or
- Returns the boolean OR of its arguments by returning the
- first non-empty argument or the last argument, that is,
- "or x y" behaves as "if x then x else y".
- Evaluation proceeds through the arguments left to right
- and returns when the result is determined.
- print
- An alias for fmt.Sprint
- printf
- An alias for fmt.Sprintf
- println
- An alias for fmt.Sprintln
- urlquery
- Returns the escaped value of the textual representation of
- its arguments in a form suitable for embedding in a URL query.
- This function is unavailable in html/template, with a few
- exceptions.
-
-The boolean functions take any zero value to be false and a non-zero
-value to be true.
-
-There is also a set of binary comparison operators defined as
-functions:
-
- eq
- Returns the boolean truth of arg1 == arg2
- ne
- Returns the boolean truth of arg1 != arg2
- lt
- Returns the boolean truth of arg1 < arg2
- le
- Returns the boolean truth of arg1 <= arg2
- gt
- Returns the boolean truth of arg1 > arg2
- ge
- Returns the boolean truth of arg1 >= arg2
-
-For simpler multi-way equality tests, eq (only) accepts two or more
-arguments and compares the second and subsequent to the first,
-returning in effect
-
- arg1==arg2 || arg1==arg3 || arg1==arg4 ...
-
-(Unlike with || in Go, however, eq is a function call and all the
-arguments will be evaluated.)
-
-The comparison functions work on any values whose type Go defines as
-comparable. For basic types such as integers, the rules are relaxed:
-size and exact type are ignored, so any integer value, signed or unsigned,
-may be compared with any other integer value. (The arithmetic value is compared,
-not the bit pattern, so all negative integers are less than all unsigned integers.)
-However, as usual, one may not compare an int with a float32 and so on.
-
-Associated templates
-
-Each template is named by a string specified when it is created. Also, each
-template is associated with zero or more other templates that it may invoke by
-name; such associations are transitive and form a name space of templates.
-
-A template may use a template invocation to instantiate another associated
-template; see the explanation of the "template" action above. The name must be
-that of a template associated with the template that contains the invocation.
-
-Nested template definitions
-
-When parsing a template, another template may be defined and associated with the
-template being parsed. Template definitions must appear at the top level of the
-template, much like global variables in a Go program.
-
-The syntax of such definitions is to surround each template declaration with a
-"define" and "end" action.
-
-The define action names the template being created by providing a string
-constant. Here is a simple example:
-
- {{define "T1"}}ONE{{end}}
- {{define "T2"}}TWO{{end}}
- {{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}}
- {{template "T3"}}
-
-This defines two templates, T1 and T2, and a third T3 that invokes the other two
-when it is executed. Finally it invokes T3. If executed this template will
-produce the text
-
- ONE TWO
-
-By construction, a template may reside in only one association. If it's
-necessary to have a template addressable from multiple associations, the
-template definition must be parsed multiple times to create distinct *Template
-values, or must be copied with the Clone or AddParseTree method.
-
-Parse may be called multiple times to assemble the various associated templates;
-see the ParseFiles and ParseGlob functions and methods for simple ways to parse
-related templates stored in files.
-
-A template may be executed directly or through ExecuteTemplate, which executes
-an associated template identified by name. To invoke our example above, we
-might write,
-
- err := tmpl.Execute(os.Stdout, "no data needed")
- if err != nil {
- log.Fatalf("execution failed: %s", err)
- }
-
-or to invoke a particular template explicitly by name,
-
- err := tmpl.ExecuteTemplate(os.Stdout, "T2", "no data needed")
- if err != nil {
- log.Fatalf("execution failed: %s", err)
- }
-
-*/
-package template
diff --git a/contrib/go/_std_1.20/src/text/template/funcs.go b/contrib/go/_std_1.20/src/text/template/funcs.go
deleted file mode 100644
index dbea6e705a..0000000000
--- a/contrib/go/_std_1.20/src/text/template/funcs.go
+++ /dev/null
@@ -1,776 +0,0 @@
-// Copyright 2011 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 template
-
-import (
- "errors"
- "fmt"
- "io"
- "net/url"
- "reflect"
- "strings"
- "sync"
- "unicode"
- "unicode/utf8"
-)
-
-// FuncMap is the type of the map defining the mapping from names to functions.
-// Each function must have either a single return value, or two return values of
-// which the second has type error. In that case, if the second (error)
-// return value evaluates to non-nil during execution, execution terminates and
-// Execute returns that error.
-//
-// Errors returned by Execute wrap the underlying error; call errors.As to
-// uncover them.
-//
-// When template execution invokes a function with an argument list, that list
-// must be assignable to the function's parameter types. Functions meant to
-// apply to arguments of arbitrary type can use parameters of type interface{} or
-// of type reflect.Value. Similarly, functions meant to return a result of arbitrary
-// type can return interface{} or reflect.Value.
-type FuncMap map[string]any
-
-// builtins returns the FuncMap.
-// It is not a global variable so the linker can dead code eliminate
-// more when this isn't called. See golang.org/issue/36021.
-// TODO: revert this back to a global map once golang.org/issue/2559 is fixed.
-func builtins() FuncMap {
- return FuncMap{
- "and": and,
- "call": call,
- "html": HTMLEscaper,
- "index": index,
- "slice": slice,
- "js": JSEscaper,
- "len": length,
- "not": not,
- "or": or,
- "print": fmt.Sprint,
- "printf": fmt.Sprintf,
- "println": fmt.Sprintln,
- "urlquery": URLQueryEscaper,
-
- // Comparisons
- "eq": eq, // ==
- "ge": ge, // >=
- "gt": gt, // >
- "le": le, // <=
- "lt": lt, // <
- "ne": ne, // !=
- }
-}
-
-var builtinFuncsOnce struct {
- sync.Once
- v map[string]reflect.Value
-}
-
-// builtinFuncsOnce lazily computes & caches the builtinFuncs map.
-// TODO: revert this back to a global map once golang.org/issue/2559 is fixed.
-func builtinFuncs() map[string]reflect.Value {
- builtinFuncsOnce.Do(func() {
- builtinFuncsOnce.v = createValueFuncs(builtins())
- })
- return builtinFuncsOnce.v
-}
-
-// createValueFuncs turns a FuncMap into a map[string]reflect.Value
-func createValueFuncs(funcMap FuncMap) map[string]reflect.Value {
- m := make(map[string]reflect.Value)
- addValueFuncs(m, funcMap)
- return m
-}
-
-// addValueFuncs adds to values the functions in funcs, converting them to reflect.Values.
-func addValueFuncs(out map[string]reflect.Value, in FuncMap) {
- for name, fn := range in {
- if !goodName(name) {
- panic(fmt.Errorf("function name %q is not a valid identifier", name))
- }
- v := reflect.ValueOf(fn)
- if v.Kind() != reflect.Func {
- panic("value for " + name + " not a function")
- }
- if !goodFunc(v.Type()) {
- panic(fmt.Errorf("can't install method/function %q with %d results", name, v.Type().NumOut()))
- }
- out[name] = v
- }
-}
-
-// addFuncs adds to values the functions in funcs. It does no checking of the input -
-// call addValueFuncs first.
-func addFuncs(out, in FuncMap) {
- for name, fn := range in {
- out[name] = fn
- }
-}
-
-// goodFunc reports whether the function or method has the right result signature.
-func goodFunc(typ reflect.Type) bool {
- // We allow functions with 1 result or 2 results where the second is an error.
- switch {
- case typ.NumOut() == 1:
- return true
- case typ.NumOut() == 2 && typ.Out(1) == errorType:
- return true
- }
- return false
-}
-
-// goodName reports whether the function name is a valid identifier.
-func goodName(name string) bool {
- if name == "" {
- return false
- }
- for i, r := range name {
- switch {
- case r == '_':
- case i == 0 && !unicode.IsLetter(r):
- return false
- case !unicode.IsLetter(r) && !unicode.IsDigit(r):
- return false
- }
- }
- return true
-}
-
-// findFunction looks for a function in the template, and global map.
-func findFunction(name string, tmpl *Template) (v reflect.Value, isBuiltin, ok bool) {
- if tmpl != nil && tmpl.common != nil {
- tmpl.muFuncs.RLock()
- defer tmpl.muFuncs.RUnlock()
- if fn := tmpl.execFuncs[name]; fn.IsValid() {
- return fn, false, true
- }
- }
- if fn := builtinFuncs()[name]; fn.IsValid() {
- return fn, true, true
- }
- return reflect.Value{}, false, false
-}
-
-// prepareArg checks if value can be used as an argument of type argType, and
-// converts an invalid value to appropriate zero if possible.
-func prepareArg(value reflect.Value, argType reflect.Type) (reflect.Value, error) {
- if !value.IsValid() {
- if !canBeNil(argType) {
- return reflect.Value{}, fmt.Errorf("value is nil; should be of type %s", argType)
- }
- value = reflect.Zero(argType)
- }
- if value.Type().AssignableTo(argType) {
- return value, nil
- }
- if intLike(value.Kind()) && intLike(argType.Kind()) && value.Type().ConvertibleTo(argType) {
- value = value.Convert(argType)
- return value, nil
- }
- return reflect.Value{}, fmt.Errorf("value has type %s; should be %s", value.Type(), argType)
-}
-
-func intLike(typ reflect.Kind) bool {
- switch typ {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return true
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return true
- }
- return false
-}
-
-// indexArg checks if a reflect.Value can be used as an index, and converts it to int if possible.
-func indexArg(index reflect.Value, cap int) (int, error) {
- var x int64
- switch index.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- x = index.Int()
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- x = int64(index.Uint())
- case reflect.Invalid:
- return 0, fmt.Errorf("cannot index slice/array with nil")
- default:
- return 0, fmt.Errorf("cannot index slice/array with type %s", index.Type())
- }
- if x < 0 || int(x) < 0 || int(x) > cap {
- return 0, fmt.Errorf("index out of range: %d", x)
- }
- return int(x), nil
-}
-
-// Indexing.
-
-// index returns the result of indexing its first argument by the following
-// arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each
-// indexed item must be a map, slice, or array.
-func index(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) {
- item = indirectInterface(item)
- if !item.IsValid() {
- return reflect.Value{}, fmt.Errorf("index of untyped nil")
- }
- for _, index := range indexes {
- index = indirectInterface(index)
- var isNil bool
- if item, isNil = indirect(item); isNil {
- return reflect.Value{}, fmt.Errorf("index of nil pointer")
- }
- switch item.Kind() {
- case reflect.Array, reflect.Slice, reflect.String:
- x, err := indexArg(index, item.Len())
- if err != nil {
- return reflect.Value{}, err
- }
- item = item.Index(x)
- case reflect.Map:
- index, err := prepareArg(index, item.Type().Key())
- if err != nil {
- return reflect.Value{}, err
- }
- if x := item.MapIndex(index); x.IsValid() {
- item = x
- } else {
- item = reflect.Zero(item.Type().Elem())
- }
- case reflect.Invalid:
- // the loop holds invariant: item.IsValid()
- panic("unreachable")
- default:
- return reflect.Value{}, fmt.Errorf("can't index item of type %s", item.Type())
- }
- }
- return item, nil
-}
-
-// Slicing.
-
-// slice returns the result of slicing its first argument by the remaining
-// arguments. Thus "slice x 1 2" is, in Go syntax, x[1:2], while "slice x"
-// is x[:], "slice x 1" is x[1:], and "slice x 1 2 3" is x[1:2:3]. The first
-// argument must be a string, slice, or array.
-func slice(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) {
- item = indirectInterface(item)
- if !item.IsValid() {
- return reflect.Value{}, fmt.Errorf("slice of untyped nil")
- }
- if len(indexes) > 3 {
- return reflect.Value{}, fmt.Errorf("too many slice indexes: %d", len(indexes))
- }
- var cap int
- switch item.Kind() {
- case reflect.String:
- if len(indexes) == 3 {
- return reflect.Value{}, fmt.Errorf("cannot 3-index slice a string")
- }
- cap = item.Len()
- case reflect.Array, reflect.Slice:
- cap = item.Cap()
- default:
- return reflect.Value{}, fmt.Errorf("can't slice item of type %s", item.Type())
- }
- // set default values for cases item[:], item[i:].
- idx := [3]int{0, item.Len()}
- for i, index := range indexes {
- x, err := indexArg(index, cap)
- if err != nil {
- return reflect.Value{}, err
- }
- idx[i] = x
- }
- // given item[i:j], make sure i <= j.
- if idx[0] > idx[1] {
- return reflect.Value{}, fmt.Errorf("invalid slice index: %d > %d", idx[0], idx[1])
- }
- if len(indexes) < 3 {
- return item.Slice(idx[0], idx[1]), nil
- }
- // given item[i:j:k], make sure i <= j <= k.
- if idx[1] > idx[2] {
- return reflect.Value{}, fmt.Errorf("invalid slice index: %d > %d", idx[1], idx[2])
- }
- return item.Slice3(idx[0], idx[1], idx[2]), nil
-}
-
-// Length
-
-// length returns the length of the item, with an error if it has no defined length.
-func length(item reflect.Value) (int, error) {
- item, isNil := indirect(item)
- if isNil {
- return 0, fmt.Errorf("len of nil pointer")
- }
- switch item.Kind() {
- case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
- return item.Len(), nil
- }
- return 0, fmt.Errorf("len of type %s", item.Type())
-}
-
-// Function invocation
-
-// call returns the result of evaluating the first argument as a function.
-// The function must return 1 result, or 2 results, the second of which is an error.
-func call(fn reflect.Value, args ...reflect.Value) (reflect.Value, error) {
- fn = indirectInterface(fn)
- if !fn.IsValid() {
- return reflect.Value{}, fmt.Errorf("call of nil")
- }
- typ := fn.Type()
- if typ.Kind() != reflect.Func {
- return reflect.Value{}, fmt.Errorf("non-function of type %s", typ)
- }
- if !goodFunc(typ) {
- return reflect.Value{}, fmt.Errorf("function called with %d args; should be 1 or 2", typ.NumOut())
- }
- numIn := typ.NumIn()
- var dddType reflect.Type
- if typ.IsVariadic() {
- if len(args) < numIn-1 {
- return reflect.Value{}, fmt.Errorf("wrong number of args: got %d want at least %d", len(args), numIn-1)
- }
- dddType = typ.In(numIn - 1).Elem()
- } else {
- if len(args) != numIn {
- return reflect.Value{}, fmt.Errorf("wrong number of args: got %d want %d", len(args), numIn)
- }
- }
- argv := make([]reflect.Value, len(args))
- for i, arg := range args {
- arg = indirectInterface(arg)
- // Compute the expected type. Clumsy because of variadics.
- argType := dddType
- if !typ.IsVariadic() || i < numIn-1 {
- argType = typ.In(i)
- }
-
- var err error
- if argv[i], err = prepareArg(arg, argType); err != nil {
- return reflect.Value{}, fmt.Errorf("arg %d: %w", i, err)
- }
- }
- return safeCall(fn, argv)
-}
-
-// safeCall runs fun.Call(args), and returns the resulting value and error, if
-// any. If the call panics, the panic value is returned as an error.
-func safeCall(fun reflect.Value, args []reflect.Value) (val reflect.Value, err error) {
- defer func() {
- if r := recover(); r != nil {
- if e, ok := r.(error); ok {
- err = e
- } else {
- err = fmt.Errorf("%v", r)
- }
- }
- }()
- ret := fun.Call(args)
- if len(ret) == 2 && !ret[1].IsNil() {
- return ret[0], ret[1].Interface().(error)
- }
- return ret[0], nil
-}
-
-// Boolean logic.
-
-func truth(arg reflect.Value) bool {
- t, _ := isTrue(indirectInterface(arg))
- return t
-}
-
-// and computes the Boolean AND of its arguments, returning
-// the first false argument it encounters, or the last argument.
-func and(arg0 reflect.Value, args ...reflect.Value) reflect.Value {
- panic("unreachable") // implemented as a special case in evalCall
-}
-
-// or computes the Boolean OR of its arguments, returning
-// the first true argument it encounters, or the last argument.
-func or(arg0 reflect.Value, args ...reflect.Value) reflect.Value {
- panic("unreachable") // implemented as a special case in evalCall
-}
-
-// not returns the Boolean negation of its argument.
-func not(arg reflect.Value) bool {
- return !truth(arg)
-}
-
-// Comparison.
-
-// TODO: Perhaps allow comparison between signed and unsigned integers.
-
-var (
- errBadComparisonType = errors.New("invalid type for comparison")
- errBadComparison = errors.New("incompatible types for comparison")
- errNoComparison = errors.New("missing argument for comparison")
-)
-
-type kind int
-
-const (
- invalidKind kind = iota
- boolKind
- complexKind
- intKind
- floatKind
- stringKind
- uintKind
-)
-
-func basicKind(v reflect.Value) (kind, error) {
- switch v.Kind() {
- case reflect.Bool:
- return boolKind, nil
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return intKind, nil
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- return uintKind, nil
- case reflect.Float32, reflect.Float64:
- return floatKind, nil
- case reflect.Complex64, reflect.Complex128:
- return complexKind, nil
- case reflect.String:
- return stringKind, nil
- }
- return invalidKind, errBadComparisonType
-}
-
-// isNil returns true if v is the zero reflect.Value, or nil of its type.
-func isNil(v reflect.Value) bool {
- if !v.IsValid() {
- return true
- }
- switch v.Kind() {
- case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice:
- return v.IsNil()
- }
- return false
-}
-
-// canCompare reports whether v1 and v2 are both the same kind, or one is nil.
-// Called only when dealing with nillable types, or there's about to be an error.
-func canCompare(v1, v2 reflect.Value) bool {
- k1 := v1.Kind()
- k2 := v2.Kind()
- if k1 == k2 {
- return true
- }
- // We know the type can be compared to nil.
- return k1 == reflect.Invalid || k2 == reflect.Invalid
-}
-
-// eq evaluates the comparison a == b || a == c || ...
-func eq(arg1 reflect.Value, arg2 ...reflect.Value) (bool, error) {
- arg1 = indirectInterface(arg1)
- if len(arg2) == 0 {
- return false, errNoComparison
- }
- k1, _ := basicKind(arg1)
- for _, arg := range arg2 {
- arg = indirectInterface(arg)
- k2, _ := basicKind(arg)
- truth := false
- if k1 != k2 {
- // Special case: Can compare integer values regardless of type's sign.
- switch {
- case k1 == intKind && k2 == uintKind:
- truth = arg1.Int() >= 0 && uint64(arg1.Int()) == arg.Uint()
- case k1 == uintKind && k2 == intKind:
- truth = arg.Int() >= 0 && arg1.Uint() == uint64(arg.Int())
- default:
- if arg1 != zero && arg != zero {
- return false, errBadComparison
- }
- }
- } else {
- switch k1 {
- case boolKind:
- truth = arg1.Bool() == arg.Bool()
- case complexKind:
- truth = arg1.Complex() == arg.Complex()
- case floatKind:
- truth = arg1.Float() == arg.Float()
- case intKind:
- truth = arg1.Int() == arg.Int()
- case stringKind:
- truth = arg1.String() == arg.String()
- case uintKind:
- truth = arg1.Uint() == arg.Uint()
- default:
- if !canCompare(arg1, arg) {
- return false, fmt.Errorf("non-comparable types %s: %v, %s: %v", arg1, arg1.Type(), arg.Type(), arg)
- }
- if isNil(arg1) || isNil(arg) {
- truth = isNil(arg) == isNil(arg1)
- } else {
- if !arg.Type().Comparable() {
- return false, fmt.Errorf("non-comparable type %s: %v", arg, arg.Type())
- }
- truth = arg1.Interface() == arg.Interface()
- }
- }
- }
- if truth {
- return true, nil
- }
- }
- return false, nil
-}
-
-// ne evaluates the comparison a != b.
-func ne(arg1, arg2 reflect.Value) (bool, error) {
- // != is the inverse of ==.
- equal, err := eq(arg1, arg2)
- return !equal, err
-}
-
-// lt evaluates the comparison a < b.
-func lt(arg1, arg2 reflect.Value) (bool, error) {
- arg1 = indirectInterface(arg1)
- k1, err := basicKind(arg1)
- if err != nil {
- return false, err
- }
- arg2 = indirectInterface(arg2)
- k2, err := basicKind(arg2)
- if err != nil {
- return false, err
- }
- truth := false
- if k1 != k2 {
- // Special case: Can compare integer values regardless of type's sign.
- switch {
- case k1 == intKind && k2 == uintKind:
- truth = arg1.Int() < 0 || uint64(arg1.Int()) < arg2.Uint()
- case k1 == uintKind && k2 == intKind:
- truth = arg2.Int() >= 0 && arg1.Uint() < uint64(arg2.Int())
- default:
- return false, errBadComparison
- }
- } else {
- switch k1 {
- case boolKind, complexKind:
- return false, errBadComparisonType
- case floatKind:
- truth = arg1.Float() < arg2.Float()
- case intKind:
- truth = arg1.Int() < arg2.Int()
- case stringKind:
- truth = arg1.String() < arg2.String()
- case uintKind:
- truth = arg1.Uint() < arg2.Uint()
- default:
- panic("invalid kind")
- }
- }
- return truth, nil
-}
-
-// le evaluates the comparison <= b.
-func le(arg1, arg2 reflect.Value) (bool, error) {
- // <= is < or ==.
- lessThan, err := lt(arg1, arg2)
- if lessThan || err != nil {
- return lessThan, err
- }
- return eq(arg1, arg2)
-}
-
-// gt evaluates the comparison a > b.
-func gt(arg1, arg2 reflect.Value) (bool, error) {
- // > is the inverse of <=.
- lessOrEqual, err := le(arg1, arg2)
- if err != nil {
- return false, err
- }
- return !lessOrEqual, nil
-}
-
-// ge evaluates the comparison a >= b.
-func ge(arg1, arg2 reflect.Value) (bool, error) {
- // >= is the inverse of <.
- lessThan, err := lt(arg1, arg2)
- if err != nil {
- return false, err
- }
- return !lessThan, nil
-}
-
-// HTML escaping.
-
-var (
- htmlQuot = []byte("&#34;") // shorter than "&quot;"
- htmlApos = []byte("&#39;") // shorter than "&apos;" and apos was not in HTML until HTML5
- htmlAmp = []byte("&amp;")
- htmlLt = []byte("&lt;")
- htmlGt = []byte("&gt;")
- htmlNull = []byte("\uFFFD")
-)
-
-// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
-func HTMLEscape(w io.Writer, b []byte) {
- last := 0
- for i, c := range b {
- var html []byte
- switch c {
- case '\000':
- html = htmlNull
- case '"':
- html = htmlQuot
- case '\'':
- html = htmlApos
- case '&':
- html = htmlAmp
- case '<':
- html = htmlLt
- case '>':
- html = htmlGt
- default:
- continue
- }
- w.Write(b[last:i])
- w.Write(html)
- last = i + 1
- }
- w.Write(b[last:])
-}
-
-// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
-func HTMLEscapeString(s string) string {
- // Avoid allocation if we can.
- if !strings.ContainsAny(s, "'\"&<>\000") {
- return s
- }
- var b strings.Builder
- HTMLEscape(&b, []byte(s))
- return b.String()
-}
-
-// HTMLEscaper returns the escaped HTML equivalent of the textual
-// representation of its arguments.
-func HTMLEscaper(args ...any) string {
- return HTMLEscapeString(evalArgs(args))
-}
-
-// JavaScript escaping.
-
-var (
- jsLowUni = []byte(`\u00`)
- hex = []byte("0123456789ABCDEF")
-
- jsBackslash = []byte(`\\`)
- jsApos = []byte(`\'`)
- jsQuot = []byte(`\"`)
- jsLt = []byte(`\u003C`)
- jsGt = []byte(`\u003E`)
- jsAmp = []byte(`\u0026`)
- jsEq = []byte(`\u003D`)
-)
-
-// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
-func JSEscape(w io.Writer, b []byte) {
- last := 0
- for i := 0; i < len(b); i++ {
- c := b[i]
-
- if !jsIsSpecial(rune(c)) {
- // fast path: nothing to do
- continue
- }
- w.Write(b[last:i])
-
- if c < utf8.RuneSelf {
- // Quotes, slashes and angle brackets get quoted.
- // Control characters get written as \u00XX.
- switch c {
- case '\\':
- w.Write(jsBackslash)
- case '\'':
- w.Write(jsApos)
- case '"':
- w.Write(jsQuot)
- case '<':
- w.Write(jsLt)
- case '>':
- w.Write(jsGt)
- case '&':
- w.Write(jsAmp)
- case '=':
- w.Write(jsEq)
- default:
- w.Write(jsLowUni)
- t, b := c>>4, c&0x0f
- w.Write(hex[t : t+1])
- w.Write(hex[b : b+1])
- }
- } else {
- // Unicode rune.
- r, size := utf8.DecodeRune(b[i:])
- if unicode.IsPrint(r) {
- w.Write(b[i : i+size])
- } else {
- fmt.Fprintf(w, "\\u%04X", r)
- }
- i += size - 1
- }
- last = i + 1
- }
- w.Write(b[last:])
-}
-
-// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
-func JSEscapeString(s string) string {
- // Avoid allocation if we can.
- if strings.IndexFunc(s, jsIsSpecial) < 0 {
- return s
- }
- var b strings.Builder
- JSEscape(&b, []byte(s))
- return b.String()
-}
-
-func jsIsSpecial(r rune) bool {
- switch r {
- case '\\', '\'', '"', '<', '>', '&', '=':
- return true
- }
- return r < ' ' || utf8.RuneSelf <= r
-}
-
-// JSEscaper returns the escaped JavaScript equivalent of the textual
-// representation of its arguments.
-func JSEscaper(args ...any) string {
- return JSEscapeString(evalArgs(args))
-}
-
-// URLQueryEscaper returns the escaped value of the textual representation of
-// its arguments in a form suitable for embedding in a URL query.
-func URLQueryEscaper(args ...any) string {
- return url.QueryEscape(evalArgs(args))
-}
-
-// evalArgs formats the list of arguments into a string. It is therefore equivalent to
-//
-// fmt.Sprint(args...)
-//
-// except that each argument is indirected (if a pointer), as required,
-// using the same rules as the default string evaluation during template
-// execution.
-func evalArgs(args []any) string {
- ok := false
- var s string
- // Fast path for simple common case.
- if len(args) == 1 {
- s, ok = args[0].(string)
- }
- if !ok {
- for i, arg := range args {
- a, ok := printableValue(reflect.ValueOf(arg))
- if ok {
- args[i] = a
- } // else let fmt do its thing
- }
- s = fmt.Sprint(args...)
- }
- return s
-}
diff --git a/contrib/go/_std_1.20/src/text/template/parse/ya.make b/contrib/go/_std_1.20/src/text/template/parse/ya.make
deleted file mode 100644
index 4b41d53980..0000000000
--- a/contrib/go/_std_1.20/src/text/template/parse/ya.make
+++ /dev/null
@@ -1,9 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- lex.go
- node.go
- parse.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/text/template/ya.make b/contrib/go/_std_1.20/src/text/template/ya.make
deleted file mode 100644
index 62de27ce94..0000000000
--- a/contrib/go/_std_1.20/src/text/template/ya.make
+++ /dev/null
@@ -1,16 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- doc.go
- exec.go
- funcs.go
- helper.go
- option.go
- template.go
-)
-
-END()
-
-RECURSE(
- parse
-)
diff --git a/contrib/go/_std_1.20/src/time/format.go b/contrib/go/_std_1.20/src/time/format.go
deleted file mode 100644
index f94d68ee02..0000000000
--- a/contrib/go/_std_1.20/src/time/format.go
+++ /dev/null
@@ -1,1686 +0,0 @@
-// Copyright 2010 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 time
-
-import "errors"
-
-// These are predefined layouts for use in Time.Format and time.Parse.
-// The reference time used in these layouts is the specific time stamp:
-//
-// 01/02 03:04:05PM '06 -0700
-//
-// (January 2, 15:04:05, 2006, in time zone seven hours west of GMT).
-// That value is recorded as the constant named Layout, listed below. As a Unix
-// time, this is 1136239445. Since MST is GMT-0700, the reference would be
-// printed by the Unix date command as:
-//
-// Mon Jan 2 15:04:05 MST 2006
-//
-// It is a regrettable historic error that the date uses the American convention
-// of putting the numerical month before the day.
-//
-// The example for Time.Format demonstrates the working of the layout string
-// in detail and is a good reference.
-//
-// Note that the RFC822, RFC850, and RFC1123 formats should be applied
-// only to local times. Applying them to UTC times will use "UTC" as the
-// time zone abbreviation, while strictly speaking those RFCs require the
-// use of "GMT" in that case.
-// In general RFC1123Z should be used instead of RFC1123 for servers
-// that insist on that format, and RFC3339 should be preferred for new protocols.
-// RFC3339, RFC822, RFC822Z, RFC1123, and RFC1123Z are useful for formatting;
-// when used with time.Parse they do not accept all the time formats
-// permitted by the RFCs and they do accept time formats not formally defined.
-// The RFC3339Nano format removes trailing zeros from the seconds field
-// and thus may not sort correctly once formatted.
-//
-// Most programs can use one of the defined constants as the layout passed to
-// Format or Parse. The rest of this comment can be ignored unless you are
-// creating a custom layout string.
-//
-// To define your own format, write down what the reference time would look like
-// formatted your way; see the values of constants like ANSIC, StampMicro or
-// Kitchen for examples. The model is to demonstrate what the reference time
-// looks like so that the Format and Parse methods can apply the same
-// transformation to a general time value.
-//
-// Here is a summary of the components of a layout string. Each element shows by
-// example the formatting of an element of the reference time. Only these values
-// are recognized. Text in the layout string that is not recognized as part of
-// the reference time is echoed verbatim during Format and expected to appear
-// verbatim in the input to Parse.
-//
-// Year: "2006" "06"
-// Month: "Jan" "January" "01" "1"
-// Day of the week: "Mon" "Monday"
-// Day of the month: "2" "_2" "02"
-// Day of the year: "__2" "002"
-// Hour: "15" "3" "03" (PM or AM)
-// Minute: "4" "04"
-// Second: "5" "05"
-// AM/PM mark: "PM"
-//
-// Numeric time zone offsets format as follows:
-//
-// "-0700" ±hhmm
-// "-07:00" ±hh:mm
-// "-07" ±hh
-// "-070000" ±hhmmss
-// "-07:00:00" ±hh:mm:ss
-//
-// Replacing the sign in the format with a Z triggers
-// the ISO 8601 behavior of printing Z instead of an
-// offset for the UTC zone. Thus:
-//
-// "Z0700" Z or ±hhmm
-// "Z07:00" Z or ±hh:mm
-// "Z07" Z or ±hh
-// "Z070000" Z or ±hhmmss
-// "Z07:00:00" Z or ±hh:mm:ss
-//
-// Within the format string, the underscores in "_2" and "__2" represent spaces
-// that may be replaced by digits if the following number has multiple digits,
-// for compatibility with fixed-width Unix time formats. A leading zero represents
-// a zero-padded value.
-//
-// The formats __2 and 002 are space-padded and zero-padded
-// three-character day of year; there is no unpadded day of year format.
-//
-// A comma or decimal point followed by one or more zeros represents
-// a fractional second, printed to the given number of decimal places.
-// A comma or decimal point followed by one or more nines represents
-// a fractional second, printed to the given number of decimal places, with
-// trailing zeros removed.
-// For example "15:04:05,000" or "15:04:05.000" formats or parses with
-// millisecond precision.
-//
-// Some valid layouts are invalid time values for time.Parse, due to formats
-// such as _ for space padding and Z for zone information.
-const (
- Layout = "01/02 03:04:05PM '06 -0700" // The reference time, in numerical order.
- ANSIC = "Mon Jan _2 15:04:05 2006"
- UnixDate = "Mon Jan _2 15:04:05 MST 2006"
- RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
- RFC822 = "02 Jan 06 15:04 MST"
- RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
- RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
- RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
- RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
- RFC3339 = "2006-01-02T15:04:05Z07:00"
- RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
- Kitchen = "3:04PM"
- // Handy time stamps.
- Stamp = "Jan _2 15:04:05"
- StampMilli = "Jan _2 15:04:05.000"
- StampMicro = "Jan _2 15:04:05.000000"
- StampNano = "Jan _2 15:04:05.000000000"
- DateTime = "2006-01-02 15:04:05"
- DateOnly = "2006-01-02"
- TimeOnly = "15:04:05"
-)
-
-const (
- _ = iota
- stdLongMonth = iota + stdNeedDate // "January"
- stdMonth // "Jan"
- stdNumMonth // "1"
- stdZeroMonth // "01"
- stdLongWeekDay // "Monday"
- stdWeekDay // "Mon"
- stdDay // "2"
- stdUnderDay // "_2"
- stdZeroDay // "02"
- stdUnderYearDay // "__2"
- stdZeroYearDay // "002"
- stdHour = iota + stdNeedClock // "15"
- stdHour12 // "3"
- stdZeroHour12 // "03"
- stdMinute // "4"
- stdZeroMinute // "04"
- stdSecond // "5"
- stdZeroSecond // "05"
- stdLongYear = iota + stdNeedDate // "2006"
- stdYear // "06"
- stdPM = iota + stdNeedClock // "PM"
- stdpm // "pm"
- stdTZ = iota // "MST"
- stdISO8601TZ // "Z0700" // prints Z for UTC
- stdISO8601SecondsTZ // "Z070000"
- stdISO8601ShortTZ // "Z07"
- stdISO8601ColonTZ // "Z07:00" // prints Z for UTC
- stdISO8601ColonSecondsTZ // "Z07:00:00"
- stdNumTZ // "-0700" // always numeric
- stdNumSecondsTz // "-070000"
- stdNumShortTZ // "-07" // always numeric
- stdNumColonTZ // "-07:00" // always numeric
- stdNumColonSecondsTZ // "-07:00:00"
- stdFracSecond0 // ".0", ".00", ... , trailing zeros included
- stdFracSecond9 // ".9", ".99", ..., trailing zeros omitted
-
- stdNeedDate = 1 << 8 // need month, day, year
- stdNeedClock = 2 << 8 // need hour, minute, second
- stdArgShift = 16 // extra argument in high bits, above low stdArgShift
- stdSeparatorShift = 28 // extra argument in high 4 bits for fractional second separators
- stdMask = 1<<stdArgShift - 1 // mask out argument
-)
-
-// std0x records the std values for "01", "02", ..., "06".
-var std0x = [...]int{stdZeroMonth, stdZeroDay, stdZeroHour12, stdZeroMinute, stdZeroSecond, stdYear}
-
-// startsWithLowerCase reports whether the string has a lower-case letter at the beginning.
-// Its purpose is to prevent matching strings like "Month" when looking for "Mon".
-func startsWithLowerCase(str string) bool {
- if len(str) == 0 {
- return false
- }
- c := str[0]
- return 'a' <= c && c <= 'z'
-}
-
-// nextStdChunk finds the first occurrence of a std string in
-// layout and returns the text before, the std string, and the text after.
-func nextStdChunk(layout string) (prefix string, std int, suffix string) {
- for i := 0; i < len(layout); i++ {
- switch c := int(layout[i]); c {
- case 'J': // January, Jan
- if len(layout) >= i+3 && layout[i:i+3] == "Jan" {
- if len(layout) >= i+7 && layout[i:i+7] == "January" {
- return layout[0:i], stdLongMonth, layout[i+7:]
- }
- if !startsWithLowerCase(layout[i+3:]) {
- return layout[0:i], stdMonth, layout[i+3:]
- }
- }
-
- case 'M': // Monday, Mon, MST
- if len(layout) >= i+3 {
- if layout[i:i+3] == "Mon" {
- if len(layout) >= i+6 && layout[i:i+6] == "Monday" {
- return layout[0:i], stdLongWeekDay, layout[i+6:]
- }
- if !startsWithLowerCase(layout[i+3:]) {
- return layout[0:i], stdWeekDay, layout[i+3:]
- }
- }
- if layout[i:i+3] == "MST" {
- return layout[0:i], stdTZ, layout[i+3:]
- }
- }
-
- case '0': // 01, 02, 03, 04, 05, 06, 002
- if len(layout) >= i+2 && '1' <= layout[i+1] && layout[i+1] <= '6' {
- return layout[0:i], std0x[layout[i+1]-'1'], layout[i+2:]
- }
- if len(layout) >= i+3 && layout[i+1] == '0' && layout[i+2] == '2' {
- return layout[0:i], stdZeroYearDay, layout[i+3:]
- }
-
- case '1': // 15, 1
- if len(layout) >= i+2 && layout[i+1] == '5' {
- return layout[0:i], stdHour, layout[i+2:]
- }
- return layout[0:i], stdNumMonth, layout[i+1:]
-
- case '2': // 2006, 2
- if len(layout) >= i+4 && layout[i:i+4] == "2006" {
- return layout[0:i], stdLongYear, layout[i+4:]
- }
- return layout[0:i], stdDay, layout[i+1:]
-
- case '_': // _2, _2006, __2
- if len(layout) >= i+2 && layout[i+1] == '2' {
- //_2006 is really a literal _, followed by stdLongYear
- if len(layout) >= i+5 && layout[i+1:i+5] == "2006" {
- return layout[0 : i+1], stdLongYear, layout[i+5:]
- }
- return layout[0:i], stdUnderDay, layout[i+2:]
- }
- if len(layout) >= i+3 && layout[i+1] == '_' && layout[i+2] == '2' {
- return layout[0:i], stdUnderYearDay, layout[i+3:]
- }
-
- case '3':
- return layout[0:i], stdHour12, layout[i+1:]
-
- case '4':
- return layout[0:i], stdMinute, layout[i+1:]
-
- case '5':
- return layout[0:i], stdSecond, layout[i+1:]
-
- case 'P': // PM
- if len(layout) >= i+2 && layout[i+1] == 'M' {
- return layout[0:i], stdPM, layout[i+2:]
- }
-
- case 'p': // pm
- if len(layout) >= i+2 && layout[i+1] == 'm' {
- return layout[0:i], stdpm, layout[i+2:]
- }
-
- case '-': // -070000, -07:00:00, -0700, -07:00, -07
- if len(layout) >= i+7 && layout[i:i+7] == "-070000" {
- return layout[0:i], stdNumSecondsTz, layout[i+7:]
- }
- if len(layout) >= i+9 && layout[i:i+9] == "-07:00:00" {
- return layout[0:i], stdNumColonSecondsTZ, layout[i+9:]
- }
- if len(layout) >= i+5 && layout[i:i+5] == "-0700" {
- return layout[0:i], stdNumTZ, layout[i+5:]
- }
- if len(layout) >= i+6 && layout[i:i+6] == "-07:00" {
- return layout[0:i], stdNumColonTZ, layout[i+6:]
- }
- if len(layout) >= i+3 && layout[i:i+3] == "-07" {
- return layout[0:i], stdNumShortTZ, layout[i+3:]
- }
-
- case 'Z': // Z070000, Z07:00:00, Z0700, Z07:00,
- if len(layout) >= i+7 && layout[i:i+7] == "Z070000" {
- return layout[0:i], stdISO8601SecondsTZ, layout[i+7:]
- }
- if len(layout) >= i+9 && layout[i:i+9] == "Z07:00:00" {
- return layout[0:i], stdISO8601ColonSecondsTZ, layout[i+9:]
- }
- if len(layout) >= i+5 && layout[i:i+5] == "Z0700" {
- return layout[0:i], stdISO8601TZ, layout[i+5:]
- }
- if len(layout) >= i+6 && layout[i:i+6] == "Z07:00" {
- return layout[0:i], stdISO8601ColonTZ, layout[i+6:]
- }
- if len(layout) >= i+3 && layout[i:i+3] == "Z07" {
- return layout[0:i], stdISO8601ShortTZ, layout[i+3:]
- }
-
- case '.', ',': // ,000, or .000, or ,999, or .999 - repeated digits for fractional seconds.
- if i+1 < len(layout) && (layout[i+1] == '0' || layout[i+1] == '9') {
- ch := layout[i+1]
- j := i + 1
- for j < len(layout) && layout[j] == ch {
- j++
- }
- // String of digits must end here - only fractional second is all digits.
- if !isDigit(layout, j) {
- code := stdFracSecond0
- if layout[i+1] == '9' {
- code = stdFracSecond9
- }
- std := stdFracSecond(code, j-(i+1), c)
- return layout[0:i], std, layout[j:]
- }
- }
- }
- }
- return layout, 0, ""
-}
-
-var longDayNames = []string{
- "Sunday",
- "Monday",
- "Tuesday",
- "Wednesday",
- "Thursday",
- "Friday",
- "Saturday",
-}
-
-var shortDayNames = []string{
- "Sun",
- "Mon",
- "Tue",
- "Wed",
- "Thu",
- "Fri",
- "Sat",
-}
-
-var shortMonthNames = []string{
- "Jan",
- "Feb",
- "Mar",
- "Apr",
- "May",
- "Jun",
- "Jul",
- "Aug",
- "Sep",
- "Oct",
- "Nov",
- "Dec",
-}
-
-var longMonthNames = []string{
- "January",
- "February",
- "March",
- "April",
- "May",
- "June",
- "July",
- "August",
- "September",
- "October",
- "November",
- "December",
-}
-
-// match reports whether s1 and s2 match ignoring case.
-// It is assumed s1 and s2 are the same length.
-func match(s1, s2 string) bool {
- for i := 0; i < len(s1); i++ {
- c1 := s1[i]
- c2 := s2[i]
- if c1 != c2 {
- // Switch to lower-case; 'a'-'A' is known to be a single bit.
- c1 |= 'a' - 'A'
- c2 |= 'a' - 'A'
- if c1 != c2 || c1 < 'a' || c1 > 'z' {
- return false
- }
- }
- }
- return true
-}
-
-func lookup(tab []string, val string) (int, string, error) {
- for i, v := range tab {
- if len(val) >= len(v) && match(val[0:len(v)], v) {
- return i, val[len(v):], nil
- }
- }
- return -1, val, errBad
-}
-
-// appendInt appends the decimal form of x to b and returns the result.
-// If the decimal form (excluding sign) is shorter than width, the result is padded with leading 0's.
-// Duplicates functionality in strconv, but avoids dependency.
-func appendInt(b []byte, x int, width int) []byte {
- u := uint(x)
- if x < 0 {
- b = append(b, '-')
- u = uint(-x)
- }
-
- // 2-digit and 4-digit fields are the most common in time formats.
- utod := func(u uint) byte { return '0' + byte(u) }
- switch {
- case width == 2 && u < 1e2:
- return append(b, utod(u/1e1), utod(u%1e1))
- case width == 4 && u < 1e4:
- return append(b, utod(u/1e3), utod(u/1e2%1e1), utod(u/1e1%1e1), utod(u%1e1))
- }
-
- // Compute the number of decimal digits.
- var n int
- if u == 0 {
- n = 1
- }
- for u2 := u; u2 > 0; u2 /= 10 {
- n++
- }
-
- // Add 0-padding.
- for pad := width - n; pad > 0; pad-- {
- b = append(b, '0')
- }
-
- // Ensure capacity.
- if len(b)+n <= cap(b) {
- b = b[:len(b)+n]
- } else {
- b = append(b, make([]byte, n)...)
- }
-
- // Assemble decimal in reverse order.
- i := len(b) - 1
- for u >= 10 && i > 0 {
- q := u / 10
- b[i] = utod(u - q*10)
- u = q
- i--
- }
- b[i] = utod(u)
- return b
-}
-
-// Never printed, just needs to be non-nil for return by atoi.
-var atoiError = errors.New("time: invalid number")
-
-// Duplicates functionality in strconv, but avoids dependency.
-func atoi[bytes []byte | string](s bytes) (x int, err error) {
- neg := false
- if len(s) > 0 && (s[0] == '-' || s[0] == '+') {
- neg = s[0] == '-'
- s = s[1:]
- }
- q, rem, err := leadingInt(s)
- x = int(q)
- if err != nil || len(rem) > 0 {
- return 0, atoiError
- }
- if neg {
- x = -x
- }
- return x, nil
-}
-
-// The "std" value passed to appendNano contains two packed fields: the number of
-// digits after the decimal and the separator character (period or comma).
-// These functions pack and unpack that variable.
-func stdFracSecond(code, n, c int) int {
- // Use 0xfff to make the failure case even more absurd.
- if c == '.' {
- return code | ((n & 0xfff) << stdArgShift)
- }
- return code | ((n & 0xfff) << stdArgShift) | 1<<stdSeparatorShift
-}
-
-func digitsLen(std int) int {
- return (std >> stdArgShift) & 0xfff
-}
-
-func separator(std int) byte {
- if (std >> stdSeparatorShift) == 0 {
- return '.'
- }
- return ','
-}
-
-// appendNano appends a fractional second, as nanoseconds, to b
-// and returns the result. The nanosec must be within [0, 999999999].
-func appendNano(b []byte, nanosec int, std int) []byte {
- trim := std&stdMask == stdFracSecond9
- n := digitsLen(std)
- if trim && (n == 0 || nanosec == 0) {
- return b
- }
- dot := separator(std)
- b = append(b, dot)
- b = appendInt(b, nanosec, 9)
- if n < 9 {
- b = b[:len(b)-9+n]
- }
- if trim {
- for len(b) > 0 && b[len(b)-1] == '0' {
- b = b[:len(b)-1]
- }
- if len(b) > 0 && b[len(b)-1] == dot {
- b = b[:len(b)-1]
- }
- }
- return b
-}
-
-// String returns the time formatted using the format string
-//
-// "2006-01-02 15:04:05.999999999 -0700 MST"
-//
-// If the time has a monotonic clock reading, the returned string
-// includes a final field "m=±<value>", where value is the monotonic
-// clock reading formatted as a decimal number of seconds.
-//
-// The returned string is meant for debugging; for a stable serialized
-// representation, use t.MarshalText, t.MarshalBinary, or t.Format
-// with an explicit format string.
-func (t Time) String() string {
- s := t.Format("2006-01-02 15:04:05.999999999 -0700 MST")
-
- // Format monotonic clock reading as m=±ddd.nnnnnnnnn.
- if t.wall&hasMonotonic != 0 {
- m2 := uint64(t.ext)
- sign := byte('+')
- if t.ext < 0 {
- sign = '-'
- m2 = -m2
- }
- m1, m2 := m2/1e9, m2%1e9
- m0, m1 := m1/1e9, m1%1e9
- buf := make([]byte, 0, 24)
- buf = append(buf, " m="...)
- buf = append(buf, sign)
- wid := 0
- if m0 != 0 {
- buf = appendInt(buf, int(m0), 0)
- wid = 9
- }
- buf = appendInt(buf, int(m1), wid)
- buf = append(buf, '.')
- buf = appendInt(buf, int(m2), 9)
- s += string(buf)
- }
- return s
-}
-
-// GoString implements fmt.GoStringer and formats t to be printed in Go source
-// code.
-func (t Time) GoString() string {
- abs := t.abs()
- year, month, day, _ := absDate(abs, true)
- hour, minute, second := absClock(abs)
-
- buf := make([]byte, 0, len("time.Date(9999, time.September, 31, 23, 59, 59, 999999999, time.Local)"))
- buf = append(buf, "time.Date("...)
- buf = appendInt(buf, year, 0)
- if January <= month && month <= December {
- buf = append(buf, ", time."...)
- buf = append(buf, longMonthNames[month-1]...)
- } else {
- // It's difficult to construct a time.Time with a date outside the
- // standard range but we might as well try to handle the case.
- buf = appendInt(buf, int(month), 0)
- }
- buf = append(buf, ", "...)
- buf = appendInt(buf, day, 0)
- buf = append(buf, ", "...)
- buf = appendInt(buf, hour, 0)
- buf = append(buf, ", "...)
- buf = appendInt(buf, minute, 0)
- buf = append(buf, ", "...)
- buf = appendInt(buf, second, 0)
- buf = append(buf, ", "...)
- buf = appendInt(buf, t.Nanosecond(), 0)
- buf = append(buf, ", "...)
- switch loc := t.Location(); loc {
- case UTC, nil:
- buf = append(buf, "time.UTC"...)
- case Local:
- buf = append(buf, "time.Local"...)
- default:
- // there are several options for how we could display this, none of
- // which are great:
- //
- // - use Location(loc.name), which is not technically valid syntax
- // - use LoadLocation(loc.name), which will cause a syntax error when
- // embedded and also would require us to escape the string without
- // importing fmt or strconv
- // - try to use FixedZone, which would also require escaping the name
- // and would represent e.g. "America/Los_Angeles" daylight saving time
- // shifts inaccurately
- // - use the pointer format, which is no worse than you'd get with the
- // old fmt.Sprintf("%#v", t) format.
- //
- // Of these, Location(loc.name) is the least disruptive. This is an edge
- // case we hope not to hit too often.
- buf = append(buf, `time.Location(`...)
- buf = append(buf, quote(loc.name)...)
- buf = append(buf, ')')
- }
- buf = append(buf, ')')
- return string(buf)
-}
-
-// Format returns a textual representation of the time value formatted according
-// to the layout defined by the argument. See the documentation for the
-// constant called Layout to see how to represent the layout format.
-//
-// The executable example for Time.Format demonstrates the working
-// of the layout string in detail and is a good reference.
-func (t Time) Format(layout string) string {
- const bufSize = 64
- var b []byte
- max := len(layout) + 10
- if max < bufSize {
- var buf [bufSize]byte
- b = buf[:0]
- } else {
- b = make([]byte, 0, max)
- }
- b = t.AppendFormat(b, layout)
- return string(b)
-}
-
-// AppendFormat is like Format but appends the textual
-// representation to b and returns the extended buffer.
-func (t Time) AppendFormat(b []byte, layout string) []byte {
- // Optimize for RFC3339 as it accounts for over half of all representations.
- switch layout {
- case RFC3339:
- return t.appendFormatRFC3339(b, false)
- case RFC3339Nano:
- return t.appendFormatRFC3339(b, true)
- default:
- return t.appendFormat(b, layout)
- }
-}
-
-func (t Time) appendFormat(b []byte, layout string) []byte {
- var (
- name, offset, abs = t.locabs()
-
- year int = -1
- month Month
- day int
- yday int
- hour int = -1
- min int
- sec int
- )
-
- // Each iteration generates one std value.
- for layout != "" {
- prefix, std, suffix := nextStdChunk(layout)
- if prefix != "" {
- b = append(b, prefix...)
- }
- if std == 0 {
- break
- }
- layout = suffix
-
- // Compute year, month, day if needed.
- if year < 0 && std&stdNeedDate != 0 {
- year, month, day, yday = absDate(abs, true)
- yday++
- }
-
- // Compute hour, minute, second if needed.
- if hour < 0 && std&stdNeedClock != 0 {
- hour, min, sec = absClock(abs)
- }
-
- switch std & stdMask {
- case stdYear:
- y := year
- if y < 0 {
- y = -y
- }
- b = appendInt(b, y%100, 2)
- case stdLongYear:
- b = appendInt(b, year, 4)
- case stdMonth:
- b = append(b, month.String()[:3]...)
- case stdLongMonth:
- m := month.String()
- b = append(b, m...)
- case stdNumMonth:
- b = appendInt(b, int(month), 0)
- case stdZeroMonth:
- b = appendInt(b, int(month), 2)
- case stdWeekDay:
- b = append(b, absWeekday(abs).String()[:3]...)
- case stdLongWeekDay:
- s := absWeekday(abs).String()
- b = append(b, s...)
- case stdDay:
- b = appendInt(b, day, 0)
- case stdUnderDay:
- if day < 10 {
- b = append(b, ' ')
- }
- b = appendInt(b, day, 0)
- case stdZeroDay:
- b = appendInt(b, day, 2)
- case stdUnderYearDay:
- if yday < 100 {
- b = append(b, ' ')
- if yday < 10 {
- b = append(b, ' ')
- }
- }
- b = appendInt(b, yday, 0)
- case stdZeroYearDay:
- b = appendInt(b, yday, 3)
- case stdHour:
- b = appendInt(b, hour, 2)
- case stdHour12:
- // Noon is 12PM, midnight is 12AM.
- hr := hour % 12
- if hr == 0 {
- hr = 12
- }
- b = appendInt(b, hr, 0)
- case stdZeroHour12:
- // Noon is 12PM, midnight is 12AM.
- hr := hour % 12
- if hr == 0 {
- hr = 12
- }
- b = appendInt(b, hr, 2)
- case stdMinute:
- b = appendInt(b, min, 0)
- case stdZeroMinute:
- b = appendInt(b, min, 2)
- case stdSecond:
- b = appendInt(b, sec, 0)
- case stdZeroSecond:
- b = appendInt(b, sec, 2)
- case stdPM:
- if hour >= 12 {
- b = append(b, "PM"...)
- } else {
- b = append(b, "AM"...)
- }
- case stdpm:
- if hour >= 12 {
- b = append(b, "pm"...)
- } else {
- b = append(b, "am"...)
- }
- case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ShortTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumColonTZ, stdNumSecondsTz, stdNumShortTZ, stdNumColonSecondsTZ:
- // Ugly special case. We cheat and take the "Z" variants
- // to mean "the time zone as formatted for ISO 8601".
- if offset == 0 && (std == stdISO8601TZ || std == stdISO8601ColonTZ || std == stdISO8601SecondsTZ || std == stdISO8601ShortTZ || std == stdISO8601ColonSecondsTZ) {
- b = append(b, 'Z')
- break
- }
- zone := offset / 60 // convert to minutes
- absoffset := offset
- if zone < 0 {
- b = append(b, '-')
- zone = -zone
- absoffset = -absoffset
- } else {
- b = append(b, '+')
- }
- b = appendInt(b, zone/60, 2)
- if std == stdISO8601ColonTZ || std == stdNumColonTZ || std == stdISO8601ColonSecondsTZ || std == stdNumColonSecondsTZ {
- b = append(b, ':')
- }
- if std != stdNumShortTZ && std != stdISO8601ShortTZ {
- b = appendInt(b, zone%60, 2)
- }
-
- // append seconds if appropriate
- if std == stdISO8601SecondsTZ || std == stdNumSecondsTz || std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
- if std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
- b = append(b, ':')
- }
- b = appendInt(b, absoffset%60, 2)
- }
-
- case stdTZ:
- if name != "" {
- b = append(b, name...)
- break
- }
- // No time zone known for this time, but we must print one.
- // Use the -0700 format.
- zone := offset / 60 // convert to minutes
- if zone < 0 {
- b = append(b, '-')
- zone = -zone
- } else {
- b = append(b, '+')
- }
- b = appendInt(b, zone/60, 2)
- b = appendInt(b, zone%60, 2)
- case stdFracSecond0, stdFracSecond9:
- b = appendNano(b, t.Nanosecond(), std)
- }
- }
- return b
-}
-
-var errBad = errors.New("bad value for field") // placeholder not passed to user
-
-// ParseError describes a problem parsing a time string.
-type ParseError struct {
- Layout string
- Value string
- LayoutElem string
- ValueElem string
- Message string
-}
-
-// newParseError creates a new ParseError.
-// The provided value and valueElem are cloned to avoid escaping their values.
-func newParseError(layout, value, layoutElem, valueElem, message string) *ParseError {
- valueCopy := cloneString(value)
- valueElemCopy := cloneString(valueElem)
- return &ParseError{layout, valueCopy, layoutElem, valueElemCopy, message}
-}
-
-// cloneString returns a string copy of s.
-// Do not use strings.Clone to avoid dependency on strings package.
-func cloneString(s string) string {
- return string([]byte(s))
-}
-
-// These are borrowed from unicode/utf8 and strconv and replicate behavior in
-// that package, since we can't take a dependency on either.
-const (
- lowerhex = "0123456789abcdef"
- runeSelf = 0x80
- runeError = '\uFFFD'
-)
-
-func quote(s string) string {
- buf := make([]byte, 1, len(s)+2) // slice will be at least len(s) + quotes
- buf[0] = '"'
- for i, c := range s {
- if c >= runeSelf || c < ' ' {
- // This means you are asking us to parse a time.Duration or
- // time.Location with unprintable or non-ASCII characters in it.
- // We don't expect to hit this case very often. We could try to
- // reproduce strconv.Quote's behavior with full fidelity but
- // given how rarely we expect to hit these edge cases, speed and
- // conciseness are better.
- var width int
- if c == runeError {
- width = 1
- if i+2 < len(s) && s[i:i+3] == string(runeError) {
- width = 3
- }
- } else {
- width = len(string(c))
- }
- for j := 0; j < width; j++ {
- buf = append(buf, `\x`...)
- buf = append(buf, lowerhex[s[i+j]>>4])
- buf = append(buf, lowerhex[s[i+j]&0xF])
- }
- } else {
- if c == '"' || c == '\\' {
- buf = append(buf, '\\')
- }
- buf = append(buf, string(c)...)
- }
- }
- buf = append(buf, '"')
- return string(buf)
-}
-
-// Error returns the string representation of a ParseError.
-func (e *ParseError) Error() string {
- if e.Message == "" {
- return "parsing time " +
- quote(e.Value) + " as " +
- quote(e.Layout) + ": cannot parse " +
- quote(e.ValueElem) + " as " +
- quote(e.LayoutElem)
- }
- return "parsing time " +
- quote(e.Value) + e.Message
-}
-
-// isDigit reports whether s[i] is in range and is a decimal digit.
-func isDigit[bytes []byte | string](s bytes, i int) bool {
- if len(s) <= i {
- return false
- }
- c := s[i]
- return '0' <= c && c <= '9'
-}
-
-// getnum parses s[0:1] or s[0:2] (fixed forces s[0:2])
-// as a decimal integer and returns the integer and the
-// remainder of the string.
-func getnum(s string, fixed bool) (int, string, error) {
- if !isDigit(s, 0) {
- return 0, s, errBad
- }
- if !isDigit(s, 1) {
- if fixed {
- return 0, s, errBad
- }
- return int(s[0] - '0'), s[1:], nil
- }
- return int(s[0]-'0')*10 + int(s[1]-'0'), s[2:], nil
-}
-
-// getnum3 parses s[0:1], s[0:2], or s[0:3] (fixed forces s[0:3])
-// as a decimal integer and returns the integer and the remainder
-// of the string.
-func getnum3(s string, fixed bool) (int, string, error) {
- var n, i int
- for i = 0; i < 3 && isDigit(s, i); i++ {
- n = n*10 + int(s[i]-'0')
- }
- if i == 0 || fixed && i != 3 {
- return 0, s, errBad
- }
- return n, s[i:], nil
-}
-
-func cutspace(s string) string {
- for len(s) > 0 && s[0] == ' ' {
- s = s[1:]
- }
- return s
-}
-
-// skip removes the given prefix from value,
-// treating runs of space characters as equivalent.
-func skip(value, prefix string) (string, error) {
- for len(prefix) > 0 {
- if prefix[0] == ' ' {
- if len(value) > 0 && value[0] != ' ' {
- return value, errBad
- }
- prefix = cutspace(prefix)
- value = cutspace(value)
- continue
- }
- if len(value) == 0 || value[0] != prefix[0] {
- return value, errBad
- }
- prefix = prefix[1:]
- value = value[1:]
- }
- return value, nil
-}
-
-// Parse parses a formatted string and returns the time value it represents.
-// See the documentation for the constant called Layout to see how to
-// represent the format. The second argument must be parseable using
-// the format string (layout) provided as the first argument.
-//
-// The example for Time.Format demonstrates the working of the layout string
-// in detail and is a good reference.
-//
-// When parsing (only), the input may contain a fractional second
-// field immediately after the seconds field, even if the layout does not
-// signify its presence. In that case either a comma or a decimal point
-// followed by a maximal series of digits is parsed as a fractional second.
-// Fractional seconds are truncated to nanosecond precision.
-//
-// Elements omitted from the layout are assumed to be zero or, when
-// zero is impossible, one, so parsing "3:04pm" returns the time
-// corresponding to Jan 1, year 0, 15:04:00 UTC (note that because the year is
-// 0, this time is before the zero Time).
-// Years must be in the range 0000..9999. The day of the week is checked
-// for syntax but it is otherwise ignored.
-//
-// For layouts specifying the two-digit year 06, a value NN >= 69 will be treated
-// as 19NN and a value NN < 69 will be treated as 20NN.
-//
-// The remainder of this comment describes the handling of time zones.
-//
-// In the absence of a time zone indicator, Parse returns a time in UTC.
-//
-// When parsing a time with a zone offset like -0700, if the offset corresponds
-// to a time zone used by the current location (Local), then Parse uses that
-// location and zone in the returned time. Otherwise it records the time as
-// being in a fabricated location with time fixed at the given zone offset.
-//
-// When parsing a time with a zone abbreviation like MST, if the zone abbreviation
-// has a defined offset in the current location, then that offset is used.
-// The zone abbreviation "UTC" is recognized as UTC regardless of location.
-// If the zone abbreviation is unknown, Parse records the time as being
-// in a fabricated location with the given zone abbreviation and a zero offset.
-// This choice means that such a time can be parsed and reformatted with the
-// same layout losslessly, but the exact instant used in the representation will
-// differ by the actual zone offset. To avoid such problems, prefer time layouts
-// that use a numeric zone offset, or use ParseInLocation.
-func Parse(layout, value string) (Time, error) {
- // Optimize for RFC3339 as it accounts for over half of all representations.
- if layout == RFC3339 || layout == RFC3339Nano {
- if t, ok := parseRFC3339(value, Local); ok {
- return t, nil
- }
- }
- return parse(layout, value, UTC, Local)
-}
-
-// ParseInLocation is like Parse but differs in two important ways.
-// First, in the absence of time zone information, Parse interprets a time as UTC;
-// ParseInLocation interprets the time as in the given location.
-// Second, when given a zone offset or abbreviation, Parse tries to match it
-// against the Local location; ParseInLocation uses the given location.
-func ParseInLocation(layout, value string, loc *Location) (Time, error) {
- // Optimize for RFC3339 as it accounts for over half of all representations.
- if layout == RFC3339 || layout == RFC3339Nano {
- if t, ok := parseRFC3339(value, loc); ok {
- return t, nil
- }
- }
- return parse(layout, value, loc, loc)
-}
-
-func parse(layout, value string, defaultLocation, local *Location) (Time, error) {
- alayout, avalue := layout, value
- rangeErrString := "" // set if a value is out of range
- amSet := false // do we need to subtract 12 from the hour for midnight?
- pmSet := false // do we need to add 12 to the hour?
-
- // Time being constructed.
- var (
- year int
- month int = -1
- day int = -1
- yday int = -1
- hour int
- min int
- sec int
- nsec int
- z *Location
- zoneOffset int = -1
- zoneName string
- )
-
- // Each iteration processes one std value.
- for {
- var err error
- prefix, std, suffix := nextStdChunk(layout)
- stdstr := layout[len(prefix) : len(layout)-len(suffix)]
- value, err = skip(value, prefix)
- if err != nil {
- return Time{}, newParseError(alayout, avalue, prefix, value, "")
- }
- if std == 0 {
- if len(value) != 0 {
- return Time{}, newParseError(alayout, avalue, "", value, ": extra text: "+quote(value))
- }
- break
- }
- layout = suffix
- var p string
- hold := value
- switch std & stdMask {
- case stdYear:
- if len(value) < 2 {
- err = errBad
- break
- }
- p, value = value[0:2], value[2:]
- year, err = atoi(p)
- if err != nil {
- break
- }
- if year >= 69 { // Unix time starts Dec 31 1969 in some time zones
- year += 1900
- } else {
- year += 2000
- }
- case stdLongYear:
- if len(value) < 4 || !isDigit(value, 0) {
- err = errBad
- break
- }
- p, value = value[0:4], value[4:]
- year, err = atoi(p)
- case stdMonth:
- month, value, err = lookup(shortMonthNames, value)
- month++
- case stdLongMonth:
- month, value, err = lookup(longMonthNames, value)
- month++
- case stdNumMonth, stdZeroMonth:
- month, value, err = getnum(value, std == stdZeroMonth)
- if err == nil && (month <= 0 || 12 < month) {
- rangeErrString = "month"
- }
- case stdWeekDay:
- // Ignore weekday except for error checking.
- _, value, err = lookup(shortDayNames, value)
- case stdLongWeekDay:
- _, value, err = lookup(longDayNames, value)
- case stdDay, stdUnderDay, stdZeroDay:
- if std == stdUnderDay && len(value) > 0 && value[0] == ' ' {
- value = value[1:]
- }
- day, value, err = getnum(value, std == stdZeroDay)
- // Note that we allow any one- or two-digit day here.
- // The month, day, year combination is validated after we've completed parsing.
- case stdUnderYearDay, stdZeroYearDay:
- for i := 0; i < 2; i++ {
- if std == stdUnderYearDay && len(value) > 0 && value[0] == ' ' {
- value = value[1:]
- }
- }
- yday, value, err = getnum3(value, std == stdZeroYearDay)
- // Note that we allow any one-, two-, or three-digit year-day here.
- // The year-day, year combination is validated after we've completed parsing.
- case stdHour:
- hour, value, err = getnum(value, false)
- if hour < 0 || 24 <= hour {
- rangeErrString = "hour"
- }
- case stdHour12, stdZeroHour12:
- hour, value, err = getnum(value, std == stdZeroHour12)
- if hour < 0 || 12 < hour {
- rangeErrString = "hour"
- }
- case stdMinute, stdZeroMinute:
- min, value, err = getnum(value, std == stdZeroMinute)
- if min < 0 || 60 <= min {
- rangeErrString = "minute"
- }
- case stdSecond, stdZeroSecond:
- sec, value, err = getnum(value, std == stdZeroSecond)
- if err != nil {
- break
- }
- if sec < 0 || 60 <= sec {
- rangeErrString = "second"
- break
- }
- // Special case: do we have a fractional second but no
- // fractional second in the format?
- if len(value) >= 2 && commaOrPeriod(value[0]) && isDigit(value, 1) {
- _, std, _ = nextStdChunk(layout)
- std &= stdMask
- if std == stdFracSecond0 || std == stdFracSecond9 {
- // Fractional second in the layout; proceed normally
- break
- }
- // No fractional second in the layout but we have one in the input.
- n := 2
- for ; n < len(value) && isDigit(value, n); n++ {
- }
- nsec, rangeErrString, err = parseNanoseconds(value, n)
- value = value[n:]
- }
- case stdPM:
- if len(value) < 2 {
- err = errBad
- break
- }
- p, value = value[0:2], value[2:]
- switch p {
- case "PM":
- pmSet = true
- case "AM":
- amSet = true
- default:
- err = errBad
- }
- case stdpm:
- if len(value) < 2 {
- err = errBad
- break
- }
- p, value = value[0:2], value[2:]
- switch p {
- case "pm":
- pmSet = true
- case "am":
- amSet = true
- default:
- err = errBad
- }
- case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ShortTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumShortTZ, stdNumColonTZ, stdNumSecondsTz, stdNumColonSecondsTZ:
- if (std == stdISO8601TZ || std == stdISO8601ShortTZ || std == stdISO8601ColonTZ) && len(value) >= 1 && value[0] == 'Z' {
- value = value[1:]
- z = UTC
- break
- }
- var sign, hour, min, seconds string
- if std == stdISO8601ColonTZ || std == stdNumColonTZ {
- if len(value) < 6 {
- err = errBad
- break
- }
- if value[3] != ':' {
- err = errBad
- break
- }
- sign, hour, min, seconds, value = value[0:1], value[1:3], value[4:6], "00", value[6:]
- } else if std == stdNumShortTZ || std == stdISO8601ShortTZ {
- if len(value) < 3 {
- err = errBad
- break
- }
- sign, hour, min, seconds, value = value[0:1], value[1:3], "00", "00", value[3:]
- } else if std == stdISO8601ColonSecondsTZ || std == stdNumColonSecondsTZ {
- if len(value) < 9 {
- err = errBad
- break
- }
- if value[3] != ':' || value[6] != ':' {
- err = errBad
- break
- }
- sign, hour, min, seconds, value = value[0:1], value[1:3], value[4:6], value[7:9], value[9:]
- } else if std == stdISO8601SecondsTZ || std == stdNumSecondsTz {
- if len(value) < 7 {
- err = errBad
- break
- }
- sign, hour, min, seconds, value = value[0:1], value[1:3], value[3:5], value[5:7], value[7:]
- } else {
- if len(value) < 5 {
- err = errBad
- break
- }
- sign, hour, min, seconds, value = value[0:1], value[1:3], value[3:5], "00", value[5:]
- }
- var hr, mm, ss int
- hr, _, err = getnum(hour, true)
- if err == nil {
- mm, _, err = getnum(min, true)
- }
- if err == nil {
- ss, _, err = getnum(seconds, true)
- }
- zoneOffset = (hr*60+mm)*60 + ss // offset is in seconds
- switch sign[0] {
- case '+':
- case '-':
- zoneOffset = -zoneOffset
- default:
- err = errBad
- }
- case stdTZ:
- // Does it look like a time zone?
- if len(value) >= 3 && value[0:3] == "UTC" {
- z = UTC
- value = value[3:]
- break
- }
- n, ok := parseTimeZone(value)
- if !ok {
- err = errBad
- break
- }
- zoneName, value = value[:n], value[n:]
-
- case stdFracSecond0:
- // stdFracSecond0 requires the exact number of digits as specified in
- // the layout.
- ndigit := 1 + digitsLen(std)
- if len(value) < ndigit {
- err = errBad
- break
- }
- nsec, rangeErrString, err = parseNanoseconds(value, ndigit)
- value = value[ndigit:]
-
- case stdFracSecond9:
- if len(value) < 2 || !commaOrPeriod(value[0]) || value[1] < '0' || '9' < value[1] {
- // Fractional second omitted.
- break
- }
- // Take any number of digits, even more than asked for,
- // because it is what the stdSecond case would do.
- i := 0
- for i+1 < len(value) && '0' <= value[i+1] && value[i+1] <= '9' {
- i++
- }
- nsec, rangeErrString, err = parseNanoseconds(value, 1+i)
- value = value[1+i:]
- }
- if rangeErrString != "" {
- return Time{}, newParseError(alayout, avalue, stdstr, value, ": "+rangeErrString+" out of range")
- }
- if err != nil {
- return Time{}, newParseError(alayout, avalue, stdstr, hold, "")
- }
- }
- if pmSet && hour < 12 {
- hour += 12
- } else if amSet && hour == 12 {
- hour = 0
- }
-
- // Convert yday to day, month.
- if yday >= 0 {
- var d int
- var m int
- if isLeap(year) {
- if yday == 31+29 {
- m = int(February)
- d = 29
- } else if yday > 31+29 {
- yday--
- }
- }
- if yday < 1 || yday > 365 {
- return Time{}, newParseError(alayout, avalue, "", value, ": day-of-year out of range")
- }
- if m == 0 {
- m = (yday-1)/31 + 1
- if int(daysBefore[m]) < yday {
- m++
- }
- d = yday - int(daysBefore[m-1])
- }
- // If month, day already seen, yday's m, d must match.
- // Otherwise, set them from m, d.
- if month >= 0 && month != m {
- return Time{}, newParseError(alayout, avalue, "", value, ": day-of-year does not match month")
- }
- month = m
- if day >= 0 && day != d {
- return Time{}, newParseError(alayout, avalue, "", value, ": day-of-year does not match day")
- }
- day = d
- } else {
- if month < 0 {
- month = int(January)
- }
- if day < 0 {
- day = 1
- }
- }
-
- // Validate the day of the month.
- if day < 1 || day > daysIn(Month(month), year) {
- return Time{}, newParseError(alayout, avalue, "", value, ": day out of range")
- }
-
- if z != nil {
- return Date(year, Month(month), day, hour, min, sec, nsec, z), nil
- }
-
- if zoneOffset != -1 {
- t := Date(year, Month(month), day, hour, min, sec, nsec, UTC)
- t.addSec(-int64(zoneOffset))
-
- // Look for local zone with the given offset.
- // If that zone was in effect at the given time, use it.
- name, offset, _, _, _ := local.lookup(t.unixSec())
- if offset == zoneOffset && (zoneName == "" || name == zoneName) {
- t.setLoc(local)
- return t, nil
- }
-
- // Otherwise create fake zone to record offset.
- zoneNameCopy := cloneString(zoneName) // avoid leaking the input value
- t.setLoc(FixedZone(zoneNameCopy, zoneOffset))
- return t, nil
- }
-
- if zoneName != "" {
- t := Date(year, Month(month), day, hour, min, sec, nsec, UTC)
- // Look for local zone with the given offset.
- // If that zone was in effect at the given time, use it.
- offset, ok := local.lookupName(zoneName, t.unixSec())
- if ok {
- t.addSec(-int64(offset))
- t.setLoc(local)
- return t, nil
- }
-
- // Otherwise, create fake zone with unknown offset.
- if len(zoneName) > 3 && zoneName[:3] == "GMT" {
- offset, _ = atoi(zoneName[3:]) // Guaranteed OK by parseGMT.
- offset *= 3600
- }
- zoneNameCopy := cloneString(zoneName) // avoid leaking the input value
- t.setLoc(FixedZone(zoneNameCopy, offset))
- return t, nil
- }
-
- // Otherwise, fall back to default.
- return Date(year, Month(month), day, hour, min, sec, nsec, defaultLocation), nil
-}
-
-// parseTimeZone parses a time zone string and returns its length. Time zones
-// are human-generated and unpredictable. We can't do precise error checking.
-// On the other hand, for a correct parse there must be a time zone at the
-// beginning of the string, so it's almost always true that there's one
-// there. We look at the beginning of the string for a run of upper-case letters.
-// If there are more than 5, it's an error.
-// If there are 4 or 5 and the last is a T, it's a time zone.
-// If there are 3, it's a time zone.
-// Otherwise, other than special cases, it's not a time zone.
-// GMT is special because it can have an hour offset.
-func parseTimeZone(value string) (length int, ok bool) {
- if len(value) < 3 {
- return 0, false
- }
- // Special case 1: ChST and MeST are the only zones with a lower-case letter.
- if len(value) >= 4 && (value[:4] == "ChST" || value[:4] == "MeST") {
- return 4, true
- }
- // Special case 2: GMT may have an hour offset; treat it specially.
- if value[:3] == "GMT" {
- length = parseGMT(value)
- return length, true
- }
- // Special Case 3: Some time zones are not named, but have +/-00 format
- if value[0] == '+' || value[0] == '-' {
- length = parseSignedOffset(value)
- ok := length > 0 // parseSignedOffset returns 0 in case of bad input
- return length, ok
- }
- // How many upper-case letters are there? Need at least three, at most five.
- var nUpper int
- for nUpper = 0; nUpper < 6; nUpper++ {
- if nUpper >= len(value) {
- break
- }
- if c := value[nUpper]; c < 'A' || 'Z' < c {
- break
- }
- }
- switch nUpper {
- case 0, 1, 2, 6:
- return 0, false
- case 5: // Must end in T to match.
- if value[4] == 'T' {
- return 5, true
- }
- case 4:
- // Must end in T, except one special case.
- if value[3] == 'T' || value[:4] == "WITA" {
- return 4, true
- }
- case 3:
- return 3, true
- }
- return 0, false
-}
-
-// parseGMT parses a GMT time zone. The input string is known to start "GMT".
-// The function checks whether that is followed by a sign and a number in the
-// range -23 through +23 excluding zero.
-func parseGMT(value string) int {
- value = value[3:]
- if len(value) == 0 {
- return 3
- }
-
- return 3 + parseSignedOffset(value)
-}
-
-// parseSignedOffset parses a signed timezone offset (e.g. "+03" or "-04").
-// The function checks for a signed number in the range -23 through +23 excluding zero.
-// Returns length of the found offset string or 0 otherwise.
-func parseSignedOffset(value string) int {
- sign := value[0]
- if sign != '-' && sign != '+' {
- return 0
- }
- x, rem, err := leadingInt(value[1:])
-
- // fail if nothing consumed by leadingInt
- if err != nil || value[1:] == rem {
- return 0
- }
- if x > 23 {
- return 0
- }
- return len(value) - len(rem)
-}
-
-func commaOrPeriod(b byte) bool {
- return b == '.' || b == ','
-}
-
-func parseNanoseconds[bytes []byte | string](value bytes, nbytes int) (ns int, rangeErrString string, err error) {
- if !commaOrPeriod(value[0]) {
- err = errBad
- return
- }
- if nbytes > 10 {
- value = value[:10]
- nbytes = 10
- }
- if ns, err = atoi(value[1:nbytes]); err != nil {
- return
- }
- if ns < 0 {
- rangeErrString = "fractional second"
- return
- }
- // We need nanoseconds, which means scaling by the number
- // of missing digits in the format, maximum length 10.
- scaleDigits := 10 - nbytes
- for i := 0; i < scaleDigits; i++ {
- ns *= 10
- }
- return
-}
-
-var errLeadingInt = errors.New("time: bad [0-9]*") // never printed
-
-// leadingInt consumes the leading [0-9]* from s.
-func leadingInt[bytes []byte | string](s bytes) (x uint64, rem bytes, err error) {
- i := 0
- for ; i < len(s); i++ {
- c := s[i]
- if c < '0' || c > '9' {
- break
- }
- if x > 1<<63/10 {
- // overflow
- return 0, rem, errLeadingInt
- }
- x = x*10 + uint64(c) - '0'
- if x > 1<<63 {
- // overflow
- return 0, rem, errLeadingInt
- }
- }
- return x, s[i:], nil
-}
-
-// leadingFraction consumes the leading [0-9]* from s.
-// It is used only for fractions, so does not return an error on overflow,
-// it just stops accumulating precision.
-func leadingFraction(s string) (x uint64, scale float64, rem string) {
- i := 0
- scale = 1
- overflow := false
- for ; i < len(s); i++ {
- c := s[i]
- if c < '0' || c > '9' {
- break
- }
- if overflow {
- continue
- }
- if x > (1<<63-1)/10 {
- // It's possible for overflow to give a positive number, so take care.
- overflow = true
- continue
- }
- y := x*10 + uint64(c) - '0'
- if y > 1<<63 {
- overflow = true
- continue
- }
- x = y
- scale *= 10
- }
- return x, scale, s[i:]
-}
-
-var unitMap = map[string]uint64{
- "ns": uint64(Nanosecond),
- "us": uint64(Microsecond),
- "µs": uint64(Microsecond), // U+00B5 = micro symbol
- "μs": uint64(Microsecond), // U+03BC = Greek letter mu
- "ms": uint64(Millisecond),
- "s": uint64(Second),
- "m": uint64(Minute),
- "h": uint64(Hour),
-}
-
-// ParseDuration parses a duration string.
-// A duration string is a possibly signed sequence of
-// decimal numbers, each with optional fraction and a unit suffix,
-// such as "300ms", "-1.5h" or "2h45m".
-// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
-func ParseDuration(s string) (Duration, error) {
- // [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
- orig := s
- var d uint64
- neg := false
-
- // Consume [-+]?
- if s != "" {
- c := s[0]
- if c == '-' || c == '+' {
- neg = c == '-'
- s = s[1:]
- }
- }
- // Special case: if all that is left is "0", this is zero.
- if s == "0" {
- return 0, nil
- }
- if s == "" {
- return 0, errors.New("time: invalid duration " + quote(orig))
- }
- for s != "" {
- var (
- v, f uint64 // integers before, after decimal point
- scale float64 = 1 // value = v + f/scale
- )
-
- var err error
-
- // The next character must be [0-9.]
- if !(s[0] == '.' || '0' <= s[0] && s[0] <= '9') {
- return 0, errors.New("time: invalid duration " + quote(orig))
- }
- // Consume [0-9]*
- pl := len(s)
- v, s, err = leadingInt(s)
- if err != nil {
- return 0, errors.New("time: invalid duration " + quote(orig))
- }
- pre := pl != len(s) // whether we consumed anything before a period
-
- // Consume (\.[0-9]*)?
- post := false
- if s != "" && s[0] == '.' {
- s = s[1:]
- pl := len(s)
- f, scale, s = leadingFraction(s)
- post = pl != len(s)
- }
- if !pre && !post {
- // no digits (e.g. ".s" or "-.s")
- return 0, errors.New("time: invalid duration " + quote(orig))
- }
-
- // Consume unit.
- i := 0
- for ; i < len(s); i++ {
- c := s[i]
- if c == '.' || '0' <= c && c <= '9' {
- break
- }
- }
- if i == 0 {
- return 0, errors.New("time: missing unit in duration " + quote(orig))
- }
- u := s[:i]
- s = s[i:]
- unit, ok := unitMap[u]
- if !ok {
- return 0, errors.New("time: unknown unit " + quote(u) + " in duration " + quote(orig))
- }
- if v > 1<<63/unit {
- // overflow
- return 0, errors.New("time: invalid duration " + quote(orig))
- }
- v *= unit
- if f > 0 {
- // float64 is needed to be nanosecond accurate for fractions of hours.
- // v >= 0 && (f*unit/scale) <= 3.6e+12 (ns/h, h is the largest unit)
- v += uint64(float64(f) * (float64(unit) / scale))
- if v > 1<<63 {
- // overflow
- return 0, errors.New("time: invalid duration " + quote(orig))
- }
- }
- d += v
- if d > 1<<63 {
- return 0, errors.New("time: invalid duration " + quote(orig))
- }
- }
- if neg {
- return -Duration(d), nil
- }
- if d > 1<<63-1 {
- return 0, errors.New("time: invalid duration " + quote(orig))
- }
- return Duration(d), nil
-}
diff --git a/contrib/go/_std_1.20/src/time/sys_unix.go b/contrib/go/_std_1.20/src/time/sys_unix.go
deleted file mode 100644
index 0f06aa6ccd..0000000000
--- a/contrib/go/_std_1.20/src/time/sys_unix.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2011 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.
-
-//go:build unix || (js && wasm)
-
-package time
-
-import (
- "errors"
- "syscall"
-)
-
-// for testing: whatever interrupts a sleep
-func interrupt() {
- syscall.Kill(syscall.Getpid(), syscall.SIGCHLD)
-}
-
-func open(name string) (uintptr, error) {
- fd, err := syscall.Open(name, syscall.O_RDONLY, 0)
- if err != nil {
- return 0, err
- }
- return uintptr(fd), nil
-}
-
-func read(fd uintptr, buf []byte) (int, error) {
- return syscall.Read(int(fd), buf)
-}
-
-func closefd(fd uintptr) {
- syscall.Close(int(fd))
-}
-
-func preadn(fd uintptr, buf []byte, off int) error {
- whence := seekStart
- if off < 0 {
- whence = seekEnd
- }
- if _, err := syscall.Seek(int(fd), int64(off), whence); err != nil {
- return err
- }
- for len(buf) > 0 {
- m, err := syscall.Read(int(fd), buf)
- if m <= 0 {
- if err == nil {
- return errors.New("short read")
- }
- return err
- }
- buf = buf[m:]
- }
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/time/tick.go b/contrib/go/_std_1.20/src/time/tick.go
deleted file mode 100644
index dcfeca8783..0000000000
--- a/contrib/go/_std_1.20/src/time/tick.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2009 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 time
-
-import "errors"
-
-// A Ticker holds a channel that delivers “ticks” of a clock
-// at intervals.
-type Ticker struct {
- C <-chan Time // The channel on which the ticks are delivered.
- r runtimeTimer
-}
-
-// NewTicker returns a new Ticker containing a channel that will send
-// the current time on the channel after each tick. The period of the
-// ticks is specified by the duration argument. The ticker will adjust
-// the time interval or drop ticks to make up for slow receivers.
-// The duration d must be greater than zero; if not, NewTicker will
-// panic. Stop the ticker to release associated resources.
-func NewTicker(d Duration) *Ticker {
- if d <= 0 {
- panic(errors.New("non-positive interval for NewTicker"))
- }
- // Give the channel a 1-element time buffer.
- // If the client falls behind while reading, we drop ticks
- // on the floor until the client catches up.
- c := make(chan Time, 1)
- t := &Ticker{
- C: c,
- r: runtimeTimer{
- when: when(d),
- period: int64(d),
- f: sendTime,
- arg: c,
- },
- }
- startTimer(&t.r)
- return t
-}
-
-// Stop turns off a ticker. After Stop, no more ticks will be sent.
-// Stop does not close the channel, to prevent a concurrent goroutine
-// reading from the channel from seeing an erroneous "tick".
-func (t *Ticker) Stop() {
- stopTimer(&t.r)
-}
-
-// Reset stops a ticker and resets its period to the specified duration.
-// The next tick will arrive after the new period elapses. The duration d
-// must be greater than zero; if not, Reset will panic.
-func (t *Ticker) Reset(d Duration) {
- if d <= 0 {
- panic("non-positive interval for Ticker.Reset")
- }
- if t.r.f == nil {
- panic("time: Reset called on uninitialized Ticker")
- }
- modTimer(&t.r, when(d), int64(d), t.r.f, t.r.arg, t.r.seq)
-}
-
-// Tick is a convenience wrapper for NewTicker providing access to the ticking
-// channel only. While Tick is useful for clients that have no need to shut down
-// the Ticker, be aware that without a way to shut it down the underlying
-// Ticker cannot be recovered by the garbage collector; it "leaks".
-// Unlike NewTicker, Tick will return nil if d <= 0.
-func Tick(d Duration) <-chan Time {
- if d <= 0 {
- return nil
- }
- return NewTicker(d).C
-}
diff --git a/contrib/go/_std_1.20/src/time/tzdata/tzdata.go b/contrib/go/_std_1.20/src/time/tzdata/tzdata.go
deleted file mode 100644
index a320e17404..0000000000
--- a/contrib/go/_std_1.20/src/time/tzdata/tzdata.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// 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.
-
-//go:generate go run generate_zipdata.go
-
-// Package tzdata provides an embedded copy of the timezone database.
-// If this package is imported anywhere in the program, then if
-// the time package cannot find tzdata files on the system,
-// it will use this embedded information.
-//
-// Importing this package will increase the size of a program by about
-// 450 KB.
-//
-// This package should normally be imported by a program's main package,
-// not by a library. Libraries normally shouldn't decide whether to
-// include the timezone database in a program.
-//
-// This package will be automatically imported if you build with
-// -tags timetzdata.
-package tzdata
-
-// The test for this package is time/tzdata_test.go.
-
-import (
- "errors"
- "syscall"
- _ "unsafe" // for go:linkname
-
-)
-
-// registerLoadFromEmbeddedTZData is defined in package time.
-//
-//go:linkname registerLoadFromEmbeddedTZData time.registerLoadFromEmbeddedTZData
-func registerLoadFromEmbeddedTZData(func(string) (string, error))
-
-func init() {
- registerLoadFromEmbeddedTZData(loadFromEmbeddedTZData)
-}
-
-// get4s returns the little-endian 32-bit value at the start of s.
-func get4s(s string) int {
- if len(s) < 4 {
- return 0
- }
- return int(s[0]) | int(s[1])<<8 | int(s[2])<<16 | int(s[3])<<24
-}
-
-// get2s returns the little-endian 16-bit value at the start of s.
-func get2s(s string) int {
- if len(s) < 2 {
- return 0
- }
- return int(s[0]) | int(s[1])<<8
-}
-
-// loadFromEmbeddedTZData returns the contents of the file with the given
-// name in an uncompressed zip file, where the contents of the file can
-// be found in embeddedTzdata.
-// This is similar to time.loadTzinfoFromZip.
-func loadFromEmbeddedTZData(name string) (string, error) {
- const (
- zecheader = 0x06054b50
- zcheader = 0x02014b50
- ztailsize = 22
-
- zheadersize = 30
- zheader = 0x04034b50
- )
-
- z := zipdata
-
- idx := len(z) - ztailsize
- n := get2s(z[idx+10:])
- idx = get4s(z[idx+16:])
-
- for i := 0; i < n; i++ {
- // See time.loadTzinfoFromZip for zip entry layout.
- if get4s(z[idx:]) != zcheader {
- break
- }
- meth := get2s(z[idx+10:])
- size := get4s(z[idx+24:])
- namelen := get2s(z[idx+28:])
- xlen := get2s(z[idx+30:])
- fclen := get2s(z[idx+32:])
- off := get4s(z[idx+42:])
- zname := z[idx+46 : idx+46+namelen]
- idx += 46 + namelen + xlen + fclen
- if zname != name {
- continue
- }
- if meth != 0 {
- return "", errors.New("unsupported compression for " + name + " in embedded tzdata")
- }
-
- // See time.loadTzinfoFromZip for zip per-file header layout.
- idx = off
- if get4s(z[idx:]) != zheader ||
- get2s(z[idx+8:]) != meth ||
- get2s(z[idx+26:]) != namelen ||
- z[idx+30:idx+30+namelen] != name {
- return "", errors.New("corrupt embedded tzdata")
- }
- xlen = get2s(z[idx+28:])
- idx += 30 + namelen + xlen
- return z[idx : idx+size], nil
- }
-
- return "", syscall.ENOENT
-}
diff --git a/contrib/go/_std_1.20/src/time/tzdata/ya.make b/contrib/go/_std_1.20/src/time/tzdata/ya.make
deleted file mode 100644
index 1f059e4640..0000000000
--- a/contrib/go/_std_1.20/src/time/tzdata/ya.make
+++ /dev/null
@@ -1,8 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- tzdata.go
- zipdata.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/time/tzdata/zipdata.go b/contrib/go/_std_1.20/src/time/tzdata/zipdata.go
deleted file mode 100644
index 856ac48222..0000000000
--- a/contrib/go/_std_1.20/src/time/tzdata/zipdata.go
+++ /dev/null
@@ -1,6690 +0,0 @@
-// 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.
-
-// Code generated by generate_zipdata. DO NOT EDIT.
-
-// This file contains an embedded zip archive that contains time zone
-// files compiled using the code and data maintained as part of the
-// IANA Time Zone Database.
-// The IANA asserts that the data is in the public domain.
-
-// For more information, see
-// https://www.iana.org/time-zones
-// ftp://ftp.iana.org/tz/code/tz-link.html
-// https://datatracker.ietf.org/doc/html/rfc6557
-
-package tzdata
-
-const zipdata = "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x00\x00Africa/AbidjanTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\f\x00\x00\x00Africa/AccraTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x12\x00\x00\x00Africa/Addis_AbabaTZif2\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" +
- "\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00" +
- "\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3" +
- "\x8a\x0e\xc0\xd6\x01\x00\x00\xd6\x01\x00\x00\x0e\x00\x00\x00Africa/AlgiersTZif2\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\x06" +
- "\x00\x00\x00\x1a\xff\xff\xff\xffkɛ$\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfep" +
- "\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\f\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa4\xb8\x06p\xff\xff\xff\xff" +
- "\xc6\xff\x06p\xff\xff\xff\xff\xc7X\xba\x80\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЊ\x00\x00\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N$p\xff\xff\xff\xff\xd4K\ap" +
- "\xff\xff\xff\xff\xe5\xce\xd3\x00\xff\xff\xff\xff\xf3\\\xb0\xf0\x00\x00\x00\x00\x02x\xc1\xf0\x00\x00\x00\x00\x03C\xc8\xf0\x00\x00\x00\x00\r\xcf\xd7\x00\x00\x00\x00\x00\x0e\xadD\xf0\x00\x00\x00\x00\x0fxZ\x00\x00\x00\x00\x00" +
- "\x10hY\x10\x00\x00\x00\x00\x12vCp\x00\x00\x00\x00\x13fB\x80\x00\x00\x00\x00\x14_|\x10\x00\x00\x00\x00\x15O_\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x03\x05\x03" +
- "\x02\x03\x02\x05\x04\x05\x03\x02\x03\x05\x00\x00\x02\xdc\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x1c \x01\x11\x00\x00\x0e\x10\x00\x16LMT\x00PMT\x00WEST\x00W" +
- "ET\x00CEST\x00CET\x00\nCET-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x00\x00Africa/Asma" +
- "raTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0" +
- "\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00" +
- "+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x00\x00Africa/AsmeraTZif" +
- "2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1" +
- "\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00" +
- "\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\r\x00\x00\x00Africa/BamakoTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00Africa/BanguiTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00" +
- "\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{" +
- "\x87\x82\x00\x00\x00\x82\x00\x00\x00\r\x00\x00\x00Africa/BanjulTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00" +
- "\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca>\xd5\xe0\x95\x00\x00\x00\x95\x00" +
- "\x00\x00\r\x00\x00\x00Africa/BissauTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x92\xe6" +
- "\x9c\x90\x00\x00\x00\x00\tga\x10\x01\x02\xff\xff\xf1d\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x00\x00\x00\bLMT\x00-01\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x00\x00Africa/BlantyreTZif2\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\x01" +
- "\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d" +
- "\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x12\x00\x00\x00Africa/BrazzavilleTZif2\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\x04\x00" +
- "\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00" +
- "\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x10\x00" +
- "\x00\x00Africa/BujumburaTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5" +
- "\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5#)\x16\x1d\x05\x00\x00\x1d\x05\x00\x00\f\x00\x00\x00A" +
- "frica/CairoTZif2\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\x80\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff}\xbdM\xab\xff\xff\xff\xffȓ" +
- "\xb4\xe0\xff\xff\xff\xff\xc8\xfa{\xd0\xff\xff\xff\xff\xc9\xfc\xef\xe0\xff\xff\xff\xff\xca\xc7\xe8\xd0\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xcc\xdf)\xd0\xff\xff\xff\xffͬ\xe1\xe0\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff" +
- "\xff\xffϏf\xe0\xff\xff\xff\xffЩy\xd0\xff\xff\xff\xffф`\xe0\xff\xff\xff\xffҊ\xadP\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\x7f\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\xc2\xfd\x80\xff\xff\xff\xff\xfc۾\xf0\xff\xff\xff\xff\xfd\xa5\x82\x80\xff\xff\xff\xff\xfe\xbc\xf2p\xff\xff\xff\xff\xff\x86\xb6\x00\x00\x00" +
- "\x00\x00\x00\x9e%\xf0\x00\x00\x00\x00\x01g\xe9\x80\x00\x00\x00\x00\x02\x7fYp\x00\x00\x00\x00\x03I\x1d\x00\x00\x00\x00\x00\x04a\xdep\x00\x00\x00\x00\x05+\xa2\x00\x00\x00\x00\x00\x06C\x11\xf0\x00\x00\x00\x00\a\f" +
- "Հ\x00\x00\x00\x00\b$Ep\x00\x00\x00\x00\b\xee\t\x00\x00\x00\x00\x00\n\x05x\xf0\x00\x00\x00\x00\n\xcf<\x80\x00\x00\x00\x00\v\xe7\xfd\xf0\x00\x00\x00\x00\f\xb1\xc1\x80\x00\x00\x00\x00\r\xc91p\x00\x00" +
- "\x00\x00\x0e\x92\xf5\x00\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11\x8b\x98p\x00\x00\x00\x00\x12U\\\x00\x00\x00\x00\x00\x13n\x1dp\x00\x00\x00\x00\x147\xe1\x00\x00\x00\x00\x00\x15O" +
- "P\xf0\x00\x00\x00\x00\x16\x19\x14\x80\x00\x00\x00\x00\x17\xa0\x93\xf0\x00\x00\x00\x00\x17\xfaH\x00\x00\x00\x00\x00\x19p\xa3\xf0\x00\x00\x00\x00\x19\xdb{\x80\x00\x00\x00\x00\x1a\xf4<\xf0\x00\x00\x00\x00\x1b\xbe\x00\x80\x00\x00" +
- "\x00\x00\x1c\xd5pp\x00\x00\x00\x00\x1d\x9f4\x00\x00\x00\x00\x00\x1e\xb6\xa3\xf0\x00\x00\x00\x00\x1f\x80g\x80\x00\x00\x00\x00 \x97\xd7p\x00\x00\x00\x00!a\x9b\x00\x00\x00\x00\x00\"z\\p\x00\x00\x00\x00#D" +
- " \x00\x00\x00\x00\x00$b'p\x00\x00\x00\x00%%S\x80\x00\x00\x00\x00&<\xc3p\x00\x00\x00\x00'\x06\x87\x00\x00\x00\x00\x00(\x1d\xf6\xf0\x00\x00\x00\x00(纀\x00\x00\x00\x00*\x00{\xf0\x00\x00" +
- "\x00\x00*\xca?\x80\x00\x00\x00\x00+\xe1\xafp\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\xc2\xe2\xf0\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00\x00/\xa0\x13\xe0\x00\x00\x00\x000k\f\xd0\x00\x00\x00\x001\x7f" +
- "\xf5\xe0\x00\x00\x00\x002J\xee\xd0\x00\x00\x00\x003_\xd7\xe0\x00\x00\x00\x004*\xd0\xd0\x00\x00\x00\x005?\xb9\xe0\x00\x00\x00\x006\n\xb2\xd0\x00\x00\x00\x007(\xd6`\x00\x00\x00\x007\xf3\xcfP\x00\x00" +
- "\x00\x009\b\xb8`\x00\x00\x00\x009ӱP\x00\x00\x00\x00:\xe8\x9a`\x00\x00\x00\x00;\xb3\x93P\x00\x00\x00\x00<\xc8|`\x00\x00\x00\x00=\x93uP\x00\x00\x00\x00>\xa8^`\x00\x00\x00\x00?s" +
- "WP\x00\x00\x00\x00@\x91z\xe0\x00\x00\x00\x00A\\s\xd0\x00\x00\x00\x00Bq\\\xe0\x00\x00\x00\x00C<U\xd0\x00\x00\x00\x00DQ>\xe0\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F1 \xe0\x00\x00" +
- "\x00\x00F\xe0jP\x00\x00\x00\x00H\x11\x02\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xf0\xe4\xe0\x00\x00\x00\x00J\x8d\xb9P\x00\x00\x00\x00K\xda\x01`\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00L\x89" +
- "X\xe0\x00\x00\x00\x00L\xa4\xfaP\x00\x00\x00\x00Su8\xe0\x00\x00\x00\x00S\xac\x89\xd0\x00\x00\x00\x00Sڼ`\x00\x00\x00\x00T$\x82P\x00\x00\x00\x00dJ\xf0`\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\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\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" +
- "\x1dU\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-2EEST,M4.5.5/0,M10.5.4/24\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001B\xb0;\x7f\a\x00\x00\x7f\a\x00\x00\x11\x00\x00\x00Africa/CasablancaTZif2\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\xc5\x00\x00\x00\x05\x00\x00\x00\f\xff\xff\xff\xff\x96Q\xf9\x9c\xff\xff\xff\xff\xc6\xff\x14\x80\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xed\x80\xff\xff\xff\xffҡ" +
- "2\xf0\xff\xff\xff\xff\xdb5\xa4\x00\xff\xff\xff\xff\xdb\xee'\xf0\xff\xff\xff\xff\xfb%r@\xff\xff\xff\xff\xfb\xc2\xefp\x00\x00\x00\x00\bk\x84\x80\x00\x00\x00\x00\b\xc6m\xf0\x00\x00\x00\x00\v\xe8\f\x00\x00\x00" +
- "\x00\x00\faG\xf0\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00\x00\x00\x1a\xb7\xa6\x00\x00\x00\x00\x00\x1e\x18o\xf0\x00\x00\x00\x00HA" +
- "\xe6\x80\x00\x00\x00\x00H\xbb\"p\x00\x00\x00\x00J#\x1a\x00\x00\x00\x00\x00J\x8d\xd5p\x00\x00\x00\x00K\xdc\xc0\x80\x00\x00\x00\x00L]\xe5p\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00N4\x8c\xf0\x00\x00" +
- "\x00\x00O\x9c\xa0\xa0\x00\x00\x00\x00P\b\xbb\xa0\x00\x00\x00\x00P1\x9a \x00\x00\x00\x00Pg\xa7\xa0\x00\x00\x00\x00Q|\x82\xa0\x00\x00\x00\x00Q\xd8ˠ\x00\x00\x00\x00R\x05\x9e\xa0\x00\x00\x00\x00Rl" +
- "s\xa0\x00\x00\x00\x00S7z\xa0\x00\x00\x00\x00S\xae!\xa0\x00\x00\x00\x00S\xdcF \x00\x00\x00\x00TLU\xa0\x00\x00\x00\x00U\x17\\\xa0\x00\x00\x00\x00U|\xe0 \x00\x00\x00\x00U\xab\x04\xa0\x00\x00" +
- "\x00\x00V,7\xa0\x00\x00\x00\x00V\xf7>\xa0\x00\x00\x00\x00WS\x87\xa0\x00\x00\x00\x00W\x81\xac \x00\x00\x00\x00X\x15T \x00\x00\x00\x00X\xd7 \xa0\x00\x00\x00\x00Y \xf4\xa0\x00\x00\x00\x00YX" +
- "S\xa0\x00\x00\x00\x00Y\xf56 \x00\x00\x00\x00Z\xb7\x02\xa0\x00\x00\x00\x00Z\xf7\x9c \x00\x00\x00\x00[%\xc0\xa0\x00\x00\x00\x00[\xd5\x18 \x00\x00\x00\x00\\\xceC\xa0\x00\x00\x00\x00\\\xfch \x00\x00" +
- "\x00\x00^\x9b\xb0\xa0\x00\x00\x00\x00^\xd3\x0f\xa0\x00\x00\x00\x00`rX \x00\x00\x00\x00`\xa0|\xa0\x00\x00\x00\x00b?\xc5 \x00\x00\x00\x00bw$ \x00\x00\x00\x00d\x16l\xa0\x00\x00\x00\x00dD" +
- "\x91 \x00\x00\x00\x00e\xed\x14 \x00\x00\x00\x00f\x1b8\xa0\x00\x00\x00\x00g\xba\x81 \x00\x00\x00\x00g\xf1\xe0 \x00\x00\x00\x00i\x91(\xa0\x00\x00\x00\x00i\xbfM \x00\x00\x00\x00kg\xd0 \x00\x00" +
- "\x00\x00k\x95\xf4\xa0\x00\x00\x00\x00m5= \x00\x00\x00\x00ml\x9c \x00\x00\x00\x00o\v\xe4\xa0\x00\x00\x00\x00o:\t \x00\x00\x00\x00p\xd9Q\xa0\x00\x00\x00\x00q\x10\xb0\xa0\x00\x00\x00\x00r\xaf" +
- "\xf9 \x00\x00\x00\x00r\xde\x1d\xa0\x00\x00\x00\x00t\x86\xa0\xa0\x00\x00\x00\x00t\xb4\xc5 \x00\x00\x00\x00vT\r\xa0\x00\x00\x00\x00v\x8bl\xa0\x00\x00\x00\x00x*\xb5 \x00\x00\x00\x00xX٠\x00\x00" +
- "\x00\x00y\xf8\" \x00\x00\x00\x00z/\x81 \x00\x00\x00\x00{\xceɠ\x00\x00\x00\x00|\x06(\xa0\x00\x00\x00\x00}\xa5q \x00\x00\x00\x00}ӕ\xa0\x00\x00\x00\x00\x7fr\xde \x00\x00\x00\x00\x7f\xaa" +
- "= \x00\x00\x00\x00\x81I\x85\xa0\x00\x00\x00\x00\x81w\xaa \x00\x00\x00\x00\x83 - \x00\x00\x00\x00\x83NQ\xa0\x00\x00\x00\x00\x84\xed\x9a \x00\x00\x00\x00\x85$\xf9 \x00\x00\x00\x00\x86\xc4A\xa0\x00\x00" +
- "\x00\x00\x86\xf2f \x00\x00\x00\x00\x88\x91\xae\xa0\x00\x00\x00\x00\x88\xc9\r\xa0\x00\x00\x00\x00\x8ahV \x00\x00\x00\x00\x8a\x9f\xb5 \x00\x00\x00\x00\x8c>\xfd\xa0\x00\x00\x00\x00\x8cm\" \x00\x00\x00\x00\x8e\f" +
- "j\xa0\x00\x00\x00\x00\x8eCɠ\x00\x00\x00\x00\x8f\xe3\x12 \x00\x00\x00\x00\x90\x116\xa0\x00\x00\x00\x00\x91\xb9\xb9\xa0\x00\x00\x00\x00\x91\xe7\xde \x00\x00\x00\x00\x93\x87&\xa0\x00\x00\x00\x00\x93\xbe\x85\xa0\x00\x00" +
- "\x00\x00\x95]\xce \x00\x00\x00\x00\x95\x8b\xf2\xa0\x00\x00\x00\x00\x97+; \x00\x00\x00\x00\x97b\x9a \x00\x00\x00\x00\x99\x01\xe2\xa0\x00\x00\x00\x00\x999A\xa0\x00\x00\x00\x00\x9a؊ \x00\x00\x00\x00\x9b\x06" +
- "\xae\xa0\x00\x00\x00\x00\x9c\xa5\xf7 \x00\x00\x00\x00\x9c\xddV \x00\x00\x00\x00\x9e|\x9e\xa0\x00\x00\x00\x00\x9e\xaa\xc3 \x00\x00\x00\x00\xa0SF \x00\x00\x00\x00\xa0\x81j\xa0\x00\x00\x00\x00\xa2 \xb3 \x00\x00" +
- "\x00\x00\xa2X\x12 \x00\x00\x00\x00\xa3\xf7Z\xa0\x00\x00\x00\x00\xa4%\x7f \x00\x00\x00\x00\xa5\xc4Ǡ\x00\x00\x00\x00\xa5\xfc&\xa0\x00\x00\x00\x00\xa7\x9bo \x00\x00\x00\x00\xa7\xd2\xce \x00\x00\x00\x00\xa9r" +
- "\x16\xa0\x00\x00\x00\x00\xa9\xa0; \x00\x00\x00\x00\xab?\x83\xa0\x00\x00\x00\x00\xabv\xe2\xa0\x00\x00\x00\x00\xad\x16+ \x00\x00\x00\x00\xadDO\xa0\x00\x00\x00\x00\xae\xecҠ\x00\x00\x00\x00\xaf\x1a\xf7 \x00\x00" +
- "\x00\x00\xb0\xba?\xa0\x00\x00\x00\x00\xb0\xf1\x9e\xa0\x00\x00\x00\x00\xb2\x90\xe7 \x00\x00\x00\x00\xb2\xbf\v\xa0\x00\x00\x00\x00\xb4^T \x00\x00\x00\x00\xb4\x95\xb3 \x00\x00\x00\x00\xb64\xfb\xa0\x00\x00\x00\x00\xb6l" +
- "Z\xa0\x00\x00\x00\x00\xb8\v\xa3 \x00\x00\x00\x00\xb89Ǡ\x00\x00\x00\x00\xb9\xd9\x10 \x00\x00\x00\x00\xba\x10o \x00\x00\x00\x00\xbb\xaf\xb7\xa0\x00\x00\x00\x00\xbb\xdd\xdc \x00\x00\x00\x00\xbd\x86_ \x00\x00" +
- "\x00\x00\xbd\xb4\x83\xa0\x00\x00\x00\x00\xbfS\xcc \x00\x00\x00\x00\xbf\x8b+ \x00\x00\x00\x00\xc1*s\xa0\x00\x00\x00\x00\xc1X\x98 \x00\x00\x00\x00\xc2\xf7\xe0\xa0\x00\x00\x00\x00\xc3/?\xa0\x00\x00\x00\x00\xc4\xce" +
- "\x88 \x00\x00\x00\x00\xc5\x05\xe7 \x00\x00\x00\x00ƥ/\xa0\x00\x00\x00\x00\xc6\xd3T \x00\x00\x00\x00\xc8r\x9c\xa0\x00\x00\x00\x00ȩ\xfb\xa0\x00\x00\x00\x00\xcaID \x00\x00\x00\x00\xcawh\xa0\x00\x00" +
- "\x00\x00\xcc\x1f\xeb\xa0\x00\x00\x00\x00\xccN\x10 \x00\x00\x00\x00\xcd\xedX\xa0\x00\x00\x00\x00\xce$\xb7\xa0\x00\x00\x00\x00\xcf\xc4\x00 \x00\x00\x00\x00\xcf\xf2$\xa0\x00\x00\x00\x00ёm \x00\x00\x00\x00\xd1\xc8" +
- "\xcc \x00\x00\x00\x00\xd3h\x14\xa0\x00\x00\x00\x00Ӗ9 \x00\x00\x00\x00\xd5>\xbc \x00\x00\x00\x00\xd5l\xe0\xa0\x00\x00\x00\x00\xd7\f) \x00\x00\x00\x00\xd7C\x88 \x00\x00\x00\x00\xd8\xe2Р\x00\x00" +
- "\x00\x00\xd9\x10\xf5 \x00\x00\x00\x00ڹx \x00\x00\x00\x00\xda眠\x00\x00\x00\x00܆\xe5 \x00\x00\x00\x00ܾD \x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\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\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\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\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\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\xff\xff\xf8\xe4\x00" +
- "\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x00\x04\x00\x00\x00\x00\x01\bLMT\x00+01\x00+00\x00\n<+01>-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x9f\x1b\xeb\xdd2\x02\x00\x002\x02\x00\x00\f\x00\x00\x00Africa/CeutaTZif2\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\x05\x00" +
- "\x00\x00\x16\xff\xff\xff\xff~6\xb5\x00\xff\xff\xff\xff\x9e\xd6up\xff\xff\xff\xff\x9f\xa1n`\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xe7n\x00\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa72\x00\xff" +
- "\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff\xfb%r@\xff\xff\xff\xff\xfb\xc2\xefp\x00\x00\x00\x00\bk\x84\x80\x00\x00\x00\x00\b" +
- "\xc6m\xf0\x00\x00\x00\x00\v\xe8\f\x00\x00\x00\x00\x00\faG\xf0\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00\x00\x00\x1a\xb7\xa6\x00\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%" +
- "\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00" +
- "\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xff\xfb\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x01\x11" +
- "LMT\x00WET\x00WEST\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x00\x00Africa/ConakryTZif2\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" +
- "\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b" +
- "{\x87\x82\x00\x00\x00\x82\x00\x00\x00\f\x00\x00\x00Africa/DakarTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00" +
- "\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00" +
- "\x00\x00\x14\x00\x00\x00Africa/Dar_es_SalaamTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00" +
- "\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00" +
- "*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf" +
- "\x00\x00\x00\x0f\x00\x00\x00Africa/DjiboutiTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff" +
- "\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n" +
- "\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r" +
- "\x00\x00\x00Africa/DoualaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff" +
- "\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+" +
- "0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xd3\xc6g&\a\x00\x00&\a\x00\x00\x0f\x00\x00\x00Africa/El_Aaiu" +
- "nTZif2\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\xba\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xbcH\xf0\xe0\x00\x00\x00\x00\vѰ\x90\x00\x00\x00\x00\v\xe8\f\x00" +
- "\x00\x00\x00\x00\faG\xf0\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00\x00\x00HA\xe6\x80\x00\x00\x00\x00H\xbb\"p\x00\x00\x00\x00" +
- "J#\x1a\x00\x00\x00\x00\x00J\x8d\xd5p\x00\x00\x00\x00K\xdc\xc0\x80\x00\x00\x00\x00L]\xe5p\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00N4\x8c\xf0\x00\x00\x00\x00O\x9c\xa0\xa0\x00\x00\x00\x00P\b\xbb\xa0" +
- "\x00\x00\x00\x00P1\x9a \x00\x00\x00\x00Pg\xa7\xa0\x00\x00\x00\x00Q|\x82\xa0\x00\x00\x00\x00Q\xd8ˠ\x00\x00\x00\x00R\x05\x9e\xa0\x00\x00\x00\x00Rls\xa0\x00\x00\x00\x00S7z\xa0\x00\x00\x00\x00" +
- "S\xae!\xa0\x00\x00\x00\x00S\xdcF \x00\x00\x00\x00TLU\xa0\x00\x00\x00\x00U\x17\\\xa0\x00\x00\x00\x00U|\xe0 \x00\x00\x00\x00U\xab\x04\xa0\x00\x00\x00\x00V,7\xa0\x00\x00\x00\x00V\xf7>\xa0" +
- "\x00\x00\x00\x00WS\x87\xa0\x00\x00\x00\x00W\x81\xac \x00\x00\x00\x00X\x15T \x00\x00\x00\x00X\xd7 \xa0\x00\x00\x00\x00Y \xf4\xa0\x00\x00\x00\x00YXS\xa0\x00\x00\x00\x00Y\xf56 \x00\x00\x00\x00" +
- "Z\xb7\x02\xa0\x00\x00\x00\x00Z\xf7\x9c \x00\x00\x00\x00[%\xc0\xa0\x00\x00\x00\x00[\xd5\x18 \x00\x00\x00\x00\\\xceC\xa0\x00\x00\x00\x00\\\xfch \x00\x00\x00\x00^\x9b\xb0\xa0\x00\x00\x00\x00^\xd3\x0f\xa0" +
- "\x00\x00\x00\x00`rX \x00\x00\x00\x00`\xa0|\xa0\x00\x00\x00\x00b?\xc5 \x00\x00\x00\x00bw$ \x00\x00\x00\x00d\x16l\xa0\x00\x00\x00\x00dD\x91 \x00\x00\x00\x00e\xed\x14 \x00\x00\x00\x00" +
- "f\x1b8\xa0\x00\x00\x00\x00g\xba\x81 \x00\x00\x00\x00g\xf1\xe0 \x00\x00\x00\x00i\x91(\xa0\x00\x00\x00\x00i\xbfM \x00\x00\x00\x00kg\xd0 \x00\x00\x00\x00k\x95\xf4\xa0\x00\x00\x00\x00m5= " +
- "\x00\x00\x00\x00ml\x9c \x00\x00\x00\x00o\v\xe4\xa0\x00\x00\x00\x00o:\t \x00\x00\x00\x00p\xd9Q\xa0\x00\x00\x00\x00q\x10\xb0\xa0\x00\x00\x00\x00r\xaf\xf9 \x00\x00\x00\x00r\xde\x1d\xa0\x00\x00\x00\x00" +
- "t\x86\xa0\xa0\x00\x00\x00\x00t\xb4\xc5 \x00\x00\x00\x00vT\r\xa0\x00\x00\x00\x00v\x8bl\xa0\x00\x00\x00\x00x*\xb5 \x00\x00\x00\x00xX٠\x00\x00\x00\x00y\xf8\" \x00\x00\x00\x00z/\x81 " +
- "\x00\x00\x00\x00{\xceɠ\x00\x00\x00\x00|\x06(\xa0\x00\x00\x00\x00}\xa5q \x00\x00\x00\x00}ӕ\xa0\x00\x00\x00\x00\x7fr\xde \x00\x00\x00\x00\x7f\xaa= \x00\x00\x00\x00\x81I\x85\xa0\x00\x00\x00\x00" +
- "\x81w\xaa \x00\x00\x00\x00\x83 - \x00\x00\x00\x00\x83NQ\xa0\x00\x00\x00\x00\x84\xed\x9a \x00\x00\x00\x00\x85$\xf9 \x00\x00\x00\x00\x86\xc4A\xa0\x00\x00\x00\x00\x86\xf2f \x00\x00\x00\x00\x88\x91\xae\xa0" +
- "\x00\x00\x00\x00\x88\xc9\r\xa0\x00\x00\x00\x00\x8ahV \x00\x00\x00\x00\x8a\x9f\xb5 \x00\x00\x00\x00\x8c>\xfd\xa0\x00\x00\x00\x00\x8cm\" \x00\x00\x00\x00\x8e\fj\xa0\x00\x00\x00\x00\x8eCɠ\x00\x00\x00\x00" +
- "\x8f\xe3\x12 \x00\x00\x00\x00\x90\x116\xa0\x00\x00\x00\x00\x91\xb9\xb9\xa0\x00\x00\x00\x00\x91\xe7\xde \x00\x00\x00\x00\x93\x87&\xa0\x00\x00\x00\x00\x93\xbe\x85\xa0\x00\x00\x00\x00\x95]\xce \x00\x00\x00\x00\x95\x8b\xf2\xa0" +
- "\x00\x00\x00\x00\x97+; \x00\x00\x00\x00\x97b\x9a \x00\x00\x00\x00\x99\x01\xe2\xa0\x00\x00\x00\x00\x999A\xa0\x00\x00\x00\x00\x9a؊ \x00\x00\x00\x00\x9b\x06\xae\xa0\x00\x00\x00\x00\x9c\xa5\xf7 \x00\x00\x00\x00" +
- "\x9c\xddV \x00\x00\x00\x00\x9e|\x9e\xa0\x00\x00\x00\x00\x9e\xaa\xc3 \x00\x00\x00\x00\xa0SF \x00\x00\x00\x00\xa0\x81j\xa0\x00\x00\x00\x00\xa2 \xb3 \x00\x00\x00\x00\xa2X\x12 \x00\x00\x00\x00\xa3\xf7Z\xa0" +
- "\x00\x00\x00\x00\xa4%\x7f \x00\x00\x00\x00\xa5\xc4Ǡ\x00\x00\x00\x00\xa5\xfc&\xa0\x00\x00\x00\x00\xa7\x9bo \x00\x00\x00\x00\xa7\xd2\xce \x00\x00\x00\x00\xa9r\x16\xa0\x00\x00\x00\x00\xa9\xa0; \x00\x00\x00\x00" +
- "\xab?\x83\xa0\x00\x00\x00\x00\xabv\xe2\xa0\x00\x00\x00\x00\xad\x16+ \x00\x00\x00\x00\xadDO\xa0\x00\x00\x00\x00\xae\xecҠ\x00\x00\x00\x00\xaf\x1a\xf7 \x00\x00\x00\x00\xb0\xba?\xa0\x00\x00\x00\x00\xb0\xf1\x9e\xa0" +
- "\x00\x00\x00\x00\xb2\x90\xe7 \x00\x00\x00\x00\xb2\xbf\v\xa0\x00\x00\x00\x00\xb4^T \x00\x00\x00\x00\xb4\x95\xb3 \x00\x00\x00\x00\xb64\xfb\xa0\x00\x00\x00\x00\xb6lZ\xa0\x00\x00\x00\x00\xb8\v\xa3 \x00\x00\x00\x00" +
- "\xb89Ǡ\x00\x00\x00\x00\xb9\xd9\x10 \x00\x00\x00\x00\xba\x10o \x00\x00\x00\x00\xbb\xaf\xb7\xa0\x00\x00\x00\x00\xbb\xdd\xdc \x00\x00\x00\x00\xbd\x86_ \x00\x00\x00\x00\xbd\xb4\x83\xa0\x00\x00\x00\x00\xbfS\xcc " +
- "\x00\x00\x00\x00\xbf\x8b+ \x00\x00\x00\x00\xc1*s\xa0\x00\x00\x00\x00\xc1X\x98 \x00\x00\x00\x00\xc2\xf7\xe0\xa0\x00\x00\x00\x00\xc3/?\xa0\x00\x00\x00\x00\xc4Έ \x00\x00\x00\x00\xc5\x05\xe7 \x00\x00\x00\x00" +
- "ƥ/\xa0\x00\x00\x00\x00\xc6\xd3T \x00\x00\x00\x00\xc8r\x9c\xa0\x00\x00\x00\x00ȩ\xfb\xa0\x00\x00\x00\x00\xcaID \x00\x00\x00\x00\xcawh\xa0\x00\x00\x00\x00\xcc\x1f\xeb\xa0\x00\x00\x00\x00\xccN\x10 " +
- "\x00\x00\x00\x00\xcd\xedX\xa0\x00\x00\x00\x00\xce$\xb7\xa0\x00\x00\x00\x00\xcf\xc4\x00 \x00\x00\x00\x00\xcf\xf2$\xa0\x00\x00\x00\x00ёm \x00\x00\x00\x00\xd1\xc8\xcc \x00\x00\x00\x00\xd3h\x14\xa0\x00\x00\x00\x00" +
- "Ӗ9 \x00\x00\x00\x00\xd5>\xbc \x00\x00\x00\x00\xd5l\xe0\xa0\x00\x00\x00\x00\xd7\f) \x00\x00\x00\x00\xd7C\x88 \x00\x00\x00\x00\xd8\xe2Р\x00\x00\x00\x00\xd9\x10\xf5 \x00\x00\x00\x00ڹx " +
- "\x00\x00\x00\x00\xda眠\x00\x00\x00\x00܆\xe5 \x00\x00\x00\x00ܾD \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\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\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\xff\xff\xf3\xa0\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\f\x00\x00\x00\x00\x01\f" +
- "\x00\x00\x0e\x10\x00\bLMT\x00-01\x00+01\x00+00\x00\n<+01>-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x00" +
- "\x00Africa/FreetownTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01" +
- "\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x00\x00Afri" +
- "ca/GaboroneTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00" +
- "\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00Africa/H" +
- "arareTZif2\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\x00TZif" +
- "2\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\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00" +
- "\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\x13\x00\x00\x00Africa/Johanne" +
- "sburgTZif2\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\x00TZif" +
- "2\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\x06\x00\x00\x00\x04\x00\x00\x00\t\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff" +
- "̮\x8c\x80\xff\xff\xff\xff͞op\xff\xff\xff\xffΎn\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LM" +
- "T\x00SAST\x00\nSAST-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xcf\x10n\xca\x01\x00\x00\xca\x01\x00\x00\v\x00\x00\x00Africa/JubaTZif" +
- "2\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\x11\xff\xff\xff\xff\xb6\xa3\xda\xdc\x00\x00\x00\x00\x00\x9e\x17\xe0\x00\x00\x00\x00\x01z4P\x00\x00\x00\x00\x02" +
- "}\xf9\xe0\x00\x00\x00\x00\x03[g\xd0\x00\x00\x00\x00\x04`~\xe0\x00\x00\x00\x00\x05=\xec\xd0\x00\x00\x00\x00\x06@`\xe0\x00\x00\x00\x00\a\x1f P\x00\x00\x00\x00\b B\xe0\x00\x00\x00\x00\t\x00S\xd0\x00" +
- "\x00\x00\x00\n\x00$\xe0\x00\x00\x00\x00\n\xe1\x87P\x00\x00\x00\x00\v\xe0\x06\xe0\x00\x00\x00\x00\f\xc4\fP\x00\x00\x00\x00\r\xbf\xe8\xe0\x00\x00\x00\x00\x0e\xa5?\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10" +
- "\x86sP\x00\x00\x00\x00\x11\x88\xe7`\x00\x00\x00\x00\x12g\xa6\xd0\x00\x00\x00\x00\x13h\xc9`\x00\x00\x00\x00\x14J+\xd0\x00\x00\x00\x00\x15H\xab`\x00\x00\x00\x00\x16+_P\x00\x00\x00\x00\x17(\x8d`\x00" +
- "\x00\x00\x00\x18\f\x92\xd0\x00\x00\x00\x00\x19\bo`\x00\x00\x00\x00\x19\xed\xc6P\x00\x00\x00\x00\x1a\xf1\x8b\xe0\x00\x00\x00\x00\x1b\xd0KP\x00\x00\x00\x00\x1c\xd1m\xe0\x00\x00\x00\x00\x1d\xb1~\xd0\x00\x00\x00\x008" +
- "\x80E \x00\x00\x00\x00`\x17\x1aP\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\x03\x02\x00\x00\x1d\xa4\x00\x00\x00\x00*0\x01\x04\x00\x00" +
- "\x1c \x00\t\x00\x00*0\x00\rLMT\x00CAST\x00CAT\x00EAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00" +
- "\x0e\x00\x00\x00Africa/KampalaTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1" +
- "\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac" +
- "\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xadD\xef\xca\x01\x00\x00\xca\x01\x00\x00\x0f\x00\x00\x00A" +
- "frica/KhartoumTZif2\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\x11\xff\xff\xff\xff\xb6\xa3\xda\x00\x00\x00\x00" +
- "\x00\x00\x9e\x17\xe0\x00\x00\x00\x00\x01z4P\x00\x00\x00\x00\x02}\xf9\xe0\x00\x00\x00\x00\x03[g\xd0\x00\x00\x00\x00\x04`~\xe0\x00\x00\x00\x00\x05=\xec\xd0\x00\x00\x00\x00\x06@`\xe0\x00\x00\x00\x00\a\x1f " +
- "P\x00\x00\x00\x00\b B\xe0\x00\x00\x00\x00\t\x00S\xd0\x00\x00\x00\x00\n\x00$\xe0\x00\x00\x00\x00\n\xe1\x87P\x00\x00\x00\x00\v\xe0\x06\xe0\x00\x00\x00\x00\f\xc4\fP\x00\x00\x00\x00\r\xbf\xe8\xe0\x00\x00\x00" +
- "\x00\x0e\xa5?\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10\x86sP\x00\x00\x00\x00\x11\x88\xe7`\x00\x00\x00\x00\x12g\xa6\xd0\x00\x00\x00\x00\x13h\xc9`\x00\x00\x00\x00\x14J+\xd0\x00\x00\x00\x00\x15H\xab" +
- "`\x00\x00\x00\x00\x16+_P\x00\x00\x00\x00\x17(\x8d`\x00\x00\x00\x00\x18\f\x92\xd0\x00\x00\x00\x00\x19\bo`\x00\x00\x00\x00\x19\xed\xc6P\x00\x00\x00\x00\x1a\xf1\x8b\xe0\x00\x00\x00\x00\x1b\xd0KP\x00\x00\x00" +
- "\x00\x1c\xd1m\xe0\x00\x00\x00\x00\x1d\xb1~\xd0\x00\x00\x00\x008\x80E \x00\x00\x00\x00Y\xf8\xe4P\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\x03\x02\x00\x00\x1e\x80\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00\rLMT\x00CAST\x00CAT\x00EAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00Africa/KigaliTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0f\x00\x00\x00Africa/KinshasaTZif2\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\x04\x00\x00" +
- "\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b" +
- "\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\f\x00\x00" +
- "\x00Africa/LagosTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff" +
- "\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+003" +
- "0\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x00\x00Africa/Libreville" +
- "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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff" +
- "\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\v\x00\x00\x00Africa/LomeTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00Africa/LuandaTZif2\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" +
- "\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a" +
- "\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00" +
- "\x11\x00\x00\x00Africa/LubumbashiTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff" +
- "\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00" +
- "\x00\x00Africa/LusakaTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00" +
- "\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00Afri" +
- "ca/MalaboTZif2\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\x00" +
- "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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00" +
- "\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WA" +
- "T\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00Africa/MaputoTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\nCAT" +
- "-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\r\x00\x00\x00Africa/MaseruTZif2\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\x06\x00\x00\x00\x04\x00\x00\x00\t\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\xff\xff\xff\xffΎn" +
- "\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00\nSAST-2\nPK\x03\x04" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\x0e\x00\x00\x00Africa/MbabaneTZif2\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\x06\x00\x00\x00\x04\x00\x00\x00\t\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\xff\xff\xff\xffΎn\x80\xff\xff\xff\xff\xcf" +
- "~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00\nSAST-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x10\x00\x00\x00Africa/MogadishuTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84" +
- "\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x006\x99rU\xa4\x00\x00\x00\xa4\x00\x00\x00\x0f\x00\x00\x00Africa/MonroviaTZif2\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\x03\x00" +
- "\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xffZz\xa6\x9c\xff\xff\xff\xff\xa0_l\x9c\x00\x00\x00\x00\x03\xcaZn\x01\x02\x03\xff\xff\xf5\xe4\x00\x00\xff\xff\xf5\xe4\x00\x04\xff\xff\xf5\x92\x00\x04\x00\x00\x00\x00\x00\bLM" +
- "T\x00MMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00Africa/Nairobi" +
- "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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff" +
- "\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0" +
- "245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x81\t\x03\xa0\x00\x00\x00\xa0\x00\x00\x00\x0f\x00\x00\x00Africa/NdjamenaTZif" +
- "2\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\x03\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\x92\xe6\x80d\x00\x00\x00\x00\x12fqp\x00\x00\x00\x00\x13&\xde`\x01\x02\x01\x00\x00" +
- "\x0e\x1c\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00WAT\x00WAST\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00" +
- "\x00\x00\r\x00\x00\x00Africa/NiameyTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xab" +
- "p\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GM" +
- "T\x00+0030\x00WAT\x00\nWAT-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x11\x00\x00\x00Africa/Noua" +
- "kchottTZif2\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\x00TZi" +
- "f2\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\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00" +
- "\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00Africa/Ouagado" +
- "ugouTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04" +
- "LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x00\x00Africa/Porto-Nov" +
- "oTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1" +
- "\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\a\b\x00\b\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\nWAT-1" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\n\x8a\x84\xad\x00\x00\x00\xad\x00\x00\x00\x0f\x00\x00\x00Africa/Sao_TomeTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff^<\xfd0\xff\xff\xff\xff\x92掀\x00\x00\x00\x00ZI\x88\x10\x00\x00\x00\x00\\*\xbb\x90\x01\x02\x03\x02\x00\x00\x06" +
- "P\x00\x00\xff\xff\xf7c\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\bLMT\x00GMT\x00WAT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00" +
- "\x00\x82\x00\x00\x00\x0f\x00\x00\x00Africa/TimbuktuTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff" +
- "\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00" +
- "\x0e\x00\x00\x00Africa/TripoliTZif2\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\x11\xff\xff\xff\xff\xa1\xf2\xc1" +
- "$\xff\xff\xff\xffݻ\xb1\x10\xff\xff\xff\xff\xde#\xad`\xff\xff\xff\xff\xe1x\xd2\x10\xff\xff\xff\xff\xe1\xe7e\xe0\xff\xff\xff\xff\xe5/?p\xff\xff\xff\xff\xe5\xa9\xcc\xe0\xff\xff\xff\xff\xebN\xc6\xf0\x00\x00\x00" +
- "\x00\x16\x92B`\x00\x00\x00\x00\x17\b\xf7p\x00\x00\x00\x00\x17\xfa+\xe0\x00\x00\x00\x00\x18\xea*\xf0\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a̯\xf0\x00\x00\x00\x00\x1b\xbd\xe4`\x00\x00\x00\x00\x1c\xb4z" +
- "\xf0\x00\x00\x00\x00\x1d\x9f\x17\xe0\x00\x00\x00\x00\x1e\x93\vp\x00\x00\x00\x00\x1f\x82\xee`\x00\x00\x00\x00 pJp\x00\x00\x00\x00!a~\xe0\x00\x00\x00\x00\"R\xcfp\x00\x00\x00\x00#D\x03\xe0\x00\x00\x00" +
- "\x00$4\x02\xf0\x00\x00\x00\x00%%7`\x00\x00\x00\x00&@\xb7\xf0\x00\x00\x00\x002N\xf1`\x00\x00\x00\x003D6p\x00\x00\x00\x0045j\xe0\x00\x00\x00\x00P\x9d\x99\x00\x00\x00\x00\x00QT\xd9" +
- "\x80\x00\x00\x00\x00Ri\xb4\x80\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x03\x02\x01\x03\x00\x00\f\\\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00" +
- "\x00\x1c \x00\rLMT\x00CEST\x00CET\x00EET\x00\nEET-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\xf4\x94\v\xc1\x01\x00\x00\xc1\x01\x00\x00\f\x00\x00\x00A" +
- "frica/TunisTZif2\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\x11\xff\xff\xff\xffYF\x13\xf4\xff\xff\xff\xff\x91`" +
- "PO\xff\xff\xff\xff\xc6:\x88\xe0\xff\xff\xff\xff\xc7X\x9e`\xff\xff\xff\xff\xc7\xdb\"\xe0\xff\xff\xff\xff\xca\xe2T\xe0\xff\xff\xff\xff˭i\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff" +
- "\xff\xff\xcd\xc2\x16\x00\xff\xff\xff\xff\xcd̰\x10\xff\xff\xff\xff\u03a25\x00\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xffЉ\xe3\xe0\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N\x16`\x00\x00\x00\x00\r\xc7" +
- "\xdf\xf0\x00\x00\x00\x00\x0e\x89\xacp\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\"\xa3:\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00" +
- "\x00\x00&<\xc3p\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00Bt\r\xf0\x00\x00\x00\x00C<\x80\x00\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#" +
- "\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\t\x8c\x00\x00\x00\x00" +
- "\x021\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00PMT\x00CEST\x00CET\x00\nCET-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m)\xb8P~\x02" +
- "\x00\x00~\x02\x00\x00\x0f\x00\x00\x00Africa/WindhoekTZif2\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\x005\x00\x00\x00\x06\x00\x00\x00\x17" +
- "\xff\xff\xff\xffm{Kx\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff̮\x8c\x80\xff\xff\xff\xff͞op\x00\x00\x00\x00&\x06\xa7\xe0\x00\x00\x00\x00-\x8c\xc7`\x00\x00\x00\x00.i\x1c\x10\x00\x00\x00\x00" +
- "/}\xe9\x00\x00\x00\x00\x000H\xfe\x10\x00\x00\x00\x001g\x05\x80\x00\x00\x00\x002(\xe0\x10\x00\x00\x00\x003F\xe7\x80\x00\x00\x00\x004\x11\xfc\x90\x00\x00\x00\x005&ɀ\x00\x00\x00\x005\xf1ސ" +
- "\x00\x00\x00\x007\x06\xab\x80\x00\x00\x00\x007\xd1\xc0\x90\x00\x00\x00\x008捀\x00\x00\x00\x009\xb1\xa2\x90\x00\x00\x00\x00:\xc6o\x80\x00\x00\x00\x00;\x91\x84\x90\x00\x00\x00\x00<\xaf\x8c\x00\x00\x00\x00\x00" +
- "=qf\x90\x00\x00\x00\x00>\x8fn\x00\x00\x00\x00\x00?Z\x83\x10\x00\x00\x00\x00@oP\x00\x00\x00\x00\x00A:e\x10\x00\x00\x00\x00BO2\x00\x00\x00\x00\x00C\x1aG\x10\x00\x00\x00\x00D/\x14\x00" +
- "\x00\x00\x00\x00D\xfa)\x10\x00\x00\x00\x00F\x0e\xf6\x00\x00\x00\x00\x00F\xda\v\x10\x00\x00\x00\x00G\xf8\x12\x80\x00\x00\x00\x00H\xc3'\x90\x00\x00\x00\x00I\xd7\xf4\x80\x00\x00\x00\x00J\xa3\t\x90\x00\x00\x00\x00" +
- "K\xb7ր\x00\x00\x00\x00L\x82\xeb\x90\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00Nb͐\x00\x00\x00\x00Ow\x9a\x80\x00\x00\x00\x00PB\xaf\x90\x00\x00\x00\x00Q`\xb7\x00\x00\x00\x00\x00R\"\x91\x90" +
- "\x00\x00\x00\x00S@\x99\x00\x00\x00\x00\x00T\v\xae\x10\x00\x00\x00\x00U {\x00\x00\x00\x00\x00U\xeb\x90\x10\x00\x00\x00\x00W\x00]\x00\x00\x00\x00\x00W\xcbr\x10\x00\x00\x00\x00X\xe0?\x00\x00\x00\x00\x00" +
- "Y\xabT\x10\x01\x02\x03\x02\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\x00\x00\x10" +
- "\b\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00\x1c \x00\n\x00\x00*0\x01\n\x00\x00\x0e\x10\x01\x0f\x00\x00\x1c \x00\x13LMT\x00+0130\x00SAST\x00WAT\x00CAT\x00\nCAT" +
- "-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\f\x00\x00\x00America/AdakTZif2\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\x00T\x00\x00\x00\n\x00\x00\x00!\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87Z^\xff\xff\xff\xffˉD\xd0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aP@" +
- "\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00" +
- "\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\a1\x16\xc0\x00\x00\x00\x00\a\x8dm\xd0\x00\x00\x00\x00\t\x10\xf8\xc0\x00\x00\x00\x00\t\xad\xe9P\x00\x00\x00\x00\n\xf0\xda\xc0" +
- "\x00\x00\x00\x00\v\xe0\xd9\xd0\x00\x00\x00\x00\f\xd9\xf7@\x00\x00\x00\x00\r\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00" +
- "\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00\x18\"}\xc0\x00\x00\x00\x00\x19\tBP" +
- "\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\" \x00\x00\x00\x00\x1a\xf2P\xc0\x00\x00\x00\x00\x1b\xe23\xb0\x00\x00\x00\x00\x1c\xd22\xc0\x00\x00\x00\x00\x1d\xc2\x15\xb0\x00\x00\x00\x00\x1e\xb2\x14\xc0\x00\x00\x00\x00" +
- "\x1f\xa1\xf7\xb0\x00\x00\x00\x00 vG@\x00\x00\x00\x00!\x81ٰ\x00\x00\x00\x00\"V)@\x00\x00\x00\x00#j\xf60\x00\x00\x00\x00$6\v@\x00\x00\x00\x00%J\xd80\x00\x00\x00\x00&\x15\xed@" +
- "\x00\x00\x00\x00'*\xba0\x00\x00\x00\x00'\xff\t\xc0\x00\x00\x00\x00)\n\x9c0\x00\x00\x00\x00)\xde\xeb\xc0\x00\x00\x00\x00*\xea~0\x00\x00\x00\x00+\xbe\xcd\xc0\x00\x00\x00\x00,Ӛ\xb0\x00\x00\x00\x00" +
- "-\x9e\xaf\xc0\x00\x00\x00\x00.\xb3|\xb0\x00\x00\x00\x00/~\x91\xc0\x00\x00\x00\x000\x93^\xb0\x00\x00\x00\x001g\xae@\x00\x00\x00\x002s@\xb0\x00\x00\x00\x003G\x90@\x00\x00\x00\x004S\"\xb0" +
- "\x00\x00\x00\x005'r@\x00\x00\x00\x0063\x04\xb0\x00\x00\x00\x007\aT@\x00\x00\x00\x008\x1c!0\x00\x00\x00\x008\xe76@\x00\x00\x00\x009\xfc\x030\x00\x00\x00\x00:\xc7\x18@\x00\x00\x00\x00" +
- ";\xdb\xe50\x00\x00\x00\x00<\xb04\xc0\x00\x00\x00\x00=\xbb\xc70\x00\x00\x00\x00>\x90\x16\xc0\x00\x00\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84Ű\x00\x00\x00\x00BO\xda\xc0" +
- "\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
- "\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xab\xe2" +
- "\x00\x00\xff\xffZb\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\b\xff\xffs`\x01\f\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xffs`\x00\x18\xff\xff\x81p\x01\x1d\xff\xffs`\x00\x19LMT\x00" +
- "NST\x00NWT\x00NPT\x00BST\x00BDT\x00AHST\x00HDT\x00\nHST10HDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x005\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\x11\x00\x00\x00America/AnchorageTZif2\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\x00T\x00\x00\x00\n\x00\x00\x00(\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87AH\xff\xff\xff\xffˉ6\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aB0\xff\xff\xff\xff" +
- "\xfa\xd2G\xa0\xff\xff\xff\xff\xfe\xb8c@\xff\xff\xff\xff\xff\xa8F0\x00\x00\x00\x00\x00\x98E@\x00\x00\x00\x00\x01\x88(0\x00\x00\x00\x00\x02x'@\x00\x00\x00\x00\x03qD\xb0\x00\x00\x00\x00\x04aC\xc0" +
- "\x00\x00\x00\x00\x05Q&\xb0\x00\x00\x00\x00\x06A%\xc0\x00\x00\x00\x00\a1\b\xb0\x00\x00\x00\x00\a\x8d_\xc0\x00\x00\x00\x00\t\x10\xea\xb0\x00\x00\x00\x00\t\xad\xdb@\x00\x00\x00\x00\n\xf0̰\x00\x00\x00\x00" +
- "\v\xe0\xcb\xc0\x00\x00\x00\x00\f\xd9\xe90\x00\x00\x00\x00\r\xc0\xad\xc0\x00\x00\x00\x00\x0e\xb9\xcb0\x00\x00\x00\x00\x0f\xa9\xca@\x00\x00\x00\x00\x10\x99\xad0\x00\x00\x00\x00\x11\x89\xac@\x00\x00\x00\x00\x12y\x8f0" +
- "\x00\x00\x00\x00\x13i\x8e@\x00\x00\x00\x00\x14Yq0\x00\x00\x00\x00\x15Ip@\x00\x00\x00\x00\x169S0\x00\x00\x00\x00\x17)R@\x00\x00\x00\x00\x18\"o\xb0\x00\x00\x00\x00\x19\t4@\x00\x00\x00\x00" +
- "\x1a\x02Q\xb0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0" +
- "\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00" +
- "'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0" +
- "\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x00" +
- "5'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 " +
- "\x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00" +
- "Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
- "\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xc4\xf8\x00\x00\xff\xff" +
- "sx\x00\x00\xff\xffs`\x00\x04\xff\xff\x81p\x01\b\xff\xff\x81p\x01\f\xff\xffs`\x00\x10\xff\xff\x81p\x01\x15\xff\xff\x81p\x00\x1a\xff\xff\x8f\x80\x01\x1e\xff\xff\x81p\x00#LMT\x00AST\x00" +
- "AWT\x00APT\x00AHST\x00AHDT\x00YST\x00AKDT\x00AKST\x00\nAKST9AKDT,M3.2.0,M11.1.0\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00America/AnguillaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00" +
- "\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1" +
- "\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America/AntiguaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00" +
- "\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01" +
- "\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x01V\rP\x02\x00\x00P\x02\x00\x00\x11\x00\x00\x00America" +
- "/AraguainaTZif2\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\x003\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaat0\xff\xff\xff\xff\xb8\x0fI" +
- "\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff" +
- "\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e" +
- "\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00" +
- "\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2" +
- "\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00" +
- "\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e" +
- "\xa0\x00\x00\x00\x00=đ0\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00P\x83e0\x00\x00\x00\x00Q 9\xa0\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\x02\xff\xff\xd2\xd0\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>" +
- "3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x00\x00America/Argentina/Buenos_Air" +
- "esTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xa8L\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R" +
- "@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff" +
- "\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6" +
- "\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff" +
- "\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10" +
- "@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff" +
- "\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2" +
- "\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00" +
- "\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc94\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff" +
- "\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00\x1b\x00\x00\x00America/Argentina/CatamarcaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e" +
- "\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff" +
- "\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe" +
- "*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff" +
- "\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13" +
- "C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff" +
- "\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!" +
- "\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00" +
- "\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01" +
- "\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00" +
- "\x00 \x00\x00\x00America/Argentina/ComodRivadaviaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0" +
- "\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff" +
- "\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0" +
- "\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff" +
- "\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30" +
- "\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00" +
- "\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0" +
- "\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00" +
- "@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT" +
- "\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00Ameri" +
- "ca/Argentina/CordobaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr" +
- "\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff" +
- "\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2" +
- ";\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff" +
- "\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4" +
- "\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff" +
- "\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#" +
- "\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00" +
- "\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I" +
- "\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05" +
- "\x04\x05\x04\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00" +
- "\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00utZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x00\x00America/Argentina/Juju" +
- "yTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xb8\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@" +
- "\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff" +
- "\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0" +
- "\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff" +
- "\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@" +
- "\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff" +
- "\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0" +
- "\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xe2۰\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x00" +
- "7\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x04\x05\x04\x05\x03\x05\x04\x05\xff\xff\xc2\xc8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5" +
- "\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m\aD\x0e\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00" +
- "\x00America/Argentina/La_RiojaTZif2\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\x06\x00\x00" +
- "\x00\x14\xff\xff\xff\xffr\x9c\xb0,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff" +
- "\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d" +
- "\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff" +
- "\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=" +
- "\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff" +
- "\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$" +
- "o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'͵\xa0\x00\x00\x00\x00(&&@\x00\x00" +
- "\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5" +
- "\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x05\x04\x05\x04\x05\x04\x05\x04\x02\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc1T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00" +
- "CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ŒZ\x8c\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00Americ" +
- "a/Argentina/MendozaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c" +
- "\xb2\x04\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff" +
- "\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;" +
- "\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff" +
- "\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f" +
- "\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff" +
- "\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94" +
- "\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'\x194@\x00\x00\x00\x00'\xcdð\x00\x00\x00\x00(\xfag\xc0\x00\x00\x00\x00)\xb0H\xb0\x00\x00" +
- "\x00\x00*\xe0\xe1@\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xb0\x13\xb0\x00\x00\x00\x00AV>\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc" +
- "\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x04\x05\x03\x05\x02" +
- "\x05\x04\x05\xff\xff\xbf|\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n" +
- "<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ep\xb4c\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x00\x00America/Argentina/Rio_G" +
- "allegosTZif2\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\x00TZ" +
- "if2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2d\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff" +
- "\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96" +
- "\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff" +
- "\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee" +
- "\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff" +
- "\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbc" +
- "S0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00" +
- "\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99" +
- "W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf\x1c\x00\x00\xff\xff\xc3" +
- "\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00t*\x9b!\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x00\x00America/Argentina/SaltaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xd4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8" +
- "\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff" +
- "\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5" +
- "\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff" +
- "\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8" +
- "\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff" +
- "\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'" +
- "!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00" +
- "\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05" +
- "\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\xff\xff¬\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-0" +
- "4\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfcz=\xe1\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00America/Arge" +
- "ntina/San_JuanTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb1\xbc\xff\xff\xff" +
- "\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1" +
- "@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff" +
- "\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1" +
- "\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff" +
- "\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35" +
- "\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00" +
- "\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'͵\xa0\x00\x00\x00\x00(&&@\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:" +
- "\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xba\x9f\xb0\x00\x00\x00\x00A\x030@\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00" +
- "\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x05\x04\x05\x04" +
- "\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf\xc4\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-" +
- "02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x80\xb9\\\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00America/Argentina/S" +
- "an_LuisTZif2\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\x00TZ" +
- "if2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf\xb4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff" +
- "\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96" +
- "\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff" +
- "\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee" +
- "\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff" +
- "\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbc" +
- "S0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00" +
- "\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xfd\xa5\xa0\x00\x00\x00\x00'\x194@\x00\x00\x00\x00'\xcdð\x00\x00\x00\x00(G\x1b\xc0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xba" +
- "\x9f\xb0\x00\x00\x00\x00A\x030@\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\x93\xfc\xa0\x00\x00\x00\x00G\xd3R\xb0\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xb34\xb0\x00\x00\x00\x00J\xd1X@\x01\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x05\x03\x05\x02\x05\x04\x03\x02\x03\x02\x05" +
- "\xff\xff\xc1\xcc\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-0" +
- "3>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd8֭\xd6\x02\x00\x00\xd6\x02\x00\x00\x19\x00\x00\x00America/Argentina/TucumanT" +
- "Zif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xa4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff" +
- "\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9" +
- "\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff" +
- "\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM" +
- "\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff" +
- "\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xac" +
- "R@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00" +
- "\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6" +
- "ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xcb\xd1@\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x04" +
- "\x05\xff\xff\xc2\xdc\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-" +
- "03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b}\xb6\x1e\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00America/Argentina/Ushuaia" +
- "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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb1\x88\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff" +
- "\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd" +
- "\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff" +
- "\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xce" +
- "M\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff" +
- "\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd" +
- "\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00" +
- "\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007" +
- "\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xb9N0\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf\xf8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0" +
- "\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\r\x00\x00\x00America/ArubaTZif2\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\x04\x00\x00" +
- "\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b" +
- "\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xa9y\x9at\x03\x00\x00t\x03\x00\x00\x10\x00\x00\x00Am" +
- "erica/AsuncionTZif2\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\x00O\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xffi\x87\x11\x90\xff\xff\xff" +
- "\xff\xb8\x17\xf5\x90\x00\x00\x00\x00\x05+\xda@\x00\x00\x00\x00\a\xfc\xf0\xb0\x00\x00\x00\x00\n\xcft\xc0\x00\x00\x00\x00\v\x97ʰ\x00\x00\x00\x00\f\xb1\xf9\xc0\x00\x00\x00\x00\rx\xfe0\x00\x00\x00\x00\x0e\x93-" +
- "@\x00\x00\x00\x00\x0fZ1\xb0\x00\x00\x00\x00\x10t`\xc0\x00\x00\x00\x00\x11dC\xb0\x00\x00\x00\x00\x12U\x94@\x00\x00\x00\x00\x13FȰ\x00\x00\x00\x00\x148\x19@\x00\x00\x00\x00\x15'\xfc0\x00\x00\x00" +
- "\x00\x16\x19L\xc0\x00\x00\x00\x00\x17\t/\xb0\x00\x00\x00\x00\x17\xfa\x80@\x00\x00\x00\x00\x18\xeac0\x00\x00\x00\x00\x19۳\xc0\x00\x00\x00\x00\x1a\xcc\xe80\x00\x00\x00\x00\x1b\xbe8\xc0\x00\x00\x00\x00\x1c\xae\x1b" +
- "\xb0\x00\x00\x00\x00\x1d\x9fl@\x00\x00\x00\x00\x1e\x8fO0\x00\x00\x00\x00\x1f\x80\x9f\xc0\x00\x00\x00\x00 p\x82\xb0\x00\x00\x00\x00!a\xd3@\x00\x00\x00\x00\"S\a\xb0\x00\x00\x00\x00#DX@\x00\x00\x00" +
- "\x00$4;0\x00\x00\x00\x00%A;@\x00\x00\x00\x00&\x15n\xb0\x00\x00\x00\x00'\x06\xbf@\x00\x00\x00\x00'\xf6\xa20\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*Ͻ" +
- "\xc0\x00\x00\x00\x00+\xb9\t0\x00\x00\x00\x00,\xab\xab@\x00\x00\x00\x00-p\f\xb0\x00\x00\x00\x00.\x8c\xde\xc0\x00\x00\x00\x00/O\xee\xb0\x00\x00\x00\x000n\x12@\x00\x00\x00\x0016h0\x00\x00\x00" +
- "\x002W.\xc0\x00\x00\x00\x003\x0f\xb2\xb0\x00\x00\x00\x0047\x10\xc0\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x006\x16\xf2\xc0\x00\x00\x00\x006\xe1\xeb\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xc1\xcd" +
- "\xb0\x00\x00\x00\x009ֶ\xc0\x00\x00\x00\x00:\xa1\xaf\xb0\x00\x00\x00\x00;\xbf\xd3@\x00\x00\x00\x00<\xaf\xb60\x00\x00\x00\x00=q\x90\xc0\x00\x00\x00\x00>\x8f\x980\x00\x00\x00\x00?Z\xad@\x00\x00\x00" +
- "\x00@oz0\x00\x00\x00\x00Aq\xee@\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x1a\xce" +
- "\xc0\x00\x00\x00\x00G\xd3R\xb0\x00\x00\x00\x00H\xfa\xb0\xc0\x00\x00\x00\x00I\xb34\xb0\x00\x00\x00\x00Jڒ\xc0\x00\x00\x00\x00K\xc1;0\x00\x00\x00\x00L\xa7\xff\xc0\x00\x00\x00\x00M\xa1\x1d0\x00\x00\x00" +
- "\x00N\x87\xe1\xc0\x00\x00\x00\x00O\x80\xff0\x00\x00\x00\x00Pp\xfe@\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04" +
- "\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\xff\xff\xc9\xf0\x00\x00\xff\xff\xc9\xf0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff" +
- "\xd5\xd0\x00\f\xff\xff\xd5\xd0\x01\fLMT\x00AMT\x00-04\x00-03\x00\n<-04>4<-03>,M10.1.0/0,M3.4.0/0\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x10\x00\x00\x00America/AtikokanTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00C" +
- "MT\x00EST\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\f\x00\x00\x00America/AtkaTZif2" +
- "\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\x00T\x00\x00\x00\n\x00\x00\x00!\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87Z^\xff\xff\xff\xffˉD\xd0\xff\xff\xff\xff\xd2#" +
- "\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P\x00\x00" +
- "\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\a1\x16\xc0\x00\x00\x00\x00\a\x8dm\xd0\x00\x00\x00\x00\t\x10\xf8\xc0\x00\x00\x00\x00\t\xad" +
- "\xe9P\x00\x00\x00\x00\n\xf0\xda\xc0\x00\x00\x00\x00\v\xe0\xd9\xd0\x00\x00\x00\x00\f\xd9\xf7@\x00\x00\x00\x00\r\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@\x00\x00" +
- "\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00\x18\"" +
- "}\xc0\x00\x00\x00\x00\x19\tBP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\" \x00\x00\x00\x00\x1a\xf2P\xc0\x00\x00\x00\x00\x1b\xe23\xb0\x00\x00\x00\x00\x1c\xd22\xc0\x00\x00\x00\x00\x1d\xc2\x15\xb0\x00\x00" +
- "\x00\x00\x1e\xb2\x14\xc0\x00\x00\x00\x00\x1f\xa1\xf7\xb0\x00\x00\x00\x00 vG@\x00\x00\x00\x00!\x81ٰ\x00\x00\x00\x00\"V)@\x00\x00\x00\x00#j\xf60\x00\x00\x00\x00$6\v@\x00\x00\x00\x00%J" +
- "\xd80\x00\x00\x00\x00&\x15\xed@\x00\x00\x00\x00'*\xba0\x00\x00\x00\x00'\xff\t\xc0\x00\x00\x00\x00)\n\x9c0\x00\x00\x00\x00)\xde\xeb\xc0\x00\x00\x00\x00*\xea~0\x00\x00\x00\x00+\xbe\xcd\xc0\x00\x00" +
- "\x00\x00,Ӛ\xb0\x00\x00\x00\x00-\x9e\xaf\xc0\x00\x00\x00\x00.\xb3|\xb0\x00\x00\x00\x00/~\x91\xc0\x00\x00\x00\x000\x93^\xb0\x00\x00\x00\x001g\xae@\x00\x00\x00\x002s@\xb0\x00\x00\x00\x003G" +
- "\x90@\x00\x00\x00\x004S\"\xb0\x00\x00\x00\x005'r@\x00\x00\x00\x0063\x04\xb0\x00\x00\x00\x007\aT@\x00\x00\x00\x008\x1c!0\x00\x00\x00\x008\xe76@\x00\x00\x00\x009\xfc\x030\x00\x00" +
- "\x00\x00:\xc7\x18@\x00\x00\x00\x00;\xdb\xe50\x00\x00\x00\x00<\xb04\xc0\x00\x00\x00\x00=\xbb\xc70\x00\x00\x00\x00>\x90\x16\xc0\x00\x00\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84" +
- "Ű\x00\x00\x00\x00BO\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
- "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b" +
- "\t\b\t\b\t\b\x00\x00\xab\xe2\x00\x00\xff\xffZb\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\b\xff\xffs`\x01\f\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xffs`\x00\x18\xff\xff\x81p\x01\x1d" +
- "\xff\xffs`\x00\x19LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00AHST\x00HDT\x00\nHST10HDT,M3.2.0,M11." +
- "1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00OKjǪ\x02\x00\x00\xaa\x02\x00\x00\r\x00\x00\x00America/BahiaTZif2\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\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaak\x1c\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xde" +
- "t \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff" +
- "\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\n" +
- "Ұ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00" +
- "\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xbd" +
- "\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\r\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00\x00\x00\x00.\xa0\x970\x00\x00" +
- "\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 " +
- "\x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00" +
- "\x00\x00=đ0\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xdb\xe4\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03" +
- "\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\x0e\x01n\xd8\x02\x00\x00\xd8\x02\x00\x00\x16\x00\x00\x00America/Bahia_Bandera" +
- "sTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`" +
- "\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x00" +
- "2s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10" +
- "\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00" +
- "@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80" +
- "\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00" +
- "N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80" +
- "\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00" +
- "\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0" +
- "\x01\x02\x01\x03\x01\x02\x01\x04\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
- "\x02\x05\x02\xff\xff\x9dT\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\x8f\x80\x00\x10\xff\xff\xb9\xb0\x01\x14LMT\x00MST\x00CST\x00MDT\x00PST\x00C" +
- "DT\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l=\xad\xbe\x16\x01\x00\x00\x16\x01\x00\x00\x10\x00\x00\x00America/BarbadosTZif2" +
- "\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\x0f\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x92@\xa9e\xff\xff\xff\xff\xcb\xe3\xcb\xd0\xff\xff\xff\xff̔\x82\xe0\xff\xff\xff\xff\xcd\xd6" +
- "\"\xd0\xff\xff\xff\xff\xce|M\xe0\xff\xff\xff\xffϛ\xa6\xd0\xff\xff\xff\xff\xd0ej`\x00\x00\x00\x00\x0e\x00\xf2\xe0\x00\x00\x00\x00\x0e\x94\x8c\xd0\x00\x00\x00\x00\x0f\x97\x00\xe0\x00\x00\x00\x00\x10tn\xd0\x00\x00" +
- "\x00\x00\x11v\xe2\xe0\x00\x00\x00\x00\x12TP\xd0\x00\x00\x00\x00\x13_\xff`\x00\x00\x00\x00\x140>P\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xc8\x1b\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7" +
- "\xc0\x00\b\xff\xff\xce\xc8\x01\fLMT\x00ADT\x00AST\x00-0330\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85-\xb9\xf8\x8a\x01\x00\x00\x8a\x01\x00\x00\r" +
- "\x00\x00\x00America/BelemTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaatt\xff" +
- "\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xff\xdc" +
- "\xb9Y \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff" +
- "\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1d" +
- "Ɏ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\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\xff\xffҌ\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x89غ\xee\x15\x04\x00\x00\x15\x04\x00\x00\x0e\x00\x00\x00America/BelizeTZif2\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" +
- "b\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xff\x93^ٰ\xff\xff\xff\xff\x9f\x9f;\xe0\xff\xff\xff\xff\xa0EQ\xd8\xff\xff\xff\xff\xa1\x7f\x1d\xe0\xff\xff\xff\xff\xa2.nX\xff\xff\xff\xff\xa3^\xff\xe0\xff\xff\xff" +
- "\xff\xa4\x0ePX\xff\xff\xff\xff\xa5>\xe1\xe0\xff\xff\xff\xff\xa5\xee2X\xff\xff\xff\xff\xa7'\xfe`\xff\xff\xff\xff\xa7\xce\x14X\xff\xff\xff\xff\xa9\a\xe0`\xff\xff\xff\xff\xa9\xad\xf6X\xff\xff\xff\xff\xaa\xe7\xc2" +
- "`\xff\xff\xff\xff\xab\x97\x12\xd8\xff\xff\xff\xff\xacǤ`\xff\xff\xff\xff\xadv\xf4\xd8\xff\xff\xff\xff\xae\xa7\x86`\xff\xff\xff\xff\xafV\xd6\xd8\xff\xff\xff\xff\xb0\x87h`\xff\xff\xff\xff\xb16\xb8\xd8\xff\xff\xff" +
- "\xff\xb2p\x84\xe0\xff\xff\xff\xff\xb3\x16\x9a\xd8\xff\xff\xff\xff\xb4Pf\xe0\xff\xff\xff\xff\xb4\xf6|\xd8\xff\xff\xff\xff\xb60H\xe0\xff\xff\xff\xff\xb6ߙX\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb8\xbf{" +
- "X\xff\xff\xff\xff\xb9\xf0\f\xe0\xff\xff\xff\xff\xba\x9f]X\xff\xff\xff\xff\xbb\xd9)`\xff\xff\xff\xff\xbc\x7f?X\xff\xff\xff\xff\xbd\xb9\v`\xff\xff\xff\xff\xbe_!X\xff\xff\xff\xff\xbf\x98\xed`\xff\xff\xff" +
- "\xff\xc0?\x03X\xff\xff\xff\xff\xc1x\xcf`\xff\xff\xff\xff\xc2(\x1f\xd8\xff\xff\xff\xff\xc3X\xb1`\xff\xff\xff\xff\xc4\b\x01\xd8\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc5\xe7\xe3\xd8\xff\xff\xff\xff\xc7!\xaf" +
- "\xe0\xff\xff\xff\xff\xc7\xc7\xc5\xd8\xff\xff\xff\xff\xc9\x01\x91\xe0\xff\xff\xff\xffɧ\xa7\xd8\xff\xff\xff\xff\xca\xe1s\xe0\xff\xff\xff\xffː\xc4X\xff\xff\xff\xff\xcc@\"\xe0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff" +
- "\xff\xd2\xc6qP\xff\xff\xff\xff\xd6)\xfa`\xff\xff\xff\xff\xd6\xd9J\xd8\xff\xff\xff\xff\xd8\t\xdc`\xff\xff\xff\xffع,\xd8\xff\xff\xff\xff\xd9\xe9\xbe`\xff\xff\xff\xffڙ\x0e\xd8\xff\xff\xff\xff\xdb\xd2\xda" +
- "\xe0\xff\xff\xff\xff\xdcx\xf0\xd8\xff\xff\xff\xffݲ\xbc\xe0\xff\xff\xff\xff\xdeX\xd2\xd8\xff\xff\xff\xffߒ\x9e\xe0\xff\xff\xff\xff\xe0A\xefX\xff\xff\xff\xff\xe1r\x80\xe0\xff\xff\xff\xff\xe2!\xd1X\xff\xff\xff" +
- "\xff\xe3Rb\xe0\xff\xff\xff\xff\xe4\x01\xb3X\xff\xff\xff\xff\xe52D\xe0\xff\xff\xff\xff\xe5\xe1\x95X\xff\xff\xff\xff\xe7\x1ba`\xff\xff\xff\xff\xe7\xc1wX\xff\xff\xff\xff\xe8\xfbC`\xff\xff\xff\xff\xe9\xa1Y" +
- "X\xff\xff\xff\xff\xea\xdb%`\xff\xff\xff\xff\xeb\x8au\xd8\xff\xff\xff\xff\xec\xbb\a`\xff\xff\xff\xff\xedjW\xd8\xff\xff\xff\xff\xee\x9a\xe9`\xff\xff\xff\xff\xefJ9\xd8\xff\xff\xff\xff\xf0\x84\x05\xe0\xff\xff\xff" +
- "\xff\xf1*\x1b\xd8\xff\xff\xff\xff\xf2c\xe7\xe0\xff\xff\xff\xff\xf3\t\xfd\xd8\xff\xff\xff\xff\xf4C\xc9\xe0\xff\xff\xff\xff\xf4\xe9\xdf\xd8\xff\xff\xff\xff\xf6#\xab\xe0\xff\xff\xff\xff\xf6\xd2\xfcX\xff\xff\xff\xff\xf8\x03\x8d" +
- "\xe0\xff\xff\xff\xff\xf8\xb2\xdeX\xff\xff\xff\xff\xf9\xe3o\xe0\xff\xff\xff\xff\xfa\x92\xc0X\xff\xff\xff\xff\xfb̌`\xff\xff\xff\xff\xfcr\xa2X\x00\x00\x00\x00\ab\xdb`\x00\x00\x00\x00\a\xb9\xd0P\x00\x00\x00" +
- "\x00\x18aq`\x00\x00\x00\x00\x18\xab7P\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\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\x05\x02\x05\x02\xff\xff\xadP\x00\x00\xff\xff\xb2" +
- "\xa8\x01\x04\xff\xff\xab\xa0\x00\n\xff\xff\xb9\xb0\x01\x0e\xff\xff\xb9\xb0\x01\x12\xff\xff\xb9\xb0\x01\x16LMT\x00-0530\x00CST\x00CWT\x00CPT\x00CDT\x00\nCST6\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x14\x00\x00\x00America/Blanc-SablonTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01" +
- "\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\xf8Dz\x97\xae\x01\x00\x00\xae\x01\x00\x00\x11\x00\x00\x00America/Boa_VistaTZif2\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\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x7f\xe0\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff" +
- "\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0" +
- "\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff" +
- "\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ" +
- "\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x930\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x009\xe9\x1d\xb0\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\xff\xff\xc7 \x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,g\xec" +
- "\xec\xb3\x00\x00\x00\xb3\x00\x00\x00\x0e\x00\x00\x00America/BogotaTZif2\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\x04\x00\x00\x00\x04\x00\x00" +
- "\x00\x10\xff\xff\xff\xff^\x9c4\xf0\xff\xff\xff\xff\x98XUp\x00\x00\x00\x00*\x03sP\x00\x00\x00\x00+t\x89@\x01\x03\x02\x03\xff\xff\xba\x90\x00\x00\xff\xff\xba\x90\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0" +
- "\x00\fLMT\x00BMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\xbe\x1a>\xe7\x03\x00\x00\xe7\x03\x00\x00\r\x00\x00\x00Amer" +
- "ica/BoiseTZif2\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\x00" +
- "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\x00Z\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x04\x1a\xc0\xff\xff\xff\xff\x9e\xa6H\xa0" +
- "\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xff\xa8FL \xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff" +
- "\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00" +
- "\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\xb2\x1f\x90\x00\x00\x00\x00" +
- "\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10" +
- "\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00" +
- "\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80" +
- "\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00" +
- "%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90" +
- "\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x00" +
- "3Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00" +
- "\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00" +
- "A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x05\x03\x04\x05\x06\x05\x06\x05\x06\x05\x06" +
- "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" +
- "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\x93\x0f\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\x9d\x90\x00\x14\xff\xff\xab\xa0\x01\x18LMT\x00" +
- "PDT\x00PST\x00MWT\x00MPT\x00MST\x00MDT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x14\x00\x00\x00America/Buenos_AiresTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xa8L\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p" +
- "0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff" +
- "\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7" +
- "\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff" +
- "\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd3" +
- "0\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00" +
- "\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X" +
- "\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00" +
- "\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc94\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLM" +
- "T\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\xba\xb2\x94s\x03\x00\x00s\x03\x00\x00\x15\x00\x00\x00Amer" +
- "ica/Cambridge_BayTZif2\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\x00L\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff\xa1\xf2̀" +
- "\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00" +
- "\b ݐ\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xbf\x90\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00" +
- "\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00" +
- "\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90" +
- "\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00" +
- "$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00" +
- "\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x00" +
- "2s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00" +
- "\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\x04\xe9P\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00" +
- "?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10" +
- "\x03\x01\x02\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\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\x06" +
- "\x05\a\x06\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x00\x00\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90\x00\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18\xff\xff" +
- "\xb9\xb0\x00\x1c-00\x00MWT\x00MPT\x00MST\x00MDT\x00CDT\x00CST\x00EST\x00\nMST7MDT,M3.2.0,M11.1.0\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xfbn۸\x03\x00\x00\xb8\x03\x00\x00\x14\x00\x00\x00America/Campo_GrandeTZif2\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\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaaz4\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff" +
- "\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ" +
- "@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff" +
- "\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3\xdd" +
- "\xb0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00#X\x1e\xc0\x00\x00\x00\x00#\xe2~0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xd4\xd50\x00\x00\x00\x00'!\x1d@\x00\x00\x00" +
- "\x00'\xbd\xf1\xb0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\x94\x990\x00\x00\x00\x00*\xea\x1b\xc0\x00\x00\x00\x00+k@\xb0\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\x00\x00\x00\x00.\xa0\xa5" +
- "@\x00\x00\x00\x00/F\xb40\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001\x1d[\xb0\x00\x00\x00\x002W.\xc0\x00\x00\x00\x003\x06x0\x00\x00\x00\x0048b@\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00" +
- "\x006 -@\x00\x00\x00\x006\xcfv\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x930\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x00:\x8f:\xb0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<o\x1c" +
- "\xb0\x00\x00\x00\x00=ğ@\x00\x00\x00\x00>N\xfe\xb0\x00\x00\x00\x00?\x92\f@\x00\x00\x00\x00@.\xe0\xb0\x00\x00\x00\x00A\x87\x06@\x00\x00\x00\x00B\x17\xfd0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00" +
- "\x00C\xf7\xdf0\x00\x00\x00\x00EMa\xc0\x00\x00\x00\x00E\xe0\xfb\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xb7\xa30\x00\x00\x00\x00H\xfa\xb0\xc0\x00\x00\x00\x00I\x97\x850\x00\x00\x00\x00Jڒ" +
- "\xc0\x00\x00\x00\x00K\x80\xa1\xb0\x00\x00\x00\x00L\xbat\xc0\x00\x00\x00\x00M`\x83\xb0\x00\x00\x00\x00N\x9aV\xc0\x00\x00\x00\x00OI\xa00\x00\x00\x00\x00P\x83s@\x00\x00\x00\x00Q G\xb0\x00\x00\x00" +
- "\x00RcU@\x00\x00\x00\x00S\x00)\xb0\x00\x00\x00\x00TC7@\x00\x00\x00\x00T\xe9F0\x00\x00\x00\x00V#\x19@\x00\x00\x00\x00V\xc9(0\x00\x00\x00\x00X\x02\xfb@\x00\x00\x00\x00X\xa9\n" +
- "0\x00\x00\x00\x00Y\xe2\xdd@\x00\x00\x00\x00Z\x88\xec0\x00\x00\x00\x00[\xden\xc0\x00\x00\x00\x00\\h\xce0\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\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\xff\xff\xcc\xcc\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x04\xde\xdd" +
- "\x11\x02\x00\x00\x11\x02\x00\x00\x0e\x00\x00\x00America/CancunTZif2\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\x05\x00\x00\x00" +
- "\x14\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\x16\x86\xd5`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00" +
- "\x005\xc4\x00`\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2" +
- "\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00" +
- "\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e" +
- "\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00" +
- "\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00T\xcd\xdd\x00\x01\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" +
- "\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\xff\xff\xae\xa8\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10LMT\x00CST\x00EDT" +
- "\x00EST\x00CDT\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x8e\xee\x13\xbe\x00\x00\x00\xbe\x00\x00\x00\x0f\x00\x00\x00America/Caracas" +
- "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\x05\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffi\x87\x1a@\xff\xff\xff\xff\x93\x1e,<\xff\xff\xff\xff\xf6\x98\xecH\x00" +
- "\x00\x00\x00G[\x92p\x00\x00\x00\x00W%\xa9p\x01\x02\x03\x02\x03\xff\xff\xc1@\x00\x00\xff\xff\xc1D\x00\x04\xff\xff\xc0\xb8\x00\b\xff\xff\xc7\xc0\x00\x0eLMT\x00CMT\x00-0430\x00-0" +
- "4\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00\x11\x00\x00\x00America/CatamarcaTZi" +
- "f2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff" +
- "\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0" +
- "\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff" +
- "\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0" +
- "\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff" +
- "\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@" +
- "\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00" +
- "%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư" +
- "\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\v\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff" +
- "\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1" +
- "'\a\xbd\x97\x00\x00\x00\x97\x00\x00\x00\x0f\x00\x00\x00America/CayenneTZif2\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\x02\x00\x00\x00" +
- "\x03\x00\x00\x00\f\xff\xff\xff\xff\x91\xf4+\x90\xff\xff\xff\xff\xfb\xc35\xc0\x01\x02\xff\xff\xce\xf0\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\bLMT\x00-04\x00-03\x00\n<-03>3" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x00\x00America/CaymanTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00" +
- "CMT\x00EST\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9bܩ=\xda\x06\x00\x00\xda\x06\x00\x00\x0f\x00\x00\x00America/ChicagoT" +
- "Zif2\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\xaf\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff" +
- "\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa2\xcbt\x00\xff\xff\xff\xff\xa3\x83\xf7\xf0\xff\xff\xff\xff\xa4EҀ\xff\xff\xff\xff\xa5c\xd9\xf0\xff\xff\xff\xff\xa6S\xd9\x00\xff\xff\xff\xff\xa7\x15" +
- "\x97p\xff\xff\xff\xff\xa83\xbb\x00\xff\xff\xff\xff\xa8\xfe\xb3\xf0\xff\xff\xff\xff\xaa\x13\x9d\x00\xff\xff\xff\xff\xaaޕ\xf0\xff\xff\xff\xff\xab\xf3\x7f\x00\xff\xff\xff\xff\xac\xbew\xf0\xff\xff\xff\xff\xad\xd3a\x00\xff\xff" +
- "\xff\xff\xae\x9eY\xf0\xff\xff\xff\xff\xaf\xb3C\x00\xff\xff\xff\xff\xb0~;\xf0\xff\xff\xff\xff\xb1\x9c_\x80\xff\xff\xff\xff\xb2gXp\xff\xff\xff\xff\xb3|A\x80\xff\xff\xff\xff\xb4G:p\xff\xff\xff\xff\xb5\\" +
- "#\x80\xff\xff\xff\xff\xb6'\x1cp\xff\xff\xff\xff\xb7<\x05\x80\xff\xff\xff\xff\xb8\x06\xfep\xff\xff\xff\xff\xb9\x1b\xe7\x80\xff\xff\xff\xff\xb9\xe6\xe0p\xff\xff\xff\xff\xbb\x05\x04\x00\xff\xff\xff\xff\xbb\xc6\xc2p\xff\xff" +
- "\xff\xff\xbc\xe4\xe6\x00\xff\xff\xff\xff\xbd\xaf\xde\xf0\xff\xff\xff\xff\xbe\xc4\xc8\x00\xff\xff\xff\xff\xbf\x8f\xc0\xf0\xff\xff\xff\xff\xc0Z\xd6\x00\xff\xff\xff\xff\xc1\xb0<p\xff\xff\xff\xff\u0084\x8c\x00\xff\xff\xff\xff\xc3O" +
- "\x84\xf0\xff\xff\xff\xff\xc4dn\x00\xff\xff\xff\xff\xc5/f\xf0\xff\xff\xff\xff\xc6M\x8a\x80\xff\xff\xff\xff\xc7\x0fH\xf0\xff\xff\xff\xff\xc8-l\x80\xff\xff\xff\xff\xc8\xf8ep\xff\xff\xff\xff\xca\rN\x80\xff\xff" +
- "\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 " +
- "\xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff" +
- "\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^" +
- "\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff" +
- "\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf2\x7f" +
- "\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xf6?ip\xff\xff\xff\xff\xf7/h\x80\xff\xff\xff\xff\xf8(\x85\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff" +
- "\xff\xff\xfa\bg\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98" +
- "\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00" +
- "\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9" +
- "\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00" +
- "\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1" +
- "\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00" +
- "\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xea" +
- "E\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00" +
- "\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6" +
- "\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00" +
- "\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\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\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xad\xd4\x00\x00\xff\xff\xb9\xb0\x01" +
- "\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00CDT\x00CST\x00EST\x00CWT\x00CPT\x00\nCST6CDT,M3" +
- ".2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x111\x04q\xb3\x02\x00\x00\xb3\x02\x00\x00\x11\x00\x00\x00America/Chihuahua" +
- "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\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff" +
- "\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005" +
- "'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00" +
- "\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00C" +
- "d}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00" +
- "\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\"\x00\x00\x00\x00\x00M\x987\x10\x00\x00\x00\x00N\xad\x04\x00\x00\x00\x00\x00Ox\x19\x10\x00\x00\x00\x00P\x8c\xe6\x00\x00\x00\x00\x00Q" +
- "a5\x90\x00\x00\x00\x00Rl\xc8\x00\x00\x00\x00\x00SA\x17\x90\x00\x00\x00\x00TL\xaa\x00\x00\x00\x00\x00U \xf9\x90\x00\x00\x00\x00V,\x8c\x00\x00\x00\x00\x00W\x00ې\x00\x00\x00\x00X\x15\xa8\x80\x00" +
- "\x00\x00\x00Xཐ\x00\x00\x00\x00Y\xf5\x8a\x80\x00\x00\x00\x00Z\xc0\x9f\x90\x00\x00\x00\x00[\xd5l\x80\x00\x00\x00\x00\\\xa9\xbc\x10\x00\x00\x00\x00]\xb5N\x80\x00\x00\x00\x00^\x89\x9e\x10\x00\x00\x00\x00_" +
- "\x950\x80\x00\x00\x00\x00`i\x80\x10\x00\x00\x00\x00a~M\x00\x00\x00\x00\x00bIb\x10\x00\x00\x00\x00c^/\x00\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03" +
- "\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x02\xff\xff\x9c\x8c\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff" +
- "\xff\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00MDT\x00CDT\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\xf2L\x06\xce\x02\x00\x00\xce\x02\x00\x00\x15\x00\x00" +
- "\x00America/Ciudad_JuarezTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff" +
- "\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\b" +
- "p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00" +
- "\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce" +
- "\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00" +
- "\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>" +
- "\x80\x00\x00\x00\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q<K\x90\x00\x00\x00\x00Rv\x02\x80\x00\x00\x00\x00S\x1c-\x90\x00\x00\x00\x00TU\xe4\x80\x00\x00\x00\x00T\xfc\x0f\x90\x00\x00\x00" +
- "\x00V5ƀ\x00\x00\x00\x00V\xe5,\x10\x00\x00\x00\x00X\x1e\xe3\x00\x00\x00\x00\x00X\xc5\x0e\x10\x00\x00\x00\x00Y\xfe\xc5\x00\x00\x00\x00\x00Z\xa4\xf0\x10\x00\x00\x00\x00[ާ\x00\x00\x00\x00\x00\\\x84\xd2" +
- "\x10\x00\x00\x00\x00]\xbe\x89\x00\x00\x00\x00\x00^d\xb4\x10\x00\x00\x00\x00_\x9ek\x00\x00\x00\x00\x00`MА\x00\x00\x00\x00a\x87\x87\x80\x00\x00\x00\x00b-\xb2\x90\x00\x00\x00\x00c^/\x00\x00\x00\x00" +
- "\x00c\x86\xf1`\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03" +
- "\x01\x03\x01\x03\x02\x01\xff\xff\x9c,\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00MDT\x00CDT\x00\nMST" +
- "7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x15\x00\x00\x00America/Co" +
- "ral_HarbourTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4" +
- "a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00CMT\x00EST\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02" +
- "\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00America/CordobaTZif2\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\x06\x00\x00\x00\x14" +
- "\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff" +
- "\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@" +
- "\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff" +
- "ȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0" +
- "\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff" +
- "\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0" +
- "\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00" +
- ")\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0" +
- "\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04" +
- "\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03" +
- "\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1݂x\xe8\x00\x00\x00\xe8\x00\x00\x00\x12\x00\x00\x00America/Costa_Ric" +
- "aTZif2\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\n\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffi\x87*M\xff\xff\xff\xff\xa3\xe8\x16M\x00\x00\x00\x00\x116I`" +
- "\x00\x00\x00\x00\x11\xb7nP\x00\x00\x00\x00\x13\x16+`\x00\x00\x00\x00\x13\x97PP\x00\x00\x00\x00'\x97\xe0`\x00\x00\x00\x00(n\xb6\xd0\x00\x00\x00\x00)w\xc2`\x00\x00\x00\x00)\xc2\xd9\xd0\x01\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\xff\xff\xb13\x00\x00\xff\xff\xb13\x00\x04\xff\xff\xb9\xb0\x01\t\xff\xff\xab\xa0\x00\rLMT\x00SJMT\x00CDT\x00CST\x00\nCST6\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00ø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x00\x00America/CrestonTZif2\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\v\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f" +
- "\x90\xff\xff\xff\xff\xcf\x17\xdf\x1c\xff\xff\xff\xffϏ\xe5\xac\xff\xff\xff\xffЁ\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96\xee\x00\x00\xff\xff" +
- "\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\fLMT\x00MDT\x00MST\x00MWT\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f$*\xa0\xa6\x03\x00\x00" +
- "\xa6\x03\x00\x00\x0e\x00\x00\x00America/CuiabaTZif2\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\x00Y\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff" +
- "\xff\x96\xaa{\x94\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef" +
- "\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff" +
- "\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b" +
- "\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00#X\x1e\xc0\x00\x00\x00" +
- "\x00#\xe2~0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xd4\xd50\x00\x00\x00\x00'!\x1d@\x00\x00\x00\x00'\xbd\xf1\xb0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\x94\x990\x00\x00\x00\x00*\xea\x1b" +
- "\xc0\x00\x00\x00\x00+k@\xb0\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\x00\x00\x00\x00.\xa0\xa5@\x00\x00\x00\x00/F\xb40\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001\x1d[\xb0\x00\x00\x00" +
- "\x002W.\xc0\x00\x00\x00\x003\x06x0\x00\x00\x00\x0048b@\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x006 -@\x00\x00\x00\x006\xcfv\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x93" +
- "0\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x00:\x8f:\xb0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<o\x1c\xb0\x00\x00\x00\x00=ğ@\x00\x00\x00\x00>N\xfe\xb0\x00\x00\x00\x00A\x87\x06@\x00\x00\x00" +
- "\x00B\x17\xfd0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00C\xf7\xdf0\x00\x00\x00\x00EMa\xc0\x00\x00\x00\x00E\xe0\xfb\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xb7\xa30\x00\x00\x00\x00H\xfa\xb0" +
- "\xc0\x00\x00\x00\x00I\x97\x850\x00\x00\x00\x00Jڒ\xc0\x00\x00\x00\x00K\x80\xa1\xb0\x00\x00\x00\x00L\xbat\xc0\x00\x00\x00\x00M`\x83\xb0\x00\x00\x00\x00N\x9aV\xc0\x00\x00\x00\x00OI\xa00\x00\x00\x00" +
- "\x00P\x83s@\x00\x00\x00\x00Q G\xb0\x00\x00\x00\x00RcU@\x00\x00\x00\x00S\x00)\xb0\x00\x00\x00\x00TC7@\x00\x00\x00\x00T\xe9F0\x00\x00\x00\x00V#\x19@\x00\x00\x00\x00V\xc9(" +
- "0\x00\x00\x00\x00X\x02\xfb@\x00\x00\x00\x00X\xa9\n0\x00\x00\x00\x00Y\xe2\xdd@\x00\x00\x00\x00Z\x88\xec0\x00\x00\x00\x00[\xden\xc0\x00\x00\x00\x00\\h\xce0\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\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\xff\xff\xcbl\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America/CuracaoTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff" +
- "\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xc2\rx\xbf\x01\x00\x00" +
- "\xbf\x01\x00\x00\x14\x00\x00\x00America/DanmarkshavnTZif2\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\x10\xff\xff\xff\xff\x9b\x80I\x00\x00\x00\x00\x00\x13M|P\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00" +
- "\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-" +
- "\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x000\xe7N0\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\x03\xff\xff\xee\x80\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\b\x00\x00\x00\x00\x00\fLMT\x00-03\x00-02\x00GMT\x00\nGMT0\nPK\x03\x04\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xe6\xf5J\x05\x04\x00\x00\x05\x04\x00\x00\x0e\x00\x00\x00America/DawsonTZif2\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\t\x00\x00\x00%\xff\xff\xff\xff}\x86\x8e\xb4\xff\xff\xff\xff\x9e\xb8˰\xff\xff\xff\xff\x9f\xbb#\xa0\xff\xff\xff\xff\xa0\xd0\f\xb0\xff\xff\xff\xff\xa1\xa2Ҁ\xff\xff\xff\xffˉ" +
- "(\xb0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00" +
- "\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2" +
- "\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00" +
- "\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xde" +
- "Ϡ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00" +
- "\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c" +
- "\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00" +
- "\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3" +
- "\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00" +
- "\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU" +
- "\xf2\x90\x00\x00\x00\x00T\xfc\x1d\xa0\x00\x00\x00\x00V5Ԑ\x00\x00\x00\x00V\xe5: \x00\x00\x00\x00X\x1e\xf1\x10\x00\x00\x00\x00X\xc5\x1c \x00\x00\x00\x00Y\xfe\xd3\x10\x00\x00\x00\x00Z\xa4\xfe \x00\x00" +
- "\x00\x00[\u07b5\x10\x00\x00\x00\x00\\\x84\xe0 \x00\x00\x00\x00]\xbe\x97\x10\x00\x00\x00\x00^d\xc2 \x00\x00\x00\x00_\x9e\\\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x02\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" +
- "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" +
- "\x06\a\x06\a\x06\a\x06\a\x06\a\b\xff\xff}L\x00\x00\xff\xff\x8f\x80\x01\x04\xff\xff\x81p\x00\b\xff\xff\x8f\x80\x01\f\xff\xff\x8f\x80\x01\x10\xff\xff\x9d\x90\x01\x14\xff\xff\x8f\x80\x00\x19\xff\xff\x9d\x90\x01\x1d\xff" +
- "\xff\x9d\x90\x00!LMT\x00YDT\x00YST\x00YWT\x00YPT\x00YDDT\x00PST\x00PDT\x00MST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00+\x10`ȫ\x02\x00\x00\xab\x02\x00\x00\x14\x00\x00\x00America/Dawson_CreekTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff^=t8\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&" +
- "\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfeѠ\xff\xff\xff" +
- "\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\u07b3\xa0\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x95\xa0\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y" +
- "\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff" +
- "\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb" +
- "\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff" +
- "\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G" +
- " \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05\x01\xf0\x90\x02\x01\x02" +
- "\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\x02\x01\x05\xff\xff\x8fH\x00" +
- "\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x00\x14LMT\x00PDT\x00PST\x00PWT\x00PPT\x00MST\x00\nMST7" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x0e\x00\x00\x00America/DenverTZif2\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\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80" +
- "\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff" +
- "\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00" +
- "\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00" +
- "\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ" +
- "\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00" +
- "\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80" +
- "\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00" +
- "!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ" +
- "\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00" +
- "/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ" +
- "\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00" +
- "=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90" +
- "\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\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\xff\xff\x9d\x94\x00\x00\xff" +
- "\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M" +
- "11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\x0f\x00\x00\x00America/DetroitTZif2\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\x00P\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x85\xbd\"[\xff\xff\xff\xff\x99<\x94\x00\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff" +
- "\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xfb3\x90\x8c\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\x00\x00\x00\x00\x06" +
- "@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00" +
- "\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14" +
- "Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00" +
- "\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"" +
- "U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00" +
- "\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000" +
- "\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00" +
- "\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>" +
- "\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00" +
- "\x00\x00\x00E\xf3\xa8\xf0\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" +
- "\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\xff\xff\xb2%\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10\xff\xff\xc7" +
- "\xc0\x01\x14LMT\x00CST\x00EST\x00EWT\x00EPT\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00America/DominicaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04" +
- "\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\a\a\xdc\xca\x03\x00\x00\xca\x03\x00\x00" +
- "\x10\x00\x00\x00America/EdmontonTZif2\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\x00Y\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x88" +
- "\xde\xce\xe0\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x98\x91\x90\xff\xff\xff\xff\xa0҅\x80\xff\xff\xff\xff\xa2\x8a\xe8\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4jʐ\xff" +
- "\xff\xff\xff\xa55À\xff\xff\xff\xff\xa6S\xe7\x10\xff\xff\xff\xff\xa7\x15\xa5\x80\xff\xff\xff\xff\xa83\xc9\x10\xff\xff\xff\xff\xa8\xfe\xc2\x00\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2" +
- "a\x18\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b ݐ\x00" +
- "\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xbf\x90\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f" +
- "\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00" +
- "\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d" +
- "\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00" +
- "\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+" +
- "\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00" +
- "\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009" +
- "\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00" +
- "\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
- "\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\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x95\xa0\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MW" +
- "T\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\xb0\xeau\xb4\x01\x00\x00\xb4\x01\x00\x00\x10\x00\x00\x00" +
- "America/EirunepeTZif2\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\f\xff\xff\xff\xff\x96\xaa\x88\x80\xff" +
- "\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xff\xdc" +
- "\xb9u@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff" +
- "\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1d" +
- "ɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00,\xc0\xd1P\x00\x00\x00\x00-f\xe0@\x00" +
- "\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\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\x03\x02\xff\xff\xbe\x80\x00\x00\xff\xff\xc7\xc0\x01\x04" +
- "\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea$\xc1\xbf\xb0\x00\x00\x00\xb0\x00\x00\x00\x13\x00" +
- "\x00\x00America/El_SalvadorTZif2\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\x05\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff" +
- "\xa3զ \x00\x00\x00\x00 \x9a\xdc\xe0\x00\x00\x00\x00!\\\x9bP\x00\x00\x00\x00\"z\xbe\xe0\x00\x00\x00\x00#<}P\x02\x01\x02\x01\x02\xff\xff\xac`\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bL" +
- "MT\x00CDT\x00CST\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x00\x00America/Ensen" +
- "adaTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2" +
- "|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\n\xf2\xf0\xff\xff\xff\xff\xcbꍀ\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xffҙ\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff" +
- "\xff\xffؑ\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8'" +
- ",\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00" +
- "\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12y" +
- "s\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00" +
- "\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v" +
- "+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00" +
- "\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3" +
- "`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00" +
- "\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0" +
- "\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00" +
- "\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4" +
- "\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80" +
- "\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00PST\x00PDT\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0," +
- "M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6@\rm\xa8\x05\x00\x00\xa8\x05\x00\x00\x13\x00\x00\x00America/Fort_NelsonTZi" +
- "f2\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\x8f\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^=v\x87\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff" +
- "ˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 " +
- "\xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfeѠ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\u07b3\xa0\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x95\xa0\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff" +
- "\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10" +
- "\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff" +
- "\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0" +
- "\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff" +
- "\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90" +
- "\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\b \xeb\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\n\x00͠\x00\x00\x00\x00" +
- "\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 " +
- "\x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00" +
- "\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې" +
- "\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00" +
- "'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0" +
- "\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x00" +
- "5'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10" +
- "\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00" +
- "Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 " +
- "\x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00" +
- "Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90\x00\x00\x00\x00T\xfc\x1d\xa0\x02\x01\x02\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\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\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\x05\xff" +
- "\xff\x8c\xf9\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x00\x14LMT\x00PDT\x00PST\x00PWT\x00PPT\x00MST\x00\n" +
- "MST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x12\x00\x00\x00America/Fort_WayneTZif2\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\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80" +
- "\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcaW\"\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff" +
- "\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80" +
- "\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff" +
- "\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0" +
- "\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
- "\x05\x02\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00" +
- "CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x11" +
- "Z\xde\xe4\x01\x00\x00\xe4\x01\x00\x00\x11\x00\x00\x00America/FortalezaTZif2\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\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaak\x18\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb" +
- "\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff" +
- "\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec" +
- "\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00" +
- "\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x009\xf2" +
- "J \x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\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\xff\xff\xdb" +
- "\xe8\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M\x94\xc7Kp\x03\x00\x00p\x03\x00" +
- "\x00\x11\x00\x00\x00America/Glace_BayTZif2\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\x00O\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff" +
- "\xff\x80\xf1\xa84\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xffˈ\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8" +
- "P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\a0\xb4P\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00" +
- "\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W" +
- "\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00" +
- "\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3" +
- "P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00" +
- "\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[" +
- "`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00" +
- "\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې" +
- "\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00" +
- "\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01\x02\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xc7\xcc\x00\x00\xff\xff\xd5\xd0\x01\x04" +
- "\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00ADT\x00AST\x00AWT\x00APT\x00\nAST4ADT,M3.2.0,M11.1." +
- "0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95'O\xce\xc5\x03\x00\x00\xc5\x03\x00\x00\x0f\x00\x00\x00America/GodthabTZif3\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\x00Y\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\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#<E\x10\x00\x00\x00\x00$," +
- "6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00" +
- "\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r" +
- "\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00" +
- "\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f" +
- "#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00" +
- "\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac" +
- "\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00" +
- "\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0" +
- "\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\x7f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00" +
- "\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\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\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\x03\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01" +
- "\b\xff\xff\xe3\xe0\x00\bLMT\x00-03\x00-02\x00\n<-02>2<-01>,M3.5.0/-1,M10.5.0/0\nPK\x03\x04\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x1d\xf7\a ,\x06\x00\x00,\x06\x00\x00\x11\x00\x00\x00America/Goose_BayTZif2\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\x98\x00\x00\x00\n\x00\x00\x00!\xff\xff\xff\xff^=<$\xff\xff\xff\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xbe\x9eMl\xff\xff\xff\xff\xc0\xb818\xff\xff\xff\xff\xc1y" +
- "\xef\xa8\xff\xff\xff\xff\u0098\x138\xff\xff\xff\xff\xc3YѨ\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff\xff\xc8@\xf3\xb8\xff\xff" +
- "\xff\xff\xc9\x02\xb2(\xff\xff\xff\xff\xca ո\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xffӈD\xd8\xff\xff\xff\xff\xd4J" +
- "\x03H\xff\xff\xff\xff\xd5h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\b\xd8\xff\xff\xff\xff\xd8\t\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff\xff\xdb\x11\aX\xff\xff" +
- "\xff\xff\xdb\xd2\xc5\xc8\xff\xff\xff\xff\xdc\xdetX\xff\xff\xff\xffݩmH\xff\xff\xff\xff\u07beVX\xff\xff\xff\xff߉OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1i1H\xff\xff\xff\xff\xe2~" +
- "\x1aX\xff\xff\xff\xff\xe3I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff\xff\xe8\xf1\xf3\xc8\xff\xff" +
- "\xff\xff\xea\x06\xdc\xd8\xff\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff챷\xc8\xff\xff\xff\xff\xedƠ\xd8\xff\xff\xff\xff\ueffeH\xff\xff\xff\xffﯽX\xff\xff\xff\xff\xf0\x9f" +
- "\xa0H\xff\xff\xff\xff\xf1\x8f\x9fX\xff\xff\xff\xff\xf2\x7f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff\xff\xff\xff\xf7/EX\xff\xff" +
- "\xff\xff\xf8(b\xc8\xff\xff\xff\xff\xf8\xdakX\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8" +
- "\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00" +
- "\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\a0\xb4P\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0" +
- "w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00" +
- "\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01" +
- "\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xd6\xfc\x00\x00" +
- "\x00\x00!\x81il\x00\x00\x00\x00\"U\xb8\xfc\x00\x00\x00\x00#jw\xdc\x00\x00\x00\x00$5\x9a\xfc\x00\x00\x00\x00%Jg\xec\x00\x00\x00\x00&\x15|\xfc\x00\x00\x00\x00'*I\xec\x00\x00\x00\x00'\xfe" +
- "\x99|\x00\x00\x00\x00)\n+\xec\x00\x00\x00\x00)\xde{|\x00\x00\x00\x00*\xea\r\xec\x00\x00\x00\x00+\xbe]|\x00\x00\x00\x00,\xd3*l\x00\x00\x00\x00-\x9e?|\x00\x00\x00\x00.\xb3\fl\x00\x00" +
- "\x00\x00/~!|\x00\x00\x00\x000\x92\xeel\x00\x00\x00\x001g=\xfc\x00\x00\x00\x002r\xd0l\x00\x00\x00\x003G\x1f\xfc\x00\x00\x00\x004R\xb2l\x00\x00\x00\x005'\x01\xfc\x00\x00\x00\x0062" +
- "\x94l\x00\x00\x00\x007\x06\xe3\xfc\x00\x00\x00\x008\x1b\xb0\xec\x00\x00\x00\x008\xe6\xc5\xfc\x00\x00\x00\x009\xfb\x92\xec\x00\x00\x00\x00:Ƨ\xfc\x00\x00\x00\x00;\xdbt\xec\x00\x00\x00\x00<\xaf\xc4|\x00\x00" +
- "\x00\x00=\xbbV\xec\x00\x00\x00\x00>\x8f\xa6|\x00\x00\x00\x00?\x9b8\xec\x00\x00\x00\x00@o\x88|\x00\x00\x00\x00A\x84Ul\x00\x00\x00\x00BOj|\x00\x00\x00\x00Cd7l\x00\x00\x00\x00D/" +
- "L|\x00\x00\x00\x00ED\x19l\x00\x00\x00\x00E\xf3~\xfc\x00\x00\x00\x00G-5\xec\x00\x00\x00\x00G\xd3`\xfc\x00\x00\x00\x00I\r\x17\xec\x00\x00\x00\x00I\xb3B\xfc\x00\x00\x00\x00J\xec\xf9\xec\x00\x00" +
- "\x00\x00K\x9c_|\x00\x00\x00\x00L\xd6\x16l\x00\x00\x00\x00M|A|\x00\x00\x00\x00N\xb6\x14P\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b" +
- "\a\b\a\b\a\b\a\b\a\b\a\b\a\b\t\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b" +
- "\a\b\xff\xff\xc7\\\x00\x00\xff\xffΔ\x00\x04\xff\xffܤ\x01\b\xff\xff\xce\xc8\x00\x04\xff\xff\xdc\xd8\x01\b\xff\xff\xdc\xd8\x01\f\xff\xff\xdc\xd8\x01\x10\xff\xff\xd5\xd0\x01\x14\xff\xff\xc7\xc0\x00\x18\xff\xff\xe3\xe0" +
- "\x01\x1cLMT\x00NST\x00NDT\x00NPT\x00NWT\x00ADT\x00AST\x00ADDT\x00\nAST4ADT,M3.2.0,M11.1.0\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xc9I\xd0U\x03\x00\x00U\x03\x00\x00\x12\x00\x00\x00America/Grand_TurkTZif2\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\x00L\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1e0\xff\xff\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13i" +
- "G\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00" +
- "\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81" +
- "\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00" +
- "\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~" +
- "Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00" +
- "\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb" +
- "\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00" +
- "\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00Gӊ\xf0\x00\x00\x00\x00I\rA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c" +
- "\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\"`\x00\x00\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q</p\x00\x00\x00\x00Ru\xe6`\x00\x00" +
- "\x00\x00S\x1c\x11p\x00\x00\x00\x00TU\xc8`\x00\x00\x00\x00T\xfb\xf3p\x00\x00\x00\x00Z\xa4\xd3\xf0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x03\xff\xff\xbdP\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff" +
- "\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x00\x10LMT\x00KMT\x00EST\x00EDT\x00AST\x00\nEST5EDT,M3.2.0,M11.1.0\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America/GrenadaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a" +
- "\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;" +
- "\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00America/GuadeloupeTZif2\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\x04\x00\x00\x00" +
- "\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff" +
- "\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x8a\x83S\xd4\x00\x00\x00\xd4\x00\x00\x00\x11\x00\x00\x00Ame" +
- "rica/GuatemalaTZif2\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\t\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9f\x9d\xea\xdc\x00\x00\x00" +
- "\x00\aU\xac`\x00\x00\x00\x00\a͖\xd0\x00\x00\x00\x00\x19,x`\x00\x00\x00\x00\x19\xcf\xe4P\x00\x00\x00\x00'\xea\xee\xe0\x00\x00\x00\x00(\xc8\\\xd0\x00\x00\x00\x00DTR`\x00\x00\x00\x00E\x1fK" +
- "P\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xab$\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00CDT\x00CST\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\xcd\xc3v\xe3\xb3\x00\x00\x00\xb3\x00\x00\x00\x11\x00\x00\x00America/GuayaquilTZif2\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\x04" +
- "\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87&X\xff\xff\xff\xff\xb6\xa4B\x18\x00\x00\x00\x00+\x16\xfc\xd0\x00\x00\x00\x00+q\xe6@\x01\x03\x02\x03\xff\xff\xb5(\x00\x00\xff\xff\xb6h\x00\x04\xff\xff\xc7\xc0" +
- "\x01\b\xff\xff\xb9\xb0\x00\fLMT\x00QMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x05\xf3\x89\xb5\x00\x00\x00\xb5\x00\x00\x00\x0e\x00" +
- "\x00\x00America/GuyanaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x92\x1d\x0f\x87\xff" +
- "\xff\xff\xff\x98\xd9{@\x00\x00\x00\x00\n\x7f\x05\xbc\x00\x00\x00\x00)\xd5@\xc0\x01\x02\x03\x01\xff\xff\xc9y\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xcbD\x00\b\xff\xff\xd5\xd0\x00\x0eLMT\x00-04\x00-" +
- "0345\x00-03\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x00\x00America/Halif" +
- "axTZif2\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\xa7\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x80\xf1\xab\xa0\xff\xff\xff\xff\x9a\xe4\xde\xc0\xff\xff\xff\xff\x9b\xd6\x13" +
- "0\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xff\xa2\x9d\x17@\xff\xff\xff\xff\xa30\xb10\xff\xff\xff\xff\xa4zV@\xff\xff\xff\xff\xa5\x1b\x1f0\xff\xff\xff\xff\xa6S\xa0\xc0\xff\xff\xff" +
- "\xff\xa6\xfcR\xb0\xff\xff\xff\xff\xa8<\xbd@\xff\xff\xff\xff\xa8\xdc4\xb0\xff\xff\xff\xff\xaa\x1c\x9f@\xff\xff\xff\xff\xaa\xcd:0\xff\xff\xff\xff\xab\xfc\x81@\xff\xff\xff\xff\xac\xbf\x910\xff\xff\xff\xff\xad\xee\xd8" +
- "@\xff\xff\xff\xff\xae\x8c\xfe0\xff\xff\xff\xff\xaf\xbcE@\xff\xff\xff\xff\xb0\x7fU0\xff\xff\xff\xff\xb1\xae\x9c@\xff\xff\xff\xff\xb2Kp\xb0\xff\xff\xff\xff\xb3\x8e~@\xff\xff\xff\xff\xb4$\xbb0\xff\xff\xff" +
- "\xff\xb5n`@\xff\xff\xff\xff\xb6\x15\xc0\xb0\xff\xff\xff\xff\xb7NB@\xff\xff\xff\xff\xb8\b\x17\xb0\xff\xff\xff\xff\xb9$\xe9\xc0\xff\xff\xff\xff\xb9\xe7\xf9\xb0\xff\xff\xff\xff\xbb\x04\xcb\xc0\xff\xff\xff\xff\xbb\xd1\x16" +
- "0\xff\xff\xff\xff\xbd\x00]@\xff\xff\xff\xff\xbd\x9d1\xb0\xff\xff\xff\xff\xbe\xf2\xb4@\xff\xff\xff\xff\xbf\x90\xda0\xff\xff\xff\xff\xc0\xd3\xe7\xc0\xff\xff\xff\xff\xc1^G0\xff\xff\xff\xff\u008d\x8e@\xff\xff\xff" +
- "\xff\xc3P\x9e0\xff\xff\xff\xff\xc4mp@\xff\xff\xff\xff\xc50\x800\xff\xff\xff\xff\xc6r<@\xff\xff\xff\xff\xc7\x10b0\xff\xff\xff\xff\xc86n\xc0\xff\xff\xff\xff\xc8\xf9~\xb0\xff\xff\xff\xff\xca\x16P" +
- "\xc0\xff\xff\xff\xff\xca\xd9`\xb0\xff\xff\xff\xffˈ\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xd3u\xd6\xe0\xff\xff\xff\xff\xd4@\xcf\xd0\xff\xff\xff\xff\xd5U\xb8\xe0\xff\xff\xff" +
- "\xff\xd6 \xb1\xd0\xff\xff\xff\xff\xd75\x9a\xe0\xff\xff\xff\xff\xd8\x00\x93\xd0\xff\xff\xff\xff\xd9\x15|\xe0\xff\xff\xff\xff\xd9\xe0u\xd0\xff\xff\xff\xff\xdc\xde{`\xff\xff\xff\xffݩtP\xff\xff\xff\xff\u07be]" +
- "`\xff\xff\xff\xff߉VP\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\xff\xff\xff\xff\xe2~!`\xff\xff\xff\xff\xe3I\x1aP\xff\xff\xff\xff\xe6G\x1f\xe0\xff\xff\xff\xff\xe7\x12\x18\xd0\xff\xff\xff" +
- "\xff\xe8'\x01\xe0\xff\xff\xff\xff\xe8\xf1\xfa\xd0\xff\xff\xff\xff\xea\x06\xe3\xe0\xff\xff\xff\xff\xea\xd1\xdc\xd0\xff\xff\xff\xff\xeb\xe6\xc5\xe0\xff\xff\xff\xff챾\xd0\xff\xff\xff\xff\xf1\x8f\xa6`\xff\xff\xff\xff\xf2\x7f\x89" +
- "P\xff\xff\xff\xff\xf3o\x88`\xff\xff\xff\xff\xf4_kP\xff\xff\xff\xff\xf5Oj`\xff\xff\xff\xff\xf6?MP\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(i\xd0\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff" +
- "\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0" +
- "\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\a0\xb4P\x00\x00\x00" +
- "\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v" +
- "\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00" +
- "\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde" +
- "`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00" +
- "\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea)" +
- "\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001gY\xe0\x00\x00\x00" +
- "\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1" +
- "\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00" +
- "\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xc4`\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff" +
- "\xd5\xd0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00ADT\x00AST\x00AWT\x00APT\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\a\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x0e\x00\x00\x00America/HavanaTZif2\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\x00j\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87(\xb8\xff\xff\xff\xff\xacb\u0080\xff\xff\xff\xff\xb1ӔP\xff\xff\xff\xff\xb2t]@\xff\xff\xff\xff\xc8[f\xd0\xff\xff\xff\xff\xc8\xd3Q" +
- "@\xff\xff\xff\xff\xca;H\xd0\xff\xff\xff\xffʼm\xc0\xff\xff\xff\xff\xcc$eP\xff\xff\xff\xff̜O\xc0\xff\xff\xff\xff\xd1\xc4\vP\xff\xff\xff\xff\xd2;\xf5\xc0\xff\xff\xff\xffӣ\xedP\xff\xff\xff" +
- "\xff\xd4\x1b\xd7\xc0\xff\xff\xff\xff\xf7`\x05\xd0\xff\xff\xff\xff\xf7\xff}@\xff\xff\xff\xff\xf9=D\xd0\xff\xff\xff\xff\xf9\xe3S\xc0\xff\xff\xff\xff\xfa\xdb;\xd0\xff\xff\xff\xff\xfb\xa7\x86@\xff\xff\xff\xff\xfcũ" +
- "\xd0\xff\xff\xff\xff\xfd\x87h@\xff\xff\xff\xff\xfe\xb8\x00\xd0\xff\xff\xff\xff\xff\xa7\xe3\xc0\x00\x00\x00\x00\x00\x97\xe2\xd0\x00\x00\x00\x00\x01\x87\xc5\xc0\x00\x00\x00\x00\x02w\xc4\xd0\x00\x00\x00\x00\x03p\xe2@\x00\x00\x00" +
- "\x00\x04`\xe1P\x00\x00\x00\x00\x055\x14\xc0\x00\x00\x00\x00\x06@\xc3P\x00\x00\x00\x00\a\x16H@\x00\x00\x00\x00\b \xa5P\x00\x00\x00\x00\b\xf7{\xc0\x00\x00\x00\x00\n\x00\x87P\x00\x00\x00\x00\n\xf0j" +
- "@\x00\x00\x00\x00\v\xe0iP\x00\x00\x00\x00\fن\xc0\x00\x00\x00\x00\r\xc0KP\x00\x00\x00\x00\x0e\xb9h\xc0\x00\x00\x00\x00\x0f\xb2\xa2P\x00\x00\x00\x00\x10}\x9b@\x00\x00\x00\x00\x11Q\xea\xd0\x00\x00\x00" +
- "\x00\x12f\xb7\xc0\x00\x00\x00\x00\x131\xcc\xd0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15[\x82\xd0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x17;d\xd0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x19\x1bF" +
- "\xd0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xfb(\xd0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\xdb\n\xd0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ezSP\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00" +
- "\x00 Z5P\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"CQ\xd0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$#3\xd0\x00\x00\x00\x00%.\xc6@\x00\x00\x00\x00&\x15\x8a\xd0\x00\x00\x00\x00'\x17\xe2" +
- "\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00(\xf7\xd2\xd0\x00\x00\x00\x00)މP\x00\x00\x00\x00*״\xd0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xb7\x96\xd0\x00\x00\x00\x00-\x9eMP\x00\x00\x00" +
- "\x00.\x97x\xd0\x00\x00\x00\x00/~/P\x00\x00\x00\x000wZ\xd0\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002W<\xd0\x00\x00\x00\x003G-\xd0\x00\x00\x00\x004@YP\x00\x00\x00\x005\x1d\xd5" +
- "P\x00\x00\x00\x0062\xb0P\x00\x00\x00\x006\xfd\xb7P\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:Ƶ\xd0\x00\x00\x00\x00;ې\xd0\x00\x00\x00" +
- "\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@f[\xd0\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x8c\xd0\x00\x00\x00\x00G$\x17" +
- "P\x00\x00\x00\x00GܩP\x00\x00\x00\x00I\x03\xf9P\x00\x00\x00\x00I\xb3P\xd0\x00\x00\x00\x00J\xe3\xdbP\x00\x00\x00\x00K\x9cmP\x00\x00\x00\x00L\xcc\xf7\xd0\x00\x00\x00\x00M\x85\x89\xd0\x00\x00\x00" +
- "\x00N\xbfN\xd0\x00\x00\x00\x00Ow\xe0\xd0\x00\x00\x00\x00P\x95\xf6P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb2\xc8\x00\x00\xff\xff\xb2\xc0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\fLMT\x00HMT\x00CDT\x00CST\x00\nCST5CDT,M3.2" +
- ".0/0,M11.1.0/1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4MS\x99\x1e\x01\x00\x00\x1e\x01\x00\x00\x12\x00\x00\x00America/Hermosi" +
- "lloTZif2\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\x0f\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6f" +
- "V`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00" +
- "\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x01\x02\x01\x03\x01\x02\x01\x04\x01\x03\x01\x03\x01\x03\x01\xff\xff\x97\xf8\x00\x00\xff" +
- "\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\x8f\x80\x00\x10LMT\x00MST\x00CST\x00MDT\x00PST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x1c\x00\x00\x00America/Indiana/IndianapolisTZif2\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\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a" +
- "\xdbp\xff\xff\xff\xff\xcaW\"\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff" +
- "\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0" +
- "s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff" +
- "\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87" +
- "\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06" +
- "\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CW" +
- "T\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00" +
- "\xf8\x03\x00\x00\x14\x00\x00\x00America/Indiana/KnoxTZif2\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\x06\x00" +
- "\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff" +
- "\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda" +
- "\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff" +
- "\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8" +
- "\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff" +
- "\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe" +
- "\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00" +
- "\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\f" +
- "ٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00" +
- "\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a" +
- "\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00" +
- "\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)" +
- "\nc\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\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\x05\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\x05\x01\x02\x01" +
- "\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00" +
- "\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M/U\x9f7\x02\x00\x007\x02\x00\x00\x17\x00\x00\x00Americ" +
- "a/Indiana/MarengoTZif2\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\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0" +
- "\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff" +
- "\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0" +
- "\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff" +
- "\ue47c\xf0\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`" +
- "\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00" +
- "\n\xf0\x86`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06" +
- "\x05\x06\x05\x01\x05\x06\x05\x06\x05\x06\xff\xff\xaf\r\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00" +
- "CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xd8" +
- "N\x8c\xab\x02\x00\x00\xab\x02\x00\x00\x1a\x00\x00\x00America/Indiana/PetersburgTZif2\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\x008\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb" +
- "\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xe4g=\xe0\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff" +
- "\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xef" +
- "\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xf6?ip\xff" +
- "\xff\xff\xff\xf7/h\x80\xff\xff\xff\xff\xfa\bg\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff" +
- "\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00" +
- "\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r" +
- "\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x01\x02\x01\x05\xff\xff\xae-\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9" +
- "\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\nEST5EDT,M3.2.0,M11.1" +
- ".0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00صK\xa6\n\x02\x00\x00\n\x02\x00\x00\x19\x00\x00\x00America/Indiana/Tell_CityTZ" +
- "if2\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\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff" +
- "\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xe4g=\xe0\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<" +
- "\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff" +
- "\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87" +
- "p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00" +
- "\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x06" +
- "\x05\x06\x05\x01\x02\x01\xff\xff\xae\xa9\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00" +
- "CWT\x00CPT\x00EST\x00EDT\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x17\x89}q\x01" +
- "\x00\x00q\x01\x00\x00\x15\x00\x00\x00America/Indiana/VevayTZif2\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\x14\x00\x00" +
- "\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#" +
- "\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00" +
- "\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06" +
- "\x05\x06\x05\x06\x05\x06\xff\xff\xb0@\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00" +
- "CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\xedsp.\x02" +
- "\x00\x00.\x02\x00\x00\x19\x00\x00\x00America/Indiana/VincennesTZif2\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\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff" +
- "\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I" +
- "6p\xff\xff\xff\xff\xe4g=\xe0\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff" +
- "\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0q\x9e\xf0\xff\xff\xff\xff\xf1\x8f" +
- "\u0080\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00" +
- "\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x02\x01\x02\x01\x02\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\x05\x06\x05\x06\x05\x01\x02\x01\x05\xff\xff\xad\xf1\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01" +
- "\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00K-E\xfad\x02\x00\x00d\x02\x00\x00\x17\x00\x00\x00America/Indiana/WinamacTZif2\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\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdb" +
- "p\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff" +
- "\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90" +
- "p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff" +
- "\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2" +
- "\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00" +
- "\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-_\xe0\x02\x01\x02\x01\x02\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\x05\x06\x05\x06\x05\x01\x02\x06\x05\xff\xff\xae\xcf\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14" +
- "\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x14\x00\x00\x00America/IndianapolisTZif2\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\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1" +
- "\x9a\xdbp\xff\xff\xff\xff\xcaW\"\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff" +
- "\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb" +
- "\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff" +
- "\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01" +
- "\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05" +
- "\x06\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00C" +
- "WT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ʼ\to1\x03\x00" +
- "\x001\x03\x00\x00\x0e\x00\x00\x00America/InuvikTZif2\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\x00H\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff" +
- "\xff\xff\xe0\x06N\x80\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\b \xeb\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\n\x00" +
- "͠\x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00" +
- "\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"" +
- "E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00" +
- "\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15" +
- "\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00" +
- "\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R" +
- "\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00" +
- "\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO" +
- "\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\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\x00\x00\x00\x00\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff" +
- "\x8f\x80\x00\b\xff\xff\x9d\x90\x00\f\xff\xff\xab\xa0\x01\x10-00\x00PDT\x00PST\x00MST\x00MDT\x00\nMST7MDT,M3.2.0,M11.1.0\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Š\xd6\x05W\x03\x00\x00W\x03\x00\x00\x0f\x00\x00\x00America/IqaluitTZif2\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\x00J\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff\xccl\xa1\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`" +
- "\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00" +
- "\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0" +
- "\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00" +
- "\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`" +
- "\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00" +
- ")\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp" +
- "\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x00" +
- "7\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0" +
- "\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00" +
- "EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x04\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x06\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10\xff\xff\xab\xa0" +
- "\x00\x14\xff\xff\xb9\xb0\x01\x18-00\x00EPT\x00EST\x00EDT\x00EWT\x00CST\x00CDT\x00\nEST5EDT,M3.2.0,M11.1.0\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%J\xd5\xebS\x01\x00\x00S\x01\x00\x00\x0f\x00\x00\x00America/JamaicaTZif2\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\x16\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87#~\xff\xff\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0" +
- "\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00" +
- "\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`" +
- "\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xb8\x02\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0" +
- "\x01\fLMT\x00KMT\x00EST\x00EDT\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00utZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\r\x00\x00\x00Americ" +
- "a/JujuyTZif2\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\x00TZ" +
- "if2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xb8\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff" +
- "\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96" +
- "\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff" +
- "\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee" +
- "\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff" +
- "\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbc" +
- "S0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00" +
- "\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xe2۰\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99" +
- "W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x04\x05\x04\x05\x03\x05\x04\x05\xff\xff\xc2\xc8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3" +
- "\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xc9\x1c\xd4\xc6\x03\x00\x00\xc6" +
- "\x03\x00\x00\x0e\x00\x00\x00America/JuneauTZif2\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\x00S\x00\x00\x00\n\x00\x00\x00&\xff\xff\xff\xff" +
- "?\xc2\xfd\xd1\xff\xff\xff\xff}\x872\xc5\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) " +
- "\x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00" +
- "\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10" +
- "\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14Yc \x00\x00\x00\x00\x15IT \x00\x00\x00\x00" +
- "\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0" +
- "\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00" +
- "#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ" +
- "\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x00" +
- "1g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 " +
- "\x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00" +
- "?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10" +
- "\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x06\x02\x05\x02\x05\x02\x05\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t" +
- "\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xd3{\x00\x00\xff\xff\x81\xfb\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff" +
- "\xff\x8f\x80\x01\x14\xff\xff\x81p\x00\x18\xff\xff\x8f\x80\x01\x1c\xff\xff\x81p\x00!LMT\x00PST\x00PWT\x00PPT\x00PDT\x00YDT\x00YST\x00AKDT\x00AKST" +
- "\x00\nAKST9AKDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x1b\x00\x00\x00Ame" +
- "rica/Kentucky/LouisvilleTZif2\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\x00u\x00\x00\x00\a\x00\x00\x00\x1c\xff" +
- "\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa4s\xf7\x00\xff\xff\xff\xff\xa5\x16\x11p\xff\xff\xff\xff\xca" +
- "\rN\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xd7\x1c\xff\xff\xff\xffӤ\tp\xff\xff\xff\xff\xda\xfe\xb5\x80\xff" +
- "\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2" +
- "~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe9\x17\x00\xf0\xff" +
- "\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0" +
- "\x1e\x90p\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00" +
- "\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t" +
- "\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00" +
- "\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18" +
- "\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00" +
- "\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&" +
- "\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00" +
- "\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004" +
- "R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00" +
- "\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00B" +
- "O\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" +
- "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf\x9a\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0" +
- "\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M1" +
- "1.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x1a|J\xcc\x03\x00\x00\xcc\x03\x00\x00\x1b\x00\x00\x00America/Kentucky/Montice" +
- "lloTZif2\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\x00W\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba" +
- "\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff" +
- "\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P" +
- "\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00" +
- "\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13i" +
- "V\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00" +
- "\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81" +
- "\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00" +
- "\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~" +
- "Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00" +
- "\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb" +
- "\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00" +
- "\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xb0t\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff" +
- "\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xc7\xc0\x01\x14\xff\xff\xb9\xb0\x00\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EDT\x00EST\x00\nEST5EDT," +
- "M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x0f\x00\x00\x00America/Knox_IN" +
- "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\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff" +
- "\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd7" +
- "5\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff" +
- "\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5" +
- "W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff" +
- "\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xfa" +
- "\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00" +
- "\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t" +
- "\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00" +
- "\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17" +
- ")\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00" +
- "\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%" +
- "J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02" +
- "\x01\x02\x01\x02\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\x05\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\x05\x01\x02\x01\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0" +
- "\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00America/KralendijkTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00" +
- "\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad`\x12\xe9\xaa" +
- "\x00\x00\x00\xaa\x00\x00\x00\x0e\x00\x00\x00America/La_PazTZif2\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\x03\x00\x00\x00\x04\x00\x00\x00\x10" +
- "\xff\xff\xff\xffi\x87\x1bd\xff\xff\xff\xff\xb8\x1e\x96\xe4\xff\xff\xff\xff\xb8\xee\xd5\xd4\x01\x02\x03\xff\xff\xc0\x1c\x00\x00\xff\xff\xc0\x1c\x00\x04\xff\xff\xce,\x01\b\xff\xff\xc7\xc0\x00\fLMT\x00CMT\x00B" +
- "ST\x00-04\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe7\xa1\x87\x1b\x01\x00\x00\x1b\x01\x00\x00\f\x00\x00\x00America/LimaTZi" +
- "f2\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\x10\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xffi\x87#\xbc\xff\xff\xff\xff\x8ct@\xd4\xff\xff\xff\xff\xc3\xcfJP\xff\xff\xff\xff" +
- "\xc4E\xe3@\xff\xff\xff\xff\xc5/J\xd0\xff\xff\xff\xff\xc6\x1f-\xc0\xff\xff\xff\xff\xc7\x0f,\xd0\xff\xff\xff\xff\xc7\xff\x0f\xc0\x00\x00\x00\x00\x1e\x18\xc4P\x00\x00\x00\x00\x1e\x8f]@\x00\x00\x00\x00\x1f\xf9\xf7\xd0" +
- "\x00\x00\x00\x00 p\x90\xc0\x00\x00\x00\x00%\x9e\xe3\xd0\x00\x00\x00\x00&\x15|\xc0\x00\x00\x00\x00-%\x03P\x00\x00\x00\x00-\x9b\x9c@\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb7\xc4" +
- "\x00\x00\xff\xff\xb7\xac\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\bLMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\"\x12\xfe\x0e\x05" +
- "\x00\x00\x0e\x05\x00\x00\x13\x00\x00\x00America/Los_AngelesTZif2\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\x05" +
- "\x00\x00\x00\x14\xff\xff\xff\xff^\x04\x1a\xc0\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p" +
- "\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd6\xfet\\\xff\xff\xff\xff\u0600\xad\x90\xff\xff\xff\xff\xda\xfeÐ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff" +
- "\u07be\x87\x90\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90" +
- "\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff" +
- "\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fА\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xb2\x90" +
- "\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\x94\x90\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff" +
- "\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10" +
- "\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00" +
- "\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae " +
- "\x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00" +
- "\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90" +
- "\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00" +
- "%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0" +
- "\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x00" +
- "3Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10" +
- "\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00" +
- "A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x91&\x00\x00\xff\xff\x9d\x90\x01" +
- "\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1" +
- ".0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x12\x00\x00\x00America/LouisvilleTZif2\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\x00u\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff" +
- "\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa4s\xf7\x00\xff\xff\xff\xff\xa5\x16\x11p\xff\xff\xff\xff\xca\rN\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a" +
- "\t\xf0\xff\xff\xff\xff\xd3u\xd7\x1c\xff\xff\xff\xffӤ\tp\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff" +
- "\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G" +
- "<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff" +
- "\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x1e\x90p\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7" +
- "\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00" +
- "\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0" +
- "gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00" +
- "\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1" +
- "\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00" +
- "\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)\xde" +
- "\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00" +
- "\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b" +
- "\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00" +
- "\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3" +
- "\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x01\x05\x06\x05\x06\x05\x06\x05" +
- "\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff" +
- "\xff\xaf\x9a\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT" +
- "\x00EST\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15" +
- "\x00\x00\x00America/Lower_PrincesTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff" +
- "\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fL" +
- "MT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00挋\x92\xf6\x01\x00\x00\xf6\x01\x00\x00\x0e\x00\x00\x00America/M" +
- "aceioTZif2\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\x00TZif" +
- "2\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\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaah|\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff" +
- "\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150" +
- "\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff" +
- "\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ" +
- "\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00" +
- "%\xd4\xc7 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x009\xf2J \x00\x00\x00\x00;\xc8\xff\xb0" +
- "\x00\x00\x00\x00<o\x0e\xa0\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\xff\xffބ\x00\x00\xff\xff\xe3\xe0\x01" +
- "\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5s\xb3\\'\x01\x00\x00'\x01\x00\x00\x0f\x00\x00\x00Ame" +
- "rica/ManaguaTZif2\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\x10\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffi\x87,d\xff\xff\xff\xff\xbd" +
- "-H\xe8\x00\x00\x00\x00\x06Ct`\x00\x00\x00\x00\t\xa4>P\x00\x00\x00\x00\x11Q\xf8\xe0\x00\x00\x00\x00\x11\xd4oP\x00\x00\x00\x00\x131\xda\xe0\x00\x00\x00\x00\x13\xb4QP\x00\x00\x00\x00)a\x91 \x00" +
- "\x00\x00\x00*\xc1KP\x00\x00\x00\x00+C\xdd\xe0\x00\x00\x00\x002\xc9\xefP\x00\x00\x00\x00BX\xc0\xe0\x00\x00\x00\x00C?iP\x00\x00\x00\x00DTn\x80\x00\x00\x00\x00E\x1fY`\x01\x02\x03\x02\x04" +
- "\x02\x04\x02\x03\x02\x03\x02\x04\x02\x04\x02\xff\xff\xaf\x1c\x00\x00\xff\xff\xaf\x18\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10LMT\x00MMT\x00CST\x00EST\x00CDT" +
- "\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\x0e\x00\x00\x00America/ManausTZif2\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\x1f\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x7fD\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff" +
- "\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdf\xdd" +
- "\xa8@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff" +
- "\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3" +
- "ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\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\xff\xffǼ\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*" +
- ";\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America/MarigotTZif2\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\x04\x00\x00\x00\x04\x00" +
- "\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5" +
- "\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x17jҲ\x00\x00\x00\xb2\x00\x00\x00\x12\x00\x00\x00Ameri" +
- "ca/MartiniqueTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffi\x87\x14\xc4\xff\xff\xff\xff" +
- "\x91\xa3\xc8D\x00\x00\x00\x00\x13Mn@\x00\x00\x00\x00\x144\x16\xb0\x01\x02\x03\x02\xff\xffƼ\x00\x00\xff\xffƼ\x00\x04\xff\xff\xc7\xc0\x00\t\xff\xff\xd5\xd0\x01\rLMT\x00FFMT\x00AST" +
- "\x00ADT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00((i\xe4\xb5\x01\x00\x00\xb5\x01\x00\x00\x11\x00\x00\x00America/MatamorosTZ" +
- "if2\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\x03\x00\x00\x00\f\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00" +
- "\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8" +
- "\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00" +
- "\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff" +
- "\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\x9c\x97\x80\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\xff\xff\xa4\x98\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\bLMT\x00CST\x00CDT\x00\nCST6CDT," +
- "M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xad=\x98\xce\x02\x00\x00\xce\x02\x00\x00\x10\x00\x00\x00America/Mazatla" +
- "nTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`" +
- "\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x00" +
- "2s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10" +
- "\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00" +
- "@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80" +
- "\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\"\x00\x00\x00\x00\x00M\x987\x10\x00\x00\x00\x00" +
- "N\xad\x04\x00\x00\x00\x00\x00Ox\x19\x10\x00\x00\x00\x00P\x8c\xe6\x00\x00\x00\x00\x00Qa5\x90\x00\x00\x00\x00Rl\xc8\x00\x00\x00\x00\x00SA\x17\x90\x00\x00\x00\x00TL\xaa\x00\x00\x00\x00\x00U \xf9\x90" +
- "\x00\x00\x00\x00V,\x8c\x00\x00\x00\x00\x00W\x00ې\x00\x00\x00\x00X\x15\xa8\x80\x00\x00\x00\x00Xཐ\x00\x00\x00\x00Y\xf5\x8a\x80\x00\x00\x00\x00Z\xc0\x9f\x90\x00\x00\x00\x00[\xd5l\x80\x00\x00\x00\x00" +
- "\\\xa9\xbc\x10\x00\x00\x00\x00]\xb5N\x80\x00\x00\x00\x00^\x89\x9e\x10\x00\x00\x00\x00_\x950\x80\x00\x00\x00\x00`i\x80\x10\x00\x00\x00\x00a~M\x00\x00\x00\x00\x00bIb\x10\x00\x00\x00\x00c^/\x00" +
- "\x01\x02\x01\x03\x01\x02\x01\x04\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03" +
- "\x01\x03\x01\xff\xff\x9c<\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\x8f\x80\x00\x10LMT\x00MST\x00CST\x00MDT\x00PST\x00\nMST7\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ŒZ\x8c\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00America/MendozaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2\x04\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff" +
- "\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf" +
- "\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff" +
- "\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xffȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3" +
- ")5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff" +
- "\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff" +
- "\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'\x194@\x00" +
- "\x00\x00\x00'\xcdð\x00\x00\x00\x00(\xfag\xc0\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*\xe0\xe1@\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@" +
- "\xb0\x13\xb0\x00\x00\x00\x00AV>\xc0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf|\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff" +
- "\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008O:\xbf\x95\x03\x00\x00\x95\x03\x00\x00\x11\x00" +
- "\x00\x00America/MenomineeTZif2\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\x00R\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xffaw" +
- "Ic\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff" +
- "\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bg\xf0\xff\xff\xff\xff\xfe\xb8+\x00\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d" +
- "'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00" +
- "\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169" +
- "\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00" +
- "\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5" +
- "\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00" +
- "\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s" +
- "\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00" +
- "\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o" +
- "\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02" +
- "\x01\x02\x05\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\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xad\xdd\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00" +
- "CWT\x00CPT\x00EST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xbd\x809\x8e\x02\x00\x00\x8e\x02" +
- "\x00\x00\x0e\x00\x00\x00America/MeridaTZif2\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\x009\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xa5" +
- "\xb6\xda`\x00\x00\x00\x00\x16\x86\xd5`\x00\x00\x00\x00\x18LKP\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00" +
- "\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<" +
- "\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00" +
- "\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J" +
- "\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00" +
- "\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00X" +
- "ீ\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00" +
- "\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01" +
- "\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\xff\xff\xab\xfc\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xb9\xb0\x01\fLMT\x00CST\x00" +
- "EST\x00CDT\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\x81\xbfyS\x02\x00\x00S\x02\x00\x00\x12\x00\x00\x00America/Metlakat" +
- "laTZif2\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\b\x00\x00\x00\x1e\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x870\x1a\xff\xff\xff\xffˉ\x1a" +
- "\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00" +
- "\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf" +
- " \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00" +
- "\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S" +
- "\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00V5\xe2\xa0\x00\x00\x00\x00V\xe5H0\x00\x00\x00\x00X\x1e\xff \x00\x00\x00\x00X\xc5*0\x00\x00\x00\x00Y\xfe\xe1 \x00\x00\x00" +
- "\x00Z\xa5\f0\x00\x00\x00\x00[\xde\xc3 \x00\x00\x00\x00\\DF\xa0\x00\x00\x00\x00\\\x84\xee0\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" +
- "\x05\x02\x05\x02\x06\a\x06\a\x06\a\x02\x06\a\x00\x00\xd6&\x00\x00\xff\xff\x84\xa6\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x81p\x00\x14\xff\xff\x8f\x80\x01" +
- "\x19LMT\x00PST\x00PWT\x00PPT\x00PDT\x00AKST\x00AKDT\x00\nAKST9AKDT,M3.2.0,M11.1.0\nPK\x03" +
- "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\b\x89\x8c\x05\x03\x00\x00\x05\x03\x00\x00\x13\x00\x00\x00America/Mexico_CityTZif2\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\x00D\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6" +
- "`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xc5ް`\xff\xff\xff\xffƗ4P\xff\xff\xff\xff\xc9U\xf1\xe0\xff\xff\xff\xff\xc9\xea\xddP\xff\xff\xff\xff\xcf\x02\xc6\xe0\xff\xff\xff\xffϷVP\xff\xff\xff" +
- "\xffڙ\x15\xe0\xff\xff\xff\xff\xdbv\x83\xd0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xcc" +
- "p\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00" +
- "\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84" +
- "\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00" +
- "\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9" +
- "\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00\x00\x00" +
- "\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`ir" +
- "\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x05\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04" +
- "\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\xff\xff\xa3\f\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xb9" +
- "\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00MST\x00CST\x00MDT\x00CDT\x00CWT\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7\b\\\xc6&\x02\x00" +
- "\x00&\x02\x00\x00\x10\x00\x00\x00America/MiquelonTZif2\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\x10" +
- "\xff\xff\xff\xff\x91\xb68\xa8\x00\x00\x00\x00\x13nc\xc0\x00\x00\x00\x00 u\xe4\xd0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"U\xc6\xd0\x00\x00\x00\x00#j\x93\xc0\x00\x00\x00\x00$5\xa8\xd0\x00\x00\x00\x00" +
- "%Ju\xc0\x00\x00\x00\x00&\x15\x8a\xd0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00)\n9\xc0\x00\x00\x00\x00)މP\x00\x00\x00\x00*\xea\x1b\xc0\x00\x00\x00\x00+\xbekP" +
- "\x00\x00\x00\x00,\xd38@\x00\x00\x00\x00-\x9eMP\x00\x00\x00\x00.\xb3\x1a@\x00\x00\x00\x00/~/P\x00\x00\x00\x000\x92\xfc@\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002r\xde@\x00\x00\x00\x00" +
- "3G-\xd0\x00\x00\x00\x004R\xc0@\x00\x00\x00\x005'\x0f\xd0\x00\x00\x00\x0062\xa2@\x00\x00\x00\x007\x06\xf1\xd0\x00\x00\x00\x008\x1b\xbe\xc0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xa0\xc0" +
- "\x00\x00\x00\x00:Ƶ\xd0\x00\x00\x00\x00;ۂ\xc0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbd\xc0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bF\xc0\x00\x00\x00\x00@o\x96P\x00\x00\x00\x00" +
- "A\x84c@\x00\x00\x00\x00BOxP\x00\x00\x00\x00CdE@\x00\x00\x00\x00D/ZP\x00\x00\x00\x00ED'@\x00\x00\x00\x00E\xf3\x8c\xd0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xcbX\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\b\xff\xff\xe3\xe0\x01\fLMT\x00AST\x00-" +
- "03\x00-02\x00\n<-03>3<-02>,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\xf9\xc0\x1e\xd5\x05\x00\x00\xd5\x05\x00" +
- "\x00\x0f\x00\x00\x00America/MonctonTZif2\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\x92\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^" +
- "\x1e\xed\xbc\xff\xff\xff\xff\x80\xf1\xb6P\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xff\xbb<8\xd0\xff\xff\xff\xff\xbb\xb4#@\xff\xff\xff\xff\xbd\x1c\x1a\xd0\xff\xff\xff\xff\xbd\x94\x05@\xff" +
- "\xff\xff\xff\xbe\xfb\xfc\xd0\xff\xff\xff\xff\xbfs\xe7@\xff\xff\xff\xff\xc0\xdb\xde\xd0\xff\xff\xff\xff\xc1S\xc9@\xff\xff\xff\xff»\xc0\xd0\xff\xff\xff\xff\xc33\xab@\xff\xff\xff\xffě\xa2\xd0\xff\xff\xff\xff\xc5" +
- "\x13\x8d@\xff\xff\xff\xff\xc6p\xf8\xd0\xff\xff\xff\xff\xc7\r\xcd@\xff\xff\xff\xff\xc8H\xf1\xd0\xff\xff\xff\xff\xc8\xed\xaf@\xff\xff\xff\xff\xca\x16^\xd0\xff\xff\xff\xff\xca\xd6\xcb\xc0\xff\xff\xff\xffˈ\xe2`\xff" +
- "\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xd3u\xd6\xe0\xff\xff\xff\xff\xd4@\xcf\xd0\xff\xff\xff\xff\xd5U\xb8\xe0\xff\xff\xff\xff\xd6 \xb1\xd0\xff\xff\xff\xff\xd75\x9a\xe0\xff\xff\xff\xff\xd8" +
- "\x00\x93\xd0\xff\xff\xff\xff\xd9\x15|\xe0\xff\xff\xff\xff\xd9\xe0u\xd0\xff\xff\xff\xff\xda\xfe\x99`\xff\xff\xff\xff\xdb\xc0W\xd0\xff\xff\xff\xff\xdc\xde{`\xff\xff\xff\xffݩtP\xff\xff\xff\xff\u07be]`\xff" +
- "\xff\xff\xff߉VP\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\xff\xff\xff\xff\xe2~!`\xff\xff\xff\xff\xe3I\x1aP\xff\xff\xff\xff\xe4^\x03`\xff\xff\xff\xff\xe5(\xfcP\xff\xff\xff\xff\xe6" +
- "G\x1f\xe0\xff\xff\xff\xff\xe7\x12\x18\xd0\xff\xff\xff\xff\xe8'\x01\xe0\xff\xff\xff\xff\xe9\x16\xe4\xd0\xff\xff\xff\xff\xea\x06\xe3\xe0\xff\xff\xff\xff\xea\xf6\xc6\xd0\xff\xff\xff\xff\xeb\xe6\xc5\xe0\xff\xff\xff\xff\xec֨\xd0\xff" +
- "\xff\xff\xff\xedƧ\xe0\xff\xff\xff\xff\xee\xbf\xc5P\xff\xff\xff\xff\xef\xaf\xc4`\xff\xff\xff\xff\xf0\x9f\xa7P\xff\xff\xff\xff\xf1\x8f\xa6`\xff\xff\xff\xff\xf2\x7f\x89P\xff\xff\xff\xff\xf3o\x88`\xff\xff\xff\xff\xf4" +
- "_kP\xff\xff\xff\xff\xf5Oj`\xff\xff\xff\xff\xf6?MP\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(i\xd0\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff" +
- "\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02" +
- "w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00" +
- "\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12" +
- "y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00" +
- "\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 " +
- "u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00" +
- "\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbe]|\x00\x00\x00\x00,\xd3*l\x00\x00\x00\x00-\x9e?|\x00\x00\x00\x00." +
- "\xb3\fl\x00\x00\x00\x00/~!|\x00\x00\x00\x000\x92\xeel\x00\x00\x00\x001g=\xfc\x00\x00\x00\x002r\xd0l\x00\x00\x00\x003G\x1f\xfc\x00\x00\x00\x004R\xb2l\x00\x00\x00\x005'\x01\xfc\x00" +
- "\x00\x00\x0062\x94l\x00\x00\x00\x007\x06\xe3\xfc\x00\x00\x00\x008\x1b\xb0\xec\x00\x00\x00\x008\xe6\xc5\xfc\x00\x00\x00\x009\xfb\x92\xec\x00\x00\x00\x00:Ƨ\xfc\x00\x00\x00\x00;\xdbt\xec\x00\x00\x00\x00<" +
- "\xaf\xc4|\x00\x00\x00\x00=\xbbV\xec\x00\x00\x00\x00>\x8f\xa6|\x00\x00\x00\x00?\x9b8\xec\x00\x00\x00\x00@o\x88|\x00\x00\x00\x00A\x84Ul\x00\x00\x00\x00BOj|\x00\x00\x00\x00Cd7l\x00" +
- "\x00\x00\x00D/L|\x00\x00\x00\x00ED\x19l\x00\x00\x00\x00E\xf3\x9a\xe0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xc3D\x00\x00\xff\xff\xb9\xb0\x00" +
- "\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xc7\xc0\x00\f\xff\xff\xd5\xd0\x01\x10\xff\xff\xd5\xd0\x01\x14LMT\x00EST\x00ADT\x00AST\x00AWT\x00APT\x00\nAST4ADT,M3" +
- ".2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L+\xe3u\x84\x02\x00\x00\x84\x02\x00\x00\x11\x00\x00\x00America/Monterrey" +
- "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\x009\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00" +
- "\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008" +
- "\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00" +
- "\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F" +
- "\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00" +
- "\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00T" +
- "L\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00" +
- "\x00\x00\x00[\xd5^p\x00\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00b" +
- "IT\x00\x00\x00\x00\x00c^ \xf0\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" +
- "\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa1\xf4\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\bLMT\x00CST\x00CDT\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x98" +
- "\x00\b\xc9\x03\x00\x00\xc9\x03\x00\x00\x12\x00\x00\x00America/MontevideoTZif2\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\x00V\x00" +
- "\x00\x00\t\x00\x00\x00&\xff\xff\xff\xff\x8c4\xe53\xff\xff\xff\xff\xa2\x92\x87\xb3\xff\xff\xff\xff\xa8\xff\xdb@\xff\xff\xff\xff\xa9\xf1\x0f\xb0\xff\xff\xff\xff\xaa\xe2Y8\xff\xff\xff\xff\xab\xd2C0\xff\xff\xff\xff\xac" +
- "Ì\xb8\xff\xff\xff\xff\xad\xb3v\xb0\xff\xff\xff\xff\xbb\xf4\xb5\xb8\xff\xff\xff\xff\xbc\xbf\xb5\xb0\xff\xff\xff\xff\xbdԗ\xb8\xff\xff\xff\xff\xbe\x9f\x97\xb0\xff\xff\xff\xff\xbf\xb4y\xb8\xff\xff\xff\xff\xc0\x7fy\xb0\xff" +
- "\xff\xff\xff\xc1\x94[\xb8\xff\xff\xff\xff\xc2_[\xb0\xff\xff\xff\xff\xc3}x8\xff\xff\xff\xff\xc4?=\xb0\xff\xff\xff\xff\xc5]Z8\xff\xff\xff\xff\xc6\x1f\x1f\xb0\xff\xff\xff\xff\xc7\x18R8\xff\xff\xff\xff\xc8" +
- "\b<0\xff\xff\xff\xff\xc9\x1d\x1e8\xff\xff\xff\xff\xc9\xe8\x1e0\xff\xff\xff\xffʋ\x9f8\xff\xff\xff\xff\xcd\x1e\xc60\xff\xff\xff\xff͕f(\xff\xff\xff\xff\xec\v\x85\xb0\xff\xff\xff\xff\xec\xf25(\xff" +
- "\xff\xff\xff\xedEJ\xb0\xff\xff\xff\xff\xed\x85\xd6 \xff\xff\xff\xff\xf7\x13r\xb0\xff\xff\xff\xff\xf7\xfa\x1b \xff\xff\xff\xff\xfc\xfe>0\xff\xff\xff\xff\xfd\xf6\x11(\x00\x00\x00\x00\x00\x96u0\x00\x00\x00\x00\x00" +
- "\xd8R \x00\x00\x00\x00\x04W\x8a\xb0\x00\x00\x00\x00\x04\xc6:\xa0\x00\x00\x00\x00\a\x96\x1b\xb0\x00\x00\x00\x00\a\xdfژ\x00\x00\x00\x00\bƟ(\x00\x00\x00\x00\tZN0\x00\x00\x00\x00\t\xdbs \x00" +
- "\x00\x00\x00\r\x1a\x120\x00\x00\x00\x00\r\x7f\x87\xa0\x00\x00\x00\x00\x0e\xe7\x7f0\x00\x00\x00\x00\x0f_i\xa0\x00\x00\x00\x00\x10\xd9\xd60\x00\x00\x00\x00\x11?K\xa0\x00\x00\x00\x00\x11\x89-\xb0\x00\x00\x00\x00\x13" +
- "1\xa2\xa0\x00\x00\x00\x00!\xc3T0\x00\x00\x00\x00\"'x \x00\x00\x00\x00#\xa1\xe4\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%Jg\xb0\x00\x00\x00\x00%\xe7< \x00\x00\x00\x00'!\x0f0\x00" +
- "\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\n+\xb0\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x90\x1c\xa0\x00\x00\x00\x00AL\xf60\x00\x00\x00\x00BF/\xc0\x00\x00\x00\x00C" +
- "H\xa3\xd0\x00\x00\x00\x00D\x13\x9c\xc0\x00\x00\x00\x00E\x1fKP\x00\x00\x00\x00E\xf3~\xc0\x00\x00\x00\x00G\bg\xd0\x00\x00\x00\x00G\xd3`\xc0\x00\x00\x00\x00H\xe8I\xd0\x00\x00\x00\x00I\xb3B\xc0\x00" +
- "\x00\x00\x00J\xc8+\xd0\x00\x00\x00\x00K\x9c_@\x00\x00\x00\x00L\xa8\r\xd0\x00\x00\x00\x00M|A@\x00\x00\x00\x00N\x87\xef\xd0\x00\x00\x00\x00O\\#@\x00\x00\x00\x00Pq\fP\x00\x00\x00\x00Q" +
- "<\x05@\x00\x00\x00\x00RP\xeeP\x00\x00\x00\x00S\x1b\xe7@\x00\x00\x00\x00T0\xd0P\x00\x00\x00\x00T\xfb\xc9@\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
- "\x06\x05\x06\x05\a\x05\a\x05\x06\x05\a\x05\a\x05\b\x06\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a\x05\a" +
- "\x05\xff\xff\xcbM\x00\x00\xff\xff\xcbM\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xce\xc8\x00\f\xff\xff\xd5\xd0\x01\x12\xff\xff\xd5\xd0\x00\x12\xff\xff\xdc\xd8\x01\x16\xff\xff\xe3\xe0\x01\x1c\xff\xff\xea\xe8\x01 LMT\x00M" +
- "MT\x00-04\x00-0330\x00-03\x00-0230\x00-02\x00-0130\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5" +
- "\x06\x00\x00\xb5\x06\x00\x00\x10\x00\x00\x00America/MontrealTZif2\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\xac\x00\x00\x00\x05\x00\x00" +
- "\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff" +
- "\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5" +
- "M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff" +
- "\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%" +
- "\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff" +
- "\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f" +
- ":\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff" +
- "\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdc\xde" +
- "\x89p\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff" +
- "\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6" +
- "\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff" +
- "\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f" +
- "<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00" +
- "\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0" +
- "\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00" +
- "\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I" +
- ")\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00" +
- "\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j" +
- "\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00" +
- "\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001g" +
- "g\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00" +
- "\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9b" +
- "b\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0" +
- "\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2.0,M11." +
- "1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00America/MontserratTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01" +
- "\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00\x00\x00America/NassauTZif2\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\xac" +
- "\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff" +
- "\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p" +
- "\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff" +
- "\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`" +
- "\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff" +
- "\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p" +
- "\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff" +
- "\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`" +
- "\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff" +
- "\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0" +
- "\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff" +
- "\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0" +
- "\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff" +
- "\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp" +
- "\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00" +
- "\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0" +
- "\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00" +
- "\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0" +
- "\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00" +
- ")ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`" +
- "\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x00" +
- "8\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p" +
- "\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00" +
- "E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94" +
- "\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2." +
- "0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\x10\x00\x00\x00America/New_YorkTZif" +
- "2\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\xaf\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x03\xf0\x90\xff\xff\xff\xff\x9e\xa6\x1ep\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0" +
- "\x86\x00p\xff\xff\xff\xff\xa1\x9a\xcd`\xff\xff\xff\xff\xa2e\xe2p\xff\xff\xff\xff\xa3\x83\xe9\xe0\xff\xff\xff\xff\xa4j\xaep\xff\xff\xff\xff\xa55\xa7`\xff\xff\xff\xff\xa6S\xca\xf0\xff\xff\xff\xff\xa7\x15\x89`\xff" +
- "\xff\xff\xff\xa83\xac\xf0\xff\xff\xff\xff\xa8\xfe\xa5\xe0\xff\xff\xff\xff\xaa\x13\x8e\xf0\xff\xff\xff\xff\xaaއ\xe0\xff\xff\xff\xff\xab\xf3p\xf0\xff\xff\xff\xff\xac\xbei\xe0\xff\xff\xff\xff\xad\xd3R\xf0\xff\xff\xff\xff\xae" +
- "\x9eK\xe0\xff\xff\xff\xff\xaf\xb34\xf0\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff" +
- "\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9\x1b\xd9p\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbbƴ`\xff\xff\xff\xff\xbc" +
- "\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff" +
- "\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xc8\xf8W`\xff\xff\xff\xff\xca\r@p\xff\xff\xff\xff\xca" +
- "\xd89`\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xc6\xf0\xff\xff\xff\xff\xd6 \xbf\xe0\xff" +
- "\xff\xff\xff\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xd9\x15\x8a\xf0\xff\xff\xff\xff\xd9\xe0\x83\xe0\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdb\xc0e\xe0\xff\xff\xff\xff\xdcމp\xff\xff\xff\xff\xdd" +
- "\xa9\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff" +
- "\xff\xff\xff\xe5W.\xe0\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe77\x10\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb" +
- "\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff" +
- "\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa" +
- "\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00" +
- "\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a" +
- "\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00" +
- "\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x16" +
- "9\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00" +
- "\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$" +
- "5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00" +
- "\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002" +
- "r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00" +
- "\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@" +
- "o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xba\x9e\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff" +
- "\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2.0,M11.1.0\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x00\x00America/NipigonTZif2\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\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@" +
- "\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff" +
- "\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop" +
- "\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff" +
- "\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0" +
- "\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff" +
- "\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0" +
- "\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff" +
- "\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`" +
- "\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff" +
- "\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p" +
- "\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff" +
- "\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0" +
- "\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00" +
- "\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p" +
- "\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00" +
- "\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`" +
- "\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00" +
- "!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p" +
- "\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00" +
- "/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`" +
- "\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00" +
- "=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp" +
- "\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nE" +
- "ST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\xab\xd5\xf9\xcf\x03\x00\x00\xcf\x03\x00\x00\f\x00\x00\x00America/" +
- "NomeTZif2\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\x00T\x00\x00\x00\n\x00\x00\x00&\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87O\xd2\xff\xff\xff\xff\xcb" +
- "\x89D\xd0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00" +
- "\x00\x00\x00\x02x5P\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\a1\x16\xc0\x00\x00\x00\x00\a\x8dm\xd0\x00\x00\x00\x00\t" +
- "\x10\xf8\xc0\x00\x00\x00\x00\t\xad\xe9P\x00\x00\x00\x00\n\xf0\xda\xc0\x00\x00\x00\x00\v\xe0\xd9\xd0\x00\x00\x00\x00\f\xd9\xf7@\x00\x00\x00\x00\r\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00" +
- "\x00\x00\x00\x10\x99\xbb@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17" +
- ")`P\x00\x00\x00\x00\x18\"}\xc0\x00\x00\x00\x00\x19\tBP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00" +
- "\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$" +
- "5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00" +
- "\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002" +
- "s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00" +
- "\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@" +
- "o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x06\x05\x06" +
- "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t" +
- "\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\x00\x00\xb6n\x00\x00\xff\xffd\xee\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\b\xff\xffs`\x01\f\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xff\x81" +
- "p\x00\x18\xff\xff\x8f\x80\x01\x1c\xff\xff\x81p\x00!LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00YST\x00AKDT\x00AKST\x00\nAKST9A" +
- "KDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x0f\x00\x00\x00America/Nor" +
- "onhaTZif2\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\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaaed\xff\xff\xff\xff\xb8\x0f;\xd0\xff\xff\xff\xff\xb8" +
- "\xfd2\x90\xff\xff\xff\xff\xb9\xf1& \xff\xff\xff\xff\xba\xdef\x10\xff\xff\xff\xff\xda8\xa0 \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdc\x19Ӡ\xff\xff\xff\xffܹK\x10\xff\xff\xff\xff\xdd\xfb\a \xff" +
- "\xff\xff\xffޛ\xd0\x10\xff\xff\xff\xff\xdf\u074c \xff\xff\xff\xff\xe0T%\x10\xff\xff\xff\xff\xf4\x97\xf1\xa0\xff\xff\xff\xff\xf5\x05P\x10\xff\xff\xff\xff\xf6\xc0V \xff\xff\xff\xff\xf7\x0e\x10\x90\xff\xff\xff\xff\xf8" +
- "Q\x1e \xff\xff\xff\xff\xf8Ƿ\x10\xff\xff\xff\xff\xfa\nĠ\xff\xff\xff\xff\xfa\xa8\xea\x90\xff\xff\xff\xff\xfb\xeb\xf8 \xff\xff\xff\xff\xfc\x8bo\x90\x00\x00\x00\x00\x1dɀ \x00\x00\x00\x00\x1exɐ\x00" +
- "\x00\x00\x00\x1f\xa0'\xa0\x00\x00\x00\x00 3\xc1\x90\x00\x00\x00\x00!\x81[ \x00\x00\x00\x00\"\v\xba\x90\x00\x00\x00\x00#X\x02\xa0\x00\x00\x00\x00#\xe2b\x10\x00\x00\x00\x00%7\xe4\xa0\x00\x00\x00\x00%" +
- "Թ\x10\x00\x00\x00\x007\xf6\xb8\xa0\x00\x00\x00\x008\xb8w\x10\x00\x00\x00\x009\xdf\xd5 \x00\x00\x00\x009\xe9\x01\x90\x00\x00\x00\x00;\xc8\xf1\xa0\x00\x00\x00\x00<o\x00\x90\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\xff\xff\xe1\x9c\x00\x00\xff\xff\xf1\xf0\x01\x04\xff\xff\xe3\xe0\x00\bLMT\x00-01\x00-02\x00" +
- "\n<-02>2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7.\xb6*\x13\x04\x00\x00\x13\x04\x00\x00\x1b\x00\x00\x00America/North_Dakota/B" +
- "eulahTZif2\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\x00TZif" +
- "2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff" +
- "\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00" +
- "\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00" +
- "\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10" +
- "\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00" +
- "\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80" +
- "\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00" +
- "\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10" +
- "\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00" +
- "-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80" +
- "\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00" +
- ";ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90" +
- "\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-|\x00\x00\x00\x00\x00Gӧ\x10\x00\x00\x00\x00I\r^\x00\x00\x00\x00\x00" +
- "I\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x02\x01\x02\x01\x02\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\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\x05\xff\xff\xa0\x95\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00" +
- "CST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\xeam\xef\xde\x03\x00\x00\xde\x03\x00\x00\x1b\x00\x00\x00Am" +
- "erica/North_Dakota/CenterTZif2\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\x00Y\x00\x00\x00\a\x00\x00\x00\x1c" +
- "\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff" +
- "\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10" +
- "\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00" +
- "\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00" +
- "\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00" +
- "\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90" +
- "\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00" +
- "$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00" +
- "\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x00" +
- "2s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00" +
- "\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00" +
- "@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\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\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\x06" +
- "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xa1\b\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab" +
- "\xa0\x00\x18LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CDT\x00CST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x1b\x8b(\xde\x03\x00\x00\xde\x03\x00\x00\x1e\x00\x00\x00America/North_Dakota/New_SalemTZif2" +
- "\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\x00Y\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86" +
- "\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff" +
- "\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a" +
- "\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00" +
- "\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12y" +
- "e\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00" +
- "\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v" +
- "\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00" +
- "\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3" +
- "R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00" +
- "\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0" +
- "\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00" +
- "\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xa0\xed\x00\x00\xff\xff\xab" +
- "\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CDT\x00CST" +
- "\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95'O\xce\xc5\x03\x00\x00\xc5\x03\x00\x00\f\x00\x00\x00Ameri" +
- "ca/NuukTZif3\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\x00TZ" +
- "if3\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\x00Y\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\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\xc3" +
- "\x91\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5" +
- "%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00" +
- "\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd" +
- "\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00" +
- "\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC" +
- "\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00" +
- "\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7" +
- "l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00" +
- "\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\n\x10\x00\x00\x00\x00\\\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\x7f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}" +
- "\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]̐\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\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\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\x03\xff\xffπ\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\b\xff\xff\xe3\xe0\x00\bLMT\x00-03\x00-02\x00\n<-02>2<-01>,M3.5.0/-" +
- "1,M10.5.0/0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe5\x9e<\xc5\x02\x00\x00\xc5\x02\x00\x00\x0f\x00\x00\x00America/OjinagaTZi" +
- "f2\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\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff" +
- "\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005'H\x10" +
- "\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00" +
- "<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80" +
- "\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00" +
- "J\xe4\x05\x80\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\\\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00\x00O\\i\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q<K\x90" +
- "\x00\x00\x00\x00Rv\x02\x80\x00\x00\x00\x00S\x1c-\x90\x00\x00\x00\x00TU\xe4\x80\x00\x00\x00\x00T\xfc\x0f\x90\x00\x00\x00\x00V5ƀ\x00\x00\x00\x00V\xe5,\x10\x00\x00\x00\x00X\x1e\xe3\x00\x00\x00\x00\x00" +
- "X\xc5\x0e\x10\x00\x00\x00\x00Y\xfe\xc5\x00\x00\x00\x00\x00Z\xa4\xf0\x10\x00\x00\x00\x00[ާ\x00\x00\x00\x00\x00\\\x84\xd2\x10\x00\x00\x00\x00]\xbe\x89\x00\x00\x00\x00\x00^d\xb4\x10\x00\x00\x00\x00_\x9ek\x00" +
- "\x00\x00\x00\x00`MА\x00\x00\x00\x00a\x87\x87\x80\x00\x00\x00\x00b-\xb2\x90\x00\x00\x00\x00c^/\x00\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01" +
- "\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x02\xff\xff\x9e\x1c\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xb9\xb0" +
- "\x01\x10LMT\x00MST\x00CST\x00MDT\x00CDT\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x00\x00America/PanamaTZif2\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\x02\x00\x00\x00" +
- "\x03\x00\x00\x00\f\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\bLMT\x00CMT\x00EST\x00\nEST5\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Š\xd6\x05W\x03\x00\x00W\x03\x00\x00\x13\x00\x00\x00America/PangnirtungTZif2\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\x00J\x00\x00\x00\a\x00\x00\x00\x1c\xff\xff\xff\xff\xccl\xa1\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05" +
- "P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00" +
- "\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13" +
- "iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00" +
- "\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!" +
- "\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00" +
- "\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/" +
- "~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00" +
- "\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=" +
- "\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00" +
- "\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x04\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x06\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10\xff" +
- "\xff\xab\xa0\x00\x14\xff\xff\xb9\xb0\x01\x18-00\x00EPT\x00EST\x00EDT\x00EWT\x00CST\x00CDT\x00\nEST5EDT,M3.2.0,M11.1" +
- ".0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\xf9\x1dɻ\x00\x00\x00\xbb\x00\x00\x00\x12\x00\x00\x00America/ParamariboTZif2\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\x04\x00\x00\x00\x05\x00\x00\x00\x12\xff\xff\xff\xff\x91\x05\x8e\xb8\xff\xff\xff\xff\xbe*K\xc4\xff\xff\xff\xff\xd2b,\xb4\x00\x00\x00\x00\x1b\xbe1\xb8\x01\x02" +
- "\x03\x04\xff\xff\xccH\x00\x00\xff\xff\xcc<\x00\x04\xff\xff\xccL\x00\x04\xff\xff\xce\xc8\x00\b\xff\xff\xd5\xd0\x00\x0eLMT\x00PMT\x00-0330\x00-03\x00\n<-03>3\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x00\x00America/PhoenixTZif2\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\v\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff" +
- "\xff\xffˉ\f\x90\xff\xff\xff\xff\xcf\x17\xdf\x1c\xff\xff\xff\xffϏ\xe5\xac\xff\xff\xff\xffЁ\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96" +
- "\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\fLMT\x00MDT\x00MST\x00MWT\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4T\xbd" +
- "\xeb5\x02\x00\x005\x02\x00\x00\x16\x00\x00\x00America/Port-au-PrinceTZif2\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\x11\xff\xff\xff\xffi\x87\x1fP\xff\xff\xff\xff\x9cnq\xfc\x00\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x1a\x01\xef@\x00\x00\x00\x00\x1a\xf1\xeeP\x00\x00\x00\x00\x1b\xe1\xd1@\x00\x00" +
- "\x00\x00\x1c\xd1\xd0P\x00\x00\x00\x00\x1d\xc1\xb3@\x00\x00\x00\x00\x1e\xb1\xb2P\x00\x00\x00\x00\x1f\xa1\x95@\x00\x00\x00\x00 \x91\x94P\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j" +
- "\xaf\xe0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޗ`\x00\x00" +
- "\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001g" +
- "Y\xe0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x00BOxP\x00\x00\x00\x00CdE@\x00\x00\x00\x00D/ZP\x00\x00\x00\x00ED'@\x00\x00" +
- "\x00\x00O\\Mp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q</p\x00\x00\x00\x00Ru\xe6`\x00\x00\x00\x00S\x1c\x11p\x00\x00\x00\x00TU\xc8`\x00\x00\x00\x00T\xfb\xf3p\x00\x00\x00\x00V5" +
- "\xaa`\x00\x00\x00\x00X\xc4\xf1\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xbc0\x00" +
- "\x00\xff\xff\xbcD\x00\x04\xff\xff\xc7\xc0\x01\t\xff\xff\xb9\xb0\x00\rLMT\x00PPMT\x00EDT\x00EST\x00\nEST5EDT,M3.2.0,M11.1.0\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00America/Port_of_SpainTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03" +
- "\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x00\x00America/Porto_AcreTZif2\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\x1f\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff" +
- "\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4" +
- "\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff" +
- "\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"" +
- "\v\xe4\xc0\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\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\x03\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0" +
- "\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x81-\xa9\x8a\x01\x00\x00\x8a\x01\x00\x00" +
- "\x13\x00\x00\x00America/Porto_VelhoTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff" +
- "\xff\xff\x96\xaa\x82\xe8\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19" +
- "\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff" +
- "\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b" +
- "\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\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\xff\xff\xc4\x18\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03" +
- "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x13\x00\x00\x00America/Puerto_RicoTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2" +
- "\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x13\x9b" +
- "\xb1\xc2\x04\x00\x00\xc2\x04\x00\x00\x14\x00\x00\x00America/Punta_ArenasTZif2\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\x00u" +
- "\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d\xfc\xff\xff\xff\xff\x8f0GE\xff\xff\xff\xff\x9b\\\xe5P\xff\xff\xff\xff\x9f|\xe2\xc5\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^w\xc5\xff\xff\xff\xff" +
- "\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\"4P\xff\xff\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP" +
- "\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff\xff\xd4\x17\xe3@\xff\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff" +
- "\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0" +
- "\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00" +
- "\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0" +
- "\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00" +
- "\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030" +
- "\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00" +
- "'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0" +
- "\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x00" +
- "6\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0" +
- "\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00" +
- "D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@" +
- "\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00" +
- "R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00XC\x86\xb0\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03" +
- "\x02\x03\x04\x02\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05" +
- "\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x06\xff\xff\xbd\x84\x00\x00\xff\xff\xbd\xbb\x00\x04\xff\xff\xb9\xb0\x00\b\xff" +
- "\xff\xc7\xc0\x00\f\xff\xff\xc7\xc0\x01\f\xff\xff\xd5\xd0\x01\x10\xff\xff\xd5\xd0\x00\x10LMT\x00SMT\x00-05\x00-04\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x13\x00\x00\x00America/Rainy_RiverTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xffd䰔\xff\xff\xff\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9búP\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xc2" +
- "\xa0;\x80\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xffӈh\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff" +
- "\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xdb\x00\a\x00\xff\xff\xff\xff\xdb\xc8\\\xf0\xff\xff\xff\xff\xdc" +
- "ޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff" +
- "\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea" +
- "\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff" +
- "\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00" +
- "\x98\r\x00\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0ހ\x00" +
- "\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xb1\x80\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e" +
- "\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I8\x00\x00" +
- "\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c" +
- "\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xcc\x00\x00" +
- "\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*" +
- "\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001gv\x00\x00" +
- "\x00\x00\x002s\x16\x80\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005':\x00\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008" +
- "\xe6\xfe\x00\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9b\x7f\x00\x00" +
- "\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02" +
- "\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\xff\xff\xa4\xec\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00CDT\x00CST\x00CWT\x00CPT\x00\nCST6CDT,M" +
- "3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xdfH\r'\x03\x00\x00'\x03\x00\x00\x14\x00\x00\x00America/Rankin_I" +
- "nletTZif2\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\x00H\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xe7\x8cn\x00\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05" +
- "P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\n\x00\xb1\x80\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00" +
- "\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13" +
- "iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00" +
- "\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!" +
- "\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00" +
- "\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/" +
- "~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00" +
- "\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=" +
- "\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00" +
- "\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\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\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x00\x00\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f-00\x00CDT\x00C" +
- "ST\x00EST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x03u\xf3\xe4\x01\x00\x00\xe4\x01\x00\x00\x0e\x00\x00" +
- "\x00America/RecifeTZif2\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\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaag\xb8\xff\xff" +
- "\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹ" +
- "Y \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff" +
- "\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1d\xc9" +
- "\x8e0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00" +
- "\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x009\xe9\x0f\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o" +
- "\x0e\xa0\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\xff\xff\xdfH\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bL" +
- "MT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u0096dK~\x02\x00\x00~\x02\x00\x00\x0e\x00\x00\x00America/Reg" +
- "inaTZif2\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\x005\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x86\xfd\x93\x1c\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb" +
- "\a\x80\xff\xff\xff\xff\xb5eO\xf0\xff\xff\xff\xff\xb60H\xe0\xff\xff\xff\xff\xb7E1\xf0\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xf0\f\xe0\xff\xff\xff\xff\xbb\x0e0p\xff\xff" +
- "\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xee\x12p\xff\xff\xff\xff\xbd\xb9\v`\xff\xff\xff\xff\xc2r\b\xf0\xff\xff\xff\xff\xc3a\xeb\xe0\xff\xff\xff\xff\xc4Q\xea\xf0\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc61" +
- "\xcc\xf0\xff\xff\xff\xff\xc7!\xaf\xe0\xff\xff\xff\xff\xc8\x1a\xe9p\xff\xff\xff\xff\xc9\n\xcc`\xff\xff\xff\xff\xc9\xfa\xcbp\xff\xff\xff\xff\xca\xea\xae`\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff" +
- "\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3c\x8c\x10\xff\xff\xff\xff\xd4So\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15" +
- "\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xda\xfeÐ\xff\xff\xff\xff\xdb\xc0\x82\x00\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ\x9e\x80\xff\xff\xff\xff\u07be\x87\x90\xff\xff\xff\xff߉\x80\x80\xff\xff" +
- "\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ib\x80\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3ID\x80\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)&\x80\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12" +
- "C\x00\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf2%\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\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\x05\xff\xff\x9d\xe4\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff" +
- "\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0I~D'" +
- "\x03\x00\x00'\x03\x00\x00\x10\x00\x00\x00America/ResoluteTZif2\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\x00H\x00\x00\x00\x04\x00\x00" +
- "\x00\x10\xff\xff\xff\xff\xd5\xfb\x81\x80\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xb2p\x00\x00" +
- "\x00\x00\n\x00\xb1\x80\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99" +
- "t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00" +
- "\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1" +
- "܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00" +
- "\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3" +
- "bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00" +
- "\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6" +
- "\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00" +
- "\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\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\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x00\x00\x00\x00\x00\x00\xff\xff\xb9\xb0" +
- "\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f-00\x00CDT\x00CST\x00EST\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x00\x00America/Rio_BrancoTZif2\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\x1f\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xbaސ@\xff\xff\xff" +
- "\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff\xdfݶP\xff\xff\xff\xff\xe0TO" +
- "@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff" +
- "\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85" +
- "P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\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\x03\x02\xff\xff\xc0p" +
- "\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02" +
- "\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00America/RosarioTZif2\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\x06\x00\x00\x00\x14" +
- "\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1aɰ\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff" +
- "\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\n\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@" +
- "\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff" +
- "ȁ\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xffΰ\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\b0" +
- "\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff" +
- "\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0" +
- "\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00" +
- ")\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\t\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0" +
- "\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04" +
- "\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\fLMT\x00CMT\x00-04\x00-03" +
- "\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x14\x00\x00\x00America/Santa_Isa" +
- "belTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2" +
- "|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\n\xf2\xf0\xff\xff\xff\xff\xcbꍀ\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xffҙ\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff" +
- "\xff\xffؑ\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8'" +
- ",\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00" +
- "\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12y" +
- "s\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00" +
- "\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v" +
- "+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00" +
- "\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3" +
- "`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00" +
- "\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0" +
- "\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00" +
- "\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4" +
- "\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80" +
- "\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00PST\x00PDT\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0," +
- "M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04,2h\x99\x01\x00\x00\x99\x01\x00\x00\x10\x00\x00\x00America/SantaremTZif2\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\x1e\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaazH\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B" +
- "@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff\xff" +
- "\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd3" +
- "0\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00" +
- "\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00H`q@\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\x03\xff" +
- "\xff̸\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x00\x04LMT\x00-03\x00-04\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\"_" +
- "WJ\x05\x00\x00J\x05\x00\x00\x10\x00\x00\x00America/SantiagoTZif3\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\x00\x82\x00\x00\x00\x06" +
- "\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d\xc5\xff\xff\xff\xff\x8f0GE\xff\xff\xff\xff\x9b\\\xe5P\xff\xff\xff\xff\x9f|\xe2\xc5\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^w\xc5\xff\xff\xff\xff\xb1w=@" +
- "\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\"4P\xff\xff\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff" +
- "\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff\xff\xd3\u070f\xc0\xff\xff\xff\xff\xd4\x17\xd50\xff\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@" +
- "\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00" +
- "\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@" +
- "\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00" +
- "\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0" +
- "\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00" +
- " \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0" +
- "\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00" +
- ".\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0" +
- "\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00" +
- "<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0" +
- "\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00" +
- "J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0" +
- "\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00" +
- "Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0" +
- "\x00\x00\x00\x00bI\r\xb0\x00\x00\x00\x00c\x1d]@\x00\x00\x00\x00d(\xef\xb0\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x05\x04\x02\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03" +
- "\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03" +
- "\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\xff\xff\xbd\xbb\x00\x00\xff\xff\xbd\xbb\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff" +
- "\xc7\xc0\x01\f\xff\xff\xd5\xd0\x01\x10LMT\x00SMT\x00-05\x00-04\x00-03\x00\n<-04>4<-03>,M9.1.6/24,M4.1.6/" +
- "24\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x0f(\b=\x01\x00\x00=\x01\x00\x00\x15\x00\x00\x00America/Santo_DomingoTZif2\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\x11\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xffi\x87\x1d\b\xff\xff\xff\xff\xba\xdfB`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff\xff\xfa\xa7\xc3" +
- "@\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00C{\xc8\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x01\xfa\x7fH\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x03\xdd\x04H\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00" +
- "\x00\x05\xbf\x89H\x00\x00\x00\x00\a0\xb4P\x00\x00\x00\x00\a\xa0\xbc\xc8\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:)\xe1`\x01\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05" +
- "\x03\x05\xff\xff\xbex\x00\x00\xff\xff\xbe`\x00\x04\xff\xff\xc7\xc0\x01\t\xff\xff\xb9\xb0\x00\r\xff\xff\xc0\xb8\x01\x11\xff\xff\xc7\xc0\x00\x17LMT\x00SDMT\x00EDT\x00EST\x00-0430" +
- "\x00AST\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d?\xdfڸ\x03\x00\x00\xb8\x03\x00\x00\x11\x00\x00\x00America/Sao_PauloTZ" +
- "if2\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\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaar\xb4\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff" +
- "\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde" +
- " \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4Z\t0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff" +
- "\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05" +
- "\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00" +
- "\x00'!\x0f0\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\r\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4" +
- " \x00\x00\x00\x00.\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00" +
- "\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff" +
- "\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=đ0\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00?\x91\xfe0\x00\x00\x00\x00@.Ҡ\x00\x00\x00\x00A\x86\xf80\x00\x00\x00\x00B\x17\xef \x00\x00\x00" +
- "\x00CQ\xc20\x00\x00\x00\x00C\xf7\xd1 \x00\x00\x00\x00EMS\xb0\x00\x00\x00\x00E\xe0\xed\xa0\x00\x00\x00\x00G\x11\x860\x00\x00\x00\x00G\xb7\x95 \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\x97w" +
- " \x00\x00\x00\x00Jڄ\xb0\x00\x00\x00\x00K\x80\x93\xa0\x00\x00\x00\x00L\xbaf\xb0\x00\x00\x00\x00M`u\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \x00\x00\x00\x00P\x83e0\x00\x00\x00" +
- "\x00Q 9\xa0\x00\x00\x00\x00RcG0\x00\x00\x00\x00S\x00\x1b\xa0\x00\x00\x00\x00TC)0\x00\x00\x00\x00T\xe98 \x00\x00\x00\x00V#\v0\x00\x00\x00\x00V\xc9\x1a \x00\x00\x00\x00X\x02\xed" +
- "0\x00\x00\x00\x00X\xa8\xfc \x00\x00\x00\x00Y\xe2\xcf0\x00\x00\x00\x00Z\x88\xde \x00\x00\x00\x00[\xde`\xb0\x00\x00\x00\x00\\h\xc0 \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\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\xff\xff\xd4L\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-02\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00:\x9a1T\xdf\x01\x00\x00\xdf\x01\x00\x00\x14\x00\x00\x00America/ScoresbysundTZif2\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\x05\x00\x00\x00\x10\xff\xff\xff\xff\x9b\x80L\x18\x00\x00\x00\x00\x13Mn@\x00\x00\x00\x00\x144$\xc0\x00\x00\x00\x00\x15#\xf9\xa0\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%" +
- "\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00" +
- "\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\xff\xff\xebh\x00\x00\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff\xf1\xf0\x00\b\x00\x00\x00\x00\x01\fLMT\x00-02\x00-" +
- "01\x00+00\x00\n<-01>1<+00>,M3.5.0/0,M10.5.0/1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00" +
- "\x00\x12\x04\x00\x00\x10\x00\x00\x00America/ShiprockTZif2\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\x00a\x00\x00\x00\x05\x00\x00\x00\x14" +
- "\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff" +
- "\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90" +
- "\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00" +
- "\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ" +
- "\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00" +
- "\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10" +
- "\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00" +
- "\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00" +
- "\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00" +
- "*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10" +
- "\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x00" +
- "8\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00" +
- "\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\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\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\xff\xff\x9d\x94\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab" +
- "\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x81{\xc1\x92\xbc\x03\x00\x00\xbc\x03\x00\x00\r\x00\x00\x00America/SitkaTZif2\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\x00S\x00\x00\x00" +
- "\t\x00\x00\x00\"\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x873\x99\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*" +
- "\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00" +
- "\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91" +
- "\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00" +
- "\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B" +
- "\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00" +
- "\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e" +
- " \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00" +
- "\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF" +
- "0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00" +
- "\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{" +
- "\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x06\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a" +
- "\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x00\x00ҧ\x00\x00\xff\xff\x81'\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\b\xff\xff\x9d\x90" +
- "\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x81p\x00\x14\xff\xff\x8f\x80\x01\x18\xff\xff\x81p\x00\x1dLMT\x00PST\x00PWT\x00PPT\x00PDT\x00YST\x00AKDT\x00AKST\x00" +
- "\nAKST9AKDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00Amer" +
- "ica/St_BarthelemyTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹" +
- "\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00" +
- "APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xb2\x0e\x19V\a\x00\x00V\a\x00\x00\x10\x00\x00\x00America/St_Johns" +
- "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\xbb\x00\x00\x00\b\x00\x00\x00\x19\xff\xff\xff\xff^=4\xec\xff\xff\xff\xff\x9c\xcfb\f\xff\xff\xff\xff\x9d\xa4\xe6\xfc\xff" +
- "\xff\xff\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xa0\xb6\x88\xdc\xff\xff\xff\xff\xa18\xffL\xff\xff\xff\xff\xa2\x95\x19\\\xff\xff\xff\xff\xa3\x84\xfcL\xff\xff\xff\xff\xa4t\xfb\\\xff\xff\xff\xff\xa5" +
- "d\xdeL\xff\xff\xff\xff\xa6^\x17\xdc\xff\xff\xff\xff\xa7D\xc0L\xff\xff\xff\xff\xa8=\xf9\xdc\xff\xff\xff\xff\xa9$\xa2L\xff\xff\xff\xff\xaa\x1d\xdb\xdc\xff\xff\xff\xff\xab\x04\x84L\xff\xff\xff\xff\xab\xfd\xbd\xdc\xff" +
- "\xff\xff\xff\xac\xe4fL\xff\xff\xff\xff\xadݟ\xdc\xff\xff\xff\xff\xae͂\xcc\xff\xff\xff\xff\xaf\xbd\x81\xdc\xff\xff\xff\xff\xb0\xadd\xcc\xff\xff\xff\xff\xb1\xa6\x9e\\\xff\xff\xff\xff\xb2\x8dF\xcc\xff\xff\xff\xff\xb3" +
- "\x86\x80\\\xff\xff\xff\xff\xb4m(\xcc\xff\xff\xff\xff\xb5fb\\\xff\xff\xff\xff\xb6M\n\xcc\xff\xff\xff\xff\xb7FD\\\xff\xff\xff\xff\xb8,\xec\xcc\xff\xff\xff\xff\xb9&&\\\xff\xff\xff\xff\xba\x16\tL\xff" +
- "\xff\xff\xff\xbb\x0fB\xdc\xff\xff\xff\xff\xbb\xf5\xebL\xff\xff\xff\xff\xbc\xef$\xdc\xff\xff\xff\xff\xbd\xd5\xcdL\xff\xff\xff\xff\xbe\x9eMl\xff\xff\xff\xff\xbe\xcf\x06\xa8\xff\xff\xff\xff\xbf\xb5\xaf\x18\xff\xff\xff\xff\xc0" +
- "\xb818\xff\xff\xff\xff\xc1y\xef\xa8\xff\xff\xff\xff\u0098\x138\xff\xff\xff\xff\xc3YѨ\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff" +
- "\xff\xff\xff\xc8@\xf3\xb8\xff\xff\xff\xff\xc9\x02\xb2(\xff\xff\xff\xff\xca ո\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xff\xd3" +
- "\x88D\xd8\xff\xff\xff\xff\xd4J\x03H\xff\xff\xff\xff\xd5h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\b\xd8\xff\xff\xff\xff\xd8\t\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff" +
- "\xff\xff\xff\xdb\x11\aX\xff\xff\xff\xff\xdb\xd2\xc5\xc8\xff\xff\xff\xff\xdc\xdetX\xff\xff\xff\xffݩmH\xff\xff\xff\xff\u07beVX\xff\xff\xff\xff߉OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1" +
- "i1H\xff\xff\xff\xff\xe2~\x1aX\xff\xff\xff\xff\xe3I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff" +
- "\xff\xff\xff\xe8\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06\xdc\xd8\xff\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff챷\xc8\xff\xff\xff\xff\xedƠ\xd8\xff\xff\xff\xff\ueffeH\xff\xff\xff\xff\xef" +
- "\xaf\xbdX\xff\xff\xff\xff\xf0\x9f\xa0H\xff\xff\xff\xff\xf1\x8f\x9fX\xff\xff\xff\xff\xf2\x7f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff" +
- "\xff\xff\xff\xf7/EX\xff\xff\xff\xff\xf8(b\xc8\xff\xff\xff\xff\xf9\x0f'X\xff\xff\xff\xff\xfa\bD\xc8\xff\xff\xff\xff\xfa\xf8C\xd8\xff\xff\xff\xff\xfb\xe8&\xc8\xff\xff\xff\xff\xfc\xd8%\xd8\xff\xff\xff\xff\xfd" +
- "\xc8\b\xc8\xff\xff\xff\xff\xfe\xb8\a\xd8\xff\xff\xff\xff\xff\xa7\xea\xc8\x00\x00\x00\x00\x00\x97\xe9\xd8\x00\x00\x00\x00\x01\x87\xcc\xc8\x00\x00\x00\x00\x02w\xcb\xd8\x00\x00\x00\x00\x03p\xe9H\x00\x00\x00\x00\x04`\xe8X\x00" +
- "\x00\x00\x00\x05P\xcbH\x00\x00\x00\x00\x06@\xcaX\x00\x00\x00\x00\a0\xadH\x00\x00\x00\x00\b \xacX\x00\x00\x00\x00\t\x10\x8fH\x00\x00\x00\x00\n\x00\x8eX\x00\x00\x00\x00\n\xf0qH\x00\x00\x00\x00\v" +
- "\xe0pX\x00\x00\x00\x00\fٍ\xc8\x00\x00\x00\x00\r\xc0RX\x00\x00\x00\x00\x0e\xb9o\xc8\x00\x00\x00\x00\x0f\xa9n\xd8\x00\x00\x00\x00\x10\x99Q\xc8\x00\x00\x00\x00\x11\x89P\xd8\x00\x00\x00\x00\x12y3\xc8\x00" +
- "\x00\x00\x00\x13i2\xd8\x00\x00\x00\x00\x14Y\x15\xc8\x00\x00\x00\x00\x15I\x14\xd8\x00\x00\x00\x00\x168\xf7\xc8\x00\x00\x00\x00\x17(\xf6\xd8\x00\x00\x00\x00\x18\"\x14H\x00\x00\x00\x00\x19\b\xd8\xd8\x00\x00\x00\x00\x1a" +
- "\x01\xf6H\x00\x00\x00\x00\x1a\xf1\xf5X\x00\x00\x00\x00\x1b\xe1\xd8H\x00\x00\x00\x00\x1c\xd1\xd7X\x00\x00\x00\x00\x1d\xc1\xbaH\x00\x00\x00\x00\x1e\xb1\xb9X\x00\x00\x00\x00\x1f\xa1\x9cH\x00\x00\x00\x00 u\xcf\xf4\x00" +
- "\x00\x00\x00!\x81bd\x00\x00\x00\x00\"U\xb1\xf4\x00\x00\x00\x00#jp\xd4\x00\x00\x00\x00$5\x93\xf4\x00\x00\x00\x00%J`\xe4\x00\x00\x00\x00&\x15u\xf4\x00\x00\x00\x00'*B\xe4\x00\x00\x00\x00'" +
- "\xfe\x92t\x00\x00\x00\x00)\n$\xe4\x00\x00\x00\x00)\xdett\x00\x00\x00\x00*\xea\x06\xe4\x00\x00\x00\x00+\xbeVt\x00\x00\x00\x00,\xd3#d\x00\x00\x00\x00-\x9e8t\x00\x00\x00\x00.\xb3\x05d\x00" +
- "\x00\x00\x00/~\x1at\x00\x00\x00\x000\x92\xe7d\x00\x00\x00\x001g6\xf4\x00\x00\x00\x002r\xc9d\x00\x00\x00\x003G\x18\xf4\x00\x00\x00\x004R\xabd\x00\x00\x00\x005&\xfa\xf4\x00\x00\x00\x006" +
- "2\x8dd\x00\x00\x00\x007\x06\xdc\xf4\x00\x00\x00\x008\x1b\xa9\xe4\x00\x00\x00\x008\xe6\xbe\xf4\x00\x00\x00\x009\xfb\x8b\xe4\x00\x00\x00\x00:Ơ\xf4\x00\x00\x00\x00;\xdbm\xe4\x00\x00\x00\x00<\xaf\xbdt\x00" +
- "\x00\x00\x00=\xbbO\xe4\x00\x00\x00\x00>\x8f\x9ft\x00\x00\x00\x00?\x9b1\xe4\x00\x00\x00\x00@o\x81t\x00\x00\x00\x00A\x84Nd\x00\x00\x00\x00BOct\x00\x00\x00\x00Cd0d\x00\x00\x00\x00D" +
- "/Et\x00\x00\x00\x00ED\x12d\x00\x00\x00\x00E\xf3w\xf4\x00\x00\x00\x00G-.\xe4\x00\x00\x00\x00G\xd3Y\xf4\x00\x00\x00\x00I\r\x10\xe4\x00\x00\x00\x00I\xb3;\xf4\x00\x00\x00\x00J\xec\xf2\xe4\x00" +
- "\x00\x00\x00K\x9cXt\x00\x00\x00\x00L\xd6\x0fd\x00\x00\x00\x00M|:t\x00\x00\x00\x00N\xb6\rH\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\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\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\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xffΔ\x00\x00\xff\xffܤ\x01\x04\xff\xffΔ\x00\b\xff\xff\xdc\xd8" +
- "\x01\x04\xff\xff\xce\xc8\x00\b\xff\xff\xdc\xd8\x01\f\xff\xff\xdc\xd8\x01\x10\xff\xff\xea\xe8\x01\x14LMT\x00NDT\x00NST\x00NPT\x00NWT\x00NDDT\x00\nNST3:30N" +
- "DT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00America/St_K" +
- "ittsTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2" +
- "#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00America/St_LuciaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff" +
- "\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9" +
- "*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x11\x00\x00\x00America/St_ThomasTZif2\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\x04\x00\x00" +
- "\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b" +
- "\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00Am" +
- "erica/St_VincentTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff" +
- "\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00A" +
- "PT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xd8\x19\x9dp\x01\x00\x00p\x01\x00\x00\x15\x00\x00\x00America/Swift_Cur" +
- "rentTZif2\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\x17\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x86\xfd\x96\x18\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f" +
- "\xbb\a\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3v\x01\x10\xff\xff\xff\xff\xd4So\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff" +
- "\xff\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe9\x17\x0f\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec" +
- "\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xcb\x00\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xad\x00\x00\x00\x00\x00\x04a\x19\x90\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\x05\xff\xff\x9a\xe8\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MP" +
- "T\x00CST\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x13z\xe2\xc2\x00\x00\x00\xc2\x00\x00\x00\x13\x00\x00\x00America/Tegucigalp" +
- "aTZif2\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\a\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa4LKD\x00\x00\x00\x00 \x9a\xdc\xe0\x00\x00\x00\x00!\\\x9bP" +
- "\x00\x00\x00\x00\"z\xbe\xe0\x00\x00\x00\x00#<}P\x00\x00\x00\x00D]\x8c\xe0\x00\x00\x00\x00D\xd6\xc8\xd0\x02\x01\x02\x01\x02\x01\x02\xff\xff\xae<\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT" +
- "\x00CDT\x00CST\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\r\xf7\xd3\xc7\x01\x00\x00\xc7\x01\x00\x00\r\x00\x00\x00America/ThuleTZ" +
- "if2\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\x03\x00\x00\x00\f\xff\xff\xff\xff\x9b\x80w\xfc\x00\x00\x00\x00'\xf5z\xe0\x00\x00\x00\x00(\xe5]\xd0\x00\x00\x00" +
- "\x00)\xd5\\\xe0\x00\x00\x00\x00*\xc5?\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\n" +
- "P\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00" +
- "\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2" +
- "`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00" +
- "\x00E\xf3\x9a\xe0\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\xff\xff\xbf\x84\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT" +
- "\x00ADT\x00AST\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x13" +
- "\x00\x00\x00America/Thunder_BayTZif2\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\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff" +
- "\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]" +
- "\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff" +
- "\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ" +
- "`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff" +
- "\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b" +
- "\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff" +
- "\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3" +
- "\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdcމp\xff\xff\xff" +
- "\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11" +
- "p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff" +
- "\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97" +
- "`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff" +
- "\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe" +
- "\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00" +
- "\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84" +
- "\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00" +
- "\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xec" +
- "p\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00" +
- "\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7" +
- "\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00" +
- "\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef" +
- "\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00" +
- "\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9" +
- "\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2.0,M11.1.0\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x0f\x00\x00\x00America/TijuanaTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff" +
- "\xff\xff\xff\xb8\n\xf2\xf0\xff\xff\xff\xff\xcbꍀ\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xffҙ\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff\xff\xffؑ\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3" +
- "IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff" +
- "\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r" +
- "\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00" +
- "\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b" +
- "\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00" +
- "\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)" +
- "\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00" +
- "\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008" +
- "\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00" +
- "\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F" +
- "\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01" +
- "\x14LMT\x00MST\x00PST\x00PDT\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x00\x00America/TorontoTZif2\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" +
- "\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff" +
- "\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9" +
- "p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff" +
- "\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0" +
- "`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff" +
- "\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|" +
- "p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff" +
- "\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t" +
- "`\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff" +
- "\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1" +
- "\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff" +
- "\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w" +
- "\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff" +
- "\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdf" +
- "p\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00" +
- "\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*" +
- "\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00" +
- "\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2" +
- "\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00" +
- "\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18" +
- "`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00" +
- "\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0" +
- "p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00" +
- "\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5" +
- "\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2" +
- ".0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America/TortolaTZif" +
- "2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2" +
- "`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00U9#\xbe2\x05\x00\x002\x05\x00\x00\x11\x00\x00\x00America/VancouverTZif2\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\x81\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^=v\xec\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2" +
- "a&\x10\xff\xff\xff\xff\xd3v\x0f \xff\xff\xff\xff\xd4A\b\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff" +
- "\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfeѠ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\u07b3\xa0\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x95\xa0\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0" +
- "\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff" +
- "\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee" +
- "\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff" +
- "\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc" +
- "\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00" +
- "\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\b \xeb\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\n\x00͠\x00\x00\x00\x00\n" +
- "\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00" +
- "\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19" +
- "\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00" +
- "\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'" +
- "*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00" +
- "\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005" +
- "'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00" +
- "\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00C" +
- "d\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x8c\x94\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f" +
- "\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0e\x00\x00\x00America/VirginTZif2\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" +
- "\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz敹\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\a\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5" +
- "\xd0\x01\b\xff\xff\xd5\xd0\x01\fLMT\x00AST\x00APT\x00AWT\x00\nAST4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x1d\xee\x91\x05\x04\x00\x00\x05\x04\x00\x00\x12\x00\x00" +
- "\x00America/WhitehorseTZif2\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\t\x00\x00\x00%\xff\xff\xff\xff}\x86" +
- "\x8a\x9c\xff\xff\xff\xff\x9e\xb8˰\xff\xff\xff\xff\x9f\xbb#\xa0\xff\xff\xff\xff\xa0\xd0\f\xb0\xff\xff\xff\xff\xa1\xa2Ҁ\xff\xff\xff\xffˉ(\xb0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff" +
- "\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf8ń\x90\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)" +
- "6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00" +
- "\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J" +
- "\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00" +
- "\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003G" +
- "t \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00" +
- "\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84" +
- "\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00Gӵ \x00\x00" +
- "\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\\" +
- "w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90\x00\x00\x00\x00T\xfc\x1d\xa0\x00\x00\x00\x00V5Ԑ\x00\x00" +
- "\x00\x00V\xe5: \x00\x00\x00\x00X\x1e\xf1\x10\x00\x00\x00\x00X\xc5\x1c \x00\x00\x00\x00Y\xfe\xd3\x10\x00\x00\x00\x00Z\xa4\xfe \x00\x00\x00\x00[\u07b5\x10\x00\x00\x00\x00\\\x84\xe0 \x00\x00\x00\x00]\xbe" +
- "\x97\x10\x00\x00\x00\x00^d\xc2 \x00\x00\x00\x00_\x9e\\\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x02\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" +
- "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\b\xff\xff\x81d\x00\x00\xff\xff\x8f" +
- "\x80\x01\x04\xff\xff\x81p\x00\b\xff\xff\x8f\x80\x01\f\xff\xff\x8f\x80\x01\x10\xff\xff\x9d\x90\x01\x14\xff\xff\x8f\x80\x00\x19\xff\xff\x9d\x90\x01\x1d\xff\xff\x9d\x90\x00!LMT\x00YDT\x00YST\x00YWT" +
- "\x00YPT\x00YDDT\x00PST\x00PDT\x00MST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x10\x00\x00\x00Am" +
- "erica/WinnipegTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xffd䰔\xff\xff\xff" +
- "\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9búP\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\u00a0;\x80\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4" +
- "p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xffӈh\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff" +
- "\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xdb\x00\a\x00\xff\xff\xff\xff\xdb\xc8\\\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉r" +
- "p\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff" +
- "\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4" +
- "\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff" +
- "\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x1a" +
- "\x80\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b π\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xb1\x80\x00\x00\x00" +
- "\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89t" +
- "\x00\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00" +
- "\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xcd" +
- "\x80\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00" +
- "\x00'*\x90\x00\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9ew" +
- "\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xf8\x80\x00\x00\x00" +
- "\x005':\x00\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;ۻ" +
- "\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00" +
- "\x00Cd}\x80\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa4\xec\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff" +
- "\xb9\xb0\x01\x10LMT\x00CDT\x00CST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00,\xdb~\xab\xb2\x03\x00\x00\xb2\x03\x00\x00\x0f\x00\x00\x00America/YakutatTZif2\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\x00S" +
- "\x00\x00\x00\b\x00\x00\x00\x1e\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x877\xbf\xff\xff\xff\xffˉ(\xb0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xfe\xb8U0\xff\xff\xff\xff" +
- "\xff\xa88 \x00\x00\x00\x00\x00\x9870\x00\x00\x00\x00\x01\x88\x1a \x00\x00\x00\x00\x02x\x190\x00\x00\x00\x00\x03q6\xa0\x00\x00\x00\x00\x04a5\xb0\x00\x00\x00\x00\x05Q\x18\xa0\x00\x00\x00\x00\x06A\x17\xb0" +
- "\x00\x00\x00\x00\a0\xfa\xa0\x00\x00\x00\x00\a\x8dQ\xb0\x00\x00\x00\x00\t\x10ܠ\x00\x00\x00\x00\t\xad\xcd0\x00\x00\x00\x00\n\xf0\xbe\xa0\x00\x00\x00\x00\v\u0f70\x00\x00\x00\x00\f\xd9\xdb \x00\x00\x00\x00" +
- "\r\xc0\x9f\xb0\x00\x00\x00\x00\x0e\xb9\xbd \x00\x00\x00\x00\x0f\xa9\xbc0\x00\x00\x00\x00\x10\x99\x9f \x00\x00\x00\x00\x11\x89\x9e0\x00\x00\x00\x00\x12y\x81 \x00\x00\x00\x00\x13i\x800\x00\x00\x00\x00\x14Yc " +
- "\x00\x00\x00\x00\x15Ib0\x00\x00\x00\x00\x169E \x00\x00\x00\x00\x17)D0\x00\x00\x00\x00\x18\"a\xa0\x00\x00\x00\x00\x19\t&0\x00\x00\x00\x00\x1a\x02C\xa0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00" +
- "\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ" +
- "\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00" +
- ")\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0" +
- "\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x00" +
- "7\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 " +
- "\x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00" +
- "ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a" +
- "\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\x00\x00\u0381\x00\x00\xff\xff}\x01\x00\x00\xff\xff\x81p\x00\x04\xff\xff\x8f\x80\x01\b\xff" +
- "\xff\x8f\x80\x01\f\xff\xff\x8f\x80\x01\x10\xff\xff\x8f\x80\x01\x14\xff\xff\x81p\x00\x19LMT\x00YST\x00YWT\x00YPT\x00YDT\x00AKDT\x00AKST\x00\nAKST9A" +
- "KDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\a\a\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x13\x00\x00\x00America/Yel" +
- "lowknifeTZif2\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\x00T" +
- "Zif2\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\x00Y\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x88\xde\xce\xe0\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff" +
- "\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x98\x91\x90\xff\xff\xff\xff\xa0҅\x80\xff\xff\xff\xff\xa2\x8a\xe8\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4jʐ\xff\xff\xff\xff\xa55À\xff\xff\xff\xff\xa6" +
- "S\xe7\x10\xff\xff\xff\xff\xa7\x15\xa5\x80\xff\xff\xff\xff\xa83\xc9\x10\xff\xff\xff\xff\xa8\xfe\xc2\x00\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff" +
- "\xff\xff\xff\xd6 \xdc\x00\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b ݐ\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\n" +
- "\x00\xbf\x90\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00" +
- "\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18" +
- "\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00" +
- "\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&" +
- "\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00" +
- "\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004" +
- "R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00" +
- "\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00B" +
- "O\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\xff\xff\x95\xa0\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST7M" +
- "DT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xddzAh\xf3\x00\x00\x00\xf3\x00\x00\x00\x10\x00\x00\x00Antarctica/C" +
- "aseyTZif2\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\f\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xfe\x1è\x00\x00\x00\x00J\xda\x06 \x00\x00\x00\x00K" +
- "\x8f\xca\xf0\x00\x00\x00\x00N\xa9\x9c \x00\x00\x00\x00OC͐\x00\x00\x00\x00X\n;\x80\x00\x00\x00\x00Z\xa4\x0f\x10\x00\x00\x00\x00[\xb9\x14@\x00\x00\x00\x00\\\x8d\x1d\x80\x00\x00\x00\x00]\x96E0\x00" +
- "\x00\x00\x00^c\xc5\x00\x00\x00\x00\x00_x\xa0<\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x9a\xb0\x00\b-00\x00+08\x00+11\x00\n<+" +
- "11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xea\x06\xd3\xc5\x00\x00\x00\xc5\x00\x00\x00\x10\x00\x00\x00Antarctica/DavisTZif2\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\a\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xe7\x9c@\x00\xff\xff\xff\xff\xf6G\xdf\x10\xff\xff\xff\xff\xfeG\xab\x00\x00\x00\x00\x00J\xda\x140" +
- "\x00\x00\x00\x00K\x97\xfa@\x00\x00\x00\x00N\xa9\xaa0\x00\x00\x00\x00OC\xf7\xc0\x01\x00\x01\x02\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00bp\x00\x04\x00\x00FP\x00\b-00\x00+07\x00+05" +
- "\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x19\x00\x00\x00Antarctica/DumontDUr" +
- "villeTZif2\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\x00TZif" +
- "2\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\x02\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV\xb6Z\b\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00" +
- "\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\tLMT\x00PMMT\x00+10\x00\n<+10>-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\x84J]\xd0\x03\x00" +
- "\x00\xd0\x03\x00\x00\x14\x00\x00\x00Antarctica/MacquarieTZif2\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\x03" +
- "\x00\x00\x00\x0e\xff\xff\xff\xff|\x05\x16\x00\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xa0\x87\xb4`\xff\xff\xff\xff\xd7\fh\x00\xff\xff\xff\xff\xfb\u008d\x00\xff\xff\xff\xff\xfc\xb2~\x00" +
- "\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00" +
- "\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80" +
- "\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00" +
- "\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00" +
- "\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00" +
- " Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00" +
- "\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00" +
- ".\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80" +
- "\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00" +
- "<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80" +
- "\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00\x00Iׄ\x00\x00\x00\x00\x00" +
- "J\xc7u\x00\x00\x00\x00\x00M\x97H\x00\x01\x02\x01\x00\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\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\x00\x00\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x01" +
- "\t-00\x00AEST\x00AEDT\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7" +
- "N\xab\x8b\x98\x00\x00\x00\x98\x00\x00\x00\x11\x00\x00\x00Antarctica/MawsonTZif2\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\x02\x00" +
- "\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xe2 2\x80\x00\x00\x00\x00J\xda\"@\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00T`\x00\x04\x00\x00FP\x00\b-00\x00+06\x00+05\x00\n<+05" +
- ">-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x12\x00\x00\x00Antarctica/McMurdoTZif2\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\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff" +
- "\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9" +
- "\xf8mh\xff\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff" +
- "\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8" +
- ",o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00" +
- "\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14" +
- "XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00" +
- "\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"" +
- "0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00" +
- "\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000" +
- "mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00" +
- "\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>" +
- "s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00" +
- "\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\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\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf" +
- "\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\nNZST-12NZDT,M" +
- "9.5.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95{\xf3\xa9w\x03\x00\x00w\x03\x00\x00\x11\x00\x00\x00Antarctica/Palm" +
- "erTZif2\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\x00R\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xf6\x98\xad\x00\xff\xff\xff\xff\xf6柰\xff\xff\xff\xff\xf8\x13C" +
- "\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff" +
- "\xff\xff\x8c4@\x00\x00\x00\x00\a\xa3J\xb0\x00\x00\x00\x00\b$o\xa0\x00\x00\x00\x00\x170\xbc\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18" +
- "\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00" +
- "\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4" +
- "\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00" +
- "\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06\xd5" +
- "\xb0\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00" +
- "\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2" +
- "@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00" +
- "\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r" +
- "\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00XC\x86\xb0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x00\x00\x00\x00\x00" +
- "\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xe3\xe0\x01\f\xff\xff\xd5\xd0\x00\b-00\x00-04\x00-03\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00Ɖ\xf71\x84\x00\x00\x00\x84\x00\x00\x00\x12\x00\x00\x00Antarctica/RotheraTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\x00\x00\x00\x00\r\x02-\x00\x01\x00\x00\x00\x00\x00\x00\xff\xff\xd5\xd0\x00\x04-00\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x15\x00\x00\x00Antarctica/South_PoleTZif2\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\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4" +
- "X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba̧\xe0\xff" +
- "\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\xc2" +
- "\x83\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff" +
- "\xff\xff\xff\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e" +
- "\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00" +
- "\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c" +
- "\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00" +
- "\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*" +
- "ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00" +
- "\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008" +
- "Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00" +
- "\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F" +
- "\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\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\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8" +
- "\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\nNZST-12NZDT,M9.5.0,M4.1.0" +
- "/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x10\x00\x00\x00Antarctica/SyowaTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\n<+03>-" +
- "3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\xc8P7\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00Antarctica/TrollTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\x00\x00\x00\x00B\rG\x00\x00\x00\x00\x00BF\x05\x90\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x00\x00\x00\b-" +
- "00\x00+02\x00+00\x00\n<+00>0<+02>-2,M3.5.0/1,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B" +
- "\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\x11\x00\x00\x00Antarctica/VostokTZif2\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\x01\x00" +
- "\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xb0\xfe\xbad\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17" +
- "S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x13\x00\x00\x00Arctic/LongyearbyenTZif2\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00" +
- "\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad" +
- "\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\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\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CES" +
- "T,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\t\x00\x00\x00Asia/AdenTZ" +
- "if2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+0" +
- "3\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xdd\\2a\x02\x00\x00a\x02\x00\x00\v\x00\x00\x00Asia/AlmatyTZif2\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\x003\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19{\xdc\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00" +
- "\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d" +
- "\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00" +
- "\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*" +
- "\xc4\xc1@\x00\x00\x00\x00+\xb4\xb2@\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00" +
- "\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008" +
- "\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00" +
- "\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x00\x00H$\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x01\fLMT\x00+05\x00+07\x00+06\x00\n<+06>-6" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\rs\xad\xa0\x03\x00\x00\xa0\x03\x00\x00\n\x00\x00\x00Asia/AmmanTZif2\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\x00W\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xb6\xa3\xd6\xd0\x00\x00\x00\x00\x06ry\xe0\x00\x00\x00\x00\a\f\xabP\x00\x00\x00\x00\b$7`\x00\x00\x00\x00\b\xed\xde\xd0\x00\x00\x00\x00" +
- "\n\x05j\xe0\x00\x00\x00\x00\n\xcf\x12P\x00\x00\x00\x00\v\xe7\xef\xe0\x00\x00\x00\x00\f\xdau\xd0\x00\x00\x00\x00\r\xc9#`\x00\x00\x00\x00\x0e\x92\xca\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10r\xac\xd0" +
- "\x00\x00\x00\x00\x1c\xad\xd5`\x00\x00\x00\x00\x1d\x9f\t\xd0\x00\x00\x00\x00\x1e\x92\xfd`\x00\x00\x00\x00\x1f\x82\xe0P\x00\x00\x00\x00 r\xdf`\x00\x00\x00\x00!b\xc2P\x00\x00\x00\x00\"R\xc1`\x00\x00\x00\x00" +
- "#K\xde\xd0\x00\x00\x00\x00$d\xbc`\x00\x00\x00\x00%+\xc0\xd0\x00\x00\x00\x00&7o`\x00\x00\x00\x00'\v\xa2\xd0\x00\x00\x00\x00(\vs\xe0\x00\x00\x00\x00(\xe2JP\x00\x00\x00\x00)\xe4\xbe`" +
- "\x00\x00\x00\x00*\xcbf\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\xabH\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00.x\xb5\xd0\x00\x00\x00\x00/\x84d`\x00\x00\x00\x000X\xa5\xe0\x00\x00\x00\x00" +
- "1dF`\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\x007z\x93`\x00\x00\x00\x007\xea\xa2\xe0" +
- "\x00\x00\x00\x008\xe2|\xe0\x00\x00\x00\x009ӿ`\x00\x00\x00\x00:\xc2^\xe0\x00\x00\x00\x00;\xb3\xa1`\x00\x00\x00\x00<\xa3\x92`\x00\x00\x00\x00=\x93\x83`\x00\x00\x00\x00>\x83t`\x00\x00\x00\x00" +
- "?\x98O`\x00\x00\x00\x00@cV`\x00\x00\x00\x00An\xf6\xe0\x00\x00\x00\x00BLr\xe0\x00\x00\x00\x00C<c\xe0\x00\x00\x00\x00D,T\xe0\x00\x00\x00\x00EA/\xe0\x00\x00\x00\x00F\f6\xe0" +
- "\x00\x00\x00\x00G!\x11\xe0\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00I\n.`\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xea\x10`\x00\x00\x00\x00K\xab\xdc\xe0\x00\x00\x00\x00L\xc9\xf2`\x00\x00\x00\x00" +
- "M\x94\xf9`\x00\x00\x00\x00N\xa9\xd4`\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00R\xb3^P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TR\xb4\xe0\x00\x00\x00\x00U\x14\x81`\x00\x00\x00\x00V2\x96\xe0" +
- "\x00\x00\x00\x00V\xfd\x9d\xe0\x00\x00\x00\x00X\x12x\xe0\x00\x00\x00\x00X\xdd\x7f\xe0\x00\x00\x00\x00Y\xf2Z\xe0\x00\x00\x00\x00Z\xbda\xe0\x00\x00\x00\x00[\xd2<\xe0\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00" +
- "]\xb2\x1e\xe0\x00\x00\x00\x00^}%\xe0\x00\x00\x00\x00_\x9b;`\x00\x00\x00\x00`]\a\xe0\x00\x00\x00\x00a{\x1d`\x00\x00\x00\x00b\x17\xff\xe0\x00\x00\x00\x00cZ\xff`\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\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\x03\x00\x00!\xb0\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00\rLMT\x00EEST\x00EET\x00+03\x00" +
- "\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xe0\xe7!\xe7\x02\x00\x00\xe7\x02\x00\x00\v\x00\x00\x00Asia/AnadyrTZif2\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\a\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x1d\x9c\xff\xff\xff\xff\xb5\xa3\x8c\xc0\x00\x00\x00\x00\x15'\x1b0\x00\x00\x00\x00\x16\x18O\xa0\x00\x00\x00" +
- "\x00\x17\bN\xb0\x00\x00\x00\x00\x17\xf9\x910\x00\x00\x00\x00\x18\xe9\x90@\x00\x00\x00\x00\x19\xdaİ\x00\x00\x00\x00\x1a\xcc\x15@\x00\x00\x00\x00\x1b\xbc\"`\x00\x00\x00\x00\x1c\xac\x13`\x00\x00\x00\x00\x1d\x9c\x04" +
- "`\x00\x00\x00\x00\x1e\x8b\xf5`\x00\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k\xd7`\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\"K\xb9`\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\x9b`\x00\x00\x00" +
- "\x00%\x1b\x8c`\x00\x00\x00\x00&\v}`\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00'\xf4\x99\xe0\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)x@\xf0\x00\x00\x00\x00)\xd4{\xe0\x00\x00\x00\x00*\xc4l" +
- "\xe0\x00\x00\x00\x00+\xb4]\xe0\x00\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-\x94?\xe0\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t!\xe0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]>`\x00\x00\x00" +
- "\x002r\x19`\x00\x00\x00\x003= `\x00\x00\x00\x004Q\xfb`\x00\x00\x00\x005\x1d\x02`\x00\x00\x00\x0061\xdd`\x00\x00\x00\x006\xfc\xe4`\x00\x00\x00\x008\x1a\xf9\xe0\x00\x00\x00\x008\xdc\xc6" +
- "`\x00\x00\x00\x009\xfa\xdb\xe0\x00\x00\x00\x00:\xbc\xa8`\x00\x00\x00\x00;ڽ\xe0\x00\x00\x00\x00<\xa5\xc4\xe0\x00\x00\x00\x00=\xba\x9f\xe0\x00\x00\x00\x00>\x85\xa6\xe0\x00\x00\x00\x00?\x9a\x81\xe0\x00\x00\x00" +
- "\x00@e\x88\xe0\x00\x00\x00\x00A\x83\x9e`\x00\x00\x00\x00BEj\xe0\x00\x00\x00\x00Cc\x80`\x00\x00\x00\x00D%L\xe0\x00\x00\x00\x00ECb`\x00\x00\x00\x00F\x05.\xe0\x00\x00\x00\x00G#D" +
- "`\x00\x00\x00\x00G\xeeK`\x00\x00\x00\x00I\x03&`\x00\x00\x00\x00I\xce-`\x00\x00\x00\x00J\xe3\b`\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x01\x03\x02" +
- "\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x05\x06\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x05\x06" +
- "\x01\x00\x00\xa6d\x00\x00\x00\x00\xa8\xc0\x00\x04\x00\x00\xc4\xe0\x01\b\x00\x00\xb6\xd0\x00\f\x00\x00\xb6\xd0\x01\f\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\x10LMT\x00+12\x00+14\x00+13\x00+" +
- "11\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x81\x18G^\x02\x00\x00^\x02\x00\x00\n\x00\x00\x00Asia/AqtauTZif2\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\x002\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x94\xe0\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xb1 " +
- "\x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00" +
- "\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0" +
- "\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00" +
- "+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0" +
- "\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x00" +
- "9\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`" +
- "\x00\x00\x00\x00A\x84\x0e\xe0\x01\x02\x03\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\x01\x02\x04\x02\x04\x02\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x02\x00\x00" +
- "/ \x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x00\f\x00\x00T`\x01\f\x00\x00FP\x01\bLMT\x00+04\x00+05\x00+06\x00\n<+05>-5\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb\xfa\xb5\xbeg\x02\x00\x00g\x02\x00\x00\v\x00\x00\x00Asia/AqtobeTZif2\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\x003\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8eh\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17" +
- "\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00" +
- "\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&" +
- "\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00" +
- "\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003" +
- "=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\\P\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00" +
- "\x00\x00\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A" +
- "\x84\x00\xd0\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x005\x98\x00\x00" +
- "\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x01\bLMT\x00+04\x00+05\x00+06\x00\n<+05>-5\nPK\x03\x04\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x1bb2w\x01\x00\x00w\x01\x00\x00\r\x00\x00\x00Asia/AshgabatTZif2\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\x19\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8dD\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xbf0\x00\x00\x00\x00\x17\xf9\xf3" +
- "\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00" +
- "\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf" +
- "\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x00" +
- "6\xbc\x00\x00\x00\x008@\x00\x04\x00\x00T`\x01\b\x00\x00FP\x00\f\x00\x00FP\x01\fLMT\x00+04\x00+06\x00+05\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00e\x1bb2w\x01\x00\x00w\x01\x00\x00\x0e\x00\x00\x00Asia/AshkhabadTZif2\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\x19\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8dD\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xbf0\x00\x00\x00\x00\x17\xf9\xf3\xa0" +
- "\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00" +
- "\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0" +
- "\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x006" +
- "\xbc\x00\x00\x00\x008@\x00\x04\x00\x00T`\x01\b\x00\x00FP\x00\f\x00\x00FP\x01\fLMT\x00+04\x00+06\x00+05\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00?\xa7^\xfah\x02\x00\x00h\x02\x00\x00\v\x00\x00\x00Asia/AtyrauTZif2\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\x002" +
- "\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x93P\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00" +
- "\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0" +
- "\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00" +
- "'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P" +
- "\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x00" +
- "5\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`" +
- "\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x01\x02\x03\x04\x02\x04\x02\x04\x02\x04\x02\x04" +
- "\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\x06\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x02\x00\x000\xb0\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x00\b\x00\x00T`" +
- "\x00\f\x00\x00T`\x01\f\x00\x00FP\x01\b\x00\x008@\x00\x10LMT\x00+03\x00+05\x00+06\x00+04\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\xd7e&uv\x02\x00\x00v\x02\x00\x00\f\x00\x00\x00Asia/BaghdadTZif2\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\x006\x00\x00" +
- "\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x86\xb1\xdc\xff\xff\xff\xff\x9e0<\xe0\x00\x00\x00\x00\x170hP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xe8\xbdP\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc" +
- "\x93\xd0\x00\x00\x00\x00\x1b\xbd\xc8@\x00\x00\x00\x00\x1c\xad\xc7P\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00" +
- "\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf6x\x00\x00\x00\x00\x00(\xe7" +
- "\xba\x80\x00\x00\x00\x00)\xd8\xfd\x00\x00\x00\x00\x00*\xca?\x80\x00\x00\x00\x00+\xba0\x80\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\x9bd\x00\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00\x00/|\x97\x80\x00\x00" +
- "\x00\x000m\xda\x00\x00\x00\x00\x001_\x1c\x80\x00\x00\x00\x002P_\x00\x00\x00\x00\x003@P\x00\x00\x00\x00\x0041\x92\x80\x00\x00\x00\x005!\x83\x80\x00\x00\x00\x006\x12\xc6\x00\x00\x00\x00\x007\x02" +
- "\xb7\x00\x00\x00\x00\x007\xf3\xf9\x80\x00\x00\x00\x008\xe5<\x00\x00\x00\x00\x009\xd6~\x80\x00\x00\x00\x00:\xc6o\x80\x00\x00\x00\x00;\xb7\xb2\x00\x00\x00\x00\x00<\xa7\xa3\x00\x00\x00\x00\x00=\x98\xe5\x80\x00\x00" +
- "\x00\x00>\x88ր\x00\x00\x00\x00?z\x19\x00\x00\x00\x00\x00@k[\x80\x00\x00\x00\x00A\\\x9e\x00\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00C=р\x00\x00\x00\x00D-\u0080\x00\x00\x00\x00E\x1f" +
- "\x05\x00\x00\x00\x00\x00F\x0e\xf6\x00\x00\x00\x00\x00G\x008\x80\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00)\xa4\x00\x00\x00\x00)\xa0\x00\x04\x00\x00*0\x00\b\x00\x008@\x01\fLMT\x00BMT\x00+03\x00+04\x00\n<+03>-3" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdav\x19z\x98\x00\x00\x00\x98\x00\x00\x00\f\x00\x00\x00Asia/BahrainTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\xa1\xf2\x9d0\x00\x00\x00\x00\x04\x8a\x92\xc0\x01\x02\x00\x000P\x00\x00\x00\x008@\x00\x04\x00\x00*0\x00\bLMT\x00+0" +
- "4\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x87\xb3<\xe8\x02\x00\x00\xe8\x02\x00\x00\t\x00\x00\x00Asia/BakuTZif2\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\x00B\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x95D\xff\xff\xff\xff\xe7\xda\fP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce" +
- "0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00" +
- "\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v" +
- "\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00" +
- "\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86" +
- "\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00" +
- "\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00\x00\x00\x00\x00D%ـ\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb" +
- "\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00Ḻ\x80\x00\x00\x00" +
- "\x00M\x8e~\x00\x00\x00\x00\x00N\xac\x93\x80\x00\x00\x00\x00On`\x00\x00\x00\x00\x00P\x8cu\x80\x00\x00\x00\x00QW|\x80\x00\x00\x00\x00RlW\x80\x00\x00\x00\x00S7^\x80\x00\x00\x00\x00TL9" +
- "\x80\x00\x00\x00\x00U\x17@\x80\x00\x00\x00\x00V,\x1b\x80\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00.\xbc\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\fLMT\x00+03" +
- "\x00+05\x00+04\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\f\x00\x00\x00Asia/Bangkok" +
- "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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00" +
- "\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\xbd\xedL\xf1\x02\x00\x00\xf1\x02\x00\x00\f\x00" +
- "\x00\x00Asia/BarnaulTZif2\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\x00C\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xd5}\xfc\xff\xff\xff" +
- "\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[" +
- "\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00" +
- "\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf" +
- "@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00" +
- "\x00/th0\x00\x00\x00\x00/\xc7L\x80\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV" +
- "\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00" +
- "\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4" +
- "\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00\x00" +
- "\x00J\xe3\\\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00V\xf6\xea@\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00N\x84\x00\x00\x00\x00" +
- "T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x01\fLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xc7\x11\xe1[\xdc\x02\x00\x00\xdc\x02\x00\x00\v\x00\x00\x00Asia/BeirutTZif2\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\x03\x00" +
- "\x00\x00\r\xff\xff\xff\xffV\xb6¸\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff" +
- "\xff\xff\xff\xa8)\xf3\xe0\xff\xff\xff\xff\xa8\xeb\xb2P\xff\xff\xff\xff\xe8*\x85\xe0\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\xec\xe0\xff\xff\xff\xff\xec" +
- "\xb6\x94P\xff\xff\xff\xff\xed\xcfq\xe0\xff\xff\xff\xff\xee\x99\x19P\xff\xff\xff\xffﰥ`\xff\xff\xff\xff\xf0zL\xd0\x00\x00\x00\x00\x04\xa6^`\x00\x00\x00\x00\x05+w\xd0\x00\x00\x00\x00\x06C\x03\xe0\x00" +
- "\x00\x00\x00\a\f\xabP\x00\x00\x00\x00\b$7`\x00\x00\x00\x00\b\xed\xde\xd0\x00\x00\x00\x00\n\x05j\xe0\x00\x00\x00\x00\n\xcf\x12P\x00\x00\x00\x00\v\xe7\xef\xe0\x00\x00\x00\x00\f\xb1\x97P\x00\x00\x00\x00\r" +
- "\xc9#`\x00\x00\x00\x00\x0e\x92\xca\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10r\xac\xd0\x00\x00\x00\x00\x1a\xf4.\xe0\x00\x00\x00\x00\x1bќ\xd0\x00\x00\x00\x00\x1c\xd5b`\x00\x00\x00\x00\x1d\xb2\xd0P\x00" +
- "\x00\x00\x00\x1e\xb6\x95\xe0\x00\x00\x00\x00\x1f\x94\x03\xd0\x00\x00\x00\x00 \x97\xc9`\x00\x00\x00\x00!u7P\x00\x00\x00\x00\"\xa3,\xe0\x00\x00\x00\x00#W\xbcP\x00\x00\x00\x00$g_`\x00\x00\x00\x00%" +
- "8\xef\xd0\x00\x00\x00\x00&<\xb5`\x00\x00\x00\x00'\x1a#P\x00\x00\x00\x00(\x1d\xe8\xe0\x00\x00\x00\x00(\xfbV\xd0\x00\x00\x00\x00*\x00m\xe0\x00\x00\x00\x00*\xce\t\xd0\x00\x00\x00\x00+\xb4\xce`\x00" +
- "\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003" +
- "=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x006\rU\xd0\x00\x00\x00\x006\xfdT\xe0\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00!H\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT" +
- "\x00EEST\x00EET\x00\nEET-2EEST,M3.5.0/0,M10.5.0/0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000]*\x1bj\x02" +
- "\x00\x00j\x02\x00\x00\f\x00\x00\x00Asia/BishkekTZif2\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\x004\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff" +
- "\xff\xaa\x19~\x10\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19" +
- "\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00" +
- "\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee" +
- "@\x00\x00\x00\x00(\xbe\xa3\xc0\x00\x00\x00\x00)\xe770\x00\x00\x00\x00*ĥ \x00\x00\x00\x00+\xc7\x190\x00\x00\x00\x00,\xa4\x87 \x00\x00\x00\x00-\xa6\xfb0\x00\x00\x00\x00.\x84i \x00\x00\x00" +
- "\x00/\x86\xdd0\x00\x00\x00\x000dK \x00\x00\x00\x001f\xbf0\x00\x00\x00\x002Mg\xa0\x00\x00\x00\x003=\x89\xd8\x00\x00\x00\x004RV\xc8\x00\x00\x00\x005\x1dk\xd8\x00\x00\x00\x00628" +
- "\xc8\x00\x00\x00\x006\xfdM\xd8\x00\x00\x00\x008\x1bUH\x00\x00\x00\x008\xdd/\xd8\x00\x00\x00\x009\xfb7H\x00\x00\x00\x00:\xbd\x11\xd8\x00\x00\x00\x00;\xdb\x19H\x00\x00\x00\x00<\xa6.X\x00\x00\x00" +
- "\x00=\xba\xfbH\x00\x00\x00\x00>\x86\x10X\x00\x00\x00\x00?\x9a\xddH\x00\x00\x00\x00@e\xf2X\x00\x00\x00\x00A\x83\xf9\xc8\x00\x00\x00\x00BE\xd4X\x00\x00\x00\x00B\xfb\x92 \x01\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x03\x00\x00E\xf0\x00\x00\x00\x00FP\x00\x04\x00\x00b" +
- "p\x01\b\x00\x00T`\x00\f\x00\x00T`\x01\fLMT\x00+05\x00+07\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7f^]@\x01" +
- "\x00\x00@\x01\x00\x00\v\x00\x00\x00Asia/BruneiTZif2\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\x12\x00\x00\x00\x05\x00\x00\x00\x18\xff\xff\xff\xff" +
- "\xad\x8a\x06\x90\xff\xff\xff\xff\xbagG\x88\xff\xff\xff\xff\xbf{'\x80\xff\xff\xff\xff\xbf\xf3\x1bP\xff\xff\xff\xff\xc1]\xac\x80\xff\xff\xff\xff\xc1ՠP\xff\xff\xff\xff\xc3>\xe0\x00\xff\xff\xff\xffö\xd3\xd0" +
- "\xff\xff\xff\xff\xc5 \x13\x80\xff\xff\xff\xffŘ\aP\xff\xff\xff\xff\xc7\x01G\x00\xff\xff\xff\xff\xc7y:\xd0\xff\xff\xff\xff\xc8\xe3\xcc\x00\xff\xff\xff\xff\xc9[\xbf\xd0\xff\xff\xff\xff\xca\xc4\xff\x80\xff\xff\xff\xff" +
- "\xcb<\xf3P\xff\xff\xff\xffˑX\x00\xff\xff\xff\xff\xd2Hm\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x00\x00gp\x00\x00\x00\x00ix\x00\x04\x00\x00u0\x01\n\x00\x00p\x80" +
- "\x00\x10\x00\x00~\x90\x00\x14LMT\x00+0730\x00+0820\x00+08\x00+09\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x1a\xdc\xca\xdc" +
- "\x00\x00\x00\xdc\x00\x00\x00\r\x00\x00\x00Asia/CalcuttaTZif2\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\a\x00\x00\x00\x05\x00\x00\x00\x16\xff" +
- "\xff\xff\xff&\xba\x18(\xff\xff\xff\xffC\xe7\xeb0\xff\xff\xff\xff\x87\x9d\xbc\xba\xff\xff\xff\xff\xcaی(\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xff\xd2t\x12\x98\x01\x02\x03\x04\x03" +
- "\x04\x03\x00\x00R\xd8\x00\x00\x00\x00R\xd0\x00\x04\x00\x00KF\x00\b\x00\x00MX\x00\f\x00\x00[h\x01\x10LMT\x00HMT\x00MMT\x00IST\x00+0630\x00\nIST-5" +
- ":30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\xcd\xdf\x05\xee\x02\x00\x00\xee\x02\x00\x00\n\x00\x00\x00Asia/ChitaTZif2\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\x00B\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\xf9\xa0\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\b\x86\xf0\x00" +
- "\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL\x90\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e" +
- "\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00#;Ԑ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xb6\x90\x00" +
- "\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk \x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ė\x10\x00\x00\x00\x00+" +
- "\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00" +
- "\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\a\x90\x00\x00\x00\x006\xfd\x0e\x90\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009" +
- "\xfb\x06\x10\x00\x00\x00\x00:\xbcҐ\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00\x00>\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00@e\xb3\x10\x00" +
- "\x00\x00\x00A\x83Ȑ\x00\x00\x00\x00BE\x95\x10\x00\x00\x00\x00Cc\xaa\x90\x00\x00\x00\x00D%w\x10\x00\x00\x00\x00EC\x8c\x90\x00\x00\x00\x00F\x05Y\x10\x00\x00\x00\x00G#n\x90\x00\x00\x00\x00G" +
- "\xeeu\x90\x00\x00\x00\x00I\x03P\x90\x00\x00\x00\x00I\xceW\x90\x00\x00\x00\x00J\xe32\x90\x00\x00\x00\x00K\xae9\x90\x00\x00\x00\x00L\xccO\x10\x00\x00\x00\x00M\x8e\x1b\x90\x00\x00\x00\x00TK\xc9\x00\x00" +
- "\x00\x00\x00V\xf6\xce \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x01\x03\x00\x00j`\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\f\x00\x00\x8c\xa0\x00\bLMT\x00+08\x00+10" +
- "\x00+09\x00\n<+09>-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81z&\x80k\x02\x00\x00k\x02\x00\x00\x0f\x00\x00\x00Asia/ChoibalsanT" +
- "Zif2\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\x003\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\x86\xd3\xe7(\x00\x00\x00\x00\x0f\vܐ\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00" +
- "\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbc\"`\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k" +
- "\xe5p\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x8c`\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00" +
- "\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\x8a\xe0\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84" +
- "0\xe0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]Lp\x00\x00\x00\x002M/`\x00\x00\x00\x003=.p\x00\x00\x00\x004-\x11`\x00\x00\x00\x005\x1d\x10p\x00\x00" +
- "\x00\x006\f\xf3`\x00\x00\x00\x00:饐\x00\x00\x00\x00;\xb4\x9e\x80\x00\x00\x00\x00<\xa4\x9d\x90\x00\x00\x00\x00=\x94\x80\x80\x00\x00\x00\x00>\x84\x7f\x90\x00\x00\x00\x00?tb\x80\x00\x00\x00\x00@d" +
- "a\x90\x00\x00\x00\x00ATD\x80\x00\x00\x00\x00BDC\x90\x00\x00\x00\x00C4&\x80\x00\x00\x00\x00D$%\x90\x00\x00\x00\x00E\x1dC\x00\x00\x00\x00\x00G\xef\xaa\xf0\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00" +
- "\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x01\x02\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\x03\x04\x03\x04\x03" +
- "\x04\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x00\x00kX\x00\x00\x00\x00bp\x00\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\f\x00\x00\x8c\xa0\x01\x10\x00\x00~\x90\x01\fLMT\x00+07\x00+08" +
- "\x00+09\x00+10\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x00\x00Asia/Chongqi" +
- "ngTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04" +
- "\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff" +
- "\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR" +
- " \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00" +
- "\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\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\x00\x00" +
- "q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00" +
- "\x00\x0e\x00\x00\x00Asia/ChungkingTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6" +
- "C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff" +
- "\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d" +
- "\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00" +
- "\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\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\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\\\x91\x87\xbb\xf7\x00\x00\x00\xf7\x00\x00\x00\f\x00\x00\x00Asia/ColomboTZif2\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" +
- "\b\x00\x00\x00\a\x00\x00\x00\x18\xff\xff\xff\xffV\xb6\x99$\xff\xff\xff\xff\x87\x9d\xbd\x1c\xff\xff\xff\xff\xcbZ\x1c(\xff\xff\xff\xff̕+\xa0\xff\xff\xff\xff\xd2u\x808\x00\x00\x00\x001\xa6\x00(\x00\x00\x00" +
- "\x002q\x00 \x00\x00\x00\x00D?\xea(\x01\x02\x03\x04\x02\x05\x06\x02\x00\x00J\xdc\x00\x00\x00\x00J\xe4\x00\x04\x00\x00MX\x00\b\x00\x00T`\x01\x0e\x00\x00[h\x01\x12\x00\x00[h\x00\x12\x00\x00T" +
- "`\x00\x0eLMT\x00MMT\x00+0530\x00+06\x00+0630\x00\n<+0530>-5:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?Y\xaf\x19\xe7" +
- "\x00\x00\x00\xe7\x00\x00\x00\n\x00\x00\x00Asia/DaccaTZif2\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\a\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xff" +
- "i\x86\x86\xbc\xff\xff\xff\xff\xcaۆ\xb0\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xffݨҘ\x00\x00\x00\x00J;\xc4\x10\x00\x00\x00\x00K<ؐ\x01\x02\x03\x02\x04\x05\x04\x00" +
- "\x00T\xc4\x00\x00\x00\x00R\xd0\x00\x04\x00\x00[h\x00\b\x00\x00MX\x00\x0e\x00\x00T`\x00\x14\x00\x00bp\x01\x18LMT\x00HMT\x00+0630\x00+0530\x00+06\x00+" +
- "07\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\a\xeci\xd2\x04\x00\x00\xd2\x04\x00\x00\r\x00\x00\x00Asia/DamascusTZif2" +
- "\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\x00y\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa1\xf2\xabx\xff\xff\xff\xff\xa2\x81/\x80\xff\xff\xff\xff\xa3^\x9dp\xff\xff\xff\xff\xa4a" +
- "\x11\x80\xff\xff\xff\xff\xa5>\x7fp\xff\xff\xff\xff\xa6@\xf3\x80\xff\xff\xff\xff\xa7\x1eap\xff\xff\xff\xff\xa8 Հ\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xf1\x8fR\x00\xff\xff\xff\xff\xf2[\x9cp\xff\xff" +
- "\xff\xff\xf3s(\x80\xff\xff\xff\xff\xf4;~p\xff\xff\xff\xff\xf5U\xad\x80\xff\xff\xff\xff\xf6\x1fT\xf0\xff\xff\xff\xff\xf76\xe1\x00\xff\xff\xff\xff\xf7\xff6\xf0\xff\xff\xff\xff\xf9\x0e\xda\x00\xff\xff\xff\xff\xf9\xe1" +
- "\xbb\xf0\xff\xff\xff\xff\xfa\xf9H\x00\xff\xff\xff\xff\xfb\xc2\xefp\xff\xff\xff\xff\xfc\xdb\xcd\x00\xff\xff\xff\xff\xfd\xa5tp\xff\xff\xff\xff\xfe\xbd\x00\x80\xff\xff\xff\xff\xff\x86\xa7\xf0\x00\x00\x00\x00\x00\x9e4\x00\x00\x00" +
- "\x00\x00\x01g\xdbp\x00\x00\x00\x00\x02\x7fg\x80\x00\x00\x00\x00\x03I\x0e\xf0\x00\x00\x00\x00\x04a\xec\x80\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06C \x00\x00\x00\x00\x00\a\f\xc7p\x00\x00\x00\x00\b$" +
- "S\x80\x00\x00\x00\x00\b\xed\xfa\xf0\x00\x00\x00\x00\n\x05\x87\x00\x00\x00\x00\x00\n\xcf.p\x00\x00\x00\x00\v\xe8\f\x00\x00\x00\x00\x00\f\xb1\xb3p\x00\x00\x00\x00\r\xc9?\x80\x00\x00\x00\x00\x0ekY\xf0\x00\x00" +
- "\x00\x00\x0f\xaas\x00\x00\x00\x00\x00\x10L\x8dp\x00\x00\x00\x00\x18\xf4\xc5\x00\x00\x00\x00\x00\x19\xdbmp\x00\x00\x00\x00\x1a\xd7J\x00\x00\x00\x00\x00\x1b\xbd\xf2p\x00\x00\x00\x00\x1eU#\x00\x00\x00\x00\x00\x1f\x8a" +
- "\xe5p\x00\x00\x00\x00 Gz\x00\x00\x00\x00\x00!\x89\x19\xf0\x00\x00\x00\x00\"<t\x00\x00\x00\x00\x00#k\x9e\xf0\x00\x00\x00\x00$2\xbf\x80\x00\x00\x00\x00%%Ep\x00\x00\x00\x00&\x15D\x80\x00\x00" +
- "\x00\x00'\x05'p\x00\x00\x00\x00'\xf6[\xe0\x00\x00\x00\x00(\xe7\x90P\x00\x00\x00\x00)\xe2\x1b`\x00\x00\x00\x00*\xca\x15P\x00\x00\x00\x00+\xb2+`\x00\x00\x00\x00,\xa3_\xd0\x00\x00\x00\x00-\x9b" +
- "G\xe0\x00\x00\x00\x00.\x8c|P\x00\x00\x00\x00/|{`\x00\x00\x00\x000m\xaf\xd0\x00\x00\x00\x001_\x00`\x00\x00\x00\x002P4\xd0\x00\x00\x00\x003>\xe2`\x00\x00\x00\x0041hP\x00\x00" +
- "\x00\x005\x1e\xc4`\x00\x00\x00\x006\x12\x9b\xd0\x00\x00\x00\x007\x02\x9a\xe0\x00\x00\x00\x007\xf3\xcfP\x00\x00\x00\x008\xe5\x1f\xe0\x00\x00\x00\x009\xd6TP\x00\x00\x00\x00:\xc6S`\x00\x00\x00\x00;\xb7" +
- "\x87\xd0\x00\x00\x00\x00<\xa7\x86\xe0\x00\x00\x00\x00=\x98\xbbP\x00\x00\x00\x00>\x88\xba`\x00\x00\x00\x00?y\xee\xd0\x00\x00\x00\x00@k?`\x00\x00\x00\x00A\\s\xd0\x00\x00\x00\x00BLr\xe0\x00\x00" +
- "\x00\x00C=\xa7P\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\f6\xe0\x00\x00\x00\x00G*>P\x00\x00\x00\x00G\xf5S`\x00\x00\x00\x00I\vq\xd0\x00\x00\x00\x00I\xcb" +
- "\xfa\xe0\x00\x00\x00\x00J\xea\x02P\x00\x00\x00\x00K\xb5\x17`\x00\x00\x00\x00L\xc9\xe4P\x00\x00\x00\x00M\x94\xf9`\x00\x00\x00\x00N\xa9\xc6P\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P\x89\xa8P\x00\x00" +
- "\x00\x00QT\xbd`\x00\x00\x00\x00Ri\x8aP\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TR\xa6\xd0\x00\x00\x00\x00U\x14\x81`\x00\x00\x00\x00V2\x88\xd0\x00\x00\x00\x00V\xf4c`\x00\x00\x00\x00X\x12" +
- "j\xd0\x00\x00\x00\x00X\xdd\x7f\xe0\x00\x00\x00\x00Y\xf2L\xd0\x00\x00\x00\x00Z\xbda\xe0\x00\x00\x00\x00[\xd2.\xd0\x00\x00\x00\x00\\\x9dC\xe0\x00\x00\x00\x00]\xb2\x10\xd0\x00\x00\x00\x00^}%\xe0\x00\x00" +
- "\x00\x00_\x9b-P\x00\x00\x00\x00`]\a\xe0\x00\x00\x00\x00a{\x0fP\x00\x00\x00\x00b<\xe9\xe0\x00\x00\x00\x00cZ\xf1P\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x00\x00\"\b\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*" +
- "0\x00\rLMT\x00EEST\x00EET\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\n\x00\x00\x00A" +
- "sia/DhakaTZif2\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\x00" +
- "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\a\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xffi\x86\x86\xbc\xff\xff\xff\xff\xcaۆ\xb0" +
- "\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xffݨҘ\x00\x00\x00\x00J;\xc4\x10\x00\x00\x00\x00K<ؐ\x01\x02\x03\x02\x04\x05\x04\x00\x00T\xc4\x00\x00\x00\x00R\xd0\x00\x04\x00" +
- "\x00[h\x00\b\x00\x00MX\x00\x0e\x00\x00T`\x00\x14\x00\x00bp\x01\x18LMT\x00HMT\x00+0630\x00+0530\x00+06\x00+07\x00\n<+06>-6\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Β\x1a\x8c\xaa\x00\x00\x00\xaa\x00\x00\x00\t\x00\x00\x00Asia/DiliTZif2\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\x04\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x92\xe6\x18\xc4\xff\xff\xff\xff˙2\xf0\x00\x00\x00\x00\v\xea0p\x00\x00\x00\x009Ù\x00\x01\x02\x01\x02\x00\x00u\xbc\x00\x00\x00\x00p\x80" +
- "\x00\x04\x00\x00~\x90\x00\bLMT\x00+08\x00+09\x00\n<+09>-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\n\x00\x00\x00A" +
- "sia/DubaiTZif2\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\x00" +
- "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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00" +
- "\x008@\x00\x04LMT\x00+04\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00's\x96\x1en\x01\x00\x00n\x01\x00\x00\r\x00\x00\x00Asia/Dus" +
- "hanbeTZif2\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\x00TZif" +
- "2\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\x18\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x83\x80\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00" +
- "\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0" +
- "\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00" +
- "#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(ʏP\x01\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x00\x00@\x80\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f\x00\x00T`\x01\fLMT\x00+05\x00+07\x00+0" +
- "6\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]S\xbb\x12\xac\x03\x00\x00\xac\x03\x00\x00\x0e\x00\x00\x00Asia/FamagustaTZif2" +
- "\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\x00V\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa5w\x1e,\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\nݒ\xd0\x00\x00\x00\x00\v\xfa" +
- "d\xe0\x00\x00\x00\x00\f\xbe\xc6P\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00" +
- "\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3" +
- "hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00" +
- "\x00\x00!\\*\xd0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf5" +
- "\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00" +
- "\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062" +
- "x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00" +
- "\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%" +
- "\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00" +
- "\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rl" +
- "e\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xd0\x7f\xd0\x00\x00\x00\x00Y\xf5(\x10\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\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\x03\x02\x00\x00\x1f\xd4\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\t\x00\x00*0\x00\rLMT\x00EEST\x00EET" +
- "\x00+03\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xda7\xf5l\xd6\t\x00\x00\xd6\t\x00" +
- "\x00\t\x00\x00\x00Asia/GazaTZif3\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\x01\x04\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\x7f\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@\x7f\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]\xb3b" +
- "P\x00\x00\x00\x00^~w`\x00\x00\x00\x00_\x93R`\x00\x00\x00\x00`^Y`\x00\x00\x00\x00a{\x1d`\x00\x00\x00\x00b?\x8c\xe0\x00\x00\x00\x00c\\^\xf0\x00\x00\x00\x00dL^\x00\x00\x00\x00" +
- "\x00e<@\xf0\x00\x00\x00\x00f\x19\xcb\x00\x00\x00\x00\x00g\x1c\"\xf0\x00\x00\x00\x00g\xf0r\x80\x00\x00\x00\x00h\xfc\x04\xf0\x00\x00\x00\x00i\xc7\x1a\x00\x00\x00\x00\x00j\xdb\xe6\xf0\x00\x00\x00\x00k\xa6\xfc" +
- "\x00\x00\x00\x00\x00l\xc5\x03p\x00\x00\x00\x00m\x86\xde\x00\x00\x00\x00\x00n\xa4\xe5p\x00\x00\x00\x00of\xc0\x00\x00\x00\x00\x00p\x84\xc7p\x00\x00\x00\x00qO܀\x00\x00\x00\x00rd\xa9p\x00\x00\x00" +
- "\x00s/\xbe\x80\x00\x00\x00\x00tD\x8bp\x00\x00\x00\x00u\x0f\xa0\x80\x00\x00\x00\x00v-\xa7\xf0\x00\x00\x00\x00v\uf080\x00\x00\x00\x00x\r\x89\xf0\x00\x00\x00\x00x\xcfd\x80\x00\x00\x00\x00y\xedk" +
- "\xf0\x00\x00\x00\x00z\xafF\x80\x00\x00\x00\x00{\xcdM\xf0\x00\x00\x00\x00|\x98c\x00\x00\x00\x00\x00}\xa3\xf5p\x00\x00\x00\x00~xE\x00\x00\x00\x00\x00\x7fz\x9c\xf0\x00\x00\x00\x00\x80X'\x00\x00\x00\x00" +
- "\x00\x81H\t\xf0\x00\x00\x00\x00\x828\t\x00\x00\x00\x00\x00\x83\x1e\xb1p\x00\x00\x00\x00\x83L\xe4\x00\x00\x00\x00\x00\x83V\x10p\x00\x00\x00\x00\x84\x17\xeb\x00\x00\x00\x00\x00\x84\xec\x1ep\x00\x00\x00\x00\x85#\x8b" +
- "\x80\x00\x00\x00\x00\x855\xf2p\x00\x00\x00\x00\x86\x01\a\x80\x00\x00\x00\x00\x86\xc2\xc5\xf0\x00\x00\x00\x00\x86\xf0\xf8\x80\x00\x00\x00\x00\x87\x15\xd4p\x00\x00\x00\x00\x87\xe0\xe9\x80\x00\x00\x00\x00\x88\x99mp\x00\x00\x00" +
- "\x00\x88Ǡ\x00\x00\x00\x00\x00\x88\xf5\xb6p\x00\x00\x00\x00\x89\xc0ˀ\x00\x00\x00\x00\x8af\xdap\x00\x00\x00\x00\x8a\x9eG\x80\x00\x00\x00\x00\x8a\u0558p\x00\x00\x00\x00\x8b\xa0\xad\x80\x00\x00\x00\x00\x8c=\x81" +
- "\xf0\x00\x00\x00\x00\x8ck\xb4\x80\x00\x00\x00\x00\x8c\xbe\xb4\xf0\x00\x00\x00\x00\x8d\x80\x8f\x80\x00\x00\x00\x00\x8e\x14)p\x00\x00\x00\x00\x8eB\\\x00\x00\x00\x00\x00\x8e\x9e\x96\xf0\x00\x00\x00\x00\x8f`q\x80\x00\x00\x00" +
- "\x00\x8f\xe1\x96p\x00\x00\x00\x00\x90\x19\x03\x80\x00\x00\x00\x00\x90~x\xf0\x00\x00\x00\x00\x91I\x8e\x00\x00\x00\x00\x00\x91\xb8=\xf0\x00\x00\x00\x00\x91\xe6p\x80\x00\x00\x00\x00\x92^Z\xf0\x00\x00\x00\x00\x93)p" +
- "\x00\x00\x00\x00\x00\x93\x85\xaa\xf0\x00\x00\x00\x00\x93\xbd\x18\x00\x00\x00\x00\x00\x94><\xf0\x00\x00\x00\x00\x95\tR\x00\x00\x00\x00\x00\x95\\Rp\x00\x00\x00\x00\x95\x8a\x85\x00\x00\x00\x00\x00\x96'Yp\x00\x00\x00" +
- "\x00\x96\xe94\x00\x00\x00\x00\x00\x972\xf9\xf0\x00\x00\x00\x00\x97a,\x80\x00\x00\x00\x00\x98\a;p\x00\x00\x00\x00\x98\xc9\x16\x00\x00\x00\x00\x00\x99\x00f\xf0\x00\x00\x00\x00\x997\xd4\x00\x00\x00\x00\x00\x99\xe7\x1d" +
- "p\x00\x00\x00\x00\x9a\xb22\x80\x00\x00\x00\x00\x9a\xd7\x0ep\x00\x00\x00\x00\x9b\x05A\x00\x00\x00\x00\x00\x9b\xc6\xffp\x00\x00\x00\x00\x9c\x92\x14\x80\x00\x00\x00\x00\x9c\xa4{p\x00\x00\x00\x00\x9c\xdb\xe8\x80\x00\x00\x00" +
- "\x00\x9d\xa6\xe1p\x00\x00\x00\x00\x9eq\xf6\x80\x00\x00\x00\x00\x9e{\"\xf0\x00\x00\x00\x00\x9e\xb2\x90\x00\x00\x00\x00\x00\x9f\x86\xc3p\x00\x00\x00\x00\xa0\x7f\xfd\x00\x00\x00\x00\x00\xa1o\xdf\xf0\x00\x00\x00\x00\xa2V\xa4" +
- "\x80\x00\x00\x00\x00\xa3O\xc1\xf0\x00\x00\x00\x00\xa4$\x11\x80\x00\x00\x00\x00\xa5/\xa3\xf0\x00\x00\x00\x00\xa5\xfa\xb9\x00\x00\x00\x00\x00\xa7\x0f\x85\xf0\x00\x00\x00\x00\xa7ڛ\x00\x00\x00\x00\x00\xa8\xefg\xf0\x00\x00\x00" +
- "\x00\xa9\xba}\x00\x00\x00\x00\x00\xaa\u0604p\x00\x00\x00\x00\xab\x9a_\x00\x00\x00\x00\x00\xac\xb8fp\x00\x00\x00\x00\xadzA\x00\x00\x00\x00\x00\xae\x98Hp\x00\x00\x00\x00\xafZ#\x00\x00\x00\x00\x00\xb0x*" +
- "p\x00\x00\x00\x00\xb1C?\x80\x00\x00\x00\x00\xb2X\fp\x00\x00\x00\x00\xb3#!\x80\x00\x00\x00\x00\xb47\xeep\x00\x00\x00\x00\xb5\x03\x03\x80\x00\x00\x00\x00\xb6!\n\xf0\x00\x00\x00\x00\xb6\xe2\xe5\x80\x00\x00\x00" +
- "\x00\xb8\x00\xec\xf0\x00\x00\x00\x00\xb8\xc2ǀ\x00\x00\x00\x00\xb9הp\x00\x00\x00\x00\xba\xab\xe4\x00\x00\x00\x00\x00\xbb\xae;\xf0\x00\x00\x00\x00\xbc\x8b\xc6\x00\x00\x00\x00\x00\xbd\x84\xe3p\x00\x00\x00\x00\xbek\xa8" +
- "\x00\x00\x00\x00\x00\xbfRPp\x00\x00\x00\x00\xc0K\x8a\x00\x00\x00\x00\x00\xc1(\xf7\xf0\x00\x00\x00\x00\xc1W*\x80\x00\x00\x00\x00\xc2\xff\x9fp\x00\x00\x00\x00\xc3-\xd2\x00\x00\x00\x00\x00\xc4\xcd\fp\x00\x00\x00" +
- "\x00\xc5\x04y\x80\x00\x00\x00\x00ƣ\xb3\xf0\x00\x00\x00\x00\xc6\xd1\xe6\x80\x00\x00\x00\x00\xc7\t7p\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\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\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\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\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/50" +
- ",M10.4.4/50\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\v\x00\x00\x00Asia/HarbinTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80" +
- "\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff" +
- "\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90" +
- "\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00" +
- "&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\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\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01" +
- "\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xba\xd4\xe5\xe8\t\x00\x00\xe8\t\x00\x00\v\x00\x00\x00Asia" +
- "/HebronTZif3\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\x00TZ" +
- "if3\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\x06\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff}\xbdJ\x19\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\x7f\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\xf2Z" +
- "Y\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@\x7f\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\xbb\x06P\x00\x00" +
- "\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00\x00K\xab\xdc\xe0\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00\x00\x00\x00N\\\v\xe0\x00\x00\x00\x00N\x84" +
- "\xdcP\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\\\x9d" +
- "C\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00\x00^~w`\x00\x00\x00\x00_\x93R`\x00\x00\x00\x00`^Y`\x00\x00\x00\x00a{\x1d`\x00\x00\x00\x00b?\x8c\xe0\x00\x00\x00\x00c\\^\xf0\x00\x00" +
- "\x00\x00dL^\x00\x00\x00\x00\x00e<@\xf0\x00\x00\x00\x00f\x19\xcb\x00\x00\x00\x00\x00g\x1c\"\xf0\x00\x00\x00\x00g\xf0r\x80\x00\x00\x00\x00h\xfc\x04\xf0\x00\x00\x00\x00i\xc7\x1a\x00\x00\x00\x00\x00j\xdb" +
- "\xe6\xf0\x00\x00\x00\x00k\xa6\xfc\x00\x00\x00\x00\x00l\xc5\x03p\x00\x00\x00\x00m\x86\xde\x00\x00\x00\x00\x00n\xa4\xe5p\x00\x00\x00\x00of\xc0\x00\x00\x00\x00\x00p\x84\xc7p\x00\x00\x00\x00qO܀\x00\x00" +
- "\x00\x00rd\xa9p\x00\x00\x00\x00s/\xbe\x80\x00\x00\x00\x00tD\x8bp\x00\x00\x00\x00u\x0f\xa0\x80\x00\x00\x00\x00v-\xa7\xf0\x00\x00\x00\x00v\uf080\x00\x00\x00\x00x\r\x89\xf0\x00\x00\x00\x00x\xcf" +
- "d\x80\x00\x00\x00\x00y\xedk\xf0\x00\x00\x00\x00z\xafF\x80\x00\x00\x00\x00{\xcdM\xf0\x00\x00\x00\x00|\x98c\x00\x00\x00\x00\x00}\xa3\xf5p\x00\x00\x00\x00~xE\x00\x00\x00\x00\x00\x7fz\x9c\xf0\x00\x00" +
- "\x00\x00\x80X'\x00\x00\x00\x00\x00\x81H\t\xf0\x00\x00\x00\x00\x828\t\x00\x00\x00\x00\x00\x83\x1e\xb1p\x00\x00\x00\x00\x83L\xe4\x00\x00\x00\x00\x00\x83V\x10p\x00\x00\x00\x00\x84\x17\xeb\x00\x00\x00\x00\x00\x84\xec" +
- "\x1ep\x00\x00\x00\x00\x85#\x8b\x80\x00\x00\x00\x00\x855\xf2p\x00\x00\x00\x00\x86\x01\a\x80\x00\x00\x00\x00\x86\xc2\xc5\xf0\x00\x00\x00\x00\x86\xf0\xf8\x80\x00\x00\x00\x00\x87\x15\xd4p\x00\x00\x00\x00\x87\xe0\xe9\x80\x00\x00" +
- "\x00\x00\x88\x99mp\x00\x00\x00\x00\x88Ǡ\x00\x00\x00\x00\x00\x88\xf5\xb6p\x00\x00\x00\x00\x89\xc0ˀ\x00\x00\x00\x00\x8af\xdap\x00\x00\x00\x00\x8a\x9eG\x80\x00\x00\x00\x00\x8a\u0558p\x00\x00\x00\x00\x8b\xa0" +
- "\xad\x80\x00\x00\x00\x00\x8c=\x81\xf0\x00\x00\x00\x00\x8ck\xb4\x80\x00\x00\x00\x00\x8c\xbe\xb4\xf0\x00\x00\x00\x00\x8d\x80\x8f\x80\x00\x00\x00\x00\x8e\x14)p\x00\x00\x00\x00\x8eB\\\x00\x00\x00\x00\x00\x8e\x9e\x96\xf0\x00\x00" +
- "\x00\x00\x8f`q\x80\x00\x00\x00\x00\x8f\xe1\x96p\x00\x00\x00\x00\x90\x19\x03\x80\x00\x00\x00\x00\x90~x\xf0\x00\x00\x00\x00\x91I\x8e\x00\x00\x00\x00\x00\x91\xb8=\xf0\x00\x00\x00\x00\x91\xe6p\x80\x00\x00\x00\x00\x92^" +
- "Z\xf0\x00\x00\x00\x00\x93)p\x00\x00\x00\x00\x00\x93\x85\xaa\xf0\x00\x00\x00\x00\x93\xbd\x18\x00\x00\x00\x00\x00\x94><\xf0\x00\x00\x00\x00\x95\tR\x00\x00\x00\x00\x00\x95\\Rp\x00\x00\x00\x00\x95\x8a\x85\x00\x00\x00" +
- "\x00\x00\x96'Yp\x00\x00\x00\x00\x96\xe94\x00\x00\x00\x00\x00\x972\xf9\xf0\x00\x00\x00\x00\x97a,\x80\x00\x00\x00\x00\x98\a;p\x00\x00\x00\x00\x98\xc9\x16\x00\x00\x00\x00\x00\x99\x00f\xf0\x00\x00\x00\x00\x997" +
- "\xd4\x00\x00\x00\x00\x00\x99\xe7\x1dp\x00\x00\x00\x00\x9a\xb22\x80\x00\x00\x00\x00\x9a\xd7\x0ep\x00\x00\x00\x00\x9b\x05A\x00\x00\x00\x00\x00\x9b\xc6\xffp\x00\x00\x00\x00\x9c\x92\x14\x80\x00\x00\x00\x00\x9c\xa4{p\x00\x00" +
- "\x00\x00\x9c\xdb\xe8\x80\x00\x00\x00\x00\x9d\xa6\xe1p\x00\x00\x00\x00\x9eq\xf6\x80\x00\x00\x00\x00\x9e{\"\xf0\x00\x00\x00\x00\x9e\xb2\x90\x00\x00\x00\x00\x00\x9f\x86\xc3p\x00\x00\x00\x00\xa0\x7f\xfd\x00\x00\x00\x00\x00\xa1o" +
- "\xdf\xf0\x00\x00\x00\x00\xa2V\xa4\x80\x00\x00\x00\x00\xa3O\xc1\xf0\x00\x00\x00\x00\xa4$\x11\x80\x00\x00\x00\x00\xa5/\xa3\xf0\x00\x00\x00\x00\xa5\xfa\xb9\x00\x00\x00\x00\x00\xa7\x0f\x85\xf0\x00\x00\x00\x00\xa7ڛ\x00\x00\x00" +
- "\x00\x00\xa8\xefg\xf0\x00\x00\x00\x00\xa9\xba}\x00\x00\x00\x00\x00\xaa\u0604p\x00\x00\x00\x00\xab\x9a_\x00\x00\x00\x00\x00\xac\xb8fp\x00\x00\x00\x00\xadzA\x00\x00\x00\x00\x00\xae\x98Hp\x00\x00\x00\x00\xafZ" +
- "#\x00\x00\x00\x00\x00\xb0x*p\x00\x00\x00\x00\xb1C?\x80\x00\x00\x00\x00\xb2X\fp\x00\x00\x00\x00\xb3#!\x80\x00\x00\x00\x00\xb47\xeep\x00\x00\x00\x00\xb5\x03\x03\x80\x00\x00\x00\x00\xb6!\n\xf0\x00\x00" +
- "\x00\x00\xb6\xe2\xe5\x80\x00\x00\x00\x00\xb8\x00\xec\xf0\x00\x00\x00\x00\xb8\xc2ǀ\x00\x00\x00\x00\xb9הp\x00\x00\x00\x00\xba\xab\xe4\x00\x00\x00\x00\x00\xbb\xae;\xf0\x00\x00\x00\x00\xbc\x8b\xc6\x00\x00\x00\x00\x00\xbd\x84" +
- "\xe3p\x00\x00\x00\x00\xbek\xa8\x00\x00\x00\x00\x00\xbfRPp\x00\x00\x00\x00\xc0K\x8a\x00\x00\x00\x00\x00\xc1(\xf7\xf0\x00\x00\x00\x00\xc1W*\x80\x00\x00\x00\x00\xc2\xff\x9fp\x00\x00\x00\x00\xc3-\xd2\x00\x00\x00" +
- "\x00\x00\xc4\xcd\fp\x00\x00\x00\x00\xc5\x04y\x80\x00\x00\x00\x00ƣ\xb3\xf0\x00\x00\x00\x00\xc6\xd1\xe6\x80\x00\x00\x00\x00\xc7\t7p\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\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\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\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" +
- "\x00\x00 \xe7\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-2EES" +
- "T,M3.4.4/50,M10.4.4/50\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000I\xc7\xde\xec\x00\x00\x00\xec\x00\x00\x00\x10\x00\x00\x00Asia/Ho" +
- "_Chi_MinhTZif2\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\x00" +
- "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\t\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\x88\x8cC\x8a\xff\xff\xff\xff\x91\xa3+\n" +
- "\xff\xff\xff\xff\xcd5\xe6\x80\xff\xff\xff\xff\xd1Y\xcep\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd52\xbb\x10\xff\xff\xff\xff\xe4\xb6\xe4\x80\xff\xff\xff\xff\xed/\x98\x00\x00\x00\x00\x00\n=\xc7\x00\x01\x02\x03\x04" +
- "\x02\x03\x02\x03\x02\x00\x00c\xf6\x00\x00\x00\x00c\xf6\x00\x04\x00\x00bp\x00\t\x00\x00p\x80\x00\r\x00\x00~\x90\x00\x11LMT\x00PLMT\x00+07\x00+08\x00+09\x00\n<+0" +
- "7>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\t\xfa-\a\x03\x00\x00\a\x03\x00\x00\x0e\x00\x00\x00Asia/Hong_KongTZif2\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\x00E\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff\x85ic\x90\xff\xff\xff\xff\xcaM10\xff\xff\xff\xff\xcaۓ0\xff\xff\xff\xff\xcbKqx\xff\xff\xff\xff" +
- "Ҡސ\xff\xff\xff\xff\xd3k׀\xff\xff\xff\xffԓX\xb8\xff\xff\xff\xff\xd5B\xb08\xff\xff\xff\xff\xd6s:\xb8\xff\xff\xff\xff\xd7>A\xb8\xff\xff\xff\xff\xd8.2\xb8\xff\xff\xff\xff\xd8\xf99\xb8" +
- "\xff\xff\xff\xff\xda\x0e\x14\xb8\xff\xff\xff\xff\xda\xd9\x1b\xb8\xff\xff\xff\xff\xdb\xed\xf6\xb8\xff\xff\xff\xffܸ\xfd\xb8\xff\xff\xff\xff\xdd\xcdظ\xff\xff\xff\xffޢ\x1a8\xff\xff\xff\xff߶\xf58\xff\xff\xff\xff" +
- "\xe0\x81\xfc8\xff\xff\xff\xff\xe1\x96\xc9(\xff\xff\xff\xff\xe2Oi8\xff\xff\xff\xff\xe3v\xab(\xff\xff\xff\xff\xe4/K8\xff\xff\xff\xff\xe5_Ǩ\xff\xff\xff\xff\xe6\x0f-8\xff\xff\xff\xff\xe7?\xa9\xa8" +
- "\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff" +
- "\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28" +
- "\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15a(\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf5C(\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff" +
- "\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8" +
- "\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\a&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00" +
- "\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x02\x03\x04\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00k\n\x00\x00\x00\x00p\x80\x00\x04\x00\x00~" +
- "\x90\x01\b\x00\x00w\x88\x01\r\x00\x00~\x90\x00\x12LMT\x00HKT\x00HKST\x00HKWT\x00JST\x00\nHKT-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xba\xa3" +
- "b\xc1R\x02\x00\x00R\x02\x00\x00\t\x00\x00\x00Asia/HovdTZif2\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\x002\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff" +
- "\xff\xff\x86\xd3\xfc\x94\x00\x00\x00\x00\x0f\v\xea\xa0\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbc>\x80\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c" +
- " \x80\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x02\x80\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xe4\x80\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00#;ƀ\x00\x00\x00\x00$+Ő\x00\x00" +
- "\x00\x00%\x1b\xa8\x80\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xc5\x00\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ĉ\x00\x00\x00\x00\x00+\xb4" +
- "\x88\x10\x00\x00\x00\x00,\xa4k\x00\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84M\x00\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d/\x00\x00\x00\x00\x001]h\x90\x00\x00\x00\x002MK\x80\x00\x00" +
- "\x00\x003=J\x90\x00\x00\x00\x004--\x80\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x006\r\x0f\x80\x00\x00\x00\x00:\xe9\xc1\xb0\x00\x00\x00\x00;\xb4\xba\xa0\x00\x00\x00\x00<\xa4\xb9\xb0\x00\x00\x00\x00=\x94" +
- "\x9c\xa0\x00\x00\x00\x00>\x84\x9b\xb0\x00\x00\x00\x00?t~\xa0\x00\x00\x00\x00@d}\xb0\x00\x00\x00\x00AT`\xa0\x00\x00\x00\x00BD_\xb0\x00\x00\x00\x00C4B\xa0\x00\x00\x00\x00D$A\xb0\x00\x00" +
- "\x00\x00E\x1d_ \x00\x00\x00\x00U\x15\xa8\xb0\x00\x00\x00\x00V\x05o\x80\x00\x00\x00\x00V\xf5\x8a\xb0\x00\x00\x00\x00W\xe5Q\x80\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00U\xec\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\fLMT\x00+06\x00" +
- "+08\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9l\x03\x12\xf8\x02\x00\x00\xf8\x02\x00\x00\f\x00\x00\x00Asia/IrkutskT" +
- "Zif2\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\x00B\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xffV\xb6\x82?\xff\xff\xff\xff\xa2\x12\x0f\xbf\xff\xff\xff\xff\xb5\xa3\xd3\x10\x00\x00" +
- "\x00\x00\x15'a\x80\x00\x00\x00\x00\x16\x18\x95\xf0\x00\x00\x00\x00\x17\b\x95\x00\x00\x00\x00\x00\x17\xf9\xc9p\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbc" +
- "Z\xa0\x00\x00\x00\x00\x1c\xacK\xa0\x00\x00\x00\x00\x1d\x9c<\xa0\x00\x00\x00\x00\x1e\x8c-\xa0\x00\x00\x00\x00\x1f|\x1e\xa0\x00\x00\x00\x00 l\x0f\xa0\x00\x00\x00\x00!\\\x00\xa0\x00\x00\x00\x00\"K\xf1\xa0\x00\x00" +
- "\x00\x00#;\xe2\xa0\x00\x00\x00\x00$+Ӡ\x00\x00\x00\x00%\x1bĠ\x00\x00\x00\x00&\v\xb5\xa0\x00\x00\x00\x00'\x04\xe1 \x00\x00\x00\x00'\xf4\xd2 \x00\x00\x00\x00(\xe4\xd10\x00\x00\x00\x00)x" +
- "y0\x00\x00\x00\x00)Դ \x00\x00\x00\x00*ĥ \x00\x00\x00\x00+\xb4\x96 \x00\x00\x00\x00,\xa4\x87 \x00\x00\x00\x00-\x94x \x00\x00\x00\x00.\x84i \x00\x00\x00\x00/tZ \x00\x00" +
- "\x00\x000dK \x00\x00\x00\x001]v\xa0\x00\x00\x00\x002rQ\xa0\x00\x00\x00\x003=X\xa0\x00\x00\x00\x004R3\xa0\x00\x00\x00\x005\x1d:\xa0\x00\x00\x00\x0062\x15\xa0\x00\x00\x00\x006\xfd" +
- "\x1c\xa0\x00\x00\x00\x008\x1b2 \x00\x00\x00\x008\xdc\xfe\xa0\x00\x00\x00\x009\xfb\x14 \x00\x00\x00\x00:\xbc\xe0\xa0\x00\x00\x00\x00;\xda\xf6 \x00\x00\x00\x00<\xa5\xfd \x00\x00\x00\x00=\xba\xd8 \x00\x00" +
- "\x00\x00>\x85\xdf \x00\x00\x00\x00?\x9a\xba \x00\x00\x00\x00@e\xc1 \x00\x00\x00\x00A\x83֠\x00\x00\x00\x00BE\xa3 \x00\x00\x00\x00Cc\xb8\xa0\x00\x00\x00\x00D%\x85 \x00\x00\x00\x00EC" +
- "\x9a\xa0\x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\ue0e0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x00\x00\x00\x00J\xe3@\xa0\x00\x00\x00\x00K\xaeG\xa0\x00\x00" +
- "\x00\x00L\xcc] \x00\x00\x00\x00M\x8e)\xa0\x00\x00\x00\x00TK\xd7\x10\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x02\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\x03\x04\x03\x04\x03\x04\x03\x04\x06\x04\x00\x00a\xc1\x00\x00\x00\x00a\xc1\x00\x04\x00\x00bp\x00\b\x00\x00~\x90\x01\f\x00\x00p\x80\x00\x10\x00\x00" +
- "p\x80\x01\x10\x00\x00~\x90\x00\fLMT\x00IMT\x00+07\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\aW\x10Ѱ\x04\x00" +
- "\x00\xb0\x04\x00\x00\r\x00\x00\x00Asia/IstanbulTZif2\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\x00s\x00\x00\x00\x06\x00\x00\x00\x19\xff\xff\xff" +
- "\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9bվ\xd0\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4" +
- "\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xaa((`\xff\xff\xff\xff\xaa\xe1\xfd\xd0\xff\xff\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc31P\xff\xff\xff\xffȁ?\xe0\xff\xff\xff" +
- "\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J\xf5`\xff\xff\xff\xff\xca\u0380P\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xd2k\tP\xff\xff\xff\xffӢ9`\xff\xff\xff\xff\xd4C\x02P\xff\xff\xff\xff\xd5L\r" +
- "\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff\xff\xff\xd7+\xef\xe0\xff\xff\xff\xff\xd8\t]\xd0\xff\xff\xff\xff\xd9\x02\x97`\xff\xff\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff\xdb\xd2\\P\xff\xff\xff" +
- "\xff\xdc\xd4\xd0`\xff\xff\xff\xffݲ>P\xff\xff\xff\xff\xf1\xf4\xb9`\xff\xff\xff\xff\xf4b\xefP\xff\xff\xff\xff\xf5h\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a9\x9a" +
- "p\x00\x00\x00\x00\a\xfbu\x00\x00\x00\x00\x00\t\x19|p\x00\x00\x00\x00\t\xd0\xcb\x00\x00\x00\x00\x00\n\xf9^p\x00\x00\x00\x00\v\xb1\xfe\x80\x00\x00\x00\x00\f\xd9@p\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00" +
- "\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x0f\xf8\x11P\x00\x00\x00\x00\x19\x89\xb0p\x00\x00\x00\x00\x19ܰ\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00\x00\x00\x1c\xc6\xef\xf0\x00\x00\x00\x00\x1d\x9b1" +
- "p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00" +
- "\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdc" +
- "p\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x8b\x83\xf0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00" +
- "\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZ" +
- "p\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00" +
- "\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6" +
- "\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8fݐ\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00" +
- "\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V>\x9e" +
- "\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01\x15LMT\x00IMT\x00EEST" +
- "\x00EET\x00+03\x00+04\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xadű\xf8\x00\x00\x00\xf8\x00\x00\x00\f\x00\x00\x00Asia/Jak" +
- "artaTZif2\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\b\x00\x00\x00\a\x00\x00\x00 \xff\xff\xff\xff?fI`\xff\xff\xff\xff\xa9x\x85\xe0\xff\xff\xff\xff\xba" +
- "\x16\xde`\xff\xff\xff\xff˿\x83\x88\xff\xff\xff\xff\xd2V\xeep\xff\xff\xff\xff\xd7<\xc6\b\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xf4\xb5\xbe\x88\x01\x02\x03\x04\x03\x05\x03\x06\x00\x00d \x00\x00\x00\x00d" +
- " \x00\x04\x00\x00g \x00\b\x00\x00ix\x00\x0e\x00\x00~\x90\x00\x14\x00\x00p\x80\x00\x18\x00\x00bp\x00\x1cLMT\x00BMT\x00+0720\x00+0730\x00+09\x00+08" +
- "\x00WIB\x00\nWIB-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.>[K\xab\x00\x00\x00\xab\x00\x00\x00\r\x00\x00\x00Asia/JayapuraTZif2" +
- "\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\x03\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\xba\x16\xc1\x98\xff\xff\xff\xff\xd0X\xb9\xf0\xff\xff\xff\xff\xf4\xb5\xa2h\x01\x02\x03\x00\x00\x83" +
- "\xe8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x00\b\x00\x00~\x90\x00\x0eLMT\x00+09\x00+0930\x00WIT\x00\nWIT-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x17✳2\x04\x00\x002\x04\x00\x00\x0e\x00\x00\x00Asia/JerusalemTZif3\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\x00d\x00\x00\x00" +
- "\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\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\xd7Z0\x80\xff\xff\xff\xff\xd7\xdfX\x00\xff\xff\xff\xff\xd8/À\xff\xff\xff\xff\xd9\x1ec\x00\xff\xff\xff\xff\xda\x10\xf7\x00\xff\xff\xff\xff\xda\xeb\xd0\x00\xff\xff\xff\xff۴4\x00\xff\xff\xff\xffܹ=" +
- "\x00\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\u07b4\u0380\xff\xff\xff\xffߤ\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2\xbef\x80\xff\xff\xff\xff\xe36_\x00\xff\xff\xff" +
- "\xff\xe4\x9eH\x80\xff\xff\xff\xff\xe5\x16A\x00\xff\xff\xff\xff\xe6t\xf0\x00\xff\xff\xff\xff\xe7\x11Ҁ\xff\xff\xff\xff\xe8&\xad\x80\xff\xff\xff\xff\xe8\xe8z\x00\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\x001H\x96\xe0\x00\x00\x00\x002<n" +
- "P\x00\x00\x00\x0031\xb3`\x00\x00\x00\x004\x1a\xfe\xd0\x00\x00\x00\x005\x11\x95`\x00\x00\x00\x005\xf1\xa6P\x00\x00\x00\x007\x04\b\x80\x00\x00\x00\x007\xcf\x01p\x00\x00\x00\x008\xf6_\x80\x00\x00\x00" +
- "\x009\xdc\xf9\xe0\x00\x00\x00\x00:\xd0\xedp\x00\x00\x00\x00;\xae[`\x00\x00\x00\x00<\xa3\xa0p\x00\x00\x00\x00=\xa0\xb2`\x00\x00\x00\x00>\x83\x82p\x00\x00\x00\x00?|\x9f\xe0\x00\x00\x00\x00@s6" +
- "p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F\fS\x00\x00\x00\x00\x00F\xecc\xf0\x00\x00\x00" +
- "\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\t\xf0\x00\x00\x00\x00M\x95\x15\x80\x00\x00\x00\x00N\x87\x9b" +
- "p\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QTـ\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\f\x00\x008@\x01\x10LMT\x00JMT\x00IDT\x00IST\x00IDDT\x00\nIST" +
- "-2IDT,M3.4.4/26,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\xe2\\\xff\x9f\x00\x00\x00\x9f\x00\x00\x00\n\x00\x00\x00Asia/K" +
- "abulTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffi\x86\x9a\xa0\xff\xff\xff\xff\xd0\xf9\xd7@\x01\x02\x00\x00@" +
- "\xe0\x00\x00\x00\x008@\x00\x04\x00\x00?H\x00\bLMT\x00+04\x00+0430\x00\n<+0430>-4:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x9cf" +
- ">\xd7\x02\x00\x00\xd7\x02\x00\x00\x0e\x00\x00\x00Asia/KamchatkaTZif2\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\x05\x00\x00" +
- "\x00\x10\xff\xff\xff\xff\xa7R\x96\xc4\xff\xff\xff\xff\xb5\xa3\x9a\xd0\x00\x00\x00\x00\x15')@\x00\x00\x00\x00\x16\x18]\xb0\x00\x00\x00\x00\x17\b\\\xc0\x00\x00\x00\x00\x17\xf9\x910\x00\x00\x00\x00\x18\xe9\x90@\x00\x00" +
- "\x00\x00\x19\xdaİ\x00\x00\x00\x00\x1a\xcc\x15@\x00\x00\x00\x00\x1b\xbc\"`\x00\x00\x00\x00\x1c\xac\x13`\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00\x1e\x8b\xf5`\x00\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k" +
- "\xd7`\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\"K\xb9`\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\x9b`\x00\x00\x00\x00%\x1b\x8c`\x00\x00\x00\x00&\v}`\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00" +
- "\x00\x00'\xf4\x99\xe0\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)x@\xf0\x00\x00\x00\x00)\xd4{\xe0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4]\xe0\x00\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-\x94" +
- "?\xe0\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t!\xe0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]>`\x00\x00\x00\x002r\x19`\x00\x00\x00\x003= `\x00\x00\x00\x004Q\xfb`\x00\x00" +
- "\x00\x005\x1d\x02`\x00\x00\x00\x0061\xdd`\x00\x00\x00\x006\xfc\xe4`\x00\x00\x00\x008\x1a\xf9\xe0\x00\x00\x00\x008\xdc\xc6`\x00\x00\x00\x009\xfa\xdb\xe0\x00\x00\x00\x00:\xbc\xa8`\x00\x00\x00\x00;\xda" +
- "\xbd\xe0\x00\x00\x00\x00<\xa5\xc4\xe0\x00\x00\x00\x00=\xba\x9f\xe0\x00\x00\x00\x00>\x85\xa6\xe0\x00\x00\x00\x00?\x9a\x81\xe0\x00\x00\x00\x00@e\x88\xe0\x00\x00\x00\x00A\x83\x9e`\x00\x00\x00\x00BEj\xe0\x00\x00" +
- "\x00\x00Cc\x80`\x00\x00\x00\x00D%L\xe0\x00\x00\x00\x00ECb`\x00\x00\x00\x00F\x05.\xe0\x00\x00\x00\x00G#D`\x00\x00\x00\x00G\xeeK`\x00\x00\x00\x00I\x03&`\x00\x00\x00\x00I\xce" +
- "-`\x00\x00\x00\x00J\xe3\b`\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x00\x94\xbc\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\xb6\xd0\x01\b\x00\x00\xa8\xc0" +
- "\x00\f\x00\x00\xa8\xc0\x01\fLMT\x00+11\x00+13\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009Y\xb7\xf1\n\x01\x00\x00\n\x01\x00\x00" +
- "\f\x00\x00\x00Asia/KarachiTZif2\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\v\x00\x00\x00\x06\x00\x00\x00\x1d\xff\xff\xff\xff\x89~\xfc\xa4\xff" +
- "\xff\xff\xff̕2\xa8\xff\xff\xff\xff\xd2t\x12\x98\xff\xff\xff\xffݨ\xe0\xa8\x00\x00\x00\x00\x02O\xab0\x00\x00\x00\x00<\xafE\xb0\x00\x00\x00\x00=\x9f(\xa0\x00\x00\x00\x00HA\xa00\x00\x00\x00\x00I" +
- "\vG\xa0\x00\x00\x00\x00I\xe4\xdd0\x00\x00\x00\x00J\xec{ \x01\x02\x01\x03\x05\x04\x05\x04\x05\x04\x05\x00\x00>\xdc\x00\x00\x00\x00MX\x00\x04\x00\x00[h\x01\n\x00\x00FP\x00\x10\x00\x00T`\x01\x14" +
- "\x00\x00FP\x00\x19LMT\x00+0530\x00+0630\x00+05\x00PKST\x00PKT\x00\nPKT-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b" +
- "\x85\x00\x00\x00\x85\x00\x00\x00\f\x00\x00\x00Asia/KashgarTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff" +
- "\xff\xff\xff\xb0\xfe\xbad\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8bSnT\xa1\x00\x00\x00\xa1" +
- "\x00\x00\x00\x0e\x00\x00\x00Asia/KathmanduTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xff" +
- "\xa1\xf2}\x84\x00\x00\x00\x00\x1e\x180\xa8\x01\x02\x00\x00O\xfc\x00\x00\x00\x00MX\x00\x04\x00\x00P\xdc\x00\nLMT\x00+0530\x00+0545\x00\n<+0545>-5:4" +
- "5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\r\x00\x00\x00Asia/KatmanduTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf2}\x84\x00\x00\x00\x00\x1e\x180\xa8\x01\x02\x00\x00O\xfc\x00\x00\x00\x00MX\x00\x04\x00\x00P\xdc\x00\nLMT\x00" +
- "+0530\x00+0545\x00\n<+0545>-5:45\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x83g\x95M\a\x03\x00\x00\a\x03\x00\x00\r\x00\x00\x00Asia" +
- "/KhandygaTZif2\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\x00" +
- "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\x00C\x00\x00\x00\b\x00\x00\x00\x14\xff\xff\xff\xff\xa1\xdb\xe4\xeb\xff\xff\xff\xff\xb5\xa3\xc5\x00" +
- "\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\b\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00" +
- "\x1b\xbcL\x90\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\"K\xe3\x90" +
- "\x00\x00\x00\x00#;Ԑ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00" +
- ")xk \x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ė\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL\x10" +
- "\x00\x00\x00\x000d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\a\x90\x00\x00\x00\x00" +
- "6\xfd\x0e\x90\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbcҐ\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10" +
- "\x00\x00\x00\x00>\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00?\xf2\xe4p\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00" +
- "D%i\x00\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80" +
- "\x00\x00\x00\x00K\xae+\x80\x00\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\r\x80\x00\x00\x00\x00Nn\x02P\x00\x00\x00\x00TK\xc9\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\x06\x03\x00\x00\x7f\x15\x00\x00\x00\x00p\x80\x00\x04\x00" +
- "\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\f\x00\x00\x9a\xb0\x01\x10\x00\x00\x8c\xa0\x00\b\x00\x00\x9a\xb0\x00\x10LMT\x00+08\x00+10\x00+09\x00+11\x00\n<+09" +
- ">-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\f\x00\x00\x00Asia/KolkataTZif2\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\a\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff&\xba\x18(\xff\xff\xff\xffC\xe7\xeb0\xff\xff\xff\xff\x87\x9d\xbc\xba\xff\xff\xff\xff\xcaی(\xff\xff\xff\xff\xcc\x05q" +
- "\x18\xff\xff\xff\xff̕2\xa8\xff\xff\xff\xff\xd2t\x12\x98\x01\x02\x03\x04\x03\x04\x03\x00\x00R\xd8\x00\x00\x00\x00R\xd0\x00\x04\x00\x00KF\x00\b\x00\x00MX\x00\f\x00\x00[h\x01\x10LMT\x00HM" +
- "T\x00MMT\x00IST\x00+0630\x00\nIST-5:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\xe0\x91y\xe5\x02\x00\x00\xe5\x02\x00\x00\x10\x00\x00\x00Asia" +
- "/KrasnoyarskTZif2\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\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf9\r\xf2\xff\xff\xff\xff\xb5" +
- "\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00" +
- "\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"" +
- "K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00" +
- "\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/" +
- "th0\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dH\xb0\x00\x00\x00\x0062#\xb0\x00" +
- "\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\f\xb0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\v0\x00\x00\x00\x00=" +
- "\xba\xe60\x00\x00\x00\x00>\x85\xed0\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xcf0\x00\x00\x00\x00A\x83\xe4\xb0\x00\x00\x00\x00BE\xb10\x00\x00\x00\x00Ccư\x00\x00\x00\x00D%\x930\x00" +
- "\x00\x00\x00EC\xa8\xb0\x00\x00\x00\x00F\x05u0\x00\x00\x00\x00G#\x8a\xb0\x00\x00\x00\x00G\ue470\x00\x00\x00\x00I\x03l\xb0\x00\x00\x00\x00I\xces\xb0\x00\x00\x00\x00J\xe3N\xb0\x00\x00\x00\x00K" +
- "\xaeU\xb0\x00\x00\x00\x00L\xcck0\x00\x00\x00\x00M\x8e7\xb0\x00\x00\x00\x00TK\xe5 \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00W\x0e\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp" +
- "\x01\f\x00\x00p\x80\x00\bLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x11" +
- "\x00\x00\x00Asia/Kuala_LumpurTZif2\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\b\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff~" +
- "6S\xa3\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xbagN\x90\xff\xff\xff\xff\xc0\n\xe4`\xff\xff\xff\xffʳ\xe5`\xff\xff\xff\xffˑ_\b\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xee\x00\x01" +
- "\x02\x03\x04\x05\x06\x05\a\x00\x00a]\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00S" +
- "MT\x00+07\x00+0720\x00+0730\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7f^]@\x01\x00\x00@\x01" +
- "\x00\x00\f\x00\x00\x00Asia/KuchingTZif2\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\x12\x00\x00\x00\x05\x00\x00\x00\x18\xff\xff\xff\xff\xad\x8a\x06" +
- "\x90\xff\xff\xff\xff\xbagG\x88\xff\xff\xff\xff\xbf{'\x80\xff\xff\xff\xff\xbf\xf3\x1bP\xff\xff\xff\xff\xc1]\xac\x80\xff\xff\xff\xff\xc1ՠP\xff\xff\xff\xff\xc3>\xe0\x00\xff\xff\xff\xffö\xd3\xd0\xff\xff\xff" +
- "\xff\xc5 \x13\x80\xff\xff\xff\xffŘ\aP\xff\xff\xff\xff\xc7\x01G\x00\xff\xff\xff\xff\xc7y:\xd0\xff\xff\xff\xff\xc8\xe3\xcc\x00\xff\xff\xff\xff\xc9[\xbf\xd0\xff\xff\xff\xff\xca\xc4\xff\x80\xff\xff\xff\xff\xcb<\xf3" +
- "P\xff\xff\xff\xffˑX\x00\xff\xff\xff\xff\xd2Hm\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x00\x00gp\x00\x00\x00\x00ix\x00\x04\x00\x00u0\x01\n\x00\x00p\x80\x00\x10\x00" +
- "\x00~\x90\x00\x14LMT\x00+0730\x00+0820\x00+08\x00+09\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00" +
- "\x85\x00\x00\x00\v\x00\x00\x00Asia/KuwaitTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b" +
- "6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d?v\f\x17\x03\x00\x00\x17\x03\x00\x00\n\x00" +
- "\x00\x00Asia/MacaoTZif2\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\x00G\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x85i[\x8e\xff\xff\xff\xff\xcb" +
- "Gu\xf0\xff\xff\xff\xff\xcb\xf2\xca\xe0\xff\xff\xff\xff\xcc\xfb\xbaP\xff\xff\xff\xff\xcd\xd3\xfe`\xff\xff\xff\xffΝ\xa5\xd0\xff\xff\xff\xff\xd2azp\xff\xff\xff\xff\xd3x\xf8p\xff\xff\xff\xff\xd4B\xad\xf0\xff" +
- "\xff\xff\xff\xd5K\xabp\xff\xff\xff\xff\xd6tL\xf0\xff\xff\xff\xff\xd7?S\xf0\xff\xff\xff\xff\xd8/D\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xda\r\xd5p\xff\xff\xff\xff\xda\xd8\xdcp\xff\xff\xff\xff\xdb" +
- "\xed\xb7p\xff\xff\xff\xffܸ\xbep\xff\xff\xff\xff\xdd\xce\xea\xf0\xff\xff\xff\xffޡ\xda\xf0\xff\xff\xff\xff߶\xb5\xf0\xff\xff\xff\xff\xe0\x81\xbc\xf0\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2O)\xf0\xff" +
- "\xff\xff\xff\xe3vy\xf0\xff\xff\xff\xff\xe4/\v\xf0\xff\xff\xff\xff\xe5_\x96p\xff\xff\xff\xff\xe6\x0e\xed\xf0\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9" +
- "\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff" +
- "\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8" +
- "\x15S\x18\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf55\x18\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff" +
- "\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x06" +
- "7\x038\x00\x00\x00\x00\a&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00" +
- "\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x03\x02\x03\x02\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" +
- "\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x00\x00jr\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\x10LMT\x00" +
- "CST\x00+10\x00+09\x00CDT\x00\nCST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d?v\f\x17\x03\x00\x00\x17\x03\x00\x00\n\x00\x00\x00Asia/Ma" +
- "cauTZif2\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\x00G\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x85i[\x8e\xff\xff\xff\xff\xcbGu\xf0\xff\xff\xff\xff\xcb\xf2" +
- "\xca\xe0\xff\xff\xff\xff\xcc\xfb\xbaP\xff\xff\xff\xff\xcd\xd3\xfe`\xff\xff\xff\xffΝ\xa5\xd0\xff\xff\xff\xff\xd2azp\xff\xff\xff\xff\xd3x\xf8p\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5K\xabp\xff\xff" +
- "\xff\xff\xd6tL\xf0\xff\xff\xff\xff\xd7?S\xf0\xff\xff\xff\xff\xd8/D\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xda\r\xd5p\xff\xff\xff\xff\xda\xd8\xdcp\xff\xff\xff\xff\xdb\xed\xb7p\xff\xff\xff\xffܸ" +
- "\xbep\xff\xff\xff\xff\xdd\xce\xea\xf0\xff\xff\xff\xffޡ\xda\xf0\xff\xff\xff\xff߶\xb5\xf0\xff\xff\xff\xff\xe0\x81\xbc\xf0\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe3vy\xf0\xff\xff" +
- "\xff\xff\xe4/\v\xf0\xff\xff\xff\xff\xe5_\x96p\xff\xff\xff\xff\xe6\x0e\xed\xf0\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xff" +
- "m\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff" +
- "\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15S\x18\xff\xff\xff\xff\xf9\x05" +
- "`8\xff\xff\xff\xff\xf9\xf55\x18\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00" +
- "\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\a&" +
- "\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc78\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00\x00\x00\x00\x11\x9b98\x00\x00" +
- "\x00\x00\x12ol\xa8\x01\x03\x02\x03\x02\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" +
- "\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x00\x00jr\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00~\x90\x00\f\x00\x00~\x90\x01\x10LMT\x00CST\x00+10\x00+" +
- "09\x00CDT\x00\nCST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4_P\x18\xef\x02\x00\x00\xef\x02\x00\x00\f\x00\x00\x00Asia/MagadanTZif" +
- "2\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\x00B\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x196\xa0\xff\xff\xff\xff\xb5\xa3\xa8\xe0\x00\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16" +
- "\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00" +
- "\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$" +
- "+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)ԉ\xf0\x00" +
- "\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001" +
- "]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\tp\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\a\xf0\x00" +
- "\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xcb\xf0\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?" +
- "\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00" +
- "\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce;p\x00\x00\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M" +
- "\x8d\xffp\x00\x00\x00\x00TK\xac\xe0\x00\x00\x00\x00W\x1b\x9c\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x01\x03\x00\x00\x8d`\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\f\x00\x00\x9a\xb0\x01\f\x00\x00\xa8\xc0\x00" +
- "\bLMT\x00+10\x00+12\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xc9\xd4\\\xbe\x00\x00\x00\xbe\x00\x00\x00\r\x00\x00\x00Asi" +
- "a/MakassarTZif2\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\x04\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\xa1\xf2]\x90\xff\xff\xff\xff\xba\x16\xd5" +
- "\x90\xff\xff\xff\xffˈ\x1d\x80\xff\xff\xff\xff\xd2V\xeep\x01\x02\x03\x04\x00\x00o\xf0\x00\x00\x00\x00o\xf0\x00\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\f\x00\x00p\x80\x00\x10LMT\x00MMT\x00+" +
- "08\x00+09\x00WITA\x00\nWITA-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ǯ\xdf\x1c\xee\x00\x00\x00\xee\x00\x00\x00\v\x00\x00\x00Asia/Manil" +
- "aTZif2\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\n\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\x14\xe1\xdc\x10\xff\xff\xff\xff{\x1f?\x90\xff\xff\xff\xff\xc1\x9c\xf4\x80" +
- "\xff\xff\xff\xff\xc2\x160p\xff\xff\xff\xff\xcb\xf2\xe7\x00\xff\xff\xff\xffЩ%p\xff\xff\xff\xff\xe2l9\x00\xff\xff\xff\xff\xe2բ\xf0\x00\x00\x00\x00\x0fuF\x80\x00\x00\x00\x00\x10fz\xf0\x01\x03\x02\x03" +
- "\x04\x03\x02\x03\x02\x03\xff\xff\x1f\xf0\x00\x00\x00\x00qp\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\fLMT\x00PDT\x00PST\x00JST\x00\nPST-8\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00Asia/MuscatTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\f\x00\x00\x00Asia/NicosiaTZif2\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" +
- "\x001\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\xa5w\x1e\xb8\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\nݒ\xd0\x00\x00\x00\x00\v\xfad\xe0\x00\x00\x00\x00\f\xbe\xc6P\x00\x00\x00\x00\r\xa49`\x00\x00" +
- "\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#" +
- "\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00" +
- "\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<" +
- "\f\xd0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00" +
- "\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]" +
- "\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062x\x10\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\x00\x00\x1fH\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EE" +
- "T\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\x9a\x90\xf7\xd6\x02\x00\x00\xd6\x02\x00\x00\x11\x00" +
- "\x00\x00Asia/NovokuznetskTZif2\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\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x18" +
- " \xc0\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00" +
- "\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\" +
- "\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00" +
- "\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84" +
- "w0\x00\x00\x00\x00/th0\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dH\xb0\x00\x00" +
- "\x00\x0062#\xb0\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\f\xb0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6" +
- "\v0\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00>\x85\xed0\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xcf0\x00\x00\x00\x00A\x83\xe4\xb0\x00\x00\x00\x00BE\xb10\x00\x00\x00\x00Ccư\x00\x00" +
- "\x00\x00D%\x930\x00\x00\x00\x00EC\xa8\xb0\x00\x00\x00\x00F\x05u0\x00\x00\x00\x00G#\x8a\xb0\x00\x00\x00\x00G\ue470\x00\x00\x00\x00I\x03l\xb0\x00\x00\x00\x00I\xces\xb0\x00\x00\x00\x00J\xe3" +
- "N\xb0\x00\x00\x00\x00K\xaeU\xb0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x00Q\xc0\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x01\f" +
- "LMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)p\x1cX\xf1\x02\x00\x00\xf1\x02\x00\x00\x10\x00\x00\x00Asia/" +
- "NovosibirskTZif2\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\x00C\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\x19$\xff\xff\xff\xff\xb5\xa3" +
- "\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00" +
- "\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K" +
- "\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00" +
- "\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00+\xfeN\x00\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00\x00\x00\x00.\x84" +
- "\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00" +
- "\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6" +
- "\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00" +
- "\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00\x00\x00J\xe3" +
- "\\\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00W\x93\xcc\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00M\xbc\x00\x00\x00\x00T`\x00" +
- "\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00bp\x01\fLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x11" +
- "\xea\xa2\xe5\x02\x00\x00\xe5\x02\x00\x00\t\x00\x00\x00Asia/OmskTZif2\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\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff" +
- "\xff\xff\xa1\xb3@\xb6\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb" +
- "\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00" +
- "\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4" +
- "\xee@\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xb2@\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00\x00" +
- "\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1d" +
- "V\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00" +
- "\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc" +
- "\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00" +
- "\x00\x00J\xe3\\\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00D\xca\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01" +
- "\b\x00\x00T`\x00\f\x00\x00T`\x01\f\x00\x00bp\x00\bLMT\x00+05\x00+07\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\xe9" +
- "\xd1\xd8q\x02\x00\x00q\x02\x00\x00\t\x00\x00\x00Asia/OralTZif2\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\x003\x00\x00\x00\a\x00\x00\x00\x14\xff\xff" +
- "\xff\xff\xaa\x19\x93\xdc\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb" +
- "' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00" +
- "\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5" +
- "\n`\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00" +
- "\x00\x00.\x84\xa1`\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1d" +
- "r\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00" +
- "\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x02\x00\x000$\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01" +
- "\f\x00\x00T`\x00\f\x00\x00FP\x01\b\x00\x008@\x00\x10LMT\x00+03\x00+05\x00+06\x00+04\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x00\x00Asia/Phnom_PenhTZif2\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\x02" +
- "\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+07\x00\n<+0" +
- "7>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xa5\x81e\xf7\x00\x00\x00\xf7\x00\x00\x00\x0e\x00\x00\x00Asia/PontianakTZif2\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\b\x00\x00\x00\a\x00\x00\x00\x1f\xff\xff\xff\xff\x8b\xff\x8e\x00\xff\xff\xff\xff\xba\x16\xdf\x00\xff\xff\xff\xff\xcby\xa4\b\xff\xff\xff\xff\xd2V\xeep\xff\xff\xff\xff" +
- "\xd7<\xc6\b\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xf4\xb5\xbe\x88\x00\x00\x00\x00!\xdat\x80\x01\x02\x03\x02\x04\x02\x05\x06\x00\x00f\x80\x00\x00\x00\x00f\x80\x00\x04\x00\x00ix\x00\b\x00\x00~\x90\x00\x0e" +
- "\x00\x00p\x80\x00\x12\x00\x00p\x80\x00\x16\x00\x00bp\x00\x1bLMT\x00PMT\x00+0730\x00+09\x00+08\x00WITA\x00WIB\x00\nWIB-7\nPK\x03\x04" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\xc1\x1eB\xb7\x00\x00\x00\xb7\x00\x00\x00\x0e\x00\x00\x00Asia/PyongyangTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x8b\xd7\xf1\x9c\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2/ap\x00\x00\x00\x00U\xce\x02p\x00\x00\x00\x00Z\xecup\x01\x02\x03\x01\x03" +
- "\x00\x00u\xe4\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x00\x04LMT\x00KST\x00JST\x00\nKST-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdav\x19" +
- "z\x98\x00\x00\x00\x98\x00\x00\x00\n\x00\x00\x00Asia/QatarTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff" +
- "\xff\xff\xa1\xf2\x9d0\x00\x00\x00\x00\x04\x8a\x92\xc0\x01\x02\x00\x000P\x00\x00\x00\x008@\x00\x04\x00\x00*0\x00\bLMT\x00+04\x00+03\x00\n<+03>-3\nPK\x03\x04\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xfax\x98g\x02\x00\x00g\x02\x00\x00\r\x00\x00\x00Asia/QostanayTZif2\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\x003\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x88\\\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3" +
- "\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00" +
- "\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf" +
- "\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00" +
- "\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82" +
- "\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\\P\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00" +
- "\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00" +
- "\xd0\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x00\x00;\xa4\x00\x00\x00\x00" +
- "8@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x01\bLMT\x00+04\x00+05\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xd5ΜGp\x02\x00\x00p\x02\x00\x00\x0e\x00\x00\x00Asia/QyzylordaTZif2\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\x004\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x86\xa0\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0" +
- "\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00" +
- "\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0" +
- "\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00" +
- ",\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0" +
- "\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\\P\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00" +
- ":\xbd\n\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0" +
- "\x00\x00\x00\x00\\\x1bؠ\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x02\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02" +
- "\x00\x00=`\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00T`\x00\f\x00\x00FP\x01\bLMT\x00+04\x00+05\x00+06\x00\n<+05>-5" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\f\x00\x00\x00Asia/RangoonTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xffњg\xf0\x01\x02\x03\x02\x00\x00Z/\x00\x00" +
- "\x00\x00Z/\x00\x04\x00\x00[h\x00\b\x00\x00~\x90\x00\x0eLMT\x00RMT\x00+0630\x00+09\x00\n<+0630>-6:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00Asia/RiyadhTZif2\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\x01\x00\x00" +
- "\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000I" +
- "\xc7\xde\xec\x00\x00\x00\xec\x00\x00\x00\v\x00\x00\x00Asia/SaigonTZif2\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\t\x00\x00\x00\x05\x00\x00\x00\x15" +
- "\xff\xff\xff\xff\x88\x8cC\x8a\xff\xff\xff\xff\x91\xa3+\n\xff\xff\xff\xff\xcd5\xe6\x80\xff\xff\xff\xff\xd1Y\xcep\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd52\xbb\x10\xff\xff\xff\xff\xe4\xb6\xe4\x80\xff\xff\xff\xff" +
- "\xed/\x98\x00\x00\x00\x00\x00\n=\xc7\x00\x01\x02\x03\x04\x02\x03\x02\x03\x02\x00\x00c\xf6\x00\x00\x00\x00c\xf6\x00\x04\x00\x00bp\x00\t\x00\x00p\x80\x00\r\x00\x00~\x90\x00\x11LMT\x00PLMT\x00" +
- "+07\x00+08\x00+09\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x15II\xf3\x02\x00\x00\xf3\x02\x00\x00\r\x00\x00\x00Asia/Sakh" +
- "alinTZif2\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\x00B\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\x86\xf0\u0378\xff\xff\xff\xff\xd20\xb2\xf0\x00\x00\x00\x00\x15" +
- "'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00" +
- "\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#" +
- ";\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00" +
- "\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000" +
- "d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00" +
- "\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xfa\xf8\x00\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>" +
- "\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D%i\x00\x00\x00\x00\x00EC~\x80\x00" +
- "\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00\x00\x00\x00K\xae+\x80\x00\x00\x00\x00L" +
- "\xccA\x00\x00\x00\x00\x00M\x8e\r\x80\x00\x00\x00\x00TK\xba\xf0\x00\x00\x00\x00V\xf6\xb2\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\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\x03\x05\x03\x00\x00\x85\xc8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\f\x00\x00\x9a" +
- "\xb0\x01\f\x00\x00\x8c\xa0\x00\x10LMT\x00+09\x00+12\x00+11\x00+10\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w\rD\an\x01\x00" +
- "\x00n\x01\x00\x00\x0e\x00\x00\x00Asia/SamarkandTZif2\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\x18\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff" +
- "\xff\xff\xaa\x19\x857\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb" +
- "' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00" +
- "\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00'\xf4" +
- "\xfcP\x00\x00\x00\x00(\xe4\xedP\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00>\xc9\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\b\x00\x00T`\x01\f\x00\x00" +
- "T`\x00\fLMT\x00+04\x00+05\x00+06\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\n\x00\x00\x00A" +
- "sia/SeoulTZif2\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\x00" +
- "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\x1d\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\x8b\xd7\xf0x\xff\xff\xff\xff\x92\xe6\x16\xf8" +
- "\xff\xff\xff\xff\xd2C'\xf0\xff\xff\xff\xff\xd7e\x8fp\xff\xff\xff\xff\xd7\xee\x9d`\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd-\xe0\xff\xff\xff\xff\xda\u05ca\xf0\xff\xff\xff\xffۭ\x0f\xe0\xff\xff\xff\xff" +
- "\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xf1\xe0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe4k\xb7\xf8\xff\xff\xff\xff\xe5\x13\x18h\xff\xff\xff\xff\xe6b\x03x\xff\xff\xff\xff\xe7\x11L\xe8\xff\xff\xff\xff\xe8/px" +
- "\xff\xff\xff\xff\xe8\xe7\xf4h\xff\xff\xff\xff\xea\x0fRx\xff\xff\xff\xff\xea\xc7\xd6h\xff\xff\xff\xff\xeb\xef4x\xff\xff\xff\xff째h\xff\xff\xff\xff\xed\xcf\x16x\xff\xff\xff\xff\ue1dah\xff\xff\xff\xff" +
- "\xf05qx\x00\x00\x00\x00 \xa3`\x90\x00\x00\x00\x00!ng\x90\x00\x00\x00\x00\"\x83B\x90\x00\x00\x00\x00#NI\x90\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01" +
- "\x04\x03\x04\x03\x04\x00\x00w\b\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x01\f\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x01\fLMT\x00KST\x00JST\x00KDT\x00\nKS" +
- "T-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\r\x00\x00\x00Asia/ShanghaiTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t" +
- "\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff" +
- "\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~" +
- "\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00" +
- "\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\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\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00" +
- "\bLMT\x00CDT\x00CST\x00\nCST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x0e\x00\x00\x00Asia/Singa" +
- "poreTZif2\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\b\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff~6S\xa3\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xba" +
- "gN\x90\xff\xff\xff\xff\xc0\n\xe4`\xff\xff\xff\xffʳ\xe5`\xff\xff\xff\xffˑ_\b\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xee\x00\x01\x02\x03\x04\x05\x06\x05\a\x00\x00a]\x00\x00\x00\x00a" +
- "]\x00\x04\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+07" +
- "30\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4Zߐ\xe6\x02\x00\x00\xe6\x02\x00\x00\x12\x00\x00\x00Asia/Sredn" +
- "ekolymskTZif2\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\x00T" +
- "Zif2\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\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x193\xe4\xff\xff\xff\xff\xb5\xa3\xa8\xe0\x00" +
- "\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b" +
- "\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p\x00" +
- "\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)" +
- "xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00" +
- "\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\tp\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x006" +
- "\xfc\xf2p\x00\x00\x00\x008\x1b\a\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xcb\xf0\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00" +
- "\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00E" +
- "Cpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce;p\x00\x00\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00" +
- "\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00TK\xac\xe0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00\x90\x1c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x01\b\x00\x00\x9a\xb0\x00\f\x00\x00\x9a\xb0\x01\f\x00\x00" +
- "\xa8\xc0\x00\bLMT\x00+10\x00+12\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\v\x00\x00\x00" +
- "Asia/TaipeiTZif2\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\x10\xff\xff\xff\xfft\xce\xf0\x18\xff\xff\xff\xff\xc3U" +
- "I\x80\xff\xff\xff\xff\xd2TY\x80\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff" +
- "\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9\xe7\x99\xf0\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xdb\xc8\xcdp\xff\xff\xff\xff\xdc\xe0Y\x80\xff\xff\xff\xffݪ\x00\xf0\xff\xff\xff\xff\xders\x00\xff\xff\xff\xffߵ" +
- "dp\xff\xff\xff\xff\xe0|\x85\x00\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2]\xb8\x80\xff\xff\xff\xff\xe3w\xcbp\xff\xff\xff\xff\xe4>\xec\x00\xff\xff\xff\xff\xe50 p\xff\xff\xff\xff\xe6!q\x00\xff\xff" +
- "\xff\xff\xe7\x12\xa5p\xff\xff\xff\xff\xe8\x02\xa4\x80\xff\xff\xff\xff\xe8\xf3\xd8\xf0\xff\xff\xff\xff\xe9\xe3\xd8\x00\xff\xff\xff\xff\xea\xd5\fp\xff\xff\xff\xff\xeb\xc5\v\x80\xff\xff\xff\xff\xec\xb6?\xf0\xff\xff\xff\xff\xed\xf7" +
- "\xfc\x00\xff\xff\xff\xff\xee\x98\xc4\xf0\xff\xff\xff\xff\xef\xd9/\x80\xff\xff\xff\xff\xf0y\xf8p\x00\x00\x00\x00\a\xfcV\x00\x00\x00\x00\x00\b\xed\x8ap\x00\x00\x00\x00\t݉\x80\x00\x00\x00\x00\nν\xf0\x00\x00" +
- "\x00\x00\x11ۡ\x80\x00\x00\x00\x00\x12T\xddp\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x00\x00q\xe8\x00" +
- "\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x01\fLMT\x00CST\x00JST\x00CDT\x00\nCST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xe27Y" +
- "n\x01\x00\x00n\x01\x00\x00\r\x00\x00\x00Asia/TashkentTZif2\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\x18\x00\x00\x00\x05\x00\x00\x00\x10" +
- "\xff\xff\xff\xff\xaa\x19\x83\t\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\b\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00" +
- "\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0" +
- "\x00\x00\x00\x00!\\\x1c\xc0\x00\x00\x00\x00\"L\r\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\v\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00" +
- "'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x00\x00@\xf7\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\b\x00\x00T`\x00\f" +
- "\x00\x00T`\x01\fLMT\x00+05\x00+07\x00+06\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ѿ\xa8\xc7u\x02\x00\x00u\x02\x00\x00\f\x00\x00" +
- "\x00Asia/TbilisiTZif2\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\x004\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xba\x01\xff\xff\xff\xff" +
- "\xaa\x19\x9a\x01\xff\xff\xff\xff\xe7\xda\fP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50" +
- "\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00" +
- "!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`" +
- "\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00" +
- "/tv@\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd8\xc0" +
- "\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00" +
- ">\x85\xfb@\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00@\xddǰ\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
- "\x04\x03\x04\x03\x04\x03\x04\x05\x02\x05\x02\x05\x02\x05\x04\x03\x04\x03\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x02\x04\x00\x00)\xff\x00\x00\x00\x00)\xff\x00\x04\x00\x00*0\x00\t\x00\x00FP\x01\r" +
- "\x00\x008@\x00\x11\x00\x008@\x01\x11LMT\x00TBMT\x00+03\x00+05\x00+04\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xdb?\xec" +
- ",\x03\x00\x00,\x03\x00\x00\v\x00\x00\x00Asia/TehranTZif2\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\x00G\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff" +
- "\xff\xff\x9al}\xc8\xff\xff\xff\xff\xbf\x00\xccH\x00\x00\x00\x00\r\x94D8\x00\x00\x00\x00\x0e\xad\x13\xb8\x00\x00\x00\x00\x0fys@\x00\x00\x00\x00\x10(\xca\xc0\x00\x00\x00\x00\x10\xed:@\x00\x00\x00\x00\x11\xad" +
- "\xbcH\x00\x00\x00\x00\x12EJ\xb8\x00\x00\x00\x00\x137\xec\xc8\x00\x00\x00\x00\x14-\x15\xb8\x00\x00\x00\x00( v\xc8\x00\x00\x00\x00(\u06dd\xb8\x00\x00\x00\x00)˜\xc8\x00\x00\x00\x00*\xbe\"\xb8\x00\x00" +
- "\x00\x00+\xac\xd0H\x00\x00\x00\x00,\x9fV8\x00\x00\x00\x00-\x8e\x03\xc8\x00\x00\x00\x00.\x80\x89\xb8\x00\x00\x00\x00/o7H\x00\x00\x00\x000a\xbd8\x00\x00\x00\x001Pj\xc8\x00\x00\x00\x002B" +
- "\xf0\xb8\x00\x00\x00\x0032\xef\xc8\x00\x00\x00\x004%u\xb8\x00\x00\x00\x005\x14#H\x00\x00\x00\x006\x06\xa98\x00\x00\x00\x006\xf5V\xc8\x00\x00\x00\x007\xe7ܸ\x00\x00\x00\x008֊H\x00\x00" +
- "\x00\x009\xc9\x108\x00\x00\x00\x00:\xb9\x0fH\x00\x00\x00\x00;\xab\x958\x00\x00\x00\x00<\x9aB\xc8\x00\x00\x00\x00=\x8cȸ\x00\x00\x00\x00>{vH\x00\x00\x00\x00?m\xfc8\x00\x00\x00\x00@\\" +
- "\xa9\xc8\x00\x00\x00\x00AO/\xb8\x00\x00\x00\x00B?.\xc8\x00\x00\x00\x00C1\xb4\xb8\x00\x00\x00\x00G\xe2\xc9H\x00\x00\x00\x00H\xd5O8\x00\x00\x00\x00I\xc5NH\x00\x00\x00\x00J\xb7\xd48\x00\x00" +
- "\x00\x00K\xa6\x81\xc8\x00\x00\x00\x00L\x99\a\xb8\x00\x00\x00\x00M\x87\xb5H\x00\x00\x00\x00Nz;8\x00\x00\x00\x00Oh\xe8\xc8\x00\x00\x00\x00P[n\xb8\x00\x00\x00\x00QKm\xc8\x00\x00\x00\x00R=" +
- "\xf3\xb8\x00\x00\x00\x00S,\xa1H\x00\x00\x00\x00T\x1f'8\x00\x00\x00\x00U\r\xd4\xc8\x00\x00\x00\x00V\x00Z\xb8\x00\x00\x00\x00V\xef\bH\x00\x00\x00\x00W\xe1\x8e8\x00\x00\x00\x00XэH\x00\x00" +
- "\x00\x00Y\xc4\x138\x00\x00\x00\x00Z\xb2\xc0\xc8\x00\x00\x00\x00[\xa5F\xb8\x00\x00\x00\x00\\\x93\xf4H\x00\x00\x00\x00]\x86z8\x00\x00\x00\x00^u'\xc8\x00\x00\x00\x00_g\xad\xb8\x00\x00\x00\x00`W" +
- "\xac\xc8\x00\x00\x00\x00aJ2\xb8\x00\x00\x00\x00b8\xe0H\x00\x00\x00\x00c+f8\x01\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x0008\x00\x00\x00\x0008\x00\x04\x00\x00?H\x01\b\x00\x0018\x00" +
- "\x0e\x00\x00FP\x01\x14\x00\x008@\x00\x18LMT\x00TMT\x00+0430\x00+0330\x00+05\x00+04\x00\n<+0330>-3:30\nPK\x03\x04\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17✳2\x04\x00\x002\x04\x00\x00\r\x00\x00\x00Asia/Tel_AvivTZif3\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\x00d\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\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\xd7Z0\x80\xff\xff\xff\xff\xd7\xdfX\x00\xff\xff\xff\xff\xd8/À\xff\xff\xff\xff\xd9\x1ec\x00\xff\xff\xff\xff\xda\x10\xf7\x00\xff\xff\xff\xff\xda\xeb\xd0\x00\xff\xff\xff\xff۴4" +
- "\x00\xff\xff\xff\xffܹ=\x00\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\u07b4\u0380\xff\xff\xff\xffߤ\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2\xbef\x80\xff\xff\xff" +
- "\xff\xe36_\x00\xff\xff\xff\xff\xe4\x9eH\x80\xff\xff\xff\xff\xe5\x16A\x00\xff\xff\xff\xff\xe6t\xf0\x00\xff\xff\xff\xff\xe7\x11Ҁ\xff\xff\xff\xff\xe8&\xad\x80\xff\xff\xff\xff\xe8\xe8z\x00\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\x001H\x96" +
- "\xe0\x00\x00\x00\x002<nP\x00\x00\x00\x0031\xb3`\x00\x00\x00\x004\x1a\xfe\xd0\x00\x00\x00\x005\x11\x95`\x00\x00\x00\x005\xf1\xa6P\x00\x00\x00\x007\x04\b\x80\x00\x00\x00\x007\xcf\x01p\x00\x00\x00" +
- "\x008\xf6_\x80\x00\x00\x00\x009\xdc\xf9\xe0\x00\x00\x00\x00:\xd0\xedp\x00\x00\x00\x00;\xae[`\x00\x00\x00\x00<\xa3\xa0p\x00\x00\x00\x00=\xa0\xb2`\x00\x00\x00\x00>\x83\x82p\x00\x00\x00\x00?|\x9f" +
- "\xe0\x00\x00\x00\x00@s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F\fS\x00\x00\x00\x00" +
- "\x00F\xecc\xf0\x00\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\t\xf0\x00\x00\x00\x00M\x95\x15" +
- "\x80\x00\x00\x00\x00N\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QTـ\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\f\x00\x008@\x01\x10LMT\x00JMT\x00IDT\x00IST\x00I" +
- "DDT\x00\nIST-2IDT,M3.4.4/26,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\v\x00" +
- "\x00\x00Asia/ThimbuTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\xd5\xe6\x15t\x00\x00\x00\x00" +
- "!aM\xa8\x01\x02\x00\x00T\f\x00\x00\x00\x00MX\x00\x04\x00\x00T`\x00\nLMT\x00+0530\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00j$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\f\x00\x00\x00Asia/ThimphuTZif2\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\x02\x00\x00\x00\x03" +
- "\x00\x00\x00\x0e\xff\xff\xff\xff\xd5\xe6\x15t\x00\x00\x00\x00!aM\xa8\x01\x02\x00\x00T\f\x00\x00\x00\x00MX\x00\x04\x00\x00T`\x00\nLMT\x00+0530\x00+06\x00\n<+06>" +
- "-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\n\x00\x00\x00Asia/TokyoTZif2\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\t\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffe¤p\xff\xff\xff\xff\xd7>\x02p\xff\xff\xff\xff\xd7\xedY\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd;\xf0\xff\xff" +
- "\xff\xff\xdb\a\x00\xf0\xff\xff\xff\xffۭ\x1d\xf0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xff\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x83\x03\x00\x00\x00\x00\x8c\xa0\x01\x04\x00\x00~\x90\x00\bLMT" +
- "\x00JDT\x00JST\x00\nJST-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[u\x99q\xf1\x02\x00\x00\xf1\x02\x00\x00\n\x00\x00\x00Asia/TomskTZif" +
- "2\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\x00C\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xe5N\xd9\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16" +
- "\x18\xa4\x00\x00\x00\x00\x00\x17\b\xa3\x10\x00\x00\x00\x00\x17\xf9׀\x00\x00\x00\x00\x18\xe9\u0590\x00\x00\x00\x00\x19\xdb\v\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00" +
- "\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\\\x0e\xb0\x00\x00\x00\x00\"K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$" +
- "+\xe1\xb0\x00\x00\x00\x00%\x1bҰ\x00\x00\x00\x00&\vð\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00" +
- "\x00\x00\x00*ij0\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x000dY0\x00\x00\x00\x001" +
- "]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dH\xb0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00" +
- "\x00\x00\x008\xdd\f\xb0\x00\x00\x00\x009\xfb\"0\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\v0\x00\x00\x00\x00<\xce\xe9\xb0\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>" +
- "\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00" +
- "\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\u0381\xc0\x00\x00\x00\x00J\xe3\\\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L" +
- "\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00WI\xf8\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00O\xa7\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\b\x00\x00bp\x00\f\x00\x00" +
- "bp\x01\fLMT\x00+06\x00+08\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xc9\xd4\\\xbe\x00\x00\x00\xbe\x00\x00\x00\x12\x00\x00\x00A" +
- "sia/Ujung_PandangTZif2\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\x04\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\xa1\xf2]\x90" +
- "\xff\xff\xff\xff\xba\x16Ր\xff\xff\xff\xffˈ\x1d\x80\xff\xff\xff\xff\xd2V\xeep\x01\x02\x03\x04\x00\x00o\xf0\x00\x00\x00\x00o\xf0\x00\x04\x00\x00p\x80\x00\b\x00\x00~\x90\x00\f\x00\x00p\x80\x00\x10LM" +
- "T\x00MMT\x00+08\x00+09\x00WITA\x00\nWITA-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x10\x00\x00\x00Asi" +
- "a/UlaanbaatarTZif2\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\x002\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x86\xd3\xeeL\x00\x00\x00\x00" +
- "\x0f\vܐ\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x11\x80" +
- "\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\"KՀ\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00" +
- "&\v\x99\x80\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xa4\\\xf0" +
- "\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002M=p\x00\x00\x00\x003=<\x80\x00\x00\x00\x00" +
- "4-\x1fp\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\r\x01p\x00\x00\x00\x00:鳠\x00\x00\x00\x00;\xb4\xac\x90\x00\x00\x00\x00<\xa4\xab\xa0\x00\x00\x00\x00=\x94\x8e\x90\x00\x00\x00\x00>\x84\x8d\xa0" +
- "\x00\x00\x00\x00?tp\x90\x00\x00\x00\x00@do\xa0\x00\x00\x00\x00ATR\x90\x00\x00\x00\x00BDQ\xa0\x00\x00\x00\x00C44\x90\x00\x00\x00\x00D$3\xa0\x00\x00\x00\x00E\x1dQ\x10\x00\x00\x00\x00" +
- "U\x15\x9a\xa0\x00\x00\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00d4\x00\x00\x00\x00bp\x00\x04\x00\x00~\x90\x01\b\x00\x00p\x80\x00\fLMT\x00+07\x00+09\x00+08\x00\n<" +
- "+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x0f\x00\x00\x00Asia/Ulan_BatorTZif2\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\x002\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x86\xd3\xeeL\x00\x00\x00\x00\x0f\vܐ\x00\x00\x00\x00\x18\xe9Ȁ\x00\x00\x00\x00\x19\xda\xfc\xf0\x00" +
- "\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00!" +
- "[\xd6p\x00\x00\x00\x00\"KՀ\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x99\x80\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xb6\x00\x00" +
- "\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/" +
- "t>\x00\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002M=p\x00\x00\x00\x003=<\x80\x00\x00\x00\x004-\x1fp\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\r\x01p\x00" +
- "\x00\x00\x00:鳠\x00\x00\x00\x00;\xb4\xac\x90\x00\x00\x00\x00<\xa4\xab\xa0\x00\x00\x00\x00=\x94\x8e\x90\x00\x00\x00\x00>\x84\x8d\xa0\x00\x00\x00\x00?tp\x90\x00\x00\x00\x00@do\xa0\x00\x00\x00\x00A" +
- "TR\x90\x00\x00\x00\x00BDQ\xa0\x00\x00\x00\x00C44\x90\x00\x00\x00\x00D$3\xa0\x00\x00\x00\x00E\x1dQ\x10\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00" +
- "\x00\x00\x00W\xe5Cp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00d" +
- "4\x00\x00\x00\x00bp\x00\x04\x00\x00~\x90\x01\b\x00\x00p\x80\x00\fLMT\x00+07\x00+09\x00+08\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00Asia/UrumqiTZif2\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\x01\x00\x00\x00\x02\x00\x00" +
- "\x00\b\xff\xff\xff\xff\xb0\xfe\xbad\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w\x86\x8d^\x03\x03" +
- "\x00\x00\x03\x03\x00\x00\r\x00\x00\x00Asia/Ust-NeraTZif2\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\x00B\x00\x00\x00\b\x00\x00\x00\x18\xff\xff" +
- "\xff\xff\xa1\xdbݺ\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\bj\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda" +
- "\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00" +
- "\x00\x00![\xd6p\x00\x00\x00\x00\"K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\v\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4" +
- "\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)ԉ\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\\\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00" +
- "\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\tp\x00\x00\x00\x005\x1d" +
- "\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\a\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xcb\xf0\x00\x00" +
- "\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc" +
- "\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce;p\x00\x00" +
- "\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00Nm\xf4@\x00\x00\x00\x00TK\xba\xf0\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
- "\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\a\x03\x06\x00\x00\x86F\x00\x00\x00\x00" +
- "p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x00\f\x00\x00\xa8\xc0\x01\x10\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x14\x00\x00\xa8\xc0\x00\x10LMT\x00+08\x00+09\x00+11\x00+12\x00" +
- "+10\x00\n<+10>-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0e\x00\x00\x00Asia/VientianeTZ" +
- "if2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^" +
- "<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d%\x05\xd8\xe6\x02\x00\x00\xe6\x02\x00\x00\x10\x00\x00\x00" +
- "Asia/VladivostokTZif2\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\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa7YG]\xff" +
- "\xff\xff\xff\xb5\xa3\xb6\xf0\x00\x00\x00\x00\x15'E`\x00\x00\x00\x00\x16\x18y\xd0\x00\x00\x00\x00\x17\bx\xe0\x00\x00\x00\x00\x17\xf9\xadP\x00\x00\x00\x00\x18\xe9\xac`\x00\x00\x00\x00\x19\xda\xe0\xd0\x00\x00\x00\x00\x1a" +
- "\xcc1`\x00\x00\x00\x00\x1b\xbc>\x80\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c \x80\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f|\x02\x80\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00![\xe4\x80\x00" +
- "\x00\x00\x00\"KՀ\x00\x00\x00\x00#;ƀ\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\xa8\x80\x00\x00\x00\x00&\v\x99\x80\x00\x00\x00\x00'\x04\xc5\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(" +
- "\xe4\xb5\x10\x00\x00\x00\x00)x]\x10\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*ĉ\x00\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xa4k\x00\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x84M\x00\x00" +
- "\x00\x00\x00/t>\x00\x00\x00\x00\x000d/\x00\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006" +
- "1\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xfa\xf8\x00\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00" +
- "\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D" +
- "%i\x00\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00" +
- "\x00\x00\x00K\xae+\x80\x00\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\r\x80\x00\x00\x00\x00TK\xba\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00{\xa3\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x9a\xb0\x01\b\x00\x00\x8c\xa0\x00\f" +
- "\x00\x00\x8c\xa0\x01\f\x00\x00\x9a\xb0\x00\bLMT\x00+09\x00+11\x00+10\x00\n<+10>-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O\xb0\x03\xe9\xe5\x02\x00\x00" +
- "\xe5\x02\x00\x00\f\x00\x00\x00Asia/YakutskTZif2\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\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1" +
- "\xdb\xea^\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\b\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00" +
- "\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL\x90\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00!" +
- "[\xf2\x90\x00\x00\x00\x00\"K\xe3\x90\x00\x00\x00\x00#;Ԑ\x00\x00\x00\x00$+Ő\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&\v\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00" +
- "\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk \x00\x00\x00\x00)Ԧ\x10\x00\x00\x00\x00*ė\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00." +
- "\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00" +
- "\x00\x00\x0062\a\x90\x00\x00\x00\x006\xfd\x0e\x90\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbcҐ\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<" +
- "\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00\x00>\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00@e\xb3\x10\x00\x00\x00\x00A\x83Ȑ\x00\x00\x00\x00BE\x95\x10\x00\x00\x00\x00Cc\xaa\x90\x00" +
- "\x00\x00\x00D%w\x10\x00\x00\x00\x00EC\x8c\x90\x00\x00\x00\x00F\x05Y\x10\x00\x00\x00\x00G#n\x90\x00\x00\x00\x00G\xeeu\x90\x00\x00\x00\x00I\x03P\x90\x00\x00\x00\x00I\xceW\x90\x00\x00\x00\x00J" +
- "\xe32\x90\x00\x00\x00\x00K\xae9\x90\x00\x00\x00\x00L\xccO\x10\x00\x00\x00\x00M\x8e\x1b\x90\x00\x00\x00\x00TK\xc9\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00y\xa2\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\b\x00\x00" +
- "~\x90\x00\f\x00\x00~\x90\x01\f\x00\x00\x8c\xa0\x00\bLMT\x00+08\x00+10\x00+09\x00\n<+09>-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ʇ{_\xbb" +
- "\x00\x00\x00\xbb\x00\x00\x00\v\x00\x00\x00Asia/YangonTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff" +
- "\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xffњg\xf0\x01\x02\x03\x02\x00\x00Z/\x00\x00\x00\x00Z/\x00\x04\x00\x00[h\x00\b\x00\x00~\x90\x00\x0eLMT" +
- "\x00RMT\x00+0630\x00+09\x00\n<+0630>-6:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xea\x18\xd4\xf8\x02\x00\x00\xf8\x02\x00\x00\x12\x00\x00\x00A" +
- "sia/YekaterinburgTZif2\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\x00B\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\x9b_\t'" +
- "\xff\xff\xff\xff\xa1\x12\xb1\xff\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\b\xbf0\x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00" +
- "\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0" +
- "\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L\x1b\xd0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xdf\xd0\x00\x00\x00\x00'\x05\vP\x00\x00\x00\x00" +
- "'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P" +
- "\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x00" +
- "5\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\\P\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\n\xd0\x00\x00\x00\x00;\xdb P" +
- "\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\tP\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x00\x00\x00\x00BE\xcdP\x00\x00\x00\x00" +
- "Cc\xe2\xd0\x00\x00\x00\x00D%\xafP\x00\x00\x00\x00EC\xc4\xd0\x00\x00\x00\x00F\x05\x91P\x00\x00\x00\x00G#\xa6\xd0\x00\x00\x00\x00G\xee\xad\xd0\x00\x00\x00\x00I\x03\x88\xd0\x00\x00\x00\x00IΏ\xd0" +
- "\x00\x00\x00\x00J\xe3j\xd0\x00\x00\x00\x00K\xaeq\xd0\x00\x00\x00\x00L̇P\x00\x00\x00\x00M\x8eS\xd0\x00\x00\x00\x00TL\x01@\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
- "\x04\x03\x04\x05\x02\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\x03\x04\x03\x04\x03\x04\x03\x04\x06\x04\x00\x008\xd9\x00\x00\x00\x004\xc1\x00\x04\x00\x00" +
- "8@\x00\b\x00\x00T`\x01\f\x00\x00FP\x00\x10\x00\x00FP\x01\x10\x00\x00T`\x00\fLMT\x00PMT\x00+04\x00+06\x00+05\x00\n<+05>-5\nPK\x03" +
- "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x95-\xad\xc4\x02\x00\x00\xc4\x02\x00\x00\f\x00\x00\x00Asia/YerevanTZif2\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\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x9aH\xff\xff\xff\xff\xe7\xda\fP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa" +
- "\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00" +
- "\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\v" +
- "\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00" +
- "\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062" +
- "M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00" +
- "\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00BE\xdb`\x00\x00\x00\x00Cc\xf0\xe0\x00\x00\x00\x00D%" +
- "\xbd`\x00\x00\x00\x00EC\xd2\xe0\x00\x00\x00\x00F\x05\x9f`\x00\x00\x00\x00G#\xb4\xe0\x00\x00\x00\x00G\xee\xbb\xe0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00IΝ\xe0\x00\x00\x00\x00J\xe3x\xe0\x00\x00" +
- "\x00\x00K\xae\x7f\xe0\x00\x00\x00\x00L̕`\x00\x00\x00\x00M\x8ea\xe0\x00\x00\x00\x00N\xacw`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x04\x01\x04\x01" +
- "\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00)\xb8\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@" +
- "\x01\fLMT\x00+03\x00+05\x00+04\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x8dY\x80\xad\x05\x00\x00\xad\x05\x00\x00\x0f\x00\x00\x00Atl" +
- "antic/AzoresTZif2\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\x8c\x00\x00\x00\a\x00\x00\x00\x18\xff\xff\xff\xff^=\x1b\x90\xff\xff\xff\xff\x92" +
- "檠\xff\xff\xff\xff\x9bK\x89\x90\xff\xff\xff\xff\x9b\xfe\xe3\xa0\xff\xff\xff\xff\x9c\x9d\t\x90\xff\xff\xff\xff\x9dɟ\x90\xff\xff\xff\xff\x9e\x7f\x8e\x90\xff\xff\xff\xff\x9f\xaa\xd3\x10\xff\xff\xff\xff\xa0_p\x90\xff" +
- "\xff\xff\xff\xa1\x8c\x06\x90\xff\xff\xff\xff\xa2A\xf5\x90\xff\xff\xff\xff\xa3n\x8b\x90\xff\xff\xff\xff\xa4#)\x10\xff\xff\xff\xff\xa5O\xbf\x10\xff\xff\xff\xff\xaa\x06\v\x90\xff\xff\xff\xff\xaa\xf4\xab\x10\xff\xff\xff\xff\xad" +
- "\xc9\xc4\x10\xff\xff\xff\xff\xae\xa7@\x10\xff\xff\xff\xff\xaf\xa0k\x90\xff\xff\xff\xff\xb0\x87\"\x10\xff\xff\xff\xff\xb1\x89\x88\x10\xff\xff\xff\xff\xb2p>\x90\xff\xff\xff\xff\xb3r\xa4\x90\xff\xff\xff\xff\xb4P \x90\xff" +
- "\xff\xff\xff\xb72h\x90\xff\xff\xff\xff\xb8\x0f\xe4\x90\xff\xff\xff\xff\xb8\xffՐ\xff\xff\xff\xff\xb9\xefƐ\xff\xff\xff\xff\xbc\xc8\xd4\x10\xff\xff\xff\xff\xbd\xb8\xc5\x10\xff\xff\xff\xff\xbe\x9f{\x90\xff\xff\xff\xff\xbf" +
- "\x98\xa7\x10\xff\xff\xff\xff\xc0\x9b\r\x10\xff\xff\xff\xff\xc1x\x89\x10\xff\xff\xff\xff\xc2hz\x10\xff\xff\xff\xff\xc3Xk\x10\xff\xff\xff\xff\xc4?!\x90\xff\xff\xff\xff\xc58M\x10\xff\xff\xff\xff\xc6:\xb3\x10\xff" +
- "\xff\xff\xff\xc7XȐ\xff\xff\xff\xff\xc7\xd9\xfb\x90\xff\xff\xff\xff\xc9\x01K\x90\xff\xff\xff\xff\xc9\xf1<\x90\xff\xff\xff\xff\xca\xe2\x7f\x10\xff\xff\xff\xff˵o\x10\xff\xff\xff\xff\xcb\xec\xc0\x00\xff\xff\xff\xff\xcc" +
- "\x80h\x00\xff\xff\xff\xff\xccܿ\x10\xff\xff\xff\xff͕Q\x10\xff\xff\xff\xff\xcd\xc3g\x80\xff\xff\xff\xff\xcer\xbf\x00\xff\xff\xff\xff\xce\xc5ې\xff\xff\xff\xff\xcfu3\x10\xff\xff\xff\xffϬ\x84\x00\xff" +
- "\xff\xff\xff\xd0R\xa1\x00\xff\xff\xff\xffХ\xbd\x90\xff\xff\xff\xff\xd1U\x15\x10\xff\xff\xff\xffьf\x00\xff\xff\xff\xff\xd22\x83\x00\xff\xff\xff\xff҅\x9f\x90\xff\xff\xff\xff\xd3Y\xe1\x10\xff\xff\xff\xff\xd4" +
- "I\xd2\x10\xff\xff\xff\xff\xd59\xed@\xff\xff\xff\xff\xd6)\xde@\xff\xff\xff\xff\xd7\x19\xcf@\xff\xff\xff\xff\xd8\t\xc0@\xff\xff\xff\xff\xd8\xf9\xb1@\xff\xff\xff\xff\xd9\xe9\xa2@\xff\xff\xff\xff\xdaٓ@\xff" +
- "\xff\xff\xff\xdbɄ@\xff\xff\xff\xffܹu@\xff\xff\xff\xffݲ\xa0\xc0\xff\xff\xff\xffޢ\x91\xc0\xff\xff\xff\xffߒ\x82\xc0\xff\xff\xff\xff\xe0\x82s\xc0\xff\xff\xff\xff\xe1rd\xc0\xff\xff\xff\xff\xe2" +
- "bU\xc0\xff\xff\xff\xff\xe3RF\xc0\xff\xff\xff\xff\xe4B7\xc0\xff\xff\xff\xff\xe52(\xc0\xff\xff\xff\xff\xe6\"\x19\xc0\xff\xff\xff\xff\xe7\x1bE@\xff\xff\xff\xff\xe8\v6@\xff\xff\xff\xff\xe8\xfb'@\xff" +
- "\xff\xff\xff\xe9\xeb\x18@\xff\xff\xff\xff\xea\xdb\t@\xff\xff\xff\xff\xeb\xca\xfa@\xff\xff\xff\xff\xec\xba\xeb@\xff\xff\xff\xff\xed\xaa\xdc@\xff\xff\xff\xff\xee\x9a\xcd@\xff\xff\xff\xff\uf2be@\xff\xff\xff\xff\xf0" +
- "z\xaf@\xff\xff\xff\xff\xf1j\xa0@\xff\xff\xff\xff\xf2c\xcb\xc0\xff\xff\xff\xff\xf3S\xbc\xc0\xff\xff\xff\xff\xf4C\xad\xc0\xff\xff\xff\xff\xf53\x9e\xc0\xff\xff\xff\xff\xf6#\x8f\xc0\xff\xff\xff\xff\xf7\x13\x80\xc0\xff" +
- "\xff\xff\xff\xf8\x03q\xc0\xff\xff\xff\xff\xf8\xf3b\xc0\x00\x00\x00\x00\r\x9b)\x10\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12" +
- "T&\xa0\x00\x00\x00\x00\x13D\t\x90\x00\x00\x00\x00\x144\b\xa0\x00\x00\x00\x00\x15#\xf9\xa0\x00\x00\x00\x00\x16\x13\xea\xa0\x00\x00\x00\x00\x17\x03۠\x00\x00\x00\x00\x17\xf3̠\x00\x00\x00\x00\x18\xe3˰\x00" +
- "\x00\x00\x00\x19Ӯ\xa0\x00\x00\x00\x00\x1aß\xa0\x00\x00\x00\x00\x1b\xbc\xcb \x00\x00\x00\x00\x1c\xac\xbc \x00\x00\x00\x00\x1d\x9c\xad \x00\x00\x00\x00\x1e\x8c\x9e \x00\x00\x00\x00\x1f|\x8f \x00\x00\x00\x00 " +
- "l\x80 \x00\x00\x00\x00!\\q \x00\x00\x00\x00\"Lb \x00\x00\x00\x00#<S \x00\x00\x00\x00$,D \x00\x00\x00\x00%\x1c5 \x00\x00\x00\x00&\f& \x00\x00\x00\x00'\x05Q\xa0\x00" +
- "\x00\x00\x00'\xf5B\xa0\x00\x00\x00\x00(\xe53\xa0\x00\x00\x00\x00)\xd5$\xa0\x00\x00\x00\x00*\xc5\x15\xa0\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00." +
- "\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\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\x06\x04\x05\x04\x05\x04\x05\x04\xff\xff\xe7\xf0\x00\x00\xff\xff\xe5(\x00\x04\xff" +
- "\xff\xf1\xf0\x01\b\xff\xff\xe3\xe0\x00\f\x00\x00\x00\x00\x01\x10\xff\xff\xf1\xf0\x00\b\x00\x00\x00\x00\x00\x14LMT\x00HMT\x00-01\x00-02\x00+00\x00WET\x00\n<-01>1" +
- "<+00>,M3.5.0/0,M10.5.0/1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l&\x04\x99\x00\x04\x00\x00\x00\x04\x00\x00\x10\x00\x00\x00Atlan" +
- "tic/BermudaTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x18F\xff\xff\xff\xff\x9c\xcc" +
- "\xaeF\xff\xff\xff\xff\x9d\xb7K6\xff\xff\xff\xff\x9e\xb8m\xc6\xff\xff\xff\xff\x9f\x84\xb86\xff\xff\xff\xff\xb4\xc3\x1d\xe6\xff\xff\xff\xff\xcbb\xa6\xe0\xff\xff\xff\xff\xccӼ\xd0\xff\xff\xff\xff͞\xd1\xe0\xff\xff" +
- "\xff\xff\xce\xc6\x13\xd0\xff\xff\xff\xff\xcfuy`\xff\xff\xff\xffЯ0P\xff\xff\xff\xff\xd1U[`\xff\xff\xff\xffҏ\x12P\xff\xff\xff\xff\xd5qh`\xff\xff\xff\xff\xd6\x0e<\xd0\xff\xff\xff\xff\xd7Z" +
- "\x84\xe0\xff\xff\xff\xff\xd7\xe4\xe4P\xff\xff\xff\xff\xd9:f\xe0\xff\xff\xff\xff\xd9\xc4\xc6P\xff\xff\xff\xff\xdb#\x83`\xff\xff\xff\xffۤ\xa8P\xff\xff\xff\xff\xdd\x03e`\xff\xff\xff\xff݄\x8aP\xff\xff" +
- "\xff\xff\xde\xe3G`\xff\xff\xff\xff\xdfm\xa6\xd0\xff\xff\xff\xff\xe6l\t\xe0\xff\xff\xff\xff\xe77\x02\xd0\x00\x00\x00\x00\b \xb3`\x00\x00\x00\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0" +
- "xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00" +
- "\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b" +
- "\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00" +
- "\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*" +
- "e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00" +
- "\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'" +
- "\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00" +
- "\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00Cd" +
- "SP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01\x02\x01\x02\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\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\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\xff\xff\xc3:\x00\x00\xff\xff\xd1J\x01\x04\xff\xff\xc3:\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xc7\xc0\x00\x10LMT\x00BST\x00BMT\x00ADT\x00AST\x00\nAST4ADT," +
- "M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf|7\xb3\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00Atlantic/Canary" +
- "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\x11\xff\xff\xff\xff\xa6\x04\\\xf0\xff\xff\xff\xff\xd4A\xf7 \x00\x00\x00\x00\x13M6\x00\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(" +
- "\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00" +
- "\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xf1\x90\x00\x00\xff\xff\xf1\xf0" +
- "\x00\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x01\fLMT\x00-01\x00WET\x00WEST\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u0097N\xad\xaf\x00\x00\x00\xaf\x00\x00\x00\x13\x00\x00\x00Atlantic/Cape_VerdeTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x92檠\xff\xff\xff\xff̕\x9c \xff\xff\xff\xff\xd2t|\x10\x00\x00\x00\x00\v\x17\xf7@\x01\x02\x01\x03\xff\xff" +
- "\xe9\xf4\x00\x00\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x01\b\xff\xff\xf1\xf0\x00\bLMT\x00-02\x00-01\x00\n<-01>1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\x0e\xbdm" +
- "\xb9\x01\x00\x00\xb9\x01\x00\x00\x0f\x00\x00\x00Atlantic/FaeroeTZif2\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\x03\x00\x00" +
- "\x00\r\xff\xff\xff\xff\x8bm\xa4X\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00" +
- "\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t" +
- "\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\xff\xff\xf9\xa8\x00\x00\x00\x00\x00\x00" +
- "\x00\x04\x00\x00\x0e\x10\x01\bLMT\x00WET\x00WEST\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0e\x00\x00\x00Atlantic/FaroeTZif2\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\x03\x00\x00\x00\r\xff\xff\xff\xff\x8bm\xa4X\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'" +
- "\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00" +
- "\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\xff\xff\xf9\xa8\x00" +
- "\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\bLMT\x00WET\x00WEST\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x12\x00\x00\x00Atlantic/Jan_MayenTZif2\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00" +
- "(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90" +
- "\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\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\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nC" +
- "ET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001)7\xad\xad\x05\x00\x00\xad\x05\x00\x00\x10\x00\x00\x00Atla" +
- "ntic/MadeiraTZif2\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\x8c\x00\x00\x00\a\x00\x00\x00\x1d\xff\xff\xff\xff^=\x13X\xff\xff\xff\xff\x92" +
- "朐\xff\xff\xff\xff\x9bK{\x80\xff\xff\xff\xff\x9b\xfeՐ\xff\xff\xff\xff\x9c\x9c\xfb\x80\xff\xff\xff\xff\x9dɑ\x80\xff\xff\xff\xff\x9e\x7f\x80\x80\xff\xff\xff\xff\x9f\xaa\xc5\x00\xff\xff\xff\xff\xa0_b\x80\xff" +
- "\xff\xff\xff\xa1\x8b\xf8\x80\xff\xff\xff\xff\xa2A\xe7\x80\xff\xff\xff\xff\xa3n}\x80\xff\xff\xff\xff\xa4#\x1b\x00\xff\xff\xff\xff\xa5O\xb1\x00\xff\xff\xff\xff\xaa\x05\xfd\x80\xff\xff\xff\xff\xaa\xf4\x9d\x00\xff\xff\xff\xff\xad" +
- "ɶ\x00\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0]\x80\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff\xb3r\x96\x80\xff\xff\xff\xff\xb4P\x12\x80\xff" +
- "\xff\xff\xff\xb72Z\x80\xff\xff\xff\xff\xb8\x0fր\xff\xff\xff\xff\xb8\xffǀ\xff\xff\xff\xff\xb9︀\xff\xff\xff\xff\xbc\xc8\xc6\x00\xff\xff\xff\xff\xbd\xb8\xb7\x00\xff\xff\xff\xff\xbe\x9fm\x80\xff\xff\xff\xff\xbf" +
- "\x98\x99\x00\xff\xff\xff\xff\xc0\x9a\xff\x00\xff\xff\xff\xff\xc1x{\x00\xff\xff\xff\xff\xc2hl\x00\xff\xff\xff\xff\xc3X]\x00\xff\xff\xff\xff\xc4?\x13\x80\xff\xff\xff\xff\xc58?\x00\xff\xff\xff\xff\xc6:\xa5\x00\xff" +
- "\xff\xff\xff\xc7X\xba\x80\xff\xff\xff\xff\xc7\xd9\xed\x80\xff\xff\xff\xff\xc9\x01=\x80\xff\xff\xff\xff\xc9\xf1.\x80\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff˵a\x00\xff\xff\xff\xff\xcb\xec\xb1\xf0\xff\xff\xff\xff\xcc" +
- "\x80Y\xf0\xff\xff\xff\xff\xccܱ\x00\xff\xff\xff\xff͕C\x00\xff\xff\xff\xff\xcd\xc3Yp\xff\xff\xff\xff\xcer\xb0\xf0\xff\xff\xff\xff\xce\xc5̀\xff\xff\xff\xff\xcfu%\x00\xff\xff\xff\xffϬu\xf0\xff" +
- "\xff\xff\xff\xd0R\x92\xf0\xff\xff\xff\xffХ\xaf\x80\xff\xff\xff\xff\xd1U\a\x00\xff\xff\xff\xffьW\xf0\xff\xff\xff\xff\xd22t\xf0\xff\xff\xff\xff҅\x91\x80\xff\xff\xff\xff\xd3Y\xd3\x00\xff\xff\xff\xff\xd4" +
- "I\xc4\x00\xff\xff\xff\xff\xd59\xdf0\xff\xff\xff\xff\xd6)\xd00\xff\xff\xff\xff\xd7\x19\xc10\xff\xff\xff\xff\xd8\t\xb20\xff\xff\xff\xff\xd8\xf9\xa30\xff\xff\xff\xff\xd9\xe9\x940\xff\xff\xff\xff\xdaم0\xff" +
- "\xff\xff\xff\xdb\xc9v0\xff\xff\xff\xffܹg0\xff\xff\xff\xffݲ\x92\xb0\xff\xff\xff\xffޢ\x83\xb0\xff\xff\xff\xffߒt\xb0\xff\xff\xff\xff\xe0\x82e\xb0\xff\xff\xff\xff\xe1rV\xb0\xff\xff\xff\xff\xe2" +
- "bG\xb0\xff\xff\xff\xff\xe3R8\xb0\xff\xff\xff\xff\xe4B)\xb0\xff\xff\xff\xff\xe52\x1a\xb0\xff\xff\xff\xff\xe6\"\v\xb0\xff\xff\xff\xff\xe7\x1b70\xff\xff\xff\xff\xe8\v(0\xff\xff\xff\xff\xe8\xfb\x190\xff" +
- "\xff\xff\xff\xe9\xeb\n0\xff\xff\xff\xff\xea\xda\xfb0\xff\xff\xff\xff\xeb\xca\xec0\xff\xff\xff\xff\xec\xba\xdd0\xff\xff\xff\xff\xed\xaa\xce0\xff\xff\xff\xff\ue6bf0\xff\xff\xff\xff\uf2b00\xff\xff\xff\xff\xf0" +
- "z\xa10\xff\xff\xff\xff\xf1j\x920\xff\xff\xff\xff\xf2c\xbd\xb0\xff\xff\xff\xff\xf3S\xae\xb0\xff\xff\xff\xff\xf4C\x9f\xb0\xff\xff\xff\xff\xf53\x90\xb0\xff\xff\xff\xff\xf6#\x81\xb0\xff\xff\xff\xff\xf7\x13r\xb0\xff" +
- "\xff\xff\xff\xf8\x03c\xb0\xff\xff\xff\xff\xf8\xf3T\xb0\x00\x00\x00\x00\r\x9b\x1b\x00\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12" +
- "T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00" +
- "\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00." +
- "\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xf0(\x00\x00\xff\xff\xf0(\x00\x04\x00" +
- "\x00\x00\x00\x01\b\xff\xff\xf1\xf0\x00\f\x00\x00\x0e\x10\x01\x10\x00\x00\x0e\x10\x01\x14\x00\x00\x00\x00\x00\x19LMT\x00FMT\x00+00\x00-01\x00+01\x00WEST\x00WET\x00\nW" +
- "ET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00Atlan" +
- "tic/ReykjavikTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc" +
- "8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f-\xadׄ\x00\x00\x00\x84\x00\x00\x00\x16\x00\x00\x00Atlanti" +
- "c/South_GeorgiaTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xffi\x86\xfd\xc0\x01\xff" +
- "\xff\xdd\xc0\x00\x00\xff\xff\xe3\xe0\x00\x04LMT\x00-02\x00\n<-02>2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00Atl" +
- "antic/St_HelenaTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff" +
- "\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7\xcf^\xb0\x15\x03\x00\x00\x15\x03\x00\x00\x10\x00\x00\x00Atlan" +
- "tic/StanleyTZif2\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\x00F\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x11\xbc\xff\xff\xff\xff\x93D" +
- "_<\xff\xff\xff\xff\xc3OZ\xc0\xff\xff\xff\xff\xc46\x030\xff\xff\xff\xff\xc5/<\xc0\xff\xff\xff\xff\xc6\x15\xe50\xff\xff\xff\xff\xc7\x18Y@\xff\xff\xff\xff\xc7\xff\x01\xb0\xff\xff\xff\xff\xc8\xf8;@\xff\xff" +
- "\xff\xff\xc9\xde\xe3\xb0\xff\xff\xff\xff\xca\xd8\x1d@\xff\xff\xff\xff˾Ű\xff\xff\xff\xff̷\xff@\xff\xff\xff\xff\xcd6\x810\x00\x00\x00\x00\x19\x11\xfe@\x00\x00\x00\x00\x19Ӽ\xb0\x00\x00\x00\x00\x1a\xf1" +
- "\xc4 \x00\x00\x00\x00\x1b\xaad0\x00\x00\x00\x00\x1cѦ \x00\x00\x00\x00\x1d\x8aF0\x00\x00\x00\x00\x1e\xa8[\xb0\x00\x00\x00\x00\x1fj6@\x00\x00\x00\x00 \x88=\xb0\x00\x00\x00\x00!J\x18@\x00\x00" +
- "\x00\x00\"h\x1f\xb0\x00\x00\x00\x00#)\xfa@\x00\x00\x00\x00$H\x01\xb0\x00\x00\x00\x00%\t\xdc@\x00\x00\x00\x00&1\x1e0\x00\x00\x00\x00&\xe9\xbe@\x00\x00\x00\x00(\x11\x000\x00\x00\x00\x00(\xd2" +
- "\xda\xc0\x00\x00\x00\x00)\xf0\xe20\x00\x00\x00\x00*\xb2\xbc\xc0\x00\x00\x00\x00+\xd0\xc40\x00\x00\x00\x00,\x92\x9e\xc0\x00\x00\x00\x00-\xb0\xa60\x00\x00\x00\x00.r\x80\xc0\x00\x00\x00\x00/\x90\x880\x00\x00" +
- "\x00\x000Rb\xc0\x00\x00\x00\x001y\xa4\xb0\x00\x00\x00\x002;\x7f@\x00\x00\x00\x003Y\x86\xb0\x00\x00\x00\x004\x1ba@\x00\x00\x00\x0059h\xb0\x00\x00\x00\x005\xfbC@\x00\x00\x00\x007\x19" +
- "J\xb0\x00\x00\x00\x007\xdb%@\x00\x00\x00\x008\xf9,\xb0\x00\x00\x00\x009\xbb\a@\x00\x00\x00\x00:\xd9*\xd0\x00\x00\x00\x00;\x91\xca\xe0\x00\x00\x00\x00<\xc2GP\x00\x00\x00\x00=q\xac\xe0\x00\x00" +
- "\x00\x00>\xa2)P\x00\x00\x00\x00?Z\xc9`\x00\x00\x00\x00@\x82\vP\x00\x00\x00\x00A:\xab`\x00\x00\x00\x00Ba\xedP\x00\x00\x00\x00C\x1a\x8d`\x00\x00\x00\x00DA\xcfP\x00\x00\x00\x00D\xfa" +
- "o`\x00\x00\x00\x00F!\xb1P\x00\x00\x00\x00F\xdaQ`\x00\x00\x00\x00H\n\xcd\xd0\x00\x00\x00\x00H\xc3m\xe0\x00\x00\x00\x00I\xea\xaf\xd0\x00\x00\x00\x00J\xa3O\xe0\x00\x00\x00\x00Kʑ\xd0\x00\x00" +
- "\x00\x00L\x831\xe0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\xff\xff\xc9\xc4\x00\x00\xff\xff\xc9\xc4\x00\x04\xff\xff\xd5\xd0\x01\b\xff\xff\xc7\xc0\x00\f\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\bLMT\x00SMT\x00" +
- "-03\x00-04\x00-02\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\r\x00\x00\x00Australia/" +
- "ACTTZif2\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\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x7f<\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc" +
- "/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00" +
- "\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef" +
- "\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00" +
- "\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\f\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xc7" +
- "\x81\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00" +
- "\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')" +
- "\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00" +
- "\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d" +
- "\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00" +
- "\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc" +
- "\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\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\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\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4" +
- ".1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ff~ՙ\x03\x00\x00\x99\x03\x00\x00\x12\x00\x00\x00Australia/AdelaideTZif2" +
- "\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\x00T\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x8b\x14\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc" +
- "6\b\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ0\x88\x00\x00\x00\x00\x03p@\x88\x00\x00" +
- "\x00\x00\x04\r#\b\x00\x00\x00\x00\x05P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88\x00\x00\x00\x00\t\x0f\xe6\x88\x00\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xef" +
- "Ȉ\x00\x00\x00\x00\v\x9f \b\x00\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\x7f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00\x0f^\xe4\b\x00\x00\x00\x00\x10\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00" +
- "\x00\x00\x12x\x8b\b\x00\x00\x00\x00\x13\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b\x00\x00\x00\x00\x16禈\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18\xc7" +
- "\x88\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00" +
- "\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b\x00\x00\x00\x00%I\xd4\b\x00\x00\x00\x00&\x02f\b\x00\x00\x00\x00')" +
- "\xb6\b\x00\x00\x00\x00'\xcf\xd3\b\x00\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xcbd\x88\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00+\x98ш\x00\x00\x00\x00,Җ\x88\x00\x00\x00\x00-\x8b(\x88\x00\x00" +
- "\x00\x00.\xb2x\x88\x00\x00\x00\x00/tE\b\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d" +
- "%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\b\x00\x00\x00\x00:\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00" +
- "\x00\x00<\xa5\xe8\b\x00\x00\x00\x00=\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc" +
- "\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\b\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x00\x00\x81\xec\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\nACST-9:30ACDT,M" +
- "10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x12\x00\x00\x00Australia/Bris" +
- "baneTZif2\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\x11\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffr\xed\x9f\b\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c" +
- "\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00" +
- "\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x02\x01\x02\x01\x02" +
- "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8fx\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x15\x00\x00\x00Australia/Broken_HillTZif2\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\x00U\x00\x00\x00\x05\x00\x00\x00\x13\xff\xff\xff\xffs\x16\x88d\xff\xff\xff\xffv\x04\xa5\xe0\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff" +
- "\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ0\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04" +
- "\r#\b\x00\x00\x00\x00\x05P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88\x00\x00\x00\x00\t\x0f\xe6\x88\x00\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xefȈ\x00" +
- "\x00\x00\x00\v\x9f \b\x00\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\x7f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00\x0f^\xe4\b\x00\x00\x00\x00\x10\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00\x00\x00\x12" +
- "x\x8b\b\x00\x00\x00\x00\x13\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b\x00\x00\x00\x00\x17\f\x90\x88\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18Lj\x88\x00" +
- "\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00\x00\x00 " +
- "Y\x85\x88\x00\x00\x00\x00!\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b\x00\x00\x00\x00%I\xd4\b\x00\x00\x00\x00%\xef\xf1\b\x00\x00\x00\x00')\xb6\b\x00" +
- "\x00\x00\x00'\xcf\xd3\b\x00\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xaf\xb5\b\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00+\x98ш\x00\x00\x00\x00,Җ\x88\x00\x00\x00\x00-x\xb3\x88\x00\x00\x00\x00." +
- "\xb2x\x88\x00\x00\x00\x00/X\x95\x88\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00" +
- "\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\b\x00\x00\x00\x00:\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00\x00\x00<" +
- "\xa5\xe8\b\x00\x00\x00\x00=\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00" +
- "\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\b\x01\x02\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\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04" +
- "\x03\x04\x03\x04\x00\x00\x84\x9c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\t\x00\x00\x93\xa8\x01\x0e\x00\x00\x85\x98\x00\tLMT\x00AEST\x00ACST\x00ACDT\x00\nACST-9" +
- ":30ACDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00Austr" +
- "alia/CanberraTZif2\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\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x7f<\xff\xff\xff\xff" +
- "\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80" +
- "\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00" +
- "\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00" +
- "\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\f\x89\x80\x00\x00\x00\x00" +
- "\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80" +
- "\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00" +
- "%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80" +
- "\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x00" +
- "4R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ" +
- "\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00" +
- "BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\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\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\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT," +
- "M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x00\x00Australia/Cur" +
- "rieTZif2\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\x03\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc" +
- "/\x00\xff\xff\xff\xff\x9d\xdaD\x80\xff\xff\xff\xff\x9e\x80a\x80\xff\xff\xff\xff\x9f\xba&\x80\xff\xff\xff\xff\xa0`C\x80\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff" +
- "\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\xff\xff\xff\xff\xfb\u008d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7" +
- ";\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00" +
- "\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~" +
- "\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00" +
- "\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1" +
- "(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00" +
- "\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)\xd4" +
- "\x98\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00" +
- "\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6" +
- ",\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00" +
- "\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05" +
- "K\x00\x00\x00\x00\x00G\a\xb1\x00\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" +
- "\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\x8a\x1c\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0" +
- "\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x10\x00\x00\x00Australia/DarwinTZif2\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\n\x00" +
- "\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x92X\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff\xcc" +
- "\xb7]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ0\x88\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00z\xa8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00" +
- "\x04LMT\x00ACST\x00ACDT\x00\nACST-9:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2ܺ\xca:\x01\x00\x00:\x01\x00\x00\x0f\x00\x00\x00Aust" +
- "ralia/EuclaTZif2\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\x13\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xfft\xa6\n\xb0\xff\xff\xff\xff\x9cN" +
- "\xd4\x14\xff\xff\xff\xff\x9c\xbc@\x94\xff\xff\xff\xff\xcbTĔ\xff\xff\xff\xff\xcb\xc7w\x14\xff\xff\xff\xff̷h\x14\xff\xff\xff\xffͧY\x14\x00\x00\x00\x00\t\x0f\xf1\x14\x00\x00\x00\x00\t\xb6\x0e\x14\x00\x00" +
- "\x00\x00\x1a\x01X\x14\x00\x00\x00\x00\x1a\xa7u\x14\x00\x00\x00\x00)%R\x14\x00\x00\x00\x00)\xaf\xbf\x94\x00\x00\x00\x00Eq\xb4\x94\x00\x00\x00\x00F\x05\\\x94\x00\x00\x00\x00G#r\x14\x00\x00\x00\x00G\xee" +
- "y\x14\x00\x00\x00\x00I\x03T\x14\x00\x00\x00\x00I\xce[\x14\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00x\xd0\x00\x00\x00\x00\x89\x1c\x01\x04\x00\x00{\f\x00\nLMT\x00+" +
- "0945\x00+0845\x00\n<+0845>-8:45\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x00\x00Austr" +
- "alia/HobartTZif2\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\x03\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff\xff\xff\xff\x9b\xd5" +
- "x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\x9d\xdaD\x80\xff\xff\xff\xff\x9e\x80a\x80\xff\xff\xff\xff\x9f\xba&\x80\xff\xff\xff\xff\xa0`C\x80\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff" +
- "\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\xff\xff\xff\xff\xfb\u008d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev" +
- "\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00" +
- "\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8" +
- "\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00" +
- "\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7" +
- "c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00" +
- "\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed" +
- "\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00" +
- "\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd" +
- "\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\f\x80\x00\x00" +
- "\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e" +
- "\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\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\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\x8a\x1c\x00\x00\x00\x00" +
- "\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00o3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\r\x00\x00\x00Australia/LHITZif2\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\x008\x00\x00\x00\x05\x00\x00\x00\x19\xff\xff\xff\xffs\x16w\xdc\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168@\xf8\x00\x00\x00\x00\x16\xe7\x8ah\x00\x00\x00\x00\x18!]x\x00\x00\x00\x00\x18\xc7lh" +
- "\x00\x00\x00\x00\x1a\x01?x\x00\x00\x00\x00\x1a\xa7Nh\x00\x00\x00\x00\x1b\xe1!x\x00\x00\x00\x00\x1c\x870h\x00\x00\x00\x00\x1d\xc1\x03x\x00\x00\x00\x00\x1ey\x8ep\x00\x00\x00\x00\x1f\x97\xaa\xf8\x00\x00\x00\x00" +
- " Ypp\x00\x00\x00\x00!\x80\xc7x\x00\x00\x00\x00\"B\x8c\xf0\x00\x00\x00\x00#i\xe3\xf8\x00\x00\x00\x00$\"n\xf0\x00\x00\x00\x00%I\xc5\xf8\x00\x00\x00\x00%\xef\xdb\xf0\x00\x00\x00\x00')\xa7\xf8" +
- "\x00\x00\x00\x00'Ͻ\xf0\x00\x00\x00\x00)\t\x89\xf8\x00\x00\x00\x00)\xaf\x9f\xf0\x00\x00\x00\x00*\xe9k\xf8\x00\x00\x00\x00+\x98\xbcp\x00\x00\x00\x00,҈x\x00\x00\x00\x00-x\x9ep\x00\x00\x00\x00" +
- ".\xb2jx\x00\x00\x00\x00/X\x80p\x00\x00\x00\x000\x92Lx\x00\x00\x00\x001]Lp\x00\x00\x00\x002r.x\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x10x\x00\x00\x00\x005\x1d\x10p" +
- "\x00\x00\x00\x0061\xf2x\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\x0e\xf8\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xa7\xe2x\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xd2\xf8\x00\x00\x00\x00" +
- "<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xb4\xf8\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x96\xf8\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xb3x\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x95x" +
- "\x00\x00\x00\x00D.\x95p\x00\x00\x00\x00ECwx\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Yx\x00\x00\x00\x00G\xf7\x93\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x95$\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa1\xb8\x01\t\x00\x00\x93\xa8\x00\x0f" +
- "\x00\x00\x9a\xb0\x01\x15LMT\x00AEST\x00+1130\x00+1030\x00+11\x00\n<+1030>-10:30<+11>-11,M10.1." +
- "0,M4.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x95\xbd\x12E\x01\x00\x00E\x01\x00\x00\x12\x00\x00\x00Australia/LindemanTZi" +
- "f2\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\x15\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffr\xed\xa2\xd4\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff" +
- "\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00" +
- "\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00" +
- "+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8b\xac\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tL" +
- "MT\x00AEDT\x00AEST\x00\nAEST-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\x13\x00\x00\x00Australi" +
- "a/Lord_HoweTZif2\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\x008\x00\x00\x00\x05\x00\x00\x00\x19\xff\xff\xff\xffs\x16w\xdc\x00\x00\x00\x00\x14\xfe" +
- "f\xe0\x00\x00\x00\x00\x168@\xf8\x00\x00\x00\x00\x16\xe7\x8ah\x00\x00\x00\x00\x18!]x\x00\x00\x00\x00\x18\xc7lh\x00\x00\x00\x00\x1a\x01?x\x00\x00\x00\x00\x1a\xa7Nh\x00\x00\x00\x00\x1b\xe1!x\x00\x00" +
- "\x00\x00\x1c\x870h\x00\x00\x00\x00\x1d\xc1\x03x\x00\x00\x00\x00\x1ey\x8ep\x00\x00\x00\x00\x1f\x97\xaa\xf8\x00\x00\x00\x00 Ypp\x00\x00\x00\x00!\x80\xc7x\x00\x00\x00\x00\"B\x8c\xf0\x00\x00\x00\x00#i" +
- "\xe3\xf8\x00\x00\x00\x00$\"n\xf0\x00\x00\x00\x00%I\xc5\xf8\x00\x00\x00\x00%\xef\xdb\xf0\x00\x00\x00\x00')\xa7\xf8\x00\x00\x00\x00'Ͻ\xf0\x00\x00\x00\x00)\t\x89\xf8\x00\x00\x00\x00)\xaf\x9f\xf0\x00\x00" +
- "\x00\x00*\xe9k\xf8\x00\x00\x00\x00+\x98\xbcp\x00\x00\x00\x00,҈x\x00\x00\x00\x00-x\x9ep\x00\x00\x00\x00.\xb2jx\x00\x00\x00\x00/X\x80p\x00\x00\x00\x000\x92Lx\x00\x00\x00\x001]" +
- "Lp\x00\x00\x00\x002r.x\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x10x\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xf2x\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\x0e\xf8\x00\x00" +
- "\x00\x008\xdc\xd4p\x00\x00\x00\x009\xa7\xe2x\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xd2\xf8\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xb4\xf8\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a" +
- "\x96\xf8\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xb3x\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x95x\x00\x00\x00\x00D.\x95p\x00\x00\x00\x00ECwx\x00\x00\x00\x00F\x05<\xf0\x00\x00" +
- "\x00\x00G#Yx\x00\x00\x00\x00G\xf7\x93\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\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\x03\x04\x03\x04\x03\x04\x03" +
- "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x95$\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa1\xb8\x01\t\x00\x00\x93\xa8\x00\x0f\x00\x00\x9a\xb0\x01\x15LMT\x00AEST\x00+1130\x00+1030" +
- "\x00+11\x00\n<+1030>-10:30<+11>-11,M10.1.0,M4.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xe1\xc1" +
- "\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x13\x00\x00\x00Australia/MelbourneTZif2\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\x00S\x00" +
- "\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x85\x18\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xff\xcd" +
- "\xa7G\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00" +
- "\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e" +
- "\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00" +
- "\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x16矀\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c" +
- "\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!w\x94\x00\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00" +
- "\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*" +
- "\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00" +
- "\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008" +
- "\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00" +
- "\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G" +
- "#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\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\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\x00\x00\x87\xe8\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT" +
- "\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03" +
- "\x00\x00\r\x00\x00\x00Australia/NSWTZif2\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\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16" +
- "\x7f<\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff" +
- "\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f" +
- "߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00" +
- "\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\f" +
- "\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00" +
- "\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I" +
- "\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00" +
- "\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=" +
- "<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00" +
- "\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83" +
- "\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\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\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\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-1" +
- "0AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x0f\x00\x00\x00Austral" +
- "ia/NorthTZif2\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\x00T" +
- "Zif2\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\n\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x92X\xff\xff\xff\xff{\x12\x03p\xff" +
- "\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xff\xcf" +
- "\x870\x88\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00z\xa8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\nACST-9:3" +
- "0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ϻ\xca\x1a2\x01\x00\x002\x01\x00\x00\x0f\x00\x00\x00Australia/PerthTZif2\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\x13\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xfft\xa6\x16\xe4\xff\xff\xff\xff\x9cNޠ\xff\xff\xff\xff\x9c\xbcK \xff\xff\xff\xff\xcbT\xcf \xff\xff\xff\xff\xcb\xc7" +
- "\x81\xa0\xff\xff\xff\xff̷r\xa0\xff\xff\xff\xffͧc\xa0\x00\x00\x00\x00\t\x0f\xfb\xa0\x00\x00\x00\x00\t\xb6\x18\xa0\x00\x00\x00\x00\x1a\x01b\xa0\x00\x00\x00\x00\x1a\xa7\x7f\xa0\x00\x00\x00\x00)%\\\xa0\x00\x00" +
- "\x00\x00)\xaf\xca \x00\x00\x00\x00Eq\xbf \x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\ue0e0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x02\x01\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00l\x9c\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\tLMT\x00AWDT\x00AWST\x00\nAWST-8\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x003\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x14\x00\x00\x00Australia/QueenslandTZif2\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\x11\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffr\xed\x9f\b\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff" +
- "\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef" +
- "\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8fx\x00\x00\x00\x00\x9a" +
- "\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ff~ՙ\x03\x00\x00\x99\x03\x00\x00\x0f\x00" +
- "\x00\x00Australia/SouthTZif2\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\x00T\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x8b\x14" +
- "\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xff" +
- "Πz\b\xff\xff\xff\xffχ0\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\r#\b\x00\x00\x00\x00\x05P\"\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88" +
- "\x00\x00\x00\x00\t\x0f\xe6\x88\x00\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xefȈ\x00\x00\x00\x00\v\x9f \b\x00\x00\x00\x00\f\xd8\xe5\b\x00\x00\x00\x00\r\x7f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00" +
- "\x0f^\xe4\b\x00\x00\x00\x00\x10\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00\x00\x00\x12x\x8b\b\x00\x00\x00\x00\x13\x1e\xa8\b\x00\x00\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b" +
- "\x00\x00\x00\x00\x16禈\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18Lj\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00" +
- "\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80Ո\x00\x00\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b" +
- "\x00\x00\x00\x00%I\xd4\b\x00\x00\x00\x00&\x02f\b\x00\x00\x00\x00')\xb6\b\x00\x00\x00\x00'\xcf\xd3\b\x00\x00\x00\x00)\t\x98\b\x00\x00\x00\x00)\xcbd\x88\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00" +
- "+\x98ш\x00\x00\x00\x00,Җ\x88\x00\x00\x00\x00-\x8b(\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/tE\b\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88" +
- "\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x00" +
- "9\xfa\xff\b\x00\x00\x00\x00:\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00\x00\x00<\xa5\xe8\b\x00\x00\x00\x00=\xba\xc3\b\x00\x00\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b" +
- "\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00" +
- "G\xf7\xa9\b\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x81\xec\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\t\x00\x00\x85\x98\x00\x04LMT\x00ACST" +
- "\x00ACDT\x00\nACST-9:30ACDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00" +
- "\x88\x03\x00\x00\x10\x00\x00\x00Australia/SydneyTZif2\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\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff" +
- "\xff\xff\xffs\x16\x7f<\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xff\xce" +
- "\xa0s\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00" +
- "\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f" +
- "^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00" +
- "\x00\x00\x00\x17\f\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d" +
- "\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00" +
- "\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+" +
- "\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00" +
- "\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009" +
- "\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00" +
- "\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G" +
- "\xf7\xa2\x00\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\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\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nA" +
- "EST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x12\x00\x00\x00Au" +
- "stralia/TasmaniaTZif2\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\x03\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff" +
- "\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\x9d\xdaD\x80\xff\xff\xff\xff\x9e\x80a\x80\xff\xff\xff\xff\x9f\xba&\x80\xff\xff\xff\xff\xa0`C\x80\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb" +
- "\xc7e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\xff\xff\xff\xff\xfb\u008d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff" +
- "\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05" +
- "P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00" +
- "\x00\x00\x00\f\xd8\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13" +
- "\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00" +
- "\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!" +
- "\x80\u0380\x00\x00\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00" +
- "\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)Ԙ\x00\x00\x00\x00\x00*\xcdÀ\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\\\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/" +
- "t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00" +
- "\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=" +
- "\x9f\f\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^Ѐ\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00" +
- "\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\a\xb1\x00\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\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\x8a" +
- "\x1c\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00Australia/VictoriaTZif2\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\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x85\x18\xff\xff\xff\xff\x9cN\u0080\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7" +
- "e\x80\xff\xff\xff\xff̷V\x80\xff\xff\xff\xffͧG\x80\xff\xff\xff\xffΠs\x00\xff\xff\xff\xffχ)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\r\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00" +
- "\x00\x00\x05\xf68\x80\x00\x00\x00\x00\a/\xfd\x80\x00\x00\x00\x00\a\xd6\x1a\x80\x00\x00\x00\x00\t\x0f߀\x00\x00\x00\x00\t\xb5\xfc\x80\x00\x00\x00\x00\n\xef\xc1\x80\x00\x00\x00\x00\v\x9f\x19\x00\x00\x00\x00\x00\f\xd8" +
- "\xde\x00\x00\x00\x00\x00\r~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00" +
- "\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x16矀\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18ǁ\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7" +
- "c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\n\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!w\x94\x00\x00\x00" +
- "\x00\x00\"B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\"}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\t" +
- "\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98ʀ\x00\x00\x00\x00,ҏ\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/t>\x00\x00\x00" +
- "\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd" +
- "\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbcĀ\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00" +
- "\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC" +
- "~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\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\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\x00\x00\x87\xe8\x00\x00\x00\x00\x9a\xb0\x01" +
- "\x04\x00\x00\x8c\xa0\x00\tLMT\x00AEDT\x00AEST\x00\nAEST-10AEDT,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00ϻ\xca\x1a2\x01\x00\x002\x01\x00\x00\x0e\x00\x00\x00Australia/WestTZif2\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\x13\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xfft\xa6\x16\xe4\xff\xff\xff\xff\x9cNޠ\xff\xff\xff\xff\x9c\xbcK \xff\xff\xff\xff\xcbT\xcf \xff\xff\xff\xff\xcbǁ\xa0\xff\xff\xff\xff̷r\xa0\xff\xff" +
- "\xff\xffͧc\xa0\x00\x00\x00\x00\t\x0f\xfb\xa0\x00\x00\x00\x00\t\xb6\x18\xa0\x00\x00\x00\x00\x1a\x01b\xa0\x00\x00\x00\x00\x1a\xa7\x7f\xa0\x00\x00\x00\x00)%\\\xa0\x00\x00\x00\x00)\xaf\xca \x00\x00\x00\x00Eq" +
- "\xbf \x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\ue0e0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\x02\x00\x00l\x9c\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\tLMT\x00AWDT\x00AWST\x00\nAWST-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xca#\x7f\xad" +
- "\x03\x00\x00\xad\x03\x00\x00\x14\x00\x00\x00Australia/YancowinnaTZif2\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\x00U\x00\x00" +
- "\x00\x05\x00\x00\x00\x13\xff\xff\xff\xffs\x16\x88d\xff\xff\xff\xffv\x04\xa5\xe0\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cNɈ\xff\xff\xff\xff\x9c\xbc6\b\xff\xff\xff\xff\xcbT\xba\b\xff\xff\xff\xff\xcb\xc7" +
- "l\x88\xff\xff\xff\xff̷]\x88\xff\xff\xff\xffͧN\x88\xff\xff\xff\xffΠz\b\xff\xff\xff\xffχ0\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\r#\b\x00\x00\x00\x00\x05P\"\x88\x00\x00" +
- "\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\a0\x04\x88\x00\x00\x00\x00\a\xd6!\x88\x00\x00\x00\x00\t\x0f\xe6\x88\x00\x00\x00\x00\t\xb6\x03\x88\x00\x00\x00\x00\n\xefȈ\x00\x00\x00\x00\v\x9f \b\x00\x00\x00\x00\f\xd8" +
- "\xe5\b\x00\x00\x00\x00\r\x7f\x02\b\x00\x00\x00\x00\x0e\xb8\xc7\b\x00\x00\x00\x00\x0f^\xe4\b\x00\x00\x00\x00\x10\x98\xa9\b\x00\x00\x00\x00\x11>\xc6\b\x00\x00\x00\x00\x12x\x8b\b\x00\x00\x00\x00\x13\x1e\xa8\b\x00\x00" +
- "\x00\x00\x14Xm\b\x00\x00\x00\x00\x14\xfe\x8a\b\x00\x00\x00\x00\x168O\b\x00\x00\x00\x00\x17\f\x90\x88\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18Lj\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7" +
- "j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\b\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80Ո\x00\x00" +
- "\x00\x00\"B\xa2\b\x00\x00\x00\x00#i\xf2\b\x00\x00\x00\x00$\"\x84\b\x00\x00\x00\x00%I\xd4\b\x00\x00\x00\x00%\xef\xf1\b\x00\x00\x00\x00')\xb6\b\x00\x00\x00\x00'\xcf\xd3\b\x00\x00\x00\x00)\t" +
- "\x98\b\x00\x00\x00\x00)\xaf\xb5\b\x00\x00\x00\x00*\xe9z\b\x00\x00\x00\x00+\x98ш\x00\x00\x00\x00,Җ\x88\x00\x00\x00\x00-x\xb3\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/X\x95\x88\x00\x00" +
- "\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd" +
- "\a\x88\x00\x00\x00\x008\x1b\x1d\b\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\b\x00\x00\x00\x00:\xbcˈ\x00\x00\x00\x00;\xda\xe1\b\x00\x00\x00\x00<\xa5\xe8\b\x00\x00\x00\x00=\xba\xc3\b\x00\x00" +
- "\x00\x00>\x85\xca\b\x00\x00\x00\x00?\x9a\xa5\b\x00\x00\x00\x00@e\xac\b\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\b\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC" +
- "\x85\x88\x00\x00\x00\x00F\x05R\b\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\b\x01\x02\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\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x84\x9c\x00\x00\x00\x00\x8c" +
- "\xa0\x00\x04\x00\x00~\x90\x00\t\x00\x00\x93\xa8\x01\x0e\x00\x00\x85\x98\x00\tLMT\x00AEST\x00ACST\x00ACDT\x00\nACST-9:30ACDT,M10.1" +
- ".0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\v\x00\x00\x00Brazil/AcreTZif2\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\x1f\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\\\xc0\xff\xff\xff\xff\xb9\xf1PP" +
- "\xff\xff\xff\xff\xbaސ@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xffܹu@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xffޛ\xfa@\xff\xff\xff\xff" +
- "\xdfݶP\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@" +
- "\xff\xff\xff\xff\xfa\n\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\"P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1dɪP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00" +
- " 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"\v\xe4\xc0\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\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\x03\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\n<-05>5\nPK\x03\x04\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x10\x00\x00\x00Brazil/DeNoronhaTZif2\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\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaaed\xff\xff\xff\xff\xb8\x0f;\xd0\xff\xff\xff\xff\xb8\xfd2\x90\xff\xff\xff\xff\xb9\xf1& \xff\xff\xff\xff\xba\xdef\x10\xff\xff\xff\xff\xda8\xa0 " +
- "\xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdc\x19Ӡ\xff\xff\xff\xffܹK\x10\xff\xff\xff\xff\xdd\xfb\a \xff\xff\xff\xffޛ\xd0\x10\xff\xff\xff\xff\xdf\u074c \xff\xff\xff\xff\xe0T%\x10\xff\xff\xff\xff" +
- "\xf4\x97\xf1\xa0\xff\xff\xff\xff\xf5\x05P\x10\xff\xff\xff\xff\xf6\xc0V \xff\xff\xff\xff\xf7\x0e\x10\x90\xff\xff\xff\xff\xf8Q\x1e \xff\xff\xff\xff\xf8Ƿ\x10\xff\xff\xff\xff\xfa\nĠ\xff\xff\xff\xff\xfa\xa8\xea\x90" +
- "\xff\xff\xff\xff\xfb\xeb\xf8 \xff\xff\xff\xff\xfc\x8bo\x90\x00\x00\x00\x00\x1dɀ \x00\x00\x00\x00\x1exɐ\x00\x00\x00\x00\x1f\xa0'\xa0\x00\x00\x00\x00 3\xc1\x90\x00\x00\x00\x00!\x81[ \x00\x00\x00\x00" +
- "\"\v\xba\x90\x00\x00\x00\x00#X\x02\xa0\x00\x00\x00\x00#\xe2b\x10\x00\x00\x00\x00%7\xe4\xa0\x00\x00\x00\x00%Թ\x10\x00\x00\x00\x007\xf6\xb8\xa0\x00\x00\x00\x008\xb8w\x10\x00\x00\x00\x009\xdf\xd5 " +
- "\x00\x00\x00\x009\xe9\x01\x90\x00\x00\x00\x00;\xc8\xf1\xa0\x00\x00\x00\x00<o\x00\x90\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\xff\xff\xe1\x9c\x00\x00\xff\xff\xf1\xf0\x01\x04\xff\xff\xe3\xe0\x00\bLMT\x00-01\x00-02\x00\n<-02>2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d?\xdfڸ" +
- "\x03\x00\x00\xb8\x03\x00\x00\v\x00\x00\x00Brazil/EastTZif2\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\x03\x00\x00\x00\f\xff\xff\xff" +
- "\xff\x96\xaar\xb4\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1" +
- "\xb0\xff\xff\xff\xffܹY \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xffޛ\xde \xff\xff\xff\xff\xdfݚ0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4Z\t0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff" +
- "\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\nҰ\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}" +
- "\xa0\x00\x00\x00\x00\x1dɎ0\x00\x00\x00\x00\x1exנ\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3Ϡ\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\"\vȠ\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00" +
- "\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\r" +
- "\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00\x00\x00\x00.\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00" +
- "\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6ư\x00\x00\x00\x008\xb8\x85" +
- " \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=đ0\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00?\x91\xfe0\x00\x00\x00" +
- "\x00@.Ҡ\x00\x00\x00\x00A\x86\xf80\x00\x00\x00\x00B\x17\xef \x00\x00\x00\x00CQ\xc20\x00\x00\x00\x00C\xf7\xd1 \x00\x00\x00\x00EMS\xb0\x00\x00\x00\x00E\xe0\xed\xa0\x00\x00\x00\x00G\x11\x86" +
- "0\x00\x00\x00\x00G\xb7\x95 \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\x97w \x00\x00\x00\x00Jڄ\xb0\x00\x00\x00\x00K\x80\x93\xa0\x00\x00\x00\x00L\xbaf\xb0\x00\x00\x00\x00M`u\xa0\x00\x00\x00" +
- "\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \x00\x00\x00\x00P\x83e0\x00\x00\x00\x00Q 9\xa0\x00\x00\x00\x00RcG0\x00\x00\x00\x00S\x00\x1b\xa0\x00\x00\x00\x00TC)0\x00\x00\x00\x00T\xe98" +
- " \x00\x00\x00\x00V#\v0\x00\x00\x00\x00V\xc9\x1a \x00\x00\x00\x00X\x02\xed0\x00\x00\x00\x00X\xa8\xfc \x00\x00\x00\x00Y\xe2\xcf0\x00\x00\x00\x00Z\x88\xde \x00\x00\x00\x00[\xde`\xb0\x00\x00\x00" +
- "\x00\\h\xc0 \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\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\xff\xff\xd4L\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\bLMT\x00-0" +
- "2\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\v\x00\x00\x00Brazil/WestTZif2" +
- "\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\x1f\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x96\xaa\x7fD\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1" +
- "B@\xff\xff\xff\xff\xbaނ0\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\b@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xffܹg0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xffޛ\xec0\xff\xff" +
- "\xff\xff\xdfݨ@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\r\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7" +
- "\xd30\xff\xff\xff\xff\xfa\n\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1dɜ@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00" +
- "\x00\x00 3ݰ\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\"\vְ\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\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\xff\xffǼ\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\bLMT\x00-03\x00-04\x00\n<-04>4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xe6\x9aM\xbem\x02\x00\x00m\x02\x00\x00\x03\x00\x00\x00CETTZif2\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\x005\x00\x00\x00\x02\x00\x00\x00\t\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\xd2N@\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e" +
- "\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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#<E\x10\x00" +
- "\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*" +
- "\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01" +
- "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x05\x00\x00" +
- "\x1c \x01\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x8b\x99\x1e\xb7" +
- "\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00CST6CDTTZif2\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\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6," +
- "\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff" +
- "\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef" +
- "\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00" +
- "\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t" +
- "\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00" +
- "\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1\xdc" +
- "\x80\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00" +
- "\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3b" +
- "p\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00" +
- "\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0" +
- "\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00" +
- "\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" +
- "\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" +
- "\x01\x00\x01\x00\x01\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\x00\xff\xff\xb9\xb0\x01\b\xff\xff\xb9\xb0\x01\fCDT\x00CST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0" +
- ",M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x00\x00Canada/AtlanticTZif2\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\xa7\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x80\xf1\xab\xa0\xff\xff\xff\xff\x9a\xe4\xde\xc0\xff\xff\xff\xff\x9b\xd6\x130\xff\xff\xff\xff\x9e\xb8\x85" +
- "`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xff\xa2\x9d\x17@\xff\xff\xff\xff\xa30\xb10\xff\xff\xff\xff\xa4zV@\xff\xff\xff\xff\xa5\x1b\x1f0\xff\xff\xff\xff\xa6S\xa0\xc0\xff\xff\xff\xff\xa6\xfcR\xb0\xff\xff\xff" +
- "\xff\xa8<\xbd@\xff\xff\xff\xff\xa8\xdc4\xb0\xff\xff\xff\xff\xaa\x1c\x9f@\xff\xff\xff\xff\xaa\xcd:0\xff\xff\xff\xff\xab\xfc\x81@\xff\xff\xff\xff\xac\xbf\x910\xff\xff\xff\xff\xad\xee\xd8@\xff\xff\xff\xff\xae\x8c\xfe" +
- "0\xff\xff\xff\xff\xaf\xbcE@\xff\xff\xff\xff\xb0\x7fU0\xff\xff\xff\xff\xb1\xae\x9c@\xff\xff\xff\xff\xb2Kp\xb0\xff\xff\xff\xff\xb3\x8e~@\xff\xff\xff\xff\xb4$\xbb0\xff\xff\xff\xff\xb5n`@\xff\xff\xff" +
- "\xff\xb6\x15\xc0\xb0\xff\xff\xff\xff\xb7NB@\xff\xff\xff\xff\xb8\b\x17\xb0\xff\xff\xff\xff\xb9$\xe9\xc0\xff\xff\xff\xff\xb9\xe7\xf9\xb0\xff\xff\xff\xff\xbb\x04\xcb\xc0\xff\xff\xff\xff\xbb\xd1\x160\xff\xff\xff\xff\xbd\x00]" +
- "@\xff\xff\xff\xff\xbd\x9d1\xb0\xff\xff\xff\xff\xbe\xf2\xb4@\xff\xff\xff\xff\xbf\x90\xda0\xff\xff\xff\xff\xc0\xd3\xe7\xc0\xff\xff\xff\xff\xc1^G0\xff\xff\xff\xff\u008d\x8e@\xff\xff\xff\xff\xc3P\x9e0\xff\xff\xff" +
- "\xff\xc4mp@\xff\xff\xff\xff\xc50\x800\xff\xff\xff\xff\xc6r<@\xff\xff\xff\xff\xc7\x10b0\xff\xff\xff\xff\xc86n\xc0\xff\xff\xff\xff\xc8\xf9~\xb0\xff\xff\xff\xff\xca\x16P\xc0\xff\xff\xff\xff\xca\xd9`" +
- "\xb0\xff\xff\xff\xffˈ\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xd3u\xd6\xe0\xff\xff\xff\xff\xd4@\xcf\xd0\xff\xff\xff\xff\xd5U\xb8\xe0\xff\xff\xff\xff\xd6 \xb1\xd0\xff\xff\xff" +
- "\xff\xd75\x9a\xe0\xff\xff\xff\xff\xd8\x00\x93\xd0\xff\xff\xff\xff\xd9\x15|\xe0\xff\xff\xff\xff\xd9\xe0u\xd0\xff\xff\xff\xff\xdc\xde{`\xff\xff\xff\xffݩtP\xff\xff\xff\xff\u07be]`\xff\xff\xff\xff߉V" +
- "P\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\xff\xff\xff\xff\xe2~!`\xff\xff\xff\xff\xe3I\x1aP\xff\xff\xff\xff\xe6G\x1f\xe0\xff\xff\xff\xff\xe7\x12\x18\xd0\xff\xff\xff\xff\xe8'\x01\xe0\xff\xff\xff" +
- "\xff\xe8\xf1\xfa\xd0\xff\xff\xff\xff\xea\x06\xe3\xe0\xff\xff\xff\xff\xea\xd1\xdc\xd0\xff\xff\xff\xff\xeb\xe6\xc5\xe0\xff\xff\xff\xff챾\xd0\xff\xff\xff\xff\xf1\x8f\xa6`\xff\xff\xff\xff\xf2\x7f\x89P\xff\xff\xff\xff\xf3o\x88" +
- "`\xff\xff\xff\xff\xf4_kP\xff\xff\xff\xff\xf5Oj`\xff\xff\xff\xff\xf6?MP\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(i\xd0\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\bK\xd0\xff\xff\xff" +
- "\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3" +
- "\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\a0\xb4P\x00\x00\x00\x00\b \xb3`\x00\x00\x00" +
- "\x00\t\x10\x96P\x00\x00\x00\x00\n\x00\x95`\x00\x00\x00\x00\n\xf0xP\x00\x00\x00\x00\v\xe0w`\x00\x00\x00\x00\fٔ\xd0\x00\x00\x00\x00\r\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u" +
- "\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00" +
- "\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\"\x1bP\x00\x00\x00\x00\x19\b\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1" +
- "P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\"U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00" +
- "\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\nG\xd0\x00\x00\x00\x00)ޗ`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey" +
- "`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\nP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00" +
- "\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae" +
- "\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00" +
- "\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xc4`\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\b\xff\xff\xd5\xd0\x01\f\xff\xff\xd5\xd0" +
- "\x01\x10LMT\x00ADT\x00AST\x00AWT\x00APT\x00\nAST4ADT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x0e\x00\x00\x00Canada/CentralTZif2\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" +
- "\x05\x00\x00\x00\x14\xff\xff\xff\xffd䰔\xff\xff\xff\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9búP\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\u00a0;\x80\xff\xff\xff\xff\xc3O\x84" +
- "\xf0\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xffӈh\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff" +
- "\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xdb\x00\a\x00\xff\xff\xff\xff\xdb\xc8\\\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90" +
- "p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff" +
- "\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2" +
- "\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\ue47c\xf0\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff" +
- "\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xfe" +
- "\x00\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b π\x00\x00\x00" +
- "\x00\t\x10\xc0\x80\x00\x00\x00\x00\n\x00\xb1\x80\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\x92" +
- "\x00\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169)\x00\x00\x00\x00" +
- "\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xeb" +
- "\x80\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00" +
- "\x00%J\xae\x00\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95" +
- "\x80\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x16\x80\x00\x00\x00" +
- "\x003GX\x00\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005':\x00\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xd9" +
- "\x00\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00" +
- "\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa4\xec\x00\x00\xff\xff\xb9\xb0" +
- "\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f\xff\xff\xb9\xb0\x01\x10LMT\x00CDT\x00CST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M11." +
- "1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00\x00\x00Canada/EasternTZif2\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\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1" +
- "\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\fN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff" +
- "\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad܍p\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf" +
- "\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff\xb6'\x0e`\xff" +
- "\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd" +
- "\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff" +
- "\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3" +
- "u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff" +
- "\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1" +
- "iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\n`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff" +
- "\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef" +
- "\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff" +
- "\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd" +
- "\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00" +
- "\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\b \xc1p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v" +
- "\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00" +
- "\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a" +
- "\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00" +
- "\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'" +
- "\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00" +
- "\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x006" +
- "2\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00" +
- "\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D" +
- "/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
- "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT" +
- "\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\a\a\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x0f\x00\x00\x00Canad" +
- "a/MountainTZif2\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\x00Y\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x88\xde\xce\xe0\xff\xff\xff\xff\x9e\xb8\xaf" +
- "\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x98\x91\x90\xff\xff\xff\xff\xa0҅\x80\xff\xff\xff\xff\xa2\x8a\xe8\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4jʐ\xff\xff\xff\xff\xa55À\xff\xff\xff" +
- "\xff\xa6S\xe7\x10\xff\xff\xff\xff\xa7\x15\xa5\x80\xff\xff\xff\xff\xa83\xc9\x10\xff\xff\xff\xff\xa8\xfe\xc2\x00\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd5U\xe3" +
- "\x10\xff\xff\xff\xff\xd6 \xdc\x00\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\b ݐ\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00" +
- "\x00\n\x00\xbf\x90\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83" +
- "\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00" +
- "\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea" +
- "\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00" +
- "\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p" +
- "\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00" +
- "\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee" +
- "\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00" +
- "\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\x01\xff\xff\x95\xa0\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST" +
- "7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xb2\x0e\x19V\a\x00\x00V\a\x00\x00\x13\x00\x00\x00Canada/New" +
- "foundlandTZif2\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\x00" +
- "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\xbb\x00\x00\x00\b\x00\x00\x00\x19\xff\xff\xff\xff^=4\xec\xff\xff\xff\xff\x9c\xcfb\f" +
- "\xff\xff\xff\xff\x9d\xa4\xe6\xfc\xff\xff\xff\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xa0\xb6\x88\xdc\xff\xff\xff\xff\xa18\xffL\xff\xff\xff\xff\xa2\x95\x19\\\xff\xff\xff\xff\xa3\x84\xfcL\xff\xff\xff\xff" +
- "\xa4t\xfb\\\xff\xff\xff\xff\xa5d\xdeL\xff\xff\xff\xff\xa6^\x17\xdc\xff\xff\xff\xff\xa7D\xc0L\xff\xff\xff\xff\xa8=\xf9\xdc\xff\xff\xff\xff\xa9$\xa2L\xff\xff\xff\xff\xaa\x1d\xdb\xdc\xff\xff\xff\xff\xab\x04\x84L" +
- "\xff\xff\xff\xff\xab\xfd\xbd\xdc\xff\xff\xff\xff\xac\xe4fL\xff\xff\xff\xff\xadݟ\xdc\xff\xff\xff\xff\xae͂\xcc\xff\xff\xff\xff\xaf\xbd\x81\xdc\xff\xff\xff\xff\xb0\xadd\xcc\xff\xff\xff\xff\xb1\xa6\x9e\\\xff\xff\xff\xff" +
- "\xb2\x8dF\xcc\xff\xff\xff\xff\xb3\x86\x80\\\xff\xff\xff\xff\xb4m(\xcc\xff\xff\xff\xff\xb5fb\\\xff\xff\xff\xff\xb6M\n\xcc\xff\xff\xff\xff\xb7FD\\\xff\xff\xff\xff\xb8,\xec\xcc\xff\xff\xff\xff\xb9&&\\" +
- "\xff\xff\xff\xff\xba\x16\tL\xff\xff\xff\xff\xbb\x0fB\xdc\xff\xff\xff\xff\xbb\xf5\xebL\xff\xff\xff\xff\xbc\xef$\xdc\xff\xff\xff\xff\xbd\xd5\xcdL\xff\xff\xff\xff\xbe\x9eMl\xff\xff\xff\xff\xbe\xcf\x06\xa8\xff\xff\xff\xff" +
- "\xbf\xb5\xaf\x18\xff\xff\xff\xff\xc0\xb818\xff\xff\xff\xff\xc1y\xef\xa8\xff\xff\xff\xff\u0098\x138\xff\xff\xff\xff\xc3YѨ\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8" +
- "\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff\xff\xc8@\xf3\xb8\xff\xff\xff\xff\xc9\x02\xb2(\xff\xff\xff\xff\xca ո\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff" +
- "\xd2`\xe6\xc8\xff\xff\xff\xffӈD\xd8\xff\xff\xff\xff\xd4J\x03H\xff\xff\xff\xff\xd5h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\b\xd8\xff\xff\xff\xff\xd8\t\xc7H\xff\xff\xff\xff\xd9'\xea\xd8" +
- "\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff\xff\xdb\x11\aX\xff\xff\xff\xff\xdb\xd2\xc5\xc8\xff\xff\xff\xff\xdc\xdetX\xff\xff\xff\xffݩmH\xff\xff\xff\xff\u07beVX\xff\xff\xff\xff߉OH\xff\xff\xff\xff" +
- "\xe0\x9e8X\xff\xff\xff\xff\xe1i1H\xff\xff\xff\xff\xe2~\x1aX\xff\xff\xff\xff\xe3I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8" +
- "\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff\xff\xe8\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06\xdc\xd8\xff\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff챷\xc8\xff\xff\xff\xff\xedƠ\xd8\xff\xff\xff\xff" +
- "\ueffeH\xff\xff\xff\xffﯽX\xff\xff\xff\xff\xf0\x9f\xa0H\xff\xff\xff\xff\xf1\x8f\x9fX\xff\xff\xff\xff\xf2\x7f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_dH\xff\xff\xff\xff\xf5OcX" +
- "\xff\xff\xff\xff\xf6?FH\xff\xff\xff\xff\xf7/EX\xff\xff\xff\xff\xf8(b\xc8\xff\xff\xff\xff\xf9\x0f'X\xff\xff\xff\xff\xfa\bD\xc8\xff\xff\xff\xff\xfa\xf8C\xd8\xff\xff\xff\xff\xfb\xe8&\xc8\xff\xff\xff\xff" +
- "\xfc\xd8%\xd8\xff\xff\xff\xff\xfd\xc8\b\xc8\xff\xff\xff\xff\xfe\xb8\a\xd8\xff\xff\xff\xff\xff\xa7\xea\xc8\x00\x00\x00\x00\x00\x97\xe9\xd8\x00\x00\x00\x00\x01\x87\xcc\xc8\x00\x00\x00\x00\x02w\xcb\xd8\x00\x00\x00\x00\x03p\xe9H" +
- "\x00\x00\x00\x00\x04`\xe8X\x00\x00\x00\x00\x05P\xcbH\x00\x00\x00\x00\x06@\xcaX\x00\x00\x00\x00\a0\xadH\x00\x00\x00\x00\b \xacX\x00\x00\x00\x00\t\x10\x8fH\x00\x00\x00\x00\n\x00\x8eX\x00\x00\x00\x00" +
- "\n\xf0qH\x00\x00\x00\x00\v\xe0pX\x00\x00\x00\x00\fٍ\xc8\x00\x00\x00\x00\r\xc0RX\x00\x00\x00\x00\x0e\xb9o\xc8\x00\x00\x00\x00\x0f\xa9n\xd8\x00\x00\x00\x00\x10\x99Q\xc8\x00\x00\x00\x00\x11\x89P\xd8" +
- "\x00\x00\x00\x00\x12y3\xc8\x00\x00\x00\x00\x13i2\xd8\x00\x00\x00\x00\x14Y\x15\xc8\x00\x00\x00\x00\x15I\x14\xd8\x00\x00\x00\x00\x168\xf7\xc8\x00\x00\x00\x00\x17(\xf6\xd8\x00\x00\x00\x00\x18\"\x14H\x00\x00\x00\x00" +
- "\x19\b\xd8\xd8\x00\x00\x00\x00\x1a\x01\xf6H\x00\x00\x00\x00\x1a\xf1\xf5X\x00\x00\x00\x00\x1b\xe1\xd8H\x00\x00\x00\x00\x1c\xd1\xd7X\x00\x00\x00\x00\x1d\xc1\xbaH\x00\x00\x00\x00\x1e\xb1\xb9X\x00\x00\x00\x00\x1f\xa1\x9cH" +
- "\x00\x00\x00\x00 u\xcf\xf4\x00\x00\x00\x00!\x81bd\x00\x00\x00\x00\"U\xb1\xf4\x00\x00\x00\x00#jp\xd4\x00\x00\x00\x00$5\x93\xf4\x00\x00\x00\x00%J`\xe4\x00\x00\x00\x00&\x15u\xf4\x00\x00\x00\x00" +
- "'*B\xe4\x00\x00\x00\x00'\xfe\x92t\x00\x00\x00\x00)\n$\xe4\x00\x00\x00\x00)\xdett\x00\x00\x00\x00*\xea\x06\xe4\x00\x00\x00\x00+\xbeVt\x00\x00\x00\x00,\xd3#d\x00\x00\x00\x00-\x9e8t" +
- "\x00\x00\x00\x00.\xb3\x05d\x00\x00\x00\x00/~\x1at\x00\x00\x00\x000\x92\xe7d\x00\x00\x00\x001g6\xf4\x00\x00\x00\x002r\xc9d\x00\x00\x00\x003G\x18\xf4\x00\x00\x00\x004R\xabd\x00\x00\x00\x00" +
- "5&\xfa\xf4\x00\x00\x00\x0062\x8dd\x00\x00\x00\x007\x06\xdc\xf4\x00\x00\x00\x008\x1b\xa9\xe4\x00\x00\x00\x008\xe6\xbe\xf4\x00\x00\x00\x009\xfb\x8b\xe4\x00\x00\x00\x00:Ơ\xf4\x00\x00\x00\x00;\xdbm\xe4" +
- "\x00\x00\x00\x00<\xaf\xbdt\x00\x00\x00\x00=\xbbO\xe4\x00\x00\x00\x00>\x8f\x9ft\x00\x00\x00\x00?\x9b1\xe4\x00\x00\x00\x00@o\x81t\x00\x00\x00\x00A\x84Nd\x00\x00\x00\x00BOct\x00\x00\x00\x00" +
- "Cd0d\x00\x00\x00\x00D/Et\x00\x00\x00\x00ED\x12d\x00\x00\x00\x00E\xf3w\xf4\x00\x00\x00\x00G-.\xe4\x00\x00\x00\x00G\xd3Y\xf4\x00\x00\x00\x00I\r\x10\xe4\x00\x00\x00\x00I\xb3;\xf4" +
- "\x00\x00\x00\x00J\xec\xf2\xe4\x00\x00\x00\x00K\x9cXt\x00\x00\x00\x00L\xd6\x0fd\x00\x00\x00\x00M|:t\x00\x00\x00\x00N\xb6\rH\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\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\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\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a" +
- "\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xffΔ\x00\x00\xff\xffܤ\x01\x04\xff" +
- "\xffΔ\x00\b\xff\xff\xdc\xd8\x01\x04\xff\xff\xce\xc8\x00\b\xff\xff\xdc\xd8\x01\f\xff\xff\xdc\xd8\x01\x10\xff\xff\xea\xe8\x01\x14LMT\x00NDT\x00NST\x00NPT\x00NWT\x00NDDT\x00" +
- "\nNST3:30NDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U9#\xbe2\x05\x00\x002\x05\x00\x00\x0e\x00\x00\x00Can" +
- "ada/PacificTZif2\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\x81\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^=v\xec\xff\xff\xff\xff\x9e\xb8" +
- "\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd3v\x0f \xff\xff\xff\xff\xd4A\b\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff" +
- "\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfeѠ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\xde" +
- "\xb3\xa0\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x95\xa0\xff\xff\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff" +
- "\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x1c \xff\xff\xff\xff\xea\xd2" +
- "\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fޠ\xff\xff" +
- "\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0f" +
- "f\xa0\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00" +
- "\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0" +
- "\xec\x90\x00\x00\x00\x00\b \xeb\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\n\x00͠\x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00" +
- "\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15I" +
- "T \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00" +
- "\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j" +
- "\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00" +
- "\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g" +
- "\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00" +
- "\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b" +
- "\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01" +
- "\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
- "\x01\x02\x01\x02\x01\x02\x01\xff\xff\x8c\x94\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00PWT\x00PPT\x00\nPS" +
- "T8PDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u0096dK~\x02\x00\x00~\x02\x00\x00\x13\x00\x00\x00Canada/Sa" +
- "skatchewanTZif2\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\x005\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x86\xfd\x93\x1c\xff\xff\xff\xff\x9e\xb8\xaf" +
- "\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xb5eO\xf0\xff\xff\xff\xff\xb60H\xe0\xff\xff\xff\xff\xb7E1\xf0\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xf0\f\xe0\xff\xff\xff" +
- "\xff\xbb\x0e0p\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xee\x12p\xff\xff\xff\xff\xbd\xb9\v`\xff\xff\xff\xff\xc2r\b\xf0\xff\xff\xff\xff\xc3a\xeb\xe0\xff\xff\xff\xff\xc4Q\xea\xf0\xff\xff\xff\xff\xc58\x93" +
- "`\xff\xff\xff\xff\xc61\xcc\xf0\xff\xff\xff\xff\xc7!\xaf\xe0\xff\xff\xff\xff\xc8\x1a\xe9p\xff\xff\xff\xff\xc9\n\xcc`\xff\xff\xff\xff\xc9\xfa\xcbp\xff\xff\xff\xff\xca\xea\xae`\xff\xff\xff\xffˉ\f\x90\xff\xff\xff" +
- "\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3c\x8c\x10\xff\xff\xff\xff\xd4So\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe" +
- "\x00\xff\xff\xff\xff\xd9\x15\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xda\xfeÐ\xff\xff\xff\xff\xdb\xc0\x82\x00\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ\x9e\x80\xff\xff\xff\xff\u07be\x87\x90\xff\xff\xff" +
- "\xff߉\x80\x80\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ib\x80\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3ID\x80\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)&\x80\xff\xff\xff\xff\xe6GJ" +
- "\x10\xff\xff\xff\xff\xe7\x12C\x00\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf2%\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
- "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\x05\xff\xff\x9d\xe4\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b" +
- "\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\nCST6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xbf\x1d\xee\x91\x05\x04\x00\x00\x05\x04\x00\x00\f\x00\x00\x00Canada/YukonTZif2\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" +
- "\t\x00\x00\x00%\xff\xff\xff\xff}\x86\x8a\x9c\xff\xff\xff\xff\x9e\xb8˰\xff\xff\xff\xff\x9f\xbb#\xa0\xff\xff\xff\xff\xa0\xd0\f\xb0\xff\xff\xff\xff\xa1\xa2Ҁ\xff\xff\xff\xffˉ(\xb0\xff\xff\xff\xff\xd2#\xf4" +
- "p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf8ń\x90\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00" +
- "\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16" +
- "\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00" +
- "\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab" +
- "\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00" +
- "\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a" +
- " \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00" +
- "\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a" +
- "\x10\x00\x00\x00\x00Gӵ \x00\x00\x00\x00I\rl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00" +
- "\x00N\xb6L\x90\x00\x00\x00\x00O\\w\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90\x00\x00\x00\x00T\xfc\x1d" +
- "\xa0\x00\x00\x00\x00V5Ԑ\x00\x00\x00\x00V\xe5: \x00\x00\x00\x00X\x1e\xf1\x10\x00\x00\x00\x00X\xc5\x1c \x00\x00\x00\x00Y\xfe\xd3\x10\x00\x00\x00\x00Z\xa4\xfe \x00\x00\x00\x00[\u07b5\x10\x00\x00\x00" +
- "\x00\\\x84\xe0 \x00\x00\x00\x00]\xbe\x97\x10\x00\x00\x00\x00^d\xc2 \x00\x00\x00\x00_\x9e\\\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x02\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" +
- "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" +
- "\a\b\xff\xff\x81d\x00\x00\xff\xff\x8f\x80\x01\x04\xff\xff\x81p\x00\b\xff\xff\x8f\x80\x01\f\xff\xff\x8f\x80\x01\x10\xff\xff\x9d\x90\x01\x14\xff\xff\x8f\x80\x00\x19\xff\xff\x9d\x90\x01\x1d\xff\xff\x9d\x90\x00!LMT\x00" +
- "YDT\x00YST\x00YWT\x00YPT\x00YDDT\x00PST\x00PDT\x00MST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\"_WJ\x05\x00" +
- "\x00J\x05\x00\x00\x11\x00\x00\x00Chile/ContinentalTZif3\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\x00\x82\x00\x00\x00\x06\x00\x00\x00" +
- "\x14\xff\xff\xff\xffi\x87\x1d\xc5\xff\xff\xff\xff\x8f0GE\xff\xff\xff\xff\x9b\\\xe5P\xff\xff\xff\xff\x9f|\xe2\xc5\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^w\xc5\xff\xff\xff\xff\xb1w=@\xff\xff\xff" +
- "\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\"4P\xff\xff\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\\" +
- "\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff\xff\xd3\u070f\xc0\xff\xff\xff\xff\xd4\x17\xd50\xff\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff" +
- "\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +" +
- "\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00" +
- "\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7" +
- "\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00" +
- "\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x03" +
- "0\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00" +
- "\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j" +
- "\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00" +
- "\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc" +
- "0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00" +
- "\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X" +
- "@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00" +
- "\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa" +
- "0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00" +
- "\x00bI\r\xb0\x00\x00\x00\x00c\x1d]@\x00\x00\x00\x00d(\xef\xb0\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x05\x04\x02\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05" +
- "\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05" +
- "\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\xff\xff\xbd\xbb\x00\x00\xff\xff\xbd\xbb\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x00\f\xff\xff\xc7\xc0\x01" +
- "\f\xff\xff\xd5\xd0\x01\x10LMT\x00SMT\x00-05\x00-04\x00-03\x00\n<-04>4<-03>,M9.1.6/24,M4.1.6/24\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?X'\x8e\x96\x04\x00\x00\x96\x04\x00\x00\x12\x00\x00\x00Chile/EasterIslandTZif3\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\x00n\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87B\b\xff\xff\xff\xff\xb9\xc7@\x88\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff" +
- "\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00" +
- "\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r" +
- "\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00" +
- "\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b" +
- "\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00" +
- "\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)" +
- "½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00" +
- "\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008" +
- "\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00" +
- "\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E" +
- "\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00" +
- "\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T" +
- "\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x00" +
- "\x00\x00\x00]t|\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\r\xb0\x00\x00\x00\x00c\x1d]@\x00\x00\x00\x00d" +
- "(\xef\xb0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\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\xff\xff\x99x\x00\x00\xff" +
- "\xff\x99x\x00\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90\x00\f\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\x10LMT\x00EMT\x00-06\x00-07\x00-05\x00\n<-06>6<-05" +
- ">,M9.1.6/22,M4.1.6/22\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x04\x00\x00\x00CubaTZif" +
- "2\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\x00j\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87(\xb8\xff\xff\xff\xff\xacb\u0080\xff\xff\xff\xff\xb1ӔP\xff\xff\xff\xff\xb2" +
- "t]@\xff\xff\xff\xff\xc8[f\xd0\xff\xff\xff\xff\xc8\xd3Q@\xff\xff\xff\xff\xca;H\xd0\xff\xff\xff\xffʼm\xc0\xff\xff\xff\xff\xcc$eP\xff\xff\xff\xff̜O\xc0\xff\xff\xff\xff\xd1\xc4\vP\xff" +
- "\xff\xff\xff\xd2;\xf5\xc0\xff\xff\xff\xffӣ\xedP\xff\xff\xff\xff\xd4\x1b\xd7\xc0\xff\xff\xff\xff\xf7`\x05\xd0\xff\xff\xff\xff\xf7\xff}@\xff\xff\xff\xff\xf9=D\xd0\xff\xff\xff\xff\xf9\xe3S\xc0\xff\xff\xff\xff\xfa" +
- "\xdb;\xd0\xff\xff\xff\xff\xfb\xa7\x86@\xff\xff\xff\xff\xfcũ\xd0\xff\xff\xff\xff\xfd\x87h@\xff\xff\xff\xff\xfe\xb8\x00\xd0\xff\xff\xff\xff\xff\xa7\xe3\xc0\x00\x00\x00\x00\x00\x97\xe2\xd0\x00\x00\x00\x00\x01\x87\xc5\xc0\x00" +
- "\x00\x00\x00\x02w\xc4\xd0\x00\x00\x00\x00\x03p\xe2@\x00\x00\x00\x00\x04`\xe1P\x00\x00\x00\x00\x055\x14\xc0\x00\x00\x00\x00\x06@\xc3P\x00\x00\x00\x00\a\x16H@\x00\x00\x00\x00\b \xa5P\x00\x00\x00\x00\b" +
- "\xf7{\xc0\x00\x00\x00\x00\n\x00\x87P\x00\x00\x00\x00\n\xf0j@\x00\x00\x00\x00\v\xe0iP\x00\x00\x00\x00\fن\xc0\x00\x00\x00\x00\r\xc0KP\x00\x00\x00\x00\x0e\xb9h\xc0\x00\x00\x00\x00\x0f\xb2\xa2P\x00" +
- "\x00\x00\x00\x10}\x9b@\x00\x00\x00\x00\x11Q\xea\xd0\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x131\xcc\xd0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15[\x82\xd0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x17" +
- ";d\xd0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xfb(\xd0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\xdb\n\xd0\x00\x00\x00\x00\x1d\xaf>@\x00" +
- "\x00\x00\x00\x1ezSP\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 Z5P\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"CQ\xd0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$#3\xd0\x00\x00\x00\x00%" +
- ".\xc6@\x00\x00\x00\x00&\x15\x8a\xd0\x00\x00\x00\x00'\x17\xe2\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00(\xf7\xd2\xd0\x00\x00\x00\x00)މP\x00\x00\x00\x00*״\xd0\x00\x00\x00\x00+\xbekP\x00" +
- "\x00\x00\x00,\xb7\x96\xd0\x00\x00\x00\x00-\x9eMP\x00\x00\x00\x00.\x97x\xd0\x00\x00\x00\x00/~/P\x00\x00\x00\x000wZ\xd0\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002W<\xd0\x00\x00\x00\x003" +
- "G-\xd0\x00\x00\x00\x004@YP\x00\x00\x00\x005\x1d\xd5P\x00\x00\x00\x0062\xb0P\x00\x00\x00\x006\xfd\xb7P\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xae\xd0\x00" +
- "\x00\x00\x00:Ƶ\xd0\x00\x00\x00\x00;ې\xd0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@f[\xd0\x00\x00\x00\x00E" +
- "D5P\x00\x00\x00\x00E\xf3\x8c\xd0\x00\x00\x00\x00G$\x17P\x00\x00\x00\x00GܩP\x00\x00\x00\x00I\x03\xf9P\x00\x00\x00\x00I\xb3P\xd0\x00\x00\x00\x00J\xe3\xdbP\x00\x00\x00\x00K\x9cmP\x00" +
- "\x00\x00\x00L\xcc\xf7\xd0\x00\x00\x00\x00M\x85\x89\xd0\x00\x00\x00\x00N\xbfN\xd0\x00\x00\x00\x00Ow\xe0\xd0\x00\x00\x00\x00P\x95\xf6P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb2\xc8\x00\x00\xff\xff\xb2\xc0\x00\x04\xff\xff\xc7\xc0\x01\b\xff\xff\xb9\xb0\x00\fLMT\x00HMT\x00CDT" +
- "\x00CST\x00\nCST5CDT,M3.2.0/0,M11.1.0/1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`l\x8d~\xf1\x01\x00\x00\xf1\x01\x00\x00\x03" +
- "\x00\x00\x00EETTZif2\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\x00TZi" +
- "f2\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\x02\x00\x00\x00\t\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00" +
- "\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc" +
- "\x90\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#<E\x10\x00\x00\x00\x00$,6" +
- "\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00" +
- "\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01" +
- "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x1c \x00\x05\x00\x00*0\x01\x00EEST\x00EET\x00\nEET-2E" +
- "EST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tX\xbe\xe4o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00ESTTZif" +
- "2\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\x00\x01\x00\x00\x00\x04\xff\xff\xb9\xb0\x00\x00EST\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xe7/\xebT\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00EST5EDTTZif2\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\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff" +
- "\xff\xff\xff\x9e\xa6\x1ep\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x86\x00p\xff\xff\xff\xff\xa1\x9a\xcd`\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xfa" +
- "\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00" +
- "\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t" +
- "\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00" +
- "\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17" +
- ")\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00" +
- "\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%" +
- "J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00" +
- "\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003" +
- "GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00" +
- "\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A" +
- "\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" +
- "\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" +
- "\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\xb9\xb0\x00\x04\xff\xff\xc7\xc0\x01\x00\xff\xff\xc7\xc0\x01\b\xff\xff\xc7\xc0\x01\fEDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT," +
- "M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5#)\x16\x1d\x05\x00\x00\x1d\x05\x00\x00\x05\x00\x00\x00EgyptTZif2\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\x80\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff}\xbdM\xab\xff\xff\xff\xffȓ\xb4\xe0\xff\xff\xff\xff\xc8\xfa{\xd0\xff\xff\xff\xff\xc9\xfc\xef\xe0\xff\xff\xff" +
- "\xff\xca\xc7\xe8\xd0\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xcc\xdf)\xd0\xff\xff\xff\xffͬ\xe1\xe0\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xffϏf\xe0\xff\xff\xff\xffЩy\xd0\xff\xff\xff\xffф`" +
- "\xe0\xff\xff\xff\xffҊ\xadP\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\x7f\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\xc2\xfd\x80\xff\xff\xff\xff\xfc۾\xf0\xff\xff\xff\xff\xfd\xa5\x82\x80\xff\xff\xff\xff\xfe\xbc\xf2p\xff\xff\xff\xff\xff\x86\xb6\x00\x00\x00\x00\x00\x00\x9e%\xf0\x00\x00\x00\x00\x01g\xe9\x80\x00\x00\x00\x00\x02\x7fY" +
- "p\x00\x00\x00\x00\x03I\x1d\x00\x00\x00\x00\x00\x04a\xdep\x00\x00\x00\x00\x05+\xa2\x00\x00\x00\x00\x00\x06C\x11\xf0\x00\x00\x00\x00\a\fՀ\x00\x00\x00\x00\b$Ep\x00\x00\x00\x00\b\xee\t\x00\x00\x00\x00" +
- "\x00\n\x05x\xf0\x00\x00\x00\x00\n\xcf<\x80\x00\x00\x00\x00\v\xe7\xfd\xf0\x00\x00\x00\x00\f\xb1\xc1\x80\x00\x00\x00\x00\r\xc91p\x00\x00\x00\x00\x0e\x92\xf5\x00\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t(" +
- "\x80\x00\x00\x00\x00\x11\x8b\x98p\x00\x00\x00\x00\x12U\\\x00\x00\x00\x00\x00\x13n\x1dp\x00\x00\x00\x00\x147\xe1\x00\x00\x00\x00\x00\x15OP\xf0\x00\x00\x00\x00\x16\x19\x14\x80\x00\x00\x00\x00\x17\xa0\x93\xf0\x00\x00\x00" +
- "\x00\x17\xfaH\x00\x00\x00\x00\x00\x19p\xa3\xf0\x00\x00\x00\x00\x19\xdb{\x80\x00\x00\x00\x00\x1a\xf4<\xf0\x00\x00\x00\x00\x1b\xbe\x00\x80\x00\x00\x00\x00\x1c\xd5pp\x00\x00\x00\x00\x1d\x9f4\x00\x00\x00\x00\x00\x1e\xb6\xa3" +
- "\xf0\x00\x00\x00\x00\x1f\x80g\x80\x00\x00\x00\x00 \x97\xd7p\x00\x00\x00\x00!a\x9b\x00\x00\x00\x00\x00\"z\\p\x00\x00\x00\x00#D \x00\x00\x00\x00\x00$b'p\x00\x00\x00\x00%%S\x80\x00\x00\x00" +
- "\x00&<\xc3p\x00\x00\x00\x00'\x06\x87\x00\x00\x00\x00\x00(\x1d\xf6\xf0\x00\x00\x00\x00(纀\x00\x00\x00\x00*\x00{\xf0\x00\x00\x00\x00*\xca?\x80\x00\x00\x00\x00+\xe1\xafp\x00\x00\x00\x00,\xabs" +
- "\x00\x00\x00\x00\x00-\xc2\xe2\xf0\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00\x00/\xa0\x13\xe0\x00\x00\x00\x000k\f\xd0\x00\x00\x00\x001\x7f\xf5\xe0\x00\x00\x00\x002J\xee\xd0\x00\x00\x00\x003_\xd7\xe0\x00\x00\x00" +
- "\x004*\xd0\xd0\x00\x00\x00\x005?\xb9\xe0\x00\x00\x00\x006\n\xb2\xd0\x00\x00\x00\x007(\xd6`\x00\x00\x00\x007\xf3\xcfP\x00\x00\x00\x009\b\xb8`\x00\x00\x00\x009ӱP\x00\x00\x00\x00:\xe8\x9a" +
- "`\x00\x00\x00\x00;\xb3\x93P\x00\x00\x00\x00<\xc8|`\x00\x00\x00\x00=\x93uP\x00\x00\x00\x00>\xa8^`\x00\x00\x00\x00?sWP\x00\x00\x00\x00@\x91z\xe0\x00\x00\x00\x00A\\s\xd0\x00\x00\x00" +
- "\x00Bq\\\xe0\x00\x00\x00\x00C<U\xd0\x00\x00\x00\x00DQ>\xe0\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F1 \xe0\x00\x00\x00\x00F\xe0jP\x00\x00\x00\x00H\x11\x02\xe0\x00\x00\x00\x00H\xb7\x11" +
- "\xd0\x00\x00\x00\x00I\xf0\xe4\xe0\x00\x00\x00\x00J\x8d\xb9P\x00\x00\x00\x00K\xda\x01`\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00L\x89X\xe0\x00\x00\x00\x00L\xa4\xfaP\x00\x00\x00\x00Su8\xe0\x00\x00\x00" +
- "\x00S\xac\x89\xd0\x00\x00\x00\x00Sڼ`\x00\x00\x00\x00T$\x82P\x00\x00\x00\x00dJ\xf0`\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\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\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\x1dU\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT\x00E" +
- "EST\x00EET\x00\nEET-2EEST,M4.5.5/0,M10.5.4/24\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xd6jL\xd8\x05\x00" +
- "\x00\xd8\x05\x00\x00\x04\x00\x00\x00EireTZif2\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\b\x00\x00\x00\x14\xff\xff\xff\xffW\xd1\n\xf1\xff\xff\xff\xff" +
- "\x9b&\xb3\x91\xff\xff\xff\xff\x9b\xd6\v\x11\xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0" +
- "\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff" +
- "\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0" +
- "\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \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Ԡ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 " +
- "\xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff" +
- "\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd7,( " +
- "\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff" +
- "\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0" +
- "\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff" +
- "\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf " +
- "\xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \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ǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: " +
- "\x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00" +
- "\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\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Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\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 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10" +
- "\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\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Ӑ\x00\x00\x00\x00-\x94ڐ\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\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" +
- "\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\xff\xff\xfa\x0f\x00\x00\xff\xff\xfa\x0f\x00\x04\x00\x00\b\x1f\x01\b\x00\x00\x0e\x10\x01\f\x00\x00\x00" +
- "\x00\x00\x10\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x01\x10\x00\x00\x0e\x10\x00\bLMT\x00DMT\x00IST\x00BST\x00GMT\x00\nIST-1GMT0,M10.5.0," +
- "M3.5.0/1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\a\x00\x00\x00Etc/GMTTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o" +
- "\x00\x00\x00\t\x00\x00\x00Etc/GMT+0TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT" +
- "\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\xb8\xe8\x86q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+1TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\xf1\xf0\x00\x00-01\x00\n<-01>1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8e\x1569r\x00\x00" +
- "\x00r\x00\x00\x00\n\x00\x00\x00Etc/GMT+10TZif2\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\x00\x01\x00\x00\x00\x04\xff\xffs`\x00\x00" +
- "-10\x00\n<-10>10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\xb9\xbe\x9dr\x00\x00\x00r\x00\x00\x00\n\x00\x00\x00Etc/GMT+11TZif2\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\x00\x01\x00\x00\x00\x04\xff\xffeP\x00\x00-11\x00\n<-11>11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xe5\xf38cr\x00\x00\x00r\x00\x00\x00\n\x00\x00\x00Etc/GMT+12TZif2\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\x00\x01\x00\x00" +
- "\x00\x04\xff\xffW@\x00\x00-12\x00\n<-12>12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9{\xa2qq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+2" +
- "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\x00\x01\x00\x00\x00\x04\xff\xff\xe3\xe0\x00\x00-02\x00\n<-02>2\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00e\xcb\xe9Qq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+3TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\xd5\xd0\x00\x00-03\x00\n<-03>3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\xfaFDq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/G" +
- "MT+4TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\xc7\xc0\x00\x00-04\x00\n<-04>4\nPK\x03" +
- "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4X\x9b\xf3q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+5TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\xb9\xb0\x00\x00-05\x00\n<-05>5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\x9b\xd1\x04q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00E" +
- "tc/GMT+6TZif2\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\x00T" +
- "Zif2\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\x04\xff\xff\xab\xa0\x00\x00-06\x00\n<-06>6" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84+\x9a$q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+7TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\x9d\x90\x00\x00-07\x00\n<-07>7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"\xf8\x8f/q\x00\x00\x00q\x00\x00\x00\t" +
- "\x00\x00\x00Etc/GMT+8TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\x8f\x80\x00\x00-08\x00\n<-" +
- "08>8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x19\xb3\tq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00Etc/GMT+9TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\x81p\x00\x00-09\x00\n<-09>9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o" +
- "\x00\x00\x00\t\x00\x00\x00Etc/GMT-0TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT" +
- "\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\x1ac\xc3r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-1TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x0e\x10\x00\x00+01\x00\n<+01>-1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9|\xbd7s\x00" +
- "\x00\x00s\x00\x00\x00\n\x00\x00\x00Etc/GMT-10TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x8c\xa0\x00" +
- "\x00+10\x00\n<+10>-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xab\xd1Is\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00Etc/GMT-11TZif2" +
- "\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\x00\x01\x00\x00\x00\x04\x00\x00\x9a\xb0\x00\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xf7\x19s\x81s\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00Etc/GMT-12TZif2\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\x00" +
- "\x01\x00\x00\x00\x04\x00\x00\xa8\xc0\x00\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90`N\xe8s\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00Etc/G" +
- "MT-13TZif2\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\x00TZif" +
- "2\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\x04\x00\x00\xb6\xd0\x00\x00+13\x00\n<+13>-13\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,{\xdc;s\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00Etc/GMT-14TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\xc4\xe0\x00\x00+14\x00\n<+14>-14\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x19y\x04r\x00\x00\x00r\x00\x00" +
- "\x00\t\x00\x00\x00Etc/GMT-2TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x1c \x00\x00+02\x00\n" +
- "<+02>-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\xfcm\x99r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-3TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00*0\x00\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x19<Qr" +
- "\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-4TZif2\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\x00\x01\x00\x00\x00\x04\x00\x008@\x00" +
- "\x00+04\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\xd6~wr\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-5TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00FP\x00\x00+05\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00j\xd5d\xb0r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-6TZif2\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\x00\x01\x00\x00\x00" +
- "\x04\x00\x00T`\x00\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J0p-r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-7T" +
- "Zif2\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\x00\x01\x00\x00\x00\x04\x00\x00bp\x00\x00+07\x00\n<+07>-7\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xc5\x18\xb6\xfbr\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/GMT-8TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00p\x80\x00\x00+08\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\x19@\xb9r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00Etc/" +
- "GMT-9TZif2\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\x00TZif" +
- "2\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\x04\x00\x00~\x90\x00\x00+09\x00\n<+09>-9\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\b\x00\x00\x00Etc/GMT0TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\r\x00\x00\x00Et" +
- "c/GreenwichTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT" +
- "0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\a\x00\x00\x00Etc/UCTTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\a\x00\x00\x00" +
- "Etc/UTCTZif2\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\x00TZ" +
- "if2\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\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\r\x00\x00\x00Etc/UniversalTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\b\x00" +
- "\x00\x00Etc/ZuluTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x10\x00\x00\x00Europe/AmsterdamTZif2\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\x00f\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xdf\xe6\xff\xff\xff\xffm\xe8\xc8\x00\xff\xff\xff\xff\x98DI\x80\xff\xff\xff\xff\x9b\f%p\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\x9f\xce\xf80\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xbbp\xff\xff" +
- "\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9\a" +
- "}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff" +
- "\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \xff\xff\xff\xff\xb60\x10\xa0\xff\xff\xff\xff\xb72" +
- "v\xa0\xff\xff\xff\xff\xb8\x0f\xf2\xa0\xff\xff\xff\xff\xb8\xff\xe3\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\u058b \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff" +
- "\xff\xff\xbe\x9f\x89\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88 \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc58" +
- "[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8J\x19 \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\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\xff\xff\xff\xffӑ@\x10\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b" +
- "\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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#<E\x10\x00\x00" +
- "\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5" +
- "\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02" +
- "\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x04\x1a\x00\x00\x00\x00\x04\x1a\x00\x04\x00\x00\x00\x00\x00\b\x00\x00" +
- "\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x01\x15LMT\x00BMT\x00WET\x00CET\x00CEST\x00WEST\x00\nCET-1CEST,M3.5.0," +
- "M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ߜvυ\x01\x00\x00\x85\x01\x00\x00\x0e\x00\x00\x00Europe/AndorraTZif2\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\x19\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff~6\xb3\x94\xff\xff\xff\xff\xd4A\xdb\x00\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00" +
- "\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8" +
- "\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x01l\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\b\x00\x00\x1c \x01\fLMT\x00WET\x00CET\x00CEST\x00\nCET-" +
- "1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]i\x11u\xd6\x02\x00\x00\xd6\x02\x00\x00\x10\x00\x00\x00Europe/" +
- "AstrakhanTZif2\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\x00" +
- "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\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x18Et\xff\xff\xff\xff\xb5\xa4\vP" +
- "\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00" +
- "\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0" +
- "\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00" +
- "*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0" +
- "\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x00" +
- "8\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p" +
- "\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00" +
- "G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0" +
- "\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00V\xf7\x14p\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04" +
- "\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00-\f\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\fLMT\x00+03\x00+0" +
- "5\x00+04\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcb*j\x8f\xaa\x02\x00\x00\xaa\x02\x00\x00\r\x00\x00\x00Europe/AthensTZ" +
- "if2\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\x007\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xfft?\x98D\xff\xff\xff\xff\x9b\x80!\x80\xff\xff\xff\xff\xb9|\xe9\xe0\xff\xff\xff" +
- "\xff\xb9Ư\xd0\xff\xff\xff\xff\xc9\xf2c\xe0\xff\xff\xff\xff\xca\x10\xa8P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͪL\xf0\xff\xff\xff\xff\u03a2\x18\xe0\xff\xff\xff\xffϓip\xff\xff\xff\xff\xdf\x13\x9e" +
- "`\xff\xff\xff\xff߷\nP\x00\x00\x00\x00\t\xec^`\x00\x00\x00\x00\v\x18\xf4`\x00\x00\x00\x00\vͮ\x00\x00\x00\x00\x00\f\xbd\x9f\x00\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\x8c]\x80\x00\x00\x00" +
- "\x00\x0f\x847\x80\x00\x00\x00\x00\x10j\xfc\x10\x00\x00\x00\x00\x11d{\xf0\x00\x00\x00\x00\x12R\xaa\xf0\x00\x00\x00\x00\x13F\x82`\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc" +
- "\x90\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#<E\x10\x00\x00\x00\x00$,6" +
- "\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00" +
- "\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x05\x04" +
- "\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x16<\x00\x00\x00\x00\x16<\x00\x04" +
- "\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15LMT\x00AMT\x00EEST\x00EET\x00CET\x00CEST\x00\nEET-2EEST" +
- ",M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0e\x00\x00\x00Europe/Bel" +
- "fastTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b" +
- "\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff" +
- "\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa" +
- "\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff" +
- "\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \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Ԡ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff" +
- "\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6" +
- ":\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff" +
- "\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4" +
- "I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff" +
- "\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0" +
- "\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff" +
- "\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\xee" +
- "\x9a\xb1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff" +
- "\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \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ǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00" +
- "\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0f" +
- "qޠ\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Ɛ\x00" +
- "\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\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 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00" +
- "\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\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Ӑ\x00\x00\x00\x00-\x94ڐ\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04" +
- "LMT\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9" +
- "\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00Europe/BelgradeTZif2\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\x03\x00" +
- "\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\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ѡ\x8c\x10\xff\xff\xff\xff\xd2N@\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#<E\x10\x00\x00\x00\x00$,6\x10\x00" +
- "\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+" +
- "\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nC" +
- "ET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\r\x00\x00\x00Euro" +
- "pe/BerlinTZif2\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\x00" +
- "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\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10" +
- "\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00" +
- ",\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01" +
- "\x02\x01\x02\x01\x03\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\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10" +
- "\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00Io\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\x11\x00\x00\x00Europe/BratislavaTZif2\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\x05\x00\x00\x00\x15\xff\xff\xff\xff\x1eI\x92\xf8\xff\xff\xff\xffl\xcf\xea\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\xd2b\a\x10\xff\xff\xff\xffӀ\x1c\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xffԓ\xb4 \xff\xff\xff\xff\xd5\x02r \xff\xff\xff\xff" +
- "\xd5L8\x10\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\x01p\x10\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90" +
- "\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00" +
- "'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː" +
- "\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\r\x88\x00\x00\x00\x00\r\x88\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x00\x00\x01\x11LMT\x00P" +
- "MT\x00CEST\x00CET\x00GMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc" +
- "\x831O\x04\x00\x00O\x04\x00\x00\x0f\x00\x00\x00Europe/BrusselsTZif2\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\x00f\x00\x00\x00\x06" +
- "\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xdf\xe6\xff\xff\xff\xffm\xe8\xc8\x00\xff\xff\xff\xff\x98DI\x80\xff\xff\xff\xff\x9b\f%p\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\x9f\xce\xf80\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xbbp\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff" +
- "\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0" +
- "\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff" +
- "\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \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\xb8\xff\xe3\xa0" +
- "\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\u058b \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\x9f\x89\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff" +
- "\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88 \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠" +
- "\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8J\x19 \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\xd0n^\x90\xff\xff\xff\xff" +
- "\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\xff\xff\xff\xffӑ@\x10\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90" +
- "\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00" +
- "&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90" +
- "\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02" +
- "\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x04\x1a\x00\x00\x00\x00\x04\x1a\x00\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x01\x15LM" +
- "T\x00BMT\x00WET\x00CET\x00CEST\x00WEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x90\xa9\xf5ϕ\x02\x00\x00\x95\x02\x00\x00\x10\x00\x00\x00Europe/BucharestTZif2\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\x007\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffl\xcf\xe0\b\xff\xff\xff\xff\xb7\xb0\xd2\b\xff\xff\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xbaߍ`\xff\xff\xff\xff\xbb\xcf~" +
- "`\xff\xff\xff\xff\xbcȩ\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff\xff\xff\xc2hO\xe0\xff\xff\xff" +
- "\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\"\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff\xff\xff\xc7\x18\x04\xe0\x00\x00\x00\x00\x11\xad\xd1`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\v" +
- "\xd0\x00\x00\x00\x00\x143\xd0`\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00" +
- "\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U" +
- "\x00\x00\x00\x00\x00\"LF\x00\x00\x00\x00\x00#<7\x00\x00\x00\x00\x00$,(\x00\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5\n`\x00\x00\x00" +
- "\x00(\xe4\xfb`\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92" +
- "`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xbb\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x18x\x00\x00\x00\x00\x18x\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00BMT\x00" +
- "EEST\x00EET\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6Kf\xab\xfe\x02\x00" +
- "\x00\xfe\x02\x00\x00\x0f\x00\x00\x00Europe/BudapestTZif2\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\x00D\x00\x00\x00\x03\x00\x00\x00\r\xff" +
- "\xff\xff\xffk\x17\x91\x9c\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\xa0" +
- "\x9a\xc4\x10\xff\xff\xff\xff\xa1dy\x90\xff\xff\xff\xff\xa2p\x1a\x10\xff\xff\xff\xff\xa3M\x96\x10\xff\xff\xff\xff\xc9\xf3\xb5`\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љx\xe0\xff\xff\xff\xffҊ\xc9p\xff\xff\xff\xff\xd3P\xa6\x90\xff\xff\xff\xff\xd4K\x15\x80\xff\xff\xff\xff\xd59\xc3\x10\xff\xff\xff\xff\xd6" +
- ")\xb4\x10\xff\xff\xff\xff\xd7\x19\xa5\x10\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff⢨\xf0\xff\xff\xff\xff\xe3Q\xf2`\xff\xff\xff\xff䂧\x10\xff" +
- "\xff\xff\xff\xe51\xfe\x90\xff\xff\xff\xff\xe6t\xfe\x10\xff\xff\xff\xff\xe7\x11\xe0\x90\xff\xff\xff\xff\xe8T\xe0\x10\xff\xff\xff\xff\xe8\xf1\u0090\x00\x00\x00\x00\x13M'\xf0\x00\x00\x00\x00\x143\xdep\x00\x00\x00\x00\x15" +
- "#\xcfp\x00\x00\x00\x00\x16\x13\xc0p\x00\x00\x00\x00\x17\x03\xb1p\x00\x00\x00\x00\x17\xf3\xa2p\x00\x00\x00\x00\x18\xe3\x93p\x00\x00\x00\x00\x19ӄp\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#" +
- "<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00" +
- "\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001" +
- "]\xd9\x10\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\x02\x01\x02\x01\x02\x01\x02" +
- "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x11\xe4\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0," +
- "M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\x0f\x00\x00\x00Europe/BusingenTZif2" +
- "\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\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff\xff\xca\xe2" +
- "q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\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 l" +
- "r\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00" +
- "\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84" +
- "ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x00\x00\b\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00BMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5." +
- "0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x00\x00Europe/ChisinauTZi" +
- "f2\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\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc8\xf8\xff\xff\xff\xff\x9ek\x9f\f\xff\xff\xff\xff\xb7\xb0\xd2\b\xff\xff\xff\xff" +
- "\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xbaߍ`\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbcȩ\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98|\xe0" +
- "\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff\xff\xff\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\"\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff\xff\xff" +
- "\xc7\x18\x04\xe0\xff\xff\xff\xffȼ\x93`\xff\xff\xff\xff\xcaw}P\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\xd0N\x90`" +
- "\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00" +
- "\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0" +
- "\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&CL\xe0\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00" +
- "(\xe5\x17\x80\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`" +
- "\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xad\x00\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x06\x05\x06\b\a\b" +
- "\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1b\b\x00\x00\x00\x00\x1a\xf4\x00\x04\x00\x00\x18x\x00\b\x00\x00*0\x01\f\x00\x00\x1c " +
- "\x00\x11\x00\x00\x0e\x10\x00\x15\x00\x00\x1c \x01\x19\x00\x008@\x01\x1e\x00\x00*0\x00\"LMT\x00CMT\x00BMT\x00EEST\x00EET\x00CET\x00CEST\x00MSD\x00" +
- "MSK\x00\nEET-2EEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x11\x00" +
- "\x00\x00Europe/CopenhagenTZif2\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\xa2" +
- "a\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#<E\x10\x00\x00\x00\x00$," +
- "6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00" +
- "\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\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\f\x88\x00\x00" +
- "\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5." +
- "0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xd6jL\xd8\x05\x00\x00\xd8\x05\x00\x00\r\x00\x00\x00Europe/DublinTZif2\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\b\x00\x00\x00\x14\xff\xff\xff\xffW\xd1\n\xf1\xff\xff\xff\xff\x9b&\xb3\x91\xff\xff\xff\xff\x9b\xd6\v\x11\xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4" +
- "à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff" +
- "\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9" +
- "\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff" +
- "\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \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" +
- "Ԡ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff" +
- "\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda" +
- "\t\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd7,( \xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff" +
- "\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1r" +
- "H\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff" +
- "\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81" +
- "g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff" +
- "\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \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 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00" +
- "\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\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Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00" +
- "\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\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 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00" +
- "\x00\x00&\f\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" +
- "Ӑ\x00\x00\x00\x00-\x94ڐ\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\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06\a\x06" +
- "\a\x06\a\x06\a\x06\a\xff\xff\xfa\x0f\x00\x00\xff\xff\xfa\x0f\x00\x04\x00\x00\b\x1f\x01\b\x00\x00\x0e\x10\x01\f\x00\x00\x00\x00\x00\x10\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x01\x10\x00\x00\x0e\x10\x00\bLMT\x00D" +
- "MT\x00IST\x00BST\x00GMT\x00\nIST-1GMT0,M10.5.0,M3.5.0/1\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00==\xa4" +
- "\x16\xc4\x04\x00\x00\xc4\x04\x00\x00\x10\x00\x00\x00Europe/GibraltarTZif2\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\x00s\x00\x00\x00\x06" +
- "\x00\x00\x00\x1a\xff\xff\xff\xffW\xd1\n\x04\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0" +
- "\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff" +
- "\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 " +
- "\xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff" +
- "\xb5IZ \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Ԡ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 " +
- "\xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff" +
- "\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90" +
- "\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff" +
- "\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac " +
- "\xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff" +
- "\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0" +
- "\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00" +
- "'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː" +
- "\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\xff\xff\xfa\xfc\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15LMT\x00B" +
- "ST\x00GMT\x00BDST\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0f\x00\x00\x00Europe/GuernseyTZif2\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" +
- "\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff" +
- "\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%`" +
- " \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff" +
- "\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P." +
- "\xa0\xff\xff\xff\xff\xb5IZ \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Ԡ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff" +
- "\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd" +
- " \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff" +
- "\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16" +
- "\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff" +
- "\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce" +
- " \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff" +
- "\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed" +
- " \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff" +
- "\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0\xd1" +
- "\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \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ǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00" +
- "\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a" +
- "\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\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Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a" +
- "\x90\x00\x00\x00\x00\x1aÑ\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 lr\x10\x00\x00\x00" +
- "\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\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Ӑ\x00\x00\x00\x00-\x94ڐ\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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" +
- "\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5" +
- ".0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x0f\x00\x00\x00Europe/HelsinkiTZ" +
- "if2\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\x11\xff\xff\xff\xffS\xba&\x9b\xff\xff\xff\xff\xa4so\x1b\xff\xff\xff\xff\xcb\xceQ`\xff\xff\xff" +
- "\xff\xcc\xc0\xe5`\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%" +
- "\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00" +
- "\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x17e\x00\x00\x00\x00\x17e\x00\x04" +
- "\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00HMT\x00EEST\x00EET\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x12\x00\x00\x00Europe/Isle_of_ManTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4" +
- "à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff" +
- "\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9" +
- "\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff" +
- "\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \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" +
- "Ԡ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff" +
- "\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda" +
- "\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff" +
- "\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B" +
- "\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff" +
- "\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2k" +
- "t \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff" +
- "\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f" +
- "} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff" +
- "\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \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ǻp\x00\x00\x00\x00\x03p" +
- "\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00" +
- "\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\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Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00" +
- "\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\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\xa1" +
- "k\x10\x00\x00\x00\x00 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\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Ӑ\x00\x00\x00\x00-\x94" +
- "ڐ\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00" +
- "\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\aW\x10Ѱ\x04\x00\x00\xb0\x04\x00\x00\x0f\x00\x00\x00Euro" +
- "pe/IstanbulTZif2\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\x00s\x00\x00\x00\x06\x00\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b" +
- "\xf5\x98\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9bվ\xd0\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff" +
- "\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xaa((`\xff\xff\xff\xff\xaa\xe1\xfd\xd0\xff\xff\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc31P\xff\xff\xff\xffȁ?\xe0\xff\xff\xff\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J" +
- "\xf5`\xff\xff\xff\xff\xca\u0380P\xff\xff\xff\xff\xcbˮ`\xff\xff\xff\xff\xd2k\tP\xff\xff\xff\xffӢ9`\xff\xff\xff\xff\xd4C\x02P\xff\xff\xff\xff\xd5L\r\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff" +
- "\xff\xff\xd7+\xef\xe0\xff\xff\xff\xff\xd8\t]\xd0\xff\xff\xff\xff\xd9\x02\x97`\xff\xff\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff\xdb\xd2\\P\xff\xff\xff\xff\xdc\xd4\xd0`\xff\xff\xff\xffݲ" +
- ">P\xff\xff\xff\xff\xf1\xf4\xb9`\xff\xff\xff\xff\xf4b\xefP\xff\xff\xff\xff\xf5h\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a9\x9ap\x00\x00\x00\x00\a\xfbu\x00\x00\x00" +
- "\x00\x00\t\x19|p\x00\x00\x00\x00\t\xd0\xcb\x00\x00\x00\x00\x00\n\xf9^p\x00\x00\x00\x00\v\xb1\xfe\x80\x00\x00\x00\x00\f\xd9@p\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x84" +
- "7\x80\x00\x00\x00\x00\x0f\xf8\x11P\x00\x00\x00\x00\x19\x89\xb0p\x00\x00\x00\x00\x19ܰ\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00\x00\x00\x1c\xc6\xef\xf0\x00\x00\x00\x00\x1d\x9b1p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00" +
- "\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v" +
- "\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00" +
- "\x00\x00-\x8b\x83\xf0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004R" +
- "y\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00" +
- "\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE" +
- "\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00" +
- "\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8fݐ\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c" +
- "\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00" +
- "\x00\x00W\xcf.P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01\x15LMT\x00IMT\x00EEST\x00EET\x00+03\x00+0" +
- "4\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\r\x00\x00\x00Europe/JerseyTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0" +
- "\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff" +
- "\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15" +
- " \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff" +
- "\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \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Ԡ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff" +
- "\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6" +
- "\xa0\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff" +
- "\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!" +
- "\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff" +
- "\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH" +
- "\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff" +
- "\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g" +
- "\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff" +
- "\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \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ǻ" +
- "p\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00" +
- "\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\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Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00" +
- "\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\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 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00" +
- "\x00&\f\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ڐ\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GM" +
- "T\x00BDST\x00\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O+j\x94\x88\x03\x00\x00\x88\x03\x00\x00\x12" +
- "\x00\x00\x00Europe/KaliningradTZif2\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\x00P\x00\x00\x00\b\x00\x00\x00\"\xff\xff\xff\xff" +
- "o\xa2[H\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\xd1|w\xe0\xff\xff\xff\xff" +
- "ѕ\x84`\xff\xff\xff\xffҊ\xadP\xff\xff\xff\xff\xd3Y\xb6\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0" +
- "\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00" +
- " lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80" +
- "\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00" +
- ".\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00" +
- "\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00" +
- "<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\r\x00" +
- "\x00\x00\x00\x00D%ـ\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00\x00\x00\x00" +
- "J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00Ḻ\x80\x00\x00\x00\x00M\x8e~\x00\x00\x00\x00\x00TL+p\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x06\x05\x06\x05\x06\x05\x06" +
- "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\a\x04\x00\x00\x138" +
- "\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\r\x00\x00\x1c \x00\x12\x00\x008@\x01\x16\x00\x00*0\x00\x1a\x00\x00*0\x00\x1eLMT\x00CEST\x00CET\x00EES" +
- "T\x00EET\x00MSD\x00MSK\x00+03\x00\nEET-2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\v\x00\x00\x00Europ" +
- "e/KievTZif2\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\x00TZi" +
- "f2\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\b\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff" +
- "\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff\xceͨp\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc" +
- "@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00" +
- "\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19" +
- "\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00" +
- "\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04" +
- "\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c\x9c\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10" +
- "\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00KMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\nEET-2" +
- "EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f(NN\xdf\x02\x00\x00\xdf\x02\x00\x00\f\x00\x00\x00Europe" +
- "/KirovTZif2\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\x00TZi" +
- "f2\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\a\x00\x00\x00\x18\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00" +
- "\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92" +
- "\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00" +
- "\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xeb" +
- "p\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00" +
- "\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD" +
- "\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00" +
- "\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2" +
- "\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00" +
- "\x00TL\x1d`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\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\x06\x05\x00\x00.\x98\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\x10\x00\x00*0\x00\x14\x00\x008@\x00\x14LMT\x00+03\x00+0" +
- "5\x00+04\x00MSD\x00MSK\x00\nMSK-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\v\x00\x00\x00Europe/Ky" +
- "ivTZif2\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\b\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4\x19" +
- "`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff\xceͨp\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00" +
- "\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82" +
- "\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00" +
- "\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4\xdb" +
- "\x80\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03\x06" +
- "\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c\x9c\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00" +
- "\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00KMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\nEET-2EEST" +
- ",M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&S\x03\t\xae\x05\x00\x00\xae\x05\x00\x00\r\x00\x00\x00Europe/Lis" +
- "bonTZif2\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\x8d\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xff^=\f\x1d\xff\xff\xff\xff\x92掀\xff\xff\xff\xff\x9bK" +
- "mp\xff\xff\xff\xff\x9b\xfeǀ\xff\xff\xff\xff\x9c\x9c\xedp\xff\xff\xff\xff\x9dɃp\xff\xff\xff\xff\x9e\x7frp\xff\xff\xff\xff\x9f\xaa\xb6\xf0\xff\xff\xff\xff\xa0_Tp\xff\xff\xff\xff\xa1\x8b\xeap\xff\xff" +
- "\xff\xff\xa2A\xd9p\xff\xff\xff\xff\xa3nop\xff\xff\xff\xff\xa4#\f\xf0\xff\xff\xff\xff\xa5O\xa2\xf0\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xf4\x8e\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7" +
- "#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb72Lp\xff\xff" +
- "\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a" +
- "\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff" +
- "\xff\xff\xc7\xd9\xdfp\xff\xff\xff\xff\xc9\x01/p\xff\xff\xff\xff\xc9\xf1 p\xff\xff\xff\xff\xca\xe2b\xf0\xff\xff\xff\xff˵R\xf0\xff\xff\xff\xff\xcb\xec\xa3\xe0\xff\xff\xff\xff̀K\xe0\xff\xff\xff\xff\xcc\xdc" +
- "\xa2\xf0\xff\xff\xff\xff͕4\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xff\xcer\xa2\xe0\xff\xff\xff\xff\xceſp\xff\xff\xff\xff\xcfu\x16\xf0\xff\xff\xff\xffϬg\xe0\xff\xff\xff\xff\xd0R\x84\xe0\xff\xff" +
- "\xff\xffХ\xa1p\xff\xff\xff\xff\xd1T\xf8\xf0\xff\xff\xff\xffьI\xe0\xff\xff\xff\xff\xd22f\xe0\xff\xff\xff\xff҅\x83p\xff\xff\xff\xff\xd3Y\xc4\xf0\xff\xff\xff\xff\xd4I\xb5\xf0\xff\xff\xff\xff\xd59" +
- "\xd1 \xff\xff\xff\xff\xd6)\xc2 \xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff\xff\xd8\t\xa4 \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xd9\xe9\x86 \xff\xff\xff\xff\xda\xd9w \xff\xff\xff\xff\xdb\xc9h \xff\xff" +
- "\xff\xffܹY \xff\xff\xff\xffݲ\x84\xa0\xff\xff\xff\xffޢu\xa0\xff\xff\xff\xffߒf\xa0\xff\xff\xff\xff\xe0\x82W\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3R" +
- "*\xa0\xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6!\xfd\xa0\xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\v\x1a \xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xea\xfc \xff\xff" +
- "\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\uf2a2 \xff\xff\xff\xff\xf0z\x93 \xff\xff\xff\xff\xf1j" +
- "\x84 \xff\xff\xff\xff\xf2c\xaf\xa0\xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff\xff\xf4C\x91\xa0\xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff\xf6#s\xa0\xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8\x03U\xa0\xff\xff" +
- "\xff\xff\xf8\xf3F\xa0\x00\x00\x00\x00\f\xab*\x00\x00\x00\x00\x00\r\x9b\x1b\x00\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T" +
- "\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\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 l" +
- "r\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00" +
- "\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84" +
- "ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00\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\x03\x01\x02\x01\x03\x01\x02\x01\x03\x01\x02\x01\x03\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\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\x04\x05\x04\x05\x04\x05\x04\x01\xff\xff\xf7c\x00\x00\x00\x00\x0e\x10\x01\x04\x00" +
- "\x00\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16LMT\x00WEST\x00WET\x00WEMT\x00CET\x00CEST\x00\nWET0WEST," +
- "M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x00\x00Europe/Ljublj" +
- "anaTZif2\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\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7" +
- "K\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ѡ\x8c\x10\xff\xff\xff\xff\xd2N@\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 l" +
- "r\x10\x00\x00\x00\x00!\\c\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00" +
- "\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84" +
- "ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\r\x00\x00\x00Europe/LondonTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff" +
- "\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5" +
- "?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff" +
- "\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3" +
- "r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \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Ԡ\xff" +
- "\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1" +
- "x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff" +
- "\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0" +
- "n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff" +
- "\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb" +
- "\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff" +
- "\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9" +
- "\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff" +
- "\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8" +
- "\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \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ǻp\x00\x00\x00\x00\x03p\xc6 \x00" +
- "\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n" +
- "\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\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Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18" +
- "㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\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 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\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Ӑ\x00\x00\x00\x00-\x94ڐ\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nGM" +
- "T0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x11\x00\x00\x00Europe/" +
- "LuxembourgTZif2\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\x00f\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xdf\xe6\xff\xff\xff\xffm\xe8\xc8" +
- "\x00\xff\xff\xff\xff\x98DI\x80\xff\xff\xff\xff\x9b\f%p\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\x9f\xce\xf80\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xbbp\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5" +
- "\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff" +
- "\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P." +
- "\xa0\xff\xff\xff\xff\xb5IZ \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\xb8\xff\xe3\xa0\xff\xff\xff\xff\xb9\xefԠ\xff\xff\xff\xff\xba\u058b \xff\xff\xff" +
- "\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\x9f\x89\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88" +
- " \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8J\x19 \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\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\xff\xff\xff\xffӑ@" +
- "\x10\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54" +
- "\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00" +
- "\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
- "\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03" +
- "\x04\x03\x04\x00\x00\x04\x1a\x00\x00\x00\x00\x04\x1a\x00\x04\x00\x00\x00\x00\x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x01\x15LMT\x00BMT\x00WET\x00CET\x00CEST\x00" +
- "WEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Zk#V\x81\x03\x00\x00\x81\x03\x00\x00\r" +
- "\x00\x00\x00Europe/MadridTZif2\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\x00O\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xff~6\xb5\x00\xff" +
- "\xff\xff\xff\x9e\xba\xc5\xf0\xff\xff\xff\xff\x9f\xa09\x00\xff\xff\xff\xff\xa0\x90\x1b\xf0\xff\xff\xff\xff\xa1\x81l\x80\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xe7n\x00\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae" +
- "\xa72\x00\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x12\x80\xff\xff\xff\xff\xc2\xc9\xec\xf0\xff" +
- "\xff\xff\xff\xc3X]\x00\xff\xff\xff\xff\xc4H?\xf0\xff\xff\xff\xff\xc4m\x1b\xe0\xff\xff\xff\xff\xc59t`\xff\xff\xff\xff\xc7![\x80\xff\xff\xff\xff\xc7\xf5\x8e\xf0\xff\xff\xff\xff\xcb\xf5\xde`\xff\xff\xff\xff\xcc" +
- "\x95q\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xffΠ\xd5p\xff\xff\xff\xffϣ-`\xff\xff\xff\xffЀ\xb7p\xff\xff\xff\xffу\x0f`\xff\xff\xff\xff\xd2`\x99p\xff\xff\xff\xff\xd3b\xf1`\xff" +
- "\xff\xff\xff\xd4@{p\xff\xff\xff\xff\xd9\x1eF\xe0\xff\xff\xff\xff\xd9\xe9[\xf0\x00\x00\x00\x00\b\r\xcd\xe0\x00\x00\x00\x00\b\xf4\x92p\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\n\xd4tp\x00\x00\x00\x00\v" +
- "\xbb\x1c\xe0\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'" +
- "\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00" +
- "\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\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\xff\xff\xfc\x8c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t" +
- "\x00\x00\x1c \x01\r\x00\x00\x1c \x01\x12\x00\x00\x0e\x10\x00\x17LMT\x00WEST\x00WET\x00WEMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5" +
- ".0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\xa5J[\xa0\x03\x00\x00\xa0\x03\x00\x00\f\x00\x00\x00Europe/MaltaTZif2" +
- "\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\x00V\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffp\xbd\xd3d\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5" +
- "\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff" +
- "\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L" +
- "\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff" +
- "\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00\xc5" +
- "\xb2\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06\x1a3p\x00\x00\x00\x00\a\n$p\x00\x00" +
- "\x00\x00\b\x17\x16p\x00\x00\x00\x00\b\xda4p\x00\x00\x00\x00\t\xf7\x14\x90\x00\x00\x00\x00\n\xc2\r\x80\x00\x00\x00\x00\v\xd6\xf6\x90\x00\x00\x00\x00\f\xa1\xef\x80\x00\x00\x00\x00\r\xb6ؐ\x00\x00\x00\x00\x0e\x81" +
- "р\x00\x00\x00\x00\x0f\x96\xba\x90\x00\x00\x00\x00\x10a\xb3\x80\x00\x00\x00\x00\x11v\x9c\x90\x00\x00\x00\x00\x12A\x95\x80\x00\x00\x00\x00\x13E[\x10\x00\x00\x00\x00\x14*\xb2\x00\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#<E\x10\x00\x00" +
- "\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5" +
- "\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\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\r\x9c\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00CET\x00\nCET-" +
- "1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x10\x00\x00\x00Europe/" +
- "MariehamnTZif2\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\x00" +
- "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\x04\x00\x00\x00\x11\xff\xff\xff\xffS\xba&\x9b\xff\xff\xff\xff\xa4so\x1b" +
- "\xff\xff\xff\xff\xcb\xceQ`\xff\xff\xff\xff\xcc\xc0\xe5`\x00\x00\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00" +
- "'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː" +
- "\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00" +
- "\x00\x17e\x00\x00\x00\x00\x17e\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\rLMT\x00HMT\x00EEST\x00EET\x00\nEET-2EEST,M3.5.0/3," +
- "M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00WI\xc3\x7f(\x03\x00\x00(\x03\x00\x00\f\x00\x00\x00Europe/MinskTZif2\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\x00D\x00\x00\x00\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xca(\xff\xff\xff\xff\xaa\x19\xaa8\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca^p\xd0\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\xd0\n\x02`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17" +
- "\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00" +
- "\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%" +
- "\x1c\n\xf0\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00" +
- "\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005" +
- "\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00" +
- "\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00C" +
- "d\r\x00\x00\x00\x00\x00D%ـ\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00Iκ\x00\x00" +
- "\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00Ḻ\x80\x00\x00\x00\x00M\x8e~\x00\x01\x02\x03\x05\x04\x05\x04\x05\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\a\x02" +
- "\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\b\x00\x00\x19\xd8\x00\x00\x00\x00\x19\xc8\x00\x04\x00\x00\x1c \x00\b\x00\x00*" +
- "0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x00*0\x00\"LMT\x00MMT\x00EET\x00MSK\x00CET\x00CEST\x00MS" +
- "D\x00EEST\x00+03\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\r\x00\x00\x00Europe/Mon" +
- "acoTZif2\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\x00e\x00\x00\x00\a\x00\x00\x00\x1f\xff\xff\xff\xffkɛ\xcf\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\x9bG" +
- "x\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\f\xf0\xff\xff" +
- "\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8X&p\xff\xff\xff\xff\xa9\a" +
- "}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff" +
- "\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb5I/\xf0\xff\xff\xff\xff\xb6/\xe6p\xff\xff\xff\xff\xb72" +
- "Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xba\xd6`\xf0\xff\xff\xff\xff\xbb\xd8\xc6\xf0\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff" +
- "\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc58" +
- "0\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8l'\xe0\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\xd0O\xe1\xe0\xff\xff\xff\xffЉ\xf1\xf0\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\v\xbb9\x00\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xa4" +
- "c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5" +
- "\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00" +
- "\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05" +
- "\x04\x05\x06\x02\x06\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\x00\x00\x021\x00\x00\x00\x00\x021\x00\x04\x00" +
- "\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15\x00\x00\x1c \x01\x1aLMT\x00PMT\x00WEST\x00WET\x00CET\x00CEST\x00WEMT\x00" +
- "\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\r\x00\x00\x00Eu" +
- "rope/MoscowTZif2\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\x00N\x00\x00\x00\v\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc0\xc7\xff\xff\xff\xff\x9b_" +
- "\x1e\xc7\xff\xff\xff\xff\x9d>\xf2y\xff\xff\xff\xff\x9e*\xee\xf9\xff\xff\xff\xff\x9e\xf79i\xff\xff\xff\xff\x9f\x84W\xf9\xff\xff\xff\xff\xa0\xd8l\xe9\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xa1<\xa6@\xff\xff" +
- "\xff\xff\xa4\x10m\xc0\xff\xff\xff\xff\xa4=2\xb0\xff\xff\xff\xff\xa5\x15h\xb0\xff\xff\xff\xff\xa5=\x03\xc0\xff\xff\xff\xff\xa7\x1eEP\xff\xff\xff\xff\xb5\xa4\x19`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18" +
- "\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00" +
- "\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$," +
- "\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)\xd4\xfap\x00\x00" +
- "\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]" +
- "\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00" +
- "\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b" +
- "\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00" +
- "\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8e" +
- "o\xf0\x00\x00\x00\x00TL\x1d`\x01\x03\x02\x03\x04\x02\x04\x05\x06\x05\a\x05\x06\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\t\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" +
- "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\n\x06\x00\x00#9\x00\x00\x00\x00#9\x00\x04\x00\x001\x87\x01\b\x00\x00#w\x00\x04\x00\x00?\x97\x01\f\x00\x00" +
- "8@\x01\x11\x00\x00*0\x00\x15\x00\x00FP\x01\x19\x00\x00\x1c \x00\x1d\x00\x00*0\x01!\x00\x008@\x00\x15LMT\x00MMT\x00MST\x00MDST\x00MSD\x00MSK\x00+" +
- "05\x00EET\x00EEST\x00\nMSK-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\x0e\x00\x00\x00Europe/Nico" +
- "siaTZif2\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\x001\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xff\xa5w\x1e\xb8\x00\x00\x00\x00\t\xed\xaf\xe0\x00\x00\x00\x00\n\xdd" +
- "\x92\xd0\x00\x00\x00\x00\v\xfad\xe0\x00\x00\x00\x00\f\xbe\xc6P\x00\x00\x00\x00\r\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00" +
- "\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3" +
- "\x85`\x00\x00\x00\x00\x19\xd3hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00" +
- "\x00\x00 lG\xe0\x00\x00\x00\x00!\\*\xd0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\f\xd0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\v\xed\xe0\x00\x00\x00\x00'\x05" +
- "\vP\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00" +
- "\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1d" +
- "r\xe0\x00\x00\x00\x0062x\x10\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\x00" +
- "\x00\x1fH\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\tLMT\x00EEST\x00EET\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\v\x00\x00\x00Europe/OsloTZif2\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00" +
- "(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90" +
- "\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\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\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\rLMT\x00CEST\x00CET\x00CEMT\x00\nC" +
- "ET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\f\x00\x00\x00Euro" +
- "pe/ParisTZif2\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\x00T" +
- "Zif2\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\x00e\x00\x00\x00\a\x00\x00\x00\x1f\xff\xff\xff\xffkɛ\xcf\xff\xff\xff\xff\x91`PO\xff" +
- "\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1" +
- "\x80\f\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8X&p\xff" +
- "\xff\xff\xff\xa9\a}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf" +
- "\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\"p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb5I/\xf0\xff\xff\xff\xff\xb6/\xe6p\xff" +
- "\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xba\xd6`\xf0\xff\xff\xff\xff\xbb\xd8\xc6\xf0\xff\xff\xff\xff\xbcȷ\xf0\xff\xff\xff\xff\xbd" +
- "\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff" +
- "\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xc8l'\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\xce" +
- "\xa2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0O\xe1\xe0\xff\xff\xff\xffЉ\xf1\xf0\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\v\xbb9\x00\x00\x00\x00\x00\f\xab\x1b\xf0\x00" +
- "\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13MD\x10\x00\x00\x00\x00\x14" +
- "3\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00" +
- "\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000" +
- "d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x05\x04\x05\x04\x05\x06\x02\x06\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\x00\x00\x021\x00\x00\x00\x00" +
- "\x021\x00\x04\x00\x00\x0e\x10\x01\b\x00\x00\x00\x00\x00\r\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15\x00\x00\x1c \x01\x1aLMT\x00PMT\x00WEST\x00WET\x00CET\x00CEST\x00" +
- "WEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10" +
- "\x00\x00\x00Europe/PodgoricaTZif2\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\x03\x00\x00\x00\r\xff\xff\xff\xff^<" +
- "\xf0H\xff\xff\xff\xff\xca\x025\xe0\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ѡ\x8c\x10\xff\xff" +
- "\xff\xff\xd2N@\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00" +
- "\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4" +
- "\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nCET-1CEST," +
- "M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Io\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\r\x00\x00\x00Europe/Prague" +
- "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\x05\x00\x00\x00\x15\xff\xff\xff\xff\x1eI\x92\xf8\xff\xff\xff\xffl\xcf\xea\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\xcd" +
- "\xa9\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\xd2b\a\x10\xff\xff\xff\xffӀ\x1c\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff" +
- "\xff\xff\xffԓ\xb4 \xff\xff\xff\xff\xd5\x02r \xff\xff\xff\xff\xd5L8\x10\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\x01p\x10\xff\xff\xff\xff\xd9" +
- "\xe9x\x10\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00" +
- "\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00," +
- "\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\r\x88\x00\x00\x00\x00\r\x88\x00\x04\x00\x00\x1c " +
- "\x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x00\x00\x01\x11LMT\x00PMT\x00CEST\x00CET\x00GMT\x00\nCET-1CEST,M3.5.0,M10.5.0" +
- "/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00gp\xc0\xa7\xb6\x02\x00\x00\xb6\x02\x00\x00\v\x00\x00\x00Europe/RigaTZif2\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\x005\x00\x00\x00\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xcd^\xff\xff\xff\xff\x9e\xb9\x87\xfe\xff\xff\xff\xff\x9f\x84\x8e\xfe\xff\xff\xff\xff\xa0\x88F~\xff\xff\xff\xff\xa0˂\xfe\xff" +
- "\xff\xff\xff\xad\xe7\xf1\xde\xff\xff\xff\xffȯd`\xff\xff\xff\xff\xcabeP\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\xd0" +
- "\x82%\x10\xff\xff\xff\xffА\x89p\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00" +
- "\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!" +
- "\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00" +
- "\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/" +
- "t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002M\xbc\x00\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00" +
- "\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00:\xbdC\x10\x01\x02\x01\x02\x01\x03\x04\x06\x05\x06\x05\x06\x05\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\b\x03\b\x03\b\x03\b" +
- "\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x03\b\x00\x00\x16\xa2\x00\x00\x00\x00\x16\xa2\x00\x04\x00\x00$\xb2\x01\b\x00\x00\x1c \x00\f\x00\x00*0\x00\x10\x00\x00\x0e\x10\x00\x14\x00\x00\x1c \x01\x18\x00\x00" +
- "8@\x01\x1d\x00\x00*0\x01!LMT\x00RMT\x00LST\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\nEET-2EEST,M" +
- "3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\v\x00\x00\x00Europe/RomeT" +
- "Zif2\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\x00W\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff" +
- "\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\" +
- "7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\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\xd0n^\x90\xff\xff" +
- "\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t" +
- "\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff" +
- "\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n" +
- "\x93p\x00\x00\x00\x00\a\vu\xf0\x00\x00\x00\x00\bE:\xf0\x00\x00\x00\x00\b\xebW\xf0\x00\x00\x00\x00\n.Wp\x00\x00\x00\x00\n\xcb9\xf0\x00\x00\x00\x00\f\x0e9p\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00" +
- "\x00\x00\r\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\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\"L" +
- "T\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00" +
- "\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d" +
- "\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\v\xb4\x00\x00\x00\x00\v\xb4\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00" +
- "\rLMT\x00RMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x95\x7fpp\xdc\x02\x00\x00\xdc\x02\x00\x00\r\x00\x00\x00Europe/SamaraTZif2\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\x06" +
- "\x00\x00\x00\x10\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0" +
- "\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00" +
- " lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p" +
- "\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\x00\xc7\x00\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xbf`\x00\x00\x00\x00" +
- "-\x94\xb0`\x00\x00\x00\x00.\x84\xa1`\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0" +
- "\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00" +
- ";\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00BE\xdb`" +
- "\x00\x00\x00\x00Cc\xf0\xe0\x00\x00\x00\x00D%\xbd`\x00\x00\x00\x00EC\xd2\xe0\x00\x00\x00\x00F\x05\x9f`\x00\x00\x00\x00G#\xb4\xe0\x00\x00\x00\x00G\xee\xbb\xe0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00" +
- "IΝ\xe0\x00\x00\x00\x00J\xe3x\xe0\x00\x00\x00\x00K\xae\x7f\xe0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x05\x01" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x02\x00\x00.\xf4\x00\x00\x00\x00*0\x00\x04\x00\x008@\x00\b\x00\x00" +
- "FP\x01\f\x00\x008@\x01\b\x00\x00*0\x01\x04LMT\x00+03\x00+04\x00+05\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3" +
- "\x03\x00\x00\xb3\x03\x00\x00\x11\x00\x00\x00Europe/San_MarinoTZif2\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\x00W\x00\x00\x00\x04\x00" +
- "\x00\x00\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff" +
- "\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd" +
- "\xa9\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff" +
- "\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb" +
- "\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00" +
- "\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a\vu\xf0\x00\x00\x00\x00\bE:\xf0\x00\x00\x00\x00\b\xebW\xf0\x00\x00\x00\x00\n" +
- ".Wp\x00\x00\x00\x00\n\xcb9\xf0\x00\x00\x00\x00\f\x0e9p\x00\x00\x00\x00\f\xab\x1b\xf0\x00\x00\x00\x00\r\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00" +
- "\x00\x00\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&" +
- "\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00" +
- "\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x00\x00\v\xb4\x00\x00\x00\x00\v\xb4\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00RMT\x00CEST\x00CET\x00\nCET-1CEST,M3" +
- ".5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00Europe/Sarajevo" +
- "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\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\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ѡ\x8c\x10\xff\xff\xff\xff\xd2N@\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'" +
- "\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00" +
- "\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x00" +
- "\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b8\xfel\xd6\x02\x00\x00\xd6\x02\x00\x00\x0e\x00\x00\x00Europe/SaratovTZif2\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\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00" +
- "\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce" +
- "\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00" +
- "\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbe" +
- "p\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00" +
- "\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<" +
- "p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00" +
- "\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ" +
- "\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00XCNp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x04\x01\x04\x01\x04\x01\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00+2\x00\x00\x00" +
- "\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\fLMT\x00+03\x00+05\x00+04\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00}\xb4N\xb8a\x03\x00\x00a\x03\x00\x00\x11\x00\x00\x00Europe/SimferopolTZif2\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" +
- "\x00K\x00\x00\x00\t\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xc4\b\xff\xff\xff\xff\xaa\x19\xa4 \xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xcb\x04\x8d\xd0\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ϟ8\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea" +
- "\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00" +
- "\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\x8d.\xf0\x00\x00\x00\x00)\xd5" +
- "\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00-\xc2\xc6\xd0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00" +
- "\x00\x000d\x91p\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd" +
- "\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00" +
- "\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC" +
- "\xfd\x10\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00" +
- "\x00\x00L̿\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7" +
- "^\x80\x00\x00\x00\x00TL\x1d`\x01\x02\x03\x05\x04\x05\x04\x05\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x02\a\x02\a\x02\a\x06\x03\x06\x03\x06\x03\a\x02\a\x02\a\x02\a\x02\a\x02\a" +
- "\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\b\x03\x00\x00\x1f\xf8\x00\x00\x00\x00\x1f\xe0\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01" +
- "\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x008@\x00\fLMT\x00SMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\nMSK-3\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\r\x00\x00\x00Europe/SkopjeTZif2\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\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\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ѡ\x8c\x10\xff\xff\xff\xff\xd2N@\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5" +
- "\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00" +
- "\x00\x001]\xd9\x10\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\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\b" +
- "LMT\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xc8\x15\xd0P" +
- "\x02\x00\x00P\x02\x00\x00\f\x00\x00\x00Europe/SofiaTZif2\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\x06\x00\x00\x00\x1a\xff\xff" +
- "\xff\xffV\xb6\xce$\xff\xff\xff\xffr\xc3\xe3\x18\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" +
- "$ \x00\x00\x00\x00\x11c\xefP\x00\x00\x00\x00\x12U?\xe0\x00\x00\x00\x00\x13M\v\xd0\x00\x00\x00\x00\x145!\xe0\x00\x00\x00\x00\x15,\xed\xd0\x00\x00\x00\x00\x16\x13\xc0p\x00\x00\x00\x00\x17\f\xcf\xd0\x00\x00" +
- "\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c" +
- "\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LF\x00\x00\x00\x00\x00#<7\x00\x00\x00\x00\x00$,(\x00\x00\x00\x00\x00%\x1c\x19\x00\x00\x00" +
- "\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5\n`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4" +
- "\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xbb\x10\x01\x02" +
- "\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x00\x00\x15\xdc\x00\x00\x00\x00\x1bh\x00\x04\x00\x00\x1c \x00" +
- "\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x01\x10\x00\x00*0\x01\x15LMT\x00IMT\x00EET\x00CET\x00CEST\x00EEST\x00\nEET-2EEST,M3.5" +
- ".0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x10\x00\x00\x00Europe/Stockhol" +
- "mTZif2\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10" +
- "\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00" +
- "-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\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\f\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00*0\x01\r" +
- "LMT\x00CEST\x00CET\x00CEMT\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "q\x16\x9b?\xa3\x02\x00\x00\xa3\x02\x00\x00\x0e\x00\x00\x00Europe/TallinnTZif2\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\x004\x00\x00\x00" +
- "\b\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xcc\xcc\xff\xff\xff\xff\x9eY-\xcc\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa1\x00+p\xff\xff\xff\xff\xa4soL\xff\xff\xff\xffȰ\xb5" +
- "\xe0\xff\xff\xff\xff\xcaƗP\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\xd0t\xcb\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00" +
- "\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91" +
- "\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00" +
- "\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9" +
- "\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00" +
- "\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00<\xa6_" +
- "\x90\x01\x03\x02\x03\x01\x04\x05\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x04\a\x00\x00\x174\x00\x00\x00" +
- "\x00\x174\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00\x1c \x00\x11\x00\x00*0\x00\x15\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00TMT\x00CEST\x00CET\x00EE" +
- "T\x00MSK\x00MSD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea" +
- "\xc48\xde\\\x02\x00\x00\\\x02\x00\x00\r\x00\x00\x00Europe/TiraneTZif2\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\x002\x00\x00\x00\x03\x00" +
- "\x00\x00\r\xff\xff\xff\xff\x96\xaa4h\xff\xff\xff\xff\xc8m\x87p\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u0378\xe9\x90\x00\x00\x00\x00\b(9\xf0\x00\x00\x00\x00\b\xef>`\x00" +
- "\x00\x00\x00\n\x05x\xf0\x00\x00\x00\x00\n\xd0q\xe0\x00\x00\x00\x00\v\xe9Op\x00\x00\x00\x00\f\xb4H`\x00\x00\x00\x00\r\xd2k\xf0\x00\x00\x00\x00\x0e\x94*`\x00\x00\x00\x00\x0f\xb0\xfcp\x00\x00\x00\x00\x10" +
- "t\f`\x00\x00\x00\x00\x11\x90\xdep\x00\x00\x00\x00\x12S\xee`\x00\x00\x00\x00\x13p\xc0p\x00\x00\x00\x00\x14;\xb9`\x00\x00\x00\x00\x15H\xb9p\x00\x00\x00\x00\x16\x13\xb2`\x00\x00\x00\x00\x171\xd5\xf0\x00" +
- "\x00\x00\x00\x17\xfc\xce\xe0\x00\x00\x00\x00\x19\x00\x94p\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a̯\xf0\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00" +
- "\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00," +
- "\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x02\x00\x00\x12\x98\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT\x00CET\x00C" +
- "EST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00" +
- "\x00\x00Europe/TiraspolTZif2\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\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc8\xf8" +
- "\xff\xff\xff\xff\x9ek\x9f\f\xff\xff\xff\xff\xb7\xb0\xd2\b\xff\xff\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xbaߍ`\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbcȩ\xe0\xff\xff\xff\xff" +
- "\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff\xff\xff\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0" +
- "\xff\xff\xff\xff\xc58\"\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff\xff\xff\xc7\x18\x04\xe0\xff\xff\xff\xffȼ\x93`\xff\xff\xff\xff\xcaw}P\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\xd0N\x90`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0" +
- "\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00" +
- " lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&CL\xe0" +
- "\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00" +
- "-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xad\x00\x01\x02\x04\x03\x04\x03\x04\x03" +
- "\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x06\x05\x06\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\b\a\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1b\b\x00\x00\x00\x00" +
- "\x1a\xf4\x00\x04\x00\x00\x18x\x00\b\x00\x00*0\x01\f\x00\x00\x1c \x00\x11\x00\x00\x0e\x10\x00\x15\x00\x00\x1c \x01\x19\x00\x008@\x01\x1e\x00\x00*0\x00\"LMT\x00CMT\x00BMT\x00EE" +
- "ST\x00EET\x00CET\x00CEST\x00MSD\x00MSK\x00\nEET-2EEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00u\xb0\xcd\xfc\xf8\x02\x00\x00\xf8\x02\x00\x00\x10\x00\x00\x00Europe/UlyanovskTZif2\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\x00B\x00\x00\x00\a\x00\x00\x00\x14\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01" +
- "\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00" +
- "\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\v\xe0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb" +
- "\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00" +
- "\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e" +
- "\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00" +
- "\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c" +
- "\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00" +
- "\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00V\xf7\x14" +
- "p\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x05\x06\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01" +
- "\x04\x01\x04\x01\x03\x01\x03\x00\x00-`\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\b\x00\x008@\x00\f\x00\x008@\x01\f\x00\x00*0\x01\x04\x00\x00\x1c \x00\x10LMT\x00+03\x00+05" +
- "\x00+04\x00+02\x00\n<+04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x0f\x00\x00\x00Europe/Uzhgo" +
- "rodTZif2\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\b\x00\x00\x00\"\xff\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4" +
- "\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff\xceͨp\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00" +
- "\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c" +
- "\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00" +
- "\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4" +
- "ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03" +
- "\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c\x9c\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00" +
- "\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00KMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\nEET-2EES" +
- "T,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\f\x00\x00\x00Europe/Va" +
- "duzTZif2\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\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17" +
- "j\x00\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00" +
- "\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94" +
- "ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\b\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLMT\x00BMT\x00CEST\x00CET\x00\nCET-1CE" +
- "ST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x0e\x00\x00\x00Europe/Vat" +
- "icanTZif2\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\x00W\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b" +
- "8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff" +
- "\xff\xff\xff\xa2\\7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\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\xd0" +
- "n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6뀐\xff" +
- "\xff\xff\xff\xd8\t\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe" +
- "\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00Ų\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00" +
- "\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a\vu\xf0\x00\x00\x00\x00\bE:\xf0\x00\x00\x00\x00\b\xebW\xf0\x00\x00\x00\x00\n.Wp\x00\x00\x00\x00\n\xcb9\xf0\x00\x00\x00\x00\f\x0e9p\x00\x00\x00\x00\f" +
- "\xab\x1b\xf0\x00\x00\x00\x00\r\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(" +
- "\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00" +
- "\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\v\xb4\x00\x00\x00\x00\v\xb4\x00\x04\x00\x00\x1c \x01\b" +
- "\x00\x00\x0e\x10\x00\rLMT\x00RMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00Z\x05wג\x02\x00\x00\x92\x02\x00\x00\r\x00\x00\x00Europe/ViennaTZif2\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" +
- "8\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffo\xa2_/\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\xa2p\x1a\x10\xff\xff\xff\xff\xa3D[\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\xd1\x7fE\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xc3\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff" +
- "\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\t\x96\x10\x00\x00\x00\x00\x13M'\xf0\x00\x00\x00\x00\x143\xd0`\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18" +
- "\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00" +
- "\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x02\x01\x02\x01\x02\x01\x00\x00\x0fQ\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\tLMT\x00CEST\x00" +
- "CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xccb\xf72\xa4\x02\x00\x00\xa4\x02\x00\x00\x0e\x00" +
- "\x00\x00Europe/VilniusTZif2\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\x003\x00\x00\x00\t\x00\x00\x00&\xff\xff\xff\xffV\xb6\xccD\xff" +
- "\xff\xff\xff\x9cO\x1fP\xff\xff\xff\xff\xa1\x85J\x98\xff\xff\xff\xff\xa2\xf10\xf0\xff\xff\xff\xff\xa3fx`\xff\xff\xff\xffȬ\xcfp\xff\xff\xff\xff\xcaY*\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd" +
- "\xa9\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xffϒ4\x10\xff\xff\xff\xff\xd00=\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00" +
- "\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f" +
- "|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\f\n\x00\x00" +
- "\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-" +
- "\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00" +
- "\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00>\x86A\x90\x01\x02\x03\x04\x03\x05\x06\x03\x06\x03\x06\x05\a\x05\a\x05\a\x05\a\x05\a" +
- "\x05\a\x05\a\x05\a\x05\b\x04\b\x04\b\x04\b\x04\b\x04\b\x04\b\x04\b\x04\b\x04\x06\x03\x06\x04\b\x00\x00\x17\xbc\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x16h\x00\b\x00\x00\x0e\x10\x00\f\x00\x00\x1c \x00\x10" +
- "\x00\x00*0\x00\x14\x00\x00\x1c \x01\x18\x00\x008@\x01\x1d\x00\x00*0\x01!LMT\x00WMT\x00KMT\x00CET\x00EET\x00MSK\x00CEST\x00MSD\x00EES" +
- "T\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xec\xa0%\xf1\x02\x00\x00\xf1\x02\x00\x00\x10\x00" +
- "\x00\x00Europe/VolgogradTZif2\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\x00A\x00\x00\x00\a\x00\x00\x00\x18\xff\xff\xff\xff\xa1\xf5F" +
- "\xdc\xff\xff\xff\xff\xb5\xa4\vP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\b\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00" +
- "\x00\x1a̅\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\\8" +
- "\xe0\x00\x00\x00\x00\"L)\xe0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00" +
- "\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91" +
- "p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00" +
- "\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%" +
- "p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00" +
- "\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00Ḷ" +
- "p\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00[\xd4\xed\xf0\x00\x00\x00\x00_\xe7\xb2`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x02\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\x06\x05\x02\x05\x00\x00)\xa4\x00\x00\x00\x00*0\x00\x04\x00\x008@\x00\b\x00\x00FP" +
- "\x01\f\x00\x008@\x01\x10\x00\x00*0\x00\x14\x00\x008@\x00\x14LMT\x00+03\x00+04\x00+05\x00MSD\x00MSK\x00\nMSK-3\nPK\x03\x04\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00>\xfe垛\x03\x00\x00\x9b\x03\x00\x00\r\x00\x00\x00Europe/WarsawTZif2\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" +
- "R\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xd0P\xff\xff\xff\xff\x99\xa8*\xd0\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\xa0\x9a\xb6\x00\xff\xff\xff\xff\xa1e\xbd\x00\xff\xff\xff\xff\xa6}|`\xff\xff\xff\xff\xc8v\xde\x10\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Є\xba\x00\xff\xff\xff\xffѕ\x92p\xff\xff\xff\xffҊ\xbb`\xff\xff\xff\xff\xd3b\xffp\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff" +
- "\xff\xd5^\xad\x10\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\xff\xff\xff\xff\xe8T\xd2\x00\xff\xff\xff\xff\xe8\xf1\xb4" +
- "\x80\xff\xff\xff\xff\xe9᥀\xff\xff\xff\xff\xeaі\x80\xff\xff\xff\xff\xec\x14\x96\x00\xff\xff\xff\xff캳\x00\xff\xff\xff\xff\xed\xaa\xa4\x00\xff\xff\xff\xff\ue695\x00\xff\xff\xff\xff\xef\xd4Z\x00\xff\xff\xff" +
- "\xff\xf0zw\x00\xff\xff\xff\xff\xf1\xb4<\x00\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3\x94\x1e\x00\xff\xff\xff\xff\xf4:;\x00\xff\xff\xff\xff\xf5}:\x80\xff\xff\xff\xff\xf6\x1a\x1d\x00\x00\x00\x00\x00\r\xa4U" +
- "\x80\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\n\x80\x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xec\x80\x00\x00\x00" +
- "\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc\xaf" +
- "\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LT\x10\x00\x00\x00" +
- "\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16" +
- "\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00" +
- "\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x13\xb0\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00*0\x01\x11\x00\x00\x1c" +
- " \x00\x16LMT\x00WMT\x00CEST\x00CET\x00EEST\x00EET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03" +
- "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\r\x00\x00\x00Europe/ZagrebTZif2\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\x03\x00\x00\x00\r\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff\xcf" +
- "\x924\x10\xff\xff\xff\xffЂ%\x10\xff\xff\xff\xffѡ\x8c\x10\xff\xff\xff\xff\xd2N@\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#" +
- "<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00" +
- "\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001" +
- "]\xd9\x10\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\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\bLMT" +
- "\x00CET\x00CEST\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00" +
- ".\x02\x00\x00\x11\x00\x00\x00Europe/ZaporozhyeTZif2\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\b\x00\x00\x00\"" +
- "\xff\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xffͩ\x17\x90\xff\xff\xff\xff\u03a2C\x10\xff\xff\xff\xff" +
- "\xceͨp\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0" +
- "\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00" +
- "\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\b\x80" +
- "\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4ۀ\x00\x00\x00\x00-\x94̀\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x00" +
- "1]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\a\x02\a\x02\a\x02\a\x02\a\x02\a\x02\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c" +
- "\x9c\x00\x04\x00\x00\x1c \x00\b\x00\x00*0\x00\f\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00KMT\x00EET\x00MSK\x00CET\x00C" +
- "EST\x00MSD\x00EEST\x00\nEET-2EEST,M3.5.0/3,M10.5.0/4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#" +
- "\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\r\x00\x00\x00Europe/ZurichTZif2\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" +
- "\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\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#<E\x10\x00\x00\x00" +
- "\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a" +
- "\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\b\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\rLM" +
- "T\x00BMT\x00CEST\x00CET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x80c" +
- "$q\x00\x00\x00q\x00\x00\x00\a\x00\x00\x00FactoryTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00" +
- "\x00-00\x00\n<-00>0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x02\x00\x00\x00GBTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à" +
- "\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff" +
- "\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 " +
- "\xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff" +
- "\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \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Ԡ" +
- "\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff" +
- "\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0" +
- "\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff" +
- "\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90" +
- "\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff" +
- "\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt " +
- "\xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff" +
- "\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} " +
- "\xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff" +
- "\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \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ǻp\x00\x00\x00\x00\x03p\xc6 " +
- "\x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00" +
- "\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ\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Ɛ\x00\x00\x00\x00\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00" +
- "\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\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 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%JK\x90\x00\x00\x00\x00&\f\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Ӑ\x00\x00\x00\x00-\x94ڐ" +
- "\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\nG" +
- "MT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\a\x00\x00\x00GB-Eir" +
- "eTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\t\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 " +
- "\xff\xff\xff\xff\x9c\xcf0\xa0\xff\xff\xff\xff\x9d\xa4à\xff\xff\xff\xff\x9e\x9c\x9d\xa0\xff\xff\xff\xff\x9f\x97\x1a\xa0\xff\xff\xff\xff\xa0\x85\xba \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff" +
- "\xa3{Ƞ\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00Ӡ" +
- "\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \xff\xff\xff\xff" +
- "\xb1\x92Р\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \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Ԡ\xff\xff\xff\xff\xba\xe9\x00 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff" +
- "\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 " +
- "\xff\xff\xff\xff\xc7X֠\xff\xff\xff\xff\xc7\xda\t\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xffʗY\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xffͱ\x00\x90\xff\xff\xff\xff" +
- "\xce`X\x10\xff\xff\xff\xffϐ\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 " +
- "\xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff" +
- "\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\u07b4\xea\xa0\xff\xff\xff\xff߮\x16 \xff\xff\xff\xff\xe0\x94̠" +
- "\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4T\x90\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6=\xad \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff" +
- "\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\ue6b1 " +
- "\xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\r\xa0\xff\xff\xff\xff" +
- "\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0Ѡ\xff\xff\xff\xff\xf9\xfe\xe7 \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ǻp\x00\x00\x00\x00\x03p\xc6 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\t: \x00\x00\x00\x00\a0\x8a \x00\x00\x00\x00\a\xe9\x1c \x00\x00\x00\x00" +
- "\t\x10l \x00\x00\x00\x00\t\xc8\xfe \x00\x00\x00\x00\n\xf0N \x00\x00\x00\x00\v\xb2\x1a\xa0\x00\x00\x00\x00\f\xd00 \x00\x00\x00\x00\r\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \x00\x00\x00\x00\x0fqޠ" +
- "\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Ɛ\x00\x00\x00\x00" +
- "\x17\x03͐\x00\x00\x00\x00\x18\x18\xa8\x90\x00\x00\x00\x00\x18㯐\x00\x00\x00\x00\x19\xf8\x8a\x90\x00\x00\x00\x00\x1aÑ\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 lr\x10\x00\x00\x00\x00!\x81M\x10\x00\x00\x00\x00\"LT\x10\x00\x00\x00\x00#a/\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00" +
- "%JK\x90\x00\x00\x00\x00&\f\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Ӑ\x00\x00\x00\x00-\x94ڐ\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\b\x00\x00\x1c \x01\f\x00\x00\x0e\x10\x00\x04LMT" +
- "\x00BST\x00GMT\x00BDST\x00\nGMT0BST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00" +
- "\x00\x00o\x00\x00\x00\x03\x00\x00\x00GMTTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nG" +
- "MT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x05\x00\x00\x00GMT+0TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x05\x00\x00\x00" +
- "GMT-0TZif2\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\x00TZif" +
- "2\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\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x04\x00\x00\x00GMT0TZif2\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\x00" +
- "\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x00\x00Greenwich" +
- "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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00=\xf7\xfawp\x00\x00\x00p\x00\x00\x00\x03\x00\x00\x00HSTTZif2\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\x00\x01\x00\x00\x00\x04\xff" +
- "\xffs`\x00\x00HST\x00\nHST10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\t\xfa-\a\x03\x00\x00\a\x03\x00\x00\b\x00\x00\x00HongkongTZif2\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\x00E\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff\x85ic\x90\xff\xff\xff\xff\xcaM10\xff\xff\xff\xff\xcaۓ0\xff\xff\xff\xff\xcbKq" +
- "x\xff\xff\xff\xffҠސ\xff\xff\xff\xff\xd3k׀\xff\xff\xff\xffԓX\xb8\xff\xff\xff\xff\xd5B\xb08\xff\xff\xff\xff\xd6s:\xb8\xff\xff\xff\xff\xd7>A\xb8\xff\xff\xff\xff\xd8.2\xb8\xff\xff\xff" +
- "\xff\xd8\xf99\xb8\xff\xff\xff\xff\xda\x0e\x14\xb8\xff\xff\xff\xff\xda\xd9\x1b\xb8\xff\xff\xff\xff\xdb\xed\xf6\xb8\xff\xff\xff\xffܸ\xfd\xb8\xff\xff\xff\xff\xdd\xcdظ\xff\xff\xff\xffޢ\x1a8\xff\xff\xff\xff߶\xf5" +
- "8\xff\xff\xff\xff\xe0\x81\xfc8\xff\xff\xff\xff\xe1\x96\xc9(\xff\xff\xff\xff\xe2Oi8\xff\xff\xff\xff\xe3v\xab(\xff\xff\xff\xff\xe4/K8\xff\xff\xff\xff\xe5_Ǩ\xff\xff\xff\xff\xe6\x0f-8\xff\xff\xff" +
- "\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\r\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef" +
- "\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefwѸ\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff" +
- "\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15a(\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf5C(\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_" +
- "\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\"\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00" +
- "\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\a&\xe6(\x00\x00\x00\x00\a\x83=8\x00\x00\x00\x00\t\x06\xc8(\x00\x00\x00\x00\t\xf6\xc7" +
- "8\x00\x00\x00\x00\n\xe6\xaa(\x00\x00\x00\x00\v֩8\x00\x00\x00\x00\fƌ(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x02\x03\x04\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00k\n\x00\x00\x00\x00p\x80" +
- "\x00\x04\x00\x00~\x90\x01\b\x00\x00w\x88\x01\r\x00\x00~\x90\x00\x12LMT\x00HKT\x00HKST\x00HKWT\x00JST\x00\nHKT-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\a\x00\x00\x00IcelandTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00" +
- "\b\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\nGMT0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00" +
- "\x00\x00\x13\x00\x00\x00Indian/AntananarivoTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14" +
- "\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*" +
- "0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\xb0W\x14\x98\x00\x00\x00\x98\x00" +
- "\x00\x00\r\x00\x00\x00Indian/ChagosTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x89~" +
- "\xf7\x9c\x00\x00\x00\x000\xe6ݰ\x01\x02\x00\x00C\xe4\x00\x00\x00\x00FP\x00\x04\x00\x00T`\x00\bLMT\x00+05\x00+06\x00\n<+06>-6\nPK\x03\x04\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x10\x00\x00\x00Indian/ChristmasTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\bLMT\x00BMT\x00+07\x00" +
- "\n<+07>-7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\f\x00\x00\x00Indian/CocosTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xffњg\xf0\x01\x02" +
- "\x03\x02\x00\x00Z/\x00\x00\x00\x00Z/\x00\x04\x00\x00[h\x00\b\x00\x00~\x90\x00\x0eLMT\x00RMT\x00+0630\x00+09\x00\n<+0630>-6:30\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x00\x00Indian/ComoroTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03" +
- "\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3\nPK\x03\x04\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\xb9\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x10\x00\x00\x00Indian/KerguelenTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x9f\x18\xff\xff\xff\xff\xed/Ø\x01\x02\x00\x00D\xe8\x00\x00\x00\x00D\xe8\x00\x04\x00\x00FP\x00\bLMT\x00MMT\x00+05" +
- "\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00Indian/MaheTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\n<+04" +
- ">-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x00\x00Indian/MaldivesTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xffV\xb6\x9f\x18\xff\xff\xff\xff\xed/Ø\x01\x02\x00\x00D\xe8\x00\x00\x00\x00D\xe8\x00\x04\x00\x00FP\x00\b" +
- "LMT\x00MMT\x00+05\x00\n<+05>-5\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xed=\x98\xb3\x00\x00\x00\xb3\x00\x00\x00\x10\x00\x00\x00Indian/Ma" +
- "uritiusTZif2\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\x00TZ" +
- "if2\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\x05\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x89\x7f\x05\x98\x00\x00\x00\x00\x18\x05\xed@\x00\x00" +
- "\x00\x00\x18\xdbr0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00IΏ\xd0\x02\x01\x02\x01\x02\x00\x005\xe8\x00\x00\x00\x00FP\x01\x04\x00\x008@\x00\bLMT\x00+05\x00+04\x00\n<+" +
- "04>-4\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00Indian/MayotteTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff" +
- "\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\"\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\n\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\nEAT-3" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x00\x00Indian/ReunionTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\n<+04>-4\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xdb?\xec,\x03\x00\x00,\x03\x00\x00\x04\x00\x00\x00IranTZif2\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\x00G\x00" +
- "\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xff\x9al}\xc8\xff\xff\xff\xff\xbf\x00\xccH\x00\x00\x00\x00\r\x94D8\x00\x00\x00\x00\x0e\xad\x13\xb8\x00\x00\x00\x00\x0fys@\x00\x00\x00\x00\x10(\xca\xc0\x00\x00\x00\x00\x10" +
- "\xed:@\x00\x00\x00\x00\x11\xad\xbcH\x00\x00\x00\x00\x12EJ\xb8\x00\x00\x00\x00\x137\xec\xc8\x00\x00\x00\x00\x14-\x15\xb8\x00\x00\x00\x00( v\xc8\x00\x00\x00\x00(\u06dd\xb8\x00\x00\x00\x00)˜\xc8\x00" +
- "\x00\x00\x00*\xbe\"\xb8\x00\x00\x00\x00+\xac\xd0H\x00\x00\x00\x00,\x9fV8\x00\x00\x00\x00-\x8e\x03\xc8\x00\x00\x00\x00.\x80\x89\xb8\x00\x00\x00\x00/o7H\x00\x00\x00\x000a\xbd8\x00\x00\x00\x001" +
- "Pj\xc8\x00\x00\x00\x002B\xf0\xb8\x00\x00\x00\x0032\xef\xc8\x00\x00\x00\x004%u\xb8\x00\x00\x00\x005\x14#H\x00\x00\x00\x006\x06\xa98\x00\x00\x00\x006\xf5V\xc8\x00\x00\x00\x007\xe7ܸ\x00" +
- "\x00\x00\x008֊H\x00\x00\x00\x009\xc9\x108\x00\x00\x00\x00:\xb9\x0fH\x00\x00\x00\x00;\xab\x958\x00\x00\x00\x00<\x9aB\xc8\x00\x00\x00\x00=\x8cȸ\x00\x00\x00\x00>{vH\x00\x00\x00\x00?" +
- "m\xfc8\x00\x00\x00\x00@\\\xa9\xc8\x00\x00\x00\x00AO/\xb8\x00\x00\x00\x00B?.\xc8\x00\x00\x00\x00C1\xb4\xb8\x00\x00\x00\x00G\xe2\xc9H\x00\x00\x00\x00H\xd5O8\x00\x00\x00\x00I\xc5NH\x00" +
- "\x00\x00\x00J\xb7\xd48\x00\x00\x00\x00K\xa6\x81\xc8\x00\x00\x00\x00L\x99\a\xb8\x00\x00\x00\x00M\x87\xb5H\x00\x00\x00\x00Nz;8\x00\x00\x00\x00Oh\xe8\xc8\x00\x00\x00\x00P[n\xb8\x00\x00\x00\x00Q" +
- "Km\xc8\x00\x00\x00\x00R=\xf3\xb8\x00\x00\x00\x00S,\xa1H\x00\x00\x00\x00T\x1f'8\x00\x00\x00\x00U\r\xd4\xc8\x00\x00\x00\x00V\x00Z\xb8\x00\x00\x00\x00V\xef\bH\x00\x00\x00\x00W\xe1\x8e8\x00" +
- "\x00\x00\x00XэH\x00\x00\x00\x00Y\xc4\x138\x00\x00\x00\x00Z\xb2\xc0\xc8\x00\x00\x00\x00[\xa5F\xb8\x00\x00\x00\x00\\\x93\xf4H\x00\x00\x00\x00]\x86z8\x00\x00\x00\x00^u'\xc8\x00\x00\x00\x00_" +
- "g\xad\xb8\x00\x00\x00\x00`W\xac\xc8\x00\x00\x00\x00aJ2\xb8\x00\x00\x00\x00b8\xe0H\x00\x00\x00\x00c+f8\x01\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x0008\x00\x00\x00\x0008\x00\x04\x00\x00" +
- "?H\x01\b\x00\x0018\x00\x0e\x00\x00FP\x01\x14\x00\x008@\x00\x18LMT\x00TMT\x00+0430\x00+0330\x00+05\x00+04\x00\n<+0330>-3" +
- ":30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17✳2\x04\x00\x002\x04\x00\x00\x06\x00\x00\x00IsraelTZif3\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\x00d\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\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\xd7Z0\x80\xff\xff\xff\xff\xd7\xdfX\x00\xff\xff\xff\xff\xd8/À\xff\xff\xff\xff\xd9\x1ec\x00\xff\xff\xff\xff\xda\x10\xf7\x00\xff\xff\xff\xff\xda\xeb\xd0\x00\xff\xff\xff\xff\xdb" +
- "\xb44\x00\xff\xff\xff\xffܹ=\x00\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\u07b4\u0380\xff\xff\xff\xffߤ\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2\xbef\x80\xff" +
- "\xff\xff\xff\xe36_\x00\xff\xff\xff\xff\xe4\x9eH\x80\xff\xff\xff\xff\xe5\x16A\x00\xff\xff\xff\xff\xe6t\xf0\x00\xff\xff\xff\xff\xe7\x11Ҁ\xff\xff\xff\xff\xe8&\xad\x80\xff\xff\xff\xff\xe8\xe8z\x00\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\x001" +
- "H\x96\xe0\x00\x00\x00\x002<nP\x00\x00\x00\x0031\xb3`\x00\x00\x00\x004\x1a\xfe\xd0\x00\x00\x00\x005\x11\x95`\x00\x00\x00\x005\xf1\xa6P\x00\x00\x00\x007\x04\b\x80\x00\x00\x00\x007\xcf\x01p\x00" +
- "\x00\x00\x008\xf6_\x80\x00\x00\x00\x009\xdc\xf9\xe0\x00\x00\x00\x00:\xd0\xedp\x00\x00\x00\x00;\xae[`\x00\x00\x00\x00<\xa3\xa0p\x00\x00\x00\x00=\xa0\xb2`\x00\x00\x00\x00>\x83\x82p\x00\x00\x00\x00?" +
- "|\x9f\xe0\x00\x00\x00\x00@s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F\fS\x00\x00" +
- "\x00\x00\x00F\xecc\xf0\x00\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\t\xf0\x00\x00\x00\x00M" +
- "\x95\x15\x80\x00\x00\x00\x00N\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QTـ\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\b\x00\x00\x1c \x00\f\x00\x008@\x01\x10LMT\x00JMT\x00IDT\x00IST" +
- "\x00IDDT\x00\nIST-2IDT,M3.4.4/26,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%J\xd5\xebS\x01\x00\x00S\x01\x00\x00" +
- "\a\x00\x00\x00JamaicaTZif2\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\x16\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87#~\xff\xff\xff\xff\x93\x0f" +
- "\xb4\xfe\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00" +
- "\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I" +
- ")\xf0\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\xff\xff\xb8\x02\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\fLMT\x00KMT\x00EST\x00EDT\x00\nEST5\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\x05\x00\x00\x00JapanTZif2\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\t\x00\x00\x00\x03\x00\x00\x00\f" +
- "\xff\xff\xff\xffe¤p\xff\xff\xff\xff\xd7>\x02p\xff\xff\xff\xff\xd7\xedY\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd;\xf0\xff\xff\xff\xff\xdb\a\x00\xf0\xff\xff\xff\xffۭ\x1d\xf0\xff\xff\xff\xff" +
- "\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xff\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x83\x03\x00\x00\x00\x00\x8c\xa0\x01\x04\x00\x00~\x90\x00\bLMT\x00JDT\x00JST\x00\nJST-9\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\t\x00\x00\x00KwajaleinTZif2\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\x06\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff~6\x18 \xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xcfF\x81\xf0\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00\x00,v\x0e@" +
- "\x01\x02\x03\x01\x04\x05\x00\x00\x9c\xe0\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\x8c\xa0\x00\b\x00\x00~\x90\x00\f\xff\xffW@\x00\x10\x00\x00\xa8\xc0\x00\x14LMT\x00+11\x00+10\x00+09\x00-1" +
- "2\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x05\x00\x00\x00LibyaTZif2\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\x11\xff\xff\xff\xff\xa1\xf2\xc1$\xff\xff\xff\xffݻ\xb1\x10\xff\xff\xff\xff\xde#\xad`\xff\xff\xff\xff\xe1x\xd2\x10\xff\xff" +
- "\xff\xff\xe1\xe7e\xe0\xff\xff\xff\xff\xe5/?p\xff\xff\xff\xff\xe5\xa9\xcc\xe0\xff\xff\xff\xff\xebN\xc6\xf0\x00\x00\x00\x00\x16\x92B`\x00\x00\x00\x00\x17\b\xf7p\x00\x00\x00\x00\x17\xfa+\xe0\x00\x00\x00\x00\x18\xea" +
- "*\xf0\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a̯\xf0\x00\x00\x00\x00\x1b\xbd\xe4`\x00\x00\x00\x00\x1c\xb4z\xf0\x00\x00\x00\x00\x1d\x9f\x17\xe0\x00\x00\x00\x00\x1e\x93\vp\x00\x00\x00\x00\x1f\x82\xee`\x00\x00" +
- "\x00\x00 pJp\x00\x00\x00\x00!a~\xe0\x00\x00\x00\x00\"R\xcfp\x00\x00\x00\x00#D\x03\xe0\x00\x00\x00\x00$4\x02\xf0\x00\x00\x00\x00%%7`\x00\x00\x00\x00&@\xb7\xf0\x00\x00\x00\x002N" +
- "\xf1`\x00\x00\x00\x003D6p\x00\x00\x00\x0045j\xe0\x00\x00\x00\x00P\x9d\x99\x00\x00\x00\x00\x00QTـ\x00\x00\x00\x00Ri\xb4\x80\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x03\x02\x01\x03\x00\x00\f\\\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\t\x00\x00\x1c \x00\rLMT\x00CEST\x00CET\x00EET\x00\nEET-" +
- "2\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\x9d\x1b\xc9m\x02\x00\x00m\x02\x00\x00\x03\x00\x00\x00METTZif2\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" +
- "\x005\x00\x00\x00\x02\x00\x00\x00\t\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\xd2N" +
- "@\x90\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xc3" +
- "\x91\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#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5" +
- "%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00" +
- "\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00" +
- "\x01\x00\x01\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x05\x00\x00\x1c \x01\x00MEST\x00MET\x00\nMET-1MEST,M3.5.0,M10.5.0/3\nPK\x03\x04" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf5\x8d\x99\x92o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00MSTTZif2\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\x00\x01" +
- "\x00\x00\x00\x04\xff\xff\x9d\x90\x00\x00MST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6h\xcac\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00MST7MDTTZi" +
- "f2\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\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff" +
- "\xa1\x9a\xe9\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00" +
- "\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00" +
- "\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ" +
- "\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00" +
- "\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80" +
- "\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00" +
- "!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ" +
- "\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00" +
- "/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ" +
- "\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00" +
- "=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90" +
- "\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" +
- "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x01\x00\xff\xff\xab\xa0" +
- "\x01\b\xff\xff\xab\xa0\x01\fMDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x00\x00Mexico/BajaNorteTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\n\xf2\xf0\xff\xff\xff" +
- "\xff\xcbꍀ\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xffҙ\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff\xff\xffؑ\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-" +
- "\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff" +
- "\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf" +
- "\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00" +
- "\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16" +
- "\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00" +
- "\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab" +
- "\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00" +
- "\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a" +
- " \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00" +
- "\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O" +
- "\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\u0601 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00P" +
- "ST\x00PDT\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xad=\x98\xce\x02\x00" +
- "\x00\xce\x02\x00\x00\x0e\x00\x00\x00Mexico/BajaSurTZif2\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\x05\x00\x00\x00\x14\xff\xff" +
- "\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xffؑ" +
- "\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00" +
- "\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb" +
- "\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00" +
- "\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8" +
- "U\x10\x00\x00\x00\x00L\xcd\"\x00\x00\x00\x00\x00M\x987\x10\x00\x00\x00\x00N\xad\x04\x00\x00\x00\x00\x00Ox\x19\x10\x00\x00\x00\x00P\x8c\xe6\x00\x00\x00\x00\x00Qa5\x90\x00\x00\x00\x00Rl\xc8\x00\x00\x00" +
- "\x00\x00SA\x17\x90\x00\x00\x00\x00TL\xaa\x00\x00\x00\x00\x00U \xf9\x90\x00\x00\x00\x00V,\x8c\x00\x00\x00\x00\x00W\x00ې\x00\x00\x00\x00X\x15\xa8\x80\x00\x00\x00\x00Xཐ\x00\x00\x00\x00Y\xf5" +
- "\x8a\x80\x00\x00\x00\x00Z\xc0\x9f\x90\x00\x00\x00\x00[\xd5l\x80\x00\x00\x00\x00\\\xa9\xbc\x10\x00\x00\x00\x00]\xb5N\x80\x00\x00\x00\x00^\x89\x9e\x10\x00\x00\x00\x00_\x950\x80\x00\x00\x00\x00`i\x80\x10\x00\x00" +
- "\x00\x00a~M\x00\x00\x00\x00\x00bIb\x10\x00\x00\x00\x00c^/\x00\x01\x02\x01\x03\x01\x02\x01\x04\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03" +
- "\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\xff\xff\x9c<\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\x8f\x80\x00\x10LMT\x00M" +
- "ST\x00CST\x00MDT\x00PST\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\b\x89\x8c\x05\x03\x00\x00\x05\x03\x00\x00\x0e\x00\x00\x00Mexico/Ge" +
- "neralTZif2\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\x00TZif" +
- "2\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\x00D\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff" +
- "\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\f6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xc5ް`\xff\xff\xff\xffƗ4P\xff\xff\xff\xff\xc9U\xf1\xe0\xff\xff\xff\xff\xc9\xea\xddP" +
- "\xff\xff\xff\xff\xcf\x02\xc6\xe0\xff\xff\xff\xffϷVP\xff\xff\xff\xffڙ\x15\xe0\xff\xff\xff\xff\xdbv\x83\xd0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x00" +
- "4R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80" +
- "\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00" +
- "BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p" +
- "\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\v\x00\x00\x00\x00\x00" +
- "P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\t\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00̀" +
- "\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00Xீ\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\\\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00" +
- "^\x89\x90\x00\x00\x00\x00\x00_\x95\"p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x05\x02\x04\x02\x04\x02" +
- "\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\xff\xff\xa3\f\x00\x00\xff\xff" +
- "\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00MST\x00CST\x00MDT\x00CDT\x00CWT\x00\nCST6\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x02\x00\x00\x00NZTZif2\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" +
- "\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7" +
- "`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba̧\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff" +
- "\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\u0083\x8e\xe0\xff\xff\xff\xff\xc3N\x9c" +
- "\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2ښ@\x00\x00\x00" +
- "\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0" +
- "\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00" +
- "\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee" +
- "`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00" +
- "\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#" +
- "`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00" +
- "\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1" +
- "\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00" +
- "\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\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\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00" +
- "\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\nNZST-12NZDT,M9.5.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\a\x00\x00\x00NZ-CHATTZif2\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\x00E\x00\x00\x00" +
- "\x04\x00\x00\x00\x16\xff\xff\xff\xffA\xb7D\x84\xff\xff\xff\xff\xd2ږ\xbc\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1" +
- "\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00" +
- "\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G" +
- "`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00" +
- "\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5" +
- "`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00" +
- "\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9" +
- "\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00" +
- "\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex" +
- "`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\xab\xfc\x00\x00\x00\x00\xacD\x00\x04\x00\x00\xc1\\\x01\n\x00\x00\xb3L\x00\x10LMT\x00+1215\x00" +
- "+1345\x00+1245\x00\n<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x06\x00\x00\x00NavajoTZif2\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" +
- "a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff" +
- "\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94" +
- "\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff" +
- "\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb" +
- "\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00" +
- "\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG" +
- "\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00" +
- "\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff" +
- "\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00" +
- "\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934" +
- "\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00" +
- "\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec" +
- "\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00" +
- "\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\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\xff\xff\x9d\x94\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b" +
- "\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x03\x00\x00\x00PRCTZif2\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\x1d\x00\x00\x00\x03" +
- "\x00\x00\x00\f\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\t\xf9p\xff\xff\xff\xff\xc9ӽ\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0" +
- "\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff" +
- "\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\"g\xa1 " +
- "\x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\aG \x00\x00\x00\x00(\xd2@\x10\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\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\bLMT\x00CDT\x00CST\x00\nCST-" +
- "8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ŭV\xad\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00PST8PDTTZif2\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\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#" +
- "\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00" +
- "\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0" +
- "\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00" +
- "\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15I" +
- "T \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00" +
- "\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j" +
- "\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00" +
- "\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g" +
- "\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00" +
- "\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b" +
- "\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x01\x00" +
- "\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01" +
- "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\x00\xff\xff\x9d\x90\x01\b\xff\xff\x9d\x90\x01\fPDT\x00PST\x00PW" +
- "T\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8A\x15\xfe\x97\x01\x00\x00\x97\x01\x00\x00\f\x00\x00\x00" +
- "Pacific/ApiaTZif2\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\x1a\x00\x00\x00\a\x00\x00\x00\x1a\xff\xff\xff\xffn=\xc9\x00\xff\xff\xff\xff\x91" +
- "\x05\xfc\x00\xff\xff\xff\xff\xdab\x048\x00\x00\x00\x00L\x9f'\xb0\x00\x00\x00\x00M\x97+\xe0\x00\x00\x00\x00N}\xe2`\x00\x00\x00\x00N\xfd\x8b\xa0\x00\x00\x00\x00Ow\r\xe0\x00\x00\x00\x00Pf\xfe\xe0\x00" +
- "\x00\x00\x00Q`*`\x00\x00\x00\x00RF\xe0\xe0\x00\x00\x00\x00S@\f`\x00\x00\x00\x00T&\xc2\xe0\x00\x00\x00\x00U\x1f\xee`\x00\x00\x00\x00V\x06\xa4\xe0\x00\x00\x00\x00V\xff\xd0`\x00\x00\x00\x00W" +
- "\xe6\x86\xe0\x00\x00\x00\x00X߲`\x00\x00\x00\x00Y\xc6h\xe0\x00\x00\x00\x00Z\xbf\x94`\x00\x00\x00\x00[\xaf\x85`\x00\x00\x00\x00\\\xa8\xb0\xe0\x00\x00\x00\x00]\x8fg`\x00\x00\x00\x00^\x88\x92\xe0\x00" +
- "\x00\x00\x00_oI`\x00\x00\x00\x00`ht\xe0\x01\x02\x04\x03\x04\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\xb0\x80\x00\x00\xff\xff_\x00\x00\x00\xff\xff^H\x00\x04\xff" +
- "\xffs`\x01\n\xff\xffeP\x00\x0e\x00\x00\xb6\xd0\x00\x12\x00\x00\xc4\xe0\x01\x16LMT\x00-1130\x00-10\x00-11\x00+13\x00+14\x00\n<+13>-13\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x10\x00\x00\x00Pacific/AucklandTZif2\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\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`" +
- "\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff" +
- "\xba̧\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8" +
- "\xff\xff\xff\xff\u0083\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff" +
- "\xc8\xf7}h\xff\xff\xff\xff\xd2ښ@\x00\x00\x00\x00\t\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0" +
- "\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00" +
- "\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`" +
- "\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00" +
- "#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0" +
- "\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x00" +
- "1J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0" +
- "\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00" +
- "?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`" +
- "\x00\x00\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\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\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8" +
- "\x00\t\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\nNZST-12NZDT,M9.5.0,M" +
- "4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xf2:F\xc9\x00\x00\x00\xc9\x00\x00\x00\x14\x00\x00\x00Pacific/BougainvilleTZ" +
- "if2\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\x05\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6R(\xff\xff\xff\xffr\xed\xa4\x90\xff\xff\xff\xff\xccC6`\xff\xff\xff" +
- "\xff\xd2+l\xf0\x00\x00\x00\x00T\x9e׀\x01\x02\x03\x02\x04\x00\x00\x91\xd8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\t\x00\x00~\x90\x00\r\x00\x00\x9a\xb0\x00\x11LMT\x00PMMT\x00+10" +
- "\x00+09\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\x0f\x00\x00\x00Pacific/Cha" +
- "thamTZif2\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\x00E\x00\x00\x00\x04\x00\x00\x00\x16\xff\xff\xff\xffA\xb7D\x84\xff\xff\xff\xff\xd2ږ\xbc\x00\x00\x00\x00\t" +
- "\x18\xfd\xe0\x00\x00\x00\x00\t\xac\xa5\xe0\x00\x00\x00\x00\n\xef\xa5`\x00\x00\x00\x00\v\x9e\xfc\xe0\x00\x00\x00\x00\f\xd8\xc1\xe0\x00\x00\x00\x00\r~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00" +
- "\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16" +
- "\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\f`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00" +
- "\x00\x00\x00\x1eg\v`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\"0\t\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%" +
- ".\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\r\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*ͧ`\x00\x00\x00\x00+\xab#`\x00" +
- "\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003" +
- "*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\n\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008Ӌ\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00" +
- "\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\\N`\x00\x00\x00\x00A" +
- "^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x01\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x00\x00\xab\xfc\x00\x00\x00\x00\xacD\x00\x04\x00\x00\xc1\\\x01\n\x00\x00\xb3L\x00\x10LMT\x00+1215\x00+1345\x00+1245\x00\n<+1245>-12:45" +
- "<+1345>,M9.5.0/2:45,M4.1.0/3:45\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\r\x00" +
- "\x00\x00Pacific/ChuukTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV\xb6Z\b\xff\xff" +
- "\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\tLMT\x00PMMT\x00+10\x00\n<+10>-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00?X'\x8e\x96\x04\x00\x00\x96\x04\x00\x00\x0e\x00\x00\x00Pacific/EasterTZif3\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\x00n" +
- "\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87B\b\xff\xff\xff\xff\xb9\xc7@\x88\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00rܰ\x00\x00\x00\x00" +
- "\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\r\xb0\x00\x00\x00\x00\a\v\xbc@\x00\x00\x00\x00\a\xdf\xef\xb0" +
- "\x00\x00\x00\x00\b\xfe\x13@\x00\x00\x00\x00\t\xbfѰ\x00\x00\x00\x00\n\xdd\xf5@\x00\x00\x00\x00\v\xa8\xee0\x00\x00\x00\x00\f\xbd\xd7@\x00\x00\x00\x00\r\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00" +
- "\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0" +
- "\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\\@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00" +
- "\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\"9\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0" +
- "\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'١0\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)½\xb0\x00\x00\x00\x00*צ\xc0\x00\x00\x00\x00" +
- "+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@" +
- "\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\vD0\x00\x00\x00\x006\r\xb8@\x00\x00\x00\x007\x06հ\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\b0\x00\x00\x00\x00" +
- "9\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\r\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@Sʰ" +
- "\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00" +
- "G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\a0\x00\x00\x00\x00NP\x82\xc0" +
- "\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\\r\xb0\x00\x00\x00\x00T\v\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00" +
- "W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\\\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00\x00^\x89I\xb0" +
- "\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\r\xb0\x00\x00\x00\x00c\x1d]@\x00\x00\x00\x00d(\xef\xb0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\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\xff\xff\x99x\x00\x00\xff\xff\x99x\x00\x04\xff\xff\xab\xa0\x01\b\xff\xff\x9d\x90" +
- "\x00\f\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\x10LMT\x00EMT\x00-06\x00-07\x00-05\x00\n<-06>6<-05>,M9.1.6/22,M4." +
- "1.6/22\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9e\x7f\xab\x95V\x01\x00\x00V\x01\x00\x00\r\x00\x00\x00Pacific/EfateTZif2\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\x17\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x92\xf5´\x00\x00\x00\x00\ay\x99@\x00\x00\x00\x00\a\xfa\xcc@\x00\x00\x00\x00\x19\xd2\xf7\xd0\x00\x00\x00" +
- "\x00\x1a\xc2\xda\xc0\x00\x00\x00\x00\x1b\xb2\xd9\xd0\x00\x00\x00\x00\x1c\xa2\xbc\xc0\x00\x00\x00\x00\x1d\x9b\xf6P\x00\x00\x00\x00\x1e\x82\x9e\xc0\x00\x00\x00\x00\x1f{\xd8P\x00\x00\x00\x00 k\xbb@\x00\x00\x00\x00![\xba" +
- "P\x00\x00\x00\x00\"K\x9d@\x00\x00\x00\x00#;\x9cP\x00\x00\x00\x00$+\x7f@\x00\x00\x00\x00%\x1b~P\x00\x00\x00\x00&\va@\x00\x00\x00\x00&\xfb`P\x00\x00\x00\x00'\xebC@\x00\x00\x00" +
- "\x00(\xe4|\xd0\x00\x00\x00\x00)\x81Q@\x00\x00\x00\x00*\xe9H\xd0\x00\x00\x00\x00+a3@\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x9d\xcc\x00\x00\x00\x00" +
- "\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\bLMT\x00+12\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x11\x00" +
- "\x00\x00Pacific/EnderburyTZif2\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\x03\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xc3," +
- "ۀ\x00\x00\x00\x00\x12V\x04\xc0\x00\x00\x00\x00/\x059\xb0\x01\x02\x03\x00\x00\x00\x00\x00\x00\xff\xffW@\x00\x04\xff\xffeP\x00\b\x00\x00\xb6\xd0\x00\f-00\x00-12\x00-11\x00+13" +
- "\x00\n<+13>-13\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a|\xdcU\x99\x00\x00\x00\x99\x00\x00\x00\x0f\x00\x00\x00Pacific/FakaofoTZif" +
- "2\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\x02\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff~7U\x88\x00\x00\x00\x00N\xfd\x99\xb0\x01\x02\xff\xff_x\x00\x00\xff\xffeP\x00" +
- "\x04\x00\x00\xb6\xd0\x00\bLMT\x00-11\x00+13\x00\n<+13>-13\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd_yl\x8c\x01\x00\x00\x8c\x01\x00\x00\f\x00\x00\x00P" +
- "acific/FijiTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x9a\x13\xb1\xc0\x00\x00\x00\x006;" +
- "\x17\xe0\x00\x00\x00\x006\xd7\xfa`\x00\x00\x00\x008$4`\x00\x00\x00\x008\xb7\xdc`\x00\x00\x00\x00K\x11,\xe0\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xc2\xea`\x00\x00\x00\x00MrA\xe0\x00\x00" +
- "\x00\x00N\xa2\xcc`\x00\x00\x00\x00O\x1a\xc4\xe0\x00\x00\x00\x00P\x82\xae`\x00\x00\x00\x00P\xfa\xa6\xe0\x00\x00\x00\x00Rk\xca\xe0\x00\x00\x00\x00R\xdaz\xd0\x00\x00\x00\x00TT\xe7`\x00\x00\x00\x00T\xba" +
- "j\xe0\x00\x00\x00\x00V4\xc9`\x00\x00\x00\x00V\x9aL\xe0\x00\x00\x00\x00X\x1d\xe5\xe0\x00\x00\x00\x00Xz.\xe0\x00\x00\x00\x00Y\xfd\xc7\xe0\x00\x00\x00\x00ZZ\x10\xe0\x00\x00\x00\x00[ݩ\xe0\x00\x00" +
- "\x00\x00\\9\xf2\xe0\x00\x00\x00\x00]\xc6\xc6`\x00\x00\x00\x00^\x19\xd4\xe0\x00\x00\x00\x00_\xde\a`\x00\x00\x00\x00`\x02\xf1`\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\x00\x00\xa7\xc0\x00\x00\x00\x00\xb6\xd0\x01\x04\x00\x00\xa8\xc0\x00\bLMT\x00+13\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x10\x00\x00\x00Pacific/FunafutiTZif2\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\x01" +
- "\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x81\xe3w\n\xaf\x00\x00\x00\xaf\x00\x00\x00\x11\x00\x00\x00Pacific/GalapagosTZif2\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" +
- "\x04\x00\x00\x00\x04\x00\x00\x00\f\xff\xff\xff\xff\xb6\xa4L\x80\x00\x00\x00\x00\x1e\x18\xc4P\x00\x00\x00\x00+\x17\n\xe0\x00\x00\x00\x00+q\xf4P\x01\x03\x02\x03\xff\xff\xac\x00\x00\x00\xff\xff\xb9\xb0\x00\x04\xff\xff\xb9" +
- "\xb0\x01\x04\xff\xff\xab\xa0\x00\bLMT\x00-05\x00-06\x00\n<-06>6\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc23\xa0\xbc\x84\x00\x00\x00\x84\x00\x00\x00\x0f\x00\x00\x00P" +
- "acific/GambierTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94PH\x04\x01\xff\xff" +
- "\x81|\x00\x00\xff\xff\x81p\x00\x04LMT\x00-09\x00\n<-09>9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x13\x00\x00\x00Paci" +
- "fic/GuadalcanalTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94O3\x8c\x01\x00" +
- "\x00\x95\xf4\x00\x00\x00\x00\x9a\xb0\x00\x04LMT\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FI\xfe\x14^\x01\x00\x00^\x01\x00\x00\f\x00\x00\x00P" +
- "acific/GuamTZif2\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\x15\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\x14\xe1\xc5\xcc\xff\xff\xff\xff~6" +
- "-L\xff\xff\xff\xff\xcb7\x95\xe0\xff\xff\xff\xff\xd0.\x89\xf0\xff\xff\xff\xff\xec7\xbe\x00\xff\xff\xff\xff\xef6\xf8\xf0\xff\xff\xff\xff\xfb\x9b\x00\x00\xff\xff\xff\xff\xfe?'\x8c\xff\xff\xff\xff\xff\x01\x1e\x00\xff\xff" +
- "\xff\xff\xff]X\xf0\x00\x00\x00\x00\x00\x97,\x00\x00\x00\x00\x00\x01Fup\x00\x00\x00\x00\x02w\x0e\x00\x00\x00\x00\x00\x03&Wp\x00\x00\x00\x00\ap\x97\x00\x00\x00\x00\x00\a\xcc\xd1\xf0\x00\x00\x00\x00\f\b" +
- "\x91\x00\x00\x00\x00\x00\f|\x87,\x00\x00\x00\x00\r\xbf\x94\x80\x00\x00\x00\x00\x0ee\xa3p\x00\x00\x00\x00:C^`\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\xff\xff64\x00" +
- "\x00\x00\x00\x87\xb4\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10LMT\x00GST\x00+09\x00GDT\x00ChST\x00\nChST-10" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x00\x00Pacific/HonoluluTZif2\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\a\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xffˉ=\xc8\xff\xff\xff\xff\xd2#" +
- "\xf4p\xff\xff\xff\xff\xd2aI8\xff\xff\xff\xffՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\b\xff\xffzh\x01\f\xff\xffzh\x01\x10\xff\xffs`\x00" +
- "\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\nHST10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x00\x00Pa" +
- "cific/JohnstonTZif2\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\a\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff" +
- "\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xffˉ=\xc8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aI8\xff\xff\xff\xffՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xff" +
- "lX\x00\x04\xff\xffzh\x01\b\xff\xffzh\x01\f\xff\xffzh\x01\x10\xff\xffs`\x00\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\nHST10\nPK\x03\x04\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x0e\x00\x00\x00Pacific/KantonTZif2\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\x03\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xc3,ۀ\x00\x00\x00\x00\x12V\x04\xc0\x00\x00\x00\x00/\x059\xb0\x01\x02\x03\x00\x00\x00\x00\x00\x00\xff\xffW@\x00\x04\xff\xffeP\x00\b\x00" +
- "\x00\xb6\xd0\x00\f-00\x00-12\x00-11\x00+13\x00\n<+13>-13\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8=ku\xae\x00\x00\x00\xae\x00\x00\x00\x12\x00\x00" +
- "\x00Pacific/KiritimatiTZif2\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\x03\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff~7" +
- "H\x80\x00\x00\x00\x00\x12U\xf2\x00\x00\x00\x00\x00/\x05+\xa0\x01\x02\x03\xff\xffl\x80\x00\x00\xff\xffj\x00\x00\x04\xff\xffs`\x00\n\x00\x00\xc4\xe0\x00\x0eLMT\x00-1040\x00-10\x00+" +
- "14\x00\n<+14>-14\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97n7\x1a\xf2\x00\x00\x00\xf2\x00\x00\x00\x0e\x00\x00\x00Pacific/KosraeTZi" +
- "f2\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\t\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\x14ᴴ\xff\xff\xff\xff~6\x1c4\xff\xff\xff\xff\x98\x11\x95\xd0\xff\xff\xff\xff" +
- "\xa09\xf9\xf0\xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xd2\x11\x0e\xf0\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00\x006\x8bg@\x01\x02\x03\x02\x04\x03\x02\x05\x02\xff\xffGL\x00\x00\x00" +
- "\x00\x98\xcc\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x00\f\x00\x00\xa8\xc0\x00\x10LMT\x00+11\x00+09\x00+10\x00+12\x00\n<+11>-11\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\x11\x00\x00\x00Pacific/KwajaleinTZif2\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\x06\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff~6\x18 \xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\n`\xff\xff\xff\xff\xcfF\x81\xf0\xff\xff\xff\xff\xff\x86\x1b" +
- "P\x00\x00\x00\x00,v\x0e@\x01\x02\x03\x01\x04\x05\x00\x00\x9c\xe0\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\x8c\xa0\x00\b\x00\x00~\x90\x00\f\xff\xffW@\x00\x10\x00\x00\xa8\xc0\x00\x14LMT\x00+11\x00+" +
- "10\x00+09\x00-12\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00Pacif" +
- "ic/MajuroTZif2\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\x00" +
- "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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00" +
- "\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D6\x83\xa1\x8b\x00\x00\x00\x8b\x00\x00\x00\x11\x00\x00\x00Pacific" +
- "/MarquesasTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\n\xff\xff\xff\xff\x94PLH\x01\xff\xff}8\x00\x00" +
- "\xff\xffzh\x00\x04LMT\x00-0930\x00\n<-0930>9:30\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x0e\x00\x00\x00P" +
- "acific/MidwayTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff" +
- "\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\nSST11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2;Z\xf7\xb7\x00\x00" +
- "\x00\xb7\x00\x00\x00\r\x00\x00\x00Pacific/NauruTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff" +
- "\xff\xa3\xe7+\x04\xff\xff\xff\xff̐\xe9\xc8\xff\xff\xff\xff\xd2C'\xf0\x00\x00\x00\x00\x11!\xa8\xe8\x01\x02\x01\x03\x00\x00\x9c|\x00\x00\x00\x00\xa1\xb8\x00\x04\x00\x00~\x90\x00\n\x00\x00\xa8\xc0\x00\x0eLMT" +
- "\x00+1130\x00+09\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\xd60\f\x9a\x00\x00\x00\x9a\x00\x00\x00\f\x00\x00\x00Pacif" +
- "ic/NiueTZif2\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\x00TZ" +
- "if2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffߡjL\xff\xff\xff\xff\xf5\xa6\xb8`\x01\x02" +
- "\xff\xff`\xb4\x00\x00\xff\xff`\xa0\x00\x04\xff\xffeP\x00\nLMT\x00-1120\x00-11\x00\n<-11>11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y5\x1a6\xf7" +
- "\x00\x00\x00\xf7\x00\x00\x00\x0f\x00\x00\x00Pacific/NorfolkTZif2\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\x06\x00\x00\x00\x06\x00\x00\x00" +
- "\x1e\xff\xff\xff\xff~6\x17\x88\xff\xff\xff\xff\xdcA\xf8\x80\x00\x00\x00\x00\t\x0f\xcah\x00\x00\x00\x00\t\xb5\xe7h\x00\x00\x00\x00V\x0f\xe6h\x00\x00\x00\x00]\x98\xaf\xf0\x01\x02\x03\x02\x04\x05\x00\x00\x9dx\x00" +
- "\x00\x00\x00\x9d\x80\x00\x04\x00\x00\xa1\xb8\x00\n\x00\x00\xaf\xc8\x01\x10\x00\x00\x9a\xb0\x00\x16\x00\x00\xa8\xc0\x01\x1aLMT\x00+1112\x00+1130\x00+1230\x00+11\x00+12" +
- "\x00\n<+11>-11<+12>,M10.1.0,M4.1.0/3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\xef\x97\xc6\xc6\x00\x00\x00\xc6\x00\x00\x00\x0e" +
- "\x00\x00\x00Pacific/NoumeaTZif2\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\a\x00\x00\x00\x03\x00\x00\x00\f\xff\xff\xff\xff\x92\xf5\xc4t" +
- "\x00\x00\x00\x00\x0e\xe6\xbaP\x00\x00\x00\x00\x0fV\xbb\xc0\x00\x00\x00\x00\x10ƜP\x00\x00\x00\x00\x117\xef@\x00\x00\x00\x002\xa0K\xf0\x00\x00\x00\x003\x18Dp\x02\x01\x02\x01\x02\x01\x02\x00\x00\x9c\f\x00" +
- "\x00\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\bLMT\x00+12\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00" +
- "\x00\x11\x00\x00\x00Pacific/Pago_PagoTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff" +
- "\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\nSST11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x80\xf8vܔ\x00\x00\x00\x94\x00\x00\x00\r\x00\x00\x00Pacific/PalauTZif2\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\x02\x00\x00" +
- "\x00\x03\x00\x00\x00\b\xff\xff\xff\xff\x14\xe1\xcfl\xff\xff\xff\xff~66\xec\x01\x02\xff\xff,\x94\x00\x00\x00\x00~\x14\x00\x00\x00\x00~\x90\x00\x04LMT\x00+09\x00\n<+09>-9\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x0fA\x05\x99\x00\x00\x00\x99\x00\x00\x00\x10\x00\x00\x00Pacific/PitcairnTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff~7.\xf4\x00\x00\x00\x005DB\b\x01\x02\xff\xff\x86\f\x00\x00\xff\xff\x88x\x00\x04\xff\xff\x8f\x80\x00\nLMT\x00" +
- "-0830\x00-08\x00\n<-08>8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x0f\x00\x00\x00Pacific/Pohn" +
- "peiTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94O3\x8c\x01\x00\x00\x95\xf4\x00\x00\x00\x00\x9a\xb0\x00\x04L" +
- "MT\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00Pacific/Ponap" +
- "eTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94O3\x8c\x01\x00\x00\x95\xf4\x00\x00\x00\x00\x9a\xb0\x00\x04LMT" +
- "\x00+11\x00\n<+11>-11\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x14\x00\x00\x00Pacific/Port_Mo" +
- "resbyTZif2\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\x00TZif" +
- "2\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\x02\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV\xb6Z\b\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00" +
- "\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\tLMT\x00PMMT\x00+10\x00\n<+10>-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xe3\xa3S\x96\x01\x00" +
- "\x00\x96\x01\x00\x00\x11\x00\x00\x00Pacific/RarotongaTZif2\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\x1c\x00\x00\x00\x05\x00\x00\x00" +
- "\x14\xff\xff\xff\xff|L\xdc\xc8\xff\xff\xff\xffߡ`\xc8\x00\x00\x00\x00\x10\xac\x1b(\x00\x00\x00\x00\x11?\xb5\x18\x00\x00\x00\x00\x12y\x81 \x00\x00\x00\x00\x13\x1f\x97\x18\x00\x00\x00\x00\x14Yc \x00\x00\x00" +
- "\x00\x14\xffy\x18\x00\x00\x00\x00\x169E \x00\x00\x00\x00\x16蕘\x00\x00\x00\x00\x18\"a\xa0\x00\x00\x00\x00\x18\xc8w\x98\x00\x00\x00\x00\x1a\x02C\xa0\x00\x00\x00\x00\x1a\xa8Y\x98\x00\x00\x00\x00\x1b\xe2%" +
- "\xa0\x00\x00\x00\x00\x1c\x88;\x98\x00\x00\x00\x00\x1d\xc2\a\xa0\x00\x00\x00\x00\x1eh\x1d\x98\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 G\xff\x98\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"1\x1c\x18\x00\x00\x00" +
- "\x00#j\xe8 \x00\x00\x00\x00$\x10\xfe\x18\x00\x00\x00\x00%J\xca \x00\x00\x00\x00%\xf0\xe0\x18\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xd0\xc2\x18\x01\x02\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\x00\x00\xbb\xb8\x00\x00\xff\xffj8\x00\x00\xff\xfflX\x00\x04\xff\xffs`\x00\n\xff\xffzh\x01\x0eLMT\x00-1030\x00-10\x00-09" +
- "30\x00\n<-10>10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FI\xfe\x14^\x01\x00\x00^\x01\x00\x00\x0e\x00\x00\x00Pacific/SaipanTZif" +
- "2\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\x15\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\x14\xe1\xc5\xcc\xff\xff\xff\xff~6-L\xff\xff\xff\xff\xcb7\x95\xe0\xff\xff\xff\xff\xd0" +
- ".\x89\xf0\xff\xff\xff\xff\xec7\xbe\x00\xff\xff\xff\xff\xef6\xf8\xf0\xff\xff\xff\xff\xfb\x9b\x00\x00\xff\xff\xff\xff\xfe?'\x8c\xff\xff\xff\xff\xff\x01\x1e\x00\xff\xff\xff\xff\xff]X\xf0\x00\x00\x00\x00\x00\x97,\x00\x00" +
- "\x00\x00\x00\x01Fup\x00\x00\x00\x00\x02w\x0e\x00\x00\x00\x00\x00\x03&Wp\x00\x00\x00\x00\ap\x97\x00\x00\x00\x00\x00\a\xcc\xd1\xf0\x00\x00\x00\x00\f\b\x91\x00\x00\x00\x00\x00\f|\x87,\x00\x00\x00\x00\r" +
- "\xbf\x94\x80\x00\x00\x00\x00\x0ee\xa3p\x00\x00\x00\x00:C^`\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\xff\xff64\x00\x00\x00\x00\x87\xb4\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00" +
- "~\x90\x00\b\x00\x00\x9a\xb0\x01\f\x00\x00\x8c\xa0\x00\x10LMT\x00GST\x00+09\x00GDT\x00ChST\x00\nChST-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\r\x00\x00\x00Pacific/SamoaTZif2\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\x02\x00\x00\x00\x03" +
- "\x00\x00\x00\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\nSST11\nPK\x03\x04\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\xc1\xdaυ\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x00\x00Pacific/TahitiTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff\x94PU\xb8\x01\xff\xffs\xc8\x00\x00\xff\xffs`\x00\x04LMT\x00-10\x00\n<-10>10\nPK\x03\x04\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00Pacific/TarawaTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x97F\x91\xb3\xed\x00\x00\x00\xed\x00\x00\x00\x11\x00\x00\x00Pacific/TongatapuTZif2\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\n\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\xd2E\x9c@\xff\xff\xff\xff\xef\x11\xe0\x10\x00\x00\x00\x007\xfbG\xd0\x00\x00\x00\x008\xd3}\xd0\x00\x00\x00\x00:\x04\bP\x00\x00\x00\x00:r\xb8@" +
- "\x00\x00\x00\x00;\xe3\xeaP\x00\x00\x00\x00<R\x9a@\x00\x00\x00\x00X\x1d\xd7\xd0\x00\x00\x00\x00Xz \xd0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\xad@\x00\x00\x00\x00\xadp\x00\x04\x00\x00\xb6\xd0\x00\n" +
- "\x00\x00\xc4\xe0\x01\x0eLMT\x00+1220\x00+13\x00+14\x00\n<+13>-13\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00" +
- "\f\x00\x00\x00Pacific/TrukTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\r\xff\xff\xff\xffV\xb6Z\b\xff" +
- "\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\tLMT\x00PMMT\x00+10\x00\n<+10>-10\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\f\x00\x00\x00Pacific/WakeTZif2\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\x01\x00" +
- "\x00\x00\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "6\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00Pacific/WallisTZif2\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\x01\x00\x00\x00" +
- "\x02\x00\x00\x00\b\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\n<+12>-12\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04" +
- "\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\v\x00\x00\x00Pacific/YapTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\r" +
- "\xff\xff\xff\xffV\xb6Z\b\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\tLMT\x00PMMT\x00+10\x00\n<+10>-10\nP" +
- "K\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xfe垛\x03\x00\x00\x9b\x03\x00\x00\x06\x00\x00\x00PolandTZif2\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" +
- "\x00R\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xd0P\xff\xff\xff\xff\x99\xa8*\xd0\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\xa0\x9a\xb6\x00\xff\xff\xff\xff\xa1e\xbd\x00\xff\xff\xff\xff\xa6}|`\xff\xff\xff\xff\xc8v\xde\x10\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Є\xba\x00\xff\xff\xff\xffѕ\x92p\xff\xff\xff\xffҊ\xbb`\xff\xff\xff\xff\xd3b\xffp\xff\xff\xff\xff\xd4K#\x90\xff\xff" +
- "\xff\xff\xd5^\xad\x10\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\xff\xff\xff\xff\xe8T\xd2\x00\xff\xff\xff\xff\xe8\xf1" +
- "\xb4\x80\xff\xff\xff\xff\xe9᥀\xff\xff\xff\xff\xeaі\x80\xff\xff\xff\xff\xec\x14\x96\x00\xff\xff\xff\xff캳\x00\xff\xff\xff\xff\xed\xaa\xa4\x00\xff\xff\xff\xff\ue695\x00\xff\xff\xff\xff\xef\xd4Z\x00\xff\xff" +
- "\xff\xff\xf0zw\x00\xff\xff\xff\xff\xf1\xb4<\x00\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3\x94\x1e\x00\xff\xff\xff\xff\xf4:;\x00\xff\xff\xff\xff\xf5}:\x80\xff\xff\xff\xff\xf6\x1a\x1d\x00\x00\x00\x00\x00\r\xa4" +
- "U\x80\x00\x00\x00\x00\x0e\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\n\x80\x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xec\x80\x00\x00" +
- "\x00\x00\x15#݀\x00\x00\x00\x00\x16\x13\u0380\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18㡀\x00\x00\x00\x00\x19Ӓ\x80\x00\x00\x00\x00\x1aÃ\x80\x00\x00\x00\x00\x1b\xbc" +
- "\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\\U\x00\x00\x00\x00\x00\"LT\x10\x00\x00" +
- "\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5" +
- "\x16\x90\x00\x00\x00\x00*\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00" +
- "\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x13\xb0\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x1c \x01\b\x00\x00\x0e\x10\x00\r\x00\x00*0\x01\x11\x00\x00" +
- "\x1c \x00\x16LMT\x00WMT\x00CEST\x00CET\x00EEST\x00EET\x00\nCET-1CEST,M3.5.0,M10.5.0/3\nPK" +
- "\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&S\x03\t\xae\x05\x00\x00\xae\x05\x00\x00\b\x00\x00\x00PortugalTZif2\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\x8d\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xff^=\f\x1d\xff\xff\xff\xff\x92掀\xff\xff\xff\xff\x9bKmp\xff\xff\xff\xff\x9b\xfeǀ\xff\xff\xff\xff\x9c\x9c\xedp\xff\xff\xff\xff\x9dɃp\xff" +
- "\xff\xff\xff\x9e\x7frp\xff\xff\xff\xff\x9f\xaa\xb6\xf0\xff\xff\xff\xff\xa0_Tp\xff\xff\xff\xff\xa1\x8b\xeap\xff\xff\xff\xff\xa2A\xd9p\xff\xff\xff\xff\xa3nop\xff\xff\xff\xff\xa4#\f\xf0\xff\xff\xff\xff\xa5" +
- "O\xa2\xf0\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xf4\x8e\xf0\xff\xff\xff\xff\xadɧ\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff" +
- "\xff\xff\xff\xb2p\"p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xbc" +
- "ȷ\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff" +
- "\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xdfp\xff\xff\xff\xff\xc9\x01/p\xff\xff\xff\xff\xc9\xf1 p\xff\xff\xff\xff\xca" +
- "\xe2b\xf0\xff\xff\xff\xff˵R\xf0\xff\xff\xff\xff\xcb\xec\xa3\xe0\xff\xff\xff\xff̀K\xe0\xff\xff\xff\xff\xccܢ\xf0\xff\xff\xff\xff͕4\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xff\xcer\xa2\xe0\xff" +
- "\xff\xff\xff\xceſp\xff\xff\xff\xff\xcfu\x16\xf0\xff\xff\xff\xffϬg\xe0\xff\xff\xff\xff\xd0R\x84\xe0\xff\xff\xff\xffХ\xa1p\xff\xff\xff\xff\xd1T\xf8\xf0\xff\xff\xff\xffьI\xe0\xff\xff\xff\xff\xd2" +
- "2f\xe0\xff\xff\xff\xff҅\x83p\xff\xff\xff\xff\xd3Y\xc4\xf0\xff\xff\xff\xff\xd4I\xb5\xf0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6)\xc2 \xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff\xff\xd8\t\xa4 \xff" +
- "\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xd9\xe9\x86 \xff\xff\xff\xff\xda\xd9w \xff\xff\xff\xff\xdb\xc9h \xff\xff\xff\xffܹY \xff\xff\xff\xffݲ\x84\xa0\xff\xff\xff\xffޢu\xa0\xff\xff\xff\xff\xdf" +
- "\x92f\xa0\xff\xff\xff\xff\xe0\x82W\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe52\f\xa0\xff\xff\xff\xff\xe6!\xfd\xa0\xff" +
- "\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\v\x1a \xff\xff\xff\xff\xe8\xfb\v \xff\xff\xff\xff\xe9\xea\xfc \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed" +
- "\xaa\xc0 \xff\xff\xff\xff\ue6b1 \xff\xff\xff\xff\uf2a2 \xff\xff\xff\xff\xf0z\x93 \xff\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2c\xaf\xa0\xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff\xff\xf4C\x91\xa0\xff" +
- "\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff\xf6#s\xa0\xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8\x03U\xa0\xff\xff\xff\xff\xf8\xf3F\xa0\x00\x00\x00\x00\f\xab*\x00\x00\x00\x00\x00\r\x9b\x1b\x00\x00\x00\x00\x00\x0e" +
- "\x8b\f\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\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#<E\x10\x00" +
- "\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*" +
- "\xc5\a\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00" +
- "\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\x03\x01\x02\x01\x03\x01\x02\x01\x03\x01\x02\x01\x03\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\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\x04\x05\x04\x05\x04\x05\x04\x01\xff\xff\xf7c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\t\x00\x00\x1c \x01\r\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16LMT\x00" +
- "WEST\x00WET\x00WEMT\x00CET\x00CEST\x00\nWET0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xee\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\x03\x00\x00\x00ROCTZif2\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\x10\xff\xff" +
- "\xff\xfft\xce\xf0\x18\xff\xff\xff\xff\xc3UI\x80\xff\xff\xff\xff\xd2TY\x80\xff\xff\xff\xffӋ{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\"\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<" +
- "\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9\xe7\x99\xf0\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xdb\xc8\xcdp\xff\xff\xff\xff\xdc\xe0Y\x80\xff\xff\xff\xffݪ\x00\xf0\xff\xff" +
- "\xff\xff\xders\x00\xff\xff\xff\xffߵdp\xff\xff\xff\xff\xe0|\x85\x00\xff\xff\xff\xffᖗ\xf0\xff\xff\xff\xff\xe2]\xb8\x80\xff\xff\xff\xff\xe3w\xcbp\xff\xff\xff\xff\xe4>\xec\x00\xff\xff\xff\xff\xe50" +
- " p\xff\xff\xff\xff\xe6!q\x00\xff\xff\xff\xff\xe7\x12\xa5p\xff\xff\xff\xff\xe8\x02\xa4\x80\xff\xff\xff\xff\xe8\xf3\xd8\xf0\xff\xff\xff\xff\xe9\xe3\xd8\x00\xff\xff\xff\xff\xea\xd5\fp\xff\xff\xff\xff\xeb\xc5\v\x80\xff\xff" +
- "\xff\xff\xec\xb6?\xf0\xff\xff\xff\xff\xed\xf7\xfc\x00\xff\xff\xff\xff\xee\x98\xc4\xf0\xff\xff\xff\xff\xef\xd9/\x80\xff\xff\xff\xff\xf0y\xf8p\x00\x00\x00\x00\a\xfcV\x00\x00\x00\x00\x00\b\xed\x8ap\x00\x00\x00\x00\t\xdd" +
- "\x89\x80\x00\x00\x00\x00\nν\xf0\x00\x00\x00\x00\x11ۡ\x80\x00\x00\x00\x00\x12T\xddp\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03" +
- "\x01\x03\x01\x03\x01\x03\x01\x00\x00q\xe8\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\b\x00\x00~\x90\x01\fLMT\x00CST\x00JST\x00CDT\x00\nCST-8\nPK\x03\x04\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\x03\x00\x00\x00ROKTZif2\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\x1d\x00\x00\x00\x06\x00\x00" +
- "\x00\x10\xff\xff\xff\xff\x8b\xd7\xf0x\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2C'\xf0\xff\xff\xff\xff\xd7e\x8fp\xff\xff\xff\xff\xd7\xee\x9d`\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd-\xe0\xff\xff" +
- "\xff\xff\xda\u05ca\xf0\xff\xff\xff\xffۭ\x0f\xe0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\u074c\xf1\xe0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe4k\xb7\xf8\xff\xff\xff\xff\xe5\x13\x18h\xff\xff\xff\xff\xe6b" +
- "\x03x\xff\xff\xff\xff\xe7\x11L\xe8\xff\xff\xff\xff\xe8/px\xff\xff\xff\xff\xe8\xe7\xf4h\xff\xff\xff\xff\xea\x0fRx\xff\xff\xff\xff\xea\xc7\xd6h\xff\xff\xff\xff\xeb\xef4x\xff\xff\xff\xff째h\xff\xff" +
- "\xff\xff\xed\xcf\x16x\xff\xff\xff\xff\ue1dah\xff\xff\xff\xff\xf05qx\x00\x00\x00\x00 \xa3`\x90\x00\x00\x00\x00!ng\x90\x00\x00\x00\x00\"\x83B\x90\x00\x00\x00\x00#NI\x90\x01\x02\x04\x03\x04\x03" +
- "\x04\x03\x04\x03\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x04\x03\x04\x03\x04\x00\x00w\b\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\b\x00\x00\x8c\xa0\x01\f\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x01\fL" +
- "MT\x00KST\x00JST\x00KDT\x00\nKST-9\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\t\x00\x00\x00Singapor" +
- "eTZif2\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\b\x00\x00\x00\b\x00\x00\x00 \xff\xff\xff\xff~6S\xa3\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xbagN\x90" +
- "\xff\xff\xff\xff\xc0\n\xe4`\xff\xff\xff\xffʳ\xe5`\xff\xff\xff\xffˑ_\b\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xee\x00\x01\x02\x03\x04\x05\x06\x05\a\x00\x00a]\x00\x00\x00\x00a]\x00\x04" +
- "\x00\x00bp\x00\b\x00\x00g \x01\f\x00\x00g \x00\f\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0730\x00" +
- "+09\x00+08\x00\n<+08>-8\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\aW\x10Ѱ\x04\x00\x00\xb0\x04\x00\x00\x06\x00\x00\x00TurkeyTZif2\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\x00s\x00\x00\x00\x06\x00\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\f\x17`\xff\xff\xff\xff\x9bվ\xd0" +
- "\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xaa((`\xff\xff\xff\xff" +
- "\xaa\xe1\xfd\xd0\xff\xff\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc31P\xff\xff\xff\xffȁ?\xe0\xff\xff\xff\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J\xf5`\xff\xff\xff\xff\xca\u0380P\xff\xff\xff\xff\xcbˮ`" +
- "\xff\xff\xff\xff\xd2k\tP\xff\xff\xff\xffӢ9`\xff\xff\xff\xff\xd4C\x02P\xff\xff\xff\xff\xd5L\r\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff\xff\xff\xd7+\xef\xe0\xff\xff\xff\xff\xd8\t]\xd0\xff\xff\xff\xff" +
- "\xd9\x02\x97`\xff\xff\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff\xdb\xd2\\P\xff\xff\xff\xff\xdc\xd4\xd0`\xff\xff\xff\xffݲ>P\xff\xff\xff\xff\xf1\xf4\xb9`\xff\xff\xff\xff\xf4b\xefP" +
- "\xff\xff\xff\xff\xf5h\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\a9\x9ap\x00\x00\x00\x00\a\xfbu\x00\x00\x00\x00\x00\t\x19|p\x00\x00\x00\x00\t\xd0\xcb\x00\x00\x00\x00\x00" +
- "\n\xf9^p\x00\x00\x00\x00\v\xb1\xfe\x80\x00\x00\x00\x00\f\xd9@p\x00\x00\x00\x00\r\xa4U\x80\x00\x00\x00\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x0f\xf8\x11P\x00\x00\x00\x00\x19\x89\xb0p" +
- "\x00\x00\x00\x00\x19ܰ\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00\x00\x00\x1c\xc6\xef\xf0\x00\x00\x00\x00\x1d\x9b1p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00" +
- "!\\F\xf0\x00\x00\x00\x00\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p" +
- "\x00\x00\x00\x00(\xe5\tp\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x8b\x83\xf0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00" +
- "/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0" +
- "\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00" +
- "=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp" +
- "\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05ɐ\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00" +
- "K\xae\xaa\x10\x00\x00\x00\x00L̿\x90\x00\x00\x00\x00M\x8fݐ\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90" +
- "\x00\x00\x00\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03" +
- "\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02" +
- "\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01" +
- "\b\x00\x00\x1c \x00\r\x00\x00*0\x00\x11\x00\x008@\x01\x15LMT\x00IMT\x00EEST\x00EET\x00+03\x00+04\x00\n<+03>-3\nPK\x03\x04\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00UCTTZif2\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\x00\x01\x00\x00\x00" +
- "\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\t\x00\x00\x00US/AlaskaTZif" +
- "2\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\x00T\x00\x00\x00\n\x00\x00\x00(\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87AH\xff\xff\xff\xffˉ6\xc0\xff\xff\xff\xff\xd2" +
- "#\xf4p\xff\xff\xff\xff\xd2aB0\xff\xff\xff\xff\xfa\xd2G\xa0\xff\xff\xff\xff\xfe\xb8c@\xff\xff\xff\xff\xff\xa8F0\x00\x00\x00\x00\x00\x98E@\x00\x00\x00\x00\x01\x88(0\x00\x00\x00\x00\x02x'@\x00" +
- "\x00\x00\x00\x03qD\xb0\x00\x00\x00\x00\x04aC\xc0\x00\x00\x00\x00\x05Q&\xb0\x00\x00\x00\x00\x06A%\xc0\x00\x00\x00\x00\a1\b\xb0\x00\x00\x00\x00\a\x8d_\xc0\x00\x00\x00\x00\t\x10\xea\xb0\x00\x00\x00\x00\t" +
- "\xad\xdb@\x00\x00\x00\x00\n\xf0̰\x00\x00\x00\x00\v\xe0\xcb\xc0\x00\x00\x00\x00\f\xd9\xe90\x00\x00\x00\x00\r\xc0\xad\xc0\x00\x00\x00\x00\x0e\xb9\xcb0\x00\x00\x00\x00\x0f\xa9\xca@\x00\x00\x00\x00\x10\x99\xad0\x00" +
- "\x00\x00\x00\x11\x89\xac@\x00\x00\x00\x00\x12y\x8f0\x00\x00\x00\x00\x13i\x8e@\x00\x00\x00\x00\x14Yq0\x00\x00\x00\x00\x15Ip@\x00\x00\x00\x00\x169S0\x00\x00\x00\x00\x17)R@\x00\x00\x00\x00\x18" +
- "\"o\xb0\x00\x00\x00\x00\x19\t4@\x00\x00\x00\x00\x1a\x02Q\xb0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\a\xa0\x00" +
- "\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81ˠ\x00\x00\x00\x00\"V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%" +
- "J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\n\x8e \x00\x00\x00\x00)\xdeݰ\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00" +
- "\x00\x00\x00,ӌ\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003" +
- "G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\aF0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00" +
- "\x00\x00\x00:\xc7\n0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\b\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A" +
- "\x84\xb7\xa0\x00\x00\x00\x00BO̰\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" +
- "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t" +
- "\b\t\b\t\b\t\b\x00\x00\xc4\xf8\x00\x00\xff\xffsx\x00\x00\xff\xffs`\x00\x04\xff\xff\x81p\x01\b\xff\xff\x81p\x01\f\xff\xffs`\x00\x10\xff\xff\x81p\x01\x15\xff\xff\x81p\x00\x1a\xff\xff\x8f\x80\x01" +
- "\x1e\xff\xff\x81p\x00#LMT\x00AST\x00AWT\x00APT\x00AHST\x00AHDT\x00YST\x00AKDT\x00AKST\x00\nAKST9AKDT,M3" +
- ".2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\v\x00\x00\x00US/AleutianTZif2\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\x00T\x00\x00\x00\n\x00\x00\x00!\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87Z^\xff\xff\xff\xffˉD\xd0\xff\xff\xff\xff\xd2#\xf4" +
- "p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P\x00\x00\x00" +
- "\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\a1\x16\xc0\x00\x00\x00\x00\a\x8dm\xd0\x00\x00\x00\x00\t\x10\xf8\xc0\x00\x00\x00\x00\t\xad\xe9" +
- "P\x00\x00\x00\x00\n\xf0\xda\xc0\x00\x00\x00\x00\v\xe0\xd9\xd0\x00\x00\x00\x00\f\xd9\xf7@\x00\x00\x00\x00\r\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@\x00\x00\x00" +
- "\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00\x18\"}" +
- "\xc0\x00\x00\x00\x00\x19\tBP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\" \x00\x00\x00\x00\x1a\xf2P\xc0\x00\x00\x00\x00\x1b\xe23\xb0\x00\x00\x00\x00\x1c\xd22\xc0\x00\x00\x00\x00\x1d\xc2\x15\xb0\x00\x00\x00" +
- "\x00\x1e\xb2\x14\xc0\x00\x00\x00\x00\x1f\xa1\xf7\xb0\x00\x00\x00\x00 vG@\x00\x00\x00\x00!\x81ٰ\x00\x00\x00\x00\"V)@\x00\x00\x00\x00#j\xf60\x00\x00\x00\x00$6\v@\x00\x00\x00\x00%J\xd8" +
- "0\x00\x00\x00\x00&\x15\xed@\x00\x00\x00\x00'*\xba0\x00\x00\x00\x00'\xff\t\xc0\x00\x00\x00\x00)\n\x9c0\x00\x00\x00\x00)\xde\xeb\xc0\x00\x00\x00\x00*\xea~0\x00\x00\x00\x00+\xbe\xcd\xc0\x00\x00\x00" +
- "\x00,Ӛ\xb0\x00\x00\x00\x00-\x9e\xaf\xc0\x00\x00\x00\x00.\xb3|\xb0\x00\x00\x00\x00/~\x91\xc0\x00\x00\x00\x000\x93^\xb0\x00\x00\x00\x001g\xae@\x00\x00\x00\x002s@\xb0\x00\x00\x00\x003G\x90" +
- "@\x00\x00\x00\x004S\"\xb0\x00\x00\x00\x005'r@\x00\x00\x00\x0063\x04\xb0\x00\x00\x00\x007\aT@\x00\x00\x00\x008\x1c!0\x00\x00\x00\x008\xe76@\x00\x00\x00\x009\xfc\x030\x00\x00\x00" +
- "\x00:\xc7\x18@\x00\x00\x00\x00;\xdb\xe50\x00\x00\x00\x00<\xb04\xc0\x00\x00\x00\x00=\xbb\xc70\x00\x00\x00\x00>\x90\x16\xc0\x00\x00\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84\xc5" +
- "\xb0\x00\x00\x00\x00BO\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06" +
- "\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\a\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t\b\t" +
- "\b\t\b\t\b\x00\x00\xab\xe2\x00\x00\xff\xffZb\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\b\xff\xffs`\x01\f\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xffs`\x00\x18\xff\xff\x81p\x01\x1d\xff" +
- "\xffs`\x00\x19LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00AHST\x00HDT\x00\nHST10HDT,M3.2.0,M11.1" +
- ".0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\n\x00\x00\x00US/ArizonaTZif2\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\v\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff" +
- "\xff\xffˉ\f\x90\xff\xff\xff\xff\xcf\x17\xdf\x1c\xff\xff\xff\xffϏ\xe5\xac\xff\xff\xff\xffЁ\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96" +
- "\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\fLMT\x00MDT\x00MST\x00MWT\x00\nMST7\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9bܩ" +
- "=\xda\x06\x00\x00\xda\x06\x00\x00\n\x00\x00\x00US/CentralTZif2\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\xaf\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff" +
- "\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa2\xcbt\x00\xff\xff\xff\xff\xa3\x83\xf7\xf0\xff\xff\xff\xff\xa4E" +
- "Ҁ\xff\xff\xff\xff\xa5c\xd9\xf0\xff\xff\xff\xff\xa6S\xd9\x00\xff\xff\xff\xff\xa7\x15\x97p\xff\xff\xff\xff\xa83\xbb\x00\xff\xff\xff\xff\xa8\xfe\xb3\xf0\xff\xff\xff\xff\xaa\x13\x9d\x00\xff\xff\xff\xff\xaaޕ\xf0\xff\xff" +
- "\xff\xff\xab\xf3\x7f\x00\xff\xff\xff\xff\xac\xbew\xf0\xff\xff\xff\xff\xad\xd3a\x00\xff\xff\xff\xff\xae\x9eY\xf0\xff\xff\xff\xff\xaf\xb3C\x00\xff\xff\xff\xff\xb0~;\xf0\xff\xff\xff\xff\xb1\x9c_\x80\xff\xff\xff\xff\xb2g" +
- "Xp\xff\xff\xff\xff\xb3|A\x80\xff\xff\xff\xff\xb4G:p\xff\xff\xff\xff\xb5\\#\x80\xff\xff\xff\xff\xb6'\x1cp\xff\xff\xff\xff\xb7<\x05\x80\xff\xff\xff\xff\xb8\x06\xfep\xff\xff\xff\xff\xb9\x1b\xe7\x80\xff\xff" +
- "\xff\xff\xb9\xe6\xe0p\xff\xff\xff\xff\xbb\x05\x04\x00\xff\xff\xff\xff\xbb\xc6\xc2p\xff\xff\xff\xff\xbc\xe4\xe6\x00\xff\xff\xff\xff\xbd\xaf\xde\xf0\xff\xff\xff\xff\xbe\xc4\xc8\x00\xff\xff\xff\xff\xbf\x8f\xc0\xf0\xff\xff\xff\xff\xc0Z" +
- "\xd6\x00\xff\xff\xff\xff\xc1\xb0<p\xff\xff\xff\xff\u0084\x8c\x00\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xff\xc4dn\x00\xff\xff\xff\xff\xc5/f\xf0\xff\xff\xff\xff\xc6M\x8a\x80\xff\xff\xff\xff\xc7\x0fH\xf0\xff\xff" +
- "\xff\xff\xc8-l\x80\xff\xff\xff\xff\xc8\xf8ep\xff\xff\xff\xff\xca\rN\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u" +
- "\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff" +
- "\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1i" +
- "Tp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff" +
- "\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf" +
- "\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xf6?ip\xff\xff" +
- "\xff\xff\xf7/h\x80\xff\xff\xff\xff\xf8(\x85\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\bg\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8" +
- "+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00" +
- "\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0" +
- "\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00" +
- "\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02" +
- "\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00" +
- "\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfe" +
- "р\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00)\u07b3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00" +
- "\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\bp\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062" +
- "\xccp\x00\x00\x00\x007\a\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;۬\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00" +
- "\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8fހ\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/" +
- "\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\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\x03\x02\x01\x02\x01" +
- "\x02\x01\x02\x01\x02\x01\x02\x04\x05\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02" +
- "\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xad\xd4\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x00\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00CDT\x00CST" +
- "\x00EST\x00CWT\x00CPT\x00\nCST6CDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13" +
- "\x02\x00\x00\x0f\x00\x00\x00US/East-IndianaTZif2\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\a\x00\x00\x00\x1c\xff\xff\xff" +
- "\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcaW\"\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xffˈ\xfe" +
- "\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff" +
- "\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xffݩ\x90p\xff\xff\xff\xff\u07bey" +
- "\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff" +
- "\xff\xea\a\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8" +
- "\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9" +
- "\xb0\x01\f\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\nEST5EDT,M3" +
- ".2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\n\x00\x00\x00US/EasternTZif2\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\xaf\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x03\xf0\x90\xff\xff\xff\xff\x9e\xa6\x1ep\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x86\x00p" +
- "\xff\xff\xff\xff\xa1\x9a\xcd`\xff\xff\xff\xff\xa2e\xe2p\xff\xff\xff\xff\xa3\x83\xe9\xe0\xff\xff\xff\xff\xa4j\xaep\xff\xff\xff\xff\xa55\xa7`\xff\xff\xff\xff\xa6S\xca\xf0\xff\xff\xff\xff\xa7\x15\x89`\xff\xff\xff\xff" +
- "\xa83\xac\xf0\xff\xff\xff\xff\xa8\xfe\xa5\xe0\xff\xff\xff\xff\xaa\x13\x8e\xf0\xff\xff\xff\xff\xaaއ\xe0\xff\xff\xff\xff\xab\xf3p\xf0\xff\xff\xff\xff\xac\xbei\xe0\xff\xff\xff\xff\xad\xd3R\xf0\xff\xff\xff\xff\xae\x9eK\xe0" +
- "\xff\xff\xff\xff\xaf\xb34\xf0\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\\\x15p\xff\xff\xff\xff" +
- "\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9\x1b\xd9p\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbbƴ`\xff\xff\xff\xff\xbc\xe4\xd7\xf0" +
- "\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbeĹ\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\u0084}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff" +
- "\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xc8\xf8W`\xff\xff\xff\xff\xca\r@p\xff\xff\xff\xff\xca\xd89`" +
- "\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xc6\xf0\xff\xff\xff\xff\xd6 \xbf\xe0\xff\xff\xff\xff" +
- "\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xd9\x15\x8a\xf0\xff\xff\xff\xff\xd9\xe0\x83\xe0\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdb\xc0e\xe0\xff\xff\xff\xff\xdcމp\xff\xff\xff\xffݩ\x82`" +
- "\xff\xff\xff\xff\u07bekp\xff\xff\xff\xff߉d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff" +
- "\xe5W.\xe0\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe77\x10\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0" +
- "\xff\xff\xff\xff\xecֶ\xe0\xff\xff\xff\xff\xedƵ\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff" +
- "\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\bY\xe0" +
- "\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00" +
- "\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`\x00\x00\x00\x00\a\x8d\x19p" +
- "\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\t\xad\x94\xf0\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00" +
- "\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\f\xe0" +
- "\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00" +
- "\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0" +
- "\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00" +
- "+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`" +
- "\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x00" +
- "9\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p" +
- "\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xba\x9e\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00" +
- "\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03" +
- "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\t\x00\x00\x00US/HawaiiTZif2\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\a\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xffˉ=\xc8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aI8\xff" +
- "\xff\xff\xffՍsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\b\xff\xffzh\x01\f\xff\xffzh\x01\x10\xff\xffs`\x00\x04LMT\x00HST\x00HD" +
- "T\x00HWT\x00HPT\x00\nHST10\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x11\x00\x00\x00US/Indiana-St" +
- "arkeTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f" +
- "\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xffˈ\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\t\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff" +
- "\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdcޗ\x80\xff\xff\xff\xff\xdd" +
- "\xa9\x90p\xff\xff\xff\xff\u07bey\x80\xff\xff\xff\xff߉rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff" +
- "\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\a\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb" +
- "\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\u0080\xff\xff\xff\xff\xf4_\x87p\xff" +
- "\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\r\xf0\x00\x00\x00\x00\x00\x98\r\x00\x00\x00\x00\x00\x01" +
- "\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\fp\x00\x00\x00\x00\x04a\v\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\a0\xd0p\x00\x00\x00\x00\a\x8d'\x80\x00" +
- "\x00\x00\x00\t\x10\xb2p\x00\x00\x00\x00\t\xad\xa3\x00\x00\x00\x00\x00\n\xf0\x94p\x00\x00\x00\x00\v\xe0\x93\x80\x00\x00\x00\x00\fٰ\xf0\x00\x00\x00\x00\r\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f" +
- "\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00" +
- "\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\"7p\x00\x00\x00\x00\x19\b\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d" +
- "\xc1\xddp\x00\x00\x00\x00\x1e\xb1܀\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\"U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00" +
- "\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfeр\x00\x00\x00\x00)\nc\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E" +
- "\xf3\xb7\x00\x02\x01\x02\x01\x02\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\x05\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\x05\x01\x02\x01\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\b\xff\xff\xb9\xb0\x01\f" +
- "\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\nCST6CDT,M3.2.0,M11.1.0\n" +
- "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\v\x00\x00\x00US/MichiganTZif2\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\x00P\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x85\xbd\"[\xff\xff\xff\xff\x99<\x94\x00\xff\xff\xff\xffˈ\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff" +
- "\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xfb3\x90\x8c\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\a0\xc2`" +
- "\x00\x00\x00\x00\a\x8d\x19p\x00\x00\x00\x00\t\x10\xa4`\x00\x00\x00\x00\n\x00\xa3p\x00\x00\x00\x00\n\xf0\x86`\x00\x00\x00\x00\v\xe0\x85p\x00\x00\x00\x00\f٢\xe0\x00\x00\x00\x00\r\xc0gp\x00\x00\x00\x00" +
- "\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0" +
- "\x00\x00\x00\x00\x169\f\xe0\x00\x00\x00\x00\x17)\v\xf0\x00\x00\x00\x00\x18\")`\x00\x00\x00\x00\x19\b\xed\xf0\x00\x00\x00\x00\x1a\x02\v`\x00\x00\x00\x00\x1a\xf2\np\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00" +
- "\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\"U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0" +
- "\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\nU\xe0\x00\x00\x00\x00)ޥp\x00\x00\x00\x00" +
- "*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0" +
- "\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\a\r\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x00" +
- "8\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;۞\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0" +
- "\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x01\x02\x03\x04" +
- "\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05" +
- "\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\xff\xff\xb2%\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\b\xff\xff\xc7\xc0\x01\f\xff\xff\xc7\xc0\x01\x10\xff\xff\xc7\xc0\x01\x14LMT\x00CST\x00" +
- "EST\x00EWT\x00EPT\x00EDT\x00\nEST5EDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04" +
- "\x00\x00\x12\x04\x00\x00\v\x00\x00\x00US/MountainTZif2\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\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff" +
- "^\x04\f\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\a\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90" +
- "\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xffˉ\f\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff" +
- "\xfa\bv\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10" +
- "\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\a0ހ\x00\x00\x00\x00" +
- "\a\x8d5\x90\x00\x00\x00\x00\t\x10\xc0\x80\x00\x00\x00\x00\t\xad\xb1\x10\x00\x00\x00\x00\n\xf0\xa2\x80\x00\x00\x00\x00\vࡐ\x00\x00\x00\x00\fٿ\x00\x00\x00\x00\x00\r\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00" +
- "\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00" +
- "\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\"E\x80\x00\x00\x00\x00\x19\t\n\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\t\x80\x00\x00\x00\x00\x1c\xd2\b\x90" +
- "\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1̀\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\"U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00" +
- "$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfeߐ\x00\x00\x00\x00)\nr\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00" +
- "\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x00" +
- "2s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062ڀ\x00\x00\x00\x007\a*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\f\x10" +
- "\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;ۻ\x00\x00\x00\x00\x00<\xb0\n\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00" +
- "@oΐ\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01" +
- "\x02\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\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\xff\xff\x9d\x94\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\b\xff\xff\xab\xa0\x01\f\xff\xff\xab\xa0\x01\x10L" +
- "MT\x00MDT\x00MST\x00MWT\x00MPT\x00\nMST7MDT,M3.2.0,M11.1.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\"\x12" +
- "\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\n\x00\x00\x00US/PacificTZif2\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\x05\x00\x00\x00\x14\xff\xff" +
- "\xff\xff^\x04\x1a\xc0\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xffˉ\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a" +
- "&\x10\xff\xff\xff\xff\xd6\xfet\\\xff\xff\xff\xff\u0600\xad\x90\xff\xff\xff\xff\xda\xfeÐ\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdcޥ\x90\xff\xff\xff\xffݩ\xac\x90\xff\xff\xff\xff\u07be\x87\x90\xff\xff" +
- "\xff\xff߉\x8e\x90\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6G" +
- "J\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\a\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff" +
- "\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8fА\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xb2\x90\xff\xff\xff\xff\xf4_" +
- "\xa3\x90\xff\xff\xff\xff\xf5O\x94\x90\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\b\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff" +
- "\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\f\x10\x00\x00\x00\x00\x02x" +
- "\v \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\n\x90\x00\x00\x00\x00\x06A\t\xa0\x00\x00\x00\x00\a0\xec\x90\x00\x00\x00\x00\a\x8dC\xa0\x00\x00\x00\x00\t\x10ΐ\x00\x00" +
- "\x00\x00\t\xad\xbf \x00\x00\x00\x00\n\xf0\xb0\x90\x00\x00\x00\x00\v\u0be0\x00\x00\x00\x00\f\xd9\xcd\x10\x00\x00\x00\x00\r\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99" +
- "\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00" +
- "\x00\x00\x18\"S\x90\x00\x00\x00\x00\x19\t\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1" +
- "\xf8\xa0\x00\x00\x00\x00\x1f\xa1ې\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\"V\r \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00" +
- "\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\n\x80\x10\x00\x00\x00\x00)\xdeϠ\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3" +
- "~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00" +
- "\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\a8 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6" +
- "\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@oܠ\x00\x00\x00\x00A\x84\xa9\x90\x00\x00" +
- "\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x91&\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00" +
- "\b\xff\xff\x9d\x90\x01\f\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00PWT\x00PPT\x00\nPST8PDT,M3.2.0,M11.1.0\nPK\x03" +
- "\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\b\x00\x00\x00US/SamoaTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\b\xff\xff\xff\xffn=\xc8\b\xff\xff\xff\xff\x91\x05\xfb\b\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\nSST11" +
- "\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00UTCTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\t\x00\x00\x00Unive" +
- "rsalTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x03\x04\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\x04\x00\x00\x00W-SUTZif2\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\x00N\x00\x00\x00\v" +
- "\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc0\xc7\xff\xff\xff\xff\x9b_\x1e\xc7\xff\xff\xff\xff\x9d>\xf2y\xff\xff\xff\xff\x9e*\xee\xf9\xff\xff\xff\xff\x9e\xf79i\xff\xff\xff\xff\x9f\x84W\xf9\xff\xff\xff\xff\xa0\xd8l\xe9" +
- "\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xa1<\xa6@\xff\xff\xff\xff\xa4\x10m\xc0\xff\xff\xff\xff\xa4=2\xb0\xff\xff\xff\xff\xa5\x15h\xb0\xff\xff\xff\xff\xa5=\x03\xc0\xff\xff\xff\xff\xa7\x1eEP\xff\xff\xff\xff" +
- "\xb5\xa4\x19`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\b\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a̓\xd0" +
- "\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\\F\xf0\x00\x00\x00\x00" +
- "\"L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\n\xf0\x00\x00\x00\x00&\v\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80" +
- "\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00" +
- "/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0" +
- "\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00" +
- "=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\ap\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp" +
- "\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00IΫ\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00" +
- "K\xae\x8d\xf0\x00\x00\x00\x00Ḷp\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x01\x03\x02\x03\x04\x02\x04\x05\x06\x05\a\x05\x06\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05" +
- "\x06\x05\x06\t\b\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\n\x06\x00\x00#9\x00\x00\x00\x00#9\x00\x04\x00\x00" +
- "1\x87\x01\b\x00\x00#w\x00\x04\x00\x00?\x97\x01\f\x00\x008@\x01\x11\x00\x00*0\x00\x15\x00\x00FP\x01\x19\x00\x00\x1c \x00\x1d\x00\x00*0\x01!\x00\x008@\x00\x15LMT\x00MMT\x00" +
- "MST\x00MDST\x00MSD\x00MSK\x00+05\x00EET\x00EEST\x00\nMSK-3\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x91B\xc0\xee\x01\x00\x00\xee" +
- "\x01\x00\x00\x03\x00\x00\x00WETTZif2\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\x02\x00\x00\x00\t\x00\x00\x00\x00\r\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a" +
- "\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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#<E\x10\x00\x00\x00" +
- "\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\f\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\a" +
- "\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94ڐ\x00\x00\x00\x00.\x84ː\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01" +
- "\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x05\x00\x00\x0e\x10\x01\x00WEST\x00WET\x00\nWE" +
- "T0WEST,M3.5.0/1,M10.5.0\nPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x04\x00\x00\x00ZuluTZ" +
- "if2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\nUTC0\nPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Africa/AbidjanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\x00\x00\x00Africa/AccraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x01\x00\x00Africa/Addis_AbabaPK\x01\x02\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00Ê\x0e\xc0\xd6\x01\x00\x00\xd6\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\x02\x00\x00Africa/AlgiersPK\x01\x02\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K\x04\x00\x00Africa/AsmaraPK\x01\x02\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x05\x00\x00Africa/AsmeraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x06\x00\x00Africa/BamakoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\x06\x00\x00Africa/BanguiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\a\x00\x00Africa/BanjulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xca>\xd5\xe0\x95\x00\x00\x00\x95\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\b\x00\x00Africa/BissauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\t\x00\x00Africa/BlantyrePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\t\x00\x00Africa/BrazzavillePK\x01\x02\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\n\x00\x00Africa/BujumburaPK\x01\x02\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\xa5#)\x16\x1d\x05\x00\x00\x1d\x05\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\v\x00\x00Africa/CairoPK\x01\x02\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x001B\xb0;\x7f\a\x00\x00\x7f\a\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x10\x00\x00Africa/CasablancaPK\x01\x02\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x1b\xeb\xdd2\x02\x00\x002\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x18\x00\x00Africa/CeutaPK\x01\x02\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\x1a\x00\x00Africa/ConakryPK\x01\x02\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\x1b\x00\x00Africa/DakarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x1c\x00\x00Africa/Dar_es_SalaamPK\x01\x02\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x1c\x00\x00Africa/DjiboutiPK\x01\x02" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\x1d\x00\x00Africa/DoualaPK\x01\x02\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xd3\xc6g&\a\x00\x00&\a\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc4\x1e\x00\x00Africa/El_AaiunPK\x01\x02" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17&\x00\x00Africa/FreetownPK\x01" +
- "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc6&\x00\x00Africa/GaboronePK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00v'\x00\x00Africa/HararePK\x01" +
- "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$(\x00\x00Africa/Johannesbu" +
- "rgPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xcf\x10n\xca\x01\x00\x00\xca\x01\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13)\x00\x00Africa/JubaP" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06+\x00\x00Africa/KampalaP" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xadD\xef\xca\x01\x00\x00\xca\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1+\x00\x00Africa/Khartoum" +
- "PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8-\x00\x00Africa/KigaliP" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96.\x00\x00Africa/Kinshasa" +
- "PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w/\x00\x00Africa/LagosPK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U0\x00\x00Africa/Librevill" +
- "ePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0081\x00\x00Africa/LomePK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe31\x00\x00Africa/LuandaPK\x01" +
- "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc22\x00\x00Africa/Lubumbashi" +
- "PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t3\x00\x00Africa/LusakaP" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\"4\x00\x00Africa/MalaboPK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x015\x00\x00Africa/MaputoPK\x01" +
- "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf5\x00\x00Africa/MaseruPK\x01\x02" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\fTξ\x00\x00\x00\xbe\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x986\x00\x00Africa/MbabanePK\x01\x02" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x827\x00\x00Africa/MogadishuPK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\x99rU\xa4\x00\x00\x00\xa4\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o8\x00\x00Africa/MonroviaP" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@9\x00\x00Africa/NairobiP" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x81\t\x03\xa0\x00\x00\x00\xa0\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+:\x00\x00Africa/Ndjamena" +
- "PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8:\x00\x00Africa/NiameyP" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7;\x00\x00Africa/Nouakcho" +
- "ttPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88<\x00\x00Africa/Ouaga" +
- "dougouPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:=\x00\x00Africa/P" +
- "orto-NovoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\n\x8a\x84\xad\x00\x00\x00\xad\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d>\x00\x00Afric" +
- "a/Sao_TomePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7>\x00\x00Afri" +
- "ca/TimbuktuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa6?\x00\x00Afr" +
- "ica/TripoliPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\xf4\x94\v\xc1\x01\x00\x00\xc1\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81A\x00\x00Afr" +
- "ica/TunisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m)\xb8P~\x02\x00\x00~\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00lC\x00\x00Afric" +
- "a/WindhoekPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17F\x00\x00Amer" +
- "ica/AdakPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\nJ\x00\x00Americ" +
- "a/AnchoragePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\nN\x00\x00Ame" +
- "rica/AnguillaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9N\x00\x00A" +
- "merica/AntiguaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x01V\rP\x02\x00\x00P\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7O\x00\x00" +
- "America/AraguainaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F" +
- "R\x00\x00America/Argentina/Buenos_AiresPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00" +
- "\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FU\x00\x00America/Argentina/CatamarcaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00CX\x00\x00America/Argentina/ComodRivad" +
- "aviaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E[\x00\x00America/Ar" +
- "gentina/CordobaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00utZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@^\x00" +
- "\x00America/Argentina/JujuyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m\aD\x0e\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00'a\x00\x00America/Argentina/La_RiojaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ŒZ\x8c\xc4\x02\x00\x00" +
- "\xc4\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,d\x00\x00America/Argentina/MendozaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x8ep\xb4c\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'g\x00\x00America/Argentina/Rio_Galle" +
- "gosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t*\x9b!\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'j\x00\x00America/Arg" +
- "entina/SaltaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfcz=\xe1\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0em\x00\x00Am" +
- "erica/Argentina/San_JuanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x80\xb9\\\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x13p\x00\x00America/Argentina/San_LuisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd8֭\xd6\x02\x00\x00" +
- "\xd6\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18s\x00\x00America/Argentina/TucumanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x8b}\xb6\x1e\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%v\x00\x00America/Argentina/UshuaiaPK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 y\x00\x00America/ArubaPK\x01" +
- "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xa9y\x9at\x03\x00\x00t\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfcy\x00\x00America/AsuncionP" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9e}\x00\x00America/Atikoka" +
- "nPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a~\x00\x00America/AtkaP" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00OKjǪ\x02\x00\x00\xaa\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x82\x00\x00America/BahiaPK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\x0e\x01n\xd8\x02\x00\x00\xd8\x02\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x85\x00\x00America/Bahia_Ba" +
- "nderasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l=\xad\xbe\x16\x01\x00\x00\x16\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x88\x00\x00America/" +
- "BarbadosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85-\xb9\xf8\x8a\x01\x00\x00\x8a\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00y\x89\x00\x00Americ" +
- "a/BelemPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89غ\xee\x15\x04\x00\x00\x15\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\x8b\x00\x00America" +
- "/BelizePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\x8f\x00\x00America" +
- "/Blanc-SablonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8Dz\x97\xae\x01\x00\x00\xae\x01\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x90\x00\x00A" +
- "merica/Boa_VistaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,g\xec\xec\xb3\x00\x00\x00\xb3\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/\x92" +
- "\x00\x00America/BogotaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\xbe\x1a>\xe7\x03\x00\x00\xe7\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x93" +
- "\x00\x00America/BoisePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x97\x00" +
- "\x00America/Buenos_AiresPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\xba\xb2\x94s\x03\x00\x00s\x03\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x16\x9a\x00\x00America/Cambridge_BayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xfbn۸\x03\x00\x00\xb8\x03\x00\x00\x14\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x9d\x00\x00America/Campo_GrandePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x04\xde\xdd\x11\x02\x00\x00\x11\x02" +
- "\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa6\xa1\x00\x00America/CancunPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x8e\xee\x13\xbe\x00\x00\x00\xbe\x00" +
- "\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xa3\x00\x00America/CaracasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4" +
- "\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Τ\x00\x00America/CatamarcaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1'\a\xbd\x97\x00" +
- "\x00\x00\x97\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\xa7\x00\x00America/CayennePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ծ\xe7#\x95" +
- "\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\xa8\x00\x00America/CaymanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9bܩ=\xda" +
- "\x06\x00\x00\xda\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F\xa9\x00\x00America/ChicagoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x111\x04q" +
- "\xb3\x02\x00\x00\xb3\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M\xb0\x00\x00America/ChihuahuaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad" +
- "\xf2L\x06\xce\x02\x00\x00\xce\x02\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/\xb3\x00\x00America/Ciudad_JuarezPK\x01\x02\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00Ծ\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\xb6\x00\x00America/Coral_HarbourPK\x01" +
- "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\xb6\x00\x00America/CordobaPK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1݂x\xe8\x00\x00\x00\xe8\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\xb9\x00\x00America/Costa_Ri" +
- "caPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xbb\x00\x00America/Cres" +
- "tonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f$*\xa0\xa6\x03\x00\x00\xa6\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xbc\x00\x00America/Cui" +
- "abaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xbf\x00\x00America/Cur" +
- "acaoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xc2\rx\xbf\x01\x00\x00\xbf\x01\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\xc0\x00\x00America/Da" +
- "nmarkshavnPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xe6\xf5J\x05\x04\x00\x00\x05\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xc2\x00\x00Amer" +
- "ica/DawsonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x10`ȫ\x02\x00\x00\xab\x02\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xc6\x00\x00Amer" +
- "ica/Dawson_CreekPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xc9" +
- "\x00\x00America/DenverPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\xce" +
- "\x00\x00America/DetroitPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb" +
- "\xd1\x00\x00America/DominicaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\a\a\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x9a\xd2\x00\x00America/EdmontonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\xb0\xeau\xb4\x01\x00\x00\xb4\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x92\xd6\x00\x00America/EirunepePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea$\xc1\xbf\xb0\x00\x00\x00\xb0\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00t\xd8\x00\x00America/El_SalvadorPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\xd9\x00\x00America/EnsenadaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6@\rm\xa8\x05\x00\x00\xa8\x05\x00\x00\x13\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\xdd\x00\x00America/Fort_NelsonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13" +
- "\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\xe3\x00\x00America/Fort_WaynePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x11Z\xde\xe4" +
- "\x01\x00\x00\xe4\x01\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\xe5\x00\x00America/FortalezaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M\x94" +
- "\xc7Kp\x03\x00\x00p\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3\xe7\x00\x00America/Glace_BayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x95'O\xce\xc5\x03\x00\x00\xc5\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xeb\x00\x00America/GodthabPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x1d\xf7\a ,\x06\x00\x00,\x06\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\xef\x00\x00America/Goose_BayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\xe3\xc9I\xd0U\x03\x00\x00U\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\xf5\x00\x00America/Grand_TurkPK\x01\x02\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\xf9\x00\x00America/GrenadaPK\x01\x02\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xfa\x00\x00America/GuadeloupePK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x8a\x83S\xd4\x00\x00\x00\xd4\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xfa\x00\x00America/Guatemal" +
- "aPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xc3v\xe3\xb3\x00\x00\x00\xb3\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xfb\x00\x00America/Guaya" +
- "quilPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x05\xf3\x89\xb5\x00\x00\x00\xb5\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\xfc\x00\x00America/Gu" +
- "yanaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9\xfd\x00\x00America/Ha" +
- "lifaxPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x04\x01\x00America/H" +
- "avanaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4MS\x99\x1e\x01\x00\x00\x1e\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7\b\x01\x00America/H" +
- "ermosilloPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\n\x01\x00Ameri" +
- "ca/Indiana/IndianapolisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x82\f\x01\x00America/Indiana/KnoxPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M/U\x9f7\x02\x00\x007\x02\x00\x00\x17\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x10\x01\x00America/Indiana/MarengoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xd8N\x8c\xab\x02" +
- "\x00\x00\xab\x02\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x13\x01\x00America/Indiana/PetersburgPK\x01\x02\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00صK\xa6\n\x02\x00\x00\n\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb\x15\x01\x00America/Indiana/Tell_Cit" +
- "yPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x17\x89}q\x01\x00\x00q\x01\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x18\x01\x00America/India" +
- "na/VevayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\r\xedsp.\x02\x00\x00.\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x19\x01\x00Americ" +
- "a/Indiana/VincennesPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K-E\xfad\x02\x00\x00d\x02\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00E\x1c\x01\x00America/Indiana/WinamacPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x14\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\x1e\x01\x00America/IndianapolisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ʼ\to1\x03\x00\x001\x03" +
- "\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#!\x01\x00America/InuvikPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Š\xd6\x05W\x03\x00\x00W\x03" +
- "\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80$\x01\x00America/IqaluitPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%J\xd5\xebS\x01\x00\x00S" +
- "\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04(\x01\x00America/JamaicaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00utZ\x1a\xb2\x02\x00\x00" +
- "\xb2\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84)\x01\x00America/JujuyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xc9\x1c\xd4\xc6\x03\x00\x00\xc6" +
- "\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a,\x01\x00America/JuneauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda" +
- "\x04\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S0\x01\x00America/Kentucky/LouisvillePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x03\x1a|J\xcc\x03\x00\x00\xcc\x03\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f5\x01\x00America/Kentucky/Monticell" +
- "oPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k9\x01\x00America/Knox_" +
- "INPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90=\x01\x00America/Kral" +
- "endijkPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad`\x12\xe9\xaa\x00\x00\x00\xaa\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q>\x01\x00America/" +
- "La_PazPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe7\xa1\x87\x1b\x01\x00\x00\x1b\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G?\x01\x00America/" +
- "LimaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\"\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c@\x01\x00America/Lo" +
- "s_AngelesPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcbE\x01\x00Ameri" +
- "ca/LouisvillePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5J\x01\x00A" +
- "merica/Lower_PrincesPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00挋\x92\xf6\x01\x00\x00\xf6\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xb9K\x01\x00America/MaceioPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5s\xb3\\'\x01\x00\x00'\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xdbM\x01\x00America/ManaguaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00/O\x01\x00America/ManausPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\xf7P\x01\x00America/MarigotPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x17jҲ\x00\x00\x00\xb2\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xd5Q\x01\x00America/MartiniquePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00((i\xe4\xb5\x01\x00\x00\xb5\x01\x00\x00\x11\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\xb7R\x01\x00America/MatamorosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xad=\x98\xce\x02\x00\x00\xce\x02\x00\x00\x10\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9bT\x01\x00America/MazatlanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ŒZ\x8c\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97W\x01\x00America/MendozaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008O:\xbf\x95\x03\x00\x00\x95\x03\x00\x00" +
- "\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88Z\x01\x00America/MenomineePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xbd\x809\x8e\x02\x00\x00\x8e" +
- "\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L^\x01\x00America/MeridaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\x81\xbfyS\x02\x00\x00S" +
- "\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06a\x01\x00America/MetlakatlaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\b\x89\x8c\x05" +
- "\x03\x00\x00\x05\x03\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89c\x01\x00America/Mexico_CityPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\xd7\b\\\xc6&\x02\x00\x00&\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbff\x01\x00America/MiquelonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00.\xf9\xc0\x1e\xd5\x05\x00\x00\xd5\x05\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13i\x01\x00America/MonctonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00L+\xe3u\x84\x02\x00\x00\x84\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15o\x01\x00America/MonterreyPK\x01\x02\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\xc0\x98\x00\b\xc9\x03\x00\x00\xc9\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8q\x01\x00America/MontevideoPK\x01\x02\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1u\x01\x00America/MontrealPK\x01\x02" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4|\x01\x00America/Montserrat" +
- "PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85}\x01\x00America/Nassau" +
- "PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f\x84\x01\x00America/New_Yo" +
- "rkPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x8b\x01\x00America/Nipi" +
- "gonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\xab\xd5\xf9\xcf\x03\x00\x00\xcf\x03\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F\x92\x01\x00America/Nom" +
- "ePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x96\x01\x00America/Noron" +
- "haPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7.\xb6*\x13\x04\x00\x00\x13\x04\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x98\x01\x00America/Nort" +
- "h_Dakota/BeulahPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\xeam\xef\xde\x03\x00\x00\xde\x03\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\x9c\x01" +
- "\x00America/North_Dakota/CenterPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x1b\x8b(\xde\x03\x00\x00\xde\x03\x00\x00\x1e\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3\xa0\x01\x00America/North_Dakota/New_SalemPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x95'O\xce\xc5\x03\x00\x00\xc5\x03\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ͤ\x01\x00America/NuukPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe5" +
- "\x9e<\xc5\x02\x00\x00\xc5\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xa8\x01\x00America/OjinagaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4" +
- "\xbe\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\xab\x01\x00America/PanamaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5" +
- "\xa0\xd6\x05W\x03\x00\x00W\x03\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xac\x01\x00America/PangnirtungPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xf1\xf9\x1dɻ\x00\x00\x00\xbb\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\xaf\x01\x00America/ParamariboPK\x01\x02\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00ø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\xb0\x01\x00America/PhoenixPK\x01\x02\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4T\xbd\xeb5\x02\x00\x005\x02\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xb1\x01\x00America/Port-au-Princ" +
- "ePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\xb4\x01\x00America/Port_" +
- "of_SpainPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\xb5\x01\x00Americ" +
- "a/Porto_AcrePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x81-\xa9\x8a\x01\x00\x00\x8a\x01\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xb7\x01\x00Am" +
- "erica/Porto_VelhoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9" +
- "\xb8\x01\x00America/Puerto_RicoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x13\x9b\xb1\xc2\x04\x00\x00\xc2\x04\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xbb\xb9\x01\x00America/Punta_ArenasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x13\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\xbe\x01\x00America/Rainy_RiverPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xdfH\r'\x03\x00\x00'\x03\x00" +
- "\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\xc3\x01\x00America/Rankin_InletPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x03u\xf3\xe4" +
- "\x01\x00\x00\xe4\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G\xc7\x01\x00America/RecifePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u0096dK~" +
- "\x02\x00\x00~\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\xc9\x01\x00America/ReginaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0I~D'" +
- "\x03\x00\x00'\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xcc\x01\x00America/ResolutePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K" +
- "\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xcf\x01\x00America/Rio_BrancoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xd1\x01\x00America/RosarioPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\xd4\x01\x00America/Santa_IsabelPK\x01\x02\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x04,2h\x99\x01\x00\x00\x99\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\xd8\x01\x00America/SantaremPK\x01\x02\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\"_WJ\x05\x00\x00J\x05\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\xda\x01\x00America/SantiagoPK\x01\x02" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x0f(\b=\x01\x00\x00=\x01\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\xdf\x01\x00America/Santo_Domi" +
- "ngoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d?\xdfڸ\x03\x00\x00\xb8\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb\xe0\x01\x00America/Sao" +
- "_PauloPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x9a1T\xdf\x01\x00\x00\xdf\x01\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\xe4\x01\x00America/" +
- "ScoresbysundPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf3\xe6\x01\x00Am" +
- "erica/ShiprockPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81{\xc1\x92\xbc\x03\x00\x00\xbc\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xeb\x01\x00" +
- "America/SitkaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\xef\x01\x00A" +
- "merica/St_BarthelemyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xb2\x0e\x19V\a\x00\x00V\a\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xfe\xef\x01\x00America/St_JohnsPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x82\xf7\x01\x00America/St_KittsPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00a\xf8\x01\x00America/St_LuciaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x11\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00@\xf9\x01\x00America/St_ThomasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \xfa\x01\x00America/St_VincentPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xd8\x19\x9dp\x01\x00\x00p\x01\x00" +
- "\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xfb\x01\x00America/Swift_CurrentPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x13z\xe2" +
- "\xc2\x00\x00\x00\xc2\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\xfc\x01\x00America/TegucigalpaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00U\r\xf7\xd3\xc7\x01\x00\x00\xc7\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97\xfd\x01\x00America/ThulePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\xff\x01\x00America/Thunder_BayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\x06\x02\x00America/TijuanaPK\x01\x02\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d\n\x02\x00America/TorontoPK\x01\x02\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x11\x02\x00America/TortolaPK\x01\x02\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00U9#\xbe2\x05\x00\x002\x05\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x12\x02\x00America/VancouverPK\x01\x02\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe\x17\x02\x00America/VirginPK\x01\x02\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x1d\xee\x91\x05\x04\x00\x00\x05\x04\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x18\x02\x00America/WhitehorseP" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x1c\x02\x00America/Winnipe" +
- "gPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,\xdb~\xab\xb2\x03\x00\x00\xb2\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\"\x02\x00America/Yakut" +
- "atPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\a\a\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeb%\x02\x00America/Yell" +
- "owknifePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xddzAh\xf3\x00\x00\x00\xf3\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6)\x02\x00Antarct" +
- "ica/CaseyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xea\x06\xd3\xc5\x00\x00\x00\xc5\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a+\x02\x00Antar" +
- "ctica/DavisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa+\x02\x00Ant" +
- "arctica/DumontDUrvillePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\x84J]\xd0\x03\x00\x00\xd0\x03\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xcb,\x02\x00Antarctica/MacquariePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7N\xab\x8b\x98\x00\x00\x00\x98\x00\x00\x00\x11\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd0\x02\x00Antarctica/MawsonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x12" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x941\x02\x00Antarctica/McMurdoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95{\xf3\xa9w\x03\x00\x00w" +
- "\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd75\x02\x00Antarctica/PalmerPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ɖ\xf71\x84\x00" +
- "\x00\x00\x84\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}9\x02\x00Antarctica/RotheraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2" +
- "\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001:\x02\x00Antarctica/South_PolePK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w>\x02\x00Antarctica/SyowaPK\x01\x02\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00:\xc8P7\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*?\x02\x00Antarctica/TrollPK\x01\x02\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t@\x02\x00Antarctica/VostokPK\x01\x02" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd@\x02\x00Arctic/Longyearbye" +
- "nPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xafC\x02\x00Asia/AdenPK\x01\x02" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xdd\\2a\x02\x00\x00a\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[D\x02\x00Asia/AlmatyPK\x01\x02\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\rs\xad\xa0\x03\x00\x00\xa0\x03\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5F\x02\x00Asia/AmmanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00V\xe0\xe7!\xe7\x02\x00\x00\xe7\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xadJ\x02\x00Asia/AnadyrPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00T\x81\x18G^\x02\x00\x00^\x02\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbdM\x02\x00Asia/AqtauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb\xfa" +
- "\xb5\xbeg\x02\x00\x00g\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00CP\x02\x00Asia/AqtobePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x1bb2w" +
- "\x01\x00\x00w\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3R\x02\x00Asia/AshgabatPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x1bb2w\x01" +
- "\x00\x00w\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00uT\x02\x00Asia/AshkhabadPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xa7^\xfah\x02" +
- "\x00\x00h\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18V\x02\x00Asia/AtyrauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7e&uv\x02\x00\x00v" +
- "\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9X\x02\x00Asia/BaghdadPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdav\x19z\x98\x00\x00\x00\x98\x00\x00" +
- "\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I[\x02\x00Asia/BahrainPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x87\xb3<\xe8\x02\x00\x00\xe8\x02\x00\x00\t" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\\\x02\x00Asia/BakuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\f\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x1a_\x02\x00Asia/BangkokPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\xbd\xedL\xf1\x02\x00\x00\xf1\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\xdc_\x02\x00Asia/BarnaulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\x11\xe1[\xdc\x02\x00\x00\xdc\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xf7b\x02\x00Asia/BeirutPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000]*\x1bj\x02\x00\x00j\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xfce\x02\x00Asia/BishkekPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7f^]@\x01\x00\x00@\x01\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90" +
- "h\x02\x00Asia/BruneiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9i\x02\x00" +
- "Asia/CalcuttaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\xcd\xdf\x05\xee\x02\x00\x00\xee\x02\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00A" +
- "sia/ChitaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81z&\x80k\x02\x00\x00k\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16n\x02\x00Asia/" +
- "ChoibalsanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaep\x02\x00Asia" +
- "/ChongqingPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00cr\x02\x00Asia" +
- "/ChungkingPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\x91\x87\xbb\xf7\x00\x00\x00\xf7\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18t\x02\x00Asia" +
- "/ColomboPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009u\x02\x00Asia/D" +
- "accaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\a\xeci\xd2\x04\x00\x00\xd2\x04\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Hv\x02\x00Asia/Damas" +
- "cusPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E{\x02\x00Asia/DhakaP" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Β\x1a\x8c\xaa\x00\x00\x00\xaa\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T|\x02\x00Asia/DiliPK\x01\x02\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%}\x02\x00Asia/DubaiPK\x01\x02\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00's\x96\x1en\x01\x00\x00n\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd2}\x02\x00Asia/DushanbePK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00]S\xbb\x12\xac\x03\x00\x00\xac\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x7f\x02\x00Asia/FamagustaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\xda7\xf5l\xd6\t\x00\x00\xd6\t\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x83\x02\x00Asia/GazaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x8d\x02\x00Asia/HarbinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xba\xd4" +
- "\xe5\xe8\t\x00\x00\xe8\t\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x8e\x02\x00Asia/HebronPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000I\xc7\xde\xec\x00" +
- "\x00\x00\xec\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x99\x02\x00Asia/Ho_Chi_MinhPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\t\xfa-" +
- "\a\x03\x00\x00\a\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x9a\x02\x00Asia/Hong_KongPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xba\xa3b\xc1" +
- "R\x02\x00\x00R\x02\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x9d\x02\x00Asia/HovdPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9l\x03\x12\xf8\x02\x00\x00\xf8" +
- "\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ɟ\x02\x00Asia/IrkutskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\aW\x10Ѱ\x04\x00\x00\xb0\x04\x00" +
- "\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeb\xa2\x02\x00Asia/IstanbulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xadű\xf8\x00\x00\x00\xf8\x00\x00\x00" +
- "\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ƨ\x02\x00Asia/JakartaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.>[K\xab\x00\x00\x00\xab\x00\x00\x00\r\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\xa8\x02\x00Asia/JayapuraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17✳2\x04\x00\x002\x04\x00\x00\x0e\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe\xa9\x02\x00Asia/JerusalemPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\xe2\\\xff\x9f\x00\x00\x00\x9f\x00\x00\x00\n\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xae\x02\x00Asia/KabulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x9cf>\xd7\x02\x00\x00\xd7\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xe3\xae\x02\x00Asia/KamchatkaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009Y\xb7\xf1\n\x01\x00\x00\n\x01\x00\x00\f\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xe6\xb1\x02\x00Asia/KarachiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x1a\xb3\x02\x00Asia/KashgarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00ɳ\x02\x00Asia/KathmanduPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x96\xb4\x02\x00Asia/KatmanduPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x83g\x95M\a\x03\x00\x00\a\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00b\xb5\x02\x00Asia/KhandygaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x94\xb8\x02\x00Asia/KolkataPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\xe0\x91y\xe5\x02\x00\x00\xe5\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a" +
- "\xb9\x02\x00Asia/KrasnoyarskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xad\xbc\x02\x00Asia/Kuala_LumpurPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7f^]@\x01\x00\x00@\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00ܽ\x02\x00Asia/KuchingPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00F\xbf\x02\x00Asia/KuwaitPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d?v\f\x17\x03\x00\x00\x17\x03\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf4" +
- "\xbf\x02\x00Asia/MacaoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d?v\f\x17\x03\x00\x00\x17\x03\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xc3\x02\x00A" +
- "sia/MacauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4_P\x18\xef\x02\x00\x00\xef\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\xc6\x02\x00Asia/" +
- "MagadanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xc9\xd4\\\xbe\x00\x00\x00\xbe\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\xc9\x02\x00Asia/Ma" +
- "kassarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ǯ\xdf\x1c\xee\x00\x00\x00\xee\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca\x02\x00Asia/Man" +
- "ilaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\xcb\x02\x00Asia/Muscat" +
- "PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009\xcc\x02\x00Asia/NicosiaPK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\x9a\x90\xf7\xd6\x02\x00\x00\xd6\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8\xce\x02\x00Asia/Novokuznets" +
- "kPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)p\x1cX\xf1\x02\x00\x00\xf1\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xd1\x02\x00Asia/Novosibi" +
- "rskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x11\xea\xa2\xe5\x02\x00\x00\xe5\x02\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdc\xd4\x02\x00Asia/OmskPK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\xe9\xd1\xd8q\x02\x00\x00q\x02\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\xd7\x02\x00Asia/OralPK\x01\x02\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xda\x02\x00Asia/Phnom_PenhPK\x01\x02\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xa5\x81e\xf7\x00\x00\x00\xf7\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xdb\x02\x00Asia/PontianakPK\x01\x02\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\xc1\x1eB\xb7\x00\x00\x00\xb7\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\xdc\x02\x00Asia/PyongyangPK\x01\x02\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdav\x19z\x98\x00\x00\x00\x98\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K\xdd\x02\x00Asia/QatarPK\x01\x02\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\xa1\xfax\x98g\x02\x00\x00g\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\xde\x02\x00Asia/QostanayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\xd5ΜGp\x02\x00\x00p\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d\xe0\x02\x00Asia/QyzylordaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00ʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009\xe3\x02\x00Asia/RangoonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\xcfׇ\xe1\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xe4\x02\x00Asia/RiyadhPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "0I\xc7\xde\xec\x00\x00\x00\xec\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\xe4\x02\x00Asia/SaigonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x15I" +
- "I\xf3\x02\x00\x00\xf3\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xe5\x02\x00Asia/SakhalinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w\rD\a" +
- "n\x01\x00\x00n\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xe8\x02\x00Asia/SamarkandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7X,Y" +
- "\x9f\x01\x00\x00\x9f\x01\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\xea\x02\x00Asia/SeoulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00" +
- "\x89\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xec\x02\x00Asia/ShanghaiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00" +
- "\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xee\x02\x00Asia/SingaporePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4Zߐ\xe6\x02\x00\x00\xe6" +
- "\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xef\x02\x00Asia/SrednekolymskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\xf0BB\xff" +
- "\x01\x00\x00\xff\x01\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xf2\x02\x00Asia/TaipeiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xe27Yn\x01\x00\x00" +
- "n\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xf4\x02\x00Asia/TashkentPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ѿ\xa8\xc7u\x02\x00\x00u" +
- "\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\xf6\x02\x00Asia/TbilisiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xdb?\xec,\x03\x00\x00,\x03\x00" +
- "\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb6\xf8\x02\x00Asia/TehranPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17✳2\x04\x00\x002\x04\x00\x00\r\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\v\xfc\x02\x00Asia/Tel_AvivPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\v\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x00\x03\x00Asia/ThimbuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\f\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00+\x01\x03\x00Asia/ThimphuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\xef\x01\x03\x00Asia/TokyoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[u\x99q\xf1\x02\x00\x00\xf1\x02\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xec\x02\x03\x00Asia/TomskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xc9\xd4\\\xbe\x00\x00\x00\xbe\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x06" +
- "\x03\x00Asia/Ujung_PandangPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xf3\x06\x03\x00Asia/UlaanbaatarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00s\t\x03\x00Asia/Ulan_BatorPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\xf2\v\x03\x00Asia/UrumqiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w\x86\x8d^\x03\x03\x00\x00\x03\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xa0\f\x03\x00Asia/Ust-NeraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xce\x0f\x03\x00Asia/VientianePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d%\x05\xd8\xe6\x02\x00\x00\xe6\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x92\x10\x03\x00Asia/VladivostokPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O\xb0\x03\xe9\xe5\x02\x00\x00\xe5\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\xa6\x13\x03\x00Asia/YakutskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xb5\x16\x03\x00Asia/YangonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xea\x18\xd4\xf8\x02\x00\x00\xf8\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\x17" +
- "\x03\x00Asia/YekaterinburgPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x95-\xad\xc4\x02\x00\x00\xc4\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xc1\x1a\x03\x00Asia/YerevanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x8dY\x80\xad\x05\x00\x00\xad\x05\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\xaf\x1d\x03\x00Atlantic/AzoresPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l&\x04\x99\x00\x04\x00\x00\x00\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x89#\x03\x00Atlantic/BermudaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf|7\xb3\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\xb7'\x03\x00Atlantic/CanaryPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u0097N\xad\xaf\x00\x00\x00\xaf\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xc2)\x03\x00Atlantic/Cape_VerdePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0f\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2*\x03\x00Atlantic/FaeroePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0e\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88,\x03\x00Atlantic/FaroePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x12\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m.\x03\x00Atlantic/Jan_MayenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001)7\xad\xad\x05\x00\x00\xad\x05\x00\x00" +
- "\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^1\x03\x00Atlantic/MadeiraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00" +
- "\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0097\x03\x00Atlantic/ReykjavikPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f-\xadׄ\x00" +
- "\x00\x00\x84\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeb7\x03\x00Atlantic/South_GeorgiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa38\x03\x00Atlantic/St_HelenaPK\x01\x02\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\xe7\xcf^\xb0\x15\x03\x00\x00\x15\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U9\x03\x00Atlantic/StanleyPK\x01\x02\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98<\x03\x00Australia/ACTPK\x01\x02\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x8ff~ՙ\x03\x00\x00\x99\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K@\x03\x00Australia/AdelaidePK\x01\x02\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14D\x03\x00Australia/BrisbaneP" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00eE\x03\x00Australia/Broke" +
- "n_HillPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00EI\x03\x00Australi" +
- "a/CanberraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfdL\x03\x00Aust" +
- "ralia/CurriePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16Q\x03\x00Au" +
- "stralia/DarwinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2ܺ\xca:\x01\x00\x00:\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.R\x03\x00" +
- "Australia/EuclaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95S\x03" +
- "\x00Australia/HobartPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae" +
- "W\x03\x00Australia/LHIPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x95\xbd\x12E\x01\x00\x00E\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8dZ" +
- "\x03\x00Australia/LindemanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x02\\\x03\x00Australia/Lord_HowePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x13\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xe7^\x03\x00Australia/MelbournePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\r\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0b\x03\x00Australia/NSWPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x0f\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Sf\x03\x00Australia/NorthPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ϻ\xca\x1a2\x01\x00\x002\x01\x00\x00\x0f\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00jg\x03\x00Australia/PerthPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x14" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc9h\x03\x00Australia/QueenslandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ff~ՙ\x03\x00" +
- "\x00\x99\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1cj\x03\x00Australia/SouthPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03" +
- "\x00\x00\x88\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2m\x03\x00Australia/SydneyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z" +
- "\xeb\x03\x00\x00\xeb\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98q\x03\x00Australia/TasmaniaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3u\x03\x00Australia/VictoriaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00ϻ\xca\x1a2\x01\x00\x002\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ky\x03\x00Australia/WestPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc9z\x03\x00Australia/YancowinnaPK\x01\x02\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8~\x03\x00Brazil/AcrePK\x01\x02\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x80\x03\x00Brazil/DeNoronhaPK\x01\x02\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d?\xdfڸ\x03\x00\x00\xb8\x03\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x82\x03\x00Brazil/EastPK\x01\x02\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00a\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f\x86\x03\x00Brazil/WestPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\xe6\x9aM\xbem\x02\x00\x00m\x02\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x88\x03\x00CETPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x8b\x99\x1e\xb7\x03\x00\x00" +
- "\xb7\x03\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\x8a\x03\x00CST6CDTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\x8e\x03\x00Canada/AtlanticPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x0e\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\x95\x03\x00Canada/CentralPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ӿ\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x9a\x03\x00Canada/EasternPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\a\a\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x0f\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\xa1\x03\x00Canada/MountainPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xb2\x0e\x19V\a\x00\x00V\a\x00\x00\x13" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\xa5\x03\x00Canada/NewfoundlandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U9#\xbe2\x05\x00\x00" +
- "2\x05\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xac\x03\x00Canada/PacificPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\u0096dK~\x02\x00\x00" +
- "~\x02\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\xb2\x03\x00Canada/SaskatchewanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x1d\xee" +
- "\x91\x05\x04\x00\x00\x05\x04\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xb4\x03\x00Canada/YukonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\"_WJ" +
- "\x05\x00\x00J\x05\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xb9\x03\x00Chile/ContinentalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?X" +
- "'\x8e\x96\x04\x00\x00\x96\x04\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\xbe\x03\x00Chile/EasterIslandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\a\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\xc3\x03\x00CubaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`l\x8d~\xf1\x01\x00\x00" +
- "\xf1\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd\xc7\x03\x00EETPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tX\xbe\xe4o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xef\xc9\x03\x00ESTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7/\xebT\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xca\x03\x00" +
- "EST5EDTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5#)\x16\x1d\x05\x00\x00\x1d\x05\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\xce\x03\x00EgyptPK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xd6jL\xd8\x05\x00\x00\xd8\x05\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xd3\x03\x00EirePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xd9\x03\x00Etc/GMTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa" +
- "\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\xda\x03\x00Etc/GMT+0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\xb8\xe8\x86q\x00\x00\x00" +
- "q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xda\x03\x00Etc/GMT+1PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8e\x1569r\x00\x00\x00r\x00\x00\x00\n" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\xdb\x03\x00Etc/GMT+10PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\xb9\xbe\x9dr\x00\x00\x00r\x00\x00\x00\n\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\xdb\x03\x00Etc/GMT+11PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xf38cr\x00\x00\x00r\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x8b\xdc\x03\x00Etc/GMT+12PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9{\xa2qq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00%\xdd\x03\x00Etc/GMT+2PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\xcb\xe9Qq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xdd\x03\x00" +
- "Etc/GMT+3PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\xfaFDq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\xde\x03\x00Etc/G" +
- "MT+4PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4X\x9b\xf3q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\xde\x03\x00Etc/GMT+5P" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\x9b\xd1\x04q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\xdf\x03\x00Etc/GMT+6PK\x01\x02\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84+\x9a$q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\xe0\x03\x00Etc/GMT+7PK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\"\xf8\x8f/q\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb5\xe0\x03\x00Etc/GMT+8PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x84\x19\xb3\tq\x00\x00\x00q\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M\xe1\x03\x00Etc/GMT+9PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o" +
- "\x00\x00\x00o\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xe1\x03\x00Etc/GMT-0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\x1ac\xc3r\x00\x00\x00r\x00" +
- "\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\xe2\x03\x00Etc/GMT-1PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9|\xbd7s\x00\x00\x00s\x00\x00\x00\n\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xe3\x03\x00Etc/GMT-10PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xab\xd1Is\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xaf\xe3\x03\x00Etc/GMT-11PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\x19s\x81s\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00J\xe4\x03\x00Etc/GMT-12PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90`N\xe8s\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5" +
- "\xe4\x03\x00Etc/GMT-13PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,{\xdc;s\x00\x00\x00s\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xe5\x03\x00E" +
- "tc/GMT-14PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x19y\x04r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xe6\x03\x00Etc/G" +
- "MT-2PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\xfcm\x99r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\xe6\x03\x00Etc/GMT-3P" +
- "K\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x19<Qr\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M\xe7\x03\x00Etc/GMT-4PK\x01\x02\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\xd6~wr\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xe7\x03\x00Etc/GMT-5PK\x01\x02\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00j\xd5d\xb0r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xe8\x03\x00Etc/GMT-6PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "J0p-r\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\xe9\x03\x00Etc/GMT-7PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x18\xb6\xfbr" +
- "\x00\x00\x00r\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1\xe9\x03\x00Etc/GMT-8PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\x19@\xb9r\x00\x00\x00r\x00" +
- "\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\xea\x03\x00Etc/GMT-9PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\b\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xea\x03\x00Etc/GMT0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00x\xeb\x03\x00Etc/GreenwichPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x12\xec\x03\x00Etc/UCTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa6\xec\x03" +
- "\x00Etc/UTCPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\xed\x03\x00Etc/Un" +
- "iversalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xed\x03\x00Etc/Zul" +
- "uPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00i\xee\x03\x00Europe/Amster" +
- "damPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ߜvυ\x01\x00\x00\x85\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xf2\x03\x00Europe/Ando" +
- "rraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]i\x11u\xd6\x02\x00\x00\xd6\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97\xf4\x03\x00Europe/Astr" +
- "akhanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcb*j\x8f\xaa\x02\x00\x00\xaa\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xf7\x03\x00Europe/At" +
- "hensPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xfa\x03\x00Europe/Bel" +
- "fastPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb\x00\x04\x00Europe/Bel" +
- "gradePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\x02\x04\x00Europe/Be" +
- "rlinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Io\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd2\x05\x04\x00Europe/Bra" +
- "tislavaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\b\x04\x00Europe/" +
- "BrusselsPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xa9\xf5ϕ\x02\x00\x00\x95\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\r\x04\x00Europe" +
- "/BucharestPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6Kf\xab\xfe\x02\x00\x00\xfe\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x10\x04\x00Euro" +
- "pe/BudapestPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x13\x04\x00Eur" +
- "ope/BusingenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\\\x15\x04\x00Eu" +
- "rope/ChisinauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\x18\x04\x00E" +
- "urope/CopenhagenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xd6jL\xd8\x05\x00\x00\xd8\x05\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l\x1b" +
- "\x04\x00Europe/DublinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00==\xa4\x16\xc4\x04\x00\x00\xc4\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o!\x04" +
- "\x00Europe/GibraltarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a" +
- "&\x04\x00Europe/GuernseyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\xcd,\x04\x00Europe/HelsinkiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xdb.\x04\x00Europe/Isle_of_ManPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\aW\x10Ѱ\x04\x00\x00\xb0\x04\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00J5\x04\x00Europe/IstanbulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\r\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00':\x04\x00Europe/JerseyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O+j\x94\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x91@\x04\x00Europe/KaliningradPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\v\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00ID\x04\x00Europe/KievPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f(NN\xdf\x02\x00\x00\xdf\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\xa0F\x04\x00Europe/KirovPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xa9I\x04\x00Europe/KyivPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&S\x03\t\xae\x05\x00\x00\xae\x05\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00L\x04\x00Europe/LisbonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\xd9Q\x04\x00Europe/LjubljanaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xe5S\x04\x00Europe/LondonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00OZ\x04\x00Europe/LuxembourgPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Zk#V\x81\x03\x00\x00\x81\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\xcd^\x04\x00Europe/MadridPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\xa5J[\xa0\x03\x00\x00\xa0\x03\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00yb\x04\x00Europe/MaltaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00Cf\x04\x00Europe/MariehamnPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00WI\xc3\x7f(\x03\x00\x00(\x03\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00Rh\x04\x00Europe/MinskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xa4k\x04\x00Europe/MonacoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- " p\x04\x00Europe/MoscowPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7" +
- "s\x04\x00Europe/NicosiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X" +
- "v\x04\x00Europe/OsloPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00By\x04\x00" +
- "Europe/ParisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd}\x04\x00Eu" +
- "rope/PodgoricaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Io\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc9\x7f\x04\x00" +
- "Europe/PraguePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00gp\xc0\xa7\xb6\x02\x00\x00\xb6\x02\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ǂ\x04\x00E" +
- "urope/RigaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa6\x85\x04\x00Euro" +
- "pe/RomePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\x7fpp\xdc\x02\x00\x00\xdc\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x89\x04\x00Europe/" +
- "SamaraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x8c\x04\x00Europe/S" +
- "an_MarinoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x90\x04\x00Europ" +
- "e/SarajevoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b8\xfel\xd6\x02\x00\x00\xd6\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00v\x92\x04\x00Euro" +
- "pe/SaratovPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\xb4N\xb8a\x03\x00\x00a\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x95\x04\x00Euro" +
- "pe/SimferopolPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b\x99\x04\x00E" +
- "urope/SkopjePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xc8\x15\xd0P\x02\x00\x00P\x02\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x9b\x04\x00Eu" +
- "rope/SofiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\x9d\x04\x00Euro" +
- "pe/StockholmPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\x16\x9b?\xa3\x02\x00\x00\xa3\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00z\xa0\x04\x00Eu" +
- "rope/TallinnPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\xc48\xde\\\x02\x00\x00\\\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xa3\x04\x00Eu" +
- "rope/TiranePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Х\x04\x00Eur" +
- "ope/TiraspolPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u\xb0\xcd\xfc\xf8\x02\x00\x00\xf8\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xa8\x04\x00Eu" +
- "rope/UlyanovskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\xac\x04\x00" +
- "Europe/UzhgorodPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xae\x04" +
- "\x00Europe/VaduzPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xb0\x04\x00E" +
- "urope/VaticanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x05wג\x02\x00\x00\x92\x02\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xb4\x04\x00E" +
- "urope/ViennaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xccb\xf72\xa4\x02\x00\x00\xa4\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xb7\x04\x00Eu" +
- "rope/VilniusPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xec\xa0%\xf1\x02\x00\x00\xf1\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\xb9\x04\x00Eu" +
- "rope/VolgogradPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xfe垛\x03\x00\x00\x9b\x03\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\xbd\x04\x00" +
- "Europe/WarsawPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd\xc0\x04\x00E" +
- "urope/ZagrebPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xc2\x04\x00Eu" +
- "rope/ZaporozhyePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\xc5\x04" +
- "\x00Europe/ZurichPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x80c$q\x00\x00\x00q\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\xc7\x04\x00" +
- "FactoryPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf5\xc7\x04\x00GBPK\x01\x02\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\xce\x04\x00GB-EirePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8\xd4\x04\x00GMTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00" +
- "\x00o\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\xd5\x04\x00GMT+0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x05\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xda\xd5\x04\x00GMT-0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00l\xd6\x04\x00GMT0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xd6\x04\x00Green" +
- "wichPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\xf7\xfawp\x00\x00\x00p\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\xd7\x04\x00HSTPK\x01\x02\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00E\t\xfa-\a\x03\x00\x00\a\x03\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\xd8\x04\x00HongkongPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\xf1\b{\x87\x82\x00\x00\x00\x82\x00\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Q\xdb\x04\x00IcelandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6" +
- "\xbf\x00\x00\x00\xbf\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\xdb\x04\x00Indian/AntananarivoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00x\xb0W\x14\x98\x00\x00\x00\x98\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\xdc\x04\x00Indian/ChagosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\xdd\x04\x00Indian/ChristmasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00ʇ{_\xbb\x00\x00\x00\xbb\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xde\x04\x00Indian/CocosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xdf\x04\x00Indian/ComoroPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9" +
- "\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xe0\x04\x00Indian/KerguelenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\xe1\x04\x00Indian/MahePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\xb2" +
- "Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\xe1\x04\x00Indian/MaldivesPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96" +
- "\xed=\x98\xb3\x00\x00\x00\xb3\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00y\xe2\x04\x00Indian/MauritiusPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xb4\x8d\x98ƿ\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\xe3\x04\x00Indian/MayottePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xe4\x04\x00Indian/ReunionPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x8c\xdb?\xec,\x03\x00\x00,\x03\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe4\x04\x00IranPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17✳2\x04\x00\x002" +
- "\x04\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\xe8\x04\x00IsraelPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%J\xd5\xebS\x01\x00\x00S\x01\x00\x00\a\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xec\x04\x00JamaicaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x12\xee\x04\x00JapanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\xef\x04\x00Kwa" +
- "jaleinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\f\xf0\x04\x00LibyaPK\x01" +
- "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\x9d\x1b\xc9m\x02\x00\x00m\x02\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xf1\x04\x00METPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\xf5\x8d\x99\x92o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l\xf4\x04\x00MSTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6h\xcac\xb7\x03\x00\x00\xb7" +
- "\x03\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\xf4\x04\x00MST7MDTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xf8\x04\x00Mexico/BajaNortePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xad=\x98\xce\x02\x00\x00\xce\x02\x00\x00\x0e\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\a\xfd\x04\x00Mexico/BajaSurPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\b\x89\x8c\x05\x03\x00\x00\x05\x03\x00\x00\x0e\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x05\x00Mexico/GeneralPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x02\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x03\x05\x00NZPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "e\a\x05\x00NZ-CHATPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\n\x05\x00Nav" +
- "ajoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x0e\x05\x00PRCPK\x01\x02\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00ŭV\xad\xb7\x03\x00\x00\xb7\x03\x00\x00\a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x10\x05\x00PST8PDTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\xa8A\x15\xfe\x97\x01\x00\x00\x97\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x14\x05\x00Pacific/ApiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b" +
- "\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/\x16\x05\x00Pacific/AucklandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x9a\xf2:F\xc9\x00\x00\x00\xc9\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x1a\x05\x00Pacific/BougainvillePK\x01\x02\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x1b\x05\x00Pacific/ChathamPK\x01\x02\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x1e\x05\x00Pacific/ChuukPK\x01\x02\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00?X'\x8e\x96\x04\x00\x00\x96\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x1f\x05\x00Pacific/EasterPK\x01\x02\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x9e\x7f\xab\x95V\x01\x00\x00V\x01\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G$\x05\x00Pacific/EfatePK\x01\x02\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8%\x05\x00Pacific/EnderburyPK\x01\x02\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a|\xdcU\x99\x00\x00\x00\x99\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3&\x05\x00Pacific/FakaofoPK\x01\x02\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd_yl\x8c\x01\x00\x00\x8c\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00i'\x05\x00Pacific/FijiPK\x01\x02\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f)\x05\x00Pacific/FunafutiPK\x01\x02\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xe3w\n\xaf\x00\x00\x00\xaf\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3)\x05\x00Pacific/GalapagosPK\x01" +
- "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc23\xa0\xbc\x84\x00\x00\x00\x84\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1*\x05\x00Pacific/GambierPK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b+\x05\x00Pacific/Guadalca" +
- "nalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FI\xfe\x14^\x01\x00\x00^\x01\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19,\x05\x00Pacific/Gua" +
- "mPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1-\x05\x00Pacific/Honol" +
- "uluPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac.\x05\x00Pacific/Joh" +
- "nstonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7/\x05\x00Pacific/K" +
- "antonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8=ku\xae\x00\x00\x00\xae\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f0\x05\x00Pacific/K" +
- "iritimatiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97n7\x1a\xf2\x00\x00\x00\xf2\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m1\x05\x00Pacif" +
- "ic/KosraePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b2\x05\x00Pacif" +
- "ic/KwajaleinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x953\x05\x00Pa" +
- "cific/MajuroPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D6\x83\xa1\x8b\x00\x00\x00\x8b\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G4\x05\x00Pa" +
- "cific/MarquesasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x015\x05" +
- "\x00Pacific/MidwayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2;Z\xf7\xb7\x00\x00\x00\xb7\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf5\x05" +
- "\x00Pacific/NauruPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\xd60\f\x9a\x00\x00\x00\x9a\x00\x00\x00\f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa16\x05\x00" +
- "Pacific/NiuePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y5\x1a6\xf7\x00\x00\x00\xf7\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e7\x05\x00Pa" +
- "cific/NorfolkPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\xef\x97\xc6\xc6\x00\x00\x00\xc6\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x898\x05\x00P" +
- "acific/NoumeaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{9\x05\x00P" +
- "acific/Pago_PagoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xf8vܔ\x00\x00\x00\x94\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<:" +
- "\x05\x00Pacific/PalauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x0fA\x05\x99\x00\x00\x00\x99\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb:\x05" +
- "\x00Pacific/PitcairnPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc2" +
- ";\x05\x00Pacific/PohnpeiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "u<\x05\x00Pacific/PonapePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "'=\x05\x00Pacific/Port_MoresbyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xe3\xa3S\x96\x01\x00\x00\x96\x01\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\xf3=\x05\x00Pacific/RarotongaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FI\xfe\x14^\x01\x00\x00^\x01\x00\x00\x0e\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8?\x05\x00Pacific/SaipanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\r\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00BA\x05\x00Pacific/SamoaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\xc1\xdaυ\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\xffA\x05\x00Pacific/TahitiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\xb0B\x05\x00Pacific/TarawaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97F\x91\xb3\xed\x00\x00\x00\xed\x00\x00\x00\x11\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00bC\x05\x00Pacific/TongatapuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\f\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~D\x05\x00Pacific/TrukPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\f\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00BE\x05\x00Pacific/WakePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xf2E\x05\x00Pacific/WallisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\v\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\xa4F\x05\x00Pacific/YapPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xfe垛\x03\x00\x00\x9b\x03\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00gG\x05\x00PolandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&S\x03\t\xae\x05\x00\x00\xae\x05\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&K\x05\x00" +
- "PortugalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfaP\x05\x00ROCPK\x01" +
- "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1aS\x05\x00ROKPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdaT\x05\x00SingaporePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\aW\x10" +
- "Ѱ\x04\x00\x00\xb0\x04\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01V\x05\x00TurkeyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00" +
- "\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5Z\x05\x00UCTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00e[\x05\x00US/AlaskaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]" +
- "_\x05\x00US/AleutianPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ø\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Oc\x05\x00" +
- "US/ArizonaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9bܩ=\xda\x06\x00\x00\xda\x06\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00gd\x05\x00US/C" +
- "entralPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ik\x05\x00US/East-" +
- "IndianaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9m\x05\x00US/East" +
- "ernPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1t\x05\x00US/HawaiiPK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5u\x05\x00US/Indiana-Stark" +
- "ePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xccy\x05\x00US/MichiganPK" +
- "\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x}\x05\x00US/MountainPK\x01\x02\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\"\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3\x81\x05\x00US/PacificPK\x01\x02\x00\x00\x00\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x86\x05\x00US/SamoaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\x87\x05\x00UTCPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00" +
- "\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\x88\x05\x00UniversalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\x04\x00\x00" +
- "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Lj\x05\x00W-SUPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x91B\xc0\xee\x01\x00\x00\xee\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
- "\x00u\x8c\x05\x00WETPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x8e\x05\x00ZuluPK" +
- "\x05\x06\x00\x00\x00\x00U\x02U\x02m\x8c\x00\x00\x15\x8f\x05\x00\x00\x00"
diff --git a/contrib/go/_std_1.20/src/time/ya.make b/contrib/go/_std_1.20/src/time/ya.make
deleted file mode 100644
index bc0a6813df..0000000000
--- a/contrib/go/_std_1.20/src/time/ya.make
+++ /dev/null
@@ -1,40 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- format.go
- format_rfc3339.go
- sleep.go
- tick.go
- time.go
- zoneinfo.go
- zoneinfo_goroot.go
- zoneinfo_read.go
-)
-
-IF (OS_DARWIN)
- SRCS(
- sys_unix.go
- zoneinfo_unix.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- sys_unix.go
- zoneinfo_unix.go
- )
-ENDIF()
-
-IF (OS_WINDOWS)
- SRCS(
- sys_windows.go
- zoneinfo_abbrs_windows.go
- zoneinfo_windows.go
- )
-ENDIF()
-
-END()
-
-RECURSE(
- tzdata
-)
diff --git a/contrib/go/_std_1.20/src/time/zoneinfo_abbrs_windows.go b/contrib/go/_std_1.20/src/time/zoneinfo_abbrs_windows.go
deleted file mode 100644
index 139bda1acc..0000000000
--- a/contrib/go/_std_1.20/src/time/zoneinfo_abbrs_windows.go
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2013 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.
-
-// Code generated by genzabbrs.go; DO NOT EDIT.
-// Based on information from https://raw.githubusercontent.com/unicode-org/cldr/master/common/supplemental/windowsZones.xml
-
-package time
-
-type abbr struct {
- std string
- dst string
-}
-
-var abbrs = map[string]abbr{
- "Egypt Standard Time": {"EET", "EET"}, // Africa/Cairo
- "Morocco Standard Time": {"+00", "+01"}, // Africa/Casablanca
- "South Africa Standard Time": {"SAST", "SAST"}, // Africa/Johannesburg
- "South Sudan Standard Time": {"CAT", "CAT"}, // Africa/Juba
- "Sudan Standard Time": {"CAT", "CAT"}, // Africa/Khartoum
- "W. Central Africa Standard Time": {"WAT", "WAT"}, // Africa/Lagos
- "E. Africa Standard Time": {"EAT", "EAT"}, // Africa/Nairobi
- "Sao Tome Standard Time": {"GMT", "GMT"}, // Africa/Sao_Tome
- "Libya Standard Time": {"EET", "EET"}, // Africa/Tripoli
- "Namibia Standard Time": {"CAT", "CAT"}, // Africa/Windhoek
- "Aleutian Standard Time": {"HST", "HDT"}, // America/Adak
- "Alaskan Standard Time": {"AKST", "AKDT"}, // America/Anchorage
- "Tocantins Standard Time": {"-03", "-03"}, // America/Araguaina
- "Paraguay Standard Time": {"-04", "-03"}, // America/Asuncion
- "Bahia Standard Time": {"-03", "-03"}, // America/Bahia
- "SA Pacific Standard Time": {"-05", "-05"}, // America/Bogota
- "Argentina Standard Time": {"-03", "-03"}, // America/Buenos_Aires
- "Eastern Standard Time (Mexico)": {"EST", "EST"}, // America/Cancun
- "Venezuela Standard Time": {"-04", "-04"}, // America/Caracas
- "SA Eastern Standard Time": {"-03", "-03"}, // America/Cayenne
- "Central Standard Time": {"CST", "CDT"}, // America/Chicago
- "Mountain Standard Time (Mexico)": {"CST", "CST"}, // America/Chihuahua
- "Central Brazilian Standard Time": {"-04", "-04"}, // America/Cuiaba
- "Mountain Standard Time": {"MST", "MDT"}, // America/Denver
- "Greenland Standard Time": {"-03", "-02"}, // America/Godthab
- "Turks And Caicos Standard Time": {"EST", "EDT"}, // America/Grand_Turk
- "Central America Standard Time": {"CST", "CST"}, // America/Guatemala
- "Atlantic Standard Time": {"AST", "ADT"}, // America/Halifax
- "Cuba Standard Time": {"CST", "CDT"}, // America/Havana
- "US Eastern Standard Time": {"EST", "EDT"}, // America/Indianapolis
- "SA Western Standard Time": {"-04", "-04"}, // America/La_Paz
- "Pacific Standard Time": {"PST", "PDT"}, // America/Los_Angeles
- "Central Standard Time (Mexico)": {"CST", "CST"}, // America/Mexico_City
- "Saint Pierre Standard Time": {"-03", "-02"}, // America/Miquelon
- "Montevideo Standard Time": {"-03", "-03"}, // America/Montevideo
- "Eastern Standard Time": {"EST", "EDT"}, // America/New_York
- "US Mountain Standard Time": {"MST", "MST"}, // America/Phoenix
- "Haiti Standard Time": {"EST", "EDT"}, // America/Port-au-Prince
- "Magallanes Standard Time": {"-03", "-03"}, // America/Punta_Arenas
- "Canada Central Standard Time": {"CST", "CST"}, // America/Regina
- "Pacific SA Standard Time": {"-04", "-03"}, // America/Santiago
- "E. South America Standard Time": {"-03", "-03"}, // America/Sao_Paulo
- "Newfoundland Standard Time": {"NST", "NDT"}, // America/St_Johns
- "Pacific Standard Time (Mexico)": {"PST", "PDT"}, // America/Tijuana
- "Yukon Standard Time": {"MST", "MST"}, // America/Whitehorse
- "Central Asia Standard Time": {"+06", "+06"}, // Asia/Almaty
- "Jordan Standard Time": {"+03", "+03"}, // Asia/Amman
- "Arabic Standard Time": {"+03", "+03"}, // Asia/Baghdad
- "Azerbaijan Standard Time": {"+04", "+04"}, // Asia/Baku
- "SE Asia Standard Time": {"+07", "+07"}, // Asia/Bangkok
- "Altai Standard Time": {"+07", "+07"}, // Asia/Barnaul
- "Middle East Standard Time": {"EET", "EEST"}, // Asia/Beirut
- "India Standard Time": {"IST", "IST"}, // Asia/Calcutta
- "Transbaikal Standard Time": {"+09", "+09"}, // Asia/Chita
- "Sri Lanka Standard Time": {"+0530", "+0530"}, // Asia/Colombo
- "Syria Standard Time": {"+03", "+03"}, // Asia/Damascus
- "Bangladesh Standard Time": {"+06", "+06"}, // Asia/Dhaka
- "Arabian Standard Time": {"+04", "+04"}, // Asia/Dubai
- "West Bank Standard Time": {"EET", "EEST"}, // Asia/Hebron
- "W. Mongolia Standard Time": {"+07", "+07"}, // Asia/Hovd
- "North Asia East Standard Time": {"+08", "+08"}, // Asia/Irkutsk
- "Israel Standard Time": {"IST", "IDT"}, // Asia/Jerusalem
- "Afghanistan Standard Time": {"+0430", "+0430"}, // Asia/Kabul
- "Russia Time Zone 11": {"+12", "+12"}, // Asia/Kamchatka
- "Pakistan Standard Time": {"PKT", "PKT"}, // Asia/Karachi
- "Nepal Standard Time": {"+0545", "+0545"}, // Asia/Katmandu
- "North Asia Standard Time": {"+07", "+07"}, // Asia/Krasnoyarsk
- "Magadan Standard Time": {"+11", "+11"}, // Asia/Magadan
- "N. Central Asia Standard Time": {"+07", "+07"}, // Asia/Novosibirsk
- "Omsk Standard Time": {"+06", "+06"}, // Asia/Omsk
- "North Korea Standard Time": {"KST", "KST"}, // Asia/Pyongyang
- "Qyzylorda Standard Time": {"+05", "+05"}, // Asia/Qyzylorda
- "Myanmar Standard Time": {"+0630", "+0630"}, // Asia/Rangoon
- "Arab Standard Time": {"+03", "+03"}, // Asia/Riyadh
- "Sakhalin Standard Time": {"+11", "+11"}, // Asia/Sakhalin
- "Korea Standard Time": {"KST", "KST"}, // Asia/Seoul
- "China Standard Time": {"CST", "CST"}, // Asia/Shanghai
- "Singapore Standard Time": {"+08", "+08"}, // Asia/Singapore
- "Russia Time Zone 10": {"+11", "+11"}, // Asia/Srednekolymsk
- "Taipei Standard Time": {"CST", "CST"}, // Asia/Taipei
- "West Asia Standard Time": {"+05", "+05"}, // Asia/Tashkent
- "Georgian Standard Time": {"+04", "+04"}, // Asia/Tbilisi
- "Iran Standard Time": {"+0330", "+0330"}, // Asia/Tehran
- "Tokyo Standard Time": {"JST", "JST"}, // Asia/Tokyo
- "Tomsk Standard Time": {"+07", "+07"}, // Asia/Tomsk
- "Ulaanbaatar Standard Time": {"+08", "+08"}, // Asia/Ulaanbaatar
- "Vladivostok Standard Time": {"+10", "+10"}, // Asia/Vladivostok
- "Yakutsk Standard Time": {"+09", "+09"}, // Asia/Yakutsk
- "Ekaterinburg Standard Time": {"+05", "+05"}, // Asia/Yekaterinburg
- "Caucasus Standard Time": {"+04", "+04"}, // Asia/Yerevan
- "Azores Standard Time": {"-01", "+00"}, // Atlantic/Azores
- "Cape Verde Standard Time": {"-01", "-01"}, // Atlantic/Cape_Verde
- "Greenwich Standard Time": {"GMT", "GMT"}, // Atlantic/Reykjavik
- "Cen. Australia Standard Time": {"ACST", "ACDT"}, // Australia/Adelaide
- "E. Australia Standard Time": {"AEST", "AEST"}, // Australia/Brisbane
- "AUS Central Standard Time": {"ACST", "ACST"}, // Australia/Darwin
- "Aus Central W. Standard Time": {"+0845", "+0845"}, // Australia/Eucla
- "Tasmania Standard Time": {"AEST", "AEDT"}, // Australia/Hobart
- "Lord Howe Standard Time": {"+1030", "+11"}, // Australia/Lord_Howe
- "W. Australia Standard Time": {"AWST", "AWST"}, // Australia/Perth
- "AUS Eastern Standard Time": {"AEST", "AEDT"}, // Australia/Sydney
- "UTC-11": {"-11", "-11"}, // Etc/GMT+11
- "Dateline Standard Time": {"-12", "-12"}, // Etc/GMT+12
- "UTC-02": {"-02", "-02"}, // Etc/GMT+2
- "UTC-08": {"-08", "-08"}, // Etc/GMT+8
- "UTC-09": {"-09", "-09"}, // Etc/GMT+9
- "UTC+12": {"+12", "+12"}, // Etc/GMT-12
- "UTC+13": {"+13", "+13"}, // Etc/GMT-13
- "UTC": {"UTC", "UTC"}, // Etc/UTC
- "Astrakhan Standard Time": {"+04", "+04"}, // Europe/Astrakhan
- "W. Europe Standard Time": {"CET", "CEST"}, // Europe/Berlin
- "GTB Standard Time": {"EET", "EEST"}, // Europe/Bucharest
- "Central Europe Standard Time": {"CET", "CEST"}, // Europe/Budapest
- "E. Europe Standard Time": {"EET", "EEST"}, // Europe/Chisinau
- "Turkey Standard Time": {"+03", "+03"}, // Europe/Istanbul
- "Kaliningrad Standard Time": {"EET", "EET"}, // Europe/Kaliningrad
- "FLE Standard Time": {"EET", "EEST"}, // Europe/Kiev
- "GMT Standard Time": {"GMT", "BST"}, // Europe/London
- "Belarus Standard Time": {"+03", "+03"}, // Europe/Minsk
- "Russian Standard Time": {"MSK", "MSK"}, // Europe/Moscow
- "Romance Standard Time": {"CET", "CEST"}, // Europe/Paris
- "Russia Time Zone 3": {"+04", "+04"}, // Europe/Samara
- "Saratov Standard Time": {"+04", "+04"}, // Europe/Saratov
- "Volgograd Standard Time": {"+03", "+03"}, // Europe/Volgograd
- "Central European Standard Time": {"CET", "CEST"}, // Europe/Warsaw
- "Mauritius Standard Time": {"+04", "+04"}, // Indian/Mauritius
- "Samoa Standard Time": {"+13", "+13"}, // Pacific/Apia
- "New Zealand Standard Time": {"NZST", "NZDT"}, // Pacific/Auckland
- "Bougainville Standard Time": {"+11", "+11"}, // Pacific/Bougainville
- "Chatham Islands Standard Time": {"+1245", "+1345"}, // Pacific/Chatham
- "Easter Island Standard Time": {"-06", "-05"}, // Pacific/Easter
- "Fiji Standard Time": {"+12", "+12"}, // Pacific/Fiji
- "Central Pacific Standard Time": {"+11", "+11"}, // Pacific/Guadalcanal
- "Hawaiian Standard Time": {"HST", "HST"}, // Pacific/Honolulu
- "Line Islands Standard Time": {"+14", "+14"}, // Pacific/Kiritimati
- "Marquesas Standard Time": {"-0930", "-0930"}, // Pacific/Marquesas
- "Norfolk Standard Time": {"+11", "+12"}, // Pacific/Norfolk
- "West Pacific Standard Time": {"+10", "+10"}, // Pacific/Port_Moresby
- "Tonga Standard Time": {"+13", "+13"}, // Pacific/Tongatapu
-}
diff --git a/contrib/go/_std_1.20/src/time/zoneinfo_read.go b/contrib/go/_std_1.20/src/time/zoneinfo_read.go
deleted file mode 100644
index 1c155dc59d..0000000000
--- a/contrib/go/_std_1.20/src/time/zoneinfo_read.go
+++ /dev/null
@@ -1,597 +0,0 @@
-// Copyright 2009 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.
-
-// Parse "zoneinfo" time zone file.
-// This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others.
-// See tzfile(5), https://en.wikipedia.org/wiki/Zoneinfo,
-// and ftp://munnari.oz.au/pub/oldtz/
-
-package time
-
-import (
- "errors"
- "runtime"
- "syscall"
-)
-
-// registerLoadFromEmbeddedTZData is called by the time/tzdata package,
-// if it is imported.
-func registerLoadFromEmbeddedTZData(f func(string) (string, error)) {
- loadFromEmbeddedTZData = f
-}
-
-// loadFromEmbeddedTZData is used to load a specific tzdata file
-// from tzdata information embedded in the binary itself.
-// This is set when the time/tzdata package is imported,
-// via registerLoadFromEmbeddedTzdata.
-var loadFromEmbeddedTZData func(zipname string) (string, error)
-
-// maxFileSize is the max permitted size of files read by readFile.
-// As reference, the zoneinfo.zip distributed by Go is ~350 KB,
-// so 10MB is overkill.
-const maxFileSize = 10 << 20
-
-type fileSizeError string
-
-func (f fileSizeError) Error() string {
- return "time: file " + string(f) + " is too large"
-}
-
-// Copies of io.Seek* constants to avoid importing "io":
-const (
- seekStart = 0
- seekCurrent = 1
- seekEnd = 2
-)
-
-// Simple I/O interface to binary blob of data.
-type dataIO struct {
- p []byte
- error bool
-}
-
-func (d *dataIO) read(n int) []byte {
- if len(d.p) < n {
- d.p = nil
- d.error = true
- return nil
- }
- p := d.p[0:n]
- d.p = d.p[n:]
- return p
-}
-
-func (d *dataIO) big4() (n uint32, ok bool) {
- p := d.read(4)
- if len(p) < 4 {
- d.error = true
- return 0, false
- }
- return uint32(p[3]) | uint32(p[2])<<8 | uint32(p[1])<<16 | uint32(p[0])<<24, true
-}
-
-func (d *dataIO) big8() (n uint64, ok bool) {
- n1, ok1 := d.big4()
- n2, ok2 := d.big4()
- if !ok1 || !ok2 {
- d.error = true
- return 0, false
- }
- return (uint64(n1) << 32) | uint64(n2), true
-}
-
-func (d *dataIO) byte() (n byte, ok bool) {
- p := d.read(1)
- if len(p) < 1 {
- d.error = true
- return 0, false
- }
- return p[0], true
-}
-
-// read returns the read of the data in the buffer.
-func (d *dataIO) rest() []byte {
- r := d.p
- d.p = nil
- return r
-}
-
-// Make a string by stopping at the first NUL
-func byteString(p []byte) string {
- for i := 0; i < len(p); i++ {
- if p[i] == 0 {
- return string(p[0:i])
- }
- }
- return string(p)
-}
-
-var badData = errors.New("malformed time zone information")
-
-// LoadLocationFromTZData returns a Location with the given name
-// initialized from the IANA Time Zone database-formatted data.
-// The data should be in the format of a standard IANA time zone file
-// (for example, the content of /etc/localtime on Unix systems).
-func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
- d := dataIO{data, false}
-
- // 4-byte magic "TZif"
- if magic := d.read(4); string(magic) != "TZif" {
- return nil, badData
- }
-
- // 1-byte version, then 15 bytes of padding
- var version int
- var p []byte
- if p = d.read(16); len(p) != 16 {
- return nil, badData
- } else {
- switch p[0] {
- case 0:
- version = 1
- case '2':
- version = 2
- case '3':
- version = 3
- default:
- return nil, badData
- }
- }
-
- // six big-endian 32-bit integers:
- // number of UTC/local indicators
- // number of standard/wall indicators
- // number of leap seconds
- // number of transition times
- // number of local time zones
- // number of characters of time zone abbrev strings
- const (
- NUTCLocal = iota
- NStdWall
- NLeap
- NTime
- NZone
- NChar
- )
- var n [6]int
- for i := 0; i < 6; i++ {
- nn, ok := d.big4()
- if !ok {
- return nil, badData
- }
- if uint32(int(nn)) != nn {
- return nil, badData
- }
- n[i] = int(nn)
- }
-
- // If we have version 2 or 3, then the data is first written out
- // in a 32-bit format, then written out again in a 64-bit format.
- // Skip the 32-bit format and read the 64-bit one, as it can
- // describe a broader range of dates.
-
- is64 := false
- if version > 1 {
- // Skip the 32-bit data.
- skip := n[NTime]*4 +
- n[NTime] +
- n[NZone]*6 +
- n[NChar] +
- n[NLeap]*8 +
- n[NStdWall] +
- n[NUTCLocal]
- // Skip the version 2 header that we just read.
- skip += 4 + 16
- d.read(skip)
-
- is64 = true
-
- // Read the counts again, they can differ.
- for i := 0; i < 6; i++ {
- nn, ok := d.big4()
- if !ok {
- return nil, badData
- }
- if uint32(int(nn)) != nn {
- return nil, badData
- }
- n[i] = int(nn)
- }
- }
-
- size := 4
- if is64 {
- size = 8
- }
-
- // Transition times.
- txtimes := dataIO{d.read(n[NTime] * size), false}
-
- // Time zone indices for transition times.
- txzones := d.read(n[NTime])
-
- // Zone info structures
- zonedata := dataIO{d.read(n[NZone] * 6), false}
-
- // Time zone abbreviations.
- abbrev := d.read(n[NChar])
-
- // Leap-second time pairs
- d.read(n[NLeap] * (size + 4))
-
- // Whether tx times associated with local time types
- // are specified as standard time or wall time.
- isstd := d.read(n[NStdWall])
-
- // Whether tx times associated with local time types
- // are specified as UTC or local time.
- isutc := d.read(n[NUTCLocal])
-
- if d.error { // ran out of data
- return nil, badData
- }
-
- var extend string
- rest := d.rest()
- if len(rest) > 2 && rest[0] == '\n' && rest[len(rest)-1] == '\n' {
- extend = string(rest[1 : len(rest)-1])
- }
-
- // Now we can build up a useful data structure.
- // First the zone information.
- // utcoff[4] isdst[1] nameindex[1]
- nzone := n[NZone]
- if nzone == 0 {
- // Reject tzdata files with no zones. There's nothing useful in them.
- // This also avoids a panic later when we add and then use a fake transition (golang.org/issue/29437).
- return nil, badData
- }
- zones := make([]zone, nzone)
- for i := range zones {
- var ok bool
- var n uint32
- if n, ok = zonedata.big4(); !ok {
- return nil, badData
- }
- if uint32(int(n)) != n {
- return nil, badData
- }
- zones[i].offset = int(int32(n))
- var b byte
- if b, ok = zonedata.byte(); !ok {
- return nil, badData
- }
- zones[i].isDST = b != 0
- if b, ok = zonedata.byte(); !ok || int(b) >= len(abbrev) {
- return nil, badData
- }
- 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
- zones[i].name = name[4:]
- }
- }
- }
-
- // Now the transition time info.
- tx := make([]zoneTrans, n[NTime])
- for i := range tx {
- var n int64
- if !is64 {
- if n4, ok := txtimes.big4(); !ok {
- return nil, badData
- } else {
- n = int64(int32(n4))
- }
- } else {
- if n8, ok := txtimes.big8(); !ok {
- return nil, badData
- } else {
- n = int64(n8)
- }
- }
- tx[i].when = n
- if int(txzones[i]) >= len(zones) {
- return nil, badData
- }
- tx[i].index = txzones[i]
- if i < len(isstd) {
- tx[i].isstd = isstd[i] != 0
- }
- if i < len(isutc) {
- tx[i].isutc = isutc[i] != 0
- }
- }
-
- if len(tx) == 0 {
- // Build fake transition to cover all time.
- // This happens in fixed locations like "Etc/GMT0".
- tx = append(tx, zoneTrans{when: alpha, index: 0})
- }
-
- // Committed to succeed.
- 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.
- sec, _, _ := now()
- for i := range tx {
- if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) {
- l.cacheStart = tx[i].when
- l.cacheEnd = omega
- 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, offset, estart, eend, isDST, ok := tzset(l.extend, l.cacheStart, sec); ok {
- l.cacheStart = estart
- l.cacheEnd = eend
- // 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,
- }
- }
- }
- }
- break
- }
- }
-
- 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) {
- if len(dir) > 4 && dir[len(dir)-4:] == ".zip" {
- return loadTzinfoFromZip(dir, name)
- }
- if dir != "" {
- name = dir + "/" + name
- }
- return readFile(name)
-}
-
-// There are 500+ zoneinfo files. Rather than distribute them all
-// individually, we ship them in an uncompressed zip file.
-// Used this way, the zip file format serves as a commonly readable
-// container for the individual small files. We choose zip over tar
-// because zip files have a contiguous table of contents, making
-// individual file lookups faster, and because the per-file overhead
-// in a zip file is considerably less than tar's 512 bytes.
-
-// get4 returns the little-endian 32-bit value in b.
-func get4(b []byte) int {
- if len(b) < 4 {
- return 0
- }
- return int(b[0]) | int(b[1])<<8 | int(b[2])<<16 | int(b[3])<<24
-}
-
-// get2 returns the little-endian 16-bit value in b.
-func get2(b []byte) int {
- if len(b) < 2 {
- return 0
- }
- return int(b[0]) | int(b[1])<<8
-}
-
-// loadTzinfoFromZip returns the contents of the file with the given name
-// in the given uncompressed zip file.
-func loadTzinfoFromZip(zipfile, name string) ([]byte, error) {
- fd, err := open(zipfile)
- if err != nil {
- return nil, err
- }
- defer closefd(fd)
-
- const (
- zecheader = 0x06054b50
- zcheader = 0x02014b50
- ztailsize = 22
-
- zheadersize = 30
- zheader = 0x04034b50
- )
-
- buf := make([]byte, ztailsize)
- if err := preadn(fd, buf, -ztailsize); err != nil || get4(buf) != zecheader {
- return nil, errors.New("corrupt zip file " + zipfile)
- }
- n := get2(buf[10:])
- size := get4(buf[12:])
- off := get4(buf[16:])
-
- buf = make([]byte, size)
- if err := preadn(fd, buf, off); err != nil {
- return nil, errors.New("corrupt zip file " + zipfile)
- }
-
- for i := 0; i < n; i++ {
- // zip entry layout:
- // 0 magic[4]
- // 4 madevers[1]
- // 5 madeos[1]
- // 6 extvers[1]
- // 7 extos[1]
- // 8 flags[2]
- // 10 meth[2]
- // 12 modtime[2]
- // 14 moddate[2]
- // 16 crc[4]
- // 20 csize[4]
- // 24 uncsize[4]
- // 28 namelen[2]
- // 30 xlen[2]
- // 32 fclen[2]
- // 34 disknum[2]
- // 36 iattr[2]
- // 38 eattr[4]
- // 42 off[4]
- // 46 name[namelen]
- // 46+namelen+xlen+fclen - next header
- //
- if get4(buf) != zcheader {
- break
- }
- meth := get2(buf[10:])
- size := get4(buf[24:])
- namelen := get2(buf[28:])
- xlen := get2(buf[30:])
- fclen := get2(buf[32:])
- off := get4(buf[42:])
- zname := buf[46 : 46+namelen]
- buf = buf[46+namelen+xlen+fclen:]
- if string(zname) != name {
- continue
- }
- if meth != 0 {
- return nil, errors.New("unsupported compression for " + name + " in " + zipfile)
- }
-
- // zip per-file header layout:
- // 0 magic[4]
- // 4 extvers[1]
- // 5 extos[1]
- // 6 flags[2]
- // 8 meth[2]
- // 10 modtime[2]
- // 12 moddate[2]
- // 14 crc[4]
- // 18 csize[4]
- // 22 uncsize[4]
- // 26 namelen[2]
- // 28 xlen[2]
- // 30 name[namelen]
- // 30+namelen+xlen - file data
- //
- buf = make([]byte, zheadersize+namelen)
- if err := preadn(fd, buf, off); err != nil ||
- get4(buf) != zheader ||
- get2(buf[8:]) != meth ||
- get2(buf[26:]) != namelen ||
- string(buf[30:30+namelen]) != name {
- return nil, errors.New("corrupt zip file " + zipfile)
- }
- xlen = get2(buf[28:])
-
- buf = make([]byte, size)
- if err := preadn(fd, buf, off+30+namelen+xlen); err != nil {
- return nil, errors.New("corrupt zip file " + zipfile)
- }
-
- return buf, nil
- }
-
- return nil, syscall.ENOENT
-}
-
-// loadTzinfoFromTzdata returns the time zone information of the time zone
-// with the given name, from a tzdata database file as they are typically
-// found on android.
-var loadTzinfoFromTzdata func(file, name string) ([]byte, error)
-
-// loadTzinfo returns the time zone information of the time zone
-// with the given name, from a given source. A source may be a
-// timezone database directory, tzdata database file or an uncompressed
-// zip file, containing the contents of such a directory.
-func loadTzinfo(name string, source string) ([]byte, error) {
- if len(source) >= 6 && source[len(source)-6:] == "tzdata" {
- return loadTzinfoFromTzdata(source, name)
- }
- return loadTzinfoFromDirOrZip(source, name)
-}
-
-// loadLocation returns the Location with the given name from one of
-// the specified sources. See loadTzinfo for a list of supported sources.
-// The first timezone data matching the given name that is successfully loaded
-// and parsed is returned as a Location.
-func loadLocation(name string, sources []string) (z *Location, firstErr error) {
- for _, source := range sources {
- zoneData, err := loadTzinfo(name, source)
- if err == nil {
- if z, err = LoadLocationFromTZData(name, zoneData); err == nil {
- return z, nil
- }
- }
- if firstErr == nil && err != syscall.ENOENT {
- firstErr = err
- }
- }
- if loadFromEmbeddedTZData != nil {
- zoneData, err := loadFromEmbeddedTZData(name)
- if err == nil {
- if z, err = LoadLocationFromTZData(name, []byte(zoneData)); err == nil {
- return z, nil
- }
- }
- if firstErr == nil && err != syscall.ENOENT {
- firstErr = err
- }
- }
- if source, ok := gorootZoneSource(runtime.GOROOT()); ok {
- zoneData, err := loadTzinfo(name, source)
- if err == nil {
- if z, err = LoadLocationFromTZData(name, zoneData); err == nil {
- return z, nil
- }
- }
- if firstErr == nil && err != syscall.ENOENT {
- firstErr = err
- }
- }
- if firstErr != nil {
- return nil, firstErr
- }
- return nil, errors.New("unknown time zone " + name)
-}
-
-// readFile reads and returns the content of the named file.
-// It is a trivial implementation of os.ReadFile, reimplemented
-// here to avoid depending on io/ioutil or os.
-// It returns an error if name exceeds maxFileSize bytes.
-func readFile(name string) ([]byte, error) {
- f, err := open(name)
- if err != nil {
- return nil, err
- }
- defer closefd(f)
- var (
- buf [4096]byte
- ret []byte
- n int
- )
- for {
- n, err = read(f, buf[:])
- if n > 0 {
- ret = append(ret, buf[:n]...)
- }
- if n == 0 || err != nil {
- break
- }
- if len(ret) > maxFileSize {
- return nil, fileSizeError(name)
- }
- }
- return ret, err
-}
diff --git a/contrib/go/_std_1.20/src/time/zoneinfo_unix.go b/contrib/go/_std_1.20/src/time/zoneinfo_unix.go
deleted file mode 100644
index 67b8beb47b..0000000000
--- a/contrib/go/_std_1.20/src/time/zoneinfo_unix.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2009 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.
-
-//go:build unix && !ios && !android
-
-// Parse "zoneinfo" time zone file.
-// This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others.
-// See tzfile(5), https://en.wikipedia.org/wiki/Zoneinfo,
-// and ftp://munnari.oz.au/pub/oldtz/
-
-package time
-
-import (
- "syscall"
-)
-
-// Many systems use /usr/share/zoneinfo, Solaris 2 has
-// /usr/share/lib/zoneinfo, IRIX 6 has /usr/lib/locale/TZ.
-var platformZoneSources = []string{
- "/usr/share/zoneinfo/",
- "/usr/share/lib/zoneinfo/",
- "/usr/lib/locale/TZ/",
-}
-
-func initLocal() {
- // consult $TZ to find the time zone to use.
- // no $TZ means use the system default /etc/localtime.
- // $TZ="" means use UTC.
- // $TZ="foo" or $TZ=":foo" if foo is an absolute path, then the file pointed
- // by foo will be used to initialize timezone; otherwise, file
- // /usr/share/zoneinfo/foo will be used.
-
- tz, ok := syscall.Getenv("TZ")
- switch {
- case !ok:
- z, err := loadLocation("localtime", []string{"/etc"})
- if err == nil {
- localLoc = *z
- localLoc.name = "Local"
- return
- }
- case tz != "":
- if tz[0] == ':' {
- tz = tz[1:]
- }
- if tz != "" && tz[0] == '/' {
- if z, err := loadLocation(tz, []string{""}); err == nil {
- localLoc = *z
- if tz == "/etc/localtime" {
- localLoc.name = "Local"
- } else {
- localLoc.name = tz
- }
- return
- }
- } else if tz != "" && tz != "UTC" {
- if z, err := loadLocation(tz, platformZoneSources); err == nil {
- localLoc = *z
- return
- }
- }
- }
-
- // Fall back to UTC.
- localLoc.name = "UTC"
-}
diff --git a/contrib/go/_std_1.20/src/unicode/tables.go b/contrib/go/_std_1.20/src/unicode/tables.go
deleted file mode 100644
index a9b23bfacd..0000000000
--- a/contrib/go/_std_1.20/src/unicode/tables.go
+++ /dev/null
@@ -1,8054 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-package unicode
-
-// Version is the Unicode edition from which the tables are derived.
-const Version = "13.0.0"
-
-// Categories is the set of Unicode category tables.
-var Categories = map[string]*RangeTable{
- "C": C,
- "Cc": Cc,
- "Cf": Cf,
- "Co": Co,
- "Cs": Cs,
- "L": L,
- "Ll": Ll,
- "Lm": Lm,
- "Lo": Lo,
- "Lt": Lt,
- "Lu": Lu,
- "M": M,
- "Mc": Mc,
- "Me": Me,
- "Mn": Mn,
- "N": N,
- "Nd": Nd,
- "Nl": Nl,
- "No": No,
- "P": P,
- "Pc": Pc,
- "Pd": Pd,
- "Pe": Pe,
- "Pf": Pf,
- "Pi": Pi,
- "Po": Po,
- "Ps": Ps,
- "S": S,
- "Sc": Sc,
- "Sk": Sk,
- "Sm": Sm,
- "So": So,
- "Z": Z,
- "Zl": Zl,
- "Zp": Zp,
- "Zs": Zs,
-}
-
-var _C = &RangeTable{
- R16: []Range16{
- {0x0000, 0x001f, 1},
- {0x007f, 0x009f, 1},
- {0x00ad, 0x0600, 1363},
- {0x0601, 0x0605, 1},
- {0x061c, 0x06dd, 193},
- {0x070f, 0x08e2, 467},
- {0x180e, 0x200b, 2045},
- {0x200c, 0x200f, 1},
- {0x202a, 0x202e, 1},
- {0x2060, 0x2064, 1},
- {0x2066, 0x206f, 1},
- {0xd800, 0xf8ff, 1},
- {0xfeff, 0xfff9, 250},
- {0xfffa, 0xfffb, 1},
- },
- R32: []Range32{
- {0x110bd, 0x110cd, 16},
- {0x13430, 0x13438, 1},
- {0x1bca0, 0x1bca3, 1},
- {0x1d173, 0x1d17a, 1},
- {0xe0001, 0xe0020, 31},
- {0xe0021, 0xe007f, 1},
- {0xf0000, 0xffffd, 1},
- {0x100000, 0x10fffd, 1},
- },
- LatinOffset: 2,
-}
-
-var _Cc = &RangeTable{
- R16: []Range16{
- {0x0000, 0x001f, 1},
- {0x007f, 0x009f, 1},
- },
- LatinOffset: 2,
-}
-
-var _Cf = &RangeTable{
- R16: []Range16{
- {0x00ad, 0x0600, 1363},
- {0x0601, 0x0605, 1},
- {0x061c, 0x06dd, 193},
- {0x070f, 0x08e2, 467},
- {0x180e, 0x200b, 2045},
- {0x200c, 0x200f, 1},
- {0x202a, 0x202e, 1},
- {0x2060, 0x2064, 1},
- {0x2066, 0x206f, 1},
- {0xfeff, 0xfff9, 250},
- {0xfffa, 0xfffb, 1},
- },
- R32: []Range32{
- {0x110bd, 0x110cd, 16},
- {0x13430, 0x13438, 1},
- {0x1bca0, 0x1bca3, 1},
- {0x1d173, 0x1d17a, 1},
- {0xe0001, 0xe0020, 31},
- {0xe0021, 0xe007f, 1},
- },
-}
-
-var _Co = &RangeTable{
- R16: []Range16{
- {0xe000, 0xf8ff, 1},
- },
- R32: []Range32{
- {0xf0000, 0xffffd, 1},
- {0x100000, 0x10fffd, 1},
- },
-}
-
-var _Cs = &RangeTable{
- R16: []Range16{
- {0xd800, 0xdfff, 1},
- },
-}
-
-var _L = &RangeTable{
- R16: []Range16{
- {0x0041, 0x005a, 1},
- {0x0061, 0x007a, 1},
- {0x00aa, 0x00b5, 11},
- {0x00ba, 0x00c0, 6},
- {0x00c1, 0x00d6, 1},
- {0x00d8, 0x00f6, 1},
- {0x00f8, 0x02c1, 1},
- {0x02c6, 0x02d1, 1},
- {0x02e0, 0x02e4, 1},
- {0x02ec, 0x02ee, 2},
- {0x0370, 0x0374, 1},
- {0x0376, 0x0377, 1},
- {0x037a, 0x037d, 1},
- {0x037f, 0x0386, 7},
- {0x0388, 0x038a, 1},
- {0x038c, 0x038e, 2},
- {0x038f, 0x03a1, 1},
- {0x03a3, 0x03f5, 1},
- {0x03f7, 0x0481, 1},
- {0x048a, 0x052f, 1},
- {0x0531, 0x0556, 1},
- {0x0559, 0x0560, 7},
- {0x0561, 0x0588, 1},
- {0x05d0, 0x05ea, 1},
- {0x05ef, 0x05f2, 1},
- {0x0620, 0x064a, 1},
- {0x066e, 0x066f, 1},
- {0x0671, 0x06d3, 1},
- {0x06d5, 0x06e5, 16},
- {0x06e6, 0x06ee, 8},
- {0x06ef, 0x06fa, 11},
- {0x06fb, 0x06fc, 1},
- {0x06ff, 0x0710, 17},
- {0x0712, 0x072f, 1},
- {0x074d, 0x07a5, 1},
- {0x07b1, 0x07ca, 25},
- {0x07cb, 0x07ea, 1},
- {0x07f4, 0x07f5, 1},
- {0x07fa, 0x0800, 6},
- {0x0801, 0x0815, 1},
- {0x081a, 0x0824, 10},
- {0x0828, 0x0840, 24},
- {0x0841, 0x0858, 1},
- {0x0860, 0x086a, 1},
- {0x08a0, 0x08b4, 1},
- {0x08b6, 0x08c7, 1},
- {0x0904, 0x0939, 1},
- {0x093d, 0x0950, 19},
- {0x0958, 0x0961, 1},
- {0x0971, 0x0980, 1},
- {0x0985, 0x098c, 1},
- {0x098f, 0x0990, 1},
- {0x0993, 0x09a8, 1},
- {0x09aa, 0x09b0, 1},
- {0x09b2, 0x09b6, 4},
- {0x09b7, 0x09b9, 1},
- {0x09bd, 0x09ce, 17},
- {0x09dc, 0x09dd, 1},
- {0x09df, 0x09e1, 1},
- {0x09f0, 0x09f1, 1},
- {0x09fc, 0x0a05, 9},
- {0x0a06, 0x0a0a, 1},
- {0x0a0f, 0x0a10, 1},
- {0x0a13, 0x0a28, 1},
- {0x0a2a, 0x0a30, 1},
- {0x0a32, 0x0a33, 1},
- {0x0a35, 0x0a36, 1},
- {0x0a38, 0x0a39, 1},
- {0x0a59, 0x0a5c, 1},
- {0x0a5e, 0x0a72, 20},
- {0x0a73, 0x0a74, 1},
- {0x0a85, 0x0a8d, 1},
- {0x0a8f, 0x0a91, 1},
- {0x0a93, 0x0aa8, 1},
- {0x0aaa, 0x0ab0, 1},
- {0x0ab2, 0x0ab3, 1},
- {0x0ab5, 0x0ab9, 1},
- {0x0abd, 0x0ad0, 19},
- {0x0ae0, 0x0ae1, 1},
- {0x0af9, 0x0b05, 12},
- {0x0b06, 0x0b0c, 1},
- {0x0b0f, 0x0b10, 1},
- {0x0b13, 0x0b28, 1},
- {0x0b2a, 0x0b30, 1},
- {0x0b32, 0x0b33, 1},
- {0x0b35, 0x0b39, 1},
- {0x0b3d, 0x0b5c, 31},
- {0x0b5d, 0x0b5f, 2},
- {0x0b60, 0x0b61, 1},
- {0x0b71, 0x0b83, 18},
- {0x0b85, 0x0b8a, 1},
- {0x0b8e, 0x0b90, 1},
- {0x0b92, 0x0b95, 1},
- {0x0b99, 0x0b9a, 1},
- {0x0b9c, 0x0b9e, 2},
- {0x0b9f, 0x0ba3, 4},
- {0x0ba4, 0x0ba8, 4},
- {0x0ba9, 0x0baa, 1},
- {0x0bae, 0x0bb9, 1},
- {0x0bd0, 0x0c05, 53},
- {0x0c06, 0x0c0c, 1},
- {0x0c0e, 0x0c10, 1},
- {0x0c12, 0x0c28, 1},
- {0x0c2a, 0x0c39, 1},
- {0x0c3d, 0x0c58, 27},
- {0x0c59, 0x0c5a, 1},
- {0x0c60, 0x0c61, 1},
- {0x0c80, 0x0c85, 5},
- {0x0c86, 0x0c8c, 1},
- {0x0c8e, 0x0c90, 1},
- {0x0c92, 0x0ca8, 1},
- {0x0caa, 0x0cb3, 1},
- {0x0cb5, 0x0cb9, 1},
- {0x0cbd, 0x0cde, 33},
- {0x0ce0, 0x0ce1, 1},
- {0x0cf1, 0x0cf2, 1},
- {0x0d04, 0x0d0c, 1},
- {0x0d0e, 0x0d10, 1},
- {0x0d12, 0x0d3a, 1},
- {0x0d3d, 0x0d4e, 17},
- {0x0d54, 0x0d56, 1},
- {0x0d5f, 0x0d61, 1},
- {0x0d7a, 0x0d7f, 1},
- {0x0d85, 0x0d96, 1},
- {0x0d9a, 0x0db1, 1},
- {0x0db3, 0x0dbb, 1},
- {0x0dbd, 0x0dc0, 3},
- {0x0dc1, 0x0dc6, 1},
- {0x0e01, 0x0e30, 1},
- {0x0e32, 0x0e33, 1},
- {0x0e40, 0x0e46, 1},
- {0x0e81, 0x0e82, 1},
- {0x0e84, 0x0e86, 2},
- {0x0e87, 0x0e8a, 1},
- {0x0e8c, 0x0ea3, 1},
- {0x0ea5, 0x0ea7, 2},
- {0x0ea8, 0x0eb0, 1},
- {0x0eb2, 0x0eb3, 1},
- {0x0ebd, 0x0ec0, 3},
- {0x0ec1, 0x0ec4, 1},
- {0x0ec6, 0x0edc, 22},
- {0x0edd, 0x0edf, 1},
- {0x0f00, 0x0f40, 64},
- {0x0f41, 0x0f47, 1},
- {0x0f49, 0x0f6c, 1},
- {0x0f88, 0x0f8c, 1},
- {0x1000, 0x102a, 1},
- {0x103f, 0x1050, 17},
- {0x1051, 0x1055, 1},
- {0x105a, 0x105d, 1},
- {0x1061, 0x1065, 4},
- {0x1066, 0x106e, 8},
- {0x106f, 0x1070, 1},
- {0x1075, 0x1081, 1},
- {0x108e, 0x10a0, 18},
- {0x10a1, 0x10c5, 1},
- {0x10c7, 0x10cd, 6},
- {0x10d0, 0x10fa, 1},
- {0x10fc, 0x1248, 1},
- {0x124a, 0x124d, 1},
- {0x1250, 0x1256, 1},
- {0x1258, 0x125a, 2},
- {0x125b, 0x125d, 1},
- {0x1260, 0x1288, 1},
- {0x128a, 0x128d, 1},
- {0x1290, 0x12b0, 1},
- {0x12b2, 0x12b5, 1},
- {0x12b8, 0x12be, 1},
- {0x12c0, 0x12c2, 2},
- {0x12c3, 0x12c5, 1},
- {0x12c8, 0x12d6, 1},
- {0x12d8, 0x1310, 1},
- {0x1312, 0x1315, 1},
- {0x1318, 0x135a, 1},
- {0x1380, 0x138f, 1},
- {0x13a0, 0x13f5, 1},
- {0x13f8, 0x13fd, 1},
- {0x1401, 0x166c, 1},
- {0x166f, 0x167f, 1},
- {0x1681, 0x169a, 1},
- {0x16a0, 0x16ea, 1},
- {0x16f1, 0x16f8, 1},
- {0x1700, 0x170c, 1},
- {0x170e, 0x1711, 1},
- {0x1720, 0x1731, 1},
- {0x1740, 0x1751, 1},
- {0x1760, 0x176c, 1},
- {0x176e, 0x1770, 1},
- {0x1780, 0x17b3, 1},
- {0x17d7, 0x17dc, 5},
- {0x1820, 0x1878, 1},
- {0x1880, 0x1884, 1},
- {0x1887, 0x18a8, 1},
- {0x18aa, 0x18b0, 6},
- {0x18b1, 0x18f5, 1},
- {0x1900, 0x191e, 1},
- {0x1950, 0x196d, 1},
- {0x1970, 0x1974, 1},
- {0x1980, 0x19ab, 1},
- {0x19b0, 0x19c9, 1},
- {0x1a00, 0x1a16, 1},
- {0x1a20, 0x1a54, 1},
- {0x1aa7, 0x1b05, 94},
- {0x1b06, 0x1b33, 1},
- {0x1b45, 0x1b4b, 1},
- {0x1b83, 0x1ba0, 1},
- {0x1bae, 0x1baf, 1},
- {0x1bba, 0x1be5, 1},
- {0x1c00, 0x1c23, 1},
- {0x1c4d, 0x1c4f, 1},
- {0x1c5a, 0x1c7d, 1},
- {0x1c80, 0x1c88, 1},
- {0x1c90, 0x1cba, 1},
- {0x1cbd, 0x1cbf, 1},
- {0x1ce9, 0x1cec, 1},
- {0x1cee, 0x1cf3, 1},
- {0x1cf5, 0x1cf6, 1},
- {0x1cfa, 0x1d00, 6},
- {0x1d01, 0x1dbf, 1},
- {0x1e00, 0x1f15, 1},
- {0x1f18, 0x1f1d, 1},
- {0x1f20, 0x1f45, 1},
- {0x1f48, 0x1f4d, 1},
- {0x1f50, 0x1f57, 1},
- {0x1f59, 0x1f5f, 2},
- {0x1f60, 0x1f7d, 1},
- {0x1f80, 0x1fb4, 1},
- {0x1fb6, 0x1fbc, 1},
- {0x1fbe, 0x1fc2, 4},
- {0x1fc3, 0x1fc4, 1},
- {0x1fc6, 0x1fcc, 1},
- {0x1fd0, 0x1fd3, 1},
- {0x1fd6, 0x1fdb, 1},
- {0x1fe0, 0x1fec, 1},
- {0x1ff2, 0x1ff4, 1},
- {0x1ff6, 0x1ffc, 1},
- {0x2071, 0x207f, 14},
- {0x2090, 0x209c, 1},
- {0x2102, 0x2107, 5},
- {0x210a, 0x2113, 1},
- {0x2115, 0x2119, 4},
- {0x211a, 0x211d, 1},
- {0x2124, 0x212a, 2},
- {0x212b, 0x212d, 1},
- {0x212f, 0x2139, 1},
- {0x213c, 0x213f, 1},
- {0x2145, 0x2149, 1},
- {0x214e, 0x2183, 53},
- {0x2184, 0x2c00, 2684},
- {0x2c01, 0x2c2e, 1},
- {0x2c30, 0x2c5e, 1},
- {0x2c60, 0x2ce4, 1},
- {0x2ceb, 0x2cee, 1},
- {0x2cf2, 0x2cf3, 1},
- {0x2d00, 0x2d25, 1},
- {0x2d27, 0x2d2d, 6},
- {0x2d30, 0x2d67, 1},
- {0x2d6f, 0x2d80, 17},
- {0x2d81, 0x2d96, 1},
- {0x2da0, 0x2da6, 1},
- {0x2da8, 0x2dae, 1},
- {0x2db0, 0x2db6, 1},
- {0x2db8, 0x2dbe, 1},
- {0x2dc0, 0x2dc6, 1},
- {0x2dc8, 0x2dce, 1},
- {0x2dd0, 0x2dd6, 1},
- {0x2dd8, 0x2dde, 1},
- {0x2e2f, 0x3005, 470},
- {0x3006, 0x3031, 43},
- {0x3032, 0x3035, 1},
- {0x303b, 0x303c, 1},
- {0x3041, 0x3096, 1},
- {0x309d, 0x309f, 1},
- {0x30a1, 0x30fa, 1},
- {0x30fc, 0x30ff, 1},
- {0x3105, 0x312f, 1},
- {0x3131, 0x318e, 1},
- {0x31a0, 0x31bf, 1},
- {0x31f0, 0x31ff, 1},
- {0x3400, 0x4dbf, 1},
- {0x4e00, 0x9ffc, 1},
- {0xa000, 0xa48c, 1},
- {0xa4d0, 0xa4fd, 1},
- {0xa500, 0xa60c, 1},
- {0xa610, 0xa61f, 1},
- {0xa62a, 0xa62b, 1},
- {0xa640, 0xa66e, 1},
- {0xa67f, 0xa69d, 1},
- {0xa6a0, 0xa6e5, 1},
- {0xa717, 0xa71f, 1},
- {0xa722, 0xa788, 1},
- {0xa78b, 0xa7bf, 1},
- {0xa7c2, 0xa7ca, 1},
- {0xa7f5, 0xa801, 1},
- {0xa803, 0xa805, 1},
- {0xa807, 0xa80a, 1},
- {0xa80c, 0xa822, 1},
- {0xa840, 0xa873, 1},
- {0xa882, 0xa8b3, 1},
- {0xa8f2, 0xa8f7, 1},
- {0xa8fb, 0xa8fd, 2},
- {0xa8fe, 0xa90a, 12},
- {0xa90b, 0xa925, 1},
- {0xa930, 0xa946, 1},
- {0xa960, 0xa97c, 1},
- {0xa984, 0xa9b2, 1},
- {0xa9cf, 0xa9e0, 17},
- {0xa9e1, 0xa9e4, 1},
- {0xa9e6, 0xa9ef, 1},
- {0xa9fa, 0xa9fe, 1},
- {0xaa00, 0xaa28, 1},
- {0xaa40, 0xaa42, 1},
- {0xaa44, 0xaa4b, 1},
- {0xaa60, 0xaa76, 1},
- {0xaa7a, 0xaa7e, 4},
- {0xaa7f, 0xaaaf, 1},
- {0xaab1, 0xaab5, 4},
- {0xaab6, 0xaab9, 3},
- {0xaaba, 0xaabd, 1},
- {0xaac0, 0xaac2, 2},
- {0xaadb, 0xaadd, 1},
- {0xaae0, 0xaaea, 1},
- {0xaaf2, 0xaaf4, 1},
- {0xab01, 0xab06, 1},
- {0xab09, 0xab0e, 1},
- {0xab11, 0xab16, 1},
- {0xab20, 0xab26, 1},
- {0xab28, 0xab2e, 1},
- {0xab30, 0xab5a, 1},
- {0xab5c, 0xab69, 1},
- {0xab70, 0xabe2, 1},
- {0xac00, 0xd7a3, 1},
- {0xd7b0, 0xd7c6, 1},
- {0xd7cb, 0xd7fb, 1},
- {0xf900, 0xfa6d, 1},
- {0xfa70, 0xfad9, 1},
- {0xfb00, 0xfb06, 1},
- {0xfb13, 0xfb17, 1},
- {0xfb1d, 0xfb1f, 2},
- {0xfb20, 0xfb28, 1},
- {0xfb2a, 0xfb36, 1},
- {0xfb38, 0xfb3c, 1},
- {0xfb3e, 0xfb40, 2},
- {0xfb41, 0xfb43, 2},
- {0xfb44, 0xfb46, 2},
- {0xfb47, 0xfbb1, 1},
- {0xfbd3, 0xfd3d, 1},
- {0xfd50, 0xfd8f, 1},
- {0xfd92, 0xfdc7, 1},
- {0xfdf0, 0xfdfb, 1},
- {0xfe70, 0xfe74, 1},
- {0xfe76, 0xfefc, 1},
- {0xff21, 0xff3a, 1},
- {0xff41, 0xff5a, 1},
- {0xff66, 0xffbe, 1},
- {0xffc2, 0xffc7, 1},
- {0xffca, 0xffcf, 1},
- {0xffd2, 0xffd7, 1},
- {0xffda, 0xffdc, 1},
- },
- R32: []Range32{
- {0x10000, 0x1000b, 1},
- {0x1000d, 0x10026, 1},
- {0x10028, 0x1003a, 1},
- {0x1003c, 0x1003d, 1},
- {0x1003f, 0x1004d, 1},
- {0x10050, 0x1005d, 1},
- {0x10080, 0x100fa, 1},
- {0x10280, 0x1029c, 1},
- {0x102a0, 0x102d0, 1},
- {0x10300, 0x1031f, 1},
- {0x1032d, 0x10340, 1},
- {0x10342, 0x10349, 1},
- {0x10350, 0x10375, 1},
- {0x10380, 0x1039d, 1},
- {0x103a0, 0x103c3, 1},
- {0x103c8, 0x103cf, 1},
- {0x10400, 0x1049d, 1},
- {0x104b0, 0x104d3, 1},
- {0x104d8, 0x104fb, 1},
- {0x10500, 0x10527, 1},
- {0x10530, 0x10563, 1},
- {0x10600, 0x10736, 1},
- {0x10740, 0x10755, 1},
- {0x10760, 0x10767, 1},
- {0x10800, 0x10805, 1},
- {0x10808, 0x1080a, 2},
- {0x1080b, 0x10835, 1},
- {0x10837, 0x10838, 1},
- {0x1083c, 0x1083f, 3},
- {0x10840, 0x10855, 1},
- {0x10860, 0x10876, 1},
- {0x10880, 0x1089e, 1},
- {0x108e0, 0x108f2, 1},
- {0x108f4, 0x108f5, 1},
- {0x10900, 0x10915, 1},
- {0x10920, 0x10939, 1},
- {0x10980, 0x109b7, 1},
- {0x109be, 0x109bf, 1},
- {0x10a00, 0x10a10, 16},
- {0x10a11, 0x10a13, 1},
- {0x10a15, 0x10a17, 1},
- {0x10a19, 0x10a35, 1},
- {0x10a60, 0x10a7c, 1},
- {0x10a80, 0x10a9c, 1},
- {0x10ac0, 0x10ac7, 1},
- {0x10ac9, 0x10ae4, 1},
- {0x10b00, 0x10b35, 1},
- {0x10b40, 0x10b55, 1},
- {0x10b60, 0x10b72, 1},
- {0x10b80, 0x10b91, 1},
- {0x10c00, 0x10c48, 1},
- {0x10c80, 0x10cb2, 1},
- {0x10cc0, 0x10cf2, 1},
- {0x10d00, 0x10d23, 1},
- {0x10e80, 0x10ea9, 1},
- {0x10eb0, 0x10eb1, 1},
- {0x10f00, 0x10f1c, 1},
- {0x10f27, 0x10f30, 9},
- {0x10f31, 0x10f45, 1},
- {0x10fb0, 0x10fc4, 1},
- {0x10fe0, 0x10ff6, 1},
- {0x11003, 0x11037, 1},
- {0x11083, 0x110af, 1},
- {0x110d0, 0x110e8, 1},
- {0x11103, 0x11126, 1},
- {0x11144, 0x11147, 3},
- {0x11150, 0x11172, 1},
- {0x11176, 0x11183, 13},
- {0x11184, 0x111b2, 1},
- {0x111c1, 0x111c4, 1},
- {0x111da, 0x111dc, 2},
- {0x11200, 0x11211, 1},
- {0x11213, 0x1122b, 1},
- {0x11280, 0x11286, 1},
- {0x11288, 0x1128a, 2},
- {0x1128b, 0x1128d, 1},
- {0x1128f, 0x1129d, 1},
- {0x1129f, 0x112a8, 1},
- {0x112b0, 0x112de, 1},
- {0x11305, 0x1130c, 1},
- {0x1130f, 0x11310, 1},
- {0x11313, 0x11328, 1},
- {0x1132a, 0x11330, 1},
- {0x11332, 0x11333, 1},
- {0x11335, 0x11339, 1},
- {0x1133d, 0x11350, 19},
- {0x1135d, 0x11361, 1},
- {0x11400, 0x11434, 1},
- {0x11447, 0x1144a, 1},
- {0x1145f, 0x11461, 1},
- {0x11480, 0x114af, 1},
- {0x114c4, 0x114c5, 1},
- {0x114c7, 0x11580, 185},
- {0x11581, 0x115ae, 1},
- {0x115d8, 0x115db, 1},
- {0x11600, 0x1162f, 1},
- {0x11644, 0x11680, 60},
- {0x11681, 0x116aa, 1},
- {0x116b8, 0x11700, 72},
- {0x11701, 0x1171a, 1},
- {0x11800, 0x1182b, 1},
- {0x118a0, 0x118df, 1},
- {0x118ff, 0x11906, 1},
- {0x11909, 0x1190c, 3},
- {0x1190d, 0x11913, 1},
- {0x11915, 0x11916, 1},
- {0x11918, 0x1192f, 1},
- {0x1193f, 0x11941, 2},
- {0x119a0, 0x119a7, 1},
- {0x119aa, 0x119d0, 1},
- {0x119e1, 0x119e3, 2},
- {0x11a00, 0x11a0b, 11},
- {0x11a0c, 0x11a32, 1},
- {0x11a3a, 0x11a50, 22},
- {0x11a5c, 0x11a89, 1},
- {0x11a9d, 0x11ac0, 35},
- {0x11ac1, 0x11af8, 1},
- {0x11c00, 0x11c08, 1},
- {0x11c0a, 0x11c2e, 1},
- {0x11c40, 0x11c72, 50},
- {0x11c73, 0x11c8f, 1},
- {0x11d00, 0x11d06, 1},
- {0x11d08, 0x11d09, 1},
- {0x11d0b, 0x11d30, 1},
- {0x11d46, 0x11d60, 26},
- {0x11d61, 0x11d65, 1},
- {0x11d67, 0x11d68, 1},
- {0x11d6a, 0x11d89, 1},
- {0x11d98, 0x11ee0, 328},
- {0x11ee1, 0x11ef2, 1},
- {0x11fb0, 0x12000, 80},
- {0x12001, 0x12399, 1},
- {0x12480, 0x12543, 1},
- {0x13000, 0x1342e, 1},
- {0x14400, 0x14646, 1},
- {0x16800, 0x16a38, 1},
- {0x16a40, 0x16a5e, 1},
- {0x16ad0, 0x16aed, 1},
- {0x16b00, 0x16b2f, 1},
- {0x16b40, 0x16b43, 1},
- {0x16b63, 0x16b77, 1},
- {0x16b7d, 0x16b8f, 1},
- {0x16e40, 0x16e7f, 1},
- {0x16f00, 0x16f4a, 1},
- {0x16f50, 0x16f93, 67},
- {0x16f94, 0x16f9f, 1},
- {0x16fe0, 0x16fe1, 1},
- {0x16fe3, 0x17000, 29},
- {0x17001, 0x187f7, 1},
- {0x18800, 0x18cd5, 1},
- {0x18d00, 0x18d08, 1},
- {0x1b000, 0x1b11e, 1},
- {0x1b150, 0x1b152, 1},
- {0x1b164, 0x1b167, 1},
- {0x1b170, 0x1b2fb, 1},
- {0x1bc00, 0x1bc6a, 1},
- {0x1bc70, 0x1bc7c, 1},
- {0x1bc80, 0x1bc88, 1},
- {0x1bc90, 0x1bc99, 1},
- {0x1d400, 0x1d454, 1},
- {0x1d456, 0x1d49c, 1},
- {0x1d49e, 0x1d49f, 1},
- {0x1d4a2, 0x1d4a5, 3},
- {0x1d4a6, 0x1d4a9, 3},
- {0x1d4aa, 0x1d4ac, 1},
- {0x1d4ae, 0x1d4b9, 1},
- {0x1d4bb, 0x1d4bd, 2},
- {0x1d4be, 0x1d4c3, 1},
- {0x1d4c5, 0x1d505, 1},
- {0x1d507, 0x1d50a, 1},
- {0x1d50d, 0x1d514, 1},
- {0x1d516, 0x1d51c, 1},
- {0x1d51e, 0x1d539, 1},
- {0x1d53b, 0x1d53e, 1},
- {0x1d540, 0x1d544, 1},
- {0x1d546, 0x1d54a, 4},
- {0x1d54b, 0x1d550, 1},
- {0x1d552, 0x1d6a5, 1},
- {0x1d6a8, 0x1d6c0, 1},
- {0x1d6c2, 0x1d6da, 1},
- {0x1d6dc, 0x1d6fa, 1},
- {0x1d6fc, 0x1d714, 1},
- {0x1d716, 0x1d734, 1},
- {0x1d736, 0x1d74e, 1},
- {0x1d750, 0x1d76e, 1},
- {0x1d770, 0x1d788, 1},
- {0x1d78a, 0x1d7a8, 1},
- {0x1d7aa, 0x1d7c2, 1},
- {0x1d7c4, 0x1d7cb, 1},
- {0x1e100, 0x1e12c, 1},
- {0x1e137, 0x1e13d, 1},
- {0x1e14e, 0x1e2c0, 370},
- {0x1e2c1, 0x1e2eb, 1},
- {0x1e800, 0x1e8c4, 1},
- {0x1e900, 0x1e943, 1},
- {0x1e94b, 0x1ee00, 1205},
- {0x1ee01, 0x1ee03, 1},
- {0x1ee05, 0x1ee1f, 1},
- {0x1ee21, 0x1ee22, 1},
- {0x1ee24, 0x1ee27, 3},
- {0x1ee29, 0x1ee32, 1},
- {0x1ee34, 0x1ee37, 1},
- {0x1ee39, 0x1ee3b, 2},
- {0x1ee42, 0x1ee47, 5},
- {0x1ee49, 0x1ee4d, 2},
- {0x1ee4e, 0x1ee4f, 1},
- {0x1ee51, 0x1ee52, 1},
- {0x1ee54, 0x1ee57, 3},
- {0x1ee59, 0x1ee61, 2},
- {0x1ee62, 0x1ee64, 2},
- {0x1ee67, 0x1ee6a, 1},
- {0x1ee6c, 0x1ee72, 1},
- {0x1ee74, 0x1ee77, 1},
- {0x1ee79, 0x1ee7c, 1},
- {0x1ee7e, 0x1ee80, 2},
- {0x1ee81, 0x1ee89, 1},
- {0x1ee8b, 0x1ee9b, 1},
- {0x1eea1, 0x1eea3, 1},
- {0x1eea5, 0x1eea9, 1},
- {0x1eeab, 0x1eebb, 1},
- {0x20000, 0x2a6dd, 1},
- {0x2a700, 0x2b734, 1},
- {0x2b740, 0x2b81d, 1},
- {0x2b820, 0x2cea1, 1},
- {0x2ceb0, 0x2ebe0, 1},
- {0x2f800, 0x2fa1d, 1},
- {0x30000, 0x3134a, 1},
- },
- LatinOffset: 6,
-}
-
-var _Ll = &RangeTable{
- R16: []Range16{
- {0x0061, 0x007a, 1},
- {0x00b5, 0x00df, 42},
- {0x00e0, 0x00f6, 1},
- {0x00f8, 0x00ff, 1},
- {0x0101, 0x0137, 2},
- {0x0138, 0x0148, 2},
- {0x0149, 0x0177, 2},
- {0x017a, 0x017e, 2},
- {0x017f, 0x0180, 1},
- {0x0183, 0x0185, 2},
- {0x0188, 0x018c, 4},
- {0x018d, 0x0192, 5},
- {0x0195, 0x0199, 4},
- {0x019a, 0x019b, 1},
- {0x019e, 0x01a1, 3},
- {0x01a3, 0x01a5, 2},
- {0x01a8, 0x01aa, 2},
- {0x01ab, 0x01ad, 2},
- {0x01b0, 0x01b4, 4},
- {0x01b6, 0x01b9, 3},
- {0x01ba, 0x01bd, 3},
- {0x01be, 0x01bf, 1},
- {0x01c6, 0x01cc, 3},
- {0x01ce, 0x01dc, 2},
- {0x01dd, 0x01ef, 2},
- {0x01f0, 0x01f3, 3},
- {0x01f5, 0x01f9, 4},
- {0x01fb, 0x0233, 2},
- {0x0234, 0x0239, 1},
- {0x023c, 0x023f, 3},
- {0x0240, 0x0242, 2},
- {0x0247, 0x024f, 2},
- {0x0250, 0x0293, 1},
- {0x0295, 0x02af, 1},
- {0x0371, 0x0373, 2},
- {0x0377, 0x037b, 4},
- {0x037c, 0x037d, 1},
- {0x0390, 0x03ac, 28},
- {0x03ad, 0x03ce, 1},
- {0x03d0, 0x03d1, 1},
- {0x03d5, 0x03d7, 1},
- {0x03d9, 0x03ef, 2},
- {0x03f0, 0x03f3, 1},
- {0x03f5, 0x03fb, 3},
- {0x03fc, 0x0430, 52},
- {0x0431, 0x045f, 1},
- {0x0461, 0x0481, 2},
- {0x048b, 0x04bf, 2},
- {0x04c2, 0x04ce, 2},
- {0x04cf, 0x052f, 2},
- {0x0560, 0x0588, 1},
- {0x10d0, 0x10fa, 1},
- {0x10fd, 0x10ff, 1},
- {0x13f8, 0x13fd, 1},
- {0x1c80, 0x1c88, 1},
- {0x1d00, 0x1d2b, 1},
- {0x1d6b, 0x1d77, 1},
- {0x1d79, 0x1d9a, 1},
- {0x1e01, 0x1e95, 2},
- {0x1e96, 0x1e9d, 1},
- {0x1e9f, 0x1eff, 2},
- {0x1f00, 0x1f07, 1},
- {0x1f10, 0x1f15, 1},
- {0x1f20, 0x1f27, 1},
- {0x1f30, 0x1f37, 1},
- {0x1f40, 0x1f45, 1},
- {0x1f50, 0x1f57, 1},
- {0x1f60, 0x1f67, 1},
- {0x1f70, 0x1f7d, 1},
- {0x1f80, 0x1f87, 1},
- {0x1f90, 0x1f97, 1},
- {0x1fa0, 0x1fa7, 1},
- {0x1fb0, 0x1fb4, 1},
- {0x1fb6, 0x1fb7, 1},
- {0x1fbe, 0x1fc2, 4},
- {0x1fc3, 0x1fc4, 1},
- {0x1fc6, 0x1fc7, 1},
- {0x1fd0, 0x1fd3, 1},
- {0x1fd6, 0x1fd7, 1},
- {0x1fe0, 0x1fe7, 1},
- {0x1ff2, 0x1ff4, 1},
- {0x1ff6, 0x1ff7, 1},
- {0x210a, 0x210e, 4},
- {0x210f, 0x2113, 4},
- {0x212f, 0x2139, 5},
- {0x213c, 0x213d, 1},
- {0x2146, 0x2149, 1},
- {0x214e, 0x2184, 54},
- {0x2c30, 0x2c5e, 1},
- {0x2c61, 0x2c65, 4},
- {0x2c66, 0x2c6c, 2},
- {0x2c71, 0x2c73, 2},
- {0x2c74, 0x2c76, 2},
- {0x2c77, 0x2c7b, 1},
- {0x2c81, 0x2ce3, 2},
- {0x2ce4, 0x2cec, 8},
- {0x2cee, 0x2cf3, 5},
- {0x2d00, 0x2d25, 1},
- {0x2d27, 0x2d2d, 6},
- {0xa641, 0xa66d, 2},
- {0xa681, 0xa69b, 2},
- {0xa723, 0xa72f, 2},
- {0xa730, 0xa731, 1},
- {0xa733, 0xa771, 2},
- {0xa772, 0xa778, 1},
- {0xa77a, 0xa77c, 2},
- {0xa77f, 0xa787, 2},
- {0xa78c, 0xa78e, 2},
- {0xa791, 0xa793, 2},
- {0xa794, 0xa795, 1},
- {0xa797, 0xa7a9, 2},
- {0xa7af, 0xa7b5, 6},
- {0xa7b7, 0xa7bf, 2},
- {0xa7c3, 0xa7c8, 5},
- {0xa7ca, 0xa7f6, 44},
- {0xa7fa, 0xab30, 822},
- {0xab31, 0xab5a, 1},
- {0xab60, 0xab68, 1},
- {0xab70, 0xabbf, 1},
- {0xfb00, 0xfb06, 1},
- {0xfb13, 0xfb17, 1},
- {0xff41, 0xff5a, 1},
- },
- R32: []Range32{
- {0x10428, 0x1044f, 1},
- {0x104d8, 0x104fb, 1},
- {0x10cc0, 0x10cf2, 1},
- {0x118c0, 0x118df, 1},
- {0x16e60, 0x16e7f, 1},
- {0x1d41a, 0x1d433, 1},
- {0x1d44e, 0x1d454, 1},
- {0x1d456, 0x1d467, 1},
- {0x1d482, 0x1d49b, 1},
- {0x1d4b6, 0x1d4b9, 1},
- {0x1d4bb, 0x1d4bd, 2},
- {0x1d4be, 0x1d4c3, 1},
- {0x1d4c5, 0x1d4cf, 1},
- {0x1d4ea, 0x1d503, 1},
- {0x1d51e, 0x1d537, 1},
- {0x1d552, 0x1d56b, 1},
- {0x1d586, 0x1d59f, 1},
- {0x1d5ba, 0x1d5d3, 1},
- {0x1d5ee, 0x1d607, 1},
- {0x1d622, 0x1d63b, 1},
- {0x1d656, 0x1d66f, 1},
- {0x1d68a, 0x1d6a5, 1},
- {0x1d6c2, 0x1d6da, 1},
- {0x1d6dc, 0x1d6e1, 1},
- {0x1d6fc, 0x1d714, 1},
- {0x1d716, 0x1d71b, 1},
- {0x1d736, 0x1d74e, 1},
- {0x1d750, 0x1d755, 1},
- {0x1d770, 0x1d788, 1},
- {0x1d78a, 0x1d78f, 1},
- {0x1d7aa, 0x1d7c2, 1},
- {0x1d7c4, 0x1d7c9, 1},
- {0x1d7cb, 0x1e922, 4439},
- {0x1e923, 0x1e943, 1},
- },
- LatinOffset: 4,
-}
-
-var _Lm = &RangeTable{
- R16: []Range16{
- {0x02b0, 0x02c1, 1},
- {0x02c6, 0x02d1, 1},
- {0x02e0, 0x02e4, 1},
- {0x02ec, 0x02ee, 2},
- {0x0374, 0x037a, 6},
- {0x0559, 0x0640, 231},
- {0x06e5, 0x06e6, 1},
- {0x07f4, 0x07f5, 1},
- {0x07fa, 0x081a, 32},
- {0x0824, 0x0828, 4},
- {0x0971, 0x0e46, 1237},
- {0x0ec6, 0x10fc, 566},
- {0x17d7, 0x1843, 108},
- {0x1aa7, 0x1c78, 465},
- {0x1c79, 0x1c7d, 1},
- {0x1d2c, 0x1d6a, 1},
- {0x1d78, 0x1d9b, 35},
- {0x1d9c, 0x1dbf, 1},
- {0x2071, 0x207f, 14},
- {0x2090, 0x209c, 1},
- {0x2c7c, 0x2c7d, 1},
- {0x2d6f, 0x2e2f, 192},
- {0x3005, 0x3031, 44},
- {0x3032, 0x3035, 1},
- {0x303b, 0x309d, 98},
- {0x309e, 0x30fc, 94},
- {0x30fd, 0x30fe, 1},
- {0xa015, 0xa4f8, 1251},
- {0xa4f9, 0xa4fd, 1},
- {0xa60c, 0xa67f, 115},
- {0xa69c, 0xa69d, 1},
- {0xa717, 0xa71f, 1},
- {0xa770, 0xa788, 24},
- {0xa7f8, 0xa7f9, 1},
- {0xa9cf, 0xa9e6, 23},
- {0xaa70, 0xaadd, 109},
- {0xaaf3, 0xaaf4, 1},
- {0xab5c, 0xab5f, 1},
- {0xab69, 0xff70, 21511},
- {0xff9e, 0xff9f, 1},
- },
- R32: []Range32{
- {0x16b40, 0x16b43, 1},
- {0x16f93, 0x16f9f, 1},
- {0x16fe0, 0x16fe1, 1},
- {0x16fe3, 0x1e137, 29012},
- {0x1e138, 0x1e13d, 1},
- {0x1e94b, 0x1e94b, 1},
- },
-}
-
-var _Lo = &RangeTable{
- R16: []Range16{
- {0x00aa, 0x00ba, 16},
- {0x01bb, 0x01c0, 5},
- {0x01c1, 0x01c3, 1},
- {0x0294, 0x05d0, 828},
- {0x05d1, 0x05ea, 1},
- {0x05ef, 0x05f2, 1},
- {0x0620, 0x063f, 1},
- {0x0641, 0x064a, 1},
- {0x066e, 0x066f, 1},
- {0x0671, 0x06d3, 1},
- {0x06d5, 0x06ee, 25},
- {0x06ef, 0x06fa, 11},
- {0x06fb, 0x06fc, 1},
- {0x06ff, 0x0710, 17},
- {0x0712, 0x072f, 1},
- {0x074d, 0x07a5, 1},
- {0x07b1, 0x07ca, 25},
- {0x07cb, 0x07ea, 1},
- {0x0800, 0x0815, 1},
- {0x0840, 0x0858, 1},
- {0x0860, 0x086a, 1},
- {0x08a0, 0x08b4, 1},
- {0x08b6, 0x08c7, 1},
- {0x0904, 0x0939, 1},
- {0x093d, 0x0950, 19},
- {0x0958, 0x0961, 1},
- {0x0972, 0x0980, 1},
- {0x0985, 0x098c, 1},
- {0x098f, 0x0990, 1},
- {0x0993, 0x09a8, 1},
- {0x09aa, 0x09b0, 1},
- {0x09b2, 0x09b6, 4},
- {0x09b7, 0x09b9, 1},
- {0x09bd, 0x09ce, 17},
- {0x09dc, 0x09dd, 1},
- {0x09df, 0x09e1, 1},
- {0x09f0, 0x09f1, 1},
- {0x09fc, 0x0a05, 9},
- {0x0a06, 0x0a0a, 1},
- {0x0a0f, 0x0a10, 1},
- {0x0a13, 0x0a28, 1},
- {0x0a2a, 0x0a30, 1},
- {0x0a32, 0x0a33, 1},
- {0x0a35, 0x0a36, 1},
- {0x0a38, 0x0a39, 1},
- {0x0a59, 0x0a5c, 1},
- {0x0a5e, 0x0a72, 20},
- {0x0a73, 0x0a74, 1},
- {0x0a85, 0x0a8d, 1},
- {0x0a8f, 0x0a91, 1},
- {0x0a93, 0x0aa8, 1},
- {0x0aaa, 0x0ab0, 1},
- {0x0ab2, 0x0ab3, 1},
- {0x0ab5, 0x0ab9, 1},
- {0x0abd, 0x0ad0, 19},
- {0x0ae0, 0x0ae1, 1},
- {0x0af9, 0x0b05, 12},
- {0x0b06, 0x0b0c, 1},
- {0x0b0f, 0x0b10, 1},
- {0x0b13, 0x0b28, 1},
- {0x0b2a, 0x0b30, 1},
- {0x0b32, 0x0b33, 1},
- {0x0b35, 0x0b39, 1},
- {0x0b3d, 0x0b5c, 31},
- {0x0b5d, 0x0b5f, 2},
- {0x0b60, 0x0b61, 1},
- {0x0b71, 0x0b83, 18},
- {0x0b85, 0x0b8a, 1},
- {0x0b8e, 0x0b90, 1},
- {0x0b92, 0x0b95, 1},
- {0x0b99, 0x0b9a, 1},
- {0x0b9c, 0x0b9e, 2},
- {0x0b9f, 0x0ba3, 4},
- {0x0ba4, 0x0ba8, 4},
- {0x0ba9, 0x0baa, 1},
- {0x0bae, 0x0bb9, 1},
- {0x0bd0, 0x0c05, 53},
- {0x0c06, 0x0c0c, 1},
- {0x0c0e, 0x0c10, 1},
- {0x0c12, 0x0c28, 1},
- {0x0c2a, 0x0c39, 1},
- {0x0c3d, 0x0c58, 27},
- {0x0c59, 0x0c5a, 1},
- {0x0c60, 0x0c61, 1},
- {0x0c80, 0x0c85, 5},
- {0x0c86, 0x0c8c, 1},
- {0x0c8e, 0x0c90, 1},
- {0x0c92, 0x0ca8, 1},
- {0x0caa, 0x0cb3, 1},
- {0x0cb5, 0x0cb9, 1},
- {0x0cbd, 0x0cde, 33},
- {0x0ce0, 0x0ce1, 1},
- {0x0cf1, 0x0cf2, 1},
- {0x0d04, 0x0d0c, 1},
- {0x0d0e, 0x0d10, 1},
- {0x0d12, 0x0d3a, 1},
- {0x0d3d, 0x0d4e, 17},
- {0x0d54, 0x0d56, 1},
- {0x0d5f, 0x0d61, 1},
- {0x0d7a, 0x0d7f, 1},
- {0x0d85, 0x0d96, 1},
- {0x0d9a, 0x0db1, 1},
- {0x0db3, 0x0dbb, 1},
- {0x0dbd, 0x0dc0, 3},
- {0x0dc1, 0x0dc6, 1},
- {0x0e01, 0x0e30, 1},
- {0x0e32, 0x0e33, 1},
- {0x0e40, 0x0e45, 1},
- {0x0e81, 0x0e82, 1},
- {0x0e84, 0x0e86, 2},
- {0x0e87, 0x0e8a, 1},
- {0x0e8c, 0x0ea3, 1},
- {0x0ea5, 0x0ea7, 2},
- {0x0ea8, 0x0eb0, 1},
- {0x0eb2, 0x0eb3, 1},
- {0x0ebd, 0x0ec0, 3},
- {0x0ec1, 0x0ec4, 1},
- {0x0edc, 0x0edf, 1},
- {0x0f00, 0x0f40, 64},
- {0x0f41, 0x0f47, 1},
- {0x0f49, 0x0f6c, 1},
- {0x0f88, 0x0f8c, 1},
- {0x1000, 0x102a, 1},
- {0x103f, 0x1050, 17},
- {0x1051, 0x1055, 1},
- {0x105a, 0x105d, 1},
- {0x1061, 0x1065, 4},
- {0x1066, 0x106e, 8},
- {0x106f, 0x1070, 1},
- {0x1075, 0x1081, 1},
- {0x108e, 0x1100, 114},
- {0x1101, 0x1248, 1},
- {0x124a, 0x124d, 1},
- {0x1250, 0x1256, 1},
- {0x1258, 0x125a, 2},
- {0x125b, 0x125d, 1},
- {0x1260, 0x1288, 1},
- {0x128a, 0x128d, 1},
- {0x1290, 0x12b0, 1},
- {0x12b2, 0x12b5, 1},
- {0x12b8, 0x12be, 1},
- {0x12c0, 0x12c2, 2},
- {0x12c3, 0x12c5, 1},
- {0x12c8, 0x12d6, 1},
- {0x12d8, 0x1310, 1},
- {0x1312, 0x1315, 1},
- {0x1318, 0x135a, 1},
- {0x1380, 0x138f, 1},
- {0x1401, 0x166c, 1},
- {0x166f, 0x167f, 1},
- {0x1681, 0x169a, 1},
- {0x16a0, 0x16ea, 1},
- {0x16f1, 0x16f8, 1},
- {0x1700, 0x170c, 1},
- {0x170e, 0x1711, 1},
- {0x1720, 0x1731, 1},
- {0x1740, 0x1751, 1},
- {0x1760, 0x176c, 1},
- {0x176e, 0x1770, 1},
- {0x1780, 0x17b3, 1},
- {0x17dc, 0x1820, 68},
- {0x1821, 0x1842, 1},
- {0x1844, 0x1878, 1},
- {0x1880, 0x1884, 1},
- {0x1887, 0x18a8, 1},
- {0x18aa, 0x18b0, 6},
- {0x18b1, 0x18f5, 1},
- {0x1900, 0x191e, 1},
- {0x1950, 0x196d, 1},
- {0x1970, 0x1974, 1},
- {0x1980, 0x19ab, 1},
- {0x19b0, 0x19c9, 1},
- {0x1a00, 0x1a16, 1},
- {0x1a20, 0x1a54, 1},
- {0x1b05, 0x1b33, 1},
- {0x1b45, 0x1b4b, 1},
- {0x1b83, 0x1ba0, 1},
- {0x1bae, 0x1baf, 1},
- {0x1bba, 0x1be5, 1},
- {0x1c00, 0x1c23, 1},
- {0x1c4d, 0x1c4f, 1},
- {0x1c5a, 0x1c77, 1},
- {0x1ce9, 0x1cec, 1},
- {0x1cee, 0x1cf3, 1},
- {0x1cf5, 0x1cf6, 1},
- {0x1cfa, 0x2135, 1083},
- {0x2136, 0x2138, 1},
- {0x2d30, 0x2d67, 1},
- {0x2d80, 0x2d96, 1},
- {0x2da0, 0x2da6, 1},
- {0x2da8, 0x2dae, 1},
- {0x2db0, 0x2db6, 1},
- {0x2db8, 0x2dbe, 1},
- {0x2dc0, 0x2dc6, 1},
- {0x2dc8, 0x2dce, 1},
- {0x2dd0, 0x2dd6, 1},
- {0x2dd8, 0x2dde, 1},
- {0x3006, 0x303c, 54},
- {0x3041, 0x3096, 1},
- {0x309f, 0x30a1, 2},
- {0x30a2, 0x30fa, 1},
- {0x30ff, 0x3105, 6},
- {0x3106, 0x312f, 1},
- {0x3131, 0x318e, 1},
- {0x31a0, 0x31bf, 1},
- {0x31f0, 0x31ff, 1},
- {0x3400, 0x4dbf, 1},
- {0x4e00, 0x9ffc, 1},
- {0xa000, 0xa014, 1},
- {0xa016, 0xa48c, 1},
- {0xa4d0, 0xa4f7, 1},
- {0xa500, 0xa60b, 1},
- {0xa610, 0xa61f, 1},
- {0xa62a, 0xa62b, 1},
- {0xa66e, 0xa6a0, 50},
- {0xa6a1, 0xa6e5, 1},
- {0xa78f, 0xa7f7, 104},
- {0xa7fb, 0xa801, 1},
- {0xa803, 0xa805, 1},
- {0xa807, 0xa80a, 1},
- {0xa80c, 0xa822, 1},
- {0xa840, 0xa873, 1},
- {0xa882, 0xa8b3, 1},
- {0xa8f2, 0xa8f7, 1},
- {0xa8fb, 0xa8fd, 2},
- {0xa8fe, 0xa90a, 12},
- {0xa90b, 0xa925, 1},
- {0xa930, 0xa946, 1},
- {0xa960, 0xa97c, 1},
- {0xa984, 0xa9b2, 1},
- {0xa9e0, 0xa9e4, 1},
- {0xa9e7, 0xa9ef, 1},
- {0xa9fa, 0xa9fe, 1},
- {0xaa00, 0xaa28, 1},
- {0xaa40, 0xaa42, 1},
- {0xaa44, 0xaa4b, 1},
- {0xaa60, 0xaa6f, 1},
- {0xaa71, 0xaa76, 1},
- {0xaa7a, 0xaa7e, 4},
- {0xaa7f, 0xaaaf, 1},
- {0xaab1, 0xaab5, 4},
- {0xaab6, 0xaab9, 3},
- {0xaaba, 0xaabd, 1},
- {0xaac0, 0xaac2, 2},
- {0xaadb, 0xaadc, 1},
- {0xaae0, 0xaaea, 1},
- {0xaaf2, 0xab01, 15},
- {0xab02, 0xab06, 1},
- {0xab09, 0xab0e, 1},
- {0xab11, 0xab16, 1},
- {0xab20, 0xab26, 1},
- {0xab28, 0xab2e, 1},
- {0xabc0, 0xabe2, 1},
- {0xac00, 0xd7a3, 1},
- {0xd7b0, 0xd7c6, 1},
- {0xd7cb, 0xd7fb, 1},
- {0xf900, 0xfa6d, 1},
- {0xfa70, 0xfad9, 1},
- {0xfb1d, 0xfb1f, 2},
- {0xfb20, 0xfb28, 1},
- {0xfb2a, 0xfb36, 1},
- {0xfb38, 0xfb3c, 1},
- {0xfb3e, 0xfb40, 2},
- {0xfb41, 0xfb43, 2},
- {0xfb44, 0xfb46, 2},
- {0xfb47, 0xfbb1, 1},
- {0xfbd3, 0xfd3d, 1},
- {0xfd50, 0xfd8f, 1},
- {0xfd92, 0xfdc7, 1},
- {0xfdf0, 0xfdfb, 1},
- {0xfe70, 0xfe74, 1},
- {0xfe76, 0xfefc, 1},
- {0xff66, 0xff6f, 1},
- {0xff71, 0xff9d, 1},
- {0xffa0, 0xffbe, 1},
- {0xffc2, 0xffc7, 1},
- {0xffca, 0xffcf, 1},
- {0xffd2, 0xffd7, 1},
- {0xffda, 0xffdc, 1},
- },
- R32: []Range32{
- {0x10000, 0x1000b, 1},
- {0x1000d, 0x10026, 1},
- {0x10028, 0x1003a, 1},
- {0x1003c, 0x1003d, 1},
- {0x1003f, 0x1004d, 1},
- {0x10050, 0x1005d, 1},
- {0x10080, 0x100fa, 1},
- {0x10280, 0x1029c, 1},
- {0x102a0, 0x102d0, 1},
- {0x10300, 0x1031f, 1},
- {0x1032d, 0x10340, 1},
- {0x10342, 0x10349, 1},
- {0x10350, 0x10375, 1},
- {0x10380, 0x1039d, 1},
- {0x103a0, 0x103c3, 1},
- {0x103c8, 0x103cf, 1},
- {0x10450, 0x1049d, 1},
- {0x10500, 0x10527, 1},
- {0x10530, 0x10563, 1},
- {0x10600, 0x10736, 1},
- {0x10740, 0x10755, 1},
- {0x10760, 0x10767, 1},
- {0x10800, 0x10805, 1},
- {0x10808, 0x1080a, 2},
- {0x1080b, 0x10835, 1},
- {0x10837, 0x10838, 1},
- {0x1083c, 0x1083f, 3},
- {0x10840, 0x10855, 1},
- {0x10860, 0x10876, 1},
- {0x10880, 0x1089e, 1},
- {0x108e0, 0x108f2, 1},
- {0x108f4, 0x108f5, 1},
- {0x10900, 0x10915, 1},
- {0x10920, 0x10939, 1},
- {0x10980, 0x109b7, 1},
- {0x109be, 0x109bf, 1},
- {0x10a00, 0x10a10, 16},
- {0x10a11, 0x10a13, 1},
- {0x10a15, 0x10a17, 1},
- {0x10a19, 0x10a35, 1},
- {0x10a60, 0x10a7c, 1},
- {0x10a80, 0x10a9c, 1},
- {0x10ac0, 0x10ac7, 1},
- {0x10ac9, 0x10ae4, 1},
- {0x10b00, 0x10b35, 1},
- {0x10b40, 0x10b55, 1},
- {0x10b60, 0x10b72, 1},
- {0x10b80, 0x10b91, 1},
- {0x10c00, 0x10c48, 1},
- {0x10d00, 0x10d23, 1},
- {0x10e80, 0x10ea9, 1},
- {0x10eb0, 0x10eb1, 1},
- {0x10f00, 0x10f1c, 1},
- {0x10f27, 0x10f30, 9},
- {0x10f31, 0x10f45, 1},
- {0x10fb0, 0x10fc4, 1},
- {0x10fe0, 0x10ff6, 1},
- {0x11003, 0x11037, 1},
- {0x11083, 0x110af, 1},
- {0x110d0, 0x110e8, 1},
- {0x11103, 0x11126, 1},
- {0x11144, 0x11147, 3},
- {0x11150, 0x11172, 1},
- {0x11176, 0x11183, 13},
- {0x11184, 0x111b2, 1},
- {0x111c1, 0x111c4, 1},
- {0x111da, 0x111dc, 2},
- {0x11200, 0x11211, 1},
- {0x11213, 0x1122b, 1},
- {0x11280, 0x11286, 1},
- {0x11288, 0x1128a, 2},
- {0x1128b, 0x1128d, 1},
- {0x1128f, 0x1129d, 1},
- {0x1129f, 0x112a8, 1},
- {0x112b0, 0x112de, 1},
- {0x11305, 0x1130c, 1},
- {0x1130f, 0x11310, 1},
- {0x11313, 0x11328, 1},
- {0x1132a, 0x11330, 1},
- {0x11332, 0x11333, 1},
- {0x11335, 0x11339, 1},
- {0x1133d, 0x11350, 19},
- {0x1135d, 0x11361, 1},
- {0x11400, 0x11434, 1},
- {0x11447, 0x1144a, 1},
- {0x1145f, 0x11461, 1},
- {0x11480, 0x114af, 1},
- {0x114c4, 0x114c5, 1},
- {0x114c7, 0x11580, 185},
- {0x11581, 0x115ae, 1},
- {0x115d8, 0x115db, 1},
- {0x11600, 0x1162f, 1},
- {0x11644, 0x11680, 60},
- {0x11681, 0x116aa, 1},
- {0x116b8, 0x11700, 72},
- {0x11701, 0x1171a, 1},
- {0x11800, 0x1182b, 1},
- {0x118ff, 0x11906, 1},
- {0x11909, 0x1190c, 3},
- {0x1190d, 0x11913, 1},
- {0x11915, 0x11916, 1},
- {0x11918, 0x1192f, 1},
- {0x1193f, 0x11941, 2},
- {0x119a0, 0x119a7, 1},
- {0x119aa, 0x119d0, 1},
- {0x119e1, 0x119e3, 2},
- {0x11a00, 0x11a0b, 11},
- {0x11a0c, 0x11a32, 1},
- {0x11a3a, 0x11a50, 22},
- {0x11a5c, 0x11a89, 1},
- {0x11a9d, 0x11ac0, 35},
- {0x11ac1, 0x11af8, 1},
- {0x11c00, 0x11c08, 1},
- {0x11c0a, 0x11c2e, 1},
- {0x11c40, 0x11c72, 50},
- {0x11c73, 0x11c8f, 1},
- {0x11d00, 0x11d06, 1},
- {0x11d08, 0x11d09, 1},
- {0x11d0b, 0x11d30, 1},
- {0x11d46, 0x11d60, 26},
- {0x11d61, 0x11d65, 1},
- {0x11d67, 0x11d68, 1},
- {0x11d6a, 0x11d89, 1},
- {0x11d98, 0x11ee0, 328},
- {0x11ee1, 0x11ef2, 1},
- {0x11fb0, 0x12000, 80},
- {0x12001, 0x12399, 1},
- {0x12480, 0x12543, 1},
- {0x13000, 0x1342e, 1},
- {0x14400, 0x14646, 1},
- {0x16800, 0x16a38, 1},
- {0x16a40, 0x16a5e, 1},
- {0x16ad0, 0x16aed, 1},
- {0x16b00, 0x16b2f, 1},
- {0x16b63, 0x16b77, 1},
- {0x16b7d, 0x16b8f, 1},
- {0x16f00, 0x16f4a, 1},
- {0x16f50, 0x17000, 176},
- {0x17001, 0x187f7, 1},
- {0x18800, 0x18cd5, 1},
- {0x18d00, 0x18d08, 1},
- {0x1b000, 0x1b11e, 1},
- {0x1b150, 0x1b152, 1},
- {0x1b164, 0x1b167, 1},
- {0x1b170, 0x1b2fb, 1},
- {0x1bc00, 0x1bc6a, 1},
- {0x1bc70, 0x1bc7c, 1},
- {0x1bc80, 0x1bc88, 1},
- {0x1bc90, 0x1bc99, 1},
- {0x1e100, 0x1e12c, 1},
- {0x1e14e, 0x1e2c0, 370},
- {0x1e2c1, 0x1e2eb, 1},
- {0x1e800, 0x1e8c4, 1},
- {0x1ee00, 0x1ee03, 1},
- {0x1ee05, 0x1ee1f, 1},
- {0x1ee21, 0x1ee22, 1},
- {0x1ee24, 0x1ee27, 3},
- {0x1ee29, 0x1ee32, 1},
- {0x1ee34, 0x1ee37, 1},
- {0x1ee39, 0x1ee3b, 2},
- {0x1ee42, 0x1ee47, 5},
- {0x1ee49, 0x1ee4d, 2},
- {0x1ee4e, 0x1ee4f, 1},
- {0x1ee51, 0x1ee52, 1},
- {0x1ee54, 0x1ee57, 3},
- {0x1ee59, 0x1ee61, 2},
- {0x1ee62, 0x1ee64, 2},
- {0x1ee67, 0x1ee6a, 1},
- {0x1ee6c, 0x1ee72, 1},
- {0x1ee74, 0x1ee77, 1},
- {0x1ee79, 0x1ee7c, 1},
- {0x1ee7e, 0x1ee80, 2},
- {0x1ee81, 0x1ee89, 1},
- {0x1ee8b, 0x1ee9b, 1},
- {0x1eea1, 0x1eea3, 1},
- {0x1eea5, 0x1eea9, 1},
- {0x1eeab, 0x1eebb, 1},
- {0x20000, 0x2a6dd, 1},
- {0x2a700, 0x2b734, 1},
- {0x2b740, 0x2b81d, 1},
- {0x2b820, 0x2cea1, 1},
- {0x2ceb0, 0x2ebe0, 1},
- {0x2f800, 0x2fa1d, 1},
- {0x30000, 0x3134a, 1},
- },
- LatinOffset: 1,
-}
-
-var _Lt = &RangeTable{
- R16: []Range16{
- {0x01c5, 0x01cb, 3},
- {0x01f2, 0x1f88, 7574},
- {0x1f89, 0x1f8f, 1},
- {0x1f98, 0x1f9f, 1},
- {0x1fa8, 0x1faf, 1},
- {0x1fbc, 0x1fcc, 16},
- {0x1ffc, 0x1ffc, 1},
- },
-}
-
-var _Lu = &RangeTable{
- R16: []Range16{
- {0x0041, 0x005a, 1},
- {0x00c0, 0x00d6, 1},
- {0x00d8, 0x00de, 1},
- {0x0100, 0x0136, 2},
- {0x0139, 0x0147, 2},
- {0x014a, 0x0178, 2},
- {0x0179, 0x017d, 2},
- {0x0181, 0x0182, 1},
- {0x0184, 0x0186, 2},
- {0x0187, 0x0189, 2},
- {0x018a, 0x018b, 1},
- {0x018e, 0x0191, 1},
- {0x0193, 0x0194, 1},
- {0x0196, 0x0198, 1},
- {0x019c, 0x019d, 1},
- {0x019f, 0x01a0, 1},
- {0x01a2, 0x01a6, 2},
- {0x01a7, 0x01a9, 2},
- {0x01ac, 0x01ae, 2},
- {0x01af, 0x01b1, 2},
- {0x01b2, 0x01b3, 1},
- {0x01b5, 0x01b7, 2},
- {0x01b8, 0x01bc, 4},
- {0x01c4, 0x01cd, 3},
- {0x01cf, 0x01db, 2},
- {0x01de, 0x01ee, 2},
- {0x01f1, 0x01f4, 3},
- {0x01f6, 0x01f8, 1},
- {0x01fa, 0x0232, 2},
- {0x023a, 0x023b, 1},
- {0x023d, 0x023e, 1},
- {0x0241, 0x0243, 2},
- {0x0244, 0x0246, 1},
- {0x0248, 0x024e, 2},
- {0x0370, 0x0372, 2},
- {0x0376, 0x037f, 9},
- {0x0386, 0x0388, 2},
- {0x0389, 0x038a, 1},
- {0x038c, 0x038e, 2},
- {0x038f, 0x0391, 2},
- {0x0392, 0x03a1, 1},
- {0x03a3, 0x03ab, 1},
- {0x03cf, 0x03d2, 3},
- {0x03d3, 0x03d4, 1},
- {0x03d8, 0x03ee, 2},
- {0x03f4, 0x03f7, 3},
- {0x03f9, 0x03fa, 1},
- {0x03fd, 0x042f, 1},
- {0x0460, 0x0480, 2},
- {0x048a, 0x04c0, 2},
- {0x04c1, 0x04cd, 2},
- {0x04d0, 0x052e, 2},
- {0x0531, 0x0556, 1},
- {0x10a0, 0x10c5, 1},
- {0x10c7, 0x10cd, 6},
- {0x13a0, 0x13f5, 1},
- {0x1c90, 0x1cba, 1},
- {0x1cbd, 0x1cbf, 1},
- {0x1e00, 0x1e94, 2},
- {0x1e9e, 0x1efe, 2},
- {0x1f08, 0x1f0f, 1},
- {0x1f18, 0x1f1d, 1},
- {0x1f28, 0x1f2f, 1},
- {0x1f38, 0x1f3f, 1},
- {0x1f48, 0x1f4d, 1},
- {0x1f59, 0x1f5f, 2},
- {0x1f68, 0x1f6f, 1},
- {0x1fb8, 0x1fbb, 1},
- {0x1fc8, 0x1fcb, 1},
- {0x1fd8, 0x1fdb, 1},
- {0x1fe8, 0x1fec, 1},
- {0x1ff8, 0x1ffb, 1},
- {0x2102, 0x2107, 5},
- {0x210b, 0x210d, 1},
- {0x2110, 0x2112, 1},
- {0x2115, 0x2119, 4},
- {0x211a, 0x211d, 1},
- {0x2124, 0x212a, 2},
- {0x212b, 0x212d, 1},
- {0x2130, 0x2133, 1},
- {0x213e, 0x213f, 1},
- {0x2145, 0x2183, 62},
- {0x2c00, 0x2c2e, 1},
- {0x2c60, 0x2c62, 2},
- {0x2c63, 0x2c64, 1},
- {0x2c67, 0x2c6d, 2},
- {0x2c6e, 0x2c70, 1},
- {0x2c72, 0x2c75, 3},
- {0x2c7e, 0x2c80, 1},
- {0x2c82, 0x2ce2, 2},
- {0x2ceb, 0x2ced, 2},
- {0x2cf2, 0xa640, 31054},
- {0xa642, 0xa66c, 2},
- {0xa680, 0xa69a, 2},
- {0xa722, 0xa72e, 2},
- {0xa732, 0xa76e, 2},
- {0xa779, 0xa77d, 2},
- {0xa77e, 0xa786, 2},
- {0xa78b, 0xa78d, 2},
- {0xa790, 0xa792, 2},
- {0xa796, 0xa7aa, 2},
- {0xa7ab, 0xa7ae, 1},
- {0xa7b0, 0xa7b4, 1},
- {0xa7b6, 0xa7be, 2},
- {0xa7c2, 0xa7c4, 2},
- {0xa7c5, 0xa7c7, 1},
- {0xa7c9, 0xa7f5, 44},
- {0xff21, 0xff3a, 1},
- },
- R32: []Range32{
- {0x10400, 0x10427, 1},
- {0x104b0, 0x104d3, 1},
- {0x10c80, 0x10cb2, 1},
- {0x118a0, 0x118bf, 1},
- {0x16e40, 0x16e5f, 1},
- {0x1d400, 0x1d419, 1},
- {0x1d434, 0x1d44d, 1},
- {0x1d468, 0x1d481, 1},
- {0x1d49c, 0x1d49e, 2},
- {0x1d49f, 0x1d4a5, 3},
- {0x1d4a6, 0x1d4a9, 3},
- {0x1d4aa, 0x1d4ac, 1},
- {0x1d4ae, 0x1d4b5, 1},
- {0x1d4d0, 0x1d4e9, 1},
- {0x1d504, 0x1d505, 1},
- {0x1d507, 0x1d50a, 1},
- {0x1d50d, 0x1d514, 1},
- {0x1d516, 0x1d51c, 1},
- {0x1d538, 0x1d539, 1},
- {0x1d53b, 0x1d53e, 1},
- {0x1d540, 0x1d544, 1},
- {0x1d546, 0x1d54a, 4},
- {0x1d54b, 0x1d550, 1},
- {0x1d56c, 0x1d585, 1},
- {0x1d5a0, 0x1d5b9, 1},
- {0x1d5d4, 0x1d5ed, 1},
- {0x1d608, 0x1d621, 1},
- {0x1d63c, 0x1d655, 1},
- {0x1d670, 0x1d689, 1},
- {0x1d6a8, 0x1d6c0, 1},
- {0x1d6e2, 0x1d6fa, 1},
- {0x1d71c, 0x1d734, 1},
- {0x1d756, 0x1d76e, 1},
- {0x1d790, 0x1d7a8, 1},
- {0x1d7ca, 0x1e900, 4406},
- {0x1e901, 0x1e921, 1},
- },
- LatinOffset: 3,
-}
-
-var _M = &RangeTable{
- R16: []Range16{
- {0x0300, 0x036f, 1},
- {0x0483, 0x0489, 1},
- {0x0591, 0x05bd, 1},
- {0x05bf, 0x05c1, 2},
- {0x05c2, 0x05c4, 2},
- {0x05c5, 0x05c7, 2},
- {0x0610, 0x061a, 1},
- {0x064b, 0x065f, 1},
- {0x0670, 0x06d6, 102},
- {0x06d7, 0x06dc, 1},
- {0x06df, 0x06e4, 1},
- {0x06e7, 0x06e8, 1},
- {0x06ea, 0x06ed, 1},
- {0x0711, 0x0730, 31},
- {0x0731, 0x074a, 1},
- {0x07a6, 0x07b0, 1},
- {0x07eb, 0x07f3, 1},
- {0x07fd, 0x0816, 25},
- {0x0817, 0x0819, 1},
- {0x081b, 0x0823, 1},
- {0x0825, 0x0827, 1},
- {0x0829, 0x082d, 1},
- {0x0859, 0x085b, 1},
- {0x08d3, 0x08e1, 1},
- {0x08e3, 0x0903, 1},
- {0x093a, 0x093c, 1},
- {0x093e, 0x094f, 1},
- {0x0951, 0x0957, 1},
- {0x0962, 0x0963, 1},
- {0x0981, 0x0983, 1},
- {0x09bc, 0x09be, 2},
- {0x09bf, 0x09c4, 1},
- {0x09c7, 0x09c8, 1},
- {0x09cb, 0x09cd, 1},
- {0x09d7, 0x09e2, 11},
- {0x09e3, 0x09fe, 27},
- {0x0a01, 0x0a03, 1},
- {0x0a3c, 0x0a3e, 2},
- {0x0a3f, 0x0a42, 1},
- {0x0a47, 0x0a48, 1},
- {0x0a4b, 0x0a4d, 1},
- {0x0a51, 0x0a70, 31},
- {0x0a71, 0x0a75, 4},
- {0x0a81, 0x0a83, 1},
- {0x0abc, 0x0abe, 2},
- {0x0abf, 0x0ac5, 1},
- {0x0ac7, 0x0ac9, 1},
- {0x0acb, 0x0acd, 1},
- {0x0ae2, 0x0ae3, 1},
- {0x0afa, 0x0aff, 1},
- {0x0b01, 0x0b03, 1},
- {0x0b3c, 0x0b3e, 2},
- {0x0b3f, 0x0b44, 1},
- {0x0b47, 0x0b48, 1},
- {0x0b4b, 0x0b4d, 1},
- {0x0b55, 0x0b57, 1},
- {0x0b62, 0x0b63, 1},
- {0x0b82, 0x0bbe, 60},
- {0x0bbf, 0x0bc2, 1},
- {0x0bc6, 0x0bc8, 1},
- {0x0bca, 0x0bcd, 1},
- {0x0bd7, 0x0c00, 41},
- {0x0c01, 0x0c04, 1},
- {0x0c3e, 0x0c44, 1},
- {0x0c46, 0x0c48, 1},
- {0x0c4a, 0x0c4d, 1},
- {0x0c55, 0x0c56, 1},
- {0x0c62, 0x0c63, 1},
- {0x0c81, 0x0c83, 1},
- {0x0cbc, 0x0cbe, 2},
- {0x0cbf, 0x0cc4, 1},
- {0x0cc6, 0x0cc8, 1},
- {0x0cca, 0x0ccd, 1},
- {0x0cd5, 0x0cd6, 1},
- {0x0ce2, 0x0ce3, 1},
- {0x0d00, 0x0d03, 1},
- {0x0d3b, 0x0d3c, 1},
- {0x0d3e, 0x0d44, 1},
- {0x0d46, 0x0d48, 1},
- {0x0d4a, 0x0d4d, 1},
- {0x0d57, 0x0d62, 11},
- {0x0d63, 0x0d81, 30},
- {0x0d82, 0x0d83, 1},
- {0x0dca, 0x0dcf, 5},
- {0x0dd0, 0x0dd4, 1},
- {0x0dd6, 0x0dd8, 2},
- {0x0dd9, 0x0ddf, 1},
- {0x0df2, 0x0df3, 1},
- {0x0e31, 0x0e34, 3},
- {0x0e35, 0x0e3a, 1},
- {0x0e47, 0x0e4e, 1},
- {0x0eb1, 0x0eb4, 3},
- {0x0eb5, 0x0ebc, 1},
- {0x0ec8, 0x0ecd, 1},
- {0x0f18, 0x0f19, 1},
- {0x0f35, 0x0f39, 2},
- {0x0f3e, 0x0f3f, 1},
- {0x0f71, 0x0f84, 1},
- {0x0f86, 0x0f87, 1},
- {0x0f8d, 0x0f97, 1},
- {0x0f99, 0x0fbc, 1},
- {0x0fc6, 0x102b, 101},
- {0x102c, 0x103e, 1},
- {0x1056, 0x1059, 1},
- {0x105e, 0x1060, 1},
- {0x1062, 0x1064, 1},
- {0x1067, 0x106d, 1},
- {0x1071, 0x1074, 1},
- {0x1082, 0x108d, 1},
- {0x108f, 0x109a, 11},
- {0x109b, 0x109d, 1},
- {0x135d, 0x135f, 1},
- {0x1712, 0x1714, 1},
- {0x1732, 0x1734, 1},
- {0x1752, 0x1753, 1},
- {0x1772, 0x1773, 1},
- {0x17b4, 0x17d3, 1},
- {0x17dd, 0x180b, 46},
- {0x180c, 0x180d, 1},
- {0x1885, 0x1886, 1},
- {0x18a9, 0x1920, 119},
- {0x1921, 0x192b, 1},
- {0x1930, 0x193b, 1},
- {0x1a17, 0x1a1b, 1},
- {0x1a55, 0x1a5e, 1},
- {0x1a60, 0x1a7c, 1},
- {0x1a7f, 0x1ab0, 49},
- {0x1ab1, 0x1ac0, 1},
- {0x1b00, 0x1b04, 1},
- {0x1b34, 0x1b44, 1},
- {0x1b6b, 0x1b73, 1},
- {0x1b80, 0x1b82, 1},
- {0x1ba1, 0x1bad, 1},
- {0x1be6, 0x1bf3, 1},
- {0x1c24, 0x1c37, 1},
- {0x1cd0, 0x1cd2, 1},
- {0x1cd4, 0x1ce8, 1},
- {0x1ced, 0x1cf4, 7},
- {0x1cf7, 0x1cf9, 1},
- {0x1dc0, 0x1df9, 1},
- {0x1dfb, 0x1dff, 1},
- {0x20d0, 0x20f0, 1},
- {0x2cef, 0x2cf1, 1},
- {0x2d7f, 0x2de0, 97},
- {0x2de1, 0x2dff, 1},
- {0x302a, 0x302f, 1},
- {0x3099, 0x309a, 1},
- {0xa66f, 0xa672, 1},
- {0xa674, 0xa67d, 1},
- {0xa69e, 0xa69f, 1},
- {0xa6f0, 0xa6f1, 1},
- {0xa802, 0xa806, 4},
- {0xa80b, 0xa823, 24},
- {0xa824, 0xa827, 1},
- {0xa82c, 0xa880, 84},
- {0xa881, 0xa8b4, 51},
- {0xa8b5, 0xa8c5, 1},
- {0xa8e0, 0xa8f1, 1},
- {0xa8ff, 0xa926, 39},
- {0xa927, 0xa92d, 1},
- {0xa947, 0xa953, 1},
- {0xa980, 0xa983, 1},
- {0xa9b3, 0xa9c0, 1},
- {0xa9e5, 0xaa29, 68},
- {0xaa2a, 0xaa36, 1},
- {0xaa43, 0xaa4c, 9},
- {0xaa4d, 0xaa7b, 46},
- {0xaa7c, 0xaa7d, 1},
- {0xaab0, 0xaab2, 2},
- {0xaab3, 0xaab4, 1},
- {0xaab7, 0xaab8, 1},
- {0xaabe, 0xaabf, 1},
- {0xaac1, 0xaaeb, 42},
- {0xaaec, 0xaaef, 1},
- {0xaaf5, 0xaaf6, 1},
- {0xabe3, 0xabea, 1},
- {0xabec, 0xabed, 1},
- {0xfb1e, 0xfe00, 738},
- {0xfe01, 0xfe0f, 1},
- {0xfe20, 0xfe2f, 1},
- },
- R32: []Range32{
- {0x101fd, 0x102e0, 227},
- {0x10376, 0x1037a, 1},
- {0x10a01, 0x10a03, 1},
- {0x10a05, 0x10a06, 1},
- {0x10a0c, 0x10a0f, 1},
- {0x10a38, 0x10a3a, 1},
- {0x10a3f, 0x10ae5, 166},
- {0x10ae6, 0x10d24, 574},
- {0x10d25, 0x10d27, 1},
- {0x10eab, 0x10eac, 1},
- {0x10f46, 0x10f50, 1},
- {0x11000, 0x11002, 1},
- {0x11038, 0x11046, 1},
- {0x1107f, 0x11082, 1},
- {0x110b0, 0x110ba, 1},
- {0x11100, 0x11102, 1},
- {0x11127, 0x11134, 1},
- {0x11145, 0x11146, 1},
- {0x11173, 0x11180, 13},
- {0x11181, 0x11182, 1},
- {0x111b3, 0x111c0, 1},
- {0x111c9, 0x111cc, 1},
- {0x111ce, 0x111cf, 1},
- {0x1122c, 0x11237, 1},
- {0x1123e, 0x112df, 161},
- {0x112e0, 0x112ea, 1},
- {0x11300, 0x11303, 1},
- {0x1133b, 0x1133c, 1},
- {0x1133e, 0x11344, 1},
- {0x11347, 0x11348, 1},
- {0x1134b, 0x1134d, 1},
- {0x11357, 0x11362, 11},
- {0x11363, 0x11366, 3},
- {0x11367, 0x1136c, 1},
- {0x11370, 0x11374, 1},
- {0x11435, 0x11446, 1},
- {0x1145e, 0x114b0, 82},
- {0x114b1, 0x114c3, 1},
- {0x115af, 0x115b5, 1},
- {0x115b8, 0x115c0, 1},
- {0x115dc, 0x115dd, 1},
- {0x11630, 0x11640, 1},
- {0x116ab, 0x116b7, 1},
- {0x1171d, 0x1172b, 1},
- {0x1182c, 0x1183a, 1},
- {0x11930, 0x11935, 1},
- {0x11937, 0x11938, 1},
- {0x1193b, 0x1193e, 1},
- {0x11940, 0x11942, 2},
- {0x11943, 0x119d1, 142},
- {0x119d2, 0x119d7, 1},
- {0x119da, 0x119e0, 1},
- {0x119e4, 0x11a01, 29},
- {0x11a02, 0x11a0a, 1},
- {0x11a33, 0x11a39, 1},
- {0x11a3b, 0x11a3e, 1},
- {0x11a47, 0x11a51, 10},
- {0x11a52, 0x11a5b, 1},
- {0x11a8a, 0x11a99, 1},
- {0x11c2f, 0x11c36, 1},
- {0x11c38, 0x11c3f, 1},
- {0x11c92, 0x11ca7, 1},
- {0x11ca9, 0x11cb6, 1},
- {0x11d31, 0x11d36, 1},
- {0x11d3a, 0x11d3c, 2},
- {0x11d3d, 0x11d3f, 2},
- {0x11d40, 0x11d45, 1},
- {0x11d47, 0x11d8a, 67},
- {0x11d8b, 0x11d8e, 1},
- {0x11d90, 0x11d91, 1},
- {0x11d93, 0x11d97, 1},
- {0x11ef3, 0x11ef6, 1},
- {0x16af0, 0x16af4, 1},
- {0x16b30, 0x16b36, 1},
- {0x16f4f, 0x16f51, 2},
- {0x16f52, 0x16f87, 1},
- {0x16f8f, 0x16f92, 1},
- {0x16fe4, 0x16ff0, 12},
- {0x16ff1, 0x1bc9d, 19628},
- {0x1bc9e, 0x1d165, 5319},
- {0x1d166, 0x1d169, 1},
- {0x1d16d, 0x1d172, 1},
- {0x1d17b, 0x1d182, 1},
- {0x1d185, 0x1d18b, 1},
- {0x1d1aa, 0x1d1ad, 1},
- {0x1d242, 0x1d244, 1},
- {0x1da00, 0x1da36, 1},
- {0x1da3b, 0x1da6c, 1},
- {0x1da75, 0x1da84, 15},
- {0x1da9b, 0x1da9f, 1},
- {0x1daa1, 0x1daaf, 1},
- {0x1e000, 0x1e006, 1},
- {0x1e008, 0x1e018, 1},
- {0x1e01b, 0x1e021, 1},
- {0x1e023, 0x1e024, 1},
- {0x1e026, 0x1e02a, 1},
- {0x1e130, 0x1e136, 1},
- {0x1e2ec, 0x1e2ef, 1},
- {0x1e8d0, 0x1e8d6, 1},
- {0x1e944, 0x1e94a, 1},
- {0xe0100, 0xe01ef, 1},
- },
-}
-
-var _Mc = &RangeTable{
- R16: []Range16{
- {0x0903, 0x093b, 56},
- {0x093e, 0x0940, 1},
- {0x0949, 0x094c, 1},
- {0x094e, 0x094f, 1},
- {0x0982, 0x0983, 1},
- {0x09be, 0x09c0, 1},
- {0x09c7, 0x09c8, 1},
- {0x09cb, 0x09cc, 1},
- {0x09d7, 0x0a03, 44},
- {0x0a3e, 0x0a40, 1},
- {0x0a83, 0x0abe, 59},
- {0x0abf, 0x0ac0, 1},
- {0x0ac9, 0x0acb, 2},
- {0x0acc, 0x0b02, 54},
- {0x0b03, 0x0b3e, 59},
- {0x0b40, 0x0b47, 7},
- {0x0b48, 0x0b4b, 3},
- {0x0b4c, 0x0b57, 11},
- {0x0bbe, 0x0bbf, 1},
- {0x0bc1, 0x0bc2, 1},
- {0x0bc6, 0x0bc8, 1},
- {0x0bca, 0x0bcc, 1},
- {0x0bd7, 0x0c01, 42},
- {0x0c02, 0x0c03, 1},
- {0x0c41, 0x0c44, 1},
- {0x0c82, 0x0c83, 1},
- {0x0cbe, 0x0cc0, 2},
- {0x0cc1, 0x0cc4, 1},
- {0x0cc7, 0x0cc8, 1},
- {0x0cca, 0x0ccb, 1},
- {0x0cd5, 0x0cd6, 1},
- {0x0d02, 0x0d03, 1},
- {0x0d3e, 0x0d40, 1},
- {0x0d46, 0x0d48, 1},
- {0x0d4a, 0x0d4c, 1},
- {0x0d57, 0x0d82, 43},
- {0x0d83, 0x0dcf, 76},
- {0x0dd0, 0x0dd1, 1},
- {0x0dd8, 0x0ddf, 1},
- {0x0df2, 0x0df3, 1},
- {0x0f3e, 0x0f3f, 1},
- {0x0f7f, 0x102b, 172},
- {0x102c, 0x1031, 5},
- {0x1038, 0x103b, 3},
- {0x103c, 0x1056, 26},
- {0x1057, 0x1062, 11},
- {0x1063, 0x1064, 1},
- {0x1067, 0x106d, 1},
- {0x1083, 0x1084, 1},
- {0x1087, 0x108c, 1},
- {0x108f, 0x109a, 11},
- {0x109b, 0x109c, 1},
- {0x17b6, 0x17be, 8},
- {0x17bf, 0x17c5, 1},
- {0x17c7, 0x17c8, 1},
- {0x1923, 0x1926, 1},
- {0x1929, 0x192b, 1},
- {0x1930, 0x1931, 1},
- {0x1933, 0x1938, 1},
- {0x1a19, 0x1a1a, 1},
- {0x1a55, 0x1a57, 2},
- {0x1a61, 0x1a63, 2},
- {0x1a64, 0x1a6d, 9},
- {0x1a6e, 0x1a72, 1},
- {0x1b04, 0x1b35, 49},
- {0x1b3b, 0x1b3d, 2},
- {0x1b3e, 0x1b41, 1},
- {0x1b43, 0x1b44, 1},
- {0x1b82, 0x1ba1, 31},
- {0x1ba6, 0x1ba7, 1},
- {0x1baa, 0x1be7, 61},
- {0x1bea, 0x1bec, 1},
- {0x1bee, 0x1bf2, 4},
- {0x1bf3, 0x1c24, 49},
- {0x1c25, 0x1c2b, 1},
- {0x1c34, 0x1c35, 1},
- {0x1ce1, 0x1cf7, 22},
- {0x302e, 0x302f, 1},
- {0xa823, 0xa824, 1},
- {0xa827, 0xa880, 89},
- {0xa881, 0xa8b4, 51},
- {0xa8b5, 0xa8c3, 1},
- {0xa952, 0xa953, 1},
- {0xa983, 0xa9b4, 49},
- {0xa9b5, 0xa9ba, 5},
- {0xa9bb, 0xa9be, 3},
- {0xa9bf, 0xa9c0, 1},
- {0xaa2f, 0xaa30, 1},
- {0xaa33, 0xaa34, 1},
- {0xaa4d, 0xaa7b, 46},
- {0xaa7d, 0xaaeb, 110},
- {0xaaee, 0xaaef, 1},
- {0xaaf5, 0xabe3, 238},
- {0xabe4, 0xabe6, 2},
- {0xabe7, 0xabe9, 2},
- {0xabea, 0xabec, 2},
- },
- R32: []Range32{
- {0x11000, 0x11002, 2},
- {0x11082, 0x110b0, 46},
- {0x110b1, 0x110b2, 1},
- {0x110b7, 0x110b8, 1},
- {0x1112c, 0x11145, 25},
- {0x11146, 0x11182, 60},
- {0x111b3, 0x111b5, 1},
- {0x111bf, 0x111c0, 1},
- {0x111ce, 0x1122c, 94},
- {0x1122d, 0x1122e, 1},
- {0x11232, 0x11233, 1},
- {0x11235, 0x112e0, 171},
- {0x112e1, 0x112e2, 1},
- {0x11302, 0x11303, 1},
- {0x1133e, 0x1133f, 1},
- {0x11341, 0x11344, 1},
- {0x11347, 0x11348, 1},
- {0x1134b, 0x1134d, 1},
- {0x11357, 0x11362, 11},
- {0x11363, 0x11435, 210},
- {0x11436, 0x11437, 1},
- {0x11440, 0x11441, 1},
- {0x11445, 0x114b0, 107},
- {0x114b1, 0x114b2, 1},
- {0x114b9, 0x114bb, 2},
- {0x114bc, 0x114be, 1},
- {0x114c1, 0x115af, 238},
- {0x115b0, 0x115b1, 1},
- {0x115b8, 0x115bb, 1},
- {0x115be, 0x11630, 114},
- {0x11631, 0x11632, 1},
- {0x1163b, 0x1163c, 1},
- {0x1163e, 0x116ac, 110},
- {0x116ae, 0x116af, 1},
- {0x116b6, 0x11720, 106},
- {0x11721, 0x11726, 5},
- {0x1182c, 0x1182e, 1},
- {0x11838, 0x11930, 248},
- {0x11931, 0x11935, 1},
- {0x11937, 0x11938, 1},
- {0x1193d, 0x11940, 3},
- {0x11942, 0x119d1, 143},
- {0x119d2, 0x119d3, 1},
- {0x119dc, 0x119df, 1},
- {0x119e4, 0x11a39, 85},
- {0x11a57, 0x11a58, 1},
- {0x11a97, 0x11c2f, 408},
- {0x11c3e, 0x11ca9, 107},
- {0x11cb1, 0x11cb4, 3},
- {0x11d8a, 0x11d8e, 1},
- {0x11d93, 0x11d94, 1},
- {0x11d96, 0x11ef5, 351},
- {0x11ef6, 0x16f51, 20571},
- {0x16f52, 0x16f87, 1},
- {0x16ff0, 0x16ff1, 1},
- {0x1d165, 0x1d166, 1},
- {0x1d16d, 0x1d172, 1},
- },
-}
-
-var _Me = &RangeTable{
- R16: []Range16{
- {0x0488, 0x0489, 1},
- {0x1abe, 0x20dd, 1567},
- {0x20de, 0x20e0, 1},
- {0x20e2, 0x20e4, 1},
- {0xa670, 0xa672, 1},
- },
-}
-
-var _Mn = &RangeTable{
- R16: []Range16{
- {0x0300, 0x036f, 1},
- {0x0483, 0x0487, 1},
- {0x0591, 0x05bd, 1},
- {0x05bf, 0x05c1, 2},
- {0x05c2, 0x05c4, 2},
- {0x05c5, 0x05c7, 2},
- {0x0610, 0x061a, 1},
- {0x064b, 0x065f, 1},
- {0x0670, 0x06d6, 102},
- {0x06d7, 0x06dc, 1},
- {0x06df, 0x06e4, 1},
- {0x06e7, 0x06e8, 1},
- {0x06ea, 0x06ed, 1},
- {0x0711, 0x0730, 31},
- {0x0731, 0x074a, 1},
- {0x07a6, 0x07b0, 1},
- {0x07eb, 0x07f3, 1},
- {0x07fd, 0x0816, 25},
- {0x0817, 0x0819, 1},
- {0x081b, 0x0823, 1},
- {0x0825, 0x0827, 1},
- {0x0829, 0x082d, 1},
- {0x0859, 0x085b, 1},
- {0x08d3, 0x08e1, 1},
- {0x08e3, 0x0902, 1},
- {0x093a, 0x093c, 2},
- {0x0941, 0x0948, 1},
- {0x094d, 0x0951, 4},
- {0x0952, 0x0957, 1},
- {0x0962, 0x0963, 1},
- {0x0981, 0x09bc, 59},
- {0x09c1, 0x09c4, 1},
- {0x09cd, 0x09e2, 21},
- {0x09e3, 0x09fe, 27},
- {0x0a01, 0x0a02, 1},
- {0x0a3c, 0x0a41, 5},
- {0x0a42, 0x0a47, 5},
- {0x0a48, 0x0a4b, 3},
- {0x0a4c, 0x0a4d, 1},
- {0x0a51, 0x0a70, 31},
- {0x0a71, 0x0a75, 4},
- {0x0a81, 0x0a82, 1},
- {0x0abc, 0x0ac1, 5},
- {0x0ac2, 0x0ac5, 1},
- {0x0ac7, 0x0ac8, 1},
- {0x0acd, 0x0ae2, 21},
- {0x0ae3, 0x0afa, 23},
- {0x0afb, 0x0aff, 1},
- {0x0b01, 0x0b3c, 59},
- {0x0b3f, 0x0b41, 2},
- {0x0b42, 0x0b44, 1},
- {0x0b4d, 0x0b55, 8},
- {0x0b56, 0x0b62, 12},
- {0x0b63, 0x0b82, 31},
- {0x0bc0, 0x0bcd, 13},
- {0x0c00, 0x0c04, 4},
- {0x0c3e, 0x0c40, 1},
- {0x0c46, 0x0c48, 1},
- {0x0c4a, 0x0c4d, 1},
- {0x0c55, 0x0c56, 1},
- {0x0c62, 0x0c63, 1},
- {0x0c81, 0x0cbc, 59},
- {0x0cbf, 0x0cc6, 7},
- {0x0ccc, 0x0ccd, 1},
- {0x0ce2, 0x0ce3, 1},
- {0x0d00, 0x0d01, 1},
- {0x0d3b, 0x0d3c, 1},
- {0x0d41, 0x0d44, 1},
- {0x0d4d, 0x0d62, 21},
- {0x0d63, 0x0d81, 30},
- {0x0dca, 0x0dd2, 8},
- {0x0dd3, 0x0dd4, 1},
- {0x0dd6, 0x0e31, 91},
- {0x0e34, 0x0e3a, 1},
- {0x0e47, 0x0e4e, 1},
- {0x0eb1, 0x0eb4, 3},
- {0x0eb5, 0x0ebc, 1},
- {0x0ec8, 0x0ecd, 1},
- {0x0f18, 0x0f19, 1},
- {0x0f35, 0x0f39, 2},
- {0x0f71, 0x0f7e, 1},
- {0x0f80, 0x0f84, 1},
- {0x0f86, 0x0f87, 1},
- {0x0f8d, 0x0f97, 1},
- {0x0f99, 0x0fbc, 1},
- {0x0fc6, 0x102d, 103},
- {0x102e, 0x1030, 1},
- {0x1032, 0x1037, 1},
- {0x1039, 0x103a, 1},
- {0x103d, 0x103e, 1},
- {0x1058, 0x1059, 1},
- {0x105e, 0x1060, 1},
- {0x1071, 0x1074, 1},
- {0x1082, 0x1085, 3},
- {0x1086, 0x108d, 7},
- {0x109d, 0x135d, 704},
- {0x135e, 0x135f, 1},
- {0x1712, 0x1714, 1},
- {0x1732, 0x1734, 1},
- {0x1752, 0x1753, 1},
- {0x1772, 0x1773, 1},
- {0x17b4, 0x17b5, 1},
- {0x17b7, 0x17bd, 1},
- {0x17c6, 0x17c9, 3},
- {0x17ca, 0x17d3, 1},
- {0x17dd, 0x180b, 46},
- {0x180c, 0x180d, 1},
- {0x1885, 0x1886, 1},
- {0x18a9, 0x1920, 119},
- {0x1921, 0x1922, 1},
- {0x1927, 0x1928, 1},
- {0x1932, 0x1939, 7},
- {0x193a, 0x193b, 1},
- {0x1a17, 0x1a18, 1},
- {0x1a1b, 0x1a56, 59},
- {0x1a58, 0x1a5e, 1},
- {0x1a60, 0x1a62, 2},
- {0x1a65, 0x1a6c, 1},
- {0x1a73, 0x1a7c, 1},
- {0x1a7f, 0x1ab0, 49},
- {0x1ab1, 0x1abd, 1},
- {0x1abf, 0x1ac0, 1},
- {0x1b00, 0x1b03, 1},
- {0x1b34, 0x1b36, 2},
- {0x1b37, 0x1b3a, 1},
- {0x1b3c, 0x1b42, 6},
- {0x1b6b, 0x1b73, 1},
- {0x1b80, 0x1b81, 1},
- {0x1ba2, 0x1ba5, 1},
- {0x1ba8, 0x1ba9, 1},
- {0x1bab, 0x1bad, 1},
- {0x1be6, 0x1be8, 2},
- {0x1be9, 0x1bed, 4},
- {0x1bef, 0x1bf1, 1},
- {0x1c2c, 0x1c33, 1},
- {0x1c36, 0x1c37, 1},
- {0x1cd0, 0x1cd2, 1},
- {0x1cd4, 0x1ce0, 1},
- {0x1ce2, 0x1ce8, 1},
- {0x1ced, 0x1cf4, 7},
- {0x1cf8, 0x1cf9, 1},
- {0x1dc0, 0x1df9, 1},
- {0x1dfb, 0x1dff, 1},
- {0x20d0, 0x20dc, 1},
- {0x20e1, 0x20e5, 4},
- {0x20e6, 0x20f0, 1},
- {0x2cef, 0x2cf1, 1},
- {0x2d7f, 0x2de0, 97},
- {0x2de1, 0x2dff, 1},
- {0x302a, 0x302d, 1},
- {0x3099, 0x309a, 1},
- {0xa66f, 0xa674, 5},
- {0xa675, 0xa67d, 1},
- {0xa69e, 0xa69f, 1},
- {0xa6f0, 0xa6f1, 1},
- {0xa802, 0xa806, 4},
- {0xa80b, 0xa825, 26},
- {0xa826, 0xa82c, 6},
- {0xa8c4, 0xa8c5, 1},
- {0xa8e0, 0xa8f1, 1},
- {0xa8ff, 0xa926, 39},
- {0xa927, 0xa92d, 1},
- {0xa947, 0xa951, 1},
- {0xa980, 0xa982, 1},
- {0xa9b3, 0xa9b6, 3},
- {0xa9b7, 0xa9b9, 1},
- {0xa9bc, 0xa9bd, 1},
- {0xa9e5, 0xaa29, 68},
- {0xaa2a, 0xaa2e, 1},
- {0xaa31, 0xaa32, 1},
- {0xaa35, 0xaa36, 1},
- {0xaa43, 0xaa4c, 9},
- {0xaa7c, 0xaab0, 52},
- {0xaab2, 0xaab4, 1},
- {0xaab7, 0xaab8, 1},
- {0xaabe, 0xaabf, 1},
- {0xaac1, 0xaaec, 43},
- {0xaaed, 0xaaf6, 9},
- {0xabe5, 0xabe8, 3},
- {0xabed, 0xfb1e, 20273},
- {0xfe00, 0xfe0f, 1},
- {0xfe20, 0xfe2f, 1},
- },
- R32: []Range32{
- {0x101fd, 0x102e0, 227},
- {0x10376, 0x1037a, 1},
- {0x10a01, 0x10a03, 1},
- {0x10a05, 0x10a06, 1},
- {0x10a0c, 0x10a0f, 1},
- {0x10a38, 0x10a3a, 1},
- {0x10a3f, 0x10ae5, 166},
- {0x10ae6, 0x10d24, 574},
- {0x10d25, 0x10d27, 1},
- {0x10eab, 0x10eac, 1},
- {0x10f46, 0x10f50, 1},
- {0x11001, 0x11038, 55},
- {0x11039, 0x11046, 1},
- {0x1107f, 0x11081, 1},
- {0x110b3, 0x110b6, 1},
- {0x110b9, 0x110ba, 1},
- {0x11100, 0x11102, 1},
- {0x11127, 0x1112b, 1},
- {0x1112d, 0x11134, 1},
- {0x11173, 0x11180, 13},
- {0x11181, 0x111b6, 53},
- {0x111b7, 0x111be, 1},
- {0x111c9, 0x111cc, 1},
- {0x111cf, 0x1122f, 96},
- {0x11230, 0x11231, 1},
- {0x11234, 0x11236, 2},
- {0x11237, 0x1123e, 7},
- {0x112df, 0x112e3, 4},
- {0x112e4, 0x112ea, 1},
- {0x11300, 0x11301, 1},
- {0x1133b, 0x1133c, 1},
- {0x11340, 0x11366, 38},
- {0x11367, 0x1136c, 1},
- {0x11370, 0x11374, 1},
- {0x11438, 0x1143f, 1},
- {0x11442, 0x11444, 1},
- {0x11446, 0x1145e, 24},
- {0x114b3, 0x114b8, 1},
- {0x114ba, 0x114bf, 5},
- {0x114c0, 0x114c2, 2},
- {0x114c3, 0x115b2, 239},
- {0x115b3, 0x115b5, 1},
- {0x115bc, 0x115bd, 1},
- {0x115bf, 0x115c0, 1},
- {0x115dc, 0x115dd, 1},
- {0x11633, 0x1163a, 1},
- {0x1163d, 0x1163f, 2},
- {0x11640, 0x116ab, 107},
- {0x116ad, 0x116b0, 3},
- {0x116b1, 0x116b5, 1},
- {0x116b7, 0x1171d, 102},
- {0x1171e, 0x1171f, 1},
- {0x11722, 0x11725, 1},
- {0x11727, 0x1172b, 1},
- {0x1182f, 0x11837, 1},
- {0x11839, 0x1183a, 1},
- {0x1193b, 0x1193c, 1},
- {0x1193e, 0x11943, 5},
- {0x119d4, 0x119d7, 1},
- {0x119da, 0x119db, 1},
- {0x119e0, 0x11a01, 33},
- {0x11a02, 0x11a0a, 1},
- {0x11a33, 0x11a38, 1},
- {0x11a3b, 0x11a3e, 1},
- {0x11a47, 0x11a51, 10},
- {0x11a52, 0x11a56, 1},
- {0x11a59, 0x11a5b, 1},
- {0x11a8a, 0x11a96, 1},
- {0x11a98, 0x11a99, 1},
- {0x11c30, 0x11c36, 1},
- {0x11c38, 0x11c3d, 1},
- {0x11c3f, 0x11c92, 83},
- {0x11c93, 0x11ca7, 1},
- {0x11caa, 0x11cb0, 1},
- {0x11cb2, 0x11cb3, 1},
- {0x11cb5, 0x11cb6, 1},
- {0x11d31, 0x11d36, 1},
- {0x11d3a, 0x11d3c, 2},
- {0x11d3d, 0x11d3f, 2},
- {0x11d40, 0x11d45, 1},
- {0x11d47, 0x11d90, 73},
- {0x11d91, 0x11d95, 4},
- {0x11d97, 0x11ef3, 348},
- {0x11ef4, 0x16af0, 19452},
- {0x16af1, 0x16af4, 1},
- {0x16b30, 0x16b36, 1},
- {0x16f4f, 0x16f8f, 64},
- {0x16f90, 0x16f92, 1},
- {0x16fe4, 0x1bc9d, 19641},
- {0x1bc9e, 0x1d167, 5321},
- {0x1d168, 0x1d169, 1},
- {0x1d17b, 0x1d182, 1},
- {0x1d185, 0x1d18b, 1},
- {0x1d1aa, 0x1d1ad, 1},
- {0x1d242, 0x1d244, 1},
- {0x1da00, 0x1da36, 1},
- {0x1da3b, 0x1da6c, 1},
- {0x1da75, 0x1da84, 15},
- {0x1da9b, 0x1da9f, 1},
- {0x1daa1, 0x1daaf, 1},
- {0x1e000, 0x1e006, 1},
- {0x1e008, 0x1e018, 1},
- {0x1e01b, 0x1e021, 1},
- {0x1e023, 0x1e024, 1},
- {0x1e026, 0x1e02a, 1},
- {0x1e130, 0x1e136, 1},
- {0x1e2ec, 0x1e2ef, 1},
- {0x1e8d0, 0x1e8d6, 1},
- {0x1e944, 0x1e94a, 1},
- {0xe0100, 0xe01ef, 1},
- },
-}
-
-var _N = &RangeTable{
- R16: []Range16{
- {0x0030, 0x0039, 1},
- {0x00b2, 0x00b3, 1},
- {0x00b9, 0x00bc, 3},
- {0x00bd, 0x00be, 1},
- {0x0660, 0x0669, 1},
- {0x06f0, 0x06f9, 1},
- {0x07c0, 0x07c9, 1},
- {0x0966, 0x096f, 1},
- {0x09e6, 0x09ef, 1},
- {0x09f4, 0x09f9, 1},
- {0x0a66, 0x0a6f, 1},
- {0x0ae6, 0x0aef, 1},
- {0x0b66, 0x0b6f, 1},
- {0x0b72, 0x0b77, 1},
- {0x0be6, 0x0bf2, 1},
- {0x0c66, 0x0c6f, 1},
- {0x0c78, 0x0c7e, 1},
- {0x0ce6, 0x0cef, 1},
- {0x0d58, 0x0d5e, 1},
- {0x0d66, 0x0d78, 1},
- {0x0de6, 0x0def, 1},
- {0x0e50, 0x0e59, 1},
- {0x0ed0, 0x0ed9, 1},
- {0x0f20, 0x0f33, 1},
- {0x1040, 0x1049, 1},
- {0x1090, 0x1099, 1},
- {0x1369, 0x137c, 1},
- {0x16ee, 0x16f0, 1},
- {0x17e0, 0x17e9, 1},
- {0x17f0, 0x17f9, 1},
- {0x1810, 0x1819, 1},
- {0x1946, 0x194f, 1},
- {0x19d0, 0x19da, 1},
- {0x1a80, 0x1a89, 1},
- {0x1a90, 0x1a99, 1},
- {0x1b50, 0x1b59, 1},
- {0x1bb0, 0x1bb9, 1},
- {0x1c40, 0x1c49, 1},
- {0x1c50, 0x1c59, 1},
- {0x2070, 0x2074, 4},
- {0x2075, 0x2079, 1},
- {0x2080, 0x2089, 1},
- {0x2150, 0x2182, 1},
- {0x2185, 0x2189, 1},
- {0x2460, 0x249b, 1},
- {0x24ea, 0x24ff, 1},
- {0x2776, 0x2793, 1},
- {0x2cfd, 0x3007, 778},
- {0x3021, 0x3029, 1},
- {0x3038, 0x303a, 1},
- {0x3192, 0x3195, 1},
- {0x3220, 0x3229, 1},
- {0x3248, 0x324f, 1},
- {0x3251, 0x325f, 1},
- {0x3280, 0x3289, 1},
- {0x32b1, 0x32bf, 1},
- {0xa620, 0xa629, 1},
- {0xa6e6, 0xa6ef, 1},
- {0xa830, 0xa835, 1},
- {0xa8d0, 0xa8d9, 1},
- {0xa900, 0xa909, 1},
- {0xa9d0, 0xa9d9, 1},
- {0xa9f0, 0xa9f9, 1},
- {0xaa50, 0xaa59, 1},
- {0xabf0, 0xabf9, 1},
- {0xff10, 0xff19, 1},
- },
- R32: []Range32{
- {0x10107, 0x10133, 1},
- {0x10140, 0x10178, 1},
- {0x1018a, 0x1018b, 1},
- {0x102e1, 0x102fb, 1},
- {0x10320, 0x10323, 1},
- {0x10341, 0x1034a, 9},
- {0x103d1, 0x103d5, 1},
- {0x104a0, 0x104a9, 1},
- {0x10858, 0x1085f, 1},
- {0x10879, 0x1087f, 1},
- {0x108a7, 0x108af, 1},
- {0x108fb, 0x108ff, 1},
- {0x10916, 0x1091b, 1},
- {0x109bc, 0x109bd, 1},
- {0x109c0, 0x109cf, 1},
- {0x109d2, 0x109ff, 1},
- {0x10a40, 0x10a48, 1},
- {0x10a7d, 0x10a7e, 1},
- {0x10a9d, 0x10a9f, 1},
- {0x10aeb, 0x10aef, 1},
- {0x10b58, 0x10b5f, 1},
- {0x10b78, 0x10b7f, 1},
- {0x10ba9, 0x10baf, 1},
- {0x10cfa, 0x10cff, 1},
- {0x10d30, 0x10d39, 1},
- {0x10e60, 0x10e7e, 1},
- {0x10f1d, 0x10f26, 1},
- {0x10f51, 0x10f54, 1},
- {0x10fc5, 0x10fcb, 1},
- {0x11052, 0x1106f, 1},
- {0x110f0, 0x110f9, 1},
- {0x11136, 0x1113f, 1},
- {0x111d0, 0x111d9, 1},
- {0x111e1, 0x111f4, 1},
- {0x112f0, 0x112f9, 1},
- {0x11450, 0x11459, 1},
- {0x114d0, 0x114d9, 1},
- {0x11650, 0x11659, 1},
- {0x116c0, 0x116c9, 1},
- {0x11730, 0x1173b, 1},
- {0x118e0, 0x118f2, 1},
- {0x11950, 0x11959, 1},
- {0x11c50, 0x11c6c, 1},
- {0x11d50, 0x11d59, 1},
- {0x11da0, 0x11da9, 1},
- {0x11fc0, 0x11fd4, 1},
- {0x12400, 0x1246e, 1},
- {0x16a60, 0x16a69, 1},
- {0x16b50, 0x16b59, 1},
- {0x16b5b, 0x16b61, 1},
- {0x16e80, 0x16e96, 1},
- {0x1d2e0, 0x1d2f3, 1},
- {0x1d360, 0x1d378, 1},
- {0x1d7ce, 0x1d7ff, 1},
- {0x1e140, 0x1e149, 1},
- {0x1e2f0, 0x1e2f9, 1},
- {0x1e8c7, 0x1e8cf, 1},
- {0x1e950, 0x1e959, 1},
- {0x1ec71, 0x1ecab, 1},
- {0x1ecad, 0x1ecaf, 1},
- {0x1ecb1, 0x1ecb4, 1},
- {0x1ed01, 0x1ed2d, 1},
- {0x1ed2f, 0x1ed3d, 1},
- {0x1f100, 0x1f10c, 1},
- {0x1fbf0, 0x1fbf9, 1},
- },
- LatinOffset: 4,
-}
-
-var _Nd = &RangeTable{
- R16: []Range16{
- {0x0030, 0x0039, 1},
- {0x0660, 0x0669, 1},
- {0x06f0, 0x06f9, 1},
- {0x07c0, 0x07c9, 1},
- {0x0966, 0x096f, 1},
- {0x09e6, 0x09ef, 1},
- {0x0a66, 0x0a6f, 1},
- {0x0ae6, 0x0aef, 1},
- {0x0b66, 0x0b6f, 1},
- {0x0be6, 0x0bef, 1},
- {0x0c66, 0x0c6f, 1},
- {0x0ce6, 0x0cef, 1},
- {0x0d66, 0x0d6f, 1},
- {0x0de6, 0x0def, 1},
- {0x0e50, 0x0e59, 1},
- {0x0ed0, 0x0ed9, 1},
- {0x0f20, 0x0f29, 1},
- {0x1040, 0x1049, 1},
- {0x1090, 0x1099, 1},
- {0x17e0, 0x17e9, 1},
- {0x1810, 0x1819, 1},
- {0x1946, 0x194f, 1},
- {0x19d0, 0x19d9, 1},
- {0x1a80, 0x1a89, 1},
- {0x1a90, 0x1a99, 1},
- {0x1b50, 0x1b59, 1},
- {0x1bb0, 0x1bb9, 1},
- {0x1c40, 0x1c49, 1},
- {0x1c50, 0x1c59, 1},
- {0xa620, 0xa629, 1},
- {0xa8d0, 0xa8d9, 1},
- {0xa900, 0xa909, 1},
- {0xa9d0, 0xa9d9, 1},
- {0xa9f0, 0xa9f9, 1},
- {0xaa50, 0xaa59, 1},
- {0xabf0, 0xabf9, 1},
- {0xff10, 0xff19, 1},
- },
- R32: []Range32{
- {0x104a0, 0x104a9, 1},
- {0x10d30, 0x10d39, 1},
- {0x11066, 0x1106f, 1},
- {0x110f0, 0x110f9, 1},
- {0x11136, 0x1113f, 1},
- {0x111d0, 0x111d9, 1},
- {0x112f0, 0x112f9, 1},
- {0x11450, 0x11459, 1},
- {0x114d0, 0x114d9, 1},
- {0x11650, 0x11659, 1},
- {0x116c0, 0x116c9, 1},
- {0x11730, 0x11739, 1},
- {0x118e0, 0x118e9, 1},
- {0x11950, 0x11959, 1},
- {0x11c50, 0x11c59, 1},
- {0x11d50, 0x11d59, 1},
- {0x11da0, 0x11da9, 1},
- {0x16a60, 0x16a69, 1},
- {0x16b50, 0x16b59, 1},
- {0x1d7ce, 0x1d7ff, 1},
- {0x1e140, 0x1e149, 1},
- {0x1e2f0, 0x1e2f9, 1},
- {0x1e950, 0x1e959, 1},
- {0x1fbf0, 0x1fbf9, 1},
- },
- LatinOffset: 1,
-}
-
-var _Nl = &RangeTable{
- R16: []Range16{
- {0x16ee, 0x16f0, 1},
- {0x2160, 0x2182, 1},
- {0x2185, 0x2188, 1},
- {0x3007, 0x3021, 26},
- {0x3022, 0x3029, 1},
- {0x3038, 0x303a, 1},
- {0xa6e6, 0xa6ef, 1},
- },
- R32: []Range32{
- {0x10140, 0x10174, 1},
- {0x10341, 0x1034a, 9},
- {0x103d1, 0x103d5, 1},
- {0x12400, 0x1246e, 1},
- },
-}
-
-var _No = &RangeTable{
- R16: []Range16{
- {0x00b2, 0x00b3, 1},
- {0x00b9, 0x00bc, 3},
- {0x00bd, 0x00be, 1},
- {0x09f4, 0x09f9, 1},
- {0x0b72, 0x0b77, 1},
- {0x0bf0, 0x0bf2, 1},
- {0x0c78, 0x0c7e, 1},
- {0x0d58, 0x0d5e, 1},
- {0x0d70, 0x0d78, 1},
- {0x0f2a, 0x0f33, 1},
- {0x1369, 0x137c, 1},
- {0x17f0, 0x17f9, 1},
- {0x19da, 0x2070, 1686},
- {0x2074, 0x2079, 1},
- {0x2080, 0x2089, 1},
- {0x2150, 0x215f, 1},
- {0x2189, 0x2460, 727},
- {0x2461, 0x249b, 1},
- {0x24ea, 0x24ff, 1},
- {0x2776, 0x2793, 1},
- {0x2cfd, 0x3192, 1173},
- {0x3193, 0x3195, 1},
- {0x3220, 0x3229, 1},
- {0x3248, 0x324f, 1},
- {0x3251, 0x325f, 1},
- {0x3280, 0x3289, 1},
- {0x32b1, 0x32bf, 1},
- {0xa830, 0xa835, 1},
- },
- R32: []Range32{
- {0x10107, 0x10133, 1},
- {0x10175, 0x10178, 1},
- {0x1018a, 0x1018b, 1},
- {0x102e1, 0x102fb, 1},
- {0x10320, 0x10323, 1},
- {0x10858, 0x1085f, 1},
- {0x10879, 0x1087f, 1},
- {0x108a7, 0x108af, 1},
- {0x108fb, 0x108ff, 1},
- {0x10916, 0x1091b, 1},
- {0x109bc, 0x109bd, 1},
- {0x109c0, 0x109cf, 1},
- {0x109d2, 0x109ff, 1},
- {0x10a40, 0x10a48, 1},
- {0x10a7d, 0x10a7e, 1},
- {0x10a9d, 0x10a9f, 1},
- {0x10aeb, 0x10aef, 1},
- {0x10b58, 0x10b5f, 1},
- {0x10b78, 0x10b7f, 1},
- {0x10ba9, 0x10baf, 1},
- {0x10cfa, 0x10cff, 1},
- {0x10e60, 0x10e7e, 1},
- {0x10f1d, 0x10f26, 1},
- {0x10f51, 0x10f54, 1},
- {0x10fc5, 0x10fcb, 1},
- {0x11052, 0x11065, 1},
- {0x111e1, 0x111f4, 1},
- {0x1173a, 0x1173b, 1},
- {0x118ea, 0x118f2, 1},
- {0x11c5a, 0x11c6c, 1},
- {0x11fc0, 0x11fd4, 1},
- {0x16b5b, 0x16b61, 1},
- {0x16e80, 0x16e96, 1},
- {0x1d2e0, 0x1d2f3, 1},
- {0x1d360, 0x1d378, 1},
- {0x1e8c7, 0x1e8cf, 1},
- {0x1ec71, 0x1ecab, 1},
- {0x1ecad, 0x1ecaf, 1},
- {0x1ecb1, 0x1ecb4, 1},
- {0x1ed01, 0x1ed2d, 1},
- {0x1ed2f, 0x1ed3d, 1},
- {0x1f100, 0x1f10c, 1},
- },
- LatinOffset: 3,
-}
-
-var _P = &RangeTable{
- R16: []Range16{
- {0x0021, 0x0023, 1},
- {0x0025, 0x002a, 1},
- {0x002c, 0x002f, 1},
- {0x003a, 0x003b, 1},
- {0x003f, 0x0040, 1},
- {0x005b, 0x005d, 1},
- {0x005f, 0x007b, 28},
- {0x007d, 0x00a1, 36},
- {0x00a7, 0x00ab, 4},
- {0x00b6, 0x00b7, 1},
- {0x00bb, 0x00bf, 4},
- {0x037e, 0x0387, 9},
- {0x055a, 0x055f, 1},
- {0x0589, 0x058a, 1},
- {0x05be, 0x05c0, 2},
- {0x05c3, 0x05c6, 3},
- {0x05f3, 0x05f4, 1},
- {0x0609, 0x060a, 1},
- {0x060c, 0x060d, 1},
- {0x061b, 0x061e, 3},
- {0x061f, 0x066a, 75},
- {0x066b, 0x066d, 1},
- {0x06d4, 0x0700, 44},
- {0x0701, 0x070d, 1},
- {0x07f7, 0x07f9, 1},
- {0x0830, 0x083e, 1},
- {0x085e, 0x0964, 262},
- {0x0965, 0x0970, 11},
- {0x09fd, 0x0a76, 121},
- {0x0af0, 0x0c77, 391},
- {0x0c84, 0x0df4, 368},
- {0x0e4f, 0x0e5a, 11},
- {0x0e5b, 0x0f04, 169},
- {0x0f05, 0x0f12, 1},
- {0x0f14, 0x0f3a, 38},
- {0x0f3b, 0x0f3d, 1},
- {0x0f85, 0x0fd0, 75},
- {0x0fd1, 0x0fd4, 1},
- {0x0fd9, 0x0fda, 1},
- {0x104a, 0x104f, 1},
- {0x10fb, 0x1360, 613},
- {0x1361, 0x1368, 1},
- {0x1400, 0x166e, 622},
- {0x169b, 0x169c, 1},
- {0x16eb, 0x16ed, 1},
- {0x1735, 0x1736, 1},
- {0x17d4, 0x17d6, 1},
- {0x17d8, 0x17da, 1},
- {0x1800, 0x180a, 1},
- {0x1944, 0x1945, 1},
- {0x1a1e, 0x1a1f, 1},
- {0x1aa0, 0x1aa6, 1},
- {0x1aa8, 0x1aad, 1},
- {0x1b5a, 0x1b60, 1},
- {0x1bfc, 0x1bff, 1},
- {0x1c3b, 0x1c3f, 1},
- {0x1c7e, 0x1c7f, 1},
- {0x1cc0, 0x1cc7, 1},
- {0x1cd3, 0x2010, 829},
- {0x2011, 0x2027, 1},
- {0x2030, 0x2043, 1},
- {0x2045, 0x2051, 1},
- {0x2053, 0x205e, 1},
- {0x207d, 0x207e, 1},
- {0x208d, 0x208e, 1},
- {0x2308, 0x230b, 1},
- {0x2329, 0x232a, 1},
- {0x2768, 0x2775, 1},
- {0x27c5, 0x27c6, 1},
- {0x27e6, 0x27ef, 1},
- {0x2983, 0x2998, 1},
- {0x29d8, 0x29db, 1},
- {0x29fc, 0x29fd, 1},
- {0x2cf9, 0x2cfc, 1},
- {0x2cfe, 0x2cff, 1},
- {0x2d70, 0x2e00, 144},
- {0x2e01, 0x2e2e, 1},
- {0x2e30, 0x2e4f, 1},
- {0x2e52, 0x3001, 431},
- {0x3002, 0x3003, 1},
- {0x3008, 0x3011, 1},
- {0x3014, 0x301f, 1},
- {0x3030, 0x303d, 13},
- {0x30a0, 0x30fb, 91},
- {0xa4fe, 0xa4ff, 1},
- {0xa60d, 0xa60f, 1},
- {0xa673, 0xa67e, 11},
- {0xa6f2, 0xa6f7, 1},
- {0xa874, 0xa877, 1},
- {0xa8ce, 0xa8cf, 1},
- {0xa8f8, 0xa8fa, 1},
- {0xa8fc, 0xa92e, 50},
- {0xa92f, 0xa95f, 48},
- {0xa9c1, 0xa9cd, 1},
- {0xa9de, 0xa9df, 1},
- {0xaa5c, 0xaa5f, 1},
- {0xaade, 0xaadf, 1},
- {0xaaf0, 0xaaf1, 1},
- {0xabeb, 0xfd3e, 20819},
- {0xfd3f, 0xfe10, 209},
- {0xfe11, 0xfe19, 1},
- {0xfe30, 0xfe52, 1},
- {0xfe54, 0xfe61, 1},
- {0xfe63, 0xfe68, 5},
- {0xfe6a, 0xfe6b, 1},
- {0xff01, 0xff03, 1},
- {0xff05, 0xff0a, 1},
- {0xff0c, 0xff0f, 1},
- {0xff1a, 0xff1b, 1},
- {0xff1f, 0xff20, 1},
- {0xff3b, 0xff3d, 1},
- {0xff3f, 0xff5b, 28},
- {0xff5d, 0xff5f, 2},
- {0xff60, 0xff65, 1},
- },
- R32: []Range32{
- {0x10100, 0x10102, 1},
- {0x1039f, 0x103d0, 49},
- {0x1056f, 0x10857, 744},
- {0x1091f, 0x1093f, 32},
- {0x10a50, 0x10a58, 1},
- {0x10a7f, 0x10af0, 113},
- {0x10af1, 0x10af6, 1},
- {0x10b39, 0x10b3f, 1},
- {0x10b99, 0x10b9c, 1},
- {0x10ead, 0x10f55, 168},
- {0x10f56, 0x10f59, 1},
- {0x11047, 0x1104d, 1},
- {0x110bb, 0x110bc, 1},
- {0x110be, 0x110c1, 1},
- {0x11140, 0x11143, 1},
- {0x11174, 0x11175, 1},
- {0x111c5, 0x111c8, 1},
- {0x111cd, 0x111db, 14},
- {0x111dd, 0x111df, 1},
- {0x11238, 0x1123d, 1},
- {0x112a9, 0x1144b, 418},
- {0x1144c, 0x1144f, 1},
- {0x1145a, 0x1145b, 1},
- {0x1145d, 0x114c6, 105},
- {0x115c1, 0x115d7, 1},
- {0x11641, 0x11643, 1},
- {0x11660, 0x1166c, 1},
- {0x1173c, 0x1173e, 1},
- {0x1183b, 0x11944, 265},
- {0x11945, 0x11946, 1},
- {0x119e2, 0x11a3f, 93},
- {0x11a40, 0x11a46, 1},
- {0x11a9a, 0x11a9c, 1},
- {0x11a9e, 0x11aa2, 1},
- {0x11c41, 0x11c45, 1},
- {0x11c70, 0x11c71, 1},
- {0x11ef7, 0x11ef8, 1},
- {0x11fff, 0x12470, 1137},
- {0x12471, 0x12474, 1},
- {0x16a6e, 0x16a6f, 1},
- {0x16af5, 0x16b37, 66},
- {0x16b38, 0x16b3b, 1},
- {0x16b44, 0x16e97, 851},
- {0x16e98, 0x16e9a, 1},
- {0x16fe2, 0x1bc9f, 19645},
- {0x1da87, 0x1da8b, 1},
- {0x1e95e, 0x1e95f, 1},
- },
- LatinOffset: 11,
-}
-
-var _Pc = &RangeTable{
- R16: []Range16{
- {0x005f, 0x203f, 8160},
- {0x2040, 0x2054, 20},
- {0xfe33, 0xfe34, 1},
- {0xfe4d, 0xfe4f, 1},
- {0xff3f, 0xff3f, 1},
- },
-}
-
-var _Pd = &RangeTable{
- R16: []Range16{
- {0x002d, 0x058a, 1373},
- {0x05be, 0x1400, 3650},
- {0x1806, 0x2010, 2058},
- {0x2011, 0x2015, 1},
- {0x2e17, 0x2e1a, 3},
- {0x2e3a, 0x2e3b, 1},
- {0x2e40, 0x301c, 476},
- {0x3030, 0x30a0, 112},
- {0xfe31, 0xfe32, 1},
- {0xfe58, 0xfe63, 11},
- {0xff0d, 0xff0d, 1},
- },
- R32: []Range32{
- {0x10ead, 0x10ead, 1},
- },
-}
-
-var _Pe = &RangeTable{
- R16: []Range16{
- {0x0029, 0x005d, 52},
- {0x007d, 0x0f3b, 3774},
- {0x0f3d, 0x169c, 1887},
- {0x2046, 0x207e, 56},
- {0x208e, 0x2309, 635},
- {0x230b, 0x232a, 31},
- {0x2769, 0x2775, 2},
- {0x27c6, 0x27e7, 33},
- {0x27e9, 0x27ef, 2},
- {0x2984, 0x2998, 2},
- {0x29d9, 0x29db, 2},
- {0x29fd, 0x2e23, 1062},
- {0x2e25, 0x2e29, 2},
- {0x3009, 0x3011, 2},
- {0x3015, 0x301b, 2},
- {0x301e, 0x301f, 1},
- {0xfd3e, 0xfe18, 218},
- {0xfe36, 0xfe44, 2},
- {0xfe48, 0xfe5a, 18},
- {0xfe5c, 0xfe5e, 2},
- {0xff09, 0xff3d, 52},
- {0xff5d, 0xff63, 3},
- },
- LatinOffset: 1,
-}
-
-var _Pf = &RangeTable{
- R16: []Range16{
- {0x00bb, 0x2019, 8030},
- {0x201d, 0x203a, 29},
- {0x2e03, 0x2e05, 2},
- {0x2e0a, 0x2e0d, 3},
- {0x2e1d, 0x2e21, 4},
- },
-}
-
-var _Pi = &RangeTable{
- R16: []Range16{
- {0x00ab, 0x2018, 8045},
- {0x201b, 0x201c, 1},
- {0x201f, 0x2039, 26},
- {0x2e02, 0x2e04, 2},
- {0x2e09, 0x2e0c, 3},
- {0x2e1c, 0x2e20, 4},
- },
-}
-
-var _Po = &RangeTable{
- R16: []Range16{
- {0x0021, 0x0023, 1},
- {0x0025, 0x0027, 1},
- {0x002a, 0x002e, 2},
- {0x002f, 0x003a, 11},
- {0x003b, 0x003f, 4},
- {0x0040, 0x005c, 28},
- {0x00a1, 0x00a7, 6},
- {0x00b6, 0x00b7, 1},
- {0x00bf, 0x037e, 703},
- {0x0387, 0x055a, 467},
- {0x055b, 0x055f, 1},
- {0x0589, 0x05c0, 55},
- {0x05c3, 0x05c6, 3},
- {0x05f3, 0x05f4, 1},
- {0x0609, 0x060a, 1},
- {0x060c, 0x060d, 1},
- {0x061b, 0x061e, 3},
- {0x061f, 0x066a, 75},
- {0x066b, 0x066d, 1},
- {0x06d4, 0x0700, 44},
- {0x0701, 0x070d, 1},
- {0x07f7, 0x07f9, 1},
- {0x0830, 0x083e, 1},
- {0x085e, 0x0964, 262},
- {0x0965, 0x0970, 11},
- {0x09fd, 0x0a76, 121},
- {0x0af0, 0x0c77, 391},
- {0x0c84, 0x0df4, 368},
- {0x0e4f, 0x0e5a, 11},
- {0x0e5b, 0x0f04, 169},
- {0x0f05, 0x0f12, 1},
- {0x0f14, 0x0f85, 113},
- {0x0fd0, 0x0fd4, 1},
- {0x0fd9, 0x0fda, 1},
- {0x104a, 0x104f, 1},
- {0x10fb, 0x1360, 613},
- {0x1361, 0x1368, 1},
- {0x166e, 0x16eb, 125},
- {0x16ec, 0x16ed, 1},
- {0x1735, 0x1736, 1},
- {0x17d4, 0x17d6, 1},
- {0x17d8, 0x17da, 1},
- {0x1800, 0x1805, 1},
- {0x1807, 0x180a, 1},
- {0x1944, 0x1945, 1},
- {0x1a1e, 0x1a1f, 1},
- {0x1aa0, 0x1aa6, 1},
- {0x1aa8, 0x1aad, 1},
- {0x1b5a, 0x1b60, 1},
- {0x1bfc, 0x1bff, 1},
- {0x1c3b, 0x1c3f, 1},
- {0x1c7e, 0x1c7f, 1},
- {0x1cc0, 0x1cc7, 1},
- {0x1cd3, 0x2016, 835},
- {0x2017, 0x2020, 9},
- {0x2021, 0x2027, 1},
- {0x2030, 0x2038, 1},
- {0x203b, 0x203e, 1},
- {0x2041, 0x2043, 1},
- {0x2047, 0x2051, 1},
- {0x2053, 0x2055, 2},
- {0x2056, 0x205e, 1},
- {0x2cf9, 0x2cfc, 1},
- {0x2cfe, 0x2cff, 1},
- {0x2d70, 0x2e00, 144},
- {0x2e01, 0x2e06, 5},
- {0x2e07, 0x2e08, 1},
- {0x2e0b, 0x2e0e, 3},
- {0x2e0f, 0x2e16, 1},
- {0x2e18, 0x2e19, 1},
- {0x2e1b, 0x2e1e, 3},
- {0x2e1f, 0x2e2a, 11},
- {0x2e2b, 0x2e2e, 1},
- {0x2e30, 0x2e39, 1},
- {0x2e3c, 0x2e3f, 1},
- {0x2e41, 0x2e43, 2},
- {0x2e44, 0x2e4f, 1},
- {0x2e52, 0x3001, 431},
- {0x3002, 0x3003, 1},
- {0x303d, 0x30fb, 190},
- {0xa4fe, 0xa4ff, 1},
- {0xa60d, 0xa60f, 1},
- {0xa673, 0xa67e, 11},
- {0xa6f2, 0xa6f7, 1},
- {0xa874, 0xa877, 1},
- {0xa8ce, 0xa8cf, 1},
- {0xa8f8, 0xa8fa, 1},
- {0xa8fc, 0xa92e, 50},
- {0xa92f, 0xa95f, 48},
- {0xa9c1, 0xa9cd, 1},
- {0xa9de, 0xa9df, 1},
- {0xaa5c, 0xaa5f, 1},
- {0xaade, 0xaadf, 1},
- {0xaaf0, 0xaaf1, 1},
- {0xabeb, 0xfe10, 21029},
- {0xfe11, 0xfe16, 1},
- {0xfe19, 0xfe30, 23},
- {0xfe45, 0xfe46, 1},
- {0xfe49, 0xfe4c, 1},
- {0xfe50, 0xfe52, 1},
- {0xfe54, 0xfe57, 1},
- {0xfe5f, 0xfe61, 1},
- {0xfe68, 0xfe6a, 2},
- {0xfe6b, 0xff01, 150},
- {0xff02, 0xff03, 1},
- {0xff05, 0xff07, 1},
- {0xff0a, 0xff0e, 2},
- {0xff0f, 0xff1a, 11},
- {0xff1b, 0xff1f, 4},
- {0xff20, 0xff3c, 28},
- {0xff61, 0xff64, 3},
- {0xff65, 0xff65, 1},
- },
- R32: []Range32{
- {0x10100, 0x10102, 1},
- {0x1039f, 0x103d0, 49},
- {0x1056f, 0x10857, 744},
- {0x1091f, 0x1093f, 32},
- {0x10a50, 0x10a58, 1},
- {0x10a7f, 0x10af0, 113},
- {0x10af1, 0x10af6, 1},
- {0x10b39, 0x10b3f, 1},
- {0x10b99, 0x10b9c, 1},
- {0x10f55, 0x10f59, 1},
- {0x11047, 0x1104d, 1},
- {0x110bb, 0x110bc, 1},
- {0x110be, 0x110c1, 1},
- {0x11140, 0x11143, 1},
- {0x11174, 0x11175, 1},
- {0x111c5, 0x111c8, 1},
- {0x111cd, 0x111db, 14},
- {0x111dd, 0x111df, 1},
- {0x11238, 0x1123d, 1},
- {0x112a9, 0x1144b, 418},
- {0x1144c, 0x1144f, 1},
- {0x1145a, 0x1145b, 1},
- {0x1145d, 0x114c6, 105},
- {0x115c1, 0x115d7, 1},
- {0x11641, 0x11643, 1},
- {0x11660, 0x1166c, 1},
- {0x1173c, 0x1173e, 1},
- {0x1183b, 0x11944, 265},
- {0x11945, 0x11946, 1},
- {0x119e2, 0x11a3f, 93},
- {0x11a40, 0x11a46, 1},
- {0x11a9a, 0x11a9c, 1},
- {0x11a9e, 0x11aa2, 1},
- {0x11c41, 0x11c45, 1},
- {0x11c70, 0x11c71, 1},
- {0x11ef7, 0x11ef8, 1},
- {0x11fff, 0x12470, 1137},
- {0x12471, 0x12474, 1},
- {0x16a6e, 0x16a6f, 1},
- {0x16af5, 0x16b37, 66},
- {0x16b38, 0x16b3b, 1},
- {0x16b44, 0x16e97, 851},
- {0x16e98, 0x16e9a, 1},
- {0x16fe2, 0x1bc9f, 19645},
- {0x1da87, 0x1da8b, 1},
- {0x1e95e, 0x1e95f, 1},
- },
- LatinOffset: 8,
-}
-
-var _Ps = &RangeTable{
- R16: []Range16{
- {0x0028, 0x005b, 51},
- {0x007b, 0x0f3a, 3775},
- {0x0f3c, 0x169b, 1887},
- {0x201a, 0x201e, 4},
- {0x2045, 0x207d, 56},
- {0x208d, 0x2308, 635},
- {0x230a, 0x2329, 31},
- {0x2768, 0x2774, 2},
- {0x27c5, 0x27e6, 33},
- {0x27e8, 0x27ee, 2},
- {0x2983, 0x2997, 2},
- {0x29d8, 0x29da, 2},
- {0x29fc, 0x2e22, 1062},
- {0x2e24, 0x2e28, 2},
- {0x2e42, 0x3008, 454},
- {0x300a, 0x3010, 2},
- {0x3014, 0x301a, 2},
- {0x301d, 0xfd3f, 52514},
- {0xfe17, 0xfe35, 30},
- {0xfe37, 0xfe43, 2},
- {0xfe47, 0xfe59, 18},
- {0xfe5b, 0xfe5d, 2},
- {0xff08, 0xff3b, 51},
- {0xff5b, 0xff5f, 4},
- {0xff62, 0xff62, 1},
- },
- LatinOffset: 1,
-}
-
-var _S = &RangeTable{
- R16: []Range16{
- {0x0024, 0x002b, 7},
- {0x003c, 0x003e, 1},
- {0x005e, 0x0060, 2},
- {0x007c, 0x007e, 2},
- {0x00a2, 0x00a6, 1},
- {0x00a8, 0x00a9, 1},
- {0x00ac, 0x00ae, 2},
- {0x00af, 0x00b1, 1},
- {0x00b4, 0x00b8, 4},
- {0x00d7, 0x00f7, 32},
- {0x02c2, 0x02c5, 1},
- {0x02d2, 0x02df, 1},
- {0x02e5, 0x02eb, 1},
- {0x02ed, 0x02ef, 2},
- {0x02f0, 0x02ff, 1},
- {0x0375, 0x0384, 15},
- {0x0385, 0x03f6, 113},
- {0x0482, 0x058d, 267},
- {0x058e, 0x058f, 1},
- {0x0606, 0x0608, 1},
- {0x060b, 0x060e, 3},
- {0x060f, 0x06de, 207},
- {0x06e9, 0x06fd, 20},
- {0x06fe, 0x07f6, 248},
- {0x07fe, 0x07ff, 1},
- {0x09f2, 0x09f3, 1},
- {0x09fa, 0x09fb, 1},
- {0x0af1, 0x0b70, 127},
- {0x0bf3, 0x0bfa, 1},
- {0x0c7f, 0x0d4f, 208},
- {0x0d79, 0x0e3f, 198},
- {0x0f01, 0x0f03, 1},
- {0x0f13, 0x0f15, 2},
- {0x0f16, 0x0f17, 1},
- {0x0f1a, 0x0f1f, 1},
- {0x0f34, 0x0f38, 2},
- {0x0fbe, 0x0fc5, 1},
- {0x0fc7, 0x0fcc, 1},
- {0x0fce, 0x0fcf, 1},
- {0x0fd5, 0x0fd8, 1},
- {0x109e, 0x109f, 1},
- {0x1390, 0x1399, 1},
- {0x166d, 0x17db, 366},
- {0x1940, 0x19de, 158},
- {0x19df, 0x19ff, 1},
- {0x1b61, 0x1b6a, 1},
- {0x1b74, 0x1b7c, 1},
- {0x1fbd, 0x1fbf, 2},
- {0x1fc0, 0x1fc1, 1},
- {0x1fcd, 0x1fcf, 1},
- {0x1fdd, 0x1fdf, 1},
- {0x1fed, 0x1fef, 1},
- {0x1ffd, 0x1ffe, 1},
- {0x2044, 0x2052, 14},
- {0x207a, 0x207c, 1},
- {0x208a, 0x208c, 1},
- {0x20a0, 0x20bf, 1},
- {0x2100, 0x2101, 1},
- {0x2103, 0x2106, 1},
- {0x2108, 0x2109, 1},
- {0x2114, 0x2116, 2},
- {0x2117, 0x2118, 1},
- {0x211e, 0x2123, 1},
- {0x2125, 0x2129, 2},
- {0x212e, 0x213a, 12},
- {0x213b, 0x2140, 5},
- {0x2141, 0x2144, 1},
- {0x214a, 0x214d, 1},
- {0x214f, 0x218a, 59},
- {0x218b, 0x2190, 5},
- {0x2191, 0x2307, 1},
- {0x230c, 0x2328, 1},
- {0x232b, 0x2426, 1},
- {0x2440, 0x244a, 1},
- {0x249c, 0x24e9, 1},
- {0x2500, 0x2767, 1},
- {0x2794, 0x27c4, 1},
- {0x27c7, 0x27e5, 1},
- {0x27f0, 0x2982, 1},
- {0x2999, 0x29d7, 1},
- {0x29dc, 0x29fb, 1},
- {0x29fe, 0x2b73, 1},
- {0x2b76, 0x2b95, 1},
- {0x2b97, 0x2bff, 1},
- {0x2ce5, 0x2cea, 1},
- {0x2e50, 0x2e51, 1},
- {0x2e80, 0x2e99, 1},
- {0x2e9b, 0x2ef3, 1},
- {0x2f00, 0x2fd5, 1},
- {0x2ff0, 0x2ffb, 1},
- {0x3004, 0x3012, 14},
- {0x3013, 0x3020, 13},
- {0x3036, 0x3037, 1},
- {0x303e, 0x303f, 1},
- {0x309b, 0x309c, 1},
- {0x3190, 0x3191, 1},
- {0x3196, 0x319f, 1},
- {0x31c0, 0x31e3, 1},
- {0x3200, 0x321e, 1},
- {0x322a, 0x3247, 1},
- {0x3250, 0x3260, 16},
- {0x3261, 0x327f, 1},
- {0x328a, 0x32b0, 1},
- {0x32c0, 0x33ff, 1},
- {0x4dc0, 0x4dff, 1},
- {0xa490, 0xa4c6, 1},
- {0xa700, 0xa716, 1},
- {0xa720, 0xa721, 1},
- {0xa789, 0xa78a, 1},
- {0xa828, 0xa82b, 1},
- {0xa836, 0xa839, 1},
- {0xaa77, 0xaa79, 1},
- {0xab5b, 0xab6a, 15},
- {0xab6b, 0xfb29, 20414},
- {0xfbb2, 0xfbc1, 1},
- {0xfdfc, 0xfdfd, 1},
- {0xfe62, 0xfe64, 2},
- {0xfe65, 0xfe66, 1},
- {0xfe69, 0xff04, 155},
- {0xff0b, 0xff1c, 17},
- {0xff1d, 0xff1e, 1},
- {0xff3e, 0xff40, 2},
- {0xff5c, 0xff5e, 2},
- {0xffe0, 0xffe6, 1},
- {0xffe8, 0xffee, 1},
- {0xfffc, 0xfffd, 1},
- },
- R32: []Range32{
- {0x10137, 0x1013f, 1},
- {0x10179, 0x10189, 1},
- {0x1018c, 0x1018e, 1},
- {0x10190, 0x1019c, 1},
- {0x101a0, 0x101d0, 48},
- {0x101d1, 0x101fc, 1},
- {0x10877, 0x10878, 1},
- {0x10ac8, 0x1173f, 3191},
- {0x11fd5, 0x11ff1, 1},
- {0x16b3c, 0x16b3f, 1},
- {0x16b45, 0x1bc9c, 20823},
- {0x1d000, 0x1d0f5, 1},
- {0x1d100, 0x1d126, 1},
- {0x1d129, 0x1d164, 1},
- {0x1d16a, 0x1d16c, 1},
- {0x1d183, 0x1d184, 1},
- {0x1d18c, 0x1d1a9, 1},
- {0x1d1ae, 0x1d1e8, 1},
- {0x1d200, 0x1d241, 1},
- {0x1d245, 0x1d300, 187},
- {0x1d301, 0x1d356, 1},
- {0x1d6c1, 0x1d6db, 26},
- {0x1d6fb, 0x1d715, 26},
- {0x1d735, 0x1d74f, 26},
- {0x1d76f, 0x1d789, 26},
- {0x1d7a9, 0x1d7c3, 26},
- {0x1d800, 0x1d9ff, 1},
- {0x1da37, 0x1da3a, 1},
- {0x1da6d, 0x1da74, 1},
- {0x1da76, 0x1da83, 1},
- {0x1da85, 0x1da86, 1},
- {0x1e14f, 0x1e2ff, 432},
- {0x1ecac, 0x1ecb0, 4},
- {0x1ed2e, 0x1eef0, 450},
- {0x1eef1, 0x1f000, 271},
- {0x1f001, 0x1f02b, 1},
- {0x1f030, 0x1f093, 1},
- {0x1f0a0, 0x1f0ae, 1},
- {0x1f0b1, 0x1f0bf, 1},
- {0x1f0c1, 0x1f0cf, 1},
- {0x1f0d1, 0x1f0f5, 1},
- {0x1f10d, 0x1f1ad, 1},
- {0x1f1e6, 0x1f202, 1},
- {0x1f210, 0x1f23b, 1},
- {0x1f240, 0x1f248, 1},
- {0x1f250, 0x1f251, 1},
- {0x1f260, 0x1f265, 1},
- {0x1f300, 0x1f6d7, 1},
- {0x1f6e0, 0x1f6ec, 1},
- {0x1f6f0, 0x1f6fc, 1},
- {0x1f700, 0x1f773, 1},
- {0x1f780, 0x1f7d8, 1},
- {0x1f7e0, 0x1f7eb, 1},
- {0x1f800, 0x1f80b, 1},
- {0x1f810, 0x1f847, 1},
- {0x1f850, 0x1f859, 1},
- {0x1f860, 0x1f887, 1},
- {0x1f890, 0x1f8ad, 1},
- {0x1f8b0, 0x1f8b1, 1},
- {0x1f900, 0x1f978, 1},
- {0x1f97a, 0x1f9cb, 1},
- {0x1f9cd, 0x1fa53, 1},
- {0x1fa60, 0x1fa6d, 1},
- {0x1fa70, 0x1fa74, 1},
- {0x1fa78, 0x1fa7a, 1},
- {0x1fa80, 0x1fa86, 1},
- {0x1fa90, 0x1faa8, 1},
- {0x1fab0, 0x1fab6, 1},
- {0x1fac0, 0x1fac2, 1},
- {0x1fad0, 0x1fad6, 1},
- {0x1fb00, 0x1fb92, 1},
- {0x1fb94, 0x1fbca, 1},
- },
- LatinOffset: 10,
-}
-
-var _Sc = &RangeTable{
- R16: []Range16{
- {0x0024, 0x00a2, 126},
- {0x00a3, 0x00a5, 1},
- {0x058f, 0x060b, 124},
- {0x07fe, 0x07ff, 1},
- {0x09f2, 0x09f3, 1},
- {0x09fb, 0x0af1, 246},
- {0x0bf9, 0x0e3f, 582},
- {0x17db, 0x20a0, 2245},
- {0x20a1, 0x20bf, 1},
- {0xa838, 0xfdfc, 21956},
- {0xfe69, 0xff04, 155},
- {0xffe0, 0xffe1, 1},
- {0xffe5, 0xffe6, 1},
- },
- R32: []Range32{
- {0x11fdd, 0x11fe0, 1},
- {0x1e2ff, 0x1ecb0, 2481},
- },
- LatinOffset: 2,
-}
-
-var _Sk = &RangeTable{
- R16: []Range16{
- {0x005e, 0x0060, 2},
- {0x00a8, 0x00af, 7},
- {0x00b4, 0x00b8, 4},
- {0x02c2, 0x02c5, 1},
- {0x02d2, 0x02df, 1},
- {0x02e5, 0x02eb, 1},
- {0x02ed, 0x02ef, 2},
- {0x02f0, 0x02ff, 1},
- {0x0375, 0x0384, 15},
- {0x0385, 0x1fbd, 7224},
- {0x1fbf, 0x1fc1, 1},
- {0x1fcd, 0x1fcf, 1},
- {0x1fdd, 0x1fdf, 1},
- {0x1fed, 0x1fef, 1},
- {0x1ffd, 0x1ffe, 1},
- {0x309b, 0x309c, 1},
- {0xa700, 0xa716, 1},
- {0xa720, 0xa721, 1},
- {0xa789, 0xa78a, 1},
- {0xab5b, 0xab6a, 15},
- {0xab6b, 0xfbb2, 20551},
- {0xfbb3, 0xfbc1, 1},
- {0xff3e, 0xff40, 2},
- {0xffe3, 0xffe3, 1},
- },
- R32: []Range32{
- {0x1f3fb, 0x1f3ff, 1},
- },
- LatinOffset: 3,
-}
-
-var _Sm = &RangeTable{
- R16: []Range16{
- {0x002b, 0x003c, 17},
- {0x003d, 0x003e, 1},
- {0x007c, 0x007e, 2},
- {0x00ac, 0x00b1, 5},
- {0x00d7, 0x00f7, 32},
- {0x03f6, 0x0606, 528},
- {0x0607, 0x0608, 1},
- {0x2044, 0x2052, 14},
- {0x207a, 0x207c, 1},
- {0x208a, 0x208c, 1},
- {0x2118, 0x2140, 40},
- {0x2141, 0x2144, 1},
- {0x214b, 0x2190, 69},
- {0x2191, 0x2194, 1},
- {0x219a, 0x219b, 1},
- {0x21a0, 0x21a6, 3},
- {0x21ae, 0x21ce, 32},
- {0x21cf, 0x21d2, 3},
- {0x21d4, 0x21f4, 32},
- {0x21f5, 0x22ff, 1},
- {0x2320, 0x2321, 1},
- {0x237c, 0x239b, 31},
- {0x239c, 0x23b3, 1},
- {0x23dc, 0x23e1, 1},
- {0x25b7, 0x25c1, 10},
- {0x25f8, 0x25ff, 1},
- {0x266f, 0x27c0, 337},
- {0x27c1, 0x27c4, 1},
- {0x27c7, 0x27e5, 1},
- {0x27f0, 0x27ff, 1},
- {0x2900, 0x2982, 1},
- {0x2999, 0x29d7, 1},
- {0x29dc, 0x29fb, 1},
- {0x29fe, 0x2aff, 1},
- {0x2b30, 0x2b44, 1},
- {0x2b47, 0x2b4c, 1},
- {0xfb29, 0xfe62, 825},
- {0xfe64, 0xfe66, 1},
- {0xff0b, 0xff1c, 17},
- {0xff1d, 0xff1e, 1},
- {0xff5c, 0xff5e, 2},
- {0xffe2, 0xffe9, 7},
- {0xffea, 0xffec, 1},
- },
- R32: []Range32{
- {0x1d6c1, 0x1d6db, 26},
- {0x1d6fb, 0x1d715, 26},
- {0x1d735, 0x1d74f, 26},
- {0x1d76f, 0x1d789, 26},
- {0x1d7a9, 0x1d7c3, 26},
- {0x1eef0, 0x1eef1, 1},
- },
- LatinOffset: 5,
-}
-
-var _So = &RangeTable{
- R16: []Range16{
- {0x00a6, 0x00a9, 3},
- {0x00ae, 0x00b0, 2},
- {0x0482, 0x058d, 267},
- {0x058e, 0x060e, 128},
- {0x060f, 0x06de, 207},
- {0x06e9, 0x06fd, 20},
- {0x06fe, 0x07f6, 248},
- {0x09fa, 0x0b70, 374},
- {0x0bf3, 0x0bf8, 1},
- {0x0bfa, 0x0c7f, 133},
- {0x0d4f, 0x0d79, 42},
- {0x0f01, 0x0f03, 1},
- {0x0f13, 0x0f15, 2},
- {0x0f16, 0x0f17, 1},
- {0x0f1a, 0x0f1f, 1},
- {0x0f34, 0x0f38, 2},
- {0x0fbe, 0x0fc5, 1},
- {0x0fc7, 0x0fcc, 1},
- {0x0fce, 0x0fcf, 1},
- {0x0fd5, 0x0fd8, 1},
- {0x109e, 0x109f, 1},
- {0x1390, 0x1399, 1},
- {0x166d, 0x1940, 723},
- {0x19de, 0x19ff, 1},
- {0x1b61, 0x1b6a, 1},
- {0x1b74, 0x1b7c, 1},
- {0x2100, 0x2101, 1},
- {0x2103, 0x2106, 1},
- {0x2108, 0x2109, 1},
- {0x2114, 0x2116, 2},
- {0x2117, 0x211e, 7},
- {0x211f, 0x2123, 1},
- {0x2125, 0x2129, 2},
- {0x212e, 0x213a, 12},
- {0x213b, 0x214a, 15},
- {0x214c, 0x214d, 1},
- {0x214f, 0x218a, 59},
- {0x218b, 0x2195, 10},
- {0x2196, 0x2199, 1},
- {0x219c, 0x219f, 1},
- {0x21a1, 0x21a2, 1},
- {0x21a4, 0x21a5, 1},
- {0x21a7, 0x21ad, 1},
- {0x21af, 0x21cd, 1},
- {0x21d0, 0x21d1, 1},
- {0x21d3, 0x21d5, 2},
- {0x21d6, 0x21f3, 1},
- {0x2300, 0x2307, 1},
- {0x230c, 0x231f, 1},
- {0x2322, 0x2328, 1},
- {0x232b, 0x237b, 1},
- {0x237d, 0x239a, 1},
- {0x23b4, 0x23db, 1},
- {0x23e2, 0x2426, 1},
- {0x2440, 0x244a, 1},
- {0x249c, 0x24e9, 1},
- {0x2500, 0x25b6, 1},
- {0x25b8, 0x25c0, 1},
- {0x25c2, 0x25f7, 1},
- {0x2600, 0x266e, 1},
- {0x2670, 0x2767, 1},
- {0x2794, 0x27bf, 1},
- {0x2800, 0x28ff, 1},
- {0x2b00, 0x2b2f, 1},
- {0x2b45, 0x2b46, 1},
- {0x2b4d, 0x2b73, 1},
- {0x2b76, 0x2b95, 1},
- {0x2b97, 0x2bff, 1},
- {0x2ce5, 0x2cea, 1},
- {0x2e50, 0x2e51, 1},
- {0x2e80, 0x2e99, 1},
- {0x2e9b, 0x2ef3, 1},
- {0x2f00, 0x2fd5, 1},
- {0x2ff0, 0x2ffb, 1},
- {0x3004, 0x3012, 14},
- {0x3013, 0x3020, 13},
- {0x3036, 0x3037, 1},
- {0x303e, 0x303f, 1},
- {0x3190, 0x3191, 1},
- {0x3196, 0x319f, 1},
- {0x31c0, 0x31e3, 1},
- {0x3200, 0x321e, 1},
- {0x322a, 0x3247, 1},
- {0x3250, 0x3260, 16},
- {0x3261, 0x327f, 1},
- {0x328a, 0x32b0, 1},
- {0x32c0, 0x33ff, 1},
- {0x4dc0, 0x4dff, 1},
- {0xa490, 0xa4c6, 1},
- {0xa828, 0xa82b, 1},
- {0xa836, 0xa837, 1},
- {0xa839, 0xaa77, 574},
- {0xaa78, 0xaa79, 1},
- {0xfdfd, 0xffe4, 487},
- {0xffe8, 0xffed, 5},
- {0xffee, 0xfffc, 14},
- {0xfffd, 0xfffd, 1},
- },
- R32: []Range32{
- {0x10137, 0x1013f, 1},
- {0x10179, 0x10189, 1},
- {0x1018c, 0x1018e, 1},
- {0x10190, 0x1019c, 1},
- {0x101a0, 0x101d0, 48},
- {0x101d1, 0x101fc, 1},
- {0x10877, 0x10878, 1},
- {0x10ac8, 0x1173f, 3191},
- {0x11fd5, 0x11fdc, 1},
- {0x11fe1, 0x11ff1, 1},
- {0x16b3c, 0x16b3f, 1},
- {0x16b45, 0x1bc9c, 20823},
- {0x1d000, 0x1d0f5, 1},
- {0x1d100, 0x1d126, 1},
- {0x1d129, 0x1d164, 1},
- {0x1d16a, 0x1d16c, 1},
- {0x1d183, 0x1d184, 1},
- {0x1d18c, 0x1d1a9, 1},
- {0x1d1ae, 0x1d1e8, 1},
- {0x1d200, 0x1d241, 1},
- {0x1d245, 0x1d300, 187},
- {0x1d301, 0x1d356, 1},
- {0x1d800, 0x1d9ff, 1},
- {0x1da37, 0x1da3a, 1},
- {0x1da6d, 0x1da74, 1},
- {0x1da76, 0x1da83, 1},
- {0x1da85, 0x1da86, 1},
- {0x1e14f, 0x1ecac, 2909},
- {0x1ed2e, 0x1f000, 722},
- {0x1f001, 0x1f02b, 1},
- {0x1f030, 0x1f093, 1},
- {0x1f0a0, 0x1f0ae, 1},
- {0x1f0b1, 0x1f0bf, 1},
- {0x1f0c1, 0x1f0cf, 1},
- {0x1f0d1, 0x1f0f5, 1},
- {0x1f10d, 0x1f1ad, 1},
- {0x1f1e6, 0x1f202, 1},
- {0x1f210, 0x1f23b, 1},
- {0x1f240, 0x1f248, 1},
- {0x1f250, 0x1f251, 1},
- {0x1f260, 0x1f265, 1},
- {0x1f300, 0x1f3fa, 1},
- {0x1f400, 0x1f6d7, 1},
- {0x1f6e0, 0x1f6ec, 1},
- {0x1f6f0, 0x1f6fc, 1},
- {0x1f700, 0x1f773, 1},
- {0x1f780, 0x1f7d8, 1},
- {0x1f7e0, 0x1f7eb, 1},
- {0x1f800, 0x1f80b, 1},
- {0x1f810, 0x1f847, 1},
- {0x1f850, 0x1f859, 1},
- {0x1f860, 0x1f887, 1},
- {0x1f890, 0x1f8ad, 1},
- {0x1f8b0, 0x1f8b1, 1},
- {0x1f900, 0x1f978, 1},
- {0x1f97a, 0x1f9cb, 1},
- {0x1f9cd, 0x1fa53, 1},
- {0x1fa60, 0x1fa6d, 1},
- {0x1fa70, 0x1fa74, 1},
- {0x1fa78, 0x1fa7a, 1},
- {0x1fa80, 0x1fa86, 1},
- {0x1fa90, 0x1faa8, 1},
- {0x1fab0, 0x1fab6, 1},
- {0x1fac0, 0x1fac2, 1},
- {0x1fad0, 0x1fad6, 1},
- {0x1fb00, 0x1fb92, 1},
- {0x1fb94, 0x1fbca, 1},
- },
- LatinOffset: 2,
-}
-
-var _Z = &RangeTable{
- R16: []Range16{
- {0x0020, 0x00a0, 128},
- {0x1680, 0x2000, 2432},
- {0x2001, 0x200a, 1},
- {0x2028, 0x2029, 1},
- {0x202f, 0x205f, 48},
- {0x3000, 0x3000, 1},
- },
- LatinOffset: 1,
-}
-
-var _Zl = &RangeTable{
- R16: []Range16{
- {0x2028, 0x2028, 1},
- },
-}
-
-var _Zp = &RangeTable{
- R16: []Range16{
- {0x2029, 0x2029, 1},
- },
-}
-
-var _Zs = &RangeTable{
- R16: []Range16{
- {0x0020, 0x00a0, 128},
- {0x1680, 0x2000, 2432},
- {0x2001, 0x200a, 1},
- {0x202f, 0x205f, 48},
- {0x3000, 0x3000, 1},
- },
- LatinOffset: 1,
-}
-
-// These variables have type *RangeTable.
-var (
- Cc = _Cc // Cc is the set of Unicode characters in category Cc (Other, control).
- Cf = _Cf // Cf is the set of Unicode characters in category Cf (Other, format).
- Co = _Co // Co is the set of Unicode characters in category Co (Other, private use).
- Cs = _Cs // Cs is the set of Unicode characters in category Cs (Other, surrogate).
- Digit = _Nd // Digit is the set of Unicode characters with the "decimal digit" property.
- Nd = _Nd // Nd is the set of Unicode characters in category Nd (Number, decimal digit).
- Letter = _L // Letter/L is the set of Unicode letters, category L.
- L = _L
- Lm = _Lm // Lm is the set of Unicode characters in category Lm (Letter, modifier).
- Lo = _Lo // Lo is the set of Unicode characters in category Lo (Letter, other).
- Lower = _Ll // Lower is the set of Unicode lower case letters.
- Ll = _Ll // Ll is the set of Unicode characters in category Ll (Letter, lowercase).
- Mark = _M // Mark/M is the set of Unicode mark characters, category M.
- M = _M
- Mc = _Mc // Mc is the set of Unicode characters in category Mc (Mark, spacing combining).
- Me = _Me // Me is the set of Unicode characters in category Me (Mark, enclosing).
- Mn = _Mn // Mn is the set of Unicode characters in category Mn (Mark, nonspacing).
- Nl = _Nl // Nl is the set of Unicode characters in category Nl (Number, letter).
- No = _No // No is the set of Unicode characters in category No (Number, other).
- Number = _N // Number/N is the set of Unicode number characters, category N.
- N = _N
- Other = _C // Other/C is the set of Unicode control and special characters, category C.
- C = _C
- Pc = _Pc // Pc is the set of Unicode characters in category Pc (Punctuation, connector).
- Pd = _Pd // Pd is the set of Unicode characters in category Pd (Punctuation, dash).
- Pe = _Pe // Pe is the set of Unicode characters in category Pe (Punctuation, close).
- Pf = _Pf // Pf is the set of Unicode characters in category Pf (Punctuation, final quote).
- Pi = _Pi // Pi is the set of Unicode characters in category Pi (Punctuation, initial quote).
- Po = _Po // Po is the set of Unicode characters in category Po (Punctuation, other).
- Ps = _Ps // Ps is the set of Unicode characters in category Ps (Punctuation, open).
- Punct = _P // Punct/P is the set of Unicode punctuation characters, category P.
- P = _P
- Sc = _Sc // Sc is the set of Unicode characters in category Sc (Symbol, currency).
- Sk = _Sk // Sk is the set of Unicode characters in category Sk (Symbol, modifier).
- Sm = _Sm // Sm is the set of Unicode characters in category Sm (Symbol, math).
- So = _So // So is the set of Unicode characters in category So (Symbol, other).
- Space = _Z // Space/Z is the set of Unicode space characters, category Z.
- Z = _Z
- Symbol = _S // Symbol/S is the set of Unicode symbol characters, category S.
- S = _S
- Title = _Lt // Title is the set of Unicode title case letters.
- Lt = _Lt // Lt is the set of Unicode characters in category Lt (Letter, titlecase).
- Upper = _Lu // Upper is the set of Unicode upper case letters.
- Lu = _Lu // Lu is the set of Unicode characters in category Lu (Letter, uppercase).
- Zl = _Zl // Zl is the set of Unicode characters in category Zl (Separator, line).
- Zp = _Zp // Zp is the set of Unicode characters in category Zp (Separator, paragraph).
- Zs = _Zs // Zs is the set of Unicode characters in category Zs (Separator, space).
-)
-
-// Scripts is the set of Unicode script tables.
-var Scripts = map[string]*RangeTable{
- "Adlam": Adlam,
- "Ahom": Ahom,
- "Anatolian_Hieroglyphs": Anatolian_Hieroglyphs,
- "Arabic": Arabic,
- "Armenian": Armenian,
- "Avestan": Avestan,
- "Balinese": Balinese,
- "Bamum": Bamum,
- "Bassa_Vah": Bassa_Vah,
- "Batak": Batak,
- "Bengali": Bengali,
- "Bhaiksuki": Bhaiksuki,
- "Bopomofo": Bopomofo,
- "Brahmi": Brahmi,
- "Braille": Braille,
- "Buginese": Buginese,
- "Buhid": Buhid,
- "Canadian_Aboriginal": Canadian_Aboriginal,
- "Carian": Carian,
- "Caucasian_Albanian": Caucasian_Albanian,
- "Chakma": Chakma,
- "Cham": Cham,
- "Cherokee": Cherokee,
- "Chorasmian": Chorasmian,
- "Common": Common,
- "Coptic": Coptic,
- "Cuneiform": Cuneiform,
- "Cypriot": Cypriot,
- "Cyrillic": Cyrillic,
- "Deseret": Deseret,
- "Devanagari": Devanagari,
- "Dives_Akuru": Dives_Akuru,
- "Dogra": Dogra,
- "Duployan": Duployan,
- "Egyptian_Hieroglyphs": Egyptian_Hieroglyphs,
- "Elbasan": Elbasan,
- "Elymaic": Elymaic,
- "Ethiopic": Ethiopic,
- "Georgian": Georgian,
- "Glagolitic": Glagolitic,
- "Gothic": Gothic,
- "Grantha": Grantha,
- "Greek": Greek,
- "Gujarati": Gujarati,
- "Gunjala_Gondi": Gunjala_Gondi,
- "Gurmukhi": Gurmukhi,
- "Han": Han,
- "Hangul": Hangul,
- "Hanifi_Rohingya": Hanifi_Rohingya,
- "Hanunoo": Hanunoo,
- "Hatran": Hatran,
- "Hebrew": Hebrew,
- "Hiragana": Hiragana,
- "Imperial_Aramaic": Imperial_Aramaic,
- "Inherited": Inherited,
- "Inscriptional_Pahlavi": Inscriptional_Pahlavi,
- "Inscriptional_Parthian": Inscriptional_Parthian,
- "Javanese": Javanese,
- "Kaithi": Kaithi,
- "Kannada": Kannada,
- "Katakana": Katakana,
- "Kayah_Li": Kayah_Li,
- "Kharoshthi": Kharoshthi,
- "Khitan_Small_Script": Khitan_Small_Script,
- "Khmer": Khmer,
- "Khojki": Khojki,
- "Khudawadi": Khudawadi,
- "Lao": Lao,
- "Latin": Latin,
- "Lepcha": Lepcha,
- "Limbu": Limbu,
- "Linear_A": Linear_A,
- "Linear_B": Linear_B,
- "Lisu": Lisu,
- "Lycian": Lycian,
- "Lydian": Lydian,
- "Mahajani": Mahajani,
- "Makasar": Makasar,
- "Malayalam": Malayalam,
- "Mandaic": Mandaic,
- "Manichaean": Manichaean,
- "Marchen": Marchen,
- "Masaram_Gondi": Masaram_Gondi,
- "Medefaidrin": Medefaidrin,
- "Meetei_Mayek": Meetei_Mayek,
- "Mende_Kikakui": Mende_Kikakui,
- "Meroitic_Cursive": Meroitic_Cursive,
- "Meroitic_Hieroglyphs": Meroitic_Hieroglyphs,
- "Miao": Miao,
- "Modi": Modi,
- "Mongolian": Mongolian,
- "Mro": Mro,
- "Multani": Multani,
- "Myanmar": Myanmar,
- "Nabataean": Nabataean,
- "Nandinagari": Nandinagari,
- "New_Tai_Lue": New_Tai_Lue,
- "Newa": Newa,
- "Nko": Nko,
- "Nushu": Nushu,
- "Nyiakeng_Puachue_Hmong": Nyiakeng_Puachue_Hmong,
- "Ogham": Ogham,
- "Ol_Chiki": Ol_Chiki,
- "Old_Hungarian": Old_Hungarian,
- "Old_Italic": Old_Italic,
- "Old_North_Arabian": Old_North_Arabian,
- "Old_Permic": Old_Permic,
- "Old_Persian": Old_Persian,
- "Old_Sogdian": Old_Sogdian,
- "Old_South_Arabian": Old_South_Arabian,
- "Old_Turkic": Old_Turkic,
- "Oriya": Oriya,
- "Osage": Osage,
- "Osmanya": Osmanya,
- "Pahawh_Hmong": Pahawh_Hmong,
- "Palmyrene": Palmyrene,
- "Pau_Cin_Hau": Pau_Cin_Hau,
- "Phags_Pa": Phags_Pa,
- "Phoenician": Phoenician,
- "Psalter_Pahlavi": Psalter_Pahlavi,
- "Rejang": Rejang,
- "Runic": Runic,
- "Samaritan": Samaritan,
- "Saurashtra": Saurashtra,
- "Sharada": Sharada,
- "Shavian": Shavian,
- "Siddham": Siddham,
- "SignWriting": SignWriting,
- "Sinhala": Sinhala,
- "Sogdian": Sogdian,
- "Sora_Sompeng": Sora_Sompeng,
- "Soyombo": Soyombo,
- "Sundanese": Sundanese,
- "Syloti_Nagri": Syloti_Nagri,
- "Syriac": Syriac,
- "Tagalog": Tagalog,
- "Tagbanwa": Tagbanwa,
- "Tai_Le": Tai_Le,
- "Tai_Tham": Tai_Tham,
- "Tai_Viet": Tai_Viet,
- "Takri": Takri,
- "Tamil": Tamil,
- "Tangut": Tangut,
- "Telugu": Telugu,
- "Thaana": Thaana,
- "Thai": Thai,
- "Tibetan": Tibetan,
- "Tifinagh": Tifinagh,
- "Tirhuta": Tirhuta,
- "Ugaritic": Ugaritic,
- "Vai": Vai,
- "Wancho": Wancho,
- "Warang_Citi": Warang_Citi,
- "Yezidi": Yezidi,
- "Yi": Yi,
- "Zanabazar_Square": Zanabazar_Square,
-}
-
-var _Adlam = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x1e900, 0x1e94b, 1},
- {0x1e950, 0x1e959, 1},
- {0x1e95e, 0x1e95f, 1},
- },
-}
-
-var _Ahom = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11700, 0x1171a, 1},
- {0x1171d, 0x1172b, 1},
- {0x11730, 0x1173f, 1},
- },
-}
-
-var _Anatolian_Hieroglyphs = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x14400, 0x14646, 1},
- },
-}
-
-var _Arabic = &RangeTable{
- R16: []Range16{
- {0x0600, 0x0604, 1},
- {0x0606, 0x060b, 1},
- {0x060d, 0x061a, 1},
- {0x061c, 0x0620, 2},
- {0x0621, 0x063f, 1},
- {0x0641, 0x064a, 1},
- {0x0656, 0x066f, 1},
- {0x0671, 0x06dc, 1},
- {0x06de, 0x06ff, 1},
- {0x0750, 0x077f, 1},
- {0x08a0, 0x08b4, 1},
- {0x08b6, 0x08c7, 1},
- {0x08d3, 0x08e1, 1},
- {0x08e3, 0x08ff, 1},
- {0xfb50, 0xfbc1, 1},
- {0xfbd3, 0xfd3d, 1},
- {0xfd50, 0xfd8f, 1},
- {0xfd92, 0xfdc7, 1},
- {0xfdf0, 0xfdfd, 1},
- {0xfe70, 0xfe74, 1},
- {0xfe76, 0xfefc, 1},
- },
- R32: []Range32{
- {0x10e60, 0x10e7e, 1},
- {0x1ee00, 0x1ee03, 1},
- {0x1ee05, 0x1ee1f, 1},
- {0x1ee21, 0x1ee22, 1},
- {0x1ee24, 0x1ee27, 3},
- {0x1ee29, 0x1ee32, 1},
- {0x1ee34, 0x1ee37, 1},
- {0x1ee39, 0x1ee3b, 2},
- {0x1ee42, 0x1ee47, 5},
- {0x1ee49, 0x1ee4d, 2},
- {0x1ee4e, 0x1ee4f, 1},
- {0x1ee51, 0x1ee52, 1},
- {0x1ee54, 0x1ee57, 3},
- {0x1ee59, 0x1ee61, 2},
- {0x1ee62, 0x1ee64, 2},
- {0x1ee67, 0x1ee6a, 1},
- {0x1ee6c, 0x1ee72, 1},
- {0x1ee74, 0x1ee77, 1},
- {0x1ee79, 0x1ee7c, 1},
- {0x1ee7e, 0x1ee80, 2},
- {0x1ee81, 0x1ee89, 1},
- {0x1ee8b, 0x1ee9b, 1},
- {0x1eea1, 0x1eea3, 1},
- {0x1eea5, 0x1eea9, 1},
- {0x1eeab, 0x1eebb, 1},
- {0x1eef0, 0x1eef1, 1},
- },
-}
-
-var _Armenian = &RangeTable{
- R16: []Range16{
- {0x0531, 0x0556, 1},
- {0x0559, 0x058a, 1},
- {0x058d, 0x058f, 1},
- {0xfb13, 0xfb17, 1},
- },
-}
-
-var _Avestan = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10b00, 0x10b35, 1},
- {0x10b39, 0x10b3f, 1},
- },
-}
-
-var _Balinese = &RangeTable{
- R16: []Range16{
- {0x1b00, 0x1b4b, 1},
- {0x1b50, 0x1b7c, 1},
- },
-}
-
-var _Bamum = &RangeTable{
- R16: []Range16{
- {0xa6a0, 0xa6f7, 1},
- },
- R32: []Range32{
- {0x16800, 0x16a38, 1},
- },
-}
-
-var _Bassa_Vah = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x16ad0, 0x16aed, 1},
- {0x16af0, 0x16af5, 1},
- },
-}
-
-var _Batak = &RangeTable{
- R16: []Range16{
- {0x1bc0, 0x1bf3, 1},
- {0x1bfc, 0x1bff, 1},
- },
-}
-
-var _Bengali = &RangeTable{
- R16: []Range16{
- {0x0980, 0x0983, 1},
- {0x0985, 0x098c, 1},
- {0x098f, 0x0990, 1},
- {0x0993, 0x09a8, 1},
- {0x09aa, 0x09b0, 1},
- {0x09b2, 0x09b6, 4},
- {0x09b7, 0x09b9, 1},
- {0x09bc, 0x09c4, 1},
- {0x09c7, 0x09c8, 1},
- {0x09cb, 0x09ce, 1},
- {0x09d7, 0x09dc, 5},
- {0x09dd, 0x09df, 2},
- {0x09e0, 0x09e3, 1},
- {0x09e6, 0x09fe, 1},
- },
-}
-
-var _Bhaiksuki = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11c00, 0x11c08, 1},
- {0x11c0a, 0x11c36, 1},
- {0x11c38, 0x11c45, 1},
- {0x11c50, 0x11c6c, 1},
- },
-}
-
-var _Bopomofo = &RangeTable{
- R16: []Range16{
- {0x02ea, 0x02eb, 1},
- {0x3105, 0x312f, 1},
- {0x31a0, 0x31bf, 1},
- },
-}
-
-var _Brahmi = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11000, 0x1104d, 1},
- {0x11052, 0x1106f, 1},
- {0x1107f, 0x1107f, 1},
- },
-}
-
-var _Braille = &RangeTable{
- R16: []Range16{
- {0x2800, 0x28ff, 1},
- },
-}
-
-var _Buginese = &RangeTable{
- R16: []Range16{
- {0x1a00, 0x1a1b, 1},
- {0x1a1e, 0x1a1f, 1},
- },
-}
-
-var _Buhid = &RangeTable{
- R16: []Range16{
- {0x1740, 0x1753, 1},
- },
-}
-
-var _Canadian_Aboriginal = &RangeTable{
- R16: []Range16{
- {0x1400, 0x167f, 1},
- {0x18b0, 0x18f5, 1},
- },
-}
-
-var _Carian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x102a0, 0x102d0, 1},
- },
-}
-
-var _Caucasian_Albanian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10530, 0x10563, 1},
- {0x1056f, 0x1056f, 1},
- },
-}
-
-var _Chakma = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11100, 0x11134, 1},
- {0x11136, 0x11147, 1},
- },
-}
-
-var _Cham = &RangeTable{
- R16: []Range16{
- {0xaa00, 0xaa36, 1},
- {0xaa40, 0xaa4d, 1},
- {0xaa50, 0xaa59, 1},
- {0xaa5c, 0xaa5f, 1},
- },
-}
-
-var _Cherokee = &RangeTable{
- R16: []Range16{
- {0x13a0, 0x13f5, 1},
- {0x13f8, 0x13fd, 1},
- {0xab70, 0xabbf, 1},
- },
-}
-
-var _Chorasmian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10fb0, 0x10fcb, 1},
- },
-}
-
-var _Common = &RangeTable{
- R16: []Range16{
- {0x0000, 0x0040, 1},
- {0x005b, 0x0060, 1},
- {0x007b, 0x00a9, 1},
- {0x00ab, 0x00b9, 1},
- {0x00bb, 0x00bf, 1},
- {0x00d7, 0x00f7, 32},
- {0x02b9, 0x02df, 1},
- {0x02e5, 0x02e9, 1},
- {0x02ec, 0x02ff, 1},
- {0x0374, 0x037e, 10},
- {0x0385, 0x0387, 2},
- {0x0605, 0x060c, 7},
- {0x061b, 0x061f, 4},
- {0x0640, 0x06dd, 157},
- {0x08e2, 0x0964, 130},
- {0x0965, 0x0e3f, 1242},
- {0x0fd5, 0x0fd8, 1},
- {0x10fb, 0x16eb, 1520},
- {0x16ec, 0x16ed, 1},
- {0x1735, 0x1736, 1},
- {0x1802, 0x1803, 1},
- {0x1805, 0x1cd3, 1230},
- {0x1ce1, 0x1ce9, 8},
- {0x1cea, 0x1cec, 1},
- {0x1cee, 0x1cf3, 1},
- {0x1cf5, 0x1cf7, 1},
- {0x1cfa, 0x2000, 774},
- {0x2001, 0x200b, 1},
- {0x200e, 0x2064, 1},
- {0x2066, 0x2070, 1},
- {0x2074, 0x207e, 1},
- {0x2080, 0x208e, 1},
- {0x20a0, 0x20bf, 1},
- {0x2100, 0x2125, 1},
- {0x2127, 0x2129, 1},
- {0x212c, 0x2131, 1},
- {0x2133, 0x214d, 1},
- {0x214f, 0x215f, 1},
- {0x2189, 0x218b, 1},
- {0x2190, 0x2426, 1},
- {0x2440, 0x244a, 1},
- {0x2460, 0x27ff, 1},
- {0x2900, 0x2b73, 1},
- {0x2b76, 0x2b95, 1},
- {0x2b97, 0x2bff, 1},
- {0x2e00, 0x2e52, 1},
- {0x2ff0, 0x2ffb, 1},
- {0x3000, 0x3004, 1},
- {0x3006, 0x3008, 2},
- {0x3009, 0x3020, 1},
- {0x3030, 0x3037, 1},
- {0x303c, 0x303f, 1},
- {0x309b, 0x309c, 1},
- {0x30a0, 0x30fb, 91},
- {0x30fc, 0x3190, 148},
- {0x3191, 0x319f, 1},
- {0x31c0, 0x31e3, 1},
- {0x3220, 0x325f, 1},
- {0x327f, 0x32cf, 1},
- {0x32ff, 0x3358, 89},
- {0x3359, 0x33ff, 1},
- {0x4dc0, 0x4dff, 1},
- {0xa700, 0xa721, 1},
- {0xa788, 0xa78a, 1},
- {0xa830, 0xa839, 1},
- {0xa92e, 0xa9cf, 161},
- {0xab5b, 0xab6a, 15},
- {0xab6b, 0xfd3e, 20947},
- {0xfd3f, 0xfe10, 209},
- {0xfe11, 0xfe19, 1},
- {0xfe30, 0xfe52, 1},
- {0xfe54, 0xfe66, 1},
- {0xfe68, 0xfe6b, 1},
- {0xfeff, 0xff01, 2},
- {0xff02, 0xff20, 1},
- {0xff3b, 0xff40, 1},
- {0xff5b, 0xff65, 1},
- {0xff70, 0xff9e, 46},
- {0xff9f, 0xffe0, 65},
- {0xffe1, 0xffe6, 1},
- {0xffe8, 0xffee, 1},
- {0xfff9, 0xfffd, 1},
- },
- R32: []Range32{
- {0x10100, 0x10102, 1},
- {0x10107, 0x10133, 1},
- {0x10137, 0x1013f, 1},
- {0x10190, 0x1019c, 1},
- {0x101d0, 0x101fc, 1},
- {0x102e1, 0x102fb, 1},
- {0x16fe2, 0x16fe3, 1},
- {0x1bca0, 0x1bca3, 1},
- {0x1d000, 0x1d0f5, 1},
- {0x1d100, 0x1d126, 1},
- {0x1d129, 0x1d166, 1},
- {0x1d16a, 0x1d17a, 1},
- {0x1d183, 0x1d184, 1},
- {0x1d18c, 0x1d1a9, 1},
- {0x1d1ae, 0x1d1e8, 1},
- {0x1d2e0, 0x1d2f3, 1},
- {0x1d300, 0x1d356, 1},
- {0x1d360, 0x1d378, 1},
- {0x1d400, 0x1d454, 1},
- {0x1d456, 0x1d49c, 1},
- {0x1d49e, 0x1d49f, 1},
- {0x1d4a2, 0x1d4a5, 3},
- {0x1d4a6, 0x1d4a9, 3},
- {0x1d4aa, 0x1d4ac, 1},
- {0x1d4ae, 0x1d4b9, 1},
- {0x1d4bb, 0x1d4bd, 2},
- {0x1d4be, 0x1d4c3, 1},
- {0x1d4c5, 0x1d505, 1},
- {0x1d507, 0x1d50a, 1},
- {0x1d50d, 0x1d514, 1},
- {0x1d516, 0x1d51c, 1},
- {0x1d51e, 0x1d539, 1},
- {0x1d53b, 0x1d53e, 1},
- {0x1d540, 0x1d544, 1},
- {0x1d546, 0x1d54a, 4},
- {0x1d54b, 0x1d550, 1},
- {0x1d552, 0x1d6a5, 1},
- {0x1d6a8, 0x1d7cb, 1},
- {0x1d7ce, 0x1d7ff, 1},
- {0x1ec71, 0x1ecb4, 1},
- {0x1ed01, 0x1ed3d, 1},
- {0x1f000, 0x1f02b, 1},
- {0x1f030, 0x1f093, 1},
- {0x1f0a0, 0x1f0ae, 1},
- {0x1f0b1, 0x1f0bf, 1},
- {0x1f0c1, 0x1f0cf, 1},
- {0x1f0d1, 0x1f0f5, 1},
- {0x1f100, 0x1f1ad, 1},
- {0x1f1e6, 0x1f1ff, 1},
- {0x1f201, 0x1f202, 1},
- {0x1f210, 0x1f23b, 1},
- {0x1f240, 0x1f248, 1},
- {0x1f250, 0x1f251, 1},
- {0x1f260, 0x1f265, 1},
- {0x1f300, 0x1f6d7, 1},
- {0x1f6e0, 0x1f6ec, 1},
- {0x1f6f0, 0x1f6fc, 1},
- {0x1f700, 0x1f773, 1},
- {0x1f780, 0x1f7d8, 1},
- {0x1f7e0, 0x1f7eb, 1},
- {0x1f800, 0x1f80b, 1},
- {0x1f810, 0x1f847, 1},
- {0x1f850, 0x1f859, 1},
- {0x1f860, 0x1f887, 1},
- {0x1f890, 0x1f8ad, 1},
- {0x1f8b0, 0x1f8b1, 1},
- {0x1f900, 0x1f978, 1},
- {0x1f97a, 0x1f9cb, 1},
- {0x1f9cd, 0x1fa53, 1},
- {0x1fa60, 0x1fa6d, 1},
- {0x1fa70, 0x1fa74, 1},
- {0x1fa78, 0x1fa7a, 1},
- {0x1fa80, 0x1fa86, 1},
- {0x1fa90, 0x1faa8, 1},
- {0x1fab0, 0x1fab6, 1},
- {0x1fac0, 0x1fac2, 1},
- {0x1fad0, 0x1fad6, 1},
- {0x1fb00, 0x1fb92, 1},
- {0x1fb94, 0x1fbca, 1},
- {0x1fbf0, 0x1fbf9, 1},
- {0xe0001, 0xe0020, 31},
- {0xe0021, 0xe007f, 1},
- },
- LatinOffset: 6,
-}
-
-var _Coptic = &RangeTable{
- R16: []Range16{
- {0x03e2, 0x03ef, 1},
- {0x2c80, 0x2cf3, 1},
- {0x2cf9, 0x2cff, 1},
- },
-}
-
-var _Cuneiform = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x12000, 0x12399, 1},
- {0x12400, 0x1246e, 1},
- {0x12470, 0x12474, 1},
- {0x12480, 0x12543, 1},
- },
-}
-
-var _Cypriot = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10800, 0x10805, 1},
- {0x10808, 0x1080a, 2},
- {0x1080b, 0x10835, 1},
- {0x10837, 0x10838, 1},
- {0x1083c, 0x1083f, 3},
- },
-}
-
-var _Cyrillic = &RangeTable{
- R16: []Range16{
- {0x0400, 0x0484, 1},
- {0x0487, 0x052f, 1},
- {0x1c80, 0x1c88, 1},
- {0x1d2b, 0x1d78, 77},
- {0x2de0, 0x2dff, 1},
- {0xa640, 0xa69f, 1},
- {0xfe2e, 0xfe2f, 1},
- },
-}
-
-var _Deseret = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10400, 0x1044f, 1},
- },
-}
-
-var _Devanagari = &RangeTable{
- R16: []Range16{
- {0x0900, 0x0950, 1},
- {0x0955, 0x0963, 1},
- {0x0966, 0x097f, 1},
- {0xa8e0, 0xa8ff, 1},
- },
-}
-
-var _Dives_Akuru = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11900, 0x11906, 1},
- {0x11909, 0x1190c, 3},
- {0x1190d, 0x11913, 1},
- {0x11915, 0x11916, 1},
- {0x11918, 0x11935, 1},
- {0x11937, 0x11938, 1},
- {0x1193b, 0x11946, 1},
- {0x11950, 0x11959, 1},
- },
-}
-
-var _Dogra = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11800, 0x1183b, 1},
- },
-}
-
-var _Duployan = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x1bc00, 0x1bc6a, 1},
- {0x1bc70, 0x1bc7c, 1},
- {0x1bc80, 0x1bc88, 1},
- {0x1bc90, 0x1bc99, 1},
- {0x1bc9c, 0x1bc9f, 1},
- },
-}
-
-var _Egyptian_Hieroglyphs = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x13000, 0x1342e, 1},
- {0x13430, 0x13438, 1},
- },
-}
-
-var _Elbasan = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10500, 0x10527, 1},
- },
-}
-
-var _Elymaic = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10fe0, 0x10ff6, 1},
- },
-}
-
-var _Ethiopic = &RangeTable{
- R16: []Range16{
- {0x1200, 0x1248, 1},
- {0x124a, 0x124d, 1},
- {0x1250, 0x1256, 1},
- {0x1258, 0x125a, 2},
- {0x125b, 0x125d, 1},
- {0x1260, 0x1288, 1},
- {0x128a, 0x128d, 1},
- {0x1290, 0x12b0, 1},
- {0x12b2, 0x12b5, 1},
- {0x12b8, 0x12be, 1},
- {0x12c0, 0x12c2, 2},
- {0x12c3, 0x12c5, 1},
- {0x12c8, 0x12d6, 1},
- {0x12d8, 0x1310, 1},
- {0x1312, 0x1315, 1},
- {0x1318, 0x135a, 1},
- {0x135d, 0x137c, 1},
- {0x1380, 0x1399, 1},
- {0x2d80, 0x2d96, 1},
- {0x2da0, 0x2da6, 1},
- {0x2da8, 0x2dae, 1},
- {0x2db0, 0x2db6, 1},
- {0x2db8, 0x2dbe, 1},
- {0x2dc0, 0x2dc6, 1},
- {0x2dc8, 0x2dce, 1},
- {0x2dd0, 0x2dd6, 1},
- {0x2dd8, 0x2dde, 1},
- {0xab01, 0xab06, 1},
- {0xab09, 0xab0e, 1},
- {0xab11, 0xab16, 1},
- {0xab20, 0xab26, 1},
- {0xab28, 0xab2e, 1},
- },
-}
-
-var _Georgian = &RangeTable{
- R16: []Range16{
- {0x10a0, 0x10c5, 1},
- {0x10c7, 0x10cd, 6},
- {0x10d0, 0x10fa, 1},
- {0x10fc, 0x10ff, 1},
- {0x1c90, 0x1cba, 1},
- {0x1cbd, 0x1cbf, 1},
- {0x2d00, 0x2d25, 1},
- {0x2d27, 0x2d2d, 6},
- },
-}
-
-var _Glagolitic = &RangeTable{
- R16: []Range16{
- {0x2c00, 0x2c2e, 1},
- {0x2c30, 0x2c5e, 1},
- },
- R32: []Range32{
- {0x1e000, 0x1e006, 1},
- {0x1e008, 0x1e018, 1},
- {0x1e01b, 0x1e021, 1},
- {0x1e023, 0x1e024, 1},
- {0x1e026, 0x1e02a, 1},
- },
-}
-
-var _Gothic = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10330, 0x1034a, 1},
- },
-}
-
-var _Grantha = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11300, 0x11303, 1},
- {0x11305, 0x1130c, 1},
- {0x1130f, 0x11310, 1},
- {0x11313, 0x11328, 1},
- {0x1132a, 0x11330, 1},
- {0x11332, 0x11333, 1},
- {0x11335, 0x11339, 1},
- {0x1133c, 0x11344, 1},
- {0x11347, 0x11348, 1},
- {0x1134b, 0x1134d, 1},
- {0x11350, 0x11357, 7},
- {0x1135d, 0x11363, 1},
- {0x11366, 0x1136c, 1},
- {0x11370, 0x11374, 1},
- },
-}
-
-var _Greek = &RangeTable{
- R16: []Range16{
- {0x0370, 0x0373, 1},
- {0x0375, 0x0377, 1},
- {0x037a, 0x037d, 1},
- {0x037f, 0x0384, 5},
- {0x0386, 0x0388, 2},
- {0x0389, 0x038a, 1},
- {0x038c, 0x038e, 2},
- {0x038f, 0x03a1, 1},
- {0x03a3, 0x03e1, 1},
- {0x03f0, 0x03ff, 1},
- {0x1d26, 0x1d2a, 1},
- {0x1d5d, 0x1d61, 1},
- {0x1d66, 0x1d6a, 1},
- {0x1dbf, 0x1f00, 321},
- {0x1f01, 0x1f15, 1},
- {0x1f18, 0x1f1d, 1},
- {0x1f20, 0x1f45, 1},
- {0x1f48, 0x1f4d, 1},
- {0x1f50, 0x1f57, 1},
- {0x1f59, 0x1f5f, 2},
- {0x1f60, 0x1f7d, 1},
- {0x1f80, 0x1fb4, 1},
- {0x1fb6, 0x1fc4, 1},
- {0x1fc6, 0x1fd3, 1},
- {0x1fd6, 0x1fdb, 1},
- {0x1fdd, 0x1fef, 1},
- {0x1ff2, 0x1ff4, 1},
- {0x1ff6, 0x1ffe, 1},
- {0x2126, 0xab65, 35391},
- },
- R32: []Range32{
- {0x10140, 0x1018e, 1},
- {0x101a0, 0x1d200, 53344},
- {0x1d201, 0x1d245, 1},
- },
-}
-
-var _Gujarati = &RangeTable{
- R16: []Range16{
- {0x0a81, 0x0a83, 1},
- {0x0a85, 0x0a8d, 1},
- {0x0a8f, 0x0a91, 1},
- {0x0a93, 0x0aa8, 1},
- {0x0aaa, 0x0ab0, 1},
- {0x0ab2, 0x0ab3, 1},
- {0x0ab5, 0x0ab9, 1},
- {0x0abc, 0x0ac5, 1},
- {0x0ac7, 0x0ac9, 1},
- {0x0acb, 0x0acd, 1},
- {0x0ad0, 0x0ae0, 16},
- {0x0ae1, 0x0ae3, 1},
- {0x0ae6, 0x0af1, 1},
- {0x0af9, 0x0aff, 1},
- },
-}
-
-var _Gunjala_Gondi = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11d60, 0x11d65, 1},
- {0x11d67, 0x11d68, 1},
- {0x11d6a, 0x11d8e, 1},
- {0x11d90, 0x11d91, 1},
- {0x11d93, 0x11d98, 1},
- {0x11da0, 0x11da9, 1},
- },
-}
-
-var _Gurmukhi = &RangeTable{
- R16: []Range16{
- {0x0a01, 0x0a03, 1},
- {0x0a05, 0x0a0a, 1},
- {0x0a0f, 0x0a10, 1},
- {0x0a13, 0x0a28, 1},
- {0x0a2a, 0x0a30, 1},
- {0x0a32, 0x0a33, 1},
- {0x0a35, 0x0a36, 1},
- {0x0a38, 0x0a39, 1},
- {0x0a3c, 0x0a3e, 2},
- {0x0a3f, 0x0a42, 1},
- {0x0a47, 0x0a48, 1},
- {0x0a4b, 0x0a4d, 1},
- {0x0a51, 0x0a59, 8},
- {0x0a5a, 0x0a5c, 1},
- {0x0a5e, 0x0a66, 8},
- {0x0a67, 0x0a76, 1},
- },
-}
-
-var _Han = &RangeTable{
- R16: []Range16{
- {0x2e80, 0x2e99, 1},
- {0x2e9b, 0x2ef3, 1},
- {0x2f00, 0x2fd5, 1},
- {0x3005, 0x3007, 2},
- {0x3021, 0x3029, 1},
- {0x3038, 0x303b, 1},
- {0x3400, 0x4dbf, 1},
- {0x4e00, 0x9ffc, 1},
- {0xf900, 0xfa6d, 1},
- {0xfa70, 0xfad9, 1},
- },
- R32: []Range32{
- {0x16ff0, 0x16ff1, 1},
- {0x20000, 0x2a6dd, 1},
- {0x2a700, 0x2b734, 1},
- {0x2b740, 0x2b81d, 1},
- {0x2b820, 0x2cea1, 1},
- {0x2ceb0, 0x2ebe0, 1},
- {0x2f800, 0x2fa1d, 1},
- {0x30000, 0x3134a, 1},
- },
-}
-
-var _Hangul = &RangeTable{
- R16: []Range16{
- {0x1100, 0x11ff, 1},
- {0x302e, 0x302f, 1},
- {0x3131, 0x318e, 1},
- {0x3200, 0x321e, 1},
- {0x3260, 0x327e, 1},
- {0xa960, 0xa97c, 1},
- {0xac00, 0xd7a3, 1},
- {0xd7b0, 0xd7c6, 1},
- {0xd7cb, 0xd7fb, 1},
- {0xffa0, 0xffbe, 1},
- {0xffc2, 0xffc7, 1},
- {0xffca, 0xffcf, 1},
- {0xffd2, 0xffd7, 1},
- {0xffda, 0xffdc, 1},
- },
-}
-
-var _Hanifi_Rohingya = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10d00, 0x10d27, 1},
- {0x10d30, 0x10d39, 1},
- },
-}
-
-var _Hanunoo = &RangeTable{
- R16: []Range16{
- {0x1720, 0x1734, 1},
- },
-}
-
-var _Hatran = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x108e0, 0x108f2, 1},
- {0x108f4, 0x108f5, 1},
- {0x108fb, 0x108ff, 1},
- },
-}
-
-var _Hebrew = &RangeTable{
- R16: []Range16{
- {0x0591, 0x05c7, 1},
- {0x05d0, 0x05ea, 1},
- {0x05ef, 0x05f4, 1},
- {0xfb1d, 0xfb36, 1},
- {0xfb38, 0xfb3c, 1},
- {0xfb3e, 0xfb40, 2},
- {0xfb41, 0xfb43, 2},
- {0xfb44, 0xfb46, 2},
- {0xfb47, 0xfb4f, 1},
- },
-}
-
-var _Hiragana = &RangeTable{
- R16: []Range16{
- {0x3041, 0x3096, 1},
- {0x309d, 0x309f, 1},
- },
- R32: []Range32{
- {0x1b001, 0x1b11e, 1},
- {0x1b150, 0x1b152, 1},
- {0x1f200, 0x1f200, 1},
- },
-}
-
-var _Imperial_Aramaic = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10840, 0x10855, 1},
- {0x10857, 0x1085f, 1},
- },
-}
-
-var _Inherited = &RangeTable{
- R16: []Range16{
- {0x0300, 0x036f, 1},
- {0x0485, 0x0486, 1},
- {0x064b, 0x0655, 1},
- {0x0670, 0x0951, 737},
- {0x0952, 0x0954, 1},
- {0x1ab0, 0x1ac0, 1},
- {0x1cd0, 0x1cd2, 1},
- {0x1cd4, 0x1ce0, 1},
- {0x1ce2, 0x1ce8, 1},
- {0x1ced, 0x1cf4, 7},
- {0x1cf8, 0x1cf9, 1},
- {0x1dc0, 0x1df9, 1},
- {0x1dfb, 0x1dff, 1},
- {0x200c, 0x200d, 1},
- {0x20d0, 0x20f0, 1},
- {0x302a, 0x302d, 1},
- {0x3099, 0x309a, 1},
- {0xfe00, 0xfe0f, 1},
- {0xfe20, 0xfe2d, 1},
- },
- R32: []Range32{
- {0x101fd, 0x102e0, 227},
- {0x1133b, 0x1d167, 48684},
- {0x1d168, 0x1d169, 1},
- {0x1d17b, 0x1d182, 1},
- {0x1d185, 0x1d18b, 1},
- {0x1d1aa, 0x1d1ad, 1},
- {0xe0100, 0xe01ef, 1},
- },
-}
-
-var _Inscriptional_Pahlavi = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10b60, 0x10b72, 1},
- {0x10b78, 0x10b7f, 1},
- },
-}
-
-var _Inscriptional_Parthian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10b40, 0x10b55, 1},
- {0x10b58, 0x10b5f, 1},
- },
-}
-
-var _Javanese = &RangeTable{
- R16: []Range16{
- {0xa980, 0xa9cd, 1},
- {0xa9d0, 0xa9d9, 1},
- {0xa9de, 0xa9df, 1},
- },
-}
-
-var _Kaithi = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11080, 0x110c1, 1},
- {0x110cd, 0x110cd, 1},
- },
-}
-
-var _Kannada = &RangeTable{
- R16: []Range16{
- {0x0c80, 0x0c8c, 1},
- {0x0c8e, 0x0c90, 1},
- {0x0c92, 0x0ca8, 1},
- {0x0caa, 0x0cb3, 1},
- {0x0cb5, 0x0cb9, 1},
- {0x0cbc, 0x0cc4, 1},
- {0x0cc6, 0x0cc8, 1},
- {0x0cca, 0x0ccd, 1},
- {0x0cd5, 0x0cd6, 1},
- {0x0cde, 0x0ce0, 2},
- {0x0ce1, 0x0ce3, 1},
- {0x0ce6, 0x0cef, 1},
- {0x0cf1, 0x0cf2, 1},
- },
-}
-
-var _Katakana = &RangeTable{
- R16: []Range16{
- {0x30a1, 0x30fa, 1},
- {0x30fd, 0x30ff, 1},
- {0x31f0, 0x31ff, 1},
- {0x32d0, 0x32fe, 1},
- {0x3300, 0x3357, 1},
- {0xff66, 0xff6f, 1},
- {0xff71, 0xff9d, 1},
- },
- R32: []Range32{
- {0x1b000, 0x1b164, 356},
- {0x1b165, 0x1b167, 1},
- },
-}
-
-var _Kayah_Li = &RangeTable{
- R16: []Range16{
- {0xa900, 0xa92d, 1},
- {0xa92f, 0xa92f, 1},
- },
-}
-
-var _Kharoshthi = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10a00, 0x10a03, 1},
- {0x10a05, 0x10a06, 1},
- {0x10a0c, 0x10a13, 1},
- {0x10a15, 0x10a17, 1},
- {0x10a19, 0x10a35, 1},
- {0x10a38, 0x10a3a, 1},
- {0x10a3f, 0x10a48, 1},
- {0x10a50, 0x10a58, 1},
- },
-}
-
-var _Khitan_Small_Script = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x16fe4, 0x18b00, 6940},
- {0x18b01, 0x18cd5, 1},
- },
-}
-
-var _Khmer = &RangeTable{
- R16: []Range16{
- {0x1780, 0x17dd, 1},
- {0x17e0, 0x17e9, 1},
- {0x17f0, 0x17f9, 1},
- {0x19e0, 0x19ff, 1},
- },
-}
-
-var _Khojki = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11200, 0x11211, 1},
- {0x11213, 0x1123e, 1},
- },
-}
-
-var _Khudawadi = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x112b0, 0x112ea, 1},
- {0x112f0, 0x112f9, 1},
- },
-}
-
-var _Lao = &RangeTable{
- R16: []Range16{
- {0x0e81, 0x0e82, 1},
- {0x0e84, 0x0e86, 2},
- {0x0e87, 0x0e8a, 1},
- {0x0e8c, 0x0ea3, 1},
- {0x0ea5, 0x0ea7, 2},
- {0x0ea8, 0x0ebd, 1},
- {0x0ec0, 0x0ec4, 1},
- {0x0ec6, 0x0ec8, 2},
- {0x0ec9, 0x0ecd, 1},
- {0x0ed0, 0x0ed9, 1},
- {0x0edc, 0x0edf, 1},
- },
-}
-
-var _Latin = &RangeTable{
- R16: []Range16{
- {0x0041, 0x005a, 1},
- {0x0061, 0x007a, 1},
- {0x00aa, 0x00ba, 16},
- {0x00c0, 0x00d6, 1},
- {0x00d8, 0x00f6, 1},
- {0x00f8, 0x02b8, 1},
- {0x02e0, 0x02e4, 1},
- {0x1d00, 0x1d25, 1},
- {0x1d2c, 0x1d5c, 1},
- {0x1d62, 0x1d65, 1},
- {0x1d6b, 0x1d77, 1},
- {0x1d79, 0x1dbe, 1},
- {0x1e00, 0x1eff, 1},
- {0x2071, 0x207f, 14},
- {0x2090, 0x209c, 1},
- {0x212a, 0x212b, 1},
- {0x2132, 0x214e, 28},
- {0x2160, 0x2188, 1},
- {0x2c60, 0x2c7f, 1},
- {0xa722, 0xa787, 1},
- {0xa78b, 0xa7bf, 1},
- {0xa7c2, 0xa7ca, 1},
- {0xa7f5, 0xa7ff, 1},
- {0xab30, 0xab5a, 1},
- {0xab5c, 0xab64, 1},
- {0xab66, 0xab69, 1},
- {0xfb00, 0xfb06, 1},
- {0xff21, 0xff3a, 1},
- {0xff41, 0xff5a, 1},
- },
- LatinOffset: 5,
-}
-
-var _Lepcha = &RangeTable{
- R16: []Range16{
- {0x1c00, 0x1c37, 1},
- {0x1c3b, 0x1c49, 1},
- {0x1c4d, 0x1c4f, 1},
- },
-}
-
-var _Limbu = &RangeTable{
- R16: []Range16{
- {0x1900, 0x191e, 1},
- {0x1920, 0x192b, 1},
- {0x1930, 0x193b, 1},
- {0x1940, 0x1944, 4},
- {0x1945, 0x194f, 1},
- },
-}
-
-var _Linear_A = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10600, 0x10736, 1},
- {0x10740, 0x10755, 1},
- {0x10760, 0x10767, 1},
- },
-}
-
-var _Linear_B = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10000, 0x1000b, 1},
- {0x1000d, 0x10026, 1},
- {0x10028, 0x1003a, 1},
- {0x1003c, 0x1003d, 1},
- {0x1003f, 0x1004d, 1},
- {0x10050, 0x1005d, 1},
- {0x10080, 0x100fa, 1},
- },
-}
-
-var _Lisu = &RangeTable{
- R16: []Range16{
- {0xa4d0, 0xa4ff, 1},
- },
- R32: []Range32{
- {0x11fb0, 0x11fb0, 1},
- },
-}
-
-var _Lycian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10280, 0x1029c, 1},
- },
-}
-
-var _Lydian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10920, 0x10939, 1},
- {0x1093f, 0x1093f, 1},
- },
-}
-
-var _Mahajani = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11150, 0x11176, 1},
- },
-}
-
-var _Makasar = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11ee0, 0x11ef8, 1},
- },
-}
-
-var _Malayalam = &RangeTable{
- R16: []Range16{
- {0x0d00, 0x0d0c, 1},
- {0x0d0e, 0x0d10, 1},
- {0x0d12, 0x0d44, 1},
- {0x0d46, 0x0d48, 1},
- {0x0d4a, 0x0d4f, 1},
- {0x0d54, 0x0d63, 1},
- {0x0d66, 0x0d7f, 1},
- },
-}
-
-var _Mandaic = &RangeTable{
- R16: []Range16{
- {0x0840, 0x085b, 1},
- {0x085e, 0x085e, 1},
- },
-}
-
-var _Manichaean = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10ac0, 0x10ae6, 1},
- {0x10aeb, 0x10af6, 1},
- },
-}
-
-var _Marchen = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11c70, 0x11c8f, 1},
- {0x11c92, 0x11ca7, 1},
- {0x11ca9, 0x11cb6, 1},
- },
-}
-
-var _Masaram_Gondi = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11d00, 0x11d06, 1},
- {0x11d08, 0x11d09, 1},
- {0x11d0b, 0x11d36, 1},
- {0x11d3a, 0x11d3c, 2},
- {0x11d3d, 0x11d3f, 2},
- {0x11d40, 0x11d47, 1},
- {0x11d50, 0x11d59, 1},
- },
-}
-
-var _Medefaidrin = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x16e40, 0x16e9a, 1},
- },
-}
-
-var _Meetei_Mayek = &RangeTable{
- R16: []Range16{
- {0xaae0, 0xaaf6, 1},
- {0xabc0, 0xabed, 1},
- {0xabf0, 0xabf9, 1},
- },
-}
-
-var _Mende_Kikakui = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x1e800, 0x1e8c4, 1},
- {0x1e8c7, 0x1e8d6, 1},
- },
-}
-
-var _Meroitic_Cursive = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x109a0, 0x109b7, 1},
- {0x109bc, 0x109cf, 1},
- {0x109d2, 0x109ff, 1},
- },
-}
-
-var _Meroitic_Hieroglyphs = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10980, 0x1099f, 1},
- },
-}
-
-var _Miao = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x16f00, 0x16f4a, 1},
- {0x16f4f, 0x16f87, 1},
- {0x16f8f, 0x16f9f, 1},
- },
-}
-
-var _Modi = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11600, 0x11644, 1},
- {0x11650, 0x11659, 1},
- },
-}
-
-var _Mongolian = &RangeTable{
- R16: []Range16{
- {0x1800, 0x1801, 1},
- {0x1804, 0x1806, 2},
- {0x1807, 0x180e, 1},
- {0x1810, 0x1819, 1},
- {0x1820, 0x1878, 1},
- {0x1880, 0x18aa, 1},
- },
- R32: []Range32{
- {0x11660, 0x1166c, 1},
- },
-}
-
-var _Mro = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x16a40, 0x16a5e, 1},
- {0x16a60, 0x16a69, 1},
- {0x16a6e, 0x16a6f, 1},
- },
-}
-
-var _Multani = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11280, 0x11286, 1},
- {0x11288, 0x1128a, 2},
- {0x1128b, 0x1128d, 1},
- {0x1128f, 0x1129d, 1},
- {0x1129f, 0x112a9, 1},
- },
-}
-
-var _Myanmar = &RangeTable{
- R16: []Range16{
- {0x1000, 0x109f, 1},
- {0xa9e0, 0xa9fe, 1},
- {0xaa60, 0xaa7f, 1},
- },
-}
-
-var _Nabataean = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10880, 0x1089e, 1},
- {0x108a7, 0x108af, 1},
- },
-}
-
-var _Nandinagari = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x119a0, 0x119a7, 1},
- {0x119aa, 0x119d7, 1},
- {0x119da, 0x119e4, 1},
- },
-}
-
-var _New_Tai_Lue = &RangeTable{
- R16: []Range16{
- {0x1980, 0x19ab, 1},
- {0x19b0, 0x19c9, 1},
- {0x19d0, 0x19da, 1},
- {0x19de, 0x19df, 1},
- },
-}
-
-var _Newa = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11400, 0x1145b, 1},
- {0x1145d, 0x11461, 1},
- },
-}
-
-var _Nko = &RangeTable{
- R16: []Range16{
- {0x07c0, 0x07fa, 1},
- {0x07fd, 0x07ff, 1},
- },
-}
-
-var _Nushu = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x16fe1, 0x1b170, 16783},
- {0x1b171, 0x1b2fb, 1},
- },
-}
-
-var _Nyiakeng_Puachue_Hmong = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x1e100, 0x1e12c, 1},
- {0x1e130, 0x1e13d, 1},
- {0x1e140, 0x1e149, 1},
- {0x1e14e, 0x1e14f, 1},
- },
-}
-
-var _Ogham = &RangeTable{
- R16: []Range16{
- {0x1680, 0x169c, 1},
- },
-}
-
-var _Ol_Chiki = &RangeTable{
- R16: []Range16{
- {0x1c50, 0x1c7f, 1},
- },
-}
-
-var _Old_Hungarian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10c80, 0x10cb2, 1},
- {0x10cc0, 0x10cf2, 1},
- {0x10cfa, 0x10cff, 1},
- },
-}
-
-var _Old_Italic = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10300, 0x10323, 1},
- {0x1032d, 0x1032f, 1},
- },
-}
-
-var _Old_North_Arabian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10a80, 0x10a9f, 1},
- },
-}
-
-var _Old_Permic = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10350, 0x1037a, 1},
- },
-}
-
-var _Old_Persian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x103a0, 0x103c3, 1},
- {0x103c8, 0x103d5, 1},
- },
-}
-
-var _Old_Sogdian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10f00, 0x10f27, 1},
- },
-}
-
-var _Old_South_Arabian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10a60, 0x10a7f, 1},
- },
-}
-
-var _Old_Turkic = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10c00, 0x10c48, 1},
- },
-}
-
-var _Oriya = &RangeTable{
- R16: []Range16{
- {0x0b01, 0x0b03, 1},
- {0x0b05, 0x0b0c, 1},
- {0x0b0f, 0x0b10, 1},
- {0x0b13, 0x0b28, 1},
- {0x0b2a, 0x0b30, 1},
- {0x0b32, 0x0b33, 1},
- {0x0b35, 0x0b39, 1},
- {0x0b3c, 0x0b44, 1},
- {0x0b47, 0x0b48, 1},
- {0x0b4b, 0x0b4d, 1},
- {0x0b55, 0x0b57, 1},
- {0x0b5c, 0x0b5d, 1},
- {0x0b5f, 0x0b63, 1},
- {0x0b66, 0x0b77, 1},
- },
-}
-
-var _Osage = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x104b0, 0x104d3, 1},
- {0x104d8, 0x104fb, 1},
- },
-}
-
-var _Osmanya = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10480, 0x1049d, 1},
- {0x104a0, 0x104a9, 1},
- },
-}
-
-var _Pahawh_Hmong = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x16b00, 0x16b45, 1},
- {0x16b50, 0x16b59, 1},
- {0x16b5b, 0x16b61, 1},
- {0x16b63, 0x16b77, 1},
- {0x16b7d, 0x16b8f, 1},
- },
-}
-
-var _Palmyrene = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10860, 0x1087f, 1},
- },
-}
-
-var _Pau_Cin_Hau = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11ac0, 0x11af8, 1},
- },
-}
-
-var _Phags_Pa = &RangeTable{
- R16: []Range16{
- {0xa840, 0xa877, 1},
- },
-}
-
-var _Phoenician = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10900, 0x1091b, 1},
- {0x1091f, 0x1091f, 1},
- },
-}
-
-var _Psalter_Pahlavi = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10b80, 0x10b91, 1},
- {0x10b99, 0x10b9c, 1},
- {0x10ba9, 0x10baf, 1},
- },
-}
-
-var _Rejang = &RangeTable{
- R16: []Range16{
- {0xa930, 0xa953, 1},
- {0xa95f, 0xa95f, 1},
- },
-}
-
-var _Runic = &RangeTable{
- R16: []Range16{
- {0x16a0, 0x16ea, 1},
- {0x16ee, 0x16f8, 1},
- },
-}
-
-var _Samaritan = &RangeTable{
- R16: []Range16{
- {0x0800, 0x082d, 1},
- {0x0830, 0x083e, 1},
- },
-}
-
-var _Saurashtra = &RangeTable{
- R16: []Range16{
- {0xa880, 0xa8c5, 1},
- {0xa8ce, 0xa8d9, 1},
- },
-}
-
-var _Sharada = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11180, 0x111df, 1},
- },
-}
-
-var _Shavian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10450, 0x1047f, 1},
- },
-}
-
-var _Siddham = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11580, 0x115b5, 1},
- {0x115b8, 0x115dd, 1},
- },
-}
-
-var _SignWriting = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x1d800, 0x1da8b, 1},
- {0x1da9b, 0x1da9f, 1},
- {0x1daa1, 0x1daaf, 1},
- },
-}
-
-var _Sinhala = &RangeTable{
- R16: []Range16{
- {0x0d81, 0x0d83, 1},
- {0x0d85, 0x0d96, 1},
- {0x0d9a, 0x0db1, 1},
- {0x0db3, 0x0dbb, 1},
- {0x0dbd, 0x0dc0, 3},
- {0x0dc1, 0x0dc6, 1},
- {0x0dca, 0x0dcf, 5},
- {0x0dd0, 0x0dd4, 1},
- {0x0dd6, 0x0dd8, 2},
- {0x0dd9, 0x0ddf, 1},
- {0x0de6, 0x0def, 1},
- {0x0df2, 0x0df4, 1},
- },
- R32: []Range32{
- {0x111e1, 0x111f4, 1},
- },
-}
-
-var _Sogdian = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10f30, 0x10f59, 1},
- },
-}
-
-var _Sora_Sompeng = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x110d0, 0x110e8, 1},
- {0x110f0, 0x110f9, 1},
- },
-}
-
-var _Soyombo = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11a50, 0x11aa2, 1},
- },
-}
-
-var _Sundanese = &RangeTable{
- R16: []Range16{
- {0x1b80, 0x1bbf, 1},
- {0x1cc0, 0x1cc7, 1},
- },
-}
-
-var _Syloti_Nagri = &RangeTable{
- R16: []Range16{
- {0xa800, 0xa82c, 1},
- },
-}
-
-var _Syriac = &RangeTable{
- R16: []Range16{
- {0x0700, 0x070d, 1},
- {0x070f, 0x074a, 1},
- {0x074d, 0x074f, 1},
- {0x0860, 0x086a, 1},
- },
-}
-
-var _Tagalog = &RangeTable{
- R16: []Range16{
- {0x1700, 0x170c, 1},
- {0x170e, 0x1714, 1},
- },
-}
-
-var _Tagbanwa = &RangeTable{
- R16: []Range16{
- {0x1760, 0x176c, 1},
- {0x176e, 0x1770, 1},
- {0x1772, 0x1773, 1},
- },
-}
-
-var _Tai_Le = &RangeTable{
- R16: []Range16{
- {0x1950, 0x196d, 1},
- {0x1970, 0x1974, 1},
- },
-}
-
-var _Tai_Tham = &RangeTable{
- R16: []Range16{
- {0x1a20, 0x1a5e, 1},
- {0x1a60, 0x1a7c, 1},
- {0x1a7f, 0x1a89, 1},
- {0x1a90, 0x1a99, 1},
- {0x1aa0, 0x1aad, 1},
- },
-}
-
-var _Tai_Viet = &RangeTable{
- R16: []Range16{
- {0xaa80, 0xaac2, 1},
- {0xaadb, 0xaadf, 1},
- },
-}
-
-var _Takri = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11680, 0x116b8, 1},
- {0x116c0, 0x116c9, 1},
- },
-}
-
-var _Tamil = &RangeTable{
- R16: []Range16{
- {0x0b82, 0x0b83, 1},
- {0x0b85, 0x0b8a, 1},
- {0x0b8e, 0x0b90, 1},
- {0x0b92, 0x0b95, 1},
- {0x0b99, 0x0b9a, 1},
- {0x0b9c, 0x0b9e, 2},
- {0x0b9f, 0x0ba3, 4},
- {0x0ba4, 0x0ba8, 4},
- {0x0ba9, 0x0baa, 1},
- {0x0bae, 0x0bb9, 1},
- {0x0bbe, 0x0bc2, 1},
- {0x0bc6, 0x0bc8, 1},
- {0x0bca, 0x0bcd, 1},
- {0x0bd0, 0x0bd7, 7},
- {0x0be6, 0x0bfa, 1},
- },
- R32: []Range32{
- {0x11fc0, 0x11ff1, 1},
- {0x11fff, 0x11fff, 1},
- },
-}
-
-var _Tangut = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x16fe0, 0x17000, 32},
- {0x17001, 0x187f7, 1},
- {0x18800, 0x18aff, 1},
- {0x18d00, 0x18d08, 1},
- },
-}
-
-var _Telugu = &RangeTable{
- R16: []Range16{
- {0x0c00, 0x0c0c, 1},
- {0x0c0e, 0x0c10, 1},
- {0x0c12, 0x0c28, 1},
- {0x0c2a, 0x0c39, 1},
- {0x0c3d, 0x0c44, 1},
- {0x0c46, 0x0c48, 1},
- {0x0c4a, 0x0c4d, 1},
- {0x0c55, 0x0c56, 1},
- {0x0c58, 0x0c5a, 1},
- {0x0c60, 0x0c63, 1},
- {0x0c66, 0x0c6f, 1},
- {0x0c77, 0x0c7f, 1},
- },
-}
-
-var _Thaana = &RangeTable{
- R16: []Range16{
- {0x0780, 0x07b1, 1},
- },
-}
-
-var _Thai = &RangeTable{
- R16: []Range16{
- {0x0e01, 0x0e3a, 1},
- {0x0e40, 0x0e5b, 1},
- },
-}
-
-var _Tibetan = &RangeTable{
- R16: []Range16{
- {0x0f00, 0x0f47, 1},
- {0x0f49, 0x0f6c, 1},
- {0x0f71, 0x0f97, 1},
- {0x0f99, 0x0fbc, 1},
- {0x0fbe, 0x0fcc, 1},
- {0x0fce, 0x0fd4, 1},
- {0x0fd9, 0x0fda, 1},
- },
-}
-
-var _Tifinagh = &RangeTable{
- R16: []Range16{
- {0x2d30, 0x2d67, 1},
- {0x2d6f, 0x2d70, 1},
- {0x2d7f, 0x2d7f, 1},
- },
-}
-
-var _Tirhuta = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11480, 0x114c7, 1},
- {0x114d0, 0x114d9, 1},
- },
-}
-
-var _Ugaritic = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10380, 0x1039d, 1},
- {0x1039f, 0x1039f, 1},
- },
-}
-
-var _Vai = &RangeTable{
- R16: []Range16{
- {0xa500, 0xa62b, 1},
- },
-}
-
-var _Wancho = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x1e2c0, 0x1e2f9, 1},
- {0x1e2ff, 0x1e2ff, 1},
- },
-}
-
-var _Warang_Citi = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x118a0, 0x118f2, 1},
- {0x118ff, 0x118ff, 1},
- },
-}
-
-var _Yezidi = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x10e80, 0x10ea9, 1},
- {0x10eab, 0x10ead, 1},
- {0x10eb0, 0x10eb1, 1},
- },
-}
-
-var _Yi = &RangeTable{
- R16: []Range16{
- {0xa000, 0xa48c, 1},
- {0xa490, 0xa4c6, 1},
- },
-}
-
-var _Zanabazar_Square = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x11a00, 0x11a47, 1},
- },
-}
-
-// These variables have type *RangeTable.
-var (
- Adlam = _Adlam // Adlam is the set of Unicode characters in script Adlam.
- Ahom = _Ahom // Ahom is the set of Unicode characters in script Ahom.
- Anatolian_Hieroglyphs = _Anatolian_Hieroglyphs // Anatolian_Hieroglyphs is the set of Unicode characters in script Anatolian_Hieroglyphs.
- Arabic = _Arabic // Arabic is the set of Unicode characters in script Arabic.
- Armenian = _Armenian // Armenian is the set of Unicode characters in script Armenian.
- Avestan = _Avestan // Avestan is the set of Unicode characters in script Avestan.
- Balinese = _Balinese // Balinese is the set of Unicode characters in script Balinese.
- Bamum = _Bamum // Bamum is the set of Unicode characters in script Bamum.
- Bassa_Vah = _Bassa_Vah // Bassa_Vah is the set of Unicode characters in script Bassa_Vah.
- Batak = _Batak // Batak is the set of Unicode characters in script Batak.
- Bengali = _Bengali // Bengali is the set of Unicode characters in script Bengali.
- Bhaiksuki = _Bhaiksuki // Bhaiksuki is the set of Unicode characters in script Bhaiksuki.
- Bopomofo = _Bopomofo // Bopomofo is the set of Unicode characters in script Bopomofo.
- Brahmi = _Brahmi // Brahmi is the set of Unicode characters in script Brahmi.
- Braille = _Braille // Braille is the set of Unicode characters in script Braille.
- Buginese = _Buginese // Buginese is the set of Unicode characters in script Buginese.
- Buhid = _Buhid // Buhid is the set of Unicode characters in script Buhid.
- Canadian_Aboriginal = _Canadian_Aboriginal // Canadian_Aboriginal is the set of Unicode characters in script Canadian_Aboriginal.
- Carian = _Carian // Carian is the set of Unicode characters in script Carian.
- Caucasian_Albanian = _Caucasian_Albanian // Caucasian_Albanian is the set of Unicode characters in script Caucasian_Albanian.
- Chakma = _Chakma // Chakma is the set of Unicode characters in script Chakma.
- Cham = _Cham // Cham is the set of Unicode characters in script Cham.
- Cherokee = _Cherokee // Cherokee is the set of Unicode characters in script Cherokee.
- Chorasmian = _Chorasmian // Chorasmian is the set of Unicode characters in script Chorasmian.
- Common = _Common // Common is the set of Unicode characters in script Common.
- Coptic = _Coptic // Coptic is the set of Unicode characters in script Coptic.
- Cuneiform = _Cuneiform // Cuneiform is the set of Unicode characters in script Cuneiform.
- Cypriot = _Cypriot // Cypriot is the set of Unicode characters in script Cypriot.
- Cyrillic = _Cyrillic // Cyrillic is the set of Unicode characters in script Cyrillic.
- Deseret = _Deseret // Deseret is the set of Unicode characters in script Deseret.
- Devanagari = _Devanagari // Devanagari is the set of Unicode characters in script Devanagari.
- Dives_Akuru = _Dives_Akuru // Dives_Akuru is the set of Unicode characters in script Dives_Akuru.
- Dogra = _Dogra // Dogra is the set of Unicode characters in script Dogra.
- Duployan = _Duployan // Duployan is the set of Unicode characters in script Duployan.
- Egyptian_Hieroglyphs = _Egyptian_Hieroglyphs // Egyptian_Hieroglyphs is the set of Unicode characters in script Egyptian_Hieroglyphs.
- Elbasan = _Elbasan // Elbasan is the set of Unicode characters in script Elbasan.
- Elymaic = _Elymaic // Elymaic is the set of Unicode characters in script Elymaic.
- Ethiopic = _Ethiopic // Ethiopic is the set of Unicode characters in script Ethiopic.
- Georgian = _Georgian // Georgian is the set of Unicode characters in script Georgian.
- Glagolitic = _Glagolitic // Glagolitic is the set of Unicode characters in script Glagolitic.
- Gothic = _Gothic // Gothic is the set of Unicode characters in script Gothic.
- Grantha = _Grantha // Grantha is the set of Unicode characters in script Grantha.
- Greek = _Greek // Greek is the set of Unicode characters in script Greek.
- Gujarati = _Gujarati // Gujarati is the set of Unicode characters in script Gujarati.
- Gunjala_Gondi = _Gunjala_Gondi // Gunjala_Gondi is the set of Unicode characters in script Gunjala_Gondi.
- Gurmukhi = _Gurmukhi // Gurmukhi is the set of Unicode characters in script Gurmukhi.
- Han = _Han // Han is the set of Unicode characters in script Han.
- Hangul = _Hangul // Hangul is the set of Unicode characters in script Hangul.
- Hanifi_Rohingya = _Hanifi_Rohingya // Hanifi_Rohingya is the set of Unicode characters in script Hanifi_Rohingya.
- Hanunoo = _Hanunoo // Hanunoo is the set of Unicode characters in script Hanunoo.
- Hatran = _Hatran // Hatran is the set of Unicode characters in script Hatran.
- Hebrew = _Hebrew // Hebrew is the set of Unicode characters in script Hebrew.
- Hiragana = _Hiragana // Hiragana is the set of Unicode characters in script Hiragana.
- Imperial_Aramaic = _Imperial_Aramaic // Imperial_Aramaic is the set of Unicode characters in script Imperial_Aramaic.
- Inherited = _Inherited // Inherited is the set of Unicode characters in script Inherited.
- Inscriptional_Pahlavi = _Inscriptional_Pahlavi // Inscriptional_Pahlavi is the set of Unicode characters in script Inscriptional_Pahlavi.
- Inscriptional_Parthian = _Inscriptional_Parthian // Inscriptional_Parthian is the set of Unicode characters in script Inscriptional_Parthian.
- Javanese = _Javanese // Javanese is the set of Unicode characters in script Javanese.
- Kaithi = _Kaithi // Kaithi is the set of Unicode characters in script Kaithi.
- Kannada = _Kannada // Kannada is the set of Unicode characters in script Kannada.
- Katakana = _Katakana // Katakana is the set of Unicode characters in script Katakana.
- Kayah_Li = _Kayah_Li // Kayah_Li is the set of Unicode characters in script Kayah_Li.
- Kharoshthi = _Kharoshthi // Kharoshthi is the set of Unicode characters in script Kharoshthi.
- Khitan_Small_Script = _Khitan_Small_Script // Khitan_Small_Script is the set of Unicode characters in script Khitan_Small_Script.
- Khmer = _Khmer // Khmer is the set of Unicode characters in script Khmer.
- Khojki = _Khojki // Khojki is the set of Unicode characters in script Khojki.
- Khudawadi = _Khudawadi // Khudawadi is the set of Unicode characters in script Khudawadi.
- Lao = _Lao // Lao is the set of Unicode characters in script Lao.
- Latin = _Latin // Latin is the set of Unicode characters in script Latin.
- Lepcha = _Lepcha // Lepcha is the set of Unicode characters in script Lepcha.
- Limbu = _Limbu // Limbu is the set of Unicode characters in script Limbu.
- Linear_A = _Linear_A // Linear_A is the set of Unicode characters in script Linear_A.
- Linear_B = _Linear_B // Linear_B is the set of Unicode characters in script Linear_B.
- Lisu = _Lisu // Lisu is the set of Unicode characters in script Lisu.
- Lycian = _Lycian // Lycian is the set of Unicode characters in script Lycian.
- Lydian = _Lydian // Lydian is the set of Unicode characters in script Lydian.
- Mahajani = _Mahajani // Mahajani is the set of Unicode characters in script Mahajani.
- Makasar = _Makasar // Makasar is the set of Unicode characters in script Makasar.
- Malayalam = _Malayalam // Malayalam is the set of Unicode characters in script Malayalam.
- Mandaic = _Mandaic // Mandaic is the set of Unicode characters in script Mandaic.
- Manichaean = _Manichaean // Manichaean is the set of Unicode characters in script Manichaean.
- Marchen = _Marchen // Marchen is the set of Unicode characters in script Marchen.
- Masaram_Gondi = _Masaram_Gondi // Masaram_Gondi is the set of Unicode characters in script Masaram_Gondi.
- Medefaidrin = _Medefaidrin // Medefaidrin is the set of Unicode characters in script Medefaidrin.
- Meetei_Mayek = _Meetei_Mayek // Meetei_Mayek is the set of Unicode characters in script Meetei_Mayek.
- Mende_Kikakui = _Mende_Kikakui // Mende_Kikakui is the set of Unicode characters in script Mende_Kikakui.
- Meroitic_Cursive = _Meroitic_Cursive // Meroitic_Cursive is the set of Unicode characters in script Meroitic_Cursive.
- Meroitic_Hieroglyphs = _Meroitic_Hieroglyphs // Meroitic_Hieroglyphs is the set of Unicode characters in script Meroitic_Hieroglyphs.
- Miao = _Miao // Miao is the set of Unicode characters in script Miao.
- Modi = _Modi // Modi is the set of Unicode characters in script Modi.
- Mongolian = _Mongolian // Mongolian is the set of Unicode characters in script Mongolian.
- Mro = _Mro // Mro is the set of Unicode characters in script Mro.
- Multani = _Multani // Multani is the set of Unicode characters in script Multani.
- Myanmar = _Myanmar // Myanmar is the set of Unicode characters in script Myanmar.
- Nabataean = _Nabataean // Nabataean is the set of Unicode characters in script Nabataean.
- Nandinagari = _Nandinagari // Nandinagari is the set of Unicode characters in script Nandinagari.
- New_Tai_Lue = _New_Tai_Lue // New_Tai_Lue is the set of Unicode characters in script New_Tai_Lue.
- Newa = _Newa // Newa is the set of Unicode characters in script Newa.
- Nko = _Nko // Nko is the set of Unicode characters in script Nko.
- Nushu = _Nushu // Nushu is the set of Unicode characters in script Nushu.
- Nyiakeng_Puachue_Hmong = _Nyiakeng_Puachue_Hmong // Nyiakeng_Puachue_Hmong is the set of Unicode characters in script Nyiakeng_Puachue_Hmong.
- Ogham = _Ogham // Ogham is the set of Unicode characters in script Ogham.
- Ol_Chiki = _Ol_Chiki // Ol_Chiki is the set of Unicode characters in script Ol_Chiki.
- Old_Hungarian = _Old_Hungarian // Old_Hungarian is the set of Unicode characters in script Old_Hungarian.
- Old_Italic = _Old_Italic // Old_Italic is the set of Unicode characters in script Old_Italic.
- Old_North_Arabian = _Old_North_Arabian // Old_North_Arabian is the set of Unicode characters in script Old_North_Arabian.
- Old_Permic = _Old_Permic // Old_Permic is the set of Unicode characters in script Old_Permic.
- Old_Persian = _Old_Persian // Old_Persian is the set of Unicode characters in script Old_Persian.
- Old_Sogdian = _Old_Sogdian // Old_Sogdian is the set of Unicode characters in script Old_Sogdian.
- Old_South_Arabian = _Old_South_Arabian // Old_South_Arabian is the set of Unicode characters in script Old_South_Arabian.
- Old_Turkic = _Old_Turkic // Old_Turkic is the set of Unicode characters in script Old_Turkic.
- Oriya = _Oriya // Oriya is the set of Unicode characters in script Oriya.
- Osage = _Osage // Osage is the set of Unicode characters in script Osage.
- Osmanya = _Osmanya // Osmanya is the set of Unicode characters in script Osmanya.
- Pahawh_Hmong = _Pahawh_Hmong // Pahawh_Hmong is the set of Unicode characters in script Pahawh_Hmong.
- Palmyrene = _Palmyrene // Palmyrene is the set of Unicode characters in script Palmyrene.
- Pau_Cin_Hau = _Pau_Cin_Hau // Pau_Cin_Hau is the set of Unicode characters in script Pau_Cin_Hau.
- Phags_Pa = _Phags_Pa // Phags_Pa is the set of Unicode characters in script Phags_Pa.
- Phoenician = _Phoenician // Phoenician is the set of Unicode characters in script Phoenician.
- Psalter_Pahlavi = _Psalter_Pahlavi // Psalter_Pahlavi is the set of Unicode characters in script Psalter_Pahlavi.
- Rejang = _Rejang // Rejang is the set of Unicode characters in script Rejang.
- Runic = _Runic // Runic is the set of Unicode characters in script Runic.
- Samaritan = _Samaritan // Samaritan is the set of Unicode characters in script Samaritan.
- Saurashtra = _Saurashtra // Saurashtra is the set of Unicode characters in script Saurashtra.
- Sharada = _Sharada // Sharada is the set of Unicode characters in script Sharada.
- Shavian = _Shavian // Shavian is the set of Unicode characters in script Shavian.
- Siddham = _Siddham // Siddham is the set of Unicode characters in script Siddham.
- SignWriting = _SignWriting // SignWriting is the set of Unicode characters in script SignWriting.
- Sinhala = _Sinhala // Sinhala is the set of Unicode characters in script Sinhala.
- Sogdian = _Sogdian // Sogdian is the set of Unicode characters in script Sogdian.
- Sora_Sompeng = _Sora_Sompeng // Sora_Sompeng is the set of Unicode characters in script Sora_Sompeng.
- Soyombo = _Soyombo // Soyombo is the set of Unicode characters in script Soyombo.
- Sundanese = _Sundanese // Sundanese is the set of Unicode characters in script Sundanese.
- Syloti_Nagri = _Syloti_Nagri // Syloti_Nagri is the set of Unicode characters in script Syloti_Nagri.
- Syriac = _Syriac // Syriac is the set of Unicode characters in script Syriac.
- Tagalog = _Tagalog // Tagalog is the set of Unicode characters in script Tagalog.
- Tagbanwa = _Tagbanwa // Tagbanwa is the set of Unicode characters in script Tagbanwa.
- Tai_Le = _Tai_Le // Tai_Le is the set of Unicode characters in script Tai_Le.
- Tai_Tham = _Tai_Tham // Tai_Tham is the set of Unicode characters in script Tai_Tham.
- Tai_Viet = _Tai_Viet // Tai_Viet is the set of Unicode characters in script Tai_Viet.
- Takri = _Takri // Takri is the set of Unicode characters in script Takri.
- Tamil = _Tamil // Tamil is the set of Unicode characters in script Tamil.
- Tangut = _Tangut // Tangut is the set of Unicode characters in script Tangut.
- Telugu = _Telugu // Telugu is the set of Unicode characters in script Telugu.
- Thaana = _Thaana // Thaana is the set of Unicode characters in script Thaana.
- Thai = _Thai // Thai is the set of Unicode characters in script Thai.
- Tibetan = _Tibetan // Tibetan is the set of Unicode characters in script Tibetan.
- Tifinagh = _Tifinagh // Tifinagh is the set of Unicode characters in script Tifinagh.
- Tirhuta = _Tirhuta // Tirhuta is the set of Unicode characters in script Tirhuta.
- Ugaritic = _Ugaritic // Ugaritic is the set of Unicode characters in script Ugaritic.
- Vai = _Vai // Vai is the set of Unicode characters in script Vai.
- Wancho = _Wancho // Wancho is the set of Unicode characters in script Wancho.
- Warang_Citi = _Warang_Citi // Warang_Citi is the set of Unicode characters in script Warang_Citi.
- Yezidi = _Yezidi // Yezidi is the set of Unicode characters in script Yezidi.
- Yi = _Yi // Yi is the set of Unicode characters in script Yi.
- Zanabazar_Square = _Zanabazar_Square // Zanabazar_Square is the set of Unicode characters in script Zanabazar_Square.
-)
-
-// Properties is the set of Unicode property tables.
-var Properties = map[string]*RangeTable{
- "ASCII_Hex_Digit": ASCII_Hex_Digit,
- "Bidi_Control": Bidi_Control,
- "Dash": Dash,
- "Deprecated": Deprecated,
- "Diacritic": Diacritic,
- "Extender": Extender,
- "Hex_Digit": Hex_Digit,
- "Hyphen": Hyphen,
- "IDS_Binary_Operator": IDS_Binary_Operator,
- "IDS_Trinary_Operator": IDS_Trinary_Operator,
- "Ideographic": Ideographic,
- "Join_Control": Join_Control,
- "Logical_Order_Exception": Logical_Order_Exception,
- "Noncharacter_Code_Point": Noncharacter_Code_Point,
- "Other_Alphabetic": Other_Alphabetic,
- "Other_Default_Ignorable_Code_Point": Other_Default_Ignorable_Code_Point,
- "Other_Grapheme_Extend": Other_Grapheme_Extend,
- "Other_ID_Continue": Other_ID_Continue,
- "Other_ID_Start": Other_ID_Start,
- "Other_Lowercase": Other_Lowercase,
- "Other_Math": Other_Math,
- "Other_Uppercase": Other_Uppercase,
- "Pattern_Syntax": Pattern_Syntax,
- "Pattern_White_Space": Pattern_White_Space,
- "Prepended_Concatenation_Mark": Prepended_Concatenation_Mark,
- "Quotation_Mark": Quotation_Mark,
- "Radical": Radical,
- "Regional_Indicator": Regional_Indicator,
- "Sentence_Terminal": Sentence_Terminal,
- "STerm": Sentence_Terminal,
- "Soft_Dotted": Soft_Dotted,
- "Terminal_Punctuation": Terminal_Punctuation,
- "Unified_Ideograph": Unified_Ideograph,
- "Variation_Selector": Variation_Selector,
- "White_Space": White_Space,
-}
-
-var _ASCII_Hex_Digit = &RangeTable{
- R16: []Range16{
- {0x0030, 0x0039, 1},
- {0x0041, 0x0046, 1},
- {0x0061, 0x0066, 1},
- },
- LatinOffset: 3,
-}
-
-var _Bidi_Control = &RangeTable{
- R16: []Range16{
- {0x061c, 0x200e, 6642},
- {0x200f, 0x202a, 27},
- {0x202b, 0x202e, 1},
- {0x2066, 0x2069, 1},
- },
-}
-
-var _Dash = &RangeTable{
- R16: []Range16{
- {0x002d, 0x058a, 1373},
- {0x05be, 0x1400, 3650},
- {0x1806, 0x2010, 2058},
- {0x2011, 0x2015, 1},
- {0x2053, 0x207b, 40},
- {0x208b, 0x2212, 391},
- {0x2e17, 0x2e1a, 3},
- {0x2e3a, 0x2e3b, 1},
- {0x2e40, 0x301c, 476},
- {0x3030, 0x30a0, 112},
- {0xfe31, 0xfe32, 1},
- {0xfe58, 0xfe63, 11},
- {0xff0d, 0xff0d, 1},
- },
- R32: []Range32{
- {0x10ead, 0x10ead, 1},
- },
-}
-
-var _Deprecated = &RangeTable{
- R16: []Range16{
- {0x0149, 0x0673, 1322},
- {0x0f77, 0x0f79, 2},
- {0x17a3, 0x17a4, 1},
- {0x206a, 0x206f, 1},
- {0x2329, 0x232a, 1},
- },
- R32: []Range32{
- {0xe0001, 0xe0001, 1},
- },
-}
-
-var _Diacritic = &RangeTable{
- R16: []Range16{
- {0x005e, 0x0060, 2},
- {0x00a8, 0x00af, 7},
- {0x00b4, 0x00b7, 3},
- {0x00b8, 0x02b0, 504},
- {0x02b1, 0x034e, 1},
- {0x0350, 0x0357, 1},
- {0x035d, 0x0362, 1},
- {0x0374, 0x0375, 1},
- {0x037a, 0x0384, 10},
- {0x0385, 0x0483, 254},
- {0x0484, 0x0487, 1},
- {0x0559, 0x0591, 56},
- {0x0592, 0x05a1, 1},
- {0x05a3, 0x05bd, 1},
- {0x05bf, 0x05c1, 2},
- {0x05c2, 0x05c4, 2},
- {0x064b, 0x0652, 1},
- {0x0657, 0x0658, 1},
- {0x06df, 0x06e0, 1},
- {0x06e5, 0x06e6, 1},
- {0x06ea, 0x06ec, 1},
- {0x0730, 0x074a, 1},
- {0x07a6, 0x07b0, 1},
- {0x07eb, 0x07f5, 1},
- {0x0818, 0x0819, 1},
- {0x08e3, 0x08fe, 1},
- {0x093c, 0x094d, 17},
- {0x0951, 0x0954, 1},
- {0x0971, 0x09bc, 75},
- {0x09cd, 0x0a3c, 111},
- {0x0a4d, 0x0abc, 111},
- {0x0acd, 0x0afd, 48},
- {0x0afe, 0x0aff, 1},
- {0x0b3c, 0x0b4d, 17},
- {0x0b55, 0x0bcd, 120},
- {0x0c4d, 0x0cbc, 111},
- {0x0ccd, 0x0d3b, 110},
- {0x0d3c, 0x0d4d, 17},
- {0x0dca, 0x0e47, 125},
- {0x0e48, 0x0e4c, 1},
- {0x0e4e, 0x0eba, 108},
- {0x0ec8, 0x0ecc, 1},
- {0x0f18, 0x0f19, 1},
- {0x0f35, 0x0f39, 2},
- {0x0f3e, 0x0f3f, 1},
- {0x0f82, 0x0f84, 1},
- {0x0f86, 0x0f87, 1},
- {0x0fc6, 0x1037, 113},
- {0x1039, 0x103a, 1},
- {0x1063, 0x1064, 1},
- {0x1069, 0x106d, 1},
- {0x1087, 0x108d, 1},
- {0x108f, 0x109a, 11},
- {0x109b, 0x135d, 706},
- {0x135e, 0x135f, 1},
- {0x17c9, 0x17d3, 1},
- {0x17dd, 0x1939, 348},
- {0x193a, 0x193b, 1},
- {0x1a75, 0x1a7c, 1},
- {0x1a7f, 0x1ab0, 49},
- {0x1ab1, 0x1abd, 1},
- {0x1b34, 0x1b44, 16},
- {0x1b6b, 0x1b73, 1},
- {0x1baa, 0x1bab, 1},
- {0x1c36, 0x1c37, 1},
- {0x1c78, 0x1c7d, 1},
- {0x1cd0, 0x1ce8, 1},
- {0x1ced, 0x1cf4, 7},
- {0x1cf7, 0x1cf9, 1},
- {0x1d2c, 0x1d6a, 1},
- {0x1dc4, 0x1dcf, 1},
- {0x1df5, 0x1df9, 1},
- {0x1dfd, 0x1dff, 1},
- {0x1fbd, 0x1fbf, 2},
- {0x1fc0, 0x1fc1, 1},
- {0x1fcd, 0x1fcf, 1},
- {0x1fdd, 0x1fdf, 1},
- {0x1fed, 0x1fef, 1},
- {0x1ffd, 0x1ffe, 1},
- {0x2cef, 0x2cf1, 1},
- {0x2e2f, 0x302a, 507},
- {0x302b, 0x302f, 1},
- {0x3099, 0x309c, 1},
- {0x30fc, 0xa66f, 30067},
- {0xa67c, 0xa67d, 1},
- {0xa67f, 0xa69c, 29},
- {0xa69d, 0xa6f0, 83},
- {0xa6f1, 0xa700, 15},
- {0xa701, 0xa721, 1},
- {0xa788, 0xa78a, 1},
- {0xa7f8, 0xa7f9, 1},
- {0xa8c4, 0xa8e0, 28},
- {0xa8e1, 0xa8f1, 1},
- {0xa92b, 0xa92e, 1},
- {0xa953, 0xa9b3, 96},
- {0xa9c0, 0xa9e5, 37},
- {0xaa7b, 0xaa7d, 1},
- {0xaabf, 0xaac2, 1},
- {0xaaf6, 0xab5b, 101},
- {0xab5c, 0xab5f, 1},
- {0xab69, 0xab6b, 1},
- {0xabec, 0xabed, 1},
- {0xfb1e, 0xfe20, 770},
- {0xfe21, 0xfe2f, 1},
- {0xff3e, 0xff40, 2},
- {0xff70, 0xff9e, 46},
- {0xff9f, 0xffe3, 68},
- },
- R32: []Range32{
- {0x102e0, 0x10ae5, 2053},
- {0x10ae6, 0x10d22, 572},
- {0x10d23, 0x10d27, 1},
- {0x10f46, 0x10f50, 1},
- {0x110b9, 0x110ba, 1},
- {0x11133, 0x11134, 1},
- {0x11173, 0x111c0, 77},
- {0x111ca, 0x111cc, 1},
- {0x11235, 0x11236, 1},
- {0x112e9, 0x112ea, 1},
- {0x1133c, 0x1134d, 17},
- {0x11366, 0x1136c, 1},
- {0x11370, 0x11374, 1},
- {0x11442, 0x11446, 4},
- {0x114c2, 0x114c3, 1},
- {0x115bf, 0x115c0, 1},
- {0x1163f, 0x116b6, 119},
- {0x116b7, 0x1172b, 116},
- {0x11839, 0x1183a, 1},
- {0x1193d, 0x1193e, 1},
- {0x11943, 0x119e0, 157},
- {0x11a34, 0x11a47, 19},
- {0x11a99, 0x11c3f, 422},
- {0x11d42, 0x11d44, 2},
- {0x11d45, 0x11d97, 82},
- {0x16af0, 0x16af4, 1},
- {0x16b30, 0x16b36, 1},
- {0x16f8f, 0x16f9f, 1},
- {0x16ff0, 0x16ff1, 1},
- {0x1d167, 0x1d169, 1},
- {0x1d16d, 0x1d172, 1},
- {0x1d17b, 0x1d182, 1},
- {0x1d185, 0x1d18b, 1},
- {0x1d1aa, 0x1d1ad, 1},
- {0x1e130, 0x1e136, 1},
- {0x1e2ec, 0x1e2ef, 1},
- {0x1e8d0, 0x1e8d6, 1},
- {0x1e944, 0x1e946, 1},
- {0x1e948, 0x1e94a, 1},
- },
- LatinOffset: 3,
-}
-
-var _Extender = &RangeTable{
- R16: []Range16{
- {0x00b7, 0x02d0, 537},
- {0x02d1, 0x0640, 879},
- {0x07fa, 0x0b55, 859},
- {0x0e46, 0x0ec6, 128},
- {0x180a, 0x1843, 57},
- {0x1aa7, 0x1c36, 399},
- {0x1c7b, 0x3005, 5002},
- {0x3031, 0x3035, 1},
- {0x309d, 0x309e, 1},
- {0x30fc, 0x30fe, 1},
- {0xa015, 0xa60c, 1527},
- {0xa9cf, 0xa9e6, 23},
- {0xaa70, 0xaadd, 109},
- {0xaaf3, 0xaaf4, 1},
- {0xff70, 0xff70, 1},
- },
- R32: []Range32{
- {0x1135d, 0x115c6, 617},
- {0x115c7, 0x115c8, 1},
- {0x11a98, 0x16b42, 20650},
- {0x16b43, 0x16fe0, 1181},
- {0x16fe1, 0x16fe3, 2},
- {0x1e13c, 0x1e13d, 1},
- {0x1e944, 0x1e946, 1},
- },
-}
-
-var _Hex_Digit = &RangeTable{
- R16: []Range16{
- {0x0030, 0x0039, 1},
- {0x0041, 0x0046, 1},
- {0x0061, 0x0066, 1},
- {0xff10, 0xff19, 1},
- {0xff21, 0xff26, 1},
- {0xff41, 0xff46, 1},
- },
- LatinOffset: 3,
-}
-
-var _Hyphen = &RangeTable{
- R16: []Range16{
- {0x002d, 0x00ad, 128},
- {0x058a, 0x1806, 4732},
- {0x2010, 0x2011, 1},
- {0x2e17, 0x30fb, 740},
- {0xfe63, 0xff0d, 170},
- {0xff65, 0xff65, 1},
- },
- LatinOffset: 1,
-}
-
-var _IDS_Binary_Operator = &RangeTable{
- R16: []Range16{
- {0x2ff0, 0x2ff1, 1},
- {0x2ff4, 0x2ffb, 1},
- },
-}
-
-var _IDS_Trinary_Operator = &RangeTable{
- R16: []Range16{
- {0x2ff2, 0x2ff3, 1},
- },
-}
-
-var _Ideographic = &RangeTable{
- R16: []Range16{
- {0x3006, 0x3007, 1},
- {0x3021, 0x3029, 1},
- {0x3038, 0x303a, 1},
- {0x3400, 0x4dbf, 1},
- {0x4e00, 0x9ffc, 1},
- {0xf900, 0xfa6d, 1},
- {0xfa70, 0xfad9, 1},
- },
- R32: []Range32{
- {0x16fe4, 0x17000, 28},
- {0x17001, 0x187f7, 1},
- {0x18800, 0x18cd5, 1},
- {0x18d00, 0x18d08, 1},
- {0x1b170, 0x1b2fb, 1},
- {0x20000, 0x2a6dd, 1},
- {0x2a700, 0x2b734, 1},
- {0x2b740, 0x2b81d, 1},
- {0x2b820, 0x2cea1, 1},
- {0x2ceb0, 0x2ebe0, 1},
- {0x2f800, 0x2fa1d, 1},
- {0x30000, 0x3134a, 1},
- },
-}
-
-var _Join_Control = &RangeTable{
- R16: []Range16{
- {0x200c, 0x200d, 1},
- },
-}
-
-var _Logical_Order_Exception = &RangeTable{
- R16: []Range16{
- {0x0e40, 0x0e44, 1},
- {0x0ec0, 0x0ec4, 1},
- {0x19b5, 0x19b7, 1},
- {0x19ba, 0xaab5, 37115},
- {0xaab6, 0xaab9, 3},
- {0xaabb, 0xaabc, 1},
- },
-}
-
-var _Noncharacter_Code_Point = &RangeTable{
- R16: []Range16{
- {0xfdd0, 0xfdef, 1},
- {0xfffe, 0xffff, 1},
- },
- R32: []Range32{
- {0x1fffe, 0x1ffff, 1},
- {0x2fffe, 0x2ffff, 1},
- {0x3fffe, 0x3ffff, 1},
- {0x4fffe, 0x4ffff, 1},
- {0x5fffe, 0x5ffff, 1},
- {0x6fffe, 0x6ffff, 1},
- {0x7fffe, 0x7ffff, 1},
- {0x8fffe, 0x8ffff, 1},
- {0x9fffe, 0x9ffff, 1},
- {0xafffe, 0xaffff, 1},
- {0xbfffe, 0xbffff, 1},
- {0xcfffe, 0xcffff, 1},
- {0xdfffe, 0xdffff, 1},
- {0xefffe, 0xeffff, 1},
- {0xffffe, 0xfffff, 1},
- {0x10fffe, 0x10ffff, 1},
- },
-}
-
-var _Other_Alphabetic = &RangeTable{
- R16: []Range16{
- {0x0345, 0x05b0, 619},
- {0x05b1, 0x05bd, 1},
- {0x05bf, 0x05c1, 2},
- {0x05c2, 0x05c4, 2},
- {0x05c5, 0x05c7, 2},
- {0x0610, 0x061a, 1},
- {0x064b, 0x0657, 1},
- {0x0659, 0x065f, 1},
- {0x0670, 0x06d6, 102},
- {0x06d7, 0x06dc, 1},
- {0x06e1, 0x06e4, 1},
- {0x06e7, 0x06e8, 1},
- {0x06ed, 0x0711, 36},
- {0x0730, 0x073f, 1},
- {0x07a6, 0x07b0, 1},
- {0x0816, 0x0817, 1},
- {0x081b, 0x0823, 1},
- {0x0825, 0x0827, 1},
- {0x0829, 0x082c, 1},
- {0x08d4, 0x08df, 1},
- {0x08e3, 0x08e9, 1},
- {0x08f0, 0x0903, 1},
- {0x093a, 0x093b, 1},
- {0x093e, 0x094c, 1},
- {0x094e, 0x094f, 1},
- {0x0955, 0x0957, 1},
- {0x0962, 0x0963, 1},
- {0x0981, 0x0983, 1},
- {0x09be, 0x09c4, 1},
- {0x09c7, 0x09c8, 1},
- {0x09cb, 0x09cc, 1},
- {0x09d7, 0x09e2, 11},
- {0x09e3, 0x0a01, 30},
- {0x0a02, 0x0a03, 1},
- {0x0a3e, 0x0a42, 1},
- {0x0a47, 0x0a48, 1},
- {0x0a4b, 0x0a4c, 1},
- {0x0a51, 0x0a70, 31},
- {0x0a71, 0x0a75, 4},
- {0x0a81, 0x0a83, 1},
- {0x0abe, 0x0ac5, 1},
- {0x0ac7, 0x0ac9, 1},
- {0x0acb, 0x0acc, 1},
- {0x0ae2, 0x0ae3, 1},
- {0x0afa, 0x0afc, 1},
- {0x0b01, 0x0b03, 1},
- {0x0b3e, 0x0b44, 1},
- {0x0b47, 0x0b48, 1},
- {0x0b4b, 0x0b4c, 1},
- {0x0b56, 0x0b57, 1},
- {0x0b62, 0x0b63, 1},
- {0x0b82, 0x0bbe, 60},
- {0x0bbf, 0x0bc2, 1},
- {0x0bc6, 0x0bc8, 1},
- {0x0bca, 0x0bcc, 1},
- {0x0bd7, 0x0c00, 41},
- {0x0c01, 0x0c03, 1},
- {0x0c3e, 0x0c44, 1},
- {0x0c46, 0x0c48, 1},
- {0x0c4a, 0x0c4c, 1},
- {0x0c55, 0x0c56, 1},
- {0x0c62, 0x0c63, 1},
- {0x0c81, 0x0c83, 1},
- {0x0cbe, 0x0cc4, 1},
- {0x0cc6, 0x0cc8, 1},
- {0x0cca, 0x0ccc, 1},
- {0x0cd5, 0x0cd6, 1},
- {0x0ce2, 0x0ce3, 1},
- {0x0d00, 0x0d03, 1},
- {0x0d3e, 0x0d44, 1},
- {0x0d46, 0x0d48, 1},
- {0x0d4a, 0x0d4c, 1},
- {0x0d57, 0x0d62, 11},
- {0x0d63, 0x0d81, 30},
- {0x0d82, 0x0d83, 1},
- {0x0dcf, 0x0dd4, 1},
- {0x0dd6, 0x0dd8, 2},
- {0x0dd9, 0x0ddf, 1},
- {0x0df2, 0x0df3, 1},
- {0x0e31, 0x0e34, 3},
- {0x0e35, 0x0e3a, 1},
- {0x0e4d, 0x0eb1, 100},
- {0x0eb4, 0x0eb9, 1},
- {0x0ebb, 0x0ebc, 1},
- {0x0ecd, 0x0f71, 164},
- {0x0f72, 0x0f81, 1},
- {0x0f8d, 0x0f97, 1},
- {0x0f99, 0x0fbc, 1},
- {0x102b, 0x1036, 1},
- {0x1038, 0x103b, 3},
- {0x103c, 0x103e, 1},
- {0x1056, 0x1059, 1},
- {0x105e, 0x1060, 1},
- {0x1062, 0x1064, 1},
- {0x1067, 0x106d, 1},
- {0x1071, 0x1074, 1},
- {0x1082, 0x108d, 1},
- {0x108f, 0x109a, 11},
- {0x109b, 0x109d, 1},
- {0x1712, 0x1713, 1},
- {0x1732, 0x1733, 1},
- {0x1752, 0x1753, 1},
- {0x1772, 0x1773, 1},
- {0x17b6, 0x17c8, 1},
- {0x1885, 0x1886, 1},
- {0x18a9, 0x1920, 119},
- {0x1921, 0x192b, 1},
- {0x1930, 0x1938, 1},
- {0x1a17, 0x1a1b, 1},
- {0x1a55, 0x1a5e, 1},
- {0x1a61, 0x1a74, 1},
- {0x1abf, 0x1ac0, 1},
- {0x1b00, 0x1b04, 1},
- {0x1b35, 0x1b43, 1},
- {0x1b80, 0x1b82, 1},
- {0x1ba1, 0x1ba9, 1},
- {0x1bac, 0x1bad, 1},
- {0x1be7, 0x1bf1, 1},
- {0x1c24, 0x1c36, 1},
- {0x1de7, 0x1df4, 1},
- {0x24b6, 0x24e9, 1},
- {0x2de0, 0x2dff, 1},
- {0xa674, 0xa67b, 1},
- {0xa69e, 0xa69f, 1},
- {0xa802, 0xa80b, 9},
- {0xa823, 0xa827, 1},
- {0xa880, 0xa881, 1},
- {0xa8b4, 0xa8c3, 1},
- {0xa8c5, 0xa8ff, 58},
- {0xa926, 0xa92a, 1},
- {0xa947, 0xa952, 1},
- {0xa980, 0xa983, 1},
- {0xa9b4, 0xa9bf, 1},
- {0xa9e5, 0xaa29, 68},
- {0xaa2a, 0xaa36, 1},
- {0xaa43, 0xaa4c, 9},
- {0xaa4d, 0xaa7b, 46},
- {0xaa7c, 0xaa7d, 1},
- {0xaab0, 0xaab2, 2},
- {0xaab3, 0xaab4, 1},
- {0xaab7, 0xaab8, 1},
- {0xaabe, 0xaaeb, 45},
- {0xaaec, 0xaaef, 1},
- {0xaaf5, 0xabe3, 238},
- {0xabe4, 0xabea, 1},
- {0xfb1e, 0xfb1e, 1},
- },
- R32: []Range32{
- {0x10376, 0x1037a, 1},
- {0x10a01, 0x10a03, 1},
- {0x10a05, 0x10a06, 1},
- {0x10a0c, 0x10a0f, 1},
- {0x10d24, 0x10d27, 1},
- {0x10eab, 0x10eac, 1},
- {0x11000, 0x11002, 1},
- {0x11038, 0x11045, 1},
- {0x11082, 0x110b0, 46},
- {0x110b1, 0x110b8, 1},
- {0x11100, 0x11102, 1},
- {0x11127, 0x11132, 1},
- {0x11145, 0x11146, 1},
- {0x11180, 0x11182, 1},
- {0x111b3, 0x111bf, 1},
- {0x111ce, 0x111cf, 1},
- {0x1122c, 0x11234, 1},
- {0x11237, 0x1123e, 7},
- {0x112df, 0x112e8, 1},
- {0x11300, 0x11303, 1},
- {0x1133e, 0x11344, 1},
- {0x11347, 0x11348, 1},
- {0x1134b, 0x1134c, 1},
- {0x11357, 0x11362, 11},
- {0x11363, 0x11435, 210},
- {0x11436, 0x11441, 1},
- {0x11443, 0x11445, 1},
- {0x114b0, 0x114c1, 1},
- {0x115af, 0x115b5, 1},
- {0x115b8, 0x115be, 1},
- {0x115dc, 0x115dd, 1},
- {0x11630, 0x1163e, 1},
- {0x11640, 0x116ab, 107},
- {0x116ac, 0x116b5, 1},
- {0x1171d, 0x1172a, 1},
- {0x1182c, 0x11838, 1},
- {0x11930, 0x11935, 1},
- {0x11937, 0x11938, 1},
- {0x1193b, 0x1193c, 1},
- {0x11940, 0x11942, 2},
- {0x119d1, 0x119d7, 1},
- {0x119da, 0x119df, 1},
- {0x119e4, 0x11a01, 29},
- {0x11a02, 0x11a0a, 1},
- {0x11a35, 0x11a39, 1},
- {0x11a3b, 0x11a3e, 1},
- {0x11a51, 0x11a5b, 1},
- {0x11a8a, 0x11a97, 1},
- {0x11c2f, 0x11c36, 1},
- {0x11c38, 0x11c3e, 1},
- {0x11c92, 0x11ca7, 1},
- {0x11ca9, 0x11cb6, 1},
- {0x11d31, 0x11d36, 1},
- {0x11d3a, 0x11d3c, 2},
- {0x11d3d, 0x11d3f, 2},
- {0x11d40, 0x11d41, 1},
- {0x11d43, 0x11d47, 4},
- {0x11d8a, 0x11d8e, 1},
- {0x11d90, 0x11d91, 1},
- {0x11d93, 0x11d96, 1},
- {0x11ef3, 0x11ef6, 1},
- {0x16f4f, 0x16f51, 2},
- {0x16f52, 0x16f87, 1},
- {0x16f8f, 0x16f92, 1},
- {0x16ff0, 0x16ff1, 1},
- {0x1bc9e, 0x1e000, 9058},
- {0x1e001, 0x1e006, 1},
- {0x1e008, 0x1e018, 1},
- {0x1e01b, 0x1e021, 1},
- {0x1e023, 0x1e024, 1},
- {0x1e026, 0x1e02a, 1},
- {0x1e947, 0x1f130, 2025},
- {0x1f131, 0x1f149, 1},
- {0x1f150, 0x1f169, 1},
- {0x1f170, 0x1f189, 1},
- },
-}
-
-var _Other_Default_Ignorable_Code_Point = &RangeTable{
- R16: []Range16{
- {0x034f, 0x115f, 3600},
- {0x1160, 0x17b4, 1620},
- {0x17b5, 0x2065, 2224},
- {0x3164, 0xffa0, 52796},
- {0xfff0, 0xfff8, 1},
- },
- R32: []Range32{
- {0xe0000, 0xe0002, 2},
- {0xe0003, 0xe001f, 1},
- {0xe0080, 0xe00ff, 1},
- {0xe01f0, 0xe0fff, 1},
- },
-}
-
-var _Other_Grapheme_Extend = &RangeTable{
- R16: []Range16{
- {0x09be, 0x09d7, 25},
- {0x0b3e, 0x0b57, 25},
- {0x0bbe, 0x0bd7, 25},
- {0x0cc2, 0x0cd5, 19},
- {0x0cd6, 0x0d3e, 104},
- {0x0d57, 0x0dcf, 120},
- {0x0ddf, 0x1b35, 3414},
- {0x200c, 0x302e, 4130},
- {0x302f, 0xff9e, 53103},
- {0xff9f, 0xff9f, 1},
- },
- R32: []Range32{
- {0x1133e, 0x11357, 25},
- {0x114b0, 0x114bd, 13},
- {0x115af, 0x11930, 897},
- {0x1d165, 0x1d16e, 9},
- {0x1d16f, 0x1d172, 1},
- {0xe0020, 0xe007f, 1},
- },
-}
-
-var _Other_ID_Continue = &RangeTable{
- R16: []Range16{
- {0x00b7, 0x0387, 720},
- {0x1369, 0x1371, 1},
- {0x19da, 0x19da, 1},
- },
-}
-
-var _Other_ID_Start = &RangeTable{
- R16: []Range16{
- {0x1885, 0x1886, 1},
- {0x2118, 0x212e, 22},
- {0x309b, 0x309c, 1},
- },
-}
-
-var _Other_Lowercase = &RangeTable{
- R16: []Range16{
- {0x00aa, 0x00ba, 16},
- {0x02b0, 0x02b8, 1},
- {0x02c0, 0x02c1, 1},
- {0x02e0, 0x02e4, 1},
- {0x0345, 0x037a, 53},
- {0x1d2c, 0x1d6a, 1},
- {0x1d78, 0x1d9b, 35},
- {0x1d9c, 0x1dbf, 1},
- {0x2071, 0x207f, 14},
- {0x2090, 0x209c, 1},
- {0x2170, 0x217f, 1},
- {0x24d0, 0x24e9, 1},
- {0x2c7c, 0x2c7d, 1},
- {0xa69c, 0xa69d, 1},
- {0xa770, 0xa7f8, 136},
- {0xa7f9, 0xab5c, 867},
- {0xab5d, 0xab5f, 1},
- },
- LatinOffset: 1,
-}
-
-var _Other_Math = &RangeTable{
- R16: []Range16{
- {0x005e, 0x03d0, 882},
- {0x03d1, 0x03d2, 1},
- {0x03d5, 0x03f0, 27},
- {0x03f1, 0x03f4, 3},
- {0x03f5, 0x2016, 7201},
- {0x2032, 0x2034, 1},
- {0x2040, 0x2061, 33},
- {0x2062, 0x2064, 1},
- {0x207d, 0x207e, 1},
- {0x208d, 0x208e, 1},
- {0x20d0, 0x20dc, 1},
- {0x20e1, 0x20e5, 4},
- {0x20e6, 0x20eb, 5},
- {0x20ec, 0x20ef, 1},
- {0x2102, 0x2107, 5},
- {0x210a, 0x2113, 1},
- {0x2115, 0x2119, 4},
- {0x211a, 0x211d, 1},
- {0x2124, 0x2128, 4},
- {0x2129, 0x212c, 3},
- {0x212d, 0x212f, 2},
- {0x2130, 0x2131, 1},
- {0x2133, 0x2138, 1},
- {0x213c, 0x213f, 1},
- {0x2145, 0x2149, 1},
- {0x2195, 0x2199, 1},
- {0x219c, 0x219f, 1},
- {0x21a1, 0x21a2, 1},
- {0x21a4, 0x21a5, 1},
- {0x21a7, 0x21a9, 2},
- {0x21aa, 0x21ad, 1},
- {0x21b0, 0x21b1, 1},
- {0x21b6, 0x21b7, 1},
- {0x21bc, 0x21cd, 1},
- {0x21d0, 0x21d1, 1},
- {0x21d3, 0x21d5, 2},
- {0x21d6, 0x21db, 1},
- {0x21dd, 0x21e4, 7},
- {0x21e5, 0x2308, 291},
- {0x2309, 0x230b, 1},
- {0x23b4, 0x23b5, 1},
- {0x23b7, 0x23d0, 25},
- {0x23e2, 0x25a0, 446},
- {0x25a1, 0x25ae, 13},
- {0x25af, 0x25b6, 1},
- {0x25bc, 0x25c0, 1},
- {0x25c6, 0x25c7, 1},
- {0x25ca, 0x25cb, 1},
- {0x25cf, 0x25d3, 1},
- {0x25e2, 0x25e4, 2},
- {0x25e7, 0x25ec, 1},
- {0x2605, 0x2606, 1},
- {0x2640, 0x2642, 2},
- {0x2660, 0x2663, 1},
- {0x266d, 0x266e, 1},
- {0x27c5, 0x27c6, 1},
- {0x27e6, 0x27ef, 1},
- {0x2983, 0x2998, 1},
- {0x29d8, 0x29db, 1},
- {0x29fc, 0x29fd, 1},
- {0xfe61, 0xfe63, 2},
- {0xfe68, 0xff3c, 212},
- {0xff3e, 0xff3e, 1},
- },
- R32: []Range32{
- {0x1d400, 0x1d454, 1},
- {0x1d456, 0x1d49c, 1},
- {0x1d49e, 0x1d49f, 1},
- {0x1d4a2, 0x1d4a5, 3},
- {0x1d4a6, 0x1d4a9, 3},
- {0x1d4aa, 0x1d4ac, 1},
- {0x1d4ae, 0x1d4b9, 1},
- {0x1d4bb, 0x1d4bd, 2},
- {0x1d4be, 0x1d4c3, 1},
- {0x1d4c5, 0x1d505, 1},
- {0x1d507, 0x1d50a, 1},
- {0x1d50d, 0x1d514, 1},
- {0x1d516, 0x1d51c, 1},
- {0x1d51e, 0x1d539, 1},
- {0x1d53b, 0x1d53e, 1},
- {0x1d540, 0x1d544, 1},
- {0x1d546, 0x1d54a, 4},
- {0x1d54b, 0x1d550, 1},
- {0x1d552, 0x1d6a5, 1},
- {0x1d6a8, 0x1d6c0, 1},
- {0x1d6c2, 0x1d6da, 1},
- {0x1d6dc, 0x1d6fa, 1},
- {0x1d6fc, 0x1d714, 1},
- {0x1d716, 0x1d734, 1},
- {0x1d736, 0x1d74e, 1},
- {0x1d750, 0x1d76e, 1},
- {0x1d770, 0x1d788, 1},
- {0x1d78a, 0x1d7a8, 1},
- {0x1d7aa, 0x1d7c2, 1},
- {0x1d7c4, 0x1d7cb, 1},
- {0x1d7ce, 0x1d7ff, 1},
- {0x1ee00, 0x1ee03, 1},
- {0x1ee05, 0x1ee1f, 1},
- {0x1ee21, 0x1ee22, 1},
- {0x1ee24, 0x1ee27, 3},
- {0x1ee29, 0x1ee32, 1},
- {0x1ee34, 0x1ee37, 1},
- {0x1ee39, 0x1ee3b, 2},
- {0x1ee42, 0x1ee47, 5},
- {0x1ee49, 0x1ee4d, 2},
- {0x1ee4e, 0x1ee4f, 1},
- {0x1ee51, 0x1ee52, 1},
- {0x1ee54, 0x1ee57, 3},
- {0x1ee59, 0x1ee61, 2},
- {0x1ee62, 0x1ee64, 2},
- {0x1ee67, 0x1ee6a, 1},
- {0x1ee6c, 0x1ee72, 1},
- {0x1ee74, 0x1ee77, 1},
- {0x1ee79, 0x1ee7c, 1},
- {0x1ee7e, 0x1ee80, 2},
- {0x1ee81, 0x1ee89, 1},
- {0x1ee8b, 0x1ee9b, 1},
- {0x1eea1, 0x1eea3, 1},
- {0x1eea5, 0x1eea9, 1},
- {0x1eeab, 0x1eebb, 1},
- },
-}
-
-var _Other_Uppercase = &RangeTable{
- R16: []Range16{
- {0x2160, 0x216f, 1},
- {0x24b6, 0x24cf, 1},
- },
- R32: []Range32{
- {0x1f130, 0x1f149, 1},
- {0x1f150, 0x1f169, 1},
- {0x1f170, 0x1f189, 1},
- },
-}
-
-var _Pattern_Syntax = &RangeTable{
- R16: []Range16{
- {0x0021, 0x002f, 1},
- {0x003a, 0x0040, 1},
- {0x005b, 0x005e, 1},
- {0x0060, 0x007b, 27},
- {0x007c, 0x007e, 1},
- {0x00a1, 0x00a7, 1},
- {0x00a9, 0x00ab, 2},
- {0x00ac, 0x00b0, 2},
- {0x00b1, 0x00bb, 5},
- {0x00bf, 0x00d7, 24},
- {0x00f7, 0x2010, 7961},
- {0x2011, 0x2027, 1},
- {0x2030, 0x203e, 1},
- {0x2041, 0x2053, 1},
- {0x2055, 0x205e, 1},
- {0x2190, 0x245f, 1},
- {0x2500, 0x2775, 1},
- {0x2794, 0x2bff, 1},
- {0x2e00, 0x2e7f, 1},
- {0x3001, 0x3003, 1},
- {0x3008, 0x3020, 1},
- {0x3030, 0xfd3e, 52494},
- {0xfd3f, 0xfe45, 262},
- {0xfe46, 0xfe46, 1},
- },
- LatinOffset: 10,
-}
-
-var _Pattern_White_Space = &RangeTable{
- R16: []Range16{
- {0x0009, 0x000d, 1},
- {0x0020, 0x0085, 101},
- {0x200e, 0x200f, 1},
- {0x2028, 0x2029, 1},
- },
- LatinOffset: 2,
-}
-
-var _Prepended_Concatenation_Mark = &RangeTable{
- R16: []Range16{
- {0x0600, 0x0605, 1},
- {0x06dd, 0x070f, 50},
- {0x08e2, 0x08e2, 1},
- },
- R32: []Range32{
- {0x110bd, 0x110cd, 16},
- },
-}
-
-var _Quotation_Mark = &RangeTable{
- R16: []Range16{
- {0x0022, 0x0027, 5},
- {0x00ab, 0x00bb, 16},
- {0x2018, 0x201f, 1},
- {0x2039, 0x203a, 1},
- {0x2e42, 0x300c, 458},
- {0x300d, 0x300f, 1},
- {0x301d, 0x301f, 1},
- {0xfe41, 0xfe44, 1},
- {0xff02, 0xff07, 5},
- {0xff62, 0xff63, 1},
- },
- LatinOffset: 2,
-}
-
-var _Radical = &RangeTable{
- R16: []Range16{
- {0x2e80, 0x2e99, 1},
- {0x2e9b, 0x2ef3, 1},
- {0x2f00, 0x2fd5, 1},
- },
-}
-
-var _Regional_Indicator = &RangeTable{
- R16: []Range16{},
- R32: []Range32{
- {0x1f1e6, 0x1f1ff, 1},
- },
-}
-
-var _Sentence_Terminal = &RangeTable{
- R16: []Range16{
- {0x0021, 0x002e, 13},
- {0x003f, 0x0589, 1354},
- {0x061e, 0x061f, 1},
- {0x06d4, 0x0700, 44},
- {0x0701, 0x0702, 1},
- {0x07f9, 0x0837, 62},
- {0x0839, 0x083d, 4},
- {0x083e, 0x0964, 294},
- {0x0965, 0x104a, 1765},
- {0x104b, 0x1362, 791},
- {0x1367, 0x1368, 1},
- {0x166e, 0x1735, 199},
- {0x1736, 0x1803, 205},
- {0x1809, 0x1944, 315},
- {0x1945, 0x1aa8, 355},
- {0x1aa9, 0x1aab, 1},
- {0x1b5a, 0x1b5b, 1},
- {0x1b5e, 0x1b5f, 1},
- {0x1c3b, 0x1c3c, 1},
- {0x1c7e, 0x1c7f, 1},
- {0x203c, 0x203d, 1},
- {0x2047, 0x2049, 1},
- {0x2e2e, 0x2e3c, 14},
- {0x3002, 0xa4ff, 29949},
- {0xa60e, 0xa60f, 1},
- {0xa6f3, 0xa6f7, 4},
- {0xa876, 0xa877, 1},
- {0xa8ce, 0xa8cf, 1},
- {0xa92f, 0xa9c8, 153},
- {0xa9c9, 0xaa5d, 148},
- {0xaa5e, 0xaa5f, 1},
- {0xaaf0, 0xaaf1, 1},
- {0xabeb, 0xfe52, 21095},
- {0xfe56, 0xfe57, 1},
- {0xff01, 0xff0e, 13},
- {0xff1f, 0xff61, 66},
- },
- R32: []Range32{
- {0x10a56, 0x10a57, 1},
- {0x10f55, 0x10f59, 1},
- {0x11047, 0x11048, 1},
- {0x110be, 0x110c1, 1},
- {0x11141, 0x11143, 1},
- {0x111c5, 0x111c6, 1},
- {0x111cd, 0x111de, 17},
- {0x111df, 0x11238, 89},
- {0x11239, 0x1123b, 2},
- {0x1123c, 0x112a9, 109},
- {0x1144b, 0x1144c, 1},
- {0x115c2, 0x115c3, 1},
- {0x115c9, 0x115d7, 1},
- {0x11641, 0x11642, 1},
- {0x1173c, 0x1173e, 1},
- {0x11944, 0x11946, 2},
- {0x11a42, 0x11a43, 1},
- {0x11a9b, 0x11a9c, 1},
- {0x11c41, 0x11c42, 1},
- {0x11ef7, 0x11ef8, 1},
- {0x16a6e, 0x16a6f, 1},
- {0x16af5, 0x16b37, 66},
- {0x16b38, 0x16b44, 12},
- {0x16e98, 0x1bc9f, 19975},
- {0x1da88, 0x1da88, 1},
- },
- LatinOffset: 1,
-}
-
-var _Soft_Dotted = &RangeTable{
- R16: []Range16{
- {0x0069, 0x006a, 1},
- {0x012f, 0x0249, 282},
- {0x0268, 0x029d, 53},
- {0x02b2, 0x03f3, 321},
- {0x0456, 0x0458, 2},
- {0x1d62, 0x1d96, 52},
- {0x1da4, 0x1da8, 4},
- {0x1e2d, 0x1ecb, 158},
- {0x2071, 0x2148, 215},
- {0x2149, 0x2c7c, 2867},
- },
- R32: []Range32{
- {0x1d422, 0x1d423, 1},
- {0x1d456, 0x1d457, 1},
- {0x1d48a, 0x1d48b, 1},
- {0x1d4be, 0x1d4bf, 1},
- {0x1d4f2, 0x1d4f3, 1},
- {0x1d526, 0x1d527, 1},
- {0x1d55a, 0x1d55b, 1},
- {0x1d58e, 0x1d58f, 1},
- {0x1d5c2, 0x1d5c3, 1},
- {0x1d5f6, 0x1d5f7, 1},
- {0x1d62a, 0x1d62b, 1},
- {0x1d65e, 0x1d65f, 1},
- {0x1d692, 0x1d693, 1},
- },
- LatinOffset: 1,
-}
-
-var _Terminal_Punctuation = &RangeTable{
- R16: []Range16{
- {0x0021, 0x002c, 11},
- {0x002e, 0x003a, 12},
- {0x003b, 0x003f, 4},
- {0x037e, 0x0387, 9},
- {0x0589, 0x05c3, 58},
- {0x060c, 0x061b, 15},
- {0x061e, 0x061f, 1},
- {0x06d4, 0x0700, 44},
- {0x0701, 0x070a, 1},
- {0x070c, 0x07f8, 236},
- {0x07f9, 0x0830, 55},
- {0x0831, 0x083e, 1},
- {0x085e, 0x0964, 262},
- {0x0965, 0x0e5a, 1269},
- {0x0e5b, 0x0f08, 173},
- {0x0f0d, 0x0f12, 1},
- {0x104a, 0x104b, 1},
- {0x1361, 0x1368, 1},
- {0x166e, 0x16eb, 125},
- {0x16ec, 0x16ed, 1},
- {0x1735, 0x1736, 1},
- {0x17d4, 0x17d6, 1},
- {0x17da, 0x1802, 40},
- {0x1803, 0x1805, 1},
- {0x1808, 0x1809, 1},
- {0x1944, 0x1945, 1},
- {0x1aa8, 0x1aab, 1},
- {0x1b5a, 0x1b5b, 1},
- {0x1b5d, 0x1b5f, 1},
- {0x1c3b, 0x1c3f, 1},
- {0x1c7e, 0x1c7f, 1},
- {0x203c, 0x203d, 1},
- {0x2047, 0x2049, 1},
- {0x2e2e, 0x2e3c, 14},
- {0x2e41, 0x2e4c, 11},
- {0x2e4e, 0x2e4f, 1},
- {0x3001, 0x3002, 1},
- {0xa4fe, 0xa4ff, 1},
- {0xa60d, 0xa60f, 1},
- {0xa6f3, 0xa6f7, 1},
- {0xa876, 0xa877, 1},
- {0xa8ce, 0xa8cf, 1},
- {0xa92f, 0xa9c7, 152},
- {0xa9c8, 0xa9c9, 1},
- {0xaa5d, 0xaa5f, 1},
- {0xaadf, 0xaaf0, 17},
- {0xaaf1, 0xabeb, 250},
- {0xfe50, 0xfe52, 1},
- {0xfe54, 0xfe57, 1},
- {0xff01, 0xff0c, 11},
- {0xff0e, 0xff1a, 12},
- {0xff1b, 0xff1f, 4},
- {0xff61, 0xff64, 3},
- },
- R32: []Range32{
- {0x1039f, 0x103d0, 49},
- {0x10857, 0x1091f, 200},
- {0x10a56, 0x10a57, 1},
- {0x10af0, 0x10af5, 1},
- {0x10b3a, 0x10b3f, 1},
- {0x10b99, 0x10b9c, 1},
- {0x10f55, 0x10f59, 1},
- {0x11047, 0x1104d, 1},
- {0x110be, 0x110c1, 1},
- {0x11141, 0x11143, 1},
- {0x111c5, 0x111c6, 1},
- {0x111cd, 0x111de, 17},
- {0x111df, 0x11238, 89},
- {0x11239, 0x1123c, 1},
- {0x112a9, 0x1144b, 418},
- {0x1144c, 0x1144d, 1},
- {0x1145a, 0x1145b, 1},
- {0x115c2, 0x115c5, 1},
- {0x115c9, 0x115d7, 1},
- {0x11641, 0x11642, 1},
- {0x1173c, 0x1173e, 1},
- {0x11944, 0x11946, 2},
- {0x11a42, 0x11a43, 1},
- {0x11a9b, 0x11a9c, 1},
- {0x11aa1, 0x11aa2, 1},
- {0x11c41, 0x11c43, 1},
- {0x11c71, 0x11ef7, 646},
- {0x11ef8, 0x12470, 1400},
- {0x12471, 0x12474, 1},
- {0x16a6e, 0x16a6f, 1},
- {0x16af5, 0x16b37, 66},
- {0x16b38, 0x16b39, 1},
- {0x16b44, 0x16e97, 851},
- {0x16e98, 0x1bc9f, 19975},
- {0x1da87, 0x1da8a, 1},
- },
- LatinOffset: 3,
-}
-
-var _Unified_Ideograph = &RangeTable{
- R16: []Range16{
- {0x3400, 0x4dbf, 1},
- {0x4e00, 0x9ffc, 1},
- {0xfa0e, 0xfa0f, 1},
- {0xfa11, 0xfa13, 2},
- {0xfa14, 0xfa1f, 11},
- {0xfa21, 0xfa23, 2},
- {0xfa24, 0xfa27, 3},
- {0xfa28, 0xfa29, 1},
- },
- R32: []Range32{
- {0x20000, 0x2a6dd, 1},
- {0x2a700, 0x2b734, 1},
- {0x2b740, 0x2b81d, 1},
- {0x2b820, 0x2cea1, 1},
- {0x2ceb0, 0x2ebe0, 1},
- {0x30000, 0x3134a, 1},
- },
-}
-
-var _Variation_Selector = &RangeTable{
- R16: []Range16{
- {0x180b, 0x180d, 1},
- {0xfe00, 0xfe0f, 1},
- },
- R32: []Range32{
- {0xe0100, 0xe01ef, 1},
- },
-}
-
-var _White_Space = &RangeTable{
- R16: []Range16{
- {0x0009, 0x000d, 1},
- {0x0020, 0x0085, 101},
- {0x00a0, 0x1680, 5600},
- {0x2000, 0x200a, 1},
- {0x2028, 0x2029, 1},
- {0x202f, 0x205f, 48},
- {0x3000, 0x3000, 1},
- },
- LatinOffset: 2,
-}
-
-// These variables have type *RangeTable.
-var (
- ASCII_Hex_Digit = _ASCII_Hex_Digit // ASCII_Hex_Digit is the set of Unicode characters with property ASCII_Hex_Digit.
- Bidi_Control = _Bidi_Control // Bidi_Control is the set of Unicode characters with property Bidi_Control.
- Dash = _Dash // Dash is the set of Unicode characters with property Dash.
- Deprecated = _Deprecated // Deprecated is the set of Unicode characters with property Deprecated.
- Diacritic = _Diacritic // Diacritic is the set of Unicode characters with property Diacritic.
- Extender = _Extender // Extender is the set of Unicode characters with property Extender.
- Hex_Digit = _Hex_Digit // Hex_Digit is the set of Unicode characters with property Hex_Digit.
- Hyphen = _Hyphen // Hyphen is the set of Unicode characters with property Hyphen.
- IDS_Binary_Operator = _IDS_Binary_Operator // IDS_Binary_Operator is the set of Unicode characters with property IDS_Binary_Operator.
- IDS_Trinary_Operator = _IDS_Trinary_Operator // IDS_Trinary_Operator is the set of Unicode characters with property IDS_Trinary_Operator.
- Ideographic = _Ideographic // Ideographic is the set of Unicode characters with property Ideographic.
- Join_Control = _Join_Control // Join_Control is the set of Unicode characters with property Join_Control.
- Logical_Order_Exception = _Logical_Order_Exception // Logical_Order_Exception is the set of Unicode characters with property Logical_Order_Exception.
- Noncharacter_Code_Point = _Noncharacter_Code_Point // Noncharacter_Code_Point is the set of Unicode characters with property Noncharacter_Code_Point.
- Other_Alphabetic = _Other_Alphabetic // Other_Alphabetic is the set of Unicode characters with property Other_Alphabetic.
- Other_Default_Ignorable_Code_Point = _Other_Default_Ignorable_Code_Point // Other_Default_Ignorable_Code_Point is the set of Unicode characters with property Other_Default_Ignorable_Code_Point.
- Other_Grapheme_Extend = _Other_Grapheme_Extend // Other_Grapheme_Extend is the set of Unicode characters with property Other_Grapheme_Extend.
- Other_ID_Continue = _Other_ID_Continue // Other_ID_Continue is the set of Unicode characters with property Other_ID_Continue.
- Other_ID_Start = _Other_ID_Start // Other_ID_Start is the set of Unicode characters with property Other_ID_Start.
- Other_Lowercase = _Other_Lowercase // Other_Lowercase is the set of Unicode characters with property Other_Lowercase.
- Other_Math = _Other_Math // Other_Math is the set of Unicode characters with property Other_Math.
- Other_Uppercase = _Other_Uppercase // Other_Uppercase is the set of Unicode characters with property Other_Uppercase.
- Pattern_Syntax = _Pattern_Syntax // Pattern_Syntax is the set of Unicode characters with property Pattern_Syntax.
- Pattern_White_Space = _Pattern_White_Space // Pattern_White_Space is the set of Unicode characters with property Pattern_White_Space.
- Prepended_Concatenation_Mark = _Prepended_Concatenation_Mark // Prepended_Concatenation_Mark is the set of Unicode characters with property Prepended_Concatenation_Mark.
- Quotation_Mark = _Quotation_Mark // Quotation_Mark is the set of Unicode characters with property Quotation_Mark.
- Radical = _Radical // Radical is the set of Unicode characters with property Radical.
- Regional_Indicator = _Regional_Indicator // Regional_Indicator is the set of Unicode characters with property Regional_Indicator.
- STerm = _Sentence_Terminal // STerm is an alias for Sentence_Terminal.
- Sentence_Terminal = _Sentence_Terminal // Sentence_Terminal is the set of Unicode characters with property Sentence_Terminal.
- Soft_Dotted = _Soft_Dotted // Soft_Dotted is the set of Unicode characters with property Soft_Dotted.
- Terminal_Punctuation = _Terminal_Punctuation // Terminal_Punctuation is the set of Unicode characters with property Terminal_Punctuation.
- Unified_Ideograph = _Unified_Ideograph // Unified_Ideograph is the set of Unicode characters with property Unified_Ideograph.
- Variation_Selector = _Variation_Selector // Variation_Selector is the set of Unicode characters with property Variation_Selector.
- White_Space = _White_Space // White_Space is the set of Unicode characters with property White_Space.
-)
-
-// CaseRanges is the table describing case mappings for all letters with
-// non-self mappings.
-var CaseRanges = _CaseRanges
-var _CaseRanges = []CaseRange{
- {0x0041, 0x005A, d{0, 32, 0}},
- {0x0061, 0x007A, d{-32, 0, -32}},
- {0x00B5, 0x00B5, d{743, 0, 743}},
- {0x00C0, 0x00D6, d{0, 32, 0}},
- {0x00D8, 0x00DE, d{0, 32, 0}},
- {0x00E0, 0x00F6, d{-32, 0, -32}},
- {0x00F8, 0x00FE, d{-32, 0, -32}},
- {0x00FF, 0x00FF, d{121, 0, 121}},
- {0x0100, 0x012F, d{UpperLower, UpperLower, UpperLower}},
- {0x0130, 0x0130, d{0, -199, 0}},
- {0x0131, 0x0131, d{-232, 0, -232}},
- {0x0132, 0x0137, d{UpperLower, UpperLower, UpperLower}},
- {0x0139, 0x0148, d{UpperLower, UpperLower, UpperLower}},
- {0x014A, 0x0177, d{UpperLower, UpperLower, UpperLower}},
- {0x0178, 0x0178, d{0, -121, 0}},
- {0x0179, 0x017E, d{UpperLower, UpperLower, UpperLower}},
- {0x017F, 0x017F, d{-300, 0, -300}},
- {0x0180, 0x0180, d{195, 0, 195}},
- {0x0181, 0x0181, d{0, 210, 0}},
- {0x0182, 0x0185, d{UpperLower, UpperLower, UpperLower}},
- {0x0186, 0x0186, d{0, 206, 0}},
- {0x0187, 0x0188, d{UpperLower, UpperLower, UpperLower}},
- {0x0189, 0x018A, d{0, 205, 0}},
- {0x018B, 0x018C, d{UpperLower, UpperLower, UpperLower}},
- {0x018E, 0x018E, d{0, 79, 0}},
- {0x018F, 0x018F, d{0, 202, 0}},
- {0x0190, 0x0190, d{0, 203, 0}},
- {0x0191, 0x0192, d{UpperLower, UpperLower, UpperLower}},
- {0x0193, 0x0193, d{0, 205, 0}},
- {0x0194, 0x0194, d{0, 207, 0}},
- {0x0195, 0x0195, d{97, 0, 97}},
- {0x0196, 0x0196, d{0, 211, 0}},
- {0x0197, 0x0197, d{0, 209, 0}},
- {0x0198, 0x0199, d{UpperLower, UpperLower, UpperLower}},
- {0x019A, 0x019A, d{163, 0, 163}},
- {0x019C, 0x019C, d{0, 211, 0}},
- {0x019D, 0x019D, d{0, 213, 0}},
- {0x019E, 0x019E, d{130, 0, 130}},
- {0x019F, 0x019F, d{0, 214, 0}},
- {0x01A0, 0x01A5, d{UpperLower, UpperLower, UpperLower}},
- {0x01A6, 0x01A6, d{0, 218, 0}},
- {0x01A7, 0x01A8, d{UpperLower, UpperLower, UpperLower}},
- {0x01A9, 0x01A9, d{0, 218, 0}},
- {0x01AC, 0x01AD, d{UpperLower, UpperLower, UpperLower}},
- {0x01AE, 0x01AE, d{0, 218, 0}},
- {0x01AF, 0x01B0, d{UpperLower, UpperLower, UpperLower}},
- {0x01B1, 0x01B2, d{0, 217, 0}},
- {0x01B3, 0x01B6, d{UpperLower, UpperLower, UpperLower}},
- {0x01B7, 0x01B7, d{0, 219, 0}},
- {0x01B8, 0x01B9, d{UpperLower, UpperLower, UpperLower}},
- {0x01BC, 0x01BD, d{UpperLower, UpperLower, UpperLower}},
- {0x01BF, 0x01BF, d{56, 0, 56}},
- {0x01C4, 0x01C4, d{0, 2, 1}},
- {0x01C5, 0x01C5, d{-1, 1, 0}},
- {0x01C6, 0x01C6, d{-2, 0, -1}},
- {0x01C7, 0x01C7, d{0, 2, 1}},
- {0x01C8, 0x01C8, d{-1, 1, 0}},
- {0x01C9, 0x01C9, d{-2, 0, -1}},
- {0x01CA, 0x01CA, d{0, 2, 1}},
- {0x01CB, 0x01CB, d{-1, 1, 0}},
- {0x01CC, 0x01CC, d{-2, 0, -1}},
- {0x01CD, 0x01DC, d{UpperLower, UpperLower, UpperLower}},
- {0x01DD, 0x01DD, d{-79, 0, -79}},
- {0x01DE, 0x01EF, d{UpperLower, UpperLower, UpperLower}},
- {0x01F1, 0x01F1, d{0, 2, 1}},
- {0x01F2, 0x01F2, d{-1, 1, 0}},
- {0x01F3, 0x01F3, d{-2, 0, -1}},
- {0x01F4, 0x01F5, d{UpperLower, UpperLower, UpperLower}},
- {0x01F6, 0x01F6, d{0, -97, 0}},
- {0x01F7, 0x01F7, d{0, -56, 0}},
- {0x01F8, 0x021F, d{UpperLower, UpperLower, UpperLower}},
- {0x0220, 0x0220, d{0, -130, 0}},
- {0x0222, 0x0233, d{UpperLower, UpperLower, UpperLower}},
- {0x023A, 0x023A, d{0, 10795, 0}},
- {0x023B, 0x023C, d{UpperLower, UpperLower, UpperLower}},
- {0x023D, 0x023D, d{0, -163, 0}},
- {0x023E, 0x023E, d{0, 10792, 0}},
- {0x023F, 0x0240, d{10815, 0, 10815}},
- {0x0241, 0x0242, d{UpperLower, UpperLower, UpperLower}},
- {0x0243, 0x0243, d{0, -195, 0}},
- {0x0244, 0x0244, d{0, 69, 0}},
- {0x0245, 0x0245, d{0, 71, 0}},
- {0x0246, 0x024F, d{UpperLower, UpperLower, UpperLower}},
- {0x0250, 0x0250, d{10783, 0, 10783}},
- {0x0251, 0x0251, d{10780, 0, 10780}},
- {0x0252, 0x0252, d{10782, 0, 10782}},
- {0x0253, 0x0253, d{-210, 0, -210}},
- {0x0254, 0x0254, d{-206, 0, -206}},
- {0x0256, 0x0257, d{-205, 0, -205}},
- {0x0259, 0x0259, d{-202, 0, -202}},
- {0x025B, 0x025B, d{-203, 0, -203}},
- {0x025C, 0x025C, d{42319, 0, 42319}},
- {0x0260, 0x0260, d{-205, 0, -205}},
- {0x0261, 0x0261, d{42315, 0, 42315}},
- {0x0263, 0x0263, d{-207, 0, -207}},
- {0x0265, 0x0265, d{42280, 0, 42280}},
- {0x0266, 0x0266, d{42308, 0, 42308}},
- {0x0268, 0x0268, d{-209, 0, -209}},
- {0x0269, 0x0269, d{-211, 0, -211}},
- {0x026A, 0x026A, d{42308, 0, 42308}},
- {0x026B, 0x026B, d{10743, 0, 10743}},
- {0x026C, 0x026C, d{42305, 0, 42305}},
- {0x026F, 0x026F, d{-211, 0, -211}},
- {0x0271, 0x0271, d{10749, 0, 10749}},
- {0x0272, 0x0272, d{-213, 0, -213}},
- {0x0275, 0x0275, d{-214, 0, -214}},
- {0x027D, 0x027D, d{10727, 0, 10727}},
- {0x0280, 0x0280, d{-218, 0, -218}},
- {0x0282, 0x0282, d{42307, 0, 42307}},
- {0x0283, 0x0283, d{-218, 0, -218}},
- {0x0287, 0x0287, d{42282, 0, 42282}},
- {0x0288, 0x0288, d{-218, 0, -218}},
- {0x0289, 0x0289, d{-69, 0, -69}},
- {0x028A, 0x028B, d{-217, 0, -217}},
- {0x028C, 0x028C, d{-71, 0, -71}},
- {0x0292, 0x0292, d{-219, 0, -219}},
- {0x029D, 0x029D, d{42261, 0, 42261}},
- {0x029E, 0x029E, d{42258, 0, 42258}},
- {0x0345, 0x0345, d{84, 0, 84}},
- {0x0370, 0x0373, d{UpperLower, UpperLower, UpperLower}},
- {0x0376, 0x0377, d{UpperLower, UpperLower, UpperLower}},
- {0x037B, 0x037D, d{130, 0, 130}},
- {0x037F, 0x037F, d{0, 116, 0}},
- {0x0386, 0x0386, d{0, 38, 0}},
- {0x0388, 0x038A, d{0, 37, 0}},
- {0x038C, 0x038C, d{0, 64, 0}},
- {0x038E, 0x038F, d{0, 63, 0}},
- {0x0391, 0x03A1, d{0, 32, 0}},
- {0x03A3, 0x03AB, d{0, 32, 0}},
- {0x03AC, 0x03AC, d{-38, 0, -38}},
- {0x03AD, 0x03AF, d{-37, 0, -37}},
- {0x03B1, 0x03C1, d{-32, 0, -32}},
- {0x03C2, 0x03C2, d{-31, 0, -31}},
- {0x03C3, 0x03CB, d{-32, 0, -32}},
- {0x03CC, 0x03CC, d{-64, 0, -64}},
- {0x03CD, 0x03CE, d{-63, 0, -63}},
- {0x03CF, 0x03CF, d{0, 8, 0}},
- {0x03D0, 0x03D0, d{-62, 0, -62}},
- {0x03D1, 0x03D1, d{-57, 0, -57}},
- {0x03D5, 0x03D5, d{-47, 0, -47}},
- {0x03D6, 0x03D6, d{-54, 0, -54}},
- {0x03D7, 0x03D7, d{-8, 0, -8}},
- {0x03D8, 0x03EF, d{UpperLower, UpperLower, UpperLower}},
- {0x03F0, 0x03F0, d{-86, 0, -86}},
- {0x03F1, 0x03F1, d{-80, 0, -80}},
- {0x03F2, 0x03F2, d{7, 0, 7}},
- {0x03F3, 0x03F3, d{-116, 0, -116}},
- {0x03F4, 0x03F4, d{0, -60, 0}},
- {0x03F5, 0x03F5, d{-96, 0, -96}},
- {0x03F7, 0x03F8, d{UpperLower, UpperLower, UpperLower}},
- {0x03F9, 0x03F9, d{0, -7, 0}},
- {0x03FA, 0x03FB, d{UpperLower, UpperLower, UpperLower}},
- {0x03FD, 0x03FF, d{0, -130, 0}},
- {0x0400, 0x040F, d{0, 80, 0}},
- {0x0410, 0x042F, d{0, 32, 0}},
- {0x0430, 0x044F, d{-32, 0, -32}},
- {0x0450, 0x045F, d{-80, 0, -80}},
- {0x0460, 0x0481, d{UpperLower, UpperLower, UpperLower}},
- {0x048A, 0x04BF, d{UpperLower, UpperLower, UpperLower}},
- {0x04C0, 0x04C0, d{0, 15, 0}},
- {0x04C1, 0x04CE, d{UpperLower, UpperLower, UpperLower}},
- {0x04CF, 0x04CF, d{-15, 0, -15}},
- {0x04D0, 0x052F, d{UpperLower, UpperLower, UpperLower}},
- {0x0531, 0x0556, d{0, 48, 0}},
- {0x0561, 0x0586, d{-48, 0, -48}},
- {0x10A0, 0x10C5, d{0, 7264, 0}},
- {0x10C7, 0x10C7, d{0, 7264, 0}},
- {0x10CD, 0x10CD, d{0, 7264, 0}},
- {0x10D0, 0x10FA, d{3008, 0, 0}},
- {0x10FD, 0x10FF, d{3008, 0, 0}},
- {0x13A0, 0x13EF, d{0, 38864, 0}},
- {0x13F0, 0x13F5, d{0, 8, 0}},
- {0x13F8, 0x13FD, d{-8, 0, -8}},
- {0x1C80, 0x1C80, d{-6254, 0, -6254}},
- {0x1C81, 0x1C81, d{-6253, 0, -6253}},
- {0x1C82, 0x1C82, d{-6244, 0, -6244}},
- {0x1C83, 0x1C84, d{-6242, 0, -6242}},
- {0x1C85, 0x1C85, d{-6243, 0, -6243}},
- {0x1C86, 0x1C86, d{-6236, 0, -6236}},
- {0x1C87, 0x1C87, d{-6181, 0, -6181}},
- {0x1C88, 0x1C88, d{35266, 0, 35266}},
- {0x1C90, 0x1CBA, d{0, -3008, 0}},
- {0x1CBD, 0x1CBF, d{0, -3008, 0}},
- {0x1D79, 0x1D79, d{35332, 0, 35332}},
- {0x1D7D, 0x1D7D, d{3814, 0, 3814}},
- {0x1D8E, 0x1D8E, d{35384, 0, 35384}},
- {0x1E00, 0x1E95, d{UpperLower, UpperLower, UpperLower}},
- {0x1E9B, 0x1E9B, d{-59, 0, -59}},
- {0x1E9E, 0x1E9E, d{0, -7615, 0}},
- {0x1EA0, 0x1EFF, d{UpperLower, UpperLower, UpperLower}},
- {0x1F00, 0x1F07, d{8, 0, 8}},
- {0x1F08, 0x1F0F, d{0, -8, 0}},
- {0x1F10, 0x1F15, d{8, 0, 8}},
- {0x1F18, 0x1F1D, d{0, -8, 0}},
- {0x1F20, 0x1F27, d{8, 0, 8}},
- {0x1F28, 0x1F2F, d{0, -8, 0}},
- {0x1F30, 0x1F37, d{8, 0, 8}},
- {0x1F38, 0x1F3F, d{0, -8, 0}},
- {0x1F40, 0x1F45, d{8, 0, 8}},
- {0x1F48, 0x1F4D, d{0, -8, 0}},
- {0x1F51, 0x1F51, d{8, 0, 8}},
- {0x1F53, 0x1F53, d{8, 0, 8}},
- {0x1F55, 0x1F55, d{8, 0, 8}},
- {0x1F57, 0x1F57, d{8, 0, 8}},
- {0x1F59, 0x1F59, d{0, -8, 0}},
- {0x1F5B, 0x1F5B, d{0, -8, 0}},
- {0x1F5D, 0x1F5D, d{0, -8, 0}},
- {0x1F5F, 0x1F5F, d{0, -8, 0}},
- {0x1F60, 0x1F67, d{8, 0, 8}},
- {0x1F68, 0x1F6F, d{0, -8, 0}},
- {0x1F70, 0x1F71, d{74, 0, 74}},
- {0x1F72, 0x1F75, d{86, 0, 86}},
- {0x1F76, 0x1F77, d{100, 0, 100}},
- {0x1F78, 0x1F79, d{128, 0, 128}},
- {0x1F7A, 0x1F7B, d{112, 0, 112}},
- {0x1F7C, 0x1F7D, d{126, 0, 126}},
- {0x1F80, 0x1F87, d{8, 0, 8}},
- {0x1F88, 0x1F8F, d{0, -8, 0}},
- {0x1F90, 0x1F97, d{8, 0, 8}},
- {0x1F98, 0x1F9F, d{0, -8, 0}},
- {0x1FA0, 0x1FA7, d{8, 0, 8}},
- {0x1FA8, 0x1FAF, d{0, -8, 0}},
- {0x1FB0, 0x1FB1, d{8, 0, 8}},
- {0x1FB3, 0x1FB3, d{9, 0, 9}},
- {0x1FB8, 0x1FB9, d{0, -8, 0}},
- {0x1FBA, 0x1FBB, d{0, -74, 0}},
- {0x1FBC, 0x1FBC, d{0, -9, 0}},
- {0x1FBE, 0x1FBE, d{-7205, 0, -7205}},
- {0x1FC3, 0x1FC3, d{9, 0, 9}},
- {0x1FC8, 0x1FCB, d{0, -86, 0}},
- {0x1FCC, 0x1FCC, d{0, -9, 0}},
- {0x1FD0, 0x1FD1, d{8, 0, 8}},
- {0x1FD8, 0x1FD9, d{0, -8, 0}},
- {0x1FDA, 0x1FDB, d{0, -100, 0}},
- {0x1FE0, 0x1FE1, d{8, 0, 8}},
- {0x1FE5, 0x1FE5, d{7, 0, 7}},
- {0x1FE8, 0x1FE9, d{0, -8, 0}},
- {0x1FEA, 0x1FEB, d{0, -112, 0}},
- {0x1FEC, 0x1FEC, d{0, -7, 0}},
- {0x1FF3, 0x1FF3, d{9, 0, 9}},
- {0x1FF8, 0x1FF9, d{0, -128, 0}},
- {0x1FFA, 0x1FFB, d{0, -126, 0}},
- {0x1FFC, 0x1FFC, d{0, -9, 0}},
- {0x2126, 0x2126, d{0, -7517, 0}},
- {0x212A, 0x212A, d{0, -8383, 0}},
- {0x212B, 0x212B, d{0, -8262, 0}},
- {0x2132, 0x2132, d{0, 28, 0}},
- {0x214E, 0x214E, d{-28, 0, -28}},
- {0x2160, 0x216F, d{0, 16, 0}},
- {0x2170, 0x217F, d{-16, 0, -16}},
- {0x2183, 0x2184, d{UpperLower, UpperLower, UpperLower}},
- {0x24B6, 0x24CF, d{0, 26, 0}},
- {0x24D0, 0x24E9, d{-26, 0, -26}},
- {0x2C00, 0x2C2E, d{0, 48, 0}},
- {0x2C30, 0x2C5E, d{-48, 0, -48}},
- {0x2C60, 0x2C61, d{UpperLower, UpperLower, UpperLower}},
- {0x2C62, 0x2C62, d{0, -10743, 0}},
- {0x2C63, 0x2C63, d{0, -3814, 0}},
- {0x2C64, 0x2C64, d{0, -10727, 0}},
- {0x2C65, 0x2C65, d{-10795, 0, -10795}},
- {0x2C66, 0x2C66, d{-10792, 0, -10792}},
- {0x2C67, 0x2C6C, d{UpperLower, UpperLower, UpperLower}},
- {0x2C6D, 0x2C6D, d{0, -10780, 0}},
- {0x2C6E, 0x2C6E, d{0, -10749, 0}},
- {0x2C6F, 0x2C6F, d{0, -10783, 0}},
- {0x2C70, 0x2C70, d{0, -10782, 0}},
- {0x2C72, 0x2C73, d{UpperLower, UpperLower, UpperLower}},
- {0x2C75, 0x2C76, d{UpperLower, UpperLower, UpperLower}},
- {0x2C7E, 0x2C7F, d{0, -10815, 0}},
- {0x2C80, 0x2CE3, d{UpperLower, UpperLower, UpperLower}},
- {0x2CEB, 0x2CEE, d{UpperLower, UpperLower, UpperLower}},
- {0x2CF2, 0x2CF3, d{UpperLower, UpperLower, UpperLower}},
- {0x2D00, 0x2D25, d{-7264, 0, -7264}},
- {0x2D27, 0x2D27, d{-7264, 0, -7264}},
- {0x2D2D, 0x2D2D, d{-7264, 0, -7264}},
- {0xA640, 0xA66D, d{UpperLower, UpperLower, UpperLower}},
- {0xA680, 0xA69B, d{UpperLower, UpperLower, UpperLower}},
- {0xA722, 0xA72F, d{UpperLower, UpperLower, UpperLower}},
- {0xA732, 0xA76F, d{UpperLower, UpperLower, UpperLower}},
- {0xA779, 0xA77C, d{UpperLower, UpperLower, UpperLower}},
- {0xA77D, 0xA77D, d{0, -35332, 0}},
- {0xA77E, 0xA787, d{UpperLower, UpperLower, UpperLower}},
- {0xA78B, 0xA78C, d{UpperLower, UpperLower, UpperLower}},
- {0xA78D, 0xA78D, d{0, -42280, 0}},
- {0xA790, 0xA793, d{UpperLower, UpperLower, UpperLower}},
- {0xA794, 0xA794, d{48, 0, 48}},
- {0xA796, 0xA7A9, d{UpperLower, UpperLower, UpperLower}},
- {0xA7AA, 0xA7AA, d{0, -42308, 0}},
- {0xA7AB, 0xA7AB, d{0, -42319, 0}},
- {0xA7AC, 0xA7AC, d{0, -42315, 0}},
- {0xA7AD, 0xA7AD, d{0, -42305, 0}},
- {0xA7AE, 0xA7AE, d{0, -42308, 0}},
- {0xA7B0, 0xA7B0, d{0, -42258, 0}},
- {0xA7B1, 0xA7B1, d{0, -42282, 0}},
- {0xA7B2, 0xA7B2, d{0, -42261, 0}},
- {0xA7B3, 0xA7B3, d{0, 928, 0}},
- {0xA7B4, 0xA7BF, d{UpperLower, UpperLower, UpperLower}},
- {0xA7C2, 0xA7C3, d{UpperLower, UpperLower, UpperLower}},
- {0xA7C4, 0xA7C4, d{0, -48, 0}},
- {0xA7C5, 0xA7C5, d{0, -42307, 0}},
- {0xA7C6, 0xA7C6, d{0, -35384, 0}},
- {0xA7C7, 0xA7CA, d{UpperLower, UpperLower, UpperLower}},
- {0xA7F5, 0xA7F6, d{UpperLower, UpperLower, UpperLower}},
- {0xAB53, 0xAB53, d{-928, 0, -928}},
- {0xAB70, 0xABBF, d{-38864, 0, -38864}},
- {0xFF21, 0xFF3A, d{0, 32, 0}},
- {0xFF41, 0xFF5A, d{-32, 0, -32}},
- {0x10400, 0x10427, d{0, 40, 0}},
- {0x10428, 0x1044F, d{-40, 0, -40}},
- {0x104B0, 0x104D3, d{0, 40, 0}},
- {0x104D8, 0x104FB, d{-40, 0, -40}},
- {0x10C80, 0x10CB2, d{0, 64, 0}},
- {0x10CC0, 0x10CF2, d{-64, 0, -64}},
- {0x118A0, 0x118BF, d{0, 32, 0}},
- {0x118C0, 0x118DF, d{-32, 0, -32}},
- {0x16E40, 0x16E5F, d{0, 32, 0}},
- {0x16E60, 0x16E7F, d{-32, 0, -32}},
- {0x1E900, 0x1E921, d{0, 34, 0}},
- {0x1E922, 0x1E943, d{-34, 0, -34}},
-}
-var properties = [MaxLatin1 + 1]uint8{
- 0x00: pC, // '\x00'
- 0x01: pC, // '\x01'
- 0x02: pC, // '\x02'
- 0x03: pC, // '\x03'
- 0x04: pC, // '\x04'
- 0x05: pC, // '\x05'
- 0x06: pC, // '\x06'
- 0x07: pC, // '\a'
- 0x08: pC, // '\b'
- 0x09: pC, // '\t'
- 0x0A: pC, // '\n'
- 0x0B: pC, // '\v'
- 0x0C: pC, // '\f'
- 0x0D: pC, // '\r'
- 0x0E: pC, // '\x0e'
- 0x0F: pC, // '\x0f'
- 0x10: pC, // '\x10'
- 0x11: pC, // '\x11'
- 0x12: pC, // '\x12'
- 0x13: pC, // '\x13'
- 0x14: pC, // '\x14'
- 0x15: pC, // '\x15'
- 0x16: pC, // '\x16'
- 0x17: pC, // '\x17'
- 0x18: pC, // '\x18'
- 0x19: pC, // '\x19'
- 0x1A: pC, // '\x1a'
- 0x1B: pC, // '\x1b'
- 0x1C: pC, // '\x1c'
- 0x1D: pC, // '\x1d'
- 0x1E: pC, // '\x1e'
- 0x1F: pC, // '\x1f'
- 0x20: pZ | pp, // ' '
- 0x21: pP | pp, // '!'
- 0x22: pP | pp, // '"'
- 0x23: pP | pp, // '#'
- 0x24: pS | pp, // '$'
- 0x25: pP | pp, // '%'
- 0x26: pP | pp, // '&'
- 0x27: pP | pp, // '\''
- 0x28: pP | pp, // '('
- 0x29: pP | pp, // ')'
- 0x2A: pP | pp, // '*'
- 0x2B: pS | pp, // '+'
- 0x2C: pP | pp, // ','
- 0x2D: pP | pp, // '-'
- 0x2E: pP | pp, // '.'
- 0x2F: pP | pp, // '/'
- 0x30: pN | pp, // '0'
- 0x31: pN | pp, // '1'
- 0x32: pN | pp, // '2'
- 0x33: pN | pp, // '3'
- 0x34: pN | pp, // '4'
- 0x35: pN | pp, // '5'
- 0x36: pN | pp, // '6'
- 0x37: pN | pp, // '7'
- 0x38: pN | pp, // '8'
- 0x39: pN | pp, // '9'
- 0x3A: pP | pp, // ':'
- 0x3B: pP | pp, // ';'
- 0x3C: pS | pp, // '<'
- 0x3D: pS | pp, // '='
- 0x3E: pS | pp, // '>'
- 0x3F: pP | pp, // '?'
- 0x40: pP | pp, // '@'
- 0x41: pLu | pp, // 'A'
- 0x42: pLu | pp, // 'B'
- 0x43: pLu | pp, // 'C'
- 0x44: pLu | pp, // 'D'
- 0x45: pLu | pp, // 'E'
- 0x46: pLu | pp, // 'F'
- 0x47: pLu | pp, // 'G'
- 0x48: pLu | pp, // 'H'
- 0x49: pLu | pp, // 'I'
- 0x4A: pLu | pp, // 'J'
- 0x4B: pLu | pp, // 'K'
- 0x4C: pLu | pp, // 'L'
- 0x4D: pLu | pp, // 'M'
- 0x4E: pLu | pp, // 'N'
- 0x4F: pLu | pp, // 'O'
- 0x50: pLu | pp, // 'P'
- 0x51: pLu | pp, // 'Q'
- 0x52: pLu | pp, // 'R'
- 0x53: pLu | pp, // 'S'
- 0x54: pLu | pp, // 'T'
- 0x55: pLu | pp, // 'U'
- 0x56: pLu | pp, // 'V'
- 0x57: pLu | pp, // 'W'
- 0x58: pLu | pp, // 'X'
- 0x59: pLu | pp, // 'Y'
- 0x5A: pLu | pp, // 'Z'
- 0x5B: pP | pp, // '['
- 0x5C: pP | pp, // '\\'
- 0x5D: pP | pp, // ']'
- 0x5E: pS | pp, // '^'
- 0x5F: pP | pp, // '_'
- 0x60: pS | pp, // '`'
- 0x61: pLl | pp, // 'a'
- 0x62: pLl | pp, // 'b'
- 0x63: pLl | pp, // 'c'
- 0x64: pLl | pp, // 'd'
- 0x65: pLl | pp, // 'e'
- 0x66: pLl | pp, // 'f'
- 0x67: pLl | pp, // 'g'
- 0x68: pLl | pp, // 'h'
- 0x69: pLl | pp, // 'i'
- 0x6A: pLl | pp, // 'j'
- 0x6B: pLl | pp, // 'k'
- 0x6C: pLl | pp, // 'l'
- 0x6D: pLl | pp, // 'm'
- 0x6E: pLl | pp, // 'n'
- 0x6F: pLl | pp, // 'o'
- 0x70: pLl | pp, // 'p'
- 0x71: pLl | pp, // 'q'
- 0x72: pLl | pp, // 'r'
- 0x73: pLl | pp, // 's'
- 0x74: pLl | pp, // 't'
- 0x75: pLl | pp, // 'u'
- 0x76: pLl | pp, // 'v'
- 0x77: pLl | pp, // 'w'
- 0x78: pLl | pp, // 'x'
- 0x79: pLl | pp, // 'y'
- 0x7A: pLl | pp, // 'z'
- 0x7B: pP | pp, // '{'
- 0x7C: pS | pp, // '|'
- 0x7D: pP | pp, // '}'
- 0x7E: pS | pp, // '~'
- 0x7F: pC, // '\u007f'
- 0x80: pC, // '\u0080'
- 0x81: pC, // '\u0081'
- 0x82: pC, // '\u0082'
- 0x83: pC, // '\u0083'
- 0x84: pC, // '\u0084'
- 0x85: pC, // '\u0085'
- 0x86: pC, // '\u0086'
- 0x87: pC, // '\u0087'
- 0x88: pC, // '\u0088'
- 0x89: pC, // '\u0089'
- 0x8A: pC, // '\u008a'
- 0x8B: pC, // '\u008b'
- 0x8C: pC, // '\u008c'
- 0x8D: pC, // '\u008d'
- 0x8E: pC, // '\u008e'
- 0x8F: pC, // '\u008f'
- 0x90: pC, // '\u0090'
- 0x91: pC, // '\u0091'
- 0x92: pC, // '\u0092'
- 0x93: pC, // '\u0093'
- 0x94: pC, // '\u0094'
- 0x95: pC, // '\u0095'
- 0x96: pC, // '\u0096'
- 0x97: pC, // '\u0097'
- 0x98: pC, // '\u0098'
- 0x99: pC, // '\u0099'
- 0x9A: pC, // '\u009a'
- 0x9B: pC, // '\u009b'
- 0x9C: pC, // '\u009c'
- 0x9D: pC, // '\u009d'
- 0x9E: pC, // '\u009e'
- 0x9F: pC, // '\u009f'
- 0xA0: pZ, // '\u00a0'
- 0xA1: pP | pp, // '¡'
- 0xA2: pS | pp, // '¢'
- 0xA3: pS | pp, // '£'
- 0xA4: pS | pp, // '¤'
- 0xA5: pS | pp, // '¥'
- 0xA6: pS | pp, // '¦'
- 0xA7: pP | pp, // '§'
- 0xA8: pS | pp, // '¨'
- 0xA9: pS | pp, // '©'
- 0xAA: pLo | pp, // 'ª'
- 0xAB: pP | pp, // '«'
- 0xAC: pS | pp, // '¬'
- 0xAD: 0, // '\u00ad'
- 0xAE: pS | pp, // '®'
- 0xAF: pS | pp, // '¯'
- 0xB0: pS | pp, // '°'
- 0xB1: pS | pp, // '±'
- 0xB2: pN | pp, // '²'
- 0xB3: pN | pp, // '³'
- 0xB4: pS | pp, // '´'
- 0xB5: pLl | pp, // 'µ'
- 0xB6: pP | pp, // '¶'
- 0xB7: pP | pp, // '·'
- 0xB8: pS | pp, // '¸'
- 0xB9: pN | pp, // '¹'
- 0xBA: pLo | pp, // 'º'
- 0xBB: pP | pp, // '»'
- 0xBC: pN | pp, // '¼'
- 0xBD: pN | pp, // '½'
- 0xBE: pN | pp, // '¾'
- 0xBF: pP | pp, // '¿'
- 0xC0: pLu | pp, // 'À'
- 0xC1: pLu | pp, // 'Á'
- 0xC2: pLu | pp, // 'Â'
- 0xC3: pLu | pp, // 'Ã'
- 0xC4: pLu | pp, // 'Ä'
- 0xC5: pLu | pp, // 'Å'
- 0xC6: pLu | pp, // 'Æ'
- 0xC7: pLu | pp, // 'Ç'
- 0xC8: pLu | pp, // 'È'
- 0xC9: pLu | pp, // 'É'
- 0xCA: pLu | pp, // 'Ê'
- 0xCB: pLu | pp, // 'Ë'
- 0xCC: pLu | pp, // 'Ì'
- 0xCD: pLu | pp, // 'Í'
- 0xCE: pLu | pp, // 'Î'
- 0xCF: pLu | pp, // 'Ï'
- 0xD0: pLu | pp, // 'Ð'
- 0xD1: pLu | pp, // 'Ñ'
- 0xD2: pLu | pp, // 'Ò'
- 0xD3: pLu | pp, // 'Ó'
- 0xD4: pLu | pp, // 'Ô'
- 0xD5: pLu | pp, // 'Õ'
- 0xD6: pLu | pp, // 'Ö'
- 0xD7: pS | pp, // '×'
- 0xD8: pLu | pp, // 'Ø'
- 0xD9: pLu | pp, // 'Ù'
- 0xDA: pLu | pp, // 'Ú'
- 0xDB: pLu | pp, // 'Û'
- 0xDC: pLu | pp, // 'Ü'
- 0xDD: pLu | pp, // 'Ý'
- 0xDE: pLu | pp, // 'Þ'
- 0xDF: pLl | pp, // 'ß'
- 0xE0: pLl | pp, // 'à'
- 0xE1: pLl | pp, // 'á'
- 0xE2: pLl | pp, // 'â'
- 0xE3: pLl | pp, // 'ã'
- 0xE4: pLl | pp, // 'ä'
- 0xE5: pLl | pp, // 'å'
- 0xE6: pLl | pp, // 'æ'
- 0xE7: pLl | pp, // 'ç'
- 0xE8: pLl | pp, // 'è'
- 0xE9: pLl | pp, // 'é'
- 0xEA: pLl | pp, // 'ê'
- 0xEB: pLl | pp, // 'ë'
- 0xEC: pLl | pp, // 'ì'
- 0xED: pLl | pp, // 'í'
- 0xEE: pLl | pp, // 'î'
- 0xEF: pLl | pp, // 'ï'
- 0xF0: pLl | pp, // 'ð'
- 0xF1: pLl | pp, // 'ñ'
- 0xF2: pLl | pp, // 'ò'
- 0xF3: pLl | pp, // 'ó'
- 0xF4: pLl | pp, // 'ô'
- 0xF5: pLl | pp, // 'õ'
- 0xF6: pLl | pp, // 'ö'
- 0xF7: pS | pp, // '÷'
- 0xF8: pLl | pp, // 'ø'
- 0xF9: pLl | pp, // 'ù'
- 0xFA: pLl | pp, // 'ú'
- 0xFB: pLl | pp, // 'û'
- 0xFC: pLl | pp, // 'ü'
- 0xFD: pLl | pp, // 'ý'
- 0xFE: pLl | pp, // 'þ'
- 0xFF: pLl | pp, // 'ÿ'
-}
-
-var asciiFold = [MaxASCII + 1]uint16{
- 0x0000,
- 0x0001,
- 0x0002,
- 0x0003,
- 0x0004,
- 0x0005,
- 0x0006,
- 0x0007,
- 0x0008,
- 0x0009,
- 0x000A,
- 0x000B,
- 0x000C,
- 0x000D,
- 0x000E,
- 0x000F,
- 0x0010,
- 0x0011,
- 0x0012,
- 0x0013,
- 0x0014,
- 0x0015,
- 0x0016,
- 0x0017,
- 0x0018,
- 0x0019,
- 0x001A,
- 0x001B,
- 0x001C,
- 0x001D,
- 0x001E,
- 0x001F,
- 0x0020,
- 0x0021,
- 0x0022,
- 0x0023,
- 0x0024,
- 0x0025,
- 0x0026,
- 0x0027,
- 0x0028,
- 0x0029,
- 0x002A,
- 0x002B,
- 0x002C,
- 0x002D,
- 0x002E,
- 0x002F,
- 0x0030,
- 0x0031,
- 0x0032,
- 0x0033,
- 0x0034,
- 0x0035,
- 0x0036,
- 0x0037,
- 0x0038,
- 0x0039,
- 0x003A,
- 0x003B,
- 0x003C,
- 0x003D,
- 0x003E,
- 0x003F,
- 0x0040,
- 0x0061,
- 0x0062,
- 0x0063,
- 0x0064,
- 0x0065,
- 0x0066,
- 0x0067,
- 0x0068,
- 0x0069,
- 0x006A,
- 0x006B,
- 0x006C,
- 0x006D,
- 0x006E,
- 0x006F,
- 0x0070,
- 0x0071,
- 0x0072,
- 0x0073,
- 0x0074,
- 0x0075,
- 0x0076,
- 0x0077,
- 0x0078,
- 0x0079,
- 0x007A,
- 0x005B,
- 0x005C,
- 0x005D,
- 0x005E,
- 0x005F,
- 0x0060,
- 0x0041,
- 0x0042,
- 0x0043,
- 0x0044,
- 0x0045,
- 0x0046,
- 0x0047,
- 0x0048,
- 0x0049,
- 0x004A,
- 0x212A,
- 0x004C,
- 0x004D,
- 0x004E,
- 0x004F,
- 0x0050,
- 0x0051,
- 0x0052,
- 0x017F,
- 0x0054,
- 0x0055,
- 0x0056,
- 0x0057,
- 0x0058,
- 0x0059,
- 0x005A,
- 0x007B,
- 0x007C,
- 0x007D,
- 0x007E,
- 0x007F,
-}
-
-var caseOrbit = []foldPair{
- {0x004B, 0x006B},
- {0x0053, 0x0073},
- {0x006B, 0x212A},
- {0x0073, 0x017F},
- {0x00B5, 0x039C},
- {0x00C5, 0x00E5},
- {0x00DF, 0x1E9E},
- {0x00E5, 0x212B},
- {0x0130, 0x0130},
- {0x0131, 0x0131},
- {0x017F, 0x0053},
- {0x01C4, 0x01C5},
- {0x01C5, 0x01C6},
- {0x01C6, 0x01C4},
- {0x01C7, 0x01C8},
- {0x01C8, 0x01C9},
- {0x01C9, 0x01C7},
- {0x01CA, 0x01CB},
- {0x01CB, 0x01CC},
- {0x01CC, 0x01CA},
- {0x01F1, 0x01F2},
- {0x01F2, 0x01F3},
- {0x01F3, 0x01F1},
- {0x0345, 0x0399},
- {0x0392, 0x03B2},
- {0x0395, 0x03B5},
- {0x0398, 0x03B8},
- {0x0399, 0x03B9},
- {0x039A, 0x03BA},
- {0x039C, 0x03BC},
- {0x03A0, 0x03C0},
- {0x03A1, 0x03C1},
- {0x03A3, 0x03C2},
- {0x03A6, 0x03C6},
- {0x03A9, 0x03C9},
- {0x03B2, 0x03D0},
- {0x03B5, 0x03F5},
- {0x03B8, 0x03D1},
- {0x03B9, 0x1FBE},
- {0x03BA, 0x03F0},
- {0x03BC, 0x00B5},
- {0x03C0, 0x03D6},
- {0x03C1, 0x03F1},
- {0x03C2, 0x03C3},
- {0x03C3, 0x03A3},
- {0x03C6, 0x03D5},
- {0x03C9, 0x2126},
- {0x03D0, 0x0392},
- {0x03D1, 0x03F4},
- {0x03D5, 0x03A6},
- {0x03D6, 0x03A0},
- {0x03F0, 0x039A},
- {0x03F1, 0x03A1},
- {0x03F4, 0x0398},
- {0x03F5, 0x0395},
- {0x0412, 0x0432},
- {0x0414, 0x0434},
- {0x041E, 0x043E},
- {0x0421, 0x0441},
- {0x0422, 0x0442},
- {0x042A, 0x044A},
- {0x0432, 0x1C80},
- {0x0434, 0x1C81},
- {0x043E, 0x1C82},
- {0x0441, 0x1C83},
- {0x0442, 0x1C84},
- {0x044A, 0x1C86},
- {0x0462, 0x0463},
- {0x0463, 0x1C87},
- {0x1C80, 0x0412},
- {0x1C81, 0x0414},
- {0x1C82, 0x041E},
- {0x1C83, 0x0421},
- {0x1C84, 0x1C85},
- {0x1C85, 0x0422},
- {0x1C86, 0x042A},
- {0x1C87, 0x0462},
- {0x1C88, 0xA64A},
- {0x1E60, 0x1E61},
- {0x1E61, 0x1E9B},
- {0x1E9B, 0x1E60},
- {0x1E9E, 0x00DF},
- {0x1FBE, 0x0345},
- {0x2126, 0x03A9},
- {0x212A, 0x004B},
- {0x212B, 0x00C5},
- {0xA64A, 0xA64B},
- {0xA64B, 0x1C88},
-}
-
-// FoldCategory maps a category name to a table of
-// code points outside the category that are equivalent under
-// simple case folding to code points inside the category.
-// If there is no entry for a category name, there are no such points.
-var FoldCategory = map[string]*RangeTable{
- "L": foldL,
- "Ll": foldLl,
- "Lt": foldLt,
- "Lu": foldLu,
- "M": foldM,
- "Mn": foldMn,
-}
-
-var foldL = &RangeTable{
- R16: []Range16{
- {0x0345, 0x0345, 1},
- },
-}
-
-var foldLl = &RangeTable{
- R16: []Range16{
- {0x0041, 0x005a, 1},
- {0x00c0, 0x00d6, 1},
- {0x00d8, 0x00de, 1},
- {0x0100, 0x012e, 2},
- {0x0132, 0x0136, 2},
- {0x0139, 0x0147, 2},
- {0x014a, 0x0178, 2},
- {0x0179, 0x017d, 2},
- {0x0181, 0x0182, 1},
- {0x0184, 0x0186, 2},
- {0x0187, 0x0189, 2},
- {0x018a, 0x018b, 1},
- {0x018e, 0x0191, 1},
- {0x0193, 0x0194, 1},
- {0x0196, 0x0198, 1},
- {0x019c, 0x019d, 1},
- {0x019f, 0x01a0, 1},
- {0x01a2, 0x01a6, 2},
- {0x01a7, 0x01a9, 2},
- {0x01ac, 0x01ae, 2},
- {0x01af, 0x01b1, 2},
- {0x01b2, 0x01b3, 1},
- {0x01b5, 0x01b7, 2},
- {0x01b8, 0x01bc, 4},
- {0x01c4, 0x01c5, 1},
- {0x01c7, 0x01c8, 1},
- {0x01ca, 0x01cb, 1},
- {0x01cd, 0x01db, 2},
- {0x01de, 0x01ee, 2},
- {0x01f1, 0x01f2, 1},
- {0x01f4, 0x01f6, 2},
- {0x01f7, 0x01f8, 1},
- {0x01fa, 0x0232, 2},
- {0x023a, 0x023b, 1},
- {0x023d, 0x023e, 1},
- {0x0241, 0x0243, 2},
- {0x0244, 0x0246, 1},
- {0x0248, 0x024e, 2},
- {0x0345, 0x0370, 43},
- {0x0372, 0x0376, 4},
- {0x037f, 0x0386, 7},
- {0x0388, 0x038a, 1},
- {0x038c, 0x038e, 2},
- {0x038f, 0x0391, 2},
- {0x0392, 0x03a1, 1},
- {0x03a3, 0x03ab, 1},
- {0x03cf, 0x03d8, 9},
- {0x03da, 0x03ee, 2},
- {0x03f4, 0x03f7, 3},
- {0x03f9, 0x03fa, 1},
- {0x03fd, 0x042f, 1},
- {0x0460, 0x0480, 2},
- {0x048a, 0x04c0, 2},
- {0x04c1, 0x04cd, 2},
- {0x04d0, 0x052e, 2},
- {0x0531, 0x0556, 1},
- {0x10a0, 0x10c5, 1},
- {0x10c7, 0x10cd, 6},
- {0x13a0, 0x13f5, 1},
- {0x1c90, 0x1cba, 1},
- {0x1cbd, 0x1cbf, 1},
- {0x1e00, 0x1e94, 2},
- {0x1e9e, 0x1efe, 2},
- {0x1f08, 0x1f0f, 1},
- {0x1f18, 0x1f1d, 1},
- {0x1f28, 0x1f2f, 1},
- {0x1f38, 0x1f3f, 1},
- {0x1f48, 0x1f4d, 1},
- {0x1f59, 0x1f5f, 2},
- {0x1f68, 0x1f6f, 1},
- {0x1f88, 0x1f8f, 1},
- {0x1f98, 0x1f9f, 1},
- {0x1fa8, 0x1faf, 1},
- {0x1fb8, 0x1fbc, 1},
- {0x1fc8, 0x1fcc, 1},
- {0x1fd8, 0x1fdb, 1},
- {0x1fe8, 0x1fec, 1},
- {0x1ff8, 0x1ffc, 1},
- {0x2126, 0x212a, 4},
- {0x212b, 0x2132, 7},
- {0x2183, 0x2c00, 2685},
- {0x2c01, 0x2c2e, 1},
- {0x2c60, 0x2c62, 2},
- {0x2c63, 0x2c64, 1},
- {0x2c67, 0x2c6d, 2},
- {0x2c6e, 0x2c70, 1},
- {0x2c72, 0x2c75, 3},
- {0x2c7e, 0x2c80, 1},
- {0x2c82, 0x2ce2, 2},
- {0x2ceb, 0x2ced, 2},
- {0x2cf2, 0xa640, 31054},
- {0xa642, 0xa66c, 2},
- {0xa680, 0xa69a, 2},
- {0xa722, 0xa72e, 2},
- {0xa732, 0xa76e, 2},
- {0xa779, 0xa77d, 2},
- {0xa77e, 0xa786, 2},
- {0xa78b, 0xa78d, 2},
- {0xa790, 0xa792, 2},
- {0xa796, 0xa7aa, 2},
- {0xa7ab, 0xa7ae, 1},
- {0xa7b0, 0xa7b4, 1},
- {0xa7b6, 0xa7be, 2},
- {0xa7c2, 0xa7c4, 2},
- {0xa7c5, 0xa7c7, 1},
- {0xa7c9, 0xa7f5, 44},
- {0xff21, 0xff3a, 1},
- },
- R32: []Range32{
- {0x10400, 0x10427, 1},
- {0x104b0, 0x104d3, 1},
- {0x10c80, 0x10cb2, 1},
- {0x118a0, 0x118bf, 1},
- {0x16e40, 0x16e5f, 1},
- {0x1e900, 0x1e921, 1},
- },
- LatinOffset: 3,
-}
-
-var foldLt = &RangeTable{
- R16: []Range16{
- {0x01c4, 0x01c6, 2},
- {0x01c7, 0x01c9, 2},
- {0x01ca, 0x01cc, 2},
- {0x01f1, 0x01f3, 2},
- {0x1f80, 0x1f87, 1},
- {0x1f90, 0x1f97, 1},
- {0x1fa0, 0x1fa7, 1},
- {0x1fb3, 0x1fc3, 16},
- {0x1ff3, 0x1ff3, 1},
- },
-}
-
-var foldLu = &RangeTable{
- R16: []Range16{
- {0x0061, 0x007a, 1},
- {0x00b5, 0x00df, 42},
- {0x00e0, 0x00f6, 1},
- {0x00f8, 0x00ff, 1},
- {0x0101, 0x012f, 2},
- {0x0133, 0x0137, 2},
- {0x013a, 0x0148, 2},
- {0x014b, 0x0177, 2},
- {0x017a, 0x017e, 2},
- {0x017f, 0x0180, 1},
- {0x0183, 0x0185, 2},
- {0x0188, 0x018c, 4},
- {0x0192, 0x0195, 3},
- {0x0199, 0x019a, 1},
- {0x019e, 0x01a1, 3},
- {0x01a3, 0x01a5, 2},
- {0x01a8, 0x01ad, 5},
- {0x01b0, 0x01b4, 4},
- {0x01b6, 0x01b9, 3},
- {0x01bd, 0x01bf, 2},
- {0x01c5, 0x01c6, 1},
- {0x01c8, 0x01c9, 1},
- {0x01cb, 0x01cc, 1},
- {0x01ce, 0x01dc, 2},
- {0x01dd, 0x01ef, 2},
- {0x01f2, 0x01f3, 1},
- {0x01f5, 0x01f9, 4},
- {0x01fb, 0x021f, 2},
- {0x0223, 0x0233, 2},
- {0x023c, 0x023f, 3},
- {0x0240, 0x0242, 2},
- {0x0247, 0x024f, 2},
- {0x0250, 0x0254, 1},
- {0x0256, 0x0257, 1},
- {0x0259, 0x025b, 2},
- {0x025c, 0x0260, 4},
- {0x0261, 0x0265, 2},
- {0x0266, 0x0268, 2},
- {0x0269, 0x026c, 1},
- {0x026f, 0x0271, 2},
- {0x0272, 0x0275, 3},
- {0x027d, 0x0280, 3},
- {0x0282, 0x0283, 1},
- {0x0287, 0x028c, 1},
- {0x0292, 0x029d, 11},
- {0x029e, 0x0345, 167},
- {0x0371, 0x0373, 2},
- {0x0377, 0x037b, 4},
- {0x037c, 0x037d, 1},
- {0x03ac, 0x03af, 1},
- {0x03b1, 0x03ce, 1},
- {0x03d0, 0x03d1, 1},
- {0x03d5, 0x03d7, 1},
- {0x03d9, 0x03ef, 2},
- {0x03f0, 0x03f3, 1},
- {0x03f5, 0x03fb, 3},
- {0x0430, 0x045f, 1},
- {0x0461, 0x0481, 2},
- {0x048b, 0x04bf, 2},
- {0x04c2, 0x04ce, 2},
- {0x04cf, 0x052f, 2},
- {0x0561, 0x0586, 1},
- {0x10d0, 0x10fa, 1},
- {0x10fd, 0x10ff, 1},
- {0x13f8, 0x13fd, 1},
- {0x1c80, 0x1c88, 1},
- {0x1d79, 0x1d7d, 4},
- {0x1d8e, 0x1e01, 115},
- {0x1e03, 0x1e95, 2},
- {0x1e9b, 0x1ea1, 6},
- {0x1ea3, 0x1eff, 2},
- {0x1f00, 0x1f07, 1},
- {0x1f10, 0x1f15, 1},
- {0x1f20, 0x1f27, 1},
- {0x1f30, 0x1f37, 1},
- {0x1f40, 0x1f45, 1},
- {0x1f51, 0x1f57, 2},
- {0x1f60, 0x1f67, 1},
- {0x1f70, 0x1f7d, 1},
- {0x1fb0, 0x1fb1, 1},
- {0x1fbe, 0x1fd0, 18},
- {0x1fd1, 0x1fe0, 15},
- {0x1fe1, 0x1fe5, 4},
- {0x214e, 0x2184, 54},
- {0x2c30, 0x2c5e, 1},
- {0x2c61, 0x2c65, 4},
- {0x2c66, 0x2c6c, 2},
- {0x2c73, 0x2c76, 3},
- {0x2c81, 0x2ce3, 2},
- {0x2cec, 0x2cee, 2},
- {0x2cf3, 0x2d00, 13},
- {0x2d01, 0x2d25, 1},
- {0x2d27, 0x2d2d, 6},
- {0xa641, 0xa66d, 2},
- {0xa681, 0xa69b, 2},
- {0xa723, 0xa72f, 2},
- {0xa733, 0xa76f, 2},
- {0xa77a, 0xa77c, 2},
- {0xa77f, 0xa787, 2},
- {0xa78c, 0xa791, 5},
- {0xa793, 0xa794, 1},
- {0xa797, 0xa7a9, 2},
- {0xa7b5, 0xa7bf, 2},
- {0xa7c3, 0xa7c8, 5},
- {0xa7ca, 0xa7f6, 44},
- {0xab53, 0xab70, 29},
- {0xab71, 0xabbf, 1},
- {0xff41, 0xff5a, 1},
- },
- R32: []Range32{
- {0x10428, 0x1044f, 1},
- {0x104d8, 0x104fb, 1},
- {0x10cc0, 0x10cf2, 1},
- {0x118c0, 0x118df, 1},
- {0x16e60, 0x16e7f, 1},
- {0x1e922, 0x1e943, 1},
- },
- LatinOffset: 4,
-}
-
-var foldM = &RangeTable{
- R16: []Range16{
- {0x0399, 0x03b9, 32},
- {0x1fbe, 0x1fbe, 1},
- },
-}
-
-var foldMn = &RangeTable{
- R16: []Range16{
- {0x0399, 0x03b9, 32},
- {0x1fbe, 0x1fbe, 1},
- },
-}
-
-// FoldScript maps a script name to a table of
-// code points outside the script that are equivalent under
-// simple case folding to code points inside the script.
-// If there is no entry for a script name, there are no such points.
-var FoldScript = map[string]*RangeTable{
- "Common": foldCommon,
- "Greek": foldGreek,
- "Inherited": foldInherited,
-}
-
-var foldCommon = &RangeTable{
- R16: []Range16{
- {0x039c, 0x03bc, 32},
- },
-}
-
-var foldGreek = &RangeTable{
- R16: []Range16{
- {0x00b5, 0x0345, 656},
- },
-}
-
-var foldInherited = &RangeTable{
- R16: []Range16{
- {0x0399, 0x03b9, 32},
- {0x1fbe, 0x1fbe, 1},
- },
-}
-
-// Range entries: 3499 16-bit, 1820 32-bit, 5319 total.
-// Range bytes: 20994 16-bit, 21840 32-bit, 42834 total.
-
-// Fold orbit bytes: 88 pairs, 352 bytes
diff --git a/contrib/go/_std_1.20/src/unicode/utf16/utf16.go b/contrib/go/_std_1.20/src/unicode/utf16/utf16.go
deleted file mode 100644
index 38d8be6060..0000000000
--- a/contrib/go/_std_1.20/src/unicode/utf16/utf16.go
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2010 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 utf16 implements encoding and decoding of UTF-16 sequences.
-package utf16
-
-// The conditions replacementChar==unicode.ReplacementChar and
-// maxRune==unicode.MaxRune are verified in the tests.
-// Defining them locally avoids this package depending on package unicode.
-
-const (
- replacementChar = '\uFFFD' // Unicode replacement character
- maxRune = '\U0010FFFF' // Maximum valid Unicode code point.
-)
-
-const (
- // 0xd800-0xdc00 encodes the high 10 bits of a pair.
- // 0xdc00-0xe000 encodes the low 10 bits of a pair.
- // the value is those 20 bits plus 0x10000.
- surr1 = 0xd800
- surr2 = 0xdc00
- surr3 = 0xe000
-
- surrSelf = 0x10000
-)
-
-// IsSurrogate reports whether the specified Unicode code point
-// can appear in a surrogate pair.
-func IsSurrogate(r rune) bool {
- return surr1 <= r && r < surr3
-}
-
-// DecodeRune returns the UTF-16 decoding of a surrogate pair.
-// If the pair is not a valid UTF-16 surrogate pair, DecodeRune returns
-// the Unicode replacement code point U+FFFD.
-func DecodeRune(r1, r2 rune) rune {
- if surr1 <= r1 && r1 < surr2 && surr2 <= r2 && r2 < surr3 {
- return (r1-surr1)<<10 | (r2 - surr2) + surrSelf
- }
- return replacementChar
-}
-
-// EncodeRune returns the UTF-16 surrogate pair r1, r2 for the given rune.
-// If the rune is not a valid Unicode code point or does not need encoding,
-// EncodeRune returns U+FFFD, U+FFFD.
-func EncodeRune(r rune) (r1, r2 rune) {
- if r < surrSelf || r > maxRune {
- return replacementChar, replacementChar
- }
- r -= surrSelf
- return surr1 + (r>>10)&0x3ff, surr2 + r&0x3ff
-}
-
-// Encode returns the UTF-16 encoding of the Unicode code point sequence s.
-func Encode(s []rune) []uint16 {
- n := len(s)
- for _, v := range s {
- if v >= surrSelf {
- n++
- }
- }
-
- a := make([]uint16, n)
- n = 0
- for _, v := range s {
- switch {
- case 0 <= v && v < surr1, surr3 <= v && v < surrSelf:
- // normal rune
- a[n] = uint16(v)
- n++
- case surrSelf <= v && v <= maxRune:
- // needs surrogate sequence
- r1, r2 := EncodeRune(v)
- a[n] = uint16(r1)
- a[n+1] = uint16(r2)
- n += 2
- default:
- a[n] = uint16(replacementChar)
- n++
- }
- }
- return a[:n]
-}
-
-// AppendRune appends the UTF-16 encoding of the Unicode code point r
-// to the end of p and returns the extended buffer. If the rune is not
-// a valid Unicode code point, it appends the encoding of U+FFFD.
-func AppendRune(a []uint16, r rune) []uint16 {
- // This function is inlineable for fast handling of ASCII.
- switch {
- case 0 <= r && r < surr1, surr3 <= r && r < surrSelf:
- // normal rune
- return append(a, uint16(r))
- case surrSelf <= r && r <= maxRune:
- // needs surrogate sequence
- r1, r2 := EncodeRune(r)
- return append(a, uint16(r1), uint16(r2))
- }
- return append(a, replacementChar)
-}
-
-// Decode returns the Unicode code point sequence represented
-// by the UTF-16 encoding s.
-func Decode(s []uint16) []rune {
- a := make([]rune, len(s))
- n := 0
- for i := 0; i < len(s); i++ {
- switch r := s[i]; {
- case r < surr1, surr3 <= r:
- // normal rune
- a[n] = rune(r)
- case surr1 <= r && r < surr2 && i+1 < len(s) &&
- surr2 <= s[i+1] && s[i+1] < surr3:
- // valid surrogate sequence
- a[n] = DecodeRune(rune(r), rune(s[i+1]))
- i++
- default:
- // invalid surrogate sequence
- a[n] = replacementChar
- }
- n++
- }
- return a[:n]
-}
diff --git a/contrib/go/_std_1.20/src/unicode/utf16/ya.make b/contrib/go/_std_1.20/src/unicode/utf16/ya.make
deleted file mode 100644
index 3bf0892f7f..0000000000
--- a/contrib/go/_std_1.20/src/unicode/utf16/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- utf16.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/unicode/utf8/ya.make b/contrib/go/_std_1.20/src/unicode/utf8/ya.make
deleted file mode 100644
index 0967482943..0000000000
--- a/contrib/go/_std_1.20/src/unicode/utf8/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- utf8.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/unicode/ya.make b/contrib/go/_std_1.20/src/unicode/ya.make
deleted file mode 100644
index a0c70be3fb..0000000000
--- a/contrib/go/_std_1.20/src/unicode/ya.make
+++ /dev/null
@@ -1,16 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- casetables.go
- digit.go
- graphic.go
- letter.go
- tables.go
-)
-
-END()
-
-RECURSE(
- utf16
- utf8
-)
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/ya.make b/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/ya.make
deleted file mode 100644
index dac47b133b..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/ya.make
+++ /dev/null
@@ -1,21 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- chacha_generic.go
- xor.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- chacha_arm64.go
- chacha_arm64.s
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- chacha_noasm.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/ya.make b/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/ya.make
deleted file mode 100644
index 2d6852407d..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/ya.make
+++ /dev/null
@@ -1,22 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- chacha20poly1305.go
- chacha20poly1305_generic.go
- xchacha20poly1305.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- chacha20poly1305_noasm.go
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- chacha20poly1305_amd64.go
- chacha20poly1305_amd64.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go b/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go
deleted file mode 100644
index 401414dde2..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go
+++ /dev/null
@@ -1,816 +0,0 @@
-// Copyright 2017 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 cryptobyte
-
-import (
- encoding_asn1 "encoding/asn1"
- "fmt"
- "math/big"
- "reflect"
- "time"
-
- "golang.org/x/crypto/cryptobyte/asn1"
-)
-
-// This file contains ASN.1-related methods for String and Builder.
-
-// Builder
-
-// AddASN1Int64 appends a DER-encoded ASN.1 INTEGER.
-func (b *Builder) AddASN1Int64(v int64) {
- b.addASN1Signed(asn1.INTEGER, v)
-}
-
-// AddASN1Int64WithTag appends a DER-encoded ASN.1 INTEGER with the
-// given tag.
-func (b *Builder) AddASN1Int64WithTag(v int64, tag asn1.Tag) {
- b.addASN1Signed(tag, v)
-}
-
-// AddASN1Enum appends a DER-encoded ASN.1 ENUMERATION.
-func (b *Builder) AddASN1Enum(v int64) {
- b.addASN1Signed(asn1.ENUM, v)
-}
-
-func (b *Builder) addASN1Signed(tag asn1.Tag, v int64) {
- b.AddASN1(tag, func(c *Builder) {
- length := 1
- for i := v; i >= 0x80 || i < -0x80; i >>= 8 {
- length++
- }
-
- for ; length > 0; length-- {
- i := v >> uint((length-1)*8) & 0xff
- c.AddUint8(uint8(i))
- }
- })
-}
-
-// AddASN1Uint64 appends a DER-encoded ASN.1 INTEGER.
-func (b *Builder) AddASN1Uint64(v uint64) {
- b.AddASN1(asn1.INTEGER, func(c *Builder) {
- length := 1
- for i := v; i >= 0x80; i >>= 8 {
- length++
- }
-
- for ; length > 0; length-- {
- i := v >> uint((length-1)*8) & 0xff
- c.AddUint8(uint8(i))
- }
- })
-}
-
-// AddASN1BigInt appends a DER-encoded ASN.1 INTEGER.
-func (b *Builder) AddASN1BigInt(n *big.Int) {
- if b.err != nil {
- return
- }
-
- b.AddASN1(asn1.INTEGER, func(c *Builder) {
- if n.Sign() < 0 {
- // A negative number has to be converted to two's-complement form. So we
- // invert and subtract 1. If the most-significant-bit isn't set then
- // we'll need to pad the beginning with 0xff in order to keep the number
- // negative.
- nMinus1 := new(big.Int).Neg(n)
- nMinus1.Sub(nMinus1, bigOne)
- bytes := nMinus1.Bytes()
- for i := range bytes {
- bytes[i] ^= 0xff
- }
- if len(bytes) == 0 || bytes[0]&0x80 == 0 {
- c.add(0xff)
- }
- c.add(bytes...)
- } else if n.Sign() == 0 {
- c.add(0)
- } else {
- bytes := n.Bytes()
- if bytes[0]&0x80 != 0 {
- c.add(0)
- }
- c.add(bytes...)
- }
- })
-}
-
-// AddASN1OctetString appends a DER-encoded ASN.1 OCTET STRING.
-func (b *Builder) AddASN1OctetString(bytes []byte) {
- b.AddASN1(asn1.OCTET_STRING, func(c *Builder) {
- c.AddBytes(bytes)
- })
-}
-
-const generalizedTimeFormatStr = "20060102150405Z0700"
-
-// AddASN1GeneralizedTime appends a DER-encoded ASN.1 GENERALIZEDTIME.
-func (b *Builder) AddASN1GeneralizedTime(t time.Time) {
- if t.Year() < 0 || t.Year() > 9999 {
- b.err = fmt.Errorf("cryptobyte: cannot represent %v as a GeneralizedTime", t)
- return
- }
- b.AddASN1(asn1.GeneralizedTime, func(c *Builder) {
- c.AddBytes([]byte(t.Format(generalizedTimeFormatStr)))
- })
-}
-
-// AddASN1UTCTime appends a DER-encoded ASN.1 UTCTime.
-func (b *Builder) AddASN1UTCTime(t time.Time) {
- b.AddASN1(asn1.UTCTime, func(c *Builder) {
- // As utilized by the X.509 profile, UTCTime can only
- // represent the years 1950 through 2049.
- if t.Year() < 1950 || t.Year() >= 2050 {
- b.err = fmt.Errorf("cryptobyte: cannot represent %v as a UTCTime", t)
- return
- }
- c.AddBytes([]byte(t.Format(defaultUTCTimeFormatStr)))
- })
-}
-
-// AddASN1BitString appends a DER-encoded ASN.1 BIT STRING. This does not
-// support BIT STRINGs that are not a whole number of bytes.
-func (b *Builder) AddASN1BitString(data []byte) {
- b.AddASN1(asn1.BIT_STRING, func(b *Builder) {
- b.AddUint8(0)
- b.AddBytes(data)
- })
-}
-
-func (b *Builder) addBase128Int(n int64) {
- var length int
- if n == 0 {
- length = 1
- } else {
- for i := n; i > 0; i >>= 7 {
- length++
- }
- }
-
- for i := length - 1; i >= 0; i-- {
- o := byte(n >> uint(i*7))
- o &= 0x7f
- if i != 0 {
- o |= 0x80
- }
-
- b.add(o)
- }
-}
-
-func isValidOID(oid encoding_asn1.ObjectIdentifier) bool {
- if len(oid) < 2 {
- return false
- }
-
- if oid[0] > 2 || (oid[0] <= 1 && oid[1] >= 40) {
- return false
- }
-
- for _, v := range oid {
- if v < 0 {
- return false
- }
- }
-
- return true
-}
-
-func (b *Builder) AddASN1ObjectIdentifier(oid encoding_asn1.ObjectIdentifier) {
- b.AddASN1(asn1.OBJECT_IDENTIFIER, func(b *Builder) {
- if !isValidOID(oid) {
- b.err = fmt.Errorf("cryptobyte: invalid OID: %v", oid)
- return
- }
-
- b.addBase128Int(int64(oid[0])*40 + int64(oid[1]))
- for _, v := range oid[2:] {
- b.addBase128Int(int64(v))
- }
- })
-}
-
-func (b *Builder) AddASN1Boolean(v bool) {
- b.AddASN1(asn1.BOOLEAN, func(b *Builder) {
- if v {
- b.AddUint8(0xff)
- } else {
- b.AddUint8(0)
- }
- })
-}
-
-func (b *Builder) AddASN1NULL() {
- b.add(uint8(asn1.NULL), 0)
-}
-
-// MarshalASN1 calls encoding_asn1.Marshal on its input and appends the result if
-// successful or records an error if one occurred.
-func (b *Builder) MarshalASN1(v interface{}) {
- // NOTE(martinkr): This is somewhat of a hack to allow propagation of
- // encoding_asn1.Marshal errors into Builder.err. N.B. if you call MarshalASN1 with a
- // value embedded into a struct, its tag information is lost.
- if b.err != nil {
- return
- }
- bytes, err := encoding_asn1.Marshal(v)
- if err != nil {
- b.err = err
- return
- }
- b.AddBytes(bytes)
-}
-
-// AddASN1 appends an ASN.1 object. The object is prefixed with the given tag.
-// Tags greater than 30 are not supported and result in an error (i.e.
-// low-tag-number form only). The child builder passed to the
-// BuilderContinuation can be used to build the content of the ASN.1 object.
-func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) {
- if b.err != nil {
- return
- }
- // Identifiers with the low five bits set indicate high-tag-number format
- // (two or more octets), which we don't support.
- if tag&0x1f == 0x1f {
- b.err = fmt.Errorf("cryptobyte: high-tag number identifier octects not supported: 0x%x", tag)
- return
- }
- b.AddUint8(uint8(tag))
- b.addLengthPrefixed(1, true, f)
-}
-
-// String
-
-// ReadASN1Boolean decodes an ASN.1 BOOLEAN and converts it to a boolean
-// representation into out and advances. It reports whether the read
-// was successful.
-func (s *String) ReadASN1Boolean(out *bool) bool {
- var bytes String
- if !s.ReadASN1(&bytes, asn1.BOOLEAN) || len(bytes) != 1 {
- return false
- }
-
- switch bytes[0] {
- case 0:
- *out = false
- case 0xff:
- *out = true
- default:
- return false
- }
-
- return true
-}
-
-// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does
-// not point to an integer, to a big.Int, or to a []byte it panics. Only
-// positive and zero values can be decoded into []byte, and they are returned as
-// big-endian binary values that share memory with s. Positive values will have
-// no leading zeroes, and zero will be returned as a single zero byte.
-// ReadASN1Integer reports whether the read was successful.
-func (s *String) ReadASN1Integer(out interface{}) bool {
- switch out := out.(type) {
- case *int, *int8, *int16, *int32, *int64:
- var i int64
- if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) {
- return false
- }
- reflect.ValueOf(out).Elem().SetInt(i)
- return true
- case *uint, *uint8, *uint16, *uint32, *uint64:
- var u uint64
- if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) {
- return false
- }
- reflect.ValueOf(out).Elem().SetUint(u)
- return true
- case *big.Int:
- return s.readASN1BigInt(out)
- case *[]byte:
- return s.readASN1Bytes(out)
- default:
- panic("out does not point to an integer type")
- }
-}
-
-func checkASN1Integer(bytes []byte) bool {
- if len(bytes) == 0 {
- // An INTEGER is encoded with at least one octet.
- return false
- }
- if len(bytes) == 1 {
- return true
- }
- if bytes[0] == 0 && bytes[1]&0x80 == 0 || bytes[0] == 0xff && bytes[1]&0x80 == 0x80 {
- // Value is not minimally encoded.
- return false
- }
- return true
-}
-
-var bigOne = big.NewInt(1)
-
-func (s *String) readASN1BigInt(out *big.Int) bool {
- var bytes String
- if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) {
- return false
- }
- if bytes[0]&0x80 == 0x80 {
- // Negative number.
- neg := make([]byte, len(bytes))
- for i, b := range bytes {
- neg[i] = ^b
- }
- out.SetBytes(neg)
- out.Add(out, bigOne)
- out.Neg(out)
- } else {
- out.SetBytes(bytes)
- }
- return true
-}
-
-func (s *String) readASN1Bytes(out *[]byte) bool {
- var bytes String
- if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) {
- return false
- }
- if bytes[0]&0x80 == 0x80 {
- return false
- }
- for len(bytes) > 1 && bytes[0] == 0 {
- bytes = bytes[1:]
- }
- *out = bytes
- return true
-}
-
-func (s *String) readASN1Int64(out *int64) bool {
- var bytes String
- if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) {
- return false
- }
- return true
-}
-
-func asn1Signed(out *int64, n []byte) bool {
- length := len(n)
- if length > 8 {
- return false
- }
- for i := 0; i < length; i++ {
- *out <<= 8
- *out |= int64(n[i])
- }
- // Shift up and down in order to sign extend the result.
- *out <<= 64 - uint8(length)*8
- *out >>= 64 - uint8(length)*8
- return true
-}
-
-func (s *String) readASN1Uint64(out *uint64) bool {
- var bytes String
- if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Unsigned(out, bytes) {
- return false
- }
- return true
-}
-
-func asn1Unsigned(out *uint64, n []byte) bool {
- length := len(n)
- if length > 9 || length == 9 && n[0] != 0 {
- // Too large for uint64.
- return false
- }
- if n[0]&0x80 != 0 {
- // Negative number.
- return false
- }
- for i := 0; i < length; i++ {
- *out <<= 8
- *out |= uint64(n[i])
- }
- return true
-}
-
-// ReadASN1Int64WithTag decodes an ASN.1 INTEGER with the given tag into out
-// and advances. It reports whether the read was successful and resulted in a
-// value that can be represented in an int64.
-func (s *String) ReadASN1Int64WithTag(out *int64, tag asn1.Tag) bool {
- var bytes String
- return s.ReadASN1(&bytes, tag) && checkASN1Integer(bytes) && asn1Signed(out, bytes)
-}
-
-// ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It reports
-// whether the read was successful.
-func (s *String) ReadASN1Enum(out *int) bool {
- var bytes String
- var i int64
- if !s.ReadASN1(&bytes, asn1.ENUM) || !checkASN1Integer(bytes) || !asn1Signed(&i, bytes) {
- return false
- }
- if int64(int(i)) != i {
- return false
- }
- *out = int(i)
- return true
-}
-
-func (s *String) readBase128Int(out *int) bool {
- ret := 0
- for i := 0; len(*s) > 0; i++ {
- if i == 5 {
- return false
- }
- // Avoid overflowing int on a 32-bit platform.
- // We don't want different behavior based on the architecture.
- if ret >= 1<<(31-7) {
- return false
- }
- ret <<= 7
- b := s.read(1)[0]
- ret |= int(b & 0x7f)
- if b&0x80 == 0 {
- *out = ret
- return true
- }
- }
- return false // truncated
-}
-
-// ReadASN1ObjectIdentifier decodes an ASN.1 OBJECT IDENTIFIER into out and
-// advances. It reports whether the read was successful.
-func (s *String) ReadASN1ObjectIdentifier(out *encoding_asn1.ObjectIdentifier) bool {
- var bytes String
- if !s.ReadASN1(&bytes, asn1.OBJECT_IDENTIFIER) || len(bytes) == 0 {
- return false
- }
-
- // In the worst case, we get two elements from the first byte (which is
- // encoded differently) and then every varint is a single byte long.
- components := make([]int, len(bytes)+1)
-
- // The first varint is 40*value1 + value2:
- // According to this packing, value1 can take the values 0, 1 and 2 only.
- // When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2,
- // then there are no restrictions on value2.
- var v int
- if !bytes.readBase128Int(&v) {
- return false
- }
- if v < 80 {
- components[0] = v / 40
- components[1] = v % 40
- } else {
- components[0] = 2
- components[1] = v - 80
- }
-
- i := 2
- for ; len(bytes) > 0; i++ {
- if !bytes.readBase128Int(&v) {
- return false
- }
- components[i] = v
- }
- *out = components[:i]
- return true
-}
-
-// ReadASN1GeneralizedTime decodes an ASN.1 GENERALIZEDTIME into out and
-// advances. It reports whether the read was successful.
-func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
- var bytes String
- if !s.ReadASN1(&bytes, asn1.GeneralizedTime) {
- return false
- }
- t := string(bytes)
- res, err := time.Parse(generalizedTimeFormatStr, t)
- if err != nil {
- return false
- }
- if serialized := res.Format(generalizedTimeFormatStr); serialized != t {
- return false
- }
- *out = res
- return true
-}
-
-const defaultUTCTimeFormatStr = "060102150405Z0700"
-
-// ReadASN1UTCTime decodes an ASN.1 UTCTime into out and advances.
-// It reports whether the read was successful.
-func (s *String) ReadASN1UTCTime(out *time.Time) bool {
- var bytes String
- if !s.ReadASN1(&bytes, asn1.UTCTime) {
- return false
- }
- t := string(bytes)
-
- formatStr := defaultUTCTimeFormatStr
- var err error
- res, err := time.Parse(formatStr, t)
- if err != nil {
- // Fallback to minute precision if we can't parse second
- // precision. If we are following X.509 or X.690 we shouldn't
- // support this, but we do.
- formatStr = "0601021504Z0700"
- res, err = time.Parse(formatStr, t)
- }
- if err != nil {
- return false
- }
-
- if serialized := res.Format(formatStr); serialized != t {
- return false
- }
-
- if res.Year() >= 2050 {
- // UTCTime interprets the low order digits 50-99 as 1950-99.
- // This only applies to its use in the X.509 profile.
- // See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
- res = res.AddDate(-100, 0, 0)
- }
- *out = res
- return true
-}
-
-// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances.
-// It reports whether the read was successful.
-func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
- var bytes String
- if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 ||
- len(bytes)*8/8 != len(bytes) {
- return false
- }
-
- paddingBits := bytes[0]
- bytes = bytes[1:]
- if paddingBits > 7 ||
- len(bytes) == 0 && paddingBits != 0 ||
- len(bytes) > 0 && bytes[len(bytes)-1]&(1<<paddingBits-1) != 0 {
- return false
- }
-
- out.BitLength = len(bytes)*8 - int(paddingBits)
- out.Bytes = bytes
- return true
-}
-
-// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances. It is
-// an error if the BIT STRING is not a whole number of bytes. It reports
-// whether the read was successful.
-func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
- var bytes String
- if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 {
- return false
- }
-
- paddingBits := bytes[0]
- if paddingBits != 0 {
- return false
- }
- *out = bytes[1:]
- return true
-}
-
-// ReadASN1Bytes reads the contents of a DER-encoded ASN.1 element (not including
-// tag and length bytes) into out, and advances. The element must match the
-// given tag. It reports whether the read was successful.
-func (s *String) ReadASN1Bytes(out *[]byte, tag asn1.Tag) bool {
- return s.ReadASN1((*String)(out), tag)
-}
-
-// ReadASN1 reads the contents of a DER-encoded ASN.1 element (not including
-// tag and length bytes) into out, and advances. The element must match the
-// given tag. It reports whether the read was successful.
-//
-// Tags greater than 30 are not supported (i.e. low-tag-number format only).
-func (s *String) ReadASN1(out *String, tag asn1.Tag) bool {
- var t asn1.Tag
- if !s.ReadAnyASN1(out, &t) || t != tag {
- return false
- }
- return true
-}
-
-// ReadASN1Element reads the contents of a DER-encoded ASN.1 element (including
-// tag and length bytes) into out, and advances. The element must match the
-// given tag. It reports whether the read was successful.
-//
-// Tags greater than 30 are not supported (i.e. low-tag-number format only).
-func (s *String) ReadASN1Element(out *String, tag asn1.Tag) bool {
- var t asn1.Tag
- if !s.ReadAnyASN1Element(out, &t) || t != tag {
- return false
- }
- return true
-}
-
-// ReadAnyASN1 reads the contents of a DER-encoded ASN.1 element (not including
-// tag and length bytes) into out, sets outTag to its tag, and advances.
-// It reports whether the read was successful.
-//
-// Tags greater than 30 are not supported (i.e. low-tag-number format only).
-func (s *String) ReadAnyASN1(out *String, outTag *asn1.Tag) bool {
- return s.readASN1(out, outTag, true /* skip header */)
-}
-
-// ReadAnyASN1Element reads the contents of a DER-encoded ASN.1 element
-// (including tag and length bytes) into out, sets outTag to is tag, and
-// advances. It reports whether the read was successful.
-//
-// Tags greater than 30 are not supported (i.e. low-tag-number format only).
-func (s *String) ReadAnyASN1Element(out *String, outTag *asn1.Tag) bool {
- return s.readASN1(out, outTag, false /* include header */)
-}
-
-// PeekASN1Tag reports whether the next ASN.1 value on the string starts with
-// the given tag.
-func (s String) PeekASN1Tag(tag asn1.Tag) bool {
- if len(s) == 0 {
- return false
- }
- return asn1.Tag(s[0]) == tag
-}
-
-// SkipASN1 reads and discards an ASN.1 element with the given tag. It
-// reports whether the operation was successful.
-func (s *String) SkipASN1(tag asn1.Tag) bool {
- var unused String
- return s.ReadASN1(&unused, tag)
-}
-
-// ReadOptionalASN1 attempts to read the contents of a DER-encoded ASN.1
-// element (not including tag and length bytes) tagged with the given tag into
-// out. It stores whether an element with the tag was found in outPresent,
-// unless outPresent is nil. It reports whether the read was successful.
-func (s *String) ReadOptionalASN1(out *String, outPresent *bool, tag asn1.Tag) bool {
- present := s.PeekASN1Tag(tag)
- if outPresent != nil {
- *outPresent = present
- }
- if present && !s.ReadASN1(out, tag) {
- return false
- }
- return true
-}
-
-// SkipOptionalASN1 advances s over an ASN.1 element with the given tag, or
-// else leaves s unchanged. It reports whether the operation was successful.
-func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
- if !s.PeekASN1Tag(tag) {
- return true
- }
- var unused String
- return s.ReadASN1(&unused, tag)
-}
-
-// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER explicitly
-// tagged with tag into out and advances. If no element with a matching tag is
-// present, it writes defaultValue into out instead. Otherwise, it behaves like
-// ReadASN1Integer.
-func (s *String) ReadOptionalASN1Integer(out interface{}, tag asn1.Tag, defaultValue interface{}) bool {
- var present bool
- var i String
- if !s.ReadOptionalASN1(&i, &present, tag) {
- return false
- }
- if !present {
- switch out.(type) {
- case *int, *int8, *int16, *int32, *int64,
- *uint, *uint8, *uint16, *uint32, *uint64, *[]byte:
- reflect.ValueOf(out).Elem().Set(reflect.ValueOf(defaultValue))
- case *big.Int:
- if defaultValue, ok := defaultValue.(*big.Int); ok {
- out.(*big.Int).Set(defaultValue)
- } else {
- panic("out points to big.Int, but defaultValue does not")
- }
- default:
- panic("invalid integer type")
- }
- return true
- }
- if !i.ReadASN1Integer(out) || !i.Empty() {
- return false
- }
- return true
-}
-
-// ReadOptionalASN1OctetString attempts to read an optional ASN.1 OCTET STRING
-// explicitly tagged with tag into out and advances. If no element with a
-// matching tag is present, it sets "out" to nil instead. It reports
-// whether the read was successful.
-func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag asn1.Tag) bool {
- var present bool
- var child String
- if !s.ReadOptionalASN1(&child, &present, tag) {
- return false
- }
- if outPresent != nil {
- *outPresent = present
- }
- if present {
- var oct String
- if !child.ReadASN1(&oct, asn1.OCTET_STRING) || !child.Empty() {
- return false
- }
- *out = oct
- } else {
- *out = nil
- }
- return true
-}
-
-// ReadOptionalASN1Boolean sets *out to the value of the next ASN.1 BOOLEAN or,
-// if the next bytes are not an ASN.1 BOOLEAN, to the value of defaultValue.
-// It reports whether the operation was successful.
-func (s *String) ReadOptionalASN1Boolean(out *bool, defaultValue bool) bool {
- var present bool
- var child String
- if !s.ReadOptionalASN1(&child, &present, asn1.BOOLEAN) {
- return false
- }
-
- if !present {
- *out = defaultValue
- return true
- }
-
- return s.ReadASN1Boolean(out)
-}
-
-func (s *String) readASN1(out *String, outTag *asn1.Tag, skipHeader bool) bool {
- if len(*s) < 2 {
- return false
- }
- tag, lenByte := (*s)[0], (*s)[1]
-
- if tag&0x1f == 0x1f {
- // ITU-T X.690 section 8.1.2
- //
- // An identifier octet with a tag part of 0x1f indicates a high-tag-number
- // form identifier with two or more octets. We only support tags less than
- // 31 (i.e. low-tag-number form, single octet identifier).
- return false
- }
-
- if outTag != nil {
- *outTag = asn1.Tag(tag)
- }
-
- // ITU-T X.690 section 8.1.3
- //
- // Bit 8 of the first length byte indicates whether the length is short- or
- // long-form.
- var length, headerLen uint32 // length includes headerLen
- if lenByte&0x80 == 0 {
- // Short-form length (section 8.1.3.4), encoded in bits 1-7.
- length = uint32(lenByte) + 2
- headerLen = 2
- } else {
- // Long-form length (section 8.1.3.5). Bits 1-7 encode the number of octets
- // used to encode the length.
- lenLen := lenByte & 0x7f
- var len32 uint32
-
- if lenLen == 0 || lenLen > 4 || len(*s) < int(2+lenLen) {
- return false
- }
-
- lenBytes := String((*s)[2 : 2+lenLen])
- if !lenBytes.readUnsigned(&len32, int(lenLen)) {
- return false
- }
-
- // ITU-T X.690 section 10.1 (DER length forms) requires encoding the length
- // with the minimum number of octets.
- if len32 < 128 {
- // Length should have used short-form encoding.
- return false
- }
- if len32>>((lenLen-1)*8) == 0 {
- // Leading octet is 0. Length should have been at least one byte shorter.
- return false
- }
-
- headerLen = 2 + uint32(lenLen)
- if headerLen+len32 < len32 {
- // Overflow.
- return false
- }
- length = headerLen + len32
- }
-
- if int(length) < 0 || !s.ReadBytes((*[]byte)(out), int(length)) {
- return false
- }
- if skipHeader && !out.Skip(int(headerLen)) {
- panic("cryptobyte: internal error")
- }
-
- return true
-}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/builder.go b/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/builder.go
deleted file mode 100644
index 2a90c592d7..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/builder.go
+++ /dev/null
@@ -1,342 +0,0 @@
-// Copyright 2017 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 cryptobyte
-
-import (
- "errors"
- "fmt"
-)
-
-// A Builder builds byte strings from fixed-length and length-prefixed values.
-// Builders either allocate space as needed, or are ‘fixed’, which means that
-// they write into a given buffer and produce an error if it's exhausted.
-//
-// The zero value is a usable Builder that allocates space as needed.
-//
-// Simple values are marshaled and appended to a Builder using methods on the
-// Builder. Length-prefixed values are marshaled by providing a
-// BuilderContinuation, which is a function that writes the inner contents of
-// the value to a given Builder. See the documentation for BuilderContinuation
-// for details.
-type Builder struct {
- err error
- result []byte
- fixedSize bool
- child *Builder
- offset int
- pendingLenLen int
- pendingIsASN1 bool
- inContinuation *bool
-}
-
-// NewBuilder creates a Builder that appends its output to the given buffer.
-// Like append(), the slice will be reallocated if its capacity is exceeded.
-// Use Bytes to get the final buffer.
-func NewBuilder(buffer []byte) *Builder {
- return &Builder{
- result: buffer,
- }
-}
-
-// NewFixedBuilder creates a Builder that appends its output into the given
-// buffer. This builder does not reallocate the output buffer. Writes that
-// would exceed the buffer's capacity are treated as an error.
-func NewFixedBuilder(buffer []byte) *Builder {
- return &Builder{
- result: buffer,
- fixedSize: true,
- }
-}
-
-// SetError sets the value to be returned as the error from Bytes. Writes
-// performed after calling SetError are ignored.
-func (b *Builder) SetError(err error) {
- b.err = err
-}
-
-// Bytes returns the bytes written by the builder or an error if one has
-// occurred during building.
-func (b *Builder) Bytes() ([]byte, error) {
- if b.err != nil {
- return nil, b.err
- }
- return b.result[b.offset:], nil
-}
-
-// BytesOrPanic returns the bytes written by the builder or panics if an error
-// has occurred during building.
-func (b *Builder) BytesOrPanic() []byte {
- if b.err != nil {
- panic(b.err)
- }
- return b.result[b.offset:]
-}
-
-// AddUint8 appends an 8-bit value to the byte string.
-func (b *Builder) AddUint8(v uint8) {
- b.add(byte(v))
-}
-
-// AddUint16 appends a big-endian, 16-bit value to the byte string.
-func (b *Builder) AddUint16(v uint16) {
- b.add(byte(v>>8), byte(v))
-}
-
-// AddUint24 appends a big-endian, 24-bit value to the byte string. The highest
-// byte of the 32-bit input value is silently truncated.
-func (b *Builder) AddUint24(v uint32) {
- b.add(byte(v>>16), byte(v>>8), byte(v))
-}
-
-// AddUint32 appends a big-endian, 32-bit value to the byte string.
-func (b *Builder) AddUint32(v uint32) {
- b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
-}
-
-// AddUint64 appends a big-endian, 64-bit value to the byte string.
-func (b *Builder) AddUint64(v uint64) {
- b.add(byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
-}
-
-// AddBytes appends a sequence of bytes to the byte string.
-func (b *Builder) AddBytes(v []byte) {
- b.add(v...)
-}
-
-// BuilderContinuation is a continuation-passing interface for building
-// length-prefixed byte sequences. Builder methods for length-prefixed
-// sequences (AddUint8LengthPrefixed etc) will invoke the BuilderContinuation
-// supplied to them. The child builder passed to the continuation can be used
-// to build the content of the length-prefixed sequence. For example:
-//
-// parent := cryptobyte.NewBuilder()
-// parent.AddUint8LengthPrefixed(func (child *Builder) {
-// child.AddUint8(42)
-// child.AddUint8LengthPrefixed(func (grandchild *Builder) {
-// grandchild.AddUint8(5)
-// })
-// })
-//
-// It is an error to write more bytes to the child than allowed by the reserved
-// length prefix. After the continuation returns, the child must be considered
-// invalid, i.e. users must not store any copies or references of the child
-// that outlive the continuation.
-//
-// If the continuation panics with a value of type BuildError then the inner
-// error will be returned as the error from Bytes. If the child panics
-// otherwise then Bytes will repanic with the same value.
-type BuilderContinuation func(child *Builder)
-
-// BuildError wraps an error. If a BuilderContinuation panics with this value,
-// the panic will be recovered and the inner error will be returned from
-// Builder.Bytes.
-type BuildError struct {
- Err error
-}
-
-// AddUint8LengthPrefixed adds a 8-bit length-prefixed byte sequence.
-func (b *Builder) AddUint8LengthPrefixed(f BuilderContinuation) {
- b.addLengthPrefixed(1, false, f)
-}
-
-// AddUint16LengthPrefixed adds a big-endian, 16-bit length-prefixed byte sequence.
-func (b *Builder) AddUint16LengthPrefixed(f BuilderContinuation) {
- b.addLengthPrefixed(2, false, f)
-}
-
-// AddUint24LengthPrefixed adds a big-endian, 24-bit length-prefixed byte sequence.
-func (b *Builder) AddUint24LengthPrefixed(f BuilderContinuation) {
- b.addLengthPrefixed(3, false, f)
-}
-
-// AddUint32LengthPrefixed adds a big-endian, 32-bit length-prefixed byte sequence.
-func (b *Builder) AddUint32LengthPrefixed(f BuilderContinuation) {
- b.addLengthPrefixed(4, false, f)
-}
-
-func (b *Builder) callContinuation(f BuilderContinuation, arg *Builder) {
- if !*b.inContinuation {
- *b.inContinuation = true
-
- defer func() {
- *b.inContinuation = false
-
- r := recover()
- if r == nil {
- return
- }
-
- if buildError, ok := r.(BuildError); ok {
- b.err = buildError.Err
- } else {
- panic(r)
- }
- }()
- }
-
- f(arg)
-}
-
-func (b *Builder) addLengthPrefixed(lenLen int, isASN1 bool, f BuilderContinuation) {
- // Subsequent writes can be ignored if the builder has encountered an error.
- if b.err != nil {
- return
- }
-
- offset := len(b.result)
- b.add(make([]byte, lenLen)...)
-
- if b.inContinuation == nil {
- b.inContinuation = new(bool)
- }
-
- b.child = &Builder{
- result: b.result,
- fixedSize: b.fixedSize,
- offset: offset,
- pendingLenLen: lenLen,
- pendingIsASN1: isASN1,
- inContinuation: b.inContinuation,
- }
-
- b.callContinuation(f, b.child)
- b.flushChild()
- if b.child != nil {
- panic("cryptobyte: internal error")
- }
-}
-
-func (b *Builder) flushChild() {
- if b.child == nil {
- return
- }
- b.child.flushChild()
- child := b.child
- b.child = nil
-
- if child.err != nil {
- b.err = child.err
- return
- }
-
- length := len(child.result) - child.pendingLenLen - child.offset
-
- if length < 0 {
- panic("cryptobyte: internal error") // result unexpectedly shrunk
- }
-
- if child.pendingIsASN1 {
- // For ASN.1, we reserved a single byte for the length. If that turned out
- // to be incorrect, we have to move the contents along in order to make
- // space.
- if child.pendingLenLen != 1 {
- panic("cryptobyte: internal error")
- }
- var lenLen, lenByte uint8
- if int64(length) > 0xfffffffe {
- b.err = errors.New("pending ASN.1 child too long")
- return
- } else if length > 0xffffff {
- lenLen = 5
- lenByte = 0x80 | 4
- } else if length > 0xffff {
- lenLen = 4
- lenByte = 0x80 | 3
- } else if length > 0xff {
- lenLen = 3
- lenByte = 0x80 | 2
- } else if length > 0x7f {
- lenLen = 2
- lenByte = 0x80 | 1
- } else {
- lenLen = 1
- lenByte = uint8(length)
- length = 0
- }
-
- // Insert the initial length byte, make space for successive length bytes,
- // and adjust the offset.
- child.result[child.offset] = lenByte
- extraBytes := int(lenLen - 1)
- if extraBytes != 0 {
- child.add(make([]byte, extraBytes)...)
- childStart := child.offset + child.pendingLenLen
- copy(child.result[childStart+extraBytes:], child.result[childStart:])
- }
- child.offset++
- child.pendingLenLen = extraBytes
- }
-
- l := length
- for i := child.pendingLenLen - 1; i >= 0; i-- {
- child.result[child.offset+i] = uint8(l)
- l >>= 8
- }
- if l != 0 {
- b.err = fmt.Errorf("cryptobyte: pending child length %d exceeds %d-byte length prefix", length, child.pendingLenLen)
- return
- }
-
- if b.fixedSize && &b.result[0] != &child.result[0] {
- panic("cryptobyte: BuilderContinuation reallocated a fixed-size buffer")
- }
-
- b.result = child.result
-}
-
-func (b *Builder) add(bytes ...byte) {
- if b.err != nil {
- return
- }
- if b.child != nil {
- panic("cryptobyte: attempted write while child is pending")
- }
- if len(b.result)+len(bytes) < len(bytes) {
- b.err = errors.New("cryptobyte: length overflow")
- }
- if b.fixedSize && len(b.result)+len(bytes) > cap(b.result) {
- b.err = errors.New("cryptobyte: Builder is exceeding its fixed-size buffer")
- return
- }
- b.result = append(b.result, bytes...)
-}
-
-// Unwrite rolls back n bytes written directly to the Builder. An attempt by a
-// child builder passed to a continuation to unwrite bytes from its parent will
-// panic.
-func (b *Builder) Unwrite(n int) {
- if b.err != nil {
- return
- }
- if b.child != nil {
- panic("cryptobyte: attempted unwrite while child is pending")
- }
- length := len(b.result) - b.pendingLenLen - b.offset
- if length < 0 {
- panic("cryptobyte: internal error")
- }
- if n > length {
- panic("cryptobyte: attempted to unwrite more than was written")
- }
- b.result = b.result[:len(b.result)-n]
-}
-
-// A MarshalingValue marshals itself into a Builder.
-type MarshalingValue interface {
- // Marshal is called by Builder.AddValue. It receives a pointer to a builder
- // to marshal itself into. It may return an error that occurred during
- // marshaling, such as unset or invalid values.
- Marshal(b *Builder) error
-}
-
-// AddValue calls Marshal on v, passing a pointer to the builder to append to.
-// If Marshal returns an error, it is set on the Builder so that subsequent
-// appends don't have an effect.
-func (b *Builder) AddValue(v MarshalingValue) {
- err := v.Marshal(b)
- if err != nil {
- b.err = err
- }
-}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/alias/ya.make b/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/alias/ya.make
deleted file mode 100644
index a2089740ca..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/alias/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- alias.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/ya.make b/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/ya.make
deleted file mode 100644
index c14530d977..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/ya.make
+++ /dev/null
@@ -1,22 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- bits_go1.13.go
- poly1305.go
- sum_generic.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- mac_noasm.go
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- sum_amd64.go
- sum_amd64.s
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/dns/dnsmessage/message.go b/contrib/go/_std_1.20/src/vendor/golang.org/x/net/dns/dnsmessage/message.go
deleted file mode 100644
index ffdf19d5d3..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/dns/dnsmessage/message.go
+++ /dev/null
@@ -1,2677 +0,0 @@
-// Copyright 2009 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 dnsmessage provides a mostly RFC 1035 compliant implementation of
-// DNS message packing and unpacking.
-//
-// The package also supports messages with Extension Mechanisms for DNS
-// (EDNS(0)) as defined in RFC 6891.
-//
-// This implementation is designed to minimize heap allocations and avoid
-// unnecessary packing and unpacking as much as possible.
-package dnsmessage
-
-import (
- "errors"
-)
-
-// Message formats
-
-// A Type is a type of DNS request and response.
-type Type uint16
-
-const (
- // ResourceHeader.Type and Question.Type
- TypeA Type = 1
- TypeNS Type = 2
- TypeCNAME Type = 5
- TypeSOA Type = 6
- TypePTR Type = 12
- TypeMX Type = 15
- TypeTXT Type = 16
- TypeAAAA Type = 28
- TypeSRV Type = 33
- TypeOPT Type = 41
-
- // Question.Type
- TypeWKS Type = 11
- TypeHINFO Type = 13
- TypeMINFO Type = 14
- TypeAXFR Type = 252
- TypeALL Type = 255
-)
-
-var typeNames = map[Type]string{
- TypeA: "TypeA",
- TypeNS: "TypeNS",
- TypeCNAME: "TypeCNAME",
- TypeSOA: "TypeSOA",
- TypePTR: "TypePTR",
- TypeMX: "TypeMX",
- TypeTXT: "TypeTXT",
- TypeAAAA: "TypeAAAA",
- TypeSRV: "TypeSRV",
- TypeOPT: "TypeOPT",
- TypeWKS: "TypeWKS",
- TypeHINFO: "TypeHINFO",
- TypeMINFO: "TypeMINFO",
- TypeAXFR: "TypeAXFR",
- TypeALL: "TypeALL",
-}
-
-// String implements fmt.Stringer.String.
-func (t Type) String() string {
- if n, ok := typeNames[t]; ok {
- return n
- }
- return printUint16(uint16(t))
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (t Type) GoString() string {
- if n, ok := typeNames[t]; ok {
- return "dnsmessage." + n
- }
- return printUint16(uint16(t))
-}
-
-// A Class is a type of network.
-type Class uint16
-
-const (
- // ResourceHeader.Class and Question.Class
- ClassINET Class = 1
- ClassCSNET Class = 2
- ClassCHAOS Class = 3
- ClassHESIOD Class = 4
-
- // Question.Class
- ClassANY Class = 255
-)
-
-var classNames = map[Class]string{
- ClassINET: "ClassINET",
- ClassCSNET: "ClassCSNET",
- ClassCHAOS: "ClassCHAOS",
- ClassHESIOD: "ClassHESIOD",
- ClassANY: "ClassANY",
-}
-
-// String implements fmt.Stringer.String.
-func (c Class) String() string {
- if n, ok := classNames[c]; ok {
- return n
- }
- return printUint16(uint16(c))
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (c Class) GoString() string {
- if n, ok := classNames[c]; ok {
- return "dnsmessage." + n
- }
- return printUint16(uint16(c))
-}
-
-// An OpCode is a DNS operation code.
-type OpCode uint16
-
-// GoString implements fmt.GoStringer.GoString.
-func (o OpCode) GoString() string {
- return printUint16(uint16(o))
-}
-
-// An RCode is a DNS response status code.
-type RCode uint16
-
-// Header.RCode values.
-const (
- RCodeSuccess RCode = 0 // NoError
- RCodeFormatError RCode = 1 // FormErr
- RCodeServerFailure RCode = 2 // ServFail
- RCodeNameError RCode = 3 // NXDomain
- RCodeNotImplemented RCode = 4 // NotImp
- RCodeRefused RCode = 5 // Refused
-)
-
-var rCodeNames = map[RCode]string{
- RCodeSuccess: "RCodeSuccess",
- RCodeFormatError: "RCodeFormatError",
- RCodeServerFailure: "RCodeServerFailure",
- RCodeNameError: "RCodeNameError",
- RCodeNotImplemented: "RCodeNotImplemented",
- RCodeRefused: "RCodeRefused",
-}
-
-// String implements fmt.Stringer.String.
-func (r RCode) String() string {
- if n, ok := rCodeNames[r]; ok {
- return n
- }
- return printUint16(uint16(r))
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (r RCode) GoString() string {
- if n, ok := rCodeNames[r]; ok {
- return "dnsmessage." + n
- }
- return printUint16(uint16(r))
-}
-
-func printPaddedUint8(i uint8) string {
- b := byte(i)
- return string([]byte{
- b/100 + '0',
- b/10%10 + '0',
- b%10 + '0',
- })
-}
-
-func printUint8Bytes(buf []byte, i uint8) []byte {
- b := byte(i)
- if i >= 100 {
- buf = append(buf, b/100+'0')
- }
- if i >= 10 {
- buf = append(buf, b/10%10+'0')
- }
- return append(buf, b%10+'0')
-}
-
-func printByteSlice(b []byte) string {
- if len(b) == 0 {
- return ""
- }
- buf := make([]byte, 0, 5*len(b))
- buf = printUint8Bytes(buf, uint8(b[0]))
- for _, n := range b[1:] {
- buf = append(buf, ',', ' ')
- buf = printUint8Bytes(buf, uint8(n))
- }
- return string(buf)
-}
-
-const hexDigits = "0123456789abcdef"
-
-func printString(str []byte) string {
- buf := make([]byte, 0, len(str))
- for i := 0; i < len(str); i++ {
- c := str[i]
- if c == '.' || c == '-' || c == ' ' ||
- 'A' <= c && c <= 'Z' ||
- 'a' <= c && c <= 'z' ||
- '0' <= c && c <= '9' {
- buf = append(buf, c)
- continue
- }
-
- upper := c >> 4
- lower := (c << 4) >> 4
- buf = append(
- buf,
- '\\',
- 'x',
- hexDigits[upper],
- hexDigits[lower],
- )
- }
- return string(buf)
-}
-
-func printUint16(i uint16) string {
- return printUint32(uint32(i))
-}
-
-func printUint32(i uint32) string {
- // Max value is 4294967295.
- buf := make([]byte, 10)
- for b, d := buf, uint32(1000000000); d > 0; d /= 10 {
- b[0] = byte(i/d%10 + '0')
- if b[0] == '0' && len(b) == len(buf) && len(buf) > 1 {
- buf = buf[1:]
- }
- b = b[1:]
- i %= d
- }
- return string(buf)
-}
-
-func printBool(b bool) string {
- if b {
- return "true"
- }
- return "false"
-}
-
-var (
- // ErrNotStarted indicates that the prerequisite information isn't
- // available yet because the previous records haven't been appropriately
- // parsed, skipped or finished.
- ErrNotStarted = errors.New("parsing/packing of this type isn't available yet")
-
- // ErrSectionDone indicated that all records in the section have been
- // parsed or finished.
- ErrSectionDone = errors.New("parsing/packing of this section has completed")
-
- errBaseLen = errors.New("insufficient data for base length type")
- errCalcLen = errors.New("insufficient data for calculated length type")
- errReserved = errors.New("segment prefix is reserved")
- errTooManyPtr = errors.New("too many pointers (>10)")
- errInvalidPtr = errors.New("invalid pointer")
- errNilResouceBody = errors.New("nil resource body")
- errResourceLen = errors.New("insufficient data for resource body length")
- errSegTooLong = errors.New("segment length too long")
- errZeroSegLen = errors.New("zero length segment")
- errResTooLong = errors.New("resource length too long")
- errTooManyQuestions = errors.New("too many Questions to pack (>65535)")
- errTooManyAnswers = errors.New("too many Answers to pack (>65535)")
- errTooManyAuthorities = errors.New("too many Authorities to pack (>65535)")
- errTooManyAdditionals = errors.New("too many Additionals to pack (>65535)")
- errNonCanonicalName = errors.New("name is not in canonical format (it must end with a .)")
- errStringTooLong = errors.New("character string exceeds maximum length (255)")
- errCompressedSRV = errors.New("compressed name in SRV resource data")
-)
-
-// Internal constants.
-const (
- // packStartingCap is the default initial buffer size allocated during
- // packing.
- //
- // The starting capacity doesn't matter too much, but most DNS responses
- // Will be <= 512 bytes as it is the limit for DNS over UDP.
- packStartingCap = 512
-
- // uint16Len is the length (in bytes) of a uint16.
- uint16Len = 2
-
- // uint32Len is the length (in bytes) of a uint32.
- uint32Len = 4
-
- // headerLen is the length (in bytes) of a DNS header.
- //
- // A header is comprised of 6 uint16s and no padding.
- headerLen = 6 * uint16Len
-)
-
-type nestedError struct {
- // s is the current level's error message.
- s string
-
- // err is the nested error.
- err error
-}
-
-// nestedError implements error.Error.
-func (e *nestedError) Error() string {
- return e.s + ": " + e.err.Error()
-}
-
-// Header is a representation of a DNS message header.
-type Header struct {
- ID uint16
- Response bool
- OpCode OpCode
- Authoritative bool
- Truncated bool
- RecursionDesired bool
- RecursionAvailable bool
- AuthenticData bool
- CheckingDisabled bool
- RCode RCode
-}
-
-func (m *Header) pack() (id uint16, bits uint16) {
- id = m.ID
- bits = uint16(m.OpCode)<<11 | uint16(m.RCode)
- if m.RecursionAvailable {
- bits |= headerBitRA
- }
- if m.RecursionDesired {
- bits |= headerBitRD
- }
- if m.Truncated {
- bits |= headerBitTC
- }
- if m.Authoritative {
- bits |= headerBitAA
- }
- if m.Response {
- bits |= headerBitQR
- }
- if m.AuthenticData {
- bits |= headerBitAD
- }
- if m.CheckingDisabled {
- bits |= headerBitCD
- }
- return
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (m *Header) GoString() string {
- return "dnsmessage.Header{" +
- "ID: " + printUint16(m.ID) + ", " +
- "Response: " + printBool(m.Response) + ", " +
- "OpCode: " + m.OpCode.GoString() + ", " +
- "Authoritative: " + printBool(m.Authoritative) + ", " +
- "Truncated: " + printBool(m.Truncated) + ", " +
- "RecursionDesired: " + printBool(m.RecursionDesired) + ", " +
- "RecursionAvailable: " + printBool(m.RecursionAvailable) + ", " +
- "RCode: " + m.RCode.GoString() + "}"
-}
-
-// Message is a representation of a DNS message.
-type Message struct {
- Header
- Questions []Question
- Answers []Resource
- Authorities []Resource
- Additionals []Resource
-}
-
-type section uint8
-
-const (
- sectionNotStarted section = iota
- sectionHeader
- sectionQuestions
- sectionAnswers
- sectionAuthorities
- sectionAdditionals
- sectionDone
-
- headerBitQR = 1 << 15 // query/response (response=1)
- headerBitAA = 1 << 10 // authoritative
- headerBitTC = 1 << 9 // truncated
- headerBitRD = 1 << 8 // recursion desired
- headerBitRA = 1 << 7 // recursion available
- headerBitAD = 1 << 5 // authentic data
- headerBitCD = 1 << 4 // checking disabled
-)
-
-var sectionNames = map[section]string{
- sectionHeader: "header",
- sectionQuestions: "Question",
- sectionAnswers: "Answer",
- sectionAuthorities: "Authority",
- sectionAdditionals: "Additional",
-}
-
-// header is the wire format for a DNS message header.
-type header struct {
- id uint16
- bits uint16
- questions uint16
- answers uint16
- authorities uint16
- additionals uint16
-}
-
-func (h *header) count(sec section) uint16 {
- switch sec {
- case sectionQuestions:
- return h.questions
- case sectionAnswers:
- return h.answers
- case sectionAuthorities:
- return h.authorities
- case sectionAdditionals:
- return h.additionals
- }
- return 0
-}
-
-// pack appends the wire format of the header to msg.
-func (h *header) pack(msg []byte) []byte {
- msg = packUint16(msg, h.id)
- msg = packUint16(msg, h.bits)
- msg = packUint16(msg, h.questions)
- msg = packUint16(msg, h.answers)
- msg = packUint16(msg, h.authorities)
- return packUint16(msg, h.additionals)
-}
-
-func (h *header) unpack(msg []byte, off int) (int, error) {
- newOff := off
- var err error
- if h.id, newOff, err = unpackUint16(msg, newOff); err != nil {
- return off, &nestedError{"id", err}
- }
- if h.bits, newOff, err = unpackUint16(msg, newOff); err != nil {
- return off, &nestedError{"bits", err}
- }
- if h.questions, newOff, err = unpackUint16(msg, newOff); err != nil {
- return off, &nestedError{"questions", err}
- }
- if h.answers, newOff, err = unpackUint16(msg, newOff); err != nil {
- return off, &nestedError{"answers", err}
- }
- if h.authorities, newOff, err = unpackUint16(msg, newOff); err != nil {
- return off, &nestedError{"authorities", err}
- }
- if h.additionals, newOff, err = unpackUint16(msg, newOff); err != nil {
- return off, &nestedError{"additionals", err}
- }
- return newOff, nil
-}
-
-func (h *header) header() Header {
- return Header{
- ID: h.id,
- Response: (h.bits & headerBitQR) != 0,
- OpCode: OpCode(h.bits>>11) & 0xF,
- Authoritative: (h.bits & headerBitAA) != 0,
- Truncated: (h.bits & headerBitTC) != 0,
- RecursionDesired: (h.bits & headerBitRD) != 0,
- RecursionAvailable: (h.bits & headerBitRA) != 0,
- AuthenticData: (h.bits & headerBitAD) != 0,
- CheckingDisabled: (h.bits & headerBitCD) != 0,
- RCode: RCode(h.bits & 0xF),
- }
-}
-
-// A Resource is a DNS resource record.
-type Resource struct {
- Header ResourceHeader
- Body ResourceBody
-}
-
-func (r *Resource) GoString() string {
- return "dnsmessage.Resource{" +
- "Header: " + r.Header.GoString() +
- ", Body: &" + r.Body.GoString() +
- "}"
-}
-
-// A ResourceBody is a DNS resource record minus the header.
-type ResourceBody interface {
- // pack packs a Resource except for its header.
- pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error)
-
- // realType returns the actual type of the Resource. This is used to
- // fill in the header Type field.
- realType() Type
-
- // GoString implements fmt.GoStringer.GoString.
- GoString() string
-}
-
-// pack appends the wire format of the Resource to msg.
-func (r *Resource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- if r.Body == nil {
- return msg, errNilResouceBody
- }
- oldMsg := msg
- r.Header.Type = r.Body.realType()
- msg, lenOff, err := r.Header.pack(msg, compression, compressionOff)
- if err != nil {
- return msg, &nestedError{"ResourceHeader", err}
- }
- preLen := len(msg)
- msg, err = r.Body.pack(msg, compression, compressionOff)
- if err != nil {
- return msg, &nestedError{"content", err}
- }
- if err := r.Header.fixLen(msg, lenOff, preLen); err != nil {
- return oldMsg, err
- }
- return msg, nil
-}
-
-// A Parser allows incrementally parsing a DNS message.
-//
-// When parsing is started, the Header is parsed. Next, each Question can be
-// either parsed or skipped. Alternatively, all Questions can be skipped at
-// once. When all Questions have been parsed, attempting to parse Questions
-// will return (nil, nil) and attempting to skip Questions will return
-// (true, nil). After all Questions have been either parsed or skipped, all
-// Answers, Authorities and Additionals can be either parsed or skipped in the
-// same way, and each type of Resource must be fully parsed or skipped before
-// proceeding to the next type of Resource.
-//
-// Note that there is no requirement to fully skip or parse the message.
-type Parser struct {
- msg []byte
- header header
-
- section section
- off int
- index int
- resHeaderValid bool
- resHeader ResourceHeader
-}
-
-// Start parses the header and enables the parsing of Questions.
-func (p *Parser) Start(msg []byte) (Header, error) {
- if p.msg != nil {
- *p = Parser{}
- }
- p.msg = msg
- var err error
- if p.off, err = p.header.unpack(msg, 0); err != nil {
- return Header{}, &nestedError{"unpacking header", err}
- }
- p.section = sectionQuestions
- return p.header.header(), nil
-}
-
-func (p *Parser) checkAdvance(sec section) error {
- if p.section < sec {
- return ErrNotStarted
- }
- if p.section > sec {
- return ErrSectionDone
- }
- p.resHeaderValid = false
- if p.index == int(p.header.count(sec)) {
- p.index = 0
- p.section++
- return ErrSectionDone
- }
- return nil
-}
-
-func (p *Parser) resource(sec section) (Resource, error) {
- var r Resource
- var err error
- r.Header, err = p.resourceHeader(sec)
- if err != nil {
- return r, err
- }
- p.resHeaderValid = false
- r.Body, p.off, err = unpackResourceBody(p.msg, p.off, r.Header)
- if err != nil {
- return Resource{}, &nestedError{"unpacking " + sectionNames[sec], err}
- }
- p.index++
- return r, nil
-}
-
-func (p *Parser) resourceHeader(sec section) (ResourceHeader, error) {
- if p.resHeaderValid {
- return p.resHeader, nil
- }
- if err := p.checkAdvance(sec); err != nil {
- return ResourceHeader{}, err
- }
- var hdr ResourceHeader
- off, err := hdr.unpack(p.msg, p.off)
- if err != nil {
- return ResourceHeader{}, err
- }
- p.resHeaderValid = true
- p.resHeader = hdr
- p.off = off
- return hdr, nil
-}
-
-func (p *Parser) skipResource(sec section) error {
- if p.resHeaderValid {
- newOff := p.off + int(p.resHeader.Length)
- if newOff > len(p.msg) {
- return errResourceLen
- }
- p.off = newOff
- p.resHeaderValid = false
- p.index++
- return nil
- }
- if err := p.checkAdvance(sec); err != nil {
- return err
- }
- var err error
- p.off, err = skipResource(p.msg, p.off)
- if err != nil {
- return &nestedError{"skipping: " + sectionNames[sec], err}
- }
- p.index++
- return nil
-}
-
-// Question parses a single Question.
-func (p *Parser) Question() (Question, error) {
- if err := p.checkAdvance(sectionQuestions); err != nil {
- return Question{}, err
- }
- var name Name
- off, err := name.unpack(p.msg, p.off)
- if err != nil {
- return Question{}, &nestedError{"unpacking Question.Name", err}
- }
- typ, off, err := unpackType(p.msg, off)
- if err != nil {
- return Question{}, &nestedError{"unpacking Question.Type", err}
- }
- class, off, err := unpackClass(p.msg, off)
- if err != nil {
- return Question{}, &nestedError{"unpacking Question.Class", err}
- }
- p.off = off
- p.index++
- return Question{name, typ, class}, nil
-}
-
-// AllQuestions parses all Questions.
-func (p *Parser) AllQuestions() ([]Question, error) {
- // Multiple questions are valid according to the spec,
- // but servers don't actually support them. There will
- // be at most one question here.
- //
- // Do not pre-allocate based on info in p.header, since
- // the data is untrusted.
- qs := []Question{}
- for {
- q, err := p.Question()
- if err == ErrSectionDone {
- return qs, nil
- }
- if err != nil {
- return nil, err
- }
- qs = append(qs, q)
- }
-}
-
-// SkipQuestion skips a single Question.
-func (p *Parser) SkipQuestion() error {
- if err := p.checkAdvance(sectionQuestions); err != nil {
- return err
- }
- off, err := skipName(p.msg, p.off)
- if err != nil {
- return &nestedError{"skipping Question Name", err}
- }
- if off, err = skipType(p.msg, off); err != nil {
- return &nestedError{"skipping Question Type", err}
- }
- if off, err = skipClass(p.msg, off); err != nil {
- return &nestedError{"skipping Question Class", err}
- }
- p.off = off
- p.index++
- return nil
-}
-
-// SkipAllQuestions skips all Questions.
-func (p *Parser) SkipAllQuestions() error {
- for {
- if err := p.SkipQuestion(); err == ErrSectionDone {
- return nil
- } else if err != nil {
- return err
- }
- }
-}
-
-// AnswerHeader parses a single Answer ResourceHeader.
-func (p *Parser) AnswerHeader() (ResourceHeader, error) {
- return p.resourceHeader(sectionAnswers)
-}
-
-// Answer parses a single Answer Resource.
-func (p *Parser) Answer() (Resource, error) {
- return p.resource(sectionAnswers)
-}
-
-// AllAnswers parses all Answer Resources.
-func (p *Parser) AllAnswers() ([]Resource, error) {
- // The most common query is for A/AAAA, which usually returns
- // a handful of IPs.
- //
- // Pre-allocate up to a certain limit, since p.header is
- // untrusted data.
- n := int(p.header.answers)
- if n > 20 {
- n = 20
- }
- as := make([]Resource, 0, n)
- for {
- a, err := p.Answer()
- if err == ErrSectionDone {
- return as, nil
- }
- if err != nil {
- return nil, err
- }
- as = append(as, a)
- }
-}
-
-// SkipAnswer skips a single Answer Resource.
-func (p *Parser) SkipAnswer() error {
- return p.skipResource(sectionAnswers)
-}
-
-// SkipAllAnswers skips all Answer Resources.
-func (p *Parser) SkipAllAnswers() error {
- for {
- if err := p.SkipAnswer(); err == ErrSectionDone {
- return nil
- } else if err != nil {
- return err
- }
- }
-}
-
-// AuthorityHeader parses a single Authority ResourceHeader.
-func (p *Parser) AuthorityHeader() (ResourceHeader, error) {
- return p.resourceHeader(sectionAuthorities)
-}
-
-// Authority parses a single Authority Resource.
-func (p *Parser) Authority() (Resource, error) {
- return p.resource(sectionAuthorities)
-}
-
-// AllAuthorities parses all Authority Resources.
-func (p *Parser) AllAuthorities() ([]Resource, error) {
- // Authorities contains SOA in case of NXDOMAIN and friends,
- // otherwise it is empty.
- //
- // Pre-allocate up to a certain limit, since p.header is
- // untrusted data.
- n := int(p.header.authorities)
- if n > 10 {
- n = 10
- }
- as := make([]Resource, 0, n)
- for {
- a, err := p.Authority()
- if err == ErrSectionDone {
- return as, nil
- }
- if err != nil {
- return nil, err
- }
- as = append(as, a)
- }
-}
-
-// SkipAuthority skips a single Authority Resource.
-func (p *Parser) SkipAuthority() error {
- return p.skipResource(sectionAuthorities)
-}
-
-// SkipAllAuthorities skips all Authority Resources.
-func (p *Parser) SkipAllAuthorities() error {
- for {
- if err := p.SkipAuthority(); err == ErrSectionDone {
- return nil
- } else if err != nil {
- return err
- }
- }
-}
-
-// AdditionalHeader parses a single Additional ResourceHeader.
-func (p *Parser) AdditionalHeader() (ResourceHeader, error) {
- return p.resourceHeader(sectionAdditionals)
-}
-
-// Additional parses a single Additional Resource.
-func (p *Parser) Additional() (Resource, error) {
- return p.resource(sectionAdditionals)
-}
-
-// AllAdditionals parses all Additional Resources.
-func (p *Parser) AllAdditionals() ([]Resource, error) {
- // Additionals usually contain OPT, and sometimes A/AAAA
- // glue records.
- //
- // Pre-allocate up to a certain limit, since p.header is
- // untrusted data.
- n := int(p.header.additionals)
- if n > 10 {
- n = 10
- }
- as := make([]Resource, 0, n)
- for {
- a, err := p.Additional()
- if err == ErrSectionDone {
- return as, nil
- }
- if err != nil {
- return nil, err
- }
- as = append(as, a)
- }
-}
-
-// SkipAdditional skips a single Additional Resource.
-func (p *Parser) SkipAdditional() error {
- return p.skipResource(sectionAdditionals)
-}
-
-// SkipAllAdditionals skips all Additional Resources.
-func (p *Parser) SkipAllAdditionals() error {
- for {
- if err := p.SkipAdditional(); err == ErrSectionDone {
- return nil
- } else if err != nil {
- return err
- }
- }
-}
-
-// CNAMEResource parses a single CNAMEResource.
-//
-// One of the XXXHeader methods must have been called before calling this
-// method.
-func (p *Parser) CNAMEResource() (CNAMEResource, error) {
- if !p.resHeaderValid || p.resHeader.Type != TypeCNAME {
- return CNAMEResource{}, ErrNotStarted
- }
- r, err := unpackCNAMEResource(p.msg, p.off)
- if err != nil {
- return CNAMEResource{}, err
- }
- p.off += int(p.resHeader.Length)
- p.resHeaderValid = false
- p.index++
- return r, nil
-}
-
-// MXResource parses a single MXResource.
-//
-// One of the XXXHeader methods must have been called before calling this
-// method.
-func (p *Parser) MXResource() (MXResource, error) {
- if !p.resHeaderValid || p.resHeader.Type != TypeMX {
- return MXResource{}, ErrNotStarted
- }
- r, err := unpackMXResource(p.msg, p.off)
- if err != nil {
- return MXResource{}, err
- }
- p.off += int(p.resHeader.Length)
- p.resHeaderValid = false
- p.index++
- return r, nil
-}
-
-// NSResource parses a single NSResource.
-//
-// One of the XXXHeader methods must have been called before calling this
-// method.
-func (p *Parser) NSResource() (NSResource, error) {
- if !p.resHeaderValid || p.resHeader.Type != TypeNS {
- return NSResource{}, ErrNotStarted
- }
- r, err := unpackNSResource(p.msg, p.off)
- if err != nil {
- return NSResource{}, err
- }
- p.off += int(p.resHeader.Length)
- p.resHeaderValid = false
- p.index++
- return r, nil
-}
-
-// PTRResource parses a single PTRResource.
-//
-// One of the XXXHeader methods must have been called before calling this
-// method.
-func (p *Parser) PTRResource() (PTRResource, error) {
- if !p.resHeaderValid || p.resHeader.Type != TypePTR {
- return PTRResource{}, ErrNotStarted
- }
- r, err := unpackPTRResource(p.msg, p.off)
- if err != nil {
- return PTRResource{}, err
- }
- p.off += int(p.resHeader.Length)
- p.resHeaderValid = false
- p.index++
- return r, nil
-}
-
-// SOAResource parses a single SOAResource.
-//
-// One of the XXXHeader methods must have been called before calling this
-// method.
-func (p *Parser) SOAResource() (SOAResource, error) {
- if !p.resHeaderValid || p.resHeader.Type != TypeSOA {
- return SOAResource{}, ErrNotStarted
- }
- r, err := unpackSOAResource(p.msg, p.off)
- if err != nil {
- return SOAResource{}, err
- }
- p.off += int(p.resHeader.Length)
- p.resHeaderValid = false
- p.index++
- return r, nil
-}
-
-// TXTResource parses a single TXTResource.
-//
-// One of the XXXHeader methods must have been called before calling this
-// method.
-func (p *Parser) TXTResource() (TXTResource, error) {
- if !p.resHeaderValid || p.resHeader.Type != TypeTXT {
- return TXTResource{}, ErrNotStarted
- }
- r, err := unpackTXTResource(p.msg, p.off, p.resHeader.Length)
- if err != nil {
- return TXTResource{}, err
- }
- p.off += int(p.resHeader.Length)
- p.resHeaderValid = false
- p.index++
- return r, nil
-}
-
-// SRVResource parses a single SRVResource.
-//
-// One of the XXXHeader methods must have been called before calling this
-// method.
-func (p *Parser) SRVResource() (SRVResource, error) {
- if !p.resHeaderValid || p.resHeader.Type != TypeSRV {
- return SRVResource{}, ErrNotStarted
- }
- r, err := unpackSRVResource(p.msg, p.off)
- if err != nil {
- return SRVResource{}, err
- }
- p.off += int(p.resHeader.Length)
- p.resHeaderValid = false
- p.index++
- return r, nil
-}
-
-// AResource parses a single AResource.
-//
-// One of the XXXHeader methods must have been called before calling this
-// method.
-func (p *Parser) AResource() (AResource, error) {
- if !p.resHeaderValid || p.resHeader.Type != TypeA {
- return AResource{}, ErrNotStarted
- }
- r, err := unpackAResource(p.msg, p.off)
- if err != nil {
- return AResource{}, err
- }
- p.off += int(p.resHeader.Length)
- p.resHeaderValid = false
- p.index++
- return r, nil
-}
-
-// AAAAResource parses a single AAAAResource.
-//
-// One of the XXXHeader methods must have been called before calling this
-// method.
-func (p *Parser) AAAAResource() (AAAAResource, error) {
- if !p.resHeaderValid || p.resHeader.Type != TypeAAAA {
- return AAAAResource{}, ErrNotStarted
- }
- r, err := unpackAAAAResource(p.msg, p.off)
- if err != nil {
- return AAAAResource{}, err
- }
- p.off += int(p.resHeader.Length)
- p.resHeaderValid = false
- p.index++
- return r, nil
-}
-
-// OPTResource parses a single OPTResource.
-//
-// One of the XXXHeader methods must have been called before calling this
-// method.
-func (p *Parser) OPTResource() (OPTResource, error) {
- if !p.resHeaderValid || p.resHeader.Type != TypeOPT {
- return OPTResource{}, ErrNotStarted
- }
- r, err := unpackOPTResource(p.msg, p.off, p.resHeader.Length)
- if err != nil {
- return OPTResource{}, err
- }
- p.off += int(p.resHeader.Length)
- p.resHeaderValid = false
- p.index++
- return r, nil
-}
-
-// UnknownResource parses a single UnknownResource.
-//
-// One of the XXXHeader methods must have been called before calling this
-// method.
-func (p *Parser) UnknownResource() (UnknownResource, error) {
- if !p.resHeaderValid {
- return UnknownResource{}, ErrNotStarted
- }
- r, err := unpackUnknownResource(p.resHeader.Type, p.msg, p.off, p.resHeader.Length)
- if err != nil {
- return UnknownResource{}, err
- }
- p.off += int(p.resHeader.Length)
- p.resHeaderValid = false
- p.index++
- return r, nil
-}
-
-// Unpack parses a full Message.
-func (m *Message) Unpack(msg []byte) error {
- var p Parser
- var err error
- if m.Header, err = p.Start(msg); err != nil {
- return err
- }
- if m.Questions, err = p.AllQuestions(); err != nil {
- return err
- }
- if m.Answers, err = p.AllAnswers(); err != nil {
- return err
- }
- if m.Authorities, err = p.AllAuthorities(); err != nil {
- return err
- }
- if m.Additionals, err = p.AllAdditionals(); err != nil {
- return err
- }
- return nil
-}
-
-// Pack packs a full Message.
-func (m *Message) Pack() ([]byte, error) {
- return m.AppendPack(make([]byte, 0, packStartingCap))
-}
-
-// AppendPack is like Pack but appends the full Message to b and returns the
-// extended buffer.
-func (m *Message) AppendPack(b []byte) ([]byte, error) {
- // Validate the lengths. It is very unlikely that anyone will try to
- // pack more than 65535 of any particular type, but it is possible and
- // we should fail gracefully.
- if len(m.Questions) > int(^uint16(0)) {
- return nil, errTooManyQuestions
- }
- if len(m.Answers) > int(^uint16(0)) {
- return nil, errTooManyAnswers
- }
- if len(m.Authorities) > int(^uint16(0)) {
- return nil, errTooManyAuthorities
- }
- if len(m.Additionals) > int(^uint16(0)) {
- return nil, errTooManyAdditionals
- }
-
- var h header
- h.id, h.bits = m.Header.pack()
-
- h.questions = uint16(len(m.Questions))
- h.answers = uint16(len(m.Answers))
- h.authorities = uint16(len(m.Authorities))
- h.additionals = uint16(len(m.Additionals))
-
- compressionOff := len(b)
- msg := h.pack(b)
-
- // RFC 1035 allows (but does not require) compression for packing. RFC
- // 1035 requires unpacking implementations to support compression, so
- // unconditionally enabling it is fine.
- //
- // DNS lookups are typically done over UDP, and RFC 1035 states that UDP
- // DNS messages can be a maximum of 512 bytes long. Without compression,
- // many DNS response messages are over this limit, so enabling
- // compression will help ensure compliance.
- compression := map[string]int{}
-
- for i := range m.Questions {
- var err error
- if msg, err = m.Questions[i].pack(msg, compression, compressionOff); err != nil {
- return nil, &nestedError{"packing Question", err}
- }
- }
- for i := range m.Answers {
- var err error
- if msg, err = m.Answers[i].pack(msg, compression, compressionOff); err != nil {
- return nil, &nestedError{"packing Answer", err}
- }
- }
- for i := range m.Authorities {
- var err error
- if msg, err = m.Authorities[i].pack(msg, compression, compressionOff); err != nil {
- return nil, &nestedError{"packing Authority", err}
- }
- }
- for i := range m.Additionals {
- var err error
- if msg, err = m.Additionals[i].pack(msg, compression, compressionOff); err != nil {
- return nil, &nestedError{"packing Additional", err}
- }
- }
-
- return msg, nil
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (m *Message) GoString() string {
- s := "dnsmessage.Message{Header: " + m.Header.GoString() + ", " +
- "Questions: []dnsmessage.Question{"
- if len(m.Questions) > 0 {
- s += m.Questions[0].GoString()
- for _, q := range m.Questions[1:] {
- s += ", " + q.GoString()
- }
- }
- s += "}, Answers: []dnsmessage.Resource{"
- if len(m.Answers) > 0 {
- s += m.Answers[0].GoString()
- for _, a := range m.Answers[1:] {
- s += ", " + a.GoString()
- }
- }
- s += "}, Authorities: []dnsmessage.Resource{"
- if len(m.Authorities) > 0 {
- s += m.Authorities[0].GoString()
- for _, a := range m.Authorities[1:] {
- s += ", " + a.GoString()
- }
- }
- s += "}, Additionals: []dnsmessage.Resource{"
- if len(m.Additionals) > 0 {
- s += m.Additionals[0].GoString()
- for _, a := range m.Additionals[1:] {
- s += ", " + a.GoString()
- }
- }
- return s + "}}"
-}
-
-// A Builder allows incrementally packing a DNS message.
-//
-// Example usage:
-//
-// buf := make([]byte, 2, 514)
-// b := NewBuilder(buf, Header{...})
-// b.EnableCompression()
-// // Optionally start a section and add things to that section.
-// // Repeat adding sections as necessary.
-// buf, err := b.Finish()
-// // If err is nil, buf[2:] will contain the built bytes.
-type Builder struct {
- // msg is the storage for the message being built.
- msg []byte
-
- // section keeps track of the current section being built.
- section section
-
- // header keeps track of what should go in the header when Finish is
- // called.
- header header
-
- // start is the starting index of the bytes allocated in msg for header.
- start int
-
- // compression is a mapping from name suffixes to their starting index
- // in msg.
- compression map[string]int
-}
-
-// NewBuilder creates a new builder with compression disabled.
-//
-// Note: Most users will want to immediately enable compression with the
-// EnableCompression method. See that method's comment for why you may or may
-// not want to enable compression.
-//
-// The DNS message is appended to the provided initial buffer buf (which may be
-// nil) as it is built. The final message is returned by the (*Builder).Finish
-// method, which includes buf[:len(buf)] and may return the same underlying
-// array if there was sufficient capacity in the slice.
-func NewBuilder(buf []byte, h Header) Builder {
- if buf == nil {
- buf = make([]byte, 0, packStartingCap)
- }
- b := Builder{msg: buf, start: len(buf)}
- b.header.id, b.header.bits = h.pack()
- var hb [headerLen]byte
- b.msg = append(b.msg, hb[:]...)
- b.section = sectionHeader
- return b
-}
-
-// EnableCompression enables compression in the Builder.
-//
-// Leaving compression disabled avoids compression related allocations, but can
-// result in larger message sizes. Be careful with this mode as it can cause
-// messages to exceed the UDP size limit.
-//
-// According to RFC 1035, section 4.1.4, the use of compression is optional, but
-// all implementations must accept both compressed and uncompressed DNS
-// messages.
-//
-// Compression should be enabled before any sections are added for best results.
-func (b *Builder) EnableCompression() {
- b.compression = map[string]int{}
-}
-
-func (b *Builder) startCheck(s section) error {
- if b.section <= sectionNotStarted {
- return ErrNotStarted
- }
- if b.section > s {
- return ErrSectionDone
- }
- return nil
-}
-
-// StartQuestions prepares the builder for packing Questions.
-func (b *Builder) StartQuestions() error {
- if err := b.startCheck(sectionQuestions); err != nil {
- return err
- }
- b.section = sectionQuestions
- return nil
-}
-
-// StartAnswers prepares the builder for packing Answers.
-func (b *Builder) StartAnswers() error {
- if err := b.startCheck(sectionAnswers); err != nil {
- return err
- }
- b.section = sectionAnswers
- return nil
-}
-
-// StartAuthorities prepares the builder for packing Authorities.
-func (b *Builder) StartAuthorities() error {
- if err := b.startCheck(sectionAuthorities); err != nil {
- return err
- }
- b.section = sectionAuthorities
- return nil
-}
-
-// StartAdditionals prepares the builder for packing Additionals.
-func (b *Builder) StartAdditionals() error {
- if err := b.startCheck(sectionAdditionals); err != nil {
- return err
- }
- b.section = sectionAdditionals
- return nil
-}
-
-func (b *Builder) incrementSectionCount() error {
- var count *uint16
- var err error
- switch b.section {
- case sectionQuestions:
- count = &b.header.questions
- err = errTooManyQuestions
- case sectionAnswers:
- count = &b.header.answers
- err = errTooManyAnswers
- case sectionAuthorities:
- count = &b.header.authorities
- err = errTooManyAuthorities
- case sectionAdditionals:
- count = &b.header.additionals
- err = errTooManyAdditionals
- }
- if *count == ^uint16(0) {
- return err
- }
- *count++
- return nil
-}
-
-// Question adds a single Question.
-func (b *Builder) Question(q Question) error {
- if b.section < sectionQuestions {
- return ErrNotStarted
- }
- if b.section > sectionQuestions {
- return ErrSectionDone
- }
- msg, err := q.pack(b.msg, b.compression, b.start)
- if err != nil {
- return err
- }
- if err := b.incrementSectionCount(); err != nil {
- return err
- }
- b.msg = msg
- return nil
-}
-
-func (b *Builder) checkResourceSection() error {
- if b.section < sectionAnswers {
- return ErrNotStarted
- }
- if b.section > sectionAdditionals {
- return ErrSectionDone
- }
- return nil
-}
-
-// CNAMEResource adds a single CNAMEResource.
-func (b *Builder) CNAMEResource(h ResourceHeader, r CNAMEResource) error {
- if err := b.checkResourceSection(); err != nil {
- return err
- }
- h.Type = r.realType()
- msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
- if err != nil {
- return &nestedError{"ResourceHeader", err}
- }
- preLen := len(msg)
- if msg, err = r.pack(msg, b.compression, b.start); err != nil {
- return &nestedError{"CNAMEResource body", err}
- }
- if err := h.fixLen(msg, lenOff, preLen); err != nil {
- return err
- }
- if err := b.incrementSectionCount(); err != nil {
- return err
- }
- b.msg = msg
- return nil
-}
-
-// MXResource adds a single MXResource.
-func (b *Builder) MXResource(h ResourceHeader, r MXResource) error {
- if err := b.checkResourceSection(); err != nil {
- return err
- }
- h.Type = r.realType()
- msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
- if err != nil {
- return &nestedError{"ResourceHeader", err}
- }
- preLen := len(msg)
- if msg, err = r.pack(msg, b.compression, b.start); err != nil {
- return &nestedError{"MXResource body", err}
- }
- if err := h.fixLen(msg, lenOff, preLen); err != nil {
- return err
- }
- if err := b.incrementSectionCount(); err != nil {
- return err
- }
- b.msg = msg
- return nil
-}
-
-// NSResource adds a single NSResource.
-func (b *Builder) NSResource(h ResourceHeader, r NSResource) error {
- if err := b.checkResourceSection(); err != nil {
- return err
- }
- h.Type = r.realType()
- msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
- if err != nil {
- return &nestedError{"ResourceHeader", err}
- }
- preLen := len(msg)
- if msg, err = r.pack(msg, b.compression, b.start); err != nil {
- return &nestedError{"NSResource body", err}
- }
- if err := h.fixLen(msg, lenOff, preLen); err != nil {
- return err
- }
- if err := b.incrementSectionCount(); err != nil {
- return err
- }
- b.msg = msg
- return nil
-}
-
-// PTRResource adds a single PTRResource.
-func (b *Builder) PTRResource(h ResourceHeader, r PTRResource) error {
- if err := b.checkResourceSection(); err != nil {
- return err
- }
- h.Type = r.realType()
- msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
- if err != nil {
- return &nestedError{"ResourceHeader", err}
- }
- preLen := len(msg)
- if msg, err = r.pack(msg, b.compression, b.start); err != nil {
- return &nestedError{"PTRResource body", err}
- }
- if err := h.fixLen(msg, lenOff, preLen); err != nil {
- return err
- }
- if err := b.incrementSectionCount(); err != nil {
- return err
- }
- b.msg = msg
- return nil
-}
-
-// SOAResource adds a single SOAResource.
-func (b *Builder) SOAResource(h ResourceHeader, r SOAResource) error {
- if err := b.checkResourceSection(); err != nil {
- return err
- }
- h.Type = r.realType()
- msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
- if err != nil {
- return &nestedError{"ResourceHeader", err}
- }
- preLen := len(msg)
- if msg, err = r.pack(msg, b.compression, b.start); err != nil {
- return &nestedError{"SOAResource body", err}
- }
- if err := h.fixLen(msg, lenOff, preLen); err != nil {
- return err
- }
- if err := b.incrementSectionCount(); err != nil {
- return err
- }
- b.msg = msg
- return nil
-}
-
-// TXTResource adds a single TXTResource.
-func (b *Builder) TXTResource(h ResourceHeader, r TXTResource) error {
- if err := b.checkResourceSection(); err != nil {
- return err
- }
- h.Type = r.realType()
- msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
- if err != nil {
- return &nestedError{"ResourceHeader", err}
- }
- preLen := len(msg)
- if msg, err = r.pack(msg, b.compression, b.start); err != nil {
- return &nestedError{"TXTResource body", err}
- }
- if err := h.fixLen(msg, lenOff, preLen); err != nil {
- return err
- }
- if err := b.incrementSectionCount(); err != nil {
- return err
- }
- b.msg = msg
- return nil
-}
-
-// SRVResource adds a single SRVResource.
-func (b *Builder) SRVResource(h ResourceHeader, r SRVResource) error {
- if err := b.checkResourceSection(); err != nil {
- return err
- }
- h.Type = r.realType()
- msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
- if err != nil {
- return &nestedError{"ResourceHeader", err}
- }
- preLen := len(msg)
- if msg, err = r.pack(msg, b.compression, b.start); err != nil {
- return &nestedError{"SRVResource body", err}
- }
- if err := h.fixLen(msg, lenOff, preLen); err != nil {
- return err
- }
- if err := b.incrementSectionCount(); err != nil {
- return err
- }
- b.msg = msg
- return nil
-}
-
-// AResource adds a single AResource.
-func (b *Builder) AResource(h ResourceHeader, r AResource) error {
- if err := b.checkResourceSection(); err != nil {
- return err
- }
- h.Type = r.realType()
- msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
- if err != nil {
- return &nestedError{"ResourceHeader", err}
- }
- preLen := len(msg)
- if msg, err = r.pack(msg, b.compression, b.start); err != nil {
- return &nestedError{"AResource body", err}
- }
- if err := h.fixLen(msg, lenOff, preLen); err != nil {
- return err
- }
- if err := b.incrementSectionCount(); err != nil {
- return err
- }
- b.msg = msg
- return nil
-}
-
-// AAAAResource adds a single AAAAResource.
-func (b *Builder) AAAAResource(h ResourceHeader, r AAAAResource) error {
- if err := b.checkResourceSection(); err != nil {
- return err
- }
- h.Type = r.realType()
- msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
- if err != nil {
- return &nestedError{"ResourceHeader", err}
- }
- preLen := len(msg)
- if msg, err = r.pack(msg, b.compression, b.start); err != nil {
- return &nestedError{"AAAAResource body", err}
- }
- if err := h.fixLen(msg, lenOff, preLen); err != nil {
- return err
- }
- if err := b.incrementSectionCount(); err != nil {
- return err
- }
- b.msg = msg
- return nil
-}
-
-// OPTResource adds a single OPTResource.
-func (b *Builder) OPTResource(h ResourceHeader, r OPTResource) error {
- if err := b.checkResourceSection(); err != nil {
- return err
- }
- h.Type = r.realType()
- msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
- if err != nil {
- return &nestedError{"ResourceHeader", err}
- }
- preLen := len(msg)
- if msg, err = r.pack(msg, b.compression, b.start); err != nil {
- return &nestedError{"OPTResource body", err}
- }
- if err := h.fixLen(msg, lenOff, preLen); err != nil {
- return err
- }
- if err := b.incrementSectionCount(); err != nil {
- return err
- }
- b.msg = msg
- return nil
-}
-
-// UnknownResource adds a single UnknownResource.
-func (b *Builder) UnknownResource(h ResourceHeader, r UnknownResource) error {
- if err := b.checkResourceSection(); err != nil {
- return err
- }
- h.Type = r.realType()
- msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
- if err != nil {
- return &nestedError{"ResourceHeader", err}
- }
- preLen := len(msg)
- if msg, err = r.pack(msg, b.compression, b.start); err != nil {
- return &nestedError{"UnknownResource body", err}
- }
- if err := h.fixLen(msg, lenOff, preLen); err != nil {
- return err
- }
- if err := b.incrementSectionCount(); err != nil {
- return err
- }
- b.msg = msg
- return nil
-}
-
-// Finish ends message building and generates a binary message.
-func (b *Builder) Finish() ([]byte, error) {
- if b.section < sectionHeader {
- return nil, ErrNotStarted
- }
- b.section = sectionDone
- // Space for the header was allocated in NewBuilder.
- b.header.pack(b.msg[b.start:b.start])
- return b.msg, nil
-}
-
-// A ResourceHeader is the header of a DNS resource record. There are
-// many types of DNS resource records, but they all share the same header.
-type ResourceHeader struct {
- // Name is the domain name for which this resource record pertains.
- Name Name
-
- // Type is the type of DNS resource record.
- //
- // This field will be set automatically during packing.
- Type Type
-
- // Class is the class of network to which this DNS resource record
- // pertains.
- Class Class
-
- // TTL is the length of time (measured in seconds) which this resource
- // record is valid for (time to live). All Resources in a set should
- // have the same TTL (RFC 2181 Section 5.2).
- TTL uint32
-
- // Length is the length of data in the resource record after the header.
- //
- // This field will be set automatically during packing.
- Length uint16
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (h *ResourceHeader) GoString() string {
- return "dnsmessage.ResourceHeader{" +
- "Name: " + h.Name.GoString() + ", " +
- "Type: " + h.Type.GoString() + ", " +
- "Class: " + h.Class.GoString() + ", " +
- "TTL: " + printUint32(h.TTL) + ", " +
- "Length: " + printUint16(h.Length) + "}"
-}
-
-// pack appends the wire format of the ResourceHeader to oldMsg.
-//
-// lenOff is the offset in msg where the Length field was packed.
-func (h *ResourceHeader) pack(oldMsg []byte, compression map[string]int, compressionOff int) (msg []byte, lenOff int, err error) {
- msg = oldMsg
- if msg, err = h.Name.pack(msg, compression, compressionOff); err != nil {
- return oldMsg, 0, &nestedError{"Name", err}
- }
- msg = packType(msg, h.Type)
- msg = packClass(msg, h.Class)
- msg = packUint32(msg, h.TTL)
- lenOff = len(msg)
- msg = packUint16(msg, h.Length)
- return msg, lenOff, nil
-}
-
-func (h *ResourceHeader) unpack(msg []byte, off int) (int, error) {
- newOff := off
- var err error
- if newOff, err = h.Name.unpack(msg, newOff); err != nil {
- return off, &nestedError{"Name", err}
- }
- if h.Type, newOff, err = unpackType(msg, newOff); err != nil {
- return off, &nestedError{"Type", err}
- }
- if h.Class, newOff, err = unpackClass(msg, newOff); err != nil {
- return off, &nestedError{"Class", err}
- }
- if h.TTL, newOff, err = unpackUint32(msg, newOff); err != nil {
- return off, &nestedError{"TTL", err}
- }
- if h.Length, newOff, err = unpackUint16(msg, newOff); err != nil {
- return off, &nestedError{"Length", err}
- }
- return newOff, nil
-}
-
-// fixLen updates a packed ResourceHeader to include the length of the
-// ResourceBody.
-//
-// lenOff is the offset of the ResourceHeader.Length field in msg.
-//
-// preLen is the length that msg was before the ResourceBody was packed.
-func (h *ResourceHeader) fixLen(msg []byte, lenOff int, preLen int) error {
- conLen := len(msg) - preLen
- if conLen > int(^uint16(0)) {
- return errResTooLong
- }
-
- // Fill in the length now that we know how long the content is.
- packUint16(msg[lenOff:lenOff], uint16(conLen))
- h.Length = uint16(conLen)
-
- return nil
-}
-
-// EDNS(0) wire constants.
-const (
- edns0Version = 0
-
- edns0DNSSECOK = 0x00008000
- ednsVersionMask = 0x00ff0000
- edns0DNSSECOKMask = 0x00ff8000
-)
-
-// SetEDNS0 configures h for EDNS(0).
-//
-// The provided extRCode must be an extended RCode.
-func (h *ResourceHeader) SetEDNS0(udpPayloadLen int, extRCode RCode, dnssecOK bool) error {
- h.Name = Name{Data: [nameLen]byte{'.'}, Length: 1} // RFC 6891 section 6.1.2
- h.Type = TypeOPT
- h.Class = Class(udpPayloadLen)
- h.TTL = uint32(extRCode) >> 4 << 24
- if dnssecOK {
- h.TTL |= edns0DNSSECOK
- }
- return nil
-}
-
-// DNSSECAllowed reports whether the DNSSEC OK bit is set.
-func (h *ResourceHeader) DNSSECAllowed() bool {
- return h.TTL&edns0DNSSECOKMask == edns0DNSSECOK // RFC 6891 section 6.1.3
-}
-
-// ExtendedRCode returns an extended RCode.
-//
-// The provided rcode must be the RCode in DNS message header.
-func (h *ResourceHeader) ExtendedRCode(rcode RCode) RCode {
- if h.TTL&ednsVersionMask == edns0Version { // RFC 6891 section 6.1.3
- return RCode(h.TTL>>24<<4) | rcode
- }
- return rcode
-}
-
-func skipResource(msg []byte, off int) (int, error) {
- newOff, err := skipName(msg, off)
- if err != nil {
- return off, &nestedError{"Name", err}
- }
- if newOff, err = skipType(msg, newOff); err != nil {
- return off, &nestedError{"Type", err}
- }
- if newOff, err = skipClass(msg, newOff); err != nil {
- return off, &nestedError{"Class", err}
- }
- if newOff, err = skipUint32(msg, newOff); err != nil {
- return off, &nestedError{"TTL", err}
- }
- length, newOff, err := unpackUint16(msg, newOff)
- if err != nil {
- return off, &nestedError{"Length", err}
- }
- if newOff += int(length); newOff > len(msg) {
- return off, errResourceLen
- }
- return newOff, nil
-}
-
-// packUint16 appends the wire format of field to msg.
-func packUint16(msg []byte, field uint16) []byte {
- return append(msg, byte(field>>8), byte(field))
-}
-
-func unpackUint16(msg []byte, off int) (uint16, int, error) {
- if off+uint16Len > len(msg) {
- return 0, off, errBaseLen
- }
- return uint16(msg[off])<<8 | uint16(msg[off+1]), off + uint16Len, nil
-}
-
-func skipUint16(msg []byte, off int) (int, error) {
- if off+uint16Len > len(msg) {
- return off, errBaseLen
- }
- return off + uint16Len, nil
-}
-
-// packType appends the wire format of field to msg.
-func packType(msg []byte, field Type) []byte {
- return packUint16(msg, uint16(field))
-}
-
-func unpackType(msg []byte, off int) (Type, int, error) {
- t, o, err := unpackUint16(msg, off)
- return Type(t), o, err
-}
-
-func skipType(msg []byte, off int) (int, error) {
- return skipUint16(msg, off)
-}
-
-// packClass appends the wire format of field to msg.
-func packClass(msg []byte, field Class) []byte {
- return packUint16(msg, uint16(field))
-}
-
-func unpackClass(msg []byte, off int) (Class, int, error) {
- c, o, err := unpackUint16(msg, off)
- return Class(c), o, err
-}
-
-func skipClass(msg []byte, off int) (int, error) {
- return skipUint16(msg, off)
-}
-
-// packUint32 appends the wire format of field to msg.
-func packUint32(msg []byte, field uint32) []byte {
- return append(
- msg,
- byte(field>>24),
- byte(field>>16),
- byte(field>>8),
- byte(field),
- )
-}
-
-func unpackUint32(msg []byte, off int) (uint32, int, error) {
- if off+uint32Len > len(msg) {
- return 0, off, errBaseLen
- }
- v := uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3])
- return v, off + uint32Len, nil
-}
-
-func skipUint32(msg []byte, off int) (int, error) {
- if off+uint32Len > len(msg) {
- return off, errBaseLen
- }
- return off + uint32Len, nil
-}
-
-// packText appends the wire format of field to msg.
-func packText(msg []byte, field string) ([]byte, error) {
- l := len(field)
- if l > 255 {
- return nil, errStringTooLong
- }
- msg = append(msg, byte(l))
- msg = append(msg, field...)
-
- return msg, nil
-}
-
-func unpackText(msg []byte, off int) (string, int, error) {
- if off >= len(msg) {
- return "", off, errBaseLen
- }
- beginOff := off + 1
- endOff := beginOff + int(msg[off])
- if endOff > len(msg) {
- return "", off, errCalcLen
- }
- return string(msg[beginOff:endOff]), endOff, nil
-}
-
-// packBytes appends the wire format of field to msg.
-func packBytes(msg []byte, field []byte) []byte {
- return append(msg, field...)
-}
-
-func unpackBytes(msg []byte, off int, field []byte) (int, error) {
- newOff := off + len(field)
- if newOff > len(msg) {
- return off, errBaseLen
- }
- copy(field, msg[off:newOff])
- return newOff, nil
-}
-
-const nameLen = 255
-
-// A Name is a non-encoded domain name. It is used instead of strings to avoid
-// allocations.
-type Name struct {
- Data [nameLen]byte // 255 bytes
- Length uint8
-}
-
-// NewName creates a new Name from a string.
-func NewName(name string) (Name, error) {
- if len(name) > nameLen {
- return Name{}, errCalcLen
- }
- n := Name{Length: uint8(len(name))}
- copy(n.Data[:], name)
- return n, nil
-}
-
-// MustNewName creates a new Name from a string and panics on error.
-func MustNewName(name string) Name {
- n, err := NewName(name)
- if err != nil {
- panic("creating name: " + err.Error())
- }
- return n
-}
-
-// String implements fmt.Stringer.String.
-func (n Name) String() string {
- return string(n.Data[:n.Length])
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (n *Name) GoString() string {
- return `dnsmessage.MustNewName("` + printString(n.Data[:n.Length]) + `")`
-}
-
-// pack appends the wire format of the Name to msg.
-//
-// Domain names are a sequence of counted strings split at the dots. They end
-// with a zero-length string. Compression can be used to reuse domain suffixes.
-//
-// The compression map will be updated with new domain suffixes. If compression
-// is nil, compression will not be used.
-func (n *Name) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- oldMsg := msg
-
- // Add a trailing dot to canonicalize name.
- if n.Length == 0 || n.Data[n.Length-1] != '.' {
- return oldMsg, errNonCanonicalName
- }
-
- // Allow root domain.
- if n.Data[0] == '.' && n.Length == 1 {
- return append(msg, 0), nil
- }
-
- // Emit sequence of counted strings, chopping at dots.
- for i, begin := 0, 0; i < int(n.Length); i++ {
- // Check for the end of the segment.
- if n.Data[i] == '.' {
- // The two most significant bits have special meaning.
- // It isn't allowed for segments to be long enough to
- // need them.
- if i-begin >= 1<<6 {
- return oldMsg, errSegTooLong
- }
-
- // Segments must have a non-zero length.
- if i-begin == 0 {
- return oldMsg, errZeroSegLen
- }
-
- msg = append(msg, byte(i-begin))
-
- for j := begin; j < i; j++ {
- msg = append(msg, n.Data[j])
- }
-
- begin = i + 1
- continue
- }
-
- // We can only compress domain suffixes starting with a new
- // segment. A pointer is two bytes with the two most significant
- // bits set to 1 to indicate that it is a pointer.
- if (i == 0 || n.Data[i-1] == '.') && compression != nil {
- if ptr, ok := compression[string(n.Data[i:])]; ok {
- // Hit. Emit a pointer instead of the rest of
- // the domain.
- return append(msg, byte(ptr>>8|0xC0), byte(ptr)), nil
- }
-
- // Miss. Add the suffix to the compression table if the
- // offset can be stored in the available 14 bytes.
- if len(msg) <= int(^uint16(0)>>2) {
- compression[string(n.Data[i:])] = len(msg) - compressionOff
- }
- }
- }
- return append(msg, 0), nil
-}
-
-// unpack unpacks a domain name.
-func (n *Name) unpack(msg []byte, off int) (int, error) {
- return n.unpackCompressed(msg, off, true /* allowCompression */)
-}
-
-func (n *Name) unpackCompressed(msg []byte, off int, allowCompression bool) (int, error) {
- // currOff is the current working offset.
- currOff := off
-
- // newOff is the offset where the next record will start. Pointers lead
- // to data that belongs to other names and thus doesn't count towards to
- // the usage of this name.
- newOff := off
-
- // ptr is the number of pointers followed.
- var ptr int
-
- // Name is a slice representation of the name data.
- name := n.Data[:0]
-
-Loop:
- for {
- if currOff >= len(msg) {
- return off, errBaseLen
- }
- c := int(msg[currOff])
- currOff++
- switch c & 0xC0 {
- case 0x00: // String segment
- if c == 0x00 {
- // A zero length signals the end of the name.
- break Loop
- }
- endOff := currOff + c
- if endOff > len(msg) {
- return off, errCalcLen
- }
- name = append(name, msg[currOff:endOff]...)
- name = append(name, '.')
- currOff = endOff
- case 0xC0: // Pointer
- if !allowCompression {
- return off, errCompressedSRV
- }
- if currOff >= len(msg) {
- return off, errInvalidPtr
- }
- c1 := msg[currOff]
- currOff++
- if ptr == 0 {
- newOff = currOff
- }
- // Don't follow too many pointers, maybe there's a loop.
- if ptr++; ptr > 10 {
- return off, errTooManyPtr
- }
- currOff = (c^0xC0)<<8 | int(c1)
- default:
- // Prefixes 0x80 and 0x40 are reserved.
- return off, errReserved
- }
- }
- if len(name) == 0 {
- name = append(name, '.')
- }
- if len(name) > len(n.Data) {
- return off, errCalcLen
- }
- n.Length = uint8(len(name))
- if ptr == 0 {
- newOff = currOff
- }
- return newOff, nil
-}
-
-func skipName(msg []byte, off int) (int, error) {
- // newOff is the offset where the next record will start. Pointers lead
- // to data that belongs to other names and thus doesn't count towards to
- // the usage of this name.
- newOff := off
-
-Loop:
- for {
- if newOff >= len(msg) {
- return off, errBaseLen
- }
- c := int(msg[newOff])
- newOff++
- switch c & 0xC0 {
- case 0x00:
- if c == 0x00 {
- // A zero length signals the end of the name.
- break Loop
- }
- // literal string
- newOff += c
- if newOff > len(msg) {
- return off, errCalcLen
- }
- case 0xC0:
- // Pointer to somewhere else in msg.
-
- // Pointers are two bytes.
- newOff++
-
- // Don't follow the pointer as the data here has ended.
- break Loop
- default:
- // Prefixes 0x80 and 0x40 are reserved.
- return off, errReserved
- }
- }
-
- return newOff, nil
-}
-
-// A Question is a DNS query.
-type Question struct {
- Name Name
- Type Type
- Class Class
-}
-
-// pack appends the wire format of the Question to msg.
-func (q *Question) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- msg, err := q.Name.pack(msg, compression, compressionOff)
- if err != nil {
- return msg, &nestedError{"Name", err}
- }
- msg = packType(msg, q.Type)
- return packClass(msg, q.Class), nil
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (q *Question) GoString() string {
- return "dnsmessage.Question{" +
- "Name: " + q.Name.GoString() + ", " +
- "Type: " + q.Type.GoString() + ", " +
- "Class: " + q.Class.GoString() + "}"
-}
-
-func unpackResourceBody(msg []byte, off int, hdr ResourceHeader) (ResourceBody, int, error) {
- var (
- r ResourceBody
- err error
- name string
- )
- switch hdr.Type {
- case TypeA:
- var rb AResource
- rb, err = unpackAResource(msg, off)
- r = &rb
- name = "A"
- case TypeNS:
- var rb NSResource
- rb, err = unpackNSResource(msg, off)
- r = &rb
- name = "NS"
- case TypeCNAME:
- var rb CNAMEResource
- rb, err = unpackCNAMEResource(msg, off)
- r = &rb
- name = "CNAME"
- case TypeSOA:
- var rb SOAResource
- rb, err = unpackSOAResource(msg, off)
- r = &rb
- name = "SOA"
- case TypePTR:
- var rb PTRResource
- rb, err = unpackPTRResource(msg, off)
- r = &rb
- name = "PTR"
- case TypeMX:
- var rb MXResource
- rb, err = unpackMXResource(msg, off)
- r = &rb
- name = "MX"
- case TypeTXT:
- var rb TXTResource
- rb, err = unpackTXTResource(msg, off, hdr.Length)
- r = &rb
- name = "TXT"
- case TypeAAAA:
- var rb AAAAResource
- rb, err = unpackAAAAResource(msg, off)
- r = &rb
- name = "AAAA"
- case TypeSRV:
- var rb SRVResource
- rb, err = unpackSRVResource(msg, off)
- r = &rb
- name = "SRV"
- case TypeOPT:
- var rb OPTResource
- rb, err = unpackOPTResource(msg, off, hdr.Length)
- r = &rb
- name = "OPT"
- default:
- var rb UnknownResource
- rb, err = unpackUnknownResource(hdr.Type, msg, off, hdr.Length)
- r = &rb
- name = "Unknown"
- }
- if err != nil {
- return nil, off, &nestedError{name + " record", err}
- }
- return r, off + int(hdr.Length), nil
-}
-
-// A CNAMEResource is a CNAME Resource record.
-type CNAMEResource struct {
- CNAME Name
-}
-
-func (r *CNAMEResource) realType() Type {
- return TypeCNAME
-}
-
-// pack appends the wire format of the CNAMEResource to msg.
-func (r *CNAMEResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- return r.CNAME.pack(msg, compression, compressionOff)
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (r *CNAMEResource) GoString() string {
- return "dnsmessage.CNAMEResource{CNAME: " + r.CNAME.GoString() + "}"
-}
-
-func unpackCNAMEResource(msg []byte, off int) (CNAMEResource, error) {
- var cname Name
- if _, err := cname.unpack(msg, off); err != nil {
- return CNAMEResource{}, err
- }
- return CNAMEResource{cname}, nil
-}
-
-// An MXResource is an MX Resource record.
-type MXResource struct {
- Pref uint16
- MX Name
-}
-
-func (r *MXResource) realType() Type {
- return TypeMX
-}
-
-// pack appends the wire format of the MXResource to msg.
-func (r *MXResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- oldMsg := msg
- msg = packUint16(msg, r.Pref)
- msg, err := r.MX.pack(msg, compression, compressionOff)
- if err != nil {
- return oldMsg, &nestedError{"MXResource.MX", err}
- }
- return msg, nil
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (r *MXResource) GoString() string {
- return "dnsmessage.MXResource{" +
- "Pref: " + printUint16(r.Pref) + ", " +
- "MX: " + r.MX.GoString() + "}"
-}
-
-func unpackMXResource(msg []byte, off int) (MXResource, error) {
- pref, off, err := unpackUint16(msg, off)
- if err != nil {
- return MXResource{}, &nestedError{"Pref", err}
- }
- var mx Name
- if _, err := mx.unpack(msg, off); err != nil {
- return MXResource{}, &nestedError{"MX", err}
- }
- return MXResource{pref, mx}, nil
-}
-
-// An NSResource is an NS Resource record.
-type NSResource struct {
- NS Name
-}
-
-func (r *NSResource) realType() Type {
- return TypeNS
-}
-
-// pack appends the wire format of the NSResource to msg.
-func (r *NSResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- return r.NS.pack(msg, compression, compressionOff)
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (r *NSResource) GoString() string {
- return "dnsmessage.NSResource{NS: " + r.NS.GoString() + "}"
-}
-
-func unpackNSResource(msg []byte, off int) (NSResource, error) {
- var ns Name
- if _, err := ns.unpack(msg, off); err != nil {
- return NSResource{}, err
- }
- return NSResource{ns}, nil
-}
-
-// A PTRResource is a PTR Resource record.
-type PTRResource struct {
- PTR Name
-}
-
-func (r *PTRResource) realType() Type {
- return TypePTR
-}
-
-// pack appends the wire format of the PTRResource to msg.
-func (r *PTRResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- return r.PTR.pack(msg, compression, compressionOff)
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (r *PTRResource) GoString() string {
- return "dnsmessage.PTRResource{PTR: " + r.PTR.GoString() + "}"
-}
-
-func unpackPTRResource(msg []byte, off int) (PTRResource, error) {
- var ptr Name
- if _, err := ptr.unpack(msg, off); err != nil {
- return PTRResource{}, err
- }
- return PTRResource{ptr}, nil
-}
-
-// An SOAResource is an SOA Resource record.
-type SOAResource struct {
- NS Name
- MBox Name
- Serial uint32
- Refresh uint32
- Retry uint32
- Expire uint32
-
- // MinTTL the is the default TTL of Resources records which did not
- // contain a TTL value and the TTL of negative responses. (RFC 2308
- // Section 4)
- MinTTL uint32
-}
-
-func (r *SOAResource) realType() Type {
- return TypeSOA
-}
-
-// pack appends the wire format of the SOAResource to msg.
-func (r *SOAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- oldMsg := msg
- msg, err := r.NS.pack(msg, compression, compressionOff)
- if err != nil {
- return oldMsg, &nestedError{"SOAResource.NS", err}
- }
- msg, err = r.MBox.pack(msg, compression, compressionOff)
- if err != nil {
- return oldMsg, &nestedError{"SOAResource.MBox", err}
- }
- msg = packUint32(msg, r.Serial)
- msg = packUint32(msg, r.Refresh)
- msg = packUint32(msg, r.Retry)
- msg = packUint32(msg, r.Expire)
- return packUint32(msg, r.MinTTL), nil
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (r *SOAResource) GoString() string {
- return "dnsmessage.SOAResource{" +
- "NS: " + r.NS.GoString() + ", " +
- "MBox: " + r.MBox.GoString() + ", " +
- "Serial: " + printUint32(r.Serial) + ", " +
- "Refresh: " + printUint32(r.Refresh) + ", " +
- "Retry: " + printUint32(r.Retry) + ", " +
- "Expire: " + printUint32(r.Expire) + ", " +
- "MinTTL: " + printUint32(r.MinTTL) + "}"
-}
-
-func unpackSOAResource(msg []byte, off int) (SOAResource, error) {
- var ns Name
- off, err := ns.unpack(msg, off)
- if err != nil {
- return SOAResource{}, &nestedError{"NS", err}
- }
- var mbox Name
- if off, err = mbox.unpack(msg, off); err != nil {
- return SOAResource{}, &nestedError{"MBox", err}
- }
- serial, off, err := unpackUint32(msg, off)
- if err != nil {
- return SOAResource{}, &nestedError{"Serial", err}
- }
- refresh, off, err := unpackUint32(msg, off)
- if err != nil {
- return SOAResource{}, &nestedError{"Refresh", err}
- }
- retry, off, err := unpackUint32(msg, off)
- if err != nil {
- return SOAResource{}, &nestedError{"Retry", err}
- }
- expire, off, err := unpackUint32(msg, off)
- if err != nil {
- return SOAResource{}, &nestedError{"Expire", err}
- }
- minTTL, _, err := unpackUint32(msg, off)
- if err != nil {
- return SOAResource{}, &nestedError{"MinTTL", err}
- }
- return SOAResource{ns, mbox, serial, refresh, retry, expire, minTTL}, nil
-}
-
-// A TXTResource is a TXT Resource record.
-type TXTResource struct {
- TXT []string
-}
-
-func (r *TXTResource) realType() Type {
- return TypeTXT
-}
-
-// pack appends the wire format of the TXTResource to msg.
-func (r *TXTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- oldMsg := msg
- for _, s := range r.TXT {
- var err error
- msg, err = packText(msg, s)
- if err != nil {
- return oldMsg, err
- }
- }
- return msg, nil
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (r *TXTResource) GoString() string {
- s := "dnsmessage.TXTResource{TXT: []string{"
- if len(r.TXT) == 0 {
- return s + "}}"
- }
- s += `"` + printString([]byte(r.TXT[0]))
- for _, t := range r.TXT[1:] {
- s += `", "` + printString([]byte(t))
- }
- return s + `"}}`
-}
-
-func unpackTXTResource(msg []byte, off int, length uint16) (TXTResource, error) {
- txts := make([]string, 0, 1)
- for n := uint16(0); n < length; {
- var t string
- var err error
- if t, off, err = unpackText(msg, off); err != nil {
- return TXTResource{}, &nestedError{"text", err}
- }
- // Check if we got too many bytes.
- if length-n < uint16(len(t))+1 {
- return TXTResource{}, errCalcLen
- }
- n += uint16(len(t)) + 1
- txts = append(txts, t)
- }
- return TXTResource{txts}, nil
-}
-
-// An SRVResource is an SRV Resource record.
-type SRVResource struct {
- Priority uint16
- Weight uint16
- Port uint16
- Target Name // Not compressed as per RFC 2782.
-}
-
-func (r *SRVResource) realType() Type {
- return TypeSRV
-}
-
-// pack appends the wire format of the SRVResource to msg.
-func (r *SRVResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- oldMsg := msg
- msg = packUint16(msg, r.Priority)
- msg = packUint16(msg, r.Weight)
- msg = packUint16(msg, r.Port)
- msg, err := r.Target.pack(msg, nil, compressionOff)
- if err != nil {
- return oldMsg, &nestedError{"SRVResource.Target", err}
- }
- return msg, nil
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (r *SRVResource) GoString() string {
- return "dnsmessage.SRVResource{" +
- "Priority: " + printUint16(r.Priority) + ", " +
- "Weight: " + printUint16(r.Weight) + ", " +
- "Port: " + printUint16(r.Port) + ", " +
- "Target: " + r.Target.GoString() + "}"
-}
-
-func unpackSRVResource(msg []byte, off int) (SRVResource, error) {
- priority, off, err := unpackUint16(msg, off)
- if err != nil {
- return SRVResource{}, &nestedError{"Priority", err}
- }
- weight, off, err := unpackUint16(msg, off)
- if err != nil {
- return SRVResource{}, &nestedError{"Weight", err}
- }
- port, off, err := unpackUint16(msg, off)
- if err != nil {
- return SRVResource{}, &nestedError{"Port", err}
- }
- var target Name
- if _, err := target.unpackCompressed(msg, off, false /* allowCompression */); err != nil {
- return SRVResource{}, &nestedError{"Target", err}
- }
- return SRVResource{priority, weight, port, target}, nil
-}
-
-// An AResource is an A Resource record.
-type AResource struct {
- A [4]byte
-}
-
-func (r *AResource) realType() Type {
- return TypeA
-}
-
-// pack appends the wire format of the AResource to msg.
-func (r *AResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- return packBytes(msg, r.A[:]), nil
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (r *AResource) GoString() string {
- return "dnsmessage.AResource{" +
- "A: [4]byte{" + printByteSlice(r.A[:]) + "}}"
-}
-
-func unpackAResource(msg []byte, off int) (AResource, error) {
- var a [4]byte
- if _, err := unpackBytes(msg, off, a[:]); err != nil {
- return AResource{}, err
- }
- return AResource{a}, nil
-}
-
-// An AAAAResource is an AAAA Resource record.
-type AAAAResource struct {
- AAAA [16]byte
-}
-
-func (r *AAAAResource) realType() Type {
- return TypeAAAA
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (r *AAAAResource) GoString() string {
- return "dnsmessage.AAAAResource{" +
- "AAAA: [16]byte{" + printByteSlice(r.AAAA[:]) + "}}"
-}
-
-// pack appends the wire format of the AAAAResource to msg.
-func (r *AAAAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- return packBytes(msg, r.AAAA[:]), nil
-}
-
-func unpackAAAAResource(msg []byte, off int) (AAAAResource, error) {
- var aaaa [16]byte
- if _, err := unpackBytes(msg, off, aaaa[:]); err != nil {
- return AAAAResource{}, err
- }
- return AAAAResource{aaaa}, nil
-}
-
-// An OPTResource is an OPT pseudo Resource record.
-//
-// The pseudo resource record is part of the extension mechanisms for DNS
-// as defined in RFC 6891.
-type OPTResource struct {
- Options []Option
-}
-
-// An Option represents a DNS message option within OPTResource.
-//
-// The message option is part of the extension mechanisms for DNS as
-// defined in RFC 6891.
-type Option struct {
- Code uint16 // option code
- Data []byte
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (o *Option) GoString() string {
- return "dnsmessage.Option{" +
- "Code: " + printUint16(o.Code) + ", " +
- "Data: []byte{" + printByteSlice(o.Data) + "}}"
-}
-
-func (r *OPTResource) realType() Type {
- return TypeOPT
-}
-
-func (r *OPTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- for _, opt := range r.Options {
- msg = packUint16(msg, opt.Code)
- l := uint16(len(opt.Data))
- msg = packUint16(msg, l)
- msg = packBytes(msg, opt.Data)
- }
- return msg, nil
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (r *OPTResource) GoString() string {
- s := "dnsmessage.OPTResource{Options: []dnsmessage.Option{"
- if len(r.Options) == 0 {
- return s + "}}"
- }
- s += r.Options[0].GoString()
- for _, o := range r.Options[1:] {
- s += ", " + o.GoString()
- }
- return s + "}}"
-}
-
-func unpackOPTResource(msg []byte, off int, length uint16) (OPTResource, error) {
- var opts []Option
- for oldOff := off; off < oldOff+int(length); {
- var err error
- var o Option
- o.Code, off, err = unpackUint16(msg, off)
- if err != nil {
- return OPTResource{}, &nestedError{"Code", err}
- }
- var l uint16
- l, off, err = unpackUint16(msg, off)
- if err != nil {
- return OPTResource{}, &nestedError{"Data", err}
- }
- o.Data = make([]byte, l)
- if copy(o.Data, msg[off:]) != int(l) {
- return OPTResource{}, &nestedError{"Data", errCalcLen}
- }
- off += int(l)
- opts = append(opts, o)
- }
- return OPTResource{opts}, nil
-}
-
-// An UnknownResource is a catch-all container for unknown record types.
-type UnknownResource struct {
- Type Type
- Data []byte
-}
-
-func (r *UnknownResource) realType() Type {
- return r.Type
-}
-
-// pack appends the wire format of the UnknownResource to msg.
-func (r *UnknownResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
- return packBytes(msg, r.Data[:]), nil
-}
-
-// GoString implements fmt.GoStringer.GoString.
-func (r *UnknownResource) GoString() string {
- return "dnsmessage.UnknownResource{" +
- "Type: " + r.Type.GoString() + ", " +
- "Data: []byte{" + printByteSlice(r.Data) + "}}"
-}
-
-func unpackUnknownResource(recordType Type, msg []byte, off int, length uint16) (UnknownResource, error) {
- parsed := UnknownResource{
- Type: recordType,
- Data: make([]byte, length),
- }
- if _, err := unpackBytes(msg, off, parsed.Data); err != nil {
- return UnknownResource{}, err
- }
- return parsed, nil
-}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/dns/dnsmessage/ya.make b/contrib/go/_std_1.20/src/vendor/golang.org/x/net/dns/dnsmessage/ya.make
deleted file mode 100644
index 1d67de6dc2..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/dns/dnsmessage/ya.make
+++ /dev/null
@@ -1,7 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- message.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/hpack.go b/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/hpack.go
deleted file mode 100644
index fe52df95e8..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/hpack.go
+++ /dev/null
@@ -1,523 +0,0 @@
-// Copyright 2014 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 hpack implements HPACK, a compression format for
-// efficiently representing HTTP header fields in the context of HTTP/2.
-//
-// See http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09
-package hpack
-
-import (
- "bytes"
- "errors"
- "fmt"
-)
-
-// A DecodingError is something the spec defines as a decoding error.
-type DecodingError struct {
- Err error
-}
-
-func (de DecodingError) Error() string {
- return fmt.Sprintf("decoding error: %v", de.Err)
-}
-
-// An InvalidIndexError is returned when an encoder references a table
-// entry before the static table or after the end of the dynamic table.
-type InvalidIndexError int
-
-func (e InvalidIndexError) Error() string {
- return fmt.Sprintf("invalid indexed representation index %d", int(e))
-}
-
-// A HeaderField is a name-value pair. Both the name and value are
-// treated as opaque sequences of octets.
-type HeaderField struct {
- Name, Value string
-
- // Sensitive means that this header field should never be
- // indexed.
- Sensitive bool
-}
-
-// IsPseudo reports whether the header field is an http2 pseudo header.
-// That is, it reports whether it starts with a colon.
-// It is not otherwise guaranteed to be a valid pseudo header field,
-// though.
-func (hf HeaderField) IsPseudo() bool {
- return len(hf.Name) != 0 && hf.Name[0] == ':'
-}
-
-func (hf HeaderField) String() string {
- var suffix string
- if hf.Sensitive {
- suffix = " (sensitive)"
- }
- return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix)
-}
-
-// Size returns the size of an entry per RFC 7541 section 4.1.
-func (hf HeaderField) Size() uint32 {
- // https://httpwg.org/specs/rfc7541.html#rfc.section.4.1
- // "The size of the dynamic table is the sum of the size of
- // its entries. The size of an entry is the sum of its name's
- // length in octets (as defined in Section 5.2), its value's
- // length in octets (see Section 5.2), plus 32. The size of
- // an entry is calculated using the length of the name and
- // value without any Huffman encoding applied."
-
- // This can overflow if somebody makes a large HeaderField
- // Name and/or Value by hand, but we don't care, because that
- // won't happen on the wire because the encoding doesn't allow
- // it.
- return uint32(len(hf.Name) + len(hf.Value) + 32)
-}
-
-// A Decoder is the decoding context for incremental processing of
-// header blocks.
-type Decoder struct {
- dynTab dynamicTable
- emit func(f HeaderField)
-
- emitEnabled bool // whether calls to emit are enabled
- maxStrLen int // 0 means unlimited
-
- // buf is the unparsed buffer. It's only written to
- // saveBuf if it was truncated in the middle of a header
- // block. Because it's usually not owned, we can only
- // process it under Write.
- buf []byte // not owned; only valid during Write
-
- // saveBuf is previous data passed to Write which we weren't able
- // to fully parse before. Unlike buf, we own this data.
- saveBuf bytes.Buffer
-
- firstField bool // processing the first field of the header block
-}
-
-// NewDecoder returns a new decoder with the provided maximum dynamic
-// table size. The emitFunc will be called for each valid field
-// parsed, in the same goroutine as calls to Write, before Write returns.
-func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder {
- d := &Decoder{
- emit: emitFunc,
- emitEnabled: true,
- firstField: true,
- }
- d.dynTab.table.init()
- d.dynTab.allowedMaxSize = maxDynamicTableSize
- d.dynTab.setMaxSize(maxDynamicTableSize)
- return d
-}
-
-// ErrStringLength is returned by Decoder.Write when the max string length
-// (as configured by Decoder.SetMaxStringLength) would be violated.
-var ErrStringLength = errors.New("hpack: string too long")
-
-// SetMaxStringLength sets the maximum size of a HeaderField name or
-// value string. If a string exceeds this length (even after any
-// decompression), Write will return ErrStringLength.
-// A value of 0 means unlimited and is the default from NewDecoder.
-func (d *Decoder) SetMaxStringLength(n int) {
- d.maxStrLen = n
-}
-
-// SetEmitFunc changes the callback used when new header fields
-// are decoded.
-// It must be non-nil. It does not affect EmitEnabled.
-func (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) {
- d.emit = emitFunc
-}
-
-// SetEmitEnabled controls whether the emitFunc provided to NewDecoder
-// should be called. The default is true.
-//
-// This facility exists to let servers enforce MAX_HEADER_LIST_SIZE
-// while still decoding and keeping in-sync with decoder state, but
-// without doing unnecessary decompression or generating unnecessary
-// garbage for header fields past the limit.
-func (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v }
-
-// EmitEnabled reports whether calls to the emitFunc provided to NewDecoder
-// are currently enabled. The default is true.
-func (d *Decoder) EmitEnabled() bool { return d.emitEnabled }
-
-// TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their
-// underlying buffers for garbage reasons.
-
-func (d *Decoder) SetMaxDynamicTableSize(v uint32) {
- d.dynTab.setMaxSize(v)
-}
-
-// SetAllowedMaxDynamicTableSize sets the upper bound that the encoded
-// stream (via dynamic table size updates) may set the maximum size
-// to.
-func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {
- d.dynTab.allowedMaxSize = v
-}
-
-type dynamicTable struct {
- // https://httpwg.org/specs/rfc7541.html#rfc.section.2.3.2
- table headerFieldTable
- size uint32 // in bytes
- maxSize uint32 // current maxSize
- allowedMaxSize uint32 // maxSize may go up to this, inclusive
-}
-
-func (dt *dynamicTable) setMaxSize(v uint32) {
- dt.maxSize = v
- dt.evict()
-}
-
-func (dt *dynamicTable) add(f HeaderField) {
- dt.table.addEntry(f)
- dt.size += f.Size()
- dt.evict()
-}
-
-// If we're too big, evict old stuff.
-func (dt *dynamicTable) evict() {
- var n int
- for dt.size > dt.maxSize && n < dt.table.len() {
- dt.size -= dt.table.ents[n].Size()
- n++
- }
- dt.table.evictOldest(n)
-}
-
-func (d *Decoder) maxTableIndex() int {
- // This should never overflow. RFC 7540 Section 6.5.2 limits the size of
- // the dynamic table to 2^32 bytes, where each entry will occupy more than
- // one byte. Further, the staticTable has a fixed, small length.
- return d.dynTab.table.len() + staticTable.len()
-}
-
-func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) {
- // See Section 2.3.3.
- if i == 0 {
- return
- }
- if i <= uint64(staticTable.len()) {
- return staticTable.ents[i-1], true
- }
- if i > uint64(d.maxTableIndex()) {
- return
- }
- // In the dynamic table, newer entries have lower indices.
- // However, dt.ents[0] is the oldest entry. Hence, dt.ents is
- // the reversed dynamic table.
- dt := d.dynTab.table
- return dt.ents[dt.len()-(int(i)-staticTable.len())], true
-}
-
-// Decode decodes an entire block.
-//
-// TODO: remove this method and make it incremental later? This is
-// easier for debugging now.
-func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {
- var hf []HeaderField
- saveFunc := d.emit
- defer func() { d.emit = saveFunc }()
- d.emit = func(f HeaderField) { hf = append(hf, f) }
- if _, err := d.Write(p); err != nil {
- return nil, err
- }
- if err := d.Close(); err != nil {
- return nil, err
- }
- return hf, nil
-}
-
-// Close declares that the decoding is complete and resets the Decoder
-// to be reused again for a new header block. If there is any remaining
-// data in the decoder's buffer, Close returns an error.
-func (d *Decoder) Close() error {
- if d.saveBuf.Len() > 0 {
- d.saveBuf.Reset()
- return DecodingError{errors.New("truncated headers")}
- }
- d.firstField = true
- return nil
-}
-
-func (d *Decoder) Write(p []byte) (n int, err error) {
- if len(p) == 0 {
- // Prevent state machine CPU attacks (making us redo
- // work up to the point of finding out we don't have
- // enough data)
- return
- }
- // Only copy the data if we have to. Optimistically assume
- // that p will contain a complete header block.
- if d.saveBuf.Len() == 0 {
- d.buf = p
- } else {
- d.saveBuf.Write(p)
- d.buf = d.saveBuf.Bytes()
- d.saveBuf.Reset()
- }
-
- for len(d.buf) > 0 {
- err = d.parseHeaderFieldRepr()
- if err == errNeedMore {
- // Extra paranoia, making sure saveBuf won't
- // get too large. All the varint and string
- // reading code earlier should already catch
- // overlong things and return ErrStringLength,
- // but keep this as a last resort.
- const varIntOverhead = 8 // conservative
- if d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) {
- return 0, ErrStringLength
- }
- d.saveBuf.Write(d.buf)
- return len(p), nil
- }
- d.firstField = false
- if err != nil {
- break
- }
- }
- return len(p), err
-}
-
-// errNeedMore is an internal sentinel error value that means the
-// buffer is truncated and we need to read more data before we can
-// continue parsing.
-var errNeedMore = errors.New("need more data")
-
-type indexType int
-
-const (
- indexedTrue indexType = iota
- indexedFalse
- indexedNever
-)
-
-func (v indexType) indexed() bool { return v == indexedTrue }
-func (v indexType) sensitive() bool { return v == indexedNever }
-
-// returns errNeedMore if there isn't enough data available.
-// any other error is fatal.
-// consumes d.buf iff it returns nil.
-// precondition: must be called with len(d.buf) > 0
-func (d *Decoder) parseHeaderFieldRepr() error {
- b := d.buf[0]
- switch {
- case b&128 != 0:
- // Indexed representation.
- // High bit set?
- // https://httpwg.org/specs/rfc7541.html#rfc.section.6.1
- return d.parseFieldIndexed()
- case b&192 == 64:
- // 6.2.1 Literal Header Field with Incremental Indexing
- // 0b10xxxxxx: top two bits are 10
- // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1
- return d.parseFieldLiteral(6, indexedTrue)
- case b&240 == 0:
- // 6.2.2 Literal Header Field without Indexing
- // 0b0000xxxx: top four bits are 0000
- // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2
- return d.parseFieldLiteral(4, indexedFalse)
- case b&240 == 16:
- // 6.2.3 Literal Header Field never Indexed
- // 0b0001xxxx: top four bits are 0001
- // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3
- return d.parseFieldLiteral(4, indexedNever)
- case b&224 == 32:
- // 6.3 Dynamic Table Size Update
- // Top three bits are '001'.
- // https://httpwg.org/specs/rfc7541.html#rfc.section.6.3
- return d.parseDynamicTableSizeUpdate()
- }
-
- return DecodingError{errors.New("invalid encoding")}
-}
-
-// (same invariants and behavior as parseHeaderFieldRepr)
-func (d *Decoder) parseFieldIndexed() error {
- buf := d.buf
- idx, buf, err := readVarInt(7, buf)
- if err != nil {
- return err
- }
- hf, ok := d.at(idx)
- if !ok {
- return DecodingError{InvalidIndexError(idx)}
- }
- d.buf = buf
- return d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value})
-}
-
-// (same invariants and behavior as parseHeaderFieldRepr)
-func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
- buf := d.buf
- nameIdx, buf, err := readVarInt(n, buf)
- if err != nil {
- return err
- }
-
- var hf HeaderField
- wantStr := d.emitEnabled || it.indexed()
- var undecodedName undecodedString
- if nameIdx > 0 {
- ihf, ok := d.at(nameIdx)
- if !ok {
- return DecodingError{InvalidIndexError(nameIdx)}
- }
- hf.Name = ihf.Name
- } else {
- undecodedName, buf, err = d.readString(buf)
- if err != nil {
- return err
- }
- }
- undecodedValue, buf, err := d.readString(buf)
- if err != nil {
- return err
- }
- if wantStr {
- if nameIdx <= 0 {
- hf.Name, err = d.decodeString(undecodedName)
- if err != nil {
- return err
- }
- }
- hf.Value, err = d.decodeString(undecodedValue)
- if err != nil {
- return err
- }
- }
- d.buf = buf
- if it.indexed() {
- d.dynTab.add(hf)
- }
- hf.Sensitive = it.sensitive()
- return d.callEmit(hf)
-}
-
-func (d *Decoder) callEmit(hf HeaderField) error {
- if d.maxStrLen != 0 {
- if len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen {
- return ErrStringLength
- }
- }
- if d.emitEnabled {
- d.emit(hf)
- }
- return nil
-}
-
-// (same invariants and behavior as parseHeaderFieldRepr)
-func (d *Decoder) parseDynamicTableSizeUpdate() error {
- // RFC 7541, sec 4.2: This dynamic table size update MUST occur at the
- // beginning of the first header block following the change to the dynamic table size.
- if !d.firstField && d.dynTab.size > 0 {
- return DecodingError{errors.New("dynamic table size update MUST occur at the beginning of a header block")}
- }
-
- buf := d.buf
- size, buf, err := readVarInt(5, buf)
- if err != nil {
- return err
- }
- if size > uint64(d.dynTab.allowedMaxSize) {
- return DecodingError{errors.New("dynamic table size update too large")}
- }
- d.dynTab.setMaxSize(uint32(size))
- d.buf = buf
- return nil
-}
-
-var errVarintOverflow = DecodingError{errors.New("varint integer overflow")}
-
-// readVarInt reads an unsigned variable length integer off the
-// beginning of p. n is the parameter as described in
-// https://httpwg.org/specs/rfc7541.html#rfc.section.5.1.
-//
-// n must always be between 1 and 8.
-//
-// The returned remain buffer is either a smaller suffix of p, or err != nil.
-// The error is errNeedMore if p doesn't contain a complete integer.
-func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {
- if n < 1 || n > 8 {
- panic("bad n")
- }
- if len(p) == 0 {
- return 0, p, errNeedMore
- }
- i = uint64(p[0])
- if n < 8 {
- i &= (1 << uint64(n)) - 1
- }
- if i < (1<<uint64(n))-1 {
- return i, p[1:], nil
- }
-
- origP := p
- p = p[1:]
- var m uint64
- for len(p) > 0 {
- b := p[0]
- p = p[1:]
- i += uint64(b&127) << m
- if b&128 == 0 {
- return i, p, nil
- }
- m += 7
- if m >= 63 { // TODO: proper overflow check. making this up.
- return 0, origP, errVarintOverflow
- }
- }
- return 0, origP, errNeedMore
-}
-
-// readString reads an hpack string from p.
-//
-// It returns a reference to the encoded string data to permit deferring decode costs
-// until after the caller verifies all data is present.
-func (d *Decoder) readString(p []byte) (u undecodedString, remain []byte, err error) {
- if len(p) == 0 {
- return u, p, errNeedMore
- }
- isHuff := p[0]&128 != 0
- strLen, p, err := readVarInt(7, p)
- if err != nil {
- return u, p, err
- }
- if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {
- // Returning an error here means Huffman decoding errors
- // for non-indexed strings past the maximum string length
- // are ignored, but the server is returning an error anyway
- // and because the string is not indexed the error will not
- // affect the decoding state.
- return u, nil, ErrStringLength
- }
- if uint64(len(p)) < strLen {
- return u, p, errNeedMore
- }
- u.isHuff = isHuff
- u.b = p[:strLen]
- return u, p[strLen:], nil
-}
-
-type undecodedString struct {
- isHuff bool
- b []byte
-}
-
-func (d *Decoder) decodeString(u undecodedString) (string, error) {
- if !u.isHuff {
- return string(u.b), nil
- }
- buf := bufPool.Get().(*bytes.Buffer)
- buf.Reset() // don't trust others
- var s string
- err := huffmanDecode(buf, d.maxStrLen, u.b)
- if err == nil {
- s = buf.String()
- }
- buf.Reset() // be nice to GC
- bufPool.Put(buf)
- return s, err
-}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/tables13.0.0.go b/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/tables13.0.0.go
deleted file mode 100644
index 390c5e56d2..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/tables13.0.0.go
+++ /dev/null
@@ -1,4840 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-//go:build go1.16
-// +build go1.16
-
-package idna
-
-// UnicodeVersion is the Unicode version from which the tables in this package are derived.
-const UnicodeVersion = "13.0.0"
-
-var mappings string = "" + // Size: 8188 bytes
- "\x00\x01 \x03 ̈\x01a\x03 ̄\x012\x013\x03 ́\x03 ̧\x011\x01o\x051⁄4\x051⁄2" +
- "\x053⁄4\x03i̇\x03l·\x03ʼn\x01s\x03dž\x03ⱥ\x03ⱦ\x01h\x01j\x01r\x01w\x01y" +
- "\x03 ̆\x03 ̇\x03 ̊\x03 ̨\x03 ̃\x03 ̋\x01l\x01x\x04̈́\x03 ι\x01;\x05 ̈́" +
- "\x04եւ\x04اٴ\x04وٴ\x04ۇٴ\x04يٴ\x06क़\x06ख़\x06ग़\x06ज़\x06ड़\x06ढ़\x06फ़" +
- "\x06य़\x06ড়\x06ঢ়\x06য়\x06ਲ਼\x06ਸ਼\x06ਖ਼\x06ਗ਼\x06ਜ਼\x06ਫ਼\x06ଡ଼\x06ଢ଼" +
- "\x06ํา\x06ໍາ\x06ຫນ\x06ຫມ\x06གྷ\x06ཌྷ\x06དྷ\x06བྷ\x06ཛྷ\x06ཀྵ\x06ཱི\x06ཱུ" +
- "\x06ྲྀ\x09ྲཱྀ\x06ླྀ\x09ླཱྀ\x06ཱྀ\x06ྒྷ\x06ྜྷ\x06ྡྷ\x06ྦྷ\x06ྫྷ\x06ྐྵ\x02" +
- "в\x02д\x02о\x02с\x02т\x02ъ\x02ѣ\x02æ\x01b\x01d\x01e\x02ǝ\x01g\x01i\x01k" +
- "\x01m\x01n\x02ȣ\x01p\x01t\x01u\x02ɐ\x02ɑ\x02ə\x02ɛ\x02ɜ\x02ŋ\x02ɔ\x02ɯ" +
- "\x01v\x02β\x02γ\x02δ\x02φ\x02χ\x02ρ\x02н\x02ɒ\x01c\x02ɕ\x02ð\x01f\x02ɟ" +
- "\x02ɡ\x02ɥ\x02ɨ\x02ɩ\x02ɪ\x02ʝ\x02ɭ\x02ʟ\x02ɱ\x02ɰ\x02ɲ\x02ɳ\x02ɴ\x02ɵ" +
- "\x02ɸ\x02ʂ\x02ʃ\x02ƫ\x02ʉ\x02ʊ\x02ʋ\x02ʌ\x01z\x02ʐ\x02ʑ\x02ʒ\x02θ\x02ss" +
- "\x02ά\x02έ\x02ή\x02ί\x02ό\x02ύ\x02ώ\x05ἀι\x05ἁι\x05ἂι\x05ἃι\x05ἄι\x05ἅι" +
- "\x05ἆι\x05ἇι\x05ἠι\x05ἡι\x05ἢι\x05ἣι\x05ἤι\x05ἥι\x05ἦι\x05ἧι\x05ὠι\x05ὡι" +
- "\x05ὢι\x05ὣι\x05ὤι\x05ὥι\x05ὦι\x05ὧι\x05ὰι\x04αι\x04άι\x05ᾶι\x02ι\x05 ̈͂" +
- "\x05ὴι\x04ηι\x04ήι\x05ῆι\x05 ̓̀\x05 ̓́\x05 ̓͂\x02ΐ\x05 ̔̀\x05 ̔́\x05 ̔͂" +
- "\x02ΰ\x05 ̈̀\x01`\x05ὼι\x04ωι\x04ώι\x05ῶι\x06′′\x09′′′\x06‵‵\x09‵‵‵\x02!" +
- "!\x02??\x02?!\x02!?\x0c′′′′\x010\x014\x015\x016\x017\x018\x019\x01+\x01=" +
- "\x01(\x01)\x02rs\x02ħ\x02no\x01q\x02sm\x02tm\x02ω\x02å\x02א\x02ב\x02ג" +
- "\x02ד\x02π\x051⁄7\x051⁄9\x061⁄10\x051⁄3\x052⁄3\x051⁄5\x052⁄5\x053⁄5\x054" +
- "⁄5\x051⁄6\x055⁄6\x051⁄8\x053⁄8\x055⁄8\x057⁄8\x041⁄\x02ii\x02iv\x02vi" +
- "\x04viii\x02ix\x02xi\x050⁄3\x06∫∫\x09∫∫∫\x06∮∮\x09∮∮∮\x0210\x0211\x0212" +
- "\x0213\x0214\x0215\x0216\x0217\x0218\x0219\x0220\x04(10)\x04(11)\x04(12)" +
- "\x04(13)\x04(14)\x04(15)\x04(16)\x04(17)\x04(18)\x04(19)\x04(20)\x0c∫∫∫∫" +
- "\x02==\x05⫝̸\x02ɫ\x02ɽ\x02ȿ\x02ɀ\x01.\x04 ゙\x04 ゚\x06より\x06コト\x05(ᄀ)\x05" +
- "(ᄂ)\x05(ᄃ)\x05(ᄅ)\x05(ᄆ)\x05(ᄇ)\x05(ᄉ)\x05(ᄋ)\x05(ᄌ)\x05(ᄎ)\x05(ᄏ)\x05(ᄐ" +
- ")\x05(ᄑ)\x05(ᄒ)\x05(가)\x05(나)\x05(다)\x05(라)\x05(마)\x05(바)\x05(사)\x05(아)" +
- "\x05(자)\x05(차)\x05(카)\x05(타)\x05(파)\x05(하)\x05(주)\x08(오전)\x08(오후)\x05(一)" +
- "\x05(二)\x05(三)\x05(四)\x05(五)\x05(六)\x05(七)\x05(八)\x05(九)\x05(十)\x05(月)" +
- "\x05(火)\x05(水)\x05(木)\x05(金)\x05(土)\x05(日)\x05(株)\x05(有)\x05(社)\x05(名)" +
- "\x05(特)\x05(財)\x05(祝)\x05(労)\x05(代)\x05(呼)\x05(学)\x05(監)\x05(企)\x05(資)" +
- "\x05(協)\x05(祭)\x05(休)\x05(自)\x05(至)\x0221\x0222\x0223\x0224\x0225\x0226" +
- "\x0227\x0228\x0229\x0230\x0231\x0232\x0233\x0234\x0235\x06참고\x06주의\x0236" +
- "\x0237\x0238\x0239\x0240\x0241\x0242\x0243\x0244\x0245\x0246\x0247\x0248" +
- "\x0249\x0250\x041月\x042月\x043月\x044月\x045月\x046月\x047月\x048月\x049月\x0510" +
- "月\x0511月\x0512月\x02hg\x02ev\x06令和\x0cアパート\x0cアルファ\x0cアンペア\x09アール\x0cイニ" +
- "ング\x09インチ\x09ウォン\x0fエスクード\x0cエーカー\x09オンス\x09オーム\x09カイリ\x0cカラット\x0cカロリー" +
- "\x09ガロン\x09ガンマ\x06ギガ\x09ギニー\x0cキュリー\x0cギルダー\x06キロ\x0fキログラム\x12キロメートル\x0f" +
- "キロワット\x09グラム\x0fグラムトン\x0fクルゼイロ\x0cクローネ\x09ケース\x09コルナ\x09コーポ\x0cサイクル" +
- "\x0fサンチーム\x0cシリング\x09センチ\x09セント\x09ダース\x06デシ\x06ドル\x06トン\x06ナノ\x09ノット" +
- "\x09ハイツ\x0fパーセント\x09パーツ\x0cバーレル\x0fピアストル\x09ピクル\x06ピコ\x06ビル\x0fファラッド\x0c" +
- "フィート\x0fブッシェル\x09フラン\x0fヘクタール\x06ペソ\x09ペニヒ\x09ヘルツ\x09ペンス\x09ページ\x09ベータ" +
- "\x0cポイント\x09ボルト\x06ホン\x09ポンド\x09ホール\x09ホーン\x0cマイクロ\x09マイル\x09マッハ\x09マルク" +
- "\x0fマンション\x0cミクロン\x06ミリ\x0fミリバール\x06メガ\x0cメガトン\x0cメートル\x09ヤード\x09ヤール\x09" +
- "ユアン\x0cリットル\x06リラ\x09ルピー\x0cルーブル\x06レム\x0fレントゲン\x09ワット\x040点\x041点\x04" +
- "2点\x043点\x044点\x045点\x046点\x047点\x048点\x049点\x0510点\x0511点\x0512点\x0513点" +
- "\x0514点\x0515点\x0516点\x0517点\x0518点\x0519点\x0520点\x0521点\x0522点\x0523点" +
- "\x0524点\x02da\x02au\x02ov\x02pc\x02dm\x02iu\x06平成\x06昭和\x06大正\x06明治\x0c株" +
- "式会社\x02pa\x02na\x02ma\x02ka\x02kb\x02mb\x02gb\x04kcal\x02pf\x02nf\x02m" +
- "g\x02kg\x02hz\x02ml\x02dl\x02kl\x02fm\x02nm\x02mm\x02cm\x02km\x02m2\x02m" +
- "3\x05m∕s\x06m∕s2\x07rad∕s\x08rad∕s2\x02ps\x02ns\x02ms\x02pv\x02nv\x02mv" +
- "\x02kv\x02pw\x02nw\x02mw\x02kw\x02bq\x02cc\x02cd\x06c∕kg\x02db\x02gy\x02" +
- "ha\x02hp\x02in\x02kk\x02kt\x02lm\x02ln\x02lx\x02ph\x02pr\x02sr\x02sv\x02" +
- "wb\x05v∕m\x05a∕m\x041日\x042日\x043日\x044日\x045日\x046日\x047日\x048日\x049日" +
- "\x0510日\x0511日\x0512日\x0513日\x0514日\x0515日\x0516日\x0517日\x0518日\x0519日" +
- "\x0520日\x0521日\x0522日\x0523日\x0524日\x0525日\x0526日\x0527日\x0528日\x0529日" +
- "\x0530日\x0531日\x02ь\x02ɦ\x02ɬ\x02ʞ\x02ʇ\x02œ\x02ʍ\x04𤋮\x04𢡊\x04𢡄\x04𣏕" +
- "\x04𥉉\x04𥳐\x04𧻓\x02ff\x02fi\x02fl\x02st\x04մն\x04մե\x04մի\x04վն\x04մխ" +
- "\x04יִ\x04ײַ\x02ע\x02ה\x02כ\x02ל\x02ם\x02ר\x02ת\x04שׁ\x04שׂ\x06שּׁ\x06שּ" +
- "ׂ\x04אַ\x04אָ\x04אּ\x04בּ\x04גּ\x04דּ\x04הּ\x04וּ\x04זּ\x04טּ\x04יּ\x04" +
- "ךּ\x04כּ\x04לּ\x04מּ\x04נּ\x04סּ\x04ףּ\x04פּ\x04צּ\x04קּ\x04רּ\x04שּ" +
- "\x04תּ\x04וֹ\x04בֿ\x04כֿ\x04פֿ\x04אל\x02ٱ\x02ٻ\x02پ\x02ڀ\x02ٺ\x02ٿ\x02ٹ" +
- "\x02ڤ\x02ڦ\x02ڄ\x02ڃ\x02چ\x02ڇ\x02ڍ\x02ڌ\x02ڎ\x02ڈ\x02ژ\x02ڑ\x02ک\x02گ" +
- "\x02ڳ\x02ڱ\x02ں\x02ڻ\x02ۀ\x02ہ\x02ھ\x02ے\x02ۓ\x02ڭ\x02ۇ\x02ۆ\x02ۈ\x02ۋ" +
- "\x02ۅ\x02ۉ\x02ې\x02ى\x04ئا\x04ئە\x04ئو\x04ئۇ\x04ئۆ\x04ئۈ\x04ئې\x04ئى\x02" +
- "ی\x04ئج\x04ئح\x04ئم\x04ئي\x04بج\x04بح\x04بخ\x04بم\x04بى\x04بي\x04تج\x04" +
- "تح\x04تخ\x04تم\x04تى\x04تي\x04ثج\x04ثم\x04ثى\x04ثي\x04جح\x04جم\x04حج" +
- "\x04حم\x04خج\x04خح\x04خم\x04سج\x04سح\x04سخ\x04سم\x04صح\x04صم\x04ضج\x04ضح" +
- "\x04ضخ\x04ضم\x04طح\x04طم\x04ظم\x04عج\x04عم\x04غج\x04غم\x04فج\x04فح\x04فخ" +
- "\x04فم\x04فى\x04في\x04قح\x04قم\x04قى\x04قي\x04كا\x04كج\x04كح\x04كخ\x04كل" +
- "\x04كم\x04كى\x04كي\x04لج\x04لح\x04لخ\x04لم\x04لى\x04لي\x04مج\x04مح\x04مخ" +
- "\x04مم\x04مى\x04مي\x04نج\x04نح\x04نخ\x04نم\x04نى\x04ني\x04هج\x04هم\x04هى" +
- "\x04هي\x04يج\x04يح\x04يخ\x04يم\x04يى\x04يي\x04ذٰ\x04رٰ\x04ىٰ\x05 ٌّ\x05 " +
- "ٍّ\x05 َّ\x05 ُّ\x05 ِّ\x05 ّٰ\x04ئر\x04ئز\x04ئن\x04بر\x04بز\x04بن\x04ت" +
- "ر\x04تز\x04تن\x04ثر\x04ثز\x04ثن\x04ما\x04نر\x04نز\x04نن\x04ير\x04يز\x04" +
- "ين\x04ئخ\x04ئه\x04به\x04ته\x04صخ\x04له\x04نه\x04هٰ\x04يه\x04ثه\x04سه" +
- "\x04شم\x04شه\x06ـَّ\x06ـُّ\x06ـِّ\x04طى\x04طي\x04عى\x04عي\x04غى\x04غي" +
- "\x04سى\x04سي\x04شى\x04شي\x04حى\x04حي\x04جى\x04جي\x04خى\x04خي\x04صى\x04صي" +
- "\x04ضى\x04ضي\x04شج\x04شح\x04شخ\x04شر\x04سر\x04صر\x04ضر\x04اً\x06تجم\x06ت" +
- "حج\x06تحم\x06تخم\x06تمج\x06تمح\x06تمخ\x06جمح\x06حمي\x06حمى\x06سحج\x06سج" +
- "ح\x06سجى\x06سمح\x06سمج\x06سمم\x06صحح\x06صمم\x06شحم\x06شجي\x06شمخ\x06شمم" +
- "\x06ضحى\x06ضخم\x06طمح\x06طمم\x06طمي\x06عجم\x06عمم\x06عمى\x06غمم\x06غمي" +
- "\x06غمى\x06فخم\x06قمح\x06قمم\x06لحم\x06لحي\x06لحى\x06لجج\x06لخم\x06لمح" +
- "\x06محج\x06محم\x06محي\x06مجح\x06مجم\x06مخج\x06مخم\x06مجخ\x06همج\x06همم" +
- "\x06نحم\x06نحى\x06نجم\x06نجى\x06نمي\x06نمى\x06يمم\x06بخي\x06تجي\x06تجى" +
- "\x06تخي\x06تخى\x06تمي\x06تمى\x06جمي\x06جحى\x06جمى\x06سخى\x06صحي\x06شحي" +
- "\x06ضحي\x06لجي\x06لمي\x06يحي\x06يجي\x06يمي\x06ممي\x06قمي\x06نحي\x06عمي" +
- "\x06كمي\x06نجح\x06مخي\x06لجم\x06كمم\x06جحي\x06حجي\x06مجي\x06فمي\x06بحي" +
- "\x06سخي\x06نجي\x06صلے\x06قلے\x08الله\x08اكبر\x08محمد\x08صلعم\x08رسول\x08" +
- "عليه\x08وسلم\x06صلى!صلى الله عليه وسلم\x0fجل جلاله\x08ریال\x01,\x01:" +
- "\x01!\x01?\x01_\x01{\x01}\x01[\x01]\x01#\x01&\x01*\x01-\x01<\x01>\x01\\" +
- "\x01$\x01%\x01@\x04ـً\x04ـَ\x04ـُ\x04ـِ\x04ـّ\x04ـْ\x02ء\x02آ\x02أ\x02ؤ" +
- "\x02إ\x02ئ\x02ا\x02ب\x02ة\x02ت\x02ث\x02ج\x02ح\x02خ\x02د\x02ذ\x02ر\x02ز" +
- "\x02س\x02ش\x02ص\x02ض\x02ط\x02ظ\x02ع\x02غ\x02ف\x02ق\x02ك\x02ل\x02م\x02ن" +
- "\x02ه\x02و\x02ي\x04لآ\x04لأ\x04لإ\x04لا\x01\x22\x01'\x01/\x01^\x01|\x01~" +
- "\x02¢\x02£\x02¬\x02¦\x02¥\x08𝅗𝅥\x08𝅘𝅥\x0c𝅘𝅥𝅮\x0c𝅘𝅥𝅯\x0c𝅘𝅥𝅰\x0c𝅘𝅥𝅱\x0c𝅘𝅥𝅲" +
- "\x08𝆹𝅥\x08𝆺𝅥\x0c𝆹𝅥𝅮\x0c𝆺𝅥𝅮\x0c𝆹𝅥𝅯\x0c𝆺𝅥𝅯\x02ı\x02ȷ\x02α\x02ε\x02ζ\x02η" +
- "\x02κ\x02λ\x02μ\x02ν\x02ξ\x02ο\x02σ\x02τ\x02υ\x02ψ\x03∇\x03∂\x02ϝ\x02ٮ" +
- "\x02ڡ\x02ٯ\x020,\x021,\x022,\x023,\x024,\x025,\x026,\x027,\x028,\x029," +
- "\x03(a)\x03(b)\x03(c)\x03(d)\x03(e)\x03(f)\x03(g)\x03(h)\x03(i)\x03(j)" +
- "\x03(k)\x03(l)\x03(m)\x03(n)\x03(o)\x03(p)\x03(q)\x03(r)\x03(s)\x03(t)" +
- "\x03(u)\x03(v)\x03(w)\x03(x)\x03(y)\x03(z)\x07〔s〕\x02wz\x02hv\x02sd\x03p" +
- "pv\x02wc\x02mc\x02md\x02mr\x02dj\x06ほか\x06ココ\x03サ\x03手\x03字\x03双\x03デ" +
- "\x03二\x03多\x03解\x03天\x03交\x03映\x03無\x03料\x03前\x03後\x03再\x03新\x03初\x03終" +
- "\x03生\x03販\x03声\x03吹\x03演\x03投\x03捕\x03一\x03三\x03遊\x03左\x03中\x03右\x03指" +
- "\x03走\x03打\x03禁\x03空\x03合\x03満\x03有\x03月\x03申\x03割\x03営\x03配\x09〔本〕\x09〔" +
- "三〕\x09〔二〕\x09〔安〕\x09〔点〕\x09〔打〕\x09〔盗〕\x09〔勝〕\x09〔敗〕\x03得\x03可\x03丽\x03" +
- "丸\x03乁\x03你\x03侮\x03侻\x03倂\x03偺\x03備\x03僧\x03像\x03㒞\x03免\x03兔\x03兤\x03" +
- "具\x03㒹\x03內\x03冗\x03冤\x03仌\x03冬\x03况\x03凵\x03刃\x03㓟\x03刻\x03剆\x03剷\x03" +
- "㔕\x03勇\x03勉\x03勤\x03勺\x03包\x03匆\x03北\x03卉\x03卑\x03博\x03即\x03卽\x03卿\x03" +
- "灰\x03及\x03叟\x03叫\x03叱\x03吆\x03咞\x03吸\x03呈\x03周\x03咢\x03哶\x03唐\x03啓\x03" +
- "啣\x03善\x03喙\x03喫\x03喳\x03嗂\x03圖\x03嘆\x03圗\x03噑\x03噴\x03切\x03壮\x03城\x03" +
- "埴\x03堍\x03型\x03堲\x03報\x03墬\x03売\x03壷\x03夆\x03夢\x03奢\x03姬\x03娛\x03娧\x03" +
- "姘\x03婦\x03㛮\x03嬈\x03嬾\x03寃\x03寘\x03寧\x03寳\x03寿\x03将\x03尢\x03㞁\x03屠\x03" +
- "屮\x03峀\x03岍\x03嵃\x03嵮\x03嵫\x03嵼\x03巡\x03巢\x03㠯\x03巽\x03帨\x03帽\x03幩\x03" +
- "㡢\x03㡼\x03庰\x03庳\x03庶\x03廊\x03廾\x03舁\x03弢\x03㣇\x03形\x03彫\x03㣣\x03徚\x03" +
- "忍\x03志\x03忹\x03悁\x03㤺\x03㤜\x03悔\x03惇\x03慈\x03慌\x03慎\x03慺\x03憎\x03憲\x03" +
- "憤\x03憯\x03懞\x03懲\x03懶\x03成\x03戛\x03扝\x03抱\x03拔\x03捐\x03挽\x03拼\x03捨\x03" +
- "掃\x03揤\x03搢\x03揅\x03掩\x03㨮\x03摩\x03摾\x03撝\x03摷\x03㩬\x03敏\x03敬\x03旣\x03" +
- "書\x03晉\x03㬙\x03暑\x03㬈\x03㫤\x03冒\x03冕\x03最\x03暜\x03肭\x03䏙\x03朗\x03望\x03" +
- "朡\x03杞\x03杓\x03㭉\x03柺\x03枅\x03桒\x03梅\x03梎\x03栟\x03椔\x03㮝\x03楂\x03榣\x03" +
- "槪\x03檨\x03櫛\x03㰘\x03次\x03歔\x03㱎\x03歲\x03殟\x03殺\x03殻\x03汎\x03沿\x03泍\x03" +
- "汧\x03洖\x03派\x03海\x03流\x03浩\x03浸\x03涅\x03洴\x03港\x03湮\x03㴳\x03滋\x03滇\x03" +
- "淹\x03潮\x03濆\x03瀹\x03瀞\x03瀛\x03㶖\x03灊\x03災\x03灷\x03炭\x03煅\x03熜\x03爨\x03" +
- "爵\x03牐\x03犀\x03犕\x03獺\x03王\x03㺬\x03玥\x03㺸\x03瑇\x03瑜\x03瑱\x03璅\x03瓊\x03" +
- "㼛\x03甤\x03甾\x03異\x03瘐\x03㿼\x03䀈\x03直\x03眞\x03真\x03睊\x03䀹\x03瞋\x03䁆\x03" +
- "䂖\x03硎\x03碌\x03磌\x03䃣\x03祖\x03福\x03秫\x03䄯\x03穀\x03穊\x03穏\x03䈂\x03篆\x03" +
- "築\x03䈧\x03糒\x03䊠\x03糨\x03糣\x03紀\x03絣\x03䌁\x03緇\x03縂\x03繅\x03䌴\x03䍙\x03" +
- "罺\x03羕\x03翺\x03者\x03聠\x03聰\x03䏕\x03育\x03脃\x03䐋\x03脾\x03媵\x03舄\x03辞\x03" +
- "䑫\x03芑\x03芋\x03芝\x03劳\x03花\x03芳\x03芽\x03苦\x03若\x03茝\x03荣\x03莭\x03茣\x03" +
- "莽\x03菧\x03著\x03荓\x03菊\x03菌\x03菜\x03䔫\x03蓱\x03蓳\x03蔖\x03蕤\x03䕝\x03䕡\x03" +
- "䕫\x03虐\x03虜\x03虧\x03虩\x03蚩\x03蚈\x03蜎\x03蛢\x03蝹\x03蜨\x03蝫\x03螆\x03蟡\x03" +
- "蠁\x03䗹\x03衠\x03衣\x03裗\x03裞\x03䘵\x03裺\x03㒻\x03䚾\x03䛇\x03誠\x03諭\x03變\x03" +
- "豕\x03貫\x03賁\x03贛\x03起\x03跋\x03趼\x03跰\x03軔\x03輸\x03邔\x03郱\x03鄑\x03鄛\x03" +
- "鈸\x03鋗\x03鋘\x03鉼\x03鏹\x03鐕\x03開\x03䦕\x03閷\x03䧦\x03雃\x03嶲\x03霣\x03䩮\x03" +
- "䩶\x03韠\x03䪲\x03頋\x03頩\x03飢\x03䬳\x03餩\x03馧\x03駂\x03駾\x03䯎\x03鬒\x03鱀\x03" +
- "鳽\x03䳎\x03䳭\x03鵧\x03䳸\x03麻\x03䵖\x03黹\x03黾\x03鼅\x03鼏\x03鼖\x03鼻"
-
-var xorData string = "" + // Size: 4862 bytes
- "\x02\x0c\x09\x02\xb0\xec\x02\xad\xd8\x02\xad\xd9\x02\x06\x07\x02\x0f\x12" +
- "\x02\x0f\x1f\x02\x0f\x1d\x02\x01\x13\x02\x0f\x16\x02\x0f\x0b\x02\x0f3" +
- "\x02\x0f7\x02\x0f?\x02\x0f/\x02\x0f*\x02\x0c&\x02\x0c*\x02\x0c;\x02\x0c9" +
- "\x02\x0c%\x02\xab\xed\x02\xab\xe2\x02\xab\xe3\x02\xa9\xe0\x02\xa9\xe1" +
- "\x02\xa9\xe6\x02\xa3\xcb\x02\xa3\xc8\x02\xa3\xc9\x02\x01#\x02\x01\x08" +
- "\x02\x0e>\x02\x0e'\x02\x0f\x03\x02\x03\x0d\x02\x03\x09\x02\x03\x17\x02" +
- "\x03\x0e\x02\x02\x03\x02\x011\x02\x01\x00\x02\x01\x10\x02\x03<\x02\x07" +
- "\x0d\x02\x02\x0c\x02\x0c0\x02\x01\x03\x02\x01\x01\x02\x01 \x02\x01\x22" +
- "\x02\x01)\x02\x01\x0a\x02\x01\x0c\x02\x02\x06\x02\x02\x02\x02\x03\x10" +
- "\x03\x037 \x03\x0b+\x03\x021\x00\x02\x01\x04\x02\x01\x02\x02\x019\x02" +
- "\x03\x1c\x02\x02$\x03\x80p$\x02\x03:\x02\x03\x0a\x03\xc1r.\x03\xc1r,\x03" +
- "\xc1r\x02\x02\x02:\x02\x02>\x02\x02,\x02\x02\x10\x02\x02\x00\x03\xc1s<" +
- "\x03\xc1s*\x03\xc2L$\x03\xc2L;\x02\x09)\x02\x0a\x19\x03\x83\xab\xe3\x03" +
- "\x83\xab\xf2\x03 4\xe0\x03\x81\xab\xea\x03\x81\xab\xf3\x03 4\xef\x03\x96" +
- "\xe1\xcd\x03\x84\xe5\xc3\x02\x0d\x11\x03\x8b\xec\xcb\x03\x94\xec\xcf\x03" +
- "\x9a\xec\xc2\x03\x8b\xec\xdb\x03\x94\xec\xdf\x03\x9a\xec\xd2\x03\x01\x0c" +
- "!\x03\x01\x0c#\x03ʠ\x9d\x03ʣ\x9c\x03ʢ\x9f\x03ʥ\x9e\x03ʤ\x91\x03ʧ\x90\x03" +
- "ʦ\x93\x03ʩ\x92\x03ʨ\x95\x03\xca\xf3\xb5\x03\xca\xf0\xb4\x03\xca\xf1\xb7" +
- "\x03\xca\xf6\xb6\x03\xca\xf7\x89\x03\xca\xf4\x88\x03\xca\xf5\x8b\x03\xca" +
- "\xfa\x8a\x03\xca\xfb\x8d\x03\xca\xf8\x8c\x03\xca\xf9\x8f\x03\xca\xfe\x8e" +
- "\x03\xca\xff\x81\x03\xca\xfc\x80\x03\xca\xfd\x83\x03\xca\xe2\x82\x03\xca" +
- "\xe3\x85\x03\xca\xe0\x84\x03\xca\xe1\x87\x03\xca\xe6\x86\x03\xca\xe7\x99" +
- "\x03\xca\xe4\x98\x03\xca\xe5\x9b\x03\xca\xea\x9a\x03\xca\xeb\x9d\x03\xca" +
- "\xe8\x9c\x03ؓ\x89\x03ߔ\x8b\x02\x010\x03\x03\x04\x1e\x03\x04\x15\x12\x03" +
- "\x0b\x05,\x03\x06\x04\x00\x03\x06\x04)\x03\x06\x044\x03\x06\x04<\x03\x06" +
- "\x05\x1d\x03\x06\x06\x00\x03\x06\x06\x0a\x03\x06\x06'\x03\x06\x062\x03" +
- "\x0786\x03\x079/\x03\x079 \x03\x07:\x0e\x03\x07:\x1b\x03\x07:%\x03\x07;/" +
- "\x03\x07;%\x03\x074\x11\x03\x076\x09\x03\x077*\x03\x070\x01\x03\x070\x0f" +
- "\x03\x070.\x03\x071\x16\x03\x071\x04\x03\x0710\x03\x072\x18\x03\x072-" +
- "\x03\x073\x14\x03\x073>\x03\x07'\x09\x03\x07 \x00\x03\x07\x1f\x0b\x03" +
- "\x07\x18#\x03\x07\x18(\x03\x07\x186\x03\x07\x18\x03\x03\x07\x19\x16\x03" +
- "\x07\x116\x03\x07\x12'\x03\x07\x13\x10\x03\x07\x0c&\x03\x07\x0c\x08\x03" +
- "\x07\x0c\x13\x03\x07\x0d\x02\x03\x07\x0d\x1c\x03\x07\x0b5\x03\x07\x0b" +
- "\x0a\x03\x07\x0b\x01\x03\x07\x0b\x0f\x03\x07\x05\x00\x03\x07\x05\x09\x03" +
- "\x07\x05\x0b\x03\x07\x07\x01\x03\x07\x07\x08\x03\x07\x00<\x03\x07\x00+" +
- "\x03\x07\x01)\x03\x07\x01\x1b\x03\x07\x01\x08\x03\x07\x03?\x03\x0445\x03" +
- "\x044\x08\x03\x0454\x03\x04)/\x03\x04)5\x03\x04+\x05\x03\x04+\x14\x03" +
- "\x04+ \x03\x04+<\x03\x04*&\x03\x04*\x22\x03\x04&8\x03\x04!\x01\x03\x04!" +
- "\x22\x03\x04\x11+\x03\x04\x10.\x03\x04\x104\x03\x04\x13=\x03\x04\x12\x04" +
- "\x03\x04\x12\x0a\x03\x04\x0d\x1d\x03\x04\x0d\x07\x03\x04\x0d \x03\x05<>" +
- "\x03\x055<\x03\x055!\x03\x055#\x03\x055&\x03\x054\x1d\x03\x054\x02\x03" +
- "\x054\x07\x03\x0571\x03\x053\x1a\x03\x053\x16\x03\x05.<\x03\x05.\x07\x03" +
- "\x05):\x03\x05)<\x03\x05)\x0c\x03\x05)\x15\x03\x05+-\x03\x05+5\x03\x05$" +
- "\x1e\x03\x05$\x14\x03\x05'\x04\x03\x05'\x14\x03\x05&\x02\x03\x05\x226" +
- "\x03\x05\x22\x0c\x03\x05\x22\x1c\x03\x05\x19\x0a\x03\x05\x1b\x09\x03\x05" +
- "\x1b\x0c\x03\x05\x14\x07\x03\x05\x16?\x03\x05\x16\x0c\x03\x05\x0c\x05" +
- "\x03\x05\x0e\x0f\x03\x05\x01\x0e\x03\x05\x00(\x03\x05\x030\x03\x05\x03" +
- "\x06\x03\x0a==\x03\x0a=1\x03\x0a=,\x03\x0a=\x0c\x03\x0a??\x03\x0a<\x08" +
- "\x03\x0a9!\x03\x0a9)\x03\x0a97\x03\x0a99\x03\x0a6\x0a\x03\x0a6\x1c\x03" +
- "\x0a6\x17\x03\x0a7'\x03\x0a78\x03\x0a73\x03\x0a'\x01\x03\x0a'&\x03\x0a" +
- "\x1f\x0e\x03\x0a\x1f\x03\x03\x0a\x1f3\x03\x0a\x1b/\x03\x0a\x18\x19\x03" +
- "\x0a\x19\x01\x03\x0a\x16\x14\x03\x0a\x0e\x22\x03\x0a\x0f\x10\x03\x0a\x0f" +
- "\x02\x03\x0a\x0f \x03\x0a\x0c\x04\x03\x0a\x0b>\x03\x0a\x0b+\x03\x0a\x08/" +
- "\x03\x0a\x046\x03\x0a\x05\x14\x03\x0a\x00\x04\x03\x0a\x00\x10\x03\x0a" +
- "\x00\x14\x03\x0b<3\x03\x0b;*\x03\x0b9\x22\x03\x0b9)\x03\x0b97\x03\x0b+" +
- "\x10\x03\x0b((\x03\x0b&5\x03\x0b$\x1c\x03\x0b$\x12\x03\x0b%\x04\x03\x0b#" +
- "<\x03\x0b#0\x03\x0b#\x0d\x03\x0b#\x19\x03\x0b!:\x03\x0b!\x1f\x03\x0b!" +
- "\x00\x03\x0b\x1e5\x03\x0b\x1c\x1d\x03\x0b\x1d-\x03\x0b\x1d(\x03\x0b\x18." +
- "\x03\x0b\x18 \x03\x0b\x18\x16\x03\x0b\x14\x13\x03\x0b\x15$\x03\x0b\x15" +
- "\x22\x03\x0b\x12\x1b\x03\x0b\x12\x10\x03\x0b\x132\x03\x0b\x13=\x03\x0b" +
- "\x12\x18\x03\x0b\x0c&\x03\x0b\x061\x03\x0b\x06:\x03\x0b\x05#\x03\x0b\x05" +
- "<\x03\x0b\x04\x0b\x03\x0b\x04\x04\x03\x0b\x04\x1b\x03\x0b\x042\x03\x0b" +
- "\x041\x03\x0b\x03\x03\x03\x0b\x03\x1d\x03\x0b\x03/\x03\x0b\x03+\x03\x0b" +
- "\x02\x1b\x03\x0b\x02\x00\x03\x0b\x01\x1e\x03\x0b\x01\x08\x03\x0b\x015" +
- "\x03\x06\x0d9\x03\x06\x0d=\x03\x06\x0d?\x03\x02\x001\x03\x02\x003\x03" +
- "\x02\x02\x19\x03\x02\x006\x03\x02\x02\x1b\x03\x02\x004\x03\x02\x00<\x03" +
- "\x02\x02\x0a\x03\x02\x02\x0e\x03\x02\x01\x1a\x03\x02\x01\x07\x03\x02\x01" +
- "\x05\x03\x02\x01\x0b\x03\x02\x01%\x03\x02\x01\x0c\x03\x02\x01\x04\x03" +
- "\x02\x01\x1c\x03\x02\x00.\x03\x02\x002\x03\x02\x00>\x03\x02\x00\x12\x03" +
- "\x02\x00\x16\x03\x02\x011\x03\x02\x013\x03\x02\x02 \x03\x02\x02%\x03\x02" +
- "\x02$\x03\x02\x028\x03\x02\x02;\x03\x02\x024\x03\x02\x012\x03\x02\x022" +
- "\x03\x02\x02/\x03\x02\x01,\x03\x02\x01\x13\x03\x02\x01\x16\x03\x02\x01" +
- "\x11\x03\x02\x01\x1e\x03\x02\x01\x15\x03\x02\x01\x17\x03\x02\x01\x0f\x03" +
- "\x02\x01\x08\x03\x02\x00?\x03\x02\x03\x07\x03\x02\x03\x0d\x03\x02\x03" +
- "\x13\x03\x02\x03\x1d\x03\x02\x03\x1f\x03\x02\x00\x03\x03\x02\x00\x0d\x03" +
- "\x02\x00\x01\x03\x02\x00\x1b\x03\x02\x00\x19\x03\x02\x00\x18\x03\x02\x00" +
- "\x13\x03\x02\x00/\x03\x07>\x12\x03\x07<\x1f\x03\x07>\x1d\x03\x06\x1d\x0e" +
- "\x03\x07>\x1c\x03\x07>:\x03\x07>\x13\x03\x04\x12+\x03\x07?\x03\x03\x07>" +
- "\x02\x03\x06\x224\x03\x06\x1a.\x03\x07<%\x03\x06\x1c\x0b\x03\x0609\x03" +
- "\x05\x1f\x01\x03\x04'\x08\x03\x93\xfd\xf5\x03\x02\x0d \x03\x02\x0d#\x03" +
- "\x02\x0d!\x03\x02\x0d&\x03\x02\x0d\x22\x03\x02\x0d/\x03\x02\x0d,\x03\x02" +
- "\x0d$\x03\x02\x0d'\x03\x02\x0d%\x03\x02\x0d;\x03\x02\x0d=\x03\x02\x0d?" +
- "\x03\x099.\x03\x08\x0b7\x03\x08\x02\x14\x03\x08\x14\x0d\x03\x08.:\x03" +
- "\x089'\x03\x0f\x0b\x18\x03\x0f\x1c1\x03\x0f\x17&\x03\x0f9\x1f\x03\x0f0" +
- "\x0c\x03\x0e\x0a9\x03\x0e\x056\x03\x0e\x1c#\x03\x0f\x13\x0e\x03\x072\x00" +
- "\x03\x070\x0d\x03\x072\x0b\x03\x06\x11\x18\x03\x070\x10\x03\x06\x0f(\x03" +
- "\x072\x05\x03\x06\x0f,\x03\x073\x15\x03\x06\x07\x08\x03\x05\x16\x02\x03" +
- "\x04\x0b \x03\x05:8\x03\x05\x16%\x03\x0a\x0d\x1f\x03\x06\x16\x10\x03\x05" +
- "\x1d5\x03\x05*;\x03\x05\x16\x1b\x03\x04.-\x03\x06\x1a\x19\x03\x04\x03," +
- "\x03\x0b87\x03\x04/\x0a\x03\x06\x00,\x03\x04-\x01\x03\x04\x1e-\x03\x06/(" +
- "\x03\x0a\x0b5\x03\x06\x0e7\x03\x06\x07.\x03\x0597\x03\x0a*%\x03\x0760" +
- "\x03\x06\x0c;\x03\x05'\x00\x03\x072.\x03\x072\x08\x03\x06=\x01\x03\x06" +
- "\x05\x1b\x03\x06\x06\x12\x03\x06$=\x03\x06'\x0d\x03\x04\x11\x0f\x03\x076" +
- ",\x03\x06\x07;\x03\x06.,\x03\x86\xf9\xea\x03\x8f\xff\xeb\x02\x092\x02" +
- "\x095\x02\x094\x02\x09;\x02\x09>\x02\x098\x02\x09*\x02\x09/\x02\x09,\x02" +
- "\x09%\x02\x09&\x02\x09#\x02\x09 \x02\x08!\x02\x08%\x02\x08$\x02\x08+\x02" +
- "\x08.\x02\x08*\x02\x08&\x02\x088\x02\x08>\x02\x084\x02\x086\x02\x080\x02" +
- "\x08\x10\x02\x08\x17\x02\x08\x12\x02\x08\x1d\x02\x08\x1f\x02\x08\x13\x02" +
- "\x08\x15\x02\x08\x14\x02\x08\x0c\x03\x8b\xfd\xd0\x03\x81\xec\xc6\x03\x87" +
- "\xe0\x8a\x03-2\xe3\x03\x80\xef\xe4\x03-2\xea\x03\x88\xe6\xeb\x03\x8e\xe6" +
- "\xe8\x03\x84\xe6\xe9\x03\x97\xe6\xee\x03-2\xf9\x03-2\xf6\x03\x8e\xe3\xad" +
- "\x03\x80\xe3\x92\x03\x88\xe3\x90\x03\x8e\xe3\x90\x03\x80\xe3\x97\x03\x88" +
- "\xe3\x95\x03\x88\xfe\xcb\x03\x8e\xfe\xca\x03\x84\xfe\xcd\x03\x91\xef\xc9" +
- "\x03-2\xc1\x03-2\xc0\x03-2\xcb\x03\x88@\x09\x03\x8e@\x08\x03\x8f\xe0\xf5" +
- "\x03\x8e\xe6\xf9\x03\x8e\xe0\xfa\x03\x93\xff\xf4\x03\x84\xee\xd3\x03\x0b" +
- "(\x04\x023 \x03\x0b)\x08\x021;\x02\x01*\x03\x0b#\x10\x03\x0b 0\x03\x0b!" +
- "\x10\x03\x0b!0\x03\x07\x15\x08\x03\x09?5\x03\x07\x1f\x08\x03\x07\x17\x0b" +
- "\x03\x09\x1f\x15\x03\x0b\x1c7\x03\x0a+#\x03\x06\x1a\x1b\x03\x06\x1a\x14" +
- "\x03\x0a\x01\x18\x03\x06#\x1b\x03\x0a2\x0c\x03\x0a\x01\x04\x03\x09#;\x03" +
- "\x08='\x03\x08\x1a\x0a\x03\x07</\x03\x07:+\x03\x07\x07*\x03\x06&\x1c\x03" +
- "\x09\x0c\x16\x03\x09\x10\x0e\x03\x08'\x0f\x03\x08+\x09\x03\x074%\x03\x06" +
- "!3\x03\x06\x03+\x03\x0b\x1e\x19\x03\x0a))\x03\x09\x08\x19\x03\x08,\x05" +
- "\x03\x07<2\x03\x06\x1c>\x03\x0a\x111\x03\x09\x1b\x09\x03\x073.\x03\x07" +
- "\x01\x00\x03\x09/,\x03\x07#>\x03\x07\x048\x03\x0a\x1f\x22\x03\x098>\x03" +
- "\x09\x11\x00\x03\x08/\x17\x03\x06'\x22\x03\x0b\x1a+\x03\x0a\x22\x19\x03" +
- "\x0a/1\x03\x0974\x03\x09\x0f\x22\x03\x08,\x22\x03\x08?\x14\x03\x07$5\x03" +
- "\x07<3\x03\x07=*\x03\x07\x13\x18\x03\x068\x0a\x03\x06\x09\x16\x03\x06" +
- "\x13\x00\x03\x08\x067\x03\x08\x01\x03\x03\x08\x12\x1d\x03\x07+7\x03\x06(" +
- ";\x03\x06\x1c?\x03\x07\x0e\x17\x03\x0a\x06\x1d\x03\x0a\x19\x07\x03\x08" +
- "\x14$\x03\x07$;\x03\x08,$\x03\x08\x06\x0d\x03\x07\x16\x0a\x03\x06>>\x03" +
- "\x0a\x06\x12\x03\x0a\x14)\x03\x09\x0d\x1f\x03\x09\x12\x17\x03\x09\x19" +
- "\x01\x03\x08\x11 \x03\x08\x1d'\x03\x06<\x1a\x03\x0a.\x00\x03\x07'\x18" +
- "\x03\x0a\x22\x08\x03\x08\x0d\x0a\x03\x08\x13)\x03\x07*)\x03\x06<,\x03" +
- "\x07\x0b\x1a\x03\x09.\x14\x03\x09\x0d\x1e\x03\x07\x0e#\x03\x0b\x1d'\x03" +
- "\x0a\x0a8\x03\x09%2\x03\x08+&\x03\x080\x12\x03\x0a)4\x03\x08\x06\x1f\x03" +
- "\x0b\x1b\x1a\x03\x0a\x1b\x0f\x03\x0b\x1d*\x03\x09\x16$\x03\x090\x11\x03" +
- "\x08\x11\x08\x03\x0a*(\x03\x0a\x042\x03\x089,\x03\x074'\x03\x07\x0f\x05" +
- "\x03\x09\x0b\x0a\x03\x07\x1b\x01\x03\x09\x17:\x03\x09.\x0d\x03\x07.\x11" +
- "\x03\x09+\x15\x03\x080\x13\x03\x0b\x1f\x19\x03\x0a \x11\x03\x0a\x220\x03" +
- "\x09\x07;\x03\x08\x16\x1c\x03\x07,\x13\x03\x07\x0e/\x03\x06\x221\x03\x0a" +
- ".\x0a\x03\x0a7\x02\x03\x0a\x032\x03\x0a\x1d.\x03\x091\x06\x03\x09\x19:" +
- "\x03\x08\x02/\x03\x060+\x03\x06\x0f-\x03\x06\x1c\x1f\x03\x06\x1d\x07\x03" +
- "\x0a,\x11\x03\x09=\x0d\x03\x09\x0b;\x03\x07\x1b/\x03\x0a\x1f:\x03\x09 " +
- "\x1f\x03\x09.\x10\x03\x094\x0b\x03\x09\x1a1\x03\x08#\x1a\x03\x084\x1d" +
- "\x03\x08\x01\x1f\x03\x08\x11\x22\x03\x07'8\x03\x07\x1a>\x03\x0757\x03" +
- "\x06&9\x03\x06+\x11\x03\x0a.\x0b\x03\x0a,>\x03\x0a4#\x03\x08%\x17\x03" +
- "\x07\x05\x22\x03\x07\x0c\x0b\x03\x0a\x1d+\x03\x0a\x19\x16\x03\x09+\x1f" +
- "\x03\x09\x08\x0b\x03\x08\x16\x18\x03\x08+\x12\x03\x0b\x1d\x0c\x03\x0a=" +
- "\x10\x03\x0a\x09\x0d\x03\x0a\x10\x11\x03\x09&0\x03\x08(\x1f\x03\x087\x07" +
- "\x03\x08\x185\x03\x07'6\x03\x06.\x05\x03\x06=\x04\x03\x06;;\x03\x06\x06," +
- "\x03\x0b\x18>\x03\x08\x00\x18\x03\x06 \x03\x03\x06<\x00\x03\x09%\x18\x03" +
- "\x0b\x1c<\x03\x0a%!\x03\x0a\x09\x12\x03\x0a\x16\x02\x03\x090'\x03\x09" +
- "\x0e=\x03\x08 \x0e\x03\x08>\x03\x03\x074>\x03\x06&?\x03\x06\x19\x09\x03" +
- "\x06?(\x03\x0a-\x0e\x03\x09:3\x03\x098:\x03\x09\x12\x0b\x03\x09\x1d\x17" +
- "\x03\x087\x05\x03\x082\x14\x03\x08\x06%\x03\x08\x13\x1f\x03\x06\x06\x0e" +
- "\x03\x0a\x22<\x03\x09/<\x03\x06>+\x03\x0a'?\x03\x0a\x13\x0c\x03\x09\x10<" +
- "\x03\x07\x1b=\x03\x0a\x19\x13\x03\x09\x22\x1d\x03\x09\x07\x0d\x03\x08)" +
- "\x1c\x03\x06=\x1a\x03\x0a/4\x03\x0a7\x11\x03\x0a\x16:\x03\x09?3\x03\x09:" +
- "/\x03\x09\x05\x0a\x03\x09\x14\x06\x03\x087\x22\x03\x080\x07\x03\x08\x1a" +
- "\x1f\x03\x07\x04(\x03\x07\x04\x09\x03\x06 %\x03\x06<\x08\x03\x0a+\x14" +
- "\x03\x09\x1d\x16\x03\x0a70\x03\x08 >\x03\x0857\x03\x070\x0a\x03\x06=\x12" +
- "\x03\x06\x16%\x03\x06\x1d,\x03\x099#\x03\x09\x10>\x03\x07 \x1e\x03\x08" +
- "\x0c<\x03\x08\x0b\x18\x03\x08\x15+\x03\x08,:\x03\x08%\x22\x03\x07\x0a$" +
- "\x03\x0b\x1c=\x03\x07+\x08\x03\x0a/\x05\x03\x0a \x07\x03\x0a\x12'\x03" +
- "\x09#\x11\x03\x08\x1b\x15\x03\x0a\x06\x01\x03\x09\x1c\x1b\x03\x0922\x03" +
- "\x07\x14<\x03\x07\x09\x04\x03\x061\x04\x03\x07\x0e\x01\x03\x0a\x13\x18" +
- "\x03\x0a-\x0c\x03\x0a?\x0d\x03\x0a\x09\x0a\x03\x091&\x03\x0a/\x0b\x03" +
- "\x08$<\x03\x083\x1d\x03\x08\x0c$\x03\x08\x0d\x07\x03\x08\x0d?\x03\x08" +
- "\x0e\x14\x03\x065\x0a\x03\x08\x1a#\x03\x08\x16#\x03\x0702\x03\x07\x03" +
- "\x1a\x03\x06(\x1d\x03\x06+\x1b\x03\x06\x0b\x05\x03\x06\x0b\x17\x03\x06" +
- "\x0c\x04\x03\x06\x1e\x19\x03\x06+0\x03\x062\x18\x03\x0b\x16\x1e\x03\x0a+" +
- "\x16\x03\x0a-?\x03\x0a#:\x03\x0a#\x10\x03\x0a%$\x03\x0a>+\x03\x0a01\x03" +
- "\x0a1\x10\x03\x0a\x099\x03\x0a\x0a\x12\x03\x0a\x19\x1f\x03\x0a\x19\x12" +
- "\x03\x09*)\x03\x09-\x16\x03\x09.1\x03\x09.2\x03\x09<\x0e\x03\x09> \x03" +
- "\x093\x12\x03\x09\x0b\x01\x03\x09\x1c2\x03\x09\x11\x1c\x03\x09\x15%\x03" +
- "\x08,&\x03\x08!\x22\x03\x089(\x03\x08\x0b\x1a\x03\x08\x0d2\x03\x08\x0c" +
- "\x04\x03\x08\x0c\x06\x03\x08\x0c\x1f\x03\x08\x0c\x0c\x03\x08\x0f\x1f\x03" +
- "\x08\x0f\x1d\x03\x08\x00\x14\x03\x08\x03\x14\x03\x08\x06\x16\x03\x08\x1e" +
- "#\x03\x08\x11\x11\x03\x08\x10\x18\x03\x08\x14(\x03\x07)\x1e\x03\x07.1" +
- "\x03\x07 $\x03\x07 '\x03\x078\x08\x03\x07\x0d0\x03\x07\x0f7\x03\x07\x05#" +
- "\x03\x07\x05\x1a\x03\x07\x1a7\x03\x07\x1d-\x03\x07\x17\x10\x03\x06)\x1f" +
- "\x03\x062\x0b\x03\x066\x16\x03\x06\x09\x11\x03\x09(\x1e\x03\x07!5\x03" +
- "\x0b\x11\x16\x03\x0a/\x04\x03\x0a,\x1a\x03\x0b\x173\x03\x0a,1\x03\x0a/5" +
- "\x03\x0a\x221\x03\x0a\x22\x0d\x03\x0a?%\x03\x0a<,\x03\x0a?#\x03\x0a>\x19" +
- "\x03\x0a\x08&\x03\x0a\x0b\x0e\x03\x0a\x0c:\x03\x0a\x0c+\x03\x0a\x03\x22" +
- "\x03\x0a\x06)\x03\x0a\x11\x10\x03\x0a\x11\x1a\x03\x0a\x17-\x03\x0a\x14(" +
- "\x03\x09)\x1e\x03\x09/\x09\x03\x09.\x00\x03\x09,\x07\x03\x09/*\x03\x09-9" +
- "\x03\x09\x228\x03\x09%\x09\x03\x09:\x12\x03\x09;\x1d\x03\x09?\x06\x03" +
- "\x093%\x03\x096\x05\x03\x096\x08\x03\x097\x02\x03\x09\x07,\x03\x09\x04," +
- "\x03\x09\x1f\x16\x03\x09\x11\x03\x03\x09\x11\x12\x03\x09\x168\x03\x08*" +
- "\x05\x03\x08/2\x03\x084:\x03\x08\x22+\x03\x08 0\x03\x08&\x0a\x03\x08;" +
- "\x10\x03\x08>$\x03\x08>\x18\x03\x0829\x03\x082:\x03\x081,\x03\x081<\x03" +
- "\x081\x1c\x03\x087#\x03\x087*\x03\x08\x09'\x03\x08\x00\x1d\x03\x08\x05-" +
- "\x03\x08\x1f4\x03\x08\x1d\x04\x03\x08\x16\x0f\x03\x07*7\x03\x07'!\x03" +
- "\x07%\x1b\x03\x077\x0c\x03\x07\x0c1\x03\x07\x0c.\x03\x07\x00\x06\x03\x07" +
- "\x01\x02\x03\x07\x010\x03\x07\x06=\x03\x07\x01\x03\x03\x07\x01\x13\x03" +
- "\x07\x06\x06\x03\x07\x05\x0a\x03\x07\x1f\x09\x03\x07\x17:\x03\x06*1\x03" +
- "\x06-\x1d\x03\x06\x223\x03\x062:\x03\x060$\x03\x066\x1e\x03\x064\x12\x03" +
- "\x0645\x03\x06\x0b\x00\x03\x06\x0b7\x03\x06\x07\x1f\x03\x06\x15\x12\x03" +
- "\x0c\x05\x0f\x03\x0b+\x0b\x03\x0b+-\x03\x06\x16\x1b\x03\x06\x15\x17\x03" +
- "\x89\xca\xea\x03\x89\xca\xe8\x03\x0c8\x10\x03\x0c8\x01\x03\x0c8\x0f\x03" +
- "\x0d8%\x03\x0d8!\x03\x0c8-\x03\x0c8/\x03\x0c8+\x03\x0c87\x03\x0c85\x03" +
- "\x0c9\x09\x03\x0c9\x0d\x03\x0c9\x0f\x03\x0c9\x0b\x03\xcfu\x0c\x03\xcfu" +
- "\x0f\x03\xcfu\x0e\x03\xcfu\x09\x03\x0c9\x10\x03\x0d9\x0c\x03\xcf`;\x03" +
- "\xcf`>\x03\xcf`9\x03\xcf`8\x03\xcf`7\x03\xcf`*\x03\xcf`-\x03\xcf`,\x03" +
- "\x0d\x1b\x1a\x03\x0d\x1b&\x03\x0c=.\x03\x0c=%\x03\x0c>\x1e\x03\x0c>\x14" +
- "\x03\x0c?\x06\x03\x0c?\x0b\x03\x0c?\x0c\x03\x0c?\x0d\x03\x0c?\x02\x03" +
- "\x0c>\x0f\x03\x0c>\x08\x03\x0c>\x09\x03\x0c>,\x03\x0c>\x0c\x03\x0c?\x13" +
- "\x03\x0c?\x16\x03\x0c?\x15\x03\x0c?\x1c\x03\x0c?\x1f\x03\x0c?\x1d\x03" +
- "\x0c?\x1a\x03\x0c?\x17\x03\x0c?\x08\x03\x0c?\x09\x03\x0c?\x0e\x03\x0c?" +
- "\x04\x03\x0c?\x05\x03\x0c<?\x03\x0c=\x00\x03\x0c=\x06\x03\x0c=\x05\x03" +
- "\x0c=\x0c\x03\x0c=\x0f\x03\x0c=\x0d\x03\x0c=\x0b\x03\x0c=\x07\x03\x0c=" +
- "\x19\x03\x0c=\x15\x03\x0c=\x11\x03\x0c=1\x03\x0c=3\x03\x0c=0\x03\x0c=>" +
- "\x03\x0c=2\x03\x0c=6\x03\x0c<\x07\x03\x0c<\x05\x03\x0e:!\x03\x0e:#\x03" +
- "\x0e8\x09\x03\x0e:&\x03\x0e8\x0b\x03\x0e:$\x03\x0e:,\x03\x0e8\x1a\x03" +
- "\x0e8\x1e\x03\x0e:*\x03\x0e:7\x03\x0e:5\x03\x0e:;\x03\x0e:\x15\x03\x0e:<" +
- "\x03\x0e:4\x03\x0e:'\x03\x0e:-\x03\x0e:%\x03\x0e:?\x03\x0e:=\x03\x0e:)" +
- "\x03\x0e:/\x03\xcfs'\x03\x0d=\x0f\x03\x0d+*\x03\x0d99\x03\x0d9;\x03\x0d9" +
- "?\x03\x0d)\x0d\x03\x0d(%\x02\x01\x18\x02\x01(\x02\x01\x1e\x03\x0f$!\x03" +
- "\x0f87\x03\x0f4\x0e\x03\x0f5\x1d\x03\x06'\x03\x03\x0f\x08\x18\x03\x0f" +
- "\x0d\x1b\x03\x0e2=\x03\x0e;\x08\x03\x0e:\x0b\x03\x0e\x06$\x03\x0e\x0d)" +
- "\x03\x0e\x16\x1f\x03\x0e\x16\x1b\x03\x0d$\x0a\x03\x05,\x1d\x03\x0d. \x03" +
- "\x0d.#\x03\x0c(/\x03\x09%\x02\x03\x0d90\x03\x0d\x0e4\x03\x0d\x0d\x0f\x03" +
- "\x0c#\x00\x03\x0c,\x1e\x03\x0c2\x0e\x03\x0c\x01\x17\x03\x0c\x09:\x03\x0e" +
- "\x173\x03\x0c\x08\x03\x03\x0c\x11\x07\x03\x0c\x10\x18\x03\x0c\x1f\x1c" +
- "\x03\x0c\x19\x0e\x03\x0c\x1a\x1f\x03\x0f0>\x03\x0b->\x03\x0b<+\x03\x0b8" +
- "\x13\x03\x0b\x043\x03\x0b\x14\x03\x03\x0b\x16%\x03\x0d\x22&\x03\x0b\x1a" +
- "\x1a\x03\x0b\x1a\x04\x03\x0a%9\x03\x0a&2\x03\x0a&0\x03\x0a!\x1a\x03\x0a!" +
- "7\x03\x0a5\x10\x03\x0a=4\x03\x0a?\x0e\x03\x0a>\x10\x03\x0a\x00 \x03\x0a" +
- "\x0f:\x03\x0a\x0f9\x03\x0a\x0b\x0a\x03\x0a\x17%\x03\x0a\x1b-\x03\x09-" +
- "\x1a\x03\x09,4\x03\x09.,\x03\x09)\x09\x03\x096!\x03\x091\x1f\x03\x093" +
- "\x16\x03\x0c+\x1f\x03\x098 \x03\x098=\x03\x0c(\x1a\x03\x0c(\x16\x03\x09" +
- "\x0a+\x03\x09\x16\x12\x03\x09\x13\x0e\x03\x09\x153\x03\x08)!\x03\x09\x1a" +
- "\x01\x03\x09\x18\x01\x03\x08%#\x03\x08>\x22\x03\x08\x05%\x03\x08\x02*" +
- "\x03\x08\x15;\x03\x08\x1b7\x03\x0f\x07\x1d\x03\x0f\x04\x03\x03\x070\x0c" +
- "\x03\x07;\x0b\x03\x07\x08\x17\x03\x07\x12\x06\x03\x06/-\x03\x0671\x03" +
- "\x065+\x03\x06>7\x03\x06\x049\x03\x05+\x1e\x03\x05,\x17\x03\x05 \x1d\x03" +
- "\x05\x22\x05\x03\x050\x1d"
-
-// lookup returns the trie value for the first UTF-8 encoding in s and
-// the width in bytes of this encoding. The size will be 0 if s does not
-// hold enough bytes to complete the encoding. len(s) must be greater than 0.
-func (t *idnaTrie) lookup(s []byte) (v uint16, sz int) {
- c0 := s[0]
- switch {
- case c0 < 0x80: // is ASCII
- return idnaValues[c0], 1
- case c0 < 0xC2:
- return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
- case c0 < 0xE0: // 2-byte UTF-8
- if len(s) < 2 {
- return 0, 0
- }
- i := idnaIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c1), 2
- case c0 < 0xF0: // 3-byte UTF-8
- if len(s) < 3 {
- return 0, 0
- }
- i := idnaIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = idnaIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c2), 3
- case c0 < 0xF8: // 4-byte UTF-8
- if len(s) < 4 {
- return 0, 0
- }
- i := idnaIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = idnaIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- o = uint32(i)<<6 + uint32(c2)
- i = idnaIndex[o]
- c3 := s[3]
- if c3 < 0x80 || 0xC0 <= c3 {
- return 0, 3 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c3), 4
- }
- // Illegal rune
- return 0, 1
-}
-
-// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
-// s must start with a full and valid UTF-8 encoded rune.
-func (t *idnaTrie) lookupUnsafe(s []byte) uint16 {
- c0 := s[0]
- if c0 < 0x80 { // is ASCII
- return idnaValues[c0]
- }
- i := idnaIndex[c0]
- if c0 < 0xE0 { // 2-byte UTF-8
- return t.lookupValue(uint32(i), s[1])
- }
- i = idnaIndex[uint32(i)<<6+uint32(s[1])]
- if c0 < 0xF0 { // 3-byte UTF-8
- return t.lookupValue(uint32(i), s[2])
- }
- i = idnaIndex[uint32(i)<<6+uint32(s[2])]
- if c0 < 0xF8 { // 4-byte UTF-8
- return t.lookupValue(uint32(i), s[3])
- }
- return 0
-}
-
-// lookupString returns the trie value for the first UTF-8 encoding in s and
-// the width in bytes of this encoding. The size will be 0 if s does not
-// hold enough bytes to complete the encoding. len(s) must be greater than 0.
-func (t *idnaTrie) lookupString(s string) (v uint16, sz int) {
- c0 := s[0]
- switch {
- case c0 < 0x80: // is ASCII
- return idnaValues[c0], 1
- case c0 < 0xC2:
- return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
- case c0 < 0xE0: // 2-byte UTF-8
- if len(s) < 2 {
- return 0, 0
- }
- i := idnaIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c1), 2
- case c0 < 0xF0: // 3-byte UTF-8
- if len(s) < 3 {
- return 0, 0
- }
- i := idnaIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = idnaIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c2), 3
- case c0 < 0xF8: // 4-byte UTF-8
- if len(s) < 4 {
- return 0, 0
- }
- i := idnaIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = idnaIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- o = uint32(i)<<6 + uint32(c2)
- i = idnaIndex[o]
- c3 := s[3]
- if c3 < 0x80 || 0xC0 <= c3 {
- return 0, 3 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c3), 4
- }
- // Illegal rune
- return 0, 1
-}
-
-// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
-// s must start with a full and valid UTF-8 encoded rune.
-func (t *idnaTrie) lookupStringUnsafe(s string) uint16 {
- c0 := s[0]
- if c0 < 0x80 { // is ASCII
- return idnaValues[c0]
- }
- i := idnaIndex[c0]
- if c0 < 0xE0 { // 2-byte UTF-8
- return t.lookupValue(uint32(i), s[1])
- }
- i = idnaIndex[uint32(i)<<6+uint32(s[1])]
- if c0 < 0xF0 { // 3-byte UTF-8
- return t.lookupValue(uint32(i), s[2])
- }
- i = idnaIndex[uint32(i)<<6+uint32(s[2])]
- if c0 < 0xF8 { // 4-byte UTF-8
- return t.lookupValue(uint32(i), s[3])
- }
- return 0
-}
-
-// idnaTrie. Total size: 30288 bytes (29.58 KiB). Checksum: c0cd84404a2f6f19.
-type idnaTrie struct{}
-
-func newIdnaTrie(i int) *idnaTrie {
- return &idnaTrie{}
-}
-
-// lookupValue determines the type of block n and looks up the value for b.
-func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {
- switch {
- case n < 126:
- return uint16(idnaValues[n<<6+uint32(b)])
- default:
- n -= 126
- return uint16(idnaSparse.lookup(n, b))
- }
-}
-
-// idnaValues: 128 blocks, 8192 entries, 16384 bytes
-// The third block is the zero block.
-var idnaValues = [8192]uint16{
- // Block 0x0, offset 0x0
- 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,
- 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,
- 0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080,
- 0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080,
- 0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080,
- 0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080,
- 0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080,
- 0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080,
- 0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008,
- 0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080,
- 0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080,
- // Block 0x1, offset 0x40
- 0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105,
- 0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105,
- 0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105,
- 0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105,
- 0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080,
- 0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008,
- 0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008,
- 0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008,
- 0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008,
- 0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080,
- 0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080,
- // Block 0x2, offset 0x80
- // Block 0x3, offset 0xc0
- 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040,
- 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040,
- 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040,
- 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040,
- 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040,
- 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018,
- 0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018,
- 0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a,
- 0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005,
- 0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018,
- 0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018,
- // Block 0x4, offset 0x100
- 0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008,
- 0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008,
- 0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008,
- 0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008,
- 0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008,
- 0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008,
- 0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008,
- 0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008,
- 0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008,
- 0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d,
- 0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199,
- // Block 0x5, offset 0x140
- 0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d,
- 0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008,
- 0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008,
- 0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008,
- 0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008,
- 0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008,
- 0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008,
- 0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008,
- 0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008,
- 0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d,
- 0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9,
- // Block 0x6, offset 0x180
- 0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008,
- 0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d,
- 0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d,
- 0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d,
- 0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155,
- 0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008,
- 0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d,
- 0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd,
- 0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d,
- 0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008,
- 0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008,
- // Block 0x7, offset 0x1c0
- 0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9,
- 0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d,
- 0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d,
- 0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d,
- 0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008,
- 0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008,
- 0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008,
- 0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008,
- 0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008,
- 0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008,
- 0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008,
- // Block 0x8, offset 0x200
- 0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008,
- 0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008,
- 0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008,
- 0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008,
- 0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008,
- 0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008,
- 0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008,
- 0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008,
- 0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008,
- 0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d,
- 0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008,
- // Block 0x9, offset 0x240
- 0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018,
- 0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008,
- 0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008,
- 0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018,
- 0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a,
- 0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369,
- 0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018,
- 0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018,
- 0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018,
- 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,
- 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,
- // Block 0xa, offset 0x280
- 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d,
- 0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308,
- 0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308,
- 0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308,
- 0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308,
- 0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308,
- 0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308,
- 0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308,
- 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,
- 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008,
- 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d,
- // Block 0xb, offset 0x2c0
- 0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2,
- 0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040,
- 0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105,
- 0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105,
- 0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105,
- 0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d,
- 0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d,
- 0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008,
- 0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008,
- 0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008,
- 0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008,
- // Block 0xc, offset 0x300
- 0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008,
- 0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008,
- 0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd,
- 0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008,
- 0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008,
- 0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008,
- 0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008,
- 0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008,
- 0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd,
- 0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008,
- 0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d,
- // Block 0xd, offset 0x340
- 0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008,
- 0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008,
- 0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008,
- 0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008,
- 0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008,
- 0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008,
- 0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008,
- 0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008,
- 0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008,
- 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,
- 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,
- // Block 0xe, offset 0x380
- 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308,
- 0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008,
- 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,
- 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,
- 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,
- 0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008,
- 0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008,
- 0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008,
- 0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008,
- 0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008,
- 0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008,
- // Block 0xf, offset 0x3c0
- 0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d,
- 0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d,
- 0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008,
- 0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008,
- 0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008,
- 0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008,
- 0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008,
- 0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008,
- 0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008,
- 0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008,
- 0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008,
- // Block 0x10, offset 0x400
- 0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008,
- 0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008,
- 0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008,
- 0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008,
- 0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008,
- 0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008,
- 0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008,
- 0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008,
- 0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5,
- 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,
- 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,
- // Block 0x11, offset 0x440
- 0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840,
- 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818,
- 0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308,
- 0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308,
- 0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040,
- 0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08,
- 0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08,
- 0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08,
- 0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08,
- 0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08,
- 0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08,
- // Block 0x12, offset 0x480
- 0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08,
- 0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308,
- 0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308,
- 0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308,
- 0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308,
- 0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808,
- 0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808,
- 0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08,
- 0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429,
- 0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08,
- 0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08,
- // Block 0x13, offset 0x4c0
- 0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08,
- 0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08,
- 0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08,
- 0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308,
- 0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840,
- 0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308,
- 0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018,
- 0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08,
- 0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008,
- 0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08,
- 0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08,
- // Block 0x14, offset 0x500
- 0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818,
- 0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818,
- 0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308,
- 0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08,
- 0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08,
- 0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08,
- 0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08,
- 0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08,
- 0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308,
- 0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308,
- 0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308,
- // Block 0x15, offset 0x540
- 0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08,
- 0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08,
- 0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08,
- 0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0c08, 0x557: 0x0c08,
- 0x558: 0x0c08, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040,
- 0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08,
- 0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08,
- 0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040,
- 0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040,
- 0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040,
- 0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040,
- // Block 0x16, offset 0x580
- 0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308,
- 0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008,
- 0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308,
- 0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308,
- 0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1,
- 0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308,
- 0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008,
- 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008,
- 0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008,
- 0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008,
- 0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008,
- // Block 0x17, offset 0x5c0
- 0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008,
- 0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008,
- 0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040,
- 0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008,
- 0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008,
- 0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008,
- 0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040,
- 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,
- 0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040,
- 0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040,
- 0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008,
- // Block 0x18, offset 0x600
- 0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040,
- 0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008,
- 0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040,
- 0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008,
- 0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1,
- 0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308,
- 0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008,
- 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,
- 0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018,
- 0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018,
- 0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x3308, 0x63f: 0x0040,
- // Block 0x19, offset 0x640
- 0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008,
- 0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040,
- 0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040,
- 0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008,
- 0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008,
- 0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008,
- 0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040,
- 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,
- 0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008,
- 0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040,
- 0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008,
- // Block 0x1a, offset 0x680
- 0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040,
- 0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308,
- 0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308,
- 0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040,
- 0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040,
- 0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040,
- 0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008,
- 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,
- 0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308,
- 0x6b6: 0x0018, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040,
- 0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040,
- // Block 0x1b, offset 0x6c0
- 0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008,
- 0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008,
- 0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008,
- 0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008,
- 0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008,
- 0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008,
- 0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040,
- 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,
- 0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008,
- 0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040,
- 0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008,
- // Block 0x1c, offset 0x700
- 0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308,
- 0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008,
- 0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040,
- 0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040,
- 0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040,
- 0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308,
- 0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008,
- 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,
- 0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040,
- 0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308,
- 0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308,
- // Block 0x1d, offset 0x740
- 0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008,
- 0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008,
- 0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040,
- 0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008,
- 0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008,
- 0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008,
- 0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040,
- 0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008,
- 0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008,
- 0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040,
- 0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308,
- // Block 0x1e, offset 0x780
- 0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040,
- 0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008,
- 0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040,
- 0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x3308, 0x796: 0x3308, 0x797: 0x3008,
- 0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9,
- 0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308,
- 0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008,
- 0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008,
- 0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018,
- 0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040,
- 0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040,
- // Block 0x1f, offset 0x7c0
- 0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008,
- 0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040,
- 0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040,
- 0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040,
- 0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040,
- 0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008,
- 0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008,
- 0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008,
- 0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008,
- 0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040,
- 0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008,
- // Block 0x20, offset 0x800
- 0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040,
- 0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308,
- 0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040,
- 0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040,
- 0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040,
- 0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308,
- 0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008,
- 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008,
- 0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040,
- 0x836: 0x0040, 0x837: 0x0018, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018,
- 0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018,
- // Block 0x21, offset 0x840
- 0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0018, 0x845: 0x0008,
- 0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008,
- 0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040,
- 0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008,
- 0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008,
- 0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008,
- 0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040,
- 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,
- 0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008,
- 0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040,
- 0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308,
- // Block 0x22, offset 0x880
- 0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040,
- 0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008,
- 0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040,
- 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040,
- 0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040,
- 0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308,
- 0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008,
- 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,
- 0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040,
- 0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040,
- 0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040,
- // Block 0x23, offset 0x8c0
- 0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040,
- 0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008,
- 0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040,
- 0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008,
- 0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018,
- 0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308,
- 0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008,
- 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008,
- 0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018,
- 0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008,
- 0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008,
- // Block 0x24, offset 0x900
- 0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040,
- 0x906: 0x0008, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0040,
- 0x90c: 0x0008, 0x90d: 0x0008, 0x90e: 0x0008, 0x90f: 0x0008, 0x910: 0x0008, 0x911: 0x0008,
- 0x912: 0x0008, 0x913: 0x0008, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008,
- 0x918: 0x0008, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008,
- 0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0008, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008,
- 0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0008, 0x929: 0x0008,
- 0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0008, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008,
- 0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308,
- 0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x3b08, 0x93b: 0x3308,
- 0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040,
- // Block 0x25, offset 0x940
- 0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008,
- 0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,
- 0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,
- 0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79,
- 0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008,
- 0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008,
- 0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9,
- 0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040,
- 0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59,
- 0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308,
- 0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008,
- // Block 0x26, offset 0x980
- 0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018,
- 0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008,
- 0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308,
- 0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308,
- 0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11,
- 0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308,
- 0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308,
- 0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308,
- 0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308,
- 0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308,
- 0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018,
- // Block 0x27, offset 0x9c0
- 0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008,
- 0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008,
- 0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008,
- 0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008,
- 0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008,
- 0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008,
- 0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008,
- 0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008,
- 0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41,
- 0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008,
- 0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269,
- // Block 0x28, offset 0xa00
- 0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1,
- 0xa06: 0x05b5, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011,
- 0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041,
- 0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05cd, 0xa15: 0x05cd, 0xa16: 0x0f99, 0xa17: 0x0fa9,
- 0xa18: 0x0fb9, 0xa19: 0x05b5, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05e5, 0xa1d: 0x1099,
- 0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269,
- 0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1,
- 0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008,
- 0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008,
- 0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008,
- 0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008,
- // Block 0x29, offset 0xa40
- 0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008,
- 0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008,
- 0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008,
- 0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008,
- 0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169,
- 0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9,
- 0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05fd, 0xa68: 0x1239, 0xa69: 0x1251,
- 0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9,
- 0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359,
- 0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x0615, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1,
- 0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429,
- // Block 0x2a, offset 0xa80
- 0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008,
- 0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008,
- 0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008,
- 0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008,
- 0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008,
- 0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008,
- 0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008,
- 0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008,
- 0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008,
- 0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008,
- 0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008,
- // Block 0x2b, offset 0xac0
- 0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008,
- 0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008,
- 0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008,
- 0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008,
- 0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x062d, 0xadb: 0x064d, 0xadc: 0x0008, 0xadd: 0x0008,
- 0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008,
- 0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008,
- 0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008,
- 0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008,
- 0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008,
- 0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008,
- // Block 0x2c, offset 0xb00
- 0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008,
- 0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045,
- 0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008,
- 0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008,
- 0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045,
- 0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008,
- 0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045,
- 0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045,
- 0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489,
- 0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1,
- 0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040,
- // Block 0x2d, offset 0xb40
- 0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1,
- 0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591,
- 0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1,
- 0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1,
- 0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771,
- 0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891,
- 0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831,
- 0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951,
- 0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040,
- 0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x0665, 0xb7b: 0x1459,
- 0xb7c: 0x19b1, 0xb7d: 0x067e, 0xb7e: 0x1a31, 0xb7f: 0x069e,
- // Block 0x2e, offset 0xb80
- 0xb80: 0x06be, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040,
- 0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06dd, 0xb89: 0x1471, 0xb8a: 0x06f5, 0xb8b: 0x1489,
- 0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008,
- 0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008,
- 0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x070d, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2,
- 0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61,
- 0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045,
- 0xbaa: 0x0725, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa,
- 0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040,
- 0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x073d, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9,
- 0xbbc: 0x1ce9, 0xbbd: 0x0756, 0xbbe: 0x0776, 0xbbf: 0x0040,
- // Block 0x2f, offset 0xbc0
- 0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a,
- 0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0,
- 0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d,
- 0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x0796,
- 0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018,
- 0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018,
- 0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040,
- 0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a,
- 0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018,
- 0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018,
- 0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x07b6, 0xbff: 0x0018,
- // Block 0x30, offset 0xc00
- 0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018,
- 0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018,
- 0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018,
- 0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9,
- 0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018,
- 0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340,
- 0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040,
- 0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340,
- 0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61,
- 0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07d5,
- 0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71,
- // Block 0x31, offset 0xc40
- 0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61,
- 0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07ed,
- 0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09,
- 0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359,
- 0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040,
- 0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018,
- 0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018,
- 0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018,
- 0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018,
- 0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018,
- 0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018,
- // Block 0x32, offset 0xc80
- 0xc80: 0x0806, 0xc81: 0x0826, 0xc82: 0x1159, 0xc83: 0x0845, 0xc84: 0x0018, 0xc85: 0x0866,
- 0xc86: 0x0886, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x08a5, 0xc8a: 0x0f31, 0xc8b: 0x0249,
- 0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41,
- 0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018,
- 0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269,
- 0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08c5, 0xca2: 0x2061, 0xca3: 0x0018,
- 0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018,
- 0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09,
- 0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9,
- 0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08e5,
- 0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109,
- // Block 0x33, offset 0xcc0
- 0xcc0: 0x0905, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9,
- 0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018,
- 0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151,
- 0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279,
- 0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399,
- 0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x091d, 0xce3: 0x2439,
- 0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x093d, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369,
- 0xcea: 0x24a9, 0xceb: 0x095d, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61,
- 0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x097d, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451,
- 0xcf6: 0x099d, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09bd,
- 0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61,
- // Block 0x34, offset 0xd00
- 0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018,
- 0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040,
- 0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040,
- 0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040,
- 0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040,
- 0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51,
- 0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601,
- 0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691,
- 0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a1e, 0xd35: 0x0a3e,
- 0xd36: 0x0a5e, 0xd37: 0x0a7e, 0xd38: 0x0a9e, 0xd39: 0x0abe, 0xd3a: 0x0ade, 0xd3b: 0x0afe,
- 0xd3c: 0x0b1e, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a,
- // Block 0x35, offset 0xd40
- 0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a,
- 0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040,
- 0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040,
- 0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040,
- 0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b3e, 0xd5d: 0x0b5e,
- 0xd5e: 0x0b7e, 0xd5f: 0x0b9e, 0xd60: 0x0bbe, 0xd61: 0x0bde, 0xd62: 0x0bfe, 0xd63: 0x0c1e,
- 0xd64: 0x0c3e, 0xd65: 0x0c5e, 0xd66: 0x0c7e, 0xd67: 0x0c9e, 0xd68: 0x0cbe, 0xd69: 0x0cde,
- 0xd6a: 0x0cfe, 0xd6b: 0x0d1e, 0xd6c: 0x0d3e, 0xd6d: 0x0d5e, 0xd6e: 0x0d7e, 0xd6f: 0x0d9e,
- 0xd70: 0x0dbe, 0xd71: 0x0dde, 0xd72: 0x0dfe, 0xd73: 0x0e1e, 0xd74: 0x0e3e, 0xd75: 0x0e5e,
- 0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199,
- 0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259,
- // Block 0x36, offset 0xd80
- 0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99,
- 0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089,
- 0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9,
- 0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249,
- 0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71,
- 0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9,
- 0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1,
- 0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018,
- 0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018,
- 0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018,
- 0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018,
- // Block 0x37, offset 0xdc0
- 0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008,
- 0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008,
- 0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008,
- 0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008,
- 0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008,
- 0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ed5,
- 0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d,
- 0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9,
- 0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d,
- 0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008,
- 0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9,
- // Block 0x38, offset 0xe00
- 0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008,
- 0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008,
- 0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008,
- 0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008,
- 0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008,
- 0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008,
- 0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018,
- 0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308,
- 0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040,
- 0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018,
- 0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018,
- // Block 0x39, offset 0xe40
- 0xe40: 0x2715, 0xe41: 0x2735, 0xe42: 0x2755, 0xe43: 0x2775, 0xe44: 0x2795, 0xe45: 0x27b5,
- 0xe46: 0x27d5, 0xe47: 0x27f5, 0xe48: 0x2815, 0xe49: 0x2835, 0xe4a: 0x2855, 0xe4b: 0x2875,
- 0xe4c: 0x2895, 0xe4d: 0x28b5, 0xe4e: 0x28d5, 0xe4f: 0x28f5, 0xe50: 0x2915, 0xe51: 0x2935,
- 0xe52: 0x2955, 0xe53: 0x2975, 0xe54: 0x2995, 0xe55: 0x29b5, 0xe56: 0x0040, 0xe57: 0x0040,
- 0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040,
- 0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040,
- 0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040,
- 0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040,
- 0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040,
- 0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040,
- 0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040,
- // Block 0x3a, offset 0xe80
- 0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008,
- 0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018,
- 0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018,
- 0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018,
- 0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018,
- 0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018,
- 0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018,
- 0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018,
- 0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018,
- 0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29d5, 0xeb9: 0x29f5, 0xeba: 0x2a15, 0xebb: 0x0018,
- 0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018,
- // Block 0x3b, offset 0xec0
- 0xec0: 0x2b55, 0xec1: 0x2b75, 0xec2: 0x2b95, 0xec3: 0x2bb5, 0xec4: 0x2bd5, 0xec5: 0x2bf5,
- 0xec6: 0x2bf5, 0xec7: 0x2bf5, 0xec8: 0x2c15, 0xec9: 0x2c15, 0xeca: 0x2c15, 0xecb: 0x2c15,
- 0xecc: 0x2c35, 0xecd: 0x2c35, 0xece: 0x2c35, 0xecf: 0x2c55, 0xed0: 0x2c75, 0xed1: 0x2c75,
- 0xed2: 0x2a95, 0xed3: 0x2a95, 0xed4: 0x2c75, 0xed5: 0x2c75, 0xed6: 0x2c95, 0xed7: 0x2c95,
- 0xed8: 0x2c75, 0xed9: 0x2c75, 0xeda: 0x2a95, 0xedb: 0x2a95, 0xedc: 0x2c75, 0xedd: 0x2c75,
- 0xede: 0x2c55, 0xedf: 0x2c55, 0xee0: 0x2cb5, 0xee1: 0x2cb5, 0xee2: 0x2cd5, 0xee3: 0x2cd5,
- 0xee4: 0x0040, 0xee5: 0x2cf5, 0xee6: 0x2d15, 0xee7: 0x2d35, 0xee8: 0x2d35, 0xee9: 0x2d55,
- 0xeea: 0x2d75, 0xeeb: 0x2d95, 0xeec: 0x2db5, 0xeed: 0x2dd5, 0xeee: 0x2df5, 0xeef: 0x2e15,
- 0xef0: 0x2e35, 0xef1: 0x2e55, 0xef2: 0x2e55, 0xef3: 0x2e75, 0xef4: 0x2e95, 0xef5: 0x2e95,
- 0xef6: 0x2eb5, 0xef7: 0x2ed5, 0xef8: 0x2e75, 0xef9: 0x2ef5, 0xefa: 0x2f15, 0xefb: 0x2ef5,
- 0xefc: 0x2e75, 0xefd: 0x2f35, 0xefe: 0x2f55, 0xeff: 0x2f75,
- // Block 0x3c, offset 0xf00
- 0xf00: 0x2f95, 0xf01: 0x2fb5, 0xf02: 0x2d15, 0xf03: 0x2cf5, 0xf04: 0x2fd5, 0xf05: 0x2ff5,
- 0xf06: 0x3015, 0xf07: 0x3035, 0xf08: 0x3055, 0xf09: 0x3075, 0xf0a: 0x3095, 0xf0b: 0x30b5,
- 0xf0c: 0x30d5, 0xf0d: 0x30f5, 0xf0e: 0x3115, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018,
- 0xf12: 0x3135, 0xf13: 0x3155, 0xf14: 0x3175, 0xf15: 0x3195, 0xf16: 0x31b5, 0xf17: 0x31d5,
- 0xf18: 0x31f5, 0xf19: 0x3215, 0xf1a: 0x3235, 0xf1b: 0x3255, 0xf1c: 0x3175, 0xf1d: 0x3275,
- 0xf1e: 0x3295, 0xf1f: 0x32b5, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008,
- 0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008,
- 0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008,
- 0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008,
- 0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0008,
- 0xf3c: 0x0008, 0xf3d: 0x0008, 0xf3e: 0x0008, 0xf3f: 0x0008,
- // Block 0x3d, offset 0xf40
- 0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32d5, 0xf45: 0x32f5,
- 0xf46: 0x3315, 0xf47: 0x3335, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018,
- 0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x3355, 0xf51: 0x3761,
- 0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1,
- 0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881,
- 0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x3375, 0xf61: 0x3395, 0xf62: 0x33b5, 0xf63: 0x33d5,
- 0xf64: 0x33f5, 0xf65: 0x33f5, 0xf66: 0x3415, 0xf67: 0x3435, 0xf68: 0x3455, 0xf69: 0x3475,
- 0xf6a: 0x3495, 0xf6b: 0x34b5, 0xf6c: 0x34d5, 0xf6d: 0x34f5, 0xf6e: 0x3515, 0xf6f: 0x3535,
- 0xf70: 0x3555, 0xf71: 0x3575, 0xf72: 0x3595, 0xf73: 0x35b5, 0xf74: 0x35d5, 0xf75: 0x35f5,
- 0xf76: 0x3615, 0xf77: 0x3635, 0xf78: 0x3655, 0xf79: 0x3675, 0xf7a: 0x3695, 0xf7b: 0x36b5,
- 0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36d5, 0xf7f: 0x0018,
- // Block 0x3e, offset 0xf80
- 0xf80: 0x36f5, 0xf81: 0x3715, 0xf82: 0x3735, 0xf83: 0x3755, 0xf84: 0x3775, 0xf85: 0x3795,
- 0xf86: 0x37b5, 0xf87: 0x37d5, 0xf88: 0x37f5, 0xf89: 0x3815, 0xf8a: 0x3835, 0xf8b: 0x3855,
- 0xf8c: 0x3875, 0xf8d: 0x3895, 0xf8e: 0x38b5, 0xf8f: 0x38d5, 0xf90: 0x38f5, 0xf91: 0x3915,
- 0xf92: 0x3935, 0xf93: 0x3955, 0xf94: 0x3975, 0xf95: 0x3995, 0xf96: 0x39b5, 0xf97: 0x39d5,
- 0xf98: 0x39f5, 0xf99: 0x3a15, 0xf9a: 0x3a35, 0xf9b: 0x3a55, 0xf9c: 0x3a75, 0xf9d: 0x3a95,
- 0xf9e: 0x3ab5, 0xf9f: 0x3ad5, 0xfa0: 0x3af5, 0xfa1: 0x3b15, 0xfa2: 0x3b35, 0xfa3: 0x3b55,
- 0xfa4: 0x3b75, 0xfa5: 0x3b95, 0xfa6: 0x1295, 0xfa7: 0x3bb5, 0xfa8: 0x3bd5, 0xfa9: 0x3bf5,
- 0xfaa: 0x3c15, 0xfab: 0x3c35, 0xfac: 0x3c55, 0xfad: 0x3c75, 0xfae: 0x23b5, 0xfaf: 0x3c95,
- 0xfb0: 0x3cb5, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999,
- 0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29,
- 0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89,
- // Block 0x3f, offset 0xfc0
- 0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69,
- 0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69,
- 0xfcc: 0x3c99, 0xfcd: 0x3cd5, 0xfce: 0x3cb1, 0xfcf: 0x3cf5, 0xfd0: 0x3d15, 0xfd1: 0x3d2d,
- 0xfd2: 0x3d45, 0xfd3: 0x3d5d, 0xfd4: 0x3d75, 0xfd5: 0x3d75, 0xfd6: 0x3d5d, 0xfd7: 0x3d8d,
- 0xfd8: 0x07d5, 0xfd9: 0x3da5, 0xfda: 0x3dbd, 0xfdb: 0x3dd5, 0xfdc: 0x3ded, 0xfdd: 0x3e05,
- 0xfde: 0x3e1d, 0xfdf: 0x3e35, 0xfe0: 0x3e4d, 0xfe1: 0x3e65, 0xfe2: 0x3e7d, 0xfe3: 0x3e95,
- 0xfe4: 0x3ead, 0xfe5: 0x3ead, 0xfe6: 0x3ec5, 0xfe7: 0x3ec5, 0xfe8: 0x3edd, 0xfe9: 0x3edd,
- 0xfea: 0x3ef5, 0xfeb: 0x3f0d, 0xfec: 0x3f25, 0xfed: 0x3f3d, 0xfee: 0x3f55, 0xfef: 0x3f55,
- 0xff0: 0x3f6d, 0xff1: 0x3f6d, 0xff2: 0x3f6d, 0xff3: 0x3f85, 0xff4: 0x3f9d, 0xff5: 0x3fb5,
- 0xff6: 0x3fcd, 0xff7: 0x3fb5, 0xff8: 0x3fe5, 0xff9: 0x3ffd, 0xffa: 0x3f85, 0xffb: 0x4015,
- 0xffc: 0x402d, 0xffd: 0x402d, 0xffe: 0x402d, 0xfff: 0x3cc9,
- // Block 0x40, offset 0x1000
- 0x1000: 0x3d01, 0x1001: 0x3d69, 0x1002: 0x3dd1, 0x1003: 0x3e39, 0x1004: 0x3e89, 0x1005: 0x3ef1,
- 0x1006: 0x3f41, 0x1007: 0x3f91, 0x1008: 0x4011, 0x1009: 0x4079, 0x100a: 0x40c9, 0x100b: 0x4119,
- 0x100c: 0x4169, 0x100d: 0x41d1, 0x100e: 0x4239, 0x100f: 0x4289, 0x1010: 0x42d9, 0x1011: 0x4311,
- 0x1012: 0x4361, 0x1013: 0x43c9, 0x1014: 0x4431, 0x1015: 0x4469, 0x1016: 0x44e9, 0x1017: 0x4581,
- 0x1018: 0x4601, 0x1019: 0x4651, 0x101a: 0x46d1, 0x101b: 0x4751, 0x101c: 0x47b9, 0x101d: 0x4809,
- 0x101e: 0x4859, 0x101f: 0x48a9, 0x1020: 0x4911, 0x1021: 0x4991, 0x1022: 0x49f9, 0x1023: 0x4a49,
- 0x1024: 0x4a99, 0x1025: 0x4ae9, 0x1026: 0x4b21, 0x1027: 0x4b59, 0x1028: 0x4b91, 0x1029: 0x4bc9,
- 0x102a: 0x4c19, 0x102b: 0x4c69, 0x102c: 0x4ce9, 0x102d: 0x4d39, 0x102e: 0x4da1, 0x102f: 0x4e21,
- 0x1030: 0x4e71, 0x1031: 0x4ea9, 0x1032: 0x4ee1, 0x1033: 0x4f61, 0x1034: 0x4fc9, 0x1035: 0x5049,
- 0x1036: 0x5099, 0x1037: 0x5119, 0x1038: 0x5151, 0x1039: 0x51a1, 0x103a: 0x51f1, 0x103b: 0x5241,
- 0x103c: 0x5291, 0x103d: 0x52e1, 0x103e: 0x5349, 0x103f: 0x5399,
- // Block 0x41, offset 0x1040
- 0x1040: 0x53d1, 0x1041: 0x5421, 0x1042: 0x5471, 0x1043: 0x54c1, 0x1044: 0x5529, 0x1045: 0x5579,
- 0x1046: 0x55c9, 0x1047: 0x5619, 0x1048: 0x5699, 0x1049: 0x5701, 0x104a: 0x5739, 0x104b: 0x57b9,
- 0x104c: 0x57f1, 0x104d: 0x5859, 0x104e: 0x58c1, 0x104f: 0x5911, 0x1050: 0x5961, 0x1051: 0x59b1,
- 0x1052: 0x5a19, 0x1053: 0x5a51, 0x1054: 0x5aa1, 0x1055: 0x5b09, 0x1056: 0x5b41, 0x1057: 0x5bc1,
- 0x1058: 0x5c11, 0x1059: 0x5c39, 0x105a: 0x5c61, 0x105b: 0x5c89, 0x105c: 0x5cb1, 0x105d: 0x5cd9,
- 0x105e: 0x5d01, 0x105f: 0x5d29, 0x1060: 0x5d51, 0x1061: 0x5d79, 0x1062: 0x5da1, 0x1063: 0x5dd1,
- 0x1064: 0x5e01, 0x1065: 0x5e31, 0x1066: 0x5e61, 0x1067: 0x5e91, 0x1068: 0x5ec1, 0x1069: 0x5ef1,
- 0x106a: 0x5f21, 0x106b: 0x5f51, 0x106c: 0x5f81, 0x106d: 0x5fb1, 0x106e: 0x5fe1, 0x106f: 0x6011,
- 0x1070: 0x6041, 0x1071: 0x4045, 0x1072: 0x6071, 0x1073: 0x6089, 0x1074: 0x4065, 0x1075: 0x60a1,
- 0x1076: 0x60b9, 0x1077: 0x60d1, 0x1078: 0x4085, 0x1079: 0x4085, 0x107a: 0x60e9, 0x107b: 0x6101,
- 0x107c: 0x6139, 0x107d: 0x6171, 0x107e: 0x61a9, 0x107f: 0x61e1,
- // Block 0x42, offset 0x1080
- 0x1080: 0x6249, 0x1081: 0x6261, 0x1082: 0x40a5, 0x1083: 0x6279, 0x1084: 0x6291, 0x1085: 0x62a9,
- 0x1086: 0x62c1, 0x1087: 0x62d9, 0x1088: 0x40c5, 0x1089: 0x62f1, 0x108a: 0x6319, 0x108b: 0x6331,
- 0x108c: 0x40e5, 0x108d: 0x40e5, 0x108e: 0x6349, 0x108f: 0x6361, 0x1090: 0x6379, 0x1091: 0x4105,
- 0x1092: 0x4125, 0x1093: 0x4145, 0x1094: 0x4165, 0x1095: 0x4185, 0x1096: 0x6391, 0x1097: 0x63a9,
- 0x1098: 0x63c1, 0x1099: 0x63d9, 0x109a: 0x63f1, 0x109b: 0x41a5, 0x109c: 0x6409, 0x109d: 0x6421,
- 0x109e: 0x6439, 0x109f: 0x41c5, 0x10a0: 0x41e5, 0x10a1: 0x6451, 0x10a2: 0x4205, 0x10a3: 0x4225,
- 0x10a4: 0x4245, 0x10a5: 0x6469, 0x10a6: 0x4265, 0x10a7: 0x6481, 0x10a8: 0x64b1, 0x10a9: 0x6249,
- 0x10aa: 0x4285, 0x10ab: 0x42a5, 0x10ac: 0x42c5, 0x10ad: 0x42e5, 0x10ae: 0x64e9, 0x10af: 0x6529,
- 0x10b0: 0x6571, 0x10b1: 0x6589, 0x10b2: 0x4305, 0x10b3: 0x65a1, 0x10b4: 0x65b9, 0x10b5: 0x65d1,
- 0x10b6: 0x4325, 0x10b7: 0x65e9, 0x10b8: 0x6601, 0x10b9: 0x65e9, 0x10ba: 0x6619, 0x10bb: 0x6631,
- 0x10bc: 0x4345, 0x10bd: 0x6649, 0x10be: 0x6661, 0x10bf: 0x6649,
- // Block 0x43, offset 0x10c0
- 0x10c0: 0x4365, 0x10c1: 0x4385, 0x10c2: 0x0040, 0x10c3: 0x6679, 0x10c4: 0x6691, 0x10c5: 0x66a9,
- 0x10c6: 0x66c1, 0x10c7: 0x0040, 0x10c8: 0x66f9, 0x10c9: 0x6711, 0x10ca: 0x6729, 0x10cb: 0x6741,
- 0x10cc: 0x6759, 0x10cd: 0x6771, 0x10ce: 0x6439, 0x10cf: 0x6789, 0x10d0: 0x67a1, 0x10d1: 0x67b9,
- 0x10d2: 0x43a5, 0x10d3: 0x67d1, 0x10d4: 0x62c1, 0x10d5: 0x43c5, 0x10d6: 0x43e5, 0x10d7: 0x67e9,
- 0x10d8: 0x0040, 0x10d9: 0x4405, 0x10da: 0x6801, 0x10db: 0x6819, 0x10dc: 0x6831, 0x10dd: 0x6849,
- 0x10de: 0x6861, 0x10df: 0x6891, 0x10e0: 0x68c1, 0x10e1: 0x68e9, 0x10e2: 0x6911, 0x10e3: 0x6939,
- 0x10e4: 0x6961, 0x10e5: 0x6989, 0x10e6: 0x69b1, 0x10e7: 0x69d9, 0x10e8: 0x6a01, 0x10e9: 0x6a29,
- 0x10ea: 0x6a59, 0x10eb: 0x6a89, 0x10ec: 0x6ab9, 0x10ed: 0x6ae9, 0x10ee: 0x6b19, 0x10ef: 0x6b49,
- 0x10f0: 0x6b79, 0x10f1: 0x6ba9, 0x10f2: 0x6bd9, 0x10f3: 0x6c09, 0x10f4: 0x6c39, 0x10f5: 0x6c69,
- 0x10f6: 0x6c99, 0x10f7: 0x6cc9, 0x10f8: 0x6cf9, 0x10f9: 0x6d29, 0x10fa: 0x6d59, 0x10fb: 0x6d89,
- 0x10fc: 0x6db9, 0x10fd: 0x6de9, 0x10fe: 0x6e19, 0x10ff: 0x4425,
- // Block 0x44, offset 0x1100
- 0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008,
- 0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008,
- 0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008,
- 0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008,
- 0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008,
- 0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008,
- 0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008,
- 0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308,
- 0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308,
- 0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308,
- 0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008,
- // Block 0x45, offset 0x1140
- 0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008,
- 0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008,
- 0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008,
- 0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008,
- 0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e49,
- 0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008,
- 0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008,
- 0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008,
- 0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008,
- 0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008,
- 0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008,
- // Block 0x46, offset 0x1180
- 0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018,
- 0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018,
- 0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018,
- 0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008,
- 0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008,
- 0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008,
- 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,
- 0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008,
- 0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008,
- 0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008,
- 0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008,
- // Block 0x47, offset 0x11c0
- 0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008,
- 0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008,
- 0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008,
- 0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008,
- 0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008,
- 0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008,
- 0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008,
- 0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008,
- 0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008,
- 0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d,
- 0x11fc: 0x0008, 0x11fd: 0x4445, 0x11fe: 0xe00d, 0x11ff: 0x0008,
- // Block 0x48, offset 0x1200
- 0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008,
- 0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d,
- 0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008,
- 0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008,
- 0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008,
- 0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008,
- 0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008,
- 0x122a: 0x6e61, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e79, 0x122e: 0x1221, 0x122f: 0x0008,
- 0x1230: 0x6e91, 0x1231: 0x6ea9, 0x1232: 0x1239, 0x1233: 0x4465, 0x1234: 0xe00d, 0x1235: 0x0008,
- 0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0xe00d, 0x1239: 0x0008, 0x123a: 0xe00d, 0x123b: 0x0008,
- 0x123c: 0xe00d, 0x123d: 0x0008, 0x123e: 0xe00d, 0x123f: 0x0008,
- // Block 0x49, offset 0x1240
- 0x1240: 0x650d, 0x1241: 0x652d, 0x1242: 0x654d, 0x1243: 0x656d, 0x1244: 0x658d, 0x1245: 0x65ad,
- 0x1246: 0x65cd, 0x1247: 0x65ed, 0x1248: 0x660d, 0x1249: 0x662d, 0x124a: 0x664d, 0x124b: 0x666d,
- 0x124c: 0x668d, 0x124d: 0x66ad, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x66cd, 0x1251: 0x0008,
- 0x1252: 0x66ed, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x670d, 0x1256: 0x672d, 0x1257: 0x674d,
- 0x1258: 0x676d, 0x1259: 0x678d, 0x125a: 0x67ad, 0x125b: 0x67cd, 0x125c: 0x67ed, 0x125d: 0x680d,
- 0x125e: 0x682d, 0x125f: 0x0008, 0x1260: 0x684d, 0x1261: 0x0008, 0x1262: 0x686d, 0x1263: 0x0008,
- 0x1264: 0x0008, 0x1265: 0x688d, 0x1266: 0x68ad, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008,
- 0x126a: 0x68cd, 0x126b: 0x68ed, 0x126c: 0x690d, 0x126d: 0x692d, 0x126e: 0x694d, 0x126f: 0x696d,
- 0x1270: 0x698d, 0x1271: 0x69ad, 0x1272: 0x69cd, 0x1273: 0x69ed, 0x1274: 0x6a0d, 0x1275: 0x6a2d,
- 0x1276: 0x6a4d, 0x1277: 0x6a6d, 0x1278: 0x6a8d, 0x1279: 0x6aad, 0x127a: 0x6acd, 0x127b: 0x6aed,
- 0x127c: 0x6b0d, 0x127d: 0x6b2d, 0x127e: 0x6b4d, 0x127f: 0x6b6d,
- // Block 0x4a, offset 0x1280
- 0x1280: 0x7acd, 0x1281: 0x7aed, 0x1282: 0x7b0d, 0x1283: 0x7b2d, 0x1284: 0x7b4d, 0x1285: 0x7b6d,
- 0x1286: 0x7b8d, 0x1287: 0x7bad, 0x1288: 0x7bcd, 0x1289: 0x7bed, 0x128a: 0x7c0d, 0x128b: 0x7c2d,
- 0x128c: 0x7c4d, 0x128d: 0x7c6d, 0x128e: 0x7c8d, 0x128f: 0x6f19, 0x1290: 0x6f41, 0x1291: 0x6f69,
- 0x1292: 0x7cad, 0x1293: 0x7ccd, 0x1294: 0x7ced, 0x1295: 0x6f91, 0x1296: 0x6fb9, 0x1297: 0x6fe1,
- 0x1298: 0x7d0d, 0x1299: 0x7d2d, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040,
- 0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040,
- 0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040,
- 0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040,
- 0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040,
- 0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040,
- 0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040,
- // Block 0x4b, offset 0x12c0
- 0x12c0: 0x7009, 0x12c1: 0x7021, 0x12c2: 0x7039, 0x12c3: 0x7d4d, 0x12c4: 0x7d6d, 0x12c5: 0x7051,
- 0x12c6: 0x7051, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040,
- 0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040,
- 0x12d2: 0x0040, 0x12d3: 0x7069, 0x12d4: 0x7091, 0x12d5: 0x70b9, 0x12d6: 0x70e1, 0x12d7: 0x7109,
- 0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x7131,
- 0x12de: 0x3308, 0x12df: 0x7159, 0x12e0: 0x7181, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7199,
- 0x12e4: 0x71b1, 0x12e5: 0x71c9, 0x12e6: 0x71e1, 0x12e7: 0x71f9, 0x12e8: 0x7211, 0x12e9: 0x1fb2,
- 0x12ea: 0x7229, 0x12eb: 0x7251, 0x12ec: 0x7279, 0x12ed: 0x72b1, 0x12ee: 0x72e9, 0x12ef: 0x7311,
- 0x12f0: 0x7339, 0x12f1: 0x7361, 0x12f2: 0x7389, 0x12f3: 0x73b1, 0x12f4: 0x73d9, 0x12f5: 0x7401,
- 0x12f6: 0x7429, 0x12f7: 0x0040, 0x12f8: 0x7451, 0x12f9: 0x7479, 0x12fa: 0x74a1, 0x12fb: 0x74c9,
- 0x12fc: 0x74f1, 0x12fd: 0x0040, 0x12fe: 0x7519, 0x12ff: 0x0040,
- // Block 0x4c, offset 0x1300
- 0x1300: 0x7541, 0x1301: 0x7569, 0x1302: 0x0040, 0x1303: 0x7591, 0x1304: 0x75b9, 0x1305: 0x0040,
- 0x1306: 0x75e1, 0x1307: 0x7609, 0x1308: 0x7631, 0x1309: 0x7659, 0x130a: 0x7681, 0x130b: 0x76a9,
- 0x130c: 0x76d1, 0x130d: 0x76f9, 0x130e: 0x7721, 0x130f: 0x7749, 0x1310: 0x7771, 0x1311: 0x7771,
- 0x1312: 0x7789, 0x1313: 0x7789, 0x1314: 0x7789, 0x1315: 0x7789, 0x1316: 0x77a1, 0x1317: 0x77a1,
- 0x1318: 0x77a1, 0x1319: 0x77a1, 0x131a: 0x77b9, 0x131b: 0x77b9, 0x131c: 0x77b9, 0x131d: 0x77b9,
- 0x131e: 0x77d1, 0x131f: 0x77d1, 0x1320: 0x77d1, 0x1321: 0x77d1, 0x1322: 0x77e9, 0x1323: 0x77e9,
- 0x1324: 0x77e9, 0x1325: 0x77e9, 0x1326: 0x7801, 0x1327: 0x7801, 0x1328: 0x7801, 0x1329: 0x7801,
- 0x132a: 0x7819, 0x132b: 0x7819, 0x132c: 0x7819, 0x132d: 0x7819, 0x132e: 0x7831, 0x132f: 0x7831,
- 0x1330: 0x7831, 0x1331: 0x7831, 0x1332: 0x7849, 0x1333: 0x7849, 0x1334: 0x7849, 0x1335: 0x7849,
- 0x1336: 0x7861, 0x1337: 0x7861, 0x1338: 0x7861, 0x1339: 0x7861, 0x133a: 0x7879, 0x133b: 0x7879,
- 0x133c: 0x7879, 0x133d: 0x7879, 0x133e: 0x7891, 0x133f: 0x7891,
- // Block 0x4d, offset 0x1340
- 0x1340: 0x7891, 0x1341: 0x7891, 0x1342: 0x78a9, 0x1343: 0x78a9, 0x1344: 0x78c1, 0x1345: 0x78c1,
- 0x1346: 0x78d9, 0x1347: 0x78d9, 0x1348: 0x78f1, 0x1349: 0x78f1, 0x134a: 0x7909, 0x134b: 0x7909,
- 0x134c: 0x7921, 0x134d: 0x7921, 0x134e: 0x7939, 0x134f: 0x7939, 0x1350: 0x7939, 0x1351: 0x7939,
- 0x1352: 0x7951, 0x1353: 0x7951, 0x1354: 0x7951, 0x1355: 0x7951, 0x1356: 0x7969, 0x1357: 0x7969,
- 0x1358: 0x7969, 0x1359: 0x7969, 0x135a: 0x7981, 0x135b: 0x7981, 0x135c: 0x7981, 0x135d: 0x7981,
- 0x135e: 0x7999, 0x135f: 0x7999, 0x1360: 0x79b1, 0x1361: 0x79b1, 0x1362: 0x79b1, 0x1363: 0x79b1,
- 0x1364: 0x79c9, 0x1365: 0x79c9, 0x1366: 0x79e1, 0x1367: 0x79e1, 0x1368: 0x79e1, 0x1369: 0x79e1,
- 0x136a: 0x79f9, 0x136b: 0x79f9, 0x136c: 0x79f9, 0x136d: 0x79f9, 0x136e: 0x7a11, 0x136f: 0x7a11,
- 0x1370: 0x7a29, 0x1371: 0x7a29, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818,
- 0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818,
- 0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818,
- // Block 0x4e, offset 0x1380
- 0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040,
- 0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040,
- 0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040,
- 0x1392: 0x0040, 0x1393: 0x7a41, 0x1394: 0x7a41, 0x1395: 0x7a41, 0x1396: 0x7a41, 0x1397: 0x7a59,
- 0x1398: 0x7a59, 0x1399: 0x7a71, 0x139a: 0x7a71, 0x139b: 0x7a89, 0x139c: 0x7a89, 0x139d: 0x0479,
- 0x139e: 0x7aa1, 0x139f: 0x7aa1, 0x13a0: 0x7ab9, 0x13a1: 0x7ab9, 0x13a2: 0x7ad1, 0x13a3: 0x7ad1,
- 0x13a4: 0x7ae9, 0x13a5: 0x7ae9, 0x13a6: 0x7ae9, 0x13a7: 0x7ae9, 0x13a8: 0x7b01, 0x13a9: 0x7b01,
- 0x13aa: 0x7b19, 0x13ab: 0x7b19, 0x13ac: 0x7b41, 0x13ad: 0x7b41, 0x13ae: 0x7b69, 0x13af: 0x7b69,
- 0x13b0: 0x7b91, 0x13b1: 0x7b91, 0x13b2: 0x7bb9, 0x13b3: 0x7bb9, 0x13b4: 0x7be1, 0x13b5: 0x7be1,
- 0x13b6: 0x7c09, 0x13b7: 0x7c09, 0x13b8: 0x7c09, 0x13b9: 0x7c31, 0x13ba: 0x7c31, 0x13bb: 0x7c31,
- 0x13bc: 0x7c59, 0x13bd: 0x7c59, 0x13be: 0x7c59, 0x13bf: 0x7c59,
- // Block 0x4f, offset 0x13c0
- 0x13c0: 0x8649, 0x13c1: 0x8671, 0x13c2: 0x8699, 0x13c3: 0x86c1, 0x13c4: 0x86e9, 0x13c5: 0x8711,
- 0x13c6: 0x8739, 0x13c7: 0x8761, 0x13c8: 0x8789, 0x13c9: 0x87b1, 0x13ca: 0x87d9, 0x13cb: 0x8801,
- 0x13cc: 0x8829, 0x13cd: 0x8851, 0x13ce: 0x8879, 0x13cf: 0x88a1, 0x13d0: 0x88c9, 0x13d1: 0x88f1,
- 0x13d2: 0x8919, 0x13d3: 0x8941, 0x13d4: 0x8969, 0x13d5: 0x8991, 0x13d6: 0x89b9, 0x13d7: 0x89e1,
- 0x13d8: 0x8a09, 0x13d9: 0x8a31, 0x13da: 0x8a59, 0x13db: 0x8a81, 0x13dc: 0x8aa9, 0x13dd: 0x8ad1,
- 0x13de: 0x8afa, 0x13df: 0x8b2a, 0x13e0: 0x8b5a, 0x13e1: 0x8b8a, 0x13e2: 0x8bba, 0x13e3: 0x8bea,
- 0x13e4: 0x8c19, 0x13e5: 0x8c41, 0x13e6: 0x7cc1, 0x13e7: 0x8c69, 0x13e8: 0x7c31, 0x13e9: 0x7ce9,
- 0x13ea: 0x8c91, 0x13eb: 0x8cb9, 0x13ec: 0x7d89, 0x13ed: 0x8ce1, 0x13ee: 0x7db1, 0x13ef: 0x7dd9,
- 0x13f0: 0x8d09, 0x13f1: 0x8d31, 0x13f2: 0x7e79, 0x13f3: 0x8d59, 0x13f4: 0x7ea1, 0x13f5: 0x7ec9,
- 0x13f6: 0x8d81, 0x13f7: 0x8da9, 0x13f8: 0x7f19, 0x13f9: 0x8dd1, 0x13fa: 0x7f41, 0x13fb: 0x7f69,
- 0x13fc: 0x83f1, 0x13fd: 0x8419, 0x13fe: 0x8491, 0x13ff: 0x84b9,
- // Block 0x50, offset 0x1400
- 0x1400: 0x84e1, 0x1401: 0x8581, 0x1402: 0x85a9, 0x1403: 0x85d1, 0x1404: 0x85f9, 0x1405: 0x8699,
- 0x1406: 0x86c1, 0x1407: 0x86e9, 0x1408: 0x8df9, 0x1409: 0x8789, 0x140a: 0x8e21, 0x140b: 0x8e49,
- 0x140c: 0x8879, 0x140d: 0x8e71, 0x140e: 0x88a1, 0x140f: 0x88c9, 0x1410: 0x8ad1, 0x1411: 0x8e99,
- 0x1412: 0x8ec1, 0x1413: 0x8a09, 0x1414: 0x8ee9, 0x1415: 0x8a31, 0x1416: 0x8a59, 0x1417: 0x7c71,
- 0x1418: 0x7c99, 0x1419: 0x8f11, 0x141a: 0x7cc1, 0x141b: 0x8f39, 0x141c: 0x7d11, 0x141d: 0x7d39,
- 0x141e: 0x7d61, 0x141f: 0x7d89, 0x1420: 0x8f61, 0x1421: 0x7e01, 0x1422: 0x7e29, 0x1423: 0x7e51,
- 0x1424: 0x7e79, 0x1425: 0x8f89, 0x1426: 0x7f19, 0x1427: 0x7f91, 0x1428: 0x7fb9, 0x1429: 0x7fe1,
- 0x142a: 0x8009, 0x142b: 0x8031, 0x142c: 0x8081, 0x142d: 0x80a9, 0x142e: 0x80d1, 0x142f: 0x80f9,
- 0x1430: 0x8121, 0x1431: 0x8149, 0x1432: 0x8fb1, 0x1433: 0x8171, 0x1434: 0x8199, 0x1435: 0x81c1,
- 0x1436: 0x81e9, 0x1437: 0x8211, 0x1438: 0x8239, 0x1439: 0x8289, 0x143a: 0x82b1, 0x143b: 0x82d9,
- 0x143c: 0x8301, 0x143d: 0x8329, 0x143e: 0x8351, 0x143f: 0x8379,
- // Block 0x51, offset 0x1440
- 0x1440: 0x83a1, 0x1441: 0x83c9, 0x1442: 0x8441, 0x1443: 0x8469, 0x1444: 0x8509, 0x1445: 0x8531,
- 0x1446: 0x8559, 0x1447: 0x8581, 0x1448: 0x85a9, 0x1449: 0x8621, 0x144a: 0x8649, 0x144b: 0x8671,
- 0x144c: 0x8699, 0x144d: 0x8fd9, 0x144e: 0x8711, 0x144f: 0x8739, 0x1450: 0x8761, 0x1451: 0x8789,
- 0x1452: 0x8801, 0x1453: 0x8829, 0x1454: 0x8851, 0x1455: 0x8879, 0x1456: 0x9001, 0x1457: 0x88f1,
- 0x1458: 0x8919, 0x1459: 0x9029, 0x145a: 0x8991, 0x145b: 0x89b9, 0x145c: 0x89e1, 0x145d: 0x8a09,
- 0x145e: 0x9051, 0x145f: 0x7cc1, 0x1460: 0x8f39, 0x1461: 0x7d89, 0x1462: 0x8f61, 0x1463: 0x7e79,
- 0x1464: 0x8f89, 0x1465: 0x7f19, 0x1466: 0x9079, 0x1467: 0x8121, 0x1468: 0x90a1, 0x1469: 0x90c9,
- 0x146a: 0x90f1, 0x146b: 0x8581, 0x146c: 0x85a9, 0x146d: 0x8699, 0x146e: 0x8879, 0x146f: 0x9001,
- 0x1470: 0x8a09, 0x1471: 0x9051, 0x1472: 0x9119, 0x1473: 0x9151, 0x1474: 0x9189, 0x1475: 0x91c1,
- 0x1476: 0x91e9, 0x1477: 0x9211, 0x1478: 0x9239, 0x1479: 0x9261, 0x147a: 0x9289, 0x147b: 0x92b1,
- 0x147c: 0x92d9, 0x147d: 0x9301, 0x147e: 0x9329, 0x147f: 0x9351,
- // Block 0x52, offset 0x1480
- 0x1480: 0x9379, 0x1481: 0x93a1, 0x1482: 0x93c9, 0x1483: 0x93f1, 0x1484: 0x9419, 0x1485: 0x9441,
- 0x1486: 0x9469, 0x1487: 0x9491, 0x1488: 0x94b9, 0x1489: 0x94e1, 0x148a: 0x9509, 0x148b: 0x9531,
- 0x148c: 0x90c9, 0x148d: 0x9559, 0x148e: 0x9581, 0x148f: 0x95a9, 0x1490: 0x95d1, 0x1491: 0x91c1,
- 0x1492: 0x91e9, 0x1493: 0x9211, 0x1494: 0x9239, 0x1495: 0x9261, 0x1496: 0x9289, 0x1497: 0x92b1,
- 0x1498: 0x92d9, 0x1499: 0x9301, 0x149a: 0x9329, 0x149b: 0x9351, 0x149c: 0x9379, 0x149d: 0x93a1,
- 0x149e: 0x93c9, 0x149f: 0x93f1, 0x14a0: 0x9419, 0x14a1: 0x9441, 0x14a2: 0x9469, 0x14a3: 0x9491,
- 0x14a4: 0x94b9, 0x14a5: 0x94e1, 0x14a6: 0x9509, 0x14a7: 0x9531, 0x14a8: 0x90c9, 0x14a9: 0x9559,
- 0x14aa: 0x9581, 0x14ab: 0x95a9, 0x14ac: 0x95d1, 0x14ad: 0x94e1, 0x14ae: 0x9509, 0x14af: 0x9531,
- 0x14b0: 0x90c9, 0x14b1: 0x90a1, 0x14b2: 0x90f1, 0x14b3: 0x8261, 0x14b4: 0x80a9, 0x14b5: 0x80d1,
- 0x14b6: 0x80f9, 0x14b7: 0x94e1, 0x14b8: 0x9509, 0x14b9: 0x9531, 0x14ba: 0x8261, 0x14bb: 0x8289,
- 0x14bc: 0x95f9, 0x14bd: 0x95f9, 0x14be: 0x0018, 0x14bf: 0x0018,
- // Block 0x53, offset 0x14c0
- 0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040,
- 0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040,
- 0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x9621, 0x14d1: 0x9659,
- 0x14d2: 0x9659, 0x14d3: 0x9691, 0x14d4: 0x96c9, 0x14d5: 0x9701, 0x14d6: 0x9739, 0x14d7: 0x9771,
- 0x14d8: 0x97a9, 0x14d9: 0x97a9, 0x14da: 0x97e1, 0x14db: 0x9819, 0x14dc: 0x9851, 0x14dd: 0x9889,
- 0x14de: 0x98c1, 0x14df: 0x98f9, 0x14e0: 0x98f9, 0x14e1: 0x9931, 0x14e2: 0x9969, 0x14e3: 0x9969,
- 0x14e4: 0x99a1, 0x14e5: 0x99a1, 0x14e6: 0x99d9, 0x14e7: 0x9a11, 0x14e8: 0x9a11, 0x14e9: 0x9a49,
- 0x14ea: 0x9a81, 0x14eb: 0x9a81, 0x14ec: 0x9ab9, 0x14ed: 0x9ab9, 0x14ee: 0x9af1, 0x14ef: 0x9b29,
- 0x14f0: 0x9b29, 0x14f1: 0x9b61, 0x14f2: 0x9b61, 0x14f3: 0x9b99, 0x14f4: 0x9bd1, 0x14f5: 0x9c09,
- 0x14f6: 0x9c41, 0x14f7: 0x9c41, 0x14f8: 0x9c79, 0x14f9: 0x9cb1, 0x14fa: 0x9ce9, 0x14fb: 0x9d21,
- 0x14fc: 0x9d59, 0x14fd: 0x9d59, 0x14fe: 0x9d91, 0x14ff: 0x9dc9,
- // Block 0x54, offset 0x1500
- 0x1500: 0xa999, 0x1501: 0xa9d1, 0x1502: 0xaa09, 0x1503: 0xa8f1, 0x1504: 0x9c09, 0x1505: 0x99d9,
- 0x1506: 0xaa41, 0x1507: 0xaa79, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040,
- 0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040,
- 0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040,
- 0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040,
- 0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040,
- 0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040,
- 0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,
- 0x1530: 0xaab1, 0x1531: 0xaae9, 0x1532: 0xab21, 0x1533: 0xab69, 0x1534: 0xabb1, 0x1535: 0xabf9,
- 0x1536: 0xac41, 0x1537: 0xac89, 0x1538: 0xacd1, 0x1539: 0xad19, 0x153a: 0xad52, 0x153b: 0xae62,
- 0x153c: 0xaee1, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040,
- // Block 0x55, offset 0x1540
- 0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0,
- 0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0,
- 0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaf2a, 0x1551: 0x7d8d,
- 0x1552: 0x0040, 0x1553: 0xaf3a, 0x1554: 0x03c2, 0x1555: 0xaf4a, 0x1556: 0xaf5a, 0x1557: 0x7dad,
- 0x1558: 0x7dcd, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040,
- 0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308,
- 0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308,
- 0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308,
- 0x1570: 0x0040, 0x1571: 0x7ded, 0x1572: 0x7e0d, 0x1573: 0xaf6a, 0x1574: 0xaf6a, 0x1575: 0x1fd2,
- 0x1576: 0x1fe2, 0x1577: 0xaf7a, 0x1578: 0xaf8a, 0x1579: 0x7e2d, 0x157a: 0x7e4d, 0x157b: 0x7e6d,
- 0x157c: 0x7e2d, 0x157d: 0x7e8d, 0x157e: 0x7ead, 0x157f: 0x7e8d,
- // Block 0x56, offset 0x1580
- 0x1580: 0x7ecd, 0x1581: 0x7eed, 0x1582: 0x7f0d, 0x1583: 0x7eed, 0x1584: 0x7f2d, 0x1585: 0x0018,
- 0x1586: 0x0018, 0x1587: 0xaf9a, 0x1588: 0xafaa, 0x1589: 0x7f4e, 0x158a: 0x7f6e, 0x158b: 0x7f8e,
- 0x158c: 0x7fae, 0x158d: 0xaf6a, 0x158e: 0xaf6a, 0x158f: 0xaf6a, 0x1590: 0xaf2a, 0x1591: 0x7fcd,
- 0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaf3a, 0x1596: 0xaf5a, 0x1597: 0xaf4a,
- 0x1598: 0x7fed, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf7a, 0x159c: 0xaf8a, 0x159d: 0x7ecd,
- 0x159e: 0x7f2d, 0x159f: 0xafba, 0x15a0: 0xafca, 0x15a1: 0xafda, 0x15a2: 0x1fb2, 0x15a3: 0xafe9,
- 0x15a4: 0xaffa, 0x15a5: 0xb00a, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xb01a, 0x15a9: 0xb02a,
- 0x15aa: 0xb03a, 0x15ab: 0xb04a, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040,
- 0x15b0: 0x800e, 0x15b1: 0xb059, 0x15b2: 0x802e, 0x15b3: 0x0808, 0x15b4: 0x804e, 0x15b5: 0x0040,
- 0x15b6: 0x806e, 0x15b7: 0xb081, 0x15b8: 0x808e, 0x15b9: 0xb0a9, 0x15ba: 0x80ae, 0x15bb: 0xb0d1,
- 0x15bc: 0x80ce, 0x15bd: 0xb0f9, 0x15be: 0x80ee, 0x15bf: 0xb121,
- // Block 0x57, offset 0x15c0
- 0x15c0: 0xb149, 0x15c1: 0xb161, 0x15c2: 0xb161, 0x15c3: 0xb179, 0x15c4: 0xb179, 0x15c5: 0xb191,
- 0x15c6: 0xb191, 0x15c7: 0xb1a9, 0x15c8: 0xb1a9, 0x15c9: 0xb1c1, 0x15ca: 0xb1c1, 0x15cb: 0xb1c1,
- 0x15cc: 0xb1c1, 0x15cd: 0xb1d9, 0x15ce: 0xb1d9, 0x15cf: 0xb1f1, 0x15d0: 0xb1f1, 0x15d1: 0xb1f1,
- 0x15d2: 0xb1f1, 0x15d3: 0xb209, 0x15d4: 0xb209, 0x15d5: 0xb221, 0x15d6: 0xb221, 0x15d7: 0xb221,
- 0x15d8: 0xb221, 0x15d9: 0xb239, 0x15da: 0xb239, 0x15db: 0xb239, 0x15dc: 0xb239, 0x15dd: 0xb251,
- 0x15de: 0xb251, 0x15df: 0xb251, 0x15e0: 0xb251, 0x15e1: 0xb269, 0x15e2: 0xb269, 0x15e3: 0xb269,
- 0x15e4: 0xb269, 0x15e5: 0xb281, 0x15e6: 0xb281, 0x15e7: 0xb281, 0x15e8: 0xb281, 0x15e9: 0xb299,
- 0x15ea: 0xb299, 0x15eb: 0xb2b1, 0x15ec: 0xb2b1, 0x15ed: 0xb2c9, 0x15ee: 0xb2c9, 0x15ef: 0xb2e1,
- 0x15f0: 0xb2e1, 0x15f1: 0xb2f9, 0x15f2: 0xb2f9, 0x15f3: 0xb2f9, 0x15f4: 0xb2f9, 0x15f5: 0xb311,
- 0x15f6: 0xb311, 0x15f7: 0xb311, 0x15f8: 0xb311, 0x15f9: 0xb329, 0x15fa: 0xb329, 0x15fb: 0xb329,
- 0x15fc: 0xb329, 0x15fd: 0xb341, 0x15fe: 0xb341, 0x15ff: 0xb341,
- // Block 0x58, offset 0x1600
- 0x1600: 0xb341, 0x1601: 0xb359, 0x1602: 0xb359, 0x1603: 0xb359, 0x1604: 0xb359, 0x1605: 0xb371,
- 0x1606: 0xb371, 0x1607: 0xb371, 0x1608: 0xb371, 0x1609: 0xb389, 0x160a: 0xb389, 0x160b: 0xb389,
- 0x160c: 0xb389, 0x160d: 0xb3a1, 0x160e: 0xb3a1, 0x160f: 0xb3a1, 0x1610: 0xb3a1, 0x1611: 0xb3b9,
- 0x1612: 0xb3b9, 0x1613: 0xb3b9, 0x1614: 0xb3b9, 0x1615: 0xb3d1, 0x1616: 0xb3d1, 0x1617: 0xb3d1,
- 0x1618: 0xb3d1, 0x1619: 0xb3e9, 0x161a: 0xb3e9, 0x161b: 0xb3e9, 0x161c: 0xb3e9, 0x161d: 0xb401,
- 0x161e: 0xb401, 0x161f: 0xb401, 0x1620: 0xb401, 0x1621: 0xb419, 0x1622: 0xb419, 0x1623: 0xb419,
- 0x1624: 0xb419, 0x1625: 0xb431, 0x1626: 0xb431, 0x1627: 0xb431, 0x1628: 0xb431, 0x1629: 0xb449,
- 0x162a: 0xb449, 0x162b: 0xb449, 0x162c: 0xb449, 0x162d: 0xb461, 0x162e: 0xb461, 0x162f: 0x7b01,
- 0x1630: 0x7b01, 0x1631: 0xb479, 0x1632: 0xb479, 0x1633: 0xb479, 0x1634: 0xb479, 0x1635: 0xb491,
- 0x1636: 0xb491, 0x1637: 0xb4b9, 0x1638: 0xb4b9, 0x1639: 0xb4e1, 0x163a: 0xb4e1, 0x163b: 0xb509,
- 0x163c: 0xb509, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0,
- // Block 0x59, offset 0x1640
- 0x1640: 0x0040, 0x1641: 0xaf4a, 0x1642: 0xb532, 0x1643: 0xafba, 0x1644: 0xb02a, 0x1645: 0xb03a,
- 0x1646: 0xafca, 0x1647: 0xb542, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xafda, 0x164b: 0x1fb2,
- 0x164c: 0xaf2a, 0x164d: 0xafe9, 0x164e: 0x29d1, 0x164f: 0xb552, 0x1650: 0x1f41, 0x1651: 0x00c9,
- 0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81,
- 0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaf3a, 0x165b: 0x03c2, 0x165c: 0xaffa, 0x165d: 0x1fc2,
- 0x165e: 0xb00a, 0x165f: 0xaf5a, 0x1660: 0xb04a, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159,
- 0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41,
- 0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9,
- 0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9,
- 0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf9a,
- 0x167c: 0xb01a, 0x167d: 0xafaa, 0x167e: 0xb562, 0x167f: 0xaf6a,
- // Block 0x5a, offset 0x1680
- 0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09,
- 0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51,
- 0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039,
- 0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279,
- 0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf7a, 0x169c: 0xb572, 0x169d: 0xaf8a,
- 0x169e: 0xb582, 0x169f: 0x810d, 0x16a0: 0x812d, 0x16a1: 0x29d1, 0x16a2: 0x814d, 0x16a3: 0x814d,
- 0x16a4: 0x816d, 0x16a5: 0x818d, 0x16a6: 0x81ad, 0x16a7: 0x81cd, 0x16a8: 0x81ed, 0x16a9: 0x820d,
- 0x16aa: 0x822d, 0x16ab: 0x824d, 0x16ac: 0x826d, 0x16ad: 0x828d, 0x16ae: 0x82ad, 0x16af: 0x82cd,
- 0x16b0: 0x82ed, 0x16b1: 0x830d, 0x16b2: 0x832d, 0x16b3: 0x834d, 0x16b4: 0x836d, 0x16b5: 0x838d,
- 0x16b6: 0x83ad, 0x16b7: 0x83cd, 0x16b8: 0x83ed, 0x16b9: 0x840d, 0x16ba: 0x842d, 0x16bb: 0x844d,
- 0x16bc: 0x81ed, 0x16bd: 0x846d, 0x16be: 0x848d, 0x16bf: 0x824d,
- // Block 0x5b, offset 0x16c0
- 0x16c0: 0x84ad, 0x16c1: 0x84cd, 0x16c2: 0x84ed, 0x16c3: 0x850d, 0x16c4: 0x852d, 0x16c5: 0x854d,
- 0x16c6: 0x856d, 0x16c7: 0x858d, 0x16c8: 0x850d, 0x16c9: 0x85ad, 0x16ca: 0x850d, 0x16cb: 0x85cd,
- 0x16cc: 0x85cd, 0x16cd: 0x85ed, 0x16ce: 0x85ed, 0x16cf: 0x860d, 0x16d0: 0x854d, 0x16d1: 0x862d,
- 0x16d2: 0x864d, 0x16d3: 0x862d, 0x16d4: 0x866d, 0x16d5: 0x864d, 0x16d6: 0x868d, 0x16d7: 0x868d,
- 0x16d8: 0x86ad, 0x16d9: 0x86ad, 0x16da: 0x86cd, 0x16db: 0x86cd, 0x16dc: 0x864d, 0x16dd: 0x814d,
- 0x16de: 0x86ed, 0x16df: 0x870d, 0x16e0: 0x0040, 0x16e1: 0x872d, 0x16e2: 0x874d, 0x16e3: 0x876d,
- 0x16e4: 0x878d, 0x16e5: 0x876d, 0x16e6: 0x87ad, 0x16e7: 0x87cd, 0x16e8: 0x87ed, 0x16e9: 0x87ed,
- 0x16ea: 0x880d, 0x16eb: 0x880d, 0x16ec: 0x882d, 0x16ed: 0x882d, 0x16ee: 0x880d, 0x16ef: 0x880d,
- 0x16f0: 0x884d, 0x16f1: 0x886d, 0x16f2: 0x888d, 0x16f3: 0x88ad, 0x16f4: 0x88cd, 0x16f5: 0x88ed,
- 0x16f6: 0x88ed, 0x16f7: 0x88ed, 0x16f8: 0x890d, 0x16f9: 0x890d, 0x16fa: 0x890d, 0x16fb: 0x890d,
- 0x16fc: 0x87ed, 0x16fd: 0x87ed, 0x16fe: 0x87ed, 0x16ff: 0x0040,
- // Block 0x5c, offset 0x1700
- 0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x874d, 0x1703: 0x872d, 0x1704: 0x892d, 0x1705: 0x872d,
- 0x1706: 0x874d, 0x1707: 0x872d, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x894d, 0x170b: 0x874d,
- 0x170c: 0x896d, 0x170d: 0x892d, 0x170e: 0x896d, 0x170f: 0x874d, 0x1710: 0x0040, 0x1711: 0x0040,
- 0x1712: 0x898d, 0x1713: 0x89ad, 0x1714: 0x88ad, 0x1715: 0x896d, 0x1716: 0x892d, 0x1717: 0x896d,
- 0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x89cd, 0x171b: 0x89ed, 0x171c: 0x89cd, 0x171d: 0x0040,
- 0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb591, 0x1721: 0xb5a9, 0x1722: 0xb5c1, 0x1723: 0x8a0e,
- 0x1724: 0xb5d9, 0x1725: 0xb5f1, 0x1726: 0x8a2d, 0x1727: 0x0040, 0x1728: 0x8a4d, 0x1729: 0x8a6d,
- 0x172a: 0x8a8d, 0x172b: 0x8a6d, 0x172c: 0x8aad, 0x172d: 0x8acd, 0x172e: 0x8aed, 0x172f: 0x0040,
- 0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040,
- 0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340,
- 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,
- // Block 0x5d, offset 0x1740
- 0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08,
- 0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808,
- 0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08,
- 0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908,
- 0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08,
- 0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808,
- 0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040,
- 0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18,
- 0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818,
- 0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040,
- 0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040,
- // Block 0x5e, offset 0x1780
- 0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08,
- 0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08,
- 0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08,
- 0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040,
- 0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040,
- 0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040,
- 0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18,
- 0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818,
- 0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040,
- 0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040,
- 0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040,
- // Block 0x5f, offset 0x17c0
- 0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008,
- 0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008,
- 0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040,
- 0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008,
- 0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008,
- 0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008,
- 0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040,
- 0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008,
- 0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008,
- 0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x3308,
- 0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008,
- // Block 0x60, offset 0x1800
- 0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040,
- 0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008,
- 0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040,
- 0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008,
- 0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008,
- 0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008,
- 0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308,
- 0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040,
- 0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040,
- 0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040,
- 0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040,
- // Block 0x61, offset 0x1840
- 0x1840: 0x0008, 0x1841: 0x0008, 0x1842: 0x0008, 0x1843: 0x0008, 0x1844: 0x0008, 0x1845: 0x0008,
- 0x1846: 0x0008, 0x1847: 0x0040, 0x1848: 0x0040, 0x1849: 0x0008, 0x184a: 0x0040, 0x184b: 0x0040,
- 0x184c: 0x0008, 0x184d: 0x0008, 0x184e: 0x0008, 0x184f: 0x0008, 0x1850: 0x0008, 0x1851: 0x0008,
- 0x1852: 0x0008, 0x1853: 0x0008, 0x1854: 0x0040, 0x1855: 0x0008, 0x1856: 0x0008, 0x1857: 0x0040,
- 0x1858: 0x0008, 0x1859: 0x0008, 0x185a: 0x0008, 0x185b: 0x0008, 0x185c: 0x0008, 0x185d: 0x0008,
- 0x185e: 0x0008, 0x185f: 0x0008, 0x1860: 0x0008, 0x1861: 0x0008, 0x1862: 0x0008, 0x1863: 0x0008,
- 0x1864: 0x0008, 0x1865: 0x0008, 0x1866: 0x0008, 0x1867: 0x0008, 0x1868: 0x0008, 0x1869: 0x0008,
- 0x186a: 0x0008, 0x186b: 0x0008, 0x186c: 0x0008, 0x186d: 0x0008, 0x186e: 0x0008, 0x186f: 0x0008,
- 0x1870: 0x3008, 0x1871: 0x3008, 0x1872: 0x3008, 0x1873: 0x3008, 0x1874: 0x3008, 0x1875: 0x3008,
- 0x1876: 0x0040, 0x1877: 0x3008, 0x1878: 0x3008, 0x1879: 0x0040, 0x187a: 0x0040, 0x187b: 0x3308,
- 0x187c: 0x3308, 0x187d: 0x3808, 0x187e: 0x3b08, 0x187f: 0x0008,
- // Block 0x62, offset 0x1880
- 0x1880: 0x0039, 0x1881: 0x0ee9, 0x1882: 0x1159, 0x1883: 0x0ef9, 0x1884: 0x0f09, 0x1885: 0x1199,
- 0x1886: 0x0f31, 0x1887: 0x0249, 0x1888: 0x0f41, 0x1889: 0x0259, 0x188a: 0x0f51, 0x188b: 0x0359,
- 0x188c: 0x0f61, 0x188d: 0x0f71, 0x188e: 0x00d9, 0x188f: 0x0f99, 0x1890: 0x2039, 0x1891: 0x0269,
- 0x1892: 0x01d9, 0x1893: 0x0fa9, 0x1894: 0x0fb9, 0x1895: 0x1089, 0x1896: 0x0279, 0x1897: 0x0369,
- 0x1898: 0x0289, 0x1899: 0x13d1, 0x189a: 0x0039, 0x189b: 0x0ee9, 0x189c: 0x1159, 0x189d: 0x0ef9,
- 0x189e: 0x0f09, 0x189f: 0x1199, 0x18a0: 0x0f31, 0x18a1: 0x0249, 0x18a2: 0x0f41, 0x18a3: 0x0259,
- 0x18a4: 0x0f51, 0x18a5: 0x0359, 0x18a6: 0x0f61, 0x18a7: 0x0f71, 0x18a8: 0x00d9, 0x18a9: 0x0f99,
- 0x18aa: 0x2039, 0x18ab: 0x0269, 0x18ac: 0x01d9, 0x18ad: 0x0fa9, 0x18ae: 0x0fb9, 0x18af: 0x1089,
- 0x18b0: 0x0279, 0x18b1: 0x0369, 0x18b2: 0x0289, 0x18b3: 0x13d1, 0x18b4: 0x0039, 0x18b5: 0x0ee9,
- 0x18b6: 0x1159, 0x18b7: 0x0ef9, 0x18b8: 0x0f09, 0x18b9: 0x1199, 0x18ba: 0x0f31, 0x18bb: 0x0249,
- 0x18bc: 0x0f41, 0x18bd: 0x0259, 0x18be: 0x0f51, 0x18bf: 0x0359,
- // Block 0x63, offset 0x18c0
- 0x18c0: 0x0f61, 0x18c1: 0x0f71, 0x18c2: 0x00d9, 0x18c3: 0x0f99, 0x18c4: 0x2039, 0x18c5: 0x0269,
- 0x18c6: 0x01d9, 0x18c7: 0x0fa9, 0x18c8: 0x0fb9, 0x18c9: 0x1089, 0x18ca: 0x0279, 0x18cb: 0x0369,
- 0x18cc: 0x0289, 0x18cd: 0x13d1, 0x18ce: 0x0039, 0x18cf: 0x0ee9, 0x18d0: 0x1159, 0x18d1: 0x0ef9,
- 0x18d2: 0x0f09, 0x18d3: 0x1199, 0x18d4: 0x0f31, 0x18d5: 0x0040, 0x18d6: 0x0f41, 0x18d7: 0x0259,
- 0x18d8: 0x0f51, 0x18d9: 0x0359, 0x18da: 0x0f61, 0x18db: 0x0f71, 0x18dc: 0x00d9, 0x18dd: 0x0f99,
- 0x18de: 0x2039, 0x18df: 0x0269, 0x18e0: 0x01d9, 0x18e1: 0x0fa9, 0x18e2: 0x0fb9, 0x18e3: 0x1089,
- 0x18e4: 0x0279, 0x18e5: 0x0369, 0x18e6: 0x0289, 0x18e7: 0x13d1, 0x18e8: 0x0039, 0x18e9: 0x0ee9,
- 0x18ea: 0x1159, 0x18eb: 0x0ef9, 0x18ec: 0x0f09, 0x18ed: 0x1199, 0x18ee: 0x0f31, 0x18ef: 0x0249,
- 0x18f0: 0x0f41, 0x18f1: 0x0259, 0x18f2: 0x0f51, 0x18f3: 0x0359, 0x18f4: 0x0f61, 0x18f5: 0x0f71,
- 0x18f6: 0x00d9, 0x18f7: 0x0f99, 0x18f8: 0x2039, 0x18f9: 0x0269, 0x18fa: 0x01d9, 0x18fb: 0x0fa9,
- 0x18fc: 0x0fb9, 0x18fd: 0x1089, 0x18fe: 0x0279, 0x18ff: 0x0369,
- // Block 0x64, offset 0x1900
- 0x1900: 0x0289, 0x1901: 0x13d1, 0x1902: 0x0039, 0x1903: 0x0ee9, 0x1904: 0x1159, 0x1905: 0x0ef9,
- 0x1906: 0x0f09, 0x1907: 0x1199, 0x1908: 0x0f31, 0x1909: 0x0249, 0x190a: 0x0f41, 0x190b: 0x0259,
- 0x190c: 0x0f51, 0x190d: 0x0359, 0x190e: 0x0f61, 0x190f: 0x0f71, 0x1910: 0x00d9, 0x1911: 0x0f99,
- 0x1912: 0x2039, 0x1913: 0x0269, 0x1914: 0x01d9, 0x1915: 0x0fa9, 0x1916: 0x0fb9, 0x1917: 0x1089,
- 0x1918: 0x0279, 0x1919: 0x0369, 0x191a: 0x0289, 0x191b: 0x13d1, 0x191c: 0x0039, 0x191d: 0x0040,
- 0x191e: 0x1159, 0x191f: 0x0ef9, 0x1920: 0x0040, 0x1921: 0x0040, 0x1922: 0x0f31, 0x1923: 0x0040,
- 0x1924: 0x0040, 0x1925: 0x0259, 0x1926: 0x0f51, 0x1927: 0x0040, 0x1928: 0x0040, 0x1929: 0x0f71,
- 0x192a: 0x00d9, 0x192b: 0x0f99, 0x192c: 0x2039, 0x192d: 0x0040, 0x192e: 0x01d9, 0x192f: 0x0fa9,
- 0x1930: 0x0fb9, 0x1931: 0x1089, 0x1932: 0x0279, 0x1933: 0x0369, 0x1934: 0x0289, 0x1935: 0x13d1,
- 0x1936: 0x0039, 0x1937: 0x0ee9, 0x1938: 0x1159, 0x1939: 0x0ef9, 0x193a: 0x0040, 0x193b: 0x1199,
- 0x193c: 0x0040, 0x193d: 0x0249, 0x193e: 0x0f41, 0x193f: 0x0259,
- // Block 0x65, offset 0x1940
- 0x1940: 0x0f51, 0x1941: 0x0359, 0x1942: 0x0f61, 0x1943: 0x0f71, 0x1944: 0x0040, 0x1945: 0x0f99,
- 0x1946: 0x2039, 0x1947: 0x0269, 0x1948: 0x01d9, 0x1949: 0x0fa9, 0x194a: 0x0fb9, 0x194b: 0x1089,
- 0x194c: 0x0279, 0x194d: 0x0369, 0x194e: 0x0289, 0x194f: 0x13d1, 0x1950: 0x0039, 0x1951: 0x0ee9,
- 0x1952: 0x1159, 0x1953: 0x0ef9, 0x1954: 0x0f09, 0x1955: 0x1199, 0x1956: 0x0f31, 0x1957: 0x0249,
- 0x1958: 0x0f41, 0x1959: 0x0259, 0x195a: 0x0f51, 0x195b: 0x0359, 0x195c: 0x0f61, 0x195d: 0x0f71,
- 0x195e: 0x00d9, 0x195f: 0x0f99, 0x1960: 0x2039, 0x1961: 0x0269, 0x1962: 0x01d9, 0x1963: 0x0fa9,
- 0x1964: 0x0fb9, 0x1965: 0x1089, 0x1966: 0x0279, 0x1967: 0x0369, 0x1968: 0x0289, 0x1969: 0x13d1,
- 0x196a: 0x0039, 0x196b: 0x0ee9, 0x196c: 0x1159, 0x196d: 0x0ef9, 0x196e: 0x0f09, 0x196f: 0x1199,
- 0x1970: 0x0f31, 0x1971: 0x0249, 0x1972: 0x0f41, 0x1973: 0x0259, 0x1974: 0x0f51, 0x1975: 0x0359,
- 0x1976: 0x0f61, 0x1977: 0x0f71, 0x1978: 0x00d9, 0x1979: 0x0f99, 0x197a: 0x2039, 0x197b: 0x0269,
- 0x197c: 0x01d9, 0x197d: 0x0fa9, 0x197e: 0x0fb9, 0x197f: 0x1089,
- // Block 0x66, offset 0x1980
- 0x1980: 0x0279, 0x1981: 0x0369, 0x1982: 0x0289, 0x1983: 0x13d1, 0x1984: 0x0039, 0x1985: 0x0ee9,
- 0x1986: 0x0040, 0x1987: 0x0ef9, 0x1988: 0x0f09, 0x1989: 0x1199, 0x198a: 0x0f31, 0x198b: 0x0040,
- 0x198c: 0x0040, 0x198d: 0x0259, 0x198e: 0x0f51, 0x198f: 0x0359, 0x1990: 0x0f61, 0x1991: 0x0f71,
- 0x1992: 0x00d9, 0x1993: 0x0f99, 0x1994: 0x2039, 0x1995: 0x0040, 0x1996: 0x01d9, 0x1997: 0x0fa9,
- 0x1998: 0x0fb9, 0x1999: 0x1089, 0x199a: 0x0279, 0x199b: 0x0369, 0x199c: 0x0289, 0x199d: 0x0040,
- 0x199e: 0x0039, 0x199f: 0x0ee9, 0x19a0: 0x1159, 0x19a1: 0x0ef9, 0x19a2: 0x0f09, 0x19a3: 0x1199,
- 0x19a4: 0x0f31, 0x19a5: 0x0249, 0x19a6: 0x0f41, 0x19a7: 0x0259, 0x19a8: 0x0f51, 0x19a9: 0x0359,
- 0x19aa: 0x0f61, 0x19ab: 0x0f71, 0x19ac: 0x00d9, 0x19ad: 0x0f99, 0x19ae: 0x2039, 0x19af: 0x0269,
- 0x19b0: 0x01d9, 0x19b1: 0x0fa9, 0x19b2: 0x0fb9, 0x19b3: 0x1089, 0x19b4: 0x0279, 0x19b5: 0x0369,
- 0x19b6: 0x0289, 0x19b7: 0x13d1, 0x19b8: 0x0039, 0x19b9: 0x0ee9, 0x19ba: 0x0040, 0x19bb: 0x0ef9,
- 0x19bc: 0x0f09, 0x19bd: 0x1199, 0x19be: 0x0f31, 0x19bf: 0x0040,
- // Block 0x67, offset 0x19c0
- 0x19c0: 0x0f41, 0x19c1: 0x0259, 0x19c2: 0x0f51, 0x19c3: 0x0359, 0x19c4: 0x0f61, 0x19c5: 0x0040,
- 0x19c6: 0x00d9, 0x19c7: 0x0040, 0x19c8: 0x0040, 0x19c9: 0x0040, 0x19ca: 0x01d9, 0x19cb: 0x0fa9,
- 0x19cc: 0x0fb9, 0x19cd: 0x1089, 0x19ce: 0x0279, 0x19cf: 0x0369, 0x19d0: 0x0289, 0x19d1: 0x0040,
- 0x19d2: 0x0039, 0x19d3: 0x0ee9, 0x19d4: 0x1159, 0x19d5: 0x0ef9, 0x19d6: 0x0f09, 0x19d7: 0x1199,
- 0x19d8: 0x0f31, 0x19d9: 0x0249, 0x19da: 0x0f41, 0x19db: 0x0259, 0x19dc: 0x0f51, 0x19dd: 0x0359,
- 0x19de: 0x0f61, 0x19df: 0x0f71, 0x19e0: 0x00d9, 0x19e1: 0x0f99, 0x19e2: 0x2039, 0x19e3: 0x0269,
- 0x19e4: 0x01d9, 0x19e5: 0x0fa9, 0x19e6: 0x0fb9, 0x19e7: 0x1089, 0x19e8: 0x0279, 0x19e9: 0x0369,
- 0x19ea: 0x0289, 0x19eb: 0x13d1, 0x19ec: 0x0039, 0x19ed: 0x0ee9, 0x19ee: 0x1159, 0x19ef: 0x0ef9,
- 0x19f0: 0x0f09, 0x19f1: 0x1199, 0x19f2: 0x0f31, 0x19f3: 0x0249, 0x19f4: 0x0f41, 0x19f5: 0x0259,
- 0x19f6: 0x0f51, 0x19f7: 0x0359, 0x19f8: 0x0f61, 0x19f9: 0x0f71, 0x19fa: 0x00d9, 0x19fb: 0x0f99,
- 0x19fc: 0x2039, 0x19fd: 0x0269, 0x19fe: 0x01d9, 0x19ff: 0x0fa9,
- // Block 0x68, offset 0x1a00
- 0x1a00: 0x0fb9, 0x1a01: 0x1089, 0x1a02: 0x0279, 0x1a03: 0x0369, 0x1a04: 0x0289, 0x1a05: 0x13d1,
- 0x1a06: 0x0039, 0x1a07: 0x0ee9, 0x1a08: 0x1159, 0x1a09: 0x0ef9, 0x1a0a: 0x0f09, 0x1a0b: 0x1199,
- 0x1a0c: 0x0f31, 0x1a0d: 0x0249, 0x1a0e: 0x0f41, 0x1a0f: 0x0259, 0x1a10: 0x0f51, 0x1a11: 0x0359,
- 0x1a12: 0x0f61, 0x1a13: 0x0f71, 0x1a14: 0x00d9, 0x1a15: 0x0f99, 0x1a16: 0x2039, 0x1a17: 0x0269,
- 0x1a18: 0x01d9, 0x1a19: 0x0fa9, 0x1a1a: 0x0fb9, 0x1a1b: 0x1089, 0x1a1c: 0x0279, 0x1a1d: 0x0369,
- 0x1a1e: 0x0289, 0x1a1f: 0x13d1, 0x1a20: 0x0039, 0x1a21: 0x0ee9, 0x1a22: 0x1159, 0x1a23: 0x0ef9,
- 0x1a24: 0x0f09, 0x1a25: 0x1199, 0x1a26: 0x0f31, 0x1a27: 0x0249, 0x1a28: 0x0f41, 0x1a29: 0x0259,
- 0x1a2a: 0x0f51, 0x1a2b: 0x0359, 0x1a2c: 0x0f61, 0x1a2d: 0x0f71, 0x1a2e: 0x00d9, 0x1a2f: 0x0f99,
- 0x1a30: 0x2039, 0x1a31: 0x0269, 0x1a32: 0x01d9, 0x1a33: 0x0fa9, 0x1a34: 0x0fb9, 0x1a35: 0x1089,
- 0x1a36: 0x0279, 0x1a37: 0x0369, 0x1a38: 0x0289, 0x1a39: 0x13d1, 0x1a3a: 0x0039, 0x1a3b: 0x0ee9,
- 0x1a3c: 0x1159, 0x1a3d: 0x0ef9, 0x1a3e: 0x0f09, 0x1a3f: 0x1199,
- // Block 0x69, offset 0x1a40
- 0x1a40: 0x0f31, 0x1a41: 0x0249, 0x1a42: 0x0f41, 0x1a43: 0x0259, 0x1a44: 0x0f51, 0x1a45: 0x0359,
- 0x1a46: 0x0f61, 0x1a47: 0x0f71, 0x1a48: 0x00d9, 0x1a49: 0x0f99, 0x1a4a: 0x2039, 0x1a4b: 0x0269,
- 0x1a4c: 0x01d9, 0x1a4d: 0x0fa9, 0x1a4e: 0x0fb9, 0x1a4f: 0x1089, 0x1a50: 0x0279, 0x1a51: 0x0369,
- 0x1a52: 0x0289, 0x1a53: 0x13d1, 0x1a54: 0x0039, 0x1a55: 0x0ee9, 0x1a56: 0x1159, 0x1a57: 0x0ef9,
- 0x1a58: 0x0f09, 0x1a59: 0x1199, 0x1a5a: 0x0f31, 0x1a5b: 0x0249, 0x1a5c: 0x0f41, 0x1a5d: 0x0259,
- 0x1a5e: 0x0f51, 0x1a5f: 0x0359, 0x1a60: 0x0f61, 0x1a61: 0x0f71, 0x1a62: 0x00d9, 0x1a63: 0x0f99,
- 0x1a64: 0x2039, 0x1a65: 0x0269, 0x1a66: 0x01d9, 0x1a67: 0x0fa9, 0x1a68: 0x0fb9, 0x1a69: 0x1089,
- 0x1a6a: 0x0279, 0x1a6b: 0x0369, 0x1a6c: 0x0289, 0x1a6d: 0x13d1, 0x1a6e: 0x0039, 0x1a6f: 0x0ee9,
- 0x1a70: 0x1159, 0x1a71: 0x0ef9, 0x1a72: 0x0f09, 0x1a73: 0x1199, 0x1a74: 0x0f31, 0x1a75: 0x0249,
- 0x1a76: 0x0f41, 0x1a77: 0x0259, 0x1a78: 0x0f51, 0x1a79: 0x0359, 0x1a7a: 0x0f61, 0x1a7b: 0x0f71,
- 0x1a7c: 0x00d9, 0x1a7d: 0x0f99, 0x1a7e: 0x2039, 0x1a7f: 0x0269,
- // Block 0x6a, offset 0x1a80
- 0x1a80: 0x01d9, 0x1a81: 0x0fa9, 0x1a82: 0x0fb9, 0x1a83: 0x1089, 0x1a84: 0x0279, 0x1a85: 0x0369,
- 0x1a86: 0x0289, 0x1a87: 0x13d1, 0x1a88: 0x0039, 0x1a89: 0x0ee9, 0x1a8a: 0x1159, 0x1a8b: 0x0ef9,
- 0x1a8c: 0x0f09, 0x1a8d: 0x1199, 0x1a8e: 0x0f31, 0x1a8f: 0x0249, 0x1a90: 0x0f41, 0x1a91: 0x0259,
- 0x1a92: 0x0f51, 0x1a93: 0x0359, 0x1a94: 0x0f61, 0x1a95: 0x0f71, 0x1a96: 0x00d9, 0x1a97: 0x0f99,
- 0x1a98: 0x2039, 0x1a99: 0x0269, 0x1a9a: 0x01d9, 0x1a9b: 0x0fa9, 0x1a9c: 0x0fb9, 0x1a9d: 0x1089,
- 0x1a9e: 0x0279, 0x1a9f: 0x0369, 0x1aa0: 0x0289, 0x1aa1: 0x13d1, 0x1aa2: 0x0039, 0x1aa3: 0x0ee9,
- 0x1aa4: 0x1159, 0x1aa5: 0x0ef9, 0x1aa6: 0x0f09, 0x1aa7: 0x1199, 0x1aa8: 0x0f31, 0x1aa9: 0x0249,
- 0x1aaa: 0x0f41, 0x1aab: 0x0259, 0x1aac: 0x0f51, 0x1aad: 0x0359, 0x1aae: 0x0f61, 0x1aaf: 0x0f71,
- 0x1ab0: 0x00d9, 0x1ab1: 0x0f99, 0x1ab2: 0x2039, 0x1ab3: 0x0269, 0x1ab4: 0x01d9, 0x1ab5: 0x0fa9,
- 0x1ab6: 0x0fb9, 0x1ab7: 0x1089, 0x1ab8: 0x0279, 0x1ab9: 0x0369, 0x1aba: 0x0289, 0x1abb: 0x13d1,
- 0x1abc: 0x0039, 0x1abd: 0x0ee9, 0x1abe: 0x1159, 0x1abf: 0x0ef9,
- // Block 0x6b, offset 0x1ac0
- 0x1ac0: 0x0f09, 0x1ac1: 0x1199, 0x1ac2: 0x0f31, 0x1ac3: 0x0249, 0x1ac4: 0x0f41, 0x1ac5: 0x0259,
- 0x1ac6: 0x0f51, 0x1ac7: 0x0359, 0x1ac8: 0x0f61, 0x1ac9: 0x0f71, 0x1aca: 0x00d9, 0x1acb: 0x0f99,
- 0x1acc: 0x2039, 0x1acd: 0x0269, 0x1ace: 0x01d9, 0x1acf: 0x0fa9, 0x1ad0: 0x0fb9, 0x1ad1: 0x1089,
- 0x1ad2: 0x0279, 0x1ad3: 0x0369, 0x1ad4: 0x0289, 0x1ad5: 0x13d1, 0x1ad6: 0x0039, 0x1ad7: 0x0ee9,
- 0x1ad8: 0x1159, 0x1ad9: 0x0ef9, 0x1ada: 0x0f09, 0x1adb: 0x1199, 0x1adc: 0x0f31, 0x1add: 0x0249,
- 0x1ade: 0x0f41, 0x1adf: 0x0259, 0x1ae0: 0x0f51, 0x1ae1: 0x0359, 0x1ae2: 0x0f61, 0x1ae3: 0x0f71,
- 0x1ae4: 0x00d9, 0x1ae5: 0x0f99, 0x1ae6: 0x2039, 0x1ae7: 0x0269, 0x1ae8: 0x01d9, 0x1ae9: 0x0fa9,
- 0x1aea: 0x0fb9, 0x1aeb: 0x1089, 0x1aec: 0x0279, 0x1aed: 0x0369, 0x1aee: 0x0289, 0x1aef: 0x13d1,
- 0x1af0: 0x0039, 0x1af1: 0x0ee9, 0x1af2: 0x1159, 0x1af3: 0x0ef9, 0x1af4: 0x0f09, 0x1af5: 0x1199,
- 0x1af6: 0x0f31, 0x1af7: 0x0249, 0x1af8: 0x0f41, 0x1af9: 0x0259, 0x1afa: 0x0f51, 0x1afb: 0x0359,
- 0x1afc: 0x0f61, 0x1afd: 0x0f71, 0x1afe: 0x00d9, 0x1aff: 0x0f99,
- // Block 0x6c, offset 0x1b00
- 0x1b00: 0x2039, 0x1b01: 0x0269, 0x1b02: 0x01d9, 0x1b03: 0x0fa9, 0x1b04: 0x0fb9, 0x1b05: 0x1089,
- 0x1b06: 0x0279, 0x1b07: 0x0369, 0x1b08: 0x0289, 0x1b09: 0x13d1, 0x1b0a: 0x0039, 0x1b0b: 0x0ee9,
- 0x1b0c: 0x1159, 0x1b0d: 0x0ef9, 0x1b0e: 0x0f09, 0x1b0f: 0x1199, 0x1b10: 0x0f31, 0x1b11: 0x0249,
- 0x1b12: 0x0f41, 0x1b13: 0x0259, 0x1b14: 0x0f51, 0x1b15: 0x0359, 0x1b16: 0x0f61, 0x1b17: 0x0f71,
- 0x1b18: 0x00d9, 0x1b19: 0x0f99, 0x1b1a: 0x2039, 0x1b1b: 0x0269, 0x1b1c: 0x01d9, 0x1b1d: 0x0fa9,
- 0x1b1e: 0x0fb9, 0x1b1f: 0x1089, 0x1b20: 0x0279, 0x1b21: 0x0369, 0x1b22: 0x0289, 0x1b23: 0x13d1,
- 0x1b24: 0xbad1, 0x1b25: 0xbae9, 0x1b26: 0x0040, 0x1b27: 0x0040, 0x1b28: 0xbb01, 0x1b29: 0x1099,
- 0x1b2a: 0x10b1, 0x1b2b: 0x10c9, 0x1b2c: 0xbb19, 0x1b2d: 0xbb31, 0x1b2e: 0xbb49, 0x1b2f: 0x1429,
- 0x1b30: 0x1a31, 0x1b31: 0xbb61, 0x1b32: 0xbb79, 0x1b33: 0xbb91, 0x1b34: 0xbba9, 0x1b35: 0xbbc1,
- 0x1b36: 0xbbd9, 0x1b37: 0x2109, 0x1b38: 0x1111, 0x1b39: 0x1429, 0x1b3a: 0xbbf1, 0x1b3b: 0xbc09,
- 0x1b3c: 0xbc21, 0x1b3d: 0x10e1, 0x1b3e: 0x10f9, 0x1b3f: 0xbc39,
- // Block 0x6d, offset 0x1b40
- 0x1b40: 0x2079, 0x1b41: 0xbc51, 0x1b42: 0xbb01, 0x1b43: 0x1099, 0x1b44: 0x10b1, 0x1b45: 0x10c9,
- 0x1b46: 0xbb19, 0x1b47: 0xbb31, 0x1b48: 0xbb49, 0x1b49: 0x1429, 0x1b4a: 0x1a31, 0x1b4b: 0xbb61,
- 0x1b4c: 0xbb79, 0x1b4d: 0xbb91, 0x1b4e: 0xbba9, 0x1b4f: 0xbbc1, 0x1b50: 0xbbd9, 0x1b51: 0x2109,
- 0x1b52: 0x1111, 0x1b53: 0xbbf1, 0x1b54: 0xbbf1, 0x1b55: 0xbc09, 0x1b56: 0xbc21, 0x1b57: 0x10e1,
- 0x1b58: 0x10f9, 0x1b59: 0xbc39, 0x1b5a: 0x2079, 0x1b5b: 0xbc71, 0x1b5c: 0xbb19, 0x1b5d: 0x1429,
- 0x1b5e: 0xbb61, 0x1b5f: 0x10e1, 0x1b60: 0x1111, 0x1b61: 0x2109, 0x1b62: 0xbb01, 0x1b63: 0x1099,
- 0x1b64: 0x10b1, 0x1b65: 0x10c9, 0x1b66: 0xbb19, 0x1b67: 0xbb31, 0x1b68: 0xbb49, 0x1b69: 0x1429,
- 0x1b6a: 0x1a31, 0x1b6b: 0xbb61, 0x1b6c: 0xbb79, 0x1b6d: 0xbb91, 0x1b6e: 0xbba9, 0x1b6f: 0xbbc1,
- 0x1b70: 0xbbd9, 0x1b71: 0x2109, 0x1b72: 0x1111, 0x1b73: 0x1429, 0x1b74: 0xbbf1, 0x1b75: 0xbc09,
- 0x1b76: 0xbc21, 0x1b77: 0x10e1, 0x1b78: 0x10f9, 0x1b79: 0xbc39, 0x1b7a: 0x2079, 0x1b7b: 0xbc51,
- 0x1b7c: 0xbb01, 0x1b7d: 0x1099, 0x1b7e: 0x10b1, 0x1b7f: 0x10c9,
- // Block 0x6e, offset 0x1b80
- 0x1b80: 0xbb19, 0x1b81: 0xbb31, 0x1b82: 0xbb49, 0x1b83: 0x1429, 0x1b84: 0x1a31, 0x1b85: 0xbb61,
- 0x1b86: 0xbb79, 0x1b87: 0xbb91, 0x1b88: 0xbba9, 0x1b89: 0xbbc1, 0x1b8a: 0xbbd9, 0x1b8b: 0x2109,
- 0x1b8c: 0x1111, 0x1b8d: 0xbbf1, 0x1b8e: 0xbbf1, 0x1b8f: 0xbc09, 0x1b90: 0xbc21, 0x1b91: 0x10e1,
- 0x1b92: 0x10f9, 0x1b93: 0xbc39, 0x1b94: 0x2079, 0x1b95: 0xbc71, 0x1b96: 0xbb19, 0x1b97: 0x1429,
- 0x1b98: 0xbb61, 0x1b99: 0x10e1, 0x1b9a: 0x1111, 0x1b9b: 0x2109, 0x1b9c: 0xbb01, 0x1b9d: 0x1099,
- 0x1b9e: 0x10b1, 0x1b9f: 0x10c9, 0x1ba0: 0xbb19, 0x1ba1: 0xbb31, 0x1ba2: 0xbb49, 0x1ba3: 0x1429,
- 0x1ba4: 0x1a31, 0x1ba5: 0xbb61, 0x1ba6: 0xbb79, 0x1ba7: 0xbb91, 0x1ba8: 0xbba9, 0x1ba9: 0xbbc1,
- 0x1baa: 0xbbd9, 0x1bab: 0x2109, 0x1bac: 0x1111, 0x1bad: 0x1429, 0x1bae: 0xbbf1, 0x1baf: 0xbc09,
- 0x1bb0: 0xbc21, 0x1bb1: 0x10e1, 0x1bb2: 0x10f9, 0x1bb3: 0xbc39, 0x1bb4: 0x2079, 0x1bb5: 0xbc51,
- 0x1bb6: 0xbb01, 0x1bb7: 0x1099, 0x1bb8: 0x10b1, 0x1bb9: 0x10c9, 0x1bba: 0xbb19, 0x1bbb: 0xbb31,
- 0x1bbc: 0xbb49, 0x1bbd: 0x1429, 0x1bbe: 0x1a31, 0x1bbf: 0xbb61,
- // Block 0x6f, offset 0x1bc0
- 0x1bc0: 0xbb79, 0x1bc1: 0xbb91, 0x1bc2: 0xbba9, 0x1bc3: 0xbbc1, 0x1bc4: 0xbbd9, 0x1bc5: 0x2109,
- 0x1bc6: 0x1111, 0x1bc7: 0xbbf1, 0x1bc8: 0xbbf1, 0x1bc9: 0xbc09, 0x1bca: 0xbc21, 0x1bcb: 0x10e1,
- 0x1bcc: 0x10f9, 0x1bcd: 0xbc39, 0x1bce: 0x2079, 0x1bcf: 0xbc71, 0x1bd0: 0xbb19, 0x1bd1: 0x1429,
- 0x1bd2: 0xbb61, 0x1bd3: 0x10e1, 0x1bd4: 0x1111, 0x1bd5: 0x2109, 0x1bd6: 0xbb01, 0x1bd7: 0x1099,
- 0x1bd8: 0x10b1, 0x1bd9: 0x10c9, 0x1bda: 0xbb19, 0x1bdb: 0xbb31, 0x1bdc: 0xbb49, 0x1bdd: 0x1429,
- 0x1bde: 0x1a31, 0x1bdf: 0xbb61, 0x1be0: 0xbb79, 0x1be1: 0xbb91, 0x1be2: 0xbba9, 0x1be3: 0xbbc1,
- 0x1be4: 0xbbd9, 0x1be5: 0x2109, 0x1be6: 0x1111, 0x1be7: 0x1429, 0x1be8: 0xbbf1, 0x1be9: 0xbc09,
- 0x1bea: 0xbc21, 0x1beb: 0x10e1, 0x1bec: 0x10f9, 0x1bed: 0xbc39, 0x1bee: 0x2079, 0x1bef: 0xbc51,
- 0x1bf0: 0xbb01, 0x1bf1: 0x1099, 0x1bf2: 0x10b1, 0x1bf3: 0x10c9, 0x1bf4: 0xbb19, 0x1bf5: 0xbb31,
- 0x1bf6: 0xbb49, 0x1bf7: 0x1429, 0x1bf8: 0x1a31, 0x1bf9: 0xbb61, 0x1bfa: 0xbb79, 0x1bfb: 0xbb91,
- 0x1bfc: 0xbba9, 0x1bfd: 0xbbc1, 0x1bfe: 0xbbd9, 0x1bff: 0x2109,
- // Block 0x70, offset 0x1c00
- 0x1c00: 0x1111, 0x1c01: 0xbbf1, 0x1c02: 0xbbf1, 0x1c03: 0xbc09, 0x1c04: 0xbc21, 0x1c05: 0x10e1,
- 0x1c06: 0x10f9, 0x1c07: 0xbc39, 0x1c08: 0x2079, 0x1c09: 0xbc71, 0x1c0a: 0xbb19, 0x1c0b: 0x1429,
- 0x1c0c: 0xbb61, 0x1c0d: 0x10e1, 0x1c0e: 0x1111, 0x1c0f: 0x2109, 0x1c10: 0xbb01, 0x1c11: 0x1099,
- 0x1c12: 0x10b1, 0x1c13: 0x10c9, 0x1c14: 0xbb19, 0x1c15: 0xbb31, 0x1c16: 0xbb49, 0x1c17: 0x1429,
- 0x1c18: 0x1a31, 0x1c19: 0xbb61, 0x1c1a: 0xbb79, 0x1c1b: 0xbb91, 0x1c1c: 0xbba9, 0x1c1d: 0xbbc1,
- 0x1c1e: 0xbbd9, 0x1c1f: 0x2109, 0x1c20: 0x1111, 0x1c21: 0x1429, 0x1c22: 0xbbf1, 0x1c23: 0xbc09,
- 0x1c24: 0xbc21, 0x1c25: 0x10e1, 0x1c26: 0x10f9, 0x1c27: 0xbc39, 0x1c28: 0x2079, 0x1c29: 0xbc51,
- 0x1c2a: 0xbb01, 0x1c2b: 0x1099, 0x1c2c: 0x10b1, 0x1c2d: 0x10c9, 0x1c2e: 0xbb19, 0x1c2f: 0xbb31,
- 0x1c30: 0xbb49, 0x1c31: 0x1429, 0x1c32: 0x1a31, 0x1c33: 0xbb61, 0x1c34: 0xbb79, 0x1c35: 0xbb91,
- 0x1c36: 0xbba9, 0x1c37: 0xbbc1, 0x1c38: 0xbbd9, 0x1c39: 0x2109, 0x1c3a: 0x1111, 0x1c3b: 0xbbf1,
- 0x1c3c: 0xbbf1, 0x1c3d: 0xbc09, 0x1c3e: 0xbc21, 0x1c3f: 0x10e1,
- // Block 0x71, offset 0x1c40
- 0x1c40: 0x10f9, 0x1c41: 0xbc39, 0x1c42: 0x2079, 0x1c43: 0xbc71, 0x1c44: 0xbb19, 0x1c45: 0x1429,
- 0x1c46: 0xbb61, 0x1c47: 0x10e1, 0x1c48: 0x1111, 0x1c49: 0x2109, 0x1c4a: 0xbc91, 0x1c4b: 0xbc91,
- 0x1c4c: 0x0040, 0x1c4d: 0x0040, 0x1c4e: 0x1f41, 0x1c4f: 0x00c9, 0x1c50: 0x0069, 0x1c51: 0x0079,
- 0x1c52: 0x1f51, 0x1c53: 0x1f61, 0x1c54: 0x1f71, 0x1c55: 0x1f81, 0x1c56: 0x1f91, 0x1c57: 0x1fa1,
- 0x1c58: 0x1f41, 0x1c59: 0x00c9, 0x1c5a: 0x0069, 0x1c5b: 0x0079, 0x1c5c: 0x1f51, 0x1c5d: 0x1f61,
- 0x1c5e: 0x1f71, 0x1c5f: 0x1f81, 0x1c60: 0x1f91, 0x1c61: 0x1fa1, 0x1c62: 0x1f41, 0x1c63: 0x00c9,
- 0x1c64: 0x0069, 0x1c65: 0x0079, 0x1c66: 0x1f51, 0x1c67: 0x1f61, 0x1c68: 0x1f71, 0x1c69: 0x1f81,
- 0x1c6a: 0x1f91, 0x1c6b: 0x1fa1, 0x1c6c: 0x1f41, 0x1c6d: 0x00c9, 0x1c6e: 0x0069, 0x1c6f: 0x0079,
- 0x1c70: 0x1f51, 0x1c71: 0x1f61, 0x1c72: 0x1f71, 0x1c73: 0x1f81, 0x1c74: 0x1f91, 0x1c75: 0x1fa1,
- 0x1c76: 0x1f41, 0x1c77: 0x00c9, 0x1c78: 0x0069, 0x1c79: 0x0079, 0x1c7a: 0x1f51, 0x1c7b: 0x1f61,
- 0x1c7c: 0x1f71, 0x1c7d: 0x1f81, 0x1c7e: 0x1f91, 0x1c7f: 0x1fa1,
- // Block 0x72, offset 0x1c80
- 0x1c80: 0xe115, 0x1c81: 0xe115, 0x1c82: 0xe135, 0x1c83: 0xe135, 0x1c84: 0xe115, 0x1c85: 0xe115,
- 0x1c86: 0xe175, 0x1c87: 0xe175, 0x1c88: 0xe115, 0x1c89: 0xe115, 0x1c8a: 0xe135, 0x1c8b: 0xe135,
- 0x1c8c: 0xe115, 0x1c8d: 0xe115, 0x1c8e: 0xe1f5, 0x1c8f: 0xe1f5, 0x1c90: 0xe115, 0x1c91: 0xe115,
- 0x1c92: 0xe135, 0x1c93: 0xe135, 0x1c94: 0xe115, 0x1c95: 0xe115, 0x1c96: 0xe175, 0x1c97: 0xe175,
- 0x1c98: 0xe115, 0x1c99: 0xe115, 0x1c9a: 0xe135, 0x1c9b: 0xe135, 0x1c9c: 0xe115, 0x1c9d: 0xe115,
- 0x1c9e: 0x8b3d, 0x1c9f: 0x8b3d, 0x1ca0: 0x04b5, 0x1ca1: 0x04b5, 0x1ca2: 0x0a08, 0x1ca3: 0x0a08,
- 0x1ca4: 0x0a08, 0x1ca5: 0x0a08, 0x1ca6: 0x0a08, 0x1ca7: 0x0a08, 0x1ca8: 0x0a08, 0x1ca9: 0x0a08,
- 0x1caa: 0x0a08, 0x1cab: 0x0a08, 0x1cac: 0x0a08, 0x1cad: 0x0a08, 0x1cae: 0x0a08, 0x1caf: 0x0a08,
- 0x1cb0: 0x0a08, 0x1cb1: 0x0a08, 0x1cb2: 0x0a08, 0x1cb3: 0x0a08, 0x1cb4: 0x0a08, 0x1cb5: 0x0a08,
- 0x1cb6: 0x0a08, 0x1cb7: 0x0a08, 0x1cb8: 0x0a08, 0x1cb9: 0x0a08, 0x1cba: 0x0a08, 0x1cbb: 0x0a08,
- 0x1cbc: 0x0a08, 0x1cbd: 0x0a08, 0x1cbe: 0x0a08, 0x1cbf: 0x0a08,
- // Block 0x73, offset 0x1cc0
- 0x1cc0: 0xb1d9, 0x1cc1: 0xb1f1, 0x1cc2: 0xb251, 0x1cc3: 0xb299, 0x1cc4: 0x0040, 0x1cc5: 0xb461,
- 0x1cc6: 0xb2e1, 0x1cc7: 0xb269, 0x1cc8: 0xb359, 0x1cc9: 0xb479, 0x1cca: 0xb3e9, 0x1ccb: 0xb401,
- 0x1ccc: 0xb419, 0x1ccd: 0xb431, 0x1cce: 0xb2f9, 0x1ccf: 0xb389, 0x1cd0: 0xb3b9, 0x1cd1: 0xb329,
- 0x1cd2: 0xb3d1, 0x1cd3: 0xb2c9, 0x1cd4: 0xb311, 0x1cd5: 0xb221, 0x1cd6: 0xb239, 0x1cd7: 0xb281,
- 0x1cd8: 0xb2b1, 0x1cd9: 0xb341, 0x1cda: 0xb371, 0x1cdb: 0xb3a1, 0x1cdc: 0xbca9, 0x1cdd: 0x7999,
- 0x1cde: 0xbcc1, 0x1cdf: 0xbcd9, 0x1ce0: 0x0040, 0x1ce1: 0xb1f1, 0x1ce2: 0xb251, 0x1ce3: 0x0040,
- 0x1ce4: 0xb449, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb269, 0x1ce8: 0x0040, 0x1ce9: 0xb479,
- 0x1cea: 0xb3e9, 0x1ceb: 0xb401, 0x1cec: 0xb419, 0x1ced: 0xb431, 0x1cee: 0xb2f9, 0x1cef: 0xb389,
- 0x1cf0: 0xb3b9, 0x1cf1: 0xb329, 0x1cf2: 0xb3d1, 0x1cf3: 0x0040, 0x1cf4: 0xb311, 0x1cf5: 0xb221,
- 0x1cf6: 0xb239, 0x1cf7: 0xb281, 0x1cf8: 0x0040, 0x1cf9: 0xb341, 0x1cfa: 0x0040, 0x1cfb: 0xb3a1,
- 0x1cfc: 0x0040, 0x1cfd: 0x0040, 0x1cfe: 0x0040, 0x1cff: 0x0040,
- // Block 0x74, offset 0x1d00
- 0x1d00: 0x0040, 0x1d01: 0x0040, 0x1d02: 0xb251, 0x1d03: 0x0040, 0x1d04: 0x0040, 0x1d05: 0x0040,
- 0x1d06: 0x0040, 0x1d07: 0xb269, 0x1d08: 0x0040, 0x1d09: 0xb479, 0x1d0a: 0x0040, 0x1d0b: 0xb401,
- 0x1d0c: 0x0040, 0x1d0d: 0xb431, 0x1d0e: 0xb2f9, 0x1d0f: 0xb389, 0x1d10: 0x0040, 0x1d11: 0xb329,
- 0x1d12: 0xb3d1, 0x1d13: 0x0040, 0x1d14: 0xb311, 0x1d15: 0x0040, 0x1d16: 0x0040, 0x1d17: 0xb281,
- 0x1d18: 0x0040, 0x1d19: 0xb341, 0x1d1a: 0x0040, 0x1d1b: 0xb3a1, 0x1d1c: 0x0040, 0x1d1d: 0x7999,
- 0x1d1e: 0x0040, 0x1d1f: 0xbcd9, 0x1d20: 0x0040, 0x1d21: 0xb1f1, 0x1d22: 0xb251, 0x1d23: 0x0040,
- 0x1d24: 0xb449, 0x1d25: 0x0040, 0x1d26: 0x0040, 0x1d27: 0xb269, 0x1d28: 0xb359, 0x1d29: 0xb479,
- 0x1d2a: 0xb3e9, 0x1d2b: 0x0040, 0x1d2c: 0xb419, 0x1d2d: 0xb431, 0x1d2e: 0xb2f9, 0x1d2f: 0xb389,
- 0x1d30: 0xb3b9, 0x1d31: 0xb329, 0x1d32: 0xb3d1, 0x1d33: 0x0040, 0x1d34: 0xb311, 0x1d35: 0xb221,
- 0x1d36: 0xb239, 0x1d37: 0xb281, 0x1d38: 0x0040, 0x1d39: 0xb341, 0x1d3a: 0xb371, 0x1d3b: 0xb3a1,
- 0x1d3c: 0xbca9, 0x1d3d: 0x0040, 0x1d3e: 0xbcc1, 0x1d3f: 0x0040,
- // Block 0x75, offset 0x1d40
- 0x1d40: 0xb1d9, 0x1d41: 0xb1f1, 0x1d42: 0xb251, 0x1d43: 0xb299, 0x1d44: 0xb449, 0x1d45: 0xb461,
- 0x1d46: 0xb2e1, 0x1d47: 0xb269, 0x1d48: 0xb359, 0x1d49: 0xb479, 0x1d4a: 0x0040, 0x1d4b: 0xb401,
- 0x1d4c: 0xb419, 0x1d4d: 0xb431, 0x1d4e: 0xb2f9, 0x1d4f: 0xb389, 0x1d50: 0xb3b9, 0x1d51: 0xb329,
- 0x1d52: 0xb3d1, 0x1d53: 0xb2c9, 0x1d54: 0xb311, 0x1d55: 0xb221, 0x1d56: 0xb239, 0x1d57: 0xb281,
- 0x1d58: 0xb2b1, 0x1d59: 0xb341, 0x1d5a: 0xb371, 0x1d5b: 0xb3a1, 0x1d5c: 0x0040, 0x1d5d: 0x0040,
- 0x1d5e: 0x0040, 0x1d5f: 0x0040, 0x1d60: 0x0040, 0x1d61: 0xb1f1, 0x1d62: 0xb251, 0x1d63: 0xb299,
- 0x1d64: 0x0040, 0x1d65: 0xb461, 0x1d66: 0xb2e1, 0x1d67: 0xb269, 0x1d68: 0xb359, 0x1d69: 0xb479,
- 0x1d6a: 0x0040, 0x1d6b: 0xb401, 0x1d6c: 0xb419, 0x1d6d: 0xb431, 0x1d6e: 0xb2f9, 0x1d6f: 0xb389,
- 0x1d70: 0xb3b9, 0x1d71: 0xb329, 0x1d72: 0xb3d1, 0x1d73: 0xb2c9, 0x1d74: 0xb311, 0x1d75: 0xb221,
- 0x1d76: 0xb239, 0x1d77: 0xb281, 0x1d78: 0xb2b1, 0x1d79: 0xb341, 0x1d7a: 0xb371, 0x1d7b: 0xb3a1,
- 0x1d7c: 0x0040, 0x1d7d: 0x0040, 0x1d7e: 0x0040, 0x1d7f: 0x0040,
- // Block 0x76, offset 0x1d80
- 0x1d80: 0x0040, 0x1d81: 0xbcf2, 0x1d82: 0xbd0a, 0x1d83: 0xbd22, 0x1d84: 0xbd3a, 0x1d85: 0xbd52,
- 0x1d86: 0xbd6a, 0x1d87: 0xbd82, 0x1d88: 0xbd9a, 0x1d89: 0xbdb2, 0x1d8a: 0xbdca, 0x1d8b: 0x0018,
- 0x1d8c: 0x0018, 0x1d8d: 0x0018, 0x1d8e: 0x0018, 0x1d8f: 0x0018, 0x1d90: 0xbde2, 0x1d91: 0xbe02,
- 0x1d92: 0xbe22, 0x1d93: 0xbe42, 0x1d94: 0xbe62, 0x1d95: 0xbe82, 0x1d96: 0xbea2, 0x1d97: 0xbec2,
- 0x1d98: 0xbee2, 0x1d99: 0xbf02, 0x1d9a: 0xbf22, 0x1d9b: 0xbf42, 0x1d9c: 0xbf62, 0x1d9d: 0xbf82,
- 0x1d9e: 0xbfa2, 0x1d9f: 0xbfc2, 0x1da0: 0xbfe2, 0x1da1: 0xc002, 0x1da2: 0xc022, 0x1da3: 0xc042,
- 0x1da4: 0xc062, 0x1da5: 0xc082, 0x1da6: 0xc0a2, 0x1da7: 0xc0c2, 0x1da8: 0xc0e2, 0x1da9: 0xc102,
- 0x1daa: 0xc121, 0x1dab: 0x1159, 0x1dac: 0x0269, 0x1dad: 0x66a9, 0x1dae: 0xc161, 0x1daf: 0x0018,
- 0x1db0: 0x0039, 0x1db1: 0x0ee9, 0x1db2: 0x1159, 0x1db3: 0x0ef9, 0x1db4: 0x0f09, 0x1db5: 0x1199,
- 0x1db6: 0x0f31, 0x1db7: 0x0249, 0x1db8: 0x0f41, 0x1db9: 0x0259, 0x1dba: 0x0f51, 0x1dbb: 0x0359,
- 0x1dbc: 0x0f61, 0x1dbd: 0x0f71, 0x1dbe: 0x00d9, 0x1dbf: 0x0f99,
- // Block 0x77, offset 0x1dc0
- 0x1dc0: 0x2039, 0x1dc1: 0x0269, 0x1dc2: 0x01d9, 0x1dc3: 0x0fa9, 0x1dc4: 0x0fb9, 0x1dc5: 0x1089,
- 0x1dc6: 0x0279, 0x1dc7: 0x0369, 0x1dc8: 0x0289, 0x1dc9: 0x13d1, 0x1dca: 0xc179, 0x1dcb: 0x65e9,
- 0x1dcc: 0xc191, 0x1dcd: 0x1441, 0x1dce: 0xc1a9, 0x1dcf: 0xc1c9, 0x1dd0: 0x0018, 0x1dd1: 0x0018,
- 0x1dd2: 0x0018, 0x1dd3: 0x0018, 0x1dd4: 0x0018, 0x1dd5: 0x0018, 0x1dd6: 0x0018, 0x1dd7: 0x0018,
- 0x1dd8: 0x0018, 0x1dd9: 0x0018, 0x1dda: 0x0018, 0x1ddb: 0x0018, 0x1ddc: 0x0018, 0x1ddd: 0x0018,
- 0x1dde: 0x0018, 0x1ddf: 0x0018, 0x1de0: 0x0018, 0x1de1: 0x0018, 0x1de2: 0x0018, 0x1de3: 0x0018,
- 0x1de4: 0x0018, 0x1de5: 0x0018, 0x1de6: 0x0018, 0x1de7: 0x0018, 0x1de8: 0x0018, 0x1de9: 0x0018,
- 0x1dea: 0xc1e1, 0x1deb: 0xc1f9, 0x1dec: 0xc211, 0x1ded: 0x0018, 0x1dee: 0x0018, 0x1def: 0x0018,
- 0x1df0: 0x0018, 0x1df1: 0x0018, 0x1df2: 0x0018, 0x1df3: 0x0018, 0x1df4: 0x0018, 0x1df5: 0x0018,
- 0x1df6: 0x0018, 0x1df7: 0x0018, 0x1df8: 0x0018, 0x1df9: 0x0018, 0x1dfa: 0x0018, 0x1dfb: 0x0018,
- 0x1dfc: 0x0018, 0x1dfd: 0x0018, 0x1dfe: 0x0018, 0x1dff: 0x0018,
- // Block 0x78, offset 0x1e00
- 0x1e00: 0xc241, 0x1e01: 0xc279, 0x1e02: 0xc2b1, 0x1e03: 0x0040, 0x1e04: 0x0040, 0x1e05: 0x0040,
- 0x1e06: 0x0040, 0x1e07: 0x0040, 0x1e08: 0x0040, 0x1e09: 0x0040, 0x1e0a: 0x0040, 0x1e0b: 0x0040,
- 0x1e0c: 0x0040, 0x1e0d: 0x0040, 0x1e0e: 0x0040, 0x1e0f: 0x0040, 0x1e10: 0xc2d1, 0x1e11: 0xc2f1,
- 0x1e12: 0xc311, 0x1e13: 0xc331, 0x1e14: 0xc351, 0x1e15: 0xc371, 0x1e16: 0xc391, 0x1e17: 0xc3b1,
- 0x1e18: 0xc3d1, 0x1e19: 0xc3f1, 0x1e1a: 0xc411, 0x1e1b: 0xc431, 0x1e1c: 0xc451, 0x1e1d: 0xc471,
- 0x1e1e: 0xc491, 0x1e1f: 0xc4b1, 0x1e20: 0xc4d1, 0x1e21: 0xc4f1, 0x1e22: 0xc511, 0x1e23: 0xc531,
- 0x1e24: 0xc551, 0x1e25: 0xc571, 0x1e26: 0xc591, 0x1e27: 0xc5b1, 0x1e28: 0xc5d1, 0x1e29: 0xc5f1,
- 0x1e2a: 0xc611, 0x1e2b: 0xc631, 0x1e2c: 0xc651, 0x1e2d: 0xc671, 0x1e2e: 0xc691, 0x1e2f: 0xc6b1,
- 0x1e30: 0xc6d1, 0x1e31: 0xc6f1, 0x1e32: 0xc711, 0x1e33: 0xc731, 0x1e34: 0xc751, 0x1e35: 0xc771,
- 0x1e36: 0xc791, 0x1e37: 0xc7b1, 0x1e38: 0xc7d1, 0x1e39: 0xc7f1, 0x1e3a: 0xc811, 0x1e3b: 0xc831,
- 0x1e3c: 0x0040, 0x1e3d: 0x0040, 0x1e3e: 0x0040, 0x1e3f: 0x0040,
- // Block 0x79, offset 0x1e40
- 0x1e40: 0xcb61, 0x1e41: 0xcb81, 0x1e42: 0xcba1, 0x1e43: 0x8b55, 0x1e44: 0xcbc1, 0x1e45: 0xcbe1,
- 0x1e46: 0xcc01, 0x1e47: 0xcc21, 0x1e48: 0xcc41, 0x1e49: 0xcc61, 0x1e4a: 0xcc81, 0x1e4b: 0xcca1,
- 0x1e4c: 0xccc1, 0x1e4d: 0x8b75, 0x1e4e: 0xcce1, 0x1e4f: 0xcd01, 0x1e50: 0xcd21, 0x1e51: 0xcd41,
- 0x1e52: 0x8b95, 0x1e53: 0xcd61, 0x1e54: 0xcd81, 0x1e55: 0xc491, 0x1e56: 0x8bb5, 0x1e57: 0xcda1,
- 0x1e58: 0xcdc1, 0x1e59: 0xcde1, 0x1e5a: 0xce01, 0x1e5b: 0xce21, 0x1e5c: 0x8bd5, 0x1e5d: 0xce41,
- 0x1e5e: 0xce61, 0x1e5f: 0xce81, 0x1e60: 0xcea1, 0x1e61: 0xcec1, 0x1e62: 0xc7f1, 0x1e63: 0xcee1,
- 0x1e64: 0xcf01, 0x1e65: 0xcf21, 0x1e66: 0xcf41, 0x1e67: 0xcf61, 0x1e68: 0xcf81, 0x1e69: 0xcfa1,
- 0x1e6a: 0xcfc1, 0x1e6b: 0xcfe1, 0x1e6c: 0xd001, 0x1e6d: 0xd021, 0x1e6e: 0xd041, 0x1e6f: 0xd061,
- 0x1e70: 0xd081, 0x1e71: 0xd0a1, 0x1e72: 0xd0a1, 0x1e73: 0xd0a1, 0x1e74: 0x8bf5, 0x1e75: 0xd0c1,
- 0x1e76: 0xd0e1, 0x1e77: 0xd101, 0x1e78: 0x8c15, 0x1e79: 0xd121, 0x1e7a: 0xd141, 0x1e7b: 0xd161,
- 0x1e7c: 0xd181, 0x1e7d: 0xd1a1, 0x1e7e: 0xd1c1, 0x1e7f: 0xd1e1,
- // Block 0x7a, offset 0x1e80
- 0x1e80: 0xd201, 0x1e81: 0xd221, 0x1e82: 0xd241, 0x1e83: 0xd261, 0x1e84: 0xd281, 0x1e85: 0xd2a1,
- 0x1e86: 0xd2a1, 0x1e87: 0xd2c1, 0x1e88: 0xd2e1, 0x1e89: 0xd301, 0x1e8a: 0xd321, 0x1e8b: 0xd341,
- 0x1e8c: 0xd361, 0x1e8d: 0xd381, 0x1e8e: 0xd3a1, 0x1e8f: 0xd3c1, 0x1e90: 0xd3e1, 0x1e91: 0xd401,
- 0x1e92: 0xd421, 0x1e93: 0xd441, 0x1e94: 0xd461, 0x1e95: 0xd481, 0x1e96: 0xd4a1, 0x1e97: 0xd4c1,
- 0x1e98: 0xd4e1, 0x1e99: 0x8c35, 0x1e9a: 0xd501, 0x1e9b: 0xd521, 0x1e9c: 0xd541, 0x1e9d: 0xc371,
- 0x1e9e: 0xd561, 0x1e9f: 0xd581, 0x1ea0: 0x8c55, 0x1ea1: 0x8c75, 0x1ea2: 0xd5a1, 0x1ea3: 0xd5c1,
- 0x1ea4: 0xd5e1, 0x1ea5: 0xd601, 0x1ea6: 0xd621, 0x1ea7: 0xd641, 0x1ea8: 0x2040, 0x1ea9: 0xd661,
- 0x1eaa: 0xd681, 0x1eab: 0xd681, 0x1eac: 0x8c95, 0x1ead: 0xd6a1, 0x1eae: 0xd6c1, 0x1eaf: 0xd6e1,
- 0x1eb0: 0xd701, 0x1eb1: 0x8cb5, 0x1eb2: 0xd721, 0x1eb3: 0xd741, 0x1eb4: 0x2040, 0x1eb5: 0xd761,
- 0x1eb6: 0xd781, 0x1eb7: 0xd7a1, 0x1eb8: 0xd7c1, 0x1eb9: 0xd7e1, 0x1eba: 0xd801, 0x1ebb: 0x8cd5,
- 0x1ebc: 0xd821, 0x1ebd: 0x8cf5, 0x1ebe: 0xd841, 0x1ebf: 0xd861,
- // Block 0x7b, offset 0x1ec0
- 0x1ec0: 0xd881, 0x1ec1: 0xd8a1, 0x1ec2: 0xd8c1, 0x1ec3: 0xd8e1, 0x1ec4: 0xd901, 0x1ec5: 0xd921,
- 0x1ec6: 0xd941, 0x1ec7: 0xd961, 0x1ec8: 0xd981, 0x1ec9: 0x8d15, 0x1eca: 0xd9a1, 0x1ecb: 0xd9c1,
- 0x1ecc: 0xd9e1, 0x1ecd: 0xda01, 0x1ece: 0xda21, 0x1ecf: 0x8d35, 0x1ed0: 0xda41, 0x1ed1: 0x8d55,
- 0x1ed2: 0x8d75, 0x1ed3: 0xda61, 0x1ed4: 0xda81, 0x1ed5: 0xda81, 0x1ed6: 0xdaa1, 0x1ed7: 0x8d95,
- 0x1ed8: 0x8db5, 0x1ed9: 0xdac1, 0x1eda: 0xdae1, 0x1edb: 0xdb01, 0x1edc: 0xdb21, 0x1edd: 0xdb41,
- 0x1ede: 0xdb61, 0x1edf: 0xdb81, 0x1ee0: 0xdba1, 0x1ee1: 0xdbc1, 0x1ee2: 0xdbe1, 0x1ee3: 0xdc01,
- 0x1ee4: 0x8dd5, 0x1ee5: 0xdc21, 0x1ee6: 0xdc41, 0x1ee7: 0xdc61, 0x1ee8: 0xdc81, 0x1ee9: 0xdc61,
- 0x1eea: 0xdca1, 0x1eeb: 0xdcc1, 0x1eec: 0xdce1, 0x1eed: 0xdd01, 0x1eee: 0xdd21, 0x1eef: 0xdd41,
- 0x1ef0: 0xdd61, 0x1ef1: 0xdd81, 0x1ef2: 0xdda1, 0x1ef3: 0xddc1, 0x1ef4: 0xdde1, 0x1ef5: 0xde01,
- 0x1ef6: 0xde21, 0x1ef7: 0xde41, 0x1ef8: 0x8df5, 0x1ef9: 0xde61, 0x1efa: 0xde81, 0x1efb: 0xdea1,
- 0x1efc: 0xdec1, 0x1efd: 0xdee1, 0x1efe: 0x8e15, 0x1eff: 0xdf01,
- // Block 0x7c, offset 0x1f00
- 0x1f00: 0xe601, 0x1f01: 0xe621, 0x1f02: 0xe641, 0x1f03: 0xe661, 0x1f04: 0xe681, 0x1f05: 0xe6a1,
- 0x1f06: 0x8f35, 0x1f07: 0xe6c1, 0x1f08: 0xe6e1, 0x1f09: 0xe701, 0x1f0a: 0xe721, 0x1f0b: 0xe741,
- 0x1f0c: 0xe761, 0x1f0d: 0x8f55, 0x1f0e: 0xe781, 0x1f0f: 0xe7a1, 0x1f10: 0x8f75, 0x1f11: 0x8f95,
- 0x1f12: 0xe7c1, 0x1f13: 0xe7e1, 0x1f14: 0xe801, 0x1f15: 0xe821, 0x1f16: 0xe841, 0x1f17: 0xe861,
- 0x1f18: 0xe881, 0x1f19: 0xe8a1, 0x1f1a: 0xe8c1, 0x1f1b: 0x8fb5, 0x1f1c: 0xe8e1, 0x1f1d: 0x8fd5,
- 0x1f1e: 0xe901, 0x1f1f: 0x2040, 0x1f20: 0xe921, 0x1f21: 0xe941, 0x1f22: 0xe961, 0x1f23: 0x8ff5,
- 0x1f24: 0xe981, 0x1f25: 0xe9a1, 0x1f26: 0x9015, 0x1f27: 0x9035, 0x1f28: 0xe9c1, 0x1f29: 0xe9e1,
- 0x1f2a: 0xea01, 0x1f2b: 0xea21, 0x1f2c: 0xea41, 0x1f2d: 0xea41, 0x1f2e: 0xea61, 0x1f2f: 0xea81,
- 0x1f30: 0xeaa1, 0x1f31: 0xeac1, 0x1f32: 0xeae1, 0x1f33: 0xeb01, 0x1f34: 0xeb21, 0x1f35: 0x9055,
- 0x1f36: 0xeb41, 0x1f37: 0x9075, 0x1f38: 0xeb61, 0x1f39: 0x9095, 0x1f3a: 0xeb81, 0x1f3b: 0x90b5,
- 0x1f3c: 0x90d5, 0x1f3d: 0x90f5, 0x1f3e: 0xeba1, 0x1f3f: 0xebc1,
- // Block 0x7d, offset 0x1f40
- 0x1f40: 0xebe1, 0x1f41: 0x9115, 0x1f42: 0x9135, 0x1f43: 0x9155, 0x1f44: 0x9175, 0x1f45: 0xec01,
- 0x1f46: 0xec21, 0x1f47: 0xec21, 0x1f48: 0xec41, 0x1f49: 0xec61, 0x1f4a: 0xec81, 0x1f4b: 0xeca1,
- 0x1f4c: 0xecc1, 0x1f4d: 0x9195, 0x1f4e: 0xece1, 0x1f4f: 0xed01, 0x1f50: 0xed21, 0x1f51: 0xed41,
- 0x1f52: 0x91b5, 0x1f53: 0xed61, 0x1f54: 0x91d5, 0x1f55: 0x91f5, 0x1f56: 0xed81, 0x1f57: 0xeda1,
- 0x1f58: 0xedc1, 0x1f59: 0xede1, 0x1f5a: 0xee01, 0x1f5b: 0xee21, 0x1f5c: 0x9215, 0x1f5d: 0x9235,
- 0x1f5e: 0x9255, 0x1f5f: 0x2040, 0x1f60: 0xee41, 0x1f61: 0x9275, 0x1f62: 0xee61, 0x1f63: 0xee81,
- 0x1f64: 0xeea1, 0x1f65: 0x9295, 0x1f66: 0xeec1, 0x1f67: 0xeee1, 0x1f68: 0xef01, 0x1f69: 0xef21,
- 0x1f6a: 0xef41, 0x1f6b: 0x92b5, 0x1f6c: 0xef61, 0x1f6d: 0xef81, 0x1f6e: 0xefa1, 0x1f6f: 0xefc1,
- 0x1f70: 0xefe1, 0x1f71: 0xf001, 0x1f72: 0x92d5, 0x1f73: 0x92f5, 0x1f74: 0xf021, 0x1f75: 0x9315,
- 0x1f76: 0xf041, 0x1f77: 0x9335, 0x1f78: 0xf061, 0x1f79: 0xf081, 0x1f7a: 0xf0a1, 0x1f7b: 0x9355,
- 0x1f7c: 0x9375, 0x1f7d: 0xf0c1, 0x1f7e: 0x9395, 0x1f7f: 0xf0e1,
- // Block 0x7e, offset 0x1f80
- 0x1f80: 0xf721, 0x1f81: 0xf741, 0x1f82: 0xf761, 0x1f83: 0xf781, 0x1f84: 0xf7a1, 0x1f85: 0x9555,
- 0x1f86: 0xf7c1, 0x1f87: 0xf7e1, 0x1f88: 0xf801, 0x1f89: 0xf821, 0x1f8a: 0xf841, 0x1f8b: 0x9575,
- 0x1f8c: 0x9595, 0x1f8d: 0xf861, 0x1f8e: 0xf881, 0x1f8f: 0xf8a1, 0x1f90: 0xf8c1, 0x1f91: 0xf8e1,
- 0x1f92: 0xf901, 0x1f93: 0x95b5, 0x1f94: 0xf921, 0x1f95: 0xf941, 0x1f96: 0xf961, 0x1f97: 0xf981,
- 0x1f98: 0x95d5, 0x1f99: 0x95f5, 0x1f9a: 0xf9a1, 0x1f9b: 0xf9c1, 0x1f9c: 0xf9e1, 0x1f9d: 0x9615,
- 0x1f9e: 0xfa01, 0x1f9f: 0xfa21, 0x1fa0: 0x684d, 0x1fa1: 0x9635, 0x1fa2: 0xfa41, 0x1fa3: 0xfa61,
- 0x1fa4: 0xfa81, 0x1fa5: 0x9655, 0x1fa6: 0xfaa1, 0x1fa7: 0xfac1, 0x1fa8: 0xfae1, 0x1fa9: 0xfb01,
- 0x1faa: 0xfb21, 0x1fab: 0xfb41, 0x1fac: 0xfb61, 0x1fad: 0x9675, 0x1fae: 0xfb81, 0x1faf: 0xfba1,
- 0x1fb0: 0xfbc1, 0x1fb1: 0x9695, 0x1fb2: 0xfbe1, 0x1fb3: 0xfc01, 0x1fb4: 0xfc21, 0x1fb5: 0xfc41,
- 0x1fb6: 0x7b6d, 0x1fb7: 0x96b5, 0x1fb8: 0xfc61, 0x1fb9: 0xfc81, 0x1fba: 0xfca1, 0x1fbb: 0x96d5,
- 0x1fbc: 0xfcc1, 0x1fbd: 0x96f5, 0x1fbe: 0xfce1, 0x1fbf: 0xfce1,
- // Block 0x7f, offset 0x1fc0
- 0x1fc0: 0xfd01, 0x1fc1: 0x9715, 0x1fc2: 0xfd21, 0x1fc3: 0xfd41, 0x1fc4: 0xfd61, 0x1fc5: 0xfd81,
- 0x1fc6: 0xfda1, 0x1fc7: 0xfdc1, 0x1fc8: 0xfde1, 0x1fc9: 0x9735, 0x1fca: 0xfe01, 0x1fcb: 0xfe21,
- 0x1fcc: 0xfe41, 0x1fcd: 0xfe61, 0x1fce: 0xfe81, 0x1fcf: 0xfea1, 0x1fd0: 0x9755, 0x1fd1: 0xfec1,
- 0x1fd2: 0x9775, 0x1fd3: 0x9795, 0x1fd4: 0x97b5, 0x1fd5: 0xfee1, 0x1fd6: 0xff01, 0x1fd7: 0xff21,
- 0x1fd8: 0xff41, 0x1fd9: 0xff61, 0x1fda: 0xff81, 0x1fdb: 0xffa1, 0x1fdc: 0xffc1, 0x1fdd: 0x97d5,
- 0x1fde: 0x0040, 0x1fdf: 0x0040, 0x1fe0: 0x0040, 0x1fe1: 0x0040, 0x1fe2: 0x0040, 0x1fe3: 0x0040,
- 0x1fe4: 0x0040, 0x1fe5: 0x0040, 0x1fe6: 0x0040, 0x1fe7: 0x0040, 0x1fe8: 0x0040, 0x1fe9: 0x0040,
- 0x1fea: 0x0040, 0x1feb: 0x0040, 0x1fec: 0x0040, 0x1fed: 0x0040, 0x1fee: 0x0040, 0x1fef: 0x0040,
- 0x1ff0: 0x0040, 0x1ff1: 0x0040, 0x1ff2: 0x0040, 0x1ff3: 0x0040, 0x1ff4: 0x0040, 0x1ff5: 0x0040,
- 0x1ff6: 0x0040, 0x1ff7: 0x0040, 0x1ff8: 0x0040, 0x1ff9: 0x0040, 0x1ffa: 0x0040, 0x1ffb: 0x0040,
- 0x1ffc: 0x0040, 0x1ffd: 0x0040, 0x1ffe: 0x0040, 0x1fff: 0x0040,
-}
-
-// idnaIndex: 37 blocks, 2368 entries, 4736 bytes
-// Block 0 is the zero block.
-var idnaIndex = [2368]uint16{
- // Block 0x0, offset 0x0
- // Block 0x1, offset 0x40
- // Block 0x2, offset 0x80
- // Block 0x3, offset 0xc0
- 0xc2: 0x01, 0xc3: 0x7e, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,
- 0xc8: 0x06, 0xc9: 0x7f, 0xca: 0x80, 0xcb: 0x07, 0xcc: 0x81, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,
- 0xd0: 0x82, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x83, 0xd6: 0x84, 0xd7: 0x85,
- 0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x86, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x87, 0xde: 0x88, 0xdf: 0x89,
- 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,
- 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c,
- 0xf0: 0x1e, 0xf1: 0x1f, 0xf2: 0x1f, 0xf3: 0x21, 0xf4: 0x22,
- // Block 0x4, offset 0x100
- 0x120: 0x8a, 0x121: 0x13, 0x122: 0x8b, 0x123: 0x8c, 0x124: 0x8d, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16,
- 0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8e,
- 0x130: 0x8f, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x90, 0x135: 0x21, 0x136: 0x91, 0x137: 0x92,
- 0x138: 0x93, 0x139: 0x94, 0x13a: 0x22, 0x13b: 0x95, 0x13c: 0x96, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x97,
- // Block 0x5, offset 0x140
- 0x140: 0x98, 0x141: 0x99, 0x142: 0x9a, 0x143: 0x9b, 0x144: 0x9c, 0x145: 0x9d, 0x146: 0x9e, 0x147: 0x9f,
- 0x148: 0xa0, 0x149: 0xa1, 0x14a: 0xa2, 0x14b: 0xa3, 0x14c: 0xa4, 0x14d: 0xa5, 0x14e: 0xa6, 0x14f: 0xa7,
- 0x150: 0xa8, 0x151: 0xa0, 0x152: 0xa0, 0x153: 0xa0, 0x154: 0xa0, 0x155: 0xa0, 0x156: 0xa0, 0x157: 0xa0,
- 0x158: 0xa0, 0x159: 0xa9, 0x15a: 0xaa, 0x15b: 0xab, 0x15c: 0xac, 0x15d: 0xad, 0x15e: 0xae, 0x15f: 0xaf,
- 0x160: 0xb0, 0x161: 0xb1, 0x162: 0xb2, 0x163: 0xb3, 0x164: 0xb4, 0x165: 0xb5, 0x166: 0xb6, 0x167: 0xb7,
- 0x168: 0xb8, 0x169: 0xb9, 0x16a: 0xba, 0x16b: 0xbb, 0x16c: 0xbc, 0x16d: 0xbd, 0x16e: 0xbe, 0x16f: 0xbf,
- 0x170: 0xc0, 0x171: 0xc1, 0x172: 0xc2, 0x173: 0xc3, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc4,
- 0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc5, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c,
- // Block 0x6, offset 0x180
- 0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc6, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc7, 0x187: 0x9c,
- 0x188: 0xc8, 0x189: 0xc9, 0x18a: 0x9c, 0x18b: 0x9c, 0x18c: 0xca, 0x18d: 0x9c, 0x18e: 0x9c, 0x18f: 0x9c,
- 0x190: 0xcb, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9c, 0x195: 0x9c, 0x196: 0x9c, 0x197: 0x9c,
- 0x198: 0x9c, 0x199: 0x9c, 0x19a: 0x9c, 0x19b: 0x9c, 0x19c: 0x9c, 0x19d: 0x9c, 0x19e: 0x9c, 0x19f: 0x9c,
- 0x1a0: 0x9c, 0x1a1: 0x9c, 0x1a2: 0x9c, 0x1a3: 0x9c, 0x1a4: 0x9c, 0x1a5: 0x9c, 0x1a6: 0x9c, 0x1a7: 0x9c,
- 0x1a8: 0xcc, 0x1a9: 0xcd, 0x1aa: 0x9c, 0x1ab: 0xce, 0x1ac: 0x9c, 0x1ad: 0xcf, 0x1ae: 0xd0, 0x1af: 0x9c,
- 0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5,
- 0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37,
- // Block 0x7, offset 0x1c0
- 0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1,
- 0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41,
- 0x1d0: 0xa0, 0x1d1: 0xa0, 0x1d2: 0xa0, 0x1d3: 0xa0, 0x1d4: 0xa0, 0x1d5: 0xa0, 0x1d6: 0xa0, 0x1d7: 0xa0,
- 0x1d8: 0xa0, 0x1d9: 0xa0, 0x1da: 0xa0, 0x1db: 0xa0, 0x1dc: 0xa0, 0x1dd: 0xa0, 0x1de: 0xa0, 0x1df: 0xa0,
- 0x1e0: 0xa0, 0x1e1: 0xa0, 0x1e2: 0xa0, 0x1e3: 0xa0, 0x1e4: 0xa0, 0x1e5: 0xa0, 0x1e6: 0xa0, 0x1e7: 0xa0,
- 0x1e8: 0xa0, 0x1e9: 0xa0, 0x1ea: 0xa0, 0x1eb: 0xa0, 0x1ec: 0xa0, 0x1ed: 0xa0, 0x1ee: 0xa0, 0x1ef: 0xa0,
- 0x1f0: 0xa0, 0x1f1: 0xa0, 0x1f2: 0xa0, 0x1f3: 0xa0, 0x1f4: 0xa0, 0x1f5: 0xa0, 0x1f6: 0xa0, 0x1f7: 0xa0,
- 0x1f8: 0xa0, 0x1f9: 0xa0, 0x1fa: 0xa0, 0x1fb: 0xa0, 0x1fc: 0xa0, 0x1fd: 0xa0, 0x1fe: 0xa0, 0x1ff: 0xa0,
- // Block 0x8, offset 0x200
- 0x200: 0xa0, 0x201: 0xa0, 0x202: 0xa0, 0x203: 0xa0, 0x204: 0xa0, 0x205: 0xa0, 0x206: 0xa0, 0x207: 0xa0,
- 0x208: 0xa0, 0x209: 0xa0, 0x20a: 0xa0, 0x20b: 0xa0, 0x20c: 0xa0, 0x20d: 0xa0, 0x20e: 0xa0, 0x20f: 0xa0,
- 0x210: 0xa0, 0x211: 0xa0, 0x212: 0xa0, 0x213: 0xa0, 0x214: 0xa0, 0x215: 0xa0, 0x216: 0xa0, 0x217: 0xa0,
- 0x218: 0xa0, 0x219: 0xa0, 0x21a: 0xa0, 0x21b: 0xa0, 0x21c: 0xa0, 0x21d: 0xa0, 0x21e: 0xa0, 0x21f: 0xa0,
- 0x220: 0xa0, 0x221: 0xa0, 0x222: 0xa0, 0x223: 0xa0, 0x224: 0xa0, 0x225: 0xa0, 0x226: 0xa0, 0x227: 0xa0,
- 0x228: 0xa0, 0x229: 0xa0, 0x22a: 0xa0, 0x22b: 0xa0, 0x22c: 0xa0, 0x22d: 0xa0, 0x22e: 0xa0, 0x22f: 0xa0,
- 0x230: 0xa0, 0x231: 0xa0, 0x232: 0xa0, 0x233: 0xa0, 0x234: 0xa0, 0x235: 0xa0, 0x236: 0xa0, 0x237: 0x9c,
- 0x238: 0xa0, 0x239: 0xa0, 0x23a: 0xa0, 0x23b: 0xa0, 0x23c: 0xa0, 0x23d: 0xa0, 0x23e: 0xa0, 0x23f: 0xa0,
- // Block 0x9, offset 0x240
- 0x240: 0xa0, 0x241: 0xa0, 0x242: 0xa0, 0x243: 0xa0, 0x244: 0xa0, 0x245: 0xa0, 0x246: 0xa0, 0x247: 0xa0,
- 0x248: 0xa0, 0x249: 0xa0, 0x24a: 0xa0, 0x24b: 0xa0, 0x24c: 0xa0, 0x24d: 0xa0, 0x24e: 0xa0, 0x24f: 0xa0,
- 0x250: 0xa0, 0x251: 0xa0, 0x252: 0xa0, 0x253: 0xa0, 0x254: 0xa0, 0x255: 0xa0, 0x256: 0xa0, 0x257: 0xa0,
- 0x258: 0xa0, 0x259: 0xa0, 0x25a: 0xa0, 0x25b: 0xa0, 0x25c: 0xa0, 0x25d: 0xa0, 0x25e: 0xa0, 0x25f: 0xa0,
- 0x260: 0xa0, 0x261: 0xa0, 0x262: 0xa0, 0x263: 0xa0, 0x264: 0xa0, 0x265: 0xa0, 0x266: 0xa0, 0x267: 0xa0,
- 0x268: 0xa0, 0x269: 0xa0, 0x26a: 0xa0, 0x26b: 0xa0, 0x26c: 0xa0, 0x26d: 0xa0, 0x26e: 0xa0, 0x26f: 0xa0,
- 0x270: 0xa0, 0x271: 0xa0, 0x272: 0xa0, 0x273: 0xa0, 0x274: 0xa0, 0x275: 0xa0, 0x276: 0xa0, 0x277: 0xa0,
- 0x278: 0xa0, 0x279: 0xa0, 0x27a: 0xa0, 0x27b: 0xa0, 0x27c: 0xa0, 0x27d: 0xa0, 0x27e: 0xa0, 0x27f: 0xa0,
- // Block 0xa, offset 0x280
- 0x280: 0xa0, 0x281: 0xa0, 0x282: 0xa0, 0x283: 0xa0, 0x284: 0xa0, 0x285: 0xa0, 0x286: 0xa0, 0x287: 0xa0,
- 0x288: 0xa0, 0x289: 0xa0, 0x28a: 0xa0, 0x28b: 0xa0, 0x28c: 0xa0, 0x28d: 0xa0, 0x28e: 0xa0, 0x28f: 0xa0,
- 0x290: 0xa0, 0x291: 0xa0, 0x292: 0xa0, 0x293: 0xa0, 0x294: 0xa0, 0x295: 0xa0, 0x296: 0xa0, 0x297: 0xa0,
- 0x298: 0xa0, 0x299: 0xa0, 0x29a: 0xa0, 0x29b: 0xa0, 0x29c: 0xa0, 0x29d: 0xa0, 0x29e: 0xa0, 0x29f: 0xa0,
- 0x2a0: 0xa0, 0x2a1: 0xa0, 0x2a2: 0xa0, 0x2a3: 0xa0, 0x2a4: 0xa0, 0x2a5: 0xa0, 0x2a6: 0xa0, 0x2a7: 0xa0,
- 0x2a8: 0xa0, 0x2a9: 0xa0, 0x2aa: 0xa0, 0x2ab: 0xa0, 0x2ac: 0xa0, 0x2ad: 0xa0, 0x2ae: 0xa0, 0x2af: 0xa0,
- 0x2b0: 0xa0, 0x2b1: 0xa0, 0x2b2: 0xa0, 0x2b3: 0xa0, 0x2b4: 0xa0, 0x2b5: 0xa0, 0x2b6: 0xa0, 0x2b7: 0xa0,
- 0x2b8: 0xa0, 0x2b9: 0xa0, 0x2ba: 0xa0, 0x2bb: 0xa0, 0x2bc: 0xa0, 0x2bd: 0xa0, 0x2be: 0xa0, 0x2bf: 0xe3,
- // Block 0xb, offset 0x2c0
- 0x2c0: 0xa0, 0x2c1: 0xa0, 0x2c2: 0xa0, 0x2c3: 0xa0, 0x2c4: 0xa0, 0x2c5: 0xa0, 0x2c6: 0xa0, 0x2c7: 0xa0,
- 0x2c8: 0xa0, 0x2c9: 0xa0, 0x2ca: 0xa0, 0x2cb: 0xa0, 0x2cc: 0xa0, 0x2cd: 0xa0, 0x2ce: 0xa0, 0x2cf: 0xa0,
- 0x2d0: 0xa0, 0x2d1: 0xa0, 0x2d2: 0xe4, 0x2d3: 0xe5, 0x2d4: 0xa0, 0x2d5: 0xa0, 0x2d6: 0xa0, 0x2d7: 0xa0,
- 0x2d8: 0xe6, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe7, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe8,
- 0x2e0: 0xe9, 0x2e1: 0xea, 0x2e2: 0xeb, 0x2e3: 0xec, 0x2e4: 0xed, 0x2e5: 0xee, 0x2e6: 0xef, 0x2e7: 0xf0,
- 0x2e8: 0xf1, 0x2e9: 0xf2, 0x2ea: 0xf3, 0x2eb: 0xf4, 0x2ec: 0xf5, 0x2ed: 0xf6, 0x2ee: 0xf7, 0x2ef: 0xf8,
- 0x2f0: 0xa0, 0x2f1: 0xa0, 0x2f2: 0xa0, 0x2f3: 0xa0, 0x2f4: 0xa0, 0x2f5: 0xa0, 0x2f6: 0xa0, 0x2f7: 0xa0,
- 0x2f8: 0xa0, 0x2f9: 0xa0, 0x2fa: 0xa0, 0x2fb: 0xa0, 0x2fc: 0xa0, 0x2fd: 0xa0, 0x2fe: 0xa0, 0x2ff: 0xa0,
- // Block 0xc, offset 0x300
- 0x300: 0xa0, 0x301: 0xa0, 0x302: 0xa0, 0x303: 0xa0, 0x304: 0xa0, 0x305: 0xa0, 0x306: 0xa0, 0x307: 0xa0,
- 0x308: 0xa0, 0x309: 0xa0, 0x30a: 0xa0, 0x30b: 0xa0, 0x30c: 0xa0, 0x30d: 0xa0, 0x30e: 0xa0, 0x30f: 0xa0,
- 0x310: 0xa0, 0x311: 0xa0, 0x312: 0xa0, 0x313: 0xa0, 0x314: 0xa0, 0x315: 0xa0, 0x316: 0xa0, 0x317: 0xa0,
- 0x318: 0xa0, 0x319: 0xa0, 0x31a: 0xa0, 0x31b: 0xa0, 0x31c: 0xa0, 0x31d: 0xa0, 0x31e: 0xf9, 0x31f: 0xfa,
- // Block 0xd, offset 0x340
- 0x340: 0xfb, 0x341: 0xfb, 0x342: 0xfb, 0x343: 0xfb, 0x344: 0xfb, 0x345: 0xfb, 0x346: 0xfb, 0x347: 0xfb,
- 0x348: 0xfb, 0x349: 0xfb, 0x34a: 0xfb, 0x34b: 0xfb, 0x34c: 0xfb, 0x34d: 0xfb, 0x34e: 0xfb, 0x34f: 0xfb,
- 0x350: 0xfb, 0x351: 0xfb, 0x352: 0xfb, 0x353: 0xfb, 0x354: 0xfb, 0x355: 0xfb, 0x356: 0xfb, 0x357: 0xfb,
- 0x358: 0xfb, 0x359: 0xfb, 0x35a: 0xfb, 0x35b: 0xfb, 0x35c: 0xfb, 0x35d: 0xfb, 0x35e: 0xfb, 0x35f: 0xfb,
- 0x360: 0xfb, 0x361: 0xfb, 0x362: 0xfb, 0x363: 0xfb, 0x364: 0xfb, 0x365: 0xfb, 0x366: 0xfb, 0x367: 0xfb,
- 0x368: 0xfb, 0x369: 0xfb, 0x36a: 0xfb, 0x36b: 0xfb, 0x36c: 0xfb, 0x36d: 0xfb, 0x36e: 0xfb, 0x36f: 0xfb,
- 0x370: 0xfb, 0x371: 0xfb, 0x372: 0xfb, 0x373: 0xfb, 0x374: 0xfb, 0x375: 0xfb, 0x376: 0xfb, 0x377: 0xfb,
- 0x378: 0xfb, 0x379: 0xfb, 0x37a: 0xfb, 0x37b: 0xfb, 0x37c: 0xfb, 0x37d: 0xfb, 0x37e: 0xfb, 0x37f: 0xfb,
- // Block 0xe, offset 0x380
- 0x380: 0xfb, 0x381: 0xfb, 0x382: 0xfb, 0x383: 0xfb, 0x384: 0xfb, 0x385: 0xfb, 0x386: 0xfb, 0x387: 0xfb,
- 0x388: 0xfb, 0x389: 0xfb, 0x38a: 0xfb, 0x38b: 0xfb, 0x38c: 0xfb, 0x38d: 0xfb, 0x38e: 0xfb, 0x38f: 0xfb,
- 0x390: 0xfb, 0x391: 0xfb, 0x392: 0xfb, 0x393: 0xfb, 0x394: 0xfb, 0x395: 0xfb, 0x396: 0xfb, 0x397: 0xfb,
- 0x398: 0xfb, 0x399: 0xfb, 0x39a: 0xfb, 0x39b: 0xfb, 0x39c: 0xfb, 0x39d: 0xfb, 0x39e: 0xfb, 0x39f: 0xfb,
- 0x3a0: 0xfb, 0x3a1: 0xfb, 0x3a2: 0xfb, 0x3a3: 0xfb, 0x3a4: 0xfc, 0x3a5: 0xfd, 0x3a6: 0xfe, 0x3a7: 0xff,
- 0x3a8: 0x47, 0x3a9: 0x100, 0x3aa: 0x101, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c,
- 0x3b0: 0x102, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x103, 0x3b7: 0x52,
- 0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a,
- // Block 0xf, offset 0x3c0
- 0x3c0: 0x104, 0x3c1: 0x105, 0x3c2: 0xa0, 0x3c3: 0x106, 0x3c4: 0x107, 0x3c5: 0x9c, 0x3c6: 0x108, 0x3c7: 0x109,
- 0x3c8: 0xfb, 0x3c9: 0xfb, 0x3ca: 0x10a, 0x3cb: 0x10b, 0x3cc: 0x10c, 0x3cd: 0x10d, 0x3ce: 0x10e, 0x3cf: 0x10f,
- 0x3d0: 0x110, 0x3d1: 0xa0, 0x3d2: 0x111, 0x3d3: 0x112, 0x3d4: 0x113, 0x3d5: 0x114, 0x3d6: 0xfb, 0x3d7: 0xfb,
- 0x3d8: 0xa0, 0x3d9: 0xa0, 0x3da: 0xa0, 0x3db: 0xa0, 0x3dc: 0x115, 0x3dd: 0x116, 0x3de: 0xfb, 0x3df: 0xfb,
- 0x3e0: 0x117, 0x3e1: 0x118, 0x3e2: 0x119, 0x3e3: 0x11a, 0x3e4: 0x11b, 0x3e5: 0xfb, 0x3e6: 0x11c, 0x3e7: 0x11d,
- 0x3e8: 0x11e, 0x3e9: 0x11f, 0x3ea: 0x120, 0x3eb: 0x5b, 0x3ec: 0x121, 0x3ed: 0x122, 0x3ee: 0x5c, 0x3ef: 0xfb,
- 0x3f0: 0x123, 0x3f1: 0x124, 0x3f2: 0x125, 0x3f3: 0x126, 0x3f4: 0x127, 0x3f5: 0xfb, 0x3f6: 0xfb, 0x3f7: 0xfb,
- 0x3f8: 0xfb, 0x3f9: 0x128, 0x3fa: 0x129, 0x3fb: 0xfb, 0x3fc: 0x12a, 0x3fd: 0x12b, 0x3fe: 0x12c, 0x3ff: 0x12d,
- // Block 0x10, offset 0x400
- 0x400: 0x12e, 0x401: 0x12f, 0x402: 0x130, 0x403: 0x131, 0x404: 0x132, 0x405: 0x133, 0x406: 0x134, 0x407: 0x135,
- 0x408: 0x136, 0x409: 0xfb, 0x40a: 0x137, 0x40b: 0x138, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xfb, 0x40f: 0xfb,
- 0x410: 0x139, 0x411: 0x13a, 0x412: 0x13b, 0x413: 0x13c, 0x414: 0xfb, 0x415: 0xfb, 0x416: 0x13d, 0x417: 0x13e,
- 0x418: 0x13f, 0x419: 0x140, 0x41a: 0x141, 0x41b: 0x142, 0x41c: 0x143, 0x41d: 0xfb, 0x41e: 0xfb, 0x41f: 0xfb,
- 0x420: 0x144, 0x421: 0xfb, 0x422: 0x145, 0x423: 0x146, 0x424: 0x5f, 0x425: 0x147, 0x426: 0x148, 0x427: 0x149,
- 0x428: 0x14a, 0x429: 0x14b, 0x42a: 0x14c, 0x42b: 0x14d, 0x42c: 0xfb, 0x42d: 0xfb, 0x42e: 0xfb, 0x42f: 0xfb,
- 0x430: 0x14e, 0x431: 0x14f, 0x432: 0x150, 0x433: 0xfb, 0x434: 0x151, 0x435: 0x152, 0x436: 0x153, 0x437: 0xfb,
- 0x438: 0xfb, 0x439: 0xfb, 0x43a: 0xfb, 0x43b: 0x154, 0x43c: 0xfb, 0x43d: 0xfb, 0x43e: 0x155, 0x43f: 0x156,
- // Block 0x11, offset 0x440
- 0x440: 0xa0, 0x441: 0xa0, 0x442: 0xa0, 0x443: 0xa0, 0x444: 0xa0, 0x445: 0xa0, 0x446: 0xa0, 0x447: 0xa0,
- 0x448: 0xa0, 0x449: 0xa0, 0x44a: 0xa0, 0x44b: 0xa0, 0x44c: 0xa0, 0x44d: 0xa0, 0x44e: 0x157, 0x44f: 0xfb,
- 0x450: 0x9c, 0x451: 0x158, 0x452: 0xa0, 0x453: 0xa0, 0x454: 0xa0, 0x455: 0x159, 0x456: 0xfb, 0x457: 0xfb,
- 0x458: 0xfb, 0x459: 0xfb, 0x45a: 0xfb, 0x45b: 0xfb, 0x45c: 0xfb, 0x45d: 0xfb, 0x45e: 0xfb, 0x45f: 0xfb,
- 0x460: 0xfb, 0x461: 0xfb, 0x462: 0xfb, 0x463: 0xfb, 0x464: 0xfb, 0x465: 0xfb, 0x466: 0xfb, 0x467: 0xfb,
- 0x468: 0xfb, 0x469: 0xfb, 0x46a: 0xfb, 0x46b: 0xfb, 0x46c: 0xfb, 0x46d: 0xfb, 0x46e: 0xfb, 0x46f: 0xfb,
- 0x470: 0xfb, 0x471: 0xfb, 0x472: 0xfb, 0x473: 0xfb, 0x474: 0xfb, 0x475: 0xfb, 0x476: 0xfb, 0x477: 0xfb,
- 0x478: 0xfb, 0x479: 0xfb, 0x47a: 0xfb, 0x47b: 0xfb, 0x47c: 0xfb, 0x47d: 0xfb, 0x47e: 0xfb, 0x47f: 0xfb,
- // Block 0x12, offset 0x480
- 0x480: 0xa0, 0x481: 0xa0, 0x482: 0xa0, 0x483: 0xa0, 0x484: 0xa0, 0x485: 0xa0, 0x486: 0xa0, 0x487: 0xa0,
- 0x488: 0xa0, 0x489: 0xa0, 0x48a: 0xa0, 0x48b: 0xa0, 0x48c: 0xa0, 0x48d: 0xa0, 0x48e: 0xa0, 0x48f: 0xa0,
- 0x490: 0x15a, 0x491: 0xfb, 0x492: 0xfb, 0x493: 0xfb, 0x494: 0xfb, 0x495: 0xfb, 0x496: 0xfb, 0x497: 0xfb,
- 0x498: 0xfb, 0x499: 0xfb, 0x49a: 0xfb, 0x49b: 0xfb, 0x49c: 0xfb, 0x49d: 0xfb, 0x49e: 0xfb, 0x49f: 0xfb,
- 0x4a0: 0xfb, 0x4a1: 0xfb, 0x4a2: 0xfb, 0x4a3: 0xfb, 0x4a4: 0xfb, 0x4a5: 0xfb, 0x4a6: 0xfb, 0x4a7: 0xfb,
- 0x4a8: 0xfb, 0x4a9: 0xfb, 0x4aa: 0xfb, 0x4ab: 0xfb, 0x4ac: 0xfb, 0x4ad: 0xfb, 0x4ae: 0xfb, 0x4af: 0xfb,
- 0x4b0: 0xfb, 0x4b1: 0xfb, 0x4b2: 0xfb, 0x4b3: 0xfb, 0x4b4: 0xfb, 0x4b5: 0xfb, 0x4b6: 0xfb, 0x4b7: 0xfb,
- 0x4b8: 0xfb, 0x4b9: 0xfb, 0x4ba: 0xfb, 0x4bb: 0xfb, 0x4bc: 0xfb, 0x4bd: 0xfb, 0x4be: 0xfb, 0x4bf: 0xfb,
- // Block 0x13, offset 0x4c0
- 0x4c0: 0xfb, 0x4c1: 0xfb, 0x4c2: 0xfb, 0x4c3: 0xfb, 0x4c4: 0xfb, 0x4c5: 0xfb, 0x4c6: 0xfb, 0x4c7: 0xfb,
- 0x4c8: 0xfb, 0x4c9: 0xfb, 0x4ca: 0xfb, 0x4cb: 0xfb, 0x4cc: 0xfb, 0x4cd: 0xfb, 0x4ce: 0xfb, 0x4cf: 0xfb,
- 0x4d0: 0xa0, 0x4d1: 0xa0, 0x4d2: 0xa0, 0x4d3: 0xa0, 0x4d4: 0xa0, 0x4d5: 0xa0, 0x4d6: 0xa0, 0x4d7: 0xa0,
- 0x4d8: 0xa0, 0x4d9: 0x15b, 0x4da: 0xfb, 0x4db: 0xfb, 0x4dc: 0xfb, 0x4dd: 0xfb, 0x4de: 0xfb, 0x4df: 0xfb,
- 0x4e0: 0xfb, 0x4e1: 0xfb, 0x4e2: 0xfb, 0x4e3: 0xfb, 0x4e4: 0xfb, 0x4e5: 0xfb, 0x4e6: 0xfb, 0x4e7: 0xfb,
- 0x4e8: 0xfb, 0x4e9: 0xfb, 0x4ea: 0xfb, 0x4eb: 0xfb, 0x4ec: 0xfb, 0x4ed: 0xfb, 0x4ee: 0xfb, 0x4ef: 0xfb,
- 0x4f0: 0xfb, 0x4f1: 0xfb, 0x4f2: 0xfb, 0x4f3: 0xfb, 0x4f4: 0xfb, 0x4f5: 0xfb, 0x4f6: 0xfb, 0x4f7: 0xfb,
- 0x4f8: 0xfb, 0x4f9: 0xfb, 0x4fa: 0xfb, 0x4fb: 0xfb, 0x4fc: 0xfb, 0x4fd: 0xfb, 0x4fe: 0xfb, 0x4ff: 0xfb,
- // Block 0x14, offset 0x500
- 0x500: 0xfb, 0x501: 0xfb, 0x502: 0xfb, 0x503: 0xfb, 0x504: 0xfb, 0x505: 0xfb, 0x506: 0xfb, 0x507: 0xfb,
- 0x508: 0xfb, 0x509: 0xfb, 0x50a: 0xfb, 0x50b: 0xfb, 0x50c: 0xfb, 0x50d: 0xfb, 0x50e: 0xfb, 0x50f: 0xfb,
- 0x510: 0xfb, 0x511: 0xfb, 0x512: 0xfb, 0x513: 0xfb, 0x514: 0xfb, 0x515: 0xfb, 0x516: 0xfb, 0x517: 0xfb,
- 0x518: 0xfb, 0x519: 0xfb, 0x51a: 0xfb, 0x51b: 0xfb, 0x51c: 0xfb, 0x51d: 0xfb, 0x51e: 0xfb, 0x51f: 0xfb,
- 0x520: 0xa0, 0x521: 0xa0, 0x522: 0xa0, 0x523: 0xa0, 0x524: 0xa0, 0x525: 0xa0, 0x526: 0xa0, 0x527: 0xa0,
- 0x528: 0x14d, 0x529: 0x15c, 0x52a: 0xfb, 0x52b: 0x15d, 0x52c: 0x15e, 0x52d: 0x15f, 0x52e: 0x160, 0x52f: 0xfb,
- 0x530: 0xfb, 0x531: 0xfb, 0x532: 0xfb, 0x533: 0xfb, 0x534: 0xfb, 0x535: 0xfb, 0x536: 0xfb, 0x537: 0xfb,
- 0x538: 0xfb, 0x539: 0x161, 0x53a: 0x162, 0x53b: 0xfb, 0x53c: 0xa0, 0x53d: 0x163, 0x53e: 0x164, 0x53f: 0x165,
- // Block 0x15, offset 0x540
- 0x540: 0xa0, 0x541: 0xa0, 0x542: 0xa0, 0x543: 0xa0, 0x544: 0xa0, 0x545: 0xa0, 0x546: 0xa0, 0x547: 0xa0,
- 0x548: 0xa0, 0x549: 0xa0, 0x54a: 0xa0, 0x54b: 0xa0, 0x54c: 0xa0, 0x54d: 0xa0, 0x54e: 0xa0, 0x54f: 0xa0,
- 0x550: 0xa0, 0x551: 0xa0, 0x552: 0xa0, 0x553: 0xa0, 0x554: 0xa0, 0x555: 0xa0, 0x556: 0xa0, 0x557: 0xa0,
- 0x558: 0xa0, 0x559: 0xa0, 0x55a: 0xa0, 0x55b: 0xa0, 0x55c: 0xa0, 0x55d: 0xa0, 0x55e: 0xa0, 0x55f: 0x166,
- 0x560: 0xa0, 0x561: 0xa0, 0x562: 0xa0, 0x563: 0xa0, 0x564: 0xa0, 0x565: 0xa0, 0x566: 0xa0, 0x567: 0xa0,
- 0x568: 0xa0, 0x569: 0xa0, 0x56a: 0xa0, 0x56b: 0xa0, 0x56c: 0xa0, 0x56d: 0xa0, 0x56e: 0xa0, 0x56f: 0xa0,
- 0x570: 0xa0, 0x571: 0xa0, 0x572: 0xa0, 0x573: 0x167, 0x574: 0x168, 0x575: 0xfb, 0x576: 0xfb, 0x577: 0xfb,
- 0x578: 0xfb, 0x579: 0xfb, 0x57a: 0xfb, 0x57b: 0xfb, 0x57c: 0xfb, 0x57d: 0xfb, 0x57e: 0xfb, 0x57f: 0xfb,
- // Block 0x16, offset 0x580
- 0x580: 0xa0, 0x581: 0xa0, 0x582: 0xa0, 0x583: 0xa0, 0x584: 0x169, 0x585: 0x16a, 0x586: 0xa0, 0x587: 0xa0,
- 0x588: 0xa0, 0x589: 0xa0, 0x58a: 0xa0, 0x58b: 0x16b, 0x58c: 0xfb, 0x58d: 0xfb, 0x58e: 0xfb, 0x58f: 0xfb,
- 0x590: 0xfb, 0x591: 0xfb, 0x592: 0xfb, 0x593: 0xfb, 0x594: 0xfb, 0x595: 0xfb, 0x596: 0xfb, 0x597: 0xfb,
- 0x598: 0xfb, 0x599: 0xfb, 0x59a: 0xfb, 0x59b: 0xfb, 0x59c: 0xfb, 0x59d: 0xfb, 0x59e: 0xfb, 0x59f: 0xfb,
- 0x5a0: 0xfb, 0x5a1: 0xfb, 0x5a2: 0xfb, 0x5a3: 0xfb, 0x5a4: 0xfb, 0x5a5: 0xfb, 0x5a6: 0xfb, 0x5a7: 0xfb,
- 0x5a8: 0xfb, 0x5a9: 0xfb, 0x5aa: 0xfb, 0x5ab: 0xfb, 0x5ac: 0xfb, 0x5ad: 0xfb, 0x5ae: 0xfb, 0x5af: 0xfb,
- 0x5b0: 0xa0, 0x5b1: 0x16c, 0x5b2: 0x16d, 0x5b3: 0xfb, 0x5b4: 0xfb, 0x5b5: 0xfb, 0x5b6: 0xfb, 0x5b7: 0xfb,
- 0x5b8: 0xfb, 0x5b9: 0xfb, 0x5ba: 0xfb, 0x5bb: 0xfb, 0x5bc: 0xfb, 0x5bd: 0xfb, 0x5be: 0xfb, 0x5bf: 0xfb,
- // Block 0x17, offset 0x5c0
- 0x5c0: 0x9c, 0x5c1: 0x9c, 0x5c2: 0x9c, 0x5c3: 0x16e, 0x5c4: 0x16f, 0x5c5: 0x170, 0x5c6: 0x171, 0x5c7: 0x172,
- 0x5c8: 0x9c, 0x5c9: 0x173, 0x5ca: 0xfb, 0x5cb: 0x174, 0x5cc: 0x9c, 0x5cd: 0x175, 0x5ce: 0xfb, 0x5cf: 0xfb,
- 0x5d0: 0x60, 0x5d1: 0x61, 0x5d2: 0x62, 0x5d3: 0x63, 0x5d4: 0x64, 0x5d5: 0x65, 0x5d6: 0x66, 0x5d7: 0x67,
- 0x5d8: 0x68, 0x5d9: 0x69, 0x5da: 0x6a, 0x5db: 0x6b, 0x5dc: 0x6c, 0x5dd: 0x6d, 0x5de: 0x6e, 0x5df: 0x6f,
- 0x5e0: 0x9c, 0x5e1: 0x9c, 0x5e2: 0x9c, 0x5e3: 0x9c, 0x5e4: 0x9c, 0x5e5: 0x9c, 0x5e6: 0x9c, 0x5e7: 0x9c,
- 0x5e8: 0x176, 0x5e9: 0x177, 0x5ea: 0x178, 0x5eb: 0xfb, 0x5ec: 0xfb, 0x5ed: 0xfb, 0x5ee: 0xfb, 0x5ef: 0xfb,
- 0x5f0: 0xfb, 0x5f1: 0xfb, 0x5f2: 0xfb, 0x5f3: 0xfb, 0x5f4: 0xfb, 0x5f5: 0xfb, 0x5f6: 0xfb, 0x5f7: 0xfb,
- 0x5f8: 0xfb, 0x5f9: 0xfb, 0x5fa: 0xfb, 0x5fb: 0xfb, 0x5fc: 0xfb, 0x5fd: 0xfb, 0x5fe: 0xfb, 0x5ff: 0xfb,
- // Block 0x18, offset 0x600
- 0x600: 0x179, 0x601: 0xfb, 0x602: 0xfb, 0x603: 0xfb, 0x604: 0x17a, 0x605: 0x17b, 0x606: 0xfb, 0x607: 0xfb,
- 0x608: 0xfb, 0x609: 0xfb, 0x60a: 0xfb, 0x60b: 0x17c, 0x60c: 0xfb, 0x60d: 0xfb, 0x60e: 0xfb, 0x60f: 0xfb,
- 0x610: 0xfb, 0x611: 0xfb, 0x612: 0xfb, 0x613: 0xfb, 0x614: 0xfb, 0x615: 0xfb, 0x616: 0xfb, 0x617: 0xfb,
- 0x618: 0xfb, 0x619: 0xfb, 0x61a: 0xfb, 0x61b: 0xfb, 0x61c: 0xfb, 0x61d: 0xfb, 0x61e: 0xfb, 0x61f: 0xfb,
- 0x620: 0x123, 0x621: 0x123, 0x622: 0x123, 0x623: 0x17d, 0x624: 0x70, 0x625: 0x17e, 0x626: 0xfb, 0x627: 0xfb,
- 0x628: 0xfb, 0x629: 0xfb, 0x62a: 0xfb, 0x62b: 0xfb, 0x62c: 0xfb, 0x62d: 0xfb, 0x62e: 0xfb, 0x62f: 0xfb,
- 0x630: 0xfb, 0x631: 0x17f, 0x632: 0x180, 0x633: 0xfb, 0x634: 0x181, 0x635: 0xfb, 0x636: 0xfb, 0x637: 0xfb,
- 0x638: 0x71, 0x639: 0x72, 0x63a: 0x73, 0x63b: 0x182, 0x63c: 0xfb, 0x63d: 0xfb, 0x63e: 0xfb, 0x63f: 0xfb,
- // Block 0x19, offset 0x640
- 0x640: 0x183, 0x641: 0x9c, 0x642: 0x184, 0x643: 0x185, 0x644: 0x74, 0x645: 0x75, 0x646: 0x186, 0x647: 0x187,
- 0x648: 0x76, 0x649: 0x188, 0x64a: 0xfb, 0x64b: 0xfb, 0x64c: 0x9c, 0x64d: 0x9c, 0x64e: 0x9c, 0x64f: 0x9c,
- 0x650: 0x9c, 0x651: 0x9c, 0x652: 0x9c, 0x653: 0x9c, 0x654: 0x9c, 0x655: 0x9c, 0x656: 0x9c, 0x657: 0x9c,
- 0x658: 0x9c, 0x659: 0x9c, 0x65a: 0x9c, 0x65b: 0x189, 0x65c: 0x9c, 0x65d: 0x18a, 0x65e: 0x9c, 0x65f: 0x18b,
- 0x660: 0x18c, 0x661: 0x18d, 0x662: 0x18e, 0x663: 0xfb, 0x664: 0x9c, 0x665: 0x18f, 0x666: 0x9c, 0x667: 0x190,
- 0x668: 0x9c, 0x669: 0x191, 0x66a: 0x192, 0x66b: 0x193, 0x66c: 0x9c, 0x66d: 0x9c, 0x66e: 0x194, 0x66f: 0x195,
- 0x670: 0xfb, 0x671: 0xfb, 0x672: 0xfb, 0x673: 0xfb, 0x674: 0xfb, 0x675: 0xfb, 0x676: 0xfb, 0x677: 0xfb,
- 0x678: 0xfb, 0x679: 0xfb, 0x67a: 0xfb, 0x67b: 0xfb, 0x67c: 0xfb, 0x67d: 0xfb, 0x67e: 0xfb, 0x67f: 0xfb,
- // Block 0x1a, offset 0x680
- 0x680: 0xa0, 0x681: 0xa0, 0x682: 0xa0, 0x683: 0xa0, 0x684: 0xa0, 0x685: 0xa0, 0x686: 0xa0, 0x687: 0xa0,
- 0x688: 0xa0, 0x689: 0xa0, 0x68a: 0xa0, 0x68b: 0xa0, 0x68c: 0xa0, 0x68d: 0xa0, 0x68e: 0xa0, 0x68f: 0xa0,
- 0x690: 0xa0, 0x691: 0xa0, 0x692: 0xa0, 0x693: 0xa0, 0x694: 0xa0, 0x695: 0xa0, 0x696: 0xa0, 0x697: 0xa0,
- 0x698: 0xa0, 0x699: 0xa0, 0x69a: 0xa0, 0x69b: 0x196, 0x69c: 0xa0, 0x69d: 0xa0, 0x69e: 0xa0, 0x69f: 0xa0,
- 0x6a0: 0xa0, 0x6a1: 0xa0, 0x6a2: 0xa0, 0x6a3: 0xa0, 0x6a4: 0xa0, 0x6a5: 0xa0, 0x6a6: 0xa0, 0x6a7: 0xa0,
- 0x6a8: 0xa0, 0x6a9: 0xa0, 0x6aa: 0xa0, 0x6ab: 0xa0, 0x6ac: 0xa0, 0x6ad: 0xa0, 0x6ae: 0xa0, 0x6af: 0xa0,
- 0x6b0: 0xa0, 0x6b1: 0xa0, 0x6b2: 0xa0, 0x6b3: 0xa0, 0x6b4: 0xa0, 0x6b5: 0xa0, 0x6b6: 0xa0, 0x6b7: 0xa0,
- 0x6b8: 0xa0, 0x6b9: 0xa0, 0x6ba: 0xa0, 0x6bb: 0xa0, 0x6bc: 0xa0, 0x6bd: 0xa0, 0x6be: 0xa0, 0x6bf: 0xa0,
- // Block 0x1b, offset 0x6c0
- 0x6c0: 0xa0, 0x6c1: 0xa0, 0x6c2: 0xa0, 0x6c3: 0xa0, 0x6c4: 0xa0, 0x6c5: 0xa0, 0x6c6: 0xa0, 0x6c7: 0xa0,
- 0x6c8: 0xa0, 0x6c9: 0xa0, 0x6ca: 0xa0, 0x6cb: 0xa0, 0x6cc: 0xa0, 0x6cd: 0xa0, 0x6ce: 0xa0, 0x6cf: 0xa0,
- 0x6d0: 0xa0, 0x6d1: 0xa0, 0x6d2: 0xa0, 0x6d3: 0xa0, 0x6d4: 0xa0, 0x6d5: 0xa0, 0x6d6: 0xa0, 0x6d7: 0xa0,
- 0x6d8: 0xa0, 0x6d9: 0xa0, 0x6da: 0xa0, 0x6db: 0xa0, 0x6dc: 0x197, 0x6dd: 0xa0, 0x6de: 0xa0, 0x6df: 0xa0,
- 0x6e0: 0x198, 0x6e1: 0xa0, 0x6e2: 0xa0, 0x6e3: 0xa0, 0x6e4: 0xa0, 0x6e5: 0xa0, 0x6e6: 0xa0, 0x6e7: 0xa0,
- 0x6e8: 0xa0, 0x6e9: 0xa0, 0x6ea: 0xa0, 0x6eb: 0xa0, 0x6ec: 0xa0, 0x6ed: 0xa0, 0x6ee: 0xa0, 0x6ef: 0xa0,
- 0x6f0: 0xa0, 0x6f1: 0xa0, 0x6f2: 0xa0, 0x6f3: 0xa0, 0x6f4: 0xa0, 0x6f5: 0xa0, 0x6f6: 0xa0, 0x6f7: 0xa0,
- 0x6f8: 0xa0, 0x6f9: 0xa0, 0x6fa: 0xa0, 0x6fb: 0xa0, 0x6fc: 0xa0, 0x6fd: 0xa0, 0x6fe: 0xa0, 0x6ff: 0xa0,
- // Block 0x1c, offset 0x700
- 0x700: 0xa0, 0x701: 0xa0, 0x702: 0xa0, 0x703: 0xa0, 0x704: 0xa0, 0x705: 0xa0, 0x706: 0xa0, 0x707: 0xa0,
- 0x708: 0xa0, 0x709: 0xa0, 0x70a: 0xa0, 0x70b: 0xa0, 0x70c: 0xa0, 0x70d: 0xa0, 0x70e: 0xa0, 0x70f: 0xa0,
- 0x710: 0xa0, 0x711: 0xa0, 0x712: 0xa0, 0x713: 0xa0, 0x714: 0xa0, 0x715: 0xa0, 0x716: 0xa0, 0x717: 0xa0,
- 0x718: 0xa0, 0x719: 0xa0, 0x71a: 0xa0, 0x71b: 0xa0, 0x71c: 0xa0, 0x71d: 0xa0, 0x71e: 0xa0, 0x71f: 0xa0,
- 0x720: 0xa0, 0x721: 0xa0, 0x722: 0xa0, 0x723: 0xa0, 0x724: 0xa0, 0x725: 0xa0, 0x726: 0xa0, 0x727: 0xa0,
- 0x728: 0xa0, 0x729: 0xa0, 0x72a: 0xa0, 0x72b: 0xa0, 0x72c: 0xa0, 0x72d: 0xa0, 0x72e: 0xa0, 0x72f: 0xa0,
- 0x730: 0xa0, 0x731: 0xa0, 0x732: 0xa0, 0x733: 0xa0, 0x734: 0xa0, 0x735: 0xa0, 0x736: 0xa0, 0x737: 0xa0,
- 0x738: 0xa0, 0x739: 0xa0, 0x73a: 0x199, 0x73b: 0xa0, 0x73c: 0xa0, 0x73d: 0xa0, 0x73e: 0xa0, 0x73f: 0xa0,
- // Block 0x1d, offset 0x740
- 0x740: 0xa0, 0x741: 0xa0, 0x742: 0xa0, 0x743: 0xa0, 0x744: 0xa0, 0x745: 0xa0, 0x746: 0xa0, 0x747: 0xa0,
- 0x748: 0xa0, 0x749: 0xa0, 0x74a: 0xa0, 0x74b: 0xa0, 0x74c: 0xa0, 0x74d: 0xa0, 0x74e: 0xa0, 0x74f: 0xa0,
- 0x750: 0xa0, 0x751: 0xa0, 0x752: 0xa0, 0x753: 0xa0, 0x754: 0xa0, 0x755: 0xa0, 0x756: 0xa0, 0x757: 0xa0,
- 0x758: 0xa0, 0x759: 0xa0, 0x75a: 0xa0, 0x75b: 0xa0, 0x75c: 0xa0, 0x75d: 0xa0, 0x75e: 0xa0, 0x75f: 0xa0,
- 0x760: 0xa0, 0x761: 0xa0, 0x762: 0xa0, 0x763: 0xa0, 0x764: 0xa0, 0x765: 0xa0, 0x766: 0xa0, 0x767: 0xa0,
- 0x768: 0xa0, 0x769: 0xa0, 0x76a: 0xa0, 0x76b: 0xa0, 0x76c: 0xa0, 0x76d: 0xa0, 0x76e: 0xa0, 0x76f: 0x19a,
- 0x770: 0xfb, 0x771: 0xfb, 0x772: 0xfb, 0x773: 0xfb, 0x774: 0xfb, 0x775: 0xfb, 0x776: 0xfb, 0x777: 0xfb,
- 0x778: 0xfb, 0x779: 0xfb, 0x77a: 0xfb, 0x77b: 0xfb, 0x77c: 0xfb, 0x77d: 0xfb, 0x77e: 0xfb, 0x77f: 0xfb,
- // Block 0x1e, offset 0x780
- 0x780: 0xfb, 0x781: 0xfb, 0x782: 0xfb, 0x783: 0xfb, 0x784: 0xfb, 0x785: 0xfb, 0x786: 0xfb, 0x787: 0xfb,
- 0x788: 0xfb, 0x789: 0xfb, 0x78a: 0xfb, 0x78b: 0xfb, 0x78c: 0xfb, 0x78d: 0xfb, 0x78e: 0xfb, 0x78f: 0xfb,
- 0x790: 0xfb, 0x791: 0xfb, 0x792: 0xfb, 0x793: 0xfb, 0x794: 0xfb, 0x795: 0xfb, 0x796: 0xfb, 0x797: 0xfb,
- 0x798: 0xfb, 0x799: 0xfb, 0x79a: 0xfb, 0x79b: 0xfb, 0x79c: 0xfb, 0x79d: 0xfb, 0x79e: 0xfb, 0x79f: 0xfb,
- 0x7a0: 0x77, 0x7a1: 0x78, 0x7a2: 0x79, 0x7a3: 0x19b, 0x7a4: 0x7a, 0x7a5: 0x7b, 0x7a6: 0x19c, 0x7a7: 0x7c,
- 0x7a8: 0x7d, 0x7a9: 0xfb, 0x7aa: 0xfb, 0x7ab: 0xfb, 0x7ac: 0xfb, 0x7ad: 0xfb, 0x7ae: 0xfb, 0x7af: 0xfb,
- 0x7b0: 0xfb, 0x7b1: 0xfb, 0x7b2: 0xfb, 0x7b3: 0xfb, 0x7b4: 0xfb, 0x7b5: 0xfb, 0x7b6: 0xfb, 0x7b7: 0xfb,
- 0x7b8: 0xfb, 0x7b9: 0xfb, 0x7ba: 0xfb, 0x7bb: 0xfb, 0x7bc: 0xfb, 0x7bd: 0xfb, 0x7be: 0xfb, 0x7bf: 0xfb,
- // Block 0x1f, offset 0x7c0
- 0x7c0: 0xa0, 0x7c1: 0xa0, 0x7c2: 0xa0, 0x7c3: 0xa0, 0x7c4: 0xa0, 0x7c5: 0xa0, 0x7c6: 0xa0, 0x7c7: 0xa0,
- 0x7c8: 0xa0, 0x7c9: 0xa0, 0x7ca: 0xa0, 0x7cb: 0xa0, 0x7cc: 0xa0, 0x7cd: 0x19d, 0x7ce: 0xfb, 0x7cf: 0xfb,
- 0x7d0: 0xfb, 0x7d1: 0xfb, 0x7d2: 0xfb, 0x7d3: 0xfb, 0x7d4: 0xfb, 0x7d5: 0xfb, 0x7d6: 0xfb, 0x7d7: 0xfb,
- 0x7d8: 0xfb, 0x7d9: 0xfb, 0x7da: 0xfb, 0x7db: 0xfb, 0x7dc: 0xfb, 0x7dd: 0xfb, 0x7de: 0xfb, 0x7df: 0xfb,
- 0x7e0: 0xfb, 0x7e1: 0xfb, 0x7e2: 0xfb, 0x7e3: 0xfb, 0x7e4: 0xfb, 0x7e5: 0xfb, 0x7e6: 0xfb, 0x7e7: 0xfb,
- 0x7e8: 0xfb, 0x7e9: 0xfb, 0x7ea: 0xfb, 0x7eb: 0xfb, 0x7ec: 0xfb, 0x7ed: 0xfb, 0x7ee: 0xfb, 0x7ef: 0xfb,
- 0x7f0: 0xfb, 0x7f1: 0xfb, 0x7f2: 0xfb, 0x7f3: 0xfb, 0x7f4: 0xfb, 0x7f5: 0xfb, 0x7f6: 0xfb, 0x7f7: 0xfb,
- 0x7f8: 0xfb, 0x7f9: 0xfb, 0x7fa: 0xfb, 0x7fb: 0xfb, 0x7fc: 0xfb, 0x7fd: 0xfb, 0x7fe: 0xfb, 0x7ff: 0xfb,
- // Block 0x20, offset 0x800
- 0x810: 0x0d, 0x811: 0x0e, 0x812: 0x0f, 0x813: 0x10, 0x814: 0x11, 0x815: 0x0b, 0x816: 0x12, 0x817: 0x07,
- 0x818: 0x13, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x14, 0x81c: 0x0b, 0x81d: 0x15, 0x81e: 0x16, 0x81f: 0x17,
- 0x820: 0x07, 0x821: 0x07, 0x822: 0x07, 0x823: 0x07, 0x824: 0x07, 0x825: 0x07, 0x826: 0x07, 0x827: 0x07,
- 0x828: 0x07, 0x829: 0x07, 0x82a: 0x18, 0x82b: 0x19, 0x82c: 0x1a, 0x82d: 0x07, 0x82e: 0x1b, 0x82f: 0x1c,
- 0x830: 0x07, 0x831: 0x1d, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b,
- 0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b,
- // Block 0x21, offset 0x840
- 0x840: 0x0b, 0x841: 0x0b, 0x842: 0x0b, 0x843: 0x0b, 0x844: 0x0b, 0x845: 0x0b, 0x846: 0x0b, 0x847: 0x0b,
- 0x848: 0x0b, 0x849: 0x0b, 0x84a: 0x0b, 0x84b: 0x0b, 0x84c: 0x0b, 0x84d: 0x0b, 0x84e: 0x0b, 0x84f: 0x0b,
- 0x850: 0x0b, 0x851: 0x0b, 0x852: 0x0b, 0x853: 0x0b, 0x854: 0x0b, 0x855: 0x0b, 0x856: 0x0b, 0x857: 0x0b,
- 0x858: 0x0b, 0x859: 0x0b, 0x85a: 0x0b, 0x85b: 0x0b, 0x85c: 0x0b, 0x85d: 0x0b, 0x85e: 0x0b, 0x85f: 0x0b,
- 0x860: 0x0b, 0x861: 0x0b, 0x862: 0x0b, 0x863: 0x0b, 0x864: 0x0b, 0x865: 0x0b, 0x866: 0x0b, 0x867: 0x0b,
- 0x868: 0x0b, 0x869: 0x0b, 0x86a: 0x0b, 0x86b: 0x0b, 0x86c: 0x0b, 0x86d: 0x0b, 0x86e: 0x0b, 0x86f: 0x0b,
- 0x870: 0x0b, 0x871: 0x0b, 0x872: 0x0b, 0x873: 0x0b, 0x874: 0x0b, 0x875: 0x0b, 0x876: 0x0b, 0x877: 0x0b,
- 0x878: 0x0b, 0x879: 0x0b, 0x87a: 0x0b, 0x87b: 0x0b, 0x87c: 0x0b, 0x87d: 0x0b, 0x87e: 0x0b, 0x87f: 0x0b,
- // Block 0x22, offset 0x880
- 0x880: 0x19e, 0x881: 0x19f, 0x882: 0xfb, 0x883: 0xfb, 0x884: 0x1a0, 0x885: 0x1a0, 0x886: 0x1a0, 0x887: 0x1a1,
- 0x888: 0xfb, 0x889: 0xfb, 0x88a: 0xfb, 0x88b: 0xfb, 0x88c: 0xfb, 0x88d: 0xfb, 0x88e: 0xfb, 0x88f: 0xfb,
- 0x890: 0xfb, 0x891: 0xfb, 0x892: 0xfb, 0x893: 0xfb, 0x894: 0xfb, 0x895: 0xfb, 0x896: 0xfb, 0x897: 0xfb,
- 0x898: 0xfb, 0x899: 0xfb, 0x89a: 0xfb, 0x89b: 0xfb, 0x89c: 0xfb, 0x89d: 0xfb, 0x89e: 0xfb, 0x89f: 0xfb,
- 0x8a0: 0xfb, 0x8a1: 0xfb, 0x8a2: 0xfb, 0x8a3: 0xfb, 0x8a4: 0xfb, 0x8a5: 0xfb, 0x8a6: 0xfb, 0x8a7: 0xfb,
- 0x8a8: 0xfb, 0x8a9: 0xfb, 0x8aa: 0xfb, 0x8ab: 0xfb, 0x8ac: 0xfb, 0x8ad: 0xfb, 0x8ae: 0xfb, 0x8af: 0xfb,
- 0x8b0: 0xfb, 0x8b1: 0xfb, 0x8b2: 0xfb, 0x8b3: 0xfb, 0x8b4: 0xfb, 0x8b5: 0xfb, 0x8b6: 0xfb, 0x8b7: 0xfb,
- 0x8b8: 0xfb, 0x8b9: 0xfb, 0x8ba: 0xfb, 0x8bb: 0xfb, 0x8bc: 0xfb, 0x8bd: 0xfb, 0x8be: 0xfb, 0x8bf: 0xfb,
- // Block 0x23, offset 0x8c0
- 0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b,
- 0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b,
- 0x8d0: 0x0b, 0x8d1: 0x0b, 0x8d2: 0x0b, 0x8d3: 0x0b, 0x8d4: 0x0b, 0x8d5: 0x0b, 0x8d6: 0x0b, 0x8d7: 0x0b,
- 0x8d8: 0x0b, 0x8d9: 0x0b, 0x8da: 0x0b, 0x8db: 0x0b, 0x8dc: 0x0b, 0x8dd: 0x0b, 0x8de: 0x0b, 0x8df: 0x0b,
- 0x8e0: 0x20, 0x8e1: 0x0b, 0x8e2: 0x0b, 0x8e3: 0x0b, 0x8e4: 0x0b, 0x8e5: 0x0b, 0x8e6: 0x0b, 0x8e7: 0x0b,
- 0x8e8: 0x0b, 0x8e9: 0x0b, 0x8ea: 0x0b, 0x8eb: 0x0b, 0x8ec: 0x0b, 0x8ed: 0x0b, 0x8ee: 0x0b, 0x8ef: 0x0b,
- 0x8f0: 0x0b, 0x8f1: 0x0b, 0x8f2: 0x0b, 0x8f3: 0x0b, 0x8f4: 0x0b, 0x8f5: 0x0b, 0x8f6: 0x0b, 0x8f7: 0x0b,
- 0x8f8: 0x0b, 0x8f9: 0x0b, 0x8fa: 0x0b, 0x8fb: 0x0b, 0x8fc: 0x0b, 0x8fd: 0x0b, 0x8fe: 0x0b, 0x8ff: 0x0b,
- // Block 0x24, offset 0x900
- 0x900: 0x0b, 0x901: 0x0b, 0x902: 0x0b, 0x903: 0x0b, 0x904: 0x0b, 0x905: 0x0b, 0x906: 0x0b, 0x907: 0x0b,
- 0x908: 0x0b, 0x909: 0x0b, 0x90a: 0x0b, 0x90b: 0x0b, 0x90c: 0x0b, 0x90d: 0x0b, 0x90e: 0x0b, 0x90f: 0x0b,
-}
-
-// idnaSparseOffset: 292 entries, 584 bytes
-var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x33, 0x3e, 0x4a, 0x4e, 0x5d, 0x62, 0x6c, 0x78, 0x85, 0x8b, 0x94, 0xa4, 0xb2, 0xbd, 0xca, 0xdb, 0xe5, 0xec, 0xf9, 0x10a, 0x111, 0x11c, 0x12b, 0x139, 0x143, 0x145, 0x14a, 0x14d, 0x150, 0x152, 0x15e, 0x169, 0x171, 0x177, 0x17d, 0x182, 0x187, 0x18a, 0x18e, 0x194, 0x199, 0x1a5, 0x1af, 0x1b5, 0x1c6, 0x1d0, 0x1d3, 0x1db, 0x1de, 0x1eb, 0x1f3, 0x1f7, 0x1fe, 0x206, 0x216, 0x222, 0x225, 0x22f, 0x23b, 0x247, 0x253, 0x25b, 0x260, 0x26d, 0x27e, 0x282, 0x28d, 0x291, 0x29a, 0x2a2, 0x2a8, 0x2ad, 0x2b0, 0x2b4, 0x2ba, 0x2be, 0x2c2, 0x2c6, 0x2cc, 0x2d4, 0x2db, 0x2e6, 0x2f0, 0x2f4, 0x2f7, 0x2fd, 0x301, 0x303, 0x306, 0x308, 0x30b, 0x315, 0x318, 0x327, 0x32b, 0x330, 0x333, 0x337, 0x33c, 0x341, 0x347, 0x358, 0x368, 0x36e, 0x372, 0x381, 0x386, 0x38e, 0x398, 0x3a3, 0x3ab, 0x3bc, 0x3c5, 0x3d5, 0x3e2, 0x3ee, 0x3f3, 0x400, 0x404, 0x409, 0x40b, 0x40d, 0x411, 0x413, 0x417, 0x420, 0x426, 0x42a, 0x43a, 0x444, 0x449, 0x44c, 0x452, 0x459, 0x45e, 0x462, 0x468, 0x46d, 0x476, 0x47b, 0x481, 0x488, 0x48f, 0x496, 0x49a, 0x49f, 0x4a2, 0x4a7, 0x4b3, 0x4b9, 0x4be, 0x4c5, 0x4cd, 0x4d2, 0x4d6, 0x4e6, 0x4ed, 0x4f1, 0x4f5, 0x4fc, 0x4fe, 0x501, 0x504, 0x508, 0x511, 0x515, 0x51d, 0x525, 0x52d, 0x539, 0x545, 0x54b, 0x554, 0x560, 0x567, 0x570, 0x57b, 0x582, 0x591, 0x59e, 0x5ab, 0x5b4, 0x5b8, 0x5c7, 0x5cf, 0x5da, 0x5e3, 0x5e9, 0x5f1, 0x5fa, 0x605, 0x608, 0x614, 0x61d, 0x620, 0x625, 0x62e, 0x633, 0x640, 0x64b, 0x654, 0x65e, 0x661, 0x66b, 0x674, 0x680, 0x68d, 0x69a, 0x6a8, 0x6af, 0x6b3, 0x6b7, 0x6ba, 0x6bf, 0x6c2, 0x6c7, 0x6ca, 0x6d1, 0x6d8, 0x6dc, 0x6e7, 0x6ea, 0x6ed, 0x6f0, 0x6f6, 0x6fc, 0x705, 0x708, 0x70b, 0x70e, 0x711, 0x718, 0x71b, 0x720, 0x72a, 0x72d, 0x731, 0x740, 0x74c, 0x750, 0x755, 0x759, 0x75e, 0x762, 0x767, 0x770, 0x77b, 0x781, 0x787, 0x78d, 0x793, 0x79c, 0x79f, 0x7a2, 0x7a6, 0x7aa, 0x7ae, 0x7b4, 0x7ba, 0x7bf, 0x7c2, 0x7d2, 0x7d9, 0x7dc, 0x7e1, 0x7e5, 0x7eb, 0x7f2, 0x7f6, 0x7fa, 0x803, 0x80a, 0x80f, 0x813, 0x821, 0x824, 0x827, 0x82b, 0x82f, 0x832, 0x842, 0x853, 0x856, 0x85b, 0x85d, 0x85f}
-
-// idnaSparseValues: 2146 entries, 8584 bytes
-var idnaSparseValues = [2146]valueRange{
- // Block 0x0, offset 0x0
- {value: 0x0000, lo: 0x07},
- {value: 0xe105, lo: 0x80, hi: 0x96},
- {value: 0x0018, lo: 0x97, hi: 0x97},
- {value: 0xe105, lo: 0x98, hi: 0x9e},
- {value: 0x001f, lo: 0x9f, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xb7},
- {value: 0x0008, lo: 0xb8, hi: 0xbf},
- // Block 0x1, offset 0x8
- {value: 0x0000, lo: 0x10},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0xe01d, lo: 0x81, hi: 0x81},
- {value: 0x0008, lo: 0x82, hi: 0x82},
- {value: 0x0335, lo: 0x83, hi: 0x83},
- {value: 0x034d, lo: 0x84, hi: 0x84},
- {value: 0x0365, lo: 0x85, hi: 0x85},
- {value: 0xe00d, lo: 0x86, hi: 0x86},
- {value: 0x0008, lo: 0x87, hi: 0x87},
- {value: 0xe00d, lo: 0x88, hi: 0x88},
- {value: 0x0008, lo: 0x89, hi: 0x89},
- {value: 0xe00d, lo: 0x8a, hi: 0x8a},
- {value: 0x0008, lo: 0x8b, hi: 0x8b},
- {value: 0xe00d, lo: 0x8c, hi: 0x8c},
- {value: 0x0008, lo: 0x8d, hi: 0x8d},
- {value: 0xe00d, lo: 0x8e, hi: 0x8e},
- {value: 0x0008, lo: 0x8f, hi: 0xbf},
- // Block 0x2, offset 0x19
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0xaf},
- {value: 0x0249, lo: 0xb0, hi: 0xb0},
- {value: 0x037d, lo: 0xb1, hi: 0xb1},
- {value: 0x0259, lo: 0xb2, hi: 0xb2},
- {value: 0x0269, lo: 0xb3, hi: 0xb3},
- {value: 0x034d, lo: 0xb4, hi: 0xb4},
- {value: 0x0395, lo: 0xb5, hi: 0xb5},
- {value: 0xe1bd, lo: 0xb6, hi: 0xb6},
- {value: 0x0279, lo: 0xb7, hi: 0xb7},
- {value: 0x0289, lo: 0xb8, hi: 0xb8},
- {value: 0x0008, lo: 0xb9, hi: 0xbf},
- // Block 0x3, offset 0x25
- {value: 0x0000, lo: 0x01},
- {value: 0x3308, lo: 0x80, hi: 0xbf},
- // Block 0x4, offset 0x27
- {value: 0x0000, lo: 0x04},
- {value: 0x03f5, lo: 0x80, hi: 0x8f},
- {value: 0xe105, lo: 0x90, hi: 0x9f},
- {value: 0x049d, lo: 0xa0, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x5, offset 0x2c
- {value: 0x0000, lo: 0x06},
- {value: 0xe185, lo: 0x80, hi: 0x8f},
- {value: 0x0545, lo: 0x90, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x98},
- {value: 0x0008, lo: 0x99, hi: 0x99},
- {value: 0x0018, lo: 0x9a, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x6, offset 0x33
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x0401, lo: 0x87, hi: 0x87},
- {value: 0x0008, lo: 0x88, hi: 0x88},
- {value: 0x0018, lo: 0x89, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0x8c},
- {value: 0x0018, lo: 0x8d, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0x90},
- {value: 0x3308, lo: 0x91, hi: 0xbd},
- {value: 0x0818, lo: 0xbe, hi: 0xbe},
- {value: 0x3308, lo: 0xbf, hi: 0xbf},
- // Block 0x7, offset 0x3e
- {value: 0x0000, lo: 0x0b},
- {value: 0x0818, lo: 0x80, hi: 0x80},
- {value: 0x3308, lo: 0x81, hi: 0x82},
- {value: 0x0818, lo: 0x83, hi: 0x83},
- {value: 0x3308, lo: 0x84, hi: 0x85},
- {value: 0x0818, lo: 0x86, hi: 0x86},
- {value: 0x3308, lo: 0x87, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x0808, lo: 0x90, hi: 0xaa},
- {value: 0x0040, lo: 0xab, hi: 0xae},
- {value: 0x0808, lo: 0xaf, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0x8, offset 0x4a
- {value: 0x0000, lo: 0x03},
- {value: 0x0a08, lo: 0x80, hi: 0x87},
- {value: 0x0c08, lo: 0x88, hi: 0x99},
- {value: 0x0a08, lo: 0x9a, hi: 0xbf},
- // Block 0x9, offset 0x4e
- {value: 0x0000, lo: 0x0e},
- {value: 0x3308, lo: 0x80, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0x8c},
- {value: 0x0c08, lo: 0x8d, hi: 0x8d},
- {value: 0x0a08, lo: 0x8e, hi: 0x98},
- {value: 0x0c08, lo: 0x99, hi: 0x9b},
- {value: 0x0a08, lo: 0x9c, hi: 0xaa},
- {value: 0x0c08, lo: 0xab, hi: 0xac},
- {value: 0x0a08, lo: 0xad, hi: 0xb0},
- {value: 0x0c08, lo: 0xb1, hi: 0xb1},
- {value: 0x0a08, lo: 0xb2, hi: 0xb2},
- {value: 0x0c08, lo: 0xb3, hi: 0xb4},
- {value: 0x0a08, lo: 0xb5, hi: 0xb7},
- {value: 0x0c08, lo: 0xb8, hi: 0xb9},
- {value: 0x0a08, lo: 0xba, hi: 0xbf},
- // Block 0xa, offset 0x5d
- {value: 0x0000, lo: 0x04},
- {value: 0x0808, lo: 0x80, hi: 0xa5},
- {value: 0x3308, lo: 0xa6, hi: 0xb0},
- {value: 0x0808, lo: 0xb1, hi: 0xb1},
- {value: 0x0040, lo: 0xb2, hi: 0xbf},
- // Block 0xb, offset 0x62
- {value: 0x0000, lo: 0x09},
- {value: 0x0808, lo: 0x80, hi: 0x89},
- {value: 0x0a08, lo: 0x8a, hi: 0xaa},
- {value: 0x3308, lo: 0xab, hi: 0xb3},
- {value: 0x0808, lo: 0xb4, hi: 0xb5},
- {value: 0x0018, lo: 0xb6, hi: 0xb9},
- {value: 0x0818, lo: 0xba, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbc},
- {value: 0x3308, lo: 0xbd, hi: 0xbd},
- {value: 0x0818, lo: 0xbe, hi: 0xbf},
- // Block 0xc, offset 0x6c
- {value: 0x0000, lo: 0x0b},
- {value: 0x0808, lo: 0x80, hi: 0x95},
- {value: 0x3308, lo: 0x96, hi: 0x99},
- {value: 0x0808, lo: 0x9a, hi: 0x9a},
- {value: 0x3308, lo: 0x9b, hi: 0xa3},
- {value: 0x0808, lo: 0xa4, hi: 0xa4},
- {value: 0x3308, lo: 0xa5, hi: 0xa7},
- {value: 0x0808, lo: 0xa8, hi: 0xa8},
- {value: 0x3308, lo: 0xa9, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x0818, lo: 0xb0, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0xd, offset 0x78
- {value: 0x0000, lo: 0x0c},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x0a08, lo: 0xa0, hi: 0xa9},
- {value: 0x0c08, lo: 0xaa, hi: 0xac},
- {value: 0x0808, lo: 0xad, hi: 0xad},
- {value: 0x0c08, lo: 0xae, hi: 0xae},
- {value: 0x0a08, lo: 0xaf, hi: 0xb0},
- {value: 0x0c08, lo: 0xb1, hi: 0xb2},
- {value: 0x0a08, lo: 0xb3, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xb5},
- {value: 0x0a08, lo: 0xb6, hi: 0xb8},
- {value: 0x0c08, lo: 0xb9, hi: 0xb9},
- {value: 0x0a08, lo: 0xba, hi: 0xbf},
- // Block 0xe, offset 0x85
- {value: 0x0000, lo: 0x05},
- {value: 0x0a08, lo: 0x80, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x92},
- {value: 0x3308, lo: 0x93, hi: 0xa1},
- {value: 0x0840, lo: 0xa2, hi: 0xa2},
- {value: 0x3308, lo: 0xa3, hi: 0xbf},
- // Block 0xf, offset 0x8b
- {value: 0x0000, lo: 0x08},
- {value: 0x3308, lo: 0x80, hi: 0x82},
- {value: 0x3008, lo: 0x83, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0xb9},
- {value: 0x3308, lo: 0xba, hi: 0xba},
- {value: 0x3008, lo: 0xbb, hi: 0xbb},
- {value: 0x3308, lo: 0xbc, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbd},
- {value: 0x3008, lo: 0xbe, hi: 0xbf},
- // Block 0x10, offset 0x94
- {value: 0x0000, lo: 0x0f},
- {value: 0x3308, lo: 0x80, hi: 0x80},
- {value: 0x3008, lo: 0x81, hi: 0x82},
- {value: 0x0040, lo: 0x83, hi: 0x85},
- {value: 0x3008, lo: 0x86, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x3008, lo: 0x8a, hi: 0x8c},
- {value: 0x3b08, lo: 0x8d, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x90},
- {value: 0x0040, lo: 0x91, hi: 0x96},
- {value: 0x3008, lo: 0x97, hi: 0x97},
- {value: 0x0040, lo: 0x98, hi: 0xa5},
- {value: 0x0008, lo: 0xa6, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbf},
- // Block 0x11, offset 0xa4
- {value: 0x0000, lo: 0x0d},
- {value: 0x3308, lo: 0x80, hi: 0x80},
- {value: 0x3008, lo: 0x81, hi: 0x83},
- {value: 0x3308, lo: 0x84, hi: 0x84},
- {value: 0x0008, lo: 0x85, hi: 0x8c},
- {value: 0x0040, lo: 0x8d, hi: 0x8d},
- {value: 0x0008, lo: 0x8e, hi: 0x90},
- {value: 0x0040, lo: 0x91, hi: 0x91},
- {value: 0x0008, lo: 0x92, hi: 0xa8},
- {value: 0x0040, lo: 0xa9, hi: 0xa9},
- {value: 0x0008, lo: 0xaa, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbd},
- {value: 0x3308, lo: 0xbe, hi: 0xbf},
- // Block 0x12, offset 0xb2
- {value: 0x0000, lo: 0x0a},
- {value: 0x3308, lo: 0x80, hi: 0x81},
- {value: 0x3008, lo: 0x82, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0x8c},
- {value: 0x0040, lo: 0x8d, hi: 0x8d},
- {value: 0x0008, lo: 0x8e, hi: 0x90},
- {value: 0x0040, lo: 0x91, hi: 0x91},
- {value: 0x0008, lo: 0x92, hi: 0xba},
- {value: 0x3b08, lo: 0xbb, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbd},
- {value: 0x3008, lo: 0xbe, hi: 0xbf},
- // Block 0x13, offset 0xbd
- {value: 0x0000, lo: 0x0c},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x3308, lo: 0x81, hi: 0x81},
- {value: 0x3008, lo: 0x82, hi: 0x83},
- {value: 0x0040, lo: 0x84, hi: 0x84},
- {value: 0x0008, lo: 0x85, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x99},
- {value: 0x0008, lo: 0x9a, hi: 0xb1},
- {value: 0x0040, lo: 0xb2, hi: 0xb2},
- {value: 0x0008, lo: 0xb3, hi: 0xbb},
- {value: 0x0040, lo: 0xbc, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbf},
- // Block 0x14, offset 0xca
- {value: 0x0000, lo: 0x10},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x89},
- {value: 0x3b08, lo: 0x8a, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0x8e},
- {value: 0x3008, lo: 0x8f, hi: 0x91},
- {value: 0x3308, lo: 0x92, hi: 0x94},
- {value: 0x0040, lo: 0x95, hi: 0x95},
- {value: 0x3308, lo: 0x96, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x97},
- {value: 0x3008, lo: 0x98, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xa5},
- {value: 0x0008, lo: 0xa6, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xb1},
- {value: 0x3008, lo: 0xb2, hi: 0xb3},
- {value: 0x0018, lo: 0xb4, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0x15, offset 0xdb
- {value: 0x0000, lo: 0x09},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0xb0},
- {value: 0x3308, lo: 0xb1, hi: 0xb1},
- {value: 0x0008, lo: 0xb2, hi: 0xb2},
- {value: 0x08f1, lo: 0xb3, hi: 0xb3},
- {value: 0x3308, lo: 0xb4, hi: 0xb9},
- {value: 0x3b08, lo: 0xba, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbe},
- {value: 0x0018, lo: 0xbf, hi: 0xbf},
- // Block 0x16, offset 0xe5
- {value: 0x0000, lo: 0x06},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x3308, lo: 0x87, hi: 0x8e},
- {value: 0x0018, lo: 0x8f, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0018, lo: 0x9a, hi: 0x9b},
- {value: 0x0040, lo: 0x9c, hi: 0xbf},
- // Block 0x17, offset 0xec
- {value: 0x0000, lo: 0x0c},
- {value: 0x0008, lo: 0x80, hi: 0x84},
- {value: 0x0040, lo: 0x85, hi: 0x85},
- {value: 0x0008, lo: 0x86, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x87},
- {value: 0x3308, lo: 0x88, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9b},
- {value: 0x0961, lo: 0x9c, hi: 0x9c},
- {value: 0x0999, lo: 0x9d, hi: 0x9d},
- {value: 0x0008, lo: 0x9e, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xbf},
- // Block 0x18, offset 0xf9
- {value: 0x0000, lo: 0x10},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x8a},
- {value: 0x0008, lo: 0x8b, hi: 0x8b},
- {value: 0xe03d, lo: 0x8c, hi: 0x8c},
- {value: 0x0018, lo: 0x8d, hi: 0x97},
- {value: 0x3308, lo: 0x98, hi: 0x99},
- {value: 0x0018, lo: 0x9a, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa9},
- {value: 0x0018, lo: 0xaa, hi: 0xb4},
- {value: 0x3308, lo: 0xb5, hi: 0xb5},
- {value: 0x0018, lo: 0xb6, hi: 0xb6},
- {value: 0x3308, lo: 0xb7, hi: 0xb7},
- {value: 0x0018, lo: 0xb8, hi: 0xb8},
- {value: 0x3308, lo: 0xb9, hi: 0xb9},
- {value: 0x0018, lo: 0xba, hi: 0xbd},
- {value: 0x3008, lo: 0xbe, hi: 0xbf},
- // Block 0x19, offset 0x10a
- {value: 0x0000, lo: 0x06},
- {value: 0x0018, lo: 0x80, hi: 0x85},
- {value: 0x3308, lo: 0x86, hi: 0x86},
- {value: 0x0018, lo: 0x87, hi: 0x8c},
- {value: 0x0040, lo: 0x8d, hi: 0x8d},
- {value: 0x0018, lo: 0x8e, hi: 0x9a},
- {value: 0x0040, lo: 0x9b, hi: 0xbf},
- // Block 0x1a, offset 0x111
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0xaa},
- {value: 0x3008, lo: 0xab, hi: 0xac},
- {value: 0x3308, lo: 0xad, hi: 0xb0},
- {value: 0x3008, lo: 0xb1, hi: 0xb1},
- {value: 0x3308, lo: 0xb2, hi: 0xb7},
- {value: 0x3008, lo: 0xb8, hi: 0xb8},
- {value: 0x3b08, lo: 0xb9, hi: 0xba},
- {value: 0x3008, lo: 0xbb, hi: 0xbc},
- {value: 0x3308, lo: 0xbd, hi: 0xbe},
- {value: 0x0008, lo: 0xbf, hi: 0xbf},
- // Block 0x1b, offset 0x11c
- {value: 0x0000, lo: 0x0e},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x0018, lo: 0x8a, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x95},
- {value: 0x3008, lo: 0x96, hi: 0x97},
- {value: 0x3308, lo: 0x98, hi: 0x99},
- {value: 0x0008, lo: 0x9a, hi: 0x9d},
- {value: 0x3308, lo: 0x9e, hi: 0xa0},
- {value: 0x0008, lo: 0xa1, hi: 0xa1},
- {value: 0x3008, lo: 0xa2, hi: 0xa4},
- {value: 0x0008, lo: 0xa5, hi: 0xa6},
- {value: 0x3008, lo: 0xa7, hi: 0xad},
- {value: 0x0008, lo: 0xae, hi: 0xb0},
- {value: 0x3308, lo: 0xb1, hi: 0xb4},
- {value: 0x0008, lo: 0xb5, hi: 0xbf},
- // Block 0x1c, offset 0x12b
- {value: 0x0000, lo: 0x0d},
- {value: 0x0008, lo: 0x80, hi: 0x81},
- {value: 0x3308, lo: 0x82, hi: 0x82},
- {value: 0x3008, lo: 0x83, hi: 0x84},
- {value: 0x3308, lo: 0x85, hi: 0x86},
- {value: 0x3008, lo: 0x87, hi: 0x8c},
- {value: 0x3308, lo: 0x8d, hi: 0x8d},
- {value: 0x0008, lo: 0x8e, hi: 0x8e},
- {value: 0x3008, lo: 0x8f, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x3008, lo: 0x9a, hi: 0x9c},
- {value: 0x3308, lo: 0x9d, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xbf},
- // Block 0x1d, offset 0x139
- {value: 0x0000, lo: 0x09},
- {value: 0x0040, lo: 0x80, hi: 0x86},
- {value: 0x055d, lo: 0x87, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8c},
- {value: 0x055d, lo: 0x8d, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xba},
- {value: 0x0018, lo: 0xbb, hi: 0xbb},
- {value: 0xe105, lo: 0xbc, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbf},
- // Block 0x1e, offset 0x143
- {value: 0x0000, lo: 0x01},
- {value: 0x0018, lo: 0x80, hi: 0xbf},
- // Block 0x1f, offset 0x145
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0xa0},
- {value: 0x2018, lo: 0xa1, hi: 0xb5},
- {value: 0x0018, lo: 0xb6, hi: 0xbf},
- // Block 0x20, offset 0x14a
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0xa7},
- {value: 0x2018, lo: 0xa8, hi: 0xbf},
- // Block 0x21, offset 0x14d
- {value: 0x0000, lo: 0x02},
- {value: 0x2018, lo: 0x80, hi: 0x82},
- {value: 0x0018, lo: 0x83, hi: 0xbf},
- // Block 0x22, offset 0x150
- {value: 0x0000, lo: 0x01},
- {value: 0x0008, lo: 0x80, hi: 0xbf},
- // Block 0x23, offset 0x152
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x0008, lo: 0x8a, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0x98},
- {value: 0x0040, lo: 0x99, hi: 0x99},
- {value: 0x0008, lo: 0x9a, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x24, offset 0x15e
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x0008, lo: 0x8a, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xb0},
- {value: 0x0040, lo: 0xb1, hi: 0xb1},
- {value: 0x0008, lo: 0xb2, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xb7},
- {value: 0x0008, lo: 0xb8, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0x25, offset 0x169
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0x0040, lo: 0x81, hi: 0x81},
- {value: 0x0008, lo: 0x82, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0x87},
- {value: 0x0008, lo: 0x88, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0xbf},
- // Block 0x26, offset 0x171
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x90},
- {value: 0x0040, lo: 0x91, hi: 0x91},
- {value: 0x0008, lo: 0x92, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0xbf},
- // Block 0x27, offset 0x177
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x9a},
- {value: 0x0040, lo: 0x9b, hi: 0x9c},
- {value: 0x3308, lo: 0x9d, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbf},
- // Block 0x28, offset 0x17d
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x29, offset 0x182
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xb7},
- {value: 0xe045, lo: 0xb8, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbf},
- // Block 0x2a, offset 0x187
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0xbf},
- // Block 0x2b, offset 0x18a
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xac},
- {value: 0x0018, lo: 0xad, hi: 0xae},
- {value: 0x0008, lo: 0xaf, hi: 0xbf},
- // Block 0x2c, offset 0x18e
- {value: 0x0000, lo: 0x05},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0x9a},
- {value: 0x0018, lo: 0x9b, hi: 0x9c},
- {value: 0x0040, lo: 0x9d, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x2d, offset 0x194
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xaa},
- {value: 0x0018, lo: 0xab, hi: 0xb0},
- {value: 0x0008, lo: 0xb1, hi: 0xb8},
- {value: 0x0040, lo: 0xb9, hi: 0xbf},
- // Block 0x2e, offset 0x199
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x8c},
- {value: 0x0040, lo: 0x8d, hi: 0x8d},
- {value: 0x0008, lo: 0x8e, hi: 0x91},
- {value: 0x3308, lo: 0x92, hi: 0x93},
- {value: 0x3b08, lo: 0x94, hi: 0x94},
- {value: 0x0040, lo: 0x95, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xb1},
- {value: 0x3308, lo: 0xb2, hi: 0xb3},
- {value: 0x3b08, lo: 0xb4, hi: 0xb4},
- {value: 0x0018, lo: 0xb5, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0x2f, offset 0x1a5
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x91},
- {value: 0x3308, lo: 0x92, hi: 0x93},
- {value: 0x0040, lo: 0x94, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xac},
- {value: 0x0040, lo: 0xad, hi: 0xad},
- {value: 0x0008, lo: 0xae, hi: 0xb0},
- {value: 0x0040, lo: 0xb1, hi: 0xb1},
- {value: 0x3308, lo: 0xb2, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xbf},
- // Block 0x30, offset 0x1af
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0xb3},
- {value: 0x3340, lo: 0xb4, hi: 0xb5},
- {value: 0x3008, lo: 0xb6, hi: 0xb6},
- {value: 0x3308, lo: 0xb7, hi: 0xbd},
- {value: 0x3008, lo: 0xbe, hi: 0xbf},
- // Block 0x31, offset 0x1b5
- {value: 0x0000, lo: 0x10},
- {value: 0x3008, lo: 0x80, hi: 0x85},
- {value: 0x3308, lo: 0x86, hi: 0x86},
- {value: 0x3008, lo: 0x87, hi: 0x88},
- {value: 0x3308, lo: 0x89, hi: 0x91},
- {value: 0x3b08, lo: 0x92, hi: 0x92},
- {value: 0x3308, lo: 0x93, hi: 0x93},
- {value: 0x0018, lo: 0x94, hi: 0x96},
- {value: 0x0008, lo: 0x97, hi: 0x97},
- {value: 0x0018, lo: 0x98, hi: 0x9b},
- {value: 0x0008, lo: 0x9c, hi: 0x9c},
- {value: 0x3308, lo: 0x9d, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa9},
- {value: 0x0040, lo: 0xaa, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0x32, offset 0x1c6
- {value: 0x0000, lo: 0x09},
- {value: 0x0018, lo: 0x80, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0x86},
- {value: 0x0218, lo: 0x87, hi: 0x87},
- {value: 0x0018, lo: 0x88, hi: 0x8a},
- {value: 0x33c0, lo: 0x8b, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x0208, lo: 0xa0, hi: 0xbf},
- // Block 0x33, offset 0x1d0
- {value: 0x0000, lo: 0x02},
- {value: 0x0208, lo: 0x80, hi: 0xb8},
- {value: 0x0040, lo: 0xb9, hi: 0xbf},
- // Block 0x34, offset 0x1d3
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0x84},
- {value: 0x3308, lo: 0x85, hi: 0x86},
- {value: 0x0208, lo: 0x87, hi: 0xa8},
- {value: 0x3308, lo: 0xa9, hi: 0xa9},
- {value: 0x0208, lo: 0xaa, hi: 0xaa},
- {value: 0x0040, lo: 0xab, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x35, offset 0x1db
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xbf},
- // Block 0x36, offset 0x1de
- {value: 0x0000, lo: 0x0c},
- {value: 0x0008, lo: 0x80, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0x9f},
- {value: 0x3308, lo: 0xa0, hi: 0xa2},
- {value: 0x3008, lo: 0xa3, hi: 0xa6},
- {value: 0x3308, lo: 0xa7, hi: 0xa8},
- {value: 0x3008, lo: 0xa9, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xaf},
- {value: 0x3008, lo: 0xb0, hi: 0xb1},
- {value: 0x3308, lo: 0xb2, hi: 0xb2},
- {value: 0x3008, lo: 0xb3, hi: 0xb8},
- {value: 0x3308, lo: 0xb9, hi: 0xbb},
- {value: 0x0040, lo: 0xbc, hi: 0xbf},
- // Block 0x37, offset 0x1eb
- {value: 0x0000, lo: 0x07},
- {value: 0x0018, lo: 0x80, hi: 0x80},
- {value: 0x0040, lo: 0x81, hi: 0x83},
- {value: 0x0018, lo: 0x84, hi: 0x85},
- {value: 0x0008, lo: 0x86, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0x38, offset 0x1f3
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x39, offset 0x1f7
- {value: 0x0000, lo: 0x06},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x0040, lo: 0x8a, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0028, lo: 0x9a, hi: 0x9a},
- {value: 0x0040, lo: 0x9b, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0xbf},
- // Block 0x3a, offset 0x1fe
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0x96},
- {value: 0x3308, lo: 0x97, hi: 0x98},
- {value: 0x3008, lo: 0x99, hi: 0x9a},
- {value: 0x3308, lo: 0x9b, hi: 0x9b},
- {value: 0x0040, lo: 0x9c, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x3b, offset 0x206
- {value: 0x0000, lo: 0x0f},
- {value: 0x0008, lo: 0x80, hi: 0x94},
- {value: 0x3008, lo: 0x95, hi: 0x95},
- {value: 0x3308, lo: 0x96, hi: 0x96},
- {value: 0x3008, lo: 0x97, hi: 0x97},
- {value: 0x3308, lo: 0x98, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0x9f},
- {value: 0x3b08, lo: 0xa0, hi: 0xa0},
- {value: 0x3008, lo: 0xa1, hi: 0xa1},
- {value: 0x3308, lo: 0xa2, hi: 0xa2},
- {value: 0x3008, lo: 0xa3, hi: 0xa4},
- {value: 0x3308, lo: 0xa5, hi: 0xac},
- {value: 0x3008, lo: 0xad, hi: 0xb2},
- {value: 0x3308, lo: 0xb3, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbe},
- {value: 0x3308, lo: 0xbf, hi: 0xbf},
- // Block 0x3c, offset 0x216
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x0040, lo: 0x8a, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xa6},
- {value: 0x0008, lo: 0xa7, hi: 0xa7},
- {value: 0x0018, lo: 0xa8, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x3308, lo: 0xb0, hi: 0xbd},
- {value: 0x3318, lo: 0xbe, hi: 0xbe},
- {value: 0x3308, lo: 0xbf, hi: 0xbf},
- // Block 0x3d, offset 0x222
- {value: 0x0000, lo: 0x02},
- {value: 0x3308, lo: 0x80, hi: 0x80},
- {value: 0x0040, lo: 0x81, hi: 0xbf},
- // Block 0x3e, offset 0x225
- {value: 0x0000, lo: 0x09},
- {value: 0x3308, lo: 0x80, hi: 0x83},
- {value: 0x3008, lo: 0x84, hi: 0x84},
- {value: 0x0008, lo: 0x85, hi: 0xb3},
- {value: 0x3308, lo: 0xb4, hi: 0xb4},
- {value: 0x3008, lo: 0xb5, hi: 0xb5},
- {value: 0x3308, lo: 0xb6, hi: 0xba},
- {value: 0x3008, lo: 0xbb, hi: 0xbb},
- {value: 0x3308, lo: 0xbc, hi: 0xbc},
- {value: 0x3008, lo: 0xbd, hi: 0xbf},
- // Block 0x3f, offset 0x22f
- {value: 0x0000, lo: 0x0b},
- {value: 0x3008, lo: 0x80, hi: 0x81},
- {value: 0x3308, lo: 0x82, hi: 0x82},
- {value: 0x3008, lo: 0x83, hi: 0x83},
- {value: 0x3808, lo: 0x84, hi: 0x84},
- {value: 0x0008, lo: 0x85, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0018, lo: 0x9a, hi: 0xaa},
- {value: 0x3308, lo: 0xab, hi: 0xb3},
- {value: 0x0018, lo: 0xb4, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbf},
- // Block 0x40, offset 0x23b
- {value: 0x0000, lo: 0x0b},
- {value: 0x3308, lo: 0x80, hi: 0x81},
- {value: 0x3008, lo: 0x82, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0xa0},
- {value: 0x3008, lo: 0xa1, hi: 0xa1},
- {value: 0x3308, lo: 0xa2, hi: 0xa5},
- {value: 0x3008, lo: 0xa6, hi: 0xa7},
- {value: 0x3308, lo: 0xa8, hi: 0xa9},
- {value: 0x3808, lo: 0xaa, hi: 0xaa},
- {value: 0x3b08, lo: 0xab, hi: 0xab},
- {value: 0x3308, lo: 0xac, hi: 0xad},
- {value: 0x0008, lo: 0xae, hi: 0xbf},
- // Block 0x41, offset 0x247
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0xa5},
- {value: 0x3308, lo: 0xa6, hi: 0xa6},
- {value: 0x3008, lo: 0xa7, hi: 0xa7},
- {value: 0x3308, lo: 0xa8, hi: 0xa9},
- {value: 0x3008, lo: 0xaa, hi: 0xac},
- {value: 0x3308, lo: 0xad, hi: 0xad},
- {value: 0x3008, lo: 0xae, hi: 0xae},
- {value: 0x3308, lo: 0xaf, hi: 0xb1},
- {value: 0x3808, lo: 0xb2, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xbb},
- {value: 0x0018, lo: 0xbc, hi: 0xbf},
- // Block 0x42, offset 0x253
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0xa3},
- {value: 0x3008, lo: 0xa4, hi: 0xab},
- {value: 0x3308, lo: 0xac, hi: 0xb3},
- {value: 0x3008, lo: 0xb4, hi: 0xb5},
- {value: 0x3308, lo: 0xb6, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xba},
- {value: 0x0018, lo: 0xbb, hi: 0xbf},
- // Block 0x43, offset 0x25b
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x0040, lo: 0x8a, hi: 0x8c},
- {value: 0x0008, lo: 0x8d, hi: 0xbd},
- {value: 0x0018, lo: 0xbe, hi: 0xbf},
- // Block 0x44, offset 0x260
- {value: 0x0000, lo: 0x0c},
- {value: 0x0e29, lo: 0x80, hi: 0x80},
- {value: 0x0e41, lo: 0x81, hi: 0x81},
- {value: 0x0e59, lo: 0x82, hi: 0x82},
- {value: 0x0e71, lo: 0x83, hi: 0x83},
- {value: 0x0e89, lo: 0x84, hi: 0x85},
- {value: 0x0ea1, lo: 0x86, hi: 0x86},
- {value: 0x0eb9, lo: 0x87, hi: 0x87},
- {value: 0x057d, lo: 0x88, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x8f},
- {value: 0x059d, lo: 0x90, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbc},
- {value: 0x059d, lo: 0xbd, hi: 0xbf},
- // Block 0x45, offset 0x26d
- {value: 0x0000, lo: 0x10},
- {value: 0x0018, lo: 0x80, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x3308, lo: 0x90, hi: 0x92},
- {value: 0x0018, lo: 0x93, hi: 0x93},
- {value: 0x3308, lo: 0x94, hi: 0xa0},
- {value: 0x3008, lo: 0xa1, hi: 0xa1},
- {value: 0x3308, lo: 0xa2, hi: 0xa8},
- {value: 0x0008, lo: 0xa9, hi: 0xac},
- {value: 0x3308, lo: 0xad, hi: 0xad},
- {value: 0x0008, lo: 0xae, hi: 0xb3},
- {value: 0x3308, lo: 0xb4, hi: 0xb4},
- {value: 0x0008, lo: 0xb5, hi: 0xb6},
- {value: 0x3008, lo: 0xb7, hi: 0xb7},
- {value: 0x3308, lo: 0xb8, hi: 0xb9},
- {value: 0x0008, lo: 0xba, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbf},
- // Block 0x46, offset 0x27e
- {value: 0x0000, lo: 0x03},
- {value: 0x3308, lo: 0x80, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xba},
- {value: 0x3308, lo: 0xbb, hi: 0xbf},
- // Block 0x47, offset 0x282
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0x87},
- {value: 0xe045, lo: 0x88, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0x97},
- {value: 0xe045, lo: 0x98, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa7},
- {value: 0xe045, lo: 0xa8, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb7},
- {value: 0xe045, lo: 0xb8, hi: 0xbf},
- // Block 0x48, offset 0x28d
- {value: 0x0000, lo: 0x03},
- {value: 0x0040, lo: 0x80, hi: 0x8f},
- {value: 0x3318, lo: 0x90, hi: 0xb0},
- {value: 0x0040, lo: 0xb1, hi: 0xbf},
- // Block 0x49, offset 0x291
- {value: 0x0000, lo: 0x08},
- {value: 0x0018, lo: 0x80, hi: 0x82},
- {value: 0x0040, lo: 0x83, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0x84},
- {value: 0x0018, lo: 0x85, hi: 0x88},
- {value: 0x24c1, lo: 0x89, hi: 0x89},
- {value: 0x0018, lo: 0x8a, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0xbf},
- // Block 0x4a, offset 0x29a
- {value: 0x0000, lo: 0x07},
- {value: 0x0018, lo: 0x80, hi: 0xab},
- {value: 0x24f1, lo: 0xac, hi: 0xac},
- {value: 0x2529, lo: 0xad, hi: 0xad},
- {value: 0x0018, lo: 0xae, hi: 0xae},
- {value: 0x2579, lo: 0xaf, hi: 0xaf},
- {value: 0x25b1, lo: 0xb0, hi: 0xb0},
- {value: 0x0018, lo: 0xb1, hi: 0xbf},
- // Block 0x4b, offset 0x2a2
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0x9f},
- {value: 0x0080, lo: 0xa0, hi: 0xa0},
- {value: 0x0018, lo: 0xa1, hi: 0xad},
- {value: 0x0080, lo: 0xae, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xbf},
- // Block 0x4c, offset 0x2a8
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0xa8},
- {value: 0x09dd, lo: 0xa9, hi: 0xa9},
- {value: 0x09fd, lo: 0xaa, hi: 0xaa},
- {value: 0x0018, lo: 0xab, hi: 0xbf},
- // Block 0x4d, offset 0x2ad
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0xa6},
- {value: 0x0040, lo: 0xa7, hi: 0xbf},
- // Block 0x4e, offset 0x2b0
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0x8b},
- {value: 0x28c1, lo: 0x8c, hi: 0x8c},
- {value: 0x0018, lo: 0x8d, hi: 0xbf},
- // Block 0x4f, offset 0x2b4
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0xb3},
- {value: 0x0e7e, lo: 0xb4, hi: 0xb4},
- {value: 0x292a, lo: 0xb5, hi: 0xb5},
- {value: 0x0e9e, lo: 0xb6, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xbf},
- // Block 0x50, offset 0x2ba
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0x9b},
- {value: 0x2941, lo: 0x9c, hi: 0x9c},
- {value: 0x0018, lo: 0x9d, hi: 0xbf},
- // Block 0x51, offset 0x2be
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xb5},
- {value: 0x0018, lo: 0xb6, hi: 0xbf},
- // Block 0x52, offset 0x2c2
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0x96},
- {value: 0x0018, lo: 0x97, hi: 0xbf},
- // Block 0x53, offset 0x2c6
- {value: 0x0000, lo: 0x05},
- {value: 0xe185, lo: 0x80, hi: 0x8f},
- {value: 0x03f5, lo: 0x90, hi: 0x9f},
- {value: 0x0ebd, lo: 0xa0, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x54, offset 0x2cc
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0xa5},
- {value: 0x0040, lo: 0xa6, hi: 0xa6},
- {value: 0x0008, lo: 0xa7, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xac},
- {value: 0x0008, lo: 0xad, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x55, offset 0x2d4
- {value: 0x0000, lo: 0x06},
- {value: 0x0008, lo: 0x80, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xae},
- {value: 0xe075, lo: 0xaf, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb0},
- {value: 0x0040, lo: 0xb1, hi: 0xbe},
- {value: 0x3b08, lo: 0xbf, hi: 0xbf},
- // Block 0x56, offset 0x2db
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa6},
- {value: 0x0040, lo: 0xa7, hi: 0xa7},
- {value: 0x0008, lo: 0xa8, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xb7},
- {value: 0x0008, lo: 0xb8, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0x57, offset 0x2e6
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x87},
- {value: 0x0008, lo: 0x88, hi: 0x8e},
- {value: 0x0040, lo: 0x8f, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0x9f},
- {value: 0x3308, lo: 0xa0, hi: 0xbf},
- // Block 0x58, offset 0x2f0
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xae},
- {value: 0x0008, lo: 0xaf, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xbf},
- // Block 0x59, offset 0x2f4
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0x92},
- {value: 0x0040, lo: 0x93, hi: 0xbf},
- // Block 0x5a, offset 0x2f7
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9a},
- {value: 0x0018, lo: 0x9b, hi: 0x9e},
- {value: 0x0ef5, lo: 0x9f, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xbf},
- // Block 0x5b, offset 0x2fd
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xb2},
- {value: 0x0f15, lo: 0xb3, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xbf},
- // Block 0x5c, offset 0x301
- {value: 0x0020, lo: 0x01},
- {value: 0x0f35, lo: 0x80, hi: 0xbf},
- // Block 0x5d, offset 0x303
- {value: 0x0020, lo: 0x02},
- {value: 0x1735, lo: 0x80, hi: 0x8f},
- {value: 0x1915, lo: 0x90, hi: 0xbf},
- // Block 0x5e, offset 0x306
- {value: 0x0020, lo: 0x01},
- {value: 0x1f15, lo: 0x80, hi: 0xbf},
- // Block 0x5f, offset 0x308
- {value: 0x0000, lo: 0x02},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0xbf},
- // Block 0x60, offset 0x30b
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x98},
- {value: 0x3308, lo: 0x99, hi: 0x9a},
- {value: 0x29e2, lo: 0x9b, hi: 0x9b},
- {value: 0x2a0a, lo: 0x9c, hi: 0x9c},
- {value: 0x0008, lo: 0x9d, hi: 0x9e},
- {value: 0x2a31, lo: 0x9f, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xa0},
- {value: 0x0008, lo: 0xa1, hi: 0xbf},
- // Block 0x61, offset 0x315
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xbe},
- {value: 0x2a69, lo: 0xbf, hi: 0xbf},
- // Block 0x62, offset 0x318
- {value: 0x0000, lo: 0x0e},
- {value: 0x0040, lo: 0x80, hi: 0x84},
- {value: 0x0008, lo: 0x85, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xb0},
- {value: 0x2a35, lo: 0xb1, hi: 0xb1},
- {value: 0x2a55, lo: 0xb2, hi: 0xb2},
- {value: 0x2a75, lo: 0xb3, hi: 0xb3},
- {value: 0x2a95, lo: 0xb4, hi: 0xb4},
- {value: 0x2a75, lo: 0xb5, hi: 0xb5},
- {value: 0x2ab5, lo: 0xb6, hi: 0xb6},
- {value: 0x2ad5, lo: 0xb7, hi: 0xb7},
- {value: 0x2af5, lo: 0xb8, hi: 0xb9},
- {value: 0x2b15, lo: 0xba, hi: 0xbb},
- {value: 0x2b35, lo: 0xbc, hi: 0xbd},
- {value: 0x2b15, lo: 0xbe, hi: 0xbf},
- // Block 0x63, offset 0x327
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xa3},
- {value: 0x0040, lo: 0xa4, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x64, offset 0x32b
- {value: 0x0030, lo: 0x04},
- {value: 0x2aa2, lo: 0x80, hi: 0x9d},
- {value: 0x305a, lo: 0x9e, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0x9f},
- {value: 0x30a2, lo: 0xa0, hi: 0xbf},
- // Block 0x65, offset 0x330
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbf},
- // Block 0x66, offset 0x333
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0x8c},
- {value: 0x0040, lo: 0x8d, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0xbf},
- // Block 0x67, offset 0x337
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xbd},
- {value: 0x0018, lo: 0xbe, hi: 0xbf},
- // Block 0x68, offset 0x33c
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x8c},
- {value: 0x0018, lo: 0x8d, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xbf},
- // Block 0x69, offset 0x341
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0xa5},
- {value: 0x0018, lo: 0xa6, hi: 0xaf},
- {value: 0x3308, lo: 0xb0, hi: 0xb1},
- {value: 0x0018, lo: 0xb2, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xbf},
- // Block 0x6a, offset 0x347
- {value: 0x0000, lo: 0x10},
- {value: 0x0040, lo: 0x80, hi: 0x81},
- {value: 0xe00d, lo: 0x82, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0x83},
- {value: 0x03f5, lo: 0x84, hi: 0x84},
- {value: 0x1329, lo: 0x85, hi: 0x85},
- {value: 0x447d, lo: 0x86, hi: 0x86},
- {value: 0xe07d, lo: 0x87, hi: 0x87},
- {value: 0x0008, lo: 0x88, hi: 0x88},
- {value: 0xe01d, lo: 0x89, hi: 0x89},
- {value: 0x0008, lo: 0x8a, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0xb4},
- {value: 0xe01d, lo: 0xb5, hi: 0xb5},
- {value: 0x0008, lo: 0xb6, hi: 0xb7},
- {value: 0x2009, lo: 0xb8, hi: 0xb8},
- {value: 0x6ec1, lo: 0xb9, hi: 0xb9},
- {value: 0x0008, lo: 0xba, hi: 0xbf},
- // Block 0x6b, offset 0x358
- {value: 0x0000, lo: 0x0f},
- {value: 0x0008, lo: 0x80, hi: 0x81},
- {value: 0x3308, lo: 0x82, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0x85},
- {value: 0x3b08, lo: 0x86, hi: 0x86},
- {value: 0x0008, lo: 0x87, hi: 0x8a},
- {value: 0x3308, lo: 0x8b, hi: 0x8b},
- {value: 0x0008, lo: 0x8c, hi: 0xa2},
- {value: 0x3008, lo: 0xa3, hi: 0xa4},
- {value: 0x3308, lo: 0xa5, hi: 0xa6},
- {value: 0x3008, lo: 0xa7, hi: 0xa7},
- {value: 0x0018, lo: 0xa8, hi: 0xab},
- {value: 0x3b08, lo: 0xac, hi: 0xac},
- {value: 0x0040, lo: 0xad, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0x6c, offset 0x368
- {value: 0x0000, lo: 0x05},
- {value: 0x0208, lo: 0x80, hi: 0xb1},
- {value: 0x0108, lo: 0xb2, hi: 0xb2},
- {value: 0x0008, lo: 0xb3, hi: 0xb3},
- {value: 0x0018, lo: 0xb4, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xbf},
- // Block 0x6d, offset 0x36e
- {value: 0x0000, lo: 0x03},
- {value: 0x3008, lo: 0x80, hi: 0x81},
- {value: 0x0008, lo: 0x82, hi: 0xb3},
- {value: 0x3008, lo: 0xb4, hi: 0xbf},
- // Block 0x6e, offset 0x372
- {value: 0x0000, lo: 0x0e},
- {value: 0x3008, lo: 0x80, hi: 0x83},
- {value: 0x3b08, lo: 0x84, hi: 0x84},
- {value: 0x3308, lo: 0x85, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0x8d},
- {value: 0x0018, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x3308, lo: 0xa0, hi: 0xb1},
- {value: 0x0008, lo: 0xb2, hi: 0xb7},
- {value: 0x0018, lo: 0xb8, hi: 0xba},
- {value: 0x0008, lo: 0xbb, hi: 0xbb},
- {value: 0x0018, lo: 0xbc, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbe},
- {value: 0x3308, lo: 0xbf, hi: 0xbf},
- // Block 0x6f, offset 0x381
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xa5},
- {value: 0x3308, lo: 0xa6, hi: 0xad},
- {value: 0x0018, lo: 0xae, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x70, offset 0x386
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x3308, lo: 0x87, hi: 0x91},
- {value: 0x3008, lo: 0x92, hi: 0x92},
- {value: 0x3808, lo: 0x93, hi: 0x93},
- {value: 0x0040, lo: 0x94, hi: 0x9e},
- {value: 0x0018, lo: 0x9f, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbf},
- // Block 0x71, offset 0x38e
- {value: 0x0000, lo: 0x09},
- {value: 0x3308, lo: 0x80, hi: 0x82},
- {value: 0x3008, lo: 0x83, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0xb2},
- {value: 0x3308, lo: 0xb3, hi: 0xb3},
- {value: 0x3008, lo: 0xb4, hi: 0xb5},
- {value: 0x3308, lo: 0xb6, hi: 0xb9},
- {value: 0x3008, lo: 0xba, hi: 0xbb},
- {value: 0x3308, lo: 0xbc, hi: 0xbd},
- {value: 0x3008, lo: 0xbe, hi: 0xbf},
- // Block 0x72, offset 0x398
- {value: 0x0000, lo: 0x0a},
- {value: 0x3808, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8e},
- {value: 0x0008, lo: 0x8f, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa4},
- {value: 0x3308, lo: 0xa5, hi: 0xa5},
- {value: 0x0008, lo: 0xa6, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0x73, offset 0x3a3
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0xa8},
- {value: 0x3308, lo: 0xa9, hi: 0xae},
- {value: 0x3008, lo: 0xaf, hi: 0xb0},
- {value: 0x3308, lo: 0xb1, hi: 0xb2},
- {value: 0x3008, lo: 0xb3, hi: 0xb4},
- {value: 0x3308, lo: 0xb5, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0x74, offset 0x3ab
- {value: 0x0000, lo: 0x10},
- {value: 0x0008, lo: 0x80, hi: 0x82},
- {value: 0x3308, lo: 0x83, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0x8b},
- {value: 0x3308, lo: 0x8c, hi: 0x8c},
- {value: 0x3008, lo: 0x8d, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9b},
- {value: 0x0018, lo: 0x9c, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xb9},
- {value: 0x0008, lo: 0xba, hi: 0xba},
- {value: 0x3008, lo: 0xbb, hi: 0xbb},
- {value: 0x3308, lo: 0xbc, hi: 0xbc},
- {value: 0x3008, lo: 0xbd, hi: 0xbd},
- {value: 0x0008, lo: 0xbe, hi: 0xbf},
- // Block 0x75, offset 0x3bc
- {value: 0x0000, lo: 0x08},
- {value: 0x0008, lo: 0x80, hi: 0xaf},
- {value: 0x3308, lo: 0xb0, hi: 0xb0},
- {value: 0x0008, lo: 0xb1, hi: 0xb1},
- {value: 0x3308, lo: 0xb2, hi: 0xb4},
- {value: 0x0008, lo: 0xb5, hi: 0xb6},
- {value: 0x3308, lo: 0xb7, hi: 0xb8},
- {value: 0x0008, lo: 0xb9, hi: 0xbd},
- {value: 0x3308, lo: 0xbe, hi: 0xbf},
- // Block 0x76, offset 0x3c5
- {value: 0x0000, lo: 0x0f},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0x3308, lo: 0x81, hi: 0x81},
- {value: 0x0008, lo: 0x82, hi: 0x82},
- {value: 0x0040, lo: 0x83, hi: 0x9a},
- {value: 0x0008, lo: 0x9b, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xaa},
- {value: 0x3008, lo: 0xab, hi: 0xab},
- {value: 0x3308, lo: 0xac, hi: 0xad},
- {value: 0x3008, lo: 0xae, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb1},
- {value: 0x0008, lo: 0xb2, hi: 0xb4},
- {value: 0x3008, lo: 0xb5, hi: 0xb5},
- {value: 0x3b08, lo: 0xb6, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0x77, offset 0x3d5
- {value: 0x0000, lo: 0x0c},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x88},
- {value: 0x0008, lo: 0x89, hi: 0x8e},
- {value: 0x0040, lo: 0x8f, hi: 0x90},
- {value: 0x0008, lo: 0x91, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa6},
- {value: 0x0040, lo: 0xa7, hi: 0xa7},
- {value: 0x0008, lo: 0xa8, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x78, offset 0x3e2
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x9a},
- {value: 0x0018, lo: 0x9b, hi: 0x9b},
- {value: 0x449d, lo: 0x9c, hi: 0x9c},
- {value: 0x44b5, lo: 0x9d, hi: 0x9d},
- {value: 0x2971, lo: 0x9e, hi: 0x9e},
- {value: 0xe06d, lo: 0x9f, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa8},
- {value: 0x6ed9, lo: 0xa9, hi: 0xa9},
- {value: 0x0018, lo: 0xaa, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xaf},
- {value: 0x44cd, lo: 0xb0, hi: 0xbf},
- // Block 0x79, offset 0x3ee
- {value: 0x0000, lo: 0x04},
- {value: 0x44ed, lo: 0x80, hi: 0x8f},
- {value: 0x450d, lo: 0x90, hi: 0x9f},
- {value: 0x452d, lo: 0xa0, hi: 0xaf},
- {value: 0x450d, lo: 0xb0, hi: 0xbf},
- // Block 0x7a, offset 0x3f3
- {value: 0x0000, lo: 0x0c},
- {value: 0x0008, lo: 0x80, hi: 0xa2},
- {value: 0x3008, lo: 0xa3, hi: 0xa4},
- {value: 0x3308, lo: 0xa5, hi: 0xa5},
- {value: 0x3008, lo: 0xa6, hi: 0xa7},
- {value: 0x3308, lo: 0xa8, hi: 0xa8},
- {value: 0x3008, lo: 0xa9, hi: 0xaa},
- {value: 0x0018, lo: 0xab, hi: 0xab},
- {value: 0x3008, lo: 0xac, hi: 0xac},
- {value: 0x3b08, lo: 0xad, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0x7b, offset 0x400
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xa3},
- {value: 0x0040, lo: 0xa4, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xbf},
- // Block 0x7c, offset 0x404
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x8a},
- {value: 0x0018, lo: 0x8b, hi: 0xbb},
- {value: 0x0040, lo: 0xbc, hi: 0xbf},
- // Block 0x7d, offset 0x409
- {value: 0x0000, lo: 0x01},
- {value: 0x0040, lo: 0x80, hi: 0xbf},
- // Block 0x7e, offset 0x40b
- {value: 0x0020, lo: 0x01},
- {value: 0x454d, lo: 0x80, hi: 0xbf},
- // Block 0x7f, offset 0x40d
- {value: 0x0020, lo: 0x03},
- {value: 0x4d4d, lo: 0x80, hi: 0x94},
- {value: 0x4b0d, lo: 0x95, hi: 0x95},
- {value: 0x4fed, lo: 0x96, hi: 0xbf},
- // Block 0x80, offset 0x411
- {value: 0x0020, lo: 0x01},
- {value: 0x552d, lo: 0x80, hi: 0xbf},
- // Block 0x81, offset 0x413
- {value: 0x0020, lo: 0x03},
- {value: 0x5d2d, lo: 0x80, hi: 0x84},
- {value: 0x568d, lo: 0x85, hi: 0x85},
- {value: 0x5dcd, lo: 0x86, hi: 0xbf},
- // Block 0x82, offset 0x417
- {value: 0x0020, lo: 0x08},
- {value: 0x6b8d, lo: 0x80, hi: 0x8f},
- {value: 0x6d4d, lo: 0x90, hi: 0x90},
- {value: 0x6d8d, lo: 0x91, hi: 0xab},
- {value: 0x6ef1, lo: 0xac, hi: 0xac},
- {value: 0x70ed, lo: 0xad, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xaf},
- {value: 0x710d, lo: 0xb0, hi: 0xbf},
- // Block 0x83, offset 0x420
- {value: 0x0020, lo: 0x05},
- {value: 0x730d, lo: 0x80, hi: 0xad},
- {value: 0x656d, lo: 0xae, hi: 0xae},
- {value: 0x78cd, lo: 0xaf, hi: 0xb5},
- {value: 0x6f8d, lo: 0xb6, hi: 0xb6},
- {value: 0x79ad, lo: 0xb7, hi: 0xbf},
- // Block 0x84, offset 0x426
- {value: 0x0028, lo: 0x03},
- {value: 0x7c71, lo: 0x80, hi: 0x82},
- {value: 0x7c31, lo: 0x83, hi: 0x83},
- {value: 0x7ce9, lo: 0x84, hi: 0xbf},
- // Block 0x85, offset 0x42a
- {value: 0x0038, lo: 0x0f},
- {value: 0x9e01, lo: 0x80, hi: 0x83},
- {value: 0x9ea9, lo: 0x84, hi: 0x85},
- {value: 0x9ee1, lo: 0x86, hi: 0x87},
- {value: 0x9f19, lo: 0x88, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0x90},
- {value: 0x0040, lo: 0x91, hi: 0x91},
- {value: 0xa0d9, lo: 0x92, hi: 0x97},
- {value: 0xa1f1, lo: 0x98, hi: 0x9c},
- {value: 0xa2d1, lo: 0x9d, hi: 0xb3},
- {value: 0x9d91, lo: 0xb4, hi: 0xb4},
- {value: 0x9e01, lo: 0xb5, hi: 0xb5},
- {value: 0xa7d9, lo: 0xb6, hi: 0xbb},
- {value: 0xa8b9, lo: 0xbc, hi: 0xbc},
- {value: 0xa849, lo: 0xbd, hi: 0xbd},
- {value: 0xa929, lo: 0xbe, hi: 0xbf},
- // Block 0x86, offset 0x43a
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x8c},
- {value: 0x0008, lo: 0x8d, hi: 0xa6},
- {value: 0x0040, lo: 0xa7, hi: 0xa7},
- {value: 0x0008, lo: 0xa8, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbb},
- {value: 0x0008, lo: 0xbc, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbe},
- {value: 0x0008, lo: 0xbf, hi: 0xbf},
- // Block 0x87, offset 0x444
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0xbf},
- // Block 0x88, offset 0x449
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbf},
- // Block 0x89, offset 0x44c
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0x82},
- {value: 0x0040, lo: 0x83, hi: 0x86},
- {value: 0x0018, lo: 0x87, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xbf},
- // Block 0x8a, offset 0x452
- {value: 0x0000, lo: 0x06},
- {value: 0x0018, lo: 0x80, hi: 0x8e},
- {value: 0x0040, lo: 0x8f, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0x9c},
- {value: 0x0040, lo: 0x9d, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xa0},
- {value: 0x0040, lo: 0xa1, hi: 0xbf},
- // Block 0x8b, offset 0x459
- {value: 0x0000, lo: 0x04},
- {value: 0x0040, lo: 0x80, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0xbc},
- {value: 0x3308, lo: 0xbd, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbf},
- // Block 0x8c, offset 0x45e
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0x9c},
- {value: 0x0040, lo: 0x9d, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x8d, offset 0x462
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x90},
- {value: 0x0040, lo: 0x91, hi: 0x9f},
- {value: 0x3308, lo: 0xa0, hi: 0xa0},
- {value: 0x0018, lo: 0xa1, hi: 0xbb},
- {value: 0x0040, lo: 0xbc, hi: 0xbf},
- // Block 0x8e, offset 0x468
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xa3},
- {value: 0x0040, lo: 0xa4, hi: 0xac},
- {value: 0x0008, lo: 0xad, hi: 0xbf},
- // Block 0x8f, offset 0x46d
- {value: 0x0000, lo: 0x08},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x81},
- {value: 0x0008, lo: 0x82, hi: 0x89},
- {value: 0x0018, lo: 0x8a, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xb5},
- {value: 0x3308, lo: 0xb6, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbf},
- // Block 0x90, offset 0x476
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9e},
- {value: 0x0018, lo: 0x9f, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x91, offset 0x47b
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x83},
- {value: 0x0040, lo: 0x84, hi: 0x87},
- {value: 0x0008, lo: 0x88, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0xbf},
- // Block 0x92, offset 0x481
- {value: 0x0000, lo: 0x06},
- {value: 0xe145, lo: 0x80, hi: 0x87},
- {value: 0xe1c5, lo: 0x88, hi: 0x8f},
- {value: 0xe145, lo: 0x90, hi: 0x97},
- {value: 0x8b0d, lo: 0x98, hi: 0x9f},
- {value: 0x8b25, lo: 0xa0, hi: 0xa7},
- {value: 0x0008, lo: 0xa8, hi: 0xbf},
- // Block 0x93, offset 0x488
- {value: 0x0000, lo: 0x06},
- {value: 0x0008, lo: 0x80, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa9},
- {value: 0x0040, lo: 0xaa, hi: 0xaf},
- {value: 0x8b25, lo: 0xb0, hi: 0xb7},
- {value: 0x8b0d, lo: 0xb8, hi: 0xbf},
- // Block 0x94, offset 0x48f
- {value: 0x0000, lo: 0x06},
- {value: 0xe145, lo: 0x80, hi: 0x87},
- {value: 0xe1c5, lo: 0x88, hi: 0x8f},
- {value: 0xe145, lo: 0x90, hi: 0x93},
- {value: 0x0040, lo: 0x94, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0xbb},
- {value: 0x0040, lo: 0xbc, hi: 0xbf},
- // Block 0x95, offset 0x496
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x96, offset 0x49a
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xa3},
- {value: 0x0040, lo: 0xa4, hi: 0xae},
- {value: 0x0018, lo: 0xaf, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbf},
- // Block 0x97, offset 0x49f
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0x98, offset 0x4a2
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xbf},
- // Block 0x99, offset 0x4a7
- {value: 0x0000, lo: 0x0b},
- {value: 0x0808, lo: 0x80, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0x87},
- {value: 0x0808, lo: 0x88, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x0808, lo: 0x8a, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xb6},
- {value: 0x0808, lo: 0xb7, hi: 0xb8},
- {value: 0x0040, lo: 0xb9, hi: 0xbb},
- {value: 0x0808, lo: 0xbc, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbe},
- {value: 0x0808, lo: 0xbf, hi: 0xbf},
- // Block 0x9a, offset 0x4b3
- {value: 0x0000, lo: 0x05},
- {value: 0x0808, lo: 0x80, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0x96},
- {value: 0x0818, lo: 0x97, hi: 0x9f},
- {value: 0x0808, lo: 0xa0, hi: 0xb6},
- {value: 0x0818, lo: 0xb7, hi: 0xbf},
- // Block 0x9b, offset 0x4b9
- {value: 0x0000, lo: 0x04},
- {value: 0x0808, lo: 0x80, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0xa6},
- {value: 0x0818, lo: 0xa7, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbf},
- // Block 0x9c, offset 0x4be
- {value: 0x0000, lo: 0x06},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x0808, lo: 0xa0, hi: 0xb2},
- {value: 0x0040, lo: 0xb3, hi: 0xb3},
- {value: 0x0808, lo: 0xb4, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xba},
- {value: 0x0818, lo: 0xbb, hi: 0xbf},
- // Block 0x9d, offset 0x4c5
- {value: 0x0000, lo: 0x07},
- {value: 0x0808, lo: 0x80, hi: 0x95},
- {value: 0x0818, lo: 0x96, hi: 0x9b},
- {value: 0x0040, lo: 0x9c, hi: 0x9e},
- {value: 0x0018, lo: 0x9f, hi: 0x9f},
- {value: 0x0808, lo: 0xa0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbe},
- {value: 0x0818, lo: 0xbf, hi: 0xbf},
- // Block 0x9e, offset 0x4cd
- {value: 0x0000, lo: 0x04},
- {value: 0x0808, lo: 0x80, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xbb},
- {value: 0x0818, lo: 0xbc, hi: 0xbd},
- {value: 0x0808, lo: 0xbe, hi: 0xbf},
- // Block 0x9f, offset 0x4d2
- {value: 0x0000, lo: 0x03},
- {value: 0x0818, lo: 0x80, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0x91},
- {value: 0x0818, lo: 0x92, hi: 0xbf},
- // Block 0xa0, offset 0x4d6
- {value: 0x0000, lo: 0x0f},
- {value: 0x0808, lo: 0x80, hi: 0x80},
- {value: 0x3308, lo: 0x81, hi: 0x83},
- {value: 0x0040, lo: 0x84, hi: 0x84},
- {value: 0x3308, lo: 0x85, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x8b},
- {value: 0x3308, lo: 0x8c, hi: 0x8f},
- {value: 0x0808, lo: 0x90, hi: 0x93},
- {value: 0x0040, lo: 0x94, hi: 0x94},
- {value: 0x0808, lo: 0x95, hi: 0x97},
- {value: 0x0040, lo: 0x98, hi: 0x98},
- {value: 0x0808, lo: 0x99, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xb7},
- {value: 0x3308, lo: 0xb8, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbe},
- {value: 0x3b08, lo: 0xbf, hi: 0xbf},
- // Block 0xa1, offset 0x4e6
- {value: 0x0000, lo: 0x06},
- {value: 0x0818, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x8f},
- {value: 0x0818, lo: 0x90, hi: 0x98},
- {value: 0x0040, lo: 0x99, hi: 0x9f},
- {value: 0x0808, lo: 0xa0, hi: 0xbc},
- {value: 0x0818, lo: 0xbd, hi: 0xbf},
- // Block 0xa2, offset 0x4ed
- {value: 0x0000, lo: 0x03},
- {value: 0x0808, lo: 0x80, hi: 0x9c},
- {value: 0x0818, lo: 0x9d, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xbf},
- // Block 0xa3, offset 0x4f1
- {value: 0x0000, lo: 0x03},
- {value: 0x0808, lo: 0x80, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xb8},
- {value: 0x0018, lo: 0xb9, hi: 0xbf},
- // Block 0xa4, offset 0x4f5
- {value: 0x0000, lo: 0x06},
- {value: 0x0808, lo: 0x80, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0x97},
- {value: 0x0818, lo: 0x98, hi: 0x9f},
- {value: 0x0808, lo: 0xa0, hi: 0xb2},
- {value: 0x0040, lo: 0xb3, hi: 0xb7},
- {value: 0x0818, lo: 0xb8, hi: 0xbf},
- // Block 0xa5, offset 0x4fc
- {value: 0x0000, lo: 0x01},
- {value: 0x0808, lo: 0x80, hi: 0xbf},
- // Block 0xa6, offset 0x4fe
- {value: 0x0000, lo: 0x02},
- {value: 0x0808, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0xbf},
- // Block 0xa7, offset 0x501
- {value: 0x0000, lo: 0x02},
- {value: 0x03dd, lo: 0x80, hi: 0xb2},
- {value: 0x0040, lo: 0xb3, hi: 0xbf},
- // Block 0xa8, offset 0x504
- {value: 0x0000, lo: 0x03},
- {value: 0x0808, lo: 0x80, hi: 0xb2},
- {value: 0x0040, lo: 0xb3, hi: 0xb9},
- {value: 0x0818, lo: 0xba, hi: 0xbf},
- // Block 0xa9, offset 0x508
- {value: 0x0000, lo: 0x08},
- {value: 0x0908, lo: 0x80, hi: 0x80},
- {value: 0x0a08, lo: 0x81, hi: 0xa1},
- {value: 0x0c08, lo: 0xa2, hi: 0xa2},
- {value: 0x0a08, lo: 0xa3, hi: 0xa3},
- {value: 0x3308, lo: 0xa4, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xaf},
- {value: 0x0808, lo: 0xb0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0xaa, offset 0x511
- {value: 0x0000, lo: 0x03},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x0818, lo: 0xa0, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0xab, offset 0x515
- {value: 0x0000, lo: 0x07},
- {value: 0x0808, lo: 0x80, hi: 0xa9},
- {value: 0x0040, lo: 0xaa, hi: 0xaa},
- {value: 0x3308, lo: 0xab, hi: 0xac},
- {value: 0x0818, lo: 0xad, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x0808, lo: 0xb0, hi: 0xb1},
- {value: 0x0040, lo: 0xb2, hi: 0xbf},
- // Block 0xac, offset 0x51d
- {value: 0x0000, lo: 0x07},
- {value: 0x0808, lo: 0x80, hi: 0x9c},
- {value: 0x0818, lo: 0x9d, hi: 0xa6},
- {value: 0x0808, lo: 0xa7, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xaf},
- {value: 0x0a08, lo: 0xb0, hi: 0xb2},
- {value: 0x0c08, lo: 0xb3, hi: 0xb3},
- {value: 0x0a08, lo: 0xb4, hi: 0xbf},
- // Block 0xad, offset 0x525
- {value: 0x0000, lo: 0x07},
- {value: 0x0a08, lo: 0x80, hi: 0x84},
- {value: 0x0808, lo: 0x85, hi: 0x85},
- {value: 0x3308, lo: 0x86, hi: 0x90},
- {value: 0x0a18, lo: 0x91, hi: 0x93},
- {value: 0x0c18, lo: 0x94, hi: 0x94},
- {value: 0x0818, lo: 0x95, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0xbf},
- // Block 0xae, offset 0x52d
- {value: 0x0000, lo: 0x0b},
- {value: 0x0040, lo: 0x80, hi: 0xaf},
- {value: 0x0a08, lo: 0xb0, hi: 0xb0},
- {value: 0x0808, lo: 0xb1, hi: 0xb1},
- {value: 0x0a08, lo: 0xb2, hi: 0xb3},
- {value: 0x0c08, lo: 0xb4, hi: 0xb6},
- {value: 0x0808, lo: 0xb7, hi: 0xb7},
- {value: 0x0a08, lo: 0xb8, hi: 0xb8},
- {value: 0x0c08, lo: 0xb9, hi: 0xba},
- {value: 0x0a08, lo: 0xbb, hi: 0xbc},
- {value: 0x0c08, lo: 0xbd, hi: 0xbd},
- {value: 0x0a08, lo: 0xbe, hi: 0xbf},
- // Block 0xaf, offset 0x539
- {value: 0x0000, lo: 0x0b},
- {value: 0x0808, lo: 0x80, hi: 0x80},
- {value: 0x0a08, lo: 0x81, hi: 0x81},
- {value: 0x0c08, lo: 0x82, hi: 0x83},
- {value: 0x0a08, lo: 0x84, hi: 0x84},
- {value: 0x0818, lo: 0x85, hi: 0x88},
- {value: 0x0c18, lo: 0x89, hi: 0x89},
- {value: 0x0a18, lo: 0x8a, hi: 0x8a},
- {value: 0x0918, lo: 0x8b, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x9f},
- {value: 0x0808, lo: 0xa0, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0xb0, offset 0x545
- {value: 0x0000, lo: 0x05},
- {value: 0x3008, lo: 0x80, hi: 0x80},
- {value: 0x3308, lo: 0x81, hi: 0x81},
- {value: 0x3008, lo: 0x82, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0xb7},
- {value: 0x3308, lo: 0xb8, hi: 0xbf},
- // Block 0xb1, offset 0x54b
- {value: 0x0000, lo: 0x08},
- {value: 0x3308, lo: 0x80, hi: 0x85},
- {value: 0x3b08, lo: 0x86, hi: 0x86},
- {value: 0x0018, lo: 0x87, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x91},
- {value: 0x0018, lo: 0x92, hi: 0xa5},
- {value: 0x0008, lo: 0xa6, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbe},
- {value: 0x3b08, lo: 0xbf, hi: 0xbf},
- // Block 0xb2, offset 0x554
- {value: 0x0000, lo: 0x0b},
- {value: 0x3308, lo: 0x80, hi: 0x81},
- {value: 0x3008, lo: 0x82, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0xaf},
- {value: 0x3008, lo: 0xb0, hi: 0xb2},
- {value: 0x3308, lo: 0xb3, hi: 0xb6},
- {value: 0x3008, lo: 0xb7, hi: 0xb8},
- {value: 0x3b08, lo: 0xb9, hi: 0xb9},
- {value: 0x3308, lo: 0xba, hi: 0xba},
- {value: 0x0018, lo: 0xbb, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbd},
- {value: 0x0018, lo: 0xbe, hi: 0xbf},
- // Block 0xb3, offset 0x560
- {value: 0x0000, lo: 0x06},
- {value: 0x0018, lo: 0x80, hi: 0x81},
- {value: 0x0040, lo: 0x82, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xa8},
- {value: 0x0040, lo: 0xa9, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0xb4, offset 0x567
- {value: 0x0000, lo: 0x08},
- {value: 0x3308, lo: 0x80, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0xa6},
- {value: 0x3308, lo: 0xa7, hi: 0xab},
- {value: 0x3008, lo: 0xac, hi: 0xac},
- {value: 0x3308, lo: 0xad, hi: 0xb2},
- {value: 0x3b08, lo: 0xb3, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xb5},
- {value: 0x0008, lo: 0xb6, hi: 0xbf},
- // Block 0xb5, offset 0x570
- {value: 0x0000, lo: 0x0a},
- {value: 0x0018, lo: 0x80, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0x84},
- {value: 0x3008, lo: 0x85, hi: 0x86},
- {value: 0x0008, lo: 0x87, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xb2},
- {value: 0x3308, lo: 0xb3, hi: 0xb3},
- {value: 0x0018, lo: 0xb4, hi: 0xb5},
- {value: 0x0008, lo: 0xb6, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0xb6, offset 0x57b
- {value: 0x0000, lo: 0x06},
- {value: 0x3308, lo: 0x80, hi: 0x81},
- {value: 0x3008, lo: 0x82, hi: 0x82},
- {value: 0x0008, lo: 0x83, hi: 0xb2},
- {value: 0x3008, lo: 0xb3, hi: 0xb5},
- {value: 0x3308, lo: 0xb6, hi: 0xbe},
- {value: 0x3008, lo: 0xbf, hi: 0xbf},
- // Block 0xb7, offset 0x582
- {value: 0x0000, lo: 0x0e},
- {value: 0x3808, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0x84},
- {value: 0x0018, lo: 0x85, hi: 0x88},
- {value: 0x3308, lo: 0x89, hi: 0x8c},
- {value: 0x0018, lo: 0x8d, hi: 0x8d},
- {value: 0x3008, lo: 0x8e, hi: 0x8e},
- {value: 0x3308, lo: 0x8f, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x9a},
- {value: 0x0018, lo: 0x9b, hi: 0x9b},
- {value: 0x0008, lo: 0x9c, hi: 0x9c},
- {value: 0x0018, lo: 0x9d, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xa0},
- {value: 0x0018, lo: 0xa1, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0xb8, offset 0x591
- {value: 0x0000, lo: 0x0c},
- {value: 0x0008, lo: 0x80, hi: 0x91},
- {value: 0x0040, lo: 0x92, hi: 0x92},
- {value: 0x0008, lo: 0x93, hi: 0xab},
- {value: 0x3008, lo: 0xac, hi: 0xae},
- {value: 0x3308, lo: 0xaf, hi: 0xb1},
- {value: 0x3008, lo: 0xb2, hi: 0xb3},
- {value: 0x3308, lo: 0xb4, hi: 0xb4},
- {value: 0x3808, lo: 0xb5, hi: 0xb5},
- {value: 0x3308, lo: 0xb6, hi: 0xb7},
- {value: 0x0018, lo: 0xb8, hi: 0xbd},
- {value: 0x3308, lo: 0xbe, hi: 0xbe},
- {value: 0x0040, lo: 0xbf, hi: 0xbf},
- // Block 0xb9, offset 0x59e
- {value: 0x0000, lo: 0x0c},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x87},
- {value: 0x0008, lo: 0x88, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x0008, lo: 0x8a, hi: 0x8d},
- {value: 0x0040, lo: 0x8e, hi: 0x8e},
- {value: 0x0008, lo: 0x8f, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9e},
- {value: 0x0008, lo: 0x9f, hi: 0xa8},
- {value: 0x0018, lo: 0xa9, hi: 0xa9},
- {value: 0x0040, lo: 0xaa, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0xba, offset 0x5ab
- {value: 0x0000, lo: 0x08},
- {value: 0x0008, lo: 0x80, hi: 0x9e},
- {value: 0x3308, lo: 0x9f, hi: 0x9f},
- {value: 0x3008, lo: 0xa0, hi: 0xa2},
- {value: 0x3308, lo: 0xa3, hi: 0xa9},
- {value: 0x3b08, lo: 0xaa, hi: 0xaa},
- {value: 0x0040, lo: 0xab, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0xbb, offset 0x5b4
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xb4},
- {value: 0x3008, lo: 0xb5, hi: 0xb7},
- {value: 0x3308, lo: 0xb8, hi: 0xbf},
- // Block 0xbc, offset 0x5b8
- {value: 0x0000, lo: 0x0e},
- {value: 0x3008, lo: 0x80, hi: 0x81},
- {value: 0x3b08, lo: 0x82, hi: 0x82},
- {value: 0x3308, lo: 0x83, hi: 0x84},
- {value: 0x3008, lo: 0x85, hi: 0x85},
- {value: 0x3308, lo: 0x86, hi: 0x86},
- {value: 0x0008, lo: 0x87, hi: 0x8a},
- {value: 0x0018, lo: 0x8b, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0018, lo: 0x9a, hi: 0x9b},
- {value: 0x0040, lo: 0x9c, hi: 0x9c},
- {value: 0x0018, lo: 0x9d, hi: 0x9d},
- {value: 0x3308, lo: 0x9e, hi: 0x9e},
- {value: 0x0008, lo: 0x9f, hi: 0xa1},
- {value: 0x0040, lo: 0xa2, hi: 0xbf},
- // Block 0xbd, offset 0x5c7
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0xaf},
- {value: 0x3008, lo: 0xb0, hi: 0xb2},
- {value: 0x3308, lo: 0xb3, hi: 0xb8},
- {value: 0x3008, lo: 0xb9, hi: 0xb9},
- {value: 0x3308, lo: 0xba, hi: 0xba},
- {value: 0x3008, lo: 0xbb, hi: 0xbe},
- {value: 0x3308, lo: 0xbf, hi: 0xbf},
- // Block 0xbe, offset 0x5cf
- {value: 0x0000, lo: 0x0a},
- {value: 0x3308, lo: 0x80, hi: 0x80},
- {value: 0x3008, lo: 0x81, hi: 0x81},
- {value: 0x3b08, lo: 0x82, hi: 0x82},
- {value: 0x3308, lo: 0x83, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0x85},
- {value: 0x0018, lo: 0x86, hi: 0x86},
- {value: 0x0008, lo: 0x87, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0xbf},
- // Block 0xbf, offset 0x5da
- {value: 0x0000, lo: 0x08},
- {value: 0x0008, lo: 0x80, hi: 0xae},
- {value: 0x3008, lo: 0xaf, hi: 0xb1},
- {value: 0x3308, lo: 0xb2, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xb7},
- {value: 0x3008, lo: 0xb8, hi: 0xbb},
- {value: 0x3308, lo: 0xbc, hi: 0xbd},
- {value: 0x3008, lo: 0xbe, hi: 0xbe},
- {value: 0x3b08, lo: 0xbf, hi: 0xbf},
- // Block 0xc0, offset 0x5e3
- {value: 0x0000, lo: 0x05},
- {value: 0x3308, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0x9b},
- {value: 0x3308, lo: 0x9c, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0xbf},
- // Block 0xc1, offset 0x5e9
- {value: 0x0000, lo: 0x07},
- {value: 0x0008, lo: 0x80, hi: 0xaf},
- {value: 0x3008, lo: 0xb0, hi: 0xb2},
- {value: 0x3308, lo: 0xb3, hi: 0xba},
- {value: 0x3008, lo: 0xbb, hi: 0xbc},
- {value: 0x3308, lo: 0xbd, hi: 0xbd},
- {value: 0x3008, lo: 0xbe, hi: 0xbe},
- {value: 0x3b08, lo: 0xbf, hi: 0xbf},
- // Block 0xc2, offset 0x5f1
- {value: 0x0000, lo: 0x08},
- {value: 0x3308, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x83},
- {value: 0x0008, lo: 0x84, hi: 0x84},
- {value: 0x0040, lo: 0x85, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xac},
- {value: 0x0040, lo: 0xad, hi: 0xbf},
- // Block 0xc3, offset 0x5fa
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0xaa},
- {value: 0x3308, lo: 0xab, hi: 0xab},
- {value: 0x3008, lo: 0xac, hi: 0xac},
- {value: 0x3308, lo: 0xad, hi: 0xad},
- {value: 0x3008, lo: 0xae, hi: 0xaf},
- {value: 0x3308, lo: 0xb0, hi: 0xb5},
- {value: 0x3808, lo: 0xb6, hi: 0xb6},
- {value: 0x3308, lo: 0xb7, hi: 0xb7},
- {value: 0x0008, lo: 0xb8, hi: 0xb8},
- {value: 0x0040, lo: 0xb9, hi: 0xbf},
- // Block 0xc4, offset 0x605
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x0040, lo: 0x8a, hi: 0xbf},
- // Block 0xc5, offset 0x608
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x9a},
- {value: 0x0040, lo: 0x9b, hi: 0x9c},
- {value: 0x3308, lo: 0x9d, hi: 0x9f},
- {value: 0x3008, lo: 0xa0, hi: 0xa1},
- {value: 0x3308, lo: 0xa2, hi: 0xa5},
- {value: 0x3008, lo: 0xa6, hi: 0xa6},
- {value: 0x3308, lo: 0xa7, hi: 0xaa},
- {value: 0x3b08, lo: 0xab, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb9},
- {value: 0x0018, lo: 0xba, hi: 0xbf},
- // Block 0xc6, offset 0x614
- {value: 0x0000, lo: 0x08},
- {value: 0x0008, lo: 0x80, hi: 0xab},
- {value: 0x3008, lo: 0xac, hi: 0xae},
- {value: 0x3308, lo: 0xaf, hi: 0xb7},
- {value: 0x3008, lo: 0xb8, hi: 0xb8},
- {value: 0x3b08, lo: 0xb9, hi: 0xb9},
- {value: 0x3308, lo: 0xba, hi: 0xba},
- {value: 0x0018, lo: 0xbb, hi: 0xbb},
- {value: 0x0040, lo: 0xbc, hi: 0xbf},
- // Block 0xc7, offset 0x61d
- {value: 0x0000, lo: 0x02},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x049d, lo: 0xa0, hi: 0xbf},
- // Block 0xc8, offset 0x620
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xa9},
- {value: 0x0018, lo: 0xaa, hi: 0xb2},
- {value: 0x0040, lo: 0xb3, hi: 0xbe},
- {value: 0x0008, lo: 0xbf, hi: 0xbf},
- // Block 0xc9, offset 0x625
- {value: 0x0000, lo: 0x08},
- {value: 0x3008, lo: 0x80, hi: 0x80},
- {value: 0x0008, lo: 0x81, hi: 0x81},
- {value: 0x3008, lo: 0x82, hi: 0x82},
- {value: 0x3308, lo: 0x83, hi: 0x83},
- {value: 0x0018, lo: 0x84, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0xbf},
- // Block 0xca, offset 0x62e
- {value: 0x0000, lo: 0x04},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xa9},
- {value: 0x0008, lo: 0xaa, hi: 0xbf},
- // Block 0xcb, offset 0x633
- {value: 0x0000, lo: 0x0c},
- {value: 0x0008, lo: 0x80, hi: 0x90},
- {value: 0x3008, lo: 0x91, hi: 0x93},
- {value: 0x3308, lo: 0x94, hi: 0x97},
- {value: 0x0040, lo: 0x98, hi: 0x99},
- {value: 0x3308, lo: 0x9a, hi: 0x9b},
- {value: 0x3008, lo: 0x9c, hi: 0x9f},
- {value: 0x3b08, lo: 0xa0, hi: 0xa0},
- {value: 0x0008, lo: 0xa1, hi: 0xa1},
- {value: 0x0018, lo: 0xa2, hi: 0xa2},
- {value: 0x0008, lo: 0xa3, hi: 0xa3},
- {value: 0x3008, lo: 0xa4, hi: 0xa4},
- {value: 0x0040, lo: 0xa5, hi: 0xbf},
- // Block 0xcc, offset 0x640
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0x3308, lo: 0x81, hi: 0x8a},
- {value: 0x0008, lo: 0x8b, hi: 0xb2},
- {value: 0x3308, lo: 0xb3, hi: 0xb3},
- {value: 0x3b08, lo: 0xb4, hi: 0xb4},
- {value: 0x3308, lo: 0xb5, hi: 0xb8},
- {value: 0x3008, lo: 0xb9, hi: 0xb9},
- {value: 0x0008, lo: 0xba, hi: 0xba},
- {value: 0x3308, lo: 0xbb, hi: 0xbe},
- {value: 0x0018, lo: 0xbf, hi: 0xbf},
- // Block 0xcd, offset 0x64b
- {value: 0x0000, lo: 0x08},
- {value: 0x0018, lo: 0x80, hi: 0x86},
- {value: 0x3b08, lo: 0x87, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x90},
- {value: 0x3308, lo: 0x91, hi: 0x96},
- {value: 0x3008, lo: 0x97, hi: 0x98},
- {value: 0x3308, lo: 0x99, hi: 0x9b},
- {value: 0x0008, lo: 0x9c, hi: 0xbf},
- // Block 0xce, offset 0x654
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x3308, lo: 0x8a, hi: 0x96},
- {value: 0x3008, lo: 0x97, hi: 0x97},
- {value: 0x3308, lo: 0x98, hi: 0x98},
- {value: 0x3b08, lo: 0x99, hi: 0x99},
- {value: 0x0018, lo: 0x9a, hi: 0x9c},
- {value: 0x0008, lo: 0x9d, hi: 0x9d},
- {value: 0x0018, lo: 0x9e, hi: 0xa2},
- {value: 0x0040, lo: 0xa3, hi: 0xbf},
- // Block 0xcf, offset 0x65e
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xb8},
- {value: 0x0040, lo: 0xb9, hi: 0xbf},
- // Block 0xd0, offset 0x661
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x89},
- {value: 0x0008, lo: 0x8a, hi: 0xae},
- {value: 0x3008, lo: 0xaf, hi: 0xaf},
- {value: 0x3308, lo: 0xb0, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xb7},
- {value: 0x3308, lo: 0xb8, hi: 0xbd},
- {value: 0x3008, lo: 0xbe, hi: 0xbe},
- {value: 0x3b08, lo: 0xbf, hi: 0xbf},
- // Block 0xd1, offset 0x66b
- {value: 0x0000, lo: 0x08},
- {value: 0x0008, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0018, lo: 0x9a, hi: 0xac},
- {value: 0x0040, lo: 0xad, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb1},
- {value: 0x0008, lo: 0xb2, hi: 0xbf},
- // Block 0xd2, offset 0x674
- {value: 0x0000, lo: 0x0b},
- {value: 0x0008, lo: 0x80, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0x91},
- {value: 0x3308, lo: 0x92, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xa8},
- {value: 0x3008, lo: 0xa9, hi: 0xa9},
- {value: 0x3308, lo: 0xaa, hi: 0xb0},
- {value: 0x3008, lo: 0xb1, hi: 0xb1},
- {value: 0x3308, lo: 0xb2, hi: 0xb3},
- {value: 0x3008, lo: 0xb4, hi: 0xb4},
- {value: 0x3308, lo: 0xb5, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0xd3, offset 0x680
- {value: 0x0000, lo: 0x0c},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x87},
- {value: 0x0008, lo: 0x88, hi: 0x89},
- {value: 0x0040, lo: 0x8a, hi: 0x8a},
- {value: 0x0008, lo: 0x8b, hi: 0xb0},
- {value: 0x3308, lo: 0xb1, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xb9},
- {value: 0x3308, lo: 0xba, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbb},
- {value: 0x3308, lo: 0xbc, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbe},
- {value: 0x3308, lo: 0xbf, hi: 0xbf},
- // Block 0xd4, offset 0x68d
- {value: 0x0000, lo: 0x0c},
- {value: 0x3308, lo: 0x80, hi: 0x83},
- {value: 0x3b08, lo: 0x84, hi: 0x85},
- {value: 0x0008, lo: 0x86, hi: 0x86},
- {value: 0x3308, lo: 0x87, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa5},
- {value: 0x0040, lo: 0xa6, hi: 0xa6},
- {value: 0x0008, lo: 0xa7, hi: 0xa8},
- {value: 0x0040, lo: 0xa9, hi: 0xa9},
- {value: 0x0008, lo: 0xaa, hi: 0xbf},
- // Block 0xd5, offset 0x69a
- {value: 0x0000, lo: 0x0d},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x3008, lo: 0x8a, hi: 0x8e},
- {value: 0x0040, lo: 0x8f, hi: 0x8f},
- {value: 0x3308, lo: 0x90, hi: 0x91},
- {value: 0x0040, lo: 0x92, hi: 0x92},
- {value: 0x3008, lo: 0x93, hi: 0x94},
- {value: 0x3308, lo: 0x95, hi: 0x95},
- {value: 0x3008, lo: 0x96, hi: 0x96},
- {value: 0x3b08, lo: 0x97, hi: 0x97},
- {value: 0x0008, lo: 0x98, hi: 0x98},
- {value: 0x0040, lo: 0x99, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa9},
- {value: 0x0040, lo: 0xaa, hi: 0xbf},
- // Block 0xd6, offset 0x6a8
- {value: 0x0000, lo: 0x06},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xb2},
- {value: 0x3308, lo: 0xb3, hi: 0xb4},
- {value: 0x3008, lo: 0xb5, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xb8},
- {value: 0x0040, lo: 0xb9, hi: 0xbf},
- // Block 0xd7, offset 0x6af
- {value: 0x0000, lo: 0x03},
- {value: 0x0040, lo: 0x80, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb0},
- {value: 0x0040, lo: 0xb1, hi: 0xbf},
- // Block 0xd8, offset 0x6b3
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xb1},
- {value: 0x0040, lo: 0xb2, hi: 0xbe},
- {value: 0x0018, lo: 0xbf, hi: 0xbf},
- // Block 0xd9, offset 0x6b7
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0xbf},
- // Block 0xda, offset 0x6ba
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0xdb, offset 0x6bf
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x83},
- {value: 0x0040, lo: 0x84, hi: 0xbf},
- // Block 0xdc, offset 0x6c2
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xaf},
- {value: 0x0340, lo: 0xb0, hi: 0xb8},
- {value: 0x0040, lo: 0xb9, hi: 0xbf},
- // Block 0xdd, offset 0x6c7
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0xbf},
- // Block 0xde, offset 0x6ca
- {value: 0x0000, lo: 0x06},
- {value: 0x0008, lo: 0x80, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa9},
- {value: 0x0040, lo: 0xaa, hi: 0xad},
- {value: 0x0018, lo: 0xae, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbf},
- // Block 0xdf, offset 0x6d1
- {value: 0x0000, lo: 0x06},
- {value: 0x0040, lo: 0x80, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x3308, lo: 0xb0, hi: 0xb4},
- {value: 0x0018, lo: 0xb5, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xbf},
- // Block 0xe0, offset 0x6d8
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xaf},
- {value: 0x3308, lo: 0xb0, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xbf},
- // Block 0xe1, offset 0x6dc
- {value: 0x0000, lo: 0x0a},
- {value: 0x0008, lo: 0x80, hi: 0x83},
- {value: 0x0018, lo: 0x84, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9a},
- {value: 0x0018, lo: 0x9b, hi: 0xa1},
- {value: 0x0040, lo: 0xa2, hi: 0xa2},
- {value: 0x0008, lo: 0xa3, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xbc},
- {value: 0x0008, lo: 0xbd, hi: 0xbf},
- // Block 0xe2, offset 0x6e7
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0xbf},
- // Block 0xe3, offset 0x6ea
- {value: 0x0000, lo: 0x02},
- {value: 0xe105, lo: 0x80, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0xe4, offset 0x6ed
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0x9a},
- {value: 0x0040, lo: 0x9b, hi: 0xbf},
- // Block 0xe5, offset 0x6f0
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0x8e},
- {value: 0x3308, lo: 0x8f, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x90},
- {value: 0x3008, lo: 0x91, hi: 0xbf},
- // Block 0xe6, offset 0x6f6
- {value: 0x0000, lo: 0x05},
- {value: 0x3008, lo: 0x80, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8e},
- {value: 0x3308, lo: 0x8f, hi: 0x92},
- {value: 0x0008, lo: 0x93, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xbf},
- // Block 0xe7, offset 0x6fc
- {value: 0x0000, lo: 0x08},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xa1},
- {value: 0x0018, lo: 0xa2, hi: 0xa2},
- {value: 0x0008, lo: 0xa3, hi: 0xa3},
- {value: 0x3308, lo: 0xa4, hi: 0xa4},
- {value: 0x0040, lo: 0xa5, hi: 0xaf},
- {value: 0x3008, lo: 0xb0, hi: 0xb1},
- {value: 0x0040, lo: 0xb2, hi: 0xbf},
- // Block 0xe8, offset 0x705
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xb7},
- {value: 0x0040, lo: 0xb8, hi: 0xbf},
- // Block 0xe9, offset 0x708
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x95},
- {value: 0x0040, lo: 0x96, hi: 0xbf},
- // Block 0xea, offset 0x70b
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0xbf},
- // Block 0xeb, offset 0x70e
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x9e},
- {value: 0x0040, lo: 0x9f, hi: 0xbf},
- // Block 0xec, offset 0x711
- {value: 0x0000, lo: 0x06},
- {value: 0x0040, lo: 0x80, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x92},
- {value: 0x0040, lo: 0x93, hi: 0xa3},
- {value: 0x0008, lo: 0xa4, hi: 0xa7},
- {value: 0x0040, lo: 0xa8, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0xed, offset 0x718
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xbb},
- {value: 0x0040, lo: 0xbc, hi: 0xbf},
- // Block 0xee, offset 0x71b
- {value: 0x0000, lo: 0x04},
- {value: 0x0008, lo: 0x80, hi: 0xaa},
- {value: 0x0040, lo: 0xab, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbf},
- // Block 0xef, offset 0x720
- {value: 0x0000, lo: 0x09},
- {value: 0x0008, lo: 0x80, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x8f},
- {value: 0x0008, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9b},
- {value: 0x0018, lo: 0x9c, hi: 0x9c},
- {value: 0x3308, lo: 0x9d, hi: 0x9e},
- {value: 0x0018, lo: 0x9f, hi: 0x9f},
- {value: 0x03c0, lo: 0xa0, hi: 0xa3},
- {value: 0x0040, lo: 0xa4, hi: 0xbf},
- // Block 0xf0, offset 0x72a
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xbf},
- // Block 0xf1, offset 0x72d
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xa6},
- {value: 0x0040, lo: 0xa7, hi: 0xa8},
- {value: 0x0018, lo: 0xa9, hi: 0xbf},
- // Block 0xf2, offset 0x731
- {value: 0x0000, lo: 0x0e},
- {value: 0x0018, lo: 0x80, hi: 0x9d},
- {value: 0xb609, lo: 0x9e, hi: 0x9e},
- {value: 0xb651, lo: 0x9f, hi: 0x9f},
- {value: 0xb699, lo: 0xa0, hi: 0xa0},
- {value: 0xb701, lo: 0xa1, hi: 0xa1},
- {value: 0xb769, lo: 0xa2, hi: 0xa2},
- {value: 0xb7d1, lo: 0xa3, hi: 0xa3},
- {value: 0xb839, lo: 0xa4, hi: 0xa4},
- {value: 0x3018, lo: 0xa5, hi: 0xa6},
- {value: 0x3318, lo: 0xa7, hi: 0xa9},
- {value: 0x0018, lo: 0xaa, hi: 0xac},
- {value: 0x3018, lo: 0xad, hi: 0xb2},
- {value: 0x0340, lo: 0xb3, hi: 0xba},
- {value: 0x3318, lo: 0xbb, hi: 0xbf},
- // Block 0xf3, offset 0x740
- {value: 0x0000, lo: 0x0b},
- {value: 0x3318, lo: 0x80, hi: 0x82},
- {value: 0x0018, lo: 0x83, hi: 0x84},
- {value: 0x3318, lo: 0x85, hi: 0x8b},
- {value: 0x0018, lo: 0x8c, hi: 0xa9},
- {value: 0x3318, lo: 0xaa, hi: 0xad},
- {value: 0x0018, lo: 0xae, hi: 0xba},
- {value: 0xb8a1, lo: 0xbb, hi: 0xbb},
- {value: 0xb8e9, lo: 0xbc, hi: 0xbc},
- {value: 0xb931, lo: 0xbd, hi: 0xbd},
- {value: 0xb999, lo: 0xbe, hi: 0xbe},
- {value: 0xba01, lo: 0xbf, hi: 0xbf},
- // Block 0xf4, offset 0x74c
- {value: 0x0000, lo: 0x03},
- {value: 0xba69, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0xa8},
- {value: 0x0040, lo: 0xa9, hi: 0xbf},
- // Block 0xf5, offset 0x750
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x81},
- {value: 0x3318, lo: 0x82, hi: 0x84},
- {value: 0x0018, lo: 0x85, hi: 0x85},
- {value: 0x0040, lo: 0x86, hi: 0xbf},
- // Block 0xf6, offset 0x755
- {value: 0x0000, lo: 0x03},
- {value: 0x0040, lo: 0x80, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xbf},
- // Block 0xf7, offset 0x759
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xb8},
- {value: 0x0040, lo: 0xb9, hi: 0xbf},
- // Block 0xf8, offset 0x75e
- {value: 0x0000, lo: 0x03},
- {value: 0x3308, lo: 0x80, hi: 0xb6},
- {value: 0x0018, lo: 0xb7, hi: 0xba},
- {value: 0x3308, lo: 0xbb, hi: 0xbf},
- // Block 0xf9, offset 0x762
- {value: 0x0000, lo: 0x04},
- {value: 0x3308, lo: 0x80, hi: 0xac},
- {value: 0x0018, lo: 0xad, hi: 0xb4},
- {value: 0x3308, lo: 0xb5, hi: 0xb5},
- {value: 0x0018, lo: 0xb6, hi: 0xbf},
- // Block 0xfa, offset 0x767
- {value: 0x0000, lo: 0x08},
- {value: 0x0018, lo: 0x80, hi: 0x83},
- {value: 0x3308, lo: 0x84, hi: 0x84},
- {value: 0x0018, lo: 0x85, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x9a},
- {value: 0x3308, lo: 0x9b, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xa0},
- {value: 0x3308, lo: 0xa1, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbf},
- // Block 0xfb, offset 0x770
- {value: 0x0000, lo: 0x0a},
- {value: 0x3308, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x87},
- {value: 0x3308, lo: 0x88, hi: 0x98},
- {value: 0x0040, lo: 0x99, hi: 0x9a},
- {value: 0x3308, lo: 0x9b, hi: 0xa1},
- {value: 0x0040, lo: 0xa2, hi: 0xa2},
- {value: 0x3308, lo: 0xa3, hi: 0xa4},
- {value: 0x0040, lo: 0xa5, hi: 0xa5},
- {value: 0x3308, lo: 0xa6, hi: 0xaa},
- {value: 0x0040, lo: 0xab, hi: 0xbf},
- // Block 0xfc, offset 0x77b
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0xac},
- {value: 0x0040, lo: 0xad, hi: 0xaf},
- {value: 0x3308, lo: 0xb0, hi: 0xb6},
- {value: 0x0008, lo: 0xb7, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbf},
- // Block 0xfd, offset 0x781
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0x89},
- {value: 0x0040, lo: 0x8a, hi: 0x8d},
- {value: 0x0008, lo: 0x8e, hi: 0x8e},
- {value: 0x0018, lo: 0x8f, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0xbf},
- // Block 0xfe, offset 0x787
- {value: 0x0000, lo: 0x05},
- {value: 0x0008, lo: 0x80, hi: 0xab},
- {value: 0x3308, lo: 0xac, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbe},
- {value: 0x0018, lo: 0xbf, hi: 0xbf},
- // Block 0xff, offset 0x78d
- {value: 0x0000, lo: 0x05},
- {value: 0x0808, lo: 0x80, hi: 0x84},
- {value: 0x0040, lo: 0x85, hi: 0x86},
- {value: 0x0818, lo: 0x87, hi: 0x8f},
- {value: 0x3308, lo: 0x90, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0xbf},
- // Block 0x100, offset 0x793
- {value: 0x0000, lo: 0x08},
- {value: 0x0a08, lo: 0x80, hi: 0x83},
- {value: 0x3308, lo: 0x84, hi: 0x8a},
- {value: 0x0b08, lo: 0x8b, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x8f},
- {value: 0x0808, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9d},
- {value: 0x0818, lo: 0x9e, hi: 0x9f},
- {value: 0x0040, lo: 0xa0, hi: 0xbf},
- // Block 0x101, offset 0x79c
- {value: 0x0000, lo: 0x02},
- {value: 0x0040, lo: 0x80, hi: 0xb0},
- {value: 0x0818, lo: 0xb1, hi: 0xbf},
- // Block 0x102, offset 0x79f
- {value: 0x0000, lo: 0x02},
- {value: 0x0818, lo: 0x80, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0x103, offset 0x7a2
- {value: 0x0000, lo: 0x03},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0818, lo: 0x81, hi: 0xbd},
- {value: 0x0040, lo: 0xbe, hi: 0xbf},
- // Block 0x104, offset 0x7a6
- {value: 0x0000, lo: 0x03},
- {value: 0x0040, lo: 0x80, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb1},
- {value: 0x0040, lo: 0xb2, hi: 0xbf},
- // Block 0x105, offset 0x7aa
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xbf},
- // Block 0x106, offset 0x7ae
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0x93},
- {value: 0x0040, lo: 0x94, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xae},
- {value: 0x0040, lo: 0xaf, hi: 0xb0},
- {value: 0x0018, lo: 0xb1, hi: 0xbf},
- // Block 0x107, offset 0x7b4
- {value: 0x0000, lo: 0x05},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0018, lo: 0x81, hi: 0x8f},
- {value: 0x0040, lo: 0x90, hi: 0x90},
- {value: 0x0018, lo: 0x91, hi: 0xb5},
- {value: 0x0040, lo: 0xb6, hi: 0xbf},
- // Block 0x108, offset 0x7ba
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x8f},
- {value: 0xc229, lo: 0x90, hi: 0x90},
- {value: 0x0018, lo: 0x91, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xbf},
- // Block 0x109, offset 0x7bf
- {value: 0x0000, lo: 0x02},
- {value: 0x0040, lo: 0x80, hi: 0xa5},
- {value: 0x0018, lo: 0xa6, hi: 0xbf},
- // Block 0x10a, offset 0x7c2
- {value: 0x0000, lo: 0x0f},
- {value: 0xc851, lo: 0x80, hi: 0x80},
- {value: 0xc8a1, lo: 0x81, hi: 0x81},
- {value: 0xc8f1, lo: 0x82, hi: 0x82},
- {value: 0xc941, lo: 0x83, hi: 0x83},
- {value: 0xc991, lo: 0x84, hi: 0x84},
- {value: 0xc9e1, lo: 0x85, hi: 0x85},
- {value: 0xca31, lo: 0x86, hi: 0x86},
- {value: 0xca81, lo: 0x87, hi: 0x87},
- {value: 0xcad1, lo: 0x88, hi: 0x88},
- {value: 0x0040, lo: 0x89, hi: 0x8f},
- {value: 0xcb21, lo: 0x90, hi: 0x90},
- {value: 0xcb41, lo: 0x91, hi: 0x91},
- {value: 0x0040, lo: 0x92, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xa5},
- {value: 0x0040, lo: 0xa6, hi: 0xbf},
- // Block 0x10b, offset 0x7d2
- {value: 0x0000, lo: 0x06},
- {value: 0x0018, lo: 0x80, hi: 0x97},
- {value: 0x0040, lo: 0x98, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xac},
- {value: 0x0040, lo: 0xad, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xbc},
- {value: 0x0040, lo: 0xbd, hi: 0xbf},
- // Block 0x10c, offset 0x7d9
- {value: 0x0000, lo: 0x02},
- {value: 0x0018, lo: 0x80, hi: 0xb3},
- {value: 0x0040, lo: 0xb4, hi: 0xbf},
- // Block 0x10d, offset 0x7dc
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x98},
- {value: 0x0040, lo: 0x99, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xab},
- {value: 0x0040, lo: 0xac, hi: 0xbf},
- // Block 0x10e, offset 0x7e1
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0xbf},
- // Block 0x10f, offset 0x7e5
- {value: 0x0000, lo: 0x05},
- {value: 0x0018, lo: 0x80, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0x99},
- {value: 0x0040, lo: 0x9a, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xbf},
- // Block 0x110, offset 0x7eb
- {value: 0x0000, lo: 0x06},
- {value: 0x0018, lo: 0x80, hi: 0x87},
- {value: 0x0040, lo: 0x88, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb1},
- {value: 0x0040, lo: 0xb2, hi: 0xbf},
- // Block 0x111, offset 0x7f2
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0xb8},
- {value: 0x0040, lo: 0xb9, hi: 0xb9},
- {value: 0x0018, lo: 0xba, hi: 0xbf},
- // Block 0x112, offset 0x7f6
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0x8b},
- {value: 0x0040, lo: 0x8c, hi: 0x8c},
- {value: 0x0018, lo: 0x8d, hi: 0xbf},
- // Block 0x113, offset 0x7fa
- {value: 0x0000, lo: 0x08},
- {value: 0x0018, lo: 0x80, hi: 0x93},
- {value: 0x0040, lo: 0x94, hi: 0x9f},
- {value: 0x0018, lo: 0xa0, hi: 0xad},
- {value: 0x0040, lo: 0xae, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xb7},
- {value: 0x0018, lo: 0xb8, hi: 0xba},
- {value: 0x0040, lo: 0xbb, hi: 0xbf},
- // Block 0x114, offset 0x803
- {value: 0x0000, lo: 0x06},
- {value: 0x0018, lo: 0x80, hi: 0x86},
- {value: 0x0040, lo: 0x87, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0xa8},
- {value: 0x0040, lo: 0xa9, hi: 0xaf},
- {value: 0x0018, lo: 0xb0, hi: 0xb6},
- {value: 0x0040, lo: 0xb7, hi: 0xbf},
- // Block 0x115, offset 0x80a
- {value: 0x0000, lo: 0x04},
- {value: 0x0018, lo: 0x80, hi: 0x82},
- {value: 0x0040, lo: 0x83, hi: 0x8f},
- {value: 0x0018, lo: 0x90, hi: 0x96},
- {value: 0x0040, lo: 0x97, hi: 0xbf},
- // Block 0x116, offset 0x80f
- {value: 0x0000, lo: 0x03},
- {value: 0x0018, lo: 0x80, hi: 0x92},
- {value: 0x0040, lo: 0x93, hi: 0x93},
- {value: 0x0018, lo: 0x94, hi: 0xbf},
- // Block 0x117, offset 0x813
- {value: 0x0000, lo: 0x0d},
- {value: 0x0018, lo: 0x80, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0xaf},
- {value: 0x1f41, lo: 0xb0, hi: 0xb0},
- {value: 0x00c9, lo: 0xb1, hi: 0xb1},
- {value: 0x0069, lo: 0xb2, hi: 0xb2},
- {value: 0x0079, lo: 0xb3, hi: 0xb3},
- {value: 0x1f51, lo: 0xb4, hi: 0xb4},
- {value: 0x1f61, lo: 0xb5, hi: 0xb5},
- {value: 0x1f71, lo: 0xb6, hi: 0xb6},
- {value: 0x1f81, lo: 0xb7, hi: 0xb7},
- {value: 0x1f91, lo: 0xb8, hi: 0xb8},
- {value: 0x1fa1, lo: 0xb9, hi: 0xb9},
- {value: 0x0040, lo: 0xba, hi: 0xbf},
- // Block 0x118, offset 0x821
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0xbf},
- // Block 0x119, offset 0x824
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xb4},
- {value: 0x0040, lo: 0xb5, hi: 0xbf},
- // Block 0x11a, offset 0x827
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0x9d},
- {value: 0x0040, lo: 0x9e, hi: 0x9f},
- {value: 0x0008, lo: 0xa0, hi: 0xbf},
- // Block 0x11b, offset 0x82b
- {value: 0x0000, lo: 0x03},
- {value: 0x0008, lo: 0x80, hi: 0xa1},
- {value: 0x0040, lo: 0xa2, hi: 0xaf},
- {value: 0x0008, lo: 0xb0, hi: 0xbf},
- // Block 0x11c, offset 0x82f
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0xa0},
- {value: 0x0040, lo: 0xa1, hi: 0xbf},
- // Block 0x11d, offset 0x832
- {value: 0x0020, lo: 0x0f},
- {value: 0xdf21, lo: 0x80, hi: 0x89},
- {value: 0x8e35, lo: 0x8a, hi: 0x8a},
- {value: 0xe061, lo: 0x8b, hi: 0x9c},
- {value: 0x8e55, lo: 0x9d, hi: 0x9d},
- {value: 0xe2a1, lo: 0x9e, hi: 0xa2},
- {value: 0x8e75, lo: 0xa3, hi: 0xa3},
- {value: 0xe341, lo: 0xa4, hi: 0xab},
- {value: 0x7f0d, lo: 0xac, hi: 0xac},
- {value: 0xe441, lo: 0xad, hi: 0xaf},
- {value: 0x8e95, lo: 0xb0, hi: 0xb0},
- {value: 0xe4a1, lo: 0xb1, hi: 0xb6},
- {value: 0x8eb5, lo: 0xb7, hi: 0xb9},
- {value: 0xe561, lo: 0xba, hi: 0xba},
- {value: 0x8f15, lo: 0xbb, hi: 0xbb},
- {value: 0xe581, lo: 0xbc, hi: 0xbf},
- // Block 0x11e, offset 0x842
- {value: 0x0020, lo: 0x10},
- {value: 0x93b5, lo: 0x80, hi: 0x80},
- {value: 0xf101, lo: 0x81, hi: 0x86},
- {value: 0x93d5, lo: 0x87, hi: 0x8a},
- {value: 0xda61, lo: 0x8b, hi: 0x8b},
- {value: 0xf1c1, lo: 0x8c, hi: 0x96},
- {value: 0x9455, lo: 0x97, hi: 0x97},
- {value: 0xf321, lo: 0x98, hi: 0xa3},
- {value: 0x9475, lo: 0xa4, hi: 0xa6},
- {value: 0xf4a1, lo: 0xa7, hi: 0xaa},
- {value: 0x94d5, lo: 0xab, hi: 0xab},
- {value: 0xf521, lo: 0xac, hi: 0xac},
- {value: 0x94f5, lo: 0xad, hi: 0xad},
- {value: 0xf541, lo: 0xae, hi: 0xaf},
- {value: 0x9515, lo: 0xb0, hi: 0xb1},
- {value: 0xf581, lo: 0xb2, hi: 0xbe},
- {value: 0x2040, lo: 0xbf, hi: 0xbf},
- // Block 0x11f, offset 0x853
- {value: 0x0000, lo: 0x02},
- {value: 0x0008, lo: 0x80, hi: 0x8a},
- {value: 0x0040, lo: 0x8b, hi: 0xbf},
- // Block 0x120, offset 0x856
- {value: 0x0000, lo: 0x04},
- {value: 0x0040, lo: 0x80, hi: 0x80},
- {value: 0x0340, lo: 0x81, hi: 0x81},
- {value: 0x0040, lo: 0x82, hi: 0x9f},
- {value: 0x0340, lo: 0xa0, hi: 0xbf},
- // Block 0x121, offset 0x85b
- {value: 0x0000, lo: 0x01},
- {value: 0x0340, lo: 0x80, hi: 0xbf},
- // Block 0x122, offset 0x85d
- {value: 0x0000, lo: 0x01},
- {value: 0x33c0, lo: 0x80, hi: 0xbf},
- // Block 0x123, offset 0x85f
- {value: 0x0000, lo: 0x02},
- {value: 0x33c0, lo: 0x80, hi: 0xaf},
- {value: 0x0040, lo: 0xb0, hi: 0xbf},
-}
-
-// Total table size 43370 bytes (42KiB); checksum: EBD909C0
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/trie.go b/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/trie.go
deleted file mode 100644
index c4ef847e7a..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/trie.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-// Copyright 2016 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 idna
-
-// appendMapping appends the mapping for the respective rune. isMapped must be
-// true. A mapping is a categorization of a rune as defined in UTS #46.
-func (c info) appendMapping(b []byte, s string) []byte {
- index := int(c >> indexShift)
- if c&xorBit == 0 {
- s := mappings[index:]
- return append(b, s[1:s[0]+1]...)
- }
- b = append(b, s...)
- if c&inlineXOR == inlineXOR {
- // TODO: support and handle two-byte inline masks
- b[len(b)-1] ^= byte(index)
- } else {
- for p := len(b) - int(xorData[index]); p < len(b); p++ {
- index++
- b[p] ^= xorData[index]
- }
- }
- return b
-}
-
-// Sparse block handling code.
-
-type valueRange struct {
- value uint16 // header: value:stride
- lo, hi byte // header: lo:n
-}
-
-type sparseBlocks struct {
- values []valueRange
- offset []uint16
-}
-
-var idnaSparse = sparseBlocks{
- values: idnaSparseValues[:],
- offset: idnaSparseOffset[:],
-}
-
-// Don't use newIdnaTrie to avoid unconditional linking in of the table.
-var trie = &idnaTrie{}
-
-// lookup determines the type of block n and looks up the value for b.
-// For n < t.cutoff, the block is a simple lookup table. Otherwise, the block
-// is a list of ranges with an accompanying value. Given a matching range r,
-// the value for b is by r.value + (b - r.lo) * stride.
-func (t *sparseBlocks) lookup(n uint32, b byte) uint16 {
- offset := t.offset[n]
- header := t.values[offset]
- lo := offset + 1
- hi := lo + uint16(header.lo)
- for lo < hi {
- m := lo + (hi-lo)/2
- r := t.values[m]
- if r.lo <= b && b <= r.hi {
- return r.value + uint16(b-r.lo)*header.value
- }
- if b < r.lo {
- hi = m
- } else {
- lo = m + 1
- }
- }
- return 0
-}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/ya.make b/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/ya.make
deleted file mode 100644
index 7fb59b257e..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/ya.make
+++ /dev/null
@@ -1,12 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- go118.go
- idna10.0.0.go
- punycode.go
- tables13.0.0.go
- trie.go
- trieval.go
-)
-
-END()
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/ya.make b/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/ya.make
deleted file mode 100644
index 172c1d022d..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/ya.make
+++ /dev/null
@@ -1,23 +0,0 @@
-GO_LIBRARY()
-
-BUILD_ONLY_IF(WARNING OS_DARWIN)
-
-IF (OS_DARWIN)
- SRCS(
- address.go
- binary.go
- empty.s
- interface.go
- interface_classic.go
- interface_multicast.go
- message.go
- route.go
- route_classic.go
- sys.go
- sys_darwin.go
- syscall.go
- zsys_darwin.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go b/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
deleted file mode 100644
index 79a38a0b9b..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2018 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 cpu
-
-// HWCAP/HWCAP2 bits. These are exposed by Linux.
-const (
- hwcap_FP = 1 << 0
- hwcap_ASIMD = 1 << 1
- hwcap_EVTSTRM = 1 << 2
- hwcap_AES = 1 << 3
- hwcap_PMULL = 1 << 4
- hwcap_SHA1 = 1 << 5
- hwcap_SHA2 = 1 << 6
- hwcap_CRC32 = 1 << 7
- hwcap_ATOMICS = 1 << 8
- hwcap_FPHP = 1 << 9
- hwcap_ASIMDHP = 1 << 10
- hwcap_CPUID = 1 << 11
- hwcap_ASIMDRDM = 1 << 12
- hwcap_JSCVT = 1 << 13
- hwcap_FCMA = 1 << 14
- hwcap_LRCPC = 1 << 15
- hwcap_DCPOP = 1 << 16
- hwcap_SHA3 = 1 << 17
- hwcap_SM3 = 1 << 18
- hwcap_SM4 = 1 << 19
- hwcap_ASIMDDP = 1 << 20
- hwcap_SHA512 = 1 << 21
- hwcap_SVE = 1 << 22
- hwcap_ASIMDFHM = 1 << 23
-)
-
-func doinit() {
- if err := readHWCAP(); err != nil {
- // failed to read /proc/self/auxv, try reading registers directly
- readARM64Registers()
- return
- }
-
- // HWCAP feature bits
- ARM64.HasFP = isSet(hwCap, hwcap_FP)
- ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD)
- ARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)
- ARM64.HasAES = isSet(hwCap, hwcap_AES)
- ARM64.HasPMULL = isSet(hwCap, hwcap_PMULL)
- ARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1)
- ARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2)
- ARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32)
- ARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS)
- ARM64.HasFPHP = isSet(hwCap, hwcap_FPHP)
- ARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP)
- ARM64.HasCPUID = isSet(hwCap, hwcap_CPUID)
- ARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM)
- ARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT)
- ARM64.HasFCMA = isSet(hwCap, hwcap_FCMA)
- ARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC)
- ARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP)
- ARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3)
- ARM64.HasSM3 = isSet(hwCap, hwcap_SM3)
- ARM64.HasSM4 = isSet(hwCap, hwcap_SM4)
- ARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP)
- ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512)
- ARM64.HasSVE = isSet(hwCap, hwcap_SVE)
- ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM)
-}
-
-func isSet(hwc uint, value uint) bool {
- return hwc&value != 0
-}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/hwcap_linux.go b/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/hwcap_linux.go
deleted file mode 100644
index f3baa37932..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/hwcap_linux.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package cpu
-
-import (
- "io/ioutil"
-)
-
-const (
- _AT_HWCAP = 16
- _AT_HWCAP2 = 26
-
- procAuxv = "/proc/self/auxv"
-
- uintSize = int(32 << (^uint(0) >> 63))
-)
-
-// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2
-// These are initialized in cpu_$GOARCH.go
-// and should not be changed after they are initialized.
-var hwCap uint
-var hwCap2 uint
-
-func readHWCAP() error {
- buf, err := ioutil.ReadFile(procAuxv)
- if err != nil {
- // e.g. on android /proc/self/auxv is not accessible, so silently
- // ignore the error and leave Initialized = false. On some
- // architectures (e.g. arm64) doinit() implements a fallback
- // readout and will set Initialized = true again.
- return err
- }
- bo := hostByteOrder()
- for len(buf) >= 2*(uintSize/8) {
- var tag, val uint
- switch uintSize {
- case 32:
- tag = uint(bo.Uint32(buf[0:]))
- val = uint(bo.Uint32(buf[4:]))
- buf = buf[8:]
- case 64:
- tag = uint(bo.Uint64(buf[0:]))
- val = uint(bo.Uint64(buf[8:]))
- buf = buf[16:]
- }
- switch tag {
- case _AT_HWCAP:
- hwCap = val
- case _AT_HWCAP2:
- hwCap2 = val
- }
- }
- return nil
-}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/ya.make b/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/ya.make
deleted file mode 100644
index 867d949759..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/ya.make
+++ /dev/null
@@ -1,54 +0,0 @@
-GO_LIBRARY()
-
-SRCS(
- byteorder.go
- cpu.go
-)
-
-IF (ARCH_ARM64)
- SRCS(
- cpu_arm64.go
- cpu_arm64.s
- cpu_gc_arm64.go
- )
-ENDIF()
-
-IF (ARCH_X86_64)
- SRCS(
- cpu_gc_x86.go
- cpu_x86.go
- cpu_x86.s
- )
-ENDIF()
-
-IF (OS_DARWIN AND ARCH_ARM64)
- SRCS(
- cpu_other_arm64.go
- )
-ENDIF()
-
-IF (OS_LINUX)
- SRCS(
- hwcap_linux.go
- )
-
- IF (ARCH_ARM64)
- SRCS(
- cpu_linux_arm64.go
- )
- ENDIF()
-
- IF (ARCH_X86_64)
- SRCS(
- cpu_linux_noinit.go
- )
- ENDIF()
-ENDIF()
-
-IF (OS_WINDOWS AND ARCH_ARM64)
- SRCS(
- cpu_other_arm64.go
- )
-ENDIF()
-
-END()
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go b/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go
deleted file mode 100644
index f248effae1..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go
+++ /dev/null
@@ -1,1956 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-//go:build go1.16
-// +build go1.16
-
-package bidi
-
-// UnicodeVersion is the Unicode version from which the tables in this package are derived.
-const UnicodeVersion = "13.0.0"
-
-// xorMasks contains masks to be xor-ed with brackets to get the reverse
-// version.
-var xorMasks = []int32{ // 8 elements
- 0, 1, 6, 7, 3, 15, 29, 63,
-} // Size: 56 bytes
-
-// lookup returns the trie value for the first UTF-8 encoding in s and
-// the width in bytes of this encoding. The size will be 0 if s does not
-// hold enough bytes to complete the encoding. len(s) must be greater than 0.
-func (t *bidiTrie) lookup(s []byte) (v uint8, sz int) {
- c0 := s[0]
- switch {
- case c0 < 0x80: // is ASCII
- return bidiValues[c0], 1
- case c0 < 0xC2:
- return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
- case c0 < 0xE0: // 2-byte UTF-8
- if len(s) < 2 {
- return 0, 0
- }
- i := bidiIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c1), 2
- case c0 < 0xF0: // 3-byte UTF-8
- if len(s) < 3 {
- return 0, 0
- }
- i := bidiIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = bidiIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c2), 3
- case c0 < 0xF8: // 4-byte UTF-8
- if len(s) < 4 {
- return 0, 0
- }
- i := bidiIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = bidiIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- o = uint32(i)<<6 + uint32(c2)
- i = bidiIndex[o]
- c3 := s[3]
- if c3 < 0x80 || 0xC0 <= c3 {
- return 0, 3 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c3), 4
- }
- // Illegal rune
- return 0, 1
-}
-
-// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
-// s must start with a full and valid UTF-8 encoded rune.
-func (t *bidiTrie) lookupUnsafe(s []byte) uint8 {
- c0 := s[0]
- if c0 < 0x80 { // is ASCII
- return bidiValues[c0]
- }
- i := bidiIndex[c0]
- if c0 < 0xE0 { // 2-byte UTF-8
- return t.lookupValue(uint32(i), s[1])
- }
- i = bidiIndex[uint32(i)<<6+uint32(s[1])]
- if c0 < 0xF0 { // 3-byte UTF-8
- return t.lookupValue(uint32(i), s[2])
- }
- i = bidiIndex[uint32(i)<<6+uint32(s[2])]
- if c0 < 0xF8 { // 4-byte UTF-8
- return t.lookupValue(uint32(i), s[3])
- }
- return 0
-}
-
-// lookupString returns the trie value for the first UTF-8 encoding in s and
-// the width in bytes of this encoding. The size will be 0 if s does not
-// hold enough bytes to complete the encoding. len(s) must be greater than 0.
-func (t *bidiTrie) lookupString(s string) (v uint8, sz int) {
- c0 := s[0]
- switch {
- case c0 < 0x80: // is ASCII
- return bidiValues[c0], 1
- case c0 < 0xC2:
- return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
- case c0 < 0xE0: // 2-byte UTF-8
- if len(s) < 2 {
- return 0, 0
- }
- i := bidiIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c1), 2
- case c0 < 0xF0: // 3-byte UTF-8
- if len(s) < 3 {
- return 0, 0
- }
- i := bidiIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = bidiIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c2), 3
- case c0 < 0xF8: // 4-byte UTF-8
- if len(s) < 4 {
- return 0, 0
- }
- i := bidiIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = bidiIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- o = uint32(i)<<6 + uint32(c2)
- i = bidiIndex[o]
- c3 := s[3]
- if c3 < 0x80 || 0xC0 <= c3 {
- return 0, 3 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c3), 4
- }
- // Illegal rune
- return 0, 1
-}
-
-// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
-// s must start with a full and valid UTF-8 encoded rune.
-func (t *bidiTrie) lookupStringUnsafe(s string) uint8 {
- c0 := s[0]
- if c0 < 0x80 { // is ASCII
- return bidiValues[c0]
- }
- i := bidiIndex[c0]
- if c0 < 0xE0 { // 2-byte UTF-8
- return t.lookupValue(uint32(i), s[1])
- }
- i = bidiIndex[uint32(i)<<6+uint32(s[1])]
- if c0 < 0xF0 { // 3-byte UTF-8
- return t.lookupValue(uint32(i), s[2])
- }
- i = bidiIndex[uint32(i)<<6+uint32(s[2])]
- if c0 < 0xF8 { // 4-byte UTF-8
- return t.lookupValue(uint32(i), s[3])
- }
- return 0
-}
-
-// bidiTrie. Total size: 17408 bytes (17.00 KiB). Checksum: df85fcbfe9b8377f.
-type bidiTrie struct{}
-
-func newBidiTrie(i int) *bidiTrie {
- return &bidiTrie{}
-}
-
-// lookupValue determines the type of block n and looks up the value for b.
-func (t *bidiTrie) lookupValue(n uint32, b byte) uint8 {
- switch {
- default:
- return uint8(bidiValues[n<<6+uint32(b)])
- }
-}
-
-// bidiValues: 248 blocks, 15872 entries, 15872 bytes
-// The third block is the zero block.
-var bidiValues = [15872]uint8{
- // Block 0x0, offset 0x0
- 0x00: 0x000b, 0x01: 0x000b, 0x02: 0x000b, 0x03: 0x000b, 0x04: 0x000b, 0x05: 0x000b,
- 0x06: 0x000b, 0x07: 0x000b, 0x08: 0x000b, 0x09: 0x0008, 0x0a: 0x0007, 0x0b: 0x0008,
- 0x0c: 0x0009, 0x0d: 0x0007, 0x0e: 0x000b, 0x0f: 0x000b, 0x10: 0x000b, 0x11: 0x000b,
- 0x12: 0x000b, 0x13: 0x000b, 0x14: 0x000b, 0x15: 0x000b, 0x16: 0x000b, 0x17: 0x000b,
- 0x18: 0x000b, 0x19: 0x000b, 0x1a: 0x000b, 0x1b: 0x000b, 0x1c: 0x0007, 0x1d: 0x0007,
- 0x1e: 0x0007, 0x1f: 0x0008, 0x20: 0x0009, 0x21: 0x000a, 0x22: 0x000a, 0x23: 0x0004,
- 0x24: 0x0004, 0x25: 0x0004, 0x26: 0x000a, 0x27: 0x000a, 0x28: 0x003a, 0x29: 0x002a,
- 0x2a: 0x000a, 0x2b: 0x0003, 0x2c: 0x0006, 0x2d: 0x0003, 0x2e: 0x0006, 0x2f: 0x0006,
- 0x30: 0x0002, 0x31: 0x0002, 0x32: 0x0002, 0x33: 0x0002, 0x34: 0x0002, 0x35: 0x0002,
- 0x36: 0x0002, 0x37: 0x0002, 0x38: 0x0002, 0x39: 0x0002, 0x3a: 0x0006, 0x3b: 0x000a,
- 0x3c: 0x000a, 0x3d: 0x000a, 0x3e: 0x000a, 0x3f: 0x000a,
- // Block 0x1, offset 0x40
- 0x40: 0x000a,
- 0x5b: 0x005a, 0x5c: 0x000a, 0x5d: 0x004a,
- 0x5e: 0x000a, 0x5f: 0x000a, 0x60: 0x000a,
- 0x7b: 0x005a,
- 0x7c: 0x000a, 0x7d: 0x004a, 0x7e: 0x000a, 0x7f: 0x000b,
- // Block 0x2, offset 0x80
- // Block 0x3, offset 0xc0
- 0xc0: 0x000b, 0xc1: 0x000b, 0xc2: 0x000b, 0xc3: 0x000b, 0xc4: 0x000b, 0xc5: 0x0007,
- 0xc6: 0x000b, 0xc7: 0x000b, 0xc8: 0x000b, 0xc9: 0x000b, 0xca: 0x000b, 0xcb: 0x000b,
- 0xcc: 0x000b, 0xcd: 0x000b, 0xce: 0x000b, 0xcf: 0x000b, 0xd0: 0x000b, 0xd1: 0x000b,
- 0xd2: 0x000b, 0xd3: 0x000b, 0xd4: 0x000b, 0xd5: 0x000b, 0xd6: 0x000b, 0xd7: 0x000b,
- 0xd8: 0x000b, 0xd9: 0x000b, 0xda: 0x000b, 0xdb: 0x000b, 0xdc: 0x000b, 0xdd: 0x000b,
- 0xde: 0x000b, 0xdf: 0x000b, 0xe0: 0x0006, 0xe1: 0x000a, 0xe2: 0x0004, 0xe3: 0x0004,
- 0xe4: 0x0004, 0xe5: 0x0004, 0xe6: 0x000a, 0xe7: 0x000a, 0xe8: 0x000a, 0xe9: 0x000a,
- 0xeb: 0x000a, 0xec: 0x000a, 0xed: 0x000b, 0xee: 0x000a, 0xef: 0x000a,
- 0xf0: 0x0004, 0xf1: 0x0004, 0xf2: 0x0002, 0xf3: 0x0002, 0xf4: 0x000a,
- 0xf6: 0x000a, 0xf7: 0x000a, 0xf8: 0x000a, 0xf9: 0x0002, 0xfb: 0x000a,
- 0xfc: 0x000a, 0xfd: 0x000a, 0xfe: 0x000a, 0xff: 0x000a,
- // Block 0x4, offset 0x100
- 0x117: 0x000a,
- 0x137: 0x000a,
- // Block 0x5, offset 0x140
- 0x179: 0x000a, 0x17a: 0x000a,
- // Block 0x6, offset 0x180
- 0x182: 0x000a, 0x183: 0x000a, 0x184: 0x000a, 0x185: 0x000a,
- 0x186: 0x000a, 0x187: 0x000a, 0x188: 0x000a, 0x189: 0x000a, 0x18a: 0x000a, 0x18b: 0x000a,
- 0x18c: 0x000a, 0x18d: 0x000a, 0x18e: 0x000a, 0x18f: 0x000a,
- 0x192: 0x000a, 0x193: 0x000a, 0x194: 0x000a, 0x195: 0x000a, 0x196: 0x000a, 0x197: 0x000a,
- 0x198: 0x000a, 0x199: 0x000a, 0x19a: 0x000a, 0x19b: 0x000a, 0x19c: 0x000a, 0x19d: 0x000a,
- 0x19e: 0x000a, 0x19f: 0x000a,
- 0x1a5: 0x000a, 0x1a6: 0x000a, 0x1a7: 0x000a, 0x1a8: 0x000a, 0x1a9: 0x000a,
- 0x1aa: 0x000a, 0x1ab: 0x000a, 0x1ac: 0x000a, 0x1ad: 0x000a, 0x1af: 0x000a,
- 0x1b0: 0x000a, 0x1b1: 0x000a, 0x1b2: 0x000a, 0x1b3: 0x000a, 0x1b4: 0x000a, 0x1b5: 0x000a,
- 0x1b6: 0x000a, 0x1b7: 0x000a, 0x1b8: 0x000a, 0x1b9: 0x000a, 0x1ba: 0x000a, 0x1bb: 0x000a,
- 0x1bc: 0x000a, 0x1bd: 0x000a, 0x1be: 0x000a, 0x1bf: 0x000a,
- // Block 0x7, offset 0x1c0
- 0x1c0: 0x000c, 0x1c1: 0x000c, 0x1c2: 0x000c, 0x1c3: 0x000c, 0x1c4: 0x000c, 0x1c5: 0x000c,
- 0x1c6: 0x000c, 0x1c7: 0x000c, 0x1c8: 0x000c, 0x1c9: 0x000c, 0x1ca: 0x000c, 0x1cb: 0x000c,
- 0x1cc: 0x000c, 0x1cd: 0x000c, 0x1ce: 0x000c, 0x1cf: 0x000c, 0x1d0: 0x000c, 0x1d1: 0x000c,
- 0x1d2: 0x000c, 0x1d3: 0x000c, 0x1d4: 0x000c, 0x1d5: 0x000c, 0x1d6: 0x000c, 0x1d7: 0x000c,
- 0x1d8: 0x000c, 0x1d9: 0x000c, 0x1da: 0x000c, 0x1db: 0x000c, 0x1dc: 0x000c, 0x1dd: 0x000c,
- 0x1de: 0x000c, 0x1df: 0x000c, 0x1e0: 0x000c, 0x1e1: 0x000c, 0x1e2: 0x000c, 0x1e3: 0x000c,
- 0x1e4: 0x000c, 0x1e5: 0x000c, 0x1e6: 0x000c, 0x1e7: 0x000c, 0x1e8: 0x000c, 0x1e9: 0x000c,
- 0x1ea: 0x000c, 0x1eb: 0x000c, 0x1ec: 0x000c, 0x1ed: 0x000c, 0x1ee: 0x000c, 0x1ef: 0x000c,
- 0x1f0: 0x000c, 0x1f1: 0x000c, 0x1f2: 0x000c, 0x1f3: 0x000c, 0x1f4: 0x000c, 0x1f5: 0x000c,
- 0x1f6: 0x000c, 0x1f7: 0x000c, 0x1f8: 0x000c, 0x1f9: 0x000c, 0x1fa: 0x000c, 0x1fb: 0x000c,
- 0x1fc: 0x000c, 0x1fd: 0x000c, 0x1fe: 0x000c, 0x1ff: 0x000c,
- // Block 0x8, offset 0x200
- 0x200: 0x000c, 0x201: 0x000c, 0x202: 0x000c, 0x203: 0x000c, 0x204: 0x000c, 0x205: 0x000c,
- 0x206: 0x000c, 0x207: 0x000c, 0x208: 0x000c, 0x209: 0x000c, 0x20a: 0x000c, 0x20b: 0x000c,
- 0x20c: 0x000c, 0x20d: 0x000c, 0x20e: 0x000c, 0x20f: 0x000c, 0x210: 0x000c, 0x211: 0x000c,
- 0x212: 0x000c, 0x213: 0x000c, 0x214: 0x000c, 0x215: 0x000c, 0x216: 0x000c, 0x217: 0x000c,
- 0x218: 0x000c, 0x219: 0x000c, 0x21a: 0x000c, 0x21b: 0x000c, 0x21c: 0x000c, 0x21d: 0x000c,
- 0x21e: 0x000c, 0x21f: 0x000c, 0x220: 0x000c, 0x221: 0x000c, 0x222: 0x000c, 0x223: 0x000c,
- 0x224: 0x000c, 0x225: 0x000c, 0x226: 0x000c, 0x227: 0x000c, 0x228: 0x000c, 0x229: 0x000c,
- 0x22a: 0x000c, 0x22b: 0x000c, 0x22c: 0x000c, 0x22d: 0x000c, 0x22e: 0x000c, 0x22f: 0x000c,
- 0x234: 0x000a, 0x235: 0x000a,
- 0x23e: 0x000a,
- // Block 0x9, offset 0x240
- 0x244: 0x000a, 0x245: 0x000a,
- 0x247: 0x000a,
- // Block 0xa, offset 0x280
- 0x2b6: 0x000a,
- // Block 0xb, offset 0x2c0
- 0x2c3: 0x000c, 0x2c4: 0x000c, 0x2c5: 0x000c,
- 0x2c6: 0x000c, 0x2c7: 0x000c, 0x2c8: 0x000c, 0x2c9: 0x000c,
- // Block 0xc, offset 0x300
- 0x30a: 0x000a,
- 0x30d: 0x000a, 0x30e: 0x000a, 0x30f: 0x0004, 0x310: 0x0001, 0x311: 0x000c,
- 0x312: 0x000c, 0x313: 0x000c, 0x314: 0x000c, 0x315: 0x000c, 0x316: 0x000c, 0x317: 0x000c,
- 0x318: 0x000c, 0x319: 0x000c, 0x31a: 0x000c, 0x31b: 0x000c, 0x31c: 0x000c, 0x31d: 0x000c,
- 0x31e: 0x000c, 0x31f: 0x000c, 0x320: 0x000c, 0x321: 0x000c, 0x322: 0x000c, 0x323: 0x000c,
- 0x324: 0x000c, 0x325: 0x000c, 0x326: 0x000c, 0x327: 0x000c, 0x328: 0x000c, 0x329: 0x000c,
- 0x32a: 0x000c, 0x32b: 0x000c, 0x32c: 0x000c, 0x32d: 0x000c, 0x32e: 0x000c, 0x32f: 0x000c,
- 0x330: 0x000c, 0x331: 0x000c, 0x332: 0x000c, 0x333: 0x000c, 0x334: 0x000c, 0x335: 0x000c,
- 0x336: 0x000c, 0x337: 0x000c, 0x338: 0x000c, 0x339: 0x000c, 0x33a: 0x000c, 0x33b: 0x000c,
- 0x33c: 0x000c, 0x33d: 0x000c, 0x33e: 0x0001, 0x33f: 0x000c,
- // Block 0xd, offset 0x340
- 0x340: 0x0001, 0x341: 0x000c, 0x342: 0x000c, 0x343: 0x0001, 0x344: 0x000c, 0x345: 0x000c,
- 0x346: 0x0001, 0x347: 0x000c, 0x348: 0x0001, 0x349: 0x0001, 0x34a: 0x0001, 0x34b: 0x0001,
- 0x34c: 0x0001, 0x34d: 0x0001, 0x34e: 0x0001, 0x34f: 0x0001, 0x350: 0x0001, 0x351: 0x0001,
- 0x352: 0x0001, 0x353: 0x0001, 0x354: 0x0001, 0x355: 0x0001, 0x356: 0x0001, 0x357: 0x0001,
- 0x358: 0x0001, 0x359: 0x0001, 0x35a: 0x0001, 0x35b: 0x0001, 0x35c: 0x0001, 0x35d: 0x0001,
- 0x35e: 0x0001, 0x35f: 0x0001, 0x360: 0x0001, 0x361: 0x0001, 0x362: 0x0001, 0x363: 0x0001,
- 0x364: 0x0001, 0x365: 0x0001, 0x366: 0x0001, 0x367: 0x0001, 0x368: 0x0001, 0x369: 0x0001,
- 0x36a: 0x0001, 0x36b: 0x0001, 0x36c: 0x0001, 0x36d: 0x0001, 0x36e: 0x0001, 0x36f: 0x0001,
- 0x370: 0x0001, 0x371: 0x0001, 0x372: 0x0001, 0x373: 0x0001, 0x374: 0x0001, 0x375: 0x0001,
- 0x376: 0x0001, 0x377: 0x0001, 0x378: 0x0001, 0x379: 0x0001, 0x37a: 0x0001, 0x37b: 0x0001,
- 0x37c: 0x0001, 0x37d: 0x0001, 0x37e: 0x0001, 0x37f: 0x0001,
- // Block 0xe, offset 0x380
- 0x380: 0x0005, 0x381: 0x0005, 0x382: 0x0005, 0x383: 0x0005, 0x384: 0x0005, 0x385: 0x0005,
- 0x386: 0x000a, 0x387: 0x000a, 0x388: 0x000d, 0x389: 0x0004, 0x38a: 0x0004, 0x38b: 0x000d,
- 0x38c: 0x0006, 0x38d: 0x000d, 0x38e: 0x000a, 0x38f: 0x000a, 0x390: 0x000c, 0x391: 0x000c,
- 0x392: 0x000c, 0x393: 0x000c, 0x394: 0x000c, 0x395: 0x000c, 0x396: 0x000c, 0x397: 0x000c,
- 0x398: 0x000c, 0x399: 0x000c, 0x39a: 0x000c, 0x39b: 0x000d, 0x39c: 0x000d, 0x39d: 0x000d,
- 0x39e: 0x000d, 0x39f: 0x000d, 0x3a0: 0x000d, 0x3a1: 0x000d, 0x3a2: 0x000d, 0x3a3: 0x000d,
- 0x3a4: 0x000d, 0x3a5: 0x000d, 0x3a6: 0x000d, 0x3a7: 0x000d, 0x3a8: 0x000d, 0x3a9: 0x000d,
- 0x3aa: 0x000d, 0x3ab: 0x000d, 0x3ac: 0x000d, 0x3ad: 0x000d, 0x3ae: 0x000d, 0x3af: 0x000d,
- 0x3b0: 0x000d, 0x3b1: 0x000d, 0x3b2: 0x000d, 0x3b3: 0x000d, 0x3b4: 0x000d, 0x3b5: 0x000d,
- 0x3b6: 0x000d, 0x3b7: 0x000d, 0x3b8: 0x000d, 0x3b9: 0x000d, 0x3ba: 0x000d, 0x3bb: 0x000d,
- 0x3bc: 0x000d, 0x3bd: 0x000d, 0x3be: 0x000d, 0x3bf: 0x000d,
- // Block 0xf, offset 0x3c0
- 0x3c0: 0x000d, 0x3c1: 0x000d, 0x3c2: 0x000d, 0x3c3: 0x000d, 0x3c4: 0x000d, 0x3c5: 0x000d,
- 0x3c6: 0x000d, 0x3c7: 0x000d, 0x3c8: 0x000d, 0x3c9: 0x000d, 0x3ca: 0x000d, 0x3cb: 0x000c,
- 0x3cc: 0x000c, 0x3cd: 0x000c, 0x3ce: 0x000c, 0x3cf: 0x000c, 0x3d0: 0x000c, 0x3d1: 0x000c,
- 0x3d2: 0x000c, 0x3d3: 0x000c, 0x3d4: 0x000c, 0x3d5: 0x000c, 0x3d6: 0x000c, 0x3d7: 0x000c,
- 0x3d8: 0x000c, 0x3d9: 0x000c, 0x3da: 0x000c, 0x3db: 0x000c, 0x3dc: 0x000c, 0x3dd: 0x000c,
- 0x3de: 0x000c, 0x3df: 0x000c, 0x3e0: 0x0005, 0x3e1: 0x0005, 0x3e2: 0x0005, 0x3e3: 0x0005,
- 0x3e4: 0x0005, 0x3e5: 0x0005, 0x3e6: 0x0005, 0x3e7: 0x0005, 0x3e8: 0x0005, 0x3e9: 0x0005,
- 0x3ea: 0x0004, 0x3eb: 0x0005, 0x3ec: 0x0005, 0x3ed: 0x000d, 0x3ee: 0x000d, 0x3ef: 0x000d,
- 0x3f0: 0x000c, 0x3f1: 0x000d, 0x3f2: 0x000d, 0x3f3: 0x000d, 0x3f4: 0x000d, 0x3f5: 0x000d,
- 0x3f6: 0x000d, 0x3f7: 0x000d, 0x3f8: 0x000d, 0x3f9: 0x000d, 0x3fa: 0x000d, 0x3fb: 0x000d,
- 0x3fc: 0x000d, 0x3fd: 0x000d, 0x3fe: 0x000d, 0x3ff: 0x000d,
- // Block 0x10, offset 0x400
- 0x400: 0x000d, 0x401: 0x000d, 0x402: 0x000d, 0x403: 0x000d, 0x404: 0x000d, 0x405: 0x000d,
- 0x406: 0x000d, 0x407: 0x000d, 0x408: 0x000d, 0x409: 0x000d, 0x40a: 0x000d, 0x40b: 0x000d,
- 0x40c: 0x000d, 0x40d: 0x000d, 0x40e: 0x000d, 0x40f: 0x000d, 0x410: 0x000d, 0x411: 0x000d,
- 0x412: 0x000d, 0x413: 0x000d, 0x414: 0x000d, 0x415: 0x000d, 0x416: 0x000d, 0x417: 0x000d,
- 0x418: 0x000d, 0x419: 0x000d, 0x41a: 0x000d, 0x41b: 0x000d, 0x41c: 0x000d, 0x41d: 0x000d,
- 0x41e: 0x000d, 0x41f: 0x000d, 0x420: 0x000d, 0x421: 0x000d, 0x422: 0x000d, 0x423: 0x000d,
- 0x424: 0x000d, 0x425: 0x000d, 0x426: 0x000d, 0x427: 0x000d, 0x428: 0x000d, 0x429: 0x000d,
- 0x42a: 0x000d, 0x42b: 0x000d, 0x42c: 0x000d, 0x42d: 0x000d, 0x42e: 0x000d, 0x42f: 0x000d,
- 0x430: 0x000d, 0x431: 0x000d, 0x432: 0x000d, 0x433: 0x000d, 0x434: 0x000d, 0x435: 0x000d,
- 0x436: 0x000d, 0x437: 0x000d, 0x438: 0x000d, 0x439: 0x000d, 0x43a: 0x000d, 0x43b: 0x000d,
- 0x43c: 0x000d, 0x43d: 0x000d, 0x43e: 0x000d, 0x43f: 0x000d,
- // Block 0x11, offset 0x440
- 0x440: 0x000d, 0x441: 0x000d, 0x442: 0x000d, 0x443: 0x000d, 0x444: 0x000d, 0x445: 0x000d,
- 0x446: 0x000d, 0x447: 0x000d, 0x448: 0x000d, 0x449: 0x000d, 0x44a: 0x000d, 0x44b: 0x000d,
- 0x44c: 0x000d, 0x44d: 0x000d, 0x44e: 0x000d, 0x44f: 0x000d, 0x450: 0x000d, 0x451: 0x000d,
- 0x452: 0x000d, 0x453: 0x000d, 0x454: 0x000d, 0x455: 0x000d, 0x456: 0x000c, 0x457: 0x000c,
- 0x458: 0x000c, 0x459: 0x000c, 0x45a: 0x000c, 0x45b: 0x000c, 0x45c: 0x000c, 0x45d: 0x0005,
- 0x45e: 0x000a, 0x45f: 0x000c, 0x460: 0x000c, 0x461: 0x000c, 0x462: 0x000c, 0x463: 0x000c,
- 0x464: 0x000c, 0x465: 0x000d, 0x466: 0x000d, 0x467: 0x000c, 0x468: 0x000c, 0x469: 0x000a,
- 0x46a: 0x000c, 0x46b: 0x000c, 0x46c: 0x000c, 0x46d: 0x000c, 0x46e: 0x000d, 0x46f: 0x000d,
- 0x470: 0x0002, 0x471: 0x0002, 0x472: 0x0002, 0x473: 0x0002, 0x474: 0x0002, 0x475: 0x0002,
- 0x476: 0x0002, 0x477: 0x0002, 0x478: 0x0002, 0x479: 0x0002, 0x47a: 0x000d, 0x47b: 0x000d,
- 0x47c: 0x000d, 0x47d: 0x000d, 0x47e: 0x000d, 0x47f: 0x000d,
- // Block 0x12, offset 0x480
- 0x480: 0x000d, 0x481: 0x000d, 0x482: 0x000d, 0x483: 0x000d, 0x484: 0x000d, 0x485: 0x000d,
- 0x486: 0x000d, 0x487: 0x000d, 0x488: 0x000d, 0x489: 0x000d, 0x48a: 0x000d, 0x48b: 0x000d,
- 0x48c: 0x000d, 0x48d: 0x000d, 0x48e: 0x000d, 0x48f: 0x000d, 0x490: 0x000d, 0x491: 0x000c,
- 0x492: 0x000d, 0x493: 0x000d, 0x494: 0x000d, 0x495: 0x000d, 0x496: 0x000d, 0x497: 0x000d,
- 0x498: 0x000d, 0x499: 0x000d, 0x49a: 0x000d, 0x49b: 0x000d, 0x49c: 0x000d, 0x49d: 0x000d,
- 0x49e: 0x000d, 0x49f: 0x000d, 0x4a0: 0x000d, 0x4a1: 0x000d, 0x4a2: 0x000d, 0x4a3: 0x000d,
- 0x4a4: 0x000d, 0x4a5: 0x000d, 0x4a6: 0x000d, 0x4a7: 0x000d, 0x4a8: 0x000d, 0x4a9: 0x000d,
- 0x4aa: 0x000d, 0x4ab: 0x000d, 0x4ac: 0x000d, 0x4ad: 0x000d, 0x4ae: 0x000d, 0x4af: 0x000d,
- 0x4b0: 0x000c, 0x4b1: 0x000c, 0x4b2: 0x000c, 0x4b3: 0x000c, 0x4b4: 0x000c, 0x4b5: 0x000c,
- 0x4b6: 0x000c, 0x4b7: 0x000c, 0x4b8: 0x000c, 0x4b9: 0x000c, 0x4ba: 0x000c, 0x4bb: 0x000c,
- 0x4bc: 0x000c, 0x4bd: 0x000c, 0x4be: 0x000c, 0x4bf: 0x000c,
- // Block 0x13, offset 0x4c0
- 0x4c0: 0x000c, 0x4c1: 0x000c, 0x4c2: 0x000c, 0x4c3: 0x000c, 0x4c4: 0x000c, 0x4c5: 0x000c,
- 0x4c6: 0x000c, 0x4c7: 0x000c, 0x4c8: 0x000c, 0x4c9: 0x000c, 0x4ca: 0x000c, 0x4cb: 0x000d,
- 0x4cc: 0x000d, 0x4cd: 0x000d, 0x4ce: 0x000d, 0x4cf: 0x000d, 0x4d0: 0x000d, 0x4d1: 0x000d,
- 0x4d2: 0x000d, 0x4d3: 0x000d, 0x4d4: 0x000d, 0x4d5: 0x000d, 0x4d6: 0x000d, 0x4d7: 0x000d,
- 0x4d8: 0x000d, 0x4d9: 0x000d, 0x4da: 0x000d, 0x4db: 0x000d, 0x4dc: 0x000d, 0x4dd: 0x000d,
- 0x4de: 0x000d, 0x4df: 0x000d, 0x4e0: 0x000d, 0x4e1: 0x000d, 0x4e2: 0x000d, 0x4e3: 0x000d,
- 0x4e4: 0x000d, 0x4e5: 0x000d, 0x4e6: 0x000d, 0x4e7: 0x000d, 0x4e8: 0x000d, 0x4e9: 0x000d,
- 0x4ea: 0x000d, 0x4eb: 0x000d, 0x4ec: 0x000d, 0x4ed: 0x000d, 0x4ee: 0x000d, 0x4ef: 0x000d,
- 0x4f0: 0x000d, 0x4f1: 0x000d, 0x4f2: 0x000d, 0x4f3: 0x000d, 0x4f4: 0x000d, 0x4f5: 0x000d,
- 0x4f6: 0x000d, 0x4f7: 0x000d, 0x4f8: 0x000d, 0x4f9: 0x000d, 0x4fa: 0x000d, 0x4fb: 0x000d,
- 0x4fc: 0x000d, 0x4fd: 0x000d, 0x4fe: 0x000d, 0x4ff: 0x000d,
- // Block 0x14, offset 0x500
- 0x500: 0x000d, 0x501: 0x000d, 0x502: 0x000d, 0x503: 0x000d, 0x504: 0x000d, 0x505: 0x000d,
- 0x506: 0x000d, 0x507: 0x000d, 0x508: 0x000d, 0x509: 0x000d, 0x50a: 0x000d, 0x50b: 0x000d,
- 0x50c: 0x000d, 0x50d: 0x000d, 0x50e: 0x000d, 0x50f: 0x000d, 0x510: 0x000d, 0x511: 0x000d,
- 0x512: 0x000d, 0x513: 0x000d, 0x514: 0x000d, 0x515: 0x000d, 0x516: 0x000d, 0x517: 0x000d,
- 0x518: 0x000d, 0x519: 0x000d, 0x51a: 0x000d, 0x51b: 0x000d, 0x51c: 0x000d, 0x51d: 0x000d,
- 0x51e: 0x000d, 0x51f: 0x000d, 0x520: 0x000d, 0x521: 0x000d, 0x522: 0x000d, 0x523: 0x000d,
- 0x524: 0x000d, 0x525: 0x000d, 0x526: 0x000c, 0x527: 0x000c, 0x528: 0x000c, 0x529: 0x000c,
- 0x52a: 0x000c, 0x52b: 0x000c, 0x52c: 0x000c, 0x52d: 0x000c, 0x52e: 0x000c, 0x52f: 0x000c,
- 0x530: 0x000c, 0x531: 0x000d, 0x532: 0x000d, 0x533: 0x000d, 0x534: 0x000d, 0x535: 0x000d,
- 0x536: 0x000d, 0x537: 0x000d, 0x538: 0x000d, 0x539: 0x000d, 0x53a: 0x000d, 0x53b: 0x000d,
- 0x53c: 0x000d, 0x53d: 0x000d, 0x53e: 0x000d, 0x53f: 0x000d,
- // Block 0x15, offset 0x540
- 0x540: 0x0001, 0x541: 0x0001, 0x542: 0x0001, 0x543: 0x0001, 0x544: 0x0001, 0x545: 0x0001,
- 0x546: 0x0001, 0x547: 0x0001, 0x548: 0x0001, 0x549: 0x0001, 0x54a: 0x0001, 0x54b: 0x0001,
- 0x54c: 0x0001, 0x54d: 0x0001, 0x54e: 0x0001, 0x54f: 0x0001, 0x550: 0x0001, 0x551: 0x0001,
- 0x552: 0x0001, 0x553: 0x0001, 0x554: 0x0001, 0x555: 0x0001, 0x556: 0x0001, 0x557: 0x0001,
- 0x558: 0x0001, 0x559: 0x0001, 0x55a: 0x0001, 0x55b: 0x0001, 0x55c: 0x0001, 0x55d: 0x0001,
- 0x55e: 0x0001, 0x55f: 0x0001, 0x560: 0x0001, 0x561: 0x0001, 0x562: 0x0001, 0x563: 0x0001,
- 0x564: 0x0001, 0x565: 0x0001, 0x566: 0x0001, 0x567: 0x0001, 0x568: 0x0001, 0x569: 0x0001,
- 0x56a: 0x0001, 0x56b: 0x000c, 0x56c: 0x000c, 0x56d: 0x000c, 0x56e: 0x000c, 0x56f: 0x000c,
- 0x570: 0x000c, 0x571: 0x000c, 0x572: 0x000c, 0x573: 0x000c, 0x574: 0x0001, 0x575: 0x0001,
- 0x576: 0x000a, 0x577: 0x000a, 0x578: 0x000a, 0x579: 0x000a, 0x57a: 0x0001, 0x57b: 0x0001,
- 0x57c: 0x0001, 0x57d: 0x000c, 0x57e: 0x0001, 0x57f: 0x0001,
- // Block 0x16, offset 0x580
- 0x580: 0x0001, 0x581: 0x0001, 0x582: 0x0001, 0x583: 0x0001, 0x584: 0x0001, 0x585: 0x0001,
- 0x586: 0x0001, 0x587: 0x0001, 0x588: 0x0001, 0x589: 0x0001, 0x58a: 0x0001, 0x58b: 0x0001,
- 0x58c: 0x0001, 0x58d: 0x0001, 0x58e: 0x0001, 0x58f: 0x0001, 0x590: 0x0001, 0x591: 0x0001,
- 0x592: 0x0001, 0x593: 0x0001, 0x594: 0x0001, 0x595: 0x0001, 0x596: 0x000c, 0x597: 0x000c,
- 0x598: 0x000c, 0x599: 0x000c, 0x59a: 0x0001, 0x59b: 0x000c, 0x59c: 0x000c, 0x59d: 0x000c,
- 0x59e: 0x000c, 0x59f: 0x000c, 0x5a0: 0x000c, 0x5a1: 0x000c, 0x5a2: 0x000c, 0x5a3: 0x000c,
- 0x5a4: 0x0001, 0x5a5: 0x000c, 0x5a6: 0x000c, 0x5a7: 0x000c, 0x5a8: 0x0001, 0x5a9: 0x000c,
- 0x5aa: 0x000c, 0x5ab: 0x000c, 0x5ac: 0x000c, 0x5ad: 0x000c, 0x5ae: 0x0001, 0x5af: 0x0001,
- 0x5b0: 0x0001, 0x5b1: 0x0001, 0x5b2: 0x0001, 0x5b3: 0x0001, 0x5b4: 0x0001, 0x5b5: 0x0001,
- 0x5b6: 0x0001, 0x5b7: 0x0001, 0x5b8: 0x0001, 0x5b9: 0x0001, 0x5ba: 0x0001, 0x5bb: 0x0001,
- 0x5bc: 0x0001, 0x5bd: 0x0001, 0x5be: 0x0001, 0x5bf: 0x0001,
- // Block 0x17, offset 0x5c0
- 0x5c0: 0x0001, 0x5c1: 0x0001, 0x5c2: 0x0001, 0x5c3: 0x0001, 0x5c4: 0x0001, 0x5c5: 0x0001,
- 0x5c6: 0x0001, 0x5c7: 0x0001, 0x5c8: 0x0001, 0x5c9: 0x0001, 0x5ca: 0x0001, 0x5cb: 0x0001,
- 0x5cc: 0x0001, 0x5cd: 0x0001, 0x5ce: 0x0001, 0x5cf: 0x0001, 0x5d0: 0x0001, 0x5d1: 0x0001,
- 0x5d2: 0x0001, 0x5d3: 0x0001, 0x5d4: 0x0001, 0x5d5: 0x0001, 0x5d6: 0x0001, 0x5d7: 0x0001,
- 0x5d8: 0x0001, 0x5d9: 0x000c, 0x5da: 0x000c, 0x5db: 0x000c, 0x5dc: 0x0001, 0x5dd: 0x0001,
- 0x5de: 0x0001, 0x5df: 0x0001, 0x5e0: 0x000d, 0x5e1: 0x000d, 0x5e2: 0x000d, 0x5e3: 0x000d,
- 0x5e4: 0x000d, 0x5e5: 0x000d, 0x5e6: 0x000d, 0x5e7: 0x000d, 0x5e8: 0x000d, 0x5e9: 0x000d,
- 0x5ea: 0x000d, 0x5eb: 0x000d, 0x5ec: 0x000d, 0x5ed: 0x000d, 0x5ee: 0x000d, 0x5ef: 0x000d,
- 0x5f0: 0x0001, 0x5f1: 0x0001, 0x5f2: 0x0001, 0x5f3: 0x0001, 0x5f4: 0x0001, 0x5f5: 0x0001,
- 0x5f6: 0x0001, 0x5f7: 0x0001, 0x5f8: 0x0001, 0x5f9: 0x0001, 0x5fa: 0x0001, 0x5fb: 0x0001,
- 0x5fc: 0x0001, 0x5fd: 0x0001, 0x5fe: 0x0001, 0x5ff: 0x0001,
- // Block 0x18, offset 0x600
- 0x600: 0x0001, 0x601: 0x0001, 0x602: 0x0001, 0x603: 0x0001, 0x604: 0x0001, 0x605: 0x0001,
- 0x606: 0x0001, 0x607: 0x0001, 0x608: 0x0001, 0x609: 0x0001, 0x60a: 0x0001, 0x60b: 0x0001,
- 0x60c: 0x0001, 0x60d: 0x0001, 0x60e: 0x0001, 0x60f: 0x0001, 0x610: 0x0001, 0x611: 0x0001,
- 0x612: 0x0001, 0x613: 0x0001, 0x614: 0x0001, 0x615: 0x0001, 0x616: 0x0001, 0x617: 0x0001,
- 0x618: 0x0001, 0x619: 0x0001, 0x61a: 0x0001, 0x61b: 0x0001, 0x61c: 0x0001, 0x61d: 0x0001,
- 0x61e: 0x0001, 0x61f: 0x0001, 0x620: 0x000d, 0x621: 0x000d, 0x622: 0x000d, 0x623: 0x000d,
- 0x624: 0x000d, 0x625: 0x000d, 0x626: 0x000d, 0x627: 0x000d, 0x628: 0x000d, 0x629: 0x000d,
- 0x62a: 0x000d, 0x62b: 0x000d, 0x62c: 0x000d, 0x62d: 0x000d, 0x62e: 0x000d, 0x62f: 0x000d,
- 0x630: 0x000d, 0x631: 0x000d, 0x632: 0x000d, 0x633: 0x000d, 0x634: 0x000d, 0x635: 0x000d,
- 0x636: 0x000d, 0x637: 0x000d, 0x638: 0x000d, 0x639: 0x000d, 0x63a: 0x000d, 0x63b: 0x000d,
- 0x63c: 0x000d, 0x63d: 0x000d, 0x63e: 0x000d, 0x63f: 0x000d,
- // Block 0x19, offset 0x640
- 0x640: 0x000d, 0x641: 0x000d, 0x642: 0x000d, 0x643: 0x000d, 0x644: 0x000d, 0x645: 0x000d,
- 0x646: 0x000d, 0x647: 0x000d, 0x648: 0x000d, 0x649: 0x000d, 0x64a: 0x000d, 0x64b: 0x000d,
- 0x64c: 0x000d, 0x64d: 0x000d, 0x64e: 0x000d, 0x64f: 0x000d, 0x650: 0x000d, 0x651: 0x000d,
- 0x652: 0x000d, 0x653: 0x000c, 0x654: 0x000c, 0x655: 0x000c, 0x656: 0x000c, 0x657: 0x000c,
- 0x658: 0x000c, 0x659: 0x000c, 0x65a: 0x000c, 0x65b: 0x000c, 0x65c: 0x000c, 0x65d: 0x000c,
- 0x65e: 0x000c, 0x65f: 0x000c, 0x660: 0x000c, 0x661: 0x000c, 0x662: 0x0005, 0x663: 0x000c,
- 0x664: 0x000c, 0x665: 0x000c, 0x666: 0x000c, 0x667: 0x000c, 0x668: 0x000c, 0x669: 0x000c,
- 0x66a: 0x000c, 0x66b: 0x000c, 0x66c: 0x000c, 0x66d: 0x000c, 0x66e: 0x000c, 0x66f: 0x000c,
- 0x670: 0x000c, 0x671: 0x000c, 0x672: 0x000c, 0x673: 0x000c, 0x674: 0x000c, 0x675: 0x000c,
- 0x676: 0x000c, 0x677: 0x000c, 0x678: 0x000c, 0x679: 0x000c, 0x67a: 0x000c, 0x67b: 0x000c,
- 0x67c: 0x000c, 0x67d: 0x000c, 0x67e: 0x000c, 0x67f: 0x000c,
- // Block 0x1a, offset 0x680
- 0x680: 0x000c, 0x681: 0x000c, 0x682: 0x000c,
- 0x6ba: 0x000c,
- 0x6bc: 0x000c,
- // Block 0x1b, offset 0x6c0
- 0x6c1: 0x000c, 0x6c2: 0x000c, 0x6c3: 0x000c, 0x6c4: 0x000c, 0x6c5: 0x000c,
- 0x6c6: 0x000c, 0x6c7: 0x000c, 0x6c8: 0x000c,
- 0x6cd: 0x000c, 0x6d1: 0x000c,
- 0x6d2: 0x000c, 0x6d3: 0x000c, 0x6d4: 0x000c, 0x6d5: 0x000c, 0x6d6: 0x000c, 0x6d7: 0x000c,
- 0x6e2: 0x000c, 0x6e3: 0x000c,
- // Block 0x1c, offset 0x700
- 0x701: 0x000c,
- 0x73c: 0x000c,
- // Block 0x1d, offset 0x740
- 0x741: 0x000c, 0x742: 0x000c, 0x743: 0x000c, 0x744: 0x000c,
- 0x74d: 0x000c,
- 0x762: 0x000c, 0x763: 0x000c,
- 0x772: 0x0004, 0x773: 0x0004,
- 0x77b: 0x0004,
- 0x77e: 0x000c,
- // Block 0x1e, offset 0x780
- 0x781: 0x000c, 0x782: 0x000c,
- 0x7bc: 0x000c,
- // Block 0x1f, offset 0x7c0
- 0x7c1: 0x000c, 0x7c2: 0x000c,
- 0x7c7: 0x000c, 0x7c8: 0x000c, 0x7cb: 0x000c,
- 0x7cc: 0x000c, 0x7cd: 0x000c, 0x7d1: 0x000c,
- 0x7f0: 0x000c, 0x7f1: 0x000c, 0x7f5: 0x000c,
- // Block 0x20, offset 0x800
- 0x801: 0x000c, 0x802: 0x000c, 0x803: 0x000c, 0x804: 0x000c, 0x805: 0x000c,
- 0x807: 0x000c, 0x808: 0x000c,
- 0x80d: 0x000c,
- 0x822: 0x000c, 0x823: 0x000c,
- 0x831: 0x0004,
- 0x83a: 0x000c, 0x83b: 0x000c,
- 0x83c: 0x000c, 0x83d: 0x000c, 0x83e: 0x000c, 0x83f: 0x000c,
- // Block 0x21, offset 0x840
- 0x841: 0x000c,
- 0x87c: 0x000c, 0x87f: 0x000c,
- // Block 0x22, offset 0x880
- 0x881: 0x000c, 0x882: 0x000c, 0x883: 0x000c, 0x884: 0x000c,
- 0x88d: 0x000c,
- 0x895: 0x000c, 0x896: 0x000c,
- 0x8a2: 0x000c, 0x8a3: 0x000c,
- // Block 0x23, offset 0x8c0
- 0x8c2: 0x000c,
- // Block 0x24, offset 0x900
- 0x900: 0x000c,
- 0x90d: 0x000c,
- 0x933: 0x000a, 0x934: 0x000a, 0x935: 0x000a,
- 0x936: 0x000a, 0x937: 0x000a, 0x938: 0x000a, 0x939: 0x0004, 0x93a: 0x000a,
- // Block 0x25, offset 0x940
- 0x940: 0x000c, 0x944: 0x000c,
- 0x97e: 0x000c, 0x97f: 0x000c,
- // Block 0x26, offset 0x980
- 0x980: 0x000c,
- 0x986: 0x000c, 0x987: 0x000c, 0x988: 0x000c, 0x98a: 0x000c, 0x98b: 0x000c,
- 0x98c: 0x000c, 0x98d: 0x000c,
- 0x995: 0x000c, 0x996: 0x000c,
- 0x9a2: 0x000c, 0x9a3: 0x000c,
- 0x9b8: 0x000a, 0x9b9: 0x000a, 0x9ba: 0x000a, 0x9bb: 0x000a,
- 0x9bc: 0x000a, 0x9bd: 0x000a, 0x9be: 0x000a,
- // Block 0x27, offset 0x9c0
- 0x9cc: 0x000c, 0x9cd: 0x000c,
- 0x9e2: 0x000c, 0x9e3: 0x000c,
- // Block 0x28, offset 0xa00
- 0xa00: 0x000c, 0xa01: 0x000c,
- 0xa3b: 0x000c,
- 0xa3c: 0x000c,
- // Block 0x29, offset 0xa40
- 0xa41: 0x000c, 0xa42: 0x000c, 0xa43: 0x000c, 0xa44: 0x000c,
- 0xa4d: 0x000c,
- 0xa62: 0x000c, 0xa63: 0x000c,
- // Block 0x2a, offset 0xa80
- 0xa81: 0x000c,
- // Block 0x2b, offset 0xac0
- 0xaca: 0x000c,
- 0xad2: 0x000c, 0xad3: 0x000c, 0xad4: 0x000c, 0xad6: 0x000c,
- // Block 0x2c, offset 0xb00
- 0xb31: 0x000c, 0xb34: 0x000c, 0xb35: 0x000c,
- 0xb36: 0x000c, 0xb37: 0x000c, 0xb38: 0x000c, 0xb39: 0x000c, 0xb3a: 0x000c,
- 0xb3f: 0x0004,
- // Block 0x2d, offset 0xb40
- 0xb47: 0x000c, 0xb48: 0x000c, 0xb49: 0x000c, 0xb4a: 0x000c, 0xb4b: 0x000c,
- 0xb4c: 0x000c, 0xb4d: 0x000c, 0xb4e: 0x000c,
- // Block 0x2e, offset 0xb80
- 0xbb1: 0x000c, 0xbb4: 0x000c, 0xbb5: 0x000c,
- 0xbb6: 0x000c, 0xbb7: 0x000c, 0xbb8: 0x000c, 0xbb9: 0x000c, 0xbba: 0x000c, 0xbbb: 0x000c,
- 0xbbc: 0x000c,
- // Block 0x2f, offset 0xbc0
- 0xbc8: 0x000c, 0xbc9: 0x000c, 0xbca: 0x000c, 0xbcb: 0x000c,
- 0xbcc: 0x000c, 0xbcd: 0x000c,
- // Block 0x30, offset 0xc00
- 0xc18: 0x000c, 0xc19: 0x000c,
- 0xc35: 0x000c,
- 0xc37: 0x000c, 0xc39: 0x000c, 0xc3a: 0x003a, 0xc3b: 0x002a,
- 0xc3c: 0x003a, 0xc3d: 0x002a,
- // Block 0x31, offset 0xc40
- 0xc71: 0x000c, 0xc72: 0x000c, 0xc73: 0x000c, 0xc74: 0x000c, 0xc75: 0x000c,
- 0xc76: 0x000c, 0xc77: 0x000c, 0xc78: 0x000c, 0xc79: 0x000c, 0xc7a: 0x000c, 0xc7b: 0x000c,
- 0xc7c: 0x000c, 0xc7d: 0x000c, 0xc7e: 0x000c,
- // Block 0x32, offset 0xc80
- 0xc80: 0x000c, 0xc81: 0x000c, 0xc82: 0x000c, 0xc83: 0x000c, 0xc84: 0x000c,
- 0xc86: 0x000c, 0xc87: 0x000c,
- 0xc8d: 0x000c, 0xc8e: 0x000c, 0xc8f: 0x000c, 0xc90: 0x000c, 0xc91: 0x000c,
- 0xc92: 0x000c, 0xc93: 0x000c, 0xc94: 0x000c, 0xc95: 0x000c, 0xc96: 0x000c, 0xc97: 0x000c,
- 0xc99: 0x000c, 0xc9a: 0x000c, 0xc9b: 0x000c, 0xc9c: 0x000c, 0xc9d: 0x000c,
- 0xc9e: 0x000c, 0xc9f: 0x000c, 0xca0: 0x000c, 0xca1: 0x000c, 0xca2: 0x000c, 0xca3: 0x000c,
- 0xca4: 0x000c, 0xca5: 0x000c, 0xca6: 0x000c, 0xca7: 0x000c, 0xca8: 0x000c, 0xca9: 0x000c,
- 0xcaa: 0x000c, 0xcab: 0x000c, 0xcac: 0x000c, 0xcad: 0x000c, 0xcae: 0x000c, 0xcaf: 0x000c,
- 0xcb0: 0x000c, 0xcb1: 0x000c, 0xcb2: 0x000c, 0xcb3: 0x000c, 0xcb4: 0x000c, 0xcb5: 0x000c,
- 0xcb6: 0x000c, 0xcb7: 0x000c, 0xcb8: 0x000c, 0xcb9: 0x000c, 0xcba: 0x000c, 0xcbb: 0x000c,
- 0xcbc: 0x000c,
- // Block 0x33, offset 0xcc0
- 0xcc6: 0x000c,
- // Block 0x34, offset 0xd00
- 0xd2d: 0x000c, 0xd2e: 0x000c, 0xd2f: 0x000c,
- 0xd30: 0x000c, 0xd32: 0x000c, 0xd33: 0x000c, 0xd34: 0x000c, 0xd35: 0x000c,
- 0xd36: 0x000c, 0xd37: 0x000c, 0xd39: 0x000c, 0xd3a: 0x000c,
- 0xd3d: 0x000c, 0xd3e: 0x000c,
- // Block 0x35, offset 0xd40
- 0xd58: 0x000c, 0xd59: 0x000c,
- 0xd5e: 0x000c, 0xd5f: 0x000c, 0xd60: 0x000c,
- 0xd71: 0x000c, 0xd72: 0x000c, 0xd73: 0x000c, 0xd74: 0x000c,
- // Block 0x36, offset 0xd80
- 0xd82: 0x000c, 0xd85: 0x000c,
- 0xd86: 0x000c,
- 0xd8d: 0x000c,
- 0xd9d: 0x000c,
- // Block 0x37, offset 0xdc0
- 0xddd: 0x000c,
- 0xdde: 0x000c, 0xddf: 0x000c,
- // Block 0x38, offset 0xe00
- 0xe10: 0x000a, 0xe11: 0x000a,
- 0xe12: 0x000a, 0xe13: 0x000a, 0xe14: 0x000a, 0xe15: 0x000a, 0xe16: 0x000a, 0xe17: 0x000a,
- 0xe18: 0x000a, 0xe19: 0x000a,
- // Block 0x39, offset 0xe40
- 0xe40: 0x000a,
- // Block 0x3a, offset 0xe80
- 0xe80: 0x0009,
- 0xe9b: 0x007a, 0xe9c: 0x006a,
- // Block 0x3b, offset 0xec0
- 0xed2: 0x000c, 0xed3: 0x000c, 0xed4: 0x000c,
- 0xef2: 0x000c, 0xef3: 0x000c, 0xef4: 0x000c,
- // Block 0x3c, offset 0xf00
- 0xf12: 0x000c, 0xf13: 0x000c,
- 0xf32: 0x000c, 0xf33: 0x000c,
- // Block 0x3d, offset 0xf40
- 0xf74: 0x000c, 0xf75: 0x000c,
- 0xf77: 0x000c, 0xf78: 0x000c, 0xf79: 0x000c, 0xf7a: 0x000c, 0xf7b: 0x000c,
- 0xf7c: 0x000c, 0xf7d: 0x000c,
- // Block 0x3e, offset 0xf80
- 0xf86: 0x000c, 0xf89: 0x000c, 0xf8a: 0x000c, 0xf8b: 0x000c,
- 0xf8c: 0x000c, 0xf8d: 0x000c, 0xf8e: 0x000c, 0xf8f: 0x000c, 0xf90: 0x000c, 0xf91: 0x000c,
- 0xf92: 0x000c, 0xf93: 0x000c,
- 0xf9b: 0x0004, 0xf9d: 0x000c,
- 0xfb0: 0x000a, 0xfb1: 0x000a, 0xfb2: 0x000a, 0xfb3: 0x000a, 0xfb4: 0x000a, 0xfb5: 0x000a,
- 0xfb6: 0x000a, 0xfb7: 0x000a, 0xfb8: 0x000a, 0xfb9: 0x000a,
- // Block 0x3f, offset 0xfc0
- 0xfc0: 0x000a, 0xfc1: 0x000a, 0xfc2: 0x000a, 0xfc3: 0x000a, 0xfc4: 0x000a, 0xfc5: 0x000a,
- 0xfc6: 0x000a, 0xfc7: 0x000a, 0xfc8: 0x000a, 0xfc9: 0x000a, 0xfca: 0x000a, 0xfcb: 0x000c,
- 0xfcc: 0x000c, 0xfcd: 0x000c, 0xfce: 0x000b,
- // Block 0x40, offset 0x1000
- 0x1005: 0x000c,
- 0x1006: 0x000c,
- 0x1029: 0x000c,
- // Block 0x41, offset 0x1040
- 0x1060: 0x000c, 0x1061: 0x000c, 0x1062: 0x000c,
- 0x1067: 0x000c, 0x1068: 0x000c,
- 0x1072: 0x000c,
- 0x1079: 0x000c, 0x107a: 0x000c, 0x107b: 0x000c,
- // Block 0x42, offset 0x1080
- 0x1080: 0x000a, 0x1084: 0x000a, 0x1085: 0x000a,
- // Block 0x43, offset 0x10c0
- 0x10de: 0x000a, 0x10df: 0x000a, 0x10e0: 0x000a, 0x10e1: 0x000a, 0x10e2: 0x000a, 0x10e3: 0x000a,
- 0x10e4: 0x000a, 0x10e5: 0x000a, 0x10e6: 0x000a, 0x10e7: 0x000a, 0x10e8: 0x000a, 0x10e9: 0x000a,
- 0x10ea: 0x000a, 0x10eb: 0x000a, 0x10ec: 0x000a, 0x10ed: 0x000a, 0x10ee: 0x000a, 0x10ef: 0x000a,
- 0x10f0: 0x000a, 0x10f1: 0x000a, 0x10f2: 0x000a, 0x10f3: 0x000a, 0x10f4: 0x000a, 0x10f5: 0x000a,
- 0x10f6: 0x000a, 0x10f7: 0x000a, 0x10f8: 0x000a, 0x10f9: 0x000a, 0x10fa: 0x000a, 0x10fb: 0x000a,
- 0x10fc: 0x000a, 0x10fd: 0x000a, 0x10fe: 0x000a, 0x10ff: 0x000a,
- // Block 0x44, offset 0x1100
- 0x1117: 0x000c,
- 0x1118: 0x000c, 0x111b: 0x000c,
- // Block 0x45, offset 0x1140
- 0x1156: 0x000c,
- 0x1158: 0x000c, 0x1159: 0x000c, 0x115a: 0x000c, 0x115b: 0x000c, 0x115c: 0x000c, 0x115d: 0x000c,
- 0x115e: 0x000c, 0x1160: 0x000c, 0x1162: 0x000c,
- 0x1165: 0x000c, 0x1166: 0x000c, 0x1167: 0x000c, 0x1168: 0x000c, 0x1169: 0x000c,
- 0x116a: 0x000c, 0x116b: 0x000c, 0x116c: 0x000c,
- 0x1173: 0x000c, 0x1174: 0x000c, 0x1175: 0x000c,
- 0x1176: 0x000c, 0x1177: 0x000c, 0x1178: 0x000c, 0x1179: 0x000c, 0x117a: 0x000c, 0x117b: 0x000c,
- 0x117c: 0x000c, 0x117f: 0x000c,
- // Block 0x46, offset 0x1180
- 0x11b0: 0x000c, 0x11b1: 0x000c, 0x11b2: 0x000c, 0x11b3: 0x000c, 0x11b4: 0x000c, 0x11b5: 0x000c,
- 0x11b6: 0x000c, 0x11b7: 0x000c, 0x11b8: 0x000c, 0x11b9: 0x000c, 0x11ba: 0x000c, 0x11bb: 0x000c,
- 0x11bc: 0x000c, 0x11bd: 0x000c, 0x11be: 0x000c, 0x11bf: 0x000c,
- // Block 0x47, offset 0x11c0
- 0x11c0: 0x000c,
- // Block 0x48, offset 0x1200
- 0x1200: 0x000c, 0x1201: 0x000c, 0x1202: 0x000c, 0x1203: 0x000c,
- 0x1234: 0x000c,
- 0x1236: 0x000c, 0x1237: 0x000c, 0x1238: 0x000c, 0x1239: 0x000c, 0x123a: 0x000c,
- 0x123c: 0x000c,
- // Block 0x49, offset 0x1240
- 0x1242: 0x000c,
- 0x126b: 0x000c, 0x126c: 0x000c, 0x126d: 0x000c, 0x126e: 0x000c, 0x126f: 0x000c,
- 0x1270: 0x000c, 0x1271: 0x000c, 0x1272: 0x000c, 0x1273: 0x000c,
- // Block 0x4a, offset 0x1280
- 0x1280: 0x000c, 0x1281: 0x000c,
- 0x12a2: 0x000c, 0x12a3: 0x000c,
- 0x12a4: 0x000c, 0x12a5: 0x000c, 0x12a8: 0x000c, 0x12a9: 0x000c,
- 0x12ab: 0x000c, 0x12ac: 0x000c, 0x12ad: 0x000c,
- // Block 0x4b, offset 0x12c0
- 0x12e6: 0x000c, 0x12e8: 0x000c, 0x12e9: 0x000c,
- 0x12ed: 0x000c, 0x12ef: 0x000c,
- 0x12f0: 0x000c, 0x12f1: 0x000c,
- // Block 0x4c, offset 0x1300
- 0x132c: 0x000c, 0x132d: 0x000c, 0x132e: 0x000c, 0x132f: 0x000c,
- 0x1330: 0x000c, 0x1331: 0x000c, 0x1332: 0x000c, 0x1333: 0x000c,
- 0x1336: 0x000c, 0x1337: 0x000c,
- // Block 0x4d, offset 0x1340
- 0x1350: 0x000c, 0x1351: 0x000c,
- 0x1352: 0x000c, 0x1354: 0x000c, 0x1355: 0x000c, 0x1356: 0x000c, 0x1357: 0x000c,
- 0x1358: 0x000c, 0x1359: 0x000c, 0x135a: 0x000c, 0x135b: 0x000c, 0x135c: 0x000c, 0x135d: 0x000c,
- 0x135e: 0x000c, 0x135f: 0x000c, 0x1360: 0x000c, 0x1362: 0x000c, 0x1363: 0x000c,
- 0x1364: 0x000c, 0x1365: 0x000c, 0x1366: 0x000c, 0x1367: 0x000c, 0x1368: 0x000c,
- 0x136d: 0x000c,
- 0x1374: 0x000c,
- 0x1378: 0x000c, 0x1379: 0x000c,
- // Block 0x4e, offset 0x1380
- 0x1380: 0x000c, 0x1381: 0x000c, 0x1382: 0x000c, 0x1383: 0x000c, 0x1384: 0x000c, 0x1385: 0x000c,
- 0x1386: 0x000c, 0x1387: 0x000c, 0x1388: 0x000c, 0x1389: 0x000c, 0x138a: 0x000c, 0x138b: 0x000c,
- 0x138c: 0x000c, 0x138d: 0x000c, 0x138e: 0x000c, 0x138f: 0x000c, 0x1390: 0x000c, 0x1391: 0x000c,
- 0x1392: 0x000c, 0x1393: 0x000c, 0x1394: 0x000c, 0x1395: 0x000c, 0x1396: 0x000c, 0x1397: 0x000c,
- 0x1398: 0x000c, 0x1399: 0x000c, 0x139a: 0x000c, 0x139b: 0x000c, 0x139c: 0x000c, 0x139d: 0x000c,
- 0x139e: 0x000c, 0x139f: 0x000c, 0x13a0: 0x000c, 0x13a1: 0x000c, 0x13a2: 0x000c, 0x13a3: 0x000c,
- 0x13a4: 0x000c, 0x13a5: 0x000c, 0x13a6: 0x000c, 0x13a7: 0x000c, 0x13a8: 0x000c, 0x13a9: 0x000c,
- 0x13aa: 0x000c, 0x13ab: 0x000c, 0x13ac: 0x000c, 0x13ad: 0x000c, 0x13ae: 0x000c, 0x13af: 0x000c,
- 0x13b0: 0x000c, 0x13b1: 0x000c, 0x13b2: 0x000c, 0x13b3: 0x000c, 0x13b4: 0x000c, 0x13b5: 0x000c,
- 0x13b6: 0x000c, 0x13b7: 0x000c, 0x13b8: 0x000c, 0x13b9: 0x000c, 0x13bb: 0x000c,
- 0x13bc: 0x000c, 0x13bd: 0x000c, 0x13be: 0x000c, 0x13bf: 0x000c,
- // Block 0x4f, offset 0x13c0
- 0x13fd: 0x000a, 0x13ff: 0x000a,
- // Block 0x50, offset 0x1400
- 0x1400: 0x000a, 0x1401: 0x000a,
- 0x140d: 0x000a, 0x140e: 0x000a, 0x140f: 0x000a,
- 0x141d: 0x000a,
- 0x141e: 0x000a, 0x141f: 0x000a,
- 0x142d: 0x000a, 0x142e: 0x000a, 0x142f: 0x000a,
- 0x143d: 0x000a, 0x143e: 0x000a,
- // Block 0x51, offset 0x1440
- 0x1440: 0x0009, 0x1441: 0x0009, 0x1442: 0x0009, 0x1443: 0x0009, 0x1444: 0x0009, 0x1445: 0x0009,
- 0x1446: 0x0009, 0x1447: 0x0009, 0x1448: 0x0009, 0x1449: 0x0009, 0x144a: 0x0009, 0x144b: 0x000b,
- 0x144c: 0x000b, 0x144d: 0x000b, 0x144f: 0x0001, 0x1450: 0x000a, 0x1451: 0x000a,
- 0x1452: 0x000a, 0x1453: 0x000a, 0x1454: 0x000a, 0x1455: 0x000a, 0x1456: 0x000a, 0x1457: 0x000a,
- 0x1458: 0x000a, 0x1459: 0x000a, 0x145a: 0x000a, 0x145b: 0x000a, 0x145c: 0x000a, 0x145d: 0x000a,
- 0x145e: 0x000a, 0x145f: 0x000a, 0x1460: 0x000a, 0x1461: 0x000a, 0x1462: 0x000a, 0x1463: 0x000a,
- 0x1464: 0x000a, 0x1465: 0x000a, 0x1466: 0x000a, 0x1467: 0x000a, 0x1468: 0x0009, 0x1469: 0x0007,
- 0x146a: 0x000e, 0x146b: 0x000e, 0x146c: 0x000e, 0x146d: 0x000e, 0x146e: 0x000e, 0x146f: 0x0006,
- 0x1470: 0x0004, 0x1471: 0x0004, 0x1472: 0x0004, 0x1473: 0x0004, 0x1474: 0x0004, 0x1475: 0x000a,
- 0x1476: 0x000a, 0x1477: 0x000a, 0x1478: 0x000a, 0x1479: 0x000a, 0x147a: 0x000a, 0x147b: 0x000a,
- 0x147c: 0x000a, 0x147d: 0x000a, 0x147e: 0x000a, 0x147f: 0x000a,
- // Block 0x52, offset 0x1480
- 0x1480: 0x000a, 0x1481: 0x000a, 0x1482: 0x000a, 0x1483: 0x000a, 0x1484: 0x0006, 0x1485: 0x009a,
- 0x1486: 0x008a, 0x1487: 0x000a, 0x1488: 0x000a, 0x1489: 0x000a, 0x148a: 0x000a, 0x148b: 0x000a,
- 0x148c: 0x000a, 0x148d: 0x000a, 0x148e: 0x000a, 0x148f: 0x000a, 0x1490: 0x000a, 0x1491: 0x000a,
- 0x1492: 0x000a, 0x1493: 0x000a, 0x1494: 0x000a, 0x1495: 0x000a, 0x1496: 0x000a, 0x1497: 0x000a,
- 0x1498: 0x000a, 0x1499: 0x000a, 0x149a: 0x000a, 0x149b: 0x000a, 0x149c: 0x000a, 0x149d: 0x000a,
- 0x149e: 0x000a, 0x149f: 0x0009, 0x14a0: 0x000b, 0x14a1: 0x000b, 0x14a2: 0x000b, 0x14a3: 0x000b,
- 0x14a4: 0x000b, 0x14a5: 0x000b, 0x14a6: 0x000e, 0x14a7: 0x000e, 0x14a8: 0x000e, 0x14a9: 0x000e,
- 0x14aa: 0x000b, 0x14ab: 0x000b, 0x14ac: 0x000b, 0x14ad: 0x000b, 0x14ae: 0x000b, 0x14af: 0x000b,
- 0x14b0: 0x0002, 0x14b4: 0x0002, 0x14b5: 0x0002,
- 0x14b6: 0x0002, 0x14b7: 0x0002, 0x14b8: 0x0002, 0x14b9: 0x0002, 0x14ba: 0x0003, 0x14bb: 0x0003,
- 0x14bc: 0x000a, 0x14bd: 0x009a, 0x14be: 0x008a,
- // Block 0x53, offset 0x14c0
- 0x14c0: 0x0002, 0x14c1: 0x0002, 0x14c2: 0x0002, 0x14c3: 0x0002, 0x14c4: 0x0002, 0x14c5: 0x0002,
- 0x14c6: 0x0002, 0x14c7: 0x0002, 0x14c8: 0x0002, 0x14c9: 0x0002, 0x14ca: 0x0003, 0x14cb: 0x0003,
- 0x14cc: 0x000a, 0x14cd: 0x009a, 0x14ce: 0x008a,
- 0x14e0: 0x0004, 0x14e1: 0x0004, 0x14e2: 0x0004, 0x14e3: 0x0004,
- 0x14e4: 0x0004, 0x14e5: 0x0004, 0x14e6: 0x0004, 0x14e7: 0x0004, 0x14e8: 0x0004, 0x14e9: 0x0004,
- 0x14ea: 0x0004, 0x14eb: 0x0004, 0x14ec: 0x0004, 0x14ed: 0x0004, 0x14ee: 0x0004, 0x14ef: 0x0004,
- 0x14f0: 0x0004, 0x14f1: 0x0004, 0x14f2: 0x0004, 0x14f3: 0x0004, 0x14f4: 0x0004, 0x14f5: 0x0004,
- 0x14f6: 0x0004, 0x14f7: 0x0004, 0x14f8: 0x0004, 0x14f9: 0x0004, 0x14fa: 0x0004, 0x14fb: 0x0004,
- 0x14fc: 0x0004, 0x14fd: 0x0004, 0x14fe: 0x0004, 0x14ff: 0x0004,
- // Block 0x54, offset 0x1500
- 0x1500: 0x0004, 0x1501: 0x0004, 0x1502: 0x0004, 0x1503: 0x0004, 0x1504: 0x0004, 0x1505: 0x0004,
- 0x1506: 0x0004, 0x1507: 0x0004, 0x1508: 0x0004, 0x1509: 0x0004, 0x150a: 0x0004, 0x150b: 0x0004,
- 0x150c: 0x0004, 0x150d: 0x0004, 0x150e: 0x0004, 0x150f: 0x0004, 0x1510: 0x000c, 0x1511: 0x000c,
- 0x1512: 0x000c, 0x1513: 0x000c, 0x1514: 0x000c, 0x1515: 0x000c, 0x1516: 0x000c, 0x1517: 0x000c,
- 0x1518: 0x000c, 0x1519: 0x000c, 0x151a: 0x000c, 0x151b: 0x000c, 0x151c: 0x000c, 0x151d: 0x000c,
- 0x151e: 0x000c, 0x151f: 0x000c, 0x1520: 0x000c, 0x1521: 0x000c, 0x1522: 0x000c, 0x1523: 0x000c,
- 0x1524: 0x000c, 0x1525: 0x000c, 0x1526: 0x000c, 0x1527: 0x000c, 0x1528: 0x000c, 0x1529: 0x000c,
- 0x152a: 0x000c, 0x152b: 0x000c, 0x152c: 0x000c, 0x152d: 0x000c, 0x152e: 0x000c, 0x152f: 0x000c,
- 0x1530: 0x000c,
- // Block 0x55, offset 0x1540
- 0x1540: 0x000a, 0x1541: 0x000a, 0x1543: 0x000a, 0x1544: 0x000a, 0x1545: 0x000a,
- 0x1546: 0x000a, 0x1548: 0x000a, 0x1549: 0x000a,
- 0x1554: 0x000a, 0x1556: 0x000a, 0x1557: 0x000a,
- 0x1558: 0x000a,
- 0x155e: 0x000a, 0x155f: 0x000a, 0x1560: 0x000a, 0x1561: 0x000a, 0x1562: 0x000a, 0x1563: 0x000a,
- 0x1565: 0x000a, 0x1567: 0x000a, 0x1569: 0x000a,
- 0x156e: 0x0004,
- 0x157a: 0x000a, 0x157b: 0x000a,
- // Block 0x56, offset 0x1580
- 0x1580: 0x000a, 0x1581: 0x000a, 0x1582: 0x000a, 0x1583: 0x000a, 0x1584: 0x000a,
- 0x158a: 0x000a, 0x158b: 0x000a,
- 0x158c: 0x000a, 0x158d: 0x000a, 0x1590: 0x000a, 0x1591: 0x000a,
- 0x1592: 0x000a, 0x1593: 0x000a, 0x1594: 0x000a, 0x1595: 0x000a, 0x1596: 0x000a, 0x1597: 0x000a,
- 0x1598: 0x000a, 0x1599: 0x000a, 0x159a: 0x000a, 0x159b: 0x000a, 0x159c: 0x000a, 0x159d: 0x000a,
- 0x159e: 0x000a, 0x159f: 0x000a,
- // Block 0x57, offset 0x15c0
- 0x15c9: 0x000a, 0x15ca: 0x000a, 0x15cb: 0x000a,
- 0x15d0: 0x000a, 0x15d1: 0x000a,
- 0x15d2: 0x000a, 0x15d3: 0x000a, 0x15d4: 0x000a, 0x15d5: 0x000a, 0x15d6: 0x000a, 0x15d7: 0x000a,
- 0x15d8: 0x000a, 0x15d9: 0x000a, 0x15da: 0x000a, 0x15db: 0x000a, 0x15dc: 0x000a, 0x15dd: 0x000a,
- 0x15de: 0x000a, 0x15df: 0x000a, 0x15e0: 0x000a, 0x15e1: 0x000a, 0x15e2: 0x000a, 0x15e3: 0x000a,
- 0x15e4: 0x000a, 0x15e5: 0x000a, 0x15e6: 0x000a, 0x15e7: 0x000a, 0x15e8: 0x000a, 0x15e9: 0x000a,
- 0x15ea: 0x000a, 0x15eb: 0x000a, 0x15ec: 0x000a, 0x15ed: 0x000a, 0x15ee: 0x000a, 0x15ef: 0x000a,
- 0x15f0: 0x000a, 0x15f1: 0x000a, 0x15f2: 0x000a, 0x15f3: 0x000a, 0x15f4: 0x000a, 0x15f5: 0x000a,
- 0x15f6: 0x000a, 0x15f7: 0x000a, 0x15f8: 0x000a, 0x15f9: 0x000a, 0x15fa: 0x000a, 0x15fb: 0x000a,
- 0x15fc: 0x000a, 0x15fd: 0x000a, 0x15fe: 0x000a, 0x15ff: 0x000a,
- // Block 0x58, offset 0x1600
- 0x1600: 0x000a, 0x1601: 0x000a, 0x1602: 0x000a, 0x1603: 0x000a, 0x1604: 0x000a, 0x1605: 0x000a,
- 0x1606: 0x000a, 0x1607: 0x000a, 0x1608: 0x000a, 0x1609: 0x000a, 0x160a: 0x000a, 0x160b: 0x000a,
- 0x160c: 0x000a, 0x160d: 0x000a, 0x160e: 0x000a, 0x160f: 0x000a, 0x1610: 0x000a, 0x1611: 0x000a,
- 0x1612: 0x000a, 0x1613: 0x000a, 0x1614: 0x000a, 0x1615: 0x000a, 0x1616: 0x000a, 0x1617: 0x000a,
- 0x1618: 0x000a, 0x1619: 0x000a, 0x161a: 0x000a, 0x161b: 0x000a, 0x161c: 0x000a, 0x161d: 0x000a,
- 0x161e: 0x000a, 0x161f: 0x000a, 0x1620: 0x000a, 0x1621: 0x000a, 0x1622: 0x000a, 0x1623: 0x000a,
- 0x1624: 0x000a, 0x1625: 0x000a, 0x1626: 0x000a, 0x1627: 0x000a, 0x1628: 0x000a, 0x1629: 0x000a,
- 0x162a: 0x000a, 0x162b: 0x000a, 0x162c: 0x000a, 0x162d: 0x000a, 0x162e: 0x000a, 0x162f: 0x000a,
- 0x1630: 0x000a, 0x1631: 0x000a, 0x1632: 0x000a, 0x1633: 0x000a, 0x1634: 0x000a, 0x1635: 0x000a,
- 0x1636: 0x000a, 0x1637: 0x000a, 0x1638: 0x000a, 0x1639: 0x000a, 0x163a: 0x000a, 0x163b: 0x000a,
- 0x163c: 0x000a, 0x163d: 0x000a, 0x163e: 0x000a, 0x163f: 0x000a,
- // Block 0x59, offset 0x1640
- 0x1640: 0x000a, 0x1641: 0x000a, 0x1642: 0x000a, 0x1643: 0x000a, 0x1644: 0x000a, 0x1645: 0x000a,
- 0x1646: 0x000a, 0x1647: 0x000a, 0x1648: 0x000a, 0x1649: 0x000a, 0x164a: 0x000a, 0x164b: 0x000a,
- 0x164c: 0x000a, 0x164d: 0x000a, 0x164e: 0x000a, 0x164f: 0x000a, 0x1650: 0x000a, 0x1651: 0x000a,
- 0x1652: 0x0003, 0x1653: 0x0004, 0x1654: 0x000a, 0x1655: 0x000a, 0x1656: 0x000a, 0x1657: 0x000a,
- 0x1658: 0x000a, 0x1659: 0x000a, 0x165a: 0x000a, 0x165b: 0x000a, 0x165c: 0x000a, 0x165d: 0x000a,
- 0x165e: 0x000a, 0x165f: 0x000a, 0x1660: 0x000a, 0x1661: 0x000a, 0x1662: 0x000a, 0x1663: 0x000a,
- 0x1664: 0x000a, 0x1665: 0x000a, 0x1666: 0x000a, 0x1667: 0x000a, 0x1668: 0x000a, 0x1669: 0x000a,
- 0x166a: 0x000a, 0x166b: 0x000a, 0x166c: 0x000a, 0x166d: 0x000a, 0x166e: 0x000a, 0x166f: 0x000a,
- 0x1670: 0x000a, 0x1671: 0x000a, 0x1672: 0x000a, 0x1673: 0x000a, 0x1674: 0x000a, 0x1675: 0x000a,
- 0x1676: 0x000a, 0x1677: 0x000a, 0x1678: 0x000a, 0x1679: 0x000a, 0x167a: 0x000a, 0x167b: 0x000a,
- 0x167c: 0x000a, 0x167d: 0x000a, 0x167e: 0x000a, 0x167f: 0x000a,
- // Block 0x5a, offset 0x1680
- 0x1680: 0x000a, 0x1681: 0x000a, 0x1682: 0x000a, 0x1683: 0x000a, 0x1684: 0x000a, 0x1685: 0x000a,
- 0x1686: 0x000a, 0x1687: 0x000a, 0x1688: 0x003a, 0x1689: 0x002a, 0x168a: 0x003a, 0x168b: 0x002a,
- 0x168c: 0x000a, 0x168d: 0x000a, 0x168e: 0x000a, 0x168f: 0x000a, 0x1690: 0x000a, 0x1691: 0x000a,
- 0x1692: 0x000a, 0x1693: 0x000a, 0x1694: 0x000a, 0x1695: 0x000a, 0x1696: 0x000a, 0x1697: 0x000a,
- 0x1698: 0x000a, 0x1699: 0x000a, 0x169a: 0x000a, 0x169b: 0x000a, 0x169c: 0x000a, 0x169d: 0x000a,
- 0x169e: 0x000a, 0x169f: 0x000a, 0x16a0: 0x000a, 0x16a1: 0x000a, 0x16a2: 0x000a, 0x16a3: 0x000a,
- 0x16a4: 0x000a, 0x16a5: 0x000a, 0x16a6: 0x000a, 0x16a7: 0x000a, 0x16a8: 0x000a, 0x16a9: 0x009a,
- 0x16aa: 0x008a, 0x16ab: 0x000a, 0x16ac: 0x000a, 0x16ad: 0x000a, 0x16ae: 0x000a, 0x16af: 0x000a,
- 0x16b0: 0x000a, 0x16b1: 0x000a, 0x16b2: 0x000a, 0x16b3: 0x000a, 0x16b4: 0x000a, 0x16b5: 0x000a,
- // Block 0x5b, offset 0x16c0
- 0x16fb: 0x000a,
- 0x16fc: 0x000a, 0x16fd: 0x000a, 0x16fe: 0x000a, 0x16ff: 0x000a,
- // Block 0x5c, offset 0x1700
- 0x1700: 0x000a, 0x1701: 0x000a, 0x1702: 0x000a, 0x1703: 0x000a, 0x1704: 0x000a, 0x1705: 0x000a,
- 0x1706: 0x000a, 0x1707: 0x000a, 0x1708: 0x000a, 0x1709: 0x000a, 0x170a: 0x000a, 0x170b: 0x000a,
- 0x170c: 0x000a, 0x170d: 0x000a, 0x170e: 0x000a, 0x170f: 0x000a, 0x1710: 0x000a, 0x1711: 0x000a,
- 0x1712: 0x000a, 0x1713: 0x000a, 0x1714: 0x000a, 0x1716: 0x000a, 0x1717: 0x000a,
- 0x1718: 0x000a, 0x1719: 0x000a, 0x171a: 0x000a, 0x171b: 0x000a, 0x171c: 0x000a, 0x171d: 0x000a,
- 0x171e: 0x000a, 0x171f: 0x000a, 0x1720: 0x000a, 0x1721: 0x000a, 0x1722: 0x000a, 0x1723: 0x000a,
- 0x1724: 0x000a, 0x1725: 0x000a, 0x1726: 0x000a, 0x1727: 0x000a, 0x1728: 0x000a, 0x1729: 0x000a,
- 0x172a: 0x000a, 0x172b: 0x000a, 0x172c: 0x000a, 0x172d: 0x000a, 0x172e: 0x000a, 0x172f: 0x000a,
- 0x1730: 0x000a, 0x1731: 0x000a, 0x1732: 0x000a, 0x1733: 0x000a, 0x1734: 0x000a, 0x1735: 0x000a,
- 0x1736: 0x000a, 0x1737: 0x000a, 0x1738: 0x000a, 0x1739: 0x000a, 0x173a: 0x000a, 0x173b: 0x000a,
- 0x173c: 0x000a, 0x173d: 0x000a, 0x173e: 0x000a, 0x173f: 0x000a,
- // Block 0x5d, offset 0x1740
- 0x1740: 0x000a, 0x1741: 0x000a, 0x1742: 0x000a, 0x1743: 0x000a, 0x1744: 0x000a, 0x1745: 0x000a,
- 0x1746: 0x000a, 0x1747: 0x000a, 0x1748: 0x000a, 0x1749: 0x000a, 0x174a: 0x000a, 0x174b: 0x000a,
- 0x174c: 0x000a, 0x174d: 0x000a, 0x174e: 0x000a, 0x174f: 0x000a, 0x1750: 0x000a, 0x1751: 0x000a,
- 0x1752: 0x000a, 0x1753: 0x000a, 0x1754: 0x000a, 0x1755: 0x000a, 0x1756: 0x000a, 0x1757: 0x000a,
- 0x1758: 0x000a, 0x1759: 0x000a, 0x175a: 0x000a, 0x175b: 0x000a, 0x175c: 0x000a, 0x175d: 0x000a,
- 0x175e: 0x000a, 0x175f: 0x000a, 0x1760: 0x000a, 0x1761: 0x000a, 0x1762: 0x000a, 0x1763: 0x000a,
- 0x1764: 0x000a, 0x1765: 0x000a, 0x1766: 0x000a,
- // Block 0x5e, offset 0x1780
- 0x1780: 0x000a, 0x1781: 0x000a, 0x1782: 0x000a, 0x1783: 0x000a, 0x1784: 0x000a, 0x1785: 0x000a,
- 0x1786: 0x000a, 0x1787: 0x000a, 0x1788: 0x000a, 0x1789: 0x000a, 0x178a: 0x000a,
- 0x17a0: 0x000a, 0x17a1: 0x000a, 0x17a2: 0x000a, 0x17a3: 0x000a,
- 0x17a4: 0x000a, 0x17a5: 0x000a, 0x17a6: 0x000a, 0x17a7: 0x000a, 0x17a8: 0x000a, 0x17a9: 0x000a,
- 0x17aa: 0x000a, 0x17ab: 0x000a, 0x17ac: 0x000a, 0x17ad: 0x000a, 0x17ae: 0x000a, 0x17af: 0x000a,
- 0x17b0: 0x000a, 0x17b1: 0x000a, 0x17b2: 0x000a, 0x17b3: 0x000a, 0x17b4: 0x000a, 0x17b5: 0x000a,
- 0x17b6: 0x000a, 0x17b7: 0x000a, 0x17b8: 0x000a, 0x17b9: 0x000a, 0x17ba: 0x000a, 0x17bb: 0x000a,
- 0x17bc: 0x000a, 0x17bd: 0x000a, 0x17be: 0x000a, 0x17bf: 0x000a,
- // Block 0x5f, offset 0x17c0
- 0x17c0: 0x000a, 0x17c1: 0x000a, 0x17c2: 0x000a, 0x17c3: 0x000a, 0x17c4: 0x000a, 0x17c5: 0x000a,
- 0x17c6: 0x000a, 0x17c7: 0x000a, 0x17c8: 0x0002, 0x17c9: 0x0002, 0x17ca: 0x0002, 0x17cb: 0x0002,
- 0x17cc: 0x0002, 0x17cd: 0x0002, 0x17ce: 0x0002, 0x17cf: 0x0002, 0x17d0: 0x0002, 0x17d1: 0x0002,
- 0x17d2: 0x0002, 0x17d3: 0x0002, 0x17d4: 0x0002, 0x17d5: 0x0002, 0x17d6: 0x0002, 0x17d7: 0x0002,
- 0x17d8: 0x0002, 0x17d9: 0x0002, 0x17da: 0x0002, 0x17db: 0x0002,
- // Block 0x60, offset 0x1800
- 0x182a: 0x000a, 0x182b: 0x000a, 0x182c: 0x000a, 0x182d: 0x000a, 0x182e: 0x000a, 0x182f: 0x000a,
- 0x1830: 0x000a, 0x1831: 0x000a, 0x1832: 0x000a, 0x1833: 0x000a, 0x1834: 0x000a, 0x1835: 0x000a,
- 0x1836: 0x000a, 0x1837: 0x000a, 0x1838: 0x000a, 0x1839: 0x000a, 0x183a: 0x000a, 0x183b: 0x000a,
- 0x183c: 0x000a, 0x183d: 0x000a, 0x183e: 0x000a, 0x183f: 0x000a,
- // Block 0x61, offset 0x1840
- 0x1840: 0x000a, 0x1841: 0x000a, 0x1842: 0x000a, 0x1843: 0x000a, 0x1844: 0x000a, 0x1845: 0x000a,
- 0x1846: 0x000a, 0x1847: 0x000a, 0x1848: 0x000a, 0x1849: 0x000a, 0x184a: 0x000a, 0x184b: 0x000a,
- 0x184c: 0x000a, 0x184d: 0x000a, 0x184e: 0x000a, 0x184f: 0x000a, 0x1850: 0x000a, 0x1851: 0x000a,
- 0x1852: 0x000a, 0x1853: 0x000a, 0x1854: 0x000a, 0x1855: 0x000a, 0x1856: 0x000a, 0x1857: 0x000a,
- 0x1858: 0x000a, 0x1859: 0x000a, 0x185a: 0x000a, 0x185b: 0x000a, 0x185c: 0x000a, 0x185d: 0x000a,
- 0x185e: 0x000a, 0x185f: 0x000a, 0x1860: 0x000a, 0x1861: 0x000a, 0x1862: 0x000a, 0x1863: 0x000a,
- 0x1864: 0x000a, 0x1865: 0x000a, 0x1866: 0x000a, 0x1867: 0x000a, 0x1868: 0x000a, 0x1869: 0x000a,
- 0x186a: 0x000a, 0x186b: 0x000a, 0x186d: 0x000a, 0x186e: 0x000a, 0x186f: 0x000a,
- 0x1870: 0x000a, 0x1871: 0x000a, 0x1872: 0x000a, 0x1873: 0x000a, 0x1874: 0x000a, 0x1875: 0x000a,
- 0x1876: 0x000a, 0x1877: 0x000a, 0x1878: 0x000a, 0x1879: 0x000a, 0x187a: 0x000a, 0x187b: 0x000a,
- 0x187c: 0x000a, 0x187d: 0x000a, 0x187e: 0x000a, 0x187f: 0x000a,
- // Block 0x62, offset 0x1880
- 0x1880: 0x000a, 0x1881: 0x000a, 0x1882: 0x000a, 0x1883: 0x000a, 0x1884: 0x000a, 0x1885: 0x000a,
- 0x1886: 0x000a, 0x1887: 0x000a, 0x1888: 0x000a, 0x1889: 0x000a, 0x188a: 0x000a, 0x188b: 0x000a,
- 0x188c: 0x000a, 0x188d: 0x000a, 0x188e: 0x000a, 0x188f: 0x000a, 0x1890: 0x000a, 0x1891: 0x000a,
- 0x1892: 0x000a, 0x1893: 0x000a, 0x1894: 0x000a, 0x1895: 0x000a, 0x1896: 0x000a, 0x1897: 0x000a,
- 0x1898: 0x000a, 0x1899: 0x000a, 0x189a: 0x000a, 0x189b: 0x000a, 0x189c: 0x000a, 0x189d: 0x000a,
- 0x189e: 0x000a, 0x189f: 0x000a, 0x18a0: 0x000a, 0x18a1: 0x000a, 0x18a2: 0x000a, 0x18a3: 0x000a,
- 0x18a4: 0x000a, 0x18a5: 0x000a, 0x18a6: 0x000a, 0x18a7: 0x000a, 0x18a8: 0x003a, 0x18a9: 0x002a,
- 0x18aa: 0x003a, 0x18ab: 0x002a, 0x18ac: 0x003a, 0x18ad: 0x002a, 0x18ae: 0x003a, 0x18af: 0x002a,
- 0x18b0: 0x003a, 0x18b1: 0x002a, 0x18b2: 0x003a, 0x18b3: 0x002a, 0x18b4: 0x003a, 0x18b5: 0x002a,
- 0x18b6: 0x000a, 0x18b7: 0x000a, 0x18b8: 0x000a, 0x18b9: 0x000a, 0x18ba: 0x000a, 0x18bb: 0x000a,
- 0x18bc: 0x000a, 0x18bd: 0x000a, 0x18be: 0x000a, 0x18bf: 0x000a,
- // Block 0x63, offset 0x18c0
- 0x18c0: 0x000a, 0x18c1: 0x000a, 0x18c2: 0x000a, 0x18c3: 0x000a, 0x18c4: 0x000a, 0x18c5: 0x009a,
- 0x18c6: 0x008a, 0x18c7: 0x000a, 0x18c8: 0x000a, 0x18c9: 0x000a, 0x18ca: 0x000a, 0x18cb: 0x000a,
- 0x18cc: 0x000a, 0x18cd: 0x000a, 0x18ce: 0x000a, 0x18cf: 0x000a, 0x18d0: 0x000a, 0x18d1: 0x000a,
- 0x18d2: 0x000a, 0x18d3: 0x000a, 0x18d4: 0x000a, 0x18d5: 0x000a, 0x18d6: 0x000a, 0x18d7: 0x000a,
- 0x18d8: 0x000a, 0x18d9: 0x000a, 0x18da: 0x000a, 0x18db: 0x000a, 0x18dc: 0x000a, 0x18dd: 0x000a,
- 0x18de: 0x000a, 0x18df: 0x000a, 0x18e0: 0x000a, 0x18e1: 0x000a, 0x18e2: 0x000a, 0x18e3: 0x000a,
- 0x18e4: 0x000a, 0x18e5: 0x000a, 0x18e6: 0x003a, 0x18e7: 0x002a, 0x18e8: 0x003a, 0x18e9: 0x002a,
- 0x18ea: 0x003a, 0x18eb: 0x002a, 0x18ec: 0x003a, 0x18ed: 0x002a, 0x18ee: 0x003a, 0x18ef: 0x002a,
- 0x18f0: 0x000a, 0x18f1: 0x000a, 0x18f2: 0x000a, 0x18f3: 0x000a, 0x18f4: 0x000a, 0x18f5: 0x000a,
- 0x18f6: 0x000a, 0x18f7: 0x000a, 0x18f8: 0x000a, 0x18f9: 0x000a, 0x18fa: 0x000a, 0x18fb: 0x000a,
- 0x18fc: 0x000a, 0x18fd: 0x000a, 0x18fe: 0x000a, 0x18ff: 0x000a,
- // Block 0x64, offset 0x1900
- 0x1900: 0x000a, 0x1901: 0x000a, 0x1902: 0x000a, 0x1903: 0x007a, 0x1904: 0x006a, 0x1905: 0x009a,
- 0x1906: 0x008a, 0x1907: 0x00ba, 0x1908: 0x00aa, 0x1909: 0x009a, 0x190a: 0x008a, 0x190b: 0x007a,
- 0x190c: 0x006a, 0x190d: 0x00da, 0x190e: 0x002a, 0x190f: 0x003a, 0x1910: 0x00ca, 0x1911: 0x009a,
- 0x1912: 0x008a, 0x1913: 0x007a, 0x1914: 0x006a, 0x1915: 0x009a, 0x1916: 0x008a, 0x1917: 0x00ba,
- 0x1918: 0x00aa, 0x1919: 0x000a, 0x191a: 0x000a, 0x191b: 0x000a, 0x191c: 0x000a, 0x191d: 0x000a,
- 0x191e: 0x000a, 0x191f: 0x000a, 0x1920: 0x000a, 0x1921: 0x000a, 0x1922: 0x000a, 0x1923: 0x000a,
- 0x1924: 0x000a, 0x1925: 0x000a, 0x1926: 0x000a, 0x1927: 0x000a, 0x1928: 0x000a, 0x1929: 0x000a,
- 0x192a: 0x000a, 0x192b: 0x000a, 0x192c: 0x000a, 0x192d: 0x000a, 0x192e: 0x000a, 0x192f: 0x000a,
- 0x1930: 0x000a, 0x1931: 0x000a, 0x1932: 0x000a, 0x1933: 0x000a, 0x1934: 0x000a, 0x1935: 0x000a,
- 0x1936: 0x000a, 0x1937: 0x000a, 0x1938: 0x000a, 0x1939: 0x000a, 0x193a: 0x000a, 0x193b: 0x000a,
- 0x193c: 0x000a, 0x193d: 0x000a, 0x193e: 0x000a, 0x193f: 0x000a,
- // Block 0x65, offset 0x1940
- 0x1940: 0x000a, 0x1941: 0x000a, 0x1942: 0x000a, 0x1943: 0x000a, 0x1944: 0x000a, 0x1945: 0x000a,
- 0x1946: 0x000a, 0x1947: 0x000a, 0x1948: 0x000a, 0x1949: 0x000a, 0x194a: 0x000a, 0x194b: 0x000a,
- 0x194c: 0x000a, 0x194d: 0x000a, 0x194e: 0x000a, 0x194f: 0x000a, 0x1950: 0x000a, 0x1951: 0x000a,
- 0x1952: 0x000a, 0x1953: 0x000a, 0x1954: 0x000a, 0x1955: 0x000a, 0x1956: 0x000a, 0x1957: 0x000a,
- 0x1958: 0x003a, 0x1959: 0x002a, 0x195a: 0x003a, 0x195b: 0x002a, 0x195c: 0x000a, 0x195d: 0x000a,
- 0x195e: 0x000a, 0x195f: 0x000a, 0x1960: 0x000a, 0x1961: 0x000a, 0x1962: 0x000a, 0x1963: 0x000a,
- 0x1964: 0x000a, 0x1965: 0x000a, 0x1966: 0x000a, 0x1967: 0x000a, 0x1968: 0x000a, 0x1969: 0x000a,
- 0x196a: 0x000a, 0x196b: 0x000a, 0x196c: 0x000a, 0x196d: 0x000a, 0x196e: 0x000a, 0x196f: 0x000a,
- 0x1970: 0x000a, 0x1971: 0x000a, 0x1972: 0x000a, 0x1973: 0x000a, 0x1974: 0x000a, 0x1975: 0x000a,
- 0x1976: 0x000a, 0x1977: 0x000a, 0x1978: 0x000a, 0x1979: 0x000a, 0x197a: 0x000a, 0x197b: 0x000a,
- 0x197c: 0x003a, 0x197d: 0x002a, 0x197e: 0x000a, 0x197f: 0x000a,
- // Block 0x66, offset 0x1980
- 0x1980: 0x000a, 0x1981: 0x000a, 0x1982: 0x000a, 0x1983: 0x000a, 0x1984: 0x000a, 0x1985: 0x000a,
- 0x1986: 0x000a, 0x1987: 0x000a, 0x1988: 0x000a, 0x1989: 0x000a, 0x198a: 0x000a, 0x198b: 0x000a,
- 0x198c: 0x000a, 0x198d: 0x000a, 0x198e: 0x000a, 0x198f: 0x000a, 0x1990: 0x000a, 0x1991: 0x000a,
- 0x1992: 0x000a, 0x1993: 0x000a, 0x1994: 0x000a, 0x1995: 0x000a, 0x1996: 0x000a, 0x1997: 0x000a,
- 0x1998: 0x000a, 0x1999: 0x000a, 0x199a: 0x000a, 0x199b: 0x000a, 0x199c: 0x000a, 0x199d: 0x000a,
- 0x199e: 0x000a, 0x199f: 0x000a, 0x19a0: 0x000a, 0x19a1: 0x000a, 0x19a2: 0x000a, 0x19a3: 0x000a,
- 0x19a4: 0x000a, 0x19a5: 0x000a, 0x19a6: 0x000a, 0x19a7: 0x000a, 0x19a8: 0x000a, 0x19a9: 0x000a,
- 0x19aa: 0x000a, 0x19ab: 0x000a, 0x19ac: 0x000a, 0x19ad: 0x000a, 0x19ae: 0x000a, 0x19af: 0x000a,
- 0x19b0: 0x000a, 0x19b1: 0x000a, 0x19b2: 0x000a, 0x19b3: 0x000a,
- 0x19b6: 0x000a, 0x19b7: 0x000a, 0x19b8: 0x000a, 0x19b9: 0x000a, 0x19ba: 0x000a, 0x19bb: 0x000a,
- 0x19bc: 0x000a, 0x19bd: 0x000a, 0x19be: 0x000a, 0x19bf: 0x000a,
- // Block 0x67, offset 0x19c0
- 0x19c0: 0x000a, 0x19c1: 0x000a, 0x19c2: 0x000a, 0x19c3: 0x000a, 0x19c4: 0x000a, 0x19c5: 0x000a,
- 0x19c6: 0x000a, 0x19c7: 0x000a, 0x19c8: 0x000a, 0x19c9: 0x000a, 0x19ca: 0x000a, 0x19cb: 0x000a,
- 0x19cc: 0x000a, 0x19cd: 0x000a, 0x19ce: 0x000a, 0x19cf: 0x000a, 0x19d0: 0x000a, 0x19d1: 0x000a,
- 0x19d2: 0x000a, 0x19d3: 0x000a, 0x19d4: 0x000a, 0x19d5: 0x000a, 0x19d7: 0x000a,
- 0x19d8: 0x000a, 0x19d9: 0x000a, 0x19da: 0x000a, 0x19db: 0x000a, 0x19dc: 0x000a, 0x19dd: 0x000a,
- 0x19de: 0x000a, 0x19df: 0x000a, 0x19e0: 0x000a, 0x19e1: 0x000a, 0x19e2: 0x000a, 0x19e3: 0x000a,
- 0x19e4: 0x000a, 0x19e5: 0x000a, 0x19e6: 0x000a, 0x19e7: 0x000a, 0x19e8: 0x000a, 0x19e9: 0x000a,
- 0x19ea: 0x000a, 0x19eb: 0x000a, 0x19ec: 0x000a, 0x19ed: 0x000a, 0x19ee: 0x000a, 0x19ef: 0x000a,
- 0x19f0: 0x000a, 0x19f1: 0x000a, 0x19f2: 0x000a, 0x19f3: 0x000a, 0x19f4: 0x000a, 0x19f5: 0x000a,
- 0x19f6: 0x000a, 0x19f7: 0x000a, 0x19f8: 0x000a, 0x19f9: 0x000a, 0x19fa: 0x000a, 0x19fb: 0x000a,
- 0x19fc: 0x000a, 0x19fd: 0x000a, 0x19fe: 0x000a, 0x19ff: 0x000a,
- // Block 0x68, offset 0x1a00
- 0x1a25: 0x000a, 0x1a26: 0x000a, 0x1a27: 0x000a, 0x1a28: 0x000a, 0x1a29: 0x000a,
- 0x1a2a: 0x000a, 0x1a2f: 0x000c,
- 0x1a30: 0x000c, 0x1a31: 0x000c,
- 0x1a39: 0x000a, 0x1a3a: 0x000a, 0x1a3b: 0x000a,
- 0x1a3c: 0x000a, 0x1a3d: 0x000a, 0x1a3e: 0x000a, 0x1a3f: 0x000a,
- // Block 0x69, offset 0x1a40
- 0x1a7f: 0x000c,
- // Block 0x6a, offset 0x1a80
- 0x1aa0: 0x000c, 0x1aa1: 0x000c, 0x1aa2: 0x000c, 0x1aa3: 0x000c,
- 0x1aa4: 0x000c, 0x1aa5: 0x000c, 0x1aa6: 0x000c, 0x1aa7: 0x000c, 0x1aa8: 0x000c, 0x1aa9: 0x000c,
- 0x1aaa: 0x000c, 0x1aab: 0x000c, 0x1aac: 0x000c, 0x1aad: 0x000c, 0x1aae: 0x000c, 0x1aaf: 0x000c,
- 0x1ab0: 0x000c, 0x1ab1: 0x000c, 0x1ab2: 0x000c, 0x1ab3: 0x000c, 0x1ab4: 0x000c, 0x1ab5: 0x000c,
- 0x1ab6: 0x000c, 0x1ab7: 0x000c, 0x1ab8: 0x000c, 0x1ab9: 0x000c, 0x1aba: 0x000c, 0x1abb: 0x000c,
- 0x1abc: 0x000c, 0x1abd: 0x000c, 0x1abe: 0x000c, 0x1abf: 0x000c,
- // Block 0x6b, offset 0x1ac0
- 0x1ac0: 0x000a, 0x1ac1: 0x000a, 0x1ac2: 0x000a, 0x1ac3: 0x000a, 0x1ac4: 0x000a, 0x1ac5: 0x000a,
- 0x1ac6: 0x000a, 0x1ac7: 0x000a, 0x1ac8: 0x000a, 0x1ac9: 0x000a, 0x1aca: 0x000a, 0x1acb: 0x000a,
- 0x1acc: 0x000a, 0x1acd: 0x000a, 0x1ace: 0x000a, 0x1acf: 0x000a, 0x1ad0: 0x000a, 0x1ad1: 0x000a,
- 0x1ad2: 0x000a, 0x1ad3: 0x000a, 0x1ad4: 0x000a, 0x1ad5: 0x000a, 0x1ad6: 0x000a, 0x1ad7: 0x000a,
- 0x1ad8: 0x000a, 0x1ad9: 0x000a, 0x1ada: 0x000a, 0x1adb: 0x000a, 0x1adc: 0x000a, 0x1add: 0x000a,
- 0x1ade: 0x000a, 0x1adf: 0x000a, 0x1ae0: 0x000a, 0x1ae1: 0x000a, 0x1ae2: 0x003a, 0x1ae3: 0x002a,
- 0x1ae4: 0x003a, 0x1ae5: 0x002a, 0x1ae6: 0x003a, 0x1ae7: 0x002a, 0x1ae8: 0x003a, 0x1ae9: 0x002a,
- 0x1aea: 0x000a, 0x1aeb: 0x000a, 0x1aec: 0x000a, 0x1aed: 0x000a, 0x1aee: 0x000a, 0x1aef: 0x000a,
- 0x1af0: 0x000a, 0x1af1: 0x000a, 0x1af2: 0x000a, 0x1af3: 0x000a, 0x1af4: 0x000a, 0x1af5: 0x000a,
- 0x1af6: 0x000a, 0x1af7: 0x000a, 0x1af8: 0x000a, 0x1af9: 0x000a, 0x1afa: 0x000a, 0x1afb: 0x000a,
- 0x1afc: 0x000a, 0x1afd: 0x000a, 0x1afe: 0x000a, 0x1aff: 0x000a,
- // Block 0x6c, offset 0x1b00
- 0x1b00: 0x000a, 0x1b01: 0x000a, 0x1b02: 0x000a, 0x1b03: 0x000a, 0x1b04: 0x000a, 0x1b05: 0x000a,
- 0x1b06: 0x000a, 0x1b07: 0x000a, 0x1b08: 0x000a, 0x1b09: 0x000a, 0x1b0a: 0x000a, 0x1b0b: 0x000a,
- 0x1b0c: 0x000a, 0x1b0d: 0x000a, 0x1b0e: 0x000a, 0x1b0f: 0x000a, 0x1b10: 0x000a, 0x1b11: 0x000a,
- 0x1b12: 0x000a,
- // Block 0x6d, offset 0x1b40
- 0x1b40: 0x000a, 0x1b41: 0x000a, 0x1b42: 0x000a, 0x1b43: 0x000a, 0x1b44: 0x000a, 0x1b45: 0x000a,
- 0x1b46: 0x000a, 0x1b47: 0x000a, 0x1b48: 0x000a, 0x1b49: 0x000a, 0x1b4a: 0x000a, 0x1b4b: 0x000a,
- 0x1b4c: 0x000a, 0x1b4d: 0x000a, 0x1b4e: 0x000a, 0x1b4f: 0x000a, 0x1b50: 0x000a, 0x1b51: 0x000a,
- 0x1b52: 0x000a, 0x1b53: 0x000a, 0x1b54: 0x000a, 0x1b55: 0x000a, 0x1b56: 0x000a, 0x1b57: 0x000a,
- 0x1b58: 0x000a, 0x1b59: 0x000a, 0x1b5b: 0x000a, 0x1b5c: 0x000a, 0x1b5d: 0x000a,
- 0x1b5e: 0x000a, 0x1b5f: 0x000a, 0x1b60: 0x000a, 0x1b61: 0x000a, 0x1b62: 0x000a, 0x1b63: 0x000a,
- 0x1b64: 0x000a, 0x1b65: 0x000a, 0x1b66: 0x000a, 0x1b67: 0x000a, 0x1b68: 0x000a, 0x1b69: 0x000a,
- 0x1b6a: 0x000a, 0x1b6b: 0x000a, 0x1b6c: 0x000a, 0x1b6d: 0x000a, 0x1b6e: 0x000a, 0x1b6f: 0x000a,
- 0x1b70: 0x000a, 0x1b71: 0x000a, 0x1b72: 0x000a, 0x1b73: 0x000a, 0x1b74: 0x000a, 0x1b75: 0x000a,
- 0x1b76: 0x000a, 0x1b77: 0x000a, 0x1b78: 0x000a, 0x1b79: 0x000a, 0x1b7a: 0x000a, 0x1b7b: 0x000a,
- 0x1b7c: 0x000a, 0x1b7d: 0x000a, 0x1b7e: 0x000a, 0x1b7f: 0x000a,
- // Block 0x6e, offset 0x1b80
- 0x1b80: 0x000a, 0x1b81: 0x000a, 0x1b82: 0x000a, 0x1b83: 0x000a, 0x1b84: 0x000a, 0x1b85: 0x000a,
- 0x1b86: 0x000a, 0x1b87: 0x000a, 0x1b88: 0x000a, 0x1b89: 0x000a, 0x1b8a: 0x000a, 0x1b8b: 0x000a,
- 0x1b8c: 0x000a, 0x1b8d: 0x000a, 0x1b8e: 0x000a, 0x1b8f: 0x000a, 0x1b90: 0x000a, 0x1b91: 0x000a,
- 0x1b92: 0x000a, 0x1b93: 0x000a, 0x1b94: 0x000a, 0x1b95: 0x000a, 0x1b96: 0x000a, 0x1b97: 0x000a,
- 0x1b98: 0x000a, 0x1b99: 0x000a, 0x1b9a: 0x000a, 0x1b9b: 0x000a, 0x1b9c: 0x000a, 0x1b9d: 0x000a,
- 0x1b9e: 0x000a, 0x1b9f: 0x000a, 0x1ba0: 0x000a, 0x1ba1: 0x000a, 0x1ba2: 0x000a, 0x1ba3: 0x000a,
- 0x1ba4: 0x000a, 0x1ba5: 0x000a, 0x1ba6: 0x000a, 0x1ba7: 0x000a, 0x1ba8: 0x000a, 0x1ba9: 0x000a,
- 0x1baa: 0x000a, 0x1bab: 0x000a, 0x1bac: 0x000a, 0x1bad: 0x000a, 0x1bae: 0x000a, 0x1baf: 0x000a,
- 0x1bb0: 0x000a, 0x1bb1: 0x000a, 0x1bb2: 0x000a, 0x1bb3: 0x000a,
- // Block 0x6f, offset 0x1bc0
- 0x1bc0: 0x000a, 0x1bc1: 0x000a, 0x1bc2: 0x000a, 0x1bc3: 0x000a, 0x1bc4: 0x000a, 0x1bc5: 0x000a,
- 0x1bc6: 0x000a, 0x1bc7: 0x000a, 0x1bc8: 0x000a, 0x1bc9: 0x000a, 0x1bca: 0x000a, 0x1bcb: 0x000a,
- 0x1bcc: 0x000a, 0x1bcd: 0x000a, 0x1bce: 0x000a, 0x1bcf: 0x000a, 0x1bd0: 0x000a, 0x1bd1: 0x000a,
- 0x1bd2: 0x000a, 0x1bd3: 0x000a, 0x1bd4: 0x000a, 0x1bd5: 0x000a,
- 0x1bf0: 0x000a, 0x1bf1: 0x000a, 0x1bf2: 0x000a, 0x1bf3: 0x000a, 0x1bf4: 0x000a, 0x1bf5: 0x000a,
- 0x1bf6: 0x000a, 0x1bf7: 0x000a, 0x1bf8: 0x000a, 0x1bf9: 0x000a, 0x1bfa: 0x000a, 0x1bfb: 0x000a,
- // Block 0x70, offset 0x1c00
- 0x1c00: 0x0009, 0x1c01: 0x000a, 0x1c02: 0x000a, 0x1c03: 0x000a, 0x1c04: 0x000a,
- 0x1c08: 0x003a, 0x1c09: 0x002a, 0x1c0a: 0x003a, 0x1c0b: 0x002a,
- 0x1c0c: 0x003a, 0x1c0d: 0x002a, 0x1c0e: 0x003a, 0x1c0f: 0x002a, 0x1c10: 0x003a, 0x1c11: 0x002a,
- 0x1c12: 0x000a, 0x1c13: 0x000a, 0x1c14: 0x003a, 0x1c15: 0x002a, 0x1c16: 0x003a, 0x1c17: 0x002a,
- 0x1c18: 0x003a, 0x1c19: 0x002a, 0x1c1a: 0x003a, 0x1c1b: 0x002a, 0x1c1c: 0x000a, 0x1c1d: 0x000a,
- 0x1c1e: 0x000a, 0x1c1f: 0x000a, 0x1c20: 0x000a,
- 0x1c2a: 0x000c, 0x1c2b: 0x000c, 0x1c2c: 0x000c, 0x1c2d: 0x000c,
- 0x1c30: 0x000a,
- 0x1c36: 0x000a, 0x1c37: 0x000a,
- 0x1c3d: 0x000a, 0x1c3e: 0x000a, 0x1c3f: 0x000a,
- // Block 0x71, offset 0x1c40
- 0x1c59: 0x000c, 0x1c5a: 0x000c, 0x1c5b: 0x000a, 0x1c5c: 0x000a,
- 0x1c60: 0x000a,
- // Block 0x72, offset 0x1c80
- 0x1cbb: 0x000a,
- // Block 0x73, offset 0x1cc0
- 0x1cc0: 0x000a, 0x1cc1: 0x000a, 0x1cc2: 0x000a, 0x1cc3: 0x000a, 0x1cc4: 0x000a, 0x1cc5: 0x000a,
- 0x1cc6: 0x000a, 0x1cc7: 0x000a, 0x1cc8: 0x000a, 0x1cc9: 0x000a, 0x1cca: 0x000a, 0x1ccb: 0x000a,
- 0x1ccc: 0x000a, 0x1ccd: 0x000a, 0x1cce: 0x000a, 0x1ccf: 0x000a, 0x1cd0: 0x000a, 0x1cd1: 0x000a,
- 0x1cd2: 0x000a, 0x1cd3: 0x000a, 0x1cd4: 0x000a, 0x1cd5: 0x000a, 0x1cd6: 0x000a, 0x1cd7: 0x000a,
- 0x1cd8: 0x000a, 0x1cd9: 0x000a, 0x1cda: 0x000a, 0x1cdb: 0x000a, 0x1cdc: 0x000a, 0x1cdd: 0x000a,
- 0x1cde: 0x000a, 0x1cdf: 0x000a, 0x1ce0: 0x000a, 0x1ce1: 0x000a, 0x1ce2: 0x000a, 0x1ce3: 0x000a,
- // Block 0x74, offset 0x1d00
- 0x1d1d: 0x000a,
- 0x1d1e: 0x000a,
- // Block 0x75, offset 0x1d40
- 0x1d50: 0x000a, 0x1d51: 0x000a,
- 0x1d52: 0x000a, 0x1d53: 0x000a, 0x1d54: 0x000a, 0x1d55: 0x000a, 0x1d56: 0x000a, 0x1d57: 0x000a,
- 0x1d58: 0x000a, 0x1d59: 0x000a, 0x1d5a: 0x000a, 0x1d5b: 0x000a, 0x1d5c: 0x000a, 0x1d5d: 0x000a,
- 0x1d5e: 0x000a, 0x1d5f: 0x000a,
- 0x1d7c: 0x000a, 0x1d7d: 0x000a, 0x1d7e: 0x000a,
- // Block 0x76, offset 0x1d80
- 0x1db1: 0x000a, 0x1db2: 0x000a, 0x1db3: 0x000a, 0x1db4: 0x000a, 0x1db5: 0x000a,
- 0x1db6: 0x000a, 0x1db7: 0x000a, 0x1db8: 0x000a, 0x1db9: 0x000a, 0x1dba: 0x000a, 0x1dbb: 0x000a,
- 0x1dbc: 0x000a, 0x1dbd: 0x000a, 0x1dbe: 0x000a, 0x1dbf: 0x000a,
- // Block 0x77, offset 0x1dc0
- 0x1dcc: 0x000a, 0x1dcd: 0x000a, 0x1dce: 0x000a, 0x1dcf: 0x000a,
- // Block 0x78, offset 0x1e00
- 0x1e37: 0x000a, 0x1e38: 0x000a, 0x1e39: 0x000a, 0x1e3a: 0x000a,
- // Block 0x79, offset 0x1e40
- 0x1e5e: 0x000a, 0x1e5f: 0x000a,
- 0x1e7f: 0x000a,
- // Block 0x7a, offset 0x1e80
- 0x1e90: 0x000a, 0x1e91: 0x000a,
- 0x1e92: 0x000a, 0x1e93: 0x000a, 0x1e94: 0x000a, 0x1e95: 0x000a, 0x1e96: 0x000a, 0x1e97: 0x000a,
- 0x1e98: 0x000a, 0x1e99: 0x000a, 0x1e9a: 0x000a, 0x1e9b: 0x000a, 0x1e9c: 0x000a, 0x1e9d: 0x000a,
- 0x1e9e: 0x000a, 0x1e9f: 0x000a, 0x1ea0: 0x000a, 0x1ea1: 0x000a, 0x1ea2: 0x000a, 0x1ea3: 0x000a,
- 0x1ea4: 0x000a, 0x1ea5: 0x000a, 0x1ea6: 0x000a, 0x1ea7: 0x000a, 0x1ea8: 0x000a, 0x1ea9: 0x000a,
- 0x1eaa: 0x000a, 0x1eab: 0x000a, 0x1eac: 0x000a, 0x1ead: 0x000a, 0x1eae: 0x000a, 0x1eaf: 0x000a,
- 0x1eb0: 0x000a, 0x1eb1: 0x000a, 0x1eb2: 0x000a, 0x1eb3: 0x000a, 0x1eb4: 0x000a, 0x1eb5: 0x000a,
- 0x1eb6: 0x000a, 0x1eb7: 0x000a, 0x1eb8: 0x000a, 0x1eb9: 0x000a, 0x1eba: 0x000a, 0x1ebb: 0x000a,
- 0x1ebc: 0x000a, 0x1ebd: 0x000a, 0x1ebe: 0x000a, 0x1ebf: 0x000a,
- // Block 0x7b, offset 0x1ec0
- 0x1ec0: 0x000a, 0x1ec1: 0x000a, 0x1ec2: 0x000a, 0x1ec3: 0x000a, 0x1ec4: 0x000a, 0x1ec5: 0x000a,
- 0x1ec6: 0x000a,
- // Block 0x7c, offset 0x1f00
- 0x1f0d: 0x000a, 0x1f0e: 0x000a, 0x1f0f: 0x000a,
- // Block 0x7d, offset 0x1f40
- 0x1f6f: 0x000c,
- 0x1f70: 0x000c, 0x1f71: 0x000c, 0x1f72: 0x000c, 0x1f73: 0x000a, 0x1f74: 0x000c, 0x1f75: 0x000c,
- 0x1f76: 0x000c, 0x1f77: 0x000c, 0x1f78: 0x000c, 0x1f79: 0x000c, 0x1f7a: 0x000c, 0x1f7b: 0x000c,
- 0x1f7c: 0x000c, 0x1f7d: 0x000c, 0x1f7e: 0x000a, 0x1f7f: 0x000a,
- // Block 0x7e, offset 0x1f80
- 0x1f9e: 0x000c, 0x1f9f: 0x000c,
- // Block 0x7f, offset 0x1fc0
- 0x1ff0: 0x000c, 0x1ff1: 0x000c,
- // Block 0x80, offset 0x2000
- 0x2000: 0x000a, 0x2001: 0x000a, 0x2002: 0x000a, 0x2003: 0x000a, 0x2004: 0x000a, 0x2005: 0x000a,
- 0x2006: 0x000a, 0x2007: 0x000a, 0x2008: 0x000a, 0x2009: 0x000a, 0x200a: 0x000a, 0x200b: 0x000a,
- 0x200c: 0x000a, 0x200d: 0x000a, 0x200e: 0x000a, 0x200f: 0x000a, 0x2010: 0x000a, 0x2011: 0x000a,
- 0x2012: 0x000a, 0x2013: 0x000a, 0x2014: 0x000a, 0x2015: 0x000a, 0x2016: 0x000a, 0x2017: 0x000a,
- 0x2018: 0x000a, 0x2019: 0x000a, 0x201a: 0x000a, 0x201b: 0x000a, 0x201c: 0x000a, 0x201d: 0x000a,
- 0x201e: 0x000a, 0x201f: 0x000a, 0x2020: 0x000a, 0x2021: 0x000a,
- // Block 0x81, offset 0x2040
- 0x2048: 0x000a,
- // Block 0x82, offset 0x2080
- 0x2082: 0x000c,
- 0x2086: 0x000c, 0x208b: 0x000c,
- 0x20a5: 0x000c, 0x20a6: 0x000c, 0x20a8: 0x000a, 0x20a9: 0x000a,
- 0x20aa: 0x000a, 0x20ab: 0x000a, 0x20ac: 0x000c,
- 0x20b8: 0x0004, 0x20b9: 0x0004,
- // Block 0x83, offset 0x20c0
- 0x20f4: 0x000a, 0x20f5: 0x000a,
- 0x20f6: 0x000a, 0x20f7: 0x000a,
- // Block 0x84, offset 0x2100
- 0x2104: 0x000c, 0x2105: 0x000c,
- 0x2120: 0x000c, 0x2121: 0x000c, 0x2122: 0x000c, 0x2123: 0x000c,
- 0x2124: 0x000c, 0x2125: 0x000c, 0x2126: 0x000c, 0x2127: 0x000c, 0x2128: 0x000c, 0x2129: 0x000c,
- 0x212a: 0x000c, 0x212b: 0x000c, 0x212c: 0x000c, 0x212d: 0x000c, 0x212e: 0x000c, 0x212f: 0x000c,
- 0x2130: 0x000c, 0x2131: 0x000c,
- 0x213f: 0x000c,
- // Block 0x85, offset 0x2140
- 0x2166: 0x000c, 0x2167: 0x000c, 0x2168: 0x000c, 0x2169: 0x000c,
- 0x216a: 0x000c, 0x216b: 0x000c, 0x216c: 0x000c, 0x216d: 0x000c,
- // Block 0x86, offset 0x2180
- 0x2187: 0x000c, 0x2188: 0x000c, 0x2189: 0x000c, 0x218a: 0x000c, 0x218b: 0x000c,
- 0x218c: 0x000c, 0x218d: 0x000c, 0x218e: 0x000c, 0x218f: 0x000c, 0x2190: 0x000c, 0x2191: 0x000c,
- // Block 0x87, offset 0x21c0
- 0x21c0: 0x000c, 0x21c1: 0x000c, 0x21c2: 0x000c,
- 0x21f3: 0x000c,
- 0x21f6: 0x000c, 0x21f7: 0x000c, 0x21f8: 0x000c, 0x21f9: 0x000c,
- 0x21fc: 0x000c, 0x21fd: 0x000c,
- // Block 0x88, offset 0x2200
- 0x2225: 0x000c,
- // Block 0x89, offset 0x2240
- 0x2269: 0x000c,
- 0x226a: 0x000c, 0x226b: 0x000c, 0x226c: 0x000c, 0x226d: 0x000c, 0x226e: 0x000c,
- 0x2271: 0x000c, 0x2272: 0x000c, 0x2275: 0x000c,
- 0x2276: 0x000c,
- // Block 0x8a, offset 0x2280
- 0x2283: 0x000c,
- 0x228c: 0x000c,
- 0x22bc: 0x000c,
- // Block 0x8b, offset 0x22c0
- 0x22f0: 0x000c, 0x22f2: 0x000c, 0x22f3: 0x000c, 0x22f4: 0x000c,
- 0x22f7: 0x000c, 0x22f8: 0x000c,
- 0x22fe: 0x000c, 0x22ff: 0x000c,
- // Block 0x8c, offset 0x2300
- 0x2301: 0x000c,
- 0x232c: 0x000c, 0x232d: 0x000c,
- 0x2336: 0x000c,
- // Block 0x8d, offset 0x2340
- 0x236a: 0x000a, 0x236b: 0x000a,
- // Block 0x8e, offset 0x2380
- 0x23a5: 0x000c, 0x23a8: 0x000c,
- 0x23ad: 0x000c,
- // Block 0x8f, offset 0x23c0
- 0x23dd: 0x0001,
- 0x23de: 0x000c, 0x23df: 0x0001, 0x23e0: 0x0001, 0x23e1: 0x0001, 0x23e2: 0x0001, 0x23e3: 0x0001,
- 0x23e4: 0x0001, 0x23e5: 0x0001, 0x23e6: 0x0001, 0x23e7: 0x0001, 0x23e8: 0x0001, 0x23e9: 0x0003,
- 0x23ea: 0x0001, 0x23eb: 0x0001, 0x23ec: 0x0001, 0x23ed: 0x0001, 0x23ee: 0x0001, 0x23ef: 0x0001,
- 0x23f0: 0x0001, 0x23f1: 0x0001, 0x23f2: 0x0001, 0x23f3: 0x0001, 0x23f4: 0x0001, 0x23f5: 0x0001,
- 0x23f6: 0x0001, 0x23f7: 0x0001, 0x23f8: 0x0001, 0x23f9: 0x0001, 0x23fa: 0x0001, 0x23fb: 0x0001,
- 0x23fc: 0x0001, 0x23fd: 0x0001, 0x23fe: 0x0001, 0x23ff: 0x0001,
- // Block 0x90, offset 0x2400
- 0x2400: 0x0001, 0x2401: 0x0001, 0x2402: 0x0001, 0x2403: 0x0001, 0x2404: 0x0001, 0x2405: 0x0001,
- 0x2406: 0x0001, 0x2407: 0x0001, 0x2408: 0x0001, 0x2409: 0x0001, 0x240a: 0x0001, 0x240b: 0x0001,
- 0x240c: 0x0001, 0x240d: 0x0001, 0x240e: 0x0001, 0x240f: 0x0001, 0x2410: 0x000d, 0x2411: 0x000d,
- 0x2412: 0x000d, 0x2413: 0x000d, 0x2414: 0x000d, 0x2415: 0x000d, 0x2416: 0x000d, 0x2417: 0x000d,
- 0x2418: 0x000d, 0x2419: 0x000d, 0x241a: 0x000d, 0x241b: 0x000d, 0x241c: 0x000d, 0x241d: 0x000d,
- 0x241e: 0x000d, 0x241f: 0x000d, 0x2420: 0x000d, 0x2421: 0x000d, 0x2422: 0x000d, 0x2423: 0x000d,
- 0x2424: 0x000d, 0x2425: 0x000d, 0x2426: 0x000d, 0x2427: 0x000d, 0x2428: 0x000d, 0x2429: 0x000d,
- 0x242a: 0x000d, 0x242b: 0x000d, 0x242c: 0x000d, 0x242d: 0x000d, 0x242e: 0x000d, 0x242f: 0x000d,
- 0x2430: 0x000d, 0x2431: 0x000d, 0x2432: 0x000d, 0x2433: 0x000d, 0x2434: 0x000d, 0x2435: 0x000d,
- 0x2436: 0x000d, 0x2437: 0x000d, 0x2438: 0x000d, 0x2439: 0x000d, 0x243a: 0x000d, 0x243b: 0x000d,
- 0x243c: 0x000d, 0x243d: 0x000d, 0x243e: 0x000d, 0x243f: 0x000d,
- // Block 0x91, offset 0x2440
- 0x2440: 0x000d, 0x2441: 0x000d, 0x2442: 0x000d, 0x2443: 0x000d, 0x2444: 0x000d, 0x2445: 0x000d,
- 0x2446: 0x000d, 0x2447: 0x000d, 0x2448: 0x000d, 0x2449: 0x000d, 0x244a: 0x000d, 0x244b: 0x000d,
- 0x244c: 0x000d, 0x244d: 0x000d, 0x244e: 0x000d, 0x244f: 0x000d, 0x2450: 0x000d, 0x2451: 0x000d,
- 0x2452: 0x000d, 0x2453: 0x000d, 0x2454: 0x000d, 0x2455: 0x000d, 0x2456: 0x000d, 0x2457: 0x000d,
- 0x2458: 0x000d, 0x2459: 0x000d, 0x245a: 0x000d, 0x245b: 0x000d, 0x245c: 0x000d, 0x245d: 0x000d,
- 0x245e: 0x000d, 0x245f: 0x000d, 0x2460: 0x000d, 0x2461: 0x000d, 0x2462: 0x000d, 0x2463: 0x000d,
- 0x2464: 0x000d, 0x2465: 0x000d, 0x2466: 0x000d, 0x2467: 0x000d, 0x2468: 0x000d, 0x2469: 0x000d,
- 0x246a: 0x000d, 0x246b: 0x000d, 0x246c: 0x000d, 0x246d: 0x000d, 0x246e: 0x000d, 0x246f: 0x000d,
- 0x2470: 0x000d, 0x2471: 0x000d, 0x2472: 0x000d, 0x2473: 0x000d, 0x2474: 0x000d, 0x2475: 0x000d,
- 0x2476: 0x000d, 0x2477: 0x000d, 0x2478: 0x000d, 0x2479: 0x000d, 0x247a: 0x000d, 0x247b: 0x000d,
- 0x247c: 0x000d, 0x247d: 0x000d, 0x247e: 0x000a, 0x247f: 0x000a,
- // Block 0x92, offset 0x2480
- 0x2480: 0x000d, 0x2481: 0x000d, 0x2482: 0x000d, 0x2483: 0x000d, 0x2484: 0x000d, 0x2485: 0x000d,
- 0x2486: 0x000d, 0x2487: 0x000d, 0x2488: 0x000d, 0x2489: 0x000d, 0x248a: 0x000d, 0x248b: 0x000d,
- 0x248c: 0x000d, 0x248d: 0x000d, 0x248e: 0x000d, 0x248f: 0x000d, 0x2490: 0x000b, 0x2491: 0x000b,
- 0x2492: 0x000b, 0x2493: 0x000b, 0x2494: 0x000b, 0x2495: 0x000b, 0x2496: 0x000b, 0x2497: 0x000b,
- 0x2498: 0x000b, 0x2499: 0x000b, 0x249a: 0x000b, 0x249b: 0x000b, 0x249c: 0x000b, 0x249d: 0x000b,
- 0x249e: 0x000b, 0x249f: 0x000b, 0x24a0: 0x000b, 0x24a1: 0x000b, 0x24a2: 0x000b, 0x24a3: 0x000b,
- 0x24a4: 0x000b, 0x24a5: 0x000b, 0x24a6: 0x000b, 0x24a7: 0x000b, 0x24a8: 0x000b, 0x24a9: 0x000b,
- 0x24aa: 0x000b, 0x24ab: 0x000b, 0x24ac: 0x000b, 0x24ad: 0x000b, 0x24ae: 0x000b, 0x24af: 0x000b,
- 0x24b0: 0x000d, 0x24b1: 0x000d, 0x24b2: 0x000d, 0x24b3: 0x000d, 0x24b4: 0x000d, 0x24b5: 0x000d,
- 0x24b6: 0x000d, 0x24b7: 0x000d, 0x24b8: 0x000d, 0x24b9: 0x000d, 0x24ba: 0x000d, 0x24bb: 0x000d,
- 0x24bc: 0x000d, 0x24bd: 0x000a, 0x24be: 0x000d, 0x24bf: 0x000d,
- // Block 0x93, offset 0x24c0
- 0x24c0: 0x000c, 0x24c1: 0x000c, 0x24c2: 0x000c, 0x24c3: 0x000c, 0x24c4: 0x000c, 0x24c5: 0x000c,
- 0x24c6: 0x000c, 0x24c7: 0x000c, 0x24c8: 0x000c, 0x24c9: 0x000c, 0x24ca: 0x000c, 0x24cb: 0x000c,
- 0x24cc: 0x000c, 0x24cd: 0x000c, 0x24ce: 0x000c, 0x24cf: 0x000c, 0x24d0: 0x000a, 0x24d1: 0x000a,
- 0x24d2: 0x000a, 0x24d3: 0x000a, 0x24d4: 0x000a, 0x24d5: 0x000a, 0x24d6: 0x000a, 0x24d7: 0x000a,
- 0x24d8: 0x000a, 0x24d9: 0x000a,
- 0x24e0: 0x000c, 0x24e1: 0x000c, 0x24e2: 0x000c, 0x24e3: 0x000c,
- 0x24e4: 0x000c, 0x24e5: 0x000c, 0x24e6: 0x000c, 0x24e7: 0x000c, 0x24e8: 0x000c, 0x24e9: 0x000c,
- 0x24ea: 0x000c, 0x24eb: 0x000c, 0x24ec: 0x000c, 0x24ed: 0x000c, 0x24ee: 0x000c, 0x24ef: 0x000c,
- 0x24f0: 0x000a, 0x24f1: 0x000a, 0x24f2: 0x000a, 0x24f3: 0x000a, 0x24f4: 0x000a, 0x24f5: 0x000a,
- 0x24f6: 0x000a, 0x24f7: 0x000a, 0x24f8: 0x000a, 0x24f9: 0x000a, 0x24fa: 0x000a, 0x24fb: 0x000a,
- 0x24fc: 0x000a, 0x24fd: 0x000a, 0x24fe: 0x000a, 0x24ff: 0x000a,
- // Block 0x94, offset 0x2500
- 0x2500: 0x000a, 0x2501: 0x000a, 0x2502: 0x000a, 0x2503: 0x000a, 0x2504: 0x000a, 0x2505: 0x000a,
- 0x2506: 0x000a, 0x2507: 0x000a, 0x2508: 0x000a, 0x2509: 0x000a, 0x250a: 0x000a, 0x250b: 0x000a,
- 0x250c: 0x000a, 0x250d: 0x000a, 0x250e: 0x000a, 0x250f: 0x000a, 0x2510: 0x0006, 0x2511: 0x000a,
- 0x2512: 0x0006, 0x2514: 0x000a, 0x2515: 0x0006, 0x2516: 0x000a, 0x2517: 0x000a,
- 0x2518: 0x000a, 0x2519: 0x009a, 0x251a: 0x008a, 0x251b: 0x007a, 0x251c: 0x006a, 0x251d: 0x009a,
- 0x251e: 0x008a, 0x251f: 0x0004, 0x2520: 0x000a, 0x2521: 0x000a, 0x2522: 0x0003, 0x2523: 0x0003,
- 0x2524: 0x000a, 0x2525: 0x000a, 0x2526: 0x000a, 0x2528: 0x000a, 0x2529: 0x0004,
- 0x252a: 0x0004, 0x252b: 0x000a,
- 0x2530: 0x000d, 0x2531: 0x000d, 0x2532: 0x000d, 0x2533: 0x000d, 0x2534: 0x000d, 0x2535: 0x000d,
- 0x2536: 0x000d, 0x2537: 0x000d, 0x2538: 0x000d, 0x2539: 0x000d, 0x253a: 0x000d, 0x253b: 0x000d,
- 0x253c: 0x000d, 0x253d: 0x000d, 0x253e: 0x000d, 0x253f: 0x000d,
- // Block 0x95, offset 0x2540
- 0x2540: 0x000d, 0x2541: 0x000d, 0x2542: 0x000d, 0x2543: 0x000d, 0x2544: 0x000d, 0x2545: 0x000d,
- 0x2546: 0x000d, 0x2547: 0x000d, 0x2548: 0x000d, 0x2549: 0x000d, 0x254a: 0x000d, 0x254b: 0x000d,
- 0x254c: 0x000d, 0x254d: 0x000d, 0x254e: 0x000d, 0x254f: 0x000d, 0x2550: 0x000d, 0x2551: 0x000d,
- 0x2552: 0x000d, 0x2553: 0x000d, 0x2554: 0x000d, 0x2555: 0x000d, 0x2556: 0x000d, 0x2557: 0x000d,
- 0x2558: 0x000d, 0x2559: 0x000d, 0x255a: 0x000d, 0x255b: 0x000d, 0x255c: 0x000d, 0x255d: 0x000d,
- 0x255e: 0x000d, 0x255f: 0x000d, 0x2560: 0x000d, 0x2561: 0x000d, 0x2562: 0x000d, 0x2563: 0x000d,
- 0x2564: 0x000d, 0x2565: 0x000d, 0x2566: 0x000d, 0x2567: 0x000d, 0x2568: 0x000d, 0x2569: 0x000d,
- 0x256a: 0x000d, 0x256b: 0x000d, 0x256c: 0x000d, 0x256d: 0x000d, 0x256e: 0x000d, 0x256f: 0x000d,
- 0x2570: 0x000d, 0x2571: 0x000d, 0x2572: 0x000d, 0x2573: 0x000d, 0x2574: 0x000d, 0x2575: 0x000d,
- 0x2576: 0x000d, 0x2577: 0x000d, 0x2578: 0x000d, 0x2579: 0x000d, 0x257a: 0x000d, 0x257b: 0x000d,
- 0x257c: 0x000d, 0x257d: 0x000d, 0x257e: 0x000d, 0x257f: 0x000b,
- // Block 0x96, offset 0x2580
- 0x2581: 0x000a, 0x2582: 0x000a, 0x2583: 0x0004, 0x2584: 0x0004, 0x2585: 0x0004,
- 0x2586: 0x000a, 0x2587: 0x000a, 0x2588: 0x003a, 0x2589: 0x002a, 0x258a: 0x000a, 0x258b: 0x0003,
- 0x258c: 0x0006, 0x258d: 0x0003, 0x258e: 0x0006, 0x258f: 0x0006, 0x2590: 0x0002, 0x2591: 0x0002,
- 0x2592: 0x0002, 0x2593: 0x0002, 0x2594: 0x0002, 0x2595: 0x0002, 0x2596: 0x0002, 0x2597: 0x0002,
- 0x2598: 0x0002, 0x2599: 0x0002, 0x259a: 0x0006, 0x259b: 0x000a, 0x259c: 0x000a, 0x259d: 0x000a,
- 0x259e: 0x000a, 0x259f: 0x000a, 0x25a0: 0x000a,
- 0x25bb: 0x005a,
- 0x25bc: 0x000a, 0x25bd: 0x004a, 0x25be: 0x000a, 0x25bf: 0x000a,
- // Block 0x97, offset 0x25c0
- 0x25c0: 0x000a,
- 0x25db: 0x005a, 0x25dc: 0x000a, 0x25dd: 0x004a,
- 0x25de: 0x000a, 0x25df: 0x00fa, 0x25e0: 0x00ea, 0x25e1: 0x000a, 0x25e2: 0x003a, 0x25e3: 0x002a,
- 0x25e4: 0x000a, 0x25e5: 0x000a,
- // Block 0x98, offset 0x2600
- 0x2620: 0x0004, 0x2621: 0x0004, 0x2622: 0x000a, 0x2623: 0x000a,
- 0x2624: 0x000a, 0x2625: 0x0004, 0x2626: 0x0004, 0x2628: 0x000a, 0x2629: 0x000a,
- 0x262a: 0x000a, 0x262b: 0x000a, 0x262c: 0x000a, 0x262d: 0x000a, 0x262e: 0x000a,
- 0x2630: 0x000b, 0x2631: 0x000b, 0x2632: 0x000b, 0x2633: 0x000b, 0x2634: 0x000b, 0x2635: 0x000b,
- 0x2636: 0x000b, 0x2637: 0x000b, 0x2638: 0x000b, 0x2639: 0x000a, 0x263a: 0x000a, 0x263b: 0x000a,
- 0x263c: 0x000a, 0x263d: 0x000a, 0x263e: 0x000b, 0x263f: 0x000b,
- // Block 0x99, offset 0x2640
- 0x2641: 0x000a,
- // Block 0x9a, offset 0x2680
- 0x2680: 0x000a, 0x2681: 0x000a, 0x2682: 0x000a, 0x2683: 0x000a, 0x2684: 0x000a, 0x2685: 0x000a,
- 0x2686: 0x000a, 0x2687: 0x000a, 0x2688: 0x000a, 0x2689: 0x000a, 0x268a: 0x000a, 0x268b: 0x000a,
- 0x268c: 0x000a, 0x2690: 0x000a, 0x2691: 0x000a,
- 0x2692: 0x000a, 0x2693: 0x000a, 0x2694: 0x000a, 0x2695: 0x000a, 0x2696: 0x000a, 0x2697: 0x000a,
- 0x2698: 0x000a, 0x2699: 0x000a, 0x269a: 0x000a, 0x269b: 0x000a, 0x269c: 0x000a,
- 0x26a0: 0x000a,
- // Block 0x9b, offset 0x26c0
- 0x26fd: 0x000c,
- // Block 0x9c, offset 0x2700
- 0x2720: 0x000c, 0x2721: 0x0002, 0x2722: 0x0002, 0x2723: 0x0002,
- 0x2724: 0x0002, 0x2725: 0x0002, 0x2726: 0x0002, 0x2727: 0x0002, 0x2728: 0x0002, 0x2729: 0x0002,
- 0x272a: 0x0002, 0x272b: 0x0002, 0x272c: 0x0002, 0x272d: 0x0002, 0x272e: 0x0002, 0x272f: 0x0002,
- 0x2730: 0x0002, 0x2731: 0x0002, 0x2732: 0x0002, 0x2733: 0x0002, 0x2734: 0x0002, 0x2735: 0x0002,
- 0x2736: 0x0002, 0x2737: 0x0002, 0x2738: 0x0002, 0x2739: 0x0002, 0x273a: 0x0002, 0x273b: 0x0002,
- // Block 0x9d, offset 0x2740
- 0x2776: 0x000c, 0x2777: 0x000c, 0x2778: 0x000c, 0x2779: 0x000c, 0x277a: 0x000c,
- // Block 0x9e, offset 0x2780
- 0x2780: 0x0001, 0x2781: 0x0001, 0x2782: 0x0001, 0x2783: 0x0001, 0x2784: 0x0001, 0x2785: 0x0001,
- 0x2786: 0x0001, 0x2787: 0x0001, 0x2788: 0x0001, 0x2789: 0x0001, 0x278a: 0x0001, 0x278b: 0x0001,
- 0x278c: 0x0001, 0x278d: 0x0001, 0x278e: 0x0001, 0x278f: 0x0001, 0x2790: 0x0001, 0x2791: 0x0001,
- 0x2792: 0x0001, 0x2793: 0x0001, 0x2794: 0x0001, 0x2795: 0x0001, 0x2796: 0x0001, 0x2797: 0x0001,
- 0x2798: 0x0001, 0x2799: 0x0001, 0x279a: 0x0001, 0x279b: 0x0001, 0x279c: 0x0001, 0x279d: 0x0001,
- 0x279e: 0x0001, 0x279f: 0x0001, 0x27a0: 0x0001, 0x27a1: 0x0001, 0x27a2: 0x0001, 0x27a3: 0x0001,
- 0x27a4: 0x0001, 0x27a5: 0x0001, 0x27a6: 0x0001, 0x27a7: 0x0001, 0x27a8: 0x0001, 0x27a9: 0x0001,
- 0x27aa: 0x0001, 0x27ab: 0x0001, 0x27ac: 0x0001, 0x27ad: 0x0001, 0x27ae: 0x0001, 0x27af: 0x0001,
- 0x27b0: 0x0001, 0x27b1: 0x0001, 0x27b2: 0x0001, 0x27b3: 0x0001, 0x27b4: 0x0001, 0x27b5: 0x0001,
- 0x27b6: 0x0001, 0x27b7: 0x0001, 0x27b8: 0x0001, 0x27b9: 0x0001, 0x27ba: 0x0001, 0x27bb: 0x0001,
- 0x27bc: 0x0001, 0x27bd: 0x0001, 0x27be: 0x0001, 0x27bf: 0x0001,
- // Block 0x9f, offset 0x27c0
- 0x27c0: 0x0001, 0x27c1: 0x0001, 0x27c2: 0x0001, 0x27c3: 0x0001, 0x27c4: 0x0001, 0x27c5: 0x0001,
- 0x27c6: 0x0001, 0x27c7: 0x0001, 0x27c8: 0x0001, 0x27c9: 0x0001, 0x27ca: 0x0001, 0x27cb: 0x0001,
- 0x27cc: 0x0001, 0x27cd: 0x0001, 0x27ce: 0x0001, 0x27cf: 0x0001, 0x27d0: 0x0001, 0x27d1: 0x0001,
- 0x27d2: 0x0001, 0x27d3: 0x0001, 0x27d4: 0x0001, 0x27d5: 0x0001, 0x27d6: 0x0001, 0x27d7: 0x0001,
- 0x27d8: 0x0001, 0x27d9: 0x0001, 0x27da: 0x0001, 0x27db: 0x0001, 0x27dc: 0x0001, 0x27dd: 0x0001,
- 0x27de: 0x0001, 0x27df: 0x000a, 0x27e0: 0x0001, 0x27e1: 0x0001, 0x27e2: 0x0001, 0x27e3: 0x0001,
- 0x27e4: 0x0001, 0x27e5: 0x0001, 0x27e6: 0x0001, 0x27e7: 0x0001, 0x27e8: 0x0001, 0x27e9: 0x0001,
- 0x27ea: 0x0001, 0x27eb: 0x0001, 0x27ec: 0x0001, 0x27ed: 0x0001, 0x27ee: 0x0001, 0x27ef: 0x0001,
- 0x27f0: 0x0001, 0x27f1: 0x0001, 0x27f2: 0x0001, 0x27f3: 0x0001, 0x27f4: 0x0001, 0x27f5: 0x0001,
- 0x27f6: 0x0001, 0x27f7: 0x0001, 0x27f8: 0x0001, 0x27f9: 0x0001, 0x27fa: 0x0001, 0x27fb: 0x0001,
- 0x27fc: 0x0001, 0x27fd: 0x0001, 0x27fe: 0x0001, 0x27ff: 0x0001,
- // Block 0xa0, offset 0x2800
- 0x2800: 0x0001, 0x2801: 0x000c, 0x2802: 0x000c, 0x2803: 0x000c, 0x2804: 0x0001, 0x2805: 0x000c,
- 0x2806: 0x000c, 0x2807: 0x0001, 0x2808: 0x0001, 0x2809: 0x0001, 0x280a: 0x0001, 0x280b: 0x0001,
- 0x280c: 0x000c, 0x280d: 0x000c, 0x280e: 0x000c, 0x280f: 0x000c, 0x2810: 0x0001, 0x2811: 0x0001,
- 0x2812: 0x0001, 0x2813: 0x0001, 0x2814: 0x0001, 0x2815: 0x0001, 0x2816: 0x0001, 0x2817: 0x0001,
- 0x2818: 0x0001, 0x2819: 0x0001, 0x281a: 0x0001, 0x281b: 0x0001, 0x281c: 0x0001, 0x281d: 0x0001,
- 0x281e: 0x0001, 0x281f: 0x0001, 0x2820: 0x0001, 0x2821: 0x0001, 0x2822: 0x0001, 0x2823: 0x0001,
- 0x2824: 0x0001, 0x2825: 0x0001, 0x2826: 0x0001, 0x2827: 0x0001, 0x2828: 0x0001, 0x2829: 0x0001,
- 0x282a: 0x0001, 0x282b: 0x0001, 0x282c: 0x0001, 0x282d: 0x0001, 0x282e: 0x0001, 0x282f: 0x0001,
- 0x2830: 0x0001, 0x2831: 0x0001, 0x2832: 0x0001, 0x2833: 0x0001, 0x2834: 0x0001, 0x2835: 0x0001,
- 0x2836: 0x0001, 0x2837: 0x0001, 0x2838: 0x000c, 0x2839: 0x000c, 0x283a: 0x000c, 0x283b: 0x0001,
- 0x283c: 0x0001, 0x283d: 0x0001, 0x283e: 0x0001, 0x283f: 0x000c,
- // Block 0xa1, offset 0x2840
- 0x2840: 0x0001, 0x2841: 0x0001, 0x2842: 0x0001, 0x2843: 0x0001, 0x2844: 0x0001, 0x2845: 0x0001,
- 0x2846: 0x0001, 0x2847: 0x0001, 0x2848: 0x0001, 0x2849: 0x0001, 0x284a: 0x0001, 0x284b: 0x0001,
- 0x284c: 0x0001, 0x284d: 0x0001, 0x284e: 0x0001, 0x284f: 0x0001, 0x2850: 0x0001, 0x2851: 0x0001,
- 0x2852: 0x0001, 0x2853: 0x0001, 0x2854: 0x0001, 0x2855: 0x0001, 0x2856: 0x0001, 0x2857: 0x0001,
- 0x2858: 0x0001, 0x2859: 0x0001, 0x285a: 0x0001, 0x285b: 0x0001, 0x285c: 0x0001, 0x285d: 0x0001,
- 0x285e: 0x0001, 0x285f: 0x0001, 0x2860: 0x0001, 0x2861: 0x0001, 0x2862: 0x0001, 0x2863: 0x0001,
- 0x2864: 0x0001, 0x2865: 0x000c, 0x2866: 0x000c, 0x2867: 0x0001, 0x2868: 0x0001, 0x2869: 0x0001,
- 0x286a: 0x0001, 0x286b: 0x0001, 0x286c: 0x0001, 0x286d: 0x0001, 0x286e: 0x0001, 0x286f: 0x0001,
- 0x2870: 0x0001, 0x2871: 0x0001, 0x2872: 0x0001, 0x2873: 0x0001, 0x2874: 0x0001, 0x2875: 0x0001,
- 0x2876: 0x0001, 0x2877: 0x0001, 0x2878: 0x0001, 0x2879: 0x0001, 0x287a: 0x0001, 0x287b: 0x0001,
- 0x287c: 0x0001, 0x287d: 0x0001, 0x287e: 0x0001, 0x287f: 0x0001,
- // Block 0xa2, offset 0x2880
- 0x2880: 0x0001, 0x2881: 0x0001, 0x2882: 0x0001, 0x2883: 0x0001, 0x2884: 0x0001, 0x2885: 0x0001,
- 0x2886: 0x0001, 0x2887: 0x0001, 0x2888: 0x0001, 0x2889: 0x0001, 0x288a: 0x0001, 0x288b: 0x0001,
- 0x288c: 0x0001, 0x288d: 0x0001, 0x288e: 0x0001, 0x288f: 0x0001, 0x2890: 0x0001, 0x2891: 0x0001,
- 0x2892: 0x0001, 0x2893: 0x0001, 0x2894: 0x0001, 0x2895: 0x0001, 0x2896: 0x0001, 0x2897: 0x0001,
- 0x2898: 0x0001, 0x2899: 0x0001, 0x289a: 0x0001, 0x289b: 0x0001, 0x289c: 0x0001, 0x289d: 0x0001,
- 0x289e: 0x0001, 0x289f: 0x0001, 0x28a0: 0x0001, 0x28a1: 0x0001, 0x28a2: 0x0001, 0x28a3: 0x0001,
- 0x28a4: 0x0001, 0x28a5: 0x0001, 0x28a6: 0x0001, 0x28a7: 0x0001, 0x28a8: 0x0001, 0x28a9: 0x0001,
- 0x28aa: 0x0001, 0x28ab: 0x0001, 0x28ac: 0x0001, 0x28ad: 0x0001, 0x28ae: 0x0001, 0x28af: 0x0001,
- 0x28b0: 0x0001, 0x28b1: 0x0001, 0x28b2: 0x0001, 0x28b3: 0x0001, 0x28b4: 0x0001, 0x28b5: 0x0001,
- 0x28b6: 0x0001, 0x28b7: 0x0001, 0x28b8: 0x0001, 0x28b9: 0x000a, 0x28ba: 0x000a, 0x28bb: 0x000a,
- 0x28bc: 0x000a, 0x28bd: 0x000a, 0x28be: 0x000a, 0x28bf: 0x000a,
- // Block 0xa3, offset 0x28c0
- 0x28c0: 0x000d, 0x28c1: 0x000d, 0x28c2: 0x000d, 0x28c3: 0x000d, 0x28c4: 0x000d, 0x28c5: 0x000d,
- 0x28c6: 0x000d, 0x28c7: 0x000d, 0x28c8: 0x000d, 0x28c9: 0x000d, 0x28ca: 0x000d, 0x28cb: 0x000d,
- 0x28cc: 0x000d, 0x28cd: 0x000d, 0x28ce: 0x000d, 0x28cf: 0x000d, 0x28d0: 0x000d, 0x28d1: 0x000d,
- 0x28d2: 0x000d, 0x28d3: 0x000d, 0x28d4: 0x000d, 0x28d5: 0x000d, 0x28d6: 0x000d, 0x28d7: 0x000d,
- 0x28d8: 0x000d, 0x28d9: 0x000d, 0x28da: 0x000d, 0x28db: 0x000d, 0x28dc: 0x000d, 0x28dd: 0x000d,
- 0x28de: 0x000d, 0x28df: 0x000d, 0x28e0: 0x000d, 0x28e1: 0x000d, 0x28e2: 0x000d, 0x28e3: 0x000d,
- 0x28e4: 0x000c, 0x28e5: 0x000c, 0x28e6: 0x000c, 0x28e7: 0x000c, 0x28e8: 0x000d, 0x28e9: 0x000d,
- 0x28ea: 0x000d, 0x28eb: 0x000d, 0x28ec: 0x000d, 0x28ed: 0x000d, 0x28ee: 0x000d, 0x28ef: 0x000d,
- 0x28f0: 0x0005, 0x28f1: 0x0005, 0x28f2: 0x0005, 0x28f3: 0x0005, 0x28f4: 0x0005, 0x28f5: 0x0005,
- 0x28f6: 0x0005, 0x28f7: 0x0005, 0x28f8: 0x0005, 0x28f9: 0x0005, 0x28fa: 0x000d, 0x28fb: 0x000d,
- 0x28fc: 0x000d, 0x28fd: 0x000d, 0x28fe: 0x000d, 0x28ff: 0x000d,
- // Block 0xa4, offset 0x2900
- 0x2900: 0x0001, 0x2901: 0x0001, 0x2902: 0x0001, 0x2903: 0x0001, 0x2904: 0x0001, 0x2905: 0x0001,
- 0x2906: 0x0001, 0x2907: 0x0001, 0x2908: 0x0001, 0x2909: 0x0001, 0x290a: 0x0001, 0x290b: 0x0001,
- 0x290c: 0x0001, 0x290d: 0x0001, 0x290e: 0x0001, 0x290f: 0x0001, 0x2910: 0x0001, 0x2911: 0x0001,
- 0x2912: 0x0001, 0x2913: 0x0001, 0x2914: 0x0001, 0x2915: 0x0001, 0x2916: 0x0001, 0x2917: 0x0001,
- 0x2918: 0x0001, 0x2919: 0x0001, 0x291a: 0x0001, 0x291b: 0x0001, 0x291c: 0x0001, 0x291d: 0x0001,
- 0x291e: 0x0001, 0x291f: 0x0001, 0x2920: 0x0005, 0x2921: 0x0005, 0x2922: 0x0005, 0x2923: 0x0005,
- 0x2924: 0x0005, 0x2925: 0x0005, 0x2926: 0x0005, 0x2927: 0x0005, 0x2928: 0x0005, 0x2929: 0x0005,
- 0x292a: 0x0005, 0x292b: 0x0005, 0x292c: 0x0005, 0x292d: 0x0005, 0x292e: 0x0005, 0x292f: 0x0005,
- 0x2930: 0x0005, 0x2931: 0x0005, 0x2932: 0x0005, 0x2933: 0x0005, 0x2934: 0x0005, 0x2935: 0x0005,
- 0x2936: 0x0005, 0x2937: 0x0005, 0x2938: 0x0005, 0x2939: 0x0005, 0x293a: 0x0005, 0x293b: 0x0005,
- 0x293c: 0x0005, 0x293d: 0x0005, 0x293e: 0x0005, 0x293f: 0x0001,
- // Block 0xa5, offset 0x2940
- 0x2940: 0x0001, 0x2941: 0x0001, 0x2942: 0x0001, 0x2943: 0x0001, 0x2944: 0x0001, 0x2945: 0x0001,
- 0x2946: 0x0001, 0x2947: 0x0001, 0x2948: 0x0001, 0x2949: 0x0001, 0x294a: 0x0001, 0x294b: 0x0001,
- 0x294c: 0x0001, 0x294d: 0x0001, 0x294e: 0x0001, 0x294f: 0x0001, 0x2950: 0x0001, 0x2951: 0x0001,
- 0x2952: 0x0001, 0x2953: 0x0001, 0x2954: 0x0001, 0x2955: 0x0001, 0x2956: 0x0001, 0x2957: 0x0001,
- 0x2958: 0x0001, 0x2959: 0x0001, 0x295a: 0x0001, 0x295b: 0x0001, 0x295c: 0x0001, 0x295d: 0x0001,
- 0x295e: 0x0001, 0x295f: 0x0001, 0x2960: 0x0001, 0x2961: 0x0001, 0x2962: 0x0001, 0x2963: 0x0001,
- 0x2964: 0x0001, 0x2965: 0x0001, 0x2966: 0x0001, 0x2967: 0x0001, 0x2968: 0x0001, 0x2969: 0x0001,
- 0x296a: 0x0001, 0x296b: 0x000c, 0x296c: 0x000c, 0x296d: 0x0001, 0x296e: 0x0001, 0x296f: 0x0001,
- 0x2970: 0x0001, 0x2971: 0x0001, 0x2972: 0x0001, 0x2973: 0x0001, 0x2974: 0x0001, 0x2975: 0x0001,
- 0x2976: 0x0001, 0x2977: 0x0001, 0x2978: 0x0001, 0x2979: 0x0001, 0x297a: 0x0001, 0x297b: 0x0001,
- 0x297c: 0x0001, 0x297d: 0x0001, 0x297e: 0x0001, 0x297f: 0x0001,
- // Block 0xa6, offset 0x2980
- 0x2980: 0x0001, 0x2981: 0x0001, 0x2982: 0x0001, 0x2983: 0x0001, 0x2984: 0x0001, 0x2985: 0x0001,
- 0x2986: 0x0001, 0x2987: 0x0001, 0x2988: 0x0001, 0x2989: 0x0001, 0x298a: 0x0001, 0x298b: 0x0001,
- 0x298c: 0x0001, 0x298d: 0x0001, 0x298e: 0x0001, 0x298f: 0x0001, 0x2990: 0x0001, 0x2991: 0x0001,
- 0x2992: 0x0001, 0x2993: 0x0001, 0x2994: 0x0001, 0x2995: 0x0001, 0x2996: 0x0001, 0x2997: 0x0001,
- 0x2998: 0x0001, 0x2999: 0x0001, 0x299a: 0x0001, 0x299b: 0x0001, 0x299c: 0x0001, 0x299d: 0x0001,
- 0x299e: 0x0001, 0x299f: 0x0001, 0x29a0: 0x0001, 0x29a1: 0x0001, 0x29a2: 0x0001, 0x29a3: 0x0001,
- 0x29a4: 0x0001, 0x29a5: 0x0001, 0x29a6: 0x0001, 0x29a7: 0x0001, 0x29a8: 0x0001, 0x29a9: 0x0001,
- 0x29aa: 0x0001, 0x29ab: 0x0001, 0x29ac: 0x0001, 0x29ad: 0x0001, 0x29ae: 0x0001, 0x29af: 0x0001,
- 0x29b0: 0x000d, 0x29b1: 0x000d, 0x29b2: 0x000d, 0x29b3: 0x000d, 0x29b4: 0x000d, 0x29b5: 0x000d,
- 0x29b6: 0x000d, 0x29b7: 0x000d, 0x29b8: 0x000d, 0x29b9: 0x000d, 0x29ba: 0x000d, 0x29bb: 0x000d,
- 0x29bc: 0x000d, 0x29bd: 0x000d, 0x29be: 0x000d, 0x29bf: 0x000d,
- // Block 0xa7, offset 0x29c0
- 0x29c0: 0x000d, 0x29c1: 0x000d, 0x29c2: 0x000d, 0x29c3: 0x000d, 0x29c4: 0x000d, 0x29c5: 0x000d,
- 0x29c6: 0x000c, 0x29c7: 0x000c, 0x29c8: 0x000c, 0x29c9: 0x000c, 0x29ca: 0x000c, 0x29cb: 0x000c,
- 0x29cc: 0x000c, 0x29cd: 0x000c, 0x29ce: 0x000c, 0x29cf: 0x000c, 0x29d0: 0x000c, 0x29d1: 0x000d,
- 0x29d2: 0x000d, 0x29d3: 0x000d, 0x29d4: 0x000d, 0x29d5: 0x000d, 0x29d6: 0x000d, 0x29d7: 0x000d,
- 0x29d8: 0x000d, 0x29d9: 0x000d, 0x29da: 0x000d, 0x29db: 0x000d, 0x29dc: 0x000d, 0x29dd: 0x000d,
- 0x29de: 0x000d, 0x29df: 0x000d, 0x29e0: 0x000d, 0x29e1: 0x000d, 0x29e2: 0x000d, 0x29e3: 0x000d,
- 0x29e4: 0x000d, 0x29e5: 0x000d, 0x29e6: 0x000d, 0x29e7: 0x000d, 0x29e8: 0x000d, 0x29e9: 0x000d,
- 0x29ea: 0x000d, 0x29eb: 0x000d, 0x29ec: 0x000d, 0x29ed: 0x000d, 0x29ee: 0x000d, 0x29ef: 0x000d,
- 0x29f0: 0x0001, 0x29f1: 0x0001, 0x29f2: 0x0001, 0x29f3: 0x0001, 0x29f4: 0x0001, 0x29f5: 0x0001,
- 0x29f6: 0x0001, 0x29f7: 0x0001, 0x29f8: 0x0001, 0x29f9: 0x0001, 0x29fa: 0x0001, 0x29fb: 0x0001,
- 0x29fc: 0x0001, 0x29fd: 0x0001, 0x29fe: 0x0001, 0x29ff: 0x0001,
- // Block 0xa8, offset 0x2a00
- 0x2a01: 0x000c,
- 0x2a38: 0x000c, 0x2a39: 0x000c, 0x2a3a: 0x000c, 0x2a3b: 0x000c,
- 0x2a3c: 0x000c, 0x2a3d: 0x000c, 0x2a3e: 0x000c, 0x2a3f: 0x000c,
- // Block 0xa9, offset 0x2a40
- 0x2a40: 0x000c, 0x2a41: 0x000c, 0x2a42: 0x000c, 0x2a43: 0x000c, 0x2a44: 0x000c, 0x2a45: 0x000c,
- 0x2a46: 0x000c,
- 0x2a52: 0x000a, 0x2a53: 0x000a, 0x2a54: 0x000a, 0x2a55: 0x000a, 0x2a56: 0x000a, 0x2a57: 0x000a,
- 0x2a58: 0x000a, 0x2a59: 0x000a, 0x2a5a: 0x000a, 0x2a5b: 0x000a, 0x2a5c: 0x000a, 0x2a5d: 0x000a,
- 0x2a5e: 0x000a, 0x2a5f: 0x000a, 0x2a60: 0x000a, 0x2a61: 0x000a, 0x2a62: 0x000a, 0x2a63: 0x000a,
- 0x2a64: 0x000a, 0x2a65: 0x000a,
- 0x2a7f: 0x000c,
- // Block 0xaa, offset 0x2a80
- 0x2a80: 0x000c, 0x2a81: 0x000c,
- 0x2ab3: 0x000c, 0x2ab4: 0x000c, 0x2ab5: 0x000c,
- 0x2ab6: 0x000c, 0x2ab9: 0x000c, 0x2aba: 0x000c,
- // Block 0xab, offset 0x2ac0
- 0x2ac0: 0x000c, 0x2ac1: 0x000c, 0x2ac2: 0x000c,
- 0x2ae7: 0x000c, 0x2ae8: 0x000c, 0x2ae9: 0x000c,
- 0x2aea: 0x000c, 0x2aeb: 0x000c, 0x2aed: 0x000c, 0x2aee: 0x000c, 0x2aef: 0x000c,
- 0x2af0: 0x000c, 0x2af1: 0x000c, 0x2af2: 0x000c, 0x2af3: 0x000c, 0x2af4: 0x000c,
- // Block 0xac, offset 0x2b00
- 0x2b33: 0x000c,
- // Block 0xad, offset 0x2b40
- 0x2b40: 0x000c, 0x2b41: 0x000c,
- 0x2b76: 0x000c, 0x2b77: 0x000c, 0x2b78: 0x000c, 0x2b79: 0x000c, 0x2b7a: 0x000c, 0x2b7b: 0x000c,
- 0x2b7c: 0x000c, 0x2b7d: 0x000c, 0x2b7e: 0x000c,
- // Block 0xae, offset 0x2b80
- 0x2b89: 0x000c, 0x2b8a: 0x000c, 0x2b8b: 0x000c,
- 0x2b8c: 0x000c, 0x2b8f: 0x000c,
- // Block 0xaf, offset 0x2bc0
- 0x2bef: 0x000c,
- 0x2bf0: 0x000c, 0x2bf1: 0x000c, 0x2bf4: 0x000c,
- 0x2bf6: 0x000c, 0x2bf7: 0x000c,
- 0x2bfe: 0x000c,
- // Block 0xb0, offset 0x2c00
- 0x2c1f: 0x000c, 0x2c23: 0x000c,
- 0x2c24: 0x000c, 0x2c25: 0x000c, 0x2c26: 0x000c, 0x2c27: 0x000c, 0x2c28: 0x000c, 0x2c29: 0x000c,
- 0x2c2a: 0x000c,
- // Block 0xb1, offset 0x2c40
- 0x2c40: 0x000c,
- 0x2c66: 0x000c, 0x2c67: 0x000c, 0x2c68: 0x000c, 0x2c69: 0x000c,
- 0x2c6a: 0x000c, 0x2c6b: 0x000c, 0x2c6c: 0x000c,
- 0x2c70: 0x000c, 0x2c71: 0x000c, 0x2c72: 0x000c, 0x2c73: 0x000c, 0x2c74: 0x000c,
- // Block 0xb2, offset 0x2c80
- 0x2cb8: 0x000c, 0x2cb9: 0x000c, 0x2cba: 0x000c, 0x2cbb: 0x000c,
- 0x2cbc: 0x000c, 0x2cbd: 0x000c, 0x2cbe: 0x000c, 0x2cbf: 0x000c,
- // Block 0xb3, offset 0x2cc0
- 0x2cc2: 0x000c, 0x2cc3: 0x000c, 0x2cc4: 0x000c,
- 0x2cc6: 0x000c,
- 0x2cde: 0x000c,
- // Block 0xb4, offset 0x2d00
- 0x2d33: 0x000c, 0x2d34: 0x000c, 0x2d35: 0x000c,
- 0x2d36: 0x000c, 0x2d37: 0x000c, 0x2d38: 0x000c, 0x2d3a: 0x000c,
- 0x2d3f: 0x000c,
- // Block 0xb5, offset 0x2d40
- 0x2d40: 0x000c, 0x2d42: 0x000c, 0x2d43: 0x000c,
- // Block 0xb6, offset 0x2d80
- 0x2db2: 0x000c, 0x2db3: 0x000c, 0x2db4: 0x000c, 0x2db5: 0x000c,
- 0x2dbc: 0x000c, 0x2dbd: 0x000c, 0x2dbf: 0x000c,
- // Block 0xb7, offset 0x2dc0
- 0x2dc0: 0x000c,
- 0x2ddc: 0x000c, 0x2ddd: 0x000c,
- // Block 0xb8, offset 0x2e00
- 0x2e33: 0x000c, 0x2e34: 0x000c, 0x2e35: 0x000c,
- 0x2e36: 0x000c, 0x2e37: 0x000c, 0x2e38: 0x000c, 0x2e39: 0x000c, 0x2e3a: 0x000c,
- 0x2e3d: 0x000c, 0x2e3f: 0x000c,
- // Block 0xb9, offset 0x2e40
- 0x2e40: 0x000c,
- 0x2e60: 0x000a, 0x2e61: 0x000a, 0x2e62: 0x000a, 0x2e63: 0x000a,
- 0x2e64: 0x000a, 0x2e65: 0x000a, 0x2e66: 0x000a, 0x2e67: 0x000a, 0x2e68: 0x000a, 0x2e69: 0x000a,
- 0x2e6a: 0x000a, 0x2e6b: 0x000a, 0x2e6c: 0x000a,
- // Block 0xba, offset 0x2e80
- 0x2eab: 0x000c, 0x2ead: 0x000c,
- 0x2eb0: 0x000c, 0x2eb1: 0x000c, 0x2eb2: 0x000c, 0x2eb3: 0x000c, 0x2eb4: 0x000c, 0x2eb5: 0x000c,
- 0x2eb7: 0x000c,
- // Block 0xbb, offset 0x2ec0
- 0x2edd: 0x000c,
- 0x2ede: 0x000c, 0x2edf: 0x000c, 0x2ee2: 0x000c, 0x2ee3: 0x000c,
- 0x2ee4: 0x000c, 0x2ee5: 0x000c, 0x2ee7: 0x000c, 0x2ee8: 0x000c, 0x2ee9: 0x000c,
- 0x2eea: 0x000c, 0x2eeb: 0x000c,
- // Block 0xbc, offset 0x2f00
- 0x2f2f: 0x000c,
- 0x2f30: 0x000c, 0x2f31: 0x000c, 0x2f32: 0x000c, 0x2f33: 0x000c, 0x2f34: 0x000c, 0x2f35: 0x000c,
- 0x2f36: 0x000c, 0x2f37: 0x000c, 0x2f39: 0x000c, 0x2f3a: 0x000c,
- // Block 0xbd, offset 0x2f40
- 0x2f7b: 0x000c,
- 0x2f7c: 0x000c, 0x2f7e: 0x000c,
- // Block 0xbe, offset 0x2f80
- 0x2f83: 0x000c,
- // Block 0xbf, offset 0x2fc0
- 0x2fd4: 0x000c, 0x2fd5: 0x000c, 0x2fd6: 0x000c, 0x2fd7: 0x000c,
- 0x2fda: 0x000c, 0x2fdb: 0x000c,
- 0x2fe0: 0x000c,
- // Block 0xc0, offset 0x3000
- 0x3001: 0x000c, 0x3002: 0x000c, 0x3003: 0x000c, 0x3004: 0x000c, 0x3005: 0x000c,
- 0x3006: 0x000c, 0x3009: 0x000c, 0x300a: 0x000c,
- 0x3033: 0x000c, 0x3034: 0x000c, 0x3035: 0x000c,
- 0x3036: 0x000c, 0x3037: 0x000c, 0x3038: 0x000c, 0x303b: 0x000c,
- 0x303c: 0x000c, 0x303d: 0x000c, 0x303e: 0x000c,
- // Block 0xc1, offset 0x3040
- 0x3047: 0x000c,
- 0x3051: 0x000c,
- 0x3052: 0x000c, 0x3053: 0x000c, 0x3054: 0x000c, 0x3055: 0x000c, 0x3056: 0x000c,
- 0x3059: 0x000c, 0x305a: 0x000c, 0x305b: 0x000c,
- // Block 0xc2, offset 0x3080
- 0x308a: 0x000c, 0x308b: 0x000c,
- 0x308c: 0x000c, 0x308d: 0x000c, 0x308e: 0x000c, 0x308f: 0x000c, 0x3090: 0x000c, 0x3091: 0x000c,
- 0x3092: 0x000c, 0x3093: 0x000c, 0x3094: 0x000c, 0x3095: 0x000c, 0x3096: 0x000c,
- 0x3098: 0x000c, 0x3099: 0x000c,
- // Block 0xc3, offset 0x30c0
- 0x30f0: 0x000c, 0x30f1: 0x000c, 0x30f2: 0x000c, 0x30f3: 0x000c, 0x30f4: 0x000c, 0x30f5: 0x000c,
- 0x30f6: 0x000c, 0x30f8: 0x000c, 0x30f9: 0x000c, 0x30fa: 0x000c, 0x30fb: 0x000c,
- 0x30fc: 0x000c, 0x30fd: 0x000c,
- // Block 0xc4, offset 0x3100
- 0x3112: 0x000c, 0x3113: 0x000c, 0x3114: 0x000c, 0x3115: 0x000c, 0x3116: 0x000c, 0x3117: 0x000c,
- 0x3118: 0x000c, 0x3119: 0x000c, 0x311a: 0x000c, 0x311b: 0x000c, 0x311c: 0x000c, 0x311d: 0x000c,
- 0x311e: 0x000c, 0x311f: 0x000c, 0x3120: 0x000c, 0x3121: 0x000c, 0x3122: 0x000c, 0x3123: 0x000c,
- 0x3124: 0x000c, 0x3125: 0x000c, 0x3126: 0x000c, 0x3127: 0x000c,
- 0x312a: 0x000c, 0x312b: 0x000c, 0x312c: 0x000c, 0x312d: 0x000c, 0x312e: 0x000c, 0x312f: 0x000c,
- 0x3130: 0x000c, 0x3132: 0x000c, 0x3133: 0x000c, 0x3135: 0x000c,
- 0x3136: 0x000c,
- // Block 0xc5, offset 0x3140
- 0x3171: 0x000c, 0x3172: 0x000c, 0x3173: 0x000c, 0x3174: 0x000c, 0x3175: 0x000c,
- 0x3176: 0x000c, 0x317a: 0x000c,
- 0x317c: 0x000c, 0x317d: 0x000c, 0x317f: 0x000c,
- // Block 0xc6, offset 0x3180
- 0x3180: 0x000c, 0x3181: 0x000c, 0x3182: 0x000c, 0x3183: 0x000c, 0x3184: 0x000c, 0x3185: 0x000c,
- 0x3187: 0x000c,
- // Block 0xc7, offset 0x31c0
- 0x31d0: 0x000c, 0x31d1: 0x000c,
- 0x31d5: 0x000c, 0x31d7: 0x000c,
- // Block 0xc8, offset 0x3200
- 0x3233: 0x000c, 0x3234: 0x000c,
- // Block 0xc9, offset 0x3240
- 0x3255: 0x000a, 0x3256: 0x000a, 0x3257: 0x000a,
- 0x3258: 0x000a, 0x3259: 0x000a, 0x325a: 0x000a, 0x325b: 0x000a, 0x325c: 0x000a, 0x325d: 0x0004,
- 0x325e: 0x0004, 0x325f: 0x0004, 0x3260: 0x0004, 0x3261: 0x000a, 0x3262: 0x000a, 0x3263: 0x000a,
- 0x3264: 0x000a, 0x3265: 0x000a, 0x3266: 0x000a, 0x3267: 0x000a, 0x3268: 0x000a, 0x3269: 0x000a,
- 0x326a: 0x000a, 0x326b: 0x000a, 0x326c: 0x000a, 0x326d: 0x000a, 0x326e: 0x000a, 0x326f: 0x000a,
- 0x3270: 0x000a, 0x3271: 0x000a,
- // Block 0xca, offset 0x3280
- 0x32b0: 0x000c, 0x32b1: 0x000c, 0x32b2: 0x000c, 0x32b3: 0x000c, 0x32b4: 0x000c,
- // Block 0xcb, offset 0x32c0
- 0x32f0: 0x000c, 0x32f1: 0x000c, 0x32f2: 0x000c, 0x32f3: 0x000c, 0x32f4: 0x000c, 0x32f5: 0x000c,
- 0x32f6: 0x000c,
- // Block 0xcc, offset 0x3300
- 0x330f: 0x000c,
- // Block 0xcd, offset 0x3340
- 0x334f: 0x000c, 0x3350: 0x000c, 0x3351: 0x000c,
- 0x3352: 0x000c,
- // Block 0xce, offset 0x3380
- 0x33a2: 0x000a,
- 0x33a4: 0x000c,
- // Block 0xcf, offset 0x33c0
- 0x33dd: 0x000c,
- 0x33de: 0x000c, 0x33e0: 0x000b, 0x33e1: 0x000b, 0x33e2: 0x000b, 0x33e3: 0x000b,
- // Block 0xd0, offset 0x3400
- 0x3427: 0x000c, 0x3428: 0x000c, 0x3429: 0x000c,
- 0x3433: 0x000b, 0x3434: 0x000b, 0x3435: 0x000b,
- 0x3436: 0x000b, 0x3437: 0x000b, 0x3438: 0x000b, 0x3439: 0x000b, 0x343a: 0x000b, 0x343b: 0x000c,
- 0x343c: 0x000c, 0x343d: 0x000c, 0x343e: 0x000c, 0x343f: 0x000c,
- // Block 0xd1, offset 0x3440
- 0x3440: 0x000c, 0x3441: 0x000c, 0x3442: 0x000c, 0x3445: 0x000c,
- 0x3446: 0x000c, 0x3447: 0x000c, 0x3448: 0x000c, 0x3449: 0x000c, 0x344a: 0x000c, 0x344b: 0x000c,
- 0x346a: 0x000c, 0x346b: 0x000c, 0x346c: 0x000c, 0x346d: 0x000c,
- // Block 0xd2, offset 0x3480
- 0x3480: 0x000a, 0x3481: 0x000a, 0x3482: 0x000c, 0x3483: 0x000c, 0x3484: 0x000c, 0x3485: 0x000a,
- // Block 0xd3, offset 0x34c0
- 0x34c0: 0x000a, 0x34c1: 0x000a, 0x34c2: 0x000a, 0x34c3: 0x000a, 0x34c4: 0x000a, 0x34c5: 0x000a,
- 0x34c6: 0x000a, 0x34c7: 0x000a, 0x34c8: 0x000a, 0x34c9: 0x000a, 0x34ca: 0x000a, 0x34cb: 0x000a,
- 0x34cc: 0x000a, 0x34cd: 0x000a, 0x34ce: 0x000a, 0x34cf: 0x000a, 0x34d0: 0x000a, 0x34d1: 0x000a,
- 0x34d2: 0x000a, 0x34d3: 0x000a, 0x34d4: 0x000a, 0x34d5: 0x000a, 0x34d6: 0x000a,
- // Block 0xd4, offset 0x3500
- 0x351b: 0x000a,
- // Block 0xd5, offset 0x3540
- 0x3555: 0x000a,
- // Block 0xd6, offset 0x3580
- 0x358f: 0x000a,
- // Block 0xd7, offset 0x35c0
- 0x35c9: 0x000a,
- // Block 0xd8, offset 0x3600
- 0x3603: 0x000a,
- 0x360e: 0x0002, 0x360f: 0x0002, 0x3610: 0x0002, 0x3611: 0x0002,
- 0x3612: 0x0002, 0x3613: 0x0002, 0x3614: 0x0002, 0x3615: 0x0002, 0x3616: 0x0002, 0x3617: 0x0002,
- 0x3618: 0x0002, 0x3619: 0x0002, 0x361a: 0x0002, 0x361b: 0x0002, 0x361c: 0x0002, 0x361d: 0x0002,
- 0x361e: 0x0002, 0x361f: 0x0002, 0x3620: 0x0002, 0x3621: 0x0002, 0x3622: 0x0002, 0x3623: 0x0002,
- 0x3624: 0x0002, 0x3625: 0x0002, 0x3626: 0x0002, 0x3627: 0x0002, 0x3628: 0x0002, 0x3629: 0x0002,
- 0x362a: 0x0002, 0x362b: 0x0002, 0x362c: 0x0002, 0x362d: 0x0002, 0x362e: 0x0002, 0x362f: 0x0002,
- 0x3630: 0x0002, 0x3631: 0x0002, 0x3632: 0x0002, 0x3633: 0x0002, 0x3634: 0x0002, 0x3635: 0x0002,
- 0x3636: 0x0002, 0x3637: 0x0002, 0x3638: 0x0002, 0x3639: 0x0002, 0x363a: 0x0002, 0x363b: 0x0002,
- 0x363c: 0x0002, 0x363d: 0x0002, 0x363e: 0x0002, 0x363f: 0x0002,
- // Block 0xd9, offset 0x3640
- 0x3640: 0x000c, 0x3641: 0x000c, 0x3642: 0x000c, 0x3643: 0x000c, 0x3644: 0x000c, 0x3645: 0x000c,
- 0x3646: 0x000c, 0x3647: 0x000c, 0x3648: 0x000c, 0x3649: 0x000c, 0x364a: 0x000c, 0x364b: 0x000c,
- 0x364c: 0x000c, 0x364d: 0x000c, 0x364e: 0x000c, 0x364f: 0x000c, 0x3650: 0x000c, 0x3651: 0x000c,
- 0x3652: 0x000c, 0x3653: 0x000c, 0x3654: 0x000c, 0x3655: 0x000c, 0x3656: 0x000c, 0x3657: 0x000c,
- 0x3658: 0x000c, 0x3659: 0x000c, 0x365a: 0x000c, 0x365b: 0x000c, 0x365c: 0x000c, 0x365d: 0x000c,
- 0x365e: 0x000c, 0x365f: 0x000c, 0x3660: 0x000c, 0x3661: 0x000c, 0x3662: 0x000c, 0x3663: 0x000c,
- 0x3664: 0x000c, 0x3665: 0x000c, 0x3666: 0x000c, 0x3667: 0x000c, 0x3668: 0x000c, 0x3669: 0x000c,
- 0x366a: 0x000c, 0x366b: 0x000c, 0x366c: 0x000c, 0x366d: 0x000c, 0x366e: 0x000c, 0x366f: 0x000c,
- 0x3670: 0x000c, 0x3671: 0x000c, 0x3672: 0x000c, 0x3673: 0x000c, 0x3674: 0x000c, 0x3675: 0x000c,
- 0x3676: 0x000c, 0x367b: 0x000c,
- 0x367c: 0x000c, 0x367d: 0x000c, 0x367e: 0x000c, 0x367f: 0x000c,
- // Block 0xda, offset 0x3680
- 0x3680: 0x000c, 0x3681: 0x000c, 0x3682: 0x000c, 0x3683: 0x000c, 0x3684: 0x000c, 0x3685: 0x000c,
- 0x3686: 0x000c, 0x3687: 0x000c, 0x3688: 0x000c, 0x3689: 0x000c, 0x368a: 0x000c, 0x368b: 0x000c,
- 0x368c: 0x000c, 0x368d: 0x000c, 0x368e: 0x000c, 0x368f: 0x000c, 0x3690: 0x000c, 0x3691: 0x000c,
- 0x3692: 0x000c, 0x3693: 0x000c, 0x3694: 0x000c, 0x3695: 0x000c, 0x3696: 0x000c, 0x3697: 0x000c,
- 0x3698: 0x000c, 0x3699: 0x000c, 0x369a: 0x000c, 0x369b: 0x000c, 0x369c: 0x000c, 0x369d: 0x000c,
- 0x369e: 0x000c, 0x369f: 0x000c, 0x36a0: 0x000c, 0x36a1: 0x000c, 0x36a2: 0x000c, 0x36a3: 0x000c,
- 0x36a4: 0x000c, 0x36a5: 0x000c, 0x36a6: 0x000c, 0x36a7: 0x000c, 0x36a8: 0x000c, 0x36a9: 0x000c,
- 0x36aa: 0x000c, 0x36ab: 0x000c, 0x36ac: 0x000c,
- 0x36b5: 0x000c,
- // Block 0xdb, offset 0x36c0
- 0x36c4: 0x000c,
- 0x36db: 0x000c, 0x36dc: 0x000c, 0x36dd: 0x000c,
- 0x36de: 0x000c, 0x36df: 0x000c, 0x36e1: 0x000c, 0x36e2: 0x000c, 0x36e3: 0x000c,
- 0x36e4: 0x000c, 0x36e5: 0x000c, 0x36e6: 0x000c, 0x36e7: 0x000c, 0x36e8: 0x000c, 0x36e9: 0x000c,
- 0x36ea: 0x000c, 0x36eb: 0x000c, 0x36ec: 0x000c, 0x36ed: 0x000c, 0x36ee: 0x000c, 0x36ef: 0x000c,
- // Block 0xdc, offset 0x3700
- 0x3700: 0x000c, 0x3701: 0x000c, 0x3702: 0x000c, 0x3703: 0x000c, 0x3704: 0x000c, 0x3705: 0x000c,
- 0x3706: 0x000c, 0x3708: 0x000c, 0x3709: 0x000c, 0x370a: 0x000c, 0x370b: 0x000c,
- 0x370c: 0x000c, 0x370d: 0x000c, 0x370e: 0x000c, 0x370f: 0x000c, 0x3710: 0x000c, 0x3711: 0x000c,
- 0x3712: 0x000c, 0x3713: 0x000c, 0x3714: 0x000c, 0x3715: 0x000c, 0x3716: 0x000c, 0x3717: 0x000c,
- 0x3718: 0x000c, 0x371b: 0x000c, 0x371c: 0x000c, 0x371d: 0x000c,
- 0x371e: 0x000c, 0x371f: 0x000c, 0x3720: 0x000c, 0x3721: 0x000c, 0x3723: 0x000c,
- 0x3724: 0x000c, 0x3726: 0x000c, 0x3727: 0x000c, 0x3728: 0x000c, 0x3729: 0x000c,
- 0x372a: 0x000c,
- // Block 0xdd, offset 0x3740
- 0x376c: 0x000c, 0x376d: 0x000c, 0x376e: 0x000c, 0x376f: 0x000c,
- 0x377f: 0x0004,
- // Block 0xde, offset 0x3780
- 0x3780: 0x0001, 0x3781: 0x0001, 0x3782: 0x0001, 0x3783: 0x0001, 0x3784: 0x0001, 0x3785: 0x0001,
- 0x3786: 0x0001, 0x3787: 0x0001, 0x3788: 0x0001, 0x3789: 0x0001, 0x378a: 0x0001, 0x378b: 0x0001,
- 0x378c: 0x0001, 0x378d: 0x0001, 0x378e: 0x0001, 0x378f: 0x0001, 0x3790: 0x000c, 0x3791: 0x000c,
- 0x3792: 0x000c, 0x3793: 0x000c, 0x3794: 0x000c, 0x3795: 0x000c, 0x3796: 0x000c, 0x3797: 0x0001,
- 0x3798: 0x0001, 0x3799: 0x0001, 0x379a: 0x0001, 0x379b: 0x0001, 0x379c: 0x0001, 0x379d: 0x0001,
- 0x379e: 0x0001, 0x379f: 0x0001, 0x37a0: 0x0001, 0x37a1: 0x0001, 0x37a2: 0x0001, 0x37a3: 0x0001,
- 0x37a4: 0x0001, 0x37a5: 0x0001, 0x37a6: 0x0001, 0x37a7: 0x0001, 0x37a8: 0x0001, 0x37a9: 0x0001,
- 0x37aa: 0x0001, 0x37ab: 0x0001, 0x37ac: 0x0001, 0x37ad: 0x0001, 0x37ae: 0x0001, 0x37af: 0x0001,
- 0x37b0: 0x0001, 0x37b1: 0x0001, 0x37b2: 0x0001, 0x37b3: 0x0001, 0x37b4: 0x0001, 0x37b5: 0x0001,
- 0x37b6: 0x0001, 0x37b7: 0x0001, 0x37b8: 0x0001, 0x37b9: 0x0001, 0x37ba: 0x0001, 0x37bb: 0x0001,
- 0x37bc: 0x0001, 0x37bd: 0x0001, 0x37be: 0x0001, 0x37bf: 0x0001,
- // Block 0xdf, offset 0x37c0
- 0x37c0: 0x0001, 0x37c1: 0x0001, 0x37c2: 0x0001, 0x37c3: 0x0001, 0x37c4: 0x000c, 0x37c5: 0x000c,
- 0x37c6: 0x000c, 0x37c7: 0x000c, 0x37c8: 0x000c, 0x37c9: 0x000c, 0x37ca: 0x000c, 0x37cb: 0x0001,
- 0x37cc: 0x0001, 0x37cd: 0x0001, 0x37ce: 0x0001, 0x37cf: 0x0001, 0x37d0: 0x0001, 0x37d1: 0x0001,
- 0x37d2: 0x0001, 0x37d3: 0x0001, 0x37d4: 0x0001, 0x37d5: 0x0001, 0x37d6: 0x0001, 0x37d7: 0x0001,
- 0x37d8: 0x0001, 0x37d9: 0x0001, 0x37da: 0x0001, 0x37db: 0x0001, 0x37dc: 0x0001, 0x37dd: 0x0001,
- 0x37de: 0x0001, 0x37df: 0x0001, 0x37e0: 0x0001, 0x37e1: 0x0001, 0x37e2: 0x0001, 0x37e3: 0x0001,
- 0x37e4: 0x0001, 0x37e5: 0x0001, 0x37e6: 0x0001, 0x37e7: 0x0001, 0x37e8: 0x0001, 0x37e9: 0x0001,
- 0x37ea: 0x0001, 0x37eb: 0x0001, 0x37ec: 0x0001, 0x37ed: 0x0001, 0x37ee: 0x0001, 0x37ef: 0x0001,
- 0x37f0: 0x0001, 0x37f1: 0x0001, 0x37f2: 0x0001, 0x37f3: 0x0001, 0x37f4: 0x0001, 0x37f5: 0x0001,
- 0x37f6: 0x0001, 0x37f7: 0x0001, 0x37f8: 0x0001, 0x37f9: 0x0001, 0x37fa: 0x0001, 0x37fb: 0x0001,
- 0x37fc: 0x0001, 0x37fd: 0x0001, 0x37fe: 0x0001, 0x37ff: 0x0001,
- // Block 0xe0, offset 0x3800
- 0x3800: 0x000d, 0x3801: 0x000d, 0x3802: 0x000d, 0x3803: 0x000d, 0x3804: 0x000d, 0x3805: 0x000d,
- 0x3806: 0x000d, 0x3807: 0x000d, 0x3808: 0x000d, 0x3809: 0x000d, 0x380a: 0x000d, 0x380b: 0x000d,
- 0x380c: 0x000d, 0x380d: 0x000d, 0x380e: 0x000d, 0x380f: 0x000d, 0x3810: 0x0001, 0x3811: 0x0001,
- 0x3812: 0x0001, 0x3813: 0x0001, 0x3814: 0x0001, 0x3815: 0x0001, 0x3816: 0x0001, 0x3817: 0x0001,
- 0x3818: 0x0001, 0x3819: 0x0001, 0x381a: 0x0001, 0x381b: 0x0001, 0x381c: 0x0001, 0x381d: 0x0001,
- 0x381e: 0x0001, 0x381f: 0x0001, 0x3820: 0x0001, 0x3821: 0x0001, 0x3822: 0x0001, 0x3823: 0x0001,
- 0x3824: 0x0001, 0x3825: 0x0001, 0x3826: 0x0001, 0x3827: 0x0001, 0x3828: 0x0001, 0x3829: 0x0001,
- 0x382a: 0x0001, 0x382b: 0x0001, 0x382c: 0x0001, 0x382d: 0x0001, 0x382e: 0x0001, 0x382f: 0x0001,
- 0x3830: 0x0001, 0x3831: 0x0001, 0x3832: 0x0001, 0x3833: 0x0001, 0x3834: 0x0001, 0x3835: 0x0001,
- 0x3836: 0x0001, 0x3837: 0x0001, 0x3838: 0x0001, 0x3839: 0x0001, 0x383a: 0x0001, 0x383b: 0x0001,
- 0x383c: 0x0001, 0x383d: 0x0001, 0x383e: 0x0001, 0x383f: 0x0001,
- // Block 0xe1, offset 0x3840
- 0x3840: 0x000d, 0x3841: 0x000d, 0x3842: 0x000d, 0x3843: 0x000d, 0x3844: 0x000d, 0x3845: 0x000d,
- 0x3846: 0x000d, 0x3847: 0x000d, 0x3848: 0x000d, 0x3849: 0x000d, 0x384a: 0x000d, 0x384b: 0x000d,
- 0x384c: 0x000d, 0x384d: 0x000d, 0x384e: 0x000d, 0x384f: 0x000d, 0x3850: 0x000d, 0x3851: 0x000d,
- 0x3852: 0x000d, 0x3853: 0x000d, 0x3854: 0x000d, 0x3855: 0x000d, 0x3856: 0x000d, 0x3857: 0x000d,
- 0x3858: 0x000d, 0x3859: 0x000d, 0x385a: 0x000d, 0x385b: 0x000d, 0x385c: 0x000d, 0x385d: 0x000d,
- 0x385e: 0x000d, 0x385f: 0x000d, 0x3860: 0x000d, 0x3861: 0x000d, 0x3862: 0x000d, 0x3863: 0x000d,
- 0x3864: 0x000d, 0x3865: 0x000d, 0x3866: 0x000d, 0x3867: 0x000d, 0x3868: 0x000d, 0x3869: 0x000d,
- 0x386a: 0x000d, 0x386b: 0x000d, 0x386c: 0x000d, 0x386d: 0x000d, 0x386e: 0x000d, 0x386f: 0x000d,
- 0x3870: 0x000a, 0x3871: 0x000a, 0x3872: 0x000d, 0x3873: 0x000d, 0x3874: 0x000d, 0x3875: 0x000d,
- 0x3876: 0x000d, 0x3877: 0x000d, 0x3878: 0x000d, 0x3879: 0x000d, 0x387a: 0x000d, 0x387b: 0x000d,
- 0x387c: 0x000d, 0x387d: 0x000d, 0x387e: 0x000d, 0x387f: 0x000d,
- // Block 0xe2, offset 0x3880
- 0x3880: 0x000a, 0x3881: 0x000a, 0x3882: 0x000a, 0x3883: 0x000a, 0x3884: 0x000a, 0x3885: 0x000a,
- 0x3886: 0x000a, 0x3887: 0x000a, 0x3888: 0x000a, 0x3889: 0x000a, 0x388a: 0x000a, 0x388b: 0x000a,
- 0x388c: 0x000a, 0x388d: 0x000a, 0x388e: 0x000a, 0x388f: 0x000a, 0x3890: 0x000a, 0x3891: 0x000a,
- 0x3892: 0x000a, 0x3893: 0x000a, 0x3894: 0x000a, 0x3895: 0x000a, 0x3896: 0x000a, 0x3897: 0x000a,
- 0x3898: 0x000a, 0x3899: 0x000a, 0x389a: 0x000a, 0x389b: 0x000a, 0x389c: 0x000a, 0x389d: 0x000a,
- 0x389e: 0x000a, 0x389f: 0x000a, 0x38a0: 0x000a, 0x38a1: 0x000a, 0x38a2: 0x000a, 0x38a3: 0x000a,
- 0x38a4: 0x000a, 0x38a5: 0x000a, 0x38a6: 0x000a, 0x38a7: 0x000a, 0x38a8: 0x000a, 0x38a9: 0x000a,
- 0x38aa: 0x000a, 0x38ab: 0x000a,
- 0x38b0: 0x000a, 0x38b1: 0x000a, 0x38b2: 0x000a, 0x38b3: 0x000a, 0x38b4: 0x000a, 0x38b5: 0x000a,
- 0x38b6: 0x000a, 0x38b7: 0x000a, 0x38b8: 0x000a, 0x38b9: 0x000a, 0x38ba: 0x000a, 0x38bb: 0x000a,
- 0x38bc: 0x000a, 0x38bd: 0x000a, 0x38be: 0x000a, 0x38bf: 0x000a,
- // Block 0xe3, offset 0x38c0
- 0x38c0: 0x000a, 0x38c1: 0x000a, 0x38c2: 0x000a, 0x38c3: 0x000a, 0x38c4: 0x000a, 0x38c5: 0x000a,
- 0x38c6: 0x000a, 0x38c7: 0x000a, 0x38c8: 0x000a, 0x38c9: 0x000a, 0x38ca: 0x000a, 0x38cb: 0x000a,
- 0x38cc: 0x000a, 0x38cd: 0x000a, 0x38ce: 0x000a, 0x38cf: 0x000a, 0x38d0: 0x000a, 0x38d1: 0x000a,
- 0x38d2: 0x000a, 0x38d3: 0x000a,
- 0x38e0: 0x000a, 0x38e1: 0x000a, 0x38e2: 0x000a, 0x38e3: 0x000a,
- 0x38e4: 0x000a, 0x38e5: 0x000a, 0x38e6: 0x000a, 0x38e7: 0x000a, 0x38e8: 0x000a, 0x38e9: 0x000a,
- 0x38ea: 0x000a, 0x38eb: 0x000a, 0x38ec: 0x000a, 0x38ed: 0x000a, 0x38ee: 0x000a,
- 0x38f1: 0x000a, 0x38f2: 0x000a, 0x38f3: 0x000a, 0x38f4: 0x000a, 0x38f5: 0x000a,
- 0x38f6: 0x000a, 0x38f7: 0x000a, 0x38f8: 0x000a, 0x38f9: 0x000a, 0x38fa: 0x000a, 0x38fb: 0x000a,
- 0x38fc: 0x000a, 0x38fd: 0x000a, 0x38fe: 0x000a, 0x38ff: 0x000a,
- // Block 0xe4, offset 0x3900
- 0x3901: 0x000a, 0x3902: 0x000a, 0x3903: 0x000a, 0x3904: 0x000a, 0x3905: 0x000a,
- 0x3906: 0x000a, 0x3907: 0x000a, 0x3908: 0x000a, 0x3909: 0x000a, 0x390a: 0x000a, 0x390b: 0x000a,
- 0x390c: 0x000a, 0x390d: 0x000a, 0x390e: 0x000a, 0x390f: 0x000a, 0x3911: 0x000a,
- 0x3912: 0x000a, 0x3913: 0x000a, 0x3914: 0x000a, 0x3915: 0x000a, 0x3916: 0x000a, 0x3917: 0x000a,
- 0x3918: 0x000a, 0x3919: 0x000a, 0x391a: 0x000a, 0x391b: 0x000a, 0x391c: 0x000a, 0x391d: 0x000a,
- 0x391e: 0x000a, 0x391f: 0x000a, 0x3920: 0x000a, 0x3921: 0x000a, 0x3922: 0x000a, 0x3923: 0x000a,
- 0x3924: 0x000a, 0x3925: 0x000a, 0x3926: 0x000a, 0x3927: 0x000a, 0x3928: 0x000a, 0x3929: 0x000a,
- 0x392a: 0x000a, 0x392b: 0x000a, 0x392c: 0x000a, 0x392d: 0x000a, 0x392e: 0x000a, 0x392f: 0x000a,
- 0x3930: 0x000a, 0x3931: 0x000a, 0x3932: 0x000a, 0x3933: 0x000a, 0x3934: 0x000a, 0x3935: 0x000a,
- // Block 0xe5, offset 0x3940
- 0x3940: 0x0002, 0x3941: 0x0002, 0x3942: 0x0002, 0x3943: 0x0002, 0x3944: 0x0002, 0x3945: 0x0002,
- 0x3946: 0x0002, 0x3947: 0x0002, 0x3948: 0x0002, 0x3949: 0x0002, 0x394a: 0x0002, 0x394b: 0x000a,
- 0x394c: 0x000a, 0x394d: 0x000a, 0x394e: 0x000a, 0x394f: 0x000a,
- 0x396f: 0x000a,
- // Block 0xe6, offset 0x3980
- 0x39aa: 0x000a, 0x39ab: 0x000a, 0x39ac: 0x000a, 0x39ad: 0x000a, 0x39ae: 0x000a, 0x39af: 0x000a,
- // Block 0xe7, offset 0x39c0
- 0x39ed: 0x000a,
- // Block 0xe8, offset 0x3a00
- 0x3a20: 0x000a, 0x3a21: 0x000a, 0x3a22: 0x000a, 0x3a23: 0x000a,
- 0x3a24: 0x000a, 0x3a25: 0x000a,
- // Block 0xe9, offset 0x3a40
- 0x3a40: 0x000a, 0x3a41: 0x000a, 0x3a42: 0x000a, 0x3a43: 0x000a, 0x3a44: 0x000a, 0x3a45: 0x000a,
- 0x3a46: 0x000a, 0x3a47: 0x000a, 0x3a48: 0x000a, 0x3a49: 0x000a, 0x3a4a: 0x000a, 0x3a4b: 0x000a,
- 0x3a4c: 0x000a, 0x3a4d: 0x000a, 0x3a4e: 0x000a, 0x3a4f: 0x000a, 0x3a50: 0x000a, 0x3a51: 0x000a,
- 0x3a52: 0x000a, 0x3a53: 0x000a, 0x3a54: 0x000a, 0x3a55: 0x000a, 0x3a56: 0x000a, 0x3a57: 0x000a,
- 0x3a60: 0x000a, 0x3a61: 0x000a, 0x3a62: 0x000a, 0x3a63: 0x000a,
- 0x3a64: 0x000a, 0x3a65: 0x000a, 0x3a66: 0x000a, 0x3a67: 0x000a, 0x3a68: 0x000a, 0x3a69: 0x000a,
- 0x3a6a: 0x000a, 0x3a6b: 0x000a, 0x3a6c: 0x000a,
- 0x3a70: 0x000a, 0x3a71: 0x000a, 0x3a72: 0x000a, 0x3a73: 0x000a, 0x3a74: 0x000a, 0x3a75: 0x000a,
- 0x3a76: 0x000a, 0x3a77: 0x000a, 0x3a78: 0x000a, 0x3a79: 0x000a, 0x3a7a: 0x000a, 0x3a7b: 0x000a,
- 0x3a7c: 0x000a,
- // Block 0xea, offset 0x3a80
- 0x3a80: 0x000a, 0x3a81: 0x000a, 0x3a82: 0x000a, 0x3a83: 0x000a, 0x3a84: 0x000a, 0x3a85: 0x000a,
- 0x3a86: 0x000a, 0x3a87: 0x000a, 0x3a88: 0x000a, 0x3a89: 0x000a, 0x3a8a: 0x000a, 0x3a8b: 0x000a,
- 0x3a8c: 0x000a, 0x3a8d: 0x000a, 0x3a8e: 0x000a, 0x3a8f: 0x000a, 0x3a90: 0x000a, 0x3a91: 0x000a,
- 0x3a92: 0x000a, 0x3a93: 0x000a, 0x3a94: 0x000a, 0x3a95: 0x000a, 0x3a96: 0x000a, 0x3a97: 0x000a,
- 0x3a98: 0x000a,
- 0x3aa0: 0x000a, 0x3aa1: 0x000a, 0x3aa2: 0x000a, 0x3aa3: 0x000a,
- 0x3aa4: 0x000a, 0x3aa5: 0x000a, 0x3aa6: 0x000a, 0x3aa7: 0x000a, 0x3aa8: 0x000a, 0x3aa9: 0x000a,
- 0x3aaa: 0x000a, 0x3aab: 0x000a,
- // Block 0xeb, offset 0x3ac0
- 0x3ac0: 0x000a, 0x3ac1: 0x000a, 0x3ac2: 0x000a, 0x3ac3: 0x000a, 0x3ac4: 0x000a, 0x3ac5: 0x000a,
- 0x3ac6: 0x000a, 0x3ac7: 0x000a, 0x3ac8: 0x000a, 0x3ac9: 0x000a, 0x3aca: 0x000a, 0x3acb: 0x000a,
- 0x3ad0: 0x000a, 0x3ad1: 0x000a,
- 0x3ad2: 0x000a, 0x3ad3: 0x000a, 0x3ad4: 0x000a, 0x3ad5: 0x000a, 0x3ad6: 0x000a, 0x3ad7: 0x000a,
- 0x3ad8: 0x000a, 0x3ad9: 0x000a, 0x3ada: 0x000a, 0x3adb: 0x000a, 0x3adc: 0x000a, 0x3add: 0x000a,
- 0x3ade: 0x000a, 0x3adf: 0x000a, 0x3ae0: 0x000a, 0x3ae1: 0x000a, 0x3ae2: 0x000a, 0x3ae3: 0x000a,
- 0x3ae4: 0x000a, 0x3ae5: 0x000a, 0x3ae6: 0x000a, 0x3ae7: 0x000a, 0x3ae8: 0x000a, 0x3ae9: 0x000a,
- 0x3aea: 0x000a, 0x3aeb: 0x000a, 0x3aec: 0x000a, 0x3aed: 0x000a, 0x3aee: 0x000a, 0x3aef: 0x000a,
- 0x3af0: 0x000a, 0x3af1: 0x000a, 0x3af2: 0x000a, 0x3af3: 0x000a, 0x3af4: 0x000a, 0x3af5: 0x000a,
- 0x3af6: 0x000a, 0x3af7: 0x000a, 0x3af8: 0x000a, 0x3af9: 0x000a, 0x3afa: 0x000a, 0x3afb: 0x000a,
- 0x3afc: 0x000a, 0x3afd: 0x000a, 0x3afe: 0x000a, 0x3aff: 0x000a,
- // Block 0xec, offset 0x3b00
- 0x3b00: 0x000a, 0x3b01: 0x000a, 0x3b02: 0x000a, 0x3b03: 0x000a, 0x3b04: 0x000a, 0x3b05: 0x000a,
- 0x3b06: 0x000a, 0x3b07: 0x000a,
- 0x3b10: 0x000a, 0x3b11: 0x000a,
- 0x3b12: 0x000a, 0x3b13: 0x000a, 0x3b14: 0x000a, 0x3b15: 0x000a, 0x3b16: 0x000a, 0x3b17: 0x000a,
- 0x3b18: 0x000a, 0x3b19: 0x000a,
- 0x3b20: 0x000a, 0x3b21: 0x000a, 0x3b22: 0x000a, 0x3b23: 0x000a,
- 0x3b24: 0x000a, 0x3b25: 0x000a, 0x3b26: 0x000a, 0x3b27: 0x000a, 0x3b28: 0x000a, 0x3b29: 0x000a,
- 0x3b2a: 0x000a, 0x3b2b: 0x000a, 0x3b2c: 0x000a, 0x3b2d: 0x000a, 0x3b2e: 0x000a, 0x3b2f: 0x000a,
- 0x3b30: 0x000a, 0x3b31: 0x000a, 0x3b32: 0x000a, 0x3b33: 0x000a, 0x3b34: 0x000a, 0x3b35: 0x000a,
- 0x3b36: 0x000a, 0x3b37: 0x000a, 0x3b38: 0x000a, 0x3b39: 0x000a, 0x3b3a: 0x000a, 0x3b3b: 0x000a,
- 0x3b3c: 0x000a, 0x3b3d: 0x000a, 0x3b3e: 0x000a, 0x3b3f: 0x000a,
- // Block 0xed, offset 0x3b40
- 0x3b40: 0x000a, 0x3b41: 0x000a, 0x3b42: 0x000a, 0x3b43: 0x000a, 0x3b44: 0x000a, 0x3b45: 0x000a,
- 0x3b46: 0x000a, 0x3b47: 0x000a,
- 0x3b50: 0x000a, 0x3b51: 0x000a,
- 0x3b52: 0x000a, 0x3b53: 0x000a, 0x3b54: 0x000a, 0x3b55: 0x000a, 0x3b56: 0x000a, 0x3b57: 0x000a,
- 0x3b58: 0x000a, 0x3b59: 0x000a, 0x3b5a: 0x000a, 0x3b5b: 0x000a, 0x3b5c: 0x000a, 0x3b5d: 0x000a,
- 0x3b5e: 0x000a, 0x3b5f: 0x000a, 0x3b60: 0x000a, 0x3b61: 0x000a, 0x3b62: 0x000a, 0x3b63: 0x000a,
- 0x3b64: 0x000a, 0x3b65: 0x000a, 0x3b66: 0x000a, 0x3b67: 0x000a, 0x3b68: 0x000a, 0x3b69: 0x000a,
- 0x3b6a: 0x000a, 0x3b6b: 0x000a, 0x3b6c: 0x000a, 0x3b6d: 0x000a,
- 0x3b70: 0x000a, 0x3b71: 0x000a,
- // Block 0xee, offset 0x3b80
- 0x3b80: 0x000a, 0x3b81: 0x000a, 0x3b82: 0x000a, 0x3b83: 0x000a, 0x3b84: 0x000a, 0x3b85: 0x000a,
- 0x3b86: 0x000a, 0x3b87: 0x000a, 0x3b88: 0x000a, 0x3b89: 0x000a, 0x3b8a: 0x000a, 0x3b8b: 0x000a,
- 0x3b8c: 0x000a, 0x3b8d: 0x000a, 0x3b8e: 0x000a, 0x3b8f: 0x000a, 0x3b90: 0x000a, 0x3b91: 0x000a,
- 0x3b92: 0x000a, 0x3b93: 0x000a, 0x3b94: 0x000a, 0x3b95: 0x000a, 0x3b96: 0x000a, 0x3b97: 0x000a,
- 0x3b98: 0x000a, 0x3b99: 0x000a, 0x3b9a: 0x000a, 0x3b9b: 0x000a, 0x3b9c: 0x000a, 0x3b9d: 0x000a,
- 0x3b9e: 0x000a, 0x3b9f: 0x000a, 0x3ba0: 0x000a, 0x3ba1: 0x000a, 0x3ba2: 0x000a, 0x3ba3: 0x000a,
- 0x3ba4: 0x000a, 0x3ba5: 0x000a, 0x3ba6: 0x000a, 0x3ba7: 0x000a, 0x3ba8: 0x000a, 0x3ba9: 0x000a,
- 0x3baa: 0x000a, 0x3bab: 0x000a, 0x3bac: 0x000a, 0x3bad: 0x000a, 0x3bae: 0x000a, 0x3baf: 0x000a,
- 0x3bb0: 0x000a, 0x3bb1: 0x000a, 0x3bb2: 0x000a, 0x3bb3: 0x000a, 0x3bb4: 0x000a, 0x3bb5: 0x000a,
- 0x3bb6: 0x000a, 0x3bb7: 0x000a, 0x3bb8: 0x000a, 0x3bba: 0x000a, 0x3bbb: 0x000a,
- 0x3bbc: 0x000a, 0x3bbd: 0x000a, 0x3bbe: 0x000a, 0x3bbf: 0x000a,
- // Block 0xef, offset 0x3bc0
- 0x3bc0: 0x000a, 0x3bc1: 0x000a, 0x3bc2: 0x000a, 0x3bc3: 0x000a, 0x3bc4: 0x000a, 0x3bc5: 0x000a,
- 0x3bc6: 0x000a, 0x3bc7: 0x000a, 0x3bc8: 0x000a, 0x3bc9: 0x000a, 0x3bca: 0x000a, 0x3bcb: 0x000a,
- 0x3bcd: 0x000a, 0x3bce: 0x000a, 0x3bcf: 0x000a, 0x3bd0: 0x000a, 0x3bd1: 0x000a,
- 0x3bd2: 0x000a, 0x3bd3: 0x000a, 0x3bd4: 0x000a, 0x3bd5: 0x000a, 0x3bd6: 0x000a, 0x3bd7: 0x000a,
- 0x3bd8: 0x000a, 0x3bd9: 0x000a, 0x3bda: 0x000a, 0x3bdb: 0x000a, 0x3bdc: 0x000a, 0x3bdd: 0x000a,
- 0x3bde: 0x000a, 0x3bdf: 0x000a, 0x3be0: 0x000a, 0x3be1: 0x000a, 0x3be2: 0x000a, 0x3be3: 0x000a,
- 0x3be4: 0x000a, 0x3be5: 0x000a, 0x3be6: 0x000a, 0x3be7: 0x000a, 0x3be8: 0x000a, 0x3be9: 0x000a,
- 0x3bea: 0x000a, 0x3beb: 0x000a, 0x3bec: 0x000a, 0x3bed: 0x000a, 0x3bee: 0x000a, 0x3bef: 0x000a,
- 0x3bf0: 0x000a, 0x3bf1: 0x000a, 0x3bf2: 0x000a, 0x3bf3: 0x000a, 0x3bf4: 0x000a, 0x3bf5: 0x000a,
- 0x3bf6: 0x000a, 0x3bf7: 0x000a, 0x3bf8: 0x000a, 0x3bf9: 0x000a, 0x3bfa: 0x000a, 0x3bfb: 0x000a,
- 0x3bfc: 0x000a, 0x3bfd: 0x000a, 0x3bfe: 0x000a, 0x3bff: 0x000a,
- // Block 0xf0, offset 0x3c00
- 0x3c00: 0x000a, 0x3c01: 0x000a, 0x3c02: 0x000a, 0x3c03: 0x000a, 0x3c04: 0x000a, 0x3c05: 0x000a,
- 0x3c06: 0x000a, 0x3c07: 0x000a, 0x3c08: 0x000a, 0x3c09: 0x000a, 0x3c0a: 0x000a, 0x3c0b: 0x000a,
- 0x3c0c: 0x000a, 0x3c0d: 0x000a, 0x3c0e: 0x000a, 0x3c0f: 0x000a, 0x3c10: 0x000a, 0x3c11: 0x000a,
- 0x3c12: 0x000a, 0x3c13: 0x000a,
- 0x3c20: 0x000a, 0x3c21: 0x000a, 0x3c22: 0x000a, 0x3c23: 0x000a,
- 0x3c24: 0x000a, 0x3c25: 0x000a, 0x3c26: 0x000a, 0x3c27: 0x000a, 0x3c28: 0x000a, 0x3c29: 0x000a,
- 0x3c2a: 0x000a, 0x3c2b: 0x000a, 0x3c2c: 0x000a, 0x3c2d: 0x000a,
- 0x3c30: 0x000a, 0x3c31: 0x000a, 0x3c32: 0x000a, 0x3c33: 0x000a, 0x3c34: 0x000a,
- 0x3c38: 0x000a, 0x3c39: 0x000a, 0x3c3a: 0x000a,
- // Block 0xf1, offset 0x3c40
- 0x3c40: 0x000a, 0x3c41: 0x000a, 0x3c42: 0x000a, 0x3c43: 0x000a, 0x3c44: 0x000a, 0x3c45: 0x000a,
- 0x3c46: 0x000a,
- 0x3c50: 0x000a, 0x3c51: 0x000a,
- 0x3c52: 0x000a, 0x3c53: 0x000a, 0x3c54: 0x000a, 0x3c55: 0x000a, 0x3c56: 0x000a, 0x3c57: 0x000a,
- 0x3c58: 0x000a, 0x3c59: 0x000a, 0x3c5a: 0x000a, 0x3c5b: 0x000a, 0x3c5c: 0x000a, 0x3c5d: 0x000a,
- 0x3c5e: 0x000a, 0x3c5f: 0x000a, 0x3c60: 0x000a, 0x3c61: 0x000a, 0x3c62: 0x000a, 0x3c63: 0x000a,
- 0x3c64: 0x000a, 0x3c65: 0x000a, 0x3c66: 0x000a, 0x3c67: 0x000a, 0x3c68: 0x000a,
- 0x3c70: 0x000a, 0x3c71: 0x000a, 0x3c72: 0x000a, 0x3c73: 0x000a, 0x3c74: 0x000a, 0x3c75: 0x000a,
- 0x3c76: 0x000a,
- // Block 0xf2, offset 0x3c80
- 0x3c80: 0x000a, 0x3c81: 0x000a, 0x3c82: 0x000a,
- 0x3c90: 0x000a, 0x3c91: 0x000a,
- 0x3c92: 0x000a, 0x3c93: 0x000a, 0x3c94: 0x000a, 0x3c95: 0x000a, 0x3c96: 0x000a,
- // Block 0xf3, offset 0x3cc0
- 0x3cc0: 0x000a, 0x3cc1: 0x000a, 0x3cc2: 0x000a, 0x3cc3: 0x000a, 0x3cc4: 0x000a, 0x3cc5: 0x000a,
- 0x3cc6: 0x000a, 0x3cc7: 0x000a, 0x3cc8: 0x000a, 0x3cc9: 0x000a, 0x3cca: 0x000a, 0x3ccb: 0x000a,
- 0x3ccc: 0x000a, 0x3ccd: 0x000a, 0x3cce: 0x000a, 0x3ccf: 0x000a, 0x3cd0: 0x000a, 0x3cd1: 0x000a,
- 0x3cd2: 0x000a, 0x3cd4: 0x000a, 0x3cd5: 0x000a, 0x3cd6: 0x000a, 0x3cd7: 0x000a,
- 0x3cd8: 0x000a, 0x3cd9: 0x000a, 0x3cda: 0x000a, 0x3cdb: 0x000a, 0x3cdc: 0x000a, 0x3cdd: 0x000a,
- 0x3cde: 0x000a, 0x3cdf: 0x000a, 0x3ce0: 0x000a, 0x3ce1: 0x000a, 0x3ce2: 0x000a, 0x3ce3: 0x000a,
- 0x3ce4: 0x000a, 0x3ce5: 0x000a, 0x3ce6: 0x000a, 0x3ce7: 0x000a, 0x3ce8: 0x000a, 0x3ce9: 0x000a,
- 0x3cea: 0x000a, 0x3ceb: 0x000a, 0x3cec: 0x000a, 0x3ced: 0x000a, 0x3cee: 0x000a, 0x3cef: 0x000a,
- 0x3cf0: 0x000a, 0x3cf1: 0x000a, 0x3cf2: 0x000a, 0x3cf3: 0x000a, 0x3cf4: 0x000a, 0x3cf5: 0x000a,
- 0x3cf6: 0x000a, 0x3cf7: 0x000a, 0x3cf8: 0x000a, 0x3cf9: 0x000a, 0x3cfa: 0x000a, 0x3cfb: 0x000a,
- 0x3cfc: 0x000a, 0x3cfd: 0x000a, 0x3cfe: 0x000a, 0x3cff: 0x000a,
- // Block 0xf4, offset 0x3d00
- 0x3d00: 0x000a, 0x3d01: 0x000a, 0x3d02: 0x000a, 0x3d03: 0x000a, 0x3d04: 0x000a, 0x3d05: 0x000a,
- 0x3d06: 0x000a, 0x3d07: 0x000a, 0x3d08: 0x000a, 0x3d09: 0x000a, 0x3d0a: 0x000a,
- 0x3d30: 0x0002, 0x3d31: 0x0002, 0x3d32: 0x0002, 0x3d33: 0x0002, 0x3d34: 0x0002, 0x3d35: 0x0002,
- 0x3d36: 0x0002, 0x3d37: 0x0002, 0x3d38: 0x0002, 0x3d39: 0x0002,
- // Block 0xf5, offset 0x3d40
- 0x3d7e: 0x000b, 0x3d7f: 0x000b,
- // Block 0xf6, offset 0x3d80
- 0x3d80: 0x000b, 0x3d81: 0x000b, 0x3d82: 0x000b, 0x3d83: 0x000b, 0x3d84: 0x000b, 0x3d85: 0x000b,
- 0x3d86: 0x000b, 0x3d87: 0x000b, 0x3d88: 0x000b, 0x3d89: 0x000b, 0x3d8a: 0x000b, 0x3d8b: 0x000b,
- 0x3d8c: 0x000b, 0x3d8d: 0x000b, 0x3d8e: 0x000b, 0x3d8f: 0x000b, 0x3d90: 0x000b, 0x3d91: 0x000b,
- 0x3d92: 0x000b, 0x3d93: 0x000b, 0x3d94: 0x000b, 0x3d95: 0x000b, 0x3d96: 0x000b, 0x3d97: 0x000b,
- 0x3d98: 0x000b, 0x3d99: 0x000b, 0x3d9a: 0x000b, 0x3d9b: 0x000b, 0x3d9c: 0x000b, 0x3d9d: 0x000b,
- 0x3d9e: 0x000b, 0x3d9f: 0x000b, 0x3da0: 0x000b, 0x3da1: 0x000b, 0x3da2: 0x000b, 0x3da3: 0x000b,
- 0x3da4: 0x000b, 0x3da5: 0x000b, 0x3da6: 0x000b, 0x3da7: 0x000b, 0x3da8: 0x000b, 0x3da9: 0x000b,
- 0x3daa: 0x000b, 0x3dab: 0x000b, 0x3dac: 0x000b, 0x3dad: 0x000b, 0x3dae: 0x000b, 0x3daf: 0x000b,
- 0x3db0: 0x000b, 0x3db1: 0x000b, 0x3db2: 0x000b, 0x3db3: 0x000b, 0x3db4: 0x000b, 0x3db5: 0x000b,
- 0x3db6: 0x000b, 0x3db7: 0x000b, 0x3db8: 0x000b, 0x3db9: 0x000b, 0x3dba: 0x000b, 0x3dbb: 0x000b,
- 0x3dbc: 0x000b, 0x3dbd: 0x000b, 0x3dbe: 0x000b, 0x3dbf: 0x000b,
- // Block 0xf7, offset 0x3dc0
- 0x3dc0: 0x000c, 0x3dc1: 0x000c, 0x3dc2: 0x000c, 0x3dc3: 0x000c, 0x3dc4: 0x000c, 0x3dc5: 0x000c,
- 0x3dc6: 0x000c, 0x3dc7: 0x000c, 0x3dc8: 0x000c, 0x3dc9: 0x000c, 0x3dca: 0x000c, 0x3dcb: 0x000c,
- 0x3dcc: 0x000c, 0x3dcd: 0x000c, 0x3dce: 0x000c, 0x3dcf: 0x000c, 0x3dd0: 0x000c, 0x3dd1: 0x000c,
- 0x3dd2: 0x000c, 0x3dd3: 0x000c, 0x3dd4: 0x000c, 0x3dd5: 0x000c, 0x3dd6: 0x000c, 0x3dd7: 0x000c,
- 0x3dd8: 0x000c, 0x3dd9: 0x000c, 0x3dda: 0x000c, 0x3ddb: 0x000c, 0x3ddc: 0x000c, 0x3ddd: 0x000c,
- 0x3dde: 0x000c, 0x3ddf: 0x000c, 0x3de0: 0x000c, 0x3de1: 0x000c, 0x3de2: 0x000c, 0x3de3: 0x000c,
- 0x3de4: 0x000c, 0x3de5: 0x000c, 0x3de6: 0x000c, 0x3de7: 0x000c, 0x3de8: 0x000c, 0x3de9: 0x000c,
- 0x3dea: 0x000c, 0x3deb: 0x000c, 0x3dec: 0x000c, 0x3ded: 0x000c, 0x3dee: 0x000c, 0x3def: 0x000c,
- 0x3df0: 0x000b, 0x3df1: 0x000b, 0x3df2: 0x000b, 0x3df3: 0x000b, 0x3df4: 0x000b, 0x3df5: 0x000b,
- 0x3df6: 0x000b, 0x3df7: 0x000b, 0x3df8: 0x000b, 0x3df9: 0x000b, 0x3dfa: 0x000b, 0x3dfb: 0x000b,
- 0x3dfc: 0x000b, 0x3dfd: 0x000b, 0x3dfe: 0x000b, 0x3dff: 0x000b,
-}
-
-// bidiIndex: 24 blocks, 1536 entries, 1536 bytes
-// Block 0 is the zero block.
-var bidiIndex = [1536]uint8{
- // Block 0x0, offset 0x0
- // Block 0x1, offset 0x40
- // Block 0x2, offset 0x80
- // Block 0x3, offset 0xc0
- 0xc2: 0x01, 0xc3: 0x02,
- 0xca: 0x03, 0xcb: 0x04, 0xcc: 0x05, 0xcd: 0x06, 0xce: 0x07, 0xcf: 0x08,
- 0xd2: 0x09, 0xd6: 0x0a, 0xd7: 0x0b,
- 0xd8: 0x0c, 0xd9: 0x0d, 0xda: 0x0e, 0xdb: 0x0f, 0xdc: 0x10, 0xdd: 0x11, 0xde: 0x12, 0xdf: 0x13,
- 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06,
- 0xea: 0x07, 0xef: 0x08,
- 0xf0: 0x11, 0xf1: 0x12, 0xf2: 0x12, 0xf3: 0x14, 0xf4: 0x15,
- // Block 0x4, offset 0x100
- 0x120: 0x14, 0x121: 0x15, 0x122: 0x16, 0x123: 0x17, 0x124: 0x18, 0x125: 0x19, 0x126: 0x1a, 0x127: 0x1b,
- 0x128: 0x1c, 0x129: 0x1d, 0x12a: 0x1c, 0x12b: 0x1e, 0x12c: 0x1f, 0x12d: 0x20, 0x12e: 0x21, 0x12f: 0x22,
- 0x130: 0x23, 0x131: 0x24, 0x132: 0x1a, 0x133: 0x25, 0x134: 0x26, 0x135: 0x27, 0x136: 0x28, 0x137: 0x29,
- 0x138: 0x2a, 0x139: 0x2b, 0x13a: 0x2c, 0x13b: 0x2d, 0x13c: 0x2e, 0x13d: 0x2f, 0x13e: 0x30, 0x13f: 0x31,
- // Block 0x5, offset 0x140
- 0x140: 0x32, 0x141: 0x33, 0x142: 0x34,
- 0x14d: 0x35, 0x14e: 0x36,
- 0x150: 0x37,
- 0x15a: 0x38, 0x15c: 0x39, 0x15d: 0x3a, 0x15e: 0x3b, 0x15f: 0x3c,
- 0x160: 0x3d, 0x162: 0x3e, 0x164: 0x3f, 0x165: 0x40, 0x167: 0x41,
- 0x168: 0x42, 0x169: 0x43, 0x16a: 0x44, 0x16b: 0x45, 0x16c: 0x46, 0x16d: 0x47, 0x16e: 0x48, 0x16f: 0x49,
- 0x170: 0x4a, 0x173: 0x4b, 0x177: 0x4c,
- 0x17e: 0x4d, 0x17f: 0x4e,
- // Block 0x6, offset 0x180
- 0x180: 0x4f, 0x181: 0x50, 0x182: 0x51, 0x183: 0x52, 0x184: 0x53, 0x185: 0x54, 0x186: 0x55, 0x187: 0x56,
- 0x188: 0x57, 0x189: 0x56, 0x18a: 0x56, 0x18b: 0x56, 0x18c: 0x58, 0x18d: 0x59, 0x18e: 0x5a, 0x18f: 0x56,
- 0x190: 0x5b, 0x191: 0x5c, 0x192: 0x5d, 0x193: 0x5e, 0x194: 0x56, 0x195: 0x56, 0x196: 0x56, 0x197: 0x56,
- 0x198: 0x56, 0x199: 0x56, 0x19a: 0x5f, 0x19b: 0x56, 0x19c: 0x56, 0x19d: 0x60, 0x19e: 0x56, 0x19f: 0x61,
- 0x1a4: 0x56, 0x1a5: 0x56, 0x1a6: 0x62, 0x1a7: 0x63,
- 0x1a8: 0x56, 0x1a9: 0x56, 0x1aa: 0x56, 0x1ab: 0x56, 0x1ac: 0x56, 0x1ad: 0x64, 0x1ae: 0x65, 0x1af: 0x56,
- 0x1b3: 0x66, 0x1b5: 0x67, 0x1b7: 0x68,
- 0x1b8: 0x69, 0x1b9: 0x6a, 0x1ba: 0x6b, 0x1bb: 0x6c, 0x1bc: 0x56, 0x1bd: 0x56, 0x1be: 0x56, 0x1bf: 0x6d,
- // Block 0x7, offset 0x1c0
- 0x1c0: 0x6e, 0x1c2: 0x6f, 0x1c3: 0x70, 0x1c7: 0x71,
- 0x1c8: 0x72, 0x1c9: 0x73, 0x1ca: 0x74, 0x1cb: 0x75, 0x1cd: 0x76, 0x1cf: 0x77,
- // Block 0x8, offset 0x200
- 0x237: 0x56,
- // Block 0x9, offset 0x240
- 0x252: 0x78, 0x253: 0x79,
- 0x258: 0x7a, 0x259: 0x7b, 0x25a: 0x7c, 0x25b: 0x7d, 0x25c: 0x7e, 0x25e: 0x7f,
- 0x260: 0x80, 0x261: 0x81, 0x263: 0x82, 0x264: 0x83, 0x265: 0x84, 0x266: 0x85, 0x267: 0x86,
- 0x268: 0x87, 0x269: 0x88, 0x26a: 0x89, 0x26b: 0x8a, 0x26d: 0x8b, 0x26f: 0x8c,
- // Block 0xa, offset 0x280
- 0x2ac: 0x8d, 0x2ad: 0x8e, 0x2ae: 0x0e, 0x2af: 0x0e,
- 0x2b0: 0x0e, 0x2b1: 0x0e, 0x2b2: 0x0e, 0x2b3: 0x0e, 0x2b4: 0x8f, 0x2b5: 0x0e, 0x2b6: 0x0e, 0x2b7: 0x90,
- 0x2b8: 0x91, 0x2b9: 0x92, 0x2ba: 0x0e, 0x2bb: 0x93, 0x2bc: 0x94, 0x2bd: 0x95, 0x2bf: 0x96,
- // Block 0xb, offset 0x2c0
- 0x2c4: 0x97, 0x2c5: 0x56, 0x2c6: 0x98, 0x2c7: 0x99,
- 0x2cb: 0x9a, 0x2cd: 0x9b,
- 0x2e0: 0x9c, 0x2e1: 0x9c, 0x2e2: 0x9c, 0x2e3: 0x9c, 0x2e4: 0x9d, 0x2e5: 0x9c, 0x2e6: 0x9c, 0x2e7: 0x9c,
- 0x2e8: 0x9e, 0x2e9: 0x9c, 0x2ea: 0x9c, 0x2eb: 0x9f, 0x2ec: 0xa0, 0x2ed: 0x9c, 0x2ee: 0x9c, 0x2ef: 0x9c,
- 0x2f0: 0x9c, 0x2f1: 0x9c, 0x2f2: 0x9c, 0x2f3: 0x9c, 0x2f4: 0xa1, 0x2f5: 0x9c, 0x2f6: 0x9c, 0x2f7: 0x9c,
- 0x2f8: 0x9c, 0x2f9: 0xa2, 0x2fa: 0xa3, 0x2fb: 0x9c, 0x2fc: 0xa4, 0x2fd: 0xa5, 0x2fe: 0x9c, 0x2ff: 0x9c,
- // Block 0xc, offset 0x300
- 0x300: 0xa6, 0x301: 0xa7, 0x302: 0xa8, 0x304: 0xa9, 0x305: 0xaa, 0x306: 0xab, 0x307: 0xac,
- 0x308: 0xad, 0x30b: 0xae, 0x30c: 0x26, 0x30d: 0xaf,
- 0x310: 0xb0, 0x311: 0xb1, 0x312: 0xb2, 0x313: 0xb3, 0x316: 0xb4, 0x317: 0xb5,
- 0x318: 0xb6, 0x319: 0xb7, 0x31a: 0xb8, 0x31c: 0xb9,
- 0x320: 0xba, 0x324: 0xbb, 0x325: 0xbc, 0x327: 0xbd,
- 0x328: 0xbe, 0x329: 0xbf, 0x32a: 0xc0,
- 0x330: 0xc1, 0x332: 0xc2, 0x334: 0xc3, 0x335: 0xc4, 0x336: 0xc5,
- 0x33b: 0xc6, 0x33f: 0xc7,
- // Block 0xd, offset 0x340
- 0x36b: 0xc8, 0x36c: 0xc9,
- 0x37d: 0xca, 0x37e: 0xcb, 0x37f: 0xcc,
- // Block 0xe, offset 0x380
- 0x3b2: 0xcd,
- // Block 0xf, offset 0x3c0
- 0x3c5: 0xce, 0x3c6: 0xcf,
- 0x3c8: 0x56, 0x3c9: 0xd0, 0x3cc: 0x56, 0x3cd: 0xd1,
- 0x3db: 0xd2, 0x3dc: 0xd3, 0x3dd: 0xd4, 0x3de: 0xd5, 0x3df: 0xd6,
- 0x3e8: 0xd7, 0x3e9: 0xd8, 0x3ea: 0xd9,
- // Block 0x10, offset 0x400
- 0x400: 0xda, 0x404: 0xc9,
- 0x40b: 0xdb,
- 0x420: 0x9c, 0x421: 0x9c, 0x422: 0x9c, 0x423: 0xdc, 0x424: 0x9c, 0x425: 0xdd, 0x426: 0x9c, 0x427: 0x9c,
- 0x428: 0x9c, 0x429: 0x9c, 0x42a: 0x9c, 0x42b: 0x9c, 0x42c: 0x9c, 0x42d: 0x9c, 0x42e: 0x9c, 0x42f: 0x9c,
- 0x430: 0x9c, 0x431: 0xa4, 0x432: 0x0e, 0x433: 0x9c, 0x434: 0x0e, 0x435: 0xde, 0x436: 0x9c, 0x437: 0x9c,
- 0x438: 0x0e, 0x439: 0x0e, 0x43a: 0x0e, 0x43b: 0xdf, 0x43c: 0x9c, 0x43d: 0x9c, 0x43e: 0x9c, 0x43f: 0x9c,
- // Block 0x11, offset 0x440
- 0x440: 0xe0, 0x441: 0x56, 0x442: 0xe1, 0x443: 0xe2, 0x444: 0xe3, 0x445: 0xe4, 0x446: 0xe5,
- 0x449: 0xe6, 0x44c: 0x56, 0x44d: 0x56, 0x44e: 0x56, 0x44f: 0x56,
- 0x450: 0x56, 0x451: 0x56, 0x452: 0x56, 0x453: 0x56, 0x454: 0x56, 0x455: 0x56, 0x456: 0x56, 0x457: 0x56,
- 0x458: 0x56, 0x459: 0x56, 0x45a: 0x56, 0x45b: 0xe7, 0x45c: 0x56, 0x45d: 0x6c, 0x45e: 0x56, 0x45f: 0xe8,
- 0x460: 0xe9, 0x461: 0xea, 0x462: 0xeb, 0x464: 0x56, 0x465: 0xec, 0x466: 0x56, 0x467: 0xed,
- 0x468: 0x56, 0x469: 0xee, 0x46a: 0xef, 0x46b: 0xf0, 0x46c: 0x56, 0x46d: 0x56, 0x46e: 0xf1, 0x46f: 0xf2,
- 0x47f: 0xf3,
- // Block 0x12, offset 0x480
- 0x4bf: 0xf3,
- // Block 0x13, offset 0x4c0
- 0x4d0: 0x09, 0x4d1: 0x0a, 0x4d6: 0x0b,
- 0x4db: 0x0c, 0x4dd: 0x0d, 0x4de: 0x0e, 0x4df: 0x0f,
- 0x4ef: 0x10,
- 0x4ff: 0x10,
- // Block 0x14, offset 0x500
- 0x50f: 0x10,
- 0x51f: 0x10,
- 0x52f: 0x10,
- 0x53f: 0x10,
- // Block 0x15, offset 0x540
- 0x540: 0xf4, 0x541: 0xf4, 0x542: 0xf4, 0x543: 0xf4, 0x544: 0x05, 0x545: 0x05, 0x546: 0x05, 0x547: 0xf5,
- 0x548: 0xf4, 0x549: 0xf4, 0x54a: 0xf4, 0x54b: 0xf4, 0x54c: 0xf4, 0x54d: 0xf4, 0x54e: 0xf4, 0x54f: 0xf4,
- 0x550: 0xf4, 0x551: 0xf4, 0x552: 0xf4, 0x553: 0xf4, 0x554: 0xf4, 0x555: 0xf4, 0x556: 0xf4, 0x557: 0xf4,
- 0x558: 0xf4, 0x559: 0xf4, 0x55a: 0xf4, 0x55b: 0xf4, 0x55c: 0xf4, 0x55d: 0xf4, 0x55e: 0xf4, 0x55f: 0xf4,
- 0x560: 0xf4, 0x561: 0xf4, 0x562: 0xf4, 0x563: 0xf4, 0x564: 0xf4, 0x565: 0xf4, 0x566: 0xf4, 0x567: 0xf4,
- 0x568: 0xf4, 0x569: 0xf4, 0x56a: 0xf4, 0x56b: 0xf4, 0x56c: 0xf4, 0x56d: 0xf4, 0x56e: 0xf4, 0x56f: 0xf4,
- 0x570: 0xf4, 0x571: 0xf4, 0x572: 0xf4, 0x573: 0xf4, 0x574: 0xf4, 0x575: 0xf4, 0x576: 0xf4, 0x577: 0xf4,
- 0x578: 0xf4, 0x579: 0xf4, 0x57a: 0xf4, 0x57b: 0xf4, 0x57c: 0xf4, 0x57d: 0xf4, 0x57e: 0xf4, 0x57f: 0xf4,
- // Block 0x16, offset 0x580
- 0x58f: 0x10,
- 0x59f: 0x10,
- 0x5a0: 0x13,
- 0x5af: 0x10,
- 0x5bf: 0x10,
- // Block 0x17, offset 0x5c0
- 0x5cf: 0x10,
-}
-
-// Total table size 17464 bytes (17KiB); checksum: F50EF68C
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/forminfo.go b/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/forminfo.go
deleted file mode 100644
index d69ccb4f97..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/forminfo.go
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2011 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 norm
-
-import "encoding/binary"
-
-// This file contains Form-specific logic and wrappers for data in tables.go.
-
-// Rune info is stored in a separate trie per composing form. A composing form
-// and its corresponding decomposing form share the same trie. Each trie maps
-// a rune to a uint16. The values take two forms. For v >= 0x8000:
-// bits
-// 15: 1 (inverse of NFD_QC bit of qcInfo)
-// 13..7: qcInfo (see below). isYesD is always true (no decompostion).
-// 6..0: ccc (compressed CCC value).
-// For v < 0x8000, the respective rune has a decomposition and v is an index
-// into a byte array of UTF-8 decomposition sequences and additional info and
-// has the form:
-// <header> <decomp_byte>* [<tccc> [<lccc>]]
-// The header contains the number of bytes in the decomposition (excluding this
-// length byte). The two most significant bits of this length byte correspond
-// to bit 5 and 4 of qcInfo (see below). The byte sequence itself starts at v+1.
-// The byte sequence is followed by a trailing and leading CCC if the values
-// for these are not zero. The value of v determines which ccc are appended
-// to the sequences. For v < firstCCC, there are none, for v >= firstCCC,
-// the sequence is followed by a trailing ccc, and for v >= firstLeadingCC
-// there is an additional leading ccc. The value of tccc itself is the
-// trailing CCC shifted left 2 bits. The two least-significant bits of tccc
-// are the number of trailing non-starters.
-
-const (
- qcInfoMask = 0x3F // to clear all but the relevant bits in a qcInfo
- headerLenMask = 0x3F // extract the length value from the header byte
- headerFlagsMask = 0xC0 // extract the qcInfo bits from the header byte
-)
-
-// Properties provides access to normalization properties of a rune.
-type Properties struct {
- pos uint8 // start position in reorderBuffer; used in composition.go
- size uint8 // length of UTF-8 encoding of this rune
- ccc uint8 // leading canonical combining class (ccc if not decomposition)
- tccc uint8 // trailing canonical combining class (ccc if not decomposition)
- nLead uint8 // number of leading non-starters.
- flags qcInfo // quick check flags
- index uint16
-}
-
-// functions dispatchable per form
-type lookupFunc func(b input, i int) Properties
-
-// formInfo holds Form-specific functions and tables.
-type formInfo struct {
- form Form
- composing, compatibility bool // form type
- info lookupFunc
- nextMain iterFunc
-}
-
-var formTable = []*formInfo{{
- form: NFC,
- composing: true,
- compatibility: false,
- info: lookupInfoNFC,
- nextMain: nextComposed,
-}, {
- form: NFD,
- composing: false,
- compatibility: false,
- info: lookupInfoNFC,
- nextMain: nextDecomposed,
-}, {
- form: NFKC,
- composing: true,
- compatibility: true,
- info: lookupInfoNFKC,
- nextMain: nextComposed,
-}, {
- form: NFKD,
- composing: false,
- compatibility: true,
- info: lookupInfoNFKC,
- nextMain: nextDecomposed,
-}}
-
-// We do not distinguish between boundaries for NFC, NFD, etc. to avoid
-// unexpected behavior for the user. For example, in NFD, there is a boundary
-// after 'a'. However, 'a' might combine with modifiers, so from the application's
-// perspective it is not a good boundary. We will therefore always use the
-// boundaries for the combining variants.
-
-// BoundaryBefore returns true if this rune starts a new segment and
-// cannot combine with any rune on the left.
-func (p Properties) BoundaryBefore() bool {
- if p.ccc == 0 && !p.combinesBackward() {
- return true
- }
- // We assume that the CCC of the first character in a decomposition
- // is always non-zero if different from info.ccc and that we can return
- // false at this point. This is verified by maketables.
- return false
-}
-
-// BoundaryAfter returns true if runes cannot combine with or otherwise
-// interact with this or previous runes.
-func (p Properties) BoundaryAfter() bool {
- // TODO: loosen these conditions.
- return p.isInert()
-}
-
-// We pack quick check data in 4 bits:
-//
-// 5: Combines forward (0 == false, 1 == true)
-// 4..3: NFC_QC Yes(00), No (10), or Maybe (11)
-// 2: NFD_QC Yes (0) or No (1). No also means there is a decomposition.
-// 1..0: Number of trailing non-starters.
-//
-// When all 4 bits are zero, the character is inert, meaning it is never
-// influenced by normalization.
-type qcInfo uint8
-
-func (p Properties) isYesC() bool { return p.flags&0x10 == 0 }
-func (p Properties) isYesD() bool { return p.flags&0x4 == 0 }
-
-func (p Properties) combinesForward() bool { return p.flags&0x20 != 0 }
-func (p Properties) combinesBackward() bool { return p.flags&0x8 != 0 } // == isMaybe
-func (p Properties) hasDecomposition() bool { return p.flags&0x4 != 0 } // == isNoD
-
-func (p Properties) isInert() bool {
- return p.flags&qcInfoMask == 0 && p.ccc == 0
-}
-
-func (p Properties) multiSegment() bool {
- return p.index >= firstMulti && p.index < endMulti
-}
-
-func (p Properties) nLeadingNonStarters() uint8 {
- return p.nLead
-}
-
-func (p Properties) nTrailingNonStarters() uint8 {
- return uint8(p.flags & 0x03)
-}
-
-// Decomposition returns the decomposition for the underlying rune
-// or nil if there is none.
-func (p Properties) Decomposition() []byte {
- // TODO: create the decomposition for Hangul?
- if p.index == 0 {
- return nil
- }
- i := p.index
- n := decomps[i] & headerLenMask
- i++
- return decomps[i : i+uint16(n)]
-}
-
-// Size returns the length of UTF-8 encoding of the rune.
-func (p Properties) Size() int {
- return int(p.size)
-}
-
-// CCC returns the canonical combining class of the underlying rune.
-func (p Properties) CCC() uint8 {
- if p.index >= firstCCCZeroExcept {
- return 0
- }
- return ccc[p.ccc]
-}
-
-// LeadCCC returns the CCC of the first rune in the decomposition.
-// If there is no decomposition, LeadCCC equals CCC.
-func (p Properties) LeadCCC() uint8 {
- return ccc[p.ccc]
-}
-
-// TrailCCC returns the CCC of the last rune in the decomposition.
-// If there is no decomposition, TrailCCC equals CCC.
-func (p Properties) TrailCCC() uint8 {
- return ccc[p.tccc]
-}
-
-func buildRecompMap() {
- recompMap = make(map[uint32]rune, len(recompMapPacked)/8)
- var buf [8]byte
- for i := 0; i < len(recompMapPacked); i += 8 {
- copy(buf[:], recompMapPacked[i:i+8])
- key := binary.BigEndian.Uint32(buf[:4])
- val := binary.BigEndian.Uint32(buf[4:])
- recompMap[key] = rune(val)
- }
-}
-
-// Recomposition
-// We use 32-bit keys instead of 64-bit for the two codepoint keys.
-// This clips off the bits of three entries, but we know this will not
-// result in a collision. In the unlikely event that changes to
-// UnicodeData.txt introduce collisions, the compiler will catch it.
-// Note that the recomposition map for NFC and NFKC are identical.
-
-// combine returns the combined rune or 0 if it doesn't exist.
-//
-// The caller is responsible for calling
-// recompMapOnce.Do(buildRecompMap) sometime before this is called.
-func combine(a, b rune) rune {
- key := uint32(uint16(a))<<16 + uint32(uint16(b))
- if recompMap == nil {
- panic("caller error") // see func comment
- }
- return recompMap[key]
-}
-
-func lookupInfoNFC(b input, i int) Properties {
- v, sz := b.charinfoNFC(i)
- return compInfo(v, sz)
-}
-
-func lookupInfoNFKC(b input, i int) Properties {
- v, sz := b.charinfoNFKC(i)
- return compInfo(v, sz)
-}
-
-// Properties returns properties for the first rune in s.
-func (f Form) Properties(s []byte) Properties {
- if f == NFC || f == NFD {
- return compInfo(nfcData.lookup(s))
- }
- return compInfo(nfkcData.lookup(s))
-}
-
-// PropertiesString returns properties for the first rune in s.
-func (f Form) PropertiesString(s string) Properties {
- if f == NFC || f == NFD {
- return compInfo(nfcData.lookupString(s))
- }
- return compInfo(nfkcData.lookupString(s))
-}
-
-// compInfo converts the information contained in v and sz
-// to a Properties. See the comment at the top of the file
-// for more information on the format.
-func compInfo(v uint16, sz int) Properties {
- if v == 0 {
- return Properties{size: uint8(sz)}
- } else if v >= 0x8000 {
- p := Properties{
- size: uint8(sz),
- ccc: uint8(v),
- tccc: uint8(v),
- flags: qcInfo(v >> 8),
- }
- if p.ccc > 0 || p.combinesBackward() {
- p.nLead = uint8(p.flags & 0x3)
- }
- return p
- }
- // has decomposition
- h := decomps[v]
- f := (qcInfo(h&headerFlagsMask) >> 2) | 0x4
- p := Properties{size: uint8(sz), flags: f, index: v}
- if v >= firstCCC {
- v += uint16(h&headerLenMask) + 1
- c := decomps[v]
- p.tccc = c >> 2
- p.flags |= qcInfo(c & 0x3)
- if v >= firstLeadingCCC {
- p.nLead = c & 0x3
- if v >= firstStarterWithNLead {
- // We were tricked. Remove the decomposition.
- p.flags &= 0x03
- p.index = 0
- return p
- }
- p.ccc = decomps[v+1]
- }
- }
- return p
-}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go b/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
deleted file mode 100644
index 9115ef257e..0000000000
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
+++ /dev/null
@@ -1,7761 +0,0 @@
-// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
-
-//go:build go1.16
-// +build go1.16
-
-package norm
-
-import "sync"
-
-const (
- // Version is the Unicode edition from which the tables are derived.
- Version = "13.0.0"
-
- // MaxTransformChunkSize indicates the maximum number of bytes that Transform
- // may need to write atomically for any Form. Making a destination buffer at
- // least this size ensures that Transform can always make progress and that
- // the user does not need to grow the buffer on an ErrShortDst.
- MaxTransformChunkSize = 35 + maxNonStarters*4
-)
-
-var ccc = [56]uint8{
- 0, 1, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 16, 17, 18, 19,
- 20, 21, 22, 23, 24, 25, 26, 27,
- 28, 29, 30, 31, 32, 33, 34, 35,
- 36, 84, 91, 103, 107, 118, 122, 129,
- 130, 132, 202, 214, 216, 218, 220, 222,
- 224, 226, 228, 230, 232, 233, 234, 240,
-}
-
-const (
- firstMulti = 0x1870
- firstCCC = 0x2CAB
- endMulti = 0x2F77
- firstLeadingCCC = 0x49C5
- firstCCCZeroExcept = 0x4A8F
- firstStarterWithNLead = 0x4AB6
- lastDecomp = 0x4AB8
- maxDecomp = 0x8000
-)
-
-// decomps: 19128 bytes
-var decomps = [...]byte{
- // Bytes 0 - 3f
- 0x00, 0x41, 0x20, 0x41, 0x21, 0x41, 0x22, 0x41,
- 0x23, 0x41, 0x24, 0x41, 0x25, 0x41, 0x26, 0x41,
- 0x27, 0x41, 0x28, 0x41, 0x29, 0x41, 0x2A, 0x41,
- 0x2B, 0x41, 0x2C, 0x41, 0x2D, 0x41, 0x2E, 0x41,
- 0x2F, 0x41, 0x30, 0x41, 0x31, 0x41, 0x32, 0x41,
- 0x33, 0x41, 0x34, 0x41, 0x35, 0x41, 0x36, 0x41,
- 0x37, 0x41, 0x38, 0x41, 0x39, 0x41, 0x3A, 0x41,
- 0x3B, 0x41, 0x3C, 0x41, 0x3D, 0x41, 0x3E, 0x41,
- // Bytes 40 - 7f
- 0x3F, 0x41, 0x40, 0x41, 0x41, 0x41, 0x42, 0x41,
- 0x43, 0x41, 0x44, 0x41, 0x45, 0x41, 0x46, 0x41,
- 0x47, 0x41, 0x48, 0x41, 0x49, 0x41, 0x4A, 0x41,
- 0x4B, 0x41, 0x4C, 0x41, 0x4D, 0x41, 0x4E, 0x41,
- 0x4F, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41,
- 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41,
- 0x57, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5A, 0x41,
- 0x5B, 0x41, 0x5C, 0x41, 0x5D, 0x41, 0x5E, 0x41,
- // Bytes 80 - bf
- 0x5F, 0x41, 0x60, 0x41, 0x61, 0x41, 0x62, 0x41,
- 0x63, 0x41, 0x64, 0x41, 0x65, 0x41, 0x66, 0x41,
- 0x67, 0x41, 0x68, 0x41, 0x69, 0x41, 0x6A, 0x41,
- 0x6B, 0x41, 0x6C, 0x41, 0x6D, 0x41, 0x6E, 0x41,
- 0x6F, 0x41, 0x70, 0x41, 0x71, 0x41, 0x72, 0x41,
- 0x73, 0x41, 0x74, 0x41, 0x75, 0x41, 0x76, 0x41,
- 0x77, 0x41, 0x78, 0x41, 0x79, 0x41, 0x7A, 0x41,
- 0x7B, 0x41, 0x7C, 0x41, 0x7D, 0x41, 0x7E, 0x42,
- // Bytes c0 - ff
- 0xC2, 0xA2, 0x42, 0xC2, 0xA3, 0x42, 0xC2, 0xA5,
- 0x42, 0xC2, 0xA6, 0x42, 0xC2, 0xAC, 0x42, 0xC2,
- 0xB7, 0x42, 0xC3, 0x86, 0x42, 0xC3, 0xB0, 0x42,
- 0xC4, 0xA6, 0x42, 0xC4, 0xA7, 0x42, 0xC4, 0xB1,
- 0x42, 0xC5, 0x8B, 0x42, 0xC5, 0x93, 0x42, 0xC6,
- 0x8E, 0x42, 0xC6, 0x90, 0x42, 0xC6, 0xAB, 0x42,
- 0xC8, 0xA2, 0x42, 0xC8, 0xB7, 0x42, 0xC9, 0x90,
- 0x42, 0xC9, 0x91, 0x42, 0xC9, 0x92, 0x42, 0xC9,
- // Bytes 100 - 13f
- 0x94, 0x42, 0xC9, 0x95, 0x42, 0xC9, 0x99, 0x42,
- 0xC9, 0x9B, 0x42, 0xC9, 0x9C, 0x42, 0xC9, 0x9F,
- 0x42, 0xC9, 0xA1, 0x42, 0xC9, 0xA3, 0x42, 0xC9,
- 0xA5, 0x42, 0xC9, 0xA6, 0x42, 0xC9, 0xA8, 0x42,
- 0xC9, 0xA9, 0x42, 0xC9, 0xAA, 0x42, 0xC9, 0xAB,
- 0x42, 0xC9, 0xAD, 0x42, 0xC9, 0xAF, 0x42, 0xC9,
- 0xB0, 0x42, 0xC9, 0xB1, 0x42, 0xC9, 0xB2, 0x42,
- 0xC9, 0xB3, 0x42, 0xC9, 0xB4, 0x42, 0xC9, 0xB5,
- // Bytes 140 - 17f
- 0x42, 0xC9, 0xB8, 0x42, 0xC9, 0xB9, 0x42, 0xC9,
- 0xBB, 0x42, 0xCA, 0x81, 0x42, 0xCA, 0x82, 0x42,
- 0xCA, 0x83, 0x42, 0xCA, 0x89, 0x42, 0xCA, 0x8A,
- 0x42, 0xCA, 0x8B, 0x42, 0xCA, 0x8C, 0x42, 0xCA,
- 0x8D, 0x42, 0xCA, 0x90, 0x42, 0xCA, 0x91, 0x42,
- 0xCA, 0x92, 0x42, 0xCA, 0x95, 0x42, 0xCA, 0x9D,
- 0x42, 0xCA, 0x9F, 0x42, 0xCA, 0xB9, 0x42, 0xCE,
- 0x91, 0x42, 0xCE, 0x92, 0x42, 0xCE, 0x93, 0x42,
- // Bytes 180 - 1bf
- 0xCE, 0x94, 0x42, 0xCE, 0x95, 0x42, 0xCE, 0x96,
- 0x42, 0xCE, 0x97, 0x42, 0xCE, 0x98, 0x42, 0xCE,
- 0x99, 0x42, 0xCE, 0x9A, 0x42, 0xCE, 0x9B, 0x42,
- 0xCE, 0x9C, 0x42, 0xCE, 0x9D, 0x42, 0xCE, 0x9E,
- 0x42, 0xCE, 0x9F, 0x42, 0xCE, 0xA0, 0x42, 0xCE,
- 0xA1, 0x42, 0xCE, 0xA3, 0x42, 0xCE, 0xA4, 0x42,
- 0xCE, 0xA5, 0x42, 0xCE, 0xA6, 0x42, 0xCE, 0xA7,
- 0x42, 0xCE, 0xA8, 0x42, 0xCE, 0xA9, 0x42, 0xCE,
- // Bytes 1c0 - 1ff
- 0xB1, 0x42, 0xCE, 0xB2, 0x42, 0xCE, 0xB3, 0x42,
- 0xCE, 0xB4, 0x42, 0xCE, 0xB5, 0x42, 0xCE, 0xB6,
- 0x42, 0xCE, 0xB7, 0x42, 0xCE, 0xB8, 0x42, 0xCE,
- 0xB9, 0x42, 0xCE, 0xBA, 0x42, 0xCE, 0xBB, 0x42,
- 0xCE, 0xBC, 0x42, 0xCE, 0xBD, 0x42, 0xCE, 0xBE,
- 0x42, 0xCE, 0xBF, 0x42, 0xCF, 0x80, 0x42, 0xCF,
- 0x81, 0x42, 0xCF, 0x82, 0x42, 0xCF, 0x83, 0x42,
- 0xCF, 0x84, 0x42, 0xCF, 0x85, 0x42, 0xCF, 0x86,
- // Bytes 200 - 23f
- 0x42, 0xCF, 0x87, 0x42, 0xCF, 0x88, 0x42, 0xCF,
- 0x89, 0x42, 0xCF, 0x9C, 0x42, 0xCF, 0x9D, 0x42,
- 0xD0, 0xBD, 0x42, 0xD1, 0x8A, 0x42, 0xD1, 0x8C,
- 0x42, 0xD7, 0x90, 0x42, 0xD7, 0x91, 0x42, 0xD7,
- 0x92, 0x42, 0xD7, 0x93, 0x42, 0xD7, 0x94, 0x42,
- 0xD7, 0x9B, 0x42, 0xD7, 0x9C, 0x42, 0xD7, 0x9D,
- 0x42, 0xD7, 0xA2, 0x42, 0xD7, 0xA8, 0x42, 0xD7,
- 0xAA, 0x42, 0xD8, 0xA1, 0x42, 0xD8, 0xA7, 0x42,
- // Bytes 240 - 27f
- 0xD8, 0xA8, 0x42, 0xD8, 0xA9, 0x42, 0xD8, 0xAA,
- 0x42, 0xD8, 0xAB, 0x42, 0xD8, 0xAC, 0x42, 0xD8,
- 0xAD, 0x42, 0xD8, 0xAE, 0x42, 0xD8, 0xAF, 0x42,
- 0xD8, 0xB0, 0x42, 0xD8, 0xB1, 0x42, 0xD8, 0xB2,
- 0x42, 0xD8, 0xB3, 0x42, 0xD8, 0xB4, 0x42, 0xD8,
- 0xB5, 0x42, 0xD8, 0xB6, 0x42, 0xD8, 0xB7, 0x42,
- 0xD8, 0xB8, 0x42, 0xD8, 0xB9, 0x42, 0xD8, 0xBA,
- 0x42, 0xD9, 0x81, 0x42, 0xD9, 0x82, 0x42, 0xD9,
- // Bytes 280 - 2bf
- 0x83, 0x42, 0xD9, 0x84, 0x42, 0xD9, 0x85, 0x42,
- 0xD9, 0x86, 0x42, 0xD9, 0x87, 0x42, 0xD9, 0x88,
- 0x42, 0xD9, 0x89, 0x42, 0xD9, 0x8A, 0x42, 0xD9,
- 0xAE, 0x42, 0xD9, 0xAF, 0x42, 0xD9, 0xB1, 0x42,
- 0xD9, 0xB9, 0x42, 0xD9, 0xBA, 0x42, 0xD9, 0xBB,
- 0x42, 0xD9, 0xBE, 0x42, 0xD9, 0xBF, 0x42, 0xDA,
- 0x80, 0x42, 0xDA, 0x83, 0x42, 0xDA, 0x84, 0x42,
- 0xDA, 0x86, 0x42, 0xDA, 0x87, 0x42, 0xDA, 0x88,
- // Bytes 2c0 - 2ff
- 0x42, 0xDA, 0x8C, 0x42, 0xDA, 0x8D, 0x42, 0xDA,
- 0x8E, 0x42, 0xDA, 0x91, 0x42, 0xDA, 0x98, 0x42,
- 0xDA, 0xA1, 0x42, 0xDA, 0xA4, 0x42, 0xDA, 0xA6,
- 0x42, 0xDA, 0xA9, 0x42, 0xDA, 0xAD, 0x42, 0xDA,
- 0xAF, 0x42, 0xDA, 0xB1, 0x42, 0xDA, 0xB3, 0x42,
- 0xDA, 0xBA, 0x42, 0xDA, 0xBB, 0x42, 0xDA, 0xBE,
- 0x42, 0xDB, 0x81, 0x42, 0xDB, 0x85, 0x42, 0xDB,
- 0x86, 0x42, 0xDB, 0x87, 0x42, 0xDB, 0x88, 0x42,
- // Bytes 300 - 33f
- 0xDB, 0x89, 0x42, 0xDB, 0x8B, 0x42, 0xDB, 0x8C,
- 0x42, 0xDB, 0x90, 0x42, 0xDB, 0x92, 0x43, 0xE0,
- 0xBC, 0x8B, 0x43, 0xE1, 0x83, 0x9C, 0x43, 0xE1,
- 0x84, 0x80, 0x43, 0xE1, 0x84, 0x81, 0x43, 0xE1,
- 0x84, 0x82, 0x43, 0xE1, 0x84, 0x83, 0x43, 0xE1,
- 0x84, 0x84, 0x43, 0xE1, 0x84, 0x85, 0x43, 0xE1,
- 0x84, 0x86, 0x43, 0xE1, 0x84, 0x87, 0x43, 0xE1,
- 0x84, 0x88, 0x43, 0xE1, 0x84, 0x89, 0x43, 0xE1,
- // Bytes 340 - 37f
- 0x84, 0x8A, 0x43, 0xE1, 0x84, 0x8B, 0x43, 0xE1,
- 0x84, 0x8C, 0x43, 0xE1, 0x84, 0x8D, 0x43, 0xE1,
- 0x84, 0x8E, 0x43, 0xE1, 0x84, 0x8F, 0x43, 0xE1,
- 0x84, 0x90, 0x43, 0xE1, 0x84, 0x91, 0x43, 0xE1,
- 0x84, 0x92, 0x43, 0xE1, 0x84, 0x94, 0x43, 0xE1,
- 0x84, 0x95, 0x43, 0xE1, 0x84, 0x9A, 0x43, 0xE1,
- 0x84, 0x9C, 0x43, 0xE1, 0x84, 0x9D, 0x43, 0xE1,
- 0x84, 0x9E, 0x43, 0xE1, 0x84, 0xA0, 0x43, 0xE1,
- // Bytes 380 - 3bf
- 0x84, 0xA1, 0x43, 0xE1, 0x84, 0xA2, 0x43, 0xE1,
- 0x84, 0xA3, 0x43, 0xE1, 0x84, 0xA7, 0x43, 0xE1,
- 0x84, 0xA9, 0x43, 0xE1, 0x84, 0xAB, 0x43, 0xE1,
- 0x84, 0xAC, 0x43, 0xE1, 0x84, 0xAD, 0x43, 0xE1,
- 0x84, 0xAE, 0x43, 0xE1, 0x84, 0xAF, 0x43, 0xE1,
- 0x84, 0xB2, 0x43, 0xE1, 0x84, 0xB6, 0x43, 0xE1,
- 0x85, 0x80, 0x43, 0xE1, 0x85, 0x87, 0x43, 0xE1,
- 0x85, 0x8C, 0x43, 0xE1, 0x85, 0x97, 0x43, 0xE1,
- // Bytes 3c0 - 3ff
- 0x85, 0x98, 0x43, 0xE1, 0x85, 0x99, 0x43, 0xE1,
- 0x85, 0xA0, 0x43, 0xE1, 0x86, 0x84, 0x43, 0xE1,
- 0x86, 0x85, 0x43, 0xE1, 0x86, 0x88, 0x43, 0xE1,
- 0x86, 0x91, 0x43, 0xE1, 0x86, 0x92, 0x43, 0xE1,
- 0x86, 0x94, 0x43, 0xE1, 0x86, 0x9E, 0x43, 0xE1,
- 0x86, 0xA1, 0x43, 0xE1, 0x87, 0x87, 0x43, 0xE1,
- 0x87, 0x88, 0x43, 0xE1, 0x87, 0x8C, 0x43, 0xE1,
- 0x87, 0x8E, 0x43, 0xE1, 0x87, 0x93, 0x43, 0xE1,
- // Bytes 400 - 43f
- 0x87, 0x97, 0x43, 0xE1, 0x87, 0x99, 0x43, 0xE1,
- 0x87, 0x9D, 0x43, 0xE1, 0x87, 0x9F, 0x43, 0xE1,
- 0x87, 0xB1, 0x43, 0xE1, 0x87, 0xB2, 0x43, 0xE1,
- 0xB4, 0x82, 0x43, 0xE1, 0xB4, 0x96, 0x43, 0xE1,
- 0xB4, 0x97, 0x43, 0xE1, 0xB4, 0x9C, 0x43, 0xE1,
- 0xB4, 0x9D, 0x43, 0xE1, 0xB4, 0xA5, 0x43, 0xE1,
- 0xB5, 0xBB, 0x43, 0xE1, 0xB6, 0x85, 0x43, 0xE2,
- 0x80, 0x82, 0x43, 0xE2, 0x80, 0x83, 0x43, 0xE2,
- // Bytes 440 - 47f
- 0x80, 0x90, 0x43, 0xE2, 0x80, 0x93, 0x43, 0xE2,
- 0x80, 0x94, 0x43, 0xE2, 0x82, 0xA9, 0x43, 0xE2,
- 0x86, 0x90, 0x43, 0xE2, 0x86, 0x91, 0x43, 0xE2,
- 0x86, 0x92, 0x43, 0xE2, 0x86, 0x93, 0x43, 0xE2,
- 0x88, 0x82, 0x43, 0xE2, 0x88, 0x87, 0x43, 0xE2,
- 0x88, 0x91, 0x43, 0xE2, 0x88, 0x92, 0x43, 0xE2,
- 0x94, 0x82, 0x43, 0xE2, 0x96, 0xA0, 0x43, 0xE2,
- 0x97, 0x8B, 0x43, 0xE2, 0xA6, 0x85, 0x43, 0xE2,
- // Bytes 480 - 4bf
- 0xA6, 0x86, 0x43, 0xE2, 0xB5, 0xA1, 0x43, 0xE3,
- 0x80, 0x81, 0x43, 0xE3, 0x80, 0x82, 0x43, 0xE3,
- 0x80, 0x88, 0x43, 0xE3, 0x80, 0x89, 0x43, 0xE3,
- 0x80, 0x8A, 0x43, 0xE3, 0x80, 0x8B, 0x43, 0xE3,
- 0x80, 0x8C, 0x43, 0xE3, 0x80, 0x8D, 0x43, 0xE3,
- 0x80, 0x8E, 0x43, 0xE3, 0x80, 0x8F, 0x43, 0xE3,
- 0x80, 0x90, 0x43, 0xE3, 0x80, 0x91, 0x43, 0xE3,
- 0x80, 0x92, 0x43, 0xE3, 0x80, 0x94, 0x43, 0xE3,
- // Bytes 4c0 - 4ff
- 0x80, 0x95, 0x43, 0xE3, 0x80, 0x96, 0x43, 0xE3,
- 0x80, 0x97, 0x43, 0xE3, 0x82, 0xA1, 0x43, 0xE3,
- 0x82, 0xA2, 0x43, 0xE3, 0x82, 0xA3, 0x43, 0xE3,
- 0x82, 0xA4, 0x43, 0xE3, 0x82, 0xA5, 0x43, 0xE3,
- 0x82, 0xA6, 0x43, 0xE3, 0x82, 0xA7, 0x43, 0xE3,
- 0x82, 0xA8, 0x43, 0xE3, 0x82, 0xA9, 0x43, 0xE3,
- 0x82, 0xAA, 0x43, 0xE3, 0x82, 0xAB, 0x43, 0xE3,
- 0x82, 0xAD, 0x43, 0xE3, 0x82, 0xAF, 0x43, 0xE3,
- // Bytes 500 - 53f
- 0x82, 0xB1, 0x43, 0xE3, 0x82, 0xB3, 0x43, 0xE3,
- 0x82, 0xB5, 0x43, 0xE3, 0x82, 0xB7, 0x43, 0xE3,
- 0x82, 0xB9, 0x43, 0xE3, 0x82, 0xBB, 0x43, 0xE3,
- 0x82, 0xBD, 0x43, 0xE3, 0x82, 0xBF, 0x43, 0xE3,
- 0x83, 0x81, 0x43, 0xE3, 0x83, 0x83, 0x43, 0xE3,
- 0x83, 0x84, 0x43, 0xE3, 0x83, 0x86, 0x43, 0xE3,
- 0x83, 0x88, 0x43, 0xE3, 0x83, 0x8A, 0x43, 0xE3,
- 0x83, 0x8B, 0x43, 0xE3, 0x83, 0x8C, 0x43, 0xE3,
- // Bytes 540 - 57f
- 0x83, 0x8D, 0x43, 0xE3, 0x83, 0x8E, 0x43, 0xE3,
- 0x83, 0x8F, 0x43, 0xE3, 0x83, 0x92, 0x43, 0xE3,
- 0x83, 0x95, 0x43, 0xE3, 0x83, 0x98, 0x43, 0xE3,
- 0x83, 0x9B, 0x43, 0xE3, 0x83, 0x9E, 0x43, 0xE3,
- 0x83, 0x9F, 0x43, 0xE3, 0x83, 0xA0, 0x43, 0xE3,
- 0x83, 0xA1, 0x43, 0xE3, 0x83, 0xA2, 0x43, 0xE3,
- 0x83, 0xA3, 0x43, 0xE3, 0x83, 0xA4, 0x43, 0xE3,
- 0x83, 0xA5, 0x43, 0xE3, 0x83, 0xA6, 0x43, 0xE3,
- // Bytes 580 - 5bf
- 0x83, 0xA7, 0x43, 0xE3, 0x83, 0xA8, 0x43, 0xE3,
- 0x83, 0xA9, 0x43, 0xE3, 0x83, 0xAA, 0x43, 0xE3,
- 0x83, 0xAB, 0x43, 0xE3, 0x83, 0xAC, 0x43, 0xE3,
- 0x83, 0xAD, 0x43, 0xE3, 0x83, 0xAF, 0x43, 0xE3,
- 0x83, 0xB0, 0x43, 0xE3, 0x83, 0xB1, 0x43, 0xE3,
- 0x83, 0xB2, 0x43, 0xE3, 0x83, 0xB3, 0x43, 0xE3,
- 0x83, 0xBB, 0x43, 0xE3, 0x83, 0xBC, 0x43, 0xE3,
- 0x92, 0x9E, 0x43, 0xE3, 0x92, 0xB9, 0x43, 0xE3,
- // Bytes 5c0 - 5ff
- 0x92, 0xBB, 0x43, 0xE3, 0x93, 0x9F, 0x43, 0xE3,
- 0x94, 0x95, 0x43, 0xE3, 0x9B, 0xAE, 0x43, 0xE3,
- 0x9B, 0xBC, 0x43, 0xE3, 0x9E, 0x81, 0x43, 0xE3,
- 0xA0, 0xAF, 0x43, 0xE3, 0xA1, 0xA2, 0x43, 0xE3,
- 0xA1, 0xBC, 0x43, 0xE3, 0xA3, 0x87, 0x43, 0xE3,
- 0xA3, 0xA3, 0x43, 0xE3, 0xA4, 0x9C, 0x43, 0xE3,
- 0xA4, 0xBA, 0x43, 0xE3, 0xA8, 0xAE, 0x43, 0xE3,
- 0xA9, 0xAC, 0x43, 0xE3, 0xAB, 0xA4, 0x43, 0xE3,
- // Bytes 600 - 63f
- 0xAC, 0x88, 0x43, 0xE3, 0xAC, 0x99, 0x43, 0xE3,
- 0xAD, 0x89, 0x43, 0xE3, 0xAE, 0x9D, 0x43, 0xE3,
- 0xB0, 0x98, 0x43, 0xE3, 0xB1, 0x8E, 0x43, 0xE3,
- 0xB4, 0xB3, 0x43, 0xE3, 0xB6, 0x96, 0x43, 0xE3,
- 0xBA, 0xAC, 0x43, 0xE3, 0xBA, 0xB8, 0x43, 0xE3,
- 0xBC, 0x9B, 0x43, 0xE3, 0xBF, 0xBC, 0x43, 0xE4,
- 0x80, 0x88, 0x43, 0xE4, 0x80, 0x98, 0x43, 0xE4,
- 0x80, 0xB9, 0x43, 0xE4, 0x81, 0x86, 0x43, 0xE4,
- // Bytes 640 - 67f
- 0x82, 0x96, 0x43, 0xE4, 0x83, 0xA3, 0x43, 0xE4,
- 0x84, 0xAF, 0x43, 0xE4, 0x88, 0x82, 0x43, 0xE4,
- 0x88, 0xA7, 0x43, 0xE4, 0x8A, 0xA0, 0x43, 0xE4,
- 0x8C, 0x81, 0x43, 0xE4, 0x8C, 0xB4, 0x43, 0xE4,
- 0x8D, 0x99, 0x43, 0xE4, 0x8F, 0x95, 0x43, 0xE4,
- 0x8F, 0x99, 0x43, 0xE4, 0x90, 0x8B, 0x43, 0xE4,
- 0x91, 0xAB, 0x43, 0xE4, 0x94, 0xAB, 0x43, 0xE4,
- 0x95, 0x9D, 0x43, 0xE4, 0x95, 0xA1, 0x43, 0xE4,
- // Bytes 680 - 6bf
- 0x95, 0xAB, 0x43, 0xE4, 0x97, 0x97, 0x43, 0xE4,
- 0x97, 0xB9, 0x43, 0xE4, 0x98, 0xB5, 0x43, 0xE4,
- 0x9A, 0xBE, 0x43, 0xE4, 0x9B, 0x87, 0x43, 0xE4,
- 0xA6, 0x95, 0x43, 0xE4, 0xA7, 0xA6, 0x43, 0xE4,
- 0xA9, 0xAE, 0x43, 0xE4, 0xA9, 0xB6, 0x43, 0xE4,
- 0xAA, 0xB2, 0x43, 0xE4, 0xAC, 0xB3, 0x43, 0xE4,
- 0xAF, 0x8E, 0x43, 0xE4, 0xB3, 0x8E, 0x43, 0xE4,
- 0xB3, 0xAD, 0x43, 0xE4, 0xB3, 0xB8, 0x43, 0xE4,
- // Bytes 6c0 - 6ff
- 0xB5, 0x96, 0x43, 0xE4, 0xB8, 0x80, 0x43, 0xE4,
- 0xB8, 0x81, 0x43, 0xE4, 0xB8, 0x83, 0x43, 0xE4,
- 0xB8, 0x89, 0x43, 0xE4, 0xB8, 0x8A, 0x43, 0xE4,
- 0xB8, 0x8B, 0x43, 0xE4, 0xB8, 0x8D, 0x43, 0xE4,
- 0xB8, 0x99, 0x43, 0xE4, 0xB8, 0xA6, 0x43, 0xE4,
- 0xB8, 0xA8, 0x43, 0xE4, 0xB8, 0xAD, 0x43, 0xE4,
- 0xB8, 0xB2, 0x43, 0xE4, 0xB8, 0xB6, 0x43, 0xE4,
- 0xB8, 0xB8, 0x43, 0xE4, 0xB8, 0xB9, 0x43, 0xE4,
- // Bytes 700 - 73f
- 0xB8, 0xBD, 0x43, 0xE4, 0xB8, 0xBF, 0x43, 0xE4,
- 0xB9, 0x81, 0x43, 0xE4, 0xB9, 0x99, 0x43, 0xE4,
- 0xB9, 0x9D, 0x43, 0xE4, 0xBA, 0x82, 0x43, 0xE4,
- 0xBA, 0x85, 0x43, 0xE4, 0xBA, 0x86, 0x43, 0xE4,
- 0xBA, 0x8C, 0x43, 0xE4, 0xBA, 0x94, 0x43, 0xE4,
- 0xBA, 0xA0, 0x43, 0xE4, 0xBA, 0xA4, 0x43, 0xE4,
- 0xBA, 0xAE, 0x43, 0xE4, 0xBA, 0xBA, 0x43, 0xE4,
- 0xBB, 0x80, 0x43, 0xE4, 0xBB, 0x8C, 0x43, 0xE4,
- // Bytes 740 - 77f
- 0xBB, 0xA4, 0x43, 0xE4, 0xBC, 0x81, 0x43, 0xE4,
- 0xBC, 0x91, 0x43, 0xE4, 0xBD, 0xA0, 0x43, 0xE4,
- 0xBE, 0x80, 0x43, 0xE4, 0xBE, 0x86, 0x43, 0xE4,
- 0xBE, 0x8B, 0x43, 0xE4, 0xBE, 0xAE, 0x43, 0xE4,
- 0xBE, 0xBB, 0x43, 0xE4, 0xBE, 0xBF, 0x43, 0xE5,
- 0x80, 0x82, 0x43, 0xE5, 0x80, 0xAB, 0x43, 0xE5,
- 0x81, 0xBA, 0x43, 0xE5, 0x82, 0x99, 0x43, 0xE5,
- 0x83, 0x8F, 0x43, 0xE5, 0x83, 0x9A, 0x43, 0xE5,
- // Bytes 780 - 7bf
- 0x83, 0xA7, 0x43, 0xE5, 0x84, 0xAA, 0x43, 0xE5,
- 0x84, 0xBF, 0x43, 0xE5, 0x85, 0x80, 0x43, 0xE5,
- 0x85, 0x85, 0x43, 0xE5, 0x85, 0x8D, 0x43, 0xE5,
- 0x85, 0x94, 0x43, 0xE5, 0x85, 0xA4, 0x43, 0xE5,
- 0x85, 0xA5, 0x43, 0xE5, 0x85, 0xA7, 0x43, 0xE5,
- 0x85, 0xA8, 0x43, 0xE5, 0x85, 0xA9, 0x43, 0xE5,
- 0x85, 0xAB, 0x43, 0xE5, 0x85, 0xAD, 0x43, 0xE5,
- 0x85, 0xB7, 0x43, 0xE5, 0x86, 0x80, 0x43, 0xE5,
- // Bytes 7c0 - 7ff
- 0x86, 0x82, 0x43, 0xE5, 0x86, 0x8D, 0x43, 0xE5,
- 0x86, 0x92, 0x43, 0xE5, 0x86, 0x95, 0x43, 0xE5,
- 0x86, 0x96, 0x43, 0xE5, 0x86, 0x97, 0x43, 0xE5,
- 0x86, 0x99, 0x43, 0xE5, 0x86, 0xA4, 0x43, 0xE5,
- 0x86, 0xAB, 0x43, 0xE5, 0x86, 0xAC, 0x43, 0xE5,
- 0x86, 0xB5, 0x43, 0xE5, 0x86, 0xB7, 0x43, 0xE5,
- 0x87, 0x89, 0x43, 0xE5, 0x87, 0x8C, 0x43, 0xE5,
- 0x87, 0x9C, 0x43, 0xE5, 0x87, 0x9E, 0x43, 0xE5,
- // Bytes 800 - 83f
- 0x87, 0xA0, 0x43, 0xE5, 0x87, 0xB5, 0x43, 0xE5,
- 0x88, 0x80, 0x43, 0xE5, 0x88, 0x83, 0x43, 0xE5,
- 0x88, 0x87, 0x43, 0xE5, 0x88, 0x97, 0x43, 0xE5,
- 0x88, 0x9D, 0x43, 0xE5, 0x88, 0xA9, 0x43, 0xE5,
- 0x88, 0xBA, 0x43, 0xE5, 0x88, 0xBB, 0x43, 0xE5,
- 0x89, 0x86, 0x43, 0xE5, 0x89, 0x8D, 0x43, 0xE5,
- 0x89, 0xB2, 0x43, 0xE5, 0x89, 0xB7, 0x43, 0xE5,
- 0x8A, 0x89, 0x43, 0xE5, 0x8A, 0x9B, 0x43, 0xE5,
- // Bytes 840 - 87f
- 0x8A, 0xA3, 0x43, 0xE5, 0x8A, 0xB3, 0x43, 0xE5,
- 0x8A, 0xB4, 0x43, 0xE5, 0x8B, 0x87, 0x43, 0xE5,
- 0x8B, 0x89, 0x43, 0xE5, 0x8B, 0x92, 0x43, 0xE5,
- 0x8B, 0x9E, 0x43, 0xE5, 0x8B, 0xA4, 0x43, 0xE5,
- 0x8B, 0xB5, 0x43, 0xE5, 0x8B, 0xB9, 0x43, 0xE5,
- 0x8B, 0xBA, 0x43, 0xE5, 0x8C, 0x85, 0x43, 0xE5,
- 0x8C, 0x86, 0x43, 0xE5, 0x8C, 0x95, 0x43, 0xE5,
- 0x8C, 0x97, 0x43, 0xE5, 0x8C, 0x9A, 0x43, 0xE5,
- // Bytes 880 - 8bf
- 0x8C, 0xB8, 0x43, 0xE5, 0x8C, 0xBB, 0x43, 0xE5,
- 0x8C, 0xBF, 0x43, 0xE5, 0x8D, 0x81, 0x43, 0xE5,
- 0x8D, 0x84, 0x43, 0xE5, 0x8D, 0x85, 0x43, 0xE5,
- 0x8D, 0x89, 0x43, 0xE5, 0x8D, 0x91, 0x43, 0xE5,
- 0x8D, 0x94, 0x43, 0xE5, 0x8D, 0x9A, 0x43, 0xE5,
- 0x8D, 0x9C, 0x43, 0xE5, 0x8D, 0xA9, 0x43, 0xE5,
- 0x8D, 0xB0, 0x43, 0xE5, 0x8D, 0xB3, 0x43, 0xE5,
- 0x8D, 0xB5, 0x43, 0xE5, 0x8D, 0xBD, 0x43, 0xE5,
- // Bytes 8c0 - 8ff
- 0x8D, 0xBF, 0x43, 0xE5, 0x8E, 0x82, 0x43, 0xE5,
- 0x8E, 0xB6, 0x43, 0xE5, 0x8F, 0x83, 0x43, 0xE5,
- 0x8F, 0x88, 0x43, 0xE5, 0x8F, 0x8A, 0x43, 0xE5,
- 0x8F, 0x8C, 0x43, 0xE5, 0x8F, 0x9F, 0x43, 0xE5,
- 0x8F, 0xA3, 0x43, 0xE5, 0x8F, 0xA5, 0x43, 0xE5,
- 0x8F, 0xAB, 0x43, 0xE5, 0x8F, 0xAF, 0x43, 0xE5,
- 0x8F, 0xB1, 0x43, 0xE5, 0x8F, 0xB3, 0x43, 0xE5,
- 0x90, 0x86, 0x43, 0xE5, 0x90, 0x88, 0x43, 0xE5,
- // Bytes 900 - 93f
- 0x90, 0x8D, 0x43, 0xE5, 0x90, 0x8F, 0x43, 0xE5,
- 0x90, 0x9D, 0x43, 0xE5, 0x90, 0xB8, 0x43, 0xE5,
- 0x90, 0xB9, 0x43, 0xE5, 0x91, 0x82, 0x43, 0xE5,
- 0x91, 0x88, 0x43, 0xE5, 0x91, 0xA8, 0x43, 0xE5,
- 0x92, 0x9E, 0x43, 0xE5, 0x92, 0xA2, 0x43, 0xE5,
- 0x92, 0xBD, 0x43, 0xE5, 0x93, 0xB6, 0x43, 0xE5,
- 0x94, 0x90, 0x43, 0xE5, 0x95, 0x8F, 0x43, 0xE5,
- 0x95, 0x93, 0x43, 0xE5, 0x95, 0x95, 0x43, 0xE5,
- // Bytes 940 - 97f
- 0x95, 0xA3, 0x43, 0xE5, 0x96, 0x84, 0x43, 0xE5,
- 0x96, 0x87, 0x43, 0xE5, 0x96, 0x99, 0x43, 0xE5,
- 0x96, 0x9D, 0x43, 0xE5, 0x96, 0xAB, 0x43, 0xE5,
- 0x96, 0xB3, 0x43, 0xE5, 0x96, 0xB6, 0x43, 0xE5,
- 0x97, 0x80, 0x43, 0xE5, 0x97, 0x82, 0x43, 0xE5,
- 0x97, 0xA2, 0x43, 0xE5, 0x98, 0x86, 0x43, 0xE5,
- 0x99, 0x91, 0x43, 0xE5, 0x99, 0xA8, 0x43, 0xE5,
- 0x99, 0xB4, 0x43, 0xE5, 0x9B, 0x97, 0x43, 0xE5,
- // Bytes 980 - 9bf
- 0x9B, 0x9B, 0x43, 0xE5, 0x9B, 0xB9, 0x43, 0xE5,
- 0x9C, 0x96, 0x43, 0xE5, 0x9C, 0x97, 0x43, 0xE5,
- 0x9C, 0x9F, 0x43, 0xE5, 0x9C, 0xB0, 0x43, 0xE5,
- 0x9E, 0x8B, 0x43, 0xE5, 0x9F, 0x8E, 0x43, 0xE5,
- 0x9F, 0xB4, 0x43, 0xE5, 0xA0, 0x8D, 0x43, 0xE5,
- 0xA0, 0xB1, 0x43, 0xE5, 0xA0, 0xB2, 0x43, 0xE5,
- 0xA1, 0x80, 0x43, 0xE5, 0xA1, 0x9A, 0x43, 0xE5,
- 0xA1, 0x9E, 0x43, 0xE5, 0xA2, 0xA8, 0x43, 0xE5,
- // Bytes 9c0 - 9ff
- 0xA2, 0xAC, 0x43, 0xE5, 0xA2, 0xB3, 0x43, 0xE5,
- 0xA3, 0x98, 0x43, 0xE5, 0xA3, 0x9F, 0x43, 0xE5,
- 0xA3, 0xAB, 0x43, 0xE5, 0xA3, 0xAE, 0x43, 0xE5,
- 0xA3, 0xB0, 0x43, 0xE5, 0xA3, 0xB2, 0x43, 0xE5,
- 0xA3, 0xB7, 0x43, 0xE5, 0xA4, 0x82, 0x43, 0xE5,
- 0xA4, 0x86, 0x43, 0xE5, 0xA4, 0x8A, 0x43, 0xE5,
- 0xA4, 0x95, 0x43, 0xE5, 0xA4, 0x9A, 0x43, 0xE5,
- 0xA4, 0x9C, 0x43, 0xE5, 0xA4, 0xA2, 0x43, 0xE5,
- // Bytes a00 - a3f
- 0xA4, 0xA7, 0x43, 0xE5, 0xA4, 0xA9, 0x43, 0xE5,
- 0xA5, 0x84, 0x43, 0xE5, 0xA5, 0x88, 0x43, 0xE5,
- 0xA5, 0x91, 0x43, 0xE5, 0xA5, 0x94, 0x43, 0xE5,
- 0xA5, 0xA2, 0x43, 0xE5, 0xA5, 0xB3, 0x43, 0xE5,
- 0xA7, 0x98, 0x43, 0xE5, 0xA7, 0xAC, 0x43, 0xE5,
- 0xA8, 0x9B, 0x43, 0xE5, 0xA8, 0xA7, 0x43, 0xE5,
- 0xA9, 0xA2, 0x43, 0xE5, 0xA9, 0xA6, 0x43, 0xE5,
- 0xAA, 0xB5, 0x43, 0xE5, 0xAC, 0x88, 0x43, 0xE5,
- // Bytes a40 - a7f
- 0xAC, 0xA8, 0x43, 0xE5, 0xAC, 0xBE, 0x43, 0xE5,
- 0xAD, 0x90, 0x43, 0xE5, 0xAD, 0x97, 0x43, 0xE5,
- 0xAD, 0xA6, 0x43, 0xE5, 0xAE, 0x80, 0x43, 0xE5,
- 0xAE, 0x85, 0x43, 0xE5, 0xAE, 0x97, 0x43, 0xE5,
- 0xAF, 0x83, 0x43, 0xE5, 0xAF, 0x98, 0x43, 0xE5,
- 0xAF, 0xA7, 0x43, 0xE5, 0xAF, 0xAE, 0x43, 0xE5,
- 0xAF, 0xB3, 0x43, 0xE5, 0xAF, 0xB8, 0x43, 0xE5,
- 0xAF, 0xBF, 0x43, 0xE5, 0xB0, 0x86, 0x43, 0xE5,
- // Bytes a80 - abf
- 0xB0, 0x8F, 0x43, 0xE5, 0xB0, 0xA2, 0x43, 0xE5,
- 0xB0, 0xB8, 0x43, 0xE5, 0xB0, 0xBF, 0x43, 0xE5,
- 0xB1, 0xA0, 0x43, 0xE5, 0xB1, 0xA2, 0x43, 0xE5,
- 0xB1, 0xA4, 0x43, 0xE5, 0xB1, 0xA5, 0x43, 0xE5,
- 0xB1, 0xAE, 0x43, 0xE5, 0xB1, 0xB1, 0x43, 0xE5,
- 0xB2, 0x8D, 0x43, 0xE5, 0xB3, 0x80, 0x43, 0xE5,
- 0xB4, 0x99, 0x43, 0xE5, 0xB5, 0x83, 0x43, 0xE5,
- 0xB5, 0x90, 0x43, 0xE5, 0xB5, 0xAB, 0x43, 0xE5,
- // Bytes ac0 - aff
- 0xB5, 0xAE, 0x43, 0xE5, 0xB5, 0xBC, 0x43, 0xE5,
- 0xB6, 0xB2, 0x43, 0xE5, 0xB6, 0xBA, 0x43, 0xE5,
- 0xB7, 0x9B, 0x43, 0xE5, 0xB7, 0xA1, 0x43, 0xE5,
- 0xB7, 0xA2, 0x43, 0xE5, 0xB7, 0xA5, 0x43, 0xE5,
- 0xB7, 0xA6, 0x43, 0xE5, 0xB7, 0xB1, 0x43, 0xE5,
- 0xB7, 0xBD, 0x43, 0xE5, 0xB7, 0xBE, 0x43, 0xE5,
- 0xB8, 0xA8, 0x43, 0xE5, 0xB8, 0xBD, 0x43, 0xE5,
- 0xB9, 0xA9, 0x43, 0xE5, 0xB9, 0xB2, 0x43, 0xE5,
- // Bytes b00 - b3f
- 0xB9, 0xB4, 0x43, 0xE5, 0xB9, 0xBA, 0x43, 0xE5,
- 0xB9, 0xBC, 0x43, 0xE5, 0xB9, 0xBF, 0x43, 0xE5,
- 0xBA, 0xA6, 0x43, 0xE5, 0xBA, 0xB0, 0x43, 0xE5,
- 0xBA, 0xB3, 0x43, 0xE5, 0xBA, 0xB6, 0x43, 0xE5,
- 0xBB, 0x89, 0x43, 0xE5, 0xBB, 0x8A, 0x43, 0xE5,
- 0xBB, 0x92, 0x43, 0xE5, 0xBB, 0x93, 0x43, 0xE5,
- 0xBB, 0x99, 0x43, 0xE5, 0xBB, 0xAC, 0x43, 0xE5,
- 0xBB, 0xB4, 0x43, 0xE5, 0xBB, 0xBE, 0x43, 0xE5,
- // Bytes b40 - b7f
- 0xBC, 0x84, 0x43, 0xE5, 0xBC, 0x8B, 0x43, 0xE5,
- 0xBC, 0x93, 0x43, 0xE5, 0xBC, 0xA2, 0x43, 0xE5,
- 0xBD, 0x90, 0x43, 0xE5, 0xBD, 0x93, 0x43, 0xE5,
- 0xBD, 0xA1, 0x43, 0xE5, 0xBD, 0xA2, 0x43, 0xE5,
- 0xBD, 0xA9, 0x43, 0xE5, 0xBD, 0xAB, 0x43, 0xE5,
- 0xBD, 0xB3, 0x43, 0xE5, 0xBE, 0x8B, 0x43, 0xE5,
- 0xBE, 0x8C, 0x43, 0xE5, 0xBE, 0x97, 0x43, 0xE5,
- 0xBE, 0x9A, 0x43, 0xE5, 0xBE, 0xA9, 0x43, 0xE5,
- // Bytes b80 - bbf
- 0xBE, 0xAD, 0x43, 0xE5, 0xBF, 0x83, 0x43, 0xE5,
- 0xBF, 0x8D, 0x43, 0xE5, 0xBF, 0x97, 0x43, 0xE5,
- 0xBF, 0xB5, 0x43, 0xE5, 0xBF, 0xB9, 0x43, 0xE6,
- 0x80, 0x92, 0x43, 0xE6, 0x80, 0x9C, 0x43, 0xE6,
- 0x81, 0xB5, 0x43, 0xE6, 0x82, 0x81, 0x43, 0xE6,
- 0x82, 0x94, 0x43, 0xE6, 0x83, 0x87, 0x43, 0xE6,
- 0x83, 0x98, 0x43, 0xE6, 0x83, 0xA1, 0x43, 0xE6,
- 0x84, 0x88, 0x43, 0xE6, 0x85, 0x84, 0x43, 0xE6,
- // Bytes bc0 - bff
- 0x85, 0x88, 0x43, 0xE6, 0x85, 0x8C, 0x43, 0xE6,
- 0x85, 0x8E, 0x43, 0xE6, 0x85, 0xA0, 0x43, 0xE6,
- 0x85, 0xA8, 0x43, 0xE6, 0x85, 0xBA, 0x43, 0xE6,
- 0x86, 0x8E, 0x43, 0xE6, 0x86, 0x90, 0x43, 0xE6,
- 0x86, 0xA4, 0x43, 0xE6, 0x86, 0xAF, 0x43, 0xE6,
- 0x86, 0xB2, 0x43, 0xE6, 0x87, 0x9E, 0x43, 0xE6,
- 0x87, 0xB2, 0x43, 0xE6, 0x87, 0xB6, 0x43, 0xE6,
- 0x88, 0x80, 0x43, 0xE6, 0x88, 0x88, 0x43, 0xE6,
- // Bytes c00 - c3f
- 0x88, 0x90, 0x43, 0xE6, 0x88, 0x9B, 0x43, 0xE6,
- 0x88, 0xAE, 0x43, 0xE6, 0x88, 0xB4, 0x43, 0xE6,
- 0x88, 0xB6, 0x43, 0xE6, 0x89, 0x8B, 0x43, 0xE6,
- 0x89, 0x93, 0x43, 0xE6, 0x89, 0x9D, 0x43, 0xE6,
- 0x8A, 0x95, 0x43, 0xE6, 0x8A, 0xB1, 0x43, 0xE6,
- 0x8B, 0x89, 0x43, 0xE6, 0x8B, 0x8F, 0x43, 0xE6,
- 0x8B, 0x93, 0x43, 0xE6, 0x8B, 0x94, 0x43, 0xE6,
- 0x8B, 0xBC, 0x43, 0xE6, 0x8B, 0xBE, 0x43, 0xE6,
- // Bytes c40 - c7f
- 0x8C, 0x87, 0x43, 0xE6, 0x8C, 0xBD, 0x43, 0xE6,
- 0x8D, 0x90, 0x43, 0xE6, 0x8D, 0x95, 0x43, 0xE6,
- 0x8D, 0xA8, 0x43, 0xE6, 0x8D, 0xBB, 0x43, 0xE6,
- 0x8E, 0x83, 0x43, 0xE6, 0x8E, 0xA0, 0x43, 0xE6,
- 0x8E, 0xA9, 0x43, 0xE6, 0x8F, 0x84, 0x43, 0xE6,
- 0x8F, 0x85, 0x43, 0xE6, 0x8F, 0xA4, 0x43, 0xE6,
- 0x90, 0x9C, 0x43, 0xE6, 0x90, 0xA2, 0x43, 0xE6,
- 0x91, 0x92, 0x43, 0xE6, 0x91, 0xA9, 0x43, 0xE6,
- // Bytes c80 - cbf
- 0x91, 0xB7, 0x43, 0xE6, 0x91, 0xBE, 0x43, 0xE6,
- 0x92, 0x9A, 0x43, 0xE6, 0x92, 0x9D, 0x43, 0xE6,
- 0x93, 0x84, 0x43, 0xE6, 0x94, 0xAF, 0x43, 0xE6,
- 0x94, 0xB4, 0x43, 0xE6, 0x95, 0x8F, 0x43, 0xE6,
- 0x95, 0x96, 0x43, 0xE6, 0x95, 0xAC, 0x43, 0xE6,
- 0x95, 0xB8, 0x43, 0xE6, 0x96, 0x87, 0x43, 0xE6,
- 0x96, 0x97, 0x43, 0xE6, 0x96, 0x99, 0x43, 0xE6,
- 0x96, 0xA4, 0x43, 0xE6, 0x96, 0xB0, 0x43, 0xE6,
- // Bytes cc0 - cff
- 0x96, 0xB9, 0x43, 0xE6, 0x97, 0x85, 0x43, 0xE6,
- 0x97, 0xA0, 0x43, 0xE6, 0x97, 0xA2, 0x43, 0xE6,
- 0x97, 0xA3, 0x43, 0xE6, 0x97, 0xA5, 0x43, 0xE6,
- 0x98, 0x93, 0x43, 0xE6, 0x98, 0xA0, 0x43, 0xE6,
- 0x99, 0x89, 0x43, 0xE6, 0x99, 0xB4, 0x43, 0xE6,
- 0x9A, 0x88, 0x43, 0xE6, 0x9A, 0x91, 0x43, 0xE6,
- 0x9A, 0x9C, 0x43, 0xE6, 0x9A, 0xB4, 0x43, 0xE6,
- 0x9B, 0x86, 0x43, 0xE6, 0x9B, 0xB0, 0x43, 0xE6,
- // Bytes d00 - d3f
- 0x9B, 0xB4, 0x43, 0xE6, 0x9B, 0xB8, 0x43, 0xE6,
- 0x9C, 0x80, 0x43, 0xE6, 0x9C, 0x88, 0x43, 0xE6,
- 0x9C, 0x89, 0x43, 0xE6, 0x9C, 0x97, 0x43, 0xE6,
- 0x9C, 0x9B, 0x43, 0xE6, 0x9C, 0xA1, 0x43, 0xE6,
- 0x9C, 0xA8, 0x43, 0xE6, 0x9D, 0x8E, 0x43, 0xE6,
- 0x9D, 0x93, 0x43, 0xE6, 0x9D, 0x96, 0x43, 0xE6,
- 0x9D, 0x9E, 0x43, 0xE6, 0x9D, 0xBB, 0x43, 0xE6,
- 0x9E, 0x85, 0x43, 0xE6, 0x9E, 0x97, 0x43, 0xE6,
- // Bytes d40 - d7f
- 0x9F, 0xB3, 0x43, 0xE6, 0x9F, 0xBA, 0x43, 0xE6,
- 0xA0, 0x97, 0x43, 0xE6, 0xA0, 0x9F, 0x43, 0xE6,
- 0xA0, 0xAA, 0x43, 0xE6, 0xA1, 0x92, 0x43, 0xE6,
- 0xA2, 0x81, 0x43, 0xE6, 0xA2, 0x85, 0x43, 0xE6,
- 0xA2, 0x8E, 0x43, 0xE6, 0xA2, 0xA8, 0x43, 0xE6,
- 0xA4, 0x94, 0x43, 0xE6, 0xA5, 0x82, 0x43, 0xE6,
- 0xA6, 0xA3, 0x43, 0xE6, 0xA7, 0xAA, 0x43, 0xE6,
- 0xA8, 0x82, 0x43, 0xE6, 0xA8, 0x93, 0x43, 0xE6,
- // Bytes d80 - dbf
- 0xAA, 0xA8, 0x43, 0xE6, 0xAB, 0x93, 0x43, 0xE6,
- 0xAB, 0x9B, 0x43, 0xE6, 0xAC, 0x84, 0x43, 0xE6,
- 0xAC, 0xA0, 0x43, 0xE6, 0xAC, 0xA1, 0x43, 0xE6,
- 0xAD, 0x94, 0x43, 0xE6, 0xAD, 0xA2, 0x43, 0xE6,
- 0xAD, 0xA3, 0x43, 0xE6, 0xAD, 0xB2, 0x43, 0xE6,
- 0xAD, 0xB7, 0x43, 0xE6, 0xAD, 0xB9, 0x43, 0xE6,
- 0xAE, 0x9F, 0x43, 0xE6, 0xAE, 0xAE, 0x43, 0xE6,
- 0xAE, 0xB3, 0x43, 0xE6, 0xAE, 0xBA, 0x43, 0xE6,
- // Bytes dc0 - dff
- 0xAE, 0xBB, 0x43, 0xE6, 0xAF, 0x8B, 0x43, 0xE6,
- 0xAF, 0x8D, 0x43, 0xE6, 0xAF, 0x94, 0x43, 0xE6,
- 0xAF, 0x9B, 0x43, 0xE6, 0xB0, 0x8F, 0x43, 0xE6,
- 0xB0, 0x94, 0x43, 0xE6, 0xB0, 0xB4, 0x43, 0xE6,
- 0xB1, 0x8E, 0x43, 0xE6, 0xB1, 0xA7, 0x43, 0xE6,
- 0xB2, 0x88, 0x43, 0xE6, 0xB2, 0xBF, 0x43, 0xE6,
- 0xB3, 0x8C, 0x43, 0xE6, 0xB3, 0x8D, 0x43, 0xE6,
- 0xB3, 0xA5, 0x43, 0xE6, 0xB3, 0xA8, 0x43, 0xE6,
- // Bytes e00 - e3f
- 0xB4, 0x96, 0x43, 0xE6, 0xB4, 0x9B, 0x43, 0xE6,
- 0xB4, 0x9E, 0x43, 0xE6, 0xB4, 0xB4, 0x43, 0xE6,
- 0xB4, 0xBE, 0x43, 0xE6, 0xB5, 0x81, 0x43, 0xE6,
- 0xB5, 0xA9, 0x43, 0xE6, 0xB5, 0xAA, 0x43, 0xE6,
- 0xB5, 0xB7, 0x43, 0xE6, 0xB5, 0xB8, 0x43, 0xE6,
- 0xB6, 0x85, 0x43, 0xE6, 0xB7, 0x8B, 0x43, 0xE6,
- 0xB7, 0x9A, 0x43, 0xE6, 0xB7, 0xAA, 0x43, 0xE6,
- 0xB7, 0xB9, 0x43, 0xE6, 0xB8, 0x9A, 0x43, 0xE6,
- // Bytes e40 - e7f
- 0xB8, 0xAF, 0x43, 0xE6, 0xB9, 0xAE, 0x43, 0xE6,
- 0xBA, 0x80, 0x43, 0xE6, 0xBA, 0x9C, 0x43, 0xE6,
- 0xBA, 0xBA, 0x43, 0xE6, 0xBB, 0x87, 0x43, 0xE6,
- 0xBB, 0x8B, 0x43, 0xE6, 0xBB, 0x91, 0x43, 0xE6,
- 0xBB, 0x9B, 0x43, 0xE6, 0xBC, 0x8F, 0x43, 0xE6,
- 0xBC, 0x94, 0x43, 0xE6, 0xBC, 0xA2, 0x43, 0xE6,
- 0xBC, 0xA3, 0x43, 0xE6, 0xBD, 0xAE, 0x43, 0xE6,
- 0xBF, 0x86, 0x43, 0xE6, 0xBF, 0xAB, 0x43, 0xE6,
- // Bytes e80 - ebf
- 0xBF, 0xBE, 0x43, 0xE7, 0x80, 0x9B, 0x43, 0xE7,
- 0x80, 0x9E, 0x43, 0xE7, 0x80, 0xB9, 0x43, 0xE7,
- 0x81, 0x8A, 0x43, 0xE7, 0x81, 0xAB, 0x43, 0xE7,
- 0x81, 0xB0, 0x43, 0xE7, 0x81, 0xB7, 0x43, 0xE7,
- 0x81, 0xBD, 0x43, 0xE7, 0x82, 0x99, 0x43, 0xE7,
- 0x82, 0xAD, 0x43, 0xE7, 0x83, 0x88, 0x43, 0xE7,
- 0x83, 0x99, 0x43, 0xE7, 0x84, 0xA1, 0x43, 0xE7,
- 0x85, 0x85, 0x43, 0xE7, 0x85, 0x89, 0x43, 0xE7,
- // Bytes ec0 - eff
- 0x85, 0xAE, 0x43, 0xE7, 0x86, 0x9C, 0x43, 0xE7,
- 0x87, 0x8E, 0x43, 0xE7, 0x87, 0x90, 0x43, 0xE7,
- 0x88, 0x90, 0x43, 0xE7, 0x88, 0x9B, 0x43, 0xE7,
- 0x88, 0xA8, 0x43, 0xE7, 0x88, 0xAA, 0x43, 0xE7,
- 0x88, 0xAB, 0x43, 0xE7, 0x88, 0xB5, 0x43, 0xE7,
- 0x88, 0xB6, 0x43, 0xE7, 0x88, 0xBB, 0x43, 0xE7,
- 0x88, 0xBF, 0x43, 0xE7, 0x89, 0x87, 0x43, 0xE7,
- 0x89, 0x90, 0x43, 0xE7, 0x89, 0x99, 0x43, 0xE7,
- // Bytes f00 - f3f
- 0x89, 0x9B, 0x43, 0xE7, 0x89, 0xA2, 0x43, 0xE7,
- 0x89, 0xB9, 0x43, 0xE7, 0x8A, 0x80, 0x43, 0xE7,
- 0x8A, 0x95, 0x43, 0xE7, 0x8A, 0xAC, 0x43, 0xE7,
- 0x8A, 0xAF, 0x43, 0xE7, 0x8B, 0x80, 0x43, 0xE7,
- 0x8B, 0xBC, 0x43, 0xE7, 0x8C, 0xAA, 0x43, 0xE7,
- 0x8D, 0xB5, 0x43, 0xE7, 0x8D, 0xBA, 0x43, 0xE7,
- 0x8E, 0x84, 0x43, 0xE7, 0x8E, 0x87, 0x43, 0xE7,
- 0x8E, 0x89, 0x43, 0xE7, 0x8E, 0x8B, 0x43, 0xE7,
- // Bytes f40 - f7f
- 0x8E, 0xA5, 0x43, 0xE7, 0x8E, 0xB2, 0x43, 0xE7,
- 0x8F, 0x9E, 0x43, 0xE7, 0x90, 0x86, 0x43, 0xE7,
- 0x90, 0x89, 0x43, 0xE7, 0x90, 0xA2, 0x43, 0xE7,
- 0x91, 0x87, 0x43, 0xE7, 0x91, 0x9C, 0x43, 0xE7,
- 0x91, 0xA9, 0x43, 0xE7, 0x91, 0xB1, 0x43, 0xE7,
- 0x92, 0x85, 0x43, 0xE7, 0x92, 0x89, 0x43, 0xE7,
- 0x92, 0x98, 0x43, 0xE7, 0x93, 0x8A, 0x43, 0xE7,
- 0x93, 0x9C, 0x43, 0xE7, 0x93, 0xA6, 0x43, 0xE7,
- // Bytes f80 - fbf
- 0x94, 0x86, 0x43, 0xE7, 0x94, 0x98, 0x43, 0xE7,
- 0x94, 0x9F, 0x43, 0xE7, 0x94, 0xA4, 0x43, 0xE7,
- 0x94, 0xA8, 0x43, 0xE7, 0x94, 0xB0, 0x43, 0xE7,
- 0x94, 0xB2, 0x43, 0xE7, 0x94, 0xB3, 0x43, 0xE7,
- 0x94, 0xB7, 0x43, 0xE7, 0x94, 0xBB, 0x43, 0xE7,
- 0x94, 0xBE, 0x43, 0xE7, 0x95, 0x99, 0x43, 0xE7,
- 0x95, 0xA5, 0x43, 0xE7, 0x95, 0xB0, 0x43, 0xE7,
- 0x96, 0x8B, 0x43, 0xE7, 0x96, 0x92, 0x43, 0xE7,
- // Bytes fc0 - fff
- 0x97, 0xA2, 0x43, 0xE7, 0x98, 0x90, 0x43, 0xE7,
- 0x98, 0x9D, 0x43, 0xE7, 0x98, 0x9F, 0x43, 0xE7,
- 0x99, 0x82, 0x43, 0xE7, 0x99, 0xA9, 0x43, 0xE7,
- 0x99, 0xB6, 0x43, 0xE7, 0x99, 0xBD, 0x43, 0xE7,
- 0x9A, 0xAE, 0x43, 0xE7, 0x9A, 0xBF, 0x43, 0xE7,
- 0x9B, 0x8A, 0x43, 0xE7, 0x9B, 0x9B, 0x43, 0xE7,
- 0x9B, 0xA3, 0x43, 0xE7, 0x9B, 0xA7, 0x43, 0xE7,
- 0x9B, 0xAE, 0x43, 0xE7, 0x9B, 0xB4, 0x43, 0xE7,
- // Bytes 1000 - 103f
- 0x9C, 0x81, 0x43, 0xE7, 0x9C, 0x9E, 0x43, 0xE7,
- 0x9C, 0x9F, 0x43, 0xE7, 0x9D, 0x80, 0x43, 0xE7,
- 0x9D, 0x8A, 0x43, 0xE7, 0x9E, 0x8B, 0x43, 0xE7,
- 0x9E, 0xA7, 0x43, 0xE7, 0x9F, 0x9B, 0x43, 0xE7,
- 0x9F, 0xA2, 0x43, 0xE7, 0x9F, 0xB3, 0x43, 0xE7,
- 0xA1, 0x8E, 0x43, 0xE7, 0xA1, 0xAB, 0x43, 0xE7,
- 0xA2, 0x8C, 0x43, 0xE7, 0xA2, 0x91, 0x43, 0xE7,
- 0xA3, 0x8A, 0x43, 0xE7, 0xA3, 0x8C, 0x43, 0xE7,
- // Bytes 1040 - 107f
- 0xA3, 0xBB, 0x43, 0xE7, 0xA4, 0xAA, 0x43, 0xE7,
- 0xA4, 0xBA, 0x43, 0xE7, 0xA4, 0xBC, 0x43, 0xE7,
- 0xA4, 0xBE, 0x43, 0xE7, 0xA5, 0x88, 0x43, 0xE7,
- 0xA5, 0x89, 0x43, 0xE7, 0xA5, 0x90, 0x43, 0xE7,
- 0xA5, 0x96, 0x43, 0xE7, 0xA5, 0x9D, 0x43, 0xE7,
- 0xA5, 0x9E, 0x43, 0xE7, 0xA5, 0xA5, 0x43, 0xE7,
- 0xA5, 0xBF, 0x43, 0xE7, 0xA6, 0x81, 0x43, 0xE7,
- 0xA6, 0x8D, 0x43, 0xE7, 0xA6, 0x8E, 0x43, 0xE7,
- // Bytes 1080 - 10bf
- 0xA6, 0x8F, 0x43, 0xE7, 0xA6, 0xAE, 0x43, 0xE7,
- 0xA6, 0xB8, 0x43, 0xE7, 0xA6, 0xBE, 0x43, 0xE7,
- 0xA7, 0x8A, 0x43, 0xE7, 0xA7, 0x98, 0x43, 0xE7,
- 0xA7, 0xAB, 0x43, 0xE7, 0xA8, 0x9C, 0x43, 0xE7,
- 0xA9, 0x80, 0x43, 0xE7, 0xA9, 0x8A, 0x43, 0xE7,
- 0xA9, 0x8F, 0x43, 0xE7, 0xA9, 0xB4, 0x43, 0xE7,
- 0xA9, 0xBA, 0x43, 0xE7, 0xAA, 0x81, 0x43, 0xE7,
- 0xAA, 0xB1, 0x43, 0xE7, 0xAB, 0x8B, 0x43, 0xE7,
- // Bytes 10c0 - 10ff
- 0xAB, 0xAE, 0x43, 0xE7, 0xAB, 0xB9, 0x43, 0xE7,
- 0xAC, 0xA0, 0x43, 0xE7, 0xAE, 0x8F, 0x43, 0xE7,
- 0xAF, 0x80, 0x43, 0xE7, 0xAF, 0x86, 0x43, 0xE7,
- 0xAF, 0x89, 0x43, 0xE7, 0xB0, 0xBE, 0x43, 0xE7,
- 0xB1, 0xA0, 0x43, 0xE7, 0xB1, 0xB3, 0x43, 0xE7,
- 0xB1, 0xBB, 0x43, 0xE7, 0xB2, 0x92, 0x43, 0xE7,
- 0xB2, 0xBE, 0x43, 0xE7, 0xB3, 0x92, 0x43, 0xE7,
- 0xB3, 0x96, 0x43, 0xE7, 0xB3, 0xA3, 0x43, 0xE7,
- // Bytes 1100 - 113f
- 0xB3, 0xA7, 0x43, 0xE7, 0xB3, 0xA8, 0x43, 0xE7,
- 0xB3, 0xB8, 0x43, 0xE7, 0xB4, 0x80, 0x43, 0xE7,
- 0xB4, 0x90, 0x43, 0xE7, 0xB4, 0xA2, 0x43, 0xE7,
- 0xB4, 0xAF, 0x43, 0xE7, 0xB5, 0x82, 0x43, 0xE7,
- 0xB5, 0x9B, 0x43, 0xE7, 0xB5, 0xA3, 0x43, 0xE7,
- 0xB6, 0xA0, 0x43, 0xE7, 0xB6, 0xBE, 0x43, 0xE7,
- 0xB7, 0x87, 0x43, 0xE7, 0xB7, 0xB4, 0x43, 0xE7,
- 0xB8, 0x82, 0x43, 0xE7, 0xB8, 0x89, 0x43, 0xE7,
- // Bytes 1140 - 117f
- 0xB8, 0xB7, 0x43, 0xE7, 0xB9, 0x81, 0x43, 0xE7,
- 0xB9, 0x85, 0x43, 0xE7, 0xBC, 0xB6, 0x43, 0xE7,
- 0xBC, 0xBE, 0x43, 0xE7, 0xBD, 0x91, 0x43, 0xE7,
- 0xBD, 0xB2, 0x43, 0xE7, 0xBD, 0xB9, 0x43, 0xE7,
- 0xBD, 0xBA, 0x43, 0xE7, 0xBE, 0x85, 0x43, 0xE7,
- 0xBE, 0x8A, 0x43, 0xE7, 0xBE, 0x95, 0x43, 0xE7,
- 0xBE, 0x9A, 0x43, 0xE7, 0xBE, 0xBD, 0x43, 0xE7,
- 0xBF, 0xBA, 0x43, 0xE8, 0x80, 0x81, 0x43, 0xE8,
- // Bytes 1180 - 11bf
- 0x80, 0x85, 0x43, 0xE8, 0x80, 0x8C, 0x43, 0xE8,
- 0x80, 0x92, 0x43, 0xE8, 0x80, 0xB3, 0x43, 0xE8,
- 0x81, 0x86, 0x43, 0xE8, 0x81, 0xA0, 0x43, 0xE8,
- 0x81, 0xAF, 0x43, 0xE8, 0x81, 0xB0, 0x43, 0xE8,
- 0x81, 0xBE, 0x43, 0xE8, 0x81, 0xBF, 0x43, 0xE8,
- 0x82, 0x89, 0x43, 0xE8, 0x82, 0x8B, 0x43, 0xE8,
- 0x82, 0xAD, 0x43, 0xE8, 0x82, 0xB2, 0x43, 0xE8,
- 0x84, 0x83, 0x43, 0xE8, 0x84, 0xBE, 0x43, 0xE8,
- // Bytes 11c0 - 11ff
- 0x87, 0x98, 0x43, 0xE8, 0x87, 0xA3, 0x43, 0xE8,
- 0x87, 0xA8, 0x43, 0xE8, 0x87, 0xAA, 0x43, 0xE8,
- 0x87, 0xAD, 0x43, 0xE8, 0x87, 0xB3, 0x43, 0xE8,
- 0x87, 0xBC, 0x43, 0xE8, 0x88, 0x81, 0x43, 0xE8,
- 0x88, 0x84, 0x43, 0xE8, 0x88, 0x8C, 0x43, 0xE8,
- 0x88, 0x98, 0x43, 0xE8, 0x88, 0x9B, 0x43, 0xE8,
- 0x88, 0x9F, 0x43, 0xE8, 0x89, 0xAE, 0x43, 0xE8,
- 0x89, 0xAF, 0x43, 0xE8, 0x89, 0xB2, 0x43, 0xE8,
- // Bytes 1200 - 123f
- 0x89, 0xB8, 0x43, 0xE8, 0x89, 0xB9, 0x43, 0xE8,
- 0x8A, 0x8B, 0x43, 0xE8, 0x8A, 0x91, 0x43, 0xE8,
- 0x8A, 0x9D, 0x43, 0xE8, 0x8A, 0xB1, 0x43, 0xE8,
- 0x8A, 0xB3, 0x43, 0xE8, 0x8A, 0xBD, 0x43, 0xE8,
- 0x8B, 0xA5, 0x43, 0xE8, 0x8B, 0xA6, 0x43, 0xE8,
- 0x8C, 0x9D, 0x43, 0xE8, 0x8C, 0xA3, 0x43, 0xE8,
- 0x8C, 0xB6, 0x43, 0xE8, 0x8D, 0x92, 0x43, 0xE8,
- 0x8D, 0x93, 0x43, 0xE8, 0x8D, 0xA3, 0x43, 0xE8,
- // Bytes 1240 - 127f
- 0x8E, 0xAD, 0x43, 0xE8, 0x8E, 0xBD, 0x43, 0xE8,
- 0x8F, 0x89, 0x43, 0xE8, 0x8F, 0x8A, 0x43, 0xE8,
- 0x8F, 0x8C, 0x43, 0xE8, 0x8F, 0x9C, 0x43, 0xE8,
- 0x8F, 0xA7, 0x43, 0xE8, 0x8F, 0xAF, 0x43, 0xE8,
- 0x8F, 0xB1, 0x43, 0xE8, 0x90, 0xBD, 0x43, 0xE8,
- 0x91, 0x89, 0x43, 0xE8, 0x91, 0x97, 0x43, 0xE8,
- 0x93, 0xAE, 0x43, 0xE8, 0x93, 0xB1, 0x43, 0xE8,
- 0x93, 0xB3, 0x43, 0xE8, 0x93, 0xBC, 0x43, 0xE8,
- // Bytes 1280 - 12bf
- 0x94, 0x96, 0x43, 0xE8, 0x95, 0xA4, 0x43, 0xE8,
- 0x97, 0x8D, 0x43, 0xE8, 0x97, 0xBA, 0x43, 0xE8,
- 0x98, 0x86, 0x43, 0xE8, 0x98, 0x92, 0x43, 0xE8,
- 0x98, 0xAD, 0x43, 0xE8, 0x98, 0xBF, 0x43, 0xE8,
- 0x99, 0x8D, 0x43, 0xE8, 0x99, 0x90, 0x43, 0xE8,
- 0x99, 0x9C, 0x43, 0xE8, 0x99, 0xA7, 0x43, 0xE8,
- 0x99, 0xA9, 0x43, 0xE8, 0x99, 0xAB, 0x43, 0xE8,
- 0x9A, 0x88, 0x43, 0xE8, 0x9A, 0xA9, 0x43, 0xE8,
- // Bytes 12c0 - 12ff
- 0x9B, 0xA2, 0x43, 0xE8, 0x9C, 0x8E, 0x43, 0xE8,
- 0x9C, 0xA8, 0x43, 0xE8, 0x9D, 0xAB, 0x43, 0xE8,
- 0x9D, 0xB9, 0x43, 0xE8, 0x9E, 0x86, 0x43, 0xE8,
- 0x9E, 0xBA, 0x43, 0xE8, 0x9F, 0xA1, 0x43, 0xE8,
- 0xA0, 0x81, 0x43, 0xE8, 0xA0, 0x9F, 0x43, 0xE8,
- 0xA1, 0x80, 0x43, 0xE8, 0xA1, 0x8C, 0x43, 0xE8,
- 0xA1, 0xA0, 0x43, 0xE8, 0xA1, 0xA3, 0x43, 0xE8,
- 0xA3, 0x82, 0x43, 0xE8, 0xA3, 0x8F, 0x43, 0xE8,
- // Bytes 1300 - 133f
- 0xA3, 0x97, 0x43, 0xE8, 0xA3, 0x9E, 0x43, 0xE8,
- 0xA3, 0xA1, 0x43, 0xE8, 0xA3, 0xB8, 0x43, 0xE8,
- 0xA3, 0xBA, 0x43, 0xE8, 0xA4, 0x90, 0x43, 0xE8,
- 0xA5, 0x81, 0x43, 0xE8, 0xA5, 0xA4, 0x43, 0xE8,
- 0xA5, 0xBE, 0x43, 0xE8, 0xA6, 0x86, 0x43, 0xE8,
- 0xA6, 0x8B, 0x43, 0xE8, 0xA6, 0x96, 0x43, 0xE8,
- 0xA7, 0x92, 0x43, 0xE8, 0xA7, 0xA3, 0x43, 0xE8,
- 0xA8, 0x80, 0x43, 0xE8, 0xAA, 0xA0, 0x43, 0xE8,
- // Bytes 1340 - 137f
- 0xAA, 0xAA, 0x43, 0xE8, 0xAA, 0xBF, 0x43, 0xE8,
- 0xAB, 0x8B, 0x43, 0xE8, 0xAB, 0x92, 0x43, 0xE8,
- 0xAB, 0x96, 0x43, 0xE8, 0xAB, 0xAD, 0x43, 0xE8,
- 0xAB, 0xB8, 0x43, 0xE8, 0xAB, 0xBE, 0x43, 0xE8,
- 0xAC, 0x81, 0x43, 0xE8, 0xAC, 0xB9, 0x43, 0xE8,
- 0xAD, 0x98, 0x43, 0xE8, 0xAE, 0x80, 0x43, 0xE8,
- 0xAE, 0x8A, 0x43, 0xE8, 0xB0, 0xB7, 0x43, 0xE8,
- 0xB1, 0x86, 0x43, 0xE8, 0xB1, 0x88, 0x43, 0xE8,
- // Bytes 1380 - 13bf
- 0xB1, 0x95, 0x43, 0xE8, 0xB1, 0xB8, 0x43, 0xE8,
- 0xB2, 0x9D, 0x43, 0xE8, 0xB2, 0xA1, 0x43, 0xE8,
- 0xB2, 0xA9, 0x43, 0xE8, 0xB2, 0xAB, 0x43, 0xE8,
- 0xB3, 0x81, 0x43, 0xE8, 0xB3, 0x82, 0x43, 0xE8,
- 0xB3, 0x87, 0x43, 0xE8, 0xB3, 0x88, 0x43, 0xE8,
- 0xB3, 0x93, 0x43, 0xE8, 0xB4, 0x88, 0x43, 0xE8,
- 0xB4, 0x9B, 0x43, 0xE8, 0xB5, 0xA4, 0x43, 0xE8,
- 0xB5, 0xB0, 0x43, 0xE8, 0xB5, 0xB7, 0x43, 0xE8,
- // Bytes 13c0 - 13ff
- 0xB6, 0xB3, 0x43, 0xE8, 0xB6, 0xBC, 0x43, 0xE8,
- 0xB7, 0x8B, 0x43, 0xE8, 0xB7, 0xAF, 0x43, 0xE8,
- 0xB7, 0xB0, 0x43, 0xE8, 0xBA, 0xAB, 0x43, 0xE8,
- 0xBB, 0x8A, 0x43, 0xE8, 0xBB, 0x94, 0x43, 0xE8,
- 0xBC, 0xA6, 0x43, 0xE8, 0xBC, 0xAA, 0x43, 0xE8,
- 0xBC, 0xB8, 0x43, 0xE8, 0xBC, 0xBB, 0x43, 0xE8,
- 0xBD, 0xA2, 0x43, 0xE8, 0xBE, 0x9B, 0x43, 0xE8,
- 0xBE, 0x9E, 0x43, 0xE8, 0xBE, 0xB0, 0x43, 0xE8,
- // Bytes 1400 - 143f
- 0xBE, 0xB5, 0x43, 0xE8, 0xBE, 0xB6, 0x43, 0xE9,
- 0x80, 0xA3, 0x43, 0xE9, 0x80, 0xB8, 0x43, 0xE9,
- 0x81, 0x8A, 0x43, 0xE9, 0x81, 0xA9, 0x43, 0xE9,
- 0x81, 0xB2, 0x43, 0xE9, 0x81, 0xBC, 0x43, 0xE9,
- 0x82, 0x8F, 0x43, 0xE9, 0x82, 0x91, 0x43, 0xE9,
- 0x82, 0x94, 0x43, 0xE9, 0x83, 0x8E, 0x43, 0xE9,
- 0x83, 0x9E, 0x43, 0xE9, 0x83, 0xB1, 0x43, 0xE9,
- 0x83, 0xBD, 0x43, 0xE9, 0x84, 0x91, 0x43, 0xE9,
- // Bytes 1440 - 147f
- 0x84, 0x9B, 0x43, 0xE9, 0x85, 0x89, 0x43, 0xE9,
- 0x85, 0x8D, 0x43, 0xE9, 0x85, 0xAA, 0x43, 0xE9,
- 0x86, 0x99, 0x43, 0xE9, 0x86, 0xB4, 0x43, 0xE9,
- 0x87, 0x86, 0x43, 0xE9, 0x87, 0x8C, 0x43, 0xE9,
- 0x87, 0x8F, 0x43, 0xE9, 0x87, 0x91, 0x43, 0xE9,
- 0x88, 0xB4, 0x43, 0xE9, 0x88, 0xB8, 0x43, 0xE9,
- 0x89, 0xB6, 0x43, 0xE9, 0x89, 0xBC, 0x43, 0xE9,
- 0x8B, 0x97, 0x43, 0xE9, 0x8B, 0x98, 0x43, 0xE9,
- // Bytes 1480 - 14bf
- 0x8C, 0x84, 0x43, 0xE9, 0x8D, 0x8A, 0x43, 0xE9,
- 0x8F, 0xB9, 0x43, 0xE9, 0x90, 0x95, 0x43, 0xE9,
- 0x95, 0xB7, 0x43, 0xE9, 0x96, 0x80, 0x43, 0xE9,
- 0x96, 0x8B, 0x43, 0xE9, 0x96, 0xAD, 0x43, 0xE9,
- 0x96, 0xB7, 0x43, 0xE9, 0x98, 0x9C, 0x43, 0xE9,
- 0x98, 0xAE, 0x43, 0xE9, 0x99, 0x8B, 0x43, 0xE9,
- 0x99, 0x8D, 0x43, 0xE9, 0x99, 0xB5, 0x43, 0xE9,
- 0x99, 0xB8, 0x43, 0xE9, 0x99, 0xBC, 0x43, 0xE9,
- // Bytes 14c0 - 14ff
- 0x9A, 0x86, 0x43, 0xE9, 0x9A, 0xA3, 0x43, 0xE9,
- 0x9A, 0xB6, 0x43, 0xE9, 0x9A, 0xB7, 0x43, 0xE9,
- 0x9A, 0xB8, 0x43, 0xE9, 0x9A, 0xB9, 0x43, 0xE9,
- 0x9B, 0x83, 0x43, 0xE9, 0x9B, 0xA2, 0x43, 0xE9,
- 0x9B, 0xA3, 0x43, 0xE9, 0x9B, 0xA8, 0x43, 0xE9,
- 0x9B, 0xB6, 0x43, 0xE9, 0x9B, 0xB7, 0x43, 0xE9,
- 0x9C, 0xA3, 0x43, 0xE9, 0x9C, 0xB2, 0x43, 0xE9,
- 0x9D, 0x88, 0x43, 0xE9, 0x9D, 0x91, 0x43, 0xE9,
- // Bytes 1500 - 153f
- 0x9D, 0x96, 0x43, 0xE9, 0x9D, 0x9E, 0x43, 0xE9,
- 0x9D, 0xA2, 0x43, 0xE9, 0x9D, 0xA9, 0x43, 0xE9,
- 0x9F, 0x8B, 0x43, 0xE9, 0x9F, 0x9B, 0x43, 0xE9,
- 0x9F, 0xA0, 0x43, 0xE9, 0x9F, 0xAD, 0x43, 0xE9,
- 0x9F, 0xB3, 0x43, 0xE9, 0x9F, 0xBF, 0x43, 0xE9,
- 0xA0, 0x81, 0x43, 0xE9, 0xA0, 0x85, 0x43, 0xE9,
- 0xA0, 0x8B, 0x43, 0xE9, 0xA0, 0x98, 0x43, 0xE9,
- 0xA0, 0xA9, 0x43, 0xE9, 0xA0, 0xBB, 0x43, 0xE9,
- // Bytes 1540 - 157f
- 0xA1, 0x9E, 0x43, 0xE9, 0xA2, 0xA8, 0x43, 0xE9,
- 0xA3, 0x9B, 0x43, 0xE9, 0xA3, 0x9F, 0x43, 0xE9,
- 0xA3, 0xA2, 0x43, 0xE9, 0xA3, 0xAF, 0x43, 0xE9,
- 0xA3, 0xBC, 0x43, 0xE9, 0xA4, 0xA8, 0x43, 0xE9,
- 0xA4, 0xA9, 0x43, 0xE9, 0xA6, 0x96, 0x43, 0xE9,
- 0xA6, 0x99, 0x43, 0xE9, 0xA6, 0xA7, 0x43, 0xE9,
- 0xA6, 0xAC, 0x43, 0xE9, 0xA7, 0x82, 0x43, 0xE9,
- 0xA7, 0xB1, 0x43, 0xE9, 0xA7, 0xBE, 0x43, 0xE9,
- // Bytes 1580 - 15bf
- 0xA9, 0xAA, 0x43, 0xE9, 0xAA, 0xA8, 0x43, 0xE9,
- 0xAB, 0x98, 0x43, 0xE9, 0xAB, 0x9F, 0x43, 0xE9,
- 0xAC, 0x92, 0x43, 0xE9, 0xAC, 0xA5, 0x43, 0xE9,
- 0xAC, 0xAF, 0x43, 0xE9, 0xAC, 0xB2, 0x43, 0xE9,
- 0xAC, 0xBC, 0x43, 0xE9, 0xAD, 0x9A, 0x43, 0xE9,
- 0xAD, 0xAF, 0x43, 0xE9, 0xB1, 0x80, 0x43, 0xE9,
- 0xB1, 0x97, 0x43, 0xE9, 0xB3, 0xA5, 0x43, 0xE9,
- 0xB3, 0xBD, 0x43, 0xE9, 0xB5, 0xA7, 0x43, 0xE9,
- // Bytes 15c0 - 15ff
- 0xB6, 0xB4, 0x43, 0xE9, 0xB7, 0xBA, 0x43, 0xE9,
- 0xB8, 0x9E, 0x43, 0xE9, 0xB9, 0xB5, 0x43, 0xE9,
- 0xB9, 0xBF, 0x43, 0xE9, 0xBA, 0x97, 0x43, 0xE9,
- 0xBA, 0x9F, 0x43, 0xE9, 0xBA, 0xA5, 0x43, 0xE9,
- 0xBA, 0xBB, 0x43, 0xE9, 0xBB, 0x83, 0x43, 0xE9,
- 0xBB, 0x8D, 0x43, 0xE9, 0xBB, 0x8E, 0x43, 0xE9,
- 0xBB, 0x91, 0x43, 0xE9, 0xBB, 0xB9, 0x43, 0xE9,
- 0xBB, 0xBD, 0x43, 0xE9, 0xBB, 0xBE, 0x43, 0xE9,
- // Bytes 1600 - 163f
- 0xBC, 0x85, 0x43, 0xE9, 0xBC, 0x8E, 0x43, 0xE9,
- 0xBC, 0x8F, 0x43, 0xE9, 0xBC, 0x93, 0x43, 0xE9,
- 0xBC, 0x96, 0x43, 0xE9, 0xBC, 0xA0, 0x43, 0xE9,
- 0xBC, 0xBB, 0x43, 0xE9, 0xBD, 0x83, 0x43, 0xE9,
- 0xBD, 0x8A, 0x43, 0xE9, 0xBD, 0x92, 0x43, 0xE9,
- 0xBE, 0x8D, 0x43, 0xE9, 0xBE, 0x8E, 0x43, 0xE9,
- 0xBE, 0x9C, 0x43, 0xE9, 0xBE, 0x9F, 0x43, 0xE9,
- 0xBE, 0xA0, 0x43, 0xEA, 0x9C, 0xA7, 0x43, 0xEA,
- // Bytes 1640 - 167f
- 0x9D, 0xAF, 0x43, 0xEA, 0xAC, 0xB7, 0x43, 0xEA,
- 0xAD, 0x92, 0x44, 0xF0, 0xA0, 0x84, 0xA2, 0x44,
- 0xF0, 0xA0, 0x94, 0x9C, 0x44, 0xF0, 0xA0, 0x94,
- 0xA5, 0x44, 0xF0, 0xA0, 0x95, 0x8B, 0x44, 0xF0,
- 0xA0, 0x98, 0xBA, 0x44, 0xF0, 0xA0, 0xA0, 0x84,
- 0x44, 0xF0, 0xA0, 0xA3, 0x9E, 0x44, 0xF0, 0xA0,
- 0xA8, 0xAC, 0x44, 0xF0, 0xA0, 0xAD, 0xA3, 0x44,
- 0xF0, 0xA1, 0x93, 0xA4, 0x44, 0xF0, 0xA1, 0x9A,
- // Bytes 1680 - 16bf
- 0xA8, 0x44, 0xF0, 0xA1, 0x9B, 0xAA, 0x44, 0xF0,
- 0xA1, 0xA7, 0x88, 0x44, 0xF0, 0xA1, 0xAC, 0x98,
- 0x44, 0xF0, 0xA1, 0xB4, 0x8B, 0x44, 0xF0, 0xA1,
- 0xB7, 0xA4, 0x44, 0xF0, 0xA1, 0xB7, 0xA6, 0x44,
- 0xF0, 0xA2, 0x86, 0x83, 0x44, 0xF0, 0xA2, 0x86,
- 0x9F, 0x44, 0xF0, 0xA2, 0x8C, 0xB1, 0x44, 0xF0,
- 0xA2, 0x9B, 0x94, 0x44, 0xF0, 0xA2, 0xA1, 0x84,
- 0x44, 0xF0, 0xA2, 0xA1, 0x8A, 0x44, 0xF0, 0xA2,
- // Bytes 16c0 - 16ff
- 0xAC, 0x8C, 0x44, 0xF0, 0xA2, 0xAF, 0xB1, 0x44,
- 0xF0, 0xA3, 0x80, 0x8A, 0x44, 0xF0, 0xA3, 0x8A,
- 0xB8, 0x44, 0xF0, 0xA3, 0x8D, 0x9F, 0x44, 0xF0,
- 0xA3, 0x8E, 0x93, 0x44, 0xF0, 0xA3, 0x8E, 0x9C,
- 0x44, 0xF0, 0xA3, 0x8F, 0x83, 0x44, 0xF0, 0xA3,
- 0x8F, 0x95, 0x44, 0xF0, 0xA3, 0x91, 0xAD, 0x44,
- 0xF0, 0xA3, 0x9A, 0xA3, 0x44, 0xF0, 0xA3, 0xA2,
- 0xA7, 0x44, 0xF0, 0xA3, 0xAA, 0x8D, 0x44, 0xF0,
- // Bytes 1700 - 173f
- 0xA3, 0xAB, 0xBA, 0x44, 0xF0, 0xA3, 0xB2, 0xBC,
- 0x44, 0xF0, 0xA3, 0xB4, 0x9E, 0x44, 0xF0, 0xA3,
- 0xBB, 0x91, 0x44, 0xF0, 0xA3, 0xBD, 0x9E, 0x44,
- 0xF0, 0xA3, 0xBE, 0x8E, 0x44, 0xF0, 0xA4, 0x89,
- 0xA3, 0x44, 0xF0, 0xA4, 0x8B, 0xAE, 0x44, 0xF0,
- 0xA4, 0x8E, 0xAB, 0x44, 0xF0, 0xA4, 0x98, 0x88,
- 0x44, 0xF0, 0xA4, 0x9C, 0xB5, 0x44, 0xF0, 0xA4,
- 0xA0, 0x94, 0x44, 0xF0, 0xA4, 0xB0, 0xB6, 0x44,
- // Bytes 1740 - 177f
- 0xF0, 0xA4, 0xB2, 0x92, 0x44, 0xF0, 0xA4, 0xBE,
- 0xA1, 0x44, 0xF0, 0xA4, 0xBE, 0xB8, 0x44, 0xF0,
- 0xA5, 0x81, 0x84, 0x44, 0xF0, 0xA5, 0x83, 0xB2,
- 0x44, 0xF0, 0xA5, 0x83, 0xB3, 0x44, 0xF0, 0xA5,
- 0x84, 0x99, 0x44, 0xF0, 0xA5, 0x84, 0xB3, 0x44,
- 0xF0, 0xA5, 0x89, 0x89, 0x44, 0xF0, 0xA5, 0x90,
- 0x9D, 0x44, 0xF0, 0xA5, 0x98, 0xA6, 0x44, 0xF0,
- 0xA5, 0x9A, 0x9A, 0x44, 0xF0, 0xA5, 0x9B, 0x85,
- // Bytes 1780 - 17bf
- 0x44, 0xF0, 0xA5, 0xA5, 0xBC, 0x44, 0xF0, 0xA5,
- 0xAA, 0xA7, 0x44, 0xF0, 0xA5, 0xAE, 0xAB, 0x44,
- 0xF0, 0xA5, 0xB2, 0x80, 0x44, 0xF0, 0xA5, 0xB3,
- 0x90, 0x44, 0xF0, 0xA5, 0xBE, 0x86, 0x44, 0xF0,
- 0xA6, 0x87, 0x9A, 0x44, 0xF0, 0xA6, 0x88, 0xA8,
- 0x44, 0xF0, 0xA6, 0x89, 0x87, 0x44, 0xF0, 0xA6,
- 0x8B, 0x99, 0x44, 0xF0, 0xA6, 0x8C, 0xBE, 0x44,
- 0xF0, 0xA6, 0x93, 0x9A, 0x44, 0xF0, 0xA6, 0x94,
- // Bytes 17c0 - 17ff
- 0xA3, 0x44, 0xF0, 0xA6, 0x96, 0xA8, 0x44, 0xF0,
- 0xA6, 0x9E, 0xA7, 0x44, 0xF0, 0xA6, 0x9E, 0xB5,
- 0x44, 0xF0, 0xA6, 0xAC, 0xBC, 0x44, 0xF0, 0xA6,
- 0xB0, 0xB6, 0x44, 0xF0, 0xA6, 0xB3, 0x95, 0x44,
- 0xF0, 0xA6, 0xB5, 0xAB, 0x44, 0xF0, 0xA6, 0xBC,
- 0xAC, 0x44, 0xF0, 0xA6, 0xBE, 0xB1, 0x44, 0xF0,
- 0xA7, 0x83, 0x92, 0x44, 0xF0, 0xA7, 0x8F, 0x8A,
- 0x44, 0xF0, 0xA7, 0x99, 0xA7, 0x44, 0xF0, 0xA7,
- // Bytes 1800 - 183f
- 0xA2, 0xAE, 0x44, 0xF0, 0xA7, 0xA5, 0xA6, 0x44,
- 0xF0, 0xA7, 0xB2, 0xA8, 0x44, 0xF0, 0xA7, 0xBB,
- 0x93, 0x44, 0xF0, 0xA7, 0xBC, 0xAF, 0x44, 0xF0,
- 0xA8, 0x97, 0x92, 0x44, 0xF0, 0xA8, 0x97, 0xAD,
- 0x44, 0xF0, 0xA8, 0x9C, 0xAE, 0x44, 0xF0, 0xA8,
- 0xAF, 0xBA, 0x44, 0xF0, 0xA8, 0xB5, 0xB7, 0x44,
- 0xF0, 0xA9, 0x85, 0x85, 0x44, 0xF0, 0xA9, 0x87,
- 0x9F, 0x44, 0xF0, 0xA9, 0x88, 0x9A, 0x44, 0xF0,
- // Bytes 1840 - 187f
- 0xA9, 0x90, 0x8A, 0x44, 0xF0, 0xA9, 0x92, 0x96,
- 0x44, 0xF0, 0xA9, 0x96, 0xB6, 0x44, 0xF0, 0xA9,
- 0xAC, 0xB0, 0x44, 0xF0, 0xAA, 0x83, 0x8E, 0x44,
- 0xF0, 0xAA, 0x84, 0x85, 0x44, 0xF0, 0xAA, 0x88,
- 0x8E, 0x44, 0xF0, 0xAA, 0x8A, 0x91, 0x44, 0xF0,
- 0xAA, 0x8E, 0x92, 0x44, 0xF0, 0xAA, 0x98, 0x80,
- 0x42, 0x21, 0x21, 0x42, 0x21, 0x3F, 0x42, 0x2E,
- 0x2E, 0x42, 0x30, 0x2C, 0x42, 0x30, 0x2E, 0x42,
- // Bytes 1880 - 18bf
- 0x31, 0x2C, 0x42, 0x31, 0x2E, 0x42, 0x31, 0x30,
- 0x42, 0x31, 0x31, 0x42, 0x31, 0x32, 0x42, 0x31,
- 0x33, 0x42, 0x31, 0x34, 0x42, 0x31, 0x35, 0x42,
- 0x31, 0x36, 0x42, 0x31, 0x37, 0x42, 0x31, 0x38,
- 0x42, 0x31, 0x39, 0x42, 0x32, 0x2C, 0x42, 0x32,
- 0x2E, 0x42, 0x32, 0x30, 0x42, 0x32, 0x31, 0x42,
- 0x32, 0x32, 0x42, 0x32, 0x33, 0x42, 0x32, 0x34,
- 0x42, 0x32, 0x35, 0x42, 0x32, 0x36, 0x42, 0x32,
- // Bytes 18c0 - 18ff
- 0x37, 0x42, 0x32, 0x38, 0x42, 0x32, 0x39, 0x42,
- 0x33, 0x2C, 0x42, 0x33, 0x2E, 0x42, 0x33, 0x30,
- 0x42, 0x33, 0x31, 0x42, 0x33, 0x32, 0x42, 0x33,
- 0x33, 0x42, 0x33, 0x34, 0x42, 0x33, 0x35, 0x42,
- 0x33, 0x36, 0x42, 0x33, 0x37, 0x42, 0x33, 0x38,
- 0x42, 0x33, 0x39, 0x42, 0x34, 0x2C, 0x42, 0x34,
- 0x2E, 0x42, 0x34, 0x30, 0x42, 0x34, 0x31, 0x42,
- 0x34, 0x32, 0x42, 0x34, 0x33, 0x42, 0x34, 0x34,
- // Bytes 1900 - 193f
- 0x42, 0x34, 0x35, 0x42, 0x34, 0x36, 0x42, 0x34,
- 0x37, 0x42, 0x34, 0x38, 0x42, 0x34, 0x39, 0x42,
- 0x35, 0x2C, 0x42, 0x35, 0x2E, 0x42, 0x35, 0x30,
- 0x42, 0x36, 0x2C, 0x42, 0x36, 0x2E, 0x42, 0x37,
- 0x2C, 0x42, 0x37, 0x2E, 0x42, 0x38, 0x2C, 0x42,
- 0x38, 0x2E, 0x42, 0x39, 0x2C, 0x42, 0x39, 0x2E,
- 0x42, 0x3D, 0x3D, 0x42, 0x3F, 0x21, 0x42, 0x3F,
- 0x3F, 0x42, 0x41, 0x55, 0x42, 0x42, 0x71, 0x42,
- // Bytes 1940 - 197f
- 0x43, 0x44, 0x42, 0x44, 0x4A, 0x42, 0x44, 0x5A,
- 0x42, 0x44, 0x7A, 0x42, 0x47, 0x42, 0x42, 0x47,
- 0x79, 0x42, 0x48, 0x50, 0x42, 0x48, 0x56, 0x42,
- 0x48, 0x67, 0x42, 0x48, 0x7A, 0x42, 0x49, 0x49,
- 0x42, 0x49, 0x4A, 0x42, 0x49, 0x55, 0x42, 0x49,
- 0x56, 0x42, 0x49, 0x58, 0x42, 0x4B, 0x42, 0x42,
- 0x4B, 0x4B, 0x42, 0x4B, 0x4D, 0x42, 0x4C, 0x4A,
- 0x42, 0x4C, 0x6A, 0x42, 0x4D, 0x42, 0x42, 0x4D,
- // Bytes 1980 - 19bf
- 0x43, 0x42, 0x4D, 0x44, 0x42, 0x4D, 0x52, 0x42,
- 0x4D, 0x56, 0x42, 0x4D, 0x57, 0x42, 0x4E, 0x4A,
- 0x42, 0x4E, 0x6A, 0x42, 0x4E, 0x6F, 0x42, 0x50,
- 0x48, 0x42, 0x50, 0x52, 0x42, 0x50, 0x61, 0x42,
- 0x52, 0x73, 0x42, 0x53, 0x44, 0x42, 0x53, 0x4D,
- 0x42, 0x53, 0x53, 0x42, 0x53, 0x76, 0x42, 0x54,
- 0x4D, 0x42, 0x56, 0x49, 0x42, 0x57, 0x43, 0x42,
- 0x57, 0x5A, 0x42, 0x57, 0x62, 0x42, 0x58, 0x49,
- // Bytes 19c0 - 19ff
- 0x42, 0x63, 0x63, 0x42, 0x63, 0x64, 0x42, 0x63,
- 0x6D, 0x42, 0x64, 0x42, 0x42, 0x64, 0x61, 0x42,
- 0x64, 0x6C, 0x42, 0x64, 0x6D, 0x42, 0x64, 0x7A,
- 0x42, 0x65, 0x56, 0x42, 0x66, 0x66, 0x42, 0x66,
- 0x69, 0x42, 0x66, 0x6C, 0x42, 0x66, 0x6D, 0x42,
- 0x68, 0x61, 0x42, 0x69, 0x69, 0x42, 0x69, 0x6A,
- 0x42, 0x69, 0x6E, 0x42, 0x69, 0x76, 0x42, 0x69,
- 0x78, 0x42, 0x6B, 0x41, 0x42, 0x6B, 0x56, 0x42,
- // Bytes 1a00 - 1a3f
- 0x6B, 0x57, 0x42, 0x6B, 0x67, 0x42, 0x6B, 0x6C,
- 0x42, 0x6B, 0x6D, 0x42, 0x6B, 0x74, 0x42, 0x6C,
- 0x6A, 0x42, 0x6C, 0x6D, 0x42, 0x6C, 0x6E, 0x42,
- 0x6C, 0x78, 0x42, 0x6D, 0x32, 0x42, 0x6D, 0x33,
- 0x42, 0x6D, 0x41, 0x42, 0x6D, 0x56, 0x42, 0x6D,
- 0x57, 0x42, 0x6D, 0x62, 0x42, 0x6D, 0x67, 0x42,
- 0x6D, 0x6C, 0x42, 0x6D, 0x6D, 0x42, 0x6D, 0x73,
- 0x42, 0x6E, 0x41, 0x42, 0x6E, 0x46, 0x42, 0x6E,
- // Bytes 1a40 - 1a7f
- 0x56, 0x42, 0x6E, 0x57, 0x42, 0x6E, 0x6A, 0x42,
- 0x6E, 0x6D, 0x42, 0x6E, 0x73, 0x42, 0x6F, 0x56,
- 0x42, 0x70, 0x41, 0x42, 0x70, 0x46, 0x42, 0x70,
- 0x56, 0x42, 0x70, 0x57, 0x42, 0x70, 0x63, 0x42,
- 0x70, 0x73, 0x42, 0x73, 0x72, 0x42, 0x73, 0x74,
- 0x42, 0x76, 0x69, 0x42, 0x78, 0x69, 0x43, 0x28,
- 0x31, 0x29, 0x43, 0x28, 0x32, 0x29, 0x43, 0x28,
- 0x33, 0x29, 0x43, 0x28, 0x34, 0x29, 0x43, 0x28,
- // Bytes 1a80 - 1abf
- 0x35, 0x29, 0x43, 0x28, 0x36, 0x29, 0x43, 0x28,
- 0x37, 0x29, 0x43, 0x28, 0x38, 0x29, 0x43, 0x28,
- 0x39, 0x29, 0x43, 0x28, 0x41, 0x29, 0x43, 0x28,
- 0x42, 0x29, 0x43, 0x28, 0x43, 0x29, 0x43, 0x28,
- 0x44, 0x29, 0x43, 0x28, 0x45, 0x29, 0x43, 0x28,
- 0x46, 0x29, 0x43, 0x28, 0x47, 0x29, 0x43, 0x28,
- 0x48, 0x29, 0x43, 0x28, 0x49, 0x29, 0x43, 0x28,
- 0x4A, 0x29, 0x43, 0x28, 0x4B, 0x29, 0x43, 0x28,
- // Bytes 1ac0 - 1aff
- 0x4C, 0x29, 0x43, 0x28, 0x4D, 0x29, 0x43, 0x28,
- 0x4E, 0x29, 0x43, 0x28, 0x4F, 0x29, 0x43, 0x28,
- 0x50, 0x29, 0x43, 0x28, 0x51, 0x29, 0x43, 0x28,
- 0x52, 0x29, 0x43, 0x28, 0x53, 0x29, 0x43, 0x28,
- 0x54, 0x29, 0x43, 0x28, 0x55, 0x29, 0x43, 0x28,
- 0x56, 0x29, 0x43, 0x28, 0x57, 0x29, 0x43, 0x28,
- 0x58, 0x29, 0x43, 0x28, 0x59, 0x29, 0x43, 0x28,
- 0x5A, 0x29, 0x43, 0x28, 0x61, 0x29, 0x43, 0x28,
- // Bytes 1b00 - 1b3f
- 0x62, 0x29, 0x43, 0x28, 0x63, 0x29, 0x43, 0x28,
- 0x64, 0x29, 0x43, 0x28, 0x65, 0x29, 0x43, 0x28,
- 0x66, 0x29, 0x43, 0x28, 0x67, 0x29, 0x43, 0x28,
- 0x68, 0x29, 0x43, 0x28, 0x69, 0x29, 0x43, 0x28,
- 0x6A, 0x29, 0x43, 0x28, 0x6B, 0x29, 0x43, 0x28,
- 0x6C, 0x29, 0x43, 0x28, 0x6D, 0x29, 0x43, 0x28,
- 0x6E, 0x29, 0x43, 0x28, 0x6F, 0x29, 0x43, 0x28,
- 0x70, 0x29, 0x43, 0x28, 0x71, 0x29, 0x43, 0x28,
- // Bytes 1b40 - 1b7f
- 0x72, 0x29, 0x43, 0x28, 0x73, 0x29, 0x43, 0x28,
- 0x74, 0x29, 0x43, 0x28, 0x75, 0x29, 0x43, 0x28,
- 0x76, 0x29, 0x43, 0x28, 0x77, 0x29, 0x43, 0x28,
- 0x78, 0x29, 0x43, 0x28, 0x79, 0x29, 0x43, 0x28,
- 0x7A, 0x29, 0x43, 0x2E, 0x2E, 0x2E, 0x43, 0x31,
- 0x30, 0x2E, 0x43, 0x31, 0x31, 0x2E, 0x43, 0x31,
- 0x32, 0x2E, 0x43, 0x31, 0x33, 0x2E, 0x43, 0x31,
- 0x34, 0x2E, 0x43, 0x31, 0x35, 0x2E, 0x43, 0x31,
- // Bytes 1b80 - 1bbf
- 0x36, 0x2E, 0x43, 0x31, 0x37, 0x2E, 0x43, 0x31,
- 0x38, 0x2E, 0x43, 0x31, 0x39, 0x2E, 0x43, 0x32,
- 0x30, 0x2E, 0x43, 0x3A, 0x3A, 0x3D, 0x43, 0x3D,
- 0x3D, 0x3D, 0x43, 0x43, 0x6F, 0x2E, 0x43, 0x46,
- 0x41, 0x58, 0x43, 0x47, 0x48, 0x7A, 0x43, 0x47,
- 0x50, 0x61, 0x43, 0x49, 0x49, 0x49, 0x43, 0x4C,
- 0x54, 0x44, 0x43, 0x4C, 0xC2, 0xB7, 0x43, 0x4D,
- 0x48, 0x7A, 0x43, 0x4D, 0x50, 0x61, 0x43, 0x4D,
- // Bytes 1bc0 - 1bff
- 0xCE, 0xA9, 0x43, 0x50, 0x50, 0x4D, 0x43, 0x50,
- 0x50, 0x56, 0x43, 0x50, 0x54, 0x45, 0x43, 0x54,
- 0x45, 0x4C, 0x43, 0x54, 0x48, 0x7A, 0x43, 0x56,
- 0x49, 0x49, 0x43, 0x58, 0x49, 0x49, 0x43, 0x61,
- 0x2F, 0x63, 0x43, 0x61, 0x2F, 0x73, 0x43, 0x61,
- 0xCA, 0xBE, 0x43, 0x62, 0x61, 0x72, 0x43, 0x63,
- 0x2F, 0x6F, 0x43, 0x63, 0x2F, 0x75, 0x43, 0x63,
- 0x61, 0x6C, 0x43, 0x63, 0x6D, 0x32, 0x43, 0x63,
- // Bytes 1c00 - 1c3f
- 0x6D, 0x33, 0x43, 0x64, 0x6D, 0x32, 0x43, 0x64,
- 0x6D, 0x33, 0x43, 0x65, 0x72, 0x67, 0x43, 0x66,
- 0x66, 0x69, 0x43, 0x66, 0x66, 0x6C, 0x43, 0x67,
- 0x61, 0x6C, 0x43, 0x68, 0x50, 0x61, 0x43, 0x69,
- 0x69, 0x69, 0x43, 0x6B, 0x48, 0x7A, 0x43, 0x6B,
- 0x50, 0x61, 0x43, 0x6B, 0x6D, 0x32, 0x43, 0x6B,
- 0x6D, 0x33, 0x43, 0x6B, 0xCE, 0xA9, 0x43, 0x6C,
- 0x6F, 0x67, 0x43, 0x6C, 0xC2, 0xB7, 0x43, 0x6D,
- // Bytes 1c40 - 1c7f
- 0x69, 0x6C, 0x43, 0x6D, 0x6D, 0x32, 0x43, 0x6D,
- 0x6D, 0x33, 0x43, 0x6D, 0x6F, 0x6C, 0x43, 0x72,
- 0x61, 0x64, 0x43, 0x76, 0x69, 0x69, 0x43, 0x78,
- 0x69, 0x69, 0x43, 0xC2, 0xB0, 0x43, 0x43, 0xC2,
- 0xB0, 0x46, 0x43, 0xCA, 0xBC, 0x6E, 0x43, 0xCE,
- 0xBC, 0x41, 0x43, 0xCE, 0xBC, 0x46, 0x43, 0xCE,
- 0xBC, 0x56, 0x43, 0xCE, 0xBC, 0x57, 0x43, 0xCE,
- 0xBC, 0x67, 0x43, 0xCE, 0xBC, 0x6C, 0x43, 0xCE,
- // Bytes 1c80 - 1cbf
- 0xBC, 0x6D, 0x43, 0xCE, 0xBC, 0x73, 0x44, 0x28,
- 0x31, 0x30, 0x29, 0x44, 0x28, 0x31, 0x31, 0x29,
- 0x44, 0x28, 0x31, 0x32, 0x29, 0x44, 0x28, 0x31,
- 0x33, 0x29, 0x44, 0x28, 0x31, 0x34, 0x29, 0x44,
- 0x28, 0x31, 0x35, 0x29, 0x44, 0x28, 0x31, 0x36,
- 0x29, 0x44, 0x28, 0x31, 0x37, 0x29, 0x44, 0x28,
- 0x31, 0x38, 0x29, 0x44, 0x28, 0x31, 0x39, 0x29,
- 0x44, 0x28, 0x32, 0x30, 0x29, 0x44, 0x30, 0xE7,
- // Bytes 1cc0 - 1cff
- 0x82, 0xB9, 0x44, 0x31, 0xE2, 0x81, 0x84, 0x44,
- 0x31, 0xE6, 0x97, 0xA5, 0x44, 0x31, 0xE6, 0x9C,
- 0x88, 0x44, 0x31, 0xE7, 0x82, 0xB9, 0x44, 0x32,
- 0xE6, 0x97, 0xA5, 0x44, 0x32, 0xE6, 0x9C, 0x88,
- 0x44, 0x32, 0xE7, 0x82, 0xB9, 0x44, 0x33, 0xE6,
- 0x97, 0xA5, 0x44, 0x33, 0xE6, 0x9C, 0x88, 0x44,
- 0x33, 0xE7, 0x82, 0xB9, 0x44, 0x34, 0xE6, 0x97,
- 0xA5, 0x44, 0x34, 0xE6, 0x9C, 0x88, 0x44, 0x34,
- // Bytes 1d00 - 1d3f
- 0xE7, 0x82, 0xB9, 0x44, 0x35, 0xE6, 0x97, 0xA5,
- 0x44, 0x35, 0xE6, 0x9C, 0x88, 0x44, 0x35, 0xE7,
- 0x82, 0xB9, 0x44, 0x36, 0xE6, 0x97, 0xA5, 0x44,
- 0x36, 0xE6, 0x9C, 0x88, 0x44, 0x36, 0xE7, 0x82,
- 0xB9, 0x44, 0x37, 0xE6, 0x97, 0xA5, 0x44, 0x37,
- 0xE6, 0x9C, 0x88, 0x44, 0x37, 0xE7, 0x82, 0xB9,
- 0x44, 0x38, 0xE6, 0x97, 0xA5, 0x44, 0x38, 0xE6,
- 0x9C, 0x88, 0x44, 0x38, 0xE7, 0x82, 0xB9, 0x44,
- // Bytes 1d40 - 1d7f
- 0x39, 0xE6, 0x97, 0xA5, 0x44, 0x39, 0xE6, 0x9C,
- 0x88, 0x44, 0x39, 0xE7, 0x82, 0xB9, 0x44, 0x56,
- 0x49, 0x49, 0x49, 0x44, 0x61, 0x2E, 0x6D, 0x2E,
- 0x44, 0x6B, 0x63, 0x61, 0x6C, 0x44, 0x70, 0x2E,
- 0x6D, 0x2E, 0x44, 0x76, 0x69, 0x69, 0x69, 0x44,
- 0xD5, 0xA5, 0xD6, 0x82, 0x44, 0xD5, 0xB4, 0xD5,
- 0xA5, 0x44, 0xD5, 0xB4, 0xD5, 0xAB, 0x44, 0xD5,
- 0xB4, 0xD5, 0xAD, 0x44, 0xD5, 0xB4, 0xD5, 0xB6,
- // Bytes 1d80 - 1dbf
- 0x44, 0xD5, 0xBE, 0xD5, 0xB6, 0x44, 0xD7, 0x90,
- 0xD7, 0x9C, 0x44, 0xD8, 0xA7, 0xD9, 0xB4, 0x44,
- 0xD8, 0xA8, 0xD8, 0xAC, 0x44, 0xD8, 0xA8, 0xD8,
- 0xAD, 0x44, 0xD8, 0xA8, 0xD8, 0xAE, 0x44, 0xD8,
- 0xA8, 0xD8, 0xB1, 0x44, 0xD8, 0xA8, 0xD8, 0xB2,
- 0x44, 0xD8, 0xA8, 0xD9, 0x85, 0x44, 0xD8, 0xA8,
- 0xD9, 0x86, 0x44, 0xD8, 0xA8, 0xD9, 0x87, 0x44,
- 0xD8, 0xA8, 0xD9, 0x89, 0x44, 0xD8, 0xA8, 0xD9,
- // Bytes 1dc0 - 1dff
- 0x8A, 0x44, 0xD8, 0xAA, 0xD8, 0xAC, 0x44, 0xD8,
- 0xAA, 0xD8, 0xAD, 0x44, 0xD8, 0xAA, 0xD8, 0xAE,
- 0x44, 0xD8, 0xAA, 0xD8, 0xB1, 0x44, 0xD8, 0xAA,
- 0xD8, 0xB2, 0x44, 0xD8, 0xAA, 0xD9, 0x85, 0x44,
- 0xD8, 0xAA, 0xD9, 0x86, 0x44, 0xD8, 0xAA, 0xD9,
- 0x87, 0x44, 0xD8, 0xAA, 0xD9, 0x89, 0x44, 0xD8,
- 0xAA, 0xD9, 0x8A, 0x44, 0xD8, 0xAB, 0xD8, 0xAC,
- 0x44, 0xD8, 0xAB, 0xD8, 0xB1, 0x44, 0xD8, 0xAB,
- // Bytes 1e00 - 1e3f
- 0xD8, 0xB2, 0x44, 0xD8, 0xAB, 0xD9, 0x85, 0x44,
- 0xD8, 0xAB, 0xD9, 0x86, 0x44, 0xD8, 0xAB, 0xD9,
- 0x87, 0x44, 0xD8, 0xAB, 0xD9, 0x89, 0x44, 0xD8,
- 0xAB, 0xD9, 0x8A, 0x44, 0xD8, 0xAC, 0xD8, 0xAD,
- 0x44, 0xD8, 0xAC, 0xD9, 0x85, 0x44, 0xD8, 0xAC,
- 0xD9, 0x89, 0x44, 0xD8, 0xAC, 0xD9, 0x8A, 0x44,
- 0xD8, 0xAD, 0xD8, 0xAC, 0x44, 0xD8, 0xAD, 0xD9,
- 0x85, 0x44, 0xD8, 0xAD, 0xD9, 0x89, 0x44, 0xD8,
- // Bytes 1e40 - 1e7f
- 0xAD, 0xD9, 0x8A, 0x44, 0xD8, 0xAE, 0xD8, 0xAC,
- 0x44, 0xD8, 0xAE, 0xD8, 0xAD, 0x44, 0xD8, 0xAE,
- 0xD9, 0x85, 0x44, 0xD8, 0xAE, 0xD9, 0x89, 0x44,
- 0xD8, 0xAE, 0xD9, 0x8A, 0x44, 0xD8, 0xB3, 0xD8,
- 0xAC, 0x44, 0xD8, 0xB3, 0xD8, 0xAD, 0x44, 0xD8,
- 0xB3, 0xD8, 0xAE, 0x44, 0xD8, 0xB3, 0xD8, 0xB1,
- 0x44, 0xD8, 0xB3, 0xD9, 0x85, 0x44, 0xD8, 0xB3,
- 0xD9, 0x87, 0x44, 0xD8, 0xB3, 0xD9, 0x89, 0x44,
- // Bytes 1e80 - 1ebf
- 0xD8, 0xB3, 0xD9, 0x8A, 0x44, 0xD8, 0xB4, 0xD8,
- 0xAC, 0x44, 0xD8, 0xB4, 0xD8, 0xAD, 0x44, 0xD8,
- 0xB4, 0xD8, 0xAE, 0x44, 0xD8, 0xB4, 0xD8, 0xB1,
- 0x44, 0xD8, 0xB4, 0xD9, 0x85, 0x44, 0xD8, 0xB4,
- 0xD9, 0x87, 0x44, 0xD8, 0xB4, 0xD9, 0x89, 0x44,
- 0xD8, 0xB4, 0xD9, 0x8A, 0x44, 0xD8, 0xB5, 0xD8,
- 0xAD, 0x44, 0xD8, 0xB5, 0xD8, 0xAE, 0x44, 0xD8,
- 0xB5, 0xD8, 0xB1, 0x44, 0xD8, 0xB5, 0xD9, 0x85,
- // Bytes 1ec0 - 1eff
- 0x44, 0xD8, 0xB5, 0xD9, 0x89, 0x44, 0xD8, 0xB5,
- 0xD9, 0x8A, 0x44, 0xD8, 0xB6, 0xD8, 0xAC, 0x44,
- 0xD8, 0xB6, 0xD8, 0xAD, 0x44, 0xD8, 0xB6, 0xD8,
- 0xAE, 0x44, 0xD8, 0xB6, 0xD8, 0xB1, 0x44, 0xD8,
- 0xB6, 0xD9, 0x85, 0x44, 0xD8, 0xB6, 0xD9, 0x89,
- 0x44, 0xD8, 0xB6, 0xD9, 0x8A, 0x44, 0xD8, 0xB7,
- 0xD8, 0xAD, 0x44, 0xD8, 0xB7, 0xD9, 0x85, 0x44,
- 0xD8, 0xB7, 0xD9, 0x89, 0x44, 0xD8, 0xB7, 0xD9,
- // Bytes 1f00 - 1f3f
- 0x8A, 0x44, 0xD8, 0xB8, 0xD9, 0x85, 0x44, 0xD8,
- 0xB9, 0xD8, 0xAC, 0x44, 0xD8, 0xB9, 0xD9, 0x85,
- 0x44, 0xD8, 0xB9, 0xD9, 0x89, 0x44, 0xD8, 0xB9,
- 0xD9, 0x8A, 0x44, 0xD8, 0xBA, 0xD8, 0xAC, 0x44,
- 0xD8, 0xBA, 0xD9, 0x85, 0x44, 0xD8, 0xBA, 0xD9,
- 0x89, 0x44, 0xD8, 0xBA, 0xD9, 0x8A, 0x44, 0xD9,
- 0x81, 0xD8, 0xAC, 0x44, 0xD9, 0x81, 0xD8, 0xAD,
- 0x44, 0xD9, 0x81, 0xD8, 0xAE, 0x44, 0xD9, 0x81,
- // Bytes 1f40 - 1f7f
- 0xD9, 0x85, 0x44, 0xD9, 0x81, 0xD9, 0x89, 0x44,
- 0xD9, 0x81, 0xD9, 0x8A, 0x44, 0xD9, 0x82, 0xD8,
- 0xAD, 0x44, 0xD9, 0x82, 0xD9, 0x85, 0x44, 0xD9,
- 0x82, 0xD9, 0x89, 0x44, 0xD9, 0x82, 0xD9, 0x8A,
- 0x44, 0xD9, 0x83, 0xD8, 0xA7, 0x44, 0xD9, 0x83,
- 0xD8, 0xAC, 0x44, 0xD9, 0x83, 0xD8, 0xAD, 0x44,
- 0xD9, 0x83, 0xD8, 0xAE, 0x44, 0xD9, 0x83, 0xD9,
- 0x84, 0x44, 0xD9, 0x83, 0xD9, 0x85, 0x44, 0xD9,
- // Bytes 1f80 - 1fbf
- 0x83, 0xD9, 0x89, 0x44, 0xD9, 0x83, 0xD9, 0x8A,
- 0x44, 0xD9, 0x84, 0xD8, 0xA7, 0x44, 0xD9, 0x84,
- 0xD8, 0xAC, 0x44, 0xD9, 0x84, 0xD8, 0xAD, 0x44,
- 0xD9, 0x84, 0xD8, 0xAE, 0x44, 0xD9, 0x84, 0xD9,
- 0x85, 0x44, 0xD9, 0x84, 0xD9, 0x87, 0x44, 0xD9,
- 0x84, 0xD9, 0x89, 0x44, 0xD9, 0x84, 0xD9, 0x8A,
- 0x44, 0xD9, 0x85, 0xD8, 0xA7, 0x44, 0xD9, 0x85,
- 0xD8, 0xAC, 0x44, 0xD9, 0x85, 0xD8, 0xAD, 0x44,
- // Bytes 1fc0 - 1fff
- 0xD9, 0x85, 0xD8, 0xAE, 0x44, 0xD9, 0x85, 0xD9,
- 0x85, 0x44, 0xD9, 0x85, 0xD9, 0x89, 0x44, 0xD9,
- 0x85, 0xD9, 0x8A, 0x44, 0xD9, 0x86, 0xD8, 0xAC,
- 0x44, 0xD9, 0x86, 0xD8, 0xAD, 0x44, 0xD9, 0x86,
- 0xD8, 0xAE, 0x44, 0xD9, 0x86, 0xD8, 0xB1, 0x44,
- 0xD9, 0x86, 0xD8, 0xB2, 0x44, 0xD9, 0x86, 0xD9,
- 0x85, 0x44, 0xD9, 0x86, 0xD9, 0x86, 0x44, 0xD9,
- 0x86, 0xD9, 0x87, 0x44, 0xD9, 0x86, 0xD9, 0x89,
- // Bytes 2000 - 203f
- 0x44, 0xD9, 0x86, 0xD9, 0x8A, 0x44, 0xD9, 0x87,
- 0xD8, 0xAC, 0x44, 0xD9, 0x87, 0xD9, 0x85, 0x44,
- 0xD9, 0x87, 0xD9, 0x89, 0x44, 0xD9, 0x87, 0xD9,
- 0x8A, 0x44, 0xD9, 0x88, 0xD9, 0xB4, 0x44, 0xD9,
- 0x8A, 0xD8, 0xAC, 0x44, 0xD9, 0x8A, 0xD8, 0xAD,
- 0x44, 0xD9, 0x8A, 0xD8, 0xAE, 0x44, 0xD9, 0x8A,
- 0xD8, 0xB1, 0x44, 0xD9, 0x8A, 0xD8, 0xB2, 0x44,
- 0xD9, 0x8A, 0xD9, 0x85, 0x44, 0xD9, 0x8A, 0xD9,
- // Bytes 2040 - 207f
- 0x86, 0x44, 0xD9, 0x8A, 0xD9, 0x87, 0x44, 0xD9,
- 0x8A, 0xD9, 0x89, 0x44, 0xD9, 0x8A, 0xD9, 0x8A,
- 0x44, 0xD9, 0x8A, 0xD9, 0xB4, 0x44, 0xDB, 0x87,
- 0xD9, 0xB4, 0x45, 0x28, 0xE1, 0x84, 0x80, 0x29,
- 0x45, 0x28, 0xE1, 0x84, 0x82, 0x29, 0x45, 0x28,
- 0xE1, 0x84, 0x83, 0x29, 0x45, 0x28, 0xE1, 0x84,
- 0x85, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x86, 0x29,
- 0x45, 0x28, 0xE1, 0x84, 0x87, 0x29, 0x45, 0x28,
- // Bytes 2080 - 20bf
- 0xE1, 0x84, 0x89, 0x29, 0x45, 0x28, 0xE1, 0x84,
- 0x8B, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x8C, 0x29,
- 0x45, 0x28, 0xE1, 0x84, 0x8E, 0x29, 0x45, 0x28,
- 0xE1, 0x84, 0x8F, 0x29, 0x45, 0x28, 0xE1, 0x84,
- 0x90, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x91, 0x29,
- 0x45, 0x28, 0xE1, 0x84, 0x92, 0x29, 0x45, 0x28,
- 0xE4, 0xB8, 0x80, 0x29, 0x45, 0x28, 0xE4, 0xB8,
- 0x83, 0x29, 0x45, 0x28, 0xE4, 0xB8, 0x89, 0x29,
- // Bytes 20c0 - 20ff
- 0x45, 0x28, 0xE4, 0xB9, 0x9D, 0x29, 0x45, 0x28,
- 0xE4, 0xBA, 0x8C, 0x29, 0x45, 0x28, 0xE4, 0xBA,
- 0x94, 0x29, 0x45, 0x28, 0xE4, 0xBB, 0xA3, 0x29,
- 0x45, 0x28, 0xE4, 0xBC, 0x81, 0x29, 0x45, 0x28,
- 0xE4, 0xBC, 0x91, 0x29, 0x45, 0x28, 0xE5, 0x85,
- 0xAB, 0x29, 0x45, 0x28, 0xE5, 0x85, 0xAD, 0x29,
- 0x45, 0x28, 0xE5, 0x8A, 0xB4, 0x29, 0x45, 0x28,
- 0xE5, 0x8D, 0x81, 0x29, 0x45, 0x28, 0xE5, 0x8D,
- // Bytes 2100 - 213f
- 0x94, 0x29, 0x45, 0x28, 0xE5, 0x90, 0x8D, 0x29,
- 0x45, 0x28, 0xE5, 0x91, 0xBC, 0x29, 0x45, 0x28,
- 0xE5, 0x9B, 0x9B, 0x29, 0x45, 0x28, 0xE5, 0x9C,
- 0x9F, 0x29, 0x45, 0x28, 0xE5, 0xAD, 0xA6, 0x29,
- 0x45, 0x28, 0xE6, 0x97, 0xA5, 0x29, 0x45, 0x28,
- 0xE6, 0x9C, 0x88, 0x29, 0x45, 0x28, 0xE6, 0x9C,
- 0x89, 0x29, 0x45, 0x28, 0xE6, 0x9C, 0xA8, 0x29,
- 0x45, 0x28, 0xE6, 0xA0, 0xAA, 0x29, 0x45, 0x28,
- // Bytes 2140 - 217f
- 0xE6, 0xB0, 0xB4, 0x29, 0x45, 0x28, 0xE7, 0x81,
- 0xAB, 0x29, 0x45, 0x28, 0xE7, 0x89, 0xB9, 0x29,
- 0x45, 0x28, 0xE7, 0x9B, 0xA3, 0x29, 0x45, 0x28,
- 0xE7, 0xA4, 0xBE, 0x29, 0x45, 0x28, 0xE7, 0xA5,
- 0x9D, 0x29, 0x45, 0x28, 0xE7, 0xA5, 0xAD, 0x29,
- 0x45, 0x28, 0xE8, 0x87, 0xAA, 0x29, 0x45, 0x28,
- 0xE8, 0x87, 0xB3, 0x29, 0x45, 0x28, 0xE8, 0xB2,
- 0xA1, 0x29, 0x45, 0x28, 0xE8, 0xB3, 0x87, 0x29,
- // Bytes 2180 - 21bf
- 0x45, 0x28, 0xE9, 0x87, 0x91, 0x29, 0x45, 0x30,
- 0xE2, 0x81, 0x84, 0x33, 0x45, 0x31, 0x30, 0xE6,
- 0x97, 0xA5, 0x45, 0x31, 0x30, 0xE6, 0x9C, 0x88,
- 0x45, 0x31, 0x30, 0xE7, 0x82, 0xB9, 0x45, 0x31,
- 0x31, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x31, 0xE6,
- 0x9C, 0x88, 0x45, 0x31, 0x31, 0xE7, 0x82, 0xB9,
- 0x45, 0x31, 0x32, 0xE6, 0x97, 0xA5, 0x45, 0x31,
- 0x32, 0xE6, 0x9C, 0x88, 0x45, 0x31, 0x32, 0xE7,
- // Bytes 21c0 - 21ff
- 0x82, 0xB9, 0x45, 0x31, 0x33, 0xE6, 0x97, 0xA5,
- 0x45, 0x31, 0x33, 0xE7, 0x82, 0xB9, 0x45, 0x31,
- 0x34, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x34, 0xE7,
- 0x82, 0xB9, 0x45, 0x31, 0x35, 0xE6, 0x97, 0xA5,
- 0x45, 0x31, 0x35, 0xE7, 0x82, 0xB9, 0x45, 0x31,
- 0x36, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x36, 0xE7,
- 0x82, 0xB9, 0x45, 0x31, 0x37, 0xE6, 0x97, 0xA5,
- 0x45, 0x31, 0x37, 0xE7, 0x82, 0xB9, 0x45, 0x31,
- // Bytes 2200 - 223f
- 0x38, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x38, 0xE7,
- 0x82, 0xB9, 0x45, 0x31, 0x39, 0xE6, 0x97, 0xA5,
- 0x45, 0x31, 0x39, 0xE7, 0x82, 0xB9, 0x45, 0x31,
- 0xE2, 0x81, 0x84, 0x32, 0x45, 0x31, 0xE2, 0x81,
- 0x84, 0x33, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x34,
- 0x45, 0x31, 0xE2, 0x81, 0x84, 0x35, 0x45, 0x31,
- 0xE2, 0x81, 0x84, 0x36, 0x45, 0x31, 0xE2, 0x81,
- 0x84, 0x37, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x38,
- // Bytes 2240 - 227f
- 0x45, 0x31, 0xE2, 0x81, 0x84, 0x39, 0x45, 0x32,
- 0x30, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x30, 0xE7,
- 0x82, 0xB9, 0x45, 0x32, 0x31, 0xE6, 0x97, 0xA5,
- 0x45, 0x32, 0x31, 0xE7, 0x82, 0xB9, 0x45, 0x32,
- 0x32, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x32, 0xE7,
- 0x82, 0xB9, 0x45, 0x32, 0x33, 0xE6, 0x97, 0xA5,
- 0x45, 0x32, 0x33, 0xE7, 0x82, 0xB9, 0x45, 0x32,
- 0x34, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x34, 0xE7,
- // Bytes 2280 - 22bf
- 0x82, 0xB9, 0x45, 0x32, 0x35, 0xE6, 0x97, 0xA5,
- 0x45, 0x32, 0x36, 0xE6, 0x97, 0xA5, 0x45, 0x32,
- 0x37, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x38, 0xE6,
- 0x97, 0xA5, 0x45, 0x32, 0x39, 0xE6, 0x97, 0xA5,
- 0x45, 0x32, 0xE2, 0x81, 0x84, 0x33, 0x45, 0x32,
- 0xE2, 0x81, 0x84, 0x35, 0x45, 0x33, 0x30, 0xE6,
- 0x97, 0xA5, 0x45, 0x33, 0x31, 0xE6, 0x97, 0xA5,
- 0x45, 0x33, 0xE2, 0x81, 0x84, 0x34, 0x45, 0x33,
- // Bytes 22c0 - 22ff
- 0xE2, 0x81, 0x84, 0x35, 0x45, 0x33, 0xE2, 0x81,
- 0x84, 0x38, 0x45, 0x34, 0xE2, 0x81, 0x84, 0x35,
- 0x45, 0x35, 0xE2, 0x81, 0x84, 0x36, 0x45, 0x35,
- 0xE2, 0x81, 0x84, 0x38, 0x45, 0x37, 0xE2, 0x81,
- 0x84, 0x38, 0x45, 0x41, 0xE2, 0x88, 0x95, 0x6D,
- 0x45, 0x56, 0xE2, 0x88, 0x95, 0x6D, 0x45, 0x6D,
- 0xE2, 0x88, 0x95, 0x73, 0x46, 0x31, 0xE2, 0x81,
- 0x84, 0x31, 0x30, 0x46, 0x43, 0xE2, 0x88, 0x95,
- // Bytes 2300 - 233f
- 0x6B, 0x67, 0x46, 0x6D, 0xE2, 0x88, 0x95, 0x73,
- 0x32, 0x46, 0xD8, 0xA8, 0xD8, 0xAD, 0xD9, 0x8A,
- 0x46, 0xD8, 0xA8, 0xD8, 0xAE, 0xD9, 0x8A, 0x46,
- 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x85, 0x46, 0xD8,
- 0xAA, 0xD8, 0xAC, 0xD9, 0x89, 0x46, 0xD8, 0xAA,
- 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, 0xAA, 0xD8,
- 0xAD, 0xD8, 0xAC, 0x46, 0xD8, 0xAA, 0xD8, 0xAD,
- 0xD9, 0x85, 0x46, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9,
- // Bytes 2340 - 237f
- 0x85, 0x46, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x89,
- 0x46, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x8A, 0x46,
- 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAC, 0x46, 0xD8,
- 0xAA, 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xAA,
- 0xD9, 0x85, 0xD8, 0xAE, 0x46, 0xD8, 0xAA, 0xD9,
- 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAA, 0xD9, 0x85,
- 0xD9, 0x8A, 0x46, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9,
- 0x89, 0x46, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x8A,
- // Bytes 2380 - 23bf
- 0x46, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, 0xAD, 0x46,
- 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8,
- 0xAC, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xAD,
- 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, 0xAD, 0xD9,
- 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAD, 0xD9, 0x85,
- 0xD9, 0x8A, 0x46, 0xD8, 0xB3, 0xD8, 0xAC, 0xD8,
- 0xAD, 0x46, 0xD8, 0xB3, 0xD8, 0xAC, 0xD9, 0x89,
- 0x46, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, 0xAC, 0x46,
- // Bytes 23c0 - 23ff
- 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x89, 0x46, 0xD8,
- 0xB3, 0xD8, 0xAE, 0xD9, 0x8A, 0x46, 0xD8, 0xB3,
- 0xD9, 0x85, 0xD8, 0xAC, 0x46, 0xD8, 0xB3, 0xD9,
- 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xB3, 0xD9, 0x85,
- 0xD9, 0x85, 0x46, 0xD8, 0xB4, 0xD8, 0xAC, 0xD9,
- 0x8A, 0x46, 0xD8, 0xB4, 0xD8, 0xAD, 0xD9, 0x85,
- 0x46, 0xD8, 0xB4, 0xD8, 0xAD, 0xD9, 0x8A, 0x46,
- 0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xAE, 0x46, 0xD8,
- // Bytes 2400 - 243f
- 0xB4, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB5,
- 0xD8, 0xAD, 0xD8, 0xAD, 0x46, 0xD8, 0xB5, 0xD8,
- 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xB5, 0xD9, 0x84,
- 0xD9, 0x89, 0x46, 0xD8, 0xB5, 0xD9, 0x84, 0xDB,
- 0x92, 0x46, 0xD8, 0xB5, 0xD9, 0x85, 0xD9, 0x85,
- 0x46, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x89, 0x46,
- 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD8,
- 0xB6, 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD8, 0xB7,
- // Bytes 2440 - 247f
- 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xB7, 0xD9,
- 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB7, 0xD9, 0x85,
- 0xD9, 0x8A, 0x46, 0xD8, 0xB9, 0xD8, 0xAC, 0xD9,
- 0x85, 0x46, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x85,
- 0x46, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x89, 0x46,
- 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8,
- 0xBA, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xBA,
- 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xBA, 0xD9,
- // Bytes 2480 - 24bf
- 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x81, 0xD8, 0xAE,
- 0xD9, 0x85, 0x46, 0xD9, 0x81, 0xD9, 0x85, 0xD9,
- 0x8A, 0x46, 0xD9, 0x82, 0xD9, 0x84, 0xDB, 0x92,
- 0x46, 0xD9, 0x82, 0xD9, 0x85, 0xD8, 0xAD, 0x46,
- 0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9,
- 0x82, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x83,
- 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, 0x83, 0xD9,
- 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x84, 0xD8, 0xAC,
- // Bytes 24c0 - 24ff
- 0xD8, 0xAC, 0x46, 0xD9, 0x84, 0xD8, 0xAC, 0xD9,
- 0x85, 0x46, 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x8A,
- 0x46, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x85, 0x46,
- 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, 0x46, 0xD9,
- 0x84, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x84,
- 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD9, 0x84, 0xD9,
- 0x85, 0xD8, 0xAD, 0x46, 0xD9, 0x84, 0xD9, 0x85,
- 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD8,
- // Bytes 2500 - 253f
- 0xAD, 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD8, 0xAE,
- 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x85, 0x46,
- 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD9,
- 0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0x46, 0xD9, 0x85,
- 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD9, 0x85, 0xD8,
- 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD8, 0xAE,
- 0xD8, 0xAC, 0x46, 0xD9, 0x85, 0xD8, 0xAE, 0xD9,
- 0x85, 0x46, 0xD9, 0x85, 0xD8, 0xAE, 0xD9, 0x8A,
- // Bytes 2540 - 257f
- 0x46, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x8A, 0x46,
- 0xD9, 0x86, 0xD8, 0xAC, 0xD8, 0xAD, 0x46, 0xD9,
- 0x86, 0xD8, 0xAC, 0xD9, 0x85, 0x46, 0xD9, 0x86,
- 0xD8, 0xAC, 0xD9, 0x89, 0x46, 0xD9, 0x86, 0xD8,
- 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x86, 0xD8, 0xAD,
- 0xD9, 0x85, 0x46, 0xD9, 0x86, 0xD8, 0xAD, 0xD9,
- 0x89, 0x46, 0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x8A,
- 0x46, 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x89, 0x46,
- // Bytes 2580 - 25bf
- 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9,
- 0x87, 0xD9, 0x85, 0xD8, 0xAC, 0x46, 0xD9, 0x87,
- 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, 0x8A, 0xD8,
- 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD8, 0xAD,
- 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD9, 0x85, 0xD9,
- 0x85, 0x46, 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x8A,
- 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xA7, 0x46,
- 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAC, 0x46, 0xD9,
- // Bytes 25c0 - 25ff
- 0x8A, 0xD9, 0x94, 0xD8, 0xAD, 0x46, 0xD9, 0x8A,
- 0xD9, 0x94, 0xD8, 0xAE, 0x46, 0xD9, 0x8A, 0xD9,
- 0x94, 0xD8, 0xB1, 0x46, 0xD9, 0x8A, 0xD9, 0x94,
- 0xD8, 0xB2, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9,
- 0x85, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x86,
- 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x87, 0x46,
- 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x88, 0x46, 0xD9,
- 0x8A, 0xD9, 0x94, 0xD9, 0x89, 0x46, 0xD9, 0x8A,
- // Bytes 2600 - 263f
- 0xD9, 0x94, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD9,
- 0x94, 0xDB, 0x86, 0x46, 0xD9, 0x8A, 0xD9, 0x94,
- 0xDB, 0x87, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB,
- 0x88, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x90,
- 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x95, 0x46,
- 0xE0, 0xB9, 0x8D, 0xE0, 0xB8, 0xB2, 0x46, 0xE0,
- 0xBA, 0xAB, 0xE0, 0xBA, 0x99, 0x46, 0xE0, 0xBA,
- 0xAB, 0xE0, 0xBA, 0xA1, 0x46, 0xE0, 0xBB, 0x8D,
- // Bytes 2640 - 267f
- 0xE0, 0xBA, 0xB2, 0x46, 0xE0, 0xBD, 0x80, 0xE0,
- 0xBE, 0xB5, 0x46, 0xE0, 0xBD, 0x82, 0xE0, 0xBE,
- 0xB7, 0x46, 0xE0, 0xBD, 0x8C, 0xE0, 0xBE, 0xB7,
- 0x46, 0xE0, 0xBD, 0x91, 0xE0, 0xBE, 0xB7, 0x46,
- 0xE0, 0xBD, 0x96, 0xE0, 0xBE, 0xB7, 0x46, 0xE0,
- 0xBD, 0x9B, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE,
- 0x90, 0xE0, 0xBE, 0xB5, 0x46, 0xE0, 0xBE, 0x92,
- 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0x9C, 0xE0,
- // Bytes 2680 - 26bf
- 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0xA1, 0xE0, 0xBE,
- 0xB7, 0x46, 0xE0, 0xBE, 0xA6, 0xE0, 0xBE, 0xB7,
- 0x46, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE, 0xB7, 0x46,
- 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x46, 0xE2,
- 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x46, 0xE2, 0x88,
- 0xAB, 0xE2, 0x88, 0xAB, 0x46, 0xE2, 0x88, 0xAE,
- 0xE2, 0x88, 0xAE, 0x46, 0xE3, 0x81, 0xBB, 0xE3,
- 0x81, 0x8B, 0x46, 0xE3, 0x82, 0x88, 0xE3, 0x82,
- // Bytes 26c0 - 26ff
- 0x8A, 0x46, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD,
- 0x46, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0xB3, 0x46,
- 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x88, 0x46, 0xE3,
- 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x46, 0xE3, 0x83,
- 0x8A, 0xE3, 0x83, 0x8E, 0x46, 0xE3, 0x83, 0x9B,
- 0xE3, 0x83, 0xB3, 0x46, 0xE3, 0x83, 0x9F, 0xE3,
- 0x83, 0xAA, 0x46, 0xE3, 0x83, 0xAA, 0xE3, 0x83,
- 0xA9, 0x46, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xA0,
- // Bytes 2700 - 273f
- 0x46, 0xE4, 0xBB, 0xA4, 0xE5, 0x92, 0x8C, 0x46,
- 0xE5, 0xA4, 0xA7, 0xE6, 0xAD, 0xA3, 0x46, 0xE5,
- 0xB9, 0xB3, 0xE6, 0x88, 0x90, 0x46, 0xE6, 0x98,
- 0x8E, 0xE6, 0xB2, 0xBB, 0x46, 0xE6, 0x98, 0xAD,
- 0xE5, 0x92, 0x8C, 0x47, 0x72, 0x61, 0x64, 0xE2,
- 0x88, 0x95, 0x73, 0x47, 0xE3, 0x80, 0x94, 0x53,
- 0xE3, 0x80, 0x95, 0x48, 0x28, 0xE1, 0x84, 0x80,
- 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84,
- // Bytes 2740 - 277f
- 0x82, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1,
- 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28,
- 0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x29, 0x48,
- 0x28, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0x29,
- 0x48, 0x28, 0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1,
- 0x29, 0x48, 0x28, 0xE1, 0x84, 0x89, 0xE1, 0x85,
- 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8B, 0xE1,
- 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8C,
- // Bytes 2780 - 27bf
- 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84,
- 0x8C, 0xE1, 0x85, 0xAE, 0x29, 0x48, 0x28, 0xE1,
- 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28,
- 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x29, 0x48,
- 0x28, 0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x29,
- 0x48, 0x28, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1,
- 0x29, 0x48, 0x28, 0xE1, 0x84, 0x92, 0xE1, 0x85,
- 0xA1, 0x29, 0x48, 0x72, 0x61, 0x64, 0xE2, 0x88,
- // Bytes 27c0 - 27ff
- 0x95, 0x73, 0x32, 0x48, 0xD8, 0xA7, 0xD9, 0x83,
- 0xD8, 0xA8, 0xD8, 0xB1, 0x48, 0xD8, 0xA7, 0xD9,
- 0x84, 0xD9, 0x84, 0xD9, 0x87, 0x48, 0xD8, 0xB1,
- 0xD8, 0xB3, 0xD9, 0x88, 0xD9, 0x84, 0x48, 0xD8,
- 0xB1, 0xDB, 0x8C, 0xD8, 0xA7, 0xD9, 0x84, 0x48,
- 0xD8, 0xB5, 0xD9, 0x84, 0xD8, 0xB9, 0xD9, 0x85,
- 0x48, 0xD8, 0xB9, 0xD9, 0x84, 0xD9, 0x8A, 0xD9,
- 0x87, 0x48, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85,
- // Bytes 2800 - 283f
- 0xD8, 0xAF, 0x48, 0xD9, 0x88, 0xD8, 0xB3, 0xD9,
- 0x84, 0xD9, 0x85, 0x49, 0xE2, 0x80, 0xB2, 0xE2,
- 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x49, 0xE2, 0x80,
- 0xB5, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x49,
- 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88,
- 0xAB, 0x49, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE,
- 0xE2, 0x88, 0xAE, 0x49, 0xE3, 0x80, 0x94, 0xE4,
- 0xB8, 0x89, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80,
- // Bytes 2840 - 287f
- 0x94, 0xE4, 0xBA, 0x8C, 0xE3, 0x80, 0x95, 0x49,
- 0xE3, 0x80, 0x94, 0xE5, 0x8B, 0x9D, 0xE3, 0x80,
- 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE5, 0xAE, 0x89,
- 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE6,
- 0x89, 0x93, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80,
- 0x94, 0xE6, 0x95, 0x97, 0xE3, 0x80, 0x95, 0x49,
- 0xE3, 0x80, 0x94, 0xE6, 0x9C, 0xAC, 0xE3, 0x80,
- 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE7, 0x82, 0xB9,
- // Bytes 2880 - 28bf
- 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE7,
- 0x9B, 0x97, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x82,
- 0xA2, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49,
- 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
- 0x81, 0x49, 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0xA9,
- 0xE3, 0x83, 0xB3, 0x49, 0xE3, 0x82, 0xAA, 0xE3,
- 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0x49, 0xE3, 0x82,
- 0xAA, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0x49,
- // Bytes 28c0 - 28ff
- 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0xA4, 0xE3, 0x83,
- 0xAA, 0x49, 0xE3, 0x82, 0xB1, 0xE3, 0x83, 0xBC,
- 0xE3, 0x82, 0xB9, 0x49, 0xE3, 0x82, 0xB3, 0xE3,
- 0x83, 0xAB, 0xE3, 0x83, 0x8A, 0x49, 0xE3, 0x82,
- 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0x49,
- 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
- 0x88, 0x49, 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99,
- 0xE3, 0x82, 0xB7, 0x49, 0xE3, 0x83, 0x88, 0xE3,
- // Bytes 2900 - 293f
- 0x82, 0x99, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83,
- 0x8E, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x49,
- 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0xA4, 0xE3, 0x83,
- 0x84, 0x49, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99,
- 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83, 0x92, 0xE3,
- 0x82, 0x9A, 0xE3, 0x82, 0xB3, 0x49, 0xE3, 0x83,
- 0x95, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xB3, 0x49,
- 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82,
- // Bytes 2940 - 297f
- 0xBD, 0x49, 0xE3, 0x83, 0x98, 0xE3, 0x83, 0xAB,
- 0xE3, 0x83, 0x84, 0x49, 0xE3, 0x83, 0x9B, 0xE3,
- 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83,
- 0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xB3, 0x49,
- 0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x83,
- 0xAB, 0x49, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x83,
- 0xE3, 0x83, 0x8F, 0x49, 0xE3, 0x83, 0x9E, 0xE3,
- 0x83, 0xAB, 0xE3, 0x82, 0xAF, 0x49, 0xE3, 0x83,
- // Bytes 2980 - 29bf
- 0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49,
- 0xE3, 0x83, 0xA6, 0xE3, 0x82, 0xA2, 0xE3, 0x83,
- 0xB3, 0x49, 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83,
- 0xE3, 0x83, 0x88, 0x4C, 0xE2, 0x80, 0xB2, 0xE2,
- 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2,
- 0x4C, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2,
- 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0x4C, 0xE3, 0x82,
- 0xA2, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x95, 0xE3,
- // Bytes 29c0 - 29ff
- 0x82, 0xA1, 0x4C, 0xE3, 0x82, 0xA8, 0xE3, 0x83,
- 0xBC, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xBC, 0x4C,
- 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83,
- 0xAD, 0xE3, 0x83, 0xB3, 0x4C, 0xE3, 0x82, 0xAB,
- 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
- 0x9E, 0x4C, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xA9,
- 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x4C, 0xE3,
- 0x82, 0xAB, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAA,
- // Bytes 2a00 - 2a3f
- 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAD, 0xE3,
- 0x82, 0x99, 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xBC,
- 0x4C, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xA5, 0xE3,
- 0x83, 0xAA, 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82,
- 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3,
- 0x83, 0xA0, 0x4C, 0xE3, 0x82, 0xAF, 0xE3, 0x83,
- 0xAD, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x8D, 0x4C,
- 0xE3, 0x82, 0xB5, 0xE3, 0x82, 0xA4, 0xE3, 0x82,
- // Bytes 2a40 - 2a7f
- 0xAF, 0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x82, 0xBF,
- 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82,
- 0xB9, 0x4C, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A,
- 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x84, 0x4C, 0xE3,
- 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xAF,
- 0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x83, 0x95, 0xE3,
- 0x82, 0xA3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88,
- 0x4C, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, 0xE3,
- // Bytes 2a80 - 2abf
- 0x83, 0xBC, 0xE3, 0x82, 0xBF, 0x4C, 0xE3, 0x83,
- 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0x8B, 0xE3,
- 0x83, 0x92, 0x4C, 0xE3, 0x83, 0x98, 0xE3, 0x82,
- 0x9A, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0x4C,
- 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, 0xE3, 0x83,
- 0xAB, 0xE3, 0x83, 0x88, 0x4C, 0xE3, 0x83, 0x9E,
- 0xE3, 0x82, 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83,
- 0xAD, 0x4C, 0xE3, 0x83, 0x9F, 0xE3, 0x82, 0xAF,
- // Bytes 2ac0 - 2aff
- 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0x4C, 0xE3,
- 0x83, 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88,
- 0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x83, 0xAA, 0xE3,
- 0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB,
- 0x4C, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92, 0xE3,
- 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0x4C, 0xE6, 0xA0,
- 0xAA, 0xE5, 0xBC, 0x8F, 0xE4, 0xBC, 0x9A, 0xE7,
- 0xA4, 0xBE, 0x4E, 0x28, 0xE1, 0x84, 0x8B, 0xE1,
- // Bytes 2b00 - 2b3f
- 0x85, 0xA9, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xAE,
- 0x29, 0x4F, 0xD8, 0xAC, 0xD9, 0x84, 0x20, 0xD8,
- 0xAC, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x84, 0xD9,
- 0x87, 0x4F, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0x8F,
- 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
- 0x88, 0x4F, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xB3,
- 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82,
- 0xA2, 0x4F, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD,
- // Bytes 2b40 - 2b7f
- 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3, 0x83,
- 0x88, 0x4F, 0xE3, 0x82, 0xB5, 0xE3, 0x83, 0xB3,
- 0xE3, 0x83, 0x81, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
- 0xA0, 0x4F, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99,
- 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAC, 0xE3, 0x83,
- 0xAB, 0x4F, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0xAF,
- 0xE3, 0x82, 0xBF, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
- 0xAB, 0x4F, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A,
- // Bytes 2b80 - 2bbf
- 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
- 0x88, 0x4F, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0xB3,
- 0xE3, 0x82, 0xB7, 0xE3, 0x83, 0xA7, 0xE3, 0x83,
- 0xB3, 0x4F, 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB,
- 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x88, 0xE3, 0x83,
- 0xB3, 0x4F, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xBC,
- 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0xE3, 0x83,
- 0xAB, 0x51, 0x28, 0xE1, 0x84, 0x8B, 0xE1, 0x85,
- // Bytes 2bc0 - 2bff
- 0xA9, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA5, 0xE1,
- 0x86, 0xAB, 0x29, 0x52, 0xE3, 0x82, 0xAD, 0xE3,
- 0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xBF,
- 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0x52, 0xE3,
- 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x82, 0xAF,
- 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3, 0x83,
- 0xA0, 0x52, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD,
- 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
- // Bytes 2c00 - 2c3f
- 0x88, 0xE3, 0x83, 0xAB, 0x52, 0xE3, 0x82, 0xAF,
- 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3, 0x83,
- 0xA0, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x52,
- 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0xE3, 0x82,
- 0xBB, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xA4, 0xE3,
- 0x83, 0xAD, 0x52, 0xE3, 0x83, 0x8F, 0xE3, 0x82,
- 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xBB, 0xE3,
- 0x83, 0xB3, 0xE3, 0x83, 0x88, 0x52, 0xE3, 0x83,
- // Bytes 2c40 - 2c7f
- 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA2, 0xE3,
- 0x82, 0xB9, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB,
- 0x52, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0xE3,
- 0x83, 0x83, 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0xA7,
- 0xE3, 0x83, 0xAB, 0x52, 0xE3, 0x83, 0x9F, 0xE3,
- 0x83, 0xAA, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99,
- 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x52, 0xE3,
- 0x83, 0xAC, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88,
- // Bytes 2c80 - 2cbf
- 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0xE3, 0x83,
- 0xB3, 0x61, 0xD8, 0xB5, 0xD9, 0x84, 0xD9, 0x89,
- 0x20, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84, 0xD9,
- 0x87, 0x20, 0xD8, 0xB9, 0xD9, 0x84, 0xD9, 0x8A,
- 0xD9, 0x87, 0x20, 0xD9, 0x88, 0xD8, 0xB3, 0xD9,
- 0x84, 0xD9, 0x85, 0x06, 0xE0, 0xA7, 0x87, 0xE0,
- 0xA6, 0xBE, 0x01, 0x06, 0xE0, 0xA7, 0x87, 0xE0,
- 0xA7, 0x97, 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0,
- // Bytes 2cc0 - 2cff
- 0xAC, 0xBE, 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0,
- 0xAD, 0x96, 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0,
- 0xAD, 0x97, 0x01, 0x06, 0xE0, 0xAE, 0x92, 0xE0,
- 0xAF, 0x97, 0x01, 0x06, 0xE0, 0xAF, 0x86, 0xE0,
- 0xAE, 0xBE, 0x01, 0x06, 0xE0, 0xAF, 0x86, 0xE0,
- 0xAF, 0x97, 0x01, 0x06, 0xE0, 0xAF, 0x87, 0xE0,
- 0xAE, 0xBE, 0x01, 0x06, 0xE0, 0xB2, 0xBF, 0xE0,
- 0xB3, 0x95, 0x01, 0x06, 0xE0, 0xB3, 0x86, 0xE0,
- // Bytes 2d00 - 2d3f
- 0xB3, 0x95, 0x01, 0x06, 0xE0, 0xB3, 0x86, 0xE0,
- 0xB3, 0x96, 0x01, 0x06, 0xE0, 0xB5, 0x86, 0xE0,
- 0xB4, 0xBE, 0x01, 0x06, 0xE0, 0xB5, 0x86, 0xE0,
- 0xB5, 0x97, 0x01, 0x06, 0xE0, 0xB5, 0x87, 0xE0,
- 0xB4, 0xBE, 0x01, 0x06, 0xE0, 0xB7, 0x99, 0xE0,
- 0xB7, 0x9F, 0x01, 0x06, 0xE1, 0x80, 0xA5, 0xE1,
- 0x80, 0xAE, 0x01, 0x06, 0xE1, 0xAC, 0x85, 0xE1,
- 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x87, 0xE1,
- // Bytes 2d40 - 2d7f
- 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x89, 0xE1,
- 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x8B, 0xE1,
- 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x8D, 0xE1,
- 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x91, 0xE1,
- 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0xBA, 0xE1,
- 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0xBC, 0xE1,
- 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0xBE, 0xE1,
- 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0xBF, 0xE1,
- // Bytes 2d80 - 2dbf
- 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAD, 0x82, 0xE1,
- 0xAC, 0xB5, 0x01, 0x08, 0xF0, 0x91, 0x84, 0xB1,
- 0xF0, 0x91, 0x84, 0xA7, 0x01, 0x08, 0xF0, 0x91,
- 0x84, 0xB2, 0xF0, 0x91, 0x84, 0xA7, 0x01, 0x08,
- 0xF0, 0x91, 0x8D, 0x87, 0xF0, 0x91, 0x8C, 0xBE,
- 0x01, 0x08, 0xF0, 0x91, 0x8D, 0x87, 0xF0, 0x91,
- 0x8D, 0x97, 0x01, 0x08, 0xF0, 0x91, 0x92, 0xB9,
- 0xF0, 0x91, 0x92, 0xB0, 0x01, 0x08, 0xF0, 0x91,
- // Bytes 2dc0 - 2dff
- 0x92, 0xB9, 0xF0, 0x91, 0x92, 0xBA, 0x01, 0x08,
- 0xF0, 0x91, 0x92, 0xB9, 0xF0, 0x91, 0x92, 0xBD,
- 0x01, 0x08, 0xF0, 0x91, 0x96, 0xB8, 0xF0, 0x91,
- 0x96, 0xAF, 0x01, 0x08, 0xF0, 0x91, 0x96, 0xB9,
- 0xF0, 0x91, 0x96, 0xAF, 0x01, 0x08, 0xF0, 0x91,
- 0xA4, 0xB5, 0xF0, 0x91, 0xA4, 0xB0, 0x01, 0x09,
- 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0xE0, 0xB3,
- 0x95, 0x02, 0x09, 0xE0, 0xB7, 0x99, 0xE0, 0xB7,
- // Bytes 2e00 - 2e3f
- 0x8F, 0xE0, 0xB7, 0x8A, 0x16, 0x44, 0x44, 0x5A,
- 0xCC, 0x8C, 0xCD, 0x44, 0x44, 0x7A, 0xCC, 0x8C,
- 0xCD, 0x44, 0x64, 0x7A, 0xCC, 0x8C, 0xCD, 0x46,
- 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x93, 0xCD, 0x46,
- 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94, 0xCD, 0x46,
- 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x95, 0xB9, 0x46,
- 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- 0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- // Bytes 2e40 - 2e7f
- 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- 0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- 0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- 0xE1, 0x84, 0x89, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xAE, 0x01, 0x46,
- 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- // Bytes 2e80 - 2ebf
- 0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- 0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, 0x01, 0x46,
- 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, 0x01, 0x49,
- 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB, 0xE3, 0x82,
- 0x99, 0x11, 0x4C, 0xE1, 0x84, 0x8C, 0xE1, 0x85,
- 0xAE, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xB4, 0x01,
- // Bytes 2ec0 - 2eff
- 0x4C, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3,
- 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x11, 0x4C, 0xE3,
- 0x82, 0xB3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x9B,
- 0xE3, 0x82, 0x9A, 0x11, 0x4C, 0xE3, 0x83, 0xA4,
- 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x82,
- 0x99, 0x11, 0x4F, 0xE1, 0x84, 0x8E, 0xE1, 0x85,
- 0xA1, 0xE1, 0x86, 0xB7, 0xE1, 0x84, 0x80, 0xE1,
- 0x85, 0xA9, 0x01, 0x4F, 0xE3, 0x82, 0xA4, 0xE3,
- // Bytes 2f00 - 2f3f
- 0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xAF,
- 0xE3, 0x82, 0x99, 0x11, 0x4F, 0xE3, 0x82, 0xB7,
- 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82,
- 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x4F, 0xE3, 0x83,
- 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3,
- 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x11, 0x4F, 0xE3,
- 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3,
- 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x11, 0x52,
- // Bytes 2f40 - 2f7f
- 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9, 0xE3, 0x82,
- 0xAF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3,
- 0x82, 0x99, 0x11, 0x52, 0xE3, 0x83, 0x95, 0xE3,
- 0x82, 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83,
- 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x11, 0x86,
- 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0x01, 0x86,
- 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8F, 0x01, 0x03,
- 0x3C, 0xCC, 0xB8, 0x05, 0x03, 0x3D, 0xCC, 0xB8,
- // Bytes 2f80 - 2fbf
- 0x05, 0x03, 0x3E, 0xCC, 0xB8, 0x05, 0x03, 0x41,
- 0xCC, 0x80, 0xCD, 0x03, 0x41, 0xCC, 0x81, 0xCD,
- 0x03, 0x41, 0xCC, 0x83, 0xCD, 0x03, 0x41, 0xCC,
- 0x84, 0xCD, 0x03, 0x41, 0xCC, 0x89, 0xCD, 0x03,
- 0x41, 0xCC, 0x8C, 0xCD, 0x03, 0x41, 0xCC, 0x8F,
- 0xCD, 0x03, 0x41, 0xCC, 0x91, 0xCD, 0x03, 0x41,
- 0xCC, 0xA5, 0xB9, 0x03, 0x41, 0xCC, 0xA8, 0xA9,
- 0x03, 0x42, 0xCC, 0x87, 0xCD, 0x03, 0x42, 0xCC,
- // Bytes 2fc0 - 2fff
- 0xA3, 0xB9, 0x03, 0x42, 0xCC, 0xB1, 0xB9, 0x03,
- 0x43, 0xCC, 0x81, 0xCD, 0x03, 0x43, 0xCC, 0x82,
- 0xCD, 0x03, 0x43, 0xCC, 0x87, 0xCD, 0x03, 0x43,
- 0xCC, 0x8C, 0xCD, 0x03, 0x44, 0xCC, 0x87, 0xCD,
- 0x03, 0x44, 0xCC, 0x8C, 0xCD, 0x03, 0x44, 0xCC,
- 0xA3, 0xB9, 0x03, 0x44, 0xCC, 0xA7, 0xA9, 0x03,
- 0x44, 0xCC, 0xAD, 0xB9, 0x03, 0x44, 0xCC, 0xB1,
- 0xB9, 0x03, 0x45, 0xCC, 0x80, 0xCD, 0x03, 0x45,
- // Bytes 3000 - 303f
- 0xCC, 0x81, 0xCD, 0x03, 0x45, 0xCC, 0x83, 0xCD,
- 0x03, 0x45, 0xCC, 0x86, 0xCD, 0x03, 0x45, 0xCC,
- 0x87, 0xCD, 0x03, 0x45, 0xCC, 0x88, 0xCD, 0x03,
- 0x45, 0xCC, 0x89, 0xCD, 0x03, 0x45, 0xCC, 0x8C,
- 0xCD, 0x03, 0x45, 0xCC, 0x8F, 0xCD, 0x03, 0x45,
- 0xCC, 0x91, 0xCD, 0x03, 0x45, 0xCC, 0xA8, 0xA9,
- 0x03, 0x45, 0xCC, 0xAD, 0xB9, 0x03, 0x45, 0xCC,
- 0xB0, 0xB9, 0x03, 0x46, 0xCC, 0x87, 0xCD, 0x03,
- // Bytes 3040 - 307f
- 0x47, 0xCC, 0x81, 0xCD, 0x03, 0x47, 0xCC, 0x82,
- 0xCD, 0x03, 0x47, 0xCC, 0x84, 0xCD, 0x03, 0x47,
- 0xCC, 0x86, 0xCD, 0x03, 0x47, 0xCC, 0x87, 0xCD,
- 0x03, 0x47, 0xCC, 0x8C, 0xCD, 0x03, 0x47, 0xCC,
- 0xA7, 0xA9, 0x03, 0x48, 0xCC, 0x82, 0xCD, 0x03,
- 0x48, 0xCC, 0x87, 0xCD, 0x03, 0x48, 0xCC, 0x88,
- 0xCD, 0x03, 0x48, 0xCC, 0x8C, 0xCD, 0x03, 0x48,
- 0xCC, 0xA3, 0xB9, 0x03, 0x48, 0xCC, 0xA7, 0xA9,
- // Bytes 3080 - 30bf
- 0x03, 0x48, 0xCC, 0xAE, 0xB9, 0x03, 0x49, 0xCC,
- 0x80, 0xCD, 0x03, 0x49, 0xCC, 0x81, 0xCD, 0x03,
- 0x49, 0xCC, 0x82, 0xCD, 0x03, 0x49, 0xCC, 0x83,
- 0xCD, 0x03, 0x49, 0xCC, 0x84, 0xCD, 0x03, 0x49,
- 0xCC, 0x86, 0xCD, 0x03, 0x49, 0xCC, 0x87, 0xCD,
- 0x03, 0x49, 0xCC, 0x89, 0xCD, 0x03, 0x49, 0xCC,
- 0x8C, 0xCD, 0x03, 0x49, 0xCC, 0x8F, 0xCD, 0x03,
- 0x49, 0xCC, 0x91, 0xCD, 0x03, 0x49, 0xCC, 0xA3,
- // Bytes 30c0 - 30ff
- 0xB9, 0x03, 0x49, 0xCC, 0xA8, 0xA9, 0x03, 0x49,
- 0xCC, 0xB0, 0xB9, 0x03, 0x4A, 0xCC, 0x82, 0xCD,
- 0x03, 0x4B, 0xCC, 0x81, 0xCD, 0x03, 0x4B, 0xCC,
- 0x8C, 0xCD, 0x03, 0x4B, 0xCC, 0xA3, 0xB9, 0x03,
- 0x4B, 0xCC, 0xA7, 0xA9, 0x03, 0x4B, 0xCC, 0xB1,
- 0xB9, 0x03, 0x4C, 0xCC, 0x81, 0xCD, 0x03, 0x4C,
- 0xCC, 0x8C, 0xCD, 0x03, 0x4C, 0xCC, 0xA7, 0xA9,
- 0x03, 0x4C, 0xCC, 0xAD, 0xB9, 0x03, 0x4C, 0xCC,
- // Bytes 3100 - 313f
- 0xB1, 0xB9, 0x03, 0x4D, 0xCC, 0x81, 0xCD, 0x03,
- 0x4D, 0xCC, 0x87, 0xCD, 0x03, 0x4D, 0xCC, 0xA3,
- 0xB9, 0x03, 0x4E, 0xCC, 0x80, 0xCD, 0x03, 0x4E,
- 0xCC, 0x81, 0xCD, 0x03, 0x4E, 0xCC, 0x83, 0xCD,
- 0x03, 0x4E, 0xCC, 0x87, 0xCD, 0x03, 0x4E, 0xCC,
- 0x8C, 0xCD, 0x03, 0x4E, 0xCC, 0xA3, 0xB9, 0x03,
- 0x4E, 0xCC, 0xA7, 0xA9, 0x03, 0x4E, 0xCC, 0xAD,
- 0xB9, 0x03, 0x4E, 0xCC, 0xB1, 0xB9, 0x03, 0x4F,
- // Bytes 3140 - 317f
- 0xCC, 0x80, 0xCD, 0x03, 0x4F, 0xCC, 0x81, 0xCD,
- 0x03, 0x4F, 0xCC, 0x86, 0xCD, 0x03, 0x4F, 0xCC,
- 0x89, 0xCD, 0x03, 0x4F, 0xCC, 0x8B, 0xCD, 0x03,
- 0x4F, 0xCC, 0x8C, 0xCD, 0x03, 0x4F, 0xCC, 0x8F,
- 0xCD, 0x03, 0x4F, 0xCC, 0x91, 0xCD, 0x03, 0x50,
- 0xCC, 0x81, 0xCD, 0x03, 0x50, 0xCC, 0x87, 0xCD,
- 0x03, 0x52, 0xCC, 0x81, 0xCD, 0x03, 0x52, 0xCC,
- 0x87, 0xCD, 0x03, 0x52, 0xCC, 0x8C, 0xCD, 0x03,
- // Bytes 3180 - 31bf
- 0x52, 0xCC, 0x8F, 0xCD, 0x03, 0x52, 0xCC, 0x91,
- 0xCD, 0x03, 0x52, 0xCC, 0xA7, 0xA9, 0x03, 0x52,
- 0xCC, 0xB1, 0xB9, 0x03, 0x53, 0xCC, 0x82, 0xCD,
- 0x03, 0x53, 0xCC, 0x87, 0xCD, 0x03, 0x53, 0xCC,
- 0xA6, 0xB9, 0x03, 0x53, 0xCC, 0xA7, 0xA9, 0x03,
- 0x54, 0xCC, 0x87, 0xCD, 0x03, 0x54, 0xCC, 0x8C,
- 0xCD, 0x03, 0x54, 0xCC, 0xA3, 0xB9, 0x03, 0x54,
- 0xCC, 0xA6, 0xB9, 0x03, 0x54, 0xCC, 0xA7, 0xA9,
- // Bytes 31c0 - 31ff
- 0x03, 0x54, 0xCC, 0xAD, 0xB9, 0x03, 0x54, 0xCC,
- 0xB1, 0xB9, 0x03, 0x55, 0xCC, 0x80, 0xCD, 0x03,
- 0x55, 0xCC, 0x81, 0xCD, 0x03, 0x55, 0xCC, 0x82,
- 0xCD, 0x03, 0x55, 0xCC, 0x86, 0xCD, 0x03, 0x55,
- 0xCC, 0x89, 0xCD, 0x03, 0x55, 0xCC, 0x8A, 0xCD,
- 0x03, 0x55, 0xCC, 0x8B, 0xCD, 0x03, 0x55, 0xCC,
- 0x8C, 0xCD, 0x03, 0x55, 0xCC, 0x8F, 0xCD, 0x03,
- 0x55, 0xCC, 0x91, 0xCD, 0x03, 0x55, 0xCC, 0xA3,
- // Bytes 3200 - 323f
- 0xB9, 0x03, 0x55, 0xCC, 0xA4, 0xB9, 0x03, 0x55,
- 0xCC, 0xA8, 0xA9, 0x03, 0x55, 0xCC, 0xAD, 0xB9,
- 0x03, 0x55, 0xCC, 0xB0, 0xB9, 0x03, 0x56, 0xCC,
- 0x83, 0xCD, 0x03, 0x56, 0xCC, 0xA3, 0xB9, 0x03,
- 0x57, 0xCC, 0x80, 0xCD, 0x03, 0x57, 0xCC, 0x81,
- 0xCD, 0x03, 0x57, 0xCC, 0x82, 0xCD, 0x03, 0x57,
- 0xCC, 0x87, 0xCD, 0x03, 0x57, 0xCC, 0x88, 0xCD,
- 0x03, 0x57, 0xCC, 0xA3, 0xB9, 0x03, 0x58, 0xCC,
- // Bytes 3240 - 327f
- 0x87, 0xCD, 0x03, 0x58, 0xCC, 0x88, 0xCD, 0x03,
- 0x59, 0xCC, 0x80, 0xCD, 0x03, 0x59, 0xCC, 0x81,
- 0xCD, 0x03, 0x59, 0xCC, 0x82, 0xCD, 0x03, 0x59,
- 0xCC, 0x83, 0xCD, 0x03, 0x59, 0xCC, 0x84, 0xCD,
- 0x03, 0x59, 0xCC, 0x87, 0xCD, 0x03, 0x59, 0xCC,
- 0x88, 0xCD, 0x03, 0x59, 0xCC, 0x89, 0xCD, 0x03,
- 0x59, 0xCC, 0xA3, 0xB9, 0x03, 0x5A, 0xCC, 0x81,
- 0xCD, 0x03, 0x5A, 0xCC, 0x82, 0xCD, 0x03, 0x5A,
- // Bytes 3280 - 32bf
- 0xCC, 0x87, 0xCD, 0x03, 0x5A, 0xCC, 0x8C, 0xCD,
- 0x03, 0x5A, 0xCC, 0xA3, 0xB9, 0x03, 0x5A, 0xCC,
- 0xB1, 0xB9, 0x03, 0x61, 0xCC, 0x80, 0xCD, 0x03,
- 0x61, 0xCC, 0x81, 0xCD, 0x03, 0x61, 0xCC, 0x83,
- 0xCD, 0x03, 0x61, 0xCC, 0x84, 0xCD, 0x03, 0x61,
- 0xCC, 0x89, 0xCD, 0x03, 0x61, 0xCC, 0x8C, 0xCD,
- 0x03, 0x61, 0xCC, 0x8F, 0xCD, 0x03, 0x61, 0xCC,
- 0x91, 0xCD, 0x03, 0x61, 0xCC, 0xA5, 0xB9, 0x03,
- // Bytes 32c0 - 32ff
- 0x61, 0xCC, 0xA8, 0xA9, 0x03, 0x62, 0xCC, 0x87,
- 0xCD, 0x03, 0x62, 0xCC, 0xA3, 0xB9, 0x03, 0x62,
- 0xCC, 0xB1, 0xB9, 0x03, 0x63, 0xCC, 0x81, 0xCD,
- 0x03, 0x63, 0xCC, 0x82, 0xCD, 0x03, 0x63, 0xCC,
- 0x87, 0xCD, 0x03, 0x63, 0xCC, 0x8C, 0xCD, 0x03,
- 0x64, 0xCC, 0x87, 0xCD, 0x03, 0x64, 0xCC, 0x8C,
- 0xCD, 0x03, 0x64, 0xCC, 0xA3, 0xB9, 0x03, 0x64,
- 0xCC, 0xA7, 0xA9, 0x03, 0x64, 0xCC, 0xAD, 0xB9,
- // Bytes 3300 - 333f
- 0x03, 0x64, 0xCC, 0xB1, 0xB9, 0x03, 0x65, 0xCC,
- 0x80, 0xCD, 0x03, 0x65, 0xCC, 0x81, 0xCD, 0x03,
- 0x65, 0xCC, 0x83, 0xCD, 0x03, 0x65, 0xCC, 0x86,
- 0xCD, 0x03, 0x65, 0xCC, 0x87, 0xCD, 0x03, 0x65,
- 0xCC, 0x88, 0xCD, 0x03, 0x65, 0xCC, 0x89, 0xCD,
- 0x03, 0x65, 0xCC, 0x8C, 0xCD, 0x03, 0x65, 0xCC,
- 0x8F, 0xCD, 0x03, 0x65, 0xCC, 0x91, 0xCD, 0x03,
- 0x65, 0xCC, 0xA8, 0xA9, 0x03, 0x65, 0xCC, 0xAD,
- // Bytes 3340 - 337f
- 0xB9, 0x03, 0x65, 0xCC, 0xB0, 0xB9, 0x03, 0x66,
- 0xCC, 0x87, 0xCD, 0x03, 0x67, 0xCC, 0x81, 0xCD,
- 0x03, 0x67, 0xCC, 0x82, 0xCD, 0x03, 0x67, 0xCC,
- 0x84, 0xCD, 0x03, 0x67, 0xCC, 0x86, 0xCD, 0x03,
- 0x67, 0xCC, 0x87, 0xCD, 0x03, 0x67, 0xCC, 0x8C,
- 0xCD, 0x03, 0x67, 0xCC, 0xA7, 0xA9, 0x03, 0x68,
- 0xCC, 0x82, 0xCD, 0x03, 0x68, 0xCC, 0x87, 0xCD,
- 0x03, 0x68, 0xCC, 0x88, 0xCD, 0x03, 0x68, 0xCC,
- // Bytes 3380 - 33bf
- 0x8C, 0xCD, 0x03, 0x68, 0xCC, 0xA3, 0xB9, 0x03,
- 0x68, 0xCC, 0xA7, 0xA9, 0x03, 0x68, 0xCC, 0xAE,
- 0xB9, 0x03, 0x68, 0xCC, 0xB1, 0xB9, 0x03, 0x69,
- 0xCC, 0x80, 0xCD, 0x03, 0x69, 0xCC, 0x81, 0xCD,
- 0x03, 0x69, 0xCC, 0x82, 0xCD, 0x03, 0x69, 0xCC,
- 0x83, 0xCD, 0x03, 0x69, 0xCC, 0x84, 0xCD, 0x03,
- 0x69, 0xCC, 0x86, 0xCD, 0x03, 0x69, 0xCC, 0x89,
- 0xCD, 0x03, 0x69, 0xCC, 0x8C, 0xCD, 0x03, 0x69,
- // Bytes 33c0 - 33ff
- 0xCC, 0x8F, 0xCD, 0x03, 0x69, 0xCC, 0x91, 0xCD,
- 0x03, 0x69, 0xCC, 0xA3, 0xB9, 0x03, 0x69, 0xCC,
- 0xA8, 0xA9, 0x03, 0x69, 0xCC, 0xB0, 0xB9, 0x03,
- 0x6A, 0xCC, 0x82, 0xCD, 0x03, 0x6A, 0xCC, 0x8C,
- 0xCD, 0x03, 0x6B, 0xCC, 0x81, 0xCD, 0x03, 0x6B,
- 0xCC, 0x8C, 0xCD, 0x03, 0x6B, 0xCC, 0xA3, 0xB9,
- 0x03, 0x6B, 0xCC, 0xA7, 0xA9, 0x03, 0x6B, 0xCC,
- 0xB1, 0xB9, 0x03, 0x6C, 0xCC, 0x81, 0xCD, 0x03,
- // Bytes 3400 - 343f
- 0x6C, 0xCC, 0x8C, 0xCD, 0x03, 0x6C, 0xCC, 0xA7,
- 0xA9, 0x03, 0x6C, 0xCC, 0xAD, 0xB9, 0x03, 0x6C,
- 0xCC, 0xB1, 0xB9, 0x03, 0x6D, 0xCC, 0x81, 0xCD,
- 0x03, 0x6D, 0xCC, 0x87, 0xCD, 0x03, 0x6D, 0xCC,
- 0xA3, 0xB9, 0x03, 0x6E, 0xCC, 0x80, 0xCD, 0x03,
- 0x6E, 0xCC, 0x81, 0xCD, 0x03, 0x6E, 0xCC, 0x83,
- 0xCD, 0x03, 0x6E, 0xCC, 0x87, 0xCD, 0x03, 0x6E,
- 0xCC, 0x8C, 0xCD, 0x03, 0x6E, 0xCC, 0xA3, 0xB9,
- // Bytes 3440 - 347f
- 0x03, 0x6E, 0xCC, 0xA7, 0xA9, 0x03, 0x6E, 0xCC,
- 0xAD, 0xB9, 0x03, 0x6E, 0xCC, 0xB1, 0xB9, 0x03,
- 0x6F, 0xCC, 0x80, 0xCD, 0x03, 0x6F, 0xCC, 0x81,
- 0xCD, 0x03, 0x6F, 0xCC, 0x86, 0xCD, 0x03, 0x6F,
- 0xCC, 0x89, 0xCD, 0x03, 0x6F, 0xCC, 0x8B, 0xCD,
- 0x03, 0x6F, 0xCC, 0x8C, 0xCD, 0x03, 0x6F, 0xCC,
- 0x8F, 0xCD, 0x03, 0x6F, 0xCC, 0x91, 0xCD, 0x03,
- 0x70, 0xCC, 0x81, 0xCD, 0x03, 0x70, 0xCC, 0x87,
- // Bytes 3480 - 34bf
- 0xCD, 0x03, 0x72, 0xCC, 0x81, 0xCD, 0x03, 0x72,
- 0xCC, 0x87, 0xCD, 0x03, 0x72, 0xCC, 0x8C, 0xCD,
- 0x03, 0x72, 0xCC, 0x8F, 0xCD, 0x03, 0x72, 0xCC,
- 0x91, 0xCD, 0x03, 0x72, 0xCC, 0xA7, 0xA9, 0x03,
- 0x72, 0xCC, 0xB1, 0xB9, 0x03, 0x73, 0xCC, 0x82,
- 0xCD, 0x03, 0x73, 0xCC, 0x87, 0xCD, 0x03, 0x73,
- 0xCC, 0xA6, 0xB9, 0x03, 0x73, 0xCC, 0xA7, 0xA9,
- 0x03, 0x74, 0xCC, 0x87, 0xCD, 0x03, 0x74, 0xCC,
- // Bytes 34c0 - 34ff
- 0x88, 0xCD, 0x03, 0x74, 0xCC, 0x8C, 0xCD, 0x03,
- 0x74, 0xCC, 0xA3, 0xB9, 0x03, 0x74, 0xCC, 0xA6,
- 0xB9, 0x03, 0x74, 0xCC, 0xA7, 0xA9, 0x03, 0x74,
- 0xCC, 0xAD, 0xB9, 0x03, 0x74, 0xCC, 0xB1, 0xB9,
- 0x03, 0x75, 0xCC, 0x80, 0xCD, 0x03, 0x75, 0xCC,
- 0x81, 0xCD, 0x03, 0x75, 0xCC, 0x82, 0xCD, 0x03,
- 0x75, 0xCC, 0x86, 0xCD, 0x03, 0x75, 0xCC, 0x89,
- 0xCD, 0x03, 0x75, 0xCC, 0x8A, 0xCD, 0x03, 0x75,
- // Bytes 3500 - 353f
- 0xCC, 0x8B, 0xCD, 0x03, 0x75, 0xCC, 0x8C, 0xCD,
- 0x03, 0x75, 0xCC, 0x8F, 0xCD, 0x03, 0x75, 0xCC,
- 0x91, 0xCD, 0x03, 0x75, 0xCC, 0xA3, 0xB9, 0x03,
- 0x75, 0xCC, 0xA4, 0xB9, 0x03, 0x75, 0xCC, 0xA8,
- 0xA9, 0x03, 0x75, 0xCC, 0xAD, 0xB9, 0x03, 0x75,
- 0xCC, 0xB0, 0xB9, 0x03, 0x76, 0xCC, 0x83, 0xCD,
- 0x03, 0x76, 0xCC, 0xA3, 0xB9, 0x03, 0x77, 0xCC,
- 0x80, 0xCD, 0x03, 0x77, 0xCC, 0x81, 0xCD, 0x03,
- // Bytes 3540 - 357f
- 0x77, 0xCC, 0x82, 0xCD, 0x03, 0x77, 0xCC, 0x87,
- 0xCD, 0x03, 0x77, 0xCC, 0x88, 0xCD, 0x03, 0x77,
- 0xCC, 0x8A, 0xCD, 0x03, 0x77, 0xCC, 0xA3, 0xB9,
- 0x03, 0x78, 0xCC, 0x87, 0xCD, 0x03, 0x78, 0xCC,
- 0x88, 0xCD, 0x03, 0x79, 0xCC, 0x80, 0xCD, 0x03,
- 0x79, 0xCC, 0x81, 0xCD, 0x03, 0x79, 0xCC, 0x82,
- 0xCD, 0x03, 0x79, 0xCC, 0x83, 0xCD, 0x03, 0x79,
- 0xCC, 0x84, 0xCD, 0x03, 0x79, 0xCC, 0x87, 0xCD,
- // Bytes 3580 - 35bf
- 0x03, 0x79, 0xCC, 0x88, 0xCD, 0x03, 0x79, 0xCC,
- 0x89, 0xCD, 0x03, 0x79, 0xCC, 0x8A, 0xCD, 0x03,
- 0x79, 0xCC, 0xA3, 0xB9, 0x03, 0x7A, 0xCC, 0x81,
- 0xCD, 0x03, 0x7A, 0xCC, 0x82, 0xCD, 0x03, 0x7A,
- 0xCC, 0x87, 0xCD, 0x03, 0x7A, 0xCC, 0x8C, 0xCD,
- 0x03, 0x7A, 0xCC, 0xA3, 0xB9, 0x03, 0x7A, 0xCC,
- 0xB1, 0xB9, 0x04, 0xC2, 0xA8, 0xCC, 0x80, 0xCE,
- 0x04, 0xC2, 0xA8, 0xCC, 0x81, 0xCE, 0x04, 0xC2,
- // Bytes 35c0 - 35ff
- 0xA8, 0xCD, 0x82, 0xCE, 0x04, 0xC3, 0x86, 0xCC,
- 0x81, 0xCD, 0x04, 0xC3, 0x86, 0xCC, 0x84, 0xCD,
- 0x04, 0xC3, 0x98, 0xCC, 0x81, 0xCD, 0x04, 0xC3,
- 0xA6, 0xCC, 0x81, 0xCD, 0x04, 0xC3, 0xA6, 0xCC,
- 0x84, 0xCD, 0x04, 0xC3, 0xB8, 0xCC, 0x81, 0xCD,
- 0x04, 0xC5, 0xBF, 0xCC, 0x87, 0xCD, 0x04, 0xC6,
- 0xB7, 0xCC, 0x8C, 0xCD, 0x04, 0xCA, 0x92, 0xCC,
- 0x8C, 0xCD, 0x04, 0xCE, 0x91, 0xCC, 0x80, 0xCD,
- // Bytes 3600 - 363f
- 0x04, 0xCE, 0x91, 0xCC, 0x81, 0xCD, 0x04, 0xCE,
- 0x91, 0xCC, 0x84, 0xCD, 0x04, 0xCE, 0x91, 0xCC,
- 0x86, 0xCD, 0x04, 0xCE, 0x91, 0xCD, 0x85, 0xDD,
- 0x04, 0xCE, 0x95, 0xCC, 0x80, 0xCD, 0x04, 0xCE,
- 0x95, 0xCC, 0x81, 0xCD, 0x04, 0xCE, 0x97, 0xCC,
- 0x80, 0xCD, 0x04, 0xCE, 0x97, 0xCC, 0x81, 0xCD,
- 0x04, 0xCE, 0x97, 0xCD, 0x85, 0xDD, 0x04, 0xCE,
- 0x99, 0xCC, 0x80, 0xCD, 0x04, 0xCE, 0x99, 0xCC,
- // Bytes 3640 - 367f
- 0x81, 0xCD, 0x04, 0xCE, 0x99, 0xCC, 0x84, 0xCD,
- 0x04, 0xCE, 0x99, 0xCC, 0x86, 0xCD, 0x04, 0xCE,
- 0x99, 0xCC, 0x88, 0xCD, 0x04, 0xCE, 0x9F, 0xCC,
- 0x80, 0xCD, 0x04, 0xCE, 0x9F, 0xCC, 0x81, 0xCD,
- 0x04, 0xCE, 0xA1, 0xCC, 0x94, 0xCD, 0x04, 0xCE,
- 0xA5, 0xCC, 0x80, 0xCD, 0x04, 0xCE, 0xA5, 0xCC,
- 0x81, 0xCD, 0x04, 0xCE, 0xA5, 0xCC, 0x84, 0xCD,
- 0x04, 0xCE, 0xA5, 0xCC, 0x86, 0xCD, 0x04, 0xCE,
- // Bytes 3680 - 36bf
- 0xA5, 0xCC, 0x88, 0xCD, 0x04, 0xCE, 0xA9, 0xCC,
- 0x80, 0xCD, 0x04, 0xCE, 0xA9, 0xCC, 0x81, 0xCD,
- 0x04, 0xCE, 0xA9, 0xCD, 0x85, 0xDD, 0x04, 0xCE,
- 0xB1, 0xCC, 0x84, 0xCD, 0x04, 0xCE, 0xB1, 0xCC,
- 0x86, 0xCD, 0x04, 0xCE, 0xB1, 0xCD, 0x85, 0xDD,
- 0x04, 0xCE, 0xB5, 0xCC, 0x80, 0xCD, 0x04, 0xCE,
- 0xB5, 0xCC, 0x81, 0xCD, 0x04, 0xCE, 0xB7, 0xCD,
- 0x85, 0xDD, 0x04, 0xCE, 0xB9, 0xCC, 0x80, 0xCD,
- // Bytes 36c0 - 36ff
- 0x04, 0xCE, 0xB9, 0xCC, 0x81, 0xCD, 0x04, 0xCE,
- 0xB9, 0xCC, 0x84, 0xCD, 0x04, 0xCE, 0xB9, 0xCC,
- 0x86, 0xCD, 0x04, 0xCE, 0xB9, 0xCD, 0x82, 0xCD,
- 0x04, 0xCE, 0xBF, 0xCC, 0x80, 0xCD, 0x04, 0xCE,
- 0xBF, 0xCC, 0x81, 0xCD, 0x04, 0xCF, 0x81, 0xCC,
- 0x93, 0xCD, 0x04, 0xCF, 0x81, 0xCC, 0x94, 0xCD,
- 0x04, 0xCF, 0x85, 0xCC, 0x80, 0xCD, 0x04, 0xCF,
- 0x85, 0xCC, 0x81, 0xCD, 0x04, 0xCF, 0x85, 0xCC,
- // Bytes 3700 - 373f
- 0x84, 0xCD, 0x04, 0xCF, 0x85, 0xCC, 0x86, 0xCD,
- 0x04, 0xCF, 0x85, 0xCD, 0x82, 0xCD, 0x04, 0xCF,
- 0x89, 0xCD, 0x85, 0xDD, 0x04, 0xCF, 0x92, 0xCC,
- 0x81, 0xCD, 0x04, 0xCF, 0x92, 0xCC, 0x88, 0xCD,
- 0x04, 0xD0, 0x86, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
- 0x90, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0x90, 0xCC,
- 0x88, 0xCD, 0x04, 0xD0, 0x93, 0xCC, 0x81, 0xCD,
- 0x04, 0xD0, 0x95, 0xCC, 0x80, 0xCD, 0x04, 0xD0,
- // Bytes 3740 - 377f
- 0x95, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0x95, 0xCC,
- 0x88, 0xCD, 0x04, 0xD0, 0x96, 0xCC, 0x86, 0xCD,
- 0x04, 0xD0, 0x96, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
- 0x97, 0xCC, 0x88, 0xCD, 0x04, 0xD0, 0x98, 0xCC,
- 0x80, 0xCD, 0x04, 0xD0, 0x98, 0xCC, 0x84, 0xCD,
- 0x04, 0xD0, 0x98, 0xCC, 0x86, 0xCD, 0x04, 0xD0,
- 0x98, 0xCC, 0x88, 0xCD, 0x04, 0xD0, 0x9A, 0xCC,
- 0x81, 0xCD, 0x04, 0xD0, 0x9E, 0xCC, 0x88, 0xCD,
- // Bytes 3780 - 37bf
- 0x04, 0xD0, 0xA3, 0xCC, 0x84, 0xCD, 0x04, 0xD0,
- 0xA3, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0xA3, 0xCC,
- 0x88, 0xCD, 0x04, 0xD0, 0xA3, 0xCC, 0x8B, 0xCD,
- 0x04, 0xD0, 0xA7, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
- 0xAB, 0xCC, 0x88, 0xCD, 0x04, 0xD0, 0xAD, 0xCC,
- 0x88, 0xCD, 0x04, 0xD0, 0xB0, 0xCC, 0x86, 0xCD,
- 0x04, 0xD0, 0xB0, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
- 0xB3, 0xCC, 0x81, 0xCD, 0x04, 0xD0, 0xB5, 0xCC,
- // Bytes 37c0 - 37ff
- 0x80, 0xCD, 0x04, 0xD0, 0xB5, 0xCC, 0x86, 0xCD,
- 0x04, 0xD0, 0xB5, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
- 0xB6, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0xB6, 0xCC,
- 0x88, 0xCD, 0x04, 0xD0, 0xB7, 0xCC, 0x88, 0xCD,
- 0x04, 0xD0, 0xB8, 0xCC, 0x80, 0xCD, 0x04, 0xD0,
- 0xB8, 0xCC, 0x84, 0xCD, 0x04, 0xD0, 0xB8, 0xCC,
- 0x86, 0xCD, 0x04, 0xD0, 0xB8, 0xCC, 0x88, 0xCD,
- 0x04, 0xD0, 0xBA, 0xCC, 0x81, 0xCD, 0x04, 0xD0,
- // Bytes 3800 - 383f
- 0xBE, 0xCC, 0x88, 0xCD, 0x04, 0xD1, 0x83, 0xCC,
- 0x84, 0xCD, 0x04, 0xD1, 0x83, 0xCC, 0x86, 0xCD,
- 0x04, 0xD1, 0x83, 0xCC, 0x88, 0xCD, 0x04, 0xD1,
- 0x83, 0xCC, 0x8B, 0xCD, 0x04, 0xD1, 0x87, 0xCC,
- 0x88, 0xCD, 0x04, 0xD1, 0x8B, 0xCC, 0x88, 0xCD,
- 0x04, 0xD1, 0x8D, 0xCC, 0x88, 0xCD, 0x04, 0xD1,
- 0x96, 0xCC, 0x88, 0xCD, 0x04, 0xD1, 0xB4, 0xCC,
- 0x8F, 0xCD, 0x04, 0xD1, 0xB5, 0xCC, 0x8F, 0xCD,
- // Bytes 3840 - 387f
- 0x04, 0xD3, 0x98, 0xCC, 0x88, 0xCD, 0x04, 0xD3,
- 0x99, 0xCC, 0x88, 0xCD, 0x04, 0xD3, 0xA8, 0xCC,
- 0x88, 0xCD, 0x04, 0xD3, 0xA9, 0xCC, 0x88, 0xCD,
- 0x04, 0xD8, 0xA7, 0xD9, 0x93, 0xCD, 0x04, 0xD8,
- 0xA7, 0xD9, 0x94, 0xCD, 0x04, 0xD8, 0xA7, 0xD9,
- 0x95, 0xB9, 0x04, 0xD9, 0x88, 0xD9, 0x94, 0xCD,
- 0x04, 0xD9, 0x8A, 0xD9, 0x94, 0xCD, 0x04, 0xDB,
- 0x81, 0xD9, 0x94, 0xCD, 0x04, 0xDB, 0x92, 0xD9,
- // Bytes 3880 - 38bf
- 0x94, 0xCD, 0x04, 0xDB, 0x95, 0xD9, 0x94, 0xCD,
- 0x05, 0x41, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05,
- 0x41, 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x41,
- 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x41, 0xCC,
- 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x41, 0xCC, 0x86,
- 0xCC, 0x80, 0xCE, 0x05, 0x41, 0xCC, 0x86, 0xCC,
- 0x81, 0xCE, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x83,
- 0xCE, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x89, 0xCE,
- // Bytes 38c0 - 38ff
- 0x05, 0x41, 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05,
- 0x41, 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x41,
- 0xCC, 0x8A, 0xCC, 0x81, 0xCE, 0x05, 0x41, 0xCC,
- 0xA3, 0xCC, 0x82, 0xCE, 0x05, 0x41, 0xCC, 0xA3,
- 0xCC, 0x86, 0xCE, 0x05, 0x43, 0xCC, 0xA7, 0xCC,
- 0x81, 0xCE, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x80,
- 0xCE, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x81, 0xCE,
- 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05,
- // Bytes 3900 - 393f
- 0x45, 0xCC, 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x45,
- 0xCC, 0x84, 0xCC, 0x80, 0xCE, 0x05, 0x45, 0xCC,
- 0x84, 0xCC, 0x81, 0xCE, 0x05, 0x45, 0xCC, 0xA3,
- 0xCC, 0x82, 0xCE, 0x05, 0x45, 0xCC, 0xA7, 0xCC,
- 0x86, 0xCE, 0x05, 0x49, 0xCC, 0x88, 0xCC, 0x81,
- 0xCE, 0x05, 0x4C, 0xCC, 0xA3, 0xCC, 0x84, 0xCE,
- 0x05, 0x4F, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05,
- 0x4F, 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x4F,
- // Bytes 3940 - 397f
- 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x4F, 0xCC,
- 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x4F, 0xCC, 0x83,
- 0xCC, 0x81, 0xCE, 0x05, 0x4F, 0xCC, 0x83, 0xCC,
- 0x84, 0xCE, 0x05, 0x4F, 0xCC, 0x83, 0xCC, 0x88,
- 0xCE, 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x80, 0xCE,
- 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x81, 0xCE, 0x05,
- 0x4F, 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, 0x4F,
- 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x4F, 0xCC,
- // Bytes 3980 - 39bf
- 0x9B, 0xCC, 0x80, 0xCE, 0x05, 0x4F, 0xCC, 0x9B,
- 0xCC, 0x81, 0xCE, 0x05, 0x4F, 0xCC, 0x9B, 0xCC,
- 0x83, 0xCE, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0x89,
- 0xCE, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA,
- 0x05, 0x4F, 0xCC, 0xA3, 0xCC, 0x82, 0xCE, 0x05,
- 0x4F, 0xCC, 0xA8, 0xCC, 0x84, 0xCE, 0x05, 0x52,
- 0xCC, 0xA3, 0xCC, 0x84, 0xCE, 0x05, 0x53, 0xCC,
- 0x81, 0xCC, 0x87, 0xCE, 0x05, 0x53, 0xCC, 0x8C,
- // Bytes 39c0 - 39ff
- 0xCC, 0x87, 0xCE, 0x05, 0x53, 0xCC, 0xA3, 0xCC,
- 0x87, 0xCE, 0x05, 0x55, 0xCC, 0x83, 0xCC, 0x81,
- 0xCE, 0x05, 0x55, 0xCC, 0x84, 0xCC, 0x88, 0xCE,
- 0x05, 0x55, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x05,
- 0x55, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x05, 0x55,
- 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x55, 0xCC,
- 0x88, 0xCC, 0x8C, 0xCE, 0x05, 0x55, 0xCC, 0x9B,
- 0xCC, 0x80, 0xCE, 0x05, 0x55, 0xCC, 0x9B, 0xCC,
- // Bytes 3a00 - 3a3f
- 0x81, 0xCE, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x83,
- 0xCE, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x89, 0xCE,
- 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, 0x05,
- 0x61, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05, 0x61,
- 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x61, 0xCC,
- 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x61, 0xCC, 0x82,
- 0xCC, 0x89, 0xCE, 0x05, 0x61, 0xCC, 0x86, 0xCC,
- 0x80, 0xCE, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x81,
- // Bytes 3a40 - 3a7f
- 0xCE, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x83, 0xCE,
- 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x89, 0xCE, 0x05,
- 0x61, 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, 0x61,
- 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x61, 0xCC,
- 0x8A, 0xCC, 0x81, 0xCE, 0x05, 0x61, 0xCC, 0xA3,
- 0xCC, 0x82, 0xCE, 0x05, 0x61, 0xCC, 0xA3, 0xCC,
- 0x86, 0xCE, 0x05, 0x63, 0xCC, 0xA7, 0xCC, 0x81,
- 0xCE, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x80, 0xCE,
- // Bytes 3a80 - 3abf
- 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05,
- 0x65, 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x65,
- 0xCC, 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x65, 0xCC,
- 0x84, 0xCC, 0x80, 0xCE, 0x05, 0x65, 0xCC, 0x84,
- 0xCC, 0x81, 0xCE, 0x05, 0x65, 0xCC, 0xA3, 0xCC,
- 0x82, 0xCE, 0x05, 0x65, 0xCC, 0xA7, 0xCC, 0x86,
- 0xCE, 0x05, 0x69, 0xCC, 0x88, 0xCC, 0x81, 0xCE,
- 0x05, 0x6C, 0xCC, 0xA3, 0xCC, 0x84, 0xCE, 0x05,
- // Bytes 3ac0 - 3aff
- 0x6F, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05, 0x6F,
- 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x6F, 0xCC,
- 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x6F, 0xCC, 0x82,
- 0xCC, 0x89, 0xCE, 0x05, 0x6F, 0xCC, 0x83, 0xCC,
- 0x81, 0xCE, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x84,
- 0xCE, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x88, 0xCE,
- 0x05, 0x6F, 0xCC, 0x84, 0xCC, 0x80, 0xCE, 0x05,
- 0x6F, 0xCC, 0x84, 0xCC, 0x81, 0xCE, 0x05, 0x6F,
- // Bytes 3b00 - 3b3f
- 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, 0x6F, 0xCC,
- 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x6F, 0xCC, 0x9B,
- 0xCC, 0x80, 0xCE, 0x05, 0x6F, 0xCC, 0x9B, 0xCC,
- 0x81, 0xCE, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x83,
- 0xCE, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x89, 0xCE,
- 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, 0x05,
- 0x6F, 0xCC, 0xA3, 0xCC, 0x82, 0xCE, 0x05, 0x6F,
- 0xCC, 0xA8, 0xCC, 0x84, 0xCE, 0x05, 0x72, 0xCC,
- // Bytes 3b40 - 3b7f
- 0xA3, 0xCC, 0x84, 0xCE, 0x05, 0x73, 0xCC, 0x81,
- 0xCC, 0x87, 0xCE, 0x05, 0x73, 0xCC, 0x8C, 0xCC,
- 0x87, 0xCE, 0x05, 0x73, 0xCC, 0xA3, 0xCC, 0x87,
- 0xCE, 0x05, 0x75, 0xCC, 0x83, 0xCC, 0x81, 0xCE,
- 0x05, 0x75, 0xCC, 0x84, 0xCC, 0x88, 0xCE, 0x05,
- 0x75, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x05, 0x75,
- 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x05, 0x75, 0xCC,
- 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x75, 0xCC, 0x88,
- // Bytes 3b80 - 3bbf
- 0xCC, 0x8C, 0xCE, 0x05, 0x75, 0xCC, 0x9B, 0xCC,
- 0x80, 0xCE, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x81,
- 0xCE, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x83, 0xCE,
- 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x89, 0xCE, 0x05,
- 0x75, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, 0x05, 0xE1,
- 0xBE, 0xBF, 0xCC, 0x80, 0xCE, 0x05, 0xE1, 0xBE,
- 0xBF, 0xCC, 0x81, 0xCE, 0x05, 0xE1, 0xBE, 0xBF,
- 0xCD, 0x82, 0xCE, 0x05, 0xE1, 0xBF, 0xBE, 0xCC,
- // Bytes 3bc0 - 3bff
- 0x80, 0xCE, 0x05, 0xE1, 0xBF, 0xBE, 0xCC, 0x81,
- 0xCE, 0x05, 0xE1, 0xBF, 0xBE, 0xCD, 0x82, 0xCE,
- 0x05, 0xE2, 0x86, 0x90, 0xCC, 0xB8, 0x05, 0x05,
- 0xE2, 0x86, 0x92, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
- 0x86, 0x94, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87,
- 0x90, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87, 0x92,
- 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87, 0x94, 0xCC,
- 0xB8, 0x05, 0x05, 0xE2, 0x88, 0x83, 0xCC, 0xB8,
- // Bytes 3c00 - 3c3f
- 0x05, 0x05, 0xE2, 0x88, 0x88, 0xCC, 0xB8, 0x05,
- 0x05, 0xE2, 0x88, 0x8B, 0xCC, 0xB8, 0x05, 0x05,
- 0xE2, 0x88, 0xA3, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
- 0x88, 0xA5, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x88,
- 0xBC, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x83,
- 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x85, 0xCC,
- 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x88, 0xCC, 0xB8,
- 0x05, 0x05, 0xE2, 0x89, 0x8D, 0xCC, 0xB8, 0x05,
- // Bytes 3c40 - 3c7f
- 0x05, 0xE2, 0x89, 0xA1, 0xCC, 0xB8, 0x05, 0x05,
- 0xE2, 0x89, 0xA4, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
- 0x89, 0xA5, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89,
- 0xB2, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB3,
- 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB6, 0xCC,
- 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB7, 0xCC, 0xB8,
- 0x05, 0x05, 0xE2, 0x89, 0xBA, 0xCC, 0xB8, 0x05,
- 0x05, 0xE2, 0x89, 0xBB, 0xCC, 0xB8, 0x05, 0x05,
- // Bytes 3c80 - 3cbf
- 0xE2, 0x89, 0xBC, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
- 0x89, 0xBD, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A,
- 0x82, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x83,
- 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x86, 0xCC,
- 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x87, 0xCC, 0xB8,
- 0x05, 0x05, 0xE2, 0x8A, 0x91, 0xCC, 0xB8, 0x05,
- 0x05, 0xE2, 0x8A, 0x92, 0xCC, 0xB8, 0x05, 0x05,
- 0xE2, 0x8A, 0xA2, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
- // Bytes 3cc0 - 3cff
- 0x8A, 0xA8, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A,
- 0xA9, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xAB,
- 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB2, 0xCC,
- 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB3, 0xCC, 0xB8,
- 0x05, 0x05, 0xE2, 0x8A, 0xB4, 0xCC, 0xB8, 0x05,
- 0x05, 0xE2, 0x8A, 0xB5, 0xCC, 0xB8, 0x05, 0x06,
- 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
- // Bytes 3d00 - 3d3f
- 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
- 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
- 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
- // Bytes 3d40 - 3d7f
- 0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x06,
- 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
- 0xCE, 0x99, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06,
- 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
- 0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
- // Bytes 3d80 - 3dbf
- 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
- 0xCE, 0xA5, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06,
- 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0xB1, 0xCC, 0x81, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
- // Bytes 3dc0 - 3dff
- 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
- 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
- 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x85, 0xDE, 0x06,
- // Bytes 3e00 - 3e3f
- 0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x85, 0xDE, 0x06,
- 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x06,
- 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0xCE, 0x06,
- 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
- // Bytes 3e40 - 3e7f
- 0xCE, 0xB9, 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x06,
- 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
- 0xCE, 0xB9, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06,
- 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
- 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
- 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
- // Bytes 3e80 - 3ebf
- 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x06,
- 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x06,
- 0xCF, 0x85, 0xCC, 0x88, 0xCD, 0x82, 0xCE, 0x06,
- 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
- 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
- 0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x06,
- 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
- 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
- // Bytes 3ec0 - 3eff
- 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06,
- 0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x85, 0xDE, 0x06,
- 0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x85, 0xDE, 0x06,
- 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
- 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
- 0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x85, 0xDE, 0x06,
- 0xE0, 0xA4, 0xA8, 0xE0, 0xA4, 0xBC, 0x0D, 0x06,
- 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC, 0x0D, 0x06,
- // Bytes 3f00 - 3f3f
- 0xE0, 0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0x0D, 0x06,
- 0xE0, 0xB1, 0x86, 0xE0, 0xB1, 0x96, 0x89, 0x06,
- 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8A, 0x15, 0x06,
- 0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0x8B, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0x8F, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0x91, 0xE3, 0x82, 0x99, 0x11, 0x06,
- // Bytes 3f40 - 3f7f
- 0xE3, 0x81, 0x93, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0x95, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0x97, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0x99, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0x9B, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0x9F, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x99, 0x11, 0x06,
- // Bytes 3f80 - 3fbf
- 0xE3, 0x81, 0xA4, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0xA6, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0xA8, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x9A, 0x11, 0x06,
- 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x9A, 0x11, 0x06,
- 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x99, 0x11, 0x06,
- // Bytes 3fc0 - 3fff
- 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x9A, 0x11, 0x06,
- 0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x9A, 0x11, 0x06,
- 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x9A, 0x11, 0x06,
- 0xE3, 0x82, 0x9D, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x11, 0x06,
- // Bytes 4000 - 403f
- 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x82, 0xB5, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0x11, 0x06,
- // Bytes 4040 - 407f
- 0xE3, 0x82, 0xBD, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0x81, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0x84, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0x11, 0x06,
- // Bytes 4080 - 40bf
- 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0x11, 0x06,
- 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x9A, 0x11, 0x06,
- 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0x11, 0x06,
- 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0x11, 0x06,
- // Bytes 40c0 - 40ff
- 0xE3, 0x83, 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0xB0, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0xB1, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0xB2, 0xE3, 0x82, 0x99, 0x11, 0x06,
- 0xE3, 0x83, 0xBD, 0xE3, 0x82, 0x99, 0x11, 0x08,
- 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85,
- 0xDF, 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x81,
- 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x91, 0xCC, 0x93,
- // Bytes 4100 - 413f
- 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x91,
- 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08,
- 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85,
- 0xDF, 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x82,
- 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97, 0xCC, 0x93,
- 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97,
- 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08,
- 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85,
- // Bytes 4140 - 417f
- 0xDF, 0x08, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x80,
- 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97, 0xCC, 0x94,
- 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97,
- 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08,
- 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85,
- 0xDF, 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x81,
- 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xA9, 0xCC, 0x93,
- 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xA9,
- // Bytes 4180 - 41bf
- 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08,
- 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85,
- 0xDF, 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x82,
- 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1, 0xCC, 0x93,
- 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1,
- 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08,
- 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85,
- 0xDF, 0x08, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x80,
- // Bytes 41c0 - 41ff
- 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1, 0xCC, 0x94,
- 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1,
- 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08,
- 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85,
- 0xDF, 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x81,
- 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB7, 0xCC, 0x93,
- 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB7,
- 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08,
- // Bytes 4200 - 423f
- 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85,
- 0xDF, 0x08, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x82,
- 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89, 0xCC, 0x93,
- 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89,
- 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08,
- 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85,
- 0xDF, 0x08, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x80,
- 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89, 0xCC, 0x94,
- // Bytes 4240 - 427f
- 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89,
- 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08,
- 0xF0, 0x91, 0x82, 0x99, 0xF0, 0x91, 0x82, 0xBA,
- 0x0D, 0x08, 0xF0, 0x91, 0x82, 0x9B, 0xF0, 0x91,
- 0x82, 0xBA, 0x0D, 0x08, 0xF0, 0x91, 0x82, 0xA5,
- 0xF0, 0x91, 0x82, 0xBA, 0x0D, 0x42, 0xC2, 0xB4,
- 0x01, 0x43, 0x20, 0xCC, 0x81, 0xCD, 0x43, 0x20,
- 0xCC, 0x83, 0xCD, 0x43, 0x20, 0xCC, 0x84, 0xCD,
- // Bytes 4280 - 42bf
- 0x43, 0x20, 0xCC, 0x85, 0xCD, 0x43, 0x20, 0xCC,
- 0x86, 0xCD, 0x43, 0x20, 0xCC, 0x87, 0xCD, 0x43,
- 0x20, 0xCC, 0x88, 0xCD, 0x43, 0x20, 0xCC, 0x8A,
- 0xCD, 0x43, 0x20, 0xCC, 0x8B, 0xCD, 0x43, 0x20,
- 0xCC, 0x93, 0xCD, 0x43, 0x20, 0xCC, 0x94, 0xCD,
- 0x43, 0x20, 0xCC, 0xA7, 0xA9, 0x43, 0x20, 0xCC,
- 0xA8, 0xA9, 0x43, 0x20, 0xCC, 0xB3, 0xB9, 0x43,
- 0x20, 0xCD, 0x82, 0xCD, 0x43, 0x20, 0xCD, 0x85,
- // Bytes 42c0 - 42ff
- 0xDD, 0x43, 0x20, 0xD9, 0x8B, 0x5D, 0x43, 0x20,
- 0xD9, 0x8C, 0x61, 0x43, 0x20, 0xD9, 0x8D, 0x65,
- 0x43, 0x20, 0xD9, 0x8E, 0x69, 0x43, 0x20, 0xD9,
- 0x8F, 0x6D, 0x43, 0x20, 0xD9, 0x90, 0x71, 0x43,
- 0x20, 0xD9, 0x91, 0x75, 0x43, 0x20, 0xD9, 0x92,
- 0x79, 0x43, 0x41, 0xCC, 0x8A, 0xCD, 0x43, 0x73,
- 0xCC, 0x87, 0xCD, 0x44, 0x20, 0xE3, 0x82, 0x99,
- 0x11, 0x44, 0x20, 0xE3, 0x82, 0x9A, 0x11, 0x44,
- // Bytes 4300 - 433f
- 0xC2, 0xA8, 0xCC, 0x81, 0xCE, 0x44, 0xCE, 0x91,
- 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0x95, 0xCC, 0x81,
- 0xCD, 0x44, 0xCE, 0x97, 0xCC, 0x81, 0xCD, 0x44,
- 0xCE, 0x99, 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0x9F,
- 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xA5, 0xCC, 0x81,
- 0xCD, 0x44, 0xCE, 0xA5, 0xCC, 0x88, 0xCD, 0x44,
- 0xCE, 0xA9, 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xB1,
- 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xB5, 0xCC, 0x81,
- // Bytes 4340 - 437f
- 0xCD, 0x44, 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x44,
- 0xCE, 0xB9, 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xBF,
- 0xCC, 0x81, 0xCD, 0x44, 0xCF, 0x85, 0xCC, 0x81,
- 0xCD, 0x44, 0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x44,
- 0xD7, 0x90, 0xD6, 0xB7, 0x35, 0x44, 0xD7, 0x90,
- 0xD6, 0xB8, 0x39, 0x44, 0xD7, 0x90, 0xD6, 0xBC,
- 0x45, 0x44, 0xD7, 0x91, 0xD6, 0xBC, 0x45, 0x44,
- 0xD7, 0x91, 0xD6, 0xBF, 0x4D, 0x44, 0xD7, 0x92,
- // Bytes 4380 - 43bf
- 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x93, 0xD6, 0xBC,
- 0x45, 0x44, 0xD7, 0x94, 0xD6, 0xBC, 0x45, 0x44,
- 0xD7, 0x95, 0xD6, 0xB9, 0x3D, 0x44, 0xD7, 0x95,
- 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x96, 0xD6, 0xBC,
- 0x45, 0x44, 0xD7, 0x98, 0xD6, 0xBC, 0x45, 0x44,
- 0xD7, 0x99, 0xD6, 0xB4, 0x29, 0x44, 0xD7, 0x99,
- 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x9A, 0xD6, 0xBC,
- 0x45, 0x44, 0xD7, 0x9B, 0xD6, 0xBC, 0x45, 0x44,
- // Bytes 43c0 - 43ff
- 0xD7, 0x9B, 0xD6, 0xBF, 0x4D, 0x44, 0xD7, 0x9C,
- 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x9E, 0xD6, 0xBC,
- 0x45, 0x44, 0xD7, 0xA0, 0xD6, 0xBC, 0x45, 0x44,
- 0xD7, 0xA1, 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA3,
- 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA4, 0xD6, 0xBC,
- 0x45, 0x44, 0xD7, 0xA4, 0xD6, 0xBF, 0x4D, 0x44,
- 0xD7, 0xA6, 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA7,
- 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA8, 0xD6, 0xBC,
- // Bytes 4400 - 443f
- 0x45, 0x44, 0xD7, 0xA9, 0xD6, 0xBC, 0x45, 0x44,
- 0xD7, 0xA9, 0xD7, 0x81, 0x51, 0x44, 0xD7, 0xA9,
- 0xD7, 0x82, 0x55, 0x44, 0xD7, 0xAA, 0xD6, 0xBC,
- 0x45, 0x44, 0xD7, 0xB2, 0xD6, 0xB7, 0x35, 0x44,
- 0xD8, 0xA7, 0xD9, 0x8B, 0x5D, 0x44, 0xD8, 0xA7,
- 0xD9, 0x93, 0xCD, 0x44, 0xD8, 0xA7, 0xD9, 0x94,
- 0xCD, 0x44, 0xD8, 0xA7, 0xD9, 0x95, 0xB9, 0x44,
- 0xD8, 0xB0, 0xD9, 0xB0, 0x7D, 0x44, 0xD8, 0xB1,
- // Bytes 4440 - 447f
- 0xD9, 0xB0, 0x7D, 0x44, 0xD9, 0x80, 0xD9, 0x8B,
- 0x5D, 0x44, 0xD9, 0x80, 0xD9, 0x8E, 0x69, 0x44,
- 0xD9, 0x80, 0xD9, 0x8F, 0x6D, 0x44, 0xD9, 0x80,
- 0xD9, 0x90, 0x71, 0x44, 0xD9, 0x80, 0xD9, 0x91,
- 0x75, 0x44, 0xD9, 0x80, 0xD9, 0x92, 0x79, 0x44,
- 0xD9, 0x87, 0xD9, 0xB0, 0x7D, 0x44, 0xD9, 0x88,
- 0xD9, 0x94, 0xCD, 0x44, 0xD9, 0x89, 0xD9, 0xB0,
- 0x7D, 0x44, 0xD9, 0x8A, 0xD9, 0x94, 0xCD, 0x44,
- // Bytes 4480 - 44bf
- 0xDB, 0x92, 0xD9, 0x94, 0xCD, 0x44, 0xDB, 0x95,
- 0xD9, 0x94, 0xCD, 0x45, 0x20, 0xCC, 0x88, 0xCC,
- 0x80, 0xCE, 0x45, 0x20, 0xCC, 0x88, 0xCC, 0x81,
- 0xCE, 0x45, 0x20, 0xCC, 0x88, 0xCD, 0x82, 0xCE,
- 0x45, 0x20, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x45,
- 0x20, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x45, 0x20,
- 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x45, 0x20, 0xCC,
- 0x94, 0xCC, 0x80, 0xCE, 0x45, 0x20, 0xCC, 0x94,
- // Bytes 44c0 - 44ff
- 0xCC, 0x81, 0xCE, 0x45, 0x20, 0xCC, 0x94, 0xCD,
- 0x82, 0xCE, 0x45, 0x20, 0xD9, 0x8C, 0xD9, 0x91,
- 0x76, 0x45, 0x20, 0xD9, 0x8D, 0xD9, 0x91, 0x76,
- 0x45, 0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x76, 0x45,
- 0x20, 0xD9, 0x8F, 0xD9, 0x91, 0x76, 0x45, 0x20,
- 0xD9, 0x90, 0xD9, 0x91, 0x76, 0x45, 0x20, 0xD9,
- 0x91, 0xD9, 0xB0, 0x7E, 0x45, 0xE2, 0xAB, 0x9D,
- 0xCC, 0xB8, 0x05, 0x46, 0xCE, 0xB9, 0xCC, 0x88,
- // Bytes 4500 - 453f
- 0xCC, 0x81, 0xCE, 0x46, 0xCF, 0x85, 0xCC, 0x88,
- 0xCC, 0x81, 0xCE, 0x46, 0xD7, 0xA9, 0xD6, 0xBC,
- 0xD7, 0x81, 0x52, 0x46, 0xD7, 0xA9, 0xD6, 0xBC,
- 0xD7, 0x82, 0x56, 0x46, 0xD9, 0x80, 0xD9, 0x8E,
- 0xD9, 0x91, 0x76, 0x46, 0xD9, 0x80, 0xD9, 0x8F,
- 0xD9, 0x91, 0x76, 0x46, 0xD9, 0x80, 0xD9, 0x90,
- 0xD9, 0x91, 0x76, 0x46, 0xE0, 0xA4, 0x95, 0xE0,
- 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0x96, 0xE0,
- // Bytes 4540 - 457f
- 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0x97, 0xE0,
- 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0x9C, 0xE0,
- 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xA1, 0xE0,
- 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xA2, 0xE0,
- 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xAB, 0xE0,
- 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xAF, 0xE0,
- 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA6, 0xA1, 0xE0,
- 0xA6, 0xBC, 0x0D, 0x46, 0xE0, 0xA6, 0xA2, 0xE0,
- // Bytes 4580 - 45bf
- 0xA6, 0xBC, 0x0D, 0x46, 0xE0, 0xA6, 0xAF, 0xE0,
- 0xA6, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0x96, 0xE0,
- 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0x97, 0xE0,
- 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0x9C, 0xE0,
- 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0xAB, 0xE0,
- 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0xB2, 0xE0,
- 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0xB8, 0xE0,
- 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xAC, 0xA1, 0xE0,
- // Bytes 45c0 - 45ff
- 0xAC, 0xBC, 0x0D, 0x46, 0xE0, 0xAC, 0xA2, 0xE0,
- 0xAC, 0xBC, 0x0D, 0x46, 0xE0, 0xBE, 0xB2, 0xE0,
- 0xBE, 0x80, 0xA1, 0x46, 0xE0, 0xBE, 0xB3, 0xE0,
- 0xBE, 0x80, 0xA1, 0x46, 0xE3, 0x83, 0x86, 0xE3,
- 0x82, 0x99, 0x11, 0x48, 0xF0, 0x9D, 0x85, 0x97,
- 0xF0, 0x9D, 0x85, 0xA5, 0xB1, 0x48, 0xF0, 0x9D,
- 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xB1, 0x48,
- 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5,
- // Bytes 4600 - 463f
- 0xB1, 0x48, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D,
- 0x85, 0xA5, 0xB1, 0x49, 0xE0, 0xBE, 0xB2, 0xE0,
- 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xA2, 0x49, 0xE0,
- 0xBE, 0xB3, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80,
- 0xA2, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D,
- 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xB2, 0x4C,
- 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5,
- 0xF0, 0x9D, 0x85, 0xAF, 0xB2, 0x4C, 0xF0, 0x9D,
- // Bytes 4640 - 467f
- 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D,
- 0x85, 0xB0, 0xB2, 0x4C, 0xF0, 0x9D, 0x85, 0x98,
- 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB1,
- 0xB2, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D,
- 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB2, 0xB2, 0x4C,
- 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5,
- 0xF0, 0x9D, 0x85, 0xAE, 0xB2, 0x4C, 0xF0, 0x9D,
- 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D,
- // Bytes 4680 - 46bf
- 0x85, 0xAF, 0xB2, 0x4C, 0xF0, 0x9D, 0x86, 0xBA,
- 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE,
- 0xB2, 0x4C, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D,
- 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0xB2, 0x83,
- 0x41, 0xCC, 0x82, 0xCD, 0x83, 0x41, 0xCC, 0x86,
- 0xCD, 0x83, 0x41, 0xCC, 0x87, 0xCD, 0x83, 0x41,
- 0xCC, 0x88, 0xCD, 0x83, 0x41, 0xCC, 0x8A, 0xCD,
- 0x83, 0x41, 0xCC, 0xA3, 0xB9, 0x83, 0x43, 0xCC,
- // Bytes 46c0 - 46ff
- 0xA7, 0xA9, 0x83, 0x45, 0xCC, 0x82, 0xCD, 0x83,
- 0x45, 0xCC, 0x84, 0xCD, 0x83, 0x45, 0xCC, 0xA3,
- 0xB9, 0x83, 0x45, 0xCC, 0xA7, 0xA9, 0x83, 0x49,
- 0xCC, 0x88, 0xCD, 0x83, 0x4C, 0xCC, 0xA3, 0xB9,
- 0x83, 0x4F, 0xCC, 0x82, 0xCD, 0x83, 0x4F, 0xCC,
- 0x83, 0xCD, 0x83, 0x4F, 0xCC, 0x84, 0xCD, 0x83,
- 0x4F, 0xCC, 0x87, 0xCD, 0x83, 0x4F, 0xCC, 0x88,
- 0xCD, 0x83, 0x4F, 0xCC, 0x9B, 0xB1, 0x83, 0x4F,
- // Bytes 4700 - 473f
- 0xCC, 0xA3, 0xB9, 0x83, 0x4F, 0xCC, 0xA8, 0xA9,
- 0x83, 0x52, 0xCC, 0xA3, 0xB9, 0x83, 0x53, 0xCC,
- 0x81, 0xCD, 0x83, 0x53, 0xCC, 0x8C, 0xCD, 0x83,
- 0x53, 0xCC, 0xA3, 0xB9, 0x83, 0x55, 0xCC, 0x83,
- 0xCD, 0x83, 0x55, 0xCC, 0x84, 0xCD, 0x83, 0x55,
- 0xCC, 0x88, 0xCD, 0x83, 0x55, 0xCC, 0x9B, 0xB1,
- 0x83, 0x61, 0xCC, 0x82, 0xCD, 0x83, 0x61, 0xCC,
- 0x86, 0xCD, 0x83, 0x61, 0xCC, 0x87, 0xCD, 0x83,
- // Bytes 4740 - 477f
- 0x61, 0xCC, 0x88, 0xCD, 0x83, 0x61, 0xCC, 0x8A,
- 0xCD, 0x83, 0x61, 0xCC, 0xA3, 0xB9, 0x83, 0x63,
- 0xCC, 0xA7, 0xA9, 0x83, 0x65, 0xCC, 0x82, 0xCD,
- 0x83, 0x65, 0xCC, 0x84, 0xCD, 0x83, 0x65, 0xCC,
- 0xA3, 0xB9, 0x83, 0x65, 0xCC, 0xA7, 0xA9, 0x83,
- 0x69, 0xCC, 0x88, 0xCD, 0x83, 0x6C, 0xCC, 0xA3,
- 0xB9, 0x83, 0x6F, 0xCC, 0x82, 0xCD, 0x83, 0x6F,
- 0xCC, 0x83, 0xCD, 0x83, 0x6F, 0xCC, 0x84, 0xCD,
- // Bytes 4780 - 47bf
- 0x83, 0x6F, 0xCC, 0x87, 0xCD, 0x83, 0x6F, 0xCC,
- 0x88, 0xCD, 0x83, 0x6F, 0xCC, 0x9B, 0xB1, 0x83,
- 0x6F, 0xCC, 0xA3, 0xB9, 0x83, 0x6F, 0xCC, 0xA8,
- 0xA9, 0x83, 0x72, 0xCC, 0xA3, 0xB9, 0x83, 0x73,
- 0xCC, 0x81, 0xCD, 0x83, 0x73, 0xCC, 0x8C, 0xCD,
- 0x83, 0x73, 0xCC, 0xA3, 0xB9, 0x83, 0x75, 0xCC,
- 0x83, 0xCD, 0x83, 0x75, 0xCC, 0x84, 0xCD, 0x83,
- 0x75, 0xCC, 0x88, 0xCD, 0x83, 0x75, 0xCC, 0x9B,
- // Bytes 47c0 - 47ff
- 0xB1, 0x84, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x84,
- 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0x95,
- 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0x95, 0xCC, 0x94,
- 0xCD, 0x84, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x84,
- 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0x99,
- 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0x99, 0xCC, 0x94,
- 0xCD, 0x84, 0xCE, 0x9F, 0xCC, 0x93, 0xCD, 0x84,
- 0xCE, 0x9F, 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0xA5,
- // Bytes 4800 - 483f
- 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0xA9, 0xCC, 0x93,
- 0xCD, 0x84, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x84,
- 0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x84, 0xCE, 0xB1,
- 0xCC, 0x81, 0xCD, 0x84, 0xCE, 0xB1, 0xCC, 0x93,
- 0xCD, 0x84, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x84,
- 0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x84, 0xCE, 0xB5,
- 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0xB5, 0xCC, 0x94,
- 0xCD, 0x84, 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x84,
- // Bytes 4840 - 487f
- 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x84, 0xCE, 0xB7,
- 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0xB7, 0xCC, 0x94,
- 0xCD, 0x84, 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x84,
- 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x84, 0xCE, 0xB9,
- 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0xB9, 0xCC, 0x94,
- 0xCD, 0x84, 0xCE, 0xBF, 0xCC, 0x93, 0xCD, 0x84,
- 0xCE, 0xBF, 0xCC, 0x94, 0xCD, 0x84, 0xCF, 0x85,
- 0xCC, 0x88, 0xCD, 0x84, 0xCF, 0x85, 0xCC, 0x93,
- // Bytes 4880 - 48bf
- 0xCD, 0x84, 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x84,
- 0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x84, 0xCF, 0x89,
- 0xCC, 0x81, 0xCD, 0x84, 0xCF, 0x89, 0xCC, 0x93,
- 0xCD, 0x84, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x84,
- 0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x86, 0xCE, 0x91,
- 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x91,
- 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x91,
- 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0x91,
- // Bytes 48c0 - 48ff
- 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x91,
- 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x91,
- 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0x97,
- 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x97,
- 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x97,
- 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0x97,
- 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x97,
- 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x97,
- // Bytes 4900 - 493f
- 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xA9,
- 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xA9,
- 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xA9,
- 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xA9,
- 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xA9,
- 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xA9,
- 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB1,
- 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB1,
- // Bytes 4940 - 497f
- 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB1,
- 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB1,
- 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB1,
- 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB1,
- 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB7,
- 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB7,
- 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB7,
- 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB7,
- // Bytes 4980 - 49bf
- 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB7,
- 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB7,
- 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCF, 0x89,
- 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCF, 0x89,
- 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCF, 0x89,
- 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCF, 0x89,
- 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCF, 0x89,
- 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCF, 0x89,
- // Bytes 49c0 - 49ff
- 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x42, 0xCC, 0x80,
- 0xCD, 0x33, 0x42, 0xCC, 0x81, 0xCD, 0x33, 0x42,
- 0xCC, 0x93, 0xCD, 0x33, 0x43, 0xE1, 0x85, 0xA1,
- 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA2, 0x01, 0x00,
- 0x43, 0xE1, 0x85, 0xA3, 0x01, 0x00, 0x43, 0xE1,
- 0x85, 0xA4, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA5,
- 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA6, 0x01, 0x00,
- 0x43, 0xE1, 0x85, 0xA7, 0x01, 0x00, 0x43, 0xE1,
- // Bytes 4a00 - 4a3f
- 0x85, 0xA8, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA9,
- 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAA, 0x01, 0x00,
- 0x43, 0xE1, 0x85, 0xAB, 0x01, 0x00, 0x43, 0xE1,
- 0x85, 0xAC, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAD,
- 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAE, 0x01, 0x00,
- 0x43, 0xE1, 0x85, 0xAF, 0x01, 0x00, 0x43, 0xE1,
- 0x85, 0xB0, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB1,
- 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB2, 0x01, 0x00,
- // Bytes 4a40 - 4a7f
- 0x43, 0xE1, 0x85, 0xB3, 0x01, 0x00, 0x43, 0xE1,
- 0x85, 0xB4, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB5,
- 0x01, 0x00, 0x43, 0xE1, 0x86, 0xAA, 0x01, 0x00,
- 0x43, 0xE1, 0x86, 0xAC, 0x01, 0x00, 0x43, 0xE1,
- 0x86, 0xAD, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB0,
- 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB1, 0x01, 0x00,
- 0x43, 0xE1, 0x86, 0xB2, 0x01, 0x00, 0x43, 0xE1,
- 0x86, 0xB3, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB4,
- // Bytes 4a80 - 4abf
- 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB5, 0x01, 0x00,
- 0x44, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x33, 0x43,
- 0xE3, 0x82, 0x99, 0x11, 0x04, 0x43, 0xE3, 0x82,
- 0x9A, 0x11, 0x04, 0x46, 0xE0, 0xBD, 0xB1, 0xE0,
- 0xBD, 0xB2, 0xA2, 0x27, 0x46, 0xE0, 0xBD, 0xB1,
- 0xE0, 0xBD, 0xB4, 0xA6, 0x27, 0x46, 0xE0, 0xBD,
- 0xB1, 0xE0, 0xBE, 0x80, 0xA2, 0x27, 0x00, 0x01,
-}
-
-// lookup returns the trie value for the first UTF-8 encoding in s and
-// the width in bytes of this encoding. The size will be 0 if s does not
-// hold enough bytes to complete the encoding. len(s) must be greater than 0.
-func (t *nfcTrie) lookup(s []byte) (v uint16, sz int) {
- c0 := s[0]
- switch {
- case c0 < 0x80: // is ASCII
- return nfcValues[c0], 1
- case c0 < 0xC2:
- return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
- case c0 < 0xE0: // 2-byte UTF-8
- if len(s) < 2 {
- return 0, 0
- }
- i := nfcIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c1), 2
- case c0 < 0xF0: // 3-byte UTF-8
- if len(s) < 3 {
- return 0, 0
- }
- i := nfcIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = nfcIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c2), 3
- case c0 < 0xF8: // 4-byte UTF-8
- if len(s) < 4 {
- return 0, 0
- }
- i := nfcIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = nfcIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- o = uint32(i)<<6 + uint32(c2)
- i = nfcIndex[o]
- c3 := s[3]
- if c3 < 0x80 || 0xC0 <= c3 {
- return 0, 3 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c3), 4
- }
- // Illegal rune
- return 0, 1
-}
-
-// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
-// s must start with a full and valid UTF-8 encoded rune.
-func (t *nfcTrie) lookupUnsafe(s []byte) uint16 {
- c0 := s[0]
- if c0 < 0x80 { // is ASCII
- return nfcValues[c0]
- }
- i := nfcIndex[c0]
- if c0 < 0xE0 { // 2-byte UTF-8
- return t.lookupValue(uint32(i), s[1])
- }
- i = nfcIndex[uint32(i)<<6+uint32(s[1])]
- if c0 < 0xF0 { // 3-byte UTF-8
- return t.lookupValue(uint32(i), s[2])
- }
- i = nfcIndex[uint32(i)<<6+uint32(s[2])]
- if c0 < 0xF8 { // 4-byte UTF-8
- return t.lookupValue(uint32(i), s[3])
- }
- return 0
-}
-
-// lookupString returns the trie value for the first UTF-8 encoding in s and
-// the width in bytes of this encoding. The size will be 0 if s does not
-// hold enough bytes to complete the encoding. len(s) must be greater than 0.
-func (t *nfcTrie) lookupString(s string) (v uint16, sz int) {
- c0 := s[0]
- switch {
- case c0 < 0x80: // is ASCII
- return nfcValues[c0], 1
- case c0 < 0xC2:
- return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
- case c0 < 0xE0: // 2-byte UTF-8
- if len(s) < 2 {
- return 0, 0
- }
- i := nfcIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c1), 2
- case c0 < 0xF0: // 3-byte UTF-8
- if len(s) < 3 {
- return 0, 0
- }
- i := nfcIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = nfcIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c2), 3
- case c0 < 0xF8: // 4-byte UTF-8
- if len(s) < 4 {
- return 0, 0
- }
- i := nfcIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = nfcIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- o = uint32(i)<<6 + uint32(c2)
- i = nfcIndex[o]
- c3 := s[3]
- if c3 < 0x80 || 0xC0 <= c3 {
- return 0, 3 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c3), 4
- }
- // Illegal rune
- return 0, 1
-}
-
-// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
-// s must start with a full and valid UTF-8 encoded rune.
-func (t *nfcTrie) lookupStringUnsafe(s string) uint16 {
- c0 := s[0]
- if c0 < 0x80 { // is ASCII
- return nfcValues[c0]
- }
- i := nfcIndex[c0]
- if c0 < 0xE0 { // 2-byte UTF-8
- return t.lookupValue(uint32(i), s[1])
- }
- i = nfcIndex[uint32(i)<<6+uint32(s[1])]
- if c0 < 0xF0 { // 3-byte UTF-8
- return t.lookupValue(uint32(i), s[2])
- }
- i = nfcIndex[uint32(i)<<6+uint32(s[2])]
- if c0 < 0xF8 { // 4-byte UTF-8
- return t.lookupValue(uint32(i), s[3])
- }
- return 0
-}
-
-// nfcTrie. Total size: 10680 bytes (10.43 KiB). Checksum: a555db76d4becdd2.
-type nfcTrie struct{}
-
-func newNfcTrie(i int) *nfcTrie {
- return &nfcTrie{}
-}
-
-// lookupValue determines the type of block n and looks up the value for b.
-func (t *nfcTrie) lookupValue(n uint32, b byte) uint16 {
- switch {
- case n < 46:
- return uint16(nfcValues[n<<6+uint32(b)])
- default:
- n -= 46
- return uint16(nfcSparse.lookup(n, b))
- }
-}
-
-// nfcValues: 48 blocks, 3072 entries, 6144 bytes
-// The third block is the zero block.
-var nfcValues = [3072]uint16{
- // Block 0x0, offset 0x0
- 0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000,
- // Block 0x1, offset 0x40
- 0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000,
- 0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000,
- 0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000,
- 0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000,
- 0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000,
- 0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000,
- 0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000,
- 0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000,
- 0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000,
- 0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000,
- // Block 0x2, offset 0x80
- // Block 0x3, offset 0xc0
- 0xc0: 0x2f86, 0xc1: 0x2f8b, 0xc2: 0x469f, 0xc3: 0x2f90, 0xc4: 0x46ae, 0xc5: 0x46b3,
- 0xc6: 0xa000, 0xc7: 0x46bd, 0xc8: 0x2ff9, 0xc9: 0x2ffe, 0xca: 0x46c2, 0xcb: 0x3012,
- 0xcc: 0x3085, 0xcd: 0x308a, 0xce: 0x308f, 0xcf: 0x46d6, 0xd1: 0x311b,
- 0xd2: 0x313e, 0xd3: 0x3143, 0xd4: 0x46e0, 0xd5: 0x46e5, 0xd6: 0x46f4,
- 0xd8: 0xa000, 0xd9: 0x31ca, 0xda: 0x31cf, 0xdb: 0x31d4, 0xdc: 0x4726, 0xdd: 0x324c,
- 0xe0: 0x3292, 0xe1: 0x3297, 0xe2: 0x4730, 0xe3: 0x329c,
- 0xe4: 0x473f, 0xe5: 0x4744, 0xe6: 0xa000, 0xe7: 0x474e, 0xe8: 0x3305, 0xe9: 0x330a,
- 0xea: 0x4753, 0xeb: 0x331e, 0xec: 0x3396, 0xed: 0x339b, 0xee: 0x33a0, 0xef: 0x4767,
- 0xf1: 0x342c, 0xf2: 0x344f, 0xf3: 0x3454, 0xf4: 0x4771, 0xf5: 0x4776,
- 0xf6: 0x4785, 0xf8: 0xa000, 0xf9: 0x34e0, 0xfa: 0x34e5, 0xfb: 0x34ea,
- 0xfc: 0x47b7, 0xfd: 0x3567, 0xff: 0x3580,
- // Block 0x4, offset 0x100
- 0x100: 0x2f95, 0x101: 0x32a1, 0x102: 0x46a4, 0x103: 0x4735, 0x104: 0x2fb3, 0x105: 0x32bf,
- 0x106: 0x2fc7, 0x107: 0x32d3, 0x108: 0x2fcc, 0x109: 0x32d8, 0x10a: 0x2fd1, 0x10b: 0x32dd,
- 0x10c: 0x2fd6, 0x10d: 0x32e2, 0x10e: 0x2fe0, 0x10f: 0x32ec,
- 0x112: 0x46c7, 0x113: 0x4758, 0x114: 0x3008, 0x115: 0x3314, 0x116: 0x300d, 0x117: 0x3319,
- 0x118: 0x302b, 0x119: 0x3337, 0x11a: 0x301c, 0x11b: 0x3328, 0x11c: 0x3044, 0x11d: 0x3350,
- 0x11e: 0x304e, 0x11f: 0x335a, 0x120: 0x3053, 0x121: 0x335f, 0x122: 0x305d, 0x123: 0x3369,
- 0x124: 0x3062, 0x125: 0x336e, 0x128: 0x3094, 0x129: 0x33a5,
- 0x12a: 0x3099, 0x12b: 0x33aa, 0x12c: 0x309e, 0x12d: 0x33af, 0x12e: 0x30c1, 0x12f: 0x33cd,
- 0x130: 0x30a3, 0x134: 0x30cb, 0x135: 0x33d7,
- 0x136: 0x30df, 0x137: 0x33f0, 0x139: 0x30e9, 0x13a: 0x33fa, 0x13b: 0x30f3,
- 0x13c: 0x3404, 0x13d: 0x30ee, 0x13e: 0x33ff,
- // Block 0x5, offset 0x140
- 0x143: 0x3116, 0x144: 0x3427, 0x145: 0x312f,
- 0x146: 0x3440, 0x147: 0x3125, 0x148: 0x3436,
- 0x14c: 0x46ea, 0x14d: 0x477b, 0x14e: 0x3148, 0x14f: 0x3459, 0x150: 0x3152, 0x151: 0x3463,
- 0x154: 0x3170, 0x155: 0x3481, 0x156: 0x3189, 0x157: 0x349a,
- 0x158: 0x317a, 0x159: 0x348b, 0x15a: 0x470d, 0x15b: 0x479e, 0x15c: 0x3193, 0x15d: 0x34a4,
- 0x15e: 0x31a2, 0x15f: 0x34b3, 0x160: 0x4712, 0x161: 0x47a3, 0x162: 0x31bb, 0x163: 0x34d1,
- 0x164: 0x31ac, 0x165: 0x34c2, 0x168: 0x471c, 0x169: 0x47ad,
- 0x16a: 0x4721, 0x16b: 0x47b2, 0x16c: 0x31d9, 0x16d: 0x34ef, 0x16e: 0x31e3, 0x16f: 0x34f9,
- 0x170: 0x31e8, 0x171: 0x34fe, 0x172: 0x3206, 0x173: 0x351c, 0x174: 0x3229, 0x175: 0x353f,
- 0x176: 0x3251, 0x177: 0x356c, 0x178: 0x3265, 0x179: 0x3274, 0x17a: 0x3594, 0x17b: 0x327e,
- 0x17c: 0x359e, 0x17d: 0x3283, 0x17e: 0x35a3, 0x17f: 0xa000,
- // Block 0x6, offset 0x180
- 0x184: 0x8100, 0x185: 0x8100,
- 0x186: 0x8100,
- 0x18d: 0x2f9f, 0x18e: 0x32ab, 0x18f: 0x30ad, 0x190: 0x33b9, 0x191: 0x3157,
- 0x192: 0x3468, 0x193: 0x31ed, 0x194: 0x3503, 0x195: 0x39e6, 0x196: 0x3b75, 0x197: 0x39df,
- 0x198: 0x3b6e, 0x199: 0x39ed, 0x19a: 0x3b7c, 0x19b: 0x39d8, 0x19c: 0x3b67,
- 0x19e: 0x38c7, 0x19f: 0x3a56, 0x1a0: 0x38c0, 0x1a1: 0x3a4f, 0x1a2: 0x35ca, 0x1a3: 0x35dc,
- 0x1a6: 0x3058, 0x1a7: 0x3364, 0x1a8: 0x30d5, 0x1a9: 0x33e6,
- 0x1aa: 0x4703, 0x1ab: 0x4794, 0x1ac: 0x39a7, 0x1ad: 0x3b36, 0x1ae: 0x35ee, 0x1af: 0x35f4,
- 0x1b0: 0x33dc, 0x1b4: 0x303f, 0x1b5: 0x334b,
- 0x1b8: 0x3111, 0x1b9: 0x3422, 0x1ba: 0x38ce, 0x1bb: 0x3a5d,
- 0x1bc: 0x35c4, 0x1bd: 0x35d6, 0x1be: 0x35d0, 0x1bf: 0x35e2,
- // Block 0x7, offset 0x1c0
- 0x1c0: 0x2fa4, 0x1c1: 0x32b0, 0x1c2: 0x2fa9, 0x1c3: 0x32b5, 0x1c4: 0x3021, 0x1c5: 0x332d,
- 0x1c6: 0x3026, 0x1c7: 0x3332, 0x1c8: 0x30b2, 0x1c9: 0x33be, 0x1ca: 0x30b7, 0x1cb: 0x33c3,
- 0x1cc: 0x315c, 0x1cd: 0x346d, 0x1ce: 0x3161, 0x1cf: 0x3472, 0x1d0: 0x317f, 0x1d1: 0x3490,
- 0x1d2: 0x3184, 0x1d3: 0x3495, 0x1d4: 0x31f2, 0x1d5: 0x3508, 0x1d6: 0x31f7, 0x1d7: 0x350d,
- 0x1d8: 0x319d, 0x1d9: 0x34ae, 0x1da: 0x31b6, 0x1db: 0x34cc,
- 0x1de: 0x3071, 0x1df: 0x337d,
- 0x1e6: 0x46a9, 0x1e7: 0x473a, 0x1e8: 0x46d1, 0x1e9: 0x4762,
- 0x1ea: 0x3976, 0x1eb: 0x3b05, 0x1ec: 0x3953, 0x1ed: 0x3ae2, 0x1ee: 0x46ef, 0x1ef: 0x4780,
- 0x1f0: 0x396f, 0x1f1: 0x3afe, 0x1f2: 0x325b, 0x1f3: 0x3576,
- // Block 0x8, offset 0x200
- 0x200: 0x9933, 0x201: 0x9933, 0x202: 0x9933, 0x203: 0x9933, 0x204: 0x9933, 0x205: 0x8133,
- 0x206: 0x9933, 0x207: 0x9933, 0x208: 0x9933, 0x209: 0x9933, 0x20a: 0x9933, 0x20b: 0x9933,
- 0x20c: 0x9933, 0x20d: 0x8133, 0x20e: 0x8133, 0x20f: 0x9933, 0x210: 0x8133, 0x211: 0x9933,
- 0x212: 0x8133, 0x213: 0x9933, 0x214: 0x9933, 0x215: 0x8134, 0x216: 0x812e, 0x217: 0x812e,
- 0x218: 0x812e, 0x219: 0x812e, 0x21a: 0x8134, 0x21b: 0x992c, 0x21c: 0x812e, 0x21d: 0x812e,
- 0x21e: 0x812e, 0x21f: 0x812e, 0x220: 0x812e, 0x221: 0x812a, 0x222: 0x812a, 0x223: 0x992e,
- 0x224: 0x992e, 0x225: 0x992e, 0x226: 0x992e, 0x227: 0x992a, 0x228: 0x992a, 0x229: 0x812e,
- 0x22a: 0x812e, 0x22b: 0x812e, 0x22c: 0x812e, 0x22d: 0x992e, 0x22e: 0x992e, 0x22f: 0x812e,
- 0x230: 0x992e, 0x231: 0x992e, 0x232: 0x812e, 0x233: 0x812e, 0x234: 0x8101, 0x235: 0x8101,
- 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812e, 0x23a: 0x812e, 0x23b: 0x812e,
- 0x23c: 0x812e, 0x23d: 0x8133, 0x23e: 0x8133, 0x23f: 0x8133,
- // Block 0x9, offset 0x240
- 0x240: 0x49c5, 0x241: 0x49ca, 0x242: 0x9933, 0x243: 0x49cf, 0x244: 0x4a88, 0x245: 0x9937,
- 0x246: 0x8133, 0x247: 0x812e, 0x248: 0x812e, 0x249: 0x812e, 0x24a: 0x8133, 0x24b: 0x8133,
- 0x24c: 0x8133, 0x24d: 0x812e, 0x24e: 0x812e, 0x250: 0x8133, 0x251: 0x8133,
- 0x252: 0x8133, 0x253: 0x812e, 0x254: 0x812e, 0x255: 0x812e, 0x256: 0x812e, 0x257: 0x8133,
- 0x258: 0x8134, 0x259: 0x812e, 0x25a: 0x812e, 0x25b: 0x8133, 0x25c: 0x8135, 0x25d: 0x8136,
- 0x25e: 0x8136, 0x25f: 0x8135, 0x260: 0x8136, 0x261: 0x8136, 0x262: 0x8135, 0x263: 0x8133,
- 0x264: 0x8133, 0x265: 0x8133, 0x266: 0x8133, 0x267: 0x8133, 0x268: 0x8133, 0x269: 0x8133,
- 0x26a: 0x8133, 0x26b: 0x8133, 0x26c: 0x8133, 0x26d: 0x8133, 0x26e: 0x8133, 0x26f: 0x8133,
- 0x274: 0x0173,
- 0x27a: 0x8100,
- 0x27e: 0x0037,
- // Block 0xa, offset 0x280
- 0x284: 0x8100, 0x285: 0x35b8,
- 0x286: 0x3600, 0x287: 0x00ce, 0x288: 0x361e, 0x289: 0x362a, 0x28a: 0x363c,
- 0x28c: 0x365a, 0x28e: 0x366c, 0x28f: 0x368a, 0x290: 0x3e1f, 0x291: 0xa000,
- 0x295: 0xa000, 0x297: 0xa000,
- 0x299: 0xa000,
- 0x29f: 0xa000, 0x2a1: 0xa000,
- 0x2a5: 0xa000, 0x2a9: 0xa000,
- 0x2aa: 0x364e, 0x2ab: 0x367e, 0x2ac: 0x4815, 0x2ad: 0x36ae, 0x2ae: 0x483f, 0x2af: 0x36c0,
- 0x2b0: 0x3e87, 0x2b1: 0xa000, 0x2b5: 0xa000,
- 0x2b7: 0xa000, 0x2b9: 0xa000,
- 0x2bf: 0xa000,
- // Block 0xb, offset 0x2c0
- 0x2c0: 0x3738, 0x2c1: 0x3744, 0x2c3: 0x3732,
- 0x2c6: 0xa000, 0x2c7: 0x3720,
- 0x2cc: 0x3774, 0x2cd: 0x375c, 0x2ce: 0x3786, 0x2d0: 0xa000,
- 0x2d3: 0xa000, 0x2d5: 0xa000, 0x2d6: 0xa000, 0x2d7: 0xa000,
- 0x2d8: 0xa000, 0x2d9: 0x3768, 0x2da: 0xa000,
- 0x2de: 0xa000, 0x2e3: 0xa000,
- 0x2e7: 0xa000,
- 0x2eb: 0xa000, 0x2ed: 0xa000,
- 0x2f0: 0xa000, 0x2f3: 0xa000, 0x2f5: 0xa000,
- 0x2f6: 0xa000, 0x2f7: 0xa000, 0x2f8: 0xa000, 0x2f9: 0x37ec, 0x2fa: 0xa000,
- 0x2fe: 0xa000,
- // Block 0xc, offset 0x300
- 0x301: 0x374a, 0x302: 0x37ce,
- 0x310: 0x3726, 0x311: 0x37aa,
- 0x312: 0x372c, 0x313: 0x37b0, 0x316: 0x373e, 0x317: 0x37c2,
- 0x318: 0xa000, 0x319: 0xa000, 0x31a: 0x3840, 0x31b: 0x3846, 0x31c: 0x3750, 0x31d: 0x37d4,
- 0x31e: 0x3756, 0x31f: 0x37da, 0x322: 0x3762, 0x323: 0x37e6,
- 0x324: 0x376e, 0x325: 0x37f2, 0x326: 0x377a, 0x327: 0x37fe, 0x328: 0xa000, 0x329: 0xa000,
- 0x32a: 0x384c, 0x32b: 0x3852, 0x32c: 0x37a4, 0x32d: 0x3828, 0x32e: 0x3780, 0x32f: 0x3804,
- 0x330: 0x378c, 0x331: 0x3810, 0x332: 0x3792, 0x333: 0x3816, 0x334: 0x3798, 0x335: 0x381c,
- 0x338: 0x379e, 0x339: 0x3822,
- // Block 0xd, offset 0x340
- 0x351: 0x812e,
- 0x352: 0x8133, 0x353: 0x8133, 0x354: 0x8133, 0x355: 0x8133, 0x356: 0x812e, 0x357: 0x8133,
- 0x358: 0x8133, 0x359: 0x8133, 0x35a: 0x812f, 0x35b: 0x812e, 0x35c: 0x8133, 0x35d: 0x8133,
- 0x35e: 0x8133, 0x35f: 0x8133, 0x360: 0x8133, 0x361: 0x8133, 0x362: 0x812e, 0x363: 0x812e,
- 0x364: 0x812e, 0x365: 0x812e, 0x366: 0x812e, 0x367: 0x812e, 0x368: 0x8133, 0x369: 0x8133,
- 0x36a: 0x812e, 0x36b: 0x8133, 0x36c: 0x8133, 0x36d: 0x812f, 0x36e: 0x8132, 0x36f: 0x8133,
- 0x370: 0x8106, 0x371: 0x8107, 0x372: 0x8108, 0x373: 0x8109, 0x374: 0x810a, 0x375: 0x810b,
- 0x376: 0x810c, 0x377: 0x810d, 0x378: 0x810e, 0x379: 0x810f, 0x37a: 0x810f, 0x37b: 0x8110,
- 0x37c: 0x8111, 0x37d: 0x8112, 0x37f: 0x8113,
- // Block 0xe, offset 0x380
- 0x388: 0xa000, 0x38a: 0xa000, 0x38b: 0x8117,
- 0x38c: 0x8118, 0x38d: 0x8119, 0x38e: 0x811a, 0x38f: 0x811b, 0x390: 0x811c, 0x391: 0x811d,
- 0x392: 0x811e, 0x393: 0x9933, 0x394: 0x9933, 0x395: 0x992e, 0x396: 0x812e, 0x397: 0x8133,
- 0x398: 0x8133, 0x399: 0x8133, 0x39a: 0x8133, 0x39b: 0x8133, 0x39c: 0x812e, 0x39d: 0x8133,
- 0x39e: 0x8133, 0x39f: 0x812e,
- 0x3b0: 0x811f,
- // Block 0xf, offset 0x3c0
- 0x3d3: 0x812e, 0x3d4: 0x8133, 0x3d5: 0x8133, 0x3d6: 0x8133, 0x3d7: 0x8133,
- 0x3d8: 0x8133, 0x3d9: 0x8133, 0x3da: 0x8133, 0x3db: 0x8133, 0x3dc: 0x8133, 0x3dd: 0x8133,
- 0x3de: 0x8133, 0x3df: 0x8133, 0x3e0: 0x8133, 0x3e1: 0x8133, 0x3e3: 0x812e,
- 0x3e4: 0x8133, 0x3e5: 0x8133, 0x3e6: 0x812e, 0x3e7: 0x8133, 0x3e8: 0x8133, 0x3e9: 0x812e,
- 0x3ea: 0x8133, 0x3eb: 0x8133, 0x3ec: 0x8133, 0x3ed: 0x812e, 0x3ee: 0x812e, 0x3ef: 0x812e,
- 0x3f0: 0x8117, 0x3f1: 0x8118, 0x3f2: 0x8119, 0x3f3: 0x8133, 0x3f4: 0x8133, 0x3f5: 0x8133,
- 0x3f6: 0x812e, 0x3f7: 0x8133, 0x3f8: 0x8133, 0x3f9: 0x812e, 0x3fa: 0x812e, 0x3fb: 0x8133,
- 0x3fc: 0x8133, 0x3fd: 0x8133, 0x3fe: 0x8133, 0x3ff: 0x8133,
- // Block 0x10, offset 0x400
- 0x405: 0xa000,
- 0x406: 0x2d33, 0x407: 0xa000, 0x408: 0x2d3b, 0x409: 0xa000, 0x40a: 0x2d43, 0x40b: 0xa000,
- 0x40c: 0x2d4b, 0x40d: 0xa000, 0x40e: 0x2d53, 0x411: 0xa000,
- 0x412: 0x2d5b,
- 0x434: 0x8103, 0x435: 0x9900,
- 0x43a: 0xa000, 0x43b: 0x2d63,
- 0x43c: 0xa000, 0x43d: 0x2d6b, 0x43e: 0xa000, 0x43f: 0xa000,
- // Block 0x11, offset 0x440
- 0x440: 0x8133, 0x441: 0x8133, 0x442: 0x812e, 0x443: 0x8133, 0x444: 0x8133, 0x445: 0x8133,
- 0x446: 0x8133, 0x447: 0x8133, 0x448: 0x8133, 0x449: 0x8133, 0x44a: 0x812e, 0x44b: 0x8133,
- 0x44c: 0x8133, 0x44d: 0x8136, 0x44e: 0x812b, 0x44f: 0x812e, 0x450: 0x812a, 0x451: 0x8133,
- 0x452: 0x8133, 0x453: 0x8133, 0x454: 0x8133, 0x455: 0x8133, 0x456: 0x8133, 0x457: 0x8133,
- 0x458: 0x8133, 0x459: 0x8133, 0x45a: 0x8133, 0x45b: 0x8133, 0x45c: 0x8133, 0x45d: 0x8133,
- 0x45e: 0x8133, 0x45f: 0x8133, 0x460: 0x8133, 0x461: 0x8133, 0x462: 0x8133, 0x463: 0x8133,
- 0x464: 0x8133, 0x465: 0x8133, 0x466: 0x8133, 0x467: 0x8133, 0x468: 0x8133, 0x469: 0x8133,
- 0x46a: 0x8133, 0x46b: 0x8133, 0x46c: 0x8133, 0x46d: 0x8133, 0x46e: 0x8133, 0x46f: 0x8133,
- 0x470: 0x8133, 0x471: 0x8133, 0x472: 0x8133, 0x473: 0x8133, 0x474: 0x8133, 0x475: 0x8133,
- 0x476: 0x8134, 0x477: 0x8132, 0x478: 0x8132, 0x479: 0x812e, 0x47b: 0x8133,
- 0x47c: 0x8135, 0x47d: 0x812e, 0x47e: 0x8133, 0x47f: 0x812e,
- // Block 0x12, offset 0x480
- 0x480: 0x2fae, 0x481: 0x32ba, 0x482: 0x2fb8, 0x483: 0x32c4, 0x484: 0x2fbd, 0x485: 0x32c9,
- 0x486: 0x2fc2, 0x487: 0x32ce, 0x488: 0x38e3, 0x489: 0x3a72, 0x48a: 0x2fdb, 0x48b: 0x32e7,
- 0x48c: 0x2fe5, 0x48d: 0x32f1, 0x48e: 0x2ff4, 0x48f: 0x3300, 0x490: 0x2fea, 0x491: 0x32f6,
- 0x492: 0x2fef, 0x493: 0x32fb, 0x494: 0x3906, 0x495: 0x3a95, 0x496: 0x390d, 0x497: 0x3a9c,
- 0x498: 0x3030, 0x499: 0x333c, 0x49a: 0x3035, 0x49b: 0x3341, 0x49c: 0x391b, 0x49d: 0x3aaa,
- 0x49e: 0x303a, 0x49f: 0x3346, 0x4a0: 0x3049, 0x4a1: 0x3355, 0x4a2: 0x3067, 0x4a3: 0x3373,
- 0x4a4: 0x3076, 0x4a5: 0x3382, 0x4a6: 0x306c, 0x4a7: 0x3378, 0x4a8: 0x307b, 0x4a9: 0x3387,
- 0x4aa: 0x3080, 0x4ab: 0x338c, 0x4ac: 0x30c6, 0x4ad: 0x33d2, 0x4ae: 0x3922, 0x4af: 0x3ab1,
- 0x4b0: 0x30d0, 0x4b1: 0x33e1, 0x4b2: 0x30da, 0x4b3: 0x33eb, 0x4b4: 0x30e4, 0x4b5: 0x33f5,
- 0x4b6: 0x46db, 0x4b7: 0x476c, 0x4b8: 0x3929, 0x4b9: 0x3ab8, 0x4ba: 0x30fd, 0x4bb: 0x340e,
- 0x4bc: 0x30f8, 0x4bd: 0x3409, 0x4be: 0x3102, 0x4bf: 0x3413,
- // Block 0x13, offset 0x4c0
- 0x4c0: 0x3107, 0x4c1: 0x3418, 0x4c2: 0x310c, 0x4c3: 0x341d, 0x4c4: 0x3120, 0x4c5: 0x3431,
- 0x4c6: 0x312a, 0x4c7: 0x343b, 0x4c8: 0x3139, 0x4c9: 0x344a, 0x4ca: 0x3134, 0x4cb: 0x3445,
- 0x4cc: 0x394c, 0x4cd: 0x3adb, 0x4ce: 0x395a, 0x4cf: 0x3ae9, 0x4d0: 0x3961, 0x4d1: 0x3af0,
- 0x4d2: 0x3968, 0x4d3: 0x3af7, 0x4d4: 0x3166, 0x4d5: 0x3477, 0x4d6: 0x316b, 0x4d7: 0x347c,
- 0x4d8: 0x3175, 0x4d9: 0x3486, 0x4da: 0x4708, 0x4db: 0x4799, 0x4dc: 0x39ae, 0x4dd: 0x3b3d,
- 0x4de: 0x318e, 0x4df: 0x349f, 0x4e0: 0x3198, 0x4e1: 0x34a9, 0x4e2: 0x4717, 0x4e3: 0x47a8,
- 0x4e4: 0x39b5, 0x4e5: 0x3b44, 0x4e6: 0x39bc, 0x4e7: 0x3b4b, 0x4e8: 0x39c3, 0x4e9: 0x3b52,
- 0x4ea: 0x31a7, 0x4eb: 0x34b8, 0x4ec: 0x31b1, 0x4ed: 0x34c7, 0x4ee: 0x31c5, 0x4ef: 0x34db,
- 0x4f0: 0x31c0, 0x4f1: 0x34d6, 0x4f2: 0x3201, 0x4f3: 0x3517, 0x4f4: 0x3210, 0x4f5: 0x3526,
- 0x4f6: 0x320b, 0x4f7: 0x3521, 0x4f8: 0x39ca, 0x4f9: 0x3b59, 0x4fa: 0x39d1, 0x4fb: 0x3b60,
- 0x4fc: 0x3215, 0x4fd: 0x352b, 0x4fe: 0x321a, 0x4ff: 0x3530,
- // Block 0x14, offset 0x500
- 0x500: 0x321f, 0x501: 0x3535, 0x502: 0x3224, 0x503: 0x353a, 0x504: 0x3233, 0x505: 0x3549,
- 0x506: 0x322e, 0x507: 0x3544, 0x508: 0x3238, 0x509: 0x3553, 0x50a: 0x323d, 0x50b: 0x3558,
- 0x50c: 0x3242, 0x50d: 0x355d, 0x50e: 0x3260, 0x50f: 0x357b, 0x510: 0x3279, 0x511: 0x3599,
- 0x512: 0x3288, 0x513: 0x35a8, 0x514: 0x328d, 0x515: 0x35ad, 0x516: 0x3391, 0x517: 0x34bd,
- 0x518: 0x354e, 0x519: 0x358a, 0x51b: 0x35e8,
- 0x520: 0x46b8, 0x521: 0x4749, 0x522: 0x2f9a, 0x523: 0x32a6,
- 0x524: 0x388f, 0x525: 0x3a1e, 0x526: 0x3888, 0x527: 0x3a17, 0x528: 0x389d, 0x529: 0x3a2c,
- 0x52a: 0x3896, 0x52b: 0x3a25, 0x52c: 0x38d5, 0x52d: 0x3a64, 0x52e: 0x38ab, 0x52f: 0x3a3a,
- 0x530: 0x38a4, 0x531: 0x3a33, 0x532: 0x38b9, 0x533: 0x3a48, 0x534: 0x38b2, 0x535: 0x3a41,
- 0x536: 0x38dc, 0x537: 0x3a6b, 0x538: 0x46cc, 0x539: 0x475d, 0x53a: 0x3017, 0x53b: 0x3323,
- 0x53c: 0x3003, 0x53d: 0x330f, 0x53e: 0x38f1, 0x53f: 0x3a80,
- // Block 0x15, offset 0x540
- 0x540: 0x38ea, 0x541: 0x3a79, 0x542: 0x38ff, 0x543: 0x3a8e, 0x544: 0x38f8, 0x545: 0x3a87,
- 0x546: 0x3914, 0x547: 0x3aa3, 0x548: 0x30a8, 0x549: 0x33b4, 0x54a: 0x30bc, 0x54b: 0x33c8,
- 0x54c: 0x46fe, 0x54d: 0x478f, 0x54e: 0x314d, 0x54f: 0x345e, 0x550: 0x3937, 0x551: 0x3ac6,
- 0x552: 0x3930, 0x553: 0x3abf, 0x554: 0x3945, 0x555: 0x3ad4, 0x556: 0x393e, 0x557: 0x3acd,
- 0x558: 0x39a0, 0x559: 0x3b2f, 0x55a: 0x3984, 0x55b: 0x3b13, 0x55c: 0x397d, 0x55d: 0x3b0c,
- 0x55e: 0x3992, 0x55f: 0x3b21, 0x560: 0x398b, 0x561: 0x3b1a, 0x562: 0x3999, 0x563: 0x3b28,
- 0x564: 0x31fc, 0x565: 0x3512, 0x566: 0x31de, 0x567: 0x34f4, 0x568: 0x39fb, 0x569: 0x3b8a,
- 0x56a: 0x39f4, 0x56b: 0x3b83, 0x56c: 0x3a09, 0x56d: 0x3b98, 0x56e: 0x3a02, 0x56f: 0x3b91,
- 0x570: 0x3a10, 0x571: 0x3b9f, 0x572: 0x3247, 0x573: 0x3562, 0x574: 0x326f, 0x575: 0x358f,
- 0x576: 0x326a, 0x577: 0x3585, 0x578: 0x3256, 0x579: 0x3571,
- // Block 0x16, offset 0x580
- 0x580: 0x481b, 0x581: 0x4821, 0x582: 0x4935, 0x583: 0x494d, 0x584: 0x493d, 0x585: 0x4955,
- 0x586: 0x4945, 0x587: 0x495d, 0x588: 0x47c1, 0x589: 0x47c7, 0x58a: 0x48a5, 0x58b: 0x48bd,
- 0x58c: 0x48ad, 0x58d: 0x48c5, 0x58e: 0x48b5, 0x58f: 0x48cd, 0x590: 0x482d, 0x591: 0x4833,
- 0x592: 0x3dcf, 0x593: 0x3ddf, 0x594: 0x3dd7, 0x595: 0x3de7,
- 0x598: 0x47cd, 0x599: 0x47d3, 0x59a: 0x3cff, 0x59b: 0x3d0f, 0x59c: 0x3d07, 0x59d: 0x3d17,
- 0x5a0: 0x4845, 0x5a1: 0x484b, 0x5a2: 0x4965, 0x5a3: 0x497d,
- 0x5a4: 0x496d, 0x5a5: 0x4985, 0x5a6: 0x4975, 0x5a7: 0x498d, 0x5a8: 0x47d9, 0x5a9: 0x47df,
- 0x5aa: 0x48d5, 0x5ab: 0x48ed, 0x5ac: 0x48dd, 0x5ad: 0x48f5, 0x5ae: 0x48e5, 0x5af: 0x48fd,
- 0x5b0: 0x485d, 0x5b1: 0x4863, 0x5b2: 0x3e2f, 0x5b3: 0x3e47, 0x5b4: 0x3e37, 0x5b5: 0x3e4f,
- 0x5b6: 0x3e3f, 0x5b7: 0x3e57, 0x5b8: 0x47e5, 0x5b9: 0x47eb, 0x5ba: 0x3d2f, 0x5bb: 0x3d47,
- 0x5bc: 0x3d37, 0x5bd: 0x3d4f, 0x5be: 0x3d3f, 0x5bf: 0x3d57,
- // Block 0x17, offset 0x5c0
- 0x5c0: 0x4869, 0x5c1: 0x486f, 0x5c2: 0x3e5f, 0x5c3: 0x3e6f, 0x5c4: 0x3e67, 0x5c5: 0x3e77,
- 0x5c8: 0x47f1, 0x5c9: 0x47f7, 0x5ca: 0x3d5f, 0x5cb: 0x3d6f,
- 0x5cc: 0x3d67, 0x5cd: 0x3d77, 0x5d0: 0x487b, 0x5d1: 0x4881,
- 0x5d2: 0x3e97, 0x5d3: 0x3eaf, 0x5d4: 0x3e9f, 0x5d5: 0x3eb7, 0x5d6: 0x3ea7, 0x5d7: 0x3ebf,
- 0x5d9: 0x47fd, 0x5db: 0x3d7f, 0x5dd: 0x3d87,
- 0x5df: 0x3d8f, 0x5e0: 0x4893, 0x5e1: 0x4899, 0x5e2: 0x4995, 0x5e3: 0x49ad,
- 0x5e4: 0x499d, 0x5e5: 0x49b5, 0x5e6: 0x49a5, 0x5e7: 0x49bd, 0x5e8: 0x4803, 0x5e9: 0x4809,
- 0x5ea: 0x4905, 0x5eb: 0x491d, 0x5ec: 0x490d, 0x5ed: 0x4925, 0x5ee: 0x4915, 0x5ef: 0x492d,
- 0x5f0: 0x480f, 0x5f1: 0x4335, 0x5f2: 0x36a8, 0x5f3: 0x433b, 0x5f4: 0x4839, 0x5f5: 0x4341,
- 0x5f6: 0x36ba, 0x5f7: 0x4347, 0x5f8: 0x36d8, 0x5f9: 0x434d, 0x5fa: 0x36f0, 0x5fb: 0x4353,
- 0x5fc: 0x4887, 0x5fd: 0x4359,
- // Block 0x18, offset 0x600
- 0x600: 0x3db7, 0x601: 0x3dbf, 0x602: 0x419b, 0x603: 0x41b9, 0x604: 0x41a5, 0x605: 0x41c3,
- 0x606: 0x41af, 0x607: 0x41cd, 0x608: 0x3cef, 0x609: 0x3cf7, 0x60a: 0x40e7, 0x60b: 0x4105,
- 0x60c: 0x40f1, 0x60d: 0x410f, 0x60e: 0x40fb, 0x60f: 0x4119, 0x610: 0x3dff, 0x611: 0x3e07,
- 0x612: 0x41d7, 0x613: 0x41f5, 0x614: 0x41e1, 0x615: 0x41ff, 0x616: 0x41eb, 0x617: 0x4209,
- 0x618: 0x3d1f, 0x619: 0x3d27, 0x61a: 0x4123, 0x61b: 0x4141, 0x61c: 0x412d, 0x61d: 0x414b,
- 0x61e: 0x4137, 0x61f: 0x4155, 0x620: 0x3ed7, 0x621: 0x3edf, 0x622: 0x4213, 0x623: 0x4231,
- 0x624: 0x421d, 0x625: 0x423b, 0x626: 0x4227, 0x627: 0x4245, 0x628: 0x3d97, 0x629: 0x3d9f,
- 0x62a: 0x415f, 0x62b: 0x417d, 0x62c: 0x4169, 0x62d: 0x4187, 0x62e: 0x4173, 0x62f: 0x4191,
- 0x630: 0x369c, 0x631: 0x3696, 0x632: 0x3da7, 0x633: 0x36a2, 0x634: 0x3daf,
- 0x636: 0x4827, 0x637: 0x3dc7, 0x638: 0x360c, 0x639: 0x3606, 0x63a: 0x35fa, 0x63b: 0x4305,
- 0x63c: 0x3612, 0x63d: 0x8100, 0x63e: 0x01d6, 0x63f: 0xa100,
- // Block 0x19, offset 0x640
- 0x640: 0x8100, 0x641: 0x35be, 0x642: 0x3def, 0x643: 0x36b4, 0x644: 0x3df7,
- 0x646: 0x4851, 0x647: 0x3e0f, 0x648: 0x3618, 0x649: 0x430b, 0x64a: 0x3624, 0x64b: 0x4311,
- 0x64c: 0x3630, 0x64d: 0x3ba6, 0x64e: 0x3bad, 0x64f: 0x3bb4, 0x650: 0x36cc, 0x651: 0x36c6,
- 0x652: 0x3e17, 0x653: 0x44fb, 0x656: 0x36d2, 0x657: 0x3e27,
- 0x658: 0x3648, 0x659: 0x3642, 0x65a: 0x3636, 0x65b: 0x4317, 0x65d: 0x3bbb,
- 0x65e: 0x3bc2, 0x65f: 0x3bc9, 0x660: 0x3702, 0x661: 0x36fc, 0x662: 0x3e7f, 0x663: 0x4503,
- 0x664: 0x36e4, 0x665: 0x36ea, 0x666: 0x3708, 0x667: 0x3e8f, 0x668: 0x3678, 0x669: 0x3672,
- 0x66a: 0x3666, 0x66b: 0x4323, 0x66c: 0x3660, 0x66d: 0x35b2, 0x66e: 0x42ff, 0x66f: 0x0081,
- 0x672: 0x3ec7, 0x673: 0x370e, 0x674: 0x3ecf,
- 0x676: 0x489f, 0x677: 0x3ee7, 0x678: 0x3654, 0x679: 0x431d, 0x67a: 0x3684, 0x67b: 0x432f,
- 0x67c: 0x3690, 0x67d: 0x426d, 0x67e: 0xa100,
- // Block 0x1a, offset 0x680
- 0x681: 0x3c1d, 0x683: 0xa000, 0x684: 0x3c24, 0x685: 0xa000,
- 0x687: 0x3c2b, 0x688: 0xa000, 0x689: 0x3c32,
- 0x68d: 0xa000,
- 0x6a0: 0x2f7c, 0x6a1: 0xa000, 0x6a2: 0x3c40,
- 0x6a4: 0xa000, 0x6a5: 0xa000,
- 0x6ad: 0x3c39, 0x6ae: 0x2f77, 0x6af: 0x2f81,
- 0x6b0: 0x3c47, 0x6b1: 0x3c4e, 0x6b2: 0xa000, 0x6b3: 0xa000, 0x6b4: 0x3c55, 0x6b5: 0x3c5c,
- 0x6b6: 0xa000, 0x6b7: 0xa000, 0x6b8: 0x3c63, 0x6b9: 0x3c6a, 0x6ba: 0xa000, 0x6bb: 0xa000,
- 0x6bc: 0xa000, 0x6bd: 0xa000,
- // Block 0x1b, offset 0x6c0
- 0x6c0: 0x3c71, 0x6c1: 0x3c78, 0x6c2: 0xa000, 0x6c3: 0xa000, 0x6c4: 0x3c8d, 0x6c5: 0x3c94,
- 0x6c6: 0xa000, 0x6c7: 0xa000, 0x6c8: 0x3c9b, 0x6c9: 0x3ca2,
- 0x6d1: 0xa000,
- 0x6d2: 0xa000,
- 0x6e2: 0xa000,
- 0x6e8: 0xa000, 0x6e9: 0xa000,
- 0x6eb: 0xa000, 0x6ec: 0x3cb7, 0x6ed: 0x3cbe, 0x6ee: 0x3cc5, 0x6ef: 0x3ccc,
- 0x6f2: 0xa000, 0x6f3: 0xa000, 0x6f4: 0xa000, 0x6f5: 0xa000,
- // Block 0x1c, offset 0x700
- 0x706: 0xa000, 0x70b: 0xa000,
- 0x70c: 0x3f1f, 0x70d: 0xa000, 0x70e: 0x3f27, 0x70f: 0xa000, 0x710: 0x3f2f, 0x711: 0xa000,
- 0x712: 0x3f37, 0x713: 0xa000, 0x714: 0x3f3f, 0x715: 0xa000, 0x716: 0x3f47, 0x717: 0xa000,
- 0x718: 0x3f4f, 0x719: 0xa000, 0x71a: 0x3f57, 0x71b: 0xa000, 0x71c: 0x3f5f, 0x71d: 0xa000,
- 0x71e: 0x3f67, 0x71f: 0xa000, 0x720: 0x3f6f, 0x721: 0xa000, 0x722: 0x3f77,
- 0x724: 0xa000, 0x725: 0x3f7f, 0x726: 0xa000, 0x727: 0x3f87, 0x728: 0xa000, 0x729: 0x3f8f,
- 0x72f: 0xa000,
- 0x730: 0x3f97, 0x731: 0x3f9f, 0x732: 0xa000, 0x733: 0x3fa7, 0x734: 0x3faf, 0x735: 0xa000,
- 0x736: 0x3fb7, 0x737: 0x3fbf, 0x738: 0xa000, 0x739: 0x3fc7, 0x73a: 0x3fcf, 0x73b: 0xa000,
- 0x73c: 0x3fd7, 0x73d: 0x3fdf,
- // Block 0x1d, offset 0x740
- 0x754: 0x3f17,
- 0x759: 0x9904, 0x75a: 0x9904, 0x75b: 0x8100, 0x75c: 0x8100, 0x75d: 0xa000,
- 0x75e: 0x3fe7,
- 0x766: 0xa000,
- 0x76b: 0xa000, 0x76c: 0x3ff7, 0x76d: 0xa000, 0x76e: 0x3fff, 0x76f: 0xa000,
- 0x770: 0x4007, 0x771: 0xa000, 0x772: 0x400f, 0x773: 0xa000, 0x774: 0x4017, 0x775: 0xa000,
- 0x776: 0x401f, 0x777: 0xa000, 0x778: 0x4027, 0x779: 0xa000, 0x77a: 0x402f, 0x77b: 0xa000,
- 0x77c: 0x4037, 0x77d: 0xa000, 0x77e: 0x403f, 0x77f: 0xa000,
- // Block 0x1e, offset 0x780
- 0x780: 0x4047, 0x781: 0xa000, 0x782: 0x404f, 0x784: 0xa000, 0x785: 0x4057,
- 0x786: 0xa000, 0x787: 0x405f, 0x788: 0xa000, 0x789: 0x4067,
- 0x78f: 0xa000, 0x790: 0x406f, 0x791: 0x4077,
- 0x792: 0xa000, 0x793: 0x407f, 0x794: 0x4087, 0x795: 0xa000, 0x796: 0x408f, 0x797: 0x4097,
- 0x798: 0xa000, 0x799: 0x409f, 0x79a: 0x40a7, 0x79b: 0xa000, 0x79c: 0x40af, 0x79d: 0x40b7,
- 0x7af: 0xa000,
- 0x7b0: 0xa000, 0x7b1: 0xa000, 0x7b2: 0xa000, 0x7b4: 0x3fef,
- 0x7b7: 0x40bf, 0x7b8: 0x40c7, 0x7b9: 0x40cf, 0x7ba: 0x40d7,
- 0x7bd: 0xa000, 0x7be: 0x40df,
- // Block 0x1f, offset 0x7c0
- 0x7c0: 0x137a, 0x7c1: 0x0cfe, 0x7c2: 0x13d6, 0x7c3: 0x13a2, 0x7c4: 0x0e5a, 0x7c5: 0x06ee,
- 0x7c6: 0x08e2, 0x7c7: 0x162e, 0x7c8: 0x162e, 0x7c9: 0x0a0e, 0x7ca: 0x1462, 0x7cb: 0x0946,
- 0x7cc: 0x0a0a, 0x7cd: 0x0bf2, 0x7ce: 0x0fd2, 0x7cf: 0x1162, 0x7d0: 0x129a, 0x7d1: 0x12d6,
- 0x7d2: 0x130a, 0x7d3: 0x141e, 0x7d4: 0x0d76, 0x7d5: 0x0e02, 0x7d6: 0x0eae, 0x7d7: 0x0f46,
- 0x7d8: 0x1262, 0x7d9: 0x144a, 0x7da: 0x1576, 0x7db: 0x0712, 0x7dc: 0x08b6, 0x7dd: 0x0d8a,
- 0x7de: 0x0ed2, 0x7df: 0x1296, 0x7e0: 0x15c6, 0x7e1: 0x0ab6, 0x7e2: 0x0e7a, 0x7e3: 0x1286,
- 0x7e4: 0x131a, 0x7e5: 0x0c26, 0x7e6: 0x11be, 0x7e7: 0x12e2, 0x7e8: 0x0b22, 0x7e9: 0x0d12,
- 0x7ea: 0x0e1a, 0x7eb: 0x0f1e, 0x7ec: 0x142a, 0x7ed: 0x0752, 0x7ee: 0x07ea, 0x7ef: 0x0856,
- 0x7f0: 0x0c8e, 0x7f1: 0x0d82, 0x7f2: 0x0ece, 0x7f3: 0x0ff2, 0x7f4: 0x117a, 0x7f5: 0x128e,
- 0x7f6: 0x12a6, 0x7f7: 0x13ca, 0x7f8: 0x14f2, 0x7f9: 0x15a6, 0x7fa: 0x15c2, 0x7fb: 0x102e,
- 0x7fc: 0x106e, 0x7fd: 0x1126, 0x7fe: 0x1246, 0x7ff: 0x147e,
- // Block 0x20, offset 0x800
- 0x800: 0x15ce, 0x801: 0x134e, 0x802: 0x09ca, 0x803: 0x0b3e, 0x804: 0x10de, 0x805: 0x119e,
- 0x806: 0x0f02, 0x807: 0x1036, 0x808: 0x139a, 0x809: 0x14ea, 0x80a: 0x09c6, 0x80b: 0x0a92,
- 0x80c: 0x0d7a, 0x80d: 0x0e2e, 0x80e: 0x0e62, 0x80f: 0x1116, 0x810: 0x113e, 0x811: 0x14aa,
- 0x812: 0x0852, 0x813: 0x11aa, 0x814: 0x07f6, 0x815: 0x07f2, 0x816: 0x109a, 0x817: 0x112a,
- 0x818: 0x125e, 0x819: 0x14b2, 0x81a: 0x136a, 0x81b: 0x0c2a, 0x81c: 0x0d76, 0x81d: 0x135a,
- 0x81e: 0x06fa, 0x81f: 0x0a66, 0x820: 0x0b96, 0x821: 0x0f32, 0x822: 0x0fb2, 0x823: 0x0876,
- 0x824: 0x103e, 0x825: 0x0762, 0x826: 0x0b7a, 0x827: 0x06da, 0x828: 0x0dee, 0x829: 0x0ca6,
- 0x82a: 0x1112, 0x82b: 0x08ca, 0x82c: 0x09b6, 0x82d: 0x0ffe, 0x82e: 0x1266, 0x82f: 0x133e,
- 0x830: 0x0dba, 0x831: 0x13fa, 0x832: 0x0de6, 0x833: 0x0c3a, 0x834: 0x121e, 0x835: 0x0c5a,
- 0x836: 0x0fae, 0x837: 0x072e, 0x838: 0x07aa, 0x839: 0x07ee, 0x83a: 0x0d56, 0x83b: 0x10fe,
- 0x83c: 0x11f6, 0x83d: 0x134a, 0x83e: 0x145e, 0x83f: 0x085e,
- // Block 0x21, offset 0x840
- 0x840: 0x0912, 0x841: 0x0a1a, 0x842: 0x0b32, 0x843: 0x0cc2, 0x844: 0x0e7e, 0x845: 0x1042,
- 0x846: 0x149a, 0x847: 0x157e, 0x848: 0x15d2, 0x849: 0x15ea, 0x84a: 0x083a, 0x84b: 0x0cf6,
- 0x84c: 0x0da6, 0x84d: 0x13ee, 0x84e: 0x0afe, 0x84f: 0x0bda, 0x850: 0x0bf6, 0x851: 0x0c86,
- 0x852: 0x0e6e, 0x853: 0x0eba, 0x854: 0x0f6a, 0x855: 0x108e, 0x856: 0x1132, 0x857: 0x1196,
- 0x858: 0x13de, 0x859: 0x126e, 0x85a: 0x1406, 0x85b: 0x1482, 0x85c: 0x0812, 0x85d: 0x083e,
- 0x85e: 0x0926, 0x85f: 0x0eaa, 0x860: 0x12f6, 0x861: 0x133e, 0x862: 0x0b1e, 0x863: 0x0b8e,
- 0x864: 0x0c52, 0x865: 0x0db2, 0x866: 0x10da, 0x867: 0x0f26, 0x868: 0x073e, 0x869: 0x0982,
- 0x86a: 0x0a66, 0x86b: 0x0aca, 0x86c: 0x0b9a, 0x86d: 0x0f42, 0x86e: 0x0f5e, 0x86f: 0x116e,
- 0x870: 0x118e, 0x871: 0x1466, 0x872: 0x14e6, 0x873: 0x14f6, 0x874: 0x1532, 0x875: 0x0756,
- 0x876: 0x1082, 0x877: 0x1452, 0x878: 0x14ce, 0x879: 0x0bb2, 0x87a: 0x071a, 0x87b: 0x077a,
- 0x87c: 0x0a6a, 0x87d: 0x0a8a, 0x87e: 0x0cb2, 0x87f: 0x0d76,
- // Block 0x22, offset 0x880
- 0x880: 0x0ec6, 0x881: 0x0fce, 0x882: 0x127a, 0x883: 0x141a, 0x884: 0x1626, 0x885: 0x0ce6,
- 0x886: 0x14a6, 0x887: 0x0836, 0x888: 0x0d32, 0x889: 0x0d3e, 0x88a: 0x0e12, 0x88b: 0x0e4a,
- 0x88c: 0x0f4e, 0x88d: 0x0faa, 0x88e: 0x102a, 0x88f: 0x110e, 0x890: 0x153e, 0x891: 0x07b2,
- 0x892: 0x0c06, 0x893: 0x14b6, 0x894: 0x076a, 0x895: 0x0aae, 0x896: 0x0e32, 0x897: 0x13e2,
- 0x898: 0x0b6a, 0x899: 0x0bba, 0x89a: 0x0d46, 0x89b: 0x0f32, 0x89c: 0x14be, 0x89d: 0x081a,
- 0x89e: 0x0902, 0x89f: 0x0a9a, 0x8a0: 0x0cd6, 0x8a1: 0x0d22, 0x8a2: 0x0d62, 0x8a3: 0x0df6,
- 0x8a4: 0x0f4a, 0x8a5: 0x0fbe, 0x8a6: 0x115a, 0x8a7: 0x12fa, 0x8a8: 0x1306, 0x8a9: 0x145a,
- 0x8aa: 0x14da, 0x8ab: 0x0886, 0x8ac: 0x0e4e, 0x8ad: 0x0906, 0x8ae: 0x0eca, 0x8af: 0x0f6e,
- 0x8b0: 0x128a, 0x8b1: 0x14c2, 0x8b2: 0x15ae, 0x8b3: 0x15d6, 0x8b4: 0x0d3a, 0x8b5: 0x0e2a,
- 0x8b6: 0x11c6, 0x8b7: 0x10ba, 0x8b8: 0x10c6, 0x8b9: 0x10ea, 0x8ba: 0x0f1a, 0x8bb: 0x0ea2,
- 0x8bc: 0x1366, 0x8bd: 0x0736, 0x8be: 0x122e, 0x8bf: 0x081e,
- // Block 0x23, offset 0x8c0
- 0x8c0: 0x080e, 0x8c1: 0x0b0e, 0x8c2: 0x0c2e, 0x8c3: 0x10f6, 0x8c4: 0x0a56, 0x8c5: 0x0e06,
- 0x8c6: 0x0cf2, 0x8c7: 0x13ea, 0x8c8: 0x12ea, 0x8c9: 0x14ae, 0x8ca: 0x1326, 0x8cb: 0x0b2a,
- 0x8cc: 0x078a, 0x8cd: 0x095e, 0x8d0: 0x09b2,
- 0x8d2: 0x0ce2, 0x8d5: 0x07fa, 0x8d6: 0x0f22, 0x8d7: 0x0fe6,
- 0x8d8: 0x104a, 0x8d9: 0x1066, 0x8da: 0x106a, 0x8db: 0x107e, 0x8dc: 0x14fe, 0x8dd: 0x10ee,
- 0x8de: 0x1172, 0x8e0: 0x1292, 0x8e2: 0x1356,
- 0x8e5: 0x140a, 0x8e6: 0x1436,
- 0x8ea: 0x1552, 0x8eb: 0x1556, 0x8ec: 0x155a, 0x8ed: 0x15be, 0x8ee: 0x142e, 0x8ef: 0x14ca,
- 0x8f0: 0x075a, 0x8f1: 0x077e, 0x8f2: 0x0792, 0x8f3: 0x084e, 0x8f4: 0x085a, 0x8f5: 0x089a,
- 0x8f6: 0x094e, 0x8f7: 0x096a, 0x8f8: 0x0972, 0x8f9: 0x09ae, 0x8fa: 0x09ba, 0x8fb: 0x0a96,
- 0x8fc: 0x0a9e, 0x8fd: 0x0ba6, 0x8fe: 0x0bce, 0x8ff: 0x0bd6,
- // Block 0x24, offset 0x900
- 0x900: 0x0bee, 0x901: 0x0c9a, 0x902: 0x0cca, 0x903: 0x0cea, 0x904: 0x0d5a, 0x905: 0x0e1e,
- 0x906: 0x0e3a, 0x907: 0x0e6a, 0x908: 0x0ebe, 0x909: 0x0ede, 0x90a: 0x0f52, 0x90b: 0x1032,
- 0x90c: 0x104e, 0x90d: 0x1056, 0x90e: 0x1052, 0x90f: 0x105a, 0x910: 0x105e, 0x911: 0x1062,
- 0x912: 0x1076, 0x913: 0x107a, 0x914: 0x109e, 0x915: 0x10b2, 0x916: 0x10ce, 0x917: 0x1132,
- 0x918: 0x113a, 0x919: 0x1142, 0x91a: 0x1156, 0x91b: 0x117e, 0x91c: 0x11ce, 0x91d: 0x1202,
- 0x91e: 0x1202, 0x91f: 0x126a, 0x920: 0x1312, 0x921: 0x132a, 0x922: 0x135e, 0x923: 0x1362,
- 0x924: 0x13a6, 0x925: 0x13aa, 0x926: 0x1402, 0x927: 0x140a, 0x928: 0x14de, 0x929: 0x1522,
- 0x92a: 0x153a, 0x92b: 0x0b9e, 0x92c: 0x1721, 0x92d: 0x11e6,
- 0x930: 0x06e2, 0x931: 0x07e6, 0x932: 0x07a6, 0x933: 0x074e, 0x934: 0x078e, 0x935: 0x07ba,
- 0x936: 0x084a, 0x937: 0x0866, 0x938: 0x094e, 0x939: 0x093a, 0x93a: 0x094a, 0x93b: 0x0966,
- 0x93c: 0x09b2, 0x93d: 0x09c2, 0x93e: 0x0a06, 0x93f: 0x0a12,
- // Block 0x25, offset 0x940
- 0x940: 0x0a2e, 0x941: 0x0a3e, 0x942: 0x0b26, 0x943: 0x0b2e, 0x944: 0x0b5e, 0x945: 0x0b7e,
- 0x946: 0x0bae, 0x947: 0x0bc6, 0x948: 0x0bb6, 0x949: 0x0bd6, 0x94a: 0x0bca, 0x94b: 0x0bee,
- 0x94c: 0x0c0a, 0x94d: 0x0c62, 0x94e: 0x0c6e, 0x94f: 0x0c76, 0x950: 0x0c9e, 0x951: 0x0ce2,
- 0x952: 0x0d12, 0x953: 0x0d16, 0x954: 0x0d2a, 0x955: 0x0daa, 0x956: 0x0dba, 0x957: 0x0e12,
- 0x958: 0x0e5e, 0x959: 0x0e56, 0x95a: 0x0e6a, 0x95b: 0x0e86, 0x95c: 0x0ebe, 0x95d: 0x1016,
- 0x95e: 0x0ee2, 0x95f: 0x0f16, 0x960: 0x0f22, 0x961: 0x0f62, 0x962: 0x0f7e, 0x963: 0x0fa2,
- 0x964: 0x0fc6, 0x965: 0x0fca, 0x966: 0x0fe6, 0x967: 0x0fea, 0x968: 0x0ffa, 0x969: 0x100e,
- 0x96a: 0x100a, 0x96b: 0x103a, 0x96c: 0x10b6, 0x96d: 0x10ce, 0x96e: 0x10e6, 0x96f: 0x111e,
- 0x970: 0x1132, 0x971: 0x114e, 0x972: 0x117e, 0x973: 0x1232, 0x974: 0x125a, 0x975: 0x12ce,
- 0x976: 0x1316, 0x977: 0x1322, 0x978: 0x132a, 0x979: 0x1342, 0x97a: 0x1356, 0x97b: 0x1346,
- 0x97c: 0x135e, 0x97d: 0x135a, 0x97e: 0x1352, 0x97f: 0x1362,
- // Block 0x26, offset 0x980
- 0x980: 0x136e, 0x981: 0x13aa, 0x982: 0x13e6, 0x983: 0x1416, 0x984: 0x144e, 0x985: 0x146e,
- 0x986: 0x14ba, 0x987: 0x14de, 0x988: 0x14fe, 0x989: 0x1512, 0x98a: 0x1522, 0x98b: 0x152e,
- 0x98c: 0x153a, 0x98d: 0x158e, 0x98e: 0x162e, 0x98f: 0x16b8, 0x990: 0x16b3, 0x991: 0x16e5,
- 0x992: 0x060a, 0x993: 0x0632, 0x994: 0x0636, 0x995: 0x1767, 0x996: 0x1794, 0x997: 0x180c,
- 0x998: 0x161a, 0x999: 0x162a,
- // Block 0x27, offset 0x9c0
- 0x9c0: 0x06fe, 0x9c1: 0x06f6, 0x9c2: 0x0706, 0x9c3: 0x164a, 0x9c4: 0x074a, 0x9c5: 0x075a,
- 0x9c6: 0x075e, 0x9c7: 0x0766, 0x9c8: 0x076e, 0x9c9: 0x0772, 0x9ca: 0x077e, 0x9cb: 0x0776,
- 0x9cc: 0x05b6, 0x9cd: 0x165e, 0x9ce: 0x0792, 0x9cf: 0x0796, 0x9d0: 0x079a, 0x9d1: 0x07b6,
- 0x9d2: 0x164f, 0x9d3: 0x05ba, 0x9d4: 0x07a2, 0x9d5: 0x07c2, 0x9d6: 0x1659, 0x9d7: 0x07d2,
- 0x9d8: 0x07da, 0x9d9: 0x073a, 0x9da: 0x07e2, 0x9db: 0x07e6, 0x9dc: 0x1834, 0x9dd: 0x0802,
- 0x9de: 0x080a, 0x9df: 0x05c2, 0x9e0: 0x0822, 0x9e1: 0x0826, 0x9e2: 0x082e, 0x9e3: 0x0832,
- 0x9e4: 0x05c6, 0x9e5: 0x084a, 0x9e6: 0x084e, 0x9e7: 0x085a, 0x9e8: 0x0866, 0x9e9: 0x086a,
- 0x9ea: 0x086e, 0x9eb: 0x0876, 0x9ec: 0x0896, 0x9ed: 0x089a, 0x9ee: 0x08a2, 0x9ef: 0x08b2,
- 0x9f0: 0x08ba, 0x9f1: 0x08be, 0x9f2: 0x08be, 0x9f3: 0x08be, 0x9f4: 0x166d, 0x9f5: 0x0e96,
- 0x9f6: 0x08d2, 0x9f7: 0x08da, 0x9f8: 0x1672, 0x9f9: 0x08e6, 0x9fa: 0x08ee, 0x9fb: 0x08f6,
- 0x9fc: 0x091e, 0x9fd: 0x090a, 0x9fe: 0x0916, 0x9ff: 0x091a,
- // Block 0x28, offset 0xa00
- 0xa00: 0x0922, 0xa01: 0x092a, 0xa02: 0x092e, 0xa03: 0x0936, 0xa04: 0x093e, 0xa05: 0x0942,
- 0xa06: 0x0942, 0xa07: 0x094a, 0xa08: 0x0952, 0xa09: 0x0956, 0xa0a: 0x0962, 0xa0b: 0x0986,
- 0xa0c: 0x096a, 0xa0d: 0x098a, 0xa0e: 0x096e, 0xa0f: 0x0976, 0xa10: 0x080e, 0xa11: 0x09d2,
- 0xa12: 0x099a, 0xa13: 0x099e, 0xa14: 0x09a2, 0xa15: 0x0996, 0xa16: 0x09aa, 0xa17: 0x09a6,
- 0xa18: 0x09be, 0xa19: 0x1677, 0xa1a: 0x09da, 0xa1b: 0x09de, 0xa1c: 0x09e6, 0xa1d: 0x09f2,
- 0xa1e: 0x09fa, 0xa1f: 0x0a16, 0xa20: 0x167c, 0xa21: 0x1681, 0xa22: 0x0a22, 0xa23: 0x0a26,
- 0xa24: 0x0a2a, 0xa25: 0x0a1e, 0xa26: 0x0a32, 0xa27: 0x05ca, 0xa28: 0x05ce, 0xa29: 0x0a3a,
- 0xa2a: 0x0a42, 0xa2b: 0x0a42, 0xa2c: 0x1686, 0xa2d: 0x0a5e, 0xa2e: 0x0a62, 0xa2f: 0x0a66,
- 0xa30: 0x0a6e, 0xa31: 0x168b, 0xa32: 0x0a76, 0xa33: 0x0a7a, 0xa34: 0x0b52, 0xa35: 0x0a82,
- 0xa36: 0x05d2, 0xa37: 0x0a8e, 0xa38: 0x0a9e, 0xa39: 0x0aaa, 0xa3a: 0x0aa6, 0xa3b: 0x1695,
- 0xa3c: 0x0ab2, 0xa3d: 0x169a, 0xa3e: 0x0abe, 0xa3f: 0x0aba,
- // Block 0x29, offset 0xa40
- 0xa40: 0x0ac2, 0xa41: 0x0ad2, 0xa42: 0x0ad6, 0xa43: 0x05d6, 0xa44: 0x0ae6, 0xa45: 0x0aee,
- 0xa46: 0x0af2, 0xa47: 0x0af6, 0xa48: 0x05da, 0xa49: 0x169f, 0xa4a: 0x05de, 0xa4b: 0x0b12,
- 0xa4c: 0x0b16, 0xa4d: 0x0b1a, 0xa4e: 0x0b22, 0xa4f: 0x1866, 0xa50: 0x0b3a, 0xa51: 0x16a9,
- 0xa52: 0x16a9, 0xa53: 0x11da, 0xa54: 0x0b4a, 0xa55: 0x0b4a, 0xa56: 0x05e2, 0xa57: 0x16cc,
- 0xa58: 0x179e, 0xa59: 0x0b5a, 0xa5a: 0x0b62, 0xa5b: 0x05e6, 0xa5c: 0x0b76, 0xa5d: 0x0b86,
- 0xa5e: 0x0b8a, 0xa5f: 0x0b92, 0xa60: 0x0ba2, 0xa61: 0x05ee, 0xa62: 0x05ea, 0xa63: 0x0ba6,
- 0xa64: 0x16ae, 0xa65: 0x0baa, 0xa66: 0x0bbe, 0xa67: 0x0bc2, 0xa68: 0x0bc6, 0xa69: 0x0bc2,
- 0xa6a: 0x0bd2, 0xa6b: 0x0bd6, 0xa6c: 0x0be6, 0xa6d: 0x0bde, 0xa6e: 0x0be2, 0xa6f: 0x0bea,
- 0xa70: 0x0bee, 0xa71: 0x0bf2, 0xa72: 0x0bfe, 0xa73: 0x0c02, 0xa74: 0x0c1a, 0xa75: 0x0c22,
- 0xa76: 0x0c32, 0xa77: 0x0c46, 0xa78: 0x16bd, 0xa79: 0x0c42, 0xa7a: 0x0c36, 0xa7b: 0x0c4e,
- 0xa7c: 0x0c56, 0xa7d: 0x0c6a, 0xa7e: 0x16c2, 0xa7f: 0x0c72,
- // Block 0x2a, offset 0xa80
- 0xa80: 0x0c66, 0xa81: 0x0c5e, 0xa82: 0x05f2, 0xa83: 0x0c7a, 0xa84: 0x0c82, 0xa85: 0x0c8a,
- 0xa86: 0x0c7e, 0xa87: 0x05f6, 0xa88: 0x0c9a, 0xa89: 0x0ca2, 0xa8a: 0x16c7, 0xa8b: 0x0cce,
- 0xa8c: 0x0d02, 0xa8d: 0x0cde, 0xa8e: 0x0602, 0xa8f: 0x0cea, 0xa90: 0x05fe, 0xa91: 0x05fa,
- 0xa92: 0x07c6, 0xa93: 0x07ca, 0xa94: 0x0d06, 0xa95: 0x0cee, 0xa96: 0x11ae, 0xa97: 0x0666,
- 0xa98: 0x0d12, 0xa99: 0x0d16, 0xa9a: 0x0d1a, 0xa9b: 0x0d2e, 0xa9c: 0x0d26, 0xa9d: 0x16e0,
- 0xa9e: 0x0606, 0xa9f: 0x0d42, 0xaa0: 0x0d36, 0xaa1: 0x0d52, 0xaa2: 0x0d5a, 0xaa3: 0x16ea,
- 0xaa4: 0x0d5e, 0xaa5: 0x0d4a, 0xaa6: 0x0d66, 0xaa7: 0x060a, 0xaa8: 0x0d6a, 0xaa9: 0x0d6e,
- 0xaaa: 0x0d72, 0xaab: 0x0d7e, 0xaac: 0x16ef, 0xaad: 0x0d86, 0xaae: 0x060e, 0xaaf: 0x0d92,
- 0xab0: 0x16f4, 0xab1: 0x0d96, 0xab2: 0x0612, 0xab3: 0x0da2, 0xab4: 0x0dae, 0xab5: 0x0dba,
- 0xab6: 0x0dbe, 0xab7: 0x16f9, 0xab8: 0x1690, 0xab9: 0x16fe, 0xaba: 0x0dde, 0xabb: 0x1703,
- 0xabc: 0x0dea, 0xabd: 0x0df2, 0xabe: 0x0de2, 0xabf: 0x0dfe,
- // Block 0x2b, offset 0xac0
- 0xac0: 0x0e0e, 0xac1: 0x0e1e, 0xac2: 0x0e12, 0xac3: 0x0e16, 0xac4: 0x0e22, 0xac5: 0x0e26,
- 0xac6: 0x1708, 0xac7: 0x0e0a, 0xac8: 0x0e3e, 0xac9: 0x0e42, 0xaca: 0x0616, 0xacb: 0x0e56,
- 0xacc: 0x0e52, 0xacd: 0x170d, 0xace: 0x0e36, 0xacf: 0x0e72, 0xad0: 0x1712, 0xad1: 0x1717,
- 0xad2: 0x0e76, 0xad3: 0x0e8a, 0xad4: 0x0e86, 0xad5: 0x0e82, 0xad6: 0x061a, 0xad7: 0x0e8e,
- 0xad8: 0x0e9e, 0xad9: 0x0e9a, 0xada: 0x0ea6, 0xadb: 0x1654, 0xadc: 0x0eb6, 0xadd: 0x171c,
- 0xade: 0x0ec2, 0xadf: 0x1726, 0xae0: 0x0ed6, 0xae1: 0x0ee2, 0xae2: 0x0ef6, 0xae3: 0x172b,
- 0xae4: 0x0f0a, 0xae5: 0x0f0e, 0xae6: 0x1730, 0xae7: 0x1735, 0xae8: 0x0f2a, 0xae9: 0x0f3a,
- 0xaea: 0x061e, 0xaeb: 0x0f3e, 0xaec: 0x0622, 0xaed: 0x0622, 0xaee: 0x0f56, 0xaef: 0x0f5a,
- 0xaf0: 0x0f62, 0xaf1: 0x0f66, 0xaf2: 0x0f72, 0xaf3: 0x0626, 0xaf4: 0x0f8a, 0xaf5: 0x173a,
- 0xaf6: 0x0fa6, 0xaf7: 0x173f, 0xaf8: 0x0fb2, 0xaf9: 0x16a4, 0xafa: 0x0fc2, 0xafb: 0x1744,
- 0xafc: 0x1749, 0xafd: 0x174e, 0xafe: 0x062a, 0xaff: 0x062e,
- // Block 0x2c, offset 0xb00
- 0xb00: 0x0ffa, 0xb01: 0x1758, 0xb02: 0x1753, 0xb03: 0x175d, 0xb04: 0x1762, 0xb05: 0x1002,
- 0xb06: 0x1006, 0xb07: 0x1006, 0xb08: 0x100e, 0xb09: 0x0636, 0xb0a: 0x1012, 0xb0b: 0x063a,
- 0xb0c: 0x063e, 0xb0d: 0x176c, 0xb0e: 0x1026, 0xb0f: 0x102e, 0xb10: 0x103a, 0xb11: 0x0642,
- 0xb12: 0x1771, 0xb13: 0x105e, 0xb14: 0x1776, 0xb15: 0x177b, 0xb16: 0x107e, 0xb17: 0x1096,
- 0xb18: 0x0646, 0xb19: 0x109e, 0xb1a: 0x10a2, 0xb1b: 0x10a6, 0xb1c: 0x1780, 0xb1d: 0x1785,
- 0xb1e: 0x1785, 0xb1f: 0x10be, 0xb20: 0x064a, 0xb21: 0x178a, 0xb22: 0x10d2, 0xb23: 0x10d6,
- 0xb24: 0x064e, 0xb25: 0x178f, 0xb26: 0x10f2, 0xb27: 0x0652, 0xb28: 0x1102, 0xb29: 0x10fa,
- 0xb2a: 0x110a, 0xb2b: 0x1799, 0xb2c: 0x1122, 0xb2d: 0x0656, 0xb2e: 0x112e, 0xb2f: 0x1136,
- 0xb30: 0x1146, 0xb31: 0x065a, 0xb32: 0x17a3, 0xb33: 0x17a8, 0xb34: 0x065e, 0xb35: 0x17ad,
- 0xb36: 0x115e, 0xb37: 0x17b2, 0xb38: 0x116a, 0xb39: 0x1176, 0xb3a: 0x117e, 0xb3b: 0x17b7,
- 0xb3c: 0x17bc, 0xb3d: 0x1192, 0xb3e: 0x17c1, 0xb3f: 0x119a,
- // Block 0x2d, offset 0xb40
- 0xb40: 0x16d1, 0xb41: 0x0662, 0xb42: 0x11b2, 0xb43: 0x11b6, 0xb44: 0x066a, 0xb45: 0x11ba,
- 0xb46: 0x0a36, 0xb47: 0x17c6, 0xb48: 0x17cb, 0xb49: 0x16d6, 0xb4a: 0x16db, 0xb4b: 0x11da,
- 0xb4c: 0x11de, 0xb4d: 0x13f6, 0xb4e: 0x066e, 0xb4f: 0x120a, 0xb50: 0x1206, 0xb51: 0x120e,
- 0xb52: 0x0842, 0xb53: 0x1212, 0xb54: 0x1216, 0xb55: 0x121a, 0xb56: 0x1222, 0xb57: 0x17d0,
- 0xb58: 0x121e, 0xb59: 0x1226, 0xb5a: 0x123a, 0xb5b: 0x123e, 0xb5c: 0x122a, 0xb5d: 0x1242,
- 0xb5e: 0x1256, 0xb5f: 0x126a, 0xb60: 0x1236, 0xb61: 0x124a, 0xb62: 0x124e, 0xb63: 0x1252,
- 0xb64: 0x17d5, 0xb65: 0x17df, 0xb66: 0x17da, 0xb67: 0x0672, 0xb68: 0x1272, 0xb69: 0x1276,
- 0xb6a: 0x127e, 0xb6b: 0x17f3, 0xb6c: 0x1282, 0xb6d: 0x17e4, 0xb6e: 0x0676, 0xb6f: 0x067a,
- 0xb70: 0x17e9, 0xb71: 0x17ee, 0xb72: 0x067e, 0xb73: 0x12a2, 0xb74: 0x12a6, 0xb75: 0x12aa,
- 0xb76: 0x12ae, 0xb77: 0x12ba, 0xb78: 0x12b6, 0xb79: 0x12c2, 0xb7a: 0x12be, 0xb7b: 0x12ce,
- 0xb7c: 0x12c6, 0xb7d: 0x12ca, 0xb7e: 0x12d2, 0xb7f: 0x0682,
- // Block 0x2e, offset 0xb80
- 0xb80: 0x12da, 0xb81: 0x12de, 0xb82: 0x0686, 0xb83: 0x12ee, 0xb84: 0x12f2, 0xb85: 0x17f8,
- 0xb86: 0x12fe, 0xb87: 0x1302, 0xb88: 0x068a, 0xb89: 0x130e, 0xb8a: 0x05be, 0xb8b: 0x17fd,
- 0xb8c: 0x1802, 0xb8d: 0x068e, 0xb8e: 0x0692, 0xb8f: 0x133a, 0xb90: 0x1352, 0xb91: 0x136e,
- 0xb92: 0x137e, 0xb93: 0x1807, 0xb94: 0x1392, 0xb95: 0x1396, 0xb96: 0x13ae, 0xb97: 0x13ba,
- 0xb98: 0x1811, 0xb99: 0x1663, 0xb9a: 0x13c6, 0xb9b: 0x13c2, 0xb9c: 0x13ce, 0xb9d: 0x1668,
- 0xb9e: 0x13da, 0xb9f: 0x13e6, 0xba0: 0x1816, 0xba1: 0x181b, 0xba2: 0x1426, 0xba3: 0x1432,
- 0xba4: 0x143a, 0xba5: 0x1820, 0xba6: 0x143e, 0xba7: 0x146a, 0xba8: 0x1476, 0xba9: 0x147a,
- 0xbaa: 0x1472, 0xbab: 0x1486, 0xbac: 0x148a, 0xbad: 0x1825, 0xbae: 0x1496, 0xbaf: 0x0696,
- 0xbb0: 0x149e, 0xbb1: 0x182a, 0xbb2: 0x069a, 0xbb3: 0x14d6, 0xbb4: 0x0ac6, 0xbb5: 0x14ee,
- 0xbb6: 0x182f, 0xbb7: 0x1839, 0xbb8: 0x069e, 0xbb9: 0x06a2, 0xbba: 0x1516, 0xbbb: 0x183e,
- 0xbbc: 0x06a6, 0xbbd: 0x1843, 0xbbe: 0x152e, 0xbbf: 0x152e,
- // Block 0x2f, offset 0xbc0
- 0xbc0: 0x1536, 0xbc1: 0x1848, 0xbc2: 0x154e, 0xbc3: 0x06aa, 0xbc4: 0x155e, 0xbc5: 0x156a,
- 0xbc6: 0x1572, 0xbc7: 0x157a, 0xbc8: 0x06ae, 0xbc9: 0x184d, 0xbca: 0x158e, 0xbcb: 0x15aa,
- 0xbcc: 0x15b6, 0xbcd: 0x06b2, 0xbce: 0x06b6, 0xbcf: 0x15ba, 0xbd0: 0x1852, 0xbd1: 0x06ba,
- 0xbd2: 0x1857, 0xbd3: 0x185c, 0xbd4: 0x1861, 0xbd5: 0x15de, 0xbd6: 0x06be, 0xbd7: 0x15f2,
- 0xbd8: 0x15fa, 0xbd9: 0x15fe, 0xbda: 0x1606, 0xbdb: 0x160e, 0xbdc: 0x1616, 0xbdd: 0x186b,
-}
-
-// nfcIndex: 22 blocks, 1408 entries, 1408 bytes
-// Block 0 is the zero block.
-var nfcIndex = [1408]uint8{
- // Block 0x0, offset 0x0
- // Block 0x1, offset 0x40
- // Block 0x2, offset 0x80
- // Block 0x3, offset 0xc0
- 0xc2: 0x2e, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x2f, 0xc7: 0x04,
- 0xc8: 0x05, 0xca: 0x30, 0xcb: 0x31, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x32,
- 0xd0: 0x09, 0xd1: 0x33, 0xd2: 0x34, 0xd3: 0x0a, 0xd6: 0x0b, 0xd7: 0x35,
- 0xd8: 0x36, 0xd9: 0x0c, 0xdb: 0x37, 0xdc: 0x38, 0xdd: 0x39, 0xdf: 0x3a,
- 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05,
- 0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a,
- 0xf0: 0x13,
- // Block 0x4, offset 0x100
- 0x120: 0x3b, 0x121: 0x3c, 0x123: 0x0d, 0x124: 0x3d, 0x125: 0x3e, 0x126: 0x3f, 0x127: 0x40,
- 0x128: 0x41, 0x129: 0x42, 0x12a: 0x43, 0x12b: 0x44, 0x12c: 0x3f, 0x12d: 0x45, 0x12e: 0x46, 0x12f: 0x47,
- 0x131: 0x48, 0x132: 0x49, 0x133: 0x4a, 0x134: 0x4b, 0x135: 0x4c, 0x137: 0x4d,
- 0x138: 0x4e, 0x139: 0x4f, 0x13a: 0x50, 0x13b: 0x51, 0x13c: 0x52, 0x13d: 0x53, 0x13e: 0x54, 0x13f: 0x55,
- // Block 0x5, offset 0x140
- 0x140: 0x56, 0x142: 0x57, 0x144: 0x58, 0x145: 0x59, 0x146: 0x5a, 0x147: 0x5b,
- 0x14d: 0x5c,
- 0x15c: 0x5d, 0x15f: 0x5e,
- 0x162: 0x5f, 0x164: 0x60,
- 0x168: 0x61, 0x169: 0x62, 0x16a: 0x63, 0x16b: 0x64, 0x16c: 0x0e, 0x16d: 0x65, 0x16e: 0x66, 0x16f: 0x67,
- 0x170: 0x68, 0x173: 0x69, 0x177: 0x0f,
- 0x178: 0x10, 0x179: 0x11, 0x17a: 0x12, 0x17b: 0x13, 0x17c: 0x14, 0x17d: 0x15, 0x17e: 0x16, 0x17f: 0x17,
- // Block 0x6, offset 0x180
- 0x180: 0x6a, 0x183: 0x6b, 0x184: 0x6c, 0x186: 0x6d, 0x187: 0x6e,
- 0x188: 0x6f, 0x189: 0x18, 0x18a: 0x19, 0x18b: 0x70, 0x18c: 0x71,
- 0x1ab: 0x72,
- 0x1b3: 0x73, 0x1b5: 0x74, 0x1b7: 0x75,
- // Block 0x7, offset 0x1c0
- 0x1c0: 0x76, 0x1c1: 0x1a, 0x1c2: 0x1b, 0x1c3: 0x1c, 0x1c4: 0x77, 0x1c5: 0x78,
- 0x1c9: 0x79, 0x1cc: 0x7a, 0x1cd: 0x7b,
- // Block 0x8, offset 0x200
- 0x219: 0x7c, 0x21a: 0x7d, 0x21b: 0x7e,
- 0x220: 0x7f, 0x223: 0x80, 0x224: 0x81, 0x225: 0x82, 0x226: 0x83, 0x227: 0x84,
- 0x22a: 0x85, 0x22b: 0x86, 0x22f: 0x87,
- 0x230: 0x88, 0x231: 0x89, 0x232: 0x8a, 0x233: 0x8b, 0x234: 0x8c, 0x235: 0x8d, 0x236: 0x8e, 0x237: 0x88,
- 0x238: 0x89, 0x239: 0x8a, 0x23a: 0x8b, 0x23b: 0x8c, 0x23c: 0x8d, 0x23d: 0x8e, 0x23e: 0x88, 0x23f: 0x89,
- // Block 0x9, offset 0x240
- 0x240: 0x8a, 0x241: 0x8b, 0x242: 0x8c, 0x243: 0x8d, 0x244: 0x8e, 0x245: 0x88, 0x246: 0x89, 0x247: 0x8a,
- 0x248: 0x8b, 0x249: 0x8c, 0x24a: 0x8d, 0x24b: 0x8e, 0x24c: 0x88, 0x24d: 0x89, 0x24e: 0x8a, 0x24f: 0x8b,
- 0x250: 0x8c, 0x251: 0x8d, 0x252: 0x8e, 0x253: 0x88, 0x254: 0x89, 0x255: 0x8a, 0x256: 0x8b, 0x257: 0x8c,
- 0x258: 0x8d, 0x259: 0x8e, 0x25a: 0x88, 0x25b: 0x89, 0x25c: 0x8a, 0x25d: 0x8b, 0x25e: 0x8c, 0x25f: 0x8d,
- 0x260: 0x8e, 0x261: 0x88, 0x262: 0x89, 0x263: 0x8a, 0x264: 0x8b, 0x265: 0x8c, 0x266: 0x8d, 0x267: 0x8e,
- 0x268: 0x88, 0x269: 0x89, 0x26a: 0x8a, 0x26b: 0x8b, 0x26c: 0x8c, 0x26d: 0x8d, 0x26e: 0x8e, 0x26f: 0x88,
- 0x270: 0x89, 0x271: 0x8a, 0x272: 0x8b, 0x273: 0x8c, 0x274: 0x8d, 0x275: 0x8e, 0x276: 0x88, 0x277: 0x89,
- 0x278: 0x8a, 0x279: 0x8b, 0x27a: 0x8c, 0x27b: 0x8d, 0x27c: 0x8e, 0x27d: 0x88, 0x27e: 0x89, 0x27f: 0x8a,
- // Block 0xa, offset 0x280
- 0x280: 0x8b, 0x281: 0x8c, 0x282: 0x8d, 0x283: 0x8e, 0x284: 0x88, 0x285: 0x89, 0x286: 0x8a, 0x287: 0x8b,
- 0x288: 0x8c, 0x289: 0x8d, 0x28a: 0x8e, 0x28b: 0x88, 0x28c: 0x89, 0x28d: 0x8a, 0x28e: 0x8b, 0x28f: 0x8c,
- 0x290: 0x8d, 0x291: 0x8e, 0x292: 0x88, 0x293: 0x89, 0x294: 0x8a, 0x295: 0x8b, 0x296: 0x8c, 0x297: 0x8d,
- 0x298: 0x8e, 0x299: 0x88, 0x29a: 0x89, 0x29b: 0x8a, 0x29c: 0x8b, 0x29d: 0x8c, 0x29e: 0x8d, 0x29f: 0x8e,
- 0x2a0: 0x88, 0x2a1: 0x89, 0x2a2: 0x8a, 0x2a3: 0x8b, 0x2a4: 0x8c, 0x2a5: 0x8d, 0x2a6: 0x8e, 0x2a7: 0x88,
- 0x2a8: 0x89, 0x2a9: 0x8a, 0x2aa: 0x8b, 0x2ab: 0x8c, 0x2ac: 0x8d, 0x2ad: 0x8e, 0x2ae: 0x88, 0x2af: 0x89,
- 0x2b0: 0x8a, 0x2b1: 0x8b, 0x2b2: 0x8c, 0x2b3: 0x8d, 0x2b4: 0x8e, 0x2b5: 0x88, 0x2b6: 0x89, 0x2b7: 0x8a,
- 0x2b8: 0x8b, 0x2b9: 0x8c, 0x2ba: 0x8d, 0x2bb: 0x8e, 0x2bc: 0x88, 0x2bd: 0x89, 0x2be: 0x8a, 0x2bf: 0x8b,
- // Block 0xb, offset 0x2c0
- 0x2c0: 0x8c, 0x2c1: 0x8d, 0x2c2: 0x8e, 0x2c3: 0x88, 0x2c4: 0x89, 0x2c5: 0x8a, 0x2c6: 0x8b, 0x2c7: 0x8c,
- 0x2c8: 0x8d, 0x2c9: 0x8e, 0x2ca: 0x88, 0x2cb: 0x89, 0x2cc: 0x8a, 0x2cd: 0x8b, 0x2ce: 0x8c, 0x2cf: 0x8d,
- 0x2d0: 0x8e, 0x2d1: 0x88, 0x2d2: 0x89, 0x2d3: 0x8a, 0x2d4: 0x8b, 0x2d5: 0x8c, 0x2d6: 0x8d, 0x2d7: 0x8e,
- 0x2d8: 0x88, 0x2d9: 0x89, 0x2da: 0x8a, 0x2db: 0x8b, 0x2dc: 0x8c, 0x2dd: 0x8d, 0x2de: 0x8f,
- // Block 0xc, offset 0x300
- 0x324: 0x1d, 0x325: 0x1e, 0x326: 0x1f, 0x327: 0x20,
- 0x328: 0x21, 0x329: 0x22, 0x32a: 0x23, 0x32b: 0x24, 0x32c: 0x90, 0x32d: 0x91, 0x32e: 0x92,
- 0x331: 0x93, 0x332: 0x94, 0x333: 0x95, 0x334: 0x96,
- 0x338: 0x97, 0x339: 0x98, 0x33a: 0x99, 0x33b: 0x9a, 0x33e: 0x9b, 0x33f: 0x9c,
- // Block 0xd, offset 0x340
- 0x347: 0x9d,
- 0x34b: 0x9e, 0x34d: 0x9f,
- 0x368: 0xa0, 0x36b: 0xa1,
- 0x374: 0xa2,
- 0x37a: 0xa3, 0x37d: 0xa4,
- // Block 0xe, offset 0x380
- 0x381: 0xa5, 0x382: 0xa6, 0x384: 0xa7, 0x385: 0x83, 0x387: 0xa8,
- 0x388: 0xa9, 0x38b: 0xaa, 0x38c: 0xab, 0x38d: 0xac,
- 0x391: 0xad, 0x392: 0xae, 0x393: 0xaf, 0x396: 0xb0, 0x397: 0xb1,
- 0x398: 0x74, 0x39a: 0xb2, 0x39c: 0xb3,
- 0x3a0: 0xb4, 0x3a4: 0xb5, 0x3a5: 0xb6, 0x3a7: 0xb7,
- 0x3a8: 0xb8, 0x3a9: 0xb9, 0x3aa: 0xba,
- 0x3b0: 0x74, 0x3b5: 0xbb, 0x3b6: 0xbc,
- // Block 0xf, offset 0x3c0
- 0x3eb: 0xbd, 0x3ec: 0xbe,
- 0x3ff: 0xbf,
- // Block 0x10, offset 0x400
- 0x432: 0xc0,
- // Block 0x11, offset 0x440
- 0x445: 0xc1, 0x446: 0xc2, 0x447: 0xc3,
- 0x449: 0xc4,
- // Block 0x12, offset 0x480
- 0x480: 0xc5, 0x484: 0xbe,
- 0x48b: 0xc6,
- 0x4a3: 0xc7, 0x4a5: 0xc8,
- // Block 0x13, offset 0x4c0
- 0x4c8: 0xc9,
- // Block 0x14, offset 0x500
- 0x520: 0x25, 0x521: 0x26, 0x522: 0x27, 0x523: 0x28, 0x524: 0x29, 0x525: 0x2a, 0x526: 0x2b, 0x527: 0x2c,
- 0x528: 0x2d,
- // Block 0x15, offset 0x540
- 0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d,
- 0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11,
- 0x56f: 0x12,
-}
-
-// nfcSparseOffset: 156 entries, 312 bytes
-var nfcSparseOffset = []uint16{0x0, 0x5, 0x9, 0xb, 0xd, 0x18, 0x28, 0x2a, 0x2f, 0x3a, 0x49, 0x56, 0x5e, 0x63, 0x68, 0x6a, 0x72, 0x79, 0x7c, 0x84, 0x88, 0x8c, 0x8e, 0x90, 0x99, 0x9d, 0xa4, 0xa9, 0xac, 0xb6, 0xb9, 0xc0, 0xc8, 0xcb, 0xcd, 0xd0, 0xd2, 0xd7, 0xe8, 0xf4, 0xf6, 0xfc, 0xfe, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10b, 0x10e, 0x110, 0x113, 0x116, 0x11a, 0x120, 0x122, 0x12b, 0x12d, 0x130, 0x132, 0x13d, 0x141, 0x14f, 0x152, 0x158, 0x15e, 0x169, 0x16d, 0x16f, 0x171, 0x173, 0x175, 0x177, 0x17d, 0x181, 0x183, 0x185, 0x18d, 0x191, 0x194, 0x196, 0x198, 0x19b, 0x19e, 0x1a0, 0x1a2, 0x1a4, 0x1a6, 0x1ac, 0x1af, 0x1b1, 0x1b8, 0x1be, 0x1c4, 0x1cc, 0x1d2, 0x1d8, 0x1de, 0x1e2, 0x1f0, 0x1f9, 0x1fc, 0x1ff, 0x201, 0x204, 0x206, 0x20a, 0x20f, 0x211, 0x213, 0x218, 0x21e, 0x220, 0x222, 0x224, 0x22a, 0x22d, 0x22f, 0x231, 0x237, 0x23a, 0x242, 0x249, 0x24c, 0x24f, 0x251, 0x254, 0x25c, 0x260, 0x267, 0x26a, 0x270, 0x272, 0x275, 0x277, 0x27a, 0x27f, 0x281, 0x283, 0x285, 0x287, 0x289, 0x28c, 0x28e, 0x290, 0x292, 0x294, 0x296, 0x2a3, 0x2ad, 0x2af, 0x2b1, 0x2b7, 0x2b9, 0x2bb, 0x2be}
-
-// nfcSparseValues: 704 entries, 2816 bytes
-var nfcSparseValues = [704]valueRange{
- // Block 0x0, offset 0x0
- {value: 0x0000, lo: 0x04},
- {value: 0xa100, lo: 0xa8, hi: 0xa8},
- {value: 0x8100, lo: 0xaf, hi: 0xaf},
- {value: 0x8100, lo: 0xb4, hi: 0xb4},
- {value: 0x8100, lo: 0xb8, hi: 0xb8},
- // Block 0x1, offset 0x5
- {value: 0x0091, lo: 0x03},
- {value: 0x46f9, lo: 0xa0, hi: 0xa1},
- {value: 0x472b, lo: 0xaf, hi: 0xb0},
- {value: 0xa000, lo: 0xb7, hi: 0xb7},
- // Block 0x2, offset 0x9
- {value: 0x0000, lo: 0x01},
- {value: 0xa000, lo: 0x92, hi: 0x92},
- // Block 0x3, offset 0xb
- {value: 0x0000, lo: 0x01},
- {value: 0x8100, lo: 0x98, hi: 0x9d},
- // Block 0x4, offset 0xd
- {value: 0x0006, lo: 0x0a},
- {value: 0xa000, lo: 0x81, hi: 0x81},
- {value: 0xa000, lo: 0x85, hi: 0x85},
- {value: 0xa000, lo: 0x89, hi: 0x89},
- {value: 0x4857, lo: 0x8a, hi: 0x8a},
- {value: 0x4875, lo: 0x8b, hi: 0x8b},
- {value: 0x36de, lo: 0x8c, hi: 0x8c},
- {value: 0x36f6, lo: 0x8d, hi: 0x8d},
- {value: 0x488d, lo: 0x8e, hi: 0x8e},
- {value: 0xa000, lo: 0x92, hi: 0x92},
- {value: 0x3714, lo: 0x93, hi: 0x94},
- // Block 0x5, offset 0x18
- {value: 0x0000, lo: 0x0f},
- {value: 0xa000, lo: 0x83, hi: 0x83},
- {value: 0xa000, lo: 0x87, hi: 0x87},
- {value: 0xa000, lo: 0x8b, hi: 0x8b},
- {value: 0xa000, lo: 0x8d, hi: 0x8d},
- {value: 0x37bc, lo: 0x90, hi: 0x90},
- {value: 0x37c8, lo: 0x91, hi: 0x91},
- {value: 0x37b6, lo: 0x93, hi: 0x93},
- {value: 0xa000, lo: 0x96, hi: 0x96},
- {value: 0x382e, lo: 0x97, hi: 0x97},
- {value: 0x37f8, lo: 0x9c, hi: 0x9c},
- {value: 0x37e0, lo: 0x9d, hi: 0x9d},
- {value: 0x380a, lo: 0x9e, hi: 0x9e},
- {value: 0xa000, lo: 0xb4, hi: 0xb5},
- {value: 0x3834, lo: 0xb6, hi: 0xb6},
- {value: 0x383a, lo: 0xb7, hi: 0xb7},
- // Block 0x6, offset 0x28
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0x83, hi: 0x87},
- // Block 0x7, offset 0x2a
- {value: 0x0001, lo: 0x04},
- {value: 0x8114, lo: 0x81, hi: 0x82},
- {value: 0x8133, lo: 0x84, hi: 0x84},
- {value: 0x812e, lo: 0x85, hi: 0x85},
- {value: 0x810e, lo: 0x87, hi: 0x87},
- // Block 0x8, offset 0x2f
- {value: 0x0000, lo: 0x0a},
- {value: 0x8133, lo: 0x90, hi: 0x97},
- {value: 0x811a, lo: 0x98, hi: 0x98},
- {value: 0x811b, lo: 0x99, hi: 0x99},
- {value: 0x811c, lo: 0x9a, hi: 0x9a},
- {value: 0x3858, lo: 0xa2, hi: 0xa2},
- {value: 0x385e, lo: 0xa3, hi: 0xa3},
- {value: 0x386a, lo: 0xa4, hi: 0xa4},
- {value: 0x3864, lo: 0xa5, hi: 0xa5},
- {value: 0x3870, lo: 0xa6, hi: 0xa6},
- {value: 0xa000, lo: 0xa7, hi: 0xa7},
- // Block 0x9, offset 0x3a
- {value: 0x0000, lo: 0x0e},
- {value: 0x3882, lo: 0x80, hi: 0x80},
- {value: 0xa000, lo: 0x81, hi: 0x81},
- {value: 0x3876, lo: 0x82, hi: 0x82},
- {value: 0xa000, lo: 0x92, hi: 0x92},
- {value: 0x387c, lo: 0x93, hi: 0x93},
- {value: 0xa000, lo: 0x95, hi: 0x95},
- {value: 0x8133, lo: 0x96, hi: 0x9c},
- {value: 0x8133, lo: 0x9f, hi: 0xa2},
- {value: 0x812e, lo: 0xa3, hi: 0xa3},
- {value: 0x8133, lo: 0xa4, hi: 0xa4},
- {value: 0x8133, lo: 0xa7, hi: 0xa8},
- {value: 0x812e, lo: 0xaa, hi: 0xaa},
- {value: 0x8133, lo: 0xab, hi: 0xac},
- {value: 0x812e, lo: 0xad, hi: 0xad},
- // Block 0xa, offset 0x49
- {value: 0x0000, lo: 0x0c},
- {value: 0x8120, lo: 0x91, hi: 0x91},
- {value: 0x8133, lo: 0xb0, hi: 0xb0},
- {value: 0x812e, lo: 0xb1, hi: 0xb1},
- {value: 0x8133, lo: 0xb2, hi: 0xb3},
- {value: 0x812e, lo: 0xb4, hi: 0xb4},
- {value: 0x8133, lo: 0xb5, hi: 0xb6},
- {value: 0x812e, lo: 0xb7, hi: 0xb9},
- {value: 0x8133, lo: 0xba, hi: 0xba},
- {value: 0x812e, lo: 0xbb, hi: 0xbc},
- {value: 0x8133, lo: 0xbd, hi: 0xbd},
- {value: 0x812e, lo: 0xbe, hi: 0xbe},
- {value: 0x8133, lo: 0xbf, hi: 0xbf},
- // Block 0xb, offset 0x56
- {value: 0x0005, lo: 0x07},
- {value: 0x8133, lo: 0x80, hi: 0x80},
- {value: 0x8133, lo: 0x81, hi: 0x81},
- {value: 0x812e, lo: 0x82, hi: 0x83},
- {value: 0x812e, lo: 0x84, hi: 0x85},
- {value: 0x812e, lo: 0x86, hi: 0x87},
- {value: 0x812e, lo: 0x88, hi: 0x89},
- {value: 0x8133, lo: 0x8a, hi: 0x8a},
- // Block 0xc, offset 0x5e
- {value: 0x0000, lo: 0x04},
- {value: 0x8133, lo: 0xab, hi: 0xb1},
- {value: 0x812e, lo: 0xb2, hi: 0xb2},
- {value: 0x8133, lo: 0xb3, hi: 0xb3},
- {value: 0x812e, lo: 0xbd, hi: 0xbd},
- // Block 0xd, offset 0x63
- {value: 0x0000, lo: 0x04},
- {value: 0x8133, lo: 0x96, hi: 0x99},
- {value: 0x8133, lo: 0x9b, hi: 0xa3},
- {value: 0x8133, lo: 0xa5, hi: 0xa7},
- {value: 0x8133, lo: 0xa9, hi: 0xad},
- // Block 0xe, offset 0x68
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0x99, hi: 0x9b},
- // Block 0xf, offset 0x6a
- {value: 0x0000, lo: 0x07},
- {value: 0xa000, lo: 0xa8, hi: 0xa8},
- {value: 0x3eef, lo: 0xa9, hi: 0xa9},
- {value: 0xa000, lo: 0xb0, hi: 0xb0},
- {value: 0x3ef7, lo: 0xb1, hi: 0xb1},
- {value: 0xa000, lo: 0xb3, hi: 0xb3},
- {value: 0x3eff, lo: 0xb4, hi: 0xb4},
- {value: 0x9903, lo: 0xbc, hi: 0xbc},
- // Block 0x10, offset 0x72
- {value: 0x0008, lo: 0x06},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x8133, lo: 0x91, hi: 0x91},
- {value: 0x812e, lo: 0x92, hi: 0x92},
- {value: 0x8133, lo: 0x93, hi: 0x93},
- {value: 0x8133, lo: 0x94, hi: 0x94},
- {value: 0x4533, lo: 0x98, hi: 0x9f},
- // Block 0x11, offset 0x79
- {value: 0x0000, lo: 0x02},
- {value: 0x8103, lo: 0xbc, hi: 0xbc},
- {value: 0x9900, lo: 0xbe, hi: 0xbe},
- // Block 0x12, offset 0x7c
- {value: 0x0008, lo: 0x07},
- {value: 0xa000, lo: 0x87, hi: 0x87},
- {value: 0x2cab, lo: 0x8b, hi: 0x8c},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x9900, lo: 0x97, hi: 0x97},
- {value: 0x4573, lo: 0x9c, hi: 0x9d},
- {value: 0x4583, lo: 0x9f, hi: 0x9f},
- {value: 0x8133, lo: 0xbe, hi: 0xbe},
- // Block 0x13, offset 0x84
- {value: 0x0000, lo: 0x03},
- {value: 0x45ab, lo: 0xb3, hi: 0xb3},
- {value: 0x45b3, lo: 0xb6, hi: 0xb6},
- {value: 0x8103, lo: 0xbc, hi: 0xbc},
- // Block 0x14, offset 0x88
- {value: 0x0008, lo: 0x03},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x458b, lo: 0x99, hi: 0x9b},
- {value: 0x45a3, lo: 0x9e, hi: 0x9e},
- // Block 0x15, offset 0x8c
- {value: 0x0000, lo: 0x01},
- {value: 0x8103, lo: 0xbc, hi: 0xbc},
- // Block 0x16, offset 0x8e
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- // Block 0x17, offset 0x90
- {value: 0x0000, lo: 0x08},
- {value: 0xa000, lo: 0x87, hi: 0x87},
- {value: 0x2cc3, lo: 0x88, hi: 0x88},
- {value: 0x2cbb, lo: 0x8b, hi: 0x8b},
- {value: 0x2ccb, lo: 0x8c, hi: 0x8c},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x9900, lo: 0x96, hi: 0x97},
- {value: 0x45bb, lo: 0x9c, hi: 0x9c},
- {value: 0x45c3, lo: 0x9d, hi: 0x9d},
- // Block 0x18, offset 0x99
- {value: 0x0000, lo: 0x03},
- {value: 0xa000, lo: 0x92, hi: 0x92},
- {value: 0x2cd3, lo: 0x94, hi: 0x94},
- {value: 0x9900, lo: 0xbe, hi: 0xbe},
- // Block 0x19, offset 0x9d
- {value: 0x0000, lo: 0x06},
- {value: 0xa000, lo: 0x86, hi: 0x87},
- {value: 0x2cdb, lo: 0x8a, hi: 0x8a},
- {value: 0x2ceb, lo: 0x8b, hi: 0x8b},
- {value: 0x2ce3, lo: 0x8c, hi: 0x8c},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x9900, lo: 0x97, hi: 0x97},
- // Block 0x1a, offset 0xa4
- {value: 0x1801, lo: 0x04},
- {value: 0xa000, lo: 0x86, hi: 0x86},
- {value: 0x3f07, lo: 0x88, hi: 0x88},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x8121, lo: 0x95, hi: 0x96},
- // Block 0x1b, offset 0xa9
- {value: 0x0000, lo: 0x02},
- {value: 0x8103, lo: 0xbc, hi: 0xbc},
- {value: 0xa000, lo: 0xbf, hi: 0xbf},
- // Block 0x1c, offset 0xac
- {value: 0x0000, lo: 0x09},
- {value: 0x2cf3, lo: 0x80, hi: 0x80},
- {value: 0x9900, lo: 0x82, hi: 0x82},
- {value: 0xa000, lo: 0x86, hi: 0x86},
- {value: 0x2cfb, lo: 0x87, hi: 0x87},
- {value: 0x2d03, lo: 0x88, hi: 0x88},
- {value: 0x2f67, lo: 0x8a, hi: 0x8a},
- {value: 0x2def, lo: 0x8b, hi: 0x8b},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x9900, lo: 0x95, hi: 0x96},
- // Block 0x1d, offset 0xb6
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0xbb, hi: 0xbc},
- {value: 0x9900, lo: 0xbe, hi: 0xbe},
- // Block 0x1e, offset 0xb9
- {value: 0x0000, lo: 0x06},
- {value: 0xa000, lo: 0x86, hi: 0x87},
- {value: 0x2d0b, lo: 0x8a, hi: 0x8a},
- {value: 0x2d1b, lo: 0x8b, hi: 0x8b},
- {value: 0x2d13, lo: 0x8c, hi: 0x8c},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x9900, lo: 0x97, hi: 0x97},
- // Block 0x1f, offset 0xc0
- {value: 0x6bdd, lo: 0x07},
- {value: 0x9905, lo: 0x8a, hi: 0x8a},
- {value: 0x9900, lo: 0x8f, hi: 0x8f},
- {value: 0xa000, lo: 0x99, hi: 0x99},
- {value: 0x3f0f, lo: 0x9a, hi: 0x9a},
- {value: 0x2f6f, lo: 0x9c, hi: 0x9c},
- {value: 0x2dfa, lo: 0x9d, hi: 0x9d},
- {value: 0x2d23, lo: 0x9e, hi: 0x9f},
- // Block 0x20, offset 0xc8
- {value: 0x0000, lo: 0x02},
- {value: 0x8123, lo: 0xb8, hi: 0xb9},
- {value: 0x8105, lo: 0xba, hi: 0xba},
- // Block 0x21, offset 0xcb
- {value: 0x0000, lo: 0x01},
- {value: 0x8124, lo: 0x88, hi: 0x8b},
- // Block 0x22, offset 0xcd
- {value: 0x0000, lo: 0x02},
- {value: 0x8125, lo: 0xb8, hi: 0xb9},
- {value: 0x8105, lo: 0xba, hi: 0xba},
- // Block 0x23, offset 0xd0
- {value: 0x0000, lo: 0x01},
- {value: 0x8126, lo: 0x88, hi: 0x8b},
- // Block 0x24, offset 0xd2
- {value: 0x0000, lo: 0x04},
- {value: 0x812e, lo: 0x98, hi: 0x99},
- {value: 0x812e, lo: 0xb5, hi: 0xb5},
- {value: 0x812e, lo: 0xb7, hi: 0xb7},
- {value: 0x812c, lo: 0xb9, hi: 0xb9},
- // Block 0x25, offset 0xd7
- {value: 0x0000, lo: 0x10},
- {value: 0x264a, lo: 0x83, hi: 0x83},
- {value: 0x2651, lo: 0x8d, hi: 0x8d},
- {value: 0x2658, lo: 0x92, hi: 0x92},
- {value: 0x265f, lo: 0x97, hi: 0x97},
- {value: 0x2666, lo: 0x9c, hi: 0x9c},
- {value: 0x2643, lo: 0xa9, hi: 0xa9},
- {value: 0x8127, lo: 0xb1, hi: 0xb1},
- {value: 0x8128, lo: 0xb2, hi: 0xb2},
- {value: 0x4a9b, lo: 0xb3, hi: 0xb3},
- {value: 0x8129, lo: 0xb4, hi: 0xb4},
- {value: 0x4aa4, lo: 0xb5, hi: 0xb5},
- {value: 0x45cb, lo: 0xb6, hi: 0xb6},
- {value: 0x8200, lo: 0xb7, hi: 0xb7},
- {value: 0x45d3, lo: 0xb8, hi: 0xb8},
- {value: 0x8200, lo: 0xb9, hi: 0xb9},
- {value: 0x8128, lo: 0xba, hi: 0xbd},
- // Block 0x26, offset 0xe8
- {value: 0x0000, lo: 0x0b},
- {value: 0x8128, lo: 0x80, hi: 0x80},
- {value: 0x4aad, lo: 0x81, hi: 0x81},
- {value: 0x8133, lo: 0x82, hi: 0x83},
- {value: 0x8105, lo: 0x84, hi: 0x84},
- {value: 0x8133, lo: 0x86, hi: 0x87},
- {value: 0x2674, lo: 0x93, hi: 0x93},
- {value: 0x267b, lo: 0x9d, hi: 0x9d},
- {value: 0x2682, lo: 0xa2, hi: 0xa2},
- {value: 0x2689, lo: 0xa7, hi: 0xa7},
- {value: 0x2690, lo: 0xac, hi: 0xac},
- {value: 0x266d, lo: 0xb9, hi: 0xb9},
- // Block 0x27, offset 0xf4
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0x86, hi: 0x86},
- // Block 0x28, offset 0xf6
- {value: 0x0000, lo: 0x05},
- {value: 0xa000, lo: 0xa5, hi: 0xa5},
- {value: 0x2d2b, lo: 0xa6, hi: 0xa6},
- {value: 0x9900, lo: 0xae, hi: 0xae},
- {value: 0x8103, lo: 0xb7, hi: 0xb7},
- {value: 0x8105, lo: 0xb9, hi: 0xba},
- // Block 0x29, offset 0xfc
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0x8d, hi: 0x8d},
- // Block 0x2a, offset 0xfe
- {value: 0x0000, lo: 0x01},
- {value: 0xa000, lo: 0x80, hi: 0x92},
- // Block 0x2b, offset 0x100
- {value: 0x0000, lo: 0x01},
- {value: 0xb900, lo: 0xa1, hi: 0xb5},
- // Block 0x2c, offset 0x102
- {value: 0x0000, lo: 0x01},
- {value: 0x9900, lo: 0xa8, hi: 0xbf},
- // Block 0x2d, offset 0x104
- {value: 0x0000, lo: 0x01},
- {value: 0x9900, lo: 0x80, hi: 0x82},
- // Block 0x2e, offset 0x106
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0x9d, hi: 0x9f},
- // Block 0x2f, offset 0x108
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x94, hi: 0x94},
- {value: 0x8105, lo: 0xb4, hi: 0xb4},
- // Block 0x30, offset 0x10b
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x92, hi: 0x92},
- {value: 0x8133, lo: 0x9d, hi: 0x9d},
- // Block 0x31, offset 0x10e
- {value: 0x0000, lo: 0x01},
- {value: 0x8132, lo: 0xa9, hi: 0xa9},
- // Block 0x32, offset 0x110
- {value: 0x0004, lo: 0x02},
- {value: 0x812f, lo: 0xb9, hi: 0xba},
- {value: 0x812e, lo: 0xbb, hi: 0xbb},
- // Block 0x33, offset 0x113
- {value: 0x0000, lo: 0x02},
- {value: 0x8133, lo: 0x97, hi: 0x97},
- {value: 0x812e, lo: 0x98, hi: 0x98},
- // Block 0x34, offset 0x116
- {value: 0x0000, lo: 0x03},
- {value: 0x8105, lo: 0xa0, hi: 0xa0},
- {value: 0x8133, lo: 0xb5, hi: 0xbc},
- {value: 0x812e, lo: 0xbf, hi: 0xbf},
- // Block 0x35, offset 0x11a
- {value: 0x0000, lo: 0x05},
- {value: 0x8133, lo: 0xb0, hi: 0xb4},
- {value: 0x812e, lo: 0xb5, hi: 0xba},
- {value: 0x8133, lo: 0xbb, hi: 0xbc},
- {value: 0x812e, lo: 0xbd, hi: 0xbd},
- {value: 0x812e, lo: 0xbf, hi: 0xbf},
- // Block 0x36, offset 0x120
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0x80, hi: 0x80},
- // Block 0x37, offset 0x122
- {value: 0x0000, lo: 0x08},
- {value: 0x2d73, lo: 0x80, hi: 0x80},
- {value: 0x2d7b, lo: 0x81, hi: 0x81},
- {value: 0xa000, lo: 0x82, hi: 0x82},
- {value: 0x2d83, lo: 0x83, hi: 0x83},
- {value: 0x8105, lo: 0x84, hi: 0x84},
- {value: 0x8133, lo: 0xab, hi: 0xab},
- {value: 0x812e, lo: 0xac, hi: 0xac},
- {value: 0x8133, lo: 0xad, hi: 0xb3},
- // Block 0x38, offset 0x12b
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0xaa, hi: 0xab},
- // Block 0x39, offset 0x12d
- {value: 0x0000, lo: 0x02},
- {value: 0x8103, lo: 0xa6, hi: 0xa6},
- {value: 0x8105, lo: 0xb2, hi: 0xb3},
- // Block 0x3a, offset 0x130
- {value: 0x0000, lo: 0x01},
- {value: 0x8103, lo: 0xb7, hi: 0xb7},
- // Block 0x3b, offset 0x132
- {value: 0x0000, lo: 0x0a},
- {value: 0x8133, lo: 0x90, hi: 0x92},
- {value: 0x8101, lo: 0x94, hi: 0x94},
- {value: 0x812e, lo: 0x95, hi: 0x99},
- {value: 0x8133, lo: 0x9a, hi: 0x9b},
- {value: 0x812e, lo: 0x9c, hi: 0x9f},
- {value: 0x8133, lo: 0xa0, hi: 0xa0},
- {value: 0x8101, lo: 0xa2, hi: 0xa8},
- {value: 0x812e, lo: 0xad, hi: 0xad},
- {value: 0x8133, lo: 0xb4, hi: 0xb4},
- {value: 0x8133, lo: 0xb8, hi: 0xb9},
- // Block 0x3c, offset 0x13d
- {value: 0x0004, lo: 0x03},
- {value: 0x0436, lo: 0x80, hi: 0x81},
- {value: 0x8100, lo: 0x97, hi: 0x97},
- {value: 0x8100, lo: 0xbe, hi: 0xbe},
- // Block 0x3d, offset 0x141
- {value: 0x0000, lo: 0x0d},
- {value: 0x8133, lo: 0x90, hi: 0x91},
- {value: 0x8101, lo: 0x92, hi: 0x93},
- {value: 0x8133, lo: 0x94, hi: 0x97},
- {value: 0x8101, lo: 0x98, hi: 0x9a},
- {value: 0x8133, lo: 0x9b, hi: 0x9c},
- {value: 0x8133, lo: 0xa1, hi: 0xa1},
- {value: 0x8101, lo: 0xa5, hi: 0xa6},
- {value: 0x8133, lo: 0xa7, hi: 0xa7},
- {value: 0x812e, lo: 0xa8, hi: 0xa8},
- {value: 0x8133, lo: 0xa9, hi: 0xa9},
- {value: 0x8101, lo: 0xaa, hi: 0xab},
- {value: 0x812e, lo: 0xac, hi: 0xaf},
- {value: 0x8133, lo: 0xb0, hi: 0xb0},
- // Block 0x3e, offset 0x14f
- {value: 0x4292, lo: 0x02},
- {value: 0x01bb, lo: 0xa6, hi: 0xa6},
- {value: 0x0057, lo: 0xaa, hi: 0xab},
- // Block 0x3f, offset 0x152
- {value: 0x0007, lo: 0x05},
- {value: 0xa000, lo: 0x90, hi: 0x90},
- {value: 0xa000, lo: 0x92, hi: 0x92},
- {value: 0xa000, lo: 0x94, hi: 0x94},
- {value: 0x3bd0, lo: 0x9a, hi: 0x9b},
- {value: 0x3bde, lo: 0xae, hi: 0xae},
- // Block 0x40, offset 0x158
- {value: 0x000e, lo: 0x05},
- {value: 0x3be5, lo: 0x8d, hi: 0x8e},
- {value: 0x3bec, lo: 0x8f, hi: 0x8f},
- {value: 0xa000, lo: 0x90, hi: 0x90},
- {value: 0xa000, lo: 0x92, hi: 0x92},
- {value: 0xa000, lo: 0x94, hi: 0x94},
- // Block 0x41, offset 0x15e
- {value: 0x63f1, lo: 0x0a},
- {value: 0xa000, lo: 0x83, hi: 0x83},
- {value: 0x3bfa, lo: 0x84, hi: 0x84},
- {value: 0xa000, lo: 0x88, hi: 0x88},
- {value: 0x3c01, lo: 0x89, hi: 0x89},
- {value: 0xa000, lo: 0x8b, hi: 0x8b},
- {value: 0x3c08, lo: 0x8c, hi: 0x8c},
- {value: 0xa000, lo: 0xa3, hi: 0xa3},
- {value: 0x3c0f, lo: 0xa4, hi: 0xa5},
- {value: 0x3c16, lo: 0xa6, hi: 0xa6},
- {value: 0xa000, lo: 0xbc, hi: 0xbc},
- // Block 0x42, offset 0x169
- {value: 0x0007, lo: 0x03},
- {value: 0x3c7f, lo: 0xa0, hi: 0xa1},
- {value: 0x3ca9, lo: 0xa2, hi: 0xa3},
- {value: 0x3cd3, lo: 0xaa, hi: 0xad},
- // Block 0x43, offset 0x16d
- {value: 0x0004, lo: 0x01},
- {value: 0x048e, lo: 0xa9, hi: 0xaa},
- // Block 0x44, offset 0x16f
- {value: 0x0000, lo: 0x01},
- {value: 0x44f4, lo: 0x9c, hi: 0x9c},
- // Block 0x45, offset 0x171
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xaf, hi: 0xb1},
- // Block 0x46, offset 0x173
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0xbf, hi: 0xbf},
- // Block 0x47, offset 0x175
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xa0, hi: 0xbf},
- // Block 0x48, offset 0x177
- {value: 0x0000, lo: 0x05},
- {value: 0x812d, lo: 0xaa, hi: 0xaa},
- {value: 0x8132, lo: 0xab, hi: 0xab},
- {value: 0x8134, lo: 0xac, hi: 0xac},
- {value: 0x812f, lo: 0xad, hi: 0xad},
- {value: 0x8130, lo: 0xae, hi: 0xaf},
- // Block 0x49, offset 0x17d
- {value: 0x0000, lo: 0x03},
- {value: 0x4ab6, lo: 0xb3, hi: 0xb3},
- {value: 0x4ab6, lo: 0xb5, hi: 0xb6},
- {value: 0x4ab6, lo: 0xba, hi: 0xbf},
- // Block 0x4a, offset 0x181
- {value: 0x0000, lo: 0x01},
- {value: 0x4ab6, lo: 0x8f, hi: 0xa3},
- // Block 0x4b, offset 0x183
- {value: 0x0000, lo: 0x01},
- {value: 0x8100, lo: 0xae, hi: 0xbe},
- // Block 0x4c, offset 0x185
- {value: 0x0000, lo: 0x07},
- {value: 0x8100, lo: 0x84, hi: 0x84},
- {value: 0x8100, lo: 0x87, hi: 0x87},
- {value: 0x8100, lo: 0x90, hi: 0x90},
- {value: 0x8100, lo: 0x9e, hi: 0x9e},
- {value: 0x8100, lo: 0xa1, hi: 0xa1},
- {value: 0x8100, lo: 0xb2, hi: 0xb2},
- {value: 0x8100, lo: 0xbb, hi: 0xbb},
- // Block 0x4d, offset 0x18d
- {value: 0x0000, lo: 0x03},
- {value: 0x8100, lo: 0x80, hi: 0x80},
- {value: 0x8100, lo: 0x8b, hi: 0x8b},
- {value: 0x8100, lo: 0x8e, hi: 0x8e},
- // Block 0x4e, offset 0x191
- {value: 0x0000, lo: 0x02},
- {value: 0x8133, lo: 0xaf, hi: 0xaf},
- {value: 0x8133, lo: 0xb4, hi: 0xbd},
- // Block 0x4f, offset 0x194
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0x9e, hi: 0x9f},
- // Block 0x50, offset 0x196
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xb0, hi: 0xb1},
- // Block 0x51, offset 0x198
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x86, hi: 0x86},
- {value: 0x8105, lo: 0xac, hi: 0xac},
- // Block 0x52, offset 0x19b
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x84, hi: 0x84},
- {value: 0x8133, lo: 0xa0, hi: 0xb1},
- // Block 0x53, offset 0x19e
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0xab, hi: 0xad},
- // Block 0x54, offset 0x1a0
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0x93, hi: 0x93},
- // Block 0x55, offset 0x1a2
- {value: 0x0000, lo: 0x01},
- {value: 0x8103, lo: 0xb3, hi: 0xb3},
- // Block 0x56, offset 0x1a4
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0x80, hi: 0x80},
- // Block 0x57, offset 0x1a6
- {value: 0x0000, lo: 0x05},
- {value: 0x8133, lo: 0xb0, hi: 0xb0},
- {value: 0x8133, lo: 0xb2, hi: 0xb3},
- {value: 0x812e, lo: 0xb4, hi: 0xb4},
- {value: 0x8133, lo: 0xb7, hi: 0xb8},
- {value: 0x8133, lo: 0xbe, hi: 0xbf},
- // Block 0x58, offset 0x1ac
- {value: 0x0000, lo: 0x02},
- {value: 0x8133, lo: 0x81, hi: 0x81},
- {value: 0x8105, lo: 0xb6, hi: 0xb6},
- // Block 0x59, offset 0x1af
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0xad, hi: 0xad},
- // Block 0x5a, offset 0x1b1
- {value: 0x0000, lo: 0x06},
- {value: 0xe500, lo: 0x80, hi: 0x80},
- {value: 0xc600, lo: 0x81, hi: 0x9b},
- {value: 0xe500, lo: 0x9c, hi: 0x9c},
- {value: 0xc600, lo: 0x9d, hi: 0xb7},
- {value: 0xe500, lo: 0xb8, hi: 0xb8},
- {value: 0xc600, lo: 0xb9, hi: 0xbf},
- // Block 0x5b, offset 0x1b8
- {value: 0x0000, lo: 0x05},
- {value: 0xc600, lo: 0x80, hi: 0x93},
- {value: 0xe500, lo: 0x94, hi: 0x94},
- {value: 0xc600, lo: 0x95, hi: 0xaf},
- {value: 0xe500, lo: 0xb0, hi: 0xb0},
- {value: 0xc600, lo: 0xb1, hi: 0xbf},
- // Block 0x5c, offset 0x1be
- {value: 0x0000, lo: 0x05},
- {value: 0xc600, lo: 0x80, hi: 0x8b},
- {value: 0xe500, lo: 0x8c, hi: 0x8c},
- {value: 0xc600, lo: 0x8d, hi: 0xa7},
- {value: 0xe500, lo: 0xa8, hi: 0xa8},
- {value: 0xc600, lo: 0xa9, hi: 0xbf},
- // Block 0x5d, offset 0x1c4
- {value: 0x0000, lo: 0x07},
- {value: 0xc600, lo: 0x80, hi: 0x83},
- {value: 0xe500, lo: 0x84, hi: 0x84},
- {value: 0xc600, lo: 0x85, hi: 0x9f},
- {value: 0xe500, lo: 0xa0, hi: 0xa0},
- {value: 0xc600, lo: 0xa1, hi: 0xbb},
- {value: 0xe500, lo: 0xbc, hi: 0xbc},
- {value: 0xc600, lo: 0xbd, hi: 0xbf},
- // Block 0x5e, offset 0x1cc
- {value: 0x0000, lo: 0x05},
- {value: 0xc600, lo: 0x80, hi: 0x97},
- {value: 0xe500, lo: 0x98, hi: 0x98},
- {value: 0xc600, lo: 0x99, hi: 0xb3},
- {value: 0xe500, lo: 0xb4, hi: 0xb4},
- {value: 0xc600, lo: 0xb5, hi: 0xbf},
- // Block 0x5f, offset 0x1d2
- {value: 0x0000, lo: 0x05},
- {value: 0xc600, lo: 0x80, hi: 0x8f},
- {value: 0xe500, lo: 0x90, hi: 0x90},
- {value: 0xc600, lo: 0x91, hi: 0xab},
- {value: 0xe500, lo: 0xac, hi: 0xac},
- {value: 0xc600, lo: 0xad, hi: 0xbf},
- // Block 0x60, offset 0x1d8
- {value: 0x0000, lo: 0x05},
- {value: 0xc600, lo: 0x80, hi: 0x87},
- {value: 0xe500, lo: 0x88, hi: 0x88},
- {value: 0xc600, lo: 0x89, hi: 0xa3},
- {value: 0xe500, lo: 0xa4, hi: 0xa4},
- {value: 0xc600, lo: 0xa5, hi: 0xbf},
- // Block 0x61, offset 0x1de
- {value: 0x0000, lo: 0x03},
- {value: 0xc600, lo: 0x80, hi: 0x87},
- {value: 0xe500, lo: 0x88, hi: 0x88},
- {value: 0xc600, lo: 0x89, hi: 0xa3},
- // Block 0x62, offset 0x1e2
- {value: 0x0006, lo: 0x0d},
- {value: 0x43a7, lo: 0x9d, hi: 0x9d},
- {value: 0x8116, lo: 0x9e, hi: 0x9e},
- {value: 0x4419, lo: 0x9f, hi: 0x9f},
- {value: 0x4407, lo: 0xaa, hi: 0xab},
- {value: 0x450b, lo: 0xac, hi: 0xac},
- {value: 0x4513, lo: 0xad, hi: 0xad},
- {value: 0x435f, lo: 0xae, hi: 0xb1},
- {value: 0x437d, lo: 0xb2, hi: 0xb4},
- {value: 0x4395, lo: 0xb5, hi: 0xb6},
- {value: 0x43a1, lo: 0xb8, hi: 0xb8},
- {value: 0x43ad, lo: 0xb9, hi: 0xbb},
- {value: 0x43c5, lo: 0xbc, hi: 0xbc},
- {value: 0x43cb, lo: 0xbe, hi: 0xbe},
- // Block 0x63, offset 0x1f0
- {value: 0x0006, lo: 0x08},
- {value: 0x43d1, lo: 0x80, hi: 0x81},
- {value: 0x43dd, lo: 0x83, hi: 0x84},
- {value: 0x43ef, lo: 0x86, hi: 0x89},
- {value: 0x4413, lo: 0x8a, hi: 0x8a},
- {value: 0x438f, lo: 0x8b, hi: 0x8b},
- {value: 0x4377, lo: 0x8c, hi: 0x8c},
- {value: 0x43bf, lo: 0x8d, hi: 0x8d},
- {value: 0x43e9, lo: 0x8e, hi: 0x8e},
- // Block 0x64, offset 0x1f9
- {value: 0x0000, lo: 0x02},
- {value: 0x8100, lo: 0xa4, hi: 0xa5},
- {value: 0x8100, lo: 0xb0, hi: 0xb1},
- // Block 0x65, offset 0x1fc
- {value: 0x0000, lo: 0x02},
- {value: 0x8100, lo: 0x9b, hi: 0x9d},
- {value: 0x8200, lo: 0x9e, hi: 0xa3},
- // Block 0x66, offset 0x1ff
- {value: 0x0000, lo: 0x01},
- {value: 0x8100, lo: 0x90, hi: 0x90},
- // Block 0x67, offset 0x201
- {value: 0x0000, lo: 0x02},
- {value: 0x8100, lo: 0x99, hi: 0x99},
- {value: 0x8200, lo: 0xb2, hi: 0xb4},
- // Block 0x68, offset 0x204
- {value: 0x0000, lo: 0x01},
- {value: 0x8100, lo: 0xbc, hi: 0xbd},
- // Block 0x69, offset 0x206
- {value: 0x0000, lo: 0x03},
- {value: 0x8133, lo: 0xa0, hi: 0xa6},
- {value: 0x812e, lo: 0xa7, hi: 0xad},
- {value: 0x8133, lo: 0xae, hi: 0xaf},
- // Block 0x6a, offset 0x20a
- {value: 0x0000, lo: 0x04},
- {value: 0x8100, lo: 0x89, hi: 0x8c},
- {value: 0x8100, lo: 0xb0, hi: 0xb2},
- {value: 0x8100, lo: 0xb4, hi: 0xb4},
- {value: 0x8100, lo: 0xb6, hi: 0xbf},
- // Block 0x6b, offset 0x20f
- {value: 0x0000, lo: 0x01},
- {value: 0x8100, lo: 0x81, hi: 0x8c},
- // Block 0x6c, offset 0x211
- {value: 0x0000, lo: 0x01},
- {value: 0x8100, lo: 0xb5, hi: 0xba},
- // Block 0x6d, offset 0x213
- {value: 0x0000, lo: 0x04},
- {value: 0x4ab6, lo: 0x9e, hi: 0x9f},
- {value: 0x4ab6, lo: 0xa3, hi: 0xa3},
- {value: 0x4ab6, lo: 0xa5, hi: 0xa6},
- {value: 0x4ab6, lo: 0xaa, hi: 0xaf},
- // Block 0x6e, offset 0x218
- {value: 0x0000, lo: 0x05},
- {value: 0x4ab6, lo: 0x82, hi: 0x87},
- {value: 0x4ab6, lo: 0x8a, hi: 0x8f},
- {value: 0x4ab6, lo: 0x92, hi: 0x97},
- {value: 0x4ab6, lo: 0x9a, hi: 0x9c},
- {value: 0x8100, lo: 0xa3, hi: 0xa3},
- // Block 0x6f, offset 0x21e
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0xbd, hi: 0xbd},
- // Block 0x70, offset 0x220
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0xa0, hi: 0xa0},
- // Block 0x71, offset 0x222
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xb6, hi: 0xba},
- // Block 0x72, offset 0x224
- {value: 0x002d, lo: 0x05},
- {value: 0x812e, lo: 0x8d, hi: 0x8d},
- {value: 0x8133, lo: 0x8f, hi: 0x8f},
- {value: 0x8133, lo: 0xb8, hi: 0xb8},
- {value: 0x8101, lo: 0xb9, hi: 0xba},
- {value: 0x8105, lo: 0xbf, hi: 0xbf},
- // Block 0x73, offset 0x22a
- {value: 0x0000, lo: 0x02},
- {value: 0x8133, lo: 0xa5, hi: 0xa5},
- {value: 0x812e, lo: 0xa6, hi: 0xa6},
- // Block 0x74, offset 0x22d
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xa4, hi: 0xa7},
- // Block 0x75, offset 0x22f
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xab, hi: 0xac},
- // Block 0x76, offset 0x231
- {value: 0x0000, lo: 0x05},
- {value: 0x812e, lo: 0x86, hi: 0x87},
- {value: 0x8133, lo: 0x88, hi: 0x8a},
- {value: 0x812e, lo: 0x8b, hi: 0x8b},
- {value: 0x8133, lo: 0x8c, hi: 0x8c},
- {value: 0x812e, lo: 0x8d, hi: 0x90},
- // Block 0x77, offset 0x237
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x86, hi: 0x86},
- {value: 0x8105, lo: 0xbf, hi: 0xbf},
- // Block 0x78, offset 0x23a
- {value: 0x17fe, lo: 0x07},
- {value: 0xa000, lo: 0x99, hi: 0x99},
- {value: 0x424f, lo: 0x9a, hi: 0x9a},
- {value: 0xa000, lo: 0x9b, hi: 0x9b},
- {value: 0x4259, lo: 0x9c, hi: 0x9c},
- {value: 0xa000, lo: 0xa5, hi: 0xa5},
- {value: 0x4263, lo: 0xab, hi: 0xab},
- {value: 0x8105, lo: 0xb9, hi: 0xba},
- // Block 0x79, offset 0x242
- {value: 0x0000, lo: 0x06},
- {value: 0x8133, lo: 0x80, hi: 0x82},
- {value: 0x9900, lo: 0xa7, hi: 0xa7},
- {value: 0x2d8b, lo: 0xae, hi: 0xae},
- {value: 0x2d95, lo: 0xaf, hi: 0xaf},
- {value: 0xa000, lo: 0xb1, hi: 0xb2},
- {value: 0x8105, lo: 0xb3, hi: 0xb4},
- // Block 0x7a, offset 0x249
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x80, hi: 0x80},
- {value: 0x8103, lo: 0x8a, hi: 0x8a},
- // Block 0x7b, offset 0x24c
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0xb5, hi: 0xb5},
- {value: 0x8103, lo: 0xb6, hi: 0xb6},
- // Block 0x7c, offset 0x24f
- {value: 0x0002, lo: 0x01},
- {value: 0x8103, lo: 0xa9, hi: 0xaa},
- // Block 0x7d, offset 0x251
- {value: 0x0000, lo: 0x02},
- {value: 0x8103, lo: 0xbb, hi: 0xbc},
- {value: 0x9900, lo: 0xbe, hi: 0xbe},
- // Block 0x7e, offset 0x254
- {value: 0x0000, lo: 0x07},
- {value: 0xa000, lo: 0x87, hi: 0x87},
- {value: 0x2d9f, lo: 0x8b, hi: 0x8b},
- {value: 0x2da9, lo: 0x8c, hi: 0x8c},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x9900, lo: 0x97, hi: 0x97},
- {value: 0x8133, lo: 0xa6, hi: 0xac},
- {value: 0x8133, lo: 0xb0, hi: 0xb4},
- // Block 0x7f, offset 0x25c
- {value: 0x0000, lo: 0x03},
- {value: 0x8105, lo: 0x82, hi: 0x82},
- {value: 0x8103, lo: 0x86, hi: 0x86},
- {value: 0x8133, lo: 0x9e, hi: 0x9e},
- // Block 0x80, offset 0x260
- {value: 0x6b4d, lo: 0x06},
- {value: 0x9900, lo: 0xb0, hi: 0xb0},
- {value: 0xa000, lo: 0xb9, hi: 0xb9},
- {value: 0x9900, lo: 0xba, hi: 0xba},
- {value: 0x2dbd, lo: 0xbb, hi: 0xbb},
- {value: 0x2db3, lo: 0xbc, hi: 0xbd},
- {value: 0x2dc7, lo: 0xbe, hi: 0xbe},
- // Block 0x81, offset 0x267
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x82, hi: 0x82},
- {value: 0x8103, lo: 0x83, hi: 0x83},
- // Block 0x82, offset 0x26a
- {value: 0x0000, lo: 0x05},
- {value: 0x9900, lo: 0xaf, hi: 0xaf},
- {value: 0xa000, lo: 0xb8, hi: 0xb9},
- {value: 0x2dd1, lo: 0xba, hi: 0xba},
- {value: 0x2ddb, lo: 0xbb, hi: 0xbb},
- {value: 0x8105, lo: 0xbf, hi: 0xbf},
- // Block 0x83, offset 0x270
- {value: 0x0000, lo: 0x01},
- {value: 0x8103, lo: 0x80, hi: 0x80},
- // Block 0x84, offset 0x272
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0xb6, hi: 0xb6},
- {value: 0x8103, lo: 0xb7, hi: 0xb7},
- // Block 0x85, offset 0x275
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0xab, hi: 0xab},
- // Block 0x86, offset 0x277
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0xb9, hi: 0xb9},
- {value: 0x8103, lo: 0xba, hi: 0xba},
- // Block 0x87, offset 0x27a
- {value: 0x0000, lo: 0x04},
- {value: 0x9900, lo: 0xb0, hi: 0xb0},
- {value: 0xa000, lo: 0xb5, hi: 0xb5},
- {value: 0x2de5, lo: 0xb8, hi: 0xb8},
- {value: 0x8105, lo: 0xbd, hi: 0xbe},
- // Block 0x88, offset 0x27f
- {value: 0x0000, lo: 0x01},
- {value: 0x8103, lo: 0x83, hi: 0x83},
- // Block 0x89, offset 0x281
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0xa0, hi: 0xa0},
- // Block 0x8a, offset 0x283
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0xb4, hi: 0xb4},
- // Block 0x8b, offset 0x285
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0x87, hi: 0x87},
- // Block 0x8c, offset 0x287
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0x99, hi: 0x99},
- // Block 0x8d, offset 0x289
- {value: 0x0000, lo: 0x02},
- {value: 0x8103, lo: 0x82, hi: 0x82},
- {value: 0x8105, lo: 0x84, hi: 0x85},
- // Block 0x8e, offset 0x28c
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0x97, hi: 0x97},
- // Block 0x8f, offset 0x28e
- {value: 0x0000, lo: 0x01},
- {value: 0x8101, lo: 0xb0, hi: 0xb4},
- // Block 0x90, offset 0x290
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xb0, hi: 0xb6},
- // Block 0x91, offset 0x292
- {value: 0x0000, lo: 0x01},
- {value: 0x8102, lo: 0xb0, hi: 0xb1},
- // Block 0x92, offset 0x294
- {value: 0x0000, lo: 0x01},
- {value: 0x8101, lo: 0x9e, hi: 0x9e},
- // Block 0x93, offset 0x296
- {value: 0x0000, lo: 0x0c},
- {value: 0x45e3, lo: 0x9e, hi: 0x9e},
- {value: 0x45ed, lo: 0x9f, hi: 0x9f},
- {value: 0x4621, lo: 0xa0, hi: 0xa0},
- {value: 0x462f, lo: 0xa1, hi: 0xa1},
- {value: 0x463d, lo: 0xa2, hi: 0xa2},
- {value: 0x464b, lo: 0xa3, hi: 0xa3},
- {value: 0x4659, lo: 0xa4, hi: 0xa4},
- {value: 0x812c, lo: 0xa5, hi: 0xa6},
- {value: 0x8101, lo: 0xa7, hi: 0xa9},
- {value: 0x8131, lo: 0xad, hi: 0xad},
- {value: 0x812c, lo: 0xae, hi: 0xb2},
- {value: 0x812e, lo: 0xbb, hi: 0xbf},
- // Block 0x94, offset 0x2a3
- {value: 0x0000, lo: 0x09},
- {value: 0x812e, lo: 0x80, hi: 0x82},
- {value: 0x8133, lo: 0x85, hi: 0x89},
- {value: 0x812e, lo: 0x8a, hi: 0x8b},
- {value: 0x8133, lo: 0xaa, hi: 0xad},
- {value: 0x45f7, lo: 0xbb, hi: 0xbb},
- {value: 0x4601, lo: 0xbc, hi: 0xbc},
- {value: 0x4667, lo: 0xbd, hi: 0xbd},
- {value: 0x4683, lo: 0xbe, hi: 0xbe},
- {value: 0x4675, lo: 0xbf, hi: 0xbf},
- // Block 0x95, offset 0x2ad
- {value: 0x0000, lo: 0x01},
- {value: 0x4691, lo: 0x80, hi: 0x80},
- // Block 0x96, offset 0x2af
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0x82, hi: 0x84},
- // Block 0x97, offset 0x2b1
- {value: 0x0000, lo: 0x05},
- {value: 0x8133, lo: 0x80, hi: 0x86},
- {value: 0x8133, lo: 0x88, hi: 0x98},
- {value: 0x8133, lo: 0x9b, hi: 0xa1},
- {value: 0x8133, lo: 0xa3, hi: 0xa4},
- {value: 0x8133, lo: 0xa6, hi: 0xaa},
- // Block 0x98, offset 0x2b7
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xac, hi: 0xaf},
- // Block 0x99, offset 0x2b9
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0x90, hi: 0x96},
- // Block 0x9a, offset 0x2bb
- {value: 0x0000, lo: 0x02},
- {value: 0x8133, lo: 0x84, hi: 0x89},
- {value: 0x8103, lo: 0x8a, hi: 0x8a},
- // Block 0x9b, offset 0x2be
- {value: 0x0000, lo: 0x01},
- {value: 0x8100, lo: 0x93, hi: 0x93},
-}
-
-// lookup returns the trie value for the first UTF-8 encoding in s and
-// the width in bytes of this encoding. The size will be 0 if s does not
-// hold enough bytes to complete the encoding. len(s) must be greater than 0.
-func (t *nfkcTrie) lookup(s []byte) (v uint16, sz int) {
- c0 := s[0]
- switch {
- case c0 < 0x80: // is ASCII
- return nfkcValues[c0], 1
- case c0 < 0xC2:
- return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
- case c0 < 0xE0: // 2-byte UTF-8
- if len(s) < 2 {
- return 0, 0
- }
- i := nfkcIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c1), 2
- case c0 < 0xF0: // 3-byte UTF-8
- if len(s) < 3 {
- return 0, 0
- }
- i := nfkcIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = nfkcIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c2), 3
- case c0 < 0xF8: // 4-byte UTF-8
- if len(s) < 4 {
- return 0, 0
- }
- i := nfkcIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = nfkcIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- o = uint32(i)<<6 + uint32(c2)
- i = nfkcIndex[o]
- c3 := s[3]
- if c3 < 0x80 || 0xC0 <= c3 {
- return 0, 3 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c3), 4
- }
- // Illegal rune
- return 0, 1
-}
-
-// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
-// s must start with a full and valid UTF-8 encoded rune.
-func (t *nfkcTrie) lookupUnsafe(s []byte) uint16 {
- c0 := s[0]
- if c0 < 0x80 { // is ASCII
- return nfkcValues[c0]
- }
- i := nfkcIndex[c0]
- if c0 < 0xE0 { // 2-byte UTF-8
- return t.lookupValue(uint32(i), s[1])
- }
- i = nfkcIndex[uint32(i)<<6+uint32(s[1])]
- if c0 < 0xF0 { // 3-byte UTF-8
- return t.lookupValue(uint32(i), s[2])
- }
- i = nfkcIndex[uint32(i)<<6+uint32(s[2])]
- if c0 < 0xF8 { // 4-byte UTF-8
- return t.lookupValue(uint32(i), s[3])
- }
- return 0
-}
-
-// lookupString returns the trie value for the first UTF-8 encoding in s and
-// the width in bytes of this encoding. The size will be 0 if s does not
-// hold enough bytes to complete the encoding. len(s) must be greater than 0.
-func (t *nfkcTrie) lookupString(s string) (v uint16, sz int) {
- c0 := s[0]
- switch {
- case c0 < 0x80: // is ASCII
- return nfkcValues[c0], 1
- case c0 < 0xC2:
- return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
- case c0 < 0xE0: // 2-byte UTF-8
- if len(s) < 2 {
- return 0, 0
- }
- i := nfkcIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c1), 2
- case c0 < 0xF0: // 3-byte UTF-8
- if len(s) < 3 {
- return 0, 0
- }
- i := nfkcIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = nfkcIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c2), 3
- case c0 < 0xF8: // 4-byte UTF-8
- if len(s) < 4 {
- return 0, 0
- }
- i := nfkcIndex[c0]
- c1 := s[1]
- if c1 < 0x80 || 0xC0 <= c1 {
- return 0, 1 // Illegal UTF-8: not a continuation byte.
- }
- o := uint32(i)<<6 + uint32(c1)
- i = nfkcIndex[o]
- c2 := s[2]
- if c2 < 0x80 || 0xC0 <= c2 {
- return 0, 2 // Illegal UTF-8: not a continuation byte.
- }
- o = uint32(i)<<6 + uint32(c2)
- i = nfkcIndex[o]
- c3 := s[3]
- if c3 < 0x80 || 0xC0 <= c3 {
- return 0, 3 // Illegal UTF-8: not a continuation byte.
- }
- return t.lookupValue(uint32(i), c3), 4
- }
- // Illegal rune
- return 0, 1
-}
-
-// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
-// s must start with a full and valid UTF-8 encoded rune.
-func (t *nfkcTrie) lookupStringUnsafe(s string) uint16 {
- c0 := s[0]
- if c0 < 0x80 { // is ASCII
- return nfkcValues[c0]
- }
- i := nfkcIndex[c0]
- if c0 < 0xE0 { // 2-byte UTF-8
- return t.lookupValue(uint32(i), s[1])
- }
- i = nfkcIndex[uint32(i)<<6+uint32(s[1])]
- if c0 < 0xF0 { // 3-byte UTF-8
- return t.lookupValue(uint32(i), s[2])
- }
- i = nfkcIndex[uint32(i)<<6+uint32(s[2])]
- if c0 < 0xF8 { // 4-byte UTF-8
- return t.lookupValue(uint32(i), s[3])
- }
- return 0
-}
-
-// nfkcTrie. Total size: 18768 bytes (18.33 KiB). Checksum: c51186dd2412943d.
-type nfkcTrie struct{}
-
-func newNfkcTrie(i int) *nfkcTrie {
- return &nfkcTrie{}
-}
-
-// lookupValue determines the type of block n and looks up the value for b.
-func (t *nfkcTrie) lookupValue(n uint32, b byte) uint16 {
- switch {
- case n < 92:
- return uint16(nfkcValues[n<<6+uint32(b)])
- default:
- n -= 92
- return uint16(nfkcSparse.lookup(n, b))
- }
-}
-
-// nfkcValues: 94 blocks, 6016 entries, 12032 bytes
-// The third block is the zero block.
-var nfkcValues = [6016]uint16{
- // Block 0x0, offset 0x0
- 0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000,
- // Block 0x1, offset 0x40
- 0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000,
- 0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000,
- 0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000,
- 0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000,
- 0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000,
- 0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000,
- 0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000,
- 0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000,
- 0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000,
- 0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000,
- // Block 0x2, offset 0x80
- // Block 0x3, offset 0xc0
- 0xc0: 0x2f86, 0xc1: 0x2f8b, 0xc2: 0x469f, 0xc3: 0x2f90, 0xc4: 0x46ae, 0xc5: 0x46b3,
- 0xc6: 0xa000, 0xc7: 0x46bd, 0xc8: 0x2ff9, 0xc9: 0x2ffe, 0xca: 0x46c2, 0xcb: 0x3012,
- 0xcc: 0x3085, 0xcd: 0x308a, 0xce: 0x308f, 0xcf: 0x46d6, 0xd1: 0x311b,
- 0xd2: 0x313e, 0xd3: 0x3143, 0xd4: 0x46e0, 0xd5: 0x46e5, 0xd6: 0x46f4,
- 0xd8: 0xa000, 0xd9: 0x31ca, 0xda: 0x31cf, 0xdb: 0x31d4, 0xdc: 0x4726, 0xdd: 0x324c,
- 0xe0: 0x3292, 0xe1: 0x3297, 0xe2: 0x4730, 0xe3: 0x329c,
- 0xe4: 0x473f, 0xe5: 0x4744, 0xe6: 0xa000, 0xe7: 0x474e, 0xe8: 0x3305, 0xe9: 0x330a,
- 0xea: 0x4753, 0xeb: 0x331e, 0xec: 0x3396, 0xed: 0x339b, 0xee: 0x33a0, 0xef: 0x4767,
- 0xf1: 0x342c, 0xf2: 0x344f, 0xf3: 0x3454, 0xf4: 0x4771, 0xf5: 0x4776,
- 0xf6: 0x4785, 0xf8: 0xa000, 0xf9: 0x34e0, 0xfa: 0x34e5, 0xfb: 0x34ea,
- 0xfc: 0x47b7, 0xfd: 0x3567, 0xff: 0x3580,
- // Block 0x4, offset 0x100
- 0x100: 0x2f95, 0x101: 0x32a1, 0x102: 0x46a4, 0x103: 0x4735, 0x104: 0x2fb3, 0x105: 0x32bf,
- 0x106: 0x2fc7, 0x107: 0x32d3, 0x108: 0x2fcc, 0x109: 0x32d8, 0x10a: 0x2fd1, 0x10b: 0x32dd,
- 0x10c: 0x2fd6, 0x10d: 0x32e2, 0x10e: 0x2fe0, 0x10f: 0x32ec,
- 0x112: 0x46c7, 0x113: 0x4758, 0x114: 0x3008, 0x115: 0x3314, 0x116: 0x300d, 0x117: 0x3319,
- 0x118: 0x302b, 0x119: 0x3337, 0x11a: 0x301c, 0x11b: 0x3328, 0x11c: 0x3044, 0x11d: 0x3350,
- 0x11e: 0x304e, 0x11f: 0x335a, 0x120: 0x3053, 0x121: 0x335f, 0x122: 0x305d, 0x123: 0x3369,
- 0x124: 0x3062, 0x125: 0x336e, 0x128: 0x3094, 0x129: 0x33a5,
- 0x12a: 0x3099, 0x12b: 0x33aa, 0x12c: 0x309e, 0x12d: 0x33af, 0x12e: 0x30c1, 0x12f: 0x33cd,
- 0x130: 0x30a3, 0x132: 0x1960, 0x133: 0x19ed, 0x134: 0x30cb, 0x135: 0x33d7,
- 0x136: 0x30df, 0x137: 0x33f0, 0x139: 0x30e9, 0x13a: 0x33fa, 0x13b: 0x30f3,
- 0x13c: 0x3404, 0x13d: 0x30ee, 0x13e: 0x33ff, 0x13f: 0x1bb2,
- // Block 0x5, offset 0x140
- 0x140: 0x1c3a, 0x143: 0x3116, 0x144: 0x3427, 0x145: 0x312f,
- 0x146: 0x3440, 0x147: 0x3125, 0x148: 0x3436, 0x149: 0x1c62,
- 0x14c: 0x46ea, 0x14d: 0x477b, 0x14e: 0x3148, 0x14f: 0x3459, 0x150: 0x3152, 0x151: 0x3463,
- 0x154: 0x3170, 0x155: 0x3481, 0x156: 0x3189, 0x157: 0x349a,
- 0x158: 0x317a, 0x159: 0x348b, 0x15a: 0x470d, 0x15b: 0x479e, 0x15c: 0x3193, 0x15d: 0x34a4,
- 0x15e: 0x31a2, 0x15f: 0x34b3, 0x160: 0x4712, 0x161: 0x47a3, 0x162: 0x31bb, 0x163: 0x34d1,
- 0x164: 0x31ac, 0x165: 0x34c2, 0x168: 0x471c, 0x169: 0x47ad,
- 0x16a: 0x4721, 0x16b: 0x47b2, 0x16c: 0x31d9, 0x16d: 0x34ef, 0x16e: 0x31e3, 0x16f: 0x34f9,
- 0x170: 0x31e8, 0x171: 0x34fe, 0x172: 0x3206, 0x173: 0x351c, 0x174: 0x3229, 0x175: 0x353f,
- 0x176: 0x3251, 0x177: 0x356c, 0x178: 0x3265, 0x179: 0x3274, 0x17a: 0x3594, 0x17b: 0x327e,
- 0x17c: 0x359e, 0x17d: 0x3283, 0x17e: 0x35a3, 0x17f: 0x00a7,
- // Block 0x6, offset 0x180
- 0x184: 0x2e05, 0x185: 0x2e0b,
- 0x186: 0x2e11, 0x187: 0x1975, 0x188: 0x1978, 0x189: 0x1a0e, 0x18a: 0x198d, 0x18b: 0x1990,
- 0x18c: 0x1a44, 0x18d: 0x2f9f, 0x18e: 0x32ab, 0x18f: 0x30ad, 0x190: 0x33b9, 0x191: 0x3157,
- 0x192: 0x3468, 0x193: 0x31ed, 0x194: 0x3503, 0x195: 0x39e6, 0x196: 0x3b75, 0x197: 0x39df,
- 0x198: 0x3b6e, 0x199: 0x39ed, 0x19a: 0x3b7c, 0x19b: 0x39d8, 0x19c: 0x3b67,
- 0x19e: 0x38c7, 0x19f: 0x3a56, 0x1a0: 0x38c0, 0x1a1: 0x3a4f, 0x1a2: 0x35ca, 0x1a3: 0x35dc,
- 0x1a6: 0x3058, 0x1a7: 0x3364, 0x1a8: 0x30d5, 0x1a9: 0x33e6,
- 0x1aa: 0x4703, 0x1ab: 0x4794, 0x1ac: 0x39a7, 0x1ad: 0x3b36, 0x1ae: 0x35ee, 0x1af: 0x35f4,
- 0x1b0: 0x33dc, 0x1b1: 0x1945, 0x1b2: 0x1948, 0x1b3: 0x19d5, 0x1b4: 0x303f, 0x1b5: 0x334b,
- 0x1b8: 0x3111, 0x1b9: 0x3422, 0x1ba: 0x38ce, 0x1bb: 0x3a5d,
- 0x1bc: 0x35c4, 0x1bd: 0x35d6, 0x1be: 0x35d0, 0x1bf: 0x35e2,
- // Block 0x7, offset 0x1c0
- 0x1c0: 0x2fa4, 0x1c1: 0x32b0, 0x1c2: 0x2fa9, 0x1c3: 0x32b5, 0x1c4: 0x3021, 0x1c5: 0x332d,
- 0x1c6: 0x3026, 0x1c7: 0x3332, 0x1c8: 0x30b2, 0x1c9: 0x33be, 0x1ca: 0x30b7, 0x1cb: 0x33c3,
- 0x1cc: 0x315c, 0x1cd: 0x346d, 0x1ce: 0x3161, 0x1cf: 0x3472, 0x1d0: 0x317f, 0x1d1: 0x3490,
- 0x1d2: 0x3184, 0x1d3: 0x3495, 0x1d4: 0x31f2, 0x1d5: 0x3508, 0x1d6: 0x31f7, 0x1d7: 0x350d,
- 0x1d8: 0x319d, 0x1d9: 0x34ae, 0x1da: 0x31b6, 0x1db: 0x34cc,
- 0x1de: 0x3071, 0x1df: 0x337d,
- 0x1e6: 0x46a9, 0x1e7: 0x473a, 0x1e8: 0x46d1, 0x1e9: 0x4762,
- 0x1ea: 0x3976, 0x1eb: 0x3b05, 0x1ec: 0x3953, 0x1ed: 0x3ae2, 0x1ee: 0x46ef, 0x1ef: 0x4780,
- 0x1f0: 0x396f, 0x1f1: 0x3afe, 0x1f2: 0x325b, 0x1f3: 0x3576,
- // Block 0x8, offset 0x200
- 0x200: 0x9933, 0x201: 0x9933, 0x202: 0x9933, 0x203: 0x9933, 0x204: 0x9933, 0x205: 0x8133,
- 0x206: 0x9933, 0x207: 0x9933, 0x208: 0x9933, 0x209: 0x9933, 0x20a: 0x9933, 0x20b: 0x9933,
- 0x20c: 0x9933, 0x20d: 0x8133, 0x20e: 0x8133, 0x20f: 0x9933, 0x210: 0x8133, 0x211: 0x9933,
- 0x212: 0x8133, 0x213: 0x9933, 0x214: 0x9933, 0x215: 0x8134, 0x216: 0x812e, 0x217: 0x812e,
- 0x218: 0x812e, 0x219: 0x812e, 0x21a: 0x8134, 0x21b: 0x992c, 0x21c: 0x812e, 0x21d: 0x812e,
- 0x21e: 0x812e, 0x21f: 0x812e, 0x220: 0x812e, 0x221: 0x812a, 0x222: 0x812a, 0x223: 0x992e,
- 0x224: 0x992e, 0x225: 0x992e, 0x226: 0x992e, 0x227: 0x992a, 0x228: 0x992a, 0x229: 0x812e,
- 0x22a: 0x812e, 0x22b: 0x812e, 0x22c: 0x812e, 0x22d: 0x992e, 0x22e: 0x992e, 0x22f: 0x812e,
- 0x230: 0x992e, 0x231: 0x992e, 0x232: 0x812e, 0x233: 0x812e, 0x234: 0x8101, 0x235: 0x8101,
- 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812e, 0x23a: 0x812e, 0x23b: 0x812e,
- 0x23c: 0x812e, 0x23d: 0x8133, 0x23e: 0x8133, 0x23f: 0x8133,
- // Block 0x9, offset 0x240
- 0x240: 0x49c5, 0x241: 0x49ca, 0x242: 0x9933, 0x243: 0x49cf, 0x244: 0x4a88, 0x245: 0x9937,
- 0x246: 0x8133, 0x247: 0x812e, 0x248: 0x812e, 0x249: 0x812e, 0x24a: 0x8133, 0x24b: 0x8133,
- 0x24c: 0x8133, 0x24d: 0x812e, 0x24e: 0x812e, 0x250: 0x8133, 0x251: 0x8133,
- 0x252: 0x8133, 0x253: 0x812e, 0x254: 0x812e, 0x255: 0x812e, 0x256: 0x812e, 0x257: 0x8133,
- 0x258: 0x8134, 0x259: 0x812e, 0x25a: 0x812e, 0x25b: 0x8133, 0x25c: 0x8135, 0x25d: 0x8136,
- 0x25e: 0x8136, 0x25f: 0x8135, 0x260: 0x8136, 0x261: 0x8136, 0x262: 0x8135, 0x263: 0x8133,
- 0x264: 0x8133, 0x265: 0x8133, 0x266: 0x8133, 0x267: 0x8133, 0x268: 0x8133, 0x269: 0x8133,
- 0x26a: 0x8133, 0x26b: 0x8133, 0x26c: 0x8133, 0x26d: 0x8133, 0x26e: 0x8133, 0x26f: 0x8133,
- 0x274: 0x0173,
- 0x27a: 0x42bc,
- 0x27e: 0x0037,
- // Block 0xa, offset 0x280
- 0x284: 0x4271, 0x285: 0x4492,
- 0x286: 0x3600, 0x287: 0x00ce, 0x288: 0x361e, 0x289: 0x362a, 0x28a: 0x363c,
- 0x28c: 0x365a, 0x28e: 0x366c, 0x28f: 0x368a, 0x290: 0x3e1f, 0x291: 0xa000,
- 0x295: 0xa000, 0x297: 0xa000,
- 0x299: 0xa000,
- 0x29f: 0xa000, 0x2a1: 0xa000,
- 0x2a5: 0xa000, 0x2a9: 0xa000,
- 0x2aa: 0x364e, 0x2ab: 0x367e, 0x2ac: 0x4815, 0x2ad: 0x36ae, 0x2ae: 0x483f, 0x2af: 0x36c0,
- 0x2b0: 0x3e87, 0x2b1: 0xa000, 0x2b5: 0xa000,
- 0x2b7: 0xa000, 0x2b9: 0xa000,
- 0x2bf: 0xa000,
- // Block 0xb, offset 0x2c0
- 0x2c1: 0xa000, 0x2c5: 0xa000,
- 0x2c9: 0xa000, 0x2ca: 0x4857, 0x2cb: 0x4875,
- 0x2cc: 0x36de, 0x2cd: 0x36f6, 0x2ce: 0x488d, 0x2d0: 0x01c1, 0x2d1: 0x01d3,
- 0x2d2: 0x01af, 0x2d3: 0x4323, 0x2d4: 0x4329, 0x2d5: 0x01fd, 0x2d6: 0x01eb,
- 0x2f0: 0x01d9, 0x2f1: 0x01ee, 0x2f2: 0x01f1, 0x2f4: 0x018b, 0x2f5: 0x01ca,
- 0x2f9: 0x01a9,
- // Block 0xc, offset 0x300
- 0x300: 0x3738, 0x301: 0x3744, 0x303: 0x3732,
- 0x306: 0xa000, 0x307: 0x3720,
- 0x30c: 0x3774, 0x30d: 0x375c, 0x30e: 0x3786, 0x310: 0xa000,
- 0x313: 0xa000, 0x315: 0xa000, 0x316: 0xa000, 0x317: 0xa000,
- 0x318: 0xa000, 0x319: 0x3768, 0x31a: 0xa000,
- 0x31e: 0xa000, 0x323: 0xa000,
- 0x327: 0xa000,
- 0x32b: 0xa000, 0x32d: 0xa000,
- 0x330: 0xa000, 0x333: 0xa000, 0x335: 0xa000,
- 0x336: 0xa000, 0x337: 0xa000, 0x338: 0xa000, 0x339: 0x37ec, 0x33a: 0xa000,
- 0x33e: 0xa000,
- // Block 0xd, offset 0x340
- 0x341: 0x374a, 0x342: 0x37ce,
- 0x350: 0x3726, 0x351: 0x37aa,
- 0x352: 0x372c, 0x353: 0x37b0, 0x356: 0x373e, 0x357: 0x37c2,
- 0x358: 0xa000, 0x359: 0xa000, 0x35a: 0x3840, 0x35b: 0x3846, 0x35c: 0x3750, 0x35d: 0x37d4,
- 0x35e: 0x3756, 0x35f: 0x37da, 0x362: 0x3762, 0x363: 0x37e6,
- 0x364: 0x376e, 0x365: 0x37f2, 0x366: 0x377a, 0x367: 0x37fe, 0x368: 0xa000, 0x369: 0xa000,
- 0x36a: 0x384c, 0x36b: 0x3852, 0x36c: 0x37a4, 0x36d: 0x3828, 0x36e: 0x3780, 0x36f: 0x3804,
- 0x370: 0x378c, 0x371: 0x3810, 0x372: 0x3792, 0x373: 0x3816, 0x374: 0x3798, 0x375: 0x381c,
- 0x378: 0x379e, 0x379: 0x3822,
- // Block 0xe, offset 0x380
- 0x387: 0x1d67,
- 0x391: 0x812e,
- 0x392: 0x8133, 0x393: 0x8133, 0x394: 0x8133, 0x395: 0x8133, 0x396: 0x812e, 0x397: 0x8133,
- 0x398: 0x8133, 0x399: 0x8133, 0x39a: 0x812f, 0x39b: 0x812e, 0x39c: 0x8133, 0x39d: 0x8133,
- 0x39e: 0x8133, 0x39f: 0x8133, 0x3a0: 0x8133, 0x3a1: 0x8133, 0x3a2: 0x812e, 0x3a3: 0x812e,
- 0x3a4: 0x812e, 0x3a5: 0x812e, 0x3a6: 0x812e, 0x3a7: 0x812e, 0x3a8: 0x8133, 0x3a9: 0x8133,
- 0x3aa: 0x812e, 0x3ab: 0x8133, 0x3ac: 0x8133, 0x3ad: 0x812f, 0x3ae: 0x8132, 0x3af: 0x8133,
- 0x3b0: 0x8106, 0x3b1: 0x8107, 0x3b2: 0x8108, 0x3b3: 0x8109, 0x3b4: 0x810a, 0x3b5: 0x810b,
- 0x3b6: 0x810c, 0x3b7: 0x810d, 0x3b8: 0x810e, 0x3b9: 0x810f, 0x3ba: 0x810f, 0x3bb: 0x8110,
- 0x3bc: 0x8111, 0x3bd: 0x8112, 0x3bf: 0x8113,
- // Block 0xf, offset 0x3c0
- 0x3c8: 0xa000, 0x3ca: 0xa000, 0x3cb: 0x8117,
- 0x3cc: 0x8118, 0x3cd: 0x8119, 0x3ce: 0x811a, 0x3cf: 0x811b, 0x3d0: 0x811c, 0x3d1: 0x811d,
- 0x3d2: 0x811e, 0x3d3: 0x9933, 0x3d4: 0x9933, 0x3d5: 0x992e, 0x3d6: 0x812e, 0x3d7: 0x8133,
- 0x3d8: 0x8133, 0x3d9: 0x8133, 0x3da: 0x8133, 0x3db: 0x8133, 0x3dc: 0x812e, 0x3dd: 0x8133,
- 0x3de: 0x8133, 0x3df: 0x812e,
- 0x3f0: 0x811f, 0x3f5: 0x1d8a,
- 0x3f6: 0x2019, 0x3f7: 0x2055, 0x3f8: 0x2050,
- // Block 0x10, offset 0x400
- 0x413: 0x812e, 0x414: 0x8133, 0x415: 0x8133, 0x416: 0x8133, 0x417: 0x8133,
- 0x418: 0x8133, 0x419: 0x8133, 0x41a: 0x8133, 0x41b: 0x8133, 0x41c: 0x8133, 0x41d: 0x8133,
- 0x41e: 0x8133, 0x41f: 0x8133, 0x420: 0x8133, 0x421: 0x8133, 0x423: 0x812e,
- 0x424: 0x8133, 0x425: 0x8133, 0x426: 0x812e, 0x427: 0x8133, 0x428: 0x8133, 0x429: 0x812e,
- 0x42a: 0x8133, 0x42b: 0x8133, 0x42c: 0x8133, 0x42d: 0x812e, 0x42e: 0x812e, 0x42f: 0x812e,
- 0x430: 0x8117, 0x431: 0x8118, 0x432: 0x8119, 0x433: 0x8133, 0x434: 0x8133, 0x435: 0x8133,
- 0x436: 0x812e, 0x437: 0x8133, 0x438: 0x8133, 0x439: 0x812e, 0x43a: 0x812e, 0x43b: 0x8133,
- 0x43c: 0x8133, 0x43d: 0x8133, 0x43e: 0x8133, 0x43f: 0x8133,
- // Block 0x11, offset 0x440
- 0x445: 0xa000,
- 0x446: 0x2d33, 0x447: 0xa000, 0x448: 0x2d3b, 0x449: 0xa000, 0x44a: 0x2d43, 0x44b: 0xa000,
- 0x44c: 0x2d4b, 0x44d: 0xa000, 0x44e: 0x2d53, 0x451: 0xa000,
- 0x452: 0x2d5b,
- 0x474: 0x8103, 0x475: 0x9900,
- 0x47a: 0xa000, 0x47b: 0x2d63,
- 0x47c: 0xa000, 0x47d: 0x2d6b, 0x47e: 0xa000, 0x47f: 0xa000,
- // Block 0x12, offset 0x480
- 0x480: 0x0069, 0x481: 0x006b, 0x482: 0x006f, 0x483: 0x0083, 0x484: 0x00f5, 0x485: 0x00f8,
- 0x486: 0x0416, 0x487: 0x0085, 0x488: 0x0089, 0x489: 0x008b, 0x48a: 0x0104, 0x48b: 0x0107,
- 0x48c: 0x010a, 0x48d: 0x008f, 0x48f: 0x0097, 0x490: 0x009b, 0x491: 0x00e0,
- 0x492: 0x009f, 0x493: 0x00fe, 0x494: 0x041a, 0x495: 0x041e, 0x496: 0x00a1, 0x497: 0x00a9,
- 0x498: 0x00ab, 0x499: 0x0426, 0x49a: 0x012b, 0x49b: 0x00ad, 0x49c: 0x042a, 0x49d: 0x01c1,
- 0x49e: 0x01c4, 0x49f: 0x01c7, 0x4a0: 0x01fd, 0x4a1: 0x0200, 0x4a2: 0x0093, 0x4a3: 0x00a5,
- 0x4a4: 0x00ab, 0x4a5: 0x00ad, 0x4a6: 0x01c1, 0x4a7: 0x01c4, 0x4a8: 0x01ee, 0x4a9: 0x01fd,
- 0x4aa: 0x0200,
- 0x4b8: 0x020f,
- // Block 0x13, offset 0x4c0
- 0x4db: 0x00fb, 0x4dc: 0x0087, 0x4dd: 0x0101,
- 0x4de: 0x00d4, 0x4df: 0x010a, 0x4e0: 0x008d, 0x4e1: 0x010d, 0x4e2: 0x0110, 0x4e3: 0x0116,
- 0x4e4: 0x011c, 0x4e5: 0x011f, 0x4e6: 0x0122, 0x4e7: 0x042e, 0x4e8: 0x016d, 0x4e9: 0x0128,
- 0x4ea: 0x0432, 0x4eb: 0x0170, 0x4ec: 0x0131, 0x4ed: 0x012e, 0x4ee: 0x0134, 0x4ef: 0x0137,
- 0x4f0: 0x013a, 0x4f1: 0x013d, 0x4f2: 0x0140, 0x4f3: 0x014c, 0x4f4: 0x014f, 0x4f5: 0x00ec,
- 0x4f6: 0x0152, 0x4f7: 0x0155, 0x4f8: 0x0422, 0x4f9: 0x0158, 0x4fa: 0x015b, 0x4fb: 0x00b5,
- 0x4fc: 0x0161, 0x4fd: 0x0164, 0x4fe: 0x0167, 0x4ff: 0x01d3,
- // Block 0x14, offset 0x500
- 0x500: 0x8133, 0x501: 0x8133, 0x502: 0x812e, 0x503: 0x8133, 0x504: 0x8133, 0x505: 0x8133,
- 0x506: 0x8133, 0x507: 0x8133, 0x508: 0x8133, 0x509: 0x8133, 0x50a: 0x812e, 0x50b: 0x8133,
- 0x50c: 0x8133, 0x50d: 0x8136, 0x50e: 0x812b, 0x50f: 0x812e, 0x510: 0x812a, 0x511: 0x8133,
- 0x512: 0x8133, 0x513: 0x8133, 0x514: 0x8133, 0x515: 0x8133, 0x516: 0x8133, 0x517: 0x8133,
- 0x518: 0x8133, 0x519: 0x8133, 0x51a: 0x8133, 0x51b: 0x8133, 0x51c: 0x8133, 0x51d: 0x8133,
- 0x51e: 0x8133, 0x51f: 0x8133, 0x520: 0x8133, 0x521: 0x8133, 0x522: 0x8133, 0x523: 0x8133,
- 0x524: 0x8133, 0x525: 0x8133, 0x526: 0x8133, 0x527: 0x8133, 0x528: 0x8133, 0x529: 0x8133,
- 0x52a: 0x8133, 0x52b: 0x8133, 0x52c: 0x8133, 0x52d: 0x8133, 0x52e: 0x8133, 0x52f: 0x8133,
- 0x530: 0x8133, 0x531: 0x8133, 0x532: 0x8133, 0x533: 0x8133, 0x534: 0x8133, 0x535: 0x8133,
- 0x536: 0x8134, 0x537: 0x8132, 0x538: 0x8132, 0x539: 0x812e, 0x53b: 0x8133,
- 0x53c: 0x8135, 0x53d: 0x812e, 0x53e: 0x8133, 0x53f: 0x812e,
- // Block 0x15, offset 0x540
- 0x540: 0x2fae, 0x541: 0x32ba, 0x542: 0x2fb8, 0x543: 0x32c4, 0x544: 0x2fbd, 0x545: 0x32c9,
- 0x546: 0x2fc2, 0x547: 0x32ce, 0x548: 0x38e3, 0x549: 0x3a72, 0x54a: 0x2fdb, 0x54b: 0x32e7,
- 0x54c: 0x2fe5, 0x54d: 0x32f1, 0x54e: 0x2ff4, 0x54f: 0x3300, 0x550: 0x2fea, 0x551: 0x32f6,
- 0x552: 0x2fef, 0x553: 0x32fb, 0x554: 0x3906, 0x555: 0x3a95, 0x556: 0x390d, 0x557: 0x3a9c,
- 0x558: 0x3030, 0x559: 0x333c, 0x55a: 0x3035, 0x55b: 0x3341, 0x55c: 0x391b, 0x55d: 0x3aaa,
- 0x55e: 0x303a, 0x55f: 0x3346, 0x560: 0x3049, 0x561: 0x3355, 0x562: 0x3067, 0x563: 0x3373,
- 0x564: 0x3076, 0x565: 0x3382, 0x566: 0x306c, 0x567: 0x3378, 0x568: 0x307b, 0x569: 0x3387,
- 0x56a: 0x3080, 0x56b: 0x338c, 0x56c: 0x30c6, 0x56d: 0x33d2, 0x56e: 0x3922, 0x56f: 0x3ab1,
- 0x570: 0x30d0, 0x571: 0x33e1, 0x572: 0x30da, 0x573: 0x33eb, 0x574: 0x30e4, 0x575: 0x33f5,
- 0x576: 0x46db, 0x577: 0x476c, 0x578: 0x3929, 0x579: 0x3ab8, 0x57a: 0x30fd, 0x57b: 0x340e,
- 0x57c: 0x30f8, 0x57d: 0x3409, 0x57e: 0x3102, 0x57f: 0x3413,
- // Block 0x16, offset 0x580
- 0x580: 0x3107, 0x581: 0x3418, 0x582: 0x310c, 0x583: 0x341d, 0x584: 0x3120, 0x585: 0x3431,
- 0x586: 0x312a, 0x587: 0x343b, 0x588: 0x3139, 0x589: 0x344a, 0x58a: 0x3134, 0x58b: 0x3445,
- 0x58c: 0x394c, 0x58d: 0x3adb, 0x58e: 0x395a, 0x58f: 0x3ae9, 0x590: 0x3961, 0x591: 0x3af0,
- 0x592: 0x3968, 0x593: 0x3af7, 0x594: 0x3166, 0x595: 0x3477, 0x596: 0x316b, 0x597: 0x347c,
- 0x598: 0x3175, 0x599: 0x3486, 0x59a: 0x4708, 0x59b: 0x4799, 0x59c: 0x39ae, 0x59d: 0x3b3d,
- 0x59e: 0x318e, 0x59f: 0x349f, 0x5a0: 0x3198, 0x5a1: 0x34a9, 0x5a2: 0x4717, 0x5a3: 0x47a8,
- 0x5a4: 0x39b5, 0x5a5: 0x3b44, 0x5a6: 0x39bc, 0x5a7: 0x3b4b, 0x5a8: 0x39c3, 0x5a9: 0x3b52,
- 0x5aa: 0x31a7, 0x5ab: 0x34b8, 0x5ac: 0x31b1, 0x5ad: 0x34c7, 0x5ae: 0x31c5, 0x5af: 0x34db,
- 0x5b0: 0x31c0, 0x5b1: 0x34d6, 0x5b2: 0x3201, 0x5b3: 0x3517, 0x5b4: 0x3210, 0x5b5: 0x3526,
- 0x5b6: 0x320b, 0x5b7: 0x3521, 0x5b8: 0x39ca, 0x5b9: 0x3b59, 0x5ba: 0x39d1, 0x5bb: 0x3b60,
- 0x5bc: 0x3215, 0x5bd: 0x352b, 0x5be: 0x321a, 0x5bf: 0x3530,
- // Block 0x17, offset 0x5c0
- 0x5c0: 0x321f, 0x5c1: 0x3535, 0x5c2: 0x3224, 0x5c3: 0x353a, 0x5c4: 0x3233, 0x5c5: 0x3549,
- 0x5c6: 0x322e, 0x5c7: 0x3544, 0x5c8: 0x3238, 0x5c9: 0x3553, 0x5ca: 0x323d, 0x5cb: 0x3558,
- 0x5cc: 0x3242, 0x5cd: 0x355d, 0x5ce: 0x3260, 0x5cf: 0x357b, 0x5d0: 0x3279, 0x5d1: 0x3599,
- 0x5d2: 0x3288, 0x5d3: 0x35a8, 0x5d4: 0x328d, 0x5d5: 0x35ad, 0x5d6: 0x3391, 0x5d7: 0x34bd,
- 0x5d8: 0x354e, 0x5d9: 0x358a, 0x5da: 0x1be6, 0x5db: 0x42ee,
- 0x5e0: 0x46b8, 0x5e1: 0x4749, 0x5e2: 0x2f9a, 0x5e3: 0x32a6,
- 0x5e4: 0x388f, 0x5e5: 0x3a1e, 0x5e6: 0x3888, 0x5e7: 0x3a17, 0x5e8: 0x389d, 0x5e9: 0x3a2c,
- 0x5ea: 0x3896, 0x5eb: 0x3a25, 0x5ec: 0x38d5, 0x5ed: 0x3a64, 0x5ee: 0x38ab, 0x5ef: 0x3a3a,
- 0x5f0: 0x38a4, 0x5f1: 0x3a33, 0x5f2: 0x38b9, 0x5f3: 0x3a48, 0x5f4: 0x38b2, 0x5f5: 0x3a41,
- 0x5f6: 0x38dc, 0x5f7: 0x3a6b, 0x5f8: 0x46cc, 0x5f9: 0x475d, 0x5fa: 0x3017, 0x5fb: 0x3323,
- 0x5fc: 0x3003, 0x5fd: 0x330f, 0x5fe: 0x38f1, 0x5ff: 0x3a80,
- // Block 0x18, offset 0x600
- 0x600: 0x38ea, 0x601: 0x3a79, 0x602: 0x38ff, 0x603: 0x3a8e, 0x604: 0x38f8, 0x605: 0x3a87,
- 0x606: 0x3914, 0x607: 0x3aa3, 0x608: 0x30a8, 0x609: 0x33b4, 0x60a: 0x30bc, 0x60b: 0x33c8,
- 0x60c: 0x46fe, 0x60d: 0x478f, 0x60e: 0x314d, 0x60f: 0x345e, 0x610: 0x3937, 0x611: 0x3ac6,
- 0x612: 0x3930, 0x613: 0x3abf, 0x614: 0x3945, 0x615: 0x3ad4, 0x616: 0x393e, 0x617: 0x3acd,
- 0x618: 0x39a0, 0x619: 0x3b2f, 0x61a: 0x3984, 0x61b: 0x3b13, 0x61c: 0x397d, 0x61d: 0x3b0c,
- 0x61e: 0x3992, 0x61f: 0x3b21, 0x620: 0x398b, 0x621: 0x3b1a, 0x622: 0x3999, 0x623: 0x3b28,
- 0x624: 0x31fc, 0x625: 0x3512, 0x626: 0x31de, 0x627: 0x34f4, 0x628: 0x39fb, 0x629: 0x3b8a,
- 0x62a: 0x39f4, 0x62b: 0x3b83, 0x62c: 0x3a09, 0x62d: 0x3b98, 0x62e: 0x3a02, 0x62f: 0x3b91,
- 0x630: 0x3a10, 0x631: 0x3b9f, 0x632: 0x3247, 0x633: 0x3562, 0x634: 0x326f, 0x635: 0x358f,
- 0x636: 0x326a, 0x637: 0x3585, 0x638: 0x3256, 0x639: 0x3571,
- // Block 0x19, offset 0x640
- 0x640: 0x481b, 0x641: 0x4821, 0x642: 0x4935, 0x643: 0x494d, 0x644: 0x493d, 0x645: 0x4955,
- 0x646: 0x4945, 0x647: 0x495d, 0x648: 0x47c1, 0x649: 0x47c7, 0x64a: 0x48a5, 0x64b: 0x48bd,
- 0x64c: 0x48ad, 0x64d: 0x48c5, 0x64e: 0x48b5, 0x64f: 0x48cd, 0x650: 0x482d, 0x651: 0x4833,
- 0x652: 0x3dcf, 0x653: 0x3ddf, 0x654: 0x3dd7, 0x655: 0x3de7,
- 0x658: 0x47cd, 0x659: 0x47d3, 0x65a: 0x3cff, 0x65b: 0x3d0f, 0x65c: 0x3d07, 0x65d: 0x3d17,
- 0x660: 0x4845, 0x661: 0x484b, 0x662: 0x4965, 0x663: 0x497d,
- 0x664: 0x496d, 0x665: 0x4985, 0x666: 0x4975, 0x667: 0x498d, 0x668: 0x47d9, 0x669: 0x47df,
- 0x66a: 0x48d5, 0x66b: 0x48ed, 0x66c: 0x48dd, 0x66d: 0x48f5, 0x66e: 0x48e5, 0x66f: 0x48fd,
- 0x670: 0x485d, 0x671: 0x4863, 0x672: 0x3e2f, 0x673: 0x3e47, 0x674: 0x3e37, 0x675: 0x3e4f,
- 0x676: 0x3e3f, 0x677: 0x3e57, 0x678: 0x47e5, 0x679: 0x47eb, 0x67a: 0x3d2f, 0x67b: 0x3d47,
- 0x67c: 0x3d37, 0x67d: 0x3d4f, 0x67e: 0x3d3f, 0x67f: 0x3d57,
- // Block 0x1a, offset 0x680
- 0x680: 0x4869, 0x681: 0x486f, 0x682: 0x3e5f, 0x683: 0x3e6f, 0x684: 0x3e67, 0x685: 0x3e77,
- 0x688: 0x47f1, 0x689: 0x47f7, 0x68a: 0x3d5f, 0x68b: 0x3d6f,
- 0x68c: 0x3d67, 0x68d: 0x3d77, 0x690: 0x487b, 0x691: 0x4881,
- 0x692: 0x3e97, 0x693: 0x3eaf, 0x694: 0x3e9f, 0x695: 0x3eb7, 0x696: 0x3ea7, 0x697: 0x3ebf,
- 0x699: 0x47fd, 0x69b: 0x3d7f, 0x69d: 0x3d87,
- 0x69f: 0x3d8f, 0x6a0: 0x4893, 0x6a1: 0x4899, 0x6a2: 0x4995, 0x6a3: 0x49ad,
- 0x6a4: 0x499d, 0x6a5: 0x49b5, 0x6a6: 0x49a5, 0x6a7: 0x49bd, 0x6a8: 0x4803, 0x6a9: 0x4809,
- 0x6aa: 0x4905, 0x6ab: 0x491d, 0x6ac: 0x490d, 0x6ad: 0x4925, 0x6ae: 0x4915, 0x6af: 0x492d,
- 0x6b0: 0x480f, 0x6b1: 0x4335, 0x6b2: 0x36a8, 0x6b3: 0x433b, 0x6b4: 0x4839, 0x6b5: 0x4341,
- 0x6b6: 0x36ba, 0x6b7: 0x4347, 0x6b8: 0x36d8, 0x6b9: 0x434d, 0x6ba: 0x36f0, 0x6bb: 0x4353,
- 0x6bc: 0x4887, 0x6bd: 0x4359,
- // Block 0x1b, offset 0x6c0
- 0x6c0: 0x3db7, 0x6c1: 0x3dbf, 0x6c2: 0x419b, 0x6c3: 0x41b9, 0x6c4: 0x41a5, 0x6c5: 0x41c3,
- 0x6c6: 0x41af, 0x6c7: 0x41cd, 0x6c8: 0x3cef, 0x6c9: 0x3cf7, 0x6ca: 0x40e7, 0x6cb: 0x4105,
- 0x6cc: 0x40f1, 0x6cd: 0x410f, 0x6ce: 0x40fb, 0x6cf: 0x4119, 0x6d0: 0x3dff, 0x6d1: 0x3e07,
- 0x6d2: 0x41d7, 0x6d3: 0x41f5, 0x6d4: 0x41e1, 0x6d5: 0x41ff, 0x6d6: 0x41eb, 0x6d7: 0x4209,
- 0x6d8: 0x3d1f, 0x6d9: 0x3d27, 0x6da: 0x4123, 0x6db: 0x4141, 0x6dc: 0x412d, 0x6dd: 0x414b,
- 0x6de: 0x4137, 0x6df: 0x4155, 0x6e0: 0x3ed7, 0x6e1: 0x3edf, 0x6e2: 0x4213, 0x6e3: 0x4231,
- 0x6e4: 0x421d, 0x6e5: 0x423b, 0x6e6: 0x4227, 0x6e7: 0x4245, 0x6e8: 0x3d97, 0x6e9: 0x3d9f,
- 0x6ea: 0x415f, 0x6eb: 0x417d, 0x6ec: 0x4169, 0x6ed: 0x4187, 0x6ee: 0x4173, 0x6ef: 0x4191,
- 0x6f0: 0x369c, 0x6f1: 0x3696, 0x6f2: 0x3da7, 0x6f3: 0x36a2, 0x6f4: 0x3daf,
- 0x6f6: 0x4827, 0x6f7: 0x3dc7, 0x6f8: 0x360c, 0x6f9: 0x3606, 0x6fa: 0x35fa, 0x6fb: 0x4305,
- 0x6fc: 0x3612, 0x6fd: 0x429e, 0x6fe: 0x01d6, 0x6ff: 0x429e,
- // Block 0x1c, offset 0x700
- 0x700: 0x42b7, 0x701: 0x4499, 0x702: 0x3def, 0x703: 0x36b4, 0x704: 0x3df7,
- 0x706: 0x4851, 0x707: 0x3e0f, 0x708: 0x3618, 0x709: 0x430b, 0x70a: 0x3624, 0x70b: 0x4311,
- 0x70c: 0x3630, 0x70d: 0x44a0, 0x70e: 0x44a7, 0x70f: 0x44ae, 0x710: 0x36cc, 0x711: 0x36c6,
- 0x712: 0x3e17, 0x713: 0x44fb, 0x716: 0x36d2, 0x717: 0x3e27,
- 0x718: 0x3648, 0x719: 0x3642, 0x71a: 0x3636, 0x71b: 0x4317, 0x71d: 0x44b5,
- 0x71e: 0x44bc, 0x71f: 0x44c3, 0x720: 0x3702, 0x721: 0x36fc, 0x722: 0x3e7f, 0x723: 0x4503,
- 0x724: 0x36e4, 0x725: 0x36ea, 0x726: 0x3708, 0x727: 0x3e8f, 0x728: 0x3678, 0x729: 0x3672,
- 0x72a: 0x3666, 0x72b: 0x4323, 0x72c: 0x3660, 0x72d: 0x448b, 0x72e: 0x4492, 0x72f: 0x0081,
- 0x732: 0x3ec7, 0x733: 0x370e, 0x734: 0x3ecf,
- 0x736: 0x489f, 0x737: 0x3ee7, 0x738: 0x3654, 0x739: 0x431d, 0x73a: 0x3684, 0x73b: 0x432f,
- 0x73c: 0x3690, 0x73d: 0x4271, 0x73e: 0x42a3,
- // Block 0x1d, offset 0x740
- 0x740: 0x1bde, 0x741: 0x1be2, 0x742: 0x0047, 0x743: 0x1c5a, 0x745: 0x1bee,
- 0x746: 0x1bf2, 0x747: 0x00e9, 0x749: 0x1c5e, 0x74a: 0x008f, 0x74b: 0x0051,
- 0x74c: 0x0051, 0x74d: 0x0051, 0x74e: 0x0091, 0x74f: 0x00da, 0x750: 0x0053, 0x751: 0x0053,
- 0x752: 0x0059, 0x753: 0x0099, 0x755: 0x005d, 0x756: 0x1993,
- 0x759: 0x0061, 0x75a: 0x0063, 0x75b: 0x0065, 0x75c: 0x0065, 0x75d: 0x0065,
- 0x760: 0x19a5, 0x761: 0x1bce, 0x762: 0x19ae,
- 0x764: 0x0075, 0x766: 0x01bb, 0x768: 0x0075,
- 0x76a: 0x0057, 0x76b: 0x42e9, 0x76c: 0x0045, 0x76d: 0x0047, 0x76f: 0x008b,
- 0x770: 0x004b, 0x771: 0x004d, 0x773: 0x005b, 0x774: 0x009f, 0x775: 0x0218,
- 0x776: 0x021b, 0x777: 0x021e, 0x778: 0x0221, 0x779: 0x0093, 0x77b: 0x1b9e,
- 0x77c: 0x01eb, 0x77d: 0x01c4, 0x77e: 0x017c, 0x77f: 0x01a3,
- // Block 0x1e, offset 0x780
- 0x780: 0x0466, 0x785: 0x0049,
- 0x786: 0x0089, 0x787: 0x008b, 0x788: 0x0093, 0x789: 0x0095,
- 0x790: 0x2234, 0x791: 0x2240,
- 0x792: 0x22f4, 0x793: 0x221c, 0x794: 0x22a0, 0x795: 0x2228, 0x796: 0x22a6, 0x797: 0x22be,
- 0x798: 0x22ca, 0x799: 0x222e, 0x79a: 0x22d0, 0x79b: 0x223a, 0x79c: 0x22c4, 0x79d: 0x22d6,
- 0x79e: 0x22dc, 0x79f: 0x1cc2, 0x7a0: 0x0053, 0x7a1: 0x195d, 0x7a2: 0x1baa, 0x7a3: 0x1966,
- 0x7a4: 0x006d, 0x7a5: 0x19b1, 0x7a6: 0x1bd6, 0x7a7: 0x1d4e, 0x7a8: 0x1969, 0x7a9: 0x0071,
- 0x7aa: 0x19bd, 0x7ab: 0x1bda, 0x7ac: 0x0059, 0x7ad: 0x0047, 0x7ae: 0x0049, 0x7af: 0x005b,
- 0x7b0: 0x0093, 0x7b1: 0x19ea, 0x7b2: 0x1c1e, 0x7b3: 0x19f3, 0x7b4: 0x00ad, 0x7b5: 0x1a68,
- 0x7b6: 0x1c52, 0x7b7: 0x1d62, 0x7b8: 0x19f6, 0x7b9: 0x00b1, 0x7ba: 0x1a6b, 0x7bb: 0x1c56,
- 0x7bc: 0x0099, 0x7bd: 0x0087, 0x7be: 0x0089, 0x7bf: 0x009b,
- // Block 0x1f, offset 0x7c0
- 0x7c1: 0x3c1d, 0x7c3: 0xa000, 0x7c4: 0x3c24, 0x7c5: 0xa000,
- 0x7c7: 0x3c2b, 0x7c8: 0xa000, 0x7c9: 0x3c32,
- 0x7cd: 0xa000,
- 0x7e0: 0x2f7c, 0x7e1: 0xa000, 0x7e2: 0x3c40,
- 0x7e4: 0xa000, 0x7e5: 0xa000,
- 0x7ed: 0x3c39, 0x7ee: 0x2f77, 0x7ef: 0x2f81,
- 0x7f0: 0x3c47, 0x7f1: 0x3c4e, 0x7f2: 0xa000, 0x7f3: 0xa000, 0x7f4: 0x3c55, 0x7f5: 0x3c5c,
- 0x7f6: 0xa000, 0x7f7: 0xa000, 0x7f8: 0x3c63, 0x7f9: 0x3c6a, 0x7fa: 0xa000, 0x7fb: 0xa000,
- 0x7fc: 0xa000, 0x7fd: 0xa000,
- // Block 0x20, offset 0x800
- 0x800: 0x3c71, 0x801: 0x3c78, 0x802: 0xa000, 0x803: 0xa000, 0x804: 0x3c8d, 0x805: 0x3c94,
- 0x806: 0xa000, 0x807: 0xa000, 0x808: 0x3c9b, 0x809: 0x3ca2,
- 0x811: 0xa000,
- 0x812: 0xa000,
- 0x822: 0xa000,
- 0x828: 0xa000, 0x829: 0xa000,
- 0x82b: 0xa000, 0x82c: 0x3cb7, 0x82d: 0x3cbe, 0x82e: 0x3cc5, 0x82f: 0x3ccc,
- 0x832: 0xa000, 0x833: 0xa000, 0x834: 0xa000, 0x835: 0xa000,
- // Block 0x21, offset 0x840
- 0x860: 0x0023, 0x861: 0x0025, 0x862: 0x0027, 0x863: 0x0029,
- 0x864: 0x002b, 0x865: 0x002d, 0x866: 0x002f, 0x867: 0x0031, 0x868: 0x0033, 0x869: 0x1885,
- 0x86a: 0x1888, 0x86b: 0x188b, 0x86c: 0x188e, 0x86d: 0x1891, 0x86e: 0x1894, 0x86f: 0x1897,
- 0x870: 0x189a, 0x871: 0x189d, 0x872: 0x18a0, 0x873: 0x18a9, 0x874: 0x1a6e, 0x875: 0x1a72,
- 0x876: 0x1a76, 0x877: 0x1a7a, 0x878: 0x1a7e, 0x879: 0x1a82, 0x87a: 0x1a86, 0x87b: 0x1a8a,
- 0x87c: 0x1a8e, 0x87d: 0x1c86, 0x87e: 0x1c8b, 0x87f: 0x1c90,
- // Block 0x22, offset 0x880
- 0x880: 0x1c95, 0x881: 0x1c9a, 0x882: 0x1c9f, 0x883: 0x1ca4, 0x884: 0x1ca9, 0x885: 0x1cae,
- 0x886: 0x1cb3, 0x887: 0x1cb8, 0x888: 0x1882, 0x889: 0x18a6, 0x88a: 0x18ca, 0x88b: 0x18ee,
- 0x88c: 0x1912, 0x88d: 0x191b, 0x88e: 0x1921, 0x88f: 0x1927, 0x890: 0x192d, 0x891: 0x1b66,
- 0x892: 0x1b6a, 0x893: 0x1b6e, 0x894: 0x1b72, 0x895: 0x1b76, 0x896: 0x1b7a, 0x897: 0x1b7e,
- 0x898: 0x1b82, 0x899: 0x1b86, 0x89a: 0x1b8a, 0x89b: 0x1b8e, 0x89c: 0x1afa, 0x89d: 0x1afe,
- 0x89e: 0x1b02, 0x89f: 0x1b06, 0x8a0: 0x1b0a, 0x8a1: 0x1b0e, 0x8a2: 0x1b12, 0x8a3: 0x1b16,
- 0x8a4: 0x1b1a, 0x8a5: 0x1b1e, 0x8a6: 0x1b22, 0x8a7: 0x1b26, 0x8a8: 0x1b2a, 0x8a9: 0x1b2e,
- 0x8aa: 0x1b32, 0x8ab: 0x1b36, 0x8ac: 0x1b3a, 0x8ad: 0x1b3e, 0x8ae: 0x1b42, 0x8af: 0x1b46,
- 0x8b0: 0x1b4a, 0x8b1: 0x1b4e, 0x8b2: 0x1b52, 0x8b3: 0x1b56, 0x8b4: 0x1b5a, 0x8b5: 0x1b5e,
- 0x8b6: 0x0043, 0x8b7: 0x0045, 0x8b8: 0x0047, 0x8b9: 0x0049, 0x8ba: 0x004b, 0x8bb: 0x004d,
- 0x8bc: 0x004f, 0x8bd: 0x0051, 0x8be: 0x0053, 0x8bf: 0x0055,
- // Block 0x23, offset 0x8c0
- 0x8c0: 0x06c2, 0x8c1: 0x06e6, 0x8c2: 0x06f2, 0x8c3: 0x0702, 0x8c4: 0x070a, 0x8c5: 0x0716,
- 0x8c6: 0x071e, 0x8c7: 0x0726, 0x8c8: 0x0732, 0x8c9: 0x0786, 0x8ca: 0x079e, 0x8cb: 0x07ae,
- 0x8cc: 0x07be, 0x8cd: 0x07ce, 0x8ce: 0x07de, 0x8cf: 0x07fe, 0x8d0: 0x0802, 0x8d1: 0x0806,
- 0x8d2: 0x083a, 0x8d3: 0x0862, 0x8d4: 0x0872, 0x8d5: 0x087a, 0x8d6: 0x087e, 0x8d7: 0x088a,
- 0x8d8: 0x08a6, 0x8d9: 0x08aa, 0x8da: 0x08c2, 0x8db: 0x08c6, 0x8dc: 0x08ce, 0x8dd: 0x08de,
- 0x8de: 0x097a, 0x8df: 0x098e, 0x8e0: 0x09ce, 0x8e1: 0x09e2, 0x8e2: 0x09ea, 0x8e3: 0x09ee,
- 0x8e4: 0x09fe, 0x8e5: 0x0a1a, 0x8e6: 0x0a46, 0x8e7: 0x0a52, 0x8e8: 0x0a72, 0x8e9: 0x0a7e,
- 0x8ea: 0x0a82, 0x8eb: 0x0a86, 0x8ec: 0x0a9e, 0x8ed: 0x0aa2, 0x8ee: 0x0ace, 0x8ef: 0x0ada,
- 0x8f0: 0x0ae2, 0x8f1: 0x0aea, 0x8f2: 0x0afa, 0x8f3: 0x0b02, 0x8f4: 0x0b0a, 0x8f5: 0x0b36,
- 0x8f6: 0x0b3a, 0x8f7: 0x0b42, 0x8f8: 0x0b46, 0x8f9: 0x0b4e, 0x8fa: 0x0b56, 0x8fb: 0x0b66,
- 0x8fc: 0x0b82, 0x8fd: 0x0bfa, 0x8fe: 0x0c0e, 0x8ff: 0x0c12,
- // Block 0x24, offset 0x900
- 0x900: 0x0c92, 0x901: 0x0c96, 0x902: 0x0caa, 0x903: 0x0cae, 0x904: 0x0cb6, 0x905: 0x0cbe,
- 0x906: 0x0cc6, 0x907: 0x0cd2, 0x908: 0x0cfa, 0x909: 0x0d0a, 0x90a: 0x0d1e, 0x90b: 0x0d8e,
- 0x90c: 0x0d9a, 0x90d: 0x0daa, 0x90e: 0x0db6, 0x90f: 0x0dc2, 0x910: 0x0dca, 0x911: 0x0dce,
- 0x912: 0x0dd2, 0x913: 0x0dd6, 0x914: 0x0dda, 0x915: 0x0e92, 0x916: 0x0eda, 0x917: 0x0ee6,
- 0x918: 0x0eea, 0x919: 0x0eee, 0x91a: 0x0ef2, 0x91b: 0x0efa, 0x91c: 0x0efe, 0x91d: 0x0f12,
- 0x91e: 0x0f2e, 0x91f: 0x0f36, 0x920: 0x0f76, 0x921: 0x0f7a, 0x922: 0x0f82, 0x923: 0x0f86,
- 0x924: 0x0f8e, 0x925: 0x0f92, 0x926: 0x0fb6, 0x927: 0x0fba, 0x928: 0x0fd6, 0x929: 0x0fda,
- 0x92a: 0x0fde, 0x92b: 0x0fe2, 0x92c: 0x0ff6, 0x92d: 0x101a, 0x92e: 0x101e, 0x92f: 0x1022,
- 0x930: 0x1046, 0x931: 0x1086, 0x932: 0x108a, 0x933: 0x10aa, 0x934: 0x10ba, 0x935: 0x10c2,
- 0x936: 0x10e2, 0x937: 0x1106, 0x938: 0x114a, 0x939: 0x1152, 0x93a: 0x1166, 0x93b: 0x1172,
- 0x93c: 0x117a, 0x93d: 0x1182, 0x93e: 0x1186, 0x93f: 0x118a,
- // Block 0x25, offset 0x940
- 0x940: 0x11a2, 0x941: 0x11a6, 0x942: 0x11c2, 0x943: 0x11ca, 0x944: 0x11d2, 0x945: 0x11d6,
- 0x946: 0x11e2, 0x947: 0x11ea, 0x948: 0x11ee, 0x949: 0x11f2, 0x94a: 0x11fa, 0x94b: 0x11fe,
- 0x94c: 0x129e, 0x94d: 0x12b2, 0x94e: 0x12e6, 0x94f: 0x12ea, 0x950: 0x12f2, 0x951: 0x131e,
- 0x952: 0x1326, 0x953: 0x132e, 0x954: 0x1336, 0x955: 0x1372, 0x956: 0x1376, 0x957: 0x137e,
- 0x958: 0x1382, 0x959: 0x1386, 0x95a: 0x13b2, 0x95b: 0x13b6, 0x95c: 0x13be, 0x95d: 0x13d2,
- 0x95e: 0x13d6, 0x95f: 0x13f2, 0x960: 0x13fa, 0x961: 0x13fe, 0x962: 0x1422, 0x963: 0x1442,
- 0x964: 0x1456, 0x965: 0x145a, 0x966: 0x1462, 0x967: 0x148e, 0x968: 0x1492, 0x969: 0x14a2,
- 0x96a: 0x14c6, 0x96b: 0x14d2, 0x96c: 0x14e2, 0x96d: 0x14fa, 0x96e: 0x1502, 0x96f: 0x1506,
- 0x970: 0x150a, 0x971: 0x150e, 0x972: 0x151a, 0x973: 0x151e, 0x974: 0x1526, 0x975: 0x1542,
- 0x976: 0x1546, 0x977: 0x154a, 0x978: 0x1562, 0x979: 0x1566, 0x97a: 0x156e, 0x97b: 0x1582,
- 0x97c: 0x1586, 0x97d: 0x158a, 0x97e: 0x1592, 0x97f: 0x1596,
- // Block 0x26, offset 0x980
- 0x986: 0xa000, 0x98b: 0xa000,
- 0x98c: 0x3f1f, 0x98d: 0xa000, 0x98e: 0x3f27, 0x98f: 0xa000, 0x990: 0x3f2f, 0x991: 0xa000,
- 0x992: 0x3f37, 0x993: 0xa000, 0x994: 0x3f3f, 0x995: 0xa000, 0x996: 0x3f47, 0x997: 0xa000,
- 0x998: 0x3f4f, 0x999: 0xa000, 0x99a: 0x3f57, 0x99b: 0xa000, 0x99c: 0x3f5f, 0x99d: 0xa000,
- 0x99e: 0x3f67, 0x99f: 0xa000, 0x9a0: 0x3f6f, 0x9a1: 0xa000, 0x9a2: 0x3f77,
- 0x9a4: 0xa000, 0x9a5: 0x3f7f, 0x9a6: 0xa000, 0x9a7: 0x3f87, 0x9a8: 0xa000, 0x9a9: 0x3f8f,
- 0x9af: 0xa000,
- 0x9b0: 0x3f97, 0x9b1: 0x3f9f, 0x9b2: 0xa000, 0x9b3: 0x3fa7, 0x9b4: 0x3faf, 0x9b5: 0xa000,
- 0x9b6: 0x3fb7, 0x9b7: 0x3fbf, 0x9b8: 0xa000, 0x9b9: 0x3fc7, 0x9ba: 0x3fcf, 0x9bb: 0xa000,
- 0x9bc: 0x3fd7, 0x9bd: 0x3fdf,
- // Block 0x27, offset 0x9c0
- 0x9d4: 0x3f17,
- 0x9d9: 0x9904, 0x9da: 0x9904, 0x9db: 0x42f3, 0x9dc: 0x42f9, 0x9dd: 0xa000,
- 0x9de: 0x3fe7, 0x9df: 0x26ba,
- 0x9e6: 0xa000,
- 0x9eb: 0xa000, 0x9ec: 0x3ff7, 0x9ed: 0xa000, 0x9ee: 0x3fff, 0x9ef: 0xa000,
- 0x9f0: 0x4007, 0x9f1: 0xa000, 0x9f2: 0x400f, 0x9f3: 0xa000, 0x9f4: 0x4017, 0x9f5: 0xa000,
- 0x9f6: 0x401f, 0x9f7: 0xa000, 0x9f8: 0x4027, 0x9f9: 0xa000, 0x9fa: 0x402f, 0x9fb: 0xa000,
- 0x9fc: 0x4037, 0x9fd: 0xa000, 0x9fe: 0x403f, 0x9ff: 0xa000,
- // Block 0x28, offset 0xa00
- 0xa00: 0x4047, 0xa01: 0xa000, 0xa02: 0x404f, 0xa04: 0xa000, 0xa05: 0x4057,
- 0xa06: 0xa000, 0xa07: 0x405f, 0xa08: 0xa000, 0xa09: 0x4067,
- 0xa0f: 0xa000, 0xa10: 0x406f, 0xa11: 0x4077,
- 0xa12: 0xa000, 0xa13: 0x407f, 0xa14: 0x4087, 0xa15: 0xa000, 0xa16: 0x408f, 0xa17: 0x4097,
- 0xa18: 0xa000, 0xa19: 0x409f, 0xa1a: 0x40a7, 0xa1b: 0xa000, 0xa1c: 0x40af, 0xa1d: 0x40b7,
- 0xa2f: 0xa000,
- 0xa30: 0xa000, 0xa31: 0xa000, 0xa32: 0xa000, 0xa34: 0x3fef,
- 0xa37: 0x40bf, 0xa38: 0x40c7, 0xa39: 0x40cf, 0xa3a: 0x40d7,
- 0xa3d: 0xa000, 0xa3e: 0x40df, 0xa3f: 0x26cf,
- // Block 0x29, offset 0xa40
- 0xa40: 0x036a, 0xa41: 0x032e, 0xa42: 0x0332, 0xa43: 0x0336, 0xa44: 0x037e, 0xa45: 0x033a,
- 0xa46: 0x033e, 0xa47: 0x0342, 0xa48: 0x0346, 0xa49: 0x034a, 0xa4a: 0x034e, 0xa4b: 0x0352,
- 0xa4c: 0x0356, 0xa4d: 0x035a, 0xa4e: 0x035e, 0xa4f: 0x49d4, 0xa50: 0x49da, 0xa51: 0x49e0,
- 0xa52: 0x49e6, 0xa53: 0x49ec, 0xa54: 0x49f2, 0xa55: 0x49f8, 0xa56: 0x49fe, 0xa57: 0x4a04,
- 0xa58: 0x4a0a, 0xa59: 0x4a10, 0xa5a: 0x4a16, 0xa5b: 0x4a1c, 0xa5c: 0x4a22, 0xa5d: 0x4a28,
- 0xa5e: 0x4a2e, 0xa5f: 0x4a34, 0xa60: 0x4a3a, 0xa61: 0x4a40, 0xa62: 0x4a46, 0xa63: 0x4a4c,
- 0xa64: 0x03c6, 0xa65: 0x0362, 0xa66: 0x0366, 0xa67: 0x03ea, 0xa68: 0x03ee, 0xa69: 0x03f2,
- 0xa6a: 0x03f6, 0xa6b: 0x03fa, 0xa6c: 0x03fe, 0xa6d: 0x0402, 0xa6e: 0x036e, 0xa6f: 0x0406,
- 0xa70: 0x040a, 0xa71: 0x0372, 0xa72: 0x0376, 0xa73: 0x037a, 0xa74: 0x0382, 0xa75: 0x0386,
- 0xa76: 0x038a, 0xa77: 0x038e, 0xa78: 0x0392, 0xa79: 0x0396, 0xa7a: 0x039a, 0xa7b: 0x039e,
- 0xa7c: 0x03a2, 0xa7d: 0x03a6, 0xa7e: 0x03aa, 0xa7f: 0x03ae,
- // Block 0x2a, offset 0xa80
- 0xa80: 0x03b2, 0xa81: 0x03b6, 0xa82: 0x040e, 0xa83: 0x0412, 0xa84: 0x03ba, 0xa85: 0x03be,
- 0xa86: 0x03c2, 0xa87: 0x03ca, 0xa88: 0x03ce, 0xa89: 0x03d2, 0xa8a: 0x03d6, 0xa8b: 0x03da,
- 0xa8c: 0x03de, 0xa8d: 0x03e2, 0xa8e: 0x03e6,
- 0xa92: 0x06c2, 0xa93: 0x071e, 0xa94: 0x06ce, 0xa95: 0x097e, 0xa96: 0x06d2, 0xa97: 0x06ea,
- 0xa98: 0x06d6, 0xa99: 0x0f96, 0xa9a: 0x070a, 0xa9b: 0x06de, 0xa9c: 0x06c6, 0xa9d: 0x0a02,
- 0xa9e: 0x0992, 0xa9f: 0x0732,
- // Block 0x2b, offset 0xac0
- 0xac0: 0x205a, 0xac1: 0x2060, 0xac2: 0x2066, 0xac3: 0x206c, 0xac4: 0x2072, 0xac5: 0x2078,
- 0xac6: 0x207e, 0xac7: 0x2084, 0xac8: 0x208a, 0xac9: 0x2090, 0xaca: 0x2096, 0xacb: 0x209c,
- 0xacc: 0x20a2, 0xacd: 0x20a8, 0xace: 0x2733, 0xacf: 0x273c, 0xad0: 0x2745, 0xad1: 0x274e,
- 0xad2: 0x2757, 0xad3: 0x2760, 0xad4: 0x2769, 0xad5: 0x2772, 0xad6: 0x277b, 0xad7: 0x278d,
- 0xad8: 0x2796, 0xad9: 0x279f, 0xada: 0x27a8, 0xadb: 0x27b1, 0xadc: 0x2784, 0xadd: 0x2bb9,
- 0xade: 0x2afa, 0xae0: 0x20ae, 0xae1: 0x20c6, 0xae2: 0x20ba, 0xae3: 0x210e,
- 0xae4: 0x20cc, 0xae5: 0x20ea, 0xae6: 0x20b4, 0xae7: 0x20e4, 0xae8: 0x20c0, 0xae9: 0x20f6,
- 0xaea: 0x2126, 0xaeb: 0x2144, 0xaec: 0x213e, 0xaed: 0x2132, 0xaee: 0x2180, 0xaef: 0x2114,
- 0xaf0: 0x2120, 0xaf1: 0x2138, 0xaf2: 0x212c, 0xaf3: 0x2156, 0xaf4: 0x2102, 0xaf5: 0x214a,
- 0xaf6: 0x2174, 0xaf7: 0x215c, 0xaf8: 0x20f0, 0xaf9: 0x20d2, 0xafa: 0x2108, 0xafb: 0x211a,
- 0xafc: 0x2150, 0xafd: 0x20d8, 0xafe: 0x217a, 0xaff: 0x20fc,
- // Block 0x2c, offset 0xb00
- 0xb00: 0x2162, 0xb01: 0x20de, 0xb02: 0x2168, 0xb03: 0x216e, 0xb04: 0x0932, 0xb05: 0x0b06,
- 0xb06: 0x0caa, 0xb07: 0x10ca,
- 0xb10: 0x1bca, 0xb11: 0x18ac,
- 0xb12: 0x18af, 0xb13: 0x18b2, 0xb14: 0x18b5, 0xb15: 0x18b8, 0xb16: 0x18bb, 0xb17: 0x18be,
- 0xb18: 0x18c1, 0xb19: 0x18c4, 0xb1a: 0x18cd, 0xb1b: 0x18d0, 0xb1c: 0x18d3, 0xb1d: 0x18d6,
- 0xb1e: 0x18d9, 0xb1f: 0x18dc, 0xb20: 0x0316, 0xb21: 0x031e, 0xb22: 0x0322, 0xb23: 0x032a,
- 0xb24: 0x032e, 0xb25: 0x0332, 0xb26: 0x033a, 0xb27: 0x0342, 0xb28: 0x0346, 0xb29: 0x034e,
- 0xb2a: 0x0352, 0xb2b: 0x0356, 0xb2c: 0x035a, 0xb2d: 0x035e, 0xb2e: 0x2e2f, 0xb2f: 0x2e37,
- 0xb30: 0x2e3f, 0xb31: 0x2e47, 0xb32: 0x2e4f, 0xb33: 0x2e57, 0xb34: 0x2e5f, 0xb35: 0x2e67,
- 0xb36: 0x2e77, 0xb37: 0x2e7f, 0xb38: 0x2e87, 0xb39: 0x2e8f, 0xb3a: 0x2e97, 0xb3b: 0x2e9f,
- 0xb3c: 0x2eea, 0xb3d: 0x2eb2, 0xb3e: 0x2e6f,
- // Block 0x2d, offset 0xb40
- 0xb40: 0x06c2, 0xb41: 0x071e, 0xb42: 0x06ce, 0xb43: 0x097e, 0xb44: 0x0722, 0xb45: 0x07b2,
- 0xb46: 0x06ca, 0xb47: 0x07ae, 0xb48: 0x070e, 0xb49: 0x088a, 0xb4a: 0x0d0a, 0xb4b: 0x0e92,
- 0xb4c: 0x0dda, 0xb4d: 0x0d1e, 0xb4e: 0x1462, 0xb4f: 0x098e, 0xb50: 0x0cd2, 0xb51: 0x0d4e,
- 0xb52: 0x0d0e, 0xb53: 0x104e, 0xb54: 0x08fe, 0xb55: 0x0f06, 0xb56: 0x138a, 0xb57: 0x1062,
- 0xb58: 0x0846, 0xb59: 0x1092, 0xb5a: 0x0f9e, 0xb5b: 0x0a1a, 0xb5c: 0x1412, 0xb5d: 0x0782,
- 0xb5e: 0x08ae, 0xb5f: 0x0dfa, 0xb60: 0x152a, 0xb61: 0x0746, 0xb62: 0x07d6, 0xb63: 0x0d9e,
- 0xb64: 0x06d2, 0xb65: 0x06ea, 0xb66: 0x06d6, 0xb67: 0x0ade, 0xb68: 0x08f2, 0xb69: 0x0882,
- 0xb6a: 0x0a5a, 0xb6b: 0x0a4e, 0xb6c: 0x0fee, 0xb6d: 0x0742, 0xb6e: 0x139e, 0xb6f: 0x089e,
- 0xb70: 0x09f6, 0xb71: 0x18df, 0xb72: 0x18e2, 0xb73: 0x18e5, 0xb74: 0x18e8, 0xb75: 0x18f1,
- 0xb76: 0x18f4, 0xb77: 0x18f7, 0xb78: 0x18fa, 0xb79: 0x18fd, 0xb7a: 0x1900, 0xb7b: 0x1903,
- 0xb7c: 0x1906, 0xb7d: 0x1909, 0xb7e: 0x190c, 0xb7f: 0x1915,
- // Block 0x2e, offset 0xb80
- 0xb80: 0x1ccc, 0xb81: 0x1cdb, 0xb82: 0x1cea, 0xb83: 0x1cf9, 0xb84: 0x1d08, 0xb85: 0x1d17,
- 0xb86: 0x1d26, 0xb87: 0x1d35, 0xb88: 0x1d44, 0xb89: 0x2192, 0xb8a: 0x21a4, 0xb8b: 0x21b6,
- 0xb8c: 0x1957, 0xb8d: 0x1c0a, 0xb8e: 0x19d8, 0xb8f: 0x1bae, 0xb90: 0x04ce, 0xb91: 0x04d6,
- 0xb92: 0x04de, 0xb93: 0x04e6, 0xb94: 0x04ee, 0xb95: 0x04f2, 0xb96: 0x04f6, 0xb97: 0x04fa,
- 0xb98: 0x04fe, 0xb99: 0x0502, 0xb9a: 0x0506, 0xb9b: 0x050a, 0xb9c: 0x050e, 0xb9d: 0x0512,
- 0xb9e: 0x0516, 0xb9f: 0x051a, 0xba0: 0x051e, 0xba1: 0x0526, 0xba2: 0x052a, 0xba3: 0x052e,
- 0xba4: 0x0532, 0xba5: 0x0536, 0xba6: 0x053a, 0xba7: 0x053e, 0xba8: 0x0542, 0xba9: 0x0546,
- 0xbaa: 0x054a, 0xbab: 0x054e, 0xbac: 0x0552, 0xbad: 0x0556, 0xbae: 0x055a, 0xbaf: 0x055e,
- 0xbb0: 0x0562, 0xbb1: 0x0566, 0xbb2: 0x056a, 0xbb3: 0x0572, 0xbb4: 0x057a, 0xbb5: 0x0582,
- 0xbb6: 0x0586, 0xbb7: 0x058a, 0xbb8: 0x058e, 0xbb9: 0x0592, 0xbba: 0x0596, 0xbbb: 0x059a,
- 0xbbc: 0x059e, 0xbbd: 0x05a2, 0xbbe: 0x05a6, 0xbbf: 0x2700,
- // Block 0x2f, offset 0xbc0
- 0xbc0: 0x2b19, 0xbc1: 0x29b5, 0xbc2: 0x2b29, 0xbc3: 0x288d, 0xbc4: 0x2efb, 0xbc5: 0x2897,
- 0xbc6: 0x28a1, 0xbc7: 0x2f3f, 0xbc8: 0x29c2, 0xbc9: 0x28ab, 0xbca: 0x28b5, 0xbcb: 0x28bf,
- 0xbcc: 0x29e9, 0xbcd: 0x29f6, 0xbce: 0x29cf, 0xbcf: 0x29dc, 0xbd0: 0x2ec0, 0xbd1: 0x2a03,
- 0xbd2: 0x2a10, 0xbd3: 0x2bcb, 0xbd4: 0x26c1, 0xbd5: 0x2bde, 0xbd6: 0x2bf1, 0xbd7: 0x2b39,
- 0xbd8: 0x2a1d, 0xbd9: 0x2c04, 0xbda: 0x2c17, 0xbdb: 0x2a2a, 0xbdc: 0x28c9, 0xbdd: 0x28d3,
- 0xbde: 0x2ece, 0xbdf: 0x2a37, 0xbe0: 0x2b49, 0xbe1: 0x2f0c, 0xbe2: 0x28dd, 0xbe3: 0x28e7,
- 0xbe4: 0x2a44, 0xbe5: 0x28f1, 0xbe6: 0x28fb, 0xbe7: 0x26d6, 0xbe8: 0x26dd, 0xbe9: 0x2905,
- 0xbea: 0x290f, 0xbeb: 0x2c2a, 0xbec: 0x2a51, 0xbed: 0x2b59, 0xbee: 0x2c3d, 0xbef: 0x2a5e,
- 0xbf0: 0x2923, 0xbf1: 0x2919, 0xbf2: 0x2f53, 0xbf3: 0x2a6b, 0xbf4: 0x2c50, 0xbf5: 0x292d,
- 0xbf6: 0x2b69, 0xbf7: 0x2937, 0xbf8: 0x2a85, 0xbf9: 0x2941, 0xbfa: 0x2a92, 0xbfb: 0x2f1d,
- 0xbfc: 0x2a78, 0xbfd: 0x2b79, 0xbfe: 0x2a9f, 0xbff: 0x26e4,
- // Block 0x30, offset 0xc00
- 0xc00: 0x2f2e, 0xc01: 0x294b, 0xc02: 0x2955, 0xc03: 0x2aac, 0xc04: 0x295f, 0xc05: 0x2969,
- 0xc06: 0x2973, 0xc07: 0x2b89, 0xc08: 0x2ab9, 0xc09: 0x26eb, 0xc0a: 0x2c63, 0xc0b: 0x2ea7,
- 0xc0c: 0x2b99, 0xc0d: 0x2ac6, 0xc0e: 0x2edc, 0xc0f: 0x297d, 0xc10: 0x2987, 0xc11: 0x2ad3,
- 0xc12: 0x26f2, 0xc13: 0x2ae0, 0xc14: 0x2ba9, 0xc15: 0x26f9, 0xc16: 0x2c76, 0xc17: 0x2991,
- 0xc18: 0x1cbd, 0xc19: 0x1cd1, 0xc1a: 0x1ce0, 0xc1b: 0x1cef, 0xc1c: 0x1cfe, 0xc1d: 0x1d0d,
- 0xc1e: 0x1d1c, 0xc1f: 0x1d2b, 0xc20: 0x1d3a, 0xc21: 0x1d49, 0xc22: 0x2198, 0xc23: 0x21aa,
- 0xc24: 0x21bc, 0xc25: 0x21c8, 0xc26: 0x21d4, 0xc27: 0x21e0, 0xc28: 0x21ec, 0xc29: 0x21f8,
- 0xc2a: 0x2204, 0xc2b: 0x2210, 0xc2c: 0x224c, 0xc2d: 0x2258, 0xc2e: 0x2264, 0xc2f: 0x2270,
- 0xc30: 0x227c, 0xc31: 0x1c1a, 0xc32: 0x19cc, 0xc33: 0x1939, 0xc34: 0x1bea, 0xc35: 0x1a4d,
- 0xc36: 0x1a5c, 0xc37: 0x19d2, 0xc38: 0x1c02, 0xc39: 0x1c06, 0xc3a: 0x1963, 0xc3b: 0x270e,
- 0xc3c: 0x271c, 0xc3d: 0x2707, 0xc3e: 0x2715, 0xc3f: 0x2aed,
- // Block 0x31, offset 0xc40
- 0xc40: 0x1a50, 0xc41: 0x1a38, 0xc42: 0x1c66, 0xc43: 0x1a20, 0xc44: 0x19f9, 0xc45: 0x196c,
- 0xc46: 0x197b, 0xc47: 0x194b, 0xc48: 0x1bf6, 0xc49: 0x1d58, 0xc4a: 0x1a53, 0xc4b: 0x1a3b,
- 0xc4c: 0x1c6a, 0xc4d: 0x1c76, 0xc4e: 0x1a2c, 0xc4f: 0x1a02, 0xc50: 0x195a, 0xc51: 0x1c22,
- 0xc52: 0x1bb6, 0xc53: 0x1ba2, 0xc54: 0x1bd2, 0xc55: 0x1c7a, 0xc56: 0x1a2f, 0xc57: 0x19cf,
- 0xc58: 0x1a05, 0xc59: 0x19e4, 0xc5a: 0x1a47, 0xc5b: 0x1c7e, 0xc5c: 0x1a32, 0xc5d: 0x19c6,
- 0xc5e: 0x1a08, 0xc5f: 0x1c42, 0xc60: 0x1bfa, 0xc61: 0x1a1a, 0xc62: 0x1c2a, 0xc63: 0x1c46,
- 0xc64: 0x1bfe, 0xc65: 0x1a1d, 0xc66: 0x1c2e, 0xc67: 0x22ee, 0xc68: 0x2302, 0xc69: 0x199c,
- 0xc6a: 0x1c26, 0xc6b: 0x1bba, 0xc6c: 0x1ba6, 0xc6d: 0x1c4e, 0xc6e: 0x2723, 0xc6f: 0x27ba,
- 0xc70: 0x1a5f, 0xc71: 0x1a4a, 0xc72: 0x1c82, 0xc73: 0x1a35, 0xc74: 0x1a56, 0xc75: 0x1a3e,
- 0xc76: 0x1c6e, 0xc77: 0x1a23, 0xc78: 0x19fc, 0xc79: 0x1987, 0xc7a: 0x1a59, 0xc7b: 0x1a41,
- 0xc7c: 0x1c72, 0xc7d: 0x1a26, 0xc7e: 0x19ff, 0xc7f: 0x198a,
- // Block 0x32, offset 0xc80
- 0xc80: 0x1c32, 0xc81: 0x1bbe, 0xc82: 0x1d53, 0xc83: 0x193c, 0xc84: 0x19c0, 0xc85: 0x19c3,
- 0xc86: 0x22fb, 0xc87: 0x1b9a, 0xc88: 0x19c9, 0xc89: 0x194e, 0xc8a: 0x19e7, 0xc8b: 0x1951,
- 0xc8c: 0x19f0, 0xc8d: 0x196f, 0xc8e: 0x1972, 0xc8f: 0x1a0b, 0xc90: 0x1a11, 0xc91: 0x1a14,
- 0xc92: 0x1c36, 0xc93: 0x1a17, 0xc94: 0x1a29, 0xc95: 0x1c3e, 0xc96: 0x1c4a, 0xc97: 0x1996,
- 0xc98: 0x1d5d, 0xc99: 0x1bc2, 0xc9a: 0x1999, 0xc9b: 0x1a62, 0xc9c: 0x19ab, 0xc9d: 0x19ba,
- 0xc9e: 0x22e8, 0xc9f: 0x22e2, 0xca0: 0x1cc7, 0xca1: 0x1cd6, 0xca2: 0x1ce5, 0xca3: 0x1cf4,
- 0xca4: 0x1d03, 0xca5: 0x1d12, 0xca6: 0x1d21, 0xca7: 0x1d30, 0xca8: 0x1d3f, 0xca9: 0x218c,
- 0xcaa: 0x219e, 0xcab: 0x21b0, 0xcac: 0x21c2, 0xcad: 0x21ce, 0xcae: 0x21da, 0xcaf: 0x21e6,
- 0xcb0: 0x21f2, 0xcb1: 0x21fe, 0xcb2: 0x220a, 0xcb3: 0x2246, 0xcb4: 0x2252, 0xcb5: 0x225e,
- 0xcb6: 0x226a, 0xcb7: 0x2276, 0xcb8: 0x2282, 0xcb9: 0x2288, 0xcba: 0x228e, 0xcbb: 0x2294,
- 0xcbc: 0x229a, 0xcbd: 0x22ac, 0xcbe: 0x22b2, 0xcbf: 0x1c16,
- // Block 0x33, offset 0xcc0
- 0xcc0: 0x137a, 0xcc1: 0x0cfe, 0xcc2: 0x13d6, 0xcc3: 0x13a2, 0xcc4: 0x0e5a, 0xcc5: 0x06ee,
- 0xcc6: 0x08e2, 0xcc7: 0x162e, 0xcc8: 0x162e, 0xcc9: 0x0a0e, 0xcca: 0x1462, 0xccb: 0x0946,
- 0xccc: 0x0a0a, 0xccd: 0x0bf2, 0xcce: 0x0fd2, 0xccf: 0x1162, 0xcd0: 0x129a, 0xcd1: 0x12d6,
- 0xcd2: 0x130a, 0xcd3: 0x141e, 0xcd4: 0x0d76, 0xcd5: 0x0e02, 0xcd6: 0x0eae, 0xcd7: 0x0f46,
- 0xcd8: 0x1262, 0xcd9: 0x144a, 0xcda: 0x1576, 0xcdb: 0x0712, 0xcdc: 0x08b6, 0xcdd: 0x0d8a,
- 0xcde: 0x0ed2, 0xcdf: 0x1296, 0xce0: 0x15c6, 0xce1: 0x0ab6, 0xce2: 0x0e7a, 0xce3: 0x1286,
- 0xce4: 0x131a, 0xce5: 0x0c26, 0xce6: 0x11be, 0xce7: 0x12e2, 0xce8: 0x0b22, 0xce9: 0x0d12,
- 0xcea: 0x0e1a, 0xceb: 0x0f1e, 0xcec: 0x142a, 0xced: 0x0752, 0xcee: 0x07ea, 0xcef: 0x0856,
- 0xcf0: 0x0c8e, 0xcf1: 0x0d82, 0xcf2: 0x0ece, 0xcf3: 0x0ff2, 0xcf4: 0x117a, 0xcf5: 0x128e,
- 0xcf6: 0x12a6, 0xcf7: 0x13ca, 0xcf8: 0x14f2, 0xcf9: 0x15a6, 0xcfa: 0x15c2, 0xcfb: 0x102e,
- 0xcfc: 0x106e, 0xcfd: 0x1126, 0xcfe: 0x1246, 0xcff: 0x147e,
- // Block 0x34, offset 0xd00
- 0xd00: 0x15ce, 0xd01: 0x134e, 0xd02: 0x09ca, 0xd03: 0x0b3e, 0xd04: 0x10de, 0xd05: 0x119e,
- 0xd06: 0x0f02, 0xd07: 0x1036, 0xd08: 0x139a, 0xd09: 0x14ea, 0xd0a: 0x09c6, 0xd0b: 0x0a92,
- 0xd0c: 0x0d7a, 0xd0d: 0x0e2e, 0xd0e: 0x0e62, 0xd0f: 0x1116, 0xd10: 0x113e, 0xd11: 0x14aa,
- 0xd12: 0x0852, 0xd13: 0x11aa, 0xd14: 0x07f6, 0xd15: 0x07f2, 0xd16: 0x109a, 0xd17: 0x112a,
- 0xd18: 0x125e, 0xd19: 0x14b2, 0xd1a: 0x136a, 0xd1b: 0x0c2a, 0xd1c: 0x0d76, 0xd1d: 0x135a,
- 0xd1e: 0x06fa, 0xd1f: 0x0a66, 0xd20: 0x0b96, 0xd21: 0x0f32, 0xd22: 0x0fb2, 0xd23: 0x0876,
- 0xd24: 0x103e, 0xd25: 0x0762, 0xd26: 0x0b7a, 0xd27: 0x06da, 0xd28: 0x0dee, 0xd29: 0x0ca6,
- 0xd2a: 0x1112, 0xd2b: 0x08ca, 0xd2c: 0x09b6, 0xd2d: 0x0ffe, 0xd2e: 0x1266, 0xd2f: 0x133e,
- 0xd30: 0x0dba, 0xd31: 0x13fa, 0xd32: 0x0de6, 0xd33: 0x0c3a, 0xd34: 0x121e, 0xd35: 0x0c5a,
- 0xd36: 0x0fae, 0xd37: 0x072e, 0xd38: 0x07aa, 0xd39: 0x07ee, 0xd3a: 0x0d56, 0xd3b: 0x10fe,
- 0xd3c: 0x11f6, 0xd3d: 0x134a, 0xd3e: 0x145e, 0xd3f: 0x085e,
- // Block 0x35, offset 0xd40
- 0xd40: 0x0912, 0xd41: 0x0a1a, 0xd42: 0x0b32, 0xd43: 0x0cc2, 0xd44: 0x0e7e, 0xd45: 0x1042,
- 0xd46: 0x149a, 0xd47: 0x157e, 0xd48: 0x15d2, 0xd49: 0x15ea, 0xd4a: 0x083a, 0xd4b: 0x0cf6,
- 0xd4c: 0x0da6, 0xd4d: 0x13ee, 0xd4e: 0x0afe, 0xd4f: 0x0bda, 0xd50: 0x0bf6, 0xd51: 0x0c86,
- 0xd52: 0x0e6e, 0xd53: 0x0eba, 0xd54: 0x0f6a, 0xd55: 0x108e, 0xd56: 0x1132, 0xd57: 0x1196,
- 0xd58: 0x13de, 0xd59: 0x126e, 0xd5a: 0x1406, 0xd5b: 0x1482, 0xd5c: 0x0812, 0xd5d: 0x083e,
- 0xd5e: 0x0926, 0xd5f: 0x0eaa, 0xd60: 0x12f6, 0xd61: 0x133e, 0xd62: 0x0b1e, 0xd63: 0x0b8e,
- 0xd64: 0x0c52, 0xd65: 0x0db2, 0xd66: 0x10da, 0xd67: 0x0f26, 0xd68: 0x073e, 0xd69: 0x0982,
- 0xd6a: 0x0a66, 0xd6b: 0x0aca, 0xd6c: 0x0b9a, 0xd6d: 0x0f42, 0xd6e: 0x0f5e, 0xd6f: 0x116e,
- 0xd70: 0x118e, 0xd71: 0x1466, 0xd72: 0x14e6, 0xd73: 0x14f6, 0xd74: 0x1532, 0xd75: 0x0756,
- 0xd76: 0x1082, 0xd77: 0x1452, 0xd78: 0x14ce, 0xd79: 0x0bb2, 0xd7a: 0x071a, 0xd7b: 0x077a,
- 0xd7c: 0x0a6a, 0xd7d: 0x0a8a, 0xd7e: 0x0cb2, 0xd7f: 0x0d76,
- // Block 0x36, offset 0xd80
- 0xd80: 0x0ec6, 0xd81: 0x0fce, 0xd82: 0x127a, 0xd83: 0x141a, 0xd84: 0x1626, 0xd85: 0x0ce6,
- 0xd86: 0x14a6, 0xd87: 0x0836, 0xd88: 0x0d32, 0xd89: 0x0d3e, 0xd8a: 0x0e12, 0xd8b: 0x0e4a,
- 0xd8c: 0x0f4e, 0xd8d: 0x0faa, 0xd8e: 0x102a, 0xd8f: 0x110e, 0xd90: 0x153e, 0xd91: 0x07b2,
- 0xd92: 0x0c06, 0xd93: 0x14b6, 0xd94: 0x076a, 0xd95: 0x0aae, 0xd96: 0x0e32, 0xd97: 0x13e2,
- 0xd98: 0x0b6a, 0xd99: 0x0bba, 0xd9a: 0x0d46, 0xd9b: 0x0f32, 0xd9c: 0x14be, 0xd9d: 0x081a,
- 0xd9e: 0x0902, 0xd9f: 0x0a9a, 0xda0: 0x0cd6, 0xda1: 0x0d22, 0xda2: 0x0d62, 0xda3: 0x0df6,
- 0xda4: 0x0f4a, 0xda5: 0x0fbe, 0xda6: 0x115a, 0xda7: 0x12fa, 0xda8: 0x1306, 0xda9: 0x145a,
- 0xdaa: 0x14da, 0xdab: 0x0886, 0xdac: 0x0e4e, 0xdad: 0x0906, 0xdae: 0x0eca, 0xdaf: 0x0f6e,
- 0xdb0: 0x128a, 0xdb1: 0x14c2, 0xdb2: 0x15ae, 0xdb3: 0x15d6, 0xdb4: 0x0d3a, 0xdb5: 0x0e2a,
- 0xdb6: 0x11c6, 0xdb7: 0x10ba, 0xdb8: 0x10c6, 0xdb9: 0x10ea, 0xdba: 0x0f1a, 0xdbb: 0x0ea2,
- 0xdbc: 0x1366, 0xdbd: 0x0736, 0xdbe: 0x122e, 0xdbf: 0x081e,
- // Block 0x37, offset 0xdc0
- 0xdc0: 0x080e, 0xdc1: 0x0b0e, 0xdc2: 0x0c2e, 0xdc3: 0x10f6, 0xdc4: 0x0a56, 0xdc5: 0x0e06,
- 0xdc6: 0x0cf2, 0xdc7: 0x13ea, 0xdc8: 0x12ea, 0xdc9: 0x14ae, 0xdca: 0x1326, 0xdcb: 0x0b2a,
- 0xdcc: 0x078a, 0xdcd: 0x095e, 0xdd0: 0x09b2,
- 0xdd2: 0x0ce2, 0xdd5: 0x07fa, 0xdd6: 0x0f22, 0xdd7: 0x0fe6,
- 0xdd8: 0x104a, 0xdd9: 0x1066, 0xdda: 0x106a, 0xddb: 0x107e, 0xddc: 0x14fe, 0xddd: 0x10ee,
- 0xdde: 0x1172, 0xde0: 0x1292, 0xde2: 0x1356,
- 0xde5: 0x140a, 0xde6: 0x1436,
- 0xdea: 0x1552, 0xdeb: 0x1556, 0xdec: 0x155a, 0xded: 0x15be, 0xdee: 0x142e, 0xdef: 0x14ca,
- 0xdf0: 0x075a, 0xdf1: 0x077e, 0xdf2: 0x0792, 0xdf3: 0x084e, 0xdf4: 0x085a, 0xdf5: 0x089a,
- 0xdf6: 0x094e, 0xdf7: 0x096a, 0xdf8: 0x0972, 0xdf9: 0x09ae, 0xdfa: 0x09ba, 0xdfb: 0x0a96,
- 0xdfc: 0x0a9e, 0xdfd: 0x0ba6, 0xdfe: 0x0bce, 0xdff: 0x0bd6,
- // Block 0x38, offset 0xe00
- 0xe00: 0x0bee, 0xe01: 0x0c9a, 0xe02: 0x0cca, 0xe03: 0x0cea, 0xe04: 0x0d5a, 0xe05: 0x0e1e,
- 0xe06: 0x0e3a, 0xe07: 0x0e6a, 0xe08: 0x0ebe, 0xe09: 0x0ede, 0xe0a: 0x0f52, 0xe0b: 0x1032,
- 0xe0c: 0x104e, 0xe0d: 0x1056, 0xe0e: 0x1052, 0xe0f: 0x105a, 0xe10: 0x105e, 0xe11: 0x1062,
- 0xe12: 0x1076, 0xe13: 0x107a, 0xe14: 0x109e, 0xe15: 0x10b2, 0xe16: 0x10ce, 0xe17: 0x1132,
- 0xe18: 0x113a, 0xe19: 0x1142, 0xe1a: 0x1156, 0xe1b: 0x117e, 0xe1c: 0x11ce, 0xe1d: 0x1202,
- 0xe1e: 0x1202, 0xe1f: 0x126a, 0xe20: 0x1312, 0xe21: 0x132a, 0xe22: 0x135e, 0xe23: 0x1362,
- 0xe24: 0x13a6, 0xe25: 0x13aa, 0xe26: 0x1402, 0xe27: 0x140a, 0xe28: 0x14de, 0xe29: 0x1522,
- 0xe2a: 0x153a, 0xe2b: 0x0b9e, 0xe2c: 0x1721, 0xe2d: 0x11e6,
- 0xe30: 0x06e2, 0xe31: 0x07e6, 0xe32: 0x07a6, 0xe33: 0x074e, 0xe34: 0x078e, 0xe35: 0x07ba,
- 0xe36: 0x084a, 0xe37: 0x0866, 0xe38: 0x094e, 0xe39: 0x093a, 0xe3a: 0x094a, 0xe3b: 0x0966,
- 0xe3c: 0x09b2, 0xe3d: 0x09c2, 0xe3e: 0x0a06, 0xe3f: 0x0a12,
- // Block 0x39, offset 0xe40
- 0xe40: 0x0a2e, 0xe41: 0x0a3e, 0xe42: 0x0b26, 0xe43: 0x0b2e, 0xe44: 0x0b5e, 0xe45: 0x0b7e,
- 0xe46: 0x0bae, 0xe47: 0x0bc6, 0xe48: 0x0bb6, 0xe49: 0x0bd6, 0xe4a: 0x0bca, 0xe4b: 0x0bee,
- 0xe4c: 0x0c0a, 0xe4d: 0x0c62, 0xe4e: 0x0c6e, 0xe4f: 0x0c76, 0xe50: 0x0c9e, 0xe51: 0x0ce2,
- 0xe52: 0x0d12, 0xe53: 0x0d16, 0xe54: 0x0d2a, 0xe55: 0x0daa, 0xe56: 0x0dba, 0xe57: 0x0e12,
- 0xe58: 0x0e5e, 0xe59: 0x0e56, 0xe5a: 0x0e6a, 0xe5b: 0x0e86, 0xe5c: 0x0ebe, 0xe5d: 0x1016,
- 0xe5e: 0x0ee2, 0xe5f: 0x0f16, 0xe60: 0x0f22, 0xe61: 0x0f62, 0xe62: 0x0f7e, 0xe63: 0x0fa2,
- 0xe64: 0x0fc6, 0xe65: 0x0fca, 0xe66: 0x0fe6, 0xe67: 0x0fea, 0xe68: 0x0ffa, 0xe69: 0x100e,
- 0xe6a: 0x100a, 0xe6b: 0x103a, 0xe6c: 0x10b6, 0xe6d: 0x10ce, 0xe6e: 0x10e6, 0xe6f: 0x111e,
- 0xe70: 0x1132, 0xe71: 0x114e, 0xe72: 0x117e, 0xe73: 0x1232, 0xe74: 0x125a, 0xe75: 0x12ce,
- 0xe76: 0x1316, 0xe77: 0x1322, 0xe78: 0x132a, 0xe79: 0x1342, 0xe7a: 0x1356, 0xe7b: 0x1346,
- 0xe7c: 0x135e, 0xe7d: 0x135a, 0xe7e: 0x1352, 0xe7f: 0x1362,
- // Block 0x3a, offset 0xe80
- 0xe80: 0x136e, 0xe81: 0x13aa, 0xe82: 0x13e6, 0xe83: 0x1416, 0xe84: 0x144e, 0xe85: 0x146e,
- 0xe86: 0x14ba, 0xe87: 0x14de, 0xe88: 0x14fe, 0xe89: 0x1512, 0xe8a: 0x1522, 0xe8b: 0x152e,
- 0xe8c: 0x153a, 0xe8d: 0x158e, 0xe8e: 0x162e, 0xe8f: 0x16b8, 0xe90: 0x16b3, 0xe91: 0x16e5,
- 0xe92: 0x060a, 0xe93: 0x0632, 0xe94: 0x0636, 0xe95: 0x1767, 0xe96: 0x1794, 0xe97: 0x180c,
- 0xe98: 0x161a, 0xe99: 0x162a,
- // Block 0x3b, offset 0xec0
- 0xec0: 0x19db, 0xec1: 0x19de, 0xec2: 0x19e1, 0xec3: 0x1c0e, 0xec4: 0x1c12, 0xec5: 0x1a65,
- 0xec6: 0x1a65,
- 0xed3: 0x1d7b, 0xed4: 0x1d6c, 0xed5: 0x1d71, 0xed6: 0x1d80, 0xed7: 0x1d76,
- 0xedd: 0x43a7,
- 0xede: 0x8116, 0xedf: 0x4419, 0xee0: 0x0230, 0xee1: 0x0218, 0xee2: 0x0221, 0xee3: 0x0224,
- 0xee4: 0x0227, 0xee5: 0x022a, 0xee6: 0x022d, 0xee7: 0x0233, 0xee8: 0x0236, 0xee9: 0x0017,
- 0xeea: 0x4407, 0xeeb: 0x440d, 0xeec: 0x450b, 0xeed: 0x4513, 0xeee: 0x435f, 0xeef: 0x4365,
- 0xef0: 0x436b, 0xef1: 0x4371, 0xef2: 0x437d, 0xef3: 0x4383, 0xef4: 0x4389, 0xef5: 0x4395,
- 0xef6: 0x439b, 0xef8: 0x43a1, 0xef9: 0x43ad, 0xefa: 0x43b3, 0xefb: 0x43b9,
- 0xefc: 0x43c5, 0xefe: 0x43cb,
- // Block 0x3c, offset 0xf00
- 0xf00: 0x43d1, 0xf01: 0x43d7, 0xf03: 0x43dd, 0xf04: 0x43e3,
- 0xf06: 0x43ef, 0xf07: 0x43f5, 0xf08: 0x43fb, 0xf09: 0x4401, 0xf0a: 0x4413, 0xf0b: 0x438f,
- 0xf0c: 0x4377, 0xf0d: 0x43bf, 0xf0e: 0x43e9, 0xf0f: 0x1d85, 0xf10: 0x029c, 0xf11: 0x029c,
- 0xf12: 0x02a5, 0xf13: 0x02a5, 0xf14: 0x02a5, 0xf15: 0x02a5, 0xf16: 0x02a8, 0xf17: 0x02a8,
- 0xf18: 0x02a8, 0xf19: 0x02a8, 0xf1a: 0x02ae, 0xf1b: 0x02ae, 0xf1c: 0x02ae, 0xf1d: 0x02ae,
- 0xf1e: 0x02a2, 0xf1f: 0x02a2, 0xf20: 0x02a2, 0xf21: 0x02a2, 0xf22: 0x02ab, 0xf23: 0x02ab,
- 0xf24: 0x02ab, 0xf25: 0x02ab, 0xf26: 0x029f, 0xf27: 0x029f, 0xf28: 0x029f, 0xf29: 0x029f,
- 0xf2a: 0x02d2, 0xf2b: 0x02d2, 0xf2c: 0x02d2, 0xf2d: 0x02d2, 0xf2e: 0x02d5, 0xf2f: 0x02d5,
- 0xf30: 0x02d5, 0xf31: 0x02d5, 0xf32: 0x02b4, 0xf33: 0x02b4, 0xf34: 0x02b4, 0xf35: 0x02b4,
- 0xf36: 0x02b1, 0xf37: 0x02b1, 0xf38: 0x02b1, 0xf39: 0x02b1, 0xf3a: 0x02b7, 0xf3b: 0x02b7,
- 0xf3c: 0x02b7, 0xf3d: 0x02b7, 0xf3e: 0x02ba, 0xf3f: 0x02ba,
- // Block 0x3d, offset 0xf40
- 0xf40: 0x02ba, 0xf41: 0x02ba, 0xf42: 0x02c3, 0xf43: 0x02c3, 0xf44: 0x02c0, 0xf45: 0x02c0,
- 0xf46: 0x02c6, 0xf47: 0x02c6, 0xf48: 0x02bd, 0xf49: 0x02bd, 0xf4a: 0x02cc, 0xf4b: 0x02cc,
- 0xf4c: 0x02c9, 0xf4d: 0x02c9, 0xf4e: 0x02d8, 0xf4f: 0x02d8, 0xf50: 0x02d8, 0xf51: 0x02d8,
- 0xf52: 0x02de, 0xf53: 0x02de, 0xf54: 0x02de, 0xf55: 0x02de, 0xf56: 0x02e4, 0xf57: 0x02e4,
- 0xf58: 0x02e4, 0xf59: 0x02e4, 0xf5a: 0x02e1, 0xf5b: 0x02e1, 0xf5c: 0x02e1, 0xf5d: 0x02e1,
- 0xf5e: 0x02e7, 0xf5f: 0x02e7, 0xf60: 0x02ea, 0xf61: 0x02ea, 0xf62: 0x02ea, 0xf63: 0x02ea,
- 0xf64: 0x4485, 0xf65: 0x4485, 0xf66: 0x02f0, 0xf67: 0x02f0, 0xf68: 0x02f0, 0xf69: 0x02f0,
- 0xf6a: 0x02ed, 0xf6b: 0x02ed, 0xf6c: 0x02ed, 0xf6d: 0x02ed, 0xf6e: 0x030b, 0xf6f: 0x030b,
- 0xf70: 0x447f, 0xf71: 0x447f,
- // Block 0x3e, offset 0xf80
- 0xf93: 0x02db, 0xf94: 0x02db, 0xf95: 0x02db, 0xf96: 0x02db, 0xf97: 0x02f9,
- 0xf98: 0x02f9, 0xf99: 0x02f6, 0xf9a: 0x02f6, 0xf9b: 0x02fc, 0xf9c: 0x02fc, 0xf9d: 0x2055,
- 0xf9e: 0x0302, 0xf9f: 0x0302, 0xfa0: 0x02f3, 0xfa1: 0x02f3, 0xfa2: 0x02ff, 0xfa3: 0x02ff,
- 0xfa4: 0x0308, 0xfa5: 0x0308, 0xfa6: 0x0308, 0xfa7: 0x0308, 0xfa8: 0x0290, 0xfa9: 0x0290,
- 0xfaa: 0x25b0, 0xfab: 0x25b0, 0xfac: 0x2620, 0xfad: 0x2620, 0xfae: 0x25ef, 0xfaf: 0x25ef,
- 0xfb0: 0x260b, 0xfb1: 0x260b, 0xfb2: 0x2604, 0xfb3: 0x2604, 0xfb4: 0x2612, 0xfb5: 0x2612,
- 0xfb6: 0x2619, 0xfb7: 0x2619, 0xfb8: 0x2619, 0xfb9: 0x25f6, 0xfba: 0x25f6, 0xfbb: 0x25f6,
- 0xfbc: 0x0305, 0xfbd: 0x0305, 0xfbe: 0x0305, 0xfbf: 0x0305,
- // Block 0x3f, offset 0xfc0
- 0xfc0: 0x25b7, 0xfc1: 0x25be, 0xfc2: 0x25da, 0xfc3: 0x25f6, 0xfc4: 0x25fd, 0xfc5: 0x1d8f,
- 0xfc6: 0x1d94, 0xfc7: 0x1d99, 0xfc8: 0x1da8, 0xfc9: 0x1db7, 0xfca: 0x1dbc, 0xfcb: 0x1dc1,
- 0xfcc: 0x1dc6, 0xfcd: 0x1dcb, 0xfce: 0x1dda, 0xfcf: 0x1de9, 0xfd0: 0x1dee, 0xfd1: 0x1df3,
- 0xfd2: 0x1e02, 0xfd3: 0x1e11, 0xfd4: 0x1e16, 0xfd5: 0x1e1b, 0xfd6: 0x1e20, 0xfd7: 0x1e2f,
- 0xfd8: 0x1e34, 0xfd9: 0x1e43, 0xfda: 0x1e48, 0xfdb: 0x1e4d, 0xfdc: 0x1e5c, 0xfdd: 0x1e61,
- 0xfde: 0x1e66, 0xfdf: 0x1e70, 0xfe0: 0x1eac, 0xfe1: 0x1ebb, 0xfe2: 0x1eca, 0xfe3: 0x1ecf,
- 0xfe4: 0x1ed4, 0xfe5: 0x1ede, 0xfe6: 0x1eed, 0xfe7: 0x1ef2, 0xfe8: 0x1f01, 0xfe9: 0x1f06,
- 0xfea: 0x1f0b, 0xfeb: 0x1f1a, 0xfec: 0x1f1f, 0xfed: 0x1f2e, 0xfee: 0x1f33, 0xfef: 0x1f38,
- 0xff0: 0x1f3d, 0xff1: 0x1f42, 0xff2: 0x1f47, 0xff3: 0x1f4c, 0xff4: 0x1f51, 0xff5: 0x1f56,
- 0xff6: 0x1f5b, 0xff7: 0x1f60, 0xff8: 0x1f65, 0xff9: 0x1f6a, 0xffa: 0x1f6f, 0xffb: 0x1f74,
- 0xffc: 0x1f79, 0xffd: 0x1f7e, 0xffe: 0x1f83, 0xfff: 0x1f8d,
- // Block 0x40, offset 0x1000
- 0x1000: 0x1f92, 0x1001: 0x1f97, 0x1002: 0x1f9c, 0x1003: 0x1fa6, 0x1004: 0x1fab, 0x1005: 0x1fb5,
- 0x1006: 0x1fba, 0x1007: 0x1fbf, 0x1008: 0x1fc4, 0x1009: 0x1fc9, 0x100a: 0x1fce, 0x100b: 0x1fd3,
- 0x100c: 0x1fd8, 0x100d: 0x1fdd, 0x100e: 0x1fec, 0x100f: 0x1ffb, 0x1010: 0x2000, 0x1011: 0x2005,
- 0x1012: 0x200a, 0x1013: 0x200f, 0x1014: 0x2014, 0x1015: 0x201e, 0x1016: 0x2023, 0x1017: 0x2028,
- 0x1018: 0x2037, 0x1019: 0x2046, 0x101a: 0x204b, 0x101b: 0x4437, 0x101c: 0x443d, 0x101d: 0x4473,
- 0x101e: 0x44ca, 0x101f: 0x44d1, 0x1020: 0x44d8, 0x1021: 0x44df, 0x1022: 0x44e6, 0x1023: 0x44ed,
- 0x1024: 0x25cc, 0x1025: 0x25d3, 0x1026: 0x25da, 0x1027: 0x25e1, 0x1028: 0x25f6, 0x1029: 0x25fd,
- 0x102a: 0x1d9e, 0x102b: 0x1da3, 0x102c: 0x1da8, 0x102d: 0x1dad, 0x102e: 0x1db7, 0x102f: 0x1dbc,
- 0x1030: 0x1dd0, 0x1031: 0x1dd5, 0x1032: 0x1dda, 0x1033: 0x1ddf, 0x1034: 0x1de9, 0x1035: 0x1dee,
- 0x1036: 0x1df8, 0x1037: 0x1dfd, 0x1038: 0x1e02, 0x1039: 0x1e07, 0x103a: 0x1e11, 0x103b: 0x1e16,
- 0x103c: 0x1f42, 0x103d: 0x1f47, 0x103e: 0x1f56, 0x103f: 0x1f5b,
- // Block 0x41, offset 0x1040
- 0x1040: 0x1f60, 0x1041: 0x1f74, 0x1042: 0x1f79, 0x1043: 0x1f7e, 0x1044: 0x1f83, 0x1045: 0x1f9c,
- 0x1046: 0x1fa6, 0x1047: 0x1fab, 0x1048: 0x1fb0, 0x1049: 0x1fc4, 0x104a: 0x1fe2, 0x104b: 0x1fe7,
- 0x104c: 0x1fec, 0x104d: 0x1ff1, 0x104e: 0x1ffb, 0x104f: 0x2000, 0x1050: 0x4473, 0x1051: 0x202d,
- 0x1052: 0x2032, 0x1053: 0x2037, 0x1054: 0x203c, 0x1055: 0x2046, 0x1056: 0x204b, 0x1057: 0x25b7,
- 0x1058: 0x25be, 0x1059: 0x25c5, 0x105a: 0x25da, 0x105b: 0x25e8, 0x105c: 0x1d8f, 0x105d: 0x1d94,
- 0x105e: 0x1d99, 0x105f: 0x1da8, 0x1060: 0x1db2, 0x1061: 0x1dc1, 0x1062: 0x1dc6, 0x1063: 0x1dcb,
- 0x1064: 0x1dda, 0x1065: 0x1de4, 0x1066: 0x1e02, 0x1067: 0x1e1b, 0x1068: 0x1e20, 0x1069: 0x1e2f,
- 0x106a: 0x1e34, 0x106b: 0x1e43, 0x106c: 0x1e4d, 0x106d: 0x1e5c, 0x106e: 0x1e61, 0x106f: 0x1e66,
- 0x1070: 0x1e70, 0x1071: 0x1eac, 0x1072: 0x1eb1, 0x1073: 0x1ebb, 0x1074: 0x1eca, 0x1075: 0x1ecf,
- 0x1076: 0x1ed4, 0x1077: 0x1ede, 0x1078: 0x1eed, 0x1079: 0x1f01, 0x107a: 0x1f06, 0x107b: 0x1f0b,
- 0x107c: 0x1f1a, 0x107d: 0x1f1f, 0x107e: 0x1f2e, 0x107f: 0x1f33,
- // Block 0x42, offset 0x1080
- 0x1080: 0x1f38, 0x1081: 0x1f3d, 0x1082: 0x1f4c, 0x1083: 0x1f51, 0x1084: 0x1f65, 0x1085: 0x1f6a,
- 0x1086: 0x1f6f, 0x1087: 0x1f74, 0x1088: 0x1f79, 0x1089: 0x1f8d, 0x108a: 0x1f92, 0x108b: 0x1f97,
- 0x108c: 0x1f9c, 0x108d: 0x1fa1, 0x108e: 0x1fb5, 0x108f: 0x1fba, 0x1090: 0x1fbf, 0x1091: 0x1fc4,
- 0x1092: 0x1fd3, 0x1093: 0x1fd8, 0x1094: 0x1fdd, 0x1095: 0x1fec, 0x1096: 0x1ff6, 0x1097: 0x2005,
- 0x1098: 0x200a, 0x1099: 0x4467, 0x109a: 0x201e, 0x109b: 0x2023, 0x109c: 0x2028, 0x109d: 0x2037,
- 0x109e: 0x2041, 0x109f: 0x25da, 0x10a0: 0x25e8, 0x10a1: 0x1da8, 0x10a2: 0x1db2, 0x10a3: 0x1dda,
- 0x10a4: 0x1de4, 0x10a5: 0x1e02, 0x10a6: 0x1e0c, 0x10a7: 0x1e70, 0x10a8: 0x1e75, 0x10a9: 0x1e98,
- 0x10aa: 0x1e9d, 0x10ab: 0x1f74, 0x10ac: 0x1f79, 0x10ad: 0x1f9c, 0x10ae: 0x1fec, 0x10af: 0x1ff6,
- 0x10b0: 0x2037, 0x10b1: 0x2041, 0x10b2: 0x451b, 0x10b3: 0x4523, 0x10b4: 0x452b, 0x10b5: 0x1ef7,
- 0x10b6: 0x1efc, 0x10b7: 0x1f10, 0x10b8: 0x1f15, 0x10b9: 0x1f24, 0x10ba: 0x1f29, 0x10bb: 0x1e7a,
- 0x10bc: 0x1e7f, 0x10bd: 0x1ea2, 0x10be: 0x1ea7, 0x10bf: 0x1e39,
- // Block 0x43, offset 0x10c0
- 0x10c0: 0x1e3e, 0x10c1: 0x1e25, 0x10c2: 0x1e2a, 0x10c3: 0x1e52, 0x10c4: 0x1e57, 0x10c5: 0x1ec0,
- 0x10c6: 0x1ec5, 0x10c7: 0x1ee3, 0x10c8: 0x1ee8, 0x10c9: 0x1e84, 0x10ca: 0x1e89, 0x10cb: 0x1e8e,
- 0x10cc: 0x1e98, 0x10cd: 0x1e93, 0x10ce: 0x1e6b, 0x10cf: 0x1eb6, 0x10d0: 0x1ed9, 0x10d1: 0x1ef7,
- 0x10d2: 0x1efc, 0x10d3: 0x1f10, 0x10d4: 0x1f15, 0x10d5: 0x1f24, 0x10d6: 0x1f29, 0x10d7: 0x1e7a,
- 0x10d8: 0x1e7f, 0x10d9: 0x1ea2, 0x10da: 0x1ea7, 0x10db: 0x1e39, 0x10dc: 0x1e3e, 0x10dd: 0x1e25,
- 0x10de: 0x1e2a, 0x10df: 0x1e52, 0x10e0: 0x1e57, 0x10e1: 0x1ec0, 0x10e2: 0x1ec5, 0x10e3: 0x1ee3,
- 0x10e4: 0x1ee8, 0x10e5: 0x1e84, 0x10e6: 0x1e89, 0x10e7: 0x1e8e, 0x10e8: 0x1e98, 0x10e9: 0x1e93,
- 0x10ea: 0x1e6b, 0x10eb: 0x1eb6, 0x10ec: 0x1ed9, 0x10ed: 0x1e84, 0x10ee: 0x1e89, 0x10ef: 0x1e8e,
- 0x10f0: 0x1e98, 0x10f1: 0x1e75, 0x10f2: 0x1e9d, 0x10f3: 0x1ef2, 0x10f4: 0x1e5c, 0x10f5: 0x1e61,
- 0x10f6: 0x1e66, 0x10f7: 0x1e84, 0x10f8: 0x1e89, 0x10f9: 0x1e8e, 0x10fa: 0x1ef2, 0x10fb: 0x1f01,
- 0x10fc: 0x441f, 0x10fd: 0x441f,
- // Block 0x44, offset 0x1100
- 0x1110: 0x2317, 0x1111: 0x232c,
- 0x1112: 0x232c, 0x1113: 0x2333, 0x1114: 0x233a, 0x1115: 0x234f, 0x1116: 0x2356, 0x1117: 0x235d,
- 0x1118: 0x2380, 0x1119: 0x2380, 0x111a: 0x23a3, 0x111b: 0x239c, 0x111c: 0x23b8, 0x111d: 0x23aa,
- 0x111e: 0x23b1, 0x111f: 0x23d4, 0x1120: 0x23d4, 0x1121: 0x23cd, 0x1122: 0x23db, 0x1123: 0x23db,
- 0x1124: 0x2405, 0x1125: 0x2405, 0x1126: 0x2421, 0x1127: 0x23e9, 0x1128: 0x23e9, 0x1129: 0x23e2,
- 0x112a: 0x23f7, 0x112b: 0x23f7, 0x112c: 0x23fe, 0x112d: 0x23fe, 0x112e: 0x2428, 0x112f: 0x2436,
- 0x1130: 0x2436, 0x1131: 0x243d, 0x1132: 0x243d, 0x1133: 0x2444, 0x1134: 0x244b, 0x1135: 0x2452,
- 0x1136: 0x2459, 0x1137: 0x2459, 0x1138: 0x2460, 0x1139: 0x246e, 0x113a: 0x247c, 0x113b: 0x2475,
- 0x113c: 0x2483, 0x113d: 0x2483, 0x113e: 0x2498, 0x113f: 0x249f,
- // Block 0x45, offset 0x1140
- 0x1140: 0x24d0, 0x1141: 0x24de, 0x1142: 0x24d7, 0x1143: 0x24bb, 0x1144: 0x24bb, 0x1145: 0x24e5,
- 0x1146: 0x24e5, 0x1147: 0x24ec, 0x1148: 0x24ec, 0x1149: 0x2516, 0x114a: 0x251d, 0x114b: 0x2524,
- 0x114c: 0x24fa, 0x114d: 0x2508, 0x114e: 0x252b, 0x114f: 0x2532,
- 0x1152: 0x2501, 0x1153: 0x2586, 0x1154: 0x258d, 0x1155: 0x2563, 0x1156: 0x256a, 0x1157: 0x254e,
- 0x1158: 0x254e, 0x1159: 0x2555, 0x115a: 0x257f, 0x115b: 0x2578, 0x115c: 0x25a2, 0x115d: 0x25a2,
- 0x115e: 0x2310, 0x115f: 0x2325, 0x1160: 0x231e, 0x1161: 0x2348, 0x1162: 0x2341, 0x1163: 0x236b,
- 0x1164: 0x2364, 0x1165: 0x238e, 0x1166: 0x2372, 0x1167: 0x2387, 0x1168: 0x23bf, 0x1169: 0x240c,
- 0x116a: 0x23f0, 0x116b: 0x242f, 0x116c: 0x24c9, 0x116d: 0x24f3, 0x116e: 0x259b, 0x116f: 0x2594,
- 0x1170: 0x25a9, 0x1171: 0x2540, 0x1172: 0x24a6, 0x1173: 0x2571, 0x1174: 0x2498, 0x1175: 0x24d0,
- 0x1176: 0x2467, 0x1177: 0x24b4, 0x1178: 0x2547, 0x1179: 0x2539, 0x117a: 0x24c2, 0x117b: 0x24ad,
- 0x117c: 0x24c2, 0x117d: 0x2547, 0x117e: 0x2379, 0x117f: 0x2395,
- // Block 0x46, offset 0x1180
- 0x1180: 0x250f, 0x1181: 0x248a, 0x1182: 0x2309, 0x1183: 0x24ad, 0x1184: 0x2452, 0x1185: 0x2421,
- 0x1186: 0x23c6, 0x1187: 0x255c,
- 0x11b0: 0x241a, 0x11b1: 0x2491, 0x11b2: 0x27cc, 0x11b3: 0x27c3, 0x11b4: 0x27f9, 0x11b5: 0x27e7,
- 0x11b6: 0x27d5, 0x11b7: 0x27f0, 0x11b8: 0x2802, 0x11b9: 0x2413, 0x11ba: 0x2c89, 0x11bb: 0x2b09,
- 0x11bc: 0x27de,
- // Block 0x47, offset 0x11c0
- 0x11d0: 0x0019, 0x11d1: 0x0486,
- 0x11d2: 0x048a, 0x11d3: 0x0035, 0x11d4: 0x0037, 0x11d5: 0x0003, 0x11d6: 0x003f, 0x11d7: 0x04c2,
- 0x11d8: 0x04c6, 0x11d9: 0x1b62,
- 0x11e0: 0x8133, 0x11e1: 0x8133, 0x11e2: 0x8133, 0x11e3: 0x8133,
- 0x11e4: 0x8133, 0x11e5: 0x8133, 0x11e6: 0x8133, 0x11e7: 0x812e, 0x11e8: 0x812e, 0x11e9: 0x812e,
- 0x11ea: 0x812e, 0x11eb: 0x812e, 0x11ec: 0x812e, 0x11ed: 0x812e, 0x11ee: 0x8133, 0x11ef: 0x8133,
- 0x11f0: 0x1876, 0x11f1: 0x0446, 0x11f2: 0x0442, 0x11f3: 0x007f, 0x11f4: 0x007f, 0x11f5: 0x0011,
- 0x11f6: 0x0013, 0x11f7: 0x00b7, 0x11f8: 0x00bb, 0x11f9: 0x04ba, 0x11fa: 0x04be, 0x11fb: 0x04ae,
- 0x11fc: 0x04b2, 0x11fd: 0x0496, 0x11fe: 0x049a, 0x11ff: 0x048e,
- // Block 0x48, offset 0x1200
- 0x1200: 0x0492, 0x1201: 0x049e, 0x1202: 0x04a2, 0x1203: 0x04a6, 0x1204: 0x04aa,
- 0x1207: 0x0077, 0x1208: 0x007b, 0x1209: 0x4280, 0x120a: 0x4280, 0x120b: 0x4280,
- 0x120c: 0x4280, 0x120d: 0x007f, 0x120e: 0x007f, 0x120f: 0x007f, 0x1210: 0x0019, 0x1211: 0x0486,
- 0x1212: 0x001d, 0x1214: 0x0037, 0x1215: 0x0035, 0x1216: 0x003f, 0x1217: 0x0003,
- 0x1218: 0x0446, 0x1219: 0x0011, 0x121a: 0x0013, 0x121b: 0x00b7, 0x121c: 0x00bb, 0x121d: 0x04ba,
- 0x121e: 0x04be, 0x121f: 0x0007, 0x1220: 0x000d, 0x1221: 0x0015, 0x1222: 0x0017, 0x1223: 0x001b,
- 0x1224: 0x0039, 0x1225: 0x003d, 0x1226: 0x003b, 0x1228: 0x0079, 0x1229: 0x0009,
- 0x122a: 0x000b, 0x122b: 0x0041,
- 0x1230: 0x42c1, 0x1231: 0x4443, 0x1232: 0x42c6, 0x1234: 0x42cb,
- 0x1236: 0x42d0, 0x1237: 0x4449, 0x1238: 0x42d5, 0x1239: 0x444f, 0x123a: 0x42da, 0x123b: 0x4455,
- 0x123c: 0x42df, 0x123d: 0x445b, 0x123e: 0x42e4, 0x123f: 0x4461,
- // Block 0x49, offset 0x1240
- 0x1240: 0x0239, 0x1241: 0x4425, 0x1242: 0x4425, 0x1243: 0x442b, 0x1244: 0x442b, 0x1245: 0x446d,
- 0x1246: 0x446d, 0x1247: 0x4431, 0x1248: 0x4431, 0x1249: 0x4479, 0x124a: 0x4479, 0x124b: 0x4479,
- 0x124c: 0x4479, 0x124d: 0x023c, 0x124e: 0x023c, 0x124f: 0x023f, 0x1250: 0x023f, 0x1251: 0x023f,
- 0x1252: 0x023f, 0x1253: 0x0242, 0x1254: 0x0242, 0x1255: 0x0245, 0x1256: 0x0245, 0x1257: 0x0245,
- 0x1258: 0x0245, 0x1259: 0x0248, 0x125a: 0x0248, 0x125b: 0x0248, 0x125c: 0x0248, 0x125d: 0x024b,
- 0x125e: 0x024b, 0x125f: 0x024b, 0x1260: 0x024b, 0x1261: 0x024e, 0x1262: 0x024e, 0x1263: 0x024e,
- 0x1264: 0x024e, 0x1265: 0x0251, 0x1266: 0x0251, 0x1267: 0x0251, 0x1268: 0x0251, 0x1269: 0x0254,
- 0x126a: 0x0254, 0x126b: 0x0257, 0x126c: 0x0257, 0x126d: 0x025a, 0x126e: 0x025a, 0x126f: 0x025d,
- 0x1270: 0x025d, 0x1271: 0x0260, 0x1272: 0x0260, 0x1273: 0x0260, 0x1274: 0x0260, 0x1275: 0x0263,
- 0x1276: 0x0263, 0x1277: 0x0263, 0x1278: 0x0263, 0x1279: 0x0266, 0x127a: 0x0266, 0x127b: 0x0266,
- 0x127c: 0x0266, 0x127d: 0x0269, 0x127e: 0x0269, 0x127f: 0x0269,
- // Block 0x4a, offset 0x1280
- 0x1280: 0x0269, 0x1281: 0x026c, 0x1282: 0x026c, 0x1283: 0x026c, 0x1284: 0x026c, 0x1285: 0x026f,
- 0x1286: 0x026f, 0x1287: 0x026f, 0x1288: 0x026f, 0x1289: 0x0272, 0x128a: 0x0272, 0x128b: 0x0272,
- 0x128c: 0x0272, 0x128d: 0x0275, 0x128e: 0x0275, 0x128f: 0x0275, 0x1290: 0x0275, 0x1291: 0x0278,
- 0x1292: 0x0278, 0x1293: 0x0278, 0x1294: 0x0278, 0x1295: 0x027b, 0x1296: 0x027b, 0x1297: 0x027b,
- 0x1298: 0x027b, 0x1299: 0x027e, 0x129a: 0x027e, 0x129b: 0x027e, 0x129c: 0x027e, 0x129d: 0x0281,
- 0x129e: 0x0281, 0x129f: 0x0281, 0x12a0: 0x0281, 0x12a1: 0x0284, 0x12a2: 0x0284, 0x12a3: 0x0284,
- 0x12a4: 0x0284, 0x12a5: 0x0287, 0x12a6: 0x0287, 0x12a7: 0x0287, 0x12a8: 0x0287, 0x12a9: 0x028a,
- 0x12aa: 0x028a, 0x12ab: 0x028a, 0x12ac: 0x028a, 0x12ad: 0x028d, 0x12ae: 0x028d, 0x12af: 0x0290,
- 0x12b0: 0x0290, 0x12b1: 0x0293, 0x12b2: 0x0293, 0x12b3: 0x0293, 0x12b4: 0x0293, 0x12b5: 0x2e17,
- 0x12b6: 0x2e17, 0x12b7: 0x2e1f, 0x12b8: 0x2e1f, 0x12b9: 0x2e27, 0x12ba: 0x2e27, 0x12bb: 0x1f88,
- 0x12bc: 0x1f88,
- // Block 0x4b, offset 0x12c0
- 0x12c0: 0x0081, 0x12c1: 0x0083, 0x12c2: 0x0085, 0x12c3: 0x0087, 0x12c4: 0x0089, 0x12c5: 0x008b,
- 0x12c6: 0x008d, 0x12c7: 0x008f, 0x12c8: 0x0091, 0x12c9: 0x0093, 0x12ca: 0x0095, 0x12cb: 0x0097,
- 0x12cc: 0x0099, 0x12cd: 0x009b, 0x12ce: 0x009d, 0x12cf: 0x009f, 0x12d0: 0x00a1, 0x12d1: 0x00a3,
- 0x12d2: 0x00a5, 0x12d3: 0x00a7, 0x12d4: 0x00a9, 0x12d5: 0x00ab, 0x12d6: 0x00ad, 0x12d7: 0x00af,
- 0x12d8: 0x00b1, 0x12d9: 0x00b3, 0x12da: 0x00b5, 0x12db: 0x00b7, 0x12dc: 0x00b9, 0x12dd: 0x00bb,
- 0x12de: 0x00bd, 0x12df: 0x047a, 0x12e0: 0x047e, 0x12e1: 0x048a, 0x12e2: 0x049e, 0x12e3: 0x04a2,
- 0x12e4: 0x0486, 0x12e5: 0x05ae, 0x12e6: 0x05a6, 0x12e7: 0x04ca, 0x12e8: 0x04d2, 0x12e9: 0x04da,
- 0x12ea: 0x04e2, 0x12eb: 0x04ea, 0x12ec: 0x056e, 0x12ed: 0x0576, 0x12ee: 0x057e, 0x12ef: 0x0522,
- 0x12f0: 0x05b2, 0x12f1: 0x04ce, 0x12f2: 0x04d6, 0x12f3: 0x04de, 0x12f4: 0x04e6, 0x12f5: 0x04ee,
- 0x12f6: 0x04f2, 0x12f7: 0x04f6, 0x12f8: 0x04fa, 0x12f9: 0x04fe, 0x12fa: 0x0502, 0x12fb: 0x0506,
- 0x12fc: 0x050a, 0x12fd: 0x050e, 0x12fe: 0x0512, 0x12ff: 0x0516,
- // Block 0x4c, offset 0x1300
- 0x1300: 0x051a, 0x1301: 0x051e, 0x1302: 0x0526, 0x1303: 0x052a, 0x1304: 0x052e, 0x1305: 0x0532,
- 0x1306: 0x0536, 0x1307: 0x053a, 0x1308: 0x053e, 0x1309: 0x0542, 0x130a: 0x0546, 0x130b: 0x054a,
- 0x130c: 0x054e, 0x130d: 0x0552, 0x130e: 0x0556, 0x130f: 0x055a, 0x1310: 0x055e, 0x1311: 0x0562,
- 0x1312: 0x0566, 0x1313: 0x056a, 0x1314: 0x0572, 0x1315: 0x057a, 0x1316: 0x0582, 0x1317: 0x0586,
- 0x1318: 0x058a, 0x1319: 0x058e, 0x131a: 0x0592, 0x131b: 0x0596, 0x131c: 0x059a, 0x131d: 0x05aa,
- 0x131e: 0x4a8f, 0x131f: 0x4a95, 0x1320: 0x03c6, 0x1321: 0x0316, 0x1322: 0x031a, 0x1323: 0x4a52,
- 0x1324: 0x031e, 0x1325: 0x4a58, 0x1326: 0x4a5e, 0x1327: 0x0322, 0x1328: 0x0326, 0x1329: 0x032a,
- 0x132a: 0x4a64, 0x132b: 0x4a6a, 0x132c: 0x4a70, 0x132d: 0x4a76, 0x132e: 0x4a7c, 0x132f: 0x4a82,
- 0x1330: 0x036a, 0x1331: 0x032e, 0x1332: 0x0332, 0x1333: 0x0336, 0x1334: 0x037e, 0x1335: 0x033a,
- 0x1336: 0x033e, 0x1337: 0x0342, 0x1338: 0x0346, 0x1339: 0x034a, 0x133a: 0x034e, 0x133b: 0x0352,
- 0x133c: 0x0356, 0x133d: 0x035a, 0x133e: 0x035e,
- // Block 0x4d, offset 0x1340
- 0x1342: 0x49d4, 0x1343: 0x49da, 0x1344: 0x49e0, 0x1345: 0x49e6,
- 0x1346: 0x49ec, 0x1347: 0x49f2, 0x134a: 0x49f8, 0x134b: 0x49fe,
- 0x134c: 0x4a04, 0x134d: 0x4a0a, 0x134e: 0x4a10, 0x134f: 0x4a16,
- 0x1352: 0x4a1c, 0x1353: 0x4a22, 0x1354: 0x4a28, 0x1355: 0x4a2e, 0x1356: 0x4a34, 0x1357: 0x4a3a,
- 0x135a: 0x4a40, 0x135b: 0x4a46, 0x135c: 0x4a4c,
- 0x1360: 0x00bf, 0x1361: 0x00c2, 0x1362: 0x00cb, 0x1363: 0x427b,
- 0x1364: 0x00c8, 0x1365: 0x00c5, 0x1366: 0x044a, 0x1368: 0x046e, 0x1369: 0x044e,
- 0x136a: 0x0452, 0x136b: 0x0456, 0x136c: 0x045a, 0x136d: 0x0472, 0x136e: 0x0476,
- // Block 0x4e, offset 0x1380
- 0x1380: 0x0063, 0x1381: 0x0065, 0x1382: 0x0067, 0x1383: 0x0069, 0x1384: 0x006b, 0x1385: 0x006d,
- 0x1386: 0x006f, 0x1387: 0x0071, 0x1388: 0x0073, 0x1389: 0x0075, 0x138a: 0x0083, 0x138b: 0x0085,
- 0x138c: 0x0087, 0x138d: 0x0089, 0x138e: 0x008b, 0x138f: 0x008d, 0x1390: 0x008f, 0x1391: 0x0091,
- 0x1392: 0x0093, 0x1393: 0x0095, 0x1394: 0x0097, 0x1395: 0x0099, 0x1396: 0x009b, 0x1397: 0x009d,
- 0x1398: 0x009f, 0x1399: 0x00a1, 0x139a: 0x00a3, 0x139b: 0x00a5, 0x139c: 0x00a7, 0x139d: 0x00a9,
- 0x139e: 0x00ab, 0x139f: 0x00ad, 0x13a0: 0x00af, 0x13a1: 0x00b1, 0x13a2: 0x00b3, 0x13a3: 0x00b5,
- 0x13a4: 0x00dd, 0x13a5: 0x00f2, 0x13a8: 0x0176, 0x13a9: 0x0179,
- 0x13aa: 0x017c, 0x13ab: 0x017f, 0x13ac: 0x0182, 0x13ad: 0x0185, 0x13ae: 0x0188, 0x13af: 0x018b,
- 0x13b0: 0x018e, 0x13b1: 0x0191, 0x13b2: 0x0194, 0x13b3: 0x0197, 0x13b4: 0x019a, 0x13b5: 0x019d,
- 0x13b6: 0x01a0, 0x13b7: 0x01a3, 0x13b8: 0x01a6, 0x13b9: 0x018b, 0x13ba: 0x01a9, 0x13bb: 0x01ac,
- 0x13bc: 0x01af, 0x13bd: 0x01b2, 0x13be: 0x01b5, 0x13bf: 0x01b8,
- // Block 0x4f, offset 0x13c0
- 0x13c0: 0x0200, 0x13c1: 0x0203, 0x13c2: 0x0206, 0x13c3: 0x045e, 0x13c4: 0x01ca, 0x13c5: 0x01d3,
- 0x13c6: 0x01d9, 0x13c7: 0x01fd, 0x13c8: 0x01ee, 0x13c9: 0x01eb, 0x13ca: 0x0209, 0x13cb: 0x020c,
- 0x13ce: 0x0021, 0x13cf: 0x0023, 0x13d0: 0x0025, 0x13d1: 0x0027,
- 0x13d2: 0x0029, 0x13d3: 0x002b, 0x13d4: 0x002d, 0x13d5: 0x002f, 0x13d6: 0x0031, 0x13d7: 0x0033,
- 0x13d8: 0x0021, 0x13d9: 0x0023, 0x13da: 0x0025, 0x13db: 0x0027, 0x13dc: 0x0029, 0x13dd: 0x002b,
- 0x13de: 0x002d, 0x13df: 0x002f, 0x13e0: 0x0031, 0x13e1: 0x0033, 0x13e2: 0x0021, 0x13e3: 0x0023,
- 0x13e4: 0x0025, 0x13e5: 0x0027, 0x13e6: 0x0029, 0x13e7: 0x002b, 0x13e8: 0x002d, 0x13e9: 0x002f,
- 0x13ea: 0x0031, 0x13eb: 0x0033, 0x13ec: 0x0021, 0x13ed: 0x0023, 0x13ee: 0x0025, 0x13ef: 0x0027,
- 0x13f0: 0x0029, 0x13f1: 0x002b, 0x13f2: 0x002d, 0x13f3: 0x002f, 0x13f4: 0x0031, 0x13f5: 0x0033,
- 0x13f6: 0x0021, 0x13f7: 0x0023, 0x13f8: 0x0025, 0x13f9: 0x0027, 0x13fa: 0x0029, 0x13fb: 0x002b,
- 0x13fc: 0x002d, 0x13fd: 0x002f, 0x13fe: 0x0031, 0x13ff: 0x0033,
- // Block 0x50, offset 0x1400
- 0x1400: 0x023c, 0x1401: 0x023f, 0x1402: 0x024b, 0x1403: 0x0254, 0x1405: 0x028d,
- 0x1406: 0x025d, 0x1407: 0x024e, 0x1408: 0x026c, 0x1409: 0x0293, 0x140a: 0x027e, 0x140b: 0x0281,
- 0x140c: 0x0284, 0x140d: 0x0287, 0x140e: 0x0260, 0x140f: 0x0272, 0x1410: 0x0278, 0x1411: 0x0266,
- 0x1412: 0x027b, 0x1413: 0x025a, 0x1414: 0x0263, 0x1415: 0x0245, 0x1416: 0x0248, 0x1417: 0x0251,
- 0x1418: 0x0257, 0x1419: 0x0269, 0x141a: 0x026f, 0x141b: 0x0275, 0x141c: 0x0296, 0x141d: 0x02e7,
- 0x141e: 0x02cf, 0x141f: 0x0299, 0x1421: 0x023f, 0x1422: 0x024b,
- 0x1424: 0x028a, 0x1427: 0x024e, 0x1429: 0x0293,
- 0x142a: 0x027e, 0x142b: 0x0281, 0x142c: 0x0284, 0x142d: 0x0287, 0x142e: 0x0260, 0x142f: 0x0272,
- 0x1430: 0x0278, 0x1431: 0x0266, 0x1432: 0x027b, 0x1434: 0x0263, 0x1435: 0x0245,
- 0x1436: 0x0248, 0x1437: 0x0251, 0x1439: 0x0269, 0x143b: 0x0275,
- // Block 0x51, offset 0x1440
- 0x1442: 0x024b,
- 0x1447: 0x024e, 0x1449: 0x0293, 0x144b: 0x0281,
- 0x144d: 0x0287, 0x144e: 0x0260, 0x144f: 0x0272, 0x1451: 0x0266,
- 0x1452: 0x027b, 0x1454: 0x0263, 0x1457: 0x0251,
- 0x1459: 0x0269, 0x145b: 0x0275, 0x145d: 0x02e7,
- 0x145f: 0x0299, 0x1461: 0x023f, 0x1462: 0x024b,
- 0x1464: 0x028a, 0x1467: 0x024e, 0x1468: 0x026c, 0x1469: 0x0293,
- 0x146a: 0x027e, 0x146c: 0x0284, 0x146d: 0x0287, 0x146e: 0x0260, 0x146f: 0x0272,
- 0x1470: 0x0278, 0x1471: 0x0266, 0x1472: 0x027b, 0x1474: 0x0263, 0x1475: 0x0245,
- 0x1476: 0x0248, 0x1477: 0x0251, 0x1479: 0x0269, 0x147a: 0x026f, 0x147b: 0x0275,
- 0x147c: 0x0296, 0x147e: 0x02cf,
- // Block 0x52, offset 0x1480
- 0x1480: 0x023c, 0x1481: 0x023f, 0x1482: 0x024b, 0x1483: 0x0254, 0x1484: 0x028a, 0x1485: 0x028d,
- 0x1486: 0x025d, 0x1487: 0x024e, 0x1488: 0x026c, 0x1489: 0x0293, 0x148b: 0x0281,
- 0x148c: 0x0284, 0x148d: 0x0287, 0x148e: 0x0260, 0x148f: 0x0272, 0x1490: 0x0278, 0x1491: 0x0266,
- 0x1492: 0x027b, 0x1493: 0x025a, 0x1494: 0x0263, 0x1495: 0x0245, 0x1496: 0x0248, 0x1497: 0x0251,
- 0x1498: 0x0257, 0x1499: 0x0269, 0x149a: 0x026f, 0x149b: 0x0275,
- 0x14a1: 0x023f, 0x14a2: 0x024b, 0x14a3: 0x0254,
- 0x14a5: 0x028d, 0x14a6: 0x025d, 0x14a7: 0x024e, 0x14a8: 0x026c, 0x14a9: 0x0293,
- 0x14ab: 0x0281, 0x14ac: 0x0284, 0x14ad: 0x0287, 0x14ae: 0x0260, 0x14af: 0x0272,
- 0x14b0: 0x0278, 0x14b1: 0x0266, 0x14b2: 0x027b, 0x14b3: 0x025a, 0x14b4: 0x0263, 0x14b5: 0x0245,
- 0x14b6: 0x0248, 0x14b7: 0x0251, 0x14b8: 0x0257, 0x14b9: 0x0269, 0x14ba: 0x026f, 0x14bb: 0x0275,
- // Block 0x53, offset 0x14c0
- 0x14c0: 0x187c, 0x14c1: 0x1879, 0x14c2: 0x187f, 0x14c3: 0x18a3, 0x14c4: 0x18c7, 0x14c5: 0x18eb,
- 0x14c6: 0x190f, 0x14c7: 0x1918, 0x14c8: 0x191e, 0x14c9: 0x1924, 0x14ca: 0x192a,
- 0x14d0: 0x1a92, 0x14d1: 0x1a96,
- 0x14d2: 0x1a9a, 0x14d3: 0x1a9e, 0x14d4: 0x1aa2, 0x14d5: 0x1aa6, 0x14d6: 0x1aaa, 0x14d7: 0x1aae,
- 0x14d8: 0x1ab2, 0x14d9: 0x1ab6, 0x14da: 0x1aba, 0x14db: 0x1abe, 0x14dc: 0x1ac2, 0x14dd: 0x1ac6,
- 0x14de: 0x1aca, 0x14df: 0x1ace, 0x14e0: 0x1ad2, 0x14e1: 0x1ad6, 0x14e2: 0x1ada, 0x14e3: 0x1ade,
- 0x14e4: 0x1ae2, 0x14e5: 0x1ae6, 0x14e6: 0x1aea, 0x14e7: 0x1aee, 0x14e8: 0x1af2, 0x14e9: 0x1af6,
- 0x14ea: 0x272b, 0x14eb: 0x0047, 0x14ec: 0x0065, 0x14ed: 0x193f, 0x14ee: 0x19b7,
- 0x14f0: 0x0043, 0x14f1: 0x0045, 0x14f2: 0x0047, 0x14f3: 0x0049, 0x14f4: 0x004b, 0x14f5: 0x004d,
- 0x14f6: 0x004f, 0x14f7: 0x0051, 0x14f8: 0x0053, 0x14f9: 0x0055, 0x14fa: 0x0057, 0x14fb: 0x0059,
- 0x14fc: 0x005b, 0x14fd: 0x005d, 0x14fe: 0x005f, 0x14ff: 0x0061,
- // Block 0x54, offset 0x1500
- 0x1500: 0x26b3, 0x1501: 0x26c8, 0x1502: 0x0506,
- 0x1510: 0x0c12, 0x1511: 0x0a4a,
- 0x1512: 0x08d6, 0x1513: 0x45db, 0x1514: 0x071e, 0x1515: 0x09f2, 0x1516: 0x1332, 0x1517: 0x0a02,
- 0x1518: 0x072a, 0x1519: 0x0cda, 0x151a: 0x0eb2, 0x151b: 0x0cb2, 0x151c: 0x082a, 0x151d: 0x0b6e,
- 0x151e: 0x07c2, 0x151f: 0x0cba, 0x1520: 0x0816, 0x1521: 0x111a, 0x1522: 0x0f86, 0x1523: 0x138e,
- 0x1524: 0x09d6, 0x1525: 0x090e, 0x1526: 0x0e66, 0x1527: 0x0c1e, 0x1528: 0x0c4a, 0x1529: 0x06c2,
- 0x152a: 0x06ce, 0x152b: 0x140e, 0x152c: 0x0ade, 0x152d: 0x06ea, 0x152e: 0x08f2, 0x152f: 0x0c3e,
- 0x1530: 0x13b6, 0x1531: 0x0c16, 0x1532: 0x1072, 0x1533: 0x10ae, 0x1534: 0x08fa, 0x1535: 0x0e46,
- 0x1536: 0x0d0e, 0x1537: 0x0d0a, 0x1538: 0x0f9a, 0x1539: 0x082e, 0x153a: 0x095a, 0x153b: 0x1446,
- // Block 0x55, offset 0x1540
- 0x1540: 0x06fe, 0x1541: 0x06f6, 0x1542: 0x0706, 0x1543: 0x164a, 0x1544: 0x074a, 0x1545: 0x075a,
- 0x1546: 0x075e, 0x1547: 0x0766, 0x1548: 0x076e, 0x1549: 0x0772, 0x154a: 0x077e, 0x154b: 0x0776,
- 0x154c: 0x05b6, 0x154d: 0x165e, 0x154e: 0x0792, 0x154f: 0x0796, 0x1550: 0x079a, 0x1551: 0x07b6,
- 0x1552: 0x164f, 0x1553: 0x05ba, 0x1554: 0x07a2, 0x1555: 0x07c2, 0x1556: 0x1659, 0x1557: 0x07d2,
- 0x1558: 0x07da, 0x1559: 0x073a, 0x155a: 0x07e2, 0x155b: 0x07e6, 0x155c: 0x1834, 0x155d: 0x0802,
- 0x155e: 0x080a, 0x155f: 0x05c2, 0x1560: 0x0822, 0x1561: 0x0826, 0x1562: 0x082e, 0x1563: 0x0832,
- 0x1564: 0x05c6, 0x1565: 0x084a, 0x1566: 0x084e, 0x1567: 0x085a, 0x1568: 0x0866, 0x1569: 0x086a,
- 0x156a: 0x086e, 0x156b: 0x0876, 0x156c: 0x0896, 0x156d: 0x089a, 0x156e: 0x08a2, 0x156f: 0x08b2,
- 0x1570: 0x08ba, 0x1571: 0x08be, 0x1572: 0x08be, 0x1573: 0x08be, 0x1574: 0x166d, 0x1575: 0x0e96,
- 0x1576: 0x08d2, 0x1577: 0x08da, 0x1578: 0x1672, 0x1579: 0x08e6, 0x157a: 0x08ee, 0x157b: 0x08f6,
- 0x157c: 0x091e, 0x157d: 0x090a, 0x157e: 0x0916, 0x157f: 0x091a,
- // Block 0x56, offset 0x1580
- 0x1580: 0x0922, 0x1581: 0x092a, 0x1582: 0x092e, 0x1583: 0x0936, 0x1584: 0x093e, 0x1585: 0x0942,
- 0x1586: 0x0942, 0x1587: 0x094a, 0x1588: 0x0952, 0x1589: 0x0956, 0x158a: 0x0962, 0x158b: 0x0986,
- 0x158c: 0x096a, 0x158d: 0x098a, 0x158e: 0x096e, 0x158f: 0x0976, 0x1590: 0x080e, 0x1591: 0x09d2,
- 0x1592: 0x099a, 0x1593: 0x099e, 0x1594: 0x09a2, 0x1595: 0x0996, 0x1596: 0x09aa, 0x1597: 0x09a6,
- 0x1598: 0x09be, 0x1599: 0x1677, 0x159a: 0x09da, 0x159b: 0x09de, 0x159c: 0x09e6, 0x159d: 0x09f2,
- 0x159e: 0x09fa, 0x159f: 0x0a16, 0x15a0: 0x167c, 0x15a1: 0x1681, 0x15a2: 0x0a22, 0x15a3: 0x0a26,
- 0x15a4: 0x0a2a, 0x15a5: 0x0a1e, 0x15a6: 0x0a32, 0x15a7: 0x05ca, 0x15a8: 0x05ce, 0x15a9: 0x0a3a,
- 0x15aa: 0x0a42, 0x15ab: 0x0a42, 0x15ac: 0x1686, 0x15ad: 0x0a5e, 0x15ae: 0x0a62, 0x15af: 0x0a66,
- 0x15b0: 0x0a6e, 0x15b1: 0x168b, 0x15b2: 0x0a76, 0x15b3: 0x0a7a, 0x15b4: 0x0b52, 0x15b5: 0x0a82,
- 0x15b6: 0x05d2, 0x15b7: 0x0a8e, 0x15b8: 0x0a9e, 0x15b9: 0x0aaa, 0x15ba: 0x0aa6, 0x15bb: 0x1695,
- 0x15bc: 0x0ab2, 0x15bd: 0x169a, 0x15be: 0x0abe, 0x15bf: 0x0aba,
- // Block 0x57, offset 0x15c0
- 0x15c0: 0x0ac2, 0x15c1: 0x0ad2, 0x15c2: 0x0ad6, 0x15c3: 0x05d6, 0x15c4: 0x0ae6, 0x15c5: 0x0aee,
- 0x15c6: 0x0af2, 0x15c7: 0x0af6, 0x15c8: 0x05da, 0x15c9: 0x169f, 0x15ca: 0x05de, 0x15cb: 0x0b12,
- 0x15cc: 0x0b16, 0x15cd: 0x0b1a, 0x15ce: 0x0b22, 0x15cf: 0x1866, 0x15d0: 0x0b3a, 0x15d1: 0x16a9,
- 0x15d2: 0x16a9, 0x15d3: 0x11da, 0x15d4: 0x0b4a, 0x15d5: 0x0b4a, 0x15d6: 0x05e2, 0x15d7: 0x16cc,
- 0x15d8: 0x179e, 0x15d9: 0x0b5a, 0x15da: 0x0b62, 0x15db: 0x05e6, 0x15dc: 0x0b76, 0x15dd: 0x0b86,
- 0x15de: 0x0b8a, 0x15df: 0x0b92, 0x15e0: 0x0ba2, 0x15e1: 0x05ee, 0x15e2: 0x05ea, 0x15e3: 0x0ba6,
- 0x15e4: 0x16ae, 0x15e5: 0x0baa, 0x15e6: 0x0bbe, 0x15e7: 0x0bc2, 0x15e8: 0x0bc6, 0x15e9: 0x0bc2,
- 0x15ea: 0x0bd2, 0x15eb: 0x0bd6, 0x15ec: 0x0be6, 0x15ed: 0x0bde, 0x15ee: 0x0be2, 0x15ef: 0x0bea,
- 0x15f0: 0x0bee, 0x15f1: 0x0bf2, 0x15f2: 0x0bfe, 0x15f3: 0x0c02, 0x15f4: 0x0c1a, 0x15f5: 0x0c22,
- 0x15f6: 0x0c32, 0x15f7: 0x0c46, 0x15f8: 0x16bd, 0x15f9: 0x0c42, 0x15fa: 0x0c36, 0x15fb: 0x0c4e,
- 0x15fc: 0x0c56, 0x15fd: 0x0c6a, 0x15fe: 0x16c2, 0x15ff: 0x0c72,
- // Block 0x58, offset 0x1600
- 0x1600: 0x0c66, 0x1601: 0x0c5e, 0x1602: 0x05f2, 0x1603: 0x0c7a, 0x1604: 0x0c82, 0x1605: 0x0c8a,
- 0x1606: 0x0c7e, 0x1607: 0x05f6, 0x1608: 0x0c9a, 0x1609: 0x0ca2, 0x160a: 0x16c7, 0x160b: 0x0cce,
- 0x160c: 0x0d02, 0x160d: 0x0cde, 0x160e: 0x0602, 0x160f: 0x0cea, 0x1610: 0x05fe, 0x1611: 0x05fa,
- 0x1612: 0x07c6, 0x1613: 0x07ca, 0x1614: 0x0d06, 0x1615: 0x0cee, 0x1616: 0x11ae, 0x1617: 0x0666,
- 0x1618: 0x0d12, 0x1619: 0x0d16, 0x161a: 0x0d1a, 0x161b: 0x0d2e, 0x161c: 0x0d26, 0x161d: 0x16e0,
- 0x161e: 0x0606, 0x161f: 0x0d42, 0x1620: 0x0d36, 0x1621: 0x0d52, 0x1622: 0x0d5a, 0x1623: 0x16ea,
- 0x1624: 0x0d5e, 0x1625: 0x0d4a, 0x1626: 0x0d66, 0x1627: 0x060a, 0x1628: 0x0d6a, 0x1629: 0x0d6e,
- 0x162a: 0x0d72, 0x162b: 0x0d7e, 0x162c: 0x16ef, 0x162d: 0x0d86, 0x162e: 0x060e, 0x162f: 0x0d92,
- 0x1630: 0x16f4, 0x1631: 0x0d96, 0x1632: 0x0612, 0x1633: 0x0da2, 0x1634: 0x0dae, 0x1635: 0x0dba,
- 0x1636: 0x0dbe, 0x1637: 0x16f9, 0x1638: 0x1690, 0x1639: 0x16fe, 0x163a: 0x0dde, 0x163b: 0x1703,
- 0x163c: 0x0dea, 0x163d: 0x0df2, 0x163e: 0x0de2, 0x163f: 0x0dfe,
- // Block 0x59, offset 0x1640
- 0x1640: 0x0e0e, 0x1641: 0x0e1e, 0x1642: 0x0e12, 0x1643: 0x0e16, 0x1644: 0x0e22, 0x1645: 0x0e26,
- 0x1646: 0x1708, 0x1647: 0x0e0a, 0x1648: 0x0e3e, 0x1649: 0x0e42, 0x164a: 0x0616, 0x164b: 0x0e56,
- 0x164c: 0x0e52, 0x164d: 0x170d, 0x164e: 0x0e36, 0x164f: 0x0e72, 0x1650: 0x1712, 0x1651: 0x1717,
- 0x1652: 0x0e76, 0x1653: 0x0e8a, 0x1654: 0x0e86, 0x1655: 0x0e82, 0x1656: 0x061a, 0x1657: 0x0e8e,
- 0x1658: 0x0e9e, 0x1659: 0x0e9a, 0x165a: 0x0ea6, 0x165b: 0x1654, 0x165c: 0x0eb6, 0x165d: 0x171c,
- 0x165e: 0x0ec2, 0x165f: 0x1726, 0x1660: 0x0ed6, 0x1661: 0x0ee2, 0x1662: 0x0ef6, 0x1663: 0x172b,
- 0x1664: 0x0f0a, 0x1665: 0x0f0e, 0x1666: 0x1730, 0x1667: 0x1735, 0x1668: 0x0f2a, 0x1669: 0x0f3a,
- 0x166a: 0x061e, 0x166b: 0x0f3e, 0x166c: 0x0622, 0x166d: 0x0622, 0x166e: 0x0f56, 0x166f: 0x0f5a,
- 0x1670: 0x0f62, 0x1671: 0x0f66, 0x1672: 0x0f72, 0x1673: 0x0626, 0x1674: 0x0f8a, 0x1675: 0x173a,
- 0x1676: 0x0fa6, 0x1677: 0x173f, 0x1678: 0x0fb2, 0x1679: 0x16a4, 0x167a: 0x0fc2, 0x167b: 0x1744,
- 0x167c: 0x1749, 0x167d: 0x174e, 0x167e: 0x062a, 0x167f: 0x062e,
- // Block 0x5a, offset 0x1680
- 0x1680: 0x0ffa, 0x1681: 0x1758, 0x1682: 0x1753, 0x1683: 0x175d, 0x1684: 0x1762, 0x1685: 0x1002,
- 0x1686: 0x1006, 0x1687: 0x1006, 0x1688: 0x100e, 0x1689: 0x0636, 0x168a: 0x1012, 0x168b: 0x063a,
- 0x168c: 0x063e, 0x168d: 0x176c, 0x168e: 0x1026, 0x168f: 0x102e, 0x1690: 0x103a, 0x1691: 0x0642,
- 0x1692: 0x1771, 0x1693: 0x105e, 0x1694: 0x1776, 0x1695: 0x177b, 0x1696: 0x107e, 0x1697: 0x1096,
- 0x1698: 0x0646, 0x1699: 0x109e, 0x169a: 0x10a2, 0x169b: 0x10a6, 0x169c: 0x1780, 0x169d: 0x1785,
- 0x169e: 0x1785, 0x169f: 0x10be, 0x16a0: 0x064a, 0x16a1: 0x178a, 0x16a2: 0x10d2, 0x16a3: 0x10d6,
- 0x16a4: 0x064e, 0x16a5: 0x178f, 0x16a6: 0x10f2, 0x16a7: 0x0652, 0x16a8: 0x1102, 0x16a9: 0x10fa,
- 0x16aa: 0x110a, 0x16ab: 0x1799, 0x16ac: 0x1122, 0x16ad: 0x0656, 0x16ae: 0x112e, 0x16af: 0x1136,
- 0x16b0: 0x1146, 0x16b1: 0x065a, 0x16b2: 0x17a3, 0x16b3: 0x17a8, 0x16b4: 0x065e, 0x16b5: 0x17ad,
- 0x16b6: 0x115e, 0x16b7: 0x17b2, 0x16b8: 0x116a, 0x16b9: 0x1176, 0x16ba: 0x117e, 0x16bb: 0x17b7,
- 0x16bc: 0x17bc, 0x16bd: 0x1192, 0x16be: 0x17c1, 0x16bf: 0x119a,
- // Block 0x5b, offset 0x16c0
- 0x16c0: 0x16d1, 0x16c1: 0x0662, 0x16c2: 0x11b2, 0x16c3: 0x11b6, 0x16c4: 0x066a, 0x16c5: 0x11ba,
- 0x16c6: 0x0a36, 0x16c7: 0x17c6, 0x16c8: 0x17cb, 0x16c9: 0x16d6, 0x16ca: 0x16db, 0x16cb: 0x11da,
- 0x16cc: 0x11de, 0x16cd: 0x13f6, 0x16ce: 0x066e, 0x16cf: 0x120a, 0x16d0: 0x1206, 0x16d1: 0x120e,
- 0x16d2: 0x0842, 0x16d3: 0x1212, 0x16d4: 0x1216, 0x16d5: 0x121a, 0x16d6: 0x1222, 0x16d7: 0x17d0,
- 0x16d8: 0x121e, 0x16d9: 0x1226, 0x16da: 0x123a, 0x16db: 0x123e, 0x16dc: 0x122a, 0x16dd: 0x1242,
- 0x16de: 0x1256, 0x16df: 0x126a, 0x16e0: 0x1236, 0x16e1: 0x124a, 0x16e2: 0x124e, 0x16e3: 0x1252,
- 0x16e4: 0x17d5, 0x16e5: 0x17df, 0x16e6: 0x17da, 0x16e7: 0x0672, 0x16e8: 0x1272, 0x16e9: 0x1276,
- 0x16ea: 0x127e, 0x16eb: 0x17f3, 0x16ec: 0x1282, 0x16ed: 0x17e4, 0x16ee: 0x0676, 0x16ef: 0x067a,
- 0x16f0: 0x17e9, 0x16f1: 0x17ee, 0x16f2: 0x067e, 0x16f3: 0x12a2, 0x16f4: 0x12a6, 0x16f5: 0x12aa,
- 0x16f6: 0x12ae, 0x16f7: 0x12ba, 0x16f8: 0x12b6, 0x16f9: 0x12c2, 0x16fa: 0x12be, 0x16fb: 0x12ce,
- 0x16fc: 0x12c6, 0x16fd: 0x12ca, 0x16fe: 0x12d2, 0x16ff: 0x0682,
- // Block 0x5c, offset 0x1700
- 0x1700: 0x12da, 0x1701: 0x12de, 0x1702: 0x0686, 0x1703: 0x12ee, 0x1704: 0x12f2, 0x1705: 0x17f8,
- 0x1706: 0x12fe, 0x1707: 0x1302, 0x1708: 0x068a, 0x1709: 0x130e, 0x170a: 0x05be, 0x170b: 0x17fd,
- 0x170c: 0x1802, 0x170d: 0x068e, 0x170e: 0x0692, 0x170f: 0x133a, 0x1710: 0x1352, 0x1711: 0x136e,
- 0x1712: 0x137e, 0x1713: 0x1807, 0x1714: 0x1392, 0x1715: 0x1396, 0x1716: 0x13ae, 0x1717: 0x13ba,
- 0x1718: 0x1811, 0x1719: 0x1663, 0x171a: 0x13c6, 0x171b: 0x13c2, 0x171c: 0x13ce, 0x171d: 0x1668,
- 0x171e: 0x13da, 0x171f: 0x13e6, 0x1720: 0x1816, 0x1721: 0x181b, 0x1722: 0x1426, 0x1723: 0x1432,
- 0x1724: 0x143a, 0x1725: 0x1820, 0x1726: 0x143e, 0x1727: 0x146a, 0x1728: 0x1476, 0x1729: 0x147a,
- 0x172a: 0x1472, 0x172b: 0x1486, 0x172c: 0x148a, 0x172d: 0x1825, 0x172e: 0x1496, 0x172f: 0x0696,
- 0x1730: 0x149e, 0x1731: 0x182a, 0x1732: 0x069a, 0x1733: 0x14d6, 0x1734: 0x0ac6, 0x1735: 0x14ee,
- 0x1736: 0x182f, 0x1737: 0x1839, 0x1738: 0x069e, 0x1739: 0x06a2, 0x173a: 0x1516, 0x173b: 0x183e,
- 0x173c: 0x06a6, 0x173d: 0x1843, 0x173e: 0x152e, 0x173f: 0x152e,
- // Block 0x5d, offset 0x1740
- 0x1740: 0x1536, 0x1741: 0x1848, 0x1742: 0x154e, 0x1743: 0x06aa, 0x1744: 0x155e, 0x1745: 0x156a,
- 0x1746: 0x1572, 0x1747: 0x157a, 0x1748: 0x06ae, 0x1749: 0x184d, 0x174a: 0x158e, 0x174b: 0x15aa,
- 0x174c: 0x15b6, 0x174d: 0x06b2, 0x174e: 0x06b6, 0x174f: 0x15ba, 0x1750: 0x1852, 0x1751: 0x06ba,
- 0x1752: 0x1857, 0x1753: 0x185c, 0x1754: 0x1861, 0x1755: 0x15de, 0x1756: 0x06be, 0x1757: 0x15f2,
- 0x1758: 0x15fa, 0x1759: 0x15fe, 0x175a: 0x1606, 0x175b: 0x160e, 0x175c: 0x1616, 0x175d: 0x186b,
-}
-
-// nfkcIndex: 22 blocks, 1408 entries, 2816 bytes
-// Block 0 is the zero block.
-var nfkcIndex = [1408]uint16{
- // Block 0x0, offset 0x0
- // Block 0x1, offset 0x40
- // Block 0x2, offset 0x80
- // Block 0x3, offset 0xc0
- 0xc2: 0x5c, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x5d, 0xc7: 0x04,
- 0xc8: 0x05, 0xca: 0x5e, 0xcb: 0x5f, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x09,
- 0xd0: 0x0a, 0xd1: 0x60, 0xd2: 0x61, 0xd3: 0x0b, 0xd6: 0x0c, 0xd7: 0x62,
- 0xd8: 0x63, 0xd9: 0x0d, 0xdb: 0x64, 0xdc: 0x65, 0xdd: 0x66, 0xdf: 0x67,
- 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05,
- 0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a,
- 0xf0: 0x13,
- // Block 0x4, offset 0x100
- 0x120: 0x68, 0x121: 0x69, 0x123: 0x0e, 0x124: 0x6a, 0x125: 0x6b, 0x126: 0x6c, 0x127: 0x6d,
- 0x128: 0x6e, 0x129: 0x6f, 0x12a: 0x70, 0x12b: 0x71, 0x12c: 0x6c, 0x12d: 0x72, 0x12e: 0x73, 0x12f: 0x74,
- 0x131: 0x75, 0x132: 0x76, 0x133: 0x77, 0x134: 0x78, 0x135: 0x79, 0x137: 0x7a,
- 0x138: 0x7b, 0x139: 0x7c, 0x13a: 0x7d, 0x13b: 0x7e, 0x13c: 0x7f, 0x13d: 0x80, 0x13e: 0x81, 0x13f: 0x82,
- // Block 0x5, offset 0x140
- 0x140: 0x83, 0x142: 0x84, 0x143: 0x85, 0x144: 0x86, 0x145: 0x87, 0x146: 0x88, 0x147: 0x89,
- 0x14d: 0x8a,
- 0x15c: 0x8b, 0x15f: 0x8c,
- 0x162: 0x8d, 0x164: 0x8e,
- 0x168: 0x8f, 0x169: 0x90, 0x16a: 0x91, 0x16b: 0x92, 0x16c: 0x0f, 0x16d: 0x93, 0x16e: 0x94, 0x16f: 0x95,
- 0x170: 0x96, 0x173: 0x97, 0x174: 0x98, 0x175: 0x10, 0x176: 0x11, 0x177: 0x12,
- 0x178: 0x13, 0x179: 0x14, 0x17a: 0x15, 0x17b: 0x16, 0x17c: 0x17, 0x17d: 0x18, 0x17e: 0x19, 0x17f: 0x1a,
- // Block 0x6, offset 0x180
- 0x180: 0x99, 0x181: 0x9a, 0x182: 0x9b, 0x183: 0x9c, 0x184: 0x1b, 0x185: 0x1c, 0x186: 0x9d, 0x187: 0x9e,
- 0x188: 0x9f, 0x189: 0x1d, 0x18a: 0x1e, 0x18b: 0xa0, 0x18c: 0xa1,
- 0x191: 0x1f, 0x192: 0x20, 0x193: 0xa2,
- 0x1a8: 0xa3, 0x1a9: 0xa4, 0x1ab: 0xa5,
- 0x1b1: 0xa6, 0x1b3: 0xa7, 0x1b5: 0xa8, 0x1b7: 0xa9,
- 0x1ba: 0xaa, 0x1bb: 0xab, 0x1bc: 0x21, 0x1bd: 0x22, 0x1be: 0x23, 0x1bf: 0xac,
- // Block 0x7, offset 0x1c0
- 0x1c0: 0xad, 0x1c1: 0x24, 0x1c2: 0x25, 0x1c3: 0x26, 0x1c4: 0xae, 0x1c5: 0x27, 0x1c6: 0x28,
- 0x1c8: 0x29, 0x1c9: 0x2a, 0x1ca: 0x2b, 0x1cb: 0x2c, 0x1cc: 0x2d, 0x1cd: 0x2e, 0x1ce: 0x2f, 0x1cf: 0x30,
- // Block 0x8, offset 0x200
- 0x219: 0xaf, 0x21a: 0xb0, 0x21b: 0xb1, 0x21d: 0xb2, 0x21f: 0xb3,
- 0x220: 0xb4, 0x223: 0xb5, 0x224: 0xb6, 0x225: 0xb7, 0x226: 0xb8, 0x227: 0xb9,
- 0x22a: 0xba, 0x22b: 0xbb, 0x22d: 0xbc, 0x22f: 0xbd,
- 0x230: 0xbe, 0x231: 0xbf, 0x232: 0xc0, 0x233: 0xc1, 0x234: 0xc2, 0x235: 0xc3, 0x236: 0xc4, 0x237: 0xbe,
- 0x238: 0xbf, 0x239: 0xc0, 0x23a: 0xc1, 0x23b: 0xc2, 0x23c: 0xc3, 0x23d: 0xc4, 0x23e: 0xbe, 0x23f: 0xbf,
- // Block 0x9, offset 0x240
- 0x240: 0xc0, 0x241: 0xc1, 0x242: 0xc2, 0x243: 0xc3, 0x244: 0xc4, 0x245: 0xbe, 0x246: 0xbf, 0x247: 0xc0,
- 0x248: 0xc1, 0x249: 0xc2, 0x24a: 0xc3, 0x24b: 0xc4, 0x24c: 0xbe, 0x24d: 0xbf, 0x24e: 0xc0, 0x24f: 0xc1,
- 0x250: 0xc2, 0x251: 0xc3, 0x252: 0xc4, 0x253: 0xbe, 0x254: 0xbf, 0x255: 0xc0, 0x256: 0xc1, 0x257: 0xc2,
- 0x258: 0xc3, 0x259: 0xc4, 0x25a: 0xbe, 0x25b: 0xbf, 0x25c: 0xc0, 0x25d: 0xc1, 0x25e: 0xc2, 0x25f: 0xc3,
- 0x260: 0xc4, 0x261: 0xbe, 0x262: 0xbf, 0x263: 0xc0, 0x264: 0xc1, 0x265: 0xc2, 0x266: 0xc3, 0x267: 0xc4,
- 0x268: 0xbe, 0x269: 0xbf, 0x26a: 0xc0, 0x26b: 0xc1, 0x26c: 0xc2, 0x26d: 0xc3, 0x26e: 0xc4, 0x26f: 0xbe,
- 0x270: 0xbf, 0x271: 0xc0, 0x272: 0xc1, 0x273: 0xc2, 0x274: 0xc3, 0x275: 0xc4, 0x276: 0xbe, 0x277: 0xbf,
- 0x278: 0xc0, 0x279: 0xc1, 0x27a: 0xc2, 0x27b: 0xc3, 0x27c: 0xc4, 0x27d: 0xbe, 0x27e: 0xbf, 0x27f: 0xc0,
- // Block 0xa, offset 0x280
- 0x280: 0xc1, 0x281: 0xc2, 0x282: 0xc3, 0x283: 0xc4, 0x284: 0xbe, 0x285: 0xbf, 0x286: 0xc0, 0x287: 0xc1,
- 0x288: 0xc2, 0x289: 0xc3, 0x28a: 0xc4, 0x28b: 0xbe, 0x28c: 0xbf, 0x28d: 0xc0, 0x28e: 0xc1, 0x28f: 0xc2,
- 0x290: 0xc3, 0x291: 0xc4, 0x292: 0xbe, 0x293: 0xbf, 0x294: 0xc0, 0x295: 0xc1, 0x296: 0xc2, 0x297: 0xc3,
- 0x298: 0xc4, 0x299: 0xbe, 0x29a: 0xbf, 0x29b: 0xc0, 0x29c: 0xc1, 0x29d: 0xc2, 0x29e: 0xc3, 0x29f: 0xc4,
- 0x2a0: 0xbe, 0x2a1: 0xbf, 0x2a2: 0xc0, 0x2a3: 0xc1, 0x2a4: 0xc2, 0x2a5: 0xc3, 0x2a6: 0xc4, 0x2a7: 0xbe,
- 0x2a8: 0xbf, 0x2a9: 0xc0, 0x2aa: 0xc1, 0x2ab: 0xc2, 0x2ac: 0xc3, 0x2ad: 0xc4, 0x2ae: 0xbe, 0x2af: 0xbf,
- 0x2b0: 0xc0, 0x2b1: 0xc1, 0x2b2: 0xc2, 0x2b3: 0xc3, 0x2b4: 0xc4, 0x2b5: 0xbe, 0x2b6: 0xbf, 0x2b7: 0xc0,
- 0x2b8: 0xc1, 0x2b9: 0xc2, 0x2ba: 0xc3, 0x2bb: 0xc4, 0x2bc: 0xbe, 0x2bd: 0xbf, 0x2be: 0xc0, 0x2bf: 0xc1,
- // Block 0xb, offset 0x2c0
- 0x2c0: 0xc2, 0x2c1: 0xc3, 0x2c2: 0xc4, 0x2c3: 0xbe, 0x2c4: 0xbf, 0x2c5: 0xc0, 0x2c6: 0xc1, 0x2c7: 0xc2,
- 0x2c8: 0xc3, 0x2c9: 0xc4, 0x2ca: 0xbe, 0x2cb: 0xbf, 0x2cc: 0xc0, 0x2cd: 0xc1, 0x2ce: 0xc2, 0x2cf: 0xc3,
- 0x2d0: 0xc4, 0x2d1: 0xbe, 0x2d2: 0xbf, 0x2d3: 0xc0, 0x2d4: 0xc1, 0x2d5: 0xc2, 0x2d6: 0xc3, 0x2d7: 0xc4,
- 0x2d8: 0xbe, 0x2d9: 0xbf, 0x2da: 0xc0, 0x2db: 0xc1, 0x2dc: 0xc2, 0x2dd: 0xc3, 0x2de: 0xc5,
- // Block 0xc, offset 0x300
- 0x324: 0x31, 0x325: 0x32, 0x326: 0x33, 0x327: 0x34,
- 0x328: 0x35, 0x329: 0x36, 0x32a: 0x37, 0x32b: 0x38, 0x32c: 0x39, 0x32d: 0x3a, 0x32e: 0x3b, 0x32f: 0x3c,
- 0x330: 0x3d, 0x331: 0x3e, 0x332: 0x3f, 0x333: 0x40, 0x334: 0x41, 0x335: 0x42, 0x336: 0x43, 0x337: 0x44,
- 0x338: 0x45, 0x339: 0x46, 0x33a: 0x47, 0x33b: 0x48, 0x33c: 0xc6, 0x33d: 0x49, 0x33e: 0x4a, 0x33f: 0x4b,
- // Block 0xd, offset 0x340
- 0x347: 0xc7,
- 0x34b: 0xc8, 0x34d: 0xc9,
- 0x368: 0xca, 0x36b: 0xcb,
- 0x374: 0xcc,
- 0x37a: 0xcd, 0x37d: 0xce,
- // Block 0xe, offset 0x380
- 0x381: 0xcf, 0x382: 0xd0, 0x384: 0xd1, 0x385: 0xb8, 0x387: 0xd2,
- 0x388: 0xd3, 0x38b: 0xd4, 0x38c: 0xd5, 0x38d: 0xd6,
- 0x391: 0xd7, 0x392: 0xd8, 0x393: 0xd9, 0x396: 0xda, 0x397: 0xdb,
- 0x398: 0xdc, 0x39a: 0xdd, 0x39c: 0xde,
- 0x3a0: 0xdf, 0x3a4: 0xe0, 0x3a5: 0xe1, 0x3a7: 0xe2,
- 0x3a8: 0xe3, 0x3a9: 0xe4, 0x3aa: 0xe5,
- 0x3b0: 0xdc, 0x3b5: 0xe6, 0x3b6: 0xe7,
- // Block 0xf, offset 0x3c0
- 0x3eb: 0xe8, 0x3ec: 0xe9,
- 0x3ff: 0xea,
- // Block 0x10, offset 0x400
- 0x432: 0xeb,
- // Block 0x11, offset 0x440
- 0x445: 0xec, 0x446: 0xed, 0x447: 0xee,
- 0x449: 0xef,
- 0x450: 0xf0, 0x451: 0xf1, 0x452: 0xf2, 0x453: 0xf3, 0x454: 0xf4, 0x455: 0xf5, 0x456: 0xf6, 0x457: 0xf7,
- 0x458: 0xf8, 0x459: 0xf9, 0x45a: 0x4c, 0x45b: 0xfa, 0x45c: 0xfb, 0x45d: 0xfc, 0x45e: 0xfd, 0x45f: 0x4d,
- // Block 0x12, offset 0x480
- 0x480: 0xfe, 0x484: 0xe9,
- 0x48b: 0xff,
- 0x4a3: 0x100, 0x4a5: 0x101,
- 0x4b8: 0x4e, 0x4b9: 0x4f, 0x4ba: 0x50,
- // Block 0x13, offset 0x4c0
- 0x4c4: 0x51, 0x4c5: 0x102, 0x4c6: 0x103,
- 0x4c8: 0x52, 0x4c9: 0x104,
- 0x4ef: 0x105,
- // Block 0x14, offset 0x500
- 0x520: 0x53, 0x521: 0x54, 0x522: 0x55, 0x523: 0x56, 0x524: 0x57, 0x525: 0x58, 0x526: 0x59, 0x527: 0x5a,
- 0x528: 0x5b,
- // Block 0x15, offset 0x540
- 0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d,
- 0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11,
- 0x56f: 0x12,
-}
-
-// nfkcSparseOffset: 170 entries, 340 bytes
-var nfkcSparseOffset = []uint16{0x0, 0xe, 0x12, 0x1b, 0x25, 0x35, 0x37, 0x3c, 0x47, 0x56, 0x63, 0x6b, 0x70, 0x75, 0x77, 0x7f, 0x86, 0x89, 0x91, 0x95, 0x99, 0x9b, 0x9d, 0xa6, 0xaa, 0xb1, 0xb6, 0xb9, 0xc3, 0xc6, 0xcd, 0xd5, 0xd9, 0xdb, 0xdf, 0xe3, 0xe9, 0xfa, 0x106, 0x108, 0x10e, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11a, 0x11c, 0x11f, 0x122, 0x124, 0x127, 0x12a, 0x12e, 0x134, 0x136, 0x13f, 0x141, 0x144, 0x146, 0x151, 0x15c, 0x16a, 0x178, 0x188, 0x196, 0x19d, 0x1a3, 0x1b2, 0x1b6, 0x1b8, 0x1bc, 0x1be, 0x1c1, 0x1c3, 0x1c6, 0x1c8, 0x1cb, 0x1cd, 0x1cf, 0x1d1, 0x1dd, 0x1e7, 0x1f1, 0x1f4, 0x1f8, 0x1fa, 0x1fc, 0x1fe, 0x201, 0x204, 0x206, 0x208, 0x20a, 0x20c, 0x212, 0x215, 0x21a, 0x21c, 0x223, 0x229, 0x22f, 0x237, 0x23d, 0x243, 0x249, 0x24d, 0x24f, 0x251, 0x253, 0x255, 0x25b, 0x25e, 0x260, 0x262, 0x268, 0x26b, 0x273, 0x27a, 0x27d, 0x280, 0x282, 0x285, 0x28d, 0x291, 0x298, 0x29b, 0x2a1, 0x2a3, 0x2a5, 0x2a8, 0x2aa, 0x2ad, 0x2b2, 0x2b4, 0x2b6, 0x2b8, 0x2ba, 0x2bc, 0x2bf, 0x2c1, 0x2c3, 0x2c5, 0x2c7, 0x2c9, 0x2d6, 0x2e0, 0x2e2, 0x2e4, 0x2e8, 0x2ed, 0x2f9, 0x2fe, 0x307, 0x30d, 0x312, 0x316, 0x31b, 0x31f, 0x32f, 0x33d, 0x34b, 0x359, 0x35f, 0x361, 0x363, 0x366, 0x371, 0x373, 0x37d}
-
-// nfkcSparseValues: 895 entries, 3580 bytes
-var nfkcSparseValues = [895]valueRange{
- // Block 0x0, offset 0x0
- {value: 0x0002, lo: 0x0d},
- {value: 0x0001, lo: 0xa0, hi: 0xa0},
- {value: 0x428f, lo: 0xa8, hi: 0xa8},
- {value: 0x0083, lo: 0xaa, hi: 0xaa},
- {value: 0x427b, lo: 0xaf, hi: 0xaf},
- {value: 0x0025, lo: 0xb2, hi: 0xb3},
- {value: 0x4271, lo: 0xb4, hi: 0xb4},
- {value: 0x01df, lo: 0xb5, hi: 0xb5},
- {value: 0x42a8, lo: 0xb8, hi: 0xb8},
- {value: 0x0023, lo: 0xb9, hi: 0xb9},
- {value: 0x009f, lo: 0xba, hi: 0xba},
- {value: 0x2222, lo: 0xbc, hi: 0xbc},
- {value: 0x2216, lo: 0xbd, hi: 0xbd},
- {value: 0x22b8, lo: 0xbe, hi: 0xbe},
- // Block 0x1, offset 0xe
- {value: 0x0091, lo: 0x03},
- {value: 0x46f9, lo: 0xa0, hi: 0xa1},
- {value: 0x472b, lo: 0xaf, hi: 0xb0},
- {value: 0xa000, lo: 0xb7, hi: 0xb7},
- // Block 0x2, offset 0x12
- {value: 0x0003, lo: 0x08},
- {value: 0xa000, lo: 0x92, hi: 0x92},
- {value: 0x0091, lo: 0xb0, hi: 0xb0},
- {value: 0x0119, lo: 0xb1, hi: 0xb1},
- {value: 0x0095, lo: 0xb2, hi: 0xb2},
- {value: 0x00a5, lo: 0xb3, hi: 0xb3},
- {value: 0x0143, lo: 0xb4, hi: 0xb6},
- {value: 0x00af, lo: 0xb7, hi: 0xb7},
- {value: 0x00b3, lo: 0xb8, hi: 0xb8},
- // Block 0x3, offset 0x1b
- {value: 0x000a, lo: 0x09},
- {value: 0x4285, lo: 0x98, hi: 0x98},
- {value: 0x428a, lo: 0x99, hi: 0x9a},
- {value: 0x42ad, lo: 0x9b, hi: 0x9b},
- {value: 0x4276, lo: 0x9c, hi: 0x9c},
- {value: 0x4299, lo: 0x9d, hi: 0x9d},
- {value: 0x0113, lo: 0xa0, hi: 0xa0},
- {value: 0x0099, lo: 0xa1, hi: 0xa1},
- {value: 0x00a7, lo: 0xa2, hi: 0xa3},
- {value: 0x016a, lo: 0xa4, hi: 0xa4},
- // Block 0x4, offset 0x25
- {value: 0x0000, lo: 0x0f},
- {value: 0xa000, lo: 0x83, hi: 0x83},
- {value: 0xa000, lo: 0x87, hi: 0x87},
- {value: 0xa000, lo: 0x8b, hi: 0x8b},
- {value: 0xa000, lo: 0x8d, hi: 0x8d},
- {value: 0x37bc, lo: 0x90, hi: 0x90},
- {value: 0x37c8, lo: 0x91, hi: 0x91},
- {value: 0x37b6, lo: 0x93, hi: 0x93},
- {value: 0xa000, lo: 0x96, hi: 0x96},
- {value: 0x382e, lo: 0x97, hi: 0x97},
- {value: 0x37f8, lo: 0x9c, hi: 0x9c},
- {value: 0x37e0, lo: 0x9d, hi: 0x9d},
- {value: 0x380a, lo: 0x9e, hi: 0x9e},
- {value: 0xa000, lo: 0xb4, hi: 0xb5},
- {value: 0x3834, lo: 0xb6, hi: 0xb6},
- {value: 0x383a, lo: 0xb7, hi: 0xb7},
- // Block 0x5, offset 0x35
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0x83, hi: 0x87},
- // Block 0x6, offset 0x37
- {value: 0x0001, lo: 0x04},
- {value: 0x8114, lo: 0x81, hi: 0x82},
- {value: 0x8133, lo: 0x84, hi: 0x84},
- {value: 0x812e, lo: 0x85, hi: 0x85},
- {value: 0x810e, lo: 0x87, hi: 0x87},
- // Block 0x7, offset 0x3c
- {value: 0x0000, lo: 0x0a},
- {value: 0x8133, lo: 0x90, hi: 0x97},
- {value: 0x811a, lo: 0x98, hi: 0x98},
- {value: 0x811b, lo: 0x99, hi: 0x99},
- {value: 0x811c, lo: 0x9a, hi: 0x9a},
- {value: 0x3858, lo: 0xa2, hi: 0xa2},
- {value: 0x385e, lo: 0xa3, hi: 0xa3},
- {value: 0x386a, lo: 0xa4, hi: 0xa4},
- {value: 0x3864, lo: 0xa5, hi: 0xa5},
- {value: 0x3870, lo: 0xa6, hi: 0xa6},
- {value: 0xa000, lo: 0xa7, hi: 0xa7},
- // Block 0x8, offset 0x47
- {value: 0x0000, lo: 0x0e},
- {value: 0x3882, lo: 0x80, hi: 0x80},
- {value: 0xa000, lo: 0x81, hi: 0x81},
- {value: 0x3876, lo: 0x82, hi: 0x82},
- {value: 0xa000, lo: 0x92, hi: 0x92},
- {value: 0x387c, lo: 0x93, hi: 0x93},
- {value: 0xa000, lo: 0x95, hi: 0x95},
- {value: 0x8133, lo: 0x96, hi: 0x9c},
- {value: 0x8133, lo: 0x9f, hi: 0xa2},
- {value: 0x812e, lo: 0xa3, hi: 0xa3},
- {value: 0x8133, lo: 0xa4, hi: 0xa4},
- {value: 0x8133, lo: 0xa7, hi: 0xa8},
- {value: 0x812e, lo: 0xaa, hi: 0xaa},
- {value: 0x8133, lo: 0xab, hi: 0xac},
- {value: 0x812e, lo: 0xad, hi: 0xad},
- // Block 0x9, offset 0x56
- {value: 0x0000, lo: 0x0c},
- {value: 0x8120, lo: 0x91, hi: 0x91},
- {value: 0x8133, lo: 0xb0, hi: 0xb0},
- {value: 0x812e, lo: 0xb1, hi: 0xb1},
- {value: 0x8133, lo: 0xb2, hi: 0xb3},
- {value: 0x812e, lo: 0xb4, hi: 0xb4},
- {value: 0x8133, lo: 0xb5, hi: 0xb6},
- {value: 0x812e, lo: 0xb7, hi: 0xb9},
- {value: 0x8133, lo: 0xba, hi: 0xba},
- {value: 0x812e, lo: 0xbb, hi: 0xbc},
- {value: 0x8133, lo: 0xbd, hi: 0xbd},
- {value: 0x812e, lo: 0xbe, hi: 0xbe},
- {value: 0x8133, lo: 0xbf, hi: 0xbf},
- // Block 0xa, offset 0x63
- {value: 0x0005, lo: 0x07},
- {value: 0x8133, lo: 0x80, hi: 0x80},
- {value: 0x8133, lo: 0x81, hi: 0x81},
- {value: 0x812e, lo: 0x82, hi: 0x83},
- {value: 0x812e, lo: 0x84, hi: 0x85},
- {value: 0x812e, lo: 0x86, hi: 0x87},
- {value: 0x812e, lo: 0x88, hi: 0x89},
- {value: 0x8133, lo: 0x8a, hi: 0x8a},
- // Block 0xb, offset 0x6b
- {value: 0x0000, lo: 0x04},
- {value: 0x8133, lo: 0xab, hi: 0xb1},
- {value: 0x812e, lo: 0xb2, hi: 0xb2},
- {value: 0x8133, lo: 0xb3, hi: 0xb3},
- {value: 0x812e, lo: 0xbd, hi: 0xbd},
- // Block 0xc, offset 0x70
- {value: 0x0000, lo: 0x04},
- {value: 0x8133, lo: 0x96, hi: 0x99},
- {value: 0x8133, lo: 0x9b, hi: 0xa3},
- {value: 0x8133, lo: 0xa5, hi: 0xa7},
- {value: 0x8133, lo: 0xa9, hi: 0xad},
- // Block 0xd, offset 0x75
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0x99, hi: 0x9b},
- // Block 0xe, offset 0x77
- {value: 0x0000, lo: 0x07},
- {value: 0xa000, lo: 0xa8, hi: 0xa8},
- {value: 0x3eef, lo: 0xa9, hi: 0xa9},
- {value: 0xa000, lo: 0xb0, hi: 0xb0},
- {value: 0x3ef7, lo: 0xb1, hi: 0xb1},
- {value: 0xa000, lo: 0xb3, hi: 0xb3},
- {value: 0x3eff, lo: 0xb4, hi: 0xb4},
- {value: 0x9903, lo: 0xbc, hi: 0xbc},
- // Block 0xf, offset 0x7f
- {value: 0x0008, lo: 0x06},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x8133, lo: 0x91, hi: 0x91},
- {value: 0x812e, lo: 0x92, hi: 0x92},
- {value: 0x8133, lo: 0x93, hi: 0x93},
- {value: 0x8133, lo: 0x94, hi: 0x94},
- {value: 0x4533, lo: 0x98, hi: 0x9f},
- // Block 0x10, offset 0x86
- {value: 0x0000, lo: 0x02},
- {value: 0x8103, lo: 0xbc, hi: 0xbc},
- {value: 0x9900, lo: 0xbe, hi: 0xbe},
- // Block 0x11, offset 0x89
- {value: 0x0008, lo: 0x07},
- {value: 0xa000, lo: 0x87, hi: 0x87},
- {value: 0x2cab, lo: 0x8b, hi: 0x8c},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x9900, lo: 0x97, hi: 0x97},
- {value: 0x4573, lo: 0x9c, hi: 0x9d},
- {value: 0x4583, lo: 0x9f, hi: 0x9f},
- {value: 0x8133, lo: 0xbe, hi: 0xbe},
- // Block 0x12, offset 0x91
- {value: 0x0000, lo: 0x03},
- {value: 0x45ab, lo: 0xb3, hi: 0xb3},
- {value: 0x45b3, lo: 0xb6, hi: 0xb6},
- {value: 0x8103, lo: 0xbc, hi: 0xbc},
- // Block 0x13, offset 0x95
- {value: 0x0008, lo: 0x03},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x458b, lo: 0x99, hi: 0x9b},
- {value: 0x45a3, lo: 0x9e, hi: 0x9e},
- // Block 0x14, offset 0x99
- {value: 0x0000, lo: 0x01},
- {value: 0x8103, lo: 0xbc, hi: 0xbc},
- // Block 0x15, offset 0x9b
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- // Block 0x16, offset 0x9d
- {value: 0x0000, lo: 0x08},
- {value: 0xa000, lo: 0x87, hi: 0x87},
- {value: 0x2cc3, lo: 0x88, hi: 0x88},
- {value: 0x2cbb, lo: 0x8b, hi: 0x8b},
- {value: 0x2ccb, lo: 0x8c, hi: 0x8c},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x9900, lo: 0x96, hi: 0x97},
- {value: 0x45bb, lo: 0x9c, hi: 0x9c},
- {value: 0x45c3, lo: 0x9d, hi: 0x9d},
- // Block 0x17, offset 0xa6
- {value: 0x0000, lo: 0x03},
- {value: 0xa000, lo: 0x92, hi: 0x92},
- {value: 0x2cd3, lo: 0x94, hi: 0x94},
- {value: 0x9900, lo: 0xbe, hi: 0xbe},
- // Block 0x18, offset 0xaa
- {value: 0x0000, lo: 0x06},
- {value: 0xa000, lo: 0x86, hi: 0x87},
- {value: 0x2cdb, lo: 0x8a, hi: 0x8a},
- {value: 0x2ceb, lo: 0x8b, hi: 0x8b},
- {value: 0x2ce3, lo: 0x8c, hi: 0x8c},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x9900, lo: 0x97, hi: 0x97},
- // Block 0x19, offset 0xb1
- {value: 0x1801, lo: 0x04},
- {value: 0xa000, lo: 0x86, hi: 0x86},
- {value: 0x3f07, lo: 0x88, hi: 0x88},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x8121, lo: 0x95, hi: 0x96},
- // Block 0x1a, offset 0xb6
- {value: 0x0000, lo: 0x02},
- {value: 0x8103, lo: 0xbc, hi: 0xbc},
- {value: 0xa000, lo: 0xbf, hi: 0xbf},
- // Block 0x1b, offset 0xb9
- {value: 0x0000, lo: 0x09},
- {value: 0x2cf3, lo: 0x80, hi: 0x80},
- {value: 0x9900, lo: 0x82, hi: 0x82},
- {value: 0xa000, lo: 0x86, hi: 0x86},
- {value: 0x2cfb, lo: 0x87, hi: 0x87},
- {value: 0x2d03, lo: 0x88, hi: 0x88},
- {value: 0x2f67, lo: 0x8a, hi: 0x8a},
- {value: 0x2def, lo: 0x8b, hi: 0x8b},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x9900, lo: 0x95, hi: 0x96},
- // Block 0x1c, offset 0xc3
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0xbb, hi: 0xbc},
- {value: 0x9900, lo: 0xbe, hi: 0xbe},
- // Block 0x1d, offset 0xc6
- {value: 0x0000, lo: 0x06},
- {value: 0xa000, lo: 0x86, hi: 0x87},
- {value: 0x2d0b, lo: 0x8a, hi: 0x8a},
- {value: 0x2d1b, lo: 0x8b, hi: 0x8b},
- {value: 0x2d13, lo: 0x8c, hi: 0x8c},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x9900, lo: 0x97, hi: 0x97},
- // Block 0x1e, offset 0xcd
- {value: 0x6bdd, lo: 0x07},
- {value: 0x9905, lo: 0x8a, hi: 0x8a},
- {value: 0x9900, lo: 0x8f, hi: 0x8f},
- {value: 0xa000, lo: 0x99, hi: 0x99},
- {value: 0x3f0f, lo: 0x9a, hi: 0x9a},
- {value: 0x2f6f, lo: 0x9c, hi: 0x9c},
- {value: 0x2dfa, lo: 0x9d, hi: 0x9d},
- {value: 0x2d23, lo: 0x9e, hi: 0x9f},
- // Block 0x1f, offset 0xd5
- {value: 0x0000, lo: 0x03},
- {value: 0x2627, lo: 0xb3, hi: 0xb3},
- {value: 0x8123, lo: 0xb8, hi: 0xb9},
- {value: 0x8105, lo: 0xba, hi: 0xba},
- // Block 0x20, offset 0xd9
- {value: 0x0000, lo: 0x01},
- {value: 0x8124, lo: 0x88, hi: 0x8b},
- // Block 0x21, offset 0xdb
- {value: 0x0000, lo: 0x03},
- {value: 0x263c, lo: 0xb3, hi: 0xb3},
- {value: 0x8125, lo: 0xb8, hi: 0xb9},
- {value: 0x8105, lo: 0xba, hi: 0xba},
- // Block 0x22, offset 0xdf
- {value: 0x0000, lo: 0x03},
- {value: 0x8126, lo: 0x88, hi: 0x8b},
- {value: 0x262e, lo: 0x9c, hi: 0x9c},
- {value: 0x2635, lo: 0x9d, hi: 0x9d},
- // Block 0x23, offset 0xe3
- {value: 0x0000, lo: 0x05},
- {value: 0x030e, lo: 0x8c, hi: 0x8c},
- {value: 0x812e, lo: 0x98, hi: 0x99},
- {value: 0x812e, lo: 0xb5, hi: 0xb5},
- {value: 0x812e, lo: 0xb7, hi: 0xb7},
- {value: 0x812c, lo: 0xb9, hi: 0xb9},
- // Block 0x24, offset 0xe9
- {value: 0x0000, lo: 0x10},
- {value: 0x264a, lo: 0x83, hi: 0x83},
- {value: 0x2651, lo: 0x8d, hi: 0x8d},
- {value: 0x2658, lo: 0x92, hi: 0x92},
- {value: 0x265f, lo: 0x97, hi: 0x97},
- {value: 0x2666, lo: 0x9c, hi: 0x9c},
- {value: 0x2643, lo: 0xa9, hi: 0xa9},
- {value: 0x8127, lo: 0xb1, hi: 0xb1},
- {value: 0x8128, lo: 0xb2, hi: 0xb2},
- {value: 0x4a9b, lo: 0xb3, hi: 0xb3},
- {value: 0x8129, lo: 0xb4, hi: 0xb4},
- {value: 0x4aa4, lo: 0xb5, hi: 0xb5},
- {value: 0x45cb, lo: 0xb6, hi: 0xb6},
- {value: 0x460b, lo: 0xb7, hi: 0xb7},
- {value: 0x45d3, lo: 0xb8, hi: 0xb8},
- {value: 0x4616, lo: 0xb9, hi: 0xb9},
- {value: 0x8128, lo: 0xba, hi: 0xbd},
- // Block 0x25, offset 0xfa
- {value: 0x0000, lo: 0x0b},
- {value: 0x8128, lo: 0x80, hi: 0x80},
- {value: 0x4aad, lo: 0x81, hi: 0x81},
- {value: 0x8133, lo: 0x82, hi: 0x83},
- {value: 0x8105, lo: 0x84, hi: 0x84},
- {value: 0x8133, lo: 0x86, hi: 0x87},
- {value: 0x2674, lo: 0x93, hi: 0x93},
- {value: 0x267b, lo: 0x9d, hi: 0x9d},
- {value: 0x2682, lo: 0xa2, hi: 0xa2},
- {value: 0x2689, lo: 0xa7, hi: 0xa7},
- {value: 0x2690, lo: 0xac, hi: 0xac},
- {value: 0x266d, lo: 0xb9, hi: 0xb9},
- // Block 0x26, offset 0x106
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0x86, hi: 0x86},
- // Block 0x27, offset 0x108
- {value: 0x0000, lo: 0x05},
- {value: 0xa000, lo: 0xa5, hi: 0xa5},
- {value: 0x2d2b, lo: 0xa6, hi: 0xa6},
- {value: 0x9900, lo: 0xae, hi: 0xae},
- {value: 0x8103, lo: 0xb7, hi: 0xb7},
- {value: 0x8105, lo: 0xb9, hi: 0xba},
- // Block 0x28, offset 0x10e
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0x8d, hi: 0x8d},
- // Block 0x29, offset 0x110
- {value: 0x0000, lo: 0x01},
- {value: 0x0312, lo: 0xbc, hi: 0xbc},
- // Block 0x2a, offset 0x112
- {value: 0x0000, lo: 0x01},
- {value: 0xa000, lo: 0x80, hi: 0x92},
- // Block 0x2b, offset 0x114
- {value: 0x0000, lo: 0x01},
- {value: 0xb900, lo: 0xa1, hi: 0xb5},
- // Block 0x2c, offset 0x116
- {value: 0x0000, lo: 0x01},
- {value: 0x9900, lo: 0xa8, hi: 0xbf},
- // Block 0x2d, offset 0x118
- {value: 0x0000, lo: 0x01},
- {value: 0x9900, lo: 0x80, hi: 0x82},
- // Block 0x2e, offset 0x11a
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0x9d, hi: 0x9f},
- // Block 0x2f, offset 0x11c
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x94, hi: 0x94},
- {value: 0x8105, lo: 0xb4, hi: 0xb4},
- // Block 0x30, offset 0x11f
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x92, hi: 0x92},
- {value: 0x8133, lo: 0x9d, hi: 0x9d},
- // Block 0x31, offset 0x122
- {value: 0x0000, lo: 0x01},
- {value: 0x8132, lo: 0xa9, hi: 0xa9},
- // Block 0x32, offset 0x124
- {value: 0x0004, lo: 0x02},
- {value: 0x812f, lo: 0xb9, hi: 0xba},
- {value: 0x812e, lo: 0xbb, hi: 0xbb},
- // Block 0x33, offset 0x127
- {value: 0x0000, lo: 0x02},
- {value: 0x8133, lo: 0x97, hi: 0x97},
- {value: 0x812e, lo: 0x98, hi: 0x98},
- // Block 0x34, offset 0x12a
- {value: 0x0000, lo: 0x03},
- {value: 0x8105, lo: 0xa0, hi: 0xa0},
- {value: 0x8133, lo: 0xb5, hi: 0xbc},
- {value: 0x812e, lo: 0xbf, hi: 0xbf},
- // Block 0x35, offset 0x12e
- {value: 0x0000, lo: 0x05},
- {value: 0x8133, lo: 0xb0, hi: 0xb4},
- {value: 0x812e, lo: 0xb5, hi: 0xba},
- {value: 0x8133, lo: 0xbb, hi: 0xbc},
- {value: 0x812e, lo: 0xbd, hi: 0xbd},
- {value: 0x812e, lo: 0xbf, hi: 0xbf},
- // Block 0x36, offset 0x134
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0x80, hi: 0x80},
- // Block 0x37, offset 0x136
- {value: 0x0000, lo: 0x08},
- {value: 0x2d73, lo: 0x80, hi: 0x80},
- {value: 0x2d7b, lo: 0x81, hi: 0x81},
- {value: 0xa000, lo: 0x82, hi: 0x82},
- {value: 0x2d83, lo: 0x83, hi: 0x83},
- {value: 0x8105, lo: 0x84, hi: 0x84},
- {value: 0x8133, lo: 0xab, hi: 0xab},
- {value: 0x812e, lo: 0xac, hi: 0xac},
- {value: 0x8133, lo: 0xad, hi: 0xb3},
- // Block 0x38, offset 0x13f
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0xaa, hi: 0xab},
- // Block 0x39, offset 0x141
- {value: 0x0000, lo: 0x02},
- {value: 0x8103, lo: 0xa6, hi: 0xa6},
- {value: 0x8105, lo: 0xb2, hi: 0xb3},
- // Block 0x3a, offset 0x144
- {value: 0x0000, lo: 0x01},
- {value: 0x8103, lo: 0xb7, hi: 0xb7},
- // Block 0x3b, offset 0x146
- {value: 0x0000, lo: 0x0a},
- {value: 0x8133, lo: 0x90, hi: 0x92},
- {value: 0x8101, lo: 0x94, hi: 0x94},
- {value: 0x812e, lo: 0x95, hi: 0x99},
- {value: 0x8133, lo: 0x9a, hi: 0x9b},
- {value: 0x812e, lo: 0x9c, hi: 0x9f},
- {value: 0x8133, lo: 0xa0, hi: 0xa0},
- {value: 0x8101, lo: 0xa2, hi: 0xa8},
- {value: 0x812e, lo: 0xad, hi: 0xad},
- {value: 0x8133, lo: 0xb4, hi: 0xb4},
- {value: 0x8133, lo: 0xb8, hi: 0xb9},
- // Block 0x3c, offset 0x151
- {value: 0x0002, lo: 0x0a},
- {value: 0x0043, lo: 0xac, hi: 0xac},
- {value: 0x00d1, lo: 0xad, hi: 0xad},
- {value: 0x0045, lo: 0xae, hi: 0xae},
- {value: 0x0049, lo: 0xb0, hi: 0xb1},
- {value: 0x00e6, lo: 0xb2, hi: 0xb2},
- {value: 0x004f, lo: 0xb3, hi: 0xba},
- {value: 0x005f, lo: 0xbc, hi: 0xbc},
- {value: 0x00ef, lo: 0xbd, hi: 0xbd},
- {value: 0x0061, lo: 0xbe, hi: 0xbe},
- {value: 0x0065, lo: 0xbf, hi: 0xbf},
- // Block 0x3d, offset 0x15c
- {value: 0x0000, lo: 0x0d},
- {value: 0x0001, lo: 0x80, hi: 0x8a},
- {value: 0x043e, lo: 0x91, hi: 0x91},
- {value: 0x42b2, lo: 0x97, hi: 0x97},
- {value: 0x001d, lo: 0xa4, hi: 0xa4},
- {value: 0x1876, lo: 0xa5, hi: 0xa5},
- {value: 0x1b62, lo: 0xa6, hi: 0xa6},
- {value: 0x0001, lo: 0xaf, hi: 0xaf},
- {value: 0x2697, lo: 0xb3, hi: 0xb3},
- {value: 0x280b, lo: 0xb4, hi: 0xb4},
- {value: 0x269e, lo: 0xb6, hi: 0xb6},
- {value: 0x2815, lo: 0xb7, hi: 0xb7},
- {value: 0x1870, lo: 0xbc, hi: 0xbc},
- {value: 0x4280, lo: 0xbe, hi: 0xbe},
- // Block 0x3e, offset 0x16a
- {value: 0x0002, lo: 0x0d},
- {value: 0x1936, lo: 0x87, hi: 0x87},
- {value: 0x1933, lo: 0x88, hi: 0x88},
- {value: 0x1873, lo: 0x89, hi: 0x89},
- {value: 0x299b, lo: 0x97, hi: 0x97},
- {value: 0x0001, lo: 0x9f, hi: 0x9f},
- {value: 0x0021, lo: 0xb0, hi: 0xb0},
- {value: 0x0093, lo: 0xb1, hi: 0xb1},
- {value: 0x0029, lo: 0xb4, hi: 0xb9},
- {value: 0x0017, lo: 0xba, hi: 0xba},
- {value: 0x046a, lo: 0xbb, hi: 0xbb},
- {value: 0x003b, lo: 0xbc, hi: 0xbc},
- {value: 0x0011, lo: 0xbd, hi: 0xbe},
- {value: 0x009d, lo: 0xbf, hi: 0xbf},
- // Block 0x3f, offset 0x178
- {value: 0x0002, lo: 0x0f},
- {value: 0x0021, lo: 0x80, hi: 0x89},
- {value: 0x0017, lo: 0x8a, hi: 0x8a},
- {value: 0x046a, lo: 0x8b, hi: 0x8b},
- {value: 0x003b, lo: 0x8c, hi: 0x8c},
- {value: 0x0011, lo: 0x8d, hi: 0x8e},
- {value: 0x0083, lo: 0x90, hi: 0x90},
- {value: 0x008b, lo: 0x91, hi: 0x91},
- {value: 0x009f, lo: 0x92, hi: 0x92},
- {value: 0x00b1, lo: 0x93, hi: 0x93},
- {value: 0x0104, lo: 0x94, hi: 0x94},
- {value: 0x0091, lo: 0x95, hi: 0x95},
- {value: 0x0097, lo: 0x96, hi: 0x99},
- {value: 0x00a1, lo: 0x9a, hi: 0x9a},
- {value: 0x00a7, lo: 0x9b, hi: 0x9c},
- {value: 0x199f, lo: 0xa8, hi: 0xa8},
- // Block 0x40, offset 0x188
- {value: 0x0000, lo: 0x0d},
- {value: 0x8133, lo: 0x90, hi: 0x91},
- {value: 0x8101, lo: 0x92, hi: 0x93},
- {value: 0x8133, lo: 0x94, hi: 0x97},
- {value: 0x8101, lo: 0x98, hi: 0x9a},
- {value: 0x8133, lo: 0x9b, hi: 0x9c},
- {value: 0x8133, lo: 0xa1, hi: 0xa1},
- {value: 0x8101, lo: 0xa5, hi: 0xa6},
- {value: 0x8133, lo: 0xa7, hi: 0xa7},
- {value: 0x812e, lo: 0xa8, hi: 0xa8},
- {value: 0x8133, lo: 0xa9, hi: 0xa9},
- {value: 0x8101, lo: 0xaa, hi: 0xab},
- {value: 0x812e, lo: 0xac, hi: 0xaf},
- {value: 0x8133, lo: 0xb0, hi: 0xb0},
- // Block 0x41, offset 0x196
- {value: 0x0007, lo: 0x06},
- {value: 0x2186, lo: 0x89, hi: 0x89},
- {value: 0xa000, lo: 0x90, hi: 0x90},
- {value: 0xa000, lo: 0x92, hi: 0x92},
- {value: 0xa000, lo: 0x94, hi: 0x94},
- {value: 0x3bd0, lo: 0x9a, hi: 0x9b},
- {value: 0x3bde, lo: 0xae, hi: 0xae},
- // Block 0x42, offset 0x19d
- {value: 0x000e, lo: 0x05},
- {value: 0x3be5, lo: 0x8d, hi: 0x8e},
- {value: 0x3bec, lo: 0x8f, hi: 0x8f},
- {value: 0xa000, lo: 0x90, hi: 0x90},
- {value: 0xa000, lo: 0x92, hi: 0x92},
- {value: 0xa000, lo: 0x94, hi: 0x94},
- // Block 0x43, offset 0x1a3
- {value: 0x017a, lo: 0x0e},
- {value: 0xa000, lo: 0x83, hi: 0x83},
- {value: 0x3bfa, lo: 0x84, hi: 0x84},
- {value: 0xa000, lo: 0x88, hi: 0x88},
- {value: 0x3c01, lo: 0x89, hi: 0x89},
- {value: 0xa000, lo: 0x8b, hi: 0x8b},
- {value: 0x3c08, lo: 0x8c, hi: 0x8c},
- {value: 0xa000, lo: 0xa3, hi: 0xa3},
- {value: 0x3c0f, lo: 0xa4, hi: 0xa4},
- {value: 0xa000, lo: 0xa5, hi: 0xa5},
- {value: 0x3c16, lo: 0xa6, hi: 0xa6},
- {value: 0x26a5, lo: 0xac, hi: 0xad},
- {value: 0x26ac, lo: 0xaf, hi: 0xaf},
- {value: 0x2829, lo: 0xb0, hi: 0xb0},
- {value: 0xa000, lo: 0xbc, hi: 0xbc},
- // Block 0x44, offset 0x1b2
- {value: 0x0007, lo: 0x03},
- {value: 0x3c7f, lo: 0xa0, hi: 0xa1},
- {value: 0x3ca9, lo: 0xa2, hi: 0xa3},
- {value: 0x3cd3, lo: 0xaa, hi: 0xad},
- // Block 0x45, offset 0x1b6
- {value: 0x0004, lo: 0x01},
- {value: 0x048e, lo: 0xa9, hi: 0xaa},
- // Block 0x46, offset 0x1b8
- {value: 0x0002, lo: 0x03},
- {value: 0x0057, lo: 0x80, hi: 0x8f},
- {value: 0x0083, lo: 0x90, hi: 0xa9},
- {value: 0x0021, lo: 0xaa, hi: 0xaa},
- // Block 0x47, offset 0x1bc
- {value: 0x0000, lo: 0x01},
- {value: 0x29a8, lo: 0x8c, hi: 0x8c},
- // Block 0x48, offset 0x1be
- {value: 0x0266, lo: 0x02},
- {value: 0x1b92, lo: 0xb4, hi: 0xb4},
- {value: 0x1930, lo: 0xb5, hi: 0xb6},
- // Block 0x49, offset 0x1c1
- {value: 0x0000, lo: 0x01},
- {value: 0x44f4, lo: 0x9c, hi: 0x9c},
- // Block 0x4a, offset 0x1c3
- {value: 0x0000, lo: 0x02},
- {value: 0x0095, lo: 0xbc, hi: 0xbc},
- {value: 0x006d, lo: 0xbd, hi: 0xbd},
- // Block 0x4b, offset 0x1c6
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xaf, hi: 0xb1},
- // Block 0x4c, offset 0x1c8
- {value: 0x0000, lo: 0x02},
- {value: 0x0482, lo: 0xaf, hi: 0xaf},
- {value: 0x8105, lo: 0xbf, hi: 0xbf},
- // Block 0x4d, offset 0x1cb
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xa0, hi: 0xbf},
- // Block 0x4e, offset 0x1cd
- {value: 0x0000, lo: 0x01},
- {value: 0x0dc6, lo: 0x9f, hi: 0x9f},
- // Block 0x4f, offset 0x1cf
- {value: 0x0000, lo: 0x01},
- {value: 0x1632, lo: 0xb3, hi: 0xb3},
- // Block 0x50, offset 0x1d1
- {value: 0x0004, lo: 0x0b},
- {value: 0x159a, lo: 0x80, hi: 0x82},
- {value: 0x15b2, lo: 0x83, hi: 0x83},
- {value: 0x15ca, lo: 0x84, hi: 0x85},
- {value: 0x15da, lo: 0x86, hi: 0x89},
- {value: 0x15ee, lo: 0x8a, hi: 0x8c},
- {value: 0x1602, lo: 0x8d, hi: 0x8d},
- {value: 0x160a, lo: 0x8e, hi: 0x8e},
- {value: 0x1612, lo: 0x8f, hi: 0x90},
- {value: 0x161e, lo: 0x91, hi: 0x93},
- {value: 0x162e, lo: 0x94, hi: 0x94},
- {value: 0x1636, lo: 0x95, hi: 0x95},
- // Block 0x51, offset 0x1dd
- {value: 0x0004, lo: 0x09},
- {value: 0x0001, lo: 0x80, hi: 0x80},
- {value: 0x812d, lo: 0xaa, hi: 0xaa},
- {value: 0x8132, lo: 0xab, hi: 0xab},
- {value: 0x8134, lo: 0xac, hi: 0xac},
- {value: 0x812f, lo: 0xad, hi: 0xad},
- {value: 0x8130, lo: 0xae, hi: 0xae},
- {value: 0x8130, lo: 0xaf, hi: 0xaf},
- {value: 0x04b6, lo: 0xb6, hi: 0xb6},
- {value: 0x088a, lo: 0xb8, hi: 0xba},
- // Block 0x52, offset 0x1e7
- {value: 0x0006, lo: 0x09},
- {value: 0x0316, lo: 0xb1, hi: 0xb1},
- {value: 0x031a, lo: 0xb2, hi: 0xb2},
- {value: 0x4a52, lo: 0xb3, hi: 0xb3},
- {value: 0x031e, lo: 0xb4, hi: 0xb4},
- {value: 0x4a58, lo: 0xb5, hi: 0xb6},
- {value: 0x0322, lo: 0xb7, hi: 0xb7},
- {value: 0x0326, lo: 0xb8, hi: 0xb8},
- {value: 0x032a, lo: 0xb9, hi: 0xb9},
- {value: 0x4a64, lo: 0xba, hi: 0xbf},
- // Block 0x53, offset 0x1f1
- {value: 0x0000, lo: 0x02},
- {value: 0x8133, lo: 0xaf, hi: 0xaf},
- {value: 0x8133, lo: 0xb4, hi: 0xbd},
- // Block 0x54, offset 0x1f4
- {value: 0x0000, lo: 0x03},
- {value: 0x0212, lo: 0x9c, hi: 0x9c},
- {value: 0x0215, lo: 0x9d, hi: 0x9d},
- {value: 0x8133, lo: 0x9e, hi: 0x9f},
- // Block 0x55, offset 0x1f8
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xb0, hi: 0xb1},
- // Block 0x56, offset 0x1fa
- {value: 0x0000, lo: 0x01},
- {value: 0x163e, lo: 0xb0, hi: 0xb0},
- // Block 0x57, offset 0x1fc
- {value: 0x000c, lo: 0x01},
- {value: 0x00d7, lo: 0xb8, hi: 0xb9},
- // Block 0x58, offset 0x1fe
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x86, hi: 0x86},
- {value: 0x8105, lo: 0xac, hi: 0xac},
- // Block 0x59, offset 0x201
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x84, hi: 0x84},
- {value: 0x8133, lo: 0xa0, hi: 0xb1},
- // Block 0x5a, offset 0x204
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0xab, hi: 0xad},
- // Block 0x5b, offset 0x206
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0x93, hi: 0x93},
- // Block 0x5c, offset 0x208
- {value: 0x0000, lo: 0x01},
- {value: 0x8103, lo: 0xb3, hi: 0xb3},
- // Block 0x5d, offset 0x20a
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0x80, hi: 0x80},
- // Block 0x5e, offset 0x20c
- {value: 0x0000, lo: 0x05},
- {value: 0x8133, lo: 0xb0, hi: 0xb0},
- {value: 0x8133, lo: 0xb2, hi: 0xb3},
- {value: 0x812e, lo: 0xb4, hi: 0xb4},
- {value: 0x8133, lo: 0xb7, hi: 0xb8},
- {value: 0x8133, lo: 0xbe, hi: 0xbf},
- // Block 0x5f, offset 0x212
- {value: 0x0000, lo: 0x02},
- {value: 0x8133, lo: 0x81, hi: 0x81},
- {value: 0x8105, lo: 0xb6, hi: 0xb6},
- // Block 0x60, offset 0x215
- {value: 0x0008, lo: 0x04},
- {value: 0x163a, lo: 0x9c, hi: 0x9d},
- {value: 0x0125, lo: 0x9e, hi: 0x9e},
- {value: 0x1646, lo: 0x9f, hi: 0x9f},
- {value: 0x015e, lo: 0xa9, hi: 0xa9},
- // Block 0x61, offset 0x21a
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0xad, hi: 0xad},
- // Block 0x62, offset 0x21c
- {value: 0x0000, lo: 0x06},
- {value: 0xe500, lo: 0x80, hi: 0x80},
- {value: 0xc600, lo: 0x81, hi: 0x9b},
- {value: 0xe500, lo: 0x9c, hi: 0x9c},
- {value: 0xc600, lo: 0x9d, hi: 0xb7},
- {value: 0xe500, lo: 0xb8, hi: 0xb8},
- {value: 0xc600, lo: 0xb9, hi: 0xbf},
- // Block 0x63, offset 0x223
- {value: 0x0000, lo: 0x05},
- {value: 0xc600, lo: 0x80, hi: 0x93},
- {value: 0xe500, lo: 0x94, hi: 0x94},
- {value: 0xc600, lo: 0x95, hi: 0xaf},
- {value: 0xe500, lo: 0xb0, hi: 0xb0},
- {value: 0xc600, lo: 0xb1, hi: 0xbf},
- // Block 0x64, offset 0x229
- {value: 0x0000, lo: 0x05},
- {value: 0xc600, lo: 0x80, hi: 0x8b},
- {value: 0xe500, lo: 0x8c, hi: 0x8c},
- {value: 0xc600, lo: 0x8d, hi: 0xa7},
- {value: 0xe500, lo: 0xa8, hi: 0xa8},
- {value: 0xc600, lo: 0xa9, hi: 0xbf},
- // Block 0x65, offset 0x22f
- {value: 0x0000, lo: 0x07},
- {value: 0xc600, lo: 0x80, hi: 0x83},
- {value: 0xe500, lo: 0x84, hi: 0x84},
- {value: 0xc600, lo: 0x85, hi: 0x9f},
- {value: 0xe500, lo: 0xa0, hi: 0xa0},
- {value: 0xc600, lo: 0xa1, hi: 0xbb},
- {value: 0xe500, lo: 0xbc, hi: 0xbc},
- {value: 0xc600, lo: 0xbd, hi: 0xbf},
- // Block 0x66, offset 0x237
- {value: 0x0000, lo: 0x05},
- {value: 0xc600, lo: 0x80, hi: 0x97},
- {value: 0xe500, lo: 0x98, hi: 0x98},
- {value: 0xc600, lo: 0x99, hi: 0xb3},
- {value: 0xe500, lo: 0xb4, hi: 0xb4},
- {value: 0xc600, lo: 0xb5, hi: 0xbf},
- // Block 0x67, offset 0x23d
- {value: 0x0000, lo: 0x05},
- {value: 0xc600, lo: 0x80, hi: 0x8f},
- {value: 0xe500, lo: 0x90, hi: 0x90},
- {value: 0xc600, lo: 0x91, hi: 0xab},
- {value: 0xe500, lo: 0xac, hi: 0xac},
- {value: 0xc600, lo: 0xad, hi: 0xbf},
- // Block 0x68, offset 0x243
- {value: 0x0000, lo: 0x05},
- {value: 0xc600, lo: 0x80, hi: 0x87},
- {value: 0xe500, lo: 0x88, hi: 0x88},
- {value: 0xc600, lo: 0x89, hi: 0xa3},
- {value: 0xe500, lo: 0xa4, hi: 0xa4},
- {value: 0xc600, lo: 0xa5, hi: 0xbf},
- // Block 0x69, offset 0x249
- {value: 0x0000, lo: 0x03},
- {value: 0xc600, lo: 0x80, hi: 0x87},
- {value: 0xe500, lo: 0x88, hi: 0x88},
- {value: 0xc600, lo: 0x89, hi: 0xa3},
- // Block 0x6a, offset 0x24d
- {value: 0x0002, lo: 0x01},
- {value: 0x0003, lo: 0x81, hi: 0xbf},
- // Block 0x6b, offset 0x24f
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0xbd, hi: 0xbd},
- // Block 0x6c, offset 0x251
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0xa0, hi: 0xa0},
- // Block 0x6d, offset 0x253
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xb6, hi: 0xba},
- // Block 0x6e, offset 0x255
- {value: 0x002d, lo: 0x05},
- {value: 0x812e, lo: 0x8d, hi: 0x8d},
- {value: 0x8133, lo: 0x8f, hi: 0x8f},
- {value: 0x8133, lo: 0xb8, hi: 0xb8},
- {value: 0x8101, lo: 0xb9, hi: 0xba},
- {value: 0x8105, lo: 0xbf, hi: 0xbf},
- // Block 0x6f, offset 0x25b
- {value: 0x0000, lo: 0x02},
- {value: 0x8133, lo: 0xa5, hi: 0xa5},
- {value: 0x812e, lo: 0xa6, hi: 0xa6},
- // Block 0x70, offset 0x25e
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xa4, hi: 0xa7},
- // Block 0x71, offset 0x260
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xab, hi: 0xac},
- // Block 0x72, offset 0x262
- {value: 0x0000, lo: 0x05},
- {value: 0x812e, lo: 0x86, hi: 0x87},
- {value: 0x8133, lo: 0x88, hi: 0x8a},
- {value: 0x812e, lo: 0x8b, hi: 0x8b},
- {value: 0x8133, lo: 0x8c, hi: 0x8c},
- {value: 0x812e, lo: 0x8d, hi: 0x90},
- // Block 0x73, offset 0x268
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x86, hi: 0x86},
- {value: 0x8105, lo: 0xbf, hi: 0xbf},
- // Block 0x74, offset 0x26b
- {value: 0x17fe, lo: 0x07},
- {value: 0xa000, lo: 0x99, hi: 0x99},
- {value: 0x424f, lo: 0x9a, hi: 0x9a},
- {value: 0xa000, lo: 0x9b, hi: 0x9b},
- {value: 0x4259, lo: 0x9c, hi: 0x9c},
- {value: 0xa000, lo: 0xa5, hi: 0xa5},
- {value: 0x4263, lo: 0xab, hi: 0xab},
- {value: 0x8105, lo: 0xb9, hi: 0xba},
- // Block 0x75, offset 0x273
- {value: 0x0000, lo: 0x06},
- {value: 0x8133, lo: 0x80, hi: 0x82},
- {value: 0x9900, lo: 0xa7, hi: 0xa7},
- {value: 0x2d8b, lo: 0xae, hi: 0xae},
- {value: 0x2d95, lo: 0xaf, hi: 0xaf},
- {value: 0xa000, lo: 0xb1, hi: 0xb2},
- {value: 0x8105, lo: 0xb3, hi: 0xb4},
- // Block 0x76, offset 0x27a
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x80, hi: 0x80},
- {value: 0x8103, lo: 0x8a, hi: 0x8a},
- // Block 0x77, offset 0x27d
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0xb5, hi: 0xb5},
- {value: 0x8103, lo: 0xb6, hi: 0xb6},
- // Block 0x78, offset 0x280
- {value: 0x0002, lo: 0x01},
- {value: 0x8103, lo: 0xa9, hi: 0xaa},
- // Block 0x79, offset 0x282
- {value: 0x0000, lo: 0x02},
- {value: 0x8103, lo: 0xbb, hi: 0xbc},
- {value: 0x9900, lo: 0xbe, hi: 0xbe},
- // Block 0x7a, offset 0x285
- {value: 0x0000, lo: 0x07},
- {value: 0xa000, lo: 0x87, hi: 0x87},
- {value: 0x2d9f, lo: 0x8b, hi: 0x8b},
- {value: 0x2da9, lo: 0x8c, hi: 0x8c},
- {value: 0x8105, lo: 0x8d, hi: 0x8d},
- {value: 0x9900, lo: 0x97, hi: 0x97},
- {value: 0x8133, lo: 0xa6, hi: 0xac},
- {value: 0x8133, lo: 0xb0, hi: 0xb4},
- // Block 0x7b, offset 0x28d
- {value: 0x0000, lo: 0x03},
- {value: 0x8105, lo: 0x82, hi: 0x82},
- {value: 0x8103, lo: 0x86, hi: 0x86},
- {value: 0x8133, lo: 0x9e, hi: 0x9e},
- // Block 0x7c, offset 0x291
- {value: 0x6b4d, lo: 0x06},
- {value: 0x9900, lo: 0xb0, hi: 0xb0},
- {value: 0xa000, lo: 0xb9, hi: 0xb9},
- {value: 0x9900, lo: 0xba, hi: 0xba},
- {value: 0x2dbd, lo: 0xbb, hi: 0xbb},
- {value: 0x2db3, lo: 0xbc, hi: 0xbd},
- {value: 0x2dc7, lo: 0xbe, hi: 0xbe},
- // Block 0x7d, offset 0x298
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0x82, hi: 0x82},
- {value: 0x8103, lo: 0x83, hi: 0x83},
- // Block 0x7e, offset 0x29b
- {value: 0x0000, lo: 0x05},
- {value: 0x9900, lo: 0xaf, hi: 0xaf},
- {value: 0xa000, lo: 0xb8, hi: 0xb9},
- {value: 0x2dd1, lo: 0xba, hi: 0xba},
- {value: 0x2ddb, lo: 0xbb, hi: 0xbb},
- {value: 0x8105, lo: 0xbf, hi: 0xbf},
- // Block 0x7f, offset 0x2a1
- {value: 0x0000, lo: 0x01},
- {value: 0x8103, lo: 0x80, hi: 0x80},
- // Block 0x80, offset 0x2a3
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0xbf, hi: 0xbf},
- // Block 0x81, offset 0x2a5
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0xb6, hi: 0xb6},
- {value: 0x8103, lo: 0xb7, hi: 0xb7},
- // Block 0x82, offset 0x2a8
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0xab, hi: 0xab},
- // Block 0x83, offset 0x2aa
- {value: 0x0000, lo: 0x02},
- {value: 0x8105, lo: 0xb9, hi: 0xb9},
- {value: 0x8103, lo: 0xba, hi: 0xba},
- // Block 0x84, offset 0x2ad
- {value: 0x0000, lo: 0x04},
- {value: 0x9900, lo: 0xb0, hi: 0xb0},
- {value: 0xa000, lo: 0xb5, hi: 0xb5},
- {value: 0x2de5, lo: 0xb8, hi: 0xb8},
- {value: 0x8105, lo: 0xbd, hi: 0xbe},
- // Block 0x85, offset 0x2b2
- {value: 0x0000, lo: 0x01},
- {value: 0x8103, lo: 0x83, hi: 0x83},
- // Block 0x86, offset 0x2b4
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0xa0, hi: 0xa0},
- // Block 0x87, offset 0x2b6
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0xb4, hi: 0xb4},
- // Block 0x88, offset 0x2b8
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0x87, hi: 0x87},
- // Block 0x89, offset 0x2ba
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0x99, hi: 0x99},
- // Block 0x8a, offset 0x2bc
- {value: 0x0000, lo: 0x02},
- {value: 0x8103, lo: 0x82, hi: 0x82},
- {value: 0x8105, lo: 0x84, hi: 0x85},
- // Block 0x8b, offset 0x2bf
- {value: 0x0000, lo: 0x01},
- {value: 0x8105, lo: 0x97, hi: 0x97},
- // Block 0x8c, offset 0x2c1
- {value: 0x0000, lo: 0x01},
- {value: 0x8101, lo: 0xb0, hi: 0xb4},
- // Block 0x8d, offset 0x2c3
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xb0, hi: 0xb6},
- // Block 0x8e, offset 0x2c5
- {value: 0x0000, lo: 0x01},
- {value: 0x8102, lo: 0xb0, hi: 0xb1},
- // Block 0x8f, offset 0x2c7
- {value: 0x0000, lo: 0x01},
- {value: 0x8101, lo: 0x9e, hi: 0x9e},
- // Block 0x90, offset 0x2c9
- {value: 0x0000, lo: 0x0c},
- {value: 0x45e3, lo: 0x9e, hi: 0x9e},
- {value: 0x45ed, lo: 0x9f, hi: 0x9f},
- {value: 0x4621, lo: 0xa0, hi: 0xa0},
- {value: 0x462f, lo: 0xa1, hi: 0xa1},
- {value: 0x463d, lo: 0xa2, hi: 0xa2},
- {value: 0x464b, lo: 0xa3, hi: 0xa3},
- {value: 0x4659, lo: 0xa4, hi: 0xa4},
- {value: 0x812c, lo: 0xa5, hi: 0xa6},
- {value: 0x8101, lo: 0xa7, hi: 0xa9},
- {value: 0x8131, lo: 0xad, hi: 0xad},
- {value: 0x812c, lo: 0xae, hi: 0xb2},
- {value: 0x812e, lo: 0xbb, hi: 0xbf},
- // Block 0x91, offset 0x2d6
- {value: 0x0000, lo: 0x09},
- {value: 0x812e, lo: 0x80, hi: 0x82},
- {value: 0x8133, lo: 0x85, hi: 0x89},
- {value: 0x812e, lo: 0x8a, hi: 0x8b},
- {value: 0x8133, lo: 0xaa, hi: 0xad},
- {value: 0x45f7, lo: 0xbb, hi: 0xbb},
- {value: 0x4601, lo: 0xbc, hi: 0xbc},
- {value: 0x4667, lo: 0xbd, hi: 0xbd},
- {value: 0x4683, lo: 0xbe, hi: 0xbe},
- {value: 0x4675, lo: 0xbf, hi: 0xbf},
- // Block 0x92, offset 0x2e0
- {value: 0x0000, lo: 0x01},
- {value: 0x4691, lo: 0x80, hi: 0x80},
- // Block 0x93, offset 0x2e2
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0x82, hi: 0x84},
- // Block 0x94, offset 0x2e4
- {value: 0x0002, lo: 0x03},
- {value: 0x0043, lo: 0x80, hi: 0x99},
- {value: 0x0083, lo: 0x9a, hi: 0xb3},
- {value: 0x0043, lo: 0xb4, hi: 0xbf},
- // Block 0x95, offset 0x2e8
- {value: 0x0002, lo: 0x04},
- {value: 0x005b, lo: 0x80, hi: 0x8d},
- {value: 0x0083, lo: 0x8e, hi: 0x94},
- {value: 0x0093, lo: 0x96, hi: 0xa7},
- {value: 0x0043, lo: 0xa8, hi: 0xbf},
- // Block 0x96, offset 0x2ed
- {value: 0x0002, lo: 0x0b},
- {value: 0x0073, lo: 0x80, hi: 0x81},
- {value: 0x0083, lo: 0x82, hi: 0x9b},
- {value: 0x0043, lo: 0x9c, hi: 0x9c},
- {value: 0x0047, lo: 0x9e, hi: 0x9f},
- {value: 0x004f, lo: 0xa2, hi: 0xa2},
- {value: 0x0055, lo: 0xa5, hi: 0xa6},
- {value: 0x005d, lo: 0xa9, hi: 0xac},
- {value: 0x0067, lo: 0xae, hi: 0xb5},
- {value: 0x0083, lo: 0xb6, hi: 0xb9},
- {value: 0x008d, lo: 0xbb, hi: 0xbb},
- {value: 0x0091, lo: 0xbd, hi: 0xbf},
- // Block 0x97, offset 0x2f9
- {value: 0x0002, lo: 0x04},
- {value: 0x0097, lo: 0x80, hi: 0x83},
- {value: 0x00a1, lo: 0x85, hi: 0x8f},
- {value: 0x0043, lo: 0x90, hi: 0xa9},
- {value: 0x0083, lo: 0xaa, hi: 0xbf},
- // Block 0x98, offset 0x2fe
- {value: 0x0002, lo: 0x08},
- {value: 0x00af, lo: 0x80, hi: 0x83},
- {value: 0x0043, lo: 0x84, hi: 0x85},
- {value: 0x0049, lo: 0x87, hi: 0x8a},
- {value: 0x0055, lo: 0x8d, hi: 0x94},
- {value: 0x0067, lo: 0x96, hi: 0x9c},
- {value: 0x0083, lo: 0x9e, hi: 0xb7},
- {value: 0x0043, lo: 0xb8, hi: 0xb9},
- {value: 0x0049, lo: 0xbb, hi: 0xbe},
- // Block 0x99, offset 0x307
- {value: 0x0002, lo: 0x05},
- {value: 0x0053, lo: 0x80, hi: 0x84},
- {value: 0x005f, lo: 0x86, hi: 0x86},
- {value: 0x0067, lo: 0x8a, hi: 0x90},
- {value: 0x0083, lo: 0x92, hi: 0xab},
- {value: 0x0043, lo: 0xac, hi: 0xbf},
- // Block 0x9a, offset 0x30d
- {value: 0x0002, lo: 0x04},
- {value: 0x006b, lo: 0x80, hi: 0x85},
- {value: 0x0083, lo: 0x86, hi: 0x9f},
- {value: 0x0043, lo: 0xa0, hi: 0xb9},
- {value: 0x0083, lo: 0xba, hi: 0xbf},
- // Block 0x9b, offset 0x312
- {value: 0x0002, lo: 0x03},
- {value: 0x008f, lo: 0x80, hi: 0x93},
- {value: 0x0043, lo: 0x94, hi: 0xad},
- {value: 0x0083, lo: 0xae, hi: 0xbf},
- // Block 0x9c, offset 0x316
- {value: 0x0002, lo: 0x04},
- {value: 0x00a7, lo: 0x80, hi: 0x87},
- {value: 0x0043, lo: 0x88, hi: 0xa1},
- {value: 0x0083, lo: 0xa2, hi: 0xbb},
- {value: 0x0043, lo: 0xbc, hi: 0xbf},
- // Block 0x9d, offset 0x31b
- {value: 0x0002, lo: 0x03},
- {value: 0x004b, lo: 0x80, hi: 0x95},
- {value: 0x0083, lo: 0x96, hi: 0xaf},
- {value: 0x0043, lo: 0xb0, hi: 0xbf},
- // Block 0x9e, offset 0x31f
- {value: 0x0003, lo: 0x0f},
- {value: 0x01bb, lo: 0x80, hi: 0x80},
- {value: 0x0462, lo: 0x81, hi: 0x81},
- {value: 0x01be, lo: 0x82, hi: 0x9a},
- {value: 0x045e, lo: 0x9b, hi: 0x9b},
- {value: 0x01ca, lo: 0x9c, hi: 0x9c},
- {value: 0x01d3, lo: 0x9d, hi: 0x9d},
- {value: 0x01d9, lo: 0x9e, hi: 0x9e},
- {value: 0x01fd, lo: 0x9f, hi: 0x9f},
- {value: 0x01ee, lo: 0xa0, hi: 0xa0},
- {value: 0x01eb, lo: 0xa1, hi: 0xa1},
- {value: 0x0176, lo: 0xa2, hi: 0xb2},
- {value: 0x018b, lo: 0xb3, hi: 0xb3},
- {value: 0x01a9, lo: 0xb4, hi: 0xba},
- {value: 0x0462, lo: 0xbb, hi: 0xbb},
- {value: 0x01be, lo: 0xbc, hi: 0xbf},
- // Block 0x9f, offset 0x32f
- {value: 0x0003, lo: 0x0d},
- {value: 0x01ca, lo: 0x80, hi: 0x94},
- {value: 0x045e, lo: 0x95, hi: 0x95},
- {value: 0x01ca, lo: 0x96, hi: 0x96},
- {value: 0x01d3, lo: 0x97, hi: 0x97},
- {value: 0x01d9, lo: 0x98, hi: 0x98},
- {value: 0x01fd, lo: 0x99, hi: 0x99},
- {value: 0x01ee, lo: 0x9a, hi: 0x9a},
- {value: 0x01eb, lo: 0x9b, hi: 0x9b},
- {value: 0x0176, lo: 0x9c, hi: 0xac},
- {value: 0x018b, lo: 0xad, hi: 0xad},
- {value: 0x01a9, lo: 0xae, hi: 0xb4},
- {value: 0x0462, lo: 0xb5, hi: 0xb5},
- {value: 0x01be, lo: 0xb6, hi: 0xbf},
- // Block 0xa0, offset 0x33d
- {value: 0x0003, lo: 0x0d},
- {value: 0x01dc, lo: 0x80, hi: 0x8e},
- {value: 0x045e, lo: 0x8f, hi: 0x8f},
- {value: 0x01ca, lo: 0x90, hi: 0x90},
- {value: 0x01d3, lo: 0x91, hi: 0x91},
- {value: 0x01d9, lo: 0x92, hi: 0x92},
- {value: 0x01fd, lo: 0x93, hi: 0x93},
- {value: 0x01ee, lo: 0x94, hi: 0x94},
- {value: 0x01eb, lo: 0x95, hi: 0x95},
- {value: 0x0176, lo: 0x96, hi: 0xa6},
- {value: 0x018b, lo: 0xa7, hi: 0xa7},
- {value: 0x01a9, lo: 0xa8, hi: 0xae},
- {value: 0x0462, lo: 0xaf, hi: 0xaf},
- {value: 0x01be, lo: 0xb0, hi: 0xbf},
- // Block 0xa1, offset 0x34b
- {value: 0x0003, lo: 0x0d},
- {value: 0x01ee, lo: 0x80, hi: 0x88},
- {value: 0x045e, lo: 0x89, hi: 0x89},
- {value: 0x01ca, lo: 0x8a, hi: 0x8a},
- {value: 0x01d3, lo: 0x8b, hi: 0x8b},
- {value: 0x01d9, lo: 0x8c, hi: 0x8c},
- {value: 0x01fd, lo: 0x8d, hi: 0x8d},
- {value: 0x01ee, lo: 0x8e, hi: 0x8e},
- {value: 0x01eb, lo: 0x8f, hi: 0x8f},
- {value: 0x0176, lo: 0x90, hi: 0xa0},
- {value: 0x018b, lo: 0xa1, hi: 0xa1},
- {value: 0x01a9, lo: 0xa2, hi: 0xa8},
- {value: 0x0462, lo: 0xa9, hi: 0xa9},
- {value: 0x01be, lo: 0xaa, hi: 0xbf},
- // Block 0xa2, offset 0x359
- {value: 0x0000, lo: 0x05},
- {value: 0x8133, lo: 0x80, hi: 0x86},
- {value: 0x8133, lo: 0x88, hi: 0x98},
- {value: 0x8133, lo: 0x9b, hi: 0xa1},
- {value: 0x8133, lo: 0xa3, hi: 0xa4},
- {value: 0x8133, lo: 0xa6, hi: 0xaa},
- // Block 0xa3, offset 0x35f
- {value: 0x0000, lo: 0x01},
- {value: 0x8133, lo: 0xac, hi: 0xaf},
- // Block 0xa4, offset 0x361
- {value: 0x0000, lo: 0x01},
- {value: 0x812e, lo: 0x90, hi: 0x96},
- // Block 0xa5, offset 0x363
- {value: 0x0000, lo: 0x02},
- {value: 0x8133, lo: 0x84, hi: 0x89},
- {value: 0x8103, lo: 0x8a, hi: 0x8a},
- // Block 0xa6, offset 0x366
- {value: 0x0002, lo: 0x0a},
- {value: 0x0063, lo: 0x80, hi: 0x89},
- {value: 0x1954, lo: 0x8a, hi: 0x8a},
- {value: 0x1987, lo: 0x8b, hi: 0x8b},
- {value: 0x19a2, lo: 0x8c, hi: 0x8c},
- {value: 0x19a8, lo: 0x8d, hi: 0x8d},
- {value: 0x1bc6, lo: 0x8e, hi: 0x8e},
- {value: 0x19b4, lo: 0x8f, hi: 0x8f},
- {value: 0x197e, lo: 0xaa, hi: 0xaa},
- {value: 0x1981, lo: 0xab, hi: 0xab},
- {value: 0x1984, lo: 0xac, hi: 0xac},
- // Block 0xa7, offset 0x371
- {value: 0x0000, lo: 0x01},
- {value: 0x1942, lo: 0x90, hi: 0x90},
- // Block 0xa8, offset 0x373
- {value: 0x0028, lo: 0x09},
- {value: 0x286f, lo: 0x80, hi: 0x80},
- {value: 0x2833, lo: 0x81, hi: 0x81},
- {value: 0x283d, lo: 0x82, hi: 0x82},
- {value: 0x2851, lo: 0x83, hi: 0x84},
- {value: 0x285b, lo: 0x85, hi: 0x86},
- {value: 0x2847, lo: 0x87, hi: 0x87},
- {value: 0x2865, lo: 0x88, hi: 0x88},
- {value: 0x0b72, lo: 0x90, hi: 0x90},
- {value: 0x08ea, lo: 0x91, hi: 0x91},
- // Block 0xa9, offset 0x37d
- {value: 0x0002, lo: 0x01},
- {value: 0x0021, lo: 0xb0, hi: 0xb9},
-}
-
-// recompMap: 7528 bytes (entries only)
-var recompMap map[uint32]rune
-var recompMapOnce sync.Once
-
-const recompMapPacked = "" +
- "\x00A\x03\x00\x00\x00\x00\xc0" + // 0x00410300: 0x000000C0
- "\x00A\x03\x01\x00\x00\x00\xc1" + // 0x00410301: 0x000000C1
- "\x00A\x03\x02\x00\x00\x00\xc2" + // 0x00410302: 0x000000C2
- "\x00A\x03\x03\x00\x00\x00\xc3" + // 0x00410303: 0x000000C3
- "\x00A\x03\b\x00\x00\x00\xc4" + // 0x00410308: 0x000000C4
- "\x00A\x03\n\x00\x00\x00\xc5" + // 0x0041030A: 0x000000C5
- "\x00C\x03'\x00\x00\x00\xc7" + // 0x00430327: 0x000000C7
- "\x00E\x03\x00\x00\x00\x00\xc8" + // 0x00450300: 0x000000C8
- "\x00E\x03\x01\x00\x00\x00\xc9" + // 0x00450301: 0x000000C9
- "\x00E\x03\x02\x00\x00\x00\xca" + // 0x00450302: 0x000000CA
- "\x00E\x03\b\x00\x00\x00\xcb" + // 0x00450308: 0x000000CB
- "\x00I\x03\x00\x00\x00\x00\xcc" + // 0x00490300: 0x000000CC
- "\x00I\x03\x01\x00\x00\x00\xcd" + // 0x00490301: 0x000000CD
- "\x00I\x03\x02\x00\x00\x00\xce" + // 0x00490302: 0x000000CE
- "\x00I\x03\b\x00\x00\x00\xcf" + // 0x00490308: 0x000000CF
- "\x00N\x03\x03\x00\x00\x00\xd1" + // 0x004E0303: 0x000000D1
- "\x00O\x03\x00\x00\x00\x00\xd2" + // 0x004F0300: 0x000000D2
- "\x00O\x03\x01\x00\x00\x00\xd3" + // 0x004F0301: 0x000000D3
- "\x00O\x03\x02\x00\x00\x00\xd4" + // 0x004F0302: 0x000000D4
- "\x00O\x03\x03\x00\x00\x00\xd5" + // 0x004F0303: 0x000000D5
- "\x00O\x03\b\x00\x00\x00\xd6" + // 0x004F0308: 0x000000D6
- "\x00U\x03\x00\x00\x00\x00\xd9" + // 0x00550300: 0x000000D9
- "\x00U\x03\x01\x00\x00\x00\xda" + // 0x00550301: 0x000000DA
- "\x00U\x03\x02\x00\x00\x00\xdb" + // 0x00550302: 0x000000DB
- "\x00U\x03\b\x00\x00\x00\xdc" + // 0x00550308: 0x000000DC
- "\x00Y\x03\x01\x00\x00\x00\xdd" + // 0x00590301: 0x000000DD
- "\x00a\x03\x00\x00\x00\x00\xe0" + // 0x00610300: 0x000000E0
- "\x00a\x03\x01\x00\x00\x00\xe1" + // 0x00610301: 0x000000E1
- "\x00a\x03\x02\x00\x00\x00\xe2" + // 0x00610302: 0x000000E2
- "\x00a\x03\x03\x00\x00\x00\xe3" + // 0x00610303: 0x000000E3
- "\x00a\x03\b\x00\x00\x00\xe4" + // 0x00610308: 0x000000E4
- "\x00a\x03\n\x00\x00\x00\xe5" + // 0x0061030A: 0x000000E5
- "\x00c\x03'\x00\x00\x00\xe7" + // 0x00630327: 0x000000E7
- "\x00e\x03\x00\x00\x00\x00\xe8" + // 0x00650300: 0x000000E8
- "\x00e\x03\x01\x00\x00\x00\xe9" + // 0x00650301: 0x000000E9
- "\x00e\x03\x02\x00\x00\x00\xea" + // 0x00650302: 0x000000EA
- "\x00e\x03\b\x00\x00\x00\xeb" + // 0x00650308: 0x000000EB
- "\x00i\x03\x00\x00\x00\x00\xec" + // 0x00690300: 0x000000EC
- "\x00i\x03\x01\x00\x00\x00\xed" + // 0x00690301: 0x000000ED
- "\x00i\x03\x02\x00\x00\x00\xee" + // 0x00690302: 0x000000EE
- "\x00i\x03\b\x00\x00\x00\xef" + // 0x00690308: 0x000000EF
- "\x00n\x03\x03\x00\x00\x00\xf1" + // 0x006E0303: 0x000000F1
- "\x00o\x03\x00\x00\x00\x00\xf2" + // 0x006F0300: 0x000000F2
- "\x00o\x03\x01\x00\x00\x00\xf3" + // 0x006F0301: 0x000000F3
- "\x00o\x03\x02\x00\x00\x00\xf4" + // 0x006F0302: 0x000000F4
- "\x00o\x03\x03\x00\x00\x00\xf5" + // 0x006F0303: 0x000000F5
- "\x00o\x03\b\x00\x00\x00\xf6" + // 0x006F0308: 0x000000F6
- "\x00u\x03\x00\x00\x00\x00\xf9" + // 0x00750300: 0x000000F9
- "\x00u\x03\x01\x00\x00\x00\xfa" + // 0x00750301: 0x000000FA
- "\x00u\x03\x02\x00\x00\x00\xfb" + // 0x00750302: 0x000000FB
- "\x00u\x03\b\x00\x00\x00\xfc" + // 0x00750308: 0x000000FC
- "\x00y\x03\x01\x00\x00\x00\xfd" + // 0x00790301: 0x000000FD
- "\x00y\x03\b\x00\x00\x00\xff" + // 0x00790308: 0x000000FF
- "\x00A\x03\x04\x00\x00\x01\x00" + // 0x00410304: 0x00000100
- "\x00a\x03\x04\x00\x00\x01\x01" + // 0x00610304: 0x00000101
- "\x00A\x03\x06\x00\x00\x01\x02" + // 0x00410306: 0x00000102
- "\x00a\x03\x06\x00\x00\x01\x03" + // 0x00610306: 0x00000103
- "\x00A\x03(\x00\x00\x01\x04" + // 0x00410328: 0x00000104
- "\x00a\x03(\x00\x00\x01\x05" + // 0x00610328: 0x00000105
- "\x00C\x03\x01\x00\x00\x01\x06" + // 0x00430301: 0x00000106
- "\x00c\x03\x01\x00\x00\x01\a" + // 0x00630301: 0x00000107
- "\x00C\x03\x02\x00\x00\x01\b" + // 0x00430302: 0x00000108
- "\x00c\x03\x02\x00\x00\x01\t" + // 0x00630302: 0x00000109
- "\x00C\x03\a\x00\x00\x01\n" + // 0x00430307: 0x0000010A
- "\x00c\x03\a\x00\x00\x01\v" + // 0x00630307: 0x0000010B
- "\x00C\x03\f\x00\x00\x01\f" + // 0x0043030C: 0x0000010C
- "\x00c\x03\f\x00\x00\x01\r" + // 0x0063030C: 0x0000010D
- "\x00D\x03\f\x00\x00\x01\x0e" + // 0x0044030C: 0x0000010E
- "\x00d\x03\f\x00\x00\x01\x0f" + // 0x0064030C: 0x0000010F
- "\x00E\x03\x04\x00\x00\x01\x12" + // 0x00450304: 0x00000112
- "\x00e\x03\x04\x00\x00\x01\x13" + // 0x00650304: 0x00000113
- "\x00E\x03\x06\x00\x00\x01\x14" + // 0x00450306: 0x00000114
- "\x00e\x03\x06\x00\x00\x01\x15" + // 0x00650306: 0x00000115
- "\x00E\x03\a\x00\x00\x01\x16" + // 0x00450307: 0x00000116
- "\x00e\x03\a\x00\x00\x01\x17" + // 0x00650307: 0x00000117
- "\x00E\x03(\x00\x00\x01\x18" + // 0x00450328: 0x00000118
- "\x00e\x03(\x00\x00\x01\x19" + // 0x00650328: 0x00000119
- "\x00E\x03\f\x00\x00\x01\x1a" + // 0x0045030C: 0x0000011A
- "\x00e\x03\f\x00\x00\x01\x1b" + // 0x0065030C: 0x0000011B
- "\x00G\x03\x02\x00\x00\x01\x1c" + // 0x00470302: 0x0000011C
- "\x00g\x03\x02\x00\x00\x01\x1d" + // 0x00670302: 0x0000011D
- "\x00G\x03\x06\x00\x00\x01\x1e" + // 0x00470306: 0x0000011E
- "\x00g\x03\x06\x00\x00\x01\x1f" + // 0x00670306: 0x0000011F
- "\x00G\x03\a\x00\x00\x01 " + // 0x00470307: 0x00000120
- "\x00g\x03\a\x00\x00\x01!" + // 0x00670307: 0x00000121
- "\x00G\x03'\x00\x00\x01\"" + // 0x00470327: 0x00000122
- "\x00g\x03'\x00\x00\x01#" + // 0x00670327: 0x00000123
- "\x00H\x03\x02\x00\x00\x01$" + // 0x00480302: 0x00000124
- "\x00h\x03\x02\x00\x00\x01%" + // 0x00680302: 0x00000125
- "\x00I\x03\x03\x00\x00\x01(" + // 0x00490303: 0x00000128
- "\x00i\x03\x03\x00\x00\x01)" + // 0x00690303: 0x00000129
- "\x00I\x03\x04\x00\x00\x01*" + // 0x00490304: 0x0000012A
- "\x00i\x03\x04\x00\x00\x01+" + // 0x00690304: 0x0000012B
- "\x00I\x03\x06\x00\x00\x01," + // 0x00490306: 0x0000012C
- "\x00i\x03\x06\x00\x00\x01-" + // 0x00690306: 0x0000012D
- "\x00I\x03(\x00\x00\x01." + // 0x00490328: 0x0000012E
- "\x00i\x03(\x00\x00\x01/" + // 0x00690328: 0x0000012F
- "\x00I\x03\a\x00\x00\x010" + // 0x00490307: 0x00000130
- "\x00J\x03\x02\x00\x00\x014" + // 0x004A0302: 0x00000134
- "\x00j\x03\x02\x00\x00\x015" + // 0x006A0302: 0x00000135
- "\x00K\x03'\x00\x00\x016" + // 0x004B0327: 0x00000136
- "\x00k\x03'\x00\x00\x017" + // 0x006B0327: 0x00000137
- "\x00L\x03\x01\x00\x00\x019" + // 0x004C0301: 0x00000139
- "\x00l\x03\x01\x00\x00\x01:" + // 0x006C0301: 0x0000013A
- "\x00L\x03'\x00\x00\x01;" + // 0x004C0327: 0x0000013B
- "\x00l\x03'\x00\x00\x01<" + // 0x006C0327: 0x0000013C
- "\x00L\x03\f\x00\x00\x01=" + // 0x004C030C: 0x0000013D
- "\x00l\x03\f\x00\x00\x01>" + // 0x006C030C: 0x0000013E
- "\x00N\x03\x01\x00\x00\x01C" + // 0x004E0301: 0x00000143
- "\x00n\x03\x01\x00\x00\x01D" + // 0x006E0301: 0x00000144
- "\x00N\x03'\x00\x00\x01E" + // 0x004E0327: 0x00000145
- "\x00n\x03'\x00\x00\x01F" + // 0x006E0327: 0x00000146
- "\x00N\x03\f\x00\x00\x01G" + // 0x004E030C: 0x00000147
- "\x00n\x03\f\x00\x00\x01H" + // 0x006E030C: 0x00000148
- "\x00O\x03\x04\x00\x00\x01L" + // 0x004F0304: 0x0000014C
- "\x00o\x03\x04\x00\x00\x01M" + // 0x006F0304: 0x0000014D
- "\x00O\x03\x06\x00\x00\x01N" + // 0x004F0306: 0x0000014E
- "\x00o\x03\x06\x00\x00\x01O" + // 0x006F0306: 0x0000014F
- "\x00O\x03\v\x00\x00\x01P" + // 0x004F030B: 0x00000150
- "\x00o\x03\v\x00\x00\x01Q" + // 0x006F030B: 0x00000151
- "\x00R\x03\x01\x00\x00\x01T" + // 0x00520301: 0x00000154
- "\x00r\x03\x01\x00\x00\x01U" + // 0x00720301: 0x00000155
- "\x00R\x03'\x00\x00\x01V" + // 0x00520327: 0x00000156
- "\x00r\x03'\x00\x00\x01W" + // 0x00720327: 0x00000157
- "\x00R\x03\f\x00\x00\x01X" + // 0x0052030C: 0x00000158
- "\x00r\x03\f\x00\x00\x01Y" + // 0x0072030C: 0x00000159
- "\x00S\x03\x01\x00\x00\x01Z" + // 0x00530301: 0x0000015A
- "\x00s\x03\x01\x00\x00\x01[" + // 0x00730301: 0x0000015B
- "\x00S\x03\x02\x00\x00\x01\\" + // 0x00530302: 0x0000015C
- "\x00s\x03\x02\x00\x00\x01]" + // 0x00730302: 0x0000015D
- "\x00S\x03'\x00\x00\x01^" + // 0x00530327: 0x0000015E
- "\x00s\x03'\x00\x00\x01_" + // 0x00730327: 0x0000015F
- "\x00S\x03\f\x00\x00\x01`" + // 0x0053030C: 0x00000160
- "\x00s\x03\f\x00\x00\x01a" + // 0x0073030C: 0x00000161
- "\x00T\x03'\x00\x00\x01b" + // 0x00540327: 0x00000162
- "\x00t\x03'\x00\x00\x01c" + // 0x00740327: 0x00000163
- "\x00T\x03\f\x00\x00\x01d" + // 0x0054030C: 0x00000164
- "\x00t\x03\f\x00\x00\x01e" + // 0x0074030C: 0x00000165
- "\x00U\x03\x03\x00\x00\x01h" + // 0x00550303: 0x00000168
- "\x00u\x03\x03\x00\x00\x01i" + // 0x00750303: 0x00000169
- "\x00U\x03\x04\x00\x00\x01j" + // 0x00550304: 0x0000016A
- "\x00u\x03\x04\x00\x00\x01k" + // 0x00750304: 0x0000016B
- "\x00U\x03\x06\x00\x00\x01l" + // 0x00550306: 0x0000016C
- "\x00u\x03\x06\x00\x00\x01m" + // 0x00750306: 0x0000016D
- "\x00U\x03\n\x00\x00\x01n" + // 0x0055030A: 0x0000016E
- "\x00u\x03\n\x00\x00\x01o" + // 0x0075030A: 0x0000016F
- "\x00U\x03\v\x00\x00\x01p" + // 0x0055030B: 0x00000170
- "\x00u\x03\v\x00\x00\x01q" + // 0x0075030B: 0x00000171
- "\x00U\x03(\x00\x00\x01r" + // 0x00550328: 0x00000172
- "\x00u\x03(\x00\x00\x01s" + // 0x00750328: 0x00000173
- "\x00W\x03\x02\x00\x00\x01t" + // 0x00570302: 0x00000174
- "\x00w\x03\x02\x00\x00\x01u" + // 0x00770302: 0x00000175
- "\x00Y\x03\x02\x00\x00\x01v" + // 0x00590302: 0x00000176
- "\x00y\x03\x02\x00\x00\x01w" + // 0x00790302: 0x00000177
- "\x00Y\x03\b\x00\x00\x01x" + // 0x00590308: 0x00000178
- "\x00Z\x03\x01\x00\x00\x01y" + // 0x005A0301: 0x00000179
- "\x00z\x03\x01\x00\x00\x01z" + // 0x007A0301: 0x0000017A
- "\x00Z\x03\a\x00\x00\x01{" + // 0x005A0307: 0x0000017B
- "\x00z\x03\a\x00\x00\x01|" + // 0x007A0307: 0x0000017C
- "\x00Z\x03\f\x00\x00\x01}" + // 0x005A030C: 0x0000017D
- "\x00z\x03\f\x00\x00\x01~" + // 0x007A030C: 0x0000017E
- "\x00O\x03\x1b\x00\x00\x01\xa0" + // 0x004F031B: 0x000001A0
- "\x00o\x03\x1b\x00\x00\x01\xa1" + // 0x006F031B: 0x000001A1
- "\x00U\x03\x1b\x00\x00\x01\xaf" + // 0x0055031B: 0x000001AF
- "\x00u\x03\x1b\x00\x00\x01\xb0" + // 0x0075031B: 0x000001B0
- "\x00A\x03\f\x00\x00\x01\xcd" + // 0x0041030C: 0x000001CD
- "\x00a\x03\f\x00\x00\x01\xce" + // 0x0061030C: 0x000001CE
- "\x00I\x03\f\x00\x00\x01\xcf" + // 0x0049030C: 0x000001CF
- "\x00i\x03\f\x00\x00\x01\xd0" + // 0x0069030C: 0x000001D0
- "\x00O\x03\f\x00\x00\x01\xd1" + // 0x004F030C: 0x000001D1
- "\x00o\x03\f\x00\x00\x01\xd2" + // 0x006F030C: 0x000001D2
- "\x00U\x03\f\x00\x00\x01\xd3" + // 0x0055030C: 0x000001D3
- "\x00u\x03\f\x00\x00\x01\xd4" + // 0x0075030C: 0x000001D4
- "\x00\xdc\x03\x04\x00\x00\x01\xd5" + // 0x00DC0304: 0x000001D5
- "\x00\xfc\x03\x04\x00\x00\x01\xd6" + // 0x00FC0304: 0x000001D6
- "\x00\xdc\x03\x01\x00\x00\x01\xd7" + // 0x00DC0301: 0x000001D7
- "\x00\xfc\x03\x01\x00\x00\x01\xd8" + // 0x00FC0301: 0x000001D8
- "\x00\xdc\x03\f\x00\x00\x01\xd9" + // 0x00DC030C: 0x000001D9
- "\x00\xfc\x03\f\x00\x00\x01\xda" + // 0x00FC030C: 0x000001DA
- "\x00\xdc\x03\x00\x00\x00\x01\xdb" + // 0x00DC0300: 0x000001DB
- "\x00\xfc\x03\x00\x00\x00\x01\xdc" + // 0x00FC0300: 0x000001DC
- "\x00\xc4\x03\x04\x00\x00\x01\xde" + // 0x00C40304: 0x000001DE
- "\x00\xe4\x03\x04\x00\x00\x01\xdf" + // 0x00E40304: 0x000001DF
- "\x02&\x03\x04\x00\x00\x01\xe0" + // 0x02260304: 0x000001E0
- "\x02'\x03\x04\x00\x00\x01\xe1" + // 0x02270304: 0x000001E1
- "\x00\xc6\x03\x04\x00\x00\x01\xe2" + // 0x00C60304: 0x000001E2
- "\x00\xe6\x03\x04\x00\x00\x01\xe3" + // 0x00E60304: 0x000001E3
- "\x00G\x03\f\x00\x00\x01\xe6" + // 0x0047030C: 0x000001E6
- "\x00g\x03\f\x00\x00\x01\xe7" + // 0x0067030C: 0x000001E7
- "\x00K\x03\f\x00\x00\x01\xe8" + // 0x004B030C: 0x000001E8
- "\x00k\x03\f\x00\x00\x01\xe9" + // 0x006B030C: 0x000001E9
- "\x00O\x03(\x00\x00\x01\xea" + // 0x004F0328: 0x000001EA
- "\x00o\x03(\x00\x00\x01\xeb" + // 0x006F0328: 0x000001EB
- "\x01\xea\x03\x04\x00\x00\x01\xec" + // 0x01EA0304: 0x000001EC
- "\x01\xeb\x03\x04\x00\x00\x01\xed" + // 0x01EB0304: 0x000001ED
- "\x01\xb7\x03\f\x00\x00\x01\xee" + // 0x01B7030C: 0x000001EE
- "\x02\x92\x03\f\x00\x00\x01\xef" + // 0x0292030C: 0x000001EF
- "\x00j\x03\f\x00\x00\x01\xf0" + // 0x006A030C: 0x000001F0
- "\x00G\x03\x01\x00\x00\x01\xf4" + // 0x00470301: 0x000001F4
- "\x00g\x03\x01\x00\x00\x01\xf5" + // 0x00670301: 0x000001F5
- "\x00N\x03\x00\x00\x00\x01\xf8" + // 0x004E0300: 0x000001F8
- "\x00n\x03\x00\x00\x00\x01\xf9" + // 0x006E0300: 0x000001F9
- "\x00\xc5\x03\x01\x00\x00\x01\xfa" + // 0x00C50301: 0x000001FA
- "\x00\xe5\x03\x01\x00\x00\x01\xfb" + // 0x00E50301: 0x000001FB
- "\x00\xc6\x03\x01\x00\x00\x01\xfc" + // 0x00C60301: 0x000001FC
- "\x00\xe6\x03\x01\x00\x00\x01\xfd" + // 0x00E60301: 0x000001FD
- "\x00\xd8\x03\x01\x00\x00\x01\xfe" + // 0x00D80301: 0x000001FE
- "\x00\xf8\x03\x01\x00\x00\x01\xff" + // 0x00F80301: 0x000001FF
- "\x00A\x03\x0f\x00\x00\x02\x00" + // 0x0041030F: 0x00000200
- "\x00a\x03\x0f\x00\x00\x02\x01" + // 0x0061030F: 0x00000201
- "\x00A\x03\x11\x00\x00\x02\x02" + // 0x00410311: 0x00000202
- "\x00a\x03\x11\x00\x00\x02\x03" + // 0x00610311: 0x00000203
- "\x00E\x03\x0f\x00\x00\x02\x04" + // 0x0045030F: 0x00000204
- "\x00e\x03\x0f\x00\x00\x02\x05" + // 0x0065030F: 0x00000205
- "\x00E\x03\x11\x00\x00\x02\x06" + // 0x00450311: 0x00000206
- "\x00e\x03\x11\x00\x00\x02\a" + // 0x00650311: 0x00000207
- "\x00I\x03\x0f\x00\x00\x02\b" + // 0x0049030F: 0x00000208
- "\x00i\x03\x0f\x00\x00\x02\t" + // 0x0069030F: 0x00000209
- "\x00I\x03\x11\x00\x00\x02\n" + // 0x00490311: 0x0000020A
- "\x00i\x03\x11\x00\x00\x02\v" + // 0x00690311: 0x0000020B
- "\x00O\x03\x0f\x00\x00\x02\f" + // 0x004F030F: 0x0000020C
- "\x00o\x03\x0f\x00\x00\x02\r" + // 0x006F030F: 0x0000020D
- "\x00O\x03\x11\x00\x00\x02\x0e" + // 0x004F0311: 0x0000020E
- "\x00o\x03\x11\x00\x00\x02\x0f" + // 0x006F0311: 0x0000020F
- "\x00R\x03\x0f\x00\x00\x02\x10" + // 0x0052030F: 0x00000210
- "\x00r\x03\x0f\x00\x00\x02\x11" + // 0x0072030F: 0x00000211
- "\x00R\x03\x11\x00\x00\x02\x12" + // 0x00520311: 0x00000212
- "\x00r\x03\x11\x00\x00\x02\x13" + // 0x00720311: 0x00000213
- "\x00U\x03\x0f\x00\x00\x02\x14" + // 0x0055030F: 0x00000214
- "\x00u\x03\x0f\x00\x00\x02\x15" + // 0x0075030F: 0x00000215
- "\x00U\x03\x11\x00\x00\x02\x16" + // 0x00550311: 0x00000216
- "\x00u\x03\x11\x00\x00\x02\x17" + // 0x00750311: 0x00000217
- "\x00S\x03&\x00\x00\x02\x18" + // 0x00530326: 0x00000218
- "\x00s\x03&\x00\x00\x02\x19" + // 0x00730326: 0x00000219
- "\x00T\x03&\x00\x00\x02\x1a" + // 0x00540326: 0x0000021A
- "\x00t\x03&\x00\x00\x02\x1b" + // 0x00740326: 0x0000021B
- "\x00H\x03\f\x00\x00\x02\x1e" + // 0x0048030C: 0x0000021E
- "\x00h\x03\f\x00\x00\x02\x1f" + // 0x0068030C: 0x0000021F
- "\x00A\x03\a\x00\x00\x02&" + // 0x00410307: 0x00000226
- "\x00a\x03\a\x00\x00\x02'" + // 0x00610307: 0x00000227
- "\x00E\x03'\x00\x00\x02(" + // 0x00450327: 0x00000228
- "\x00e\x03'\x00\x00\x02)" + // 0x00650327: 0x00000229
- "\x00\xd6\x03\x04\x00\x00\x02*" + // 0x00D60304: 0x0000022A
- "\x00\xf6\x03\x04\x00\x00\x02+" + // 0x00F60304: 0x0000022B
- "\x00\xd5\x03\x04\x00\x00\x02," + // 0x00D50304: 0x0000022C
- "\x00\xf5\x03\x04\x00\x00\x02-" + // 0x00F50304: 0x0000022D
- "\x00O\x03\a\x00\x00\x02." + // 0x004F0307: 0x0000022E
- "\x00o\x03\a\x00\x00\x02/" + // 0x006F0307: 0x0000022F
- "\x02.\x03\x04\x00\x00\x020" + // 0x022E0304: 0x00000230
- "\x02/\x03\x04\x00\x00\x021" + // 0x022F0304: 0x00000231
- "\x00Y\x03\x04\x00\x00\x022" + // 0x00590304: 0x00000232
- "\x00y\x03\x04\x00\x00\x023" + // 0x00790304: 0x00000233
- "\x00\xa8\x03\x01\x00\x00\x03\x85" + // 0x00A80301: 0x00000385
- "\x03\x91\x03\x01\x00\x00\x03\x86" + // 0x03910301: 0x00000386
- "\x03\x95\x03\x01\x00\x00\x03\x88" + // 0x03950301: 0x00000388
- "\x03\x97\x03\x01\x00\x00\x03\x89" + // 0x03970301: 0x00000389
- "\x03\x99\x03\x01\x00\x00\x03\x8a" + // 0x03990301: 0x0000038A
- "\x03\x9f\x03\x01\x00\x00\x03\x8c" + // 0x039F0301: 0x0000038C
- "\x03\xa5\x03\x01\x00\x00\x03\x8e" + // 0x03A50301: 0x0000038E
- "\x03\xa9\x03\x01\x00\x00\x03\x8f" + // 0x03A90301: 0x0000038F
- "\x03\xca\x03\x01\x00\x00\x03\x90" + // 0x03CA0301: 0x00000390
- "\x03\x99\x03\b\x00\x00\x03\xaa" + // 0x03990308: 0x000003AA
- "\x03\xa5\x03\b\x00\x00\x03\xab" + // 0x03A50308: 0x000003AB
- "\x03\xb1\x03\x01\x00\x00\x03\xac" + // 0x03B10301: 0x000003AC
- "\x03\xb5\x03\x01\x00\x00\x03\xad" + // 0x03B50301: 0x000003AD
- "\x03\xb7\x03\x01\x00\x00\x03\xae" + // 0x03B70301: 0x000003AE
- "\x03\xb9\x03\x01\x00\x00\x03\xaf" + // 0x03B90301: 0x000003AF
- "\x03\xcb\x03\x01\x00\x00\x03\xb0" + // 0x03CB0301: 0x000003B0
- "\x03\xb9\x03\b\x00\x00\x03\xca" + // 0x03B90308: 0x000003CA
- "\x03\xc5\x03\b\x00\x00\x03\xcb" + // 0x03C50308: 0x000003CB
- "\x03\xbf\x03\x01\x00\x00\x03\xcc" + // 0x03BF0301: 0x000003CC
- "\x03\xc5\x03\x01\x00\x00\x03\xcd" + // 0x03C50301: 0x000003CD
- "\x03\xc9\x03\x01\x00\x00\x03\xce" + // 0x03C90301: 0x000003CE
- "\x03\xd2\x03\x01\x00\x00\x03\xd3" + // 0x03D20301: 0x000003D3
- "\x03\xd2\x03\b\x00\x00\x03\xd4" + // 0x03D20308: 0x000003D4
- "\x04\x15\x03\x00\x00\x00\x04\x00" + // 0x04150300: 0x00000400
- "\x04\x15\x03\b\x00\x00\x04\x01" + // 0x04150308: 0x00000401
- "\x04\x13\x03\x01\x00\x00\x04\x03" + // 0x04130301: 0x00000403
- "\x04\x06\x03\b\x00\x00\x04\a" + // 0x04060308: 0x00000407
- "\x04\x1a\x03\x01\x00\x00\x04\f" + // 0x041A0301: 0x0000040C
- "\x04\x18\x03\x00\x00\x00\x04\r" + // 0x04180300: 0x0000040D
- "\x04#\x03\x06\x00\x00\x04\x0e" + // 0x04230306: 0x0000040E
- "\x04\x18\x03\x06\x00\x00\x04\x19" + // 0x04180306: 0x00000419
- "\x048\x03\x06\x00\x00\x049" + // 0x04380306: 0x00000439
- "\x045\x03\x00\x00\x00\x04P" + // 0x04350300: 0x00000450
- "\x045\x03\b\x00\x00\x04Q" + // 0x04350308: 0x00000451
- "\x043\x03\x01\x00\x00\x04S" + // 0x04330301: 0x00000453
- "\x04V\x03\b\x00\x00\x04W" + // 0x04560308: 0x00000457
- "\x04:\x03\x01\x00\x00\x04\\" + // 0x043A0301: 0x0000045C
- "\x048\x03\x00\x00\x00\x04]" + // 0x04380300: 0x0000045D
- "\x04C\x03\x06\x00\x00\x04^" + // 0x04430306: 0x0000045E
- "\x04t\x03\x0f\x00\x00\x04v" + // 0x0474030F: 0x00000476
- "\x04u\x03\x0f\x00\x00\x04w" + // 0x0475030F: 0x00000477
- "\x04\x16\x03\x06\x00\x00\x04\xc1" + // 0x04160306: 0x000004C1
- "\x046\x03\x06\x00\x00\x04\xc2" + // 0x04360306: 0x000004C2
- "\x04\x10\x03\x06\x00\x00\x04\xd0" + // 0x04100306: 0x000004D0
- "\x040\x03\x06\x00\x00\x04\xd1" + // 0x04300306: 0x000004D1
- "\x04\x10\x03\b\x00\x00\x04\xd2" + // 0x04100308: 0x000004D2
- "\x040\x03\b\x00\x00\x04\xd3" + // 0x04300308: 0x000004D3
- "\x04\x15\x03\x06\x00\x00\x04\xd6" + // 0x04150306: 0x000004D6
- "\x045\x03\x06\x00\x00\x04\xd7" + // 0x04350306: 0x000004D7
- "\x04\xd8\x03\b\x00\x00\x04\xda" + // 0x04D80308: 0x000004DA
- "\x04\xd9\x03\b\x00\x00\x04\xdb" + // 0x04D90308: 0x000004DB
- "\x04\x16\x03\b\x00\x00\x04\xdc" + // 0x04160308: 0x000004DC
- "\x046\x03\b\x00\x00\x04\xdd" + // 0x04360308: 0x000004DD
- "\x04\x17\x03\b\x00\x00\x04\xde" + // 0x04170308: 0x000004DE
- "\x047\x03\b\x00\x00\x04\xdf" + // 0x04370308: 0x000004DF
- "\x04\x18\x03\x04\x00\x00\x04\xe2" + // 0x04180304: 0x000004E2
- "\x048\x03\x04\x00\x00\x04\xe3" + // 0x04380304: 0x000004E3
- "\x04\x18\x03\b\x00\x00\x04\xe4" + // 0x04180308: 0x000004E4
- "\x048\x03\b\x00\x00\x04\xe5" + // 0x04380308: 0x000004E5
- "\x04\x1e\x03\b\x00\x00\x04\xe6" + // 0x041E0308: 0x000004E6
- "\x04>\x03\b\x00\x00\x04\xe7" + // 0x043E0308: 0x000004E7
- "\x04\xe8\x03\b\x00\x00\x04\xea" + // 0x04E80308: 0x000004EA
- "\x04\xe9\x03\b\x00\x00\x04\xeb" + // 0x04E90308: 0x000004EB
- "\x04-\x03\b\x00\x00\x04\xec" + // 0x042D0308: 0x000004EC
- "\x04M\x03\b\x00\x00\x04\xed" + // 0x044D0308: 0x000004ED
- "\x04#\x03\x04\x00\x00\x04\xee" + // 0x04230304: 0x000004EE
- "\x04C\x03\x04\x00\x00\x04\xef" + // 0x04430304: 0x000004EF
- "\x04#\x03\b\x00\x00\x04\xf0" + // 0x04230308: 0x000004F0
- "\x04C\x03\b\x00\x00\x04\xf1" + // 0x04430308: 0x000004F1
- "\x04#\x03\v\x00\x00\x04\xf2" + // 0x0423030B: 0x000004F2
- "\x04C\x03\v\x00\x00\x04\xf3" + // 0x0443030B: 0x000004F3
- "\x04'\x03\b\x00\x00\x04\xf4" + // 0x04270308: 0x000004F4
- "\x04G\x03\b\x00\x00\x04\xf5" + // 0x04470308: 0x000004F5
- "\x04+\x03\b\x00\x00\x04\xf8" + // 0x042B0308: 0x000004F8
- "\x04K\x03\b\x00\x00\x04\xf9" + // 0x044B0308: 0x000004F9
- "\x06'\x06S\x00\x00\x06\"" + // 0x06270653: 0x00000622
- "\x06'\x06T\x00\x00\x06#" + // 0x06270654: 0x00000623
- "\x06H\x06T\x00\x00\x06$" + // 0x06480654: 0x00000624
- "\x06'\x06U\x00\x00\x06%" + // 0x06270655: 0x00000625
- "\x06J\x06T\x00\x00\x06&" + // 0x064A0654: 0x00000626
- "\x06\xd5\x06T\x00\x00\x06\xc0" + // 0x06D50654: 0x000006C0
- "\x06\xc1\x06T\x00\x00\x06\xc2" + // 0x06C10654: 0x000006C2
- "\x06\xd2\x06T\x00\x00\x06\xd3" + // 0x06D20654: 0x000006D3
- "\t(\t<\x00\x00\t)" + // 0x0928093C: 0x00000929
- "\t0\t<\x00\x00\t1" + // 0x0930093C: 0x00000931
- "\t3\t<\x00\x00\t4" + // 0x0933093C: 0x00000934
- "\t\xc7\t\xbe\x00\x00\t\xcb" + // 0x09C709BE: 0x000009CB
- "\t\xc7\t\xd7\x00\x00\t\xcc" + // 0x09C709D7: 0x000009CC
- "\vG\vV\x00\x00\vH" + // 0x0B470B56: 0x00000B48
- "\vG\v>\x00\x00\vK" + // 0x0B470B3E: 0x00000B4B
- "\vG\vW\x00\x00\vL" + // 0x0B470B57: 0x00000B4C
- "\v\x92\v\xd7\x00\x00\v\x94" + // 0x0B920BD7: 0x00000B94
- "\v\xc6\v\xbe\x00\x00\v\xca" + // 0x0BC60BBE: 0x00000BCA
- "\v\xc7\v\xbe\x00\x00\v\xcb" + // 0x0BC70BBE: 0x00000BCB
- "\v\xc6\v\xd7\x00\x00\v\xcc" + // 0x0BC60BD7: 0x00000BCC
- "\fF\fV\x00\x00\fH" + // 0x0C460C56: 0x00000C48
- "\f\xbf\f\xd5\x00\x00\f\xc0" + // 0x0CBF0CD5: 0x00000CC0
- "\f\xc6\f\xd5\x00\x00\f\xc7" + // 0x0CC60CD5: 0x00000CC7
- "\f\xc6\f\xd6\x00\x00\f\xc8" + // 0x0CC60CD6: 0x00000CC8
- "\f\xc6\f\xc2\x00\x00\f\xca" + // 0x0CC60CC2: 0x00000CCA
- "\f\xca\f\xd5\x00\x00\f\xcb" + // 0x0CCA0CD5: 0x00000CCB
- "\rF\r>\x00\x00\rJ" + // 0x0D460D3E: 0x00000D4A
- "\rG\r>\x00\x00\rK" + // 0x0D470D3E: 0x00000D4B
- "\rF\rW\x00\x00\rL" + // 0x0D460D57: 0x00000D4C
- "\r\xd9\r\xca\x00\x00\r\xda" + // 0x0DD90DCA: 0x00000DDA
- "\r\xd9\r\xcf\x00\x00\r\xdc" + // 0x0DD90DCF: 0x00000DDC
- "\r\xdc\r\xca\x00\x00\r\xdd" + // 0x0DDC0DCA: 0x00000DDD
- "\r\xd9\r\xdf\x00\x00\r\xde" + // 0x0DD90DDF: 0x00000DDE
- "\x10%\x10.\x00\x00\x10&" + // 0x1025102E: 0x00001026
- "\x1b\x05\x1b5\x00\x00\x1b\x06" + // 0x1B051B35: 0x00001B06
- "\x1b\a\x1b5\x00\x00\x1b\b" + // 0x1B071B35: 0x00001B08
- "\x1b\t\x1b5\x00\x00\x1b\n" + // 0x1B091B35: 0x00001B0A
- "\x1b\v\x1b5\x00\x00\x1b\f" + // 0x1B0B1B35: 0x00001B0C
- "\x1b\r\x1b5\x00\x00\x1b\x0e" + // 0x1B0D1B35: 0x00001B0E
- "\x1b\x11\x1b5\x00\x00\x1b\x12" + // 0x1B111B35: 0x00001B12
- "\x1b:\x1b5\x00\x00\x1b;" + // 0x1B3A1B35: 0x00001B3B
- "\x1b<\x1b5\x00\x00\x1b=" + // 0x1B3C1B35: 0x00001B3D
- "\x1b>\x1b5\x00\x00\x1b@" + // 0x1B3E1B35: 0x00001B40
- "\x1b?\x1b5\x00\x00\x1bA" + // 0x1B3F1B35: 0x00001B41
- "\x1bB\x1b5\x00\x00\x1bC" + // 0x1B421B35: 0x00001B43
- "\x00A\x03%\x00\x00\x1e\x00" + // 0x00410325: 0x00001E00
- "\x00a\x03%\x00\x00\x1e\x01" + // 0x00610325: 0x00001E01
- "\x00B\x03\a\x00\x00\x1e\x02" + // 0x00420307: 0x00001E02
- "\x00b\x03\a\x00\x00\x1e\x03" + // 0x00620307: 0x00001E03
- "\x00B\x03#\x00\x00\x1e\x04" + // 0x00420323: 0x00001E04
- "\x00b\x03#\x00\x00\x1e\x05" + // 0x00620323: 0x00001E05
- "\x00B\x031\x00\x00\x1e\x06" + // 0x00420331: 0x00001E06
- "\x00b\x031\x00\x00\x1e\a" + // 0x00620331: 0x00001E07
- "\x00\xc7\x03\x01\x00\x00\x1e\b" + // 0x00C70301: 0x00001E08
- "\x00\xe7\x03\x01\x00\x00\x1e\t" + // 0x00E70301: 0x00001E09
- "\x00D\x03\a\x00\x00\x1e\n" + // 0x00440307: 0x00001E0A
- "\x00d\x03\a\x00\x00\x1e\v" + // 0x00640307: 0x00001E0B
- "\x00D\x03#\x00\x00\x1e\f" + // 0x00440323: 0x00001E0C
- "\x00d\x03#\x00\x00\x1e\r" + // 0x00640323: 0x00001E0D
- "\x00D\x031\x00\x00\x1e\x0e" + // 0x00440331: 0x00001E0E
- "\x00d\x031\x00\x00\x1e\x0f" + // 0x00640331: 0x00001E0F
- "\x00D\x03'\x00\x00\x1e\x10" + // 0x00440327: 0x00001E10
- "\x00d\x03'\x00\x00\x1e\x11" + // 0x00640327: 0x00001E11
- "\x00D\x03-\x00\x00\x1e\x12" + // 0x0044032D: 0x00001E12
- "\x00d\x03-\x00\x00\x1e\x13" + // 0x0064032D: 0x00001E13
- "\x01\x12\x03\x00\x00\x00\x1e\x14" + // 0x01120300: 0x00001E14
- "\x01\x13\x03\x00\x00\x00\x1e\x15" + // 0x01130300: 0x00001E15
- "\x01\x12\x03\x01\x00\x00\x1e\x16" + // 0x01120301: 0x00001E16
- "\x01\x13\x03\x01\x00\x00\x1e\x17" + // 0x01130301: 0x00001E17
- "\x00E\x03-\x00\x00\x1e\x18" + // 0x0045032D: 0x00001E18
- "\x00e\x03-\x00\x00\x1e\x19" + // 0x0065032D: 0x00001E19
- "\x00E\x030\x00\x00\x1e\x1a" + // 0x00450330: 0x00001E1A
- "\x00e\x030\x00\x00\x1e\x1b" + // 0x00650330: 0x00001E1B
- "\x02(\x03\x06\x00\x00\x1e\x1c" + // 0x02280306: 0x00001E1C
- "\x02)\x03\x06\x00\x00\x1e\x1d" + // 0x02290306: 0x00001E1D
- "\x00F\x03\a\x00\x00\x1e\x1e" + // 0x00460307: 0x00001E1E
- "\x00f\x03\a\x00\x00\x1e\x1f" + // 0x00660307: 0x00001E1F
- "\x00G\x03\x04\x00\x00\x1e " + // 0x00470304: 0x00001E20
- "\x00g\x03\x04\x00\x00\x1e!" + // 0x00670304: 0x00001E21
- "\x00H\x03\a\x00\x00\x1e\"" + // 0x00480307: 0x00001E22
- "\x00h\x03\a\x00\x00\x1e#" + // 0x00680307: 0x00001E23
- "\x00H\x03#\x00\x00\x1e$" + // 0x00480323: 0x00001E24
- "\x00h\x03#\x00\x00\x1e%" + // 0x00680323: 0x00001E25
- "\x00H\x03\b\x00\x00\x1e&" + // 0x00480308: 0x00001E26
- "\x00h\x03\b\x00\x00\x1e'" + // 0x00680308: 0x00001E27
- "\x00H\x03'\x00\x00\x1e(" + // 0x00480327: 0x00001E28
- "\x00h\x03'\x00\x00\x1e)" + // 0x00680327: 0x00001E29
- "\x00H\x03.\x00\x00\x1e*" + // 0x0048032E: 0x00001E2A
- "\x00h\x03.\x00\x00\x1e+" + // 0x0068032E: 0x00001E2B
- "\x00I\x030\x00\x00\x1e," + // 0x00490330: 0x00001E2C
- "\x00i\x030\x00\x00\x1e-" + // 0x00690330: 0x00001E2D
- "\x00\xcf\x03\x01\x00\x00\x1e." + // 0x00CF0301: 0x00001E2E
- "\x00\xef\x03\x01\x00\x00\x1e/" + // 0x00EF0301: 0x00001E2F
- "\x00K\x03\x01\x00\x00\x1e0" + // 0x004B0301: 0x00001E30
- "\x00k\x03\x01\x00\x00\x1e1" + // 0x006B0301: 0x00001E31
- "\x00K\x03#\x00\x00\x1e2" + // 0x004B0323: 0x00001E32
- "\x00k\x03#\x00\x00\x1e3" + // 0x006B0323: 0x00001E33
- "\x00K\x031\x00\x00\x1e4" + // 0x004B0331: 0x00001E34
- "\x00k\x031\x00\x00\x1e5" + // 0x006B0331: 0x00001E35
- "\x00L\x03#\x00\x00\x1e6" + // 0x004C0323: 0x00001E36
- "\x00l\x03#\x00\x00\x1e7" + // 0x006C0323: 0x00001E37
- "\x1e6\x03\x04\x00\x00\x1e8" + // 0x1E360304: 0x00001E38
- "\x1e7\x03\x04\x00\x00\x1e9" + // 0x1E370304: 0x00001E39
- "\x00L\x031\x00\x00\x1e:" + // 0x004C0331: 0x00001E3A
- "\x00l\x031\x00\x00\x1e;" + // 0x006C0331: 0x00001E3B
- "\x00L\x03-\x00\x00\x1e<" + // 0x004C032D: 0x00001E3C
- "\x00l\x03-\x00\x00\x1e=" + // 0x006C032D: 0x00001E3D
- "\x00M\x03\x01\x00\x00\x1e>" + // 0x004D0301: 0x00001E3E
- "\x00m\x03\x01\x00\x00\x1e?" + // 0x006D0301: 0x00001E3F
- "\x00M\x03\a\x00\x00\x1e@" + // 0x004D0307: 0x00001E40
- "\x00m\x03\a\x00\x00\x1eA" + // 0x006D0307: 0x00001E41
- "\x00M\x03#\x00\x00\x1eB" + // 0x004D0323: 0x00001E42
- "\x00m\x03#\x00\x00\x1eC" + // 0x006D0323: 0x00001E43
- "\x00N\x03\a\x00\x00\x1eD" + // 0x004E0307: 0x00001E44
- "\x00n\x03\a\x00\x00\x1eE" + // 0x006E0307: 0x00001E45
- "\x00N\x03#\x00\x00\x1eF" + // 0x004E0323: 0x00001E46
- "\x00n\x03#\x00\x00\x1eG" + // 0x006E0323: 0x00001E47
- "\x00N\x031\x00\x00\x1eH" + // 0x004E0331: 0x00001E48
- "\x00n\x031\x00\x00\x1eI" + // 0x006E0331: 0x00001E49
- "\x00N\x03-\x00\x00\x1eJ" + // 0x004E032D: 0x00001E4A
- "\x00n\x03-\x00\x00\x1eK" + // 0x006E032D: 0x00001E4B
- "\x00\xd5\x03\x01\x00\x00\x1eL" + // 0x00D50301: 0x00001E4C
- "\x00\xf5\x03\x01\x00\x00\x1eM" + // 0x00F50301: 0x00001E4D
- "\x00\xd5\x03\b\x00\x00\x1eN" + // 0x00D50308: 0x00001E4E
- "\x00\xf5\x03\b\x00\x00\x1eO" + // 0x00F50308: 0x00001E4F
- "\x01L\x03\x00\x00\x00\x1eP" + // 0x014C0300: 0x00001E50
- "\x01M\x03\x00\x00\x00\x1eQ" + // 0x014D0300: 0x00001E51
- "\x01L\x03\x01\x00\x00\x1eR" + // 0x014C0301: 0x00001E52
- "\x01M\x03\x01\x00\x00\x1eS" + // 0x014D0301: 0x00001E53
- "\x00P\x03\x01\x00\x00\x1eT" + // 0x00500301: 0x00001E54
- "\x00p\x03\x01\x00\x00\x1eU" + // 0x00700301: 0x00001E55
- "\x00P\x03\a\x00\x00\x1eV" + // 0x00500307: 0x00001E56
- "\x00p\x03\a\x00\x00\x1eW" + // 0x00700307: 0x00001E57
- "\x00R\x03\a\x00\x00\x1eX" + // 0x00520307: 0x00001E58
- "\x00r\x03\a\x00\x00\x1eY" + // 0x00720307: 0x00001E59
- "\x00R\x03#\x00\x00\x1eZ" + // 0x00520323: 0x00001E5A
- "\x00r\x03#\x00\x00\x1e[" + // 0x00720323: 0x00001E5B
- "\x1eZ\x03\x04\x00\x00\x1e\\" + // 0x1E5A0304: 0x00001E5C
- "\x1e[\x03\x04\x00\x00\x1e]" + // 0x1E5B0304: 0x00001E5D
- "\x00R\x031\x00\x00\x1e^" + // 0x00520331: 0x00001E5E
- "\x00r\x031\x00\x00\x1e_" + // 0x00720331: 0x00001E5F
- "\x00S\x03\a\x00\x00\x1e`" + // 0x00530307: 0x00001E60
- "\x00s\x03\a\x00\x00\x1ea" + // 0x00730307: 0x00001E61
- "\x00S\x03#\x00\x00\x1eb" + // 0x00530323: 0x00001E62
- "\x00s\x03#\x00\x00\x1ec" + // 0x00730323: 0x00001E63
- "\x01Z\x03\a\x00\x00\x1ed" + // 0x015A0307: 0x00001E64
- "\x01[\x03\a\x00\x00\x1ee" + // 0x015B0307: 0x00001E65
- "\x01`\x03\a\x00\x00\x1ef" + // 0x01600307: 0x00001E66
- "\x01a\x03\a\x00\x00\x1eg" + // 0x01610307: 0x00001E67
- "\x1eb\x03\a\x00\x00\x1eh" + // 0x1E620307: 0x00001E68
- "\x1ec\x03\a\x00\x00\x1ei" + // 0x1E630307: 0x00001E69
- "\x00T\x03\a\x00\x00\x1ej" + // 0x00540307: 0x00001E6A
- "\x00t\x03\a\x00\x00\x1ek" + // 0x00740307: 0x00001E6B
- "\x00T\x03#\x00\x00\x1el" + // 0x00540323: 0x00001E6C
- "\x00t\x03#\x00\x00\x1em" + // 0x00740323: 0x00001E6D
- "\x00T\x031\x00\x00\x1en" + // 0x00540331: 0x00001E6E
- "\x00t\x031\x00\x00\x1eo" + // 0x00740331: 0x00001E6F
- "\x00T\x03-\x00\x00\x1ep" + // 0x0054032D: 0x00001E70
- "\x00t\x03-\x00\x00\x1eq" + // 0x0074032D: 0x00001E71
- "\x00U\x03$\x00\x00\x1er" + // 0x00550324: 0x00001E72
- "\x00u\x03$\x00\x00\x1es" + // 0x00750324: 0x00001E73
- "\x00U\x030\x00\x00\x1et" + // 0x00550330: 0x00001E74
- "\x00u\x030\x00\x00\x1eu" + // 0x00750330: 0x00001E75
- "\x00U\x03-\x00\x00\x1ev" + // 0x0055032D: 0x00001E76
- "\x00u\x03-\x00\x00\x1ew" + // 0x0075032D: 0x00001E77
- "\x01h\x03\x01\x00\x00\x1ex" + // 0x01680301: 0x00001E78
- "\x01i\x03\x01\x00\x00\x1ey" + // 0x01690301: 0x00001E79
- "\x01j\x03\b\x00\x00\x1ez" + // 0x016A0308: 0x00001E7A
- "\x01k\x03\b\x00\x00\x1e{" + // 0x016B0308: 0x00001E7B
- "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C
- "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D
- "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E
- "\x00v\x03#\x00\x00\x1e\x7f" + // 0x00760323: 0x00001E7F
- "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80
- "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81
- "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82
- "\x00w\x03\x01\x00\x00\x1e\x83" + // 0x00770301: 0x00001E83
- "\x00W\x03\b\x00\x00\x1e\x84" + // 0x00570308: 0x00001E84
- "\x00w\x03\b\x00\x00\x1e\x85" + // 0x00770308: 0x00001E85
- "\x00W\x03\a\x00\x00\x1e\x86" + // 0x00570307: 0x00001E86
- "\x00w\x03\a\x00\x00\x1e\x87" + // 0x00770307: 0x00001E87
- "\x00W\x03#\x00\x00\x1e\x88" + // 0x00570323: 0x00001E88
- "\x00w\x03#\x00\x00\x1e\x89" + // 0x00770323: 0x00001E89
- "\x00X\x03\a\x00\x00\x1e\x8a" + // 0x00580307: 0x00001E8A
- "\x00x\x03\a\x00\x00\x1e\x8b" + // 0x00780307: 0x00001E8B
- "\x00X\x03\b\x00\x00\x1e\x8c" + // 0x00580308: 0x00001E8C
- "\x00x\x03\b\x00\x00\x1e\x8d" + // 0x00780308: 0x00001E8D
- "\x00Y\x03\a\x00\x00\x1e\x8e" + // 0x00590307: 0x00001E8E
- "\x00y\x03\a\x00\x00\x1e\x8f" + // 0x00790307: 0x00001E8F
- "\x00Z\x03\x02\x00\x00\x1e\x90" + // 0x005A0302: 0x00001E90
- "\x00z\x03\x02\x00\x00\x1e\x91" + // 0x007A0302: 0x00001E91
- "\x00Z\x03#\x00\x00\x1e\x92" + // 0x005A0323: 0x00001E92
- "\x00z\x03#\x00\x00\x1e\x93" + // 0x007A0323: 0x00001E93
- "\x00Z\x031\x00\x00\x1e\x94" + // 0x005A0331: 0x00001E94
- "\x00z\x031\x00\x00\x1e\x95" + // 0x007A0331: 0x00001E95
- "\x00h\x031\x00\x00\x1e\x96" + // 0x00680331: 0x00001E96
- "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97
- "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98
- "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99
- "\x01\x7f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B
- "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0
- "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1
- "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2
- "\x00a\x03\t\x00\x00\x1e\xa3" + // 0x00610309: 0x00001EA3
- "\x00\xc2\x03\x01\x00\x00\x1e\xa4" + // 0x00C20301: 0x00001EA4
- "\x00\xe2\x03\x01\x00\x00\x1e\xa5" + // 0x00E20301: 0x00001EA5
- "\x00\xc2\x03\x00\x00\x00\x1e\xa6" + // 0x00C20300: 0x00001EA6
- "\x00\xe2\x03\x00\x00\x00\x1e\xa7" + // 0x00E20300: 0x00001EA7
- "\x00\xc2\x03\t\x00\x00\x1e\xa8" + // 0x00C20309: 0x00001EA8
- "\x00\xe2\x03\t\x00\x00\x1e\xa9" + // 0x00E20309: 0x00001EA9
- "\x00\xc2\x03\x03\x00\x00\x1e\xaa" + // 0x00C20303: 0x00001EAA
- "\x00\xe2\x03\x03\x00\x00\x1e\xab" + // 0x00E20303: 0x00001EAB
- "\x1e\xa0\x03\x02\x00\x00\x1e\xac" + // 0x1EA00302: 0x00001EAC
- "\x1e\xa1\x03\x02\x00\x00\x1e\xad" + // 0x1EA10302: 0x00001EAD
- "\x01\x02\x03\x01\x00\x00\x1e\xae" + // 0x01020301: 0x00001EAE
- "\x01\x03\x03\x01\x00\x00\x1e\xaf" + // 0x01030301: 0x00001EAF
- "\x01\x02\x03\x00\x00\x00\x1e\xb0" + // 0x01020300: 0x00001EB0
- "\x01\x03\x03\x00\x00\x00\x1e\xb1" + // 0x01030300: 0x00001EB1
- "\x01\x02\x03\t\x00\x00\x1e\xb2" + // 0x01020309: 0x00001EB2
- "\x01\x03\x03\t\x00\x00\x1e\xb3" + // 0x01030309: 0x00001EB3
- "\x01\x02\x03\x03\x00\x00\x1e\xb4" + // 0x01020303: 0x00001EB4
- "\x01\x03\x03\x03\x00\x00\x1e\xb5" + // 0x01030303: 0x00001EB5
- "\x1e\xa0\x03\x06\x00\x00\x1e\xb6" + // 0x1EA00306: 0x00001EB6
- "\x1e\xa1\x03\x06\x00\x00\x1e\xb7" + // 0x1EA10306: 0x00001EB7
- "\x00E\x03#\x00\x00\x1e\xb8" + // 0x00450323: 0x00001EB8
- "\x00e\x03#\x00\x00\x1e\xb9" + // 0x00650323: 0x00001EB9
- "\x00E\x03\t\x00\x00\x1e\xba" + // 0x00450309: 0x00001EBA
- "\x00e\x03\t\x00\x00\x1e\xbb" + // 0x00650309: 0x00001EBB
- "\x00E\x03\x03\x00\x00\x1e\xbc" + // 0x00450303: 0x00001EBC
- "\x00e\x03\x03\x00\x00\x1e\xbd" + // 0x00650303: 0x00001EBD
- "\x00\xca\x03\x01\x00\x00\x1e\xbe" + // 0x00CA0301: 0x00001EBE
- "\x00\xea\x03\x01\x00\x00\x1e\xbf" + // 0x00EA0301: 0x00001EBF
- "\x00\xca\x03\x00\x00\x00\x1e\xc0" + // 0x00CA0300: 0x00001EC0
- "\x00\xea\x03\x00\x00\x00\x1e\xc1" + // 0x00EA0300: 0x00001EC1
- "\x00\xca\x03\t\x00\x00\x1e\xc2" + // 0x00CA0309: 0x00001EC2
- "\x00\xea\x03\t\x00\x00\x1e\xc3" + // 0x00EA0309: 0x00001EC3
- "\x00\xca\x03\x03\x00\x00\x1e\xc4" + // 0x00CA0303: 0x00001EC4
- "\x00\xea\x03\x03\x00\x00\x1e\xc5" + // 0x00EA0303: 0x00001EC5
- "\x1e\xb8\x03\x02\x00\x00\x1e\xc6" + // 0x1EB80302: 0x00001EC6
- "\x1e\xb9\x03\x02\x00\x00\x1e\xc7" + // 0x1EB90302: 0x00001EC7
- "\x00I\x03\t\x00\x00\x1e\xc8" + // 0x00490309: 0x00001EC8
- "\x00i\x03\t\x00\x00\x1e\xc9" + // 0x00690309: 0x00001EC9
- "\x00I\x03#\x00\x00\x1e\xca" + // 0x00490323: 0x00001ECA
- "\x00i\x03#\x00\x00\x1e\xcb" + // 0x00690323: 0x00001ECB
- "\x00O\x03#\x00\x00\x1e\xcc" + // 0x004F0323: 0x00001ECC
- "\x00o\x03#\x00\x00\x1e\xcd" + // 0x006F0323: 0x00001ECD
- "\x00O\x03\t\x00\x00\x1e\xce" + // 0x004F0309: 0x00001ECE
- "\x00o\x03\t\x00\x00\x1e\xcf" + // 0x006F0309: 0x00001ECF
- "\x00\xd4\x03\x01\x00\x00\x1e\xd0" + // 0x00D40301: 0x00001ED0
- "\x00\xf4\x03\x01\x00\x00\x1e\xd1" + // 0x00F40301: 0x00001ED1
- "\x00\xd4\x03\x00\x00\x00\x1e\xd2" + // 0x00D40300: 0x00001ED2
- "\x00\xf4\x03\x00\x00\x00\x1e\xd3" + // 0x00F40300: 0x00001ED3
- "\x00\xd4\x03\t\x00\x00\x1e\xd4" + // 0x00D40309: 0x00001ED4
- "\x00\xf4\x03\t\x00\x00\x1e\xd5" + // 0x00F40309: 0x00001ED5
- "\x00\xd4\x03\x03\x00\x00\x1e\xd6" + // 0x00D40303: 0x00001ED6
- "\x00\xf4\x03\x03\x00\x00\x1e\xd7" + // 0x00F40303: 0x00001ED7
- "\x1e\xcc\x03\x02\x00\x00\x1e\xd8" + // 0x1ECC0302: 0x00001ED8
- "\x1e\xcd\x03\x02\x00\x00\x1e\xd9" + // 0x1ECD0302: 0x00001ED9
- "\x01\xa0\x03\x01\x00\x00\x1e\xda" + // 0x01A00301: 0x00001EDA
- "\x01\xa1\x03\x01\x00\x00\x1e\xdb" + // 0x01A10301: 0x00001EDB
- "\x01\xa0\x03\x00\x00\x00\x1e\xdc" + // 0x01A00300: 0x00001EDC
- "\x01\xa1\x03\x00\x00\x00\x1e\xdd" + // 0x01A10300: 0x00001EDD
- "\x01\xa0\x03\t\x00\x00\x1e\xde" + // 0x01A00309: 0x00001EDE
- "\x01\xa1\x03\t\x00\x00\x1e\xdf" + // 0x01A10309: 0x00001EDF
- "\x01\xa0\x03\x03\x00\x00\x1e\xe0" + // 0x01A00303: 0x00001EE0
- "\x01\xa1\x03\x03\x00\x00\x1e\xe1" + // 0x01A10303: 0x00001EE1
- "\x01\xa0\x03#\x00\x00\x1e\xe2" + // 0x01A00323: 0x00001EE2
- "\x01\xa1\x03#\x00\x00\x1e\xe3" + // 0x01A10323: 0x00001EE3
- "\x00U\x03#\x00\x00\x1e\xe4" + // 0x00550323: 0x00001EE4
- "\x00u\x03#\x00\x00\x1e\xe5" + // 0x00750323: 0x00001EE5
- "\x00U\x03\t\x00\x00\x1e\xe6" + // 0x00550309: 0x00001EE6
- "\x00u\x03\t\x00\x00\x1e\xe7" + // 0x00750309: 0x00001EE7
- "\x01\xaf\x03\x01\x00\x00\x1e\xe8" + // 0x01AF0301: 0x00001EE8
- "\x01\xb0\x03\x01\x00\x00\x1e\xe9" + // 0x01B00301: 0x00001EE9
- "\x01\xaf\x03\x00\x00\x00\x1e\xea" + // 0x01AF0300: 0x00001EEA
- "\x01\xb0\x03\x00\x00\x00\x1e\xeb" + // 0x01B00300: 0x00001EEB
- "\x01\xaf\x03\t\x00\x00\x1e\xec" + // 0x01AF0309: 0x00001EEC
- "\x01\xb0\x03\t\x00\x00\x1e\xed" + // 0x01B00309: 0x00001EED
- "\x01\xaf\x03\x03\x00\x00\x1e\xee" + // 0x01AF0303: 0x00001EEE
- "\x01\xb0\x03\x03\x00\x00\x1e\xef" + // 0x01B00303: 0x00001EEF
- "\x01\xaf\x03#\x00\x00\x1e\xf0" + // 0x01AF0323: 0x00001EF0
- "\x01\xb0\x03#\x00\x00\x1e\xf1" + // 0x01B00323: 0x00001EF1
- "\x00Y\x03\x00\x00\x00\x1e\xf2" + // 0x00590300: 0x00001EF2
- "\x00y\x03\x00\x00\x00\x1e\xf3" + // 0x00790300: 0x00001EF3
- "\x00Y\x03#\x00\x00\x1e\xf4" + // 0x00590323: 0x00001EF4
- "\x00y\x03#\x00\x00\x1e\xf5" + // 0x00790323: 0x00001EF5
- "\x00Y\x03\t\x00\x00\x1e\xf6" + // 0x00590309: 0x00001EF6
- "\x00y\x03\t\x00\x00\x1e\xf7" + // 0x00790309: 0x00001EF7
- "\x00Y\x03\x03\x00\x00\x1e\xf8" + // 0x00590303: 0x00001EF8
- "\x00y\x03\x03\x00\x00\x1e\xf9" + // 0x00790303: 0x00001EF9
- "\x03\xb1\x03\x13\x00\x00\x1f\x00" + // 0x03B10313: 0x00001F00
- "\x03\xb1\x03\x14\x00\x00\x1f\x01" + // 0x03B10314: 0x00001F01
- "\x1f\x00\x03\x00\x00\x00\x1f\x02" + // 0x1F000300: 0x00001F02
- "\x1f\x01\x03\x00\x00\x00\x1f\x03" + // 0x1F010300: 0x00001F03
- "\x1f\x00\x03\x01\x00\x00\x1f\x04" + // 0x1F000301: 0x00001F04
- "\x1f\x01\x03\x01\x00\x00\x1f\x05" + // 0x1F010301: 0x00001F05
- "\x1f\x00\x03B\x00\x00\x1f\x06" + // 0x1F000342: 0x00001F06
- "\x1f\x01\x03B\x00\x00\x1f\a" + // 0x1F010342: 0x00001F07
- "\x03\x91\x03\x13\x00\x00\x1f\b" + // 0x03910313: 0x00001F08
- "\x03\x91\x03\x14\x00\x00\x1f\t" + // 0x03910314: 0x00001F09
- "\x1f\b\x03\x00\x00\x00\x1f\n" + // 0x1F080300: 0x00001F0A
- "\x1f\t\x03\x00\x00\x00\x1f\v" + // 0x1F090300: 0x00001F0B
- "\x1f\b\x03\x01\x00\x00\x1f\f" + // 0x1F080301: 0x00001F0C
- "\x1f\t\x03\x01\x00\x00\x1f\r" + // 0x1F090301: 0x00001F0D
- "\x1f\b\x03B\x00\x00\x1f\x0e" + // 0x1F080342: 0x00001F0E
- "\x1f\t\x03B\x00\x00\x1f\x0f" + // 0x1F090342: 0x00001F0F
- "\x03\xb5\x03\x13\x00\x00\x1f\x10" + // 0x03B50313: 0x00001F10
- "\x03\xb5\x03\x14\x00\x00\x1f\x11" + // 0x03B50314: 0x00001F11
- "\x1f\x10\x03\x00\x00\x00\x1f\x12" + // 0x1F100300: 0x00001F12
- "\x1f\x11\x03\x00\x00\x00\x1f\x13" + // 0x1F110300: 0x00001F13
- "\x1f\x10\x03\x01\x00\x00\x1f\x14" + // 0x1F100301: 0x00001F14
- "\x1f\x11\x03\x01\x00\x00\x1f\x15" + // 0x1F110301: 0x00001F15
- "\x03\x95\x03\x13\x00\x00\x1f\x18" + // 0x03950313: 0x00001F18
- "\x03\x95\x03\x14\x00\x00\x1f\x19" + // 0x03950314: 0x00001F19
- "\x1f\x18\x03\x00\x00\x00\x1f\x1a" + // 0x1F180300: 0x00001F1A
- "\x1f\x19\x03\x00\x00\x00\x1f\x1b" + // 0x1F190300: 0x00001F1B
- "\x1f\x18\x03\x01\x00\x00\x1f\x1c" + // 0x1F180301: 0x00001F1C
- "\x1f\x19\x03\x01\x00\x00\x1f\x1d" + // 0x1F190301: 0x00001F1D
- "\x03\xb7\x03\x13\x00\x00\x1f " + // 0x03B70313: 0x00001F20
- "\x03\xb7\x03\x14\x00\x00\x1f!" + // 0x03B70314: 0x00001F21
- "\x1f \x03\x00\x00\x00\x1f\"" + // 0x1F200300: 0x00001F22
- "\x1f!\x03\x00\x00\x00\x1f#" + // 0x1F210300: 0x00001F23
- "\x1f \x03\x01\x00\x00\x1f$" + // 0x1F200301: 0x00001F24
- "\x1f!\x03\x01\x00\x00\x1f%" + // 0x1F210301: 0x00001F25
- "\x1f \x03B\x00\x00\x1f&" + // 0x1F200342: 0x00001F26
- "\x1f!\x03B\x00\x00\x1f'" + // 0x1F210342: 0x00001F27
- "\x03\x97\x03\x13\x00\x00\x1f(" + // 0x03970313: 0x00001F28
- "\x03\x97\x03\x14\x00\x00\x1f)" + // 0x03970314: 0x00001F29
- "\x1f(\x03\x00\x00\x00\x1f*" + // 0x1F280300: 0x00001F2A
- "\x1f)\x03\x00\x00\x00\x1f+" + // 0x1F290300: 0x00001F2B
- "\x1f(\x03\x01\x00\x00\x1f," + // 0x1F280301: 0x00001F2C
- "\x1f)\x03\x01\x00\x00\x1f-" + // 0x1F290301: 0x00001F2D
- "\x1f(\x03B\x00\x00\x1f." + // 0x1F280342: 0x00001F2E
- "\x1f)\x03B\x00\x00\x1f/" + // 0x1F290342: 0x00001F2F
- "\x03\xb9\x03\x13\x00\x00\x1f0" + // 0x03B90313: 0x00001F30
- "\x03\xb9\x03\x14\x00\x00\x1f1" + // 0x03B90314: 0x00001F31
- "\x1f0\x03\x00\x00\x00\x1f2" + // 0x1F300300: 0x00001F32
- "\x1f1\x03\x00\x00\x00\x1f3" + // 0x1F310300: 0x00001F33
- "\x1f0\x03\x01\x00\x00\x1f4" + // 0x1F300301: 0x00001F34
- "\x1f1\x03\x01\x00\x00\x1f5" + // 0x1F310301: 0x00001F35
- "\x1f0\x03B\x00\x00\x1f6" + // 0x1F300342: 0x00001F36
- "\x1f1\x03B\x00\x00\x1f7" + // 0x1F310342: 0x00001F37
- "\x03\x99\x03\x13\x00\x00\x1f8" + // 0x03990313: 0x00001F38
- "\x03\x99\x03\x14\x00\x00\x1f9" + // 0x03990314: 0x00001F39
- "\x1f8\x03\x00\x00\x00\x1f:" + // 0x1F380300: 0x00001F3A
- "\x1f9\x03\x00\x00\x00\x1f;" + // 0x1F390300: 0x00001F3B
- "\x1f8\x03\x01\x00\x00\x1f<" + // 0x1F380301: 0x00001F3C
- "\x1f9\x03\x01\x00\x00\x1f=" + // 0x1F390301: 0x00001F3D
- "\x1f8\x03B\x00\x00\x1f>" + // 0x1F380342: 0x00001F3E
- "\x1f9\x03B\x00\x00\x1f?" + // 0x1F390342: 0x00001F3F
- "\x03\xbf\x03\x13\x00\x00\x1f@" + // 0x03BF0313: 0x00001F40
- "\x03\xbf\x03\x14\x00\x00\x1fA" + // 0x03BF0314: 0x00001F41
- "\x1f@\x03\x00\x00\x00\x1fB" + // 0x1F400300: 0x00001F42
- "\x1fA\x03\x00\x00\x00\x1fC" + // 0x1F410300: 0x00001F43
- "\x1f@\x03\x01\x00\x00\x1fD" + // 0x1F400301: 0x00001F44
- "\x1fA\x03\x01\x00\x00\x1fE" + // 0x1F410301: 0x00001F45
- "\x03\x9f\x03\x13\x00\x00\x1fH" + // 0x039F0313: 0x00001F48
- "\x03\x9f\x03\x14\x00\x00\x1fI" + // 0x039F0314: 0x00001F49
- "\x1fH\x03\x00\x00\x00\x1fJ" + // 0x1F480300: 0x00001F4A
- "\x1fI\x03\x00\x00\x00\x1fK" + // 0x1F490300: 0x00001F4B
- "\x1fH\x03\x01\x00\x00\x1fL" + // 0x1F480301: 0x00001F4C
- "\x1fI\x03\x01\x00\x00\x1fM" + // 0x1F490301: 0x00001F4D
- "\x03\xc5\x03\x13\x00\x00\x1fP" + // 0x03C50313: 0x00001F50
- "\x03\xc5\x03\x14\x00\x00\x1fQ" + // 0x03C50314: 0x00001F51
- "\x1fP\x03\x00\x00\x00\x1fR" + // 0x1F500300: 0x00001F52
- "\x1fQ\x03\x00\x00\x00\x1fS" + // 0x1F510300: 0x00001F53
- "\x1fP\x03\x01\x00\x00\x1fT" + // 0x1F500301: 0x00001F54
- "\x1fQ\x03\x01\x00\x00\x1fU" + // 0x1F510301: 0x00001F55
- "\x1fP\x03B\x00\x00\x1fV" + // 0x1F500342: 0x00001F56
- "\x1fQ\x03B\x00\x00\x1fW" + // 0x1F510342: 0x00001F57
- "\x03\xa5\x03\x14\x00\x00\x1fY" + // 0x03A50314: 0x00001F59
- "\x1fY\x03\x00\x00\x00\x1f[" + // 0x1F590300: 0x00001F5B
- "\x1fY\x03\x01\x00\x00\x1f]" + // 0x1F590301: 0x00001F5D
- "\x1fY\x03B\x00\x00\x1f_" + // 0x1F590342: 0x00001F5F
- "\x03\xc9\x03\x13\x00\x00\x1f`" + // 0x03C90313: 0x00001F60
- "\x03\xc9\x03\x14\x00\x00\x1fa" + // 0x03C90314: 0x00001F61
- "\x1f`\x03\x00\x00\x00\x1fb" + // 0x1F600300: 0x00001F62
- "\x1fa\x03\x00\x00\x00\x1fc" + // 0x1F610300: 0x00001F63
- "\x1f`\x03\x01\x00\x00\x1fd" + // 0x1F600301: 0x00001F64
- "\x1fa\x03\x01\x00\x00\x1fe" + // 0x1F610301: 0x00001F65
- "\x1f`\x03B\x00\x00\x1ff" + // 0x1F600342: 0x00001F66
- "\x1fa\x03B\x00\x00\x1fg" + // 0x1F610342: 0x00001F67
- "\x03\xa9\x03\x13\x00\x00\x1fh" + // 0x03A90313: 0x00001F68
- "\x03\xa9\x03\x14\x00\x00\x1fi" + // 0x03A90314: 0x00001F69
- "\x1fh\x03\x00\x00\x00\x1fj" + // 0x1F680300: 0x00001F6A
- "\x1fi\x03\x00\x00\x00\x1fk" + // 0x1F690300: 0x00001F6B
- "\x1fh\x03\x01\x00\x00\x1fl" + // 0x1F680301: 0x00001F6C
- "\x1fi\x03\x01\x00\x00\x1fm" + // 0x1F690301: 0x00001F6D
- "\x1fh\x03B\x00\x00\x1fn" + // 0x1F680342: 0x00001F6E
- "\x1fi\x03B\x00\x00\x1fo" + // 0x1F690342: 0x00001F6F
- "\x03\xb1\x03\x00\x00\x00\x1fp" + // 0x03B10300: 0x00001F70
- "\x03\xb5\x03\x00\x00\x00\x1fr" + // 0x03B50300: 0x00001F72
- "\x03\xb7\x03\x00\x00\x00\x1ft" + // 0x03B70300: 0x00001F74
- "\x03\xb9\x03\x00\x00\x00\x1fv" + // 0x03B90300: 0x00001F76
- "\x03\xbf\x03\x00\x00\x00\x1fx" + // 0x03BF0300: 0x00001F78
- "\x03\xc5\x03\x00\x00\x00\x1fz" + // 0x03C50300: 0x00001F7A
- "\x03\xc9\x03\x00\x00\x00\x1f|" + // 0x03C90300: 0x00001F7C
- "\x1f\x00\x03E\x00\x00\x1f\x80" + // 0x1F000345: 0x00001F80
- "\x1f\x01\x03E\x00\x00\x1f\x81" + // 0x1F010345: 0x00001F81
- "\x1f\x02\x03E\x00\x00\x1f\x82" + // 0x1F020345: 0x00001F82
- "\x1f\x03\x03E\x00\x00\x1f\x83" + // 0x1F030345: 0x00001F83
- "\x1f\x04\x03E\x00\x00\x1f\x84" + // 0x1F040345: 0x00001F84
- "\x1f\x05\x03E\x00\x00\x1f\x85" + // 0x1F050345: 0x00001F85
- "\x1f\x06\x03E\x00\x00\x1f\x86" + // 0x1F060345: 0x00001F86
- "\x1f\a\x03E\x00\x00\x1f\x87" + // 0x1F070345: 0x00001F87
- "\x1f\b\x03E\x00\x00\x1f\x88" + // 0x1F080345: 0x00001F88
- "\x1f\t\x03E\x00\x00\x1f\x89" + // 0x1F090345: 0x00001F89
- "\x1f\n\x03E\x00\x00\x1f\x8a" + // 0x1F0A0345: 0x00001F8A
- "\x1f\v\x03E\x00\x00\x1f\x8b" + // 0x1F0B0345: 0x00001F8B
- "\x1f\f\x03E\x00\x00\x1f\x8c" + // 0x1F0C0345: 0x00001F8C
- "\x1f\r\x03E\x00\x00\x1f\x8d" + // 0x1F0D0345: 0x00001F8D
- "\x1f\x0e\x03E\x00\x00\x1f\x8e" + // 0x1F0E0345: 0x00001F8E
- "\x1f\x0f\x03E\x00\x00\x1f\x8f" + // 0x1F0F0345: 0x00001F8F
- "\x1f \x03E\x00\x00\x1f\x90" + // 0x1F200345: 0x00001F90
- "\x1f!\x03E\x00\x00\x1f\x91" + // 0x1F210345: 0x00001F91
- "\x1f\"\x03E\x00\x00\x1f\x92" + // 0x1F220345: 0x00001F92
- "\x1f#\x03E\x00\x00\x1f\x93" + // 0x1F230345: 0x00001F93
- "\x1f$\x03E\x00\x00\x1f\x94" + // 0x1F240345: 0x00001F94
- "\x1f%\x03E\x00\x00\x1f\x95" + // 0x1F250345: 0x00001F95
- "\x1f&\x03E\x00\x00\x1f\x96" + // 0x1F260345: 0x00001F96
- "\x1f'\x03E\x00\x00\x1f\x97" + // 0x1F270345: 0x00001F97
- "\x1f(\x03E\x00\x00\x1f\x98" + // 0x1F280345: 0x00001F98
- "\x1f)\x03E\x00\x00\x1f\x99" + // 0x1F290345: 0x00001F99
- "\x1f*\x03E\x00\x00\x1f\x9a" + // 0x1F2A0345: 0x00001F9A
- "\x1f+\x03E\x00\x00\x1f\x9b" + // 0x1F2B0345: 0x00001F9B
- "\x1f,\x03E\x00\x00\x1f\x9c" + // 0x1F2C0345: 0x00001F9C
- "\x1f-\x03E\x00\x00\x1f\x9d" + // 0x1F2D0345: 0x00001F9D
- "\x1f.\x03E\x00\x00\x1f\x9e" + // 0x1F2E0345: 0x00001F9E
- "\x1f/\x03E\x00\x00\x1f\x9f" + // 0x1F2F0345: 0x00001F9F
- "\x1f`\x03E\x00\x00\x1f\xa0" + // 0x1F600345: 0x00001FA0
- "\x1fa\x03E\x00\x00\x1f\xa1" + // 0x1F610345: 0x00001FA1
- "\x1fb\x03E\x00\x00\x1f\xa2" + // 0x1F620345: 0x00001FA2
- "\x1fc\x03E\x00\x00\x1f\xa3" + // 0x1F630345: 0x00001FA3
- "\x1fd\x03E\x00\x00\x1f\xa4" + // 0x1F640345: 0x00001FA4
- "\x1fe\x03E\x00\x00\x1f\xa5" + // 0x1F650345: 0x00001FA5
- "\x1ff\x03E\x00\x00\x1f\xa6" + // 0x1F660345: 0x00001FA6
- "\x1fg\x03E\x00\x00\x1f\xa7" + // 0x1F670345: 0x00001FA7
- "\x1fh\x03E\x00\x00\x1f\xa8" + // 0x1F680345: 0x00001FA8
- "\x1fi\x03E\x00\x00\x1f\xa9" + // 0x1F690345: 0x00001FA9
- "\x1fj\x03E\x00\x00\x1f\xaa" + // 0x1F6A0345: 0x00001FAA
- "\x1fk\x03E\x00\x00\x1f\xab" + // 0x1F6B0345: 0x00001FAB
- "\x1fl\x03E\x00\x00\x1f\xac" + // 0x1F6C0345: 0x00001FAC
- "\x1fm\x03E\x00\x00\x1f\xad" + // 0x1F6D0345: 0x00001FAD
- "\x1fn\x03E\x00\x00\x1f\xae" + // 0x1F6E0345: 0x00001FAE
- "\x1fo\x03E\x00\x00\x1f\xaf" + // 0x1F6F0345: 0x00001FAF
- "\x03\xb1\x03\x06\x00\x00\x1f\xb0" + // 0x03B10306: 0x00001FB0
- "\x03\xb1\x03\x04\x00\x00\x1f\xb1" + // 0x03B10304: 0x00001FB1
- "\x1fp\x03E\x00\x00\x1f\xb2" + // 0x1F700345: 0x00001FB2
- "\x03\xb1\x03E\x00\x00\x1f\xb3" + // 0x03B10345: 0x00001FB3
- "\x03\xac\x03E\x00\x00\x1f\xb4" + // 0x03AC0345: 0x00001FB4
- "\x03\xb1\x03B\x00\x00\x1f\xb6" + // 0x03B10342: 0x00001FB6
- "\x1f\xb6\x03E\x00\x00\x1f\xb7" + // 0x1FB60345: 0x00001FB7
- "\x03\x91\x03\x06\x00\x00\x1f\xb8" + // 0x03910306: 0x00001FB8
- "\x03\x91\x03\x04\x00\x00\x1f\xb9" + // 0x03910304: 0x00001FB9
- "\x03\x91\x03\x00\x00\x00\x1f\xba" + // 0x03910300: 0x00001FBA
- "\x03\x91\x03E\x00\x00\x1f\xbc" + // 0x03910345: 0x00001FBC
- "\x00\xa8\x03B\x00\x00\x1f\xc1" + // 0x00A80342: 0x00001FC1
- "\x1ft\x03E\x00\x00\x1f\xc2" + // 0x1F740345: 0x00001FC2
- "\x03\xb7\x03E\x00\x00\x1f\xc3" + // 0x03B70345: 0x00001FC3
- "\x03\xae\x03E\x00\x00\x1f\xc4" + // 0x03AE0345: 0x00001FC4
- "\x03\xb7\x03B\x00\x00\x1f\xc6" + // 0x03B70342: 0x00001FC6
- "\x1f\xc6\x03E\x00\x00\x1f\xc7" + // 0x1FC60345: 0x00001FC7
- "\x03\x95\x03\x00\x00\x00\x1f\xc8" + // 0x03950300: 0x00001FC8
- "\x03\x97\x03\x00\x00\x00\x1f\xca" + // 0x03970300: 0x00001FCA
- "\x03\x97\x03E\x00\x00\x1f\xcc" + // 0x03970345: 0x00001FCC
- "\x1f\xbf\x03\x00\x00\x00\x1f\xcd" + // 0x1FBF0300: 0x00001FCD
- "\x1f\xbf\x03\x01\x00\x00\x1f\xce" + // 0x1FBF0301: 0x00001FCE
- "\x1f\xbf\x03B\x00\x00\x1f\xcf" + // 0x1FBF0342: 0x00001FCF
- "\x03\xb9\x03\x06\x00\x00\x1f\xd0" + // 0x03B90306: 0x00001FD0
- "\x03\xb9\x03\x04\x00\x00\x1f\xd1" + // 0x03B90304: 0x00001FD1
- "\x03\xca\x03\x00\x00\x00\x1f\xd2" + // 0x03CA0300: 0x00001FD2
- "\x03\xb9\x03B\x00\x00\x1f\xd6" + // 0x03B90342: 0x00001FD6
- "\x03\xca\x03B\x00\x00\x1f\xd7" + // 0x03CA0342: 0x00001FD7
- "\x03\x99\x03\x06\x00\x00\x1f\xd8" + // 0x03990306: 0x00001FD8
- "\x03\x99\x03\x04\x00\x00\x1f\xd9" + // 0x03990304: 0x00001FD9
- "\x03\x99\x03\x00\x00\x00\x1f\xda" + // 0x03990300: 0x00001FDA
- "\x1f\xfe\x03\x00\x00\x00\x1f\xdd" + // 0x1FFE0300: 0x00001FDD
- "\x1f\xfe\x03\x01\x00\x00\x1f\xde" + // 0x1FFE0301: 0x00001FDE
- "\x1f\xfe\x03B\x00\x00\x1f\xdf" + // 0x1FFE0342: 0x00001FDF
- "\x03\xc5\x03\x06\x00\x00\x1f\xe0" + // 0x03C50306: 0x00001FE0
- "\x03\xc5\x03\x04\x00\x00\x1f\xe1" + // 0x03C50304: 0x00001FE1
- "\x03\xcb\x03\x00\x00\x00\x1f\xe2" + // 0x03CB0300: 0x00001FE2
- "\x03\xc1\x03\x13\x00\x00\x1f\xe4" + // 0x03C10313: 0x00001FE4
- "\x03\xc1\x03\x14\x00\x00\x1f\xe5" + // 0x03C10314: 0x00001FE5
- "\x03\xc5\x03B\x00\x00\x1f\xe6" + // 0x03C50342: 0x00001FE6
- "\x03\xcb\x03B\x00\x00\x1f\xe7" + // 0x03CB0342: 0x00001FE7
- "\x03\xa5\x03\x06\x00\x00\x1f\xe8" + // 0x03A50306: 0x00001FE8
- "\x03\xa5\x03\x04\x00\x00\x1f\xe9" + // 0x03A50304: 0x00001FE9
- "\x03\xa5\x03\x00\x00\x00\x1f\xea" + // 0x03A50300: 0x00001FEA
- "\x03\xa1\x03\x14\x00\x00\x1f\xec" + // 0x03A10314: 0x00001FEC
- "\x00\xa8\x03\x00\x00\x00\x1f\xed" + // 0x00A80300: 0x00001FED
- "\x1f|\x03E\x00\x00\x1f\xf2" + // 0x1F7C0345: 0x00001FF2
- "\x03\xc9\x03E\x00\x00\x1f\xf3" + // 0x03C90345: 0x00001FF3
- "\x03\xce\x03E\x00\x00\x1f\xf4" + // 0x03CE0345: 0x00001FF4
- "\x03\xc9\x03B\x00\x00\x1f\xf6" + // 0x03C90342: 0x00001FF6
- "\x1f\xf6\x03E\x00\x00\x1f\xf7" + // 0x1FF60345: 0x00001FF7
- "\x03\x9f\x03\x00\x00\x00\x1f\xf8" + // 0x039F0300: 0x00001FF8
- "\x03\xa9\x03\x00\x00\x00\x1f\xfa" + // 0x03A90300: 0x00001FFA
- "\x03\xa9\x03E\x00\x00\x1f\xfc" + // 0x03A90345: 0x00001FFC
- "!\x90\x038\x00\x00!\x9a" + // 0x21900338: 0x0000219A
- "!\x92\x038\x00\x00!\x9b" + // 0x21920338: 0x0000219B
- "!\x94\x038\x00\x00!\xae" + // 0x21940338: 0x000021AE
- "!\xd0\x038\x00\x00!\xcd" + // 0x21D00338: 0x000021CD
- "!\xd4\x038\x00\x00!\xce" + // 0x21D40338: 0x000021CE
- "!\xd2\x038\x00\x00!\xcf" + // 0x21D20338: 0x000021CF
- "\"\x03\x038\x00\x00\"\x04" + // 0x22030338: 0x00002204
- "\"\b\x038\x00\x00\"\t" + // 0x22080338: 0x00002209
- "\"\v\x038\x00\x00\"\f" + // 0x220B0338: 0x0000220C
- "\"#\x038\x00\x00\"$" + // 0x22230338: 0x00002224
- "\"%\x038\x00\x00\"&" + // 0x22250338: 0x00002226
- "\"<\x038\x00\x00\"A" + // 0x223C0338: 0x00002241
- "\"C\x038\x00\x00\"D" + // 0x22430338: 0x00002244
- "\"E\x038\x00\x00\"G" + // 0x22450338: 0x00002247
- "\"H\x038\x00\x00\"I" + // 0x22480338: 0x00002249
- "\x00=\x038\x00\x00\"`" + // 0x003D0338: 0x00002260
- "\"a\x038\x00\x00\"b" + // 0x22610338: 0x00002262
- "\"M\x038\x00\x00\"m" + // 0x224D0338: 0x0000226D
- "\x00<\x038\x00\x00\"n" + // 0x003C0338: 0x0000226E
- "\x00>\x038\x00\x00\"o" + // 0x003E0338: 0x0000226F
- "\"d\x038\x00\x00\"p" + // 0x22640338: 0x00002270
- "\"e\x038\x00\x00\"q" + // 0x22650338: 0x00002271
- "\"r\x038\x00\x00\"t" + // 0x22720338: 0x00002274
- "\"s\x038\x00\x00\"u" + // 0x22730338: 0x00002275
- "\"v\x038\x00\x00\"x" + // 0x22760338: 0x00002278
- "\"w\x038\x00\x00\"y" + // 0x22770338: 0x00002279
- "\"z\x038\x00\x00\"\x80" + // 0x227A0338: 0x00002280
- "\"{\x038\x00\x00\"\x81" + // 0x227B0338: 0x00002281
- "\"\x82\x038\x00\x00\"\x84" + // 0x22820338: 0x00002284
- "\"\x83\x038\x00\x00\"\x85" + // 0x22830338: 0x00002285
- "\"\x86\x038\x00\x00\"\x88" + // 0x22860338: 0x00002288
- "\"\x87\x038\x00\x00\"\x89" + // 0x22870338: 0x00002289
- "\"\xa2\x038\x00\x00\"\xac" + // 0x22A20338: 0x000022AC
- "\"\xa8\x038\x00\x00\"\xad" + // 0x22A80338: 0x000022AD
- "\"\xa9\x038\x00\x00\"\xae" + // 0x22A90338: 0x000022AE
- "\"\xab\x038\x00\x00\"\xaf" + // 0x22AB0338: 0x000022AF
- "\"|\x038\x00\x00\"\xe0" + // 0x227C0338: 0x000022E0
- "\"}\x038\x00\x00\"\xe1" + // 0x227D0338: 0x000022E1
- "\"\x91\x038\x00\x00\"\xe2" + // 0x22910338: 0x000022E2
- "\"\x92\x038\x00\x00\"\xe3" + // 0x22920338: 0x000022E3
- "\"\xb2\x038\x00\x00\"\xea" + // 0x22B20338: 0x000022EA
- "\"\xb3\x038\x00\x00\"\xeb" + // 0x22B30338: 0x000022EB
- "\"\xb4\x038\x00\x00\"\xec" + // 0x22B40338: 0x000022EC
- "\"\xb5\x038\x00\x00\"\xed" + // 0x22B50338: 0x000022ED
- "0K0\x99\x00\x000L" + // 0x304B3099: 0x0000304C
- "0M0\x99\x00\x000N" + // 0x304D3099: 0x0000304E
- "0O0\x99\x00\x000P" + // 0x304F3099: 0x00003050
- "0Q0\x99\x00\x000R" + // 0x30513099: 0x00003052
- "0S0\x99\x00\x000T" + // 0x30533099: 0x00003054
- "0U0\x99\x00\x000V" + // 0x30553099: 0x00003056
- "0W0\x99\x00\x000X" + // 0x30573099: 0x00003058
- "0Y0\x99\x00\x000Z" + // 0x30593099: 0x0000305A
- "0[0\x99\x00\x000\\" + // 0x305B3099: 0x0000305C
- "0]0\x99\x00\x000^" + // 0x305D3099: 0x0000305E
- "0_0\x99\x00\x000`" + // 0x305F3099: 0x00003060
- "0a0\x99\x00\x000b" + // 0x30613099: 0x00003062
- "0d0\x99\x00\x000e" + // 0x30643099: 0x00003065
- "0f0\x99\x00\x000g" + // 0x30663099: 0x00003067
- "0h0\x99\x00\x000i" + // 0x30683099: 0x00003069
- "0o0\x99\x00\x000p" + // 0x306F3099: 0x00003070
- "0o0\x9a\x00\x000q" + // 0x306F309A: 0x00003071
- "0r0\x99\x00\x000s" + // 0x30723099: 0x00003073
- "0r0\x9a\x00\x000t" + // 0x3072309A: 0x00003074
- "0u0\x99\x00\x000v" + // 0x30753099: 0x00003076
- "0u0\x9a\x00\x000w" + // 0x3075309A: 0x00003077
- "0x0\x99\x00\x000y" + // 0x30783099: 0x00003079
- "0x0\x9a\x00\x000z" + // 0x3078309A: 0x0000307A
- "0{0\x99\x00\x000|" + // 0x307B3099: 0x0000307C
- "0{0\x9a\x00\x000}" + // 0x307B309A: 0x0000307D
- "0F0\x99\x00\x000\x94" + // 0x30463099: 0x00003094
- "0\x9d0\x99\x00\x000\x9e" + // 0x309D3099: 0x0000309E
- "0\xab0\x99\x00\x000\xac" + // 0x30AB3099: 0x000030AC
- "0\xad0\x99\x00\x000\xae" + // 0x30AD3099: 0x000030AE
- "0\xaf0\x99\x00\x000\xb0" + // 0x30AF3099: 0x000030B0
- "0\xb10\x99\x00\x000\xb2" + // 0x30B13099: 0x000030B2
- "0\xb30\x99\x00\x000\xb4" + // 0x30B33099: 0x000030B4
- "0\xb50\x99\x00\x000\xb6" + // 0x30B53099: 0x000030B6
- "0\xb70\x99\x00\x000\xb8" + // 0x30B73099: 0x000030B8
- "0\xb90\x99\x00\x000\xba" + // 0x30B93099: 0x000030BA
- "0\xbb0\x99\x00\x000\xbc" + // 0x30BB3099: 0x000030BC
- "0\xbd0\x99\x00\x000\xbe" + // 0x30BD3099: 0x000030BE
- "0\xbf0\x99\x00\x000\xc0" + // 0x30BF3099: 0x000030C0
- "0\xc10\x99\x00\x000\xc2" + // 0x30C13099: 0x000030C2
- "0\xc40\x99\x00\x000\xc5" + // 0x30C43099: 0x000030C5
- "0\xc60\x99\x00\x000\xc7" + // 0x30C63099: 0x000030C7
- "0\xc80\x99\x00\x000\xc9" + // 0x30C83099: 0x000030C9
- "0\xcf0\x99\x00\x000\xd0" + // 0x30CF3099: 0x000030D0
- "0\xcf0\x9a\x00\x000\xd1" + // 0x30CF309A: 0x000030D1
- "0\xd20\x99\x00\x000\xd3" + // 0x30D23099: 0x000030D3
- "0\xd20\x9a\x00\x000\xd4" + // 0x30D2309A: 0x000030D4
- "0\xd50\x99\x00\x000\xd6" + // 0x30D53099: 0x000030D6
- "0\xd50\x9a\x00\x000\xd7" + // 0x30D5309A: 0x000030D7
- "0\xd80\x99\x00\x000\xd9" + // 0x30D83099: 0x000030D9
- "0\xd80\x9a\x00\x000\xda" + // 0x30D8309A: 0x000030DA
- "0\xdb0\x99\x00\x000\xdc" + // 0x30DB3099: 0x000030DC
- "0\xdb0\x9a\x00\x000\xdd" + // 0x30DB309A: 0x000030DD
- "0\xa60\x99\x00\x000\xf4" + // 0x30A63099: 0x000030F4
- "0\xef0\x99\x00\x000\xf7" + // 0x30EF3099: 0x000030F7
- "0\xf00\x99\x00\x000\xf8" + // 0x30F03099: 0x000030F8
- "0\xf10\x99\x00\x000\xf9" + // 0x30F13099: 0x000030F9
- "0\xf20\x99\x00\x000\xfa" + // 0x30F23099: 0x000030FA
- "0\xfd0\x99\x00\x000\xfe" + // 0x30FD3099: 0x000030FE
- "\x10\x99\x10\xba\x00\x01\x10\x9a" + // 0x109910BA: 0x0001109A
- "\x10\x9b\x10\xba\x00\x01\x10\x9c" + // 0x109B10BA: 0x0001109C
- "\x10\xa5\x10\xba\x00\x01\x10\xab" + // 0x10A510BA: 0x000110AB
- "\x111\x11'\x00\x01\x11." + // 0x11311127: 0x0001112E
- "\x112\x11'\x00\x01\x11/" + // 0x11321127: 0x0001112F
- "\x13G\x13>\x00\x01\x13K" + // 0x1347133E: 0x0001134B
- "\x13G\x13W\x00\x01\x13L" + // 0x13471357: 0x0001134C
- "\x14\xb9\x14\xba\x00\x01\x14\xbb" + // 0x14B914BA: 0x000114BB
- "\x14\xb9\x14\xb0\x00\x01\x14\xbc" + // 0x14B914B0: 0x000114BC
- "\x14\xb9\x14\xbd\x00\x01\x14\xbe" + // 0x14B914BD: 0x000114BE
- "\x15\xb8\x15\xaf\x00\x01\x15\xba" + // 0x15B815AF: 0x000115BA
- "\x15\xb9\x15\xaf\x00\x01\x15\xbb" + // 0x15B915AF: 0x000115BB
- "\x195\x190\x00\x01\x198" + // 0x19351930: 0x00011938
- ""
- // Total size of tables: 55KB (56160 bytes)
diff --git a/contrib/go/_std_1.21/src/archive/tar/common.go b/contrib/go/_std_1.21/src/archive/tar/common.go
new file mode 100644
index 0000000000..dc9d350eb7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/archive/tar/common.go
@@ -0,0 +1,736 @@
+// Copyright 2009 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 tar implements access to tar archives.
+//
+// Tape archives (tar) are a file format for storing a sequence of files that
+// can be read and written in a streaming manner.
+// This package aims to cover most variations of the format,
+// including those produced by GNU and BSD tar tools.
+package tar
+
+import (
+ "errors"
+ "fmt"
+ "internal/godebug"
+ "io/fs"
+ "math"
+ "path"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// BUG: Use of the Uid and Gid fields in Header could overflow on 32-bit
+// architectures. If a large value is encountered when decoding, the result
+// stored in Header will be the truncated version.
+
+var tarinsecurepath = godebug.New("tarinsecurepath")
+
+var (
+ ErrHeader = errors.New("archive/tar: invalid tar header")
+ ErrWriteTooLong = errors.New("archive/tar: write too long")
+ ErrFieldTooLong = errors.New("archive/tar: header field too long")
+ ErrWriteAfterClose = errors.New("archive/tar: write after close")
+ ErrInsecurePath = errors.New("archive/tar: insecure file path")
+ errMissData = errors.New("archive/tar: sparse file references non-existent data")
+ errUnrefData = errors.New("archive/tar: sparse file contains unreferenced data")
+ errWriteHole = errors.New("archive/tar: write non-NUL byte in sparse hole")
+)
+
+type headerError []string
+
+func (he headerError) Error() string {
+ const prefix = "archive/tar: cannot encode header"
+ var ss []string
+ for _, s := range he {
+ if s != "" {
+ ss = append(ss, s)
+ }
+ }
+ if len(ss) == 0 {
+ return prefix
+ }
+ return fmt.Sprintf("%s: %v", prefix, strings.Join(ss, "; and "))
+}
+
+// Type flags for Header.Typeflag.
+const (
+ // Type '0' indicates a regular file.
+ TypeReg = '0'
+
+ // Deprecated: Use TypeReg instead.
+ TypeRegA = '\x00'
+
+ // Type '1' to '6' are header-only flags and may not have a data body.
+ TypeLink = '1' // Hard link
+ TypeSymlink = '2' // Symbolic link
+ TypeChar = '3' // Character device node
+ TypeBlock = '4' // Block device node
+ TypeDir = '5' // Directory
+ TypeFifo = '6' // FIFO node
+
+ // Type '7' is reserved.
+ TypeCont = '7'
+
+ // Type 'x' is used by the PAX format to store key-value records that
+ // are only relevant to the next file.
+ // This package transparently handles these types.
+ TypeXHeader = 'x'
+
+ // Type 'g' is used by the PAX format to store key-value records that
+ // are relevant to all subsequent files.
+ // This package only supports parsing and composing such headers,
+ // but does not currently support persisting the global state across files.
+ TypeXGlobalHeader = 'g'
+
+ // Type 'S' indicates a sparse file in the GNU format.
+ TypeGNUSparse = 'S'
+
+ // Types 'L' and 'K' are used by the GNU format for a meta file
+ // used to store the path or link name for the next file.
+ // This package transparently handles these types.
+ TypeGNULongName = 'L'
+ TypeGNULongLink = 'K'
+)
+
+// Keywords for PAX extended header records.
+const (
+ paxNone = "" // Indicates that no PAX key is suitable
+ paxPath = "path"
+ paxLinkpath = "linkpath"
+ paxSize = "size"
+ paxUid = "uid"
+ paxGid = "gid"
+ paxUname = "uname"
+ paxGname = "gname"
+ paxMtime = "mtime"
+ paxAtime = "atime"
+ paxCtime = "ctime" // Removed from later revision of PAX spec, but was valid
+ paxCharset = "charset" // Currently unused
+ paxComment = "comment" // Currently unused
+
+ paxSchilyXattr = "SCHILY.xattr."
+
+ // Keywords for GNU sparse files in a PAX extended header.
+ paxGNUSparse = "GNU.sparse."
+ paxGNUSparseNumBlocks = "GNU.sparse.numblocks"
+ paxGNUSparseOffset = "GNU.sparse.offset"
+ paxGNUSparseNumBytes = "GNU.sparse.numbytes"
+ paxGNUSparseMap = "GNU.sparse.map"
+ paxGNUSparseName = "GNU.sparse.name"
+ paxGNUSparseMajor = "GNU.sparse.major"
+ paxGNUSparseMinor = "GNU.sparse.minor"
+ paxGNUSparseSize = "GNU.sparse.size"
+ paxGNUSparseRealSize = "GNU.sparse.realsize"
+)
+
+// basicKeys is a set of the PAX keys for which we have built-in support.
+// This does not contain "charset" or "comment", which are both PAX-specific,
+// so adding them as first-class features of Header is unlikely.
+// Users can use the PAXRecords field to set it themselves.
+var basicKeys = map[string]bool{
+ paxPath: true, paxLinkpath: true, paxSize: true, paxUid: true, paxGid: true,
+ paxUname: true, paxGname: true, paxMtime: true, paxAtime: true, paxCtime: true,
+}
+
+// A Header represents a single header in a tar archive.
+// Some fields may not be populated.
+//
+// For forward compatibility, users that retrieve a Header from Reader.Next,
+// mutate it in some ways, and then pass it back to Writer.WriteHeader
+// should do so by creating a new Header and copying the fields
+// that they are interested in preserving.
+type Header struct {
+ // Typeflag is the type of header entry.
+ // The zero value is automatically promoted to either TypeReg or TypeDir
+ // depending on the presence of a trailing slash in Name.
+ Typeflag byte
+
+ Name string // Name of file entry
+ Linkname string // Target name of link (valid for TypeLink or TypeSymlink)
+
+ Size int64 // Logical file size in bytes
+ Mode int64 // Permission and mode bits
+ Uid int // User ID of owner
+ Gid int // Group ID of owner
+ Uname string // User name of owner
+ Gname string // Group name of owner
+
+ // If the Format is unspecified, then Writer.WriteHeader rounds ModTime
+ // to the nearest second and ignores the AccessTime and ChangeTime fields.
+ //
+ // To use AccessTime or ChangeTime, specify the Format as PAX or GNU.
+ // To use sub-second resolution, specify the Format as PAX.
+ ModTime time.Time // Modification time
+ AccessTime time.Time // Access time (requires either PAX or GNU support)
+ ChangeTime time.Time // Change time (requires either PAX or GNU support)
+
+ Devmajor int64 // Major device number (valid for TypeChar or TypeBlock)
+ Devminor int64 // Minor device number (valid for TypeChar or TypeBlock)
+
+ // Xattrs stores extended attributes as PAX records under the
+ // "SCHILY.xattr." namespace.
+ //
+ // The following are semantically equivalent:
+ // h.Xattrs[key] = value
+ // h.PAXRecords["SCHILY.xattr."+key] = value
+ //
+ // When Writer.WriteHeader is called, the contents of Xattrs will take
+ // precedence over those in PAXRecords.
+ //
+ // Deprecated: Use PAXRecords instead.
+ Xattrs map[string]string
+
+ // PAXRecords is a map of PAX extended header records.
+ //
+ // User-defined records should have keys of the following form:
+ // VENDOR.keyword
+ // Where VENDOR is some namespace in all uppercase, and keyword may
+ // not contain the '=' character (e.g., "GOLANG.pkg.version").
+ // The key and value should be non-empty UTF-8 strings.
+ //
+ // When Writer.WriteHeader is called, PAX records derived from the
+ // other fields in Header take precedence over PAXRecords.
+ PAXRecords map[string]string
+
+ // Format specifies the format of the tar header.
+ //
+ // This is set by Reader.Next as a best-effort guess at the format.
+ // Since the Reader liberally reads some non-compliant files,
+ // it is possible for this to be FormatUnknown.
+ //
+ // If the format is unspecified when Writer.WriteHeader is called,
+ // then it uses the first format (in the order of USTAR, PAX, GNU)
+ // capable of encoding this Header (see Format).
+ Format Format
+}
+
+// sparseEntry represents a Length-sized fragment at Offset in the file.
+type sparseEntry struct{ Offset, Length int64 }
+
+func (s sparseEntry) endOffset() int64 { return s.Offset + s.Length }
+
+// A sparse file can be represented as either a sparseDatas or a sparseHoles.
+// As long as the total size is known, they are equivalent and one can be
+// converted to the other form and back. The various tar formats with sparse
+// file support represent sparse files in the sparseDatas form. That is, they
+// specify the fragments in the file that has data, and treat everything else as
+// having zero bytes. As such, the encoding and decoding logic in this package
+// deals with sparseDatas.
+//
+// However, the external API uses sparseHoles instead of sparseDatas because the
+// zero value of sparseHoles logically represents a normal file (i.e., there are
+// no holes in it). On the other hand, the zero value of sparseDatas implies
+// that the file has no data in it, which is rather odd.
+//
+// As an example, if the underlying raw file contains the 10-byte data:
+//
+// var compactFile = "abcdefgh"
+//
+// And the sparse map has the following entries:
+//
+// var spd sparseDatas = []sparseEntry{
+// {Offset: 2, Length: 5}, // Data fragment for 2..6
+// {Offset: 18, Length: 3}, // Data fragment for 18..20
+// }
+// var sph sparseHoles = []sparseEntry{
+// {Offset: 0, Length: 2}, // Hole fragment for 0..1
+// {Offset: 7, Length: 11}, // Hole fragment for 7..17
+// {Offset: 21, Length: 4}, // Hole fragment for 21..24
+// }
+//
+// Then the content of the resulting sparse file with a Header.Size of 25 is:
+//
+// var sparseFile = "\x00"*2 + "abcde" + "\x00"*11 + "fgh" + "\x00"*4
+type (
+ sparseDatas []sparseEntry
+ sparseHoles []sparseEntry
+)
+
+// validateSparseEntries reports whether sp is a valid sparse map.
+// It does not matter whether sp represents data fragments or hole fragments.
+func validateSparseEntries(sp []sparseEntry, size int64) bool {
+ // Validate all sparse entries. These are the same checks as performed by
+ // the BSD tar utility.
+ if size < 0 {
+ return false
+ }
+ var pre sparseEntry
+ for _, cur := range sp {
+ switch {
+ case cur.Offset < 0 || cur.Length < 0:
+ return false // Negative values are never okay
+ case cur.Offset > math.MaxInt64-cur.Length:
+ return false // Integer overflow with large length
+ case cur.endOffset() > size:
+ return false // Region extends beyond the actual size
+ case pre.endOffset() > cur.Offset:
+ return false // Regions cannot overlap and must be in order
+ }
+ pre = cur
+ }
+ return true
+}
+
+// alignSparseEntries mutates src and returns dst where each fragment's
+// starting offset is aligned up to the nearest block edge, and each
+// ending offset is aligned down to the nearest block edge.
+//
+// Even though the Go tar Reader and the BSD tar utility can handle entries
+// with arbitrary offsets and lengths, the GNU tar utility can only handle
+// offsets and lengths that are multiples of blockSize.
+func alignSparseEntries(src []sparseEntry, size int64) []sparseEntry {
+ dst := src[:0]
+ for _, s := range src {
+ pos, end := s.Offset, s.endOffset()
+ pos += blockPadding(+pos) // Round-up to nearest blockSize
+ if end != size {
+ end -= blockPadding(-end) // Round-down to nearest blockSize
+ }
+ if pos < end {
+ dst = append(dst, sparseEntry{Offset: pos, Length: end - pos})
+ }
+ }
+ return dst
+}
+
+// invertSparseEntries converts a sparse map from one form to the other.
+// If the input is sparseHoles, then it will output sparseDatas and vice-versa.
+// The input must have been already validated.
+//
+// This function mutates src and returns a normalized map where:
+// - adjacent fragments are coalesced together
+// - only the last fragment may be empty
+// - the endOffset of the last fragment is the total size
+func invertSparseEntries(src []sparseEntry, size int64) []sparseEntry {
+ dst := src[:0]
+ var pre sparseEntry
+ for _, cur := range src {
+ if cur.Length == 0 {
+ continue // Skip empty fragments
+ }
+ pre.Length = cur.Offset - pre.Offset
+ if pre.Length > 0 {
+ dst = append(dst, pre) // Only add non-empty fragments
+ }
+ pre.Offset = cur.endOffset()
+ }
+ pre.Length = size - pre.Offset // Possibly the only empty fragment
+ return append(dst, pre)
+}
+
+// fileState tracks the number of logical (includes sparse holes) and physical
+// (actual in tar archive) bytes remaining for the current file.
+//
+// Invariant: logicalRemaining >= physicalRemaining
+type fileState interface {
+ logicalRemaining() int64
+ physicalRemaining() int64
+}
+
+// allowedFormats determines which formats can be used.
+// The value returned is the logical OR of multiple possible formats.
+// If the value is FormatUnknown, then the input Header cannot be encoded
+// and an error is returned explaining why.
+//
+// As a by-product of checking the fields, this function returns paxHdrs, which
+// contain all fields that could not be directly encoded.
+// A value receiver ensures that this method does not mutate the source Header.
+func (h Header) allowedFormats() (format Format, paxHdrs map[string]string, err error) {
+ format = FormatUSTAR | FormatPAX | FormatGNU
+ paxHdrs = make(map[string]string)
+
+ var whyNoUSTAR, whyNoPAX, whyNoGNU string
+ var preferPAX bool // Prefer PAX over USTAR
+ verifyString := func(s string, size int, name, paxKey string) {
+ // NUL-terminator is optional for path and linkpath.
+ // Technically, it is required for uname and gname,
+ // but neither GNU nor BSD tar checks for it.
+ tooLong := len(s) > size
+ allowLongGNU := paxKey == paxPath || paxKey == paxLinkpath
+ if hasNUL(s) || (tooLong && !allowLongGNU) {
+ whyNoGNU = fmt.Sprintf("GNU cannot encode %s=%q", name, s)
+ format.mustNotBe(FormatGNU)
+ }
+ if !isASCII(s) || tooLong {
+ canSplitUSTAR := paxKey == paxPath
+ if _, _, ok := splitUSTARPath(s); !canSplitUSTAR || !ok {
+ whyNoUSTAR = fmt.Sprintf("USTAR cannot encode %s=%q", name, s)
+ format.mustNotBe(FormatUSTAR)
+ }
+ if paxKey == paxNone {
+ whyNoPAX = fmt.Sprintf("PAX cannot encode %s=%q", name, s)
+ format.mustNotBe(FormatPAX)
+ } else {
+ paxHdrs[paxKey] = s
+ }
+ }
+ if v, ok := h.PAXRecords[paxKey]; ok && v == s {
+ paxHdrs[paxKey] = v
+ }
+ }
+ verifyNumeric := func(n int64, size int, name, paxKey string) {
+ if !fitsInBase256(size, n) {
+ whyNoGNU = fmt.Sprintf("GNU cannot encode %s=%d", name, n)
+ format.mustNotBe(FormatGNU)
+ }
+ if !fitsInOctal(size, n) {
+ whyNoUSTAR = fmt.Sprintf("USTAR cannot encode %s=%d", name, n)
+ format.mustNotBe(FormatUSTAR)
+ if paxKey == paxNone {
+ whyNoPAX = fmt.Sprintf("PAX cannot encode %s=%d", name, n)
+ format.mustNotBe(FormatPAX)
+ } else {
+ paxHdrs[paxKey] = strconv.FormatInt(n, 10)
+ }
+ }
+ if v, ok := h.PAXRecords[paxKey]; ok && v == strconv.FormatInt(n, 10) {
+ paxHdrs[paxKey] = v
+ }
+ }
+ verifyTime := func(ts time.Time, size int, name, paxKey string) {
+ if ts.IsZero() {
+ return // Always okay
+ }
+ if !fitsInBase256(size, ts.Unix()) {
+ whyNoGNU = fmt.Sprintf("GNU cannot encode %s=%v", name, ts)
+ format.mustNotBe(FormatGNU)
+ }
+ isMtime := paxKey == paxMtime
+ fitsOctal := fitsInOctal(size, ts.Unix())
+ if (isMtime && !fitsOctal) || !isMtime {
+ whyNoUSTAR = fmt.Sprintf("USTAR cannot encode %s=%v", name, ts)
+ format.mustNotBe(FormatUSTAR)
+ }
+ needsNano := ts.Nanosecond() != 0
+ if !isMtime || !fitsOctal || needsNano {
+ preferPAX = true // USTAR may truncate sub-second measurements
+ if paxKey == paxNone {
+ whyNoPAX = fmt.Sprintf("PAX cannot encode %s=%v", name, ts)
+ format.mustNotBe(FormatPAX)
+ } else {
+ paxHdrs[paxKey] = formatPAXTime(ts)
+ }
+ }
+ if v, ok := h.PAXRecords[paxKey]; ok && v == formatPAXTime(ts) {
+ paxHdrs[paxKey] = v
+ }
+ }
+
+ // Check basic fields.
+ var blk block
+ v7 := blk.toV7()
+ ustar := blk.toUSTAR()
+ gnu := blk.toGNU()
+ verifyString(h.Name, len(v7.name()), "Name", paxPath)
+ verifyString(h.Linkname, len(v7.linkName()), "Linkname", paxLinkpath)
+ verifyString(h.Uname, len(ustar.userName()), "Uname", paxUname)
+ verifyString(h.Gname, len(ustar.groupName()), "Gname", paxGname)
+ verifyNumeric(h.Mode, len(v7.mode()), "Mode", paxNone)
+ verifyNumeric(int64(h.Uid), len(v7.uid()), "Uid", paxUid)
+ verifyNumeric(int64(h.Gid), len(v7.gid()), "Gid", paxGid)
+ verifyNumeric(h.Size, len(v7.size()), "Size", paxSize)
+ verifyNumeric(h.Devmajor, len(ustar.devMajor()), "Devmajor", paxNone)
+ verifyNumeric(h.Devminor, len(ustar.devMinor()), "Devminor", paxNone)
+ verifyTime(h.ModTime, len(v7.modTime()), "ModTime", paxMtime)
+ verifyTime(h.AccessTime, len(gnu.accessTime()), "AccessTime", paxAtime)
+ verifyTime(h.ChangeTime, len(gnu.changeTime()), "ChangeTime", paxCtime)
+
+ // Check for header-only types.
+ var whyOnlyPAX, whyOnlyGNU string
+ switch h.Typeflag {
+ case TypeReg, TypeChar, TypeBlock, TypeFifo, TypeGNUSparse:
+ // Exclude TypeLink and TypeSymlink, since they may reference directories.
+ if strings.HasSuffix(h.Name, "/") {
+ return FormatUnknown, nil, headerError{"filename may not have trailing slash"}
+ }
+ case TypeXHeader, TypeGNULongName, TypeGNULongLink:
+ return FormatUnknown, nil, headerError{"cannot manually encode TypeXHeader, TypeGNULongName, or TypeGNULongLink headers"}
+ case TypeXGlobalHeader:
+ h2 := Header{Name: h.Name, Typeflag: h.Typeflag, Xattrs: h.Xattrs, PAXRecords: h.PAXRecords, Format: h.Format}
+ if !reflect.DeepEqual(h, h2) {
+ return FormatUnknown, nil, headerError{"only PAXRecords should be set for TypeXGlobalHeader"}
+ }
+ whyOnlyPAX = "only PAX supports TypeXGlobalHeader"
+ format.mayOnlyBe(FormatPAX)
+ }
+ if !isHeaderOnlyType(h.Typeflag) && h.Size < 0 {
+ return FormatUnknown, nil, headerError{"negative size on header-only type"}
+ }
+
+ // Check PAX records.
+ if len(h.Xattrs) > 0 {
+ for k, v := range h.Xattrs {
+ paxHdrs[paxSchilyXattr+k] = v
+ }
+ whyOnlyPAX = "only PAX supports Xattrs"
+ format.mayOnlyBe(FormatPAX)
+ }
+ if len(h.PAXRecords) > 0 {
+ for k, v := range h.PAXRecords {
+ switch _, exists := paxHdrs[k]; {
+ case exists:
+ continue // Do not overwrite existing records
+ case h.Typeflag == TypeXGlobalHeader:
+ paxHdrs[k] = v // Copy all records
+ case !basicKeys[k] && !strings.HasPrefix(k, paxGNUSparse):
+ paxHdrs[k] = v // Ignore local records that may conflict
+ }
+ }
+ whyOnlyPAX = "only PAX supports PAXRecords"
+ format.mayOnlyBe(FormatPAX)
+ }
+ for k, v := range paxHdrs {
+ if !validPAXRecord(k, v) {
+ return FormatUnknown, nil, headerError{fmt.Sprintf("invalid PAX record: %q", k+" = "+v)}
+ }
+ }
+
+ // TODO(dsnet): Re-enable this when adding sparse support.
+ // See https://golang.org/issue/22735
+ /*
+ // Check sparse files.
+ if len(h.SparseHoles) > 0 || h.Typeflag == TypeGNUSparse {
+ if isHeaderOnlyType(h.Typeflag) {
+ return FormatUnknown, nil, headerError{"header-only type cannot be sparse"}
+ }
+ if !validateSparseEntries(h.SparseHoles, h.Size) {
+ return FormatUnknown, nil, headerError{"invalid sparse holes"}
+ }
+ if h.Typeflag == TypeGNUSparse {
+ whyOnlyGNU = "only GNU supports TypeGNUSparse"
+ format.mayOnlyBe(FormatGNU)
+ } else {
+ whyNoGNU = "GNU supports sparse files only with TypeGNUSparse"
+ format.mustNotBe(FormatGNU)
+ }
+ whyNoUSTAR = "USTAR does not support sparse files"
+ format.mustNotBe(FormatUSTAR)
+ }
+ */
+
+ // Check desired format.
+ if wantFormat := h.Format; wantFormat != FormatUnknown {
+ if wantFormat.has(FormatPAX) && !preferPAX {
+ wantFormat.mayBe(FormatUSTAR) // PAX implies USTAR allowed too
+ }
+ format.mayOnlyBe(wantFormat) // Set union of formats allowed and format wanted
+ }
+ if format == FormatUnknown {
+ switch h.Format {
+ case FormatUSTAR:
+ err = headerError{"Format specifies USTAR", whyNoUSTAR, whyOnlyPAX, whyOnlyGNU}
+ case FormatPAX:
+ err = headerError{"Format specifies PAX", whyNoPAX, whyOnlyGNU}
+ case FormatGNU:
+ err = headerError{"Format specifies GNU", whyNoGNU, whyOnlyPAX}
+ default:
+ err = headerError{whyNoUSTAR, whyNoPAX, whyNoGNU, whyOnlyPAX, whyOnlyGNU}
+ }
+ }
+ return format, paxHdrs, err
+}
+
+// FileInfo returns an fs.FileInfo for the Header.
+func (h *Header) FileInfo() fs.FileInfo {
+ return headerFileInfo{h}
+}
+
+// headerFileInfo implements fs.FileInfo.
+type headerFileInfo struct {
+ h *Header
+}
+
+func (fi headerFileInfo) Size() int64 { return fi.h.Size }
+func (fi headerFileInfo) IsDir() bool { return fi.Mode().IsDir() }
+func (fi headerFileInfo) ModTime() time.Time { return fi.h.ModTime }
+func (fi headerFileInfo) Sys() any { return fi.h }
+
+// Name returns the base name of the file.
+func (fi headerFileInfo) Name() string {
+ if fi.IsDir() {
+ return path.Base(path.Clean(fi.h.Name))
+ }
+ return path.Base(fi.h.Name)
+}
+
+// Mode returns the permission and mode bits for the headerFileInfo.
+func (fi headerFileInfo) Mode() (mode fs.FileMode) {
+ // Set file permission bits.
+ mode = fs.FileMode(fi.h.Mode).Perm()
+
+ // Set setuid, setgid and sticky bits.
+ if fi.h.Mode&c_ISUID != 0 {
+ mode |= fs.ModeSetuid
+ }
+ if fi.h.Mode&c_ISGID != 0 {
+ mode |= fs.ModeSetgid
+ }
+ if fi.h.Mode&c_ISVTX != 0 {
+ mode |= fs.ModeSticky
+ }
+
+ // Set file mode bits; clear perm, setuid, setgid, and sticky bits.
+ switch m := fs.FileMode(fi.h.Mode) &^ 07777; m {
+ case c_ISDIR:
+ mode |= fs.ModeDir
+ case c_ISFIFO:
+ mode |= fs.ModeNamedPipe
+ case c_ISLNK:
+ mode |= fs.ModeSymlink
+ case c_ISBLK:
+ mode |= fs.ModeDevice
+ case c_ISCHR:
+ mode |= fs.ModeDevice
+ mode |= fs.ModeCharDevice
+ case c_ISSOCK:
+ mode |= fs.ModeSocket
+ }
+
+ switch fi.h.Typeflag {
+ case TypeSymlink:
+ mode |= fs.ModeSymlink
+ case TypeChar:
+ mode |= fs.ModeDevice
+ mode |= fs.ModeCharDevice
+ case TypeBlock:
+ mode |= fs.ModeDevice
+ case TypeDir:
+ mode |= fs.ModeDir
+ case TypeFifo:
+ mode |= fs.ModeNamedPipe
+ }
+
+ return mode
+}
+
+func (fi headerFileInfo) String() string {
+ return fs.FormatFileInfo(fi)
+}
+
+// sysStat, if non-nil, populates h from system-dependent fields of fi.
+var sysStat func(fi fs.FileInfo, h *Header) error
+
+const (
+ // Mode constants from the USTAR spec:
+ // See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06
+ c_ISUID = 04000 // Set uid
+ c_ISGID = 02000 // Set gid
+ c_ISVTX = 01000 // Save text (sticky bit)
+
+ // Common Unix mode constants; these are not defined in any common tar standard.
+ // Header.FileInfo understands these, but FileInfoHeader will never produce these.
+ c_ISDIR = 040000 // Directory
+ c_ISFIFO = 010000 // FIFO
+ c_ISREG = 0100000 // Regular file
+ c_ISLNK = 0120000 // Symbolic link
+ c_ISBLK = 060000 // Block special file
+ c_ISCHR = 020000 // Character special file
+ c_ISSOCK = 0140000 // Socket
+)
+
+// FileInfoHeader creates a partially-populated Header from fi.
+// If fi describes a symlink, FileInfoHeader records link as the link target.
+// If fi describes a directory, a slash is appended to the name.
+//
+// Since fs.FileInfo's Name method only returns the base name of
+// the file it describes, it may be necessary to modify Header.Name
+// to provide the full path name of the file.
+func FileInfoHeader(fi fs.FileInfo, link string) (*Header, error) {
+ if fi == nil {
+ return nil, errors.New("archive/tar: FileInfo is nil")
+ }
+ fm := fi.Mode()
+ h := &Header{
+ Name: fi.Name(),
+ ModTime: fi.ModTime(),
+ Mode: int64(fm.Perm()), // or'd with c_IS* constants later
+ }
+ switch {
+ case fm.IsRegular():
+ h.Typeflag = TypeReg
+ h.Size = fi.Size()
+ case fi.IsDir():
+ h.Typeflag = TypeDir
+ h.Name += "/"
+ case fm&fs.ModeSymlink != 0:
+ h.Typeflag = TypeSymlink
+ h.Linkname = link
+ case fm&fs.ModeDevice != 0:
+ if fm&fs.ModeCharDevice != 0 {
+ h.Typeflag = TypeChar
+ } else {
+ h.Typeflag = TypeBlock
+ }
+ case fm&fs.ModeNamedPipe != 0:
+ h.Typeflag = TypeFifo
+ case fm&fs.ModeSocket != 0:
+ return nil, fmt.Errorf("archive/tar: sockets not supported")
+ default:
+ return nil, fmt.Errorf("archive/tar: unknown file mode %v", fm)
+ }
+ if fm&fs.ModeSetuid != 0 {
+ h.Mode |= c_ISUID
+ }
+ if fm&fs.ModeSetgid != 0 {
+ h.Mode |= c_ISGID
+ }
+ if fm&fs.ModeSticky != 0 {
+ h.Mode |= c_ISVTX
+ }
+ // If possible, populate additional fields from OS-specific
+ // FileInfo fields.
+ if sys, ok := fi.Sys().(*Header); ok {
+ // This FileInfo came from a Header (not the OS). Use the
+ // original Header to populate all remaining fields.
+ h.Uid = sys.Uid
+ h.Gid = sys.Gid
+ h.Uname = sys.Uname
+ h.Gname = sys.Gname
+ h.AccessTime = sys.AccessTime
+ h.ChangeTime = sys.ChangeTime
+ if sys.Xattrs != nil {
+ h.Xattrs = make(map[string]string)
+ for k, v := range sys.Xattrs {
+ h.Xattrs[k] = v
+ }
+ }
+ if sys.Typeflag == TypeLink {
+ // hard link
+ h.Typeflag = TypeLink
+ h.Size = 0
+ h.Linkname = sys.Linkname
+ }
+ if sys.PAXRecords != nil {
+ h.PAXRecords = make(map[string]string)
+ for k, v := range sys.PAXRecords {
+ h.PAXRecords[k] = v
+ }
+ }
+ }
+ if sysStat != nil {
+ return h, sysStat(fi, h)
+ }
+ return h, nil
+}
+
+// isHeaderOnlyType checks if the given type flag is of the type that has no
+// data section even if a size is specified.
+func isHeaderOnlyType(flag byte) bool {
+ switch flag {
+ case TypeLink, TypeSymlink, TypeChar, TypeBlock, TypeDir, TypeFifo:
+ return true
+ default:
+ return false
+ }
+}
+
+func min(a, b int64) int64 {
+ if a < b {
+ return a
+ }
+ return b
+}
diff --git a/contrib/go/_std_1.20/src/archive/tar/format.go b/contrib/go/_std_1.21/src/archive/tar/format.go
index e50124d99e..e50124d99e 100644
--- a/contrib/go/_std_1.20/src/archive/tar/format.go
+++ b/contrib/go/_std_1.21/src/archive/tar/format.go
diff --git a/contrib/go/_std_1.21/src/archive/tar/reader.go b/contrib/go/_std_1.21/src/archive/tar/reader.go
new file mode 100644
index 0000000000..cfa50446ed
--- /dev/null
+++ b/contrib/go/_std_1.21/src/archive/tar/reader.go
@@ -0,0 +1,882 @@
+// Copyright 2009 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 tar
+
+import (
+ "bytes"
+ "io"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// Reader provides sequential access to the contents of a tar archive.
+// Reader.Next advances to the next file in the archive (including the first),
+// and then Reader can be treated as an io.Reader to access the file's data.
+type Reader struct {
+ r io.Reader
+ pad int64 // Amount of padding (ignored) after current file entry
+ curr fileReader // Reader for current file entry
+ blk block // Buffer to use as temporary local storage
+
+ // err is a persistent error.
+ // It is only the responsibility of every exported method of Reader to
+ // ensure that this error is sticky.
+ err error
+}
+
+type fileReader interface {
+ io.Reader
+ fileState
+
+ WriteTo(io.Writer) (int64, error)
+}
+
+// NewReader creates a new Reader reading from r.
+func NewReader(r io.Reader) *Reader {
+ return &Reader{r: r, curr: &regFileReader{r, 0}}
+}
+
+// Next advances to the next entry in the tar archive.
+// The Header.Size determines how many bytes can be read for the next file.
+// Any remaining data in the current file is automatically discarded.
+// At the end of the archive, Next returns the error io.EOF.
+//
+// If Next encounters a non-local name (as defined by [filepath.IsLocal])
+// and the GODEBUG environment variable contains `tarinsecurepath=0`,
+// Next returns the header with an ErrInsecurePath error.
+// A future version of Go may introduce this behavior by default.
+// Programs that want to accept non-local names can ignore
+// the ErrInsecurePath error and use the returned header.
+func (tr *Reader) Next() (*Header, error) {
+ if tr.err != nil {
+ return nil, tr.err
+ }
+ hdr, err := tr.next()
+ tr.err = err
+ if err == nil && !filepath.IsLocal(hdr.Name) {
+ if tarinsecurepath.Value() == "0" {
+ tarinsecurepath.IncNonDefault()
+ err = ErrInsecurePath
+ }
+ }
+ return hdr, err
+}
+
+func (tr *Reader) next() (*Header, error) {
+ var paxHdrs map[string]string
+ var gnuLongName, gnuLongLink string
+
+ // Externally, Next iterates through the tar archive as if it is a series of
+ // files. Internally, the tar format often uses fake "files" to add meta
+ // data that describes the next file. These meta data "files" should not
+ // normally be visible to the outside. As such, this loop iterates through
+ // one or more "header files" until it finds a "normal file".
+ format := FormatUSTAR | FormatPAX | FormatGNU
+ for {
+ // Discard the remainder of the file and any padding.
+ if err := discard(tr.r, tr.curr.physicalRemaining()); err != nil {
+ return nil, err
+ }
+ if _, err := tryReadFull(tr.r, tr.blk[:tr.pad]); err != nil {
+ return nil, err
+ }
+ tr.pad = 0
+
+ hdr, rawHdr, err := tr.readHeader()
+ if err != nil {
+ return nil, err
+ }
+ if err := tr.handleRegularFile(hdr); err != nil {
+ return nil, err
+ }
+ format.mayOnlyBe(hdr.Format)
+
+ // Check for PAX/GNU special headers and files.
+ switch hdr.Typeflag {
+ case TypeXHeader, TypeXGlobalHeader:
+ format.mayOnlyBe(FormatPAX)
+ paxHdrs, err = parsePAX(tr)
+ if err != nil {
+ return nil, err
+ }
+ if hdr.Typeflag == TypeXGlobalHeader {
+ mergePAX(hdr, paxHdrs)
+ return &Header{
+ Name: hdr.Name,
+ Typeflag: hdr.Typeflag,
+ Xattrs: hdr.Xattrs,
+ PAXRecords: hdr.PAXRecords,
+ Format: format,
+ }, nil
+ }
+ continue // This is a meta header affecting the next header
+ case TypeGNULongName, TypeGNULongLink:
+ format.mayOnlyBe(FormatGNU)
+ realname, err := readSpecialFile(tr)
+ if err != nil {
+ return nil, err
+ }
+
+ var p parser
+ switch hdr.Typeflag {
+ case TypeGNULongName:
+ gnuLongName = p.parseString(realname)
+ case TypeGNULongLink:
+ gnuLongLink = p.parseString(realname)
+ }
+ continue // This is a meta header affecting the next header
+ default:
+ // The old GNU sparse format is handled here since it is technically
+ // just a regular file with additional attributes.
+
+ if err := mergePAX(hdr, paxHdrs); err != nil {
+ return nil, err
+ }
+ if gnuLongName != "" {
+ hdr.Name = gnuLongName
+ }
+ if gnuLongLink != "" {
+ hdr.Linkname = gnuLongLink
+ }
+ if hdr.Typeflag == TypeRegA {
+ if strings.HasSuffix(hdr.Name, "/") {
+ hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories
+ } else {
+ hdr.Typeflag = TypeReg
+ }
+ }
+
+ // The extended headers may have updated the size.
+ // Thus, setup the regFileReader again after merging PAX headers.
+ if err := tr.handleRegularFile(hdr); err != nil {
+ return nil, err
+ }
+
+ // Sparse formats rely on being able to read from the logical data
+ // section; there must be a preceding call to handleRegularFile.
+ if err := tr.handleSparseFile(hdr, rawHdr); err != nil {
+ return nil, err
+ }
+
+ // Set the final guess at the format.
+ if format.has(FormatUSTAR) && format.has(FormatPAX) {
+ format.mayOnlyBe(FormatUSTAR)
+ }
+ hdr.Format = format
+ return hdr, nil // This is a file, so stop
+ }
+ }
+}
+
+// handleRegularFile sets up the current file reader and padding such that it
+// can only read the following logical data section. It will properly handle
+// special headers that contain no data section.
+func (tr *Reader) handleRegularFile(hdr *Header) error {
+ nb := hdr.Size
+ if isHeaderOnlyType(hdr.Typeflag) {
+ nb = 0
+ }
+ if nb < 0 {
+ return ErrHeader
+ }
+
+ tr.pad = blockPadding(nb)
+ tr.curr = &regFileReader{r: tr.r, nb: nb}
+ return nil
+}
+
+// handleSparseFile checks if the current file is a sparse format of any type
+// and sets the curr reader appropriately.
+func (tr *Reader) handleSparseFile(hdr *Header, rawHdr *block) error {
+ var spd sparseDatas
+ var err error
+ if hdr.Typeflag == TypeGNUSparse {
+ spd, err = tr.readOldGNUSparseMap(hdr, rawHdr)
+ } else {
+ spd, err = tr.readGNUSparsePAXHeaders(hdr)
+ }
+
+ // If sp is non-nil, then this is a sparse file.
+ // Note that it is possible for len(sp) == 0.
+ if err == nil && spd != nil {
+ if isHeaderOnlyType(hdr.Typeflag) || !validateSparseEntries(spd, hdr.Size) {
+ return ErrHeader
+ }
+ sph := invertSparseEntries(spd, hdr.Size)
+ tr.curr = &sparseFileReader{tr.curr, sph, 0}
+ }
+ return err
+}
+
+// readGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers.
+// If they are found, then this function reads the sparse map and returns it.
+// This assumes that 0.0 headers have already been converted to 0.1 headers
+// by the PAX header parsing logic.
+func (tr *Reader) readGNUSparsePAXHeaders(hdr *Header) (sparseDatas, error) {
+ // Identify the version of GNU headers.
+ var is1x0 bool
+ major, minor := hdr.PAXRecords[paxGNUSparseMajor], hdr.PAXRecords[paxGNUSparseMinor]
+ switch {
+ case major == "0" && (minor == "0" || minor == "1"):
+ is1x0 = false
+ case major == "1" && minor == "0":
+ is1x0 = true
+ case major != "" || minor != "":
+ return nil, nil // Unknown GNU sparse PAX version
+ case hdr.PAXRecords[paxGNUSparseMap] != "":
+ is1x0 = false // 0.0 and 0.1 did not have explicit version records, so guess
+ default:
+ return nil, nil // Not a PAX format GNU sparse file.
+ }
+ hdr.Format.mayOnlyBe(FormatPAX)
+
+ // Update hdr from GNU sparse PAX headers.
+ if name := hdr.PAXRecords[paxGNUSparseName]; name != "" {
+ hdr.Name = name
+ }
+ size := hdr.PAXRecords[paxGNUSparseSize]
+ if size == "" {
+ size = hdr.PAXRecords[paxGNUSparseRealSize]
+ }
+ if size != "" {
+ n, err := strconv.ParseInt(size, 10, 64)
+ if err != nil {
+ return nil, ErrHeader
+ }
+ hdr.Size = n
+ }
+
+ // Read the sparse map according to the appropriate format.
+ if is1x0 {
+ return readGNUSparseMap1x0(tr.curr)
+ }
+ return readGNUSparseMap0x1(hdr.PAXRecords)
+}
+
+// mergePAX merges paxHdrs into hdr for all relevant fields of Header.
+func mergePAX(hdr *Header, paxHdrs map[string]string) (err error) {
+ for k, v := range paxHdrs {
+ if v == "" {
+ continue // Keep the original USTAR value
+ }
+ var id64 int64
+ switch k {
+ case paxPath:
+ hdr.Name = v
+ case paxLinkpath:
+ hdr.Linkname = v
+ case paxUname:
+ hdr.Uname = v
+ case paxGname:
+ hdr.Gname = v
+ case paxUid:
+ id64, err = strconv.ParseInt(v, 10, 64)
+ hdr.Uid = int(id64) // Integer overflow possible
+ case paxGid:
+ id64, err = strconv.ParseInt(v, 10, 64)
+ hdr.Gid = int(id64) // Integer overflow possible
+ case paxAtime:
+ hdr.AccessTime, err = parsePAXTime(v)
+ case paxMtime:
+ hdr.ModTime, err = parsePAXTime(v)
+ case paxCtime:
+ hdr.ChangeTime, err = parsePAXTime(v)
+ case paxSize:
+ hdr.Size, err = strconv.ParseInt(v, 10, 64)
+ default:
+ if strings.HasPrefix(k, paxSchilyXattr) {
+ if hdr.Xattrs == nil {
+ hdr.Xattrs = make(map[string]string)
+ }
+ hdr.Xattrs[k[len(paxSchilyXattr):]] = v
+ }
+ }
+ if err != nil {
+ return ErrHeader
+ }
+ }
+ hdr.PAXRecords = paxHdrs
+ return nil
+}
+
+// parsePAX parses PAX headers.
+// If an extended header (type 'x') is invalid, ErrHeader is returned.
+func parsePAX(r io.Reader) (map[string]string, error) {
+ buf, err := readSpecialFile(r)
+ if err != nil {
+ return nil, err
+ }
+ sbuf := string(buf)
+
+ // For GNU PAX sparse format 0.0 support.
+ // This function transforms the sparse format 0.0 headers into format 0.1
+ // headers since 0.0 headers were not PAX compliant.
+ var sparseMap []string
+
+ paxHdrs := make(map[string]string)
+ for len(sbuf) > 0 {
+ key, value, residual, err := parsePAXRecord(sbuf)
+ if err != nil {
+ return nil, ErrHeader
+ }
+ sbuf = residual
+
+ switch key {
+ case paxGNUSparseOffset, paxGNUSparseNumBytes:
+ // Validate sparse header order and value.
+ if (len(sparseMap)%2 == 0 && key != paxGNUSparseOffset) ||
+ (len(sparseMap)%2 == 1 && key != paxGNUSparseNumBytes) ||
+ strings.Contains(value, ",") {
+ return nil, ErrHeader
+ }
+ sparseMap = append(sparseMap, value)
+ default:
+ paxHdrs[key] = value
+ }
+ }
+ if len(sparseMap) > 0 {
+ paxHdrs[paxGNUSparseMap] = strings.Join(sparseMap, ",")
+ }
+ return paxHdrs, nil
+}
+
+// readHeader reads the next block header and assumes that the underlying reader
+// is already aligned to a block boundary. It returns the raw block of the
+// header in case further processing is required.
+//
+// The err will be set to io.EOF only when one of the following occurs:
+// - Exactly 0 bytes are read and EOF is hit.
+// - Exactly 1 block of zeros is read and EOF is hit.
+// - At least 2 blocks of zeros are read.
+func (tr *Reader) readHeader() (*Header, *block, error) {
+ // Two blocks of zero bytes marks the end of the archive.
+ if _, err := io.ReadFull(tr.r, tr.blk[:]); err != nil {
+ return nil, nil, err // EOF is okay here; exactly 0 bytes read
+ }
+ if bytes.Equal(tr.blk[:], zeroBlock[:]) {
+ if _, err := io.ReadFull(tr.r, tr.blk[:]); err != nil {
+ return nil, nil, err // EOF is okay here; exactly 1 block of zeros read
+ }
+ if bytes.Equal(tr.blk[:], zeroBlock[:]) {
+ return nil, nil, io.EOF // normal EOF; exactly 2 block of zeros read
+ }
+ return nil, nil, ErrHeader // Zero block and then non-zero block
+ }
+
+ // Verify the header matches a known format.
+ format := tr.blk.getFormat()
+ if format == FormatUnknown {
+ return nil, nil, ErrHeader
+ }
+
+ var p parser
+ hdr := new(Header)
+
+ // Unpack the V7 header.
+ v7 := tr.blk.toV7()
+ hdr.Typeflag = v7.typeFlag()[0]
+ hdr.Name = p.parseString(v7.name())
+ hdr.Linkname = p.parseString(v7.linkName())
+ hdr.Size = p.parseNumeric(v7.size())
+ hdr.Mode = p.parseNumeric(v7.mode())
+ hdr.Uid = int(p.parseNumeric(v7.uid()))
+ hdr.Gid = int(p.parseNumeric(v7.gid()))
+ hdr.ModTime = time.Unix(p.parseNumeric(v7.modTime()), 0)
+
+ // Unpack format specific fields.
+ if format > formatV7 {
+ ustar := tr.blk.toUSTAR()
+ hdr.Uname = p.parseString(ustar.userName())
+ hdr.Gname = p.parseString(ustar.groupName())
+ hdr.Devmajor = p.parseNumeric(ustar.devMajor())
+ hdr.Devminor = p.parseNumeric(ustar.devMinor())
+
+ var prefix string
+ switch {
+ case format.has(FormatUSTAR | FormatPAX):
+ hdr.Format = format
+ ustar := tr.blk.toUSTAR()
+ prefix = p.parseString(ustar.prefix())
+
+ // For Format detection, check if block is properly formatted since
+ // the parser is more liberal than what USTAR actually permits.
+ notASCII := func(r rune) bool { return r >= 0x80 }
+ if bytes.IndexFunc(tr.blk[:], notASCII) >= 0 {
+ hdr.Format = FormatUnknown // Non-ASCII characters in block.
+ }
+ nul := func(b []byte) bool { return int(b[len(b)-1]) == 0 }
+ if !(nul(v7.size()) && nul(v7.mode()) && nul(v7.uid()) && nul(v7.gid()) &&
+ nul(v7.modTime()) && nul(ustar.devMajor()) && nul(ustar.devMinor())) {
+ hdr.Format = FormatUnknown // Numeric fields must end in NUL
+ }
+ case format.has(formatSTAR):
+ star := tr.blk.toSTAR()
+ prefix = p.parseString(star.prefix())
+ hdr.AccessTime = time.Unix(p.parseNumeric(star.accessTime()), 0)
+ hdr.ChangeTime = time.Unix(p.parseNumeric(star.changeTime()), 0)
+ case format.has(FormatGNU):
+ hdr.Format = format
+ var p2 parser
+ gnu := tr.blk.toGNU()
+ if b := gnu.accessTime(); b[0] != 0 {
+ hdr.AccessTime = time.Unix(p2.parseNumeric(b), 0)
+ }
+ if b := gnu.changeTime(); b[0] != 0 {
+ hdr.ChangeTime = time.Unix(p2.parseNumeric(b), 0)
+ }
+
+ // Prior to Go1.8, the Writer had a bug where it would output
+ // an invalid tar file in certain rare situations because the logic
+ // incorrectly believed that the old GNU format had a prefix field.
+ // This is wrong and leads to an output file that mangles the
+ // atime and ctime fields, which are often left unused.
+ //
+ // In order to continue reading tar files created by former, buggy
+ // versions of Go, we skeptically parse the atime and ctime fields.
+ // If we are unable to parse them and the prefix field looks like
+ // an ASCII string, then we fallback on the pre-Go1.8 behavior
+ // of treating these fields as the USTAR prefix field.
+ //
+ // Note that this will not use the fallback logic for all possible
+ // files generated by a pre-Go1.8 toolchain. If the generated file
+ // happened to have a prefix field that parses as valid
+ // atime and ctime fields (e.g., when they are valid octal strings),
+ // then it is impossible to distinguish between a valid GNU file
+ // and an invalid pre-Go1.8 file.
+ //
+ // See https://golang.org/issues/12594
+ // See https://golang.org/issues/21005
+ if p2.err != nil {
+ hdr.AccessTime, hdr.ChangeTime = time.Time{}, time.Time{}
+ ustar := tr.blk.toUSTAR()
+ if s := p.parseString(ustar.prefix()); isASCII(s) {
+ prefix = s
+ }
+ hdr.Format = FormatUnknown // Buggy file is not GNU
+ }
+ }
+ if len(prefix) > 0 {
+ hdr.Name = prefix + "/" + hdr.Name
+ }
+ }
+ return hdr, &tr.blk, p.err
+}
+
+// readOldGNUSparseMap reads the sparse map from the old GNU sparse format.
+// The sparse map is stored in the tar header if it's small enough.
+// If it's larger than four entries, then one or more extension headers are used
+// to store the rest of the sparse map.
+//
+// The Header.Size does not reflect the size of any extended headers used.
+// Thus, this function will read from the raw io.Reader to fetch extra headers.
+// This method mutates blk in the process.
+func (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, error) {
+ // Make sure that the input format is GNU.
+ // Unfortunately, the STAR format also has a sparse header format that uses
+ // the same type flag but has a completely different layout.
+ if blk.getFormat() != FormatGNU {
+ return nil, ErrHeader
+ }
+ hdr.Format.mayOnlyBe(FormatGNU)
+
+ var p parser
+ hdr.Size = p.parseNumeric(blk.toGNU().realSize())
+ if p.err != nil {
+ return nil, p.err
+ }
+ s := blk.toGNU().sparse()
+ spd := make(sparseDatas, 0, s.maxEntries())
+ for {
+ for i := 0; i < s.maxEntries(); i++ {
+ // This termination condition is identical to GNU and BSD tar.
+ if s.entry(i).offset()[0] == 0x00 {
+ break // Don't return, need to process extended headers (even if empty)
+ }
+ offset := p.parseNumeric(s.entry(i).offset())
+ length := p.parseNumeric(s.entry(i).length())
+ if p.err != nil {
+ return nil, p.err
+ }
+ spd = append(spd, sparseEntry{Offset: offset, Length: length})
+ }
+
+ if s.isExtended()[0] > 0 {
+ // There are more entries. Read an extension header and parse its entries.
+ if _, err := mustReadFull(tr.r, blk[:]); err != nil {
+ return nil, err
+ }
+ s = blk.toSparse()
+ continue
+ }
+ return spd, nil // Done
+ }
+}
+
+// readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format
+// version 1.0. The format of the sparse map consists of a series of
+// newline-terminated numeric fields. The first field is the number of entries
+// and is always present. Following this are the entries, consisting of two
+// fields (offset, length). This function must stop reading at the end
+// boundary of the block containing the last newline.
+//
+// Note that the GNU manual says that numeric values should be encoded in octal
+// format. However, the GNU tar utility itself outputs these values in decimal.
+// As such, this library treats values as being encoded in decimal.
+func readGNUSparseMap1x0(r io.Reader) (sparseDatas, error) {
+ var (
+ cntNewline int64
+ buf bytes.Buffer
+ blk block
+ )
+
+ // feedTokens copies data in blocks from r into buf until there are
+ // at least cnt newlines in buf. It will not read more blocks than needed.
+ feedTokens := func(n int64) error {
+ for cntNewline < n {
+ if _, err := mustReadFull(r, blk[:]); err != nil {
+ return err
+ }
+ buf.Write(blk[:])
+ for _, c := range blk {
+ if c == '\n' {
+ cntNewline++
+ }
+ }
+ }
+ return nil
+ }
+
+ // nextToken gets the next token delimited by a newline. This assumes that
+ // at least one newline exists in the buffer.
+ nextToken := func() string {
+ cntNewline--
+ tok, _ := buf.ReadString('\n')
+ return strings.TrimRight(tok, "\n")
+ }
+
+ // Parse for the number of entries.
+ // Use integer overflow resistant math to check this.
+ if err := feedTokens(1); err != nil {
+ return nil, err
+ }
+ numEntries, err := strconv.ParseInt(nextToken(), 10, 0) // Intentionally parse as native int
+ if err != nil || numEntries < 0 || int(2*numEntries) < int(numEntries) {
+ return nil, ErrHeader
+ }
+
+ // Parse for all member entries.
+ // numEntries is trusted after this since a potential attacker must have
+ // committed resources proportional to what this library used.
+ if err := feedTokens(2 * numEntries); err != nil {
+ return nil, err
+ }
+ spd := make(sparseDatas, 0, numEntries)
+ for i := int64(0); i < numEntries; i++ {
+ offset, err1 := strconv.ParseInt(nextToken(), 10, 64)
+ length, err2 := strconv.ParseInt(nextToken(), 10, 64)
+ if err1 != nil || err2 != nil {
+ return nil, ErrHeader
+ }
+ spd = append(spd, sparseEntry{Offset: offset, Length: length})
+ }
+ return spd, nil
+}
+
+// readGNUSparseMap0x1 reads the sparse map as stored in GNU's PAX sparse format
+// version 0.1. The sparse map is stored in the PAX headers.
+func readGNUSparseMap0x1(paxHdrs map[string]string) (sparseDatas, error) {
+ // Get number of entries.
+ // Use integer overflow resistant math to check this.
+ numEntriesStr := paxHdrs[paxGNUSparseNumBlocks]
+ numEntries, err := strconv.ParseInt(numEntriesStr, 10, 0) // Intentionally parse as native int
+ if err != nil || numEntries < 0 || int(2*numEntries) < int(numEntries) {
+ return nil, ErrHeader
+ }
+
+ // There should be two numbers in sparseMap for each entry.
+ sparseMap := strings.Split(paxHdrs[paxGNUSparseMap], ",")
+ if len(sparseMap) == 1 && sparseMap[0] == "" {
+ sparseMap = sparseMap[:0]
+ }
+ if int64(len(sparseMap)) != 2*numEntries {
+ return nil, ErrHeader
+ }
+
+ // Loop through the entries in the sparse map.
+ // numEntries is trusted now.
+ spd := make(sparseDatas, 0, numEntries)
+ for len(sparseMap) >= 2 {
+ offset, err1 := strconv.ParseInt(sparseMap[0], 10, 64)
+ length, err2 := strconv.ParseInt(sparseMap[1], 10, 64)
+ if err1 != nil || err2 != nil {
+ return nil, ErrHeader
+ }
+ spd = append(spd, sparseEntry{Offset: offset, Length: length})
+ sparseMap = sparseMap[2:]
+ }
+ return spd, nil
+}
+
+// Read reads from the current file in the tar archive.
+// It returns (0, io.EOF) when it reaches the end of that file,
+// until Next is called to advance to the next file.
+//
+// If the current file is sparse, then the regions marked as a hole
+// are read back as NUL-bytes.
+//
+// Calling Read on special types like TypeLink, TypeSymlink, TypeChar,
+// TypeBlock, TypeDir, and TypeFifo returns (0, io.EOF) regardless of what
+// the Header.Size claims.
+func (tr *Reader) Read(b []byte) (int, error) {
+ if tr.err != nil {
+ return 0, tr.err
+ }
+ n, err := tr.curr.Read(b)
+ if err != nil && err != io.EOF {
+ tr.err = err
+ }
+ return n, err
+}
+
+// writeTo writes the content of the current file to w.
+// The bytes written matches the number of remaining bytes in the current file.
+//
+// If the current file is sparse and w is an io.WriteSeeker,
+// then writeTo uses Seek to skip past holes defined in Header.SparseHoles,
+// assuming that skipped regions are filled with NULs.
+// This always writes the last byte to ensure w is the right size.
+//
+// TODO(dsnet): Re-export this when adding sparse file support.
+// See https://golang.org/issue/22735
+func (tr *Reader) writeTo(w io.Writer) (int64, error) {
+ if tr.err != nil {
+ return 0, tr.err
+ }
+ n, err := tr.curr.WriteTo(w)
+ if err != nil {
+ tr.err = err
+ }
+ return n, err
+}
+
+// regFileReader is a fileReader for reading data from a regular file entry.
+type regFileReader struct {
+ r io.Reader // Underlying Reader
+ nb int64 // Number of remaining bytes to read
+}
+
+func (fr *regFileReader) Read(b []byte) (n int, err error) {
+ if int64(len(b)) > fr.nb {
+ b = b[:fr.nb]
+ }
+ if len(b) > 0 {
+ n, err = fr.r.Read(b)
+ fr.nb -= int64(n)
+ }
+ switch {
+ case err == io.EOF && fr.nb > 0:
+ return n, io.ErrUnexpectedEOF
+ case err == nil && fr.nb == 0:
+ return n, io.EOF
+ default:
+ return n, err
+ }
+}
+
+func (fr *regFileReader) WriteTo(w io.Writer) (int64, error) {
+ return io.Copy(w, struct{ io.Reader }{fr})
+}
+
+// logicalRemaining implements fileState.logicalRemaining.
+func (fr regFileReader) logicalRemaining() int64 {
+ return fr.nb
+}
+
+// physicalRemaining implements fileState.physicalRemaining.
+func (fr regFileReader) physicalRemaining() int64 {
+ return fr.nb
+}
+
+// sparseFileReader is a fileReader for reading data from a sparse file entry.
+type sparseFileReader struct {
+ fr fileReader // Underlying fileReader
+ sp sparseHoles // Normalized list of sparse holes
+ pos int64 // Current position in sparse file
+}
+
+func (sr *sparseFileReader) Read(b []byte) (n int, err error) {
+ finished := int64(len(b)) >= sr.logicalRemaining()
+ if finished {
+ b = b[:sr.logicalRemaining()]
+ }
+
+ b0 := b
+ endPos := sr.pos + int64(len(b))
+ for endPos > sr.pos && err == nil {
+ var nf int // Bytes read in fragment
+ holeStart, holeEnd := sr.sp[0].Offset, sr.sp[0].endOffset()
+ if sr.pos < holeStart { // In a data fragment
+ bf := b[:min(int64(len(b)), holeStart-sr.pos)]
+ nf, err = tryReadFull(sr.fr, bf)
+ } else { // In a hole fragment
+ bf := b[:min(int64(len(b)), holeEnd-sr.pos)]
+ nf, err = tryReadFull(zeroReader{}, bf)
+ }
+ b = b[nf:]
+ sr.pos += int64(nf)
+ if sr.pos >= holeEnd && len(sr.sp) > 1 {
+ sr.sp = sr.sp[1:] // Ensure last fragment always remains
+ }
+ }
+
+ n = len(b0) - len(b)
+ switch {
+ case err == io.EOF:
+ return n, errMissData // Less data in dense file than sparse file
+ case err != nil:
+ return n, err
+ case sr.logicalRemaining() == 0 && sr.physicalRemaining() > 0:
+ return n, errUnrefData // More data in dense file than sparse file
+ case finished:
+ return n, io.EOF
+ default:
+ return n, nil
+ }
+}
+
+func (sr *sparseFileReader) WriteTo(w io.Writer) (n int64, err error) {
+ ws, ok := w.(io.WriteSeeker)
+ if ok {
+ if _, err := ws.Seek(0, io.SeekCurrent); err != nil {
+ ok = false // Not all io.Seeker can really seek
+ }
+ }
+ if !ok {
+ return io.Copy(w, struct{ io.Reader }{sr})
+ }
+
+ var writeLastByte bool
+ pos0 := sr.pos
+ for sr.logicalRemaining() > 0 && !writeLastByte && err == nil {
+ var nf int64 // Size of fragment
+ holeStart, holeEnd := sr.sp[0].Offset, sr.sp[0].endOffset()
+ if sr.pos < holeStart { // In a data fragment
+ nf = holeStart - sr.pos
+ nf, err = io.CopyN(ws, sr.fr, nf)
+ } else { // In a hole fragment
+ nf = holeEnd - sr.pos
+ if sr.physicalRemaining() == 0 {
+ writeLastByte = true
+ nf--
+ }
+ _, err = ws.Seek(nf, io.SeekCurrent)
+ }
+ sr.pos += nf
+ if sr.pos >= holeEnd && len(sr.sp) > 1 {
+ sr.sp = sr.sp[1:] // Ensure last fragment always remains
+ }
+ }
+
+ // If the last fragment is a hole, then seek to 1-byte before EOF, and
+ // write a single byte to ensure the file is the right size.
+ if writeLastByte && err == nil {
+ _, err = ws.Write([]byte{0})
+ sr.pos++
+ }
+
+ n = sr.pos - pos0
+ switch {
+ case err == io.EOF:
+ return n, errMissData // Less data in dense file than sparse file
+ case err != nil:
+ return n, err
+ case sr.logicalRemaining() == 0 && sr.physicalRemaining() > 0:
+ return n, errUnrefData // More data in dense file than sparse file
+ default:
+ return n, nil
+ }
+}
+
+func (sr sparseFileReader) logicalRemaining() int64 {
+ return sr.sp[len(sr.sp)-1].endOffset() - sr.pos
+}
+func (sr sparseFileReader) physicalRemaining() int64 {
+ return sr.fr.physicalRemaining()
+}
+
+type zeroReader struct{}
+
+func (zeroReader) Read(b []byte) (int, error) {
+ for i := range b {
+ b[i] = 0
+ }
+ return len(b), nil
+}
+
+// mustReadFull is like io.ReadFull except it returns
+// io.ErrUnexpectedEOF when io.EOF is hit before len(b) bytes are read.
+func mustReadFull(r io.Reader, b []byte) (int, error) {
+ n, err := tryReadFull(r, b)
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return n, err
+}
+
+// tryReadFull is like io.ReadFull except it returns
+// io.EOF when it is hit before len(b) bytes are read.
+func tryReadFull(r io.Reader, b []byte) (n int, err error) {
+ for len(b) > n && err == nil {
+ var nn int
+ nn, err = r.Read(b[n:])
+ n += nn
+ }
+ if len(b) == n && err == io.EOF {
+ err = nil
+ }
+ return n, err
+}
+
+// readSpecialFile is like io.ReadAll except it returns
+// ErrFieldTooLong if more than maxSpecialFileSize is read.
+func readSpecialFile(r io.Reader) ([]byte, error) {
+ buf, err := io.ReadAll(io.LimitReader(r, maxSpecialFileSize+1))
+ if len(buf) > maxSpecialFileSize {
+ return nil, ErrFieldTooLong
+ }
+ return buf, err
+}
+
+// discard skips n bytes in r, reporting an error if unable to do so.
+func discard(r io.Reader, n int64) error {
+ // If possible, Seek to the last byte before the end of the data section.
+ // Do this because Seek is often lazy about reporting errors; this will mask
+ // the fact that the stream may be truncated. We can rely on the
+ // io.CopyN done shortly afterwards to trigger any IO errors.
+ var seekSkipped int64 // Number of bytes skipped via Seek
+ if sr, ok := r.(io.Seeker); ok && n > 1 {
+ // Not all io.Seeker can actually Seek. For example, os.Stdin implements
+ // io.Seeker, but calling Seek always returns an error and performs
+ // no action. Thus, we try an innocent seek to the current position
+ // to see if Seek is really supported.
+ pos1, err := sr.Seek(0, io.SeekCurrent)
+ if pos1 >= 0 && err == nil {
+ // Seek seems supported, so perform the real Seek.
+ pos2, err := sr.Seek(n-1, io.SeekCurrent)
+ if pos2 < 0 || err != nil {
+ return err
+ }
+ seekSkipped = pos2 - pos1
+ }
+ }
+
+ copySkipped, err := io.CopyN(io.Discard, r, n-seekSkipped)
+ if err == io.EOF && seekSkipped+copySkipped < n {
+ err = io.ErrUnexpectedEOF
+ }
+ return err
+}
diff --git a/contrib/go/_std_1.20/src/archive/tar/stat_actime1.go b/contrib/go/_std_1.21/src/archive/tar/stat_actime1.go
index c4c2480fee..c4c2480fee 100644
--- a/contrib/go/_std_1.20/src/archive/tar/stat_actime1.go
+++ b/contrib/go/_std_1.21/src/archive/tar/stat_actime1.go
diff --git a/contrib/go/_std_1.20/src/archive/tar/stat_actime2.go b/contrib/go/_std_1.21/src/archive/tar/stat_actime2.go
index f76d6be220..f76d6be220 100644
--- a/contrib/go/_std_1.20/src/archive/tar/stat_actime2.go
+++ b/contrib/go/_std_1.21/src/archive/tar/stat_actime2.go
diff --git a/contrib/go/_std_1.20/src/archive/tar/stat_unix.go b/contrib/go/_std_1.21/src/archive/tar/stat_unix.go
index 0f3428bc24..0f3428bc24 100644
--- a/contrib/go/_std_1.20/src/archive/tar/stat_unix.go
+++ b/contrib/go/_std_1.21/src/archive/tar/stat_unix.go
diff --git a/contrib/go/_std_1.20/src/archive/tar/strconv.go b/contrib/go/_std_1.21/src/archive/tar/strconv.go
index ac3196370e..ac3196370e 100644
--- a/contrib/go/_std_1.20/src/archive/tar/strconv.go
+++ b/contrib/go/_std_1.21/src/archive/tar/strconv.go
diff --git a/contrib/go/_std_1.20/src/archive/tar/writer.go b/contrib/go/_std_1.21/src/archive/tar/writer.go
index 1c95f0738a..1c95f0738a 100644
--- a/contrib/go/_std_1.20/src/archive/tar/writer.go
+++ b/contrib/go/_std_1.21/src/archive/tar/writer.go
diff --git a/contrib/go/_std_1.21/src/archive/tar/ya.make b/contrib/go/_std_1.21/src/archive/tar/ya.make
new file mode 100644
index 0000000000..4b06fb1c02
--- /dev/null
+++ b/contrib/go/_std_1.21/src/archive/tar/ya.make
@@ -0,0 +1,38 @@
+GO_LIBRARY()
+
+SRCS(
+ common.go
+ format.go
+ reader.go
+ strconv.go
+ writer.go
+)
+
+GO_TEST_SRCS(
+ fuzz_test.go
+ reader_test.go
+ strconv_test.go
+ tar_test.go
+ writer_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+IF (OS_LINUX)
+ SRCS(
+ stat_actime1.go
+ stat_unix.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ stat_actime2.go
+ stat_unix.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/archive/zip/reader.go b/contrib/go/_std_1.21/src/archive/zip/reader.go
new file mode 100644
index 0000000000..1fde1decc4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/archive/zip/reader.go
@@ -0,0 +1,979 @@
+// Copyright 2010 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 zip
+
+import (
+ "bufio"
+ "encoding/binary"
+ "errors"
+ "hash"
+ "hash/crc32"
+ "internal/godebug"
+ "io"
+ "io/fs"
+ "os"
+ "path"
+ "path/filepath"
+ "sort"
+ "strings"
+ "sync"
+ "time"
+)
+
+var zipinsecurepath = godebug.New("zipinsecurepath")
+
+var (
+ ErrFormat = errors.New("zip: not a valid zip file")
+ ErrAlgorithm = errors.New("zip: unsupported compression algorithm")
+ ErrChecksum = errors.New("zip: checksum error")
+ ErrInsecurePath = errors.New("zip: insecure file path")
+)
+
+// A Reader serves content from a ZIP archive.
+type Reader struct {
+ r io.ReaderAt
+ File []*File
+ Comment string
+ decompressors map[uint16]Decompressor
+
+ // Some JAR files are zip files with a prefix that is a bash script.
+ // The baseOffset field is the start of the zip file proper.
+ baseOffset int64
+
+ // fileList is a list of files sorted by ename,
+ // for use by the Open method.
+ fileListOnce sync.Once
+ fileList []fileListEntry
+}
+
+// A ReadCloser is a Reader that must be closed when no longer needed.
+type ReadCloser struct {
+ f *os.File
+ Reader
+}
+
+// A File is a single file in a ZIP archive.
+// The file information is in the embedded FileHeader.
+// The file content can be accessed by calling Open.
+type File struct {
+ FileHeader
+ zip *Reader
+ zipr io.ReaderAt
+ headerOffset int64 // includes overall ZIP archive baseOffset
+ zip64 bool // zip64 extended information extra field presence
+}
+
+// OpenReader will open the Zip file specified by name and return a ReadCloser.
+//
+// If any file inside the archive uses a non-local name
+// (as defined by [filepath.IsLocal]) or a name containing backslashes
+// and the GODEBUG environment variable contains `zipinsecurepath=0`,
+// OpenReader returns the reader with an ErrInsecurePath error.
+// A future version of Go may introduce this behavior by default.
+// Programs that want to accept non-local names can ignore
+// the ErrInsecurePath error and use the returned reader.
+func OpenReader(name string) (*ReadCloser, error) {
+ f, err := os.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ fi, err := f.Stat()
+ if err != nil {
+ f.Close()
+ return nil, err
+ }
+ r := new(ReadCloser)
+ if err = r.init(f, fi.Size()); err != nil && err != ErrInsecurePath {
+ f.Close()
+ return nil, err
+ }
+ r.f = f
+ return r, err
+}
+
+// NewReader returns a new Reader reading from r, which is assumed to
+// have the given size in bytes.
+//
+// If any file inside the archive uses a non-local name
+// (as defined by [filepath.IsLocal]) or a name containing backslashes
+// and the GODEBUG environment variable contains `zipinsecurepath=0`,
+// NewReader returns the reader with an ErrInsecurePath error.
+// A future version of Go may introduce this behavior by default.
+// Programs that want to accept non-local names can ignore
+// the ErrInsecurePath error and use the returned reader.
+func NewReader(r io.ReaderAt, size int64) (*Reader, error) {
+ if size < 0 {
+ return nil, errors.New("zip: size cannot be negative")
+ }
+ zr := new(Reader)
+ var err error
+ if err = zr.init(r, size); err != nil && err != ErrInsecurePath {
+ return nil, err
+ }
+ return zr, err
+}
+
+func (r *Reader) init(rdr io.ReaderAt, size int64) error {
+ end, baseOffset, err := readDirectoryEnd(rdr, size)
+ if err != nil {
+ return err
+ }
+ r.r = rdr
+ r.baseOffset = baseOffset
+ // Since the number of directory records is not validated, it is not
+ // safe to preallocate r.File without first checking that the specified
+ // number of files is reasonable, since a malformed archive may
+ // indicate it contains up to 1 << 128 - 1 files. Since each file has a
+ // header which will be _at least_ 30 bytes we can safely preallocate
+ // if (data size / 30) >= end.directoryRecords.
+ if end.directorySize < uint64(size) && (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
+ r.File = make([]*File, 0, end.directoryRecords)
+ }
+ r.Comment = end.comment
+ rs := io.NewSectionReader(rdr, 0, size)
+ if _, err = rs.Seek(r.baseOffset+int64(end.directoryOffset), io.SeekStart); err != nil {
+ return err
+ }
+ buf := bufio.NewReader(rs)
+
+ // The count of files inside a zip is truncated to fit in a uint16.
+ // Gloss over this by reading headers until we encounter
+ // a bad one, and then only report an ErrFormat or UnexpectedEOF if
+ // the file count modulo 65536 is incorrect.
+ for {
+ f := &File{zip: r, zipr: rdr}
+ err = readDirectoryHeader(f, buf)
+ if err == ErrFormat || err == io.ErrUnexpectedEOF {
+ break
+ }
+ if err != nil {
+ return err
+ }
+ f.headerOffset += r.baseOffset
+ r.File = append(r.File, f)
+ }
+ if uint16(len(r.File)) != uint16(end.directoryRecords) { // only compare 16 bits here
+ // Return the readDirectoryHeader error if we read
+ // the wrong number of directory entries.
+ return err
+ }
+ if zipinsecurepath.Value() == "0" {
+ for _, f := range r.File {
+ if f.Name == "" {
+ // Zip permits an empty file name field.
+ continue
+ }
+ // The zip specification states that names must use forward slashes,
+ // so consider any backslashes in the name insecure.
+ if !filepath.IsLocal(f.Name) || strings.Contains(f.Name, `\`) {
+ zipinsecurepath.IncNonDefault()
+ return ErrInsecurePath
+ }
+ }
+ }
+ return nil
+}
+
+// RegisterDecompressor registers or overrides a custom decompressor for a
+// specific method ID. If a decompressor for a given method is not found,
+// Reader will default to looking up the decompressor at the package level.
+func (r *Reader) RegisterDecompressor(method uint16, dcomp Decompressor) {
+ if r.decompressors == nil {
+ r.decompressors = make(map[uint16]Decompressor)
+ }
+ r.decompressors[method] = dcomp
+}
+
+func (r *Reader) decompressor(method uint16) Decompressor {
+ dcomp := r.decompressors[method]
+ if dcomp == nil {
+ dcomp = decompressor(method)
+ }
+ return dcomp
+}
+
+// Close closes the Zip file, rendering it unusable for I/O.
+func (rc *ReadCloser) Close() error {
+ return rc.f.Close()
+}
+
+// DataOffset returns the offset of the file's possibly-compressed
+// data, relative to the beginning of the zip file.
+//
+// Most callers should instead use Open, which transparently
+// decompresses data and verifies checksums.
+func (f *File) DataOffset() (offset int64, err error) {
+ bodyOffset, err := f.findBodyOffset()
+ if err != nil {
+ return
+ }
+ return f.headerOffset + bodyOffset, nil
+}
+
+// Open returns a ReadCloser that provides access to the File's contents.
+// Multiple files may be read concurrently.
+func (f *File) Open() (io.ReadCloser, error) {
+ bodyOffset, err := f.findBodyOffset()
+ if err != nil {
+ return nil, err
+ }
+ if strings.HasSuffix(f.Name, "/") {
+ // The ZIP specification (APPNOTE.TXT) specifies that directories, which
+ // are technically zero-byte files, must not have any associated file
+ // data. We previously tried failing here if f.CompressedSize64 != 0,
+ // but it turns out that a number of implementations (namely, the Java
+ // jar tool) don't properly set the storage method on directories
+ // resulting in a file with compressed size > 0 but uncompressed size ==
+ // 0. We still want to fail when a directory has associated uncompressed
+ // data, but we are tolerant of cases where the uncompressed size is
+ // zero but compressed size is not.
+ if f.UncompressedSize64 != 0 {
+ return &dirReader{ErrFormat}, nil
+ } else {
+ return &dirReader{io.EOF}, nil
+ }
+ }
+ size := int64(f.CompressedSize64)
+ r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, size)
+ dcomp := f.zip.decompressor(f.Method)
+ if dcomp == nil {
+ return nil, ErrAlgorithm
+ }
+ var rc io.ReadCloser = dcomp(r)
+ var desr io.Reader
+ if f.hasDataDescriptor() {
+ desr = io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+size, dataDescriptorLen)
+ }
+ rc = &checksumReader{
+ rc: rc,
+ hash: crc32.NewIEEE(),
+ f: f,
+ desr: desr,
+ }
+ return rc, nil
+}
+
+// OpenRaw returns a Reader that provides access to the File's contents without
+// decompression.
+func (f *File) OpenRaw() (io.Reader, error) {
+ bodyOffset, err := f.findBodyOffset()
+ if err != nil {
+ return nil, err
+ }
+ r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, int64(f.CompressedSize64))
+ return r, nil
+}
+
+type dirReader struct {
+ err error
+}
+
+func (r *dirReader) Read([]byte) (int, error) {
+ return 0, r.err
+}
+
+func (r *dirReader) Close() error {
+ return nil
+}
+
+type checksumReader struct {
+ rc io.ReadCloser
+ hash hash.Hash32
+ nread uint64 // number of bytes read so far
+ f *File
+ desr io.Reader // if non-nil, where to read the data descriptor
+ err error // sticky error
+}
+
+func (r *checksumReader) Stat() (fs.FileInfo, error) {
+ return headerFileInfo{&r.f.FileHeader}, nil
+}
+
+func (r *checksumReader) Read(b []byte) (n int, err error) {
+ if r.err != nil {
+ return 0, r.err
+ }
+ n, err = r.rc.Read(b)
+ r.hash.Write(b[:n])
+ r.nread += uint64(n)
+ if r.nread > r.f.UncompressedSize64 {
+ return 0, ErrFormat
+ }
+ if err == nil {
+ return
+ }
+ if err == io.EOF {
+ if r.nread != r.f.UncompressedSize64 {
+ return 0, io.ErrUnexpectedEOF
+ }
+ if r.desr != nil {
+ if err1 := readDataDescriptor(r.desr, r.f); err1 != nil {
+ if err1 == io.EOF {
+ err = io.ErrUnexpectedEOF
+ } else {
+ err = err1
+ }
+ } else if r.hash.Sum32() != r.f.CRC32 {
+ err = ErrChecksum
+ }
+ } else {
+ // If there's not a data descriptor, we still compare
+ // the CRC32 of what we've read against the file header
+ // or TOC's CRC32, if it seems like it was set.
+ if r.f.CRC32 != 0 && r.hash.Sum32() != r.f.CRC32 {
+ err = ErrChecksum
+ }
+ }
+ }
+ r.err = err
+ return
+}
+
+func (r *checksumReader) Close() error { return r.rc.Close() }
+
+// findBodyOffset does the minimum work to verify the file has a header
+// and returns the file body offset.
+func (f *File) findBodyOffset() (int64, error) {
+ var buf [fileHeaderLen]byte
+ if _, err := f.zipr.ReadAt(buf[:], f.headerOffset); err != nil {
+ return 0, err
+ }
+ b := readBuf(buf[:])
+ if sig := b.uint32(); sig != fileHeaderSignature {
+ return 0, ErrFormat
+ }
+ b = b[22:] // skip over most of the header
+ filenameLen := int(b.uint16())
+ extraLen := int(b.uint16())
+ return int64(fileHeaderLen + filenameLen + extraLen), nil
+}
+
+// readDirectoryHeader attempts to read a directory header from r.
+// It returns io.ErrUnexpectedEOF if it cannot read a complete header,
+// and ErrFormat if it doesn't find a valid header signature.
+func readDirectoryHeader(f *File, r io.Reader) error {
+ var buf [directoryHeaderLen]byte
+ if _, err := io.ReadFull(r, buf[:]); err != nil {
+ return err
+ }
+ b := readBuf(buf[:])
+ if sig := b.uint32(); sig != directoryHeaderSignature {
+ return ErrFormat
+ }
+ f.CreatorVersion = b.uint16()
+ f.ReaderVersion = b.uint16()
+ f.Flags = b.uint16()
+ f.Method = b.uint16()
+ f.ModifiedTime = b.uint16()
+ f.ModifiedDate = b.uint16()
+ f.CRC32 = b.uint32()
+ f.CompressedSize = b.uint32()
+ f.UncompressedSize = b.uint32()
+ f.CompressedSize64 = uint64(f.CompressedSize)
+ f.UncompressedSize64 = uint64(f.UncompressedSize)
+ filenameLen := int(b.uint16())
+ extraLen := int(b.uint16())
+ commentLen := int(b.uint16())
+ b = b[4:] // skipped start disk number and internal attributes (2x uint16)
+ f.ExternalAttrs = b.uint32()
+ f.headerOffset = int64(b.uint32())
+ d := make([]byte, filenameLen+extraLen+commentLen)
+ if _, err := io.ReadFull(r, d); err != nil {
+ return err
+ }
+ f.Name = string(d[:filenameLen])
+ f.Extra = d[filenameLen : filenameLen+extraLen]
+ f.Comment = string(d[filenameLen+extraLen:])
+
+ // Determine the character encoding.
+ utf8Valid1, utf8Require1 := detectUTF8(f.Name)
+ utf8Valid2, utf8Require2 := detectUTF8(f.Comment)
+ switch {
+ case !utf8Valid1 || !utf8Valid2:
+ // Name and Comment definitely not UTF-8.
+ f.NonUTF8 = true
+ case !utf8Require1 && !utf8Require2:
+ // Name and Comment use only single-byte runes that overlap with UTF-8.
+ f.NonUTF8 = false
+ default:
+ // Might be UTF-8, might be some other encoding; preserve existing flag.
+ // Some ZIP writers use UTF-8 encoding without setting the UTF-8 flag.
+ // Since it is impossible to always distinguish valid UTF-8 from some
+ // other encoding (e.g., GBK or Shift-JIS), we trust the flag.
+ f.NonUTF8 = f.Flags&0x800 == 0
+ }
+
+ needUSize := f.UncompressedSize == ^uint32(0)
+ needCSize := f.CompressedSize == ^uint32(0)
+ needHeaderOffset := f.headerOffset == int64(^uint32(0))
+
+ // Best effort to find what we need.
+ // Other zip authors might not even follow the basic format,
+ // and we'll just ignore the Extra content in that case.
+ var modified time.Time
+parseExtras:
+ for extra := readBuf(f.Extra); len(extra) >= 4; { // need at least tag and size
+ fieldTag := extra.uint16()
+ fieldSize := int(extra.uint16())
+ if len(extra) < fieldSize {
+ break
+ }
+ fieldBuf := extra.sub(fieldSize)
+
+ switch fieldTag {
+ case zip64ExtraID:
+ f.zip64 = true
+
+ // update directory values from the zip64 extra block.
+ // They should only be consulted if the sizes read earlier
+ // are maxed out.
+ // See golang.org/issue/13367.
+ if needUSize {
+ needUSize = false
+ if len(fieldBuf) < 8 {
+ return ErrFormat
+ }
+ f.UncompressedSize64 = fieldBuf.uint64()
+ }
+ if needCSize {
+ needCSize = false
+ if len(fieldBuf) < 8 {
+ return ErrFormat
+ }
+ f.CompressedSize64 = fieldBuf.uint64()
+ }
+ if needHeaderOffset {
+ needHeaderOffset = false
+ if len(fieldBuf) < 8 {
+ return ErrFormat
+ }
+ f.headerOffset = int64(fieldBuf.uint64())
+ }
+ case ntfsExtraID:
+ if len(fieldBuf) < 4 {
+ continue parseExtras
+ }
+ fieldBuf.uint32() // reserved (ignored)
+ for len(fieldBuf) >= 4 { // need at least tag and size
+ attrTag := fieldBuf.uint16()
+ attrSize := int(fieldBuf.uint16())
+ if len(fieldBuf) < attrSize {
+ continue parseExtras
+ }
+ attrBuf := fieldBuf.sub(attrSize)
+ if attrTag != 1 || attrSize != 24 {
+ continue // Ignore irrelevant attributes
+ }
+
+ const ticksPerSecond = 1e7 // Windows timestamp resolution
+ ts := int64(attrBuf.uint64()) // ModTime since Windows epoch
+ secs := int64(ts / ticksPerSecond)
+ nsecs := (1e9 / ticksPerSecond) * int64(ts%ticksPerSecond)
+ epoch := time.Date(1601, time.January, 1, 0, 0, 0, 0, time.UTC)
+ modified = time.Unix(epoch.Unix()+secs, nsecs)
+ }
+ case unixExtraID, infoZipUnixExtraID:
+ if len(fieldBuf) < 8 {
+ continue parseExtras
+ }
+ fieldBuf.uint32() // AcTime (ignored)
+ ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
+ modified = time.Unix(ts, 0)
+ case extTimeExtraID:
+ if len(fieldBuf) < 5 || fieldBuf.uint8()&1 == 0 {
+ continue parseExtras
+ }
+ ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
+ modified = time.Unix(ts, 0)
+ }
+ }
+
+ msdosModified := msDosTimeToTime(f.ModifiedDate, f.ModifiedTime)
+ f.Modified = msdosModified
+ if !modified.IsZero() {
+ f.Modified = modified.UTC()
+
+ // If legacy MS-DOS timestamps are set, we can use the delta between
+ // the legacy and extended versions to estimate timezone offset.
+ //
+ // A non-UTC timezone is always used (even if offset is zero).
+ // Thus, FileHeader.Modified.Location() == time.UTC is useful for
+ // determining whether extended timestamps are present.
+ // This is necessary for users that need to do additional time
+ // calculations when dealing with legacy ZIP formats.
+ if f.ModifiedTime != 0 || f.ModifiedDate != 0 {
+ f.Modified = modified.In(timeZone(msdosModified.Sub(modified)))
+ }
+ }
+
+ // Assume that uncompressed size 2³²-1 could plausibly happen in
+ // an old zip32 file that was sharding inputs into the largest chunks
+ // possible (or is just malicious; search the web for 42.zip).
+ // If needUSize is true still, it means we didn't see a zip64 extension.
+ // As long as the compressed size is not also 2³²-1 (implausible)
+ // and the header is not also 2³²-1 (equally implausible),
+ // accept the uncompressed size 2³²-1 as valid.
+ // If nothing else, this keeps archive/zip working with 42.zip.
+ _ = needUSize
+
+ if needCSize || needHeaderOffset {
+ return ErrFormat
+ }
+
+ return nil
+}
+
+func readDataDescriptor(r io.Reader, f *File) error {
+ var buf [dataDescriptorLen]byte
+ // The spec says: "Although not originally assigned a
+ // signature, the value 0x08074b50 has commonly been adopted
+ // as a signature value for the data descriptor record.
+ // Implementers should be aware that ZIP files may be
+ // encountered with or without this signature marking data
+ // descriptors and should account for either case when reading
+ // ZIP files to ensure compatibility."
+ //
+ // dataDescriptorLen includes the size of the signature but
+ // first read just those 4 bytes to see if it exists.
+ if _, err := io.ReadFull(r, buf[:4]); err != nil {
+ return err
+ }
+ off := 0
+ maybeSig := readBuf(buf[:4])
+ if maybeSig.uint32() != dataDescriptorSignature {
+ // No data descriptor signature. Keep these four
+ // bytes.
+ off += 4
+ }
+ if _, err := io.ReadFull(r, buf[off:12]); err != nil {
+ return err
+ }
+ b := readBuf(buf[:12])
+ if b.uint32() != f.CRC32 {
+ return ErrChecksum
+ }
+
+ // The two sizes that follow here can be either 32 bits or 64 bits
+ // but the spec is not very clear on this and different
+ // interpretations has been made causing incompatibilities. We
+ // already have the sizes from the central directory so we can
+ // just ignore these.
+
+ return nil
+}
+
+func readDirectoryEnd(r io.ReaderAt, size int64) (dir *directoryEnd, baseOffset int64, err error) {
+ // look for directoryEndSignature in the last 1k, then in the last 65k
+ var buf []byte
+ var directoryEndOffset int64
+ for i, bLen := range []int64{1024, 65 * 1024} {
+ if bLen > size {
+ bLen = size
+ }
+ buf = make([]byte, int(bLen))
+ if _, err := r.ReadAt(buf, size-bLen); err != nil && err != io.EOF {
+ return nil, 0, err
+ }
+ if p := findSignatureInBlock(buf); p >= 0 {
+ buf = buf[p:]
+ directoryEndOffset = size - bLen + int64(p)
+ break
+ }
+ if i == 1 || bLen == size {
+ return nil, 0, ErrFormat
+ }
+ }
+
+ // read header into struct
+ b := readBuf(buf[4:]) // skip signature
+ d := &directoryEnd{
+ diskNbr: uint32(b.uint16()),
+ dirDiskNbr: uint32(b.uint16()),
+ dirRecordsThisDisk: uint64(b.uint16()),
+ directoryRecords: uint64(b.uint16()),
+ directorySize: uint64(b.uint32()),
+ directoryOffset: uint64(b.uint32()),
+ commentLen: b.uint16(),
+ }
+ l := int(d.commentLen)
+ if l > len(b) {
+ return nil, 0, errors.New("zip: invalid comment length")
+ }
+ d.comment = string(b[:l])
+
+ // These values mean that the file can be a zip64 file
+ if d.directoryRecords == 0xffff || d.directorySize == 0xffff || d.directoryOffset == 0xffffffff {
+ p, err := findDirectory64End(r, directoryEndOffset)
+ if err == nil && p >= 0 {
+ directoryEndOffset = p
+ err = readDirectory64End(r, p, d)
+ }
+ if err != nil {
+ return nil, 0, err
+ }
+ }
+
+ maxInt64 := uint64(1<<63 - 1)
+ if d.directorySize > maxInt64 || d.directoryOffset > maxInt64 {
+ return nil, 0, ErrFormat
+ }
+
+ baseOffset = directoryEndOffset - int64(d.directorySize) - int64(d.directoryOffset)
+
+ // Make sure directoryOffset points to somewhere in our file.
+ if o := baseOffset + int64(d.directoryOffset); o < 0 || o >= size {
+ return nil, 0, ErrFormat
+ }
+
+ // If the directory end data tells us to use a non-zero baseOffset,
+ // but we would find a valid directory entry if we assume that the
+ // baseOffset is 0, then just use a baseOffset of 0.
+ // We've seen files in which the directory end data gives us
+ // an incorrect baseOffset.
+ if baseOffset > 0 {
+ off := int64(d.directoryOffset)
+ rs := io.NewSectionReader(r, off, size-off)
+ if readDirectoryHeader(&File{}, rs) == nil {
+ baseOffset = 0
+ }
+ }
+
+ return d, baseOffset, nil
+}
+
+// findDirectory64End tries to read the zip64 locator just before the
+// directory end and returns the offset of the zip64 directory end if
+// found.
+func findDirectory64End(r io.ReaderAt, directoryEndOffset int64) (int64, error) {
+ locOffset := directoryEndOffset - directory64LocLen
+ if locOffset < 0 {
+ return -1, nil // no need to look for a header outside the file
+ }
+ buf := make([]byte, directory64LocLen)
+ if _, err := r.ReadAt(buf, locOffset); err != nil {
+ return -1, err
+ }
+ b := readBuf(buf)
+ if sig := b.uint32(); sig != directory64LocSignature {
+ return -1, nil
+ }
+ if b.uint32() != 0 { // number of the disk with the start of the zip64 end of central directory
+ return -1, nil // the file is not a valid zip64-file
+ }
+ p := b.uint64() // relative offset of the zip64 end of central directory record
+ if b.uint32() != 1 { // total number of disks
+ return -1, nil // the file is not a valid zip64-file
+ }
+ return int64(p), nil
+}
+
+// readDirectory64End reads the zip64 directory end and updates the
+// directory end with the zip64 directory end values.
+func readDirectory64End(r io.ReaderAt, offset int64, d *directoryEnd) (err error) {
+ buf := make([]byte, directory64EndLen)
+ if _, err := r.ReadAt(buf, offset); err != nil {
+ return err
+ }
+
+ b := readBuf(buf)
+ if sig := b.uint32(); sig != directory64EndSignature {
+ return ErrFormat
+ }
+
+ b = b[12:] // skip dir size, version and version needed (uint64 + 2x uint16)
+ d.diskNbr = b.uint32() // number of this disk
+ d.dirDiskNbr = b.uint32() // number of the disk with the start of the central directory
+ d.dirRecordsThisDisk = b.uint64() // total number of entries in the central directory on this disk
+ d.directoryRecords = b.uint64() // total number of entries in the central directory
+ d.directorySize = b.uint64() // size of the central directory
+ d.directoryOffset = b.uint64() // offset of start of central directory with respect to the starting disk number
+
+ return nil
+}
+
+func findSignatureInBlock(b []byte) int {
+ for i := len(b) - directoryEndLen; i >= 0; i-- {
+ // defined from directoryEndSignature in struct.go
+ if b[i] == 'P' && b[i+1] == 'K' && b[i+2] == 0x05 && b[i+3] == 0x06 {
+ // n is length of comment
+ n := int(b[i+directoryEndLen-2]) | int(b[i+directoryEndLen-1])<<8
+ if n+directoryEndLen+i <= len(b) {
+ return i
+ }
+ }
+ }
+ return -1
+}
+
+type readBuf []byte
+
+func (b *readBuf) uint8() uint8 {
+ v := (*b)[0]
+ *b = (*b)[1:]
+ return v
+}
+
+func (b *readBuf) uint16() uint16 {
+ v := binary.LittleEndian.Uint16(*b)
+ *b = (*b)[2:]
+ return v
+}
+
+func (b *readBuf) uint32() uint32 {
+ v := binary.LittleEndian.Uint32(*b)
+ *b = (*b)[4:]
+ return v
+}
+
+func (b *readBuf) uint64() uint64 {
+ v := binary.LittleEndian.Uint64(*b)
+ *b = (*b)[8:]
+ return v
+}
+
+func (b *readBuf) sub(n int) readBuf {
+ b2 := (*b)[:n]
+ *b = (*b)[n:]
+ return b2
+}
+
+// A fileListEntry is a File and its ename.
+// If file == nil, the fileListEntry describes a directory without metadata.
+type fileListEntry struct {
+ name string
+ file *File
+ isDir bool
+ isDup bool
+}
+
+type fileInfoDirEntry interface {
+ fs.FileInfo
+ fs.DirEntry
+}
+
+func (f *fileListEntry) stat() (fileInfoDirEntry, error) {
+ if f.isDup {
+ return nil, errors.New(f.name + ": duplicate entries in zip file")
+ }
+ if !f.isDir {
+ return headerFileInfo{&f.file.FileHeader}, nil
+ }
+ return f, nil
+}
+
+// Only used for directories.
+func (f *fileListEntry) Name() string { _, elem, _ := split(f.name); return elem }
+func (f *fileListEntry) Size() int64 { return 0 }
+func (f *fileListEntry) Mode() fs.FileMode { return fs.ModeDir | 0555 }
+func (f *fileListEntry) Type() fs.FileMode { return fs.ModeDir }
+func (f *fileListEntry) IsDir() bool { return true }
+func (f *fileListEntry) Sys() any { return nil }
+
+func (f *fileListEntry) ModTime() time.Time {
+ if f.file == nil {
+ return time.Time{}
+ }
+ return f.file.FileHeader.Modified.UTC()
+}
+
+func (f *fileListEntry) Info() (fs.FileInfo, error) { return f, nil }
+
+func (f *fileListEntry) String() string {
+ return fs.FormatDirEntry(f)
+}
+
+// toValidName coerces name to be a valid name for fs.FS.Open.
+func toValidName(name string) string {
+ name = strings.ReplaceAll(name, `\`, `/`)
+ p := path.Clean(name)
+
+ p = strings.TrimPrefix(p, "/")
+
+ for strings.HasPrefix(p, "../") {
+ p = p[len("../"):]
+ }
+
+ return p
+}
+
+func (r *Reader) initFileList() {
+ r.fileListOnce.Do(func() {
+ // files and knownDirs map from a file/directory name
+ // to an index into the r.fileList entry that we are
+ // building. They are used to mark duplicate entries.
+ files := make(map[string]int)
+ knownDirs := make(map[string]int)
+
+ // dirs[name] is true if name is known to be a directory,
+ // because it appears as a prefix in a path.
+ dirs := make(map[string]bool)
+
+ for _, file := range r.File {
+ isDir := len(file.Name) > 0 && file.Name[len(file.Name)-1] == '/'
+ name := toValidName(file.Name)
+ if name == "" {
+ continue
+ }
+
+ if idx, ok := files[name]; ok {
+ r.fileList[idx].isDup = true
+ continue
+ }
+ if idx, ok := knownDirs[name]; ok {
+ r.fileList[idx].isDup = true
+ continue
+ }
+
+ for dir := path.Dir(name); dir != "."; dir = path.Dir(dir) {
+ dirs[dir] = true
+ }
+
+ idx := len(r.fileList)
+ entry := fileListEntry{
+ name: name,
+ file: file,
+ isDir: isDir,
+ }
+ r.fileList = append(r.fileList, entry)
+ if isDir {
+ knownDirs[name] = idx
+ } else {
+ files[name] = idx
+ }
+ }
+ for dir := range dirs {
+ if _, ok := knownDirs[dir]; !ok {
+ if idx, ok := files[dir]; ok {
+ r.fileList[idx].isDup = true
+ } else {
+ entry := fileListEntry{
+ name: dir,
+ file: nil,
+ isDir: true,
+ }
+ r.fileList = append(r.fileList, entry)
+ }
+ }
+ }
+
+ sort.Slice(r.fileList, func(i, j int) bool { return fileEntryLess(r.fileList[i].name, r.fileList[j].name) })
+ })
+}
+
+func fileEntryLess(x, y string) bool {
+ xdir, xelem, _ := split(x)
+ ydir, yelem, _ := split(y)
+ return xdir < ydir || xdir == ydir && xelem < yelem
+}
+
+// Open opens the named file in the ZIP archive,
+// using the semantics of fs.FS.Open:
+// paths are always slash separated, with no
+// leading / or ../ elements.
+func (r *Reader) Open(name string) (fs.File, error) {
+ r.initFileList()
+
+ if !fs.ValidPath(name) {
+ return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrInvalid}
+ }
+ e := r.openLookup(name)
+ if e == nil {
+ return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
+ }
+ if e.isDir {
+ return &openDir{e, r.openReadDir(name), 0}, nil
+ }
+ rc, err := e.file.Open()
+ if err != nil {
+ return nil, err
+ }
+ return rc.(fs.File), nil
+}
+
+func split(name string) (dir, elem string, isDir bool) {
+ if len(name) > 0 && name[len(name)-1] == '/' {
+ isDir = true
+ name = name[:len(name)-1]
+ }
+ i := len(name) - 1
+ for i >= 0 && name[i] != '/' {
+ i--
+ }
+ if i < 0 {
+ return ".", name, isDir
+ }
+ return name[:i], name[i+1:], isDir
+}
+
+var dotFile = &fileListEntry{name: "./", isDir: true}
+
+func (r *Reader) openLookup(name string) *fileListEntry {
+ if name == "." {
+ return dotFile
+ }
+
+ dir, elem, _ := split(name)
+ files := r.fileList
+ i := sort.Search(len(files), func(i int) bool {
+ idir, ielem, _ := split(files[i].name)
+ return idir > dir || idir == dir && ielem >= elem
+ })
+ if i < len(files) {
+ fname := files[i].name
+ if fname == name || len(fname) == len(name)+1 && fname[len(name)] == '/' && fname[:len(name)] == name {
+ return &files[i]
+ }
+ }
+ return nil
+}
+
+func (r *Reader) openReadDir(dir string) []fileListEntry {
+ files := r.fileList
+ i := sort.Search(len(files), func(i int) bool {
+ idir, _, _ := split(files[i].name)
+ return idir >= dir
+ })
+ j := sort.Search(len(files), func(j int) bool {
+ jdir, _, _ := split(files[j].name)
+ return jdir > dir
+ })
+ return files[i:j]
+}
+
+type openDir struct {
+ e *fileListEntry
+ files []fileListEntry
+ offset int
+}
+
+func (d *openDir) Close() error { return nil }
+func (d *openDir) Stat() (fs.FileInfo, error) { return d.e.stat() }
+
+func (d *openDir) Read([]byte) (int, error) {
+ return 0, &fs.PathError{Op: "read", Path: d.e.name, Err: errors.New("is a directory")}
+}
+
+func (d *openDir) ReadDir(count int) ([]fs.DirEntry, error) {
+ n := len(d.files) - d.offset
+ if count > 0 && n > count {
+ n = count
+ }
+ if n == 0 {
+ if count <= 0 {
+ return nil, nil
+ }
+ return nil, io.EOF
+ }
+ list := make([]fs.DirEntry, n)
+ for i := range list {
+ s, err := d.files[d.offset+i].stat()
+ if err != nil {
+ return nil, err
+ }
+ list[i] = s
+ }
+ d.offset += n
+ return list, nil
+}
diff --git a/contrib/go/_std_1.20/src/archive/zip/register.go b/contrib/go/_std_1.21/src/archive/zip/register.go
index 4389246286..4389246286 100644
--- a/contrib/go/_std_1.20/src/archive/zip/register.go
+++ b/contrib/go/_std_1.21/src/archive/zip/register.go
diff --git a/contrib/go/_std_1.21/src/archive/zip/struct.go b/contrib/go/_std_1.21/src/archive/zip/struct.go
new file mode 100644
index 0000000000..9a8e67cc69
--- /dev/null
+++ b/contrib/go/_std_1.21/src/archive/zip/struct.go
@@ -0,0 +1,419 @@
+// Copyright 2010 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 zip provides support for reading and writing ZIP archives.
+
+See the [ZIP specification] for details.
+
+This package does not support disk spanning.
+
+A note about ZIP64:
+
+To be backwards compatible the FileHeader has both 32 and 64 bit Size
+fields. The 64 bit fields will always contain the correct value and
+for normal archives both fields will be the same. For files requiring
+the ZIP64 format the 32 bit fields will be 0xffffffff and the 64 bit
+fields must be used instead.
+
+[ZIP specification]: https://www.pkware.com/appnote
+*/
+package zip
+
+import (
+ "io/fs"
+ "path"
+ "time"
+)
+
+// Compression methods.
+const (
+ Store uint16 = 0 // no compression
+ Deflate uint16 = 8 // DEFLATE compressed
+)
+
+const (
+ fileHeaderSignature = 0x04034b50
+ directoryHeaderSignature = 0x02014b50
+ directoryEndSignature = 0x06054b50
+ directory64LocSignature = 0x07064b50
+ directory64EndSignature = 0x06064b50
+ dataDescriptorSignature = 0x08074b50 // de-facto standard; required by OS X Finder
+ fileHeaderLen = 30 // + filename + extra
+ directoryHeaderLen = 46 // + filename + extra + comment
+ directoryEndLen = 22 // + comment
+ dataDescriptorLen = 16 // four uint32: descriptor signature, crc32, compressed size, size
+ dataDescriptor64Len = 24 // two uint32: signature, crc32 | two uint64: compressed size, size
+ directory64LocLen = 20 //
+ directory64EndLen = 56 // + extra
+
+ // Constants for the first byte in CreatorVersion.
+ creatorFAT = 0
+ creatorUnix = 3
+ creatorNTFS = 11
+ creatorVFAT = 14
+ creatorMacOSX = 19
+
+ // Version numbers.
+ zipVersion20 = 20 // 2.0
+ zipVersion45 = 45 // 4.5 (reads and writes zip64 archives)
+
+ // Limits for non zip64 files.
+ uint16max = (1 << 16) - 1
+ uint32max = (1 << 32) - 1
+
+ // Extra header IDs.
+ //
+ // IDs 0..31 are reserved for official use by PKWARE.
+ // IDs above that range are defined by third-party vendors.
+ // Since ZIP lacked high precision timestamps (nor an official specification
+ // of the timezone used for the date fields), many competing extra fields
+ // have been invented. Pervasive use effectively makes them "official".
+ //
+ // See http://mdfs.net/Docs/Comp/Archiving/Zip/ExtraField
+ zip64ExtraID = 0x0001 // Zip64 extended information
+ ntfsExtraID = 0x000a // NTFS
+ unixExtraID = 0x000d // UNIX
+ extTimeExtraID = 0x5455 // Extended timestamp
+ infoZipUnixExtraID = 0x5855 // Info-ZIP Unix extension
+)
+
+// FileHeader describes a file within a ZIP file.
+// See the [ZIP specification] for details.
+//
+// [ZIP specification]: https://www.pkware.com/appnote
+type FileHeader struct {
+ // Name is the name of the file.
+ //
+ // It must be a relative path, not start with a drive letter (such as "C:"),
+ // and must use forward slashes instead of back slashes. A trailing slash
+ // indicates that this file is a directory and should have no data.
+ Name string
+
+ // Comment is any arbitrary user-defined string shorter than 64KiB.
+ Comment string
+
+ // NonUTF8 indicates that Name and Comment are not encoded in UTF-8.
+ //
+ // By specification, the only other encoding permitted should be CP-437,
+ // but historically many ZIP readers interpret Name and Comment as whatever
+ // the system's local character encoding happens to be.
+ //
+ // This flag should only be set if the user intends to encode a non-portable
+ // ZIP file for a specific localized region. Otherwise, the Writer
+ // automatically sets the ZIP format's UTF-8 flag for valid UTF-8 strings.
+ NonUTF8 bool
+
+ CreatorVersion uint16
+ ReaderVersion uint16
+ Flags uint16
+
+ // Method is the compression method. If zero, Store is used.
+ Method uint16
+
+ // Modified is the modified time of the file.
+ //
+ // When reading, an extended timestamp is preferred over the legacy MS-DOS
+ // date field, and the offset between the times is used as the timezone.
+ // If only the MS-DOS date is present, the timezone is assumed to be UTC.
+ //
+ // When writing, an extended timestamp (which is timezone-agnostic) is
+ // always emitted. The legacy MS-DOS date field is encoded according to the
+ // location of the Modified time.
+ Modified time.Time
+
+ // ModifiedTime is an MS-DOS-encoded time.
+ //
+ // Deprecated: Use Modified instead.
+ ModifiedTime uint16
+
+ // ModifiedDate is an MS-DOS-encoded date.
+ //
+ // Deprecated: Use Modified instead.
+ ModifiedDate uint16
+
+ // CRC32 is the CRC32 checksum of the file content.
+ CRC32 uint32
+
+ // CompressedSize is the compressed size of the file in bytes.
+ // If either the uncompressed or compressed size of the file
+ // does not fit in 32 bits, CompressedSize is set to ^uint32(0).
+ //
+ // Deprecated: Use CompressedSize64 instead.
+ CompressedSize uint32
+
+ // UncompressedSize is the compressed size of the file in bytes.
+ // If either the uncompressed or compressed size of the file
+ // does not fit in 32 bits, CompressedSize is set to ^uint32(0).
+ //
+ // Deprecated: Use UncompressedSize64 instead.
+ UncompressedSize uint32
+
+ // CompressedSize64 is the compressed size of the file in bytes.
+ CompressedSize64 uint64
+
+ // UncompressedSize64 is the uncompressed size of the file in bytes.
+ UncompressedSize64 uint64
+
+ Extra []byte
+ ExternalAttrs uint32 // Meaning depends on CreatorVersion
+}
+
+// FileInfo returns an fs.FileInfo for the FileHeader.
+func (h *FileHeader) FileInfo() fs.FileInfo {
+ return headerFileInfo{h}
+}
+
+// headerFileInfo implements fs.FileInfo.
+type headerFileInfo struct {
+ fh *FileHeader
+}
+
+func (fi headerFileInfo) Name() string { return path.Base(fi.fh.Name) }
+func (fi headerFileInfo) Size() int64 {
+ if fi.fh.UncompressedSize64 > 0 {
+ return int64(fi.fh.UncompressedSize64)
+ }
+ return int64(fi.fh.UncompressedSize)
+}
+func (fi headerFileInfo) IsDir() bool { return fi.Mode().IsDir() }
+func (fi headerFileInfo) ModTime() time.Time {
+ if fi.fh.Modified.IsZero() {
+ return fi.fh.ModTime()
+ }
+ return fi.fh.Modified.UTC()
+}
+func (fi headerFileInfo) Mode() fs.FileMode { return fi.fh.Mode() }
+func (fi headerFileInfo) Type() fs.FileMode { return fi.fh.Mode().Type() }
+func (fi headerFileInfo) Sys() any { return fi.fh }
+
+func (fi headerFileInfo) Info() (fs.FileInfo, error) { return fi, nil }
+
+func (fi headerFileInfo) String() string {
+ return fs.FormatFileInfo(fi)
+}
+
+// FileInfoHeader creates a partially-populated FileHeader from an
+// fs.FileInfo.
+// Because fs.FileInfo's Name method returns only the base name of
+// the file it describes, it may be necessary to modify the Name field
+// of the returned header to provide the full path name of the file.
+// If compression is desired, callers should set the FileHeader.Method
+// field; it is unset by default.
+func FileInfoHeader(fi fs.FileInfo) (*FileHeader, error) {
+ size := fi.Size()
+ fh := &FileHeader{
+ Name: fi.Name(),
+ UncompressedSize64: uint64(size),
+ }
+ fh.SetModTime(fi.ModTime())
+ fh.SetMode(fi.Mode())
+ if fh.UncompressedSize64 > uint32max {
+ fh.UncompressedSize = uint32max
+ } else {
+ fh.UncompressedSize = uint32(fh.UncompressedSize64)
+ }
+ return fh, nil
+}
+
+type directoryEnd struct {
+ diskNbr uint32 // unused
+ dirDiskNbr uint32 // unused
+ dirRecordsThisDisk uint64 // unused
+ directoryRecords uint64
+ directorySize uint64
+ directoryOffset uint64 // relative to file
+ commentLen uint16
+ comment string
+}
+
+// timeZone returns a *time.Location based on the provided offset.
+// If the offset is non-sensible, then this uses an offset of zero.
+func timeZone(offset time.Duration) *time.Location {
+ const (
+ minOffset = -12 * time.Hour // E.g., Baker island at -12:00
+ maxOffset = +14 * time.Hour // E.g., Line island at +14:00
+ offsetAlias = 15 * time.Minute // E.g., Nepal at +5:45
+ )
+ offset = offset.Round(offsetAlias)
+ if offset < minOffset || maxOffset < offset {
+ offset = 0
+ }
+ return time.FixedZone("", int(offset/time.Second))
+}
+
+// msDosTimeToTime converts an MS-DOS date and time into a time.Time.
+// The resolution is 2s.
+// See: https://msdn.microsoft.com/en-us/library/ms724247(v=VS.85).aspx
+func msDosTimeToTime(dosDate, dosTime uint16) time.Time {
+ return time.Date(
+ // date bits 0-4: day of month; 5-8: month; 9-15: years since 1980
+ int(dosDate>>9+1980),
+ time.Month(dosDate>>5&0xf),
+ int(dosDate&0x1f),
+
+ // time bits 0-4: second/2; 5-10: minute; 11-15: hour
+ int(dosTime>>11),
+ int(dosTime>>5&0x3f),
+ int(dosTime&0x1f*2),
+ 0, // nanoseconds
+
+ time.UTC,
+ )
+}
+
+// timeToMsDosTime converts a time.Time to an MS-DOS date and time.
+// The resolution is 2s.
+// See: https://msdn.microsoft.com/en-us/library/ms724274(v=VS.85).aspx
+func timeToMsDosTime(t time.Time) (fDate uint16, fTime uint16) {
+ fDate = uint16(t.Day() + int(t.Month())<<5 + (t.Year()-1980)<<9)
+ fTime = uint16(t.Second()/2 + t.Minute()<<5 + t.Hour()<<11)
+ return
+}
+
+// ModTime returns the modification time in UTC using the legacy
+// ModifiedDate and ModifiedTime fields.
+//
+// Deprecated: Use Modified instead.
+func (h *FileHeader) ModTime() time.Time {
+ return msDosTimeToTime(h.ModifiedDate, h.ModifiedTime)
+}
+
+// SetModTime sets the Modified, ModifiedTime, and ModifiedDate fields
+// to the given time in UTC.
+//
+// Deprecated: Use Modified instead.
+func (h *FileHeader) SetModTime(t time.Time) {
+ t = t.UTC() // Convert to UTC for compatibility
+ h.Modified = t
+ h.ModifiedDate, h.ModifiedTime = timeToMsDosTime(t)
+}
+
+const (
+ // Unix constants. The specification doesn't mention them,
+ // but these seem to be the values agreed on by tools.
+ s_IFMT = 0xf000
+ s_IFSOCK = 0xc000
+ s_IFLNK = 0xa000
+ s_IFREG = 0x8000
+ s_IFBLK = 0x6000
+ s_IFDIR = 0x4000
+ s_IFCHR = 0x2000
+ s_IFIFO = 0x1000
+ s_ISUID = 0x800
+ s_ISGID = 0x400
+ s_ISVTX = 0x200
+
+ msdosDir = 0x10
+ msdosReadOnly = 0x01
+)
+
+// Mode returns the permission and mode bits for the FileHeader.
+func (h *FileHeader) Mode() (mode fs.FileMode) {
+ switch h.CreatorVersion >> 8 {
+ case creatorUnix, creatorMacOSX:
+ mode = unixModeToFileMode(h.ExternalAttrs >> 16)
+ case creatorNTFS, creatorVFAT, creatorFAT:
+ mode = msdosModeToFileMode(h.ExternalAttrs)
+ }
+ if len(h.Name) > 0 && h.Name[len(h.Name)-1] == '/' {
+ mode |= fs.ModeDir
+ }
+ return mode
+}
+
+// SetMode changes the permission and mode bits for the FileHeader.
+func (h *FileHeader) SetMode(mode fs.FileMode) {
+ h.CreatorVersion = h.CreatorVersion&0xff | creatorUnix<<8
+ h.ExternalAttrs = fileModeToUnixMode(mode) << 16
+
+ // set MSDOS attributes too, as the original zip does.
+ if mode&fs.ModeDir != 0 {
+ h.ExternalAttrs |= msdosDir
+ }
+ if mode&0200 == 0 {
+ h.ExternalAttrs |= msdosReadOnly
+ }
+}
+
+// isZip64 reports whether the file size exceeds the 32 bit limit
+func (h *FileHeader) isZip64() bool {
+ return h.CompressedSize64 >= uint32max || h.UncompressedSize64 >= uint32max
+}
+
+func (h *FileHeader) hasDataDescriptor() bool {
+ return h.Flags&0x8 != 0
+}
+
+func msdosModeToFileMode(m uint32) (mode fs.FileMode) {
+ if m&msdosDir != 0 {
+ mode = fs.ModeDir | 0777
+ } else {
+ mode = 0666
+ }
+ if m&msdosReadOnly != 0 {
+ mode &^= 0222
+ }
+ return mode
+}
+
+func fileModeToUnixMode(mode fs.FileMode) uint32 {
+ var m uint32
+ switch mode & fs.ModeType {
+ default:
+ m = s_IFREG
+ case fs.ModeDir:
+ m = s_IFDIR
+ case fs.ModeSymlink:
+ m = s_IFLNK
+ case fs.ModeNamedPipe:
+ m = s_IFIFO
+ case fs.ModeSocket:
+ m = s_IFSOCK
+ case fs.ModeDevice:
+ m = s_IFBLK
+ case fs.ModeDevice | fs.ModeCharDevice:
+ m = s_IFCHR
+ }
+ if mode&fs.ModeSetuid != 0 {
+ m |= s_ISUID
+ }
+ if mode&fs.ModeSetgid != 0 {
+ m |= s_ISGID
+ }
+ if mode&fs.ModeSticky != 0 {
+ m |= s_ISVTX
+ }
+ return m | uint32(mode&0777)
+}
+
+func unixModeToFileMode(m uint32) fs.FileMode {
+ mode := fs.FileMode(m & 0777)
+ switch m & s_IFMT {
+ case s_IFBLK:
+ mode |= fs.ModeDevice
+ case s_IFCHR:
+ mode |= fs.ModeDevice | fs.ModeCharDevice
+ case s_IFDIR:
+ mode |= fs.ModeDir
+ case s_IFIFO:
+ mode |= fs.ModeNamedPipe
+ case s_IFLNK:
+ mode |= fs.ModeSymlink
+ case s_IFREG:
+ // nothing to do
+ case s_IFSOCK:
+ mode |= fs.ModeSocket
+ }
+ if m&s_ISGID != 0 {
+ mode |= fs.ModeSetgid
+ }
+ if m&s_ISUID != 0 {
+ mode |= fs.ModeSetuid
+ }
+ if m&s_ISVTX != 0 {
+ mode |= fs.ModeSticky
+ }
+ return mode
+}
diff --git a/contrib/go/_std_1.20/src/archive/zip/writer.go b/contrib/go/_std_1.21/src/archive/zip/writer.go
index 3b23cc3391..3b23cc3391 100644
--- a/contrib/go/_std_1.20/src/archive/zip/writer.go
+++ b/contrib/go/_std_1.21/src/archive/zip/writer.go
diff --git a/contrib/go/_std_1.21/src/archive/zip/ya.make b/contrib/go/_std_1.21/src/archive/zip/ya.make
new file mode 100644
index 0000000000..bd1ac428a5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/archive/zip/ya.make
@@ -0,0 +1,22 @@
+GO_LIBRARY()
+
+SRCS(
+ reader.go
+ register.go
+ struct.go
+ writer.go
+)
+
+GO_TEST_SRCS(
+ fuzz_test.go
+ reader_test.go
+ writer_test.go
+ zip_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/bufio/bufio.go b/contrib/go/_std_1.21/src/bufio/bufio.go
new file mode 100644
index 0000000000..8469b9eff7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/bufio/bufio.go
@@ -0,0 +1,842 @@
+// Copyright 2009 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 bufio implements buffered I/O. It wraps an io.Reader or io.Writer
+// object, creating another object (Reader or Writer) that also implements
+// the interface but provides buffering and some help for textual I/O.
+package bufio
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "strings"
+ "unicode/utf8"
+)
+
+const (
+ defaultBufSize = 4096
+)
+
+var (
+ ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte")
+ ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune")
+ ErrBufferFull = errors.New("bufio: buffer full")
+ ErrNegativeCount = errors.New("bufio: negative count")
+)
+
+// Buffered input.
+
+// Reader implements buffering for an io.Reader object.
+type Reader struct {
+ buf []byte
+ rd io.Reader // reader provided by the client
+ r, w int // buf read and write positions
+ err error
+ lastByte int // last byte read for UnreadByte; -1 means invalid
+ lastRuneSize int // size of last rune read for UnreadRune; -1 means invalid
+}
+
+const minReadBufferSize = 16
+const maxConsecutiveEmptyReads = 100
+
+// NewReaderSize returns a new Reader whose buffer has at least the specified
+// size. If the argument io.Reader is already a Reader with large enough
+// size, it returns the underlying Reader.
+func NewReaderSize(rd io.Reader, size int) *Reader {
+ // Is it already a Reader?
+ b, ok := rd.(*Reader)
+ if ok && len(b.buf) >= size {
+ return b
+ }
+ if size < minReadBufferSize {
+ size = minReadBufferSize
+ }
+ r := new(Reader)
+ r.reset(make([]byte, size), rd)
+ return r
+}
+
+// NewReader returns a new Reader whose buffer has the default size.
+func NewReader(rd io.Reader) *Reader {
+ return NewReaderSize(rd, defaultBufSize)
+}
+
+// Size returns the size of the underlying buffer in bytes.
+func (b *Reader) Size() int { return len(b.buf) }
+
+// Reset discards any buffered data, resets all state, and switches
+// the buffered reader to read from r.
+// Calling Reset on the zero value of Reader initializes the internal buffer
+// to the default size.
+// Calling b.Reset(b) (that is, resetting a Reader to itself) does nothing.
+func (b *Reader) Reset(r io.Reader) {
+ // If a Reader r is passed to NewReader, NewReader will return r.
+ // Different layers of code may do that, and then later pass r
+ // to Reset. Avoid infinite recursion in that case.
+ if b == r {
+ return
+ }
+ if b.buf == nil {
+ b.buf = make([]byte, defaultBufSize)
+ }
+ b.reset(b.buf, r)
+}
+
+func (b *Reader) reset(buf []byte, r io.Reader) {
+ *b = Reader{
+ buf: buf,
+ rd: r,
+ lastByte: -1,
+ lastRuneSize: -1,
+ }
+}
+
+var errNegativeRead = errors.New("bufio: reader returned negative count from Read")
+
+// fill reads a new chunk into the buffer.
+func (b *Reader) fill() {
+ // Slide existing data to beginning.
+ if b.r > 0 {
+ copy(b.buf, b.buf[b.r:b.w])
+ b.w -= b.r
+ b.r = 0
+ }
+
+ if b.w >= len(b.buf) {
+ panic("bufio: tried to fill full buffer")
+ }
+
+ // Read new data: try a limited number of times.
+ for i := maxConsecutiveEmptyReads; i > 0; i-- {
+ n, err := b.rd.Read(b.buf[b.w:])
+ if n < 0 {
+ panic(errNegativeRead)
+ }
+ b.w += n
+ if err != nil {
+ b.err = err
+ return
+ }
+ if n > 0 {
+ return
+ }
+ }
+ b.err = io.ErrNoProgress
+}
+
+func (b *Reader) readErr() error {
+ err := b.err
+ b.err = nil
+ return err
+}
+
+// Peek returns the next n bytes without advancing the reader. The bytes stop
+// being valid at the next read call. If Peek returns fewer than n bytes, it
+// also returns an error explaining why the read is short. The error is
+// ErrBufferFull if n is larger than b's buffer size.
+//
+// Calling Peek prevents a UnreadByte or UnreadRune call from succeeding
+// until the next read operation.
+func (b *Reader) Peek(n int) ([]byte, error) {
+ if n < 0 {
+ return nil, ErrNegativeCount
+ }
+
+ b.lastByte = -1
+ b.lastRuneSize = -1
+
+ for b.w-b.r < n && b.w-b.r < len(b.buf) && b.err == nil {
+ b.fill() // b.w-b.r < len(b.buf) => buffer is not full
+ }
+
+ if n > len(b.buf) {
+ return b.buf[b.r:b.w], ErrBufferFull
+ }
+
+ // 0 <= n <= len(b.buf)
+ var err error
+ if avail := b.w - b.r; avail < n {
+ // not enough data in buffer
+ n = avail
+ err = b.readErr()
+ if err == nil {
+ err = ErrBufferFull
+ }
+ }
+ return b.buf[b.r : b.r+n], err
+}
+
+// Discard skips the next n bytes, returning the number of bytes discarded.
+//
+// If Discard skips fewer than n bytes, it also returns an error.
+// If 0 <= n <= b.Buffered(), Discard is guaranteed to succeed without
+// reading from the underlying io.Reader.
+func (b *Reader) Discard(n int) (discarded int, err error) {
+ if n < 0 {
+ return 0, ErrNegativeCount
+ }
+ if n == 0 {
+ return
+ }
+
+ b.lastByte = -1
+ b.lastRuneSize = -1
+
+ remain := n
+ for {
+ skip := b.Buffered()
+ if skip == 0 {
+ b.fill()
+ skip = b.Buffered()
+ }
+ if skip > remain {
+ skip = remain
+ }
+ b.r += skip
+ remain -= skip
+ if remain == 0 {
+ return n, nil
+ }
+ if b.err != nil {
+ return n - remain, b.readErr()
+ }
+ }
+}
+
+// Read reads data into p.
+// It returns the number of bytes read into p.
+// The bytes are taken from at most one Read on the underlying Reader,
+// hence n may be less than len(p).
+// To read exactly len(p) bytes, use io.ReadFull(b, p).
+// If the underlying Reader can return a non-zero count with io.EOF,
+// then this Read method can do so as well; see the [io.Reader] docs.
+func (b *Reader) Read(p []byte) (n int, err error) {
+ n = len(p)
+ if n == 0 {
+ if b.Buffered() > 0 {
+ return 0, nil
+ }
+ return 0, b.readErr()
+ }
+ if b.r == b.w {
+ if b.err != nil {
+ return 0, b.readErr()
+ }
+ if len(p) >= len(b.buf) {
+ // Large read, empty buffer.
+ // Read directly into p to avoid copy.
+ n, b.err = b.rd.Read(p)
+ if n < 0 {
+ panic(errNegativeRead)
+ }
+ if n > 0 {
+ b.lastByte = int(p[n-1])
+ b.lastRuneSize = -1
+ }
+ return n, b.readErr()
+ }
+ // One read.
+ // Do not use b.fill, which will loop.
+ b.r = 0
+ b.w = 0
+ n, b.err = b.rd.Read(b.buf)
+ if n < 0 {
+ panic(errNegativeRead)
+ }
+ if n == 0 {
+ return 0, b.readErr()
+ }
+ b.w += n
+ }
+
+ // copy as much as we can
+ // Note: if the slice panics here, it is probably because
+ // the underlying reader returned a bad count. See issue 49795.
+ n = copy(p, b.buf[b.r:b.w])
+ b.r += n
+ b.lastByte = int(b.buf[b.r-1])
+ b.lastRuneSize = -1
+ return n, nil
+}
+
+// ReadByte reads and returns a single byte.
+// If no byte is available, returns an error.
+func (b *Reader) ReadByte() (byte, error) {
+ b.lastRuneSize = -1
+ for b.r == b.w {
+ if b.err != nil {
+ return 0, b.readErr()
+ }
+ b.fill() // buffer is empty
+ }
+ c := b.buf[b.r]
+ b.r++
+ b.lastByte = int(c)
+ return c, nil
+}
+
+// UnreadByte unreads the last byte. Only the most recently read byte can be unread.
+//
+// UnreadByte returns an error if the most recent method called on the
+// Reader was not a read operation. Notably, Peek, Discard, and WriteTo are not
+// considered read operations.
+func (b *Reader) UnreadByte() error {
+ if b.lastByte < 0 || b.r == 0 && b.w > 0 {
+ return ErrInvalidUnreadByte
+ }
+ // b.r > 0 || b.w == 0
+ if b.r > 0 {
+ b.r--
+ } else {
+ // b.r == 0 && b.w == 0
+ b.w = 1
+ }
+ b.buf[b.r] = byte(b.lastByte)
+ b.lastByte = -1
+ b.lastRuneSize = -1
+ return nil
+}
+
+// ReadRune reads a single UTF-8 encoded Unicode character and returns the
+// rune and its size in bytes. If the encoded rune is invalid, it consumes one byte
+// and returns unicode.ReplacementChar (U+FFFD) with a size of 1.
+func (b *Reader) ReadRune() (r rune, size int, err error) {
+ for b.r+utf8.UTFMax > b.w && !utf8.FullRune(b.buf[b.r:b.w]) && b.err == nil && b.w-b.r < len(b.buf) {
+ b.fill() // b.w-b.r < len(buf) => buffer is not full
+ }
+ b.lastRuneSize = -1
+ if b.r == b.w {
+ return 0, 0, b.readErr()
+ }
+ r, size = rune(b.buf[b.r]), 1
+ if r >= utf8.RuneSelf {
+ r, size = utf8.DecodeRune(b.buf[b.r:b.w])
+ }
+ b.r += size
+ b.lastByte = int(b.buf[b.r-1])
+ b.lastRuneSize = size
+ return r, size, nil
+}
+
+// UnreadRune unreads the last rune. If the most recent method called on
+// the Reader was not a ReadRune, UnreadRune returns an error. (In this
+// regard it is stricter than UnreadByte, which will unread the last byte
+// from any read operation.)
+func (b *Reader) UnreadRune() error {
+ if b.lastRuneSize < 0 || b.r < b.lastRuneSize {
+ return ErrInvalidUnreadRune
+ }
+ b.r -= b.lastRuneSize
+ b.lastByte = -1
+ b.lastRuneSize = -1
+ return nil
+}
+
+// Buffered returns the number of bytes that can be read from the current buffer.
+func (b *Reader) Buffered() int { return b.w - b.r }
+
+// ReadSlice reads until the first occurrence of delim in the input,
+// returning a slice pointing at the bytes in the buffer.
+// The bytes stop being valid at the next read.
+// If ReadSlice encounters an error before finding a delimiter,
+// it returns all the data in the buffer and the error itself (often io.EOF).
+// ReadSlice fails with error ErrBufferFull if the buffer fills without a delim.
+// Because the data returned from ReadSlice will be overwritten
+// by the next I/O operation, most clients should use
+// ReadBytes or ReadString instead.
+// ReadSlice returns err != nil if and only if line does not end in delim.
+func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
+ s := 0 // search start index
+ for {
+ // Search buffer.
+ if i := bytes.IndexByte(b.buf[b.r+s:b.w], delim); i >= 0 {
+ i += s
+ line = b.buf[b.r : b.r+i+1]
+ b.r += i + 1
+ break
+ }
+
+ // Pending error?
+ if b.err != nil {
+ line = b.buf[b.r:b.w]
+ b.r = b.w
+ err = b.readErr()
+ break
+ }
+
+ // Buffer full?
+ if b.Buffered() >= len(b.buf) {
+ b.r = b.w
+ line = b.buf
+ err = ErrBufferFull
+ break
+ }
+
+ s = b.w - b.r // do not rescan area we scanned before
+
+ b.fill() // buffer is not full
+ }
+
+ // Handle last byte, if any.
+ if i := len(line) - 1; i >= 0 {
+ b.lastByte = int(line[i])
+ b.lastRuneSize = -1
+ }
+
+ return
+}
+
+// ReadLine is a low-level line-reading primitive. Most callers should use
+// ReadBytes('\n') or ReadString('\n') instead or use a Scanner.
+//
+// ReadLine tries to return a single line, not including the end-of-line bytes.
+// If the line was too long for the buffer then isPrefix is set and the
+// beginning of the line is returned. The rest of the line will be returned
+// from future calls. isPrefix will be false when returning the last fragment
+// of the line. The returned buffer is only valid until the next call to
+// ReadLine. ReadLine either returns a non-nil line or it returns an error,
+// never both.
+//
+// The text returned from ReadLine does not include the line end ("\r\n" or "\n").
+// No indication or error is given if the input ends without a final line end.
+// Calling UnreadByte after ReadLine will always unread the last byte read
+// (possibly a character belonging to the line end) even if that byte is not
+// part of the line returned by ReadLine.
+func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) {
+ line, err = b.ReadSlice('\n')
+ if err == ErrBufferFull {
+ // Handle the case where "\r\n" straddles the buffer.
+ if len(line) > 0 && line[len(line)-1] == '\r' {
+ // Put the '\r' back on buf and drop it from line.
+ // Let the next call to ReadLine check for "\r\n".
+ if b.r == 0 {
+ // should be unreachable
+ panic("bufio: tried to rewind past start of buffer")
+ }
+ b.r--
+ line = line[:len(line)-1]
+ }
+ return line, true, nil
+ }
+
+ if len(line) == 0 {
+ if err != nil {
+ line = nil
+ }
+ return
+ }
+ err = nil
+
+ if line[len(line)-1] == '\n' {
+ drop := 1
+ if len(line) > 1 && line[len(line)-2] == '\r' {
+ drop = 2
+ }
+ line = line[:len(line)-drop]
+ }
+ return
+}
+
+// collectFragments reads until the first occurrence of delim in the input. It
+// returns (slice of full buffers, remaining bytes before delim, total number
+// of bytes in the combined first two elements, error).
+// The complete result is equal to
+// `bytes.Join(append(fullBuffers, finalFragment), nil)`, which has a
+// length of `totalLen`. The result is structured in this way to allow callers
+// to minimize allocations and copies.
+func (b *Reader) collectFragments(delim byte) (fullBuffers [][]byte, finalFragment []byte, totalLen int, err error) {
+ var frag []byte
+ // Use ReadSlice to look for delim, accumulating full buffers.
+ for {
+ var e error
+ frag, e = b.ReadSlice(delim)
+ if e == nil { // got final fragment
+ break
+ }
+ if e != ErrBufferFull { // unexpected error
+ err = e
+ break
+ }
+
+ // Make a copy of the buffer.
+ buf := bytes.Clone(frag)
+ fullBuffers = append(fullBuffers, buf)
+ totalLen += len(buf)
+ }
+
+ totalLen += len(frag)
+ return fullBuffers, frag, totalLen, err
+}
+
+// ReadBytes reads until the first occurrence of delim in the input,
+// returning a slice containing the data up to and including the delimiter.
+// If ReadBytes encounters an error before finding a delimiter,
+// it returns the data read before the error and the error itself (often io.EOF).
+// ReadBytes returns err != nil if and only if the returned data does not end in
+// delim.
+// For simple uses, a Scanner may be more convenient.
+func (b *Reader) ReadBytes(delim byte) ([]byte, error) {
+ full, frag, n, err := b.collectFragments(delim)
+ // Allocate new buffer to hold the full pieces and the fragment.
+ buf := make([]byte, n)
+ n = 0
+ // Copy full pieces and fragment in.
+ for i := range full {
+ n += copy(buf[n:], full[i])
+ }
+ copy(buf[n:], frag)
+ return buf, err
+}
+
+// ReadString reads until the first occurrence of delim in the input,
+// returning a string containing the data up to and including the delimiter.
+// If ReadString encounters an error before finding a delimiter,
+// it returns the data read before the error and the error itself (often io.EOF).
+// ReadString returns err != nil if and only if the returned data does not end in
+// delim.
+// For simple uses, a Scanner may be more convenient.
+func (b *Reader) ReadString(delim byte) (string, error) {
+ full, frag, n, err := b.collectFragments(delim)
+ // Allocate new buffer to hold the full pieces and the fragment.
+ var buf strings.Builder
+ buf.Grow(n)
+ // Copy full pieces and fragment in.
+ for _, fb := range full {
+ buf.Write(fb)
+ }
+ buf.Write(frag)
+ return buf.String(), err
+}
+
+// WriteTo implements io.WriterTo.
+// This may make multiple calls to the Read method of the underlying Reader.
+// If the underlying reader supports the WriteTo method,
+// this calls the underlying WriteTo without buffering.
+func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
+ b.lastByte = -1
+ b.lastRuneSize = -1
+
+ n, err = b.writeBuf(w)
+ if err != nil {
+ return
+ }
+
+ if r, ok := b.rd.(io.WriterTo); ok {
+ m, err := r.WriteTo(w)
+ n += m
+ return n, err
+ }
+
+ if w, ok := w.(io.ReaderFrom); ok {
+ m, err := w.ReadFrom(b.rd)
+ n += m
+ return n, err
+ }
+
+ if b.w-b.r < len(b.buf) {
+ b.fill() // buffer not full
+ }
+
+ for b.r < b.w {
+ // b.r < b.w => buffer is not empty
+ m, err := b.writeBuf(w)
+ n += m
+ if err != nil {
+ return n, err
+ }
+ b.fill() // buffer is empty
+ }
+
+ if b.err == io.EOF {
+ b.err = nil
+ }
+
+ return n, b.readErr()
+}
+
+var errNegativeWrite = errors.New("bufio: writer returned negative count from Write")
+
+// writeBuf writes the Reader's buffer to the writer.
+func (b *Reader) writeBuf(w io.Writer) (int64, error) {
+ n, err := w.Write(b.buf[b.r:b.w])
+ if n < 0 {
+ panic(errNegativeWrite)
+ }
+ b.r += n
+ return int64(n), err
+}
+
+// buffered output
+
+// Writer implements buffering for an io.Writer object.
+// If an error occurs writing to a Writer, no more data will be
+// accepted and all subsequent writes, and Flush, will return the error.
+// After all data has been written, the client should call the
+// Flush method to guarantee all data has been forwarded to
+// the underlying io.Writer.
+type Writer struct {
+ err error
+ buf []byte
+ n int
+ wr io.Writer
+}
+
+// NewWriterSize returns a new Writer whose buffer has at least the specified
+// size. If the argument io.Writer is already a Writer with large enough
+// size, it returns the underlying Writer.
+func NewWriterSize(w io.Writer, size int) *Writer {
+ // Is it already a Writer?
+ b, ok := w.(*Writer)
+ if ok && len(b.buf) >= size {
+ return b
+ }
+ if size <= 0 {
+ size = defaultBufSize
+ }
+ return &Writer{
+ buf: make([]byte, size),
+ wr: w,
+ }
+}
+
+// NewWriter returns a new Writer whose buffer has the default size.
+// If the argument io.Writer is already a Writer with large enough buffer size,
+// it returns the underlying Writer.
+func NewWriter(w io.Writer) *Writer {
+ return NewWriterSize(w, defaultBufSize)
+}
+
+// Size returns the size of the underlying buffer in bytes.
+func (b *Writer) Size() int { return len(b.buf) }
+
+// Reset discards any unflushed buffered data, clears any error, and
+// resets b to write its output to w.
+// Calling Reset on the zero value of Writer initializes the internal buffer
+// to the default size.
+// Calling w.Reset(w) (that is, resetting a Writer to itself) does nothing.
+func (b *Writer) Reset(w io.Writer) {
+ // If a Writer w is passed to NewWriter, NewWriter will return w.
+ // Different layers of code may do that, and then later pass w
+ // to Reset. Avoid infinite recursion in that case.
+ if b == w {
+ return
+ }
+ if b.buf == nil {
+ b.buf = make([]byte, defaultBufSize)
+ }
+ b.err = nil
+ b.n = 0
+ b.wr = w
+}
+
+// Flush writes any buffered data to the underlying io.Writer.
+func (b *Writer) Flush() error {
+ if b.err != nil {
+ return b.err
+ }
+ if b.n == 0 {
+ return nil
+ }
+ n, err := b.wr.Write(b.buf[0:b.n])
+ if n < b.n && err == nil {
+ err = io.ErrShortWrite
+ }
+ if err != nil {
+ if n > 0 && n < b.n {
+ copy(b.buf[0:b.n-n], b.buf[n:b.n])
+ }
+ b.n -= n
+ b.err = err
+ return err
+ }
+ b.n = 0
+ return nil
+}
+
+// Available returns how many bytes are unused in the buffer.
+func (b *Writer) Available() int { return len(b.buf) - b.n }
+
+// AvailableBuffer returns an empty buffer with b.Available() capacity.
+// This buffer is intended to be appended to and
+// passed to an immediately succeeding Write call.
+// The buffer is only valid until the next write operation on b.
+func (b *Writer) AvailableBuffer() []byte {
+ return b.buf[b.n:][:0]
+}
+
+// Buffered returns the number of bytes that have been written into the current buffer.
+func (b *Writer) Buffered() int { return b.n }
+
+// Write writes the contents of p into the buffer.
+// It returns the number of bytes written.
+// If nn < len(p), it also returns an error explaining
+// why the write is short.
+func (b *Writer) Write(p []byte) (nn int, err error) {
+ for len(p) > b.Available() && b.err == nil {
+ var n int
+ if b.Buffered() == 0 {
+ // Large write, empty buffer.
+ // Write directly from p to avoid copy.
+ n, b.err = b.wr.Write(p)
+ } else {
+ n = copy(b.buf[b.n:], p)
+ b.n += n
+ b.Flush()
+ }
+ nn += n
+ p = p[n:]
+ }
+ if b.err != nil {
+ return nn, b.err
+ }
+ n := copy(b.buf[b.n:], p)
+ b.n += n
+ nn += n
+ return nn, nil
+}
+
+// WriteByte writes a single byte.
+func (b *Writer) WriteByte(c byte) error {
+ if b.err != nil {
+ return b.err
+ }
+ if b.Available() <= 0 && b.Flush() != nil {
+ return b.err
+ }
+ b.buf[b.n] = c
+ b.n++
+ return nil
+}
+
+// WriteRune writes a single Unicode code point, returning
+// the number of bytes written and any error.
+func (b *Writer) WriteRune(r rune) (size int, err error) {
+ // Compare as uint32 to correctly handle negative runes.
+ if uint32(r) < utf8.RuneSelf {
+ err = b.WriteByte(byte(r))
+ if err != nil {
+ return 0, err
+ }
+ return 1, nil
+ }
+ if b.err != nil {
+ return 0, b.err
+ }
+ n := b.Available()
+ if n < utf8.UTFMax {
+ if b.Flush(); b.err != nil {
+ return 0, b.err
+ }
+ n = b.Available()
+ if n < utf8.UTFMax {
+ // Can only happen if buffer is silly small.
+ return b.WriteString(string(r))
+ }
+ }
+ size = utf8.EncodeRune(b.buf[b.n:], r)
+ b.n += size
+ return size, nil
+}
+
+// WriteString writes a string.
+// It returns the number of bytes written.
+// If the count is less than len(s), it also returns an error explaining
+// why the write is short.
+func (b *Writer) WriteString(s string) (int, error) {
+ var sw io.StringWriter
+ tryStringWriter := true
+
+ nn := 0
+ for len(s) > b.Available() && b.err == nil {
+ var n int
+ if b.Buffered() == 0 && sw == nil && tryStringWriter {
+ // Check at most once whether b.wr is a StringWriter.
+ sw, tryStringWriter = b.wr.(io.StringWriter)
+ }
+ if b.Buffered() == 0 && tryStringWriter {
+ // Large write, empty buffer, and the underlying writer supports
+ // WriteString: forward the write to the underlying StringWriter.
+ // This avoids an extra copy.
+ n, b.err = sw.WriteString(s)
+ } else {
+ n = copy(b.buf[b.n:], s)
+ b.n += n
+ b.Flush()
+ }
+ nn += n
+ s = s[n:]
+ }
+ if b.err != nil {
+ return nn, b.err
+ }
+ n := copy(b.buf[b.n:], s)
+ b.n += n
+ nn += n
+ return nn, nil
+}
+
+// ReadFrom implements io.ReaderFrom. If the underlying writer
+// supports the ReadFrom method, this calls the underlying ReadFrom.
+// If there is buffered data and an underlying ReadFrom, this fills
+// the buffer and writes it before calling ReadFrom.
+func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
+ if b.err != nil {
+ return 0, b.err
+ }
+ readerFrom, readerFromOK := b.wr.(io.ReaderFrom)
+ var m int
+ for {
+ if b.Available() == 0 {
+ if err1 := b.Flush(); err1 != nil {
+ return n, err1
+ }
+ }
+ if readerFromOK && b.Buffered() == 0 {
+ nn, err := readerFrom.ReadFrom(r)
+ b.err = err
+ n += nn
+ return n, err
+ }
+ nr := 0
+ for nr < maxConsecutiveEmptyReads {
+ m, err = r.Read(b.buf[b.n:])
+ if m != 0 || err != nil {
+ break
+ }
+ nr++
+ }
+ if nr == maxConsecutiveEmptyReads {
+ return n, io.ErrNoProgress
+ }
+ b.n += m
+ n += int64(m)
+ if err != nil {
+ break
+ }
+ }
+ if err == io.EOF {
+ // If we filled the buffer exactly, flush preemptively.
+ if b.Available() == 0 {
+ err = b.Flush()
+ } else {
+ err = nil
+ }
+ }
+ return n, err
+}
+
+// buffered input and output
+
+// ReadWriter stores pointers to a Reader and a Writer.
+// It implements io.ReadWriter.
+type ReadWriter struct {
+ *Reader
+ *Writer
+}
+
+// NewReadWriter allocates a new ReadWriter that dispatches to r and w.
+func NewReadWriter(r *Reader, w *Writer) *ReadWriter {
+ return &ReadWriter{r, w}
+}
diff --git a/contrib/go/_std_1.20/src/bufio/scan.go b/contrib/go/_std_1.21/src/bufio/scan.go
index e247cbcf32..e247cbcf32 100644
--- a/contrib/go/_std_1.20/src/bufio/scan.go
+++ b/contrib/go/_std_1.21/src/bufio/scan.go
diff --git a/contrib/go/_std_1.21/src/bufio/ya.make b/contrib/go/_std_1.21/src/bufio/ya.make
new file mode 100644
index 0000000000..c934753516
--- /dev/null
+++ b/contrib/go/_std_1.21/src/bufio/ya.make
@@ -0,0 +1,19 @@
+GO_LIBRARY()
+
+SRCS(
+ bufio.go
+ scan.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ bufio_test.go
+ example_test.go
+ scan_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/bytes/buffer.go b/contrib/go/_std_1.21/src/bytes/buffer.go
new file mode 100644
index 0000000000..5a68188423
--- /dev/null
+++ b/contrib/go/_std_1.21/src/bytes/buffer.go
@@ -0,0 +1,482 @@
+// Copyright 2009 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 bytes
+
+// Simple byte buffer for marshaling data.
+
+import (
+ "errors"
+ "io"
+ "unicode/utf8"
+)
+
+// smallBufferSize is an initial allocation minimal capacity.
+const smallBufferSize = 64
+
+// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
+// The zero value for Buffer is an empty buffer ready to use.
+type Buffer struct {
+ buf []byte // contents are the bytes buf[off : len(buf)]
+ off int // read at &buf[off], write at &buf[len(buf)]
+ lastRead readOp // last read operation, so that Unread* can work correctly.
+}
+
+// The readOp constants describe the last action performed on
+// the buffer, so that UnreadRune and UnreadByte can check for
+// invalid usage. opReadRuneX constants are chosen such that
+// converted to int they correspond to the rune size that was read.
+type readOp int8
+
+// Don't use iota for these, as the values need to correspond with the
+// names and comments, which is easier to see when being explicit.
+const (
+ opRead readOp = -1 // Any other read operation.
+ opInvalid readOp = 0 // Non-read operation.
+ opReadRune1 readOp = 1 // Read rune of size 1.
+ opReadRune2 readOp = 2 // Read rune of size 2.
+ opReadRune3 readOp = 3 // Read rune of size 3.
+ opReadRune4 readOp = 4 // Read rune of size 4.
+)
+
+// ErrTooLarge is passed to panic if memory cannot be allocated to store data in a buffer.
+var ErrTooLarge = errors.New("bytes.Buffer: too large")
+var errNegativeRead = errors.New("bytes.Buffer: reader returned negative count from Read")
+
+const maxInt = int(^uint(0) >> 1)
+
+// Bytes returns a slice of length b.Len() holding the unread portion of the buffer.
+// The slice is valid for use only until the next buffer modification (that is,
+// only until the next call to a method like Read, Write, Reset, or Truncate).
+// The slice aliases the buffer content at least until the next buffer modification,
+// so immediate changes to the slice will affect the result of future reads.
+func (b *Buffer) Bytes() []byte { return b.buf[b.off:] }
+
+// AvailableBuffer returns an empty buffer with b.Available() capacity.
+// This buffer is intended to be appended to and
+// passed to an immediately succeeding Write call.
+// The buffer is only valid until the next write operation on b.
+func (b *Buffer) AvailableBuffer() []byte { return b.buf[len(b.buf):] }
+
+// String returns the contents of the unread portion of the buffer
+// as a string. If the Buffer is a nil pointer, it returns "<nil>".
+//
+// To build strings more efficiently, see the strings.Builder type.
+func (b *Buffer) String() string {
+ if b == nil {
+ // Special case, useful in debugging.
+ return "<nil>"
+ }
+ return string(b.buf[b.off:])
+}
+
+// empty reports whether the unread portion of the buffer is empty.
+func (b *Buffer) empty() bool { return len(b.buf) <= b.off }
+
+// Len returns the number of bytes of the unread portion of the buffer;
+// b.Len() == len(b.Bytes()).
+func (b *Buffer) Len() int { return len(b.buf) - b.off }
+
+// Cap returns the capacity of the buffer's underlying byte slice, that is, the
+// total space allocated for the buffer's data.
+func (b *Buffer) Cap() int { return cap(b.buf) }
+
+// Available returns how many bytes are unused in the buffer.
+func (b *Buffer) Available() int { return cap(b.buf) - len(b.buf) }
+
+// Truncate discards all but the first n unread bytes from the buffer
+// but continues to use the same allocated storage.
+// It panics if n is negative or greater than the length of the buffer.
+func (b *Buffer) Truncate(n int) {
+ if n == 0 {
+ b.Reset()
+ return
+ }
+ b.lastRead = opInvalid
+ if n < 0 || n > b.Len() {
+ panic("bytes.Buffer: truncation out of range")
+ }
+ b.buf = b.buf[:b.off+n]
+}
+
+// Reset resets the buffer to be empty,
+// but it retains the underlying storage for use by future writes.
+// Reset is the same as Truncate(0).
+func (b *Buffer) Reset() {
+ b.buf = b.buf[:0]
+ b.off = 0
+ b.lastRead = opInvalid
+}
+
+// tryGrowByReslice is an inlineable version of grow for the fast-case where the
+// internal buffer only needs to be resliced.
+// It returns the index where bytes should be written and whether it succeeded.
+func (b *Buffer) tryGrowByReslice(n int) (int, bool) {
+ if l := len(b.buf); n <= cap(b.buf)-l {
+ b.buf = b.buf[:l+n]
+ return l, true
+ }
+ return 0, false
+}
+
+// grow grows the buffer to guarantee space for n more bytes.
+// It returns the index where bytes should be written.
+// If the buffer can't grow it will panic with ErrTooLarge.
+func (b *Buffer) grow(n int) int {
+ m := b.Len()
+ // If buffer is empty, reset to recover space.
+ if m == 0 && b.off != 0 {
+ b.Reset()
+ }
+ // Try to grow by means of a reslice.
+ if i, ok := b.tryGrowByReslice(n); ok {
+ return i
+ }
+ if b.buf == nil && n <= smallBufferSize {
+ b.buf = make([]byte, n, smallBufferSize)
+ return 0
+ }
+ c := cap(b.buf)
+ if n <= c/2-m {
+ // We can slide things down instead of allocating a new
+ // slice. We only need m+n <= c to slide, but
+ // we instead let capacity get twice as large so we
+ // don't spend all our time copying.
+ copy(b.buf, b.buf[b.off:])
+ } else if c > maxInt-c-n {
+ panic(ErrTooLarge)
+ } else {
+ // Add b.off to account for b.buf[:b.off] being sliced off the front.
+ b.buf = growSlice(b.buf[b.off:], b.off+n)
+ }
+ // Restore b.off and len(b.buf).
+ b.off = 0
+ b.buf = b.buf[:m+n]
+ return m
+}
+
+// Grow grows the buffer's capacity, if necessary, to guarantee space for
+// another n bytes. After Grow(n), at least n bytes can be written to the
+// buffer without another allocation.
+// If n is negative, Grow will panic.
+// If the buffer can't grow it will panic with ErrTooLarge.
+func (b *Buffer) Grow(n int) {
+ if n < 0 {
+ panic("bytes.Buffer.Grow: negative count")
+ }
+ m := b.grow(n)
+ b.buf = b.buf[:m]
+}
+
+// Write appends the contents of p to the buffer, growing the buffer as
+// needed. The return value n is the length of p; err is always nil. If the
+// buffer becomes too large, Write will panic with ErrTooLarge.
+func (b *Buffer) Write(p []byte) (n int, err error) {
+ b.lastRead = opInvalid
+ m, ok := b.tryGrowByReslice(len(p))
+ if !ok {
+ m = b.grow(len(p))
+ }
+ return copy(b.buf[m:], p), nil
+}
+
+// WriteString appends the contents of s to the buffer, growing the buffer as
+// needed. The return value n is the length of s; err is always nil. If the
+// buffer becomes too large, WriteString will panic with ErrTooLarge.
+func (b *Buffer) WriteString(s string) (n int, err error) {
+ b.lastRead = opInvalid
+ m, ok := b.tryGrowByReslice(len(s))
+ if !ok {
+ m = b.grow(len(s))
+ }
+ return copy(b.buf[m:], s), nil
+}
+
+// MinRead is the minimum slice size passed to a Read call by
+// Buffer.ReadFrom. As long as the Buffer has at least MinRead bytes beyond
+// what is required to hold the contents of r, ReadFrom will not grow the
+// underlying buffer.
+const MinRead = 512
+
+// ReadFrom reads data from r until EOF and appends it to the buffer, growing
+// the buffer as needed. The return value n is the number of bytes read. Any
+// error except io.EOF encountered during the read is also returned. If the
+// buffer becomes too large, ReadFrom will panic with ErrTooLarge.
+func (b *Buffer) ReadFrom(r io.Reader) (n int64, err error) {
+ b.lastRead = opInvalid
+ for {
+ i := b.grow(MinRead)
+ b.buf = b.buf[:i]
+ m, e := r.Read(b.buf[i:cap(b.buf)])
+ if m < 0 {
+ panic(errNegativeRead)
+ }
+
+ b.buf = b.buf[:i+m]
+ n += int64(m)
+ if e == io.EOF {
+ return n, nil // e is EOF, so return nil explicitly
+ }
+ if e != nil {
+ return n, e
+ }
+ }
+}
+
+// growSlice grows b by n, preserving the original content of b.
+// If the allocation fails, it panics with ErrTooLarge.
+func growSlice(b []byte, n int) []byte {
+ defer func() {
+ if recover() != nil {
+ panic(ErrTooLarge)
+ }
+ }()
+ // TODO(http://golang.org/issue/51462): We should rely on the append-make
+ // pattern so that the compiler can call runtime.growslice. For example:
+ // return append(b, make([]byte, n)...)
+ // This avoids unnecessary zero-ing of the first len(b) bytes of the
+ // allocated slice, but this pattern causes b to escape onto the heap.
+ //
+ // Instead use the append-make pattern with a nil slice to ensure that
+ // we allocate buffers rounded up to the closest size class.
+ c := len(b) + n // ensure enough space for n elements
+ if c < 2*cap(b) {
+ // The growth rate has historically always been 2x. In the future,
+ // we could rely purely on append to determine the growth rate.
+ c = 2 * cap(b)
+ }
+ b2 := append([]byte(nil), make([]byte, c)...)
+ copy(b2, b)
+ return b2[:len(b)]
+}
+
+// WriteTo writes data to w until the buffer is drained or an error occurs.
+// The return value n is the number of bytes written; it always fits into an
+// int, but it is int64 to match the io.WriterTo interface. Any error
+// encountered during the write is also returned.
+func (b *Buffer) WriteTo(w io.Writer) (n int64, err error) {
+ b.lastRead = opInvalid
+ if nBytes := b.Len(); nBytes > 0 {
+ m, e := w.Write(b.buf[b.off:])
+ if m > nBytes {
+ panic("bytes.Buffer.WriteTo: invalid Write count")
+ }
+ b.off += m
+ n = int64(m)
+ if e != nil {
+ return n, e
+ }
+ // all bytes should have been written, by definition of
+ // Write method in io.Writer
+ if m != nBytes {
+ return n, io.ErrShortWrite
+ }
+ }
+ // Buffer is now empty; reset.
+ b.Reset()
+ return n, nil
+}
+
+// WriteByte appends the byte c to the buffer, growing the buffer as needed.
+// The returned error is always nil, but is included to match bufio.Writer's
+// WriteByte. If the buffer becomes too large, WriteByte will panic with
+// ErrTooLarge.
+func (b *Buffer) WriteByte(c byte) error {
+ b.lastRead = opInvalid
+ m, ok := b.tryGrowByReslice(1)
+ if !ok {
+ m = b.grow(1)
+ }
+ b.buf[m] = c
+ return nil
+}
+
+// WriteRune appends the UTF-8 encoding of Unicode code point r to the
+// buffer, returning its length and an error, which is always nil but is
+// included to match bufio.Writer's WriteRune. The buffer is grown as needed;
+// if it becomes too large, WriteRune will panic with ErrTooLarge.
+func (b *Buffer) WriteRune(r rune) (n int, err error) {
+ // Compare as uint32 to correctly handle negative runes.
+ if uint32(r) < utf8.RuneSelf {
+ b.WriteByte(byte(r))
+ return 1, nil
+ }
+ b.lastRead = opInvalid
+ m, ok := b.tryGrowByReslice(utf8.UTFMax)
+ if !ok {
+ m = b.grow(utf8.UTFMax)
+ }
+ b.buf = utf8.AppendRune(b.buf[:m], r)
+ return len(b.buf) - m, nil
+}
+
+// Read reads the next len(p) bytes from the buffer or until the buffer
+// is drained. The return value n is the number of bytes read. If the
+// buffer has no data to return, err is io.EOF (unless len(p) is zero);
+// otherwise it is nil.
+func (b *Buffer) Read(p []byte) (n int, err error) {
+ b.lastRead = opInvalid
+ if b.empty() {
+ // Buffer is empty, reset to recover space.
+ b.Reset()
+ if len(p) == 0 {
+ return 0, nil
+ }
+ return 0, io.EOF
+ }
+ n = copy(p, b.buf[b.off:])
+ b.off += n
+ if n > 0 {
+ b.lastRead = opRead
+ }
+ return n, nil
+}
+
+// Next returns a slice containing the next n bytes from the buffer,
+// advancing the buffer as if the bytes had been returned by Read.
+// If there are fewer than n bytes in the buffer, Next returns the entire buffer.
+// The slice is only valid until the next call to a read or write method.
+func (b *Buffer) Next(n int) []byte {
+ b.lastRead = opInvalid
+ m := b.Len()
+ if n > m {
+ n = m
+ }
+ data := b.buf[b.off : b.off+n]
+ b.off += n
+ if n > 0 {
+ b.lastRead = opRead
+ }
+ return data
+}
+
+// ReadByte reads and returns the next byte from the buffer.
+// If no byte is available, it returns error io.EOF.
+func (b *Buffer) ReadByte() (byte, error) {
+ if b.empty() {
+ // Buffer is empty, reset to recover space.
+ b.Reset()
+ return 0, io.EOF
+ }
+ c := b.buf[b.off]
+ b.off++
+ b.lastRead = opRead
+ return c, nil
+}
+
+// ReadRune reads and returns the next UTF-8-encoded
+// Unicode code point from the buffer.
+// If no bytes are available, the error returned is io.EOF.
+// If the bytes are an erroneous UTF-8 encoding, it
+// consumes one byte and returns U+FFFD, 1.
+func (b *Buffer) ReadRune() (r rune, size int, err error) {
+ if b.empty() {
+ // Buffer is empty, reset to recover space.
+ b.Reset()
+ return 0, 0, io.EOF
+ }
+ c := b.buf[b.off]
+ if c < utf8.RuneSelf {
+ b.off++
+ b.lastRead = opReadRune1
+ return rune(c), 1, nil
+ }
+ r, n := utf8.DecodeRune(b.buf[b.off:])
+ b.off += n
+ b.lastRead = readOp(n)
+ return r, n, nil
+}
+
+// UnreadRune unreads the last rune returned by ReadRune.
+// If the most recent read or write operation on the buffer was
+// not a successful ReadRune, UnreadRune returns an error. (In this regard
+// it is stricter than UnreadByte, which will unread the last byte
+// from any read operation.)
+func (b *Buffer) UnreadRune() error {
+ if b.lastRead <= opInvalid {
+ return errors.New("bytes.Buffer: UnreadRune: previous operation was not a successful ReadRune")
+ }
+ if b.off >= int(b.lastRead) {
+ b.off -= int(b.lastRead)
+ }
+ b.lastRead = opInvalid
+ return nil
+}
+
+var errUnreadByte = errors.New("bytes.Buffer: UnreadByte: previous operation was not a successful read")
+
+// UnreadByte unreads the last byte returned by the most recent successful
+// read operation that read at least one byte. If a write has happened since
+// the last read, if the last read returned an error, or if the read read zero
+// bytes, UnreadByte returns an error.
+func (b *Buffer) UnreadByte() error {
+ if b.lastRead == opInvalid {
+ return errUnreadByte
+ }
+ b.lastRead = opInvalid
+ if b.off > 0 {
+ b.off--
+ }
+ return nil
+}
+
+// ReadBytes reads until the first occurrence of delim in the input,
+// returning a slice containing the data up to and including the delimiter.
+// If ReadBytes encounters an error before finding a delimiter,
+// it returns the data read before the error and the error itself (often io.EOF).
+// ReadBytes returns err != nil if and only if the returned data does not end in
+// delim.
+func (b *Buffer) ReadBytes(delim byte) (line []byte, err error) {
+ slice, err := b.readSlice(delim)
+ // return a copy of slice. The buffer's backing array may
+ // be overwritten by later calls.
+ line = append(line, slice...)
+ return line, err
+}
+
+// readSlice is like ReadBytes but returns a reference to internal buffer data.
+func (b *Buffer) readSlice(delim byte) (line []byte, err error) {
+ i := IndexByte(b.buf[b.off:], delim)
+ end := b.off + i + 1
+ if i < 0 {
+ end = len(b.buf)
+ err = io.EOF
+ }
+ line = b.buf[b.off:end]
+ b.off = end
+ b.lastRead = opRead
+ return line, err
+}
+
+// ReadString reads until the first occurrence of delim in the input,
+// returning a string containing the data up to and including the delimiter.
+// If ReadString encounters an error before finding a delimiter,
+// it returns the data read before the error and the error itself (often io.EOF).
+// ReadString returns err != nil if and only if the returned data does not end
+// in delim.
+func (b *Buffer) ReadString(delim byte) (line string, err error) {
+ slice, err := b.readSlice(delim)
+ return string(slice), err
+}
+
+// NewBuffer creates and initializes a new Buffer using buf as its
+// initial contents. The new Buffer takes ownership of buf, and the
+// caller should not use buf after this call. NewBuffer is intended to
+// prepare a Buffer to read existing data. It can also be used to set
+// the initial size of the internal buffer for writing. To do that,
+// buf should have the desired capacity but a length of zero.
+//
+// In most cases, new(Buffer) (or just declaring a Buffer variable) is
+// sufficient to initialize a Buffer.
+func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }
+
+// NewBufferString creates and initializes a new Buffer using string s as its
+// initial contents. It is intended to prepare a buffer to read an existing
+// string.
+//
+// In most cases, new(Buffer) (or just declaring a Buffer variable) is
+// sufficient to initialize a Buffer.
+func NewBufferString(s string) *Buffer {
+ return &Buffer{buf: []byte(s)}
+}
diff --git a/contrib/go/_std_1.21/src/bytes/bytes.go b/contrib/go/_std_1.21/src/bytes/bytes.go
new file mode 100644
index 0000000000..c54e52e4fc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/bytes/bytes.go
@@ -0,0 +1,1396 @@
+// Copyright 2009 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 bytes implements functions for the manipulation of byte slices.
+// It is analogous to the facilities of the [strings] package.
+package bytes
+
+import (
+ "internal/bytealg"
+ "unicode"
+ "unicode/utf8"
+)
+
+// Equal reports whether a and b
+// are the same length and contain the same bytes.
+// A nil argument is equivalent to an empty slice.
+func Equal(a, b []byte) bool {
+ // Neither cmd/compile nor gccgo allocates for these string conversions.
+ return string(a) == string(b)
+}
+
+// Compare returns an integer comparing two byte slices lexicographically.
+// The result will be 0 if a == b, -1 if a < b, and +1 if a > b.
+// A nil argument is equivalent to an empty slice.
+func Compare(a, b []byte) int {
+ return bytealg.Compare(a, b)
+}
+
+// explode splits s into a slice of UTF-8 sequences, one per Unicode code point (still slices of bytes),
+// up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes.
+func explode(s []byte, n int) [][]byte {
+ if n <= 0 || n > len(s) {
+ n = len(s)
+ }
+ a := make([][]byte, n)
+ var size int
+ na := 0
+ for len(s) > 0 {
+ if na+1 >= n {
+ a[na] = s
+ na++
+ break
+ }
+ _, size = utf8.DecodeRune(s)
+ a[na] = s[0:size:size]
+ s = s[size:]
+ na++
+ }
+ return a[0:na]
+}
+
+// Count counts the number of non-overlapping instances of sep in s.
+// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
+func Count(s, sep []byte) int {
+ // special case
+ if len(sep) == 0 {
+ return utf8.RuneCount(s) + 1
+ }
+ if len(sep) == 1 {
+ return bytealg.Count(s, sep[0])
+ }
+ n := 0
+ for {
+ i := Index(s, sep)
+ if i == -1 {
+ return n
+ }
+ n++
+ s = s[i+len(sep):]
+ }
+}
+
+// Contains reports whether subslice is within b.
+func Contains(b, subslice []byte) bool {
+ return Index(b, subslice) != -1
+}
+
+// ContainsAny reports whether any of the UTF-8-encoded code points in chars are within b.
+func ContainsAny(b []byte, chars string) bool {
+ return IndexAny(b, chars) >= 0
+}
+
+// ContainsRune reports whether the rune is contained in the UTF-8-encoded byte slice b.
+func ContainsRune(b []byte, r rune) bool {
+ return IndexRune(b, r) >= 0
+}
+
+// ContainsFunc reports whether any of the UTF-8-encoded code points r within b satisfy f(r).
+func ContainsFunc(b []byte, f func(rune) bool) bool {
+ return IndexFunc(b, f) >= 0
+}
+
+// IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b.
+func IndexByte(b []byte, c byte) int {
+ return bytealg.IndexByte(b, c)
+}
+
+func indexBytePortable(s []byte, c byte) int {
+ for i, b := range s {
+ if b == c {
+ return i
+ }
+ }
+ return -1
+}
+
+// LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s.
+func LastIndex(s, sep []byte) int {
+ n := len(sep)
+ switch {
+ case n == 0:
+ return len(s)
+ case n == 1:
+ return LastIndexByte(s, sep[0])
+ case n == len(s):
+ if Equal(s, sep) {
+ return 0
+ }
+ return -1
+ case n > len(s):
+ return -1
+ }
+ // Rabin-Karp search from the end of the string
+ hashss, pow := bytealg.HashStrRevBytes(sep)
+ last := len(s) - n
+ var h uint32
+ for i := len(s) - 1; i >= last; i-- {
+ h = h*bytealg.PrimeRK + uint32(s[i])
+ }
+ if h == hashss && Equal(s[last:], sep) {
+ return last
+ }
+ for i := last - 1; i >= 0; i-- {
+ h *= bytealg.PrimeRK
+ h += uint32(s[i])
+ h -= pow * uint32(s[i+n])
+ if h == hashss && Equal(s[i:i+n], sep) {
+ return i
+ }
+ }
+ return -1
+}
+
+// LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
+func LastIndexByte(s []byte, c byte) int {
+ for i := len(s) - 1; i >= 0; i-- {
+ if s[i] == c {
+ return i
+ }
+ }
+ return -1
+}
+
+// IndexRune interprets s as a sequence of UTF-8-encoded code points.
+// It returns the byte index of the first occurrence in s of the given rune.
+// It returns -1 if rune is not present in s.
+// If r is utf8.RuneError, it returns the first instance of any
+// invalid UTF-8 byte sequence.
+func IndexRune(s []byte, r rune) int {
+ switch {
+ case 0 <= r && r < utf8.RuneSelf:
+ return IndexByte(s, byte(r))
+ case r == utf8.RuneError:
+ for i := 0; i < len(s); {
+ r1, n := utf8.DecodeRune(s[i:])
+ if r1 == utf8.RuneError {
+ return i
+ }
+ i += n
+ }
+ return -1
+ case !utf8.ValidRune(r):
+ return -1
+ default:
+ var b [utf8.UTFMax]byte
+ n := utf8.EncodeRune(b[:], r)
+ return Index(s, b[:n])
+ }
+}
+
+// IndexAny interprets s as a sequence of UTF-8-encoded Unicode code points.
+// It returns the byte index of the first occurrence in s of any of the Unicode
+// code points in chars. It returns -1 if chars is empty or if there is no code
+// point in common.
+func IndexAny(s []byte, chars string) int {
+ if chars == "" {
+ // Avoid scanning all of s.
+ return -1
+ }
+ if len(s) == 1 {
+ r := rune(s[0])
+ if r >= utf8.RuneSelf {
+ // search utf8.RuneError.
+ for _, r = range chars {
+ if r == utf8.RuneError {
+ return 0
+ }
+ }
+ return -1
+ }
+ if bytealg.IndexByteString(chars, s[0]) >= 0 {
+ return 0
+ }
+ return -1
+ }
+ if len(chars) == 1 {
+ r := rune(chars[0])
+ if r >= utf8.RuneSelf {
+ r = utf8.RuneError
+ }
+ return IndexRune(s, r)
+ }
+ if len(s) > 8 {
+ if as, isASCII := makeASCIISet(chars); isASCII {
+ for i, c := range s {
+ if as.contains(c) {
+ return i
+ }
+ }
+ return -1
+ }
+ }
+ var width int
+ for i := 0; i < len(s); i += width {
+ r := rune(s[i])
+ if r < utf8.RuneSelf {
+ if bytealg.IndexByteString(chars, s[i]) >= 0 {
+ return i
+ }
+ width = 1
+ continue
+ }
+ r, width = utf8.DecodeRune(s[i:])
+ if r != utf8.RuneError {
+ // r is 2 to 4 bytes
+ if len(chars) == width {
+ if chars == string(r) {
+ return i
+ }
+ continue
+ }
+ // Use bytealg.IndexString for performance if available.
+ if bytealg.MaxLen >= width {
+ if bytealg.IndexString(chars, string(r)) >= 0 {
+ return i
+ }
+ continue
+ }
+ }
+ for _, ch := range chars {
+ if r == ch {
+ return i
+ }
+ }
+ }
+ return -1
+}
+
+// LastIndexAny interprets s as a sequence of UTF-8-encoded Unicode code
+// points. It returns the byte index of the last occurrence in s of any of
+// the Unicode code points in chars. It returns -1 if chars is empty or if
+// there is no code point in common.
+func LastIndexAny(s []byte, chars string) int {
+ if chars == "" {
+ // Avoid scanning all of s.
+ return -1
+ }
+ if len(s) > 8 {
+ if as, isASCII := makeASCIISet(chars); isASCII {
+ for i := len(s) - 1; i >= 0; i-- {
+ if as.contains(s[i]) {
+ return i
+ }
+ }
+ return -1
+ }
+ }
+ if len(s) == 1 {
+ r := rune(s[0])
+ if r >= utf8.RuneSelf {
+ for _, r = range chars {
+ if r == utf8.RuneError {
+ return 0
+ }
+ }
+ return -1
+ }
+ if bytealg.IndexByteString(chars, s[0]) >= 0 {
+ return 0
+ }
+ return -1
+ }
+ if len(chars) == 1 {
+ cr := rune(chars[0])
+ if cr >= utf8.RuneSelf {
+ cr = utf8.RuneError
+ }
+ for i := len(s); i > 0; {
+ r, size := utf8.DecodeLastRune(s[:i])
+ i -= size
+ if r == cr {
+ return i
+ }
+ }
+ return -1
+ }
+ for i := len(s); i > 0; {
+ r := rune(s[i-1])
+ if r < utf8.RuneSelf {
+ if bytealg.IndexByteString(chars, s[i-1]) >= 0 {
+ return i - 1
+ }
+ i--
+ continue
+ }
+ r, size := utf8.DecodeLastRune(s[:i])
+ i -= size
+ if r != utf8.RuneError {
+ // r is 2 to 4 bytes
+ if len(chars) == size {
+ if chars == string(r) {
+ return i
+ }
+ continue
+ }
+ // Use bytealg.IndexString for performance if available.
+ if bytealg.MaxLen >= size {
+ if bytealg.IndexString(chars, string(r)) >= 0 {
+ return i
+ }
+ continue
+ }
+ }
+ for _, ch := range chars {
+ if r == ch {
+ return i
+ }
+ }
+ }
+ return -1
+}
+
+// Generic split: splits after each instance of sep,
+// including sepSave bytes of sep in the subslices.
+func genSplit(s, sep []byte, sepSave, n int) [][]byte {
+ if n == 0 {
+ return nil
+ }
+ if len(sep) == 0 {
+ return explode(s, n)
+ }
+ if n < 0 {
+ n = Count(s, sep) + 1
+ }
+ if n > len(s)+1 {
+ n = len(s) + 1
+ }
+
+ a := make([][]byte, n)
+ n--
+ i := 0
+ for i < n {
+ m := Index(s, sep)
+ if m < 0 {
+ break
+ }
+ a[i] = s[: m+sepSave : m+sepSave]
+ s = s[m+len(sep):]
+ i++
+ }
+ a[i] = s
+ return a[:i+1]
+}
+
+// SplitN slices s into subslices separated by sep and returns a slice of
+// the subslices between those separators.
+// If sep is empty, SplitN splits after each UTF-8 sequence.
+// The count determines the number of subslices to return:
+//
+// n > 0: at most n subslices; the last subslice will be the unsplit remainder.
+// n == 0: the result is nil (zero subslices)
+// n < 0: all subslices
+//
+// To split around the first instance of a separator, see Cut.
+func SplitN(s, sep []byte, n int) [][]byte { return genSplit(s, sep, 0, n) }
+
+// SplitAfterN slices s into subslices after each instance of sep and
+// returns a slice of those subslices.
+// If sep is empty, SplitAfterN splits after each UTF-8 sequence.
+// The count determines the number of subslices to return:
+//
+// n > 0: at most n subslices; the last subslice will be the unsplit remainder.
+// n == 0: the result is nil (zero subslices)
+// n < 0: all subslices
+func SplitAfterN(s, sep []byte, n int) [][]byte {
+ return genSplit(s, sep, len(sep), n)
+}
+
+// Split slices s into all subslices separated by sep and returns a slice of
+// the subslices between those separators.
+// If sep is empty, Split splits after each UTF-8 sequence.
+// It is equivalent to SplitN with a count of -1.
+//
+// To split around the first instance of a separator, see Cut.
+func Split(s, sep []byte) [][]byte { return genSplit(s, sep, 0, -1) }
+
+// SplitAfter slices s into all subslices after each instance of sep and
+// returns a slice of those subslices.
+// If sep is empty, SplitAfter splits after each UTF-8 sequence.
+// It is equivalent to SplitAfterN with a count of -1.
+func SplitAfter(s, sep []byte) [][]byte {
+ return genSplit(s, sep, len(sep), -1)
+}
+
+var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
+
+// Fields interprets s as a sequence of UTF-8-encoded code points.
+// It splits the slice s around each instance of one or more consecutive white space
+// characters, as defined by unicode.IsSpace, returning a slice of subslices of s or an
+// empty slice if s contains only white space.
+func Fields(s []byte) [][]byte {
+ // First count the fields.
+ // This is an exact count if s is ASCII, otherwise it is an approximation.
+ n := 0
+ wasSpace := 1
+ // setBits is used to track which bits are set in the bytes of s.
+ setBits := uint8(0)
+ for i := 0; i < len(s); i++ {
+ r := s[i]
+ setBits |= r
+ isSpace := int(asciiSpace[r])
+ n += wasSpace & ^isSpace
+ wasSpace = isSpace
+ }
+
+ if setBits >= utf8.RuneSelf {
+ // Some runes in the input slice are not ASCII.
+ return FieldsFunc(s, unicode.IsSpace)
+ }
+
+ // ASCII fast path
+ a := make([][]byte, n)
+ na := 0
+ fieldStart := 0
+ i := 0
+ // Skip spaces in the front of the input.
+ for i < len(s) && asciiSpace[s[i]] != 0 {
+ i++
+ }
+ fieldStart = i
+ for i < len(s) {
+ if asciiSpace[s[i]] == 0 {
+ i++
+ continue
+ }
+ a[na] = s[fieldStart:i:i]
+ na++
+ i++
+ // Skip spaces in between fields.
+ for i < len(s) && asciiSpace[s[i]] != 0 {
+ i++
+ }
+ fieldStart = i
+ }
+ if fieldStart < len(s) { // Last field might end at EOF.
+ a[na] = s[fieldStart:len(s):len(s)]
+ }
+ return a
+}
+
+// FieldsFunc interprets s as a sequence of UTF-8-encoded code points.
+// It splits the slice s at each run of code points c satisfying f(c) and
+// returns a slice of subslices of s. If all code points in s satisfy f(c), or
+// len(s) == 0, an empty slice is returned.
+//
+// FieldsFunc makes no guarantees about the order in which it calls f(c)
+// and assumes that f always returns the same value for a given c.
+func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
+ // A span is used to record a slice of s of the form s[start:end].
+ // The start index is inclusive and the end index is exclusive.
+ type span struct {
+ start int
+ end int
+ }
+ spans := make([]span, 0, 32)
+
+ // Find the field start and end indices.
+ // Doing this in a separate pass (rather than slicing the string s
+ // and collecting the result substrings right away) is significantly
+ // more efficient, possibly due to cache effects.
+ start := -1 // valid span start if >= 0
+ for i := 0; i < len(s); {
+ size := 1
+ r := rune(s[i])
+ if r >= utf8.RuneSelf {
+ r, size = utf8.DecodeRune(s[i:])
+ }
+ if f(r) {
+ if start >= 0 {
+ spans = append(spans, span{start, i})
+ start = -1
+ }
+ } else {
+ if start < 0 {
+ start = i
+ }
+ }
+ i += size
+ }
+
+ // Last field might end at EOF.
+ if start >= 0 {
+ spans = append(spans, span{start, len(s)})
+ }
+
+ // Create subslices from recorded field indices.
+ a := make([][]byte, len(spans))
+ for i, span := range spans {
+ a[i] = s[span.start:span.end:span.end]
+ }
+
+ return a
+}
+
+// Join concatenates the elements of s to create a new byte slice. The separator
+// sep is placed between elements in the resulting slice.
+func Join(s [][]byte, sep []byte) []byte {
+ if len(s) == 0 {
+ return []byte{}
+ }
+ if len(s) == 1 {
+ // Just return a copy.
+ return append([]byte(nil), s[0]...)
+ }
+
+ var n int
+ if len(sep) > 0 {
+ if len(sep) >= maxInt/(len(s)-1) {
+ panic("bytes: Join output length overflow")
+ }
+ n += len(sep) * (len(s) - 1)
+ }
+ for _, v := range s {
+ if len(v) > maxInt-n {
+ panic("bytes: Join output length overflow")
+ }
+ n += len(v)
+ }
+
+ b := bytealg.MakeNoZero(n)
+ bp := copy(b, s[0])
+ for _, v := range s[1:] {
+ bp += copy(b[bp:], sep)
+ bp += copy(b[bp:], v)
+ }
+ return b
+}
+
+// HasPrefix tests whether the byte slice s begins with prefix.
+func HasPrefix(s, prefix []byte) bool {
+ return len(s) >= len(prefix) && Equal(s[0:len(prefix)], prefix)
+}
+
+// HasSuffix tests whether the byte slice s ends with suffix.
+func HasSuffix(s, suffix []byte) bool {
+ return len(s) >= len(suffix) && Equal(s[len(s)-len(suffix):], suffix)
+}
+
+// Map returns a copy of the byte slice s with all its characters modified
+// according to the mapping function. If mapping returns a negative value, the character is
+// dropped from the byte slice with no replacement. The characters in s and the
+// output are interpreted as UTF-8-encoded code points.
+func Map(mapping func(r rune) rune, s []byte) []byte {
+ // In the worst case, the slice can grow when mapped, making
+ // things unpleasant. But it's so rare we barge in assuming it's
+ // fine. It could also shrink but that falls out naturally.
+ b := make([]byte, 0, len(s))
+ for i := 0; i < len(s); {
+ wid := 1
+ r := rune(s[i])
+ if r >= utf8.RuneSelf {
+ r, wid = utf8.DecodeRune(s[i:])
+ }
+ r = mapping(r)
+ if r >= 0 {
+ b = utf8.AppendRune(b, r)
+ }
+ i += wid
+ }
+ return b
+}
+
+// Repeat returns a new byte slice consisting of count copies of b.
+//
+// It panics if count is negative or if the result of (len(b) * count)
+// overflows.
+func Repeat(b []byte, count int) []byte {
+ if count == 0 {
+ return []byte{}
+ }
+
+ // Since we cannot return an error on overflow,
+ // we should panic if the repeat will generate an overflow.
+ // See golang.org/issue/16237.
+ if count < 0 {
+ panic("bytes: negative Repeat count")
+ }
+ if len(b) >= maxInt/count {
+ panic("bytes: Repeat output length overflow")
+ }
+ n := len(b) * count
+
+ if len(b) == 0 {
+ return []byte{}
+ }
+
+ // Past a certain chunk size it is counterproductive to use
+ // larger chunks as the source of the write, as when the source
+ // is too large we are basically just thrashing the CPU D-cache.
+ // So if the result length is larger than an empirically-found
+ // limit (8KB), we stop growing the source string once the limit
+ // is reached and keep reusing the same source string - that
+ // should therefore be always resident in the L1 cache - until we
+ // have completed the construction of the result.
+ // This yields significant speedups (up to +100%) in cases where
+ // the result length is large (roughly, over L2 cache size).
+ const chunkLimit = 8 * 1024
+ chunkMax := n
+ if chunkMax > chunkLimit {
+ chunkMax = chunkLimit / len(b) * len(b)
+ if chunkMax == 0 {
+ chunkMax = len(b)
+ }
+ }
+ nb := bytealg.MakeNoZero(n)
+ bp := copy(nb, b)
+ for bp < n {
+ chunk := bp
+ if chunk > chunkMax {
+ chunk = chunkMax
+ }
+ bp += copy(nb[bp:], nb[:chunk])
+ }
+ return nb
+}
+
+// ToUpper returns a copy of the byte slice s with all Unicode letters mapped to
+// their upper case.
+func ToUpper(s []byte) []byte {
+ isASCII, hasLower := true, false
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ if c >= utf8.RuneSelf {
+ isASCII = false
+ break
+ }
+ hasLower = hasLower || ('a' <= c && c <= 'z')
+ }
+
+ if isASCII { // optimize for ASCII-only byte slices.
+ if !hasLower {
+ // Just return a copy.
+ return append([]byte(""), s...)
+ }
+ b := bytealg.MakeNoZero(len(s))
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ if 'a' <= c && c <= 'z' {
+ c -= 'a' - 'A'
+ }
+ b[i] = c
+ }
+ return b
+ }
+ return Map(unicode.ToUpper, s)
+}
+
+// ToLower returns a copy of the byte slice s with all Unicode letters mapped to
+// their lower case.
+func ToLower(s []byte) []byte {
+ isASCII, hasUpper := true, false
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ if c >= utf8.RuneSelf {
+ isASCII = false
+ break
+ }
+ hasUpper = hasUpper || ('A' <= c && c <= 'Z')
+ }
+
+ if isASCII { // optimize for ASCII-only byte slices.
+ if !hasUpper {
+ return append([]byte(""), s...)
+ }
+ b := bytealg.MakeNoZero(len(s))
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ if 'A' <= c && c <= 'Z' {
+ c += 'a' - 'A'
+ }
+ b[i] = c
+ }
+ return b
+ }
+ return Map(unicode.ToLower, s)
+}
+
+// ToTitle treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their title case.
+func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) }
+
+// ToUpperSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
+// upper case, giving priority to the special casing rules.
+func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte {
+ return Map(c.ToUpper, s)
+}
+
+// ToLowerSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
+// lower case, giving priority to the special casing rules.
+func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte {
+ return Map(c.ToLower, s)
+}
+
+// ToTitleSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their
+// title case, giving priority to the special casing rules.
+func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte {
+ return Map(c.ToTitle, s)
+}
+
+// ToValidUTF8 treats s as UTF-8-encoded bytes and returns a copy with each run of bytes
+// representing invalid UTF-8 replaced with the bytes in replacement, which may be empty.
+func ToValidUTF8(s, replacement []byte) []byte {
+ b := make([]byte, 0, len(s)+len(replacement))
+ invalid := false // previous byte was from an invalid UTF-8 sequence
+ for i := 0; i < len(s); {
+ c := s[i]
+ if c < utf8.RuneSelf {
+ i++
+ invalid = false
+ b = append(b, c)
+ continue
+ }
+ _, wid := utf8.DecodeRune(s[i:])
+ if wid == 1 {
+ i++
+ if !invalid {
+ invalid = true
+ b = append(b, replacement...)
+ }
+ continue
+ }
+ invalid = false
+ b = append(b, s[i:i+wid]...)
+ i += wid
+ }
+ return b
+}
+
+// isSeparator reports whether the rune could mark a word boundary.
+// TODO: update when package unicode captures more of the properties.
+func isSeparator(r rune) bool {
+ // ASCII alphanumerics and underscore are not separators
+ if r <= 0x7F {
+ switch {
+ case '0' <= r && r <= '9':
+ return false
+ case 'a' <= r && r <= 'z':
+ return false
+ case 'A' <= r && r <= 'Z':
+ return false
+ case r == '_':
+ return false
+ }
+ return true
+ }
+ // Letters and digits are not separators
+ if unicode.IsLetter(r) || unicode.IsDigit(r) {
+ return false
+ }
+ // Otherwise, all we can do for now is treat spaces as separators.
+ return unicode.IsSpace(r)
+}
+
+// Title treats s as UTF-8-encoded bytes and returns a copy with all Unicode letters that begin
+// words mapped to their title case.
+//
+// Deprecated: The rule Title uses for word boundaries does not handle Unicode
+// punctuation properly. Use golang.org/x/text/cases instead.
+func Title(s []byte) []byte {
+ // Use a closure here to remember state.
+ // Hackish but effective. Depends on Map scanning in order and calling
+ // the closure once per rune.
+ prev := ' '
+ return Map(
+ func(r rune) rune {
+ if isSeparator(prev) {
+ prev = r
+ return unicode.ToTitle(r)
+ }
+ prev = r
+ return r
+ },
+ s)
+}
+
+// TrimLeftFunc treats s as UTF-8-encoded bytes and returns a subslice of s by slicing off
+// all leading UTF-8-encoded code points c that satisfy f(c).
+func TrimLeftFunc(s []byte, f func(r rune) bool) []byte {
+ i := indexFunc(s, f, false)
+ if i == -1 {
+ return nil
+ }
+ return s[i:]
+}
+
+// TrimRightFunc returns a subslice of s by slicing off all trailing
+// UTF-8-encoded code points c that satisfy f(c).
+func TrimRightFunc(s []byte, f func(r rune) bool) []byte {
+ i := lastIndexFunc(s, f, false)
+ if i >= 0 && s[i] >= utf8.RuneSelf {
+ _, wid := utf8.DecodeRune(s[i:])
+ i += wid
+ } else {
+ i++
+ }
+ return s[0:i]
+}
+
+// TrimFunc returns a subslice of s by slicing off all leading and trailing
+// UTF-8-encoded code points c that satisfy f(c).
+func TrimFunc(s []byte, f func(r rune) bool) []byte {
+ return TrimRightFunc(TrimLeftFunc(s, f), f)
+}
+
+// TrimPrefix returns s without the provided leading prefix string.
+// If s doesn't start with prefix, s is returned unchanged.
+func TrimPrefix(s, prefix []byte) []byte {
+ if HasPrefix(s, prefix) {
+ return s[len(prefix):]
+ }
+ return s
+}
+
+// TrimSuffix returns s without the provided trailing suffix string.
+// If s doesn't end with suffix, s is returned unchanged.
+func TrimSuffix(s, suffix []byte) []byte {
+ if HasSuffix(s, suffix) {
+ return s[:len(s)-len(suffix)]
+ }
+ return s
+}
+
+// IndexFunc interprets s as a sequence of UTF-8-encoded code points.
+// It returns the byte index in s of the first Unicode
+// code point satisfying f(c), or -1 if none do.
+func IndexFunc(s []byte, f func(r rune) bool) int {
+ return indexFunc(s, f, true)
+}
+
+// LastIndexFunc interprets s as a sequence of UTF-8-encoded code points.
+// It returns the byte index in s of the last Unicode
+// code point satisfying f(c), or -1 if none do.
+func LastIndexFunc(s []byte, f func(r rune) bool) int {
+ return lastIndexFunc(s, f, true)
+}
+
+// indexFunc is the same as IndexFunc except that if
+// truth==false, the sense of the predicate function is
+// inverted.
+func indexFunc(s []byte, f func(r rune) bool, truth bool) int {
+ start := 0
+ for start < len(s) {
+ wid := 1
+ r := rune(s[start])
+ if r >= utf8.RuneSelf {
+ r, wid = utf8.DecodeRune(s[start:])
+ }
+ if f(r) == truth {
+ return start
+ }
+ start += wid
+ }
+ return -1
+}
+
+// lastIndexFunc is the same as LastIndexFunc except that if
+// truth==false, the sense of the predicate function is
+// inverted.
+func lastIndexFunc(s []byte, f func(r rune) bool, truth bool) int {
+ for i := len(s); i > 0; {
+ r, size := rune(s[i-1]), 1
+ if r >= utf8.RuneSelf {
+ r, size = utf8.DecodeLastRune(s[0:i])
+ }
+ i -= size
+ if f(r) == truth {
+ return i
+ }
+ }
+ return -1
+}
+
+// asciiSet is a 32-byte value, where each bit represents the presence of a
+// given ASCII character in the set. The 128-bits of the lower 16 bytes,
+// starting with the least-significant bit of the lowest word to the
+// most-significant bit of the highest word, map to the full range of all
+// 128 ASCII characters. The 128-bits of the upper 16 bytes will be zeroed,
+// ensuring that any non-ASCII character will be reported as not in the set.
+// This allocates a total of 32 bytes even though the upper half
+// is unused to avoid bounds checks in asciiSet.contains.
+type asciiSet [8]uint32
+
+// makeASCIISet creates a set of ASCII characters and reports whether all
+// characters in chars are ASCII.
+func makeASCIISet(chars string) (as asciiSet, ok bool) {
+ for i := 0; i < len(chars); i++ {
+ c := chars[i]
+ if c >= utf8.RuneSelf {
+ return as, false
+ }
+ as[c/32] |= 1 << (c % 32)
+ }
+ return as, true
+}
+
+// contains reports whether c is inside the set.
+func (as *asciiSet) contains(c byte) bool {
+ return (as[c/32] & (1 << (c % 32))) != 0
+}
+
+// containsRune is a simplified version of strings.ContainsRune
+// to avoid importing the strings package.
+// We avoid bytes.ContainsRune to avoid allocating a temporary copy of s.
+func containsRune(s string, r rune) bool {
+ for _, c := range s {
+ if c == r {
+ return true
+ }
+ }
+ return false
+}
+
+// Trim returns a subslice of s by slicing off all leading and
+// trailing UTF-8-encoded code points contained in cutset.
+func Trim(s []byte, cutset string) []byte {
+ if len(s) == 0 {
+ // This is what we've historically done.
+ return nil
+ }
+ if cutset == "" {
+ return s
+ }
+ if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
+ return trimLeftByte(trimRightByte(s, cutset[0]), cutset[0])
+ }
+ if as, ok := makeASCIISet(cutset); ok {
+ return trimLeftASCII(trimRightASCII(s, &as), &as)
+ }
+ return trimLeftUnicode(trimRightUnicode(s, cutset), cutset)
+}
+
+// TrimLeft returns a subslice of s by slicing off all leading
+// UTF-8-encoded code points contained in cutset.
+func TrimLeft(s []byte, cutset string) []byte {
+ if len(s) == 0 {
+ // This is what we've historically done.
+ return nil
+ }
+ if cutset == "" {
+ return s
+ }
+ if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
+ return trimLeftByte(s, cutset[0])
+ }
+ if as, ok := makeASCIISet(cutset); ok {
+ return trimLeftASCII(s, &as)
+ }
+ return trimLeftUnicode(s, cutset)
+}
+
+func trimLeftByte(s []byte, c byte) []byte {
+ for len(s) > 0 && s[0] == c {
+ s = s[1:]
+ }
+ if len(s) == 0 {
+ // This is what we've historically done.
+ return nil
+ }
+ return s
+}
+
+func trimLeftASCII(s []byte, as *asciiSet) []byte {
+ for len(s) > 0 {
+ if !as.contains(s[0]) {
+ break
+ }
+ s = s[1:]
+ }
+ if len(s) == 0 {
+ // This is what we've historically done.
+ return nil
+ }
+ return s
+}
+
+func trimLeftUnicode(s []byte, cutset string) []byte {
+ for len(s) > 0 {
+ r, n := rune(s[0]), 1
+ if r >= utf8.RuneSelf {
+ r, n = utf8.DecodeRune(s)
+ }
+ if !containsRune(cutset, r) {
+ break
+ }
+ s = s[n:]
+ }
+ if len(s) == 0 {
+ // This is what we've historically done.
+ return nil
+ }
+ return s
+}
+
+// TrimRight returns a subslice of s by slicing off all trailing
+// UTF-8-encoded code points that are contained in cutset.
+func TrimRight(s []byte, cutset string) []byte {
+ if len(s) == 0 || cutset == "" {
+ return s
+ }
+ if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
+ return trimRightByte(s, cutset[0])
+ }
+ if as, ok := makeASCIISet(cutset); ok {
+ return trimRightASCII(s, &as)
+ }
+ return trimRightUnicode(s, cutset)
+}
+
+func trimRightByte(s []byte, c byte) []byte {
+ for len(s) > 0 && s[len(s)-1] == c {
+ s = s[:len(s)-1]
+ }
+ return s
+}
+
+func trimRightASCII(s []byte, as *asciiSet) []byte {
+ for len(s) > 0 {
+ if !as.contains(s[len(s)-1]) {
+ break
+ }
+ s = s[:len(s)-1]
+ }
+ return s
+}
+
+func trimRightUnicode(s []byte, cutset string) []byte {
+ for len(s) > 0 {
+ r, n := rune(s[len(s)-1]), 1
+ if r >= utf8.RuneSelf {
+ r, n = utf8.DecodeLastRune(s)
+ }
+ if !containsRune(cutset, r) {
+ break
+ }
+ s = s[:len(s)-n]
+ }
+ return s
+}
+
+// TrimSpace returns a subslice of s by slicing off all leading and
+// trailing white space, as defined by Unicode.
+func TrimSpace(s []byte) []byte {
+ // Fast path for ASCII: look for the first ASCII non-space byte
+ start := 0
+ for ; start < len(s); start++ {
+ c := s[start]
+ if c >= utf8.RuneSelf {
+ // If we run into a non-ASCII byte, fall back to the
+ // slower unicode-aware method on the remaining bytes
+ return TrimFunc(s[start:], unicode.IsSpace)
+ }
+ if asciiSpace[c] == 0 {
+ break
+ }
+ }
+
+ // Now look for the first ASCII non-space byte from the end
+ stop := len(s)
+ for ; stop > start; stop-- {
+ c := s[stop-1]
+ if c >= utf8.RuneSelf {
+ return TrimFunc(s[start:stop], unicode.IsSpace)
+ }
+ if asciiSpace[c] == 0 {
+ break
+ }
+ }
+
+ // At this point s[start:stop] starts and ends with an ASCII
+ // non-space bytes, so we're done. Non-ASCII cases have already
+ // been handled above.
+ if start == stop {
+ // Special case to preserve previous TrimLeftFunc behavior,
+ // returning nil instead of empty slice if all spaces.
+ return nil
+ }
+ return s[start:stop]
+}
+
+// Runes interprets s as a sequence of UTF-8-encoded code points.
+// It returns a slice of runes (Unicode code points) equivalent to s.
+func Runes(s []byte) []rune {
+ t := make([]rune, utf8.RuneCount(s))
+ i := 0
+ for len(s) > 0 {
+ r, l := utf8.DecodeRune(s)
+ t[i] = r
+ i++
+ s = s[l:]
+ }
+ return t
+}
+
+// Replace returns a copy of the slice s with the first n
+// non-overlapping instances of old replaced by new.
+// If old is empty, it matches at the beginning of the slice
+// and after each UTF-8 sequence, yielding up to k+1 replacements
+// for a k-rune slice.
+// If n < 0, there is no limit on the number of replacements.
+func Replace(s, old, new []byte, n int) []byte {
+ m := 0
+ if n != 0 {
+ // Compute number of replacements.
+ m = Count(s, old)
+ }
+ if m == 0 {
+ // Just return a copy.
+ return append([]byte(nil), s...)
+ }
+ if n < 0 || m < n {
+ n = m
+ }
+
+ // Apply replacements to buffer.
+ t := make([]byte, len(s)+n*(len(new)-len(old)))
+ w := 0
+ start := 0
+ for i := 0; i < n; i++ {
+ j := start
+ if len(old) == 0 {
+ if i > 0 {
+ _, wid := utf8.DecodeRune(s[start:])
+ j += wid
+ }
+ } else {
+ j += Index(s[start:], old)
+ }
+ w += copy(t[w:], s[start:j])
+ w += copy(t[w:], new)
+ start = j + len(old)
+ }
+ w += copy(t[w:], s[start:])
+ return t[0:w]
+}
+
+// ReplaceAll returns a copy of the slice s with all
+// non-overlapping instances of old replaced by new.
+// If old is empty, it matches at the beginning of the slice
+// and after each UTF-8 sequence, yielding up to k+1 replacements
+// for a k-rune slice.
+func ReplaceAll(s, old, new []byte) []byte {
+ return Replace(s, old, new, -1)
+}
+
+// EqualFold reports whether s and t, interpreted as UTF-8 strings,
+// are equal under simple Unicode case-folding, which is a more general
+// form of case-insensitivity.
+func EqualFold(s, t []byte) bool {
+ // ASCII fast path
+ i := 0
+ for ; i < len(s) && i < len(t); i++ {
+ sr := s[i]
+ tr := t[i]
+ if sr|tr >= utf8.RuneSelf {
+ goto hasUnicode
+ }
+
+ // Easy case.
+ if tr == sr {
+ continue
+ }
+
+ // Make sr < tr to simplify what follows.
+ if tr < sr {
+ tr, sr = sr, tr
+ }
+ // ASCII only, sr/tr must be upper/lower case
+ if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
+ continue
+ }
+ return false
+ }
+ // Check if we've exhausted both strings.
+ return len(s) == len(t)
+
+hasUnicode:
+ s = s[i:]
+ t = t[i:]
+ for len(s) != 0 && len(t) != 0 {
+ // Extract first rune from each.
+ var sr, tr rune
+ if s[0] < utf8.RuneSelf {
+ sr, s = rune(s[0]), s[1:]
+ } else {
+ r, size := utf8.DecodeRune(s)
+ sr, s = r, s[size:]
+ }
+ if t[0] < utf8.RuneSelf {
+ tr, t = rune(t[0]), t[1:]
+ } else {
+ r, size := utf8.DecodeRune(t)
+ tr, t = r, t[size:]
+ }
+
+ // If they match, keep going; if not, return false.
+
+ // Easy case.
+ if tr == sr {
+ continue
+ }
+
+ // Make sr < tr to simplify what follows.
+ if tr < sr {
+ tr, sr = sr, tr
+ }
+ // Fast check for ASCII.
+ if tr < utf8.RuneSelf {
+ // ASCII only, sr/tr must be upper/lower case
+ if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
+ continue
+ }
+ return false
+ }
+
+ // General case. SimpleFold(x) returns the next equivalent rune > x
+ // or wraps around to smaller values.
+ r := unicode.SimpleFold(sr)
+ for r != sr && r < tr {
+ r = unicode.SimpleFold(r)
+ }
+ if r == tr {
+ continue
+ }
+ return false
+ }
+
+ // One string is empty. Are both?
+ return len(s) == len(t)
+}
+
+// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
+func Index(s, sep []byte) int {
+ n := len(sep)
+ switch {
+ case n == 0:
+ return 0
+ case n == 1:
+ return IndexByte(s, sep[0])
+ case n == len(s):
+ if Equal(sep, s) {
+ return 0
+ }
+ return -1
+ case n > len(s):
+ return -1
+ case n <= bytealg.MaxLen:
+ // Use brute force when s and sep both are small
+ if len(s) <= bytealg.MaxBruteForce {
+ return bytealg.Index(s, sep)
+ }
+ c0 := sep[0]
+ c1 := sep[1]
+ i := 0
+ t := len(s) - n + 1
+ fails := 0
+ for i < t {
+ if s[i] != c0 {
+ // IndexByte is faster than bytealg.Index, so use it as long as
+ // we're not getting lots of false positives.
+ o := IndexByte(s[i+1:t], c0)
+ if o < 0 {
+ return -1
+ }
+ i += o + 1
+ }
+ if s[i+1] == c1 && Equal(s[i:i+n], sep) {
+ return i
+ }
+ fails++
+ i++
+ // Switch to bytealg.Index when IndexByte produces too many false positives.
+ if fails > bytealg.Cutover(i) {
+ r := bytealg.Index(s[i:], sep)
+ if r >= 0 {
+ return r + i
+ }
+ return -1
+ }
+ }
+ return -1
+ }
+ c0 := sep[0]
+ c1 := sep[1]
+ i := 0
+ fails := 0
+ t := len(s) - n + 1
+ for i < t {
+ if s[i] != c0 {
+ o := IndexByte(s[i+1:t], c0)
+ if o < 0 {
+ break
+ }
+ i += o + 1
+ }
+ if s[i+1] == c1 && Equal(s[i:i+n], sep) {
+ return i
+ }
+ i++
+ fails++
+ if fails >= 4+i>>4 && i < t {
+ // Give up on IndexByte, it isn't skipping ahead
+ // far enough to be better than Rabin-Karp.
+ // Experiments (using IndexPeriodic) suggest
+ // the cutover is about 16 byte skips.
+ // TODO: if large prefixes of sep are matching
+ // we should cutover at even larger average skips,
+ // because Equal becomes that much more expensive.
+ // This code does not take that effect into account.
+ j := bytealg.IndexRabinKarpBytes(s[i:], sep)
+ if j < 0 {
+ return -1
+ }
+ return i + j
+ }
+ }
+ return -1
+}
+
+// Cut slices s around the first instance of sep,
+// returning the text before and after sep.
+// The found result reports whether sep appears in s.
+// If sep does not appear in s, cut returns s, nil, false.
+//
+// Cut returns slices of the original slice s, not copies.
+func Cut(s, sep []byte) (before, after []byte, found bool) {
+ if i := Index(s, sep); i >= 0 {
+ return s[:i], s[i+len(sep):], true
+ }
+ return s, nil, false
+}
+
+// Clone returns a copy of b[:len(b)].
+// The result may have additional unused capacity.
+// Clone(nil) returns nil.
+func Clone(b []byte) []byte {
+ if b == nil {
+ return nil
+ }
+ return append([]byte{}, b...)
+}
+
+// CutPrefix returns s without the provided leading prefix byte slice
+// and reports whether it found the prefix.
+// If s doesn't start with prefix, CutPrefix returns s, false.
+// If prefix is the empty byte slice, CutPrefix returns s, true.
+//
+// CutPrefix returns slices of the original slice s, not copies.
+func CutPrefix(s, prefix []byte) (after []byte, found bool) {
+ if !HasPrefix(s, prefix) {
+ return s, false
+ }
+ return s[len(prefix):], true
+}
+
+// CutSuffix returns s without the provided ending suffix byte slice
+// and reports whether it found the suffix.
+// If s doesn't end with suffix, CutSuffix returns s, false.
+// If suffix is the empty byte slice, CutSuffix returns s, true.
+//
+// CutSuffix returns slices of the original slice s, not copies.
+func CutSuffix(s, suffix []byte) (before []byte, found bool) {
+ if !HasSuffix(s, suffix) {
+ return s, false
+ }
+ return s[:len(s)-len(suffix)], true
+}
diff --git a/contrib/go/_std_1.20/src/bytes/reader.go b/contrib/go/_std_1.21/src/bytes/reader.go
index 81c22aa029..81c22aa029 100644
--- a/contrib/go/_std_1.20/src/bytes/reader.go
+++ b/contrib/go/_std_1.21/src/bytes/reader.go
diff --git a/contrib/go/_std_1.21/src/bytes/ya.make b/contrib/go/_std_1.21/src/bytes/ya.make
new file mode 100644
index 0000000000..cfc6e35e7f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/bytes/ya.make
@@ -0,0 +1,26 @@
+GO_LIBRARY()
+
+SRCS(
+ buffer.go
+ bytes.go
+ reader.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ buffer_test.go
+ bytes_test.go
+ compare_test.go
+ example_test.go
+ reader_test.go
+)
+
+IF (OS_LINUX)
+ GO_XTEST_SRCS(boundary_test.go)
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/cmp/cmp.go b/contrib/go/_std_1.21/src/cmp/cmp.go
new file mode 100644
index 0000000000..0fba5c1211
--- /dev/null
+++ b/contrib/go/_std_1.21/src/cmp/cmp.go
@@ -0,0 +1,59 @@
+// Copyright 2023 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 cmp provides types and functions related to comparing
+// ordered values.
+package cmp
+
+// Ordered is a constraint that permits any ordered type: any type
+// that supports the operators < <= >= >.
+// If future releases of Go add new ordered types,
+// this constraint will be modified to include them.
+//
+// Note that floating-point types may contain NaN ("not-a-number") values.
+// An operator such as == or < will always report false when
+// comparing a NaN value with any other value, NaN or not.
+// See the [Compare] function for a consistent way to compare NaN values.
+type Ordered interface {
+ ~int | ~int8 | ~int16 | ~int32 | ~int64 |
+ ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
+ ~float32 | ~float64 |
+ ~string
+}
+
+// Less reports whether x is less than y.
+// For floating-point types, a NaN is considered less than any non-NaN,
+// and -0.0 is not less than (is equal to) 0.0.
+func Less[T Ordered](x, y T) bool {
+ return (isNaN(x) && !isNaN(y)) || x < y
+}
+
+// Compare returns
+//
+// -1 if x is less than y,
+// 0 if x equals y,
+// +1 if x is greater than y.
+//
+// For floating-point types, a NaN is considered less than any non-NaN,
+// a NaN is considered equal to a NaN, and -0.0 is equal to 0.0.
+func Compare[T Ordered](x, y T) int {
+ xNaN := isNaN(x)
+ yNaN := isNaN(y)
+ if xNaN && yNaN {
+ return 0
+ }
+ if xNaN || x < y {
+ return -1
+ }
+ if yNaN || x > y {
+ return +1
+ }
+ return 0
+}
+
+// isNaN reports whether x is a NaN without requiring the math package.
+// This will always return false if T is not floating-point.
+func isNaN[T Ordered](x T) bool {
+ return x != x
+}
diff --git a/contrib/go/_std_1.21/src/cmp/ya.make b/contrib/go/_std_1.21/src/cmp/ya.make
new file mode 100644
index 0000000000..418258f050
--- /dev/null
+++ b/contrib/go/_std_1.21/src/cmp/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ cmp.go
+)
+
+GO_XTEST_SRCS(cmp_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/compress/flate/deflate.go b/contrib/go/_std_1.21/src/compress/flate/deflate.go
index b53764b552..b53764b552 100644
--- a/contrib/go/_std_1.20/src/compress/flate/deflate.go
+++ b/contrib/go/_std_1.21/src/compress/flate/deflate.go
diff --git a/contrib/go/_std_1.20/src/compress/flate/deflatefast.go b/contrib/go/_std_1.21/src/compress/flate/deflatefast.go
index 6aa439f13d..6aa439f13d 100644
--- a/contrib/go/_std_1.20/src/compress/flate/deflatefast.go
+++ b/contrib/go/_std_1.21/src/compress/flate/deflatefast.go
diff --git a/contrib/go/_std_1.20/src/compress/flate/dict_decoder.go b/contrib/go/_std_1.21/src/compress/flate/dict_decoder.go
index d2c19040f5..d2c19040f5 100644
--- a/contrib/go/_std_1.20/src/compress/flate/dict_decoder.go
+++ b/contrib/go/_std_1.21/src/compress/flate/dict_decoder.go
diff --git a/contrib/go/_std_1.20/src/compress/flate/huffman_bit_writer.go b/contrib/go/_std_1.21/src/compress/flate/huffman_bit_writer.go
index 005637557e..005637557e 100644
--- a/contrib/go/_std_1.20/src/compress/flate/huffman_bit_writer.go
+++ b/contrib/go/_std_1.21/src/compress/flate/huffman_bit_writer.go
diff --git a/contrib/go/_std_1.20/src/compress/flate/huffman_code.go b/contrib/go/_std_1.21/src/compress/flate/huffman_code.go
index ade4c8fb28..ade4c8fb28 100644
--- a/contrib/go/_std_1.20/src/compress/flate/huffman_code.go
+++ b/contrib/go/_std_1.21/src/compress/flate/huffman_code.go
diff --git a/contrib/go/_std_1.21/src/compress/flate/inflate.go b/contrib/go/_std_1.21/src/compress/flate/inflate.go
new file mode 100644
index 0000000000..d7375f2f1f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/compress/flate/inflate.go
@@ -0,0 +1,836 @@
+// Copyright 2009 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 flate implements the DEFLATE compressed data format, described in
+// RFC 1951. The gzip and zlib packages implement access to DEFLATE-based file
+// formats.
+package flate
+
+import (
+ "bufio"
+ "io"
+ "math/bits"
+ "strconv"
+ "sync"
+)
+
+const (
+ maxCodeLen = 16 // max length of Huffman code
+ // The next three numbers come from the RFC section 3.2.7, with the
+ // additional proviso in section 3.2.5 which implies that distance codes
+ // 30 and 31 should never occur in compressed data.
+ maxNumLit = 286
+ maxNumDist = 30
+ numCodes = 19 // number of codes in Huffman meta-code
+)
+
+// Initialize the fixedHuffmanDecoder only once upon first use.
+var fixedOnce sync.Once
+var fixedHuffmanDecoder huffmanDecoder
+
+// A CorruptInputError reports the presence of corrupt input at a given offset.
+type CorruptInputError int64
+
+func (e CorruptInputError) Error() string {
+ return "flate: corrupt input before offset " + strconv.FormatInt(int64(e), 10)
+}
+
+// An InternalError reports an error in the flate code itself.
+type InternalError string
+
+func (e InternalError) Error() string { return "flate: internal error: " + string(e) }
+
+// A ReadError reports an error encountered while reading input.
+//
+// Deprecated: No longer returned.
+type ReadError struct {
+ Offset int64 // byte offset where error occurred
+ Err error // error returned by underlying Read
+}
+
+func (e *ReadError) Error() string {
+ return "flate: read error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error()
+}
+
+// A WriteError reports an error encountered while writing output.
+//
+// Deprecated: No longer returned.
+type WriteError struct {
+ Offset int64 // byte offset where error occurred
+ Err error // error returned by underlying Write
+}
+
+func (e *WriteError) Error() string {
+ return "flate: write error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error()
+}
+
+// Resetter resets a ReadCloser returned by NewReader or NewReaderDict
+// to switch to a new underlying Reader. This permits reusing a ReadCloser
+// instead of allocating a new one.
+type Resetter interface {
+ // Reset discards any buffered data and resets the Resetter as if it was
+ // newly initialized with the given reader.
+ Reset(r io.Reader, dict []byte) error
+}
+
+// The data structure for decoding Huffman tables is based on that of
+// zlib. There is a lookup table of a fixed bit width (huffmanChunkBits),
+// For codes smaller than the table width, there are multiple entries
+// (each combination of trailing bits has the same value). For codes
+// larger than the table width, the table contains a link to an overflow
+// table. The width of each entry in the link table is the maximum code
+// size minus the chunk width.
+//
+// Note that you can do a lookup in the table even without all bits
+// filled. Since the extra bits are zero, and the DEFLATE Huffman codes
+// have the property that shorter codes come before longer ones, the
+// bit length estimate in the result is a lower bound on the actual
+// number of bits.
+//
+// See the following:
+// https://github.com/madler/zlib/raw/master/doc/algorithm.txt
+
+// chunk & 15 is number of bits
+// chunk >> 4 is value, including table link
+
+const (
+ huffmanChunkBits = 9
+ huffmanNumChunks = 1 << huffmanChunkBits
+ huffmanCountMask = 15
+ huffmanValueShift = 4
+)
+
+type huffmanDecoder struct {
+ min int // the minimum code length
+ chunks [huffmanNumChunks]uint32 // chunks as described above
+ links [][]uint32 // overflow links
+ linkMask uint32 // mask the width of the link table
+}
+
+// Initialize Huffman decoding tables from array of code lengths.
+// Following this function, h is guaranteed to be initialized into a complete
+// tree (i.e., neither over-subscribed nor under-subscribed). The exception is a
+// degenerate case where the tree has only a single symbol with length 1. Empty
+// trees are permitted.
+func (h *huffmanDecoder) init(lengths []int) bool {
+ // Sanity enables additional runtime tests during Huffman
+ // table construction. It's intended to be used during
+ // development to supplement the currently ad-hoc unit tests.
+ const sanity = false
+
+ if h.min != 0 {
+ *h = huffmanDecoder{}
+ }
+
+ // Count number of codes of each length,
+ // compute min and max length.
+ var count [maxCodeLen]int
+ var min, max int
+ for _, n := range lengths {
+ if n == 0 {
+ continue
+ }
+ if min == 0 || n < min {
+ min = n
+ }
+ if n > max {
+ max = n
+ }
+ count[n]++
+ }
+
+ // Empty tree. The decompressor.huffSym function will fail later if the tree
+ // is used. Technically, an empty tree is only valid for the HDIST tree and
+ // not the HCLEN and HLIT tree. However, a stream with an empty HCLEN tree
+ // is guaranteed to fail since it will attempt to use the tree to decode the
+ // codes for the HLIT and HDIST trees. Similarly, an empty HLIT tree is
+ // guaranteed to fail later since the compressed data section must be
+ // composed of at least one symbol (the end-of-block marker).
+ if max == 0 {
+ return true
+ }
+
+ code := 0
+ var nextcode [maxCodeLen]int
+ for i := min; i <= max; i++ {
+ code <<= 1
+ nextcode[i] = code
+ code += count[i]
+ }
+
+ // Check that the coding is complete (i.e., that we've
+ // assigned all 2-to-the-max possible bit sequences).
+ // Exception: To be compatible with zlib, we also need to
+ // accept degenerate single-code codings. See also
+ // TestDegenerateHuffmanCoding.
+ if code != 1<<uint(max) && !(code == 1 && max == 1) {
+ return false
+ }
+
+ h.min = min
+ if max > huffmanChunkBits {
+ numLinks := 1 << (uint(max) - huffmanChunkBits)
+ h.linkMask = uint32(numLinks - 1)
+
+ // create link tables
+ link := nextcode[huffmanChunkBits+1] >> 1
+ h.links = make([][]uint32, huffmanNumChunks-link)
+ for j := uint(link); j < huffmanNumChunks; j++ {
+ reverse := int(bits.Reverse16(uint16(j)))
+ reverse >>= uint(16 - huffmanChunkBits)
+ off := j - uint(link)
+ if sanity && h.chunks[reverse] != 0 {
+ panic("impossible: overwriting existing chunk")
+ }
+ h.chunks[reverse] = uint32(off<<huffmanValueShift | (huffmanChunkBits + 1))
+ h.links[off] = make([]uint32, numLinks)
+ }
+ }
+
+ for i, n := range lengths {
+ if n == 0 {
+ continue
+ }
+ code := nextcode[n]
+ nextcode[n]++
+ chunk := uint32(i<<huffmanValueShift | n)
+ reverse := int(bits.Reverse16(uint16(code)))
+ reverse >>= uint(16 - n)
+ if n <= huffmanChunkBits {
+ for off := reverse; off < len(h.chunks); off += 1 << uint(n) {
+ // We should never need to overwrite
+ // an existing chunk. Also, 0 is
+ // never a valid chunk, because the
+ // lower 4 "count" bits should be
+ // between 1 and 15.
+ if sanity && h.chunks[off] != 0 {
+ panic("impossible: overwriting existing chunk")
+ }
+ h.chunks[off] = chunk
+ }
+ } else {
+ j := reverse & (huffmanNumChunks - 1)
+ if sanity && h.chunks[j]&huffmanCountMask != huffmanChunkBits+1 {
+ // Longer codes should have been
+ // associated with a link table above.
+ panic("impossible: not an indirect chunk")
+ }
+ value := h.chunks[j] >> huffmanValueShift
+ linktab := h.links[value]
+ reverse >>= huffmanChunkBits
+ for off := reverse; off < len(linktab); off += 1 << uint(n-huffmanChunkBits) {
+ if sanity && linktab[off] != 0 {
+ panic("impossible: overwriting existing chunk")
+ }
+ linktab[off] = chunk
+ }
+ }
+ }
+
+ if sanity {
+ // Above we've sanity checked that we never overwrote
+ // an existing entry. Here we additionally check that
+ // we filled the tables completely.
+ for i, chunk := range h.chunks {
+ if chunk == 0 {
+ // As an exception, in the degenerate
+ // single-code case, we allow odd
+ // chunks to be missing.
+ if code == 1 && i%2 == 1 {
+ continue
+ }
+ panic("impossible: missing chunk")
+ }
+ }
+ for _, linktab := range h.links {
+ for _, chunk := range linktab {
+ if chunk == 0 {
+ panic("impossible: missing chunk")
+ }
+ }
+ }
+ }
+
+ return true
+}
+
+// The actual read interface needed by NewReader.
+// If the passed in io.Reader does not also have ReadByte,
+// the NewReader will introduce its own buffering.
+type Reader interface {
+ io.Reader
+ io.ByteReader
+}
+
+// Decompress state.
+type decompressor struct {
+ // Input source.
+ r Reader
+ rBuf *bufio.Reader // created if provided io.Reader does not implement io.ByteReader
+ roffset int64
+
+ // Input bits, in top of b.
+ b uint32
+ nb uint
+
+ // Huffman decoders for literal/length, distance.
+ h1, h2 huffmanDecoder
+
+ // Length arrays used to define Huffman codes.
+ bits *[maxNumLit + maxNumDist]int
+ codebits *[numCodes]int
+
+ // Output history, buffer.
+ dict dictDecoder
+
+ // Temporary buffer (avoids repeated allocation).
+ buf [4]byte
+
+ // Next step in the decompression,
+ // and decompression state.
+ step func(*decompressor)
+ stepState int
+ final bool
+ err error
+ toRead []byte
+ hl, hd *huffmanDecoder
+ copyLen int
+ copyDist int
+}
+
+func (f *decompressor) nextBlock() {
+ for f.nb < 1+2 {
+ if f.err = f.moreBits(); f.err != nil {
+ return
+ }
+ }
+ f.final = f.b&1 == 1
+ f.b >>= 1
+ typ := f.b & 3
+ f.b >>= 2
+ f.nb -= 1 + 2
+ switch typ {
+ case 0:
+ f.dataBlock()
+ case 1:
+ // compressed, fixed Huffman tables
+ f.hl = &fixedHuffmanDecoder
+ f.hd = nil
+ f.huffmanBlock()
+ case 2:
+ // compressed, dynamic Huffman tables
+ if f.err = f.readHuffman(); f.err != nil {
+ break
+ }
+ f.hl = &f.h1
+ f.hd = &f.h2
+ f.huffmanBlock()
+ default:
+ // 3 is reserved.
+ f.err = CorruptInputError(f.roffset)
+ }
+}
+
+func (f *decompressor) Read(b []byte) (int, error) {
+ for {
+ if len(f.toRead) > 0 {
+ n := copy(b, f.toRead)
+ f.toRead = f.toRead[n:]
+ if len(f.toRead) == 0 {
+ return n, f.err
+ }
+ return n, nil
+ }
+ if f.err != nil {
+ return 0, f.err
+ }
+ f.step(f)
+ if f.err != nil && len(f.toRead) == 0 {
+ f.toRead = f.dict.readFlush() // Flush what's left in case of error
+ }
+ }
+}
+
+func (f *decompressor) Close() error {
+ if f.err == io.EOF {
+ return nil
+ }
+ return f.err
+}
+
+// RFC 1951 section 3.2.7.
+// Compression with dynamic Huffman codes
+
+var codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
+
+func (f *decompressor) readHuffman() error {
+ // HLIT[5], HDIST[5], HCLEN[4].
+ for f.nb < 5+5+4 {
+ if err := f.moreBits(); err != nil {
+ return err
+ }
+ }
+ nlit := int(f.b&0x1F) + 257
+ if nlit > maxNumLit {
+ return CorruptInputError(f.roffset)
+ }
+ f.b >>= 5
+ ndist := int(f.b&0x1F) + 1
+ if ndist > maxNumDist {
+ return CorruptInputError(f.roffset)
+ }
+ f.b >>= 5
+ nclen := int(f.b&0xF) + 4
+ // numCodes is 19, so nclen is always valid.
+ f.b >>= 4
+ f.nb -= 5 + 5 + 4
+
+ // (HCLEN+4)*3 bits: code lengths in the magic codeOrder order.
+ for i := 0; i < nclen; i++ {
+ for f.nb < 3 {
+ if err := f.moreBits(); err != nil {
+ return err
+ }
+ }
+ f.codebits[codeOrder[i]] = int(f.b & 0x7)
+ f.b >>= 3
+ f.nb -= 3
+ }
+ for i := nclen; i < len(codeOrder); i++ {
+ f.codebits[codeOrder[i]] = 0
+ }
+ if !f.h1.init(f.codebits[0:]) {
+ return CorruptInputError(f.roffset)
+ }
+
+ // HLIT + 257 code lengths, HDIST + 1 code lengths,
+ // using the code length Huffman code.
+ for i, n := 0, nlit+ndist; i < n; {
+ x, err := f.huffSym(&f.h1)
+ if err != nil {
+ return err
+ }
+ if x < 16 {
+ // Actual length.
+ f.bits[i] = x
+ i++
+ continue
+ }
+ // Repeat previous length or zero.
+ var rep int
+ var nb uint
+ var b int
+ switch x {
+ default:
+ return InternalError("unexpected length code")
+ case 16:
+ rep = 3
+ nb = 2
+ if i == 0 {
+ return CorruptInputError(f.roffset)
+ }
+ b = f.bits[i-1]
+ case 17:
+ rep = 3
+ nb = 3
+ b = 0
+ case 18:
+ rep = 11
+ nb = 7
+ b = 0
+ }
+ for f.nb < nb {
+ if err := f.moreBits(); err != nil {
+ return err
+ }
+ }
+ rep += int(f.b & uint32(1<<nb-1))
+ f.b >>= nb
+ f.nb -= nb
+ if i+rep > n {
+ return CorruptInputError(f.roffset)
+ }
+ for j := 0; j < rep; j++ {
+ f.bits[i] = b
+ i++
+ }
+ }
+
+ if !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) {
+ return CorruptInputError(f.roffset)
+ }
+
+ // As an optimization, we can initialize the min bits to read at a time
+ // for the HLIT tree to the length of the EOB marker since we know that
+ // every block must terminate with one. This preserves the property that
+ // we never read any extra bytes after the end of the DEFLATE stream.
+ if f.h1.min < f.bits[endBlockMarker] {
+ f.h1.min = f.bits[endBlockMarker]
+ }
+
+ return nil
+}
+
+// Decode a single Huffman block from f.
+// hl and hd are the Huffman states for the lit/length values
+// and the distance values, respectively. If hd == nil, using the
+// fixed distance encoding associated with fixed Huffman blocks.
+func (f *decompressor) huffmanBlock() {
+ const (
+ stateInit = iota // Zero value must be stateInit
+ stateDict
+ )
+
+ switch f.stepState {
+ case stateInit:
+ goto readLiteral
+ case stateDict:
+ goto copyHistory
+ }
+
+readLiteral:
+ // Read literal and/or (length, distance) according to RFC section 3.2.3.
+ {
+ v, err := f.huffSym(f.hl)
+ if err != nil {
+ f.err = err
+ return
+ }
+ var n uint // number of bits extra
+ var length int
+ switch {
+ case v < 256:
+ f.dict.writeByte(byte(v))
+ if f.dict.availWrite() == 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).huffmanBlock
+ f.stepState = stateInit
+ return
+ }
+ goto readLiteral
+ case v == 256:
+ f.finishBlock()
+ return
+ // otherwise, reference to older data
+ case v < 265:
+ length = v - (257 - 3)
+ n = 0
+ case v < 269:
+ length = v*2 - (265*2 - 11)
+ n = 1
+ case v < 273:
+ length = v*4 - (269*4 - 19)
+ n = 2
+ case v < 277:
+ length = v*8 - (273*8 - 35)
+ n = 3
+ case v < 281:
+ length = v*16 - (277*16 - 67)
+ n = 4
+ case v < 285:
+ length = v*32 - (281*32 - 131)
+ n = 5
+ case v < maxNumLit:
+ length = 258
+ n = 0
+ default:
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+ if n > 0 {
+ for f.nb < n {
+ if err = f.moreBits(); err != nil {
+ f.err = err
+ return
+ }
+ }
+ length += int(f.b & uint32(1<<n-1))
+ f.b >>= n
+ f.nb -= n
+ }
+
+ var dist int
+ if f.hd == nil {
+ for f.nb < 5 {
+ if err = f.moreBits(); err != nil {
+ f.err = err
+ return
+ }
+ }
+ dist = int(bits.Reverse8(uint8(f.b & 0x1F << 3)))
+ f.b >>= 5
+ f.nb -= 5
+ } else {
+ if dist, err = f.huffSym(f.hd); err != nil {
+ f.err = err
+ return
+ }
+ }
+
+ switch {
+ case dist < 4:
+ dist++
+ case dist < maxNumDist:
+ nb := uint(dist-2) >> 1
+ // have 1 bit in bottom of dist, need nb more.
+ extra := (dist & 1) << nb
+ for f.nb < nb {
+ if err = f.moreBits(); err != nil {
+ f.err = err
+ return
+ }
+ }
+ extra |= int(f.b & uint32(1<<nb-1))
+ f.b >>= nb
+ f.nb -= nb
+ dist = 1<<(nb+1) + 1 + extra
+ default:
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ // No check on length; encoding can be prescient.
+ if dist > f.dict.histSize() {
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ f.copyLen, f.copyDist = length, dist
+ goto copyHistory
+ }
+
+copyHistory:
+ // Perform a backwards copy according to RFC section 3.2.3.
+ {
+ cnt := f.dict.tryWriteCopy(f.copyDist, f.copyLen)
+ if cnt == 0 {
+ cnt = f.dict.writeCopy(f.copyDist, f.copyLen)
+ }
+ f.copyLen -= cnt
+
+ if f.dict.availWrite() == 0 || f.copyLen > 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).huffmanBlock // We need to continue this work
+ f.stepState = stateDict
+ return
+ }
+ goto readLiteral
+ }
+}
+
+// Copy a single uncompressed data block from input to output.
+func (f *decompressor) dataBlock() {
+ // Uncompressed.
+ // Discard current half-byte.
+ f.nb = 0
+ f.b = 0
+
+ // Length then ones-complement of length.
+ nr, err := io.ReadFull(f.r, f.buf[0:4])
+ f.roffset += int64(nr)
+ if err != nil {
+ f.err = noEOF(err)
+ return
+ }
+ n := int(f.buf[0]) | int(f.buf[1])<<8
+ nn := int(f.buf[2]) | int(f.buf[3])<<8
+ if uint16(nn) != uint16(^n) {
+ f.err = CorruptInputError(f.roffset)
+ return
+ }
+
+ if n == 0 {
+ f.toRead = f.dict.readFlush()
+ f.finishBlock()
+ return
+ }
+
+ f.copyLen = n
+ f.copyData()
+}
+
+// copyData copies f.copyLen bytes from the underlying reader into f.hist.
+// It pauses for reads when f.hist is full.
+func (f *decompressor) copyData() {
+ buf := f.dict.writeSlice()
+ if len(buf) > f.copyLen {
+ buf = buf[:f.copyLen]
+ }
+
+ cnt, err := io.ReadFull(f.r, buf)
+ f.roffset += int64(cnt)
+ f.copyLen -= cnt
+ f.dict.writeMark(cnt)
+ if err != nil {
+ f.err = noEOF(err)
+ return
+ }
+
+ if f.dict.availWrite() == 0 || f.copyLen > 0 {
+ f.toRead = f.dict.readFlush()
+ f.step = (*decompressor).copyData
+ return
+ }
+ f.finishBlock()
+}
+
+func (f *decompressor) finishBlock() {
+ if f.final {
+ if f.dict.availRead() > 0 {
+ f.toRead = f.dict.readFlush()
+ }
+ f.err = io.EOF
+ }
+ f.step = (*decompressor).nextBlock
+}
+
+// noEOF returns err, unless err == io.EOF, in which case it returns io.ErrUnexpectedEOF.
+func noEOF(e error) error {
+ if e == io.EOF {
+ return io.ErrUnexpectedEOF
+ }
+ return e
+}
+
+func (f *decompressor) moreBits() error {
+ c, err := f.r.ReadByte()
+ if err != nil {
+ return noEOF(err)
+ }
+ f.roffset++
+ f.b |= uint32(c) << f.nb
+ f.nb += 8
+ return nil
+}
+
+// Read the next Huffman-encoded symbol from f according to h.
+func (f *decompressor) huffSym(h *huffmanDecoder) (int, error) {
+ // Since a huffmanDecoder can be empty or be composed of a degenerate tree
+ // with single element, huffSym must error on these two edge cases. In both
+ // cases, the chunks slice will be 0 for the invalid sequence, leading it
+ // satisfy the n == 0 check below.
+ n := uint(h.min)
+ // Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,
+ // but is smart enough to keep local variables in registers, so use nb and b,
+ // inline call to moreBits and reassign b,nb back to f on return.
+ nb, b := f.nb, f.b
+ for {
+ for nb < n {
+ c, err := f.r.ReadByte()
+ if err != nil {
+ f.b = b
+ f.nb = nb
+ return 0, noEOF(err)
+ }
+ f.roffset++
+ b |= uint32(c) << (nb & 31)
+ nb += 8
+ }
+ chunk := h.chunks[b&(huffmanNumChunks-1)]
+ n = uint(chunk & huffmanCountMask)
+ if n > huffmanChunkBits {
+ chunk = h.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&h.linkMask]
+ n = uint(chunk & huffmanCountMask)
+ }
+ if n <= nb {
+ if n == 0 {
+ f.b = b
+ f.nb = nb
+ f.err = CorruptInputError(f.roffset)
+ return 0, f.err
+ }
+ f.b = b >> (n & 31)
+ f.nb = nb - n
+ return int(chunk >> huffmanValueShift), nil
+ }
+ }
+}
+
+func (f *decompressor) makeReader(r io.Reader) {
+ if rr, ok := r.(Reader); ok {
+ f.rBuf = nil
+ f.r = rr
+ return
+ }
+ // Reuse rBuf if possible. Invariant: rBuf is always created (and owned) by decompressor.
+ if f.rBuf != nil {
+ f.rBuf.Reset(r)
+ } else {
+ // bufio.NewReader will not return r, as r does not implement flate.Reader, so it is not bufio.Reader.
+ f.rBuf = bufio.NewReader(r)
+ }
+ f.r = f.rBuf
+}
+
+func fixedHuffmanDecoderInit() {
+ fixedOnce.Do(func() {
+ // These come from the RFC section 3.2.6.
+ var bits [288]int
+ for i := 0; i < 144; i++ {
+ bits[i] = 8
+ }
+ for i := 144; i < 256; i++ {
+ bits[i] = 9
+ }
+ for i := 256; i < 280; i++ {
+ bits[i] = 7
+ }
+ for i := 280; i < 288; i++ {
+ bits[i] = 8
+ }
+ fixedHuffmanDecoder.init(bits[:])
+ })
+}
+
+func (f *decompressor) Reset(r io.Reader, dict []byte) error {
+ *f = decompressor{
+ rBuf: f.rBuf,
+ bits: f.bits,
+ codebits: f.codebits,
+ dict: f.dict,
+ step: (*decompressor).nextBlock,
+ }
+ f.makeReader(r)
+ f.dict.init(maxMatchOffset, dict)
+ return nil
+}
+
+// NewReader returns a new ReadCloser that can be used
+// to read the uncompressed version of r.
+// If r does not also implement io.ByteReader,
+// the decompressor may read more data than necessary from r.
+// The reader returns io.EOF after the final block in the DEFLATE stream has
+// been encountered. Any trailing data after the final block is ignored.
+//
+// The ReadCloser returned by NewReader also implements Resetter.
+func NewReader(r io.Reader) io.ReadCloser {
+ fixedHuffmanDecoderInit()
+
+ var f decompressor
+ f.makeReader(r)
+ f.bits = new([maxNumLit + maxNumDist]int)
+ f.codebits = new([numCodes]int)
+ f.step = (*decompressor).nextBlock
+ f.dict.init(maxMatchOffset, nil)
+ return &f
+}
+
+// NewReaderDict is like NewReader but initializes the reader
+// with a preset dictionary. The returned Reader behaves as if
+// the uncompressed data stream started with the given dictionary,
+// which has already been read. NewReaderDict is typically used
+// to read data compressed by NewWriterDict.
+//
+// The ReadCloser returned by NewReader also implements Resetter.
+func NewReaderDict(r io.Reader, dict []byte) io.ReadCloser {
+ fixedHuffmanDecoderInit()
+
+ var f decompressor
+ f.makeReader(r)
+ f.bits = new([maxNumLit + maxNumDist]int)
+ f.codebits = new([numCodes]int)
+ f.step = (*decompressor).nextBlock
+ f.dict.init(maxMatchOffset, dict)
+ return &f
+}
diff --git a/contrib/go/_std_1.20/src/compress/flate/token.go b/contrib/go/_std_1.21/src/compress/flate/token.go
index fc0e4941e7..fc0e4941e7 100644
--- a/contrib/go/_std_1.20/src/compress/flate/token.go
+++ b/contrib/go/_std_1.21/src/compress/flate/token.go
diff --git a/contrib/go/_std_1.21/src/compress/flate/ya.make b/contrib/go/_std_1.21/src/compress/flate/ya.make
new file mode 100644
index 0000000000..163761b9e2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/compress/flate/ya.make
@@ -0,0 +1,28 @@
+GO_LIBRARY()
+
+SRCS(
+ deflate.go
+ deflatefast.go
+ dict_decoder.go
+ huffman_bit_writer.go
+ huffman_code.go
+ inflate.go
+ token.go
+)
+
+GO_TEST_SRCS(
+ deflate_test.go
+ dict_decoder_test.go
+ flate_test.go
+ huffman_bit_writer_test.go
+ inflate_test.go
+ reader_test.go
+ writer_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/compress/gzip/gunzip.go b/contrib/go/_std_1.21/src/compress/gzip/gunzip.go
index ba8de97e6a..ba8de97e6a 100644
--- a/contrib/go/_std_1.20/src/compress/gzip/gunzip.go
+++ b/contrib/go/_std_1.21/src/compress/gzip/gunzip.go
diff --git a/contrib/go/_std_1.20/src/compress/gzip/gzip.go b/contrib/go/_std_1.21/src/compress/gzip/gzip.go
index eaeb185795..eaeb185795 100644
--- a/contrib/go/_std_1.20/src/compress/gzip/gzip.go
+++ b/contrib/go/_std_1.21/src/compress/gzip/gzip.go
diff --git a/contrib/go/_std_1.21/src/compress/gzip/ya.make b/contrib/go/_std_1.21/src/compress/gzip/ya.make
new file mode 100644
index 0000000000..5666a544f9
--- /dev/null
+++ b/contrib/go/_std_1.21/src/compress/gzip/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ gunzip.go
+ gzip.go
+)
+
+GO_TEST_SRCS(
+ fuzz_test.go
+ gunzip_test.go
+ gzip_test.go
+ issue14937_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/compress/zlib/reader.go b/contrib/go/_std_1.21/src/compress/zlib/reader.go
new file mode 100644
index 0000000000..10954eaad7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/compress/zlib/reader.go
@@ -0,0 +1,181 @@
+// Copyright 2009 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 zlib implements reading and writing of zlib format compressed data,
+as specified in RFC 1950.
+
+The implementation provides filters that uncompress during reading
+and compress during writing. For example, to write compressed data
+to a buffer:
+
+ var b bytes.Buffer
+ w := zlib.NewWriter(&b)
+ w.Write([]byte("hello, world\n"))
+ w.Close()
+
+and to read that data back:
+
+ r, err := zlib.NewReader(&b)
+ io.Copy(os.Stdout, r)
+ r.Close()
+*/
+package zlib
+
+import (
+ "bufio"
+ "compress/flate"
+ "encoding/binary"
+ "errors"
+ "hash"
+ "hash/adler32"
+ "io"
+)
+
+const (
+ zlibDeflate = 8
+ zlibMaxWindow = 7
+)
+
+var (
+ // ErrChecksum is returned when reading ZLIB data that has an invalid checksum.
+ ErrChecksum = errors.New("zlib: invalid checksum")
+ // ErrDictionary is returned when reading ZLIB data that has an invalid dictionary.
+ ErrDictionary = errors.New("zlib: invalid dictionary")
+ // ErrHeader is returned when reading ZLIB data that has an invalid header.
+ ErrHeader = errors.New("zlib: invalid header")
+)
+
+type reader struct {
+ r flate.Reader
+ decompressor io.ReadCloser
+ digest hash.Hash32
+ err error
+ scratch [4]byte
+}
+
+// Resetter resets a ReadCloser returned by NewReader or NewReaderDict
+// to switch to a new underlying Reader. This permits reusing a ReadCloser
+// instead of allocating a new one.
+type Resetter interface {
+ // Reset discards any buffered data and resets the Resetter as if it was
+ // newly initialized with the given reader.
+ Reset(r io.Reader, dict []byte) error
+}
+
+// NewReader creates a new ReadCloser.
+// Reads from the returned ReadCloser read and decompress data from r.
+// If r does not implement io.ByteReader, the decompressor may read more
+// data than necessary from r.
+// It is the caller's responsibility to call Close on the ReadCloser when done.
+//
+// The ReadCloser returned by NewReader also implements Resetter.
+func NewReader(r io.Reader) (io.ReadCloser, error) {
+ return NewReaderDict(r, nil)
+}
+
+// NewReaderDict is like NewReader but uses a preset dictionary.
+// NewReaderDict ignores the dictionary if the compressed data does not refer to it.
+// If the compressed data refers to a different dictionary, NewReaderDict returns ErrDictionary.
+//
+// The ReadCloser returned by NewReaderDict also implements Resetter.
+func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error) {
+ z := new(reader)
+ err := z.Reset(r, dict)
+ if err != nil {
+ return nil, err
+ }
+ return z, nil
+}
+
+func (z *reader) Read(p []byte) (int, error) {
+ if z.err != nil {
+ return 0, z.err
+ }
+
+ var n int
+ n, z.err = z.decompressor.Read(p)
+ z.digest.Write(p[0:n])
+ if z.err != io.EOF {
+ // In the normal case we return here.
+ return n, z.err
+ }
+
+ // Finished file; check checksum.
+ if _, err := io.ReadFull(z.r, z.scratch[0:4]); err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ z.err = err
+ return n, z.err
+ }
+ // ZLIB (RFC 1950) is big-endian, unlike GZIP (RFC 1952).
+ checksum := binary.BigEndian.Uint32(z.scratch[:4])
+ if checksum != z.digest.Sum32() {
+ z.err = ErrChecksum
+ return n, z.err
+ }
+ return n, io.EOF
+}
+
+// Calling Close does not close the wrapped io.Reader originally passed to NewReader.
+// In order for the ZLIB checksum to be verified, the reader must be
+// fully consumed until the io.EOF.
+func (z *reader) Close() error {
+ if z.err != nil && z.err != io.EOF {
+ return z.err
+ }
+ z.err = z.decompressor.Close()
+ return z.err
+}
+
+func (z *reader) Reset(r io.Reader, dict []byte) error {
+ *z = reader{decompressor: z.decompressor}
+ if fr, ok := r.(flate.Reader); ok {
+ z.r = fr
+ } else {
+ z.r = bufio.NewReader(r)
+ }
+
+ // Read the header (RFC 1950 section 2.2.).
+ _, z.err = io.ReadFull(z.r, z.scratch[0:2])
+ if z.err != nil {
+ if z.err == io.EOF {
+ z.err = io.ErrUnexpectedEOF
+ }
+ return z.err
+ }
+ h := binary.BigEndian.Uint16(z.scratch[:2])
+ if (z.scratch[0]&0x0f != zlibDeflate) || (z.scratch[0]>>4 > zlibMaxWindow) || (h%31 != 0) {
+ z.err = ErrHeader
+ return z.err
+ }
+ haveDict := z.scratch[1]&0x20 != 0
+ if haveDict {
+ _, z.err = io.ReadFull(z.r, z.scratch[0:4])
+ if z.err != nil {
+ if z.err == io.EOF {
+ z.err = io.ErrUnexpectedEOF
+ }
+ return z.err
+ }
+ checksum := binary.BigEndian.Uint32(z.scratch[:4])
+ if checksum != adler32.Checksum(dict) {
+ z.err = ErrDictionary
+ return z.err
+ }
+ }
+
+ if z.decompressor == nil {
+ if haveDict {
+ z.decompressor = flate.NewReaderDict(z.r, dict)
+ } else {
+ z.decompressor = flate.NewReader(z.r)
+ }
+ } else {
+ z.decompressor.(flate.Resetter).Reset(z.r, dict)
+ }
+ z.digest = adler32.New()
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/compress/zlib/writer.go b/contrib/go/_std_1.21/src/compress/zlib/writer.go
new file mode 100644
index 0000000000..c65e80f742
--- /dev/null
+++ b/contrib/go/_std_1.21/src/compress/zlib/writer.go
@@ -0,0 +1,193 @@
+// Copyright 2009 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 zlib
+
+import (
+ "compress/flate"
+ "encoding/binary"
+ "fmt"
+ "hash"
+ "hash/adler32"
+ "io"
+)
+
+// These constants are copied from the flate package, so that code that imports
+// "compress/zlib" does not also have to import "compress/flate".
+const (
+ NoCompression = flate.NoCompression
+ BestSpeed = flate.BestSpeed
+ BestCompression = flate.BestCompression
+ DefaultCompression = flate.DefaultCompression
+ HuffmanOnly = flate.HuffmanOnly
+)
+
+// A Writer takes data written to it and writes the compressed
+// form of that data to an underlying writer (see NewWriter).
+type Writer struct {
+ w io.Writer
+ level int
+ dict []byte
+ compressor *flate.Writer
+ digest hash.Hash32
+ err error
+ scratch [4]byte
+ wroteHeader bool
+}
+
+// NewWriter creates a new Writer.
+// Writes to the returned Writer are compressed and written to w.
+//
+// It is the caller's responsibility to call Close on the Writer when done.
+// Writes may be buffered and not flushed until Close.
+func NewWriter(w io.Writer) *Writer {
+ z, _ := NewWriterLevelDict(w, DefaultCompression, nil)
+ return z
+}
+
+// NewWriterLevel is like NewWriter but specifies the compression level instead
+// of assuming DefaultCompression.
+//
+// The compression level can be DefaultCompression, NoCompression, HuffmanOnly
+// or any integer value between BestSpeed and BestCompression inclusive.
+// The error returned will be nil if the level is valid.
+func NewWriterLevel(w io.Writer, level int) (*Writer, error) {
+ return NewWriterLevelDict(w, level, nil)
+}
+
+// NewWriterLevelDict is like NewWriterLevel but specifies a dictionary to
+// compress with.
+//
+// The dictionary may be nil. If not, its contents should not be modified until
+// the Writer is closed.
+func NewWriterLevelDict(w io.Writer, level int, dict []byte) (*Writer, error) {
+ if level < HuffmanOnly || level > BestCompression {
+ return nil, fmt.Errorf("zlib: invalid compression level: %d", level)
+ }
+ return &Writer{
+ w: w,
+ level: level,
+ dict: dict,
+ }, nil
+}
+
+// Reset clears the state of the Writer z such that it is equivalent to its
+// initial state from NewWriterLevel or NewWriterLevelDict, but instead writing
+// to w.
+func (z *Writer) Reset(w io.Writer) {
+ z.w = w
+ // z.level and z.dict left unchanged.
+ if z.compressor != nil {
+ z.compressor.Reset(w)
+ }
+ if z.digest != nil {
+ z.digest.Reset()
+ }
+ z.err = nil
+ z.scratch = [4]byte{}
+ z.wroteHeader = false
+}
+
+// writeHeader writes the ZLIB header.
+func (z *Writer) writeHeader() (err error) {
+ z.wroteHeader = true
+ // ZLIB has a two-byte header (as documented in RFC 1950).
+ // The first four bits is the CINFO (compression info), which is 7 for the default deflate window size.
+ // The next four bits is the CM (compression method), which is 8 for deflate.
+ z.scratch[0] = 0x78
+ // The next two bits is the FLEVEL (compression level). The four values are:
+ // 0=fastest, 1=fast, 2=default, 3=best.
+ // The next bit, FDICT, is set if a dictionary is given.
+ // The final five FCHECK bits form a mod-31 checksum.
+ switch z.level {
+ case -2, 0, 1:
+ z.scratch[1] = 0 << 6
+ case 2, 3, 4, 5:
+ z.scratch[1] = 1 << 6
+ case 6, -1:
+ z.scratch[1] = 2 << 6
+ case 7, 8, 9:
+ z.scratch[1] = 3 << 6
+ default:
+ panic("unreachable")
+ }
+ if z.dict != nil {
+ z.scratch[1] |= 1 << 5
+ }
+ z.scratch[1] += uint8(31 - binary.BigEndian.Uint16(z.scratch[:2])%31)
+ if _, err = z.w.Write(z.scratch[0:2]); err != nil {
+ return err
+ }
+ if z.dict != nil {
+ // The next four bytes are the Adler-32 checksum of the dictionary.
+ binary.BigEndian.PutUint32(z.scratch[:], adler32.Checksum(z.dict))
+ if _, err = z.w.Write(z.scratch[0:4]); err != nil {
+ return err
+ }
+ }
+ if z.compressor == nil {
+ // Initialize deflater unless the Writer is being reused
+ // after a Reset call.
+ z.compressor, err = flate.NewWriterDict(z.w, z.level, z.dict)
+ if err != nil {
+ return err
+ }
+ z.digest = adler32.New()
+ }
+ return nil
+}
+
+// Write writes a compressed form of p to the underlying io.Writer. The
+// compressed bytes are not necessarily flushed until the Writer is closed or
+// explicitly flushed.
+func (z *Writer) Write(p []byte) (n int, err error) {
+ if !z.wroteHeader {
+ z.err = z.writeHeader()
+ }
+ if z.err != nil {
+ return 0, z.err
+ }
+ if len(p) == 0 {
+ return 0, nil
+ }
+ n, err = z.compressor.Write(p)
+ if err != nil {
+ z.err = err
+ return
+ }
+ z.digest.Write(p)
+ return
+}
+
+// Flush flushes the Writer to its underlying io.Writer.
+func (z *Writer) Flush() error {
+ if !z.wroteHeader {
+ z.err = z.writeHeader()
+ }
+ if z.err != nil {
+ return z.err
+ }
+ z.err = z.compressor.Flush()
+ return z.err
+}
+
+// Close closes the Writer, flushing any unwritten data to the underlying
+// io.Writer, but does not close the underlying io.Writer.
+func (z *Writer) Close() error {
+ if !z.wroteHeader {
+ z.err = z.writeHeader()
+ }
+ if z.err != nil {
+ return z.err
+ }
+ z.err = z.compressor.Close()
+ if z.err != nil {
+ return z.err
+ }
+ checksum := z.digest.Sum32()
+ // ZLIB (RFC 1950) is big-endian, unlike GZIP (RFC 1952).
+ binary.BigEndian.PutUint32(z.scratch[:], checksum)
+ _, z.err = z.w.Write(z.scratch[0:4])
+ return z.err
+}
diff --git a/contrib/go/_std_1.21/src/compress/zlib/ya.make b/contrib/go/_std_1.21/src/compress/zlib/ya.make
new file mode 100644
index 0000000000..e2ae04e06e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/compress/zlib/ya.make
@@ -0,0 +1,18 @@
+GO_LIBRARY()
+
+SRCS(
+ reader.go
+ writer.go
+)
+
+GO_TEST_SRCS(
+ reader_test.go
+ writer_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/container/heap/heap.go b/contrib/go/_std_1.21/src/container/heap/heap.go
index 27de11e19e..27de11e19e 100644
--- a/contrib/go/_std_1.20/src/container/heap/heap.go
+++ b/contrib/go/_std_1.21/src/container/heap/heap.go
diff --git a/contrib/go/_std_1.21/src/container/heap/ya.make b/contrib/go/_std_1.21/src/container/heap/ya.make
new file mode 100644
index 0000000000..75dd72bcd5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/container/heap/ya.make
@@ -0,0 +1,17 @@
+GO_LIBRARY()
+
+SRCS(
+ heap.go
+)
+
+GO_TEST_SRCS(heap_test.go)
+
+GO_XTEST_SRCS(
+ example_intheap_test.go
+ example_pq_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/container/list/list.go b/contrib/go/_std_1.21/src/container/list/list.go
index f2d77f0560..f2d77f0560 100644
--- a/contrib/go/_std_1.20/src/container/list/list.go
+++ b/contrib/go/_std_1.21/src/container/list/list.go
diff --git a/contrib/go/_std_1.21/src/container/list/ya.make b/contrib/go/_std_1.21/src/container/list/ya.make
new file mode 100644
index 0000000000..79383165e4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/container/list/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ list.go
+)
+
+GO_TEST_SRCS(list_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/context/context.go b/contrib/go/_std_1.21/src/context/context.go
new file mode 100644
index 0000000000..ee66b43c85
--- /dev/null
+++ b/contrib/go/_std_1.21/src/context/context.go
@@ -0,0 +1,785 @@
+// Copyright 2014 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 context defines the Context type, which carries deadlines,
+// cancellation signals, and other request-scoped values across API boundaries
+// and between processes.
+//
+// Incoming requests to a server should create a [Context], and outgoing
+// calls to servers should accept a Context. The chain of function
+// calls between them must propagate the Context, optionally replacing
+// it with a derived Context created using [WithCancel], [WithDeadline],
+// [WithTimeout], or [WithValue]. When a Context is canceled, all
+// Contexts derived from it are also canceled.
+//
+// The [WithCancel], [WithDeadline], and [WithTimeout] functions take a
+// Context (the parent) and return a derived Context (the child) and a
+// [CancelFunc]. Calling the CancelFunc cancels the child and its
+// children, removes the parent's reference to the child, and stops
+// any associated timers. Failing to call the CancelFunc leaks the
+// child and its children until the parent is canceled or the timer
+// fires. The go vet tool checks that CancelFuncs are used on all
+// control-flow paths.
+//
+// The [WithCancelCause] function returns a [CancelCauseFunc], which
+// takes an error and records it as the cancellation cause. Calling
+// [Cause] on the canceled context or any of its children retrieves
+// the cause. If no cause is specified, Cause(ctx) returns the same
+// value as ctx.Err().
+//
+// Programs that use Contexts should follow these rules to keep interfaces
+// consistent across packages and enable static analysis tools to check context
+// propagation:
+//
+// Do not store Contexts inside a struct type; instead, pass a Context
+// explicitly to each function that needs it. The Context should be the first
+// parameter, typically named ctx:
+//
+// func DoSomething(ctx context.Context, arg Arg) error {
+// // ... use ctx ...
+// }
+//
+// Do not pass a nil [Context], even if a function permits it. Pass [context.TODO]
+// if you are unsure about which Context to use.
+//
+// Use context Values only for request-scoped data that transits processes and
+// APIs, not for passing optional parameters to functions.
+//
+// The same Context may be passed to functions running in different goroutines;
+// Contexts are safe for simultaneous use by multiple goroutines.
+//
+// See https://blog.golang.org/context for example code for a server that uses
+// Contexts.
+package context
+
+import (
+ "errors"
+ "internal/reflectlite"
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+// A Context carries a deadline, a cancellation signal, and other values across
+// API boundaries.
+//
+// Context's methods may be called by multiple goroutines simultaneously.
+type Context interface {
+ // Deadline returns the time when work done on behalf of this context
+ // should be canceled. Deadline returns ok==false when no deadline is
+ // set. Successive calls to Deadline return the same results.
+ Deadline() (deadline time.Time, ok bool)
+
+ // Done returns a channel that's closed when work done on behalf of this
+ // context should be canceled. Done may return nil if this context can
+ // never be canceled. Successive calls to Done return the same value.
+ // The close of the Done channel may happen asynchronously,
+ // after the cancel function returns.
+ //
+ // WithCancel arranges for Done to be closed when cancel is called;
+ // WithDeadline arranges for Done to be closed when the deadline
+ // expires; WithTimeout arranges for Done to be closed when the timeout
+ // elapses.
+ //
+ // Done is provided for use in select statements:
+ //
+ // // Stream generates values with DoSomething and sends them to out
+ // // until DoSomething returns an error or ctx.Done is closed.
+ // func Stream(ctx context.Context, out chan<- Value) error {
+ // for {
+ // v, err := DoSomething(ctx)
+ // if err != nil {
+ // return err
+ // }
+ // select {
+ // case <-ctx.Done():
+ // return ctx.Err()
+ // case out <- v:
+ // }
+ // }
+ // }
+ //
+ // See https://blog.golang.org/pipelines for more examples of how to use
+ // a Done channel for cancellation.
+ Done() <-chan struct{}
+
+ // If Done is not yet closed, Err returns nil.
+ // If Done is closed, Err returns a non-nil error explaining why:
+ // Canceled if the context was canceled
+ // or DeadlineExceeded if the context's deadline passed.
+ // After Err returns a non-nil error, successive calls to Err return the same error.
+ Err() error
+
+ // Value returns the value associated with this context for key, or nil
+ // if no value is associated with key. Successive calls to Value with
+ // the same key returns the same result.
+ //
+ // Use context values only for request-scoped data that transits
+ // processes and API boundaries, not for passing optional parameters to
+ // functions.
+ //
+ // A key identifies a specific value in a Context. Functions that wish
+ // to store values in Context typically allocate a key in a global
+ // variable then use that key as the argument to context.WithValue and
+ // Context.Value. A key can be any type that supports equality;
+ // packages should define keys as an unexported type to avoid
+ // collisions.
+ //
+ // Packages that define a Context key should provide type-safe accessors
+ // for the values stored using that key:
+ //
+ // // Package user defines a User type that's stored in Contexts.
+ // package user
+ //
+ // import "context"
+ //
+ // // User is the type of value stored in the Contexts.
+ // type User struct {...}
+ //
+ // // key is an unexported type for keys defined in this package.
+ // // This prevents collisions with keys defined in other packages.
+ // type key int
+ //
+ // // userKey is the key for user.User values in Contexts. It is
+ // // unexported; clients use user.NewContext and user.FromContext
+ // // instead of using this key directly.
+ // var userKey key
+ //
+ // // NewContext returns a new Context that carries value u.
+ // func NewContext(ctx context.Context, u *User) context.Context {
+ // return context.WithValue(ctx, userKey, u)
+ // }
+ //
+ // // FromContext returns the User value stored in ctx, if any.
+ // func FromContext(ctx context.Context) (*User, bool) {
+ // u, ok := ctx.Value(userKey).(*User)
+ // return u, ok
+ // }
+ Value(key any) any
+}
+
+// Canceled is the error returned by [Context.Err] when the context is canceled.
+var Canceled = errors.New("context canceled")
+
+// DeadlineExceeded is the error returned by [Context.Err] when the context's
+// deadline passes.
+var DeadlineExceeded error = deadlineExceededError{}
+
+type deadlineExceededError struct{}
+
+func (deadlineExceededError) Error() string { return "context deadline exceeded" }
+func (deadlineExceededError) Timeout() bool { return true }
+func (deadlineExceededError) Temporary() bool { return true }
+
+// An emptyCtx is never canceled, has no values, and has no deadline.
+// It is the common base of backgroundCtx and todoCtx.
+type emptyCtx struct{}
+
+func (emptyCtx) Deadline() (deadline time.Time, ok bool) {
+ return
+}
+
+func (emptyCtx) Done() <-chan struct{} {
+ return nil
+}
+
+func (emptyCtx) Err() error {
+ return nil
+}
+
+func (emptyCtx) Value(key any) any {
+ return nil
+}
+
+type backgroundCtx struct{ emptyCtx }
+
+func (backgroundCtx) String() string {
+ return "context.Background"
+}
+
+type todoCtx struct{ emptyCtx }
+
+func (todoCtx) String() string {
+ return "context.TODO"
+}
+
+// Background returns a non-nil, empty [Context]. It is never canceled, has no
+// values, and has no deadline. It is typically used by the main function,
+// initialization, and tests, and as the top-level Context for incoming
+// requests.
+func Background() Context {
+ return backgroundCtx{}
+}
+
+// TODO returns a non-nil, empty [Context]. Code should use context.TODO when
+// it's unclear which Context to use or it is not yet available (because the
+// surrounding function has not yet been extended to accept a Context
+// parameter).
+func TODO() Context {
+ return todoCtx{}
+}
+
+// A CancelFunc tells an operation to abandon its work.
+// A CancelFunc does not wait for the work to stop.
+// A CancelFunc may be called by multiple goroutines simultaneously.
+// After the first call, subsequent calls to a CancelFunc do nothing.
+type CancelFunc func()
+
+// WithCancel returns a copy of parent with a new Done channel. The returned
+// context's Done channel is closed when the returned cancel function is called
+// or when the parent context's Done channel is closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this Context complete.
+func WithCancel(parent Context) (ctx Context, cancel CancelFunc) {
+ c := withCancel(parent)
+ return c, func() { c.cancel(true, Canceled, nil) }
+}
+
+// A CancelCauseFunc behaves like a [CancelFunc] but additionally sets the cancellation cause.
+// This cause can be retrieved by calling [Cause] on the canceled Context or on
+// any of its derived Contexts.
+//
+// If the context has already been canceled, CancelCauseFunc does not set the cause.
+// For example, if childContext is derived from parentContext:
+// - if parentContext is canceled with cause1 before childContext is canceled with cause2,
+// then Cause(parentContext) == Cause(childContext) == cause1
+// - if childContext is canceled with cause2 before parentContext is canceled with cause1,
+// then Cause(parentContext) == cause1 and Cause(childContext) == cause2
+type CancelCauseFunc func(cause error)
+
+// WithCancelCause behaves like [WithCancel] but returns a [CancelCauseFunc] instead of a [CancelFunc].
+// Calling cancel with a non-nil error (the "cause") records that error in ctx;
+// it can then be retrieved using Cause(ctx).
+// Calling cancel with nil sets the cause to Canceled.
+//
+// Example use:
+//
+// ctx, cancel := context.WithCancelCause(parent)
+// cancel(myError)
+// ctx.Err() // returns context.Canceled
+// context.Cause(ctx) // returns myError
+func WithCancelCause(parent Context) (ctx Context, cancel CancelCauseFunc) {
+ c := withCancel(parent)
+ return c, func(cause error) { c.cancel(true, Canceled, cause) }
+}
+
+func withCancel(parent Context) *cancelCtx {
+ if parent == nil {
+ panic("cannot create context from nil parent")
+ }
+ c := &cancelCtx{}
+ c.propagateCancel(parent, c)
+ return c
+}
+
+// Cause returns a non-nil error explaining why c was canceled.
+// The first cancellation of c or one of its parents sets the cause.
+// If that cancellation happened via a call to CancelCauseFunc(err),
+// then [Cause] returns err.
+// Otherwise Cause(c) returns the same value as c.Err().
+// Cause returns nil if c has not been canceled yet.
+func Cause(c Context) error {
+ if cc, ok := c.Value(&cancelCtxKey).(*cancelCtx); ok {
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+ return cc.cause
+ }
+ return nil
+}
+
+// AfterFunc arranges to call f in its own goroutine after ctx is done
+// (cancelled or timed out).
+// If ctx is already done, AfterFunc calls f immediately in its own goroutine.
+//
+// Multiple calls to AfterFunc on a context operate independently;
+// one does not replace another.
+//
+// Calling the returned stop function stops the association of ctx with f.
+// It returns true if the call stopped f from being run.
+// If stop returns false,
+// either the context is done and f has been started in its own goroutine;
+// or f was already stopped.
+// The stop function does not wait for f to complete before returning.
+// If the caller needs to know whether f is completed,
+// it must coordinate with f explicitly.
+//
+// If ctx has a "AfterFunc(func()) func() bool" method,
+// AfterFunc will use it to schedule the call.
+func AfterFunc(ctx Context, f func()) (stop func() bool) {
+ a := &afterFuncCtx{
+ f: f,
+ }
+ a.cancelCtx.propagateCancel(ctx, a)
+ return func() bool {
+ stopped := false
+ a.once.Do(func() {
+ stopped = true
+ })
+ if stopped {
+ a.cancel(true, Canceled, nil)
+ }
+ return stopped
+ }
+}
+
+type afterFuncer interface {
+ AfterFunc(func()) func() bool
+}
+
+type afterFuncCtx struct {
+ cancelCtx
+ once sync.Once // either starts running f or stops f from running
+ f func()
+}
+
+func (a *afterFuncCtx) cancel(removeFromParent bool, err, cause error) {
+ a.cancelCtx.cancel(false, err, cause)
+ if removeFromParent {
+ removeChild(a.Context, a)
+ }
+ a.once.Do(func() {
+ go a.f()
+ })
+}
+
+// A stopCtx is used as the parent context of a cancelCtx when
+// an AfterFunc has been registered with the parent.
+// It holds the stop function used to unregister the AfterFunc.
+type stopCtx struct {
+ Context
+ stop func() bool
+}
+
+// goroutines counts the number of goroutines ever created; for testing.
+var goroutines atomic.Int32
+
+// &cancelCtxKey is the key that a cancelCtx returns itself for.
+var cancelCtxKey int
+
+// parentCancelCtx returns the underlying *cancelCtx for parent.
+// It does this by looking up parent.Value(&cancelCtxKey) to find
+// the innermost enclosing *cancelCtx and then checking whether
+// parent.Done() matches that *cancelCtx. (If not, the *cancelCtx
+// has been wrapped in a custom implementation providing a
+// different done channel, in which case we should not bypass it.)
+func parentCancelCtx(parent Context) (*cancelCtx, bool) {
+ done := parent.Done()
+ if done == closedchan || done == nil {
+ return nil, false
+ }
+ p, ok := parent.Value(&cancelCtxKey).(*cancelCtx)
+ if !ok {
+ return nil, false
+ }
+ pdone, _ := p.done.Load().(chan struct{})
+ if pdone != done {
+ return nil, false
+ }
+ return p, true
+}
+
+// removeChild removes a context from its parent.
+func removeChild(parent Context, child canceler) {
+ if s, ok := parent.(stopCtx); ok {
+ s.stop()
+ return
+ }
+ p, ok := parentCancelCtx(parent)
+ if !ok {
+ return
+ }
+ p.mu.Lock()
+ if p.children != nil {
+ delete(p.children, child)
+ }
+ p.mu.Unlock()
+}
+
+// A canceler is a context type that can be canceled directly. The
+// implementations are *cancelCtx and *timerCtx.
+type canceler interface {
+ cancel(removeFromParent bool, err, cause error)
+ Done() <-chan struct{}
+}
+
+// closedchan is a reusable closed channel.
+var closedchan = make(chan struct{})
+
+func init() {
+ close(closedchan)
+}
+
+// A cancelCtx can be canceled. When canceled, it also cancels any children
+// that implement canceler.
+type cancelCtx struct {
+ Context
+
+ mu sync.Mutex // protects following fields
+ done atomic.Value // of chan struct{}, created lazily, closed by first cancel call
+ children map[canceler]struct{} // set to nil by the first cancel call
+ err error // set to non-nil by the first cancel call
+ cause error // set to non-nil by the first cancel call
+}
+
+func (c *cancelCtx) Value(key any) any {
+ if key == &cancelCtxKey {
+ return c
+ }
+ return value(c.Context, key)
+}
+
+func (c *cancelCtx) Done() <-chan struct{} {
+ d := c.done.Load()
+ if d != nil {
+ return d.(chan struct{})
+ }
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ d = c.done.Load()
+ if d == nil {
+ d = make(chan struct{})
+ c.done.Store(d)
+ }
+ return d.(chan struct{})
+}
+
+func (c *cancelCtx) Err() error {
+ c.mu.Lock()
+ err := c.err
+ c.mu.Unlock()
+ return err
+}
+
+// propagateCancel arranges for child to be canceled when parent is.
+// It sets the parent context of cancelCtx.
+func (c *cancelCtx) propagateCancel(parent Context, child canceler) {
+ c.Context = parent
+
+ done := parent.Done()
+ if done == nil {
+ return // parent is never canceled
+ }
+
+ select {
+ case <-done:
+ // parent is already canceled
+ child.cancel(false, parent.Err(), Cause(parent))
+ return
+ default:
+ }
+
+ if p, ok := parentCancelCtx(parent); ok {
+ // parent is a *cancelCtx, or derives from one.
+ p.mu.Lock()
+ if p.err != nil {
+ // parent has already been canceled
+ child.cancel(false, p.err, p.cause)
+ } else {
+ if p.children == nil {
+ p.children = make(map[canceler]struct{})
+ }
+ p.children[child] = struct{}{}
+ }
+ p.mu.Unlock()
+ return
+ }
+
+ if a, ok := parent.(afterFuncer); ok {
+ // parent implements an AfterFunc method.
+ c.mu.Lock()
+ stop := a.AfterFunc(func() {
+ child.cancel(false, parent.Err(), Cause(parent))
+ })
+ c.Context = stopCtx{
+ Context: parent,
+ stop: stop,
+ }
+ c.mu.Unlock()
+ return
+ }
+
+ goroutines.Add(1)
+ go func() {
+ select {
+ case <-parent.Done():
+ child.cancel(false, parent.Err(), Cause(parent))
+ case <-child.Done():
+ }
+ }()
+}
+
+type stringer interface {
+ String() string
+}
+
+func contextName(c Context) string {
+ if s, ok := c.(stringer); ok {
+ return s.String()
+ }
+ return reflectlite.TypeOf(c).String()
+}
+
+func (c *cancelCtx) String() string {
+ return contextName(c.Context) + ".WithCancel"
+}
+
+// cancel closes c.done, cancels each of c's children, and, if
+// removeFromParent is true, removes c from its parent's children.
+// cancel sets c.cause to cause if this is the first time c is canceled.
+func (c *cancelCtx) cancel(removeFromParent bool, err, cause error) {
+ if err == nil {
+ panic("context: internal error: missing cancel error")
+ }
+ if cause == nil {
+ cause = err
+ }
+ c.mu.Lock()
+ if c.err != nil {
+ c.mu.Unlock()
+ return // already canceled
+ }
+ c.err = err
+ c.cause = cause
+ d, _ := c.done.Load().(chan struct{})
+ if d == nil {
+ c.done.Store(closedchan)
+ } else {
+ close(d)
+ }
+ for child := range c.children {
+ // NOTE: acquiring the child's lock while holding parent's lock.
+ child.cancel(false, err, cause)
+ }
+ c.children = nil
+ c.mu.Unlock()
+
+ if removeFromParent {
+ removeChild(c.Context, c)
+ }
+}
+
+// WithoutCancel returns a copy of parent that is not canceled when parent is canceled.
+// The returned context returns no Deadline or Err, and its Done channel is nil.
+// Calling [Cause] on the returned context returns nil.
+func WithoutCancel(parent Context) Context {
+ if parent == nil {
+ panic("cannot create context from nil parent")
+ }
+ return withoutCancelCtx{parent}
+}
+
+type withoutCancelCtx struct {
+ c Context
+}
+
+func (withoutCancelCtx) Deadline() (deadline time.Time, ok bool) {
+ return
+}
+
+func (withoutCancelCtx) Done() <-chan struct{} {
+ return nil
+}
+
+func (withoutCancelCtx) Err() error {
+ return nil
+}
+
+func (c withoutCancelCtx) Value(key any) any {
+ return value(c, key)
+}
+
+func (c withoutCancelCtx) String() string {
+ return contextName(c.c) + ".WithoutCancel"
+}
+
+// WithDeadline returns a copy of the parent context with the deadline adjusted
+// to be no later than d. If the parent's deadline is already earlier than d,
+// WithDeadline(parent, d) is semantically equivalent to parent. The returned
+// [Context.Done] channel is closed when the deadline expires, when the returned
+// cancel function is called, or when the parent context's Done channel is
+// closed, whichever happens first.
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this [Context] complete.
+func WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {
+ return WithDeadlineCause(parent, d, nil)
+}
+
+// WithDeadlineCause behaves like [WithDeadline] but also sets the cause of the
+// returned Context when the deadline is exceeded. The returned [CancelFunc] does
+// not set the cause.
+func WithDeadlineCause(parent Context, d time.Time, cause error) (Context, CancelFunc) {
+ if parent == nil {
+ panic("cannot create context from nil parent")
+ }
+ if cur, ok := parent.Deadline(); ok && cur.Before(d) {
+ // The current deadline is already sooner than the new one.
+ return WithCancel(parent)
+ }
+ c := &timerCtx{
+ deadline: d,
+ }
+ c.cancelCtx.propagateCancel(parent, c)
+ dur := time.Until(d)
+ if dur <= 0 {
+ c.cancel(true, DeadlineExceeded, cause) // deadline has already passed
+ return c, func() { c.cancel(false, Canceled, nil) }
+ }
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if c.err == nil {
+ c.timer = time.AfterFunc(dur, func() {
+ c.cancel(true, DeadlineExceeded, cause)
+ })
+ }
+ return c, func() { c.cancel(true, Canceled, nil) }
+}
+
+// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to
+// implement Done and Err. It implements cancel by stopping its timer then
+// delegating to cancelCtx.cancel.
+type timerCtx struct {
+ cancelCtx
+ timer *time.Timer // Under cancelCtx.mu.
+
+ deadline time.Time
+}
+
+func (c *timerCtx) Deadline() (deadline time.Time, ok bool) {
+ return c.deadline, true
+}
+
+func (c *timerCtx) String() string {
+ return contextName(c.cancelCtx.Context) + ".WithDeadline(" +
+ c.deadline.String() + " [" +
+ time.Until(c.deadline).String() + "])"
+}
+
+func (c *timerCtx) cancel(removeFromParent bool, err, cause error) {
+ c.cancelCtx.cancel(false, err, cause)
+ if removeFromParent {
+ // Remove this timerCtx from its parent cancelCtx's children.
+ removeChild(c.cancelCtx.Context, c)
+ }
+ c.mu.Lock()
+ if c.timer != nil {
+ c.timer.Stop()
+ c.timer = nil
+ }
+ c.mu.Unlock()
+}
+
+// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).
+//
+// Canceling this context releases resources associated with it, so code should
+// call cancel as soon as the operations running in this [Context] complete:
+//
+// func slowOperationWithTimeout(ctx context.Context) (Result, error) {
+// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
+// defer cancel() // releases resources if slowOperation completes before timeout elapses
+// return slowOperation(ctx)
+// }
+func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
+ return WithDeadline(parent, time.Now().Add(timeout))
+}
+
+// WithTimeoutCause behaves like [WithTimeout] but also sets the cause of the
+// returned Context when the timeout expires. The returned [CancelFunc] does
+// not set the cause.
+func WithTimeoutCause(parent Context, timeout time.Duration, cause error) (Context, CancelFunc) {
+ return WithDeadlineCause(parent, time.Now().Add(timeout), cause)
+}
+
+// WithValue returns a copy of parent in which the value associated with key is
+// val.
+//
+// Use context Values only for request-scoped data that transits processes and
+// APIs, not for passing optional parameters to functions.
+//
+// The provided key must be comparable and should not be of type
+// string or any other built-in type to avoid collisions between
+// packages using context. Users of WithValue should define their own
+// types for keys. To avoid allocating when assigning to an
+// interface{}, context keys often have concrete type
+// struct{}. Alternatively, exported context key variables' static
+// type should be a pointer or interface.
+func WithValue(parent Context, key, val any) Context {
+ if parent == nil {
+ panic("cannot create context from nil parent")
+ }
+ if key == nil {
+ panic("nil key")
+ }
+ if !reflectlite.TypeOf(key).Comparable() {
+ panic("key is not comparable")
+ }
+ return &valueCtx{parent, key, val}
+}
+
+// A valueCtx carries a key-value pair. It implements Value for that key and
+// delegates all other calls to the embedded Context.
+type valueCtx struct {
+ Context
+ key, val any
+}
+
+// stringify tries a bit to stringify v, without using fmt, since we don't
+// want context depending on the unicode tables. This is only used by
+// *valueCtx.String().
+func stringify(v any) string {
+ switch s := v.(type) {
+ case stringer:
+ return s.String()
+ case string:
+ return s
+ }
+ return "<not Stringer>"
+}
+
+func (c *valueCtx) String() string {
+ return contextName(c.Context) + ".WithValue(type " +
+ reflectlite.TypeOf(c.key).String() +
+ ", val " + stringify(c.val) + ")"
+}
+
+func (c *valueCtx) Value(key any) any {
+ if c.key == key {
+ return c.val
+ }
+ return value(c.Context, key)
+}
+
+func value(c Context, key any) any {
+ for {
+ switch ctx := c.(type) {
+ case *valueCtx:
+ if key == ctx.key {
+ return ctx.val
+ }
+ c = ctx.Context
+ case *cancelCtx:
+ if key == &cancelCtxKey {
+ return c
+ }
+ c = ctx.Context
+ case withoutCancelCtx:
+ if key == &cancelCtxKey {
+ // This implements Cause(ctx) == nil
+ // when ctx is created using WithoutCancel.
+ return nil
+ }
+ c = ctx.c
+ case *timerCtx:
+ if key == &cancelCtxKey {
+ return &ctx.cancelCtx
+ }
+ c = ctx.Context
+ case backgroundCtx, todoCtx:
+ return nil
+ default:
+ return c.Value(key)
+ }
+ }
+}
diff --git a/contrib/go/_std_1.21/src/context/ya.make b/contrib/go/_std_1.21/src/context/ya.make
new file mode 100644
index 0000000000..fde43d9cfb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/context/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ context.go
+)
+
+GO_TEST_SRCS(context_test.go)
+
+GO_XTEST_SRCS(
+ afterfunc_test.go
+ benchmark_test.go
+ example_test.go
+ net_test.go
+ x_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/aes/aes_gcm.go b/contrib/go/_std_1.21/src/crypto/aes/aes_gcm.go
index f77d27969a..f77d27969a 100644
--- a/contrib/go/_std_1.20/src/crypto/aes/aes_gcm.go
+++ b/contrib/go/_std_1.21/src/crypto/aes/aes_gcm.go
diff --git a/contrib/go/_std_1.20/src/crypto/aes/asm_amd64.s b/contrib/go/_std_1.21/src/crypto/aes/asm_amd64.s
index ed831bf47f..ed831bf47f 100644
--- a/contrib/go/_std_1.20/src/crypto/aes/asm_amd64.s
+++ b/contrib/go/_std_1.21/src/crypto/aes/asm_amd64.s
diff --git a/contrib/go/_std_1.21/src/crypto/aes/asm_arm64.s b/contrib/go/_std_1.21/src/crypto/aes/asm_arm64.s
new file mode 100644
index 0000000000..4a02e943ce
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/aes/asm_arm64.s
@@ -0,0 +1,281 @@
+// Copyright 2017 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.
+
+#include "textflag.h"
+DATA rotInvSRows<>+0x00(SB)/8, $0x080f0205040b0e01
+DATA rotInvSRows<>+0x08(SB)/8, $0x00070a0d0c030609
+GLOBL rotInvSRows<>(SB), (NOPTR+RODATA), $16
+DATA invSRows<>+0x00(SB)/8, $0x0b0e0104070a0d00
+DATA invSRows<>+0x08(SB)/8, $0x0306090c0f020508
+GLOBL invSRows<>(SB), (NOPTR+RODATA), $16
+// func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
+TEXT ·encryptBlockAsm(SB),NOSPLIT,$0
+ MOVD nr+0(FP), R9
+ MOVD xk+8(FP), R10
+ MOVD dst+16(FP), R11
+ MOVD src+24(FP), R12
+
+ VLD1 (R12), [V0.B16]
+
+ CMP $12, R9
+ BLT enc128
+ BEQ enc196
+enc256:
+ VLD1.P 32(R10), [V1.B16, V2.B16]
+ AESE V1.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V2.B16, V0.B16
+ AESMC V0.B16, V0.B16
+enc196:
+ VLD1.P 32(R10), [V3.B16, V4.B16]
+ AESE V3.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V4.B16, V0.B16
+ AESMC V0.B16, V0.B16
+enc128:
+ VLD1.P 64(R10), [V5.B16, V6.B16, V7.B16, V8.B16]
+ VLD1.P 64(R10), [V9.B16, V10.B16, V11.B16, V12.B16]
+ VLD1.P 48(R10), [V13.B16, V14.B16, V15.B16]
+ AESE V5.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V6.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V7.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V8.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V9.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V10.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V11.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V12.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V13.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V14.B16, V0.B16
+ VEOR V0.B16, V15.B16, V0.B16
+ VST1 [V0.B16], (R11)
+ RET
+
+// func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
+TEXT ·decryptBlockAsm(SB),NOSPLIT,$0
+ MOVD nr+0(FP), R9
+ MOVD xk+8(FP), R10
+ MOVD dst+16(FP), R11
+ MOVD src+24(FP), R12
+
+ VLD1 (R12), [V0.B16]
+
+ CMP $12, R9
+ BLT dec128
+ BEQ dec196
+dec256:
+ VLD1.P 32(R10), [V1.B16, V2.B16]
+ AESD V1.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+ AESD V2.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+dec196:
+ VLD1.P 32(R10), [V3.B16, V4.B16]
+ AESD V3.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+ AESD V4.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+dec128:
+ VLD1.P 64(R10), [V5.B16, V6.B16, V7.B16, V8.B16]
+ VLD1.P 64(R10), [V9.B16, V10.B16, V11.B16, V12.B16]
+ VLD1.P 48(R10), [V13.B16, V14.B16, V15.B16]
+ AESD V5.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+ AESD V6.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+ AESD V7.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+ AESD V8.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+ AESD V9.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+ AESD V10.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+ AESD V11.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+ AESD V12.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+ AESD V13.B16, V0.B16
+ AESIMC V0.B16, V0.B16
+ AESD V14.B16, V0.B16
+ VEOR V0.B16, V15.B16, V0.B16
+ VST1 [V0.B16], (R11)
+ RET
+
+// func expandKeyAsm(nr int, key *byte, enc, dec *uint32) {
+// Note that round keys are stored in uint128 format, not uint32
+TEXT ·expandKeyAsm(SB),NOSPLIT,$0
+ MOVD nr+0(FP), R8
+ MOVD key+8(FP), R9
+ MOVD enc+16(FP), R10
+ MOVD dec+24(FP), R11
+ LDP rotInvSRows<>(SB), (R0, R1)
+ VMOV R0, V3.D[0]
+ VMOV R1, V3.D[1]
+ VEOR V0.B16, V0.B16, V0.B16 // All zeroes
+ MOVW $1, R13
+ TBZ $1, R8, ks192
+ TBNZ $2, R8, ks256
+ LDPW (R9), (R4, R5)
+ LDPW 8(R9), (R6, R7)
+ STPW.P (R4, R5), 8(R10)
+ STPW.P (R6, R7), 8(R10)
+ MOVW $0x1b, R14
+ks128Loop:
+ VMOV R7, V2.S[0]
+ WORD $0x4E030042 // TBL V3.B16, [V2.B16], V2.B16
+ AESE V0.B16, V2.B16 // Use AES to compute the SBOX
+ EORW R13, R4
+ LSLW $1, R13 // Compute next Rcon
+ ANDSW $0x100, R13, ZR
+ CSELW NE, R14, R13, R13 // Fake modulo
+ SUBS $1, R8
+ VMOV V2.S[0], R0
+ EORW R0, R4
+ EORW R4, R5
+ EORW R5, R6
+ EORW R6, R7
+ STPW.P (R4, R5), 8(R10)
+ STPW.P (R6, R7), 8(R10)
+ BNE ks128Loop
+ CBZ R11, ksDone // If dec is nil we are done
+ SUB $176, R10
+ // Decryption keys are encryption keys with InverseMixColumns applied
+ VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
+ VMOV V0.B16, V7.B16
+ AESIMC V1.B16, V6.B16
+ AESIMC V2.B16, V5.B16
+ AESIMC V3.B16, V4.B16
+ VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
+ AESIMC V0.B16, V11.B16
+ AESIMC V1.B16, V10.B16
+ AESIMC V2.B16, V9.B16
+ AESIMC V3.B16, V8.B16
+ VLD1 (R10), [V0.B16, V1.B16, V2.B16]
+ AESIMC V0.B16, V14.B16
+ AESIMC V1.B16, V13.B16
+ VMOV V2.B16, V12.B16
+ VST1.P [V12.B16, V13.B16, V14.B16], 48(R11)
+ VST1.P [V8.B16, V9.B16, V10.B16, V11.B16], 64(R11)
+ VST1 [V4.B16, V5.B16, V6.B16, V7.B16], (R11)
+ B ksDone
+ks192:
+ LDPW (R9), (R2, R3)
+ LDPW 8(R9), (R4, R5)
+ LDPW 16(R9), (R6, R7)
+ STPW.P (R2, R3), 8(R10)
+ STPW.P (R4, R5), 8(R10)
+ SUB $4, R8
+ks192Loop:
+ STPW.P (R6, R7), 8(R10)
+ VMOV R7, V2.S[0]
+ WORD $0x4E030042 //TBL V3.B16, [V2.B16], V2.B16
+ AESE V0.B16, V2.B16
+ EORW R13, R2
+ LSLW $1, R13
+ SUBS $1, R8
+ VMOV V2.S[0], R0
+ EORW R0, R2
+ EORW R2, R3
+ EORW R3, R4
+ EORW R4, R5
+ EORW R5, R6
+ EORW R6, R7
+ STPW.P (R2, R3), 8(R10)
+ STPW.P (R4, R5), 8(R10)
+ BNE ks192Loop
+ CBZ R11, ksDone
+ SUB $208, R10
+ VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
+ VMOV V0.B16, V7.B16
+ AESIMC V1.B16, V6.B16
+ AESIMC V2.B16, V5.B16
+ AESIMC V3.B16, V4.B16
+ VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
+ AESIMC V0.B16, V11.B16
+ AESIMC V1.B16, V10.B16
+ AESIMC V2.B16, V9.B16
+ AESIMC V3.B16, V8.B16
+ VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
+ AESIMC V0.B16, V15.B16
+ AESIMC V1.B16, V14.B16
+ AESIMC V2.B16, V13.B16
+ AESIMC V3.B16, V12.B16
+ VLD1 (R10), [V0.B16]
+ VST1.P [V0.B16], 16(R11)
+ VST1.P [V12.B16, V13.B16, V14.B16, V15.B16], 64(R11)
+ VST1.P [V8.B16, V9.B16, V10.B16, V11.B16], 64(R11)
+ VST1 [V4.B16, V5.B16, V6.B16, V7.B16], (R11)
+ B ksDone
+ks256:
+ LDP invSRows<>(SB), (R0, R1)
+ VMOV R0, V4.D[0]
+ VMOV R1, V4.D[1]
+ LDPW (R9), (R0, R1)
+ LDPW 8(R9), (R2, R3)
+ LDPW 16(R9), (R4, R5)
+ LDPW 24(R9), (R6, R7)
+ STPW.P (R0, R1), 8(R10)
+ STPW.P (R2, R3), 8(R10)
+ SUB $7, R8
+ks256Loop:
+ STPW.P (R4, R5), 8(R10)
+ STPW.P (R6, R7), 8(R10)
+ VMOV R7, V2.S[0]
+ WORD $0x4E030042 //TBL V3.B16, [V2.B16], V2.B16
+ AESE V0.B16, V2.B16
+ EORW R13, R0
+ LSLW $1, R13
+ SUBS $1, R8
+ VMOV V2.S[0], R9
+ EORW R9, R0
+ EORW R0, R1
+ EORW R1, R2
+ EORW R2, R3
+ VMOV R3, V2.S[0]
+ WORD $0x4E040042 //TBL V3.B16, [V2.B16], V2.B16
+ AESE V0.B16, V2.B16
+ VMOV V2.S[0], R9
+ EORW R9, R4
+ EORW R4, R5
+ EORW R5, R6
+ EORW R6, R7
+ STPW.P (R0, R1), 8(R10)
+ STPW.P (R2, R3), 8(R10)
+ BNE ks256Loop
+ CBZ R11, ksDone
+ SUB $240, R10
+ VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
+ VMOV V0.B16, V7.B16
+ AESIMC V1.B16, V6.B16
+ AESIMC V2.B16, V5.B16
+ AESIMC V3.B16, V4.B16
+ VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
+ AESIMC V0.B16, V11.B16
+ AESIMC V1.B16, V10.B16
+ AESIMC V2.B16, V9.B16
+ AESIMC V3.B16, V8.B16
+ VLD1.P 64(R10), [V0.B16, V1.B16, V2.B16, V3.B16]
+ AESIMC V0.B16, V15.B16
+ AESIMC V1.B16, V14.B16
+ AESIMC V2.B16, V13.B16
+ AESIMC V3.B16, V12.B16
+ VLD1 (R10), [V0.B16, V1.B16, V2.B16]
+ AESIMC V0.B16, V18.B16
+ AESIMC V1.B16, V17.B16
+ VMOV V2.B16, V16.B16
+ VST1.P [V16.B16, V17.B16, V18.B16], 48(R11)
+ VST1.P [V12.B16, V13.B16, V14.B16, V15.B16], 64(R11)
+ VST1.P [V8.B16, V9.B16, V10.B16, V11.B16], 64(R11)
+ VST1 [V4.B16, V5.B16, V6.B16, V7.B16], (R11)
+ksDone:
+ RET
diff --git a/contrib/go/_std_1.20/src/crypto/aes/block.go b/contrib/go/_std_1.21/src/crypto/aes/block.go
index 53308ae92e..53308ae92e 100644
--- a/contrib/go/_std_1.20/src/crypto/aes/block.go
+++ b/contrib/go/_std_1.21/src/crypto/aes/block.go
diff --git a/contrib/go/_std_1.20/src/crypto/aes/cipher.go b/contrib/go/_std_1.21/src/crypto/aes/cipher.go
index 183c1697c8..183c1697c8 100644
--- a/contrib/go/_std_1.20/src/crypto/aes/cipher.go
+++ b/contrib/go/_std_1.21/src/crypto/aes/cipher.go
diff --git a/contrib/go/_std_1.20/src/crypto/aes/cipher_asm.go b/contrib/go/_std_1.21/src/crypto/aes/cipher_asm.go
index 90031c5e2c..90031c5e2c 100644
--- a/contrib/go/_std_1.20/src/crypto/aes/cipher_asm.go
+++ b/contrib/go/_std_1.21/src/crypto/aes/cipher_asm.go
diff --git a/contrib/go/_std_1.20/src/crypto/aes/const.go b/contrib/go/_std_1.21/src/crypto/aes/const.go
index 4eca4b9aff..4eca4b9aff 100644
--- a/contrib/go/_std_1.20/src/crypto/aes/const.go
+++ b/contrib/go/_std_1.21/src/crypto/aes/const.go
diff --git a/contrib/go/_std_1.20/src/crypto/aes/gcm_amd64.s b/contrib/go/_std_1.21/src/crypto/aes/gcm_amd64.s
index e6eedf3264..e6eedf3264 100644
--- a/contrib/go/_std_1.20/src/crypto/aes/gcm_amd64.s
+++ b/contrib/go/_std_1.21/src/crypto/aes/gcm_amd64.s
diff --git a/contrib/go/_std_1.21/src/crypto/aes/gcm_arm64.s b/contrib/go/_std_1.21/src/crypto/aes/gcm_arm64.s
new file mode 100644
index 0000000000..c3501024c9
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/aes/gcm_arm64.s
@@ -0,0 +1,1021 @@
+// Copyright 2018 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.
+
+#include "textflag.h"
+
+#define B0 V0
+#define B1 V1
+#define B2 V2
+#define B3 V3
+#define B4 V4
+#define B5 V5
+#define B6 V6
+#define B7 V7
+
+#define ACC0 V8
+#define ACC1 V9
+#define ACCM V10
+
+#define T0 V11
+#define T1 V12
+#define T2 V13
+#define T3 V14
+
+#define POLY V15
+#define ZERO V16
+#define INC V17
+#define CTR V18
+
+#define K0 V19
+#define K1 V20
+#define K2 V21
+#define K3 V22
+#define K4 V23
+#define K5 V24
+#define K6 V25
+#define K7 V26
+#define K8 V27
+#define K9 V28
+#define K10 V29
+#define K11 V30
+#define KLAST V31
+
+#define reduce() \
+ VEOR ACC0.B16, ACCM.B16, ACCM.B16 \
+ VEOR ACC1.B16, ACCM.B16, ACCM.B16 \
+ VEXT $8, ZERO.B16, ACCM.B16, T0.B16 \
+ VEXT $8, ACCM.B16, ZERO.B16, ACCM.B16 \
+ VEOR ACCM.B16, ACC0.B16, ACC0.B16 \
+ VEOR T0.B16, ACC1.B16, ACC1.B16 \
+ VPMULL POLY.D1, ACC0.D1, T0.Q1 \
+ VEXT $8, ACC0.B16, ACC0.B16, ACC0.B16 \
+ VEOR T0.B16, ACC0.B16, ACC0.B16 \
+ VPMULL POLY.D1, ACC0.D1, T0.Q1 \
+ VEOR T0.B16, ACC1.B16, ACC1.B16 \
+ VEXT $8, ACC1.B16, ACC1.B16, ACC1.B16 \
+ VEOR ACC1.B16, ACC0.B16, ACC0.B16 \
+
+// func gcmAesFinish(productTable *[256]byte, tagMask, T *[16]byte, pLen, dLen uint64)
+TEXT ·gcmAesFinish(SB),NOSPLIT,$0
+#define pTbl R0
+#define tMsk R1
+#define tPtr R2
+#define plen R3
+#define dlen R4
+
+ MOVD $0xC2, R1
+ LSL $56, R1
+ MOVD $1, R0
+ VMOV R1, POLY.D[0]
+ VMOV R0, POLY.D[1]
+ VEOR ZERO.B16, ZERO.B16, ZERO.B16
+
+ MOVD productTable+0(FP), pTbl
+ MOVD tagMask+8(FP), tMsk
+ MOVD T+16(FP), tPtr
+ MOVD pLen+24(FP), plen
+ MOVD dLen+32(FP), dlen
+
+ VLD1 (tPtr), [ACC0.B16]
+ VLD1 (tMsk), [B1.B16]
+
+ LSL $3, plen
+ LSL $3, dlen
+
+ VMOV dlen, B0.D[0]
+ VMOV plen, B0.D[1]
+
+ ADD $14*16, pTbl
+ VLD1.P (pTbl), [T1.B16, T2.B16]
+
+ VEOR ACC0.B16, B0.B16, B0.B16
+
+ VEXT $8, B0.B16, B0.B16, T0.B16
+ VEOR B0.B16, T0.B16, T0.B16
+ VPMULL B0.D1, T1.D1, ACC1.Q1
+ VPMULL2 B0.D2, T1.D2, ACC0.Q1
+ VPMULL T0.D1, T2.D1, ACCM.Q1
+
+ reduce()
+
+ VREV64 ACC0.B16, ACC0.B16
+ VEOR B1.B16, ACC0.B16, ACC0.B16
+
+ VST1 [ACC0.B16], (tPtr)
+ RET
+#undef pTbl
+#undef tMsk
+#undef tPtr
+#undef plen
+#undef dlen
+
+// func gcmAesInit(productTable *[256]byte, ks []uint32)
+TEXT ·gcmAesInit(SB),NOSPLIT,$0
+#define pTbl R0
+#define KS R1
+#define NR R2
+#define I R3
+ MOVD productTable+0(FP), pTbl
+ MOVD ks_base+8(FP), KS
+ MOVD ks_len+16(FP), NR
+
+ MOVD $0xC2, I
+ LSL $56, I
+ VMOV I, POLY.D[0]
+ MOVD $1, I
+ VMOV I, POLY.D[1]
+ VEOR ZERO.B16, ZERO.B16, ZERO.B16
+
+ // Encrypt block 0 with the AES key to generate the hash key H
+ VLD1.P 64(KS), [T0.B16, T1.B16, T2.B16, T3.B16]
+ VEOR B0.B16, B0.B16, B0.B16
+ AESE T0.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE T1.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE T2.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE T3.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ VLD1.P 64(KS), [T0.B16, T1.B16, T2.B16, T3.B16]
+ AESE T0.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE T1.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE T2.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE T3.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ TBZ $4, NR, initEncFinish
+ VLD1.P 32(KS), [T0.B16, T1.B16]
+ AESE T0.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE T1.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ TBZ $3, NR, initEncFinish
+ VLD1.P 32(KS), [T0.B16, T1.B16]
+ AESE T0.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE T1.B16, B0.B16
+ AESMC B0.B16, B0.B16
+initEncFinish:
+ VLD1 (KS), [T0.B16, T1.B16, T2.B16]
+ AESE T0.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE T1.B16, B0.B16
+ VEOR T2.B16, B0.B16, B0.B16
+
+ VREV64 B0.B16, B0.B16
+
+ // Multiply by 2 modulo P
+ VMOV B0.D[0], I
+ ASR $63, I
+ VMOV I, T1.D[0]
+ VMOV I, T1.D[1]
+ VAND POLY.B16, T1.B16, T1.B16
+ VUSHR $63, B0.D2, T2.D2
+ VEXT $8, ZERO.B16, T2.B16, T2.B16
+ VSHL $1, B0.D2, B0.D2
+ VEOR T1.B16, B0.B16, B0.B16
+ VEOR T2.B16, B0.B16, B0.B16 // Can avoid this when VSLI is available
+
+ // Karatsuba pre-computation
+ VEXT $8, B0.B16, B0.B16, B1.B16
+ VEOR B0.B16, B1.B16, B1.B16
+
+ ADD $14*16, pTbl
+ VST1 [B0.B16, B1.B16], (pTbl)
+ SUB $2*16, pTbl
+
+ VMOV B0.B16, B2.B16
+ VMOV B1.B16, B3.B16
+
+ MOVD $7, I
+
+initLoop:
+ // Compute powers of H
+ SUBS $1, I
+
+ VPMULL B0.D1, B2.D1, T1.Q1
+ VPMULL2 B0.D2, B2.D2, T0.Q1
+ VPMULL B1.D1, B3.D1, T2.Q1
+ VEOR T0.B16, T2.B16, T2.B16
+ VEOR T1.B16, T2.B16, T2.B16
+ VEXT $8, ZERO.B16, T2.B16, T3.B16
+ VEXT $8, T2.B16, ZERO.B16, T2.B16
+ VEOR T2.B16, T0.B16, T0.B16
+ VEOR T3.B16, T1.B16, T1.B16
+ VPMULL POLY.D1, T0.D1, T2.Q1
+ VEXT $8, T0.B16, T0.B16, T0.B16
+ VEOR T2.B16, T0.B16, T0.B16
+ VPMULL POLY.D1, T0.D1, T2.Q1
+ VEXT $8, T0.B16, T0.B16, T0.B16
+ VEOR T2.B16, T0.B16, T0.B16
+ VEOR T1.B16, T0.B16, B2.B16
+ VMOV B2.B16, B3.B16
+ VEXT $8, B2.B16, B2.B16, B2.B16
+ VEOR B2.B16, B3.B16, B3.B16
+
+ VST1 [B2.B16, B3.B16], (pTbl)
+ SUB $2*16, pTbl
+
+ BNE initLoop
+ RET
+#undef I
+#undef NR
+#undef KS
+#undef pTbl
+
+// func gcmAesData(productTable *[256]byte, data []byte, T *[16]byte)
+TEXT ·gcmAesData(SB),NOSPLIT,$0
+#define pTbl R0
+#define aut R1
+#define tPtr R2
+#define autLen R3
+#define H0 R4
+#define pTblSave R5
+
+#define mulRound(X) \
+ VLD1.P 32(pTbl), [T1.B16, T2.B16] \
+ VREV64 X.B16, X.B16 \
+ VEXT $8, X.B16, X.B16, T0.B16 \
+ VEOR X.B16, T0.B16, T0.B16 \
+ VPMULL X.D1, T1.D1, T3.Q1 \
+ VEOR T3.B16, ACC1.B16, ACC1.B16 \
+ VPMULL2 X.D2, T1.D2, T3.Q1 \
+ VEOR T3.B16, ACC0.B16, ACC0.B16 \
+ VPMULL T0.D1, T2.D1, T3.Q1 \
+ VEOR T3.B16, ACCM.B16, ACCM.B16
+
+ MOVD productTable+0(FP), pTbl
+ MOVD data_base+8(FP), aut
+ MOVD data_len+16(FP), autLen
+ MOVD T+32(FP), tPtr
+
+ VEOR ACC0.B16, ACC0.B16, ACC0.B16
+ CBZ autLen, dataBail
+
+ MOVD $0xC2, H0
+ LSL $56, H0
+ VMOV H0, POLY.D[0]
+ MOVD $1, H0
+ VMOV H0, POLY.D[1]
+ VEOR ZERO.B16, ZERO.B16, ZERO.B16
+ MOVD pTbl, pTblSave
+
+ CMP $13, autLen
+ BEQ dataTLS
+ CMP $128, autLen
+ BLT startSinglesLoop
+ B octetsLoop
+
+dataTLS:
+ ADD $14*16, pTbl
+ VLD1.P (pTbl), [T1.B16, T2.B16]
+ VEOR B0.B16, B0.B16, B0.B16
+
+ MOVD (aut), H0
+ VMOV H0, B0.D[0]
+ MOVW 8(aut), H0
+ VMOV H0, B0.S[2]
+ MOVB 12(aut), H0
+ VMOV H0, B0.B[12]
+
+ MOVD $0, autLen
+ B dataMul
+
+octetsLoop:
+ CMP $128, autLen
+ BLT startSinglesLoop
+ SUB $128, autLen
+
+ VLD1.P 32(aut), [B0.B16, B1.B16]
+
+ VLD1.P 32(pTbl), [T1.B16, T2.B16]
+ VREV64 B0.B16, B0.B16
+ VEOR ACC0.B16, B0.B16, B0.B16
+ VEXT $8, B0.B16, B0.B16, T0.B16
+ VEOR B0.B16, T0.B16, T0.B16
+ VPMULL B0.D1, T1.D1, ACC1.Q1
+ VPMULL2 B0.D2, T1.D2, ACC0.Q1
+ VPMULL T0.D1, T2.D1, ACCM.Q1
+
+ mulRound(B1)
+ VLD1.P 32(aut), [B2.B16, B3.B16]
+ mulRound(B2)
+ mulRound(B3)
+ VLD1.P 32(aut), [B4.B16, B5.B16]
+ mulRound(B4)
+ mulRound(B5)
+ VLD1.P 32(aut), [B6.B16, B7.B16]
+ mulRound(B6)
+ mulRound(B7)
+
+ MOVD pTblSave, pTbl
+ reduce()
+ B octetsLoop
+
+startSinglesLoop:
+
+ ADD $14*16, pTbl
+ VLD1.P (pTbl), [T1.B16, T2.B16]
+
+singlesLoop:
+
+ CMP $16, autLen
+ BLT dataEnd
+ SUB $16, autLen
+
+ VLD1.P 16(aut), [B0.B16]
+dataMul:
+ VREV64 B0.B16, B0.B16
+ VEOR ACC0.B16, B0.B16, B0.B16
+
+ VEXT $8, B0.B16, B0.B16, T0.B16
+ VEOR B0.B16, T0.B16, T0.B16
+ VPMULL B0.D1, T1.D1, ACC1.Q1
+ VPMULL2 B0.D2, T1.D2, ACC0.Q1
+ VPMULL T0.D1, T2.D1, ACCM.Q1
+
+ reduce()
+
+ B singlesLoop
+
+dataEnd:
+
+ CBZ autLen, dataBail
+ VEOR B0.B16, B0.B16, B0.B16
+ ADD autLen, aut
+
+dataLoadLoop:
+ MOVB.W -1(aut), H0
+ VEXT $15, B0.B16, ZERO.B16, B0.B16
+ VMOV H0, B0.B[0]
+ SUBS $1, autLen
+ BNE dataLoadLoop
+ B dataMul
+
+dataBail:
+ VST1 [ACC0.B16], (tPtr)
+ RET
+
+#undef pTbl
+#undef aut
+#undef tPtr
+#undef autLen
+#undef H0
+#undef pTblSave
+
+// func gcmAesEnc(productTable *[256]byte, dst, src []byte, ctr, T *[16]byte, ks []uint32)
+TEXT ·gcmAesEnc(SB),NOSPLIT,$0
+#define pTbl R0
+#define dstPtr R1
+#define ctrPtr R2
+#define srcPtr R3
+#define ks R4
+#define tPtr R5
+#define srcPtrLen R6
+#define aluCTR R7
+#define aluTMP R8
+#define aluK R9
+#define NR R10
+#define H0 R11
+#define H1 R12
+#define curK R13
+#define pTblSave R14
+
+#define aesrndx8(K) \
+ AESE K.B16, B0.B16 \
+ AESMC B0.B16, B0.B16 \
+ AESE K.B16, B1.B16 \
+ AESMC B1.B16, B1.B16 \
+ AESE K.B16, B2.B16 \
+ AESMC B2.B16, B2.B16 \
+ AESE K.B16, B3.B16 \
+ AESMC B3.B16, B3.B16 \
+ AESE K.B16, B4.B16 \
+ AESMC B4.B16, B4.B16 \
+ AESE K.B16, B5.B16 \
+ AESMC B5.B16, B5.B16 \
+ AESE K.B16, B6.B16 \
+ AESMC B6.B16, B6.B16 \
+ AESE K.B16, B7.B16 \
+ AESMC B7.B16, B7.B16
+
+#define aesrndlastx8(K) \
+ AESE K.B16, B0.B16 \
+ AESE K.B16, B1.B16 \
+ AESE K.B16, B2.B16 \
+ AESE K.B16, B3.B16 \
+ AESE K.B16, B4.B16 \
+ AESE K.B16, B5.B16 \
+ AESE K.B16, B6.B16 \
+ AESE K.B16, B7.B16
+
+ MOVD productTable+0(FP), pTbl
+ MOVD dst+8(FP), dstPtr
+ MOVD src_base+32(FP), srcPtr
+ MOVD src_len+40(FP), srcPtrLen
+ MOVD ctr+56(FP), ctrPtr
+ MOVD T+64(FP), tPtr
+ MOVD ks_base+72(FP), ks
+ MOVD ks_len+80(FP), NR
+
+ MOVD $0xC2, H1
+ LSL $56, H1
+ MOVD $1, H0
+ VMOV H1, POLY.D[0]
+ VMOV H0, POLY.D[1]
+ VEOR ZERO.B16, ZERO.B16, ZERO.B16
+ // Compute NR from len(ks)
+ MOVD pTbl, pTblSave
+ // Current tag, after AAD
+ VLD1 (tPtr), [ACC0.B16]
+ VEOR ACC1.B16, ACC1.B16, ACC1.B16
+ VEOR ACCM.B16, ACCM.B16, ACCM.B16
+ // Prepare initial counter, and the increment vector
+ VLD1 (ctrPtr), [CTR.B16]
+ VEOR INC.B16, INC.B16, INC.B16
+ MOVD $1, H0
+ VMOV H0, INC.S[3]
+ VREV32 CTR.B16, CTR.B16
+ VADD CTR.S4, INC.S4, CTR.S4
+ // Skip to <8 blocks loop
+ CMP $128, srcPtrLen
+
+ MOVD ks, H0
+ // For AES-128 round keys are stored in: K0 .. K10, KLAST
+ VLD1.P 64(H0), [K0.B16, K1.B16, K2.B16, K3.B16]
+ VLD1.P 64(H0), [K4.B16, K5.B16, K6.B16, K7.B16]
+ VLD1.P 48(H0), [K8.B16, K9.B16, K10.B16]
+ VMOV K10.B16, KLAST.B16
+
+ BLT startSingles
+ // There are at least 8 blocks to encrypt
+ TBZ $4, NR, octetsLoop
+
+ // For AES-192 round keys occupy: K0 .. K7, K10, K11, K8, K9, KLAST
+ VMOV K8.B16, K10.B16
+ VMOV K9.B16, K11.B16
+ VMOV KLAST.B16, K8.B16
+ VLD1.P 16(H0), [K9.B16]
+ VLD1.P 16(H0), [KLAST.B16]
+ TBZ $3, NR, octetsLoop
+ // For AES-256 round keys occupy: K0 .. K7, K10, K11, mem, mem, K8, K9, KLAST
+ VMOV KLAST.B16, K8.B16
+ VLD1.P 16(H0), [K9.B16]
+ VLD1.P 16(H0), [KLAST.B16]
+ ADD $10*16, ks, H0
+ MOVD H0, curK
+
+octetsLoop:
+ SUB $128, srcPtrLen
+
+ VMOV CTR.B16, B0.B16
+ VADD B0.S4, INC.S4, B1.S4
+ VREV32 B0.B16, B0.B16
+ VADD B1.S4, INC.S4, B2.S4
+ VREV32 B1.B16, B1.B16
+ VADD B2.S4, INC.S4, B3.S4
+ VREV32 B2.B16, B2.B16
+ VADD B3.S4, INC.S4, B4.S4
+ VREV32 B3.B16, B3.B16
+ VADD B4.S4, INC.S4, B5.S4
+ VREV32 B4.B16, B4.B16
+ VADD B5.S4, INC.S4, B6.S4
+ VREV32 B5.B16, B5.B16
+ VADD B6.S4, INC.S4, B7.S4
+ VREV32 B6.B16, B6.B16
+ VADD B7.S4, INC.S4, CTR.S4
+ VREV32 B7.B16, B7.B16
+
+ aesrndx8(K0)
+ aesrndx8(K1)
+ aesrndx8(K2)
+ aesrndx8(K3)
+ aesrndx8(K4)
+ aesrndx8(K5)
+ aesrndx8(K6)
+ aesrndx8(K7)
+ TBZ $4, NR, octetsFinish
+ aesrndx8(K10)
+ aesrndx8(K11)
+ TBZ $3, NR, octetsFinish
+ VLD1.P 32(curK), [T1.B16, T2.B16]
+ aesrndx8(T1)
+ aesrndx8(T2)
+ MOVD H0, curK
+octetsFinish:
+ aesrndx8(K8)
+ aesrndlastx8(K9)
+
+ VEOR KLAST.B16, B0.B16, B0.B16
+ VEOR KLAST.B16, B1.B16, B1.B16
+ VEOR KLAST.B16, B2.B16, B2.B16
+ VEOR KLAST.B16, B3.B16, B3.B16
+ VEOR KLAST.B16, B4.B16, B4.B16
+ VEOR KLAST.B16, B5.B16, B5.B16
+ VEOR KLAST.B16, B6.B16, B6.B16
+ VEOR KLAST.B16, B7.B16, B7.B16
+
+ VLD1.P 32(srcPtr), [T1.B16, T2.B16]
+ VEOR B0.B16, T1.B16, B0.B16
+ VEOR B1.B16, T2.B16, B1.B16
+ VST1.P [B0.B16, B1.B16], 32(dstPtr)
+ VLD1.P 32(srcPtr), [T1.B16, T2.B16]
+ VEOR B2.B16, T1.B16, B2.B16
+ VEOR B3.B16, T2.B16, B3.B16
+ VST1.P [B2.B16, B3.B16], 32(dstPtr)
+ VLD1.P 32(srcPtr), [T1.B16, T2.B16]
+ VEOR B4.B16, T1.B16, B4.B16
+ VEOR B5.B16, T2.B16, B5.B16
+ VST1.P [B4.B16, B5.B16], 32(dstPtr)
+ VLD1.P 32(srcPtr), [T1.B16, T2.B16]
+ VEOR B6.B16, T1.B16, B6.B16
+ VEOR B7.B16, T2.B16, B7.B16
+ VST1.P [B6.B16, B7.B16], 32(dstPtr)
+
+ VLD1.P 32(pTbl), [T1.B16, T2.B16]
+ VREV64 B0.B16, B0.B16
+ VEOR ACC0.B16, B0.B16, B0.B16
+ VEXT $8, B0.B16, B0.B16, T0.B16
+ VEOR B0.B16, T0.B16, T0.B16
+ VPMULL B0.D1, T1.D1, ACC1.Q1
+ VPMULL2 B0.D2, T1.D2, ACC0.Q1
+ VPMULL T0.D1, T2.D1, ACCM.Q1
+
+ mulRound(B1)
+ mulRound(B2)
+ mulRound(B3)
+ mulRound(B4)
+ mulRound(B5)
+ mulRound(B6)
+ mulRound(B7)
+ MOVD pTblSave, pTbl
+ reduce()
+
+ CMP $128, srcPtrLen
+ BGE octetsLoop
+
+startSingles:
+ CBZ srcPtrLen, done
+ ADD $14*16, pTbl
+ // Preload H and its Karatsuba precomp
+ VLD1.P (pTbl), [T1.B16, T2.B16]
+ // Preload AES round keys
+ ADD $128, ks
+ VLD1.P 48(ks), [K8.B16, K9.B16, K10.B16]
+ VMOV K10.B16, KLAST.B16
+ TBZ $4, NR, singlesLoop
+ VLD1.P 32(ks), [B1.B16, B2.B16]
+ VMOV B2.B16, KLAST.B16
+ TBZ $3, NR, singlesLoop
+ VLD1.P 32(ks), [B3.B16, B4.B16]
+ VMOV B4.B16, KLAST.B16
+
+singlesLoop:
+ CMP $16, srcPtrLen
+ BLT tail
+ SUB $16, srcPtrLen
+
+ VLD1.P 16(srcPtr), [T0.B16]
+ VEOR KLAST.B16, T0.B16, T0.B16
+
+ VREV32 CTR.B16, B0.B16
+ VADD CTR.S4, INC.S4, CTR.S4
+
+ AESE K0.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K1.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K2.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K3.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K4.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K5.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K6.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K7.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K8.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K9.B16, B0.B16
+ TBZ $4, NR, singlesLast
+ AESMC B0.B16, B0.B16
+ AESE K10.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE B1.B16, B0.B16
+ TBZ $3, NR, singlesLast
+ AESMC B0.B16, B0.B16
+ AESE B2.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE B3.B16, B0.B16
+singlesLast:
+ VEOR T0.B16, B0.B16, B0.B16
+encReduce:
+ VST1.P [B0.B16], 16(dstPtr)
+
+ VREV64 B0.B16, B0.B16
+ VEOR ACC0.B16, B0.B16, B0.B16
+
+ VEXT $8, B0.B16, B0.B16, T0.B16
+ VEOR B0.B16, T0.B16, T0.B16
+ VPMULL B0.D1, T1.D1, ACC1.Q1
+ VPMULL2 B0.D2, T1.D2, ACC0.Q1
+ VPMULL T0.D1, T2.D1, ACCM.Q1
+
+ reduce()
+
+ B singlesLoop
+tail:
+ CBZ srcPtrLen, done
+
+ VEOR T0.B16, T0.B16, T0.B16
+ VEOR T3.B16, T3.B16, T3.B16
+ MOVD $0, H1
+ SUB $1, H1
+ ADD srcPtrLen, srcPtr
+
+ TBZ $3, srcPtrLen, ld4
+ MOVD.W -8(srcPtr), H0
+ VMOV H0, T0.D[0]
+ VMOV H1, T3.D[0]
+ld4:
+ TBZ $2, srcPtrLen, ld2
+ MOVW.W -4(srcPtr), H0
+ VEXT $12, T0.B16, ZERO.B16, T0.B16
+ VEXT $12, T3.B16, ZERO.B16, T3.B16
+ VMOV H0, T0.S[0]
+ VMOV H1, T3.S[0]
+ld2:
+ TBZ $1, srcPtrLen, ld1
+ MOVH.W -2(srcPtr), H0
+ VEXT $14, T0.B16, ZERO.B16, T0.B16
+ VEXT $14, T3.B16, ZERO.B16, T3.B16
+ VMOV H0, T0.H[0]
+ VMOV H1, T3.H[0]
+ld1:
+ TBZ $0, srcPtrLen, ld0
+ MOVB.W -1(srcPtr), H0
+ VEXT $15, T0.B16, ZERO.B16, T0.B16
+ VEXT $15, T3.B16, ZERO.B16, T3.B16
+ VMOV H0, T0.B[0]
+ VMOV H1, T3.B[0]
+ld0:
+
+ MOVD ZR, srcPtrLen
+ VEOR KLAST.B16, T0.B16, T0.B16
+ VREV32 CTR.B16, B0.B16
+
+ AESE K0.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K1.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K2.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K3.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K4.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K5.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K6.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K7.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K8.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K9.B16, B0.B16
+ TBZ $4, NR, tailLast
+ AESMC B0.B16, B0.B16
+ AESE K10.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE B1.B16, B0.B16
+ TBZ $3, NR, tailLast
+ AESMC B0.B16, B0.B16
+ AESE B2.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE B3.B16, B0.B16
+
+tailLast:
+ VEOR T0.B16, B0.B16, B0.B16
+ VAND T3.B16, B0.B16, B0.B16
+ B encReduce
+
+done:
+ VST1 [ACC0.B16], (tPtr)
+ RET
+
+// func gcmAesDec(productTable *[256]byte, dst, src []byte, ctr, T *[16]byte, ks []uint32)
+TEXT ·gcmAesDec(SB),NOSPLIT,$0
+ MOVD productTable+0(FP), pTbl
+ MOVD dst+8(FP), dstPtr
+ MOVD src_base+32(FP), srcPtr
+ MOVD src_len+40(FP), srcPtrLen
+ MOVD ctr+56(FP), ctrPtr
+ MOVD T+64(FP), tPtr
+ MOVD ks_base+72(FP), ks
+ MOVD ks_len+80(FP), NR
+
+ MOVD $0xC2, H1
+ LSL $56, H1
+ MOVD $1, H0
+ VMOV H1, POLY.D[0]
+ VMOV H0, POLY.D[1]
+ VEOR ZERO.B16, ZERO.B16, ZERO.B16
+ // Compute NR from len(ks)
+ MOVD pTbl, pTblSave
+ // Current tag, after AAD
+ VLD1 (tPtr), [ACC0.B16]
+ VEOR ACC1.B16, ACC1.B16, ACC1.B16
+ VEOR ACCM.B16, ACCM.B16, ACCM.B16
+ // Prepare initial counter, and the increment vector
+ VLD1 (ctrPtr), [CTR.B16]
+ VEOR INC.B16, INC.B16, INC.B16
+ MOVD $1, H0
+ VMOV H0, INC.S[3]
+ VREV32 CTR.B16, CTR.B16
+ VADD CTR.S4, INC.S4, CTR.S4
+
+ MOVD ks, H0
+ // For AES-128 round keys are stored in: K0 .. K10, KLAST
+ VLD1.P 64(H0), [K0.B16, K1.B16, K2.B16, K3.B16]
+ VLD1.P 64(H0), [K4.B16, K5.B16, K6.B16, K7.B16]
+ VLD1.P 48(H0), [K8.B16, K9.B16, K10.B16]
+ VMOV K10.B16, KLAST.B16
+
+ // Skip to <8 blocks loop
+ CMP $128, srcPtrLen
+ BLT startSingles
+ // There are at least 8 blocks to encrypt
+ TBZ $4, NR, octetsLoop
+
+ // For AES-192 round keys occupy: K0 .. K7, K10, K11, K8, K9, KLAST
+ VMOV K8.B16, K10.B16
+ VMOV K9.B16, K11.B16
+ VMOV KLAST.B16, K8.B16
+ VLD1.P 16(H0), [K9.B16]
+ VLD1.P 16(H0), [KLAST.B16]
+ TBZ $3, NR, octetsLoop
+ // For AES-256 round keys occupy: K0 .. K7, K10, K11, mem, mem, K8, K9, KLAST
+ VMOV KLAST.B16, K8.B16
+ VLD1.P 16(H0), [K9.B16]
+ VLD1.P 16(H0), [KLAST.B16]
+ ADD $10*16, ks, H0
+ MOVD H0, curK
+
+octetsLoop:
+ SUB $128, srcPtrLen
+
+ VMOV CTR.B16, B0.B16
+ VADD B0.S4, INC.S4, B1.S4
+ VREV32 B0.B16, B0.B16
+ VADD B1.S4, INC.S4, B2.S4
+ VREV32 B1.B16, B1.B16
+ VADD B2.S4, INC.S4, B3.S4
+ VREV32 B2.B16, B2.B16
+ VADD B3.S4, INC.S4, B4.S4
+ VREV32 B3.B16, B3.B16
+ VADD B4.S4, INC.S4, B5.S4
+ VREV32 B4.B16, B4.B16
+ VADD B5.S4, INC.S4, B6.S4
+ VREV32 B5.B16, B5.B16
+ VADD B6.S4, INC.S4, B7.S4
+ VREV32 B6.B16, B6.B16
+ VADD B7.S4, INC.S4, CTR.S4
+ VREV32 B7.B16, B7.B16
+
+ aesrndx8(K0)
+ aesrndx8(K1)
+ aesrndx8(K2)
+ aesrndx8(K3)
+ aesrndx8(K4)
+ aesrndx8(K5)
+ aesrndx8(K6)
+ aesrndx8(K7)
+ TBZ $4, NR, octetsFinish
+ aesrndx8(K10)
+ aesrndx8(K11)
+ TBZ $3, NR, octetsFinish
+ VLD1.P 32(curK), [T1.B16, T2.B16]
+ aesrndx8(T1)
+ aesrndx8(T2)
+ MOVD H0, curK
+octetsFinish:
+ aesrndx8(K8)
+ aesrndlastx8(K9)
+
+ VEOR KLAST.B16, B0.B16, T1.B16
+ VEOR KLAST.B16, B1.B16, T2.B16
+ VEOR KLAST.B16, B2.B16, B2.B16
+ VEOR KLAST.B16, B3.B16, B3.B16
+ VEOR KLAST.B16, B4.B16, B4.B16
+ VEOR KLAST.B16, B5.B16, B5.B16
+ VEOR KLAST.B16, B6.B16, B6.B16
+ VEOR KLAST.B16, B7.B16, B7.B16
+
+ VLD1.P 32(srcPtr), [B0.B16, B1.B16]
+ VEOR B0.B16, T1.B16, T1.B16
+ VEOR B1.B16, T2.B16, T2.B16
+ VST1.P [T1.B16, T2.B16], 32(dstPtr)
+
+ VLD1.P 32(pTbl), [T1.B16, T2.B16]
+ VREV64 B0.B16, B0.B16
+ VEOR ACC0.B16, B0.B16, B0.B16
+ VEXT $8, B0.B16, B0.B16, T0.B16
+ VEOR B0.B16, T0.B16, T0.B16
+ VPMULL B0.D1, T1.D1, ACC1.Q1
+ VPMULL2 B0.D2, T1.D2, ACC0.Q1
+ VPMULL T0.D1, T2.D1, ACCM.Q1
+ mulRound(B1)
+
+ VLD1.P 32(srcPtr), [B0.B16, B1.B16]
+ VEOR B2.B16, B0.B16, T1.B16
+ VEOR B3.B16, B1.B16, T2.B16
+ VST1.P [T1.B16, T2.B16], 32(dstPtr)
+ mulRound(B0)
+ mulRound(B1)
+
+ VLD1.P 32(srcPtr), [B0.B16, B1.B16]
+ VEOR B4.B16, B0.B16, T1.B16
+ VEOR B5.B16, B1.B16, T2.B16
+ VST1.P [T1.B16, T2.B16], 32(dstPtr)
+ mulRound(B0)
+ mulRound(B1)
+
+ VLD1.P 32(srcPtr), [B0.B16, B1.B16]
+ VEOR B6.B16, B0.B16, T1.B16
+ VEOR B7.B16, B1.B16, T2.B16
+ VST1.P [T1.B16, T2.B16], 32(dstPtr)
+ mulRound(B0)
+ mulRound(B1)
+
+ MOVD pTblSave, pTbl
+ reduce()
+
+ CMP $128, srcPtrLen
+ BGE octetsLoop
+
+startSingles:
+ CBZ srcPtrLen, done
+ ADD $14*16, pTbl
+ // Preload H and its Karatsuba precomp
+ VLD1.P (pTbl), [T1.B16, T2.B16]
+ // Preload AES round keys
+ ADD $128, ks
+ VLD1.P 48(ks), [K8.B16, K9.B16, K10.B16]
+ VMOV K10.B16, KLAST.B16
+ TBZ $4, NR, singlesLoop
+ VLD1.P 32(ks), [B1.B16, B2.B16]
+ VMOV B2.B16, KLAST.B16
+ TBZ $3, NR, singlesLoop
+ VLD1.P 32(ks), [B3.B16, B4.B16]
+ VMOV B4.B16, KLAST.B16
+
+singlesLoop:
+ CMP $16, srcPtrLen
+ BLT tail
+ SUB $16, srcPtrLen
+
+ VLD1.P 16(srcPtr), [T0.B16]
+ VREV64 T0.B16, B5.B16
+ VEOR KLAST.B16, T0.B16, T0.B16
+
+ VREV32 CTR.B16, B0.B16
+ VADD CTR.S4, INC.S4, CTR.S4
+
+ AESE K0.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K1.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K2.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K3.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K4.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K5.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K6.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K7.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K8.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K9.B16, B0.B16
+ TBZ $4, NR, singlesLast
+ AESMC B0.B16, B0.B16
+ AESE K10.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE B1.B16, B0.B16
+ TBZ $3, NR, singlesLast
+ AESMC B0.B16, B0.B16
+ AESE B2.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE B3.B16, B0.B16
+singlesLast:
+ VEOR T0.B16, B0.B16, B0.B16
+
+ VST1.P [B0.B16], 16(dstPtr)
+
+ VEOR ACC0.B16, B5.B16, B5.B16
+ VEXT $8, B5.B16, B5.B16, T0.B16
+ VEOR B5.B16, T0.B16, T0.B16
+ VPMULL B5.D1, T1.D1, ACC1.Q1
+ VPMULL2 B5.D2, T1.D2, ACC0.Q1
+ VPMULL T0.D1, T2.D1, ACCM.Q1
+ reduce()
+
+ B singlesLoop
+tail:
+ CBZ srcPtrLen, done
+
+ VREV32 CTR.B16, B0.B16
+ VADD CTR.S4, INC.S4, CTR.S4
+
+ AESE K0.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K1.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K2.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K3.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K4.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K5.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K6.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K7.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K8.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE K9.B16, B0.B16
+ TBZ $4, NR, tailLast
+ AESMC B0.B16, B0.B16
+ AESE K10.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE B1.B16, B0.B16
+ TBZ $3, NR, tailLast
+ AESMC B0.B16, B0.B16
+ AESE B2.B16, B0.B16
+ AESMC B0.B16, B0.B16
+ AESE B3.B16, B0.B16
+tailLast:
+ VEOR KLAST.B16, B0.B16, B0.B16
+
+ // Assuming it is safe to load past dstPtr due to the presence of the tag
+ VLD1 (srcPtr), [B5.B16]
+
+ VEOR B5.B16, B0.B16, B0.B16
+
+ VEOR T3.B16, T3.B16, T3.B16
+ MOVD $0, H1
+ SUB $1, H1
+
+ TBZ $3, srcPtrLen, ld4
+ VMOV B0.D[0], H0
+ MOVD.P H0, 8(dstPtr)
+ VMOV H1, T3.D[0]
+ VEXT $8, ZERO.B16, B0.B16, B0.B16
+ld4:
+ TBZ $2, srcPtrLen, ld2
+ VMOV B0.S[0], H0
+ MOVW.P H0, 4(dstPtr)
+ VEXT $12, T3.B16, ZERO.B16, T3.B16
+ VMOV H1, T3.S[0]
+ VEXT $4, ZERO.B16, B0.B16, B0.B16
+ld2:
+ TBZ $1, srcPtrLen, ld1
+ VMOV B0.H[0], H0
+ MOVH.P H0, 2(dstPtr)
+ VEXT $14, T3.B16, ZERO.B16, T3.B16
+ VMOV H1, T3.H[0]
+ VEXT $2, ZERO.B16, B0.B16, B0.B16
+ld1:
+ TBZ $0, srcPtrLen, ld0
+ VMOV B0.B[0], H0
+ MOVB.P H0, 1(dstPtr)
+ VEXT $15, T3.B16, ZERO.B16, T3.B16
+ VMOV H1, T3.B[0]
+ld0:
+
+ VAND T3.B16, B5.B16, B5.B16
+ VREV64 B5.B16, B5.B16
+
+ VEOR ACC0.B16, B5.B16, B5.B16
+ VEXT $8, B5.B16, B5.B16, T0.B16
+ VEOR B5.B16, T0.B16, T0.B16
+ VPMULL B5.D1, T1.D1, ACC1.Q1
+ VPMULL2 B5.D2, T1.D2, ACC0.Q1
+ VPMULL T0.D1, T2.D1, ACCM.Q1
+ reduce()
+done:
+ VST1 [ACC0.B16], (tPtr)
+
+ RET
diff --git a/contrib/go/_std_1.20/src/crypto/aes/modes.go b/contrib/go/_std_1.21/src/crypto/aes/modes.go
index 5c0b08eb6d..5c0b08eb6d 100644
--- a/contrib/go/_std_1.20/src/crypto/aes/modes.go
+++ b/contrib/go/_std_1.21/src/crypto/aes/modes.go
diff --git a/contrib/go/_std_1.21/src/crypto/aes/ya.make b/contrib/go/_std_1.21/src/crypto/aes/ya.make
new file mode 100644
index 0000000000..5eb38390f3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/aes/ya.make
@@ -0,0 +1,34 @@
+GO_LIBRARY()
+
+SRCS(
+ aes_gcm.go
+ block.go
+ cipher.go
+ cipher_asm.go
+ const.go
+ modes.go
+)
+
+GO_TEST_SRCS(
+ aes_test.go
+ modes_test.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ asm_amd64.s
+ gcm_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ asm_arm64.s
+ gcm_arm64.s
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/cipher/cbc.go b/contrib/go/_std_1.21/src/crypto/cipher/cbc.go
index 51a142071f..51a142071f 100644
--- a/contrib/go/_std_1.20/src/crypto/cipher/cbc.go
+++ b/contrib/go/_std_1.21/src/crypto/cipher/cbc.go
diff --git a/contrib/go/_std_1.20/src/crypto/cipher/cfb.go b/contrib/go/_std_1.21/src/crypto/cipher/cfb.go
index aae3575da1..aae3575da1 100644
--- a/contrib/go/_std_1.20/src/crypto/cipher/cfb.go
+++ b/contrib/go/_std_1.21/src/crypto/cipher/cfb.go
diff --git a/contrib/go/_std_1.20/src/crypto/cipher/cipher.go b/contrib/go/_std_1.21/src/crypto/cipher/cipher.go
index df6f596b4d..df6f596b4d 100644
--- a/contrib/go/_std_1.20/src/crypto/cipher/cipher.go
+++ b/contrib/go/_std_1.21/src/crypto/cipher/cipher.go
diff --git a/contrib/go/_std_1.20/src/crypto/cipher/ctr.go b/contrib/go/_std_1.21/src/crypto/cipher/ctr.go
index 3ac0ff74d0..3ac0ff74d0 100644
--- a/contrib/go/_std_1.20/src/crypto/cipher/ctr.go
+++ b/contrib/go/_std_1.21/src/crypto/cipher/ctr.go
diff --git a/contrib/go/_std_1.20/src/crypto/cipher/gcm.go b/contrib/go/_std_1.21/src/crypto/cipher/gcm.go
index 477d26a0e0..477d26a0e0 100644
--- a/contrib/go/_std_1.20/src/crypto/cipher/gcm.go
+++ b/contrib/go/_std_1.21/src/crypto/cipher/gcm.go
diff --git a/contrib/go/_std_1.20/src/crypto/cipher/io.go b/contrib/go/_std_1.21/src/crypto/cipher/io.go
index 0974ac748e..0974ac748e 100644
--- a/contrib/go/_std_1.20/src/crypto/cipher/io.go
+++ b/contrib/go/_std_1.21/src/crypto/cipher/io.go
diff --git a/contrib/go/_std_1.20/src/crypto/cipher/ofb.go b/contrib/go/_std_1.21/src/crypto/cipher/ofb.go
index 1195fdd45a..1195fdd45a 100644
--- a/contrib/go/_std_1.20/src/crypto/cipher/ofb.go
+++ b/contrib/go/_std_1.21/src/crypto/cipher/ofb.go
diff --git a/contrib/go/_std_1.21/src/crypto/cipher/ya.make b/contrib/go/_std_1.21/src/crypto/cipher/ya.make
new file mode 100644
index 0000000000..a6b4e2f711
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/cipher/ya.make
@@ -0,0 +1,31 @@
+GO_LIBRARY()
+
+SRCS(
+ cbc.go
+ cfb.go
+ cipher.go
+ ctr.go
+ gcm.go
+ io.go
+ ofb.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ benchmark_test.go
+ cbc_aes_test.go
+ cfb_test.go
+ cipher_test.go
+ common_test.go
+ ctr_aes_test.go
+ ctr_test.go
+ example_test.go
+ gcm_test.go
+ ofb_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/crypto.go b/contrib/go/_std_1.21/src/crypto/crypto.go
index 10a1cd8403..10a1cd8403 100644
--- a/contrib/go/_std_1.20/src/crypto/crypto.go
+++ b/contrib/go/_std_1.21/src/crypto/crypto.go
diff --git a/contrib/go/_std_1.20/src/crypto/des/block.go b/contrib/go/_std_1.21/src/crypto/des/block.go
index e0299760d9..e0299760d9 100644
--- a/contrib/go/_std_1.20/src/crypto/des/block.go
+++ b/contrib/go/_std_1.21/src/crypto/des/block.go
diff --git a/contrib/go/_std_1.20/src/crypto/des/cipher.go b/contrib/go/_std_1.21/src/crypto/des/cipher.go
index ece764f171..ece764f171 100644
--- a/contrib/go/_std_1.20/src/crypto/des/cipher.go
+++ b/contrib/go/_std_1.21/src/crypto/des/cipher.go
diff --git a/contrib/go/_std_1.20/src/crypto/des/const.go b/contrib/go/_std_1.21/src/crypto/des/const.go
index a20879d574..a20879d574 100644
--- a/contrib/go/_std_1.20/src/crypto/des/const.go
+++ b/contrib/go/_std_1.21/src/crypto/des/const.go
diff --git a/contrib/go/_std_1.21/src/crypto/des/ya.make b/contrib/go/_std_1.21/src/crypto/des/ya.make
new file mode 100644
index 0000000000..976015eb31
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/des/ya.make
@@ -0,0 +1,16 @@
+GO_LIBRARY()
+
+SRCS(
+ block.go
+ cipher.go
+ const.go
+)
+
+GO_TEST_SRCS(des_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/dsa/dsa.go b/contrib/go/_std_1.21/src/crypto/dsa/dsa.go
index 29dab1c9fc..29dab1c9fc 100644
--- a/contrib/go/_std_1.20/src/crypto/dsa/dsa.go
+++ b/contrib/go/_std_1.21/src/crypto/dsa/dsa.go
diff --git a/contrib/go/_std_1.21/src/crypto/dsa/ya.make b/contrib/go/_std_1.21/src/crypto/dsa/ya.make
new file mode 100644
index 0000000000..0412fb0263
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/dsa/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ dsa.go
+)
+
+GO_TEST_SRCS(dsa_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/crypto/ecdh/ecdh.go b/contrib/go/_std_1.21/src/crypto/ecdh/ecdh.go
new file mode 100644
index 0000000000..b86f521787
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/ecdh/ecdh.go
@@ -0,0 +1,188 @@
+// Copyright 2022 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 ecdh implements Elliptic Curve Diffie-Hellman over
+// NIST curves and Curve25519.
+package ecdh
+
+import (
+ "crypto"
+ "crypto/internal/boring"
+ "crypto/subtle"
+ "errors"
+ "io"
+ "sync"
+)
+
+type Curve interface {
+ // GenerateKey generates a random PrivateKey.
+ //
+ // Most applications should use [crypto/rand.Reader] as rand. Note that the
+ // returned key does not depend deterministically on the bytes read from rand,
+ // and may change between calls and/or between versions.
+ GenerateKey(rand io.Reader) (*PrivateKey, error)
+
+ // NewPrivateKey checks that key is valid and returns a PrivateKey.
+ //
+ // For NIST curves, this follows SEC 1, Version 2.0, Section 2.3.6, which
+ // amounts to decoding the bytes as a fixed length big endian integer and
+ // checking that the result is lower than the order of the curve. The zero
+ // private key is also rejected, as the encoding of the corresponding public
+ // key would be irregular.
+ //
+ // For X25519, this only checks the scalar length.
+ NewPrivateKey(key []byte) (*PrivateKey, error)
+
+ // NewPublicKey checks that key is valid and returns a PublicKey.
+ //
+ // For NIST curves, this decodes an uncompressed point according to SEC 1,
+ // Version 2.0, Section 2.3.4. Compressed encodings and the point at
+ // infinity are rejected.
+ //
+ // For X25519, this only checks the u-coordinate length. Adversarially
+ // selected public keys can cause ECDH to return an error.
+ NewPublicKey(key []byte) (*PublicKey, error)
+
+ // ecdh performs a ECDH exchange and returns the shared secret. It's exposed
+ // as the PrivateKey.ECDH method.
+ //
+ // The private method also allow us to expand the ECDH interface with more
+ // methods in the future without breaking backwards compatibility.
+ ecdh(local *PrivateKey, remote *PublicKey) ([]byte, error)
+
+ // privateKeyToPublicKey converts a PrivateKey to a PublicKey. It's exposed
+ // as the PrivateKey.PublicKey method.
+ //
+ // This method always succeeds: for X25519, the zero key can't be
+ // constructed due to clamping; for NIST curves, it is rejected by
+ // NewPrivateKey.
+ privateKeyToPublicKey(*PrivateKey) *PublicKey
+}
+
+// PublicKey is an ECDH public key, usually a peer's ECDH share sent over the wire.
+//
+// These keys can be parsed with [crypto/x509.ParsePKIXPublicKey] and encoded
+// with [crypto/x509.MarshalPKIXPublicKey]. For NIST curves, they then need to
+// be converted with [crypto/ecdsa.PublicKey.ECDH] after parsing.
+type PublicKey struct {
+ curve Curve
+ publicKey []byte
+ boring *boring.PublicKeyECDH
+}
+
+// Bytes returns a copy of the encoding of the public key.
+func (k *PublicKey) Bytes() []byte {
+ // Copy the public key to a fixed size buffer that can get allocated on the
+ // caller's stack after inlining.
+ var buf [133]byte
+ return append(buf[:0], k.publicKey...)
+}
+
+// Equal returns whether x represents the same public key as k.
+//
+// Note that there can be equivalent public keys with different encodings which
+// would return false from this check but behave the same way as inputs to ECDH.
+//
+// This check is performed in constant time as long as the key types and their
+// curve match.
+func (k *PublicKey) Equal(x crypto.PublicKey) bool {
+ xx, ok := x.(*PublicKey)
+ if !ok {
+ return false
+ }
+ return k.curve == xx.curve &&
+ subtle.ConstantTimeCompare(k.publicKey, xx.publicKey) == 1
+}
+
+func (k *PublicKey) Curve() Curve {
+ return k.curve
+}
+
+// PrivateKey is an ECDH private key, usually kept secret.
+//
+// These keys can be parsed with [crypto/x509.ParsePKCS8PrivateKey] and encoded
+// with [crypto/x509.MarshalPKCS8PrivateKey]. For NIST curves, they then need to
+// be converted with [crypto/ecdsa.PrivateKey.ECDH] after parsing.
+type PrivateKey struct {
+ curve Curve
+ privateKey []byte
+ boring *boring.PrivateKeyECDH
+ // publicKey is set under publicKeyOnce, to allow loading private keys with
+ // NewPrivateKey without having to perform a scalar multiplication.
+ publicKey *PublicKey
+ publicKeyOnce sync.Once
+}
+
+// ECDH performs a ECDH exchange and returns the shared secret. The PrivateKey
+// and PublicKey must use the same curve.
+//
+// For NIST curves, this performs ECDH as specified in SEC 1, Version 2.0,
+// Section 3.3.1, and returns the x-coordinate encoded according to SEC 1,
+// Version 2.0, Section 2.3.5. The result is never the point at infinity.
+//
+// For X25519, this performs ECDH as specified in RFC 7748, Section 6.1. If
+// the result is the all-zero value, ECDH returns an error.
+func (k *PrivateKey) ECDH(remote *PublicKey) ([]byte, error) {
+ if k.curve != remote.curve {
+ return nil, errors.New("crypto/ecdh: private key and public key curves do not match")
+ }
+ return k.curve.ecdh(k, remote)
+}
+
+// Bytes returns a copy of the encoding of the private key.
+func (k *PrivateKey) Bytes() []byte {
+ // Copy the private key to a fixed size buffer that can get allocated on the
+ // caller's stack after inlining.
+ var buf [66]byte
+ return append(buf[:0], k.privateKey...)
+}
+
+// Equal returns whether x represents the same private key as k.
+//
+// Note that there can be equivalent private keys with different encodings which
+// would return false from this check but behave the same way as inputs to ECDH.
+//
+// This check is performed in constant time as long as the key types and their
+// curve match.
+func (k *PrivateKey) Equal(x crypto.PrivateKey) bool {
+ xx, ok := x.(*PrivateKey)
+ if !ok {
+ return false
+ }
+ return k.curve == xx.curve &&
+ subtle.ConstantTimeCompare(k.privateKey, xx.privateKey) == 1
+}
+
+func (k *PrivateKey) Curve() Curve {
+ return k.curve
+}
+
+func (k *PrivateKey) PublicKey() *PublicKey {
+ k.publicKeyOnce.Do(func() {
+ if k.boring != nil {
+ // Because we already checked in NewPrivateKey that the key is valid,
+ // there should not be any possible errors from BoringCrypto,
+ // so we turn the error into a panic.
+ // (We can't return it anyhow.)
+ kpub, err := k.boring.PublicKey()
+ if err != nil {
+ panic("boringcrypto: " + err.Error())
+ }
+ k.publicKey = &PublicKey{
+ curve: k.curve,
+ publicKey: kpub.Bytes(),
+ boring: kpub,
+ }
+ } else {
+ k.publicKey = k.curve.privateKeyToPublicKey(k)
+ }
+ })
+ return k.publicKey
+}
+
+// Public implements the implicit interface of all standard library private
+// keys. See the docs of crypto.PrivateKey.
+func (k *PrivateKey) Public() crypto.PublicKey {
+ return k.PublicKey()
+}
diff --git a/contrib/go/_std_1.20/src/crypto/ecdh/nist.go b/contrib/go/_std_1.21/src/crypto/ecdh/nist.go
index 01354fa2cf..01354fa2cf 100644
--- a/contrib/go/_std_1.20/src/crypto/ecdh/nist.go
+++ b/contrib/go/_std_1.21/src/crypto/ecdh/nist.go
diff --git a/contrib/go/_std_1.20/src/crypto/ecdh/x25519.go b/contrib/go/_std_1.21/src/crypto/ecdh/x25519.go
index dbc3ea9dc8..dbc3ea9dc8 100644
--- a/contrib/go/_std_1.20/src/crypto/ecdh/x25519.go
+++ b/contrib/go/_std_1.21/src/crypto/ecdh/x25519.go
diff --git a/contrib/go/_std_1.21/src/crypto/ecdh/ya.make b/contrib/go/_std_1.21/src/crypto/ecdh/ya.make
new file mode 100644
index 0000000000..3251ddf69e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/ecdh/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ ecdh.go
+ nist.go
+ x25519.go
+)
+
+GO_XTEST_SRCS(ecdh_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/crypto/ecdsa/ecdsa.go b/contrib/go/_std_1.21/src/crypto/ecdsa/ecdsa.go
new file mode 100644
index 0000000000..e1503779ae
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/ecdsa/ecdsa.go
@@ -0,0 +1,672 @@
+// Copyright 2011 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 ecdsa implements the Elliptic Curve Digital Signature Algorithm, as
+// defined in FIPS 186-4 and SEC 1, Version 2.0.
+//
+// Signatures generated by this package are not deterministic, but entropy is
+// mixed with the private key and the message, achieving the same level of
+// security in case of randomness source failure.
+package ecdsa
+
+// [FIPS 186-4] references ANSI X9.62-2005 for the bulk of the ECDSA algorithm.
+// That standard is not freely available, which is a problem in an open source
+// implementation, because not only the implementer, but also any maintainer,
+// contributor, reviewer, auditor, and learner needs access to it. Instead, this
+// package references and follows the equivalent [SEC 1, Version 2.0].
+//
+// [FIPS 186-4]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
+// [SEC 1, Version 2.0]: https://www.secg.org/sec1-v2.pdf
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/ecdh"
+ "crypto/elliptic"
+ "crypto/internal/bigmod"
+ "crypto/internal/boring"
+ "crypto/internal/boring/bbig"
+ "crypto/internal/nistec"
+ "crypto/internal/randutil"
+ "crypto/sha512"
+ "crypto/subtle"
+ "errors"
+ "io"
+ "math/big"
+ "sync"
+
+ "golang.org/x/crypto/cryptobyte"
+ "golang.org/x/crypto/cryptobyte/asn1"
+)
+
+// PublicKey represents an ECDSA public key.
+type PublicKey struct {
+ elliptic.Curve
+ X, Y *big.Int
+}
+
+// Any methods implemented on PublicKey might need to also be implemented on
+// PrivateKey, as the latter embeds the former and will expose its methods.
+
+// ECDH returns k as a [ecdh.PublicKey]. It returns an error if the key is
+// invalid according to the definition of [ecdh.Curve.NewPublicKey], or if the
+// Curve is not supported by crypto/ecdh.
+func (k *PublicKey) ECDH() (*ecdh.PublicKey, error) {
+ c := curveToECDH(k.Curve)
+ if c == nil {
+ return nil, errors.New("ecdsa: unsupported curve by crypto/ecdh")
+ }
+ if !k.Curve.IsOnCurve(k.X, k.Y) {
+ return nil, errors.New("ecdsa: invalid public key")
+ }
+ return c.NewPublicKey(elliptic.Marshal(k.Curve, k.X, k.Y))
+}
+
+// Equal reports whether pub and x have the same value.
+//
+// Two keys are only considered to have the same value if they have the same Curve value.
+// Note that for example elliptic.P256() and elliptic.P256().Params() are different
+// values, as the latter is a generic not constant time implementation.
+func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
+ xx, ok := x.(*PublicKey)
+ if !ok {
+ return false
+ }
+ return bigIntEqual(pub.X, xx.X) && bigIntEqual(pub.Y, xx.Y) &&
+ // Standard library Curve implementations are singletons, so this check
+ // will work for those. Other Curves might be equivalent even if not
+ // singletons, but there is no definitive way to check for that, and
+ // better to err on the side of safety.
+ pub.Curve == xx.Curve
+}
+
+// PrivateKey represents an ECDSA private key.
+type PrivateKey struct {
+ PublicKey
+ D *big.Int
+}
+
+// ECDH returns k as a [ecdh.PrivateKey]. It returns an error if the key is
+// invalid according to the definition of [ecdh.Curve.NewPrivateKey], or if the
+// Curve is not supported by crypto/ecdh.
+func (k *PrivateKey) ECDH() (*ecdh.PrivateKey, error) {
+ c := curveToECDH(k.Curve)
+ if c == nil {
+ return nil, errors.New("ecdsa: unsupported curve by crypto/ecdh")
+ }
+ size := (k.Curve.Params().N.BitLen() + 7) / 8
+ if k.D.BitLen() > size*8 {
+ return nil, errors.New("ecdsa: invalid private key")
+ }
+ return c.NewPrivateKey(k.D.FillBytes(make([]byte, size)))
+}
+
+func curveToECDH(c elliptic.Curve) ecdh.Curve {
+ switch c {
+ case elliptic.P256():
+ return ecdh.P256()
+ case elliptic.P384():
+ return ecdh.P384()
+ case elliptic.P521():
+ return ecdh.P521()
+ default:
+ return nil
+ }
+}
+
+// Public returns the public key corresponding to priv.
+func (priv *PrivateKey) Public() crypto.PublicKey {
+ return &priv.PublicKey
+}
+
+// Equal reports whether priv and x have the same value.
+//
+// See PublicKey.Equal for details on how Curve is compared.
+func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
+ xx, ok := x.(*PrivateKey)
+ if !ok {
+ return false
+ }
+ return priv.PublicKey.Equal(&xx.PublicKey) && bigIntEqual(priv.D, xx.D)
+}
+
+// bigIntEqual reports whether a and b are equal leaking only their bit length
+// through timing side-channels.
+func bigIntEqual(a, b *big.Int) bool {
+ return subtle.ConstantTimeCompare(a.Bytes(), b.Bytes()) == 1
+}
+
+// Sign signs digest with priv, reading randomness from rand. The opts argument
+// is not currently used but, in keeping with the crypto.Signer interface,
+// should be the hash function used to digest the message.
+//
+// This method implements crypto.Signer, which is an interface to support keys
+// where the private part is kept in, for example, a hardware module. Common
+// uses can use the SignASN1 function in this package directly.
+func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
+ return SignASN1(rand, priv, digest)
+}
+
+// GenerateKey generates a new ECDSA private key for the specified curve.
+//
+// Most applications should use [crypto/rand.Reader] as rand. Note that the
+// returned key does not depend deterministically on the bytes read from rand,
+// and may change between calls and/or between versions.
+func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
+ randutil.MaybeReadByte(rand)
+
+ if boring.Enabled && rand == boring.RandReader {
+ x, y, d, err := boring.GenerateKeyECDSA(c.Params().Name)
+ if err != nil {
+ return nil, err
+ }
+ return &PrivateKey{PublicKey: PublicKey{Curve: c, X: bbig.Dec(x), Y: bbig.Dec(y)}, D: bbig.Dec(d)}, nil
+ }
+ boring.UnreachableExceptTests()
+
+ switch c.Params() {
+ case elliptic.P224().Params():
+ return generateNISTEC(p224(), rand)
+ case elliptic.P256().Params():
+ return generateNISTEC(p256(), rand)
+ case elliptic.P384().Params():
+ return generateNISTEC(p384(), rand)
+ case elliptic.P521().Params():
+ return generateNISTEC(p521(), rand)
+ default:
+ return generateLegacy(c, rand)
+ }
+}
+
+func generateNISTEC[Point nistPoint[Point]](c *nistCurve[Point], rand io.Reader) (*PrivateKey, error) {
+ k, Q, err := randomPoint(c, rand)
+ if err != nil {
+ return nil, err
+ }
+
+ priv := new(PrivateKey)
+ priv.PublicKey.Curve = c.curve
+ priv.D = new(big.Int).SetBytes(k.Bytes(c.N))
+ priv.PublicKey.X, priv.PublicKey.Y, err = c.pointToAffine(Q)
+ if err != nil {
+ return nil, err
+ }
+ return priv, nil
+}
+
+// randomPoint returns a random scalar and the corresponding point using the
+// procedure given in FIPS 186-4, Appendix B.5.2 (rejection sampling).
+func randomPoint[Point nistPoint[Point]](c *nistCurve[Point], rand io.Reader) (k *bigmod.Nat, p Point, err error) {
+ k = bigmod.NewNat()
+ for {
+ b := make([]byte, c.N.Size())
+ if _, err = io.ReadFull(rand, b); err != nil {
+ return
+ }
+
+ // Mask off any excess bits to increase the chance of hitting a value in
+ // (0, N). These are the most dangerous lines in the package and maybe in
+ // the library: a single bit of bias in the selection of nonces would likely
+ // lead to key recovery, but no tests would fail. Look but DO NOT TOUCH.
+ if excess := len(b)*8 - c.N.BitLen(); excess > 0 {
+ // Just to be safe, assert that this only happens for the one curve that
+ // doesn't have a round number of bits.
+ if excess != 0 && c.curve.Params().Name != "P-521" {
+ panic("ecdsa: internal error: unexpectedly masking off bits")
+ }
+ b[0] >>= excess
+ }
+
+ // FIPS 186-4 makes us check k <= N - 2 and then add one.
+ // Checking 0 < k <= N - 1 is strictly equivalent.
+ // None of this matters anyway because the chance of selecting
+ // zero is cryptographically negligible.
+ if _, err = k.SetBytes(b, c.N); err == nil && k.IsZero() == 0 {
+ break
+ }
+
+ if testingOnlyRejectionSamplingLooped != nil {
+ testingOnlyRejectionSamplingLooped()
+ }
+ }
+
+ p, err = c.newPoint().ScalarBaseMult(k.Bytes(c.N))
+ return
+}
+
+// testingOnlyRejectionSamplingLooped is called when rejection sampling in
+// randomPoint rejects a candidate for being higher than the modulus.
+var testingOnlyRejectionSamplingLooped func()
+
+// errNoAsm is returned by signAsm and verifyAsm when the assembly
+// implementation is not available.
+var errNoAsm = errors.New("no assembly implementation available")
+
+// SignASN1 signs a hash (which should be the result of hashing a larger message)
+// using the private key, priv. If the hash is longer than the bit-length of the
+// private key's curve order, the hash will be truncated to that length. It
+// returns the ASN.1 encoded signature.
+//
+// The signature is randomized. Most applications should use [crypto/rand.Reader]
+// as rand. Note that the returned signature does not depend deterministically on
+// the bytes read from rand, and may change between calls and/or between versions.
+func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
+ randutil.MaybeReadByte(rand)
+
+ if boring.Enabled && rand == boring.RandReader {
+ b, err := boringPrivateKey(priv)
+ if err != nil {
+ return nil, err
+ }
+ return boring.SignMarshalECDSA(b, hash)
+ }
+ boring.UnreachableExceptTests()
+
+ csprng, err := mixedCSPRNG(rand, priv, hash)
+ if err != nil {
+ return nil, err
+ }
+
+ if sig, err := signAsm(priv, csprng, hash); err != errNoAsm {
+ return sig, err
+ }
+
+ switch priv.Curve.Params() {
+ case elliptic.P224().Params():
+ return signNISTEC(p224(), priv, csprng, hash)
+ case elliptic.P256().Params():
+ return signNISTEC(p256(), priv, csprng, hash)
+ case elliptic.P384().Params():
+ return signNISTEC(p384(), priv, csprng, hash)
+ case elliptic.P521().Params():
+ return signNISTEC(p521(), priv, csprng, hash)
+ default:
+ return signLegacy(priv, csprng, hash)
+ }
+}
+
+func signNISTEC[Point nistPoint[Point]](c *nistCurve[Point], priv *PrivateKey, csprng io.Reader, hash []byte) (sig []byte, err error) {
+ // SEC 1, Version 2.0, Section 4.1.3
+
+ k, R, err := randomPoint(c, csprng)
+ if err != nil {
+ return nil, err
+ }
+
+ // kInv = k⁻¹
+ kInv := bigmod.NewNat()
+ inverse(c, kInv, k)
+
+ Rx, err := R.BytesX()
+ if err != nil {
+ return nil, err
+ }
+ r, err := bigmod.NewNat().SetOverflowingBytes(Rx, c.N)
+ if err != nil {
+ return nil, err
+ }
+
+ // The spec wants us to retry here, but the chance of hitting this condition
+ // on a large prime-order group like the NIST curves we support is
+ // cryptographically negligible. If we hit it, something is awfully wrong.
+ if r.IsZero() == 1 {
+ return nil, errors.New("ecdsa: internal error: r is zero")
+ }
+
+ e := bigmod.NewNat()
+ hashToNat(c, e, hash)
+
+ s, err := bigmod.NewNat().SetBytes(priv.D.Bytes(), c.N)
+ if err != nil {
+ return nil, err
+ }
+ s.Mul(r, c.N)
+ s.Add(e, c.N)
+ s.Mul(kInv, c.N)
+
+ // Again, the chance of this happening is cryptographically negligible.
+ if s.IsZero() == 1 {
+ return nil, errors.New("ecdsa: internal error: s is zero")
+ }
+
+ return encodeSignature(r.Bytes(c.N), s.Bytes(c.N))
+}
+
+func encodeSignature(r, s []byte) ([]byte, error) {
+ var b cryptobyte.Builder
+ b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ addASN1IntBytes(b, r)
+ addASN1IntBytes(b, s)
+ })
+ return b.Bytes()
+}
+
+// addASN1IntBytes encodes in ASN.1 a positive integer represented as
+// a big-endian byte slice with zero or more leading zeroes.
+func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) {
+ for len(bytes) > 0 && bytes[0] == 0 {
+ bytes = bytes[1:]
+ }
+ if len(bytes) == 0 {
+ b.SetError(errors.New("invalid integer"))
+ return
+ }
+ b.AddASN1(asn1.INTEGER, func(c *cryptobyte.Builder) {
+ if bytes[0]&0x80 != 0 {
+ c.AddUint8(0)
+ }
+ c.AddBytes(bytes)
+ })
+}
+
+// inverse sets kInv to the inverse of k modulo the order of the curve.
+func inverse[Point nistPoint[Point]](c *nistCurve[Point], kInv, k *bigmod.Nat) {
+ if c.curve.Params().Name == "P-256" {
+ kBytes, err := nistec.P256OrdInverse(k.Bytes(c.N))
+ // Some platforms don't implement P256OrdInverse, and always return an error.
+ if err == nil {
+ _, err := kInv.SetBytes(kBytes, c.N)
+ if err != nil {
+ panic("ecdsa: internal error: P256OrdInverse produced an invalid value")
+ }
+ return
+ }
+ }
+
+ // Calculate the inverse of s in GF(N) using Fermat's method
+ // (exponentiation modulo P - 2, per Euler's theorem)
+ kInv.Exp(k, c.nMinus2, c.N)
+}
+
+// hashToNat sets e to the left-most bits of hash, according to
+// SEC 1, Section 4.1.3, point 5 and Section 4.1.4, point 3.
+func hashToNat[Point nistPoint[Point]](c *nistCurve[Point], e *bigmod.Nat, hash []byte) {
+ // ECDSA asks us to take the left-most log2(N) bits of hash, and use them as
+ // an integer modulo N. This is the absolute worst of all worlds: we still
+ // have to reduce, because the result might still overflow N, but to take
+ // the left-most bits for P-521 we have to do a right shift.
+ if size := c.N.Size(); len(hash) >= size {
+ hash = hash[:size]
+ if excess := len(hash)*8 - c.N.BitLen(); excess > 0 {
+ hash = bytes.Clone(hash)
+ for i := len(hash) - 1; i >= 0; i-- {
+ hash[i] >>= excess
+ if i > 0 {
+ hash[i] |= hash[i-1] << (8 - excess)
+ }
+ }
+ }
+ }
+ _, err := e.SetOverflowingBytes(hash, c.N)
+ if err != nil {
+ panic("ecdsa: internal error: truncated hash is too long")
+ }
+}
+
+// mixedCSPRNG returns a CSPRNG that mixes entropy from rand with the message
+// and the private key, to protect the key in case rand fails. This is
+// equivalent in security to RFC 6979 deterministic nonce generation, but still
+// produces randomized signatures.
+func mixedCSPRNG(rand io.Reader, priv *PrivateKey, hash []byte) (io.Reader, error) {
+ // This implementation derives the nonce from an AES-CTR CSPRNG keyed by:
+ //
+ // SHA2-512(priv.D || entropy || hash)[:32]
+ //
+ // The CSPRNG key is indifferentiable from a random oracle as shown in
+ // [Coron], the AES-CTR stream is indifferentiable from a random oracle
+ // under standard cryptographic assumptions (see [Larsson] for examples).
+ //
+ // [Coron]: https://cs.nyu.edu/~dodis/ps/merkle.pdf
+ // [Larsson]: https://web.archive.org/web/20040719170906/https://www.nada.kth.se/kurser/kth/2D1441/semteo03/lecturenotes/assump.pdf
+
+ // Get 256 bits of entropy from rand.
+ entropy := make([]byte, 32)
+ if _, err := io.ReadFull(rand, entropy); err != nil {
+ return nil, err
+ }
+
+ // Initialize an SHA-512 hash context; digest...
+ md := sha512.New()
+ md.Write(priv.D.Bytes()) // the private key,
+ md.Write(entropy) // the entropy,
+ md.Write(hash) // and the input hash;
+ key := md.Sum(nil)[:32] // and compute ChopMD-256(SHA-512),
+ // which is an indifferentiable MAC.
+
+ // Create an AES-CTR instance to use as a CSPRNG.
+ block, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, err
+ }
+
+ // Create a CSPRNG that xors a stream of zeros with
+ // the output of the AES-CTR instance.
+ const aesIV = "IV for ECDSA CTR"
+ return &cipher.StreamReader{
+ R: zeroReader,
+ S: cipher.NewCTR(block, []byte(aesIV)),
+ }, nil
+}
+
+type zr struct{}
+
+var zeroReader = zr{}
+
+// Read replaces the contents of dst with zeros. It is safe for concurrent use.
+func (zr) Read(dst []byte) (n int, err error) {
+ for i := range dst {
+ dst[i] = 0
+ }
+ return len(dst), nil
+}
+
+// VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the
+// public key, pub. Its return value records whether the signature is valid.
+func VerifyASN1(pub *PublicKey, hash, sig []byte) bool {
+ if boring.Enabled {
+ key, err := boringPublicKey(pub)
+ if err != nil {
+ return false
+ }
+ return boring.VerifyECDSA(key, hash, sig)
+ }
+ boring.UnreachableExceptTests()
+
+ if err := verifyAsm(pub, hash, sig); err != errNoAsm {
+ return err == nil
+ }
+
+ switch pub.Curve.Params() {
+ case elliptic.P224().Params():
+ return verifyNISTEC(p224(), pub, hash, sig)
+ case elliptic.P256().Params():
+ return verifyNISTEC(p256(), pub, hash, sig)
+ case elliptic.P384().Params():
+ return verifyNISTEC(p384(), pub, hash, sig)
+ case elliptic.P521().Params():
+ return verifyNISTEC(p521(), pub, hash, sig)
+ default:
+ return verifyLegacy(pub, hash, sig)
+ }
+}
+
+func verifyNISTEC[Point nistPoint[Point]](c *nistCurve[Point], pub *PublicKey, hash, sig []byte) bool {
+ rBytes, sBytes, err := parseSignature(sig)
+ if err != nil {
+ return false
+ }
+
+ Q, err := c.pointFromAffine(pub.X, pub.Y)
+ if err != nil {
+ return false
+ }
+
+ // SEC 1, Version 2.0, Section 4.1.4
+
+ r, err := bigmod.NewNat().SetBytes(rBytes, c.N)
+ if err != nil || r.IsZero() == 1 {
+ return false
+ }
+ s, err := bigmod.NewNat().SetBytes(sBytes, c.N)
+ if err != nil || s.IsZero() == 1 {
+ return false
+ }
+
+ e := bigmod.NewNat()
+ hashToNat(c, e, hash)
+
+ // w = s⁻¹
+ w := bigmod.NewNat()
+ inverse(c, w, s)
+
+ // p₁ = [e * s⁻¹]G
+ p1, err := c.newPoint().ScalarBaseMult(e.Mul(w, c.N).Bytes(c.N))
+ if err != nil {
+ return false
+ }
+ // p₂ = [r * s⁻¹]Q
+ p2, err := Q.ScalarMult(Q, w.Mul(r, c.N).Bytes(c.N))
+ if err != nil {
+ return false
+ }
+ // BytesX returns an error for the point at infinity.
+ Rx, err := p1.Add(p1, p2).BytesX()
+ if err != nil {
+ return false
+ }
+
+ v, err := bigmod.NewNat().SetOverflowingBytes(Rx, c.N)
+ if err != nil {
+ return false
+ }
+
+ return v.Equal(r) == 1
+}
+
+func parseSignature(sig []byte) (r, s []byte, err error) {
+ var inner cryptobyte.String
+ input := cryptobyte.String(sig)
+ if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
+ !input.Empty() ||
+ !inner.ReadASN1Integer(&r) ||
+ !inner.ReadASN1Integer(&s) ||
+ !inner.Empty() {
+ return nil, nil, errors.New("invalid ASN.1")
+ }
+ return r, s, nil
+}
+
+type nistCurve[Point nistPoint[Point]] struct {
+ newPoint func() Point
+ curve elliptic.Curve
+ N *bigmod.Modulus
+ nMinus2 []byte
+}
+
+// nistPoint is a generic constraint for the nistec Point types.
+type nistPoint[T any] interface {
+ Bytes() []byte
+ BytesX() ([]byte, error)
+ SetBytes([]byte) (T, error)
+ Add(T, T) T
+ ScalarMult(T, []byte) (T, error)
+ ScalarBaseMult([]byte) (T, error)
+}
+
+// pointFromAffine is used to convert the PublicKey to a nistec Point.
+func (curve *nistCurve[Point]) pointFromAffine(x, y *big.Int) (p Point, err error) {
+ bitSize := curve.curve.Params().BitSize
+ // Reject values that would not get correctly encoded.
+ if x.Sign() < 0 || y.Sign() < 0 {
+ return p, errors.New("negative coordinate")
+ }
+ if x.BitLen() > bitSize || y.BitLen() > bitSize {
+ return p, errors.New("overflowing coordinate")
+ }
+ // Encode the coordinates and let SetBytes reject invalid points.
+ byteLen := (bitSize + 7) / 8
+ buf := make([]byte, 1+2*byteLen)
+ buf[0] = 4 // uncompressed point
+ x.FillBytes(buf[1 : 1+byteLen])
+ y.FillBytes(buf[1+byteLen : 1+2*byteLen])
+ return curve.newPoint().SetBytes(buf)
+}
+
+// pointToAffine is used to convert a nistec Point to a PublicKey.
+func (curve *nistCurve[Point]) pointToAffine(p Point) (x, y *big.Int, err error) {
+ out := p.Bytes()
+ if len(out) == 1 && out[0] == 0 {
+ // This is the encoding of the point at infinity.
+ return nil, nil, errors.New("ecdsa: public key point is the infinity")
+ }
+ byteLen := (curve.curve.Params().BitSize + 7) / 8
+ x = new(big.Int).SetBytes(out[1 : 1+byteLen])
+ y = new(big.Int).SetBytes(out[1+byteLen:])
+ return x, y, nil
+}
+
+var p224Once sync.Once
+var _p224 *nistCurve[*nistec.P224Point]
+
+func p224() *nistCurve[*nistec.P224Point] {
+ p224Once.Do(func() {
+ _p224 = &nistCurve[*nistec.P224Point]{
+ newPoint: func() *nistec.P224Point { return nistec.NewP224Point() },
+ }
+ precomputeParams(_p224, elliptic.P224())
+ })
+ return _p224
+}
+
+var p256Once sync.Once
+var _p256 *nistCurve[*nistec.P256Point]
+
+func p256() *nistCurve[*nistec.P256Point] {
+ p256Once.Do(func() {
+ _p256 = &nistCurve[*nistec.P256Point]{
+ newPoint: func() *nistec.P256Point { return nistec.NewP256Point() },
+ }
+ precomputeParams(_p256, elliptic.P256())
+ })
+ return _p256
+}
+
+var p384Once sync.Once
+var _p384 *nistCurve[*nistec.P384Point]
+
+func p384() *nistCurve[*nistec.P384Point] {
+ p384Once.Do(func() {
+ _p384 = &nistCurve[*nistec.P384Point]{
+ newPoint: func() *nistec.P384Point { return nistec.NewP384Point() },
+ }
+ precomputeParams(_p384, elliptic.P384())
+ })
+ return _p384
+}
+
+var p521Once sync.Once
+var _p521 *nistCurve[*nistec.P521Point]
+
+func p521() *nistCurve[*nistec.P521Point] {
+ p521Once.Do(func() {
+ _p521 = &nistCurve[*nistec.P521Point]{
+ newPoint: func() *nistec.P521Point { return nistec.NewP521Point() },
+ }
+ precomputeParams(_p521, elliptic.P521())
+ })
+ return _p521
+}
+
+func precomputeParams[Point nistPoint[Point]](c *nistCurve[Point], curve elliptic.Curve) {
+ params := curve.Params()
+ c.curve = curve
+ var err error
+ c.N, err = bigmod.NewModulusFromBig(params.N)
+ if err != nil {
+ panic(err)
+ }
+ c.nMinus2 = new(big.Int).Sub(params.N, big.NewInt(2)).Bytes()
+}
diff --git a/contrib/go/_std_1.20/src/crypto/ecdsa/ecdsa_legacy.go b/contrib/go/_std_1.21/src/crypto/ecdsa/ecdsa_legacy.go
index 12a40e4828..12a40e4828 100644
--- a/contrib/go/_std_1.20/src/crypto/ecdsa/ecdsa_legacy.go
+++ b/contrib/go/_std_1.21/src/crypto/ecdsa/ecdsa_legacy.go
diff --git a/contrib/go/_std_1.20/src/crypto/ecdsa/ecdsa_noasm.go b/contrib/go/_std_1.21/src/crypto/ecdsa/ecdsa_noasm.go
index a72aa4b04e..a72aa4b04e 100644
--- a/contrib/go/_std_1.20/src/crypto/ecdsa/ecdsa_noasm.go
+++ b/contrib/go/_std_1.21/src/crypto/ecdsa/ecdsa_noasm.go
diff --git a/contrib/go/_std_1.20/src/crypto/ecdsa/notboring.go b/contrib/go/_std_1.21/src/crypto/ecdsa/notboring.go
index 039bd82ed2..039bd82ed2 100644
--- a/contrib/go/_std_1.20/src/crypto/ecdsa/notboring.go
+++ b/contrib/go/_std_1.21/src/crypto/ecdsa/notboring.go
diff --git a/contrib/go/_std_1.21/src/crypto/ecdsa/ya.make b/contrib/go/_std_1.21/src/crypto/ecdsa/ya.make
new file mode 100644
index 0000000000..833256a8bd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/ecdsa/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ ecdsa.go
+ ecdsa_legacy.go
+ ecdsa_noasm.go
+ notboring.go
+)
+
+GO_TEST_SRCS(ecdsa_test.go)
+
+GO_XTEST_SRCS(
+ equal_test.go
+ example_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/crypto/ed25519/ed25519.go b/contrib/go/_std_1.21/src/crypto/ed25519/ed25519.go
new file mode 100644
index 0000000000..1dda9e5e9a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/ed25519/ed25519.go
@@ -0,0 +1,344 @@
+// Copyright 2016 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 ed25519 implements the Ed25519 signature algorithm. See
+// https://ed25519.cr.yp.to/.
+//
+// These functions are also compatible with the “Ed25519” function defined in
+// RFC 8032. However, unlike RFC 8032's formulation, this package's private key
+// representation includes a public key suffix to make multiple signing
+// operations with the same key more efficient. This package refers to the RFC
+// 8032 private key as the “seed”.
+package ed25519
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/internal/edwards25519"
+ cryptorand "crypto/rand"
+ "crypto/sha512"
+ "crypto/subtle"
+ "errors"
+ "io"
+ "strconv"
+)
+
+const (
+ // PublicKeySize is the size, in bytes, of public keys as used in this package.
+ PublicKeySize = 32
+ // PrivateKeySize is the size, in bytes, of private keys as used in this package.
+ PrivateKeySize = 64
+ // SignatureSize is the size, in bytes, of signatures generated and verified by this package.
+ SignatureSize = 64
+ // SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032.
+ SeedSize = 32
+)
+
+// PublicKey is the type of Ed25519 public keys.
+type PublicKey []byte
+
+// Any methods implemented on PublicKey might need to also be implemented on
+// PrivateKey, as the latter embeds the former and will expose its methods.
+
+// Equal reports whether pub and x have the same value.
+func (pub PublicKey) Equal(x crypto.PublicKey) bool {
+ xx, ok := x.(PublicKey)
+ if !ok {
+ return false
+ }
+ return subtle.ConstantTimeCompare(pub, xx) == 1
+}
+
+// PrivateKey is the type of Ed25519 private keys. It implements [crypto.Signer].
+type PrivateKey []byte
+
+// Public returns the [PublicKey] corresponding to priv.
+func (priv PrivateKey) Public() crypto.PublicKey {
+ publicKey := make([]byte, PublicKeySize)
+ copy(publicKey, priv[32:])
+ return PublicKey(publicKey)
+}
+
+// Equal reports whether priv and x have the same value.
+func (priv PrivateKey) Equal(x crypto.PrivateKey) bool {
+ xx, ok := x.(PrivateKey)
+ if !ok {
+ return false
+ }
+ return subtle.ConstantTimeCompare(priv, xx) == 1
+}
+
+// Seed returns the private key seed corresponding to priv. It is provided for
+// interoperability with RFC 8032. RFC 8032's private keys correspond to seeds
+// in this package.
+func (priv PrivateKey) Seed() []byte {
+ return bytes.Clone(priv[:SeedSize])
+}
+
+// Sign signs the given message with priv. rand is ignored and can be nil.
+//
+// If opts.HashFunc() is [crypto.SHA512], the pre-hashed variant Ed25519ph is used
+// and message is expected to be a SHA-512 hash, otherwise opts.HashFunc() must
+// be [crypto.Hash](0) and the message must not be hashed, as Ed25519 performs two
+// passes over messages to be signed.
+//
+// A value of type [Options] can be used as opts, or crypto.Hash(0) or
+// crypto.SHA512 directly to select plain Ed25519 or Ed25519ph, respectively.
+func (priv PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) (signature []byte, err error) {
+ hash := opts.HashFunc()
+ context := ""
+ if opts, ok := opts.(*Options); ok {
+ context = opts.Context
+ }
+ switch {
+ case hash == crypto.SHA512: // Ed25519ph
+ if l := len(message); l != sha512.Size {
+ return nil, errors.New("ed25519: bad Ed25519ph message hash length: " + strconv.Itoa(l))
+ }
+ if l := len(context); l > 255 {
+ return nil, errors.New("ed25519: bad Ed25519ph context length: " + strconv.Itoa(l))
+ }
+ signature := make([]byte, SignatureSize)
+ sign(signature, priv, message, domPrefixPh, context)
+ return signature, nil
+ case hash == crypto.Hash(0) && context != "": // Ed25519ctx
+ if l := len(context); l > 255 {
+ return nil, errors.New("ed25519: bad Ed25519ctx context length: " + strconv.Itoa(l))
+ }
+ signature := make([]byte, SignatureSize)
+ sign(signature, priv, message, domPrefixCtx, context)
+ return signature, nil
+ case hash == crypto.Hash(0): // Ed25519
+ return Sign(priv, message), nil
+ default:
+ return nil, errors.New("ed25519: expected opts.HashFunc() zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)")
+ }
+}
+
+// Options can be used with [PrivateKey.Sign] or [VerifyWithOptions]
+// to select Ed25519 variants.
+type Options struct {
+ // Hash can be zero for regular Ed25519, or crypto.SHA512 for Ed25519ph.
+ Hash crypto.Hash
+
+ // Context, if not empty, selects Ed25519ctx or provides the context string
+ // for Ed25519ph. It can be at most 255 bytes in length.
+ Context string
+}
+
+// HashFunc returns o.Hash.
+func (o *Options) HashFunc() crypto.Hash { return o.Hash }
+
+// GenerateKey generates a public/private key pair using entropy from rand.
+// If rand is nil, [crypto/rand.Reader] will be used.
+//
+// The output of this function is deterministic, and equivalent to reading
+// [SeedSize] bytes from rand, and passing them to [NewKeyFromSeed].
+func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) {
+ if rand == nil {
+ rand = cryptorand.Reader
+ }
+
+ seed := make([]byte, SeedSize)
+ if _, err := io.ReadFull(rand, seed); err != nil {
+ return nil, nil, err
+ }
+
+ privateKey := NewKeyFromSeed(seed)
+ publicKey := make([]byte, PublicKeySize)
+ copy(publicKey, privateKey[32:])
+
+ return publicKey, privateKey, nil
+}
+
+// NewKeyFromSeed calculates a private key from a seed. It will panic if
+// len(seed) is not [SeedSize]. This function is provided for interoperability
+// with RFC 8032. RFC 8032's private keys correspond to seeds in this
+// package.
+func NewKeyFromSeed(seed []byte) PrivateKey {
+ // Outline the function body so that the returned key can be stack-allocated.
+ privateKey := make([]byte, PrivateKeySize)
+ newKeyFromSeed(privateKey, seed)
+ return privateKey
+}
+
+func newKeyFromSeed(privateKey, seed []byte) {
+ if l := len(seed); l != SeedSize {
+ panic("ed25519: bad seed length: " + strconv.Itoa(l))
+ }
+
+ h := sha512.Sum512(seed)
+ s, err := edwards25519.NewScalar().SetBytesWithClamping(h[:32])
+ if err != nil {
+ panic("ed25519: internal error: setting scalar failed")
+ }
+ A := (&edwards25519.Point{}).ScalarBaseMult(s)
+
+ publicKey := A.Bytes()
+
+ copy(privateKey, seed)
+ copy(privateKey[32:], publicKey)
+}
+
+// Sign signs the message with privateKey and returns a signature. It will
+// panic if len(privateKey) is not [PrivateKeySize].
+func Sign(privateKey PrivateKey, message []byte) []byte {
+ // Outline the function body so that the returned signature can be
+ // stack-allocated.
+ signature := make([]byte, SignatureSize)
+ sign(signature, privateKey, message, domPrefixPure, "")
+ return signature
+}
+
+// Domain separation prefixes used to disambiguate Ed25519/Ed25519ph/Ed25519ctx.
+// See RFC 8032, Section 2 and Section 5.1.
+const (
+ // domPrefixPure is empty for pure Ed25519.
+ domPrefixPure = ""
+ // domPrefixPh is dom2(phflag=1) for Ed25519ph. It must be followed by the
+ // uint8-length prefixed context.
+ domPrefixPh = "SigEd25519 no Ed25519 collisions\x01"
+ // domPrefixCtx is dom2(phflag=0) for Ed25519ctx. It must be followed by the
+ // uint8-length prefixed context.
+ domPrefixCtx = "SigEd25519 no Ed25519 collisions\x00"
+)
+
+func sign(signature, privateKey, message []byte, domPrefix, context string) {
+ if l := len(privateKey); l != PrivateKeySize {
+ panic("ed25519: bad private key length: " + strconv.Itoa(l))
+ }
+ seed, publicKey := privateKey[:SeedSize], privateKey[SeedSize:]
+
+ h := sha512.Sum512(seed)
+ s, err := edwards25519.NewScalar().SetBytesWithClamping(h[:32])
+ if err != nil {
+ panic("ed25519: internal error: setting scalar failed")
+ }
+ prefix := h[32:]
+
+ mh := sha512.New()
+ if domPrefix != domPrefixPure {
+ mh.Write([]byte(domPrefix))
+ mh.Write([]byte{byte(len(context))})
+ mh.Write([]byte(context))
+ }
+ mh.Write(prefix)
+ mh.Write(message)
+ messageDigest := make([]byte, 0, sha512.Size)
+ messageDigest = mh.Sum(messageDigest)
+ r, err := edwards25519.NewScalar().SetUniformBytes(messageDigest)
+ if err != nil {
+ panic("ed25519: internal error: setting scalar failed")
+ }
+
+ R := (&edwards25519.Point{}).ScalarBaseMult(r)
+
+ kh := sha512.New()
+ if domPrefix != domPrefixPure {
+ kh.Write([]byte(domPrefix))
+ kh.Write([]byte{byte(len(context))})
+ kh.Write([]byte(context))
+ }
+ kh.Write(R.Bytes())
+ kh.Write(publicKey)
+ kh.Write(message)
+ hramDigest := make([]byte, 0, sha512.Size)
+ hramDigest = kh.Sum(hramDigest)
+ k, err := edwards25519.NewScalar().SetUniformBytes(hramDigest)
+ if err != nil {
+ panic("ed25519: internal error: setting scalar failed")
+ }
+
+ S := edwards25519.NewScalar().MultiplyAdd(k, s, r)
+
+ copy(signature[:32], R.Bytes())
+ copy(signature[32:], S.Bytes())
+}
+
+// Verify reports whether sig is a valid signature of message by publicKey. It
+// will panic if len(publicKey) is not [PublicKeySize].
+func Verify(publicKey PublicKey, message, sig []byte) bool {
+ return verify(publicKey, message, sig, domPrefixPure, "")
+}
+
+// VerifyWithOptions reports whether sig is a valid signature of message by
+// publicKey. A valid signature is indicated by returning a nil error. It will
+// panic if len(publicKey) is not [PublicKeySize].
+//
+// If opts.Hash is [crypto.SHA512], the pre-hashed variant Ed25519ph is used and
+// message is expected to be a SHA-512 hash, otherwise opts.Hash must be
+// [crypto.Hash](0) and the message must not be hashed, as Ed25519 performs two
+// passes over messages to be signed.
+func VerifyWithOptions(publicKey PublicKey, message, sig []byte, opts *Options) error {
+ switch {
+ case opts.Hash == crypto.SHA512: // Ed25519ph
+ if l := len(message); l != sha512.Size {
+ return errors.New("ed25519: bad Ed25519ph message hash length: " + strconv.Itoa(l))
+ }
+ if l := len(opts.Context); l > 255 {
+ return errors.New("ed25519: bad Ed25519ph context length: " + strconv.Itoa(l))
+ }
+ if !verify(publicKey, message, sig, domPrefixPh, opts.Context) {
+ return errors.New("ed25519: invalid signature")
+ }
+ return nil
+ case opts.Hash == crypto.Hash(0) && opts.Context != "": // Ed25519ctx
+ if l := len(opts.Context); l > 255 {
+ return errors.New("ed25519: bad Ed25519ctx context length: " + strconv.Itoa(l))
+ }
+ if !verify(publicKey, message, sig, domPrefixCtx, opts.Context) {
+ return errors.New("ed25519: invalid signature")
+ }
+ return nil
+ case opts.Hash == crypto.Hash(0): // Ed25519
+ if !verify(publicKey, message, sig, domPrefixPure, "") {
+ return errors.New("ed25519: invalid signature")
+ }
+ return nil
+ default:
+ return errors.New("ed25519: expected opts.Hash zero (unhashed message, for standard Ed25519) or SHA-512 (for Ed25519ph)")
+ }
+}
+
+func verify(publicKey PublicKey, message, sig []byte, domPrefix, context string) bool {
+ if l := len(publicKey); l != PublicKeySize {
+ panic("ed25519: bad public key length: " + strconv.Itoa(l))
+ }
+
+ if len(sig) != SignatureSize || sig[63]&224 != 0 {
+ return false
+ }
+
+ A, err := (&edwards25519.Point{}).SetBytes(publicKey)
+ if err != nil {
+ return false
+ }
+
+ kh := sha512.New()
+ if domPrefix != domPrefixPure {
+ kh.Write([]byte(domPrefix))
+ kh.Write([]byte{byte(len(context))})
+ kh.Write([]byte(context))
+ }
+ kh.Write(sig[:32])
+ kh.Write(publicKey)
+ kh.Write(message)
+ hramDigest := make([]byte, 0, sha512.Size)
+ hramDigest = kh.Sum(hramDigest)
+ k, err := edwards25519.NewScalar().SetUniformBytes(hramDigest)
+ if err != nil {
+ panic("ed25519: internal error: setting scalar failed")
+ }
+
+ S, err := edwards25519.NewScalar().SetCanonicalBytes(sig[32:])
+ if err != nil {
+ return false
+ }
+
+ // [S]B = R + [k]A --> [k](-A) + [S]B = R
+ minusA := (&edwards25519.Point{}).Negate(A)
+ R := (&edwards25519.Point{}).VarTimeDoubleScalarBaseMult(k, minusA, S)
+
+ return bytes.Equal(sig[:32], R.Bytes())
+}
diff --git a/contrib/go/_std_1.21/src/crypto/ed25519/ya.make b/contrib/go/_std_1.21/src/crypto/ed25519/ya.make
new file mode 100644
index 0000000000..d69fb49a29
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/ed25519/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ ed25519.go
+)
+
+GO_TEST_SRCS(ed25519_test.go)
+
+GO_XTEST_SRCS(ed25519vectors_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/crypto/elliptic/elliptic.go b/contrib/go/_std_1.21/src/crypto/elliptic/elliptic.go
new file mode 100644
index 0000000000..96555ada39
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/elliptic/elliptic.go
@@ -0,0 +1,280 @@
+// Copyright 2010 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 elliptic implements the standard NIST P-224, P-256, P-384, and P-521
+// elliptic curves over prime fields.
+//
+// Direct use of this package is deprecated, beyond the [P224], [P256], [P384],
+// and [P521] values necessary to use [crypto/ecdsa]. Most other uses
+// should migrate to the more efficient and safer [crypto/ecdh], or to
+// third-party modules for lower-level functionality.
+package elliptic
+
+import (
+ "io"
+ "math/big"
+ "sync"
+)
+
+// A Curve represents a short-form Weierstrass curve with a=-3.
+//
+// The behavior of Add, Double, and ScalarMult when the input is not a point on
+// the curve is undefined.
+//
+// Note that the conventional point at infinity (0, 0) is not considered on the
+// curve, although it can be returned by Add, Double, ScalarMult, or
+// ScalarBaseMult (but not the Unmarshal or UnmarshalCompressed functions).
+//
+// Using Curve implementations besides those returned by P224(), P256(), P384(),
+// and P521() is deprecated.
+type Curve interface {
+ // Params returns the parameters for the curve.
+ Params() *CurveParams
+
+ // IsOnCurve reports whether the given (x,y) lies on the curve.
+ //
+ // Deprecated: this is a low-level unsafe API. For ECDH, use the crypto/ecdh
+ // package. The NewPublicKey methods of NIST curves in crypto/ecdh accept
+ // the same encoding as the Unmarshal function, and perform on-curve checks.
+ IsOnCurve(x, y *big.Int) bool
+
+ // Add returns the sum of (x1,y1) and (x2,y2).
+ //
+ // Deprecated: this is a low-level unsafe API.
+ Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int)
+
+ // Double returns 2*(x,y).
+ //
+ // Deprecated: this is a low-level unsafe API.
+ Double(x1, y1 *big.Int) (x, y *big.Int)
+
+ // ScalarMult returns k*(x,y) where k is an integer in big-endian form.
+ //
+ // Deprecated: this is a low-level unsafe API. For ECDH, use the crypto/ecdh
+ // package. Most uses of ScalarMult can be replaced by a call to the ECDH
+ // methods of NIST curves in crypto/ecdh.
+ ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int)
+
+ // ScalarBaseMult returns k*G, where G is the base point of the group
+ // and k is an integer in big-endian form.
+ //
+ // Deprecated: this is a low-level unsafe API. For ECDH, use the crypto/ecdh
+ // package. Most uses of ScalarBaseMult can be replaced by a call to the
+ // PrivateKey.PublicKey method in crypto/ecdh.
+ ScalarBaseMult(k []byte) (x, y *big.Int)
+}
+
+var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
+
+// GenerateKey returns a public/private key pair. The private key is
+// generated using the given reader, which must return random data.
+//
+// Deprecated: for ECDH, use the GenerateKey methods of the crypto/ecdh package;
+// for ECDSA, use the GenerateKey function of the crypto/ecdsa package.
+func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error) {
+ N := curve.Params().N
+ bitSize := N.BitLen()
+ byteLen := (bitSize + 7) / 8
+ priv = make([]byte, byteLen)
+
+ for x == nil {
+ _, err = io.ReadFull(rand, priv)
+ if err != nil {
+ return
+ }
+ // We have to mask off any excess bits in the case that the size of the
+ // underlying field is not a whole number of bytes.
+ priv[0] &= mask[bitSize%8]
+ // This is because, in tests, rand will return all zeros and we don't
+ // want to get the point at infinity and loop forever.
+ priv[1] ^= 0x42
+
+ // If the scalar is out of range, sample another random number.
+ if new(big.Int).SetBytes(priv).Cmp(N) >= 0 {
+ continue
+ }
+
+ x, y = curve.ScalarBaseMult(priv)
+ }
+ return
+}
+
+// Marshal converts a point on the curve into the uncompressed form specified in
+// SEC 1, Version 2.0, Section 2.3.3. If the point is not on the curve (or is
+// the conventional point at infinity), the behavior is undefined.
+//
+// Deprecated: for ECDH, use the crypto/ecdh package. This function returns an
+// encoding equivalent to that of PublicKey.Bytes in crypto/ecdh.
+func Marshal(curve Curve, x, y *big.Int) []byte {
+ panicIfNotOnCurve(curve, x, y)
+
+ byteLen := (curve.Params().BitSize + 7) / 8
+
+ ret := make([]byte, 1+2*byteLen)
+ ret[0] = 4 // uncompressed point
+
+ x.FillBytes(ret[1 : 1+byteLen])
+ y.FillBytes(ret[1+byteLen : 1+2*byteLen])
+
+ return ret
+}
+
+// MarshalCompressed converts a point on the curve into the compressed form
+// specified in SEC 1, Version 2.0, Section 2.3.3. If the point is not on the
+// curve (or is the conventional point at infinity), the behavior is undefined.
+func MarshalCompressed(curve Curve, x, y *big.Int) []byte {
+ panicIfNotOnCurve(curve, x, y)
+ byteLen := (curve.Params().BitSize + 7) / 8
+ compressed := make([]byte, 1+byteLen)
+ compressed[0] = byte(y.Bit(0)) | 2
+ x.FillBytes(compressed[1:])
+ return compressed
+}
+
+// unmarshaler is implemented by curves with their own constant-time Unmarshal.
+//
+// There isn't an equivalent interface for Marshal/MarshalCompressed because
+// that doesn't involve any mathematical operations, only FillBytes and Bit.
+type unmarshaler interface {
+ Unmarshal([]byte) (x, y *big.Int)
+ UnmarshalCompressed([]byte) (x, y *big.Int)
+}
+
+// Assert that the known curves implement unmarshaler.
+var _ = []unmarshaler{p224, p256, p384, p521}
+
+// Unmarshal converts a point, serialized by Marshal, into an x, y pair. It is
+// an error if the point is not in uncompressed form, is not on the curve, or is
+// the point at infinity. On error, x = nil.
+//
+// Deprecated: for ECDH, use the crypto/ecdh package. This function accepts an
+// encoding equivalent to that of the NewPublicKey methods in crypto/ecdh.
+func Unmarshal(curve Curve, data []byte) (x, y *big.Int) {
+ if c, ok := curve.(unmarshaler); ok {
+ return c.Unmarshal(data)
+ }
+
+ byteLen := (curve.Params().BitSize + 7) / 8
+ if len(data) != 1+2*byteLen {
+ return nil, nil
+ }
+ if data[0] != 4 { // uncompressed form
+ return nil, nil
+ }
+ p := curve.Params().P
+ x = new(big.Int).SetBytes(data[1 : 1+byteLen])
+ y = new(big.Int).SetBytes(data[1+byteLen:])
+ if x.Cmp(p) >= 0 || y.Cmp(p) >= 0 {
+ return nil, nil
+ }
+ if !curve.IsOnCurve(x, y) {
+ return nil, nil
+ }
+ return
+}
+
+// UnmarshalCompressed converts a point, serialized by MarshalCompressed, into
+// an x, y pair. It is an error if the point is not in compressed form, is not
+// on the curve, or is the point at infinity. On error, x = nil.
+func UnmarshalCompressed(curve Curve, data []byte) (x, y *big.Int) {
+ if c, ok := curve.(unmarshaler); ok {
+ return c.UnmarshalCompressed(data)
+ }
+
+ byteLen := (curve.Params().BitSize + 7) / 8
+ if len(data) != 1+byteLen {
+ return nil, nil
+ }
+ if data[0] != 2 && data[0] != 3 { // compressed form
+ return nil, nil
+ }
+ p := curve.Params().P
+ x = new(big.Int).SetBytes(data[1:])
+ if x.Cmp(p) >= 0 {
+ return nil, nil
+ }
+ // y² = x³ - 3x + b
+ y = curve.Params().polynomial(x)
+ y = y.ModSqrt(y, p)
+ if y == nil {
+ return nil, nil
+ }
+ if byte(y.Bit(0)) != data[0]&1 {
+ y.Neg(y).Mod(y, p)
+ }
+ if !curve.IsOnCurve(x, y) {
+ return nil, nil
+ }
+ return
+}
+
+func panicIfNotOnCurve(curve Curve, x, y *big.Int) {
+ // (0, 0) is the point at infinity by convention. It's ok to operate on it,
+ // although IsOnCurve is documented to return false for it. See Issue 37294.
+ if x.Sign() == 0 && y.Sign() == 0 {
+ return
+ }
+
+ if !curve.IsOnCurve(x, y) {
+ panic("crypto/elliptic: attempted operation on invalid point")
+ }
+}
+
+var initonce sync.Once
+
+func initAll() {
+ initP224()
+ initP256()
+ initP384()
+ initP521()
+}
+
+// P224 returns a Curve which implements NIST P-224 (FIPS 186-3, section D.2.2),
+// also known as secp224r1. The CurveParams.Name of this Curve is "P-224".
+//
+// Multiple invocations of this function will return the same value, so it can
+// be used for equality checks and switch statements.
+//
+// The cryptographic operations are implemented using constant-time algorithms.
+func P224() Curve {
+ initonce.Do(initAll)
+ return p224
+}
+
+// P256 returns a Curve which implements NIST P-256 (FIPS 186-3, section D.2.3),
+// also known as secp256r1 or prime256v1. The CurveParams.Name of this Curve is
+// "P-256".
+//
+// Multiple invocations of this function will return the same value, so it can
+// be used for equality checks and switch statements.
+//
+// The cryptographic operations are implemented using constant-time algorithms.
+func P256() Curve {
+ initonce.Do(initAll)
+ return p256
+}
+
+// P384 returns a Curve which implements NIST P-384 (FIPS 186-3, section D.2.4),
+// also known as secp384r1. The CurveParams.Name of this Curve is "P-384".
+//
+// Multiple invocations of this function will return the same value, so it can
+// be used for equality checks and switch statements.
+//
+// The cryptographic operations are implemented using constant-time algorithms.
+func P384() Curve {
+ initonce.Do(initAll)
+ return p384
+}
+
+// P521 returns a Curve which implements NIST P-521 (FIPS 186-3, section D.2.5),
+// also known as secp521r1. The CurveParams.Name of this Curve is "P-521".
+//
+// Multiple invocations of this function will return the same value, so it can
+// be used for equality checks and switch statements.
+//
+// The cryptographic operations are implemented using constant-time algorithms.
+func P521() Curve {
+ initonce.Do(initAll)
+ return p521
+}
diff --git a/contrib/go/_std_1.20/src/crypto/elliptic/nistec.go b/contrib/go/_std_1.21/src/crypto/elliptic/nistec.go
index d906c57074..d906c57074 100644
--- a/contrib/go/_std_1.20/src/crypto/elliptic/nistec.go
+++ b/contrib/go/_std_1.21/src/crypto/elliptic/nistec.go
diff --git a/contrib/go/_std_1.20/src/crypto/elliptic/nistec_p256.go b/contrib/go/_std_1.21/src/crypto/elliptic/nistec_p256.go
index 304f8f2659..304f8f2659 100644
--- a/contrib/go/_std_1.20/src/crypto/elliptic/nistec_p256.go
+++ b/contrib/go/_std_1.21/src/crypto/elliptic/nistec_p256.go
diff --git a/contrib/go/_std_1.21/src/crypto/elliptic/params.go b/contrib/go/_std_1.21/src/crypto/elliptic/params.go
new file mode 100644
index 0000000000..1ae57fae9e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/elliptic/params.go
@@ -0,0 +1,334 @@
+// 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 elliptic
+
+import "math/big"
+
+// CurveParams contains the parameters of an elliptic curve and also provides
+// a generic, non-constant time implementation of Curve.
+//
+// The generic Curve implementation is deprecated, and using custom curves
+// (those not returned by P224(), P256(), P384(), and P521()) is not guaranteed
+// to provide any security property.
+type CurveParams struct {
+ P *big.Int // the order of the underlying field
+ N *big.Int // the order of the base point
+ B *big.Int // the constant of the curve equation
+ Gx, Gy *big.Int // (x,y) of the base point
+ BitSize int // the size of the underlying field
+ Name string // the canonical name of the curve
+}
+
+func (curve *CurveParams) Params() *CurveParams {
+ return curve
+}
+
+// CurveParams operates, internally, on Jacobian coordinates. For a given
+// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
+// where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole
+// calculation can be performed within the transform (as in ScalarMult and
+// ScalarBaseMult). But even for Add and Double, it's faster to apply and
+// reverse the transform than to operate in affine coordinates.
+
+// polynomial returns x³ - 3x + b.
+func (curve *CurveParams) polynomial(x *big.Int) *big.Int {
+ x3 := new(big.Int).Mul(x, x)
+ x3.Mul(x3, x)
+
+ threeX := new(big.Int).Lsh(x, 1)
+ threeX.Add(threeX, x)
+
+ x3.Sub(x3, threeX)
+ x3.Add(x3, curve.B)
+ x3.Mod(x3, curve.P)
+
+ return x3
+}
+
+// IsOnCurve implements Curve.IsOnCurve.
+//
+// Deprecated: the CurveParams methods are deprecated and are not guaranteed to
+// provide any security property. For ECDH, use the crypto/ecdh package.
+// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
+// from P224(), P256(), P384(), or P521().
+func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool {
+ // If there is a dedicated constant-time implementation for this curve operation,
+ // use that instead of the generic one.
+ if specific, ok := matchesSpecificCurve(curve); ok {
+ return specific.IsOnCurve(x, y)
+ }
+
+ if x.Sign() < 0 || x.Cmp(curve.P) >= 0 ||
+ y.Sign() < 0 || y.Cmp(curve.P) >= 0 {
+ return false
+ }
+
+ // y² = x³ - 3x + b
+ y2 := new(big.Int).Mul(y, y)
+ y2.Mod(y2, curve.P)
+
+ return curve.polynomial(x).Cmp(y2) == 0
+}
+
+// zForAffine returns a Jacobian Z value for the affine point (x, y). If x and
+// y are zero, it assumes that they represent the point at infinity because (0,
+// 0) is not on the any of the curves handled here.
+func zForAffine(x, y *big.Int) *big.Int {
+ z := new(big.Int)
+ if x.Sign() != 0 || y.Sign() != 0 {
+ z.SetInt64(1)
+ }
+ return z
+}
+
+// affineFromJacobian reverses the Jacobian transform. See the comment at the
+// top of the file. If the point is ∞ it returns 0, 0.
+func (curve *CurveParams) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
+ if z.Sign() == 0 {
+ return new(big.Int), new(big.Int)
+ }
+
+ zinv := new(big.Int).ModInverse(z, curve.P)
+ zinvsq := new(big.Int).Mul(zinv, zinv)
+
+ xOut = new(big.Int).Mul(x, zinvsq)
+ xOut.Mod(xOut, curve.P)
+ zinvsq.Mul(zinvsq, zinv)
+ yOut = new(big.Int).Mul(y, zinvsq)
+ yOut.Mod(yOut, curve.P)
+ return
+}
+
+// Add implements Curve.Add.
+//
+// Deprecated: the CurveParams methods are deprecated and are not guaranteed to
+// provide any security property. For ECDH, use the crypto/ecdh package.
+// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
+// from P224(), P256(), P384(), or P521().
+func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
+ // If there is a dedicated constant-time implementation for this curve operation,
+ // use that instead of the generic one.
+ if specific, ok := matchesSpecificCurve(curve); ok {
+ return specific.Add(x1, y1, x2, y2)
+ }
+ panicIfNotOnCurve(curve, x1, y1)
+ panicIfNotOnCurve(curve, x2, y2)
+
+ z1 := zForAffine(x1, y1)
+ z2 := zForAffine(x2, y2)
+ return curve.affineFromJacobian(curve.addJacobian(x1, y1, z1, x2, y2, z2))
+}
+
+// addJacobian takes two points in Jacobian coordinates, (x1, y1, z1) and
+// (x2, y2, z2) and returns their sum, also in Jacobian form.
+func (curve *CurveParams) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) {
+ // See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl
+ x3, y3, z3 := new(big.Int), new(big.Int), new(big.Int)
+ if z1.Sign() == 0 {
+ x3.Set(x2)
+ y3.Set(y2)
+ z3.Set(z2)
+ return x3, y3, z3
+ }
+ if z2.Sign() == 0 {
+ x3.Set(x1)
+ y3.Set(y1)
+ z3.Set(z1)
+ return x3, y3, z3
+ }
+
+ z1z1 := new(big.Int).Mul(z1, z1)
+ z1z1.Mod(z1z1, curve.P)
+ z2z2 := new(big.Int).Mul(z2, z2)
+ z2z2.Mod(z2z2, curve.P)
+
+ u1 := new(big.Int).Mul(x1, z2z2)
+ u1.Mod(u1, curve.P)
+ u2 := new(big.Int).Mul(x2, z1z1)
+ u2.Mod(u2, curve.P)
+ h := new(big.Int).Sub(u2, u1)
+ xEqual := h.Sign() == 0
+ if h.Sign() == -1 {
+ h.Add(h, curve.P)
+ }
+ i := new(big.Int).Lsh(h, 1)
+ i.Mul(i, i)
+ j := new(big.Int).Mul(h, i)
+
+ s1 := new(big.Int).Mul(y1, z2)
+ s1.Mul(s1, z2z2)
+ s1.Mod(s1, curve.P)
+ s2 := new(big.Int).Mul(y2, z1)
+ s2.Mul(s2, z1z1)
+ s2.Mod(s2, curve.P)
+ r := new(big.Int).Sub(s2, s1)
+ if r.Sign() == -1 {
+ r.Add(r, curve.P)
+ }
+ yEqual := r.Sign() == 0
+ if xEqual && yEqual {
+ return curve.doubleJacobian(x1, y1, z1)
+ }
+ r.Lsh(r, 1)
+ v := new(big.Int).Mul(u1, i)
+
+ x3.Set(r)
+ x3.Mul(x3, x3)
+ x3.Sub(x3, j)
+ x3.Sub(x3, v)
+ x3.Sub(x3, v)
+ x3.Mod(x3, curve.P)
+
+ y3.Set(r)
+ v.Sub(v, x3)
+ y3.Mul(y3, v)
+ s1.Mul(s1, j)
+ s1.Lsh(s1, 1)
+ y3.Sub(y3, s1)
+ y3.Mod(y3, curve.P)
+
+ z3.Add(z1, z2)
+ z3.Mul(z3, z3)
+ z3.Sub(z3, z1z1)
+ z3.Sub(z3, z2z2)
+ z3.Mul(z3, h)
+ z3.Mod(z3, curve.P)
+
+ return x3, y3, z3
+}
+
+// Double implements Curve.Double.
+//
+// Deprecated: the CurveParams methods are deprecated and are not guaranteed to
+// provide any security property. For ECDH, use the crypto/ecdh package.
+// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
+// from P224(), P256(), P384(), or P521().
+func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
+ // If there is a dedicated constant-time implementation for this curve operation,
+ // use that instead of the generic one.
+ if specific, ok := matchesSpecificCurve(curve); ok {
+ return specific.Double(x1, y1)
+ }
+ panicIfNotOnCurve(curve, x1, y1)
+
+ z1 := zForAffine(x1, y1)
+ return curve.affineFromJacobian(curve.doubleJacobian(x1, y1, z1))
+}
+
+// doubleJacobian takes a point in Jacobian coordinates, (x, y, z), and
+// returns its double, also in Jacobian form.
+func (curve *CurveParams) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) {
+ // See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+ delta := new(big.Int).Mul(z, z)
+ delta.Mod(delta, curve.P)
+ gamma := new(big.Int).Mul(y, y)
+ gamma.Mod(gamma, curve.P)
+ alpha := new(big.Int).Sub(x, delta)
+ if alpha.Sign() == -1 {
+ alpha.Add(alpha, curve.P)
+ }
+ alpha2 := new(big.Int).Add(x, delta)
+ alpha.Mul(alpha, alpha2)
+ alpha2.Set(alpha)
+ alpha.Lsh(alpha, 1)
+ alpha.Add(alpha, alpha2)
+
+ beta := alpha2.Mul(x, gamma)
+
+ x3 := new(big.Int).Mul(alpha, alpha)
+ beta8 := new(big.Int).Lsh(beta, 3)
+ beta8.Mod(beta8, curve.P)
+ x3.Sub(x3, beta8)
+ if x3.Sign() == -1 {
+ x3.Add(x3, curve.P)
+ }
+ x3.Mod(x3, curve.P)
+
+ z3 := new(big.Int).Add(y, z)
+ z3.Mul(z3, z3)
+ z3.Sub(z3, gamma)
+ if z3.Sign() == -1 {
+ z3.Add(z3, curve.P)
+ }
+ z3.Sub(z3, delta)
+ if z3.Sign() == -1 {
+ z3.Add(z3, curve.P)
+ }
+ z3.Mod(z3, curve.P)
+
+ beta.Lsh(beta, 2)
+ beta.Sub(beta, x3)
+ if beta.Sign() == -1 {
+ beta.Add(beta, curve.P)
+ }
+ y3 := alpha.Mul(alpha, beta)
+
+ gamma.Mul(gamma, gamma)
+ gamma.Lsh(gamma, 3)
+ gamma.Mod(gamma, curve.P)
+
+ y3.Sub(y3, gamma)
+ if y3.Sign() == -1 {
+ y3.Add(y3, curve.P)
+ }
+ y3.Mod(y3, curve.P)
+
+ return x3, y3, z3
+}
+
+// ScalarMult implements Curve.ScalarMult.
+//
+// Deprecated: the CurveParams methods are deprecated and are not guaranteed to
+// provide any security property. For ECDH, use the crypto/ecdh package.
+// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
+// from P224(), P256(), P384(), or P521().
+func (curve *CurveParams) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
+ // If there is a dedicated constant-time implementation for this curve operation,
+ // use that instead of the generic one.
+ if specific, ok := matchesSpecificCurve(curve); ok {
+ return specific.ScalarMult(Bx, By, k)
+ }
+ panicIfNotOnCurve(curve, Bx, By)
+
+ Bz := new(big.Int).SetInt64(1)
+ x, y, z := new(big.Int), new(big.Int), new(big.Int)
+
+ for _, byte := range k {
+ for bitNum := 0; bitNum < 8; bitNum++ {
+ x, y, z = curve.doubleJacobian(x, y, z)
+ if byte&0x80 == 0x80 {
+ x, y, z = curve.addJacobian(Bx, By, Bz, x, y, z)
+ }
+ byte <<= 1
+ }
+ }
+
+ return curve.affineFromJacobian(x, y, z)
+}
+
+// ScalarBaseMult implements Curve.ScalarBaseMult.
+//
+// Deprecated: the CurveParams methods are deprecated and are not guaranteed to
+// provide any security property. For ECDH, use the crypto/ecdh package.
+// For ECDSA, use the crypto/ecdsa package with a Curve value returned directly
+// from P224(), P256(), P384(), or P521().
+func (curve *CurveParams) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
+ // If there is a dedicated constant-time implementation for this curve operation,
+ // use that instead of the generic one.
+ if specific, ok := matchesSpecificCurve(curve); ok {
+ return specific.ScalarBaseMult(k)
+ }
+
+ return curve.ScalarMult(curve.Gx, curve.Gy, k)
+}
+
+func matchesSpecificCurve(params *CurveParams) (Curve, bool) {
+ for _, c := range []Curve{p224, p256, p384, p521} {
+ if params == c.Params() {
+ return c, true
+ }
+ }
+ return nil, false
+}
diff --git a/contrib/go/_std_1.21/src/crypto/elliptic/ya.make b/contrib/go/_std_1.21/src/crypto/elliptic/ya.make
new file mode 100644
index 0000000000..8c614afd42
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/elliptic/ya.make
@@ -0,0 +1,19 @@
+GO_LIBRARY()
+
+SRCS(
+ elliptic.go
+ nistec.go
+ nistec_p256.go
+ params.go
+)
+
+GO_TEST_SRCS(
+ elliptic_test.go
+ p224_test.go
+ p256_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/crypto/hmac/hmac.go b/contrib/go/_std_1.21/src/crypto/hmac/hmac.go
new file mode 100644
index 0000000000..35b9d5a17a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/hmac/hmac.go
@@ -0,0 +1,180 @@
+// Copyright 2009 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 hmac implements the Keyed-Hash Message Authentication Code (HMAC) as
+defined in U.S. Federal Information Processing Standards Publication 198.
+An HMAC is a cryptographic hash that uses a key to sign a message.
+The receiver verifies the hash by recomputing it using the same key.
+
+Receivers should be careful to use Equal to compare MACs in order to avoid
+timing side-channels:
+
+ // ValidMAC reports whether messageMAC is a valid HMAC tag for message.
+ func ValidMAC(message, messageMAC, key []byte) bool {
+ mac := hmac.New(sha256.New, key)
+ mac.Write(message)
+ expectedMAC := mac.Sum(nil)
+ return hmac.Equal(messageMAC, expectedMAC)
+ }
+*/
+package hmac
+
+import (
+ "crypto/internal/boring"
+ "crypto/subtle"
+ "hash"
+)
+
+// FIPS 198-1:
+// https://csrc.nist.gov/publications/fips/fips198-1/FIPS-198-1_final.pdf
+
+// key is zero padded to the block size of the hash function
+// ipad = 0x36 byte repeated for key length
+// opad = 0x5c byte repeated for key length
+// hmac = H([key ^ opad] H([key ^ ipad] text))
+
+// marshalable is the combination of encoding.BinaryMarshaler and
+// encoding.BinaryUnmarshaler. Their method definitions are repeated here to
+// avoid a dependency on the encoding package.
+type marshalable interface {
+ MarshalBinary() ([]byte, error)
+ UnmarshalBinary([]byte) error
+}
+
+type hmac struct {
+ opad, ipad []byte
+ outer, inner hash.Hash
+
+ // If marshaled is true, then opad and ipad do not contain a padded
+ // copy of the key, but rather the marshaled state of outer/inner after
+ // opad/ipad has been fed into it.
+ marshaled bool
+}
+
+func (h *hmac) Sum(in []byte) []byte {
+ origLen := len(in)
+ in = h.inner.Sum(in)
+
+ if h.marshaled {
+ if err := h.outer.(marshalable).UnmarshalBinary(h.opad); err != nil {
+ panic(err)
+ }
+ } else {
+ h.outer.Reset()
+ h.outer.Write(h.opad)
+ }
+ h.outer.Write(in[origLen:])
+ return h.outer.Sum(in[:origLen])
+}
+
+func (h *hmac) Write(p []byte) (n int, err error) {
+ return h.inner.Write(p)
+}
+
+func (h *hmac) Size() int { return h.outer.Size() }
+func (h *hmac) BlockSize() int { return h.inner.BlockSize() }
+
+func (h *hmac) Reset() {
+ if h.marshaled {
+ if err := h.inner.(marshalable).UnmarshalBinary(h.ipad); err != nil {
+ panic(err)
+ }
+ return
+ }
+
+ h.inner.Reset()
+ h.inner.Write(h.ipad)
+
+ // If the underlying hash is marshalable, we can save some time by
+ // saving a copy of the hash state now, and restoring it on future
+ // calls to Reset and Sum instead of writing ipad/opad every time.
+ //
+ // If either hash is unmarshalable for whatever reason,
+ // it's safe to bail out here.
+ marshalableInner, innerOK := h.inner.(marshalable)
+ if !innerOK {
+ return
+ }
+ marshalableOuter, outerOK := h.outer.(marshalable)
+ if !outerOK {
+ return
+ }
+
+ imarshal, err := marshalableInner.MarshalBinary()
+ if err != nil {
+ return
+ }
+
+ h.outer.Reset()
+ h.outer.Write(h.opad)
+ omarshal, err := marshalableOuter.MarshalBinary()
+ if err != nil {
+ return
+ }
+
+ // Marshaling succeeded; save the marshaled state for later
+ h.ipad = imarshal
+ h.opad = omarshal
+ h.marshaled = true
+}
+
+// New returns a new HMAC hash using the given hash.Hash type and key.
+// New functions like sha256.New from crypto/sha256 can be used as h.
+// h must return a new Hash every time it is called.
+// Note that unlike other hash implementations in the standard library,
+// the returned Hash does not implement encoding.BinaryMarshaler
+// or encoding.BinaryUnmarshaler.
+func New(h func() hash.Hash, key []byte) hash.Hash {
+ if boring.Enabled {
+ hm := boring.NewHMAC(h, key)
+ if hm != nil {
+ return hm
+ }
+ // BoringCrypto did not recognize h, so fall through to standard Go code.
+ }
+ hm := new(hmac)
+ hm.outer = h()
+ hm.inner = h()
+ unique := true
+ func() {
+ defer func() {
+ // The comparison might panic if the underlying types are not comparable.
+ _ = recover()
+ }()
+ if hm.outer == hm.inner {
+ unique = false
+ }
+ }()
+ if !unique {
+ panic("crypto/hmac: hash generation function does not produce unique values")
+ }
+ blocksize := hm.inner.BlockSize()
+ hm.ipad = make([]byte, blocksize)
+ hm.opad = make([]byte, blocksize)
+ if len(key) > blocksize {
+ // If key is too big, hash it.
+ hm.outer.Write(key)
+ key = hm.outer.Sum(nil)
+ }
+ copy(hm.ipad, key)
+ copy(hm.opad, key)
+ for i := range hm.ipad {
+ hm.ipad[i] ^= 0x36
+ }
+ for i := range hm.opad {
+ hm.opad[i] ^= 0x5c
+ }
+ hm.inner.Write(hm.ipad)
+
+ return hm
+}
+
+// Equal compares two MACs for equality without leaking timing information.
+func Equal(mac1, mac2 []byte) bool {
+ // We don't have to be constant time if the lengths of the MACs are
+ // different as that suggests that a completely different hash function
+ // was used.
+ return subtle.ConstantTimeCompare(mac1, mac2) == 1
+}
diff --git a/contrib/go/_std_1.21/src/crypto/hmac/ya.make b/contrib/go/_std_1.21/src/crypto/hmac/ya.make
new file mode 100644
index 0000000000..d8c301ed1b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/hmac/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ hmac.go
+)
+
+GO_TEST_SRCS(hmac_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/crypto/internal/alias/alias.go b/contrib/go/_std_1.21/src/crypto/internal/alias/alias.go
new file mode 100644
index 0000000000..daf3ebcc4d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/alias/alias.go
@@ -0,0 +1,30 @@
+// Copyright 2018 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 alias implements memory aliasing tests.
+// This code also exists as golang.org/x/crypto/internal/alias.
+package alias
+
+import "unsafe"
+
+// AnyOverlap reports whether x and y share memory at any (not necessarily
+// corresponding) index. The memory beyond the slice length is ignored.
+func AnyOverlap(x, y []byte) bool {
+ return len(x) > 0 && len(y) > 0 &&
+ uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) &&
+ uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1]))
+}
+
+// InexactOverlap reports whether x and y share memory at any non-corresponding
+// index. The memory beyond the slice length is ignored. Note that x and y can
+// have different lengths and still not have any inexact overlap.
+//
+// InexactOverlap can be used to implement the requirements of the crypto/cipher
+// AEAD, Block, BlockMode and Stream interfaces.
+func InexactOverlap(x, y []byte) bool {
+ if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] {
+ return false
+ }
+ return AnyOverlap(x, y)
+}
diff --git a/contrib/go/_std_1.21/src/crypto/internal/alias/ya.make b/contrib/go/_std_1.21/src/crypto/internal/alias/ya.make
new file mode 100644
index 0000000000..2a4afa5e15
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/alias/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ alias.go
+)
+
+GO_TEST_SRCS(alias_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/crypto/internal/bigmod/nat.go b/contrib/go/_std_1.21/src/crypto/internal/bigmod/nat.go
new file mode 100644
index 0000000000..5605e9f1c3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/bigmod/nat.go
@@ -0,0 +1,770 @@
+// 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 bigmod
+
+import (
+ "encoding/binary"
+ "errors"
+ "math/big"
+ "math/bits"
+)
+
+const (
+ // _W is the size in bits of our limbs.
+ _W = bits.UintSize
+ // _S is the size in bytes of our limbs.
+ _S = _W / 8
+)
+
+// choice represents a constant-time boolean. The value of choice is always
+// either 1 or 0. We use an int instead of bool in order to make decisions in
+// constant time by turning it into a mask.
+type choice uint
+
+func not(c choice) choice { return 1 ^ c }
+
+const yes = choice(1)
+const no = choice(0)
+
+// ctMask is all 1s if on is yes, and all 0s otherwise.
+func ctMask(on choice) uint { return -uint(on) }
+
+// ctEq returns 1 if x == y, and 0 otherwise. The execution time of this
+// function does not depend on its inputs.
+func ctEq(x, y uint) choice {
+ // If x != y, then either x - y or y - x will generate a carry.
+ _, c1 := bits.Sub(x, y, 0)
+ _, c2 := bits.Sub(y, x, 0)
+ return not(choice(c1 | c2))
+}
+
+// ctGeq returns 1 if x >= y, and 0 otherwise. The execution time of this
+// function does not depend on its inputs.
+func ctGeq(x, y uint) choice {
+ // If x < y, then x - y generates a carry.
+ _, carry := bits.Sub(x, y, 0)
+ return not(choice(carry))
+}
+
+// Nat represents an arbitrary natural number
+//
+// Each Nat has an announced length, which is the number of limbs it has stored.
+// Operations on this number are allowed to leak this length, but will not leak
+// any information about the values contained in those limbs.
+type Nat struct {
+ // limbs is little-endian in base 2^W with W = bits.UintSize.
+ limbs []uint
+}
+
+// preallocTarget is the size in bits of the numbers used to implement the most
+// common and most performant RSA key size. It's also enough to cover some of
+// the operations of key sizes up to 4096.
+const preallocTarget = 2048
+const preallocLimbs = (preallocTarget + _W - 1) / _W
+
+// NewNat returns a new nat with a size of zero, just like new(Nat), but with
+// the preallocated capacity to hold a number of up to preallocTarget bits.
+// NewNat inlines, so the allocation can live on the stack.
+func NewNat() *Nat {
+ limbs := make([]uint, 0, preallocLimbs)
+ return &Nat{limbs}
+}
+
+// expand expands x to n limbs, leaving its value unchanged.
+func (x *Nat) expand(n int) *Nat {
+ if len(x.limbs) > n {
+ panic("bigmod: internal error: shrinking nat")
+ }
+ if cap(x.limbs) < n {
+ newLimbs := make([]uint, n)
+ copy(newLimbs, x.limbs)
+ x.limbs = newLimbs
+ return x
+ }
+ extraLimbs := x.limbs[len(x.limbs):n]
+ for i := range extraLimbs {
+ extraLimbs[i] = 0
+ }
+ x.limbs = x.limbs[:n]
+ return x
+}
+
+// reset returns a zero nat of n limbs, reusing x's storage if n <= cap(x.limbs).
+func (x *Nat) reset(n int) *Nat {
+ if cap(x.limbs) < n {
+ x.limbs = make([]uint, n)
+ return x
+ }
+ for i := range x.limbs {
+ x.limbs[i] = 0
+ }
+ x.limbs = x.limbs[:n]
+ return x
+}
+
+// set assigns x = y, optionally resizing x to the appropriate size.
+func (x *Nat) set(y *Nat) *Nat {
+ x.reset(len(y.limbs))
+ copy(x.limbs, y.limbs)
+ return x
+}
+
+// setBig assigns x = n, optionally resizing n to the appropriate size.
+//
+// The announced length of x is set based on the actual bit size of the input,
+// ignoring leading zeroes.
+func (x *Nat) setBig(n *big.Int) *Nat {
+ limbs := n.Bits()
+ x.reset(len(limbs))
+ for i := range limbs {
+ x.limbs[i] = uint(limbs[i])
+ }
+ return x
+}
+
+// Bytes returns x as a zero-extended big-endian byte slice. The size of the
+// slice will match the size of m.
+//
+// x must have the same size as m and it must be reduced modulo m.
+func (x *Nat) Bytes(m *Modulus) []byte {
+ i := m.Size()
+ bytes := make([]byte, i)
+ for _, limb := range x.limbs {
+ for j := 0; j < _S; j++ {
+ i--
+ if i < 0 {
+ if limb == 0 {
+ break
+ }
+ panic("bigmod: modulus is smaller than nat")
+ }
+ bytes[i] = byte(limb)
+ limb >>= 8
+ }
+ }
+ return bytes
+}
+
+// SetBytes assigns x = b, where b is a slice of big-endian bytes.
+// SetBytes returns an error if b >= m.
+//
+// The output will be resized to the size of m and overwritten.
+func (x *Nat) SetBytes(b []byte, m *Modulus) (*Nat, error) {
+ if err := x.setBytes(b, m); err != nil {
+ return nil, err
+ }
+ if x.cmpGeq(m.nat) == yes {
+ return nil, errors.New("input overflows the modulus")
+ }
+ return x, nil
+}
+
+// SetOverflowingBytes assigns x = b, where b is a slice of big-endian bytes.
+// SetOverflowingBytes returns an error if b has a longer bit length than m, but
+// reduces overflowing values up to 2^⌈log2(m)⌉ - 1.
+//
+// The output will be resized to the size of m and overwritten.
+func (x *Nat) SetOverflowingBytes(b []byte, m *Modulus) (*Nat, error) {
+ if err := x.setBytes(b, m); err != nil {
+ return nil, err
+ }
+ leading := _W - bitLen(x.limbs[len(x.limbs)-1])
+ if leading < m.leading {
+ return nil, errors.New("input overflows the modulus size")
+ }
+ x.maybeSubtractModulus(no, m)
+ return x, nil
+}
+
+// bigEndianUint returns the contents of buf interpreted as a
+// big-endian encoded uint value.
+func bigEndianUint(buf []byte) uint {
+ if _W == 64 {
+ return uint(binary.BigEndian.Uint64(buf))
+ }
+ return uint(binary.BigEndian.Uint32(buf))
+}
+
+func (x *Nat) setBytes(b []byte, m *Modulus) error {
+ x.resetFor(m)
+ i, k := len(b), 0
+ for k < len(x.limbs) && i >= _S {
+ x.limbs[k] = bigEndianUint(b[i-_S : i])
+ i -= _S
+ k++
+ }
+ for s := 0; s < _W && k < len(x.limbs) && i > 0; s += 8 {
+ x.limbs[k] |= uint(b[i-1]) << s
+ i--
+ }
+ if i > 0 {
+ return errors.New("input overflows the modulus size")
+ }
+ return nil
+}
+
+// Equal returns 1 if x == y, and 0 otherwise.
+//
+// Both operands must have the same announced length.
+func (x *Nat) Equal(y *Nat) choice {
+ // Eliminate bounds checks in the loop.
+ size := len(x.limbs)
+ xLimbs := x.limbs[:size]
+ yLimbs := y.limbs[:size]
+
+ equal := yes
+ for i := 0; i < size; i++ {
+ equal &= ctEq(xLimbs[i], yLimbs[i])
+ }
+ return equal
+}
+
+// IsZero returns 1 if x == 0, and 0 otherwise.
+func (x *Nat) IsZero() choice {
+ // Eliminate bounds checks in the loop.
+ size := len(x.limbs)
+ xLimbs := x.limbs[:size]
+
+ zero := yes
+ for i := 0; i < size; i++ {
+ zero &= ctEq(xLimbs[i], 0)
+ }
+ return zero
+}
+
+// cmpGeq returns 1 if x >= y, and 0 otherwise.
+//
+// Both operands must have the same announced length.
+func (x *Nat) cmpGeq(y *Nat) choice {
+ // Eliminate bounds checks in the loop.
+ size := len(x.limbs)
+ xLimbs := x.limbs[:size]
+ yLimbs := y.limbs[:size]
+
+ var c uint
+ for i := 0; i < size; i++ {
+ _, c = bits.Sub(xLimbs[i], yLimbs[i], c)
+ }
+ // If there was a carry, then subtracting y underflowed, so
+ // x is not greater than or equal to y.
+ return not(choice(c))
+}
+
+// assign sets x <- y if on == 1, and does nothing otherwise.
+//
+// Both operands must have the same announced length.
+func (x *Nat) assign(on choice, y *Nat) *Nat {
+ // Eliminate bounds checks in the loop.
+ size := len(x.limbs)
+ xLimbs := x.limbs[:size]
+ yLimbs := y.limbs[:size]
+
+ mask := ctMask(on)
+ for i := 0; i < size; i++ {
+ xLimbs[i] ^= mask & (xLimbs[i] ^ yLimbs[i])
+ }
+ return x
+}
+
+// add computes x += y and returns the carry.
+//
+// Both operands must have the same announced length.
+func (x *Nat) add(y *Nat) (c uint) {
+ // Eliminate bounds checks in the loop.
+ size := len(x.limbs)
+ xLimbs := x.limbs[:size]
+ yLimbs := y.limbs[:size]
+
+ for i := 0; i < size; i++ {
+ xLimbs[i], c = bits.Add(xLimbs[i], yLimbs[i], c)
+ }
+ return
+}
+
+// sub computes x -= y. It returns the borrow of the subtraction.
+//
+// Both operands must have the same announced length.
+func (x *Nat) sub(y *Nat) (c uint) {
+ // Eliminate bounds checks in the loop.
+ size := len(x.limbs)
+ xLimbs := x.limbs[:size]
+ yLimbs := y.limbs[:size]
+
+ for i := 0; i < size; i++ {
+ xLimbs[i], c = bits.Sub(xLimbs[i], yLimbs[i], c)
+ }
+ return
+}
+
+// Modulus is used for modular arithmetic, precomputing relevant constants.
+//
+// Moduli are assumed to be odd numbers. Moduli can also leak the exact
+// number of bits needed to store their value, and are stored without padding.
+//
+// Their actual value is still kept secret.
+type Modulus struct {
+ // The underlying natural number for this modulus.
+ //
+ // This will be stored without any padding, and shouldn't alias with any
+ // other natural number being used.
+ nat *Nat
+ leading int // number of leading zeros in the modulus
+ m0inv uint // -nat.limbs[0]⁻¹ mod _W
+ rr *Nat // R*R for montgomeryRepresentation
+}
+
+// rr returns R*R with R = 2^(_W * n) and n = len(m.nat.limbs).
+func rr(m *Modulus) *Nat {
+ rr := NewNat().ExpandFor(m)
+ // R*R is 2^(2 * _W * n). We can safely get 2^(_W * (n - 1)) by setting the
+ // most significant limb to 1. We then get to R*R by shifting left by _W
+ // n + 1 times.
+ n := len(rr.limbs)
+ rr.limbs[n-1] = 1
+ for i := n - 1; i < 2*n; i++ {
+ rr.shiftIn(0, m) // x = x * 2^_W mod m
+ }
+ return rr
+}
+
+// minusInverseModW computes -x⁻¹ mod _W with x odd.
+//
+// This operation is used to precompute a constant involved in Montgomery
+// multiplication.
+func minusInverseModW(x uint) uint {
+ // Every iteration of this loop doubles the least-significant bits of
+ // correct inverse in y. The first three bits are already correct (1⁻¹ = 1,
+ // 3⁻¹ = 3, 5⁻¹ = 5, and 7⁻¹ = 7 mod 8), so doubling five times is enough
+ // for 64 bits (and wastes only one iteration for 32 bits).
+ //
+ // See https://crypto.stackexchange.com/a/47496.
+ y := x
+ for i := 0; i < 5; i++ {
+ y = y * (2 - x*y)
+ }
+ return -y
+}
+
+// NewModulusFromBig creates a new Modulus from a [big.Int].
+//
+// The Int must be odd. The number of significant bits (and nothing else) is
+// leaked through timing side-channels.
+func NewModulusFromBig(n *big.Int) (*Modulus, error) {
+ if b := n.Bits(); len(b) == 0 {
+ return nil, errors.New("modulus must be >= 0")
+ } else if b[0]&1 != 1 {
+ return nil, errors.New("modulus must be odd")
+ }
+ m := &Modulus{}
+ m.nat = NewNat().setBig(n)
+ m.leading = _W - bitLen(m.nat.limbs[len(m.nat.limbs)-1])
+ m.m0inv = minusInverseModW(m.nat.limbs[0])
+ m.rr = rr(m)
+ return m, nil
+}
+
+// bitLen is a version of bits.Len that only leaks the bit length of n, but not
+// its value. bits.Len and bits.LeadingZeros use a lookup table for the
+// low-order bits on some architectures.
+func bitLen(n uint) int {
+ var len int
+ // We assume, here and elsewhere, that comparison to zero is constant time
+ // with respect to different non-zero values.
+ for n != 0 {
+ len++
+ n >>= 1
+ }
+ return len
+}
+
+// Size returns the size of m in bytes.
+func (m *Modulus) Size() int {
+ return (m.BitLen() + 7) / 8
+}
+
+// BitLen returns the size of m in bits.
+func (m *Modulus) BitLen() int {
+ return len(m.nat.limbs)*_W - int(m.leading)
+}
+
+// Nat returns m as a Nat. The return value must not be written to.
+func (m *Modulus) Nat() *Nat {
+ return m.nat
+}
+
+// shiftIn calculates x = x << _W + y mod m.
+//
+// This assumes that x is already reduced mod m.
+func (x *Nat) shiftIn(y uint, m *Modulus) *Nat {
+ d := NewNat().resetFor(m)
+
+ // Eliminate bounds checks in the loop.
+ size := len(m.nat.limbs)
+ xLimbs := x.limbs[:size]
+ dLimbs := d.limbs[:size]
+ mLimbs := m.nat.limbs[:size]
+
+ // Each iteration of this loop computes x = 2x + b mod m, where b is a bit
+ // from y. Effectively, it left-shifts x and adds y one bit at a time,
+ // reducing it every time.
+ //
+ // To do the reduction, each iteration computes both 2x + b and 2x + b - m.
+ // The next iteration (and finally the return line) will use either result
+ // based on whether 2x + b overflows m.
+ needSubtraction := no
+ for i := _W - 1; i >= 0; i-- {
+ carry := (y >> i) & 1
+ var borrow uint
+ mask := ctMask(needSubtraction)
+ for i := 0; i < size; i++ {
+ l := xLimbs[i] ^ (mask & (xLimbs[i] ^ dLimbs[i]))
+ xLimbs[i], carry = bits.Add(l, l, carry)
+ dLimbs[i], borrow = bits.Sub(xLimbs[i], mLimbs[i], borrow)
+ }
+ // Like in maybeSubtractModulus, we need the subtraction if either it
+ // didn't underflow (meaning 2x + b > m) or if computing 2x + b
+ // overflowed (meaning 2x + b > 2^_W*n > m).
+ needSubtraction = not(choice(borrow)) | choice(carry)
+ }
+ return x.assign(needSubtraction, d)
+}
+
+// Mod calculates out = x mod m.
+//
+// This works regardless how large the value of x is.
+//
+// The output will be resized to the size of m and overwritten.
+func (out *Nat) Mod(x *Nat, m *Modulus) *Nat {
+ out.resetFor(m)
+ // Working our way from the most significant to the least significant limb,
+ // we can insert each limb at the least significant position, shifting all
+ // previous limbs left by _W. This way each limb will get shifted by the
+ // correct number of bits. We can insert at least N - 1 limbs without
+ // overflowing m. After that, we need to reduce every time we shift.
+ i := len(x.limbs) - 1
+ // For the first N - 1 limbs we can skip the actual shifting and position
+ // them at the shifted position, which starts at min(N - 2, i).
+ start := len(m.nat.limbs) - 2
+ if i < start {
+ start = i
+ }
+ for j := start; j >= 0; j-- {
+ out.limbs[j] = x.limbs[i]
+ i--
+ }
+ // We shift in the remaining limbs, reducing modulo m each time.
+ for i >= 0 {
+ out.shiftIn(x.limbs[i], m)
+ i--
+ }
+ return out
+}
+
+// ExpandFor ensures x has the right size to work with operations modulo m.
+//
+// The announced size of x must be smaller than or equal to that of m.
+func (x *Nat) ExpandFor(m *Modulus) *Nat {
+ return x.expand(len(m.nat.limbs))
+}
+
+// resetFor ensures out has the right size to work with operations modulo m.
+//
+// out is zeroed and may start at any size.
+func (out *Nat) resetFor(m *Modulus) *Nat {
+ return out.reset(len(m.nat.limbs))
+}
+
+// maybeSubtractModulus computes x -= m if and only if x >= m or if "always" is yes.
+//
+// It can be used to reduce modulo m a value up to 2m - 1, which is a common
+// range for results computed by higher level operations.
+//
+// always is usually a carry that indicates that the operation that produced x
+// overflowed its size, meaning abstractly x > 2^_W*n > m even if x < m.
+//
+// x and m operands must have the same announced length.
+func (x *Nat) maybeSubtractModulus(always choice, m *Modulus) {
+ t := NewNat().set(x)
+ underflow := t.sub(m.nat)
+ // We keep the result if x - m didn't underflow (meaning x >= m)
+ // or if always was set.
+ keep := not(choice(underflow)) | choice(always)
+ x.assign(keep, t)
+}
+
+// Sub computes x = x - y mod m.
+//
+// The length of both operands must be the same as the modulus. Both operands
+// must already be reduced modulo m.
+func (x *Nat) Sub(y *Nat, m *Modulus) *Nat {
+ underflow := x.sub(y)
+ // If the subtraction underflowed, add m.
+ t := NewNat().set(x)
+ t.add(m.nat)
+ x.assign(choice(underflow), t)
+ return x
+}
+
+// Add computes x = x + y mod m.
+//
+// The length of both operands must be the same as the modulus. Both operands
+// must already be reduced modulo m.
+func (x *Nat) Add(y *Nat, m *Modulus) *Nat {
+ overflow := x.add(y)
+ x.maybeSubtractModulus(choice(overflow), m)
+ return x
+}
+
+// montgomeryRepresentation calculates x = x * R mod m, with R = 2^(_W * n) and
+// n = len(m.nat.limbs).
+//
+// Faster Montgomery multiplication replaces standard modular multiplication for
+// numbers in this representation.
+//
+// This assumes that x is already reduced mod m.
+func (x *Nat) montgomeryRepresentation(m *Modulus) *Nat {
+ // A Montgomery multiplication (which computes a * b / R) by R * R works out
+ // to a multiplication by R, which takes the value out of the Montgomery domain.
+ return x.montgomeryMul(x, m.rr, m)
+}
+
+// montgomeryReduction calculates x = x / R mod m, with R = 2^(_W * n) and
+// n = len(m.nat.limbs).
+//
+// This assumes that x is already reduced mod m.
+func (x *Nat) montgomeryReduction(m *Modulus) *Nat {
+ // By Montgomery multiplying with 1 not in Montgomery representation, we
+ // convert out back from Montgomery representation, because it works out to
+ // dividing by R.
+ one := NewNat().ExpandFor(m)
+ one.limbs[0] = 1
+ return x.montgomeryMul(x, one, m)
+}
+
+// montgomeryMul calculates x = a * b / R mod m, with R = 2^(_W * n) and
+// n = len(m.nat.limbs), also known as a Montgomery multiplication.
+//
+// All inputs should be the same length and already reduced modulo m.
+// x will be resized to the size of m and overwritten.
+func (x *Nat) montgomeryMul(a *Nat, b *Nat, m *Modulus) *Nat {
+ n := len(m.nat.limbs)
+ mLimbs := m.nat.limbs[:n]
+ aLimbs := a.limbs[:n]
+ bLimbs := b.limbs[:n]
+
+ switch n {
+ default:
+ // Attempt to use a stack-allocated backing array.
+ T := make([]uint, 0, preallocLimbs*2)
+ if cap(T) < n*2 {
+ T = make([]uint, 0, n*2)
+ }
+ T = T[:n*2]
+
+ // This loop implements Word-by-Word Montgomery Multiplication, as
+ // described in Algorithm 4 (Fig. 3) of "Efficient Software
+ // Implementations of Modular Exponentiation" by Shay Gueron
+ // [https://eprint.iacr.org/2011/239.pdf].
+ var c uint
+ for i := 0; i < n; i++ {
+ _ = T[n+i] // bounds check elimination hint
+
+ // Step 1 (T = a × b) is computed as a large pen-and-paper column
+ // multiplication of two numbers with n base-2^_W digits. If we just
+ // wanted to produce 2n-wide T, we would do
+ //
+ // for i := 0; i < n; i++ {
+ // d := bLimbs[i]
+ // T[n+i] = addMulVVW(T[i:n+i], aLimbs, d)
+ // }
+ //
+ // where d is a digit of the multiplier, T[i:n+i] is the shifted
+ // position of the product of that digit, and T[n+i] is the final carry.
+ // Note that T[i] isn't modified after processing the i-th digit.
+ //
+ // Instead of running two loops, one for Step 1 and one for Steps 2–6,
+ // the result of Step 1 is computed during the next loop. This is
+ // possible because each iteration only uses T[i] in Step 2 and then
+ // discards it in Step 6.
+ d := bLimbs[i]
+ c1 := addMulVVW(T[i:n+i], aLimbs, d)
+
+ // Step 6 is replaced by shifting the virtual window we operate
+ // over: T of the algorithm is T[i:] for us. That means that T1 in
+ // Step 2 (T mod 2^_W) is simply T[i]. k0 in Step 3 is our m0inv.
+ Y := T[i] * m.m0inv
+
+ // Step 4 and 5 add Y × m to T, which as mentioned above is stored
+ // at T[i:]. The two carries (from a × d and Y × m) are added up in
+ // the next word T[n+i], and the carry bit from that addition is
+ // brought forward to the next iteration.
+ c2 := addMulVVW(T[i:n+i], mLimbs, Y)
+ T[n+i], c = bits.Add(c1, c2, c)
+ }
+
+ // Finally for Step 7 we copy the final T window into x, and subtract m
+ // if necessary (which as explained in maybeSubtractModulus can be the
+ // case both if x >= m, or if x overflowed).
+ //
+ // The paper suggests in Section 4 that we can do an "Almost Montgomery
+ // Multiplication" by subtracting only in the overflow case, but the
+ // cost is very similar since the constant time subtraction tells us if
+ // x >= m as a side effect, and taking care of the broken invariant is
+ // highly undesirable (see https://go.dev/issue/13907).
+ copy(x.reset(n).limbs, T[n:])
+ x.maybeSubtractModulus(choice(c), m)
+
+ // The following specialized cases follow the exact same algorithm, but
+ // optimized for the sizes most used in RSA. addMulVVW is implemented in
+ // assembly with loop unrolling depending on the architecture and bounds
+ // checks are removed by the compiler thanks to the constant size.
+ case 1024 / _W:
+ const n = 1024 / _W // compiler hint
+ T := make([]uint, n*2)
+ var c uint
+ for i := 0; i < n; i++ {
+ d := bLimbs[i]
+ c1 := addMulVVW1024(&T[i], &aLimbs[0], d)
+ Y := T[i] * m.m0inv
+ c2 := addMulVVW1024(&T[i], &mLimbs[0], Y)
+ T[n+i], c = bits.Add(c1, c2, c)
+ }
+ copy(x.reset(n).limbs, T[n:])
+ x.maybeSubtractModulus(choice(c), m)
+
+ case 1536 / _W:
+ const n = 1536 / _W // compiler hint
+ T := make([]uint, n*2)
+ var c uint
+ for i := 0; i < n; i++ {
+ d := bLimbs[i]
+ c1 := addMulVVW1536(&T[i], &aLimbs[0], d)
+ Y := T[i] * m.m0inv
+ c2 := addMulVVW1536(&T[i], &mLimbs[0], Y)
+ T[n+i], c = bits.Add(c1, c2, c)
+ }
+ copy(x.reset(n).limbs, T[n:])
+ x.maybeSubtractModulus(choice(c), m)
+
+ case 2048 / _W:
+ const n = 2048 / _W // compiler hint
+ T := make([]uint, n*2)
+ var c uint
+ for i := 0; i < n; i++ {
+ d := bLimbs[i]
+ c1 := addMulVVW2048(&T[i], &aLimbs[0], d)
+ Y := T[i] * m.m0inv
+ c2 := addMulVVW2048(&T[i], &mLimbs[0], Y)
+ T[n+i], c = bits.Add(c1, c2, c)
+ }
+ copy(x.reset(n).limbs, T[n:])
+ x.maybeSubtractModulus(choice(c), m)
+ }
+
+ return x
+}
+
+// addMulVVW multiplies the multi-word value x by the single-word value y,
+// adding the result to the multi-word value z and returning the final carry.
+// It can be thought of as one row of a pen-and-paper column multiplication.
+func addMulVVW(z, x []uint, y uint) (carry uint) {
+ _ = x[len(z)-1] // bounds check elimination hint
+ for i := range z {
+ hi, lo := bits.Mul(x[i], y)
+ lo, c := bits.Add(lo, z[i], 0)
+ // We use bits.Add with zero to get an add-with-carry instruction that
+ // absorbs the carry from the previous bits.Add.
+ hi, _ = bits.Add(hi, 0, c)
+ lo, c = bits.Add(lo, carry, 0)
+ hi, _ = bits.Add(hi, 0, c)
+ carry = hi
+ z[i] = lo
+ }
+ return carry
+}
+
+// Mul calculates x = x * y mod m.
+//
+// The length of both operands must be the same as the modulus. Both operands
+// must already be reduced modulo m.
+func (x *Nat) Mul(y *Nat, m *Modulus) *Nat {
+ // A Montgomery multiplication by a value out of the Montgomery domain
+ // takes the result out of Montgomery representation.
+ xR := NewNat().set(x).montgomeryRepresentation(m) // xR = x * R mod m
+ return x.montgomeryMul(xR, y, m) // x = xR * y / R mod m
+}
+
+// Exp calculates out = x^e mod m.
+//
+// The exponent e is represented in big-endian order. The output will be resized
+// to the size of m and overwritten. x must already be reduced modulo m.
+func (out *Nat) Exp(x *Nat, e []byte, m *Modulus) *Nat {
+ // We use a 4 bit window. For our RSA workload, 4 bit windows are faster
+ // than 2 bit windows, but use an extra 12 nats worth of scratch space.
+ // Using bit sizes that don't divide 8 are more complex to implement, but
+ // are likely to be more efficient if necessary.
+
+ table := [(1 << 4) - 1]*Nat{ // table[i] = x ^ (i+1)
+ // newNat calls are unrolled so they are allocated on the stack.
+ NewNat(), NewNat(), NewNat(), NewNat(), NewNat(),
+ NewNat(), NewNat(), NewNat(), NewNat(), NewNat(),
+ NewNat(), NewNat(), NewNat(), NewNat(), NewNat(),
+ }
+ table[0].set(x).montgomeryRepresentation(m)
+ for i := 1; i < len(table); i++ {
+ table[i].montgomeryMul(table[i-1], table[0], m)
+ }
+
+ out.resetFor(m)
+ out.limbs[0] = 1
+ out.montgomeryRepresentation(m)
+ tmp := NewNat().ExpandFor(m)
+ for _, b := range e {
+ for _, j := range []int{4, 0} {
+ // Square four times. Optimization note: this can be implemented
+ // more efficiently than with generic Montgomery multiplication.
+ out.montgomeryMul(out, out, m)
+ out.montgomeryMul(out, out, m)
+ out.montgomeryMul(out, out, m)
+ out.montgomeryMul(out, out, m)
+
+ // Select x^k in constant time from the table.
+ k := uint((b >> j) & 0b1111)
+ for i := range table {
+ tmp.assign(ctEq(k, uint(i+1)), table[i])
+ }
+
+ // Multiply by x^k, discarding the result if k = 0.
+ tmp.montgomeryMul(out, tmp, m)
+ out.assign(not(ctEq(k, 0)), tmp)
+ }
+ }
+
+ return out.montgomeryReduction(m)
+}
+
+// ExpShort calculates out = x^e mod m.
+//
+// The output will be resized to the size of m and overwritten. x must already
+// be reduced modulo m. This leaks the exact bit size of the exponent.
+func (out *Nat) ExpShort(x *Nat, e uint, m *Modulus) *Nat {
+ xR := NewNat().set(x).montgomeryRepresentation(m)
+
+ out.resetFor(m)
+ out.limbs[0] = 1
+ out.montgomeryRepresentation(m)
+
+ // For short exponents, precomputing a table and using a window like in Exp
+ // doesn't pay off. Instead, we do a simple constant-time conditional
+ // square-and-multiply chain, skipping the initial run of zeroes.
+ tmp := NewNat().ExpandFor(m)
+ for i := bits.UintSize - bitLen(e); i < bits.UintSize; i++ {
+ out.montgomeryMul(out, out, m)
+ k := (e >> (bits.UintSize - i - 1)) & 1
+ tmp.montgomeryMul(out, xR, m)
+ out.assign(ctEq(k, 1), tmp)
+ }
+ return out.montgomeryReduction(m)
+}
diff --git a/contrib/go/_std_1.21/src/crypto/internal/bigmod/nat_amd64.s b/contrib/go/_std_1.21/src/crypto/internal/bigmod/nat_amd64.s
new file mode 100644
index 0000000000..ab94344e10
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/bigmod/nat_amd64.s
@@ -0,0 +1,1230 @@
+// Code generated by command: go run nat_amd64_asm.go -out ../nat_amd64.s -pkg bigmod. DO NOT EDIT.
+
+//go:build !purego
+
+// func addMulVVW1024(z *uint, x *uint, y uint) (c uint)
+// Requires: ADX, BMI2
+TEXT ·addMulVVW1024(SB), $0-32
+ CMPB ·supportADX+0(SB), $0x01
+ JEQ adx
+ MOVQ z+0(FP), CX
+ MOVQ x+8(FP), BX
+ MOVQ y+16(FP), SI
+ XORQ DI, DI
+
+ // Iteration 0
+ MOVQ (BX), AX
+ MULQ SI
+ ADDQ (CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, (CX)
+
+ // Iteration 1
+ MOVQ 8(BX), AX
+ MULQ SI
+ ADDQ 8(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 8(CX)
+
+ // Iteration 2
+ MOVQ 16(BX), AX
+ MULQ SI
+ ADDQ 16(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 16(CX)
+
+ // Iteration 3
+ MOVQ 24(BX), AX
+ MULQ SI
+ ADDQ 24(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 24(CX)
+
+ // Iteration 4
+ MOVQ 32(BX), AX
+ MULQ SI
+ ADDQ 32(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 32(CX)
+
+ // Iteration 5
+ MOVQ 40(BX), AX
+ MULQ SI
+ ADDQ 40(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 40(CX)
+
+ // Iteration 6
+ MOVQ 48(BX), AX
+ MULQ SI
+ ADDQ 48(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 48(CX)
+
+ // Iteration 7
+ MOVQ 56(BX), AX
+ MULQ SI
+ ADDQ 56(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 56(CX)
+
+ // Iteration 8
+ MOVQ 64(BX), AX
+ MULQ SI
+ ADDQ 64(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 64(CX)
+
+ // Iteration 9
+ MOVQ 72(BX), AX
+ MULQ SI
+ ADDQ 72(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 72(CX)
+
+ // Iteration 10
+ MOVQ 80(BX), AX
+ MULQ SI
+ ADDQ 80(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 80(CX)
+
+ // Iteration 11
+ MOVQ 88(BX), AX
+ MULQ SI
+ ADDQ 88(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 88(CX)
+
+ // Iteration 12
+ MOVQ 96(BX), AX
+ MULQ SI
+ ADDQ 96(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 96(CX)
+
+ // Iteration 13
+ MOVQ 104(BX), AX
+ MULQ SI
+ ADDQ 104(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 104(CX)
+
+ // Iteration 14
+ MOVQ 112(BX), AX
+ MULQ SI
+ ADDQ 112(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 112(CX)
+
+ // Iteration 15
+ MOVQ 120(BX), AX
+ MULQ SI
+ ADDQ 120(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 120(CX)
+ MOVQ DI, c+24(FP)
+ RET
+
+adx:
+ MOVQ z+0(FP), AX
+ MOVQ x+8(FP), CX
+ MOVQ y+16(FP), DX
+ XORQ BX, BX
+ XORQ SI, SI
+
+ // Iteration 0
+ MULXQ (CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ (AX), R8
+ MOVQ R8, (AX)
+
+ // Iteration 1
+ MULXQ 8(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 8(AX), R8
+ MOVQ R8, 8(AX)
+
+ // Iteration 2
+ MULXQ 16(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 16(AX), R8
+ MOVQ R8, 16(AX)
+
+ // Iteration 3
+ MULXQ 24(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 24(AX), R8
+ MOVQ R8, 24(AX)
+
+ // Iteration 4
+ MULXQ 32(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 32(AX), R8
+ MOVQ R8, 32(AX)
+
+ // Iteration 5
+ MULXQ 40(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 40(AX), R8
+ MOVQ R8, 40(AX)
+
+ // Iteration 6
+ MULXQ 48(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 48(AX), R8
+ MOVQ R8, 48(AX)
+
+ // Iteration 7
+ MULXQ 56(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 56(AX), R8
+ MOVQ R8, 56(AX)
+
+ // Iteration 8
+ MULXQ 64(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 64(AX), R8
+ MOVQ R8, 64(AX)
+
+ // Iteration 9
+ MULXQ 72(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 72(AX), R8
+ MOVQ R8, 72(AX)
+
+ // Iteration 10
+ MULXQ 80(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 80(AX), R8
+ MOVQ R8, 80(AX)
+
+ // Iteration 11
+ MULXQ 88(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 88(AX), R8
+ MOVQ R8, 88(AX)
+
+ // Iteration 12
+ MULXQ 96(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 96(AX), R8
+ MOVQ R8, 96(AX)
+
+ // Iteration 13
+ MULXQ 104(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 104(AX), R8
+ MOVQ R8, 104(AX)
+
+ // Iteration 14
+ MULXQ 112(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 112(AX), R8
+ MOVQ R8, 112(AX)
+
+ // Iteration 15
+ MULXQ 120(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 120(AX), R8
+ MOVQ R8, 120(AX)
+
+ // Add back carry flags and return
+ ADCXQ SI, BX
+ ADOXQ SI, BX
+ MOVQ BX, c+24(FP)
+ RET
+
+// func addMulVVW1536(z *uint, x *uint, y uint) (c uint)
+// Requires: ADX, BMI2
+TEXT ·addMulVVW1536(SB), $0-32
+ CMPB ·supportADX+0(SB), $0x01
+ JEQ adx
+ MOVQ z+0(FP), CX
+ MOVQ x+8(FP), BX
+ MOVQ y+16(FP), SI
+ XORQ DI, DI
+
+ // Iteration 0
+ MOVQ (BX), AX
+ MULQ SI
+ ADDQ (CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, (CX)
+
+ // Iteration 1
+ MOVQ 8(BX), AX
+ MULQ SI
+ ADDQ 8(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 8(CX)
+
+ // Iteration 2
+ MOVQ 16(BX), AX
+ MULQ SI
+ ADDQ 16(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 16(CX)
+
+ // Iteration 3
+ MOVQ 24(BX), AX
+ MULQ SI
+ ADDQ 24(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 24(CX)
+
+ // Iteration 4
+ MOVQ 32(BX), AX
+ MULQ SI
+ ADDQ 32(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 32(CX)
+
+ // Iteration 5
+ MOVQ 40(BX), AX
+ MULQ SI
+ ADDQ 40(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 40(CX)
+
+ // Iteration 6
+ MOVQ 48(BX), AX
+ MULQ SI
+ ADDQ 48(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 48(CX)
+
+ // Iteration 7
+ MOVQ 56(BX), AX
+ MULQ SI
+ ADDQ 56(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 56(CX)
+
+ // Iteration 8
+ MOVQ 64(BX), AX
+ MULQ SI
+ ADDQ 64(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 64(CX)
+
+ // Iteration 9
+ MOVQ 72(BX), AX
+ MULQ SI
+ ADDQ 72(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 72(CX)
+
+ // Iteration 10
+ MOVQ 80(BX), AX
+ MULQ SI
+ ADDQ 80(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 80(CX)
+
+ // Iteration 11
+ MOVQ 88(BX), AX
+ MULQ SI
+ ADDQ 88(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 88(CX)
+
+ // Iteration 12
+ MOVQ 96(BX), AX
+ MULQ SI
+ ADDQ 96(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 96(CX)
+
+ // Iteration 13
+ MOVQ 104(BX), AX
+ MULQ SI
+ ADDQ 104(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 104(CX)
+
+ // Iteration 14
+ MOVQ 112(BX), AX
+ MULQ SI
+ ADDQ 112(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 112(CX)
+
+ // Iteration 15
+ MOVQ 120(BX), AX
+ MULQ SI
+ ADDQ 120(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 120(CX)
+
+ // Iteration 16
+ MOVQ 128(BX), AX
+ MULQ SI
+ ADDQ 128(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 128(CX)
+
+ // Iteration 17
+ MOVQ 136(BX), AX
+ MULQ SI
+ ADDQ 136(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 136(CX)
+
+ // Iteration 18
+ MOVQ 144(BX), AX
+ MULQ SI
+ ADDQ 144(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 144(CX)
+
+ // Iteration 19
+ MOVQ 152(BX), AX
+ MULQ SI
+ ADDQ 152(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 152(CX)
+
+ // Iteration 20
+ MOVQ 160(BX), AX
+ MULQ SI
+ ADDQ 160(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 160(CX)
+
+ // Iteration 21
+ MOVQ 168(BX), AX
+ MULQ SI
+ ADDQ 168(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 168(CX)
+
+ // Iteration 22
+ MOVQ 176(BX), AX
+ MULQ SI
+ ADDQ 176(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 176(CX)
+
+ // Iteration 23
+ MOVQ 184(BX), AX
+ MULQ SI
+ ADDQ 184(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 184(CX)
+ MOVQ DI, c+24(FP)
+ RET
+
+adx:
+ MOVQ z+0(FP), AX
+ MOVQ x+8(FP), CX
+ MOVQ y+16(FP), DX
+ XORQ BX, BX
+ XORQ SI, SI
+
+ // Iteration 0
+ MULXQ (CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ (AX), R8
+ MOVQ R8, (AX)
+
+ // Iteration 1
+ MULXQ 8(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 8(AX), R8
+ MOVQ R8, 8(AX)
+
+ // Iteration 2
+ MULXQ 16(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 16(AX), R8
+ MOVQ R8, 16(AX)
+
+ // Iteration 3
+ MULXQ 24(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 24(AX), R8
+ MOVQ R8, 24(AX)
+
+ // Iteration 4
+ MULXQ 32(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 32(AX), R8
+ MOVQ R8, 32(AX)
+
+ // Iteration 5
+ MULXQ 40(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 40(AX), R8
+ MOVQ R8, 40(AX)
+
+ // Iteration 6
+ MULXQ 48(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 48(AX), R8
+ MOVQ R8, 48(AX)
+
+ // Iteration 7
+ MULXQ 56(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 56(AX), R8
+ MOVQ R8, 56(AX)
+
+ // Iteration 8
+ MULXQ 64(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 64(AX), R8
+ MOVQ R8, 64(AX)
+
+ // Iteration 9
+ MULXQ 72(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 72(AX), R8
+ MOVQ R8, 72(AX)
+
+ // Iteration 10
+ MULXQ 80(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 80(AX), R8
+ MOVQ R8, 80(AX)
+
+ // Iteration 11
+ MULXQ 88(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 88(AX), R8
+ MOVQ R8, 88(AX)
+
+ // Iteration 12
+ MULXQ 96(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 96(AX), R8
+ MOVQ R8, 96(AX)
+
+ // Iteration 13
+ MULXQ 104(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 104(AX), R8
+ MOVQ R8, 104(AX)
+
+ // Iteration 14
+ MULXQ 112(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 112(AX), R8
+ MOVQ R8, 112(AX)
+
+ // Iteration 15
+ MULXQ 120(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 120(AX), R8
+ MOVQ R8, 120(AX)
+
+ // Iteration 16
+ MULXQ 128(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 128(AX), R8
+ MOVQ R8, 128(AX)
+
+ // Iteration 17
+ MULXQ 136(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 136(AX), R8
+ MOVQ R8, 136(AX)
+
+ // Iteration 18
+ MULXQ 144(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 144(AX), R8
+ MOVQ R8, 144(AX)
+
+ // Iteration 19
+ MULXQ 152(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 152(AX), R8
+ MOVQ R8, 152(AX)
+
+ // Iteration 20
+ MULXQ 160(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 160(AX), R8
+ MOVQ R8, 160(AX)
+
+ // Iteration 21
+ MULXQ 168(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 168(AX), R8
+ MOVQ R8, 168(AX)
+
+ // Iteration 22
+ MULXQ 176(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 176(AX), R8
+ MOVQ R8, 176(AX)
+
+ // Iteration 23
+ MULXQ 184(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 184(AX), R8
+ MOVQ R8, 184(AX)
+
+ // Add back carry flags and return
+ ADCXQ SI, BX
+ ADOXQ SI, BX
+ MOVQ BX, c+24(FP)
+ RET
+
+// func addMulVVW2048(z *uint, x *uint, y uint) (c uint)
+// Requires: ADX, BMI2
+TEXT ·addMulVVW2048(SB), $0-32
+ CMPB ·supportADX+0(SB), $0x01
+ JEQ adx
+ MOVQ z+0(FP), CX
+ MOVQ x+8(FP), BX
+ MOVQ y+16(FP), SI
+ XORQ DI, DI
+
+ // Iteration 0
+ MOVQ (BX), AX
+ MULQ SI
+ ADDQ (CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, (CX)
+
+ // Iteration 1
+ MOVQ 8(BX), AX
+ MULQ SI
+ ADDQ 8(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 8(CX)
+
+ // Iteration 2
+ MOVQ 16(BX), AX
+ MULQ SI
+ ADDQ 16(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 16(CX)
+
+ // Iteration 3
+ MOVQ 24(BX), AX
+ MULQ SI
+ ADDQ 24(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 24(CX)
+
+ // Iteration 4
+ MOVQ 32(BX), AX
+ MULQ SI
+ ADDQ 32(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 32(CX)
+
+ // Iteration 5
+ MOVQ 40(BX), AX
+ MULQ SI
+ ADDQ 40(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 40(CX)
+
+ // Iteration 6
+ MOVQ 48(BX), AX
+ MULQ SI
+ ADDQ 48(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 48(CX)
+
+ // Iteration 7
+ MOVQ 56(BX), AX
+ MULQ SI
+ ADDQ 56(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 56(CX)
+
+ // Iteration 8
+ MOVQ 64(BX), AX
+ MULQ SI
+ ADDQ 64(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 64(CX)
+
+ // Iteration 9
+ MOVQ 72(BX), AX
+ MULQ SI
+ ADDQ 72(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 72(CX)
+
+ // Iteration 10
+ MOVQ 80(BX), AX
+ MULQ SI
+ ADDQ 80(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 80(CX)
+
+ // Iteration 11
+ MOVQ 88(BX), AX
+ MULQ SI
+ ADDQ 88(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 88(CX)
+
+ // Iteration 12
+ MOVQ 96(BX), AX
+ MULQ SI
+ ADDQ 96(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 96(CX)
+
+ // Iteration 13
+ MOVQ 104(BX), AX
+ MULQ SI
+ ADDQ 104(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 104(CX)
+
+ // Iteration 14
+ MOVQ 112(BX), AX
+ MULQ SI
+ ADDQ 112(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 112(CX)
+
+ // Iteration 15
+ MOVQ 120(BX), AX
+ MULQ SI
+ ADDQ 120(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 120(CX)
+
+ // Iteration 16
+ MOVQ 128(BX), AX
+ MULQ SI
+ ADDQ 128(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 128(CX)
+
+ // Iteration 17
+ MOVQ 136(BX), AX
+ MULQ SI
+ ADDQ 136(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 136(CX)
+
+ // Iteration 18
+ MOVQ 144(BX), AX
+ MULQ SI
+ ADDQ 144(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 144(CX)
+
+ // Iteration 19
+ MOVQ 152(BX), AX
+ MULQ SI
+ ADDQ 152(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 152(CX)
+
+ // Iteration 20
+ MOVQ 160(BX), AX
+ MULQ SI
+ ADDQ 160(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 160(CX)
+
+ // Iteration 21
+ MOVQ 168(BX), AX
+ MULQ SI
+ ADDQ 168(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 168(CX)
+
+ // Iteration 22
+ MOVQ 176(BX), AX
+ MULQ SI
+ ADDQ 176(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 176(CX)
+
+ // Iteration 23
+ MOVQ 184(BX), AX
+ MULQ SI
+ ADDQ 184(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 184(CX)
+
+ // Iteration 24
+ MOVQ 192(BX), AX
+ MULQ SI
+ ADDQ 192(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 192(CX)
+
+ // Iteration 25
+ MOVQ 200(BX), AX
+ MULQ SI
+ ADDQ 200(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 200(CX)
+
+ // Iteration 26
+ MOVQ 208(BX), AX
+ MULQ SI
+ ADDQ 208(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 208(CX)
+
+ // Iteration 27
+ MOVQ 216(BX), AX
+ MULQ SI
+ ADDQ 216(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 216(CX)
+
+ // Iteration 28
+ MOVQ 224(BX), AX
+ MULQ SI
+ ADDQ 224(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 224(CX)
+
+ // Iteration 29
+ MOVQ 232(BX), AX
+ MULQ SI
+ ADDQ 232(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 232(CX)
+
+ // Iteration 30
+ MOVQ 240(BX), AX
+ MULQ SI
+ ADDQ 240(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 240(CX)
+
+ // Iteration 31
+ MOVQ 248(BX), AX
+ MULQ SI
+ ADDQ 248(CX), AX
+ ADCQ $0x00, DX
+ ADDQ DI, AX
+ ADCQ $0x00, DX
+ MOVQ DX, DI
+ MOVQ AX, 248(CX)
+ MOVQ DI, c+24(FP)
+ RET
+
+adx:
+ MOVQ z+0(FP), AX
+ MOVQ x+8(FP), CX
+ MOVQ y+16(FP), DX
+ XORQ BX, BX
+ XORQ SI, SI
+
+ // Iteration 0
+ MULXQ (CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ (AX), R8
+ MOVQ R8, (AX)
+
+ // Iteration 1
+ MULXQ 8(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 8(AX), R8
+ MOVQ R8, 8(AX)
+
+ // Iteration 2
+ MULXQ 16(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 16(AX), R8
+ MOVQ R8, 16(AX)
+
+ // Iteration 3
+ MULXQ 24(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 24(AX), R8
+ MOVQ R8, 24(AX)
+
+ // Iteration 4
+ MULXQ 32(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 32(AX), R8
+ MOVQ R8, 32(AX)
+
+ // Iteration 5
+ MULXQ 40(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 40(AX), R8
+ MOVQ R8, 40(AX)
+
+ // Iteration 6
+ MULXQ 48(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 48(AX), R8
+ MOVQ R8, 48(AX)
+
+ // Iteration 7
+ MULXQ 56(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 56(AX), R8
+ MOVQ R8, 56(AX)
+
+ // Iteration 8
+ MULXQ 64(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 64(AX), R8
+ MOVQ R8, 64(AX)
+
+ // Iteration 9
+ MULXQ 72(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 72(AX), R8
+ MOVQ R8, 72(AX)
+
+ // Iteration 10
+ MULXQ 80(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 80(AX), R8
+ MOVQ R8, 80(AX)
+
+ // Iteration 11
+ MULXQ 88(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 88(AX), R8
+ MOVQ R8, 88(AX)
+
+ // Iteration 12
+ MULXQ 96(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 96(AX), R8
+ MOVQ R8, 96(AX)
+
+ // Iteration 13
+ MULXQ 104(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 104(AX), R8
+ MOVQ R8, 104(AX)
+
+ // Iteration 14
+ MULXQ 112(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 112(AX), R8
+ MOVQ R8, 112(AX)
+
+ // Iteration 15
+ MULXQ 120(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 120(AX), R8
+ MOVQ R8, 120(AX)
+
+ // Iteration 16
+ MULXQ 128(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 128(AX), R8
+ MOVQ R8, 128(AX)
+
+ // Iteration 17
+ MULXQ 136(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 136(AX), R8
+ MOVQ R8, 136(AX)
+
+ // Iteration 18
+ MULXQ 144(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 144(AX), R8
+ MOVQ R8, 144(AX)
+
+ // Iteration 19
+ MULXQ 152(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 152(AX), R8
+ MOVQ R8, 152(AX)
+
+ // Iteration 20
+ MULXQ 160(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 160(AX), R8
+ MOVQ R8, 160(AX)
+
+ // Iteration 21
+ MULXQ 168(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 168(AX), R8
+ MOVQ R8, 168(AX)
+
+ // Iteration 22
+ MULXQ 176(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 176(AX), R8
+ MOVQ R8, 176(AX)
+
+ // Iteration 23
+ MULXQ 184(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 184(AX), R8
+ MOVQ R8, 184(AX)
+
+ // Iteration 24
+ MULXQ 192(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 192(AX), R8
+ MOVQ R8, 192(AX)
+
+ // Iteration 25
+ MULXQ 200(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 200(AX), R8
+ MOVQ R8, 200(AX)
+
+ // Iteration 26
+ MULXQ 208(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 208(AX), R8
+ MOVQ R8, 208(AX)
+
+ // Iteration 27
+ MULXQ 216(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 216(AX), R8
+ MOVQ R8, 216(AX)
+
+ // Iteration 28
+ MULXQ 224(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 224(AX), R8
+ MOVQ R8, 224(AX)
+
+ // Iteration 29
+ MULXQ 232(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 232(AX), R8
+ MOVQ R8, 232(AX)
+
+ // Iteration 30
+ MULXQ 240(CX), R8, DI
+ ADCXQ BX, R8
+ ADOXQ 240(AX), R8
+ MOVQ R8, 240(AX)
+
+ // Iteration 31
+ MULXQ 248(CX), R8, BX
+ ADCXQ DI, R8
+ ADOXQ 248(AX), R8
+ MOVQ R8, 248(AX)
+
+ // Add back carry flags and return
+ ADCXQ SI, BX
+ ADOXQ SI, BX
+ MOVQ BX, c+24(FP)
+ RET
diff --git a/contrib/go/_std_1.21/src/crypto/internal/bigmod/nat_arm64.s b/contrib/go/_std_1.21/src/crypto/internal/bigmod/nat_arm64.s
new file mode 100644
index 0000000000..ba1e6118cc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/bigmod/nat_arm64.s
@@ -0,0 +1,69 @@
+// Copyright 2013 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.
+
+//go:build !purego
+
+#include "textflag.h"
+
+// func addMulVVW1024(z, x *uint, y uint) (c uint)
+TEXT ·addMulVVW1024(SB), $0-32
+ MOVD $16, R0
+ JMP addMulVVWx(SB)
+
+// func addMulVVW1536(z, x *uint, y uint) (c uint)
+TEXT ·addMulVVW1536(SB), $0-32
+ MOVD $24, R0
+ JMP addMulVVWx(SB)
+
+// func addMulVVW2048(z, x *uint, y uint) (c uint)
+TEXT ·addMulVVW2048(SB), $0-32
+ MOVD $32, R0
+ JMP addMulVVWx(SB)
+
+TEXT addMulVVWx(SB), NOFRAME|NOSPLIT, $0
+ MOVD z+0(FP), R1
+ MOVD x+8(FP), R2
+ MOVD y+16(FP), R3
+ MOVD $0, R4
+
+// The main loop of this code operates on a block of 4 words every iteration
+// performing [R4:R12:R11:R10:R9] = R4 + R3 * [R8:R7:R6:R5] + [R12:R11:R10:R9]
+// where R4 is carried from the previous iteration, R8:R7:R6:R5 hold the next
+// 4 words of x, R3 is y and R12:R11:R10:R9 are part of the result z.
+loop:
+ CBZ R0, done
+
+ LDP.P 16(R2), (R5, R6)
+ LDP.P 16(R2), (R7, R8)
+
+ LDP (R1), (R9, R10)
+ ADDS R4, R9
+ MUL R6, R3, R14
+ ADCS R14, R10
+ MUL R7, R3, R15
+ LDP 16(R1), (R11, R12)
+ ADCS R15, R11
+ MUL R8, R3, R16
+ ADCS R16, R12
+ UMULH R8, R3, R20
+ ADC $0, R20
+
+ MUL R5, R3, R13
+ ADDS R13, R9
+ UMULH R5, R3, R17
+ ADCS R17, R10
+ UMULH R6, R3, R21
+ STP.P (R9, R10), 16(R1)
+ ADCS R21, R11
+ UMULH R7, R3, R19
+ ADCS R19, R12
+ STP.P (R11, R12), 16(R1)
+ ADC $0, R20, R4
+
+ SUB $4, R0
+ B loop
+
+done:
+ MOVD R4, c+24(FP)
+ RET
diff --git a/contrib/go/_std_1.21/src/crypto/internal/bigmod/nat_asm.go b/contrib/go/_std_1.21/src/crypto/internal/bigmod/nat_asm.go
new file mode 100644
index 0000000000..5eb91e1c6c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/bigmod/nat_asm.go
@@ -0,0 +1,28 @@
+// Copyright 2023 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.
+
+//go:build !purego && (386 || amd64 || arm || arm64 || ppc64 || ppc64le || s390x)
+
+package bigmod
+
+import "internal/cpu"
+
+// amd64 assembly uses ADCX/ADOX/MULX if ADX is available to run two carry
+// chains in the flags in parallel across the whole operation, and aggressively
+// unrolls loops. arm64 processes four words at a time.
+//
+// It's unclear why the assembly for all other architectures, as well as for
+// amd64 without ADX, perform better than the compiler output.
+// TODO(filippo): file cmd/compile performance issue.
+
+var supportADX = cpu.X86.HasADX && cpu.X86.HasBMI2
+
+//go:noescape
+func addMulVVW1024(z, x *uint, y uint) (c uint)
+
+//go:noescape
+func addMulVVW1536(z, x *uint, y uint) (c uint)
+
+//go:noescape
+func addMulVVW2048(z, x *uint, y uint) (c uint)
diff --git a/contrib/go/_std_1.21/src/crypto/internal/bigmod/ya.make b/contrib/go/_std_1.21/src/crypto/internal/bigmod/ya.make
new file mode 100644
index 0000000000..3aff5955ad
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/bigmod/ya.make
@@ -0,0 +1,25 @@
+GO_LIBRARY()
+
+SRCS(
+ nat.go
+ nat_asm.go
+)
+
+GO_TEST_SRCS(nat_test.go)
+
+IF (ARCH_X86_64)
+ SRCS(
+ nat_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ nat_arm64.s
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/internal/boring/bbig/big.go b/contrib/go/_std_1.21/src/crypto/internal/boring/bbig/big.go
index 5ce46972b3..5ce46972b3 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/boring/bbig/big.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/bbig/big.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/boring/bbig/ya.make b/contrib/go/_std_1.21/src/crypto/internal/boring/bbig/ya.make
index 762b87265e..762b87265e 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/boring/bbig/ya.make
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/bbig/ya.make
diff --git a/contrib/go/_std_1.20/src/crypto/internal/boring/bcache/cache.go b/contrib/go/_std_1.21/src/crypto/internal/boring/bcache/cache.go
index 7934d03e7b..7934d03e7b 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/boring/bcache/cache.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/bcache/cache.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/boring/bcache/stub.s b/contrib/go/_std_1.21/src/crypto/internal/boring/bcache/stub.s
index 59f2deeb60..59f2deeb60 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/boring/bcache/stub.s
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/bcache/stub.s
diff --git a/contrib/go/_std_1.21/src/crypto/internal/boring/bcache/ya.make b/contrib/go/_std_1.21/src/crypto/internal/boring/bcache/ya.make
new file mode 100644
index 0000000000..9e7974385f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/bcache/ya.make
@@ -0,0 +1,13 @@
+GO_LIBRARY()
+
+SRCS(
+ cache.go
+ stub.s
+)
+
+GO_TEST_SRCS(cache_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/internal/boring/doc.go b/contrib/go/_std_1.21/src/crypto/internal/boring/doc.go
index 6060fe5951..6060fe5951 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/boring/doc.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/doc.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/boring/notboring.go b/contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go
index 1c5e4c742d..1c5e4c742d 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/boring/notboring.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/notboring.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/boring/sig/sig.go b/contrib/go/_std_1.21/src/crypto/internal/boring/sig/sig.go
index 716c03c5e9..716c03c5e9 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/boring/sig/sig.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/sig/sig.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/boring/sig/sig_amd64.s b/contrib/go/_std_1.21/src/crypto/internal/boring/sig/sig_amd64.s
index 64e3462e4e..64e3462e4e 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/boring/sig/sig_amd64.s
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/sig/sig_amd64.s
diff --git a/contrib/go/_std_1.20/src/crypto/internal/boring/sig/sig_other.s b/contrib/go/_std_1.21/src/crypto/internal/boring/sig/sig_other.s
index 2bbb1df301..2bbb1df301 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/boring/sig/sig_other.s
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/sig/sig_other.s
diff --git a/contrib/go/_std_1.21/src/crypto/internal/boring/sig/ya.make b/contrib/go/_std_1.21/src/crypto/internal/boring/sig/ya.make
new file mode 100644
index 0000000000..d23e74bdf2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/sig/ya.make
@@ -0,0 +1,19 @@
+GO_LIBRARY()
+
+SRCS(
+ sig.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ sig_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ sig_other.s
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.21/src/crypto/internal/boring/ya.make b/contrib/go/_std_1.21/src/crypto/internal/boring/ya.make
new file mode 100644
index 0000000000..acdd9ce54d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/boring/ya.make
@@ -0,0 +1,16 @@
+GO_LIBRARY()
+
+SRCS(
+ doc.go
+ notboring.go
+)
+
+GO_TEST_SRCS(boring_test.go)
+
+END()
+
+RECURSE(
+ bbig
+ bcache
+ sig
+)
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/doc.go b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/doc.go
index 8cba6febfe..8cba6febfe 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/doc.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/doc.go
diff --git a/contrib/go/_std_1.21/src/crypto/internal/edwards25519/edwards25519.go b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/edwards25519.go
new file mode 100644
index 0000000000..e162dc8cbd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/edwards25519.go
@@ -0,0 +1,426 @@
+// Copyright (c) 2017 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 edwards25519
+
+import (
+ "crypto/internal/edwards25519/field"
+ "errors"
+)
+
+// Point types.
+
+type projP1xP1 struct {
+ X, Y, Z, T field.Element
+}
+
+type projP2 struct {
+ X, Y, Z field.Element
+}
+
+// Point represents a point on the edwards25519 curve.
+//
+// This type works similarly to math/big.Int, and all arguments and receivers
+// are allowed to alias.
+//
+// The zero value is NOT valid, and it may be used only as a receiver.
+type Point struct {
+ // Make the type not comparable (i.e. used with == or as a map key), as
+ // equivalent points can be represented by different Go values.
+ _ incomparable
+
+ // The point is internally represented in extended coordinates (X, Y, Z, T)
+ // where x = X/Z, y = Y/Z, and xy = T/Z per https://eprint.iacr.org/2008/522.
+ x, y, z, t field.Element
+}
+
+type incomparable [0]func()
+
+func checkInitialized(points ...*Point) {
+ for _, p := range points {
+ if p.x == (field.Element{}) && p.y == (field.Element{}) {
+ panic("edwards25519: use of uninitialized Point")
+ }
+ }
+}
+
+type projCached struct {
+ YplusX, YminusX, Z, T2d field.Element
+}
+
+type affineCached struct {
+ YplusX, YminusX, T2d field.Element
+}
+
+// Constructors.
+
+func (v *projP2) Zero() *projP2 {
+ v.X.Zero()
+ v.Y.One()
+ v.Z.One()
+ return v
+}
+
+// identity is the point at infinity.
+var identity, _ = new(Point).SetBytes([]byte{
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
+
+// NewIdentityPoint returns a new Point set to the identity.
+func NewIdentityPoint() *Point {
+ return new(Point).Set(identity)
+}
+
+// generator is the canonical curve basepoint. See TestGenerator for the
+// correspondence of this encoding with the values in RFC 8032.
+var generator, _ = new(Point).SetBytes([]byte{
+ 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66})
+
+// NewGeneratorPoint returns a new Point set to the canonical generator.
+func NewGeneratorPoint() *Point {
+ return new(Point).Set(generator)
+}
+
+func (v *projCached) Zero() *projCached {
+ v.YplusX.One()
+ v.YminusX.One()
+ v.Z.One()
+ v.T2d.Zero()
+ return v
+}
+
+func (v *affineCached) Zero() *affineCached {
+ v.YplusX.One()
+ v.YminusX.One()
+ v.T2d.Zero()
+ return v
+}
+
+// Assignments.
+
+// Set sets v = u, and returns v.
+func (v *Point) Set(u *Point) *Point {
+ *v = *u
+ return v
+}
+
+// Encoding.
+
+// Bytes returns the canonical 32-byte encoding of v, according to RFC 8032,
+// Section 5.1.2.
+func (v *Point) Bytes() []byte {
+ // This function is outlined to make the allocations inline in the caller
+ // rather than happen on the heap.
+ var buf [32]byte
+ return v.bytes(&buf)
+}
+
+func (v *Point) bytes(buf *[32]byte) []byte {
+ checkInitialized(v)
+
+ var zInv, x, y field.Element
+ zInv.Invert(&v.z) // zInv = 1 / Z
+ x.Multiply(&v.x, &zInv) // x = X / Z
+ y.Multiply(&v.y, &zInv) // y = Y / Z
+
+ out := copyFieldElement(buf, &y)
+ out[31] |= byte(x.IsNegative() << 7)
+ return out
+}
+
+var feOne = new(field.Element).One()
+
+// SetBytes sets v = x, where x is a 32-byte encoding of v. If x does not
+// represent a valid point on the curve, SetBytes returns nil and an error and
+// the receiver is unchanged. Otherwise, SetBytes returns v.
+//
+// Note that SetBytes accepts all non-canonical encodings of valid points.
+// That is, it follows decoding rules that match most implementations in
+// the ecosystem rather than RFC 8032.
+func (v *Point) SetBytes(x []byte) (*Point, error) {
+ // Specifically, the non-canonical encodings that are accepted are
+ // 1) the ones where the field element is not reduced (see the
+ // (*field.Element).SetBytes docs) and
+ // 2) the ones where the x-coordinate is zero and the sign bit is set.
+ //
+ // Read more at https://hdevalence.ca/blog/2020-10-04-its-25519am,
+ // specifically the "Canonical A, R" section.
+
+ y, err := new(field.Element).SetBytes(x)
+ if err != nil {
+ return nil, errors.New("edwards25519: invalid point encoding length")
+ }
+
+ // -x² + y² = 1 + dx²y²
+ // x² + dx²y² = x²(dy² + 1) = y² - 1
+ // x² = (y² - 1) / (dy² + 1)
+
+ // u = y² - 1
+ y2 := new(field.Element).Square(y)
+ u := new(field.Element).Subtract(y2, feOne)
+
+ // v = dy² + 1
+ vv := new(field.Element).Multiply(y2, d)
+ vv = vv.Add(vv, feOne)
+
+ // x = +√(u/v)
+ xx, wasSquare := new(field.Element).SqrtRatio(u, vv)
+ if wasSquare == 0 {
+ return nil, errors.New("edwards25519: invalid point encoding")
+ }
+
+ // Select the negative square root if the sign bit is set.
+ xxNeg := new(field.Element).Negate(xx)
+ xx = xx.Select(xxNeg, xx, int(x[31]>>7))
+
+ v.x.Set(xx)
+ v.y.Set(y)
+ v.z.One()
+ v.t.Multiply(xx, y) // xy = T / Z
+
+ return v, nil
+}
+
+func copyFieldElement(buf *[32]byte, v *field.Element) []byte {
+ copy(buf[:], v.Bytes())
+ return buf[:]
+}
+
+// Conversions.
+
+func (v *projP2) FromP1xP1(p *projP1xP1) *projP2 {
+ v.X.Multiply(&p.X, &p.T)
+ v.Y.Multiply(&p.Y, &p.Z)
+ v.Z.Multiply(&p.Z, &p.T)
+ return v
+}
+
+func (v *projP2) FromP3(p *Point) *projP2 {
+ v.X.Set(&p.x)
+ v.Y.Set(&p.y)
+ v.Z.Set(&p.z)
+ return v
+}
+
+func (v *Point) fromP1xP1(p *projP1xP1) *Point {
+ v.x.Multiply(&p.X, &p.T)
+ v.y.Multiply(&p.Y, &p.Z)
+ v.z.Multiply(&p.Z, &p.T)
+ v.t.Multiply(&p.X, &p.Y)
+ return v
+}
+
+func (v *Point) fromP2(p *projP2) *Point {
+ v.x.Multiply(&p.X, &p.Z)
+ v.y.Multiply(&p.Y, &p.Z)
+ v.z.Square(&p.Z)
+ v.t.Multiply(&p.X, &p.Y)
+ return v
+}
+
+// d is a constant in the curve equation.
+var d, _ = new(field.Element).SetBytes([]byte{
+ 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
+ 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
+ 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
+ 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52})
+var d2 = new(field.Element).Add(d, d)
+
+func (v *projCached) FromP3(p *Point) *projCached {
+ v.YplusX.Add(&p.y, &p.x)
+ v.YminusX.Subtract(&p.y, &p.x)
+ v.Z.Set(&p.z)
+ v.T2d.Multiply(&p.t, d2)
+ return v
+}
+
+func (v *affineCached) FromP3(p *Point) *affineCached {
+ v.YplusX.Add(&p.y, &p.x)
+ v.YminusX.Subtract(&p.y, &p.x)
+ v.T2d.Multiply(&p.t, d2)
+
+ var invZ field.Element
+ invZ.Invert(&p.z)
+ v.YplusX.Multiply(&v.YplusX, &invZ)
+ v.YminusX.Multiply(&v.YminusX, &invZ)
+ v.T2d.Multiply(&v.T2d, &invZ)
+ return v
+}
+
+// (Re)addition and subtraction.
+
+// Add sets v = p + q, and returns v.
+func (v *Point) Add(p, q *Point) *Point {
+ checkInitialized(p, q)
+ qCached := new(projCached).FromP3(q)
+ result := new(projP1xP1).Add(p, qCached)
+ return v.fromP1xP1(result)
+}
+
+// Subtract sets v = p - q, and returns v.
+func (v *Point) Subtract(p, q *Point) *Point {
+ checkInitialized(p, q)
+ qCached := new(projCached).FromP3(q)
+ result := new(projP1xP1).Sub(p, qCached)
+ return v.fromP1xP1(result)
+}
+
+func (v *projP1xP1) Add(p *Point, q *projCached) *projP1xP1 {
+ var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element
+
+ YplusX.Add(&p.y, &p.x)
+ YminusX.Subtract(&p.y, &p.x)
+
+ PP.Multiply(&YplusX, &q.YplusX)
+ MM.Multiply(&YminusX, &q.YminusX)
+ TT2d.Multiply(&p.t, &q.T2d)
+ ZZ2.Multiply(&p.z, &q.Z)
+
+ ZZ2.Add(&ZZ2, &ZZ2)
+
+ v.X.Subtract(&PP, &MM)
+ v.Y.Add(&PP, &MM)
+ v.Z.Add(&ZZ2, &TT2d)
+ v.T.Subtract(&ZZ2, &TT2d)
+ return v
+}
+
+func (v *projP1xP1) Sub(p *Point, q *projCached) *projP1xP1 {
+ var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element
+
+ YplusX.Add(&p.y, &p.x)
+ YminusX.Subtract(&p.y, &p.x)
+
+ PP.Multiply(&YplusX, &q.YminusX) // flipped sign
+ MM.Multiply(&YminusX, &q.YplusX) // flipped sign
+ TT2d.Multiply(&p.t, &q.T2d)
+ ZZ2.Multiply(&p.z, &q.Z)
+
+ ZZ2.Add(&ZZ2, &ZZ2)
+
+ v.X.Subtract(&PP, &MM)
+ v.Y.Add(&PP, &MM)
+ v.Z.Subtract(&ZZ2, &TT2d) // flipped sign
+ v.T.Add(&ZZ2, &TT2d) // flipped sign
+ return v
+}
+
+func (v *projP1xP1) AddAffine(p *Point, q *affineCached) *projP1xP1 {
+ var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element
+
+ YplusX.Add(&p.y, &p.x)
+ YminusX.Subtract(&p.y, &p.x)
+
+ PP.Multiply(&YplusX, &q.YplusX)
+ MM.Multiply(&YminusX, &q.YminusX)
+ TT2d.Multiply(&p.t, &q.T2d)
+
+ Z2.Add(&p.z, &p.z)
+
+ v.X.Subtract(&PP, &MM)
+ v.Y.Add(&PP, &MM)
+ v.Z.Add(&Z2, &TT2d)
+ v.T.Subtract(&Z2, &TT2d)
+ return v
+}
+
+func (v *projP1xP1) SubAffine(p *Point, q *affineCached) *projP1xP1 {
+ var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element
+
+ YplusX.Add(&p.y, &p.x)
+ YminusX.Subtract(&p.y, &p.x)
+
+ PP.Multiply(&YplusX, &q.YminusX) // flipped sign
+ MM.Multiply(&YminusX, &q.YplusX) // flipped sign
+ TT2d.Multiply(&p.t, &q.T2d)
+
+ Z2.Add(&p.z, &p.z)
+
+ v.X.Subtract(&PP, &MM)
+ v.Y.Add(&PP, &MM)
+ v.Z.Subtract(&Z2, &TT2d) // flipped sign
+ v.T.Add(&Z2, &TT2d) // flipped sign
+ return v
+}
+
+// Doubling.
+
+func (v *projP1xP1) Double(p *projP2) *projP1xP1 {
+ var XX, YY, ZZ2, XplusYsq field.Element
+
+ XX.Square(&p.X)
+ YY.Square(&p.Y)
+ ZZ2.Square(&p.Z)
+ ZZ2.Add(&ZZ2, &ZZ2)
+ XplusYsq.Add(&p.X, &p.Y)
+ XplusYsq.Square(&XplusYsq)
+
+ v.Y.Add(&YY, &XX)
+ v.Z.Subtract(&YY, &XX)
+
+ v.X.Subtract(&XplusYsq, &v.Y)
+ v.T.Subtract(&ZZ2, &v.Z)
+ return v
+}
+
+// Negation.
+
+// Negate sets v = -p, and returns v.
+func (v *Point) Negate(p *Point) *Point {
+ checkInitialized(p)
+ v.x.Negate(&p.x)
+ v.y.Set(&p.y)
+ v.z.Set(&p.z)
+ v.t.Negate(&p.t)
+ return v
+}
+
+// Equal returns 1 if v is equivalent to u, and 0 otherwise.
+func (v *Point) Equal(u *Point) int {
+ checkInitialized(v, u)
+
+ var t1, t2, t3, t4 field.Element
+ t1.Multiply(&v.x, &u.z)
+ t2.Multiply(&u.x, &v.z)
+ t3.Multiply(&v.y, &u.z)
+ t4.Multiply(&u.y, &v.z)
+
+ return t1.Equal(&t2) & t3.Equal(&t4)
+}
+
+// Constant-time operations
+
+// Select sets v to a if cond == 1 and to b if cond == 0.
+func (v *projCached) Select(a, b *projCached, cond int) *projCached {
+ v.YplusX.Select(&a.YplusX, &b.YplusX, cond)
+ v.YminusX.Select(&a.YminusX, &b.YminusX, cond)
+ v.Z.Select(&a.Z, &b.Z, cond)
+ v.T2d.Select(&a.T2d, &b.T2d, cond)
+ return v
+}
+
+// Select sets v to a if cond == 1 and to b if cond == 0.
+func (v *affineCached) Select(a, b *affineCached, cond int) *affineCached {
+ v.YplusX.Select(&a.YplusX, &b.YplusX, cond)
+ v.YminusX.Select(&a.YminusX, &b.YminusX, cond)
+ v.T2d.Select(&a.T2d, &b.T2d, cond)
+ return v
+}
+
+// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0.
+func (v *projCached) CondNeg(cond int) *projCached {
+ v.YplusX.Swap(&v.YminusX, cond)
+ v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond)
+ return v
+}
+
+// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0.
+func (v *affineCached) CondNeg(cond int) *affineCached {
+ v.YplusX.Swap(&v.YminusX, cond)
+ v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond)
+ return v
+}
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe.go b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe.go
index 5518ef2b90..5518ef2b90 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_amd64.go b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_amd64.go
index 70c541692c..70c541692c 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_amd64.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_amd64.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_amd64.s b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_amd64.s
index 60817acc41..60817acc41 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_amd64.s
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_amd64.s
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_amd64_noasm.go b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_amd64_noasm.go
index 9da280d1d8..9da280d1d8 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_amd64_noasm.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_amd64_noasm.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_arm64.go b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_arm64.go
index 075fe9b925..075fe9b925 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_arm64.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_arm64.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_arm64.s b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_arm64.s
index 751ab2ada3..751ab2ada3 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_arm64.s
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_arm64.s
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_arm64_noasm.go b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_arm64_noasm.go
index fc029ac12d..fc029ac12d 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/field/fe_arm64_noasm.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_arm64_noasm.go
diff --git a/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_generic.go b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_generic.go
new file mode 100644
index 0000000000..3582df8b22
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/fe_generic.go
@@ -0,0 +1,266 @@
+// Copyright (c) 2017 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 field
+
+import "math/bits"
+
+// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
+// bits.Mul64 and bits.Add64 intrinsics.
+type uint128 struct {
+ lo, hi uint64
+}
+
+// mul64 returns a * b.
+func mul64(a, b uint64) uint128 {
+ hi, lo := bits.Mul64(a, b)
+ return uint128{lo, hi}
+}
+
+// addMul64 returns v + a * b.
+func addMul64(v uint128, a, b uint64) uint128 {
+ hi, lo := bits.Mul64(a, b)
+ lo, c := bits.Add64(lo, v.lo, 0)
+ hi, _ = bits.Add64(hi, v.hi, c)
+ return uint128{lo, hi}
+}
+
+// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits.
+func shiftRightBy51(a uint128) uint64 {
+ return (a.hi << (64 - 51)) | (a.lo >> 51)
+}
+
+func feMulGeneric(v, a, b *Element) {
+ a0 := a.l0
+ a1 := a.l1
+ a2 := a.l2
+ a3 := a.l3
+ a4 := a.l4
+
+ b0 := b.l0
+ b1 := b.l1
+ b2 := b.l2
+ b3 := b.l3
+ b4 := b.l4
+
+ // Limb multiplication works like pen-and-paper columnar multiplication, but
+ // with 51-bit limbs instead of digits.
+ //
+ // a4 a3 a2 a1 a0 x
+ // b4 b3 b2 b1 b0 =
+ // ------------------------
+ // a4b0 a3b0 a2b0 a1b0 a0b0 +
+ // a4b1 a3b1 a2b1 a1b1 a0b1 +
+ // a4b2 a3b2 a2b2 a1b2 a0b2 +
+ // a4b3 a3b3 a2b3 a1b3 a0b3 +
+ // a4b4 a3b4 a2b4 a1b4 a0b4 =
+ // ----------------------------------------------
+ // r8 r7 r6 r5 r4 r3 r2 r1 r0
+ //
+ // We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to
+ // reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5,
+ // r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc.
+ //
+ // Reduction can be carried out simultaneously to multiplication. For
+ // example, we do not compute r5: whenever the result of a multiplication
+ // belongs to r5, like a1b4, we multiply it by 19 and add the result to r0.
+ //
+ // a4b0 a3b0 a2b0 a1b0 a0b0 +
+ // a3b1 a2b1 a1b1 a0b1 19×a4b1 +
+ // a2b2 a1b2 a0b2 19×a4b2 19×a3b2 +
+ // a1b3 a0b3 19×a4b3 19×a3b3 19×a2b3 +
+ // a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4 =
+ // --------------------------------------
+ // r4 r3 r2 r1 r0
+ //
+ // Finally we add up the columns into wide, overlapping limbs.
+
+ a1_19 := a1 * 19
+ a2_19 := a2 * 19
+ a3_19 := a3 * 19
+ a4_19 := a4 * 19
+
+ // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
+ r0 := mul64(a0, b0)
+ r0 = addMul64(r0, a1_19, b4)
+ r0 = addMul64(r0, a2_19, b3)
+ r0 = addMul64(r0, a3_19, b2)
+ r0 = addMul64(r0, a4_19, b1)
+
+ // r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
+ r1 := mul64(a0, b1)
+ r1 = addMul64(r1, a1, b0)
+ r1 = addMul64(r1, a2_19, b4)
+ r1 = addMul64(r1, a3_19, b3)
+ r1 = addMul64(r1, a4_19, b2)
+
+ // r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
+ r2 := mul64(a0, b2)
+ r2 = addMul64(r2, a1, b1)
+ r2 = addMul64(r2, a2, b0)
+ r2 = addMul64(r2, a3_19, b4)
+ r2 = addMul64(r2, a4_19, b3)
+
+ // r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
+ r3 := mul64(a0, b3)
+ r3 = addMul64(r3, a1, b2)
+ r3 = addMul64(r3, a2, b1)
+ r3 = addMul64(r3, a3, b0)
+ r3 = addMul64(r3, a4_19, b4)
+
+ // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
+ r4 := mul64(a0, b4)
+ r4 = addMul64(r4, a1, b3)
+ r4 = addMul64(r4, a2, b2)
+ r4 = addMul64(r4, a3, b1)
+ r4 = addMul64(r4, a4, b0)
+
+ // After the multiplication, we need to reduce (carry) the five coefficients
+ // to obtain a result with limbs that are at most slightly larger than 2⁵¹,
+ // to respect the Element invariant.
+ //
+ // Overall, the reduction works the same as carryPropagate, except with
+ // wider inputs: we take the carry for each coefficient by shifting it right
+ // by 51, and add it to the limb above it. The top carry is multiplied by 19
+ // according to the reduction identity and added to the lowest limb.
+ //
+ // The largest coefficient (r0) will be at most 111 bits, which guarantees
+ // that all carries are at most 111 - 51 = 60 bits, which fits in a uint64.
+ //
+ // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
+ // r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²)
+ // r0 < (1 + 19 × 4) × 2⁵² × 2⁵²
+ // r0 < 2⁷ × 2⁵² × 2⁵²
+ // r0 < 2¹¹¹
+ //
+ // Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most
+ // 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and
+ // allows us to easily apply the reduction identity.
+ //
+ // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
+ // r4 < 5 × 2⁵² × 2⁵²
+ // r4 < 2¹⁰⁷
+ //
+
+ c0 := shiftRightBy51(r0)
+ c1 := shiftRightBy51(r1)
+ c2 := shiftRightBy51(r2)
+ c3 := shiftRightBy51(r3)
+ c4 := shiftRightBy51(r4)
+
+ rr0 := r0.lo&maskLow51Bits + c4*19
+ rr1 := r1.lo&maskLow51Bits + c0
+ rr2 := r2.lo&maskLow51Bits + c1
+ rr3 := r3.lo&maskLow51Bits + c2
+ rr4 := r4.lo&maskLow51Bits + c3
+
+ // Now all coefficients fit into 64-bit registers but are still too large to
+ // be passed around as a Element. We therefore do one last carry chain,
+ // where the carries will be small enough to fit in the wiggle room above 2⁵¹.
+ *v = Element{rr0, rr1, rr2, rr3, rr4}
+ v.carryPropagate()
+}
+
+func feSquareGeneric(v, a *Element) {
+ l0 := a.l0
+ l1 := a.l1
+ l2 := a.l2
+ l3 := a.l3
+ l4 := a.l4
+
+ // Squaring works precisely like multiplication above, but thanks to its
+ // symmetry we get to group a few terms together.
+ //
+ // l4 l3 l2 l1 l0 x
+ // l4 l3 l2 l1 l0 =
+ // ------------------------
+ // l4l0 l3l0 l2l0 l1l0 l0l0 +
+ // l4l1 l3l1 l2l1 l1l1 l0l1 +
+ // l4l2 l3l2 l2l2 l1l2 l0l2 +
+ // l4l3 l3l3 l2l3 l1l3 l0l3 +
+ // l4l4 l3l4 l2l4 l1l4 l0l4 =
+ // ----------------------------------------------
+ // r8 r7 r6 r5 r4 r3 r2 r1 r0
+ //
+ // l4l0 l3l0 l2l0 l1l0 l0l0 +
+ // l3l1 l2l1 l1l1 l0l1 19×l4l1 +
+ // l2l2 l1l2 l0l2 19×l4l2 19×l3l2 +
+ // l1l3 l0l3 19×l4l3 19×l3l3 19×l2l3 +
+ // l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4 =
+ // --------------------------------------
+ // r4 r3 r2 r1 r0
+ //
+ // With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with
+ // only three Mul64 and four Add64, instead of five and eight.
+
+ l0_2 := l0 * 2
+ l1_2 := l1 * 2
+
+ l1_38 := l1 * 38
+ l2_38 := l2 * 38
+ l3_38 := l3 * 38
+
+ l3_19 := l3 * 19
+ l4_19 := l4 * 19
+
+ // r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3)
+ r0 := mul64(l0, l0)
+ r0 = addMul64(r0, l1_38, l4)
+ r0 = addMul64(r0, l2_38, l3)
+
+ // r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
+ r1 := mul64(l0_2, l1)
+ r1 = addMul64(r1, l2_38, l4)
+ r1 = addMul64(r1, l3_19, l3)
+
+ // r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4
+ r2 := mul64(l0_2, l2)
+ r2 = addMul64(r2, l1, l1)
+ r2 = addMul64(r2, l3_38, l4)
+
+ // r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
+ r3 := mul64(l0_2, l3)
+ r3 = addMul64(r3, l1_2, l2)
+ r3 = addMul64(r3, l4_19, l4)
+
+ // r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2
+ r4 := mul64(l0_2, l4)
+ r4 = addMul64(r4, l1_2, l3)
+ r4 = addMul64(r4, l2, l2)
+
+ c0 := shiftRightBy51(r0)
+ c1 := shiftRightBy51(r1)
+ c2 := shiftRightBy51(r2)
+ c3 := shiftRightBy51(r3)
+ c4 := shiftRightBy51(r4)
+
+ rr0 := r0.lo&maskLow51Bits + c4*19
+ rr1 := r1.lo&maskLow51Bits + c0
+ rr2 := r2.lo&maskLow51Bits + c1
+ rr3 := r3.lo&maskLow51Bits + c2
+ rr4 := r4.lo&maskLow51Bits + c3
+
+ *v = Element{rr0, rr1, rr2, rr3, rr4}
+ v.carryPropagate()
+}
+
+// carryPropagateGeneric brings the limbs below 52 bits by applying the reduction
+// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry.
+func (v *Element) carryPropagateGeneric() *Element {
+ c0 := v.l0 >> 51
+ c1 := v.l1 >> 51
+ c2 := v.l2 >> 51
+ c3 := v.l3 >> 51
+ c4 := v.l4 >> 51
+
+ // c4 is at most 64 - 51 = 13 bits, so c4*19 is at most 18 bits, and
+ // the final l0 will be at most 52 bits. Similarly for the rest.
+ v.l0 = v.l0&maskLow51Bits + c4*19
+ v.l1 = v.l1&maskLow51Bits + c0
+ v.l2 = v.l2&maskLow51Bits + c1
+ v.l3 = v.l3&maskLow51Bits + c2
+ v.l4 = v.l4&maskLow51Bits + c3
+
+ return v
+}
diff --git a/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/ya.make b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/ya.make
new file mode 100644
index 0000000000..2b1b5825c7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/field/ya.make
@@ -0,0 +1,37 @@
+GO_LIBRARY()
+
+SRCS(
+ fe.go
+ fe_generic.go
+)
+
+GO_TEST_SRCS(
+ fe_alias_test.go
+ fe_bench_test.go
+ fe_test.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ fe_amd64.go
+ fe_amd64.s
+ fe_arm64_noasm.go
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ fe_amd64_noasm.go
+ fe_arm64.go
+ fe_arm64.s
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
+
+RECURSE(
+ # _asm
+)
diff --git a/contrib/go/_std_1.21/src/crypto/internal/edwards25519/scalar.go b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/scalar.go
new file mode 100644
index 0000000000..3fd1653877
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/scalar.go
@@ -0,0 +1,343 @@
+// Copyright (c) 2016 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 edwards25519
+
+import (
+ "encoding/binary"
+ "errors"
+)
+
+// A Scalar is an integer modulo
+//
+// l = 2^252 + 27742317777372353535851937790883648493
+//
+// which is the prime order of the edwards25519 group.
+//
+// This type works similarly to math/big.Int, and all arguments and
+// receivers are allowed to alias.
+//
+// The zero value is a valid zero element.
+type Scalar struct {
+ // s is the scalar in the Montgomery domain, in the format of the
+ // fiat-crypto implementation.
+ s fiatScalarMontgomeryDomainFieldElement
+}
+
+// The field implementation in scalar_fiat.go is generated by the fiat-crypto
+// project (https://github.com/mit-plv/fiat-crypto) at version v0.0.9 (23d2dbc)
+// from a formally verified model.
+//
+// fiat-crypto code comes under the following license.
+//
+// Copyright (c) 2015-2020 The fiat-crypto Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// THIS SOFTWARE IS PROVIDED BY the fiat-crypto authors "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design,
+// Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// NewScalar returns a new zero Scalar.
+func NewScalar() *Scalar {
+ return &Scalar{}
+}
+
+// MultiplyAdd sets s = x * y + z mod l, and returns s. It is equivalent to
+// using Multiply and then Add.
+func (s *Scalar) MultiplyAdd(x, y, z *Scalar) *Scalar {
+ // Make a copy of z in case it aliases s.
+ zCopy := new(Scalar).Set(z)
+ return s.Multiply(x, y).Add(s, zCopy)
+}
+
+// Add sets s = x + y mod l, and returns s.
+func (s *Scalar) Add(x, y *Scalar) *Scalar {
+ // s = 1 * x + y mod l
+ fiatScalarAdd(&s.s, &x.s, &y.s)
+ return s
+}
+
+// Subtract sets s = x - y mod l, and returns s.
+func (s *Scalar) Subtract(x, y *Scalar) *Scalar {
+ // s = -1 * y + x mod l
+ fiatScalarSub(&s.s, &x.s, &y.s)
+ return s
+}
+
+// Negate sets s = -x mod l, and returns s.
+func (s *Scalar) Negate(x *Scalar) *Scalar {
+ // s = -1 * x + 0 mod l
+ fiatScalarOpp(&s.s, &x.s)
+ return s
+}
+
+// Multiply sets s = x * y mod l, and returns s.
+func (s *Scalar) Multiply(x, y *Scalar) *Scalar {
+ // s = x * y + 0 mod l
+ fiatScalarMul(&s.s, &x.s, &y.s)
+ return s
+}
+
+// Set sets s = x, and returns s.
+func (s *Scalar) Set(x *Scalar) *Scalar {
+ *s = *x
+ return s
+}
+
+// SetUniformBytes sets s = x mod l, where x is a 64-byte little-endian integer.
+// If x is not of the right length, SetUniformBytes returns nil and an error,
+// and the receiver is unchanged.
+//
+// SetUniformBytes can be used to set s to a uniformly distributed value given
+// 64 uniformly distributed random bytes.
+func (s *Scalar) SetUniformBytes(x []byte) (*Scalar, error) {
+ if len(x) != 64 {
+ return nil, errors.New("edwards25519: invalid SetUniformBytes input length")
+ }
+
+ // We have a value x of 512 bits, but our fiatScalarFromBytes function
+ // expects an input lower than l, which is a little over 252 bits.
+ //
+ // Instead of writing a reduction function that operates on wider inputs, we
+ // can interpret x as the sum of three shorter values a, b, and c.
+ //
+ // x = a + b * 2^168 + c * 2^336 mod l
+ //
+ // We then precompute 2^168 and 2^336 modulo l, and perform the reduction
+ // with two multiplications and two additions.
+
+ s.setShortBytes(x[:21])
+ t := new(Scalar).setShortBytes(x[21:42])
+ s.Add(s, t.Multiply(t, scalarTwo168))
+ t.setShortBytes(x[42:])
+ s.Add(s, t.Multiply(t, scalarTwo336))
+
+ return s, nil
+}
+
+// scalarTwo168 and scalarTwo336 are 2^168 and 2^336 modulo l, encoded as a
+// fiatScalarMontgomeryDomainFieldElement, which is a little-endian 4-limb value
+// in the 2^256 Montgomery domain.
+var scalarTwo168 = &Scalar{s: [4]uint64{0x5b8ab432eac74798, 0x38afddd6de59d5d7,
+ 0xa2c131b399411b7c, 0x6329a7ed9ce5a30}}
+var scalarTwo336 = &Scalar{s: [4]uint64{0xbd3d108e2b35ecc5, 0x5c3a3718bdf9c90b,
+ 0x63aa97a331b4f2ee, 0x3d217f5be65cb5c}}
+
+// setShortBytes sets s = x mod l, where x is a little-endian integer shorter
+// than 32 bytes.
+func (s *Scalar) setShortBytes(x []byte) *Scalar {
+ if len(x) >= 32 {
+ panic("edwards25519: internal error: setShortBytes called with a long string")
+ }
+ var buf [32]byte
+ copy(buf[:], x)
+ fiatScalarFromBytes((*[4]uint64)(&s.s), &buf)
+ fiatScalarToMontgomery(&s.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&s.s))
+ return s
+}
+
+// SetCanonicalBytes sets s = x, where x is a 32-byte little-endian encoding of
+// s, and returns s. If x is not a canonical encoding of s, SetCanonicalBytes
+// returns nil and an error, and the receiver is unchanged.
+func (s *Scalar) SetCanonicalBytes(x []byte) (*Scalar, error) {
+ if len(x) != 32 {
+ return nil, errors.New("invalid scalar length")
+ }
+ if !isReduced(x) {
+ return nil, errors.New("invalid scalar encoding")
+ }
+
+ fiatScalarFromBytes((*[4]uint64)(&s.s), (*[32]byte)(x))
+ fiatScalarToMontgomery(&s.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&s.s))
+
+ return s, nil
+}
+
+// scalarMinusOneBytes is l - 1 in little endian.
+var scalarMinusOneBytes = [32]byte{236, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16}
+
+// isReduced returns whether the given scalar in 32-byte little endian encoded
+// form is reduced modulo l.
+func isReduced(s []byte) bool {
+ if len(s) != 32 {
+ return false
+ }
+
+ for i := len(s) - 1; i >= 0; i-- {
+ switch {
+ case s[i] > scalarMinusOneBytes[i]:
+ return false
+ case s[i] < scalarMinusOneBytes[i]:
+ return true
+ }
+ }
+ return true
+}
+
+// SetBytesWithClamping applies the buffer pruning described in RFC 8032,
+// Section 5.1.5 (also known as clamping) and sets s to the result. The input
+// must be 32 bytes, and it is not modified. If x is not of the right length,
+// SetBytesWithClamping returns nil and an error, and the receiver is unchanged.
+//
+// Note that since Scalar values are always reduced modulo the prime order of
+// the curve, the resulting value will not preserve any of the cofactor-clearing
+// properties that clamping is meant to provide. It will however work as
+// expected as long as it is applied to points on the prime order subgroup, like
+// in Ed25519. In fact, it is lost to history why RFC 8032 adopted the
+// irrelevant RFC 7748 clamping, but it is now required for compatibility.
+func (s *Scalar) SetBytesWithClamping(x []byte) (*Scalar, error) {
+ // The description above omits the purpose of the high bits of the clamping
+ // for brevity, but those are also lost to reductions, and are also
+ // irrelevant to edwards25519 as they protect against a specific
+ // implementation bug that was once observed in a generic Montgomery ladder.
+ if len(x) != 32 {
+ return nil, errors.New("edwards25519: invalid SetBytesWithClamping input length")
+ }
+
+ // We need to use the wide reduction from SetUniformBytes, since clamping
+ // sets the 2^254 bit, making the value higher than the order.
+ var wideBytes [64]byte
+ copy(wideBytes[:], x[:])
+ wideBytes[0] &= 248
+ wideBytes[31] &= 63
+ wideBytes[31] |= 64
+ return s.SetUniformBytes(wideBytes[:])
+}
+
+// Bytes returns the canonical 32-byte little-endian encoding of s.
+func (s *Scalar) Bytes() []byte {
+ // This function is outlined to make the allocations inline in the caller
+ // rather than happen on the heap.
+ var encoded [32]byte
+ return s.bytes(&encoded)
+}
+
+func (s *Scalar) bytes(out *[32]byte) []byte {
+ var ss fiatScalarNonMontgomeryDomainFieldElement
+ fiatScalarFromMontgomery(&ss, &s.s)
+ fiatScalarToBytes(out, (*[4]uint64)(&ss))
+ return out[:]
+}
+
+// Equal returns 1 if s and t are equal, and 0 otherwise.
+func (s *Scalar) Equal(t *Scalar) int {
+ var diff fiatScalarMontgomeryDomainFieldElement
+ fiatScalarSub(&diff, &s.s, &t.s)
+ var nonzero uint64
+ fiatScalarNonzero(&nonzero, (*[4]uint64)(&diff))
+ nonzero |= nonzero >> 32
+ nonzero |= nonzero >> 16
+ nonzero |= nonzero >> 8
+ nonzero |= nonzero >> 4
+ nonzero |= nonzero >> 2
+ nonzero |= nonzero >> 1
+ return int(^nonzero) & 1
+}
+
+// nonAdjacentForm computes a width-w non-adjacent form for this scalar.
+//
+// w must be between 2 and 8, or nonAdjacentForm will panic.
+func (s *Scalar) nonAdjacentForm(w uint) [256]int8 {
+ // This implementation is adapted from the one
+ // in curve25519-dalek and is documented there:
+ // https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871
+ b := s.Bytes()
+ if b[31] > 127 {
+ panic("scalar has high bit set illegally")
+ }
+ if w < 2 {
+ panic("w must be at least 2 by the definition of NAF")
+ } else if w > 8 {
+ panic("NAF digits must fit in int8")
+ }
+
+ var naf [256]int8
+ var digits [5]uint64
+
+ for i := 0; i < 4; i++ {
+ digits[i] = binary.LittleEndian.Uint64(b[i*8:])
+ }
+
+ width := uint64(1 << w)
+ windowMask := uint64(width - 1)
+
+ pos := uint(0)
+ carry := uint64(0)
+ for pos < 256 {
+ indexU64 := pos / 64
+ indexBit := pos % 64
+ var bitBuf uint64
+ if indexBit < 64-w {
+ // This window's bits are contained in a single u64
+ bitBuf = digits[indexU64] >> indexBit
+ } else {
+ // Combine the current 64 bits with bits from the next 64
+ bitBuf = (digits[indexU64] >> indexBit) | (digits[1+indexU64] << (64 - indexBit))
+ }
+
+ // Add carry into the current window
+ window := carry + (bitBuf & windowMask)
+
+ if window&1 == 0 {
+ // If the window value is even, preserve the carry and continue.
+ // Why is the carry preserved?
+ // If carry == 0 and window & 1 == 0,
+ // then the next carry should be 0
+ // If carry == 1 and window & 1 == 0,
+ // then bit_buf & 1 == 1 so the next carry should be 1
+ pos += 1
+ continue
+ }
+
+ if window < width/2 {
+ carry = 0
+ naf[pos] = int8(window)
+ } else {
+ carry = 1
+ naf[pos] = int8(window) - int8(width)
+ }
+
+ pos += w
+ }
+ return naf
+}
+
+func (s *Scalar) signedRadix16() [64]int8 {
+ b := s.Bytes()
+ if b[31] > 127 {
+ panic("scalar has high bit set illegally")
+ }
+
+ var digits [64]int8
+
+ // Compute unsigned radix-16 digits:
+ for i := 0; i < 32; i++ {
+ digits[2*i] = int8(b[i] & 15)
+ digits[2*i+1] = int8((b[i] >> 4) & 15)
+ }
+
+ // Recenter coefficients:
+ for i := 0; i < 63; i++ {
+ carry := (digits[i] + 8) >> 4
+ digits[i] -= carry << 4
+ digits[i+1] += carry
+ }
+
+ return digits
+}
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/scalar_fiat.go b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/scalar_fiat.go
index 2e5782b605..2e5782b605 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/scalar_fiat.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/scalar_fiat.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/scalarmult.go b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/scalarmult.go
index f7ca3cef99..f7ca3cef99 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/scalarmult.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/scalarmult.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/tables.go b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/tables.go
index 83234bbc0f..83234bbc0f 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/edwards25519/tables.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/tables.go
diff --git a/contrib/go/_std_1.21/src/crypto/internal/edwards25519/ya.make b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/ya.make
new file mode 100644
index 0000000000..db3dacfdeb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/edwards25519/ya.make
@@ -0,0 +1,24 @@
+GO_LIBRARY()
+
+SRCS(
+ doc.go
+ edwards25519.go
+ scalar.go
+ scalar_fiat.go
+ scalarmult.go
+ tables.go
+)
+
+GO_TEST_SRCS(
+ edwards25519_test.go
+ scalar_alias_test.go
+ scalar_test.go
+ scalarmult_test.go
+ tables_test.go
+)
+
+END()
+
+RECURSE(
+ field
+)
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p224.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p224.go
index e1a78db33e..e1a78db33e 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p224.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p224.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p224_fiat64.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p224_fiat64.go
index 9337bfefef..9337bfefef 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p224_fiat64.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p224_fiat64.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p224_invert.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p224_invert.go
index 3cf528639f..3cf528639f 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p224_invert.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p224_invert.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p256.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p256.go
index 7705904ca1..7705904ca1 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p256.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p256.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p256_fiat64.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p256_fiat64.go
index 75352d5d26..75352d5d26 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p256_fiat64.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p256_fiat64.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p256_invert.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p256_invert.go
index d0101e1d4f..d0101e1d4f 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p256_invert.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p256_invert.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p384.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p384.go
index aed0c013c8..aed0c013c8 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p384.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p384.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p384_fiat64.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p384_fiat64.go
index 979eadd2df..979eadd2df 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p384_fiat64.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p384_fiat64.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p384_invert.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p384_invert.go
index 31591ac153..31591ac153 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p384_invert.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p384_invert.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p521.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p521.go
index 43ac7d06a0..43ac7d06a0 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p521.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p521.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p521_fiat64.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p521_fiat64.go
index 87a359e88e..87a359e88e 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p521_fiat64.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p521_fiat64.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p521_invert.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p521_invert.go
index 16c53e186d..16c53e186d 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/fiat/p521_invert.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/p521_invert.go
diff --git a/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/ya.make b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/ya.make
new file mode 100644
index 0000000000..4f2b792aa5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/fiat/ya.make
@@ -0,0 +1,23 @@
+GO_LIBRARY()
+
+SRCS(
+ p224.go
+ p224_fiat64.go
+ p224_invert.go
+ p256.go
+ p256_fiat64.go
+ p256_invert.go
+ p384.go
+ p384_fiat64.go
+ p384_invert.go
+ p521.go
+ p521_fiat64.go
+ p521_invert.go
+)
+
+GO_XTEST_SRCS(fiat_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/nistec.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/nistec.go
index d898d409ca..d898d409ca 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/nistec.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/nistec.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/p224.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/p224.go
index faa971d7ed..faa971d7ed 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/p224.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/p224.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/p224_sqrt.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/p224_sqrt.go
index 0c775790da..0c775790da 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/p224_sqrt.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/p224_sqrt.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/p256_asm.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/p256_asm.go
index 99a22b833f..99a22b833f 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/p256_asm.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/p256_asm.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/p256_asm_amd64.s b/contrib/go/_std_1.21/src/crypto/internal/nistec/p256_asm_amd64.s
index 84e4cee903..84e4cee903 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/p256_asm_amd64.s
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/p256_asm_amd64.s
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/p256_asm_arm64.s b/contrib/go/_std_1.21/src/crypto/internal/nistec/p256_asm_arm64.s
index 1ba5df381b..1ba5df381b 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/p256_asm_arm64.s
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/p256_asm_arm64.s
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/p256_asm_table.bin b/contrib/go/_std_1.21/src/crypto/internal/nistec/p256_asm_table.bin
index 20c527e4e0..20c527e4e0 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/p256_asm_table.bin
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/p256_asm_table.bin
Binary files differ
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/p256_ordinv.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/p256_ordinv.go
index 1274fb7fd3..1274fb7fd3 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/p256_ordinv.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/p256_ordinv.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/p384.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/p384.go
index b452ec9aea..b452ec9aea 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/p384.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/p384.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/nistec/p521.go b/contrib/go/_std_1.21/src/crypto/internal/nistec/p521.go
index a57ad24c4d..a57ad24c4d 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/nistec/p521.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/p521.go
diff --git a/contrib/go/_std_1.21/src/crypto/internal/nistec/ya.make b/contrib/go/_std_1.21/src/crypto/internal/nistec/ya.make
new file mode 100644
index 0000000000..90fcdd7c9e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/internal/nistec/ya.make
@@ -0,0 +1,38 @@
+GO_LIBRARY()
+
+SRCS(
+ nistec.go
+ p224.go
+ p224_sqrt.go
+ p256_asm.go
+ p256_ordinv.go
+ p384.go
+ p521.go
+)
+
+GO_TEST_SRCS(p256_asm_table_test.go)
+
+GO_XTEST_SRCS(
+ nistec_test.go
+ p256_ordinv_test.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ p256_asm_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ p256_asm_arm64.s
+ )
+ENDIF()
+
+GO_EMBED_PATTERN(p256_asm_table.bin)
+
+END()
+
+RECURSE(
+ fiat
+)
diff --git a/contrib/go/_std_1.20/src/crypto/internal/randutil/randutil.go b/contrib/go/_std_1.21/src/crypto/internal/randutil/randutil.go
index 84b1295a87..84b1295a87 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/randutil/randutil.go
+++ b/contrib/go/_std_1.21/src/crypto/internal/randutil/randutil.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/randutil/ya.make b/contrib/go/_std_1.21/src/crypto/internal/randutil/ya.make
index 070825d9f3..070825d9f3 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/randutil/ya.make
+++ b/contrib/go/_std_1.21/src/crypto/internal/randutil/ya.make
diff --git a/contrib/go/_std_1.20/src/crypto/internal/ya.make b/contrib/go/_std_1.21/src/crypto/internal/ya.make
index 72a1f578a2..72a1f578a2 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/ya.make
+++ b/contrib/go/_std_1.21/src/crypto/internal/ya.make
diff --git a/contrib/go/_std_1.20/src/crypto/md5/md5.go b/contrib/go/_std_1.21/src/crypto/md5/md5.go
index ccee4ea3a9..ccee4ea3a9 100644
--- a/contrib/go/_std_1.20/src/crypto/md5/md5.go
+++ b/contrib/go/_std_1.21/src/crypto/md5/md5.go
diff --git a/contrib/go/_std_1.20/src/crypto/md5/md5block.go b/contrib/go/_std_1.21/src/crypto/md5/md5block.go
index 4ff289e860..4ff289e860 100644
--- a/contrib/go/_std_1.20/src/crypto/md5/md5block.go
+++ b/contrib/go/_std_1.21/src/crypto/md5/md5block.go
diff --git a/contrib/go/_std_1.20/src/crypto/md5/md5block_amd64.s b/contrib/go/_std_1.21/src/crypto/md5/md5block_amd64.s
index 7c7d92d7e8..7c7d92d7e8 100644
--- a/contrib/go/_std_1.20/src/crypto/md5/md5block_amd64.s
+++ b/contrib/go/_std_1.21/src/crypto/md5/md5block_amd64.s
diff --git a/contrib/go/_std_1.20/src/crypto/md5/md5block_arm64.s b/contrib/go/_std_1.21/src/crypto/md5/md5block_arm64.s
index 39b9851d1f..39b9851d1f 100644
--- a/contrib/go/_std_1.20/src/crypto/md5/md5block_arm64.s
+++ b/contrib/go/_std_1.21/src/crypto/md5/md5block_arm64.s
diff --git a/contrib/go/_std_1.21/src/crypto/md5/md5block_decl.go b/contrib/go/_std_1.21/src/crypto/md5/md5block_decl.go
new file mode 100644
index 0000000000..f1fb34c3d7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/md5/md5block_decl.go
@@ -0,0 +1,12 @@
+// Copyright 2013 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.
+
+//go:build amd64 || 386 || arm || ppc64le || ppc64 || s390x || arm64
+
+package md5
+
+const haveAsm = true
+
+//go:noescape
+func block(dig *digest, p []byte)
diff --git a/contrib/go/_std_1.21/src/crypto/md5/ya.make b/contrib/go/_std_1.21/src/crypto/md5/ya.make
new file mode 100644
index 0000000000..b92b7a4931
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/md5/ya.make
@@ -0,0 +1,28 @@
+GO_LIBRARY()
+
+SRCS(
+ md5.go
+ md5block.go
+ md5block_decl.go
+)
+
+GO_TEST_SRCS(md5_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+IF (ARCH_X86_64)
+ SRCS(
+ md5block_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ md5block_arm64.s
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/crypto/rand/rand.go b/contrib/go/_std_1.21/src/crypto/rand/rand.go
new file mode 100644
index 0000000000..62738e2cb1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/rand/rand.go
@@ -0,0 +1,45 @@
+// Copyright 2010 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 rand implements a cryptographically secure
+// random number generator.
+package rand
+
+import "io"
+
+// Reader is a global, shared instance of a cryptographically
+// secure random number generator.
+//
+// On Linux, FreeBSD, Dragonfly, NetBSD and Solaris, Reader uses getrandom(2) if
+// available, /dev/urandom otherwise.
+// On OpenBSD and macOS, Reader uses getentropy(2).
+// On other Unix-like systems, Reader reads from /dev/urandom.
+// On Windows systems, Reader uses the RtlGenRandom API.
+// On JS/Wasm, Reader uses the Web Crypto API.
+// On WASIP1/Wasm, Reader uses random_get from wasi_snapshot_preview1.
+var Reader io.Reader
+
+// Read is a helper function that calls Reader.Read using io.ReadFull.
+// On return, n == len(b) if and only if err == nil.
+func Read(b []byte) (n int, err error) {
+ return io.ReadFull(Reader, b)
+}
+
+// batched returns a function that calls f to populate a []byte by chunking it
+// into subslices of, at most, readMax bytes.
+func batched(f func([]byte) error, readMax int) func([]byte) error {
+ return func(out []byte) error {
+ for len(out) > 0 {
+ read := len(out)
+ if read > readMax {
+ read = readMax
+ }
+ if err := f(out[:read]); err != nil {
+ return err
+ }
+ out = out[read:]
+ }
+ return nil
+ }
+}
diff --git a/contrib/go/_std_1.20/src/crypto/rand/rand_getentropy.go b/contrib/go/_std_1.21/src/crypto/rand/rand_getentropy.go
index 68f921b0fc..68f921b0fc 100644
--- a/contrib/go/_std_1.20/src/crypto/rand/rand_getentropy.go
+++ b/contrib/go/_std_1.21/src/crypto/rand/rand_getentropy.go
diff --git a/contrib/go/_std_1.21/src/crypto/rand/rand_getrandom.go b/contrib/go/_std_1.21/src/crypto/rand/rand_getrandom.go
new file mode 100644
index 0000000000..46c4133a73
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/rand/rand_getrandom.go
@@ -0,0 +1,48 @@
+// Copyright 2014 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.
+
+//go:build dragonfly || freebsd || linux || netbsd || solaris
+
+package rand
+
+import (
+ "internal/syscall/unix"
+ "runtime"
+ "syscall"
+)
+
+func init() {
+ var maxGetRandomRead int
+ switch runtime.GOOS {
+ case "linux", "android":
+ // Per the manpage:
+ // When reading from the urandom source, a maximum of 33554431 bytes
+ // is returned by a single call to getrandom() on systems where int
+ // has a size of 32 bits.
+ maxGetRandomRead = (1 << 25) - 1
+ case "dragonfly", "freebsd", "illumos", "netbsd", "solaris":
+ maxGetRandomRead = 1 << 8
+ default:
+ panic("no maximum specified for GetRandom")
+ }
+ altGetRandom = batched(getRandom, maxGetRandomRead)
+}
+
+// If the kernel is too old to support the getrandom syscall(),
+// unix.GetRandom will immediately return ENOSYS and we will then fall back to
+// reading from /dev/urandom in rand_unix.go. unix.GetRandom caches the ENOSYS
+// result so we only suffer the syscall overhead once in this case.
+// If the kernel supports the getrandom() syscall, unix.GetRandom will block
+// until the kernel has sufficient randomness (as we don't use GRND_NONBLOCK).
+// In this case, unix.GetRandom will not return an error.
+func getRandom(p []byte) error {
+ n, err := unix.GetRandom(p, 0)
+ if err != nil {
+ return err
+ }
+ if n != len(p) {
+ return syscall.EIO
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.20/src/crypto/rand/rand_unix.go b/contrib/go/_std_1.21/src/crypto/rand/rand_unix.go
index 40fce36314..40fce36314 100644
--- a/contrib/go/_std_1.20/src/crypto/rand/rand_unix.go
+++ b/contrib/go/_std_1.21/src/crypto/rand/rand_unix.go
diff --git a/contrib/go/_std_1.20/src/crypto/rand/rand_windows.go b/contrib/go/_std_1.21/src/crypto/rand/rand_windows.go
index 6c0655c72b..6c0655c72b 100644
--- a/contrib/go/_std_1.20/src/crypto/rand/rand_windows.go
+++ b/contrib/go/_std_1.21/src/crypto/rand/rand_windows.go
diff --git a/contrib/go/_std_1.20/src/crypto/rand/util.go b/contrib/go/_std_1.21/src/crypto/rand/util.go
index 11b1a28ec5..11b1a28ec5 100644
--- a/contrib/go/_std_1.20/src/crypto/rand/util.go
+++ b/contrib/go/_std_1.21/src/crypto/rand/util.go
diff --git a/contrib/go/_std_1.21/src/crypto/rand/ya.make b/contrib/go/_std_1.21/src/crypto/rand/ya.make
new file mode 100644
index 0000000000..d3eb5da2ba
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/rand/ya.make
@@ -0,0 +1,42 @@
+GO_LIBRARY()
+
+SRCS(
+ rand.go
+ util.go
+)
+
+GO_TEST_SRCS(rand_test.go)
+
+GO_XTEST_SRCS(
+ example_test.go
+ util_test.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ rand_getrandom.go
+ rand_unix.go
+ )
+
+ GO_TEST_SRCS(rand_batched_test.go)
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ rand_getentropy.go
+ rand_unix.go
+ )
+
+ GO_TEST_SRCS(rand_batched_test.go)
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ rand_windows.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/rc4/rc4.go b/contrib/go/_std_1.21/src/crypto/rc4/rc4.go
index f08da0e469..f08da0e469 100644
--- a/contrib/go/_std_1.20/src/crypto/rc4/rc4.go
+++ b/contrib/go/_std_1.21/src/crypto/rc4/rc4.go
diff --git a/contrib/go/_std_1.21/src/crypto/rc4/ya.make b/contrib/go/_std_1.21/src/crypto/rc4/ya.make
new file mode 100644
index 0000000000..4cde397aaa
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/rc4/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ rc4.go
+)
+
+GO_TEST_SRCS(rc4_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/rsa/notboring.go b/contrib/go/_std_1.21/src/crypto/rsa/notboring.go
index 2abc043640..2abc043640 100644
--- a/contrib/go/_std_1.20/src/crypto/rsa/notboring.go
+++ b/contrib/go/_std_1.21/src/crypto/rsa/notboring.go
diff --git a/contrib/go/_std_1.21/src/crypto/rsa/pkcs1v15.go b/contrib/go/_std_1.21/src/crypto/rsa/pkcs1v15.go
new file mode 100644
index 0000000000..55fea1ab93
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/rsa/pkcs1v15.go
@@ -0,0 +1,393 @@
+// Copyright 2009 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 rsa
+
+import (
+ "crypto"
+ "crypto/internal/boring"
+ "crypto/internal/randutil"
+ "crypto/subtle"
+ "errors"
+ "io"
+)
+
+// This file implements encryption and decryption using PKCS #1 v1.5 padding.
+
+// PKCS1v15DecryptOptions is for passing options to PKCS #1 v1.5 decryption using
+// the crypto.Decrypter interface.
+type PKCS1v15DecryptOptions struct {
+ // SessionKeyLen is the length of the session key that is being
+ // decrypted. If not zero, then a padding error during decryption will
+ // cause a random plaintext of this length to be returned rather than
+ // an error. These alternatives happen in constant time.
+ SessionKeyLen int
+}
+
+// EncryptPKCS1v15 encrypts the given message with RSA and the padding
+// scheme from PKCS #1 v1.5. The message must be no longer than the
+// length of the public modulus minus 11 bytes.
+//
+// The random parameter is used as a source of entropy to ensure that
+// encrypting the same message twice doesn't result in the same
+// ciphertext. Most applications should use [crypto/rand.Reader]
+// as random. Note that the returned ciphertext does not depend
+// deterministically on the bytes read from random, and may change
+// between calls and/or between versions.
+//
+// WARNING: use of this function to encrypt plaintexts other than
+// session keys is dangerous. Use RSA OAEP in new protocols.
+func EncryptPKCS1v15(random io.Reader, pub *PublicKey, msg []byte) ([]byte, error) {
+ randutil.MaybeReadByte(random)
+
+ if err := checkPub(pub); err != nil {
+ return nil, err
+ }
+ k := pub.Size()
+ if len(msg) > k-11 {
+ return nil, ErrMessageTooLong
+ }
+
+ if boring.Enabled && random == boring.RandReader {
+ bkey, err := boringPublicKey(pub)
+ if err != nil {
+ return nil, err
+ }
+ return boring.EncryptRSAPKCS1(bkey, msg)
+ }
+ boring.UnreachableExceptTests()
+
+ // EM = 0x00 || 0x02 || PS || 0x00 || M
+ em := make([]byte, k)
+ em[1] = 2
+ ps, mm := em[2:len(em)-len(msg)-1], em[len(em)-len(msg):]
+ err := nonZeroRandomBytes(ps, random)
+ if err != nil {
+ return nil, err
+ }
+ em[len(em)-len(msg)-1] = 0
+ copy(mm, msg)
+
+ if boring.Enabled {
+ var bkey *boring.PublicKeyRSA
+ bkey, err = boringPublicKey(pub)
+ if err != nil {
+ return nil, err
+ }
+ return boring.EncryptRSANoPadding(bkey, em)
+ }
+
+ return encrypt(pub, em)
+}
+
+// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS #1 v1.5.
+// The random parameter is legacy and ignored, and it can be nil.
+//
+// Note that whether this function returns an error or not discloses secret
+// information. If an attacker can cause this function to run repeatedly and
+// learn whether each instance returned an error then they can decrypt and
+// forge signatures as if they had the private key. See
+// DecryptPKCS1v15SessionKey for a way of solving this problem.
+func DecryptPKCS1v15(random io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error) {
+ if err := checkPub(&priv.PublicKey); err != nil {
+ return nil, err
+ }
+
+ if boring.Enabled {
+ bkey, err := boringPrivateKey(priv)
+ if err != nil {
+ return nil, err
+ }
+ out, err := boring.DecryptRSAPKCS1(bkey, ciphertext)
+ if err != nil {
+ return nil, ErrDecryption
+ }
+ return out, nil
+ }
+
+ valid, out, index, err := decryptPKCS1v15(priv, ciphertext)
+ if err != nil {
+ return nil, err
+ }
+ if valid == 0 {
+ return nil, ErrDecryption
+ }
+ return out[index:], nil
+}
+
+// DecryptPKCS1v15SessionKey decrypts a session key using RSA and the padding
+// scheme from PKCS #1 v1.5. The random parameter is legacy and ignored, and it
+// can be nil.
+//
+// DecryptPKCS1v15SessionKey returns an error if the ciphertext is the wrong
+// length or if the ciphertext is greater than the public modulus. Otherwise, no
+// error is returned. If the padding is valid, the resulting plaintext message
+// is copied into key. Otherwise, key is unchanged. These alternatives occur in
+// constant time. It is intended that the user of this function generate a
+// random session key beforehand and continue the protocol with the resulting
+// value.
+//
+// Note that if the session key is too small then it may be possible for an
+// attacker to brute-force it. If they can do that then they can learn whether a
+// random value was used (because it'll be different for the same ciphertext)
+// and thus whether the padding was correct. This also defeats the point of this
+// function. Using at least a 16-byte key will protect against this attack.
+//
+// This method implements protections against Bleichenbacher chosen ciphertext
+// attacks [0] described in RFC 3218 Section 2.3.2 [1]. While these protections
+// make a Bleichenbacher attack significantly more difficult, the protections
+// are only effective if the rest of the protocol which uses
+// DecryptPKCS1v15SessionKey is designed with these considerations in mind. In
+// particular, if any subsequent operations which use the decrypted session key
+// leak any information about the key (e.g. whether it is a static or random
+// key) then the mitigations are defeated. This method must be used extremely
+// carefully, and typically should only be used when absolutely necessary for
+// compatibility with an existing protocol (such as TLS) that is designed with
+// these properties in mind.
+//
+// - [0] “Chosen Ciphertext Attacks Against Protocols Based on the RSA Encryption
+// Standard PKCS #1”, Daniel Bleichenbacher, Advances in Cryptology (Crypto '98)
+// - [1] RFC 3218, Preventing the Million Message Attack on CMS,
+// https://www.rfc-editor.org/rfc/rfc3218.html
+func DecryptPKCS1v15SessionKey(random io.Reader, priv *PrivateKey, ciphertext []byte, key []byte) error {
+ if err := checkPub(&priv.PublicKey); err != nil {
+ return err
+ }
+ k := priv.Size()
+ if k-(len(key)+3+8) < 0 {
+ return ErrDecryption
+ }
+
+ valid, em, index, err := decryptPKCS1v15(priv, ciphertext)
+ if err != nil {
+ return err
+ }
+
+ if len(em) != k {
+ // This should be impossible because decryptPKCS1v15 always
+ // returns the full slice.
+ return ErrDecryption
+ }
+
+ valid &= subtle.ConstantTimeEq(int32(len(em)-index), int32(len(key)))
+ subtle.ConstantTimeCopy(valid, key, em[len(em)-len(key):])
+ return nil
+}
+
+// decryptPKCS1v15 decrypts ciphertext using priv. It returns one or zero in
+// valid that indicates whether the plaintext was correctly structured.
+// In either case, the plaintext is returned in em so that it may be read
+// independently of whether it was valid in order to maintain constant memory
+// access patterns. If the plaintext was valid then index contains the index of
+// the original message in em, to allow constant time padding removal.
+func decryptPKCS1v15(priv *PrivateKey, ciphertext []byte) (valid int, em []byte, index int, err error) {
+ k := priv.Size()
+ if k < 11 {
+ err = ErrDecryption
+ return
+ }
+
+ if boring.Enabled {
+ var bkey *boring.PrivateKeyRSA
+ bkey, err = boringPrivateKey(priv)
+ if err != nil {
+ return
+ }
+ em, err = boring.DecryptRSANoPadding(bkey, ciphertext)
+ if err != nil {
+ return
+ }
+ } else {
+ em, err = decrypt(priv, ciphertext, noCheck)
+ if err != nil {
+ return
+ }
+ }
+
+ firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
+ secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2)
+
+ // The remainder of the plaintext must be a string of non-zero random
+ // octets, followed by a 0, followed by the message.
+ // lookingForIndex: 1 iff we are still looking for the zero.
+ // index: the offset of the first zero byte.
+ lookingForIndex := 1
+
+ for i := 2; i < len(em); i++ {
+ equals0 := subtle.ConstantTimeByteEq(em[i], 0)
+ index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
+ lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
+ }
+
+ // The PS padding must be at least 8 bytes long, and it starts two
+ // bytes into em.
+ validPS := subtle.ConstantTimeLessOrEq(2+8, index)
+
+ valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & validPS
+ index = subtle.ConstantTimeSelect(valid, index+1, 0)
+ return valid, em, index, nil
+}
+
+// nonZeroRandomBytes fills the given slice with non-zero random octets.
+func nonZeroRandomBytes(s []byte, random io.Reader) (err error) {
+ _, err = io.ReadFull(random, s)
+ if err != nil {
+ return
+ }
+
+ for i := 0; i < len(s); i++ {
+ for s[i] == 0 {
+ _, err = io.ReadFull(random, s[i:i+1])
+ if err != nil {
+ return
+ }
+ // In tests, the PRNG may return all zeros so we do
+ // this to break the loop.
+ s[i] ^= 0x42
+ }
+ }
+
+ return
+}
+
+// These are ASN1 DER structures:
+//
+// DigestInfo ::= SEQUENCE {
+// digestAlgorithm AlgorithmIdentifier,
+// digest OCTET STRING
+// }
+//
+// For performance, we don't use the generic ASN1 encoder. Rather, we
+// precompute a prefix of the digest value that makes a valid ASN1 DER string
+// with the correct contents.
+var hashPrefixes = map[crypto.Hash][]byte{
+ crypto.MD5: {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
+ crypto.SHA1: {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
+ crypto.SHA224: {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
+ crypto.SHA256: {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
+ crypto.SHA384: {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
+ crypto.SHA512: {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
+ crypto.MD5SHA1: {}, // A special TLS case which doesn't use an ASN1 prefix.
+ crypto.RIPEMD160: {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
+}
+
+// SignPKCS1v15 calculates the signature of hashed using
+// RSASSA-PKCS1-V1_5-SIGN from RSA PKCS #1 v1.5. Note that hashed must
+// be the result of hashing the input message using the given hash
+// function. If hash is zero, hashed is signed directly. This isn't
+// advisable except for interoperability.
+//
+// The random parameter is legacy and ignored, and it can be nil.
+//
+// This function is deterministic. Thus, if the set of possible
+// messages is small, an attacker may be able to build a map from
+// messages to signatures and identify the signed messages. As ever,
+// signatures provide authenticity, not confidentiality.
+func SignPKCS1v15(random io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error) {
+ hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
+ if err != nil {
+ return nil, err
+ }
+
+ tLen := len(prefix) + hashLen
+ k := priv.Size()
+ if k < tLen+11 {
+ return nil, ErrMessageTooLong
+ }
+
+ if boring.Enabled {
+ bkey, err := boringPrivateKey(priv)
+ if err != nil {
+ return nil, err
+ }
+ return boring.SignRSAPKCS1v15(bkey, hash, hashed)
+ }
+
+ // EM = 0x00 || 0x01 || PS || 0x00 || T
+ em := make([]byte, k)
+ em[1] = 1
+ for i := 2; i < k-tLen-1; i++ {
+ em[i] = 0xff
+ }
+ copy(em[k-tLen:k-hashLen], prefix)
+ copy(em[k-hashLen:k], hashed)
+
+ return decrypt(priv, em, withCheck)
+}
+
+// VerifyPKCS1v15 verifies an RSA PKCS #1 v1.5 signature.
+// hashed is the result of hashing the input message using the given hash
+// function and sig is the signature. A valid signature is indicated by
+// returning a nil error. If hash is zero then hashed is used directly. This
+// isn't advisable except for interoperability.
+func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error {
+ if boring.Enabled {
+ bkey, err := boringPublicKey(pub)
+ if err != nil {
+ return err
+ }
+ if err := boring.VerifyRSAPKCS1v15(bkey, hash, hashed, sig); err != nil {
+ return ErrVerification
+ }
+ return nil
+ }
+
+ hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
+ if err != nil {
+ return err
+ }
+
+ tLen := len(prefix) + hashLen
+ k := pub.Size()
+ if k < tLen+11 {
+ return ErrVerification
+ }
+
+ // RFC 8017 Section 8.2.2: If the length of the signature S is not k
+ // octets (where k is the length in octets of the RSA modulus n), output
+ // "invalid signature" and stop.
+ if k != len(sig) {
+ return ErrVerification
+ }
+
+ em, err := encrypt(pub, sig)
+ if err != nil {
+ return ErrVerification
+ }
+ // EM = 0x00 || 0x01 || PS || 0x00 || T
+
+ ok := subtle.ConstantTimeByteEq(em[0], 0)
+ ok &= subtle.ConstantTimeByteEq(em[1], 1)
+ ok &= subtle.ConstantTimeCompare(em[k-hashLen:k], hashed)
+ ok &= subtle.ConstantTimeCompare(em[k-tLen:k-hashLen], prefix)
+ ok &= subtle.ConstantTimeByteEq(em[k-tLen-1], 0)
+
+ for i := 2; i < k-tLen-1; i++ {
+ ok &= subtle.ConstantTimeByteEq(em[i], 0xff)
+ }
+
+ if ok != 1 {
+ return ErrVerification
+ }
+
+ return nil
+}
+
+func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte, err error) {
+ // Special case: crypto.Hash(0) is used to indicate that the data is
+ // signed directly.
+ if hash == 0 {
+ return inLen, nil, nil
+ }
+
+ hashLen = hash.Size()
+ if inLen != hashLen {
+ return 0, nil, errors.New("crypto/rsa: input must be hashed message")
+ }
+ prefix, ok := hashPrefixes[hash]
+ if !ok {
+ return 0, nil, errors.New("crypto/rsa: unsupported hash function")
+ }
+ return
+}
diff --git a/contrib/go/_std_1.21/src/crypto/rsa/pss.go b/contrib/go/_std_1.21/src/crypto/rsa/pss.go
new file mode 100644
index 0000000000..3a377cc9db
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/rsa/pss.go
@@ -0,0 +1,382 @@
+// Copyright 2013 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 rsa
+
+// This file implements the RSASSA-PSS signature scheme according to RFC 8017.
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/internal/boring"
+ "errors"
+ "hash"
+ "io"
+)
+
+// Per RFC 8017, Section 9.1
+//
+// EM = MGF1 xor DB || H( 8*0x00 || mHash || salt ) || 0xbc
+//
+// where
+//
+// DB = PS || 0x01 || salt
+//
+// and PS can be empty so
+//
+// emLen = dbLen + hLen + 1 = psLen + sLen + hLen + 2
+//
+
+func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byte, error) {
+ // See RFC 8017, Section 9.1.1.
+
+ hLen := hash.Size()
+ sLen := len(salt)
+ emLen := (emBits + 7) / 8
+
+ // 1. If the length of M is greater than the input limitation for the
+ // hash function (2^61 - 1 octets for SHA-1), output "message too
+ // long" and stop.
+ //
+ // 2. Let mHash = Hash(M), an octet string of length hLen.
+
+ if len(mHash) != hLen {
+ return nil, errors.New("crypto/rsa: input must be hashed with given hash")
+ }
+
+ // 3. If emLen < hLen + sLen + 2, output "encoding error" and stop.
+
+ if emLen < hLen+sLen+2 {
+ return nil, ErrMessageTooLong
+ }
+
+ em := make([]byte, emLen)
+ psLen := emLen - sLen - hLen - 2
+ db := em[:psLen+1+sLen]
+ h := em[psLen+1+sLen : emLen-1]
+
+ // 4. Generate a random octet string salt of length sLen; if sLen = 0,
+ // then salt is the empty string.
+ //
+ // 5. Let
+ // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt;
+ //
+ // M' is an octet string of length 8 + hLen + sLen with eight
+ // initial zero octets.
+ //
+ // 6. Let H = Hash(M'), an octet string of length hLen.
+
+ var prefix [8]byte
+
+ hash.Write(prefix[:])
+ hash.Write(mHash)
+ hash.Write(salt)
+
+ h = hash.Sum(h[:0])
+ hash.Reset()
+
+ // 7. Generate an octet string PS consisting of emLen - sLen - hLen - 2
+ // zero octets. The length of PS may be 0.
+ //
+ // 8. Let DB = PS || 0x01 || salt; DB is an octet string of length
+ // emLen - hLen - 1.
+
+ db[psLen] = 0x01
+ copy(db[psLen+1:], salt)
+
+ // 9. Let dbMask = MGF(H, emLen - hLen - 1).
+ //
+ // 10. Let maskedDB = DB \xor dbMask.
+
+ mgf1XOR(db, hash, h)
+
+ // 11. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in
+ // maskedDB to zero.
+
+ db[0] &= 0xff >> (8*emLen - emBits)
+
+ // 12. Let EM = maskedDB || H || 0xbc.
+ em[emLen-1] = 0xbc
+
+ // 13. Output EM.
+ return em, nil
+}
+
+func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error {
+ // See RFC 8017, Section 9.1.2.
+
+ hLen := hash.Size()
+ if sLen == PSSSaltLengthEqualsHash {
+ sLen = hLen
+ }
+ emLen := (emBits + 7) / 8
+ if emLen != len(em) {
+ return errors.New("rsa: internal error: inconsistent length")
+ }
+
+ // 1. If the length of M is greater than the input limitation for the
+ // hash function (2^61 - 1 octets for SHA-1), output "inconsistent"
+ // and stop.
+ //
+ // 2. Let mHash = Hash(M), an octet string of length hLen.
+ if hLen != len(mHash) {
+ return ErrVerification
+ }
+
+ // 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop.
+ if emLen < hLen+sLen+2 {
+ return ErrVerification
+ }
+
+ // 4. If the rightmost octet of EM does not have hexadecimal value
+ // 0xbc, output "inconsistent" and stop.
+ if em[emLen-1] != 0xbc {
+ return ErrVerification
+ }
+
+ // 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and
+ // let H be the next hLen octets.
+ db := em[:emLen-hLen-1]
+ h := em[emLen-hLen-1 : emLen-1]
+
+ // 6. If the leftmost 8 * emLen - emBits bits of the leftmost octet in
+ // maskedDB are not all equal to zero, output "inconsistent" and
+ // stop.
+ var bitMask byte = 0xff >> (8*emLen - emBits)
+ if em[0] & ^bitMask != 0 {
+ return ErrVerification
+ }
+
+ // 7. Let dbMask = MGF(H, emLen - hLen - 1).
+ //
+ // 8. Let DB = maskedDB \xor dbMask.
+ mgf1XOR(db, hash, h)
+
+ // 9. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in DB
+ // to zero.
+ db[0] &= bitMask
+
+ // If we don't know the salt length, look for the 0x01 delimiter.
+ if sLen == PSSSaltLengthAuto {
+ psLen := bytes.IndexByte(db, 0x01)
+ if psLen < 0 {
+ return ErrVerification
+ }
+ sLen = len(db) - psLen - 1
+ }
+
+ // 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
+ // or if the octet at position emLen - hLen - sLen - 1 (the leftmost
+ // position is "position 1") does not have hexadecimal value 0x01,
+ // output "inconsistent" and stop.
+ psLen := emLen - hLen - sLen - 2
+ for _, e := range db[:psLen] {
+ if e != 0x00 {
+ return ErrVerification
+ }
+ }
+ if db[psLen] != 0x01 {
+ return ErrVerification
+ }
+
+ // 11. Let salt be the last sLen octets of DB.
+ salt := db[len(db)-sLen:]
+
+ // 12. Let
+ // M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ;
+ // M' is an octet string of length 8 + hLen + sLen with eight
+ // initial zero octets.
+ //
+ // 13. Let H' = Hash(M'), an octet string of length hLen.
+ var prefix [8]byte
+ hash.Write(prefix[:])
+ hash.Write(mHash)
+ hash.Write(salt)
+
+ h0 := hash.Sum(nil)
+
+ // 14. If H = H', output "consistent." Otherwise, output "inconsistent."
+ if !bytes.Equal(h0, h) { // TODO: constant time?
+ return ErrVerification
+ }
+ return nil
+}
+
+// signPSSWithSalt calculates the signature of hashed using PSS with specified salt.
+// Note that hashed must be the result of hashing the input message using the
+// given hash function. salt is a random sequence of bytes whose length will be
+// later used to verify the signature.
+func signPSSWithSalt(priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) ([]byte, error) {
+ emBits := priv.N.BitLen() - 1
+ em, err := emsaPSSEncode(hashed, emBits, salt, hash.New())
+ if err != nil {
+ return nil, err
+ }
+
+ if boring.Enabled {
+ bkey, err := boringPrivateKey(priv)
+ if err != nil {
+ return nil, err
+ }
+ // Note: BoringCrypto always does decrypt "withCheck".
+ // (It's not just decrypt.)
+ s, err := boring.DecryptRSANoPadding(bkey, em)
+ if err != nil {
+ return nil, err
+ }
+ return s, nil
+ }
+
+ // RFC 8017: "Note that the octet length of EM will be one less than k if
+ // modBits - 1 is divisible by 8 and equal to k otherwise, where k is the
+ // length in octets of the RSA modulus n." 🙄
+ //
+ // This is extremely annoying, as all other encrypt and decrypt inputs are
+ // always the exact same size as the modulus. Since it only happens for
+ // weird modulus sizes, fix it by padding inefficiently.
+ if emLen, k := len(em), priv.Size(); emLen < k {
+ emNew := make([]byte, k)
+ copy(emNew[k-emLen:], em)
+ em = emNew
+ }
+
+ return decrypt(priv, em, withCheck)
+}
+
+const (
+ // PSSSaltLengthAuto causes the salt in a PSS signature to be as large
+ // as possible when signing, and to be auto-detected when verifying.
+ PSSSaltLengthAuto = 0
+ // PSSSaltLengthEqualsHash causes the salt length to equal the length
+ // of the hash used in the signature.
+ PSSSaltLengthEqualsHash = -1
+)
+
+// PSSOptions contains options for creating and verifying PSS signatures.
+type PSSOptions struct {
+ // SaltLength controls the length of the salt used in the PSS signature. It
+ // can either be a positive number of bytes, or one of the special
+ // PSSSaltLength constants.
+ SaltLength int
+
+ // Hash is the hash function used to generate the message digest. If not
+ // zero, it overrides the hash function passed to SignPSS. It's required
+ // when using PrivateKey.Sign.
+ Hash crypto.Hash
+}
+
+// HashFunc returns opts.Hash so that PSSOptions implements crypto.SignerOpts.
+func (opts *PSSOptions) HashFunc() crypto.Hash {
+ return opts.Hash
+}
+
+func (opts *PSSOptions) saltLength() int {
+ if opts == nil {
+ return PSSSaltLengthAuto
+ }
+ return opts.SaltLength
+}
+
+var invalidSaltLenErr = errors.New("crypto/rsa: PSSOptions.SaltLength cannot be negative")
+
+// SignPSS calculates the signature of digest using PSS.
+//
+// digest must be the result of hashing the input message using the given hash
+// function. The opts argument may be nil, in which case sensible defaults are
+// used. If opts.Hash is set, it overrides hash.
+//
+// The signature is randomized depending on the message, key, and salt size,
+// using bytes from rand. Most applications should use [crypto/rand.Reader] as
+// rand.
+func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, opts *PSSOptions) ([]byte, error) {
+ // Note that while we don't commit to deterministic execution with respect
+ // to the rand stream, we also don't apply MaybeReadByte, so per Hyrum's Law
+ // it's probably relied upon by some. It's a tolerable promise because a
+ // well-specified number of random bytes is included in the signature, in a
+ // well-specified way.
+
+ if boring.Enabled && rand == boring.RandReader {
+ bkey, err := boringPrivateKey(priv)
+ if err != nil {
+ return nil, err
+ }
+ return boring.SignRSAPSS(bkey, hash, digest, opts.saltLength())
+ }
+ boring.UnreachableExceptTests()
+
+ if opts != nil && opts.Hash != 0 {
+ hash = opts.Hash
+ }
+
+ saltLength := opts.saltLength()
+ switch saltLength {
+ case PSSSaltLengthAuto:
+ saltLength = (priv.N.BitLen()-1+7)/8 - 2 - hash.Size()
+ if saltLength < 0 {
+ return nil, ErrMessageTooLong
+ }
+ case PSSSaltLengthEqualsHash:
+ saltLength = hash.Size()
+ default:
+ // If we get here saltLength is either > 0 or < -1, in the
+ // latter case we fail out.
+ if saltLength <= 0 {
+ return nil, invalidSaltLenErr
+ }
+ }
+ salt := make([]byte, saltLength)
+ if _, err := io.ReadFull(rand, salt); err != nil {
+ return nil, err
+ }
+ return signPSSWithSalt(priv, hash, digest, salt)
+}
+
+// VerifyPSS verifies a PSS signature.
+//
+// A valid signature is indicated by returning a nil error. digest must be the
+// result of hashing the input message using the given hash function. The opts
+// argument may be nil, in which case sensible defaults are used. opts.Hash is
+// ignored.
+func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *PSSOptions) error {
+ if boring.Enabled {
+ bkey, err := boringPublicKey(pub)
+ if err != nil {
+ return err
+ }
+ if err := boring.VerifyRSAPSS(bkey, hash, digest, sig, opts.saltLength()); err != nil {
+ return ErrVerification
+ }
+ return nil
+ }
+ if len(sig) != pub.Size() {
+ return ErrVerification
+ }
+ // Salt length must be either one of the special constants (-1 or 0)
+ // or otherwise positive. If it is < PSSSaltLengthEqualsHash (-1)
+ // we return an error.
+ if opts.saltLength() < PSSSaltLengthEqualsHash {
+ return invalidSaltLenErr
+ }
+
+ emBits := pub.N.BitLen() - 1
+ emLen := (emBits + 7) / 8
+ em, err := encrypt(pub, sig)
+ if err != nil {
+ return ErrVerification
+ }
+
+ // Like in signPSSWithSalt, deal with mismatches between emLen and the size
+ // of the modulus. The spec would have us wire emLen into the encoding
+ // function, but we'd rather always encode to the size of the modulus and
+ // then strip leading zeroes if necessary. This only happens for weird
+ // modulus sizes anyway.
+ for len(em) > emLen && len(em) > 0 {
+ if em[0] != 0 {
+ return ErrVerification
+ }
+ em = em[1:]
+ }
+
+ return emsaPSSVerify(digest, em, emBits, opts.saltLength(), hash.New())
+}
diff --git a/contrib/go/_std_1.21/src/crypto/rsa/rsa.go b/contrib/go/_std_1.21/src/crypto/rsa/rsa.go
new file mode 100644
index 0000000000..f0aef1f542
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/rsa/rsa.go
@@ -0,0 +1,781 @@
+// Copyright 2009 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 rsa implements RSA encryption as specified in PKCS #1 and RFC 8017.
+//
+// RSA is a single, fundamental operation that is used in this package to
+// implement either public-key encryption or public-key signatures.
+//
+// The original specification for encryption and signatures with RSA is PKCS #1
+// and the terms "RSA encryption" and "RSA signatures" by default refer to
+// PKCS #1 version 1.5. However, that specification has flaws and new designs
+// should use version 2, usually called by just OAEP and PSS, where
+// possible.
+//
+// Two sets of interfaces are included in this package. When a more abstract
+// interface isn't necessary, there are functions for encrypting/decrypting
+// with v1.5/OAEP and signing/verifying with v1.5/PSS. If one needs to abstract
+// over the public key primitive, the PrivateKey type implements the
+// Decrypter and Signer interfaces from the crypto package.
+//
+// Operations in this package are implemented using constant-time algorithms,
+// except for [GenerateKey], [PrivateKey.Precompute], and [PrivateKey.Validate].
+// Every other operation only leaks the bit size of the involved values, which
+// all depend on the selected key size.
+package rsa
+
+import (
+ "crypto"
+ "crypto/internal/bigmod"
+ "crypto/internal/boring"
+ "crypto/internal/boring/bbig"
+ "crypto/internal/randutil"
+ "crypto/rand"
+ "crypto/subtle"
+ "errors"
+ "hash"
+ "io"
+ "math"
+ "math/big"
+)
+
+var bigOne = big.NewInt(1)
+
+// A PublicKey represents the public part of an RSA key.
+type PublicKey struct {
+ N *big.Int // modulus
+ E int // public exponent
+}
+
+// Any methods implemented on PublicKey might need to also be implemented on
+// PrivateKey, as the latter embeds the former and will expose its methods.
+
+// Size returns the modulus size in bytes. Raw signatures and ciphertexts
+// for or by this public key will have the same size.
+func (pub *PublicKey) Size() int {
+ return (pub.N.BitLen() + 7) / 8
+}
+
+// Equal reports whether pub and x have the same value.
+func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
+ xx, ok := x.(*PublicKey)
+ if !ok {
+ return false
+ }
+ return bigIntEqual(pub.N, xx.N) && pub.E == xx.E
+}
+
+// OAEPOptions is an interface for passing options to OAEP decryption using the
+// crypto.Decrypter interface.
+type OAEPOptions struct {
+ // Hash is the hash function that will be used when generating the mask.
+ Hash crypto.Hash
+
+ // MGFHash is the hash function used for MGF1.
+ // If zero, Hash is used instead.
+ MGFHash crypto.Hash
+
+ // Label is an arbitrary byte string that must be equal to the value
+ // used when encrypting.
+ Label []byte
+}
+
+var (
+ errPublicModulus = errors.New("crypto/rsa: missing public modulus")
+ errPublicExponentSmall = errors.New("crypto/rsa: public exponent too small")
+ errPublicExponentLarge = errors.New("crypto/rsa: public exponent too large")
+)
+
+// checkPub sanity checks the public key before we use it.
+// We require pub.E to fit into a 32-bit integer so that we
+// do not have different behavior depending on whether
+// int is 32 or 64 bits. See also
+// https://www.imperialviolet.org/2012/03/16/rsae.html.
+func checkPub(pub *PublicKey) error {
+ if pub.N == nil {
+ return errPublicModulus
+ }
+ if pub.E < 2 {
+ return errPublicExponentSmall
+ }
+ if pub.E > 1<<31-1 {
+ return errPublicExponentLarge
+ }
+ return nil
+}
+
+// A PrivateKey represents an RSA key
+type PrivateKey struct {
+ PublicKey // public part.
+ D *big.Int // private exponent
+ Primes []*big.Int // prime factors of N, has >= 2 elements.
+
+ // Precomputed contains precomputed values that speed up RSA operations,
+ // if available. It must be generated by calling PrivateKey.Precompute and
+ // must not be modified.
+ Precomputed PrecomputedValues
+}
+
+// Public returns the public key corresponding to priv.
+func (priv *PrivateKey) Public() crypto.PublicKey {
+ return &priv.PublicKey
+}
+
+// Equal reports whether priv and x have equivalent values. It ignores
+// Precomputed values.
+func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
+ xx, ok := x.(*PrivateKey)
+ if !ok {
+ return false
+ }
+ if !priv.PublicKey.Equal(&xx.PublicKey) || !bigIntEqual(priv.D, xx.D) {
+ return false
+ }
+ if len(priv.Primes) != len(xx.Primes) {
+ return false
+ }
+ for i := range priv.Primes {
+ if !bigIntEqual(priv.Primes[i], xx.Primes[i]) {
+ return false
+ }
+ }
+ return true
+}
+
+// bigIntEqual reports whether a and b are equal leaking only their bit length
+// through timing side-channels.
+func bigIntEqual(a, b *big.Int) bool {
+ return subtle.ConstantTimeCompare(a.Bytes(), b.Bytes()) == 1
+}
+
+// Sign signs digest with priv, reading randomness from rand. If opts is a
+// *PSSOptions then the PSS algorithm will be used, otherwise PKCS #1 v1.5 will
+// be used. digest must be the result of hashing the input message using
+// opts.HashFunc().
+//
+// This method implements crypto.Signer, which is an interface to support keys
+// where the private part is kept in, for example, a hardware module. Common
+// uses should use the Sign* functions in this package directly.
+func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
+ if pssOpts, ok := opts.(*PSSOptions); ok {
+ return SignPSS(rand, priv, pssOpts.Hash, digest, pssOpts)
+ }
+
+ return SignPKCS1v15(rand, priv, opts.HashFunc(), digest)
+}
+
+// Decrypt decrypts ciphertext with priv. If opts is nil or of type
+// *PKCS1v15DecryptOptions then PKCS #1 v1.5 decryption is performed. Otherwise
+// opts must have type *OAEPOptions and OAEP decryption is done.
+func (priv *PrivateKey) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error) {
+ if opts == nil {
+ return DecryptPKCS1v15(rand, priv, ciphertext)
+ }
+
+ switch opts := opts.(type) {
+ case *OAEPOptions:
+ if opts.MGFHash == 0 {
+ return decryptOAEP(opts.Hash.New(), opts.Hash.New(), rand, priv, ciphertext, opts.Label)
+ } else {
+ return decryptOAEP(opts.Hash.New(), opts.MGFHash.New(), rand, priv, ciphertext, opts.Label)
+ }
+
+ case *PKCS1v15DecryptOptions:
+ if l := opts.SessionKeyLen; l > 0 {
+ plaintext = make([]byte, l)
+ if _, err := io.ReadFull(rand, plaintext); err != nil {
+ return nil, err
+ }
+ if err := DecryptPKCS1v15SessionKey(rand, priv, ciphertext, plaintext); err != nil {
+ return nil, err
+ }
+ return plaintext, nil
+ } else {
+ return DecryptPKCS1v15(rand, priv, ciphertext)
+ }
+
+ default:
+ return nil, errors.New("crypto/rsa: invalid options for Decrypt")
+ }
+}
+
+type PrecomputedValues struct {
+ Dp, Dq *big.Int // D mod (P-1) (or mod Q-1)
+ Qinv *big.Int // Q^-1 mod P
+
+ // CRTValues is used for the 3rd and subsequent primes. Due to a
+ // historical accident, the CRT for the first two primes is handled
+ // differently in PKCS #1 and interoperability is sufficiently
+ // important that we mirror this.
+ //
+ // Deprecated: These values are still filled in by Precompute for
+ // backwards compatibility but are not used. Multi-prime RSA is very rare,
+ // and is implemented by this package without CRT optimizations to limit
+ // complexity.
+ CRTValues []CRTValue
+
+ n, p, q *bigmod.Modulus // moduli for CRT with Montgomery precomputed constants
+}
+
+// CRTValue contains the precomputed Chinese remainder theorem values.
+type CRTValue struct {
+ Exp *big.Int // D mod (prime-1).
+ Coeff *big.Int // R·Coeff ≡ 1 mod Prime.
+ R *big.Int // product of primes prior to this (inc p and q).
+}
+
+// Validate performs basic sanity checks on the key.
+// It returns nil if the key is valid, or else an error describing a problem.
+func (priv *PrivateKey) Validate() error {
+ if err := checkPub(&priv.PublicKey); err != nil {
+ return err
+ }
+
+ // Check that Πprimes == n.
+ modulus := new(big.Int).Set(bigOne)
+ for _, prime := range priv.Primes {
+ // Any primes ≤ 1 will cause divide-by-zero panics later.
+ if prime.Cmp(bigOne) <= 0 {
+ return errors.New("crypto/rsa: invalid prime value")
+ }
+ modulus.Mul(modulus, prime)
+ }
+ if modulus.Cmp(priv.N) != 0 {
+ return errors.New("crypto/rsa: invalid modulus")
+ }
+
+ // Check that de ≡ 1 mod p-1, for each prime.
+ // This implies that e is coprime to each p-1 as e has a multiplicative
+ // inverse. Therefore e is coprime to lcm(p-1,q-1,r-1,...) =
+ // exponent(ℤ/nℤ). It also implies that a^de ≡ a mod p as a^(p-1) ≡ 1
+ // mod p. Thus a^de ≡ a mod n for all a coprime to n, as required.
+ congruence := new(big.Int)
+ de := new(big.Int).SetInt64(int64(priv.E))
+ de.Mul(de, priv.D)
+ for _, prime := range priv.Primes {
+ pminus1 := new(big.Int).Sub(prime, bigOne)
+ congruence.Mod(de, pminus1)
+ if congruence.Cmp(bigOne) != 0 {
+ return errors.New("crypto/rsa: invalid exponents")
+ }
+ }
+ return nil
+}
+
+// GenerateKey generates a random RSA private key of the given bit size.
+//
+// Most applications should use [crypto/rand.Reader] as rand. Note that the
+// returned key does not depend deterministically on the bytes read from rand,
+// and may change between calls and/or between versions.
+func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) {
+ return GenerateMultiPrimeKey(random, 2, bits)
+}
+
+// GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit
+// size and the given random source.
+//
+// Table 1 in "[On the Security of Multi-prime RSA]" suggests maximum numbers of
+// primes for a given bit size.
+//
+// Although the public keys are compatible (actually, indistinguishable) from
+// the 2-prime case, the private keys are not. Thus it may not be possible to
+// export multi-prime private keys in certain formats or to subsequently import
+// them into other code.
+//
+// This package does not implement CRT optimizations for multi-prime RSA, so the
+// keys with more than two primes will have worse performance.
+//
+// Deprecated: The use of this function with a number of primes different from
+// two is not recommended for the above security, compatibility, and performance
+// reasons. Use GenerateKey instead.
+//
+// [On the Security of Multi-prime RSA]: http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
+func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (*PrivateKey, error) {
+ randutil.MaybeReadByte(random)
+
+ if boring.Enabled && random == boring.RandReader && nprimes == 2 &&
+ (bits == 2048 || bits == 3072 || bits == 4096) {
+ bN, bE, bD, bP, bQ, bDp, bDq, bQinv, err := boring.GenerateKeyRSA(bits)
+ if err != nil {
+ return nil, err
+ }
+ N := bbig.Dec(bN)
+ E := bbig.Dec(bE)
+ D := bbig.Dec(bD)
+ P := bbig.Dec(bP)
+ Q := bbig.Dec(bQ)
+ Dp := bbig.Dec(bDp)
+ Dq := bbig.Dec(bDq)
+ Qinv := bbig.Dec(bQinv)
+ e64 := E.Int64()
+ if !E.IsInt64() || int64(int(e64)) != e64 {
+ return nil, errors.New("crypto/rsa: generated key exponent too large")
+ }
+
+ mn, err := bigmod.NewModulusFromBig(N)
+ if err != nil {
+ return nil, err
+ }
+ mp, err := bigmod.NewModulusFromBig(P)
+ if err != nil {
+ return nil, err
+ }
+ mq, err := bigmod.NewModulusFromBig(Q)
+ if err != nil {
+ return nil, err
+ }
+
+ key := &PrivateKey{
+ PublicKey: PublicKey{
+ N: N,
+ E: int(e64),
+ },
+ D: D,
+ Primes: []*big.Int{P, Q},
+ Precomputed: PrecomputedValues{
+ Dp: Dp,
+ Dq: Dq,
+ Qinv: Qinv,
+ CRTValues: make([]CRTValue, 0), // non-nil, to match Precompute
+ n: mn,
+ p: mp,
+ q: mq,
+ },
+ }
+ return key, nil
+ }
+
+ priv := new(PrivateKey)
+ priv.E = 65537
+
+ if nprimes < 2 {
+ return nil, errors.New("crypto/rsa: GenerateMultiPrimeKey: nprimes must be >= 2")
+ }
+
+ if bits < 64 {
+ primeLimit := float64(uint64(1) << uint(bits/nprimes))
+ // pi approximates the number of primes less than primeLimit
+ pi := primeLimit / (math.Log(primeLimit) - 1)
+ // Generated primes start with 11 (in binary) so we can only
+ // use a quarter of them.
+ pi /= 4
+ // Use a factor of two to ensure that key generation terminates
+ // in a reasonable amount of time.
+ pi /= 2
+ if pi <= float64(nprimes) {
+ return nil, errors.New("crypto/rsa: too few primes of given length to generate an RSA key")
+ }
+ }
+
+ primes := make([]*big.Int, nprimes)
+
+NextSetOfPrimes:
+ for {
+ todo := bits
+ // crypto/rand should set the top two bits in each prime.
+ // Thus each prime has the form
+ // p_i = 2^bitlen(p_i) × 0.11... (in base 2).
+ // And the product is:
+ // P = 2^todo × α
+ // where α is the product of nprimes numbers of the form 0.11...
+ //
+ // If α < 1/2 (which can happen for nprimes > 2), we need to
+ // shift todo to compensate for lost bits: the mean value of 0.11...
+ // is 7/8, so todo + shift - nprimes * log2(7/8) ~= bits - 1/2
+ // will give good results.
+ if nprimes >= 7 {
+ todo += (nprimes - 2) / 5
+ }
+ for i := 0; i < nprimes; i++ {
+ var err error
+ primes[i], err = rand.Prime(random, todo/(nprimes-i))
+ if err != nil {
+ return nil, err
+ }
+ todo -= primes[i].BitLen()
+ }
+
+ // Make sure that primes is pairwise unequal.
+ for i, prime := range primes {
+ for j := 0; j < i; j++ {
+ if prime.Cmp(primes[j]) == 0 {
+ continue NextSetOfPrimes
+ }
+ }
+ }
+
+ n := new(big.Int).Set(bigOne)
+ totient := new(big.Int).Set(bigOne)
+ pminus1 := new(big.Int)
+ for _, prime := range primes {
+ n.Mul(n, prime)
+ pminus1.Sub(prime, bigOne)
+ totient.Mul(totient, pminus1)
+ }
+ if n.BitLen() != bits {
+ // This should never happen for nprimes == 2 because
+ // crypto/rand should set the top two bits in each prime.
+ // For nprimes > 2 we hope it does not happen often.
+ continue NextSetOfPrimes
+ }
+
+ priv.D = new(big.Int)
+ e := big.NewInt(int64(priv.E))
+ ok := priv.D.ModInverse(e, totient)
+
+ if ok != nil {
+ priv.Primes = primes
+ priv.N = n
+ break
+ }
+ }
+
+ priv.Precompute()
+ return priv, nil
+}
+
+// incCounter increments a four byte, big-endian counter.
+func incCounter(c *[4]byte) {
+ if c[3]++; c[3] != 0 {
+ return
+ }
+ if c[2]++; c[2] != 0 {
+ return
+ }
+ if c[1]++; c[1] != 0 {
+ return
+ }
+ c[0]++
+}
+
+// mgf1XOR XORs the bytes in out with a mask generated using the MGF1 function
+// specified in PKCS #1 v2.1.
+func mgf1XOR(out []byte, hash hash.Hash, seed []byte) {
+ var counter [4]byte
+ var digest []byte
+
+ done := 0
+ for done < len(out) {
+ hash.Write(seed)
+ hash.Write(counter[0:4])
+ digest = hash.Sum(digest[:0])
+ hash.Reset()
+
+ for i := 0; i < len(digest) && done < len(out); i++ {
+ out[done] ^= digest[i]
+ done++
+ }
+ incCounter(&counter)
+ }
+}
+
+// ErrMessageTooLong is returned when attempting to encrypt or sign a message
+// which is too large for the size of the key. When using SignPSS, this can also
+// be returned if the size of the salt is too large.
+var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA key size")
+
+func encrypt(pub *PublicKey, plaintext []byte) ([]byte, error) {
+ boring.Unreachable()
+
+ // Most of the CPU time for encryption and verification is spent in this
+ // NewModulusFromBig call, because PublicKey doesn't have a Precomputed
+ // field. If performance becomes an issue, consider placing a private
+ // sync.Once on PublicKey to compute this.
+ N, err := bigmod.NewModulusFromBig(pub.N)
+ if err != nil {
+ return nil, err
+ }
+ m, err := bigmod.NewNat().SetBytes(plaintext, N)
+ if err != nil {
+ return nil, err
+ }
+ e := uint(pub.E)
+
+ return bigmod.NewNat().ExpShort(m, e, N).Bytes(N), nil
+}
+
+// EncryptOAEP encrypts the given message with RSA-OAEP.
+//
+// OAEP is parameterised by a hash function that is used as a random oracle.
+// Encryption and decryption of a given message must use the same hash function
+// and sha256.New() is a reasonable choice.
+//
+// The random parameter is used as a source of entropy to ensure that
+// encrypting the same message twice doesn't result in the same ciphertext.
+// Most applications should use [crypto/rand.Reader] as random.
+//
+// The label parameter may contain arbitrary data that will not be encrypted,
+// but which gives important context to the message. For example, if a given
+// public key is used to encrypt two types of messages then distinct label
+// values could be used to ensure that a ciphertext for one purpose cannot be
+// used for another by an attacker. If not required it can be empty.
+//
+// The message must be no longer than the length of the public modulus minus
+// twice the hash length, minus a further 2.
+func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) ([]byte, error) {
+ // Note that while we don't commit to deterministic execution with respect
+ // to the random stream, we also don't apply MaybeReadByte, so per Hyrum's
+ // Law it's probably relied upon by some. It's a tolerable promise because a
+ // well-specified number of random bytes is included in the ciphertext, in a
+ // well-specified way.
+
+ if err := checkPub(pub); err != nil {
+ return nil, err
+ }
+ hash.Reset()
+ k := pub.Size()
+ if len(msg) > k-2*hash.Size()-2 {
+ return nil, ErrMessageTooLong
+ }
+
+ if boring.Enabled && random == boring.RandReader {
+ bkey, err := boringPublicKey(pub)
+ if err != nil {
+ return nil, err
+ }
+ return boring.EncryptRSAOAEP(hash, hash, bkey, msg, label)
+ }
+ boring.UnreachableExceptTests()
+
+ hash.Write(label)
+ lHash := hash.Sum(nil)
+ hash.Reset()
+
+ em := make([]byte, k)
+ seed := em[1 : 1+hash.Size()]
+ db := em[1+hash.Size():]
+
+ copy(db[0:hash.Size()], lHash)
+ db[len(db)-len(msg)-1] = 1
+ copy(db[len(db)-len(msg):], msg)
+
+ _, err := io.ReadFull(random, seed)
+ if err != nil {
+ return nil, err
+ }
+
+ mgf1XOR(db, hash, seed)
+ mgf1XOR(seed, hash, db)
+
+ if boring.Enabled {
+ var bkey *boring.PublicKeyRSA
+ bkey, err = boringPublicKey(pub)
+ if err != nil {
+ return nil, err
+ }
+ return boring.EncryptRSANoPadding(bkey, em)
+ }
+
+ return encrypt(pub, em)
+}
+
+// ErrDecryption represents a failure to decrypt a message.
+// It is deliberately vague to avoid adaptive attacks.
+var ErrDecryption = errors.New("crypto/rsa: decryption error")
+
+// ErrVerification represents a failure to verify a signature.
+// It is deliberately vague to avoid adaptive attacks.
+var ErrVerification = errors.New("crypto/rsa: verification error")
+
+// Precompute performs some calculations that speed up private key operations
+// in the future.
+func (priv *PrivateKey) Precompute() {
+ if priv.Precomputed.n == nil && len(priv.Primes) == 2 {
+ // Precomputed values _should_ always be valid, but if they aren't
+ // just return. We could also panic.
+ var err error
+ priv.Precomputed.n, err = bigmod.NewModulusFromBig(priv.N)
+ if err != nil {
+ return
+ }
+ priv.Precomputed.p, err = bigmod.NewModulusFromBig(priv.Primes[0])
+ if err != nil {
+ // Unset previous values, so we either have everything or nothing
+ priv.Precomputed.n = nil
+ return
+ }
+ priv.Precomputed.q, err = bigmod.NewModulusFromBig(priv.Primes[1])
+ if err != nil {
+ // Unset previous values, so we either have everything or nothing
+ priv.Precomputed.n, priv.Precomputed.p = nil, nil
+ return
+ }
+ }
+
+ // Fill in the backwards-compatibility *big.Int values.
+ if priv.Precomputed.Dp != nil {
+ return
+ }
+
+ priv.Precomputed.Dp = new(big.Int).Sub(priv.Primes[0], bigOne)
+ priv.Precomputed.Dp.Mod(priv.D, priv.Precomputed.Dp)
+
+ priv.Precomputed.Dq = new(big.Int).Sub(priv.Primes[1], bigOne)
+ priv.Precomputed.Dq.Mod(priv.D, priv.Precomputed.Dq)
+
+ priv.Precomputed.Qinv = new(big.Int).ModInverse(priv.Primes[1], priv.Primes[0])
+
+ r := new(big.Int).Mul(priv.Primes[0], priv.Primes[1])
+ priv.Precomputed.CRTValues = make([]CRTValue, len(priv.Primes)-2)
+ for i := 2; i < len(priv.Primes); i++ {
+ prime := priv.Primes[i]
+ values := &priv.Precomputed.CRTValues[i-2]
+
+ values.Exp = new(big.Int).Sub(prime, bigOne)
+ values.Exp.Mod(priv.D, values.Exp)
+
+ values.R = new(big.Int).Set(r)
+ values.Coeff = new(big.Int).ModInverse(r, prime)
+
+ r.Mul(r, prime)
+ }
+}
+
+const withCheck = true
+const noCheck = false
+
+// decrypt performs an RSA decryption of ciphertext into out. If check is true,
+// m^e is calculated and compared with ciphertext, in order to defend against
+// errors in the CRT computation.
+func decrypt(priv *PrivateKey, ciphertext []byte, check bool) ([]byte, error) {
+ if len(priv.Primes) <= 2 {
+ boring.Unreachable()
+ }
+
+ var (
+ err error
+ m, c *bigmod.Nat
+ N *bigmod.Modulus
+ t0 = bigmod.NewNat()
+ )
+ if priv.Precomputed.n == nil {
+ N, err = bigmod.NewModulusFromBig(priv.N)
+ if err != nil {
+ return nil, ErrDecryption
+ }
+ c, err = bigmod.NewNat().SetBytes(ciphertext, N)
+ if err != nil {
+ return nil, ErrDecryption
+ }
+ m = bigmod.NewNat().Exp(c, priv.D.Bytes(), N)
+ } else {
+ N = priv.Precomputed.n
+ P, Q := priv.Precomputed.p, priv.Precomputed.q
+ Qinv, err := bigmod.NewNat().SetBytes(priv.Precomputed.Qinv.Bytes(), P)
+ if err != nil {
+ return nil, ErrDecryption
+ }
+ c, err = bigmod.NewNat().SetBytes(ciphertext, N)
+ if err != nil {
+ return nil, ErrDecryption
+ }
+
+ // m = c ^ Dp mod p
+ m = bigmod.NewNat().Exp(t0.Mod(c, P), priv.Precomputed.Dp.Bytes(), P)
+ // m2 = c ^ Dq mod q
+ m2 := bigmod.NewNat().Exp(t0.Mod(c, Q), priv.Precomputed.Dq.Bytes(), Q)
+ // m = m - m2 mod p
+ m.Sub(t0.Mod(m2, P), P)
+ // m = m * Qinv mod p
+ m.Mul(Qinv, P)
+ // m = m * q mod N
+ m.ExpandFor(N).Mul(t0.Mod(Q.Nat(), N), N)
+ // m = m + m2 mod N
+ m.Add(m2.ExpandFor(N), N)
+ }
+
+ if check {
+ c1 := bigmod.NewNat().ExpShort(m, uint(priv.E), N)
+ if c1.Equal(c) != 1 {
+ return nil, ErrDecryption
+ }
+ }
+
+ return m.Bytes(N), nil
+}
+
+// DecryptOAEP decrypts ciphertext using RSA-OAEP.
+//
+// OAEP is parameterised by a hash function that is used as a random oracle.
+// Encryption and decryption of a given message must use the same hash function
+// and sha256.New() is a reasonable choice.
+//
+// The random parameter is legacy and ignored, and it can be nil.
+//
+// The label parameter must match the value given when encrypting. See
+// EncryptOAEP for details.
+func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
+ return decryptOAEP(hash, hash, random, priv, ciphertext, label)
+}
+
+func decryptOAEP(hash, mgfHash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) ([]byte, error) {
+ if err := checkPub(&priv.PublicKey); err != nil {
+ return nil, err
+ }
+ k := priv.Size()
+ if len(ciphertext) > k ||
+ k < hash.Size()*2+2 {
+ return nil, ErrDecryption
+ }
+
+ if boring.Enabled {
+ bkey, err := boringPrivateKey(priv)
+ if err != nil {
+ return nil, err
+ }
+ out, err := boring.DecryptRSAOAEP(hash, mgfHash, bkey, ciphertext, label)
+ if err != nil {
+ return nil, ErrDecryption
+ }
+ return out, nil
+ }
+
+ em, err := decrypt(priv, ciphertext, noCheck)
+ if err != nil {
+ return nil, err
+ }
+
+ hash.Write(label)
+ lHash := hash.Sum(nil)
+ hash.Reset()
+
+ firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
+
+ seed := em[1 : hash.Size()+1]
+ db := em[hash.Size()+1:]
+
+ mgf1XOR(seed, mgfHash, db)
+ mgf1XOR(db, mgfHash, seed)
+
+ lHash2 := db[0:hash.Size()]
+
+ // We have to validate the plaintext in constant time in order to avoid
+ // attacks like: J. Manger. A Chosen Ciphertext Attack on RSA Optimal
+ // Asymmetric Encryption Padding (OAEP) as Standardized in PKCS #1
+ // v2.0. In J. Kilian, editor, Advances in Cryptology.
+ lHash2Good := subtle.ConstantTimeCompare(lHash, lHash2)
+
+ // The remainder of the plaintext must be zero or more 0x00, followed
+ // by 0x01, followed by the message.
+ // lookingForIndex: 1 iff we are still looking for the 0x01
+ // index: the offset of the first 0x01 byte
+ // invalid: 1 iff we saw a non-zero byte before the 0x01.
+ var lookingForIndex, index, invalid int
+ lookingForIndex = 1
+ rest := db[hash.Size():]
+
+ for i := 0; i < len(rest); i++ {
+ equals0 := subtle.ConstantTimeByteEq(rest[i], 0)
+ equals1 := subtle.ConstantTimeByteEq(rest[i], 1)
+ index = subtle.ConstantTimeSelect(lookingForIndex&equals1, i, index)
+ lookingForIndex = subtle.ConstantTimeSelect(equals1, 0, lookingForIndex)
+ invalid = subtle.ConstantTimeSelect(lookingForIndex&^equals0, 1, invalid)
+ }
+
+ if firstByteIsZero&lHash2Good&^invalid&^lookingForIndex != 1 {
+ return nil, ErrDecryption
+ }
+
+ return rest[index+1:], nil
+}
diff --git a/contrib/go/_std_1.21/src/crypto/rsa/ya.make b/contrib/go/_std_1.21/src/crypto/rsa/ya.make
new file mode 100644
index 0000000000..1b4b4a7769
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/rsa/ya.make
@@ -0,0 +1,23 @@
+GO_LIBRARY()
+
+SRCS(
+ notboring.go
+ pkcs1v15.go
+ pss.go
+ rsa.go
+)
+
+GO_TEST_SRCS(rsa_export_test.go)
+
+GO_XTEST_SRCS(
+ equal_test.go
+ example_test.go
+ pkcs1v15_test.go
+ pss_test.go
+ rsa_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/sha1/boring.go b/contrib/go/_std_1.21/src/crypto/sha1/boring.go
index b5786d1bf4..b5786d1bf4 100644
--- a/contrib/go/_std_1.20/src/crypto/sha1/boring.go
+++ b/contrib/go/_std_1.21/src/crypto/sha1/boring.go
diff --git a/contrib/go/_std_1.20/src/crypto/sha1/sha1.go b/contrib/go/_std_1.21/src/crypto/sha1/sha1.go
index 43ab72a485..43ab72a485 100644
--- a/contrib/go/_std_1.20/src/crypto/sha1/sha1.go
+++ b/contrib/go/_std_1.21/src/crypto/sha1/sha1.go
diff --git a/contrib/go/_std_1.21/src/crypto/sha1/sha1block.go b/contrib/go/_std_1.21/src/crypto/sha1/sha1block.go
new file mode 100644
index 0000000000..1c1a7c5f31
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/sha1/sha1block.go
@@ -0,0 +1,83 @@
+// Copyright 2009 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 sha1
+
+import (
+ "math/bits"
+)
+
+const (
+ _K0 = 0x5A827999
+ _K1 = 0x6ED9EBA1
+ _K2 = 0x8F1BBCDC
+ _K3 = 0xCA62C1D6
+)
+
+// blockGeneric is a portable, pure Go version of the SHA-1 block step.
+// It's used by sha1block_generic.go and tests.
+func blockGeneric(dig *digest, p []byte) {
+ var w [16]uint32
+
+ h0, h1, h2, h3, h4 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4]
+ for len(p) >= chunk {
+ // Can interlace the computation of w with the
+ // rounds below if needed for speed.
+ for i := 0; i < 16; i++ {
+ j := i * 4
+ w[i] = uint32(p[j])<<24 | uint32(p[j+1])<<16 | uint32(p[j+2])<<8 | uint32(p[j+3])
+ }
+
+ a, b, c, d, e := h0, h1, h2, h3, h4
+
+ // Each of the four 20-iteration rounds
+ // differs only in the computation of f and
+ // the choice of K (_K0, _K1, etc).
+ i := 0
+ for ; i < 16; i++ {
+ f := b&c | (^b)&d
+ t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K0
+ a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
+ }
+ for ; i < 20; i++ {
+ tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
+ w[i&0xf] = bits.RotateLeft32(tmp, 1)
+
+ f := b&c | (^b)&d
+ t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K0
+ a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
+ }
+ for ; i < 40; i++ {
+ tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
+ w[i&0xf] = bits.RotateLeft32(tmp, 1)
+ f := b ^ c ^ d
+ t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K1
+ a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
+ }
+ for ; i < 60; i++ {
+ tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
+ w[i&0xf] = bits.RotateLeft32(tmp, 1)
+ f := ((b | c) & d) | (b & c)
+ t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K2
+ a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
+ }
+ for ; i < 80; i++ {
+ tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
+ w[i&0xf] = bits.RotateLeft32(tmp, 1)
+ f := b ^ c ^ d
+ t := bits.RotateLeft32(a, 5) + f + e + w[i&0xf] + _K3
+ a, b, c, d, e = t, a, bits.RotateLeft32(b, 30), c, d
+ }
+
+ h0 += a
+ h1 += b
+ h2 += c
+ h3 += d
+ h4 += e
+
+ p = p[chunk:]
+ }
+
+ dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4] = h0, h1, h2, h3, h4
+}
diff --git a/contrib/go/_std_1.20/src/crypto/sha1/sha1block_amd64.go b/contrib/go/_std_1.21/src/crypto/sha1/sha1block_amd64.go
index 039813d7dc..039813d7dc 100644
--- a/contrib/go/_std_1.20/src/crypto/sha1/sha1block_amd64.go
+++ b/contrib/go/_std_1.21/src/crypto/sha1/sha1block_amd64.go
diff --git a/contrib/go/_std_1.21/src/crypto/sha1/sha1block_amd64.s b/contrib/go/_std_1.21/src/crypto/sha1/sha1block_amd64.s
new file mode 100644
index 0000000000..9bdf24cf49
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/sha1/sha1block_amd64.s
@@ -0,0 +1,1500 @@
+// Copyright 2013 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.
+
+// AVX2 version by Intel, same algorithm as code in Linux kernel:
+// https://github.com/torvalds/linux/blob/master/arch/x86/crypto/sha1_avx2_x86_64_asm.S
+// Authors:
+// Ilya Albrekht <ilya.albrekht@intel.com>
+// Maxim Locktyukhin <maxim.locktyukhin@intel.com>
+// Ronen Zohar <ronen.zohar@intel.com>
+// Chandramouli Narayanan <mouli@linux.intel.com>
+
+
+#include "textflag.h"
+
+// SHA-1 block routine. See sha1block.go for Go equivalent.
+//
+// There are 80 rounds of 4 types:
+// - rounds 0-15 are type 1 and load data (ROUND1 macro).
+// - rounds 16-19 are type 1 and do not load data (ROUND1x macro).
+// - rounds 20-39 are type 2 and do not load data (ROUND2 macro).
+// - rounds 40-59 are type 3 and do not load data (ROUND3 macro).
+// - rounds 60-79 are type 4 and do not load data (ROUND4 macro).
+//
+// Each round loads or shuffles the data, then computes a per-round
+// function of b, c, d, and then mixes the result into and rotates the
+// five registers a, b, c, d, e holding the intermediate results.
+//
+// The register rotation is implemented by rotating the arguments to
+// the round macros instead of by explicit move instructions.
+
+#define LOAD(index) \
+ MOVL (index*4)(SI), R10; \
+ BSWAPL R10; \
+ MOVL R10, (index*4)(SP)
+
+#define SHUFFLE(index) \
+ MOVL (((index)&0xf)*4)(SP), R10; \
+ XORL (((index-3)&0xf)*4)(SP), R10; \
+ XORL (((index-8)&0xf)*4)(SP), R10; \
+ XORL (((index-14)&0xf)*4)(SP), R10; \
+ ROLL $1, R10; \
+ MOVL R10, (((index)&0xf)*4)(SP)
+
+#define FUNC1(a, b, c, d, e) \
+ MOVL d, R9; \
+ XORL c, R9; \
+ ANDL b, R9; \
+ XORL d, R9
+
+#define FUNC2(a, b, c, d, e) \
+ MOVL b, R9; \
+ XORL c, R9; \
+ XORL d, R9
+
+#define FUNC3(a, b, c, d, e) \
+ MOVL b, R8; \
+ ORL c, R8; \
+ ANDL d, R8; \
+ MOVL b, R9; \
+ ANDL c, R9; \
+ ORL R8, R9
+
+#define FUNC4 FUNC2
+
+#define MIX(a, b, c, d, e, const) \
+ ROLL $30, b; \
+ ADDL R9, e; \
+ MOVL a, R8; \
+ ROLL $5, R8; \
+ LEAL const(e)(R10*1), e; \
+ ADDL R8, e
+
+#define ROUND1(a, b, c, d, e, index) \
+ LOAD(index); \
+ FUNC1(a, b, c, d, e); \
+ MIX(a, b, c, d, e, 0x5A827999)
+
+#define ROUND1x(a, b, c, d, e, index) \
+ SHUFFLE(index); \
+ FUNC1(a, b, c, d, e); \
+ MIX(a, b, c, d, e, 0x5A827999)
+
+#define ROUND2(a, b, c, d, e, index) \
+ SHUFFLE(index); \
+ FUNC2(a, b, c, d, e); \
+ MIX(a, b, c, d, e, 0x6ED9EBA1)
+
+#define ROUND3(a, b, c, d, e, index) \
+ SHUFFLE(index); \
+ FUNC3(a, b, c, d, e); \
+ MIX(a, b, c, d, e, 0x8F1BBCDC)
+
+#define ROUND4(a, b, c, d, e, index) \
+ SHUFFLE(index); \
+ FUNC4(a, b, c, d, e); \
+ MIX(a, b, c, d, e, 0xCA62C1D6)
+
+TEXT ·blockAMD64(SB),NOSPLIT,$64-32
+ MOVQ dig+0(FP), BP
+ MOVQ p_base+8(FP), SI
+ MOVQ p_len+16(FP), DX
+ SHRQ $6, DX
+ SHLQ $6, DX
+
+ LEAQ (SI)(DX*1), DI
+ MOVL (0*4)(BP), AX
+ MOVL (1*4)(BP), BX
+ MOVL (2*4)(BP), CX
+ MOVL (3*4)(BP), DX
+ MOVL (4*4)(BP), BP
+
+ CMPQ SI, DI
+ JEQ end
+
+loop:
+ MOVL AX, R11
+ MOVL BX, R12
+ MOVL CX, R13
+ MOVL DX, R14
+ MOVL BP, R15
+
+ ROUND1(AX, BX, CX, DX, BP, 0)
+ ROUND1(BP, AX, BX, CX, DX, 1)
+ ROUND1(DX, BP, AX, BX, CX, 2)
+ ROUND1(CX, DX, BP, AX, BX, 3)
+ ROUND1(BX, CX, DX, BP, AX, 4)
+ ROUND1(AX, BX, CX, DX, BP, 5)
+ ROUND1(BP, AX, BX, CX, DX, 6)
+ ROUND1(DX, BP, AX, BX, CX, 7)
+ ROUND1(CX, DX, BP, AX, BX, 8)
+ ROUND1(BX, CX, DX, BP, AX, 9)
+ ROUND1(AX, BX, CX, DX, BP, 10)
+ ROUND1(BP, AX, BX, CX, DX, 11)
+ ROUND1(DX, BP, AX, BX, CX, 12)
+ ROUND1(CX, DX, BP, AX, BX, 13)
+ ROUND1(BX, CX, DX, BP, AX, 14)
+ ROUND1(AX, BX, CX, DX, BP, 15)
+
+ ROUND1x(BP, AX, BX, CX, DX, 16)
+ ROUND1x(DX, BP, AX, BX, CX, 17)
+ ROUND1x(CX, DX, BP, AX, BX, 18)
+ ROUND1x(BX, CX, DX, BP, AX, 19)
+
+ ROUND2(AX, BX, CX, DX, BP, 20)
+ ROUND2(BP, AX, BX, CX, DX, 21)
+ ROUND2(DX, BP, AX, BX, CX, 22)
+ ROUND2(CX, DX, BP, AX, BX, 23)
+ ROUND2(BX, CX, DX, BP, AX, 24)
+ ROUND2(AX, BX, CX, DX, BP, 25)
+ ROUND2(BP, AX, BX, CX, DX, 26)
+ ROUND2(DX, BP, AX, BX, CX, 27)
+ ROUND2(CX, DX, BP, AX, BX, 28)
+ ROUND2(BX, CX, DX, BP, AX, 29)
+ ROUND2(AX, BX, CX, DX, BP, 30)
+ ROUND2(BP, AX, BX, CX, DX, 31)
+ ROUND2(DX, BP, AX, BX, CX, 32)
+ ROUND2(CX, DX, BP, AX, BX, 33)
+ ROUND2(BX, CX, DX, BP, AX, 34)
+ ROUND2(AX, BX, CX, DX, BP, 35)
+ ROUND2(BP, AX, BX, CX, DX, 36)
+ ROUND2(DX, BP, AX, BX, CX, 37)
+ ROUND2(CX, DX, BP, AX, BX, 38)
+ ROUND2(BX, CX, DX, BP, AX, 39)
+
+ ROUND3(AX, BX, CX, DX, BP, 40)
+ ROUND3(BP, AX, BX, CX, DX, 41)
+ ROUND3(DX, BP, AX, BX, CX, 42)
+ ROUND3(CX, DX, BP, AX, BX, 43)
+ ROUND3(BX, CX, DX, BP, AX, 44)
+ ROUND3(AX, BX, CX, DX, BP, 45)
+ ROUND3(BP, AX, BX, CX, DX, 46)
+ ROUND3(DX, BP, AX, BX, CX, 47)
+ ROUND3(CX, DX, BP, AX, BX, 48)
+ ROUND3(BX, CX, DX, BP, AX, 49)
+ ROUND3(AX, BX, CX, DX, BP, 50)
+ ROUND3(BP, AX, BX, CX, DX, 51)
+ ROUND3(DX, BP, AX, BX, CX, 52)
+ ROUND3(CX, DX, BP, AX, BX, 53)
+ ROUND3(BX, CX, DX, BP, AX, 54)
+ ROUND3(AX, BX, CX, DX, BP, 55)
+ ROUND3(BP, AX, BX, CX, DX, 56)
+ ROUND3(DX, BP, AX, BX, CX, 57)
+ ROUND3(CX, DX, BP, AX, BX, 58)
+ ROUND3(BX, CX, DX, BP, AX, 59)
+
+ ROUND4(AX, BX, CX, DX, BP, 60)
+ ROUND4(BP, AX, BX, CX, DX, 61)
+ ROUND4(DX, BP, AX, BX, CX, 62)
+ ROUND4(CX, DX, BP, AX, BX, 63)
+ ROUND4(BX, CX, DX, BP, AX, 64)
+ ROUND4(AX, BX, CX, DX, BP, 65)
+ ROUND4(BP, AX, BX, CX, DX, 66)
+ ROUND4(DX, BP, AX, BX, CX, 67)
+ ROUND4(CX, DX, BP, AX, BX, 68)
+ ROUND4(BX, CX, DX, BP, AX, 69)
+ ROUND4(AX, BX, CX, DX, BP, 70)
+ ROUND4(BP, AX, BX, CX, DX, 71)
+ ROUND4(DX, BP, AX, BX, CX, 72)
+ ROUND4(CX, DX, BP, AX, BX, 73)
+ ROUND4(BX, CX, DX, BP, AX, 74)
+ ROUND4(AX, BX, CX, DX, BP, 75)
+ ROUND4(BP, AX, BX, CX, DX, 76)
+ ROUND4(DX, BP, AX, BX, CX, 77)
+ ROUND4(CX, DX, BP, AX, BX, 78)
+ ROUND4(BX, CX, DX, BP, AX, 79)
+
+ ADDL R11, AX
+ ADDL R12, BX
+ ADDL R13, CX
+ ADDL R14, DX
+ ADDL R15, BP
+
+ ADDQ $64, SI
+ CMPQ SI, DI
+ JB loop
+
+end:
+ MOVQ dig+0(FP), DI
+ MOVL AX, (0*4)(DI)
+ MOVL BX, (1*4)(DI)
+ MOVL CX, (2*4)(DI)
+ MOVL DX, (3*4)(DI)
+ MOVL BP, (4*4)(DI)
+ RET
+
+
+// This is the implementation using AVX2, BMI1 and BMI2. It is based on:
+// "SHA-1 implementation with Intel(R) AVX2 instruction set extensions"
+// From http://software.intel.com/en-us/articles
+// (look for improving-the-performance-of-the-secure-hash-algorithm-1)
+// This implementation is 2x unrolled, and interleaves vector instructions,
+// used to precompute W, with scalar computation of current round
+// for optimal scheduling.
+
+// Trivial helper macros.
+#define UPDATE_HASH(A,TB,C,D,E) \
+ ADDL (R9), A \
+ MOVL A, (R9) \
+ ADDL 4(R9), TB \
+ MOVL TB, 4(R9) \
+ ADDL 8(R9), C \
+ MOVL C, 8(R9) \
+ ADDL 12(R9), D \
+ MOVL D, 12(R9) \
+ ADDL 16(R9), E \
+ MOVL E, 16(R9)
+
+
+
+// Helper macros for PRECALC, which does precomputations
+#define PRECALC_0(OFFSET) \
+ VMOVDQU OFFSET(R10),X0
+
+#define PRECALC_1(OFFSET) \
+ VINSERTI128 $1, OFFSET(R13), Y0, Y0
+
+#define PRECALC_2(YREG) \
+ VPSHUFB Y10, Y0, YREG
+
+#define PRECALC_4(YREG,K_OFFSET) \
+ VPADDD K_OFFSET(R8), YREG, Y0
+
+#define PRECALC_7(OFFSET) \
+ VMOVDQU Y0, (OFFSET*2)(R14)
+
+
+// Message scheduling pre-compute for rounds 0-15
+// R13 is a pointer to even 64-byte block
+// R10 is a pointer to odd 64-byte block
+// R14 is a pointer to temp buffer
+// X0 is used as temp register
+// YREG is clobbered as part of computation
+// OFFSET chooses 16 byte chunk within a block
+// R8 is a pointer to constants block
+// K_OFFSET chooses K constants relevant to this round
+// X10 holds swap mask
+#define PRECALC_00_15(OFFSET,YREG) \
+ PRECALC_0(OFFSET) \
+ PRECALC_1(OFFSET) \
+ PRECALC_2(YREG) \
+ PRECALC_4(YREG,0x0) \
+ PRECALC_7(OFFSET)
+
+
+// Helper macros for PRECALC_16_31
+#define PRECALC_16(REG_SUB_16,REG_SUB_12,REG_SUB_4,REG) \
+ VPALIGNR $8, REG_SUB_16, REG_SUB_12, REG \ // w[i-14]
+ VPSRLDQ $4, REG_SUB_4, Y0 // w[i-3]
+
+#define PRECALC_17(REG_SUB_16,REG_SUB_8,REG) \
+ VPXOR REG_SUB_8, REG, REG \
+ VPXOR REG_SUB_16, Y0, Y0
+
+#define PRECALC_18(REG) \
+ VPXOR Y0, REG, REG \
+ VPSLLDQ $12, REG, Y9
+
+#define PRECALC_19(REG) \
+ VPSLLD $1, REG, Y0 \
+ VPSRLD $31, REG, REG
+
+#define PRECALC_20(REG) \
+ VPOR REG, Y0, Y0 \
+ VPSLLD $2, Y9, REG
+
+#define PRECALC_21(REG) \
+ VPSRLD $30, Y9, Y9 \
+ VPXOR REG, Y0, Y0
+
+#define PRECALC_23(REG,K_OFFSET,OFFSET) \
+ VPXOR Y9, Y0, REG \
+ VPADDD K_OFFSET(R8), REG, Y0 \
+ VMOVDQU Y0, (OFFSET)(R14)
+
+// Message scheduling pre-compute for rounds 16-31
+// calculating last 32 w[i] values in 8 XMM registers
+// pre-calculate K+w[i] values and store to mem
+// for later load by ALU add instruction.
+// "brute force" vectorization for rounds 16-31 only
+// due to w[i]->w[i-3] dependency.
+// clobbers 5 input ymm registers REG_SUB*
+// uses X0 and X9 as temp registers
+// As always, R8 is a pointer to constants block
+// and R14 is a pointer to temp buffer
+#define PRECALC_16_31(REG,REG_SUB_4,REG_SUB_8,REG_SUB_12,REG_SUB_16,K_OFFSET,OFFSET) \
+ PRECALC_16(REG_SUB_16,REG_SUB_12,REG_SUB_4,REG) \
+ PRECALC_17(REG_SUB_16,REG_SUB_8,REG) \
+ PRECALC_18(REG) \
+ PRECALC_19(REG) \
+ PRECALC_20(REG) \
+ PRECALC_21(REG) \
+ PRECALC_23(REG,K_OFFSET,OFFSET)
+
+
+// Helper macros for PRECALC_32_79
+#define PRECALC_32(REG_SUB_8,REG_SUB_4) \
+ VPALIGNR $8, REG_SUB_8, REG_SUB_4, Y0
+
+#define PRECALC_33(REG_SUB_28,REG) \
+ VPXOR REG_SUB_28, REG, REG
+
+#define PRECALC_34(REG_SUB_16) \
+ VPXOR REG_SUB_16, Y0, Y0
+
+#define PRECALC_35(REG) \
+ VPXOR Y0, REG, REG
+
+#define PRECALC_36(REG) \
+ VPSLLD $2, REG, Y0
+
+#define PRECALC_37(REG) \
+ VPSRLD $30, REG, REG \
+ VPOR REG, Y0, REG
+
+#define PRECALC_39(REG,K_OFFSET,OFFSET) \
+ VPADDD K_OFFSET(R8), REG, Y0 \
+ VMOVDQU Y0, (OFFSET)(R14)
+
+// Message scheduling pre-compute for rounds 32-79
+// In SHA-1 specification we have:
+// w[i] = (w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]) rol 1
+// Which is the same as:
+// w[i] = (w[i-6] ^ w[i-16] ^ w[i-28] ^ w[i-32]) rol 2
+// This allows for more efficient vectorization,
+// since w[i]->w[i-3] dependency is broken
+#define PRECALC_32_79(REG,REG_SUB_4,REG_SUB_8,REG_SUB_16,REG_SUB_28,K_OFFSET,OFFSET) \
+ PRECALC_32(REG_SUB_8,REG_SUB_4) \
+ PRECALC_33(REG_SUB_28,REG) \
+ PRECALC_34(REG_SUB_16) \
+ PRECALC_35(REG) \
+ PRECALC_36(REG) \
+ PRECALC_37(REG) \
+ PRECALC_39(REG,K_OFFSET,OFFSET)
+
+#define PRECALC \
+ PRECALC_00_15(0,Y15) \
+ PRECALC_00_15(0x10,Y14) \
+ PRECALC_00_15(0x20,Y13) \
+ PRECALC_00_15(0x30,Y12) \
+ PRECALC_16_31(Y8,Y12,Y13,Y14,Y15,0,0x80) \
+ PRECALC_16_31(Y7,Y8,Y12,Y13,Y14,0x20,0xa0) \
+ PRECALC_16_31(Y5,Y7,Y8,Y12,Y13,0x20,0xc0) \
+ PRECALC_16_31(Y3,Y5,Y7,Y8,Y12,0x20,0xe0) \
+ PRECALC_32_79(Y15,Y3,Y5,Y8,Y14,0x20,0x100) \
+ PRECALC_32_79(Y14,Y15,Y3,Y7,Y13,0x20,0x120) \
+ PRECALC_32_79(Y13,Y14,Y15,Y5,Y12,0x40,0x140) \
+ PRECALC_32_79(Y12,Y13,Y14,Y3,Y8,0x40,0x160) \
+ PRECALC_32_79(Y8,Y12,Y13,Y15,Y7,0x40,0x180) \
+ PRECALC_32_79(Y7,Y8,Y12,Y14,Y5,0x40,0x1a0) \
+ PRECALC_32_79(Y5,Y7,Y8,Y13,Y3,0x40,0x1c0) \
+ PRECALC_32_79(Y3,Y5,Y7,Y12,Y15,0x60,0x1e0) \
+ PRECALC_32_79(Y15,Y3,Y5,Y8,Y14,0x60,0x200) \
+ PRECALC_32_79(Y14,Y15,Y3,Y7,Y13,0x60,0x220) \
+ PRECALC_32_79(Y13,Y14,Y15,Y5,Y12,0x60,0x240) \
+ PRECALC_32_79(Y12,Y13,Y14,Y3,Y8,0x60,0x260)
+
+// Macros calculating individual rounds have general form
+// CALC_ROUND_PRE + PRECALC_ROUND + CALC_ROUND_POST
+// CALC_ROUND_{PRE,POST} macros follow
+
+#define CALC_F1_PRE(OFFSET,REG_A,REG_B,REG_C,REG_E) \
+ ADDL OFFSET(R15),REG_E \
+ ANDNL REG_C,REG_A,BP \
+ LEAL (REG_E)(REG_B*1), REG_E \ // Add F from the previous round
+ RORXL $0x1b, REG_A, R12 \
+ RORXL $2, REG_A, REG_B // for next round
+
+// Calculate F for the next round
+#define CALC_F1_POST(REG_A,REG_B,REG_E) \
+ ANDL REG_B,REG_A \ // b&c
+ XORL BP, REG_A \ // F1 = (b&c) ^ (~b&d)
+ LEAL (REG_E)(R12*1), REG_E // E += A >>> 5
+
+
+// Registers are cyclically rotated DX -> AX -> DI -> SI -> BX -> CX
+#define CALC_0 \
+ MOVL SI, BX \ // Precalculating first round
+ RORXL $2, SI, SI \
+ ANDNL AX, BX, BP \
+ ANDL DI, BX \
+ XORL BP, BX \
+ CALC_F1_PRE(0x0,CX,BX,DI,DX) \
+ PRECALC_0(0x80) \
+ CALC_F1_POST(CX,SI,DX)
+
+#define CALC_1 \
+ CALC_F1_PRE(0x4,DX,CX,SI,AX) \
+ PRECALC_1(0x80) \
+ CALC_F1_POST(DX,BX,AX)
+
+#define CALC_2 \
+ CALC_F1_PRE(0x8,AX,DX,BX,DI) \
+ PRECALC_2(Y15) \
+ CALC_F1_POST(AX,CX,DI)
+
+#define CALC_3 \
+ CALC_F1_PRE(0xc,DI,AX,CX,SI) \
+ CALC_F1_POST(DI,DX,SI)
+
+#define CALC_4 \
+ CALC_F1_PRE(0x20,SI,DI,DX,BX) \
+ PRECALC_4(Y15,0x0) \
+ CALC_F1_POST(SI,AX,BX)
+
+#define CALC_5 \
+ CALC_F1_PRE(0x24,BX,SI,AX,CX) \
+ CALC_F1_POST(BX,DI,CX)
+
+#define CALC_6 \
+ CALC_F1_PRE(0x28,CX,BX,DI,DX) \
+ CALC_F1_POST(CX,SI,DX)
+
+#define CALC_7 \
+ CALC_F1_PRE(0x2c,DX,CX,SI,AX) \
+ PRECALC_7(0x0) \
+ CALC_F1_POST(DX,BX,AX)
+
+#define CALC_8 \
+ CALC_F1_PRE(0x40,AX,DX,BX,DI) \
+ PRECALC_0(0x90) \
+ CALC_F1_POST(AX,CX,DI)
+
+#define CALC_9 \
+ CALC_F1_PRE(0x44,DI,AX,CX,SI) \
+ PRECALC_1(0x90) \
+ CALC_F1_POST(DI,DX,SI)
+
+#define CALC_10 \
+ CALC_F1_PRE(0x48,SI,DI,DX,BX) \
+ PRECALC_2(Y14) \
+ CALC_F1_POST(SI,AX,BX)
+
+#define CALC_11 \
+ CALC_F1_PRE(0x4c,BX,SI,AX,CX) \
+ CALC_F1_POST(BX,DI,CX)
+
+#define CALC_12 \
+ CALC_F1_PRE(0x60,CX,BX,DI,DX) \
+ PRECALC_4(Y14,0x0) \
+ CALC_F1_POST(CX,SI,DX)
+
+#define CALC_13 \
+ CALC_F1_PRE(0x64,DX,CX,SI,AX) \
+ CALC_F1_POST(DX,BX,AX)
+
+#define CALC_14 \
+ CALC_F1_PRE(0x68,AX,DX,BX,DI) \
+ CALC_F1_POST(AX,CX,DI)
+
+#define CALC_15 \
+ CALC_F1_PRE(0x6c,DI,AX,CX,SI) \
+ PRECALC_7(0x10) \
+ CALC_F1_POST(DI,DX,SI)
+
+#define CALC_16 \
+ CALC_F1_PRE(0x80,SI,DI,DX,BX) \
+ PRECALC_0(0xa0) \
+ CALC_F1_POST(SI,AX,BX)
+
+#define CALC_17 \
+ CALC_F1_PRE(0x84,BX,SI,AX,CX) \
+ PRECALC_1(0xa0) \
+ CALC_F1_POST(BX,DI,CX)
+
+#define CALC_18 \
+ CALC_F1_PRE(0x88,CX,BX,DI,DX) \
+ PRECALC_2(Y13) \
+ CALC_F1_POST(CX,SI,DX)
+
+
+#define CALC_F2_PRE(OFFSET,REG_A,REG_B,REG_E) \
+ ADDL OFFSET(R15),REG_E \
+ LEAL (REG_E)(REG_B*1), REG_E \ // Add F from the previous round
+ RORXL $0x1b, REG_A, R12 \
+ RORXL $2, REG_A, REG_B // for next round
+
+#define CALC_F2_POST(REG_A,REG_B,REG_C,REG_E) \
+ XORL REG_B, REG_A \
+ ADDL R12, REG_E \
+ XORL REG_C, REG_A
+
+#define CALC_19 \
+ CALC_F2_PRE(0x8c,DX,CX,AX) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_20 \
+ CALC_F2_PRE(0xa0,AX,DX,DI) \
+ PRECALC_4(Y13,0x0) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_21 \
+ CALC_F2_PRE(0xa4,DI,AX,SI) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_22 \
+ CALC_F2_PRE(0xa8,SI,DI,BX) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_23 \
+ CALC_F2_PRE(0xac,BX,SI,CX) \
+ PRECALC_7(0x20) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_24 \
+ CALC_F2_PRE(0xc0,CX,BX,DX) \
+ PRECALC_0(0xb0) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_25 \
+ CALC_F2_PRE(0xc4,DX,CX,AX) \
+ PRECALC_1(0xb0) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_26 \
+ CALC_F2_PRE(0xc8,AX,DX,DI) \
+ PRECALC_2(Y12) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_27 \
+ CALC_F2_PRE(0xcc,DI,AX,SI) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_28 \
+ CALC_F2_PRE(0xe0,SI,DI,BX) \
+ PRECALC_4(Y12,0x0) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_29 \
+ CALC_F2_PRE(0xe4,BX,SI,CX) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_30 \
+ CALC_F2_PRE(0xe8,CX,BX,DX) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_31 \
+ CALC_F2_PRE(0xec,DX,CX,AX) \
+ PRECALC_7(0x30) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_32 \
+ CALC_F2_PRE(0x100,AX,DX,DI) \
+ PRECALC_16(Y15,Y14,Y12,Y8) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_33 \
+ CALC_F2_PRE(0x104,DI,AX,SI) \
+ PRECALC_17(Y15,Y13,Y8) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_34 \
+ CALC_F2_PRE(0x108,SI,DI,BX) \
+ PRECALC_18(Y8) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_35 \
+ CALC_F2_PRE(0x10c,BX,SI,CX) \
+ PRECALC_19(Y8) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_36 \
+ CALC_F2_PRE(0x120,CX,BX,DX) \
+ PRECALC_20(Y8) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_37 \
+ CALC_F2_PRE(0x124,DX,CX,AX) \
+ PRECALC_21(Y8) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_38 \
+ CALC_F2_PRE(0x128,AX,DX,DI) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+
+#define CALC_F3_PRE(OFFSET,REG_E) \
+ ADDL OFFSET(R15),REG_E
+
+#define CALC_F3_POST(REG_A,REG_B,REG_C,REG_E,REG_TB) \
+ LEAL (REG_E)(REG_TB*1), REG_E \ // Add F from the previous round
+ MOVL REG_B, BP \
+ ORL REG_A, BP \
+ RORXL $0x1b, REG_A, R12 \
+ RORXL $2, REG_A, REG_TB \
+ ANDL REG_C, BP \ // Calculate F for the next round
+ ANDL REG_B, REG_A \
+ ORL BP, REG_A \
+ ADDL R12, REG_E
+
+#define CALC_39 \
+ CALC_F3_PRE(0x12c,SI) \
+ PRECALC_23(Y8,0x0,0x80) \
+ CALC_F3_POST(DI,DX,CX,SI,AX)
+
+#define CALC_40 \
+ CALC_F3_PRE(0x140,BX) \
+ PRECALC_16(Y14,Y13,Y8,Y7) \
+ CALC_F3_POST(SI,AX,DX,BX,DI)
+
+#define CALC_41 \
+ CALC_F3_PRE(0x144,CX) \
+ PRECALC_17(Y14,Y12,Y7) \
+ CALC_F3_POST(BX,DI,AX,CX,SI)
+
+#define CALC_42 \
+ CALC_F3_PRE(0x148,DX) \
+ PRECALC_18(Y7) \
+ CALC_F3_POST(CX,SI,DI,DX,BX)
+
+#define CALC_43 \
+ CALC_F3_PRE(0x14c,AX) \
+ PRECALC_19(Y7) \
+ CALC_F3_POST(DX,BX,SI,AX,CX)
+
+#define CALC_44 \
+ CALC_F3_PRE(0x160,DI) \
+ PRECALC_20(Y7) \
+ CALC_F3_POST(AX,CX,BX,DI,DX)
+
+#define CALC_45 \
+ CALC_F3_PRE(0x164,SI) \
+ PRECALC_21(Y7) \
+ CALC_F3_POST(DI,DX,CX,SI,AX)
+
+#define CALC_46 \
+ CALC_F3_PRE(0x168,BX) \
+ CALC_F3_POST(SI,AX,DX,BX,DI)
+
+#define CALC_47 \
+ CALC_F3_PRE(0x16c,CX) \
+ VPXOR Y9, Y0, Y7 \
+ VPADDD 0x20(R8), Y7, Y0 \
+ VMOVDQU Y0, 0xa0(R14) \
+ CALC_F3_POST(BX,DI,AX,CX,SI)
+
+#define CALC_48 \
+ CALC_F3_PRE(0x180,DX) \
+ PRECALC_16(Y13,Y12,Y7,Y5) \
+ CALC_F3_POST(CX,SI,DI,DX,BX)
+
+#define CALC_49 \
+ CALC_F3_PRE(0x184,AX) \
+ PRECALC_17(Y13,Y8,Y5) \
+ CALC_F3_POST(DX,BX,SI,AX,CX)
+
+#define CALC_50 \
+ CALC_F3_PRE(0x188,DI) \
+ PRECALC_18(Y5) \
+ CALC_F3_POST(AX,CX,BX,DI,DX)
+
+#define CALC_51 \
+ CALC_F3_PRE(0x18c,SI) \
+ PRECALC_19(Y5) \
+ CALC_F3_POST(DI,DX,CX,SI,AX)
+
+#define CALC_52 \
+ CALC_F3_PRE(0x1a0,BX) \
+ PRECALC_20(Y5) \
+ CALC_F3_POST(SI,AX,DX,BX,DI)
+
+#define CALC_53 \
+ CALC_F3_PRE(0x1a4,CX) \
+ PRECALC_21(Y5) \
+ CALC_F3_POST(BX,DI,AX,CX,SI)
+
+#define CALC_54 \
+ CALC_F3_PRE(0x1a8,DX) \
+ CALC_F3_POST(CX,SI,DI,DX,BX)
+
+#define CALC_55 \
+ CALC_F3_PRE(0x1ac,AX) \
+ PRECALC_23(Y5,0x20,0xc0) \
+ CALC_F3_POST(DX,BX,SI,AX,CX)
+
+#define CALC_56 \
+ CALC_F3_PRE(0x1c0,DI) \
+ PRECALC_16(Y12,Y8,Y5,Y3) \
+ CALC_F3_POST(AX,CX,BX,DI,DX)
+
+#define CALC_57 \
+ CALC_F3_PRE(0x1c4,SI) \
+ PRECALC_17(Y12,Y7,Y3) \
+ CALC_F3_POST(DI,DX,CX,SI,AX)
+
+#define CALC_58 \
+ CALC_F3_PRE(0x1c8,BX) \
+ PRECALC_18(Y3) \
+ CALC_F3_POST(SI,AX,DX,BX,DI)
+
+#define CALC_59 \
+ CALC_F2_PRE(0x1cc,BX,SI,CX) \
+ PRECALC_19(Y3) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_60 \
+ CALC_F2_PRE(0x1e0,CX,BX,DX) \
+ PRECALC_20(Y3) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_61 \
+ CALC_F2_PRE(0x1e4,DX,CX,AX) \
+ PRECALC_21(Y3) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_62 \
+ CALC_F2_PRE(0x1e8,AX,DX,DI) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_63 \
+ CALC_F2_PRE(0x1ec,DI,AX,SI) \
+ PRECALC_23(Y3,0x20,0xe0) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_64 \
+ CALC_F2_PRE(0x200,SI,DI,BX) \
+ PRECALC_32(Y5,Y3) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_65 \
+ CALC_F2_PRE(0x204,BX,SI,CX) \
+ PRECALC_33(Y14,Y15) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_66 \
+ CALC_F2_PRE(0x208,CX,BX,DX) \
+ PRECALC_34(Y8) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_67 \
+ CALC_F2_PRE(0x20c,DX,CX,AX) \
+ PRECALC_35(Y15) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_68 \
+ CALC_F2_PRE(0x220,AX,DX,DI) \
+ PRECALC_36(Y15) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_69 \
+ CALC_F2_PRE(0x224,DI,AX,SI) \
+ PRECALC_37(Y15) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_70 \
+ CALC_F2_PRE(0x228,SI,DI,BX) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_71 \
+ CALC_F2_PRE(0x22c,BX,SI,CX) \
+ PRECALC_39(Y15,0x20,0x100) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_72 \
+ CALC_F2_PRE(0x240,CX,BX,DX) \
+ PRECALC_32(Y3,Y15) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_73 \
+ CALC_F2_PRE(0x244,DX,CX,AX) \
+ PRECALC_33(Y13,Y14) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_74 \
+ CALC_F2_PRE(0x248,AX,DX,DI) \
+ PRECALC_34(Y7) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_75 \
+ CALC_F2_PRE(0x24c,DI,AX,SI) \
+ PRECALC_35(Y14) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_76 \
+ CALC_F2_PRE(0x260,SI,DI,BX) \
+ PRECALC_36(Y14) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_77 \
+ CALC_F2_PRE(0x264,BX,SI,CX) \
+ PRECALC_37(Y14) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_78 \
+ CALC_F2_PRE(0x268,CX,BX,DX) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_79 \
+ ADDL 0x26c(R15), AX \
+ LEAL (AX)(CX*1), AX \
+ RORXL $0x1b, DX, R12 \
+ PRECALC_39(Y14,0x20,0x120) \
+ ADDL R12, AX
+
+// Similar to CALC_0
+#define CALC_80 \
+ MOVL CX, DX \
+ RORXL $2, CX, CX \
+ ANDNL SI, DX, BP \
+ ANDL BX, DX \
+ XORL BP, DX \
+ CALC_F1_PRE(0x10,AX,DX,BX,DI) \
+ PRECALC_32(Y15,Y14) \
+ CALC_F1_POST(AX,CX,DI)
+
+#define CALC_81 \
+ CALC_F1_PRE(0x14,DI,AX,CX,SI) \
+ PRECALC_33(Y12,Y13) \
+ CALC_F1_POST(DI,DX,SI)
+
+#define CALC_82 \
+ CALC_F1_PRE(0x18,SI,DI,DX,BX) \
+ PRECALC_34(Y5) \
+ CALC_F1_POST(SI,AX,BX)
+
+#define CALC_83 \
+ CALC_F1_PRE(0x1c,BX,SI,AX,CX) \
+ PRECALC_35(Y13) \
+ CALC_F1_POST(BX,DI,CX)
+
+#define CALC_84 \
+ CALC_F1_PRE(0x30,CX,BX,DI,DX) \
+ PRECALC_36(Y13) \
+ CALC_F1_POST(CX,SI,DX)
+
+#define CALC_85 \
+ CALC_F1_PRE(0x34,DX,CX,SI,AX) \
+ PRECALC_37(Y13) \
+ CALC_F1_POST(DX,BX,AX)
+
+#define CALC_86 \
+ CALC_F1_PRE(0x38,AX,DX,BX,DI) \
+ CALC_F1_POST(AX,CX,DI)
+
+#define CALC_87 \
+ CALC_F1_PRE(0x3c,DI,AX,CX,SI) \
+ PRECALC_39(Y13,0x40,0x140) \
+ CALC_F1_POST(DI,DX,SI)
+
+#define CALC_88 \
+ CALC_F1_PRE(0x50,SI,DI,DX,BX) \
+ PRECALC_32(Y14,Y13) \
+ CALC_F1_POST(SI,AX,BX)
+
+#define CALC_89 \
+ CALC_F1_PRE(0x54,BX,SI,AX,CX) \
+ PRECALC_33(Y8,Y12) \
+ CALC_F1_POST(BX,DI,CX)
+
+#define CALC_90 \
+ CALC_F1_PRE(0x58,CX,BX,DI,DX) \
+ PRECALC_34(Y3) \
+ CALC_F1_POST(CX,SI,DX)
+
+#define CALC_91 \
+ CALC_F1_PRE(0x5c,DX,CX,SI,AX) \
+ PRECALC_35(Y12) \
+ CALC_F1_POST(DX,BX,AX)
+
+#define CALC_92 \
+ CALC_F1_PRE(0x70,AX,DX,BX,DI) \
+ PRECALC_36(Y12) \
+ CALC_F1_POST(AX,CX,DI)
+
+#define CALC_93 \
+ CALC_F1_PRE(0x74,DI,AX,CX,SI) \
+ PRECALC_37(Y12) \
+ CALC_F1_POST(DI,DX,SI)
+
+#define CALC_94 \
+ CALC_F1_PRE(0x78,SI,DI,DX,BX) \
+ CALC_F1_POST(SI,AX,BX)
+
+#define CALC_95 \
+ CALC_F1_PRE(0x7c,BX,SI,AX,CX) \
+ PRECALC_39(Y12,0x40,0x160) \
+ CALC_F1_POST(BX,DI,CX)
+
+#define CALC_96 \
+ CALC_F1_PRE(0x90,CX,BX,DI,DX) \
+ PRECALC_32(Y13,Y12) \
+ CALC_F1_POST(CX,SI,DX)
+
+#define CALC_97 \
+ CALC_F1_PRE(0x94,DX,CX,SI,AX) \
+ PRECALC_33(Y7,Y8) \
+ CALC_F1_POST(DX,BX,AX)
+
+#define CALC_98 \
+ CALC_F1_PRE(0x98,AX,DX,BX,DI) \
+ PRECALC_34(Y15) \
+ CALC_F1_POST(AX,CX,DI)
+
+#define CALC_99 \
+ CALC_F2_PRE(0x9c,DI,AX,SI) \
+ PRECALC_35(Y8) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_100 \
+ CALC_F2_PRE(0xb0,SI,DI,BX) \
+ PRECALC_36(Y8) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_101 \
+ CALC_F2_PRE(0xb4,BX,SI,CX) \
+ PRECALC_37(Y8) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_102 \
+ CALC_F2_PRE(0xb8,CX,BX,DX) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_103 \
+ CALC_F2_PRE(0xbc,DX,CX,AX) \
+ PRECALC_39(Y8,0x40,0x180) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_104 \
+ CALC_F2_PRE(0xd0,AX,DX,DI) \
+ PRECALC_32(Y12,Y8) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_105 \
+ CALC_F2_PRE(0xd4,DI,AX,SI) \
+ PRECALC_33(Y5,Y7) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_106 \
+ CALC_F2_PRE(0xd8,SI,DI,BX) \
+ PRECALC_34(Y14) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_107 \
+ CALC_F2_PRE(0xdc,BX,SI,CX) \
+ PRECALC_35(Y7) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_108 \
+ CALC_F2_PRE(0xf0,CX,BX,DX) \
+ PRECALC_36(Y7) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_109 \
+ CALC_F2_PRE(0xf4,DX,CX,AX) \
+ PRECALC_37(Y7) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_110 \
+ CALC_F2_PRE(0xf8,AX,DX,DI) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_111 \
+ CALC_F2_PRE(0xfc,DI,AX,SI) \
+ PRECALC_39(Y7,0x40,0x1a0) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_112 \
+ CALC_F2_PRE(0x110,SI,DI,BX) \
+ PRECALC_32(Y8,Y7) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_113 \
+ CALC_F2_PRE(0x114,BX,SI,CX) \
+ PRECALC_33(Y3,Y5) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_114 \
+ CALC_F2_PRE(0x118,CX,BX,DX) \
+ PRECALC_34(Y13) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_115 \
+ CALC_F2_PRE(0x11c,DX,CX,AX) \
+ PRECALC_35(Y5) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_116 \
+ CALC_F2_PRE(0x130,AX,DX,DI) \
+ PRECALC_36(Y5) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_117 \
+ CALC_F2_PRE(0x134,DI,AX,SI) \
+ PRECALC_37(Y5) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_118 \
+ CALC_F2_PRE(0x138,SI,DI,BX) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_119 \
+ CALC_F3_PRE(0x13c,CX) \
+ PRECALC_39(Y5,0x40,0x1c0) \
+ CALC_F3_POST(BX,DI,AX,CX,SI)
+
+#define CALC_120 \
+ CALC_F3_PRE(0x150,DX) \
+ PRECALC_32(Y7,Y5) \
+ CALC_F3_POST(CX,SI,DI,DX,BX)
+
+#define CALC_121 \
+ CALC_F3_PRE(0x154,AX) \
+ PRECALC_33(Y15,Y3) \
+ CALC_F3_POST(DX,BX,SI,AX,CX)
+
+#define CALC_122 \
+ CALC_F3_PRE(0x158,DI) \
+ PRECALC_34(Y12) \
+ CALC_F3_POST(AX,CX,BX,DI,DX)
+
+#define CALC_123 \
+ CALC_F3_PRE(0x15c,SI) \
+ PRECALC_35(Y3) \
+ CALC_F3_POST(DI,DX,CX,SI,AX)
+
+#define CALC_124 \
+ CALC_F3_PRE(0x170,BX) \
+ PRECALC_36(Y3) \
+ CALC_F3_POST(SI,AX,DX,BX,DI)
+
+#define CALC_125 \
+ CALC_F3_PRE(0x174,CX) \
+ PRECALC_37(Y3) \
+ CALC_F3_POST(BX,DI,AX,CX,SI)
+
+#define CALC_126 \
+ CALC_F3_PRE(0x178,DX) \
+ CALC_F3_POST(CX,SI,DI,DX,BX)
+
+#define CALC_127 \
+ CALC_F3_PRE(0x17c,AX) \
+ PRECALC_39(Y3,0x60,0x1e0) \
+ CALC_F3_POST(DX,BX,SI,AX,CX)
+
+#define CALC_128 \
+ CALC_F3_PRE(0x190,DI) \
+ PRECALC_32(Y5,Y3) \
+ CALC_F3_POST(AX,CX,BX,DI,DX)
+
+#define CALC_129 \
+ CALC_F3_PRE(0x194,SI) \
+ PRECALC_33(Y14,Y15) \
+ CALC_F3_POST(DI,DX,CX,SI,AX)
+
+#define CALC_130 \
+ CALC_F3_PRE(0x198,BX) \
+ PRECALC_34(Y8) \
+ CALC_F3_POST(SI,AX,DX,BX,DI)
+
+#define CALC_131 \
+ CALC_F3_PRE(0x19c,CX) \
+ PRECALC_35(Y15) \
+ CALC_F3_POST(BX,DI,AX,CX,SI)
+
+#define CALC_132 \
+ CALC_F3_PRE(0x1b0,DX) \
+ PRECALC_36(Y15) \
+ CALC_F3_POST(CX,SI,DI,DX,BX)
+
+#define CALC_133 \
+ CALC_F3_PRE(0x1b4,AX) \
+ PRECALC_37(Y15) \
+ CALC_F3_POST(DX,BX,SI,AX,CX)
+
+#define CALC_134 \
+ CALC_F3_PRE(0x1b8,DI) \
+ CALC_F3_POST(AX,CX,BX,DI,DX)
+
+#define CALC_135 \
+ CALC_F3_PRE(0x1bc,SI) \
+ PRECALC_39(Y15,0x60,0x200) \
+ CALC_F3_POST(DI,DX,CX,SI,AX)
+
+#define CALC_136 \
+ CALC_F3_PRE(0x1d0,BX) \
+ PRECALC_32(Y3,Y15) \
+ CALC_F3_POST(SI,AX,DX,BX,DI)
+
+#define CALC_137 \
+ CALC_F3_PRE(0x1d4,CX) \
+ PRECALC_33(Y13,Y14) \
+ CALC_F3_POST(BX,DI,AX,CX,SI)
+
+#define CALC_138 \
+ CALC_F3_PRE(0x1d8,DX) \
+ PRECALC_34(Y7) \
+ CALC_F3_POST(CX,SI,DI,DX,BX)
+
+#define CALC_139 \
+ CALC_F2_PRE(0x1dc,DX,CX,AX) \
+ PRECALC_35(Y14) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_140 \
+ CALC_F2_PRE(0x1f0,AX,DX,DI) \
+ PRECALC_36(Y14) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_141 \
+ CALC_F2_PRE(0x1f4,DI,AX,SI) \
+ PRECALC_37(Y14) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_142 \
+ CALC_F2_PRE(0x1f8,SI,DI,BX) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_143 \
+ CALC_F2_PRE(0x1fc,BX,SI,CX) \
+ PRECALC_39(Y14,0x60,0x220) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_144 \
+ CALC_F2_PRE(0x210,CX,BX,DX) \
+ PRECALC_32(Y15,Y14) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_145 \
+ CALC_F2_PRE(0x214,DX,CX,AX) \
+ PRECALC_33(Y12,Y13) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_146 \
+ CALC_F2_PRE(0x218,AX,DX,DI) \
+ PRECALC_34(Y5) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_147 \
+ CALC_F2_PRE(0x21c,DI,AX,SI) \
+ PRECALC_35(Y13) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_148 \
+ CALC_F2_PRE(0x230,SI,DI,BX) \
+ PRECALC_36(Y13) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_149 \
+ CALC_F2_PRE(0x234,BX,SI,CX) \
+ PRECALC_37(Y13) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_150 \
+ CALC_F2_PRE(0x238,CX,BX,DX) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_151 \
+ CALC_F2_PRE(0x23c,DX,CX,AX) \
+ PRECALC_39(Y13,0x60,0x240) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_152 \
+ CALC_F2_PRE(0x250,AX,DX,DI) \
+ PRECALC_32(Y14,Y13) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_153 \
+ CALC_F2_PRE(0x254,DI,AX,SI) \
+ PRECALC_33(Y8,Y12) \
+ CALC_F2_POST(DI,DX,CX,SI)
+
+#define CALC_154 \
+ CALC_F2_PRE(0x258,SI,DI,BX) \
+ PRECALC_34(Y3) \
+ CALC_F2_POST(SI,AX,DX,BX)
+
+#define CALC_155 \
+ CALC_F2_PRE(0x25c,BX,SI,CX) \
+ PRECALC_35(Y12) \
+ CALC_F2_POST(BX,DI,AX,CX)
+
+#define CALC_156 \
+ CALC_F2_PRE(0x270,CX,BX,DX) \
+ PRECALC_36(Y12) \
+ CALC_F2_POST(CX,SI,DI,DX)
+
+#define CALC_157 \
+ CALC_F2_PRE(0x274,DX,CX,AX) \
+ PRECALC_37(Y12) \
+ CALC_F2_POST(DX,BX,SI,AX)
+
+#define CALC_158 \
+ CALC_F2_PRE(0x278,AX,DX,DI) \
+ CALC_F2_POST(AX,CX,BX,DI)
+
+#define CALC_159 \
+ ADDL 0x27c(R15),SI \
+ LEAL (SI)(AX*1), SI \
+ RORXL $0x1b, DI, R12 \
+ PRECALC_39(Y12,0x60,0x260) \
+ ADDL R12, SI
+
+
+
+#define CALC \
+ MOVL (R9), CX \
+ MOVL 4(R9), SI \
+ MOVL 8(R9), DI \
+ MOVL 12(R9), AX \
+ MOVL 16(R9), DX \
+ MOVQ SP, R14 \
+ LEAQ (2*4*80+32)(SP), R15 \
+ PRECALC \ // Precalc WK for first 2 blocks
+ XCHGQ R15, R14 \
+loop: \ // this loops is unrolled
+ CMPQ R10, R8 \ // we use R8 value (set below) as a signal of a last block
+ JNE begin \
+ VZEROUPPER \
+ RET \
+begin: \
+ CALC_0 \
+ CALC_1 \
+ CALC_2 \
+ CALC_3 \
+ CALC_4 \
+ CALC_5 \
+ CALC_6 \
+ CALC_7 \
+ CALC_8 \
+ CALC_9 \
+ CALC_10 \
+ CALC_11 \
+ CALC_12 \
+ CALC_13 \
+ CALC_14 \
+ CALC_15 \
+ CALC_16 \
+ CALC_17 \
+ CALC_18 \
+ CALC_19 \
+ CALC_20 \
+ CALC_21 \
+ CALC_22 \
+ CALC_23 \
+ CALC_24 \
+ CALC_25 \
+ CALC_26 \
+ CALC_27 \
+ CALC_28 \
+ CALC_29 \
+ CALC_30 \
+ CALC_31 \
+ CALC_32 \
+ CALC_33 \
+ CALC_34 \
+ CALC_35 \
+ CALC_36 \
+ CALC_37 \
+ CALC_38 \
+ CALC_39 \
+ CALC_40 \
+ CALC_41 \
+ CALC_42 \
+ CALC_43 \
+ CALC_44 \
+ CALC_45 \
+ CALC_46 \
+ CALC_47 \
+ CALC_48 \
+ CALC_49 \
+ CALC_50 \
+ CALC_51 \
+ CALC_52 \
+ CALC_53 \
+ CALC_54 \
+ CALC_55 \
+ CALC_56 \
+ CALC_57 \
+ CALC_58 \
+ CALC_59 \
+ ADDQ $128, R10 \ // move to next even-64-byte block
+ CMPQ R10, R11 \ // is current block the last one?
+ CMOVQCC R8, R10 \ // signal the last iteration smartly
+ CALC_60 \
+ CALC_61 \
+ CALC_62 \
+ CALC_63 \
+ CALC_64 \
+ CALC_65 \
+ CALC_66 \
+ CALC_67 \
+ CALC_68 \
+ CALC_69 \
+ CALC_70 \
+ CALC_71 \
+ CALC_72 \
+ CALC_73 \
+ CALC_74 \
+ CALC_75 \
+ CALC_76 \
+ CALC_77 \
+ CALC_78 \
+ CALC_79 \
+ UPDATE_HASH(AX,DX,BX,SI,DI) \
+ CMPQ R10, R8 \ // is current block the last one?
+ JE loop\
+ MOVL DX, CX \
+ CALC_80 \
+ CALC_81 \
+ CALC_82 \
+ CALC_83 \
+ CALC_84 \
+ CALC_85 \
+ CALC_86 \
+ CALC_87 \
+ CALC_88 \
+ CALC_89 \
+ CALC_90 \
+ CALC_91 \
+ CALC_92 \
+ CALC_93 \
+ CALC_94 \
+ CALC_95 \
+ CALC_96 \
+ CALC_97 \
+ CALC_98 \
+ CALC_99 \
+ CALC_100 \
+ CALC_101 \
+ CALC_102 \
+ CALC_103 \
+ CALC_104 \
+ CALC_105 \
+ CALC_106 \
+ CALC_107 \
+ CALC_108 \
+ CALC_109 \
+ CALC_110 \
+ CALC_111 \
+ CALC_112 \
+ CALC_113 \
+ CALC_114 \
+ CALC_115 \
+ CALC_116 \
+ CALC_117 \
+ CALC_118 \
+ CALC_119 \
+ CALC_120 \
+ CALC_121 \
+ CALC_122 \
+ CALC_123 \
+ CALC_124 \
+ CALC_125 \
+ CALC_126 \
+ CALC_127 \
+ CALC_128 \
+ CALC_129 \
+ CALC_130 \
+ CALC_131 \
+ CALC_132 \
+ CALC_133 \
+ CALC_134 \
+ CALC_135 \
+ CALC_136 \
+ CALC_137 \
+ CALC_138 \
+ CALC_139 \
+ ADDQ $128, R13 \ //move to next even-64-byte block
+ CMPQ R13, R11 \ //is current block the last one?
+ CMOVQCC R8, R10 \
+ CALC_140 \
+ CALC_141 \
+ CALC_142 \
+ CALC_143 \
+ CALC_144 \
+ CALC_145 \
+ CALC_146 \
+ CALC_147 \
+ CALC_148 \
+ CALC_149 \
+ CALC_150 \
+ CALC_151 \
+ CALC_152 \
+ CALC_153 \
+ CALC_154 \
+ CALC_155 \
+ CALC_156 \
+ CALC_157 \
+ CALC_158 \
+ CALC_159 \
+ UPDATE_HASH(SI,DI,DX,CX,BX) \
+ MOVL SI, R12 \ //Reset state for AVX2 reg permutation
+ MOVL DI, SI \
+ MOVL DX, DI \
+ MOVL BX, DX \
+ MOVL CX, AX \
+ MOVL R12, CX \
+ XCHGQ R15, R14 \
+ JMP loop
+
+
+
+TEXT ·blockAVX2(SB),$1408-32
+
+ MOVQ dig+0(FP), DI
+ MOVQ p_base+8(FP), SI
+ MOVQ p_len+16(FP), DX
+ SHRQ $6, DX
+ SHLQ $6, DX
+
+ MOVQ $K_XMM_AR<>(SB), R8
+
+ MOVQ DI, R9
+ MOVQ SI, R10
+ LEAQ 64(SI), R13
+
+ ADDQ SI, DX
+ ADDQ $64, DX
+ MOVQ DX, R11
+
+ CMPQ R13, R11
+ CMOVQCC R8, R13
+
+ VMOVDQU BSWAP_SHUFB_CTL<>(SB), Y10
+
+ CALC // RET is inside macros
+
+DATA K_XMM_AR<>+0x00(SB)/4,$0x5a827999
+DATA K_XMM_AR<>+0x04(SB)/4,$0x5a827999
+DATA K_XMM_AR<>+0x08(SB)/4,$0x5a827999
+DATA K_XMM_AR<>+0x0c(SB)/4,$0x5a827999
+DATA K_XMM_AR<>+0x10(SB)/4,$0x5a827999
+DATA K_XMM_AR<>+0x14(SB)/4,$0x5a827999
+DATA K_XMM_AR<>+0x18(SB)/4,$0x5a827999
+DATA K_XMM_AR<>+0x1c(SB)/4,$0x5a827999
+DATA K_XMM_AR<>+0x20(SB)/4,$0x6ed9eba1
+DATA K_XMM_AR<>+0x24(SB)/4,$0x6ed9eba1
+DATA K_XMM_AR<>+0x28(SB)/4,$0x6ed9eba1
+DATA K_XMM_AR<>+0x2c(SB)/4,$0x6ed9eba1
+DATA K_XMM_AR<>+0x30(SB)/4,$0x6ed9eba1
+DATA K_XMM_AR<>+0x34(SB)/4,$0x6ed9eba1
+DATA K_XMM_AR<>+0x38(SB)/4,$0x6ed9eba1
+DATA K_XMM_AR<>+0x3c(SB)/4,$0x6ed9eba1
+DATA K_XMM_AR<>+0x40(SB)/4,$0x8f1bbcdc
+DATA K_XMM_AR<>+0x44(SB)/4,$0x8f1bbcdc
+DATA K_XMM_AR<>+0x48(SB)/4,$0x8f1bbcdc
+DATA K_XMM_AR<>+0x4c(SB)/4,$0x8f1bbcdc
+DATA K_XMM_AR<>+0x50(SB)/4,$0x8f1bbcdc
+DATA K_XMM_AR<>+0x54(SB)/4,$0x8f1bbcdc
+DATA K_XMM_AR<>+0x58(SB)/4,$0x8f1bbcdc
+DATA K_XMM_AR<>+0x5c(SB)/4,$0x8f1bbcdc
+DATA K_XMM_AR<>+0x60(SB)/4,$0xca62c1d6
+DATA K_XMM_AR<>+0x64(SB)/4,$0xca62c1d6
+DATA K_XMM_AR<>+0x68(SB)/4,$0xca62c1d6
+DATA K_XMM_AR<>+0x6c(SB)/4,$0xca62c1d6
+DATA K_XMM_AR<>+0x70(SB)/4,$0xca62c1d6
+DATA K_XMM_AR<>+0x74(SB)/4,$0xca62c1d6
+DATA K_XMM_AR<>+0x78(SB)/4,$0xca62c1d6
+DATA K_XMM_AR<>+0x7c(SB)/4,$0xca62c1d6
+GLOBL K_XMM_AR<>(SB),RODATA,$128
+
+DATA BSWAP_SHUFB_CTL<>+0x00(SB)/4,$0x00010203
+DATA BSWAP_SHUFB_CTL<>+0x04(SB)/4,$0x04050607
+DATA BSWAP_SHUFB_CTL<>+0x08(SB)/4,$0x08090a0b
+DATA BSWAP_SHUFB_CTL<>+0x0c(SB)/4,$0x0c0d0e0f
+DATA BSWAP_SHUFB_CTL<>+0x10(SB)/4,$0x00010203
+DATA BSWAP_SHUFB_CTL<>+0x14(SB)/4,$0x04050607
+DATA BSWAP_SHUFB_CTL<>+0x18(SB)/4,$0x08090a0b
+DATA BSWAP_SHUFB_CTL<>+0x1c(SB)/4,$0x0c0d0e0f
+GLOBL BSWAP_SHUFB_CTL<>(SB),RODATA,$32
diff --git a/contrib/go/_std_1.20/src/crypto/sha1/sha1block_arm64.go b/contrib/go/_std_1.21/src/crypto/sha1/sha1block_arm64.go
index 08d3df0000..08d3df0000 100644
--- a/contrib/go/_std_1.20/src/crypto/sha1/sha1block_arm64.go
+++ b/contrib/go/_std_1.21/src/crypto/sha1/sha1block_arm64.go
diff --git a/contrib/go/_std_1.20/src/crypto/sha1/sha1block_arm64.s b/contrib/go/_std_1.21/src/crypto/sha1/sha1block_arm64.s
index d56838464d..d56838464d 100644
--- a/contrib/go/_std_1.20/src/crypto/sha1/sha1block_arm64.s
+++ b/contrib/go/_std_1.21/src/crypto/sha1/sha1block_arm64.s
diff --git a/contrib/go/_std_1.21/src/crypto/sha1/ya.make b/contrib/go/_std_1.21/src/crypto/sha1/ya.make
new file mode 100644
index 0000000000..9997b6297a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/sha1/ya.make
@@ -0,0 +1,38 @@
+GO_LIBRARY()
+
+SRCS(
+ boring.go
+ sha1.go
+ sha1block.go
+)
+
+GO_TEST_SRCS(sha1_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+IF (ARCH_X86_64)
+ SRCS(
+ sha1block_amd64.go
+ sha1block_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ sha1block_arm64.go
+ sha1block_arm64.s
+ )
+ENDIF()
+
+IF (OS_LINUX AND ARCH_X86_64)
+ GO_XTEST_SRCS(issue15617_test.go)
+ENDIF()
+
+IF (OS_DARWIN AND ARCH_X86_64)
+ GO_XTEST_SRCS(issue15617_test.go)
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/sha256/sha256.go b/contrib/go/_std_1.21/src/crypto/sha256/sha256.go
index 2deafbc9fc..2deafbc9fc 100644
--- a/contrib/go/_std_1.20/src/crypto/sha256/sha256.go
+++ b/contrib/go/_std_1.21/src/crypto/sha256/sha256.go
diff --git a/contrib/go/_std_1.20/src/crypto/sha256/sha256block.go b/contrib/go/_std_1.21/src/crypto/sha256/sha256block.go
index bd2f9da93c..bd2f9da93c 100644
--- a/contrib/go/_std_1.20/src/crypto/sha256/sha256block.go
+++ b/contrib/go/_std_1.21/src/crypto/sha256/sha256block.go
diff --git a/contrib/go/_std_1.21/src/crypto/sha256/sha256block_amd64.go b/contrib/go/_std_1.21/src/crypto/sha256/sha256block_amd64.go
new file mode 100644
index 0000000000..b5d2c9b574
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/sha256/sha256block_amd64.go
@@ -0,0 +1,10 @@
+// Copyright 2017 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 sha256
+
+import "internal/cpu"
+
+var useAVX2 = cpu.X86.HasAVX2 && cpu.X86.HasBMI2
+var useSHA = useAVX2 && cpu.X86.HasSHA
diff --git a/contrib/go/_std_1.21/src/crypto/sha256/sha256block_amd64.s b/contrib/go/_std_1.21/src/crypto/sha256/sha256block_amd64.s
new file mode 100644
index 0000000000..bbde6285d1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/sha256/sha256block_amd64.s
@@ -0,0 +1,1173 @@
+// Copyright 2013 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.
+
+#include "textflag.h"
+
+// SHA256 block routine. See sha256block.go for Go equivalent.
+//
+// The algorithm is detailed in FIPS 180-4:
+//
+// https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
+
+// The avx2-version is described in an Intel White-Paper:
+// "Fast SHA-256 Implementations on Intel Architecture Processors"
+// To find it, surf to http://www.intel.com/p/en_US/embedded
+// and search for that title.
+// AVX2 version by Intel, same algorithm as code in Linux kernel:
+// https://github.com/torvalds/linux/blob/master/arch/x86/crypto/sha256-avx2-asm.S
+// by
+// James Guilford <james.guilford@intel.com>
+// Kirk Yap <kirk.s.yap@intel.com>
+// Tim Chen <tim.c.chen@linux.intel.com>
+
+// Wt = Mt; for 0 <= t <= 15
+// Wt = SIGMA1(Wt-2) + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
+//
+// a = H0
+// b = H1
+// c = H2
+// d = H3
+// e = H4
+// f = H5
+// g = H6
+// h = H7
+//
+// for t = 0 to 63 {
+// T1 = h + BIGSIGMA1(e) + Ch(e,f,g) + Kt + Wt
+// T2 = BIGSIGMA0(a) + Maj(a,b,c)
+// h = g
+// g = f
+// f = e
+// e = d + T1
+// d = c
+// c = b
+// b = a
+// a = T1 + T2
+// }
+//
+// H0 = a + H0
+// H1 = b + H1
+// H2 = c + H2
+// H3 = d + H3
+// H4 = e + H4
+// H5 = f + H5
+// H6 = g + H6
+// H7 = h + H7
+
+// Wt = Mt; for 0 <= t <= 15
+#define MSGSCHEDULE0(index) \
+ MOVL (index*4)(SI), AX; \
+ BSWAPL AX; \
+ MOVL AX, (index*4)(BP)
+
+// Wt = SIGMA1(Wt-2) + Wt-7 + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
+// SIGMA0(x) = ROTR(7,x) XOR ROTR(18,x) XOR SHR(3,x)
+// SIGMA1(x) = ROTR(17,x) XOR ROTR(19,x) XOR SHR(10,x)
+#define MSGSCHEDULE1(index) \
+ MOVL ((index-2)*4)(BP), AX; \
+ MOVL AX, CX; \
+ RORL $17, AX; \
+ MOVL CX, DX; \
+ RORL $19, CX; \
+ SHRL $10, DX; \
+ MOVL ((index-15)*4)(BP), BX; \
+ XORL CX, AX; \
+ MOVL BX, CX; \
+ XORL DX, AX; \
+ RORL $7, BX; \
+ MOVL CX, DX; \
+ SHRL $3, DX; \
+ RORL $18, CX; \
+ ADDL ((index-7)*4)(BP), AX; \
+ XORL CX, BX; \
+ XORL DX, BX; \
+ ADDL ((index-16)*4)(BP), BX; \
+ ADDL BX, AX; \
+ MOVL AX, ((index)*4)(BP)
+
+// Calculate T1 in AX - uses AX, CX and DX registers.
+// h is also used as an accumulator. Wt is passed in AX.
+// T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + Kt + Wt
+// BIGSIGMA1(x) = ROTR(6,x) XOR ROTR(11,x) XOR ROTR(25,x)
+// Ch(x, y, z) = (x AND y) XOR (NOT x AND z)
+#define SHA256T1(const, e, f, g, h) \
+ ADDL AX, h; \
+ MOVL e, AX; \
+ ADDL $const, h; \
+ MOVL e, CX; \
+ RORL $6, AX; \
+ MOVL e, DX; \
+ RORL $11, CX; \
+ XORL CX, AX; \
+ MOVL e, CX; \
+ RORL $25, DX; \
+ ANDL f, CX; \
+ XORL AX, DX; \
+ MOVL e, AX; \
+ NOTL AX; \
+ ADDL DX, h; \
+ ANDL g, AX; \
+ XORL CX, AX; \
+ ADDL h, AX
+
+// Calculate T2 in BX - uses BX, CX, DX and DI registers.
+// T2 = BIGSIGMA0(a) + Maj(a, b, c)
+// BIGSIGMA0(x) = ROTR(2,x) XOR ROTR(13,x) XOR ROTR(22,x)
+// Maj(x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
+#define SHA256T2(a, b, c) \
+ MOVL a, DI; \
+ MOVL c, BX; \
+ RORL $2, DI; \
+ MOVL a, DX; \
+ ANDL b, BX; \
+ RORL $13, DX; \
+ MOVL a, CX; \
+ ANDL c, CX; \
+ XORL DX, DI; \
+ XORL CX, BX; \
+ MOVL a, DX; \
+ MOVL b, CX; \
+ RORL $22, DX; \
+ ANDL a, CX; \
+ XORL CX, BX; \
+ XORL DX, DI; \
+ ADDL DI, BX
+
+// Calculate T1 and T2, then e = d + T1 and a = T1 + T2.
+// The values for e and a are stored in d and h, ready for rotation.
+#define SHA256ROUND(index, const, a, b, c, d, e, f, g, h) \
+ SHA256T1(const, e, f, g, h); \
+ SHA256T2(a, b, c); \
+ MOVL BX, h; \
+ ADDL AX, d; \
+ ADDL AX, h
+
+#define SHA256ROUND0(index, const, a, b, c, d, e, f, g, h) \
+ MSGSCHEDULE0(index); \
+ SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
+
+#define SHA256ROUND1(index, const, a, b, c, d, e, f, g, h) \
+ MSGSCHEDULE1(index); \
+ SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
+
+
+// Definitions for AVX2 version
+
+// addm (mem), reg
+// Add reg to mem using reg-mem add and store
+#define addm(P1, P2) \
+ ADDL P2, P1; \
+ MOVL P1, P2
+
+#define XDWORD0 Y4
+#define XDWORD1 Y5
+#define XDWORD2 Y6
+#define XDWORD3 Y7
+
+#define XWORD0 X4
+#define XWORD1 X5
+#define XWORD2 X6
+#define XWORD3 X7
+
+#define XTMP0 Y0
+#define XTMP1 Y1
+#define XTMP2 Y2
+#define XTMP3 Y3
+#define XTMP4 Y8
+#define XTMP5 Y11
+
+#define XFER Y9
+
+#define BYTE_FLIP_MASK Y13 // mask to convert LE -> BE
+#define X_BYTE_FLIP_MASK X13
+
+#define NUM_BYTES DX
+#define INP DI
+
+#define CTX SI // Beginning of digest in memory (a, b, c, ... , h)
+
+#define a AX
+#define b BX
+#define c CX
+#define d R8
+#define e DX
+#define f R9
+#define g R10
+#define h R11
+
+#define old_h R11
+
+#define TBL BP
+
+#define SRND SI // SRND is same register as CTX
+
+#define T1 R12
+
+#define y0 R13
+#define y1 R14
+#define y2 R15
+#define y3 DI
+
+// Offsets
+#define XFER_SIZE 2*64*4
+#define INP_END_SIZE 8
+#define INP_SIZE 8
+
+#define _XFER 0
+#define _INP_END _XFER + XFER_SIZE
+#define _INP _INP_END + INP_END_SIZE
+#define STACK_SIZE _INP + INP_SIZE
+
+#define ROUND_AND_SCHED_N_0(disp, a, b, c, d, e, f, g, h, XDWORD0, XDWORD1, XDWORD2, XDWORD3) \
+ ; \ // ############################# RND N + 0 ############################//
+ MOVL a, y3; \ // y3 = a // MAJA
+ RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
+ RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
+ ; \
+ ADDL (disp + 0*4)(SP)(SRND*1), h; \ // h = k + w + h // disp = k + w
+ ORL c, y3; \ // y3 = a|c // MAJA
+ VPALIGNR $4, XDWORD2, XDWORD3, XTMP0; \ // XTMP0 = W[-7]
+ MOVL f, y2; \ // y2 = f // CH
+ RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
+ ; \
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
+ XORL g, y2; \ // y2 = f^g // CH
+ VPADDD XDWORD0, XTMP0, XTMP0; \ // XTMP0 = W[-7] + W[-16] // y1 = (e >> 6) // S1
+ RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
+ ; \
+ ANDL e, y2; \ // y2 = (f^g)&e // CH
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
+ RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
+ ADDL h, d; \ // d = k + w + h + d // --
+ ; \
+ ANDL b, y3; \ // y3 = (a|c)&b // MAJA
+ VPALIGNR $4, XDWORD0, XDWORD1, XTMP1; \ // XTMP1 = W[-15]
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
+ RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
+ ; \
+ XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
+ VPSRLD $7, XTMP1, XTMP2; \
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
+ MOVL a, T1; \ // T1 = a // MAJB
+ ANDL c, T1; \ // T1 = a&c // MAJB
+ ; \
+ ADDL y0, y2; \ // y2 = S1 + CH // --
+ VPSLLD $(32-7), XTMP1, XTMP3; \
+ ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
+ ADDL y1, h; \ // h = k + w + h + S0 // --
+ ; \
+ ADDL y2, d; \ // d = k + w + h + d + S1 + CH = d + t1 // --
+ VPOR XTMP2, XTMP3, XTMP3; \ // XTMP3 = W[-15] ror 7
+ ; \
+ VPSRLD $18, XTMP1, XTMP2; \
+ ADDL y2, h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
+ ADDL y3, h // h = t1 + S0 + MAJ // --
+
+#define ROUND_AND_SCHED_N_1(disp, a, b, c, d, e, f, g, h, XDWORD0, XDWORD1, XDWORD2, XDWORD3) \
+ ; \ // ################################### RND N + 1 ############################
+ ; \
+ MOVL a, y3; \ // y3 = a // MAJA
+ RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
+ RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
+ ADDL (disp + 1*4)(SP)(SRND*1), h; \ // h = k + w + h // --
+ ORL c, y3; \ // y3 = a|c // MAJA
+ ; \
+ VPSRLD $3, XTMP1, XTMP4; \ // XTMP4 = W[-15] >> 3
+ MOVL f, y2; \ // y2 = f // CH
+ RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
+ XORL g, y2; \ // y2 = f^g // CH
+ ; \
+ RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
+ RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
+ ANDL e, y2; \ // y2 = (f^g)&e // CH
+ ADDL h, d; \ // d = k + w + h + d // --
+ ; \
+ VPSLLD $(32-18), XTMP1, XTMP1; \
+ ANDL b, y3; \ // y3 = (a|c)&b // MAJA
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
+ ; \
+ VPXOR XTMP1, XTMP3, XTMP3; \
+ RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
+ XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
+ ; \
+ VPXOR XTMP2, XTMP3, XTMP3; \ // XTMP3 = W[-15] ror 7 ^ W[-15] ror 18
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
+ MOVL a, T1; \ // T1 = a // MAJB
+ ANDL c, T1; \ // T1 = a&c // MAJB
+ ADDL y0, y2; \ // y2 = S1 + CH // --
+ ; \
+ VPXOR XTMP4, XTMP3, XTMP1; \ // XTMP1 = s0
+ VPSHUFD $0xFA, XDWORD3, XTMP2; \ // XTMP2 = W[-2] {BBAA}
+ ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
+ ADDL y1, h; \ // h = k + w + h + S0 // --
+ ; \
+ VPADDD XTMP1, XTMP0, XTMP0; \ // XTMP0 = W[-16] + W[-7] + s0
+ ADDL y2, d; \ // d = k + w + h + d + S1 + CH = d + t1 // --
+ ADDL y2, h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
+ ADDL y3, h; \ // h = t1 + S0 + MAJ // --
+ ; \
+ VPSRLD $10, XTMP2, XTMP4 // XTMP4 = W[-2] >> 10 {BBAA}
+
+#define ROUND_AND_SCHED_N_2(disp, a, b, c, d, e, f, g, h, XDWORD0, XDWORD1, XDWORD2, XDWORD3) \
+ ; \ // ################################### RND N + 2 ############################
+ ; \
+ MOVL a, y3; \ // y3 = a // MAJA
+ RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
+ ADDL (disp + 2*4)(SP)(SRND*1), h; \ // h = k + w + h // --
+ ; \
+ VPSRLQ $19, XTMP2, XTMP3; \ // XTMP3 = W[-2] ror 19 {xBxA}
+ RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
+ ORL c, y3; \ // y3 = a|c // MAJA
+ MOVL f, y2; \ // y2 = f // CH
+ XORL g, y2; \ // y2 = f^g // CH
+ ; \
+ RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
+ VPSRLQ $17, XTMP2, XTMP2; \ // XTMP2 = W[-2] ror 17 {xBxA}
+ ANDL e, y2; \ // y2 = (f^g)&e // CH
+ ; \
+ RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
+ VPXOR XTMP3, XTMP2, XTMP2; \
+ ADDL h, d; \ // d = k + w + h + d // --
+ ANDL b, y3; \ // y3 = (a|c)&b // MAJA
+ ; \
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
+ RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
+ VPXOR XTMP2, XTMP4, XTMP4; \ // XTMP4 = s1 {xBxA}
+ XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
+ ; \
+ VPSHUFB shuff_00BA<>(SB), XTMP4, XTMP4;\ // XTMP4 = s1 {00BA}
+ ; \
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
+ RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
+ VPADDD XTMP4, XTMP0, XTMP0; \ // XTMP0 = {..., ..., W[1], W[0]}
+ ; \
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
+ MOVL a, T1; \ // T1 = a // MAJB
+ ANDL c, T1; \ // T1 = a&c // MAJB
+ ADDL y0, y2; \ // y2 = S1 + CH // --
+ VPSHUFD $80, XTMP0, XTMP2; \ // XTMP2 = W[-2] {DDCC}
+ ; \
+ ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
+ ADDL y1, h; \ // h = k + w + h + S0 // --
+ ADDL y2, d; \ // d = k + w + h + d + S1 + CH = d + t1 // --
+ ADDL y2, h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
+ ; \
+ ADDL y3, h // h = t1 + S0 + MAJ // --
+
+#define ROUND_AND_SCHED_N_3(disp, a, b, c, d, e, f, g, h, XDWORD0, XDWORD1, XDWORD2, XDWORD3) \
+ ; \ // ################################### RND N + 3 ############################
+ ; \
+ MOVL a, y3; \ // y3 = a // MAJA
+ RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
+ RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
+ ADDL (disp + 3*4)(SP)(SRND*1), h; \ // h = k + w + h // --
+ ORL c, y3; \ // y3 = a|c // MAJA
+ ; \
+ VPSRLD $10, XTMP2, XTMP5; \ // XTMP5 = W[-2] >> 10 {DDCC}
+ MOVL f, y2; \ // y2 = f // CH
+ RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
+ XORL g, y2; \ // y2 = f^g // CH
+ ; \
+ VPSRLQ $19, XTMP2, XTMP3; \ // XTMP3 = W[-2] ror 19 {xDxC}
+ RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
+ ANDL e, y2; \ // y2 = (f^g)&e // CH
+ ADDL h, d; \ // d = k + w + h + d // --
+ ANDL b, y3; \ // y3 = (a|c)&b // MAJA
+ ; \
+ VPSRLQ $17, XTMP2, XTMP2; \ // XTMP2 = W[-2] ror 17 {xDxC}
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
+ XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
+ ; \
+ VPXOR XTMP3, XTMP2, XTMP2; \
+ RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
+ ADDL y0, y2; \ // y2 = S1 + CH // --
+ ; \
+ VPXOR XTMP2, XTMP5, XTMP5; \ // XTMP5 = s1 {xDxC}
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
+ ADDL y2, d; \ // d = k + w + h + d + S1 + CH = d + t1 // --
+ ; \
+ RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
+ ; \
+ VPSHUFB shuff_DC00<>(SB), XTMP5, XTMP5;\ // XTMP5 = s1 {DC00}
+ ; \
+ VPADDD XTMP0, XTMP5, XDWORD0; \ // XDWORD0 = {W[3], W[2], W[1], W[0]}
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
+ MOVL a, T1; \ // T1 = a // MAJB
+ ANDL c, T1; \ // T1 = a&c // MAJB
+ ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
+ ; \
+ ADDL y1, h; \ // h = k + w + h + S0 // --
+ ADDL y2, h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
+ ADDL y3, h // h = t1 + S0 + MAJ // --
+
+#define DO_ROUND_N_0(disp, a, b, c, d, e, f, g, h, old_h) \
+ ; \ // ################################### RND N + 0 ###########################
+ MOVL f, y2; \ // y2 = f // CH
+ RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
+ RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
+ XORL g, y2; \ // y2 = f^g // CH
+ ; \
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
+ RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
+ ANDL e, y2; \ // y2 = (f^g)&e // CH
+ ; \
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
+ RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
+ XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
+ RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
+ MOVL a, y3; \ // y3 = a // MAJA
+ ; \
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
+ RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
+ ADDL (disp + 0*4)(SP)(SRND*1), h; \ // h = k + w + h // --
+ ORL c, y3; \ // y3 = a|c // MAJA
+ ; \
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
+ MOVL a, T1; \ // T1 = a // MAJB
+ ANDL b, y3; \ // y3 = (a|c)&b // MAJA
+ ANDL c, T1; \ // T1 = a&c // MAJB
+ ADDL y0, y2; \ // y2 = S1 + CH // --
+ ; \
+ ADDL h, d; \ // d = k + w + h + d // --
+ ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
+ ADDL y1, h; \ // h = k + w + h + S0 // --
+ ADDL y2, d // d = k + w + h + d + S1 + CH = d + t1 // --
+
+#define DO_ROUND_N_1(disp, a, b, c, d, e, f, g, h, old_h) \
+ ; \ // ################################### RND N + 1 ###########################
+ ADDL y2, old_h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0 // --
+ MOVL f, y2; \ // y2 = f // CH
+ RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
+ RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
+ XORL g, y2; \ // y2 = f^g // CH
+ ; \
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
+ RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
+ ANDL e, y2; \ // y2 = (f^g)&e // CH
+ ADDL y3, old_h; \ // h = t1 + S0 + MAJ // --
+ ; \
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
+ RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
+ XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
+ RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
+ MOVL a, y3; \ // y3 = a // MAJA
+ ; \
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
+ RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
+ ADDL (disp + 1*4)(SP)(SRND*1), h; \ // h = k + w + h // --
+ ORL c, y3; \ // y3 = a|c // MAJA
+ ; \
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
+ MOVL a, T1; \ // T1 = a // MAJB
+ ANDL b, y3; \ // y3 = (a|c)&b // MAJA
+ ANDL c, T1; \ // T1 = a&c // MAJB
+ ADDL y0, y2; \ // y2 = S1 + CH // --
+ ; \
+ ADDL h, d; \ // d = k + w + h + d // --
+ ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
+ ADDL y1, h; \ // h = k + w + h + S0 // --
+ ; \
+ ADDL y2, d // d = k + w + h + d + S1 + CH = d + t1 // --
+
+#define DO_ROUND_N_2(disp, a, b, c, d, e, f, g, h, old_h) \
+ ; \ // ################################### RND N + 2 ##############################
+ ADDL y2, old_h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
+ MOVL f, y2; \ // y2 = f // CH
+ RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
+ RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
+ XORL g, y2; \ // y2 = f^g // CH
+ ; \
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
+ RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
+ ANDL e, y2; \ // y2 = (f^g)&e // CH
+ ADDL y3, old_h; \ // h = t1 + S0 + MAJ // --
+ ; \
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
+ RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
+ XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
+ RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
+ MOVL a, y3; \ // y3 = a // MAJA
+ ; \
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
+ RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
+ ADDL (disp + 2*4)(SP)(SRND*1), h; \ // h = k + w + h // --
+ ORL c, y3; \ // y3 = a|c // MAJA
+ ; \
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
+ MOVL a, T1; \ // T1 = a // MAJB
+ ANDL b, y3; \ // y3 = (a|c)&b // MAJA
+ ANDL c, T1; \ // T1 = a&c // MAJB
+ ADDL y0, y2; \ // y2 = S1 + CH // --
+ ; \
+ ADDL h, d; \ // d = k + w + h + d // --
+ ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
+ ADDL y1, h; \ // h = k + w + h + S0 // --
+ ; \
+ ADDL y2, d // d = k + w + h + d + S1 + CH = d + t1 // --
+
+#define DO_ROUND_N_3(disp, a, b, c, d, e, f, g, h, old_h) \
+ ; \ // ################################### RND N + 3 ###########################
+ ADDL y2, old_h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
+ MOVL f, y2; \ // y2 = f // CH
+ RORXL $25, e, y0; \ // y0 = e >> 25 // S1A
+ RORXL $11, e, y1; \ // y1 = e >> 11 // S1B
+ XORL g, y2; \ // y2 = f^g // CH
+ ; \
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) // S1
+ RORXL $6, e, y1; \ // y1 = (e >> 6) // S1
+ ANDL e, y2; \ // y2 = (f^g)&e // CH
+ ADDL y3, old_h; \ // h = t1 + S0 + MAJ // --
+ ; \
+ XORL y1, y0; \ // y0 = (e>>25) ^ (e>>11) ^ (e>>6) // S1
+ RORXL $13, a, T1; \ // T1 = a >> 13 // S0B
+ XORL g, y2; \ // y2 = CH = ((f^g)&e)^g // CH
+ RORXL $22, a, y1; \ // y1 = a >> 22 // S0A
+ MOVL a, y3; \ // y3 = a // MAJA
+ ; \
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) // S0
+ RORXL $2, a, T1; \ // T1 = (a >> 2) // S0
+ ADDL (disp + 3*4)(SP)(SRND*1), h; \ // h = k + w + h // --
+ ORL c, y3; \ // y3 = a|c // MAJA
+ ; \
+ XORL T1, y1; \ // y1 = (a>>22) ^ (a>>13) ^ (a>>2) // S0
+ MOVL a, T1; \ // T1 = a // MAJB
+ ANDL b, y3; \ // y3 = (a|c)&b // MAJA
+ ANDL c, T1; \ // T1 = a&c // MAJB
+ ADDL y0, y2; \ // y2 = S1 + CH // --
+ ; \
+ ADDL h, d; \ // d = k + w + h + d // --
+ ORL T1, y3; \ // y3 = MAJ = (a|c)&b)|(a&c) // MAJ
+ ADDL y1, h; \ // h = k + w + h + S0 // --
+ ; \
+ ADDL y2, d; \ // d = k + w + h + d + S1 + CH = d + t1 // --
+ ; \
+ ADDL y2, h; \ // h = k + w + h + S0 + S1 + CH = t1 + S0// --
+ ; \
+ ADDL y3, h // h = t1 + S0 + MAJ // --
+
+// Definitions for sha-ni version
+//
+// The sha-ni implementation uses Intel(R) SHA extensions SHA256RNDS2, SHA256MSG1, SHA256MSG2
+// It also reuses portions of the flip_mask (half) and K256 table (stride 32) from the avx2 version
+//
+// Reference
+// S. Gulley, et al, "New Instructions Supporting the Secure Hash
+// Algorithm on Intel® Architecture Processors", July 2013
+// https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sha-extensions.html
+//
+
+#define digestPtr DI // input/output, base pointer to digest hash vector H0, H1, ..., H7
+#define dataPtr SI // input, base pointer to first input data block
+#define numBytes DX // input, number of input bytes to be processed
+#define sha256Constants AX // round contents from K256 table, indexed by round number x 32
+#define msg X0 // input data
+#define state0 X1 // round intermediates and outputs
+#define state1 X2
+#define m0 X3 // m0, m1,... m4 -- round message temps
+#define m1 X4
+#define m2 X5
+#define m3 X6
+#define m4 X7
+#define shufMask X8 // input data endian conversion control mask
+#define abefSave X9 // digest hash vector inter-block buffer abef
+#define cdghSave X10 // digest hash vector inter-block buffer cdgh
+
+#define nop(m,a) // nop instead of final SHA256MSG1 for first and last few rounds
+
+#define sha256msg1(m,a) \ // final SHA256MSG1 for middle rounds that require it
+ SHA256MSG1 m, a
+
+#define vmov(a,b) \ // msg copy for all but rounds 12-15
+ VMOVDQA a, b
+
+#define vmovrev(a,b) \ // reverse copy for rounds 12-15
+ VMOVDQA b, a
+
+// sha rounds 0 to 11
+// identical with the exception of the final msg op
+// which is replaced with a nop for rounds where it is not needed
+// refer to Gulley, et al for more information
+#define rounds0to11(m,a,c,sha256Msg1) \
+ VMOVDQU c*16(dataPtr), msg \
+ PSHUFB shufMask, msg \
+ VMOVDQA msg, m \
+ PADDD (c*32)(sha256Constants), msg \
+ SHA256RNDS2 msg, state0, state1 \
+ PSHUFD $0x0e, msg, msg \
+ SHA256RNDS2 msg, state1, state0 \
+ sha256Msg1 (m,a)
+
+// sha rounds 12 to 59
+// identical with the exception of the final msg op
+// and the reverse copy(m,msg) in round 12 which is required
+// after the last data load
+// refer to Gulley, et al for more information
+#define rounds12to59(m,c,a,t,sha256Msg1,movop) \
+ movop (m,msg) \
+ PADDD (c*32)(sha256Constants), msg \
+ SHA256RNDS2 msg, state0, state1 \
+ VMOVDQA m, m4 \
+ PALIGNR $4, a, m4 \
+ PADDD m4, t \
+ SHA256MSG2 m, t \
+ PSHUFD $0x0e, msg, msg \
+ SHA256RNDS2 msg, state1, state0 \
+ sha256Msg1 (m,a)
+
+TEXT ·block(SB), 0, $536-32
+ CMPB ·useSHA(SB), $1
+ JE sha_ni
+ CMPB ·useAVX2(SB), $1
+ JE avx2
+
+ MOVQ p_base+8(FP), SI
+ MOVQ p_len+16(FP), DX
+ SHRQ $6, DX
+ SHLQ $6, DX
+
+ LEAQ (SI)(DX*1), DI
+ MOVQ DI, 256(SP)
+ CMPQ SI, DI
+ JEQ end
+
+ MOVQ dig+0(FP), BP
+ MOVL (0*4)(BP), R8 // a = H0
+ MOVL (1*4)(BP), R9 // b = H1
+ MOVL (2*4)(BP), R10 // c = H2
+ MOVL (3*4)(BP), R11 // d = H3
+ MOVL (4*4)(BP), R12 // e = H4
+ MOVL (5*4)(BP), R13 // f = H5
+ MOVL (6*4)(BP), R14 // g = H6
+ MOVL (7*4)(BP), R15 // h = H7
+
+loop:
+ MOVQ SP, BP
+
+ SHA256ROUND0(0, 0x428a2f98, R8, R9, R10, R11, R12, R13, R14, R15)
+ SHA256ROUND0(1, 0x71374491, R15, R8, R9, R10, R11, R12, R13, R14)
+ SHA256ROUND0(2, 0xb5c0fbcf, R14, R15, R8, R9, R10, R11, R12, R13)
+ SHA256ROUND0(3, 0xe9b5dba5, R13, R14, R15, R8, R9, R10, R11, R12)
+ SHA256ROUND0(4, 0x3956c25b, R12, R13, R14, R15, R8, R9, R10, R11)
+ SHA256ROUND0(5, 0x59f111f1, R11, R12, R13, R14, R15, R8, R9, R10)
+ SHA256ROUND0(6, 0x923f82a4, R10, R11, R12, R13, R14, R15, R8, R9)
+ SHA256ROUND0(7, 0xab1c5ed5, R9, R10, R11, R12, R13, R14, R15, R8)
+ SHA256ROUND0(8, 0xd807aa98, R8, R9, R10, R11, R12, R13, R14, R15)
+ SHA256ROUND0(9, 0x12835b01, R15, R8, R9, R10, R11, R12, R13, R14)
+ SHA256ROUND0(10, 0x243185be, R14, R15, R8, R9, R10, R11, R12, R13)
+ SHA256ROUND0(11, 0x550c7dc3, R13, R14, R15, R8, R9, R10, R11, R12)
+ SHA256ROUND0(12, 0x72be5d74, R12, R13, R14, R15, R8, R9, R10, R11)
+ SHA256ROUND0(13, 0x80deb1fe, R11, R12, R13, R14, R15, R8, R9, R10)
+ SHA256ROUND0(14, 0x9bdc06a7, R10, R11, R12, R13, R14, R15, R8, R9)
+ SHA256ROUND0(15, 0xc19bf174, R9, R10, R11, R12, R13, R14, R15, R8)
+
+ SHA256ROUND1(16, 0xe49b69c1, R8, R9, R10, R11, R12, R13, R14, R15)
+ SHA256ROUND1(17, 0xefbe4786, R15, R8, R9, R10, R11, R12, R13, R14)
+ SHA256ROUND1(18, 0x0fc19dc6, R14, R15, R8, R9, R10, R11, R12, R13)
+ SHA256ROUND1(19, 0x240ca1cc, R13, R14, R15, R8, R9, R10, R11, R12)
+ SHA256ROUND1(20, 0x2de92c6f, R12, R13, R14, R15, R8, R9, R10, R11)
+ SHA256ROUND1(21, 0x4a7484aa, R11, R12, R13, R14, R15, R8, R9, R10)
+ SHA256ROUND1(22, 0x5cb0a9dc, R10, R11, R12, R13, R14, R15, R8, R9)
+ SHA256ROUND1(23, 0x76f988da, R9, R10, R11, R12, R13, R14, R15, R8)
+ SHA256ROUND1(24, 0x983e5152, R8, R9, R10, R11, R12, R13, R14, R15)
+ SHA256ROUND1(25, 0xa831c66d, R15, R8, R9, R10, R11, R12, R13, R14)
+ SHA256ROUND1(26, 0xb00327c8, R14, R15, R8, R9, R10, R11, R12, R13)
+ SHA256ROUND1(27, 0xbf597fc7, R13, R14, R15, R8, R9, R10, R11, R12)
+ SHA256ROUND1(28, 0xc6e00bf3, R12, R13, R14, R15, R8, R9, R10, R11)
+ SHA256ROUND1(29, 0xd5a79147, R11, R12, R13, R14, R15, R8, R9, R10)
+ SHA256ROUND1(30, 0x06ca6351, R10, R11, R12, R13, R14, R15, R8, R9)
+ SHA256ROUND1(31, 0x14292967, R9, R10, R11, R12, R13, R14, R15, R8)
+ SHA256ROUND1(32, 0x27b70a85, R8, R9, R10, R11, R12, R13, R14, R15)
+ SHA256ROUND1(33, 0x2e1b2138, R15, R8, R9, R10, R11, R12, R13, R14)
+ SHA256ROUND1(34, 0x4d2c6dfc, R14, R15, R8, R9, R10, R11, R12, R13)
+ SHA256ROUND1(35, 0x53380d13, R13, R14, R15, R8, R9, R10, R11, R12)
+ SHA256ROUND1(36, 0x650a7354, R12, R13, R14, R15, R8, R9, R10, R11)
+ SHA256ROUND1(37, 0x766a0abb, R11, R12, R13, R14, R15, R8, R9, R10)
+ SHA256ROUND1(38, 0x81c2c92e, R10, R11, R12, R13, R14, R15, R8, R9)
+ SHA256ROUND1(39, 0x92722c85, R9, R10, R11, R12, R13, R14, R15, R8)
+ SHA256ROUND1(40, 0xa2bfe8a1, R8, R9, R10, R11, R12, R13, R14, R15)
+ SHA256ROUND1(41, 0xa81a664b, R15, R8, R9, R10, R11, R12, R13, R14)
+ SHA256ROUND1(42, 0xc24b8b70, R14, R15, R8, R9, R10, R11, R12, R13)
+ SHA256ROUND1(43, 0xc76c51a3, R13, R14, R15, R8, R9, R10, R11, R12)
+ SHA256ROUND1(44, 0xd192e819, R12, R13, R14, R15, R8, R9, R10, R11)
+ SHA256ROUND1(45, 0xd6990624, R11, R12, R13, R14, R15, R8, R9, R10)
+ SHA256ROUND1(46, 0xf40e3585, R10, R11, R12, R13, R14, R15, R8, R9)
+ SHA256ROUND1(47, 0x106aa070, R9, R10, R11, R12, R13, R14, R15, R8)
+ SHA256ROUND1(48, 0x19a4c116, R8, R9, R10, R11, R12, R13, R14, R15)
+ SHA256ROUND1(49, 0x1e376c08, R15, R8, R9, R10, R11, R12, R13, R14)
+ SHA256ROUND1(50, 0x2748774c, R14, R15, R8, R9, R10, R11, R12, R13)
+ SHA256ROUND1(51, 0x34b0bcb5, R13, R14, R15, R8, R9, R10, R11, R12)
+ SHA256ROUND1(52, 0x391c0cb3, R12, R13, R14, R15, R8, R9, R10, R11)
+ SHA256ROUND1(53, 0x4ed8aa4a, R11, R12, R13, R14, R15, R8, R9, R10)
+ SHA256ROUND1(54, 0x5b9cca4f, R10, R11, R12, R13, R14, R15, R8, R9)
+ SHA256ROUND1(55, 0x682e6ff3, R9, R10, R11, R12, R13, R14, R15, R8)
+ SHA256ROUND1(56, 0x748f82ee, R8, R9, R10, R11, R12, R13, R14, R15)
+ SHA256ROUND1(57, 0x78a5636f, R15, R8, R9, R10, R11, R12, R13, R14)
+ SHA256ROUND1(58, 0x84c87814, R14, R15, R8, R9, R10, R11, R12, R13)
+ SHA256ROUND1(59, 0x8cc70208, R13, R14, R15, R8, R9, R10, R11, R12)
+ SHA256ROUND1(60, 0x90befffa, R12, R13, R14, R15, R8, R9, R10, R11)
+ SHA256ROUND1(61, 0xa4506ceb, R11, R12, R13, R14, R15, R8, R9, R10)
+ SHA256ROUND1(62, 0xbef9a3f7, R10, R11, R12, R13, R14, R15, R8, R9)
+ SHA256ROUND1(63, 0xc67178f2, R9, R10, R11, R12, R13, R14, R15, R8)
+
+ MOVQ dig+0(FP), BP
+ ADDL (0*4)(BP), R8 // H0 = a + H0
+ MOVL R8, (0*4)(BP)
+ ADDL (1*4)(BP), R9 // H1 = b + H1
+ MOVL R9, (1*4)(BP)
+ ADDL (2*4)(BP), R10 // H2 = c + H2
+ MOVL R10, (2*4)(BP)
+ ADDL (3*4)(BP), R11 // H3 = d + H3
+ MOVL R11, (3*4)(BP)
+ ADDL (4*4)(BP), R12 // H4 = e + H4
+ MOVL R12, (4*4)(BP)
+ ADDL (5*4)(BP), R13 // H5 = f + H5
+ MOVL R13, (5*4)(BP)
+ ADDL (6*4)(BP), R14 // H6 = g + H6
+ MOVL R14, (6*4)(BP)
+ ADDL (7*4)(BP), R15 // H7 = h + H7
+ MOVL R15, (7*4)(BP)
+
+ ADDQ $64, SI
+ CMPQ SI, 256(SP)
+ JB loop
+
+end:
+ RET
+
+avx2:
+ MOVQ dig+0(FP), CTX // d.h[8]
+ MOVQ p_base+8(FP), INP
+ MOVQ p_len+16(FP), NUM_BYTES
+
+ LEAQ -64(INP)(NUM_BYTES*1), NUM_BYTES // Pointer to the last block
+ MOVQ NUM_BYTES, _INP_END(SP)
+
+ CMPQ NUM_BYTES, INP
+ JE avx2_only_one_block
+
+ // Load initial digest
+ MOVL 0(CTX), a // a = H0
+ MOVL 4(CTX), b // b = H1
+ MOVL 8(CTX), c // c = H2
+ MOVL 12(CTX), d // d = H3
+ MOVL 16(CTX), e // e = H4
+ MOVL 20(CTX), f // f = H5
+ MOVL 24(CTX), g // g = H6
+ MOVL 28(CTX), h // h = H7
+
+avx2_loop0: // at each iteration works with one block (512 bit)
+
+ VMOVDQU (0*32)(INP), XTMP0
+ VMOVDQU (1*32)(INP), XTMP1
+ VMOVDQU (2*32)(INP), XTMP2
+ VMOVDQU (3*32)(INP), XTMP3
+
+ VMOVDQU flip_mask<>(SB), BYTE_FLIP_MASK
+
+ // Apply Byte Flip Mask: LE -> BE
+ VPSHUFB BYTE_FLIP_MASK, XTMP0, XTMP0
+ VPSHUFB BYTE_FLIP_MASK, XTMP1, XTMP1
+ VPSHUFB BYTE_FLIP_MASK, XTMP2, XTMP2
+ VPSHUFB BYTE_FLIP_MASK, XTMP3, XTMP3
+
+ // Transpose data into high/low parts
+ VPERM2I128 $0x20, XTMP2, XTMP0, XDWORD0 // w3, w2, w1, w0
+ VPERM2I128 $0x31, XTMP2, XTMP0, XDWORD1 // w7, w6, w5, w4
+ VPERM2I128 $0x20, XTMP3, XTMP1, XDWORD2 // w11, w10, w9, w8
+ VPERM2I128 $0x31, XTMP3, XTMP1, XDWORD3 // w15, w14, w13, w12
+
+ MOVQ $K256<>(SB), TBL // Loading address of table with round-specific constants
+
+avx2_last_block_enter:
+ ADDQ $64, INP
+ MOVQ INP, _INP(SP)
+ XORQ SRND, SRND
+
+avx2_loop1: // for w0 - w47
+ // Do 4 rounds and scheduling
+ VPADDD 0*32(TBL)(SRND*1), XDWORD0, XFER
+ VMOVDQU XFER, (_XFER + 0*32)(SP)(SRND*1)
+ ROUND_AND_SCHED_N_0(_XFER + 0*32, a, b, c, d, e, f, g, h, XDWORD0, XDWORD1, XDWORD2, XDWORD3)
+ ROUND_AND_SCHED_N_1(_XFER + 0*32, h, a, b, c, d, e, f, g, XDWORD0, XDWORD1, XDWORD2, XDWORD3)
+ ROUND_AND_SCHED_N_2(_XFER + 0*32, g, h, a, b, c, d, e, f, XDWORD0, XDWORD1, XDWORD2, XDWORD3)
+ ROUND_AND_SCHED_N_3(_XFER + 0*32, f, g, h, a, b, c, d, e, XDWORD0, XDWORD1, XDWORD2, XDWORD3)
+
+ // Do 4 rounds and scheduling
+ VPADDD 1*32(TBL)(SRND*1), XDWORD1, XFER
+ VMOVDQU XFER, (_XFER + 1*32)(SP)(SRND*1)
+ ROUND_AND_SCHED_N_0(_XFER + 1*32, e, f, g, h, a, b, c, d, XDWORD1, XDWORD2, XDWORD3, XDWORD0)
+ ROUND_AND_SCHED_N_1(_XFER + 1*32, d, e, f, g, h, a, b, c, XDWORD1, XDWORD2, XDWORD3, XDWORD0)
+ ROUND_AND_SCHED_N_2(_XFER + 1*32, c, d, e, f, g, h, a, b, XDWORD1, XDWORD2, XDWORD3, XDWORD0)
+ ROUND_AND_SCHED_N_3(_XFER + 1*32, b, c, d, e, f, g, h, a, XDWORD1, XDWORD2, XDWORD3, XDWORD0)
+
+ // Do 4 rounds and scheduling
+ VPADDD 2*32(TBL)(SRND*1), XDWORD2, XFER
+ VMOVDQU XFER, (_XFER + 2*32)(SP)(SRND*1)
+ ROUND_AND_SCHED_N_0(_XFER + 2*32, a, b, c, d, e, f, g, h, XDWORD2, XDWORD3, XDWORD0, XDWORD1)
+ ROUND_AND_SCHED_N_1(_XFER + 2*32, h, a, b, c, d, e, f, g, XDWORD2, XDWORD3, XDWORD0, XDWORD1)
+ ROUND_AND_SCHED_N_2(_XFER + 2*32, g, h, a, b, c, d, e, f, XDWORD2, XDWORD3, XDWORD0, XDWORD1)
+ ROUND_AND_SCHED_N_3(_XFER + 2*32, f, g, h, a, b, c, d, e, XDWORD2, XDWORD3, XDWORD0, XDWORD1)
+
+ // Do 4 rounds and scheduling
+ VPADDD 3*32(TBL)(SRND*1), XDWORD3, XFER
+ VMOVDQU XFER, (_XFER + 3*32)(SP)(SRND*1)
+ ROUND_AND_SCHED_N_0(_XFER + 3*32, e, f, g, h, a, b, c, d, XDWORD3, XDWORD0, XDWORD1, XDWORD2)
+ ROUND_AND_SCHED_N_1(_XFER + 3*32, d, e, f, g, h, a, b, c, XDWORD3, XDWORD0, XDWORD1, XDWORD2)
+ ROUND_AND_SCHED_N_2(_XFER + 3*32, c, d, e, f, g, h, a, b, XDWORD3, XDWORD0, XDWORD1, XDWORD2)
+ ROUND_AND_SCHED_N_3(_XFER + 3*32, b, c, d, e, f, g, h, a, XDWORD3, XDWORD0, XDWORD1, XDWORD2)
+
+ ADDQ $4*32, SRND
+ CMPQ SRND, $3*4*32
+ JB avx2_loop1
+
+avx2_loop2:
+ // w48 - w63 processed with no scheduling (last 16 rounds)
+ VPADDD 0*32(TBL)(SRND*1), XDWORD0, XFER
+ VMOVDQU XFER, (_XFER + 0*32)(SP)(SRND*1)
+ DO_ROUND_N_0(_XFER + 0*32, a, b, c, d, e, f, g, h, h)
+ DO_ROUND_N_1(_XFER + 0*32, h, a, b, c, d, e, f, g, h)
+ DO_ROUND_N_2(_XFER + 0*32, g, h, a, b, c, d, e, f, g)
+ DO_ROUND_N_3(_XFER + 0*32, f, g, h, a, b, c, d, e, f)
+
+ VPADDD 1*32(TBL)(SRND*1), XDWORD1, XFER
+ VMOVDQU XFER, (_XFER + 1*32)(SP)(SRND*1)
+ DO_ROUND_N_0(_XFER + 1*32, e, f, g, h, a, b, c, d, e)
+ DO_ROUND_N_1(_XFER + 1*32, d, e, f, g, h, a, b, c, d)
+ DO_ROUND_N_2(_XFER + 1*32, c, d, e, f, g, h, a, b, c)
+ DO_ROUND_N_3(_XFER + 1*32, b, c, d, e, f, g, h, a, b)
+
+ ADDQ $2*32, SRND
+
+ VMOVDQU XDWORD2, XDWORD0
+ VMOVDQU XDWORD3, XDWORD1
+
+ CMPQ SRND, $4*4*32
+ JB avx2_loop2
+
+ MOVQ dig+0(FP), CTX // d.h[8]
+ MOVQ _INP(SP), INP
+
+ addm( 0(CTX), a)
+ addm( 4(CTX), b)
+ addm( 8(CTX), c)
+ addm( 12(CTX), d)
+ addm( 16(CTX), e)
+ addm( 20(CTX), f)
+ addm( 24(CTX), g)
+ addm( 28(CTX), h)
+
+ CMPQ _INP_END(SP), INP
+ JB done_hash
+
+ XORQ SRND, SRND
+
+avx2_loop3: // Do second block using previously scheduled results
+ DO_ROUND_N_0(_XFER + 0*32 + 16, a, b, c, d, e, f, g, h, a)
+ DO_ROUND_N_1(_XFER + 0*32 + 16, h, a, b, c, d, e, f, g, h)
+ DO_ROUND_N_2(_XFER + 0*32 + 16, g, h, a, b, c, d, e, f, g)
+ DO_ROUND_N_3(_XFER + 0*32 + 16, f, g, h, a, b, c, d, e, f)
+
+ DO_ROUND_N_0(_XFER + 1*32 + 16, e, f, g, h, a, b, c, d, e)
+ DO_ROUND_N_1(_XFER + 1*32 + 16, d, e, f, g, h, a, b, c, d)
+ DO_ROUND_N_2(_XFER + 1*32 + 16, c, d, e, f, g, h, a, b, c)
+ DO_ROUND_N_3(_XFER + 1*32 + 16, b, c, d, e, f, g, h, a, b)
+
+ ADDQ $2*32, SRND
+ CMPQ SRND, $4*4*32
+ JB avx2_loop3
+
+ MOVQ dig+0(FP), CTX // d.h[8]
+ MOVQ _INP(SP), INP
+ ADDQ $64, INP
+
+ addm( 0(CTX), a)
+ addm( 4(CTX), b)
+ addm( 8(CTX), c)
+ addm( 12(CTX), d)
+ addm( 16(CTX), e)
+ addm( 20(CTX), f)
+ addm( 24(CTX), g)
+ addm( 28(CTX), h)
+
+ CMPQ _INP_END(SP), INP
+ JA avx2_loop0
+ JB done_hash
+
+avx2_do_last_block:
+
+ VMOVDQU 0(INP), XWORD0
+ VMOVDQU 16(INP), XWORD1
+ VMOVDQU 32(INP), XWORD2
+ VMOVDQU 48(INP), XWORD3
+
+ VMOVDQU flip_mask<>(SB), BYTE_FLIP_MASK
+
+ VPSHUFB X_BYTE_FLIP_MASK, XWORD0, XWORD0
+ VPSHUFB X_BYTE_FLIP_MASK, XWORD1, XWORD1
+ VPSHUFB X_BYTE_FLIP_MASK, XWORD2, XWORD2
+ VPSHUFB X_BYTE_FLIP_MASK, XWORD3, XWORD3
+
+ MOVQ $K256<>(SB), TBL
+
+ JMP avx2_last_block_enter
+
+avx2_only_one_block:
+ // Load initial digest
+ MOVL 0(CTX), a // a = H0
+ MOVL 4(CTX), b // b = H1
+ MOVL 8(CTX), c // c = H2
+ MOVL 12(CTX), d // d = H3
+ MOVL 16(CTX), e // e = H4
+ MOVL 20(CTX), f // f = H5
+ MOVL 24(CTX), g // g = H6
+ MOVL 28(CTX), h // h = H7
+
+ JMP avx2_do_last_block
+
+done_hash:
+ VZEROUPPER
+ RET
+
+sha_ni:
+ MOVQ dig+0(FP), digestPtr // init digest hash vector H0, H1,..., H7 pointer
+ MOVQ p_base+8(FP), dataPtr // init input data base pointer
+ MOVQ p_len+16(FP), numBytes // get number of input bytes to hash
+ SHRQ $6, numBytes // force modulo 64 input buffer length
+ SHLQ $6, numBytes
+ CMPQ numBytes, $0 // exit early for zero-length input buffer
+ JEQ done
+ ADDQ dataPtr, numBytes // point numBytes to end of input buffer
+ VMOVDQU (0*16)(digestPtr), state0 // load initial hash values and reorder
+ VMOVDQU (1*16)(digestPtr), state1 // DCBA, HGFE -> ABEF, CDGH
+ PSHUFD $0xb1, state0, state0 // CDAB
+ PSHUFD $0x1b, state1, state1 // EFGH
+ VMOVDQA state0, m4
+ PALIGNR $8, state1, state0 // ABEF
+ PBLENDW $0xf0, m4, state1 // CDGH
+ VMOVDQA flip_mask<>(SB), shufMask
+ LEAQ K256<>(SB), sha256Constants
+
+roundLoop:
+ // save hash values for addition after rounds
+ VMOVDQA state0, abefSave
+ VMOVDQA state1, cdghSave
+
+ // do rounds 0-59
+ rounds0to11 (m0,-,0,nop) // 0-3
+ rounds0to11 (m1,m0,1,sha256msg1) // 4-7
+ rounds0to11 (m2,m1,2,sha256msg1) // 8-11
+ VMOVDQU (3*16)(dataPtr), msg
+ PSHUFB shufMask, msg
+ rounds12to59 (m3,3,m2,m0,sha256msg1,vmovrev) // 12-15
+ rounds12to59 (m0,4,m3,m1,sha256msg1,vmov) // 16-19
+ rounds12to59 (m1,5,m0,m2,sha256msg1,vmov) // 20-23
+ rounds12to59 (m2,6,m1,m3,sha256msg1,vmov) // 24-27
+ rounds12to59 (m3,7,m2,m0,sha256msg1,vmov) // 28-31
+ rounds12to59 (m0,8,m3,m1,sha256msg1,vmov) // 32-35
+ rounds12to59 (m1,9,m0,m2,sha256msg1,vmov) // 36-39
+ rounds12to59 (m2,10,m1,m3,sha256msg1,vmov) // 40-43
+ rounds12to59 (m3,11,m2,m0,sha256msg1,vmov) // 44-47
+ rounds12to59 (m0,12,m3,m1,sha256msg1,vmov) // 48-51
+ rounds12to59 (m1,13,m0,m2,nop,vmov) // 52-55
+ rounds12to59 (m2,14,m1,m3,nop,vmov) // 56-59
+
+ // do rounds 60-63
+ VMOVDQA m3, msg
+ PADDD (15*32)(sha256Constants), msg
+ SHA256RNDS2 msg, state0, state1
+ PSHUFD $0x0e, msg, msg
+ SHA256RNDS2 msg, state1, state0
+
+ // add current hash values with previously saved
+ PADDD abefSave, state0
+ PADDD cdghSave, state1
+
+ // advance data pointer; loop until buffer empty
+ ADDQ $64, dataPtr
+ CMPQ numBytes, dataPtr
+ JNE roundLoop
+
+ // write hash values back in the correct order
+ PSHUFD $0x1b, state0, state0 // FEBA
+ PSHUFD $0xb1, state1, state1 // DCHG
+ VMOVDQA state0, m4
+ PBLENDW $0xf0, state1, state0 // DCBA
+ PALIGNR $8, m4, state1 // HGFE
+ VMOVDQU state0, (0*16)(digestPtr)
+ VMOVDQU state1, (1*16)(digestPtr)
+
+done:
+ RET
+
+// shuffle byte order from LE to BE
+DATA flip_mask<>+0x00(SB)/8, $0x0405060700010203
+DATA flip_mask<>+0x08(SB)/8, $0x0c0d0e0f08090a0b
+DATA flip_mask<>+0x10(SB)/8, $0x0405060700010203
+DATA flip_mask<>+0x18(SB)/8, $0x0c0d0e0f08090a0b
+GLOBL flip_mask<>(SB), 8, $32
+
+// shuffle xBxA -> 00BA
+DATA shuff_00BA<>+0x00(SB)/8, $0x0b0a090803020100
+DATA shuff_00BA<>+0x08(SB)/8, $0xFFFFFFFFFFFFFFFF
+DATA shuff_00BA<>+0x10(SB)/8, $0x0b0a090803020100
+DATA shuff_00BA<>+0x18(SB)/8, $0xFFFFFFFFFFFFFFFF
+GLOBL shuff_00BA<>(SB), 8, $32
+
+// shuffle xDxC -> DC00
+DATA shuff_DC00<>+0x00(SB)/8, $0xFFFFFFFFFFFFFFFF
+DATA shuff_DC00<>+0x08(SB)/8, $0x0b0a090803020100
+DATA shuff_DC00<>+0x10(SB)/8, $0xFFFFFFFFFFFFFFFF
+DATA shuff_DC00<>+0x18(SB)/8, $0x0b0a090803020100
+GLOBL shuff_DC00<>(SB), 8, $32
+
+// Round specific constants
+DATA K256<>+0x00(SB)/4, $0x428a2f98 // k1
+DATA K256<>+0x04(SB)/4, $0x71374491 // k2
+DATA K256<>+0x08(SB)/4, $0xb5c0fbcf // k3
+DATA K256<>+0x0c(SB)/4, $0xe9b5dba5 // k4
+DATA K256<>+0x10(SB)/4, $0x428a2f98 // k1
+DATA K256<>+0x14(SB)/4, $0x71374491 // k2
+DATA K256<>+0x18(SB)/4, $0xb5c0fbcf // k3
+DATA K256<>+0x1c(SB)/4, $0xe9b5dba5 // k4
+
+DATA K256<>+0x20(SB)/4, $0x3956c25b // k5 - k8
+DATA K256<>+0x24(SB)/4, $0x59f111f1
+DATA K256<>+0x28(SB)/4, $0x923f82a4
+DATA K256<>+0x2c(SB)/4, $0xab1c5ed5
+DATA K256<>+0x30(SB)/4, $0x3956c25b
+DATA K256<>+0x34(SB)/4, $0x59f111f1
+DATA K256<>+0x38(SB)/4, $0x923f82a4
+DATA K256<>+0x3c(SB)/4, $0xab1c5ed5
+
+DATA K256<>+0x40(SB)/4, $0xd807aa98 // k9 - k12
+DATA K256<>+0x44(SB)/4, $0x12835b01
+DATA K256<>+0x48(SB)/4, $0x243185be
+DATA K256<>+0x4c(SB)/4, $0x550c7dc3
+DATA K256<>+0x50(SB)/4, $0xd807aa98
+DATA K256<>+0x54(SB)/4, $0x12835b01
+DATA K256<>+0x58(SB)/4, $0x243185be
+DATA K256<>+0x5c(SB)/4, $0x550c7dc3
+
+DATA K256<>+0x60(SB)/4, $0x72be5d74 // k13 - k16
+DATA K256<>+0x64(SB)/4, $0x80deb1fe
+DATA K256<>+0x68(SB)/4, $0x9bdc06a7
+DATA K256<>+0x6c(SB)/4, $0xc19bf174
+DATA K256<>+0x70(SB)/4, $0x72be5d74
+DATA K256<>+0x74(SB)/4, $0x80deb1fe
+DATA K256<>+0x78(SB)/4, $0x9bdc06a7
+DATA K256<>+0x7c(SB)/4, $0xc19bf174
+
+DATA K256<>+0x80(SB)/4, $0xe49b69c1 // k17 - k20
+DATA K256<>+0x84(SB)/4, $0xefbe4786
+DATA K256<>+0x88(SB)/4, $0x0fc19dc6
+DATA K256<>+0x8c(SB)/4, $0x240ca1cc
+DATA K256<>+0x90(SB)/4, $0xe49b69c1
+DATA K256<>+0x94(SB)/4, $0xefbe4786
+DATA K256<>+0x98(SB)/4, $0x0fc19dc6
+DATA K256<>+0x9c(SB)/4, $0x240ca1cc
+
+DATA K256<>+0xa0(SB)/4, $0x2de92c6f // k21 - k24
+DATA K256<>+0xa4(SB)/4, $0x4a7484aa
+DATA K256<>+0xa8(SB)/4, $0x5cb0a9dc
+DATA K256<>+0xac(SB)/4, $0x76f988da
+DATA K256<>+0xb0(SB)/4, $0x2de92c6f
+DATA K256<>+0xb4(SB)/4, $0x4a7484aa
+DATA K256<>+0xb8(SB)/4, $0x5cb0a9dc
+DATA K256<>+0xbc(SB)/4, $0x76f988da
+
+DATA K256<>+0xc0(SB)/4, $0x983e5152 // k25 - k28
+DATA K256<>+0xc4(SB)/4, $0xa831c66d
+DATA K256<>+0xc8(SB)/4, $0xb00327c8
+DATA K256<>+0xcc(SB)/4, $0xbf597fc7
+DATA K256<>+0xd0(SB)/4, $0x983e5152
+DATA K256<>+0xd4(SB)/4, $0xa831c66d
+DATA K256<>+0xd8(SB)/4, $0xb00327c8
+DATA K256<>+0xdc(SB)/4, $0xbf597fc7
+
+DATA K256<>+0xe0(SB)/4, $0xc6e00bf3 // k29 - k32
+DATA K256<>+0xe4(SB)/4, $0xd5a79147
+DATA K256<>+0xe8(SB)/4, $0x06ca6351
+DATA K256<>+0xec(SB)/4, $0x14292967
+DATA K256<>+0xf0(SB)/4, $0xc6e00bf3
+DATA K256<>+0xf4(SB)/4, $0xd5a79147
+DATA K256<>+0xf8(SB)/4, $0x06ca6351
+DATA K256<>+0xfc(SB)/4, $0x14292967
+
+DATA K256<>+0x100(SB)/4, $0x27b70a85
+DATA K256<>+0x104(SB)/4, $0x2e1b2138
+DATA K256<>+0x108(SB)/4, $0x4d2c6dfc
+DATA K256<>+0x10c(SB)/4, $0x53380d13
+DATA K256<>+0x110(SB)/4, $0x27b70a85
+DATA K256<>+0x114(SB)/4, $0x2e1b2138
+DATA K256<>+0x118(SB)/4, $0x4d2c6dfc
+DATA K256<>+0x11c(SB)/4, $0x53380d13
+
+DATA K256<>+0x120(SB)/4, $0x650a7354
+DATA K256<>+0x124(SB)/4, $0x766a0abb
+DATA K256<>+0x128(SB)/4, $0x81c2c92e
+DATA K256<>+0x12c(SB)/4, $0x92722c85
+DATA K256<>+0x130(SB)/4, $0x650a7354
+DATA K256<>+0x134(SB)/4, $0x766a0abb
+DATA K256<>+0x138(SB)/4, $0x81c2c92e
+DATA K256<>+0x13c(SB)/4, $0x92722c85
+
+DATA K256<>+0x140(SB)/4, $0xa2bfe8a1
+DATA K256<>+0x144(SB)/4, $0xa81a664b
+DATA K256<>+0x148(SB)/4, $0xc24b8b70
+DATA K256<>+0x14c(SB)/4, $0xc76c51a3
+DATA K256<>+0x150(SB)/4, $0xa2bfe8a1
+DATA K256<>+0x154(SB)/4, $0xa81a664b
+DATA K256<>+0x158(SB)/4, $0xc24b8b70
+DATA K256<>+0x15c(SB)/4, $0xc76c51a3
+
+DATA K256<>+0x160(SB)/4, $0xd192e819
+DATA K256<>+0x164(SB)/4, $0xd6990624
+DATA K256<>+0x168(SB)/4, $0xf40e3585
+DATA K256<>+0x16c(SB)/4, $0x106aa070
+DATA K256<>+0x170(SB)/4, $0xd192e819
+DATA K256<>+0x174(SB)/4, $0xd6990624
+DATA K256<>+0x178(SB)/4, $0xf40e3585
+DATA K256<>+0x17c(SB)/4, $0x106aa070
+
+DATA K256<>+0x180(SB)/4, $0x19a4c116
+DATA K256<>+0x184(SB)/4, $0x1e376c08
+DATA K256<>+0x188(SB)/4, $0x2748774c
+DATA K256<>+0x18c(SB)/4, $0x34b0bcb5
+DATA K256<>+0x190(SB)/4, $0x19a4c116
+DATA K256<>+0x194(SB)/4, $0x1e376c08
+DATA K256<>+0x198(SB)/4, $0x2748774c
+DATA K256<>+0x19c(SB)/4, $0x34b0bcb5
+
+DATA K256<>+0x1a0(SB)/4, $0x391c0cb3
+DATA K256<>+0x1a4(SB)/4, $0x4ed8aa4a
+DATA K256<>+0x1a8(SB)/4, $0x5b9cca4f
+DATA K256<>+0x1ac(SB)/4, $0x682e6ff3
+DATA K256<>+0x1b0(SB)/4, $0x391c0cb3
+DATA K256<>+0x1b4(SB)/4, $0x4ed8aa4a
+DATA K256<>+0x1b8(SB)/4, $0x5b9cca4f
+DATA K256<>+0x1bc(SB)/4, $0x682e6ff3
+
+DATA K256<>+0x1c0(SB)/4, $0x748f82ee
+DATA K256<>+0x1c4(SB)/4, $0x78a5636f
+DATA K256<>+0x1c8(SB)/4, $0x84c87814
+DATA K256<>+0x1cc(SB)/4, $0x8cc70208
+DATA K256<>+0x1d0(SB)/4, $0x748f82ee
+DATA K256<>+0x1d4(SB)/4, $0x78a5636f
+DATA K256<>+0x1d8(SB)/4, $0x84c87814
+DATA K256<>+0x1dc(SB)/4, $0x8cc70208
+
+DATA K256<>+0x1e0(SB)/4, $0x90befffa
+DATA K256<>+0x1e4(SB)/4, $0xa4506ceb
+DATA K256<>+0x1e8(SB)/4, $0xbef9a3f7
+DATA K256<>+0x1ec(SB)/4, $0xc67178f2
+DATA K256<>+0x1f0(SB)/4, $0x90befffa
+DATA K256<>+0x1f4(SB)/4, $0xa4506ceb
+DATA K256<>+0x1f8(SB)/4, $0xbef9a3f7
+DATA K256<>+0x1fc(SB)/4, $0xc67178f2
+
+GLOBL K256<>(SB), (NOPTR + RODATA), $512
diff --git a/contrib/go/_std_1.20/src/crypto/sha256/sha256block_arm64.go b/contrib/go/_std_1.21/src/crypto/sha256/sha256block_arm64.go
index e5da566363..e5da566363 100644
--- a/contrib/go/_std_1.20/src/crypto/sha256/sha256block_arm64.go
+++ b/contrib/go/_std_1.21/src/crypto/sha256/sha256block_arm64.go
diff --git a/contrib/go/_std_1.20/src/crypto/sha256/sha256block_arm64.s b/contrib/go/_std_1.21/src/crypto/sha256/sha256block_arm64.s
index d5c1eb0b2e..d5c1eb0b2e 100644
--- a/contrib/go/_std_1.20/src/crypto/sha256/sha256block_arm64.s
+++ b/contrib/go/_std_1.21/src/crypto/sha256/sha256block_arm64.s
diff --git a/contrib/go/_std_1.21/src/crypto/sha256/sha256block_decl.go b/contrib/go/_std_1.21/src/crypto/sha256/sha256block_decl.go
new file mode 100644
index 0000000000..7d68cd95fe
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/sha256/sha256block_decl.go
@@ -0,0 +1,10 @@
+// Copyright 2013 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.
+
+//go:build 386 || amd64 || s390x || ppc64le || ppc64
+
+package sha256
+
+//go:noescape
+func block(dig *digest, p []byte)
diff --git a/contrib/go/_std_1.21/src/crypto/sha256/ya.make b/contrib/go/_std_1.21/src/crypto/sha256/ya.make
new file mode 100644
index 0000000000..c4eb086700
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/sha256/ya.make
@@ -0,0 +1,30 @@
+GO_LIBRARY()
+
+SRCS(
+ sha256.go
+ sha256block.go
+)
+
+GO_TEST_SRCS(sha256_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+IF (ARCH_X86_64)
+ SRCS(
+ sha256block_amd64.go
+ sha256block_amd64.s
+ sha256block_decl.go
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ sha256block_arm64.go
+ sha256block_arm64.s
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/sha512/sha512.go b/contrib/go/_std_1.21/src/crypto/sha512/sha512.go
index 9ae1b3aae2..9ae1b3aae2 100644
--- a/contrib/go/_std_1.20/src/crypto/sha512/sha512.go
+++ b/contrib/go/_std_1.21/src/crypto/sha512/sha512.go
diff --git a/contrib/go/_std_1.20/src/crypto/sha512/sha512block.go b/contrib/go/_std_1.21/src/crypto/sha512/sha512block.go
index 81569c5f84..81569c5f84 100644
--- a/contrib/go/_std_1.20/src/crypto/sha512/sha512block.go
+++ b/contrib/go/_std_1.21/src/crypto/sha512/sha512block.go
diff --git a/contrib/go/_std_1.20/src/crypto/sha512/sha512block_amd64.go b/contrib/go/_std_1.21/src/crypto/sha512/sha512block_amd64.go
index 8da3e1473f..8da3e1473f 100644
--- a/contrib/go/_std_1.20/src/crypto/sha512/sha512block_amd64.go
+++ b/contrib/go/_std_1.21/src/crypto/sha512/sha512block_amd64.go
diff --git a/contrib/go/_std_1.20/src/crypto/sha512/sha512block_amd64.s b/contrib/go/_std_1.21/src/crypto/sha512/sha512block_amd64.s
index 0fa0df2f60..0fa0df2f60 100644
--- a/contrib/go/_std_1.20/src/crypto/sha512/sha512block_amd64.s
+++ b/contrib/go/_std_1.21/src/crypto/sha512/sha512block_amd64.s
diff --git a/contrib/go/_std_1.20/src/crypto/sha512/sha512block_arm64.go b/contrib/go/_std_1.21/src/crypto/sha512/sha512block_arm64.go
index 243eb5c1d6..243eb5c1d6 100644
--- a/contrib/go/_std_1.20/src/crypto/sha512/sha512block_arm64.go
+++ b/contrib/go/_std_1.21/src/crypto/sha512/sha512block_arm64.go
diff --git a/contrib/go/_std_1.20/src/crypto/sha512/sha512block_arm64.s b/contrib/go/_std_1.21/src/crypto/sha512/sha512block_arm64.s
index dfc35d69c3..dfc35d69c3 100644
--- a/contrib/go/_std_1.20/src/crypto/sha512/sha512block_arm64.s
+++ b/contrib/go/_std_1.21/src/crypto/sha512/sha512block_arm64.s
diff --git a/contrib/go/_std_1.21/src/crypto/sha512/ya.make b/contrib/go/_std_1.21/src/crypto/sha512/ya.make
new file mode 100644
index 0000000000..f3da001107
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/sha512/ya.make
@@ -0,0 +1,27 @@
+GO_LIBRARY()
+
+SRCS(
+ sha512.go
+ sha512block.go
+)
+
+GO_TEST_SRCS(sha512_test.go)
+
+IF (ARCH_X86_64)
+ SRCS(
+ sha512block_amd64.go
+ sha512block_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ sha512block_arm64.go
+ sha512block_arm64.s
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/subtle/constant_time.go b/contrib/go/_std_1.21/src/crypto/subtle/constant_time.go
index 4e0527f9d5..4e0527f9d5 100644
--- a/contrib/go/_std_1.20/src/crypto/subtle/constant_time.go
+++ b/contrib/go/_std_1.21/src/crypto/subtle/constant_time.go
diff --git a/contrib/go/_std_1.20/src/crypto/subtle/xor.go b/contrib/go/_std_1.21/src/crypto/subtle/xor.go
index a8805ac61d..a8805ac61d 100644
--- a/contrib/go/_std_1.20/src/crypto/subtle/xor.go
+++ b/contrib/go/_std_1.21/src/crypto/subtle/xor.go
diff --git a/contrib/go/_std_1.20/src/crypto/subtle/xor_amd64.go b/contrib/go/_std_1.21/src/crypto/subtle/xor_amd64.go
index 3bb2f08b7c..3bb2f08b7c 100644
--- a/contrib/go/_std_1.20/src/crypto/subtle/xor_amd64.go
+++ b/contrib/go/_std_1.21/src/crypto/subtle/xor_amd64.go
diff --git a/contrib/go/_std_1.20/src/crypto/subtle/xor_amd64.s b/contrib/go/_std_1.21/src/crypto/subtle/xor_amd64.s
index 8b04b58702..8b04b58702 100644
--- a/contrib/go/_std_1.20/src/crypto/subtle/xor_amd64.s
+++ b/contrib/go/_std_1.21/src/crypto/subtle/xor_amd64.s
diff --git a/contrib/go/_std_1.20/src/crypto/subtle/xor_arm64.go b/contrib/go/_std_1.21/src/crypto/subtle/xor_arm64.go
index 65bab4c657..65bab4c657 100644
--- a/contrib/go/_std_1.20/src/crypto/subtle/xor_arm64.go
+++ b/contrib/go/_std_1.21/src/crypto/subtle/xor_arm64.go
diff --git a/contrib/go/_std_1.20/src/crypto/subtle/xor_arm64.s b/contrib/go/_std_1.21/src/crypto/subtle/xor_arm64.s
index 76321645d7..76321645d7 100644
--- a/contrib/go/_std_1.20/src/crypto/subtle/xor_arm64.s
+++ b/contrib/go/_std_1.21/src/crypto/subtle/xor_arm64.s
diff --git a/contrib/go/_std_1.21/src/crypto/subtle/ya.make b/contrib/go/_std_1.21/src/crypto/subtle/ya.make
new file mode 100644
index 0000000000..e2c71e7a2a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/subtle/ya.make
@@ -0,0 +1,29 @@
+GO_LIBRARY()
+
+SRCS(
+ constant_time.go
+ xor.go
+)
+
+GO_TEST_SRCS(constant_time_test.go)
+
+GO_XTEST_SRCS(xor_test.go)
+
+IF (ARCH_X86_64)
+ SRCS(
+ xor_amd64.go
+ xor_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ xor_arm64.go
+ xor_arm64.s
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/crypto/tls/alert.go b/contrib/go/_std_1.21/src/crypto/tls/alert.go
new file mode 100644
index 0000000000..33022cd2b4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/alert.go
@@ -0,0 +1,109 @@
+// Copyright 2009 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 tls
+
+import "strconv"
+
+// An AlertError is a TLS alert.
+//
+// When using a QUIC transport, QUICConn methods will return an error
+// which wraps AlertError rather than sending a TLS alert.
+type AlertError uint8
+
+func (e AlertError) Error() string {
+ return alert(e).String()
+}
+
+type alert uint8
+
+const (
+ // alert level
+ alertLevelWarning = 1
+ alertLevelError = 2
+)
+
+const (
+ alertCloseNotify alert = 0
+ alertUnexpectedMessage alert = 10
+ alertBadRecordMAC alert = 20
+ alertDecryptionFailed alert = 21
+ alertRecordOverflow alert = 22
+ alertDecompressionFailure alert = 30
+ alertHandshakeFailure alert = 40
+ alertBadCertificate alert = 42
+ alertUnsupportedCertificate alert = 43
+ alertCertificateRevoked alert = 44
+ alertCertificateExpired alert = 45
+ alertCertificateUnknown alert = 46
+ alertIllegalParameter alert = 47
+ alertUnknownCA alert = 48
+ alertAccessDenied alert = 49
+ alertDecodeError alert = 50
+ alertDecryptError alert = 51
+ alertExportRestriction alert = 60
+ alertProtocolVersion alert = 70
+ alertInsufficientSecurity alert = 71
+ alertInternalError alert = 80
+ alertInappropriateFallback alert = 86
+ alertUserCanceled alert = 90
+ alertNoRenegotiation alert = 100
+ alertMissingExtension alert = 109
+ alertUnsupportedExtension alert = 110
+ alertCertificateUnobtainable alert = 111
+ alertUnrecognizedName alert = 112
+ alertBadCertificateStatusResponse alert = 113
+ alertBadCertificateHashValue alert = 114
+ alertUnknownPSKIdentity alert = 115
+ alertCertificateRequired alert = 116
+ alertNoApplicationProtocol alert = 120
+)
+
+var alertText = map[alert]string{
+ alertCloseNotify: "close notify",
+ alertUnexpectedMessage: "unexpected message",
+ alertBadRecordMAC: "bad record MAC",
+ alertDecryptionFailed: "decryption failed",
+ alertRecordOverflow: "record overflow",
+ alertDecompressionFailure: "decompression failure",
+ alertHandshakeFailure: "handshake failure",
+ alertBadCertificate: "bad certificate",
+ alertUnsupportedCertificate: "unsupported certificate",
+ alertCertificateRevoked: "revoked certificate",
+ alertCertificateExpired: "expired certificate",
+ alertCertificateUnknown: "unknown certificate",
+ alertIllegalParameter: "illegal parameter",
+ alertUnknownCA: "unknown certificate authority",
+ alertAccessDenied: "access denied",
+ alertDecodeError: "error decoding message",
+ alertDecryptError: "error decrypting message",
+ alertExportRestriction: "export restriction",
+ alertProtocolVersion: "protocol version not supported",
+ alertInsufficientSecurity: "insufficient security level",
+ alertInternalError: "internal error",
+ alertInappropriateFallback: "inappropriate fallback",
+ alertUserCanceled: "user canceled",
+ alertNoRenegotiation: "no renegotiation",
+ alertMissingExtension: "missing extension",
+ alertUnsupportedExtension: "unsupported extension",
+ alertCertificateUnobtainable: "certificate unobtainable",
+ alertUnrecognizedName: "unrecognized name",
+ alertBadCertificateStatusResponse: "bad certificate status response",
+ alertBadCertificateHashValue: "bad certificate hash value",
+ alertUnknownPSKIdentity: "unknown PSK identity",
+ alertCertificateRequired: "certificate required",
+ alertNoApplicationProtocol: "no application protocol",
+}
+
+func (e alert) String() string {
+ s, ok := alertText[e]
+ if ok {
+ return "tls: " + s
+ }
+ return "tls: alert(" + strconv.Itoa(int(e)) + ")"
+}
+
+func (e alert) Error() string {
+ return e.String()
+}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/auth.go b/contrib/go/_std_1.21/src/crypto/tls/auth.go
index 7c5675c6d9..7c5675c6d9 100644
--- a/contrib/go/_std_1.20/src/crypto/tls/auth.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/auth.go
diff --git a/contrib/go/_std_1.21/src/crypto/tls/cache.go b/contrib/go/_std_1.21/src/crypto/tls/cache.go
new file mode 100644
index 0000000000..a7677611fd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/cache.go
@@ -0,0 +1,95 @@
+// Copyright 2022 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 tls
+
+import (
+ "crypto/x509"
+ "runtime"
+ "sync"
+ "sync/atomic"
+)
+
+type cacheEntry struct {
+ refs atomic.Int64
+ cert *x509.Certificate
+}
+
+// certCache implements an intern table for reference counted x509.Certificates,
+// implemented in a similar fashion to BoringSSL's CRYPTO_BUFFER_POOL. This
+// allows for a single x509.Certificate to be kept in memory and referenced from
+// multiple Conns. Returned references should not be mutated by callers. Certificates
+// are still safe to use after they are removed from the cache.
+//
+// Certificates are returned wrapped in an activeCert struct that should be held by
+// the caller. When references to the activeCert are freed, the number of references
+// to the certificate in the cache is decremented. Once the number of references
+// reaches zero, the entry is evicted from the cache.
+//
+// The main difference between this implementation and CRYPTO_BUFFER_POOL is that
+// CRYPTO_BUFFER_POOL is a more generic structure which supports blobs of data,
+// rather than specific structures. Since we only care about x509.Certificates,
+// certCache is implemented as a specific cache, rather than a generic one.
+//
+// See https://boringssl.googlesource.com/boringssl/+/master/include/openssl/pool.h
+// and https://boringssl.googlesource.com/boringssl/+/master/crypto/pool/pool.c
+// for the BoringSSL reference.
+type certCache struct {
+ sync.Map
+}
+
+var globalCertCache = new(certCache)
+
+// activeCert is a handle to a certificate held in the cache. Once there are
+// no alive activeCerts for a given certificate, the certificate is removed
+// from the cache by a finalizer.
+type activeCert struct {
+ cert *x509.Certificate
+}
+
+// active increments the number of references to the entry, wraps the
+// certificate in the entry in an activeCert, and sets the finalizer.
+//
+// Note that there is a race between active and the finalizer set on the
+// returned activeCert, triggered if active is called after the ref count is
+// decremented such that refs may be > 0 when evict is called. We consider this
+// safe, since the caller holding an activeCert for an entry that is no longer
+// in the cache is fine, with the only side effect being the memory overhead of
+// there being more than one distinct reference to a certificate alive at once.
+func (cc *certCache) active(e *cacheEntry) *activeCert {
+ e.refs.Add(1)
+ a := &activeCert{e.cert}
+ runtime.SetFinalizer(a, func(_ *activeCert) {
+ if e.refs.Add(-1) == 0 {
+ cc.evict(e)
+ }
+ })
+ return a
+}
+
+// evict removes a cacheEntry from the cache.
+func (cc *certCache) evict(e *cacheEntry) {
+ cc.Delete(string(e.cert.Raw))
+}
+
+// newCert returns a x509.Certificate parsed from der. If there is already a copy
+// of the certificate in the cache, a reference to the existing certificate will
+// be returned. Otherwise, a fresh certificate will be added to the cache, and
+// the reference returned. The returned reference should not be mutated.
+func (cc *certCache) newCert(der []byte) (*activeCert, error) {
+ if entry, ok := cc.Load(string(der)); ok {
+ return cc.active(entry.(*cacheEntry)), nil
+ }
+
+ cert, err := x509.ParseCertificate(der)
+ if err != nil {
+ return nil, err
+ }
+
+ entry := &cacheEntry{cert: cert}
+ if entry, loaded := cc.LoadOrStore(string(der), entry); loaded {
+ return cc.active(entry.(*cacheEntry)), nil
+ }
+ return cc.active(entry), nil
+}
diff --git a/contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go b/contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go
new file mode 100644
index 0000000000..589e8b6faf
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/cipher_suites.go
@@ -0,0 +1,694 @@
+// Copyright 2010 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 tls
+
+import (
+ "crypto"
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/des"
+ "crypto/hmac"
+ "crypto/internal/boring"
+ "crypto/rc4"
+ "crypto/sha1"
+ "crypto/sha256"
+ "fmt"
+ "hash"
+ "internal/cpu"
+ "runtime"
+
+ "golang.org/x/crypto/chacha20poly1305"
+)
+
+// CipherSuite is a TLS cipher suite. Note that most functions in this package
+// accept and expose cipher suite IDs instead of this type.
+type CipherSuite struct {
+ ID uint16
+ Name string
+
+ // Supported versions is the list of TLS protocol versions that can
+ // negotiate this cipher suite.
+ SupportedVersions []uint16
+
+ // Insecure is true if the cipher suite has known security issues
+ // due to its primitives, design, or implementation.
+ Insecure bool
+}
+
+var (
+ supportedUpToTLS12 = []uint16{VersionTLS10, VersionTLS11, VersionTLS12}
+ supportedOnlyTLS12 = []uint16{VersionTLS12}
+ supportedOnlyTLS13 = []uint16{VersionTLS13}
+)
+
+// CipherSuites returns a list of cipher suites currently implemented by this
+// package, excluding those with security issues, which are returned by
+// InsecureCipherSuites.
+//
+// The list is sorted by ID. Note that the default cipher suites selected by
+// this package might depend on logic that can't be captured by a static list,
+// and might not match those returned by this function.
+func CipherSuites() []*CipherSuite {
+ return []*CipherSuite{
+ {TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
+ {TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
+ {TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
+ {TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
+
+ {TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256", supportedOnlyTLS13, false},
+ {TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384", supportedOnlyTLS13, false},
+ {TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256", supportedOnlyTLS13, false},
+
+ {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
+ {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
+ {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
+ {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
+ {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
+ {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
+ {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
+ {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
+ {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
+ }
+}
+
+// InsecureCipherSuites returns a list of cipher suites currently implemented by
+// this package and which have security issues.
+//
+// Most applications should not use the cipher suites in this list, and should
+// only use those returned by CipherSuites.
+func InsecureCipherSuites() []*CipherSuite {
+ // This list includes RC4, CBC_SHA256, and 3DES cipher suites. See
+ // cipherSuitesPreferenceOrder for details.
+ return []*CipherSuite{
+ {TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
+ {TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
+ {TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
+ {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
+ {TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
+ {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
+ {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
+ }
+}
+
+// CipherSuiteName returns the standard name for the passed cipher suite ID
+// (e.g. "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), or a fallback representation
+// of the ID value if the cipher suite is not implemented by this package.
+func CipherSuiteName(id uint16) string {
+ for _, c := range CipherSuites() {
+ if c.ID == id {
+ return c.Name
+ }
+ }
+ for _, c := range InsecureCipherSuites() {
+ if c.ID == id {
+ return c.Name
+ }
+ }
+ return fmt.Sprintf("0x%04X", id)
+}
+
+const (
+ // suiteECDHE indicates that the cipher suite involves elliptic curve
+ // Diffie-Hellman. This means that it should only be selected when the
+ // client indicates that it supports ECC with a curve and point format
+ // that we're happy with.
+ suiteECDHE = 1 << iota
+ // suiteECSign indicates that the cipher suite involves an ECDSA or
+ // EdDSA signature and therefore may only be selected when the server's
+ // certificate is ECDSA or EdDSA. If this is not set then the cipher suite
+ // is RSA based.
+ suiteECSign
+ // suiteTLS12 indicates that the cipher suite should only be advertised
+ // and accepted when using TLS 1.2.
+ suiteTLS12
+ // suiteSHA384 indicates that the cipher suite uses SHA384 as the
+ // handshake hash.
+ suiteSHA384
+)
+
+// A cipherSuite is a TLS 1.0–1.2 cipher suite, and defines the key exchange
+// mechanism, as well as the cipher+MAC pair or the AEAD.
+type cipherSuite struct {
+ id uint16
+ // the lengths, in bytes, of the key material needed for each component.
+ keyLen int
+ macLen int
+ ivLen int
+ ka func(version uint16) keyAgreement
+ // flags is a bitmask of the suite* values, above.
+ flags int
+ cipher func(key, iv []byte, isRead bool) any
+ mac func(key []byte) hash.Hash
+ aead func(key, fixedNonce []byte) aead
+}
+
+var cipherSuites = []*cipherSuite{ // TODO: replace with a map, since the order doesn't matter.
+ {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
+ {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
+ {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadAESGCM},
+ {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
+ {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
+ {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil},
+ {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, cipherAES, macSHA256, nil},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
+ {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
+ {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
+ {TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
+ {TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
+ {TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil},
+ {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
+ {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
+ {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
+ {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
+ {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil},
+ {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil},
+ {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherRC4, macSHA1, nil},
+}
+
+// selectCipherSuite returns the first TLS 1.0–1.2 cipher suite from ids which
+// is also in supportedIDs and passes the ok filter.
+func selectCipherSuite(ids, supportedIDs []uint16, ok func(*cipherSuite) bool) *cipherSuite {
+ for _, id := range ids {
+ candidate := cipherSuiteByID(id)
+ if candidate == nil || !ok(candidate) {
+ continue
+ }
+
+ for _, suppID := range supportedIDs {
+ if id == suppID {
+ return candidate
+ }
+ }
+ }
+ return nil
+}
+
+// A cipherSuiteTLS13 defines only the pair of the AEAD algorithm and hash
+// algorithm to be used with HKDF. See RFC 8446, Appendix B.4.
+type cipherSuiteTLS13 struct {
+ id uint16
+ keyLen int
+ aead func(key, fixedNonce []byte) aead
+ hash crypto.Hash
+}
+
+var cipherSuitesTLS13 = []*cipherSuiteTLS13{ // TODO: replace with a map.
+ {TLS_AES_128_GCM_SHA256, 16, aeadAESGCMTLS13, crypto.SHA256},
+ {TLS_CHACHA20_POLY1305_SHA256, 32, aeadChaCha20Poly1305, crypto.SHA256},
+ {TLS_AES_256_GCM_SHA384, 32, aeadAESGCMTLS13, crypto.SHA384},
+}
+
+// cipherSuitesPreferenceOrder is the order in which we'll select (on the
+// server) or advertise (on the client) TLS 1.0–1.2 cipher suites.
+//
+// Cipher suites are filtered but not reordered based on the application and
+// peer's preferences, meaning we'll never select a suite lower in this list if
+// any higher one is available. This makes it more defensible to keep weaker
+// cipher suites enabled, especially on the server side where we get the last
+// word, since there are no known downgrade attacks on cipher suites selection.
+//
+// The list is sorted by applying the following priority rules, stopping at the
+// first (most important) applicable one:
+//
+// - Anything else comes before RC4
+//
+// RC4 has practically exploitable biases. See https://www.rc4nomore.com.
+//
+// - Anything else comes before CBC_SHA256
+//
+// SHA-256 variants of the CBC ciphersuites don't implement any Lucky13
+// countermeasures. See http://www.isg.rhul.ac.uk/tls/Lucky13.html and
+// https://www.imperialviolet.org/2013/02/04/luckythirteen.html.
+//
+// - Anything else comes before 3DES
+//
+// 3DES has 64-bit blocks, which makes it fundamentally susceptible to
+// birthday attacks. See https://sweet32.info.
+//
+// - ECDHE comes before anything else
+//
+// Once we got the broken stuff out of the way, the most important
+// property a cipher suite can have is forward secrecy. We don't
+// implement FFDHE, so that means ECDHE.
+//
+// - AEADs come before CBC ciphers
+//
+// Even with Lucky13 countermeasures, MAC-then-Encrypt CBC cipher suites
+// are fundamentally fragile, and suffered from an endless sequence of
+// padding oracle attacks. See https://eprint.iacr.org/2015/1129,
+// https://www.imperialviolet.org/2014/12/08/poodleagain.html, and
+// https://blog.cloudflare.com/yet-another-padding-oracle-in-openssl-cbc-ciphersuites/.
+//
+// - AES comes before ChaCha20
+//
+// When AES hardware is available, AES-128-GCM and AES-256-GCM are faster
+// than ChaCha20Poly1305.
+//
+// When AES hardware is not available, AES-128-GCM is one or more of: much
+// slower, way more complex, and less safe (because not constant time)
+// than ChaCha20Poly1305.
+//
+// We use this list if we think both peers have AES hardware, and
+// cipherSuitesPreferenceOrderNoAES otherwise.
+//
+// - AES-128 comes before AES-256
+//
+// The only potential advantages of AES-256 are better multi-target
+// margins, and hypothetical post-quantum properties. Neither apply to
+// TLS, and AES-256 is slower due to its four extra rounds (which don't
+// contribute to the advantages above).
+//
+// - ECDSA comes before RSA
+//
+// The relative order of ECDSA and RSA cipher suites doesn't matter,
+// as they depend on the certificate. Pick one to get a stable order.
+var cipherSuitesPreferenceOrder = []uint16{
+ // AEADs w/ ECDHE
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+
+ // CBC w/ ECDHE
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+
+ // AEADs w/o ECDHE
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+
+ // CBC w/o ECDHE
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+
+ // 3DES
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+
+ // CBC_SHA256
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+
+ // RC4
+ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+ TLS_RSA_WITH_RC4_128_SHA,
+}
+
+var cipherSuitesPreferenceOrderNoAES = []uint16{
+ // ChaCha20Poly1305
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+
+ // AES-GCM w/ ECDHE
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+
+ // The rest of cipherSuitesPreferenceOrder.
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+ TLS_RSA_WITH_RC4_128_SHA,
+}
+
+// disabledCipherSuites are not used unless explicitly listed in
+// Config.CipherSuites. They MUST be at the end of cipherSuitesPreferenceOrder.
+var disabledCipherSuites = []uint16{
+ // CBC_SHA256
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+
+ // RC4
+ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+ TLS_RSA_WITH_RC4_128_SHA,
+}
+
+var (
+ defaultCipherSuitesLen = len(cipherSuitesPreferenceOrder) - len(disabledCipherSuites)
+ defaultCipherSuites = cipherSuitesPreferenceOrder[:defaultCipherSuitesLen]
+)
+
+// defaultCipherSuitesTLS13 is also the preference order, since there are no
+// disabled by default TLS 1.3 cipher suites. The same AES vs ChaCha20 logic as
+// cipherSuitesPreferenceOrder applies.
+var defaultCipherSuitesTLS13 = []uint16{
+ TLS_AES_128_GCM_SHA256,
+ TLS_AES_256_GCM_SHA384,
+ TLS_CHACHA20_POLY1305_SHA256,
+}
+
+var defaultCipherSuitesTLS13NoAES = []uint16{
+ TLS_CHACHA20_POLY1305_SHA256,
+ TLS_AES_128_GCM_SHA256,
+ TLS_AES_256_GCM_SHA384,
+}
+
+var (
+ hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ
+ hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
+ // Keep in sync with crypto/aes/cipher_s390x.go.
+ hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR &&
+ (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)
+
+ hasAESGCMHardwareSupport = runtime.GOARCH == "amd64" && hasGCMAsmAMD64 ||
+ runtime.GOARCH == "arm64" && hasGCMAsmARM64 ||
+ runtime.GOARCH == "s390x" && hasGCMAsmS390X
+)
+
+var aesgcmCiphers = map[uint16]bool{
+ // TLS 1.2
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: true,
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: true,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true,
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true,
+ // TLS 1.3
+ TLS_AES_128_GCM_SHA256: true,
+ TLS_AES_256_GCM_SHA384: true,
+}
+
+// aesgcmPreferred returns whether the first known cipher in the preference list
+// is an AES-GCM cipher, implying the peer has hardware support for it.
+func aesgcmPreferred(ciphers []uint16) bool {
+ for _, cID := range ciphers {
+ if c := cipherSuiteByID(cID); c != nil {
+ return aesgcmCiphers[cID]
+ }
+ if c := cipherSuiteTLS13ByID(cID); c != nil {
+ return aesgcmCiphers[cID]
+ }
+ }
+ return false
+}
+
+func cipherRC4(key, iv []byte, isRead bool) any {
+ cipher, _ := rc4.NewCipher(key)
+ return cipher
+}
+
+func cipher3DES(key, iv []byte, isRead bool) any {
+ block, _ := des.NewTripleDESCipher(key)
+ if isRead {
+ return cipher.NewCBCDecrypter(block, iv)
+ }
+ return cipher.NewCBCEncrypter(block, iv)
+}
+
+func cipherAES(key, iv []byte, isRead bool) any {
+ block, _ := aes.NewCipher(key)
+ if isRead {
+ return cipher.NewCBCDecrypter(block, iv)
+ }
+ return cipher.NewCBCEncrypter(block, iv)
+}
+
+// macSHA1 returns a SHA-1 based constant time MAC.
+func macSHA1(key []byte) hash.Hash {
+ h := sha1.New
+ // The BoringCrypto SHA1 does not have a constant-time
+ // checksum function, so don't try to use it.
+ if !boring.Enabled {
+ h = newConstantTimeHash(h)
+ }
+ return hmac.New(h, key)
+}
+
+// macSHA256 returns a SHA-256 based MAC. This is only supported in TLS 1.2 and
+// is currently only used in disabled-by-default cipher suites.
+func macSHA256(key []byte) hash.Hash {
+ return hmac.New(sha256.New, key)
+}
+
+type aead interface {
+ cipher.AEAD
+
+ // explicitNonceLen returns the number of bytes of explicit nonce
+ // included in each record. This is eight for older AEADs and
+ // zero for modern ones.
+ explicitNonceLen() int
+}
+
+const (
+ aeadNonceLength = 12
+ noncePrefixLength = 4
+)
+
+// prefixNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to
+// each call.
+type prefixNonceAEAD struct {
+ // nonce contains the fixed part of the nonce in the first four bytes.
+ nonce [aeadNonceLength]byte
+ aead cipher.AEAD
+}
+
+func (f *prefixNonceAEAD) NonceSize() int { return aeadNonceLength - noncePrefixLength }
+func (f *prefixNonceAEAD) Overhead() int { return f.aead.Overhead() }
+func (f *prefixNonceAEAD) explicitNonceLen() int { return f.NonceSize() }
+
+func (f *prefixNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
+ copy(f.nonce[4:], nonce)
+ return f.aead.Seal(out, f.nonce[:], plaintext, additionalData)
+}
+
+func (f *prefixNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+ copy(f.nonce[4:], nonce)
+ return f.aead.Open(out, f.nonce[:], ciphertext, additionalData)
+}
+
+// xorNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce
+// before each call.
+type xorNonceAEAD struct {
+ nonceMask [aeadNonceLength]byte
+ aead cipher.AEAD
+}
+
+func (f *xorNonceAEAD) NonceSize() int { return 8 } // 64-bit sequence number
+func (f *xorNonceAEAD) Overhead() int { return f.aead.Overhead() }
+func (f *xorNonceAEAD) explicitNonceLen() int { return 0 }
+
+func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
+ for i, b := range nonce {
+ f.nonceMask[4+i] ^= b
+ }
+ result := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData)
+ for i, b := range nonce {
+ f.nonceMask[4+i] ^= b
+ }
+
+ return result
+}
+
+func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+ for i, b := range nonce {
+ f.nonceMask[4+i] ^= b
+ }
+ result, err := f.aead.Open(out, f.nonceMask[:], ciphertext, additionalData)
+ for i, b := range nonce {
+ f.nonceMask[4+i] ^= b
+ }
+
+ return result, err
+}
+
+func aeadAESGCM(key, noncePrefix []byte) aead {
+ if len(noncePrefix) != noncePrefixLength {
+ panic("tls: internal error: wrong nonce length")
+ }
+ aes, err := aes.NewCipher(key)
+ if err != nil {
+ panic(err)
+ }
+ var aead cipher.AEAD
+ if boring.Enabled {
+ aead, err = boring.NewGCMTLS(aes)
+ } else {
+ boring.Unreachable()
+ aead, err = cipher.NewGCM(aes)
+ }
+ if err != nil {
+ panic(err)
+ }
+
+ ret := &prefixNonceAEAD{aead: aead}
+ copy(ret.nonce[:], noncePrefix)
+ return ret
+}
+
+func aeadAESGCMTLS13(key, nonceMask []byte) aead {
+ if len(nonceMask) != aeadNonceLength {
+ panic("tls: internal error: wrong nonce length")
+ }
+ aes, err := aes.NewCipher(key)
+ if err != nil {
+ panic(err)
+ }
+ aead, err := cipher.NewGCM(aes)
+ if err != nil {
+ panic(err)
+ }
+
+ ret := &xorNonceAEAD{aead: aead}
+ copy(ret.nonceMask[:], nonceMask)
+ return ret
+}
+
+func aeadChaCha20Poly1305(key, nonceMask []byte) aead {
+ if len(nonceMask) != aeadNonceLength {
+ panic("tls: internal error: wrong nonce length")
+ }
+ aead, err := chacha20poly1305.New(key)
+ if err != nil {
+ panic(err)
+ }
+
+ ret := &xorNonceAEAD{aead: aead}
+ copy(ret.nonceMask[:], nonceMask)
+ return ret
+}
+
+type constantTimeHash interface {
+ hash.Hash
+ ConstantTimeSum(b []byte) []byte
+}
+
+// cthWrapper wraps any hash.Hash that implements ConstantTimeSum, and replaces
+// with that all calls to Sum. It's used to obtain a ConstantTimeSum-based HMAC.
+type cthWrapper struct {
+ h constantTimeHash
+}
+
+func (c *cthWrapper) Size() int { return c.h.Size() }
+func (c *cthWrapper) BlockSize() int { return c.h.BlockSize() }
+func (c *cthWrapper) Reset() { c.h.Reset() }
+func (c *cthWrapper) Write(p []byte) (int, error) { return c.h.Write(p) }
+func (c *cthWrapper) Sum(b []byte) []byte { return c.h.ConstantTimeSum(b) }
+
+func newConstantTimeHash(h func() hash.Hash) func() hash.Hash {
+ boring.Unreachable()
+ return func() hash.Hash {
+ return &cthWrapper{h().(constantTimeHash)}
+ }
+}
+
+// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3.
+func tls10MAC(h hash.Hash, out, seq, header, data, extra []byte) []byte {
+ h.Reset()
+ h.Write(seq)
+ h.Write(header)
+ h.Write(data)
+ res := h.Sum(out)
+ if extra != nil {
+ h.Write(extra)
+ }
+ return res
+}
+
+func rsaKA(version uint16) keyAgreement {
+ return rsaKeyAgreement{}
+}
+
+func ecdheECDSAKA(version uint16) keyAgreement {
+ return &ecdheKeyAgreement{
+ isRSA: false,
+ version: version,
+ }
+}
+
+func ecdheRSAKA(version uint16) keyAgreement {
+ return &ecdheKeyAgreement{
+ isRSA: true,
+ version: version,
+ }
+}
+
+// mutualCipherSuite returns a cipherSuite given a list of supported
+// ciphersuites and the id requested by the peer.
+func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
+ for _, id := range have {
+ if id == want {
+ return cipherSuiteByID(id)
+ }
+ }
+ return nil
+}
+
+func cipherSuiteByID(id uint16) *cipherSuite {
+ for _, cipherSuite := range cipherSuites {
+ if cipherSuite.id == id {
+ return cipherSuite
+ }
+ }
+ return nil
+}
+
+func mutualCipherSuiteTLS13(have []uint16, want uint16) *cipherSuiteTLS13 {
+ for _, id := range have {
+ if id == want {
+ return cipherSuiteTLS13ByID(id)
+ }
+ }
+ return nil
+}
+
+func cipherSuiteTLS13ByID(id uint16) *cipherSuiteTLS13 {
+ for _, cipherSuite := range cipherSuitesTLS13 {
+ if cipherSuite.id == id {
+ return cipherSuite
+ }
+ }
+ return nil
+}
+
+// A list of cipher suite IDs that are, or have been, implemented by this
+// package.
+//
+// See https://www.iana.org/assignments/tls-parameters/tls-parameters.xml
+const (
+ // TLS 1.0 - 1.2 cipher suites.
+ TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
+ TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
+ TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
+ TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c
+ TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c
+ TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d
+ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
+ TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca8
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9
+
+ // TLS 1.3 cipher suites.
+ TLS_AES_128_GCM_SHA256 uint16 = 0x1301
+ TLS_AES_256_GCM_SHA384 uint16 = 0x1302
+ TLS_CHACHA20_POLY1305_SHA256 uint16 = 0x1303
+
+ // TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator
+ // that the client is doing version fallback. See RFC 7507.
+ TLS_FALLBACK_SCSV uint16 = 0x5600
+
+ // Legacy names for the corresponding cipher suites with the correct _SHA256
+ // suffix, retained for backward compatibility.
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+)
diff --git a/contrib/go/_std_1.21/src/crypto/tls/common.go b/contrib/go/_std_1.21/src/crypto/tls/common.go
new file mode 100644
index 0000000000..e0885a0da9
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/common.go
@@ -0,0 +1,1547 @@
+// Copyright 2009 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 tls
+
+import (
+ "bytes"
+ "container/list"
+ "context"
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha512"
+ "crypto/x509"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "strings"
+ "sync"
+ "time"
+)
+
+const (
+ VersionTLS10 = 0x0301
+ VersionTLS11 = 0x0302
+ VersionTLS12 = 0x0303
+ VersionTLS13 = 0x0304
+
+ // Deprecated: SSLv3 is cryptographically broken, and is no longer
+ // supported by this package. See golang.org/issue/32716.
+ VersionSSL30 = 0x0300
+)
+
+// VersionName returns the name for the provided TLS version number
+// (e.g. "TLS 1.3"), or a fallback representation of the value if the
+// version is not implemented by this package.
+func VersionName(version uint16) string {
+ switch version {
+ case VersionSSL30:
+ return "SSLv3"
+ case VersionTLS10:
+ return "TLS 1.0"
+ case VersionTLS11:
+ return "TLS 1.1"
+ case VersionTLS12:
+ return "TLS 1.2"
+ case VersionTLS13:
+ return "TLS 1.3"
+ default:
+ return fmt.Sprintf("0x%04X", version)
+ }
+}
+
+const (
+ maxPlaintext = 16384 // maximum plaintext payload length
+ maxCiphertext = 16384 + 2048 // maximum ciphertext payload length
+ maxCiphertextTLS13 = 16384 + 256 // maximum ciphertext length in TLS 1.3
+ recordHeaderLen = 5 // record header length
+ maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB)
+ maxUselessRecords = 16 // maximum number of consecutive non-advancing records
+)
+
+// TLS record types.
+type recordType uint8
+
+const (
+ recordTypeChangeCipherSpec recordType = 20
+ recordTypeAlert recordType = 21
+ recordTypeHandshake recordType = 22
+ recordTypeApplicationData recordType = 23
+)
+
+// TLS handshake message types.
+const (
+ typeHelloRequest uint8 = 0
+ typeClientHello uint8 = 1
+ typeServerHello uint8 = 2
+ typeNewSessionTicket uint8 = 4
+ typeEndOfEarlyData uint8 = 5
+ typeEncryptedExtensions uint8 = 8
+ typeCertificate uint8 = 11
+ typeServerKeyExchange uint8 = 12
+ typeCertificateRequest uint8 = 13
+ typeServerHelloDone uint8 = 14
+ typeCertificateVerify uint8 = 15
+ typeClientKeyExchange uint8 = 16
+ typeFinished uint8 = 20
+ typeCertificateStatus uint8 = 22
+ typeKeyUpdate uint8 = 24
+ typeNextProtocol uint8 = 67 // Not IANA assigned
+ typeMessageHash uint8 = 254 // synthetic message
+)
+
+// TLS compression types.
+const (
+ compressionNone uint8 = 0
+)
+
+// TLS extension numbers
+const (
+ extensionServerName uint16 = 0
+ extensionStatusRequest uint16 = 5
+ extensionSupportedCurves uint16 = 10 // supported_groups in TLS 1.3, see RFC 8446, Section 4.2.7
+ extensionSupportedPoints uint16 = 11
+ extensionSignatureAlgorithms uint16 = 13
+ extensionALPN uint16 = 16
+ extensionSCT uint16 = 18
+ extensionExtendedMasterSecret uint16 = 23
+ extensionSessionTicket uint16 = 35
+ extensionPreSharedKey uint16 = 41
+ extensionEarlyData uint16 = 42
+ extensionSupportedVersions uint16 = 43
+ extensionCookie uint16 = 44
+ extensionPSKModes uint16 = 45
+ extensionCertificateAuthorities uint16 = 47
+ extensionSignatureAlgorithmsCert uint16 = 50
+ extensionKeyShare uint16 = 51
+ extensionQUICTransportParameters uint16 = 57
+ extensionRenegotiationInfo uint16 = 0xff01
+)
+
+// TLS signaling cipher suite values
+const (
+ scsvRenegotiation uint16 = 0x00ff
+)
+
+// CurveID is the type of a TLS identifier for an elliptic curve. See
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8.
+//
+// In TLS 1.3, this type is called NamedGroup, but at this time this library
+// only supports Elliptic Curve based groups. See RFC 8446, Section 4.2.7.
+type CurveID uint16
+
+const (
+ CurveP256 CurveID = 23
+ CurveP384 CurveID = 24
+ CurveP521 CurveID = 25
+ X25519 CurveID = 29
+)
+
+// TLS 1.3 Key Share. See RFC 8446, Section 4.2.8.
+type keyShare struct {
+ group CurveID
+ data []byte
+}
+
+// TLS 1.3 PSK Key Exchange Modes. See RFC 8446, Section 4.2.9.
+const (
+ pskModePlain uint8 = 0
+ pskModeDHE uint8 = 1
+)
+
+// TLS 1.3 PSK Identity. Can be a Session Ticket, or a reference to a saved
+// session. See RFC 8446, Section 4.2.11.
+type pskIdentity struct {
+ label []byte
+ obfuscatedTicketAge uint32
+}
+
+// TLS Elliptic Curve Point Formats
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
+const (
+ pointFormatUncompressed uint8 = 0
+)
+
+// TLS CertificateStatusType (RFC 3546)
+const (
+ statusTypeOCSP uint8 = 1
+)
+
+// Certificate types (for certificateRequestMsg)
+const (
+ certTypeRSASign = 1
+ certTypeECDSASign = 64 // ECDSA or EdDSA keys, see RFC 8422, Section 3.
+)
+
+// Signature algorithms (for internal signaling use). Starting at 225 to avoid overlap with
+// TLS 1.2 codepoints (RFC 5246, Appendix A.4.1), with which these have nothing to do.
+const (
+ signaturePKCS1v15 uint8 = iota + 225
+ signatureRSAPSS
+ signatureECDSA
+ signatureEd25519
+)
+
+// directSigning is a standard Hash value that signals that no pre-hashing
+// should be performed, and that the input should be signed directly. It is the
+// hash function associated with the Ed25519 signature scheme.
+var directSigning crypto.Hash = 0
+
+// defaultSupportedSignatureAlgorithms contains the signature and hash algorithms that
+// the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+
+// CertificateRequest. The two fields are merged to match with TLS 1.3.
+// Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc.
+var defaultSupportedSignatureAlgorithms = []SignatureScheme{
+ PSSWithSHA256,
+ ECDSAWithP256AndSHA256,
+ Ed25519,
+ PSSWithSHA384,
+ PSSWithSHA512,
+ PKCS1WithSHA256,
+ PKCS1WithSHA384,
+ PKCS1WithSHA512,
+ ECDSAWithP384AndSHA384,
+ ECDSAWithP521AndSHA512,
+ PKCS1WithSHA1,
+ ECDSAWithSHA1,
+}
+
+// helloRetryRequestRandom is set as the Random value of a ServerHello
+// to signal that the message is actually a HelloRetryRequest.
+var helloRetryRequestRandom = []byte{ // See RFC 8446, Section 4.1.3.
+ 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
+ 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
+ 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
+ 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C,
+}
+
+const (
+ // downgradeCanaryTLS12 or downgradeCanaryTLS11 is embedded in the server
+ // random as a downgrade protection if the server would be capable of
+ // negotiating a higher version. See RFC 8446, Section 4.1.3.
+ downgradeCanaryTLS12 = "DOWNGRD\x01"
+ downgradeCanaryTLS11 = "DOWNGRD\x00"
+)
+
+// testingOnlyForceDowngradeCanary is set in tests to force the server side to
+// include downgrade canaries even if it's using its highers supported version.
+var testingOnlyForceDowngradeCanary bool
+
+// ConnectionState records basic TLS details about the connection.
+type ConnectionState struct {
+ // Version is the TLS version used by the connection (e.g. VersionTLS12).
+ Version uint16
+
+ // HandshakeComplete is true if the handshake has concluded.
+ HandshakeComplete bool
+
+ // DidResume is true if this connection was successfully resumed from a
+ // previous session with a session ticket or similar mechanism.
+ DidResume bool
+
+ // CipherSuite is the cipher suite negotiated for the connection (e.g.
+ // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_AES_128_GCM_SHA256).
+ CipherSuite uint16
+
+ // NegotiatedProtocol is the application protocol negotiated with ALPN.
+ NegotiatedProtocol string
+
+ // NegotiatedProtocolIsMutual used to indicate a mutual NPN negotiation.
+ //
+ // Deprecated: this value is always true.
+ NegotiatedProtocolIsMutual bool
+
+ // ServerName is the value of the Server Name Indication extension sent by
+ // the client. It's available both on the server and on the client side.
+ ServerName string
+
+ // PeerCertificates are the parsed certificates sent by the peer, in the
+ // order in which they were sent. The first element is the leaf certificate
+ // that the connection is verified against.
+ //
+ // On the client side, it can't be empty. On the server side, it can be
+ // empty if Config.ClientAuth is not RequireAnyClientCert or
+ // RequireAndVerifyClientCert.
+ //
+ // PeerCertificates and its contents should not be modified.
+ PeerCertificates []*x509.Certificate
+
+ // VerifiedChains is a list of one or more chains where the first element is
+ // PeerCertificates[0] and the last element is from Config.RootCAs (on the
+ // client side) or Config.ClientCAs (on the server side).
+ //
+ // On the client side, it's set if Config.InsecureSkipVerify is false. On
+ // the server side, it's set if Config.ClientAuth is VerifyClientCertIfGiven
+ // (and the peer provided a certificate) or RequireAndVerifyClientCert.
+ //
+ // VerifiedChains and its contents should not be modified.
+ VerifiedChains [][]*x509.Certificate
+
+ // SignedCertificateTimestamps is a list of SCTs provided by the peer
+ // through the TLS handshake for the leaf certificate, if any.
+ SignedCertificateTimestamps [][]byte
+
+ // OCSPResponse is a stapled Online Certificate Status Protocol (OCSP)
+ // response provided by the peer for the leaf certificate, if any.
+ OCSPResponse []byte
+
+ // TLSUnique contains the "tls-unique" channel binding value (see RFC 5929,
+ // Section 3). This value will be nil for TLS 1.3 connections and for
+ // resumed connections that don't support Extended Master Secret (RFC 7627).
+ TLSUnique []byte
+
+ // ekm is a closure exposed via ExportKeyingMaterial.
+ ekm func(label string, context []byte, length int) ([]byte, error)
+}
+
+// ExportKeyingMaterial returns length bytes of exported key material in a new
+// slice as defined in RFC 5705. If context is nil, it is not used as part of
+// the seed. If the connection was set to allow renegotiation via
+// Config.Renegotiation, this function will return an error.
+//
+// There are conditions in which the returned values might not be unique to a
+// connection. See the Security Considerations sections of RFC 5705 and RFC 7627,
+// and https://mitls.org/pages/attacks/3SHAKE#channelbindings.
+func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
+ return cs.ekm(label, context, length)
+}
+
+// ClientAuthType declares the policy the server will follow for
+// TLS Client Authentication.
+type ClientAuthType int
+
+const (
+ // NoClientCert indicates that no client certificate should be requested
+ // during the handshake, and if any certificates are sent they will not
+ // be verified.
+ NoClientCert ClientAuthType = iota
+ // RequestClientCert indicates that a client certificate should be requested
+ // during the handshake, but does not require that the client send any
+ // certificates.
+ RequestClientCert
+ // RequireAnyClientCert indicates that a client certificate should be requested
+ // during the handshake, and that at least one certificate is required to be
+ // sent by the client, but that certificate is not required to be valid.
+ RequireAnyClientCert
+ // VerifyClientCertIfGiven indicates that a client certificate should be requested
+ // during the handshake, but does not require that the client sends a
+ // certificate. If the client does send a certificate it is required to be
+ // valid.
+ VerifyClientCertIfGiven
+ // RequireAndVerifyClientCert indicates that a client certificate should be requested
+ // during the handshake, and that at least one valid certificate is required
+ // to be sent by the client.
+ RequireAndVerifyClientCert
+)
+
+// requiresClientCert reports whether the ClientAuthType requires a client
+// certificate to be provided.
+func requiresClientCert(c ClientAuthType) bool {
+ switch c {
+ case RequireAnyClientCert, RequireAndVerifyClientCert:
+ return true
+ default:
+ return false
+ }
+}
+
+// ClientSessionCache is a cache of ClientSessionState objects that can be used
+// by a client to resume a TLS session with a given server. ClientSessionCache
+// implementations should expect to be called concurrently from different
+// goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not
+// SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which
+// are supported via this interface.
+type ClientSessionCache interface {
+ // Get searches for a ClientSessionState associated with the given key.
+ // On return, ok is true if one was found.
+ Get(sessionKey string) (session *ClientSessionState, ok bool)
+
+ // Put adds the ClientSessionState to the cache with the given key. It might
+ // get called multiple times in a connection if a TLS 1.3 server provides
+ // more than one session ticket. If called with a nil *ClientSessionState,
+ // it should remove the cache entry.
+ Put(sessionKey string, cs *ClientSessionState)
+}
+
+//go:generate stringer -type=SignatureScheme,CurveID,ClientAuthType -output=common_string.go
+
+// SignatureScheme identifies a signature algorithm supported by TLS. See
+// RFC 8446, Section 4.2.3.
+type SignatureScheme uint16
+
+const (
+ // RSASSA-PKCS1-v1_5 algorithms.
+ PKCS1WithSHA256 SignatureScheme = 0x0401
+ PKCS1WithSHA384 SignatureScheme = 0x0501
+ PKCS1WithSHA512 SignatureScheme = 0x0601
+
+ // RSASSA-PSS algorithms with public key OID rsaEncryption.
+ PSSWithSHA256 SignatureScheme = 0x0804
+ PSSWithSHA384 SignatureScheme = 0x0805
+ PSSWithSHA512 SignatureScheme = 0x0806
+
+ // ECDSA algorithms. Only constrained to a specific curve in TLS 1.3.
+ ECDSAWithP256AndSHA256 SignatureScheme = 0x0403
+ ECDSAWithP384AndSHA384 SignatureScheme = 0x0503
+ ECDSAWithP521AndSHA512 SignatureScheme = 0x0603
+
+ // EdDSA algorithms.
+ Ed25519 SignatureScheme = 0x0807
+
+ // Legacy signature and hash algorithms for TLS 1.2.
+ PKCS1WithSHA1 SignatureScheme = 0x0201
+ ECDSAWithSHA1 SignatureScheme = 0x0203
+)
+
+// ClientHelloInfo contains information from a ClientHello message in order to
+// guide application logic in the GetCertificate and GetConfigForClient callbacks.
+type ClientHelloInfo struct {
+ // CipherSuites lists the CipherSuites supported by the client (e.g.
+ // TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).
+ CipherSuites []uint16
+
+ // ServerName indicates the name of the server requested by the client
+ // in order to support virtual hosting. ServerName is only set if the
+ // client is using SNI (see RFC 4366, Section 3.1).
+ ServerName string
+
+ // SupportedCurves lists the elliptic curves supported by the client.
+ // SupportedCurves is set only if the Supported Elliptic Curves
+ // Extension is being used (see RFC 4492, Section 5.1.1).
+ SupportedCurves []CurveID
+
+ // SupportedPoints lists the point formats supported by the client.
+ // SupportedPoints is set only if the Supported Point Formats Extension
+ // is being used (see RFC 4492, Section 5.1.2).
+ SupportedPoints []uint8
+
+ // SignatureSchemes lists the signature and hash schemes that the client
+ // is willing to verify. SignatureSchemes is set only if the Signature
+ // Algorithms Extension is being used (see RFC 5246, Section 7.4.1.4.1).
+ SignatureSchemes []SignatureScheme
+
+ // SupportedProtos lists the application protocols supported by the client.
+ // SupportedProtos is set only if the Application-Layer Protocol
+ // Negotiation Extension is being used (see RFC 7301, Section 3.1).
+ //
+ // Servers can select a protocol by setting Config.NextProtos in a
+ // GetConfigForClient return value.
+ SupportedProtos []string
+
+ // SupportedVersions lists the TLS versions supported by the client.
+ // For TLS versions less than 1.3, this is extrapolated from the max
+ // version advertised by the client, so values other than the greatest
+ // might be rejected if used.
+ SupportedVersions []uint16
+
+ // Conn is the underlying net.Conn for the connection. Do not read
+ // from, or write to, this connection; that will cause the TLS
+ // connection to fail.
+ Conn net.Conn
+
+ // config is embedded by the GetCertificate or GetConfigForClient caller,
+ // for use with SupportsCertificate.
+ config *Config
+
+ // ctx is the context of the handshake that is in progress.
+ ctx context.Context
+}
+
+// Context returns the context of the handshake that is in progress.
+// This context is a child of the context passed to HandshakeContext,
+// if any, and is canceled when the handshake concludes.
+func (c *ClientHelloInfo) Context() context.Context {
+ return c.ctx
+}
+
+// CertificateRequestInfo contains information from a server's
+// CertificateRequest message, which is used to demand a certificate and proof
+// of control from a client.
+type CertificateRequestInfo struct {
+ // AcceptableCAs contains zero or more, DER-encoded, X.501
+ // Distinguished Names. These are the names of root or intermediate CAs
+ // that the server wishes the returned certificate to be signed by. An
+ // empty slice indicates that the server has no preference.
+ AcceptableCAs [][]byte
+
+ // SignatureSchemes lists the signature schemes that the server is
+ // willing to verify.
+ SignatureSchemes []SignatureScheme
+
+ // Version is the TLS version that was negotiated for this connection.
+ Version uint16
+
+ // ctx is the context of the handshake that is in progress.
+ ctx context.Context
+}
+
+// Context returns the context of the handshake that is in progress.
+// This context is a child of the context passed to HandshakeContext,
+// if any, and is canceled when the handshake concludes.
+func (c *CertificateRequestInfo) Context() context.Context {
+ return c.ctx
+}
+
+// RenegotiationSupport enumerates the different levels of support for TLS
+// renegotiation. TLS renegotiation is the act of performing subsequent
+// handshakes on a connection after the first. This significantly complicates
+// the state machine and has been the source of numerous, subtle security
+// issues. Initiating a renegotiation is not supported, but support for
+// accepting renegotiation requests may be enabled.
+//
+// Even when enabled, the server may not change its identity between handshakes
+// (i.e. the leaf certificate must be the same). Additionally, concurrent
+// handshake and application data flow is not permitted so renegotiation can
+// only be used with protocols that synchronise with the renegotiation, such as
+// HTTPS.
+//
+// Renegotiation is not defined in TLS 1.3.
+type RenegotiationSupport int
+
+const (
+ // RenegotiateNever disables renegotiation.
+ RenegotiateNever RenegotiationSupport = iota
+
+ // RenegotiateOnceAsClient allows a remote server to request
+ // renegotiation once per connection.
+ RenegotiateOnceAsClient
+
+ // RenegotiateFreelyAsClient allows a remote server to repeatedly
+ // request renegotiation.
+ RenegotiateFreelyAsClient
+)
+
+// A Config structure is used to configure a TLS client or server.
+// After one has been passed to a TLS function it must not be
+// modified. A Config may be reused; the tls package will also not
+// modify it.
+type Config struct {
+ // Rand provides the source of entropy for nonces and RSA blinding.
+ // If Rand is nil, TLS uses the cryptographic random reader in package
+ // crypto/rand.
+ // The Reader must be safe for use by multiple goroutines.
+ Rand io.Reader
+
+ // Time returns the current time as the number of seconds since the epoch.
+ // If Time is nil, TLS uses time.Now.
+ Time func() time.Time
+
+ // Certificates contains one or more certificate chains to present to the
+ // other side of the connection. The first certificate compatible with the
+ // peer's requirements is selected automatically.
+ //
+ // Server configurations must set one of Certificates, GetCertificate or
+ // GetConfigForClient. Clients doing client-authentication may set either
+ // Certificates or GetClientCertificate.
+ //
+ // Note: if there are multiple Certificates, and they don't have the
+ // optional field Leaf set, certificate selection will incur a significant
+ // per-handshake performance cost.
+ Certificates []Certificate
+
+ // NameToCertificate maps from a certificate name to an element of
+ // Certificates. Note that a certificate name can be of the form
+ // '*.example.com' and so doesn't have to be a domain name as such.
+ //
+ // Deprecated: NameToCertificate only allows associating a single
+ // certificate with a given name. Leave this field nil to let the library
+ // select the first compatible chain from Certificates.
+ NameToCertificate map[string]*Certificate
+
+ // GetCertificate returns a Certificate based on the given
+ // ClientHelloInfo. It will only be called if the client supplies SNI
+ // information or if Certificates is empty.
+ //
+ // If GetCertificate is nil or returns nil, then the certificate is
+ // retrieved from NameToCertificate. If NameToCertificate is nil, the
+ // best element of Certificates will be used.
+ //
+ // Once a Certificate is returned it should not be modified.
+ GetCertificate func(*ClientHelloInfo) (*Certificate, error)
+
+ // GetClientCertificate, if not nil, is called when a server requests a
+ // certificate from a client. If set, the contents of Certificates will
+ // be ignored.
+ //
+ // If GetClientCertificate returns an error, the handshake will be
+ // aborted and that error will be returned. Otherwise
+ // GetClientCertificate must return a non-nil Certificate. If
+ // Certificate.Certificate is empty then no certificate will be sent to
+ // the server. If this is unacceptable to the server then it may abort
+ // the handshake.
+ //
+ // GetClientCertificate may be called multiple times for the same
+ // connection if renegotiation occurs or if TLS 1.3 is in use.
+ //
+ // Once a Certificate is returned it should not be modified.
+ GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error)
+
+ // GetConfigForClient, if not nil, is called after a ClientHello is
+ // received from a client. It may return a non-nil Config in order to
+ // change the Config that will be used to handle this connection. If
+ // the returned Config is nil, the original Config will be used. The
+ // Config returned by this callback may not be subsequently modified.
+ //
+ // If GetConfigForClient is nil, the Config passed to Server() will be
+ // used for all connections.
+ //
+ // If SessionTicketKey was explicitly set on the returned Config, or if
+ // SetSessionTicketKeys was called on the returned Config, those keys will
+ // be used. Otherwise, the original Config keys will be used (and possibly
+ // rotated if they are automatically managed).
+ GetConfigForClient func(*ClientHelloInfo) (*Config, error)
+
+ // VerifyPeerCertificate, if not nil, is called after normal
+ // certificate verification by either a TLS client or server. It
+ // receives the raw ASN.1 certificates provided by the peer and also
+ // any verified chains that normal processing found. If it returns a
+ // non-nil error, the handshake is aborted and that error results.
+ //
+ // If normal verification fails then the handshake will abort before
+ // considering this callback. If normal verification is disabled (on the
+ // client when InsecureSkipVerify is set, or on a server when ClientAuth is
+ // RequestClientCert or RequireAnyClientCert), then this callback will be
+ // considered but the verifiedChains argument will always be nil. When
+ // ClientAuth is NoClientCert, this callback is not called on the server.
+ // rawCerts may be empty on the server if ClientAuth is RequestClientCert or
+ // VerifyClientCertIfGiven.
+ //
+ // This callback is not invoked on resumed connections, as certificates are
+ // not re-verified on resumption.
+ //
+ // verifiedChains and its contents should not be modified.
+ VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
+
+ // VerifyConnection, if not nil, is called after normal certificate
+ // verification and after VerifyPeerCertificate by either a TLS client
+ // or server. If it returns a non-nil error, the handshake is aborted
+ // and that error results.
+ //
+ // If normal verification fails then the handshake will abort before
+ // considering this callback. This callback will run for all connections,
+ // including resumptions, regardless of InsecureSkipVerify or ClientAuth
+ // settings.
+ VerifyConnection func(ConnectionState) error
+
+ // RootCAs defines the set of root certificate authorities
+ // that clients use when verifying server certificates.
+ // If RootCAs is nil, TLS uses the host's root CA set.
+ RootCAs *x509.CertPool
+
+ // NextProtos is a list of supported application level protocols, in
+ // order of preference. If both peers support ALPN, the selected
+ // protocol will be one from this list, and the connection will fail
+ // if there is no mutually supported protocol. If NextProtos is empty
+ // or the peer doesn't support ALPN, the connection will succeed and
+ // ConnectionState.NegotiatedProtocol will be empty.
+ NextProtos []string
+
+ // ServerName is used to verify the hostname on the returned
+ // certificates unless InsecureSkipVerify is given. It is also included
+ // in the client's handshake to support virtual hosting unless it is
+ // an IP address.
+ ServerName string
+
+ // ClientAuth determines the server's policy for
+ // TLS Client Authentication. The default is NoClientCert.
+ ClientAuth ClientAuthType
+
+ // ClientCAs defines the set of root certificate authorities
+ // that servers use if required to verify a client certificate
+ // by the policy in ClientAuth.
+ ClientCAs *x509.CertPool
+
+ // InsecureSkipVerify controls whether a client verifies the server's
+ // certificate chain and host name. If InsecureSkipVerify is true, crypto/tls
+ // accepts any certificate presented by the server and any host name in that
+ // certificate. In this mode, TLS is susceptible to machine-in-the-middle
+ // attacks unless custom verification is used. This should be used only for
+ // testing or in combination with VerifyConnection or VerifyPeerCertificate.
+ InsecureSkipVerify bool
+
+ // CipherSuites is a list of enabled TLS 1.0–1.2 cipher suites. The order of
+ // the list is ignored. Note that TLS 1.3 ciphersuites are not configurable.
+ //
+ // If CipherSuites is nil, a safe default list is used. The default cipher
+ // suites might change over time.
+ CipherSuites []uint16
+
+ // PreferServerCipherSuites is a legacy field and has no effect.
+ //
+ // It used to control whether the server would follow the client's or the
+ // server's preference. Servers now select the best mutually supported
+ // cipher suite based on logic that takes into account inferred client
+ // hardware, server hardware, and security.
+ //
+ // Deprecated: PreferServerCipherSuites is ignored.
+ PreferServerCipherSuites bool
+
+ // SessionTicketsDisabled may be set to true to disable session ticket and
+ // PSK (resumption) support. Note that on clients, session ticket support is
+ // also disabled if ClientSessionCache is nil.
+ SessionTicketsDisabled bool
+
+ // SessionTicketKey is used by TLS servers to provide session resumption.
+ // See RFC 5077 and the PSK mode of RFC 8446. If zero, it will be filled
+ // with random data before the first server handshake.
+ //
+ // Deprecated: if this field is left at zero, session ticket keys will be
+ // automatically rotated every day and dropped after seven days. For
+ // customizing the rotation schedule or synchronizing servers that are
+ // terminating connections for the same host, use SetSessionTicketKeys.
+ SessionTicketKey [32]byte
+
+ // ClientSessionCache is a cache of ClientSessionState entries for TLS
+ // session resumption. It is only used by clients.
+ ClientSessionCache ClientSessionCache
+
+ // UnwrapSession is called on the server to turn a ticket/identity
+ // previously produced by [WrapSession] into a usable session.
+ //
+ // UnwrapSession will usually either decrypt a session state in the ticket
+ // (for example with [Config.EncryptTicket]), or use the ticket as a handle
+ // to recover a previously stored state. It must use [ParseSessionState] to
+ // deserialize the session state.
+ //
+ // If UnwrapSession returns an error, the connection is terminated. If it
+ // returns (nil, nil), the session is ignored. crypto/tls may still choose
+ // not to resume the returned session.
+ UnwrapSession func(identity []byte, cs ConnectionState) (*SessionState, error)
+
+ // WrapSession is called on the server to produce a session ticket/identity.
+ //
+ // WrapSession must serialize the session state with [SessionState.Bytes].
+ // It may then encrypt the serialized state (for example with
+ // [Config.DecryptTicket]) and use it as the ticket, or store the state and
+ // return a handle for it.
+ //
+ // If WrapSession returns an error, the connection is terminated.
+ //
+ // Warning: the return value will be exposed on the wire and to clients in
+ // plaintext. The application is in charge of encrypting and authenticating
+ // it (and rotating keys) or returning high-entropy identifiers. Failing to
+ // do so correctly can compromise current, previous, and future connections
+ // depending on the protocol version.
+ WrapSession func(ConnectionState, *SessionState) ([]byte, error)
+
+ // MinVersion contains the minimum TLS version that is acceptable.
+ //
+ // By default, TLS 1.2 is currently used as the minimum when acting as a
+ // client, and TLS 1.0 when acting as a server. TLS 1.0 is the minimum
+ // supported by this package, both as a client and as a server.
+ //
+ // The client-side default can temporarily be reverted to TLS 1.0 by
+ // including the value "x509sha1=1" in the GODEBUG environment variable.
+ // Note that this option will be removed in Go 1.19 (but it will still be
+ // possible to set this field to VersionTLS10 explicitly).
+ MinVersion uint16
+
+ // MaxVersion contains the maximum TLS version that is acceptable.
+ //
+ // By default, the maximum version supported by this package is used,
+ // which is currently TLS 1.3.
+ MaxVersion uint16
+
+ // CurvePreferences contains the elliptic curves that will be used in
+ // an ECDHE handshake, in preference order. If empty, the default will
+ // be used. The client will use the first preference as the type for
+ // its key share in TLS 1.3. This may change in the future.
+ CurvePreferences []CurveID
+
+ // DynamicRecordSizingDisabled disables adaptive sizing of TLS records.
+ // When true, the largest possible TLS record size is always used. When
+ // false, the size of TLS records may be adjusted in an attempt to
+ // improve latency.
+ DynamicRecordSizingDisabled bool
+
+ // Renegotiation controls what types of renegotiation are supported.
+ // The default, none, is correct for the vast majority of applications.
+ Renegotiation RenegotiationSupport
+
+ // KeyLogWriter optionally specifies a destination for TLS master secrets
+ // in NSS key log format that can be used to allow external programs
+ // such as Wireshark to decrypt TLS connections.
+ // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.
+ // Use of KeyLogWriter compromises security and should only be
+ // used for debugging.
+ KeyLogWriter io.Writer
+
+ // mutex protects sessionTicketKeys and autoSessionTicketKeys.
+ mutex sync.RWMutex
+ // sessionTicketKeys contains zero or more ticket keys. If set, it means
+ // the keys were set with SessionTicketKey or SetSessionTicketKeys. The
+ // first key is used for new tickets and any subsequent keys can be used to
+ // decrypt old tickets. The slice contents are not protected by the mutex
+ // and are immutable.
+ sessionTicketKeys []ticketKey
+ // autoSessionTicketKeys is like sessionTicketKeys but is owned by the
+ // auto-rotation logic. See Config.ticketKeys.
+ autoSessionTicketKeys []ticketKey
+}
+
+const (
+ // ticketKeyLifetime is how long a ticket key remains valid and can be used to
+ // resume a client connection.
+ ticketKeyLifetime = 7 * 24 * time.Hour // 7 days
+
+ // ticketKeyRotation is how often the server should rotate the session ticket key
+ // that is used for new tickets.
+ ticketKeyRotation = 24 * time.Hour
+)
+
+// ticketKey is the internal representation of a session ticket key.
+type ticketKey struct {
+ aesKey [16]byte
+ hmacKey [16]byte
+ // created is the time at which this ticket key was created. See Config.ticketKeys.
+ created time.Time
+}
+
+// ticketKeyFromBytes converts from the external representation of a session
+// ticket key to a ticketKey. Externally, session ticket keys are 32 random
+// bytes and this function expands that into sufficient name and key material.
+func (c *Config) ticketKeyFromBytes(b [32]byte) (key ticketKey) {
+ hashed := sha512.Sum512(b[:])
+ // The first 16 bytes of the hash used to be exposed on the wire as a ticket
+ // prefix. They MUST NOT be used as a secret. In the future, it would make
+ // sense to use a proper KDF here, like HKDF with a fixed salt.
+ const legacyTicketKeyNameLen = 16
+ copy(key.aesKey[:], hashed[legacyTicketKeyNameLen:])
+ copy(key.hmacKey[:], hashed[legacyTicketKeyNameLen+len(key.aesKey):])
+ key.created = c.time()
+ return key
+}
+
+// maxSessionTicketLifetime is the maximum allowed lifetime of a TLS 1.3 session
+// ticket, and the lifetime we set for all tickets we send.
+const maxSessionTicketLifetime = 7 * 24 * time.Hour
+
+// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a Config that is
+// being used concurrently by a TLS client or server.
+func (c *Config) Clone() *Config {
+ if c == nil {
+ return nil
+ }
+ c.mutex.RLock()
+ defer c.mutex.RUnlock()
+ return &Config{
+ Rand: c.Rand,
+ Time: c.Time,
+ Certificates: c.Certificates,
+ NameToCertificate: c.NameToCertificate,
+ GetCertificate: c.GetCertificate,
+ GetClientCertificate: c.GetClientCertificate,
+ GetConfigForClient: c.GetConfigForClient,
+ VerifyPeerCertificate: c.VerifyPeerCertificate,
+ VerifyConnection: c.VerifyConnection,
+ RootCAs: c.RootCAs,
+ NextProtos: c.NextProtos,
+ ServerName: c.ServerName,
+ ClientAuth: c.ClientAuth,
+ ClientCAs: c.ClientCAs,
+ InsecureSkipVerify: c.InsecureSkipVerify,
+ CipherSuites: c.CipherSuites,
+ PreferServerCipherSuites: c.PreferServerCipherSuites,
+ SessionTicketsDisabled: c.SessionTicketsDisabled,
+ SessionTicketKey: c.SessionTicketKey,
+ ClientSessionCache: c.ClientSessionCache,
+ UnwrapSession: c.UnwrapSession,
+ WrapSession: c.WrapSession,
+ MinVersion: c.MinVersion,
+ MaxVersion: c.MaxVersion,
+ CurvePreferences: c.CurvePreferences,
+ DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
+ Renegotiation: c.Renegotiation,
+ KeyLogWriter: c.KeyLogWriter,
+ sessionTicketKeys: c.sessionTicketKeys,
+ autoSessionTicketKeys: c.autoSessionTicketKeys,
+ }
+}
+
+// deprecatedSessionTicketKey is set as the prefix of SessionTicketKey if it was
+// randomized for backwards compatibility but is not in use.
+var deprecatedSessionTicketKey = []byte("DEPRECATED")
+
+// initLegacySessionTicketKeyRLocked ensures the legacy SessionTicketKey field is
+// randomized if empty, and that sessionTicketKeys is populated from it otherwise.
+func (c *Config) initLegacySessionTicketKeyRLocked() {
+ // Don't write if SessionTicketKey is already defined as our deprecated string,
+ // or if it is defined by the user but sessionTicketKeys is already set.
+ if c.SessionTicketKey != [32]byte{} &&
+ (bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) || len(c.sessionTicketKeys) > 0) {
+ return
+ }
+
+ // We need to write some data, so get an exclusive lock and re-check any conditions.
+ c.mutex.RUnlock()
+ defer c.mutex.RLock()
+ c.mutex.Lock()
+ defer c.mutex.Unlock()
+ if c.SessionTicketKey == [32]byte{} {
+ if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {
+ panic(fmt.Sprintf("tls: unable to generate random session ticket key: %v", err))
+ }
+ // Write the deprecated prefix at the beginning so we know we created
+ // it. This key with the DEPRECATED prefix isn't used as an actual
+ // session ticket key, and is only randomized in case the application
+ // reuses it for some reason.
+ copy(c.SessionTicketKey[:], deprecatedSessionTicketKey)
+ } else if !bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) && len(c.sessionTicketKeys) == 0 {
+ c.sessionTicketKeys = []ticketKey{c.ticketKeyFromBytes(c.SessionTicketKey)}
+ }
+
+}
+
+// ticketKeys returns the ticketKeys for this connection.
+// If configForClient has explicitly set keys, those will
+// be returned. Otherwise, the keys on c will be used and
+// may be rotated if auto-managed.
+// During rotation, any expired session ticket keys are deleted from
+// c.sessionTicketKeys. If the session ticket key that is currently
+// encrypting tickets (ie. the first ticketKey in c.sessionTicketKeys)
+// is not fresh, then a new session ticket key will be
+// created and prepended to c.sessionTicketKeys.
+func (c *Config) ticketKeys(configForClient *Config) []ticketKey {
+ // If the ConfigForClient callback returned a Config with explicitly set
+ // keys, use those, otherwise just use the original Config.
+ if configForClient != nil {
+ configForClient.mutex.RLock()
+ if configForClient.SessionTicketsDisabled {
+ return nil
+ }
+ configForClient.initLegacySessionTicketKeyRLocked()
+ if len(configForClient.sessionTicketKeys) != 0 {
+ ret := configForClient.sessionTicketKeys
+ configForClient.mutex.RUnlock()
+ return ret
+ }
+ configForClient.mutex.RUnlock()
+ }
+
+ c.mutex.RLock()
+ defer c.mutex.RUnlock()
+ if c.SessionTicketsDisabled {
+ return nil
+ }
+ c.initLegacySessionTicketKeyRLocked()
+ if len(c.sessionTicketKeys) != 0 {
+ return c.sessionTicketKeys
+ }
+ // Fast path for the common case where the key is fresh enough.
+ if len(c.autoSessionTicketKeys) > 0 && c.time().Sub(c.autoSessionTicketKeys[0].created) < ticketKeyRotation {
+ return c.autoSessionTicketKeys
+ }
+
+ // autoSessionTicketKeys are managed by auto-rotation.
+ c.mutex.RUnlock()
+ defer c.mutex.RLock()
+ c.mutex.Lock()
+ defer c.mutex.Unlock()
+ // Re-check the condition in case it changed since obtaining the new lock.
+ if len(c.autoSessionTicketKeys) == 0 || c.time().Sub(c.autoSessionTicketKeys[0].created) >= ticketKeyRotation {
+ var newKey [32]byte
+ if _, err := io.ReadFull(c.rand(), newKey[:]); err != nil {
+ panic(fmt.Sprintf("unable to generate random session ticket key: %v", err))
+ }
+ valid := make([]ticketKey, 0, len(c.autoSessionTicketKeys)+1)
+ valid = append(valid, c.ticketKeyFromBytes(newKey))
+ for _, k := range c.autoSessionTicketKeys {
+ // While rotating the current key, also remove any expired ones.
+ if c.time().Sub(k.created) < ticketKeyLifetime {
+ valid = append(valid, k)
+ }
+ }
+ c.autoSessionTicketKeys = valid
+ }
+ return c.autoSessionTicketKeys
+}
+
+// SetSessionTicketKeys updates the session ticket keys for a server.
+//
+// The first key will be used when creating new tickets, while all keys can be
+// used for decrypting tickets. It is safe to call this function while the
+// server is running in order to rotate the session ticket keys. The function
+// will panic if keys is empty.
+//
+// Calling this function will turn off automatic session ticket key rotation.
+//
+// If multiple servers are terminating connections for the same host they should
+// all have the same session ticket keys. If the session ticket keys leaks,
+// previously recorded and future TLS connections using those keys might be
+// compromised.
+func (c *Config) SetSessionTicketKeys(keys [][32]byte) {
+ if len(keys) == 0 {
+ panic("tls: keys must have at least one key")
+ }
+
+ newKeys := make([]ticketKey, len(keys))
+ for i, bytes := range keys {
+ newKeys[i] = c.ticketKeyFromBytes(bytes)
+ }
+
+ c.mutex.Lock()
+ c.sessionTicketKeys = newKeys
+ c.mutex.Unlock()
+}
+
+func (c *Config) rand() io.Reader {
+ r := c.Rand
+ if r == nil {
+ return rand.Reader
+ }
+ return r
+}
+
+func (c *Config) time() time.Time {
+ t := c.Time
+ if t == nil {
+ t = time.Now
+ }
+ return t()
+}
+
+func (c *Config) cipherSuites() []uint16 {
+ if needFIPS() {
+ return fipsCipherSuites(c)
+ }
+ if c.CipherSuites != nil {
+ return c.CipherSuites
+ }
+ return defaultCipherSuites
+}
+
+var supportedVersions = []uint16{
+ VersionTLS13,
+ VersionTLS12,
+ VersionTLS11,
+ VersionTLS10,
+}
+
+// roleClient and roleServer are meant to call supportedVersions and parents
+// with more readability at the callsite.
+const roleClient = true
+const roleServer = false
+
+func (c *Config) supportedVersions(isClient bool) []uint16 {
+ versions := make([]uint16, 0, len(supportedVersions))
+ for _, v := range supportedVersions {
+ if needFIPS() && (v < fipsMinVersion(c) || v > fipsMaxVersion(c)) {
+ continue
+ }
+ if (c == nil || c.MinVersion == 0) &&
+ isClient && v < VersionTLS12 {
+ continue
+ }
+ if c != nil && c.MinVersion != 0 && v < c.MinVersion {
+ continue
+ }
+ if c != nil && c.MaxVersion != 0 && v > c.MaxVersion {
+ continue
+ }
+ versions = append(versions, v)
+ }
+ return versions
+}
+
+func (c *Config) maxSupportedVersion(isClient bool) uint16 {
+ supportedVersions := c.supportedVersions(isClient)
+ if len(supportedVersions) == 0 {
+ return 0
+ }
+ return supportedVersions[0]
+}
+
+// supportedVersionsFromMax returns a list of supported versions derived from a
+// legacy maximum version value. Note that only versions supported by this
+// library are returned. Any newer peer will use supportedVersions anyway.
+func supportedVersionsFromMax(maxVersion uint16) []uint16 {
+ versions := make([]uint16, 0, len(supportedVersions))
+ for _, v := range supportedVersions {
+ if v > maxVersion {
+ continue
+ }
+ versions = append(versions, v)
+ }
+ return versions
+}
+
+var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521}
+
+func (c *Config) curvePreferences() []CurveID {
+ if needFIPS() {
+ return fipsCurvePreferences(c)
+ }
+ if c == nil || len(c.CurvePreferences) == 0 {
+ return defaultCurvePreferences
+ }
+ return c.CurvePreferences
+}
+
+func (c *Config) supportsCurve(curve CurveID) bool {
+ for _, cc := range c.curvePreferences() {
+ if cc == curve {
+ return true
+ }
+ }
+ return false
+}
+
+// mutualVersion returns the protocol version to use given the advertised
+// versions of the peer. Priority is given to the peer preference order.
+func (c *Config) mutualVersion(isClient bool, peerVersions []uint16) (uint16, bool) {
+ supportedVersions := c.supportedVersions(isClient)
+ for _, peerVersion := range peerVersions {
+ for _, v := range supportedVersions {
+ if v == peerVersion {
+ return v, true
+ }
+ }
+ }
+ return 0, false
+}
+
+var errNoCertificates = errors.New("tls: no certificates configured")
+
+// getCertificate returns the best certificate for the given ClientHelloInfo,
+// defaulting to the first element of c.Certificates.
+func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) {
+ if c.GetCertificate != nil &&
+ (len(c.Certificates) == 0 || len(clientHello.ServerName) > 0) {
+ cert, err := c.GetCertificate(clientHello)
+ if cert != nil || err != nil {
+ return cert, err
+ }
+ }
+
+ if len(c.Certificates) == 0 {
+ return nil, errNoCertificates
+ }
+
+ if len(c.Certificates) == 1 {
+ // There's only one choice, so no point doing any work.
+ return &c.Certificates[0], nil
+ }
+
+ if c.NameToCertificate != nil {
+ name := strings.ToLower(clientHello.ServerName)
+ if cert, ok := c.NameToCertificate[name]; ok {
+ return cert, nil
+ }
+ if len(name) > 0 {
+ labels := strings.Split(name, ".")
+ labels[0] = "*"
+ wildcardName := strings.Join(labels, ".")
+ if cert, ok := c.NameToCertificate[wildcardName]; ok {
+ return cert, nil
+ }
+ }
+ }
+
+ for _, cert := range c.Certificates {
+ if err := clientHello.SupportsCertificate(&cert); err == nil {
+ return &cert, nil
+ }
+ }
+
+ // If nothing matches, return the first certificate.
+ return &c.Certificates[0], nil
+}
+
+// SupportsCertificate returns nil if the provided certificate is supported by
+// the client that sent the ClientHello. Otherwise, it returns an error
+// describing the reason for the incompatibility.
+//
+// If this ClientHelloInfo was passed to a GetConfigForClient or GetCertificate
+// callback, this method will take into account the associated Config. Note that
+// if GetConfigForClient returns a different Config, the change can't be
+// accounted for by this method.
+//
+// This function will call x509.ParseCertificate unless c.Leaf is set, which can
+// incur a significant performance cost.
+func (chi *ClientHelloInfo) SupportsCertificate(c *Certificate) error {
+ // Note we don't currently support certificate_authorities nor
+ // signature_algorithms_cert, and don't check the algorithms of the
+ // signatures on the chain (which anyway are a SHOULD, see RFC 8446,
+ // Section 4.4.2.2).
+
+ config := chi.config
+ if config == nil {
+ config = &Config{}
+ }
+ vers, ok := config.mutualVersion(roleServer, chi.SupportedVersions)
+ if !ok {
+ return errors.New("no mutually supported protocol versions")
+ }
+
+ // If the client specified the name they are trying to connect to, the
+ // certificate needs to be valid for it.
+ if chi.ServerName != "" {
+ x509Cert, err := c.leaf()
+ if err != nil {
+ return fmt.Errorf("failed to parse certificate: %w", err)
+ }
+ if err := x509Cert.VerifyHostname(chi.ServerName); err != nil {
+ return fmt.Errorf("certificate is not valid for requested server name: %w", err)
+ }
+ }
+
+ // supportsRSAFallback returns nil if the certificate and connection support
+ // the static RSA key exchange, and unsupported otherwise. The logic for
+ // supporting static RSA is completely disjoint from the logic for
+ // supporting signed key exchanges, so we just check it as a fallback.
+ supportsRSAFallback := func(unsupported error) error {
+ // TLS 1.3 dropped support for the static RSA key exchange.
+ if vers == VersionTLS13 {
+ return unsupported
+ }
+ // The static RSA key exchange works by decrypting a challenge with the
+ // RSA private key, not by signing, so check the PrivateKey implements
+ // crypto.Decrypter, like *rsa.PrivateKey does.
+ if priv, ok := c.PrivateKey.(crypto.Decrypter); ok {
+ if _, ok := priv.Public().(*rsa.PublicKey); !ok {
+ return unsupported
+ }
+ } else {
+ return unsupported
+ }
+ // Finally, there needs to be a mutual cipher suite that uses the static
+ // RSA key exchange instead of ECDHE.
+ rsaCipherSuite := selectCipherSuite(chi.CipherSuites, config.cipherSuites(), func(c *cipherSuite) bool {
+ if c.flags&suiteECDHE != 0 {
+ return false
+ }
+ if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
+ return false
+ }
+ return true
+ })
+ if rsaCipherSuite == nil {
+ return unsupported
+ }
+ return nil
+ }
+
+ // If the client sent the signature_algorithms extension, ensure it supports
+ // schemes we can use with this certificate and TLS version.
+ if len(chi.SignatureSchemes) > 0 {
+ if _, err := selectSignatureScheme(vers, c, chi.SignatureSchemes); err != nil {
+ return supportsRSAFallback(err)
+ }
+ }
+
+ // In TLS 1.3 we are done because supported_groups is only relevant to the
+ // ECDHE computation, point format negotiation is removed, cipher suites are
+ // only relevant to the AEAD choice, and static RSA does not exist.
+ if vers == VersionTLS13 {
+ return nil
+ }
+
+ // The only signed key exchange we support is ECDHE.
+ if !supportsECDHE(config, chi.SupportedCurves, chi.SupportedPoints) {
+ return supportsRSAFallback(errors.New("client doesn't support ECDHE, can only use legacy RSA key exchange"))
+ }
+
+ var ecdsaCipherSuite bool
+ if priv, ok := c.PrivateKey.(crypto.Signer); ok {
+ switch pub := priv.Public().(type) {
+ case *ecdsa.PublicKey:
+ var curve CurveID
+ switch pub.Curve {
+ case elliptic.P256():
+ curve = CurveP256
+ case elliptic.P384():
+ curve = CurveP384
+ case elliptic.P521():
+ curve = CurveP521
+ default:
+ return supportsRSAFallback(unsupportedCertificateError(c))
+ }
+ var curveOk bool
+ for _, c := range chi.SupportedCurves {
+ if c == curve && config.supportsCurve(c) {
+ curveOk = true
+ break
+ }
+ }
+ if !curveOk {
+ return errors.New("client doesn't support certificate curve")
+ }
+ ecdsaCipherSuite = true
+ case ed25519.PublicKey:
+ if vers < VersionTLS12 || len(chi.SignatureSchemes) == 0 {
+ return errors.New("connection doesn't support Ed25519")
+ }
+ ecdsaCipherSuite = true
+ case *rsa.PublicKey:
+ default:
+ return supportsRSAFallback(unsupportedCertificateError(c))
+ }
+ } else {
+ return supportsRSAFallback(unsupportedCertificateError(c))
+ }
+
+ // Make sure that there is a mutually supported cipher suite that works with
+ // this certificate. Cipher suite selection will then apply the logic in
+ // reverse to pick it. See also serverHandshakeState.cipherSuiteOk.
+ cipherSuite := selectCipherSuite(chi.CipherSuites, config.cipherSuites(), func(c *cipherSuite) bool {
+ if c.flags&suiteECDHE == 0 {
+ return false
+ }
+ if c.flags&suiteECSign != 0 {
+ if !ecdsaCipherSuite {
+ return false
+ }
+ } else {
+ if ecdsaCipherSuite {
+ return false
+ }
+ }
+ if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
+ return false
+ }
+ return true
+ })
+ if cipherSuite == nil {
+ return supportsRSAFallback(errors.New("client doesn't support any cipher suites compatible with the certificate"))
+ }
+
+ return nil
+}
+
+// SupportsCertificate returns nil if the provided certificate is supported by
+// the server that sent the CertificateRequest. Otherwise, it returns an error
+// describing the reason for the incompatibility.
+func (cri *CertificateRequestInfo) SupportsCertificate(c *Certificate) error {
+ if _, err := selectSignatureScheme(cri.Version, c, cri.SignatureSchemes); err != nil {
+ return err
+ }
+
+ if len(cri.AcceptableCAs) == 0 {
+ return nil
+ }
+
+ for j, cert := range c.Certificate {
+ x509Cert := c.Leaf
+ // Parse the certificate if this isn't the leaf node, or if
+ // chain.Leaf was nil.
+ if j != 0 || x509Cert == nil {
+ var err error
+ if x509Cert, err = x509.ParseCertificate(cert); err != nil {
+ return fmt.Errorf("failed to parse certificate #%d in the chain: %w", j, err)
+ }
+ }
+
+ for _, ca := range cri.AcceptableCAs {
+ if bytes.Equal(x509Cert.RawIssuer, ca) {
+ return nil
+ }
+ }
+ }
+ return errors.New("chain is not signed by an acceptable CA")
+}
+
+// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate
+// from the CommonName and SubjectAlternateName fields of each of the leaf
+// certificates.
+//
+// Deprecated: NameToCertificate only allows associating a single certificate
+// with a given name. Leave that field nil to let the library select the first
+// compatible chain from Certificates.
+func (c *Config) BuildNameToCertificate() {
+ c.NameToCertificate = make(map[string]*Certificate)
+ for i := range c.Certificates {
+ cert := &c.Certificates[i]
+ x509Cert, err := cert.leaf()
+ if err != nil {
+ continue
+ }
+ // If SANs are *not* present, some clients will consider the certificate
+ // valid for the name in the Common Name.
+ if x509Cert.Subject.CommonName != "" && len(x509Cert.DNSNames) == 0 {
+ c.NameToCertificate[x509Cert.Subject.CommonName] = cert
+ }
+ for _, san := range x509Cert.DNSNames {
+ c.NameToCertificate[san] = cert
+ }
+ }
+}
+
+const (
+ keyLogLabelTLS12 = "CLIENT_RANDOM"
+ keyLogLabelClientHandshake = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"
+ keyLogLabelServerHandshake = "SERVER_HANDSHAKE_TRAFFIC_SECRET"
+ keyLogLabelClientTraffic = "CLIENT_TRAFFIC_SECRET_0"
+ keyLogLabelServerTraffic = "SERVER_TRAFFIC_SECRET_0"
+)
+
+func (c *Config) writeKeyLog(label string, clientRandom, secret []byte) error {
+ if c.KeyLogWriter == nil {
+ return nil
+ }
+
+ logLine := fmt.Appendf(nil, "%s %x %x\n", label, clientRandom, secret)
+
+ writerMutex.Lock()
+ _, err := c.KeyLogWriter.Write(logLine)
+ writerMutex.Unlock()
+
+ return err
+}
+
+// writerMutex protects all KeyLogWriters globally. It is rarely enabled,
+// and is only for debugging, so a global mutex saves space.
+var writerMutex sync.Mutex
+
+// A Certificate is a chain of one or more certificates, leaf first.
+type Certificate struct {
+ Certificate [][]byte
+ // PrivateKey contains the private key corresponding to the public key in
+ // Leaf. This must implement crypto.Signer with an RSA, ECDSA or Ed25519 PublicKey.
+ // For a server up to TLS 1.2, it can also implement crypto.Decrypter with
+ // an RSA PublicKey.
+ PrivateKey crypto.PrivateKey
+ // SupportedSignatureAlgorithms is an optional list restricting what
+ // signature algorithms the PrivateKey can be used for.
+ SupportedSignatureAlgorithms []SignatureScheme
+ // OCSPStaple contains an optional OCSP response which will be served
+ // to clients that request it.
+ OCSPStaple []byte
+ // SignedCertificateTimestamps contains an optional list of Signed
+ // Certificate Timestamps which will be served to clients that request it.
+ SignedCertificateTimestamps [][]byte
+ // Leaf is the parsed form of the leaf certificate, which may be initialized
+ // using x509.ParseCertificate to reduce per-handshake processing. If nil,
+ // the leaf certificate will be parsed as needed.
+ Leaf *x509.Certificate
+}
+
+// leaf returns the parsed leaf certificate, either from c.Leaf or by parsing
+// the corresponding c.Certificate[0].
+func (c *Certificate) leaf() (*x509.Certificate, error) {
+ if c.Leaf != nil {
+ return c.Leaf, nil
+ }
+ return x509.ParseCertificate(c.Certificate[0])
+}
+
+type handshakeMessage interface {
+ marshal() ([]byte, error)
+ unmarshal([]byte) bool
+}
+
+// lruSessionCache is a ClientSessionCache implementation that uses an LRU
+// caching strategy.
+type lruSessionCache struct {
+ sync.Mutex
+
+ m map[string]*list.Element
+ q *list.List
+ capacity int
+}
+
+type lruSessionCacheEntry struct {
+ sessionKey string
+ state *ClientSessionState
+}
+
+// NewLRUClientSessionCache returns a ClientSessionCache with the given
+// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
+// is used instead.
+func NewLRUClientSessionCache(capacity int) ClientSessionCache {
+ const defaultSessionCacheCapacity = 64
+
+ if capacity < 1 {
+ capacity = defaultSessionCacheCapacity
+ }
+ return &lruSessionCache{
+ m: make(map[string]*list.Element),
+ q: list.New(),
+ capacity: capacity,
+ }
+}
+
+// Put adds the provided (sessionKey, cs) pair to the cache. If cs is nil, the entry
+// corresponding to sessionKey is removed from the cache instead.
+func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) {
+ c.Lock()
+ defer c.Unlock()
+
+ if elem, ok := c.m[sessionKey]; ok {
+ if cs == nil {
+ c.q.Remove(elem)
+ delete(c.m, sessionKey)
+ } else {
+ entry := elem.Value.(*lruSessionCacheEntry)
+ entry.state = cs
+ c.q.MoveToFront(elem)
+ }
+ return
+ }
+
+ if c.q.Len() < c.capacity {
+ entry := &lruSessionCacheEntry{sessionKey, cs}
+ c.m[sessionKey] = c.q.PushFront(entry)
+ return
+ }
+
+ elem := c.q.Back()
+ entry := elem.Value.(*lruSessionCacheEntry)
+ delete(c.m, entry.sessionKey)
+ entry.sessionKey = sessionKey
+ entry.state = cs
+ c.q.MoveToFront(elem)
+ c.m[sessionKey] = elem
+}
+
+// Get returns the ClientSessionState value associated with a given key. It
+// returns (nil, false) if no value is found.
+func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
+ c.Lock()
+ defer c.Unlock()
+
+ if elem, ok := c.m[sessionKey]; ok {
+ c.q.MoveToFront(elem)
+ return elem.Value.(*lruSessionCacheEntry).state, true
+ }
+ return nil, false
+}
+
+var emptyConfig Config
+
+func defaultConfig() *Config {
+ return &emptyConfig
+}
+
+func unexpectedMessageError(wanted, got any) error {
+ return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted)
+}
+
+func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlgorithms []SignatureScheme) bool {
+ for _, s := range supportedSignatureAlgorithms {
+ if s == sigAlg {
+ return true
+ }
+ }
+ return false
+}
+
+// CertificateVerificationError is returned when certificate verification fails during the handshake.
+type CertificateVerificationError struct {
+ // UnverifiedCertificates and its contents should not be modified.
+ UnverifiedCertificates []*x509.Certificate
+ Err error
+}
+
+func (e *CertificateVerificationError) Error() string {
+ return fmt.Sprintf("tls: failed to verify certificate: %s", e.Err)
+}
+
+func (e *CertificateVerificationError) Unwrap() error {
+ return e.Err
+}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/common_string.go b/contrib/go/_std_1.21/src/crypto/tls/common_string.go
index 238108811f..238108811f 100644
--- a/contrib/go/_std_1.20/src/crypto/tls/common_string.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/common_string.go
diff --git a/contrib/go/_std_1.21/src/crypto/tls/conn.go b/contrib/go/_std_1.21/src/crypto/tls/conn.go
new file mode 100644
index 0000000000..c04bd48d6a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/conn.go
@@ -0,0 +1,1655 @@
+// Copyright 2010 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.
+
+// TLS low level connection and record layer
+
+package tls
+
+import (
+ "bytes"
+ "context"
+ "crypto/cipher"
+ "crypto/subtle"
+ "crypto/x509"
+ "errors"
+ "fmt"
+ "hash"
+ "io"
+ "net"
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+// A Conn represents a secured connection.
+// It implements the net.Conn interface.
+type Conn struct {
+ // constant
+ conn net.Conn
+ isClient bool
+ handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake
+ quic *quicState // nil for non-QUIC connections
+
+ // isHandshakeComplete is true if the connection is currently transferring
+ // application data (i.e. is not currently processing a handshake).
+ // isHandshakeComplete is true implies handshakeErr == nil.
+ isHandshakeComplete atomic.Bool
+ // constant after handshake; protected by handshakeMutex
+ handshakeMutex sync.Mutex
+ handshakeErr error // error resulting from handshake
+ vers uint16 // TLS version
+ haveVers bool // version has been negotiated
+ config *Config // configuration passed to constructor
+ // handshakes counts the number of handshakes performed on the
+ // connection so far. If renegotiation is disabled then this is either
+ // zero or one.
+ handshakes int
+ extMasterSecret bool
+ didResume bool // whether this connection was a session resumption
+ cipherSuite uint16
+ ocspResponse []byte // stapled OCSP response
+ scts [][]byte // signed certificate timestamps from server
+ peerCertificates []*x509.Certificate
+ // activeCertHandles contains the cache handles to certificates in
+ // peerCertificates that are used to track active references.
+ activeCertHandles []*activeCert
+ // verifiedChains contains the certificate chains that we built, as
+ // opposed to the ones presented by the server.
+ verifiedChains [][]*x509.Certificate
+ // serverName contains the server name indicated by the client, if any.
+ serverName string
+ // secureRenegotiation is true if the server echoed the secure
+ // renegotiation extension. (This is meaningless as a server because
+ // renegotiation is not supported in that case.)
+ secureRenegotiation bool
+ // ekm is a closure for exporting keying material.
+ ekm func(label string, context []byte, length int) ([]byte, error)
+ // resumptionSecret is the resumption_master_secret for handling
+ // or sending NewSessionTicket messages.
+ resumptionSecret []byte
+
+ // ticketKeys is the set of active session ticket keys for this
+ // connection. The first one is used to encrypt new tickets and
+ // all are tried to decrypt tickets.
+ ticketKeys []ticketKey
+
+ // clientFinishedIsFirst is true if the client sent the first Finished
+ // message during the most recent handshake. This is recorded because
+ // the first transmitted Finished message is the tls-unique
+ // channel-binding value.
+ clientFinishedIsFirst bool
+
+ // closeNotifyErr is any error from sending the alertCloseNotify record.
+ closeNotifyErr error
+ // closeNotifySent is true if the Conn attempted to send an
+ // alertCloseNotify record.
+ closeNotifySent bool
+
+ // clientFinished and serverFinished contain the Finished message sent
+ // by the client or server in the most recent handshake. This is
+ // retained to support the renegotiation extension and tls-unique
+ // channel-binding.
+ clientFinished [12]byte
+ serverFinished [12]byte
+
+ // clientProtocol is the negotiated ALPN protocol.
+ clientProtocol string
+
+ // input/output
+ in, out halfConn
+ rawInput bytes.Buffer // raw input, starting with a record header
+ input bytes.Reader // application data waiting to be read, from rawInput.Next
+ hand bytes.Buffer // handshake data waiting to be read
+ buffering bool // whether records are buffered in sendBuf
+ sendBuf []byte // a buffer of records waiting to be sent
+
+ // bytesSent counts the bytes of application data sent.
+ // packetsSent counts packets.
+ bytesSent int64
+ packetsSent int64
+
+ // retryCount counts the number of consecutive non-advancing records
+ // received by Conn.readRecord. That is, records that neither advance the
+ // handshake, nor deliver application data. Protected by in.Mutex.
+ retryCount int
+
+ // activeCall indicates whether Close has been call in the low bit.
+ // the rest of the bits are the number of goroutines in Conn.Write.
+ activeCall atomic.Int32
+
+ tmp [16]byte
+}
+
+// Access to net.Conn methods.
+// Cannot just embed net.Conn because that would
+// export the struct field too.
+
+// LocalAddr returns the local network address.
+func (c *Conn) LocalAddr() net.Addr {
+ return c.conn.LocalAddr()
+}
+
+// RemoteAddr returns the remote network address.
+func (c *Conn) RemoteAddr() net.Addr {
+ return c.conn.RemoteAddr()
+}
+
+// SetDeadline sets the read and write deadlines associated with the connection.
+// A zero value for t means Read and Write will not time out.
+// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
+func (c *Conn) SetDeadline(t time.Time) error {
+ return c.conn.SetDeadline(t)
+}
+
+// SetReadDeadline sets the read deadline on the underlying connection.
+// A zero value for t means Read will not time out.
+func (c *Conn) SetReadDeadline(t time.Time) error {
+ return c.conn.SetReadDeadline(t)
+}
+
+// SetWriteDeadline sets the write deadline on the underlying connection.
+// A zero value for t means Write will not time out.
+// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
+func (c *Conn) SetWriteDeadline(t time.Time) error {
+ return c.conn.SetWriteDeadline(t)
+}
+
+// NetConn returns the underlying connection that is wrapped by c.
+// Note that writing to or reading from this connection directly will corrupt the
+// TLS session.
+func (c *Conn) NetConn() net.Conn {
+ return c.conn
+}
+
+// A halfConn represents one direction of the record layer
+// connection, either sending or receiving.
+type halfConn struct {
+ sync.Mutex
+
+ err error // first permanent error
+ version uint16 // protocol version
+ cipher any // cipher algorithm
+ mac hash.Hash
+ seq [8]byte // 64-bit sequence number
+
+ scratchBuf [13]byte // to avoid allocs; interface method args escape
+
+ nextCipher any // next encryption state
+ nextMac hash.Hash // next MAC algorithm
+
+ level QUICEncryptionLevel // current QUIC encryption level
+ trafficSecret []byte // current TLS 1.3 traffic secret
+}
+
+type permanentError struct {
+ err net.Error
+}
+
+func (e *permanentError) Error() string { return e.err.Error() }
+func (e *permanentError) Unwrap() error { return e.err }
+func (e *permanentError) Timeout() bool { return e.err.Timeout() }
+func (e *permanentError) Temporary() bool { return false }
+
+func (hc *halfConn) setErrorLocked(err error) error {
+ if e, ok := err.(net.Error); ok {
+ hc.err = &permanentError{err: e}
+ } else {
+ hc.err = err
+ }
+ return hc.err
+}
+
+// prepareCipherSpec sets the encryption and MAC states
+// that a subsequent changeCipherSpec will use.
+func (hc *halfConn) prepareCipherSpec(version uint16, cipher any, mac hash.Hash) {
+ hc.version = version
+ hc.nextCipher = cipher
+ hc.nextMac = mac
+}
+
+// changeCipherSpec changes the encryption and MAC states
+// to the ones previously passed to prepareCipherSpec.
+func (hc *halfConn) changeCipherSpec() error {
+ if hc.nextCipher == nil || hc.version == VersionTLS13 {
+ return alertInternalError
+ }
+ hc.cipher = hc.nextCipher
+ hc.mac = hc.nextMac
+ hc.nextCipher = nil
+ hc.nextMac = nil
+ for i := range hc.seq {
+ hc.seq[i] = 0
+ }
+ return nil
+}
+
+func (hc *halfConn) setTrafficSecret(suite *cipherSuiteTLS13, level QUICEncryptionLevel, secret []byte) {
+ hc.trafficSecret = secret
+ hc.level = level
+ key, iv := suite.trafficKey(secret)
+ hc.cipher = suite.aead(key, iv)
+ for i := range hc.seq {
+ hc.seq[i] = 0
+ }
+}
+
+// incSeq increments the sequence number.
+func (hc *halfConn) incSeq() {
+ for i := 7; i >= 0; i-- {
+ hc.seq[i]++
+ if hc.seq[i] != 0 {
+ return
+ }
+ }
+
+ // Not allowed to let sequence number wrap.
+ // Instead, must renegotiate before it does.
+ // Not likely enough to bother.
+ panic("TLS: sequence number wraparound")
+}
+
+// explicitNonceLen returns the number of bytes of explicit nonce or IV included
+// in each record. Explicit nonces are present only in CBC modes after TLS 1.0
+// and in certain AEAD modes in TLS 1.2.
+func (hc *halfConn) explicitNonceLen() int {
+ if hc.cipher == nil {
+ return 0
+ }
+
+ switch c := hc.cipher.(type) {
+ case cipher.Stream:
+ return 0
+ case aead:
+ return c.explicitNonceLen()
+ case cbcMode:
+ // TLS 1.1 introduced a per-record explicit IV to fix the BEAST attack.
+ if hc.version >= VersionTLS11 {
+ return c.BlockSize()
+ }
+ return 0
+ default:
+ panic("unknown cipher type")
+ }
+}
+
+// extractPadding returns, in constant time, the length of the padding to remove
+// from the end of payload. It also returns a byte which is equal to 255 if the
+// padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2.
+func extractPadding(payload []byte) (toRemove int, good byte) {
+ if len(payload) < 1 {
+ return 0, 0
+ }
+
+ paddingLen := payload[len(payload)-1]
+ t := uint(len(payload)-1) - uint(paddingLen)
+ // if len(payload) >= (paddingLen - 1) then the MSB of t is zero
+ good = byte(int32(^t) >> 31)
+
+ // The maximum possible padding length plus the actual length field
+ toCheck := 256
+ // The length of the padded data is public, so we can use an if here
+ if toCheck > len(payload) {
+ toCheck = len(payload)
+ }
+
+ for i := 0; i < toCheck; i++ {
+ t := uint(paddingLen) - uint(i)
+ // if i <= paddingLen then the MSB of t is zero
+ mask := byte(int32(^t) >> 31)
+ b := payload[len(payload)-1-i]
+ good &^= mask&paddingLen ^ mask&b
+ }
+
+ // We AND together the bits of good and replicate the result across
+ // all the bits.
+ good &= good << 4
+ good &= good << 2
+ good &= good << 1
+ good = uint8(int8(good) >> 7)
+
+ // Zero the padding length on error. This ensures any unchecked bytes
+ // are included in the MAC. Otherwise, an attacker that could
+ // distinguish MAC failures from padding failures could mount an attack
+ // similar to POODLE in SSL 3.0: given a good ciphertext that uses a
+ // full block's worth of padding, replace the final block with another
+ // block. If the MAC check passed but the padding check failed, the
+ // last byte of that block decrypted to the block size.
+ //
+ // See also macAndPaddingGood logic below.
+ paddingLen &= good
+
+ toRemove = int(paddingLen) + 1
+ return
+}
+
+func roundUp(a, b int) int {
+ return a + (b-a%b)%b
+}
+
+// cbcMode is an interface for block ciphers using cipher block chaining.
+type cbcMode interface {
+ cipher.BlockMode
+ SetIV([]byte)
+}
+
+// decrypt authenticates and decrypts the record if protection is active at
+// this stage. The returned plaintext might overlap with the input.
+func (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) {
+ var plaintext []byte
+ typ := recordType(record[0])
+ payload := record[recordHeaderLen:]
+
+ // In TLS 1.3, change_cipher_spec messages are to be ignored without being
+ // decrypted. See RFC 8446, Appendix D.4.
+ if hc.version == VersionTLS13 && typ == recordTypeChangeCipherSpec {
+ return payload, typ, nil
+ }
+
+ paddingGood := byte(255)
+ paddingLen := 0
+
+ explicitNonceLen := hc.explicitNonceLen()
+
+ if hc.cipher != nil {
+ switch c := hc.cipher.(type) {
+ case cipher.Stream:
+ c.XORKeyStream(payload, payload)
+ case aead:
+ if len(payload) < explicitNonceLen {
+ return nil, 0, alertBadRecordMAC
+ }
+ nonce := payload[:explicitNonceLen]
+ if len(nonce) == 0 {
+ nonce = hc.seq[:]
+ }
+ payload = payload[explicitNonceLen:]
+
+ var additionalData []byte
+ if hc.version == VersionTLS13 {
+ additionalData = record[:recordHeaderLen]
+ } else {
+ additionalData = append(hc.scratchBuf[:0], hc.seq[:]...)
+ additionalData = append(additionalData, record[:3]...)
+ n := len(payload) - c.Overhead()
+ additionalData = append(additionalData, byte(n>>8), byte(n))
+ }
+
+ var err error
+ plaintext, err = c.Open(payload[:0], nonce, payload, additionalData)
+ if err != nil {
+ return nil, 0, alertBadRecordMAC
+ }
+ case cbcMode:
+ blockSize := c.BlockSize()
+ minPayload := explicitNonceLen + roundUp(hc.mac.Size()+1, blockSize)
+ if len(payload)%blockSize != 0 || len(payload) < minPayload {
+ return nil, 0, alertBadRecordMAC
+ }
+
+ if explicitNonceLen > 0 {
+ c.SetIV(payload[:explicitNonceLen])
+ payload = payload[explicitNonceLen:]
+ }
+ c.CryptBlocks(payload, payload)
+
+ // In a limited attempt to protect against CBC padding oracles like
+ // Lucky13, the data past paddingLen (which is secret) is passed to
+ // the MAC function as extra data, to be fed into the HMAC after
+ // computing the digest. This makes the MAC roughly constant time as
+ // long as the digest computation is constant time and does not
+ // affect the subsequent write, modulo cache effects.
+ paddingLen, paddingGood = extractPadding(payload)
+ default:
+ panic("unknown cipher type")
+ }
+
+ if hc.version == VersionTLS13 {
+ if typ != recordTypeApplicationData {
+ return nil, 0, alertUnexpectedMessage
+ }
+ if len(plaintext) > maxPlaintext+1 {
+ return nil, 0, alertRecordOverflow
+ }
+ // Remove padding and find the ContentType scanning from the end.
+ for i := len(plaintext) - 1; i >= 0; i-- {
+ if plaintext[i] != 0 {
+ typ = recordType(plaintext[i])
+ plaintext = plaintext[:i]
+ break
+ }
+ if i == 0 {
+ return nil, 0, alertUnexpectedMessage
+ }
+ }
+ }
+ } else {
+ plaintext = payload
+ }
+
+ if hc.mac != nil {
+ macSize := hc.mac.Size()
+ if len(payload) < macSize {
+ return nil, 0, alertBadRecordMAC
+ }
+
+ n := len(payload) - macSize - paddingLen
+ n = subtle.ConstantTimeSelect(int(uint32(n)>>31), 0, n) // if n < 0 { n = 0 }
+ record[3] = byte(n >> 8)
+ record[4] = byte(n)
+ remoteMAC := payload[n : n+macSize]
+ localMAC := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload[:n], payload[n+macSize:])
+
+ // This is equivalent to checking the MACs and paddingGood
+ // separately, but in constant-time to prevent distinguishing
+ // padding failures from MAC failures. Depending on what value
+ // of paddingLen was returned on bad padding, distinguishing
+ // bad MAC from bad padding can lead to an attack.
+ //
+ // See also the logic at the end of extractPadding.
+ macAndPaddingGood := subtle.ConstantTimeCompare(localMAC, remoteMAC) & int(paddingGood)
+ if macAndPaddingGood != 1 {
+ return nil, 0, alertBadRecordMAC
+ }
+
+ plaintext = payload[:n]
+ }
+
+ hc.incSeq()
+ return plaintext, typ, nil
+}
+
+// sliceForAppend extends the input slice by n bytes. head is the full extended
+// slice, while tail is the appended part. If the original slice has sufficient
+// capacity no allocation is performed.
+func sliceForAppend(in []byte, n int) (head, tail []byte) {
+ if total := len(in) + n; cap(in) >= total {
+ head = in[:total]
+ } else {
+ head = make([]byte, total)
+ copy(head, in)
+ }
+ tail = head[len(in):]
+ return
+}
+
+// encrypt encrypts payload, adding the appropriate nonce and/or MAC, and
+// appends it to record, which must already contain the record header.
+func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, error) {
+ if hc.cipher == nil {
+ return append(record, payload...), nil
+ }
+
+ var explicitNonce []byte
+ if explicitNonceLen := hc.explicitNonceLen(); explicitNonceLen > 0 {
+ record, explicitNonce = sliceForAppend(record, explicitNonceLen)
+ if _, isCBC := hc.cipher.(cbcMode); !isCBC && explicitNonceLen < 16 {
+ // The AES-GCM construction in TLS has an explicit nonce so that the
+ // nonce can be random. However, the nonce is only 8 bytes which is
+ // too small for a secure, random nonce. Therefore we use the
+ // sequence number as the nonce. The 3DES-CBC construction also has
+ // an 8 bytes nonce but its nonces must be unpredictable (see RFC
+ // 5246, Appendix F.3), forcing us to use randomness. That's not
+ // 3DES' biggest problem anyway because the birthday bound on block
+ // collision is reached first due to its similarly small block size
+ // (see the Sweet32 attack).
+ copy(explicitNonce, hc.seq[:])
+ } else {
+ if _, err := io.ReadFull(rand, explicitNonce); err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ var dst []byte
+ switch c := hc.cipher.(type) {
+ case cipher.Stream:
+ mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil)
+ record, dst = sliceForAppend(record, len(payload)+len(mac))
+ c.XORKeyStream(dst[:len(payload)], payload)
+ c.XORKeyStream(dst[len(payload):], mac)
+ case aead:
+ nonce := explicitNonce
+ if len(nonce) == 0 {
+ nonce = hc.seq[:]
+ }
+
+ if hc.version == VersionTLS13 {
+ record = append(record, payload...)
+
+ // Encrypt the actual ContentType and replace the plaintext one.
+ record = append(record, record[0])
+ record[0] = byte(recordTypeApplicationData)
+
+ n := len(payload) + 1 + c.Overhead()
+ record[3] = byte(n >> 8)
+ record[4] = byte(n)
+
+ record = c.Seal(record[:recordHeaderLen],
+ nonce, record[recordHeaderLen:], record[:recordHeaderLen])
+ } else {
+ additionalData := append(hc.scratchBuf[:0], hc.seq[:]...)
+ additionalData = append(additionalData, record[:recordHeaderLen]...)
+ record = c.Seal(record, nonce, payload, additionalData)
+ }
+ case cbcMode:
+ mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil)
+ blockSize := c.BlockSize()
+ plaintextLen := len(payload) + len(mac)
+ paddingLen := blockSize - plaintextLen%blockSize
+ record, dst = sliceForAppend(record, plaintextLen+paddingLen)
+ copy(dst, payload)
+ copy(dst[len(payload):], mac)
+ for i := plaintextLen; i < len(dst); i++ {
+ dst[i] = byte(paddingLen - 1)
+ }
+ if len(explicitNonce) > 0 {
+ c.SetIV(explicitNonce)
+ }
+ c.CryptBlocks(dst, dst)
+ default:
+ panic("unknown cipher type")
+ }
+
+ // Update length to include nonce, MAC and any block padding needed.
+ n := len(record) - recordHeaderLen
+ record[3] = byte(n >> 8)
+ record[4] = byte(n)
+ hc.incSeq()
+
+ return record, nil
+}
+
+// RecordHeaderError is returned when a TLS record header is invalid.
+type RecordHeaderError struct {
+ // Msg contains a human readable string that describes the error.
+ Msg string
+ // RecordHeader contains the five bytes of TLS record header that
+ // triggered the error.
+ RecordHeader [5]byte
+ // Conn provides the underlying net.Conn in the case that a client
+ // sent an initial handshake that didn't look like TLS.
+ // It is nil if there's already been a handshake or a TLS alert has
+ // been written to the connection.
+ Conn net.Conn
+}
+
+func (e RecordHeaderError) Error() string { return "tls: " + e.Msg }
+
+func (c *Conn) newRecordHeaderError(conn net.Conn, msg string) (err RecordHeaderError) {
+ err.Msg = msg
+ err.Conn = conn
+ copy(err.RecordHeader[:], c.rawInput.Bytes())
+ return err
+}
+
+func (c *Conn) readRecord() error {
+ return c.readRecordOrCCS(false)
+}
+
+func (c *Conn) readChangeCipherSpec() error {
+ return c.readRecordOrCCS(true)
+}
+
+// readRecordOrCCS reads one or more TLS records from the connection and
+// updates the record layer state. Some invariants:
+// - c.in must be locked
+// - c.input must be empty
+//
+// During the handshake one and only one of the following will happen:
+// - c.hand grows
+// - c.in.changeCipherSpec is called
+// - an error is returned
+//
+// After the handshake one and only one of the following will happen:
+// - c.hand grows
+// - c.input is set
+// - an error is returned
+func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {
+ if c.in.err != nil {
+ return c.in.err
+ }
+ handshakeComplete := c.isHandshakeComplete.Load()
+
+ // This function modifies c.rawInput, which owns the c.input memory.
+ if c.input.Len() != 0 {
+ return c.in.setErrorLocked(errors.New("tls: internal error: attempted to read record with pending application data"))
+ }
+ c.input.Reset(nil)
+
+ if c.quic != nil {
+ return c.in.setErrorLocked(errors.New("tls: internal error: attempted to read record with QUIC transport"))
+ }
+
+ // Read header, payload.
+ if err := c.readFromUntil(c.conn, recordHeaderLen); err != nil {
+ // RFC 8446, Section 6.1 suggests that EOF without an alertCloseNotify
+ // is an error, but popular web sites seem to do this, so we accept it
+ // if and only if at the record boundary.
+ if err == io.ErrUnexpectedEOF && c.rawInput.Len() == 0 {
+ err = io.EOF
+ }
+ if e, ok := err.(net.Error); !ok || !e.Temporary() {
+ c.in.setErrorLocked(err)
+ }
+ return err
+ }
+ hdr := c.rawInput.Bytes()[:recordHeaderLen]
+ typ := recordType(hdr[0])
+
+ // No valid TLS record has a type of 0x80, however SSLv2 handshakes
+ // start with a uint16 length where the MSB is set and the first record
+ // is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
+ // an SSLv2 client.
+ if !handshakeComplete && typ == 0x80 {
+ c.sendAlert(alertProtocolVersion)
+ return c.in.setErrorLocked(c.newRecordHeaderError(nil, "unsupported SSLv2 handshake received"))
+ }
+
+ vers := uint16(hdr[1])<<8 | uint16(hdr[2])
+ expectedVers := c.vers
+ if expectedVers == VersionTLS13 {
+ // All TLS 1.3 records are expected to have 0x0303 (1.2) after
+ // the initial hello (RFC 8446 Section 5.1).
+ expectedVers = VersionTLS12
+ }
+ n := int(hdr[3])<<8 | int(hdr[4])
+ if c.haveVers && vers != expectedVers {
+ c.sendAlert(alertProtocolVersion)
+ msg := fmt.Sprintf("received record with version %x when expecting version %x", vers, expectedVers)
+ return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg))
+ }
+ if !c.haveVers {
+ // First message, be extra suspicious: this might not be a TLS
+ // client. Bail out before reading a full 'body', if possible.
+ // The current max version is 3.3 so if the version is >= 16.0,
+ // it's probably not real.
+ if (typ != recordTypeAlert && typ != recordTypeHandshake) || vers >= 0x1000 {
+ return c.in.setErrorLocked(c.newRecordHeaderError(c.conn, "first record does not look like a TLS handshake"))
+ }
+ }
+ if c.vers == VersionTLS13 && n > maxCiphertextTLS13 || n > maxCiphertext {
+ c.sendAlert(alertRecordOverflow)
+ msg := fmt.Sprintf("oversized record received with length %d", n)
+ return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg))
+ }
+ if err := c.readFromUntil(c.conn, recordHeaderLen+n); err != nil {
+ if e, ok := err.(net.Error); !ok || !e.Temporary() {
+ c.in.setErrorLocked(err)
+ }
+ return err
+ }
+
+ // Process message.
+ record := c.rawInput.Next(recordHeaderLen + n)
+ data, typ, err := c.in.decrypt(record)
+ if err != nil {
+ return c.in.setErrorLocked(c.sendAlert(err.(alert)))
+ }
+ if len(data) > maxPlaintext {
+ return c.in.setErrorLocked(c.sendAlert(alertRecordOverflow))
+ }
+
+ // Application Data messages are always protected.
+ if c.in.cipher == nil && typ == recordTypeApplicationData {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+
+ if typ != recordTypeAlert && typ != recordTypeChangeCipherSpec && len(data) > 0 {
+ // This is a state-advancing message: reset the retry count.
+ c.retryCount = 0
+ }
+
+ // Handshake messages MUST NOT be interleaved with other record types in TLS 1.3.
+ if c.vers == VersionTLS13 && typ != recordTypeHandshake && c.hand.Len() > 0 {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+
+ switch typ {
+ default:
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+
+ case recordTypeAlert:
+ if c.quic != nil {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ if len(data) != 2 {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ if alert(data[1]) == alertCloseNotify {
+ return c.in.setErrorLocked(io.EOF)
+ }
+ if c.vers == VersionTLS13 {
+ return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
+ }
+ switch data[0] {
+ case alertLevelWarning:
+ // Drop the record on the floor and retry.
+ return c.retryReadRecord(expectChangeCipherSpec)
+ case alertLevelError:
+ return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
+ default:
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+
+ case recordTypeChangeCipherSpec:
+ if len(data) != 1 || data[0] != 1 {
+ return c.in.setErrorLocked(c.sendAlert(alertDecodeError))
+ }
+ // Handshake messages are not allowed to fragment across the CCS.
+ if c.hand.Len() > 0 {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ // In TLS 1.3, change_cipher_spec records are ignored until the
+ // Finished. See RFC 8446, Appendix D.4. Note that according to Section
+ // 5, a server can send a ChangeCipherSpec before its ServerHello, when
+ // c.vers is still unset. That's not useful though and suspicious if the
+ // server then selects a lower protocol version, so don't allow that.
+ if c.vers == VersionTLS13 {
+ return c.retryReadRecord(expectChangeCipherSpec)
+ }
+ if !expectChangeCipherSpec {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ if err := c.in.changeCipherSpec(); err != nil {
+ return c.in.setErrorLocked(c.sendAlert(err.(alert)))
+ }
+
+ case recordTypeApplicationData:
+ if !handshakeComplete || expectChangeCipherSpec {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ // Some OpenSSL servers send empty records in order to randomize the
+ // CBC IV. Ignore a limited number of empty records.
+ if len(data) == 0 {
+ return c.retryReadRecord(expectChangeCipherSpec)
+ }
+ // Note that data is owned by c.rawInput, following the Next call above,
+ // to avoid copying the plaintext. This is safe because c.rawInput is
+ // not read from or written to until c.input is drained.
+ c.input.Reset(data)
+
+ case recordTypeHandshake:
+ if len(data) == 0 || expectChangeCipherSpec {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ c.hand.Write(data)
+ }
+
+ return nil
+}
+
+// retryReadRecord recurs into readRecordOrCCS to drop a non-advancing record, like
+// a warning alert, empty application_data, or a change_cipher_spec in TLS 1.3.
+func (c *Conn) retryReadRecord(expectChangeCipherSpec bool) error {
+ c.retryCount++
+ if c.retryCount > maxUselessRecords {
+ c.sendAlert(alertUnexpectedMessage)
+ return c.in.setErrorLocked(errors.New("tls: too many ignored records"))
+ }
+ return c.readRecordOrCCS(expectChangeCipherSpec)
+}
+
+// atLeastReader reads from R, stopping with EOF once at least N bytes have been
+// read. It is different from an io.LimitedReader in that it doesn't cut short
+// the last Read call, and in that it considers an early EOF an error.
+type atLeastReader struct {
+ R io.Reader
+ N int64
+}
+
+func (r *atLeastReader) Read(p []byte) (int, error) {
+ if r.N <= 0 {
+ return 0, io.EOF
+ }
+ n, err := r.R.Read(p)
+ r.N -= int64(n) // won't underflow unless len(p) >= n > 9223372036854775809
+ if r.N > 0 && err == io.EOF {
+ return n, io.ErrUnexpectedEOF
+ }
+ if r.N <= 0 && err == nil {
+ return n, io.EOF
+ }
+ return n, err
+}
+
+// readFromUntil reads from r into c.rawInput until c.rawInput contains
+// at least n bytes or else returns an error.
+func (c *Conn) readFromUntil(r io.Reader, n int) error {
+ if c.rawInput.Len() >= n {
+ return nil
+ }
+ needs := n - c.rawInput.Len()
+ // There might be extra input waiting on the wire. Make a best effort
+ // attempt to fetch it so that it can be used in (*Conn).Read to
+ // "predict" closeNotify alerts.
+ c.rawInput.Grow(needs + bytes.MinRead)
+ _, err := c.rawInput.ReadFrom(&atLeastReader{r, int64(needs)})
+ return err
+}
+
+// sendAlertLocked sends a TLS alert message.
+func (c *Conn) sendAlertLocked(err alert) error {
+ if c.quic != nil {
+ return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+ }
+
+ switch err {
+ case alertNoRenegotiation, alertCloseNotify:
+ c.tmp[0] = alertLevelWarning
+ default:
+ c.tmp[0] = alertLevelError
+ }
+ c.tmp[1] = byte(err)
+
+ _, writeErr := c.writeRecordLocked(recordTypeAlert, c.tmp[0:2])
+ if err == alertCloseNotify {
+ // closeNotify is a special case in that it isn't an error.
+ return writeErr
+ }
+
+ return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+}
+
+// sendAlert sends a TLS alert message.
+func (c *Conn) sendAlert(err alert) error {
+ c.out.Lock()
+ defer c.out.Unlock()
+ return c.sendAlertLocked(err)
+}
+
+const (
+ // tcpMSSEstimate is a conservative estimate of the TCP maximum segment
+ // size (MSS). A constant is used, rather than querying the kernel for
+ // the actual MSS, to avoid complexity. The value here is the IPv6
+ // minimum MTU (1280 bytes) minus the overhead of an IPv6 header (40
+ // bytes) and a TCP header with timestamps (32 bytes).
+ tcpMSSEstimate = 1208
+
+ // recordSizeBoostThreshold is the number of bytes of application data
+ // sent after which the TLS record size will be increased to the
+ // maximum.
+ recordSizeBoostThreshold = 128 * 1024
+)
+
+// maxPayloadSizeForWrite returns the maximum TLS payload size to use for the
+// next application data record. There is the following trade-off:
+//
+// - For latency-sensitive applications, such as web browsing, each TLS
+// record should fit in one TCP segment.
+// - For throughput-sensitive applications, such as large file transfers,
+// larger TLS records better amortize framing and encryption overheads.
+//
+// A simple heuristic that works well in practice is to use small records for
+// the first 1MB of data, then use larger records for subsequent data, and
+// reset back to smaller records after the connection becomes idle. See "High
+// Performance Web Networking", Chapter 4, or:
+// https://www.igvita.com/2013/10/24/optimizing-tls-record-size-and-buffering-latency/
+//
+// In the interests of simplicity and determinism, this code does not attempt
+// to reset the record size once the connection is idle, however.
+func (c *Conn) maxPayloadSizeForWrite(typ recordType) int {
+ if c.config.DynamicRecordSizingDisabled || typ != recordTypeApplicationData {
+ return maxPlaintext
+ }
+
+ if c.bytesSent >= recordSizeBoostThreshold {
+ return maxPlaintext
+ }
+
+ // Subtract TLS overheads to get the maximum payload size.
+ payloadBytes := tcpMSSEstimate - recordHeaderLen - c.out.explicitNonceLen()
+ if c.out.cipher != nil {
+ switch ciph := c.out.cipher.(type) {
+ case cipher.Stream:
+ payloadBytes -= c.out.mac.Size()
+ case cipher.AEAD:
+ payloadBytes -= ciph.Overhead()
+ case cbcMode:
+ blockSize := ciph.BlockSize()
+ // The payload must fit in a multiple of blockSize, with
+ // room for at least one padding byte.
+ payloadBytes = (payloadBytes & ^(blockSize - 1)) - 1
+ // The MAC is appended before padding so affects the
+ // payload size directly.
+ payloadBytes -= c.out.mac.Size()
+ default:
+ panic("unknown cipher type")
+ }
+ }
+ if c.vers == VersionTLS13 {
+ payloadBytes-- // encrypted ContentType
+ }
+
+ // Allow packet growth in arithmetic progression up to max.
+ pkt := c.packetsSent
+ c.packetsSent++
+ if pkt > 1000 {
+ return maxPlaintext // avoid overflow in multiply below
+ }
+
+ n := payloadBytes * int(pkt+1)
+ if n > maxPlaintext {
+ n = maxPlaintext
+ }
+ return n
+}
+
+func (c *Conn) write(data []byte) (int, error) {
+ if c.buffering {
+ c.sendBuf = append(c.sendBuf, data...)
+ return len(data), nil
+ }
+
+ n, err := c.conn.Write(data)
+ c.bytesSent += int64(n)
+ return n, err
+}
+
+func (c *Conn) flush() (int, error) {
+ if len(c.sendBuf) == 0 {
+ return 0, nil
+ }
+
+ n, err := c.conn.Write(c.sendBuf)
+ c.bytesSent += int64(n)
+ c.sendBuf = nil
+ c.buffering = false
+ return n, err
+}
+
+// outBufPool pools the record-sized scratch buffers used by writeRecordLocked.
+var outBufPool = sync.Pool{
+ New: func() any {
+ return new([]byte)
+ },
+}
+
+// writeRecordLocked writes a TLS record with the given type and payload to the
+// connection and updates the record layer state.
+func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {
+ if c.quic != nil {
+ if typ != recordTypeHandshake {
+ return 0, errors.New("tls: internal error: sending non-handshake message to QUIC transport")
+ }
+ c.quicWriteCryptoData(c.out.level, data)
+ if !c.buffering {
+ if _, err := c.flush(); err != nil {
+ return 0, err
+ }
+ }
+ return len(data), nil
+ }
+
+ outBufPtr := outBufPool.Get().(*[]byte)
+ outBuf := *outBufPtr
+ defer func() {
+ // You might be tempted to simplify this by just passing &outBuf to Put,
+ // but that would make the local copy of the outBuf slice header escape
+ // to the heap, causing an allocation. Instead, we keep around the
+ // pointer to the slice header returned by Get, which is already on the
+ // heap, and overwrite and return that.
+ *outBufPtr = outBuf
+ outBufPool.Put(outBufPtr)
+ }()
+
+ var n int
+ for len(data) > 0 {
+ m := len(data)
+ if maxPayload := c.maxPayloadSizeForWrite(typ); m > maxPayload {
+ m = maxPayload
+ }
+
+ _, outBuf = sliceForAppend(outBuf[:0], recordHeaderLen)
+ outBuf[0] = byte(typ)
+ vers := c.vers
+ if vers == 0 {
+ // Some TLS servers fail if the record version is
+ // greater than TLS 1.0 for the initial ClientHello.
+ vers = VersionTLS10
+ } else if vers == VersionTLS13 {
+ // TLS 1.3 froze the record layer version to 1.2.
+ // See RFC 8446, Section 5.1.
+ vers = VersionTLS12
+ }
+ outBuf[1] = byte(vers >> 8)
+ outBuf[2] = byte(vers)
+ outBuf[3] = byte(m >> 8)
+ outBuf[4] = byte(m)
+
+ var err error
+ outBuf, err = c.out.encrypt(outBuf, data[:m], c.config.rand())
+ if err != nil {
+ return n, err
+ }
+ if _, err := c.write(outBuf); err != nil {
+ return n, err
+ }
+ n += m
+ data = data[m:]
+ }
+
+ if typ == recordTypeChangeCipherSpec && c.vers != VersionTLS13 {
+ if err := c.out.changeCipherSpec(); err != nil {
+ return n, c.sendAlertLocked(err.(alert))
+ }
+ }
+
+ return n, nil
+}
+
+// writeHandshakeRecord writes a handshake message to the connection and updates
+// the record layer state. If transcript is non-nil the marshalled message is
+// written to it.
+func (c *Conn) writeHandshakeRecord(msg handshakeMessage, transcript transcriptHash) (int, error) {
+ c.out.Lock()
+ defer c.out.Unlock()
+
+ data, err := msg.marshal()
+ if err != nil {
+ return 0, err
+ }
+ if transcript != nil {
+ transcript.Write(data)
+ }
+
+ return c.writeRecordLocked(recordTypeHandshake, data)
+}
+
+// writeChangeCipherRecord writes a ChangeCipherSpec message to the connection and
+// updates the record layer state.
+func (c *Conn) writeChangeCipherRecord() error {
+ c.out.Lock()
+ defer c.out.Unlock()
+ _, err := c.writeRecordLocked(recordTypeChangeCipherSpec, []byte{1})
+ return err
+}
+
+// readHandshakeBytes reads handshake data until c.hand contains at least n bytes.
+func (c *Conn) readHandshakeBytes(n int) error {
+ if c.quic != nil {
+ return c.quicReadHandshakeBytes(n)
+ }
+ for c.hand.Len() < n {
+ if err := c.readRecord(); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// readHandshake reads the next handshake message from
+// the record layer. If transcript is non-nil, the message
+// is written to the passed transcriptHash.
+func (c *Conn) readHandshake(transcript transcriptHash) (any, error) {
+ if err := c.readHandshakeBytes(4); err != nil {
+ return nil, err
+ }
+ data := c.hand.Bytes()
+ n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
+ if n > maxHandshake {
+ c.sendAlertLocked(alertInternalError)
+ return nil, c.in.setErrorLocked(fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake))
+ }
+ if err := c.readHandshakeBytes(4 + n); err != nil {
+ return nil, err
+ }
+ data = c.hand.Next(4 + n)
+ return c.unmarshalHandshakeMessage(data, transcript)
+}
+
+func (c *Conn) unmarshalHandshakeMessage(data []byte, transcript transcriptHash) (handshakeMessage, error) {
+ var m handshakeMessage
+ switch data[0] {
+ case typeHelloRequest:
+ m = new(helloRequestMsg)
+ case typeClientHello:
+ m = new(clientHelloMsg)
+ case typeServerHello:
+ m = new(serverHelloMsg)
+ case typeNewSessionTicket:
+ if c.vers == VersionTLS13 {
+ m = new(newSessionTicketMsgTLS13)
+ } else {
+ m = new(newSessionTicketMsg)
+ }
+ case typeCertificate:
+ if c.vers == VersionTLS13 {
+ m = new(certificateMsgTLS13)
+ } else {
+ m = new(certificateMsg)
+ }
+ case typeCertificateRequest:
+ if c.vers == VersionTLS13 {
+ m = new(certificateRequestMsgTLS13)
+ } else {
+ m = &certificateRequestMsg{
+ hasSignatureAlgorithm: c.vers >= VersionTLS12,
+ }
+ }
+ case typeCertificateStatus:
+ m = new(certificateStatusMsg)
+ case typeServerKeyExchange:
+ m = new(serverKeyExchangeMsg)
+ case typeServerHelloDone:
+ m = new(serverHelloDoneMsg)
+ case typeClientKeyExchange:
+ m = new(clientKeyExchangeMsg)
+ case typeCertificateVerify:
+ m = &certificateVerifyMsg{
+ hasSignatureAlgorithm: c.vers >= VersionTLS12,
+ }
+ case typeFinished:
+ m = new(finishedMsg)
+ case typeEncryptedExtensions:
+ m = new(encryptedExtensionsMsg)
+ case typeEndOfEarlyData:
+ m = new(endOfEarlyDataMsg)
+ case typeKeyUpdate:
+ m = new(keyUpdateMsg)
+ default:
+ return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+
+ // The handshake message unmarshalers
+ // expect to be able to keep references to data,
+ // so pass in a fresh copy that won't be overwritten.
+ data = append([]byte(nil), data...)
+
+ if !m.unmarshal(data) {
+ return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+
+ if transcript != nil {
+ transcript.Write(data)
+ }
+
+ return m, nil
+}
+
+var (
+ errShutdown = errors.New("tls: protocol is shutdown")
+)
+
+// Write writes data to the connection.
+//
+// As Write calls Handshake, in order to prevent indefinite blocking a deadline
+// must be set for both Read and Write before Write is called when the handshake
+// has not yet completed. See SetDeadline, SetReadDeadline, and
+// SetWriteDeadline.
+func (c *Conn) Write(b []byte) (int, error) {
+ // interlock with Close below
+ for {
+ x := c.activeCall.Load()
+ if x&1 != 0 {
+ return 0, net.ErrClosed
+ }
+ if c.activeCall.CompareAndSwap(x, x+2) {
+ break
+ }
+ }
+ defer c.activeCall.Add(-2)
+
+ if err := c.Handshake(); err != nil {
+ return 0, err
+ }
+
+ c.out.Lock()
+ defer c.out.Unlock()
+
+ if err := c.out.err; err != nil {
+ return 0, err
+ }
+
+ if !c.isHandshakeComplete.Load() {
+ return 0, alertInternalError
+ }
+
+ if c.closeNotifySent {
+ return 0, errShutdown
+ }
+
+ // TLS 1.0 is susceptible to a chosen-plaintext
+ // attack when using block mode ciphers due to predictable IVs.
+ // This can be prevented by splitting each Application Data
+ // record into two records, effectively randomizing the IV.
+ //
+ // https://www.openssl.org/~bodo/tls-cbc.txt
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=665814
+ // https://www.imperialviolet.org/2012/01/15/beastfollowup.html
+
+ var m int
+ if len(b) > 1 && c.vers == VersionTLS10 {
+ if _, ok := c.out.cipher.(cipher.BlockMode); ok {
+ n, err := c.writeRecordLocked(recordTypeApplicationData, b[:1])
+ if err != nil {
+ return n, c.out.setErrorLocked(err)
+ }
+ m, b = 1, b[1:]
+ }
+ }
+
+ n, err := c.writeRecordLocked(recordTypeApplicationData, b)
+ return n + m, c.out.setErrorLocked(err)
+}
+
+// handleRenegotiation processes a HelloRequest handshake message.
+func (c *Conn) handleRenegotiation() error {
+ if c.vers == VersionTLS13 {
+ return errors.New("tls: internal error: unexpected renegotiation")
+ }
+
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ helloReq, ok := msg.(*helloRequestMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(helloReq, msg)
+ }
+
+ if !c.isClient {
+ return c.sendAlert(alertNoRenegotiation)
+ }
+
+ switch c.config.Renegotiation {
+ case RenegotiateNever:
+ return c.sendAlert(alertNoRenegotiation)
+ case RenegotiateOnceAsClient:
+ if c.handshakes > 1 {
+ return c.sendAlert(alertNoRenegotiation)
+ }
+ case RenegotiateFreelyAsClient:
+ // Ok.
+ default:
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: unknown Renegotiation value")
+ }
+
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+
+ c.isHandshakeComplete.Store(false)
+ if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil {
+ c.handshakes++
+ }
+ return c.handshakeErr
+}
+
+// handlePostHandshakeMessage processes a handshake message arrived after the
+// handshake is complete. Up to TLS 1.2, it indicates the start of a renegotiation.
+func (c *Conn) handlePostHandshakeMessage() error {
+ if c.vers != VersionTLS13 {
+ return c.handleRenegotiation()
+ }
+
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+ c.retryCount++
+ if c.retryCount > maxUselessRecords {
+ c.sendAlert(alertUnexpectedMessage)
+ return c.in.setErrorLocked(errors.New("tls: too many non-advancing records"))
+ }
+
+ switch msg := msg.(type) {
+ case *newSessionTicketMsgTLS13:
+ return c.handleNewSessionTicket(msg)
+ case *keyUpdateMsg:
+ return c.handleKeyUpdate(msg)
+ }
+ // The QUIC layer is supposed to treat an unexpected post-handshake CertificateRequest
+ // as a QUIC-level PROTOCOL_VIOLATION error (RFC 9001, Section 4.4). Returning an
+ // unexpected_message alert here doesn't provide it with enough information to distinguish
+ // this condition from other unexpected messages. This is probably fine.
+ c.sendAlert(alertUnexpectedMessage)
+ return fmt.Errorf("tls: received unexpected handshake message of type %T", msg)
+}
+
+func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
+ if c.quic != nil {
+ c.sendAlert(alertUnexpectedMessage)
+ return c.in.setErrorLocked(errors.New("tls: received unexpected key update message"))
+ }
+
+ cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
+ if cipherSuite == nil {
+ return c.in.setErrorLocked(c.sendAlert(alertInternalError))
+ }
+
+ newSecret := cipherSuite.nextTrafficSecret(c.in.trafficSecret)
+ c.in.setTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret)
+
+ if keyUpdate.updateRequested {
+ c.out.Lock()
+ defer c.out.Unlock()
+
+ msg := &keyUpdateMsg{}
+ msgBytes, err := msg.marshal()
+ if err != nil {
+ return err
+ }
+ _, err = c.writeRecordLocked(recordTypeHandshake, msgBytes)
+ if err != nil {
+ // Surface the error at the next write.
+ c.out.setErrorLocked(err)
+ return nil
+ }
+
+ newSecret := cipherSuite.nextTrafficSecret(c.out.trafficSecret)
+ c.out.setTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret)
+ }
+
+ return nil
+}
+
+// Read reads data from the connection.
+//
+// As Read calls Handshake, in order to prevent indefinite blocking a deadline
+// must be set for both Read and Write before Read is called when the handshake
+// has not yet completed. See SetDeadline, SetReadDeadline, and
+// SetWriteDeadline.
+func (c *Conn) Read(b []byte) (int, error) {
+ if err := c.Handshake(); err != nil {
+ return 0, err
+ }
+ if len(b) == 0 {
+ // Put this after Handshake, in case people were calling
+ // Read(nil) for the side effect of the Handshake.
+ return 0, nil
+ }
+
+ c.in.Lock()
+ defer c.in.Unlock()
+
+ for c.input.Len() == 0 {
+ if err := c.readRecord(); err != nil {
+ return 0, err
+ }
+ for c.hand.Len() > 0 {
+ if err := c.handlePostHandshakeMessage(); err != nil {
+ return 0, err
+ }
+ }
+ }
+
+ n, _ := c.input.Read(b)
+
+ // If a close-notify alert is waiting, read it so that we can return (n,
+ // EOF) instead of (n, nil), to signal to the HTTP response reading
+ // goroutine that the connection is now closed. This eliminates a race
+ // where the HTTP response reading goroutine would otherwise not observe
+ // the EOF until its next read, by which time a client goroutine might
+ // have already tried to reuse the HTTP connection for a new request.
+ // See https://golang.org/cl/76400046 and https://golang.org/issue/3514
+ if n != 0 && c.input.Len() == 0 && c.rawInput.Len() > 0 &&
+ recordType(c.rawInput.Bytes()[0]) == recordTypeAlert {
+ if err := c.readRecord(); err != nil {
+ return n, err // will be io.EOF on closeNotify
+ }
+ }
+
+ return n, nil
+}
+
+// Close closes the connection.
+func (c *Conn) Close() error {
+ // Interlock with Conn.Write above.
+ var x int32
+ for {
+ x = c.activeCall.Load()
+ if x&1 != 0 {
+ return net.ErrClosed
+ }
+ if c.activeCall.CompareAndSwap(x, x|1) {
+ break
+ }
+ }
+ if x != 0 {
+ // io.Writer and io.Closer should not be used concurrently.
+ // If Close is called while a Write is currently in-flight,
+ // interpret that as a sign that this Close is really just
+ // being used to break the Write and/or clean up resources and
+ // avoid sending the alertCloseNotify, which may block
+ // waiting on handshakeMutex or the c.out mutex.
+ return c.conn.Close()
+ }
+
+ var alertErr error
+ if c.isHandshakeComplete.Load() {
+ if err := c.closeNotify(); err != nil {
+ alertErr = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", err)
+ }
+ }
+
+ if err := c.conn.Close(); err != nil {
+ return err
+ }
+ return alertErr
+}
+
+var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake complete")
+
+// CloseWrite shuts down the writing side of the connection. It should only be
+// called once the handshake has completed and does not call CloseWrite on the
+// underlying connection. Most callers should just use Close.
+func (c *Conn) CloseWrite() error {
+ if !c.isHandshakeComplete.Load() {
+ return errEarlyCloseWrite
+ }
+
+ return c.closeNotify()
+}
+
+func (c *Conn) closeNotify() error {
+ c.out.Lock()
+ defer c.out.Unlock()
+
+ if !c.closeNotifySent {
+ // Set a Write Deadline to prevent possibly blocking forever.
+ c.SetWriteDeadline(time.Now().Add(time.Second * 5))
+ c.closeNotifyErr = c.sendAlertLocked(alertCloseNotify)
+ c.closeNotifySent = true
+ // Any subsequent writes will fail.
+ c.SetWriteDeadline(time.Now())
+ }
+ return c.closeNotifyErr
+}
+
+// Handshake runs the client or server handshake
+// protocol if it has not yet been run.
+//
+// Most uses of this package need not call Handshake explicitly: the
+// first Read or Write will call it automatically.
+//
+// For control over canceling or setting a timeout on a handshake, use
+// HandshakeContext or the Dialer's DialContext method instead.
+//
+// In order to avoid denial of service attacks, the maximum RSA key size allowed
+// in certificates sent by either the TLS server or client is limited to 8192
+// bits. This limit can be overridden by setting tlsmaxrsasize in the GODEBUG
+// environment variable (e.g. GODEBUG=tlsmaxrsasize=4096).
+func (c *Conn) Handshake() error {
+ return c.HandshakeContext(context.Background())
+}
+
+// HandshakeContext runs the client or server handshake
+// protocol if it has not yet been run.
+//
+// The provided Context must be non-nil. If the context is canceled before
+// the handshake is complete, the handshake is interrupted and an error is returned.
+// Once the handshake has completed, cancellation of the context will not affect the
+// connection.
+//
+// Most uses of this package need not call HandshakeContext explicitly: the
+// first Read or Write will call it automatically.
+func (c *Conn) HandshakeContext(ctx context.Context) error {
+ // Delegate to unexported method for named return
+ // without confusing documented signature.
+ return c.handshakeContext(ctx)
+}
+
+func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
+ // Fast sync/atomic-based exit if there is no handshake in flight and the
+ // last one succeeded without an error. Avoids the expensive context setup
+ // and mutex for most Read and Write calls.
+ if c.isHandshakeComplete.Load() {
+ return nil
+ }
+
+ handshakeCtx, cancel := context.WithCancel(ctx)
+ // Note: defer this before starting the "interrupter" goroutine
+ // so that we can tell the difference between the input being canceled and
+ // this cancellation. In the former case, we need to close the connection.
+ defer cancel()
+
+ if c.quic != nil {
+ c.quic.cancelc = handshakeCtx.Done()
+ c.quic.cancel = cancel
+ } else if ctx.Done() != nil {
+ // Start the "interrupter" goroutine, if this context might be canceled.
+ // (The background context cannot).
+ //
+ // The interrupter goroutine waits for the input context to be done and
+ // closes the connection if this happens before the function returns.
+ done := make(chan struct{})
+ interruptRes := make(chan error, 1)
+ defer func() {
+ close(done)
+ if ctxErr := <-interruptRes; ctxErr != nil {
+ // Return context error to user.
+ ret = ctxErr
+ }
+ }()
+ go func() {
+ select {
+ case <-handshakeCtx.Done():
+ // Close the connection, discarding the error
+ _ = c.conn.Close()
+ interruptRes <- handshakeCtx.Err()
+ case <-done:
+ interruptRes <- nil
+ }
+ }()
+ }
+
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+
+ if err := c.handshakeErr; err != nil {
+ return err
+ }
+ if c.isHandshakeComplete.Load() {
+ return nil
+ }
+
+ c.in.Lock()
+ defer c.in.Unlock()
+
+ c.handshakeErr = c.handshakeFn(handshakeCtx)
+ if c.handshakeErr == nil {
+ c.handshakes++
+ } else {
+ // If an error occurred during the handshake try to flush the
+ // alert that might be left in the buffer.
+ c.flush()
+ }
+
+ if c.handshakeErr == nil && !c.isHandshakeComplete.Load() {
+ c.handshakeErr = errors.New("tls: internal error: handshake should have had a result")
+ }
+ if c.handshakeErr != nil && c.isHandshakeComplete.Load() {
+ panic("tls: internal error: handshake returned an error but is marked successful")
+ }
+
+ if c.quic != nil {
+ if c.handshakeErr == nil {
+ c.quicHandshakeComplete()
+ // Provide the 1-RTT read secret now that the handshake is complete.
+ // The QUIC layer MUST NOT decrypt 1-RTT packets prior to completing
+ // the handshake (RFC 9001, Section 5.7).
+ c.quicSetReadSecret(QUICEncryptionLevelApplication, c.cipherSuite, c.in.trafficSecret)
+ } else {
+ var a alert
+ c.out.Lock()
+ if !errors.As(c.out.err, &a) {
+ a = alertInternalError
+ }
+ c.out.Unlock()
+ // Return an error which wraps both the handshake error and
+ // any alert error we may have sent, or alertInternalError
+ // if we didn't send an alert.
+ // Truncate the text of the alert to 0 characters.
+ c.handshakeErr = fmt.Errorf("%w%.0w", c.handshakeErr, AlertError(a))
+ }
+ close(c.quic.blockedc)
+ close(c.quic.signalc)
+ }
+
+ return c.handshakeErr
+}
+
+// ConnectionState returns basic TLS details about the connection.
+func (c *Conn) ConnectionState() ConnectionState {
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+ return c.connectionStateLocked()
+}
+
+func (c *Conn) connectionStateLocked() ConnectionState {
+ var state ConnectionState
+ state.HandshakeComplete = c.isHandshakeComplete.Load()
+ state.Version = c.vers
+ state.NegotiatedProtocol = c.clientProtocol
+ state.DidResume = c.didResume
+ state.NegotiatedProtocolIsMutual = true
+ state.ServerName = c.serverName
+ state.CipherSuite = c.cipherSuite
+ state.PeerCertificates = c.peerCertificates
+ state.VerifiedChains = c.verifiedChains
+ state.SignedCertificateTimestamps = c.scts
+ state.OCSPResponse = c.ocspResponse
+ if (!c.didResume || c.extMasterSecret) && c.vers != VersionTLS13 {
+ if c.clientFinishedIsFirst {
+ state.TLSUnique = c.clientFinished[:]
+ } else {
+ state.TLSUnique = c.serverFinished[:]
+ }
+ }
+ if c.config.Renegotiation != RenegotiateNever {
+ state.ekm = noExportedKeyingMaterial
+ } else {
+ state.ekm = c.ekm
+ }
+ return state
+}
+
+// OCSPResponse returns the stapled OCSP response from the TLS server, if
+// any. (Only valid for client connections.)
+func (c *Conn) OCSPResponse() []byte {
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+
+ return c.ocspResponse
+}
+
+// VerifyHostname checks that the peer certificate chain is valid for
+// connecting to host. If so, it returns nil; if not, it returns an error
+// describing the problem.
+func (c *Conn) VerifyHostname(host string) error {
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+ if !c.isClient {
+ return errors.New("tls: VerifyHostname called on TLS server connection")
+ }
+ if !c.isHandshakeComplete.Load() {
+ return errors.New("tls: handshake has not yet been performed")
+ }
+ if len(c.verifiedChains) == 0 {
+ return errors.New("tls: handshake did not verify certificate chain")
+ }
+ return c.peerCertificates[0].VerifyHostname(host)
+}
diff --git a/contrib/go/_std_1.21/src/crypto/tls/handshake_client.go b/contrib/go/_std_1.21/src/crypto/tls/handshake_client.go
new file mode 100644
index 0000000000..4649f36dea
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/handshake_client.go
@@ -0,0 +1,1140 @@
+// Copyright 2009 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 tls
+
+import (
+ "bytes"
+ "context"
+ "crypto"
+ "crypto/ecdh"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "crypto/subtle"
+ "crypto/x509"
+ "errors"
+ "fmt"
+ "hash"
+ "internal/godebug"
+ "io"
+ "net"
+ "strconv"
+ "strings"
+ "time"
+)
+
+type clientHandshakeState struct {
+ c *Conn
+ ctx context.Context
+ serverHello *serverHelloMsg
+ hello *clientHelloMsg
+ suite *cipherSuite
+ finishedHash finishedHash
+ masterSecret []byte
+ session *SessionState // the session being resumed
+ ticket []byte // a fresh ticket received during this handshake
+}
+
+var testingOnlyForceClientHelloSignatureAlgorithms []SignatureScheme
+
+func (c *Conn) makeClientHello() (*clientHelloMsg, *ecdh.PrivateKey, error) {
+ config := c.config
+ if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
+ return nil, nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
+ }
+
+ nextProtosLength := 0
+ for _, proto := range config.NextProtos {
+ if l := len(proto); l == 0 || l > 255 {
+ return nil, nil, errors.New("tls: invalid NextProtos value")
+ } else {
+ nextProtosLength += 1 + l
+ }
+ }
+ if nextProtosLength > 0xffff {
+ return nil, nil, errors.New("tls: NextProtos values too large")
+ }
+
+ supportedVersions := config.supportedVersions(roleClient)
+ if len(supportedVersions) == 0 {
+ return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
+ }
+
+ clientHelloVersion := config.maxSupportedVersion(roleClient)
+ // The version at the beginning of the ClientHello was capped at TLS 1.2
+ // for compatibility reasons. The supported_versions extension is used
+ // to negotiate versions now. See RFC 8446, Section 4.2.1.
+ if clientHelloVersion > VersionTLS12 {
+ clientHelloVersion = VersionTLS12
+ }
+
+ hello := &clientHelloMsg{
+ vers: clientHelloVersion,
+ compressionMethods: []uint8{compressionNone},
+ random: make([]byte, 32),
+ extendedMasterSecret: true,
+ ocspStapling: true,
+ scts: true,
+ serverName: hostnameInSNI(config.ServerName),
+ supportedCurves: config.curvePreferences(),
+ supportedPoints: []uint8{pointFormatUncompressed},
+ secureRenegotiationSupported: true,
+ alpnProtocols: config.NextProtos,
+ supportedVersions: supportedVersions,
+ }
+
+ if c.handshakes > 0 {
+ hello.secureRenegotiation = c.clientFinished[:]
+ }
+
+ preferenceOrder := cipherSuitesPreferenceOrder
+ if !hasAESGCMHardwareSupport {
+ preferenceOrder = cipherSuitesPreferenceOrderNoAES
+ }
+ configCipherSuites := config.cipherSuites()
+ hello.cipherSuites = make([]uint16, 0, len(configCipherSuites))
+
+ for _, suiteId := range preferenceOrder {
+ suite := mutualCipherSuite(configCipherSuites, suiteId)
+ if suite == nil {
+ continue
+ }
+ // Don't advertise TLS 1.2-only cipher suites unless
+ // we're attempting TLS 1.2.
+ if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
+ continue
+ }
+ hello.cipherSuites = append(hello.cipherSuites, suiteId)
+ }
+
+ _, err := io.ReadFull(config.rand(), hello.random)
+ if err != nil {
+ return nil, nil, errors.New("tls: short read from Rand: " + err.Error())
+ }
+
+ // A random session ID is used to detect when the server accepted a ticket
+ // and is resuming a session (see RFC 5077). In TLS 1.3, it's always set as
+ // a compatibility measure (see RFC 8446, Section 4.1.2).
+ //
+ // The session ID is not set for QUIC connections (see RFC 9001, Section 8.4).
+ if c.quic == nil {
+ hello.sessionId = make([]byte, 32)
+ if _, err := io.ReadFull(config.rand(), hello.sessionId); err != nil {
+ return nil, nil, errors.New("tls: short read from Rand: " + err.Error())
+ }
+ }
+
+ if hello.vers >= VersionTLS12 {
+ hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+ }
+ if testingOnlyForceClientHelloSignatureAlgorithms != nil {
+ hello.supportedSignatureAlgorithms = testingOnlyForceClientHelloSignatureAlgorithms
+ }
+
+ var key *ecdh.PrivateKey
+ if hello.supportedVersions[0] == VersionTLS13 {
+ // Reset the list of ciphers when the client only supports TLS 1.3.
+ if len(hello.supportedVersions) == 1 {
+ hello.cipherSuites = nil
+ }
+ if hasAESGCMHardwareSupport {
+ hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
+ } else {
+ hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...)
+ }
+
+ curveID := config.curvePreferences()[0]
+ if _, ok := curveForCurveID(curveID); !ok {
+ return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve")
+ }
+ key, err = generateECDHEKey(config.rand(), curveID)
+ if err != nil {
+ return nil, nil, err
+ }
+ hello.keyShares = []keyShare{{group: curveID, data: key.PublicKey().Bytes()}}
+ }
+
+ if c.quic != nil {
+ p, err := c.quicGetTransportParameters()
+ if err != nil {
+ return nil, nil, err
+ }
+ if p == nil {
+ p = []byte{}
+ }
+ hello.quicTransportParameters = p
+ }
+
+ return hello, key, nil
+}
+
+func (c *Conn) clientHandshake(ctx context.Context) (err error) {
+ if c.config == nil {
+ c.config = defaultConfig()
+ }
+
+ // This may be a renegotiation handshake, in which case some fields
+ // need to be reset.
+ c.didResume = false
+
+ hello, ecdheKey, err := c.makeClientHello()
+ if err != nil {
+ return err
+ }
+ c.serverName = hello.serverName
+
+ session, earlySecret, binderKey, err := c.loadSession(hello)
+ if err != nil {
+ return err
+ }
+ if session != nil {
+ defer func() {
+ // If we got a handshake failure when resuming a session, throw away
+ // the session ticket. See RFC 5077, Section 3.2.
+ //
+ // RFC 8446 makes no mention of dropping tickets on failure, but it
+ // does require servers to abort on invalid binders, so we need to
+ // delete tickets to recover from a corrupted PSK.
+ if err != nil {
+ if cacheKey := c.clientSessionCacheKey(); cacheKey != "" {
+ c.config.ClientSessionCache.Put(cacheKey, nil)
+ }
+ }
+ }()
+ }
+
+ if _, err := c.writeHandshakeRecord(hello, nil); err != nil {
+ return err
+ }
+
+ if hello.earlyData {
+ suite := cipherSuiteTLS13ByID(session.cipherSuite)
+ transcript := suite.hash.New()
+ if err := transcriptMsg(hello, transcript); err != nil {
+ return err
+ }
+ earlyTrafficSecret := suite.deriveSecret(earlySecret, clientEarlyTrafficLabel, transcript)
+ c.quicSetWriteSecret(QUICEncryptionLevelEarly, suite.id, earlyTrafficSecret)
+ }
+
+ // serverHelloMsg is not included in the transcript
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ serverHello, ok := msg.(*serverHelloMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(serverHello, msg)
+ }
+
+ if err := c.pickTLSVersion(serverHello); err != nil {
+ return err
+ }
+
+ // If we are negotiating a protocol version that's lower than what we
+ // support, check for the server downgrade canaries.
+ // See RFC 8446, Section 4.1.3.
+ maxVers := c.config.maxSupportedVersion(roleClient)
+ tls12Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS12
+ tls11Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS11
+ if maxVers == VersionTLS13 && c.vers <= VersionTLS12 && (tls12Downgrade || tls11Downgrade) ||
+ maxVers == VersionTLS12 && c.vers <= VersionTLS11 && tls11Downgrade {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: downgrade attempt detected, possibly due to a MitM attack or a broken middlebox")
+ }
+
+ if c.vers == VersionTLS13 {
+ hs := &clientHandshakeStateTLS13{
+ c: c,
+ ctx: ctx,
+ serverHello: serverHello,
+ hello: hello,
+ ecdheKey: ecdheKey,
+ session: session,
+ earlySecret: earlySecret,
+ binderKey: binderKey,
+ }
+
+ // In TLS 1.3, session tickets are delivered after the handshake.
+ return hs.handshake()
+ }
+
+ hs := &clientHandshakeState{
+ c: c,
+ ctx: ctx,
+ serverHello: serverHello,
+ hello: hello,
+ session: session,
+ }
+
+ if err := hs.handshake(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (c *Conn) loadSession(hello *clientHelloMsg) (
+ session *SessionState, earlySecret, binderKey []byte, err error) {
+ if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil {
+ return nil, nil, nil, nil
+ }
+
+ hello.ticketSupported = true
+
+ if hello.supportedVersions[0] == VersionTLS13 {
+ // Require DHE on resumption as it guarantees forward secrecy against
+ // compromise of the session ticket key. See RFC 8446, Section 4.2.9.
+ hello.pskModes = []uint8{pskModeDHE}
+ }
+
+ // Session resumption is not allowed if renegotiating because
+ // renegotiation is primarily used to allow a client to send a client
+ // certificate, which would be skipped if session resumption occurred.
+ if c.handshakes != 0 {
+ return nil, nil, nil, nil
+ }
+
+ // Try to resume a previously negotiated TLS session, if available.
+ cacheKey := c.clientSessionCacheKey()
+ if cacheKey == "" {
+ return nil, nil, nil, nil
+ }
+ cs, ok := c.config.ClientSessionCache.Get(cacheKey)
+ if !ok || cs == nil {
+ return nil, nil, nil, nil
+ }
+ session = cs.session
+
+ // Check that version used for the previous session is still valid.
+ versOk := false
+ for _, v := range hello.supportedVersions {
+ if v == session.version {
+ versOk = true
+ break
+ }
+ }
+ if !versOk {
+ return nil, nil, nil, nil
+ }
+
+ // Check that the cached server certificate is not expired, and that it's
+ // valid for the ServerName. This should be ensured by the cache key, but
+ // protect the application from a faulty ClientSessionCache implementation.
+ if c.config.time().After(session.peerCertificates[0].NotAfter) {
+ // Expired certificate, delete the entry.
+ c.config.ClientSessionCache.Put(cacheKey, nil)
+ return nil, nil, nil, nil
+ }
+ if !c.config.InsecureSkipVerify {
+ if len(session.verifiedChains) == 0 {
+ // The original connection had InsecureSkipVerify, while this doesn't.
+ return nil, nil, nil, nil
+ }
+ if err := session.peerCertificates[0].VerifyHostname(c.config.ServerName); err != nil {
+ return nil, nil, nil, nil
+ }
+ }
+
+ if session.version != VersionTLS13 {
+ // In TLS 1.2 the cipher suite must match the resumed session. Ensure we
+ // are still offering it.
+ if mutualCipherSuite(hello.cipherSuites, session.cipherSuite) == nil {
+ return nil, nil, nil, nil
+ }
+
+ hello.sessionTicket = cs.ticket
+ return
+ }
+
+ // Check that the session ticket is not expired.
+ if c.config.time().After(time.Unix(int64(session.useBy), 0)) {
+ c.config.ClientSessionCache.Put(cacheKey, nil)
+ return nil, nil, nil, nil
+ }
+
+ // In TLS 1.3 the KDF hash must match the resumed session. Ensure we
+ // offer at least one cipher suite with that hash.
+ cipherSuite := cipherSuiteTLS13ByID(session.cipherSuite)
+ if cipherSuite == nil {
+ return nil, nil, nil, nil
+ }
+ cipherSuiteOk := false
+ for _, offeredID := range hello.cipherSuites {
+ offeredSuite := cipherSuiteTLS13ByID(offeredID)
+ if offeredSuite != nil && offeredSuite.hash == cipherSuite.hash {
+ cipherSuiteOk = true
+ break
+ }
+ }
+ if !cipherSuiteOk {
+ return nil, nil, nil, nil
+ }
+
+ if c.quic != nil && session.EarlyData {
+ // For 0-RTT, the cipher suite has to match exactly, and we need to be
+ // offering the same ALPN.
+ if mutualCipherSuiteTLS13(hello.cipherSuites, session.cipherSuite) != nil {
+ for _, alpn := range hello.alpnProtocols {
+ if alpn == session.alpnProtocol {
+ hello.earlyData = true
+ break
+ }
+ }
+ }
+ }
+
+ // Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1.
+ ticketAge := c.config.time().Sub(time.Unix(int64(session.createdAt), 0))
+ identity := pskIdentity{
+ label: cs.ticket,
+ obfuscatedTicketAge: uint32(ticketAge/time.Millisecond) + session.ageAdd,
+ }
+ hello.pskIdentities = []pskIdentity{identity}
+ hello.pskBinders = [][]byte{make([]byte, cipherSuite.hash.Size())}
+
+ // Compute the PSK binders. See RFC 8446, Section 4.2.11.2.
+ earlySecret = cipherSuite.extract(session.secret, nil)
+ binderKey = cipherSuite.deriveSecret(earlySecret, resumptionBinderLabel, nil)
+ transcript := cipherSuite.hash.New()
+ helloBytes, err := hello.marshalWithoutBinders()
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ transcript.Write(helloBytes)
+ pskBinders := [][]byte{cipherSuite.finishedHash(binderKey, transcript)}
+ if err := hello.updateBinders(pskBinders); err != nil {
+ return nil, nil, nil, err
+ }
+
+ return
+}
+
+func (c *Conn) pickTLSVersion(serverHello *serverHelloMsg) error {
+ peerVersion := serverHello.vers
+ if serverHello.supportedVersion != 0 {
+ peerVersion = serverHello.supportedVersion
+ }
+
+ vers, ok := c.config.mutualVersion(roleClient, []uint16{peerVersion})
+ if !ok {
+ c.sendAlert(alertProtocolVersion)
+ return fmt.Errorf("tls: server selected unsupported protocol version %x", peerVersion)
+ }
+
+ c.vers = vers
+ c.haveVers = true
+ c.in.version = vers
+ c.out.version = vers
+
+ return nil
+}
+
+// Does the handshake, either a full one or resumes old session. Requires hs.c,
+// hs.hello, hs.serverHello, and, optionally, hs.session to be set.
+func (hs *clientHandshakeState) handshake() error {
+ c := hs.c
+
+ isResume, err := hs.processServerHello()
+ if err != nil {
+ return err
+ }
+
+ hs.finishedHash = newFinishedHash(c.vers, hs.suite)
+
+ // No signatures of the handshake are needed in a resumption.
+ // Otherwise, in a full handshake, if we don't have any certificates
+ // configured then we will never send a CertificateVerify message and
+ // thus no signatures are needed in that case either.
+ if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) {
+ hs.finishedHash.discardHandshakeBuffer()
+ }
+
+ if err := transcriptMsg(hs.hello, &hs.finishedHash); err != nil {
+ return err
+ }
+ if err := transcriptMsg(hs.serverHello, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ c.buffering = true
+ c.didResume = isResume
+ if isResume {
+ if err := hs.establishKeys(); err != nil {
+ return err
+ }
+ if err := hs.readSessionTicket(); err != nil {
+ return err
+ }
+ if err := hs.readFinished(c.serverFinished[:]); err != nil {
+ return err
+ }
+ c.clientFinishedIsFirst = false
+ // Make sure the connection is still being verified whether or not this
+ // is a resumption. Resumptions currently don't reverify certificates so
+ // they don't call verifyServerCertificate. See Issue 31641.
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+ if err := hs.sendFinished(c.clientFinished[:]); err != nil {
+ return err
+ }
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+ } else {
+ if err := hs.doFullHandshake(); err != nil {
+ return err
+ }
+ if err := hs.establishKeys(); err != nil {
+ return err
+ }
+ if err := hs.sendFinished(c.clientFinished[:]); err != nil {
+ return err
+ }
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+ c.clientFinishedIsFirst = true
+ if err := hs.readSessionTicket(); err != nil {
+ return err
+ }
+ if err := hs.readFinished(c.serverFinished[:]); err != nil {
+ return err
+ }
+ }
+ if err := hs.saveSessionTicket(); err != nil {
+ return err
+ }
+
+ c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)
+ c.isHandshakeComplete.Store(true)
+
+ return nil
+}
+
+func (hs *clientHandshakeState) pickCipherSuite() error {
+ if hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil {
+ hs.c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: server chose an unconfigured cipher suite")
+ }
+
+ hs.c.cipherSuite = hs.suite.id
+ return nil
+}
+
+func (hs *clientHandshakeState) doFullHandshake() error {
+ c := hs.c
+
+ msg, err := c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+ certMsg, ok := msg.(*certificateMsg)
+ if !ok || len(certMsg.certificates) == 0 {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certMsg, msg)
+ }
+
+ msg, err = c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+
+ cs, ok := msg.(*certificateStatusMsg)
+ if ok {
+ // RFC4366 on Certificate Status Request:
+ // The server MAY return a "certificate_status" message.
+
+ if !hs.serverHello.ocspStapling {
+ // If a server returns a "CertificateStatus" message, then the
+ // server MUST have included an extension of type "status_request"
+ // with empty "extension_data" in the extended server hello.
+
+ c.sendAlert(alertUnexpectedMessage)
+ return errors.New("tls: received unexpected CertificateStatus message")
+ }
+
+ c.ocspResponse = cs.response
+
+ msg, err = c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+ }
+
+ if c.handshakes == 0 {
+ // If this is the first handshake on a connection, process and
+ // (optionally) verify the server's certificates.
+ if err := c.verifyServerCertificate(certMsg.certificates); err != nil {
+ return err
+ }
+ } else {
+ // This is a renegotiation handshake. We require that the
+ // server's identity (i.e. leaf certificate) is unchanged and
+ // thus any previous trust decision is still valid.
+ //
+ // See https://mitls.org/pages/attacks/3SHAKE for the
+ // motivation behind this requirement.
+ if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
+ c.sendAlert(alertBadCertificate)
+ return errors.New("tls: server's identity changed during renegotiation")
+ }
+ }
+
+ keyAgreement := hs.suite.ka(c.vers)
+
+ skx, ok := msg.(*serverKeyExchangeMsg)
+ if ok {
+ err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)
+ if err != nil {
+ c.sendAlert(alertUnexpectedMessage)
+ return err
+ }
+
+ msg, err = c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+ }
+
+ var chainToSend *Certificate
+ var certRequested bool
+ certReq, ok := msg.(*certificateRequestMsg)
+ if ok {
+ certRequested = true
+
+ cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq)
+ if chainToSend, err = c.getClientCertificate(cri); err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ msg, err = c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+ }
+
+ shd, ok := msg.(*serverHelloDoneMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(shd, msg)
+ }
+
+ // If the server requested a certificate then we have to send a
+ // Certificate message, even if it's empty because we don't have a
+ // certificate to send.
+ if certRequested {
+ certMsg = new(certificateMsg)
+ certMsg.certificates = chainToSend.Certificate
+ if _, err := hs.c.writeHandshakeRecord(certMsg, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0])
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ if ckx != nil {
+ if _, err := hs.c.writeHandshakeRecord(ckx, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ if hs.serverHello.extendedMasterSecret {
+ c.extMasterSecret = true
+ hs.masterSecret = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret,
+ hs.finishedHash.Sum())
+ } else {
+ hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret,
+ hs.hello.random, hs.serverHello.random)
+ }
+ if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil {
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: failed to write to key log: " + err.Error())
+ }
+
+ if chainToSend != nil && len(chainToSend.Certificate) > 0 {
+ certVerify := &certificateVerifyMsg{}
+
+ key, ok := chainToSend.PrivateKey.(crypto.Signer)
+ if !ok {
+ c.sendAlert(alertInternalError)
+ return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
+ }
+
+ var sigType uint8
+ var sigHash crypto.Hash
+ if c.vers >= VersionTLS12 {
+ signatureAlgorithm, err := selectSignatureScheme(c.vers, chainToSend, certReq.supportedSignatureAlgorithms)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return err
+ }
+ sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)
+ if err != nil {
+ return c.sendAlert(alertInternalError)
+ }
+ certVerify.hasSignatureAlgorithm = true
+ certVerify.signatureAlgorithm = signatureAlgorithm
+ } else {
+ sigType, sigHash, err = legacyTypeAndHashFromPublicKey(key.Public())
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return err
+ }
+ }
+
+ signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash)
+ signOpts := crypto.SignerOpts(sigHash)
+ if sigType == signatureRSAPSS {
+ signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
+ }
+ certVerify.signature, err = key.Sign(c.config.rand(), signed, signOpts)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(certVerify, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ hs.finishedHash.discardHandshakeBuffer()
+
+ return nil
+}
+
+func (hs *clientHandshakeState) establishKeys() error {
+ c := hs.c
+
+ clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
+ keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
+ var clientCipher, serverCipher any
+ var clientHash, serverHash hash.Hash
+ if hs.suite.cipher != nil {
+ clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
+ clientHash = hs.suite.mac(clientMAC)
+ serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
+ serverHash = hs.suite.mac(serverMAC)
+ } else {
+ clientCipher = hs.suite.aead(clientKey, clientIV)
+ serverCipher = hs.suite.aead(serverKey, serverIV)
+ }
+
+ c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
+ c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
+ return nil
+}
+
+func (hs *clientHandshakeState) serverResumedSession() bool {
+ // If the server responded with the same sessionId then it means the
+ // sessionTicket is being used to resume a TLS session.
+ return hs.session != nil && hs.hello.sessionId != nil &&
+ bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
+}
+
+func (hs *clientHandshakeState) processServerHello() (bool, error) {
+ c := hs.c
+
+ if err := hs.pickCipherSuite(); err != nil {
+ return false, err
+ }
+
+ if hs.serverHello.compressionMethod != compressionNone {
+ c.sendAlert(alertUnexpectedMessage)
+ return false, errors.New("tls: server selected unsupported compression format")
+ }
+
+ if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
+ c.secureRenegotiation = true
+ if len(hs.serverHello.secureRenegotiation) != 0 {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
+ }
+ }
+
+ if c.handshakes > 0 && c.secureRenegotiation {
+ var expectedSecureRenegotiation [24]byte
+ copy(expectedSecureRenegotiation[:], c.clientFinished[:])
+ copy(expectedSecureRenegotiation[12:], c.serverFinished[:])
+ if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: incorrect renegotiation extension contents")
+ }
+ }
+
+ if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol, false); err != nil {
+ c.sendAlert(alertUnsupportedExtension)
+ return false, err
+ }
+ c.clientProtocol = hs.serverHello.alpnProtocol
+
+ c.scts = hs.serverHello.scts
+
+ if !hs.serverResumedSession() {
+ return false, nil
+ }
+
+ if hs.session.version != c.vers {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: server resumed a session with a different version")
+ }
+
+ if hs.session.cipherSuite != hs.suite.id {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: server resumed a session with a different cipher suite")
+ }
+
+ // RFC 7627, Section 5.3
+ if hs.session.extMasterSecret != hs.serverHello.extendedMasterSecret {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: server resumed a session with a different EMS extension")
+ }
+
+ // Restore master secret and certificates from previous state
+ hs.masterSecret = hs.session.secret
+ c.extMasterSecret = hs.session.extMasterSecret
+ c.peerCertificates = hs.session.peerCertificates
+ c.activeCertHandles = hs.c.activeCertHandles
+ c.verifiedChains = hs.session.verifiedChains
+ c.ocspResponse = hs.session.ocspResponse
+ // Let the ServerHello SCTs override the session SCTs from the original
+ // connection, if any are provided
+ if len(c.scts) == 0 && len(hs.session.scts) != 0 {
+ c.scts = hs.session.scts
+ }
+
+ return true, nil
+}
+
+// checkALPN ensure that the server's choice of ALPN protocol is compatible with
+// the protocols that we advertised in the Client Hello.
+func checkALPN(clientProtos []string, serverProto string, quic bool) error {
+ if serverProto == "" {
+ if quic && len(clientProtos) > 0 {
+ // RFC 9001, Section 8.1
+ return errors.New("tls: server did not select an ALPN protocol")
+ }
+ return nil
+ }
+ if len(clientProtos) == 0 {
+ return errors.New("tls: server advertised unrequested ALPN extension")
+ }
+ for _, proto := range clientProtos {
+ if proto == serverProto {
+ return nil
+ }
+ }
+ return errors.New("tls: server selected unadvertised ALPN protocol")
+}
+
+func (hs *clientHandshakeState) readFinished(out []byte) error {
+ c := hs.c
+
+ if err := c.readChangeCipherSpec(); err != nil {
+ return err
+ }
+
+ // finishedMsg is included in the transcript, but not until after we
+ // check the client version, since the state before this message was
+ // sent is used during verification.
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+ serverFinished, ok := msg.(*finishedMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(serverFinished, msg)
+ }
+
+ verify := hs.finishedHash.serverSum(hs.masterSecret)
+ if len(verify) != len(serverFinished.verifyData) ||
+ subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: server's Finished message was incorrect")
+ }
+
+ if err := transcriptMsg(serverFinished, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ copy(out, verify)
+ return nil
+}
+
+func (hs *clientHandshakeState) readSessionTicket() error {
+ if !hs.serverHello.ticketSupported {
+ return nil
+ }
+ c := hs.c
+
+ if !hs.hello.ticketSupported {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server sent unrequested session ticket")
+ }
+
+ msg, err := c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+ sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(sessionTicketMsg, msg)
+ }
+
+ hs.ticket = sessionTicketMsg.ticket
+ return nil
+}
+
+func (hs *clientHandshakeState) saveSessionTicket() error {
+ if hs.ticket == nil {
+ return nil
+ }
+ c := hs.c
+
+ cacheKey := c.clientSessionCacheKey()
+ if cacheKey == "" {
+ return nil
+ }
+
+ session, err := c.sessionState()
+ if err != nil {
+ return err
+ }
+ session.secret = hs.masterSecret
+
+ cs := &ClientSessionState{ticket: hs.ticket, session: session}
+ c.config.ClientSessionCache.Put(cacheKey, cs)
+ return nil
+}
+
+func (hs *clientHandshakeState) sendFinished(out []byte) error {
+ c := hs.c
+
+ if err := c.writeChangeCipherRecord(); err != nil {
+ return err
+ }
+
+ finished := new(finishedMsg)
+ finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
+ if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil {
+ return err
+ }
+ copy(out, finished.verifyData)
+ return nil
+}
+
+// defaultMaxRSAKeySize is the maximum RSA key size in bits that we are willing
+// to verify the signatures of during a TLS handshake.
+const defaultMaxRSAKeySize = 8192
+
+var tlsmaxrsasize = godebug.New("tlsmaxrsasize")
+
+func checkKeySize(n int) (max int, ok bool) {
+ if v := tlsmaxrsasize.Value(); v != "" {
+ if max, err := strconv.Atoi(v); err == nil {
+ if (n <= max) != (n <= defaultMaxRSAKeySize) {
+ tlsmaxrsasize.IncNonDefault()
+ }
+ return max, n <= max
+ }
+ }
+ return defaultMaxRSAKeySize, n <= defaultMaxRSAKeySize
+}
+
+// verifyServerCertificate parses and verifies the provided chain, setting
+// c.verifiedChains and c.peerCertificates or sending the appropriate alert.
+func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
+ activeHandles := make([]*activeCert, len(certificates))
+ certs := make([]*x509.Certificate, len(certificates))
+ for i, asn1Data := range certificates {
+ cert, err := globalCertCache.newCert(asn1Data)
+ if err != nil {
+ c.sendAlert(alertBadCertificate)
+ return errors.New("tls: failed to parse certificate from server: " + err.Error())
+ }
+ if cert.cert.PublicKeyAlgorithm == x509.RSA {
+ n := cert.cert.PublicKey.(*rsa.PublicKey).N.BitLen()
+ if max, ok := checkKeySize(n); !ok {
+ c.sendAlert(alertBadCertificate)
+ return fmt.Errorf("tls: server sent certificate containing RSA key larger than %d bits", max)
+ }
+ }
+ activeHandles[i] = cert
+ certs[i] = cert.cert
+ }
+
+ if !c.config.InsecureSkipVerify {
+ opts := x509.VerifyOptions{
+ Roots: c.config.RootCAs,
+ CurrentTime: c.config.time(),
+ DNSName: c.config.ServerName,
+ Intermediates: x509.NewCertPool(),
+ }
+
+ for _, cert := range certs[1:] {
+ opts.Intermediates.AddCert(cert)
+ }
+ var err error
+ c.verifiedChains, err = certs[0].Verify(opts)
+ if err != nil {
+ c.sendAlert(alertBadCertificate)
+ return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
+ }
+ }
+
+ switch certs[0].PublicKey.(type) {
+ case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
+ break
+ default:
+ c.sendAlert(alertUnsupportedCertificate)
+ return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
+ }
+
+ c.activeCertHandles = activeHandles
+ c.peerCertificates = certs
+
+ if c.config.VerifyPeerCertificate != nil {
+ if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+
+ return nil
+}
+
+// certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS
+// <= 1.2 CertificateRequest, making an effort to fill in missing information.
+func certificateRequestInfoFromMsg(ctx context.Context, vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
+ cri := &CertificateRequestInfo{
+ AcceptableCAs: certReq.certificateAuthorities,
+ Version: vers,
+ ctx: ctx,
+ }
+
+ var rsaAvail, ecAvail bool
+ for _, certType := range certReq.certificateTypes {
+ switch certType {
+ case certTypeRSASign:
+ rsaAvail = true
+ case certTypeECDSASign:
+ ecAvail = true
+ }
+ }
+
+ if !certReq.hasSignatureAlgorithm {
+ // Prior to TLS 1.2, signature schemes did not exist. In this case we
+ // make up a list based on the acceptable certificate types, to help
+ // GetClientCertificate and SupportsCertificate select the right certificate.
+ // The hash part of the SignatureScheme is a lie here, because
+ // TLS 1.0 and 1.1 always use MD5+SHA1 for RSA and SHA1 for ECDSA.
+ switch {
+ case rsaAvail && ecAvail:
+ cri.SignatureSchemes = []SignatureScheme{
+ ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512,
+ PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1,
+ }
+ case rsaAvail:
+ cri.SignatureSchemes = []SignatureScheme{
+ PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1,
+ }
+ case ecAvail:
+ cri.SignatureSchemes = []SignatureScheme{
+ ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512,
+ }
+ }
+ return cri
+ }
+
+ // Filter the signature schemes based on the certificate types.
+ // See RFC 5246, Section 7.4.4 (where it calls this "somewhat complicated").
+ cri.SignatureSchemes = make([]SignatureScheme, 0, len(certReq.supportedSignatureAlgorithms))
+ for _, sigScheme := range certReq.supportedSignatureAlgorithms {
+ sigType, _, err := typeAndHashFromSignatureScheme(sigScheme)
+ if err != nil {
+ continue
+ }
+ switch sigType {
+ case signatureECDSA, signatureEd25519:
+ if ecAvail {
+ cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme)
+ }
+ case signatureRSAPSS, signaturePKCS1v15:
+ if rsaAvail {
+ cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme)
+ }
+ }
+ }
+
+ return cri
+}
+
+func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate, error) {
+ if c.config.GetClientCertificate != nil {
+ return c.config.GetClientCertificate(cri)
+ }
+
+ for _, chain := range c.config.Certificates {
+ if err := cri.SupportsCertificate(&chain); err != nil {
+ continue
+ }
+ return &chain, nil
+ }
+
+ // No acceptable certificate found. Don't send a certificate.
+ return new(Certificate), nil
+}
+
+// clientSessionCacheKey returns a key used to cache sessionTickets that could
+// be used to resume previously negotiated TLS sessions with a server.
+func (c *Conn) clientSessionCacheKey() string {
+ if len(c.config.ServerName) > 0 {
+ return c.config.ServerName
+ }
+ if c.conn != nil {
+ return c.conn.RemoteAddr().String()
+ }
+ return ""
+}
+
+// hostnameInSNI converts name into an appropriate hostname for SNI.
+// Literal IP addresses and absolute FQDNs are not permitted as SNI values.
+// See RFC 6066, Section 3.
+func hostnameInSNI(name string) string {
+ host := name
+ if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
+ host = host[1 : len(host)-1]
+ }
+ if i := strings.LastIndex(host, "%"); i > 0 {
+ host = host[:i]
+ }
+ if net.ParseIP(host) != nil {
+ return ""
+ }
+ for len(name) > 0 && name[len(name)-1] == '.' {
+ name = name[:len(name)-1]
+ }
+ return name
+}
diff --git a/contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go b/contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go
new file mode 100644
index 0000000000..2f59f6888c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/handshake_client_tls13.go
@@ -0,0 +1,772 @@
+// Copyright 2018 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 tls
+
+import (
+ "bytes"
+ "context"
+ "crypto"
+ "crypto/ecdh"
+ "crypto/hmac"
+ "crypto/rsa"
+ "errors"
+ "hash"
+ "time"
+)
+
+type clientHandshakeStateTLS13 struct {
+ c *Conn
+ ctx context.Context
+ serverHello *serverHelloMsg
+ hello *clientHelloMsg
+ ecdheKey *ecdh.PrivateKey
+
+ session *SessionState
+ earlySecret []byte
+ binderKey []byte
+
+ certReq *certificateRequestMsgTLS13
+ usingPSK bool
+ sentDummyCCS bool
+ suite *cipherSuiteTLS13
+ transcript hash.Hash
+ masterSecret []byte
+ trafficSecret []byte // client_application_traffic_secret_0
+}
+
+// handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheKey, and,
+// optionally, hs.session, hs.earlySecret and hs.binderKey to be set.
+func (hs *clientHandshakeStateTLS13) handshake() error {
+ c := hs.c
+
+ if needFIPS() {
+ return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
+ }
+
+ // The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
+ // sections 4.1.2 and 4.1.3.
+ if c.handshakes > 0 {
+ c.sendAlert(alertProtocolVersion)
+ return errors.New("tls: server selected TLS 1.3 in a renegotiation")
+ }
+
+ // Consistency check on the presence of a keyShare and its parameters.
+ if hs.ecdheKey == nil || len(hs.hello.keyShares) != 1 {
+ return c.sendAlert(alertInternalError)
+ }
+
+ if err := hs.checkServerHelloOrHRR(); err != nil {
+ return err
+ }
+
+ hs.transcript = hs.suite.hash.New()
+
+ if err := transcriptMsg(hs.hello, hs.transcript); err != nil {
+ return err
+ }
+
+ if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
+ if err := hs.sendDummyChangeCipherSpec(); err != nil {
+ return err
+ }
+ if err := hs.processHelloRetryRequest(); err != nil {
+ return err
+ }
+ }
+
+ if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
+ return err
+ }
+
+ c.buffering = true
+ if err := hs.processServerHello(); err != nil {
+ return err
+ }
+ if err := hs.sendDummyChangeCipherSpec(); err != nil {
+ return err
+ }
+ if err := hs.establishHandshakeKeys(); err != nil {
+ return err
+ }
+ if err := hs.readServerParameters(); err != nil {
+ return err
+ }
+ if err := hs.readServerCertificate(); err != nil {
+ return err
+ }
+ if err := hs.readServerFinished(); err != nil {
+ return err
+ }
+ if err := hs.sendClientCertificate(); err != nil {
+ return err
+ }
+ if err := hs.sendClientFinished(); err != nil {
+ return err
+ }
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+
+ c.isHandshakeComplete.Store(true)
+
+ return nil
+}
+
+// checkServerHelloOrHRR does validity checks that apply to both ServerHello and
+// HelloRetryRequest messages. It sets hs.suite.
+func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error {
+ c := hs.c
+
+ if hs.serverHello.supportedVersion == 0 {
+ c.sendAlert(alertMissingExtension)
+ return errors.New("tls: server selected TLS 1.3 using the legacy version field")
+ }
+
+ if hs.serverHello.supportedVersion != VersionTLS13 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server selected an invalid version after a HelloRetryRequest")
+ }
+
+ if hs.serverHello.vers != VersionTLS12 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server sent an incorrect legacy version")
+ }
+
+ if hs.serverHello.ocspStapling ||
+ hs.serverHello.ticketSupported ||
+ hs.serverHello.extendedMasterSecret ||
+ hs.serverHello.secureRenegotiationSupported ||
+ len(hs.serverHello.secureRenegotiation) != 0 ||
+ len(hs.serverHello.alpnProtocol) != 0 ||
+ len(hs.serverHello.scts) != 0 {
+ c.sendAlert(alertUnsupportedExtension)
+ return errors.New("tls: server sent a ServerHello extension forbidden in TLS 1.3")
+ }
+
+ if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server did not echo the legacy session ID")
+ }
+
+ if hs.serverHello.compressionMethod != compressionNone {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server selected unsupported compression format")
+ }
+
+ selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite)
+ if hs.suite != nil && selectedSuite != hs.suite {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server changed cipher suite after a HelloRetryRequest")
+ }
+ if selectedSuite == nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server chose an unconfigured cipher suite")
+ }
+ hs.suite = selectedSuite
+ c.cipherSuite = hs.suite.id
+
+ return nil
+}
+
+// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
+// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
+func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
+ if hs.c.quic != nil {
+ return nil
+ }
+ if hs.sentDummyCCS {
+ return nil
+ }
+ hs.sentDummyCCS = true
+
+ return hs.c.writeChangeCipherRecord()
+}
+
+// processHelloRetryRequest handles the HRR in hs.serverHello, modifies and
+// resends hs.hello, and reads the new ServerHello into hs.serverHello.
+func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
+ c := hs.c
+
+ // The first ClientHello gets double-hashed into the transcript upon a
+ // HelloRetryRequest. (The idea is that the server might offload transcript
+ // storage to the client in the cookie.) See RFC 8446, Section 4.4.1.
+ chHash := hs.transcript.Sum(nil)
+ hs.transcript.Reset()
+ hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
+ hs.transcript.Write(chHash)
+ if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
+ return err
+ }
+
+ // The only HelloRetryRequest extensions we support are key_share and
+ // cookie, and clients must abort the handshake if the HRR would not result
+ // in any change in the ClientHello.
+ if hs.serverHello.selectedGroup == 0 && hs.serverHello.cookie == nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server sent an unnecessary HelloRetryRequest message")
+ }
+
+ if hs.serverHello.cookie != nil {
+ hs.hello.cookie = hs.serverHello.cookie
+ }
+
+ if hs.serverHello.serverShare.group != 0 {
+ c.sendAlert(alertDecodeError)
+ return errors.New("tls: received malformed key_share extension")
+ }
+
+ // If the server sent a key_share extension selecting a group, ensure it's
+ // a group we advertised but did not send a key share for, and send a key
+ // share for it this time.
+ if curveID := hs.serverHello.selectedGroup; curveID != 0 {
+ curveOK := false
+ for _, id := range hs.hello.supportedCurves {
+ if id == curveID {
+ curveOK = true
+ break
+ }
+ }
+ if !curveOK {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server selected unsupported group")
+ }
+ if sentID, _ := curveIDForCurve(hs.ecdheKey.Curve()); sentID == curveID {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
+ }
+ if _, ok := curveForCurveID(curveID); !ok {
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: CurvePreferences includes unsupported curve")
+ }
+ key, err := generateECDHEKey(c.config.rand(), curveID)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ hs.ecdheKey = key
+ hs.hello.keyShares = []keyShare{{group: curveID, data: key.PublicKey().Bytes()}}
+ }
+
+ hs.hello.raw = nil
+ if len(hs.hello.pskIdentities) > 0 {
+ pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite)
+ if pskSuite == nil {
+ return c.sendAlert(alertInternalError)
+ }
+ if pskSuite.hash == hs.suite.hash {
+ // Update binders and obfuscated_ticket_age.
+ ticketAge := c.config.time().Sub(time.Unix(int64(hs.session.createdAt), 0))
+ hs.hello.pskIdentities[0].obfuscatedTicketAge = uint32(ticketAge/time.Millisecond) + hs.session.ageAdd
+
+ transcript := hs.suite.hash.New()
+ transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
+ transcript.Write(chHash)
+ if err := transcriptMsg(hs.serverHello, transcript); err != nil {
+ return err
+ }
+ helloBytes, err := hs.hello.marshalWithoutBinders()
+ if err != nil {
+ return err
+ }
+ transcript.Write(helloBytes)
+ pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)}
+ if err := hs.hello.updateBinders(pskBinders); err != nil {
+ return err
+ }
+ } else {
+ // Server selected a cipher suite incompatible with the PSK.
+ hs.hello.pskIdentities = nil
+ hs.hello.pskBinders = nil
+ }
+ }
+
+ if hs.hello.earlyData {
+ hs.hello.earlyData = false
+ c.quicRejectedEarlyData()
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil {
+ return err
+ }
+
+ // serverHelloMsg is not included in the transcript
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ serverHello, ok := msg.(*serverHelloMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(serverHello, msg)
+ }
+ hs.serverHello = serverHello
+
+ if err := hs.checkServerHelloOrHRR(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) processServerHello() error {
+ c := hs.c
+
+ if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
+ c.sendAlert(alertUnexpectedMessage)
+ return errors.New("tls: server sent two HelloRetryRequest messages")
+ }
+
+ if len(hs.serverHello.cookie) != 0 {
+ c.sendAlert(alertUnsupportedExtension)
+ return errors.New("tls: server sent a cookie in a normal ServerHello")
+ }
+
+ if hs.serverHello.selectedGroup != 0 {
+ c.sendAlert(alertDecodeError)
+ return errors.New("tls: malformed key_share extension")
+ }
+
+ if hs.serverHello.serverShare.group == 0 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server did not send a key share")
+ }
+ if sentID, _ := curveIDForCurve(hs.ecdheKey.Curve()); hs.serverHello.serverShare.group != sentID {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server selected unsupported group")
+ }
+
+ if !hs.serverHello.selectedIdentityPresent {
+ return nil
+ }
+
+ if int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server selected an invalid PSK")
+ }
+
+ if len(hs.hello.pskIdentities) != 1 || hs.session == nil {
+ return c.sendAlert(alertInternalError)
+ }
+ pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite)
+ if pskSuite == nil {
+ return c.sendAlert(alertInternalError)
+ }
+ if pskSuite.hash != hs.suite.hash {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server selected an invalid PSK and cipher suite pair")
+ }
+
+ hs.usingPSK = true
+ c.didResume = true
+ c.peerCertificates = hs.session.peerCertificates
+ c.activeCertHandles = hs.session.activeCertHandles
+ c.verifiedChains = hs.session.verifiedChains
+ c.ocspResponse = hs.session.ocspResponse
+ c.scts = hs.session.scts
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
+ c := hs.c
+
+ peerKey, err := hs.ecdheKey.Curve().NewPublicKey(hs.serverHello.serverShare.data)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid server key share")
+ }
+ sharedKey, err := hs.ecdheKey.ECDH(peerKey)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid server key share")
+ }
+
+ earlySecret := hs.earlySecret
+ if !hs.usingPSK {
+ earlySecret = hs.suite.extract(nil, nil)
+ }
+
+ handshakeSecret := hs.suite.extract(sharedKey,
+ hs.suite.deriveSecret(earlySecret, "derived", nil))
+
+ clientSecret := hs.suite.deriveSecret(handshakeSecret,
+ clientHandshakeTrafficLabel, hs.transcript)
+ c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
+ serverSecret := hs.suite.deriveSecret(handshakeSecret,
+ serverHandshakeTrafficLabel, hs.transcript)
+ c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
+
+ if c.quic != nil {
+ if c.hand.Len() != 0 {
+ c.sendAlert(alertUnexpectedMessage)
+ }
+ c.quicSetWriteSecret(QUICEncryptionLevelHandshake, hs.suite.id, clientSecret)
+ c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, serverSecret)
+ }
+
+ err = c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.hello.random, serverSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ hs.masterSecret = hs.suite.extract(nil,
+ hs.suite.deriveSecret(handshakeSecret, "derived", nil))
+
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) readServerParameters() error {
+ c := hs.c
+
+ msg, err := c.readHandshake(hs.transcript)
+ if err != nil {
+ return err
+ }
+
+ encryptedExtensions, ok := msg.(*encryptedExtensionsMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(encryptedExtensions, msg)
+ }
+
+ if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol, c.quic != nil); err != nil {
+ // RFC 8446 specifies that no_application_protocol is sent by servers, but
+ // does not specify how clients handle the selection of an incompatible protocol.
+ // RFC 9001 Section 8.1 specifies that QUIC clients send no_application_protocol
+ // in this case. Always sending no_application_protocol seems reasonable.
+ c.sendAlert(alertNoApplicationProtocol)
+ return err
+ }
+ c.clientProtocol = encryptedExtensions.alpnProtocol
+
+ if c.quic != nil {
+ if encryptedExtensions.quicTransportParameters == nil {
+ // RFC 9001 Section 8.2.
+ c.sendAlert(alertMissingExtension)
+ return errors.New("tls: server did not send a quic_transport_parameters extension")
+ }
+ c.quicSetTransportParameters(encryptedExtensions.quicTransportParameters)
+ } else {
+ if encryptedExtensions.quicTransportParameters != nil {
+ c.sendAlert(alertUnsupportedExtension)
+ return errors.New("tls: server sent an unexpected quic_transport_parameters extension")
+ }
+ }
+
+ if !hs.hello.earlyData && encryptedExtensions.earlyData {
+ c.sendAlert(alertUnsupportedExtension)
+ return errors.New("tls: server sent an unexpected early_data extension")
+ }
+ if hs.hello.earlyData && !encryptedExtensions.earlyData {
+ c.quicRejectedEarlyData()
+ }
+ if encryptedExtensions.earlyData {
+ if hs.session.cipherSuite != c.cipherSuite {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: server accepted 0-RTT with the wrong cipher suite")
+ }
+ if hs.session.alpnProtocol != c.clientProtocol {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: server accepted 0-RTT with the wrong ALPN")
+ }
+ }
+
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) readServerCertificate() error {
+ c := hs.c
+
+ // Either a PSK or a certificate is always used, but not both.
+ // See RFC 8446, Section 4.1.1.
+ if hs.usingPSK {
+ // Make sure the connection is still being verified whether or not this
+ // is a resumption. Resumptions currently don't reverify certificates so
+ // they don't call verifyServerCertificate. See Issue 31641.
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+ return nil
+ }
+
+ msg, err := c.readHandshake(hs.transcript)
+ if err != nil {
+ return err
+ }
+
+ certReq, ok := msg.(*certificateRequestMsgTLS13)
+ if ok {
+ hs.certReq = certReq
+
+ msg, err = c.readHandshake(hs.transcript)
+ if err != nil {
+ return err
+ }
+ }
+
+ certMsg, ok := msg.(*certificateMsgTLS13)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certMsg, msg)
+ }
+ if len(certMsg.certificate.Certificate) == 0 {
+ c.sendAlert(alertDecodeError)
+ return errors.New("tls: received empty certificates message")
+ }
+
+ c.scts = certMsg.certificate.SignedCertificateTimestamps
+ c.ocspResponse = certMsg.certificate.OCSPStaple
+
+ if err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil {
+ return err
+ }
+
+ // certificateVerifyMsg is included in the transcript, but not until
+ // after we verify the handshake signature, since the state before
+ // this message was sent is used.
+ msg, err = c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ certVerify, ok := msg.(*certificateVerifyMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certVerify, msg)
+ }
+
+ // See RFC 8446, Section 4.4.3.
+ if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: certificate used with invalid signature algorithm")
+ }
+ sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
+ if err != nil {
+ return c.sendAlert(alertInternalError)
+ }
+ if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: certificate used with invalid signature algorithm")
+ }
+ signed := signedMessage(sigHash, serverSignatureContext, hs.transcript)
+ if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey,
+ sigHash, signed, certVerify.signature); err != nil {
+ c.sendAlert(alertDecryptError)
+ return errors.New("tls: invalid signature by the server certificate: " + err.Error())
+ }
+
+ if err := transcriptMsg(certVerify, hs.transcript); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) readServerFinished() error {
+ c := hs.c
+
+ // finishedMsg is included in the transcript, but not until after we
+ // check the client version, since the state before this message was
+ // sent is used during verification.
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ finished, ok := msg.(*finishedMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(finished, msg)
+ }
+
+ expectedMAC := hs.suite.finishedHash(c.in.trafficSecret, hs.transcript)
+ if !hmac.Equal(expectedMAC, finished.verifyData) {
+ c.sendAlert(alertDecryptError)
+ return errors.New("tls: invalid server finished hash")
+ }
+
+ if err := transcriptMsg(finished, hs.transcript); err != nil {
+ return err
+ }
+
+ // Derive secrets that take context through the server Finished.
+
+ hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret,
+ clientApplicationTrafficLabel, hs.transcript)
+ serverSecret := hs.suite.deriveSecret(hs.masterSecret,
+ serverApplicationTrafficLabel, hs.transcript)
+ c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret)
+
+ err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.hello.random, serverSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript)
+
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) sendClientCertificate() error {
+ c := hs.c
+
+ if hs.certReq == nil {
+ return nil
+ }
+
+ cert, err := c.getClientCertificate(&CertificateRequestInfo{
+ AcceptableCAs: hs.certReq.certificateAuthorities,
+ SignatureSchemes: hs.certReq.supportedSignatureAlgorithms,
+ Version: c.vers,
+ ctx: hs.ctx,
+ })
+ if err != nil {
+ return err
+ }
+
+ certMsg := new(certificateMsgTLS13)
+
+ certMsg.certificate = *cert
+ certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0
+ certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0
+
+ if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != nil {
+ return err
+ }
+
+ // If we sent an empty certificate message, skip the CertificateVerify.
+ if len(cert.Certificate) == 0 {
+ return nil
+ }
+
+ certVerifyMsg := new(certificateVerifyMsg)
+ certVerifyMsg.hasSignatureAlgorithm = true
+
+ certVerifyMsg.signatureAlgorithm, err = selectSignatureScheme(c.vers, cert, hs.certReq.supportedSignatureAlgorithms)
+ if err != nil {
+ // getClientCertificate returned a certificate incompatible with the
+ // CertificateRequestInfo supported signature algorithms.
+ c.sendAlert(alertHandshakeFailure)
+ return err
+ }
+
+ sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerifyMsg.signatureAlgorithm)
+ if err != nil {
+ return c.sendAlert(alertInternalError)
+ }
+
+ signed := signedMessage(sigHash, clientSignatureContext, hs.transcript)
+ signOpts := crypto.SignerOpts(sigHash)
+ if sigType == signatureRSAPSS {
+ signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
+ }
+ sig, err := cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: failed to sign handshake: " + err.Error())
+ }
+ certVerifyMsg.signature = sig
+
+ if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) sendClientFinished() error {
+ c := hs.c
+
+ finished := &finishedMsg{
+ verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != nil {
+ return err
+ }
+
+ c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret)
+
+ if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil {
+ c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
+ resumptionLabel, hs.transcript)
+ }
+
+ if c.quic != nil {
+ if c.hand.Len() != 0 {
+ c.sendAlert(alertUnexpectedMessage)
+ }
+ c.quicSetWriteSecret(QUICEncryptionLevelApplication, hs.suite.id, hs.trafficSecret)
+ }
+
+ return nil
+}
+
+func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error {
+ if !c.isClient {
+ c.sendAlert(alertUnexpectedMessage)
+ return errors.New("tls: received new session ticket from a client")
+ }
+
+ if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil {
+ return nil
+ }
+
+ // See RFC 8446, Section 4.6.1.
+ if msg.lifetime == 0 {
+ return nil
+ }
+ lifetime := time.Duration(msg.lifetime) * time.Second
+ if lifetime > maxSessionTicketLifetime {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: received a session ticket with invalid lifetime")
+ }
+
+ // RFC 9001, Section 4.6.1
+ if c.quic != nil && msg.maxEarlyData != 0 && msg.maxEarlyData != 0xffffffff {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid early data for QUIC connection")
+ }
+
+ cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
+ if cipherSuite == nil || c.resumptionSecret == nil {
+ return c.sendAlert(alertInternalError)
+ }
+
+ psk := cipherSuite.expandLabel(c.resumptionSecret, "resumption",
+ msg.nonce, cipherSuite.hash.Size())
+
+ session, err := c.sessionState()
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ session.secret = psk
+ session.useBy = uint64(c.config.time().Add(lifetime).Unix())
+ session.ageAdd = msg.ageAdd
+ session.EarlyData = c.quic != nil && msg.maxEarlyData == 0xffffffff // RFC 9001, Section 4.6.1
+ cs := &ClientSessionState{ticket: msg.label, session: session}
+
+ if cacheKey := c.clientSessionCacheKey(); cacheKey != "" {
+ c.config.ClientSessionCache.Put(cacheKey, cs)
+ }
+
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/crypto/tls/handshake_messages.go b/contrib/go/_std_1.21/src/crypto/tls/handshake_messages.go
new file mode 100644
index 0000000000..a86055a060
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/handshake_messages.go
@@ -0,0 +1,1903 @@
+// Copyright 2009 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 tls
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+
+ "golang.org/x/crypto/cryptobyte"
+)
+
+// The marshalingFunction type is an adapter to allow the use of ordinary
+// functions as cryptobyte.MarshalingValue.
+type marshalingFunction func(b *cryptobyte.Builder) error
+
+func (f marshalingFunction) Marshal(b *cryptobyte.Builder) error {
+ return f(b)
+}
+
+// addBytesWithLength appends a sequence of bytes to the cryptobyte.Builder. If
+// the length of the sequence is not the value specified, it produces an error.
+func addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) {
+ b.AddValue(marshalingFunction(func(b *cryptobyte.Builder) error {
+ if len(v) != n {
+ return fmt.Errorf("invalid value length: expected %d, got %d", n, len(v))
+ }
+ b.AddBytes(v)
+ return nil
+ }))
+}
+
+// addUint64 appends a big-endian, 64-bit value to the cryptobyte.Builder.
+func addUint64(b *cryptobyte.Builder, v uint64) {
+ b.AddUint32(uint32(v >> 32))
+ b.AddUint32(uint32(v))
+}
+
+// readUint64 decodes a big-endian, 64-bit value into out and advances over it.
+// It reports whether the read was successful.
+func readUint64(s *cryptobyte.String, out *uint64) bool {
+ var hi, lo uint32
+ if !s.ReadUint32(&hi) || !s.ReadUint32(&lo) {
+ return false
+ }
+ *out = uint64(hi)<<32 | uint64(lo)
+ return true
+}
+
+// readUint8LengthPrefixed acts like s.ReadUint8LengthPrefixed, but targets a
+// []byte instead of a cryptobyte.String.
+func readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
+ return s.ReadUint8LengthPrefixed((*cryptobyte.String)(out))
+}
+
+// readUint16LengthPrefixed acts like s.ReadUint16LengthPrefixed, but targets a
+// []byte instead of a cryptobyte.String.
+func readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
+ return s.ReadUint16LengthPrefixed((*cryptobyte.String)(out))
+}
+
+// readUint24LengthPrefixed acts like s.ReadUint24LengthPrefixed, but targets a
+// []byte instead of a cryptobyte.String.
+func readUint24LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
+ return s.ReadUint24LengthPrefixed((*cryptobyte.String)(out))
+}
+
+type clientHelloMsg struct {
+ raw []byte
+ vers uint16
+ random []byte
+ sessionId []byte
+ cipherSuites []uint16
+ compressionMethods []uint8
+ serverName string
+ ocspStapling bool
+ supportedCurves []CurveID
+ supportedPoints []uint8
+ ticketSupported bool
+ sessionTicket []uint8
+ supportedSignatureAlgorithms []SignatureScheme
+ supportedSignatureAlgorithmsCert []SignatureScheme
+ secureRenegotiationSupported bool
+ secureRenegotiation []byte
+ extendedMasterSecret bool
+ alpnProtocols []string
+ scts bool
+ supportedVersions []uint16
+ cookie []byte
+ keyShares []keyShare
+ earlyData bool
+ pskModes []uint8
+ pskIdentities []pskIdentity
+ pskBinders [][]byte
+ quicTransportParameters []byte
+}
+
+func (m *clientHelloMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var exts cryptobyte.Builder
+ if len(m.serverName) > 0 {
+ // RFC 6066, Section 3
+ exts.AddUint16(extensionServerName)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8(0) // name_type = host_name
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes([]byte(m.serverName))
+ })
+ })
+ })
+ }
+ if m.ocspStapling {
+ // RFC 4366, Section 3.6
+ exts.AddUint16(extensionStatusRequest)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8(1) // status_type = ocsp
+ exts.AddUint16(0) // empty responder_id_list
+ exts.AddUint16(0) // empty request_extensions
+ })
+ }
+ if len(m.supportedCurves) > 0 {
+ // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
+ exts.AddUint16(extensionSupportedCurves)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, curve := range m.supportedCurves {
+ exts.AddUint16(uint16(curve))
+ }
+ })
+ })
+ }
+ if len(m.supportedPoints) > 0 {
+ // RFC 4492, Section 5.1.2
+ exts.AddUint16(extensionSupportedPoints)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.supportedPoints)
+ })
+ })
+ }
+ if m.ticketSupported {
+ // RFC 5077, Section 3.2
+ exts.AddUint16(extensionSessionTicket)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.sessionTicket)
+ })
+ }
+ if len(m.supportedSignatureAlgorithms) > 0 {
+ // RFC 5246, Section 7.4.1.4.1
+ exts.AddUint16(extensionSignatureAlgorithms)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, sigAlgo := range m.supportedSignatureAlgorithms {
+ exts.AddUint16(uint16(sigAlgo))
+ }
+ })
+ })
+ }
+ if len(m.supportedSignatureAlgorithmsCert) > 0 {
+ // RFC 8446, Section 4.2.3
+ exts.AddUint16(extensionSignatureAlgorithmsCert)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, sigAlgo := range m.supportedSignatureAlgorithmsCert {
+ exts.AddUint16(uint16(sigAlgo))
+ }
+ })
+ })
+ }
+ if m.secureRenegotiationSupported {
+ // RFC 5746, Section 3.2
+ exts.AddUint16(extensionRenegotiationInfo)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.secureRenegotiation)
+ })
+ })
+ }
+ if m.extendedMasterSecret {
+ // RFC 7627
+ exts.AddUint16(extensionExtendedMasterSecret)
+ exts.AddUint16(0) // empty extension_data
+ }
+ if len(m.alpnProtocols) > 0 {
+ // RFC 7301, Section 3.1
+ exts.AddUint16(extensionALPN)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, proto := range m.alpnProtocols {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes([]byte(proto))
+ })
+ }
+ })
+ })
+ }
+ if m.scts {
+ // RFC 6962, Section 3.3.1
+ exts.AddUint16(extensionSCT)
+ exts.AddUint16(0) // empty extension_data
+ }
+ if len(m.supportedVersions) > 0 {
+ // RFC 8446, Section 4.2.1
+ exts.AddUint16(extensionSupportedVersions)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, vers := range m.supportedVersions {
+ exts.AddUint16(vers)
+ }
+ })
+ })
+ }
+ if len(m.cookie) > 0 {
+ // RFC 8446, Section 4.2.2
+ exts.AddUint16(extensionCookie)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.cookie)
+ })
+ })
+ }
+ if len(m.keyShares) > 0 {
+ // RFC 8446, Section 4.2.8
+ exts.AddUint16(extensionKeyShare)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, ks := range m.keyShares {
+ exts.AddUint16(uint16(ks.group))
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(ks.data)
+ })
+ }
+ })
+ })
+ }
+ if m.earlyData {
+ // RFC 8446, Section 4.2.10
+ exts.AddUint16(extensionEarlyData)
+ exts.AddUint16(0) // empty extension_data
+ }
+ if len(m.pskModes) > 0 {
+ // RFC 8446, Section 4.2.9
+ exts.AddUint16(extensionPSKModes)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.pskModes)
+ })
+ })
+ }
+ if m.quicTransportParameters != nil { // marshal zero-length parameters when present
+ // RFC 9001, Section 8.2
+ exts.AddUint16(extensionQUICTransportParameters)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.quicTransportParameters)
+ })
+ }
+ if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension
+ // RFC 8446, Section 4.2.11
+ exts.AddUint16(extensionPreSharedKey)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, psk := range m.pskIdentities {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(psk.label)
+ })
+ exts.AddUint32(psk.obfuscatedTicketAge)
+ }
+ })
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, binder := range m.pskBinders {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(binder)
+ })
+ }
+ })
+ })
+ }
+ extBytes, err := exts.Bytes()
+ if err != nil {
+ return nil, err
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeClientHello)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16(m.vers)
+ addBytesWithLength(b, m.random, 32)
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.sessionId)
+ })
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, suite := range m.cipherSuites {
+ b.AddUint16(suite)
+ }
+ })
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.compressionMethods)
+ })
+
+ if len(extBytes) > 0 {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(extBytes)
+ })
+ }
+ })
+
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+// marshalWithoutBinders returns the ClientHello through the
+// PreSharedKeyExtension.identities field, according to RFC 8446, Section
+// 4.2.11.2. Note that m.pskBinders must be set to slices of the correct length.
+func (m *clientHelloMsg) marshalWithoutBinders() ([]byte, error) {
+ bindersLen := 2 // uint16 length prefix
+ for _, binder := range m.pskBinders {
+ bindersLen += 1 // uint8 length prefix
+ bindersLen += len(binder)
+ }
+
+ fullMessage, err := m.marshal()
+ if err != nil {
+ return nil, err
+ }
+ return fullMessage[:len(fullMessage)-bindersLen], nil
+}
+
+// updateBinders updates the m.pskBinders field, if necessary updating the
+// cached marshaled representation. The supplied binders must have the same
+// length as the current m.pskBinders.
+func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) error {
+ if len(pskBinders) != len(m.pskBinders) {
+ return errors.New("tls: internal error: pskBinders length mismatch")
+ }
+ for i := range m.pskBinders {
+ if len(pskBinders[i]) != len(m.pskBinders[i]) {
+ return errors.New("tls: internal error: pskBinders length mismatch")
+ }
+ }
+ m.pskBinders = pskBinders
+ if m.raw != nil {
+ helloBytes, err := m.marshalWithoutBinders()
+ if err != nil {
+ return err
+ }
+ lenWithoutBinders := len(helloBytes)
+ b := cryptobyte.NewFixedBuilder(m.raw[:lenWithoutBinders])
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, binder := range m.pskBinders {
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(binder)
+ })
+ }
+ })
+ if out, err := b.Bytes(); err != nil || len(out) != len(m.raw) {
+ return errors.New("tls: internal error: failed to update binders")
+ }
+ }
+
+ return nil
+}
+
+func (m *clientHelloMsg) unmarshal(data []byte) bool {
+ *m = clientHelloMsg{raw: data}
+ s := cryptobyte.String(data)
+
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) ||
+ !readUint8LengthPrefixed(&s, &m.sessionId) {
+ return false
+ }
+
+ var cipherSuites cryptobyte.String
+ if !s.ReadUint16LengthPrefixed(&cipherSuites) {
+ return false
+ }
+ m.cipherSuites = []uint16{}
+ m.secureRenegotiationSupported = false
+ for !cipherSuites.Empty() {
+ var suite uint16
+ if !cipherSuites.ReadUint16(&suite) {
+ return false
+ }
+ if suite == scsvRenegotiation {
+ m.secureRenegotiationSupported = true
+ }
+ m.cipherSuites = append(m.cipherSuites, suite)
+ }
+
+ if !readUint8LengthPrefixed(&s, &m.compressionMethods) {
+ return false
+ }
+
+ if s.Empty() {
+ // ClientHello is optionally followed by extension data
+ return true
+ }
+
+ var extensions cryptobyte.String
+ if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
+ return false
+ }
+
+ seenExts := make(map[uint16]bool)
+ for !extensions.Empty() {
+ var extension uint16
+ var extData cryptobyte.String
+ if !extensions.ReadUint16(&extension) ||
+ !extensions.ReadUint16LengthPrefixed(&extData) {
+ return false
+ }
+
+ if seenExts[extension] {
+ return false
+ }
+ seenExts[extension] = true
+
+ switch extension {
+ case extensionServerName:
+ // RFC 6066, Section 3
+ var nameList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() {
+ return false
+ }
+ for !nameList.Empty() {
+ var nameType uint8
+ var serverName cryptobyte.String
+ if !nameList.ReadUint8(&nameType) ||
+ !nameList.ReadUint16LengthPrefixed(&serverName) ||
+ serverName.Empty() {
+ return false
+ }
+ if nameType != 0 {
+ continue
+ }
+ if len(m.serverName) != 0 {
+ // Multiple names of the same name_type are prohibited.
+ return false
+ }
+ m.serverName = string(serverName)
+ // An SNI value may not include a trailing dot.
+ if strings.HasSuffix(m.serverName, ".") {
+ return false
+ }
+ }
+ case extensionStatusRequest:
+ // RFC 4366, Section 3.6
+ var statusType uint8
+ var ignored cryptobyte.String
+ if !extData.ReadUint8(&statusType) ||
+ !extData.ReadUint16LengthPrefixed(&ignored) ||
+ !extData.ReadUint16LengthPrefixed(&ignored) {
+ return false
+ }
+ m.ocspStapling = statusType == statusTypeOCSP
+ case extensionSupportedCurves:
+ // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
+ var curves cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&curves) || curves.Empty() {
+ return false
+ }
+ for !curves.Empty() {
+ var curve uint16
+ if !curves.ReadUint16(&curve) {
+ return false
+ }
+ m.supportedCurves = append(m.supportedCurves, CurveID(curve))
+ }
+ case extensionSupportedPoints:
+ // RFC 4492, Section 5.1.2
+ if !readUint8LengthPrefixed(&extData, &m.supportedPoints) ||
+ len(m.supportedPoints) == 0 {
+ return false
+ }
+ case extensionSessionTicket:
+ // RFC 5077, Section 3.2
+ m.ticketSupported = true
+ extData.ReadBytes(&m.sessionTicket, len(extData))
+ case extensionSignatureAlgorithms:
+ // RFC 5246, Section 7.4.1.4.1
+ var sigAndAlgs cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
+ return false
+ }
+ for !sigAndAlgs.Empty() {
+ var sigAndAlg uint16
+ if !sigAndAlgs.ReadUint16(&sigAndAlg) {
+ return false
+ }
+ m.supportedSignatureAlgorithms = append(
+ m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg))
+ }
+ case extensionSignatureAlgorithmsCert:
+ // RFC 8446, Section 4.2.3
+ var sigAndAlgs cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
+ return false
+ }
+ for !sigAndAlgs.Empty() {
+ var sigAndAlg uint16
+ if !sigAndAlgs.ReadUint16(&sigAndAlg) {
+ return false
+ }
+ m.supportedSignatureAlgorithmsCert = append(
+ m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg))
+ }
+ case extensionRenegotiationInfo:
+ // RFC 5746, Section 3.2
+ if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {
+ return false
+ }
+ m.secureRenegotiationSupported = true
+ case extensionExtendedMasterSecret:
+ // RFC 7627
+ m.extendedMasterSecret = true
+ case extensionALPN:
+ // RFC 7301, Section 3.1
+ var protoList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
+ return false
+ }
+ for !protoList.Empty() {
+ var proto cryptobyte.String
+ if !protoList.ReadUint8LengthPrefixed(&proto) || proto.Empty() {
+ return false
+ }
+ m.alpnProtocols = append(m.alpnProtocols, string(proto))
+ }
+ case extensionSCT:
+ // RFC 6962, Section 3.3.1
+ m.scts = true
+ case extensionSupportedVersions:
+ // RFC 8446, Section 4.2.1
+ var versList cryptobyte.String
+ if !extData.ReadUint8LengthPrefixed(&versList) || versList.Empty() {
+ return false
+ }
+ for !versList.Empty() {
+ var vers uint16
+ if !versList.ReadUint16(&vers) {
+ return false
+ }
+ m.supportedVersions = append(m.supportedVersions, vers)
+ }
+ case extensionCookie:
+ // RFC 8446, Section 4.2.2
+ if !readUint16LengthPrefixed(&extData, &m.cookie) ||
+ len(m.cookie) == 0 {
+ return false
+ }
+ case extensionKeyShare:
+ // RFC 8446, Section 4.2.8
+ var clientShares cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&clientShares) {
+ return false
+ }
+ for !clientShares.Empty() {
+ var ks keyShare
+ if !clientShares.ReadUint16((*uint16)(&ks.group)) ||
+ !readUint16LengthPrefixed(&clientShares, &ks.data) ||
+ len(ks.data) == 0 {
+ return false
+ }
+ m.keyShares = append(m.keyShares, ks)
+ }
+ case extensionEarlyData:
+ // RFC 8446, Section 4.2.10
+ m.earlyData = true
+ case extensionPSKModes:
+ // RFC 8446, Section 4.2.9
+ if !readUint8LengthPrefixed(&extData, &m.pskModes) {
+ return false
+ }
+ case extensionQUICTransportParameters:
+ m.quicTransportParameters = make([]byte, len(extData))
+ if !extData.CopyBytes(m.quicTransportParameters) {
+ return false
+ }
+ case extensionPreSharedKey:
+ // RFC 8446, Section 4.2.11
+ if !extensions.Empty() {
+ return false // pre_shared_key must be the last extension
+ }
+ var identities cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&identities) || identities.Empty() {
+ return false
+ }
+ for !identities.Empty() {
+ var psk pskIdentity
+ if !readUint16LengthPrefixed(&identities, &psk.label) ||
+ !identities.ReadUint32(&psk.obfuscatedTicketAge) ||
+ len(psk.label) == 0 {
+ return false
+ }
+ m.pskIdentities = append(m.pskIdentities, psk)
+ }
+ var binders cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&binders) || binders.Empty() {
+ return false
+ }
+ for !binders.Empty() {
+ var binder []byte
+ if !readUint8LengthPrefixed(&binders, &binder) ||
+ len(binder) == 0 {
+ return false
+ }
+ m.pskBinders = append(m.pskBinders, binder)
+ }
+ default:
+ // Ignore unknown extensions.
+ continue
+ }
+
+ if !extData.Empty() {
+ return false
+ }
+ }
+
+ return true
+}
+
+type serverHelloMsg struct {
+ raw []byte
+ vers uint16
+ random []byte
+ sessionId []byte
+ cipherSuite uint16
+ compressionMethod uint8
+ ocspStapling bool
+ ticketSupported bool
+ secureRenegotiationSupported bool
+ secureRenegotiation []byte
+ extendedMasterSecret bool
+ alpnProtocol string
+ scts [][]byte
+ supportedVersion uint16
+ serverShare keyShare
+ selectedIdentityPresent bool
+ selectedIdentity uint16
+ supportedPoints []uint8
+
+ // HelloRetryRequest extensions
+ cookie []byte
+ selectedGroup CurveID
+}
+
+func (m *serverHelloMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var exts cryptobyte.Builder
+ if m.ocspStapling {
+ exts.AddUint16(extensionStatusRequest)
+ exts.AddUint16(0) // empty extension_data
+ }
+ if m.ticketSupported {
+ exts.AddUint16(extensionSessionTicket)
+ exts.AddUint16(0) // empty extension_data
+ }
+ if m.secureRenegotiationSupported {
+ exts.AddUint16(extensionRenegotiationInfo)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.secureRenegotiation)
+ })
+ })
+ }
+ if m.extendedMasterSecret {
+ exts.AddUint16(extensionExtendedMasterSecret)
+ exts.AddUint16(0) // empty extension_data
+ }
+ if len(m.alpnProtocol) > 0 {
+ exts.AddUint16(extensionALPN)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes([]byte(m.alpnProtocol))
+ })
+ })
+ })
+ }
+ if len(m.scts) > 0 {
+ exts.AddUint16(extensionSCT)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, sct := range m.scts {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(sct)
+ })
+ }
+ })
+ })
+ }
+ if m.supportedVersion != 0 {
+ exts.AddUint16(extensionSupportedVersions)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16(m.supportedVersion)
+ })
+ }
+ if m.serverShare.group != 0 {
+ exts.AddUint16(extensionKeyShare)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16(uint16(m.serverShare.group))
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.serverShare.data)
+ })
+ })
+ }
+ if m.selectedIdentityPresent {
+ exts.AddUint16(extensionPreSharedKey)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16(m.selectedIdentity)
+ })
+ }
+
+ if len(m.cookie) > 0 {
+ exts.AddUint16(extensionCookie)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.cookie)
+ })
+ })
+ }
+ if m.selectedGroup != 0 {
+ exts.AddUint16(extensionKeyShare)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16(uint16(m.selectedGroup))
+ })
+ }
+ if len(m.supportedPoints) > 0 {
+ exts.AddUint16(extensionSupportedPoints)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.supportedPoints)
+ })
+ })
+ }
+
+ extBytes, err := exts.Bytes()
+ if err != nil {
+ return nil, err
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeServerHello)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16(m.vers)
+ addBytesWithLength(b, m.random, 32)
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.sessionId)
+ })
+ b.AddUint16(m.cipherSuite)
+ b.AddUint8(m.compressionMethod)
+
+ if len(extBytes) > 0 {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(extBytes)
+ })
+ }
+ })
+
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *serverHelloMsg) unmarshal(data []byte) bool {
+ *m = serverHelloMsg{raw: data}
+ s := cryptobyte.String(data)
+
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) ||
+ !readUint8LengthPrefixed(&s, &m.sessionId) ||
+ !s.ReadUint16(&m.cipherSuite) ||
+ !s.ReadUint8(&m.compressionMethod) {
+ return false
+ }
+
+ if s.Empty() {
+ // ServerHello is optionally followed by extension data
+ return true
+ }
+
+ var extensions cryptobyte.String
+ if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
+ return false
+ }
+
+ seenExts := make(map[uint16]bool)
+ for !extensions.Empty() {
+ var extension uint16
+ var extData cryptobyte.String
+ if !extensions.ReadUint16(&extension) ||
+ !extensions.ReadUint16LengthPrefixed(&extData) {
+ return false
+ }
+
+ if seenExts[extension] {
+ return false
+ }
+ seenExts[extension] = true
+
+ switch extension {
+ case extensionStatusRequest:
+ m.ocspStapling = true
+ case extensionSessionTicket:
+ m.ticketSupported = true
+ case extensionRenegotiationInfo:
+ if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {
+ return false
+ }
+ m.secureRenegotiationSupported = true
+ case extensionExtendedMasterSecret:
+ m.extendedMasterSecret = true
+ case extensionALPN:
+ var protoList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
+ return false
+ }
+ var proto cryptobyte.String
+ if !protoList.ReadUint8LengthPrefixed(&proto) ||
+ proto.Empty() || !protoList.Empty() {
+ return false
+ }
+ m.alpnProtocol = string(proto)
+ case extensionSCT:
+ var sctList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {
+ return false
+ }
+ for !sctList.Empty() {
+ var sct []byte
+ if !readUint16LengthPrefixed(&sctList, &sct) ||
+ len(sct) == 0 {
+ return false
+ }
+ m.scts = append(m.scts, sct)
+ }
+ case extensionSupportedVersions:
+ if !extData.ReadUint16(&m.supportedVersion) {
+ return false
+ }
+ case extensionCookie:
+ if !readUint16LengthPrefixed(&extData, &m.cookie) ||
+ len(m.cookie) == 0 {
+ return false
+ }
+ case extensionKeyShare:
+ // This extension has different formats in SH and HRR, accept either
+ // and let the handshake logic decide. See RFC 8446, Section 4.2.8.
+ if len(extData) == 2 {
+ if !extData.ReadUint16((*uint16)(&m.selectedGroup)) {
+ return false
+ }
+ } else {
+ if !extData.ReadUint16((*uint16)(&m.serverShare.group)) ||
+ !readUint16LengthPrefixed(&extData, &m.serverShare.data) {
+ return false
+ }
+ }
+ case extensionPreSharedKey:
+ m.selectedIdentityPresent = true
+ if !extData.ReadUint16(&m.selectedIdentity) {
+ return false
+ }
+ case extensionSupportedPoints:
+ // RFC 4492, Section 5.1.2
+ if !readUint8LengthPrefixed(&extData, &m.supportedPoints) ||
+ len(m.supportedPoints) == 0 {
+ return false
+ }
+ default:
+ // Ignore unknown extensions.
+ continue
+ }
+
+ if !extData.Empty() {
+ return false
+ }
+ }
+
+ return true
+}
+
+type encryptedExtensionsMsg struct {
+ raw []byte
+ alpnProtocol string
+ quicTransportParameters []byte
+ earlyData bool
+}
+
+func (m *encryptedExtensionsMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeEncryptedExtensions)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ if len(m.alpnProtocol) > 0 {
+ b.AddUint16(extensionALPN)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes([]byte(m.alpnProtocol))
+ })
+ })
+ })
+ }
+ if m.quicTransportParameters != nil { // marshal zero-length parameters when present
+ // draft-ietf-quic-tls-32, Section 8.2
+ b.AddUint16(extensionQUICTransportParameters)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.quicTransportParameters)
+ })
+ }
+ if m.earlyData {
+ // RFC 8446, Section 4.2.10
+ b.AddUint16(extensionEarlyData)
+ b.AddUint16(0) // empty extension_data
+ }
+ })
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
+ *m = encryptedExtensionsMsg{raw: data}
+ s := cryptobyte.String(data)
+
+ var extensions cryptobyte.String
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
+ return false
+ }
+
+ for !extensions.Empty() {
+ var extension uint16
+ var extData cryptobyte.String
+ if !extensions.ReadUint16(&extension) ||
+ !extensions.ReadUint16LengthPrefixed(&extData) {
+ return false
+ }
+
+ switch extension {
+ case extensionALPN:
+ var protoList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
+ return false
+ }
+ var proto cryptobyte.String
+ if !protoList.ReadUint8LengthPrefixed(&proto) ||
+ proto.Empty() || !protoList.Empty() {
+ return false
+ }
+ m.alpnProtocol = string(proto)
+ case extensionQUICTransportParameters:
+ m.quicTransportParameters = make([]byte, len(extData))
+ if !extData.CopyBytes(m.quicTransportParameters) {
+ return false
+ }
+ case extensionEarlyData:
+ // RFC 8446, Section 4.2.10
+ m.earlyData = true
+ default:
+ // Ignore unknown extensions.
+ continue
+ }
+
+ if !extData.Empty() {
+ return false
+ }
+ }
+
+ return true
+}
+
+type endOfEarlyDataMsg struct{}
+
+func (m *endOfEarlyDataMsg) marshal() ([]byte, error) {
+ x := make([]byte, 4)
+ x[0] = typeEndOfEarlyData
+ return x, nil
+}
+
+func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool {
+ return len(data) == 4
+}
+
+type keyUpdateMsg struct {
+ raw []byte
+ updateRequested bool
+}
+
+func (m *keyUpdateMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeKeyUpdate)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ if m.updateRequested {
+ b.AddUint8(1)
+ } else {
+ b.AddUint8(0)
+ }
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *keyUpdateMsg) unmarshal(data []byte) bool {
+ m.raw = data
+ s := cryptobyte.String(data)
+
+ var updateRequested uint8
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint8(&updateRequested) || !s.Empty() {
+ return false
+ }
+ switch updateRequested {
+ case 0:
+ m.updateRequested = false
+ case 1:
+ m.updateRequested = true
+ default:
+ return false
+ }
+ return true
+}
+
+type newSessionTicketMsgTLS13 struct {
+ raw []byte
+ lifetime uint32
+ ageAdd uint32
+ nonce []byte
+ label []byte
+ maxEarlyData uint32
+}
+
+func (m *newSessionTicketMsgTLS13) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeNewSessionTicket)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint32(m.lifetime)
+ b.AddUint32(m.ageAdd)
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.nonce)
+ })
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.label)
+ })
+
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ if m.maxEarlyData > 0 {
+ b.AddUint16(extensionEarlyData)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint32(m.maxEarlyData)
+ })
+ }
+ })
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool {
+ *m = newSessionTicketMsgTLS13{raw: data}
+ s := cryptobyte.String(data)
+
+ var extensions cryptobyte.String
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint32(&m.lifetime) ||
+ !s.ReadUint32(&m.ageAdd) ||
+ !readUint8LengthPrefixed(&s, &m.nonce) ||
+ !readUint16LengthPrefixed(&s, &m.label) ||
+ !s.ReadUint16LengthPrefixed(&extensions) ||
+ !s.Empty() {
+ return false
+ }
+
+ for !extensions.Empty() {
+ var extension uint16
+ var extData cryptobyte.String
+ if !extensions.ReadUint16(&extension) ||
+ !extensions.ReadUint16LengthPrefixed(&extData) {
+ return false
+ }
+
+ switch extension {
+ case extensionEarlyData:
+ if !extData.ReadUint32(&m.maxEarlyData) {
+ return false
+ }
+ default:
+ // Ignore unknown extensions.
+ continue
+ }
+
+ if !extData.Empty() {
+ return false
+ }
+ }
+
+ return true
+}
+
+type certificateRequestMsgTLS13 struct {
+ raw []byte
+ ocspStapling bool
+ scts bool
+ supportedSignatureAlgorithms []SignatureScheme
+ supportedSignatureAlgorithmsCert []SignatureScheme
+ certificateAuthorities [][]byte
+}
+
+func (m *certificateRequestMsgTLS13) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeCertificateRequest)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ // certificate_request_context (SHALL be zero length unless used for
+ // post-handshake authentication)
+ b.AddUint8(0)
+
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ if m.ocspStapling {
+ b.AddUint16(extensionStatusRequest)
+ b.AddUint16(0) // empty extension_data
+ }
+ if m.scts {
+ // RFC 8446, Section 4.4.2.1 makes no mention of
+ // signed_certificate_timestamp in CertificateRequest, but
+ // "Extensions in the Certificate message from the client MUST
+ // correspond to extensions in the CertificateRequest message
+ // from the server." and it appears in the table in Section 4.2.
+ b.AddUint16(extensionSCT)
+ b.AddUint16(0) // empty extension_data
+ }
+ if len(m.supportedSignatureAlgorithms) > 0 {
+ b.AddUint16(extensionSignatureAlgorithms)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, sigAlgo := range m.supportedSignatureAlgorithms {
+ b.AddUint16(uint16(sigAlgo))
+ }
+ })
+ })
+ }
+ if len(m.supportedSignatureAlgorithmsCert) > 0 {
+ b.AddUint16(extensionSignatureAlgorithmsCert)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, sigAlgo := range m.supportedSignatureAlgorithmsCert {
+ b.AddUint16(uint16(sigAlgo))
+ }
+ })
+ })
+ }
+ if len(m.certificateAuthorities) > 0 {
+ b.AddUint16(extensionCertificateAuthorities)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, ca := range m.certificateAuthorities {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(ca)
+ })
+ }
+ })
+ })
+ }
+ })
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool {
+ *m = certificateRequestMsgTLS13{raw: data}
+ s := cryptobyte.String(data)
+
+ var context, extensions cryptobyte.String
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||
+ !s.ReadUint16LengthPrefixed(&extensions) ||
+ !s.Empty() {
+ return false
+ }
+
+ for !extensions.Empty() {
+ var extension uint16
+ var extData cryptobyte.String
+ if !extensions.ReadUint16(&extension) ||
+ !extensions.ReadUint16LengthPrefixed(&extData) {
+ return false
+ }
+
+ switch extension {
+ case extensionStatusRequest:
+ m.ocspStapling = true
+ case extensionSCT:
+ m.scts = true
+ case extensionSignatureAlgorithms:
+ var sigAndAlgs cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
+ return false
+ }
+ for !sigAndAlgs.Empty() {
+ var sigAndAlg uint16
+ if !sigAndAlgs.ReadUint16(&sigAndAlg) {
+ return false
+ }
+ m.supportedSignatureAlgorithms = append(
+ m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg))
+ }
+ case extensionSignatureAlgorithmsCert:
+ var sigAndAlgs cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
+ return false
+ }
+ for !sigAndAlgs.Empty() {
+ var sigAndAlg uint16
+ if !sigAndAlgs.ReadUint16(&sigAndAlg) {
+ return false
+ }
+ m.supportedSignatureAlgorithmsCert = append(
+ m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg))
+ }
+ case extensionCertificateAuthorities:
+ var auths cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&auths) || auths.Empty() {
+ return false
+ }
+ for !auths.Empty() {
+ var ca []byte
+ if !readUint16LengthPrefixed(&auths, &ca) || len(ca) == 0 {
+ return false
+ }
+ m.certificateAuthorities = append(m.certificateAuthorities, ca)
+ }
+ default:
+ // Ignore unknown extensions.
+ continue
+ }
+
+ if !extData.Empty() {
+ return false
+ }
+ }
+
+ return true
+}
+
+type certificateMsg struct {
+ raw []byte
+ certificates [][]byte
+}
+
+func (m *certificateMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var i int
+ for _, slice := range m.certificates {
+ i += len(slice)
+ }
+
+ length := 3 + 3*len(m.certificates) + i
+ x := make([]byte, 4+length)
+ x[0] = typeCertificate
+ x[1] = uint8(length >> 16)
+ x[2] = uint8(length >> 8)
+ x[3] = uint8(length)
+
+ certificateOctets := length - 3
+ x[4] = uint8(certificateOctets >> 16)
+ x[5] = uint8(certificateOctets >> 8)
+ x[6] = uint8(certificateOctets)
+
+ y := x[7:]
+ for _, slice := range m.certificates {
+ y[0] = uint8(len(slice) >> 16)
+ y[1] = uint8(len(slice) >> 8)
+ y[2] = uint8(len(slice))
+ copy(y[3:], slice)
+ y = y[3+len(slice):]
+ }
+
+ m.raw = x
+ return m.raw, nil
+}
+
+func (m *certificateMsg) unmarshal(data []byte) bool {
+ if len(data) < 7 {
+ return false
+ }
+
+ m.raw = data
+ certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
+ if uint32(len(data)) != certsLen+7 {
+ return false
+ }
+
+ numCerts := 0
+ d := data[7:]
+ for certsLen > 0 {
+ if len(d) < 4 {
+ return false
+ }
+ certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
+ if uint32(len(d)) < 3+certLen {
+ return false
+ }
+ d = d[3+certLen:]
+ certsLen -= 3 + certLen
+ numCerts++
+ }
+
+ m.certificates = make([][]byte, numCerts)
+ d = data[7:]
+ for i := 0; i < numCerts; i++ {
+ certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
+ m.certificates[i] = d[3 : 3+certLen]
+ d = d[3+certLen:]
+ }
+
+ return true
+}
+
+type certificateMsgTLS13 struct {
+ raw []byte
+ certificate Certificate
+ ocspStapling bool
+ scts bool
+}
+
+func (m *certificateMsgTLS13) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeCertificate)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint8(0) // certificate_request_context
+
+ certificate := m.certificate
+ if !m.ocspStapling {
+ certificate.OCSPStaple = nil
+ }
+ if !m.scts {
+ certificate.SignedCertificateTimestamps = nil
+ }
+ marshalCertificate(b, certificate)
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) {
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ for i, cert := range certificate.Certificate {
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(cert)
+ })
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ if i > 0 {
+ // This library only supports OCSP and SCT for leaf certificates.
+ return
+ }
+ if certificate.OCSPStaple != nil {
+ b.AddUint16(extensionStatusRequest)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint8(statusTypeOCSP)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(certificate.OCSPStaple)
+ })
+ })
+ }
+ if certificate.SignedCertificateTimestamps != nil {
+ b.AddUint16(extensionSCT)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, sct := range certificate.SignedCertificateTimestamps {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(sct)
+ })
+ }
+ })
+ })
+ }
+ })
+ }
+ })
+}
+
+func (m *certificateMsgTLS13) unmarshal(data []byte) bool {
+ *m = certificateMsgTLS13{raw: data}
+ s := cryptobyte.String(data)
+
+ var context cryptobyte.String
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||
+ !unmarshalCertificate(&s, &m.certificate) ||
+ !s.Empty() {
+ return false
+ }
+
+ m.scts = m.certificate.SignedCertificateTimestamps != nil
+ m.ocspStapling = m.certificate.OCSPStaple != nil
+
+ return true
+}
+
+func unmarshalCertificate(s *cryptobyte.String, certificate *Certificate) bool {
+ var certList cryptobyte.String
+ if !s.ReadUint24LengthPrefixed(&certList) {
+ return false
+ }
+ for !certList.Empty() {
+ var cert []byte
+ var extensions cryptobyte.String
+ if !readUint24LengthPrefixed(&certList, &cert) ||
+ !certList.ReadUint16LengthPrefixed(&extensions) {
+ return false
+ }
+ certificate.Certificate = append(certificate.Certificate, cert)
+ for !extensions.Empty() {
+ var extension uint16
+ var extData cryptobyte.String
+ if !extensions.ReadUint16(&extension) ||
+ !extensions.ReadUint16LengthPrefixed(&extData) {
+ return false
+ }
+ if len(certificate.Certificate) > 1 {
+ // This library only supports OCSP and SCT for leaf certificates.
+ continue
+ }
+
+ switch extension {
+ case extensionStatusRequest:
+ var statusType uint8
+ if !extData.ReadUint8(&statusType) || statusType != statusTypeOCSP ||
+ !readUint24LengthPrefixed(&extData, &certificate.OCSPStaple) ||
+ len(certificate.OCSPStaple) == 0 {
+ return false
+ }
+ case extensionSCT:
+ var sctList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {
+ return false
+ }
+ for !sctList.Empty() {
+ var sct []byte
+ if !readUint16LengthPrefixed(&sctList, &sct) ||
+ len(sct) == 0 {
+ return false
+ }
+ certificate.SignedCertificateTimestamps = append(
+ certificate.SignedCertificateTimestamps, sct)
+ }
+ default:
+ // Ignore unknown extensions.
+ continue
+ }
+
+ if !extData.Empty() {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+type serverKeyExchangeMsg struct {
+ raw []byte
+ key []byte
+}
+
+func (m *serverKeyExchangeMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+ length := len(m.key)
+ x := make([]byte, length+4)
+ x[0] = typeServerKeyExchange
+ x[1] = uint8(length >> 16)
+ x[2] = uint8(length >> 8)
+ x[3] = uint8(length)
+ copy(x[4:], m.key)
+
+ m.raw = x
+ return x, nil
+}
+
+func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
+ m.raw = data
+ if len(data) < 4 {
+ return false
+ }
+ m.key = data[4:]
+ return true
+}
+
+type certificateStatusMsg struct {
+ raw []byte
+ response []byte
+}
+
+func (m *certificateStatusMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeCertificateStatus)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint8(statusTypeOCSP)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.response)
+ })
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *certificateStatusMsg) unmarshal(data []byte) bool {
+ m.raw = data
+ s := cryptobyte.String(data)
+
+ var statusType uint8
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint8(&statusType) || statusType != statusTypeOCSP ||
+ !readUint24LengthPrefixed(&s, &m.response) ||
+ len(m.response) == 0 || !s.Empty() {
+ return false
+ }
+ return true
+}
+
+type serverHelloDoneMsg struct{}
+
+func (m *serverHelloDoneMsg) marshal() ([]byte, error) {
+ x := make([]byte, 4)
+ x[0] = typeServerHelloDone
+ return x, nil
+}
+
+func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
+ return len(data) == 4
+}
+
+type clientKeyExchangeMsg struct {
+ raw []byte
+ ciphertext []byte
+}
+
+func (m *clientKeyExchangeMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+ length := len(m.ciphertext)
+ x := make([]byte, length+4)
+ x[0] = typeClientKeyExchange
+ x[1] = uint8(length >> 16)
+ x[2] = uint8(length >> 8)
+ x[3] = uint8(length)
+ copy(x[4:], m.ciphertext)
+
+ m.raw = x
+ return x, nil
+}
+
+func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
+ m.raw = data
+ if len(data) < 4 {
+ return false
+ }
+ l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
+ if l != len(data)-4 {
+ return false
+ }
+ m.ciphertext = data[4:]
+ return true
+}
+
+type finishedMsg struct {
+ raw []byte
+ verifyData []byte
+}
+
+func (m *finishedMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeFinished)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.verifyData)
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *finishedMsg) unmarshal(data []byte) bool {
+ m.raw = data
+ s := cryptobyte.String(data)
+ return s.Skip(1) &&
+ readUint24LengthPrefixed(&s, &m.verifyData) &&
+ s.Empty()
+}
+
+type certificateRequestMsg struct {
+ raw []byte
+ // hasSignatureAlgorithm indicates whether this message includes a list of
+ // supported signature algorithms. This change was introduced with TLS 1.2.
+ hasSignatureAlgorithm bool
+
+ certificateTypes []byte
+ supportedSignatureAlgorithms []SignatureScheme
+ certificateAuthorities [][]byte
+}
+
+func (m *certificateRequestMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ // See RFC 4346, Section 7.4.4.
+ length := 1 + len(m.certificateTypes) + 2
+ casLength := 0
+ for _, ca := range m.certificateAuthorities {
+ casLength += 2 + len(ca)
+ }
+ length += casLength
+
+ if m.hasSignatureAlgorithm {
+ length += 2 + 2*len(m.supportedSignatureAlgorithms)
+ }
+
+ x := make([]byte, 4+length)
+ x[0] = typeCertificateRequest
+ x[1] = uint8(length >> 16)
+ x[2] = uint8(length >> 8)
+ x[3] = uint8(length)
+
+ x[4] = uint8(len(m.certificateTypes))
+
+ copy(x[5:], m.certificateTypes)
+ y := x[5+len(m.certificateTypes):]
+
+ if m.hasSignatureAlgorithm {
+ n := len(m.supportedSignatureAlgorithms) * 2
+ y[0] = uint8(n >> 8)
+ y[1] = uint8(n)
+ y = y[2:]
+ for _, sigAlgo := range m.supportedSignatureAlgorithms {
+ y[0] = uint8(sigAlgo >> 8)
+ y[1] = uint8(sigAlgo)
+ y = y[2:]
+ }
+ }
+
+ y[0] = uint8(casLength >> 8)
+ y[1] = uint8(casLength)
+ y = y[2:]
+ for _, ca := range m.certificateAuthorities {
+ y[0] = uint8(len(ca) >> 8)
+ y[1] = uint8(len(ca))
+ y = y[2:]
+ copy(y, ca)
+ y = y[len(ca):]
+ }
+
+ m.raw = x
+ return m.raw, nil
+}
+
+func (m *certificateRequestMsg) unmarshal(data []byte) bool {
+ m.raw = data
+
+ if len(data) < 5 {
+ return false
+ }
+
+ length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
+ if uint32(len(data))-4 != length {
+ return false
+ }
+
+ numCertTypes := int(data[4])
+ data = data[5:]
+ if numCertTypes == 0 || len(data) <= numCertTypes {
+ return false
+ }
+
+ m.certificateTypes = make([]byte, numCertTypes)
+ if copy(m.certificateTypes, data) != numCertTypes {
+ return false
+ }
+
+ data = data[numCertTypes:]
+
+ if m.hasSignatureAlgorithm {
+ if len(data) < 2 {
+ return false
+ }
+ sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
+ data = data[2:]
+ if sigAndHashLen&1 != 0 {
+ return false
+ }
+ if len(data) < int(sigAndHashLen) {
+ return false
+ }
+ numSigAlgos := sigAndHashLen / 2
+ m.supportedSignatureAlgorithms = make([]SignatureScheme, numSigAlgos)
+ for i := range m.supportedSignatureAlgorithms {
+ m.supportedSignatureAlgorithms[i] = SignatureScheme(data[0])<<8 | SignatureScheme(data[1])
+ data = data[2:]
+ }
+ }
+
+ if len(data) < 2 {
+ return false
+ }
+ casLength := uint16(data[0])<<8 | uint16(data[1])
+ data = data[2:]
+ if len(data) < int(casLength) {
+ return false
+ }
+ cas := make([]byte, casLength)
+ copy(cas, data)
+ data = data[casLength:]
+
+ m.certificateAuthorities = nil
+ for len(cas) > 0 {
+ if len(cas) < 2 {
+ return false
+ }
+ caLen := uint16(cas[0])<<8 | uint16(cas[1])
+ cas = cas[2:]
+
+ if len(cas) < int(caLen) {
+ return false
+ }
+
+ m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
+ cas = cas[caLen:]
+ }
+
+ return len(data) == 0
+}
+
+type certificateVerifyMsg struct {
+ raw []byte
+ hasSignatureAlgorithm bool // format change introduced in TLS 1.2
+ signatureAlgorithm SignatureScheme
+ signature []byte
+}
+
+func (m *certificateVerifyMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeCertificateVerify)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ if m.hasSignatureAlgorithm {
+ b.AddUint16(uint16(m.signatureAlgorithm))
+ }
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.signature)
+ })
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
+ m.raw = data
+ s := cryptobyte.String(data)
+
+ if !s.Skip(4) { // message type and uint24 length field
+ return false
+ }
+ if m.hasSignatureAlgorithm {
+ if !s.ReadUint16((*uint16)(&m.signatureAlgorithm)) {
+ return false
+ }
+ }
+ return readUint16LengthPrefixed(&s, &m.signature) && s.Empty()
+}
+
+type newSessionTicketMsg struct {
+ raw []byte
+ ticket []byte
+}
+
+func (m *newSessionTicketMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ // See RFC 5077, Section 3.3.
+ ticketLen := len(m.ticket)
+ length := 2 + 4 + ticketLen
+ x := make([]byte, 4+length)
+ x[0] = typeNewSessionTicket
+ x[1] = uint8(length >> 16)
+ x[2] = uint8(length >> 8)
+ x[3] = uint8(length)
+ x[8] = uint8(ticketLen >> 8)
+ x[9] = uint8(ticketLen)
+ copy(x[10:], m.ticket)
+
+ m.raw = x
+
+ return m.raw, nil
+}
+
+func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
+ m.raw = data
+
+ if len(data) < 10 {
+ return false
+ }
+
+ length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
+ if uint32(len(data))-4 != length {
+ return false
+ }
+
+ ticketLen := int(data[8])<<8 + int(data[9])
+ if len(data)-10 != ticketLen {
+ return false
+ }
+
+ m.ticket = data[10:]
+
+ return true
+}
+
+type helloRequestMsg struct {
+}
+
+func (*helloRequestMsg) marshal() ([]byte, error) {
+ return []byte{typeHelloRequest, 0, 0, 0}, nil
+}
+
+func (*helloRequestMsg) unmarshal(data []byte) bool {
+ return len(data) == 4
+}
+
+type transcriptHash interface {
+ Write([]byte) (int, error)
+}
+
+// transcriptMsg is a helper used to marshal and hash messages which typically
+// are not written to the wire, and as such aren't hashed during Conn.writeRecord.
+func transcriptMsg(msg handshakeMessage, h transcriptHash) error {
+ data, err := msg.marshal()
+ if err != nil {
+ return err
+ }
+ h.Write(data)
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/crypto/tls/handshake_server.go b/contrib/go/_std_1.21/src/crypto/tls/handshake_server.go
new file mode 100644
index 0000000000..996b23b1f5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/handshake_server.go
@@ -0,0 +1,954 @@
+// Copyright 2009 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 tls
+
+import (
+ "context"
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "crypto/subtle"
+ "crypto/x509"
+ "errors"
+ "fmt"
+ "hash"
+ "io"
+ "time"
+)
+
+// serverHandshakeState contains details of a server handshake in progress.
+// It's discarded once the handshake has completed.
+type serverHandshakeState struct {
+ c *Conn
+ ctx context.Context
+ clientHello *clientHelloMsg
+ hello *serverHelloMsg
+ suite *cipherSuite
+ ecdheOk bool
+ ecSignOk bool
+ rsaDecryptOk bool
+ rsaSignOk bool
+ sessionState *SessionState
+ finishedHash finishedHash
+ masterSecret []byte
+ cert *Certificate
+}
+
+// serverHandshake performs a TLS handshake as a server.
+func (c *Conn) serverHandshake(ctx context.Context) error {
+ clientHello, err := c.readClientHello(ctx)
+ if err != nil {
+ return err
+ }
+
+ if c.vers == VersionTLS13 {
+ hs := serverHandshakeStateTLS13{
+ c: c,
+ ctx: ctx,
+ clientHello: clientHello,
+ }
+ return hs.handshake()
+ }
+
+ hs := serverHandshakeState{
+ c: c,
+ ctx: ctx,
+ clientHello: clientHello,
+ }
+ return hs.handshake()
+}
+
+func (hs *serverHandshakeState) handshake() error {
+ c := hs.c
+
+ if err := hs.processClientHello(); err != nil {
+ return err
+ }
+
+ // For an overview of TLS handshaking, see RFC 5246, Section 7.3.
+ c.buffering = true
+ if err := hs.checkForResumption(); err != nil {
+ return err
+ }
+ if hs.sessionState != nil {
+ // The client has included a session ticket and so we do an abbreviated handshake.
+ if err := hs.doResumeHandshake(); err != nil {
+ return err
+ }
+ if err := hs.establishKeys(); err != nil {
+ return err
+ }
+ if err := hs.sendSessionTicket(); err != nil {
+ return err
+ }
+ if err := hs.sendFinished(c.serverFinished[:]); err != nil {
+ return err
+ }
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+ c.clientFinishedIsFirst = false
+ if err := hs.readFinished(nil); err != nil {
+ return err
+ }
+ } else {
+ // The client didn't include a session ticket, or it wasn't
+ // valid so we do a full handshake.
+ if err := hs.pickCipherSuite(); err != nil {
+ return err
+ }
+ if err := hs.doFullHandshake(); err != nil {
+ return err
+ }
+ if err := hs.establishKeys(); err != nil {
+ return err
+ }
+ if err := hs.readFinished(c.clientFinished[:]); err != nil {
+ return err
+ }
+ c.clientFinishedIsFirst = true
+ c.buffering = true
+ if err := hs.sendSessionTicket(); err != nil {
+ return err
+ }
+ if err := hs.sendFinished(nil); err != nil {
+ return err
+ }
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+ }
+
+ c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random)
+ c.isHandshakeComplete.Store(true)
+
+ return nil
+}
+
+// readClientHello reads a ClientHello message and selects the protocol version.
+func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
+ // clientHelloMsg is included in the transcript, but we haven't initialized
+ // it yet. The respective handshake functions will record it themselves.
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return nil, err
+ }
+ clientHello, ok := msg.(*clientHelloMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return nil, unexpectedMessageError(clientHello, msg)
+ }
+
+ var configForClient *Config
+ originalConfig := c.config
+ if c.config.GetConfigForClient != nil {
+ chi := clientHelloInfo(ctx, c, clientHello)
+ if configForClient, err = c.config.GetConfigForClient(chi); err != nil {
+ c.sendAlert(alertInternalError)
+ return nil, err
+ } else if configForClient != nil {
+ c.config = configForClient
+ }
+ }
+ c.ticketKeys = originalConfig.ticketKeys(configForClient)
+
+ clientVersions := clientHello.supportedVersions
+ if len(clientHello.supportedVersions) == 0 {
+ clientVersions = supportedVersionsFromMax(clientHello.vers)
+ }
+ c.vers, ok = c.config.mutualVersion(roleServer, clientVersions)
+ if !ok {
+ c.sendAlert(alertProtocolVersion)
+ return nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions)
+ }
+ c.haveVers = true
+ c.in.version = c.vers
+ c.out.version = c.vers
+
+ return clientHello, nil
+}
+
+func (hs *serverHandshakeState) processClientHello() error {
+ c := hs.c
+
+ hs.hello = new(serverHelloMsg)
+ hs.hello.vers = c.vers
+
+ foundCompression := false
+ // We only support null compression, so check that the client offered it.
+ for _, compression := range hs.clientHello.compressionMethods {
+ if compression == compressionNone {
+ foundCompression = true
+ break
+ }
+ }
+
+ if !foundCompression {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: client does not support uncompressed connections")
+ }
+
+ hs.hello.random = make([]byte, 32)
+ serverRandom := hs.hello.random
+ // Downgrade protection canaries. See RFC 8446, Section 4.1.3.
+ maxVers := c.config.maxSupportedVersion(roleServer)
+ if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary {
+ if c.vers == VersionTLS12 {
+ copy(serverRandom[24:], downgradeCanaryTLS12)
+ } else {
+ copy(serverRandom[24:], downgradeCanaryTLS11)
+ }
+ serverRandom = serverRandom[:24]
+ }
+ _, err := io.ReadFull(c.config.rand(), serverRandom)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ if len(hs.clientHello.secureRenegotiation) != 0 {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: initial handshake had non-empty renegotiation extension")
+ }
+
+ hs.hello.extendedMasterSecret = hs.clientHello.extendedMasterSecret
+ hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported
+ hs.hello.compressionMethod = compressionNone
+ if len(hs.clientHello.serverName) > 0 {
+ c.serverName = hs.clientHello.serverName
+ }
+
+ selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols, false)
+ if err != nil {
+ c.sendAlert(alertNoApplicationProtocol)
+ return err
+ }
+ hs.hello.alpnProtocol = selectedProto
+ c.clientProtocol = selectedProto
+
+ hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
+ if err != nil {
+ if err == errNoCertificates {
+ c.sendAlert(alertUnrecognizedName)
+ } else {
+ c.sendAlert(alertInternalError)
+ }
+ return err
+ }
+ if hs.clientHello.scts {
+ hs.hello.scts = hs.cert.SignedCertificateTimestamps
+ }
+
+ hs.ecdheOk = supportsECDHE(c.config, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints)
+
+ if hs.ecdheOk && len(hs.clientHello.supportedPoints) > 0 {
+ // Although omitting the ec_point_formats extension is permitted, some
+ // old OpenSSL version will refuse to handshake if not present.
+ //
+ // Per RFC 4492, section 5.1.2, implementations MUST support the
+ // uncompressed point format. See golang.org/issue/31943.
+ hs.hello.supportedPoints = []uint8{pointFormatUncompressed}
+ }
+
+ if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok {
+ switch priv.Public().(type) {
+ case *ecdsa.PublicKey:
+ hs.ecSignOk = true
+ case ed25519.PublicKey:
+ hs.ecSignOk = true
+ case *rsa.PublicKey:
+ hs.rsaSignOk = true
+ default:
+ c.sendAlert(alertInternalError)
+ return fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public())
+ }
+ }
+ if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok {
+ switch priv.Public().(type) {
+ case *rsa.PublicKey:
+ hs.rsaDecryptOk = true
+ default:
+ c.sendAlert(alertInternalError)
+ return fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public())
+ }
+ }
+
+ return nil
+}
+
+// negotiateALPN picks a shared ALPN protocol that both sides support in server
+// preference order. If ALPN is not configured or the peer doesn't support it,
+// it returns "" and no error.
+func negotiateALPN(serverProtos, clientProtos []string, quic bool) (string, error) {
+ if len(serverProtos) == 0 || len(clientProtos) == 0 {
+ if quic && len(serverProtos) != 0 {
+ // RFC 9001, Section 8.1
+ return "", fmt.Errorf("tls: client did not request an application protocol")
+ }
+ return "", nil
+ }
+ var http11fallback bool
+ for _, s := range serverProtos {
+ for _, c := range clientProtos {
+ if s == c {
+ return s, nil
+ }
+ if s == "h2" && c == "http/1.1" {
+ http11fallback = true
+ }
+ }
+ }
+ // As a special case, let http/1.1 clients connect to h2 servers as if they
+ // didn't support ALPN. We used not to enforce protocol overlap, so over
+ // time a number of HTTP servers were configured with only "h2", but
+ // expected to accept connections from "http/1.1" clients. See Issue 46310.
+ if http11fallback {
+ return "", nil
+ }
+ return "", fmt.Errorf("tls: client requested unsupported application protocols (%s)", clientProtos)
+}
+
+// supportsECDHE returns whether ECDHE key exchanges can be used with this
+// pre-TLS 1.3 client.
+func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8) bool {
+ supportsCurve := false
+ for _, curve := range supportedCurves {
+ if c.supportsCurve(curve) {
+ supportsCurve = true
+ break
+ }
+ }
+
+ supportsPointFormat := false
+ for _, pointFormat := range supportedPoints {
+ if pointFormat == pointFormatUncompressed {
+ supportsPointFormat = true
+ break
+ }
+ }
+ // Per RFC 8422, Section 5.1.2, if the Supported Point Formats extension is
+ // missing, uncompressed points are supported. If supportedPoints is empty,
+ // the extension must be missing, as an empty extension body is rejected by
+ // the parser. See https://go.dev/issue/49126.
+ if len(supportedPoints) == 0 {
+ supportsPointFormat = true
+ }
+
+ return supportsCurve && supportsPointFormat
+}
+
+func (hs *serverHandshakeState) pickCipherSuite() error {
+ c := hs.c
+
+ preferenceOrder := cipherSuitesPreferenceOrder
+ if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
+ preferenceOrder = cipherSuitesPreferenceOrderNoAES
+ }
+
+ configCipherSuites := c.config.cipherSuites()
+ preferenceList := make([]uint16, 0, len(configCipherSuites))
+ for _, suiteID := range preferenceOrder {
+ for _, id := range configCipherSuites {
+ if id == suiteID {
+ preferenceList = append(preferenceList, id)
+ break
+ }
+ }
+ }
+
+ hs.suite = selectCipherSuite(preferenceList, hs.clientHello.cipherSuites, hs.cipherSuiteOk)
+ if hs.suite == nil {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: no cipher suite supported by both client and server")
+ }
+ c.cipherSuite = hs.suite.id
+
+ for _, id := range hs.clientHello.cipherSuites {
+ if id == TLS_FALLBACK_SCSV {
+ // The client is doing a fallback connection. See RFC 7507.
+ if hs.clientHello.vers < c.config.maxSupportedVersion(roleServer) {
+ c.sendAlert(alertInappropriateFallback)
+ return errors.New("tls: client using inappropriate protocol fallback")
+ }
+ break
+ }
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool {
+ if c.flags&suiteECDHE != 0 {
+ if !hs.ecdheOk {
+ return false
+ }
+ if c.flags&suiteECSign != 0 {
+ if !hs.ecSignOk {
+ return false
+ }
+ } else if !hs.rsaSignOk {
+ return false
+ }
+ } else if !hs.rsaDecryptOk {
+ return false
+ }
+ if hs.c.vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
+ return false
+ }
+ return true
+}
+
+// checkForResumption reports whether we should perform resumption on this connection.
+func (hs *serverHandshakeState) checkForResumption() error {
+ c := hs.c
+
+ if c.config.SessionTicketsDisabled {
+ return nil
+ }
+
+ var sessionState *SessionState
+ if c.config.UnwrapSession != nil {
+ ss, err := c.config.UnwrapSession(hs.clientHello.sessionTicket, c.connectionStateLocked())
+ if err != nil {
+ return err
+ }
+ if ss == nil {
+ return nil
+ }
+ sessionState = ss
+ } else {
+ plaintext := c.config.decryptTicket(hs.clientHello.sessionTicket, c.ticketKeys)
+ if plaintext == nil {
+ return nil
+ }
+ ss, err := ParseSessionState(plaintext)
+ if err != nil {
+ return nil
+ }
+ sessionState = ss
+ }
+
+ // TLS 1.2 tickets don't natively have a lifetime, but we want to avoid
+ // re-wrapping the same master secret in different tickets over and over for
+ // too long, weakening forward secrecy.
+ createdAt := time.Unix(int64(sessionState.createdAt), 0)
+ if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
+ return nil
+ }
+
+ // Never resume a session for a different TLS version.
+ if c.vers != sessionState.version {
+ return nil
+ }
+
+ cipherSuiteOk := false
+ // Check that the client is still offering the ciphersuite in the session.
+ for _, id := range hs.clientHello.cipherSuites {
+ if id == sessionState.cipherSuite {
+ cipherSuiteOk = true
+ break
+ }
+ }
+ if !cipherSuiteOk {
+ return nil
+ }
+
+ // Check that we also support the ciphersuite from the session.
+ suite := selectCipherSuite([]uint16{sessionState.cipherSuite},
+ c.config.cipherSuites(), hs.cipherSuiteOk)
+ if suite == nil {
+ return nil
+ }
+
+ sessionHasClientCerts := len(sessionState.peerCertificates) != 0
+ needClientCerts := requiresClientCert(c.config.ClientAuth)
+ if needClientCerts && !sessionHasClientCerts {
+ return nil
+ }
+ if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
+ return nil
+ }
+ if sessionHasClientCerts && c.config.time().After(sessionState.peerCertificates[0].NotAfter) {
+ return nil
+ }
+ if sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven &&
+ len(sessionState.verifiedChains) == 0 {
+ return nil
+ }
+
+ // RFC 7627, Section 5.3
+ if !sessionState.extMasterSecret && hs.clientHello.extendedMasterSecret {
+ return nil
+ }
+ if sessionState.extMasterSecret && !hs.clientHello.extendedMasterSecret {
+ // Aborting is somewhat harsh, but it's a MUST and it would indicate a
+ // weird downgrade in client capabilities.
+ return errors.New("tls: session supported extended_master_secret but client does not")
+ }
+
+ c.peerCertificates = sessionState.peerCertificates
+ c.ocspResponse = sessionState.ocspResponse
+ c.scts = sessionState.scts
+ c.verifiedChains = sessionState.verifiedChains
+ c.extMasterSecret = sessionState.extMasterSecret
+ hs.sessionState = sessionState
+ hs.suite = suite
+ c.didResume = true
+ return nil
+}
+
+func (hs *serverHandshakeState) doResumeHandshake() error {
+ c := hs.c
+
+ hs.hello.cipherSuite = hs.suite.id
+ c.cipherSuite = hs.suite.id
+ // We echo the client's session ID in the ServerHello to let it know
+ // that we're doing a resumption.
+ hs.hello.sessionId = hs.clientHello.sessionId
+ // We always send a new session ticket, even if it wraps the same master
+ // secret and it's potentially encrypted with the same key, to help the
+ // client avoid cross-connection tracking from a network observer.
+ hs.hello.ticketSupported = true
+ hs.finishedHash = newFinishedHash(c.vers, hs.suite)
+ hs.finishedHash.discardHandshakeBuffer()
+ if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil {
+ return err
+ }
+ if _, err := hs.c.writeHandshakeRecord(hs.hello, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+
+ hs.masterSecret = hs.sessionState.secret
+
+ return nil
+}
+
+func (hs *serverHandshakeState) doFullHandshake() error {
+ c := hs.c
+
+ if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
+ hs.hello.ocspStapling = true
+ }
+
+ hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled
+ hs.hello.cipherSuite = hs.suite.id
+
+ hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite)
+ if c.config.ClientAuth == NoClientCert {
+ // No need to keep a full record of the handshake if client
+ // certificates won't be used.
+ hs.finishedHash.discardHandshakeBuffer()
+ }
+ if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil {
+ return err
+ }
+ if _, err := hs.c.writeHandshakeRecord(hs.hello, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ certMsg := new(certificateMsg)
+ certMsg.certificates = hs.cert.Certificate
+ if _, err := hs.c.writeHandshakeRecord(certMsg, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ if hs.hello.ocspStapling {
+ certStatus := new(certificateStatusMsg)
+ certStatus.response = hs.cert.OCSPStaple
+ if _, err := hs.c.writeHandshakeRecord(certStatus, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ keyAgreement := hs.suite.ka(c.vers)
+ skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert, hs.clientHello, hs.hello)
+ if err != nil {
+ c.sendAlert(alertHandshakeFailure)
+ return err
+ }
+ if skx != nil {
+ if _, err := hs.c.writeHandshakeRecord(skx, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ var certReq *certificateRequestMsg
+ if c.config.ClientAuth >= RequestClientCert {
+ // Request a client certificate
+ certReq = new(certificateRequestMsg)
+ certReq.certificateTypes = []byte{
+ byte(certTypeRSASign),
+ byte(certTypeECDSASign),
+ }
+ if c.vers >= VersionTLS12 {
+ certReq.hasSignatureAlgorithm = true
+ certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+ }
+
+ // An empty list of certificateAuthorities signals to
+ // the client that it may send any certificate in response
+ // to our request. When we know the CAs we trust, then
+ // we can send them down, so that the client can choose
+ // an appropriate certificate to give to us.
+ if c.config.ClientCAs != nil {
+ certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
+ }
+ if _, err := hs.c.writeHandshakeRecord(certReq, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ helloDone := new(serverHelloDoneMsg)
+ if _, err := hs.c.writeHandshakeRecord(helloDone, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+
+ var pub crypto.PublicKey // public key for client auth, if any
+
+ msg, err := c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+
+ // If we requested a client certificate, then the client must send a
+ // certificate message, even if it's empty.
+ if c.config.ClientAuth >= RequestClientCert {
+ certMsg, ok := msg.(*certificateMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certMsg, msg)
+ }
+
+ if err := c.processCertsFromClient(Certificate{
+ Certificate: certMsg.certificates,
+ }); err != nil {
+ return err
+ }
+ if len(certMsg.certificates) != 0 {
+ pub = c.peerCertificates[0].PublicKey
+ }
+
+ msg, err = c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+ }
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+
+ // Get client key exchange
+ ckx, ok := msg.(*clientKeyExchangeMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(ckx, msg)
+ }
+
+ preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers)
+ if err != nil {
+ c.sendAlert(alertHandshakeFailure)
+ return err
+ }
+ if hs.hello.extendedMasterSecret {
+ c.extMasterSecret = true
+ hs.masterSecret = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret,
+ hs.finishedHash.Sum())
+ } else {
+ hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret,
+ hs.clientHello.random, hs.hello.random)
+ }
+ if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ // If we received a client cert in response to our certificate request message,
+ // the client will send us a certificateVerifyMsg immediately after the
+ // clientKeyExchangeMsg. This message is a digest of all preceding
+ // handshake-layer messages that is signed using the private key corresponding
+ // to the client's certificate. This allows us to verify that the client is in
+ // possession of the private key of the certificate.
+ if len(c.peerCertificates) > 0 {
+ // certificateVerifyMsg is included in the transcript, but not until
+ // after we verify the handshake signature, since the state before
+ // this message was sent is used.
+ msg, err = c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+ certVerify, ok := msg.(*certificateVerifyMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certVerify, msg)
+ }
+
+ var sigType uint8
+ var sigHash crypto.Hash
+ if c.vers >= VersionTLS12 {
+ if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client certificate used with invalid signature algorithm")
+ }
+ sigType, sigHash, err = typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
+ if err != nil {
+ return c.sendAlert(alertInternalError)
+ }
+ } else {
+ sigType, sigHash, err = legacyTypeAndHashFromPublicKey(pub)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return err
+ }
+ }
+
+ signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash)
+ if err := verifyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil {
+ c.sendAlert(alertDecryptError)
+ return errors.New("tls: invalid signature by the client certificate: " + err.Error())
+ }
+
+ if err := transcriptMsg(certVerify, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ hs.finishedHash.discardHandshakeBuffer()
+
+ return nil
+}
+
+func (hs *serverHandshakeState) establishKeys() error {
+ c := hs.c
+
+ clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
+ keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
+
+ var clientCipher, serverCipher any
+ var clientHash, serverHash hash.Hash
+
+ if hs.suite.aead == nil {
+ clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
+ clientHash = hs.suite.mac(clientMAC)
+ serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
+ serverHash = hs.suite.mac(serverMAC)
+ } else {
+ clientCipher = hs.suite.aead(clientKey, clientIV)
+ serverCipher = hs.suite.aead(serverKey, serverIV)
+ }
+
+ c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
+ c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
+
+ return nil
+}
+
+func (hs *serverHandshakeState) readFinished(out []byte) error {
+ c := hs.c
+
+ if err := c.readChangeCipherSpec(); err != nil {
+ return err
+ }
+
+ // finishedMsg is included in the transcript, but not until after we
+ // check the client version, since the state before this message was
+ // sent is used during verification.
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+ clientFinished, ok := msg.(*finishedMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(clientFinished, msg)
+ }
+
+ verify := hs.finishedHash.clientSum(hs.masterSecret)
+ if len(verify) != len(clientFinished.verifyData) ||
+ subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: client's Finished message is incorrect")
+ }
+
+ if err := transcriptMsg(clientFinished, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ copy(out, verify)
+ return nil
+}
+
+func (hs *serverHandshakeState) sendSessionTicket() error {
+ if !hs.hello.ticketSupported {
+ return nil
+ }
+
+ c := hs.c
+ m := new(newSessionTicketMsg)
+
+ state, err := c.sessionState()
+ if err != nil {
+ return err
+ }
+ state.secret = hs.masterSecret
+ if hs.sessionState != nil {
+ // If this is re-wrapping an old key, then keep
+ // the original time it was created.
+ state.createdAt = hs.sessionState.createdAt
+ }
+ if c.config.WrapSession != nil {
+ m.ticket, err = c.config.WrapSession(c.connectionStateLocked(), state)
+ if err != nil {
+ return err
+ }
+ } else {
+ stateBytes, err := state.Bytes()
+ if err != nil {
+ return err
+ }
+ m.ticket, err = c.config.encryptTicket(stateBytes, c.ticketKeys)
+ if err != nil {
+ return err
+ }
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(m, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeState) sendFinished(out []byte) error {
+ c := hs.c
+
+ if err := c.writeChangeCipherRecord(); err != nil {
+ return err
+ }
+
+ finished := new(finishedMsg)
+ finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
+ if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ copy(out, finished.verifyData)
+
+ return nil
+}
+
+// processCertsFromClient takes a chain of client certificates either from a
+// Certificates message and verifies them.
+func (c *Conn) processCertsFromClient(certificate Certificate) error {
+ certificates := certificate.Certificate
+ certs := make([]*x509.Certificate, len(certificates))
+ var err error
+ for i, asn1Data := range certificates {
+ if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return errors.New("tls: failed to parse client certificate: " + err.Error())
+ }
+ if certs[i].PublicKeyAlgorithm == x509.RSA {
+ n := certs[i].PublicKey.(*rsa.PublicKey).N.BitLen()
+ if max, ok := checkKeySize(n); !ok {
+ c.sendAlert(alertBadCertificate)
+ return fmt.Errorf("tls: client sent certificate containing RSA key larger than %d bits", max)
+ }
+ }
+ }
+
+ if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) {
+ if c.vers == VersionTLS13 {
+ c.sendAlert(alertCertificateRequired)
+ } else {
+ c.sendAlert(alertBadCertificate)
+ }
+ return errors.New("tls: client didn't provide a certificate")
+ }
+
+ if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
+ opts := x509.VerifyOptions{
+ Roots: c.config.ClientCAs,
+ CurrentTime: c.config.time(),
+ Intermediates: x509.NewCertPool(),
+ KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
+ }
+
+ for _, cert := range certs[1:] {
+ opts.Intermediates.AddCert(cert)
+ }
+
+ chains, err := certs[0].Verify(opts)
+ if err != nil {
+ var errCertificateInvalid x509.CertificateInvalidError
+ if errors.As(err, &x509.UnknownAuthorityError{}) {
+ c.sendAlert(alertUnknownCA)
+ } else if errors.As(err, &errCertificateInvalid) && errCertificateInvalid.Reason == x509.Expired {
+ c.sendAlert(alertCertificateExpired)
+ } else {
+ c.sendAlert(alertBadCertificate)
+ }
+ return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
+ }
+
+ c.verifiedChains = chains
+ }
+
+ c.peerCertificates = certs
+ c.ocspResponse = certificate.OCSPStaple
+ c.scts = certificate.SignedCertificateTimestamps
+
+ if len(certs) > 0 {
+ switch certs[0].PublicKey.(type) {
+ case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:
+ default:
+ c.sendAlert(alertUnsupportedCertificate)
+ return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey)
+ }
+ }
+
+ if c.config.VerifyPeerCertificate != nil {
+ if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+
+ return nil
+}
+
+func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
+ supportedVersions := clientHello.supportedVersions
+ if len(clientHello.supportedVersions) == 0 {
+ supportedVersions = supportedVersionsFromMax(clientHello.vers)
+ }
+
+ return &ClientHelloInfo{
+ CipherSuites: clientHello.cipherSuites,
+ ServerName: clientHello.serverName,
+ SupportedCurves: clientHello.supportedCurves,
+ SupportedPoints: clientHello.supportedPoints,
+ SignatureSchemes: clientHello.supportedSignatureAlgorithms,
+ SupportedProtos: clientHello.alpnProtocols,
+ SupportedVersions: supportedVersions,
+ Conn: c.conn,
+ config: c.config,
+ ctx: ctx,
+ }
+}
diff --git a/contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go b/contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go
new file mode 100644
index 0000000000..07b1a3851e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/handshake_server_tls13.go
@@ -0,0 +1,991 @@
+// Copyright 2018 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 tls
+
+import (
+ "bytes"
+ "context"
+ "crypto"
+ "crypto/hmac"
+ "crypto/rsa"
+ "encoding/binary"
+ "errors"
+ "hash"
+ "io"
+ "time"
+)
+
+// maxClientPSKIdentities is the number of client PSK identities the server will
+// attempt to validate. It will ignore the rest not to let cheap ClientHello
+// messages cause too much work in session ticket decryption attempts.
+const maxClientPSKIdentities = 5
+
+type serverHandshakeStateTLS13 struct {
+ c *Conn
+ ctx context.Context
+ clientHello *clientHelloMsg
+ hello *serverHelloMsg
+ sentDummyCCS bool
+ usingPSK bool
+ earlyData bool
+ suite *cipherSuiteTLS13
+ cert *Certificate
+ sigAlg SignatureScheme
+ earlySecret []byte
+ sharedKey []byte
+ handshakeSecret []byte
+ masterSecret []byte
+ trafficSecret []byte // client_application_traffic_secret_0
+ transcript hash.Hash
+ clientFinished []byte
+}
+
+func (hs *serverHandshakeStateTLS13) handshake() error {
+ c := hs.c
+
+ if needFIPS() {
+ return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
+ }
+
+ // For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2.
+ if err := hs.processClientHello(); err != nil {
+ return err
+ }
+ if err := hs.checkForResumption(); err != nil {
+ return err
+ }
+ if err := hs.pickCertificate(); err != nil {
+ return err
+ }
+ c.buffering = true
+ if err := hs.sendServerParameters(); err != nil {
+ return err
+ }
+ if err := hs.sendServerCertificate(); err != nil {
+ return err
+ }
+ if err := hs.sendServerFinished(); err != nil {
+ return err
+ }
+ // Note that at this point we could start sending application data without
+ // waiting for the client's second flight, but the application might not
+ // expect the lack of replay protection of the ClientHello parameters.
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+ if err := hs.readClientCertificate(); err != nil {
+ return err
+ }
+ if err := hs.readClientFinished(); err != nil {
+ return err
+ }
+
+ c.isHandshakeComplete.Store(true)
+
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) processClientHello() error {
+ c := hs.c
+
+ hs.hello = new(serverHelloMsg)
+
+ // TLS 1.3 froze the ServerHello.legacy_version field, and uses
+ // supported_versions instead. See RFC 8446, sections 4.1.3 and 4.2.1.
+ hs.hello.vers = VersionTLS12
+ hs.hello.supportedVersion = c.vers
+
+ if len(hs.clientHello.supportedVersions) == 0 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client used the legacy version field to negotiate TLS 1.3")
+ }
+
+ // Abort if the client is doing a fallback and landing lower than what we
+ // support. See RFC 7507, which however does not specify the interaction
+ // with supported_versions. The only difference is that with
+ // supported_versions a client has a chance to attempt a [TLS 1.2, TLS 1.4]
+ // handshake in case TLS 1.3 is broken but 1.2 is not. Alas, in that case,
+ // it will have to drop the TLS_FALLBACK_SCSV protection if it falls back to
+ // TLS 1.2, because a TLS 1.3 server would abort here. The situation before
+ // supported_versions was not better because there was just no way to do a
+ // TLS 1.4 handshake without risking the server selecting TLS 1.3.
+ for _, id := range hs.clientHello.cipherSuites {
+ if id == TLS_FALLBACK_SCSV {
+ // Use c.vers instead of max(supported_versions) because an attacker
+ // could defeat this by adding an arbitrary high version otherwise.
+ if c.vers < c.config.maxSupportedVersion(roleServer) {
+ c.sendAlert(alertInappropriateFallback)
+ return errors.New("tls: client using inappropriate protocol fallback")
+ }
+ break
+ }
+ }
+
+ if len(hs.clientHello.compressionMethods) != 1 ||
+ hs.clientHello.compressionMethods[0] != compressionNone {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: TLS 1.3 client supports illegal compression methods")
+ }
+
+ hs.hello.random = make([]byte, 32)
+ if _, err := io.ReadFull(c.config.rand(), hs.hello.random); err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ if len(hs.clientHello.secureRenegotiation) != 0 {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: initial handshake had non-empty renegotiation extension")
+ }
+
+ if hs.clientHello.earlyData && c.quic != nil {
+ if len(hs.clientHello.pskIdentities) == 0 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: early_data without pre_shared_key")
+ }
+ } else if hs.clientHello.earlyData {
+ // See RFC 8446, Section 4.2.10 for the complicated behavior required
+ // here. The scenario is that a different server at our address offered
+ // to accept early data in the past, which we can't handle. For now, all
+ // 0-RTT enabled session tickets need to expire before a Go server can
+ // replace a server or join a pool. That's the same requirement that
+ // applies to mixing or replacing with any TLS 1.2 server.
+ c.sendAlert(alertUnsupportedExtension)
+ return errors.New("tls: client sent unexpected early data")
+ }
+
+ hs.hello.sessionId = hs.clientHello.sessionId
+ hs.hello.compressionMethod = compressionNone
+
+ preferenceList := defaultCipherSuitesTLS13
+ if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
+ preferenceList = defaultCipherSuitesTLS13NoAES
+ }
+ for _, suiteID := range preferenceList {
+ hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID)
+ if hs.suite != nil {
+ break
+ }
+ }
+ if hs.suite == nil {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: no cipher suite supported by both client and server")
+ }
+ c.cipherSuite = hs.suite.id
+ hs.hello.cipherSuite = hs.suite.id
+ hs.transcript = hs.suite.hash.New()
+
+ // Pick the ECDHE group in server preference order, but give priority to
+ // groups with a key share, to avoid a HelloRetryRequest round-trip.
+ var selectedGroup CurveID
+ var clientKeyShare *keyShare
+GroupSelection:
+ for _, preferredGroup := range c.config.curvePreferences() {
+ for _, ks := range hs.clientHello.keyShares {
+ if ks.group == preferredGroup {
+ selectedGroup = ks.group
+ clientKeyShare = &ks
+ break GroupSelection
+ }
+ }
+ if selectedGroup != 0 {
+ continue
+ }
+ for _, group := range hs.clientHello.supportedCurves {
+ if group == preferredGroup {
+ selectedGroup = group
+ break
+ }
+ }
+ }
+ if selectedGroup == 0 {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: no ECDHE curve supported by both client and server")
+ }
+ if clientKeyShare == nil {
+ if err := hs.doHelloRetryRequest(selectedGroup); err != nil {
+ return err
+ }
+ clientKeyShare = &hs.clientHello.keyShares[0]
+ }
+
+ if _, ok := curveForCurveID(selectedGroup); !ok {
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: CurvePreferences includes unsupported curve")
+ }
+ key, err := generateECDHEKey(c.config.rand(), selectedGroup)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ hs.hello.serverShare = keyShare{group: selectedGroup, data: key.PublicKey().Bytes()}
+ peerKey, err := key.Curve().NewPublicKey(clientKeyShare.data)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid client key share")
+ }
+ hs.sharedKey, err = key.ECDH(peerKey)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid client key share")
+ }
+
+ selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols, c.quic != nil)
+ if err != nil {
+ c.sendAlert(alertNoApplicationProtocol)
+ return err
+ }
+ c.clientProtocol = selectedProto
+
+ if c.quic != nil {
+ if hs.clientHello.quicTransportParameters == nil {
+ // RFC 9001 Section 8.2.
+ c.sendAlert(alertMissingExtension)
+ return errors.New("tls: client did not send a quic_transport_parameters extension")
+ }
+ c.quicSetTransportParameters(hs.clientHello.quicTransportParameters)
+ } else {
+ if hs.clientHello.quicTransportParameters != nil {
+ c.sendAlert(alertUnsupportedExtension)
+ return errors.New("tls: client sent an unexpected quic_transport_parameters extension")
+ }
+ }
+
+ c.serverName = hs.clientHello.serverName
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) checkForResumption() error {
+ c := hs.c
+
+ if c.config.SessionTicketsDisabled {
+ return nil
+ }
+
+ modeOK := false
+ for _, mode := range hs.clientHello.pskModes {
+ if mode == pskModeDHE {
+ modeOK = true
+ break
+ }
+ }
+ if !modeOK {
+ return nil
+ }
+
+ if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid or missing PSK binders")
+ }
+ if len(hs.clientHello.pskIdentities) == 0 {
+ return nil
+ }
+
+ for i, identity := range hs.clientHello.pskIdentities {
+ if i >= maxClientPSKIdentities {
+ break
+ }
+
+ var sessionState *SessionState
+ if c.config.UnwrapSession != nil {
+ var err error
+ sessionState, err = c.config.UnwrapSession(identity.label, c.connectionStateLocked())
+ if err != nil {
+ return err
+ }
+ if sessionState == nil {
+ continue
+ }
+ } else {
+ plaintext := c.config.decryptTicket(identity.label, c.ticketKeys)
+ if plaintext == nil {
+ continue
+ }
+ var err error
+ sessionState, err = ParseSessionState(plaintext)
+ if err != nil {
+ continue
+ }
+ }
+
+ if sessionState.version != VersionTLS13 {
+ continue
+ }
+
+ createdAt := time.Unix(int64(sessionState.createdAt), 0)
+ if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
+ continue
+ }
+
+ pskSuite := cipherSuiteTLS13ByID(sessionState.cipherSuite)
+ if pskSuite == nil || pskSuite.hash != hs.suite.hash {
+ continue
+ }
+
+ // PSK connections don't re-establish client certificates, but carry
+ // them over in the session ticket. Ensure the presence of client certs
+ // in the ticket is consistent with the configured requirements.
+ sessionHasClientCerts := len(sessionState.peerCertificates) != 0
+ needClientCerts := requiresClientCert(c.config.ClientAuth)
+ if needClientCerts && !sessionHasClientCerts {
+ continue
+ }
+ if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
+ continue
+ }
+ if sessionHasClientCerts && c.config.time().After(sessionState.peerCertificates[0].NotAfter) {
+ continue
+ }
+ if sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven &&
+ len(sessionState.verifiedChains) == 0 {
+ continue
+ }
+
+ hs.earlySecret = hs.suite.extract(sessionState.secret, nil)
+ binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil)
+ // Clone the transcript in case a HelloRetryRequest was recorded.
+ transcript := cloneHash(hs.transcript, hs.suite.hash)
+ if transcript == nil {
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: internal error: failed to clone hash")
+ }
+ clientHelloBytes, err := hs.clientHello.marshalWithoutBinders()
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ transcript.Write(clientHelloBytes)
+ pskBinder := hs.suite.finishedHash(binderKey, transcript)
+ if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) {
+ c.sendAlert(alertDecryptError)
+ return errors.New("tls: invalid PSK binder")
+ }
+
+ if c.quic != nil && hs.clientHello.earlyData && i == 0 &&
+ sessionState.EarlyData && sessionState.cipherSuite == hs.suite.id &&
+ sessionState.alpnProtocol == c.clientProtocol {
+ hs.earlyData = true
+
+ transcript := hs.suite.hash.New()
+ if err := transcriptMsg(hs.clientHello, transcript); err != nil {
+ return err
+ }
+ earlyTrafficSecret := hs.suite.deriveSecret(hs.earlySecret, clientEarlyTrafficLabel, transcript)
+ c.quicSetReadSecret(QUICEncryptionLevelEarly, hs.suite.id, earlyTrafficSecret)
+ }
+
+ c.didResume = true
+ c.peerCertificates = sessionState.peerCertificates
+ c.ocspResponse = sessionState.ocspResponse
+ c.scts = sessionState.scts
+ c.verifiedChains = sessionState.verifiedChains
+
+ hs.hello.selectedIdentityPresent = true
+ hs.hello.selectedIdentity = uint16(i)
+ hs.usingPSK = true
+ return nil
+ }
+
+ return nil
+}
+
+// cloneHash uses the encoding.BinaryMarshaler and encoding.BinaryUnmarshaler
+// interfaces implemented by standard library hashes to clone the state of in
+// to a new instance of h. It returns nil if the operation fails.
+func cloneHash(in hash.Hash, h crypto.Hash) hash.Hash {
+ // Recreate the interface to avoid importing encoding.
+ type binaryMarshaler interface {
+ MarshalBinary() (data []byte, err error)
+ UnmarshalBinary(data []byte) error
+ }
+ marshaler, ok := in.(binaryMarshaler)
+ if !ok {
+ return nil
+ }
+ state, err := marshaler.MarshalBinary()
+ if err != nil {
+ return nil
+ }
+ out := h.New()
+ unmarshaler, ok := out.(binaryMarshaler)
+ if !ok {
+ return nil
+ }
+ if err := unmarshaler.UnmarshalBinary(state); err != nil {
+ return nil
+ }
+ return out
+}
+
+func (hs *serverHandshakeStateTLS13) pickCertificate() error {
+ c := hs.c
+
+ // Only one of PSK and certificates are used at a time.
+ if hs.usingPSK {
+ return nil
+ }
+
+ // signature_algorithms is required in TLS 1.3. See RFC 8446, Section 4.2.3.
+ if len(hs.clientHello.supportedSignatureAlgorithms) == 0 {
+ return c.sendAlert(alertMissingExtension)
+ }
+
+ certificate, err := c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
+ if err != nil {
+ if err == errNoCertificates {
+ c.sendAlert(alertUnrecognizedName)
+ } else {
+ c.sendAlert(alertInternalError)
+ }
+ return err
+ }
+ hs.sigAlg, err = selectSignatureScheme(c.vers, certificate, hs.clientHello.supportedSignatureAlgorithms)
+ if err != nil {
+ // getCertificate returned a certificate that is unsupported or
+ // incompatible with the client's signature algorithms.
+ c.sendAlert(alertHandshakeFailure)
+ return err
+ }
+ hs.cert = certificate
+
+ return nil
+}
+
+// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
+// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
+func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
+ if hs.c.quic != nil {
+ return nil
+ }
+ if hs.sentDummyCCS {
+ return nil
+ }
+ hs.sentDummyCCS = true
+
+ return hs.c.writeChangeCipherRecord()
+}
+
+func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error {
+ c := hs.c
+
+ // The first ClientHello gets double-hashed into the transcript upon a
+ // HelloRetryRequest. See RFC 8446, Section 4.4.1.
+ if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil {
+ return err
+ }
+ chHash := hs.transcript.Sum(nil)
+ hs.transcript.Reset()
+ hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
+ hs.transcript.Write(chHash)
+
+ helloRetryRequest := &serverHelloMsg{
+ vers: hs.hello.vers,
+ random: helloRetryRequestRandom,
+ sessionId: hs.hello.sessionId,
+ cipherSuite: hs.hello.cipherSuite,
+ compressionMethod: hs.hello.compressionMethod,
+ supportedVersion: hs.hello.supportedVersion,
+ selectedGroup: selectedGroup,
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(helloRetryRequest, hs.transcript); err != nil {
+ return err
+ }
+
+ if err := hs.sendDummyChangeCipherSpec(); err != nil {
+ return err
+ }
+
+ // clientHelloMsg is not included in the transcript.
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ clientHello, ok := msg.(*clientHelloMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(clientHello, msg)
+ }
+
+ if len(clientHello.keyShares) != 1 || clientHello.keyShares[0].group != selectedGroup {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client sent invalid key share in second ClientHello")
+ }
+
+ if clientHello.earlyData {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client indicated early data in second ClientHello")
+ }
+
+ if illegalClientHelloChange(clientHello, hs.clientHello) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client illegally modified second ClientHello")
+ }
+
+ hs.clientHello = clientHello
+ return nil
+}
+
+// illegalClientHelloChange reports whether the two ClientHello messages are
+// different, with the exception of the changes allowed before and after a
+// HelloRetryRequest. See RFC 8446, Section 4.1.2.
+func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool {
+ if len(ch.supportedVersions) != len(ch1.supportedVersions) ||
+ len(ch.cipherSuites) != len(ch1.cipherSuites) ||
+ len(ch.supportedCurves) != len(ch1.supportedCurves) ||
+ len(ch.supportedSignatureAlgorithms) != len(ch1.supportedSignatureAlgorithms) ||
+ len(ch.supportedSignatureAlgorithmsCert) != len(ch1.supportedSignatureAlgorithmsCert) ||
+ len(ch.alpnProtocols) != len(ch1.alpnProtocols) {
+ return true
+ }
+ for i := range ch.supportedVersions {
+ if ch.supportedVersions[i] != ch1.supportedVersions[i] {
+ return true
+ }
+ }
+ for i := range ch.cipherSuites {
+ if ch.cipherSuites[i] != ch1.cipherSuites[i] {
+ return true
+ }
+ }
+ for i := range ch.supportedCurves {
+ if ch.supportedCurves[i] != ch1.supportedCurves[i] {
+ return true
+ }
+ }
+ for i := range ch.supportedSignatureAlgorithms {
+ if ch.supportedSignatureAlgorithms[i] != ch1.supportedSignatureAlgorithms[i] {
+ return true
+ }
+ }
+ for i := range ch.supportedSignatureAlgorithmsCert {
+ if ch.supportedSignatureAlgorithmsCert[i] != ch1.supportedSignatureAlgorithmsCert[i] {
+ return true
+ }
+ }
+ for i := range ch.alpnProtocols {
+ if ch.alpnProtocols[i] != ch1.alpnProtocols[i] {
+ return true
+ }
+ }
+ return ch.vers != ch1.vers ||
+ !bytes.Equal(ch.random, ch1.random) ||
+ !bytes.Equal(ch.sessionId, ch1.sessionId) ||
+ !bytes.Equal(ch.compressionMethods, ch1.compressionMethods) ||
+ ch.serverName != ch1.serverName ||
+ ch.ocspStapling != ch1.ocspStapling ||
+ !bytes.Equal(ch.supportedPoints, ch1.supportedPoints) ||
+ ch.ticketSupported != ch1.ticketSupported ||
+ !bytes.Equal(ch.sessionTicket, ch1.sessionTicket) ||
+ ch.secureRenegotiationSupported != ch1.secureRenegotiationSupported ||
+ !bytes.Equal(ch.secureRenegotiation, ch1.secureRenegotiation) ||
+ ch.scts != ch1.scts ||
+ !bytes.Equal(ch.cookie, ch1.cookie) ||
+ !bytes.Equal(ch.pskModes, ch1.pskModes)
+}
+
+func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
+ c := hs.c
+
+ if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil {
+ return err
+ }
+ if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil {
+ return err
+ }
+
+ if err := hs.sendDummyChangeCipherSpec(); err != nil {
+ return err
+ }
+
+ earlySecret := hs.earlySecret
+ if earlySecret == nil {
+ earlySecret = hs.suite.extract(nil, nil)
+ }
+ hs.handshakeSecret = hs.suite.extract(hs.sharedKey,
+ hs.suite.deriveSecret(earlySecret, "derived", nil))
+
+ clientSecret := hs.suite.deriveSecret(hs.handshakeSecret,
+ clientHandshakeTrafficLabel, hs.transcript)
+ c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
+ serverSecret := hs.suite.deriveSecret(hs.handshakeSecret,
+ serverHandshakeTrafficLabel, hs.transcript)
+ c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
+
+ if c.quic != nil {
+ if c.hand.Len() != 0 {
+ c.sendAlert(alertUnexpectedMessage)
+ }
+ c.quicSetWriteSecret(QUICEncryptionLevelHandshake, hs.suite.id, serverSecret)
+ c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, clientSecret)
+ }
+
+ err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.clientHello.random, serverSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ encryptedExtensions := new(encryptedExtensionsMsg)
+ encryptedExtensions.alpnProtocol = c.clientProtocol
+
+ if c.quic != nil {
+ p, err := c.quicGetTransportParameters()
+ if err != nil {
+ return err
+ }
+ encryptedExtensions.quicTransportParameters = p
+ encryptedExtensions.earlyData = hs.earlyData
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(encryptedExtensions, hs.transcript); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) requestClientCert() bool {
+ return hs.c.config.ClientAuth >= RequestClientCert && !hs.usingPSK
+}
+
+func (hs *serverHandshakeStateTLS13) sendServerCertificate() error {
+ c := hs.c
+
+ // Only one of PSK and certificates are used at a time.
+ if hs.usingPSK {
+ return nil
+ }
+
+ if hs.requestClientCert() {
+ // Request a client certificate
+ certReq := new(certificateRequestMsgTLS13)
+ certReq.ocspStapling = true
+ certReq.scts = true
+ certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+ if c.config.ClientCAs != nil {
+ certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(certReq, hs.transcript); err != nil {
+ return err
+ }
+ }
+
+ certMsg := new(certificateMsgTLS13)
+
+ certMsg.certificate = *hs.cert
+ certMsg.scts = hs.clientHello.scts && len(hs.cert.SignedCertificateTimestamps) > 0
+ certMsg.ocspStapling = hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0
+
+ if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != nil {
+ return err
+ }
+
+ certVerifyMsg := new(certificateVerifyMsg)
+ certVerifyMsg.hasSignatureAlgorithm = true
+ certVerifyMsg.signatureAlgorithm = hs.sigAlg
+
+ sigType, sigHash, err := typeAndHashFromSignatureScheme(hs.sigAlg)
+ if err != nil {
+ return c.sendAlert(alertInternalError)
+ }
+
+ signed := signedMessage(sigHash, serverSignatureContext, hs.transcript)
+ signOpts := crypto.SignerOpts(sigHash)
+ if sigType == signatureRSAPSS {
+ signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
+ }
+ sig, err := hs.cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts)
+ if err != nil {
+ public := hs.cert.PrivateKey.(crypto.Signer).Public()
+ if rsaKey, ok := public.(*rsa.PublicKey); ok && sigType == signatureRSAPSS &&
+ rsaKey.N.BitLen()/8 < sigHash.Size()*2+2 { // key too small for RSA-PSS
+ c.sendAlert(alertHandshakeFailure)
+ } else {
+ c.sendAlert(alertInternalError)
+ }
+ return errors.New("tls: failed to sign handshake: " + err.Error())
+ }
+ certVerifyMsg.signature = sig
+
+ if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) sendServerFinished() error {
+ c := hs.c
+
+ finished := &finishedMsg{
+ verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != nil {
+ return err
+ }
+
+ // Derive secrets that take context through the server Finished.
+
+ hs.masterSecret = hs.suite.extract(nil,
+ hs.suite.deriveSecret(hs.handshakeSecret, "derived", nil))
+
+ hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret,
+ clientApplicationTrafficLabel, hs.transcript)
+ serverSecret := hs.suite.deriveSecret(hs.masterSecret,
+ serverApplicationTrafficLabel, hs.transcript)
+ c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret)
+
+ if c.quic != nil {
+ if c.hand.Len() != 0 {
+ // TODO: Handle this in setTrafficSecret?
+ c.sendAlert(alertUnexpectedMessage)
+ }
+ c.quicSetWriteSecret(QUICEncryptionLevelApplication, hs.suite.id, serverSecret)
+ }
+
+ err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.clientHello.random, serverSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript)
+
+ // If we did not request client certificates, at this point we can
+ // precompute the client finished and roll the transcript forward to send
+ // session tickets in our first flight.
+ if !hs.requestClientCert() {
+ if err := hs.sendSessionTickets(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool {
+ if hs.c.config.SessionTicketsDisabled {
+ return false
+ }
+
+ // QUIC tickets are sent by QUICConn.SendSessionTicket, not automatically.
+ if hs.c.quic != nil {
+ return false
+ }
+
+ // Don't send tickets the client wouldn't use. See RFC 8446, Section 4.2.9.
+ for _, pskMode := range hs.clientHello.pskModes {
+ if pskMode == pskModeDHE {
+ return true
+ }
+ }
+ return false
+}
+
+func (hs *serverHandshakeStateTLS13) sendSessionTickets() error {
+ c := hs.c
+
+ hs.clientFinished = hs.suite.finishedHash(c.in.trafficSecret, hs.transcript)
+ finishedMsg := &finishedMsg{
+ verifyData: hs.clientFinished,
+ }
+ if err := transcriptMsg(finishedMsg, hs.transcript); err != nil {
+ return err
+ }
+
+ c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
+ resumptionLabel, hs.transcript)
+
+ if !hs.shouldSendSessionTickets() {
+ return nil
+ }
+ return c.sendSessionTicket(false)
+}
+
+func (c *Conn) sendSessionTicket(earlyData bool) error {
+ suite := cipherSuiteTLS13ByID(c.cipherSuite)
+ if suite == nil {
+ return errors.New("tls: internal error: unknown cipher suite")
+ }
+ // ticket_nonce, which must be unique per connection, is always left at
+ // zero because we only ever send one ticket per connection.
+ psk := suite.expandLabel(c.resumptionSecret, "resumption",
+ nil, suite.hash.Size())
+
+ m := new(newSessionTicketMsgTLS13)
+
+ state, err := c.sessionState()
+ if err != nil {
+ return err
+ }
+ state.secret = psk
+ state.EarlyData = earlyData
+ if c.config.WrapSession != nil {
+ m.label, err = c.config.WrapSession(c.connectionStateLocked(), state)
+ if err != nil {
+ return err
+ }
+ } else {
+ stateBytes, err := state.Bytes()
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ m.label, err = c.config.encryptTicket(stateBytes, c.ticketKeys)
+ if err != nil {
+ return err
+ }
+ }
+ m.lifetime = uint32(maxSessionTicketLifetime / time.Second)
+
+ // ticket_age_add is a random 32-bit value. See RFC 8446, section 4.6.1
+ // The value is not stored anywhere; we never need to check the ticket age
+ // because 0-RTT is not supported.
+ ageAdd := make([]byte, 4)
+ _, err = c.config.rand().Read(ageAdd)
+ if err != nil {
+ return err
+ }
+ m.ageAdd = binary.LittleEndian.Uint32(ageAdd)
+
+ if earlyData {
+ // RFC 9001, Section 4.6.1
+ m.maxEarlyData = 0xffffffff
+ }
+
+ if _, err := c.writeHandshakeRecord(m, nil); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) readClientCertificate() error {
+ c := hs.c
+
+ if !hs.requestClientCert() {
+ // Make sure the connection is still being verified whether or not
+ // the server requested a client certificate.
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+ return nil
+ }
+
+ // If we requested a client certificate, then the client must send a
+ // certificate message. If it's empty, no CertificateVerify is sent.
+
+ msg, err := c.readHandshake(hs.transcript)
+ if err != nil {
+ return err
+ }
+
+ certMsg, ok := msg.(*certificateMsgTLS13)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certMsg, msg)
+ }
+
+ if err := c.processCertsFromClient(certMsg.certificate); err != nil {
+ return err
+ }
+
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+
+ if len(certMsg.certificate.Certificate) != 0 {
+ // certificateVerifyMsg is included in the transcript, but not until
+ // after we verify the handshake signature, since the state before
+ // this message was sent is used.
+ msg, err = c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ certVerify, ok := msg.(*certificateVerifyMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certVerify, msg)
+ }
+
+ // See RFC 8446, Section 4.4.3.
+ if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client certificate used with invalid signature algorithm")
+ }
+ sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
+ if err != nil {
+ return c.sendAlert(alertInternalError)
+ }
+ if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client certificate used with invalid signature algorithm")
+ }
+ signed := signedMessage(sigHash, clientSignatureContext, hs.transcript)
+ if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey,
+ sigHash, signed, certVerify.signature); err != nil {
+ c.sendAlert(alertDecryptError)
+ return errors.New("tls: invalid signature by the client certificate: " + err.Error())
+ }
+
+ if err := transcriptMsg(certVerify, hs.transcript); err != nil {
+ return err
+ }
+ }
+
+ // If we waited until the client certificates to send session tickets, we
+ // are ready to do it now.
+ if err := hs.sendSessionTickets(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) readClientFinished() error {
+ c := hs.c
+
+ // finishedMsg is not included in the transcript.
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ finished, ok := msg.(*finishedMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(finished, msg)
+ }
+
+ if !hmac.Equal(hs.clientFinished, finished.verifyData) {
+ c.sendAlert(alertDecryptError)
+ return errors.New("tls: invalid client finished hash")
+ }
+
+ c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret)
+
+ return nil
+}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/key_agreement.go b/contrib/go/_std_1.21/src/crypto/tls/key_agreement.go
index 2c8c5b8d77..2c8c5b8d77 100644
--- a/contrib/go/_std_1.20/src/crypto/tls/key_agreement.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/key_agreement.go
diff --git a/contrib/go/_std_1.21/src/crypto/tls/key_schedule.go b/contrib/go/_std_1.21/src/crypto/tls/key_schedule.go
new file mode 100644
index 0000000000..d7f082c9ee
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/key_schedule.go
@@ -0,0 +1,159 @@
+// Copyright 2018 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 tls
+
+import (
+ "crypto/ecdh"
+ "crypto/hmac"
+ "errors"
+ "fmt"
+ "hash"
+ "io"
+
+ "golang.org/x/crypto/cryptobyte"
+ "golang.org/x/crypto/hkdf"
+)
+
+// This file contains the functions necessary to compute the TLS 1.3 key
+// schedule. See RFC 8446, Section 7.
+
+const (
+ resumptionBinderLabel = "res binder"
+ clientEarlyTrafficLabel = "c e traffic"
+ clientHandshakeTrafficLabel = "c hs traffic"
+ serverHandshakeTrafficLabel = "s hs traffic"
+ clientApplicationTrafficLabel = "c ap traffic"
+ serverApplicationTrafficLabel = "s ap traffic"
+ exporterLabel = "exp master"
+ resumptionLabel = "res master"
+ trafficUpdateLabel = "traffic upd"
+)
+
+// expandLabel implements HKDF-Expand-Label from RFC 8446, Section 7.1.
+func (c *cipherSuiteTLS13) expandLabel(secret []byte, label string, context []byte, length int) []byte {
+ var hkdfLabel cryptobyte.Builder
+ hkdfLabel.AddUint16(uint16(length))
+ hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes([]byte("tls13 "))
+ b.AddBytes([]byte(label))
+ })
+ hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(context)
+ })
+ hkdfLabelBytes, err := hkdfLabel.Bytes()
+ if err != nil {
+ // Rather than calling BytesOrPanic, we explicitly handle this error, in
+ // order to provide a reasonable error message. It should be basically
+ // impossible for this to panic, and routing errors back through the
+ // tree rooted in this function is quite painful. The labels are fixed
+ // size, and the context is either a fixed-length computed hash, or
+ // parsed from a field which has the same length limitation. As such, an
+ // error here is likely to only be caused during development.
+ //
+ // NOTE: another reasonable approach here might be to return a
+ // randomized slice if we encounter an error, which would break the
+ // connection, but avoid panicking. This would perhaps be safer but
+ // significantly more confusing to users.
+ panic(fmt.Errorf("failed to construct HKDF label: %s", err))
+ }
+ out := make([]byte, length)
+ n, err := hkdf.Expand(c.hash.New, secret, hkdfLabelBytes).Read(out)
+ if err != nil || n != length {
+ panic("tls: HKDF-Expand-Label invocation failed unexpectedly")
+ }
+ return out
+}
+
+// deriveSecret implements Derive-Secret from RFC 8446, Section 7.1.
+func (c *cipherSuiteTLS13) deriveSecret(secret []byte, label string, transcript hash.Hash) []byte {
+ if transcript == nil {
+ transcript = c.hash.New()
+ }
+ return c.expandLabel(secret, label, transcript.Sum(nil), c.hash.Size())
+}
+
+// extract implements HKDF-Extract with the cipher suite hash.
+func (c *cipherSuiteTLS13) extract(newSecret, currentSecret []byte) []byte {
+ if newSecret == nil {
+ newSecret = make([]byte, c.hash.Size())
+ }
+ return hkdf.Extract(c.hash.New, newSecret, currentSecret)
+}
+
+// nextTrafficSecret generates the next traffic secret, given the current one,
+// according to RFC 8446, Section 7.2.
+func (c *cipherSuiteTLS13) nextTrafficSecret(trafficSecret []byte) []byte {
+ return c.expandLabel(trafficSecret, trafficUpdateLabel, nil, c.hash.Size())
+}
+
+// trafficKey generates traffic keys according to RFC 8446, Section 7.3.
+func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) {
+ key = c.expandLabel(trafficSecret, "key", nil, c.keyLen)
+ iv = c.expandLabel(trafficSecret, "iv", nil, aeadNonceLength)
+ return
+}
+
+// finishedHash generates the Finished verify_data or PskBinderEntry according
+// to RFC 8446, Section 4.4.4. See sections 4.4 and 4.2.11.2 for the baseKey
+// selection.
+func (c *cipherSuiteTLS13) finishedHash(baseKey []byte, transcript hash.Hash) []byte {
+ finishedKey := c.expandLabel(baseKey, "finished", nil, c.hash.Size())
+ verifyData := hmac.New(c.hash.New, finishedKey)
+ verifyData.Write(transcript.Sum(nil))
+ return verifyData.Sum(nil)
+}
+
+// exportKeyingMaterial implements RFC5705 exporters for TLS 1.3 according to
+// RFC 8446, Section 7.5.
+func (c *cipherSuiteTLS13) exportKeyingMaterial(masterSecret []byte, transcript hash.Hash) func(string, []byte, int) ([]byte, error) {
+ expMasterSecret := c.deriveSecret(masterSecret, exporterLabel, transcript)
+ return func(label string, context []byte, length int) ([]byte, error) {
+ secret := c.deriveSecret(expMasterSecret, label, nil)
+ h := c.hash.New()
+ h.Write(context)
+ return c.expandLabel(secret, "exporter", h.Sum(nil), length), nil
+ }
+}
+
+// generateECDHEKey returns a PrivateKey that implements Diffie-Hellman
+// according to RFC 8446, Section 4.2.8.2.
+func generateECDHEKey(rand io.Reader, curveID CurveID) (*ecdh.PrivateKey, error) {
+ curve, ok := curveForCurveID(curveID)
+ if !ok {
+ return nil, errors.New("tls: internal error: unsupported curve")
+ }
+
+ return curve.GenerateKey(rand)
+}
+
+func curveForCurveID(id CurveID) (ecdh.Curve, bool) {
+ switch id {
+ case X25519:
+ return ecdh.X25519(), true
+ case CurveP256:
+ return ecdh.P256(), true
+ case CurveP384:
+ return ecdh.P384(), true
+ case CurveP521:
+ return ecdh.P521(), true
+ default:
+ return nil, false
+ }
+}
+
+func curveIDForCurve(curve ecdh.Curve) (CurveID, bool) {
+ switch curve {
+ case ecdh.X25519():
+ return X25519, true
+ case ecdh.P256():
+ return CurveP256, true
+ case ecdh.P384():
+ return CurveP384, true
+ case ecdh.P521():
+ return CurveP521, true
+ default:
+ return 0, false
+ }
+}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/notboring.go b/contrib/go/_std_1.21/src/crypto/tls/notboring.go
index 7d85b39c59..7d85b39c59 100644
--- a/contrib/go/_std_1.20/src/crypto/tls/notboring.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/notboring.go
diff --git a/contrib/go/_std_1.21/src/crypto/tls/prf.go b/contrib/go/_std_1.21/src/crypto/tls/prf.go
new file mode 100644
index 0000000000..20bac96e86
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/prf.go
@@ -0,0 +1,292 @@
+// Copyright 2009 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 tls
+
+import (
+ "crypto"
+ "crypto/hmac"
+ "crypto/md5"
+ "crypto/sha1"
+ "crypto/sha256"
+ "crypto/sha512"
+ "errors"
+ "fmt"
+ "hash"
+)
+
+// Split a premaster secret in two as specified in RFC 4346, Section 5.
+func splitPreMasterSecret(secret []byte) (s1, s2 []byte) {
+ s1 = secret[0 : (len(secret)+1)/2]
+ s2 = secret[len(secret)/2:]
+ return
+}
+
+// pHash implements the P_hash function, as defined in RFC 4346, Section 5.
+func pHash(result, secret, seed []byte, hash func() hash.Hash) {
+ h := hmac.New(hash, secret)
+ h.Write(seed)
+ a := h.Sum(nil)
+
+ j := 0
+ for j < len(result) {
+ h.Reset()
+ h.Write(a)
+ h.Write(seed)
+ b := h.Sum(nil)
+ copy(result[j:], b)
+ j += len(b)
+
+ h.Reset()
+ h.Write(a)
+ a = h.Sum(nil)
+ }
+}
+
+// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5.
+func prf10(result, secret, label, seed []byte) {
+ hashSHA1 := sha1.New
+ hashMD5 := md5.New
+
+ labelAndSeed := make([]byte, len(label)+len(seed))
+ copy(labelAndSeed, label)
+ copy(labelAndSeed[len(label):], seed)
+
+ s1, s2 := splitPreMasterSecret(secret)
+ pHash(result, s1, labelAndSeed, hashMD5)
+ result2 := make([]byte, len(result))
+ pHash(result2, s2, labelAndSeed, hashSHA1)
+
+ for i, b := range result2 {
+ result[i] ^= b
+ }
+}
+
+// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5.
+func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) {
+ return func(result, secret, label, seed []byte) {
+ labelAndSeed := make([]byte, len(label)+len(seed))
+ copy(labelAndSeed, label)
+ copy(labelAndSeed[len(label):], seed)
+
+ pHash(result, secret, labelAndSeed, hashFunc)
+ }
+}
+
+const (
+ masterSecretLength = 48 // Length of a master secret in TLS 1.1.
+ finishedVerifyLength = 12 // Length of verify_data in a Finished message.
+)
+
+var masterSecretLabel = []byte("master secret")
+var extendedMasterSecretLabel = []byte("extended master secret")
+var keyExpansionLabel = []byte("key expansion")
+var clientFinishedLabel = []byte("client finished")
+var serverFinishedLabel = []byte("server finished")
+
+func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) {
+ switch version {
+ case VersionTLS10, VersionTLS11:
+ return prf10, crypto.Hash(0)
+ case VersionTLS12:
+ if suite.flags&suiteSHA384 != 0 {
+ return prf12(sha512.New384), crypto.SHA384
+ }
+ return prf12(sha256.New), crypto.SHA256
+ default:
+ panic("unknown version")
+ }
+}
+
+func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) {
+ prf, _ := prfAndHashForVersion(version, suite)
+ return prf
+}
+
+// masterFromPreMasterSecret generates the master secret from the pre-master
+// secret. See RFC 5246, Section 8.1.
+func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte {
+ seed := make([]byte, 0, len(clientRandom)+len(serverRandom))
+ seed = append(seed, clientRandom...)
+ seed = append(seed, serverRandom...)
+
+ masterSecret := make([]byte, masterSecretLength)
+ prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed)
+ return masterSecret
+}
+
+// extMasterFromPreMasterSecret generates the extended master secret from the
+// pre-master secret. See RFC 7627.
+func extMasterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, transcript []byte) []byte {
+ masterSecret := make([]byte, masterSecretLength)
+ prfForVersion(version, suite)(masterSecret, preMasterSecret, extendedMasterSecretLabel, transcript)
+ return masterSecret
+}
+
+// keysFromMasterSecret generates the connection keys from the master
+// secret, given the lengths of the MAC key, cipher key and IV, as defined in
+// RFC 2246, Section 6.3.
+func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
+ seed := make([]byte, 0, len(serverRandom)+len(clientRandom))
+ seed = append(seed, serverRandom...)
+ seed = append(seed, clientRandom...)
+
+ n := 2*macLen + 2*keyLen + 2*ivLen
+ keyMaterial := make([]byte, n)
+ prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed)
+ clientMAC = keyMaterial[:macLen]
+ keyMaterial = keyMaterial[macLen:]
+ serverMAC = keyMaterial[:macLen]
+ keyMaterial = keyMaterial[macLen:]
+ clientKey = keyMaterial[:keyLen]
+ keyMaterial = keyMaterial[keyLen:]
+ serverKey = keyMaterial[:keyLen]
+ keyMaterial = keyMaterial[keyLen:]
+ clientIV = keyMaterial[:ivLen]
+ keyMaterial = keyMaterial[ivLen:]
+ serverIV = keyMaterial[:ivLen]
+ return
+}
+
+func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash {
+ var buffer []byte
+ if version >= VersionTLS12 {
+ buffer = []byte{}
+ }
+
+ prf, hash := prfAndHashForVersion(version, cipherSuite)
+ if hash != 0 {
+ return finishedHash{hash.New(), hash.New(), nil, nil, buffer, version, prf}
+ }
+
+ return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), buffer, version, prf}
+}
+
+// A finishedHash calculates the hash of a set of handshake messages suitable
+// for including in a Finished message.
+type finishedHash struct {
+ client hash.Hash
+ server hash.Hash
+
+ // Prior to TLS 1.2, an additional MD5 hash is required.
+ clientMD5 hash.Hash
+ serverMD5 hash.Hash
+
+ // In TLS 1.2, a full buffer is sadly required.
+ buffer []byte
+
+ version uint16
+ prf func(result, secret, label, seed []byte)
+}
+
+func (h *finishedHash) Write(msg []byte) (n int, err error) {
+ h.client.Write(msg)
+ h.server.Write(msg)
+
+ if h.version < VersionTLS12 {
+ h.clientMD5.Write(msg)
+ h.serverMD5.Write(msg)
+ }
+
+ if h.buffer != nil {
+ h.buffer = append(h.buffer, msg...)
+ }
+
+ return len(msg), nil
+}
+
+func (h finishedHash) Sum() []byte {
+ if h.version >= VersionTLS12 {
+ return h.client.Sum(nil)
+ }
+
+ out := make([]byte, 0, md5.Size+sha1.Size)
+ out = h.clientMD5.Sum(out)
+ return h.client.Sum(out)
+}
+
+// clientSum returns the contents of the verify_data member of a client's
+// Finished message.
+func (h finishedHash) clientSum(masterSecret []byte) []byte {
+ out := make([]byte, finishedVerifyLength)
+ h.prf(out, masterSecret, clientFinishedLabel, h.Sum())
+ return out
+}
+
+// serverSum returns the contents of the verify_data member of a server's
+// Finished message.
+func (h finishedHash) serverSum(masterSecret []byte) []byte {
+ out := make([]byte, finishedVerifyLength)
+ h.prf(out, masterSecret, serverFinishedLabel, h.Sum())
+ return out
+}
+
+// hashForClientCertificate returns the handshake messages so far, pre-hashed if
+// necessary, suitable for signing by a TLS client certificate.
+func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash) []byte {
+ if (h.version >= VersionTLS12 || sigType == signatureEd25519) && h.buffer == nil {
+ panic("tls: handshake hash for a client certificate requested after discarding the handshake buffer")
+ }
+
+ if sigType == signatureEd25519 {
+ return h.buffer
+ }
+
+ if h.version >= VersionTLS12 {
+ hash := hashAlg.New()
+ hash.Write(h.buffer)
+ return hash.Sum(nil)
+ }
+
+ if sigType == signatureECDSA {
+ return h.server.Sum(nil)
+ }
+
+ return h.Sum()
+}
+
+// discardHandshakeBuffer is called when there is no more need to
+// buffer the entirety of the handshake messages.
+func (h *finishedHash) discardHandshakeBuffer() {
+ h.buffer = nil
+}
+
+// noExportedKeyingMaterial is used as a value of
+// ConnectionState.ekm when renegotiation is enabled and thus
+// we wish to fail all key-material export requests.
+func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
+ return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled")
+}
+
+// ekmFromMasterSecret generates exported keying material as defined in RFC 5705.
+func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) {
+ return func(label string, context []byte, length int) ([]byte, error) {
+ switch label {
+ case "client finished", "server finished", "master secret", "key expansion":
+ // These values are reserved and may not be used.
+ return nil, fmt.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label)
+ }
+
+ seedLen := len(serverRandom) + len(clientRandom)
+ if context != nil {
+ seedLen += 2 + len(context)
+ }
+ seed := make([]byte, 0, seedLen)
+
+ seed = append(seed, clientRandom...)
+ seed = append(seed, serverRandom...)
+
+ if context != nil {
+ if len(context) >= 1<<16 {
+ return nil, fmt.Errorf("crypto/tls: ExportKeyingMaterial context too long")
+ }
+ seed = append(seed, byte(len(context)>>8), byte(len(context)))
+ seed = append(seed, context...)
+ }
+
+ keyMaterial := make([]byte, length)
+ prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed)
+ return keyMaterial, nil
+ }
+}
diff --git a/contrib/go/_std_1.21/src/crypto/tls/quic.go b/contrib/go/_std_1.21/src/crypto/tls/quic.go
new file mode 100644
index 0000000000..ba5c2af0fb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/quic.go
@@ -0,0 +1,421 @@
+// Copyright 2023 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 tls
+
+import (
+ "context"
+ "errors"
+ "fmt"
+)
+
+// QUICEncryptionLevel represents a QUIC encryption level used to transmit
+// handshake messages.
+type QUICEncryptionLevel int
+
+const (
+ QUICEncryptionLevelInitial = QUICEncryptionLevel(iota)
+ QUICEncryptionLevelEarly
+ QUICEncryptionLevelHandshake
+ QUICEncryptionLevelApplication
+)
+
+func (l QUICEncryptionLevel) String() string {
+ switch l {
+ case QUICEncryptionLevelInitial:
+ return "Initial"
+ case QUICEncryptionLevelEarly:
+ return "Early"
+ case QUICEncryptionLevelHandshake:
+ return "Handshake"
+ case QUICEncryptionLevelApplication:
+ return "Application"
+ default:
+ return fmt.Sprintf("QUICEncryptionLevel(%v)", int(l))
+ }
+}
+
+// A QUICConn represents a connection which uses a QUIC implementation as the underlying
+// transport as described in RFC 9001.
+//
+// Methods of QUICConn are not safe for concurrent use.
+type QUICConn struct {
+ conn *Conn
+
+ sessionTicketSent bool
+}
+
+// A QUICConfig configures a QUICConn.
+type QUICConfig struct {
+ TLSConfig *Config
+}
+
+// A QUICEventKind is a type of operation on a QUIC connection.
+type QUICEventKind int
+
+const (
+ // QUICNoEvent indicates that there are no events available.
+ QUICNoEvent QUICEventKind = iota
+
+ // QUICSetReadSecret and QUICSetWriteSecret provide the read and write
+ // secrets for a given encryption level.
+ // QUICEvent.Level, QUICEvent.Data, and QUICEvent.Suite are set.
+ //
+ // Secrets for the Initial encryption level are derived from the initial
+ // destination connection ID, and are not provided by the QUICConn.
+ QUICSetReadSecret
+ QUICSetWriteSecret
+
+ // QUICWriteData provides data to send to the peer in CRYPTO frames.
+ // QUICEvent.Data is set.
+ QUICWriteData
+
+ // QUICTransportParameters provides the peer's QUIC transport parameters.
+ // QUICEvent.Data is set.
+ QUICTransportParameters
+
+ // QUICTransportParametersRequired indicates that the caller must provide
+ // QUIC transport parameters to send to the peer. The caller should set
+ // the transport parameters with QUICConn.SetTransportParameters and call
+ // QUICConn.NextEvent again.
+ //
+ // If transport parameters are set before calling QUICConn.Start, the
+ // connection will never generate a QUICTransportParametersRequired event.
+ QUICTransportParametersRequired
+
+ // QUICRejectedEarlyData indicates that the server rejected 0-RTT data even
+ // if we offered it. It's returned before QUICEncryptionLevelApplication
+ // keys are returned.
+ QUICRejectedEarlyData
+
+ // QUICHandshakeDone indicates that the TLS handshake has completed.
+ QUICHandshakeDone
+)
+
+// A QUICEvent is an event occurring on a QUIC connection.
+//
+// The type of event is specified by the Kind field.
+// The contents of the other fields are kind-specific.
+type QUICEvent struct {
+ Kind QUICEventKind
+
+ // Set for QUICSetReadSecret, QUICSetWriteSecret, and QUICWriteData.
+ Level QUICEncryptionLevel
+
+ // Set for QUICTransportParameters, QUICSetReadSecret, QUICSetWriteSecret, and QUICWriteData.
+ // The contents are owned by crypto/tls, and are valid until the next NextEvent call.
+ Data []byte
+
+ // Set for QUICSetReadSecret and QUICSetWriteSecret.
+ Suite uint16
+}
+
+type quicState struct {
+ events []QUICEvent
+ nextEvent int
+
+ // eventArr is a statically allocated event array, large enough to handle
+ // the usual maximum number of events resulting from a single call: transport
+ // parameters, Initial data, Early read secret, Handshake write and read
+ // secrets, Handshake data, Application write secret, Application data.
+ eventArr [8]QUICEvent
+
+ started bool
+ signalc chan struct{} // handshake data is available to be read
+ blockedc chan struct{} // handshake is waiting for data, closed when done
+ cancelc <-chan struct{} // handshake has been canceled
+ cancel context.CancelFunc
+
+ // readbuf is shared between HandleData and the handshake goroutine.
+ // HandshakeCryptoData passes ownership to the handshake goroutine by
+ // reading from signalc, and reclaims ownership by reading from blockedc.
+ readbuf []byte
+
+ transportParams []byte // to send to the peer
+}
+
+// QUICClient returns a new TLS client side connection using QUICTransport as the
+// underlying transport. The config cannot be nil.
+//
+// The config's MinVersion must be at least TLS 1.3.
+func QUICClient(config *QUICConfig) *QUICConn {
+ return newQUICConn(Client(nil, config.TLSConfig))
+}
+
+// QUICServer returns a new TLS server side connection using QUICTransport as the
+// underlying transport. The config cannot be nil.
+//
+// The config's MinVersion must be at least TLS 1.3.
+func QUICServer(config *QUICConfig) *QUICConn {
+ return newQUICConn(Server(nil, config.TLSConfig))
+}
+
+func newQUICConn(conn *Conn) *QUICConn {
+ conn.quic = &quicState{
+ signalc: make(chan struct{}),
+ blockedc: make(chan struct{}),
+ }
+ conn.quic.events = conn.quic.eventArr[:0]
+ return &QUICConn{
+ conn: conn,
+ }
+}
+
+// Start starts the client or server handshake protocol.
+// It may produce connection events, which may be read with NextEvent.
+//
+// Start must be called at most once.
+func (q *QUICConn) Start(ctx context.Context) error {
+ if q.conn.quic.started {
+ return quicError(errors.New("tls: Start called more than once"))
+ }
+ q.conn.quic.started = true
+ if q.conn.config.MinVersion < VersionTLS13 {
+ return quicError(errors.New("tls: Config MinVersion must be at least TLS 1.13"))
+ }
+ go q.conn.HandshakeContext(ctx)
+ if _, ok := <-q.conn.quic.blockedc; !ok {
+ return q.conn.handshakeErr
+ }
+ return nil
+}
+
+// NextEvent returns the next event occurring on the connection.
+// It returns an event with a Kind of QUICNoEvent when no events are available.
+func (q *QUICConn) NextEvent() QUICEvent {
+ qs := q.conn.quic
+ if last := qs.nextEvent - 1; last >= 0 && len(qs.events[last].Data) > 0 {
+ // Write over some of the previous event's data,
+ // to catch callers erroniously retaining it.
+ qs.events[last].Data[0] = 0
+ }
+ if qs.nextEvent >= len(qs.events) {
+ qs.events = qs.events[:0]
+ qs.nextEvent = 0
+ return QUICEvent{Kind: QUICNoEvent}
+ }
+ e := qs.events[qs.nextEvent]
+ qs.events[qs.nextEvent] = QUICEvent{} // zero out references to data
+ qs.nextEvent++
+ return e
+}
+
+// Close closes the connection and stops any in-progress handshake.
+func (q *QUICConn) Close() error {
+ if q.conn.quic.cancel == nil {
+ return nil // never started
+ }
+ q.conn.quic.cancel()
+ for range q.conn.quic.blockedc {
+ // Wait for the handshake goroutine to return.
+ }
+ return q.conn.handshakeErr
+}
+
+// HandleData handles handshake bytes received from the peer.
+// It may produce connection events, which may be read with NextEvent.
+func (q *QUICConn) HandleData(level QUICEncryptionLevel, data []byte) error {
+ c := q.conn
+ if c.in.level != level {
+ return quicError(c.in.setErrorLocked(errors.New("tls: handshake data received at wrong level")))
+ }
+ c.quic.readbuf = data
+ <-c.quic.signalc
+ _, ok := <-c.quic.blockedc
+ if ok {
+ // The handshake goroutine is waiting for more data.
+ return nil
+ }
+ // The handshake goroutine has exited.
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+ c.hand.Write(c.quic.readbuf)
+ c.quic.readbuf = nil
+ for q.conn.hand.Len() >= 4 && q.conn.handshakeErr == nil {
+ b := q.conn.hand.Bytes()
+ n := int(b[1])<<16 | int(b[2])<<8 | int(b[3])
+ if n > maxHandshake {
+ q.conn.handshakeErr = fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake)
+ break
+ }
+ if len(b) < 4+n {
+ return nil
+ }
+ if err := q.conn.handlePostHandshakeMessage(); err != nil {
+ q.conn.handshakeErr = err
+ }
+ }
+ if q.conn.handshakeErr != nil {
+ return quicError(q.conn.handshakeErr)
+ }
+ return nil
+}
+
+type QUICSessionTicketOptions struct {
+ // EarlyData specifies whether the ticket may be used for 0-RTT.
+ EarlyData bool
+}
+
+// SendSessionTicket sends a session ticket to the client.
+// It produces connection events, which may be read with NextEvent.
+// Currently, it can only be called once.
+func (q *QUICConn) SendSessionTicket(opts QUICSessionTicketOptions) error {
+ c := q.conn
+ if !c.isHandshakeComplete.Load() {
+ return quicError(errors.New("tls: SendSessionTicket called before handshake completed"))
+ }
+ if c.isClient {
+ return quicError(errors.New("tls: SendSessionTicket called on the client"))
+ }
+ if q.sessionTicketSent {
+ return quicError(errors.New("tls: SendSessionTicket called multiple times"))
+ }
+ q.sessionTicketSent = true
+ return quicError(c.sendSessionTicket(opts.EarlyData))
+}
+
+// ConnectionState returns basic TLS details about the connection.
+func (q *QUICConn) ConnectionState() ConnectionState {
+ return q.conn.ConnectionState()
+}
+
+// SetTransportParameters sets the transport parameters to send to the peer.
+//
+// Server connections may delay setting the transport parameters until after
+// receiving the client's transport parameters. See QUICTransportParametersRequired.
+func (q *QUICConn) SetTransportParameters(params []byte) {
+ if params == nil {
+ params = []byte{}
+ }
+ q.conn.quic.transportParams = params
+ if q.conn.quic.started {
+ <-q.conn.quic.signalc
+ <-q.conn.quic.blockedc
+ }
+}
+
+// quicError ensures err is an AlertError.
+// If err is not already, quicError wraps it with alertInternalError.
+func quicError(err error) error {
+ if err == nil {
+ return nil
+ }
+ var ae AlertError
+ if errors.As(err, &ae) {
+ return err
+ }
+ var a alert
+ if !errors.As(err, &a) {
+ a = alertInternalError
+ }
+ // Return an error wrapping the original error and an AlertError.
+ // Truncate the text of the alert to 0 characters.
+ return fmt.Errorf("%w%.0w", err, AlertError(a))
+}
+
+func (c *Conn) quicReadHandshakeBytes(n int) error {
+ for c.hand.Len() < n {
+ if err := c.quicWaitForSignal(); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (c *Conn) quicSetReadSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICSetReadSecret,
+ Level: level,
+ Suite: suite,
+ Data: secret,
+ })
+}
+
+func (c *Conn) quicSetWriteSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICSetWriteSecret,
+ Level: level,
+ Suite: suite,
+ Data: secret,
+ })
+}
+
+func (c *Conn) quicWriteCryptoData(level QUICEncryptionLevel, data []byte) {
+ var last *QUICEvent
+ if len(c.quic.events) > 0 {
+ last = &c.quic.events[len(c.quic.events)-1]
+ }
+ if last == nil || last.Kind != QUICWriteData || last.Level != level {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICWriteData,
+ Level: level,
+ })
+ last = &c.quic.events[len(c.quic.events)-1]
+ }
+ last.Data = append(last.Data, data...)
+}
+
+func (c *Conn) quicSetTransportParameters(params []byte) {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICTransportParameters,
+ Data: params,
+ })
+}
+
+func (c *Conn) quicGetTransportParameters() ([]byte, error) {
+ if c.quic.transportParams == nil {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICTransportParametersRequired,
+ })
+ }
+ for c.quic.transportParams == nil {
+ if err := c.quicWaitForSignal(); err != nil {
+ return nil, err
+ }
+ }
+ return c.quic.transportParams, nil
+}
+
+func (c *Conn) quicHandshakeComplete() {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICHandshakeDone,
+ })
+}
+
+func (c *Conn) quicRejectedEarlyData() {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICRejectedEarlyData,
+ })
+}
+
+// quicWaitForSignal notifies the QUICConn that handshake progress is blocked,
+// and waits for a signal that the handshake should proceed.
+//
+// The handshake may become blocked waiting for handshake bytes
+// or for the user to provide transport parameters.
+func (c *Conn) quicWaitForSignal() error {
+ // Drop the handshake mutex while blocked to allow the user
+ // to call ConnectionState before the handshake completes.
+ c.handshakeMutex.Unlock()
+ defer c.handshakeMutex.Lock()
+ // Send on blockedc to notify the QUICConn that the handshake is blocked.
+ // Exported methods of QUICConn wait for the handshake to become blocked
+ // before returning to the user.
+ select {
+ case c.quic.blockedc <- struct{}{}:
+ case <-c.quic.cancelc:
+ return c.sendAlertLocked(alertCloseNotify)
+ }
+ // The QUICConn reads from signalc to notify us that the handshake may
+ // be able to proceed. (The QUICConn reads, because we close signalc to
+ // indicate that the handshake has completed.)
+ select {
+ case c.quic.signalc <- struct{}{}:
+ c.hand.Write(c.quic.readbuf)
+ c.quic.readbuf = nil
+ case <-c.quic.cancelc:
+ return c.sendAlertLocked(alertCloseNotify)
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/crypto/tls/ticket.go b/contrib/go/_std_1.21/src/crypto/tls/ticket.go
new file mode 100644
index 0000000000..b43101ff66
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/ticket.go
@@ -0,0 +1,421 @@
+// Copyright 2012 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 tls
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/hmac"
+ "crypto/sha256"
+ "crypto/subtle"
+ "crypto/x509"
+ "errors"
+ "io"
+
+ "golang.org/x/crypto/cryptobyte"
+)
+
+// A SessionState is a resumable session.
+type SessionState struct {
+ // Encoded as a SessionState (in the language of RFC 8446, Section 3).
+ //
+ // enum { server(1), client(2) } SessionStateType;
+ //
+ // opaque Certificate<1..2^24-1>;
+ //
+ // Certificate CertificateChain<0..2^24-1>;
+ //
+ // opaque Extra<0..2^24-1>;
+ //
+ // struct {
+ // uint16 version;
+ // SessionStateType type;
+ // uint16 cipher_suite;
+ // uint64 created_at;
+ // opaque secret<1..2^8-1>;
+ // Extra extra<0..2^24-1>;
+ // uint8 ext_master_secret = { 0, 1 };
+ // uint8 early_data = { 0, 1 };
+ // CertificateEntry certificate_list<0..2^24-1>;
+ // CertificateChain verified_chains<0..2^24-1>; /* excluding leaf */
+ // select (SessionState.early_data) {
+ // case 0: Empty;
+ // case 1: opaque alpn<1..2^8-1>;
+ // };
+ // select (SessionState.type) {
+ // case server: Empty;
+ // case client: struct {
+ // select (SessionState.version) {
+ // case VersionTLS10..VersionTLS12: Empty;
+ // case VersionTLS13: struct {
+ // uint64 use_by;
+ // uint32 age_add;
+ // };
+ // };
+ // };
+ // };
+ // } SessionState;
+ //
+
+ // Extra is ignored by crypto/tls, but is encoded by [SessionState.Bytes]
+ // and parsed by [ParseSessionState].
+ //
+ // This allows [Config.UnwrapSession]/[Config.WrapSession] and
+ // [ClientSessionCache] implementations to store and retrieve additional
+ // data alongside this session.
+ //
+ // To allow different layers in a protocol stack to share this field,
+ // applications must only append to it, not replace it, and must use entries
+ // that can be recognized even if out of order (for example, by starting
+ // with a id and version prefix).
+ Extra [][]byte
+
+ // EarlyData indicates whether the ticket can be used for 0-RTT in a QUIC
+ // connection. The application may set this to false if it is true to
+ // decline to offer 0-RTT even if supported.
+ EarlyData bool
+
+ version uint16
+ isClient bool
+ cipherSuite uint16
+ // createdAt is the generation time of the secret on the sever (which for
+ // TLS 1.0–1.2 might be earlier than the current session) and the time at
+ // which the ticket was received on the client.
+ createdAt uint64 // seconds since UNIX epoch
+ secret []byte // master secret for TLS 1.2, or the PSK for TLS 1.3
+ extMasterSecret bool
+ peerCertificates []*x509.Certificate
+ activeCertHandles []*activeCert
+ ocspResponse []byte
+ scts [][]byte
+ verifiedChains [][]*x509.Certificate
+ alpnProtocol string // only set if EarlyData is true
+
+ // Client-side TLS 1.3-only fields.
+ useBy uint64 // seconds since UNIX epoch
+ ageAdd uint32
+}
+
+// Bytes encodes the session, including any private fields, so that it can be
+// parsed by [ParseSessionState]. The encoding contains secret values critical
+// to the security of future and possibly past sessions.
+//
+// The specific encoding should be considered opaque and may change incompatibly
+// between Go versions.
+func (s *SessionState) Bytes() ([]byte, error) {
+ var b cryptobyte.Builder
+ b.AddUint16(s.version)
+ if s.isClient {
+ b.AddUint8(2) // client
+ } else {
+ b.AddUint8(1) // server
+ }
+ b.AddUint16(s.cipherSuite)
+ addUint64(&b, s.createdAt)
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(s.secret)
+ })
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, extra := range s.Extra {
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(extra)
+ })
+ }
+ })
+ if s.extMasterSecret {
+ b.AddUint8(1)
+ } else {
+ b.AddUint8(0)
+ }
+ if s.EarlyData {
+ b.AddUint8(1)
+ } else {
+ b.AddUint8(0)
+ }
+ marshalCertificate(&b, Certificate{
+ Certificate: certificatesToBytesSlice(s.peerCertificates),
+ OCSPStaple: s.ocspResponse,
+ SignedCertificateTimestamps: s.scts,
+ })
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, chain := range s.verifiedChains {
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ // We elide the first certificate because it's always the leaf.
+ if len(chain) == 0 {
+ b.SetError(errors.New("tls: internal error: empty verified chain"))
+ return
+ }
+ for _, cert := range chain[1:] {
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(cert.Raw)
+ })
+ }
+ })
+ }
+ })
+ if s.EarlyData {
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes([]byte(s.alpnProtocol))
+ })
+ }
+ if s.isClient {
+ if s.version >= VersionTLS13 {
+ addUint64(&b, s.useBy)
+ b.AddUint32(s.ageAdd)
+ }
+ }
+ return b.Bytes()
+}
+
+func certificatesToBytesSlice(certs []*x509.Certificate) [][]byte {
+ s := make([][]byte, 0, len(certs))
+ for _, c := range certs {
+ s = append(s, c.Raw)
+ }
+ return s
+}
+
+// ParseSessionState parses a [SessionState] encoded by [SessionState.Bytes].
+func ParseSessionState(data []byte) (*SessionState, error) {
+ ss := &SessionState{}
+ s := cryptobyte.String(data)
+ var typ, extMasterSecret, earlyData uint8
+ var cert Certificate
+ var extra cryptobyte.String
+ if !s.ReadUint16(&ss.version) ||
+ !s.ReadUint8(&typ) ||
+ (typ != 1 && typ != 2) ||
+ !s.ReadUint16(&ss.cipherSuite) ||
+ !readUint64(&s, &ss.createdAt) ||
+ !readUint8LengthPrefixed(&s, &ss.secret) ||
+ !s.ReadUint24LengthPrefixed(&extra) ||
+ !s.ReadUint8(&extMasterSecret) ||
+ !s.ReadUint8(&earlyData) ||
+ len(ss.secret) == 0 ||
+ !unmarshalCertificate(&s, &cert) {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ for !extra.Empty() {
+ var e []byte
+ if !readUint24LengthPrefixed(&extra, &e) {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ ss.Extra = append(ss.Extra, e)
+ }
+ switch extMasterSecret {
+ case 0:
+ ss.extMasterSecret = false
+ case 1:
+ ss.extMasterSecret = true
+ default:
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ switch earlyData {
+ case 0:
+ ss.EarlyData = false
+ case 1:
+ ss.EarlyData = true
+ default:
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ for _, cert := range cert.Certificate {
+ c, err := globalCertCache.newCert(cert)
+ if err != nil {
+ return nil, err
+ }
+ ss.activeCertHandles = append(ss.activeCertHandles, c)
+ ss.peerCertificates = append(ss.peerCertificates, c.cert)
+ }
+ ss.ocspResponse = cert.OCSPStaple
+ ss.scts = cert.SignedCertificateTimestamps
+ var chainList cryptobyte.String
+ if !s.ReadUint24LengthPrefixed(&chainList) {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ for !chainList.Empty() {
+ var certList cryptobyte.String
+ if !chainList.ReadUint24LengthPrefixed(&certList) {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ var chain []*x509.Certificate
+ if len(ss.peerCertificates) == 0 {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ chain = append(chain, ss.peerCertificates[0])
+ for !certList.Empty() {
+ var cert []byte
+ if !readUint24LengthPrefixed(&certList, &cert) {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ c, err := globalCertCache.newCert(cert)
+ if err != nil {
+ return nil, err
+ }
+ ss.activeCertHandles = append(ss.activeCertHandles, c)
+ chain = append(chain, c.cert)
+ }
+ ss.verifiedChains = append(ss.verifiedChains, chain)
+ }
+ if ss.EarlyData {
+ var alpn []byte
+ if !readUint8LengthPrefixed(&s, &alpn) {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ ss.alpnProtocol = string(alpn)
+ }
+ if isClient := typ == 2; !isClient {
+ if !s.Empty() {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ return ss, nil
+ }
+ ss.isClient = true
+ if len(ss.peerCertificates) == 0 {
+ return nil, errors.New("tls: no server certificates in client session")
+ }
+ if ss.version < VersionTLS13 {
+ if !s.Empty() {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ return ss, nil
+ }
+ if !s.ReadUint64(&ss.useBy) || !s.ReadUint32(&ss.ageAdd) || !s.Empty() {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ return ss, nil
+}
+
+// sessionState returns a partially filled-out [SessionState] with information
+// from the current connection.
+func (c *Conn) sessionState() (*SessionState, error) {
+ return &SessionState{
+ version: c.vers,
+ cipherSuite: c.cipherSuite,
+ createdAt: uint64(c.config.time().Unix()),
+ alpnProtocol: c.clientProtocol,
+ peerCertificates: c.peerCertificates,
+ activeCertHandles: c.activeCertHandles,
+ ocspResponse: c.ocspResponse,
+ scts: c.scts,
+ isClient: c.isClient,
+ extMasterSecret: c.extMasterSecret,
+ verifiedChains: c.verifiedChains,
+ }, nil
+}
+
+// EncryptTicket encrypts a ticket with the Config's configured (or default)
+// session ticket keys. It can be used as a [Config.WrapSession] implementation.
+func (c *Config) EncryptTicket(cs ConnectionState, ss *SessionState) ([]byte, error) {
+ ticketKeys := c.ticketKeys(nil)
+ stateBytes, err := ss.Bytes()
+ if err != nil {
+ return nil, err
+ }
+ return c.encryptTicket(stateBytes, ticketKeys)
+}
+
+func (c *Config) encryptTicket(state []byte, ticketKeys []ticketKey) ([]byte, error) {
+ if len(ticketKeys) == 0 {
+ return nil, errors.New("tls: internal error: session ticket keys unavailable")
+ }
+
+ encrypted := make([]byte, aes.BlockSize+len(state)+sha256.Size)
+ iv := encrypted[:aes.BlockSize]
+ ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size]
+ authenticated := encrypted[:len(encrypted)-sha256.Size]
+ macBytes := encrypted[len(encrypted)-sha256.Size:]
+
+ if _, err := io.ReadFull(c.rand(), iv); err != nil {
+ return nil, err
+ }
+ key := ticketKeys[0]
+ block, err := aes.NewCipher(key.aesKey[:])
+ if err != nil {
+ return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error())
+ }
+ cipher.NewCTR(block, iv).XORKeyStream(ciphertext, state)
+
+ mac := hmac.New(sha256.New, key.hmacKey[:])
+ mac.Write(authenticated)
+ mac.Sum(macBytes[:0])
+
+ return encrypted, nil
+}
+
+// DecryptTicket decrypts a ticket encrypted by [Config.EncryptTicket]. It can
+// be used as a [Config.UnwrapSession] implementation.
+//
+// If the ticket can't be decrypted or parsed, DecryptTicket returns (nil, nil).
+func (c *Config) DecryptTicket(identity []byte, cs ConnectionState) (*SessionState, error) {
+ ticketKeys := c.ticketKeys(nil)
+ stateBytes := c.decryptTicket(identity, ticketKeys)
+ if stateBytes == nil {
+ return nil, nil
+ }
+ s, err := ParseSessionState(stateBytes)
+ if err != nil {
+ return nil, nil // drop unparsable tickets on the floor
+ }
+ return s, nil
+}
+
+func (c *Config) decryptTicket(encrypted []byte, ticketKeys []ticketKey) []byte {
+ if len(encrypted) < aes.BlockSize+sha256.Size {
+ return nil
+ }
+
+ iv := encrypted[:aes.BlockSize]
+ ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size]
+ authenticated := encrypted[:len(encrypted)-sha256.Size]
+ macBytes := encrypted[len(encrypted)-sha256.Size:]
+
+ for _, key := range ticketKeys {
+ mac := hmac.New(sha256.New, key.hmacKey[:])
+ mac.Write(authenticated)
+ expected := mac.Sum(nil)
+
+ if subtle.ConstantTimeCompare(macBytes, expected) != 1 {
+ continue
+ }
+
+ block, err := aes.NewCipher(key.aesKey[:])
+ if err != nil {
+ return nil
+ }
+ plaintext := make([]byte, len(ciphertext))
+ cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)
+
+ return plaintext
+ }
+
+ return nil
+}
+
+// ClientSessionState contains the state needed by a client to
+// resume a previous TLS session.
+type ClientSessionState struct {
+ ticket []byte
+ session *SessionState
+}
+
+// ResumptionState returns the session ticket sent by the server (also known as
+// the session's identity) and the state necessary to resume this session.
+//
+// It can be called by [ClientSessionCache.Put] to serialize (with
+// [SessionState.Bytes]) and store the session.
+func (cs *ClientSessionState) ResumptionState() (ticket []byte, state *SessionState, err error) {
+ return cs.ticket, cs.session, nil
+}
+
+// NewResumptionState returns a state value that can be returned by
+// [ClientSessionCache.Get] to resume a previous session.
+//
+// state needs to be returned by [ParseSessionState], and the ticket and session
+// state must have been returned by [ClientSessionState.ResumptionState].
+func NewResumptionState(ticket []byte, state *SessionState) (*ClientSessionState, error) {
+ return &ClientSessionState{
+ ticket: ticket, session: state,
+ }, nil
+}
diff --git a/contrib/go/_std_1.20/src/crypto/tls/tls.go b/contrib/go/_std_1.21/src/crypto/tls/tls.go
index b529c70523..b529c70523 100644
--- a/contrib/go/_std_1.20/src/crypto/tls/tls.go
+++ b/contrib/go/_std_1.21/src/crypto/tls/tls.go
diff --git a/contrib/go/_std_1.21/src/crypto/tls/ya.make b/contrib/go/_std_1.21/src/crypto/tls/ya.make
new file mode 100644
index 0000000000..fce6f9ee97
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/tls/ya.make
@@ -0,0 +1,54 @@
+GO_LIBRARY()
+
+SRCS(
+ alert.go
+ auth.go
+ cache.go
+ cipher_suites.go
+ common.go
+ common_string.go
+ conn.go
+ handshake_client.go
+ handshake_client_tls13.go
+ handshake_messages.go
+ handshake_server.go
+ handshake_server_tls13.go
+ key_agreement.go
+ key_schedule.go
+ notboring.go
+ prf.go
+ quic.go
+ ticket.go
+ tls.go
+)
+
+GO_TEST_SRCS(
+ auth_test.go
+ cache_test.go
+ conn_test.go
+ handshake_client_test.go
+ handshake_messages_test.go
+ handshake_server_test.go
+ handshake_test.go
+ key_schedule_test.go
+ link_test.go
+ prf_test.go
+ quic_test.go
+ ticket_test.go
+ tls_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+IF (OS_LINUX)
+ GO_TEST_SRCS(handshake_unix_test.go)
+ENDIF()
+
+IF (OS_DARWIN)
+ GO_TEST_SRCS(handshake_unix_test.go)
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/crypto/x509/cert_pool.go b/contrib/go/_std_1.21/src/crypto/x509/cert_pool.go
index e9b2c122b9..e9b2c122b9 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/cert_pool.go
+++ b/contrib/go/_std_1.21/src/crypto/x509/cert_pool.go
diff --git a/contrib/go/_std_1.20/src/crypto/x509/internal/macos/corefoundation.go b/contrib/go/_std_1.21/src/crypto/x509/internal/macos/corefoundation.go
index b4032a5d91..b4032a5d91 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/internal/macos/corefoundation.go
+++ b/contrib/go/_std_1.21/src/crypto/x509/internal/macos/corefoundation.go
diff --git a/contrib/go/_std_1.20/src/crypto/x509/internal/macos/corefoundation.s b/contrib/go/_std_1.21/src/crypto/x509/internal/macos/corefoundation.s
index 49cd084467..49cd084467 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/internal/macos/corefoundation.s
+++ b/contrib/go/_std_1.21/src/crypto/x509/internal/macos/corefoundation.s
diff --git a/contrib/go/_std_1.20/src/crypto/x509/internal/macos/security.go b/contrib/go/_std_1.21/src/crypto/x509/internal/macos/security.go
index a6972c0c09..a6972c0c09 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/internal/macos/security.go
+++ b/contrib/go/_std_1.21/src/crypto/x509/internal/macos/security.go
diff --git a/contrib/go/_std_1.20/src/crypto/x509/internal/macos/security.s b/contrib/go/_std_1.21/src/crypto/x509/internal/macos/security.s
index ed726f1127..ed726f1127 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/internal/macos/security.s
+++ b/contrib/go/_std_1.21/src/crypto/x509/internal/macos/security.s
diff --git a/contrib/go/_std_1.21/src/crypto/x509/internal/macos/ya.make b/contrib/go/_std_1.21/src/crypto/x509/internal/macos/ya.make
new file mode 100644
index 0000000000..65a47c4b7d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/x509/internal/macos/ya.make
@@ -0,0 +1,17 @@
+GO_LIBRARY()
+
+BUILD_ONLY_IF(
+ WARNING
+ OS_DARWIN
+)
+
+IF (OS_DARWIN)
+ SRCS(
+ corefoundation.go
+ corefoundation.s
+ security.go
+ security.s
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.20/src/crypto/x509/internal/ya.make b/contrib/go/_std_1.21/src/crypto/x509/internal/ya.make
index c2b4135d6d..c2b4135d6d 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/internal/ya.make
+++ b/contrib/go/_std_1.21/src/crypto/x509/internal/ya.make
diff --git a/contrib/go/_std_1.20/src/crypto/x509/notboring.go b/contrib/go/_std_1.21/src/crypto/x509/notboring.go
index c83a7272c9..c83a7272c9 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/notboring.go
+++ b/contrib/go/_std_1.21/src/crypto/x509/notboring.go
diff --git a/contrib/go/_std_1.21/src/crypto/x509/parser.go b/contrib/go/_std_1.21/src/crypto/x509/parser.go
new file mode 100644
index 0000000000..6695212a0b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/x509/parser.go
@@ -0,0 +1,1193 @@
+// 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 x509
+
+import (
+ "bytes"
+ "crypto/dsa"
+ "crypto/ecdh"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/elliptic"
+ "crypto/rsa"
+ "crypto/x509/pkix"
+ "encoding/asn1"
+ "errors"
+ "fmt"
+ "math/big"
+ "net"
+ "net/url"
+ "strconv"
+ "strings"
+ "time"
+ "unicode/utf16"
+ "unicode/utf8"
+
+ "golang.org/x/crypto/cryptobyte"
+ cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
+)
+
+// isPrintable reports whether the given b is in the ASN.1 PrintableString set.
+// This is a simplified version of encoding/asn1.isPrintable.
+func isPrintable(b byte) bool {
+ return 'a' <= b && b <= 'z' ||
+ 'A' <= b && b <= 'Z' ||
+ '0' <= b && b <= '9' ||
+ '\'' <= b && b <= ')' ||
+ '+' <= b && b <= '/' ||
+ b == ' ' ||
+ b == ':' ||
+ b == '=' ||
+ b == '?' ||
+ // This is technically not allowed in a PrintableString.
+ // However, x509 certificates with wildcard strings don't
+ // always use the correct string type so we permit it.
+ b == '*' ||
+ // This is not technically allowed either. However, not
+ // only is it relatively common, but there are also a
+ // handful of CA certificates that contain it. At least
+ // one of which will not expire until 2027.
+ b == '&'
+}
+
+// parseASN1String parses the ASN.1 string types T61String, PrintableString,
+// UTF8String, BMPString, IA5String, and NumericString. This is mostly copied
+// from the respective encoding/asn1.parse... methods, rather than just
+// increasing the API surface of that package.
+func parseASN1String(tag cryptobyte_asn1.Tag, value []byte) (string, error) {
+ switch tag {
+ case cryptobyte_asn1.T61String:
+ return string(value), nil
+ case cryptobyte_asn1.PrintableString:
+ for _, b := range value {
+ if !isPrintable(b) {
+ return "", errors.New("invalid PrintableString")
+ }
+ }
+ return string(value), nil
+ case cryptobyte_asn1.UTF8String:
+ if !utf8.Valid(value) {
+ return "", errors.New("invalid UTF-8 string")
+ }
+ return string(value), nil
+ case cryptobyte_asn1.Tag(asn1.TagBMPString):
+ if len(value)%2 != 0 {
+ return "", errors.New("invalid BMPString")
+ }
+
+ // Strip terminator if present.
+ if l := len(value); l >= 2 && value[l-1] == 0 && value[l-2] == 0 {
+ value = value[:l-2]
+ }
+
+ s := make([]uint16, 0, len(value)/2)
+ for len(value) > 0 {
+ s = append(s, uint16(value[0])<<8+uint16(value[1]))
+ value = value[2:]
+ }
+
+ return string(utf16.Decode(s)), nil
+ case cryptobyte_asn1.IA5String:
+ s := string(value)
+ if isIA5String(s) != nil {
+ return "", errors.New("invalid IA5String")
+ }
+ return s, nil
+ case cryptobyte_asn1.Tag(asn1.TagNumericString):
+ for _, b := range value {
+ if !('0' <= b && b <= '9' || b == ' ') {
+ return "", errors.New("invalid NumericString")
+ }
+ }
+ return string(value), nil
+ }
+ return "", fmt.Errorf("unsupported string type: %v", tag)
+}
+
+// parseName parses a DER encoded Name as defined in RFC 5280. We may
+// want to export this function in the future for use in crypto/tls.
+func parseName(raw cryptobyte.String) (*pkix.RDNSequence, error) {
+ if !raw.ReadASN1(&raw, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: invalid RDNSequence")
+ }
+
+ var rdnSeq pkix.RDNSequence
+ for !raw.Empty() {
+ var rdnSet pkix.RelativeDistinguishedNameSET
+ var set cryptobyte.String
+ if !raw.ReadASN1(&set, cryptobyte_asn1.SET) {
+ return nil, errors.New("x509: invalid RDNSequence")
+ }
+ for !set.Empty() {
+ var atav cryptobyte.String
+ if !set.ReadASN1(&atav, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: invalid RDNSequence: invalid attribute")
+ }
+ var attr pkix.AttributeTypeAndValue
+ if !atav.ReadASN1ObjectIdentifier(&attr.Type) {
+ return nil, errors.New("x509: invalid RDNSequence: invalid attribute type")
+ }
+ var rawValue cryptobyte.String
+ var valueTag cryptobyte_asn1.Tag
+ if !atav.ReadAnyASN1(&rawValue, &valueTag) {
+ return nil, errors.New("x509: invalid RDNSequence: invalid attribute value")
+ }
+ var err error
+ attr.Value, err = parseASN1String(valueTag, rawValue)
+ if err != nil {
+ return nil, fmt.Errorf("x509: invalid RDNSequence: invalid attribute value: %s", err)
+ }
+ rdnSet = append(rdnSet, attr)
+ }
+
+ rdnSeq = append(rdnSeq, rdnSet)
+ }
+
+ return &rdnSeq, nil
+}
+
+func parseAI(der cryptobyte.String) (pkix.AlgorithmIdentifier, error) {
+ ai := pkix.AlgorithmIdentifier{}
+ if !der.ReadASN1ObjectIdentifier(&ai.Algorithm) {
+ return ai, errors.New("x509: malformed OID")
+ }
+ if der.Empty() {
+ return ai, nil
+ }
+ var params cryptobyte.String
+ var tag cryptobyte_asn1.Tag
+ if !der.ReadAnyASN1Element(&params, &tag) {
+ return ai, errors.New("x509: malformed parameters")
+ }
+ ai.Parameters.Tag = int(tag)
+ ai.Parameters.FullBytes = params
+ return ai, nil
+}
+
+func parseTime(der *cryptobyte.String) (time.Time, error) {
+ var t time.Time
+ switch {
+ case der.PeekASN1Tag(cryptobyte_asn1.UTCTime):
+ if !der.ReadASN1UTCTime(&t) {
+ return t, errors.New("x509: malformed UTCTime")
+ }
+ case der.PeekASN1Tag(cryptobyte_asn1.GeneralizedTime):
+ if !der.ReadASN1GeneralizedTime(&t) {
+ return t, errors.New("x509: malformed GeneralizedTime")
+ }
+ default:
+ return t, errors.New("x509: unsupported time format")
+ }
+ return t, nil
+}
+
+func parseValidity(der cryptobyte.String) (time.Time, time.Time, error) {
+ notBefore, err := parseTime(&der)
+ if err != nil {
+ return time.Time{}, time.Time{}, err
+ }
+ notAfter, err := parseTime(&der)
+ if err != nil {
+ return time.Time{}, time.Time{}, err
+ }
+
+ return notBefore, notAfter, nil
+}
+
+func parseExtension(der cryptobyte.String) (pkix.Extension, error) {
+ var ext pkix.Extension
+ if !der.ReadASN1ObjectIdentifier(&ext.Id) {
+ return ext, errors.New("x509: malformed extension OID field")
+ }
+ if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
+ if !der.ReadASN1Boolean(&ext.Critical) {
+ return ext, errors.New("x509: malformed extension critical field")
+ }
+ }
+ var val cryptobyte.String
+ if !der.ReadASN1(&val, cryptobyte_asn1.OCTET_STRING) {
+ return ext, errors.New("x509: malformed extension value field")
+ }
+ ext.Value = val
+ return ext, nil
+}
+
+func parsePublicKey(keyData *publicKeyInfo) (any, error) {
+ oid := keyData.Algorithm.Algorithm
+ params := keyData.Algorithm.Parameters
+ der := cryptobyte.String(keyData.PublicKey.RightAlign())
+ switch {
+ case oid.Equal(oidPublicKeyRSA):
+ // RSA public keys must have a NULL in the parameters.
+ // See RFC 3279, Section 2.3.1.
+ if !bytes.Equal(params.FullBytes, asn1.NullBytes) {
+ return nil, errors.New("x509: RSA key missing NULL parameters")
+ }
+
+ p := &pkcs1PublicKey{N: new(big.Int)}
+ if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: invalid RSA public key")
+ }
+ if !der.ReadASN1Integer(p.N) {
+ return nil, errors.New("x509: invalid RSA modulus")
+ }
+ if !der.ReadASN1Integer(&p.E) {
+ return nil, errors.New("x509: invalid RSA public exponent")
+ }
+
+ if p.N.Sign() <= 0 {
+ return nil, errors.New("x509: RSA modulus is not a positive number")
+ }
+ if p.E <= 0 {
+ return nil, errors.New("x509: RSA public exponent is not a positive number")
+ }
+
+ pub := &rsa.PublicKey{
+ E: p.E,
+ N: p.N,
+ }
+ return pub, nil
+ case oid.Equal(oidPublicKeyECDSA):
+ paramsDer := cryptobyte.String(params.FullBytes)
+ namedCurveOID := new(asn1.ObjectIdentifier)
+ if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {
+ return nil, errors.New("x509: invalid ECDSA parameters")
+ }
+ namedCurve := namedCurveFromOID(*namedCurveOID)
+ if namedCurve == nil {
+ return nil, errors.New("x509: unsupported elliptic curve")
+ }
+ x, y := elliptic.Unmarshal(namedCurve, der)
+ if x == nil {
+ return nil, errors.New("x509: failed to unmarshal elliptic curve point")
+ }
+ pub := &ecdsa.PublicKey{
+ Curve: namedCurve,
+ X: x,
+ Y: y,
+ }
+ return pub, nil
+ case oid.Equal(oidPublicKeyEd25519):
+ // RFC 8410, Section 3
+ // > For all of the OIDs, the parameters MUST be absent.
+ if len(params.FullBytes) != 0 {
+ return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")
+ }
+ if len(der) != ed25519.PublicKeySize {
+ return nil, errors.New("x509: wrong Ed25519 public key size")
+ }
+ return ed25519.PublicKey(der), nil
+ case oid.Equal(oidPublicKeyX25519):
+ // RFC 8410, Section 3
+ // > For all of the OIDs, the parameters MUST be absent.
+ if len(params.FullBytes) != 0 {
+ return nil, errors.New("x509: X25519 key encoded with illegal parameters")
+ }
+ return ecdh.X25519().NewPublicKey(der)
+ case oid.Equal(oidPublicKeyDSA):
+ y := new(big.Int)
+ if !der.ReadASN1Integer(y) {
+ return nil, errors.New("x509: invalid DSA public key")
+ }
+ pub := &dsa.PublicKey{
+ Y: y,
+ Parameters: dsa.Parameters{
+ P: new(big.Int),
+ Q: new(big.Int),
+ G: new(big.Int),
+ },
+ }
+ paramsDer := cryptobyte.String(params.FullBytes)
+ if !paramsDer.ReadASN1(&paramsDer, cryptobyte_asn1.SEQUENCE) ||
+ !paramsDer.ReadASN1Integer(pub.Parameters.P) ||
+ !paramsDer.ReadASN1Integer(pub.Parameters.Q) ||
+ !paramsDer.ReadASN1Integer(pub.Parameters.G) {
+ return nil, errors.New("x509: invalid DSA parameters")
+ }
+ if pub.Y.Sign() <= 0 || pub.Parameters.P.Sign() <= 0 ||
+ pub.Parameters.Q.Sign() <= 0 || pub.Parameters.G.Sign() <= 0 {
+ return nil, errors.New("x509: zero or negative DSA parameter")
+ }
+ return pub, nil
+ default:
+ return nil, errors.New("x509: unknown public key algorithm")
+ }
+}
+
+func parseKeyUsageExtension(der cryptobyte.String) (KeyUsage, error) {
+ var usageBits asn1.BitString
+ if !der.ReadASN1BitString(&usageBits) {
+ return 0, errors.New("x509: invalid key usage")
+ }
+
+ var usage int
+ for i := 0; i < 9; i++ {
+ if usageBits.At(i) != 0 {
+ usage |= 1 << uint(i)
+ }
+ }
+ return KeyUsage(usage), nil
+}
+
+func parseBasicConstraintsExtension(der cryptobyte.String) (bool, int, error) {
+ var isCA bool
+ if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+ return false, 0, errors.New("x509: invalid basic constraints")
+ }
+ if der.PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
+ if !der.ReadASN1Boolean(&isCA) {
+ return false, 0, errors.New("x509: invalid basic constraints")
+ }
+ }
+ maxPathLen := -1
+ if der.PeekASN1Tag(cryptobyte_asn1.INTEGER) {
+ if !der.ReadASN1Integer(&maxPathLen) {
+ return false, 0, errors.New("x509: invalid basic constraints")
+ }
+ }
+
+ // TODO: map out.MaxPathLen to 0 if it has the -1 default value? (Issue 19285)
+ return isCA, maxPathLen, nil
+}
+
+func forEachSAN(der cryptobyte.String, callback func(tag int, data []byte) error) error {
+ if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+ return errors.New("x509: invalid subject alternative names")
+ }
+ for !der.Empty() {
+ var san cryptobyte.String
+ var tag cryptobyte_asn1.Tag
+ if !der.ReadAnyASN1(&san, &tag) {
+ return errors.New("x509: invalid subject alternative name")
+ }
+ if err := callback(int(tag^0x80), san); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func parseSANExtension(der cryptobyte.String) (dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL, err error) {
+ err = forEachSAN(der, func(tag int, data []byte) error {
+ switch tag {
+ case nameTypeEmail:
+ email := string(data)
+ if err := isIA5String(email); err != nil {
+ return errors.New("x509: SAN rfc822Name is malformed")
+ }
+ emailAddresses = append(emailAddresses, email)
+ case nameTypeDNS:
+ name := string(data)
+ if err := isIA5String(name); err != nil {
+ return errors.New("x509: SAN dNSName is malformed")
+ }
+ dnsNames = append(dnsNames, string(name))
+ case nameTypeURI:
+ uriStr := string(data)
+ if err := isIA5String(uriStr); err != nil {
+ return errors.New("x509: SAN uniformResourceIdentifier is malformed")
+ }
+ uri, err := url.Parse(uriStr)
+ if err != nil {
+ return fmt.Errorf("x509: cannot parse URI %q: %s", uriStr, err)
+ }
+ if len(uri.Host) > 0 {
+ if _, ok := domainToReverseLabels(uri.Host); !ok {
+ return fmt.Errorf("x509: cannot parse URI %q: invalid domain", uriStr)
+ }
+ }
+ uris = append(uris, uri)
+ case nameTypeIP:
+ switch len(data) {
+ case net.IPv4len, net.IPv6len:
+ ipAddresses = append(ipAddresses, data)
+ default:
+ return errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len(data)))
+ }
+ }
+
+ return nil
+ })
+
+ return
+}
+
+func parseExtKeyUsageExtension(der cryptobyte.String) ([]ExtKeyUsage, []asn1.ObjectIdentifier, error) {
+ var extKeyUsages []ExtKeyUsage
+ var unknownUsages []asn1.ObjectIdentifier
+ if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+ return nil, nil, errors.New("x509: invalid extended key usages")
+ }
+ for !der.Empty() {
+ var eku asn1.ObjectIdentifier
+ if !der.ReadASN1ObjectIdentifier(&eku) {
+ return nil, nil, errors.New("x509: invalid extended key usages")
+ }
+ if extKeyUsage, ok := extKeyUsageFromOID(eku); ok {
+ extKeyUsages = append(extKeyUsages, extKeyUsage)
+ } else {
+ unknownUsages = append(unknownUsages, eku)
+ }
+ }
+ return extKeyUsages, unknownUsages, nil
+}
+
+func parseCertificatePoliciesExtension(der cryptobyte.String) ([]asn1.ObjectIdentifier, error) {
+ var oids []asn1.ObjectIdentifier
+ if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: invalid certificate policies")
+ }
+ for !der.Empty() {
+ var cp cryptobyte.String
+ if !der.ReadASN1(&cp, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: invalid certificate policies")
+ }
+ var oid asn1.ObjectIdentifier
+ if !cp.ReadASN1ObjectIdentifier(&oid) {
+ return nil, errors.New("x509: invalid certificate policies")
+ }
+ oids = append(oids, oid)
+ }
+
+ return oids, nil
+}
+
+// isValidIPMask reports whether mask consists of zero or more 1 bits, followed by zero bits.
+func isValidIPMask(mask []byte) bool {
+ seenZero := false
+
+ for _, b := range mask {
+ if seenZero {
+ if b != 0 {
+ return false
+ }
+
+ continue
+ }
+
+ switch b {
+ case 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe:
+ seenZero = true
+ case 0xff:
+ default:
+ return false
+ }
+ }
+
+ return true
+}
+
+func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandled bool, err error) {
+ // RFC 5280, 4.2.1.10
+
+ // NameConstraints ::= SEQUENCE {
+ // permittedSubtrees [0] GeneralSubtrees OPTIONAL,
+ // excludedSubtrees [1] GeneralSubtrees OPTIONAL }
+ //
+ // GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+ //
+ // GeneralSubtree ::= SEQUENCE {
+ // base GeneralName,
+ // minimum [0] BaseDistance DEFAULT 0,
+ // maximum [1] BaseDistance OPTIONAL }
+ //
+ // BaseDistance ::= INTEGER (0..MAX)
+
+ outer := cryptobyte.String(e.Value)
+ var toplevel, permitted, excluded cryptobyte.String
+ var havePermitted, haveExcluded bool
+ if !outer.ReadASN1(&toplevel, cryptobyte_asn1.SEQUENCE) ||
+ !outer.Empty() ||
+ !toplevel.ReadOptionalASN1(&permitted, &havePermitted, cryptobyte_asn1.Tag(0).ContextSpecific().Constructed()) ||
+ !toplevel.ReadOptionalASN1(&excluded, &haveExcluded, cryptobyte_asn1.Tag(1).ContextSpecific().Constructed()) ||
+ !toplevel.Empty() {
+ return false, errors.New("x509: invalid NameConstraints extension")
+ }
+
+ if !havePermitted && !haveExcluded || len(permitted) == 0 && len(excluded) == 0 {
+ // From RFC 5280, Section 4.2.1.10:
+ // “either the permittedSubtrees field
+ // or the excludedSubtrees MUST be
+ // present”
+ return false, errors.New("x509: empty name constraints extension")
+ }
+
+ getValues := func(subtrees cryptobyte.String) (dnsNames []string, ips []*net.IPNet, emails, uriDomains []string, err error) {
+ for !subtrees.Empty() {
+ var seq, value cryptobyte.String
+ var tag cryptobyte_asn1.Tag
+ if !subtrees.ReadASN1(&seq, cryptobyte_asn1.SEQUENCE) ||
+ !seq.ReadAnyASN1(&value, &tag) {
+ return nil, nil, nil, nil, fmt.Errorf("x509: invalid NameConstraints extension")
+ }
+
+ var (
+ dnsTag = cryptobyte_asn1.Tag(2).ContextSpecific()
+ emailTag = cryptobyte_asn1.Tag(1).ContextSpecific()
+ ipTag = cryptobyte_asn1.Tag(7).ContextSpecific()
+ uriTag = cryptobyte_asn1.Tag(6).ContextSpecific()
+ )
+
+ switch tag {
+ case dnsTag:
+ domain := string(value)
+ if err := isIA5String(domain); err != nil {
+ return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
+ }
+
+ trimmedDomain := domain
+ if len(trimmedDomain) > 0 && trimmedDomain[0] == '.' {
+ // constraints can have a leading
+ // period to exclude the domain
+ // itself, but that's not valid in a
+ // normal domain name.
+ trimmedDomain = trimmedDomain[1:]
+ }
+ if _, ok := domainToReverseLabels(trimmedDomain); !ok {
+ return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse dnsName constraint %q", domain)
+ }
+ dnsNames = append(dnsNames, domain)
+
+ case ipTag:
+ l := len(value)
+ var ip, mask []byte
+
+ switch l {
+ case 8:
+ ip = value[:4]
+ mask = value[4:]
+
+ case 32:
+ ip = value[:16]
+ mask = value[16:]
+
+ default:
+ return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained value of length %d", l)
+ }
+
+ if !isValidIPMask(mask) {
+ return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained invalid mask %x", mask)
+ }
+
+ ips = append(ips, &net.IPNet{IP: net.IP(ip), Mask: net.IPMask(mask)})
+
+ case emailTag:
+ constraint := string(value)
+ if err := isIA5String(constraint); err != nil {
+ return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
+ }
+
+ // If the constraint contains an @ then
+ // it specifies an exact mailbox name.
+ if strings.Contains(constraint, "@") {
+ if _, ok := parseRFC2821Mailbox(constraint); !ok {
+ return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
+ }
+ } else {
+ // Otherwise it's a domain name.
+ domain := constraint
+ if len(domain) > 0 && domain[0] == '.' {
+ domain = domain[1:]
+ }
+ if _, ok := domainToReverseLabels(domain); !ok {
+ return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
+ }
+ }
+ emails = append(emails, constraint)
+
+ case uriTag:
+ domain := string(value)
+ if err := isIA5String(domain); err != nil {
+ return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + err.Error())
+ }
+
+ if net.ParseIP(domain) != nil {
+ return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q: cannot be IP address", domain)
+ }
+
+ trimmedDomain := domain
+ if len(trimmedDomain) > 0 && trimmedDomain[0] == '.' {
+ // constraints can have a leading
+ // period to exclude the domain itself,
+ // but that's not valid in a normal
+ // domain name.
+ trimmedDomain = trimmedDomain[1:]
+ }
+ if _, ok := domainToReverseLabels(trimmedDomain); !ok {
+ return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q", domain)
+ }
+ uriDomains = append(uriDomains, domain)
+
+ default:
+ unhandled = true
+ }
+ }
+
+ return dnsNames, ips, emails, uriDomains, nil
+ }
+
+ if out.PermittedDNSDomains, out.PermittedIPRanges, out.PermittedEmailAddresses, out.PermittedURIDomains, err = getValues(permitted); err != nil {
+ return false, err
+ }
+ if out.ExcludedDNSDomains, out.ExcludedIPRanges, out.ExcludedEmailAddresses, out.ExcludedURIDomains, err = getValues(excluded); err != nil {
+ return false, err
+ }
+ out.PermittedDNSDomainsCritical = e.Critical
+
+ return unhandled, nil
+}
+
+func processExtensions(out *Certificate) error {
+ var err error
+ for _, e := range out.Extensions {
+ unhandled := false
+
+ if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 {
+ switch e.Id[3] {
+ case 15:
+ out.KeyUsage, err = parseKeyUsageExtension(e.Value)
+ if err != nil {
+ return err
+ }
+ case 19:
+ out.IsCA, out.MaxPathLen, err = parseBasicConstraintsExtension(e.Value)
+ if err != nil {
+ return err
+ }
+ out.BasicConstraintsValid = true
+ out.MaxPathLenZero = out.MaxPathLen == 0
+ case 17:
+ out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(e.Value)
+ if err != nil {
+ return err
+ }
+
+ if len(out.DNSNames) == 0 && len(out.EmailAddresses) == 0 && len(out.IPAddresses) == 0 && len(out.URIs) == 0 {
+ // If we didn't parse anything then we do the critical check, below.
+ unhandled = true
+ }
+
+ case 30:
+ unhandled, err = parseNameConstraintsExtension(out, e)
+ if err != nil {
+ return err
+ }
+
+ case 31:
+ // RFC 5280, 4.2.1.13
+
+ // CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+ //
+ // DistributionPoint ::= SEQUENCE {
+ // distributionPoint [0] DistributionPointName OPTIONAL,
+ // reasons [1] ReasonFlags OPTIONAL,
+ // cRLIssuer [2] GeneralNames OPTIONAL }
+ //
+ // DistributionPointName ::= CHOICE {
+ // fullName [0] GeneralNames,
+ // nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
+ val := cryptobyte.String(e.Value)
+ if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {
+ return errors.New("x509: invalid CRL distribution points")
+ }
+ for !val.Empty() {
+ var dpDER cryptobyte.String
+ if !val.ReadASN1(&dpDER, cryptobyte_asn1.SEQUENCE) {
+ return errors.New("x509: invalid CRL distribution point")
+ }
+ var dpNameDER cryptobyte.String
+ var dpNamePresent bool
+ if !dpDER.ReadOptionalASN1(&dpNameDER, &dpNamePresent, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
+ return errors.New("x509: invalid CRL distribution point")
+ }
+ if !dpNamePresent {
+ continue
+ }
+ if !dpNameDER.ReadASN1(&dpNameDER, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
+ return errors.New("x509: invalid CRL distribution point")
+ }
+ for !dpNameDER.Empty() {
+ if !dpNameDER.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {
+ break
+ }
+ var uri cryptobyte.String
+ if !dpNameDER.ReadASN1(&uri, cryptobyte_asn1.Tag(6).ContextSpecific()) {
+ return errors.New("x509: invalid CRL distribution point")
+ }
+ out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(uri))
+ }
+ }
+
+ case 35:
+ // RFC 5280, 4.2.1.1
+ val := cryptobyte.String(e.Value)
+ var akid cryptobyte.String
+ if !val.ReadASN1(&akid, cryptobyte_asn1.SEQUENCE) {
+ return errors.New("x509: invalid authority key identifier")
+ }
+ if akid.PeekASN1Tag(cryptobyte_asn1.Tag(0).ContextSpecific()) {
+ if !akid.ReadASN1(&akid, cryptobyte_asn1.Tag(0).ContextSpecific()) {
+ return errors.New("x509: invalid authority key identifier")
+ }
+ out.AuthorityKeyId = akid
+ }
+ case 37:
+ out.ExtKeyUsage, out.UnknownExtKeyUsage, err = parseExtKeyUsageExtension(e.Value)
+ if err != nil {
+ return err
+ }
+ case 14:
+ // RFC 5280, 4.2.1.2
+ val := cryptobyte.String(e.Value)
+ var skid cryptobyte.String
+ if !val.ReadASN1(&skid, cryptobyte_asn1.OCTET_STRING) {
+ return errors.New("x509: invalid subject key identifier")
+ }
+ out.SubjectKeyId = skid
+ case 32:
+ out.PolicyIdentifiers, err = parseCertificatePoliciesExtension(e.Value)
+ if err != nil {
+ return err
+ }
+ default:
+ // Unknown extensions are recorded if critical.
+ unhandled = true
+ }
+ } else if e.Id.Equal(oidExtensionAuthorityInfoAccess) {
+ // RFC 5280 4.2.2.1: Authority Information Access
+ val := cryptobyte.String(e.Value)
+ if !val.ReadASN1(&val, cryptobyte_asn1.SEQUENCE) {
+ return errors.New("x509: invalid authority info access")
+ }
+ for !val.Empty() {
+ var aiaDER cryptobyte.String
+ if !val.ReadASN1(&aiaDER, cryptobyte_asn1.SEQUENCE) {
+ return errors.New("x509: invalid authority info access")
+ }
+ var method asn1.ObjectIdentifier
+ if !aiaDER.ReadASN1ObjectIdentifier(&method) {
+ return errors.New("x509: invalid authority info access")
+ }
+ if !aiaDER.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {
+ continue
+ }
+ if !aiaDER.ReadASN1(&aiaDER, cryptobyte_asn1.Tag(6).ContextSpecific()) {
+ return errors.New("x509: invalid authority info access")
+ }
+ switch {
+ case method.Equal(oidAuthorityInfoAccessOcsp):
+ out.OCSPServer = append(out.OCSPServer, string(aiaDER))
+ case method.Equal(oidAuthorityInfoAccessIssuers):
+ out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(aiaDER))
+ }
+ }
+ } else {
+ // Unknown extensions are recorded if critical.
+ unhandled = true
+ }
+
+ if e.Critical && unhandled {
+ out.UnhandledCriticalExtensions = append(out.UnhandledCriticalExtensions, e.Id)
+ }
+ }
+
+ return nil
+}
+
+func parseCertificate(der []byte) (*Certificate, error) {
+ cert := &Certificate{}
+
+ input := cryptobyte.String(der)
+ // we read the SEQUENCE including length and tag bytes so that
+ // we can populate Certificate.Raw, before unwrapping the
+ // SEQUENCE so it can be operated on
+ if !input.ReadASN1Element(&input, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed certificate")
+ }
+ cert.Raw = input
+ if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed certificate")
+ }
+
+ var tbs cryptobyte.String
+ // do the same trick again as above to extract the raw
+ // bytes for Certificate.RawTBSCertificate
+ if !input.ReadASN1Element(&tbs, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed tbs certificate")
+ }
+ cert.RawTBSCertificate = tbs
+ if !tbs.ReadASN1(&tbs, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed tbs certificate")
+ }
+
+ if !tbs.ReadOptionalASN1Integer(&cert.Version, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific(), 0) {
+ return nil, errors.New("x509: malformed version")
+ }
+ if cert.Version < 0 {
+ return nil, errors.New("x509: malformed version")
+ }
+ // for backwards compat reasons Version is one-indexed,
+ // rather than zero-indexed as defined in 5280
+ cert.Version++
+ if cert.Version > 3 {
+ return nil, errors.New("x509: invalid version")
+ }
+
+ serial := new(big.Int)
+ if !tbs.ReadASN1Integer(serial) {
+ return nil, errors.New("x509: malformed serial number")
+ }
+ // we ignore the presence of negative serial numbers because
+ // of their prevalence, despite them being invalid
+ // TODO(rolandshoemaker): revisit this decision, there are currently
+ // only 10 trusted certificates with negative serial numbers
+ // according to censys.io.
+ cert.SerialNumber = serial
+
+ var sigAISeq cryptobyte.String
+ if !tbs.ReadASN1(&sigAISeq, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed signature algorithm identifier")
+ }
+ // Before parsing the inner algorithm identifier, extract
+ // the outer algorithm identifier and make sure that they
+ // match.
+ var outerSigAISeq cryptobyte.String
+ if !input.ReadASN1(&outerSigAISeq, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed algorithm identifier")
+ }
+ if !bytes.Equal(outerSigAISeq, sigAISeq) {
+ return nil, errors.New("x509: inner and outer signature algorithm identifiers don't match")
+ }
+ sigAI, err := parseAI(sigAISeq)
+ if err != nil {
+ return nil, err
+ }
+ cert.SignatureAlgorithm = getSignatureAlgorithmFromAI(sigAI)
+
+ var issuerSeq cryptobyte.String
+ if !tbs.ReadASN1Element(&issuerSeq, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed issuer")
+ }
+ cert.RawIssuer = issuerSeq
+ issuerRDNs, err := parseName(issuerSeq)
+ if err != nil {
+ return nil, err
+ }
+ cert.Issuer.FillFromRDNSequence(issuerRDNs)
+
+ var validity cryptobyte.String
+ if !tbs.ReadASN1(&validity, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed validity")
+ }
+ cert.NotBefore, cert.NotAfter, err = parseValidity(validity)
+ if err != nil {
+ return nil, err
+ }
+
+ var subjectSeq cryptobyte.String
+ if !tbs.ReadASN1Element(&subjectSeq, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed issuer")
+ }
+ cert.RawSubject = subjectSeq
+ subjectRDNs, err := parseName(subjectSeq)
+ if err != nil {
+ return nil, err
+ }
+ cert.Subject.FillFromRDNSequence(subjectRDNs)
+
+ var spki cryptobyte.String
+ if !tbs.ReadASN1Element(&spki, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed spki")
+ }
+ cert.RawSubjectPublicKeyInfo = spki
+ if !spki.ReadASN1(&spki, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed spki")
+ }
+ var pkAISeq cryptobyte.String
+ if !spki.ReadASN1(&pkAISeq, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed public key algorithm identifier")
+ }
+ pkAI, err := parseAI(pkAISeq)
+ if err != nil {
+ return nil, err
+ }
+ cert.PublicKeyAlgorithm = getPublicKeyAlgorithmFromOID(pkAI.Algorithm)
+ var spk asn1.BitString
+ if !spki.ReadASN1BitString(&spk) {
+ return nil, errors.New("x509: malformed subjectPublicKey")
+ }
+ if cert.PublicKeyAlgorithm != UnknownPublicKeyAlgorithm {
+ cert.PublicKey, err = parsePublicKey(&publicKeyInfo{
+ Algorithm: pkAI,
+ PublicKey: spk,
+ })
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if cert.Version > 1 {
+ if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(1).ContextSpecific()) {
+ return nil, errors.New("x509: malformed issuerUniqueID")
+ }
+ if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(2).ContextSpecific()) {
+ return nil, errors.New("x509: malformed subjectUniqueID")
+ }
+ if cert.Version == 3 {
+ var extensions cryptobyte.String
+ var present bool
+ if !tbs.ReadOptionalASN1(&extensions, &present, cryptobyte_asn1.Tag(3).Constructed().ContextSpecific()) {
+ return nil, errors.New("x509: malformed extensions")
+ }
+ if present {
+ seenExts := make(map[string]bool)
+ if !extensions.ReadASN1(&extensions, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed extensions")
+ }
+ for !extensions.Empty() {
+ var extension cryptobyte.String
+ if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed extension")
+ }
+ ext, err := parseExtension(extension)
+ if err != nil {
+ return nil, err
+ }
+ oidStr := ext.Id.String()
+ if seenExts[oidStr] {
+ return nil, errors.New("x509: certificate contains duplicate extensions")
+ }
+ seenExts[oidStr] = true
+ cert.Extensions = append(cert.Extensions, ext)
+ }
+ err = processExtensions(cert)
+ if err != nil {
+ return nil, err
+ }
+ }
+ }
+ }
+
+ var signature asn1.BitString
+ if !input.ReadASN1BitString(&signature) {
+ return nil, errors.New("x509: malformed signature")
+ }
+ cert.Signature = signature.RightAlign()
+
+ return cert, nil
+}
+
+// ParseCertificate parses a single certificate from the given ASN.1 DER data.
+func ParseCertificate(der []byte) (*Certificate, error) {
+ cert, err := parseCertificate(der)
+ if err != nil {
+ return nil, err
+ }
+ if len(der) != len(cert.Raw) {
+ return nil, errors.New("x509: trailing data")
+ }
+ return cert, err
+}
+
+// ParseCertificates parses one or more certificates from the given ASN.1 DER
+// data. The certificates must be concatenated with no intermediate padding.
+func ParseCertificates(der []byte) ([]*Certificate, error) {
+ var certs []*Certificate
+ for len(der) > 0 {
+ cert, err := parseCertificate(der)
+ if err != nil {
+ return nil, err
+ }
+ certs = append(certs, cert)
+ der = der[len(cert.Raw):]
+ }
+ return certs, nil
+}
+
+// The X.509 standards confusingly 1-indexed the version names, but 0-indexed
+// the actual encoded version, so the version for X.509v2 is 1.
+const x509v2Version = 1
+
+// ParseRevocationList parses a X509 v2 Certificate Revocation List from the given
+// ASN.1 DER data.
+func ParseRevocationList(der []byte) (*RevocationList, error) {
+ rl := &RevocationList{}
+
+ input := cryptobyte.String(der)
+ // we read the SEQUENCE including length and tag bytes so that
+ // we can populate RevocationList.Raw, before unwrapping the
+ // SEQUENCE so it can be operated on
+ if !input.ReadASN1Element(&input, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed crl")
+ }
+ rl.Raw = input
+ if !input.ReadASN1(&input, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed crl")
+ }
+
+ var tbs cryptobyte.String
+ // do the same trick again as above to extract the raw
+ // bytes for Certificate.RawTBSCertificate
+ if !input.ReadASN1Element(&tbs, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed tbs crl")
+ }
+ rl.RawTBSRevocationList = tbs
+ if !tbs.ReadASN1(&tbs, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed tbs crl")
+ }
+
+ var version int
+ if !tbs.PeekASN1Tag(cryptobyte_asn1.INTEGER) {
+ return nil, errors.New("x509: unsupported crl version")
+ }
+ if !tbs.ReadASN1Integer(&version) {
+ return nil, errors.New("x509: malformed crl")
+ }
+ if version != x509v2Version {
+ return nil, fmt.Errorf("x509: unsupported crl version: %d", version)
+ }
+
+ var sigAISeq cryptobyte.String
+ if !tbs.ReadASN1(&sigAISeq, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed signature algorithm identifier")
+ }
+ // Before parsing the inner algorithm identifier, extract
+ // the outer algorithm identifier and make sure that they
+ // match.
+ var outerSigAISeq cryptobyte.String
+ if !input.ReadASN1(&outerSigAISeq, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed algorithm identifier")
+ }
+ if !bytes.Equal(outerSigAISeq, sigAISeq) {
+ return nil, errors.New("x509: inner and outer signature algorithm identifiers don't match")
+ }
+ sigAI, err := parseAI(sigAISeq)
+ if err != nil {
+ return nil, err
+ }
+ rl.SignatureAlgorithm = getSignatureAlgorithmFromAI(sigAI)
+
+ var signature asn1.BitString
+ if !input.ReadASN1BitString(&signature) {
+ return nil, errors.New("x509: malformed signature")
+ }
+ rl.Signature = signature.RightAlign()
+
+ var issuerSeq cryptobyte.String
+ if !tbs.ReadASN1Element(&issuerSeq, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed issuer")
+ }
+ rl.RawIssuer = issuerSeq
+ issuerRDNs, err := parseName(issuerSeq)
+ if err != nil {
+ return nil, err
+ }
+ rl.Issuer.FillFromRDNSequence(issuerRDNs)
+
+ rl.ThisUpdate, err = parseTime(&tbs)
+ if err != nil {
+ return nil, err
+ }
+ if tbs.PeekASN1Tag(cryptobyte_asn1.GeneralizedTime) || tbs.PeekASN1Tag(cryptobyte_asn1.UTCTime) {
+ rl.NextUpdate, err = parseTime(&tbs)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if tbs.PeekASN1Tag(cryptobyte_asn1.SEQUENCE) {
+ var revokedSeq cryptobyte.String
+ if !tbs.ReadASN1(&revokedSeq, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed crl")
+ }
+ for !revokedSeq.Empty() {
+ rce := RevocationListEntry{}
+
+ var certSeq cryptobyte.String
+ if !revokedSeq.ReadASN1Element(&certSeq, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed crl")
+ }
+ rce.Raw = certSeq
+ if !certSeq.ReadASN1(&certSeq, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed crl")
+ }
+
+ rce.SerialNumber = new(big.Int)
+ if !certSeq.ReadASN1Integer(rce.SerialNumber) {
+ return nil, errors.New("x509: malformed serial number")
+ }
+ rce.RevocationTime, err = parseTime(&certSeq)
+ if err != nil {
+ return nil, err
+ }
+ var extensions cryptobyte.String
+ var present bool
+ if !certSeq.ReadOptionalASN1(&extensions, &present, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed extensions")
+ }
+ if present {
+ for !extensions.Empty() {
+ var extension cryptobyte.String
+ if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed extension")
+ }
+ ext, err := parseExtension(extension)
+ if err != nil {
+ return nil, err
+ }
+ if ext.Id.Equal(oidExtensionReasonCode) {
+ val := cryptobyte.String(ext.Value)
+ if !val.ReadASN1Enum(&rce.ReasonCode) {
+ return nil, fmt.Errorf("x509: malformed reasonCode extension")
+ }
+ }
+ rce.Extensions = append(rce.Extensions, ext)
+ }
+ }
+
+ rl.RevokedCertificateEntries = append(rl.RevokedCertificateEntries, rce)
+ rcDeprecated := pkix.RevokedCertificate{
+ SerialNumber: rce.SerialNumber,
+ RevocationTime: rce.RevocationTime,
+ Extensions: rce.Extensions,
+ }
+ rl.RevokedCertificates = append(rl.RevokedCertificates, rcDeprecated)
+ }
+ }
+
+ var extensions cryptobyte.String
+ var present bool
+ if !tbs.ReadOptionalASN1(&extensions, &present, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
+ return nil, errors.New("x509: malformed extensions")
+ }
+ if present {
+ if !extensions.ReadASN1(&extensions, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed extensions")
+ }
+ for !extensions.Empty() {
+ var extension cryptobyte.String
+ if !extensions.ReadASN1(&extension, cryptobyte_asn1.SEQUENCE) {
+ return nil, errors.New("x509: malformed extension")
+ }
+ ext, err := parseExtension(extension)
+ if err != nil {
+ return nil, err
+ }
+ if ext.Id.Equal(oidExtensionAuthorityKeyId) {
+ rl.AuthorityKeyId = ext.Value
+ } else if ext.Id.Equal(oidExtensionCRLNumber) {
+ value := cryptobyte.String(ext.Value)
+ rl.Number = new(big.Int)
+ if !value.ReadASN1Integer(rl.Number) {
+ return nil, errors.New("x509: malformed crl number")
+ }
+ }
+ rl.Extensions = append(rl.Extensions, ext)
+ }
+ }
+
+ return rl, nil
+}
diff --git a/contrib/go/_std_1.20/src/crypto/x509/pem_decrypt.go b/contrib/go/_std_1.21/src/crypto/x509/pem_decrypt.go
index 682923ac53..682923ac53 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/pem_decrypt.go
+++ b/contrib/go/_std_1.21/src/crypto/x509/pem_decrypt.go
diff --git a/contrib/go/_std_1.20/src/crypto/x509/pkcs1.go b/contrib/go/_std_1.21/src/crypto/x509/pkcs1.go
index f9d384018a..f9d384018a 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/pkcs1.go
+++ b/contrib/go/_std_1.21/src/crypto/x509/pkcs1.go
diff --git a/contrib/go/_std_1.21/src/crypto/x509/pkcs8.go b/contrib/go/_std_1.21/src/crypto/x509/pkcs8.go
new file mode 100644
index 0000000000..74b2f99708
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/x509/pkcs8.go
@@ -0,0 +1,175 @@
+// Copyright 2011 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 x509
+
+import (
+ "crypto/ecdh"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "crypto/x509/pkix"
+ "encoding/asn1"
+ "errors"
+ "fmt"
+)
+
+// pkcs8 reflects an ASN.1, PKCS #8 PrivateKey. See
+// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn
+// and RFC 5208.
+type pkcs8 struct {
+ Version int
+ Algo pkix.AlgorithmIdentifier
+ PrivateKey []byte
+ // optional attributes omitted.
+}
+
+// ParsePKCS8PrivateKey parses an unencrypted private key in PKCS #8, ASN.1 DER form.
+//
+// It returns a *rsa.PrivateKey, an *ecdsa.PrivateKey, an ed25519.PrivateKey (not
+// a pointer), or an *ecdh.PrivateKey (for X25519). More types might be supported
+// in the future.
+//
+// This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY".
+func ParsePKCS8PrivateKey(der []byte) (key any, err error) {
+ var privKey pkcs8
+ if _, err := asn1.Unmarshal(der, &privKey); err != nil {
+ if _, err := asn1.Unmarshal(der, &ecPrivateKey{}); err == nil {
+ return nil, errors.New("x509: failed to parse private key (use ParseECPrivateKey instead for this key format)")
+ }
+ if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil {
+ return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)")
+ }
+ return nil, err
+ }
+ switch {
+ case privKey.Algo.Algorithm.Equal(oidPublicKeyRSA):
+ key, err = ParsePKCS1PrivateKey(privKey.PrivateKey)
+ if err != nil {
+ return nil, errors.New("x509: failed to parse RSA private key embedded in PKCS#8: " + err.Error())
+ }
+ return key, nil
+
+ case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA):
+ bytes := privKey.Algo.Parameters.FullBytes
+ namedCurveOID := new(asn1.ObjectIdentifier)
+ if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil {
+ namedCurveOID = nil
+ }
+ key, err = parseECPrivateKey(namedCurveOID, privKey.PrivateKey)
+ if err != nil {
+ return nil, errors.New("x509: failed to parse EC private key embedded in PKCS#8: " + err.Error())
+ }
+ return key, nil
+
+ case privKey.Algo.Algorithm.Equal(oidPublicKeyEd25519):
+ if l := len(privKey.Algo.Parameters.FullBytes); l != 0 {
+ return nil, errors.New("x509: invalid Ed25519 private key parameters")
+ }
+ var curvePrivateKey []byte
+ if _, err := asn1.Unmarshal(privKey.PrivateKey, &curvePrivateKey); err != nil {
+ return nil, fmt.Errorf("x509: invalid Ed25519 private key: %v", err)
+ }
+ if l := len(curvePrivateKey); l != ed25519.SeedSize {
+ return nil, fmt.Errorf("x509: invalid Ed25519 private key length: %d", l)
+ }
+ return ed25519.NewKeyFromSeed(curvePrivateKey), nil
+
+ case privKey.Algo.Algorithm.Equal(oidPublicKeyX25519):
+ if l := len(privKey.Algo.Parameters.FullBytes); l != 0 {
+ return nil, errors.New("x509: invalid X25519 private key parameters")
+ }
+ var curvePrivateKey []byte
+ if _, err := asn1.Unmarshal(privKey.PrivateKey, &curvePrivateKey); err != nil {
+ return nil, fmt.Errorf("x509: invalid X25519 private key: %v", err)
+ }
+ return ecdh.X25519().NewPrivateKey(curvePrivateKey)
+
+ default:
+ return nil, fmt.Errorf("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v", privKey.Algo.Algorithm)
+ }
+}
+
+// MarshalPKCS8PrivateKey converts a private key to PKCS #8, ASN.1 DER form.
+//
+// The following key types are currently supported: *rsa.PrivateKey,
+// *ecdsa.PrivateKey, ed25519.PrivateKey (not a pointer), and *ecdh.PrivateKey.
+// Unsupported key types result in an error.
+//
+// This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY".
+func MarshalPKCS8PrivateKey(key any) ([]byte, error) {
+ var privKey pkcs8
+
+ switch k := key.(type) {
+ case *rsa.PrivateKey:
+ privKey.Algo = pkix.AlgorithmIdentifier{
+ Algorithm: oidPublicKeyRSA,
+ Parameters: asn1.NullRawValue,
+ }
+ privKey.PrivateKey = MarshalPKCS1PrivateKey(k)
+
+ case *ecdsa.PrivateKey:
+ oid, ok := oidFromNamedCurve(k.Curve)
+ if !ok {
+ return nil, errors.New("x509: unknown curve while marshaling to PKCS#8")
+ }
+ oidBytes, err := asn1.Marshal(oid)
+ if err != nil {
+ return nil, errors.New("x509: failed to marshal curve OID: " + err.Error())
+ }
+ privKey.Algo = pkix.AlgorithmIdentifier{
+ Algorithm: oidPublicKeyECDSA,
+ Parameters: asn1.RawValue{
+ FullBytes: oidBytes,
+ },
+ }
+ if privKey.PrivateKey, err = marshalECPrivateKeyWithOID(k, nil); err != nil {
+ return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error())
+ }
+
+ case ed25519.PrivateKey:
+ privKey.Algo = pkix.AlgorithmIdentifier{
+ Algorithm: oidPublicKeyEd25519,
+ }
+ curvePrivateKey, err := asn1.Marshal(k.Seed())
+ if err != nil {
+ return nil, fmt.Errorf("x509: failed to marshal private key: %v", err)
+ }
+ privKey.PrivateKey = curvePrivateKey
+
+ case *ecdh.PrivateKey:
+ if k.Curve() == ecdh.X25519() {
+ privKey.Algo = pkix.AlgorithmIdentifier{
+ Algorithm: oidPublicKeyX25519,
+ }
+ var err error
+ if privKey.PrivateKey, err = asn1.Marshal(k.Bytes()); err != nil {
+ return nil, fmt.Errorf("x509: failed to marshal private key: %v", err)
+ }
+ } else {
+ oid, ok := oidFromECDHCurve(k.Curve())
+ if !ok {
+ return nil, errors.New("x509: unknown curve while marshaling to PKCS#8")
+ }
+ oidBytes, err := asn1.Marshal(oid)
+ if err != nil {
+ return nil, errors.New("x509: failed to marshal curve OID: " + err.Error())
+ }
+ privKey.Algo = pkix.AlgorithmIdentifier{
+ Algorithm: oidPublicKeyECDSA,
+ Parameters: asn1.RawValue{
+ FullBytes: oidBytes,
+ },
+ }
+ if privKey.PrivateKey, err = marshalECDHPrivateKey(k); err != nil {
+ return nil, errors.New("x509: failed to marshal EC private key while building PKCS#8: " + err.Error())
+ }
+ }
+
+ default:
+ return nil, fmt.Errorf("x509: unknown key type while marshaling PKCS#8: %T", key)
+ }
+
+ return asn1.Marshal(privKey)
+}
diff --git a/contrib/go/_std_1.20/src/crypto/x509/pkix/pkix.go b/contrib/go/_std_1.21/src/crypto/x509/pkix/pkix.go
index 22a50eef39..22a50eef39 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/pkix/pkix.go
+++ b/contrib/go/_std_1.21/src/crypto/x509/pkix/pkix.go
diff --git a/contrib/go/_std_1.20/src/crypto/x509/pkix/ya.make b/contrib/go/_std_1.21/src/crypto/x509/pkix/ya.make
index a28856a362..a28856a362 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/pkix/ya.make
+++ b/contrib/go/_std_1.21/src/crypto/x509/pkix/ya.make
diff --git a/contrib/go/_std_1.21/src/crypto/x509/root.go b/contrib/go/_std_1.21/src/crypto/x509/root.go
new file mode 100644
index 0000000000..b454af2c4c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/x509/root.go
@@ -0,0 +1,75 @@
+// Copyright 2012 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 x509
+
+import (
+ "internal/godebug"
+ "sync"
+)
+
+var (
+ once sync.Once
+ systemRootsMu sync.RWMutex
+ systemRoots *CertPool
+ systemRootsErr error
+ fallbacksSet bool
+)
+
+func systemRootsPool() *CertPool {
+ once.Do(initSystemRoots)
+ systemRootsMu.RLock()
+ defer systemRootsMu.RUnlock()
+ return systemRoots
+}
+
+func initSystemRoots() {
+ systemRootsMu.Lock()
+ defer systemRootsMu.Unlock()
+ systemRoots, systemRootsErr = loadSystemRoots()
+ if systemRootsErr != nil {
+ systemRoots = nil
+ }
+}
+
+var x509usefallbackroots = godebug.New("x509usefallbackroots")
+
+// SetFallbackRoots sets the roots to use during certificate verification, if no
+// custom roots are specified and a platform verifier or a system certificate
+// pool is not available (for instance in a container which does not have a root
+// certificate bundle). SetFallbackRoots will panic if roots is nil.
+//
+// SetFallbackRoots may only be called once, if called multiple times it will
+// panic.
+//
+// The fallback behavior can be forced on all platforms, even when there is a
+// system certificate pool, by setting GODEBUG=x509usefallbackroots=1 (note that
+// on Windows and macOS this will disable usage of the platform verification
+// APIs and cause the pure Go verifier to be used). Setting
+// x509usefallbackroots=1 without calling SetFallbackRoots has no effect.
+func SetFallbackRoots(roots *CertPool) {
+ if roots == nil {
+ panic("roots must be non-nil")
+ }
+
+ // trigger initSystemRoots if it hasn't already been called before we
+ // take the lock
+ _ = systemRootsPool()
+
+ systemRootsMu.Lock()
+ defer systemRootsMu.Unlock()
+
+ if fallbacksSet {
+ panic("SetFallbackRoots has already been called")
+ }
+ fallbacksSet = true
+
+ if systemRoots != nil && (systemRoots.len() > 0 || systemRoots.systemPool) {
+ if x509usefallbackroots.Value() != "1" {
+ return
+ }
+ x509usefallbackroots.IncNonDefault()
+ }
+ systemRoots, systemRootsErr = roots, nil
+}
diff --git a/contrib/go/_std_1.20/src/crypto/x509/root_darwin.go b/contrib/go/_std_1.21/src/crypto/x509/root_darwin.go
index 469e907a8e..469e907a8e 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/root_darwin.go
+++ b/contrib/go/_std_1.21/src/crypto/x509/root_darwin.go
diff --git a/contrib/go/_std_1.20/src/crypto/x509/root_linux.go b/contrib/go/_std_1.21/src/crypto/x509/root_linux.go
index e32989b999..e32989b999 100644
--- a/contrib/go/_std_1.20/src/crypto/x509/root_linux.go
+++ b/contrib/go/_std_1.21/src/crypto/x509/root_linux.go
diff --git a/contrib/go/_std_1.21/src/crypto/x509/root_unix.go b/contrib/go/_std_1.21/src/crypto/x509/root_unix.go
new file mode 100644
index 0000000000..c513b20169
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/x509/root_unix.go
@@ -0,0 +1,108 @@
+// Copyright 2011 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.
+
+//go:build aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || wasip1
+
+package x509
+
+import (
+ "io/fs"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+const (
+ // certFileEnv is the environment variable which identifies where to locate
+ // the SSL certificate file. If set this overrides the system default.
+ certFileEnv = "SSL_CERT_FILE"
+
+ // certDirEnv is the environment variable which identifies which directory
+ // to check for SSL certificate files. If set this overrides the system default.
+ // It is a colon separated list of directories.
+ // See https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html.
+ certDirEnv = "SSL_CERT_DIR"
+)
+
+func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
+ return nil, nil
+}
+
+func loadSystemRoots() (*CertPool, error) {
+ roots := NewCertPool()
+
+ files := certFiles
+ if f := os.Getenv(certFileEnv); f != "" {
+ files = []string{f}
+ }
+
+ var firstErr error
+ for _, file := range files {
+ data, err := os.ReadFile(file)
+ if err == nil {
+ roots.AppendCertsFromPEM(data)
+ break
+ }
+ if firstErr == nil && !os.IsNotExist(err) {
+ firstErr = err
+ }
+ }
+
+ dirs := certDirectories
+ if d := os.Getenv(certDirEnv); d != "" {
+ // OpenSSL and BoringSSL both use ":" as the SSL_CERT_DIR separator.
+ // See:
+ // * https://golang.org/issue/35325
+ // * https://www.openssl.org/docs/man1.0.2/man1/c_rehash.html
+ dirs = strings.Split(d, ":")
+ }
+
+ for _, directory := range dirs {
+ fis, err := readUniqueDirectoryEntries(directory)
+ if err != nil {
+ if firstErr == nil && !os.IsNotExist(err) {
+ firstErr = err
+ }
+ continue
+ }
+ for _, fi := range fis {
+ data, err := os.ReadFile(directory + "/" + fi.Name())
+ if err == nil {
+ roots.AppendCertsFromPEM(data)
+ }
+ }
+ }
+
+ if roots.len() > 0 || firstErr == nil {
+ return roots, nil
+ }
+
+ return nil, firstErr
+}
+
+// readUniqueDirectoryEntries is like os.ReadDir but omits
+// symlinks that point within the directory.
+func readUniqueDirectoryEntries(dir string) ([]fs.DirEntry, error) {
+ files, err := os.ReadDir(dir)
+ if err != nil {
+ return nil, err
+ }
+ uniq := files[:0]
+ for _, f := range files {
+ if !isSameDirSymlink(f, dir) {
+ uniq = append(uniq, f)
+ }
+ }
+ return uniq, nil
+}
+
+// isSameDirSymlink reports whether fi in dir is a symlink with a
+// target not containing a slash.
+func isSameDirSymlink(f fs.DirEntry, dir string) bool {
+ if f.Type()&fs.ModeSymlink == 0 {
+ return false
+ }
+ target, err := os.Readlink(filepath.Join(dir, f.Name()))
+ return err == nil && !strings.Contains(target, "/")
+}
diff --git a/contrib/go/_std_1.21/src/crypto/x509/root_windows.go b/contrib/go/_std_1.21/src/crypto/x509/root_windows.go
new file mode 100644
index 0000000000..11a4257b01
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/x509/root_windows.go
@@ -0,0 +1,277 @@
+// Copyright 2012 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 x509
+
+import (
+ "bytes"
+ "errors"
+ "strings"
+ "syscall"
+ "unsafe"
+)
+
+func loadSystemRoots() (*CertPool, error) {
+ return &CertPool{systemPool: true}, nil
+}
+
+// Creates a new *syscall.CertContext representing the leaf certificate in an in-memory
+// certificate store containing itself and all of the intermediate certificates specified
+// in the opts.Intermediates CertPool.
+//
+// A pointer to the in-memory store is available in the returned CertContext's Store field.
+// The store is automatically freed when the CertContext is freed using
+// syscall.CertFreeCertificateContext.
+func createStoreContext(leaf *Certificate, opts *VerifyOptions) (*syscall.CertContext, error) {
+ var storeCtx *syscall.CertContext
+
+ leafCtx, err := syscall.CertCreateCertificateContext(syscall.X509_ASN_ENCODING|syscall.PKCS_7_ASN_ENCODING, &leaf.Raw[0], uint32(len(leaf.Raw)))
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CertFreeCertificateContext(leafCtx)
+
+ handle, err := syscall.CertOpenStore(syscall.CERT_STORE_PROV_MEMORY, 0, 0, syscall.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, 0)
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CertCloseStore(handle, 0)
+
+ err = syscall.CertAddCertificateContextToStore(handle, leafCtx, syscall.CERT_STORE_ADD_ALWAYS, &storeCtx)
+ if err != nil {
+ return nil, err
+ }
+
+ if opts.Intermediates != nil {
+ for i := 0; i < opts.Intermediates.len(); i++ {
+ intermediate, err := opts.Intermediates.cert(i)
+ if err != nil {
+ return nil, err
+ }
+ ctx, err := syscall.CertCreateCertificateContext(syscall.X509_ASN_ENCODING|syscall.PKCS_7_ASN_ENCODING, &intermediate.Raw[0], uint32(len(intermediate.Raw)))
+ if err != nil {
+ return nil, err
+ }
+
+ err = syscall.CertAddCertificateContextToStore(handle, ctx, syscall.CERT_STORE_ADD_ALWAYS, nil)
+ syscall.CertFreeCertificateContext(ctx)
+ if err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ return storeCtx, nil
+}
+
+// extractSimpleChain extracts the final certificate chain from a CertSimpleChain.
+func extractSimpleChain(simpleChain **syscall.CertSimpleChain, count int) (chain []*Certificate, err error) {
+ if simpleChain == nil || count == 0 {
+ return nil, errors.New("x509: invalid simple chain")
+ }
+
+ simpleChains := unsafe.Slice(simpleChain, count)
+ lastChain := simpleChains[count-1]
+ elements := unsafe.Slice(lastChain.Elements, lastChain.NumElements)
+ for i := 0; i < int(lastChain.NumElements); i++ {
+ // Copy the buf, since ParseCertificate does not create its own copy.
+ cert := elements[i].CertContext
+ encodedCert := unsafe.Slice(cert.EncodedCert, cert.Length)
+ buf := bytes.Clone(encodedCert)
+ parsedCert, err := ParseCertificate(buf)
+ if err != nil {
+ return nil, err
+ }
+ chain = append(chain, parsedCert)
+ }
+
+ return chain, nil
+}
+
+// checkChainTrustStatus checks the trust status of the certificate chain, translating
+// any errors it finds into Go errors in the process.
+func checkChainTrustStatus(c *Certificate, chainCtx *syscall.CertChainContext) error {
+ if chainCtx.TrustStatus.ErrorStatus != syscall.CERT_TRUST_NO_ERROR {
+ status := chainCtx.TrustStatus.ErrorStatus
+ switch status {
+ case syscall.CERT_TRUST_IS_NOT_TIME_VALID:
+ return CertificateInvalidError{c, Expired, ""}
+ case syscall.CERT_TRUST_IS_NOT_VALID_FOR_USAGE:
+ return CertificateInvalidError{c, IncompatibleUsage, ""}
+ // TODO(filippo): surface more error statuses.
+ default:
+ return UnknownAuthorityError{c, nil, nil}
+ }
+ }
+ return nil
+}
+
+// checkChainSSLServerPolicy checks that the certificate chain in chainCtx is valid for
+// use as a certificate chain for a SSL/TLS server.
+func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertChainContext, opts *VerifyOptions) error {
+ servernamep, err := syscall.UTF16PtrFromString(strings.TrimSuffix(opts.DNSName, "."))
+ if err != nil {
+ return err
+ }
+ sslPara := &syscall.SSLExtraCertChainPolicyPara{
+ AuthType: syscall.AUTHTYPE_SERVER,
+ ServerName: servernamep,
+ }
+ sslPara.Size = uint32(unsafe.Sizeof(*sslPara))
+
+ para := &syscall.CertChainPolicyPara{
+ ExtraPolicyPara: (syscall.Pointer)(unsafe.Pointer(sslPara)),
+ }
+ para.Size = uint32(unsafe.Sizeof(*para))
+
+ status := syscall.CertChainPolicyStatus{}
+ err = syscall.CertVerifyCertificateChainPolicy(syscall.CERT_CHAIN_POLICY_SSL, chainCtx, para, &status)
+ if err != nil {
+ return err
+ }
+
+ // TODO(mkrautz): use the lChainIndex and lElementIndex fields
+ // of the CertChainPolicyStatus to provide proper context, instead
+ // using c.
+ if status.Error != 0 {
+ switch status.Error {
+ case syscall.CERT_E_EXPIRED:
+ return CertificateInvalidError{c, Expired, ""}
+ case syscall.CERT_E_CN_NO_MATCH:
+ return HostnameError{c, opts.DNSName}
+ case syscall.CERT_E_UNTRUSTEDROOT:
+ return UnknownAuthorityError{c, nil, nil}
+ default:
+ return UnknownAuthorityError{c, nil, nil}
+ }
+ }
+
+ return nil
+}
+
+// windowsExtKeyUsageOIDs are the C NUL-terminated string representations of the
+// OIDs for use with the Windows API.
+var windowsExtKeyUsageOIDs = make(map[ExtKeyUsage][]byte, len(extKeyUsageOIDs))
+
+func init() {
+ for _, eku := range extKeyUsageOIDs {
+ windowsExtKeyUsageOIDs[eku.extKeyUsage] = []byte(eku.oid.String() + "\x00")
+ }
+}
+
+func verifyChain(c *Certificate, chainCtx *syscall.CertChainContext, opts *VerifyOptions) (chain []*Certificate, err error) {
+ err = checkChainTrustStatus(c, chainCtx)
+ if err != nil {
+ return nil, err
+ }
+
+ if opts != nil && len(opts.DNSName) > 0 {
+ err = checkChainSSLServerPolicy(c, chainCtx, opts)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ chain, err = extractSimpleChain(chainCtx.Chains, int(chainCtx.ChainCount))
+ if err != nil {
+ return nil, err
+ }
+ if len(chain) == 0 {
+ return nil, errors.New("x509: internal error: system verifier returned an empty chain")
+ }
+
+ // Mitigate CVE-2020-0601, where the Windows system verifier might be
+ // tricked into using custom curve parameters for a trusted root, by
+ // double-checking all ECDSA signatures. If the system was tricked into
+ // using spoofed parameters, the signature will be invalid for the correct
+ // ones we parsed. (We don't support custom curves ourselves.)
+ for i, parent := range chain[1:] {
+ if parent.PublicKeyAlgorithm != ECDSA {
+ continue
+ }
+ if err := parent.CheckSignature(chain[i].SignatureAlgorithm,
+ chain[i].RawTBSCertificate, chain[i].Signature); err != nil {
+ return nil, err
+ }
+ }
+ return chain, nil
+}
+
+// systemVerify is like Verify, except that it uses CryptoAPI calls
+// to build certificate chains and verify them.
+func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
+ storeCtx, err := createStoreContext(c, opts)
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CertFreeCertificateContext(storeCtx)
+
+ para := new(syscall.CertChainPara)
+ para.Size = uint32(unsafe.Sizeof(*para))
+
+ keyUsages := opts.KeyUsages
+ if len(keyUsages) == 0 {
+ keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
+ }
+ oids := make([]*byte, 0, len(keyUsages))
+ for _, eku := range keyUsages {
+ if eku == ExtKeyUsageAny {
+ oids = nil
+ break
+ }
+ if oid, ok := windowsExtKeyUsageOIDs[eku]; ok {
+ oids = append(oids, &oid[0])
+ }
+ }
+ if oids != nil {
+ para.RequestedUsage.Type = syscall.USAGE_MATCH_TYPE_OR
+ para.RequestedUsage.Usage.Length = uint32(len(oids))
+ para.RequestedUsage.Usage.UsageIdentifiers = &oids[0]
+ } else {
+ para.RequestedUsage.Type = syscall.USAGE_MATCH_TYPE_AND
+ para.RequestedUsage.Usage.Length = 0
+ para.RequestedUsage.Usage.UsageIdentifiers = nil
+ }
+
+ var verifyTime *syscall.Filetime
+ if opts != nil && !opts.CurrentTime.IsZero() {
+ ft := syscall.NsecToFiletime(opts.CurrentTime.UnixNano())
+ verifyTime = &ft
+ }
+
+ // The default is to return only the highest quality chain,
+ // setting this flag will add additional lower quality contexts.
+ // These are returned in the LowerQualityChains field.
+ const CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS = 0x00000080
+
+ // CertGetCertificateChain will traverse Windows's root stores in an attempt to build a verified certificate chain
+ var topCtx *syscall.CertChainContext
+ err = syscall.CertGetCertificateChain(syscall.Handle(0), storeCtx, verifyTime, storeCtx.Store, para, CERT_CHAIN_RETURN_LOWER_QUALITY_CONTEXTS, 0, &topCtx)
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CertFreeCertificateChain(topCtx)
+
+ chain, topErr := verifyChain(c, topCtx, opts)
+ if topErr == nil {
+ chains = append(chains, chain)
+ }
+
+ if lqCtxCount := topCtx.LowerQualityChainCount; lqCtxCount > 0 {
+ lqCtxs := unsafe.Slice(topCtx.LowerQualityChains, lqCtxCount)
+ for _, ctx := range lqCtxs {
+ chain, err := verifyChain(c, ctx, opts)
+ if err == nil {
+ chains = append(chains, chain)
+ }
+ }
+ }
+
+ if len(chains) == 0 {
+ // Return the error from the highest quality context.
+ return nil, topErr
+ }
+
+ return chains, nil
+}
diff --git a/contrib/go/_std_1.21/src/crypto/x509/sec1.go b/contrib/go/_std_1.21/src/crypto/x509/sec1.go
new file mode 100644
index 0000000000..6bfba0d93f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/x509/sec1.go
@@ -0,0 +1,136 @@
+// Copyright 2012 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 x509
+
+import (
+ "crypto/ecdh"
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "encoding/asn1"
+ "errors"
+ "fmt"
+ "math/big"
+)
+
+const ecPrivKeyVersion = 1
+
+// ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure.
+// References:
+//
+// RFC 5915
+// SEC1 - http://www.secg.org/sec1-v2.pdf
+//
+// Per RFC 5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in
+// most cases it is not.
+type ecPrivateKey struct {
+ Version int
+ PrivateKey []byte
+ NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"`
+ PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"`
+}
+
+// ParseECPrivateKey parses an EC private key in SEC 1, ASN.1 DER form.
+//
+// This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY".
+func ParseECPrivateKey(der []byte) (*ecdsa.PrivateKey, error) {
+ return parseECPrivateKey(nil, der)
+}
+
+// MarshalECPrivateKey converts an EC private key to SEC 1, ASN.1 DER form.
+//
+// This kind of key is commonly encoded in PEM blocks of type "EC PRIVATE KEY".
+// For a more flexible key format which is not EC specific, use
+// MarshalPKCS8PrivateKey.
+func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) {
+ oid, ok := oidFromNamedCurve(key.Curve)
+ if !ok {
+ return nil, errors.New("x509: unknown elliptic curve")
+ }
+
+ return marshalECPrivateKeyWithOID(key, oid)
+}
+
+// marshalECPrivateKeyWithOID marshals an EC private key into ASN.1, DER format and
+// sets the curve ID to the given OID, or omits it if OID is nil.
+func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectIdentifier) ([]byte, error) {
+ if !key.Curve.IsOnCurve(key.X, key.Y) {
+ return nil, errors.New("invalid elliptic key public key")
+ }
+ privateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8)
+ return asn1.Marshal(ecPrivateKey{
+ Version: 1,
+ PrivateKey: key.D.FillBytes(privateKey),
+ NamedCurveOID: oid,
+ PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)},
+ })
+}
+
+// marshalECDHPrivateKey marshals an EC private key into ASN.1, DER format
+// suitable for NIST curves.
+func marshalECDHPrivateKey(key *ecdh.PrivateKey) ([]byte, error) {
+ return asn1.Marshal(ecPrivateKey{
+ Version: 1,
+ PrivateKey: key.Bytes(),
+ PublicKey: asn1.BitString{Bytes: key.PublicKey().Bytes()},
+ })
+}
+
+// parseECPrivateKey parses an ASN.1 Elliptic Curve Private Key Structure.
+// The OID for the named curve may be provided from another source (such as
+// the PKCS8 container) - if it is provided then use this instead of the OID
+// that may exist in the EC private key structure.
+func parseECPrivateKey(namedCurveOID *asn1.ObjectIdentifier, der []byte) (key *ecdsa.PrivateKey, err error) {
+ var privKey ecPrivateKey
+ if _, err := asn1.Unmarshal(der, &privKey); err != nil {
+ if _, err := asn1.Unmarshal(der, &pkcs8{}); err == nil {
+ return nil, errors.New("x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)")
+ }
+ if _, err := asn1.Unmarshal(der, &pkcs1PrivateKey{}); err == nil {
+ return nil, errors.New("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)")
+ }
+ return nil, errors.New("x509: failed to parse EC private key: " + err.Error())
+ }
+ if privKey.Version != ecPrivKeyVersion {
+ return nil, fmt.Errorf("x509: unknown EC private key version %d", privKey.Version)
+ }
+
+ var curve elliptic.Curve
+ if namedCurveOID != nil {
+ curve = namedCurveFromOID(*namedCurveOID)
+ } else {
+ curve = namedCurveFromOID(privKey.NamedCurveOID)
+ }
+ if curve == nil {
+ return nil, errors.New("x509: unknown elliptic curve")
+ }
+
+ k := new(big.Int).SetBytes(privKey.PrivateKey)
+ curveOrder := curve.Params().N
+ if k.Cmp(curveOrder) >= 0 {
+ return nil, errors.New("x509: invalid elliptic curve private key value")
+ }
+ priv := new(ecdsa.PrivateKey)
+ priv.Curve = curve
+ priv.D = k
+
+ privateKey := make([]byte, (curveOrder.BitLen()+7)/8)
+
+ // Some private keys have leading zero padding. This is invalid
+ // according to [SEC1], but this code will ignore it.
+ for len(privKey.PrivateKey) > len(privateKey) {
+ if privKey.PrivateKey[0] != 0 {
+ return nil, errors.New("x509: invalid private key length")
+ }
+ privKey.PrivateKey = privKey.PrivateKey[1:]
+ }
+
+ // Some private keys remove all leading zeros, this is also invalid
+ // according to [SEC1] but since OpenSSL used to do this, we ignore
+ // this too.
+ copy(privateKey[len(privateKey)-len(privKey.PrivateKey):], privKey.PrivateKey)
+ priv.X, priv.Y = curve.ScalarBaseMult(privateKey)
+
+ return priv, nil
+}
diff --git a/contrib/go/_std_1.21/src/crypto/x509/verify.go b/contrib/go/_std_1.21/src/crypto/x509/verify.go
new file mode 100644
index 0000000000..345d434453
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/x509/verify.go
@@ -0,0 +1,1176 @@
+// Copyright 2011 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 x509
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/x509/pkix"
+ "errors"
+ "fmt"
+ "net"
+ "net/url"
+ "reflect"
+ "runtime"
+ "strings"
+ "time"
+ "unicode/utf8"
+)
+
+type InvalidReason int
+
+const (
+ // NotAuthorizedToSign results when a certificate is signed by another
+ // which isn't marked as a CA certificate.
+ NotAuthorizedToSign InvalidReason = iota
+ // Expired results when a certificate has expired, based on the time
+ // given in the VerifyOptions.
+ Expired
+ // CANotAuthorizedForThisName results when an intermediate or root
+ // certificate has a name constraint which doesn't permit a DNS or
+ // other name (including IP address) in the leaf certificate.
+ CANotAuthorizedForThisName
+ // TooManyIntermediates results when a path length constraint is
+ // violated.
+ TooManyIntermediates
+ // IncompatibleUsage results when the certificate's key usage indicates
+ // that it may only be used for a different purpose.
+ IncompatibleUsage
+ // NameMismatch results when the subject name of a parent certificate
+ // does not match the issuer name in the child.
+ NameMismatch
+ // NameConstraintsWithoutSANs is a legacy error and is no longer returned.
+ NameConstraintsWithoutSANs
+ // UnconstrainedName results when a CA certificate contains permitted
+ // name constraints, but leaf certificate contains a name of an
+ // unsupported or unconstrained type.
+ UnconstrainedName
+ // TooManyConstraints results when the number of comparison operations
+ // needed to check a certificate exceeds the limit set by
+ // VerifyOptions.MaxConstraintComparisions. This limit exists to
+ // prevent pathological certificates can consuming excessive amounts of
+ // CPU time to verify.
+ TooManyConstraints
+ // CANotAuthorizedForExtKeyUsage results when an intermediate or root
+ // certificate does not permit a requested extended key usage.
+ CANotAuthorizedForExtKeyUsage
+)
+
+// CertificateInvalidError results when an odd error occurs. Users of this
+// library probably want to handle all these errors uniformly.
+type CertificateInvalidError struct {
+ Cert *Certificate
+ Reason InvalidReason
+ Detail string
+}
+
+func (e CertificateInvalidError) Error() string {
+ switch e.Reason {
+ case NotAuthorizedToSign:
+ return "x509: certificate is not authorized to sign other certificates"
+ case Expired:
+ return "x509: certificate has expired or is not yet valid: " + e.Detail
+ case CANotAuthorizedForThisName:
+ return "x509: a root or intermediate certificate is not authorized to sign for this name: " + e.Detail
+ case CANotAuthorizedForExtKeyUsage:
+ return "x509: a root or intermediate certificate is not authorized for an extended key usage: " + e.Detail
+ case TooManyIntermediates:
+ return "x509: too many intermediates for path length constraint"
+ case IncompatibleUsage:
+ return "x509: certificate specifies an incompatible key usage"
+ case NameMismatch:
+ return "x509: issuer name does not match subject from issuing certificate"
+ case NameConstraintsWithoutSANs:
+ return "x509: issuer has name constraints but leaf doesn't have a SAN extension"
+ case UnconstrainedName:
+ return "x509: issuer has name constraints but leaf contains unknown or unconstrained name: " + e.Detail
+ }
+ return "x509: unknown error"
+}
+
+// HostnameError results when the set of authorized names doesn't match the
+// requested name.
+type HostnameError struct {
+ Certificate *Certificate
+ Host string
+}
+
+func (h HostnameError) Error() string {
+ c := h.Certificate
+
+ if !c.hasSANExtension() && matchHostnames(c.Subject.CommonName, h.Host) {
+ return "x509: certificate relies on legacy Common Name field, use SANs instead"
+ }
+
+ var valid string
+ if ip := net.ParseIP(h.Host); ip != nil {
+ // Trying to validate an IP
+ if len(c.IPAddresses) == 0 {
+ return "x509: cannot validate certificate for " + h.Host + " because it doesn't contain any IP SANs"
+ }
+ for _, san := range c.IPAddresses {
+ if len(valid) > 0 {
+ valid += ", "
+ }
+ valid += san.String()
+ }
+ } else {
+ valid = strings.Join(c.DNSNames, ", ")
+ }
+
+ if len(valid) == 0 {
+ return "x509: certificate is not valid for any names, but wanted to match " + h.Host
+ }
+ return "x509: certificate is valid for " + valid + ", not " + h.Host
+}
+
+// UnknownAuthorityError results when the certificate issuer is unknown
+type UnknownAuthorityError struct {
+ Cert *Certificate
+ // hintErr contains an error that may be helpful in determining why an
+ // authority wasn't found.
+ hintErr error
+ // hintCert contains a possible authority certificate that was rejected
+ // because of the error in hintErr.
+ hintCert *Certificate
+}
+
+func (e UnknownAuthorityError) Error() string {
+ s := "x509: certificate signed by unknown authority"
+ if e.hintErr != nil {
+ certName := e.hintCert.Subject.CommonName
+ if len(certName) == 0 {
+ if len(e.hintCert.Subject.Organization) > 0 {
+ certName = e.hintCert.Subject.Organization[0]
+ } else {
+ certName = "serial:" + e.hintCert.SerialNumber.String()
+ }
+ }
+ s += fmt.Sprintf(" (possibly because of %q while trying to verify candidate authority certificate %q)", e.hintErr, certName)
+ }
+ return s
+}
+
+// SystemRootsError results when we fail to load the system root certificates.
+type SystemRootsError struct {
+ Err error
+}
+
+func (se SystemRootsError) Error() string {
+ msg := "x509: failed to load system roots and no roots provided"
+ if se.Err != nil {
+ return msg + "; " + se.Err.Error()
+ }
+ return msg
+}
+
+func (se SystemRootsError) Unwrap() error { return se.Err }
+
+// errNotParsed is returned when a certificate without ASN.1 contents is
+// verified. Platform-specific verification needs the ASN.1 contents.
+var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificate")
+
+// VerifyOptions contains parameters for Certificate.Verify.
+type VerifyOptions struct {
+ // DNSName, if set, is checked against the leaf certificate with
+ // Certificate.VerifyHostname or the platform verifier.
+ DNSName string
+
+ // Intermediates is an optional pool of certificates that are not trust
+ // anchors, but can be used to form a chain from the leaf certificate to a
+ // root certificate.
+ Intermediates *CertPool
+ // Roots is the set of trusted root certificates the leaf certificate needs
+ // to chain up to. If nil, the system roots or the platform verifier are used.
+ Roots *CertPool
+
+ // CurrentTime is used to check the validity of all certificates in the
+ // chain. If zero, the current time is used.
+ CurrentTime time.Time
+
+ // KeyUsages specifies which Extended Key Usage values are acceptable. A
+ // chain is accepted if it allows any of the listed values. An empty list
+ // means ExtKeyUsageServerAuth. To accept any key usage, include ExtKeyUsageAny.
+ KeyUsages []ExtKeyUsage
+
+ // MaxConstraintComparisions is the maximum number of comparisons to
+ // perform when checking a given certificate's name constraints. If
+ // zero, a sensible default is used. This limit prevents pathological
+ // certificates from consuming excessive amounts of CPU time when
+ // validating. It does not apply to the platform verifier.
+ MaxConstraintComparisions int
+}
+
+const (
+ leafCertificate = iota
+ intermediateCertificate
+ rootCertificate
+)
+
+// rfc2821Mailbox represents a “mailbox” (which is an email address to most
+// people) by breaking it into the “local” (i.e. before the '@') and “domain”
+// parts.
+type rfc2821Mailbox struct {
+ local, domain string
+}
+
+// parseRFC2821Mailbox parses an email address into local and domain parts,
+// based on the ABNF for a “Mailbox” from RFC 2821. According to RFC 5280,
+// Section 4.2.1.6 that's correct for an rfc822Name from a certificate: “The
+// format of an rfc822Name is a "Mailbox" as defined in RFC 2821, Section 4.1.2”.
+func parseRFC2821Mailbox(in string) (mailbox rfc2821Mailbox, ok bool) {
+ if len(in) == 0 {
+ return mailbox, false
+ }
+
+ localPartBytes := make([]byte, 0, len(in)/2)
+
+ if in[0] == '"' {
+ // Quoted-string = DQUOTE *qcontent DQUOTE
+ // non-whitespace-control = %d1-8 / %d11 / %d12 / %d14-31 / %d127
+ // qcontent = qtext / quoted-pair
+ // qtext = non-whitespace-control /
+ // %d33 / %d35-91 / %d93-126
+ // quoted-pair = ("\" text) / obs-qp
+ // text = %d1-9 / %d11 / %d12 / %d14-127 / obs-text
+ //
+ // (Names beginning with “obs-” are the obsolete syntax from RFC 2822,
+ // Section 4. Since it has been 16 years, we no longer accept that.)
+ in = in[1:]
+ QuotedString:
+ for {
+ if len(in) == 0 {
+ return mailbox, false
+ }
+ c := in[0]
+ in = in[1:]
+
+ switch {
+ case c == '"':
+ break QuotedString
+
+ case c == '\\':
+ // quoted-pair
+ if len(in) == 0 {
+ return mailbox, false
+ }
+ if in[0] == 11 ||
+ in[0] == 12 ||
+ (1 <= in[0] && in[0] <= 9) ||
+ (14 <= in[0] && in[0] <= 127) {
+ localPartBytes = append(localPartBytes, in[0])
+ in = in[1:]
+ } else {
+ return mailbox, false
+ }
+
+ case c == 11 ||
+ c == 12 ||
+ // Space (char 32) is not allowed based on the
+ // BNF, but RFC 3696 gives an example that
+ // assumes that it is. Several “verified”
+ // errata continue to argue about this point.
+ // We choose to accept it.
+ c == 32 ||
+ c == 33 ||
+ c == 127 ||
+ (1 <= c && c <= 8) ||
+ (14 <= c && c <= 31) ||
+ (35 <= c && c <= 91) ||
+ (93 <= c && c <= 126):
+ // qtext
+ localPartBytes = append(localPartBytes, c)
+
+ default:
+ return mailbox, false
+ }
+ }
+ } else {
+ // Atom ("." Atom)*
+ NextChar:
+ for len(in) > 0 {
+ // atext from RFC 2822, Section 3.2.4
+ c := in[0]
+
+ switch {
+ case c == '\\':
+ // Examples given in RFC 3696 suggest that
+ // escaped characters can appear outside of a
+ // quoted string. Several “verified” errata
+ // continue to argue the point. We choose to
+ // accept it.
+ in = in[1:]
+ if len(in) == 0 {
+ return mailbox, false
+ }
+ fallthrough
+
+ case ('0' <= c && c <= '9') ||
+ ('a' <= c && c <= 'z') ||
+ ('A' <= c && c <= 'Z') ||
+ c == '!' || c == '#' || c == '$' || c == '%' ||
+ c == '&' || c == '\'' || c == '*' || c == '+' ||
+ c == '-' || c == '/' || c == '=' || c == '?' ||
+ c == '^' || c == '_' || c == '`' || c == '{' ||
+ c == '|' || c == '}' || c == '~' || c == '.':
+ localPartBytes = append(localPartBytes, in[0])
+ in = in[1:]
+
+ default:
+ break NextChar
+ }
+ }
+
+ if len(localPartBytes) == 0 {
+ return mailbox, false
+ }
+
+ // From RFC 3696, Section 3:
+ // “period (".") may also appear, but may not be used to start
+ // or end the local part, nor may two or more consecutive
+ // periods appear.”
+ twoDots := []byte{'.', '.'}
+ if localPartBytes[0] == '.' ||
+ localPartBytes[len(localPartBytes)-1] == '.' ||
+ bytes.Contains(localPartBytes, twoDots) {
+ return mailbox, false
+ }
+ }
+
+ if len(in) == 0 || in[0] != '@' {
+ return mailbox, false
+ }
+ in = in[1:]
+
+ // The RFC species a format for domains, but that's known to be
+ // violated in practice so we accept that anything after an '@' is the
+ // domain part.
+ if _, ok := domainToReverseLabels(in); !ok {
+ return mailbox, false
+ }
+
+ mailbox.local = string(localPartBytes)
+ mailbox.domain = in
+ return mailbox, true
+}
+
+// domainToReverseLabels converts a textual domain name like foo.example.com to
+// the list of labels in reverse order, e.g. ["com", "example", "foo"].
+func domainToReverseLabels(domain string) (reverseLabels []string, ok bool) {
+ for len(domain) > 0 {
+ if i := strings.LastIndexByte(domain, '.'); i == -1 {
+ reverseLabels = append(reverseLabels, domain)
+ domain = ""
+ } else {
+ reverseLabels = append(reverseLabels, domain[i+1:])
+ domain = domain[:i]
+ }
+ }
+
+ if len(reverseLabels) > 0 && len(reverseLabels[0]) == 0 {
+ // An empty label at the end indicates an absolute value.
+ return nil, false
+ }
+
+ for _, label := range reverseLabels {
+ if len(label) == 0 {
+ // Empty labels are otherwise invalid.
+ return nil, false
+ }
+
+ for _, c := range label {
+ if c < 33 || c > 126 {
+ // Invalid character.
+ return nil, false
+ }
+ }
+ }
+
+ return reverseLabels, true
+}
+
+func matchEmailConstraint(mailbox rfc2821Mailbox, constraint string) (bool, error) {
+ // If the constraint contains an @, then it specifies an exact mailbox
+ // name.
+ if strings.Contains(constraint, "@") {
+ constraintMailbox, ok := parseRFC2821Mailbox(constraint)
+ if !ok {
+ return false, fmt.Errorf("x509: internal error: cannot parse constraint %q", constraint)
+ }
+ return mailbox.local == constraintMailbox.local && strings.EqualFold(mailbox.domain, constraintMailbox.domain), nil
+ }
+
+ // Otherwise the constraint is like a DNS constraint of the domain part
+ // of the mailbox.
+ return matchDomainConstraint(mailbox.domain, constraint)
+}
+
+func matchURIConstraint(uri *url.URL, constraint string) (bool, error) {
+ // From RFC 5280, Section 4.2.1.10:
+ // “a uniformResourceIdentifier that does not include an authority
+ // component with a host name specified as a fully qualified domain
+ // name (e.g., if the URI either does not include an authority
+ // component or includes an authority component in which the host name
+ // is specified as an IP address), then the application MUST reject the
+ // certificate.”
+
+ host := uri.Host
+ if len(host) == 0 {
+ return false, fmt.Errorf("URI with empty host (%q) cannot be matched against constraints", uri.String())
+ }
+
+ if strings.Contains(host, ":") && !strings.HasSuffix(host, "]") {
+ var err error
+ host, _, err = net.SplitHostPort(uri.Host)
+ if err != nil {
+ return false, err
+ }
+ }
+
+ if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") ||
+ net.ParseIP(host) != nil {
+ return false, fmt.Errorf("URI with IP (%q) cannot be matched against constraints", uri.String())
+ }
+
+ return matchDomainConstraint(host, constraint)
+}
+
+func matchIPConstraint(ip net.IP, constraint *net.IPNet) (bool, error) {
+ if len(ip) != len(constraint.IP) {
+ return false, nil
+ }
+
+ for i := range ip {
+ if mask := constraint.Mask[i]; ip[i]&mask != constraint.IP[i]&mask {
+ return false, nil
+ }
+ }
+
+ return true, nil
+}
+
+func matchDomainConstraint(domain, constraint string) (bool, error) {
+ // The meaning of zero length constraints is not specified, but this
+ // code follows NSS and accepts them as matching everything.
+ if len(constraint) == 0 {
+ return true, nil
+ }
+
+ domainLabels, ok := domainToReverseLabels(domain)
+ if !ok {
+ return false, fmt.Errorf("x509: internal error: cannot parse domain %q", domain)
+ }
+
+ // RFC 5280 says that a leading period in a domain name means that at
+ // least one label must be prepended, but only for URI and email
+ // constraints, not DNS constraints. The code also supports that
+ // behaviour for DNS constraints.
+
+ mustHaveSubdomains := false
+ if constraint[0] == '.' {
+ mustHaveSubdomains = true
+ constraint = constraint[1:]
+ }
+
+ constraintLabels, ok := domainToReverseLabels(constraint)
+ if !ok {
+ return false, fmt.Errorf("x509: internal error: cannot parse domain %q", constraint)
+ }
+
+ if len(domainLabels) < len(constraintLabels) ||
+ (mustHaveSubdomains && len(domainLabels) == len(constraintLabels)) {
+ return false, nil
+ }
+
+ for i, constraintLabel := range constraintLabels {
+ if !strings.EqualFold(constraintLabel, domainLabels[i]) {
+ return false, nil
+ }
+ }
+
+ return true, nil
+}
+
+// checkNameConstraints checks that c permits a child certificate to claim the
+// given name, of type nameType. The argument parsedName contains the parsed
+// form of name, suitable for passing to the match function. The total number
+// of comparisons is tracked in the given count and should not exceed the given
+// limit.
+func (c *Certificate) checkNameConstraints(count *int,
+ maxConstraintComparisons int,
+ nameType string,
+ name string,
+ parsedName any,
+ match func(parsedName, constraint any) (match bool, err error),
+ permitted, excluded any) error {
+
+ excludedValue := reflect.ValueOf(excluded)
+
+ *count += excludedValue.Len()
+ if *count > maxConstraintComparisons {
+ return CertificateInvalidError{c, TooManyConstraints, ""}
+ }
+
+ for i := 0; i < excludedValue.Len(); i++ {
+ constraint := excludedValue.Index(i).Interface()
+ match, err := match(parsedName, constraint)
+ if err != nil {
+ return CertificateInvalidError{c, CANotAuthorizedForThisName, err.Error()}
+ }
+
+ if match {
+ return CertificateInvalidError{c, CANotAuthorizedForThisName, fmt.Sprintf("%s %q is excluded by constraint %q", nameType, name, constraint)}
+ }
+ }
+
+ permittedValue := reflect.ValueOf(permitted)
+
+ *count += permittedValue.Len()
+ if *count > maxConstraintComparisons {
+ return CertificateInvalidError{c, TooManyConstraints, ""}
+ }
+
+ ok := true
+ for i := 0; i < permittedValue.Len(); i++ {
+ constraint := permittedValue.Index(i).Interface()
+
+ var err error
+ if ok, err = match(parsedName, constraint); err != nil {
+ return CertificateInvalidError{c, CANotAuthorizedForThisName, err.Error()}
+ }
+
+ if ok {
+ break
+ }
+ }
+
+ if !ok {
+ return CertificateInvalidError{c, CANotAuthorizedForThisName, fmt.Sprintf("%s %q is not permitted by any constraint", nameType, name)}
+ }
+
+ return nil
+}
+
+// isValid performs validity checks on c given that it is a candidate to append
+// to the chain in currentChain.
+func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *VerifyOptions) error {
+ if len(c.UnhandledCriticalExtensions) > 0 {
+ return UnhandledCriticalExtension{}
+ }
+
+ if len(currentChain) > 0 {
+ child := currentChain[len(currentChain)-1]
+ if !bytes.Equal(child.RawIssuer, c.RawSubject) {
+ return CertificateInvalidError{c, NameMismatch, ""}
+ }
+ }
+
+ now := opts.CurrentTime
+ if now.IsZero() {
+ now = time.Now()
+ }
+ if now.Before(c.NotBefore) {
+ return CertificateInvalidError{
+ Cert: c,
+ Reason: Expired,
+ Detail: fmt.Sprintf("current time %s is before %s", now.Format(time.RFC3339), c.NotBefore.Format(time.RFC3339)),
+ }
+ } else if now.After(c.NotAfter) {
+ return CertificateInvalidError{
+ Cert: c,
+ Reason: Expired,
+ Detail: fmt.Sprintf("current time %s is after %s", now.Format(time.RFC3339), c.NotAfter.Format(time.RFC3339)),
+ }
+ }
+
+ maxConstraintComparisons := opts.MaxConstraintComparisions
+ if maxConstraintComparisons == 0 {
+ maxConstraintComparisons = 250000
+ }
+ comparisonCount := 0
+
+ if certType == intermediateCertificate || certType == rootCertificate {
+ if len(currentChain) == 0 {
+ return errors.New("x509: internal error: empty chain when appending CA cert")
+ }
+ }
+
+ if (certType == intermediateCertificate || certType == rootCertificate) &&
+ c.hasNameConstraints() {
+ toCheck := []*Certificate{}
+ for _, c := range currentChain {
+ if c.hasSANExtension() {
+ toCheck = append(toCheck, c)
+ }
+ }
+ for _, sanCert := range toCheck {
+ err := forEachSAN(sanCert.getSANExtension(), func(tag int, data []byte) error {
+ switch tag {
+ case nameTypeEmail:
+ name := string(data)
+ mailbox, ok := parseRFC2821Mailbox(name)
+ if !ok {
+ return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox)
+ }
+
+ if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "email address", name, mailbox,
+ func(parsedName, constraint any) (bool, error) {
+ return matchEmailConstraint(parsedName.(rfc2821Mailbox), constraint.(string))
+ }, c.PermittedEmailAddresses, c.ExcludedEmailAddresses); err != nil {
+ return err
+ }
+
+ case nameTypeDNS:
+ name := string(data)
+ if _, ok := domainToReverseLabels(name); !ok {
+ return fmt.Errorf("x509: cannot parse dnsName %q", name)
+ }
+
+ if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "DNS name", name, name,
+ func(parsedName, constraint any) (bool, error) {
+ return matchDomainConstraint(parsedName.(string), constraint.(string))
+ }, c.PermittedDNSDomains, c.ExcludedDNSDomains); err != nil {
+ return err
+ }
+
+ case nameTypeURI:
+ name := string(data)
+ uri, err := url.Parse(name)
+ if err != nil {
+ return fmt.Errorf("x509: internal error: URI SAN %q failed to parse", name)
+ }
+
+ if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "URI", name, uri,
+ func(parsedName, constraint any) (bool, error) {
+ return matchURIConstraint(parsedName.(*url.URL), constraint.(string))
+ }, c.PermittedURIDomains, c.ExcludedURIDomains); err != nil {
+ return err
+ }
+
+ case nameTypeIP:
+ ip := net.IP(data)
+ if l := len(ip); l != net.IPv4len && l != net.IPv6len {
+ return fmt.Errorf("x509: internal error: IP SAN %x failed to parse", data)
+ }
+
+ if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "IP address", ip.String(), ip,
+ func(parsedName, constraint any) (bool, error) {
+ return matchIPConstraint(parsedName.(net.IP), constraint.(*net.IPNet))
+ }, c.PermittedIPRanges, c.ExcludedIPRanges); err != nil {
+ return err
+ }
+
+ default:
+ // Unknown SAN types are ignored.
+ }
+
+ return nil
+ })
+
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ // KeyUsage status flags are ignored. From Engineering Security, Peter
+ // Gutmann: A European government CA marked its signing certificates as
+ // being valid for encryption only, but no-one noticed. Another
+ // European CA marked its signature keys as not being valid for
+ // signatures. A different CA marked its own trusted root certificate
+ // as being invalid for certificate signing. Another national CA
+ // distributed a certificate to be used to encrypt data for the
+ // country’s tax authority that was marked as only being usable for
+ // digital signatures but not for encryption. Yet another CA reversed
+ // the order of the bit flags in the keyUsage due to confusion over
+ // encoding endianness, essentially setting a random keyUsage in
+ // certificates that it issued. Another CA created a self-invalidating
+ // certificate by adding a certificate policy statement stipulating
+ // that the certificate had to be used strictly as specified in the
+ // keyUsage, and a keyUsage containing a flag indicating that the RSA
+ // encryption key could only be used for Diffie-Hellman key agreement.
+
+ if certType == intermediateCertificate && (!c.BasicConstraintsValid || !c.IsCA) {
+ return CertificateInvalidError{c, NotAuthorizedToSign, ""}
+ }
+
+ if c.BasicConstraintsValid && c.MaxPathLen >= 0 {
+ numIntermediates := len(currentChain) - 1
+ if numIntermediates > c.MaxPathLen {
+ return CertificateInvalidError{c, TooManyIntermediates, ""}
+ }
+ }
+
+ if !boringAllowCert(c) {
+ // IncompatibleUsage is not quite right here,
+ // but it's also the "no chains found" error
+ // and is close enough.
+ return CertificateInvalidError{c, IncompatibleUsage, ""}
+ }
+
+ return nil
+}
+
+// Verify attempts to verify c by building one or more chains from c to a
+// certificate in opts.Roots, using certificates in opts.Intermediates if
+// needed. If successful, it returns one or more chains where the first
+// element of the chain is c and the last element is from opts.Roots.
+//
+// If opts.Roots is nil, the platform verifier might be used, and
+// verification details might differ from what is described below. If system
+// roots are unavailable the returned error will be of type SystemRootsError.
+//
+// Name constraints in the intermediates will be applied to all names claimed
+// in the chain, not just opts.DNSName. Thus it is invalid for a leaf to claim
+// example.com if an intermediate doesn't permit it, even if example.com is not
+// the name being validated. Note that DirectoryName constraints are not
+// supported.
+//
+// Name constraint validation follows the rules from RFC 5280, with the
+// addition that DNS name constraints may use the leading period format
+// defined for emails and URIs. When a constraint has a leading period
+// it indicates that at least one additional label must be prepended to
+// the constrained name to be considered valid.
+//
+// Extended Key Usage values are enforced nested down a chain, so an intermediate
+// or root that enumerates EKUs prevents a leaf from asserting an EKU not in that
+// list. (While this is not specified, it is common practice in order to limit
+// the types of certificates a CA can issue.)
+//
+// Certificates that use SHA1WithRSA and ECDSAWithSHA1 signatures are not supported,
+// and will not be used to build chains.
+//
+// Certificates other than c in the returned chains should not be modified.
+//
+// WARNING: this function doesn't do any revocation checking.
+func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
+ // Platform-specific verification needs the ASN.1 contents so
+ // this makes the behavior consistent across platforms.
+ if len(c.Raw) == 0 {
+ return nil, errNotParsed
+ }
+ for i := 0; i < opts.Intermediates.len(); i++ {
+ c, err := opts.Intermediates.cert(i)
+ if err != nil {
+ return nil, fmt.Errorf("crypto/x509: error fetching intermediate: %w", err)
+ }
+ if len(c.Raw) == 0 {
+ return nil, errNotParsed
+ }
+ }
+
+ // Use platform verifiers, where available, if Roots is from SystemCertPool.
+ if runtime.GOOS == "windows" || runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
+ // Don't use the system verifier if the system pool was replaced with a non-system pool,
+ // i.e. if SetFallbackRoots was called with x509usefallbackroots=1.
+ systemPool := systemRootsPool()
+ if opts.Roots == nil && (systemPool == nil || systemPool.systemPool) {
+ return c.systemVerify(&opts)
+ }
+ if opts.Roots != nil && opts.Roots.systemPool {
+ platformChains, err := c.systemVerify(&opts)
+ // If the platform verifier succeeded, or there are no additional
+ // roots, return the platform verifier result. Otherwise, continue
+ // with the Go verifier.
+ if err == nil || opts.Roots.len() == 0 {
+ return platformChains, err
+ }
+ }
+ }
+
+ if opts.Roots == nil {
+ opts.Roots = systemRootsPool()
+ if opts.Roots == nil {
+ return nil, SystemRootsError{systemRootsErr}
+ }
+ }
+
+ err = c.isValid(leafCertificate, nil, &opts)
+ if err != nil {
+ return
+ }
+
+ if len(opts.DNSName) > 0 {
+ err = c.VerifyHostname(opts.DNSName)
+ if err != nil {
+ return
+ }
+ }
+
+ var candidateChains [][]*Certificate
+ if opts.Roots.contains(c) {
+ candidateChains = [][]*Certificate{{c}}
+ } else {
+ candidateChains, err = c.buildChains([]*Certificate{c}, nil, &opts)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if len(opts.KeyUsages) == 0 {
+ opts.KeyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
+ }
+
+ for _, eku := range opts.KeyUsages {
+ if eku == ExtKeyUsageAny {
+ // If any key usage is acceptable, no need to check the chain for
+ // key usages.
+ return candidateChains, nil
+ }
+ }
+
+ chains = make([][]*Certificate, 0, len(candidateChains))
+ for _, candidate := range candidateChains {
+ if checkChainForKeyUsage(candidate, opts.KeyUsages) {
+ chains = append(chains, candidate)
+ }
+ }
+
+ if len(chains) == 0 {
+ return nil, CertificateInvalidError{c, IncompatibleUsage, ""}
+ }
+
+ return chains, nil
+}
+
+func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate {
+ n := make([]*Certificate, len(chain)+1)
+ copy(n, chain)
+ n[len(chain)] = cert
+ return n
+}
+
+// alreadyInChain checks whether a candidate certificate is present in a chain.
+// Rather than doing a direct byte for byte equivalency check, we check if the
+// subject, public key, and SAN, if present, are equal. This prevents loops that
+// are created by mutual cross-signatures, or other cross-signature bridge
+// oddities.
+func alreadyInChain(candidate *Certificate, chain []*Certificate) bool {
+ type pubKeyEqual interface {
+ Equal(crypto.PublicKey) bool
+ }
+
+ var candidateSAN *pkix.Extension
+ for _, ext := range candidate.Extensions {
+ if ext.Id.Equal(oidExtensionSubjectAltName) {
+ candidateSAN = &ext
+ break
+ }
+ }
+
+ for _, cert := range chain {
+ if !bytes.Equal(candidate.RawSubject, cert.RawSubject) {
+ continue
+ }
+ if !candidate.PublicKey.(pubKeyEqual).Equal(cert.PublicKey) {
+ continue
+ }
+ var certSAN *pkix.Extension
+ for _, ext := range cert.Extensions {
+ if ext.Id.Equal(oidExtensionSubjectAltName) {
+ certSAN = &ext
+ break
+ }
+ }
+ if candidateSAN == nil && certSAN == nil {
+ return true
+ } else if candidateSAN == nil || certSAN == nil {
+ return false
+ }
+ if bytes.Equal(candidateSAN.Value, certSAN.Value) {
+ return true
+ }
+ }
+ return false
+}
+
+// maxChainSignatureChecks is the maximum number of CheckSignatureFrom calls
+// that an invocation of buildChains will (transitively) make. Most chains are
+// less than 15 certificates long, so this leaves space for multiple chains and
+// for failed checks due to different intermediates having the same Subject.
+const maxChainSignatureChecks = 100
+
+func (c *Certificate) buildChains(currentChain []*Certificate, sigChecks *int, opts *VerifyOptions) (chains [][]*Certificate, err error) {
+ var (
+ hintErr error
+ hintCert *Certificate
+ )
+
+ considerCandidate := func(certType int, candidate *Certificate) {
+ if alreadyInChain(candidate, currentChain) {
+ return
+ }
+
+ if sigChecks == nil {
+ sigChecks = new(int)
+ }
+ *sigChecks++
+ if *sigChecks > maxChainSignatureChecks {
+ err = errors.New("x509: signature check attempts limit reached while verifying certificate chain")
+ return
+ }
+
+ if err := c.CheckSignatureFrom(candidate); err != nil {
+ if hintErr == nil {
+ hintErr = err
+ hintCert = candidate
+ }
+ return
+ }
+
+ err = candidate.isValid(certType, currentChain, opts)
+ if err != nil {
+ if hintErr == nil {
+ hintErr = err
+ hintCert = candidate
+ }
+ return
+ }
+
+ switch certType {
+ case rootCertificate:
+ chains = append(chains, appendToFreshChain(currentChain, candidate))
+ case intermediateCertificate:
+ var childChains [][]*Certificate
+ childChains, err = candidate.buildChains(appendToFreshChain(currentChain, candidate), sigChecks, opts)
+ chains = append(chains, childChains...)
+ }
+ }
+
+ for _, root := range opts.Roots.findPotentialParents(c) {
+ considerCandidate(rootCertificate, root)
+ }
+ for _, intermediate := range opts.Intermediates.findPotentialParents(c) {
+ considerCandidate(intermediateCertificate, intermediate)
+ }
+
+ if len(chains) > 0 {
+ err = nil
+ }
+ if len(chains) == 0 && err == nil {
+ err = UnknownAuthorityError{c, hintErr, hintCert}
+ }
+
+ return
+}
+
+func validHostnamePattern(host string) bool { return validHostname(host, true) }
+func validHostnameInput(host string) bool { return validHostname(host, false) }
+
+// validHostname reports whether host is a valid hostname that can be matched or
+// matched against according to RFC 6125 2.2, with some leniency to accommodate
+// legacy values.
+func validHostname(host string, isPattern bool) bool {
+ if !isPattern {
+ host = strings.TrimSuffix(host, ".")
+ }
+ if len(host) == 0 {
+ return false
+ }
+
+ for i, part := range strings.Split(host, ".") {
+ if part == "" {
+ // Empty label.
+ return false
+ }
+ if isPattern && i == 0 && part == "*" {
+ // Only allow full left-most wildcards, as those are the only ones
+ // we match, and matching literal '*' characters is probably never
+ // the expected behavior.
+ continue
+ }
+ for j, c := range part {
+ if 'a' <= c && c <= 'z' {
+ continue
+ }
+ if '0' <= c && c <= '9' {
+ continue
+ }
+ if 'A' <= c && c <= 'Z' {
+ continue
+ }
+ if c == '-' && j != 0 {
+ continue
+ }
+ if c == '_' {
+ // Not a valid character in hostnames, but commonly
+ // found in deployments outside the WebPKI.
+ continue
+ }
+ return false
+ }
+ }
+
+ return true
+}
+
+func matchExactly(hostA, hostB string) bool {
+ if hostA == "" || hostA == "." || hostB == "" || hostB == "." {
+ return false
+ }
+ return toLowerCaseASCII(hostA) == toLowerCaseASCII(hostB)
+}
+
+func matchHostnames(pattern, host string) bool {
+ pattern = toLowerCaseASCII(pattern)
+ host = toLowerCaseASCII(strings.TrimSuffix(host, "."))
+
+ if len(pattern) == 0 || len(host) == 0 {
+ return false
+ }
+
+ patternParts := strings.Split(pattern, ".")
+ hostParts := strings.Split(host, ".")
+
+ if len(patternParts) != len(hostParts) {
+ return false
+ }
+
+ for i, patternPart := range patternParts {
+ if i == 0 && patternPart == "*" {
+ continue
+ }
+ if patternPart != hostParts[i] {
+ return false
+ }
+ }
+
+ return true
+}
+
+// toLowerCaseASCII returns a lower-case version of in. See RFC 6125 6.4.1. We use
+// an explicitly ASCII function to avoid any sharp corners resulting from
+// performing Unicode operations on DNS labels.
+func toLowerCaseASCII(in string) string {
+ // If the string is already lower-case then there's nothing to do.
+ isAlreadyLowerCase := true
+ for _, c := range in {
+ if c == utf8.RuneError {
+ // If we get a UTF-8 error then there might be
+ // upper-case ASCII bytes in the invalid sequence.
+ isAlreadyLowerCase = false
+ break
+ }
+ if 'A' <= c && c <= 'Z' {
+ isAlreadyLowerCase = false
+ break
+ }
+ }
+
+ if isAlreadyLowerCase {
+ return in
+ }
+
+ out := []byte(in)
+ for i, c := range out {
+ if 'A' <= c && c <= 'Z' {
+ out[i] += 'a' - 'A'
+ }
+ }
+ return string(out)
+}
+
+// VerifyHostname returns nil if c is a valid certificate for the named host.
+// Otherwise it returns an error describing the mismatch.
+//
+// IP addresses can be optionally enclosed in square brackets and are checked
+// against the IPAddresses field. Other names are checked case insensitively
+// against the DNSNames field. If the names are valid hostnames, the certificate
+// fields can have a wildcard as the complete left-most label (e.g. *.example.com).
+//
+// Note that the legacy Common Name field is ignored.
+func (c *Certificate) VerifyHostname(h string) error {
+ // IP addresses may be written in [ ].
+ candidateIP := h
+ if len(h) >= 3 && h[0] == '[' && h[len(h)-1] == ']' {
+ candidateIP = h[1 : len(h)-1]
+ }
+ if ip := net.ParseIP(candidateIP); ip != nil {
+ // We only match IP addresses against IP SANs.
+ // See RFC 6125, Appendix B.2.
+ for _, candidate := range c.IPAddresses {
+ if ip.Equal(candidate) {
+ return nil
+ }
+ }
+ return HostnameError{c, candidateIP}
+ }
+
+ candidateName := toLowerCaseASCII(h) // Save allocations inside the loop.
+ validCandidateName := validHostnameInput(candidateName)
+
+ for _, match := range c.DNSNames {
+ // Ideally, we'd only match valid hostnames according to RFC 6125 like
+ // browsers (more or less) do, but in practice Go is used in a wider
+ // array of contexts and can't even assume DNS resolution. Instead,
+ // always allow perfect matches, and only apply wildcard and trailing
+ // dot processing to valid hostnames.
+ if validCandidateName && validHostnamePattern(match) {
+ if matchHostnames(match, candidateName) {
+ return nil
+ }
+ } else {
+ if matchExactly(match, candidateName) {
+ return nil
+ }
+ }
+ }
+
+ return HostnameError{c, h}
+}
+
+func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool {
+ usages := make([]ExtKeyUsage, len(keyUsages))
+ copy(usages, keyUsages)
+
+ if len(chain) == 0 {
+ return false
+ }
+
+ usagesRemaining := len(usages)
+
+ // We walk down the list and cross out any usages that aren't supported
+ // by each certificate. If we cross out all the usages, then the chain
+ // is unacceptable.
+
+NextCert:
+ for i := len(chain) - 1; i >= 0; i-- {
+ cert := chain[i]
+ if len(cert.ExtKeyUsage) == 0 && len(cert.UnknownExtKeyUsage) == 0 {
+ // The certificate doesn't have any extended key usage specified.
+ continue
+ }
+
+ for _, usage := range cert.ExtKeyUsage {
+ if usage == ExtKeyUsageAny {
+ // The certificate is explicitly good for any usage.
+ continue NextCert
+ }
+ }
+
+ const invalidUsage ExtKeyUsage = -1
+
+ NextRequestedUsage:
+ for i, requestedUsage := range usages {
+ if requestedUsage == invalidUsage {
+ continue
+ }
+
+ for _, usage := range cert.ExtKeyUsage {
+ if requestedUsage == usage {
+ continue NextRequestedUsage
+ }
+ }
+
+ usages[i] = invalidUsage
+ usagesRemaining--
+ if usagesRemaining == 0 {
+ return false
+ }
+ }
+ }
+
+ return true
+}
diff --git a/contrib/go/_std_1.21/src/crypto/x509/x509.go b/contrib/go/_std_1.21/src/crypto/x509/x509.go
new file mode 100644
index 0000000000..af932b7577
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/x509/x509.go
@@ -0,0 +1,2470 @@
+// Copyright 2009 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 x509 implements a subset of the X.509 standard.
+//
+// It allows parsing and generating certificates, certificate signing
+// requests, certificate revocation lists, and encoded public and private keys.
+// It provides a certificate verifier, complete with a chain builder.
+//
+// The package targets the X.509 technical profile defined by the IETF (RFC
+// 2459/3280/5280), and as further restricted by the CA/Browser Forum Baseline
+// Requirements. There is minimal support for features outside of these
+// profiles, as the primary goal of the package is to provide compatibility
+// with the publicly trusted TLS certificate ecosystem and its policies and
+// constraints.
+//
+// On macOS and Windows, certificate verification is handled by system APIs, but
+// the package aims to apply consistent validation rules across operating
+// systems.
+package x509
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/ecdh"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/elliptic"
+ "crypto/rsa"
+ "crypto/sha1"
+ // Explicitly import these for their crypto.RegisterHash init side-effects.
+ // Keep these as blank imports, even if they're imported above.
+ _ "crypto/sha1"
+ _ "crypto/sha256"
+ _ "crypto/sha512"
+ "crypto/x509/pkix"
+ "encoding/asn1"
+ "encoding/pem"
+ "errors"
+ "fmt"
+ "internal/godebug"
+ "io"
+ "math/big"
+ "net"
+ "net/url"
+ "strconv"
+ "time"
+ "unicode"
+
+ "golang.org/x/crypto/cryptobyte"
+ cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
+)
+
+// pkixPublicKey reflects a PKIX public key structure. See SubjectPublicKeyInfo
+// in RFC 3280.
+type pkixPublicKey struct {
+ Algo pkix.AlgorithmIdentifier
+ BitString asn1.BitString
+}
+
+// ParsePKIXPublicKey parses a public key in PKIX, ASN.1 DER form. The encoded
+// public key is a SubjectPublicKeyInfo structure (see RFC 5280, Section 4.1).
+//
+// It returns a *rsa.PublicKey, *dsa.PublicKey, *ecdsa.PublicKey,
+// ed25519.PublicKey (not a pointer), or *ecdh.PublicKey (for X25519).
+// More types might be supported in the future.
+//
+// This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY".
+func ParsePKIXPublicKey(derBytes []byte) (pub any, err error) {
+ var pki publicKeyInfo
+ if rest, err := asn1.Unmarshal(derBytes, &pki); err != nil {
+ if _, err := asn1.Unmarshal(derBytes, &pkcs1PublicKey{}); err == nil {
+ return nil, errors.New("x509: failed to parse public key (use ParsePKCS1PublicKey instead for this key format)")
+ }
+ return nil, err
+ } else if len(rest) != 0 {
+ return nil, errors.New("x509: trailing data after ASN.1 of public-key")
+ }
+ return parsePublicKey(&pki)
+}
+
+func marshalPublicKey(pub any) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) {
+ switch pub := pub.(type) {
+ case *rsa.PublicKey:
+ publicKeyBytes, err = asn1.Marshal(pkcs1PublicKey{
+ N: pub.N,
+ E: pub.E,
+ })
+ if err != nil {
+ return nil, pkix.AlgorithmIdentifier{}, err
+ }
+ publicKeyAlgorithm.Algorithm = oidPublicKeyRSA
+ // This is a NULL parameters value which is required by
+ // RFC 3279, Section 2.3.1.
+ publicKeyAlgorithm.Parameters = asn1.NullRawValue
+ case *ecdsa.PublicKey:
+ oid, ok := oidFromNamedCurve(pub.Curve)
+ if !ok {
+ return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve")
+ }
+ if !pub.Curve.IsOnCurve(pub.X, pub.Y) {
+ return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: invalid elliptic curve public key")
+ }
+ publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
+ publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA
+ var paramBytes []byte
+ paramBytes, err = asn1.Marshal(oid)
+ if err != nil {
+ return
+ }
+ publicKeyAlgorithm.Parameters.FullBytes = paramBytes
+ case ed25519.PublicKey:
+ publicKeyBytes = pub
+ publicKeyAlgorithm.Algorithm = oidPublicKeyEd25519
+ case *ecdh.PublicKey:
+ publicKeyBytes = pub.Bytes()
+ if pub.Curve() == ecdh.X25519() {
+ publicKeyAlgorithm.Algorithm = oidPublicKeyX25519
+ } else {
+ oid, ok := oidFromECDHCurve(pub.Curve())
+ if !ok {
+ return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve")
+ }
+ publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA
+ var paramBytes []byte
+ paramBytes, err = asn1.Marshal(oid)
+ if err != nil {
+ return
+ }
+ publicKeyAlgorithm.Parameters.FullBytes = paramBytes
+ }
+ default:
+ return nil, pkix.AlgorithmIdentifier{}, fmt.Errorf("x509: unsupported public key type: %T", pub)
+ }
+
+ return publicKeyBytes, publicKeyAlgorithm, nil
+}
+
+// MarshalPKIXPublicKey converts a public key to PKIX, ASN.1 DER form.
+// The encoded public key is a SubjectPublicKeyInfo structure
+// (see RFC 5280, Section 4.1).
+//
+// The following key types are currently supported: *rsa.PublicKey,
+// *ecdsa.PublicKey, ed25519.PublicKey (not a pointer), and *ecdh.PublicKey.
+// Unsupported key types result in an error.
+//
+// This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY".
+func MarshalPKIXPublicKey(pub any) ([]byte, error) {
+ var publicKeyBytes []byte
+ var publicKeyAlgorithm pkix.AlgorithmIdentifier
+ var err error
+
+ if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil {
+ return nil, err
+ }
+
+ pkix := pkixPublicKey{
+ Algo: publicKeyAlgorithm,
+ BitString: asn1.BitString{
+ Bytes: publicKeyBytes,
+ BitLength: 8 * len(publicKeyBytes),
+ },
+ }
+
+ ret, _ := asn1.Marshal(pkix)
+ return ret, nil
+}
+
+// These structures reflect the ASN.1 structure of X.509 certificates.:
+
+type certificate struct {
+ TBSCertificate tbsCertificate
+ SignatureAlgorithm pkix.AlgorithmIdentifier
+ SignatureValue asn1.BitString
+}
+
+type tbsCertificate struct {
+ Raw asn1.RawContent
+ Version int `asn1:"optional,explicit,default:0,tag:0"`
+ SerialNumber *big.Int
+ SignatureAlgorithm pkix.AlgorithmIdentifier
+ Issuer asn1.RawValue
+ Validity validity
+ Subject asn1.RawValue
+ PublicKey publicKeyInfo
+ UniqueId asn1.BitString `asn1:"optional,tag:1"`
+ SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"`
+ Extensions []pkix.Extension `asn1:"omitempty,optional,explicit,tag:3"`
+}
+
+type dsaAlgorithmParameters struct {
+ P, Q, G *big.Int
+}
+
+type validity struct {
+ NotBefore, NotAfter time.Time
+}
+
+type publicKeyInfo struct {
+ Raw asn1.RawContent
+ Algorithm pkix.AlgorithmIdentifier
+ PublicKey asn1.BitString
+}
+
+// RFC 5280, 4.2.1.1
+type authKeyId struct {
+ Id []byte `asn1:"optional,tag:0"`
+}
+
+type SignatureAlgorithm int
+
+const (
+ UnknownSignatureAlgorithm SignatureAlgorithm = iota
+
+ MD2WithRSA // Unsupported.
+ MD5WithRSA // Only supported for signing, not verification.
+ SHA1WithRSA // Only supported for signing, and verification of CRLs, CSRs, and OCSP responses.
+ SHA256WithRSA
+ SHA384WithRSA
+ SHA512WithRSA
+ DSAWithSHA1 // Unsupported.
+ DSAWithSHA256 // Unsupported.
+ ECDSAWithSHA1 // Only supported for signing, and verification of CRLs, CSRs, and OCSP responses.
+ ECDSAWithSHA256
+ ECDSAWithSHA384
+ ECDSAWithSHA512
+ SHA256WithRSAPSS
+ SHA384WithRSAPSS
+ SHA512WithRSAPSS
+ PureEd25519
+)
+
+func (algo SignatureAlgorithm) isRSAPSS() bool {
+ switch algo {
+ case SHA256WithRSAPSS, SHA384WithRSAPSS, SHA512WithRSAPSS:
+ return true
+ default:
+ return false
+ }
+}
+
+func (algo SignatureAlgorithm) String() string {
+ for _, details := range signatureAlgorithmDetails {
+ if details.algo == algo {
+ return details.name
+ }
+ }
+ return strconv.Itoa(int(algo))
+}
+
+type PublicKeyAlgorithm int
+
+const (
+ UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
+ RSA
+ DSA // Only supported for parsing.
+ ECDSA
+ Ed25519
+)
+
+var publicKeyAlgoName = [...]string{
+ RSA: "RSA",
+ DSA: "DSA",
+ ECDSA: "ECDSA",
+ Ed25519: "Ed25519",
+}
+
+func (algo PublicKeyAlgorithm) String() string {
+ if 0 < algo && int(algo) < len(publicKeyAlgoName) {
+ return publicKeyAlgoName[algo]
+ }
+ return strconv.Itoa(int(algo))
+}
+
+// OIDs for signature algorithms
+//
+// pkcs-1 OBJECT IDENTIFIER ::= {
+// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
+//
+// RFC 3279 2.2.1 RSA Signature Algorithms
+//
+// md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
+//
+// md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
+//
+// sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
+//
+// dsaWithSha1 OBJECT IDENTIFIER ::= {
+// iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 }
+//
+// RFC 3279 2.2.3 ECDSA Signature Algorithm
+//
+// ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
+// iso(1) member-body(2) us(840) ansi-x962(10045)
+// signatures(4) ecdsa-with-SHA1(1)}
+//
+// RFC 4055 5 PKCS #1 Version 1.5
+//
+// sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
+//
+// sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
+//
+// sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
+//
+// RFC 5758 3.1 DSA Signature Algorithms
+//
+// dsaWithSha256 OBJECT IDENTIFIER ::= {
+// joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)
+// csor(3) algorithms(4) id-dsa-with-sha2(3) 2}
+//
+// RFC 5758 3.2 ECDSA Signature Algorithm
+//
+// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
+//
+// ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
+//
+// ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
+//
+// RFC 8410 3 Curve25519 and Curve448 Algorithm Identifiers
+//
+// id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
+var (
+ oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
+ oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
+ oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
+ oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
+ oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
+ oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
+ oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
+ oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
+ oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2}
+ oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
+ oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
+ oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
+ oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
+ oidSignatureEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
+
+ oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}
+ oidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2}
+ oidSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3}
+
+ oidMGF1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 8}
+
+ // oidISOSignatureSHA1WithRSA means the same as oidSignatureSHA1WithRSA
+ // but it's specified by ISO. Microsoft's makecert.exe has been known
+ // to produce certificates with this OID.
+ oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29}
+)
+
+var signatureAlgorithmDetails = []struct {
+ algo SignatureAlgorithm
+ name string
+ oid asn1.ObjectIdentifier
+ pubKeyAlgo PublicKeyAlgorithm
+ hash crypto.Hash
+}{
+ {MD2WithRSA, "MD2-RSA", oidSignatureMD2WithRSA, RSA, crypto.Hash(0) /* no value for MD2 */},
+ {MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, RSA, crypto.MD5},
+ {SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, RSA, crypto.SHA1},
+ {SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, RSA, crypto.SHA1},
+ {SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, RSA, crypto.SHA256},
+ {SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, RSA, crypto.SHA384},
+ {SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, RSA, crypto.SHA512},
+ {SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA256},
+ {SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA384},
+ {SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA512},
+ {DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, DSA, crypto.SHA1},
+ {DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, DSA, crypto.SHA256},
+ {ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, ECDSA, crypto.SHA1},
+ {ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, ECDSA, crypto.SHA256},
+ {ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, ECDSA, crypto.SHA384},
+ {ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, ECDSA, crypto.SHA512},
+ {PureEd25519, "Ed25519", oidSignatureEd25519, Ed25519, crypto.Hash(0) /* no pre-hashing */},
+}
+
+// hashToPSSParameters contains the DER encoded RSA PSS parameters for the
+// SHA256, SHA384, and SHA512 hashes as defined in RFC 3447, Appendix A.2.3.
+// The parameters contain the following values:
+// - hashAlgorithm contains the associated hash identifier with NULL parameters
+// - maskGenAlgorithm always contains the default mgf1SHA1 identifier
+// - saltLength contains the length of the associated hash
+// - trailerField always contains the default trailerFieldBC value
+var hashToPSSParameters = map[crypto.Hash]asn1.RawValue{
+ crypto.SHA256: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 162, 3, 2, 1, 32}},
+ crypto.SHA384: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 162, 3, 2, 1, 48}},
+ crypto.SHA512: asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 162, 3, 2, 1, 64}},
+}
+
+// pssParameters reflects the parameters in an AlgorithmIdentifier that
+// specifies RSA PSS. See RFC 3447, Appendix A.2.3.
+type pssParameters struct {
+ // The following three fields are not marked as
+ // optional because the default values specify SHA-1,
+ // which is no longer suitable for use in signatures.
+ Hash pkix.AlgorithmIdentifier `asn1:"explicit,tag:0"`
+ MGF pkix.AlgorithmIdentifier `asn1:"explicit,tag:1"`
+ SaltLength int `asn1:"explicit,tag:2"`
+ TrailerField int `asn1:"optional,explicit,tag:3,default:1"`
+}
+
+func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm {
+ if ai.Algorithm.Equal(oidSignatureEd25519) {
+ // RFC 8410, Section 3
+ // > For all of the OIDs, the parameters MUST be absent.
+ if len(ai.Parameters.FullBytes) != 0 {
+ return UnknownSignatureAlgorithm
+ }
+ }
+
+ if !ai.Algorithm.Equal(oidSignatureRSAPSS) {
+ for _, details := range signatureAlgorithmDetails {
+ if ai.Algorithm.Equal(details.oid) {
+ return details.algo
+ }
+ }
+ return UnknownSignatureAlgorithm
+ }
+
+ // RSA PSS is special because it encodes important parameters
+ // in the Parameters.
+
+ var params pssParameters
+ if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, &params); err != nil {
+ return UnknownSignatureAlgorithm
+ }
+
+ var mgf1HashFunc pkix.AlgorithmIdentifier
+ if _, err := asn1.Unmarshal(params.MGF.Parameters.FullBytes, &mgf1HashFunc); err != nil {
+ return UnknownSignatureAlgorithm
+ }
+
+ // PSS is greatly overburdened with options. This code forces them into
+ // three buckets by requiring that the MGF1 hash function always match the
+ // message hash function (as recommended in RFC 3447, Section 8.1), that the
+ // salt length matches the hash length, and that the trailer field has the
+ // default value.
+ if (len(params.Hash.Parameters.FullBytes) != 0 && !bytes.Equal(params.Hash.Parameters.FullBytes, asn1.NullBytes)) ||
+ !params.MGF.Algorithm.Equal(oidMGF1) ||
+ !mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) ||
+ (len(mgf1HashFunc.Parameters.FullBytes) != 0 && !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, asn1.NullBytes)) ||
+ params.TrailerField != 1 {
+ return UnknownSignatureAlgorithm
+ }
+
+ switch {
+ case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32:
+ return SHA256WithRSAPSS
+ case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48:
+ return SHA384WithRSAPSS
+ case params.Hash.Algorithm.Equal(oidSHA512) && params.SaltLength == 64:
+ return SHA512WithRSAPSS
+ }
+
+ return UnknownSignatureAlgorithm
+}
+
+var (
+ // RFC 3279, 2.3 Public Key Algorithms
+ //
+ // pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
+ // rsadsi(113549) pkcs(1) 1 }
+ //
+ // rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
+ //
+ // id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
+ // x9-57(10040) x9cm(4) 1 }
+ oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
+ oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
+ // RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
+ //
+ // id-ecPublicKey OBJECT IDENTIFIER ::= {
+ // iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
+ oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
+ // RFC 8410, Section 3
+ //
+ // id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 }
+ // id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
+ oidPublicKeyX25519 = asn1.ObjectIdentifier{1, 3, 101, 110}
+ oidPublicKeyEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
+)
+
+// getPublicKeyAlgorithmFromOID returns the exposed PublicKeyAlgorithm
+// identifier for public key types supported in certificates and CSRs. Marshal
+// and Parse functions may support a different set of public key types.
+func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm {
+ switch {
+ case oid.Equal(oidPublicKeyRSA):
+ return RSA
+ case oid.Equal(oidPublicKeyDSA):
+ return DSA
+ case oid.Equal(oidPublicKeyECDSA):
+ return ECDSA
+ case oid.Equal(oidPublicKeyEd25519):
+ return Ed25519
+ }
+ return UnknownPublicKeyAlgorithm
+}
+
+// RFC 5480, 2.1.1.1. Named Curve
+//
+// secp224r1 OBJECT IDENTIFIER ::= {
+// iso(1) identified-organization(3) certicom(132) curve(0) 33 }
+//
+// secp256r1 OBJECT IDENTIFIER ::= {
+// iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
+// prime(1) 7 }
+//
+// secp384r1 OBJECT IDENTIFIER ::= {
+// iso(1) identified-organization(3) certicom(132) curve(0) 34 }
+//
+// secp521r1 OBJECT IDENTIFIER ::= {
+// iso(1) identified-organization(3) certicom(132) curve(0) 35 }
+//
+// NB: secp256r1 is equivalent to prime256v1
+var (
+ oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
+ oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
+ oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
+ oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
+)
+
+func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
+ switch {
+ case oid.Equal(oidNamedCurveP224):
+ return elliptic.P224()
+ case oid.Equal(oidNamedCurveP256):
+ return elliptic.P256()
+ case oid.Equal(oidNamedCurveP384):
+ return elliptic.P384()
+ case oid.Equal(oidNamedCurveP521):
+ return elliptic.P521()
+ }
+ return nil
+}
+
+func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
+ switch curve {
+ case elliptic.P224():
+ return oidNamedCurveP224, true
+ case elliptic.P256():
+ return oidNamedCurveP256, true
+ case elliptic.P384():
+ return oidNamedCurveP384, true
+ case elliptic.P521():
+ return oidNamedCurveP521, true
+ }
+
+ return nil, false
+}
+
+func oidFromECDHCurve(curve ecdh.Curve) (asn1.ObjectIdentifier, bool) {
+ switch curve {
+ case ecdh.X25519():
+ return oidPublicKeyX25519, true
+ case ecdh.P256():
+ return oidNamedCurveP256, true
+ case ecdh.P384():
+ return oidNamedCurveP384, true
+ case ecdh.P521():
+ return oidNamedCurveP521, true
+ }
+
+ return nil, false
+}
+
+// KeyUsage represents the set of actions that are valid for a given key. It's
+// a bitmap of the KeyUsage* constants.
+type KeyUsage int
+
+const (
+ KeyUsageDigitalSignature KeyUsage = 1 << iota
+ KeyUsageContentCommitment
+ KeyUsageKeyEncipherment
+ KeyUsageDataEncipherment
+ KeyUsageKeyAgreement
+ KeyUsageCertSign
+ KeyUsageCRLSign
+ KeyUsageEncipherOnly
+ KeyUsageDecipherOnly
+)
+
+// RFC 5280, 4.2.1.12 Extended Key Usage
+//
+// anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
+//
+// id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
+//
+// id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
+// id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
+// id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
+// id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
+// id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
+// id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 }
+var (
+ oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0}
+ oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1}
+ oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2}
+ oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3}
+ oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4}
+ oidExtKeyUsageIPSECEndSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5}
+ oidExtKeyUsageIPSECTunnel = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6}
+ oidExtKeyUsageIPSECUser = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7}
+ oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}
+ oidExtKeyUsageOCSPSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9}
+ oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3}
+ oidExtKeyUsageNetscapeServerGatedCrypto = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1}
+ oidExtKeyUsageMicrosoftCommercialCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 22}
+ oidExtKeyUsageMicrosoftKernelCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 61, 1, 1}
+)
+
+// ExtKeyUsage represents an extended set of actions that are valid for a given key.
+// Each of the ExtKeyUsage* constants define a unique action.
+type ExtKeyUsage int
+
+const (
+ ExtKeyUsageAny ExtKeyUsage = iota
+ ExtKeyUsageServerAuth
+ ExtKeyUsageClientAuth
+ ExtKeyUsageCodeSigning
+ ExtKeyUsageEmailProtection
+ ExtKeyUsageIPSECEndSystem
+ ExtKeyUsageIPSECTunnel
+ ExtKeyUsageIPSECUser
+ ExtKeyUsageTimeStamping
+ ExtKeyUsageOCSPSigning
+ ExtKeyUsageMicrosoftServerGatedCrypto
+ ExtKeyUsageNetscapeServerGatedCrypto
+ ExtKeyUsageMicrosoftCommercialCodeSigning
+ ExtKeyUsageMicrosoftKernelCodeSigning
+)
+
+// extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID.
+var extKeyUsageOIDs = []struct {
+ extKeyUsage ExtKeyUsage
+ oid asn1.ObjectIdentifier
+}{
+ {ExtKeyUsageAny, oidExtKeyUsageAny},
+ {ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth},
+ {ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth},
+ {ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning},
+ {ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection},
+ {ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem},
+ {ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel},
+ {ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser},
+ {ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping},
+ {ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning},
+ {ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto},
+ {ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto},
+ {ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning},
+ {ExtKeyUsageMicrosoftKernelCodeSigning, oidExtKeyUsageMicrosoftKernelCodeSigning},
+}
+
+func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok bool) {
+ for _, pair := range extKeyUsageOIDs {
+ if oid.Equal(pair.oid) {
+ return pair.extKeyUsage, true
+ }
+ }
+ return
+}
+
+func oidFromExtKeyUsage(eku ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) {
+ for _, pair := range extKeyUsageOIDs {
+ if eku == pair.extKeyUsage {
+ return pair.oid, true
+ }
+ }
+ return
+}
+
+// A Certificate represents an X.509 certificate.
+type Certificate struct {
+ Raw []byte // Complete ASN.1 DER content (certificate, signature algorithm and signature).
+ RawTBSCertificate []byte // Certificate part of raw ASN.1 DER content.
+ RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo.
+ RawSubject []byte // DER encoded Subject
+ RawIssuer []byte // DER encoded Issuer
+
+ Signature []byte
+ SignatureAlgorithm SignatureAlgorithm
+
+ PublicKeyAlgorithm PublicKeyAlgorithm
+ PublicKey any
+
+ Version int
+ SerialNumber *big.Int
+ Issuer pkix.Name
+ Subject pkix.Name
+ NotBefore, NotAfter time.Time // Validity bounds.
+ KeyUsage KeyUsage
+
+ // Extensions contains raw X.509 extensions. When parsing certificates,
+ // this can be used to extract non-critical extensions that are not
+ // parsed by this package. When marshaling certificates, the Extensions
+ // field is ignored, see ExtraExtensions.
+ Extensions []pkix.Extension
+
+ // ExtraExtensions contains extensions to be copied, raw, into any
+ // marshaled certificates. Values override any extensions that would
+ // otherwise be produced based on the other fields. The ExtraExtensions
+ // field is not populated when parsing certificates, see Extensions.
+ ExtraExtensions []pkix.Extension
+
+ // UnhandledCriticalExtensions contains a list of extension IDs that
+ // were not (fully) processed when parsing. Verify will fail if this
+ // slice is non-empty, unless verification is delegated to an OS
+ // library which understands all the critical extensions.
+ //
+ // Users can access these extensions using Extensions and can remove
+ // elements from this slice if they believe that they have been
+ // handled.
+ UnhandledCriticalExtensions []asn1.ObjectIdentifier
+
+ ExtKeyUsage []ExtKeyUsage // Sequence of extended key usages.
+ UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package.
+
+ // BasicConstraintsValid indicates whether IsCA, MaxPathLen,
+ // and MaxPathLenZero are valid.
+ BasicConstraintsValid bool
+ IsCA bool
+
+ // MaxPathLen and MaxPathLenZero indicate the presence and
+ // value of the BasicConstraints' "pathLenConstraint".
+ //
+ // When parsing a certificate, a positive non-zero MaxPathLen
+ // means that the field was specified, -1 means it was unset,
+ // and MaxPathLenZero being true mean that the field was
+ // explicitly set to zero. The case of MaxPathLen==0 with MaxPathLenZero==false
+ // should be treated equivalent to -1 (unset).
+ //
+ // When generating a certificate, an unset pathLenConstraint
+ // can be requested with either MaxPathLen == -1 or using the
+ // zero value for both MaxPathLen and MaxPathLenZero.
+ MaxPathLen int
+ // MaxPathLenZero indicates that BasicConstraintsValid==true
+ // and MaxPathLen==0 should be interpreted as an actual
+ // maximum path length of zero. Otherwise, that combination is
+ // interpreted as MaxPathLen not being set.
+ MaxPathLenZero bool
+
+ SubjectKeyId []byte
+ AuthorityKeyId []byte
+
+ // RFC 5280, 4.2.2.1 (Authority Information Access)
+ OCSPServer []string
+ IssuingCertificateURL []string
+
+ // Subject Alternate Name values. (Note that these values may not be valid
+ // if invalid values were contained within a parsed certificate. For
+ // example, an element of DNSNames may not be a valid DNS domain name.)
+ DNSNames []string
+ EmailAddresses []string
+ IPAddresses []net.IP
+ URIs []*url.URL
+
+ // Name constraints
+ PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical.
+ PermittedDNSDomains []string
+ ExcludedDNSDomains []string
+ PermittedIPRanges []*net.IPNet
+ ExcludedIPRanges []*net.IPNet
+ PermittedEmailAddresses []string
+ ExcludedEmailAddresses []string
+ PermittedURIDomains []string
+ ExcludedURIDomains []string
+
+ // CRL Distribution Points
+ CRLDistributionPoints []string
+
+ PolicyIdentifiers []asn1.ObjectIdentifier
+}
+
+// ErrUnsupportedAlgorithm results from attempting to perform an operation that
+// involves algorithms that are not currently implemented.
+var ErrUnsupportedAlgorithm = errors.New("x509: cannot verify signature: algorithm unimplemented")
+
+// An InsecureAlgorithmError indicates that the SignatureAlgorithm used to
+// generate the signature is not secure, and the signature has been rejected.
+//
+// To temporarily restore support for SHA-1 signatures, include the value
+// "x509sha1=1" in the GODEBUG environment variable. Note that this option will
+// be removed in a future release.
+type InsecureAlgorithmError SignatureAlgorithm
+
+func (e InsecureAlgorithmError) Error() string {
+ var override string
+ if SignatureAlgorithm(e) == SHA1WithRSA || SignatureAlgorithm(e) == ECDSAWithSHA1 {
+ override = " (temporarily override with GODEBUG=x509sha1=1)"
+ }
+ return fmt.Sprintf("x509: cannot verify signature: insecure algorithm %v", SignatureAlgorithm(e)) + override
+}
+
+// ConstraintViolationError results when a requested usage is not permitted by
+// a certificate. For example: checking a signature when the public key isn't a
+// certificate signing key.
+type ConstraintViolationError struct{}
+
+func (ConstraintViolationError) Error() string {
+ return "x509: invalid signature: parent certificate cannot sign this kind of certificate"
+}
+
+func (c *Certificate) Equal(other *Certificate) bool {
+ if c == nil || other == nil {
+ return c == other
+ }
+ return bytes.Equal(c.Raw, other.Raw)
+}
+
+func (c *Certificate) hasSANExtension() bool {
+ return oidInExtensions(oidExtensionSubjectAltName, c.Extensions)
+}
+
+// CheckSignatureFrom verifies that the signature on c is a valid signature from parent.
+//
+// This is a low-level API that performs very limited checks, and not a full
+// path verifier. Most users should use [Certificate.Verify] instead.
+func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
+ // RFC 5280, 4.2.1.9:
+ // "If the basic constraints extension is not present in a version 3
+ // certificate, or the extension is present but the cA boolean is not
+ // asserted, then the certified public key MUST NOT be used to verify
+ // certificate signatures."
+ if parent.Version == 3 && !parent.BasicConstraintsValid ||
+ parent.BasicConstraintsValid && !parent.IsCA {
+ return ConstraintViolationError{}
+ }
+
+ if parent.KeyUsage != 0 && parent.KeyUsage&KeyUsageCertSign == 0 {
+ return ConstraintViolationError{}
+ }
+
+ if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
+ return ErrUnsupportedAlgorithm
+ }
+
+ return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature, parent.PublicKey, false)
+}
+
+// CheckSignature verifies that signature is a valid signature over signed from
+// c's public key.
+//
+// This is a low-level API that performs no validity checks on the certificate.
+//
+// [MD5WithRSA] signatures are rejected, while [SHA1WithRSA] and [ECDSAWithSHA1]
+// signatures are currently accepted.
+func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) error {
+ return checkSignature(algo, signed, signature, c.PublicKey, true)
+}
+
+func (c *Certificate) hasNameConstraints() bool {
+ return oidInExtensions(oidExtensionNameConstraints, c.Extensions)
+}
+
+func (c *Certificate) getSANExtension() []byte {
+ for _, e := range c.Extensions {
+ if e.Id.Equal(oidExtensionSubjectAltName) {
+ return e.Value
+ }
+ }
+ return nil
+}
+
+func signaturePublicKeyAlgoMismatchError(expectedPubKeyAlgo PublicKeyAlgorithm, pubKey any) error {
+ return fmt.Errorf("x509: signature algorithm specifies an %s public key, but have public key of type %T", expectedPubKeyAlgo.String(), pubKey)
+}
+
+var x509sha1 = godebug.New("x509sha1")
+
+// checkSignature verifies that signature is a valid signature over signed from
+// a crypto.PublicKey.
+func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey crypto.PublicKey, allowSHA1 bool) (err error) {
+ var hashType crypto.Hash
+ var pubKeyAlgo PublicKeyAlgorithm
+
+ for _, details := range signatureAlgorithmDetails {
+ if details.algo == algo {
+ hashType = details.hash
+ pubKeyAlgo = details.pubKeyAlgo
+ }
+ }
+
+ switch hashType {
+ case crypto.Hash(0):
+ if pubKeyAlgo != Ed25519 {
+ return ErrUnsupportedAlgorithm
+ }
+ case crypto.MD5:
+ return InsecureAlgorithmError(algo)
+ case crypto.SHA1:
+ // SHA-1 signatures are mostly disabled. See go.dev/issue/41682.
+ if !allowSHA1 {
+ if x509sha1.Value() != "1" {
+ return InsecureAlgorithmError(algo)
+ }
+ x509sha1.IncNonDefault()
+ }
+ fallthrough
+ default:
+ if !hashType.Available() {
+ return ErrUnsupportedAlgorithm
+ }
+ h := hashType.New()
+ h.Write(signed)
+ signed = h.Sum(nil)
+ }
+
+ switch pub := publicKey.(type) {
+ case *rsa.PublicKey:
+ if pubKeyAlgo != RSA {
+ return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)
+ }
+ if algo.isRSAPSS() {
+ return rsa.VerifyPSS(pub, hashType, signed, signature, &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash})
+ } else {
+ return rsa.VerifyPKCS1v15(pub, hashType, signed, signature)
+ }
+ case *ecdsa.PublicKey:
+ if pubKeyAlgo != ECDSA {
+ return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)
+ }
+ if !ecdsa.VerifyASN1(pub, signed, signature) {
+ return errors.New("x509: ECDSA verification failure")
+ }
+ return
+ case ed25519.PublicKey:
+ if pubKeyAlgo != Ed25519 {
+ return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)
+ }
+ if !ed25519.Verify(pub, signed, signature) {
+ return errors.New("x509: Ed25519 verification failure")
+ }
+ return
+ }
+ return ErrUnsupportedAlgorithm
+}
+
+// CheckCRLSignature checks that the signature in crl is from c.
+//
+// Deprecated: Use RevocationList.CheckSignatureFrom instead.
+func (c *Certificate) CheckCRLSignature(crl *pkix.CertificateList) error {
+ algo := getSignatureAlgorithmFromAI(crl.SignatureAlgorithm)
+ return c.CheckSignature(algo, crl.TBSCertList.Raw, crl.SignatureValue.RightAlign())
+}
+
+type UnhandledCriticalExtension struct{}
+
+func (h UnhandledCriticalExtension) Error() string {
+ return "x509: unhandled critical extension"
+}
+
+type basicConstraints struct {
+ IsCA bool `asn1:"optional"`
+ MaxPathLen int `asn1:"optional,default:-1"`
+}
+
+// RFC 5280 4.2.1.4
+type policyInformation struct {
+ Policy asn1.ObjectIdentifier
+ // policyQualifiers omitted
+}
+
+const (
+ nameTypeEmail = 1
+ nameTypeDNS = 2
+ nameTypeURI = 6
+ nameTypeIP = 7
+)
+
+// RFC 5280, 4.2.2.1
+type authorityInfoAccess struct {
+ Method asn1.ObjectIdentifier
+ Location asn1.RawValue
+}
+
+// RFC 5280, 4.2.1.14
+type distributionPoint struct {
+ DistributionPoint distributionPointName `asn1:"optional,tag:0"`
+ Reason asn1.BitString `asn1:"optional,tag:1"`
+ CRLIssuer asn1.RawValue `asn1:"optional,tag:2"`
+}
+
+type distributionPointName struct {
+ FullName []asn1.RawValue `asn1:"optional,tag:0"`
+ RelativeName pkix.RDNSequence `asn1:"optional,tag:1"`
+}
+
+func reverseBitsInAByte(in byte) byte {
+ b1 := in>>4 | in<<4
+ b2 := b1>>2&0x33 | b1<<2&0xcc
+ b3 := b2>>1&0x55 | b2<<1&0xaa
+ return b3
+}
+
+// asn1BitLength returns the bit-length of bitString by considering the
+// most-significant bit in a byte to be the "first" bit. This convention
+// matches ASN.1, but differs from almost everything else.
+func asn1BitLength(bitString []byte) int {
+ bitLen := len(bitString) * 8
+
+ for i := range bitString {
+ b := bitString[len(bitString)-i-1]
+
+ for bit := uint(0); bit < 8; bit++ {
+ if (b>>bit)&1 == 1 {
+ return bitLen
+ }
+ bitLen--
+ }
+ }
+
+ return 0
+}
+
+var (
+ oidExtensionSubjectKeyId = []int{2, 5, 29, 14}
+ oidExtensionKeyUsage = []int{2, 5, 29, 15}
+ oidExtensionExtendedKeyUsage = []int{2, 5, 29, 37}
+ oidExtensionAuthorityKeyId = []int{2, 5, 29, 35}
+ oidExtensionBasicConstraints = []int{2, 5, 29, 19}
+ oidExtensionSubjectAltName = []int{2, 5, 29, 17}
+ oidExtensionCertificatePolicies = []int{2, 5, 29, 32}
+ oidExtensionNameConstraints = []int{2, 5, 29, 30}
+ oidExtensionCRLDistributionPoints = []int{2, 5, 29, 31}
+ oidExtensionAuthorityInfoAccess = []int{1, 3, 6, 1, 5, 5, 7, 1, 1}
+ oidExtensionCRLNumber = []int{2, 5, 29, 20}
+ oidExtensionReasonCode = []int{2, 5, 29, 21}
+)
+
+var (
+ oidAuthorityInfoAccessOcsp = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1}
+ oidAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2}
+)
+
+// oidInExtensions reports whether an extension with the given oid exists in
+// extensions.
+func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) bool {
+ for _, e := range extensions {
+ if e.Id.Equal(oid) {
+ return true
+ }
+ }
+ return false
+}
+
+// marshalSANs marshals a list of addresses into a the contents of an X.509
+// SubjectAlternativeName extension.
+func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL) (derBytes []byte, err error) {
+ var rawValues []asn1.RawValue
+ for _, name := range dnsNames {
+ if err := isIA5String(name); err != nil {
+ return nil, err
+ }
+ rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeDNS, Class: 2, Bytes: []byte(name)})
+ }
+ for _, email := range emailAddresses {
+ if err := isIA5String(email); err != nil {
+ return nil, err
+ }
+ rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeEmail, Class: 2, Bytes: []byte(email)})
+ }
+ for _, rawIP := range ipAddresses {
+ // If possible, we always want to encode IPv4 addresses in 4 bytes.
+ ip := rawIP.To4()
+ if ip == nil {
+ ip = rawIP
+ }
+ rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeIP, Class: 2, Bytes: ip})
+ }
+ for _, uri := range uris {
+ uriStr := uri.String()
+ if err := isIA5String(uriStr); err != nil {
+ return nil, err
+ }
+ rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte(uriStr)})
+ }
+ return asn1.Marshal(rawValues)
+}
+
+func isIA5String(s string) error {
+ for _, r := range s {
+ // Per RFC5280 "IA5String is limited to the set of ASCII characters"
+ if r > unicode.MaxASCII {
+ return fmt.Errorf("x509: %q cannot be encoded as an IA5String", s)
+ }
+ }
+
+ return nil
+}
+
+func buildCertExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId []byte, subjectKeyId []byte) (ret []pkix.Extension, err error) {
+ ret = make([]pkix.Extension, 10 /* maximum number of elements. */)
+ n := 0
+
+ if template.KeyUsage != 0 &&
+ !oidInExtensions(oidExtensionKeyUsage, template.ExtraExtensions) {
+ ret[n], err = marshalKeyUsage(template.KeyUsage)
+ if err != nil {
+ return nil, err
+ }
+ n++
+ }
+
+ if (len(template.ExtKeyUsage) > 0 || len(template.UnknownExtKeyUsage) > 0) &&
+ !oidInExtensions(oidExtensionExtendedKeyUsage, template.ExtraExtensions) {
+ ret[n], err = marshalExtKeyUsage(template.ExtKeyUsage, template.UnknownExtKeyUsage)
+ if err != nil {
+ return nil, err
+ }
+ n++
+ }
+
+ if template.BasicConstraintsValid && !oidInExtensions(oidExtensionBasicConstraints, template.ExtraExtensions) {
+ ret[n], err = marshalBasicConstraints(template.IsCA, template.MaxPathLen, template.MaxPathLenZero)
+ if err != nil {
+ return nil, err
+ }
+ n++
+ }
+
+ if len(subjectKeyId) > 0 && !oidInExtensions(oidExtensionSubjectKeyId, template.ExtraExtensions) {
+ ret[n].Id = oidExtensionSubjectKeyId
+ ret[n].Value, err = asn1.Marshal(subjectKeyId)
+ if err != nil {
+ return
+ }
+ n++
+ }
+
+ if len(authorityKeyId) > 0 && !oidInExtensions(oidExtensionAuthorityKeyId, template.ExtraExtensions) {
+ ret[n].Id = oidExtensionAuthorityKeyId
+ ret[n].Value, err = asn1.Marshal(authKeyId{authorityKeyId})
+ if err != nil {
+ return
+ }
+ n++
+ }
+
+ if (len(template.OCSPServer) > 0 || len(template.IssuingCertificateURL) > 0) &&
+ !oidInExtensions(oidExtensionAuthorityInfoAccess, template.ExtraExtensions) {
+ ret[n].Id = oidExtensionAuthorityInfoAccess
+ var aiaValues []authorityInfoAccess
+ for _, name := range template.OCSPServer {
+ aiaValues = append(aiaValues, authorityInfoAccess{
+ Method: oidAuthorityInfoAccessOcsp,
+ Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},
+ })
+ }
+ for _, name := range template.IssuingCertificateURL {
+ aiaValues = append(aiaValues, authorityInfoAccess{
+ Method: oidAuthorityInfoAccessIssuers,
+ Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},
+ })
+ }
+ ret[n].Value, err = asn1.Marshal(aiaValues)
+ if err != nil {
+ return
+ }
+ n++
+ }
+
+ if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) &&
+ !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {
+ ret[n].Id = oidExtensionSubjectAltName
+ // From RFC 5280, Section 4.2.1.6:
+ // “If the subject field contains an empty sequence ... then
+ // subjectAltName extension ... is marked as critical”
+ ret[n].Critical = subjectIsEmpty
+ ret[n].Value, err = marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses, template.URIs)
+ if err != nil {
+ return
+ }
+ n++
+ }
+
+ if len(template.PolicyIdentifiers) > 0 &&
+ !oidInExtensions(oidExtensionCertificatePolicies, template.ExtraExtensions) {
+ ret[n], err = marshalCertificatePolicies(template.PolicyIdentifiers)
+ if err != nil {
+ return nil, err
+ }
+ n++
+ }
+
+ if (len(template.PermittedDNSDomains) > 0 || len(template.ExcludedDNSDomains) > 0 ||
+ len(template.PermittedIPRanges) > 0 || len(template.ExcludedIPRanges) > 0 ||
+ len(template.PermittedEmailAddresses) > 0 || len(template.ExcludedEmailAddresses) > 0 ||
+ len(template.PermittedURIDomains) > 0 || len(template.ExcludedURIDomains) > 0) &&
+ !oidInExtensions(oidExtensionNameConstraints, template.ExtraExtensions) {
+ ret[n].Id = oidExtensionNameConstraints
+ ret[n].Critical = template.PermittedDNSDomainsCritical
+
+ ipAndMask := func(ipNet *net.IPNet) []byte {
+ maskedIP := ipNet.IP.Mask(ipNet.Mask)
+ ipAndMask := make([]byte, 0, len(maskedIP)+len(ipNet.Mask))
+ ipAndMask = append(ipAndMask, maskedIP...)
+ ipAndMask = append(ipAndMask, ipNet.Mask...)
+ return ipAndMask
+ }
+
+ serialiseConstraints := func(dns []string, ips []*net.IPNet, emails []string, uriDomains []string) (der []byte, err error) {
+ var b cryptobyte.Builder
+
+ for _, name := range dns {
+ if err = isIA5String(name); err != nil {
+ return nil, err
+ }
+
+ b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ b.AddASN1(cryptobyte_asn1.Tag(2).ContextSpecific(), func(b *cryptobyte.Builder) {
+ b.AddBytes([]byte(name))
+ })
+ })
+ }
+
+ for _, ipNet := range ips {
+ b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ b.AddASN1(cryptobyte_asn1.Tag(7).ContextSpecific(), func(b *cryptobyte.Builder) {
+ b.AddBytes(ipAndMask(ipNet))
+ })
+ })
+ }
+
+ for _, email := range emails {
+ if err = isIA5String(email); err != nil {
+ return nil, err
+ }
+
+ b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ b.AddASN1(cryptobyte_asn1.Tag(1).ContextSpecific(), func(b *cryptobyte.Builder) {
+ b.AddBytes([]byte(email))
+ })
+ })
+ }
+
+ for _, uriDomain := range uriDomains {
+ if err = isIA5String(uriDomain); err != nil {
+ return nil, err
+ }
+
+ b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ b.AddASN1(cryptobyte_asn1.Tag(6).ContextSpecific(), func(b *cryptobyte.Builder) {
+ b.AddBytes([]byte(uriDomain))
+ })
+ })
+ }
+
+ return b.Bytes()
+ }
+
+ permitted, err := serialiseConstraints(template.PermittedDNSDomains, template.PermittedIPRanges, template.PermittedEmailAddresses, template.PermittedURIDomains)
+ if err != nil {
+ return nil, err
+ }
+
+ excluded, err := serialiseConstraints(template.ExcludedDNSDomains, template.ExcludedIPRanges, template.ExcludedEmailAddresses, template.ExcludedURIDomains)
+ if err != nil {
+ return nil, err
+ }
+
+ var b cryptobyte.Builder
+ b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {
+ if len(permitted) > 0 {
+ b.AddASN1(cryptobyte_asn1.Tag(0).ContextSpecific().Constructed(), func(b *cryptobyte.Builder) {
+ b.AddBytes(permitted)
+ })
+ }
+
+ if len(excluded) > 0 {
+ b.AddASN1(cryptobyte_asn1.Tag(1).ContextSpecific().Constructed(), func(b *cryptobyte.Builder) {
+ b.AddBytes(excluded)
+ })
+ }
+ })
+
+ ret[n].Value, err = b.Bytes()
+ if err != nil {
+ return nil, err
+ }
+ n++
+ }
+
+ if len(template.CRLDistributionPoints) > 0 &&
+ !oidInExtensions(oidExtensionCRLDistributionPoints, template.ExtraExtensions) {
+ ret[n].Id = oidExtensionCRLDistributionPoints
+
+ var crlDp []distributionPoint
+ for _, name := range template.CRLDistributionPoints {
+ dp := distributionPoint{
+ DistributionPoint: distributionPointName{
+ FullName: []asn1.RawValue{
+ {Tag: 6, Class: 2, Bytes: []byte(name)},
+ },
+ },
+ }
+ crlDp = append(crlDp, dp)
+ }
+
+ ret[n].Value, err = asn1.Marshal(crlDp)
+ if err != nil {
+ return
+ }
+ n++
+ }
+
+ // Adding another extension here? Remember to update the maximum number
+ // of elements in the make() at the top of the function and the list of
+ // template fields used in CreateCertificate documentation.
+
+ return append(ret[:n], template.ExtraExtensions...), nil
+}
+
+func marshalKeyUsage(ku KeyUsage) (pkix.Extension, error) {
+ ext := pkix.Extension{Id: oidExtensionKeyUsage, Critical: true}
+
+ var a [2]byte
+ a[0] = reverseBitsInAByte(byte(ku))
+ a[1] = reverseBitsInAByte(byte(ku >> 8))
+
+ l := 1
+ if a[1] != 0 {
+ l = 2
+ }
+
+ bitString := a[:l]
+ var err error
+ ext.Value, err = asn1.Marshal(asn1.BitString{Bytes: bitString, BitLength: asn1BitLength(bitString)})
+ return ext, err
+}
+
+func marshalExtKeyUsage(extUsages []ExtKeyUsage, unknownUsages []asn1.ObjectIdentifier) (pkix.Extension, error) {
+ ext := pkix.Extension{Id: oidExtensionExtendedKeyUsage}
+
+ oids := make([]asn1.ObjectIdentifier, len(extUsages)+len(unknownUsages))
+ for i, u := range extUsages {
+ if oid, ok := oidFromExtKeyUsage(u); ok {
+ oids[i] = oid
+ } else {
+ return ext, errors.New("x509: unknown extended key usage")
+ }
+ }
+
+ copy(oids[len(extUsages):], unknownUsages)
+
+ var err error
+ ext.Value, err = asn1.Marshal(oids)
+ return ext, err
+}
+
+func marshalBasicConstraints(isCA bool, maxPathLen int, maxPathLenZero bool) (pkix.Extension, error) {
+ ext := pkix.Extension{Id: oidExtensionBasicConstraints, Critical: true}
+ // Leaving MaxPathLen as zero indicates that no maximum path
+ // length is desired, unless MaxPathLenZero is set. A value of
+ // -1 causes encoding/asn1 to omit the value as desired.
+ if maxPathLen == 0 && !maxPathLenZero {
+ maxPathLen = -1
+ }
+ var err error
+ ext.Value, err = asn1.Marshal(basicConstraints{isCA, maxPathLen})
+ return ext, err
+}
+
+func marshalCertificatePolicies(policyIdentifiers []asn1.ObjectIdentifier) (pkix.Extension, error) {
+ ext := pkix.Extension{Id: oidExtensionCertificatePolicies}
+ policies := make([]policyInformation, len(policyIdentifiers))
+ for i, policy := range policyIdentifiers {
+ policies[i].Policy = policy
+ }
+ var err error
+ ext.Value, err = asn1.Marshal(policies)
+ return ext, err
+}
+
+func buildCSRExtensions(template *CertificateRequest) ([]pkix.Extension, error) {
+ var ret []pkix.Extension
+
+ if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) &&
+ !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {
+ sanBytes, err := marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses, template.URIs)
+ if err != nil {
+ return nil, err
+ }
+
+ ret = append(ret, pkix.Extension{
+ Id: oidExtensionSubjectAltName,
+ Value: sanBytes,
+ })
+ }
+
+ return append(ret, template.ExtraExtensions...), nil
+}
+
+func subjectBytes(cert *Certificate) ([]byte, error) {
+ if len(cert.RawSubject) > 0 {
+ return cert.RawSubject, nil
+ }
+
+ return asn1.Marshal(cert.Subject.ToRDNSequence())
+}
+
+// signingParamsForPublicKey returns the parameters to use for signing with
+// priv. If requestedSigAlgo is not zero then it overrides the default
+// signature algorithm.
+func signingParamsForPublicKey(pub any, requestedSigAlgo SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {
+ var pubType PublicKeyAlgorithm
+
+ switch pub := pub.(type) {
+ case *rsa.PublicKey:
+ pubType = RSA
+ hashFunc = crypto.SHA256
+ sigAlgo.Algorithm = oidSignatureSHA256WithRSA
+ sigAlgo.Parameters = asn1.NullRawValue
+
+ case *ecdsa.PublicKey:
+ pubType = ECDSA
+
+ switch pub.Curve {
+ case elliptic.P224(), elliptic.P256():
+ hashFunc = crypto.SHA256
+ sigAlgo.Algorithm = oidSignatureECDSAWithSHA256
+ case elliptic.P384():
+ hashFunc = crypto.SHA384
+ sigAlgo.Algorithm = oidSignatureECDSAWithSHA384
+ case elliptic.P521():
+ hashFunc = crypto.SHA512
+ sigAlgo.Algorithm = oidSignatureECDSAWithSHA512
+ default:
+ err = errors.New("x509: unknown elliptic curve")
+ }
+
+ case ed25519.PublicKey:
+ pubType = Ed25519
+ sigAlgo.Algorithm = oidSignatureEd25519
+
+ default:
+ err = errors.New("x509: only RSA, ECDSA and Ed25519 keys supported")
+ }
+
+ if err != nil {
+ return
+ }
+
+ if requestedSigAlgo == 0 {
+ return
+ }
+
+ found := false
+ for _, details := range signatureAlgorithmDetails {
+ if details.algo == requestedSigAlgo {
+ if details.pubKeyAlgo != pubType {
+ err = errors.New("x509: requested SignatureAlgorithm does not match private key type")
+ return
+ }
+ sigAlgo.Algorithm, hashFunc = details.oid, details.hash
+ if hashFunc == 0 && pubType != Ed25519 {
+ err = errors.New("x509: cannot sign with hash function requested")
+ return
+ }
+ if hashFunc == crypto.MD5 {
+ err = errors.New("x509: signing with MD5 is not supported")
+ return
+ }
+ if requestedSigAlgo.isRSAPSS() {
+ sigAlgo.Parameters = hashToPSSParameters[hashFunc]
+ }
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ err = errors.New("x509: unknown SignatureAlgorithm")
+ }
+
+ return
+}
+
+// emptyASN1Subject is the ASN.1 DER encoding of an empty Subject, which is
+// just an empty SEQUENCE.
+var emptyASN1Subject = []byte{0x30, 0}
+
+// CreateCertificate creates a new X.509 v3 certificate based on a template.
+// The following members of template are currently used:
+//
+// - AuthorityKeyId
+// - BasicConstraintsValid
+// - CRLDistributionPoints
+// - DNSNames
+// - EmailAddresses
+// - ExcludedDNSDomains
+// - ExcludedEmailAddresses
+// - ExcludedIPRanges
+// - ExcludedURIDomains
+// - ExtKeyUsage
+// - ExtraExtensions
+// - IPAddresses
+// - IsCA
+// - IssuingCertificateURL
+// - KeyUsage
+// - MaxPathLen
+// - MaxPathLenZero
+// - NotAfter
+// - NotBefore
+// - OCSPServer
+// - PermittedDNSDomains
+// - PermittedDNSDomainsCritical
+// - PermittedEmailAddresses
+// - PermittedIPRanges
+// - PermittedURIDomains
+// - PolicyIdentifiers
+// - SerialNumber
+// - SignatureAlgorithm
+// - Subject
+// - SubjectKeyId
+// - URIs
+// - UnknownExtKeyUsage
+//
+// The certificate is signed by parent. If parent is equal to template then the
+// certificate is self-signed. The parameter pub is the public key of the
+// certificate to be generated and priv is the private key of the signer.
+//
+// The returned slice is the certificate in DER encoding.
+//
+// The currently supported key types are *rsa.PublicKey, *ecdsa.PublicKey and
+// ed25519.PublicKey. pub must be a supported key type, and priv must be a
+// crypto.Signer with a supported public key.
+//
+// The AuthorityKeyId will be taken from the SubjectKeyId of parent, if any,
+// unless the resulting certificate is self-signed. Otherwise the value from
+// template will be used.
+//
+// If SubjectKeyId from template is empty and the template is a CA, SubjectKeyId
+// will be generated from the hash of the public key.
+func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv any) ([]byte, error) {
+ key, ok := priv.(crypto.Signer)
+ if !ok {
+ return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
+ }
+
+ if template.SerialNumber == nil {
+ return nil, errors.New("x509: no SerialNumber given")
+ }
+
+ // RFC 5280 Section 4.1.2.2: serial number must positive
+ //
+ // We _should_ also restrict serials to <= 20 octets, but it turns out a lot of people
+ // get this wrong, in part because the encoding can itself alter the length of the
+ // serial. For now we accept these non-conformant serials.
+ if template.SerialNumber.Sign() == -1 {
+ return nil, errors.New("x509: serial number must be positive")
+ }
+
+ if template.BasicConstraintsValid && !template.IsCA && template.MaxPathLen != -1 && (template.MaxPathLen != 0 || template.MaxPathLenZero) {
+ return nil, errors.New("x509: only CAs are allowed to specify MaxPathLen")
+ }
+
+ hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(key.Public(), template.SignatureAlgorithm)
+ if err != nil {
+ return nil, err
+ }
+
+ publicKeyBytes, publicKeyAlgorithm, err := marshalPublicKey(pub)
+ if err != nil {
+ return nil, err
+ }
+ if getPublicKeyAlgorithmFromOID(publicKeyAlgorithm.Algorithm) == UnknownPublicKeyAlgorithm {
+ return nil, fmt.Errorf("x509: unsupported public key type: %T", pub)
+ }
+
+ asn1Issuer, err := subjectBytes(parent)
+ if err != nil {
+ return nil, err
+ }
+
+ asn1Subject, err := subjectBytes(template)
+ if err != nil {
+ return nil, err
+ }
+
+ authorityKeyId := template.AuthorityKeyId
+ if !bytes.Equal(asn1Issuer, asn1Subject) && len(parent.SubjectKeyId) > 0 {
+ authorityKeyId = parent.SubjectKeyId
+ }
+
+ subjectKeyId := template.SubjectKeyId
+ if len(subjectKeyId) == 0 && template.IsCA {
+ // SubjectKeyId generated using method 1 in RFC 5280, Section 4.2.1.2:
+ // (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
+ // value of the BIT STRING subjectPublicKey (excluding the tag,
+ // length, and number of unused bits).
+ h := sha1.Sum(publicKeyBytes)
+ subjectKeyId = h[:]
+ }
+
+ // Check that the signer's public key matches the private key, if available.
+ type privateKey interface {
+ Equal(crypto.PublicKey) bool
+ }
+ if privPub, ok := key.Public().(privateKey); !ok {
+ return nil, errors.New("x509: internal error: supported public key does not implement Equal")
+ } else if parent.PublicKey != nil && !privPub.Equal(parent.PublicKey) {
+ return nil, errors.New("x509: provided PrivateKey doesn't match parent's PublicKey")
+ }
+
+ extensions, err := buildCertExtensions(template, bytes.Equal(asn1Subject, emptyASN1Subject), authorityKeyId, subjectKeyId)
+ if err != nil {
+ return nil, err
+ }
+
+ encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}
+ c := tbsCertificate{
+ Version: 2,
+ SerialNumber: template.SerialNumber,
+ SignatureAlgorithm: signatureAlgorithm,
+ Issuer: asn1.RawValue{FullBytes: asn1Issuer},
+ Validity: validity{template.NotBefore.UTC(), template.NotAfter.UTC()},
+ Subject: asn1.RawValue{FullBytes: asn1Subject},
+ PublicKey: publicKeyInfo{nil, publicKeyAlgorithm, encodedPublicKey},
+ Extensions: extensions,
+ }
+
+ tbsCertContents, err := asn1.Marshal(c)
+ if err != nil {
+ return nil, err
+ }
+ c.Raw = tbsCertContents
+
+ signed := tbsCertContents
+ if hashFunc != 0 {
+ h := hashFunc.New()
+ h.Write(signed)
+ signed = h.Sum(nil)
+ }
+
+ var signerOpts crypto.SignerOpts = hashFunc
+ if template.SignatureAlgorithm != 0 && template.SignatureAlgorithm.isRSAPSS() {
+ signerOpts = &rsa.PSSOptions{
+ SaltLength: rsa.PSSSaltLengthEqualsHash,
+ Hash: hashFunc,
+ }
+ }
+
+ var signature []byte
+ signature, err = key.Sign(rand, signed, signerOpts)
+ if err != nil {
+ return nil, err
+ }
+
+ signedCert, err := asn1.Marshal(certificate{
+ c,
+ signatureAlgorithm,
+ asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ // Check the signature to ensure the crypto.Signer behaved correctly.
+ if err := checkSignature(getSignatureAlgorithmFromAI(signatureAlgorithm), c.Raw, signature, key.Public(), true); err != nil {
+ return nil, fmt.Errorf("x509: signature over certificate returned by signer is invalid: %w", err)
+ }
+
+ return signedCert, nil
+}
+
+// pemCRLPrefix is the magic string that indicates that we have a PEM encoded
+// CRL.
+var pemCRLPrefix = []byte("-----BEGIN X509 CRL")
+
+// pemType is the type of a PEM encoded CRL.
+var pemType = "X509 CRL"
+
+// ParseCRL parses a CRL from the given bytes. It's often the case that PEM
+// encoded CRLs will appear where they should be DER encoded, so this function
+// will transparently handle PEM encoding as long as there isn't any leading
+// garbage.
+//
+// Deprecated: Use ParseRevocationList instead.
+func ParseCRL(crlBytes []byte) (*pkix.CertificateList, error) {
+ if bytes.HasPrefix(crlBytes, pemCRLPrefix) {
+ block, _ := pem.Decode(crlBytes)
+ if block != nil && block.Type == pemType {
+ crlBytes = block.Bytes
+ }
+ }
+ return ParseDERCRL(crlBytes)
+}
+
+// ParseDERCRL parses a DER encoded CRL from the given bytes.
+//
+// Deprecated: Use ParseRevocationList instead.
+func ParseDERCRL(derBytes []byte) (*pkix.CertificateList, error) {
+ certList := new(pkix.CertificateList)
+ if rest, err := asn1.Unmarshal(derBytes, certList); err != nil {
+ return nil, err
+ } else if len(rest) != 0 {
+ return nil, errors.New("x509: trailing data after CRL")
+ }
+ return certList, nil
+}
+
+// CreateCRL returns a DER encoded CRL, signed by this Certificate, that
+// contains the given list of revoked certificates.
+//
+// Deprecated: this method does not generate an RFC 5280 conformant X.509 v2 CRL.
+// To generate a standards compliant CRL, use CreateRevocationList instead.
+func (c *Certificate) CreateCRL(rand io.Reader, priv any, revokedCerts []pkix.RevokedCertificate, now, expiry time.Time) (crlBytes []byte, err error) {
+ key, ok := priv.(crypto.Signer)
+ if !ok {
+ return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
+ }
+
+ hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(key.Public(), 0)
+ if err != nil {
+ return nil, err
+ }
+
+ // Force revocation times to UTC per RFC 5280.
+ revokedCertsUTC := make([]pkix.RevokedCertificate, len(revokedCerts))
+ for i, rc := range revokedCerts {
+ rc.RevocationTime = rc.RevocationTime.UTC()
+ revokedCertsUTC[i] = rc
+ }
+
+ tbsCertList := pkix.TBSCertificateList{
+ Version: 1,
+ Signature: signatureAlgorithm,
+ Issuer: c.Subject.ToRDNSequence(),
+ ThisUpdate: now.UTC(),
+ NextUpdate: expiry.UTC(),
+ RevokedCertificates: revokedCertsUTC,
+ }
+
+ // Authority Key Id
+ if len(c.SubjectKeyId) > 0 {
+ var aki pkix.Extension
+ aki.Id = oidExtensionAuthorityKeyId
+ aki.Value, err = asn1.Marshal(authKeyId{Id: c.SubjectKeyId})
+ if err != nil {
+ return
+ }
+ tbsCertList.Extensions = append(tbsCertList.Extensions, aki)
+ }
+
+ tbsCertListContents, err := asn1.Marshal(tbsCertList)
+ if err != nil {
+ return
+ }
+
+ signed := tbsCertListContents
+ if hashFunc != 0 {
+ h := hashFunc.New()
+ h.Write(signed)
+ signed = h.Sum(nil)
+ }
+
+ var signature []byte
+ signature, err = key.Sign(rand, signed, hashFunc)
+ if err != nil {
+ return
+ }
+
+ return asn1.Marshal(pkix.CertificateList{
+ TBSCertList: tbsCertList,
+ SignatureAlgorithm: signatureAlgorithm,
+ SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
+ })
+}
+
+// CertificateRequest represents a PKCS #10, certificate signature request.
+type CertificateRequest struct {
+ Raw []byte // Complete ASN.1 DER content (CSR, signature algorithm and signature).
+ RawTBSCertificateRequest []byte // Certificate request info part of raw ASN.1 DER content.
+ RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo.
+ RawSubject []byte // DER encoded Subject.
+
+ Version int
+ Signature []byte
+ SignatureAlgorithm SignatureAlgorithm
+
+ PublicKeyAlgorithm PublicKeyAlgorithm
+ PublicKey any
+
+ Subject pkix.Name
+
+ // Attributes contains the CSR attributes that can parse as
+ // pkix.AttributeTypeAndValueSET.
+ //
+ // Deprecated: Use Extensions and ExtraExtensions instead for parsing and
+ // generating the requestedExtensions attribute.
+ Attributes []pkix.AttributeTypeAndValueSET
+
+ // Extensions contains all requested extensions, in raw form. When parsing
+ // CSRs, this can be used to extract extensions that are not parsed by this
+ // package.
+ Extensions []pkix.Extension
+
+ // ExtraExtensions contains extensions to be copied, raw, into any CSR
+ // marshaled by CreateCertificateRequest. Values override any extensions
+ // that would otherwise be produced based on the other fields but are
+ // overridden by any extensions specified in Attributes.
+ //
+ // The ExtraExtensions field is not populated by ParseCertificateRequest,
+ // see Extensions instead.
+ ExtraExtensions []pkix.Extension
+
+ // Subject Alternate Name values.
+ DNSNames []string
+ EmailAddresses []string
+ IPAddresses []net.IP
+ URIs []*url.URL
+}
+
+// These structures reflect the ASN.1 structure of X.509 certificate
+// signature requests (see RFC 2986):
+
+type tbsCertificateRequest struct {
+ Raw asn1.RawContent
+ Version int
+ Subject asn1.RawValue
+ PublicKey publicKeyInfo
+ RawAttributes []asn1.RawValue `asn1:"tag:0"`
+}
+
+type certificateRequest struct {
+ Raw asn1.RawContent
+ TBSCSR tbsCertificateRequest
+ SignatureAlgorithm pkix.AlgorithmIdentifier
+ SignatureValue asn1.BitString
+}
+
+// oidExtensionRequest is a PKCS #9 OBJECT IDENTIFIER that indicates requested
+// extensions in a CSR.
+var oidExtensionRequest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 14}
+
+// newRawAttributes converts AttributeTypeAndValueSETs from a template
+// CertificateRequest's Attributes into tbsCertificateRequest RawAttributes.
+func newRawAttributes(attributes []pkix.AttributeTypeAndValueSET) ([]asn1.RawValue, error) {
+ var rawAttributes []asn1.RawValue
+ b, err := asn1.Marshal(attributes)
+ if err != nil {
+ return nil, err
+ }
+ rest, err := asn1.Unmarshal(b, &rawAttributes)
+ if err != nil {
+ return nil, err
+ }
+ if len(rest) != 0 {
+ return nil, errors.New("x509: failed to unmarshal raw CSR Attributes")
+ }
+ return rawAttributes, nil
+}
+
+// parseRawAttributes Unmarshals RawAttributes into AttributeTypeAndValueSETs.
+func parseRawAttributes(rawAttributes []asn1.RawValue) []pkix.AttributeTypeAndValueSET {
+ var attributes []pkix.AttributeTypeAndValueSET
+ for _, rawAttr := range rawAttributes {
+ var attr pkix.AttributeTypeAndValueSET
+ rest, err := asn1.Unmarshal(rawAttr.FullBytes, &attr)
+ // Ignore attributes that don't parse into pkix.AttributeTypeAndValueSET
+ // (i.e.: challengePassword or unstructuredName).
+ if err == nil && len(rest) == 0 {
+ attributes = append(attributes, attr)
+ }
+ }
+ return attributes
+}
+
+// parseCSRExtensions parses the attributes from a CSR and extracts any
+// requested extensions.
+func parseCSRExtensions(rawAttributes []asn1.RawValue) ([]pkix.Extension, error) {
+ // pkcs10Attribute reflects the Attribute structure from RFC 2986, Section 4.1.
+ type pkcs10Attribute struct {
+ Id asn1.ObjectIdentifier
+ Values []asn1.RawValue `asn1:"set"`
+ }
+
+ var ret []pkix.Extension
+ requestedExts := make(map[string]bool)
+ for _, rawAttr := range rawAttributes {
+ var attr pkcs10Attribute
+ if rest, err := asn1.Unmarshal(rawAttr.FullBytes, &attr); err != nil || len(rest) != 0 || len(attr.Values) == 0 {
+ // Ignore attributes that don't parse.
+ continue
+ }
+
+ if !attr.Id.Equal(oidExtensionRequest) {
+ continue
+ }
+
+ var extensions []pkix.Extension
+ if _, err := asn1.Unmarshal(attr.Values[0].FullBytes, &extensions); err != nil {
+ return nil, err
+ }
+ for _, ext := range extensions {
+ oidStr := ext.Id.String()
+ if requestedExts[oidStr] {
+ return nil, errors.New("x509: certificate request contains duplicate requested extensions")
+ }
+ requestedExts[oidStr] = true
+ }
+ ret = append(ret, extensions...)
+ }
+
+ return ret, nil
+}
+
+// CreateCertificateRequest creates a new certificate request based on a
+// template. The following members of template are used:
+//
+// - SignatureAlgorithm
+// - Subject
+// - DNSNames
+// - EmailAddresses
+// - IPAddresses
+// - URIs
+// - ExtraExtensions
+// - Attributes (deprecated)
+//
+// priv is the private key to sign the CSR with, and the corresponding public
+// key will be included in the CSR. It must implement crypto.Signer and its
+// Public() method must return a *rsa.PublicKey or a *ecdsa.PublicKey or a
+// ed25519.PublicKey. (A *rsa.PrivateKey, *ecdsa.PrivateKey or
+// ed25519.PrivateKey satisfies this.)
+//
+// The returned slice is the certificate request in DER encoding.
+func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv any) (csr []byte, err error) {
+ key, ok := priv.(crypto.Signer)
+ if !ok {
+ return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
+ }
+
+ var hashFunc crypto.Hash
+ var sigAlgo pkix.AlgorithmIdentifier
+ hashFunc, sigAlgo, err = signingParamsForPublicKey(key.Public(), template.SignatureAlgorithm)
+ if err != nil {
+ return nil, err
+ }
+
+ var publicKeyBytes []byte
+ var publicKeyAlgorithm pkix.AlgorithmIdentifier
+ publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(key.Public())
+ if err != nil {
+ return nil, err
+ }
+
+ extensions, err := buildCSRExtensions(template)
+ if err != nil {
+ return nil, err
+ }
+
+ // Make a copy of template.Attributes because we may alter it below.
+ attributes := make([]pkix.AttributeTypeAndValueSET, 0, len(template.Attributes))
+ for _, attr := range template.Attributes {
+ values := make([][]pkix.AttributeTypeAndValue, len(attr.Value))
+ copy(values, attr.Value)
+ attributes = append(attributes, pkix.AttributeTypeAndValueSET{
+ Type: attr.Type,
+ Value: values,
+ })
+ }
+
+ extensionsAppended := false
+ if len(extensions) > 0 {
+ // Append the extensions to an existing attribute if possible.
+ for _, atvSet := range attributes {
+ if !atvSet.Type.Equal(oidExtensionRequest) || len(atvSet.Value) == 0 {
+ continue
+ }
+
+ // specifiedExtensions contains all the extensions that we
+ // found specified via template.Attributes.
+ specifiedExtensions := make(map[string]bool)
+
+ for _, atvs := range atvSet.Value {
+ for _, atv := range atvs {
+ specifiedExtensions[atv.Type.String()] = true
+ }
+ }
+
+ newValue := make([]pkix.AttributeTypeAndValue, 0, len(atvSet.Value[0])+len(extensions))
+ newValue = append(newValue, atvSet.Value[0]...)
+
+ for _, e := range extensions {
+ if specifiedExtensions[e.Id.String()] {
+ // Attributes already contained a value for
+ // this extension and it takes priority.
+ continue
+ }
+
+ newValue = append(newValue, pkix.AttributeTypeAndValue{
+ // There is no place for the critical
+ // flag in an AttributeTypeAndValue.
+ Type: e.Id,
+ Value: e.Value,
+ })
+ }
+
+ atvSet.Value[0] = newValue
+ extensionsAppended = true
+ break
+ }
+ }
+
+ rawAttributes, err := newRawAttributes(attributes)
+ if err != nil {
+ return
+ }
+
+ // If not included in attributes, add a new attribute for the
+ // extensions.
+ if len(extensions) > 0 && !extensionsAppended {
+ attr := struct {
+ Type asn1.ObjectIdentifier
+ Value [][]pkix.Extension `asn1:"set"`
+ }{
+ Type: oidExtensionRequest,
+ Value: [][]pkix.Extension{extensions},
+ }
+
+ b, err := asn1.Marshal(attr)
+ if err != nil {
+ return nil, errors.New("x509: failed to serialise extensions attribute: " + err.Error())
+ }
+
+ var rawValue asn1.RawValue
+ if _, err := asn1.Unmarshal(b, &rawValue); err != nil {
+ return nil, err
+ }
+
+ rawAttributes = append(rawAttributes, rawValue)
+ }
+
+ asn1Subject := template.RawSubject
+ if len(asn1Subject) == 0 {
+ asn1Subject, err = asn1.Marshal(template.Subject.ToRDNSequence())
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ tbsCSR := tbsCertificateRequest{
+ Version: 0, // PKCS #10, RFC 2986
+ Subject: asn1.RawValue{FullBytes: asn1Subject},
+ PublicKey: publicKeyInfo{
+ Algorithm: publicKeyAlgorithm,
+ PublicKey: asn1.BitString{
+ Bytes: publicKeyBytes,
+ BitLength: len(publicKeyBytes) * 8,
+ },
+ },
+ RawAttributes: rawAttributes,
+ }
+
+ tbsCSRContents, err := asn1.Marshal(tbsCSR)
+ if err != nil {
+ return
+ }
+ tbsCSR.Raw = tbsCSRContents
+
+ signed := tbsCSRContents
+ if hashFunc != 0 {
+ h := hashFunc.New()
+ h.Write(signed)
+ signed = h.Sum(nil)
+ }
+
+ var signature []byte
+ signature, err = key.Sign(rand, signed, hashFunc)
+ if err != nil {
+ return
+ }
+
+ return asn1.Marshal(certificateRequest{
+ TBSCSR: tbsCSR,
+ SignatureAlgorithm: sigAlgo,
+ SignatureValue: asn1.BitString{
+ Bytes: signature,
+ BitLength: len(signature) * 8,
+ },
+ })
+}
+
+// ParseCertificateRequest parses a single certificate request from the
+// given ASN.1 DER data.
+func ParseCertificateRequest(asn1Data []byte) (*CertificateRequest, error) {
+ var csr certificateRequest
+
+ rest, err := asn1.Unmarshal(asn1Data, &csr)
+ if err != nil {
+ return nil, err
+ } else if len(rest) != 0 {
+ return nil, asn1.SyntaxError{Msg: "trailing data"}
+ }
+
+ return parseCertificateRequest(&csr)
+}
+
+func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error) {
+ out := &CertificateRequest{
+ Raw: in.Raw,
+ RawTBSCertificateRequest: in.TBSCSR.Raw,
+ RawSubjectPublicKeyInfo: in.TBSCSR.PublicKey.Raw,
+ RawSubject: in.TBSCSR.Subject.FullBytes,
+
+ Signature: in.SignatureValue.RightAlign(),
+ SignatureAlgorithm: getSignatureAlgorithmFromAI(in.SignatureAlgorithm),
+
+ PublicKeyAlgorithm: getPublicKeyAlgorithmFromOID(in.TBSCSR.PublicKey.Algorithm.Algorithm),
+
+ Version: in.TBSCSR.Version,
+ Attributes: parseRawAttributes(in.TBSCSR.RawAttributes),
+ }
+
+ var err error
+ if out.PublicKeyAlgorithm != UnknownPublicKeyAlgorithm {
+ out.PublicKey, err = parsePublicKey(&in.TBSCSR.PublicKey)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ var subject pkix.RDNSequence
+ if rest, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil {
+ return nil, err
+ } else if len(rest) != 0 {
+ return nil, errors.New("x509: trailing data after X.509 Subject")
+ }
+
+ out.Subject.FillFromRDNSequence(&subject)
+
+ if out.Extensions, err = parseCSRExtensions(in.TBSCSR.RawAttributes); err != nil {
+ return nil, err
+ }
+
+ for _, extension := range out.Extensions {
+ switch {
+ case extension.Id.Equal(oidExtensionSubjectAltName):
+ out.DNSNames, out.EmailAddresses, out.IPAddresses, out.URIs, err = parseSANExtension(extension.Value)
+ if err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ return out, nil
+}
+
+// CheckSignature reports whether the signature on c is valid.
+func (c *CertificateRequest) CheckSignature() error {
+ return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificateRequest, c.Signature, c.PublicKey, true)
+}
+
+// RevocationListEntry represents an entry in the revokedCertificates
+// sequence of a CRL.
+type RevocationListEntry struct {
+ // Raw contains the raw bytes of the revokedCertificates entry. It is set when
+ // parsing a CRL; it is ignored when generating a CRL.
+ Raw []byte
+
+ // SerialNumber represents the serial number of a revoked certificate. It is
+ // both used when creating a CRL and populated when parsing a CRL. It must not
+ // be nil.
+ SerialNumber *big.Int
+ // RevocationTime represents the time at which the certificate was revoked. It
+ // is both used when creating a CRL and populated when parsing a CRL. It must
+ // not be the zero time.
+ RevocationTime time.Time
+ // ReasonCode represents the reason for revocation, using the integer enum
+ // values specified in RFC 5280 Section 5.3.1. When creating a CRL, the zero
+ // value will result in the reasonCode extension being omitted. When parsing a
+ // CRL, the zero value may represent either the reasonCode extension being
+ // absent (which implies the default revocation reason of 0/Unspecified), or
+ // it may represent the reasonCode extension being present and explicitly
+ // containing a value of 0/Unspecified (which should not happen according to
+ // the DER encoding rules, but can and does happen anyway).
+ ReasonCode int
+
+ // Extensions contains raw X.509 extensions. When parsing CRL entries,
+ // this can be used to extract non-critical extensions that are not
+ // parsed by this package. When marshaling CRL entries, the Extensions
+ // field is ignored, see ExtraExtensions.
+ Extensions []pkix.Extension
+ // ExtraExtensions contains extensions to be copied, raw, into any
+ // marshaled CRL entries. Values override any extensions that would
+ // otherwise be produced based on the other fields. The ExtraExtensions
+ // field is not populated when parsing CRL entries, see Extensions.
+ ExtraExtensions []pkix.Extension
+}
+
+// RevocationList represents a Certificate Revocation List (CRL) as specified
+// by RFC 5280.
+type RevocationList struct {
+ // Raw contains the complete ASN.1 DER content of the CRL (tbsCertList,
+ // signatureAlgorithm, and signatureValue.)
+ Raw []byte
+ // RawTBSRevocationList contains just the tbsCertList portion of the ASN.1
+ // DER.
+ RawTBSRevocationList []byte
+ // RawIssuer contains the DER encoded Issuer.
+ RawIssuer []byte
+
+ // Issuer contains the DN of the issuing certificate.
+ Issuer pkix.Name
+ // AuthorityKeyId is used to identify the public key associated with the
+ // issuing certificate. It is populated from the authorityKeyIdentifier
+ // extension when parsing a CRL. It is ignored when creating a CRL; the
+ // extension is populated from the issuing certificate itself.
+ AuthorityKeyId []byte
+
+ Signature []byte
+ // SignatureAlgorithm is used to determine the signature algorithm to be
+ // used when signing the CRL. If 0 the default algorithm for the signing
+ // key will be used.
+ SignatureAlgorithm SignatureAlgorithm
+
+ // RevokedCertificateEntries represents the revokedCertificates sequence in
+ // the CRL. It is used when creating a CRL and also populated when parsing a
+ // CRL. When creating a CRL, it may be empty or nil, in which case the
+ // revokedCertificates ASN.1 sequence will be omitted from the CRL entirely.
+ RevokedCertificateEntries []RevocationListEntry
+
+ // RevokedCertificates is used to populate the revokedCertificates
+ // sequence in the CRL if RevokedCertificateEntries is empty. It may be empty
+ // or nil, in which case an empty CRL will be created.
+ //
+ // Deprecated: Use RevokedCertificateEntries instead.
+ RevokedCertificates []pkix.RevokedCertificate
+
+ // Number is used to populate the X.509 v2 cRLNumber extension in the CRL,
+ // which should be a monotonically increasing sequence number for a given
+ // CRL scope and CRL issuer. It is also populated from the cRLNumber
+ // extension when parsing a CRL.
+ Number *big.Int
+
+ // ThisUpdate is used to populate the thisUpdate field in the CRL, which
+ // indicates the issuance date of the CRL.
+ ThisUpdate time.Time
+ // NextUpdate is used to populate the nextUpdate field in the CRL, which
+ // indicates the date by which the next CRL will be issued. NextUpdate
+ // must be greater than ThisUpdate.
+ NextUpdate time.Time
+
+ // Extensions contains raw X.509 extensions. When creating a CRL,
+ // the Extensions field is ignored, see ExtraExtensions.
+ Extensions []pkix.Extension
+
+ // ExtraExtensions contains any additional extensions to add directly to
+ // the CRL.
+ ExtraExtensions []pkix.Extension
+}
+
+// These structures reflect the ASN.1 structure of X.509 CRLs better than
+// the existing crypto/x509/pkix variants do. These mirror the existing
+// certificate structs in this file.
+//
+// Notably, we include issuer as an asn1.RawValue, mirroring the behavior of
+// tbsCertificate and allowing raw (unparsed) subjects to be passed cleanly.
+type certificateList struct {
+ TBSCertList tbsCertificateList
+ SignatureAlgorithm pkix.AlgorithmIdentifier
+ SignatureValue asn1.BitString
+}
+
+type tbsCertificateList struct {
+ Raw asn1.RawContent
+ Version int `asn1:"optional,default:0"`
+ Signature pkix.AlgorithmIdentifier
+ Issuer asn1.RawValue
+ ThisUpdate time.Time
+ NextUpdate time.Time `asn1:"optional"`
+ RevokedCertificates []pkix.RevokedCertificate `asn1:"optional"`
+ Extensions []pkix.Extension `asn1:"tag:0,optional,explicit"`
+}
+
+// CreateRevocationList creates a new X.509 v2 Certificate Revocation List,
+// according to RFC 5280, based on template.
+//
+// The CRL is signed by priv which should be the private key associated with
+// the public key in the issuer certificate.
+//
+// The issuer may not be nil, and the crlSign bit must be set in KeyUsage in
+// order to use it as a CRL issuer.
+//
+// The issuer distinguished name CRL field and authority key identifier
+// extension are populated using the issuer certificate. issuer must have
+// SubjectKeyId set.
+func CreateRevocationList(rand io.Reader, template *RevocationList, issuer *Certificate, priv crypto.Signer) ([]byte, error) {
+ if template == nil {
+ return nil, errors.New("x509: template can not be nil")
+ }
+ if issuer == nil {
+ return nil, errors.New("x509: issuer can not be nil")
+ }
+ if (issuer.KeyUsage & KeyUsageCRLSign) == 0 {
+ return nil, errors.New("x509: issuer must have the crlSign key usage bit set")
+ }
+ if len(issuer.SubjectKeyId) == 0 {
+ return nil, errors.New("x509: issuer certificate doesn't contain a subject key identifier")
+ }
+ if template.NextUpdate.Before(template.ThisUpdate) {
+ return nil, errors.New("x509: template.ThisUpdate is after template.NextUpdate")
+ }
+ if template.Number == nil {
+ return nil, errors.New("x509: template contains nil Number field")
+ }
+
+ hashFunc, signatureAlgorithm, err := signingParamsForPublicKey(priv.Public(), template.SignatureAlgorithm)
+ if err != nil {
+ return nil, err
+ }
+
+ var revokedCerts []pkix.RevokedCertificate
+ // Only process the deprecated RevokedCertificates field if it is populated
+ // and the new RevokedCertificateEntries field is not populated.
+ if len(template.RevokedCertificates) > 0 && len(template.RevokedCertificateEntries) == 0 {
+ // Force revocation times to UTC per RFC 5280.
+ revokedCerts = make([]pkix.RevokedCertificate, len(template.RevokedCertificates))
+ for i, rc := range template.RevokedCertificates {
+ rc.RevocationTime = rc.RevocationTime.UTC()
+ revokedCerts[i] = rc
+ }
+ } else {
+ // Convert the ReasonCode field to a proper extension, and force revocation
+ // times to UTC per RFC 5280.
+ revokedCerts = make([]pkix.RevokedCertificate, len(template.RevokedCertificateEntries))
+ for i, rce := range template.RevokedCertificateEntries {
+ if rce.SerialNumber == nil {
+ return nil, errors.New("x509: template contains entry with nil SerialNumber field")
+ }
+ if rce.RevocationTime.IsZero() {
+ return nil, errors.New("x509: template contains entry with zero RevocationTime field")
+ }
+
+ rc := pkix.RevokedCertificate{
+ SerialNumber: rce.SerialNumber,
+ RevocationTime: rce.RevocationTime.UTC(),
+ }
+
+ // Copy over any extra extensions, except for a Reason Code extension,
+ // because we'll synthesize that ourselves to ensure it is correct.
+ exts := make([]pkix.Extension, 0, len(rce.ExtraExtensions))
+ for _, ext := range rce.ExtraExtensions {
+ if ext.Id.Equal(oidExtensionReasonCode) {
+ return nil, errors.New("x509: template contains entry with ReasonCode ExtraExtension; use ReasonCode field instead")
+ }
+ exts = append(exts, ext)
+ }
+
+ // Only add a reasonCode extension if the reason is non-zero, as per
+ // RFC 5280 Section 5.3.1.
+ if rce.ReasonCode != 0 {
+ reasonBytes, err := asn1.Marshal(asn1.Enumerated(rce.ReasonCode))
+ if err != nil {
+ return nil, err
+ }
+
+ exts = append(exts, pkix.Extension{
+ Id: oidExtensionReasonCode,
+ Value: reasonBytes,
+ })
+ }
+
+ if len(exts) > 0 {
+ rc.Extensions = exts
+ }
+ revokedCerts[i] = rc
+ }
+ }
+
+ aki, err := asn1.Marshal(authKeyId{Id: issuer.SubjectKeyId})
+ if err != nil {
+ return nil, err
+ }
+
+ if numBytes := template.Number.Bytes(); len(numBytes) > 20 || (len(numBytes) == 20 && numBytes[0]&0x80 != 0) {
+ return nil, errors.New("x509: CRL number exceeds 20 octets")
+ }
+ crlNum, err := asn1.Marshal(template.Number)
+ if err != nil {
+ return nil, err
+ }
+
+ // Correctly use the issuer's subject sequence if one is specified.
+ issuerSubject, err := subjectBytes(issuer)
+ if err != nil {
+ return nil, err
+ }
+
+ tbsCertList := tbsCertificateList{
+ Version: 1, // v2
+ Signature: signatureAlgorithm,
+ Issuer: asn1.RawValue{FullBytes: issuerSubject},
+ ThisUpdate: template.ThisUpdate.UTC(),
+ NextUpdate: template.NextUpdate.UTC(),
+ Extensions: []pkix.Extension{
+ {
+ Id: oidExtensionAuthorityKeyId,
+ Value: aki,
+ },
+ {
+ Id: oidExtensionCRLNumber,
+ Value: crlNum,
+ },
+ },
+ }
+ if len(revokedCerts) > 0 {
+ tbsCertList.RevokedCertificates = revokedCerts
+ }
+
+ if len(template.ExtraExtensions) > 0 {
+ tbsCertList.Extensions = append(tbsCertList.Extensions, template.ExtraExtensions...)
+ }
+
+ tbsCertListContents, err := asn1.Marshal(tbsCertList)
+ if err != nil {
+ return nil, err
+ }
+
+ // Optimization to only marshal this struct once, when signing and
+ // then embedding in certificateList below.
+ tbsCertList.Raw = tbsCertListContents
+
+ input := tbsCertListContents
+ if hashFunc != 0 {
+ h := hashFunc.New()
+ h.Write(tbsCertListContents)
+ input = h.Sum(nil)
+ }
+ var signerOpts crypto.SignerOpts = hashFunc
+ if template.SignatureAlgorithm.isRSAPSS() {
+ signerOpts = &rsa.PSSOptions{
+ SaltLength: rsa.PSSSaltLengthEqualsHash,
+ Hash: hashFunc,
+ }
+ }
+
+ signature, err := priv.Sign(rand, input, signerOpts)
+ if err != nil {
+ return nil, err
+ }
+
+ return asn1.Marshal(certificateList{
+ TBSCertList: tbsCertList,
+ SignatureAlgorithm: signatureAlgorithm,
+ SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
+ })
+}
+
+// CheckSignatureFrom verifies that the signature on rl is a valid signature
+// from issuer.
+func (rl *RevocationList) CheckSignatureFrom(parent *Certificate) error {
+ if parent.Version == 3 && !parent.BasicConstraintsValid ||
+ parent.BasicConstraintsValid && !parent.IsCA {
+ return ConstraintViolationError{}
+ }
+
+ if parent.KeyUsage != 0 && parent.KeyUsage&KeyUsageCRLSign == 0 {
+ return ConstraintViolationError{}
+ }
+
+ if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
+ return ErrUnsupportedAlgorithm
+ }
+
+ return parent.CheckSignature(rl.SignatureAlgorithm, rl.RawTBSRevocationList, rl.Signature)
+}
diff --git a/contrib/go/_std_1.21/src/crypto/x509/ya.make b/contrib/go/_std_1.21/src/crypto/x509/ya.make
new file mode 100644
index 0000000000..19d8337fae
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/x509/ya.make
@@ -0,0 +1,64 @@
+GO_LIBRARY()
+
+SRCS(
+ cert_pool.go
+ notboring.go
+ parser.go
+ pem_decrypt.go
+ pkcs1.go
+ pkcs8.go
+ root.go
+ sec1.go
+ verify.go
+ x509.go
+)
+
+GO_TEST_SRCS(
+ cert_pool_test.go
+ name_constraints_test.go
+ parser_test.go
+ pem_decrypt_test.go
+ pkcs8_test.go
+ platform_test.go
+ root_test.go
+ sec1_test.go
+ verify_test.go
+ x509_test.go
+)
+
+GO_XTEST_SRCS(
+ example_test.go
+ hybrid_pool_test.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ root_linux.go
+ root_unix.go
+ )
+
+ GO_TEST_SRCS(root_unix_test.go)
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ root_darwin.go
+ )
+
+ GO_XTEST_SRCS(root_darwin_test.go)
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ root_windows.go
+ )
+
+ GO_XTEST_SRCS(root_windows_test.go)
+ENDIF()
+
+END()
+
+RECURSE(
+ internal
+ pkix
+)
diff --git a/contrib/go/_std_1.21/src/crypto/ya.make b/contrib/go/_std_1.21/src/crypto/ya.make
new file mode 100644
index 0000000000..e8680ab1ba
--- /dev/null
+++ b/contrib/go/_std_1.21/src/crypto/ya.make
@@ -0,0 +1,32 @@
+GO_LIBRARY()
+
+SRCS(
+ crypto.go
+)
+
+GO_XTEST_SRCS(issue21104_test.go)
+
+END()
+
+RECURSE(
+ aes
+ cipher
+ des
+ dsa
+ ecdh
+ ecdsa
+ ed25519
+ elliptic
+ hmac
+ internal
+ md5
+ rand
+ rc4
+ rsa
+ sha1
+ sha256
+ sha512
+ subtle
+ tls
+ x509
+)
diff --git a/contrib/go/_std_1.21/src/database/sql/convert.go b/contrib/go/_std_1.21/src/database/sql/convert.go
new file mode 100644
index 0000000000..ffc4e497b4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/database/sql/convert.go
@@ -0,0 +1,591 @@
+// Copyright 2011 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.
+
+// Type conversions for Scan.
+
+package sql
+
+import (
+ "bytes"
+ "database/sql/driver"
+ "errors"
+ "fmt"
+ "reflect"
+ "strconv"
+ "time"
+ "unicode"
+ "unicode/utf8"
+)
+
+var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
+
+func describeNamedValue(nv *driver.NamedValue) string {
+ if len(nv.Name) == 0 {
+ return fmt.Sprintf("$%d", nv.Ordinal)
+ }
+ return fmt.Sprintf("with name %q", nv.Name)
+}
+
+func validateNamedValueName(name string) error {
+ if len(name) == 0 {
+ return nil
+ }
+ r, _ := utf8.DecodeRuneInString(name)
+ if unicode.IsLetter(r) {
+ return nil
+ }
+ return fmt.Errorf("name %q does not begin with a letter", name)
+}
+
+// ccChecker wraps the driver.ColumnConverter and allows it to be used
+// as if it were a NamedValueChecker. If the driver ColumnConverter
+// is not present then the NamedValueChecker will return driver.ErrSkip.
+type ccChecker struct {
+ cci driver.ColumnConverter
+ want int
+}
+
+func (c ccChecker) CheckNamedValue(nv *driver.NamedValue) error {
+ if c.cci == nil {
+ return driver.ErrSkip
+ }
+ // The column converter shouldn't be called on any index
+ // it isn't expecting. The final error will be thrown
+ // in the argument converter loop.
+ index := nv.Ordinal - 1
+ if c.want <= index {
+ return nil
+ }
+
+ // First, see if the value itself knows how to convert
+ // itself to a driver type. For example, a NullString
+ // struct changing into a string or nil.
+ if vr, ok := nv.Value.(driver.Valuer); ok {
+ sv, err := callValuerValue(vr)
+ if err != nil {
+ return err
+ }
+ if !driver.IsValue(sv) {
+ return fmt.Errorf("non-subset type %T returned from Value", sv)
+ }
+ nv.Value = sv
+ }
+
+ // Second, ask the column to sanity check itself. For
+ // example, drivers might use this to make sure that
+ // an int64 values being inserted into a 16-bit
+ // integer field is in range (before getting
+ // truncated), or that a nil can't go into a NOT NULL
+ // column before going across the network to get the
+ // same error.
+ var err error
+ arg := nv.Value
+ nv.Value, err = c.cci.ColumnConverter(index).ConvertValue(arg)
+ if err != nil {
+ return err
+ }
+ if !driver.IsValue(nv.Value) {
+ return fmt.Errorf("driver ColumnConverter error converted %T to unsupported type %T", arg, nv.Value)
+ }
+ return nil
+}
+
+// defaultCheckNamedValue wraps the default ColumnConverter to have the same
+// function signature as the CheckNamedValue in the driver.NamedValueChecker
+// interface.
+func defaultCheckNamedValue(nv *driver.NamedValue) (err error) {
+ nv.Value, err = driver.DefaultParameterConverter.ConvertValue(nv.Value)
+ return err
+}
+
+// driverArgsConnLocked converts arguments from callers of Stmt.Exec and
+// Stmt.Query into driver Values.
+//
+// The statement ds may be nil, if no statement is available.
+//
+// ci must be locked.
+func driverArgsConnLocked(ci driver.Conn, ds *driverStmt, args []any) ([]driver.NamedValue, error) {
+ nvargs := make([]driver.NamedValue, len(args))
+
+ // -1 means the driver doesn't know how to count the number of
+ // placeholders, so we won't sanity check input here and instead let the
+ // driver deal with errors.
+ want := -1
+
+ var si driver.Stmt
+ var cc ccChecker
+ if ds != nil {
+ si = ds.si
+ want = ds.si.NumInput()
+ cc.want = want
+ }
+
+ // Check all types of interfaces from the start.
+ // Drivers may opt to use the NamedValueChecker for special
+ // argument types, then return driver.ErrSkip to pass it along
+ // to the column converter.
+ nvc, ok := si.(driver.NamedValueChecker)
+ if !ok {
+ nvc, ok = ci.(driver.NamedValueChecker)
+ }
+ cci, ok := si.(driver.ColumnConverter)
+ if ok {
+ cc.cci = cci
+ }
+
+ // Loop through all the arguments, checking each one.
+ // If no error is returned simply increment the index
+ // and continue. However if driver.ErrRemoveArgument
+ // is returned the argument is not included in the query
+ // argument list.
+ var err error
+ var n int
+ for _, arg := range args {
+ nv := &nvargs[n]
+ if np, ok := arg.(NamedArg); ok {
+ if err = validateNamedValueName(np.Name); err != nil {
+ return nil, err
+ }
+ arg = np.Value
+ nv.Name = np.Name
+ }
+ nv.Ordinal = n + 1
+ nv.Value = arg
+
+ // Checking sequence has four routes:
+ // A: 1. Default
+ // B: 1. NamedValueChecker 2. Column Converter 3. Default
+ // C: 1. NamedValueChecker 3. Default
+ // D: 1. Column Converter 2. Default
+ //
+ // The only time a Column Converter is called is first
+ // or after NamedValueConverter. If first it is handled before
+ // the nextCheck label. Thus for repeats tries only when the
+ // NamedValueConverter is selected should the Column Converter
+ // be used in the retry.
+ checker := defaultCheckNamedValue
+ nextCC := false
+ switch {
+ case nvc != nil:
+ nextCC = cci != nil
+ checker = nvc.CheckNamedValue
+ case cci != nil:
+ checker = cc.CheckNamedValue
+ }
+
+ nextCheck:
+ err = checker(nv)
+ switch err {
+ case nil:
+ n++
+ continue
+ case driver.ErrRemoveArgument:
+ nvargs = nvargs[:len(nvargs)-1]
+ continue
+ case driver.ErrSkip:
+ if nextCC {
+ nextCC = false
+ checker = cc.CheckNamedValue
+ } else {
+ checker = defaultCheckNamedValue
+ }
+ goto nextCheck
+ default:
+ return nil, fmt.Errorf("sql: converting argument %s type: %v", describeNamedValue(nv), err)
+ }
+ }
+
+ // Check the length of arguments after conversion to allow for omitted
+ // arguments.
+ if want != -1 && len(nvargs) != want {
+ return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(nvargs))
+ }
+
+ return nvargs, nil
+
+}
+
+// convertAssign is the same as convertAssignRows, but without the optional
+// rows argument.
+func convertAssign(dest, src any) error {
+ return convertAssignRows(dest, src, nil)
+}
+
+// convertAssignRows copies to dest the value in src, converting it if possible.
+// An error is returned if the copy would result in loss of information.
+// dest should be a pointer type. If rows is passed in, the rows will
+// be used as the parent for any cursor values converted from a
+// driver.Rows to a *Rows.
+func convertAssignRows(dest, src any, rows *Rows) error {
+ // Common cases, without reflect.
+ switch s := src.(type) {
+ case string:
+ switch d := dest.(type) {
+ case *string:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = s
+ return nil
+ case *[]byte:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = []byte(s)
+ return nil
+ case *RawBytes:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = append((*d)[:0], s...)
+ return nil
+ }
+ case []byte:
+ switch d := dest.(type) {
+ case *string:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = string(s)
+ return nil
+ case *any:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = bytes.Clone(s)
+ return nil
+ case *[]byte:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = bytes.Clone(s)
+ return nil
+ case *RawBytes:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = s
+ return nil
+ }
+ case time.Time:
+ switch d := dest.(type) {
+ case *time.Time:
+ *d = s
+ return nil
+ case *string:
+ *d = s.Format(time.RFC3339Nano)
+ return nil
+ case *[]byte:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = []byte(s.Format(time.RFC3339Nano))
+ return nil
+ case *RawBytes:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = s.AppendFormat((*d)[:0], time.RFC3339Nano)
+ return nil
+ }
+ case decimalDecompose:
+ switch d := dest.(type) {
+ case decimalCompose:
+ return d.Compose(s.Decompose(nil))
+ }
+ case nil:
+ switch d := dest.(type) {
+ case *any:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = nil
+ return nil
+ case *[]byte:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = nil
+ return nil
+ case *RawBytes:
+ if d == nil {
+ return errNilPtr
+ }
+ *d = nil
+ return nil
+ }
+ // The driver is returning a cursor the client may iterate over.
+ case driver.Rows:
+ switch d := dest.(type) {
+ case *Rows:
+ if d == nil {
+ return errNilPtr
+ }
+ if rows == nil {
+ return errors.New("invalid context to convert cursor rows, missing parent *Rows")
+ }
+ rows.closemu.Lock()
+ *d = Rows{
+ dc: rows.dc,
+ releaseConn: func(error) {},
+ rowsi: s,
+ }
+ // Chain the cancel function.
+ parentCancel := rows.cancel
+ rows.cancel = func() {
+ // When Rows.cancel is called, the closemu will be locked as well.
+ // So we can access rs.lasterr.
+ d.close(rows.lasterr)
+ if parentCancel != nil {
+ parentCancel()
+ }
+ }
+ rows.closemu.Unlock()
+ return nil
+ }
+ }
+
+ var sv reflect.Value
+
+ switch d := dest.(type) {
+ case *string:
+ sv = reflect.ValueOf(src)
+ switch sv.Kind() {
+ case reflect.Bool,
+ reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+ reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+ reflect.Float32, reflect.Float64:
+ *d = asString(src)
+ return nil
+ }
+ case *[]byte:
+ sv = reflect.ValueOf(src)
+ if b, ok := asBytes(nil, sv); ok {
+ *d = b
+ return nil
+ }
+ case *RawBytes:
+ sv = reflect.ValueOf(src)
+ if b, ok := asBytes([]byte(*d)[:0], sv); ok {
+ *d = RawBytes(b)
+ return nil
+ }
+ case *bool:
+ bv, err := driver.Bool.ConvertValue(src)
+ if err == nil {
+ *d = bv.(bool)
+ }
+ return err
+ case *any:
+ *d = src
+ return nil
+ }
+
+ if scanner, ok := dest.(Scanner); ok {
+ return scanner.Scan(src)
+ }
+
+ dpv := reflect.ValueOf(dest)
+ if dpv.Kind() != reflect.Pointer {
+ return errors.New("destination not a pointer")
+ }
+ if dpv.IsNil() {
+ return errNilPtr
+ }
+
+ if !sv.IsValid() {
+ sv = reflect.ValueOf(src)
+ }
+
+ dv := reflect.Indirect(dpv)
+ if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) {
+ switch b := src.(type) {
+ case []byte:
+ dv.Set(reflect.ValueOf(bytes.Clone(b)))
+ default:
+ dv.Set(sv)
+ }
+ return nil
+ }
+
+ if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) {
+ dv.Set(sv.Convert(dv.Type()))
+ return nil
+ }
+
+ // The following conversions use a string value as an intermediate representation
+ // to convert between various numeric types.
+ //
+ // This also allows scanning into user defined types such as "type Int int64".
+ // For symmetry, also check for string destination types.
+ switch dv.Kind() {
+ case reflect.Pointer:
+ if src == nil {
+ dv.SetZero()
+ return nil
+ }
+ dv.Set(reflect.New(dv.Type().Elem()))
+ return convertAssignRows(dv.Interface(), src, rows)
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ if src == nil {
+ return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
+ }
+ s := asString(src)
+ i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
+ if err != nil {
+ err = strconvErr(err)
+ return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
+ }
+ dv.SetInt(i64)
+ return nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ if src == nil {
+ return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
+ }
+ s := asString(src)
+ u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
+ if err != nil {
+ err = strconvErr(err)
+ return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
+ }
+ dv.SetUint(u64)
+ return nil
+ case reflect.Float32, reflect.Float64:
+ if src == nil {
+ return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
+ }
+ s := asString(src)
+ f64, err := strconv.ParseFloat(s, dv.Type().Bits())
+ if err != nil {
+ err = strconvErr(err)
+ return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
+ }
+ dv.SetFloat(f64)
+ return nil
+ case reflect.String:
+ if src == nil {
+ return fmt.Errorf("converting NULL to %s is unsupported", dv.Kind())
+ }
+ switch v := src.(type) {
+ case string:
+ dv.SetString(v)
+ return nil
+ case []byte:
+ dv.SetString(string(v))
+ return nil
+ }
+ }
+
+ return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest)
+}
+
+func strconvErr(err error) error {
+ if ne, ok := err.(*strconv.NumError); ok {
+ return ne.Err
+ }
+ return err
+}
+
+func asString(src any) string {
+ switch v := src.(type) {
+ case string:
+ return v
+ case []byte:
+ return string(v)
+ }
+ rv := reflect.ValueOf(src)
+ switch rv.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return strconv.FormatInt(rv.Int(), 10)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return strconv.FormatUint(rv.Uint(), 10)
+ case reflect.Float64:
+ return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
+ case reflect.Float32:
+ return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
+ case reflect.Bool:
+ return strconv.FormatBool(rv.Bool())
+ }
+ return fmt.Sprintf("%v", src)
+}
+
+func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) {
+ switch rv.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return strconv.AppendInt(buf, rv.Int(), 10), true
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ return strconv.AppendUint(buf, rv.Uint(), 10), true
+ case reflect.Float32:
+ return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true
+ case reflect.Float64:
+ return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true
+ case reflect.Bool:
+ return strconv.AppendBool(buf, rv.Bool()), true
+ case reflect.String:
+ s := rv.String()
+ return append(buf, s...), true
+ }
+ return
+}
+
+var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
+
+// callValuerValue returns vr.Value(), with one exception:
+// If vr.Value is an auto-generated method on a pointer type and the
+// pointer is nil, it would panic at runtime in the panicwrap
+// method. Treat it like nil instead.
+// Issue 8415.
+//
+// This is so people can implement driver.Value on value types and
+// still use nil pointers to those types to mean nil/NULL, just like
+// string/*string.
+//
+// This function is mirrored in the database/sql/driver package.
+func callValuerValue(vr driver.Valuer) (v driver.Value, err error) {
+ if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Pointer &&
+ rv.IsNil() &&
+ rv.Type().Elem().Implements(valuerReflectType) {
+ return nil, nil
+ }
+ return vr.Value()
+}
+
+// decimal composes or decomposes a decimal value to and from individual parts.
+// There are four parts: a boolean negative flag, a form byte with three possible states
+// (finite=0, infinite=1, NaN=2), a base-2 big-endian integer
+// coefficient (also known as a significand) as a []byte, and an int32 exponent.
+// These are composed into a final value as "decimal = (neg) (form=finite) coefficient * 10 ^ exponent".
+// A zero length coefficient is a zero value.
+// The big-endian integer coefficient stores the most significant byte first (at coefficient[0]).
+// If the form is not finite the coefficient and exponent should be ignored.
+// The negative parameter may be set to true for any form, although implementations are not required
+// to respect the negative parameter in the non-finite form.
+//
+// Implementations may choose to set the negative parameter to true on a zero or NaN value,
+// but implementations that do not differentiate between negative and positive
+// zero or NaN values should ignore the negative parameter without error.
+// If an implementation does not support Infinity it may be converted into a NaN without error.
+// If a value is set that is larger than what is supported by an implementation,
+// an error must be returned.
+// Implementations must return an error if a NaN or Infinity is attempted to be set while neither
+// are supported.
+//
+// NOTE(kardianos): This is an experimental interface. See https://golang.org/issue/30870
+type decimal interface {
+ decimalDecompose
+ decimalCompose
+}
+
+type decimalDecompose interface {
+ // Decompose returns the internal decimal state in parts.
+ // If the provided buf has sufficient capacity, buf may be returned as the coefficient with
+ // the value set and length set as appropriate.
+ Decompose(buf []byte) (form byte, negative bool, coefficient []byte, exponent int32)
+}
+
+type decimalCompose interface {
+ // Compose sets the internal decimal value from parts. If the value cannot be
+ // represented then an error should be returned.
+ Compose(form byte, negative bool, coefficient []byte, exponent int32) error
+}
diff --git a/contrib/go/_std_1.20/src/database/sql/ctxutil.go b/contrib/go/_std_1.21/src/database/sql/ctxutil.go
index 4dbe6af6d2..4dbe6af6d2 100644
--- a/contrib/go/_std_1.20/src/database/sql/ctxutil.go
+++ b/contrib/go/_std_1.21/src/database/sql/ctxutil.go
diff --git a/contrib/go/_std_1.20/src/database/sql/driver/driver.go b/contrib/go/_std_1.21/src/database/sql/driver/driver.go
index daf282bf74..daf282bf74 100644
--- a/contrib/go/_std_1.20/src/database/sql/driver/driver.go
+++ b/contrib/go/_std_1.21/src/database/sql/driver/driver.go
diff --git a/contrib/go/_std_1.20/src/database/sql/driver/types.go b/contrib/go/_std_1.21/src/database/sql/driver/types.go
index fa98df7acd..fa98df7acd 100644
--- a/contrib/go/_std_1.20/src/database/sql/driver/types.go
+++ b/contrib/go/_std_1.21/src/database/sql/driver/types.go
diff --git a/contrib/go/_std_1.21/src/database/sql/driver/ya.make b/contrib/go/_std_1.21/src/database/sql/driver/ya.make
new file mode 100644
index 0000000000..17f61233d8
--- /dev/null
+++ b/contrib/go/_std_1.21/src/database/sql/driver/ya.make
@@ -0,0 +1,13 @@
+GO_LIBRARY()
+
+SRCS(
+ driver.go
+ types.go
+)
+
+GO_TEST_SRCS(types_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/database/sql/sql.go b/contrib/go/_std_1.21/src/database/sql/sql.go
new file mode 100644
index 0000000000..836fe83e2e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/database/sql/sql.go
@@ -0,0 +1,3503 @@
+// Copyright 2011 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 sql provides a generic interface around SQL (or SQL-like)
+// databases.
+//
+// The sql package must be used in conjunction with a database driver.
+// See https://golang.org/s/sqldrivers for a list of drivers.
+//
+// Drivers that do not support context cancellation will not return until
+// after the query is completed.
+//
+// For usage examples, see the wiki page at
+// https://golang.org/s/sqlwiki.
+package sql
+
+import (
+ "context"
+ "database/sql/driver"
+ "errors"
+ "fmt"
+ "io"
+ "reflect"
+ "runtime"
+ "sort"
+ "strconv"
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+var (
+ driversMu sync.RWMutex
+ drivers = make(map[string]driver.Driver)
+)
+
+// nowFunc returns the current time; it's overridden in tests.
+var nowFunc = time.Now
+
+// Register makes a database driver available by the provided name.
+// If Register is called twice with the same name or if driver is nil,
+// it panics.
+func Register(name string, driver driver.Driver) {
+ driversMu.Lock()
+ defer driversMu.Unlock()
+ if driver == nil {
+ panic("sql: Register driver is nil")
+ }
+ if _, dup := drivers[name]; dup {
+ panic("sql: Register called twice for driver " + name)
+ }
+ drivers[name] = driver
+}
+
+func unregisterAllDrivers() {
+ driversMu.Lock()
+ defer driversMu.Unlock()
+ // For tests.
+ drivers = make(map[string]driver.Driver)
+}
+
+// Drivers returns a sorted list of the names of the registered drivers.
+func Drivers() []string {
+ driversMu.RLock()
+ defer driversMu.RUnlock()
+ list := make([]string, 0, len(drivers))
+ for name := range drivers {
+ list = append(list, name)
+ }
+ sort.Strings(list)
+ return list
+}
+
+// A NamedArg is a named argument. NamedArg values may be used as
+// arguments to Query or Exec and bind to the corresponding named
+// parameter in the SQL statement.
+//
+// For a more concise way to create NamedArg values, see
+// the Named function.
+type NamedArg struct {
+ _NamedFieldsRequired struct{}
+
+ // Name is the name of the parameter placeholder.
+ //
+ // If empty, the ordinal position in the argument list will be
+ // used.
+ //
+ // Name must omit any symbol prefix.
+ Name string
+
+ // Value is the value of the parameter.
+ // It may be assigned the same value types as the query
+ // arguments.
+ Value any
+}
+
+// Named provides a more concise way to create NamedArg values.
+//
+// Example usage:
+//
+// db.ExecContext(ctx, `
+// delete from Invoice
+// where
+// TimeCreated < @end
+// and TimeCreated >= @start;`,
+// sql.Named("start", startTime),
+// sql.Named("end", endTime),
+// )
+func Named(name string, value any) NamedArg {
+ // This method exists because the go1compat promise
+ // doesn't guarantee that structs don't grow more fields,
+ // so unkeyed struct literals are a vet error. Thus, we don't
+ // want to allow sql.NamedArg{name, value}.
+ return NamedArg{Name: name, Value: value}
+}
+
+// IsolationLevel is the transaction isolation level used in TxOptions.
+type IsolationLevel int
+
+// Various isolation levels that drivers may support in BeginTx.
+// If a driver does not support a given isolation level an error may be returned.
+//
+// See https://en.wikipedia.org/wiki/Isolation_(database_systems)#Isolation_levels.
+const (
+ LevelDefault IsolationLevel = iota
+ LevelReadUncommitted
+ LevelReadCommitted
+ LevelWriteCommitted
+ LevelRepeatableRead
+ LevelSnapshot
+ LevelSerializable
+ LevelLinearizable
+)
+
+// String returns the name of the transaction isolation level.
+func (i IsolationLevel) String() string {
+ switch i {
+ case LevelDefault:
+ return "Default"
+ case LevelReadUncommitted:
+ return "Read Uncommitted"
+ case LevelReadCommitted:
+ return "Read Committed"
+ case LevelWriteCommitted:
+ return "Write Committed"
+ case LevelRepeatableRead:
+ return "Repeatable Read"
+ case LevelSnapshot:
+ return "Snapshot"
+ case LevelSerializable:
+ return "Serializable"
+ case LevelLinearizable:
+ return "Linearizable"
+ default:
+ return "IsolationLevel(" + strconv.Itoa(int(i)) + ")"
+ }
+}
+
+var _ fmt.Stringer = LevelDefault
+
+// TxOptions holds the transaction options to be used in DB.BeginTx.
+type TxOptions struct {
+ // Isolation is the transaction isolation level.
+ // If zero, the driver or database's default level is used.
+ Isolation IsolationLevel
+ ReadOnly bool
+}
+
+// RawBytes is a byte slice that holds a reference to memory owned by
+// the database itself. After a Scan into a RawBytes, the slice is only
+// valid until the next call to Next, Scan, or Close.
+type RawBytes []byte
+
+// NullString represents a string that may be null.
+// NullString implements the Scanner interface so
+// it can be used as a scan destination:
+//
+// var s NullString
+// err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s)
+// ...
+// if s.Valid {
+// // use s.String
+// } else {
+// // NULL value
+// }
+type NullString struct {
+ String string
+ Valid bool // Valid is true if String is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (ns *NullString) Scan(value any) error {
+ if value == nil {
+ ns.String, ns.Valid = "", false
+ return nil
+ }
+ ns.Valid = true
+ return convertAssign(&ns.String, value)
+}
+
+// Value implements the driver Valuer interface.
+func (ns NullString) Value() (driver.Value, error) {
+ if !ns.Valid {
+ return nil, nil
+ }
+ return ns.String, nil
+}
+
+// NullInt64 represents an int64 that may be null.
+// NullInt64 implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullInt64 struct {
+ Int64 int64
+ Valid bool // Valid is true if Int64 is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullInt64) Scan(value any) error {
+ if value == nil {
+ n.Int64, n.Valid = 0, false
+ return nil
+ }
+ n.Valid = true
+ return convertAssign(&n.Int64, value)
+}
+
+// Value implements the driver Valuer interface.
+func (n NullInt64) Value() (driver.Value, error) {
+ if !n.Valid {
+ return nil, nil
+ }
+ return n.Int64, nil
+}
+
+// NullInt32 represents an int32 that may be null.
+// NullInt32 implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullInt32 struct {
+ Int32 int32
+ Valid bool // Valid is true if Int32 is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullInt32) Scan(value any) error {
+ if value == nil {
+ n.Int32, n.Valid = 0, false
+ return nil
+ }
+ n.Valid = true
+ return convertAssign(&n.Int32, value)
+}
+
+// Value implements the driver Valuer interface.
+func (n NullInt32) Value() (driver.Value, error) {
+ if !n.Valid {
+ return nil, nil
+ }
+ return int64(n.Int32), nil
+}
+
+// NullInt16 represents an int16 that may be null.
+// NullInt16 implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullInt16 struct {
+ Int16 int16
+ Valid bool // Valid is true if Int16 is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullInt16) Scan(value any) error {
+ if value == nil {
+ n.Int16, n.Valid = 0, false
+ return nil
+ }
+ err := convertAssign(&n.Int16, value)
+ n.Valid = err == nil
+ return err
+}
+
+// Value implements the driver Valuer interface.
+func (n NullInt16) Value() (driver.Value, error) {
+ if !n.Valid {
+ return nil, nil
+ }
+ return int64(n.Int16), nil
+}
+
+// NullByte represents a byte that may be null.
+// NullByte implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullByte struct {
+ Byte byte
+ Valid bool // Valid is true if Byte is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullByte) Scan(value any) error {
+ if value == nil {
+ n.Byte, n.Valid = 0, false
+ return nil
+ }
+ err := convertAssign(&n.Byte, value)
+ n.Valid = err == nil
+ return err
+}
+
+// Value implements the driver Valuer interface.
+func (n NullByte) Value() (driver.Value, error) {
+ if !n.Valid {
+ return nil, nil
+ }
+ return int64(n.Byte), nil
+}
+
+// NullFloat64 represents a float64 that may be null.
+// NullFloat64 implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullFloat64 struct {
+ Float64 float64
+ Valid bool // Valid is true if Float64 is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullFloat64) Scan(value any) error {
+ if value == nil {
+ n.Float64, n.Valid = 0, false
+ return nil
+ }
+ n.Valid = true
+ return convertAssign(&n.Float64, value)
+}
+
+// Value implements the driver Valuer interface.
+func (n NullFloat64) Value() (driver.Value, error) {
+ if !n.Valid {
+ return nil, nil
+ }
+ return n.Float64, nil
+}
+
+// NullBool represents a bool that may be null.
+// NullBool implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullBool struct {
+ Bool bool
+ Valid bool // Valid is true if Bool is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullBool) Scan(value any) error {
+ if value == nil {
+ n.Bool, n.Valid = false, false
+ return nil
+ }
+ n.Valid = true
+ return convertAssign(&n.Bool, value)
+}
+
+// Value implements the driver Valuer interface.
+func (n NullBool) Value() (driver.Value, error) {
+ if !n.Valid {
+ return nil, nil
+ }
+ return n.Bool, nil
+}
+
+// NullTime represents a time.Time that may be null.
+// NullTime implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullTime struct {
+ Time time.Time
+ Valid bool // Valid is true if Time is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullTime) Scan(value any) error {
+ if value == nil {
+ n.Time, n.Valid = time.Time{}, false
+ return nil
+ }
+ n.Valid = true
+ return convertAssign(&n.Time, value)
+}
+
+// Value implements the driver Valuer interface.
+func (n NullTime) Value() (driver.Value, error) {
+ if !n.Valid {
+ return nil, nil
+ }
+ return n.Time, nil
+}
+
+// Scanner is an interface used by Scan.
+type Scanner interface {
+ // Scan assigns a value from a database driver.
+ //
+ // The src value will be of one of the following types:
+ //
+ // int64
+ // float64
+ // bool
+ // []byte
+ // string
+ // time.Time
+ // nil - for NULL values
+ //
+ // An error should be returned if the value cannot be stored
+ // without loss of information.
+ //
+ // Reference types such as []byte are only valid until the next call to Scan
+ // and should not be retained. Their underlying memory is owned by the driver.
+ // If retention is necessary, copy their values before the next call to Scan.
+ Scan(src any) error
+}
+
+// Out may be used to retrieve OUTPUT value parameters from stored procedures.
+//
+// Not all drivers and databases support OUTPUT value parameters.
+//
+// Example usage:
+//
+// var outArg string
+// _, err := db.ExecContext(ctx, "ProcName", sql.Named("Arg1", sql.Out{Dest: &outArg}))
+type Out struct {
+ _NamedFieldsRequired struct{}
+
+ // Dest is a pointer to the value that will be set to the result of the
+ // stored procedure's OUTPUT parameter.
+ Dest any
+
+ // In is whether the parameter is an INOUT parameter. If so, the input value to the stored
+ // procedure is the dereferenced value of Dest's pointer, which is then replaced with
+ // the output value.
+ In bool
+}
+
+// ErrNoRows is returned by Scan when QueryRow doesn't return a
+// row. In such a case, QueryRow returns a placeholder *Row value that
+// defers this error until a Scan.
+var ErrNoRows = errors.New("sql: no rows in result set")
+
+// DB is a database handle representing a pool of zero or more
+// underlying connections. It's safe for concurrent use by multiple
+// goroutines.
+//
+// The sql package creates and frees connections automatically; it
+// also maintains a free pool of idle connections. If the database has
+// a concept of per-connection state, such state can be reliably observed
+// within a transaction (Tx) or connection (Conn). Once DB.Begin is called, the
+// returned Tx is bound to a single connection. Once Commit or
+// Rollback is called on the transaction, that transaction's
+// connection is returned to DB's idle connection pool. The pool size
+// can be controlled with SetMaxIdleConns.
+type DB struct {
+ // Total time waited for new connections.
+ waitDuration atomic.Int64
+
+ connector driver.Connector
+ // numClosed is an atomic counter which represents a total number of
+ // closed connections. Stmt.openStmt checks it before cleaning closed
+ // connections in Stmt.css.
+ numClosed atomic.Uint64
+
+ mu sync.Mutex // protects following fields
+ freeConn []*driverConn // free connections ordered by returnedAt oldest to newest
+ connRequests map[uint64]chan connRequest
+ nextRequest uint64 // Next key to use in connRequests.
+ numOpen int // number of opened and pending open connections
+ // Used to signal the need for new connections
+ // a goroutine running connectionOpener() reads on this chan and
+ // maybeOpenNewConnections sends on the chan (one send per needed connection)
+ // It is closed during db.Close(). The close tells the connectionOpener
+ // goroutine to exit.
+ openerCh chan struct{}
+ closed bool
+ dep map[finalCloser]depSet
+ lastPut map[*driverConn]string // stacktrace of last conn's put; debug only
+ maxIdleCount int // zero means defaultMaxIdleConns; negative means 0
+ maxOpen int // <= 0 means unlimited
+ maxLifetime time.Duration // maximum amount of time a connection may be reused
+ maxIdleTime time.Duration // maximum amount of time a connection may be idle before being closed
+ cleanerCh chan struct{}
+ waitCount int64 // Total number of connections waited for.
+ maxIdleClosed int64 // Total number of connections closed due to idle count.
+ maxIdleTimeClosed int64 // Total number of connections closed due to idle time.
+ maxLifetimeClosed int64 // Total number of connections closed due to max connection lifetime limit.
+
+ stop func() // stop cancels the connection opener.
+}
+
+// connReuseStrategy determines how (*DB).conn returns database connections.
+type connReuseStrategy uint8
+
+const (
+ // alwaysNewConn forces a new connection to the database.
+ alwaysNewConn connReuseStrategy = iota
+ // cachedOrNewConn returns a cached connection, if available, else waits
+ // for one to become available (if MaxOpenConns has been reached) or
+ // creates a new database connection.
+ cachedOrNewConn
+)
+
+// driverConn wraps a driver.Conn with a mutex, to
+// be held during all calls into the Conn. (including any calls onto
+// interfaces returned via that Conn, such as calls on Tx, Stmt,
+// Result, Rows)
+type driverConn struct {
+ db *DB
+ createdAt time.Time
+
+ sync.Mutex // guards following
+ ci driver.Conn
+ needReset bool // The connection session should be reset before use if true.
+ closed bool
+ finalClosed bool // ci.Close has been called
+ openStmt map[*driverStmt]bool
+
+ // guarded by db.mu
+ inUse bool
+ returnedAt time.Time // Time the connection was created or returned.
+ onPut []func() // code (with db.mu held) run when conn is next returned
+ dbmuClosed bool // same as closed, but guarded by db.mu, for removeClosedStmtLocked
+}
+
+func (dc *driverConn) releaseConn(err error) {
+ dc.db.putConn(dc, err, true)
+}
+
+func (dc *driverConn) removeOpenStmt(ds *driverStmt) {
+ dc.Lock()
+ defer dc.Unlock()
+ delete(dc.openStmt, ds)
+}
+
+func (dc *driverConn) expired(timeout time.Duration) bool {
+ if timeout <= 0 {
+ return false
+ }
+ return dc.createdAt.Add(timeout).Before(nowFunc())
+}
+
+// resetSession checks if the driver connection needs the
+// session to be reset and if required, resets it.
+func (dc *driverConn) resetSession(ctx context.Context) error {
+ dc.Lock()
+ defer dc.Unlock()
+
+ if !dc.needReset {
+ return nil
+ }
+ if cr, ok := dc.ci.(driver.SessionResetter); ok {
+ return cr.ResetSession(ctx)
+ }
+ return nil
+}
+
+// validateConnection checks if the connection is valid and can
+// still be used. It also marks the session for reset if required.
+func (dc *driverConn) validateConnection(needsReset bool) bool {
+ dc.Lock()
+ defer dc.Unlock()
+
+ if needsReset {
+ dc.needReset = true
+ }
+ if cv, ok := dc.ci.(driver.Validator); ok {
+ return cv.IsValid()
+ }
+ return true
+}
+
+// prepareLocked prepares the query on dc. When cg == nil the dc must keep track of
+// the prepared statements in a pool.
+func (dc *driverConn) prepareLocked(ctx context.Context, cg stmtConnGrabber, query string) (*driverStmt, error) {
+ si, err := ctxDriverPrepare(ctx, dc.ci, query)
+ if err != nil {
+ return nil, err
+ }
+ ds := &driverStmt{Locker: dc, si: si}
+
+ // No need to manage open statements if there is a single connection grabber.
+ if cg != nil {
+ return ds, nil
+ }
+
+ // Track each driverConn's open statements, so we can close them
+ // before closing the conn.
+ //
+ // Wrap all driver.Stmt is *driverStmt to ensure they are only closed once.
+ if dc.openStmt == nil {
+ dc.openStmt = make(map[*driverStmt]bool)
+ }
+ dc.openStmt[ds] = true
+ return ds, nil
+}
+
+// the dc.db's Mutex is held.
+func (dc *driverConn) closeDBLocked() func() error {
+ dc.Lock()
+ defer dc.Unlock()
+ if dc.closed {
+ return func() error { return errors.New("sql: duplicate driverConn close") }
+ }
+ dc.closed = true
+ return dc.db.removeDepLocked(dc, dc)
+}
+
+func (dc *driverConn) Close() error {
+ dc.Lock()
+ if dc.closed {
+ dc.Unlock()
+ return errors.New("sql: duplicate driverConn close")
+ }
+ dc.closed = true
+ dc.Unlock() // not defer; removeDep finalClose calls may need to lock
+
+ // And now updates that require holding dc.mu.Lock.
+ dc.db.mu.Lock()
+ dc.dbmuClosed = true
+ fn := dc.db.removeDepLocked(dc, dc)
+ dc.db.mu.Unlock()
+ return fn()
+}
+
+func (dc *driverConn) finalClose() error {
+ var err error
+
+ // Each *driverStmt has a lock to the dc. Copy the list out of the dc
+ // before calling close on each stmt.
+ var openStmt []*driverStmt
+ withLock(dc, func() {
+ openStmt = make([]*driverStmt, 0, len(dc.openStmt))
+ for ds := range dc.openStmt {
+ openStmt = append(openStmt, ds)
+ }
+ dc.openStmt = nil
+ })
+ for _, ds := range openStmt {
+ ds.Close()
+ }
+ withLock(dc, func() {
+ dc.finalClosed = true
+ err = dc.ci.Close()
+ dc.ci = nil
+ })
+
+ dc.db.mu.Lock()
+ dc.db.numOpen--
+ dc.db.maybeOpenNewConnections()
+ dc.db.mu.Unlock()
+
+ dc.db.numClosed.Add(1)
+ return err
+}
+
+// driverStmt associates a driver.Stmt with the
+// *driverConn from which it came, so the driverConn's lock can be
+// held during calls.
+type driverStmt struct {
+ sync.Locker // the *driverConn
+ si driver.Stmt
+ closed bool
+ closeErr error // return value of previous Close call
+}
+
+// Close ensures driver.Stmt is only closed once and always returns the same
+// result.
+func (ds *driverStmt) Close() error {
+ ds.Lock()
+ defer ds.Unlock()
+ if ds.closed {
+ return ds.closeErr
+ }
+ ds.closed = true
+ ds.closeErr = ds.si.Close()
+ return ds.closeErr
+}
+
+// depSet is a finalCloser's outstanding dependencies
+type depSet map[any]bool // set of true bools
+
+// The finalCloser interface is used by (*DB).addDep and related
+// dependency reference counting.
+type finalCloser interface {
+ // finalClose is called when the reference count of an object
+ // goes to zero. (*DB).mu is not held while calling it.
+ finalClose() error
+}
+
+// addDep notes that x now depends on dep, and x's finalClose won't be
+// called until all of x's dependencies are removed with removeDep.
+func (db *DB) addDep(x finalCloser, dep any) {
+ db.mu.Lock()
+ defer db.mu.Unlock()
+ db.addDepLocked(x, dep)
+}
+
+func (db *DB) addDepLocked(x finalCloser, dep any) {
+ if db.dep == nil {
+ db.dep = make(map[finalCloser]depSet)
+ }
+ xdep := db.dep[x]
+ if xdep == nil {
+ xdep = make(depSet)
+ db.dep[x] = xdep
+ }
+ xdep[dep] = true
+}
+
+// removeDep notes that x no longer depends on dep.
+// If x still has dependencies, nil is returned.
+// If x no longer has any dependencies, its finalClose method will be
+// called and its error value will be returned.
+func (db *DB) removeDep(x finalCloser, dep any) error {
+ db.mu.Lock()
+ fn := db.removeDepLocked(x, dep)
+ db.mu.Unlock()
+ return fn()
+}
+
+func (db *DB) removeDepLocked(x finalCloser, dep any) func() error {
+ xdep, ok := db.dep[x]
+ if !ok {
+ panic(fmt.Sprintf("unpaired removeDep: no deps for %T", x))
+ }
+
+ l0 := len(xdep)
+ delete(xdep, dep)
+
+ switch len(xdep) {
+ case l0:
+ // Nothing removed. Shouldn't happen.
+ panic(fmt.Sprintf("unpaired removeDep: no %T dep on %T", dep, x))
+ case 0:
+ // No more dependencies.
+ delete(db.dep, x)
+ return x.finalClose
+ default:
+ // Dependencies remain.
+ return func() error { return nil }
+ }
+}
+
+// This is the size of the connectionOpener request chan (DB.openerCh).
+// This value should be larger than the maximum typical value
+// used for db.maxOpen. If maxOpen is significantly larger than
+// connectionRequestQueueSize then it is possible for ALL calls into the *DB
+// to block until the connectionOpener can satisfy the backlog of requests.
+var connectionRequestQueueSize = 1000000
+
+type dsnConnector struct {
+ dsn string
+ driver driver.Driver
+}
+
+func (t dsnConnector) Connect(_ context.Context) (driver.Conn, error) {
+ return t.driver.Open(t.dsn)
+}
+
+func (t dsnConnector) Driver() driver.Driver {
+ return t.driver
+}
+
+// OpenDB opens a database using a Connector, allowing drivers to
+// bypass a string based data source name.
+//
+// Most users will open a database via a driver-specific connection
+// helper function that returns a *DB. No database drivers are included
+// in the Go standard library. See https://golang.org/s/sqldrivers for
+// a list of third-party drivers.
+//
+// OpenDB may just validate its arguments without creating a connection
+// to the database. To verify that the data source name is valid, call
+// Ping.
+//
+// The returned DB is safe for concurrent use by multiple goroutines
+// and maintains its own pool of idle connections. Thus, the OpenDB
+// function should be called just once. It is rarely necessary to
+// close a DB.
+func OpenDB(c driver.Connector) *DB {
+ ctx, cancel := context.WithCancel(context.Background())
+ db := &DB{
+ connector: c,
+ openerCh: make(chan struct{}, connectionRequestQueueSize),
+ lastPut: make(map[*driverConn]string),
+ connRequests: make(map[uint64]chan connRequest),
+ stop: cancel,
+ }
+
+ go db.connectionOpener(ctx)
+
+ return db
+}
+
+// Open opens a database specified by its database driver name and a
+// driver-specific data source name, usually consisting of at least a
+// database name and connection information.
+//
+// Most users will open a database via a driver-specific connection
+// helper function that returns a *DB. No database drivers are included
+// in the Go standard library. See https://golang.org/s/sqldrivers for
+// a list of third-party drivers.
+//
+// Open may just validate its arguments without creating a connection
+// to the database. To verify that the data source name is valid, call
+// Ping.
+//
+// The returned DB is safe for concurrent use by multiple goroutines
+// and maintains its own pool of idle connections. Thus, the Open
+// function should be called just once. It is rarely necessary to
+// close a DB.
+func Open(driverName, dataSourceName string) (*DB, error) {
+ driversMu.RLock()
+ driveri, ok := drivers[driverName]
+ driversMu.RUnlock()
+ if !ok {
+ return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
+ }
+
+ if driverCtx, ok := driveri.(driver.DriverContext); ok {
+ connector, err := driverCtx.OpenConnector(dataSourceName)
+ if err != nil {
+ return nil, err
+ }
+ return OpenDB(connector), nil
+ }
+
+ return OpenDB(dsnConnector{dsn: dataSourceName, driver: driveri}), nil
+}
+
+func (db *DB) pingDC(ctx context.Context, dc *driverConn, release func(error)) error {
+ var err error
+ if pinger, ok := dc.ci.(driver.Pinger); ok {
+ withLock(dc, func() {
+ err = pinger.Ping(ctx)
+ })
+ }
+ release(err)
+ return err
+}
+
+// PingContext verifies a connection to the database is still alive,
+// establishing a connection if necessary.
+func (db *DB) PingContext(ctx context.Context) error {
+ var dc *driverConn
+ var err error
+
+ err = db.retry(func(strategy connReuseStrategy) error {
+ dc, err = db.conn(ctx, strategy)
+ return err
+ })
+
+ if err != nil {
+ return err
+ }
+
+ return db.pingDC(ctx, dc, dc.releaseConn)
+}
+
+// Ping verifies a connection to the database is still alive,
+// establishing a connection if necessary.
+//
+// Ping uses context.Background internally; to specify the context, use
+// PingContext.
+func (db *DB) Ping() error {
+ return db.PingContext(context.Background())
+}
+
+// Close closes the database and prevents new queries from starting.
+// Close then waits for all queries that have started processing on the server
+// to finish.
+//
+// It is rare to Close a DB, as the DB handle is meant to be
+// long-lived and shared between many goroutines.
+func (db *DB) Close() error {
+ db.mu.Lock()
+ if db.closed { // Make DB.Close idempotent
+ db.mu.Unlock()
+ return nil
+ }
+ if db.cleanerCh != nil {
+ close(db.cleanerCh)
+ }
+ var err error
+ fns := make([]func() error, 0, len(db.freeConn))
+ for _, dc := range db.freeConn {
+ fns = append(fns, dc.closeDBLocked())
+ }
+ db.freeConn = nil
+ db.closed = true
+ for _, req := range db.connRequests {
+ close(req)
+ }
+ db.mu.Unlock()
+ for _, fn := range fns {
+ err1 := fn()
+ if err1 != nil {
+ err = err1
+ }
+ }
+ db.stop()
+ if c, ok := db.connector.(io.Closer); ok {
+ err1 := c.Close()
+ if err1 != nil {
+ err = err1
+ }
+ }
+ return err
+}
+
+const defaultMaxIdleConns = 2
+
+func (db *DB) maxIdleConnsLocked() int {
+ n := db.maxIdleCount
+ switch {
+ case n == 0:
+ // TODO(bradfitz): ask driver, if supported, for its default preference
+ return defaultMaxIdleConns
+ case n < 0:
+ return 0
+ default:
+ return n
+ }
+}
+
+func (db *DB) shortestIdleTimeLocked() time.Duration {
+ if db.maxIdleTime <= 0 {
+ return db.maxLifetime
+ }
+ if db.maxLifetime <= 0 {
+ return db.maxIdleTime
+ }
+
+ min := db.maxIdleTime
+ if min > db.maxLifetime {
+ min = db.maxLifetime
+ }
+ return min
+}
+
+// SetMaxIdleConns sets the maximum number of connections in the idle
+// connection pool.
+//
+// If MaxOpenConns is greater than 0 but less than the new MaxIdleConns,
+// then the new MaxIdleConns will be reduced to match the MaxOpenConns limit.
+//
+// If n <= 0, no idle connections are retained.
+//
+// The default max idle connections is currently 2. This may change in
+// a future release.
+func (db *DB) SetMaxIdleConns(n int) {
+ db.mu.Lock()
+ if n > 0 {
+ db.maxIdleCount = n
+ } else {
+ // No idle connections.
+ db.maxIdleCount = -1
+ }
+ // Make sure maxIdle doesn't exceed maxOpen
+ if db.maxOpen > 0 && db.maxIdleConnsLocked() > db.maxOpen {
+ db.maxIdleCount = db.maxOpen
+ }
+ var closing []*driverConn
+ idleCount := len(db.freeConn)
+ maxIdle := db.maxIdleConnsLocked()
+ if idleCount > maxIdle {
+ closing = db.freeConn[maxIdle:]
+ db.freeConn = db.freeConn[:maxIdle]
+ }
+ db.maxIdleClosed += int64(len(closing))
+ db.mu.Unlock()
+ for _, c := range closing {
+ c.Close()
+ }
+}
+
+// SetMaxOpenConns sets the maximum number of open connections to the database.
+//
+// If MaxIdleConns is greater than 0 and the new MaxOpenConns is less than
+// MaxIdleConns, then MaxIdleConns will be reduced to match the new
+// MaxOpenConns limit.
+//
+// If n <= 0, then there is no limit on the number of open connections.
+// The default is 0 (unlimited).
+func (db *DB) SetMaxOpenConns(n int) {
+ db.mu.Lock()
+ db.maxOpen = n
+ if n < 0 {
+ db.maxOpen = 0
+ }
+ syncMaxIdle := db.maxOpen > 0 && db.maxIdleConnsLocked() > db.maxOpen
+ db.mu.Unlock()
+ if syncMaxIdle {
+ db.SetMaxIdleConns(n)
+ }
+}
+
+// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
+//
+// Expired connections may be closed lazily before reuse.
+//
+// If d <= 0, connections are not closed due to a connection's age.
+func (db *DB) SetConnMaxLifetime(d time.Duration) {
+ if d < 0 {
+ d = 0
+ }
+ db.mu.Lock()
+ // Wake cleaner up when lifetime is shortened.
+ if d > 0 && d < db.maxLifetime && db.cleanerCh != nil {
+ select {
+ case db.cleanerCh <- struct{}{}:
+ default:
+ }
+ }
+ db.maxLifetime = d
+ db.startCleanerLocked()
+ db.mu.Unlock()
+}
+
+// SetConnMaxIdleTime sets the maximum amount of time a connection may be idle.
+//
+// Expired connections may be closed lazily before reuse.
+//
+// If d <= 0, connections are not closed due to a connection's idle time.
+func (db *DB) SetConnMaxIdleTime(d time.Duration) {
+ if d < 0 {
+ d = 0
+ }
+ db.mu.Lock()
+ defer db.mu.Unlock()
+
+ // Wake cleaner up when idle time is shortened.
+ if d > 0 && d < db.maxIdleTime && db.cleanerCh != nil {
+ select {
+ case db.cleanerCh <- struct{}{}:
+ default:
+ }
+ }
+ db.maxIdleTime = d
+ db.startCleanerLocked()
+}
+
+// startCleanerLocked starts connectionCleaner if needed.
+func (db *DB) startCleanerLocked() {
+ if (db.maxLifetime > 0 || db.maxIdleTime > 0) && db.numOpen > 0 && db.cleanerCh == nil {
+ db.cleanerCh = make(chan struct{}, 1)
+ go db.connectionCleaner(db.shortestIdleTimeLocked())
+ }
+}
+
+func (db *DB) connectionCleaner(d time.Duration) {
+ const minInterval = time.Second
+
+ if d < minInterval {
+ d = minInterval
+ }
+ t := time.NewTimer(d)
+
+ for {
+ select {
+ case <-t.C:
+ case <-db.cleanerCh: // maxLifetime was changed or db was closed.
+ }
+
+ db.mu.Lock()
+
+ d = db.shortestIdleTimeLocked()
+ if db.closed || db.numOpen == 0 || d <= 0 {
+ db.cleanerCh = nil
+ db.mu.Unlock()
+ return
+ }
+
+ d, closing := db.connectionCleanerRunLocked(d)
+ db.mu.Unlock()
+ for _, c := range closing {
+ c.Close()
+ }
+
+ if d < minInterval {
+ d = minInterval
+ }
+
+ if !t.Stop() {
+ select {
+ case <-t.C:
+ default:
+ }
+ }
+ t.Reset(d)
+ }
+}
+
+// connectionCleanerRunLocked removes connections that should be closed from
+// freeConn and returns them along side an updated duration to the next check
+// if a quicker check is required to ensure connections are checked appropriately.
+func (db *DB) connectionCleanerRunLocked(d time.Duration) (time.Duration, []*driverConn) {
+ var idleClosing int64
+ var closing []*driverConn
+ if db.maxIdleTime > 0 {
+ // As freeConn is ordered by returnedAt process
+ // in reverse order to minimise the work needed.
+ idleSince := nowFunc().Add(-db.maxIdleTime)
+ last := len(db.freeConn) - 1
+ for i := last; i >= 0; i-- {
+ c := db.freeConn[i]
+ if c.returnedAt.Before(idleSince) {
+ i++
+ closing = db.freeConn[:i:i]
+ db.freeConn = db.freeConn[i:]
+ idleClosing = int64(len(closing))
+ db.maxIdleTimeClosed += idleClosing
+ break
+ }
+ }
+
+ if len(db.freeConn) > 0 {
+ c := db.freeConn[0]
+ if d2 := c.returnedAt.Sub(idleSince); d2 < d {
+ // Ensure idle connections are cleaned up as soon as
+ // possible.
+ d = d2
+ }
+ }
+ }
+
+ if db.maxLifetime > 0 {
+ expiredSince := nowFunc().Add(-db.maxLifetime)
+ for i := 0; i < len(db.freeConn); i++ {
+ c := db.freeConn[i]
+ if c.createdAt.Before(expiredSince) {
+ closing = append(closing, c)
+
+ last := len(db.freeConn) - 1
+ // Use slow delete as order is required to ensure
+ // connections are reused least idle time first.
+ copy(db.freeConn[i:], db.freeConn[i+1:])
+ db.freeConn[last] = nil
+ db.freeConn = db.freeConn[:last]
+ i--
+ } else if d2 := c.createdAt.Sub(expiredSince); d2 < d {
+ // Prevent connections sitting the freeConn when they
+ // have expired by updating our next deadline d.
+ d = d2
+ }
+ }
+ db.maxLifetimeClosed += int64(len(closing)) - idleClosing
+ }
+
+ return d, closing
+}
+
+// DBStats contains database statistics.
+type DBStats struct {
+ MaxOpenConnections int // Maximum number of open connections to the database.
+
+ // Pool Status
+ OpenConnections int // The number of established connections both in use and idle.
+ InUse int // The number of connections currently in use.
+ Idle int // The number of idle connections.
+
+ // Counters
+ WaitCount int64 // The total number of connections waited for.
+ WaitDuration time.Duration // The total time blocked waiting for a new connection.
+ MaxIdleClosed int64 // The total number of connections closed due to SetMaxIdleConns.
+ MaxIdleTimeClosed int64 // The total number of connections closed due to SetConnMaxIdleTime.
+ MaxLifetimeClosed int64 // The total number of connections closed due to SetConnMaxLifetime.
+}
+
+// Stats returns database statistics.
+func (db *DB) Stats() DBStats {
+ wait := db.waitDuration.Load()
+
+ db.mu.Lock()
+ defer db.mu.Unlock()
+
+ stats := DBStats{
+ MaxOpenConnections: db.maxOpen,
+
+ Idle: len(db.freeConn),
+ OpenConnections: db.numOpen,
+ InUse: db.numOpen - len(db.freeConn),
+
+ WaitCount: db.waitCount,
+ WaitDuration: time.Duration(wait),
+ MaxIdleClosed: db.maxIdleClosed,
+ MaxIdleTimeClosed: db.maxIdleTimeClosed,
+ MaxLifetimeClosed: db.maxLifetimeClosed,
+ }
+ return stats
+}
+
+// Assumes db.mu is locked.
+// If there are connRequests and the connection limit hasn't been reached,
+// then tell the connectionOpener to open new connections.
+func (db *DB) maybeOpenNewConnections() {
+ numRequests := len(db.connRequests)
+ if db.maxOpen > 0 {
+ numCanOpen := db.maxOpen - db.numOpen
+ if numRequests > numCanOpen {
+ numRequests = numCanOpen
+ }
+ }
+ for numRequests > 0 {
+ db.numOpen++ // optimistically
+ numRequests--
+ if db.closed {
+ return
+ }
+ db.openerCh <- struct{}{}
+ }
+}
+
+// Runs in a separate goroutine, opens new connections when requested.
+func (db *DB) connectionOpener(ctx context.Context) {
+ for {
+ select {
+ case <-ctx.Done():
+ return
+ case <-db.openerCh:
+ db.openNewConnection(ctx)
+ }
+ }
+}
+
+// Open one new connection
+func (db *DB) openNewConnection(ctx context.Context) {
+ // maybeOpenNewConnections has already executed db.numOpen++ before it sent
+ // on db.openerCh. This function must execute db.numOpen-- if the
+ // connection fails or is closed before returning.
+ ci, err := db.connector.Connect(ctx)
+ db.mu.Lock()
+ defer db.mu.Unlock()
+ if db.closed {
+ if err == nil {
+ ci.Close()
+ }
+ db.numOpen--
+ return
+ }
+ if err != nil {
+ db.numOpen--
+ db.putConnDBLocked(nil, err)
+ db.maybeOpenNewConnections()
+ return
+ }
+ dc := &driverConn{
+ db: db,
+ createdAt: nowFunc(),
+ returnedAt: nowFunc(),
+ ci: ci,
+ }
+ if db.putConnDBLocked(dc, err) {
+ db.addDepLocked(dc, dc)
+ } else {
+ db.numOpen--
+ ci.Close()
+ }
+}
+
+// connRequest represents one request for a new connection
+// When there are no idle connections available, DB.conn will create
+// a new connRequest and put it on the db.connRequests list.
+type connRequest struct {
+ conn *driverConn
+ err error
+}
+
+var errDBClosed = errors.New("sql: database is closed")
+
+// nextRequestKeyLocked returns the next connection request key.
+// It is assumed that nextRequest will not overflow.
+func (db *DB) nextRequestKeyLocked() uint64 {
+ next := db.nextRequest
+ db.nextRequest++
+ return next
+}
+
+// conn returns a newly-opened or cached *driverConn.
+func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn, error) {
+ db.mu.Lock()
+ if db.closed {
+ db.mu.Unlock()
+ return nil, errDBClosed
+ }
+ // Check if the context is expired.
+ select {
+ default:
+ case <-ctx.Done():
+ db.mu.Unlock()
+ return nil, ctx.Err()
+ }
+ lifetime := db.maxLifetime
+
+ // Prefer a free connection, if possible.
+ last := len(db.freeConn) - 1
+ if strategy == cachedOrNewConn && last >= 0 {
+ // Reuse the lowest idle time connection so we can close
+ // connections which remain idle as soon as possible.
+ conn := db.freeConn[last]
+ db.freeConn = db.freeConn[:last]
+ conn.inUse = true
+ if conn.expired(lifetime) {
+ db.maxLifetimeClosed++
+ db.mu.Unlock()
+ conn.Close()
+ return nil, driver.ErrBadConn
+ }
+ db.mu.Unlock()
+
+ // Reset the session if required.
+ if err := conn.resetSession(ctx); errors.Is(err, driver.ErrBadConn) {
+ conn.Close()
+ return nil, err
+ }
+
+ return conn, nil
+ }
+
+ // Out of free connections or we were asked not to use one. If we're not
+ // allowed to open any more connections, make a request and wait.
+ if db.maxOpen > 0 && db.numOpen >= db.maxOpen {
+ // Make the connRequest channel. It's buffered so that the
+ // connectionOpener doesn't block while waiting for the req to be read.
+ req := make(chan connRequest, 1)
+ reqKey := db.nextRequestKeyLocked()
+ db.connRequests[reqKey] = req
+ db.waitCount++
+ db.mu.Unlock()
+
+ waitStart := nowFunc()
+
+ // Timeout the connection request with the context.
+ select {
+ case <-ctx.Done():
+ // Remove the connection request and ensure no value has been sent
+ // on it after removing.
+ db.mu.Lock()
+ delete(db.connRequests, reqKey)
+ db.mu.Unlock()
+
+ db.waitDuration.Add(int64(time.Since(waitStart)))
+
+ select {
+ default:
+ case ret, ok := <-req:
+ if ok && ret.conn != nil {
+ db.putConn(ret.conn, ret.err, false)
+ }
+ }
+ return nil, ctx.Err()
+ case ret, ok := <-req:
+ db.waitDuration.Add(int64(time.Since(waitStart)))
+
+ if !ok {
+ return nil, errDBClosed
+ }
+ // Only check if the connection is expired if the strategy is cachedOrNewConns.
+ // If we require a new connection, just re-use the connection without looking
+ // at the expiry time. If it is expired, it will be checked when it is placed
+ // back into the connection pool.
+ // This prioritizes giving a valid connection to a client over the exact connection
+ // lifetime, which could expire exactly after this point anyway.
+ if strategy == cachedOrNewConn && ret.err == nil && ret.conn.expired(lifetime) {
+ db.mu.Lock()
+ db.maxLifetimeClosed++
+ db.mu.Unlock()
+ ret.conn.Close()
+ return nil, driver.ErrBadConn
+ }
+ if ret.conn == nil {
+ return nil, ret.err
+ }
+
+ // Reset the session if required.
+ if err := ret.conn.resetSession(ctx); errors.Is(err, driver.ErrBadConn) {
+ ret.conn.Close()
+ return nil, err
+ }
+ return ret.conn, ret.err
+ }
+ }
+
+ db.numOpen++ // optimistically
+ db.mu.Unlock()
+ ci, err := db.connector.Connect(ctx)
+ if err != nil {
+ db.mu.Lock()
+ db.numOpen-- // correct for earlier optimism
+ db.maybeOpenNewConnections()
+ db.mu.Unlock()
+ return nil, err
+ }
+ db.mu.Lock()
+ dc := &driverConn{
+ db: db,
+ createdAt: nowFunc(),
+ returnedAt: nowFunc(),
+ ci: ci,
+ inUse: true,
+ }
+ db.addDepLocked(dc, dc)
+ db.mu.Unlock()
+ return dc, nil
+}
+
+// putConnHook is a hook for testing.
+var putConnHook func(*DB, *driverConn)
+
+// noteUnusedDriverStatement notes that ds is no longer used and should
+// be closed whenever possible (when c is next not in use), unless c is
+// already closed.
+func (db *DB) noteUnusedDriverStatement(c *driverConn, ds *driverStmt) {
+ db.mu.Lock()
+ defer db.mu.Unlock()
+ if c.inUse {
+ c.onPut = append(c.onPut, func() {
+ ds.Close()
+ })
+ } else {
+ c.Lock()
+ fc := c.finalClosed
+ c.Unlock()
+ if !fc {
+ ds.Close()
+ }
+ }
+}
+
+// debugGetPut determines whether getConn & putConn calls' stack traces
+// are returned for more verbose crashes.
+const debugGetPut = false
+
+// putConn adds a connection to the db's free pool.
+// err is optionally the last error that occurred on this connection.
+func (db *DB) putConn(dc *driverConn, err error, resetSession bool) {
+ if !errors.Is(err, driver.ErrBadConn) {
+ if !dc.validateConnection(resetSession) {
+ err = driver.ErrBadConn
+ }
+ }
+ db.mu.Lock()
+ if !dc.inUse {
+ db.mu.Unlock()
+ if debugGetPut {
+ fmt.Printf("putConn(%v) DUPLICATE was: %s\n\nPREVIOUS was: %s", dc, stack(), db.lastPut[dc])
+ }
+ panic("sql: connection returned that was never out")
+ }
+
+ if !errors.Is(err, driver.ErrBadConn) && dc.expired(db.maxLifetime) {
+ db.maxLifetimeClosed++
+ err = driver.ErrBadConn
+ }
+ if debugGetPut {
+ db.lastPut[dc] = stack()
+ }
+ dc.inUse = false
+ dc.returnedAt = nowFunc()
+
+ for _, fn := range dc.onPut {
+ fn()
+ }
+ dc.onPut = nil
+
+ if errors.Is(err, driver.ErrBadConn) {
+ // Don't reuse bad connections.
+ // Since the conn is considered bad and is being discarded, treat it
+ // as closed. Don't decrement the open count here, finalClose will
+ // take care of that.
+ db.maybeOpenNewConnections()
+ db.mu.Unlock()
+ dc.Close()
+ return
+ }
+ if putConnHook != nil {
+ putConnHook(db, dc)
+ }
+ added := db.putConnDBLocked(dc, nil)
+ db.mu.Unlock()
+
+ if !added {
+ dc.Close()
+ return
+ }
+}
+
+// Satisfy a connRequest or put the driverConn in the idle pool and return true
+// or return false.
+// putConnDBLocked will satisfy a connRequest if there is one, or it will
+// return the *driverConn to the freeConn list if err == nil and the idle
+// connection limit will not be exceeded.
+// If err != nil, the value of dc is ignored.
+// If err == nil, then dc must not equal nil.
+// If a connRequest was fulfilled or the *driverConn was placed in the
+// freeConn list, then true is returned, otherwise false is returned.
+func (db *DB) putConnDBLocked(dc *driverConn, err error) bool {
+ if db.closed {
+ return false
+ }
+ if db.maxOpen > 0 && db.numOpen > db.maxOpen {
+ return false
+ }
+ if c := len(db.connRequests); c > 0 {
+ var req chan connRequest
+ var reqKey uint64
+ for reqKey, req = range db.connRequests {
+ break
+ }
+ delete(db.connRequests, reqKey) // Remove from pending requests.
+ if err == nil {
+ dc.inUse = true
+ }
+ req <- connRequest{
+ conn: dc,
+ err: err,
+ }
+ return true
+ } else if err == nil && !db.closed {
+ if db.maxIdleConnsLocked() > len(db.freeConn) {
+ db.freeConn = append(db.freeConn, dc)
+ db.startCleanerLocked()
+ return true
+ }
+ db.maxIdleClosed++
+ }
+ return false
+}
+
+// maxBadConnRetries is the number of maximum retries if the driver returns
+// driver.ErrBadConn to signal a broken connection before forcing a new
+// connection to be opened.
+const maxBadConnRetries = 2
+
+func (db *DB) retry(fn func(strategy connReuseStrategy) error) error {
+ for i := int64(0); i < maxBadConnRetries; i++ {
+ err := fn(cachedOrNewConn)
+ // retry if err is driver.ErrBadConn
+ if err == nil || !errors.Is(err, driver.ErrBadConn) {
+ return err
+ }
+ }
+
+ return fn(alwaysNewConn)
+}
+
+// PrepareContext creates a prepared statement for later queries or executions.
+// Multiple queries or executions may be run concurrently from the
+// returned statement.
+// The caller must call the statement's Close method
+// when the statement is no longer needed.
+//
+// The provided context is used for the preparation of the statement, not for the
+// execution of the statement.
+func (db *DB) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
+ var stmt *Stmt
+ var err error
+
+ err = db.retry(func(strategy connReuseStrategy) error {
+ stmt, err = db.prepare(ctx, query, strategy)
+ return err
+ })
+
+ return stmt, err
+}
+
+// Prepare creates a prepared statement for later queries or executions.
+// Multiple queries or executions may be run concurrently from the
+// returned statement.
+// The caller must call the statement's Close method
+// when the statement is no longer needed.
+//
+// Prepare uses context.Background internally; to specify the context, use
+// PrepareContext.
+func (db *DB) Prepare(query string) (*Stmt, error) {
+ return db.PrepareContext(context.Background(), query)
+}
+
+func (db *DB) prepare(ctx context.Context, query string, strategy connReuseStrategy) (*Stmt, error) {
+ // TODO: check if db.driver supports an optional
+ // driver.Preparer interface and call that instead, if so,
+ // otherwise we make a prepared statement that's bound
+ // to a connection, and to execute this prepared statement
+ // we either need to use this connection (if it's free), else
+ // get a new connection + re-prepare + execute on that one.
+ dc, err := db.conn(ctx, strategy)
+ if err != nil {
+ return nil, err
+ }
+ return db.prepareDC(ctx, dc, dc.releaseConn, nil, query)
+}
+
+// prepareDC prepares a query on the driverConn and calls release before
+// returning. When cg == nil it implies that a connection pool is used, and
+// when cg != nil only a single driver connection is used.
+func (db *DB) prepareDC(ctx context.Context, dc *driverConn, release func(error), cg stmtConnGrabber, query string) (*Stmt, error) {
+ var ds *driverStmt
+ var err error
+ defer func() {
+ release(err)
+ }()
+ withLock(dc, func() {
+ ds, err = dc.prepareLocked(ctx, cg, query)
+ })
+ if err != nil {
+ return nil, err
+ }
+ stmt := &Stmt{
+ db: db,
+ query: query,
+ cg: cg,
+ cgds: ds,
+ }
+
+ // When cg == nil this statement will need to keep track of various
+ // connections they are prepared on and record the stmt dependency on
+ // the DB.
+ if cg == nil {
+ stmt.css = []connStmt{{dc, ds}}
+ stmt.lastNumClosed = db.numClosed.Load()
+ db.addDep(stmt, stmt)
+ }
+ return stmt, nil
+}
+
+// ExecContext executes a query without returning any rows.
+// The args are for any placeholder parameters in the query.
+func (db *DB) ExecContext(ctx context.Context, query string, args ...any) (Result, error) {
+ var res Result
+ var err error
+
+ err = db.retry(func(strategy connReuseStrategy) error {
+ res, err = db.exec(ctx, query, args, strategy)
+ return err
+ })
+
+ return res, err
+}
+
+// Exec executes a query without returning any rows.
+// The args are for any placeholder parameters in the query.
+//
+// Exec uses context.Background internally; to specify the context, use
+// ExecContext.
+func (db *DB) Exec(query string, args ...any) (Result, error) {
+ return db.ExecContext(context.Background(), query, args...)
+}
+
+func (db *DB) exec(ctx context.Context, query string, args []any, strategy connReuseStrategy) (Result, error) {
+ dc, err := db.conn(ctx, strategy)
+ if err != nil {
+ return nil, err
+ }
+ return db.execDC(ctx, dc, dc.releaseConn, query, args)
+}
+
+func (db *DB) execDC(ctx context.Context, dc *driverConn, release func(error), query string, args []any) (res Result, err error) {
+ defer func() {
+ release(err)
+ }()
+ execerCtx, ok := dc.ci.(driver.ExecerContext)
+ var execer driver.Execer
+ if !ok {
+ execer, ok = dc.ci.(driver.Execer)
+ }
+ if ok {
+ var nvdargs []driver.NamedValue
+ var resi driver.Result
+ withLock(dc, func() {
+ nvdargs, err = driverArgsConnLocked(dc.ci, nil, args)
+ if err != nil {
+ return
+ }
+ resi, err = ctxDriverExec(ctx, execerCtx, execer, query, nvdargs)
+ })
+ if err != driver.ErrSkip {
+ if err != nil {
+ return nil, err
+ }
+ return driverResult{dc, resi}, nil
+ }
+ }
+
+ var si driver.Stmt
+ withLock(dc, func() {
+ si, err = ctxDriverPrepare(ctx, dc.ci, query)
+ })
+ if err != nil {
+ return nil, err
+ }
+ ds := &driverStmt{Locker: dc, si: si}
+ defer ds.Close()
+ return resultFromStatement(ctx, dc.ci, ds, args...)
+}
+
+// QueryContext executes a query that returns rows, typically a SELECT.
+// The args are for any placeholder parameters in the query.
+func (db *DB) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error) {
+ var rows *Rows
+ var err error
+
+ err = db.retry(func(strategy connReuseStrategy) error {
+ rows, err = db.query(ctx, query, args, strategy)
+ return err
+ })
+
+ return rows, err
+}
+
+// Query executes a query that returns rows, typically a SELECT.
+// The args are for any placeholder parameters in the query.
+//
+// Query uses context.Background internally; to specify the context, use
+// QueryContext.
+func (db *DB) Query(query string, args ...any) (*Rows, error) {
+ return db.QueryContext(context.Background(), query, args...)
+}
+
+func (db *DB) query(ctx context.Context, query string, args []any, strategy connReuseStrategy) (*Rows, error) {
+ dc, err := db.conn(ctx, strategy)
+ if err != nil {
+ return nil, err
+ }
+
+ return db.queryDC(ctx, nil, dc, dc.releaseConn, query, args)
+}
+
+// queryDC executes a query on the given connection.
+// The connection gets released by the releaseConn function.
+// The ctx context is from a query method and the txctx context is from an
+// optional transaction context.
+func (db *DB) queryDC(ctx, txctx context.Context, dc *driverConn, releaseConn func(error), query string, args []any) (*Rows, error) {
+ queryerCtx, ok := dc.ci.(driver.QueryerContext)
+ var queryer driver.Queryer
+ if !ok {
+ queryer, ok = dc.ci.(driver.Queryer)
+ }
+ if ok {
+ var nvdargs []driver.NamedValue
+ var rowsi driver.Rows
+ var err error
+ withLock(dc, func() {
+ nvdargs, err = driverArgsConnLocked(dc.ci, nil, args)
+ if err != nil {
+ return
+ }
+ rowsi, err = ctxDriverQuery(ctx, queryerCtx, queryer, query, nvdargs)
+ })
+ if err != driver.ErrSkip {
+ if err != nil {
+ releaseConn(err)
+ return nil, err
+ }
+ // Note: ownership of dc passes to the *Rows, to be freed
+ // with releaseConn.
+ rows := &Rows{
+ dc: dc,
+ releaseConn: releaseConn,
+ rowsi: rowsi,
+ }
+ rows.initContextClose(ctx, txctx)
+ return rows, nil
+ }
+ }
+
+ var si driver.Stmt
+ var err error
+ withLock(dc, func() {
+ si, err = ctxDriverPrepare(ctx, dc.ci, query)
+ })
+ if err != nil {
+ releaseConn(err)
+ return nil, err
+ }
+
+ ds := &driverStmt{Locker: dc, si: si}
+ rowsi, err := rowsiFromStatement(ctx, dc.ci, ds, args...)
+ if err != nil {
+ ds.Close()
+ releaseConn(err)
+ return nil, err
+ }
+
+ // Note: ownership of ci passes to the *Rows, to be freed
+ // with releaseConn.
+ rows := &Rows{
+ dc: dc,
+ releaseConn: releaseConn,
+ rowsi: rowsi,
+ closeStmt: ds,
+ }
+ rows.initContextClose(ctx, txctx)
+ return rows, nil
+}
+
+// QueryRowContext executes a query that is expected to return at most one row.
+// QueryRowContext always returns a non-nil value. Errors are deferred until
+// Row's Scan method is called.
+// If the query selects no rows, the *Row's Scan will return ErrNoRows.
+// Otherwise, the *Row's Scan scans the first selected row and discards
+// the rest.
+func (db *DB) QueryRowContext(ctx context.Context, query string, args ...any) *Row {
+ rows, err := db.QueryContext(ctx, query, args...)
+ return &Row{rows: rows, err: err}
+}
+
+// QueryRow executes a query that is expected to return at most one row.
+// QueryRow always returns a non-nil value. Errors are deferred until
+// Row's Scan method is called.
+// If the query selects no rows, the *Row's Scan will return ErrNoRows.
+// Otherwise, the *Row's Scan scans the first selected row and discards
+// the rest.
+//
+// QueryRow uses context.Background internally; to specify the context, use
+// QueryRowContext.
+func (db *DB) QueryRow(query string, args ...any) *Row {
+ return db.QueryRowContext(context.Background(), query, args...)
+}
+
+// BeginTx starts a transaction.
+//
+// The provided context is used until the transaction is committed or rolled back.
+// If the context is canceled, the sql package will roll back
+// the transaction. Tx.Commit will return an error if the context provided to
+// BeginTx is canceled.
+//
+// The provided TxOptions is optional and may be nil if defaults should be used.
+// If a non-default isolation level is used that the driver doesn't support,
+// an error will be returned.
+func (db *DB) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error) {
+ var tx *Tx
+ var err error
+
+ err = db.retry(func(strategy connReuseStrategy) error {
+ tx, err = db.begin(ctx, opts, strategy)
+ return err
+ })
+
+ return tx, err
+}
+
+// Begin starts a transaction. The default isolation level is dependent on
+// the driver.
+//
+// Begin uses context.Background internally; to specify the context, use
+// BeginTx.
+func (db *DB) Begin() (*Tx, error) {
+ return db.BeginTx(context.Background(), nil)
+}
+
+func (db *DB) begin(ctx context.Context, opts *TxOptions, strategy connReuseStrategy) (tx *Tx, err error) {
+ dc, err := db.conn(ctx, strategy)
+ if err != nil {
+ return nil, err
+ }
+ return db.beginDC(ctx, dc, dc.releaseConn, opts)
+}
+
+// beginDC starts a transaction. The provided dc must be valid and ready to use.
+func (db *DB) beginDC(ctx context.Context, dc *driverConn, release func(error), opts *TxOptions) (tx *Tx, err error) {
+ var txi driver.Tx
+ keepConnOnRollback := false
+ withLock(dc, func() {
+ _, hasSessionResetter := dc.ci.(driver.SessionResetter)
+ _, hasConnectionValidator := dc.ci.(driver.Validator)
+ keepConnOnRollback = hasSessionResetter && hasConnectionValidator
+ txi, err = ctxDriverBegin(ctx, opts, dc.ci)
+ })
+ if err != nil {
+ release(err)
+ return nil, err
+ }
+
+ // Schedule the transaction to rollback when the context is canceled.
+ // The cancel function in Tx will be called after done is set to true.
+ ctx, cancel := context.WithCancel(ctx)
+ tx = &Tx{
+ db: db,
+ dc: dc,
+ releaseConn: release,
+ txi: txi,
+ cancel: cancel,
+ keepConnOnRollback: keepConnOnRollback,
+ ctx: ctx,
+ }
+ go tx.awaitDone()
+ return tx, nil
+}
+
+// Driver returns the database's underlying driver.
+func (db *DB) Driver() driver.Driver {
+ return db.connector.Driver()
+}
+
+// ErrConnDone is returned by any operation that is performed on a connection
+// that has already been returned to the connection pool.
+var ErrConnDone = errors.New("sql: connection is already closed")
+
+// Conn returns a single connection by either opening a new connection
+// or returning an existing connection from the connection pool. Conn will
+// block until either a connection is returned or ctx is canceled.
+// Queries run on the same Conn will be run in the same database session.
+//
+// Every Conn must be returned to the database pool after use by
+// calling Conn.Close.
+func (db *DB) Conn(ctx context.Context) (*Conn, error) {
+ var dc *driverConn
+ var err error
+
+ err = db.retry(func(strategy connReuseStrategy) error {
+ dc, err = db.conn(ctx, strategy)
+ return err
+ })
+
+ if err != nil {
+ return nil, err
+ }
+
+ conn := &Conn{
+ db: db,
+ dc: dc,
+ }
+ return conn, nil
+}
+
+type releaseConn func(error)
+
+// Conn represents a single database connection rather than a pool of database
+// connections. Prefer running queries from DB unless there is a specific
+// need for a continuous single database connection.
+//
+// A Conn must call Close to return the connection to the database pool
+// and may do so concurrently with a running query.
+//
+// After a call to Close, all operations on the
+// connection fail with ErrConnDone.
+type Conn struct {
+ db *DB
+
+ // closemu prevents the connection from closing while there
+ // is an active query. It is held for read during queries
+ // and exclusively during close.
+ closemu sync.RWMutex
+
+ // dc is owned until close, at which point
+ // it's returned to the connection pool.
+ dc *driverConn
+
+ // done transitions from false to true exactly once, on close.
+ // Once done, all operations fail with ErrConnDone.
+ done atomic.Bool
+
+ // releaseConn is a cache of c.closemuRUnlockCondReleaseConn
+ // to save allocations in a call to grabConn.
+ releaseConnOnce sync.Once
+ releaseConnCache releaseConn
+}
+
+// grabConn takes a context to implement stmtConnGrabber
+// but the context is not used.
+func (c *Conn) grabConn(context.Context) (*driverConn, releaseConn, error) {
+ if c.done.Load() {
+ return nil, nil, ErrConnDone
+ }
+ c.releaseConnOnce.Do(func() {
+ c.releaseConnCache = c.closemuRUnlockCondReleaseConn
+ })
+ c.closemu.RLock()
+ return c.dc, c.releaseConnCache, nil
+}
+
+// PingContext verifies the connection to the database is still alive.
+func (c *Conn) PingContext(ctx context.Context) error {
+ dc, release, err := c.grabConn(ctx)
+ if err != nil {
+ return err
+ }
+ return c.db.pingDC(ctx, dc, release)
+}
+
+// ExecContext executes a query without returning any rows.
+// The args are for any placeholder parameters in the query.
+func (c *Conn) ExecContext(ctx context.Context, query string, args ...any) (Result, error) {
+ dc, release, err := c.grabConn(ctx)
+ if err != nil {
+ return nil, err
+ }
+ return c.db.execDC(ctx, dc, release, query, args)
+}
+
+// QueryContext executes a query that returns rows, typically a SELECT.
+// The args are for any placeholder parameters in the query.
+func (c *Conn) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error) {
+ dc, release, err := c.grabConn(ctx)
+ if err != nil {
+ return nil, err
+ }
+ return c.db.queryDC(ctx, nil, dc, release, query, args)
+}
+
+// QueryRowContext executes a query that is expected to return at most one row.
+// QueryRowContext always returns a non-nil value. Errors are deferred until
+// Row's Scan method is called.
+// If the query selects no rows, the *Row's Scan will return ErrNoRows.
+// Otherwise, the *Row's Scan scans the first selected row and discards
+// the rest.
+func (c *Conn) QueryRowContext(ctx context.Context, query string, args ...any) *Row {
+ rows, err := c.QueryContext(ctx, query, args...)
+ return &Row{rows: rows, err: err}
+}
+
+// PrepareContext creates a prepared statement for later queries or executions.
+// Multiple queries or executions may be run concurrently from the
+// returned statement.
+// The caller must call the statement's Close method
+// when the statement is no longer needed.
+//
+// The provided context is used for the preparation of the statement, not for the
+// execution of the statement.
+func (c *Conn) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
+ dc, release, err := c.grabConn(ctx)
+ if err != nil {
+ return nil, err
+ }
+ return c.db.prepareDC(ctx, dc, release, c, query)
+}
+
+// Raw executes f exposing the underlying driver connection for the
+// duration of f. The driverConn must not be used outside of f.
+//
+// Once f returns and err is not driver.ErrBadConn, the Conn will continue to be usable
+// until Conn.Close is called.
+func (c *Conn) Raw(f func(driverConn any) error) (err error) {
+ var dc *driverConn
+ var release releaseConn
+
+ // grabConn takes a context to implement stmtConnGrabber, but the context is not used.
+ dc, release, err = c.grabConn(nil)
+ if err != nil {
+ return
+ }
+ fPanic := true
+ dc.Mutex.Lock()
+ defer func() {
+ dc.Mutex.Unlock()
+
+ // If f panics fPanic will remain true.
+ // Ensure an error is passed to release so the connection
+ // may be discarded.
+ if fPanic {
+ err = driver.ErrBadConn
+ }
+ release(err)
+ }()
+ err = f(dc.ci)
+ fPanic = false
+
+ return
+}
+
+// BeginTx starts a transaction.
+//
+// The provided context is used until the transaction is committed or rolled back.
+// If the context is canceled, the sql package will roll back
+// the transaction. Tx.Commit will return an error if the context provided to
+// BeginTx is canceled.
+//
+// The provided TxOptions is optional and may be nil if defaults should be used.
+// If a non-default isolation level is used that the driver doesn't support,
+// an error will be returned.
+func (c *Conn) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error) {
+ dc, release, err := c.grabConn(ctx)
+ if err != nil {
+ return nil, err
+ }
+ return c.db.beginDC(ctx, dc, release, opts)
+}
+
+// closemuRUnlockCondReleaseConn read unlocks closemu
+// as the sql operation is done with the dc.
+func (c *Conn) closemuRUnlockCondReleaseConn(err error) {
+ c.closemu.RUnlock()
+ if errors.Is(err, driver.ErrBadConn) {
+ c.close(err)
+ }
+}
+
+func (c *Conn) txCtx() context.Context {
+ return nil
+}
+
+func (c *Conn) close(err error) error {
+ if !c.done.CompareAndSwap(false, true) {
+ return ErrConnDone
+ }
+
+ // Lock around releasing the driver connection
+ // to ensure all queries have been stopped before doing so.
+ c.closemu.Lock()
+ defer c.closemu.Unlock()
+
+ c.dc.releaseConn(err)
+ c.dc = nil
+ c.db = nil
+ return err
+}
+
+// Close returns the connection to the connection pool.
+// All operations after a Close will return with ErrConnDone.
+// Close is safe to call concurrently with other operations and will
+// block until all other operations finish. It may be useful to first
+// cancel any used context and then call close directly after.
+func (c *Conn) Close() error {
+ return c.close(nil)
+}
+
+// Tx is an in-progress database transaction.
+//
+// A transaction must end with a call to Commit or Rollback.
+//
+// After a call to Commit or Rollback, all operations on the
+// transaction fail with ErrTxDone.
+//
+// The statements prepared for a transaction by calling
+// the transaction's Prepare or Stmt methods are closed
+// by the call to Commit or Rollback.
+type Tx struct {
+ db *DB
+
+ // closemu prevents the transaction from closing while there
+ // is an active query. It is held for read during queries
+ // and exclusively during close.
+ closemu sync.RWMutex
+
+ // dc is owned exclusively until Commit or Rollback, at which point
+ // it's returned with putConn.
+ dc *driverConn
+ txi driver.Tx
+
+ // releaseConn is called once the Tx is closed to release
+ // any held driverConn back to the pool.
+ releaseConn func(error)
+
+ // done transitions from false to true exactly once, on Commit
+ // or Rollback. once done, all operations fail with
+ // ErrTxDone.
+ done atomic.Bool
+
+ // keepConnOnRollback is true if the driver knows
+ // how to reset the connection's session and if need be discard
+ // the connection.
+ keepConnOnRollback bool
+
+ // All Stmts prepared for this transaction. These will be closed after the
+ // transaction has been committed or rolled back.
+ stmts struct {
+ sync.Mutex
+ v []*Stmt
+ }
+
+ // cancel is called after done transitions from 0 to 1.
+ cancel func()
+
+ // ctx lives for the life of the transaction.
+ ctx context.Context
+}
+
+// awaitDone blocks until the context in Tx is canceled and rolls back
+// the transaction if it's not already done.
+func (tx *Tx) awaitDone() {
+ // Wait for either the transaction to be committed or rolled
+ // back, or for the associated context to be closed.
+ <-tx.ctx.Done()
+
+ // Discard and close the connection used to ensure the
+ // transaction is closed and the resources are released. This
+ // rollback does nothing if the transaction has already been
+ // committed or rolled back.
+ // Do not discard the connection if the connection knows
+ // how to reset the session.
+ discardConnection := !tx.keepConnOnRollback
+ tx.rollback(discardConnection)
+}
+
+func (tx *Tx) isDone() bool {
+ return tx.done.Load()
+}
+
+// ErrTxDone is returned by any operation that is performed on a transaction
+// that has already been committed or rolled back.
+var ErrTxDone = errors.New("sql: transaction has already been committed or rolled back")
+
+// close returns the connection to the pool and
+// must only be called by Tx.rollback or Tx.Commit while
+// 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
+}
+
+// hookTxGrabConn specifies an optional hook to be called on
+// a successful call to (*Tx).grabConn. For tests.
+var hookTxGrabConn func()
+
+func (tx *Tx) grabConn(ctx context.Context) (*driverConn, releaseConn, error) {
+ select {
+ default:
+ case <-ctx.Done():
+ return nil, nil, ctx.Err()
+ }
+
+ // closemu.RLock must come before the check for isDone to prevent the Tx from
+ // closing while a query is executing.
+ tx.closemu.RLock()
+ if tx.isDone() {
+ tx.closemu.RUnlock()
+ return nil, nil, ErrTxDone
+ }
+ if hookTxGrabConn != nil { // test hook
+ hookTxGrabConn()
+ }
+ return tx.dc, tx.closemuRUnlockRelease, nil
+}
+
+func (tx *Tx) txCtx() context.Context {
+ return tx.ctx
+}
+
+// closemuRUnlockRelease is used as a func(error) method value in
+// ExecContext and QueryContext. Unlocking in the releaseConn keeps
+// the driver conn from being returned to the connection pool until
+// the Rows has been closed.
+func (tx *Tx) closemuRUnlockRelease(error) {
+ tx.closemu.RUnlock()
+}
+
+// Closes all Stmts prepared for this transaction.
+func (tx *Tx) closePrepared() {
+ tx.stmts.Lock()
+ defer tx.stmts.Unlock()
+ for _, stmt := range tx.stmts.v {
+ stmt.Close()
+ }
+}
+
+// Commit commits the transaction.
+func (tx *Tx) Commit() error {
+ // Check context first to avoid transaction leak.
+ // If put it behind tx.done CompareAndSwap statement, we can't ensure
+ // the consistency between tx.done and the real COMMIT operation.
+ select {
+ default:
+ case <-tx.ctx.Done():
+ if tx.done.Load() {
+ return ErrTxDone
+ }
+ return tx.ctx.Err()
+ }
+ if !tx.done.CompareAndSwap(false, true) {
+ return ErrTxDone
+ }
+
+ // Cancel the Tx to release any active R-closemu locks.
+ // This is safe to do because tx.done has already transitioned
+ // from 0 to 1. Hold the W-closemu lock prior to rollback
+ // to ensure no other connection has an active query.
+ tx.cancel()
+ tx.closemu.Lock()
+ tx.closemu.Unlock()
+
+ var err error
+ withLock(tx.dc, func() {
+ err = tx.txi.Commit()
+ })
+ if !errors.Is(err, driver.ErrBadConn) {
+ tx.closePrepared()
+ }
+ tx.close(err)
+ return err
+}
+
+var rollbackHook func()
+
+// rollback aborts the transaction and optionally forces the pool to discard
+// the connection.
+func (tx *Tx) rollback(discardConn bool) error {
+ if !tx.done.CompareAndSwap(false, true) {
+ return ErrTxDone
+ }
+
+ if rollbackHook != nil {
+ rollbackHook()
+ }
+
+ // Cancel the Tx to release any active R-closemu locks.
+ // This is safe to do because tx.done has already transitioned
+ // from 0 to 1. Hold the W-closemu lock prior to rollback
+ // to ensure no other connection has an active query.
+ tx.cancel()
+ tx.closemu.Lock()
+ tx.closemu.Unlock()
+
+ var err error
+ withLock(tx.dc, func() {
+ err = tx.txi.Rollback()
+ })
+ if !errors.Is(err, driver.ErrBadConn) {
+ tx.closePrepared()
+ }
+ if discardConn {
+ err = driver.ErrBadConn
+ }
+ tx.close(err)
+ return err
+}
+
+// Rollback aborts the transaction.
+func (tx *Tx) Rollback() error {
+ return tx.rollback(false)
+}
+
+// PrepareContext creates a prepared statement for use within a transaction.
+//
+// The returned statement operates within the transaction and will be closed
+// when the transaction has been committed or rolled back.
+//
+// To use an existing prepared statement on this transaction, see Tx.Stmt.
+//
+// The provided context will be used for the preparation of the context, not
+// for the execution of the returned statement. The returned statement
+// will run in the transaction context.
+func (tx *Tx) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
+ dc, release, err := tx.grabConn(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ stmt, err := tx.db.prepareDC(ctx, dc, release, tx, query)
+ if err != nil {
+ return nil, err
+ }
+ tx.stmts.Lock()
+ tx.stmts.v = append(tx.stmts.v, stmt)
+ tx.stmts.Unlock()
+ return stmt, nil
+}
+
+// Prepare creates a prepared statement for use within a transaction.
+//
+// The returned statement operates within the transaction and will be closed
+// when the transaction has been committed or rolled back.
+//
+// To use an existing prepared statement on this transaction, see Tx.Stmt.
+//
+// Prepare uses context.Background internally; to specify the context, use
+// PrepareContext.
+func (tx *Tx) Prepare(query string) (*Stmt, error) {
+ return tx.PrepareContext(context.Background(), query)
+}
+
+// StmtContext returns a transaction-specific prepared statement from
+// an existing statement.
+//
+// Example:
+//
+// updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?")
+// ...
+// tx, err := db.Begin()
+// ...
+// res, err := tx.StmtContext(ctx, updateMoney).Exec(123.45, 98293203)
+//
+// The provided context is used for the preparation of the statement, not for the
+// execution of the statement.
+//
+// The returned statement operates within the transaction and will be closed
+// when the transaction has been committed or rolled back.
+func (tx *Tx) StmtContext(ctx context.Context, stmt *Stmt) *Stmt {
+ dc, release, err := tx.grabConn(ctx)
+ if err != nil {
+ return &Stmt{stickyErr: err}
+ }
+ defer release(nil)
+
+ if tx.db != stmt.db {
+ return &Stmt{stickyErr: errors.New("sql: Tx.Stmt: statement from different database used")}
+ }
+ var si driver.Stmt
+ var parentStmt *Stmt
+ stmt.mu.Lock()
+ if stmt.closed || stmt.cg != nil {
+ // If the statement has been closed or already belongs to a
+ // transaction, we can't reuse it in this connection.
+ // Since tx.StmtContext should never need to be called with a
+ // Stmt already belonging to tx, we ignore this edge case and
+ // re-prepare the statement in this case. No need to add
+ // code-complexity for this.
+ stmt.mu.Unlock()
+ withLock(dc, func() {
+ si, err = ctxDriverPrepare(ctx, dc.ci, stmt.query)
+ })
+ if err != nil {
+ return &Stmt{stickyErr: err}
+ }
+ } else {
+ stmt.removeClosedStmtLocked()
+ // See if the statement has already been prepared on this connection,
+ // and reuse it if possible.
+ for _, v := range stmt.css {
+ if v.dc == dc {
+ si = v.ds.si
+ break
+ }
+ }
+
+ stmt.mu.Unlock()
+
+ if si == nil {
+ var ds *driverStmt
+ withLock(dc, func() {
+ ds, err = stmt.prepareOnConnLocked(ctx, dc)
+ })
+ if err != nil {
+ return &Stmt{stickyErr: err}
+ }
+ si = ds.si
+ }
+ parentStmt = stmt
+ }
+
+ txs := &Stmt{
+ db: tx.db,
+ cg: tx,
+ cgds: &driverStmt{
+ Locker: dc,
+ si: si,
+ },
+ parentStmt: parentStmt,
+ query: stmt.query,
+ }
+ if parentStmt != nil {
+ tx.db.addDep(parentStmt, txs)
+ }
+ tx.stmts.Lock()
+ tx.stmts.v = append(tx.stmts.v, txs)
+ tx.stmts.Unlock()
+ return txs
+}
+
+// Stmt returns a transaction-specific prepared statement from
+// an existing statement.
+//
+// Example:
+//
+// updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?")
+// ...
+// tx, err := db.Begin()
+// ...
+// res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203)
+//
+// The returned statement operates within the transaction and will be closed
+// when the transaction has been committed or rolled back.
+//
+// Stmt uses context.Background internally; to specify the context, use
+// StmtContext.
+func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
+ return tx.StmtContext(context.Background(), stmt)
+}
+
+// ExecContext executes a query that doesn't return rows.
+// For example: an INSERT and UPDATE.
+func (tx *Tx) ExecContext(ctx context.Context, query string, args ...any) (Result, error) {
+ dc, release, err := tx.grabConn(ctx)
+ if err != nil {
+ return nil, err
+ }
+ return tx.db.execDC(ctx, dc, release, query, args)
+}
+
+// Exec executes a query that doesn't return rows.
+// For example: an INSERT and UPDATE.
+//
+// Exec uses context.Background internally; to specify the context, use
+// ExecContext.
+func (tx *Tx) Exec(query string, args ...any) (Result, error) {
+ return tx.ExecContext(context.Background(), query, args...)
+}
+
+// QueryContext executes a query that returns rows, typically a SELECT.
+func (tx *Tx) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error) {
+ dc, release, err := tx.grabConn(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ return tx.db.queryDC(ctx, tx.ctx, dc, release, query, args)
+}
+
+// Query executes a query that returns rows, typically a SELECT.
+//
+// Query uses context.Background internally; to specify the context, use
+// QueryContext.
+func (tx *Tx) Query(query string, args ...any) (*Rows, error) {
+ return tx.QueryContext(context.Background(), query, args...)
+}
+
+// QueryRowContext executes a query that is expected to return at most one row.
+// QueryRowContext always returns a non-nil value. Errors are deferred until
+// Row's Scan method is called.
+// If the query selects no rows, the *Row's Scan will return ErrNoRows.
+// Otherwise, the *Row's Scan scans the first selected row and discards
+// the rest.
+func (tx *Tx) QueryRowContext(ctx context.Context, query string, args ...any) *Row {
+ rows, err := tx.QueryContext(ctx, query, args...)
+ return &Row{rows: rows, err: err}
+}
+
+// QueryRow executes a query that is expected to return at most one row.
+// QueryRow always returns a non-nil value. Errors are deferred until
+// Row's Scan method is called.
+// If the query selects no rows, the *Row's Scan will return ErrNoRows.
+// Otherwise, the *Row's Scan scans the first selected row and discards
+// the rest.
+//
+// QueryRow uses context.Background internally; to specify the context, use
+// QueryRowContext.
+func (tx *Tx) QueryRow(query string, args ...any) *Row {
+ return tx.QueryRowContext(context.Background(), query, args...)
+}
+
+// connStmt is a prepared statement on a particular connection.
+type connStmt struct {
+ dc *driverConn
+ ds *driverStmt
+}
+
+// stmtConnGrabber represents a Tx or Conn that will return the underlying
+// driverConn and release function.
+type stmtConnGrabber interface {
+ // grabConn returns the driverConn and the associated release function
+ // that must be called when the operation completes.
+ grabConn(context.Context) (*driverConn, releaseConn, error)
+
+ // txCtx returns the transaction context if available.
+ // The returned context should be selected on along with
+ // any query context when awaiting a cancel.
+ txCtx() context.Context
+}
+
+var (
+ _ stmtConnGrabber = &Tx{}
+ _ stmtConnGrabber = &Conn{}
+)
+
+// Stmt is a prepared statement.
+// A Stmt is safe for concurrent use by multiple goroutines.
+//
+// If a Stmt is prepared on a Tx or Conn, it will be bound to a single
+// underlying connection forever. If the Tx or Conn closes, the Stmt will
+// become unusable and all operations will return an error.
+// If a Stmt is prepared on a DB, it will remain usable for the lifetime of the
+// DB. When the Stmt needs to execute on a new underlying connection, it will
+// prepare itself on the new connection automatically.
+type Stmt struct {
+ // Immutable:
+ db *DB // where we came from
+ query string // that created the Stmt
+ stickyErr error // if non-nil, this error is returned for all operations
+
+ closemu sync.RWMutex // held exclusively during close, for read otherwise.
+
+ // If Stmt is prepared on a Tx or Conn then cg is present and will
+ // only ever grab a connection from cg.
+ // If cg is nil then the Stmt must grab an arbitrary connection
+ // from db and determine if it must prepare the stmt again by
+ // inspecting css.
+ cg stmtConnGrabber
+ cgds *driverStmt
+
+ // parentStmt is set when a transaction-specific statement
+ // is requested from an identical statement prepared on the same
+ // conn. parentStmt is used to track the dependency of this statement
+ // on its originating ("parent") statement so that parentStmt may
+ // be closed by the user without them having to know whether or not
+ // any transactions are still using it.
+ parentStmt *Stmt
+
+ mu sync.Mutex // protects the rest of the fields
+ closed bool
+
+ // css is a list of underlying driver statement interfaces
+ // that are valid on particular connections. This is only
+ // used if cg == nil and one is found that has idle
+ // connections. If cg != nil, cgds is always used.
+ css []connStmt
+
+ // lastNumClosed is copied from db.numClosed when Stmt is created
+ // without tx and closed connections in css are removed.
+ lastNumClosed uint64
+}
+
+// ExecContext executes a prepared statement with the given arguments and
+// returns a Result summarizing the effect of the statement.
+func (s *Stmt) ExecContext(ctx context.Context, args ...any) (Result, error) {
+ s.closemu.RLock()
+ defer s.closemu.RUnlock()
+
+ var res Result
+ err := s.db.retry(func(strategy connReuseStrategy) error {
+ dc, releaseConn, ds, err := s.connStmt(ctx, strategy)
+ if err != nil {
+ return err
+ }
+
+ res, err = resultFromStatement(ctx, dc.ci, ds, args...)
+ releaseConn(err)
+ return err
+ })
+
+ return res, err
+}
+
+// Exec executes a prepared statement with the given arguments and
+// returns a Result summarizing the effect of the statement.
+//
+// Exec uses context.Background internally; to specify the context, use
+// ExecContext.
+func (s *Stmt) Exec(args ...any) (Result, error) {
+ return s.ExecContext(context.Background(), args...)
+}
+
+func resultFromStatement(ctx context.Context, ci driver.Conn, ds *driverStmt, args ...any) (Result, error) {
+ ds.Lock()
+ defer ds.Unlock()
+
+ dargs, err := driverArgsConnLocked(ci, ds, args)
+ if err != nil {
+ return nil, err
+ }
+
+ resi, err := ctxDriverStmtExec(ctx, ds.si, dargs)
+ if err != nil {
+ return nil, err
+ }
+ return driverResult{ds.Locker, resi}, nil
+}
+
+// removeClosedStmtLocked removes closed conns in s.css.
+//
+// To avoid lock contention on DB.mu, we do it only when
+// s.db.numClosed - s.lastNum is large enough.
+func (s *Stmt) removeClosedStmtLocked() {
+ t := len(s.css)/2 + 1
+ if t > 10 {
+ t = 10
+ }
+ dbClosed := s.db.numClosed.Load()
+ if dbClosed-s.lastNumClosed < uint64(t) {
+ return
+ }
+
+ s.db.mu.Lock()
+ for i := 0; i < len(s.css); i++ {
+ if s.css[i].dc.dbmuClosed {
+ s.css[i] = s.css[len(s.css)-1]
+ s.css = s.css[:len(s.css)-1]
+ i--
+ }
+ }
+ s.db.mu.Unlock()
+ s.lastNumClosed = dbClosed
+}
+
+// connStmt returns a free driver connection on which to execute the
+// statement, a function to call to release the connection, and a
+// statement bound to that connection.
+func (s *Stmt) connStmt(ctx context.Context, strategy connReuseStrategy) (dc *driverConn, releaseConn func(error), ds *driverStmt, err error) {
+ if err = s.stickyErr; err != nil {
+ return
+ }
+ s.mu.Lock()
+ if s.closed {
+ s.mu.Unlock()
+ err = errors.New("sql: statement is closed")
+ return
+ }
+
+ // In a transaction or connection, we always use the connection that the
+ // stmt was created on.
+ if s.cg != nil {
+ s.mu.Unlock()
+ dc, releaseConn, err = s.cg.grabConn(ctx) // blocks, waiting for the connection.
+ if err != nil {
+ return
+ }
+ return dc, releaseConn, s.cgds, nil
+ }
+
+ s.removeClosedStmtLocked()
+ s.mu.Unlock()
+
+ dc, err = s.db.conn(ctx, strategy)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+
+ s.mu.Lock()
+ for _, v := range s.css {
+ if v.dc == dc {
+ s.mu.Unlock()
+ return dc, dc.releaseConn, v.ds, nil
+ }
+ }
+ s.mu.Unlock()
+
+ // No luck; we need to prepare the statement on this connection
+ withLock(dc, func() {
+ ds, err = s.prepareOnConnLocked(ctx, dc)
+ })
+ if err != nil {
+ dc.releaseConn(err)
+ return nil, nil, nil, err
+ }
+
+ return dc, dc.releaseConn, ds, nil
+}
+
+// prepareOnConnLocked prepares the query in Stmt s on dc and adds it to the list of
+// open connStmt on the statement. It assumes the caller is holding the lock on dc.
+func (s *Stmt) prepareOnConnLocked(ctx context.Context, dc *driverConn) (*driverStmt, error) {
+ si, err := dc.prepareLocked(ctx, s.cg, s.query)
+ if err != nil {
+ return nil, err
+ }
+ cs := connStmt{dc, si}
+ s.mu.Lock()
+ s.css = append(s.css, cs)
+ s.mu.Unlock()
+ return cs.ds, nil
+}
+
+// QueryContext executes a prepared query statement with the given arguments
+// and returns the query results as a *Rows.
+func (s *Stmt) QueryContext(ctx context.Context, args ...any) (*Rows, error) {
+ s.closemu.RLock()
+ defer s.closemu.RUnlock()
+
+ var rowsi driver.Rows
+ var rows *Rows
+
+ err := s.db.retry(func(strategy connReuseStrategy) error {
+ dc, releaseConn, ds, err := s.connStmt(ctx, strategy)
+ if err != nil {
+ return err
+ }
+
+ rowsi, err = rowsiFromStatement(ctx, dc.ci, ds, args...)
+ if err == nil {
+ // Note: ownership of ci passes to the *Rows, to be freed
+ // with releaseConn.
+ rows = &Rows{
+ dc: dc,
+ rowsi: rowsi,
+ // releaseConn set below
+ }
+ // addDep must be added before initContextClose or it could attempt
+ // to removeDep before it has been added.
+ s.db.addDep(s, rows)
+
+ // releaseConn must be set before initContextClose or it could
+ // release the connection before it is set.
+ rows.releaseConn = func(err error) {
+ releaseConn(err)
+ s.db.removeDep(s, rows)
+ }
+ var txctx context.Context
+ if s.cg != nil {
+ txctx = s.cg.txCtx()
+ }
+ rows.initContextClose(ctx, txctx)
+ return nil
+ }
+
+ releaseConn(err)
+ return err
+ })
+
+ return rows, err
+}
+
+// Query executes a prepared query statement with the given arguments
+// and returns the query results as a *Rows.
+//
+// Query uses context.Background internally; to specify the context, use
+// QueryContext.
+func (s *Stmt) Query(args ...any) (*Rows, error) {
+ return s.QueryContext(context.Background(), args...)
+}
+
+func rowsiFromStatement(ctx context.Context, ci driver.Conn, ds *driverStmt, args ...any) (driver.Rows, error) {
+ ds.Lock()
+ defer ds.Unlock()
+ dargs, err := driverArgsConnLocked(ci, ds, args)
+ if err != nil {
+ return nil, err
+ }
+ return ctxDriverStmtQuery(ctx, ds.si, dargs)
+}
+
+// QueryRowContext executes a prepared query statement with the given arguments.
+// If an error occurs during the execution of the statement, that error will
+// be returned by a call to Scan on the returned *Row, which is always non-nil.
+// If the query selects no rows, the *Row's Scan will return ErrNoRows.
+// Otherwise, the *Row's Scan scans the first selected row and discards
+// the rest.
+func (s *Stmt) QueryRowContext(ctx context.Context, args ...any) *Row {
+ rows, err := s.QueryContext(ctx, args...)
+ if err != nil {
+ return &Row{err: err}
+ }
+ return &Row{rows: rows}
+}
+
+// QueryRow executes a prepared query statement with the given arguments.
+// If an error occurs during the execution of the statement, that error will
+// be returned by a call to Scan on the returned *Row, which is always non-nil.
+// If the query selects no rows, the *Row's Scan will return ErrNoRows.
+// Otherwise, the *Row's Scan scans the first selected row and discards
+// the rest.
+//
+// Example usage:
+//
+// var name string
+// err := nameByUseridStmt.QueryRow(id).Scan(&name)
+//
+// QueryRow uses context.Background internally; to specify the context, use
+// QueryRowContext.
+func (s *Stmt) QueryRow(args ...any) *Row {
+ return s.QueryRowContext(context.Background(), args...)
+}
+
+// Close closes the statement.
+func (s *Stmt) Close() error {
+ s.closemu.Lock()
+ defer s.closemu.Unlock()
+
+ if s.stickyErr != nil {
+ return s.stickyErr
+ }
+ s.mu.Lock()
+ if s.closed {
+ s.mu.Unlock()
+ return nil
+ }
+ s.closed = true
+ txds := s.cgds
+ s.cgds = nil
+
+ s.mu.Unlock()
+
+ if s.cg == nil {
+ return s.db.removeDep(s, s)
+ }
+
+ if s.parentStmt != nil {
+ // If parentStmt is set, we must not close s.txds since it's stored
+ // in the css array of the parentStmt.
+ return s.db.removeDep(s.parentStmt, s)
+ }
+ return txds.Close()
+}
+
+func (s *Stmt) finalClose() error {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if s.css != nil {
+ for _, v := range s.css {
+ s.db.noteUnusedDriverStatement(v.dc, v.ds)
+ v.dc.removeOpenStmt(v.ds)
+ }
+ s.css = nil
+ }
+ return nil
+}
+
+// Rows is the result of a query. Its cursor starts before the first row
+// of the result set. Use Next to advance from row to row.
+type Rows struct {
+ dc *driverConn // owned; must call releaseConn when closed to release
+ releaseConn func(error)
+ rowsi driver.Rows
+ cancel func() // called when Rows is closed, may be nil.
+ closeStmt *driverStmt // if non-nil, statement to Close on close
+
+ contextDone atomic.Pointer[error] // error that awaitDone saw; set before close attempt
+
+ // closemu prevents Rows from closing while there
+ // is an active streaming result. It is held for read during non-close operations
+ // and exclusively during close.
+ //
+ // closemu guards lasterr and closed.
+ closemu sync.RWMutex
+ closed bool
+ lasterr error // non-nil only if closed is true
+
+ // lastcols is only used in Scan, Next, and NextResultSet which are expected
+ // not to be called concurrently.
+ lastcols []driver.Value
+
+ // closemuScanHold is whether the previous call to Scan kept closemu RLock'ed
+ // without unlocking it. It does that when the user passes a *RawBytes scan
+ // target. In that case, we need to prevent awaitDone from closing the Rows
+ // while the user's still using the memory. See go.dev/issue/60304.
+ //
+ // It is only used by Scan, Next, and NextResultSet which are expected
+ // not to be called concurrently.
+ closemuScanHold bool
+
+ // hitEOF is whether Next hit the end of the rows without
+ // encountering an error. It's set in Next before
+ // returning. It's only used by Next and Err which are
+ // expected not to be called concurrently.
+ hitEOF bool
+}
+
+// lasterrOrErrLocked returns either lasterr or the provided err.
+// rs.closemu must be read-locked.
+func (rs *Rows) lasterrOrErrLocked(err error) error {
+ if rs.lasterr != nil && rs.lasterr != io.EOF {
+ return rs.lasterr
+ }
+ return err
+}
+
+// bypassRowsAwaitDone is only used for testing.
+// If true, it will not close the Rows automatically from the context.
+var bypassRowsAwaitDone = false
+
+func (rs *Rows) initContextClose(ctx, txctx context.Context) {
+ if ctx.Done() == nil && (txctx == nil || txctx.Done() == nil) {
+ return
+ }
+ if bypassRowsAwaitDone {
+ return
+ }
+ closectx, cancel := context.WithCancel(ctx)
+ rs.cancel = cancel
+ go rs.awaitDone(ctx, txctx, closectx)
+}
+
+// awaitDone blocks until ctx, txctx, or closectx is canceled.
+// The ctx is provided from the query context.
+// If the query was issued in a transaction, the transaction's context
+// is also provided in txctx, to ensure Rows is closed if the Tx is closed.
+// The closectx is closed by an explicit call to rs.Close.
+func (rs *Rows) awaitDone(ctx, txctx, closectx context.Context) {
+ var txctxDone <-chan struct{}
+ if txctx != nil {
+ txctxDone = txctx.Done()
+ }
+ select {
+ case <-ctx.Done():
+ err := ctx.Err()
+ rs.contextDone.Store(&err)
+ case <-txctxDone:
+ err := txctx.Err()
+ rs.contextDone.Store(&err)
+ case <-closectx.Done():
+ // rs.cancel was called via Close(); don't store this into contextDone
+ // to ensure Err() is unaffected.
+ }
+ rs.close(ctx.Err())
+}
+
+// Next prepares the next result row for reading with the Scan method. It
+// returns true on success, or false if there is no next result row or an error
+// happened while preparing it. Err should be consulted to distinguish between
+// the two cases.
+//
+// Every call to Scan, even the first one, must be preceded by a call to Next.
+func (rs *Rows) Next() bool {
+ // If the user's calling Next, they're done with their previous row's Scan
+ // results (any RawBytes memory), so we can release the read lock that would
+ // be preventing awaitDone from calling close.
+ rs.closemuRUnlockIfHeldByScan()
+
+ if rs.contextDone.Load() != nil {
+ return false
+ }
+
+ var doClose, ok bool
+ withLock(rs.closemu.RLocker(), func() {
+ doClose, ok = rs.nextLocked()
+ })
+ if doClose {
+ rs.Close()
+ }
+ if doClose && !ok {
+ rs.hitEOF = true
+ }
+ return ok
+}
+
+func (rs *Rows) nextLocked() (doClose, ok bool) {
+ if rs.closed {
+ return false, false
+ }
+
+ // Lock the driver connection before calling the driver interface
+ // rowsi to prevent a Tx from rolling back the connection at the same time.
+ rs.dc.Lock()
+ defer rs.dc.Unlock()
+
+ if rs.lastcols == nil {
+ rs.lastcols = make([]driver.Value, len(rs.rowsi.Columns()))
+ }
+
+ rs.lasterr = rs.rowsi.Next(rs.lastcols)
+ if rs.lasterr != nil {
+ // Close the connection if there is a driver error.
+ if rs.lasterr != io.EOF {
+ return true, false
+ }
+ nextResultSet, ok := rs.rowsi.(driver.RowsNextResultSet)
+ if !ok {
+ return true, false
+ }
+ // The driver is at the end of the current result set.
+ // Test to see if there is another result set after the current one.
+ // Only close Rows if there is no further result sets to read.
+ if !nextResultSet.HasNextResultSet() {
+ doClose = true
+ }
+ return doClose, false
+ }
+ return false, true
+}
+
+// NextResultSet prepares the next result set for reading. It reports whether
+// there is further result sets, or false if there is no further result set
+// or if there is an error advancing to it. The Err method should be consulted
+// to distinguish between the two cases.
+//
+// After calling NextResultSet, the Next method should always be called before
+// scanning. If there are further result sets they may not have rows in the result
+// set.
+func (rs *Rows) NextResultSet() bool {
+ // If the user's calling NextResultSet, they're done with their previous
+ // row's Scan results (any RawBytes memory), so we can release the read lock
+ // that would be preventing awaitDone from calling close.
+ rs.closemuRUnlockIfHeldByScan()
+
+ var doClose bool
+ defer func() {
+ if doClose {
+ rs.Close()
+ }
+ }()
+ rs.closemu.RLock()
+ defer rs.closemu.RUnlock()
+
+ if rs.closed {
+ return false
+ }
+
+ rs.lastcols = nil
+ nextResultSet, ok := rs.rowsi.(driver.RowsNextResultSet)
+ if !ok {
+ doClose = true
+ return false
+ }
+
+ // Lock the driver connection before calling the driver interface
+ // rowsi to prevent a Tx from rolling back the connection at the same time.
+ rs.dc.Lock()
+ defer rs.dc.Unlock()
+
+ rs.lasterr = nextResultSet.NextResultSet()
+ if rs.lasterr != nil {
+ doClose = true
+ return false
+ }
+ return true
+}
+
+// Err returns the error, if any, that was encountered during iteration.
+// Err may be called after an explicit or implicit Close.
+func (rs *Rows) Err() error {
+ // Return any context error that might've happened during row iteration,
+ // but only if we haven't reported the final Next() = false after rows
+ // are done, in which case the user might've canceled their own context
+ // before calling Rows.Err.
+ if !rs.hitEOF {
+ if errp := rs.contextDone.Load(); errp != nil {
+ return *errp
+ }
+ }
+
+ rs.closemu.RLock()
+ defer rs.closemu.RUnlock()
+ return rs.lasterrOrErrLocked(nil)
+}
+
+var errRowsClosed = errors.New("sql: Rows are closed")
+var errNoRows = errors.New("sql: no Rows available")
+
+// Columns returns the column names.
+// Columns returns an error if the rows are closed.
+func (rs *Rows) Columns() ([]string, error) {
+ rs.closemu.RLock()
+ defer rs.closemu.RUnlock()
+ if rs.closed {
+ return nil, rs.lasterrOrErrLocked(errRowsClosed)
+ }
+ if rs.rowsi == nil {
+ return nil, rs.lasterrOrErrLocked(errNoRows)
+ }
+ rs.dc.Lock()
+ defer rs.dc.Unlock()
+
+ return rs.rowsi.Columns(), nil
+}
+
+// ColumnTypes returns column information such as column type, length,
+// and nullable. Some information may not be available from some drivers.
+func (rs *Rows) ColumnTypes() ([]*ColumnType, error) {
+ rs.closemu.RLock()
+ defer rs.closemu.RUnlock()
+ if rs.closed {
+ return nil, rs.lasterrOrErrLocked(errRowsClosed)
+ }
+ if rs.rowsi == nil {
+ return nil, rs.lasterrOrErrLocked(errNoRows)
+ }
+ rs.dc.Lock()
+ defer rs.dc.Unlock()
+
+ return rowsColumnInfoSetupConnLocked(rs.rowsi), nil
+}
+
+// ColumnType contains the name and type of a column.
+type ColumnType struct {
+ name string
+
+ hasNullable bool
+ hasLength bool
+ hasPrecisionScale bool
+
+ nullable bool
+ length int64
+ databaseType string
+ precision int64
+ scale int64
+ scanType reflect.Type
+}
+
+// Name returns the name or alias of the column.
+func (ci *ColumnType) Name() string {
+ return ci.name
+}
+
+// Length returns the column type length for variable length column types such
+// as text and binary field types. If the type length is unbounded the value will
+// be math.MaxInt64 (any database limits will still apply).
+// If the column type is not variable length, such as an int, or if not supported
+// by the driver ok is false.
+func (ci *ColumnType) Length() (length int64, ok bool) {
+ return ci.length, ci.hasLength
+}
+
+// DecimalSize returns the scale and precision of a decimal type.
+// If not applicable or if not supported ok is false.
+func (ci *ColumnType) DecimalSize() (precision, scale int64, ok bool) {
+ return ci.precision, ci.scale, ci.hasPrecisionScale
+}
+
+// ScanType returns a Go type suitable for scanning into using Rows.Scan.
+// If a driver does not support this property ScanType will return
+// the type of an empty interface.
+func (ci *ColumnType) ScanType() reflect.Type {
+ return ci.scanType
+}
+
+// Nullable reports whether the column may be null.
+// If a driver does not support this property ok will be false.
+func (ci *ColumnType) Nullable() (nullable, ok bool) {
+ return ci.nullable, ci.hasNullable
+}
+
+// DatabaseTypeName returns the database system name of the column type. If an empty
+// string is returned, then the driver type name is not supported.
+// Consult your driver documentation for a list of driver data types. Length specifiers
+// are not included.
+// Common type names include "VARCHAR", "TEXT", "NVARCHAR", "DECIMAL", "BOOL",
+// "INT", and "BIGINT".
+func (ci *ColumnType) DatabaseTypeName() string {
+ return ci.databaseType
+}
+
+func rowsColumnInfoSetupConnLocked(rowsi driver.Rows) []*ColumnType {
+ names := rowsi.Columns()
+
+ list := make([]*ColumnType, len(names))
+ for i := range list {
+ ci := &ColumnType{
+ name: names[i],
+ }
+ list[i] = ci
+
+ if prop, ok := rowsi.(driver.RowsColumnTypeScanType); ok {
+ ci.scanType = prop.ColumnTypeScanType(i)
+ } else {
+ ci.scanType = reflect.TypeOf(new(any)).Elem()
+ }
+ if prop, ok := rowsi.(driver.RowsColumnTypeDatabaseTypeName); ok {
+ ci.databaseType = prop.ColumnTypeDatabaseTypeName(i)
+ }
+ if prop, ok := rowsi.(driver.RowsColumnTypeLength); ok {
+ ci.length, ci.hasLength = prop.ColumnTypeLength(i)
+ }
+ if prop, ok := rowsi.(driver.RowsColumnTypeNullable); ok {
+ ci.nullable, ci.hasNullable = prop.ColumnTypeNullable(i)
+ }
+ if prop, ok := rowsi.(driver.RowsColumnTypePrecisionScale); ok {
+ ci.precision, ci.scale, ci.hasPrecisionScale = prop.ColumnTypePrecisionScale(i)
+ }
+ }
+ return list
+}
+
+// Scan copies the columns in the current row into the values pointed
+// at by dest. The number of values in dest must be the same as the
+// number of columns in Rows.
+//
+// Scan converts columns read from the database into the following
+// common Go types and special types provided by the sql package:
+//
+// *string
+// *[]byte
+// *int, *int8, *int16, *int32, *int64
+// *uint, *uint8, *uint16, *uint32, *uint64
+// *bool
+// *float32, *float64
+// *interface{}
+// *RawBytes
+// *Rows (cursor value)
+// any type implementing Scanner (see Scanner docs)
+//
+// In the most simple case, if the type of the value from the source
+// column is an integer, bool or string type T and dest is of type *T,
+// Scan simply assigns the value through the pointer.
+//
+// Scan also converts between string and numeric types, as long as no
+// information would be lost. While Scan stringifies all numbers
+// scanned from numeric database columns into *string, scans into
+// numeric types are checked for overflow. For example, a float64 with
+// value 300 or a string with value "300" can scan into a uint16, but
+// not into a uint8, though float64(255) or "255" can scan into a
+// uint8. One exception is that scans of some float64 numbers to
+// strings may lose information when stringifying. In general, scan
+// floating point columns into *float64.
+//
+// If a dest argument has type *[]byte, Scan saves in that argument a
+// copy of the corresponding data. The copy is owned by the caller and
+// can be modified and held indefinitely. The copy can be avoided by
+// using an argument of type *RawBytes instead; see the documentation
+// for RawBytes for restrictions on its use.
+//
+// If an argument has type *interface{}, Scan copies the value
+// provided by the underlying driver without conversion. When scanning
+// from a source value of type []byte to *interface{}, a copy of the
+// slice is made and the caller owns the result.
+//
+// Source values of type time.Time may be scanned into values of type
+// *time.Time, *interface{}, *string, or *[]byte. When converting to
+// the latter two, time.RFC3339Nano is used.
+//
+// Source values of type bool may be scanned into types *bool,
+// *interface{}, *string, *[]byte, or *RawBytes.
+//
+// For scanning into *bool, the source may be true, false, 1, 0, or
+// string inputs parseable by strconv.ParseBool.
+//
+// Scan can also convert a cursor returned from a query, such as
+// "select cursor(select * from my_table) from dual", into a
+// *Rows value that can itself be scanned from. The parent
+// select query will close any cursor *Rows if the parent *Rows is closed.
+//
+// If any of the first arguments implementing Scanner returns an error,
+// that error will be wrapped in the returned error.
+func (rs *Rows) Scan(dest ...any) error {
+ if rs.closemuScanHold {
+ // This should only be possible if the user calls Scan twice in a row
+ // without calling Next.
+ return fmt.Errorf("sql: Scan called without calling Next (closemuScanHold)")
+ }
+ rs.closemu.RLock()
+
+ if rs.lasterr != nil && rs.lasterr != io.EOF {
+ rs.closemu.RUnlock()
+ return rs.lasterr
+ }
+ if rs.closed {
+ err := rs.lasterrOrErrLocked(errRowsClosed)
+ rs.closemu.RUnlock()
+ return err
+ }
+
+ if scanArgsContainRawBytes(dest) {
+ rs.closemuScanHold = true
+ } else {
+ rs.closemu.RUnlock()
+ }
+
+ if rs.lastcols == nil {
+ rs.closemuRUnlockIfHeldByScan()
+ return errors.New("sql: Scan called without calling Next")
+ }
+ if len(dest) != len(rs.lastcols) {
+ rs.closemuRUnlockIfHeldByScan()
+ return fmt.Errorf("sql: expected %d destination arguments in Scan, not %d", len(rs.lastcols), len(dest))
+ }
+
+ for i, sv := range rs.lastcols {
+ err := convertAssignRows(dest[i], sv, rs)
+ if err != nil {
+ rs.closemuRUnlockIfHeldByScan()
+ return fmt.Errorf(`sql: Scan error on column index %d, name %q: %w`, i, rs.rowsi.Columns()[i], err)
+ }
+ }
+ return nil
+}
+
+// closemuRUnlockIfHeldByScan releases any closemu.RLock held open by a previous
+// call to Scan with *RawBytes.
+func (rs *Rows) closemuRUnlockIfHeldByScan() {
+ if rs.closemuScanHold {
+ rs.closemuScanHold = false
+ rs.closemu.RUnlock()
+ }
+}
+
+func scanArgsContainRawBytes(args []any) bool {
+ for _, a := range args {
+ if _, ok := a.(*RawBytes); ok {
+ return true
+ }
+ }
+ return false
+}
+
+// rowsCloseHook returns a function so tests may install the
+// hook through a test only mutex.
+var rowsCloseHook = func() func(*Rows, *error) { return nil }
+
+// Close closes the Rows, preventing further enumeration. If Next is called
+// and returns false and there are no further result sets,
+// the Rows are closed automatically and it will suffice to check the
+// result of Err. Close is idempotent and does not affect the result of Err.
+func (rs *Rows) Close() error {
+ // If the user's calling Close, they're done with their previous row's Scan
+ // results (any RawBytes memory), so we can release the read lock that would
+ // be preventing awaitDone from calling the unexported close before we do so.
+ rs.closemuRUnlockIfHeldByScan()
+
+ return rs.close(nil)
+}
+
+func (rs *Rows) close(err error) error {
+ rs.closemu.Lock()
+ defer rs.closemu.Unlock()
+
+ if rs.closed {
+ return nil
+ }
+ rs.closed = true
+
+ if rs.lasterr == nil {
+ rs.lasterr = err
+ }
+
+ withLock(rs.dc, func() {
+ err = rs.rowsi.Close()
+ })
+ if fn := rowsCloseHook(); fn != nil {
+ fn(rs, &err)
+ }
+ if rs.cancel != nil {
+ rs.cancel()
+ }
+
+ if rs.closeStmt != nil {
+ rs.closeStmt.Close()
+ }
+ rs.releaseConn(err)
+
+ rs.lasterr = rs.lasterrOrErrLocked(err)
+ return err
+}
+
+// Row is the result of calling QueryRow to select a single row.
+type Row struct {
+ // One of these two will be non-nil:
+ err error // deferred error for easy chaining
+ rows *Rows
+}
+
+// Scan copies the columns from the matched row into the values
+// pointed at by dest. See the documentation on Rows.Scan for details.
+// If more than one row matches the query,
+// Scan uses the first row and discards the rest. If no row matches
+// the query, Scan returns ErrNoRows.
+func (r *Row) Scan(dest ...any) error {
+ if r.err != nil {
+ return r.err
+ }
+
+ // TODO(bradfitz): for now we need to defensively clone all
+ // []byte that the driver returned (not permitting
+ // *RawBytes in Rows.Scan), since we're about to close
+ // the Rows in our defer, when we return from this function.
+ // the contract with the driver.Next(...) interface is that it
+ // can return slices into read-only temporary memory that's
+ // only valid until the next Scan/Close. But the TODO is that
+ // for a lot of drivers, this copy will be unnecessary. We
+ // should provide an optional interface for drivers to
+ // implement to say, "don't worry, the []bytes that I return
+ // from Next will not be modified again." (for instance, if
+ // they were obtained from the network anyway) But for now we
+ // don't care.
+ defer r.rows.Close()
+ for _, dp := range dest {
+ if _, ok := dp.(*RawBytes); ok {
+ return errors.New("sql: RawBytes isn't allowed on Row.Scan")
+ }
+ }
+
+ if !r.rows.Next() {
+ if err := r.rows.Err(); err != nil {
+ return err
+ }
+ return ErrNoRows
+ }
+ err := r.rows.Scan(dest...)
+ if err != nil {
+ return err
+ }
+ // Make sure the query can be processed to completion with no errors.
+ return r.rows.Close()
+}
+
+// Err provides a way for wrapping packages to check for
+// query errors without calling Scan.
+// Err returns the error, if any, that was encountered while running the query.
+// If this error is not nil, this error will also be returned from Scan.
+func (r *Row) Err() error {
+ return r.err
+}
+
+// A Result summarizes an executed SQL command.
+type Result interface {
+ // LastInsertId returns the integer generated by the database
+ // in response to a command. Typically this will be from an
+ // "auto increment" column when inserting a new row. Not all
+ // databases support this feature, and the syntax of such
+ // statements varies.
+ LastInsertId() (int64, error)
+
+ // RowsAffected returns the number of rows affected by an
+ // update, insert, or delete. Not every database or database
+ // driver may support this.
+ RowsAffected() (int64, error)
+}
+
+type driverResult struct {
+ sync.Locker // the *driverConn
+ resi driver.Result
+}
+
+func (dr driverResult) LastInsertId() (int64, error) {
+ dr.Lock()
+ defer dr.Unlock()
+ return dr.resi.LastInsertId()
+}
+
+func (dr driverResult) RowsAffected() (int64, error) {
+ dr.Lock()
+ defer dr.Unlock()
+ return dr.resi.RowsAffected()
+}
+
+func stack() string {
+ var buf [2 << 10]byte
+ return string(buf[:runtime.Stack(buf[:], false)])
+}
+
+// withLock runs while holding lk.
+func withLock(lk sync.Locker, fn func()) {
+ lk.Lock()
+ defer lk.Unlock() // in case fn panics
+ fn()
+}
diff --git a/contrib/go/_std_1.21/src/database/sql/ya.make b/contrib/go/_std_1.21/src/database/sql/ya.make
new file mode 100644
index 0000000000..1287f3aafa
--- /dev/null
+++ b/contrib/go/_std_1.21/src/database/sql/ya.make
@@ -0,0 +1,25 @@
+GO_LIBRARY()
+
+SRCS(
+ convert.go
+ ctxutil.go
+ sql.go
+)
+
+GO_TEST_SRCS(
+ convert_test.go
+ fakedb_test.go
+ sql_test.go
+)
+
+GO_XTEST_SRCS(
+ example_cli_test.go
+ example_service_test.go
+ example_test.go
+)
+
+END()
+
+RECURSE(
+ driver
+)
diff --git a/contrib/go/_std_1.20/src/debug/dwarf/attr_string.go b/contrib/go/_std_1.21/src/debug/dwarf/attr_string.go
index 8a4fff85a4..8a4fff85a4 100644
--- a/contrib/go/_std_1.20/src/debug/dwarf/attr_string.go
+++ b/contrib/go/_std_1.21/src/debug/dwarf/attr_string.go
diff --git a/contrib/go/_std_1.20/src/debug/dwarf/buf.go b/contrib/go/_std_1.21/src/debug/dwarf/buf.go
index 7ac53efcb6..7ac53efcb6 100644
--- a/contrib/go/_std_1.20/src/debug/dwarf/buf.go
+++ b/contrib/go/_std_1.21/src/debug/dwarf/buf.go
diff --git a/contrib/go/_std_1.21/src/debug/dwarf/class_string.go b/contrib/go/_std_1.21/src/debug/dwarf/class_string.go
new file mode 100644
index 0000000000..163bed712a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/debug/dwarf/class_string.go
@@ -0,0 +1,42 @@
+// Code generated by "stringer -type=Class"; DO NOT EDIT.
+
+package dwarf
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[ClassUnknown-0]
+ _ = x[ClassAddress-1]
+ _ = x[ClassBlock-2]
+ _ = x[ClassConstant-3]
+ _ = x[ClassExprLoc-4]
+ _ = x[ClassFlag-5]
+ _ = x[ClassLinePtr-6]
+ _ = x[ClassLocListPtr-7]
+ _ = x[ClassMacPtr-8]
+ _ = x[ClassRangeListPtr-9]
+ _ = x[ClassReference-10]
+ _ = x[ClassReferenceSig-11]
+ _ = x[ClassString-12]
+ _ = x[ClassReferenceAlt-13]
+ _ = x[ClassStringAlt-14]
+ _ = x[ClassAddrPtr-15]
+ _ = x[ClassLocList-16]
+ _ = x[ClassRngList-17]
+ _ = x[ClassRngListsPtr-18]
+ _ = x[ClassStrOffsetsPtr-19]
+}
+
+const _Class_name = "ClassUnknownClassAddressClassBlockClassConstantClassExprLocClassFlagClassLinePtrClassLocListPtrClassMacPtrClassRangeListPtrClassReferenceClassReferenceSigClassStringClassReferenceAltClassStringAltClassAddrPtrClassLocListClassRngListClassRngListsPtrClassStrOffsetsPtr"
+
+var _Class_index = [...]uint16{0, 12, 24, 34, 47, 59, 68, 80, 95, 106, 123, 137, 154, 165, 182, 196, 208, 220, 232, 248, 266}
+
+func (i Class) String() string {
+ if i < 0 || i >= Class(len(_Class_index)-1) {
+ return "Class(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _Class_name[_Class_index[i]:_Class_index[i+1]]
+}
diff --git a/contrib/go/_std_1.20/src/debug/dwarf/const.go b/contrib/go/_std_1.21/src/debug/dwarf/const.go
index c0a74b08bb..c0a74b08bb 100644
--- a/contrib/go/_std_1.20/src/debug/dwarf/const.go
+++ b/contrib/go/_std_1.21/src/debug/dwarf/const.go
diff --git a/contrib/go/_std_1.21/src/debug/dwarf/entry.go b/contrib/go/_std_1.21/src/debug/dwarf/entry.go
new file mode 100644
index 0000000000..f1215d2b01
--- /dev/null
+++ b/contrib/go/_std_1.21/src/debug/dwarf/entry.go
@@ -0,0 +1,1221 @@
+// Copyright 2009 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.
+
+// DWARF debug information entry parser.
+// An entry is a sequence of data items of a given format.
+// The first word in the entry is an index into what DWARF
+// calls the ``abbreviation table.'' An abbreviation is really
+// just a type descriptor: it's an array of attribute tag/value format pairs.
+
+package dwarf
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "strconv"
+)
+
+// a single entry's description: a sequence of attributes
+type abbrev struct {
+ tag Tag
+ children bool
+ field []afield
+}
+
+type afield struct {
+ attr Attr
+ fmt format
+ class Class
+ val int64 // for formImplicitConst
+}
+
+// a map from entry format ids to their descriptions
+type abbrevTable map[uint32]abbrev
+
+// parseAbbrev returns the abbreviation table that starts at byte off
+// in the .debug_abbrev section.
+func (d *Data) parseAbbrev(off uint64, vers int) (abbrevTable, error) {
+ if m, ok := d.abbrevCache[off]; ok {
+ return m, nil
+ }
+
+ data := d.abbrev
+ if off > uint64(len(data)) {
+ data = nil
+ } else {
+ data = data[off:]
+ }
+ b := makeBuf(d, unknownFormat{}, "abbrev", 0, data)
+
+ // Error handling is simplified by the buf getters
+ // returning an endless stream of 0s after an error.
+ m := make(abbrevTable)
+ for {
+ // Table ends with id == 0.
+ id := uint32(b.uint())
+ if id == 0 {
+ break
+ }
+
+ // Walk over attributes, counting.
+ n := 0
+ b1 := b // Read from copy of b.
+ b1.uint()
+ b1.uint8()
+ for {
+ tag := b1.uint()
+ fmt := b1.uint()
+ if tag == 0 && fmt == 0 {
+ break
+ }
+ if format(fmt) == formImplicitConst {
+ b1.int()
+ }
+ n++
+ }
+ if b1.err != nil {
+ return nil, b1.err
+ }
+
+ // Walk over attributes again, this time writing them down.
+ var a abbrev
+ a.tag = Tag(b.uint())
+ a.children = b.uint8() != 0
+ a.field = make([]afield, n)
+ for i := range a.field {
+ a.field[i].attr = Attr(b.uint())
+ a.field[i].fmt = format(b.uint())
+ a.field[i].class = formToClass(a.field[i].fmt, a.field[i].attr, vers, &b)
+ if a.field[i].fmt == formImplicitConst {
+ a.field[i].val = b.int()
+ }
+ }
+ b.uint()
+ b.uint()
+
+ m[id] = a
+ }
+ if b.err != nil {
+ return nil, b.err
+ }
+ d.abbrevCache[off] = m
+ return m, nil
+}
+
+// attrIsExprloc indicates attributes that allow exprloc values that
+// are encoded as block values in DWARF 2 and 3. See DWARF 4, Figure
+// 20.
+var attrIsExprloc = map[Attr]bool{
+ AttrLocation: true,
+ AttrByteSize: true,
+ AttrBitOffset: true,
+ AttrBitSize: true,
+ AttrStringLength: true,
+ AttrLowerBound: true,
+ AttrReturnAddr: true,
+ AttrStrideSize: true,
+ AttrUpperBound: true,
+ AttrCount: true,
+ AttrDataMemberLoc: true,
+ AttrFrameBase: true,
+ AttrSegment: true,
+ AttrStaticLink: true,
+ AttrUseLocation: true,
+ AttrVtableElemLoc: true,
+ AttrAllocated: true,
+ AttrAssociated: true,
+ AttrDataLocation: true,
+ AttrStride: true,
+}
+
+// attrPtrClass indicates the *ptr class of attributes that have
+// encoding formSecOffset in DWARF 4 or formData* in DWARF 2 and 3.
+var attrPtrClass = map[Attr]Class{
+ AttrLocation: ClassLocListPtr,
+ AttrStmtList: ClassLinePtr,
+ AttrStringLength: ClassLocListPtr,
+ AttrReturnAddr: ClassLocListPtr,
+ AttrStartScope: ClassRangeListPtr,
+ AttrDataMemberLoc: ClassLocListPtr,
+ AttrFrameBase: ClassLocListPtr,
+ AttrMacroInfo: ClassMacPtr,
+ AttrSegment: ClassLocListPtr,
+ AttrStaticLink: ClassLocListPtr,
+ AttrUseLocation: ClassLocListPtr,
+ AttrVtableElemLoc: ClassLocListPtr,
+ AttrRanges: ClassRangeListPtr,
+ // The following are new in DWARF 5.
+ AttrStrOffsetsBase: ClassStrOffsetsPtr,
+ AttrAddrBase: ClassAddrPtr,
+ AttrRnglistsBase: ClassRngListsPtr,
+ AttrLoclistsBase: ClassLocListPtr,
+}
+
+// formToClass returns the DWARF 4 Class for the given form. If the
+// DWARF version is less then 4, it will disambiguate some forms
+// depending on the attribute.
+func formToClass(form format, attr Attr, vers int, b *buf) Class {
+ switch form {
+ default:
+ b.error("cannot determine class of unknown attribute form")
+ return 0
+
+ case formIndirect:
+ return ClassUnknown
+
+ case formAddr, formAddrx, formAddrx1, formAddrx2, formAddrx3, formAddrx4:
+ return ClassAddress
+
+ case formDwarfBlock1, formDwarfBlock2, formDwarfBlock4, formDwarfBlock:
+ // In DWARF 2 and 3, ClassExprLoc was encoded as a
+ // block. DWARF 4 distinguishes ClassBlock and
+ // ClassExprLoc, but there are no attributes that can
+ // be both, so we also promote ClassBlock values in
+ // DWARF 4 that should be ClassExprLoc in case
+ // producers get this wrong.
+ if attrIsExprloc[attr] {
+ return ClassExprLoc
+ }
+ return ClassBlock
+
+ case formData1, formData2, formData4, formData8, formSdata, formUdata, formData16, formImplicitConst:
+ // In DWARF 2 and 3, ClassPtr was encoded as a
+ // constant. Unlike ClassExprLoc/ClassBlock, some
+ // DWARF 4 attributes need to distinguish Class*Ptr
+ // from ClassConstant, so we only do this promotion
+ // for versions 2 and 3.
+ if class, ok := attrPtrClass[attr]; vers < 4 && ok {
+ return class
+ }
+ return ClassConstant
+
+ case formFlag, formFlagPresent:
+ return ClassFlag
+
+ case formRefAddr, formRef1, formRef2, formRef4, formRef8, formRefUdata, formRefSup4, formRefSup8:
+ return ClassReference
+
+ case formRefSig8:
+ return ClassReferenceSig
+
+ case formString, formStrp, formStrx, formStrpSup, formLineStrp, formStrx1, formStrx2, formStrx3, formStrx4:
+ return ClassString
+
+ case formSecOffset:
+ // DWARF 4 defines four *ptr classes, but doesn't
+ // distinguish them in the encoding. Disambiguate
+ // these classes using the attribute.
+ if class, ok := attrPtrClass[attr]; ok {
+ return class
+ }
+ return ClassUnknown
+
+ case formExprloc:
+ return ClassExprLoc
+
+ case formGnuRefAlt:
+ return ClassReferenceAlt
+
+ case formGnuStrpAlt:
+ return ClassStringAlt
+
+ case formLoclistx:
+ return ClassLocList
+
+ case formRnglistx:
+ return ClassRngList
+ }
+}
+
+// An entry is a sequence of attribute/value pairs.
+type Entry struct {
+ Offset Offset // offset of Entry in DWARF info
+ Tag Tag // tag (kind of Entry)
+ Children bool // whether Entry is followed by children
+ Field []Field
+}
+
+// A Field is a single attribute/value pair in an Entry.
+//
+// A value can be one of several "attribute classes" defined by DWARF.
+// The Go types corresponding to each class are:
+//
+// DWARF class Go type Class
+// ----------- ------- -----
+// address uint64 ClassAddress
+// block []byte ClassBlock
+// constant int64 ClassConstant
+// flag bool ClassFlag
+// reference
+// to info dwarf.Offset ClassReference
+// to type unit uint64 ClassReferenceSig
+// string string ClassString
+// exprloc []byte ClassExprLoc
+// lineptr int64 ClassLinePtr
+// loclistptr int64 ClassLocListPtr
+// macptr int64 ClassMacPtr
+// rangelistptr int64 ClassRangeListPtr
+//
+// For unrecognized or vendor-defined attributes, Class may be
+// ClassUnknown.
+type Field struct {
+ Attr Attr
+ Val any
+ Class Class
+}
+
+// A Class is the DWARF 4 class of an attribute value.
+//
+// In general, a given attribute's value may take on one of several
+// possible classes defined by DWARF, each of which leads to a
+// slightly different interpretation of the attribute.
+//
+// DWARF version 4 distinguishes attribute value classes more finely
+// than previous versions of DWARF. The reader will disambiguate
+// coarser classes from earlier versions of DWARF into the appropriate
+// DWARF 4 class. For example, DWARF 2 uses "constant" for constants
+// as well as all types of section offsets, but the reader will
+// canonicalize attributes in DWARF 2 files that refer to section
+// offsets to one of the Class*Ptr classes, even though these classes
+// were only defined in DWARF 3.
+type Class int
+
+const (
+ // ClassUnknown represents values of unknown DWARF class.
+ ClassUnknown Class = iota
+
+ // ClassAddress represents values of type uint64 that are
+ // addresses on the target machine.
+ ClassAddress
+
+ // ClassBlock represents values of type []byte whose
+ // interpretation depends on the attribute.
+ ClassBlock
+
+ // ClassConstant represents values of type int64 that are
+ // constants. The interpretation of this constant depends on
+ // the attribute.
+ ClassConstant
+
+ // ClassExprLoc represents values of type []byte that contain
+ // an encoded DWARF expression or location description.
+ ClassExprLoc
+
+ // ClassFlag represents values of type bool.
+ ClassFlag
+
+ // ClassLinePtr represents values that are an int64 offset
+ // into the "line" section.
+ ClassLinePtr
+
+ // ClassLocListPtr represents values that are an int64 offset
+ // into the "loclist" section.
+ ClassLocListPtr
+
+ // ClassMacPtr represents values that are an int64 offset into
+ // the "mac" section.
+ ClassMacPtr
+
+ // ClassRangeListPtr represents values that are an int64 offset into
+ // the "rangelist" section.
+ ClassRangeListPtr
+
+ // ClassReference represents values that are an Offset offset
+ // of an Entry in the info section (for use with Reader.Seek).
+ // The DWARF specification combines ClassReference and
+ // ClassReferenceSig into class "reference".
+ ClassReference
+
+ // ClassReferenceSig represents values that are a uint64 type
+ // signature referencing a type Entry.
+ ClassReferenceSig
+
+ // ClassString represents values that are strings. If the
+ // compilation unit specifies the AttrUseUTF8 flag (strongly
+ // recommended), the string value will be encoded in UTF-8.
+ // Otherwise, the encoding is unspecified.
+ ClassString
+
+ // ClassReferenceAlt represents values of type int64 that are
+ // an offset into the DWARF "info" section of an alternate
+ // object file.
+ ClassReferenceAlt
+
+ // ClassStringAlt represents values of type int64 that are an
+ // offset into the DWARF string section of an alternate object
+ // file.
+ ClassStringAlt
+
+ // ClassAddrPtr represents values that are an int64 offset
+ // into the "addr" section.
+ ClassAddrPtr
+
+ // ClassLocList represents values that are an int64 offset
+ // into the "loclists" section.
+ ClassLocList
+
+ // ClassRngList represents values that are a uint64 offset
+ // from the base of the "rnglists" section.
+ ClassRngList
+
+ // ClassRngListsPtr represents values that are an int64 offset
+ // into the "rnglists" section. These are used as the base for
+ // ClassRngList values.
+ ClassRngListsPtr
+
+ // ClassStrOffsetsPtr represents values that are an int64
+ // offset into the "str_offsets" section.
+ ClassStrOffsetsPtr
+)
+
+//go:generate stringer -type=Class
+
+func (i Class) GoString() string {
+ return "dwarf." + i.String()
+}
+
+// Val returns the value associated with attribute Attr in Entry,
+// or nil if there is no such attribute.
+//
+// A common idiom is to merge the check for nil return with
+// the check that the value has the expected dynamic type, as in:
+//
+// v, ok := e.Val(AttrSibling).(int64)
+func (e *Entry) Val(a Attr) any {
+ if f := e.AttrField(a); f != nil {
+ return f.Val
+ }
+ return nil
+}
+
+// AttrField returns the Field associated with attribute Attr in
+// Entry, or nil if there is no such attribute.
+func (e *Entry) AttrField(a Attr) *Field {
+ for i, f := range e.Field {
+ if f.Attr == a {
+ return &e.Field[i]
+ }
+ }
+ return nil
+}
+
+// An Offset represents the location of an Entry within the DWARF info.
+// (See Reader.Seek.)
+type Offset uint32
+
+// Entry reads a single entry from buf, decoding
+// according to the given abbreviation table.
+func (b *buf) entry(cu *Entry, atab abbrevTable, ubase Offset, vers int) *Entry {
+ off := b.off
+ id := uint32(b.uint())
+ if id == 0 {
+ return &Entry{}
+ }
+ a, ok := atab[id]
+ if !ok {
+ b.error("unknown abbreviation table index")
+ return nil
+ }
+ e := &Entry{
+ Offset: off,
+ Tag: a.tag,
+ Children: a.children,
+ Field: make([]Field, len(a.field)),
+ }
+
+ // If we are currently parsing the compilation unit,
+ // we can't evaluate Addrx or Strx until we've seen the
+ // relevant base entry.
+ type delayed struct {
+ idx int
+ off uint64
+ fmt format
+ }
+ var delay []delayed
+
+ resolveStrx := func(strBase, off uint64) string {
+ off += strBase
+ if uint64(int(off)) != off {
+ b.error("DW_FORM_strx offset out of range")
+ }
+
+ b1 := makeBuf(b.dwarf, b.format, "str_offsets", 0, b.dwarf.strOffsets)
+ b1.skip(int(off))
+ is64, _ := b.format.dwarf64()
+ if is64 {
+ off = b1.uint64()
+ } else {
+ off = uint64(b1.uint32())
+ }
+ if b1.err != nil {
+ b.err = b1.err
+ return ""
+ }
+ if uint64(int(off)) != off {
+ b.error("DW_FORM_strx indirect offset out of range")
+ }
+ b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
+ b1.skip(int(off))
+ val := b1.string()
+ if b1.err != nil {
+ b.err = b1.err
+ }
+ return val
+ }
+
+ resolveRnglistx := func(rnglistsBase, off uint64) uint64 {
+ is64, _ := b.format.dwarf64()
+ if is64 {
+ off *= 8
+ } else {
+ off *= 4
+ }
+ off += rnglistsBase
+ if uint64(int(off)) != off {
+ b.error("DW_FORM_rnglistx offset out of range")
+ }
+
+ b1 := makeBuf(b.dwarf, b.format, "rnglists", 0, b.dwarf.rngLists)
+ b1.skip(int(off))
+ if is64 {
+ off = b1.uint64()
+ } else {
+ off = uint64(b1.uint32())
+ }
+ if b1.err != nil {
+ b.err = b1.err
+ return 0
+ }
+ if uint64(int(off)) != off {
+ b.error("DW_FORM_rnglistx indirect offset out of range")
+ }
+ return rnglistsBase + off
+ }
+
+ for i := range e.Field {
+ e.Field[i].Attr = a.field[i].attr
+ e.Field[i].Class = a.field[i].class
+ fmt := a.field[i].fmt
+ if fmt == formIndirect {
+ fmt = format(b.uint())
+ e.Field[i].Class = formToClass(fmt, a.field[i].attr, vers, b)
+ }
+ var val any
+ switch fmt {
+ default:
+ b.error("unknown entry attr format 0x" + strconv.FormatInt(int64(fmt), 16))
+
+ // address
+ case formAddr:
+ val = b.addr()
+ case formAddrx, formAddrx1, formAddrx2, formAddrx3, formAddrx4:
+ var off uint64
+ switch fmt {
+ case formAddrx:
+ off = b.uint()
+ case formAddrx1:
+ off = uint64(b.uint8())
+ case formAddrx2:
+ off = uint64(b.uint16())
+ case formAddrx3:
+ off = uint64(b.uint24())
+ case formAddrx4:
+ off = uint64(b.uint32())
+ }
+ if b.dwarf.addr == nil {
+ b.error("DW_FORM_addrx with no .debug_addr section")
+ }
+ if b.err != nil {
+ return nil
+ }
+
+ // We have to adjust by the offset of the
+ // compilation unit. This won't work if the
+ // program uses Reader.Seek to skip over the
+ // unit. Not much we can do about that.
+ var addrBase int64
+ if cu != nil {
+ addrBase, _ = cu.Val(AttrAddrBase).(int64)
+ } else if a.tag == TagCompileUnit {
+ delay = append(delay, delayed{i, off, formAddrx})
+ break
+ }
+
+ var err error
+ val, err = b.dwarf.debugAddr(b.format, uint64(addrBase), off)
+ if err != nil {
+ if b.err == nil {
+ b.err = err
+ }
+ return nil
+ }
+
+ // block
+ case formDwarfBlock1:
+ val = b.bytes(int(b.uint8()))
+ case formDwarfBlock2:
+ val = b.bytes(int(b.uint16()))
+ case formDwarfBlock4:
+ val = b.bytes(int(b.uint32()))
+ case formDwarfBlock:
+ val = b.bytes(int(b.uint()))
+
+ // constant
+ case formData1:
+ val = int64(b.uint8())
+ case formData2:
+ val = int64(b.uint16())
+ case formData4:
+ val = int64(b.uint32())
+ case formData8:
+ val = int64(b.uint64())
+ case formData16:
+ val = b.bytes(16)
+ case formSdata:
+ val = int64(b.int())
+ case formUdata:
+ val = int64(b.uint())
+ case formImplicitConst:
+ val = a.field[i].val
+
+ // flag
+ case formFlag:
+ val = b.uint8() == 1
+ // New in DWARF 4.
+ case formFlagPresent:
+ // The attribute is implicitly indicated as present, and no value is
+ // encoded in the debugging information entry itself.
+ val = true
+
+ // reference to other entry
+ case formRefAddr:
+ vers := b.format.version()
+ if vers == 0 {
+ b.error("unknown version for DW_FORM_ref_addr")
+ } else if vers == 2 {
+ val = Offset(b.addr())
+ } else {
+ is64, known := b.format.dwarf64()
+ if !known {
+ b.error("unknown size for DW_FORM_ref_addr")
+ } else if is64 {
+ val = Offset(b.uint64())
+ } else {
+ val = Offset(b.uint32())
+ }
+ }
+ case formRef1:
+ val = Offset(b.uint8()) + ubase
+ case formRef2:
+ val = Offset(b.uint16()) + ubase
+ case formRef4:
+ val = Offset(b.uint32()) + ubase
+ case formRef8:
+ val = Offset(b.uint64()) + ubase
+ case formRefUdata:
+ val = Offset(b.uint()) + ubase
+
+ // string
+ case formString:
+ val = b.string()
+ case formStrp, formLineStrp:
+ var off uint64 // offset into .debug_str
+ is64, known := b.format.dwarf64()
+ if !known {
+ b.error("unknown size for DW_FORM_strp/line_strp")
+ } else if is64 {
+ off = b.uint64()
+ } else {
+ off = uint64(b.uint32())
+ }
+ if uint64(int(off)) != off {
+ b.error("DW_FORM_strp/line_strp offset out of range")
+ }
+ if b.err != nil {
+ return nil
+ }
+ var b1 buf
+ if fmt == formStrp {
+ b1 = makeBuf(b.dwarf, b.format, "str", 0, b.dwarf.str)
+ } else {
+ if len(b.dwarf.lineStr) == 0 {
+ b.error("DW_FORM_line_strp with no .debug_line_str section")
+ return nil
+ }
+ b1 = makeBuf(b.dwarf, b.format, "line_str", 0, b.dwarf.lineStr)
+ }
+ b1.skip(int(off))
+ val = b1.string()
+ if b1.err != nil {
+ b.err = b1.err
+ return nil
+ }
+ case formStrx, formStrx1, formStrx2, formStrx3, formStrx4:
+ var off uint64
+ switch fmt {
+ case formStrx:
+ off = b.uint()
+ case formStrx1:
+ off = uint64(b.uint8())
+ case formStrx2:
+ off = uint64(b.uint16())
+ case formStrx3:
+ off = uint64(b.uint24())
+ case formStrx4:
+ off = uint64(b.uint32())
+ }
+ if len(b.dwarf.strOffsets) == 0 {
+ b.error("DW_FORM_strx with no .debug_str_offsets section")
+ }
+ is64, known := b.format.dwarf64()
+ if !known {
+ b.error("unknown offset size for DW_FORM_strx")
+ }
+ if b.err != nil {
+ return nil
+ }
+ if is64 {
+ off *= 8
+ } else {
+ off *= 4
+ }
+
+ // We have to adjust by the offset of the
+ // compilation unit. This won't work if the
+ // program uses Reader.Seek to skip over the
+ // unit. Not much we can do about that.
+ var strBase int64
+ if cu != nil {
+ strBase, _ = cu.Val(AttrStrOffsetsBase).(int64)
+ } else if a.tag == TagCompileUnit {
+ delay = append(delay, delayed{i, off, formStrx})
+ break
+ }
+
+ val = resolveStrx(uint64(strBase), off)
+
+ case formStrpSup:
+ is64, known := b.format.dwarf64()
+ if !known {
+ b.error("unknown size for DW_FORM_strp_sup")
+ } else if is64 {
+ val = b.uint64()
+ } else {
+ val = b.uint32()
+ }
+
+ // lineptr, loclistptr, macptr, rangelistptr
+ // New in DWARF 4, but clang can generate them with -gdwarf-2.
+ // Section reference, replacing use of formData4 and formData8.
+ case formSecOffset, formGnuRefAlt, formGnuStrpAlt:
+ is64, known := b.format.dwarf64()
+ if !known {
+ b.error("unknown size for form 0x" + strconv.FormatInt(int64(fmt), 16))
+ } else if is64 {
+ val = int64(b.uint64())
+ } else {
+ val = int64(b.uint32())
+ }
+
+ // exprloc
+ // New in DWARF 4.
+ case formExprloc:
+ val = b.bytes(int(b.uint()))
+
+ // reference
+ // New in DWARF 4.
+ case formRefSig8:
+ // 64-bit type signature.
+ val = b.uint64()
+ case formRefSup4:
+ val = b.uint32()
+ case formRefSup8:
+ val = b.uint64()
+
+ // loclist
+ case formLoclistx:
+ val = b.uint()
+
+ // rnglist
+ case formRnglistx:
+ off := b.uint()
+
+ // We have to adjust by the rnglists_base of
+ // the compilation unit. This won't work if
+ // the program uses Reader.Seek to skip over
+ // the unit. Not much we can do about that.
+ var rnglistsBase int64
+ if cu != nil {
+ rnglistsBase, _ = cu.Val(AttrRnglistsBase).(int64)
+ } else if a.tag == TagCompileUnit {
+ delay = append(delay, delayed{i, off, formRnglistx})
+ break
+ }
+
+ val = resolveRnglistx(uint64(rnglistsBase), off)
+ }
+
+ e.Field[i].Val = val
+ }
+ if b.err != nil {
+ return nil
+ }
+
+ for _, del := range delay {
+ switch del.fmt {
+ case formAddrx:
+ addrBase, _ := e.Val(AttrAddrBase).(int64)
+ val, err := b.dwarf.debugAddr(b.format, uint64(addrBase), del.off)
+ if err != nil {
+ b.err = err
+ return nil
+ }
+ e.Field[del.idx].Val = val
+ case formStrx:
+ strBase, _ := e.Val(AttrStrOffsetsBase).(int64)
+ e.Field[del.idx].Val = resolveStrx(uint64(strBase), del.off)
+ if b.err != nil {
+ return nil
+ }
+ case formRnglistx:
+ rnglistsBase, _ := e.Val(AttrRnglistsBase).(int64)
+ e.Field[del.idx].Val = resolveRnglistx(uint64(rnglistsBase), del.off)
+ if b.err != nil {
+ return nil
+ }
+ }
+ }
+
+ return e
+}
+
+// A Reader allows reading Entry structures from a DWARF “info” section.
+// The Entry structures are arranged in a tree. The Reader's Next function
+// return successive entries from a pre-order traversal of the tree.
+// If an entry has children, its Children field will be true, and the children
+// follow, terminated by an Entry with Tag 0.
+type Reader struct {
+ b buf
+ d *Data
+ err error
+ unit int
+ lastUnit bool // set if last entry returned by Next is TagCompileUnit/TagPartialUnit
+ lastChildren bool // .Children of last entry returned by Next
+ lastSibling Offset // .Val(AttrSibling) of last entry returned by Next
+ cu *Entry // current compilation unit
+}
+
+// Reader returns a new Reader for Data.
+// The reader is positioned at byte offset 0 in the DWARF “info” section.
+func (d *Data) Reader() *Reader {
+ r := &Reader{d: d}
+ r.Seek(0)
+ return r
+}
+
+// AddressSize returns the size in bytes of addresses in the current compilation
+// unit.
+func (r *Reader) AddressSize() int {
+ return r.d.unit[r.unit].asize
+}
+
+// ByteOrder returns the byte order in the current compilation unit.
+func (r *Reader) ByteOrder() binary.ByteOrder {
+ return r.b.order
+}
+
+// Seek positions the Reader at offset off in the encoded entry stream.
+// Offset 0 can be used to denote the first entry.
+func (r *Reader) Seek(off Offset) {
+ d := r.d
+ r.err = nil
+ r.lastChildren = false
+ if off == 0 {
+ if len(d.unit) == 0 {
+ return
+ }
+ u := &d.unit[0]
+ r.unit = 0
+ r.b = makeBuf(r.d, u, "info", u.off, u.data)
+ r.cu = nil
+ return
+ }
+
+ i := d.offsetToUnit(off)
+ if i == -1 {
+ r.err = errors.New("offset out of range")
+ return
+ }
+ if i != r.unit {
+ r.cu = nil
+ }
+ u := &d.unit[i]
+ r.unit = i
+ r.b = makeBuf(r.d, u, "info", off, u.data[off-u.off:])
+}
+
+// maybeNextUnit advances to the next unit if this one is finished.
+func (r *Reader) maybeNextUnit() {
+ for len(r.b.data) == 0 && r.unit+1 < len(r.d.unit) {
+ r.nextUnit()
+ }
+}
+
+// nextUnit advances to the next unit.
+func (r *Reader) nextUnit() {
+ r.unit++
+ u := &r.d.unit[r.unit]
+ r.b = makeBuf(r.d, u, "info", u.off, u.data)
+ r.cu = nil
+}
+
+// Next reads the next entry from the encoded entry stream.
+// It returns nil, nil when it reaches the end of the section.
+// It returns an error if the current offset is invalid or the data at the
+// offset cannot be decoded as a valid Entry.
+func (r *Reader) Next() (*Entry, error) {
+ if r.err != nil {
+ return nil, r.err
+ }
+ r.maybeNextUnit()
+ if len(r.b.data) == 0 {
+ return nil, nil
+ }
+ u := &r.d.unit[r.unit]
+ e := r.b.entry(r.cu, u.atable, u.base, u.vers)
+ if r.b.err != nil {
+ r.err = r.b.err
+ return nil, r.err
+ }
+ r.lastUnit = false
+ if e != nil {
+ r.lastChildren = e.Children
+ if r.lastChildren {
+ r.lastSibling, _ = e.Val(AttrSibling).(Offset)
+ }
+ if e.Tag == TagCompileUnit || e.Tag == TagPartialUnit {
+ r.lastUnit = true
+ r.cu = e
+ }
+ } else {
+ r.lastChildren = false
+ }
+ return e, nil
+}
+
+// SkipChildren skips over the child entries associated with
+// the last Entry returned by Next. If that Entry did not have
+// children or Next has not been called, SkipChildren is a no-op.
+func (r *Reader) SkipChildren() {
+ if r.err != nil || !r.lastChildren {
+ return
+ }
+
+ // If the last entry had a sibling attribute,
+ // that attribute gives the offset of the next
+ // sibling, so we can avoid decoding the
+ // child subtrees.
+ if r.lastSibling >= r.b.off {
+ r.Seek(r.lastSibling)
+ return
+ }
+
+ if r.lastUnit && r.unit+1 < len(r.d.unit) {
+ r.nextUnit()
+ return
+ }
+
+ for {
+ e, err := r.Next()
+ if err != nil || e == nil || e.Tag == 0 {
+ break
+ }
+ if e.Children {
+ r.SkipChildren()
+ }
+ }
+}
+
+// clone returns a copy of the reader. This is used by the typeReader
+// interface.
+func (r *Reader) clone() typeReader {
+ return r.d.Reader()
+}
+
+// offset returns the current buffer offset. This is used by the
+// typeReader interface.
+func (r *Reader) offset() Offset {
+ return r.b.off
+}
+
+// SeekPC returns the Entry for the compilation unit that includes pc,
+// and positions the reader to read the children of that unit. If pc
+// is not covered by any unit, SeekPC returns ErrUnknownPC and the
+// position of the reader is undefined.
+//
+// Because compilation units can describe multiple regions of the
+// executable, in the worst case SeekPC must search through all the
+// ranges in all the compilation units. Each call to SeekPC starts the
+// search at the compilation unit of the last call, so in general
+// looking up a series of PCs will be faster if they are sorted. If
+// the caller wishes to do repeated fast PC lookups, it should build
+// an appropriate index using the Ranges method.
+func (r *Reader) SeekPC(pc uint64) (*Entry, error) {
+ unit := r.unit
+ for i := 0; i < len(r.d.unit); i++ {
+ if unit >= len(r.d.unit) {
+ unit = 0
+ }
+ r.err = nil
+ r.lastChildren = false
+ r.unit = unit
+ r.cu = nil
+ u := &r.d.unit[unit]
+ r.b = makeBuf(r.d, u, "info", u.off, u.data)
+ e, err := r.Next()
+ if err != nil {
+ return nil, err
+ }
+ if e == nil || e.Tag == 0 {
+ return nil, ErrUnknownPC
+ }
+ ranges, err := r.d.Ranges(e)
+ if err != nil {
+ return nil, err
+ }
+ for _, pcs := range ranges {
+ if pcs[0] <= pc && pc < pcs[1] {
+ return e, nil
+ }
+ }
+ unit++
+ }
+ return nil, ErrUnknownPC
+}
+
+// Ranges returns the PC ranges covered by e, a slice of [low,high) pairs.
+// Only some entry types, such as TagCompileUnit or TagSubprogram, have PC
+// ranges; for others, this will return nil with no error.
+func (d *Data) Ranges(e *Entry) ([][2]uint64, error) {
+ var ret [][2]uint64
+
+ low, lowOK := e.Val(AttrLowpc).(uint64)
+
+ var high uint64
+ var highOK bool
+ highField := e.AttrField(AttrHighpc)
+ if highField != nil {
+ switch highField.Class {
+ case ClassAddress:
+ high, highOK = highField.Val.(uint64)
+ case ClassConstant:
+ off, ok := highField.Val.(int64)
+ if ok {
+ high = low + uint64(off)
+ highOK = true
+ }
+ }
+ }
+
+ if lowOK && highOK {
+ ret = append(ret, [2]uint64{low, high})
+ }
+
+ var u *unit
+ if uidx := d.offsetToUnit(e.Offset); uidx >= 0 && uidx < len(d.unit) {
+ u = &d.unit[uidx]
+ }
+
+ if u != nil && u.vers >= 5 && d.rngLists != nil {
+ // DWARF version 5 and later
+ field := e.AttrField(AttrRanges)
+ if field == nil {
+ return ret, nil
+ }
+ switch field.Class {
+ case ClassRangeListPtr:
+ ranges, rangesOK := field.Val.(int64)
+ if !rangesOK {
+ return ret, nil
+ }
+ cu, base, err := d.baseAddressForEntry(e)
+ if err != nil {
+ return nil, err
+ }
+ return d.dwarf5Ranges(u, cu, base, ranges, ret)
+
+ case ClassRngList:
+ rnglist, ok := field.Val.(uint64)
+ if !ok {
+ return ret, nil
+ }
+ cu, base, err := d.baseAddressForEntry(e)
+ if err != nil {
+ return nil, err
+ }
+ return d.dwarf5Ranges(u, cu, base, int64(rnglist), ret)
+
+ default:
+ return ret, nil
+ }
+ }
+
+ // DWARF version 2 through 4
+ ranges, rangesOK := e.Val(AttrRanges).(int64)
+ if rangesOK && d.ranges != nil {
+ _, base, err := d.baseAddressForEntry(e)
+ if err != nil {
+ return nil, err
+ }
+ return d.dwarf2Ranges(u, base, ranges, ret)
+ }
+
+ return ret, nil
+}
+
+// baseAddressForEntry returns the initial base address to be used when
+// looking up the range list of entry e.
+// DWARF specifies that this should be the lowpc attribute of the enclosing
+// compilation unit, however comments in gdb/dwarf2read.c say that some
+// versions of GCC use the entrypc attribute, so we check that too.
+func (d *Data) baseAddressForEntry(e *Entry) (*Entry, uint64, error) {
+ var cu *Entry
+ if e.Tag == TagCompileUnit {
+ cu = e
+ } else {
+ i := d.offsetToUnit(e.Offset)
+ if i == -1 {
+ return nil, 0, errors.New("no unit for entry")
+ }
+ u := &d.unit[i]
+ b := makeBuf(d, u, "info", u.off, u.data)
+ cu = b.entry(nil, u.atable, u.base, u.vers)
+ if b.err != nil {
+ return nil, 0, b.err
+ }
+ }
+
+ if cuEntry, cuEntryOK := cu.Val(AttrEntrypc).(uint64); cuEntryOK {
+ return cu, cuEntry, nil
+ } else if cuLow, cuLowOK := cu.Val(AttrLowpc).(uint64); cuLowOK {
+ return cu, cuLow, nil
+ }
+
+ return cu, 0, nil
+}
+
+func (d *Data) dwarf2Ranges(u *unit, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
+ if ranges < 0 || ranges > int64(len(d.ranges)) {
+ return nil, fmt.Errorf("invalid range offset %d (max %d)", ranges, len(d.ranges))
+ }
+ buf := makeBuf(d, u, "ranges", Offset(ranges), d.ranges[ranges:])
+ for len(buf.data) > 0 {
+ low := buf.addr()
+ high := buf.addr()
+
+ if low == 0 && high == 0 {
+ break
+ }
+
+ if low == ^uint64(0)>>uint((8-u.addrsize())*8) {
+ base = high
+ } else {
+ ret = append(ret, [2]uint64{base + low, base + high})
+ }
+ }
+
+ return ret, nil
+}
+
+// dwarf5Ranges interprets a debug_rnglists sequence, see DWARFv5 section
+// 2.17.3 (page 53).
+func (d *Data) dwarf5Ranges(u *unit, cu *Entry, base uint64, ranges int64, ret [][2]uint64) ([][2]uint64, error) {
+ if ranges < 0 || ranges > int64(len(d.rngLists)) {
+ return nil, fmt.Errorf("invalid rnglist offset %d (max %d)", ranges, len(d.ranges))
+ }
+ var addrBase int64
+ if cu != nil {
+ addrBase, _ = cu.Val(AttrAddrBase).(int64)
+ }
+
+ buf := makeBuf(d, u, "rnglists", 0, d.rngLists)
+ buf.skip(int(ranges))
+ for {
+ opcode := buf.uint8()
+ switch opcode {
+ case rleEndOfList:
+ if buf.err != nil {
+ return nil, buf.err
+ }
+ return ret, nil
+
+ case rleBaseAddressx:
+ baseIdx := buf.uint()
+ var err error
+ base, err = d.debugAddr(u, uint64(addrBase), baseIdx)
+ if err != nil {
+ return nil, err
+ }
+
+ case rleStartxEndx:
+ startIdx := buf.uint()
+ endIdx := buf.uint()
+
+ start, err := d.debugAddr(u, uint64(addrBase), startIdx)
+ if err != nil {
+ return nil, err
+ }
+ end, err := d.debugAddr(u, uint64(addrBase), endIdx)
+ if err != nil {
+ return nil, err
+ }
+ ret = append(ret, [2]uint64{start, end})
+
+ case rleStartxLength:
+ startIdx := buf.uint()
+ len := buf.uint()
+ start, err := d.debugAddr(u, uint64(addrBase), startIdx)
+ if err != nil {
+ return nil, err
+ }
+ ret = append(ret, [2]uint64{start, start + len})
+
+ case rleOffsetPair:
+ off1 := buf.uint()
+ off2 := buf.uint()
+ ret = append(ret, [2]uint64{base + off1, base + off2})
+
+ case rleBaseAddress:
+ base = buf.addr()
+
+ case rleStartEnd:
+ start := buf.addr()
+ end := buf.addr()
+ ret = append(ret, [2]uint64{start, end})
+
+ case rleStartLength:
+ start := buf.addr()
+ len := buf.uint()
+ ret = append(ret, [2]uint64{start, start + len})
+ }
+ }
+}
+
+// debugAddr returns the address at idx in debug_addr
+func (d *Data) debugAddr(format dataFormat, addrBase, idx uint64) (uint64, error) {
+ off := idx*uint64(format.addrsize()) + addrBase
+
+ if uint64(int(off)) != off {
+ return 0, errors.New("offset out of range")
+ }
+
+ b := makeBuf(d, format, "addr", 0, d.addr)
+ b.skip(int(off))
+ val := b.addr()
+ if b.err != nil {
+ return 0, b.err
+ }
+ return val, nil
+}
diff --git a/contrib/go/_std_1.20/src/debug/dwarf/line.go b/contrib/go/_std_1.21/src/debug/dwarf/line.go
index 4df4a1751f..4df4a1751f 100644
--- a/contrib/go/_std_1.20/src/debug/dwarf/line.go
+++ b/contrib/go/_std_1.21/src/debug/dwarf/line.go
diff --git a/contrib/go/_std_1.20/src/debug/dwarf/open.go b/contrib/go/_std_1.21/src/debug/dwarf/open.go
index 994b7262d1..994b7262d1 100644
--- a/contrib/go/_std_1.20/src/debug/dwarf/open.go
+++ b/contrib/go/_std_1.21/src/debug/dwarf/open.go
diff --git a/contrib/go/_std_1.20/src/debug/dwarf/tag_string.go b/contrib/go/_std_1.21/src/debug/dwarf/tag_string.go
index b79ea175b0..b79ea175b0 100644
--- a/contrib/go/_std_1.20/src/debug/dwarf/tag_string.go
+++ b/contrib/go/_std_1.21/src/debug/dwarf/tag_string.go
diff --git a/contrib/go/_std_1.20/src/debug/dwarf/type.go b/contrib/go/_std_1.21/src/debug/dwarf/type.go
index a95c4c738f..a95c4c738f 100644
--- a/contrib/go/_std_1.20/src/debug/dwarf/type.go
+++ b/contrib/go/_std_1.21/src/debug/dwarf/type.go
diff --git a/contrib/go/_std_1.20/src/debug/dwarf/typeunit.go b/contrib/go/_std_1.21/src/debug/dwarf/typeunit.go
index 27aa0784f0..27aa0784f0 100644
--- a/contrib/go/_std_1.20/src/debug/dwarf/typeunit.go
+++ b/contrib/go/_std_1.21/src/debug/dwarf/typeunit.go
diff --git a/contrib/go/_std_1.20/src/debug/dwarf/unit.go b/contrib/go/_std_1.21/src/debug/dwarf/unit.go
index 8b810d0a00..8b810d0a00 100644
--- a/contrib/go/_std_1.20/src/debug/dwarf/unit.go
+++ b/contrib/go/_std_1.21/src/debug/dwarf/unit.go
diff --git a/contrib/go/_std_1.21/src/debug/dwarf/ya.make b/contrib/go/_std_1.21/src/debug/dwarf/ya.make
new file mode 100644
index 0000000000..d3a0f8bef1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/debug/dwarf/ya.make
@@ -0,0 +1,31 @@
+GO_LIBRARY()
+
+SRCS(
+ attr_string.go
+ buf.go
+ class_string.go
+ const.go
+ entry.go
+ line.go
+ open.go
+ tag_string.go
+ type.go
+ typeunit.go
+ unit.go
+)
+
+GO_TEST_SRCS(
+ dwarf5ranges_test.go
+ export_test.go
+)
+
+GO_XTEST_SRCS(
+ entry_test.go
+ line_test.go
+ type_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/debug/elf/elf.go b/contrib/go/_std_1.21/src/debug/elf/elf.go
new file mode 100644
index 0000000000..c982c684ba
--- /dev/null
+++ b/contrib/go/_std_1.21/src/debug/elf/elf.go
@@ -0,0 +1,3600 @@
+/*
+ * ELF constants and data structures
+ *
+ * Derived from:
+ * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
+ * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
+ * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
+ * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
+ * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
+ * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
+ * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
+ * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
+ * "System V ABI" (http://www.sco.com/developers/gabi/latest/ch4.eheader.html)
+ * "ELF for the ARM® 64-bit Architecture (AArch64)" (ARM IHI 0056B)
+ * "RISC-V ELF psABI specification" (https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc)
+ * llvm/BinaryFormat/ELF.h - ELF constants and structures
+ *
+ * Copyright (c) 1996-1998 John D. Polstra. All rights reserved.
+ * Copyright (c) 2001 David E. O'Brien
+ * Portions Copyright 2009 The Go Authors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+package elf
+
+import "strconv"
+
+/*
+ * Constants
+ */
+
+// Indexes into the Header.Ident array.
+const (
+ EI_CLASS = 4 /* Class of machine. */
+ EI_DATA = 5 /* Data format. */
+ EI_VERSION = 6 /* ELF format version. */
+ EI_OSABI = 7 /* Operating system / ABI identification */
+ EI_ABIVERSION = 8 /* ABI version */
+ EI_PAD = 9 /* Start of padding (per SVR4 ABI). */
+ EI_NIDENT = 16 /* Size of e_ident array. */
+)
+
+// Initial magic number for ELF files.
+const ELFMAG = "\177ELF"
+
+// Version is found in Header.Ident[EI_VERSION] and Header.Version.
+type Version byte
+
+const (
+ EV_NONE Version = 0
+ EV_CURRENT Version = 1
+)
+
+var versionStrings = []intName{
+ {0, "EV_NONE"},
+ {1, "EV_CURRENT"},
+}
+
+func (i Version) String() string { return stringName(uint32(i), versionStrings, false) }
+func (i Version) GoString() string { return stringName(uint32(i), versionStrings, true) }
+
+// Class is found in Header.Ident[EI_CLASS] and Header.Class.
+type Class byte
+
+const (
+ ELFCLASSNONE Class = 0 /* Unknown class. */
+ ELFCLASS32 Class = 1 /* 32-bit architecture. */
+ ELFCLASS64 Class = 2 /* 64-bit architecture. */
+)
+
+var classStrings = []intName{
+ {0, "ELFCLASSNONE"},
+ {1, "ELFCLASS32"},
+ {2, "ELFCLASS64"},
+}
+
+func (i Class) String() string { return stringName(uint32(i), classStrings, false) }
+func (i Class) GoString() string { return stringName(uint32(i), classStrings, true) }
+
+// Data is found in Header.Ident[EI_DATA] and Header.Data.
+type Data byte
+
+const (
+ ELFDATANONE Data = 0 /* Unknown data format. */
+ ELFDATA2LSB Data = 1 /* 2's complement little-endian. */
+ ELFDATA2MSB Data = 2 /* 2's complement big-endian. */
+)
+
+var dataStrings = []intName{
+ {0, "ELFDATANONE"},
+ {1, "ELFDATA2LSB"},
+ {2, "ELFDATA2MSB"},
+}
+
+func (i Data) String() string { return stringName(uint32(i), dataStrings, false) }
+func (i Data) GoString() string { return stringName(uint32(i), dataStrings, true) }
+
+// OSABI is found in Header.Ident[EI_OSABI] and Header.OSABI.
+type OSABI byte
+
+const (
+ ELFOSABI_NONE OSABI = 0 /* UNIX System V ABI */
+ ELFOSABI_HPUX OSABI = 1 /* HP-UX operating system */
+ ELFOSABI_NETBSD OSABI = 2 /* NetBSD */
+ ELFOSABI_LINUX OSABI = 3 /* Linux */
+ ELFOSABI_HURD OSABI = 4 /* Hurd */
+ ELFOSABI_86OPEN OSABI = 5 /* 86Open common IA32 ABI */
+ ELFOSABI_SOLARIS OSABI = 6 /* Solaris */
+ ELFOSABI_AIX OSABI = 7 /* AIX */
+ ELFOSABI_IRIX OSABI = 8 /* IRIX */
+ ELFOSABI_FREEBSD OSABI = 9 /* FreeBSD */
+ ELFOSABI_TRU64 OSABI = 10 /* TRU64 UNIX */
+ ELFOSABI_MODESTO OSABI = 11 /* Novell Modesto */
+ ELFOSABI_OPENBSD OSABI = 12 /* OpenBSD */
+ ELFOSABI_OPENVMS OSABI = 13 /* Open VMS */
+ ELFOSABI_NSK OSABI = 14 /* HP Non-Stop Kernel */
+ ELFOSABI_AROS OSABI = 15 /* Amiga Research OS */
+ ELFOSABI_FENIXOS OSABI = 16 /* The FenixOS highly scalable multi-core OS */
+ ELFOSABI_CLOUDABI OSABI = 17 /* Nuxi CloudABI */
+ ELFOSABI_ARM OSABI = 97 /* ARM */
+ ELFOSABI_STANDALONE OSABI = 255 /* Standalone (embedded) application */
+)
+
+var osabiStrings = []intName{
+ {0, "ELFOSABI_NONE"},
+ {1, "ELFOSABI_HPUX"},
+ {2, "ELFOSABI_NETBSD"},
+ {3, "ELFOSABI_LINUX"},
+ {4, "ELFOSABI_HURD"},
+ {5, "ELFOSABI_86OPEN"},
+ {6, "ELFOSABI_SOLARIS"},
+ {7, "ELFOSABI_AIX"},
+ {8, "ELFOSABI_IRIX"},
+ {9, "ELFOSABI_FREEBSD"},
+ {10, "ELFOSABI_TRU64"},
+ {11, "ELFOSABI_MODESTO"},
+ {12, "ELFOSABI_OPENBSD"},
+ {13, "ELFOSABI_OPENVMS"},
+ {14, "ELFOSABI_NSK"},
+ {15, "ELFOSABI_AROS"},
+ {16, "ELFOSABI_FENIXOS"},
+ {17, "ELFOSABI_CLOUDABI"},
+ {97, "ELFOSABI_ARM"},
+ {255, "ELFOSABI_STANDALONE"},
+}
+
+func (i OSABI) String() string { return stringName(uint32(i), osabiStrings, false) }
+func (i OSABI) GoString() string { return stringName(uint32(i), osabiStrings, true) }
+
+// Type is found in Header.Type.
+type Type uint16
+
+const (
+ ET_NONE Type = 0 /* Unknown type. */
+ ET_REL Type = 1 /* Relocatable. */
+ ET_EXEC Type = 2 /* Executable. */
+ ET_DYN Type = 3 /* Shared object. */
+ ET_CORE Type = 4 /* Core file. */
+ ET_LOOS Type = 0xfe00 /* First operating system specific. */
+ ET_HIOS Type = 0xfeff /* Last operating system-specific. */
+ ET_LOPROC Type = 0xff00 /* First processor-specific. */
+ ET_HIPROC Type = 0xffff /* Last processor-specific. */
+)
+
+var typeStrings = []intName{
+ {0, "ET_NONE"},
+ {1, "ET_REL"},
+ {2, "ET_EXEC"},
+ {3, "ET_DYN"},
+ {4, "ET_CORE"},
+ {0xfe00, "ET_LOOS"},
+ {0xfeff, "ET_HIOS"},
+ {0xff00, "ET_LOPROC"},
+ {0xffff, "ET_HIPROC"},
+}
+
+func (i Type) String() string { return stringName(uint32(i), typeStrings, false) }
+func (i Type) GoString() string { return stringName(uint32(i), typeStrings, true) }
+
+// Machine is found in Header.Machine.
+type Machine uint16
+
+const (
+ EM_NONE Machine = 0 /* Unknown machine. */
+ EM_M32 Machine = 1 /* AT&T WE32100. */
+ EM_SPARC Machine = 2 /* Sun SPARC. */
+ EM_386 Machine = 3 /* Intel i386. */
+ EM_68K Machine = 4 /* Motorola 68000. */
+ EM_88K Machine = 5 /* Motorola 88000. */
+ EM_860 Machine = 7 /* Intel i860. */
+ EM_MIPS Machine = 8 /* MIPS R3000 Big-Endian only. */
+ EM_S370 Machine = 9 /* IBM System/370. */
+ EM_MIPS_RS3_LE Machine = 10 /* MIPS R3000 Little-Endian. */
+ EM_PARISC Machine = 15 /* HP PA-RISC. */
+ EM_VPP500 Machine = 17 /* Fujitsu VPP500. */
+ EM_SPARC32PLUS Machine = 18 /* SPARC v8plus. */
+ EM_960 Machine = 19 /* Intel 80960. */
+ EM_PPC Machine = 20 /* PowerPC 32-bit. */
+ EM_PPC64 Machine = 21 /* PowerPC 64-bit. */
+ EM_S390 Machine = 22 /* IBM System/390. */
+ EM_V800 Machine = 36 /* NEC V800. */
+ EM_FR20 Machine = 37 /* Fujitsu FR20. */
+ EM_RH32 Machine = 38 /* TRW RH-32. */
+ EM_RCE Machine = 39 /* Motorola RCE. */
+ EM_ARM Machine = 40 /* ARM. */
+ EM_SH Machine = 42 /* Hitachi SH. */
+ EM_SPARCV9 Machine = 43 /* SPARC v9 64-bit. */
+ EM_TRICORE Machine = 44 /* Siemens TriCore embedded processor. */
+ EM_ARC Machine = 45 /* Argonaut RISC Core. */
+ EM_H8_300 Machine = 46 /* Hitachi H8/300. */
+ EM_H8_300H Machine = 47 /* Hitachi H8/300H. */
+ EM_H8S Machine = 48 /* Hitachi H8S. */
+ EM_H8_500 Machine = 49 /* Hitachi H8/500. */
+ EM_IA_64 Machine = 50 /* Intel IA-64 Processor. */
+ EM_MIPS_X Machine = 51 /* Stanford MIPS-X. */
+ EM_COLDFIRE Machine = 52 /* Motorola ColdFire. */
+ EM_68HC12 Machine = 53 /* Motorola M68HC12. */
+ EM_MMA Machine = 54 /* Fujitsu MMA. */
+ EM_PCP Machine = 55 /* Siemens PCP. */
+ EM_NCPU Machine = 56 /* Sony nCPU. */
+ EM_NDR1 Machine = 57 /* Denso NDR1 microprocessor. */
+ EM_STARCORE Machine = 58 /* Motorola Star*Core processor. */
+ EM_ME16 Machine = 59 /* Toyota ME16 processor. */
+ EM_ST100 Machine = 60 /* STMicroelectronics ST100 processor. */
+ EM_TINYJ Machine = 61 /* Advanced Logic Corp. TinyJ processor. */
+ EM_X86_64 Machine = 62 /* Advanced Micro Devices x86-64 */
+ EM_PDSP Machine = 63 /* Sony DSP Processor */
+ EM_PDP10 Machine = 64 /* Digital Equipment Corp. PDP-10 */
+ EM_PDP11 Machine = 65 /* Digital Equipment Corp. PDP-11 */
+ EM_FX66 Machine = 66 /* Siemens FX66 microcontroller */
+ EM_ST9PLUS Machine = 67 /* STMicroelectronics ST9+ 8/16 bit microcontroller */
+ EM_ST7 Machine = 68 /* STMicroelectronics ST7 8-bit microcontroller */
+ EM_68HC16 Machine = 69 /* Motorola MC68HC16 Microcontroller */
+ EM_68HC11 Machine = 70 /* Motorola MC68HC11 Microcontroller */
+ EM_68HC08 Machine = 71 /* Motorola MC68HC08 Microcontroller */
+ EM_68HC05 Machine = 72 /* Motorola MC68HC05 Microcontroller */
+ EM_SVX Machine = 73 /* Silicon Graphics SVx */
+ EM_ST19 Machine = 74 /* STMicroelectronics ST19 8-bit microcontroller */
+ EM_VAX Machine = 75 /* Digital VAX */
+ EM_CRIS Machine = 76 /* Axis Communications 32-bit embedded processor */
+ EM_JAVELIN Machine = 77 /* Infineon Technologies 32-bit embedded processor */
+ EM_FIREPATH Machine = 78 /* Element 14 64-bit DSP Processor */
+ EM_ZSP Machine = 79 /* LSI Logic 16-bit DSP Processor */
+ EM_MMIX Machine = 80 /* Donald Knuth's educational 64-bit processor */
+ EM_HUANY Machine = 81 /* Harvard University machine-independent object files */
+ EM_PRISM Machine = 82 /* SiTera Prism */
+ EM_AVR Machine = 83 /* Atmel AVR 8-bit microcontroller */
+ EM_FR30 Machine = 84 /* Fujitsu FR30 */
+ EM_D10V Machine = 85 /* Mitsubishi D10V */
+ EM_D30V Machine = 86 /* Mitsubishi D30V */
+ EM_V850 Machine = 87 /* NEC v850 */
+ EM_M32R Machine = 88 /* Mitsubishi M32R */
+ EM_MN10300 Machine = 89 /* Matsushita MN10300 */
+ EM_MN10200 Machine = 90 /* Matsushita MN10200 */
+ EM_PJ Machine = 91 /* picoJava */
+ EM_OPENRISC Machine = 92 /* OpenRISC 32-bit embedded processor */
+ EM_ARC_COMPACT Machine = 93 /* ARC International ARCompact processor (old spelling/synonym: EM_ARC_A5) */
+ EM_XTENSA Machine = 94 /* Tensilica Xtensa Architecture */
+ EM_VIDEOCORE Machine = 95 /* Alphamosaic VideoCore processor */
+ EM_TMM_GPP Machine = 96 /* Thompson Multimedia General Purpose Processor */
+ EM_NS32K Machine = 97 /* National Semiconductor 32000 series */
+ EM_TPC Machine = 98 /* Tenor Network TPC processor */
+ EM_SNP1K Machine = 99 /* Trebia SNP 1000 processor */
+ EM_ST200 Machine = 100 /* STMicroelectronics (www.st.com) ST200 microcontroller */
+ EM_IP2K Machine = 101 /* Ubicom IP2xxx microcontroller family */
+ EM_MAX Machine = 102 /* MAX Processor */
+ EM_CR Machine = 103 /* National Semiconductor CompactRISC microprocessor */
+ EM_F2MC16 Machine = 104 /* Fujitsu F2MC16 */
+ EM_MSP430 Machine = 105 /* Texas Instruments embedded microcontroller msp430 */
+ EM_BLACKFIN Machine = 106 /* Analog Devices Blackfin (DSP) processor */
+ EM_SE_C33 Machine = 107 /* S1C33 Family of Seiko Epson processors */
+ EM_SEP Machine = 108 /* Sharp embedded microprocessor */
+ EM_ARCA Machine = 109 /* Arca RISC Microprocessor */
+ EM_UNICORE Machine = 110 /* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University */
+ EM_EXCESS Machine = 111 /* eXcess: 16/32/64-bit configurable embedded CPU */
+ EM_DXP Machine = 112 /* Icera Semiconductor Inc. Deep Execution Processor */
+ EM_ALTERA_NIOS2 Machine = 113 /* Altera Nios II soft-core processor */
+ EM_CRX Machine = 114 /* National Semiconductor CompactRISC CRX microprocessor */
+ EM_XGATE Machine = 115 /* Motorola XGATE embedded processor */
+ EM_C166 Machine = 116 /* Infineon C16x/XC16x processor */
+ EM_M16C Machine = 117 /* Renesas M16C series microprocessors */
+ EM_DSPIC30F Machine = 118 /* Microchip Technology dsPIC30F Digital Signal Controller */
+ EM_CE Machine = 119 /* Freescale Communication Engine RISC core */
+ EM_M32C Machine = 120 /* Renesas M32C series microprocessors */
+ EM_TSK3000 Machine = 131 /* Altium TSK3000 core */
+ EM_RS08 Machine = 132 /* Freescale RS08 embedded processor */
+ EM_SHARC Machine = 133 /* Analog Devices SHARC family of 32-bit DSP processors */
+ EM_ECOG2 Machine = 134 /* Cyan Technology eCOG2 microprocessor */
+ EM_SCORE7 Machine = 135 /* Sunplus S+core7 RISC processor */
+ EM_DSP24 Machine = 136 /* New Japan Radio (NJR) 24-bit DSP Processor */
+ EM_VIDEOCORE3 Machine = 137 /* Broadcom VideoCore III processor */
+ EM_LATTICEMICO32 Machine = 138 /* RISC processor for Lattice FPGA architecture */
+ EM_SE_C17 Machine = 139 /* Seiko Epson C17 family */
+ EM_TI_C6000 Machine = 140 /* The Texas Instruments TMS320C6000 DSP family */
+ EM_TI_C2000 Machine = 141 /* The Texas Instruments TMS320C2000 DSP family */
+ EM_TI_C5500 Machine = 142 /* The Texas Instruments TMS320C55x DSP family */
+ EM_TI_ARP32 Machine = 143 /* Texas Instruments Application Specific RISC Processor, 32bit fetch */
+ EM_TI_PRU Machine = 144 /* Texas Instruments Programmable Realtime Unit */
+ EM_MMDSP_PLUS Machine = 160 /* STMicroelectronics 64bit VLIW Data Signal Processor */
+ EM_CYPRESS_M8C Machine = 161 /* Cypress M8C microprocessor */
+ EM_R32C Machine = 162 /* Renesas R32C series microprocessors */
+ EM_TRIMEDIA Machine = 163 /* NXP Semiconductors TriMedia architecture family */
+ EM_QDSP6 Machine = 164 /* QUALCOMM DSP6 Processor */
+ EM_8051 Machine = 165 /* Intel 8051 and variants */
+ EM_STXP7X Machine = 166 /* STMicroelectronics STxP7x family of configurable and extensible RISC processors */
+ EM_NDS32 Machine = 167 /* Andes Technology compact code size embedded RISC processor family */
+ EM_ECOG1 Machine = 168 /* Cyan Technology eCOG1X family */
+ EM_ECOG1X Machine = 168 /* Cyan Technology eCOG1X family */
+ EM_MAXQ30 Machine = 169 /* Dallas Semiconductor MAXQ30 Core Micro-controllers */
+ EM_XIMO16 Machine = 170 /* New Japan Radio (NJR) 16-bit DSP Processor */
+ EM_MANIK Machine = 171 /* M2000 Reconfigurable RISC Microprocessor */
+ EM_CRAYNV2 Machine = 172 /* Cray Inc. NV2 vector architecture */
+ EM_RX Machine = 173 /* Renesas RX family */
+ EM_METAG Machine = 174 /* Imagination Technologies META processor architecture */
+ EM_MCST_ELBRUS Machine = 175 /* MCST Elbrus general purpose hardware architecture */
+ EM_ECOG16 Machine = 176 /* Cyan Technology eCOG16 family */
+ EM_CR16 Machine = 177 /* National Semiconductor CompactRISC CR16 16-bit microprocessor */
+ EM_ETPU Machine = 178 /* Freescale Extended Time Processing Unit */
+ EM_SLE9X Machine = 179 /* Infineon Technologies SLE9X core */
+ EM_L10M Machine = 180 /* Intel L10M */
+ EM_K10M Machine = 181 /* Intel K10M */
+ EM_AARCH64 Machine = 183 /* ARM 64-bit Architecture (AArch64) */
+ EM_AVR32 Machine = 185 /* Atmel Corporation 32-bit microprocessor family */
+ EM_STM8 Machine = 186 /* STMicroeletronics STM8 8-bit microcontroller */
+ EM_TILE64 Machine = 187 /* Tilera TILE64 multicore architecture family */
+ EM_TILEPRO Machine = 188 /* Tilera TILEPro multicore architecture family */
+ EM_MICROBLAZE Machine = 189 /* Xilinx MicroBlaze 32-bit RISC soft processor core */
+ EM_CUDA Machine = 190 /* NVIDIA CUDA architecture */
+ EM_TILEGX Machine = 191 /* Tilera TILE-Gx multicore architecture family */
+ EM_CLOUDSHIELD Machine = 192 /* CloudShield architecture family */
+ EM_COREA_1ST Machine = 193 /* KIPO-KAIST Core-A 1st generation processor family */
+ EM_COREA_2ND Machine = 194 /* KIPO-KAIST Core-A 2nd generation processor family */
+ EM_ARC_COMPACT2 Machine = 195 /* Synopsys ARCompact V2 */
+ EM_OPEN8 Machine = 196 /* Open8 8-bit RISC soft processor core */
+ EM_RL78 Machine = 197 /* Renesas RL78 family */
+ EM_VIDEOCORE5 Machine = 198 /* Broadcom VideoCore V processor */
+ EM_78KOR Machine = 199 /* Renesas 78KOR family */
+ EM_56800EX Machine = 200 /* Freescale 56800EX Digital Signal Controller (DSC) */
+ EM_BA1 Machine = 201 /* Beyond BA1 CPU architecture */
+ EM_BA2 Machine = 202 /* Beyond BA2 CPU architecture */
+ EM_XCORE Machine = 203 /* XMOS xCORE processor family */
+ EM_MCHP_PIC Machine = 204 /* Microchip 8-bit PIC(r) family */
+ EM_INTEL205 Machine = 205 /* Reserved by Intel */
+ EM_INTEL206 Machine = 206 /* Reserved by Intel */
+ EM_INTEL207 Machine = 207 /* Reserved by Intel */
+ EM_INTEL208 Machine = 208 /* Reserved by Intel */
+ EM_INTEL209 Machine = 209 /* Reserved by Intel */
+ EM_KM32 Machine = 210 /* KM211 KM32 32-bit processor */
+ EM_KMX32 Machine = 211 /* KM211 KMX32 32-bit processor */
+ EM_KMX16 Machine = 212 /* KM211 KMX16 16-bit processor */
+ EM_KMX8 Machine = 213 /* KM211 KMX8 8-bit processor */
+ EM_KVARC Machine = 214 /* KM211 KVARC processor */
+ EM_CDP Machine = 215 /* Paneve CDP architecture family */
+ EM_COGE Machine = 216 /* Cognitive Smart Memory Processor */
+ EM_COOL Machine = 217 /* Bluechip Systems CoolEngine */
+ EM_NORC Machine = 218 /* Nanoradio Optimized RISC */
+ EM_CSR_KALIMBA Machine = 219 /* CSR Kalimba architecture family */
+ EM_Z80 Machine = 220 /* Zilog Z80 */
+ EM_VISIUM Machine = 221 /* Controls and Data Services VISIUMcore processor */
+ EM_FT32 Machine = 222 /* FTDI Chip FT32 high performance 32-bit RISC architecture */
+ EM_MOXIE Machine = 223 /* Moxie processor family */
+ EM_AMDGPU Machine = 224 /* AMD GPU architecture */
+ EM_RISCV Machine = 243 /* RISC-V */
+ EM_LANAI Machine = 244 /* Lanai 32-bit processor */
+ EM_BPF Machine = 247 /* Linux BPF – in-kernel virtual machine */
+ EM_LOONGARCH Machine = 258 /* LoongArch */
+
+ /* Non-standard or deprecated. */
+ EM_486 Machine = 6 /* Intel i486. */
+ EM_MIPS_RS4_BE Machine = 10 /* MIPS R4000 Big-Endian */
+ EM_ALPHA_STD Machine = 41 /* Digital Alpha (standard value). */
+ EM_ALPHA Machine = 0x9026 /* Alpha (written in the absence of an ABI) */
+)
+
+var machineStrings = []intName{
+ {0, "EM_NONE"},
+ {1, "EM_M32"},
+ {2, "EM_SPARC"},
+ {3, "EM_386"},
+ {4, "EM_68K"},
+ {5, "EM_88K"},
+ {7, "EM_860"},
+ {8, "EM_MIPS"},
+ {9, "EM_S370"},
+ {10, "EM_MIPS_RS3_LE"},
+ {15, "EM_PARISC"},
+ {17, "EM_VPP500"},
+ {18, "EM_SPARC32PLUS"},
+ {19, "EM_960"},
+ {20, "EM_PPC"},
+ {21, "EM_PPC64"},
+ {22, "EM_S390"},
+ {36, "EM_V800"},
+ {37, "EM_FR20"},
+ {38, "EM_RH32"},
+ {39, "EM_RCE"},
+ {40, "EM_ARM"},
+ {42, "EM_SH"},
+ {43, "EM_SPARCV9"},
+ {44, "EM_TRICORE"},
+ {45, "EM_ARC"},
+ {46, "EM_H8_300"},
+ {47, "EM_H8_300H"},
+ {48, "EM_H8S"},
+ {49, "EM_H8_500"},
+ {50, "EM_IA_64"},
+ {51, "EM_MIPS_X"},
+ {52, "EM_COLDFIRE"},
+ {53, "EM_68HC12"},
+ {54, "EM_MMA"},
+ {55, "EM_PCP"},
+ {56, "EM_NCPU"},
+ {57, "EM_NDR1"},
+ {58, "EM_STARCORE"},
+ {59, "EM_ME16"},
+ {60, "EM_ST100"},
+ {61, "EM_TINYJ"},
+ {62, "EM_X86_64"},
+ {63, "EM_PDSP"},
+ {64, "EM_PDP10"},
+ {65, "EM_PDP11"},
+ {66, "EM_FX66"},
+ {67, "EM_ST9PLUS"},
+ {68, "EM_ST7"},
+ {69, "EM_68HC16"},
+ {70, "EM_68HC11"},
+ {71, "EM_68HC08"},
+ {72, "EM_68HC05"},
+ {73, "EM_SVX"},
+ {74, "EM_ST19"},
+ {75, "EM_VAX"},
+ {76, "EM_CRIS"},
+ {77, "EM_JAVELIN"},
+ {78, "EM_FIREPATH"},
+ {79, "EM_ZSP"},
+ {80, "EM_MMIX"},
+ {81, "EM_HUANY"},
+ {82, "EM_PRISM"},
+ {83, "EM_AVR"},
+ {84, "EM_FR30"},
+ {85, "EM_D10V"},
+ {86, "EM_D30V"},
+ {87, "EM_V850"},
+ {88, "EM_M32R"},
+ {89, "EM_MN10300"},
+ {90, "EM_MN10200"},
+ {91, "EM_PJ"},
+ {92, "EM_OPENRISC"},
+ {93, "EM_ARC_COMPACT"},
+ {94, "EM_XTENSA"},
+ {95, "EM_VIDEOCORE"},
+ {96, "EM_TMM_GPP"},
+ {97, "EM_NS32K"},
+ {98, "EM_TPC"},
+ {99, "EM_SNP1K"},
+ {100, "EM_ST200"},
+ {101, "EM_IP2K"},
+ {102, "EM_MAX"},
+ {103, "EM_CR"},
+ {104, "EM_F2MC16"},
+ {105, "EM_MSP430"},
+ {106, "EM_BLACKFIN"},
+ {107, "EM_SE_C33"},
+ {108, "EM_SEP"},
+ {109, "EM_ARCA"},
+ {110, "EM_UNICORE"},
+ {111, "EM_EXCESS"},
+ {112, "EM_DXP"},
+ {113, "EM_ALTERA_NIOS2"},
+ {114, "EM_CRX"},
+ {115, "EM_XGATE"},
+ {116, "EM_C166"},
+ {117, "EM_M16C"},
+ {118, "EM_DSPIC30F"},
+ {119, "EM_CE"},
+ {120, "EM_M32C"},
+ {131, "EM_TSK3000"},
+ {132, "EM_RS08"},
+ {133, "EM_SHARC"},
+ {134, "EM_ECOG2"},
+ {135, "EM_SCORE7"},
+ {136, "EM_DSP24"},
+ {137, "EM_VIDEOCORE3"},
+ {138, "EM_LATTICEMICO32"},
+ {139, "EM_SE_C17"},
+ {140, "EM_TI_C6000"},
+ {141, "EM_TI_C2000"},
+ {142, "EM_TI_C5500"},
+ {143, "EM_TI_ARP32"},
+ {144, "EM_TI_PRU"},
+ {160, "EM_MMDSP_PLUS"},
+ {161, "EM_CYPRESS_M8C"},
+ {162, "EM_R32C"},
+ {163, "EM_TRIMEDIA"},
+ {164, "EM_QDSP6"},
+ {165, "EM_8051"},
+ {166, "EM_STXP7X"},
+ {167, "EM_NDS32"},
+ {168, "EM_ECOG1"},
+ {168, "EM_ECOG1X"},
+ {169, "EM_MAXQ30"},
+ {170, "EM_XIMO16"},
+ {171, "EM_MANIK"},
+ {172, "EM_CRAYNV2"},
+ {173, "EM_RX"},
+ {174, "EM_METAG"},
+ {175, "EM_MCST_ELBRUS"},
+ {176, "EM_ECOG16"},
+ {177, "EM_CR16"},
+ {178, "EM_ETPU"},
+ {179, "EM_SLE9X"},
+ {180, "EM_L10M"},
+ {181, "EM_K10M"},
+ {183, "EM_AARCH64"},
+ {185, "EM_AVR32"},
+ {186, "EM_STM8"},
+ {187, "EM_TILE64"},
+ {188, "EM_TILEPRO"},
+ {189, "EM_MICROBLAZE"},
+ {190, "EM_CUDA"},
+ {191, "EM_TILEGX"},
+ {192, "EM_CLOUDSHIELD"},
+ {193, "EM_COREA_1ST"},
+ {194, "EM_COREA_2ND"},
+ {195, "EM_ARC_COMPACT2"},
+ {196, "EM_OPEN8"},
+ {197, "EM_RL78"},
+ {198, "EM_VIDEOCORE5"},
+ {199, "EM_78KOR"},
+ {200, "EM_56800EX"},
+ {201, "EM_BA1"},
+ {202, "EM_BA2"},
+ {203, "EM_XCORE"},
+ {204, "EM_MCHP_PIC"},
+ {205, "EM_INTEL205"},
+ {206, "EM_INTEL206"},
+ {207, "EM_INTEL207"},
+ {208, "EM_INTEL208"},
+ {209, "EM_INTEL209"},
+ {210, "EM_KM32"},
+ {211, "EM_KMX32"},
+ {212, "EM_KMX16"},
+ {213, "EM_KMX8"},
+ {214, "EM_KVARC"},
+ {215, "EM_CDP"},
+ {216, "EM_COGE"},
+ {217, "EM_COOL"},
+ {218, "EM_NORC"},
+ {219, "EM_CSR_KALIMBA "},
+ {220, "EM_Z80 "},
+ {221, "EM_VISIUM "},
+ {222, "EM_FT32 "},
+ {223, "EM_MOXIE"},
+ {224, "EM_AMDGPU"},
+ {243, "EM_RISCV"},
+ {244, "EM_LANAI"},
+ {247, "EM_BPF"},
+ {258, "EM_LOONGARCH"},
+
+ /* Non-standard or deprecated. */
+ {6, "EM_486"},
+ {10, "EM_MIPS_RS4_BE"},
+ {41, "EM_ALPHA_STD"},
+ {0x9026, "EM_ALPHA"},
+}
+
+func (i Machine) String() string { return stringName(uint32(i), machineStrings, false) }
+func (i Machine) GoString() string { return stringName(uint32(i), machineStrings, true) }
+
+// Special section indices.
+type SectionIndex int
+
+const (
+ SHN_UNDEF SectionIndex = 0 /* Undefined, missing, irrelevant. */
+ SHN_LORESERVE SectionIndex = 0xff00 /* First of reserved range. */
+ SHN_LOPROC SectionIndex = 0xff00 /* First processor-specific. */
+ SHN_HIPROC SectionIndex = 0xff1f /* Last processor-specific. */
+ SHN_LOOS SectionIndex = 0xff20 /* First operating system-specific. */
+ SHN_HIOS SectionIndex = 0xff3f /* Last operating system-specific. */
+ SHN_ABS SectionIndex = 0xfff1 /* Absolute values. */
+ SHN_COMMON SectionIndex = 0xfff2 /* Common data. */
+ SHN_XINDEX SectionIndex = 0xffff /* Escape; index stored elsewhere. */
+ SHN_HIRESERVE SectionIndex = 0xffff /* Last of reserved range. */
+)
+
+var shnStrings = []intName{
+ {0, "SHN_UNDEF"},
+ {0xff00, "SHN_LOPROC"},
+ {0xff20, "SHN_LOOS"},
+ {0xfff1, "SHN_ABS"},
+ {0xfff2, "SHN_COMMON"},
+ {0xffff, "SHN_XINDEX"},
+}
+
+func (i SectionIndex) String() string { return stringName(uint32(i), shnStrings, false) }
+func (i SectionIndex) GoString() string { return stringName(uint32(i), shnStrings, true) }
+
+// Section type.
+type SectionType uint32
+
+const (
+ SHT_NULL SectionType = 0 /* inactive */
+ SHT_PROGBITS SectionType = 1 /* program defined information */
+ SHT_SYMTAB SectionType = 2 /* symbol table section */
+ SHT_STRTAB SectionType = 3 /* string table section */
+ SHT_RELA SectionType = 4 /* relocation section with addends */
+ SHT_HASH SectionType = 5 /* symbol hash table section */
+ SHT_DYNAMIC SectionType = 6 /* dynamic section */
+ SHT_NOTE SectionType = 7 /* note section */
+ SHT_NOBITS SectionType = 8 /* no space section */
+ SHT_REL SectionType = 9 /* relocation section - no addends */
+ SHT_SHLIB SectionType = 10 /* reserved - purpose unknown */
+ SHT_DYNSYM SectionType = 11 /* dynamic symbol table section */
+ SHT_INIT_ARRAY SectionType = 14 /* Initialization function pointers. */
+ SHT_FINI_ARRAY SectionType = 15 /* Termination function pointers. */
+ SHT_PREINIT_ARRAY SectionType = 16 /* Pre-initialization function ptrs. */
+ SHT_GROUP SectionType = 17 /* Section group. */
+ SHT_SYMTAB_SHNDX SectionType = 18 /* Section indexes (see SHN_XINDEX). */
+ SHT_LOOS SectionType = 0x60000000 /* First of OS specific semantics */
+ SHT_GNU_ATTRIBUTES SectionType = 0x6ffffff5 /* GNU object attributes */
+ SHT_GNU_HASH SectionType = 0x6ffffff6 /* GNU hash table */
+ SHT_GNU_LIBLIST SectionType = 0x6ffffff7 /* GNU prelink library list */
+ SHT_GNU_VERDEF SectionType = 0x6ffffffd /* GNU version definition section */
+ SHT_GNU_VERNEED SectionType = 0x6ffffffe /* GNU version needs section */
+ SHT_GNU_VERSYM SectionType = 0x6fffffff /* GNU version symbol table */
+ SHT_HIOS SectionType = 0x6fffffff /* Last of OS specific semantics */
+ SHT_LOPROC SectionType = 0x70000000 /* reserved range for processor */
+ SHT_MIPS_ABIFLAGS SectionType = 0x7000002a /* .MIPS.abiflags */
+ SHT_HIPROC SectionType = 0x7fffffff /* specific section header types */
+ SHT_LOUSER SectionType = 0x80000000 /* reserved range for application */
+ SHT_HIUSER SectionType = 0xffffffff /* specific indexes */
+)
+
+var shtStrings = []intName{
+ {0, "SHT_NULL"},
+ {1, "SHT_PROGBITS"},
+ {2, "SHT_SYMTAB"},
+ {3, "SHT_STRTAB"},
+ {4, "SHT_RELA"},
+ {5, "SHT_HASH"},
+ {6, "SHT_DYNAMIC"},
+ {7, "SHT_NOTE"},
+ {8, "SHT_NOBITS"},
+ {9, "SHT_REL"},
+ {10, "SHT_SHLIB"},
+ {11, "SHT_DYNSYM"},
+ {14, "SHT_INIT_ARRAY"},
+ {15, "SHT_FINI_ARRAY"},
+ {16, "SHT_PREINIT_ARRAY"},
+ {17, "SHT_GROUP"},
+ {18, "SHT_SYMTAB_SHNDX"},
+ {0x60000000, "SHT_LOOS"},
+ {0x6ffffff5, "SHT_GNU_ATTRIBUTES"},
+ {0x6ffffff6, "SHT_GNU_HASH"},
+ {0x6ffffff7, "SHT_GNU_LIBLIST"},
+ {0x6ffffffd, "SHT_GNU_VERDEF"},
+ {0x6ffffffe, "SHT_GNU_VERNEED"},
+ {0x6fffffff, "SHT_GNU_VERSYM"},
+ {0x70000000, "SHT_LOPROC"},
+ {0x7000002a, "SHT_MIPS_ABIFLAGS"},
+ {0x7fffffff, "SHT_HIPROC"},
+ {0x80000000, "SHT_LOUSER"},
+ {0xffffffff, "SHT_HIUSER"},
+}
+
+func (i SectionType) String() string { return stringName(uint32(i), shtStrings, false) }
+func (i SectionType) GoString() string { return stringName(uint32(i), shtStrings, true) }
+
+// Section flags.
+type SectionFlag uint32
+
+const (
+ SHF_WRITE SectionFlag = 0x1 /* Section contains writable data. */
+ SHF_ALLOC SectionFlag = 0x2 /* Section occupies memory. */
+ SHF_EXECINSTR SectionFlag = 0x4 /* Section contains instructions. */
+ SHF_MERGE SectionFlag = 0x10 /* Section may be merged. */
+ SHF_STRINGS SectionFlag = 0x20 /* Section contains strings. */
+ SHF_INFO_LINK SectionFlag = 0x40 /* sh_info holds section index. */
+ SHF_LINK_ORDER SectionFlag = 0x80 /* Special ordering requirements. */
+ SHF_OS_NONCONFORMING SectionFlag = 0x100 /* OS-specific processing required. */
+ SHF_GROUP SectionFlag = 0x200 /* Member of section group. */
+ SHF_TLS SectionFlag = 0x400 /* Section contains TLS data. */
+ SHF_COMPRESSED SectionFlag = 0x800 /* Section is compressed. */
+ SHF_MASKOS SectionFlag = 0x0ff00000 /* OS-specific semantics. */
+ SHF_MASKPROC SectionFlag = 0xf0000000 /* Processor-specific semantics. */
+)
+
+var shfStrings = []intName{
+ {0x1, "SHF_WRITE"},
+ {0x2, "SHF_ALLOC"},
+ {0x4, "SHF_EXECINSTR"},
+ {0x10, "SHF_MERGE"},
+ {0x20, "SHF_STRINGS"},
+ {0x40, "SHF_INFO_LINK"},
+ {0x80, "SHF_LINK_ORDER"},
+ {0x100, "SHF_OS_NONCONFORMING"},
+ {0x200, "SHF_GROUP"},
+ {0x400, "SHF_TLS"},
+ {0x800, "SHF_COMPRESSED"},
+}
+
+func (i SectionFlag) String() string { return flagName(uint32(i), shfStrings, false) }
+func (i SectionFlag) GoString() string { return flagName(uint32(i), shfStrings, true) }
+
+// Section compression type.
+type CompressionType int
+
+const (
+ COMPRESS_ZLIB CompressionType = 1 /* ZLIB compression. */
+ COMPRESS_ZSTD CompressionType = 2 /* ZSTD compression. */
+ COMPRESS_LOOS CompressionType = 0x60000000 /* First OS-specific. */
+ COMPRESS_HIOS CompressionType = 0x6fffffff /* Last OS-specific. */
+ COMPRESS_LOPROC CompressionType = 0x70000000 /* First processor-specific type. */
+ COMPRESS_HIPROC CompressionType = 0x7fffffff /* Last processor-specific type. */
+)
+
+var compressionStrings = []intName{
+ {1, "COMPRESS_ZLIB"},
+ {2, "COMPRESS_ZSTD"},
+ {0x60000000, "COMPRESS_LOOS"},
+ {0x6fffffff, "COMPRESS_HIOS"},
+ {0x70000000, "COMPRESS_LOPROC"},
+ {0x7fffffff, "COMPRESS_HIPROC"},
+}
+
+func (i CompressionType) String() string { return stringName(uint32(i), compressionStrings, false) }
+func (i CompressionType) GoString() string { return stringName(uint32(i), compressionStrings, true) }
+
+// Prog.Type
+type ProgType int
+
+const (
+ PT_NULL ProgType = 0 /* Unused entry. */
+ PT_LOAD ProgType = 1 /* Loadable segment. */
+ PT_DYNAMIC ProgType = 2 /* Dynamic linking information segment. */
+ PT_INTERP ProgType = 3 /* Pathname of interpreter. */
+ PT_NOTE ProgType = 4 /* Auxiliary information. */
+ PT_SHLIB ProgType = 5 /* Reserved (not used). */
+ PT_PHDR ProgType = 6 /* Location of program header itself. */
+ PT_TLS ProgType = 7 /* Thread local storage segment */
+
+ PT_LOOS ProgType = 0x60000000 /* First OS-specific. */
+
+ PT_GNU_EH_FRAME ProgType = 0x6474e550 /* Frame unwind information */
+ PT_GNU_STACK ProgType = 0x6474e551 /* Stack flags */
+ PT_GNU_RELRO ProgType = 0x6474e552 /* Read only after relocs */
+ PT_GNU_PROPERTY ProgType = 0x6474e553 /* GNU property */
+ PT_GNU_MBIND_LO ProgType = 0x6474e555 /* Mbind segments start */
+ PT_GNU_MBIND_HI ProgType = 0x6474f554 /* Mbind segments finish */
+
+ PT_PAX_FLAGS ProgType = 0x65041580 /* PAX flags */
+
+ PT_OPENBSD_RANDOMIZE ProgType = 0x65a3dbe6 /* Random data */
+ PT_OPENBSD_WXNEEDED ProgType = 0x65a3dbe7 /* W^X violations */
+ PT_OPENBSD_BOOTDATA ProgType = 0x65a41be6 /* Boot arguments */
+
+ PT_SUNW_EH_FRAME ProgType = 0x6474e550 /* Frame unwind information */
+ PT_SUNWSTACK ProgType = 0x6ffffffb /* Stack segment */
+
+ PT_HIOS ProgType = 0x6fffffff /* Last OS-specific. */
+
+ PT_LOPROC ProgType = 0x70000000 /* First processor-specific type. */
+
+ PT_ARM_ARCHEXT ProgType = 0x70000000 /* Architecture compatibility */
+ PT_ARM_EXIDX ProgType = 0x70000001 /* Exception unwind tables */
+
+ PT_AARCH64_ARCHEXT ProgType = 0x70000000 /* Architecture compatibility */
+ PT_AARCH64_UNWIND ProgType = 0x70000001 /* Exception unwind tables */
+
+ PT_MIPS_REGINFO ProgType = 0x70000000 /* Register usage */
+ PT_MIPS_RTPROC ProgType = 0x70000001 /* Runtime procedures */
+ PT_MIPS_OPTIONS ProgType = 0x70000002 /* Options */
+ PT_MIPS_ABIFLAGS ProgType = 0x70000003 /* ABI flags */
+
+ PT_S390_PGSTE ProgType = 0x70000000 /* 4k page table size */
+
+ PT_HIPROC ProgType = 0x7fffffff /* Last processor-specific type. */
+)
+
+var ptStrings = []intName{
+ {0, "PT_NULL"},
+ {1, "PT_LOAD"},
+ {2, "PT_DYNAMIC"},
+ {3, "PT_INTERP"},
+ {4, "PT_NOTE"},
+ {5, "PT_SHLIB"},
+ {6, "PT_PHDR"},
+ {7, "PT_TLS"},
+ {0x60000000, "PT_LOOS"},
+ {0x6474e550, "PT_GNU_EH_FRAME"},
+ {0x6474e551, "PT_GNU_STACK"},
+ {0x6474e552, "PT_GNU_RELRO"},
+ {0x6474e553, "PT_GNU_PROPERTY"},
+ {0x65041580, "PT_PAX_FLAGS"},
+ {0x65a3dbe6, "PT_OPENBSD_RANDOMIZE"},
+ {0x65a3dbe7, "PT_OPENBSD_WXNEEDED"},
+ {0x65a41be6, "PT_OPENBSD_BOOTDATA"},
+ {0x6ffffffb, "PT_SUNWSTACK"},
+ {0x6fffffff, "PT_HIOS"},
+ {0x70000000, "PT_LOPROC"},
+ // We don't list the processor-dependent ProgTypes,
+ // as the values overlap.
+ {0x7fffffff, "PT_HIPROC"},
+}
+
+func (i ProgType) String() string { return stringName(uint32(i), ptStrings, false) }
+func (i ProgType) GoString() string { return stringName(uint32(i), ptStrings, true) }
+
+// Prog.Flag
+type ProgFlag uint32
+
+const (
+ PF_X ProgFlag = 0x1 /* Executable. */
+ PF_W ProgFlag = 0x2 /* Writable. */
+ PF_R ProgFlag = 0x4 /* Readable. */
+ PF_MASKOS ProgFlag = 0x0ff00000 /* Operating system-specific. */
+ PF_MASKPROC ProgFlag = 0xf0000000 /* Processor-specific. */
+)
+
+var pfStrings = []intName{
+ {0x1, "PF_X"},
+ {0x2, "PF_W"},
+ {0x4, "PF_R"},
+}
+
+func (i ProgFlag) String() string { return flagName(uint32(i), pfStrings, false) }
+func (i ProgFlag) GoString() string { return flagName(uint32(i), pfStrings, true) }
+
+// Dyn.Tag
+type DynTag int
+
+const (
+ DT_NULL DynTag = 0 /* Terminating entry. */
+ DT_NEEDED DynTag = 1 /* String table offset of a needed shared library. */
+ DT_PLTRELSZ DynTag = 2 /* Total size in bytes of PLT relocations. */
+ DT_PLTGOT DynTag = 3 /* Processor-dependent address. */
+ DT_HASH DynTag = 4 /* Address of symbol hash table. */
+ DT_STRTAB DynTag = 5 /* Address of string table. */
+ DT_SYMTAB DynTag = 6 /* Address of symbol table. */
+ DT_RELA DynTag = 7 /* Address of ElfNN_Rela relocations. */
+ DT_RELASZ DynTag = 8 /* Total size of ElfNN_Rela relocations. */
+ DT_RELAENT DynTag = 9 /* Size of each ElfNN_Rela relocation entry. */
+ DT_STRSZ DynTag = 10 /* Size of string table. */
+ DT_SYMENT DynTag = 11 /* Size of each symbol table entry. */
+ DT_INIT DynTag = 12 /* Address of initialization function. */
+ DT_FINI DynTag = 13 /* Address of finalization function. */
+ DT_SONAME DynTag = 14 /* String table offset of shared object name. */
+ DT_RPATH DynTag = 15 /* String table offset of library path. [sup] */
+ DT_SYMBOLIC DynTag = 16 /* Indicates "symbolic" linking. [sup] */
+ DT_REL DynTag = 17 /* Address of ElfNN_Rel relocations. */
+ DT_RELSZ DynTag = 18 /* Total size of ElfNN_Rel relocations. */
+ DT_RELENT DynTag = 19 /* Size of each ElfNN_Rel relocation. */
+ DT_PLTREL DynTag = 20 /* Type of relocation used for PLT. */
+ DT_DEBUG DynTag = 21 /* Reserved (not used). */
+ DT_TEXTREL DynTag = 22 /* Indicates there may be relocations in non-writable segments. [sup] */
+ DT_JMPREL DynTag = 23 /* Address of PLT relocations. */
+ DT_BIND_NOW DynTag = 24 /* [sup] */
+ DT_INIT_ARRAY DynTag = 25 /* Address of the array of pointers to initialization functions */
+ DT_FINI_ARRAY DynTag = 26 /* Address of the array of pointers to termination functions */
+ DT_INIT_ARRAYSZ DynTag = 27 /* Size in bytes of the array of initialization functions. */
+ DT_FINI_ARRAYSZ DynTag = 28 /* Size in bytes of the array of termination functions. */
+ DT_RUNPATH DynTag = 29 /* String table offset of a null-terminated library search path string. */
+ DT_FLAGS DynTag = 30 /* Object specific flag values. */
+ DT_ENCODING DynTag = 32 /* Values greater than or equal to DT_ENCODING
+ and less than DT_LOOS follow the rules for
+ the interpretation of the d_un union
+ as follows: even == 'd_ptr', even == 'd_val'
+ or none */
+ DT_PREINIT_ARRAY DynTag = 32 /* Address of the array of pointers to pre-initialization functions. */
+ DT_PREINIT_ARRAYSZ DynTag = 33 /* Size in bytes of the array of pre-initialization functions. */
+ DT_SYMTAB_SHNDX DynTag = 34 /* Address of SHT_SYMTAB_SHNDX section. */
+
+ DT_LOOS DynTag = 0x6000000d /* First OS-specific */
+ DT_HIOS DynTag = 0x6ffff000 /* Last OS-specific */
+
+ DT_VALRNGLO DynTag = 0x6ffffd00
+ DT_GNU_PRELINKED DynTag = 0x6ffffdf5
+ DT_GNU_CONFLICTSZ DynTag = 0x6ffffdf6
+ DT_GNU_LIBLISTSZ DynTag = 0x6ffffdf7
+ DT_CHECKSUM DynTag = 0x6ffffdf8
+ DT_PLTPADSZ DynTag = 0x6ffffdf9
+ DT_MOVEENT DynTag = 0x6ffffdfa
+ DT_MOVESZ DynTag = 0x6ffffdfb
+ DT_FEATURE DynTag = 0x6ffffdfc
+ DT_POSFLAG_1 DynTag = 0x6ffffdfd
+ DT_SYMINSZ DynTag = 0x6ffffdfe
+ DT_SYMINENT DynTag = 0x6ffffdff
+ DT_VALRNGHI DynTag = 0x6ffffdff
+
+ DT_ADDRRNGLO DynTag = 0x6ffffe00
+ DT_GNU_HASH DynTag = 0x6ffffef5
+ DT_TLSDESC_PLT DynTag = 0x6ffffef6
+ DT_TLSDESC_GOT DynTag = 0x6ffffef7
+ DT_GNU_CONFLICT DynTag = 0x6ffffef8
+ DT_GNU_LIBLIST DynTag = 0x6ffffef9
+ DT_CONFIG DynTag = 0x6ffffefa
+ DT_DEPAUDIT DynTag = 0x6ffffefb
+ DT_AUDIT DynTag = 0x6ffffefc
+ DT_PLTPAD DynTag = 0x6ffffefd
+ DT_MOVETAB DynTag = 0x6ffffefe
+ DT_SYMINFO DynTag = 0x6ffffeff
+ DT_ADDRRNGHI DynTag = 0x6ffffeff
+
+ DT_VERSYM DynTag = 0x6ffffff0
+ DT_RELACOUNT DynTag = 0x6ffffff9
+ DT_RELCOUNT DynTag = 0x6ffffffa
+ DT_FLAGS_1 DynTag = 0x6ffffffb
+ DT_VERDEF DynTag = 0x6ffffffc
+ DT_VERDEFNUM DynTag = 0x6ffffffd
+ DT_VERNEED DynTag = 0x6ffffffe
+ DT_VERNEEDNUM DynTag = 0x6fffffff
+
+ DT_LOPROC DynTag = 0x70000000 /* First processor-specific type. */
+
+ DT_MIPS_RLD_VERSION DynTag = 0x70000001
+ DT_MIPS_TIME_STAMP DynTag = 0x70000002
+ DT_MIPS_ICHECKSUM DynTag = 0x70000003
+ DT_MIPS_IVERSION DynTag = 0x70000004
+ DT_MIPS_FLAGS DynTag = 0x70000005
+ DT_MIPS_BASE_ADDRESS DynTag = 0x70000006
+ DT_MIPS_MSYM DynTag = 0x70000007
+ DT_MIPS_CONFLICT DynTag = 0x70000008
+ DT_MIPS_LIBLIST DynTag = 0x70000009
+ DT_MIPS_LOCAL_GOTNO DynTag = 0x7000000a
+ DT_MIPS_CONFLICTNO DynTag = 0x7000000b
+ DT_MIPS_LIBLISTNO DynTag = 0x70000010
+ DT_MIPS_SYMTABNO DynTag = 0x70000011
+ DT_MIPS_UNREFEXTNO DynTag = 0x70000012
+ DT_MIPS_GOTSYM DynTag = 0x70000013
+ DT_MIPS_HIPAGENO DynTag = 0x70000014
+ DT_MIPS_RLD_MAP DynTag = 0x70000016
+ DT_MIPS_DELTA_CLASS DynTag = 0x70000017
+ DT_MIPS_DELTA_CLASS_NO DynTag = 0x70000018
+ DT_MIPS_DELTA_INSTANCE DynTag = 0x70000019
+ DT_MIPS_DELTA_INSTANCE_NO DynTag = 0x7000001a
+ DT_MIPS_DELTA_RELOC DynTag = 0x7000001b
+ DT_MIPS_DELTA_RELOC_NO DynTag = 0x7000001c
+ DT_MIPS_DELTA_SYM DynTag = 0x7000001d
+ DT_MIPS_DELTA_SYM_NO DynTag = 0x7000001e
+ DT_MIPS_DELTA_CLASSSYM DynTag = 0x70000020
+ DT_MIPS_DELTA_CLASSSYM_NO DynTag = 0x70000021
+ DT_MIPS_CXX_FLAGS DynTag = 0x70000022
+ DT_MIPS_PIXIE_INIT DynTag = 0x70000023
+ DT_MIPS_SYMBOL_LIB DynTag = 0x70000024
+ DT_MIPS_LOCALPAGE_GOTIDX DynTag = 0x70000025
+ DT_MIPS_LOCAL_GOTIDX DynTag = 0x70000026
+ DT_MIPS_HIDDEN_GOTIDX DynTag = 0x70000027
+ DT_MIPS_PROTECTED_GOTIDX DynTag = 0x70000028
+ DT_MIPS_OPTIONS DynTag = 0x70000029
+ DT_MIPS_INTERFACE DynTag = 0x7000002a
+ DT_MIPS_DYNSTR_ALIGN DynTag = 0x7000002b
+ DT_MIPS_INTERFACE_SIZE DynTag = 0x7000002c
+ DT_MIPS_RLD_TEXT_RESOLVE_ADDR DynTag = 0x7000002d
+ DT_MIPS_PERF_SUFFIX DynTag = 0x7000002e
+ DT_MIPS_COMPACT_SIZE DynTag = 0x7000002f
+ DT_MIPS_GP_VALUE DynTag = 0x70000030
+ DT_MIPS_AUX_DYNAMIC DynTag = 0x70000031
+ DT_MIPS_PLTGOT DynTag = 0x70000032
+ DT_MIPS_RWPLT DynTag = 0x70000034
+ DT_MIPS_RLD_MAP_REL DynTag = 0x70000035
+
+ DT_PPC_GOT DynTag = 0x70000000
+ DT_PPC_OPT DynTag = 0x70000001
+
+ DT_PPC64_GLINK DynTag = 0x70000000
+ DT_PPC64_OPD DynTag = 0x70000001
+ DT_PPC64_OPDSZ DynTag = 0x70000002
+ DT_PPC64_OPT DynTag = 0x70000003
+
+ DT_SPARC_REGISTER DynTag = 0x70000001
+
+ DT_AUXILIARY DynTag = 0x7ffffffd
+ DT_USED DynTag = 0x7ffffffe
+ DT_FILTER DynTag = 0x7fffffff
+
+ DT_HIPROC DynTag = 0x7fffffff /* Last processor-specific type. */
+)
+
+var dtStrings = []intName{
+ {0, "DT_NULL"},
+ {1, "DT_NEEDED"},
+ {2, "DT_PLTRELSZ"},
+ {3, "DT_PLTGOT"},
+ {4, "DT_HASH"},
+ {5, "DT_STRTAB"},
+ {6, "DT_SYMTAB"},
+ {7, "DT_RELA"},
+ {8, "DT_RELASZ"},
+ {9, "DT_RELAENT"},
+ {10, "DT_STRSZ"},
+ {11, "DT_SYMENT"},
+ {12, "DT_INIT"},
+ {13, "DT_FINI"},
+ {14, "DT_SONAME"},
+ {15, "DT_RPATH"},
+ {16, "DT_SYMBOLIC"},
+ {17, "DT_REL"},
+ {18, "DT_RELSZ"},
+ {19, "DT_RELENT"},
+ {20, "DT_PLTREL"},
+ {21, "DT_DEBUG"},
+ {22, "DT_TEXTREL"},
+ {23, "DT_JMPREL"},
+ {24, "DT_BIND_NOW"},
+ {25, "DT_INIT_ARRAY"},
+ {26, "DT_FINI_ARRAY"},
+ {27, "DT_INIT_ARRAYSZ"},
+ {28, "DT_FINI_ARRAYSZ"},
+ {29, "DT_RUNPATH"},
+ {30, "DT_FLAGS"},
+ {32, "DT_ENCODING"},
+ {32, "DT_PREINIT_ARRAY"},
+ {33, "DT_PREINIT_ARRAYSZ"},
+ {34, "DT_SYMTAB_SHNDX"},
+ {0x6000000d, "DT_LOOS"},
+ {0x6ffff000, "DT_HIOS"},
+ {0x6ffffd00, "DT_VALRNGLO"},
+ {0x6ffffdf5, "DT_GNU_PRELINKED"},
+ {0x6ffffdf6, "DT_GNU_CONFLICTSZ"},
+ {0x6ffffdf7, "DT_GNU_LIBLISTSZ"},
+ {0x6ffffdf8, "DT_CHECKSUM"},
+ {0x6ffffdf9, "DT_PLTPADSZ"},
+ {0x6ffffdfa, "DT_MOVEENT"},
+ {0x6ffffdfb, "DT_MOVESZ"},
+ {0x6ffffdfc, "DT_FEATURE"},
+ {0x6ffffdfd, "DT_POSFLAG_1"},
+ {0x6ffffdfe, "DT_SYMINSZ"},
+ {0x6ffffdff, "DT_SYMINENT"},
+ {0x6ffffdff, "DT_VALRNGHI"},
+ {0x6ffffe00, "DT_ADDRRNGLO"},
+ {0x6ffffef5, "DT_GNU_HASH"},
+ {0x6ffffef6, "DT_TLSDESC_PLT"},
+ {0x6ffffef7, "DT_TLSDESC_GOT"},
+ {0x6ffffef8, "DT_GNU_CONFLICT"},
+ {0x6ffffef9, "DT_GNU_LIBLIST"},
+ {0x6ffffefa, "DT_CONFIG"},
+ {0x6ffffefb, "DT_DEPAUDIT"},
+ {0x6ffffefc, "DT_AUDIT"},
+ {0x6ffffefd, "DT_PLTPAD"},
+ {0x6ffffefe, "DT_MOVETAB"},
+ {0x6ffffeff, "DT_SYMINFO"},
+ {0x6ffffeff, "DT_ADDRRNGHI"},
+ {0x6ffffff0, "DT_VERSYM"},
+ {0x6ffffff9, "DT_RELACOUNT"},
+ {0x6ffffffa, "DT_RELCOUNT"},
+ {0x6ffffffb, "DT_FLAGS_1"},
+ {0x6ffffffc, "DT_VERDEF"},
+ {0x6ffffffd, "DT_VERDEFNUM"},
+ {0x6ffffffe, "DT_VERNEED"},
+ {0x6fffffff, "DT_VERNEEDNUM"},
+ {0x70000000, "DT_LOPROC"},
+ // We don't list the processor-dependent DynTags,
+ // as the values overlap.
+ {0x7ffffffd, "DT_AUXILIARY"},
+ {0x7ffffffe, "DT_USED"},
+ {0x7fffffff, "DT_FILTER"},
+}
+
+func (i DynTag) String() string { return stringName(uint32(i), dtStrings, false) }
+func (i DynTag) GoString() string { return stringName(uint32(i), dtStrings, true) }
+
+// DT_FLAGS values.
+type DynFlag int
+
+const (
+ DF_ORIGIN DynFlag = 0x0001 /* Indicates that the object being loaded may
+ make reference to the
+ $ORIGIN substitution string */
+ DF_SYMBOLIC DynFlag = 0x0002 /* Indicates "symbolic" linking. */
+ DF_TEXTREL DynFlag = 0x0004 /* Indicates there may be relocations in non-writable segments. */
+ DF_BIND_NOW DynFlag = 0x0008 /* Indicates that the dynamic linker should
+ process all relocations for the object
+ containing this entry before transferring
+ control to the program. */
+ DF_STATIC_TLS DynFlag = 0x0010 /* Indicates that the shared object or
+ executable contains code using a static
+ thread-local storage scheme. */
+)
+
+var dflagStrings = []intName{
+ {0x0001, "DF_ORIGIN"},
+ {0x0002, "DF_SYMBOLIC"},
+ {0x0004, "DF_TEXTREL"},
+ {0x0008, "DF_BIND_NOW"},
+ {0x0010, "DF_STATIC_TLS"},
+}
+
+func (i DynFlag) String() string { return flagName(uint32(i), dflagStrings, false) }
+func (i DynFlag) GoString() string { return flagName(uint32(i), dflagStrings, true) }
+
+// DT_FLAGS_1 values.
+type DynFlag1 uint32
+
+const (
+ // Indicates that all relocations for this object must be processed before
+ // returning control to the program.
+ DF_1_NOW DynFlag1 = 0x00000001
+ // Unused.
+ DF_1_GLOBAL DynFlag1 = 0x00000002
+ // Indicates that the object is a member of a group.
+ DF_1_GROUP DynFlag1 = 0x00000004
+ // Indicates that the object cannot be deleted from a process.
+ DF_1_NODELETE DynFlag1 = 0x00000008
+ // Meaningful only for filters. Indicates that all associated filtees be
+ // processed immediately.
+ DF_1_LOADFLTR DynFlag1 = 0x00000010
+ // Indicates that this object's initialization section be run before any other
+ // objects loaded.
+ DF_1_INITFIRST DynFlag1 = 0x00000020
+ // Indicates that the object cannot be added to a running process with dlopen.
+ DF_1_NOOPEN DynFlag1 = 0x00000040
+ // Indicates the object requires $ORIGIN processing.
+ DF_1_ORIGIN DynFlag1 = 0x00000080
+ // Indicates that the object should use direct binding information.
+ DF_1_DIRECT DynFlag1 = 0x00000100
+ // Unused.
+ DF_1_TRANS DynFlag1 = 0x00000200
+ // Indicates that the objects symbol table is to interpose before all symbols
+ // except the primary load object, which is typically the executable.
+ DF_1_INTERPOSE DynFlag1 = 0x00000400
+ // Indicates that the search for dependencies of this object ignores any
+ // default library search paths.
+ DF_1_NODEFLIB DynFlag1 = 0x00000800
+ // Indicates that this object is not dumped by dldump. Candidates are objects
+ // with no relocations that might get included when generating alternative
+ // objects using.
+ DF_1_NODUMP DynFlag1 = 0x00001000
+ // Identifies this object as a configuration alternative object generated by
+ // crle. Triggers the runtime linker to search for a configuration file $ORIGIN/ld.config.app-name.
+ DF_1_CONFALT DynFlag1 = 0x00002000
+ // Meaningful only for filtees. Terminates a filters search for any
+ // further filtees.
+ DF_1_ENDFILTEE DynFlag1 = 0x00004000
+ // Indicates that this object has displacement relocations applied.
+ DF_1_DISPRELDNE DynFlag1 = 0x00008000
+ // Indicates that this object has displacement relocations pending.
+ DF_1_DISPRELPND DynFlag1 = 0x00010000
+ // Indicates that this object contains symbols that cannot be directly
+ // bound to.
+ DF_1_NODIRECT DynFlag1 = 0x00020000
+ // Reserved for internal use by the kernel runtime-linker.
+ DF_1_IGNMULDEF DynFlag1 = 0x00040000
+ // Reserved for internal use by the kernel runtime-linker.
+ DF_1_NOKSYMS DynFlag1 = 0x00080000
+ // Reserved for internal use by the kernel runtime-linker.
+ DF_1_NOHDR DynFlag1 = 0x00100000
+ // Indicates that this object has been edited or has been modified since the
+ // objects original construction by the link-editor.
+ DF_1_EDITED DynFlag1 = 0x00200000
+ // Reserved for internal use by the kernel runtime-linker.
+ DF_1_NORELOC DynFlag1 = 0x00400000
+ // Indicates that the object contains individual symbols that should interpose
+ // before all symbols except the primary load object, which is typically the
+ // executable.
+ DF_1_SYMINTPOSE DynFlag1 = 0x00800000
+ // Indicates that the executable requires global auditing.
+ DF_1_GLOBAUDIT DynFlag1 = 0x01000000
+ // Indicates that the object defines, or makes reference to singleton symbols.
+ DF_1_SINGLETON DynFlag1 = 0x02000000
+ // Indicates that the object is a stub.
+ DF_1_STUB DynFlag1 = 0x04000000
+ // Indicates that the object is a position-independent executable.
+ DF_1_PIE DynFlag1 = 0x08000000
+ // Indicates that the object is a kernel module.
+ DF_1_KMOD DynFlag1 = 0x10000000
+ // Indicates that the object is a weak standard filter.
+ DF_1_WEAKFILTER DynFlag1 = 0x20000000
+ // Unused.
+ DF_1_NOCOMMON DynFlag1 = 0x40000000
+)
+
+var dflag1Strings = []intName{
+ {0x00000001, "DF_1_NOW"},
+ {0x00000002, "DF_1_GLOBAL"},
+ {0x00000004, "DF_1_GROUP"},
+ {0x00000008, "DF_1_NODELETE"},
+ {0x00000010, "DF_1_LOADFLTR"},
+ {0x00000020, "DF_1_INITFIRST"},
+ {0x00000040, "DF_1_NOOPEN"},
+ {0x00000080, "DF_1_ORIGIN"},
+ {0x00000100, "DF_1_DIRECT"},
+ {0x00000200, "DF_1_TRANS"},
+ {0x00000400, "DF_1_INTERPOSE"},
+ {0x00000800, "DF_1_NODEFLIB"},
+ {0x00001000, "DF_1_NODUMP"},
+ {0x00002000, "DF_1_CONFALT"},
+ {0x00004000, "DF_1_ENDFILTEE"},
+ {0x00008000, "DF_1_DISPRELDNE"},
+ {0x00010000, "DF_1_DISPRELPND"},
+ {0x00020000, "DF_1_NODIRECT"},
+ {0x00040000, "DF_1_IGNMULDEF"},
+ {0x00080000, "DF_1_NOKSYMS"},
+ {0x00100000, "DF_1_NOHDR"},
+ {0x00200000, "DF_1_EDITED"},
+ {0x00400000, "DF_1_NORELOC"},
+ {0x00800000, "DF_1_SYMINTPOSE"},
+ {0x01000000, "DF_1_GLOBAUDIT"},
+ {0x02000000, "DF_1_SINGLETON"},
+ {0x04000000, "DF_1_STUB"},
+ {0x08000000, "DF_1_PIE"},
+ {0x10000000, "DF_1_KMOD"},
+ {0x20000000, "DF_1_WEAKFILTER"},
+ {0x40000000, "DF_1_NOCOMMON"},
+}
+
+func (i DynFlag1) String() string { return flagName(uint32(i), dflag1Strings, false) }
+func (i DynFlag1) GoString() string { return flagName(uint32(i), dflag1Strings, true) }
+
+// NType values; used in core files.
+type NType int
+
+const (
+ NT_PRSTATUS NType = 1 /* Process status. */
+ NT_FPREGSET NType = 2 /* Floating point registers. */
+ NT_PRPSINFO NType = 3 /* Process state info. */
+)
+
+var ntypeStrings = []intName{
+ {1, "NT_PRSTATUS"},
+ {2, "NT_FPREGSET"},
+ {3, "NT_PRPSINFO"},
+}
+
+func (i NType) String() string { return stringName(uint32(i), ntypeStrings, false) }
+func (i NType) GoString() string { return stringName(uint32(i), ntypeStrings, true) }
+
+/* Symbol Binding - ELFNN_ST_BIND - st_info */
+type SymBind int
+
+const (
+ STB_LOCAL SymBind = 0 /* Local symbol */
+ STB_GLOBAL SymBind = 1 /* Global symbol */
+ STB_WEAK SymBind = 2 /* like global - lower precedence */
+ STB_LOOS SymBind = 10 /* Reserved range for operating system */
+ STB_HIOS SymBind = 12 /* specific semantics. */
+ STB_LOPROC SymBind = 13 /* reserved range for processor */
+ STB_HIPROC SymBind = 15 /* specific semantics. */
+)
+
+var stbStrings = []intName{
+ {0, "STB_LOCAL"},
+ {1, "STB_GLOBAL"},
+ {2, "STB_WEAK"},
+ {10, "STB_LOOS"},
+ {12, "STB_HIOS"},
+ {13, "STB_LOPROC"},
+ {15, "STB_HIPROC"},
+}
+
+func (i SymBind) String() string { return stringName(uint32(i), stbStrings, false) }
+func (i SymBind) GoString() string { return stringName(uint32(i), stbStrings, true) }
+
+/* Symbol type - ELFNN_ST_TYPE - st_info */
+type SymType int
+
+const (
+ STT_NOTYPE SymType = 0 /* Unspecified type. */
+ STT_OBJECT SymType = 1 /* Data object. */
+ STT_FUNC SymType = 2 /* Function. */
+ STT_SECTION SymType = 3 /* Section. */
+ STT_FILE SymType = 4 /* Source file. */
+ STT_COMMON SymType = 5 /* Uninitialized common block. */
+ STT_TLS SymType = 6 /* TLS object. */
+ STT_LOOS SymType = 10 /* Reserved range for operating system */
+ STT_HIOS SymType = 12 /* specific semantics. */
+ STT_LOPROC SymType = 13 /* reserved range for processor */
+ STT_HIPROC SymType = 15 /* specific semantics. */
+)
+
+var sttStrings = []intName{
+ {0, "STT_NOTYPE"},
+ {1, "STT_OBJECT"},
+ {2, "STT_FUNC"},
+ {3, "STT_SECTION"},
+ {4, "STT_FILE"},
+ {5, "STT_COMMON"},
+ {6, "STT_TLS"},
+ {10, "STT_LOOS"},
+ {12, "STT_HIOS"},
+ {13, "STT_LOPROC"},
+ {15, "STT_HIPROC"},
+}
+
+func (i SymType) String() string { return stringName(uint32(i), sttStrings, false) }
+func (i SymType) GoString() string { return stringName(uint32(i), sttStrings, true) }
+
+/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
+type SymVis int
+
+const (
+ STV_DEFAULT SymVis = 0x0 /* Default visibility (see binding). */
+ STV_INTERNAL SymVis = 0x1 /* Special meaning in relocatable objects. */
+ STV_HIDDEN SymVis = 0x2 /* Not visible. */
+ STV_PROTECTED SymVis = 0x3 /* Visible but not preemptible. */
+)
+
+var stvStrings = []intName{
+ {0x0, "STV_DEFAULT"},
+ {0x1, "STV_INTERNAL"},
+ {0x2, "STV_HIDDEN"},
+ {0x3, "STV_PROTECTED"},
+}
+
+func (i SymVis) String() string { return stringName(uint32(i), stvStrings, false) }
+func (i SymVis) GoString() string { return stringName(uint32(i), stvStrings, true) }
+
+/*
+ * Relocation types.
+ */
+
+// Relocation types for x86-64.
+type R_X86_64 int
+
+const (
+ R_X86_64_NONE R_X86_64 = 0 /* No relocation. */
+ R_X86_64_64 R_X86_64 = 1 /* Add 64 bit symbol value. */
+ R_X86_64_PC32 R_X86_64 = 2 /* PC-relative 32 bit signed sym value. */
+ R_X86_64_GOT32 R_X86_64 = 3 /* PC-relative 32 bit GOT offset. */
+ R_X86_64_PLT32 R_X86_64 = 4 /* PC-relative 32 bit PLT offset. */
+ R_X86_64_COPY R_X86_64 = 5 /* Copy data from shared object. */
+ R_X86_64_GLOB_DAT R_X86_64 = 6 /* Set GOT entry to data address. */
+ R_X86_64_JMP_SLOT R_X86_64 = 7 /* Set GOT entry to code address. */
+ R_X86_64_RELATIVE R_X86_64 = 8 /* Add load address of shared object. */
+ R_X86_64_GOTPCREL R_X86_64 = 9 /* Add 32 bit signed pcrel offset to GOT. */
+ R_X86_64_32 R_X86_64 = 10 /* Add 32 bit zero extended symbol value */
+ R_X86_64_32S R_X86_64 = 11 /* Add 32 bit sign extended symbol value */
+ R_X86_64_16 R_X86_64 = 12 /* Add 16 bit zero extended symbol value */
+ R_X86_64_PC16 R_X86_64 = 13 /* Add 16 bit signed extended pc relative symbol value */
+ R_X86_64_8 R_X86_64 = 14 /* Add 8 bit zero extended symbol value */
+ R_X86_64_PC8 R_X86_64 = 15 /* Add 8 bit signed extended pc relative symbol value */
+ R_X86_64_DTPMOD64 R_X86_64 = 16 /* ID of module containing symbol */
+ R_X86_64_DTPOFF64 R_X86_64 = 17 /* Offset in TLS block */
+ R_X86_64_TPOFF64 R_X86_64 = 18 /* Offset in static TLS block */
+ R_X86_64_TLSGD R_X86_64 = 19 /* PC relative offset to GD GOT entry */
+ R_X86_64_TLSLD R_X86_64 = 20 /* PC relative offset to LD GOT entry */
+ R_X86_64_DTPOFF32 R_X86_64 = 21 /* Offset in TLS block */
+ R_X86_64_GOTTPOFF R_X86_64 = 22 /* PC relative offset to IE GOT entry */
+ R_X86_64_TPOFF32 R_X86_64 = 23 /* Offset in static TLS block */
+ R_X86_64_PC64 R_X86_64 = 24 /* PC relative 64-bit sign extended symbol value. */
+ R_X86_64_GOTOFF64 R_X86_64 = 25
+ R_X86_64_GOTPC32 R_X86_64 = 26
+ R_X86_64_GOT64 R_X86_64 = 27
+ R_X86_64_GOTPCREL64 R_X86_64 = 28
+ R_X86_64_GOTPC64 R_X86_64 = 29
+ R_X86_64_GOTPLT64 R_X86_64 = 30
+ R_X86_64_PLTOFF64 R_X86_64 = 31
+ R_X86_64_SIZE32 R_X86_64 = 32
+ R_X86_64_SIZE64 R_X86_64 = 33
+ R_X86_64_GOTPC32_TLSDESC R_X86_64 = 34
+ R_X86_64_TLSDESC_CALL R_X86_64 = 35
+ R_X86_64_TLSDESC R_X86_64 = 36
+ R_X86_64_IRELATIVE R_X86_64 = 37
+ R_X86_64_RELATIVE64 R_X86_64 = 38
+ R_X86_64_PC32_BND R_X86_64 = 39
+ R_X86_64_PLT32_BND R_X86_64 = 40
+ R_X86_64_GOTPCRELX R_X86_64 = 41
+ R_X86_64_REX_GOTPCRELX R_X86_64 = 42
+)
+
+var rx86_64Strings = []intName{
+ {0, "R_X86_64_NONE"},
+ {1, "R_X86_64_64"},
+ {2, "R_X86_64_PC32"},
+ {3, "R_X86_64_GOT32"},
+ {4, "R_X86_64_PLT32"},
+ {5, "R_X86_64_COPY"},
+ {6, "R_X86_64_GLOB_DAT"},
+ {7, "R_X86_64_JMP_SLOT"},
+ {8, "R_X86_64_RELATIVE"},
+ {9, "R_X86_64_GOTPCREL"},
+ {10, "R_X86_64_32"},
+ {11, "R_X86_64_32S"},
+ {12, "R_X86_64_16"},
+ {13, "R_X86_64_PC16"},
+ {14, "R_X86_64_8"},
+ {15, "R_X86_64_PC8"},
+ {16, "R_X86_64_DTPMOD64"},
+ {17, "R_X86_64_DTPOFF64"},
+ {18, "R_X86_64_TPOFF64"},
+ {19, "R_X86_64_TLSGD"},
+ {20, "R_X86_64_TLSLD"},
+ {21, "R_X86_64_DTPOFF32"},
+ {22, "R_X86_64_GOTTPOFF"},
+ {23, "R_X86_64_TPOFF32"},
+ {24, "R_X86_64_PC64"},
+ {25, "R_X86_64_GOTOFF64"},
+ {26, "R_X86_64_GOTPC32"},
+ {27, "R_X86_64_GOT64"},
+ {28, "R_X86_64_GOTPCREL64"},
+ {29, "R_X86_64_GOTPC64"},
+ {30, "R_X86_64_GOTPLT64"},
+ {31, "R_X86_64_PLTOFF64"},
+ {32, "R_X86_64_SIZE32"},
+ {33, "R_X86_64_SIZE64"},
+ {34, "R_X86_64_GOTPC32_TLSDESC"},
+ {35, "R_X86_64_TLSDESC_CALL"},
+ {36, "R_X86_64_TLSDESC"},
+ {37, "R_X86_64_IRELATIVE"},
+ {38, "R_X86_64_RELATIVE64"},
+ {39, "R_X86_64_PC32_BND"},
+ {40, "R_X86_64_PLT32_BND"},
+ {41, "R_X86_64_GOTPCRELX"},
+ {42, "R_X86_64_REX_GOTPCRELX"},
+}
+
+func (i R_X86_64) String() string { return stringName(uint32(i), rx86_64Strings, false) }
+func (i R_X86_64) GoString() string { return stringName(uint32(i), rx86_64Strings, true) }
+
+// Relocation types for AArch64 (aka arm64)
+type R_AARCH64 int
+
+const (
+ R_AARCH64_NONE R_AARCH64 = 0
+ R_AARCH64_P32_ABS32 R_AARCH64 = 1
+ R_AARCH64_P32_ABS16 R_AARCH64 = 2
+ R_AARCH64_P32_PREL32 R_AARCH64 = 3
+ R_AARCH64_P32_PREL16 R_AARCH64 = 4
+ R_AARCH64_P32_MOVW_UABS_G0 R_AARCH64 = 5
+ R_AARCH64_P32_MOVW_UABS_G0_NC R_AARCH64 = 6
+ R_AARCH64_P32_MOVW_UABS_G1 R_AARCH64 = 7
+ R_AARCH64_P32_MOVW_SABS_G0 R_AARCH64 = 8
+ R_AARCH64_P32_LD_PREL_LO19 R_AARCH64 = 9
+ R_AARCH64_P32_ADR_PREL_LO21 R_AARCH64 = 10
+ R_AARCH64_P32_ADR_PREL_PG_HI21 R_AARCH64 = 11
+ R_AARCH64_P32_ADD_ABS_LO12_NC R_AARCH64 = 12
+ R_AARCH64_P32_LDST8_ABS_LO12_NC R_AARCH64 = 13
+ R_AARCH64_P32_LDST16_ABS_LO12_NC R_AARCH64 = 14
+ R_AARCH64_P32_LDST32_ABS_LO12_NC R_AARCH64 = 15
+ R_AARCH64_P32_LDST64_ABS_LO12_NC R_AARCH64 = 16
+ R_AARCH64_P32_LDST128_ABS_LO12_NC R_AARCH64 = 17
+ R_AARCH64_P32_TSTBR14 R_AARCH64 = 18
+ R_AARCH64_P32_CONDBR19 R_AARCH64 = 19
+ R_AARCH64_P32_JUMP26 R_AARCH64 = 20
+ R_AARCH64_P32_CALL26 R_AARCH64 = 21
+ R_AARCH64_P32_GOT_LD_PREL19 R_AARCH64 = 25
+ R_AARCH64_P32_ADR_GOT_PAGE R_AARCH64 = 26
+ R_AARCH64_P32_LD32_GOT_LO12_NC R_AARCH64 = 27
+ R_AARCH64_P32_TLSGD_ADR_PAGE21 R_AARCH64 = 81
+ R_AARCH64_P32_TLSGD_ADD_LO12_NC R_AARCH64 = 82
+ R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21 R_AARCH64 = 103
+ R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC R_AARCH64 = 104
+ R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19 R_AARCH64 = 105
+ R_AARCH64_P32_TLSLE_MOVW_TPREL_G1 R_AARCH64 = 106
+ R_AARCH64_P32_TLSLE_MOVW_TPREL_G0 R_AARCH64 = 107
+ R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC R_AARCH64 = 108
+ R_AARCH64_P32_TLSLE_ADD_TPREL_HI12 R_AARCH64 = 109
+ R_AARCH64_P32_TLSLE_ADD_TPREL_LO12 R_AARCH64 = 110
+ R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC R_AARCH64 = 111
+ R_AARCH64_P32_TLSDESC_LD_PREL19 R_AARCH64 = 122
+ R_AARCH64_P32_TLSDESC_ADR_PREL21 R_AARCH64 = 123
+ R_AARCH64_P32_TLSDESC_ADR_PAGE21 R_AARCH64 = 124
+ R_AARCH64_P32_TLSDESC_LD32_LO12_NC R_AARCH64 = 125
+ R_AARCH64_P32_TLSDESC_ADD_LO12_NC R_AARCH64 = 126
+ R_AARCH64_P32_TLSDESC_CALL R_AARCH64 = 127
+ R_AARCH64_P32_COPY R_AARCH64 = 180
+ R_AARCH64_P32_GLOB_DAT R_AARCH64 = 181
+ R_AARCH64_P32_JUMP_SLOT R_AARCH64 = 182
+ R_AARCH64_P32_RELATIVE R_AARCH64 = 183
+ R_AARCH64_P32_TLS_DTPMOD R_AARCH64 = 184
+ R_AARCH64_P32_TLS_DTPREL R_AARCH64 = 185
+ R_AARCH64_P32_TLS_TPREL R_AARCH64 = 186
+ R_AARCH64_P32_TLSDESC R_AARCH64 = 187
+ R_AARCH64_P32_IRELATIVE R_AARCH64 = 188
+ R_AARCH64_NULL R_AARCH64 = 256
+ R_AARCH64_ABS64 R_AARCH64 = 257
+ R_AARCH64_ABS32 R_AARCH64 = 258
+ R_AARCH64_ABS16 R_AARCH64 = 259
+ R_AARCH64_PREL64 R_AARCH64 = 260
+ R_AARCH64_PREL32 R_AARCH64 = 261
+ R_AARCH64_PREL16 R_AARCH64 = 262
+ R_AARCH64_MOVW_UABS_G0 R_AARCH64 = 263
+ R_AARCH64_MOVW_UABS_G0_NC R_AARCH64 = 264
+ R_AARCH64_MOVW_UABS_G1 R_AARCH64 = 265
+ R_AARCH64_MOVW_UABS_G1_NC R_AARCH64 = 266
+ R_AARCH64_MOVW_UABS_G2 R_AARCH64 = 267
+ R_AARCH64_MOVW_UABS_G2_NC R_AARCH64 = 268
+ R_AARCH64_MOVW_UABS_G3 R_AARCH64 = 269
+ R_AARCH64_MOVW_SABS_G0 R_AARCH64 = 270
+ R_AARCH64_MOVW_SABS_G1 R_AARCH64 = 271
+ R_AARCH64_MOVW_SABS_G2 R_AARCH64 = 272
+ R_AARCH64_LD_PREL_LO19 R_AARCH64 = 273
+ R_AARCH64_ADR_PREL_LO21 R_AARCH64 = 274
+ R_AARCH64_ADR_PREL_PG_HI21 R_AARCH64 = 275
+ R_AARCH64_ADR_PREL_PG_HI21_NC R_AARCH64 = 276
+ R_AARCH64_ADD_ABS_LO12_NC R_AARCH64 = 277
+ R_AARCH64_LDST8_ABS_LO12_NC R_AARCH64 = 278
+ R_AARCH64_TSTBR14 R_AARCH64 = 279
+ R_AARCH64_CONDBR19 R_AARCH64 = 280
+ R_AARCH64_JUMP26 R_AARCH64 = 282
+ R_AARCH64_CALL26 R_AARCH64 = 283
+ R_AARCH64_LDST16_ABS_LO12_NC R_AARCH64 = 284
+ R_AARCH64_LDST32_ABS_LO12_NC R_AARCH64 = 285
+ R_AARCH64_LDST64_ABS_LO12_NC R_AARCH64 = 286
+ R_AARCH64_LDST128_ABS_LO12_NC R_AARCH64 = 299
+ R_AARCH64_GOT_LD_PREL19 R_AARCH64 = 309
+ R_AARCH64_LD64_GOTOFF_LO15 R_AARCH64 = 310
+ R_AARCH64_ADR_GOT_PAGE R_AARCH64 = 311
+ R_AARCH64_LD64_GOT_LO12_NC R_AARCH64 = 312
+ R_AARCH64_LD64_GOTPAGE_LO15 R_AARCH64 = 313
+ R_AARCH64_TLSGD_ADR_PREL21 R_AARCH64 = 512
+ R_AARCH64_TLSGD_ADR_PAGE21 R_AARCH64 = 513
+ R_AARCH64_TLSGD_ADD_LO12_NC R_AARCH64 = 514
+ R_AARCH64_TLSGD_MOVW_G1 R_AARCH64 = 515
+ R_AARCH64_TLSGD_MOVW_G0_NC R_AARCH64 = 516
+ R_AARCH64_TLSLD_ADR_PREL21 R_AARCH64 = 517
+ R_AARCH64_TLSLD_ADR_PAGE21 R_AARCH64 = 518
+ R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 R_AARCH64 = 539
+ R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC R_AARCH64 = 540
+ R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 R_AARCH64 = 541
+ R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC R_AARCH64 = 542
+ R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 R_AARCH64 = 543
+ R_AARCH64_TLSLE_MOVW_TPREL_G2 R_AARCH64 = 544
+ R_AARCH64_TLSLE_MOVW_TPREL_G1 R_AARCH64 = 545
+ R_AARCH64_TLSLE_MOVW_TPREL_G1_NC R_AARCH64 = 546
+ R_AARCH64_TLSLE_MOVW_TPREL_G0 R_AARCH64 = 547
+ R_AARCH64_TLSLE_MOVW_TPREL_G0_NC R_AARCH64 = 548
+ R_AARCH64_TLSLE_ADD_TPREL_HI12 R_AARCH64 = 549
+ R_AARCH64_TLSLE_ADD_TPREL_LO12 R_AARCH64 = 550
+ R_AARCH64_TLSLE_ADD_TPREL_LO12_NC R_AARCH64 = 551
+ R_AARCH64_TLSDESC_LD_PREL19 R_AARCH64 = 560
+ R_AARCH64_TLSDESC_ADR_PREL21 R_AARCH64 = 561
+ R_AARCH64_TLSDESC_ADR_PAGE21 R_AARCH64 = 562
+ R_AARCH64_TLSDESC_LD64_LO12_NC R_AARCH64 = 563
+ R_AARCH64_TLSDESC_ADD_LO12_NC R_AARCH64 = 564
+ R_AARCH64_TLSDESC_OFF_G1 R_AARCH64 = 565
+ R_AARCH64_TLSDESC_OFF_G0_NC R_AARCH64 = 566
+ R_AARCH64_TLSDESC_LDR R_AARCH64 = 567
+ R_AARCH64_TLSDESC_ADD R_AARCH64 = 568
+ R_AARCH64_TLSDESC_CALL R_AARCH64 = 569
+ R_AARCH64_TLSLE_LDST128_TPREL_LO12 R_AARCH64 = 570
+ R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC R_AARCH64 = 571
+ R_AARCH64_TLSLD_LDST128_DTPREL_LO12 R_AARCH64 = 572
+ R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC R_AARCH64 = 573
+ R_AARCH64_COPY R_AARCH64 = 1024
+ R_AARCH64_GLOB_DAT R_AARCH64 = 1025
+ R_AARCH64_JUMP_SLOT R_AARCH64 = 1026
+ R_AARCH64_RELATIVE R_AARCH64 = 1027
+ R_AARCH64_TLS_DTPMOD64 R_AARCH64 = 1028
+ R_AARCH64_TLS_DTPREL64 R_AARCH64 = 1029
+ R_AARCH64_TLS_TPREL64 R_AARCH64 = 1030
+ R_AARCH64_TLSDESC R_AARCH64 = 1031
+ R_AARCH64_IRELATIVE R_AARCH64 = 1032
+)
+
+var raarch64Strings = []intName{
+ {0, "R_AARCH64_NONE"},
+ {1, "R_AARCH64_P32_ABS32"},
+ {2, "R_AARCH64_P32_ABS16"},
+ {3, "R_AARCH64_P32_PREL32"},
+ {4, "R_AARCH64_P32_PREL16"},
+ {5, "R_AARCH64_P32_MOVW_UABS_G0"},
+ {6, "R_AARCH64_P32_MOVW_UABS_G0_NC"},
+ {7, "R_AARCH64_P32_MOVW_UABS_G1"},
+ {8, "R_AARCH64_P32_MOVW_SABS_G0"},
+ {9, "R_AARCH64_P32_LD_PREL_LO19"},
+ {10, "R_AARCH64_P32_ADR_PREL_LO21"},
+ {11, "R_AARCH64_P32_ADR_PREL_PG_HI21"},
+ {12, "R_AARCH64_P32_ADD_ABS_LO12_NC"},
+ {13, "R_AARCH64_P32_LDST8_ABS_LO12_NC"},
+ {14, "R_AARCH64_P32_LDST16_ABS_LO12_NC"},
+ {15, "R_AARCH64_P32_LDST32_ABS_LO12_NC"},
+ {16, "R_AARCH64_P32_LDST64_ABS_LO12_NC"},
+ {17, "R_AARCH64_P32_LDST128_ABS_LO12_NC"},
+ {18, "R_AARCH64_P32_TSTBR14"},
+ {19, "R_AARCH64_P32_CONDBR19"},
+ {20, "R_AARCH64_P32_JUMP26"},
+ {21, "R_AARCH64_P32_CALL26"},
+ {25, "R_AARCH64_P32_GOT_LD_PREL19"},
+ {26, "R_AARCH64_P32_ADR_GOT_PAGE"},
+ {27, "R_AARCH64_P32_LD32_GOT_LO12_NC"},
+ {81, "R_AARCH64_P32_TLSGD_ADR_PAGE21"},
+ {82, "R_AARCH64_P32_TLSGD_ADD_LO12_NC"},
+ {103, "R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21"},
+ {104, "R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC"},
+ {105, "R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19"},
+ {106, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G1"},
+ {107, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G0"},
+ {108, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC"},
+ {109, "R_AARCH64_P32_TLSLE_ADD_TPREL_HI12"},
+ {110, "R_AARCH64_P32_TLSLE_ADD_TPREL_LO12"},
+ {111, "R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC"},
+ {122, "R_AARCH64_P32_TLSDESC_LD_PREL19"},
+ {123, "R_AARCH64_P32_TLSDESC_ADR_PREL21"},
+ {124, "R_AARCH64_P32_TLSDESC_ADR_PAGE21"},
+ {125, "R_AARCH64_P32_TLSDESC_LD32_LO12_NC"},
+ {126, "R_AARCH64_P32_TLSDESC_ADD_LO12_NC"},
+ {127, "R_AARCH64_P32_TLSDESC_CALL"},
+ {180, "R_AARCH64_P32_COPY"},
+ {181, "R_AARCH64_P32_GLOB_DAT"},
+ {182, "R_AARCH64_P32_JUMP_SLOT"},
+ {183, "R_AARCH64_P32_RELATIVE"},
+ {184, "R_AARCH64_P32_TLS_DTPMOD"},
+ {185, "R_AARCH64_P32_TLS_DTPREL"},
+ {186, "R_AARCH64_P32_TLS_TPREL"},
+ {187, "R_AARCH64_P32_TLSDESC"},
+ {188, "R_AARCH64_P32_IRELATIVE"},
+ {256, "R_AARCH64_NULL"},
+ {257, "R_AARCH64_ABS64"},
+ {258, "R_AARCH64_ABS32"},
+ {259, "R_AARCH64_ABS16"},
+ {260, "R_AARCH64_PREL64"},
+ {261, "R_AARCH64_PREL32"},
+ {262, "R_AARCH64_PREL16"},
+ {263, "R_AARCH64_MOVW_UABS_G0"},
+ {264, "R_AARCH64_MOVW_UABS_G0_NC"},
+ {265, "R_AARCH64_MOVW_UABS_G1"},
+ {266, "R_AARCH64_MOVW_UABS_G1_NC"},
+ {267, "R_AARCH64_MOVW_UABS_G2"},
+ {268, "R_AARCH64_MOVW_UABS_G2_NC"},
+ {269, "R_AARCH64_MOVW_UABS_G3"},
+ {270, "R_AARCH64_MOVW_SABS_G0"},
+ {271, "R_AARCH64_MOVW_SABS_G1"},
+ {272, "R_AARCH64_MOVW_SABS_G2"},
+ {273, "R_AARCH64_LD_PREL_LO19"},
+ {274, "R_AARCH64_ADR_PREL_LO21"},
+ {275, "R_AARCH64_ADR_PREL_PG_HI21"},
+ {276, "R_AARCH64_ADR_PREL_PG_HI21_NC"},
+ {277, "R_AARCH64_ADD_ABS_LO12_NC"},
+ {278, "R_AARCH64_LDST8_ABS_LO12_NC"},
+ {279, "R_AARCH64_TSTBR14"},
+ {280, "R_AARCH64_CONDBR19"},
+ {282, "R_AARCH64_JUMP26"},
+ {283, "R_AARCH64_CALL26"},
+ {284, "R_AARCH64_LDST16_ABS_LO12_NC"},
+ {285, "R_AARCH64_LDST32_ABS_LO12_NC"},
+ {286, "R_AARCH64_LDST64_ABS_LO12_NC"},
+ {299, "R_AARCH64_LDST128_ABS_LO12_NC"},
+ {309, "R_AARCH64_GOT_LD_PREL19"},
+ {310, "R_AARCH64_LD64_GOTOFF_LO15"},
+ {311, "R_AARCH64_ADR_GOT_PAGE"},
+ {312, "R_AARCH64_LD64_GOT_LO12_NC"},
+ {313, "R_AARCH64_LD64_GOTPAGE_LO15"},
+ {512, "R_AARCH64_TLSGD_ADR_PREL21"},
+ {513, "R_AARCH64_TLSGD_ADR_PAGE21"},
+ {514, "R_AARCH64_TLSGD_ADD_LO12_NC"},
+ {515, "R_AARCH64_TLSGD_MOVW_G1"},
+ {516, "R_AARCH64_TLSGD_MOVW_G0_NC"},
+ {517, "R_AARCH64_TLSLD_ADR_PREL21"},
+ {518, "R_AARCH64_TLSLD_ADR_PAGE21"},
+ {539, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G1"},
+ {540, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC"},
+ {541, "R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21"},
+ {542, "R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC"},
+ {543, "R_AARCH64_TLSIE_LD_GOTTPREL_PREL19"},
+ {544, "R_AARCH64_TLSLE_MOVW_TPREL_G2"},
+ {545, "R_AARCH64_TLSLE_MOVW_TPREL_G1"},
+ {546, "R_AARCH64_TLSLE_MOVW_TPREL_G1_NC"},
+ {547, "R_AARCH64_TLSLE_MOVW_TPREL_G0"},
+ {548, "R_AARCH64_TLSLE_MOVW_TPREL_G0_NC"},
+ {549, "R_AARCH64_TLSLE_ADD_TPREL_HI12"},
+ {550, "R_AARCH64_TLSLE_ADD_TPREL_LO12"},
+ {551, "R_AARCH64_TLSLE_ADD_TPREL_LO12_NC"},
+ {560, "R_AARCH64_TLSDESC_LD_PREL19"},
+ {561, "R_AARCH64_TLSDESC_ADR_PREL21"},
+ {562, "R_AARCH64_TLSDESC_ADR_PAGE21"},
+ {563, "R_AARCH64_TLSDESC_LD64_LO12_NC"},
+ {564, "R_AARCH64_TLSDESC_ADD_LO12_NC"},
+ {565, "R_AARCH64_TLSDESC_OFF_G1"},
+ {566, "R_AARCH64_TLSDESC_OFF_G0_NC"},
+ {567, "R_AARCH64_TLSDESC_LDR"},
+ {568, "R_AARCH64_TLSDESC_ADD"},
+ {569, "R_AARCH64_TLSDESC_CALL"},
+ {570, "R_AARCH64_TLSLE_LDST128_TPREL_LO12"},
+ {571, "R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC"},
+ {572, "R_AARCH64_TLSLD_LDST128_DTPREL_LO12"},
+ {573, "R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC"},
+ {1024, "R_AARCH64_COPY"},
+ {1025, "R_AARCH64_GLOB_DAT"},
+ {1026, "R_AARCH64_JUMP_SLOT"},
+ {1027, "R_AARCH64_RELATIVE"},
+ {1028, "R_AARCH64_TLS_DTPMOD64"},
+ {1029, "R_AARCH64_TLS_DTPREL64"},
+ {1030, "R_AARCH64_TLS_TPREL64"},
+ {1031, "R_AARCH64_TLSDESC"},
+ {1032, "R_AARCH64_IRELATIVE"},
+}
+
+func (i R_AARCH64) String() string { return stringName(uint32(i), raarch64Strings, false) }
+func (i R_AARCH64) GoString() string { return stringName(uint32(i), raarch64Strings, true) }
+
+// Relocation types for Alpha.
+type R_ALPHA int
+
+const (
+ R_ALPHA_NONE R_ALPHA = 0 /* No reloc */
+ R_ALPHA_REFLONG R_ALPHA = 1 /* Direct 32 bit */
+ R_ALPHA_REFQUAD R_ALPHA = 2 /* Direct 64 bit */
+ R_ALPHA_GPREL32 R_ALPHA = 3 /* GP relative 32 bit */
+ R_ALPHA_LITERAL R_ALPHA = 4 /* GP relative 16 bit w/optimization */
+ R_ALPHA_LITUSE R_ALPHA = 5 /* Optimization hint for LITERAL */
+ R_ALPHA_GPDISP R_ALPHA = 6 /* Add displacement to GP */
+ R_ALPHA_BRADDR R_ALPHA = 7 /* PC+4 relative 23 bit shifted */
+ R_ALPHA_HINT R_ALPHA = 8 /* PC+4 relative 16 bit shifted */
+ R_ALPHA_SREL16 R_ALPHA = 9 /* PC relative 16 bit */
+ R_ALPHA_SREL32 R_ALPHA = 10 /* PC relative 32 bit */
+ R_ALPHA_SREL64 R_ALPHA = 11 /* PC relative 64 bit */
+ R_ALPHA_OP_PUSH R_ALPHA = 12 /* OP stack push */
+ R_ALPHA_OP_STORE R_ALPHA = 13 /* OP stack pop and store */
+ R_ALPHA_OP_PSUB R_ALPHA = 14 /* OP stack subtract */
+ R_ALPHA_OP_PRSHIFT R_ALPHA = 15 /* OP stack right shift */
+ R_ALPHA_GPVALUE R_ALPHA = 16
+ R_ALPHA_GPRELHIGH R_ALPHA = 17
+ R_ALPHA_GPRELLOW R_ALPHA = 18
+ R_ALPHA_IMMED_GP_16 R_ALPHA = 19
+ R_ALPHA_IMMED_GP_HI32 R_ALPHA = 20
+ R_ALPHA_IMMED_SCN_HI32 R_ALPHA = 21
+ R_ALPHA_IMMED_BR_HI32 R_ALPHA = 22
+ R_ALPHA_IMMED_LO32 R_ALPHA = 23
+ R_ALPHA_COPY R_ALPHA = 24 /* Copy symbol at runtime */
+ R_ALPHA_GLOB_DAT R_ALPHA = 25 /* Create GOT entry */
+ R_ALPHA_JMP_SLOT R_ALPHA = 26 /* Create PLT entry */
+ R_ALPHA_RELATIVE R_ALPHA = 27 /* Adjust by program base */
+)
+
+var ralphaStrings = []intName{
+ {0, "R_ALPHA_NONE"},
+ {1, "R_ALPHA_REFLONG"},
+ {2, "R_ALPHA_REFQUAD"},
+ {3, "R_ALPHA_GPREL32"},
+ {4, "R_ALPHA_LITERAL"},
+ {5, "R_ALPHA_LITUSE"},
+ {6, "R_ALPHA_GPDISP"},
+ {7, "R_ALPHA_BRADDR"},
+ {8, "R_ALPHA_HINT"},
+ {9, "R_ALPHA_SREL16"},
+ {10, "R_ALPHA_SREL32"},
+ {11, "R_ALPHA_SREL64"},
+ {12, "R_ALPHA_OP_PUSH"},
+ {13, "R_ALPHA_OP_STORE"},
+ {14, "R_ALPHA_OP_PSUB"},
+ {15, "R_ALPHA_OP_PRSHIFT"},
+ {16, "R_ALPHA_GPVALUE"},
+ {17, "R_ALPHA_GPRELHIGH"},
+ {18, "R_ALPHA_GPRELLOW"},
+ {19, "R_ALPHA_IMMED_GP_16"},
+ {20, "R_ALPHA_IMMED_GP_HI32"},
+ {21, "R_ALPHA_IMMED_SCN_HI32"},
+ {22, "R_ALPHA_IMMED_BR_HI32"},
+ {23, "R_ALPHA_IMMED_LO32"},
+ {24, "R_ALPHA_COPY"},
+ {25, "R_ALPHA_GLOB_DAT"},
+ {26, "R_ALPHA_JMP_SLOT"},
+ {27, "R_ALPHA_RELATIVE"},
+}
+
+func (i R_ALPHA) String() string { return stringName(uint32(i), ralphaStrings, false) }
+func (i R_ALPHA) GoString() string { return stringName(uint32(i), ralphaStrings, true) }
+
+// Relocation types for ARM.
+type R_ARM int
+
+const (
+ R_ARM_NONE R_ARM = 0 /* No relocation. */
+ R_ARM_PC24 R_ARM = 1
+ R_ARM_ABS32 R_ARM = 2
+ R_ARM_REL32 R_ARM = 3
+ R_ARM_PC13 R_ARM = 4
+ R_ARM_ABS16 R_ARM = 5
+ R_ARM_ABS12 R_ARM = 6
+ R_ARM_THM_ABS5 R_ARM = 7
+ R_ARM_ABS8 R_ARM = 8
+ R_ARM_SBREL32 R_ARM = 9
+ R_ARM_THM_PC22 R_ARM = 10
+ R_ARM_THM_PC8 R_ARM = 11
+ R_ARM_AMP_VCALL9 R_ARM = 12
+ R_ARM_SWI24 R_ARM = 13
+ R_ARM_THM_SWI8 R_ARM = 14
+ R_ARM_XPC25 R_ARM = 15
+ R_ARM_THM_XPC22 R_ARM = 16
+ R_ARM_TLS_DTPMOD32 R_ARM = 17
+ R_ARM_TLS_DTPOFF32 R_ARM = 18
+ R_ARM_TLS_TPOFF32 R_ARM = 19
+ R_ARM_COPY R_ARM = 20 /* Copy data from shared object. */
+ R_ARM_GLOB_DAT R_ARM = 21 /* Set GOT entry to data address. */
+ R_ARM_JUMP_SLOT R_ARM = 22 /* Set GOT entry to code address. */
+ R_ARM_RELATIVE R_ARM = 23 /* Add load address of shared object. */
+ R_ARM_GOTOFF R_ARM = 24 /* Add GOT-relative symbol address. */
+ R_ARM_GOTPC R_ARM = 25 /* Add PC-relative GOT table address. */
+ R_ARM_GOT32 R_ARM = 26 /* Add PC-relative GOT offset. */
+ R_ARM_PLT32 R_ARM = 27 /* Add PC-relative PLT offset. */
+ R_ARM_CALL R_ARM = 28
+ R_ARM_JUMP24 R_ARM = 29
+ R_ARM_THM_JUMP24 R_ARM = 30
+ R_ARM_BASE_ABS R_ARM = 31
+ R_ARM_ALU_PCREL_7_0 R_ARM = 32
+ R_ARM_ALU_PCREL_15_8 R_ARM = 33
+ R_ARM_ALU_PCREL_23_15 R_ARM = 34
+ R_ARM_LDR_SBREL_11_10_NC R_ARM = 35
+ R_ARM_ALU_SBREL_19_12_NC R_ARM = 36
+ R_ARM_ALU_SBREL_27_20_CK R_ARM = 37
+ R_ARM_TARGET1 R_ARM = 38
+ R_ARM_SBREL31 R_ARM = 39
+ R_ARM_V4BX R_ARM = 40
+ R_ARM_TARGET2 R_ARM = 41
+ R_ARM_PREL31 R_ARM = 42
+ R_ARM_MOVW_ABS_NC R_ARM = 43
+ R_ARM_MOVT_ABS R_ARM = 44
+ R_ARM_MOVW_PREL_NC R_ARM = 45
+ R_ARM_MOVT_PREL R_ARM = 46
+ R_ARM_THM_MOVW_ABS_NC R_ARM = 47
+ R_ARM_THM_MOVT_ABS R_ARM = 48
+ R_ARM_THM_MOVW_PREL_NC R_ARM = 49
+ R_ARM_THM_MOVT_PREL R_ARM = 50
+ R_ARM_THM_JUMP19 R_ARM = 51
+ R_ARM_THM_JUMP6 R_ARM = 52
+ R_ARM_THM_ALU_PREL_11_0 R_ARM = 53
+ R_ARM_THM_PC12 R_ARM = 54
+ R_ARM_ABS32_NOI R_ARM = 55
+ R_ARM_REL32_NOI R_ARM = 56
+ R_ARM_ALU_PC_G0_NC R_ARM = 57
+ R_ARM_ALU_PC_G0 R_ARM = 58
+ R_ARM_ALU_PC_G1_NC R_ARM = 59
+ R_ARM_ALU_PC_G1 R_ARM = 60
+ R_ARM_ALU_PC_G2 R_ARM = 61
+ R_ARM_LDR_PC_G1 R_ARM = 62
+ R_ARM_LDR_PC_G2 R_ARM = 63
+ R_ARM_LDRS_PC_G0 R_ARM = 64
+ R_ARM_LDRS_PC_G1 R_ARM = 65
+ R_ARM_LDRS_PC_G2 R_ARM = 66
+ R_ARM_LDC_PC_G0 R_ARM = 67
+ R_ARM_LDC_PC_G1 R_ARM = 68
+ R_ARM_LDC_PC_G2 R_ARM = 69
+ R_ARM_ALU_SB_G0_NC R_ARM = 70
+ R_ARM_ALU_SB_G0 R_ARM = 71
+ R_ARM_ALU_SB_G1_NC R_ARM = 72
+ R_ARM_ALU_SB_G1 R_ARM = 73
+ R_ARM_ALU_SB_G2 R_ARM = 74
+ R_ARM_LDR_SB_G0 R_ARM = 75
+ R_ARM_LDR_SB_G1 R_ARM = 76
+ R_ARM_LDR_SB_G2 R_ARM = 77
+ R_ARM_LDRS_SB_G0 R_ARM = 78
+ R_ARM_LDRS_SB_G1 R_ARM = 79
+ R_ARM_LDRS_SB_G2 R_ARM = 80
+ R_ARM_LDC_SB_G0 R_ARM = 81
+ R_ARM_LDC_SB_G1 R_ARM = 82
+ R_ARM_LDC_SB_G2 R_ARM = 83
+ R_ARM_MOVW_BREL_NC R_ARM = 84
+ R_ARM_MOVT_BREL R_ARM = 85
+ R_ARM_MOVW_BREL R_ARM = 86
+ R_ARM_THM_MOVW_BREL_NC R_ARM = 87
+ R_ARM_THM_MOVT_BREL R_ARM = 88
+ R_ARM_THM_MOVW_BREL R_ARM = 89
+ R_ARM_TLS_GOTDESC R_ARM = 90
+ R_ARM_TLS_CALL R_ARM = 91
+ R_ARM_TLS_DESCSEQ R_ARM = 92
+ R_ARM_THM_TLS_CALL R_ARM = 93
+ R_ARM_PLT32_ABS R_ARM = 94
+ R_ARM_GOT_ABS R_ARM = 95
+ R_ARM_GOT_PREL R_ARM = 96
+ R_ARM_GOT_BREL12 R_ARM = 97
+ R_ARM_GOTOFF12 R_ARM = 98
+ R_ARM_GOTRELAX R_ARM = 99
+ R_ARM_GNU_VTENTRY R_ARM = 100
+ R_ARM_GNU_VTINHERIT R_ARM = 101
+ R_ARM_THM_JUMP11 R_ARM = 102
+ R_ARM_THM_JUMP8 R_ARM = 103
+ R_ARM_TLS_GD32 R_ARM = 104
+ R_ARM_TLS_LDM32 R_ARM = 105
+ R_ARM_TLS_LDO32 R_ARM = 106
+ R_ARM_TLS_IE32 R_ARM = 107
+ R_ARM_TLS_LE32 R_ARM = 108
+ R_ARM_TLS_LDO12 R_ARM = 109
+ R_ARM_TLS_LE12 R_ARM = 110
+ R_ARM_TLS_IE12GP R_ARM = 111
+ R_ARM_PRIVATE_0 R_ARM = 112
+ R_ARM_PRIVATE_1 R_ARM = 113
+ R_ARM_PRIVATE_2 R_ARM = 114
+ R_ARM_PRIVATE_3 R_ARM = 115
+ R_ARM_PRIVATE_4 R_ARM = 116
+ R_ARM_PRIVATE_5 R_ARM = 117
+ R_ARM_PRIVATE_6 R_ARM = 118
+ R_ARM_PRIVATE_7 R_ARM = 119
+ R_ARM_PRIVATE_8 R_ARM = 120
+ R_ARM_PRIVATE_9 R_ARM = 121
+ R_ARM_PRIVATE_10 R_ARM = 122
+ R_ARM_PRIVATE_11 R_ARM = 123
+ R_ARM_PRIVATE_12 R_ARM = 124
+ R_ARM_PRIVATE_13 R_ARM = 125
+ R_ARM_PRIVATE_14 R_ARM = 126
+ R_ARM_PRIVATE_15 R_ARM = 127
+ R_ARM_ME_TOO R_ARM = 128
+ R_ARM_THM_TLS_DESCSEQ16 R_ARM = 129
+ R_ARM_THM_TLS_DESCSEQ32 R_ARM = 130
+ R_ARM_THM_GOT_BREL12 R_ARM = 131
+ R_ARM_THM_ALU_ABS_G0_NC R_ARM = 132
+ R_ARM_THM_ALU_ABS_G1_NC R_ARM = 133
+ R_ARM_THM_ALU_ABS_G2_NC R_ARM = 134
+ R_ARM_THM_ALU_ABS_G3 R_ARM = 135
+ R_ARM_IRELATIVE R_ARM = 160
+ R_ARM_RXPC25 R_ARM = 249
+ R_ARM_RSBREL32 R_ARM = 250
+ R_ARM_THM_RPC22 R_ARM = 251
+ R_ARM_RREL32 R_ARM = 252
+ R_ARM_RABS32 R_ARM = 253
+ R_ARM_RPC24 R_ARM = 254
+ R_ARM_RBASE R_ARM = 255
+)
+
+var rarmStrings = []intName{
+ {0, "R_ARM_NONE"},
+ {1, "R_ARM_PC24"},
+ {2, "R_ARM_ABS32"},
+ {3, "R_ARM_REL32"},
+ {4, "R_ARM_PC13"},
+ {5, "R_ARM_ABS16"},
+ {6, "R_ARM_ABS12"},
+ {7, "R_ARM_THM_ABS5"},
+ {8, "R_ARM_ABS8"},
+ {9, "R_ARM_SBREL32"},
+ {10, "R_ARM_THM_PC22"},
+ {11, "R_ARM_THM_PC8"},
+ {12, "R_ARM_AMP_VCALL9"},
+ {13, "R_ARM_SWI24"},
+ {14, "R_ARM_THM_SWI8"},
+ {15, "R_ARM_XPC25"},
+ {16, "R_ARM_THM_XPC22"},
+ {17, "R_ARM_TLS_DTPMOD32"},
+ {18, "R_ARM_TLS_DTPOFF32"},
+ {19, "R_ARM_TLS_TPOFF32"},
+ {20, "R_ARM_COPY"},
+ {21, "R_ARM_GLOB_DAT"},
+ {22, "R_ARM_JUMP_SLOT"},
+ {23, "R_ARM_RELATIVE"},
+ {24, "R_ARM_GOTOFF"},
+ {25, "R_ARM_GOTPC"},
+ {26, "R_ARM_GOT32"},
+ {27, "R_ARM_PLT32"},
+ {28, "R_ARM_CALL"},
+ {29, "R_ARM_JUMP24"},
+ {30, "R_ARM_THM_JUMP24"},
+ {31, "R_ARM_BASE_ABS"},
+ {32, "R_ARM_ALU_PCREL_7_0"},
+ {33, "R_ARM_ALU_PCREL_15_8"},
+ {34, "R_ARM_ALU_PCREL_23_15"},
+ {35, "R_ARM_LDR_SBREL_11_10_NC"},
+ {36, "R_ARM_ALU_SBREL_19_12_NC"},
+ {37, "R_ARM_ALU_SBREL_27_20_CK"},
+ {38, "R_ARM_TARGET1"},
+ {39, "R_ARM_SBREL31"},
+ {40, "R_ARM_V4BX"},
+ {41, "R_ARM_TARGET2"},
+ {42, "R_ARM_PREL31"},
+ {43, "R_ARM_MOVW_ABS_NC"},
+ {44, "R_ARM_MOVT_ABS"},
+ {45, "R_ARM_MOVW_PREL_NC"},
+ {46, "R_ARM_MOVT_PREL"},
+ {47, "R_ARM_THM_MOVW_ABS_NC"},
+ {48, "R_ARM_THM_MOVT_ABS"},
+ {49, "R_ARM_THM_MOVW_PREL_NC"},
+ {50, "R_ARM_THM_MOVT_PREL"},
+ {51, "R_ARM_THM_JUMP19"},
+ {52, "R_ARM_THM_JUMP6"},
+ {53, "R_ARM_THM_ALU_PREL_11_0"},
+ {54, "R_ARM_THM_PC12"},
+ {55, "R_ARM_ABS32_NOI"},
+ {56, "R_ARM_REL32_NOI"},
+ {57, "R_ARM_ALU_PC_G0_NC"},
+ {58, "R_ARM_ALU_PC_G0"},
+ {59, "R_ARM_ALU_PC_G1_NC"},
+ {60, "R_ARM_ALU_PC_G1"},
+ {61, "R_ARM_ALU_PC_G2"},
+ {62, "R_ARM_LDR_PC_G1"},
+ {63, "R_ARM_LDR_PC_G2"},
+ {64, "R_ARM_LDRS_PC_G0"},
+ {65, "R_ARM_LDRS_PC_G1"},
+ {66, "R_ARM_LDRS_PC_G2"},
+ {67, "R_ARM_LDC_PC_G0"},
+ {68, "R_ARM_LDC_PC_G1"},
+ {69, "R_ARM_LDC_PC_G2"},
+ {70, "R_ARM_ALU_SB_G0_NC"},
+ {71, "R_ARM_ALU_SB_G0"},
+ {72, "R_ARM_ALU_SB_G1_NC"},
+ {73, "R_ARM_ALU_SB_G1"},
+ {74, "R_ARM_ALU_SB_G2"},
+ {75, "R_ARM_LDR_SB_G0"},
+ {76, "R_ARM_LDR_SB_G1"},
+ {77, "R_ARM_LDR_SB_G2"},
+ {78, "R_ARM_LDRS_SB_G0"},
+ {79, "R_ARM_LDRS_SB_G1"},
+ {80, "R_ARM_LDRS_SB_G2"},
+ {81, "R_ARM_LDC_SB_G0"},
+ {82, "R_ARM_LDC_SB_G1"},
+ {83, "R_ARM_LDC_SB_G2"},
+ {84, "R_ARM_MOVW_BREL_NC"},
+ {85, "R_ARM_MOVT_BREL"},
+ {86, "R_ARM_MOVW_BREL"},
+ {87, "R_ARM_THM_MOVW_BREL_NC"},
+ {88, "R_ARM_THM_MOVT_BREL"},
+ {89, "R_ARM_THM_MOVW_BREL"},
+ {90, "R_ARM_TLS_GOTDESC"},
+ {91, "R_ARM_TLS_CALL"},
+ {92, "R_ARM_TLS_DESCSEQ"},
+ {93, "R_ARM_THM_TLS_CALL"},
+ {94, "R_ARM_PLT32_ABS"},
+ {95, "R_ARM_GOT_ABS"},
+ {96, "R_ARM_GOT_PREL"},
+ {97, "R_ARM_GOT_BREL12"},
+ {98, "R_ARM_GOTOFF12"},
+ {99, "R_ARM_GOTRELAX"},
+ {100, "R_ARM_GNU_VTENTRY"},
+ {101, "R_ARM_GNU_VTINHERIT"},
+ {102, "R_ARM_THM_JUMP11"},
+ {103, "R_ARM_THM_JUMP8"},
+ {104, "R_ARM_TLS_GD32"},
+ {105, "R_ARM_TLS_LDM32"},
+ {106, "R_ARM_TLS_LDO32"},
+ {107, "R_ARM_TLS_IE32"},
+ {108, "R_ARM_TLS_LE32"},
+ {109, "R_ARM_TLS_LDO12"},
+ {110, "R_ARM_TLS_LE12"},
+ {111, "R_ARM_TLS_IE12GP"},
+ {112, "R_ARM_PRIVATE_0"},
+ {113, "R_ARM_PRIVATE_1"},
+ {114, "R_ARM_PRIVATE_2"},
+ {115, "R_ARM_PRIVATE_3"},
+ {116, "R_ARM_PRIVATE_4"},
+ {117, "R_ARM_PRIVATE_5"},
+ {118, "R_ARM_PRIVATE_6"},
+ {119, "R_ARM_PRIVATE_7"},
+ {120, "R_ARM_PRIVATE_8"},
+ {121, "R_ARM_PRIVATE_9"},
+ {122, "R_ARM_PRIVATE_10"},
+ {123, "R_ARM_PRIVATE_11"},
+ {124, "R_ARM_PRIVATE_12"},
+ {125, "R_ARM_PRIVATE_13"},
+ {126, "R_ARM_PRIVATE_14"},
+ {127, "R_ARM_PRIVATE_15"},
+ {128, "R_ARM_ME_TOO"},
+ {129, "R_ARM_THM_TLS_DESCSEQ16"},
+ {130, "R_ARM_THM_TLS_DESCSEQ32"},
+ {131, "R_ARM_THM_GOT_BREL12"},
+ {132, "R_ARM_THM_ALU_ABS_G0_NC"},
+ {133, "R_ARM_THM_ALU_ABS_G1_NC"},
+ {134, "R_ARM_THM_ALU_ABS_G2_NC"},
+ {135, "R_ARM_THM_ALU_ABS_G3"},
+ {160, "R_ARM_IRELATIVE"},
+ {249, "R_ARM_RXPC25"},
+ {250, "R_ARM_RSBREL32"},
+ {251, "R_ARM_THM_RPC22"},
+ {252, "R_ARM_RREL32"},
+ {253, "R_ARM_RABS32"},
+ {254, "R_ARM_RPC24"},
+ {255, "R_ARM_RBASE"},
+}
+
+func (i R_ARM) String() string { return stringName(uint32(i), rarmStrings, false) }
+func (i R_ARM) GoString() string { return stringName(uint32(i), rarmStrings, true) }
+
+// Relocation types for 386.
+type R_386 int
+
+const (
+ R_386_NONE R_386 = 0 /* No relocation. */
+ R_386_32 R_386 = 1 /* Add symbol value. */
+ R_386_PC32 R_386 = 2 /* Add PC-relative symbol value. */
+ R_386_GOT32 R_386 = 3 /* Add PC-relative GOT offset. */
+ R_386_PLT32 R_386 = 4 /* Add PC-relative PLT offset. */
+ R_386_COPY R_386 = 5 /* Copy data from shared object. */
+ R_386_GLOB_DAT R_386 = 6 /* Set GOT entry to data address. */
+ R_386_JMP_SLOT R_386 = 7 /* Set GOT entry to code address. */
+ R_386_RELATIVE R_386 = 8 /* Add load address of shared object. */
+ R_386_GOTOFF R_386 = 9 /* Add GOT-relative symbol address. */
+ R_386_GOTPC R_386 = 10 /* Add PC-relative GOT table address. */
+ R_386_32PLT R_386 = 11
+ R_386_TLS_TPOFF R_386 = 14 /* Negative offset in static TLS block */
+ R_386_TLS_IE R_386 = 15 /* Absolute address of GOT for -ve static TLS */
+ R_386_TLS_GOTIE R_386 = 16 /* GOT entry for negative static TLS block */
+ R_386_TLS_LE R_386 = 17 /* Negative offset relative to static TLS */
+ R_386_TLS_GD R_386 = 18 /* 32 bit offset to GOT (index,off) pair */
+ R_386_TLS_LDM R_386 = 19 /* 32 bit offset to GOT (index,zero) pair */
+ R_386_16 R_386 = 20
+ R_386_PC16 R_386 = 21
+ R_386_8 R_386 = 22
+ R_386_PC8 R_386 = 23
+ R_386_TLS_GD_32 R_386 = 24 /* 32 bit offset to GOT (index,off) pair */
+ R_386_TLS_GD_PUSH R_386 = 25 /* pushl instruction for Sun ABI GD sequence */
+ R_386_TLS_GD_CALL R_386 = 26 /* call instruction for Sun ABI GD sequence */
+ R_386_TLS_GD_POP R_386 = 27 /* popl instruction for Sun ABI GD sequence */
+ R_386_TLS_LDM_32 R_386 = 28 /* 32 bit offset to GOT (index,zero) pair */
+ R_386_TLS_LDM_PUSH R_386 = 29 /* pushl instruction for Sun ABI LD sequence */
+ R_386_TLS_LDM_CALL R_386 = 30 /* call instruction for Sun ABI LD sequence */
+ R_386_TLS_LDM_POP R_386 = 31 /* popl instruction for Sun ABI LD sequence */
+ R_386_TLS_LDO_32 R_386 = 32 /* 32 bit offset from start of TLS block */
+ R_386_TLS_IE_32 R_386 = 33 /* 32 bit offset to GOT static TLS offset entry */
+ R_386_TLS_LE_32 R_386 = 34 /* 32 bit offset within static TLS block */
+ R_386_TLS_DTPMOD32 R_386 = 35 /* GOT entry containing TLS index */
+ R_386_TLS_DTPOFF32 R_386 = 36 /* GOT entry containing TLS offset */
+ R_386_TLS_TPOFF32 R_386 = 37 /* GOT entry of -ve static TLS offset */
+ R_386_SIZE32 R_386 = 38
+ R_386_TLS_GOTDESC R_386 = 39
+ R_386_TLS_DESC_CALL R_386 = 40
+ R_386_TLS_DESC R_386 = 41
+ R_386_IRELATIVE R_386 = 42
+ R_386_GOT32X R_386 = 43
+)
+
+var r386Strings = []intName{
+ {0, "R_386_NONE"},
+ {1, "R_386_32"},
+ {2, "R_386_PC32"},
+ {3, "R_386_GOT32"},
+ {4, "R_386_PLT32"},
+ {5, "R_386_COPY"},
+ {6, "R_386_GLOB_DAT"},
+ {7, "R_386_JMP_SLOT"},
+ {8, "R_386_RELATIVE"},
+ {9, "R_386_GOTOFF"},
+ {10, "R_386_GOTPC"},
+ {11, "R_386_32PLT"},
+ {14, "R_386_TLS_TPOFF"},
+ {15, "R_386_TLS_IE"},
+ {16, "R_386_TLS_GOTIE"},
+ {17, "R_386_TLS_LE"},
+ {18, "R_386_TLS_GD"},
+ {19, "R_386_TLS_LDM"},
+ {20, "R_386_16"},
+ {21, "R_386_PC16"},
+ {22, "R_386_8"},
+ {23, "R_386_PC8"},
+ {24, "R_386_TLS_GD_32"},
+ {25, "R_386_TLS_GD_PUSH"},
+ {26, "R_386_TLS_GD_CALL"},
+ {27, "R_386_TLS_GD_POP"},
+ {28, "R_386_TLS_LDM_32"},
+ {29, "R_386_TLS_LDM_PUSH"},
+ {30, "R_386_TLS_LDM_CALL"},
+ {31, "R_386_TLS_LDM_POP"},
+ {32, "R_386_TLS_LDO_32"},
+ {33, "R_386_TLS_IE_32"},
+ {34, "R_386_TLS_LE_32"},
+ {35, "R_386_TLS_DTPMOD32"},
+ {36, "R_386_TLS_DTPOFF32"},
+ {37, "R_386_TLS_TPOFF32"},
+ {38, "R_386_SIZE32"},
+ {39, "R_386_TLS_GOTDESC"},
+ {40, "R_386_TLS_DESC_CALL"},
+ {41, "R_386_TLS_DESC"},
+ {42, "R_386_IRELATIVE"},
+ {43, "R_386_GOT32X"},
+}
+
+func (i R_386) String() string { return stringName(uint32(i), r386Strings, false) }
+func (i R_386) GoString() string { return stringName(uint32(i), r386Strings, true) }
+
+// Relocation types for MIPS.
+type R_MIPS int
+
+const (
+ R_MIPS_NONE R_MIPS = 0
+ R_MIPS_16 R_MIPS = 1
+ R_MIPS_32 R_MIPS = 2
+ R_MIPS_REL32 R_MIPS = 3
+ R_MIPS_26 R_MIPS = 4
+ R_MIPS_HI16 R_MIPS = 5 /* high 16 bits of symbol value */
+ R_MIPS_LO16 R_MIPS = 6 /* low 16 bits of symbol value */
+ R_MIPS_GPREL16 R_MIPS = 7 /* GP-relative reference */
+ R_MIPS_LITERAL R_MIPS = 8 /* Reference to literal section */
+ R_MIPS_GOT16 R_MIPS = 9 /* Reference to global offset table */
+ R_MIPS_PC16 R_MIPS = 10 /* 16 bit PC relative reference */
+ R_MIPS_CALL16 R_MIPS = 11 /* 16 bit call through glbl offset tbl */
+ R_MIPS_GPREL32 R_MIPS = 12
+ R_MIPS_SHIFT5 R_MIPS = 16
+ R_MIPS_SHIFT6 R_MIPS = 17
+ R_MIPS_64 R_MIPS = 18
+ R_MIPS_GOT_DISP R_MIPS = 19
+ R_MIPS_GOT_PAGE R_MIPS = 20
+ R_MIPS_GOT_OFST R_MIPS = 21
+ R_MIPS_GOT_HI16 R_MIPS = 22
+ R_MIPS_GOT_LO16 R_MIPS = 23
+ R_MIPS_SUB R_MIPS = 24
+ R_MIPS_INSERT_A R_MIPS = 25
+ R_MIPS_INSERT_B R_MIPS = 26
+ R_MIPS_DELETE R_MIPS = 27
+ R_MIPS_HIGHER R_MIPS = 28
+ R_MIPS_HIGHEST R_MIPS = 29
+ R_MIPS_CALL_HI16 R_MIPS = 30
+ R_MIPS_CALL_LO16 R_MIPS = 31
+ R_MIPS_SCN_DISP R_MIPS = 32
+ R_MIPS_REL16 R_MIPS = 33
+ R_MIPS_ADD_IMMEDIATE R_MIPS = 34
+ R_MIPS_PJUMP R_MIPS = 35
+ R_MIPS_RELGOT R_MIPS = 36
+ R_MIPS_JALR R_MIPS = 37
+
+ R_MIPS_TLS_DTPMOD32 R_MIPS = 38 /* Module number 32 bit */
+ R_MIPS_TLS_DTPREL32 R_MIPS = 39 /* Module-relative offset 32 bit */
+ R_MIPS_TLS_DTPMOD64 R_MIPS = 40 /* Module number 64 bit */
+ R_MIPS_TLS_DTPREL64 R_MIPS = 41 /* Module-relative offset 64 bit */
+ R_MIPS_TLS_GD R_MIPS = 42 /* 16 bit GOT offset for GD */
+ R_MIPS_TLS_LDM R_MIPS = 43 /* 16 bit GOT offset for LDM */
+ R_MIPS_TLS_DTPREL_HI16 R_MIPS = 44 /* Module-relative offset, high 16 bits */
+ R_MIPS_TLS_DTPREL_LO16 R_MIPS = 45 /* Module-relative offset, low 16 bits */
+ R_MIPS_TLS_GOTTPREL R_MIPS = 46 /* 16 bit GOT offset for IE */
+ R_MIPS_TLS_TPREL32 R_MIPS = 47 /* TP-relative offset, 32 bit */
+ R_MIPS_TLS_TPREL64 R_MIPS = 48 /* TP-relative offset, 64 bit */
+ R_MIPS_TLS_TPREL_HI16 R_MIPS = 49 /* TP-relative offset, high 16 bits */
+ R_MIPS_TLS_TPREL_LO16 R_MIPS = 50 /* TP-relative offset, low 16 bits */
+)
+
+var rmipsStrings = []intName{
+ {0, "R_MIPS_NONE"},
+ {1, "R_MIPS_16"},
+ {2, "R_MIPS_32"},
+ {3, "R_MIPS_REL32"},
+ {4, "R_MIPS_26"},
+ {5, "R_MIPS_HI16"},
+ {6, "R_MIPS_LO16"},
+ {7, "R_MIPS_GPREL16"},
+ {8, "R_MIPS_LITERAL"},
+ {9, "R_MIPS_GOT16"},
+ {10, "R_MIPS_PC16"},
+ {11, "R_MIPS_CALL16"},
+ {12, "R_MIPS_GPREL32"},
+ {16, "R_MIPS_SHIFT5"},
+ {17, "R_MIPS_SHIFT6"},
+ {18, "R_MIPS_64"},
+ {19, "R_MIPS_GOT_DISP"},
+ {20, "R_MIPS_GOT_PAGE"},
+ {21, "R_MIPS_GOT_OFST"},
+ {22, "R_MIPS_GOT_HI16"},
+ {23, "R_MIPS_GOT_LO16"},
+ {24, "R_MIPS_SUB"},
+ {25, "R_MIPS_INSERT_A"},
+ {26, "R_MIPS_INSERT_B"},
+ {27, "R_MIPS_DELETE"},
+ {28, "R_MIPS_HIGHER"},
+ {29, "R_MIPS_HIGHEST"},
+ {30, "R_MIPS_CALL_HI16"},
+ {31, "R_MIPS_CALL_LO16"},
+ {32, "R_MIPS_SCN_DISP"},
+ {33, "R_MIPS_REL16"},
+ {34, "R_MIPS_ADD_IMMEDIATE"},
+ {35, "R_MIPS_PJUMP"},
+ {36, "R_MIPS_RELGOT"},
+ {37, "R_MIPS_JALR"},
+ {38, "R_MIPS_TLS_DTPMOD32"},
+ {39, "R_MIPS_TLS_DTPREL32"},
+ {40, "R_MIPS_TLS_DTPMOD64"},
+ {41, "R_MIPS_TLS_DTPREL64"},
+ {42, "R_MIPS_TLS_GD"},
+ {43, "R_MIPS_TLS_LDM"},
+ {44, "R_MIPS_TLS_DTPREL_HI16"},
+ {45, "R_MIPS_TLS_DTPREL_LO16"},
+ {46, "R_MIPS_TLS_GOTTPREL"},
+ {47, "R_MIPS_TLS_TPREL32"},
+ {48, "R_MIPS_TLS_TPREL64"},
+ {49, "R_MIPS_TLS_TPREL_HI16"},
+ {50, "R_MIPS_TLS_TPREL_LO16"},
+}
+
+func (i R_MIPS) String() string { return stringName(uint32(i), rmipsStrings, false) }
+func (i R_MIPS) GoString() string { return stringName(uint32(i), rmipsStrings, true) }
+
+// Relocation types for LoongArch.
+type R_LARCH int
+
+const (
+ R_LARCH_NONE R_LARCH = 0
+ R_LARCH_32 R_LARCH = 1
+ R_LARCH_64 R_LARCH = 2
+ R_LARCH_RELATIVE R_LARCH = 3
+ R_LARCH_COPY R_LARCH = 4
+ R_LARCH_JUMP_SLOT R_LARCH = 5
+ R_LARCH_TLS_DTPMOD32 R_LARCH = 6
+ R_LARCH_TLS_DTPMOD64 R_LARCH = 7
+ R_LARCH_TLS_DTPREL32 R_LARCH = 8
+ R_LARCH_TLS_DTPREL64 R_LARCH = 9
+ R_LARCH_TLS_TPREL32 R_LARCH = 10
+ R_LARCH_TLS_TPREL64 R_LARCH = 11
+ R_LARCH_IRELATIVE R_LARCH = 12
+ R_LARCH_MARK_LA R_LARCH = 20
+ R_LARCH_MARK_PCREL R_LARCH = 21
+ R_LARCH_SOP_PUSH_PCREL R_LARCH = 22
+ R_LARCH_SOP_PUSH_ABSOLUTE R_LARCH = 23
+ R_LARCH_SOP_PUSH_DUP R_LARCH = 24
+ R_LARCH_SOP_PUSH_GPREL R_LARCH = 25
+ R_LARCH_SOP_PUSH_TLS_TPREL R_LARCH = 26
+ R_LARCH_SOP_PUSH_TLS_GOT R_LARCH = 27
+ R_LARCH_SOP_PUSH_TLS_GD R_LARCH = 28
+ R_LARCH_SOP_PUSH_PLT_PCREL R_LARCH = 29
+ R_LARCH_SOP_ASSERT R_LARCH = 30
+ R_LARCH_SOP_NOT R_LARCH = 31
+ R_LARCH_SOP_SUB R_LARCH = 32
+ R_LARCH_SOP_SL R_LARCH = 33
+ R_LARCH_SOP_SR R_LARCH = 34
+ R_LARCH_SOP_ADD R_LARCH = 35
+ R_LARCH_SOP_AND R_LARCH = 36
+ R_LARCH_SOP_IF_ELSE R_LARCH = 37
+ R_LARCH_SOP_POP_32_S_10_5 R_LARCH = 38
+ R_LARCH_SOP_POP_32_U_10_12 R_LARCH = 39
+ R_LARCH_SOP_POP_32_S_10_12 R_LARCH = 40
+ R_LARCH_SOP_POP_32_S_10_16 R_LARCH = 41
+ R_LARCH_SOP_POP_32_S_10_16_S2 R_LARCH = 42
+ R_LARCH_SOP_POP_32_S_5_20 R_LARCH = 43
+ R_LARCH_SOP_POP_32_S_0_5_10_16_S2 R_LARCH = 44
+ R_LARCH_SOP_POP_32_S_0_10_10_16_S2 R_LARCH = 45
+ R_LARCH_SOP_POP_32_U R_LARCH = 46
+ R_LARCH_ADD8 R_LARCH = 47
+ R_LARCH_ADD16 R_LARCH = 48
+ R_LARCH_ADD24 R_LARCH = 49
+ R_LARCH_ADD32 R_LARCH = 50
+ R_LARCH_ADD64 R_LARCH = 51
+ R_LARCH_SUB8 R_LARCH = 52
+ R_LARCH_SUB16 R_LARCH = 53
+ R_LARCH_SUB24 R_LARCH = 54
+ R_LARCH_SUB32 R_LARCH = 55
+ R_LARCH_SUB64 R_LARCH = 56
+ R_LARCH_GNU_VTINHERIT R_LARCH = 57
+ R_LARCH_GNU_VTENTRY R_LARCH = 58
+ R_LARCH_B16 R_LARCH = 64
+ R_LARCH_B21 R_LARCH = 65
+ R_LARCH_B26 R_LARCH = 66
+ R_LARCH_ABS_HI20 R_LARCH = 67
+ R_LARCH_ABS_LO12 R_LARCH = 68
+ R_LARCH_ABS64_LO20 R_LARCH = 69
+ R_LARCH_ABS64_HI12 R_LARCH = 70
+ R_LARCH_PCALA_HI20 R_LARCH = 71
+ R_LARCH_PCALA_LO12 R_LARCH = 72
+ R_LARCH_PCALA64_LO20 R_LARCH = 73
+ R_LARCH_PCALA64_HI12 R_LARCH = 74
+ R_LARCH_GOT_PC_HI20 R_LARCH = 75
+ R_LARCH_GOT_PC_LO12 R_LARCH = 76
+ R_LARCH_GOT64_PC_LO20 R_LARCH = 77
+ R_LARCH_GOT64_PC_HI12 R_LARCH = 78
+ R_LARCH_GOT_HI20 R_LARCH = 79
+ R_LARCH_GOT_LO12 R_LARCH = 80
+ R_LARCH_GOT64_LO20 R_LARCH = 81
+ R_LARCH_GOT64_HI12 R_LARCH = 82
+ R_LARCH_TLS_LE_HI20 R_LARCH = 83
+ R_LARCH_TLS_LE_LO12 R_LARCH = 84
+ R_LARCH_TLS_LE64_LO20 R_LARCH = 85
+ R_LARCH_TLS_LE64_HI12 R_LARCH = 86
+ R_LARCH_TLS_IE_PC_HI20 R_LARCH = 87
+ R_LARCH_TLS_IE_PC_LO12 R_LARCH = 88
+ R_LARCH_TLS_IE64_PC_LO20 R_LARCH = 89
+ R_LARCH_TLS_IE64_PC_HI12 R_LARCH = 90
+ R_LARCH_TLS_IE_HI20 R_LARCH = 91
+ R_LARCH_TLS_IE_LO12 R_LARCH = 92
+ R_LARCH_TLS_IE64_LO20 R_LARCH = 93
+ R_LARCH_TLS_IE64_HI12 R_LARCH = 94
+ R_LARCH_TLS_LD_PC_HI20 R_LARCH = 95
+ R_LARCH_TLS_LD_HI20 R_LARCH = 96
+ R_LARCH_TLS_GD_PC_HI20 R_LARCH = 97
+ R_LARCH_TLS_GD_HI20 R_LARCH = 98
+ R_LARCH_32_PCREL R_LARCH = 99
+ R_LARCH_RELAX R_LARCH = 100
+)
+
+var rlarchStrings = []intName{
+ {0, "R_LARCH_NONE"},
+ {1, "R_LARCH_32"},
+ {2, "R_LARCH_64"},
+ {3, "R_LARCH_RELATIVE"},
+ {4, "R_LARCH_COPY"},
+ {5, "R_LARCH_JUMP_SLOT"},
+ {6, "R_LARCH_TLS_DTPMOD32"},
+ {7, "R_LARCH_TLS_DTPMOD64"},
+ {8, "R_LARCH_TLS_DTPREL32"},
+ {9, "R_LARCH_TLS_DTPREL64"},
+ {10, "R_LARCH_TLS_TPREL32"},
+ {11, "R_LARCH_TLS_TPREL64"},
+ {12, "R_LARCH_IRELATIVE"},
+ {20, "R_LARCH_MARK_LA"},
+ {21, "R_LARCH_MARK_PCREL"},
+ {22, "R_LARCH_SOP_PUSH_PCREL"},
+ {23, "R_LARCH_SOP_PUSH_ABSOLUTE"},
+ {24, "R_LARCH_SOP_PUSH_DUP"},
+ {25, "R_LARCH_SOP_PUSH_GPREL"},
+ {26, "R_LARCH_SOP_PUSH_TLS_TPREL"},
+ {27, "R_LARCH_SOP_PUSH_TLS_GOT"},
+ {28, "R_LARCH_SOP_PUSH_TLS_GD"},
+ {29, "R_LARCH_SOP_PUSH_PLT_PCREL"},
+ {30, "R_LARCH_SOP_ASSERT"},
+ {31, "R_LARCH_SOP_NOT"},
+ {32, "R_LARCH_SOP_SUB"},
+ {33, "R_LARCH_SOP_SL"},
+ {34, "R_LARCH_SOP_SR"},
+ {35, "R_LARCH_SOP_ADD"},
+ {36, "R_LARCH_SOP_AND"},
+ {37, "R_LARCH_SOP_IF_ELSE"},
+ {38, "R_LARCH_SOP_POP_32_S_10_5"},
+ {39, "R_LARCH_SOP_POP_32_U_10_12"},
+ {40, "R_LARCH_SOP_POP_32_S_10_12"},
+ {41, "R_LARCH_SOP_POP_32_S_10_16"},
+ {42, "R_LARCH_SOP_POP_32_S_10_16_S2"},
+ {43, "R_LARCH_SOP_POP_32_S_5_20"},
+ {44, "R_LARCH_SOP_POP_32_S_0_5_10_16_S2"},
+ {45, "R_LARCH_SOP_POP_32_S_0_10_10_16_S2"},
+ {46, "R_LARCH_SOP_POP_32_U"},
+ {47, "R_LARCH_ADD8"},
+ {48, "R_LARCH_ADD16"},
+ {49, "R_LARCH_ADD24"},
+ {50, "R_LARCH_ADD32"},
+ {51, "R_LARCH_ADD64"},
+ {52, "R_LARCH_SUB8"},
+ {53, "R_LARCH_SUB16"},
+ {54, "R_LARCH_SUB24"},
+ {55, "R_LARCH_SUB32"},
+ {56, "R_LARCH_SUB64"},
+ {57, "R_LARCH_GNU_VTINHERIT"},
+ {58, "R_LARCH_GNU_VTENTRY"},
+ {64, "R_LARCH_B16"},
+ {65, "R_LARCH_B21"},
+ {66, "R_LARCH_B26"},
+ {67, "R_LARCH_ABS_HI20"},
+ {68, "R_LARCH_ABS_LO12"},
+ {69, "R_LARCH_ABS64_LO20"},
+ {70, "R_LARCH_ABS64_HI12"},
+ {71, "R_LARCH_PCALA_HI20"},
+ {72, "R_LARCH_PCALA_LO12"},
+ {73, "R_LARCH_PCALA64_LO20"},
+ {74, "R_LARCH_PCALA64_HI12"},
+ {75, "R_LARCH_GOT_PC_HI20"},
+ {76, "R_LARCH_GOT_PC_LO12"},
+ {77, "R_LARCH_GOT64_PC_LO20"},
+ {78, "R_LARCH_GOT64_PC_HI12"},
+ {79, "R_LARCH_GOT_HI20"},
+ {80, "R_LARCH_GOT_LO12"},
+ {81, "R_LARCH_GOT64_LO20"},
+ {82, "R_LARCH_GOT64_HI12"},
+ {83, "R_LARCH_TLS_LE_HI20"},
+ {84, "R_LARCH_TLS_LE_LO12"},
+ {85, "R_LARCH_TLS_LE64_LO20"},
+ {86, "R_LARCH_TLS_LE64_HI12"},
+ {87, "R_LARCH_TLS_IE_PC_HI20"},
+ {88, "R_LARCH_TLS_IE_PC_LO12"},
+ {89, "R_LARCH_TLS_IE64_PC_LO20"},
+ {90, "R_LARCH_TLS_IE64_PC_HI12"},
+ {91, "R_LARCH_TLS_IE_HI20"},
+ {92, "R_LARCH_TLS_IE_LO12"},
+ {93, "R_LARCH_TLS_IE64_LO20"},
+ {94, "R_LARCH_TLS_IE64_HI12"},
+ {95, "R_LARCH_TLS_LD_PC_HI20"},
+ {96, "R_LARCH_TLS_LD_HI20"},
+ {97, "R_LARCH_TLS_GD_PC_HI20"},
+ {98, "R_LARCH_TLS_GD_HI20"},
+ {99, "R_LARCH_32_PCREL"},
+ {100, "R_LARCH_RELAX"},
+}
+
+func (i R_LARCH) String() string { return stringName(uint32(i), rlarchStrings, false) }
+func (i R_LARCH) GoString() string { return stringName(uint32(i), rlarchStrings, true) }
+
+// Relocation types for PowerPC.
+//
+// Values that are shared by both R_PPC and R_PPC64 are prefixed with
+// R_POWERPC_ in the ELF standard. For the R_PPC type, the relevant
+// shared relocations have been renamed with the prefix R_PPC_.
+// The original name follows the value in a comment.
+type R_PPC int
+
+const (
+ R_PPC_NONE R_PPC = 0 // R_POWERPC_NONE
+ R_PPC_ADDR32 R_PPC = 1 // R_POWERPC_ADDR32
+ R_PPC_ADDR24 R_PPC = 2 // R_POWERPC_ADDR24
+ R_PPC_ADDR16 R_PPC = 3 // R_POWERPC_ADDR16
+ R_PPC_ADDR16_LO R_PPC = 4 // R_POWERPC_ADDR16_LO
+ R_PPC_ADDR16_HI R_PPC = 5 // R_POWERPC_ADDR16_HI
+ R_PPC_ADDR16_HA R_PPC = 6 // R_POWERPC_ADDR16_HA
+ R_PPC_ADDR14 R_PPC = 7 // R_POWERPC_ADDR14
+ R_PPC_ADDR14_BRTAKEN R_PPC = 8 // R_POWERPC_ADDR14_BRTAKEN
+ R_PPC_ADDR14_BRNTAKEN R_PPC = 9 // R_POWERPC_ADDR14_BRNTAKEN
+ R_PPC_REL24 R_PPC = 10 // R_POWERPC_REL24
+ R_PPC_REL14 R_PPC = 11 // R_POWERPC_REL14
+ R_PPC_REL14_BRTAKEN R_PPC = 12 // R_POWERPC_REL14_BRTAKEN
+ R_PPC_REL14_BRNTAKEN R_PPC = 13 // R_POWERPC_REL14_BRNTAKEN
+ R_PPC_GOT16 R_PPC = 14 // R_POWERPC_GOT16
+ R_PPC_GOT16_LO R_PPC = 15 // R_POWERPC_GOT16_LO
+ R_PPC_GOT16_HI R_PPC = 16 // R_POWERPC_GOT16_HI
+ R_PPC_GOT16_HA R_PPC = 17 // R_POWERPC_GOT16_HA
+ R_PPC_PLTREL24 R_PPC = 18
+ R_PPC_COPY R_PPC = 19 // R_POWERPC_COPY
+ R_PPC_GLOB_DAT R_PPC = 20 // R_POWERPC_GLOB_DAT
+ R_PPC_JMP_SLOT R_PPC = 21 // R_POWERPC_JMP_SLOT
+ R_PPC_RELATIVE R_PPC = 22 // R_POWERPC_RELATIVE
+ R_PPC_LOCAL24PC R_PPC = 23
+ R_PPC_UADDR32 R_PPC = 24 // R_POWERPC_UADDR32
+ R_PPC_UADDR16 R_PPC = 25 // R_POWERPC_UADDR16
+ R_PPC_REL32 R_PPC = 26 // R_POWERPC_REL32
+ R_PPC_PLT32 R_PPC = 27 // R_POWERPC_PLT32
+ R_PPC_PLTREL32 R_PPC = 28 // R_POWERPC_PLTREL32
+ R_PPC_PLT16_LO R_PPC = 29 // R_POWERPC_PLT16_LO
+ R_PPC_PLT16_HI R_PPC = 30 // R_POWERPC_PLT16_HI
+ R_PPC_PLT16_HA R_PPC = 31 // R_POWERPC_PLT16_HA
+ R_PPC_SDAREL16 R_PPC = 32
+ R_PPC_SECTOFF R_PPC = 33 // R_POWERPC_SECTOFF
+ R_PPC_SECTOFF_LO R_PPC = 34 // R_POWERPC_SECTOFF_LO
+ R_PPC_SECTOFF_HI R_PPC = 35 // R_POWERPC_SECTOFF_HI
+ R_PPC_SECTOFF_HA R_PPC = 36 // R_POWERPC_SECTOFF_HA
+ R_PPC_TLS R_PPC = 67 // R_POWERPC_TLS
+ R_PPC_DTPMOD32 R_PPC = 68 // R_POWERPC_DTPMOD32
+ R_PPC_TPREL16 R_PPC = 69 // R_POWERPC_TPREL16
+ R_PPC_TPREL16_LO R_PPC = 70 // R_POWERPC_TPREL16_LO
+ R_PPC_TPREL16_HI R_PPC = 71 // R_POWERPC_TPREL16_HI
+ R_PPC_TPREL16_HA R_PPC = 72 // R_POWERPC_TPREL16_HA
+ R_PPC_TPREL32 R_PPC = 73 // R_POWERPC_TPREL32
+ R_PPC_DTPREL16 R_PPC = 74 // R_POWERPC_DTPREL16
+ R_PPC_DTPREL16_LO R_PPC = 75 // R_POWERPC_DTPREL16_LO
+ R_PPC_DTPREL16_HI R_PPC = 76 // R_POWERPC_DTPREL16_HI
+ R_PPC_DTPREL16_HA R_PPC = 77 // R_POWERPC_DTPREL16_HA
+ R_PPC_DTPREL32 R_PPC = 78 // R_POWERPC_DTPREL32
+ R_PPC_GOT_TLSGD16 R_PPC = 79 // R_POWERPC_GOT_TLSGD16
+ R_PPC_GOT_TLSGD16_LO R_PPC = 80 // R_POWERPC_GOT_TLSGD16_LO
+ R_PPC_GOT_TLSGD16_HI R_PPC = 81 // R_POWERPC_GOT_TLSGD16_HI
+ R_PPC_GOT_TLSGD16_HA R_PPC = 82 // R_POWERPC_GOT_TLSGD16_HA
+ R_PPC_GOT_TLSLD16 R_PPC = 83 // R_POWERPC_GOT_TLSLD16
+ R_PPC_GOT_TLSLD16_LO R_PPC = 84 // R_POWERPC_GOT_TLSLD16_LO
+ R_PPC_GOT_TLSLD16_HI R_PPC = 85 // R_POWERPC_GOT_TLSLD16_HI
+ R_PPC_GOT_TLSLD16_HA R_PPC = 86 // R_POWERPC_GOT_TLSLD16_HA
+ R_PPC_GOT_TPREL16 R_PPC = 87 // R_POWERPC_GOT_TPREL16
+ R_PPC_GOT_TPREL16_LO R_PPC = 88 // R_POWERPC_GOT_TPREL16_LO
+ R_PPC_GOT_TPREL16_HI R_PPC = 89 // R_POWERPC_GOT_TPREL16_HI
+ R_PPC_GOT_TPREL16_HA R_PPC = 90 // R_POWERPC_GOT_TPREL16_HA
+ R_PPC_EMB_NADDR32 R_PPC = 101
+ R_PPC_EMB_NADDR16 R_PPC = 102
+ R_PPC_EMB_NADDR16_LO R_PPC = 103
+ R_PPC_EMB_NADDR16_HI R_PPC = 104
+ R_PPC_EMB_NADDR16_HA R_PPC = 105
+ R_PPC_EMB_SDAI16 R_PPC = 106
+ R_PPC_EMB_SDA2I16 R_PPC = 107
+ R_PPC_EMB_SDA2REL R_PPC = 108
+ R_PPC_EMB_SDA21 R_PPC = 109
+ R_PPC_EMB_MRKREF R_PPC = 110
+ R_PPC_EMB_RELSEC16 R_PPC = 111
+ R_PPC_EMB_RELST_LO R_PPC = 112
+ R_PPC_EMB_RELST_HI R_PPC = 113
+ R_PPC_EMB_RELST_HA R_PPC = 114
+ R_PPC_EMB_BIT_FLD R_PPC = 115
+ R_PPC_EMB_RELSDA R_PPC = 116
+)
+
+var rppcStrings = []intName{
+ {0, "R_PPC_NONE"},
+ {1, "R_PPC_ADDR32"},
+ {2, "R_PPC_ADDR24"},
+ {3, "R_PPC_ADDR16"},
+ {4, "R_PPC_ADDR16_LO"},
+ {5, "R_PPC_ADDR16_HI"},
+ {6, "R_PPC_ADDR16_HA"},
+ {7, "R_PPC_ADDR14"},
+ {8, "R_PPC_ADDR14_BRTAKEN"},
+ {9, "R_PPC_ADDR14_BRNTAKEN"},
+ {10, "R_PPC_REL24"},
+ {11, "R_PPC_REL14"},
+ {12, "R_PPC_REL14_BRTAKEN"},
+ {13, "R_PPC_REL14_BRNTAKEN"},
+ {14, "R_PPC_GOT16"},
+ {15, "R_PPC_GOT16_LO"},
+ {16, "R_PPC_GOT16_HI"},
+ {17, "R_PPC_GOT16_HA"},
+ {18, "R_PPC_PLTREL24"},
+ {19, "R_PPC_COPY"},
+ {20, "R_PPC_GLOB_DAT"},
+ {21, "R_PPC_JMP_SLOT"},
+ {22, "R_PPC_RELATIVE"},
+ {23, "R_PPC_LOCAL24PC"},
+ {24, "R_PPC_UADDR32"},
+ {25, "R_PPC_UADDR16"},
+ {26, "R_PPC_REL32"},
+ {27, "R_PPC_PLT32"},
+ {28, "R_PPC_PLTREL32"},
+ {29, "R_PPC_PLT16_LO"},
+ {30, "R_PPC_PLT16_HI"},
+ {31, "R_PPC_PLT16_HA"},
+ {32, "R_PPC_SDAREL16"},
+ {33, "R_PPC_SECTOFF"},
+ {34, "R_PPC_SECTOFF_LO"},
+ {35, "R_PPC_SECTOFF_HI"},
+ {36, "R_PPC_SECTOFF_HA"},
+ {67, "R_PPC_TLS"},
+ {68, "R_PPC_DTPMOD32"},
+ {69, "R_PPC_TPREL16"},
+ {70, "R_PPC_TPREL16_LO"},
+ {71, "R_PPC_TPREL16_HI"},
+ {72, "R_PPC_TPREL16_HA"},
+ {73, "R_PPC_TPREL32"},
+ {74, "R_PPC_DTPREL16"},
+ {75, "R_PPC_DTPREL16_LO"},
+ {76, "R_PPC_DTPREL16_HI"},
+ {77, "R_PPC_DTPREL16_HA"},
+ {78, "R_PPC_DTPREL32"},
+ {79, "R_PPC_GOT_TLSGD16"},
+ {80, "R_PPC_GOT_TLSGD16_LO"},
+ {81, "R_PPC_GOT_TLSGD16_HI"},
+ {82, "R_PPC_GOT_TLSGD16_HA"},
+ {83, "R_PPC_GOT_TLSLD16"},
+ {84, "R_PPC_GOT_TLSLD16_LO"},
+ {85, "R_PPC_GOT_TLSLD16_HI"},
+ {86, "R_PPC_GOT_TLSLD16_HA"},
+ {87, "R_PPC_GOT_TPREL16"},
+ {88, "R_PPC_GOT_TPREL16_LO"},
+ {89, "R_PPC_GOT_TPREL16_HI"},
+ {90, "R_PPC_GOT_TPREL16_HA"},
+ {101, "R_PPC_EMB_NADDR32"},
+ {102, "R_PPC_EMB_NADDR16"},
+ {103, "R_PPC_EMB_NADDR16_LO"},
+ {104, "R_PPC_EMB_NADDR16_HI"},
+ {105, "R_PPC_EMB_NADDR16_HA"},
+ {106, "R_PPC_EMB_SDAI16"},
+ {107, "R_PPC_EMB_SDA2I16"},
+ {108, "R_PPC_EMB_SDA2REL"},
+ {109, "R_PPC_EMB_SDA21"},
+ {110, "R_PPC_EMB_MRKREF"},
+ {111, "R_PPC_EMB_RELSEC16"},
+ {112, "R_PPC_EMB_RELST_LO"},
+ {113, "R_PPC_EMB_RELST_HI"},
+ {114, "R_PPC_EMB_RELST_HA"},
+ {115, "R_PPC_EMB_BIT_FLD"},
+ {116, "R_PPC_EMB_RELSDA"},
+}
+
+func (i R_PPC) String() string { return stringName(uint32(i), rppcStrings, false) }
+func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) }
+
+// Relocation types for 64-bit PowerPC or Power Architecture processors.
+//
+// Values that are shared by both R_PPC and R_PPC64 are prefixed with
+// R_POWERPC_ in the ELF standard. For the R_PPC64 type, the relevant
+// shared relocations have been renamed with the prefix R_PPC64_.
+// The original name follows the value in a comment.
+type R_PPC64 int
+
+const (
+ R_PPC64_NONE R_PPC64 = 0 // R_POWERPC_NONE
+ R_PPC64_ADDR32 R_PPC64 = 1 // R_POWERPC_ADDR32
+ R_PPC64_ADDR24 R_PPC64 = 2 // R_POWERPC_ADDR24
+ R_PPC64_ADDR16 R_PPC64 = 3 // R_POWERPC_ADDR16
+ R_PPC64_ADDR16_LO R_PPC64 = 4 // R_POWERPC_ADDR16_LO
+ R_PPC64_ADDR16_HI R_PPC64 = 5 // R_POWERPC_ADDR16_HI
+ R_PPC64_ADDR16_HA R_PPC64 = 6 // R_POWERPC_ADDR16_HA
+ R_PPC64_ADDR14 R_PPC64 = 7 // R_POWERPC_ADDR14
+ R_PPC64_ADDR14_BRTAKEN R_PPC64 = 8 // R_POWERPC_ADDR14_BRTAKEN
+ R_PPC64_ADDR14_BRNTAKEN R_PPC64 = 9 // R_POWERPC_ADDR14_BRNTAKEN
+ R_PPC64_REL24 R_PPC64 = 10 // R_POWERPC_REL24
+ R_PPC64_REL14 R_PPC64 = 11 // R_POWERPC_REL14
+ R_PPC64_REL14_BRTAKEN R_PPC64 = 12 // R_POWERPC_REL14_BRTAKEN
+ R_PPC64_REL14_BRNTAKEN R_PPC64 = 13 // R_POWERPC_REL14_BRNTAKEN
+ R_PPC64_GOT16 R_PPC64 = 14 // R_POWERPC_GOT16
+ R_PPC64_GOT16_LO R_PPC64 = 15 // R_POWERPC_GOT16_LO
+ R_PPC64_GOT16_HI R_PPC64 = 16 // R_POWERPC_GOT16_HI
+ R_PPC64_GOT16_HA R_PPC64 = 17 // R_POWERPC_GOT16_HA
+ R_PPC64_COPY R_PPC64 = 19 // R_POWERPC_COPY
+ R_PPC64_GLOB_DAT R_PPC64 = 20 // R_POWERPC_GLOB_DAT
+ R_PPC64_JMP_SLOT R_PPC64 = 21 // R_POWERPC_JMP_SLOT
+ R_PPC64_RELATIVE R_PPC64 = 22 // R_POWERPC_RELATIVE
+ R_PPC64_UADDR32 R_PPC64 = 24 // R_POWERPC_UADDR32
+ R_PPC64_UADDR16 R_PPC64 = 25 // R_POWERPC_UADDR16
+ R_PPC64_REL32 R_PPC64 = 26 // R_POWERPC_REL32
+ R_PPC64_PLT32 R_PPC64 = 27 // R_POWERPC_PLT32
+ R_PPC64_PLTREL32 R_PPC64 = 28 // R_POWERPC_PLTREL32
+ R_PPC64_PLT16_LO R_PPC64 = 29 // R_POWERPC_PLT16_LO
+ R_PPC64_PLT16_HI R_PPC64 = 30 // R_POWERPC_PLT16_HI
+ R_PPC64_PLT16_HA R_PPC64 = 31 // R_POWERPC_PLT16_HA
+ R_PPC64_SECTOFF R_PPC64 = 33 // R_POWERPC_SECTOFF
+ R_PPC64_SECTOFF_LO R_PPC64 = 34 // R_POWERPC_SECTOFF_LO
+ R_PPC64_SECTOFF_HI R_PPC64 = 35 // R_POWERPC_SECTOFF_HI
+ R_PPC64_SECTOFF_HA R_PPC64 = 36 // R_POWERPC_SECTOFF_HA
+ R_PPC64_REL30 R_PPC64 = 37 // R_POWERPC_ADDR30
+ R_PPC64_ADDR64 R_PPC64 = 38
+ R_PPC64_ADDR16_HIGHER R_PPC64 = 39
+ R_PPC64_ADDR16_HIGHERA R_PPC64 = 40
+ R_PPC64_ADDR16_HIGHEST R_PPC64 = 41
+ R_PPC64_ADDR16_HIGHESTA R_PPC64 = 42
+ R_PPC64_UADDR64 R_PPC64 = 43
+ R_PPC64_REL64 R_PPC64 = 44
+ R_PPC64_PLT64 R_PPC64 = 45
+ R_PPC64_PLTREL64 R_PPC64 = 46
+ R_PPC64_TOC16 R_PPC64 = 47
+ R_PPC64_TOC16_LO R_PPC64 = 48
+ R_PPC64_TOC16_HI R_PPC64 = 49
+ R_PPC64_TOC16_HA R_PPC64 = 50
+ R_PPC64_TOC R_PPC64 = 51
+ R_PPC64_PLTGOT16 R_PPC64 = 52
+ R_PPC64_PLTGOT16_LO R_PPC64 = 53
+ R_PPC64_PLTGOT16_HI R_PPC64 = 54
+ R_PPC64_PLTGOT16_HA R_PPC64 = 55
+ R_PPC64_ADDR16_DS R_PPC64 = 56
+ R_PPC64_ADDR16_LO_DS R_PPC64 = 57
+ R_PPC64_GOT16_DS R_PPC64 = 58
+ R_PPC64_GOT16_LO_DS R_PPC64 = 59
+ R_PPC64_PLT16_LO_DS R_PPC64 = 60
+ R_PPC64_SECTOFF_DS R_PPC64 = 61
+ R_PPC64_SECTOFF_LO_DS R_PPC64 = 62
+ R_PPC64_TOC16_DS R_PPC64 = 63
+ R_PPC64_TOC16_LO_DS R_PPC64 = 64
+ R_PPC64_PLTGOT16_DS R_PPC64 = 65
+ R_PPC64_PLTGOT_LO_DS R_PPC64 = 66
+ R_PPC64_TLS R_PPC64 = 67 // R_POWERPC_TLS
+ R_PPC64_DTPMOD64 R_PPC64 = 68 // R_POWERPC_DTPMOD64
+ R_PPC64_TPREL16 R_PPC64 = 69 // R_POWERPC_TPREL16
+ R_PPC64_TPREL16_LO R_PPC64 = 70 // R_POWERPC_TPREL16_LO
+ R_PPC64_TPREL16_HI R_PPC64 = 71 // R_POWERPC_TPREL16_HI
+ R_PPC64_TPREL16_HA R_PPC64 = 72 // R_POWERPC_TPREL16_HA
+ R_PPC64_TPREL64 R_PPC64 = 73 // R_POWERPC_TPREL64
+ R_PPC64_DTPREL16 R_PPC64 = 74 // R_POWERPC_DTPREL16
+ R_PPC64_DTPREL16_LO R_PPC64 = 75 // R_POWERPC_DTPREL16_LO
+ R_PPC64_DTPREL16_HI R_PPC64 = 76 // R_POWERPC_DTPREL16_HI
+ R_PPC64_DTPREL16_HA R_PPC64 = 77 // R_POWERPC_DTPREL16_HA
+ R_PPC64_DTPREL64 R_PPC64 = 78 // R_POWERPC_DTPREL64
+ R_PPC64_GOT_TLSGD16 R_PPC64 = 79 // R_POWERPC_GOT_TLSGD16
+ R_PPC64_GOT_TLSGD16_LO R_PPC64 = 80 // R_POWERPC_GOT_TLSGD16_LO
+ R_PPC64_GOT_TLSGD16_HI R_PPC64 = 81 // R_POWERPC_GOT_TLSGD16_HI
+ R_PPC64_GOT_TLSGD16_HA R_PPC64 = 82 // R_POWERPC_GOT_TLSGD16_HA
+ R_PPC64_GOT_TLSLD16 R_PPC64 = 83 // R_POWERPC_GOT_TLSLD16
+ R_PPC64_GOT_TLSLD16_LO R_PPC64 = 84 // R_POWERPC_GOT_TLSLD16_LO
+ R_PPC64_GOT_TLSLD16_HI R_PPC64 = 85 // R_POWERPC_GOT_TLSLD16_HI
+ R_PPC64_GOT_TLSLD16_HA R_PPC64 = 86 // R_POWERPC_GOT_TLSLD16_HA
+ R_PPC64_GOT_TPREL16_DS R_PPC64 = 87 // R_POWERPC_GOT_TPREL16_DS
+ R_PPC64_GOT_TPREL16_LO_DS R_PPC64 = 88 // R_POWERPC_GOT_TPREL16_LO_DS
+ R_PPC64_GOT_TPREL16_HI R_PPC64 = 89 // R_POWERPC_GOT_TPREL16_HI
+ R_PPC64_GOT_TPREL16_HA R_PPC64 = 90 // R_POWERPC_GOT_TPREL16_HA
+ R_PPC64_GOT_DTPREL16_DS R_PPC64 = 91 // R_POWERPC_GOT_DTPREL16_DS
+ R_PPC64_GOT_DTPREL16_LO_DS R_PPC64 = 92 // R_POWERPC_GOT_DTPREL16_LO_DS
+ R_PPC64_GOT_DTPREL16_HI R_PPC64 = 93 // R_POWERPC_GOT_DTPREL16_HI
+ R_PPC64_GOT_DTPREL16_HA R_PPC64 = 94 // R_POWERPC_GOT_DTPREL16_HA
+ R_PPC64_TPREL16_DS R_PPC64 = 95
+ R_PPC64_TPREL16_LO_DS R_PPC64 = 96
+ R_PPC64_TPREL16_HIGHER R_PPC64 = 97
+ R_PPC64_TPREL16_HIGHERA R_PPC64 = 98
+ R_PPC64_TPREL16_HIGHEST R_PPC64 = 99
+ R_PPC64_TPREL16_HIGHESTA R_PPC64 = 100
+ R_PPC64_DTPREL16_DS R_PPC64 = 101
+ R_PPC64_DTPREL16_LO_DS R_PPC64 = 102
+ R_PPC64_DTPREL16_HIGHER R_PPC64 = 103
+ R_PPC64_DTPREL16_HIGHERA R_PPC64 = 104
+ R_PPC64_DTPREL16_HIGHEST R_PPC64 = 105
+ R_PPC64_DTPREL16_HIGHESTA R_PPC64 = 106
+ R_PPC64_TLSGD R_PPC64 = 107
+ R_PPC64_TLSLD R_PPC64 = 108
+ R_PPC64_TOCSAVE R_PPC64 = 109
+ R_PPC64_ADDR16_HIGH R_PPC64 = 110
+ R_PPC64_ADDR16_HIGHA R_PPC64 = 111
+ R_PPC64_TPREL16_HIGH R_PPC64 = 112
+ R_PPC64_TPREL16_HIGHA R_PPC64 = 113
+ R_PPC64_DTPREL16_HIGH R_PPC64 = 114
+ R_PPC64_DTPREL16_HIGHA R_PPC64 = 115
+ R_PPC64_REL24_NOTOC R_PPC64 = 116
+ R_PPC64_ADDR64_LOCAL R_PPC64 = 117
+ R_PPC64_ENTRY R_PPC64 = 118
+ R_PPC64_PLTSEQ R_PPC64 = 119
+ R_PPC64_PLTCALL R_PPC64 = 120
+ R_PPC64_PLTSEQ_NOTOC R_PPC64 = 121
+ R_PPC64_PLTCALL_NOTOC R_PPC64 = 122
+ R_PPC64_PCREL_OPT R_PPC64 = 123
+ R_PPC64_REL24_P9NOTOC R_PPC64 = 124
+ R_PPC64_D34 R_PPC64 = 128
+ R_PPC64_D34_LO R_PPC64 = 129
+ R_PPC64_D34_HI30 R_PPC64 = 130
+ R_PPC64_D34_HA30 R_PPC64 = 131
+ R_PPC64_PCREL34 R_PPC64 = 132
+ R_PPC64_GOT_PCREL34 R_PPC64 = 133
+ R_PPC64_PLT_PCREL34 R_PPC64 = 134
+ R_PPC64_PLT_PCREL34_NOTOC R_PPC64 = 135
+ R_PPC64_ADDR16_HIGHER34 R_PPC64 = 136
+ R_PPC64_ADDR16_HIGHERA34 R_PPC64 = 137
+ R_PPC64_ADDR16_HIGHEST34 R_PPC64 = 138
+ R_PPC64_ADDR16_HIGHESTA34 R_PPC64 = 139
+ R_PPC64_REL16_HIGHER34 R_PPC64 = 140
+ R_PPC64_REL16_HIGHERA34 R_PPC64 = 141
+ R_PPC64_REL16_HIGHEST34 R_PPC64 = 142
+ R_PPC64_REL16_HIGHESTA34 R_PPC64 = 143
+ R_PPC64_D28 R_PPC64 = 144
+ R_PPC64_PCREL28 R_PPC64 = 145
+ R_PPC64_TPREL34 R_PPC64 = 146
+ R_PPC64_DTPREL34 R_PPC64 = 147
+ R_PPC64_GOT_TLSGD_PCREL34 R_PPC64 = 148
+ R_PPC64_GOT_TLSLD_PCREL34 R_PPC64 = 149
+ R_PPC64_GOT_TPREL_PCREL34 R_PPC64 = 150
+ R_PPC64_GOT_DTPREL_PCREL34 R_PPC64 = 151
+ R_PPC64_REL16_HIGH R_PPC64 = 240
+ R_PPC64_REL16_HIGHA R_PPC64 = 241
+ R_PPC64_REL16_HIGHER R_PPC64 = 242
+ R_PPC64_REL16_HIGHERA R_PPC64 = 243
+ R_PPC64_REL16_HIGHEST R_PPC64 = 244
+ R_PPC64_REL16_HIGHESTA R_PPC64 = 245
+ R_PPC64_REL16DX_HA R_PPC64 = 246 // R_POWERPC_REL16DX_HA
+ R_PPC64_JMP_IREL R_PPC64 = 247
+ R_PPC64_IRELATIVE R_PPC64 = 248 // R_POWERPC_IRELATIVE
+ R_PPC64_REL16 R_PPC64 = 249 // R_POWERPC_REL16
+ R_PPC64_REL16_LO R_PPC64 = 250 // R_POWERPC_REL16_LO
+ R_PPC64_REL16_HI R_PPC64 = 251 // R_POWERPC_REL16_HI
+ R_PPC64_REL16_HA R_PPC64 = 252 // R_POWERPC_REL16_HA
+ R_PPC64_GNU_VTINHERIT R_PPC64 = 253
+ R_PPC64_GNU_VTENTRY R_PPC64 = 254
+)
+
+var rppc64Strings = []intName{
+ {0, "R_PPC64_NONE"},
+ {1, "R_PPC64_ADDR32"},
+ {2, "R_PPC64_ADDR24"},
+ {3, "R_PPC64_ADDR16"},
+ {4, "R_PPC64_ADDR16_LO"},
+ {5, "R_PPC64_ADDR16_HI"},
+ {6, "R_PPC64_ADDR16_HA"},
+ {7, "R_PPC64_ADDR14"},
+ {8, "R_PPC64_ADDR14_BRTAKEN"},
+ {9, "R_PPC64_ADDR14_BRNTAKEN"},
+ {10, "R_PPC64_REL24"},
+ {11, "R_PPC64_REL14"},
+ {12, "R_PPC64_REL14_BRTAKEN"},
+ {13, "R_PPC64_REL14_BRNTAKEN"},
+ {14, "R_PPC64_GOT16"},
+ {15, "R_PPC64_GOT16_LO"},
+ {16, "R_PPC64_GOT16_HI"},
+ {17, "R_PPC64_GOT16_HA"},
+ {19, "R_PPC64_COPY"},
+ {20, "R_PPC64_GLOB_DAT"},
+ {21, "R_PPC64_JMP_SLOT"},
+ {22, "R_PPC64_RELATIVE"},
+ {24, "R_PPC64_UADDR32"},
+ {25, "R_PPC64_UADDR16"},
+ {26, "R_PPC64_REL32"},
+ {27, "R_PPC64_PLT32"},
+ {28, "R_PPC64_PLTREL32"},
+ {29, "R_PPC64_PLT16_LO"},
+ {30, "R_PPC64_PLT16_HI"},
+ {31, "R_PPC64_PLT16_HA"},
+ {33, "R_PPC64_SECTOFF"},
+ {34, "R_PPC64_SECTOFF_LO"},
+ {35, "R_PPC64_SECTOFF_HI"},
+ {36, "R_PPC64_SECTOFF_HA"},
+ {37, "R_PPC64_REL30"},
+ {38, "R_PPC64_ADDR64"},
+ {39, "R_PPC64_ADDR16_HIGHER"},
+ {40, "R_PPC64_ADDR16_HIGHERA"},
+ {41, "R_PPC64_ADDR16_HIGHEST"},
+ {42, "R_PPC64_ADDR16_HIGHESTA"},
+ {43, "R_PPC64_UADDR64"},
+ {44, "R_PPC64_REL64"},
+ {45, "R_PPC64_PLT64"},
+ {46, "R_PPC64_PLTREL64"},
+ {47, "R_PPC64_TOC16"},
+ {48, "R_PPC64_TOC16_LO"},
+ {49, "R_PPC64_TOC16_HI"},
+ {50, "R_PPC64_TOC16_HA"},
+ {51, "R_PPC64_TOC"},
+ {52, "R_PPC64_PLTGOT16"},
+ {53, "R_PPC64_PLTGOT16_LO"},
+ {54, "R_PPC64_PLTGOT16_HI"},
+ {55, "R_PPC64_PLTGOT16_HA"},
+ {56, "R_PPC64_ADDR16_DS"},
+ {57, "R_PPC64_ADDR16_LO_DS"},
+ {58, "R_PPC64_GOT16_DS"},
+ {59, "R_PPC64_GOT16_LO_DS"},
+ {60, "R_PPC64_PLT16_LO_DS"},
+ {61, "R_PPC64_SECTOFF_DS"},
+ {62, "R_PPC64_SECTOFF_LO_DS"},
+ {63, "R_PPC64_TOC16_DS"},
+ {64, "R_PPC64_TOC16_LO_DS"},
+ {65, "R_PPC64_PLTGOT16_DS"},
+ {66, "R_PPC64_PLTGOT_LO_DS"},
+ {67, "R_PPC64_TLS"},
+ {68, "R_PPC64_DTPMOD64"},
+ {69, "R_PPC64_TPREL16"},
+ {70, "R_PPC64_TPREL16_LO"},
+ {71, "R_PPC64_TPREL16_HI"},
+ {72, "R_PPC64_TPREL16_HA"},
+ {73, "R_PPC64_TPREL64"},
+ {74, "R_PPC64_DTPREL16"},
+ {75, "R_PPC64_DTPREL16_LO"},
+ {76, "R_PPC64_DTPREL16_HI"},
+ {77, "R_PPC64_DTPREL16_HA"},
+ {78, "R_PPC64_DTPREL64"},
+ {79, "R_PPC64_GOT_TLSGD16"},
+ {80, "R_PPC64_GOT_TLSGD16_LO"},
+ {81, "R_PPC64_GOT_TLSGD16_HI"},
+ {82, "R_PPC64_GOT_TLSGD16_HA"},
+ {83, "R_PPC64_GOT_TLSLD16"},
+ {84, "R_PPC64_GOT_TLSLD16_LO"},
+ {85, "R_PPC64_GOT_TLSLD16_HI"},
+ {86, "R_PPC64_GOT_TLSLD16_HA"},
+ {87, "R_PPC64_GOT_TPREL16_DS"},
+ {88, "R_PPC64_GOT_TPREL16_LO_DS"},
+ {89, "R_PPC64_GOT_TPREL16_HI"},
+ {90, "R_PPC64_GOT_TPREL16_HA"},
+ {91, "R_PPC64_GOT_DTPREL16_DS"},
+ {92, "R_PPC64_GOT_DTPREL16_LO_DS"},
+ {93, "R_PPC64_GOT_DTPREL16_HI"},
+ {94, "R_PPC64_GOT_DTPREL16_HA"},
+ {95, "R_PPC64_TPREL16_DS"},
+ {96, "R_PPC64_TPREL16_LO_DS"},
+ {97, "R_PPC64_TPREL16_HIGHER"},
+ {98, "R_PPC64_TPREL16_HIGHERA"},
+ {99, "R_PPC64_TPREL16_HIGHEST"},
+ {100, "R_PPC64_TPREL16_HIGHESTA"},
+ {101, "R_PPC64_DTPREL16_DS"},
+ {102, "R_PPC64_DTPREL16_LO_DS"},
+ {103, "R_PPC64_DTPREL16_HIGHER"},
+ {104, "R_PPC64_DTPREL16_HIGHERA"},
+ {105, "R_PPC64_DTPREL16_HIGHEST"},
+ {106, "R_PPC64_DTPREL16_HIGHESTA"},
+ {107, "R_PPC64_TLSGD"},
+ {108, "R_PPC64_TLSLD"},
+ {109, "R_PPC64_TOCSAVE"},
+ {110, "R_PPC64_ADDR16_HIGH"},
+ {111, "R_PPC64_ADDR16_HIGHA"},
+ {112, "R_PPC64_TPREL16_HIGH"},
+ {113, "R_PPC64_TPREL16_HIGHA"},
+ {114, "R_PPC64_DTPREL16_HIGH"},
+ {115, "R_PPC64_DTPREL16_HIGHA"},
+ {116, "R_PPC64_REL24_NOTOC"},
+ {117, "R_PPC64_ADDR64_LOCAL"},
+ {118, "R_PPC64_ENTRY"},
+ {119, "R_PPC64_PLTSEQ"},
+ {120, "R_PPC64_PLTCALL"},
+ {121, "R_PPC64_PLTSEQ_NOTOC"},
+ {122, "R_PPC64_PLTCALL_NOTOC"},
+ {123, "R_PPC64_PCREL_OPT"},
+ {124, "R_PPC64_REL24_P9NOTOC"},
+ {128, "R_PPC64_D34"},
+ {129, "R_PPC64_D34_LO"},
+ {130, "R_PPC64_D34_HI30"},
+ {131, "R_PPC64_D34_HA30"},
+ {132, "R_PPC64_PCREL34"},
+ {133, "R_PPC64_GOT_PCREL34"},
+ {134, "R_PPC64_PLT_PCREL34"},
+ {135, "R_PPC64_PLT_PCREL34_NOTOC"},
+ {136, "R_PPC64_ADDR16_HIGHER34"},
+ {137, "R_PPC64_ADDR16_HIGHERA34"},
+ {138, "R_PPC64_ADDR16_HIGHEST34"},
+ {139, "R_PPC64_ADDR16_HIGHESTA34"},
+ {140, "R_PPC64_REL16_HIGHER34"},
+ {141, "R_PPC64_REL16_HIGHERA34"},
+ {142, "R_PPC64_REL16_HIGHEST34"},
+ {143, "R_PPC64_REL16_HIGHESTA34"},
+ {144, "R_PPC64_D28"},
+ {145, "R_PPC64_PCREL28"},
+ {146, "R_PPC64_TPREL34"},
+ {147, "R_PPC64_DTPREL34"},
+ {148, "R_PPC64_GOT_TLSGD_PCREL34"},
+ {149, "R_PPC64_GOT_TLSLD_PCREL34"},
+ {150, "R_PPC64_GOT_TPREL_PCREL34"},
+ {151, "R_PPC64_GOT_DTPREL_PCREL34"},
+ {240, "R_PPC64_REL16_HIGH"},
+ {241, "R_PPC64_REL16_HIGHA"},
+ {242, "R_PPC64_REL16_HIGHER"},
+ {243, "R_PPC64_REL16_HIGHERA"},
+ {244, "R_PPC64_REL16_HIGHEST"},
+ {245, "R_PPC64_REL16_HIGHESTA"},
+ {246, "R_PPC64_REL16DX_HA"},
+ {247, "R_PPC64_JMP_IREL"},
+ {248, "R_PPC64_IRELATIVE"},
+ {249, "R_PPC64_REL16"},
+ {250, "R_PPC64_REL16_LO"},
+ {251, "R_PPC64_REL16_HI"},
+ {252, "R_PPC64_REL16_HA"},
+ {253, "R_PPC64_GNU_VTINHERIT"},
+ {254, "R_PPC64_GNU_VTENTRY"},
+}
+
+func (i R_PPC64) String() string { return stringName(uint32(i), rppc64Strings, false) }
+func (i R_PPC64) GoString() string { return stringName(uint32(i), rppc64Strings, true) }
+
+// Relocation types for RISC-V processors.
+type R_RISCV int
+
+const (
+ R_RISCV_NONE R_RISCV = 0 /* No relocation. */
+ R_RISCV_32 R_RISCV = 1 /* Add 32 bit zero extended symbol value */
+ R_RISCV_64 R_RISCV = 2 /* Add 64 bit symbol value. */
+ R_RISCV_RELATIVE R_RISCV = 3 /* Add load address of shared object. */
+ R_RISCV_COPY R_RISCV = 4 /* Copy data from shared object. */
+ R_RISCV_JUMP_SLOT R_RISCV = 5 /* Set GOT entry to code address. */
+ R_RISCV_TLS_DTPMOD32 R_RISCV = 6 /* 32 bit ID of module containing symbol */
+ R_RISCV_TLS_DTPMOD64 R_RISCV = 7 /* ID of module containing symbol */
+ R_RISCV_TLS_DTPREL32 R_RISCV = 8 /* 32 bit relative offset in TLS block */
+ R_RISCV_TLS_DTPREL64 R_RISCV = 9 /* Relative offset in TLS block */
+ R_RISCV_TLS_TPREL32 R_RISCV = 10 /* 32 bit relative offset in static TLS block */
+ R_RISCV_TLS_TPREL64 R_RISCV = 11 /* Relative offset in static TLS block */
+ R_RISCV_BRANCH R_RISCV = 16 /* PC-relative branch */
+ R_RISCV_JAL R_RISCV = 17 /* PC-relative jump */
+ R_RISCV_CALL R_RISCV = 18 /* PC-relative call */
+ R_RISCV_CALL_PLT R_RISCV = 19 /* PC-relative call (PLT) */
+ R_RISCV_GOT_HI20 R_RISCV = 20 /* PC-relative GOT reference */
+ R_RISCV_TLS_GOT_HI20 R_RISCV = 21 /* PC-relative TLS IE GOT offset */
+ R_RISCV_TLS_GD_HI20 R_RISCV = 22 /* PC-relative TLS GD reference */
+ R_RISCV_PCREL_HI20 R_RISCV = 23 /* PC-relative reference */
+ R_RISCV_PCREL_LO12_I R_RISCV = 24 /* PC-relative reference */
+ R_RISCV_PCREL_LO12_S R_RISCV = 25 /* PC-relative reference */
+ R_RISCV_HI20 R_RISCV = 26 /* Absolute address */
+ R_RISCV_LO12_I R_RISCV = 27 /* Absolute address */
+ R_RISCV_LO12_S R_RISCV = 28 /* Absolute address */
+ R_RISCV_TPREL_HI20 R_RISCV = 29 /* TLS LE thread offset */
+ R_RISCV_TPREL_LO12_I R_RISCV = 30 /* TLS LE thread offset */
+ R_RISCV_TPREL_LO12_S R_RISCV = 31 /* TLS LE thread offset */
+ R_RISCV_TPREL_ADD R_RISCV = 32 /* TLS LE thread usage */
+ R_RISCV_ADD8 R_RISCV = 33 /* 8-bit label addition */
+ R_RISCV_ADD16 R_RISCV = 34 /* 16-bit label addition */
+ R_RISCV_ADD32 R_RISCV = 35 /* 32-bit label addition */
+ R_RISCV_ADD64 R_RISCV = 36 /* 64-bit label addition */
+ R_RISCV_SUB8 R_RISCV = 37 /* 8-bit label subtraction */
+ R_RISCV_SUB16 R_RISCV = 38 /* 16-bit label subtraction */
+ R_RISCV_SUB32 R_RISCV = 39 /* 32-bit label subtraction */
+ R_RISCV_SUB64 R_RISCV = 40 /* 64-bit label subtraction */
+ R_RISCV_GNU_VTINHERIT R_RISCV = 41 /* GNU C++ vtable hierarchy */
+ R_RISCV_GNU_VTENTRY R_RISCV = 42 /* GNU C++ vtable member usage */
+ R_RISCV_ALIGN R_RISCV = 43 /* Alignment statement */
+ R_RISCV_RVC_BRANCH R_RISCV = 44 /* PC-relative branch offset */
+ R_RISCV_RVC_JUMP R_RISCV = 45 /* PC-relative jump offset */
+ R_RISCV_RVC_LUI R_RISCV = 46 /* Absolute address */
+ R_RISCV_GPREL_I R_RISCV = 47 /* GP-relative reference */
+ R_RISCV_GPREL_S R_RISCV = 48 /* GP-relative reference */
+ R_RISCV_TPREL_I R_RISCV = 49 /* TP-relative TLS LE load */
+ R_RISCV_TPREL_S R_RISCV = 50 /* TP-relative TLS LE store */
+ R_RISCV_RELAX R_RISCV = 51 /* Instruction pair can be relaxed */
+ R_RISCV_SUB6 R_RISCV = 52 /* Local label subtraction */
+ R_RISCV_SET6 R_RISCV = 53 /* Local label subtraction */
+ R_RISCV_SET8 R_RISCV = 54 /* Local label subtraction */
+ R_RISCV_SET16 R_RISCV = 55 /* Local label subtraction */
+ R_RISCV_SET32 R_RISCV = 56 /* Local label subtraction */
+ R_RISCV_32_PCREL R_RISCV = 57 /* 32-bit PC relative */
+)
+
+var rriscvStrings = []intName{
+ {0, "R_RISCV_NONE"},
+ {1, "R_RISCV_32"},
+ {2, "R_RISCV_64"},
+ {3, "R_RISCV_RELATIVE"},
+ {4, "R_RISCV_COPY"},
+ {5, "R_RISCV_JUMP_SLOT"},
+ {6, "R_RISCV_TLS_DTPMOD32"},
+ {7, "R_RISCV_TLS_DTPMOD64"},
+ {8, "R_RISCV_TLS_DTPREL32"},
+ {9, "R_RISCV_TLS_DTPREL64"},
+ {10, "R_RISCV_TLS_TPREL32"},
+ {11, "R_RISCV_TLS_TPREL64"},
+ {16, "R_RISCV_BRANCH"},
+ {17, "R_RISCV_JAL"},
+ {18, "R_RISCV_CALL"},
+ {19, "R_RISCV_CALL_PLT"},
+ {20, "R_RISCV_GOT_HI20"},
+ {21, "R_RISCV_TLS_GOT_HI20"},
+ {22, "R_RISCV_TLS_GD_HI20"},
+ {23, "R_RISCV_PCREL_HI20"},
+ {24, "R_RISCV_PCREL_LO12_I"},
+ {25, "R_RISCV_PCREL_LO12_S"},
+ {26, "R_RISCV_HI20"},
+ {27, "R_RISCV_LO12_I"},
+ {28, "R_RISCV_LO12_S"},
+ {29, "R_RISCV_TPREL_HI20"},
+ {30, "R_RISCV_TPREL_LO12_I"},
+ {31, "R_RISCV_TPREL_LO12_S"},
+ {32, "R_RISCV_TPREL_ADD"},
+ {33, "R_RISCV_ADD8"},
+ {34, "R_RISCV_ADD16"},
+ {35, "R_RISCV_ADD32"},
+ {36, "R_RISCV_ADD64"},
+ {37, "R_RISCV_SUB8"},
+ {38, "R_RISCV_SUB16"},
+ {39, "R_RISCV_SUB32"},
+ {40, "R_RISCV_SUB64"},
+ {41, "R_RISCV_GNU_VTINHERIT"},
+ {42, "R_RISCV_GNU_VTENTRY"},
+ {43, "R_RISCV_ALIGN"},
+ {44, "R_RISCV_RVC_BRANCH"},
+ {45, "R_RISCV_RVC_JUMP"},
+ {46, "R_RISCV_RVC_LUI"},
+ {47, "R_RISCV_GPREL_I"},
+ {48, "R_RISCV_GPREL_S"},
+ {49, "R_RISCV_TPREL_I"},
+ {50, "R_RISCV_TPREL_S"},
+ {51, "R_RISCV_RELAX"},
+ {52, "R_RISCV_SUB6"},
+ {53, "R_RISCV_SET6"},
+ {54, "R_RISCV_SET8"},
+ {55, "R_RISCV_SET16"},
+ {56, "R_RISCV_SET32"},
+ {57, "R_RISCV_32_PCREL"},
+}
+
+func (i R_RISCV) String() string { return stringName(uint32(i), rriscvStrings, false) }
+func (i R_RISCV) GoString() string { return stringName(uint32(i), rriscvStrings, true) }
+
+// Relocation types for s390x processors.
+type R_390 int
+
+const (
+ R_390_NONE R_390 = 0
+ R_390_8 R_390 = 1
+ R_390_12 R_390 = 2
+ R_390_16 R_390 = 3
+ R_390_32 R_390 = 4
+ R_390_PC32 R_390 = 5
+ R_390_GOT12 R_390 = 6
+ R_390_GOT32 R_390 = 7
+ R_390_PLT32 R_390 = 8
+ R_390_COPY R_390 = 9
+ R_390_GLOB_DAT R_390 = 10
+ R_390_JMP_SLOT R_390 = 11
+ R_390_RELATIVE R_390 = 12
+ R_390_GOTOFF R_390 = 13
+ R_390_GOTPC R_390 = 14
+ R_390_GOT16 R_390 = 15
+ R_390_PC16 R_390 = 16
+ R_390_PC16DBL R_390 = 17
+ R_390_PLT16DBL R_390 = 18
+ R_390_PC32DBL R_390 = 19
+ R_390_PLT32DBL R_390 = 20
+ R_390_GOTPCDBL R_390 = 21
+ R_390_64 R_390 = 22
+ R_390_PC64 R_390 = 23
+ R_390_GOT64 R_390 = 24
+ R_390_PLT64 R_390 = 25
+ R_390_GOTENT R_390 = 26
+ R_390_GOTOFF16 R_390 = 27
+ R_390_GOTOFF64 R_390 = 28
+ R_390_GOTPLT12 R_390 = 29
+ R_390_GOTPLT16 R_390 = 30
+ R_390_GOTPLT32 R_390 = 31
+ R_390_GOTPLT64 R_390 = 32
+ R_390_GOTPLTENT R_390 = 33
+ R_390_GOTPLTOFF16 R_390 = 34
+ R_390_GOTPLTOFF32 R_390 = 35
+ R_390_GOTPLTOFF64 R_390 = 36
+ R_390_TLS_LOAD R_390 = 37
+ R_390_TLS_GDCALL R_390 = 38
+ R_390_TLS_LDCALL R_390 = 39
+ R_390_TLS_GD32 R_390 = 40
+ R_390_TLS_GD64 R_390 = 41
+ R_390_TLS_GOTIE12 R_390 = 42
+ R_390_TLS_GOTIE32 R_390 = 43
+ R_390_TLS_GOTIE64 R_390 = 44
+ R_390_TLS_LDM32 R_390 = 45
+ R_390_TLS_LDM64 R_390 = 46
+ R_390_TLS_IE32 R_390 = 47
+ R_390_TLS_IE64 R_390 = 48
+ R_390_TLS_IEENT R_390 = 49
+ R_390_TLS_LE32 R_390 = 50
+ R_390_TLS_LE64 R_390 = 51
+ R_390_TLS_LDO32 R_390 = 52
+ R_390_TLS_LDO64 R_390 = 53
+ R_390_TLS_DTPMOD R_390 = 54
+ R_390_TLS_DTPOFF R_390 = 55
+ R_390_TLS_TPOFF R_390 = 56
+ R_390_20 R_390 = 57
+ R_390_GOT20 R_390 = 58
+ R_390_GOTPLT20 R_390 = 59
+ R_390_TLS_GOTIE20 R_390 = 60
+)
+
+var r390Strings = []intName{
+ {0, "R_390_NONE"},
+ {1, "R_390_8"},
+ {2, "R_390_12"},
+ {3, "R_390_16"},
+ {4, "R_390_32"},
+ {5, "R_390_PC32"},
+ {6, "R_390_GOT12"},
+ {7, "R_390_GOT32"},
+ {8, "R_390_PLT32"},
+ {9, "R_390_COPY"},
+ {10, "R_390_GLOB_DAT"},
+ {11, "R_390_JMP_SLOT"},
+ {12, "R_390_RELATIVE"},
+ {13, "R_390_GOTOFF"},
+ {14, "R_390_GOTPC"},
+ {15, "R_390_GOT16"},
+ {16, "R_390_PC16"},
+ {17, "R_390_PC16DBL"},
+ {18, "R_390_PLT16DBL"},
+ {19, "R_390_PC32DBL"},
+ {20, "R_390_PLT32DBL"},
+ {21, "R_390_GOTPCDBL"},
+ {22, "R_390_64"},
+ {23, "R_390_PC64"},
+ {24, "R_390_GOT64"},
+ {25, "R_390_PLT64"},
+ {26, "R_390_GOTENT"},
+ {27, "R_390_GOTOFF16"},
+ {28, "R_390_GOTOFF64"},
+ {29, "R_390_GOTPLT12"},
+ {30, "R_390_GOTPLT16"},
+ {31, "R_390_GOTPLT32"},
+ {32, "R_390_GOTPLT64"},
+ {33, "R_390_GOTPLTENT"},
+ {34, "R_390_GOTPLTOFF16"},
+ {35, "R_390_GOTPLTOFF32"},
+ {36, "R_390_GOTPLTOFF64"},
+ {37, "R_390_TLS_LOAD"},
+ {38, "R_390_TLS_GDCALL"},
+ {39, "R_390_TLS_LDCALL"},
+ {40, "R_390_TLS_GD32"},
+ {41, "R_390_TLS_GD64"},
+ {42, "R_390_TLS_GOTIE12"},
+ {43, "R_390_TLS_GOTIE32"},
+ {44, "R_390_TLS_GOTIE64"},
+ {45, "R_390_TLS_LDM32"},
+ {46, "R_390_TLS_LDM64"},
+ {47, "R_390_TLS_IE32"},
+ {48, "R_390_TLS_IE64"},
+ {49, "R_390_TLS_IEENT"},
+ {50, "R_390_TLS_LE32"},
+ {51, "R_390_TLS_LE64"},
+ {52, "R_390_TLS_LDO32"},
+ {53, "R_390_TLS_LDO64"},
+ {54, "R_390_TLS_DTPMOD"},
+ {55, "R_390_TLS_DTPOFF"},
+ {56, "R_390_TLS_TPOFF"},
+ {57, "R_390_20"},
+ {58, "R_390_GOT20"},
+ {59, "R_390_GOTPLT20"},
+ {60, "R_390_TLS_GOTIE20"},
+}
+
+func (i R_390) String() string { return stringName(uint32(i), r390Strings, false) }
+func (i R_390) GoString() string { return stringName(uint32(i), r390Strings, true) }
+
+// Relocation types for SPARC.
+type R_SPARC int
+
+const (
+ R_SPARC_NONE R_SPARC = 0
+ R_SPARC_8 R_SPARC = 1
+ R_SPARC_16 R_SPARC = 2
+ R_SPARC_32 R_SPARC = 3
+ R_SPARC_DISP8 R_SPARC = 4
+ R_SPARC_DISP16 R_SPARC = 5
+ R_SPARC_DISP32 R_SPARC = 6
+ R_SPARC_WDISP30 R_SPARC = 7
+ R_SPARC_WDISP22 R_SPARC = 8
+ R_SPARC_HI22 R_SPARC = 9
+ R_SPARC_22 R_SPARC = 10
+ R_SPARC_13 R_SPARC = 11
+ R_SPARC_LO10 R_SPARC = 12
+ R_SPARC_GOT10 R_SPARC = 13
+ R_SPARC_GOT13 R_SPARC = 14
+ R_SPARC_GOT22 R_SPARC = 15
+ R_SPARC_PC10 R_SPARC = 16
+ R_SPARC_PC22 R_SPARC = 17
+ R_SPARC_WPLT30 R_SPARC = 18
+ R_SPARC_COPY R_SPARC = 19
+ R_SPARC_GLOB_DAT R_SPARC = 20
+ R_SPARC_JMP_SLOT R_SPARC = 21
+ R_SPARC_RELATIVE R_SPARC = 22
+ R_SPARC_UA32 R_SPARC = 23
+ R_SPARC_PLT32 R_SPARC = 24
+ R_SPARC_HIPLT22 R_SPARC = 25
+ R_SPARC_LOPLT10 R_SPARC = 26
+ R_SPARC_PCPLT32 R_SPARC = 27
+ R_SPARC_PCPLT22 R_SPARC = 28
+ R_SPARC_PCPLT10 R_SPARC = 29
+ R_SPARC_10 R_SPARC = 30
+ R_SPARC_11 R_SPARC = 31
+ R_SPARC_64 R_SPARC = 32
+ R_SPARC_OLO10 R_SPARC = 33
+ R_SPARC_HH22 R_SPARC = 34
+ R_SPARC_HM10 R_SPARC = 35
+ R_SPARC_LM22 R_SPARC = 36
+ R_SPARC_PC_HH22 R_SPARC = 37
+ R_SPARC_PC_HM10 R_SPARC = 38
+ R_SPARC_PC_LM22 R_SPARC = 39
+ R_SPARC_WDISP16 R_SPARC = 40
+ R_SPARC_WDISP19 R_SPARC = 41
+ R_SPARC_GLOB_JMP R_SPARC = 42
+ R_SPARC_7 R_SPARC = 43
+ R_SPARC_5 R_SPARC = 44
+ R_SPARC_6 R_SPARC = 45
+ R_SPARC_DISP64 R_SPARC = 46
+ R_SPARC_PLT64 R_SPARC = 47
+ R_SPARC_HIX22 R_SPARC = 48
+ R_SPARC_LOX10 R_SPARC = 49
+ R_SPARC_H44 R_SPARC = 50
+ R_SPARC_M44 R_SPARC = 51
+ R_SPARC_L44 R_SPARC = 52
+ R_SPARC_REGISTER R_SPARC = 53
+ R_SPARC_UA64 R_SPARC = 54
+ R_SPARC_UA16 R_SPARC = 55
+)
+
+var rsparcStrings = []intName{
+ {0, "R_SPARC_NONE"},
+ {1, "R_SPARC_8"},
+ {2, "R_SPARC_16"},
+ {3, "R_SPARC_32"},
+ {4, "R_SPARC_DISP8"},
+ {5, "R_SPARC_DISP16"},
+ {6, "R_SPARC_DISP32"},
+ {7, "R_SPARC_WDISP30"},
+ {8, "R_SPARC_WDISP22"},
+ {9, "R_SPARC_HI22"},
+ {10, "R_SPARC_22"},
+ {11, "R_SPARC_13"},
+ {12, "R_SPARC_LO10"},
+ {13, "R_SPARC_GOT10"},
+ {14, "R_SPARC_GOT13"},
+ {15, "R_SPARC_GOT22"},
+ {16, "R_SPARC_PC10"},
+ {17, "R_SPARC_PC22"},
+ {18, "R_SPARC_WPLT30"},
+ {19, "R_SPARC_COPY"},
+ {20, "R_SPARC_GLOB_DAT"},
+ {21, "R_SPARC_JMP_SLOT"},
+ {22, "R_SPARC_RELATIVE"},
+ {23, "R_SPARC_UA32"},
+ {24, "R_SPARC_PLT32"},
+ {25, "R_SPARC_HIPLT22"},
+ {26, "R_SPARC_LOPLT10"},
+ {27, "R_SPARC_PCPLT32"},
+ {28, "R_SPARC_PCPLT22"},
+ {29, "R_SPARC_PCPLT10"},
+ {30, "R_SPARC_10"},
+ {31, "R_SPARC_11"},
+ {32, "R_SPARC_64"},
+ {33, "R_SPARC_OLO10"},
+ {34, "R_SPARC_HH22"},
+ {35, "R_SPARC_HM10"},
+ {36, "R_SPARC_LM22"},
+ {37, "R_SPARC_PC_HH22"},
+ {38, "R_SPARC_PC_HM10"},
+ {39, "R_SPARC_PC_LM22"},
+ {40, "R_SPARC_WDISP16"},
+ {41, "R_SPARC_WDISP19"},
+ {42, "R_SPARC_GLOB_JMP"},
+ {43, "R_SPARC_7"},
+ {44, "R_SPARC_5"},
+ {45, "R_SPARC_6"},
+ {46, "R_SPARC_DISP64"},
+ {47, "R_SPARC_PLT64"},
+ {48, "R_SPARC_HIX22"},
+ {49, "R_SPARC_LOX10"},
+ {50, "R_SPARC_H44"},
+ {51, "R_SPARC_M44"},
+ {52, "R_SPARC_L44"},
+ {53, "R_SPARC_REGISTER"},
+ {54, "R_SPARC_UA64"},
+ {55, "R_SPARC_UA16"},
+}
+
+func (i R_SPARC) String() string { return stringName(uint32(i), rsparcStrings, false) }
+func (i R_SPARC) GoString() string { return stringName(uint32(i), rsparcStrings, true) }
+
+// Magic number for the elf trampoline, chosen wisely to be an immediate value.
+const ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
+
+// ELF32 File header.
+type Header32 struct {
+ Ident [EI_NIDENT]byte /* File identification. */
+ Type uint16 /* File type. */
+ Machine uint16 /* Machine architecture. */
+ Version uint32 /* ELF format version. */
+ Entry uint32 /* Entry point. */
+ Phoff uint32 /* Program header file offset. */
+ Shoff uint32 /* Section header file offset. */
+ Flags uint32 /* Architecture-specific flags. */
+ Ehsize uint16 /* Size of ELF header in bytes. */
+ Phentsize uint16 /* Size of program header entry. */
+ Phnum uint16 /* Number of program header entries. */
+ Shentsize uint16 /* Size of section header entry. */
+ Shnum uint16 /* Number of section header entries. */
+ Shstrndx uint16 /* Section name strings section. */
+}
+
+// ELF32 Section header.
+type Section32 struct {
+ Name uint32 /* Section name (index into the section header string table). */
+ Type uint32 /* Section type. */
+ Flags uint32 /* Section flags. */
+ Addr uint32 /* Address in memory image. */
+ Off uint32 /* Offset in file. */
+ Size uint32 /* Size in bytes. */
+ Link uint32 /* Index of a related section. */
+ Info uint32 /* Depends on section type. */
+ Addralign uint32 /* Alignment in bytes. */
+ Entsize uint32 /* Size of each entry in section. */
+}
+
+// ELF32 Program header.
+type Prog32 struct {
+ Type uint32 /* Entry type. */
+ Off uint32 /* File offset of contents. */
+ Vaddr uint32 /* Virtual address in memory image. */
+ Paddr uint32 /* Physical address (not used). */
+ Filesz uint32 /* Size of contents in file. */
+ Memsz uint32 /* Size of contents in memory. */
+ Flags uint32 /* Access permission flags. */
+ Align uint32 /* Alignment in memory and file. */
+}
+
+// ELF32 Dynamic structure. The ".dynamic" section contains an array of them.
+type Dyn32 struct {
+ Tag int32 /* Entry type. */
+ Val uint32 /* Integer/Address value. */
+}
+
+// ELF32 Compression header.
+type Chdr32 struct {
+ Type uint32
+ Size uint32
+ Addralign uint32
+}
+
+/*
+ * Relocation entries.
+ */
+
+// ELF32 Relocations that don't need an addend field.
+type Rel32 struct {
+ Off uint32 /* Location to be relocated. */
+ Info uint32 /* Relocation type and symbol index. */
+}
+
+// ELF32 Relocations that need an addend field.
+type Rela32 struct {
+ Off uint32 /* Location to be relocated. */
+ Info uint32 /* Relocation type and symbol index. */
+ Addend int32 /* Addend. */
+}
+
+func R_SYM32(info uint32) uint32 { return info >> 8 }
+func R_TYPE32(info uint32) uint32 { return info & 0xff }
+func R_INFO32(sym, typ uint32) uint32 { return sym<<8 | typ }
+
+// ELF32 Symbol.
+type Sym32 struct {
+ Name uint32
+ Value uint32
+ Size uint32
+ Info uint8
+ Other uint8
+ Shndx uint16
+}
+
+const Sym32Size = 16
+
+func ST_BIND(info uint8) SymBind { return SymBind(info >> 4) }
+func ST_TYPE(info uint8) SymType { return SymType(info & 0xF) }
+func ST_INFO(bind SymBind, typ SymType) uint8 {
+ return uint8(bind)<<4 | uint8(typ)&0xf
+}
+func ST_VISIBILITY(other uint8) SymVis { return SymVis(other & 3) }
+
+/*
+ * ELF64
+ */
+
+// ELF64 file header.
+type Header64 struct {
+ Ident [EI_NIDENT]byte /* File identification. */
+ Type uint16 /* File type. */
+ Machine uint16 /* Machine architecture. */
+ Version uint32 /* ELF format version. */
+ Entry uint64 /* Entry point. */
+ Phoff uint64 /* Program header file offset. */
+ Shoff uint64 /* Section header file offset. */
+ Flags uint32 /* Architecture-specific flags. */
+ Ehsize uint16 /* Size of ELF header in bytes. */
+ Phentsize uint16 /* Size of program header entry. */
+ Phnum uint16 /* Number of program header entries. */
+ Shentsize uint16 /* Size of section header entry. */
+ Shnum uint16 /* Number of section header entries. */
+ Shstrndx uint16 /* Section name strings section. */
+}
+
+// ELF64 Section header.
+type Section64 struct {
+ Name uint32 /* Section name (index into the section header string table). */
+ Type uint32 /* Section type. */
+ Flags uint64 /* Section flags. */
+ Addr uint64 /* Address in memory image. */
+ Off uint64 /* Offset in file. */
+ Size uint64 /* Size in bytes. */
+ Link uint32 /* Index of a related section. */
+ Info uint32 /* Depends on section type. */
+ Addralign uint64 /* Alignment in bytes. */
+ Entsize uint64 /* Size of each entry in section. */
+}
+
+// ELF64 Program header.
+type Prog64 struct {
+ Type uint32 /* Entry type. */
+ Flags uint32 /* Access permission flags. */
+ Off uint64 /* File offset of contents. */
+ Vaddr uint64 /* Virtual address in memory image. */
+ Paddr uint64 /* Physical address (not used). */
+ Filesz uint64 /* Size of contents in file. */
+ Memsz uint64 /* Size of contents in memory. */
+ Align uint64 /* Alignment in memory and file. */
+}
+
+// ELF64 Dynamic structure. The ".dynamic" section contains an array of them.
+type Dyn64 struct {
+ Tag int64 /* Entry type. */
+ Val uint64 /* Integer/address value */
+}
+
+// ELF64 Compression header.
+type Chdr64 struct {
+ Type uint32
+ _ uint32 /* Reserved. */
+ Size uint64
+ Addralign uint64
+}
+
+/*
+ * Relocation entries.
+ */
+
+/* ELF64 relocations that don't need an addend field. */
+type Rel64 struct {
+ Off uint64 /* Location to be relocated. */
+ Info uint64 /* Relocation type and symbol index. */
+}
+
+/* ELF64 relocations that need an addend field. */
+type Rela64 struct {
+ Off uint64 /* Location to be relocated. */
+ Info uint64 /* Relocation type and symbol index. */
+ Addend int64 /* Addend. */
+}
+
+func R_SYM64(info uint64) uint32 { return uint32(info >> 32) }
+func R_TYPE64(info uint64) uint32 { return uint32(info) }
+func R_INFO(sym, typ uint32) uint64 { return uint64(sym)<<32 | uint64(typ) }
+
+// ELF64 symbol table entries.
+type Sym64 struct {
+ Name uint32 /* String table index of name. */
+ Info uint8 /* Type and binding information. */
+ Other uint8 /* Reserved (not used). */
+ Shndx uint16 /* Section index of symbol. */
+ Value uint64 /* Symbol value. */
+ Size uint64 /* Size of associated object. */
+}
+
+const Sym64Size = 24
+
+type intName struct {
+ i uint32
+ s string
+}
+
+func stringName(i uint32, names []intName, goSyntax bool) string {
+ for _, n := range names {
+ if n.i == i {
+ if goSyntax {
+ return "elf." + n.s
+ }
+ return n.s
+ }
+ }
+
+ // second pass - look for smaller to add with.
+ // assume sorted already
+ for j := len(names) - 1; j >= 0; j-- {
+ n := names[j]
+ if n.i < i {
+ s := n.s
+ if goSyntax {
+ s = "elf." + s
+ }
+ return s + "+" + strconv.FormatUint(uint64(i-n.i), 10)
+ }
+ }
+
+ return strconv.FormatUint(uint64(i), 10)
+}
+
+func flagName(i uint32, names []intName, goSyntax bool) string {
+ s := ""
+ for _, n := range names {
+ if n.i&i == n.i {
+ if len(s) > 0 {
+ s += "+"
+ }
+ if goSyntax {
+ s += "elf."
+ }
+ s += n.s
+ i -= n.i
+ }
+ }
+ if len(s) == 0 {
+ return "0x" + strconv.FormatUint(uint64(i), 16)
+ }
+ if i != 0 {
+ s += "+0x" + strconv.FormatUint(uint64(i), 16)
+ }
+ return s
+}
diff --git a/contrib/go/_std_1.21/src/debug/elf/file.go b/contrib/go/_std_1.21/src/debug/elf/file.go
new file mode 100644
index 0000000000..7485337905
--- /dev/null
+++ b/contrib/go/_std_1.21/src/debug/elf/file.go
@@ -0,0 +1,1676 @@
+// Copyright 2009 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 elf implements access to ELF object files.
+
+# Security
+
+This package is not designed to be hardened against adversarial inputs, and is
+outside the scope of https://go.dev/security/policy. In particular, only basic
+validation is done when parsing object files. As such, care should be taken when
+parsing untrusted inputs, as parsing malformed files may consume significant
+resources, or cause panics.
+*/
+package elf
+
+import (
+ "bytes"
+ "compress/zlib"
+ "debug/dwarf"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "internal/saferio"
+ "internal/zstd"
+ "io"
+ "os"
+ "strings"
+)
+
+// seekStart, seekCurrent, seekEnd are copies of
+// io.SeekStart, io.SeekCurrent, and io.SeekEnd.
+// We can't use the ones from package io because
+// we want this code to build with Go 1.4 during
+// cmd/dist bootstrap.
+const (
+ seekStart int = 0
+ seekCurrent int = 1
+ seekEnd int = 2
+)
+
+// TODO: error reporting detail
+
+/*
+ * Internal ELF representation
+ */
+
+// A FileHeader represents an ELF file header.
+type FileHeader struct {
+ Class Class
+ Data Data
+ Version Version
+ OSABI OSABI
+ ABIVersion uint8
+ ByteOrder binary.ByteOrder
+ Type Type
+ Machine Machine
+ Entry uint64
+}
+
+// A File represents an open ELF file.
+type File struct {
+ FileHeader
+ Sections []*Section
+ Progs []*Prog
+ closer io.Closer
+ gnuNeed []verneed
+ gnuVersym []byte
+}
+
+// A SectionHeader represents a single ELF section header.
+type SectionHeader struct {
+ Name string
+ Type SectionType
+ Flags SectionFlag
+ Addr uint64
+ Offset uint64
+ Size uint64
+ Link uint32
+ Info uint32
+ Addralign uint64
+ Entsize uint64
+
+ // FileSize is the size of this section in the file in bytes.
+ // If a section is compressed, FileSize is the size of the
+ // compressed data, while Size (above) is the size of the
+ // uncompressed data.
+ FileSize uint64
+}
+
+// A Section represents a single section in an ELF file.
+type Section struct {
+ SectionHeader
+
+ // Embed ReaderAt for ReadAt method.
+ // Do not embed SectionReader directly
+ // to avoid having Read and Seek.
+ // If a client wants Read and Seek it must use
+ // Open() to avoid fighting over the seek offset
+ // with other clients.
+ //
+ // ReaderAt may be nil if the section is not easily available
+ // in a random-access form. For example, a compressed section
+ // may have a nil ReaderAt.
+ io.ReaderAt
+ sr *io.SectionReader
+
+ compressionType CompressionType
+ compressionOffset int64
+}
+
+// Data reads and returns the contents of the ELF section.
+// Even if the section is stored compressed in the ELF file,
+// Data returns uncompressed data.
+//
+// For an SHT_NOBITS section, Data always returns a non-nil error.
+func (s *Section) Data() ([]byte, error) {
+ return saferio.ReadData(s.Open(), s.Size)
+}
+
+// stringTable reads and returns the string table given by the
+// specified link value.
+func (f *File) stringTable(link uint32) ([]byte, error) {
+ if link <= 0 || link >= uint32(len(f.Sections)) {
+ return nil, errors.New("section has invalid string table link")
+ }
+ return f.Sections[link].Data()
+}
+
+// Open returns a new ReadSeeker reading the ELF section.
+// Even if the section is stored compressed in the ELF file,
+// the ReadSeeker reads uncompressed data.
+//
+// For an SHT_NOBITS section, all calls to the opened reader
+// will return a non-nil error.
+func (s *Section) Open() io.ReadSeeker {
+ if s.Type == SHT_NOBITS {
+ return io.NewSectionReader(&nobitsSectionReader{}, 0, int64(s.Size))
+ }
+
+ var zrd func(io.Reader) (io.ReadCloser, error)
+ if s.Flags&SHF_COMPRESSED == 0 {
+
+ if !strings.HasPrefix(s.Name, ".zdebug") {
+ return io.NewSectionReader(s.sr, 0, 1<<63-1)
+ }
+
+ b := make([]byte, 12)
+ n, _ := s.sr.ReadAt(b, 0)
+ if n != 12 || string(b[:4]) != "ZLIB" {
+ return io.NewSectionReader(s.sr, 0, 1<<63-1)
+ }
+
+ s.compressionOffset = 12
+ s.compressionType = COMPRESS_ZLIB
+ s.Size = binary.BigEndian.Uint64(b[4:12])
+ zrd = zlib.NewReader
+
+ } else if s.Flags&SHF_ALLOC != 0 {
+ return errorReader{&FormatError{int64(s.Offset),
+ "SHF_COMPRESSED applies only to non-allocable sections", s.compressionType}}
+ }
+
+ switch s.compressionType {
+ case COMPRESS_ZLIB:
+ zrd = zlib.NewReader
+ case COMPRESS_ZSTD:
+ zrd = func(r io.Reader) (io.ReadCloser, error) {
+ return io.NopCloser(zstd.NewReader(r)), nil
+ }
+ }
+
+ if zrd == nil {
+ return errorReader{&FormatError{int64(s.Offset), "unknown compression type", s.compressionType}}
+ }
+
+ return &readSeekerFromReader{
+ reset: func() (io.Reader, error) {
+ fr := io.NewSectionReader(s.sr, s.compressionOffset, int64(s.FileSize)-s.compressionOffset)
+ return zrd(fr)
+ },
+ size: int64(s.Size),
+ }
+}
+
+// A ProgHeader represents a single ELF program header.
+type ProgHeader struct {
+ Type ProgType
+ Flags ProgFlag
+ Off uint64
+ Vaddr uint64
+ Paddr uint64
+ Filesz uint64
+ Memsz uint64
+ Align uint64
+}
+
+// A Prog represents a single ELF program header in an ELF binary.
+type Prog struct {
+ ProgHeader
+
+ // Embed ReaderAt for ReadAt method.
+ // Do not embed SectionReader directly
+ // to avoid having Read and Seek.
+ // If a client wants Read and Seek it must use
+ // Open() to avoid fighting over the seek offset
+ // with other clients.
+ io.ReaderAt
+ sr *io.SectionReader
+}
+
+// Open returns a new ReadSeeker reading the ELF program body.
+func (p *Prog) Open() io.ReadSeeker { return io.NewSectionReader(p.sr, 0, 1<<63-1) }
+
+// A Symbol represents an entry in an ELF symbol table section.
+type Symbol struct {
+ Name string
+ Info, Other byte
+ Section SectionIndex
+ Value, Size uint64
+
+ // Version and Library are present only for the dynamic symbol
+ // table.
+ Version string
+ Library string
+}
+
+/*
+ * ELF reader
+ */
+
+type FormatError struct {
+ off int64
+ msg string
+ val any
+}
+
+func (e *FormatError) Error() string {
+ msg := e.msg
+ if e.val != nil {
+ msg += fmt.Sprintf(" '%v' ", e.val)
+ }
+ msg += fmt.Sprintf("in record at byte %#x", e.off)
+ return msg
+}
+
+// Open opens the named file using os.Open and prepares it for use as an ELF binary.
+func Open(name string) (*File, error) {
+ f, err := os.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ ff, err := NewFile(f)
+ if err != nil {
+ f.Close()
+ return nil, err
+ }
+ ff.closer = f
+ return ff, nil
+}
+
+// Close closes the File.
+// If the File was created using NewFile directly instead of Open,
+// Close has no effect.
+func (f *File) Close() error {
+ var err error
+ if f.closer != nil {
+ err = f.closer.Close()
+ f.closer = nil
+ }
+ return err
+}
+
+// SectionByType returns the first section in f with the
+// given type, or nil if there is no such section.
+func (f *File) SectionByType(typ SectionType) *Section {
+ for _, s := range f.Sections {
+ if s.Type == typ {
+ return s
+ }
+ }
+ return nil
+}
+
+// NewFile creates a new File for accessing an ELF binary in an underlying reader.
+// The ELF binary is expected to start at position 0 in the ReaderAt.
+func NewFile(r io.ReaderAt) (*File, error) {
+ sr := io.NewSectionReader(r, 0, 1<<63-1)
+ // Read and decode ELF identifier
+ var ident [16]uint8
+ if _, err := r.ReadAt(ident[0:], 0); err != nil {
+ return nil, err
+ }
+ if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' {
+ return nil, &FormatError{0, "bad magic number", ident[0:4]}
+ }
+
+ f := new(File)
+ f.Class = Class(ident[EI_CLASS])
+ switch f.Class {
+ case ELFCLASS32:
+ case ELFCLASS64:
+ // ok
+ default:
+ return nil, &FormatError{0, "unknown ELF class", f.Class}
+ }
+
+ f.Data = Data(ident[EI_DATA])
+ switch f.Data {
+ case ELFDATA2LSB:
+ f.ByteOrder = binary.LittleEndian
+ case ELFDATA2MSB:
+ f.ByteOrder = binary.BigEndian
+ default:
+ return nil, &FormatError{0, "unknown ELF data encoding", f.Data}
+ }
+
+ f.Version = Version(ident[EI_VERSION])
+ if f.Version != EV_CURRENT {
+ return nil, &FormatError{0, "unknown ELF version", f.Version}
+ }
+
+ f.OSABI = OSABI(ident[EI_OSABI])
+ f.ABIVersion = ident[EI_ABIVERSION]
+
+ // Read ELF file header
+ var phoff int64
+ var phentsize, phnum int
+ var shoff int64
+ var shentsize, shnum, shstrndx int
+ switch f.Class {
+ case ELFCLASS32:
+ hdr := new(Header32)
+ sr.Seek(0, seekStart)
+ if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
+ return nil, err
+ }
+ f.Type = Type(hdr.Type)
+ f.Machine = Machine(hdr.Machine)
+ f.Entry = uint64(hdr.Entry)
+ if v := Version(hdr.Version); v != f.Version {
+ return nil, &FormatError{0, "mismatched ELF version", v}
+ }
+ phoff = int64(hdr.Phoff)
+ phentsize = int(hdr.Phentsize)
+ phnum = int(hdr.Phnum)
+ shoff = int64(hdr.Shoff)
+ shentsize = int(hdr.Shentsize)
+ shnum = int(hdr.Shnum)
+ shstrndx = int(hdr.Shstrndx)
+ case ELFCLASS64:
+ hdr := new(Header64)
+ sr.Seek(0, seekStart)
+ if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
+ return nil, err
+ }
+ f.Type = Type(hdr.Type)
+ f.Machine = Machine(hdr.Machine)
+ f.Entry = hdr.Entry
+ if v := Version(hdr.Version); v != f.Version {
+ return nil, &FormatError{0, "mismatched ELF version", v}
+ }
+ phoff = int64(hdr.Phoff)
+ phentsize = int(hdr.Phentsize)
+ phnum = int(hdr.Phnum)
+ shoff = int64(hdr.Shoff)
+ shentsize = int(hdr.Shentsize)
+ shnum = int(hdr.Shnum)
+ shstrndx = int(hdr.Shstrndx)
+ }
+
+ if shoff < 0 {
+ return nil, &FormatError{0, "invalid shoff", shoff}
+ }
+ if phoff < 0 {
+ return nil, &FormatError{0, "invalid phoff", phoff}
+ }
+
+ if shoff == 0 && shnum != 0 {
+ return nil, &FormatError{0, "invalid ELF shnum for shoff=0", shnum}
+ }
+
+ if shnum > 0 && shstrndx >= shnum {
+ return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx}
+ }
+
+ var wantPhentsize, wantShentsize int
+ switch f.Class {
+ case ELFCLASS32:
+ wantPhentsize = 8 * 4
+ wantShentsize = 10 * 4
+ case ELFCLASS64:
+ wantPhentsize = 2*4 + 6*8
+ wantShentsize = 4*4 + 6*8
+ }
+ if phnum > 0 && phentsize < wantPhentsize {
+ return nil, &FormatError{0, "invalid ELF phentsize", phentsize}
+ }
+
+ // Read program headers
+ f.Progs = make([]*Prog, phnum)
+ for i := 0; i < phnum; i++ {
+ off := phoff + int64(i)*int64(phentsize)
+ sr.Seek(off, seekStart)
+ p := new(Prog)
+ switch f.Class {
+ case ELFCLASS32:
+ ph := new(Prog32)
+ if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
+ return nil, err
+ }
+ p.ProgHeader = ProgHeader{
+ Type: ProgType(ph.Type),
+ Flags: ProgFlag(ph.Flags),
+ Off: uint64(ph.Off),
+ Vaddr: uint64(ph.Vaddr),
+ Paddr: uint64(ph.Paddr),
+ Filesz: uint64(ph.Filesz),
+ Memsz: uint64(ph.Memsz),
+ Align: uint64(ph.Align),
+ }
+ case ELFCLASS64:
+ ph := new(Prog64)
+ if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
+ return nil, err
+ }
+ p.ProgHeader = ProgHeader{
+ Type: ProgType(ph.Type),
+ Flags: ProgFlag(ph.Flags),
+ Off: ph.Off,
+ Vaddr: ph.Vaddr,
+ Paddr: ph.Paddr,
+ Filesz: ph.Filesz,
+ Memsz: ph.Memsz,
+ Align: ph.Align,
+ }
+ }
+ if int64(p.Off) < 0 {
+ return nil, &FormatError{off, "invalid program header offset", p.Off}
+ }
+ if int64(p.Filesz) < 0 {
+ return nil, &FormatError{off, "invalid program header file size", p.Filesz}
+ }
+ p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz))
+ p.ReaderAt = p.sr
+ f.Progs[i] = p
+ }
+
+ // If the number of sections is greater than or equal to SHN_LORESERVE
+ // (0xff00), shnum has the value zero and the actual number of section
+ // header table entries is contained in the sh_size field of the section
+ // header at index 0.
+ if shoff > 0 && shnum == 0 {
+ var typ, link uint32
+ sr.Seek(shoff, seekStart)
+ switch f.Class {
+ case ELFCLASS32:
+ sh := new(Section32)
+ if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
+ return nil, err
+ }
+ shnum = int(sh.Size)
+ typ = sh.Type
+ link = sh.Link
+ case ELFCLASS64:
+ sh := new(Section64)
+ if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
+ return nil, err
+ }
+ shnum = int(sh.Size)
+ typ = sh.Type
+ link = sh.Link
+ }
+ if SectionType(typ) != SHT_NULL {
+ return nil, &FormatError{shoff, "invalid type of the initial section", SectionType(typ)}
+ }
+
+ if shnum < int(SHN_LORESERVE) {
+ return nil, &FormatError{shoff, "invalid ELF shnum contained in sh_size", shnum}
+ }
+
+ // If the section name string table section index is greater than or
+ // equal to SHN_LORESERVE (0xff00), this member has the value
+ // SHN_XINDEX (0xffff) and the actual index of the section name
+ // string table section is contained in the sh_link field of the
+ // section header at index 0.
+ if shstrndx == int(SHN_XINDEX) {
+ shstrndx = int(link)
+ if shstrndx < int(SHN_LORESERVE) {
+ return nil, &FormatError{shoff, "invalid ELF shstrndx contained in sh_link", shstrndx}
+ }
+ }
+ }
+
+ if shnum > 0 && shentsize < wantShentsize {
+ return nil, &FormatError{0, "invalid ELF shentsize", shentsize}
+ }
+
+ // Read section headers
+ c := saferio.SliceCap((*Section)(nil), uint64(shnum))
+ if c < 0 {
+ return nil, &FormatError{0, "too many sections", shnum}
+ }
+ f.Sections = make([]*Section, 0, c)
+ names := make([]uint32, 0, c)
+ for i := 0; i < shnum; i++ {
+ off := shoff + int64(i)*int64(shentsize)
+ sr.Seek(off, seekStart)
+ s := new(Section)
+ switch f.Class {
+ case ELFCLASS32:
+ sh := new(Section32)
+ if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
+ return nil, err
+ }
+ names = append(names, sh.Name)
+ s.SectionHeader = SectionHeader{
+ Type: SectionType(sh.Type),
+ Flags: SectionFlag(sh.Flags),
+ Addr: uint64(sh.Addr),
+ Offset: uint64(sh.Off),
+ FileSize: uint64(sh.Size),
+ Link: sh.Link,
+ Info: sh.Info,
+ Addralign: uint64(sh.Addralign),
+ Entsize: uint64(sh.Entsize),
+ }
+ case ELFCLASS64:
+ sh := new(Section64)
+ if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
+ return nil, err
+ }
+ names = append(names, sh.Name)
+ s.SectionHeader = SectionHeader{
+ Type: SectionType(sh.Type),
+ Flags: SectionFlag(sh.Flags),
+ Offset: sh.Off,
+ FileSize: sh.Size,
+ Addr: sh.Addr,
+ Link: sh.Link,
+ Info: sh.Info,
+ Addralign: sh.Addralign,
+ Entsize: sh.Entsize,
+ }
+ }
+ if int64(s.Offset) < 0 {
+ return nil, &FormatError{off, "invalid section offset", int64(s.Offset)}
+ }
+ if int64(s.FileSize) < 0 {
+ return nil, &FormatError{off, "invalid section size", int64(s.FileSize)}
+ }
+ s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.FileSize))
+
+ if s.Flags&SHF_COMPRESSED == 0 {
+ s.ReaderAt = s.sr
+ s.Size = s.FileSize
+ } else {
+ // Read the compression header.
+ switch f.Class {
+ case ELFCLASS32:
+ ch := new(Chdr32)
+ if err := binary.Read(s.sr, f.ByteOrder, ch); err != nil {
+ return nil, err
+ }
+ s.compressionType = CompressionType(ch.Type)
+ s.Size = uint64(ch.Size)
+ s.Addralign = uint64(ch.Addralign)
+ s.compressionOffset = int64(binary.Size(ch))
+ case ELFCLASS64:
+ ch := new(Chdr64)
+ if err := binary.Read(s.sr, f.ByteOrder, ch); err != nil {
+ return nil, err
+ }
+ s.compressionType = CompressionType(ch.Type)
+ s.Size = ch.Size
+ s.Addralign = ch.Addralign
+ s.compressionOffset = int64(binary.Size(ch))
+ }
+ }
+
+ f.Sections = append(f.Sections, s)
+ }
+
+ if len(f.Sections) == 0 {
+ return f, nil
+ }
+
+ // Load section header string table.
+ if shstrndx == 0 {
+ // If the file has no section name string table,
+ // shstrndx holds the value SHN_UNDEF (0).
+ return f, nil
+ }
+ shstr := f.Sections[shstrndx]
+ if shstr.Type != SHT_STRTAB {
+ return nil, &FormatError{shoff + int64(shstrndx*shentsize), "invalid ELF section name string table type", shstr.Type}
+ }
+ shstrtab, err := shstr.Data()
+ if err != nil {
+ return nil, err
+ }
+ for i, s := range f.Sections {
+ var ok bool
+ s.Name, ok = getString(shstrtab, int(names[i]))
+ if !ok {
+ return nil, &FormatError{shoff + int64(i*shentsize), "bad section name index", names[i]}
+ }
+ }
+
+ return f, nil
+}
+
+// getSymbols returns a slice of Symbols from parsing the symbol table
+// with the given type, along with the associated string table.
+func (f *File) getSymbols(typ SectionType) ([]Symbol, []byte, error) {
+ switch f.Class {
+ case ELFCLASS64:
+ return f.getSymbols64(typ)
+
+ case ELFCLASS32:
+ return f.getSymbols32(typ)
+ }
+
+ return nil, nil, errors.New("not implemented")
+}
+
+// ErrNoSymbols is returned by File.Symbols and File.DynamicSymbols
+// if there is no such section in the File.
+var ErrNoSymbols = errors.New("no symbol section")
+
+func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) {
+ symtabSection := f.SectionByType(typ)
+ if symtabSection == nil {
+ return nil, nil, ErrNoSymbols
+ }
+
+ data, err := symtabSection.Data()
+ if err != nil {
+ return nil, nil, fmt.Errorf("cannot load symbol section: %w", err)
+ }
+ symtab := bytes.NewReader(data)
+ if symtab.Len()%Sym32Size != 0 {
+ return nil, nil, errors.New("length of symbol section is not a multiple of SymSize")
+ }
+
+ strdata, err := f.stringTable(symtabSection.Link)
+ if err != nil {
+ return nil, nil, fmt.Errorf("cannot load string table section: %w", err)
+ }
+
+ // The first entry is all zeros.
+ var skip [Sym32Size]byte
+ symtab.Read(skip[:])
+
+ symbols := make([]Symbol, symtab.Len()/Sym32Size)
+
+ i := 0
+ var sym Sym32
+ for symtab.Len() > 0 {
+ binary.Read(symtab, f.ByteOrder, &sym)
+ str, _ := getString(strdata, int(sym.Name))
+ symbols[i].Name = str
+ symbols[i].Info = sym.Info
+ symbols[i].Other = sym.Other
+ symbols[i].Section = SectionIndex(sym.Shndx)
+ symbols[i].Value = uint64(sym.Value)
+ symbols[i].Size = uint64(sym.Size)
+ i++
+ }
+
+ return symbols, strdata, nil
+}
+
+func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) {
+ symtabSection := f.SectionByType(typ)
+ if symtabSection == nil {
+ return nil, nil, ErrNoSymbols
+ }
+
+ data, err := symtabSection.Data()
+ if err != nil {
+ return nil, nil, fmt.Errorf("cannot load symbol section: %w", err)
+ }
+ symtab := bytes.NewReader(data)
+ if symtab.Len()%Sym64Size != 0 {
+ return nil, nil, errors.New("length of symbol section is not a multiple of Sym64Size")
+ }
+
+ strdata, err := f.stringTable(symtabSection.Link)
+ if err != nil {
+ return nil, nil, fmt.Errorf("cannot load string table section: %w", err)
+ }
+
+ // The first entry is all zeros.
+ var skip [Sym64Size]byte
+ symtab.Read(skip[:])
+
+ symbols := make([]Symbol, symtab.Len()/Sym64Size)
+
+ i := 0
+ var sym Sym64
+ for symtab.Len() > 0 {
+ binary.Read(symtab, f.ByteOrder, &sym)
+ str, _ := getString(strdata, int(sym.Name))
+ symbols[i].Name = str
+ symbols[i].Info = sym.Info
+ symbols[i].Other = sym.Other
+ symbols[i].Section = SectionIndex(sym.Shndx)
+ symbols[i].Value = sym.Value
+ symbols[i].Size = sym.Size
+ i++
+ }
+
+ return symbols, strdata, nil
+}
+
+// getString extracts a string from an ELF string table.
+func getString(section []byte, start int) (string, bool) {
+ if start < 0 || start >= len(section) {
+ return "", false
+ }
+
+ for end := start; end < len(section); end++ {
+ if section[end] == 0 {
+ return string(section[start:end]), true
+ }
+ }
+ return "", false
+}
+
+// Section returns a section with the given name, or nil if no such
+// section exists.
+func (f *File) Section(name string) *Section {
+ for _, s := range f.Sections {
+ if s.Name == name {
+ return s
+ }
+ }
+ return nil
+}
+
+// applyRelocations applies relocations to dst. rels is a relocations section
+// in REL or RELA format.
+func (f *File) applyRelocations(dst []byte, rels []byte) error {
+ switch {
+ case f.Class == ELFCLASS64 && f.Machine == EM_X86_64:
+ return f.applyRelocationsAMD64(dst, rels)
+ case f.Class == ELFCLASS32 && f.Machine == EM_386:
+ return f.applyRelocations386(dst, rels)
+ case f.Class == ELFCLASS32 && f.Machine == EM_ARM:
+ return f.applyRelocationsARM(dst, rels)
+ case f.Class == ELFCLASS64 && f.Machine == EM_AARCH64:
+ return f.applyRelocationsARM64(dst, rels)
+ case f.Class == ELFCLASS32 && f.Machine == EM_PPC:
+ return f.applyRelocationsPPC(dst, rels)
+ case f.Class == ELFCLASS64 && f.Machine == EM_PPC64:
+ return f.applyRelocationsPPC64(dst, rels)
+ case f.Class == ELFCLASS32 && f.Machine == EM_MIPS:
+ return f.applyRelocationsMIPS(dst, rels)
+ case f.Class == ELFCLASS64 && f.Machine == EM_MIPS:
+ return f.applyRelocationsMIPS64(dst, rels)
+ case f.Class == ELFCLASS64 && f.Machine == EM_LOONGARCH:
+ return f.applyRelocationsLOONG64(dst, rels)
+ case f.Class == ELFCLASS64 && f.Machine == EM_RISCV:
+ return f.applyRelocationsRISCV64(dst, rels)
+ case f.Class == ELFCLASS64 && f.Machine == EM_S390:
+ return f.applyRelocationss390x(dst, rels)
+ case f.Class == ELFCLASS64 && f.Machine == EM_SPARCV9:
+ return f.applyRelocationsSPARC64(dst, rels)
+ default:
+ return errors.New("applyRelocations: not implemented")
+ }
+}
+
+// canApplyRelocation reports whether we should try to apply a
+// relocation to a DWARF data section, given a pointer to the symbol
+// targeted by the relocation.
+// Most relocations in DWARF data tend to be section-relative, but
+// some target non-section symbols (for example, low_PC attrs on
+// subprogram or compilation unit DIEs that target function symbols).
+func canApplyRelocation(sym *Symbol) bool {
+ return sym.Section != SHN_UNDEF && sym.Section < SHN_LORESERVE
+}
+
+func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
+ // 24 is the size of Rela64.
+ if len(rels)%24 != 0 {
+ return errors.New("length of relocation section is not a multiple of 24")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rela Rela64
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rela)
+ symNo := rela.Info >> 32
+ t := R_X86_64(rela.Info & 0xffff)
+
+ if symNo == 0 || symNo > uint64(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+ if !canApplyRelocation(sym) {
+ continue
+ }
+
+ // There are relocations, so this must be a normal
+ // object file. The code below handles only basic relocations
+ // of the form S + A (symbol plus addend).
+
+ switch t {
+ case R_X86_64_64:
+ if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val64 := sym.Value + uint64(rela.Addend)
+ f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
+ case R_X86_64_32:
+ if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
+ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
+ }
+ }
+
+ return nil
+}
+
+func (f *File) applyRelocations386(dst []byte, rels []byte) error {
+ // 8 is the size of Rel32.
+ if len(rels)%8 != 0 {
+ return errors.New("length of relocation section is not a multiple of 8")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rel Rel32
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rel)
+ symNo := rel.Info >> 8
+ t := R_386(rel.Info & 0xff)
+
+ if symNo == 0 || symNo > uint32(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+
+ if t == R_386_32 {
+ if rel.Off+4 >= uint32(len(dst)) {
+ continue
+ }
+ val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
+ val += uint32(sym.Value)
+ f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
+ }
+ }
+
+ return nil
+}
+
+func (f *File) applyRelocationsARM(dst []byte, rels []byte) error {
+ // 8 is the size of Rel32.
+ if len(rels)%8 != 0 {
+ return errors.New("length of relocation section is not a multiple of 8")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rel Rel32
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rel)
+ symNo := rel.Info >> 8
+ t := R_ARM(rel.Info & 0xff)
+
+ if symNo == 0 || symNo > uint32(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+
+ switch t {
+ case R_ARM_ABS32:
+ if rel.Off+4 >= uint32(len(dst)) {
+ continue
+ }
+ val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
+ val += uint32(sym.Value)
+ f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
+ }
+ }
+
+ return nil
+}
+
+func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
+ // 24 is the size of Rela64.
+ if len(rels)%24 != 0 {
+ return errors.New("length of relocation section is not a multiple of 24")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rela Rela64
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rela)
+ symNo := rela.Info >> 32
+ t := R_AARCH64(rela.Info & 0xffff)
+
+ if symNo == 0 || symNo > uint64(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+ if !canApplyRelocation(sym) {
+ continue
+ }
+
+ // There are relocations, so this must be a normal
+ // object file. The code below handles only basic relocations
+ // of the form S + A (symbol plus addend).
+
+ switch t {
+ case R_AARCH64_ABS64:
+ if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val64 := sym.Value + uint64(rela.Addend)
+ f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
+ case R_AARCH64_ABS32:
+ if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
+ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
+ }
+ }
+
+ return nil
+}
+
+func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error {
+ // 12 is the size of Rela32.
+ if len(rels)%12 != 0 {
+ return errors.New("length of relocation section is not a multiple of 12")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rela Rela32
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rela)
+ symNo := rela.Info >> 8
+ t := R_PPC(rela.Info & 0xff)
+
+ if symNo == 0 || symNo > uint32(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+ if !canApplyRelocation(sym) {
+ continue
+ }
+
+ switch t {
+ case R_PPC_ADDR32:
+ if rela.Off+4 >= uint32(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
+ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
+ }
+ }
+
+ return nil
+}
+
+func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error {
+ // 24 is the size of Rela64.
+ if len(rels)%24 != 0 {
+ return errors.New("length of relocation section is not a multiple of 24")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rela Rela64
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rela)
+ symNo := rela.Info >> 32
+ t := R_PPC64(rela.Info & 0xffff)
+
+ if symNo == 0 || symNo > uint64(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+ if !canApplyRelocation(sym) {
+ continue
+ }
+
+ switch t {
+ case R_PPC64_ADDR64:
+ if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val64 := sym.Value + uint64(rela.Addend)
+ f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
+ case R_PPC64_ADDR32:
+ if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
+ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
+ }
+ }
+
+ return nil
+}
+
+func (f *File) applyRelocationsMIPS(dst []byte, rels []byte) error {
+ // 8 is the size of Rel32.
+ if len(rels)%8 != 0 {
+ return errors.New("length of relocation section is not a multiple of 8")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rel Rel32
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rel)
+ symNo := rel.Info >> 8
+ t := R_MIPS(rel.Info & 0xff)
+
+ if symNo == 0 || symNo > uint32(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+
+ switch t {
+ case R_MIPS_32:
+ if rel.Off+4 >= uint32(len(dst)) {
+ continue
+ }
+ val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
+ val += uint32(sym.Value)
+ f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
+ }
+ }
+
+ return nil
+}
+
+func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error {
+ // 24 is the size of Rela64.
+ if len(rels)%24 != 0 {
+ return errors.New("length of relocation section is not a multiple of 24")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rela Rela64
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rela)
+ var symNo uint64
+ var t R_MIPS
+ if f.ByteOrder == binary.BigEndian {
+ symNo = rela.Info >> 32
+ t = R_MIPS(rela.Info & 0xff)
+ } else {
+ symNo = rela.Info & 0xffffffff
+ t = R_MIPS(rela.Info >> 56)
+ }
+
+ if symNo == 0 || symNo > uint64(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+ if !canApplyRelocation(sym) {
+ continue
+ }
+
+ switch t {
+ case R_MIPS_64:
+ if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val64 := sym.Value + uint64(rela.Addend)
+ f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
+ case R_MIPS_32:
+ if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
+ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
+ }
+ }
+
+ return nil
+}
+
+func (f *File) applyRelocationsLOONG64(dst []byte, rels []byte) error {
+ // 24 is the size of Rela64.
+ if len(rels)%24 != 0 {
+ return errors.New("length of relocation section is not a multiple of 24")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rela Rela64
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rela)
+ var symNo uint64
+ var t R_LARCH
+ symNo = rela.Info >> 32
+ t = R_LARCH(rela.Info & 0xffff)
+
+ if symNo == 0 || symNo > uint64(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+ if !canApplyRelocation(sym) {
+ continue
+ }
+
+ switch t {
+ case R_LARCH_64:
+ if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val64 := sym.Value + uint64(rela.Addend)
+ f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
+ case R_LARCH_32:
+ if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
+ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
+ }
+ }
+
+ return nil
+}
+
+func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error {
+ // 24 is the size of Rela64.
+ if len(rels)%24 != 0 {
+ return errors.New("length of relocation section is not a multiple of 24")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rela Rela64
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rela)
+ symNo := rela.Info >> 32
+ t := R_RISCV(rela.Info & 0xffff)
+
+ if symNo == 0 || symNo > uint64(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+ if !canApplyRelocation(sym) {
+ continue
+ }
+
+ switch t {
+ case R_RISCV_64:
+ if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val64 := sym.Value + uint64(rela.Addend)
+ f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
+ case R_RISCV_32:
+ if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
+ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
+ }
+ }
+
+ return nil
+}
+
+func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
+ // 24 is the size of Rela64.
+ if len(rels)%24 != 0 {
+ return errors.New("length of relocation section is not a multiple of 24")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rela Rela64
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rela)
+ symNo := rela.Info >> 32
+ t := R_390(rela.Info & 0xffff)
+
+ if symNo == 0 || symNo > uint64(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+ if !canApplyRelocation(sym) {
+ continue
+ }
+
+ switch t {
+ case R_390_64:
+ if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val64 := sym.Value + uint64(rela.Addend)
+ f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
+ case R_390_32:
+ if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
+ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
+ }
+ }
+
+ return nil
+}
+
+func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
+ // 24 is the size of Rela64.
+ if len(rels)%24 != 0 {
+ return errors.New("length of relocation section is not a multiple of 24")
+ }
+
+ symbols, _, err := f.getSymbols(SHT_SYMTAB)
+ if err != nil {
+ return err
+ }
+
+ b := bytes.NewReader(rels)
+ var rela Rela64
+
+ for b.Len() > 0 {
+ binary.Read(b, f.ByteOrder, &rela)
+ symNo := rela.Info >> 32
+ t := R_SPARC(rela.Info & 0xff)
+
+ if symNo == 0 || symNo > uint64(len(symbols)) {
+ continue
+ }
+ sym := &symbols[symNo-1]
+ if !canApplyRelocation(sym) {
+ continue
+ }
+
+ switch t {
+ case R_SPARC_64, R_SPARC_UA64:
+ if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val64 := sym.Value + uint64(rela.Addend)
+ f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], val64)
+ case R_SPARC_32, R_SPARC_UA32:
+ if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+ continue
+ }
+ val32 := uint32(sym.Value) + uint32(rela.Addend)
+ f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], val32)
+ }
+ }
+
+ return nil
+}
+
+func (f *File) DWARF() (*dwarf.Data, error) {
+ dwarfSuffix := func(s *Section) string {
+ switch {
+ case strings.HasPrefix(s.Name, ".debug_"):
+ return s.Name[7:]
+ case strings.HasPrefix(s.Name, ".zdebug_"):
+ return s.Name[8:]
+ default:
+ return ""
+ }
+
+ }
+ // sectionData gets the data for s, checks its size, and
+ // applies any applicable relations.
+ sectionData := func(i int, s *Section) ([]byte, error) {
+ b, err := s.Data()
+ if err != nil && uint64(len(b)) < s.Size {
+ return nil, err
+ }
+
+ if f.Type == ET_EXEC {
+ // Do not apply relocations to DWARF sections for ET_EXEC binaries.
+ // Relocations should already be applied, and .rela sections may
+ // contain incorrect data.
+ return b, nil
+ }
+
+ for _, r := range f.Sections {
+ if r.Type != SHT_RELA && r.Type != SHT_REL {
+ continue
+ }
+ if int(r.Info) != i {
+ continue
+ }
+ rd, err := r.Data()
+ if err != nil {
+ return nil, err
+ }
+ err = f.applyRelocations(b, rd)
+ if err != nil {
+ return nil, err
+ }
+ }
+ return b, nil
+ }
+
+ // There are many DWARf sections, but these are the ones
+ // the debug/dwarf package started with.
+ var dat = map[string][]byte{"abbrev": nil, "info": nil, "str": nil, "line": nil, "ranges": nil}
+ for i, s := range f.Sections {
+ suffix := dwarfSuffix(s)
+ if suffix == "" {
+ continue
+ }
+ if _, ok := dat[suffix]; !ok {
+ continue
+ }
+ b, err := sectionData(i, s)
+ if err != nil {
+ return nil, err
+ }
+ dat[suffix] = b
+ }
+
+ d, err := dwarf.New(dat["abbrev"], nil, nil, dat["info"], dat["line"], nil, dat["ranges"], dat["str"])
+ if err != nil {
+ return nil, err
+ }
+
+ // Look for DWARF4 .debug_types sections and DWARF5 sections.
+ for i, s := range f.Sections {
+ suffix := dwarfSuffix(s)
+ if suffix == "" {
+ continue
+ }
+ if _, ok := dat[suffix]; ok {
+ // Already handled.
+ continue
+ }
+
+ b, err := sectionData(i, s)
+ if err != nil {
+ return nil, err
+ }
+
+ if suffix == "types" {
+ if err := d.AddTypes(fmt.Sprintf("types-%d", i), b); err != nil {
+ return nil, err
+ }
+ } else {
+ if err := d.AddSection(".debug_"+suffix, b); err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ return d, nil
+}
+
+// Symbols returns the symbol table for f. The symbols will be listed in the order
+// they appear in f.
+//
+// For compatibility with Go 1.0, Symbols omits the null symbol at index 0.
+// After retrieving the symbols as symtab, an externally supplied index x
+// corresponds to symtab[x-1], not symtab[x].
+func (f *File) Symbols() ([]Symbol, error) {
+ sym, _, err := f.getSymbols(SHT_SYMTAB)
+ return sym, err
+}
+
+// DynamicSymbols returns the dynamic symbol table for f. The symbols
+// will be listed in the order they appear in f.
+//
+// If f has a symbol version table, the returned Symbols will have
+// initialized Version and Library fields.
+//
+// For compatibility with Symbols, DynamicSymbols omits the null symbol at index 0.
+// After retrieving the symbols as symtab, an externally supplied index x
+// corresponds to symtab[x-1], not symtab[x].
+func (f *File) DynamicSymbols() ([]Symbol, error) {
+ sym, str, err := f.getSymbols(SHT_DYNSYM)
+ if err != nil {
+ return nil, err
+ }
+ if f.gnuVersionInit(str) {
+ for i := range sym {
+ sym[i].Library, sym[i].Version = f.gnuVersion(i)
+ }
+ }
+ return sym, nil
+}
+
+type ImportedSymbol struct {
+ Name string
+ Version string
+ Library string
+}
+
+// ImportedSymbols returns the names of all symbols
+// referred to by the binary f that are expected to be
+// satisfied by other libraries at dynamic load time.
+// It does not return weak symbols.
+func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
+ sym, str, err := f.getSymbols(SHT_DYNSYM)
+ if err != nil {
+ return nil, err
+ }
+ f.gnuVersionInit(str)
+ var all []ImportedSymbol
+ for i, s := range sym {
+ if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF {
+ all = append(all, ImportedSymbol{Name: s.Name})
+ sym := &all[len(all)-1]
+ sym.Library, sym.Version = f.gnuVersion(i)
+ }
+ }
+ return all, nil
+}
+
+type verneed struct {
+ File string
+ Name string
+}
+
+// gnuVersionInit parses the GNU version tables
+// for use by calls to gnuVersion.
+func (f *File) gnuVersionInit(str []byte) bool {
+ if f.gnuNeed != nil {
+ // Already initialized
+ return true
+ }
+
+ // Accumulate verneed information.
+ vn := f.SectionByType(SHT_GNU_VERNEED)
+ if vn == nil {
+ return false
+ }
+ d, _ := vn.Data()
+
+ var need []verneed
+ i := 0
+ for {
+ if i+16 > len(d) {
+ break
+ }
+ vers := f.ByteOrder.Uint16(d[i : i+2])
+ if vers != 1 {
+ break
+ }
+ cnt := f.ByteOrder.Uint16(d[i+2 : i+4])
+ fileoff := f.ByteOrder.Uint32(d[i+4 : i+8])
+ aux := f.ByteOrder.Uint32(d[i+8 : i+12])
+ next := f.ByteOrder.Uint32(d[i+12 : i+16])
+ file, _ := getString(str, int(fileoff))
+
+ var name string
+ j := i + int(aux)
+ for c := 0; c < int(cnt); c++ {
+ if j+16 > len(d) {
+ break
+ }
+ // hash := f.ByteOrder.Uint32(d[j:j+4])
+ // flags := f.ByteOrder.Uint16(d[j+4:j+6])
+ other := f.ByteOrder.Uint16(d[j+6 : j+8])
+ nameoff := f.ByteOrder.Uint32(d[j+8 : j+12])
+ next := f.ByteOrder.Uint32(d[j+12 : j+16])
+ name, _ = getString(str, int(nameoff))
+ ndx := int(other)
+ if ndx >= len(need) {
+ a := make([]verneed, 2*(ndx+1))
+ copy(a, need)
+ need = a
+ }
+
+ need[ndx] = verneed{file, name}
+ if next == 0 {
+ break
+ }
+ j += int(next)
+ }
+
+ if next == 0 {
+ break
+ }
+ i += int(next)
+ }
+
+ // Versym parallels symbol table, indexing into verneed.
+ vs := f.SectionByType(SHT_GNU_VERSYM)
+ if vs == nil {
+ return false
+ }
+ d, _ = vs.Data()
+
+ f.gnuNeed = need
+ f.gnuVersym = d
+ return true
+}
+
+// gnuVersion adds Library and Version information to sym,
+// which came from offset i of the symbol table.
+func (f *File) gnuVersion(i int) (library string, version string) {
+ // Each entry is two bytes; skip undef entry at beginning.
+ i = (i + 1) * 2
+ if i >= len(f.gnuVersym) {
+ return
+ }
+ s := f.gnuVersym[i:]
+ if len(s) < 2 {
+ return
+ }
+ j := int(f.ByteOrder.Uint16(s))
+ if j < 2 || j >= len(f.gnuNeed) {
+ return
+ }
+ n := &f.gnuNeed[j]
+ return n.File, n.Name
+}
+
+// ImportedLibraries returns the names of all libraries
+// referred to by the binary f that are expected to be
+// linked with the binary at dynamic link time.
+func (f *File) ImportedLibraries() ([]string, error) {
+ return f.DynString(DT_NEEDED)
+}
+
+// DynString returns the strings listed for the given tag in the file's dynamic
+// section.
+//
+// The tag must be one that takes string values: DT_NEEDED, DT_SONAME, DT_RPATH, or
+// DT_RUNPATH.
+func (f *File) DynString(tag DynTag) ([]string, error) {
+ switch tag {
+ case DT_NEEDED, DT_SONAME, DT_RPATH, DT_RUNPATH:
+ default:
+ return nil, fmt.Errorf("non-string-valued tag %v", tag)
+ }
+ ds := f.SectionByType(SHT_DYNAMIC)
+ if ds == nil {
+ // not dynamic, so no libraries
+ return nil, nil
+ }
+ d, err := ds.Data()
+ if err != nil {
+ return nil, err
+ }
+ str, err := f.stringTable(ds.Link)
+ if err != nil {
+ return nil, err
+ }
+ var all []string
+ for len(d) > 0 {
+ var t DynTag
+ var v uint64
+ switch f.Class {
+ case ELFCLASS32:
+ t = DynTag(f.ByteOrder.Uint32(d[0:4]))
+ v = uint64(f.ByteOrder.Uint32(d[4:8]))
+ d = d[8:]
+ case ELFCLASS64:
+ t = DynTag(f.ByteOrder.Uint64(d[0:8]))
+ v = f.ByteOrder.Uint64(d[8:16])
+ d = d[16:]
+ }
+ if t == tag {
+ s, ok := getString(str, int(v))
+ if ok {
+ all = append(all, s)
+ }
+ }
+ }
+ return all, nil
+}
+
+// DynValue returns the values listed for the given tag in the file's dynamic
+// section.
+func (f *File) DynValue(tag DynTag) ([]uint64, error) {
+ ds := f.SectionByType(SHT_DYNAMIC)
+ if ds == nil {
+ return nil, nil
+ }
+ d, err := ds.Data()
+ if err != nil {
+ return nil, err
+ }
+
+ // Parse the .dynamic section as a string of bytes.
+ var vals []uint64
+ for len(d) > 0 {
+ var t DynTag
+ var v uint64
+ switch f.Class {
+ case ELFCLASS32:
+ t = DynTag(f.ByteOrder.Uint32(d[0:4]))
+ v = uint64(f.ByteOrder.Uint32(d[4:8]))
+ d = d[8:]
+ case ELFCLASS64:
+ t = DynTag(f.ByteOrder.Uint64(d[0:8]))
+ v = f.ByteOrder.Uint64(d[8:16])
+ d = d[16:]
+ }
+ if t == tag {
+ vals = append(vals, v)
+ }
+ }
+ return vals, nil
+}
+
+type nobitsSectionReader struct{}
+
+func (*nobitsSectionReader) ReadAt(p []byte, off int64) (n int, err error) {
+ return 0, errors.New("unexpected read from SHT_NOBITS section")
+}
diff --git a/contrib/go/_std_1.20/src/debug/elf/reader.go b/contrib/go/_std_1.21/src/debug/elf/reader.go
index a45843619e..a45843619e 100644
--- a/contrib/go/_std_1.20/src/debug/elf/reader.go
+++ b/contrib/go/_std_1.21/src/debug/elf/reader.go
diff --git a/contrib/go/_std_1.21/src/debug/elf/ya.make b/contrib/go/_std_1.21/src/debug/elf/ya.make
new file mode 100644
index 0000000000..3f69915129
--- /dev/null
+++ b/contrib/go/_std_1.21/src/debug/elf/ya.make
@@ -0,0 +1,18 @@
+GO_LIBRARY()
+
+SRCS(
+ elf.go
+ file.go
+ reader.go
+)
+
+GO_TEST_SRCS(
+ elf_test.go
+ file_test.go
+ symbols_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/embed/embed.go b/contrib/go/_std_1.21/src/embed/embed.go
new file mode 100644
index 0000000000..8d155ebd55
--- /dev/null
+++ b/contrib/go/_std_1.21/src/embed/embed.go
@@ -0,0 +1,448 @@
+// 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 embed provides access to files embedded in the running Go program.
+//
+// Go source files that import "embed" can use the //go:embed directive
+// to initialize a variable of type string, []byte, or FS with the contents of
+// files read from the package directory or subdirectories at compile time.
+//
+// For example, here are three ways to embed a file named hello.txt
+// and then print its contents at run time.
+//
+// Embedding one file into a string:
+//
+// import _ "embed"
+//
+// //go:embed hello.txt
+// var s string
+// print(s)
+//
+// Embedding one file into a slice of bytes:
+//
+// import _ "embed"
+//
+// //go:embed hello.txt
+// var b []byte
+// print(string(b))
+//
+// Embedded one or more files into a file system:
+//
+// import "embed"
+//
+// //go:embed hello.txt
+// var f embed.FS
+// data, _ := f.ReadFile("hello.txt")
+// print(string(data))
+//
+// # Directives
+//
+// A //go:embed directive above a variable declaration specifies which files to embed,
+// using one or more path.Match patterns.
+//
+// The directive must immediately precede a line containing the declaration of a single variable.
+// Only blank lines and ‘//’ line comments are permitted between the directive and the declaration.
+//
+// The type of the variable must be a string type, or a slice of a byte type,
+// or FS (or an alias of FS).
+//
+// For example:
+//
+// package server
+//
+// import "embed"
+//
+// // content holds our static web server content.
+// //go:embed image/* template/*
+// //go:embed html/index.html
+// var content embed.FS
+//
+// The Go build system will recognize the directives and arrange for the declared variable
+// (in the example above, content) to be populated with the matching files from the file system.
+//
+// The //go:embed directive accepts multiple space-separated patterns for
+// brevity, but it can also be repeated, to avoid very long lines when there are
+// many patterns. The patterns are interpreted relative to the package directory
+// containing the source file. The path separator is a forward slash, even on
+// Windows systems. Patterns may not contain ‘.’ or ‘..’ or empty path elements,
+// nor may they begin or end with a slash. To match everything in the current
+// directory, use ‘*’ instead of ‘.’. To allow for naming files with spaces in
+// their names, patterns can be written as Go double-quoted or back-quoted
+// string literals.
+//
+// If a pattern names a directory, all files in the subtree rooted at that directory are
+// embedded (recursively), except that files with names beginning with ‘.’ or ‘_’
+// are excluded. So the variable in the above example is almost equivalent to:
+//
+// // content is our static web server content.
+// //go:embed image template html/index.html
+// var content embed.FS
+//
+// The difference is that ‘image/*’ embeds ‘image/.tempfile’ while ‘image’ does not.
+// Neither embeds ‘image/dir/.tempfile’.
+//
+// If a pattern begins with the prefix ‘all:’, then the rule for walking directories is changed
+// to include those files beginning with ‘.’ or ‘_’. For example, ‘all:image’ embeds
+// both ‘image/.tempfile’ and ‘image/dir/.tempfile’.
+//
+// The //go:embed directive can be used with both exported and unexported variables,
+// depending on whether the package wants to make the data available to other packages.
+// It can only be used with variables at package scope, not with local variables.
+//
+// Patterns must not match files outside the package's module, such as ‘.git/*’ or symbolic links.
+// Patterns must not match files whose names include the special punctuation characters " * < > ? ` ' | / \ and :.
+// Matches for empty directories are ignored. After that, each pattern in a //go:embed line
+// must match at least one file or non-empty directory.
+//
+// If any patterns are invalid or have invalid matches, the build will fail.
+//
+// # Strings and Bytes
+//
+// The //go:embed line for a variable of type string or []byte can have only a single pattern,
+// and that pattern can match only a single file. The string or []byte is initialized with
+// the contents of that file.
+//
+// The //go:embed directive requires importing "embed", even when using a string or []byte.
+// In source files that don't refer to embed.FS, use a blank import (import _ "embed").
+//
+// # File Systems
+//
+// For embedding a single file, a variable of type string or []byte is often best.
+// The FS type enables embedding a tree of files, such as a directory of static
+// web server content, as in the example above.
+//
+// FS implements the io/fs package's FS interface, so it can be used with any package that
+// understands file systems, including net/http, text/template, and html/template.
+//
+// For example, given the content variable in the example above, we can write:
+//
+// http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(content))))
+//
+// template.ParseFS(content, "*.tmpl")
+//
+// # Tools
+//
+// To support tools that analyze Go packages, the patterns found in //go:embed lines
+// are available in “go list” output. See the EmbedPatterns, TestEmbedPatterns,
+// and XTestEmbedPatterns fields in the “go help list” output.
+package embed
+
+import (
+ "errors"
+ "io"
+ "io/fs"
+ "time"
+)
+
+// An FS is a read-only collection of files, usually initialized with a //go:embed directive.
+// When declared without a //go:embed directive, an FS is an empty file system.
+//
+// An FS is a read-only value, so it is safe to use from multiple goroutines
+// simultaneously and also safe to assign values of type FS to each other.
+//
+// FS implements fs.FS, so it can be used with any package that understands
+// file system interfaces, including net/http, text/template, and html/template.
+//
+// See the package documentation for more details about initializing an FS.
+type FS struct {
+ // The compiler knows the layout of this struct.
+ // See cmd/compile/internal/staticdata's WriteEmbed.
+ //
+ // The files list is sorted by name but not by simple string comparison.
+ // Instead, each file's name takes the form "dir/elem" or "dir/elem/".
+ // The optional trailing slash indicates that the file is itself a directory.
+ // The files list is sorted first by dir (if dir is missing, it is taken to be ".")
+ // and then by base, so this list of files:
+ //
+ // p
+ // q/
+ // q/r
+ // q/s/
+ // q/s/t
+ // q/s/u
+ // q/v
+ // w
+ //
+ // is actually sorted as:
+ //
+ // p # dir=. elem=p
+ // q/ # dir=. elem=q
+ // w/ # dir=. elem=w
+ // q/r # dir=q elem=r
+ // q/s/ # dir=q elem=s
+ // q/v # dir=q elem=v
+ // q/s/t # dir=q/s elem=t
+ // q/s/u # dir=q/s elem=u
+ //
+ // This order brings directory contents together in contiguous sections
+ // of the list, allowing a directory read to use binary search to find
+ // the relevant sequence of entries.
+ files *[]file
+}
+
+// split splits the name into dir and elem as described in the
+// comment in the FS struct above. isDir reports whether the
+// final trailing slash was present, indicating that name is a directory.
+func split(name string) (dir, elem string, isDir bool) {
+ if name[len(name)-1] == '/' {
+ isDir = true
+ name = name[:len(name)-1]
+ }
+ i := len(name) - 1
+ for i >= 0 && name[i] != '/' {
+ i--
+ }
+ if i < 0 {
+ return ".", name, isDir
+ }
+ return name[:i], name[i+1:], isDir
+}
+
+// trimSlash trims a trailing slash from name, if present,
+// returning the possibly shortened name.
+func trimSlash(name string) string {
+ if len(name) > 0 && name[len(name)-1] == '/' {
+ return name[:len(name)-1]
+ }
+ return name
+}
+
+var (
+ _ fs.ReadDirFS = FS{}
+ _ fs.ReadFileFS = FS{}
+)
+
+// A file is a single file in the FS.
+// It implements fs.FileInfo and fs.DirEntry.
+type file struct {
+ // The compiler knows the layout of this struct.
+ // See cmd/compile/internal/staticdata's WriteEmbed.
+ name string
+ data string
+ hash [16]byte // truncated SHA256 hash
+}
+
+var (
+ _ fs.FileInfo = (*file)(nil)
+ _ fs.DirEntry = (*file)(nil)
+)
+
+func (f *file) Name() string { _, elem, _ := split(f.name); return elem }
+func (f *file) Size() int64 { return int64(len(f.data)) }
+func (f *file) ModTime() time.Time { return time.Time{} }
+func (f *file) IsDir() bool { _, _, isDir := split(f.name); return isDir }
+func (f *file) Sys() any { return nil }
+func (f *file) Type() fs.FileMode { return f.Mode().Type() }
+func (f *file) Info() (fs.FileInfo, error) { return f, nil }
+
+func (f *file) Mode() fs.FileMode {
+ if f.IsDir() {
+ return fs.ModeDir | 0555
+ }
+ return 0444
+}
+
+func (f *file) String() string {
+ return fs.FormatFileInfo(f)
+}
+
+// dotFile is a file for the root directory,
+// which is omitted from the files list in a FS.
+var dotFile = &file{name: "./"}
+
+// lookup returns the named file, or nil if it is not present.
+func (f FS) lookup(name string) *file {
+ if !fs.ValidPath(name) {
+ // The compiler should never emit a file with an invalid name,
+ // so this check is not strictly necessary (if name is invalid,
+ // we shouldn't find a match below), but it's a good backstop anyway.
+ return nil
+ }
+ if name == "." {
+ return dotFile
+ }
+ if f.files == nil {
+ return nil
+ }
+
+ // Binary search to find where name would be in the list,
+ // and then check if name is at that position.
+ dir, elem, _ := split(name)
+ files := *f.files
+ i := sortSearch(len(files), func(i int) bool {
+ idir, ielem, _ := split(files[i].name)
+ return idir > dir || idir == dir && ielem >= elem
+ })
+ if i < len(files) && trimSlash(files[i].name) == name {
+ return &files[i]
+ }
+ return nil
+}
+
+// readDir returns the list of files corresponding to the directory dir.
+func (f FS) readDir(dir string) []file {
+ if f.files == nil {
+ return nil
+ }
+ // Binary search to find where dir starts and ends in the list
+ // and then return that slice of the list.
+ files := *f.files
+ i := sortSearch(len(files), func(i int) bool {
+ idir, _, _ := split(files[i].name)
+ return idir >= dir
+ })
+ j := sortSearch(len(files), func(j int) bool {
+ jdir, _, _ := split(files[j].name)
+ return jdir > dir
+ })
+ return files[i:j]
+}
+
+// Open opens the named file for reading and returns it as an fs.File.
+//
+// The returned file implements io.Seeker and io.ReaderAt when the file is not a directory.
+func (f FS) Open(name string) (fs.File, error) {
+ file := f.lookup(name)
+ if file == nil {
+ return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
+ }
+ if file.IsDir() {
+ return &openDir{file, f.readDir(name), 0}, nil
+ }
+ return &openFile{file, 0}, nil
+}
+
+// ReadDir reads and returns the entire named directory.
+func (f FS) ReadDir(name string) ([]fs.DirEntry, error) {
+ file, err := f.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ dir, ok := file.(*openDir)
+ if !ok {
+ return nil, &fs.PathError{Op: "read", Path: name, Err: errors.New("not a directory")}
+ }
+ list := make([]fs.DirEntry, len(dir.files))
+ for i := range list {
+ list[i] = &dir.files[i]
+ }
+ return list, nil
+}
+
+// ReadFile reads and returns the content of the named file.
+func (f FS) ReadFile(name string) ([]byte, error) {
+ file, err := f.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ ofile, ok := file.(*openFile)
+ if !ok {
+ return nil, &fs.PathError{Op: "read", Path: name, Err: errors.New("is a directory")}
+ }
+ return []byte(ofile.f.data), nil
+}
+
+// An openFile is a regular file open for reading.
+type openFile struct {
+ f *file // the file itself
+ offset int64 // current read offset
+}
+
+var (
+ _ io.Seeker = (*openFile)(nil)
+ _ io.ReaderAt = (*openFile)(nil)
+)
+
+func (f *openFile) Close() error { return nil }
+func (f *openFile) Stat() (fs.FileInfo, error) { return f.f, nil }
+
+func (f *openFile) Read(b []byte) (int, error) {
+ if f.offset >= int64(len(f.f.data)) {
+ return 0, io.EOF
+ }
+ if f.offset < 0 {
+ return 0, &fs.PathError{Op: "read", Path: f.f.name, Err: fs.ErrInvalid}
+ }
+ n := copy(b, f.f.data[f.offset:])
+ f.offset += int64(n)
+ return n, nil
+}
+
+func (f *openFile) Seek(offset int64, whence int) (int64, error) {
+ switch whence {
+ case 0:
+ // offset += 0
+ case 1:
+ offset += f.offset
+ case 2:
+ offset += int64(len(f.f.data))
+ }
+ if offset < 0 || offset > int64(len(f.f.data)) {
+ return 0, &fs.PathError{Op: "seek", Path: f.f.name, Err: fs.ErrInvalid}
+ }
+ f.offset = offset
+ return offset, nil
+}
+
+func (f *openFile) ReadAt(b []byte, offset int64) (int, error) {
+ if offset < 0 || offset > int64(len(f.f.data)) {
+ return 0, &fs.PathError{Op: "read", Path: f.f.name, Err: fs.ErrInvalid}
+ }
+ n := copy(b, f.f.data[offset:])
+ if n < len(b) {
+ return n, io.EOF
+ }
+ return n, nil
+}
+
+// An openDir is a directory open for reading.
+type openDir struct {
+ f *file // the directory file itself
+ files []file // the directory contents
+ offset int // the read offset, an index into the files slice
+}
+
+func (d *openDir) Close() error { return nil }
+func (d *openDir) Stat() (fs.FileInfo, error) { return d.f, nil }
+
+func (d *openDir) Read([]byte) (int, error) {
+ return 0, &fs.PathError{Op: "read", Path: d.f.name, Err: errors.New("is a directory")}
+}
+
+func (d *openDir) ReadDir(count int) ([]fs.DirEntry, error) {
+ n := len(d.files) - d.offset
+ if n == 0 {
+ if count <= 0 {
+ return nil, nil
+ }
+ return nil, io.EOF
+ }
+ if count > 0 && n > count {
+ n = count
+ }
+ list := make([]fs.DirEntry, n)
+ for i := range list {
+ list[i] = &d.files[d.offset+i]
+ }
+ d.offset += n
+ return list, nil
+}
+
+// sortSearch is like sort.Search, avoiding an import.
+func sortSearch(n int, f func(int) bool) int {
+ // Define f(-1) == false and f(n) == true.
+ // Invariant: f(i-1) == false, f(j) == true.
+ i, j := 0, n
+ for i < j {
+ h := int(uint(i+j) >> 1) // avoid overflow when computing h
+ // i ≤ h < j
+ if !f(h) {
+ i = h + 1 // preserves f(i-1) == false
+ } else {
+ j = h // preserves f(j) == true
+ }
+ }
+ // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i.
+ return i
+}
diff --git a/contrib/go/_std_1.21/src/embed/ya.make b/contrib/go/_std_1.21/src/embed/ya.make
new file mode 100644
index 0000000000..424cc3fb1f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/embed/ya.make
@@ -0,0 +1,15 @@
+GO_LIBRARY()
+
+SRCS(
+ embed.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+GO_XTEST_EMBED_PATTERN(internal/embedtest/testdata/*.txt)
+
+END()
+
+RECURSE(
+ # internal # tests don't work due to fail to embed hidden folders
+)
diff --git a/contrib/go/_std_1.20/src/encoding/ascii85/ascii85.go b/contrib/go/_std_1.21/src/encoding/ascii85/ascii85.go
index 1f1fb00ffa..1f1fb00ffa 100644
--- a/contrib/go/_std_1.20/src/encoding/ascii85/ascii85.go
+++ b/contrib/go/_std_1.21/src/encoding/ascii85/ascii85.go
diff --git a/contrib/go/_std_1.21/src/encoding/ascii85/ya.make b/contrib/go/_std_1.21/src/encoding/ascii85/ya.make
new file mode 100644
index 0000000000..d510e5e1d0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/ascii85/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ ascii85.go
+)
+
+GO_TEST_SRCS(ascii85_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/encoding/asn1/asn1.go b/contrib/go/_std_1.21/src/encoding/asn1/asn1.go
new file mode 100644
index 0000000000..e7bf793a82
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/asn1/asn1.go
@@ -0,0 +1,1125 @@
+// Copyright 2009 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 asn1 implements parsing of DER-encoded ASN.1 data structures,
+// as defined in ITU-T Rec X.690.
+//
+// See also “A Layman's Guide to a Subset of ASN.1, BER, and DER,”
+// http://luca.ntop.org/Teaching/Appunti/asn1.html.
+package asn1
+
+// ASN.1 is a syntax for specifying abstract objects and BER, DER, PER, XER etc
+// are different encoding formats for those objects. Here, we'll be dealing
+// with DER, the Distinguished Encoding Rules. DER is used in X.509 because
+// it's fast to parse and, unlike BER, has a unique encoding for every object.
+// When calculating hashes over objects, it's important that the resulting
+// bytes be the same at both ends and DER removes this margin of error.
+//
+// ASN.1 is very complex and this package doesn't attempt to implement
+// everything by any means.
+
+import (
+ "errors"
+ "fmt"
+ "math"
+ "math/big"
+ "reflect"
+ "strconv"
+ "strings"
+ "time"
+ "unicode/utf16"
+ "unicode/utf8"
+)
+
+// A StructuralError suggests that the ASN.1 data is valid, but the Go type
+// which is receiving it doesn't match.
+type StructuralError struct {
+ Msg string
+}
+
+func (e StructuralError) Error() string { return "asn1: structure error: " + e.Msg }
+
+// A SyntaxError suggests that the ASN.1 data is invalid.
+type SyntaxError struct {
+ Msg string
+}
+
+func (e SyntaxError) Error() string { return "asn1: syntax error: " + e.Msg }
+
+// We start by dealing with each of the primitive types in turn.
+
+// BOOLEAN
+
+func parseBool(bytes []byte) (ret bool, err error) {
+ if len(bytes) != 1 {
+ err = SyntaxError{"invalid boolean"}
+ return
+ }
+
+ // DER demands that "If the encoding represents the boolean value TRUE,
+ // its single contents octet shall have all eight bits set to one."
+ // Thus only 0 and 255 are valid encoded values.
+ switch bytes[0] {
+ case 0:
+ ret = false
+ case 0xff:
+ ret = true
+ default:
+ err = SyntaxError{"invalid boolean"}
+ }
+
+ return
+}
+
+// INTEGER
+
+// checkInteger returns nil if the given bytes are a valid DER-encoded
+// INTEGER and an error otherwise.
+func checkInteger(bytes []byte) error {
+ if len(bytes) == 0 {
+ return StructuralError{"empty integer"}
+ }
+ if len(bytes) == 1 {
+ return nil
+ }
+ if (bytes[0] == 0 && bytes[1]&0x80 == 0) || (bytes[0] == 0xff && bytes[1]&0x80 == 0x80) {
+ return StructuralError{"integer not minimally-encoded"}
+ }
+ return nil
+}
+
+// parseInt64 treats the given bytes as a big-endian, signed integer and
+// returns the result.
+func parseInt64(bytes []byte) (ret int64, err error) {
+ err = checkInteger(bytes)
+ if err != nil {
+ return
+ }
+ if len(bytes) > 8 {
+ // We'll overflow an int64 in this case.
+ err = StructuralError{"integer too large"}
+ return
+ }
+ for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
+ ret <<= 8
+ ret |= int64(bytes[bytesRead])
+ }
+
+ // Shift up and down in order to sign extend the result.
+ ret <<= 64 - uint8(len(bytes))*8
+ ret >>= 64 - uint8(len(bytes))*8
+ return
+}
+
+// parseInt32 treats the given bytes as a big-endian, signed integer and returns
+// the result.
+func parseInt32(bytes []byte) (int32, error) {
+ if err := checkInteger(bytes); err != nil {
+ return 0, err
+ }
+ ret64, err := parseInt64(bytes)
+ if err != nil {
+ return 0, err
+ }
+ if ret64 != int64(int32(ret64)) {
+ return 0, StructuralError{"integer too large"}
+ }
+ return int32(ret64), nil
+}
+
+var bigOne = big.NewInt(1)
+
+// parseBigInt treats the given bytes as a big-endian, signed integer and returns
+// the result.
+func parseBigInt(bytes []byte) (*big.Int, error) {
+ if err := checkInteger(bytes); err != nil {
+ return nil, err
+ }
+ ret := new(big.Int)
+ if len(bytes) > 0 && bytes[0]&0x80 == 0x80 {
+ // This is a negative number.
+ notBytes := make([]byte, len(bytes))
+ for i := range notBytes {
+ notBytes[i] = ^bytes[i]
+ }
+ ret.SetBytes(notBytes)
+ ret.Add(ret, bigOne)
+ ret.Neg(ret)
+ return ret, nil
+ }
+ ret.SetBytes(bytes)
+ return ret, nil
+}
+
+// BIT STRING
+
+// BitString is the structure to use when you want an ASN.1 BIT STRING type. A
+// bit string is padded up to the nearest byte in memory and the number of
+// valid bits is recorded. Padding bits will be zero.
+type BitString struct {
+ Bytes []byte // bits packed into bytes.
+ BitLength int // length in bits.
+}
+
+// At returns the bit at the given index. If the index is out of range it
+// returns 0.
+func (b BitString) At(i int) int {
+ if i < 0 || i >= b.BitLength {
+ return 0
+ }
+ x := i / 8
+ y := 7 - uint(i%8)
+ return int(b.Bytes[x]>>y) & 1
+}
+
+// RightAlign returns a slice where the padding bits are at the beginning. The
+// slice may share memory with the BitString.
+func (b BitString) RightAlign() []byte {
+ shift := uint(8 - (b.BitLength % 8))
+ if shift == 8 || len(b.Bytes) == 0 {
+ return b.Bytes
+ }
+
+ a := make([]byte, len(b.Bytes))
+ a[0] = b.Bytes[0] >> shift
+ for i := 1; i < len(b.Bytes); i++ {
+ a[i] = b.Bytes[i-1] << (8 - shift)
+ a[i] |= b.Bytes[i] >> shift
+ }
+
+ return a
+}
+
+// parseBitString parses an ASN.1 bit string from the given byte slice and returns it.
+func parseBitString(bytes []byte) (ret BitString, err error) {
+ if len(bytes) == 0 {
+ err = SyntaxError{"zero length BIT STRING"}
+ return
+ }
+ paddingBits := int(bytes[0])
+ if paddingBits > 7 ||
+ len(bytes) == 1 && paddingBits > 0 ||
+ bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {
+ err = SyntaxError{"invalid padding bits in BIT STRING"}
+ return
+ }
+ ret.BitLength = (len(bytes)-1)*8 - paddingBits
+ ret.Bytes = bytes[1:]
+ return
+}
+
+// NULL
+
+// NullRawValue is a RawValue with its Tag set to the ASN.1 NULL type tag (5).
+var NullRawValue = RawValue{Tag: TagNull}
+
+// NullBytes contains bytes representing the DER-encoded ASN.1 NULL type.
+var NullBytes = []byte{TagNull, 0}
+
+// OBJECT IDENTIFIER
+
+// An ObjectIdentifier represents an ASN.1 OBJECT IDENTIFIER.
+type ObjectIdentifier []int
+
+// Equal reports whether oi and other represent the same identifier.
+func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
+ if len(oi) != len(other) {
+ return false
+ }
+ for i := 0; i < len(oi); i++ {
+ if oi[i] != other[i] {
+ return false
+ }
+ }
+
+ return true
+}
+
+func (oi ObjectIdentifier) String() string {
+ var s strings.Builder
+ s.Grow(32)
+
+ buf := make([]byte, 0, 19)
+ for i, v := range oi {
+ if i > 0 {
+ s.WriteByte('.')
+ }
+ s.Write(strconv.AppendInt(buf, int64(v), 10))
+ }
+
+ return s.String()
+}
+
+// parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and
+// returns it. An object identifier is a sequence of variable length integers
+// that are assigned in a hierarchy.
+func parseObjectIdentifier(bytes []byte) (s ObjectIdentifier, err error) {
+ if len(bytes) == 0 {
+ err = SyntaxError{"zero length OBJECT IDENTIFIER"}
+ return
+ }
+
+ // In the worst case, we get two elements from the first byte (which is
+ // encoded differently) and then every varint is a single byte long.
+ s = make([]int, len(bytes)+1)
+
+ // The first varint is 40*value1 + value2:
+ // According to this packing, value1 can take the values 0, 1 and 2 only.
+ // When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2,
+ // then there are no restrictions on value2.
+ v, offset, err := parseBase128Int(bytes, 0)
+ if err != nil {
+ return
+ }
+ if v < 80 {
+ s[0] = v / 40
+ s[1] = v % 40
+ } else {
+ s[0] = 2
+ s[1] = v - 80
+ }
+
+ i := 2
+ for ; offset < len(bytes); i++ {
+ v, offset, err = parseBase128Int(bytes, offset)
+ if err != nil {
+ return
+ }
+ s[i] = v
+ }
+ s = s[0:i]
+ return
+}
+
+// ENUMERATED
+
+// An Enumerated is represented as a plain int.
+type Enumerated int
+
+// FLAG
+
+// A Flag accepts any data and is set to true if present.
+type Flag bool
+
+// parseBase128Int parses a base-128 encoded int from the given offset in the
+// given byte slice. It returns the value and the new offset.
+func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error) {
+ offset = initOffset
+ var ret64 int64
+ for shifted := 0; offset < len(bytes); shifted++ {
+ // 5 * 7 bits per byte == 35 bits of data
+ // Thus the representation is either non-minimal or too large for an int32
+ if shifted == 5 {
+ err = StructuralError{"base 128 integer too large"}
+ return
+ }
+ ret64 <<= 7
+ b := bytes[offset]
+ // integers should be minimally encoded, so the leading octet should
+ // never be 0x80
+ if shifted == 0 && b == 0x80 {
+ err = SyntaxError{"integer is not minimally encoded"}
+ return
+ }
+ ret64 |= int64(b & 0x7f)
+ offset++
+ if b&0x80 == 0 {
+ ret = int(ret64)
+ // Ensure that the returned value fits in an int on all platforms
+ if ret64 > math.MaxInt32 {
+ err = StructuralError{"base 128 integer too large"}
+ }
+ return
+ }
+ }
+ err = SyntaxError{"truncated base 128 integer"}
+ return
+}
+
+// UTCTime
+
+func parseUTCTime(bytes []byte) (ret time.Time, err error) {
+ s := string(bytes)
+
+ formatStr := "0601021504Z0700"
+ ret, err = time.Parse(formatStr, s)
+ if err != nil {
+ formatStr = "060102150405Z0700"
+ ret, err = time.Parse(formatStr, s)
+ }
+ if err != nil {
+ return
+ }
+
+ if serialized := ret.Format(formatStr); serialized != s {
+ err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
+ return
+ }
+
+ if ret.Year() >= 2050 {
+ // UTCTime only encodes times prior to 2050. See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+ ret = ret.AddDate(-100, 0, 0)
+ }
+
+ return
+}
+
+// parseGeneralizedTime parses the GeneralizedTime from the given byte slice
+// and returns the resulting time.
+func parseGeneralizedTime(bytes []byte) (ret time.Time, err error) {
+ const formatStr = "20060102150405.999999999Z0700"
+ s := string(bytes)
+
+ if ret, err = time.Parse(formatStr, s); err != nil {
+ return
+ }
+
+ if serialized := ret.Format(formatStr); serialized != s {
+ err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
+ }
+
+ return
+}
+
+// NumericString
+
+// parseNumericString parses an ASN.1 NumericString from the given byte array
+// and returns it.
+func parseNumericString(bytes []byte) (ret string, err error) {
+ for _, b := range bytes {
+ if !isNumeric(b) {
+ return "", SyntaxError{"NumericString contains invalid character"}
+ }
+ }
+ return string(bytes), nil
+}
+
+// isNumeric reports whether the given b is in the ASN.1 NumericString set.
+func isNumeric(b byte) bool {
+ return '0' <= b && b <= '9' ||
+ b == ' '
+}
+
+// PrintableString
+
+// parsePrintableString parses an ASN.1 PrintableString from the given byte
+// array and returns it.
+func parsePrintableString(bytes []byte) (ret string, err error) {
+ for _, b := range bytes {
+ if !isPrintable(b, allowAsterisk, allowAmpersand) {
+ err = SyntaxError{"PrintableString contains invalid character"}
+ return
+ }
+ }
+ ret = string(bytes)
+ return
+}
+
+type asteriskFlag bool
+type ampersandFlag bool
+
+const (
+ allowAsterisk asteriskFlag = true
+ rejectAsterisk asteriskFlag = false
+
+ allowAmpersand ampersandFlag = true
+ rejectAmpersand ampersandFlag = false
+)
+
+// isPrintable reports whether the given b is in the ASN.1 PrintableString set.
+// If asterisk is allowAsterisk then '*' is also allowed, reflecting existing
+// practice. If ampersand is allowAmpersand then '&' is allowed as well.
+func isPrintable(b byte, asterisk asteriskFlag, ampersand ampersandFlag) bool {
+ return 'a' <= b && b <= 'z' ||
+ 'A' <= b && b <= 'Z' ||
+ '0' <= b && b <= '9' ||
+ '\'' <= b && b <= ')' ||
+ '+' <= b && b <= '/' ||
+ b == ' ' ||
+ b == ':' ||
+ b == '=' ||
+ b == '?' ||
+ // This is technically not allowed in a PrintableString.
+ // However, x509 certificates with wildcard strings don't
+ // always use the correct string type so we permit it.
+ (bool(asterisk) && b == '*') ||
+ // This is not technically allowed either. However, not
+ // only is it relatively common, but there are also a
+ // handful of CA certificates that contain it. At least
+ // one of which will not expire until 2027.
+ (bool(ampersand) && b == '&')
+}
+
+// IA5String
+
+// parseIA5String parses an ASN.1 IA5String (ASCII string) from the given
+// byte slice and returns it.
+func parseIA5String(bytes []byte) (ret string, err error) {
+ for _, b := range bytes {
+ if b >= utf8.RuneSelf {
+ err = SyntaxError{"IA5String contains invalid character"}
+ return
+ }
+ }
+ ret = string(bytes)
+ return
+}
+
+// T61String
+
+// parseT61String parses an ASN.1 T61String (8-bit clean string) from the given
+// byte slice and returns it.
+func parseT61String(bytes []byte) (ret string, err error) {
+ return string(bytes), nil
+}
+
+// UTF8String
+
+// parseUTF8String parses an ASN.1 UTF8String (raw UTF-8) from the given byte
+// array and returns it.
+func parseUTF8String(bytes []byte) (ret string, err error) {
+ if !utf8.Valid(bytes) {
+ return "", errors.New("asn1: invalid UTF-8 string")
+ }
+ return string(bytes), nil
+}
+
+// BMPString
+
+// parseBMPString parses an ASN.1 BMPString (Basic Multilingual Plane of
+// ISO/IEC/ITU 10646-1) from the given byte slice and returns it.
+func parseBMPString(bmpString []byte) (string, error) {
+ if len(bmpString)%2 != 0 {
+ return "", errors.New("pkcs12: odd-length BMP string")
+ }
+
+ // Strip terminator if present.
+ if l := len(bmpString); l >= 2 && bmpString[l-1] == 0 && bmpString[l-2] == 0 {
+ bmpString = bmpString[:l-2]
+ }
+
+ s := make([]uint16, 0, len(bmpString)/2)
+ for len(bmpString) > 0 {
+ s = append(s, uint16(bmpString[0])<<8+uint16(bmpString[1]))
+ bmpString = bmpString[2:]
+ }
+
+ return string(utf16.Decode(s)), nil
+}
+
+// A RawValue represents an undecoded ASN.1 object.
+type RawValue struct {
+ Class, Tag int
+ IsCompound bool
+ Bytes []byte
+ FullBytes []byte // includes the tag and length
+}
+
+// RawContent is used to signal that the undecoded, DER data needs to be
+// preserved for a struct. To use it, the first field of the struct must have
+// this type. It's an error for any of the other fields to have this type.
+type RawContent []byte
+
+// Tagging
+
+// parseTagAndLength parses an ASN.1 tag and length pair from the given offset
+// into a byte slice. It returns the parsed data and the new offset. SET and
+// SET OF (tag 17) are mapped to SEQUENCE and SEQUENCE OF (tag 16) since we
+// don't distinguish between ordered and unordered objects in this code.
+func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err error) {
+ offset = initOffset
+ // parseTagAndLength should not be called without at least a single
+ // byte to read. Thus this check is for robustness:
+ if offset >= len(bytes) {
+ err = errors.New("asn1: internal error in parseTagAndLength")
+ return
+ }
+ b := bytes[offset]
+ offset++
+ ret.class = int(b >> 6)
+ ret.isCompound = b&0x20 == 0x20
+ ret.tag = int(b & 0x1f)
+
+ // If the bottom five bits are set, then the tag number is actually base 128
+ // encoded afterwards
+ if ret.tag == 0x1f {
+ ret.tag, offset, err = parseBase128Int(bytes, offset)
+ if err != nil {
+ return
+ }
+ // Tags should be encoded in minimal form.
+ if ret.tag < 0x1f {
+ err = SyntaxError{"non-minimal tag"}
+ return
+ }
+ }
+ if offset >= len(bytes) {
+ err = SyntaxError{"truncated tag or length"}
+ return
+ }
+ b = bytes[offset]
+ offset++
+ if b&0x80 == 0 {
+ // The length is encoded in the bottom 7 bits.
+ ret.length = int(b & 0x7f)
+ } else {
+ // Bottom 7 bits give the number of length bytes to follow.
+ numBytes := int(b & 0x7f)
+ if numBytes == 0 {
+ err = SyntaxError{"indefinite length found (not DER)"}
+ return
+ }
+ ret.length = 0
+ for i := 0; i < numBytes; i++ {
+ if offset >= len(bytes) {
+ err = SyntaxError{"truncated tag or length"}
+ return
+ }
+ b = bytes[offset]
+ offset++
+ if ret.length >= 1<<23 {
+ // We can't shift ret.length up without
+ // overflowing.
+ err = StructuralError{"length too large"}
+ return
+ }
+ ret.length <<= 8
+ ret.length |= int(b)
+ if ret.length == 0 {
+ // DER requires that lengths be minimal.
+ err = StructuralError{"superfluous leading zeros in length"}
+ return
+ }
+ }
+ // Short lengths must be encoded in short form.
+ if ret.length < 0x80 {
+ err = StructuralError{"non-minimal length"}
+ return
+ }
+ }
+
+ return
+}
+
+// parseSequenceOf is used for SEQUENCE OF and SET OF values. It tries to parse
+// a number of ASN.1 values from the given byte slice and returns them as a
+// slice of Go values of the given type.
+func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err error) {
+ matchAny, expectedTag, compoundType, ok := getUniversalType(elemType)
+ if !ok {
+ err = StructuralError{"unknown Go type for slice"}
+ return
+ }
+
+ // First we iterate over the input and count the number of elements,
+ // checking that the types are correct in each case.
+ numElements := 0
+ for offset := 0; offset < len(bytes); {
+ var t tagAndLength
+ t, offset, err = parseTagAndLength(bytes, offset)
+ if err != nil {
+ return
+ }
+ switch t.tag {
+ case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString, TagBMPString:
+ // We pretend that various other string types are
+ // PRINTABLE STRINGs so that a sequence of them can be
+ // parsed into a []string.
+ t.tag = TagPrintableString
+ case TagGeneralizedTime, TagUTCTime:
+ // Likewise, both time types are treated the same.
+ t.tag = TagUTCTime
+ }
+
+ if !matchAny && (t.class != ClassUniversal || t.isCompound != compoundType || t.tag != expectedTag) {
+ err = StructuralError{"sequence tag mismatch"}
+ return
+ }
+ if invalidLength(offset, t.length, len(bytes)) {
+ err = SyntaxError{"truncated sequence"}
+ return
+ }
+ offset += t.length
+ numElements++
+ }
+ ret = reflect.MakeSlice(sliceType, numElements, numElements)
+ params := fieldParameters{}
+ offset := 0
+ for i := 0; i < numElements; i++ {
+ offset, err = parseField(ret.Index(i), bytes, offset, params)
+ if err != nil {
+ return
+ }
+ }
+ return
+}
+
+var (
+ bitStringType = reflect.TypeOf(BitString{})
+ objectIdentifierType = reflect.TypeOf(ObjectIdentifier{})
+ enumeratedType = reflect.TypeOf(Enumerated(0))
+ flagType = reflect.TypeOf(Flag(false))
+ timeType = reflect.TypeOf(time.Time{})
+ rawValueType = reflect.TypeOf(RawValue{})
+ rawContentsType = reflect.TypeOf(RawContent(nil))
+ bigIntType = reflect.TypeOf((*big.Int)(nil))
+)
+
+// invalidLength reports whether offset + length > sliceLength, or if the
+// addition would overflow.
+func invalidLength(offset, length, sliceLength int) bool {
+ return offset+length < offset || offset+length > sliceLength
+}
+
+// parseField is the main parsing function. Given a byte slice and an offset
+// into the array, it will try to parse a suitable ASN.1 value out and store it
+// in the given Value.
+func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParameters) (offset int, err error) {
+ offset = initOffset
+ fieldType := v.Type()
+
+ // If we have run out of data, it may be that there are optional elements at the end.
+ if offset == len(bytes) {
+ if !setDefaultValue(v, params) {
+ err = SyntaxError{"sequence truncated"}
+ }
+ return
+ }
+
+ // Deal with the ANY type.
+ if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 {
+ var t tagAndLength
+ t, offset, err = parseTagAndLength(bytes, offset)
+ if err != nil {
+ return
+ }
+ if invalidLength(offset, t.length, len(bytes)) {
+ err = SyntaxError{"data truncated"}
+ return
+ }
+ var result any
+ if !t.isCompound && t.class == ClassUniversal {
+ innerBytes := bytes[offset : offset+t.length]
+ switch t.tag {
+ case TagPrintableString:
+ result, err = parsePrintableString(innerBytes)
+ case TagNumericString:
+ result, err = parseNumericString(innerBytes)
+ case TagIA5String:
+ result, err = parseIA5String(innerBytes)
+ case TagT61String:
+ result, err = parseT61String(innerBytes)
+ case TagUTF8String:
+ result, err = parseUTF8String(innerBytes)
+ case TagInteger:
+ result, err = parseInt64(innerBytes)
+ case TagBitString:
+ result, err = parseBitString(innerBytes)
+ case TagOID:
+ result, err = parseObjectIdentifier(innerBytes)
+ case TagUTCTime:
+ result, err = parseUTCTime(innerBytes)
+ case TagGeneralizedTime:
+ result, err = parseGeneralizedTime(innerBytes)
+ case TagOctetString:
+ result = innerBytes
+ case TagBMPString:
+ result, err = parseBMPString(innerBytes)
+ default:
+ // If we don't know how to handle the type, we just leave Value as nil.
+ }
+ }
+ offset += t.length
+ if err != nil {
+ return
+ }
+ if result != nil {
+ v.Set(reflect.ValueOf(result))
+ }
+ return
+ }
+
+ t, offset, err := parseTagAndLength(bytes, offset)
+ if err != nil {
+ return
+ }
+ if params.explicit {
+ expectedClass := ClassContextSpecific
+ if params.application {
+ expectedClass = ClassApplication
+ }
+ if offset == len(bytes) {
+ err = StructuralError{"explicit tag has no child"}
+ return
+ }
+ if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
+ if fieldType == rawValueType {
+ // The inner element should not be parsed for RawValues.
+ } else if t.length > 0 {
+ t, offset, err = parseTagAndLength(bytes, offset)
+ if err != nil {
+ return
+ }
+ } else {
+ if fieldType != flagType {
+ err = StructuralError{"zero length explicit tag was not an asn1.Flag"}
+ return
+ }
+ v.SetBool(true)
+ return
+ }
+ } else {
+ // The tags didn't match, it might be an optional element.
+ ok := setDefaultValue(v, params)
+ if ok {
+ offset = initOffset
+ } else {
+ err = StructuralError{"explicitly tagged member didn't match"}
+ }
+ return
+ }
+ }
+
+ matchAny, universalTag, compoundType, ok1 := getUniversalType(fieldType)
+ if !ok1 {
+ err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)}
+ return
+ }
+
+ // Special case for strings: all the ASN.1 string types map to the Go
+ // type string. getUniversalType returns the tag for PrintableString
+ // when it sees a string, so if we see a different string type on the
+ // wire, we change the universal type to match.
+ if universalTag == TagPrintableString {
+ if t.class == ClassUniversal {
+ switch t.tag {
+ case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString, TagBMPString:
+ universalTag = t.tag
+ }
+ } else if params.stringType != 0 {
+ universalTag = params.stringType
+ }
+ }
+
+ // Special case for time: UTCTime and GeneralizedTime both map to the
+ // Go type time.Time.
+ if universalTag == TagUTCTime && t.tag == TagGeneralizedTime && t.class == ClassUniversal {
+ universalTag = TagGeneralizedTime
+ }
+
+ if params.set {
+ universalTag = TagSet
+ }
+
+ matchAnyClassAndTag := matchAny
+ expectedClass := ClassUniversal
+ expectedTag := universalTag
+
+ if !params.explicit && params.tag != nil {
+ expectedClass = ClassContextSpecific
+ expectedTag = *params.tag
+ matchAnyClassAndTag = false
+ }
+
+ if !params.explicit && params.application && params.tag != nil {
+ expectedClass = ClassApplication
+ expectedTag = *params.tag
+ matchAnyClassAndTag = false
+ }
+
+ if !params.explicit && params.private && params.tag != nil {
+ expectedClass = ClassPrivate
+ expectedTag = *params.tag
+ matchAnyClassAndTag = false
+ }
+
+ // We have unwrapped any explicit tagging at this point.
+ if !matchAnyClassAndTag && (t.class != expectedClass || t.tag != expectedTag) ||
+ (!matchAny && t.isCompound != compoundType) {
+ // Tags don't match. Again, it could be an optional element.
+ ok := setDefaultValue(v, params)
+ if ok {
+ offset = initOffset
+ } else {
+ err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)}
+ }
+ return
+ }
+ if invalidLength(offset, t.length, len(bytes)) {
+ err = SyntaxError{"data truncated"}
+ return
+ }
+ innerBytes := bytes[offset : offset+t.length]
+ offset += t.length
+
+ // We deal with the structures defined in this package first.
+ switch v := v.Addr().Interface().(type) {
+ case *RawValue:
+ *v = RawValue{t.class, t.tag, t.isCompound, innerBytes, bytes[initOffset:offset]}
+ return
+ case *ObjectIdentifier:
+ *v, err = parseObjectIdentifier(innerBytes)
+ return
+ case *BitString:
+ *v, err = parseBitString(innerBytes)
+ return
+ case *time.Time:
+ if universalTag == TagUTCTime {
+ *v, err = parseUTCTime(innerBytes)
+ return
+ }
+ *v, err = parseGeneralizedTime(innerBytes)
+ return
+ case *Enumerated:
+ parsedInt, err1 := parseInt32(innerBytes)
+ if err1 == nil {
+ *v = Enumerated(parsedInt)
+ }
+ err = err1
+ return
+ case *Flag:
+ *v = true
+ return
+ case **big.Int:
+ parsedInt, err1 := parseBigInt(innerBytes)
+ if err1 == nil {
+ *v = parsedInt
+ }
+ err = err1
+ return
+ }
+ switch val := v; val.Kind() {
+ case reflect.Bool:
+ parsedBool, err1 := parseBool(innerBytes)
+ if err1 == nil {
+ val.SetBool(parsedBool)
+ }
+ err = err1
+ return
+ case reflect.Int, reflect.Int32, reflect.Int64:
+ if val.Type().Size() == 4 {
+ parsedInt, err1 := parseInt32(innerBytes)
+ if err1 == nil {
+ val.SetInt(int64(parsedInt))
+ }
+ err = err1
+ } else {
+ parsedInt, err1 := parseInt64(innerBytes)
+ if err1 == nil {
+ val.SetInt(parsedInt)
+ }
+ err = err1
+ }
+ return
+ // TODO(dfc) Add support for the remaining integer types
+ case reflect.Struct:
+ structType := fieldType
+
+ for i := 0; i < structType.NumField(); i++ {
+ if !structType.Field(i).IsExported() {
+ err = StructuralError{"struct contains unexported fields"}
+ return
+ }
+ }
+
+ if structType.NumField() > 0 &&
+ structType.Field(0).Type == rawContentsType {
+ bytes := bytes[initOffset:offset]
+ val.Field(0).Set(reflect.ValueOf(RawContent(bytes)))
+ }
+
+ innerOffset := 0
+ for i := 0; i < structType.NumField(); i++ {
+ field := structType.Field(i)
+ if i == 0 && field.Type == rawContentsType {
+ continue
+ }
+ innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag.Get("asn1")))
+ if err != nil {
+ return
+ }
+ }
+ // We allow extra bytes at the end of the SEQUENCE because
+ // adding elements to the end has been used in X.509 as the
+ // version numbers have increased.
+ return
+ case reflect.Slice:
+ sliceType := fieldType
+ if sliceType.Elem().Kind() == reflect.Uint8 {
+ val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes)))
+ reflect.Copy(val, reflect.ValueOf(innerBytes))
+ return
+ }
+ newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem())
+ if err1 == nil {
+ val.Set(newSlice)
+ }
+ err = err1
+ return
+ case reflect.String:
+ var v string
+ switch universalTag {
+ case TagPrintableString:
+ v, err = parsePrintableString(innerBytes)
+ case TagNumericString:
+ v, err = parseNumericString(innerBytes)
+ case TagIA5String:
+ v, err = parseIA5String(innerBytes)
+ case TagT61String:
+ v, err = parseT61String(innerBytes)
+ case TagUTF8String:
+ v, err = parseUTF8String(innerBytes)
+ case TagGeneralString:
+ // GeneralString is specified in ISO-2022/ECMA-35,
+ // A brief review suggests that it includes structures
+ // that allow the encoding to change midstring and
+ // such. We give up and pass it as an 8-bit string.
+ v, err = parseT61String(innerBytes)
+ case TagBMPString:
+ v, err = parseBMPString(innerBytes)
+
+ default:
+ err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)}
+ }
+ if err == nil {
+ val.SetString(v)
+ }
+ return
+ }
+ err = StructuralError{"unsupported: " + v.Type().String()}
+ return
+}
+
+// canHaveDefaultValue reports whether k is a Kind that we will set a default
+// value for. (A signed integer, essentially.)
+func canHaveDefaultValue(k reflect.Kind) bool {
+ switch k {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return true
+ }
+
+ return false
+}
+
+// setDefaultValue is used to install a default value, from a tag string, into
+// a Value. It is successful if the field was optional, even if a default value
+// wasn't provided or it failed to install it into the Value.
+func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
+ if !params.optional {
+ return
+ }
+ ok = true
+ if params.defaultValue == nil {
+ return
+ }
+ if canHaveDefaultValue(v.Kind()) {
+ v.SetInt(*params.defaultValue)
+ }
+ return
+}
+
+// Unmarshal parses the DER-encoded ASN.1 data structure b
+// and uses the reflect package to fill in an arbitrary value pointed at by val.
+// Because Unmarshal uses the reflect package, the structs
+// being written to must use upper case field names. If val
+// is nil or not a pointer, Unmarshal returns an error.
+//
+// After parsing b, any bytes that were leftover and not used to fill
+// val will be returned in rest. When parsing a SEQUENCE into a struct,
+// any trailing elements of the SEQUENCE that do not have matching
+// fields in val will not be included in rest, as these are considered
+// valid elements of the SEQUENCE and not trailing data.
+//
+// An ASN.1 INTEGER can be written to an int, int32, int64,
+// or *big.Int (from the math/big package).
+// If the encoded value does not fit in the Go type,
+// Unmarshal returns a parse error.
+//
+// An ASN.1 BIT STRING can be written to a BitString.
+//
+// An ASN.1 OCTET STRING can be written to a []byte.
+//
+// An ASN.1 OBJECT IDENTIFIER can be written to an
+// ObjectIdentifier.
+//
+// An ASN.1 ENUMERATED can be written to an Enumerated.
+//
+// An ASN.1 UTCTIME or GENERALIZEDTIME can be written to a time.Time.
+//
+// An ASN.1 PrintableString, IA5String, or NumericString can be written to a string.
+//
+// Any of the above ASN.1 values can be written to an interface{}.
+// The value stored in the interface has the corresponding Go type.
+// For integers, that type is int64.
+//
+// An ASN.1 SEQUENCE OF x or SET OF x can be written
+// to a slice if an x can be written to the slice's element type.
+//
+// An ASN.1 SEQUENCE or SET can be written to a struct
+// if each of the elements in the sequence can be
+// written to the corresponding element in the struct.
+//
+// The following tags on struct fields have special meaning to Unmarshal:
+//
+// application specifies that an APPLICATION tag is used
+// private specifies that a PRIVATE tag is used
+// default:x sets the default value for optional integer fields (only used if optional is also present)
+// explicit specifies that an additional, explicit tag wraps the implicit one
+// optional marks the field as ASN.1 OPTIONAL
+// set causes a SET, rather than a SEQUENCE type to be expected
+// tag:x specifies the ASN.1 tag number; implies ASN.1 CONTEXT SPECIFIC
+//
+// When decoding an ASN.1 value with an IMPLICIT tag into a string field,
+// Unmarshal will default to a PrintableString, which doesn't support
+// characters such as '@' and '&'. To force other encodings, use the following
+// tags:
+//
+// ia5 causes strings to be unmarshaled as ASN.1 IA5String values
+// numeric causes strings to be unmarshaled as ASN.1 NumericString values
+// utf8 causes strings to be unmarshaled as ASN.1 UTF8String values
+//
+// If the type of the first field of a structure is RawContent then the raw
+// ASN1 contents of the struct will be stored in it.
+//
+// If the name of a slice type ends with "SET" then it's treated as if
+// the "set" tag was set on it. This results in interpreting the type as a
+// SET OF x rather than a SEQUENCE OF x. This can be used with nested slices
+// where a struct tag cannot be given.
+//
+// Other ASN.1 types are not supported; if it encounters them,
+// Unmarshal returns a parse error.
+func Unmarshal(b []byte, val any) (rest []byte, err error) {
+ return UnmarshalWithParams(b, val, "")
+}
+
+// An invalidUnmarshalError describes an invalid argument passed to Unmarshal.
+// (The argument to Unmarshal must be a non-nil pointer.)
+type invalidUnmarshalError struct {
+ Type reflect.Type
+}
+
+func (e *invalidUnmarshalError) Error() string {
+ if e.Type == nil {
+ return "asn1: Unmarshal recipient value is nil"
+ }
+
+ if e.Type.Kind() != reflect.Pointer {
+ return "asn1: Unmarshal recipient value is non-pointer " + e.Type.String()
+ }
+ return "asn1: Unmarshal recipient value is nil " + e.Type.String()
+}
+
+// UnmarshalWithParams allows field parameters to be specified for the
+// top-level element. The form of the params is the same as the field tags.
+func UnmarshalWithParams(b []byte, val any, params string) (rest []byte, err error) {
+ v := reflect.ValueOf(val)
+ if v.Kind() != reflect.Pointer || v.IsNil() {
+ return nil, &invalidUnmarshalError{reflect.TypeOf(val)}
+ }
+ offset, err := parseField(v.Elem(), b, 0, parseFieldParameters(params))
+ if err != nil {
+ return nil, err
+ }
+ return b[offset:], nil
+}
diff --git a/contrib/go/_std_1.20/src/encoding/asn1/common.go b/contrib/go/_std_1.21/src/encoding/asn1/common.go
index 40115df8b4..40115df8b4 100644
--- a/contrib/go/_std_1.20/src/encoding/asn1/common.go
+++ b/contrib/go/_std_1.21/src/encoding/asn1/common.go
diff --git a/contrib/go/_std_1.20/src/encoding/asn1/marshal.go b/contrib/go/_std_1.21/src/encoding/asn1/marshal.go
index c243349175..c243349175 100644
--- a/contrib/go/_std_1.20/src/encoding/asn1/marshal.go
+++ b/contrib/go/_std_1.21/src/encoding/asn1/marshal.go
diff --git a/contrib/go/_std_1.21/src/encoding/asn1/ya.make b/contrib/go/_std_1.21/src/encoding/asn1/ya.make
new file mode 100644
index 0000000000..6563cfb2bf
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/asn1/ya.make
@@ -0,0 +1,17 @@
+GO_LIBRARY()
+
+SRCS(
+ asn1.go
+ common.go
+ marshal.go
+)
+
+GO_TEST_SRCS(
+ asn1_test.go
+ marshal_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/encoding/base32/base32.go b/contrib/go/_std_1.21/src/encoding/base32/base32.go
new file mode 100644
index 0000000000..3dc37b0aa7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/base32/base32.go
@@ -0,0 +1,552 @@
+// Copyright 2011 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 base32 implements base32 encoding as specified by RFC 4648.
+package base32
+
+import (
+ "io"
+ "strconv"
+)
+
+/*
+ * Encodings
+ */
+
+// An Encoding is a radix 32 encoding/decoding scheme, defined by a
+// 32-character alphabet. The most common is the "base32" encoding
+// introduced for SASL GSSAPI and standardized in RFC 4648.
+// The alternate "base32hex" encoding is used in DNSSEC.
+type Encoding struct {
+ encode [32]byte
+ decodeMap [256]byte
+ padChar rune
+}
+
+const (
+ StdPadding rune = '=' // Standard padding character
+ NoPadding rune = -1 // No padding
+ decodeMapInitialize = "" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+)
+
+const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
+const encodeHex = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
+
+// NewEncoding returns a new Encoding defined by the given alphabet,
+// which must be a 32-byte string. The alphabet is treated as sequence
+// of byte values without any special treatment for multi-byte UTF-8.
+func NewEncoding(encoder string) *Encoding {
+ if len(encoder) != 32 {
+ panic("encoding alphabet is not 32-bytes long")
+ }
+
+ e := new(Encoding)
+ e.padChar = StdPadding
+ copy(e.encode[:], encoder)
+ copy(e.decodeMap[:], decodeMapInitialize)
+
+ for i := 0; i < len(encoder); i++ {
+ e.decodeMap[encoder[i]] = byte(i)
+ }
+ return e
+}
+
+// StdEncoding is the standard base32 encoding, as defined in
+// RFC 4648.
+var StdEncoding = NewEncoding(encodeStd)
+
+// HexEncoding is the “Extended Hex Alphabet” defined in RFC 4648.
+// It is typically used in DNS.
+var HexEncoding = NewEncoding(encodeHex)
+
+// WithPadding creates a new encoding identical to enc except
+// with a specified padding character, or NoPadding to disable padding.
+// The padding character must not be '\r' or '\n', must not
+// be contained in the encoding's alphabet and must be a rune equal or
+// below '\xff'.
+// Padding characters above '\x7f' are encoded as their exact byte value
+// rather than using the UTF-8 representation of the codepoint.
+func (enc Encoding) WithPadding(padding rune) *Encoding {
+ if padding == '\r' || padding == '\n' || padding > 0xff {
+ panic("invalid padding")
+ }
+
+ for i := 0; i < len(enc.encode); i++ {
+ if rune(enc.encode[i]) == padding {
+ panic("padding contained in alphabet")
+ }
+ }
+
+ enc.padChar = padding
+ return &enc
+}
+
+/*
+ * Encoder
+ */
+
+// Encode encodes src using the encoding enc, writing
+// EncodedLen(len(src)) bytes to dst.
+//
+// The encoding pads the output to a multiple of 8 bytes,
+// so Encode is not appropriate for use on individual blocks
+// of a large data stream. Use NewEncoder() instead.
+func (enc *Encoding) Encode(dst, src []byte) {
+ for len(src) > 0 {
+ var b [8]byte
+
+ // Unpack 8x 5-bit source blocks into a 5 byte
+ // destination quantum
+ switch len(src) {
+ default:
+ b[7] = src[4] & 0x1F
+ b[6] = src[4] >> 5
+ fallthrough
+ case 4:
+ b[6] |= (src[3] << 3) & 0x1F
+ b[5] = (src[3] >> 2) & 0x1F
+ b[4] = src[3] >> 7
+ fallthrough
+ case 3:
+ b[4] |= (src[2] << 1) & 0x1F
+ b[3] = (src[2] >> 4) & 0x1F
+ fallthrough
+ case 2:
+ b[3] |= (src[1] << 4) & 0x1F
+ b[2] = (src[1] >> 1) & 0x1F
+ b[1] = (src[1] >> 6) & 0x1F
+ fallthrough
+ case 1:
+ b[1] |= (src[0] << 2) & 0x1F
+ b[0] = src[0] >> 3
+ }
+
+ // Encode 5-bit blocks using the base32 alphabet
+ size := len(dst)
+ if size >= 8 {
+ // Common case, unrolled for extra performance
+ dst[0] = enc.encode[b[0]&31]
+ dst[1] = enc.encode[b[1]&31]
+ dst[2] = enc.encode[b[2]&31]
+ dst[3] = enc.encode[b[3]&31]
+ dst[4] = enc.encode[b[4]&31]
+ dst[5] = enc.encode[b[5]&31]
+ dst[6] = enc.encode[b[6]&31]
+ dst[7] = enc.encode[b[7]&31]
+ } else {
+ for i := 0; i < size; i++ {
+ dst[i] = enc.encode[b[i]&31]
+ }
+ }
+
+ // Pad the final quantum
+ if len(src) < 5 {
+ if enc.padChar == NoPadding {
+ break
+ }
+
+ dst[7] = byte(enc.padChar)
+ if len(src) < 4 {
+ dst[6] = byte(enc.padChar)
+ dst[5] = byte(enc.padChar)
+ if len(src) < 3 {
+ dst[4] = byte(enc.padChar)
+ if len(src) < 2 {
+ dst[3] = byte(enc.padChar)
+ dst[2] = byte(enc.padChar)
+ }
+ }
+ }
+
+ break
+ }
+
+ src = src[5:]
+ dst = dst[8:]
+ }
+}
+
+// EncodeToString returns the base32 encoding of src.
+func (enc *Encoding) EncodeToString(src []byte) string {
+ buf := make([]byte, enc.EncodedLen(len(src)))
+ enc.Encode(buf, src)
+ return string(buf)
+}
+
+type encoder struct {
+ err error
+ enc *Encoding
+ w io.Writer
+ buf [5]byte // buffered data waiting to be encoded
+ nbuf int // number of bytes in buf
+ out [1024]byte // output buffer
+}
+
+func (e *encoder) Write(p []byte) (n int, err error) {
+ if e.err != nil {
+ return 0, e.err
+ }
+
+ // Leading fringe.
+ if e.nbuf > 0 {
+ var i int
+ for i = 0; i < len(p) && e.nbuf < 5; i++ {
+ e.buf[e.nbuf] = p[i]
+ e.nbuf++
+ }
+ n += i
+ p = p[i:]
+ if e.nbuf < 5 {
+ return
+ }
+ e.enc.Encode(e.out[0:], e.buf[0:])
+ if _, e.err = e.w.Write(e.out[0:8]); e.err != nil {
+ return n, e.err
+ }
+ e.nbuf = 0
+ }
+
+ // Large interior chunks.
+ for len(p) >= 5 {
+ nn := len(e.out) / 8 * 5
+ if nn > len(p) {
+ nn = len(p)
+ nn -= nn % 5
+ }
+ e.enc.Encode(e.out[0:], p[0:nn])
+ if _, e.err = e.w.Write(e.out[0 : nn/5*8]); e.err != nil {
+ return n, e.err
+ }
+ n += nn
+ p = p[nn:]
+ }
+
+ // Trailing fringe.
+ copy(e.buf[:], p)
+ e.nbuf = len(p)
+ n += len(p)
+ return
+}
+
+// Close flushes any pending output from the encoder.
+// It is an error to call Write after calling Close.
+func (e *encoder) Close() error {
+ // If there's anything left in the buffer, flush it out
+ if e.err == nil && e.nbuf > 0 {
+ e.enc.Encode(e.out[0:], e.buf[0:e.nbuf])
+ encodedLen := e.enc.EncodedLen(e.nbuf)
+ e.nbuf = 0
+ _, e.err = e.w.Write(e.out[0:encodedLen])
+ }
+ return e.err
+}
+
+// NewEncoder returns a new base32 stream encoder. Data written to
+// the returned writer will be encoded using enc and then written to w.
+// Base32 encodings operate in 5-byte blocks; when finished
+// writing, the caller must Close the returned encoder to flush any
+// partially written blocks.
+func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
+ return &encoder{enc: enc, w: w}
+}
+
+// EncodedLen returns the length in bytes of the base32 encoding
+// of an input buffer of length n.
+func (enc *Encoding) EncodedLen(n int) int {
+ if enc.padChar == NoPadding {
+ return (n*8 + 4) / 5
+ }
+ return (n + 4) / 5 * 8
+}
+
+/*
+ * Decoder
+ */
+
+type CorruptInputError int64
+
+func (e CorruptInputError) Error() string {
+ return "illegal base32 data at input byte " + strconv.FormatInt(int64(e), 10)
+}
+
+// decode is like Decode but returns an additional 'end' value, which
+// indicates if end-of-message padding was encountered and thus any
+// additional data is an error. This method assumes that src has been
+// stripped of all supported whitespace ('\r' and '\n').
+func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
+ // Lift the nil check outside of the loop.
+ _ = enc.decodeMap
+
+ dsti := 0
+ olen := len(src)
+
+ for len(src) > 0 && !end {
+ // Decode quantum using the base32 alphabet
+ var dbuf [8]byte
+ dlen := 8
+
+ for j := 0; j < 8; {
+
+ if len(src) == 0 {
+ if enc.padChar != NoPadding {
+ // We have reached the end and are missing padding
+ return n, false, CorruptInputError(olen - len(src) - j)
+ }
+ // We have reached the end and are not expecting any padding
+ dlen, end = j, true
+ break
+ }
+ in := src[0]
+ src = src[1:]
+ if in == byte(enc.padChar) && j >= 2 && len(src) < 8 {
+ // We've reached the end and there's padding
+ if len(src)+j < 8-1 {
+ // not enough padding
+ return n, false, CorruptInputError(olen)
+ }
+ for k := 0; k < 8-1-j; k++ {
+ if len(src) > k && src[k] != byte(enc.padChar) {
+ // incorrect padding
+ return n, false, CorruptInputError(olen - len(src) + k - 1)
+ }
+ }
+ dlen, end = j, true
+ // 7, 5 and 2 are not valid padding lengths, and so 1, 3 and 6 are not
+ // valid dlen values. See RFC 4648 Section 6 "Base 32 Encoding" listing
+ // the five valid padding lengths, and Section 9 "Illustrations and
+ // Examples" for an illustration for how the 1st, 3rd and 6th base32
+ // src bytes do not yield enough information to decode a dst byte.
+ if dlen == 1 || dlen == 3 || dlen == 6 {
+ return n, false, CorruptInputError(olen - len(src) - 1)
+ }
+ break
+ }
+ dbuf[j] = enc.decodeMap[in]
+ if dbuf[j] == 0xFF {
+ return n, false, CorruptInputError(olen - len(src) - 1)
+ }
+ j++
+ }
+
+ // Pack 8x 5-bit source blocks into 5 byte destination
+ // quantum
+ switch dlen {
+ case 8:
+ dst[dsti+4] = dbuf[6]<<5 | dbuf[7]
+ n++
+ fallthrough
+ case 7:
+ dst[dsti+3] = dbuf[4]<<7 | dbuf[5]<<2 | dbuf[6]>>3
+ n++
+ fallthrough
+ case 5:
+ dst[dsti+2] = dbuf[3]<<4 | dbuf[4]>>1
+ n++
+ fallthrough
+ case 4:
+ dst[dsti+1] = dbuf[1]<<6 | dbuf[2]<<1 | dbuf[3]>>4
+ n++
+ fallthrough
+ case 2:
+ dst[dsti+0] = dbuf[0]<<3 | dbuf[1]>>2
+ n++
+ }
+ dsti += 5
+ }
+ return n, end, nil
+}
+
+// Decode decodes src using the encoding enc. It writes at most
+// DecodedLen(len(src)) bytes to dst and returns the number of bytes
+// written. If src contains invalid base32 data, it will return the
+// number of bytes successfully written and CorruptInputError.
+// New line characters (\r and \n) are ignored.
+func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
+ buf := make([]byte, len(src))
+ l := stripNewlines(buf, src)
+ n, _, err = enc.decode(dst, buf[:l])
+ return
+}
+
+// DecodeString returns the bytes represented by the base32 string s.
+func (enc *Encoding) DecodeString(s string) ([]byte, error) {
+ buf := []byte(s)
+ l := stripNewlines(buf, buf)
+ n, _, err := enc.decode(buf, buf[:l])
+ return buf[:n], err
+}
+
+type decoder struct {
+ err error
+ enc *Encoding
+ r io.Reader
+ end bool // saw end of message
+ buf [1024]byte // leftover input
+ nbuf int
+ out []byte // leftover decoded output
+ outbuf [1024 / 8 * 5]byte
+}
+
+func readEncodedData(r io.Reader, buf []byte, min int, expectsPadding bool) (n int, err error) {
+ for n < min && err == nil {
+ var nn int
+ nn, err = r.Read(buf[n:])
+ n += nn
+ }
+ // data was read, less than min bytes could be read
+ if n < min && n > 0 && err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ // no data was read, the buffer already contains some data
+ // when padding is disabled this is not an error, as the message can be of
+ // any length
+ if expectsPadding && min < 8 && n == 0 && err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return
+}
+
+func (d *decoder) Read(p []byte) (n int, err error) {
+ // Use leftover decoded output from last read.
+ if len(d.out) > 0 {
+ n = copy(p, d.out)
+ d.out = d.out[n:]
+ if len(d.out) == 0 {
+ return n, d.err
+ }
+ return n, nil
+ }
+
+ if d.err != nil {
+ return 0, d.err
+ }
+
+ // Read a chunk.
+ nn := len(p) / 5 * 8
+ if nn < 8 {
+ nn = 8
+ }
+ if nn > len(d.buf) {
+ nn = len(d.buf)
+ }
+
+ // Minimum amount of bytes that needs to be read each cycle
+ var min int
+ var expectsPadding bool
+ if d.enc.padChar == NoPadding {
+ min = 1
+ expectsPadding = false
+ } else {
+ min = 8 - d.nbuf
+ expectsPadding = true
+ }
+
+ nn, d.err = readEncodedData(d.r, d.buf[d.nbuf:nn], min, expectsPadding)
+ d.nbuf += nn
+ if d.nbuf < min {
+ return 0, d.err
+ }
+ if nn > 0 && d.end {
+ return 0, CorruptInputError(0)
+ }
+
+ // Decode chunk into p, or d.out and then p if p is too small.
+ var nr int
+ if d.enc.padChar == NoPadding {
+ nr = d.nbuf
+ } else {
+ nr = d.nbuf / 8 * 8
+ }
+ nw := d.enc.DecodedLen(d.nbuf)
+
+ if nw > len(p) {
+ nw, d.end, err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
+ d.out = d.outbuf[0:nw]
+ n = copy(p, d.out)
+ d.out = d.out[n:]
+ } else {
+ n, d.end, err = d.enc.decode(p, d.buf[0:nr])
+ }
+ d.nbuf -= nr
+ for i := 0; i < d.nbuf; i++ {
+ d.buf[i] = d.buf[i+nr]
+ }
+
+ if err != nil && (d.err == nil || d.err == io.EOF) {
+ d.err = err
+ }
+
+ if len(d.out) > 0 {
+ // We cannot return all the decoded bytes to the caller in this
+ // invocation of Read, so we return a nil error to ensure that Read
+ // will be called again. The error stored in d.err, if any, will be
+ // returned with the last set of decoded bytes.
+ return n, nil
+ }
+
+ return n, d.err
+}
+
+type newlineFilteringReader struct {
+ wrapped io.Reader
+}
+
+// stripNewlines removes newline characters and returns the number
+// of non-newline characters copied to dst.
+func stripNewlines(dst, src []byte) int {
+ offset := 0
+ for _, b := range src {
+ if b == '\r' || b == '\n' {
+ continue
+ }
+ dst[offset] = b
+ offset++
+ }
+ return offset
+}
+
+func (r *newlineFilteringReader) Read(p []byte) (int, error) {
+ n, err := r.wrapped.Read(p)
+ for n > 0 {
+ s := p[0:n]
+ offset := stripNewlines(s, s)
+ if err != nil || offset > 0 {
+ return offset, err
+ }
+ // Previous buffer entirely whitespace, read again
+ n, err = r.wrapped.Read(p)
+ }
+ return n, err
+}
+
+// NewDecoder constructs a new base32 stream decoder.
+func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
+ return &decoder{enc: enc, r: &newlineFilteringReader{r}}
+}
+
+// DecodedLen returns the maximum length in bytes of the decoded data
+// corresponding to n bytes of base32-encoded data.
+func (enc *Encoding) DecodedLen(n int) int {
+ if enc.padChar == NoPadding {
+ return n * 5 / 8
+ }
+
+ return n / 8 * 5
+}
diff --git a/contrib/go/_std_1.21/src/encoding/base32/ya.make b/contrib/go/_std_1.21/src/encoding/base32/ya.make
new file mode 100644
index 0000000000..93cbc4bdf7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/base32/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ base32.go
+)
+
+GO_TEST_SRCS(base32_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/encoding/base64/base64.go b/contrib/go/_std_1.21/src/encoding/base64/base64.go
new file mode 100644
index 0000000000..6aa8a15bdc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/base64/base64.go
@@ -0,0 +1,630 @@
+// Copyright 2009 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 base64 implements base64 encoding as specified by RFC 4648.
+package base64
+
+import (
+ "encoding/binary"
+ "io"
+ "strconv"
+)
+
+/*
+ * Encodings
+ */
+
+// An Encoding is a radix 64 encoding/decoding scheme, defined by a
+// 64-character alphabet. The most common encoding is the "base64"
+// encoding defined in RFC 4648 and used in MIME (RFC 2045) and PEM
+// (RFC 1421). RFC 4648 also defines an alternate encoding, which is
+// the standard encoding with - and _ substituted for + and /.
+type Encoding struct {
+ encode [64]byte
+ decodeMap [256]byte
+ padChar rune
+ strict bool
+}
+
+const (
+ StdPadding rune = '=' // Standard padding character
+ NoPadding rune = -1 // No padding
+ decodeMapInitialize = "" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
+ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
+)
+
+const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
+
+// NewEncoding returns a new padded Encoding defined by the given alphabet,
+// which must be a 64-byte string that does not contain the padding character
+// or CR / LF ('\r', '\n'). The alphabet is treated as sequence of byte values
+// without any special treatment for multi-byte UTF-8.
+// The resulting Encoding uses the default padding character ('='),
+// which may be changed or disabled via WithPadding.
+func NewEncoding(encoder string) *Encoding {
+ if len(encoder) != 64 {
+ panic("encoding alphabet is not 64-bytes long")
+ }
+ for i := 0; i < len(encoder); i++ {
+ if encoder[i] == '\n' || encoder[i] == '\r' {
+ panic("encoding alphabet contains newline character")
+ }
+ }
+
+ e := new(Encoding)
+ e.padChar = StdPadding
+ copy(e.encode[:], encoder)
+ copy(e.decodeMap[:], decodeMapInitialize)
+
+ for i := 0; i < len(encoder); i++ {
+ e.decodeMap[encoder[i]] = byte(i)
+ }
+ return e
+}
+
+// WithPadding creates a new encoding identical to enc except
+// with a specified padding character, or NoPadding to disable padding.
+// The padding character must not be '\r' or '\n', must not
+// be contained in the encoding's alphabet and must be a rune equal or
+// below '\xff'.
+// Padding characters above '\x7f' are encoded as their exact byte value
+// rather than using the UTF-8 representation of the codepoint.
+func (enc Encoding) WithPadding(padding rune) *Encoding {
+ if padding == '\r' || padding == '\n' || padding > 0xff {
+ panic("invalid padding")
+ }
+
+ for i := 0; i < len(enc.encode); i++ {
+ if rune(enc.encode[i]) == padding {
+ panic("padding contained in alphabet")
+ }
+ }
+
+ enc.padChar = padding
+ return &enc
+}
+
+// Strict creates a new encoding identical to enc except with
+// strict decoding enabled. In this mode, the decoder requires that
+// trailing padding bits are zero, as described in RFC 4648 section 3.5.
+//
+// Note that the input is still malleable, as new line characters
+// (CR and LF) are still ignored.
+func (enc Encoding) Strict() *Encoding {
+ enc.strict = true
+ return &enc
+}
+
+// StdEncoding is the standard base64 encoding, as defined in
+// RFC 4648.
+var StdEncoding = NewEncoding(encodeStd)
+
+// URLEncoding is the alternate base64 encoding defined in RFC 4648.
+// It is typically used in URLs and file names.
+var URLEncoding = NewEncoding(encodeURL)
+
+// RawStdEncoding is the standard raw, unpadded base64 encoding,
+// as defined in RFC 4648 section 3.2.
+// This is the same as StdEncoding but omits padding characters.
+var RawStdEncoding = StdEncoding.WithPadding(NoPadding)
+
+// RawURLEncoding is the unpadded alternate base64 encoding defined in RFC 4648.
+// It is typically used in URLs and file names.
+// This is the same as URLEncoding but omits padding characters.
+var RawURLEncoding = URLEncoding.WithPadding(NoPadding)
+
+/*
+ * Encoder
+ */
+
+// Encode encodes src using the encoding enc, writing
+// EncodedLen(len(src)) bytes to dst.
+//
+// The encoding pads the output to a multiple of 4 bytes,
+// so Encode is not appropriate for use on individual blocks
+// of a large data stream. Use NewEncoder() instead.
+func (enc *Encoding) Encode(dst, src []byte) {
+ if len(src) == 0 {
+ return
+ }
+ // enc is a pointer receiver, so the use of enc.encode within the hot
+ // loop below means a nil check at every operation. Lift that nil check
+ // outside of the loop to speed up the encoder.
+ _ = enc.encode
+
+ di, si := 0, 0
+ n := (len(src) / 3) * 3
+ for si < n {
+ // Convert 3x 8bit source bytes into 4 bytes
+ val := uint(src[si+0])<<16 | uint(src[si+1])<<8 | uint(src[si+2])
+
+ dst[di+0] = enc.encode[val>>18&0x3F]
+ dst[di+1] = enc.encode[val>>12&0x3F]
+ dst[di+2] = enc.encode[val>>6&0x3F]
+ dst[di+3] = enc.encode[val&0x3F]
+
+ si += 3
+ di += 4
+ }
+
+ remain := len(src) - si
+ if remain == 0 {
+ return
+ }
+ // Add the remaining small block
+ val := uint(src[si+0]) << 16
+ if remain == 2 {
+ val |= uint(src[si+1]) << 8
+ }
+
+ dst[di+0] = enc.encode[val>>18&0x3F]
+ dst[di+1] = enc.encode[val>>12&0x3F]
+
+ switch remain {
+ case 2:
+ dst[di+2] = enc.encode[val>>6&0x3F]
+ if enc.padChar != NoPadding {
+ dst[di+3] = byte(enc.padChar)
+ }
+ case 1:
+ if enc.padChar != NoPadding {
+ dst[di+2] = byte(enc.padChar)
+ dst[di+3] = byte(enc.padChar)
+ }
+ }
+}
+
+// EncodeToString returns the base64 encoding of src.
+func (enc *Encoding) EncodeToString(src []byte) string {
+ buf := make([]byte, enc.EncodedLen(len(src)))
+ enc.Encode(buf, src)
+ return string(buf)
+}
+
+type encoder struct {
+ err error
+ enc *Encoding
+ w io.Writer
+ buf [3]byte // buffered data waiting to be encoded
+ nbuf int // number of bytes in buf
+ out [1024]byte // output buffer
+}
+
+func (e *encoder) Write(p []byte) (n int, err error) {
+ if e.err != nil {
+ return 0, e.err
+ }
+
+ // Leading fringe.
+ if e.nbuf > 0 {
+ var i int
+ for i = 0; i < len(p) && e.nbuf < 3; i++ {
+ e.buf[e.nbuf] = p[i]
+ e.nbuf++
+ }
+ n += i
+ p = p[i:]
+ if e.nbuf < 3 {
+ return
+ }
+ e.enc.Encode(e.out[:], e.buf[:])
+ if _, e.err = e.w.Write(e.out[:4]); e.err != nil {
+ return n, e.err
+ }
+ e.nbuf = 0
+ }
+
+ // Large interior chunks.
+ for len(p) >= 3 {
+ nn := len(e.out) / 4 * 3
+ if nn > len(p) {
+ nn = len(p)
+ nn -= nn % 3
+ }
+ e.enc.Encode(e.out[:], p[:nn])
+ if _, e.err = e.w.Write(e.out[0 : nn/3*4]); e.err != nil {
+ return n, e.err
+ }
+ n += nn
+ p = p[nn:]
+ }
+
+ // Trailing fringe.
+ copy(e.buf[:], p)
+ e.nbuf = len(p)
+ n += len(p)
+ return
+}
+
+// Close flushes any pending output from the encoder.
+// It is an error to call Write after calling Close.
+func (e *encoder) Close() error {
+ // If there's anything left in the buffer, flush it out
+ if e.err == nil && e.nbuf > 0 {
+ e.enc.Encode(e.out[:], e.buf[:e.nbuf])
+ _, e.err = e.w.Write(e.out[:e.enc.EncodedLen(e.nbuf)])
+ e.nbuf = 0
+ }
+ return e.err
+}
+
+// NewEncoder returns a new base64 stream encoder. Data written to
+// the returned writer will be encoded using enc and then written to w.
+// Base64 encodings operate in 4-byte blocks; when finished
+// writing, the caller must Close the returned encoder to flush any
+// partially written blocks.
+func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
+ return &encoder{enc: enc, w: w}
+}
+
+// EncodedLen returns the length in bytes of the base64 encoding
+// of an input buffer of length n.
+func (enc *Encoding) EncodedLen(n int) int {
+ if enc.padChar == NoPadding {
+ return (n*8 + 5) / 6 // minimum # chars at 6 bits per char
+ }
+ return (n + 2) / 3 * 4 // minimum # 4-char quanta, 3 bytes each
+}
+
+/*
+ * Decoder
+ */
+
+type CorruptInputError int64
+
+func (e CorruptInputError) Error() string {
+ return "illegal base64 data at input byte " + strconv.FormatInt(int64(e), 10)
+}
+
+// decodeQuantum decodes up to 4 base64 bytes. The received parameters are
+// the destination buffer dst, the source buffer src and an index in the
+// source buffer si.
+// It returns the number of bytes read from src, the number of bytes written
+// to dst, and an error, if any.
+func (enc *Encoding) decodeQuantum(dst, src []byte, si int) (nsi, n int, err error) {
+ // Decode quantum using the base64 alphabet
+ var dbuf [4]byte
+ dlen := 4
+
+ // Lift the nil check outside of the loop.
+ _ = enc.decodeMap
+
+ for j := 0; j < len(dbuf); j++ {
+ if len(src) == si {
+ switch {
+ case j == 0:
+ return si, 0, nil
+ case j == 1, enc.padChar != NoPadding:
+ return si, 0, CorruptInputError(si - j)
+ }
+ dlen = j
+ break
+ }
+ in := src[si]
+ si++
+
+ out := enc.decodeMap[in]
+ if out != 0xff {
+ dbuf[j] = out
+ continue
+ }
+
+ if in == '\n' || in == '\r' {
+ j--
+ continue
+ }
+
+ if rune(in) != enc.padChar {
+ return si, 0, CorruptInputError(si - 1)
+ }
+
+ // We've reached the end and there's padding
+ switch j {
+ case 0, 1:
+ // incorrect padding
+ return si, 0, CorruptInputError(si - 1)
+ case 2:
+ // "==" is expected, the first "=" is already consumed.
+ // skip over newlines
+ for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
+ si++
+ }
+ if si == len(src) {
+ // not enough padding
+ return si, 0, CorruptInputError(len(src))
+ }
+ if rune(src[si]) != enc.padChar {
+ // incorrect padding
+ return si, 0, CorruptInputError(si - 1)
+ }
+
+ si++
+ }
+
+ // skip over newlines
+ for si < len(src) && (src[si] == '\n' || src[si] == '\r') {
+ si++
+ }
+ if si < len(src) {
+ // trailing garbage
+ err = CorruptInputError(si)
+ }
+ dlen = j
+ break
+ }
+
+ // Convert 4x 6bit source bytes into 3 bytes
+ val := uint(dbuf[0])<<18 | uint(dbuf[1])<<12 | uint(dbuf[2])<<6 | uint(dbuf[3])
+ dbuf[2], dbuf[1], dbuf[0] = byte(val>>0), byte(val>>8), byte(val>>16)
+ switch dlen {
+ case 4:
+ dst[2] = dbuf[2]
+ dbuf[2] = 0
+ fallthrough
+ case 3:
+ dst[1] = dbuf[1]
+ if enc.strict && dbuf[2] != 0 {
+ return si, 0, CorruptInputError(si - 1)
+ }
+ dbuf[1] = 0
+ fallthrough
+ case 2:
+ dst[0] = dbuf[0]
+ if enc.strict && (dbuf[1] != 0 || dbuf[2] != 0) {
+ return si, 0, CorruptInputError(si - 2)
+ }
+ }
+
+ return si, dlen - 1, err
+}
+
+// DecodeString returns the bytes represented by the base64 string s.
+func (enc *Encoding) DecodeString(s string) ([]byte, error) {
+ dbuf := make([]byte, enc.DecodedLen(len(s)))
+ n, err := enc.Decode(dbuf, []byte(s))
+ return dbuf[:n], err
+}
+
+type decoder struct {
+ err error
+ readErr error // error from r.Read
+ enc *Encoding
+ r io.Reader
+ buf [1024]byte // leftover input
+ nbuf int
+ out []byte // leftover decoded output
+ outbuf [1024 / 4 * 3]byte
+}
+
+func (d *decoder) Read(p []byte) (n int, err error) {
+ // Use leftover decoded output from last read.
+ if len(d.out) > 0 {
+ n = copy(p, d.out)
+ d.out = d.out[n:]
+ return n, nil
+ }
+
+ if d.err != nil {
+ return 0, d.err
+ }
+
+ // This code assumes that d.r strips supported whitespace ('\r' and '\n').
+
+ // Refill buffer.
+ for d.nbuf < 4 && d.readErr == nil {
+ nn := len(p) / 3 * 4
+ if nn < 4 {
+ nn = 4
+ }
+ if nn > len(d.buf) {
+ nn = len(d.buf)
+ }
+ nn, d.readErr = d.r.Read(d.buf[d.nbuf:nn])
+ d.nbuf += nn
+ }
+
+ if d.nbuf < 4 {
+ if d.enc.padChar == NoPadding && d.nbuf > 0 {
+ // Decode final fragment, without padding.
+ var nw int
+ nw, d.err = d.enc.Decode(d.outbuf[:], d.buf[:d.nbuf])
+ d.nbuf = 0
+ d.out = d.outbuf[:nw]
+ n = copy(p, d.out)
+ d.out = d.out[n:]
+ if n > 0 || len(p) == 0 && len(d.out) > 0 {
+ return n, nil
+ }
+ if d.err != nil {
+ return 0, d.err
+ }
+ }
+ d.err = d.readErr
+ if d.err == io.EOF && d.nbuf > 0 {
+ d.err = io.ErrUnexpectedEOF
+ }
+ return 0, d.err
+ }
+
+ // Decode chunk into p, or d.out and then p if p is too small.
+ nr := d.nbuf / 4 * 4
+ nw := d.nbuf / 4 * 3
+ if nw > len(p) {
+ nw, d.err = d.enc.Decode(d.outbuf[:], d.buf[:nr])
+ d.out = d.outbuf[:nw]
+ n = copy(p, d.out)
+ d.out = d.out[n:]
+ } else {
+ n, d.err = d.enc.Decode(p, d.buf[:nr])
+ }
+ d.nbuf -= nr
+ copy(d.buf[:d.nbuf], d.buf[nr:])
+ return n, d.err
+}
+
+// Decode decodes src using the encoding enc. It writes at most
+// DecodedLen(len(src)) bytes to dst and returns the number of bytes
+// written. If src contains invalid base64 data, it will return the
+// number of bytes successfully written and CorruptInputError.
+// New line characters (\r and \n) are ignored.
+func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
+ if len(src) == 0 {
+ return 0, nil
+ }
+
+ // Lift the nil check outside of the loop. enc.decodeMap is directly
+ // used later in this function, to let the compiler know that the
+ // receiver can't be nil.
+ _ = enc.decodeMap
+
+ si := 0
+ for strconv.IntSize >= 64 && len(src)-si >= 8 && len(dst)-n >= 8 {
+ src2 := src[si : si+8]
+ if dn, ok := assemble64(
+ enc.decodeMap[src2[0]],
+ enc.decodeMap[src2[1]],
+ enc.decodeMap[src2[2]],
+ enc.decodeMap[src2[3]],
+ enc.decodeMap[src2[4]],
+ enc.decodeMap[src2[5]],
+ enc.decodeMap[src2[6]],
+ enc.decodeMap[src2[7]],
+ ); ok {
+ binary.BigEndian.PutUint64(dst[n:], dn)
+ n += 6
+ si += 8
+ } else {
+ var ninc int
+ si, ninc, err = enc.decodeQuantum(dst[n:], src, si)
+ n += ninc
+ if err != nil {
+ return n, err
+ }
+ }
+ }
+
+ for len(src)-si >= 4 && len(dst)-n >= 4 {
+ src2 := src[si : si+4]
+ if dn, ok := assemble32(
+ enc.decodeMap[src2[0]],
+ enc.decodeMap[src2[1]],
+ enc.decodeMap[src2[2]],
+ enc.decodeMap[src2[3]],
+ ); ok {
+ binary.BigEndian.PutUint32(dst[n:], dn)
+ n += 3
+ si += 4
+ } else {
+ var ninc int
+ si, ninc, err = enc.decodeQuantum(dst[n:], src, si)
+ n += ninc
+ if err != nil {
+ return n, err
+ }
+ }
+ }
+
+ for si < len(src) {
+ var ninc int
+ si, ninc, err = enc.decodeQuantum(dst[n:], src, si)
+ n += ninc
+ if err != nil {
+ return n, err
+ }
+ }
+ return n, err
+}
+
+// assemble32 assembles 4 base64 digits into 3 bytes.
+// Each digit comes from the decode map, and will be 0xff
+// if it came from an invalid character.
+func assemble32(n1, n2, n3, n4 byte) (dn uint32, ok bool) {
+ // Check that all the digits are valid. If any of them was 0xff, their
+ // bitwise OR will be 0xff.
+ if n1|n2|n3|n4 == 0xff {
+ return 0, false
+ }
+ return uint32(n1)<<26 |
+ uint32(n2)<<20 |
+ uint32(n3)<<14 |
+ uint32(n4)<<8,
+ true
+}
+
+// assemble64 assembles 8 base64 digits into 6 bytes.
+// Each digit comes from the decode map, and will be 0xff
+// if it came from an invalid character.
+func assemble64(n1, n2, n3, n4, n5, n6, n7, n8 byte) (dn uint64, ok bool) {
+ // Check that all the digits are valid. If any of them was 0xff, their
+ // bitwise OR will be 0xff.
+ if n1|n2|n3|n4|n5|n6|n7|n8 == 0xff {
+ return 0, false
+ }
+ return uint64(n1)<<58 |
+ uint64(n2)<<52 |
+ uint64(n3)<<46 |
+ uint64(n4)<<40 |
+ uint64(n5)<<34 |
+ uint64(n6)<<28 |
+ uint64(n7)<<22 |
+ uint64(n8)<<16,
+ true
+}
+
+type newlineFilteringReader struct {
+ wrapped io.Reader
+}
+
+func (r *newlineFilteringReader) Read(p []byte) (int, error) {
+ n, err := r.wrapped.Read(p)
+ for n > 0 {
+ offset := 0
+ for i, b := range p[:n] {
+ if b != '\r' && b != '\n' {
+ if i != offset {
+ p[offset] = b
+ }
+ offset++
+ }
+ }
+ if offset > 0 {
+ return offset, err
+ }
+ // Previous buffer entirely whitespace, read again
+ n, err = r.wrapped.Read(p)
+ }
+ return n, err
+}
+
+// NewDecoder constructs a new base64 stream decoder.
+func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
+ return &decoder{enc: enc, r: &newlineFilteringReader{r}}
+}
+
+// DecodedLen returns the maximum length in bytes of the decoded data
+// corresponding to n bytes of base64-encoded data.
+func (enc *Encoding) DecodedLen(n int) int {
+ if enc.padChar == NoPadding {
+ // Unpadded data may end with partial block of 2-3 characters.
+ return n * 6 / 8
+ }
+ // Padded base64 should always be a multiple of 4 characters in length.
+ return n / 4 * 3
+}
diff --git a/contrib/go/_std_1.21/src/encoding/base64/ya.make b/contrib/go/_std_1.21/src/encoding/base64/ya.make
new file mode 100644
index 0000000000..936b2c25a0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/base64/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ base64.go
+)
+
+GO_TEST_SRCS(base64_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/encoding/binary/binary.go b/contrib/go/_std_1.21/src/encoding/binary/binary.go
new file mode 100644
index 0000000000..3fb18a7a03
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/binary/binary.go
@@ -0,0 +1,811 @@
+// Copyright 2009 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 binary implements simple translation between numbers and byte
+// sequences and encoding and decoding of varints.
+//
+// Numbers are translated by reading and writing fixed-size values.
+// A fixed-size value is either a fixed-size arithmetic
+// type (bool, int8, uint8, int16, float32, complex64, ...)
+// or an array or struct containing only fixed-size values.
+//
+// The varint functions encode and decode single integer values using
+// a variable-length encoding; smaller values require fewer bytes.
+// For a specification, see
+// https://developers.google.com/protocol-buffers/docs/encoding.
+//
+// This package favors simplicity over efficiency. Clients that require
+// high-performance serialization, especially for large data structures,
+// should look at more advanced solutions such as the encoding/gob
+// package or protocol buffers.
+package binary
+
+import (
+ "errors"
+ "io"
+ "math"
+ "reflect"
+ "sync"
+)
+
+// A ByteOrder specifies how to convert byte slices into
+// 16-, 32-, or 64-bit unsigned integers.
+type ByteOrder interface {
+ Uint16([]byte) uint16
+ Uint32([]byte) uint32
+ Uint64([]byte) uint64
+ PutUint16([]byte, uint16)
+ PutUint32([]byte, uint32)
+ PutUint64([]byte, uint64)
+ String() string
+}
+
+// AppendByteOrder specifies how to append 16-, 32-, or 64-bit unsigned integers
+// into a byte slice.
+type AppendByteOrder interface {
+ AppendUint16([]byte, uint16) []byte
+ AppendUint32([]byte, uint32) []byte
+ AppendUint64([]byte, uint64) []byte
+ String() string
+}
+
+// LittleEndian is the little-endian implementation of ByteOrder and AppendByteOrder.
+var LittleEndian littleEndian
+
+// BigEndian is the big-endian implementation of ByteOrder and AppendByteOrder.
+var BigEndian bigEndian
+
+type littleEndian struct{}
+
+func (littleEndian) Uint16(b []byte) uint16 {
+ _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint16(b[0]) | uint16(b[1])<<8
+}
+
+func (littleEndian) PutUint16(b []byte, v uint16) {
+ _ = b[1] // early bounds check to guarantee safety of writes below
+ b[0] = byte(v)
+ b[1] = byte(v >> 8)
+}
+
+func (littleEndian) AppendUint16(b []byte, v uint16) []byte {
+ return append(b,
+ byte(v),
+ byte(v>>8),
+ )
+}
+
+func (littleEndian) Uint32(b []byte) uint32 {
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+}
+
+func (littleEndian) PutUint32(b []byte, v uint32) {
+ _ = b[3] // early bounds check to guarantee safety of writes below
+ b[0] = byte(v)
+ b[1] = byte(v >> 8)
+ b[2] = byte(v >> 16)
+ b[3] = byte(v >> 24)
+}
+
+func (littleEndian) AppendUint32(b []byte, v uint32) []byte {
+ return append(b,
+ byte(v),
+ byte(v>>8),
+ byte(v>>16),
+ byte(v>>24),
+ )
+}
+
+func (littleEndian) Uint64(b []byte) uint64 {
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
+ uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+}
+
+func (littleEndian) PutUint64(b []byte, v uint64) {
+ _ = b[7] // early bounds check to guarantee safety of writes below
+ b[0] = byte(v)
+ b[1] = byte(v >> 8)
+ b[2] = byte(v >> 16)
+ b[3] = byte(v >> 24)
+ b[4] = byte(v >> 32)
+ b[5] = byte(v >> 40)
+ b[6] = byte(v >> 48)
+ b[7] = byte(v >> 56)
+}
+
+func (littleEndian) AppendUint64(b []byte, v uint64) []byte {
+ return append(b,
+ byte(v),
+ byte(v>>8),
+ byte(v>>16),
+ byte(v>>24),
+ byte(v>>32),
+ byte(v>>40),
+ byte(v>>48),
+ byte(v>>56),
+ )
+}
+
+func (littleEndian) String() string { return "LittleEndian" }
+
+func (littleEndian) GoString() string { return "binary.LittleEndian" }
+
+type bigEndian struct{}
+
+func (bigEndian) Uint16(b []byte) uint16 {
+ _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint16(b[1]) | uint16(b[0])<<8
+}
+
+func (bigEndian) PutUint16(b []byte, v uint16) {
+ _ = b[1] // early bounds check to guarantee safety of writes below
+ b[0] = byte(v >> 8)
+ b[1] = byte(v)
+}
+
+func (bigEndian) AppendUint16(b []byte, v uint16) []byte {
+ return append(b,
+ byte(v>>8),
+ byte(v),
+ )
+}
+
+func (bigEndian) Uint32(b []byte) uint32 {
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+}
+
+func (bigEndian) PutUint32(b []byte, v uint32) {
+ _ = b[3] // early bounds check to guarantee safety of writes below
+ b[0] = byte(v >> 24)
+ b[1] = byte(v >> 16)
+ b[2] = byte(v >> 8)
+ b[3] = byte(v)
+}
+
+func (bigEndian) AppendUint32(b []byte, v uint32) []byte {
+ return append(b,
+ byte(v>>24),
+ byte(v>>16),
+ byte(v>>8),
+ byte(v),
+ )
+}
+
+func (bigEndian) Uint64(b []byte) uint64 {
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+}
+
+func (bigEndian) PutUint64(b []byte, v uint64) {
+ _ = b[7] // early bounds check to guarantee safety of writes below
+ b[0] = byte(v >> 56)
+ b[1] = byte(v >> 48)
+ b[2] = byte(v >> 40)
+ b[3] = byte(v >> 32)
+ b[4] = byte(v >> 24)
+ b[5] = byte(v >> 16)
+ b[6] = byte(v >> 8)
+ b[7] = byte(v)
+}
+
+func (bigEndian) AppendUint64(b []byte, v uint64) []byte {
+ return append(b,
+ byte(v>>56),
+ byte(v>>48),
+ byte(v>>40),
+ byte(v>>32),
+ byte(v>>24),
+ byte(v>>16),
+ byte(v>>8),
+ byte(v),
+ )
+}
+
+func (bigEndian) String() string { return "BigEndian" }
+
+func (bigEndian) GoString() string { return "binary.BigEndian" }
+
+func (nativeEndian) String() string { return "NativeEndian" }
+
+func (nativeEndian) GoString() string { return "binary.NativeEndian" }
+
+// Read reads structured binary data from r into data.
+// Data must be a pointer to a fixed-size value or a slice
+// of fixed-size values.
+// Bytes read from r are decoded using the specified byte order
+// and written to successive fields of the data.
+// When decoding boolean values, a zero byte is decoded as false, and
+// any other non-zero byte is decoded as true.
+// When reading into structs, the field data for fields with
+// blank (_) field names is skipped; i.e., blank field names
+// may be used for padding.
+// When reading into a struct, all non-blank fields must be exported
+// or Read may panic.
+//
+// The error is EOF only if no bytes were read.
+// If an EOF happens after reading some but not all the bytes,
+// Read returns ErrUnexpectedEOF.
+func Read(r io.Reader, order ByteOrder, data any) error {
+ // Fast path for basic types and slices.
+ if n := intDataSize(data); n != 0 {
+ bs := make([]byte, n)
+ if _, err := io.ReadFull(r, bs); err != nil {
+ return err
+ }
+ switch data := data.(type) {
+ case *bool:
+ *data = bs[0] != 0
+ case *int8:
+ *data = int8(bs[0])
+ case *uint8:
+ *data = bs[0]
+ case *int16:
+ *data = int16(order.Uint16(bs))
+ case *uint16:
+ *data = order.Uint16(bs)
+ case *int32:
+ *data = int32(order.Uint32(bs))
+ case *uint32:
+ *data = order.Uint32(bs)
+ case *int64:
+ *data = int64(order.Uint64(bs))
+ case *uint64:
+ *data = order.Uint64(bs)
+ case *float32:
+ *data = math.Float32frombits(order.Uint32(bs))
+ case *float64:
+ *data = math.Float64frombits(order.Uint64(bs))
+ case []bool:
+ for i, x := range bs { // Easier to loop over the input for 8-bit values.
+ data[i] = x != 0
+ }
+ case []int8:
+ for i, x := range bs {
+ data[i] = int8(x)
+ }
+ case []uint8:
+ copy(data, bs)
+ case []int16:
+ for i := range data {
+ data[i] = int16(order.Uint16(bs[2*i:]))
+ }
+ case []uint16:
+ for i := range data {
+ data[i] = order.Uint16(bs[2*i:])
+ }
+ case []int32:
+ for i := range data {
+ data[i] = int32(order.Uint32(bs[4*i:]))
+ }
+ case []uint32:
+ for i := range data {
+ data[i] = order.Uint32(bs[4*i:])
+ }
+ case []int64:
+ for i := range data {
+ data[i] = int64(order.Uint64(bs[8*i:]))
+ }
+ case []uint64:
+ for i := range data {
+ data[i] = order.Uint64(bs[8*i:])
+ }
+ case []float32:
+ for i := range data {
+ data[i] = math.Float32frombits(order.Uint32(bs[4*i:]))
+ }
+ case []float64:
+ for i := range data {
+ data[i] = math.Float64frombits(order.Uint64(bs[8*i:]))
+ }
+ default:
+ n = 0 // fast path doesn't apply
+ }
+ if n != 0 {
+ return nil
+ }
+ }
+
+ // Fallback to reflect-based decoding.
+ v := reflect.ValueOf(data)
+ size := -1
+ switch v.Kind() {
+ case reflect.Pointer:
+ v = v.Elem()
+ size = dataSize(v)
+ case reflect.Slice:
+ size = dataSize(v)
+ }
+ if size < 0 {
+ return errors.New("binary.Read: invalid type " + reflect.TypeOf(data).String())
+ }
+ d := &decoder{order: order, buf: make([]byte, size)}
+ if _, err := io.ReadFull(r, d.buf); err != nil {
+ return err
+ }
+ d.value(v)
+ return nil
+}
+
+// Write writes the binary representation of data into w.
+// Data must be a fixed-size value or a slice of fixed-size
+// values, or a pointer to such data.
+// Boolean values encode as one byte: 1 for true, and 0 for false.
+// Bytes written to w are encoded using the specified byte order
+// and read from successive fields of the data.
+// When writing structs, zero values are written for fields
+// with blank (_) field names.
+func Write(w io.Writer, order ByteOrder, data any) error {
+ // Fast path for basic types and slices.
+ if n := intDataSize(data); n != 0 {
+ bs := make([]byte, n)
+ switch v := data.(type) {
+ case *bool:
+ if *v {
+ bs[0] = 1
+ } else {
+ bs[0] = 0
+ }
+ case bool:
+ if v {
+ bs[0] = 1
+ } else {
+ bs[0] = 0
+ }
+ case []bool:
+ for i, x := range v {
+ if x {
+ bs[i] = 1
+ } else {
+ bs[i] = 0
+ }
+ }
+ case *int8:
+ bs[0] = byte(*v)
+ case int8:
+ bs[0] = byte(v)
+ case []int8:
+ for i, x := range v {
+ bs[i] = byte(x)
+ }
+ case *uint8:
+ bs[0] = *v
+ case uint8:
+ bs[0] = v
+ case []uint8:
+ bs = v
+ case *int16:
+ order.PutUint16(bs, uint16(*v))
+ case int16:
+ order.PutUint16(bs, uint16(v))
+ case []int16:
+ for i, x := range v {
+ order.PutUint16(bs[2*i:], uint16(x))
+ }
+ case *uint16:
+ order.PutUint16(bs, *v)
+ case uint16:
+ order.PutUint16(bs, v)
+ case []uint16:
+ for i, x := range v {
+ order.PutUint16(bs[2*i:], x)
+ }
+ case *int32:
+ order.PutUint32(bs, uint32(*v))
+ case int32:
+ order.PutUint32(bs, uint32(v))
+ case []int32:
+ for i, x := range v {
+ order.PutUint32(bs[4*i:], uint32(x))
+ }
+ case *uint32:
+ order.PutUint32(bs, *v)
+ case uint32:
+ order.PutUint32(bs, v)
+ case []uint32:
+ for i, x := range v {
+ order.PutUint32(bs[4*i:], x)
+ }
+ case *int64:
+ order.PutUint64(bs, uint64(*v))
+ case int64:
+ order.PutUint64(bs, uint64(v))
+ case []int64:
+ for i, x := range v {
+ order.PutUint64(bs[8*i:], uint64(x))
+ }
+ case *uint64:
+ order.PutUint64(bs, *v)
+ case uint64:
+ order.PutUint64(bs, v)
+ case []uint64:
+ for i, x := range v {
+ order.PutUint64(bs[8*i:], x)
+ }
+ case *float32:
+ order.PutUint32(bs, math.Float32bits(*v))
+ case float32:
+ order.PutUint32(bs, math.Float32bits(v))
+ case []float32:
+ for i, x := range v {
+ order.PutUint32(bs[4*i:], math.Float32bits(x))
+ }
+ case *float64:
+ order.PutUint64(bs, math.Float64bits(*v))
+ case float64:
+ order.PutUint64(bs, math.Float64bits(v))
+ case []float64:
+ for i, x := range v {
+ order.PutUint64(bs[8*i:], math.Float64bits(x))
+ }
+ }
+ _, err := w.Write(bs)
+ return err
+ }
+
+ // Fallback to reflect-based encoding.
+ v := reflect.Indirect(reflect.ValueOf(data))
+ size := dataSize(v)
+ if size < 0 {
+ return errors.New("binary.Write: some values are not fixed-sized in type " + reflect.TypeOf(data).String())
+ }
+ buf := make([]byte, size)
+ e := &encoder{order: order, buf: buf}
+ e.value(v)
+ _, err := w.Write(buf)
+ return err
+}
+
+// Size returns how many bytes Write would generate to encode the value v, which
+// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.
+// If v is neither of these, Size returns -1.
+func Size(v any) int {
+ return dataSize(reflect.Indirect(reflect.ValueOf(v)))
+}
+
+var structSize sync.Map // map[reflect.Type]int
+
+// dataSize returns the number of bytes the actual data represented by v occupies in memory.
+// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice
+// it returns the length of the slice times the element size and does not count the memory
+// occupied by the header. If the type of v is not acceptable, dataSize returns -1.
+func dataSize(v reflect.Value) int {
+ switch v.Kind() {
+ case reflect.Slice:
+ if s := sizeof(v.Type().Elem()); s >= 0 {
+ return s * v.Len()
+ }
+
+ case reflect.Struct:
+ t := v.Type()
+ if size, ok := structSize.Load(t); ok {
+ return size.(int)
+ }
+ size := sizeof(t)
+ structSize.Store(t, size)
+ return size
+
+ default:
+ if v.IsValid() {
+ return sizeof(v.Type())
+ }
+ }
+
+ return -1
+}
+
+// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.
+func sizeof(t reflect.Type) int {
+ switch t.Kind() {
+ case reflect.Array:
+ if s := sizeof(t.Elem()); s >= 0 {
+ return s * t.Len()
+ }
+
+ case reflect.Struct:
+ sum := 0
+ for i, n := 0, t.NumField(); i < n; i++ {
+ s := sizeof(t.Field(i).Type)
+ if s < 0 {
+ return -1
+ }
+ sum += s
+ }
+ return sum
+
+ case reflect.Bool,
+ reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+ reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+ reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
+ return int(t.Size())
+ }
+
+ return -1
+}
+
+type coder struct {
+ order ByteOrder
+ buf []byte
+ offset int
+}
+
+type decoder coder
+type encoder coder
+
+func (d *decoder) bool() bool {
+ x := d.buf[d.offset]
+ d.offset++
+ return x != 0
+}
+
+func (e *encoder) bool(x bool) {
+ if x {
+ e.buf[e.offset] = 1
+ } else {
+ e.buf[e.offset] = 0
+ }
+ e.offset++
+}
+
+func (d *decoder) uint8() uint8 {
+ x := d.buf[d.offset]
+ d.offset++
+ return x
+}
+
+func (e *encoder) uint8(x uint8) {
+ e.buf[e.offset] = x
+ e.offset++
+}
+
+func (d *decoder) uint16() uint16 {
+ x := d.order.Uint16(d.buf[d.offset : d.offset+2])
+ d.offset += 2
+ return x
+}
+
+func (e *encoder) uint16(x uint16) {
+ e.order.PutUint16(e.buf[e.offset:e.offset+2], x)
+ e.offset += 2
+}
+
+func (d *decoder) uint32() uint32 {
+ x := d.order.Uint32(d.buf[d.offset : d.offset+4])
+ d.offset += 4
+ return x
+}
+
+func (e *encoder) uint32(x uint32) {
+ e.order.PutUint32(e.buf[e.offset:e.offset+4], x)
+ e.offset += 4
+}
+
+func (d *decoder) uint64() uint64 {
+ x := d.order.Uint64(d.buf[d.offset : d.offset+8])
+ d.offset += 8
+ return x
+}
+
+func (e *encoder) uint64(x uint64) {
+ e.order.PutUint64(e.buf[e.offset:e.offset+8], x)
+ e.offset += 8
+}
+
+func (d *decoder) int8() int8 { return int8(d.uint8()) }
+
+func (e *encoder) int8(x int8) { e.uint8(uint8(x)) }
+
+func (d *decoder) int16() int16 { return int16(d.uint16()) }
+
+func (e *encoder) int16(x int16) { e.uint16(uint16(x)) }
+
+func (d *decoder) int32() int32 { return int32(d.uint32()) }
+
+func (e *encoder) int32(x int32) { e.uint32(uint32(x)) }
+
+func (d *decoder) int64() int64 { return int64(d.uint64()) }
+
+func (e *encoder) int64(x int64) { e.uint64(uint64(x)) }
+
+func (d *decoder) value(v reflect.Value) {
+ switch v.Kind() {
+ case reflect.Array:
+ l := v.Len()
+ for i := 0; i < l; i++ {
+ d.value(v.Index(i))
+ }
+
+ case reflect.Struct:
+ t := v.Type()
+ l := v.NumField()
+ for i := 0; i < l; i++ {
+ // Note: Calling v.CanSet() below is an optimization.
+ // It would be sufficient to check the field name,
+ // but creating the StructField info for each field is
+ // costly (run "go test -bench=ReadStruct" and compare
+ // results when making changes to this code).
+ if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
+ d.value(v)
+ } else {
+ d.skip(v)
+ }
+ }
+
+ case reflect.Slice:
+ l := v.Len()
+ for i := 0; i < l; i++ {
+ d.value(v.Index(i))
+ }
+
+ case reflect.Bool:
+ v.SetBool(d.bool())
+
+ case reflect.Int8:
+ v.SetInt(int64(d.int8()))
+ case reflect.Int16:
+ v.SetInt(int64(d.int16()))
+ case reflect.Int32:
+ v.SetInt(int64(d.int32()))
+ case reflect.Int64:
+ v.SetInt(d.int64())
+
+ case reflect.Uint8:
+ v.SetUint(uint64(d.uint8()))
+ case reflect.Uint16:
+ v.SetUint(uint64(d.uint16()))
+ case reflect.Uint32:
+ v.SetUint(uint64(d.uint32()))
+ case reflect.Uint64:
+ v.SetUint(d.uint64())
+
+ case reflect.Float32:
+ v.SetFloat(float64(math.Float32frombits(d.uint32())))
+ case reflect.Float64:
+ v.SetFloat(math.Float64frombits(d.uint64()))
+
+ case reflect.Complex64:
+ v.SetComplex(complex(
+ float64(math.Float32frombits(d.uint32())),
+ float64(math.Float32frombits(d.uint32())),
+ ))
+ case reflect.Complex128:
+ v.SetComplex(complex(
+ math.Float64frombits(d.uint64()),
+ math.Float64frombits(d.uint64()),
+ ))
+ }
+}
+
+func (e *encoder) value(v reflect.Value) {
+ switch v.Kind() {
+ case reflect.Array:
+ l := v.Len()
+ for i := 0; i < l; i++ {
+ e.value(v.Index(i))
+ }
+
+ case reflect.Struct:
+ t := v.Type()
+ l := v.NumField()
+ for i := 0; i < l; i++ {
+ // see comment for corresponding code in decoder.value()
+ if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
+ e.value(v)
+ } else {
+ e.skip(v)
+ }
+ }
+
+ case reflect.Slice:
+ l := v.Len()
+ for i := 0; i < l; i++ {
+ e.value(v.Index(i))
+ }
+
+ case reflect.Bool:
+ e.bool(v.Bool())
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ switch v.Type().Kind() {
+ case reflect.Int8:
+ e.int8(int8(v.Int()))
+ case reflect.Int16:
+ e.int16(int16(v.Int()))
+ case reflect.Int32:
+ e.int32(int32(v.Int()))
+ case reflect.Int64:
+ e.int64(v.Int())
+ }
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ switch v.Type().Kind() {
+ case reflect.Uint8:
+ e.uint8(uint8(v.Uint()))
+ case reflect.Uint16:
+ e.uint16(uint16(v.Uint()))
+ case reflect.Uint32:
+ e.uint32(uint32(v.Uint()))
+ case reflect.Uint64:
+ e.uint64(v.Uint())
+ }
+
+ case reflect.Float32, reflect.Float64:
+ switch v.Type().Kind() {
+ case reflect.Float32:
+ e.uint32(math.Float32bits(float32(v.Float())))
+ case reflect.Float64:
+ e.uint64(math.Float64bits(v.Float()))
+ }
+
+ case reflect.Complex64, reflect.Complex128:
+ switch v.Type().Kind() {
+ case reflect.Complex64:
+ x := v.Complex()
+ e.uint32(math.Float32bits(float32(real(x))))
+ e.uint32(math.Float32bits(float32(imag(x))))
+ case reflect.Complex128:
+ x := v.Complex()
+ e.uint64(math.Float64bits(real(x)))
+ e.uint64(math.Float64bits(imag(x)))
+ }
+ }
+}
+
+func (d *decoder) skip(v reflect.Value) {
+ d.offset += dataSize(v)
+}
+
+func (e *encoder) skip(v reflect.Value) {
+ n := dataSize(v)
+ zero := e.buf[e.offset : e.offset+n]
+ for i := range zero {
+ zero[i] = 0
+ }
+ e.offset += n
+}
+
+// intDataSize returns the size of the data required to represent the data when encoded.
+// It returns zero if the type cannot be implemented by the fast path in Read or Write.
+func intDataSize(data any) int {
+ switch data := data.(type) {
+ case bool, int8, uint8, *bool, *int8, *uint8:
+ return 1
+ case []bool:
+ return len(data)
+ case []int8:
+ return len(data)
+ case []uint8:
+ return len(data)
+ case int16, uint16, *int16, *uint16:
+ return 2
+ case []int16:
+ return 2 * len(data)
+ case []uint16:
+ return 2 * len(data)
+ case int32, uint32, *int32, *uint32:
+ return 4
+ case []int32:
+ return 4 * len(data)
+ case []uint32:
+ return 4 * len(data)
+ case int64, uint64, *int64, *uint64:
+ return 8
+ case []int64:
+ return 8 * len(data)
+ case []uint64:
+ return 8 * len(data)
+ case float32, *float32:
+ return 4
+ case float64, *float64:
+ return 8
+ case []float32:
+ return 4 * len(data)
+ case []float64:
+ return 8 * len(data)
+ }
+ return 0
+}
diff --git a/contrib/go/_std_1.21/src/encoding/binary/native_endian_little.go b/contrib/go/_std_1.21/src/encoding/binary/native_endian_little.go
new file mode 100644
index 0000000000..67b41ae0a2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/binary/native_endian_little.go
@@ -0,0 +1,14 @@
+// Copyright 2023 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.
+
+//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh || wasm
+
+package binary
+
+type nativeEndian struct {
+ littleEndian
+}
+
+// NativeEndian is the native-endian implementation of ByteOrder and AppendByteOrder.
+var NativeEndian nativeEndian
diff --git a/contrib/go/_std_1.21/src/encoding/binary/varint.go b/contrib/go/_std_1.21/src/encoding/binary/varint.go
new file mode 100644
index 0000000000..7b14fb2b63
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/binary/varint.go
@@ -0,0 +1,166 @@
+// Copyright 2011 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 binary
+
+// This file implements "varint" encoding of 64-bit integers.
+// The encoding is:
+// - unsigned integers are serialized 7 bits at a time, starting with the
+// least significant bits
+// - the most significant bit (msb) in each output byte indicates if there
+// is a continuation byte (msb = 1)
+// - signed integers are mapped to unsigned integers using "zig-zag"
+// encoding: Positive values x are written as 2*x + 0, negative values
+// are written as 2*(^x) + 1; that is, negative numbers are complemented
+// and whether to complement is encoded in bit 0.
+//
+// Design note:
+// At most 10 bytes are needed for 64-bit values. The encoding could
+// be more dense: a full 64-bit value needs an extra byte just to hold bit 63.
+// Instead, the msb of the previous byte could be used to hold bit 63 since we
+// know there can't be more than 64 bits. This is a trivial improvement and
+// would reduce the maximum encoding length to 9 bytes. However, it breaks the
+// invariant that the msb is always the "continuation bit" and thus makes the
+// format incompatible with a varint encoding for larger numbers (say 128-bit).
+
+import (
+ "errors"
+ "io"
+)
+
+// MaxVarintLenN is the maximum length of a varint-encoded N-bit integer.
+const (
+ MaxVarintLen16 = 3
+ MaxVarintLen32 = 5
+ MaxVarintLen64 = 10
+)
+
+// AppendUvarint appends the varint-encoded form of x,
+// as generated by PutUvarint, to buf and returns the extended buffer.
+func AppendUvarint(buf []byte, x uint64) []byte {
+ for x >= 0x80 {
+ buf = append(buf, byte(x)|0x80)
+ x >>= 7
+ }
+ return append(buf, byte(x))
+}
+
+// PutUvarint encodes a uint64 into buf and returns the number of bytes written.
+// If the buffer is too small, PutUvarint will panic.
+func PutUvarint(buf []byte, x uint64) int {
+ i := 0
+ for x >= 0x80 {
+ buf[i] = byte(x) | 0x80
+ x >>= 7
+ i++
+ }
+ buf[i] = byte(x)
+ return i + 1
+}
+
+// Uvarint decodes a uint64 from buf and returns that value and the
+// number of bytes read (> 0). If an error occurred, the value is 0
+// and the number of bytes n is <= 0 meaning:
+//
+// n == 0: buf too small
+// n < 0: value larger than 64 bits (overflow)
+// and -n is the number of bytes read
+func Uvarint(buf []byte) (uint64, int) {
+ var x uint64
+ var s uint
+ for i, b := range buf {
+ if i == MaxVarintLen64 {
+ // Catch byte reads past MaxVarintLen64.
+ // See issue https://golang.org/issues/41185
+ return 0, -(i + 1) // overflow
+ }
+ if b < 0x80 {
+ if i == MaxVarintLen64-1 && b > 1 {
+ return 0, -(i + 1) // overflow
+ }
+ return x | uint64(b)<<s, i + 1
+ }
+ x |= uint64(b&0x7f) << s
+ s += 7
+ }
+ return 0, 0
+}
+
+// AppendVarint appends the varint-encoded form of x,
+// as generated by PutVarint, to buf and returns the extended buffer.
+func AppendVarint(buf []byte, x int64) []byte {
+ ux := uint64(x) << 1
+ if x < 0 {
+ ux = ^ux
+ }
+ return AppendUvarint(buf, ux)
+}
+
+// PutVarint encodes an int64 into buf and returns the number of bytes written.
+// If the buffer is too small, PutVarint will panic.
+func PutVarint(buf []byte, x int64) int {
+ ux := uint64(x) << 1
+ if x < 0 {
+ ux = ^ux
+ }
+ return PutUvarint(buf, ux)
+}
+
+// Varint decodes an int64 from buf and returns that value and the
+// number of bytes read (> 0). If an error occurred, the value is 0
+// and the number of bytes n is <= 0 with the following meaning:
+//
+// n == 0: buf too small
+// n < 0: value larger than 64 bits (overflow)
+// and -n is the number of bytes read
+func Varint(buf []byte) (int64, int) {
+ ux, n := Uvarint(buf) // ok to continue in presence of error
+ x := int64(ux >> 1)
+ if ux&1 != 0 {
+ x = ^x
+ }
+ return x, n
+}
+
+var errOverflow = errors.New("binary: varint overflows a 64-bit integer")
+
+// ReadUvarint reads an encoded unsigned integer from r and returns it as a uint64.
+// The error is EOF only if no bytes were read.
+// If an EOF happens after reading some but not all the bytes,
+// ReadUvarint returns io.ErrUnexpectedEOF.
+func ReadUvarint(r io.ByteReader) (uint64, error) {
+ var x uint64
+ var s uint
+ for i := 0; i < MaxVarintLen64; i++ {
+ b, err := r.ReadByte()
+ if err != nil {
+ if i > 0 && err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return x, err
+ }
+ if b < 0x80 {
+ if i == MaxVarintLen64-1 && b > 1 {
+ return x, errOverflow
+ }
+ return x | uint64(b)<<s, nil
+ }
+ x |= uint64(b&0x7f) << s
+ s += 7
+ }
+ return x, errOverflow
+}
+
+// ReadVarint reads an encoded signed integer from r and returns it as an int64.
+// The error is EOF only if no bytes were read.
+// If an EOF happens after reading some but not all the bytes,
+// ReadVarint returns io.ErrUnexpectedEOF.
+func ReadVarint(r io.ByteReader) (int64, error) {
+ ux, err := ReadUvarint(r) // ok to continue in presence of error
+ x := int64(ux >> 1)
+ if ux&1 != 0 {
+ x = ^x
+ }
+ return x, err
+}
diff --git a/contrib/go/_std_1.21/src/encoding/binary/ya.make b/contrib/go/_std_1.21/src/encoding/binary/ya.make
new file mode 100644
index 0000000000..b6b07c3f81
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/binary/ya.make
@@ -0,0 +1,19 @@
+GO_LIBRARY()
+
+SRCS(
+ binary.go
+ native_endian_little.go
+ varint.go
+)
+
+GO_TEST_SRCS(
+ binary_test.go
+ varint_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/encoding/csv/reader.go b/contrib/go/_std_1.21/src/encoding/csv/reader.go
new file mode 100644
index 0000000000..c6a8ed02c1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/csv/reader.go
@@ -0,0 +1,466 @@
+// Copyright 2011 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 csv reads and writes comma-separated values (CSV) files.
+// There are many kinds of CSV files; this package supports the format
+// described in RFC 4180.
+//
+// A csv file contains zero or more records of one or more fields per record.
+// Each record is separated by the newline character. The final record may
+// optionally be followed by a newline character.
+//
+// field1,field2,field3
+//
+// White space is considered part of a field.
+//
+// Carriage returns before newline characters are silently removed.
+//
+// Blank lines are ignored. A line with only whitespace characters (excluding
+// the ending newline character) is not considered a blank line.
+//
+// Fields which start and stop with the quote character " are called
+// quoted-fields. The beginning and ending quote are not part of the
+// field.
+//
+// The source:
+//
+// normal string,"quoted-field"
+//
+// results in the fields
+//
+// {`normal string`, `quoted-field`}
+//
+// Within a quoted-field a quote character followed by a second quote
+// character is considered a single quote.
+//
+// "the ""word"" is true","a ""quoted-field"""
+//
+// results in
+//
+// {`the "word" is true`, `a "quoted-field"`}
+//
+// Newlines and commas may be included in a quoted-field
+//
+// "Multi-line
+// field","comma is ,"
+//
+// results in
+//
+// {`Multi-line
+// field`, `comma is ,`}
+package csv
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "unicode"
+ "unicode/utf8"
+)
+
+// A ParseError is returned for parsing errors.
+// Line numbers are 1-indexed and columns are 0-indexed.
+type ParseError struct {
+ StartLine int // Line where the record starts
+ Line int // Line where the error occurred
+ Column int // Column (1-based byte index) where the error occurred
+ Err error // The actual error
+}
+
+func (e *ParseError) Error() string {
+ if e.Err == ErrFieldCount {
+ return fmt.Sprintf("record on line %d: %v", e.Line, e.Err)
+ }
+ if e.StartLine != e.Line {
+ return fmt.Sprintf("record on line %d; parse error on line %d, column %d: %v", e.StartLine, e.Line, e.Column, e.Err)
+ }
+ return fmt.Sprintf("parse error on line %d, column %d: %v", e.Line, e.Column, e.Err)
+}
+
+func (e *ParseError) Unwrap() error { return e.Err }
+
+// These are the errors that can be returned in ParseError.Err.
+var (
+ ErrBareQuote = errors.New("bare \" in non-quoted-field")
+ ErrQuote = errors.New("extraneous or missing \" in quoted-field")
+ ErrFieldCount = errors.New("wrong number of fields")
+
+ // Deprecated: ErrTrailingComma is no longer used.
+ ErrTrailingComma = errors.New("extra delimiter at end of line")
+)
+
+var errInvalidDelim = errors.New("csv: invalid field or comment delimiter")
+
+func validDelim(r rune) bool {
+ return r != 0 && r != '"' && r != '\r' && r != '\n' && utf8.ValidRune(r) && r != utf8.RuneError
+}
+
+// A Reader reads records from a CSV-encoded file.
+//
+// As returned by NewReader, a Reader expects input conforming to RFC 4180.
+// The exported fields can be changed to customize the details before the
+// first call to Read or ReadAll.
+//
+// The Reader converts all \r\n sequences in its input to plain \n,
+// including in multiline field values, so that the returned data does
+// not depend on which line-ending convention an input file uses.
+type Reader struct {
+ // Comma is the field delimiter.
+ // It is set to comma (',') by NewReader.
+ // Comma must be a valid rune and must not be \r, \n,
+ // or the Unicode replacement character (0xFFFD).
+ Comma rune
+
+ // Comment, if not 0, is the comment character. Lines beginning with the
+ // Comment character without preceding whitespace are ignored.
+ // With leading whitespace the Comment character becomes part of the
+ // field, even if TrimLeadingSpace is true.
+ // Comment must be a valid rune and must not be \r, \n,
+ // or the Unicode replacement character (0xFFFD).
+ // It must also not be equal to Comma.
+ Comment rune
+
+ // FieldsPerRecord is the number of expected fields per record.
+ // If FieldsPerRecord is positive, Read requires each record to
+ // have the given number of fields. If FieldsPerRecord is 0, Read sets it to
+ // the number of fields in the first record, so that future records must
+ // have the same field count. If FieldsPerRecord is negative, no check is
+ // made and records may have a variable number of fields.
+ FieldsPerRecord int
+
+ // If LazyQuotes is true, a quote may appear in an unquoted field and a
+ // non-doubled quote may appear in a quoted field.
+ LazyQuotes bool
+
+ // If TrimLeadingSpace is true, leading white space in a field is ignored.
+ // This is done even if the field delimiter, Comma, is white space.
+ TrimLeadingSpace bool
+
+ // ReuseRecord controls whether calls to Read may return a slice sharing
+ // the backing array of the previous call's returned slice for performance.
+ // By default, each call to Read returns newly allocated memory owned by the caller.
+ ReuseRecord bool
+
+ // Deprecated: TrailingComma is no longer used.
+ TrailingComma bool
+
+ r *bufio.Reader
+
+ // numLine is the current line being read in the CSV file.
+ numLine int
+
+ // offset is the input stream byte offset of the current reader position.
+ offset int64
+
+ // rawBuffer is a line buffer only used by the readLine method.
+ rawBuffer []byte
+
+ // recordBuffer holds the unescaped fields, one after another.
+ // The fields can be accessed by using the indexes in fieldIndexes.
+ // E.g., For the row `a,"b","c""d",e`, recordBuffer will contain `abc"de`
+ // and fieldIndexes will contain the indexes [1, 2, 5, 6].
+ recordBuffer []byte
+
+ // fieldIndexes is an index of fields inside recordBuffer.
+ // The i'th field ends at offset fieldIndexes[i] in recordBuffer.
+ fieldIndexes []int
+
+ // fieldPositions is an index of field positions for the
+ // last record returned by Read.
+ fieldPositions []position
+
+ // lastRecord is a record cache and only used when ReuseRecord == true.
+ lastRecord []string
+}
+
+// NewReader returns a new Reader that reads from r.
+func NewReader(r io.Reader) *Reader {
+ return &Reader{
+ Comma: ',',
+ r: bufio.NewReader(r),
+ }
+}
+
+// Read reads one record (a slice of fields) from r.
+// If the record has an unexpected number of fields,
+// Read returns the record along with the error ErrFieldCount.
+// If the record contains a field that cannot be parsed,
+// Read returns a partial record along with the parse error.
+// The partial record contains all fields read before the error.
+// If there is no data left to be read, Read returns nil, io.EOF.
+// If ReuseRecord is true, the returned slice may be shared
+// between multiple calls to Read.
+func (r *Reader) Read() (record []string, err error) {
+ if r.ReuseRecord {
+ record, err = r.readRecord(r.lastRecord)
+ r.lastRecord = record
+ } else {
+ record, err = r.readRecord(nil)
+ }
+ return record, err
+}
+
+// FieldPos returns the line and column corresponding to
+// the start of the field with the given index in the slice most recently
+// returned by Read. Numbering of lines and columns starts at 1;
+// columns are counted in bytes, not runes.
+//
+// If this is called with an out-of-bounds index, it panics.
+func (r *Reader) FieldPos(field int) (line, column int) {
+ if field < 0 || field >= len(r.fieldPositions) {
+ panic("out of range index passed to FieldPos")
+ }
+ p := &r.fieldPositions[field]
+ return p.line, p.col
+}
+
+// InputOffset returns the input stream byte offset of the current reader
+// position. The offset gives the location of the end of the most recently
+// read row and the beginning of the next row.
+func (r *Reader) InputOffset() int64 {
+ return r.offset
+}
+
+// pos holds the position of a field in the current line.
+type position struct {
+ line, col int
+}
+
+// ReadAll reads all the remaining records from r.
+// Each record is a slice of fields.
+// A successful call returns err == nil, not err == io.EOF. Because ReadAll is
+// defined to read until EOF, it does not treat end of file as an error to be
+// reported.
+func (r *Reader) ReadAll() (records [][]string, err error) {
+ for {
+ record, err := r.readRecord(nil)
+ if err == io.EOF {
+ return records, nil
+ }
+ if err != nil {
+ return nil, err
+ }
+ records = append(records, record)
+ }
+}
+
+// readLine reads the next line (with the trailing endline).
+// If EOF is hit without a trailing endline, it will be omitted.
+// If some bytes were read, then the error is never io.EOF.
+// The result is only valid until the next call to readLine.
+func (r *Reader) readLine() ([]byte, error) {
+ line, err := r.r.ReadSlice('\n')
+ if err == bufio.ErrBufferFull {
+ r.rawBuffer = append(r.rawBuffer[:0], line...)
+ for err == bufio.ErrBufferFull {
+ line, err = r.r.ReadSlice('\n')
+ r.rawBuffer = append(r.rawBuffer, line...)
+ }
+ line = r.rawBuffer
+ }
+ readSize := len(line)
+ if readSize > 0 && err == io.EOF {
+ err = nil
+ // For backwards compatibility, drop trailing \r before EOF.
+ if line[readSize-1] == '\r' {
+ line = line[:readSize-1]
+ }
+ }
+ r.numLine++
+ r.offset += int64(readSize)
+ // Normalize \r\n to \n on all input lines.
+ if n := len(line); n >= 2 && line[n-2] == '\r' && line[n-1] == '\n' {
+ line[n-2] = '\n'
+ line = line[:n-1]
+ }
+ return line, err
+}
+
+// lengthNL reports the number of bytes for the trailing \n.
+func lengthNL(b []byte) int {
+ if len(b) > 0 && b[len(b)-1] == '\n' {
+ return 1
+ }
+ return 0
+}
+
+// nextRune returns the next rune in b or utf8.RuneError.
+func nextRune(b []byte) rune {
+ r, _ := utf8.DecodeRune(b)
+ return r
+}
+
+func (r *Reader) readRecord(dst []string) ([]string, error) {
+ if r.Comma == r.Comment || !validDelim(r.Comma) || (r.Comment != 0 && !validDelim(r.Comment)) {
+ return nil, errInvalidDelim
+ }
+
+ // Read line (automatically skipping past empty lines and any comments).
+ var line []byte
+ var errRead error
+ for errRead == nil {
+ line, errRead = r.readLine()
+ if r.Comment != 0 && nextRune(line) == r.Comment {
+ line = nil
+ continue // Skip comment lines
+ }
+ if errRead == nil && len(line) == lengthNL(line) {
+ line = nil
+ continue // Skip empty lines
+ }
+ break
+ }
+ if errRead == io.EOF {
+ return nil, errRead
+ }
+
+ // Parse each field in the record.
+ var err error
+ const quoteLen = len(`"`)
+ commaLen := utf8.RuneLen(r.Comma)
+ recLine := r.numLine // Starting line for record
+ r.recordBuffer = r.recordBuffer[:0]
+ r.fieldIndexes = r.fieldIndexes[:0]
+ r.fieldPositions = r.fieldPositions[:0]
+ pos := position{line: r.numLine, col: 1}
+parseField:
+ for {
+ if r.TrimLeadingSpace {
+ i := bytes.IndexFunc(line, func(r rune) bool {
+ return !unicode.IsSpace(r)
+ })
+ if i < 0 {
+ i = len(line)
+ pos.col -= lengthNL(line)
+ }
+ line = line[i:]
+ pos.col += i
+ }
+ if len(line) == 0 || line[0] != '"' {
+ // Non-quoted string field
+ i := bytes.IndexRune(line, r.Comma)
+ field := line
+ if i >= 0 {
+ field = field[:i]
+ } else {
+ field = field[:len(field)-lengthNL(field)]
+ }
+ // Check to make sure a quote does not appear in field.
+ if !r.LazyQuotes {
+ if j := bytes.IndexByte(field, '"'); j >= 0 {
+ col := pos.col + j
+ err = &ParseError{StartLine: recLine, Line: r.numLine, Column: col, Err: ErrBareQuote}
+ break parseField
+ }
+ }
+ r.recordBuffer = append(r.recordBuffer, field...)
+ r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
+ r.fieldPositions = append(r.fieldPositions, pos)
+ if i >= 0 {
+ line = line[i+commaLen:]
+ pos.col += i + commaLen
+ continue parseField
+ }
+ break parseField
+ } else {
+ // Quoted string field
+ fieldPos := pos
+ line = line[quoteLen:]
+ pos.col += quoteLen
+ for {
+ i := bytes.IndexByte(line, '"')
+ if i >= 0 {
+ // Hit next quote.
+ r.recordBuffer = append(r.recordBuffer, line[:i]...)
+ line = line[i+quoteLen:]
+ pos.col += i + quoteLen
+ switch rn := nextRune(line); {
+ case rn == '"':
+ // `""` sequence (append quote).
+ r.recordBuffer = append(r.recordBuffer, '"')
+ line = line[quoteLen:]
+ pos.col += quoteLen
+ case rn == r.Comma:
+ // `",` sequence (end of field).
+ line = line[commaLen:]
+ pos.col += commaLen
+ r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
+ r.fieldPositions = append(r.fieldPositions, fieldPos)
+ continue parseField
+ case lengthNL(line) == len(line):
+ // `"\n` sequence (end of line).
+ r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
+ r.fieldPositions = append(r.fieldPositions, fieldPos)
+ break parseField
+ case r.LazyQuotes:
+ // `"` sequence (bare quote).
+ r.recordBuffer = append(r.recordBuffer, '"')
+ default:
+ // `"*` sequence (invalid non-escaped quote).
+ err = &ParseError{StartLine: recLine, Line: r.numLine, Column: pos.col - quoteLen, Err: ErrQuote}
+ break parseField
+ }
+ } else if len(line) > 0 {
+ // Hit end of line (copy all data so far).
+ r.recordBuffer = append(r.recordBuffer, line...)
+ if errRead != nil {
+ break parseField
+ }
+ pos.col += len(line)
+ line, errRead = r.readLine()
+ if len(line) > 0 {
+ pos.line++
+ pos.col = 1
+ }
+ if errRead == io.EOF {
+ errRead = nil
+ }
+ } else {
+ // Abrupt end of file (EOF or error).
+ if !r.LazyQuotes && errRead == nil {
+ err = &ParseError{StartLine: recLine, Line: pos.line, Column: pos.col, Err: ErrQuote}
+ break parseField
+ }
+ r.fieldIndexes = append(r.fieldIndexes, len(r.recordBuffer))
+ r.fieldPositions = append(r.fieldPositions, fieldPos)
+ break parseField
+ }
+ }
+ }
+ }
+ if err == nil {
+ err = errRead
+ }
+
+ // Create a single string and create slices out of it.
+ // This pins the memory of the fields together, but allocates once.
+ str := string(r.recordBuffer) // Convert to string once to batch allocations
+ dst = dst[:0]
+ if cap(dst) < len(r.fieldIndexes) {
+ dst = make([]string, len(r.fieldIndexes))
+ }
+ dst = dst[:len(r.fieldIndexes)]
+ var preIdx int
+ for i, idx := range r.fieldIndexes {
+ dst[i] = str[preIdx:idx]
+ preIdx = idx
+ }
+
+ // Check or update the expected fields per record.
+ if r.FieldsPerRecord > 0 {
+ if len(dst) != r.FieldsPerRecord && err == nil {
+ err = &ParseError{
+ StartLine: recLine,
+ Line: recLine,
+ Column: 1,
+ Err: ErrFieldCount,
+ }
+ }
+ } else if r.FieldsPerRecord == 0 {
+ r.FieldsPerRecord = len(dst)
+ }
+ return dst, err
+}
diff --git a/contrib/go/_std_1.20/src/encoding/csv/writer.go b/contrib/go/_std_1.21/src/encoding/csv/writer.go
index ac64b4d54c..ac64b4d54c 100644
--- a/contrib/go/_std_1.20/src/encoding/csv/writer.go
+++ b/contrib/go/_std_1.21/src/encoding/csv/writer.go
diff --git a/contrib/go/_std_1.21/src/encoding/csv/ya.make b/contrib/go/_std_1.21/src/encoding/csv/ya.make
new file mode 100644
index 0000000000..e2ae04e06e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/csv/ya.make
@@ -0,0 +1,18 @@
+GO_LIBRARY()
+
+SRCS(
+ reader.go
+ writer.go
+)
+
+GO_TEST_SRCS(
+ reader_test.go
+ writer_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/encoding/encoding.go b/contrib/go/_std_1.21/src/encoding/encoding.go
new file mode 100644
index 0000000000..50acf3c23a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/encoding.go
@@ -0,0 +1,54 @@
+// Copyright 2013 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 encoding defines interfaces shared by other packages that
+// convert data to and from byte-level and textual representations.
+// Packages that check for these interfaces include encoding/gob,
+// encoding/json, and encoding/xml. As a result, implementing an
+// interface once can make a type useful in multiple encodings.
+// Standard types that implement these interfaces include time.Time and net.IP.
+// The interfaces come in pairs that produce and consume encoded data.
+//
+// Adding encoding/decoding methods to existing types may constitute a breaking change,
+// as they can be used for serialization in communicating with programs
+// written with different library versions.
+// The policy for packages maintained by the Go project is to only allow
+// the addition of marshaling functions if no existing, reasonable marshaling exists.
+package encoding
+
+// BinaryMarshaler is the interface implemented by an object that can
+// marshal itself into a binary form.
+//
+// MarshalBinary encodes the receiver into a binary form and returns the result.
+type BinaryMarshaler interface {
+ MarshalBinary() (data []byte, err error)
+}
+
+// BinaryUnmarshaler is the interface implemented by an object that can
+// unmarshal a binary representation of itself.
+//
+// UnmarshalBinary must be able to decode the form generated by MarshalBinary.
+// UnmarshalBinary must copy the data if it wishes to retain the data
+// after returning.
+type BinaryUnmarshaler interface {
+ UnmarshalBinary(data []byte) error
+}
+
+// TextMarshaler is the interface implemented by an object that can
+// marshal itself into a textual form.
+//
+// MarshalText encodes the receiver into UTF-8-encoded text and returns the result.
+type TextMarshaler interface {
+ MarshalText() (text []byte, err error)
+}
+
+// TextUnmarshaler is the interface implemented by an object that can
+// unmarshal a textual representation of itself.
+//
+// UnmarshalText must be able to decode the form generated by MarshalText.
+// UnmarshalText must copy the text if it wishes to retain the text
+// after returning.
+type TextUnmarshaler interface {
+ UnmarshalText(text []byte) error
+}
diff --git a/contrib/go/_std_1.21/src/encoding/gob/dec_helpers.go b/contrib/go/_std_1.21/src/encoding/gob/dec_helpers.go
new file mode 100644
index 0000000000..44a74e2442
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/gob/dec_helpers.go
@@ -0,0 +1,548 @@
+// Code generated by go run decgen.go -output dec_helpers.go; DO NOT EDIT.
+
+// Copyright 2014 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 gob
+
+import (
+ "math"
+ "reflect"
+)
+
+var decArrayHelper = map[reflect.Kind]decHelper{
+ reflect.Bool: decBoolArray,
+ reflect.Complex64: decComplex64Array,
+ reflect.Complex128: decComplex128Array,
+ reflect.Float32: decFloat32Array,
+ reflect.Float64: decFloat64Array,
+ reflect.Int: decIntArray,
+ reflect.Int16: decInt16Array,
+ reflect.Int32: decInt32Array,
+ reflect.Int64: decInt64Array,
+ reflect.Int8: decInt8Array,
+ reflect.String: decStringArray,
+ reflect.Uint: decUintArray,
+ reflect.Uint16: decUint16Array,
+ reflect.Uint32: decUint32Array,
+ reflect.Uint64: decUint64Array,
+ reflect.Uintptr: decUintptrArray,
+}
+
+var decSliceHelper = map[reflect.Kind]decHelper{
+ reflect.Bool: decBoolSlice,
+ reflect.Complex64: decComplex64Slice,
+ reflect.Complex128: decComplex128Slice,
+ reflect.Float32: decFloat32Slice,
+ reflect.Float64: decFloat64Slice,
+ reflect.Int: decIntSlice,
+ reflect.Int16: decInt16Slice,
+ reflect.Int32: decInt32Slice,
+ reflect.Int64: decInt64Slice,
+ reflect.Int8: decInt8Slice,
+ reflect.String: decStringSlice,
+ reflect.Uint: decUintSlice,
+ reflect.Uint16: decUint16Slice,
+ reflect.Uint32: decUint32Slice,
+ reflect.Uint64: decUint64Slice,
+ reflect.Uintptr: decUintptrSlice,
+}
+
+func decBoolArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decBoolSlice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decBoolSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]bool)
+ if !ok {
+ // It is kind bool but not type bool. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding bool array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ slice[i] = state.decodeUint() != 0
+ }
+ return true
+}
+
+func decComplex64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decComplex64Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decComplex64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]complex64)
+ if !ok {
+ // It is kind complex64 but not type complex64. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding complex64 array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ real := float32FromBits(state.decodeUint(), ovfl)
+ imag := float32FromBits(state.decodeUint(), ovfl)
+ slice[i] = complex(float32(real), float32(imag))
+ }
+ return true
+}
+
+func decComplex128Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decComplex128Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decComplex128Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]complex128)
+ if !ok {
+ // It is kind complex128 but not type complex128. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding complex128 array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ real := float64FromBits(state.decodeUint())
+ imag := float64FromBits(state.decodeUint())
+ slice[i] = complex(real, imag)
+ }
+ return true
+}
+
+func decFloat32Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decFloat32Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decFloat32Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]float32)
+ if !ok {
+ // It is kind float32 but not type float32. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding float32 array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ slice[i] = float32(float32FromBits(state.decodeUint(), ovfl))
+ }
+ return true
+}
+
+func decFloat64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decFloat64Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decFloat64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]float64)
+ if !ok {
+ // It is kind float64 but not type float64. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding float64 array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ slice[i] = float64FromBits(state.decodeUint())
+ }
+ return true
+}
+
+func decIntArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decIntSlice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decIntSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]int)
+ if !ok {
+ // It is kind int but not type int. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding int array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ x := state.decodeInt()
+ // MinInt and MaxInt
+ if x < ^int64(^uint(0)>>1) || int64(^uint(0)>>1) < x {
+ error_(ovfl)
+ }
+ slice[i] = int(x)
+ }
+ return true
+}
+
+func decInt16Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decInt16Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decInt16Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]int16)
+ if !ok {
+ // It is kind int16 but not type int16. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding int16 array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ x := state.decodeInt()
+ if x < math.MinInt16 || math.MaxInt16 < x {
+ error_(ovfl)
+ }
+ slice[i] = int16(x)
+ }
+ return true
+}
+
+func decInt32Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decInt32Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decInt32Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]int32)
+ if !ok {
+ // It is kind int32 but not type int32. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding int32 array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ x := state.decodeInt()
+ if x < math.MinInt32 || math.MaxInt32 < x {
+ error_(ovfl)
+ }
+ slice[i] = int32(x)
+ }
+ return true
+}
+
+func decInt64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decInt64Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decInt64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]int64)
+ if !ok {
+ // It is kind int64 but not type int64. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding int64 array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ slice[i] = state.decodeInt()
+ }
+ return true
+}
+
+func decInt8Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decInt8Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decInt8Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]int8)
+ if !ok {
+ // It is kind int8 but not type int8. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding int8 array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ x := state.decodeInt()
+ if x < math.MinInt8 || math.MaxInt8 < x {
+ error_(ovfl)
+ }
+ slice[i] = int8(x)
+ }
+ return true
+}
+
+func decStringArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decStringSlice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decStringSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]string)
+ if !ok {
+ // It is kind string but not type string. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding string array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ u := state.decodeUint()
+ n := int(u)
+ if n < 0 || uint64(n) != u || n > state.b.Len() {
+ errorf("length of string exceeds input size (%d bytes)", u)
+ }
+ if n > state.b.Len() {
+ errorf("string data too long for buffer: %d", n)
+ }
+ // Read the data.
+ data := state.b.Bytes()
+ if len(data) < n {
+ errorf("invalid string length %d: exceeds input size %d", n, len(data))
+ }
+ slice[i] = string(data[:n])
+ state.b.Drop(n)
+ }
+ return true
+}
+
+func decUintArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decUintSlice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decUintSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]uint)
+ if !ok {
+ // It is kind uint but not type uint. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding uint array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ x := state.decodeUint()
+ /*TODO if math.MaxUint32 < x {
+ error_(ovfl)
+ }*/
+ slice[i] = uint(x)
+ }
+ return true
+}
+
+func decUint16Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decUint16Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decUint16Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]uint16)
+ if !ok {
+ // It is kind uint16 but not type uint16. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding uint16 array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ x := state.decodeUint()
+ if math.MaxUint16 < x {
+ error_(ovfl)
+ }
+ slice[i] = uint16(x)
+ }
+ return true
+}
+
+func decUint32Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decUint32Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decUint32Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]uint32)
+ if !ok {
+ // It is kind uint32 but not type uint32. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding uint32 array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ x := state.decodeUint()
+ if math.MaxUint32 < x {
+ error_(ovfl)
+ }
+ slice[i] = uint32(x)
+ }
+ return true
+}
+
+func decUint64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decUint64Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decUint64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]uint64)
+ if !ok {
+ // It is kind uint64 but not type uint64. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding uint64 array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ slice[i] = state.decodeUint()
+ }
+ return true
+}
+
+func decUintptrArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ // Can only slice if it is addressable.
+ if !v.CanAddr() {
+ return false
+ }
+ return decUintptrSlice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decUintptrSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+ slice, ok := v.Interface().([]uintptr)
+ if !ok {
+ // It is kind uintptr but not type uintptr. TODO: We can handle this unsafely.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding uintptr array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= len(slice) {
+ // This is a slice that we only partially allocated.
+ growSlice(v, &slice, length)
+ }
+ x := state.decodeUint()
+ if uint64(^uintptr(0)) < x {
+ error_(ovfl)
+ }
+ slice[i] = uintptr(x)
+ }
+ return true
+}
+
+// growSlice is called for a slice that we only partially allocated,
+// to grow it up to length.
+func growSlice[E any](v reflect.Value, ps *[]E, length int) {
+ var zero E
+ s := *ps
+ s = append(s, zero)
+ cp := cap(s)
+ if cp > length {
+ cp = length
+ }
+ s = s[:cp]
+ v.Set(reflect.ValueOf(s))
+ *ps = s
+}
diff --git a/contrib/go/_std_1.21/src/encoding/gob/decode.go b/contrib/go/_std_1.21/src/encoding/gob/decode.go
new file mode 100644
index 0000000000..c0b054ef80
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/gob/decode.go
@@ -0,0 +1,1306 @@
+// Copyright 2009 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.
+
+//go:generate go run decgen.go -output dec_helpers.go
+
+package gob
+
+import (
+ "encoding"
+ "errors"
+ "internal/saferio"
+ "io"
+ "math"
+ "math/bits"
+ "reflect"
+)
+
+var (
+ errBadUint = errors.New("gob: encoded unsigned integer out of range")
+ errBadType = errors.New("gob: unknown type id or corrupted data")
+ errRange = errors.New("gob: bad data: field numbers out of bounds")
+)
+
+type decHelper func(state *decoderState, v reflect.Value, length int, ovfl error) bool
+
+// decoderState is the execution state of an instance of the decoder. A new state
+// is created for nested objects.
+type decoderState struct {
+ dec *Decoder
+ // The buffer is stored with an extra indirection because it may be replaced
+ // if we load a type during decode (when reading an interface value).
+ b *decBuffer
+ fieldnum int // the last field number read.
+ next *decoderState // for free list
+}
+
+// decBuffer is an extremely simple, fast implementation of a read-only byte buffer.
+// It is initialized by calling Size and then copying the data into the slice returned by Bytes().
+type decBuffer struct {
+ data []byte
+ offset int // Read offset.
+}
+
+func (d *decBuffer) Read(p []byte) (int, error) {
+ n := copy(p, d.data[d.offset:])
+ if n == 0 && len(p) != 0 {
+ return 0, io.EOF
+ }
+ d.offset += n
+ return n, nil
+}
+
+func (d *decBuffer) Drop(n int) {
+ if n > d.Len() {
+ panic("drop")
+ }
+ d.offset += n
+}
+
+func (d *decBuffer) ReadByte() (byte, error) {
+ if d.offset >= len(d.data) {
+ return 0, io.EOF
+ }
+ c := d.data[d.offset]
+ d.offset++
+ return c, nil
+}
+
+func (d *decBuffer) Len() int {
+ return len(d.data) - d.offset
+}
+
+func (d *decBuffer) Bytes() []byte {
+ return d.data[d.offset:]
+}
+
+// SetBytes sets the buffer to the bytes, discarding any existing data.
+func (d *decBuffer) SetBytes(data []byte) {
+ d.data = data
+ d.offset = 0
+}
+
+func (d *decBuffer) Reset() {
+ d.data = d.data[0:0]
+ d.offset = 0
+}
+
+// We pass the bytes.Buffer separately for easier testing of the infrastructure
+// without requiring a full Decoder.
+func (dec *Decoder) newDecoderState(buf *decBuffer) *decoderState {
+ d := dec.freeList
+ if d == nil {
+ d = new(decoderState)
+ d.dec = dec
+ } else {
+ dec.freeList = d.next
+ }
+ d.b = buf
+ return d
+}
+
+func (dec *Decoder) freeDecoderState(d *decoderState) {
+ d.next = dec.freeList
+ dec.freeList = d
+}
+
+func overflow(name string) error {
+ return errors.New(`value for "` + name + `" out of range`)
+}
+
+// decodeUintReader reads an encoded unsigned integer from an io.Reader.
+// Used only by the Decoder to read the message length.
+func decodeUintReader(r io.Reader, buf []byte) (x uint64, width int, err error) {
+ width = 1
+ n, err := io.ReadFull(r, buf[0:width])
+ if n == 0 {
+ return
+ }
+ b := buf[0]
+ if b <= 0x7f {
+ return uint64(b), width, nil
+ }
+ n = -int(int8(b))
+ if n > uint64Size {
+ err = errBadUint
+ return
+ }
+ width, err = io.ReadFull(r, buf[0:n])
+ if err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return
+ }
+ // Could check that the high byte is zero but it's not worth it.
+ for _, b := range buf[0:width] {
+ x = x<<8 | uint64(b)
+ }
+ width++ // +1 for length byte
+ return
+}
+
+// decodeUint reads an encoded unsigned integer from state.r.
+// Does not check for overflow.
+func (state *decoderState) decodeUint() (x uint64) {
+ b, err := state.b.ReadByte()
+ if err != nil {
+ error_(err)
+ }
+ if b <= 0x7f {
+ return uint64(b)
+ }
+ n := -int(int8(b))
+ if n > uint64Size {
+ error_(errBadUint)
+ }
+ buf := state.b.Bytes()
+ if len(buf) < n {
+ errorf("invalid uint data length %d: exceeds input size %d", n, len(buf))
+ }
+ // Don't need to check error; it's safe to loop regardless.
+ // Could check that the high byte is zero but it's not worth it.
+ for _, b := range buf[0:n] {
+ x = x<<8 | uint64(b)
+ }
+ state.b.Drop(n)
+ return x
+}
+
+// decodeInt reads an encoded signed integer from state.r.
+// Does not check for overflow.
+func (state *decoderState) decodeInt() int64 {
+ x := state.decodeUint()
+ if x&1 != 0 {
+ return ^int64(x >> 1)
+ }
+ return int64(x >> 1)
+}
+
+// getLength decodes the next uint and makes sure it is a possible
+// size for a data item that follows, which means it must fit in a
+// non-negative int and fit in the buffer.
+func (state *decoderState) getLength() (int, bool) {
+ n := int(state.decodeUint())
+ if n < 0 || state.b.Len() < n || tooBig <= n {
+ return 0, false
+ }
+ return n, true
+}
+
+// decOp is the signature of a decoding operator for a given type.
+type decOp func(i *decInstr, state *decoderState, v reflect.Value)
+
+// The 'instructions' of the decoding machine
+type decInstr struct {
+ op decOp
+ field int // field number of the wire type
+ index []int // field access indices for destination type
+ ovfl error // error message for overflow/underflow (for arrays, of the elements)
+}
+
+// ignoreUint discards a uint value with no destination.
+func ignoreUint(i *decInstr, state *decoderState, v reflect.Value) {
+ state.decodeUint()
+}
+
+// ignoreTwoUints discards a uint value with no destination. It's used to skip
+// complex values.
+func ignoreTwoUints(i *decInstr, state *decoderState, v reflect.Value) {
+ state.decodeUint()
+ state.decodeUint()
+}
+
+// Since the encoder writes no zeros, if we arrive at a decoder we have
+// a value to extract and store. The field number has already been read
+// (it's how we knew to call this decoder).
+// Each decoder is responsible for handling any indirections associated
+// with the data structure. If any pointer so reached is nil, allocation must
+// be done.
+
+// decAlloc takes a value and returns a settable value that can
+// be assigned to. If the value is a pointer, decAlloc guarantees it points to storage.
+// The callers to the individual decoders are expected to have used decAlloc.
+// The individual decoders don't need to it.
+func decAlloc(v reflect.Value) reflect.Value {
+ for v.Kind() == reflect.Pointer {
+ if v.IsNil() {
+ v.Set(reflect.New(v.Type().Elem()))
+ }
+ v = v.Elem()
+ }
+ return v
+}
+
+// decBool decodes a uint and stores it as a boolean in value.
+func decBool(i *decInstr, state *decoderState, value reflect.Value) {
+ value.SetBool(state.decodeUint() != 0)
+}
+
+// decInt8 decodes an integer and stores it as an int8 in value.
+func decInt8(i *decInstr, state *decoderState, value reflect.Value) {
+ v := state.decodeInt()
+ if v < math.MinInt8 || math.MaxInt8 < v {
+ error_(i.ovfl)
+ }
+ value.SetInt(v)
+}
+
+// decUint8 decodes an unsigned integer and stores it as a uint8 in value.
+func decUint8(i *decInstr, state *decoderState, value reflect.Value) {
+ v := state.decodeUint()
+ if math.MaxUint8 < v {
+ error_(i.ovfl)
+ }
+ value.SetUint(v)
+}
+
+// decInt16 decodes an integer and stores it as an int16 in value.
+func decInt16(i *decInstr, state *decoderState, value reflect.Value) {
+ v := state.decodeInt()
+ if v < math.MinInt16 || math.MaxInt16 < v {
+ error_(i.ovfl)
+ }
+ value.SetInt(v)
+}
+
+// decUint16 decodes an unsigned integer and stores it as a uint16 in value.
+func decUint16(i *decInstr, state *decoderState, value reflect.Value) {
+ v := state.decodeUint()
+ if math.MaxUint16 < v {
+ error_(i.ovfl)
+ }
+ value.SetUint(v)
+}
+
+// decInt32 decodes an integer and stores it as an int32 in value.
+func decInt32(i *decInstr, state *decoderState, value reflect.Value) {
+ v := state.decodeInt()
+ if v < math.MinInt32 || math.MaxInt32 < v {
+ error_(i.ovfl)
+ }
+ value.SetInt(v)
+}
+
+// decUint32 decodes an unsigned integer and stores it as a uint32 in value.
+func decUint32(i *decInstr, state *decoderState, value reflect.Value) {
+ v := state.decodeUint()
+ if math.MaxUint32 < v {
+ error_(i.ovfl)
+ }
+ value.SetUint(v)
+}
+
+// decInt64 decodes an integer and stores it as an int64 in value.
+func decInt64(i *decInstr, state *decoderState, value reflect.Value) {
+ v := state.decodeInt()
+ value.SetInt(v)
+}
+
+// decUint64 decodes an unsigned integer and stores it as a uint64 in value.
+func decUint64(i *decInstr, state *decoderState, value reflect.Value) {
+ v := state.decodeUint()
+ value.SetUint(v)
+}
+
+// Floating-point numbers are transmitted as uint64s holding the bits
+// of the underlying representation. They are sent byte-reversed, with
+// the exponent end coming out first, so integer floating point numbers
+// (for example) transmit more compactly. This routine does the
+// unswizzling.
+func float64FromBits(u uint64) float64 {
+ v := bits.ReverseBytes64(u)
+ return math.Float64frombits(v)
+}
+
+// float32FromBits decodes an unsigned integer, treats it as a 32-bit floating-point
+// number, and returns it. It's a helper function for float32 and complex64.
+// It returns a float64 because that's what reflection needs, but its return
+// value is known to be accurately representable in a float32.
+func float32FromBits(u uint64, ovfl error) float64 {
+ v := float64FromBits(u)
+ av := v
+ if av < 0 {
+ av = -av
+ }
+ // +Inf is OK in both 32- and 64-bit floats. Underflow is always OK.
+ if math.MaxFloat32 < av && av <= math.MaxFloat64 {
+ error_(ovfl)
+ }
+ return v
+}
+
+// decFloat32 decodes an unsigned integer, treats it as a 32-bit floating-point
+// number, and stores it in value.
+func decFloat32(i *decInstr, state *decoderState, value reflect.Value) {
+ value.SetFloat(float32FromBits(state.decodeUint(), i.ovfl))
+}
+
+// decFloat64 decodes an unsigned integer, treats it as a 64-bit floating-point
+// number, and stores it in value.
+func decFloat64(i *decInstr, state *decoderState, value reflect.Value) {
+ value.SetFloat(float64FromBits(state.decodeUint()))
+}
+
+// decComplex64 decodes a pair of unsigned integers, treats them as a
+// pair of floating point numbers, and stores them as a complex64 in value.
+// The real part comes first.
+func decComplex64(i *decInstr, state *decoderState, value reflect.Value) {
+ real := float32FromBits(state.decodeUint(), i.ovfl)
+ imag := float32FromBits(state.decodeUint(), i.ovfl)
+ value.SetComplex(complex(real, imag))
+}
+
+// decComplex128 decodes a pair of unsigned integers, treats them as a
+// pair of floating point numbers, and stores them as a complex128 in value.
+// The real part comes first.
+func decComplex128(i *decInstr, state *decoderState, value reflect.Value) {
+ real := float64FromBits(state.decodeUint())
+ imag := float64FromBits(state.decodeUint())
+ value.SetComplex(complex(real, imag))
+}
+
+// decUint8Slice decodes a byte slice and stores in value a slice header
+// describing the data.
+// uint8 slices are encoded as an unsigned count followed by the raw bytes.
+func decUint8Slice(i *decInstr, state *decoderState, value reflect.Value) {
+ n, ok := state.getLength()
+ if !ok {
+ errorf("bad %s slice length: %d", value.Type(), n)
+ }
+ if value.Cap() < n {
+ safe := saferio.SliceCap((*byte)(nil), uint64(n))
+ if safe < 0 {
+ errorf("%s slice too big: %d elements", value.Type(), n)
+ }
+ value.Set(reflect.MakeSlice(value.Type(), safe, safe))
+ ln := safe
+ i := 0
+ for i < n {
+ if i >= ln {
+ // We didn't allocate the entire slice,
+ // due to using saferio.SliceCap.
+ // Grow the slice for one more element.
+ // The slice is full, so this should
+ // bump up the capacity.
+ value.Grow(1)
+ }
+ // Copy into s up to the capacity or n,
+ // whichever is less.
+ ln = value.Cap()
+ if ln > n {
+ ln = n
+ }
+ value.SetLen(ln)
+ sub := value.Slice(i, ln)
+ if _, err := state.b.Read(sub.Bytes()); err != nil {
+ errorf("error decoding []byte at %d: %s", err, i)
+ }
+ i = ln
+ }
+ } else {
+ value.SetLen(n)
+ if _, err := state.b.Read(value.Bytes()); err != nil {
+ errorf("error decoding []byte: %s", err)
+ }
+ }
+}
+
+// decString decodes byte array and stores in value a string header
+// describing the data.
+// Strings are encoded as an unsigned count followed by the raw bytes.
+func decString(i *decInstr, state *decoderState, value reflect.Value) {
+ n, ok := state.getLength()
+ if !ok {
+ errorf("bad %s slice length: %d", value.Type(), n)
+ }
+ // Read the data.
+ data := state.b.Bytes()
+ if len(data) < n {
+ errorf("invalid string length %d: exceeds input size %d", n, len(data))
+ }
+ s := string(data[:n])
+ state.b.Drop(n)
+ value.SetString(s)
+}
+
+// ignoreUint8Array skips over the data for a byte slice value with no destination.
+func ignoreUint8Array(i *decInstr, state *decoderState, value reflect.Value) {
+ n, ok := state.getLength()
+ if !ok {
+ errorf("slice length too large")
+ }
+ bn := state.b.Len()
+ if bn < n {
+ errorf("invalid slice length %d: exceeds input size %d", n, bn)
+ }
+ state.b.Drop(n)
+}
+
+// Execution engine
+
+// The encoder engine is an array of instructions indexed by field number of the incoming
+// decoder. It is executed with random access according to field number.
+type decEngine struct {
+ instr []decInstr
+ numInstr int // the number of active instructions
+}
+
+// decodeSingle decodes a top-level value that is not a struct and stores it in value.
+// Such values are preceded by a zero, making them have the memory layout of a
+// struct field (although with an illegal field number).
+func (dec *Decoder) decodeSingle(engine *decEngine, value reflect.Value) {
+ state := dec.newDecoderState(&dec.buf)
+ defer dec.freeDecoderState(state)
+ state.fieldnum = singletonField
+ if state.decodeUint() != 0 {
+ errorf("decode: corrupted data: non-zero delta for singleton")
+ }
+ instr := &engine.instr[singletonField]
+ instr.op(instr, state, value)
+}
+
+// decodeStruct decodes a top-level struct and stores it in value.
+// Indir is for the value, not the type. At the time of the call it may
+// differ from ut.indir, which was computed when the engine was built.
+// This state cannot arise for decodeSingle, which is called directly
+// from the user's value, not from the innards of an engine.
+func (dec *Decoder) decodeStruct(engine *decEngine, value reflect.Value) {
+ state := dec.newDecoderState(&dec.buf)
+ defer dec.freeDecoderState(state)
+ state.fieldnum = -1
+ for state.b.Len() > 0 {
+ delta := int(state.decodeUint())
+ if delta < 0 {
+ errorf("decode: corrupted data: negative delta")
+ }
+ if delta == 0 { // struct terminator is zero delta fieldnum
+ break
+ }
+ if state.fieldnum >= len(engine.instr)-delta { // subtract to compare without overflow
+ error_(errRange)
+ }
+ fieldnum := state.fieldnum + delta
+ instr := &engine.instr[fieldnum]
+ var field reflect.Value
+ if instr.index != nil {
+ // Otherwise the field is unknown to us and instr.op is an ignore op.
+ field = value.FieldByIndex(instr.index)
+ if field.Kind() == reflect.Pointer {
+ field = decAlloc(field)
+ }
+ }
+ instr.op(instr, state, field)
+ state.fieldnum = fieldnum
+ }
+}
+
+var noValue reflect.Value
+
+// ignoreStruct discards the data for a struct with no destination.
+func (dec *Decoder) ignoreStruct(engine *decEngine) {
+ state := dec.newDecoderState(&dec.buf)
+ defer dec.freeDecoderState(state)
+ state.fieldnum = -1
+ for state.b.Len() > 0 {
+ delta := int(state.decodeUint())
+ if delta < 0 {
+ errorf("ignore decode: corrupted data: negative delta")
+ }
+ if delta == 0 { // struct terminator is zero delta fieldnum
+ break
+ }
+ fieldnum := state.fieldnum + delta
+ if fieldnum >= len(engine.instr) {
+ error_(errRange)
+ }
+ instr := &engine.instr[fieldnum]
+ instr.op(instr, state, noValue)
+ state.fieldnum = fieldnum
+ }
+}
+
+// ignoreSingle discards the data for a top-level non-struct value with no
+// destination. It's used when calling Decode with a nil value.
+func (dec *Decoder) ignoreSingle(engine *decEngine) {
+ state := dec.newDecoderState(&dec.buf)
+ defer dec.freeDecoderState(state)
+ state.fieldnum = singletonField
+ delta := int(state.decodeUint())
+ if delta != 0 {
+ errorf("decode: corrupted data: non-zero delta for singleton")
+ }
+ instr := &engine.instr[singletonField]
+ instr.op(instr, state, noValue)
+}
+
+// decodeArrayHelper does the work for decoding arrays and slices.
+func (dec *Decoder) decodeArrayHelper(state *decoderState, value reflect.Value, elemOp decOp, length int, ovfl error, helper decHelper) {
+ if helper != nil && helper(state, value, length, ovfl) {
+ return
+ }
+ instr := &decInstr{elemOp, 0, nil, ovfl}
+ isPtr := value.Type().Elem().Kind() == reflect.Pointer
+ ln := value.Len()
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding array or slice: length exceeds input size (%d elements)", length)
+ }
+ if i >= ln {
+ // This is a slice that we only partially allocated.
+ // Grow it up to length.
+ value.Grow(1)
+ cp := value.Cap()
+ if cp > length {
+ cp = length
+ }
+ value.SetLen(cp)
+ ln = cp
+ }
+ v := value.Index(i)
+ if isPtr {
+ v = decAlloc(v)
+ }
+ elemOp(instr, state, v)
+ }
+}
+
+// decodeArray decodes an array and stores it in value.
+// The length is an unsigned integer preceding the elements. Even though the length is redundant
+// (it's part of the type), it's a useful check and is included in the encoding.
+func (dec *Decoder) decodeArray(state *decoderState, value reflect.Value, elemOp decOp, length int, ovfl error, helper decHelper) {
+ if n := state.decodeUint(); n != uint64(length) {
+ errorf("length mismatch in decodeArray")
+ }
+ dec.decodeArrayHelper(state, value, elemOp, length, ovfl, helper)
+}
+
+// decodeIntoValue is a helper for map decoding.
+func decodeIntoValue(state *decoderState, op decOp, isPtr bool, value reflect.Value, instr *decInstr) reflect.Value {
+ v := value
+ if isPtr {
+ v = decAlloc(value)
+ }
+
+ op(instr, state, v)
+ return value
+}
+
+// decodeMap decodes a map and stores it in value.
+// Maps are encoded as a length followed by key:value pairs.
+// Because the internals of maps are not visible to us, we must
+// use reflection rather than pointer magic.
+func (dec *Decoder) decodeMap(mtyp reflect.Type, state *decoderState, value reflect.Value, keyOp, elemOp decOp, ovfl error) {
+ n := int(state.decodeUint())
+ if value.IsNil() {
+ value.Set(reflect.MakeMapWithSize(mtyp, n))
+ }
+ keyIsPtr := mtyp.Key().Kind() == reflect.Pointer
+ elemIsPtr := mtyp.Elem().Kind() == reflect.Pointer
+ keyInstr := &decInstr{keyOp, 0, nil, ovfl}
+ elemInstr := &decInstr{elemOp, 0, nil, ovfl}
+ keyP := reflect.New(mtyp.Key())
+ elemP := reflect.New(mtyp.Elem())
+ for i := 0; i < n; i++ {
+ key := decodeIntoValue(state, keyOp, keyIsPtr, keyP.Elem(), keyInstr)
+ elem := decodeIntoValue(state, elemOp, elemIsPtr, elemP.Elem(), elemInstr)
+ value.SetMapIndex(key, elem)
+ keyP.Elem().SetZero()
+ elemP.Elem().SetZero()
+ }
+}
+
+// ignoreArrayHelper does the work for discarding arrays and slices.
+func (dec *Decoder) ignoreArrayHelper(state *decoderState, elemOp decOp, length int) {
+ instr := &decInstr{elemOp, 0, nil, errors.New("no error")}
+ for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding array or slice: length exceeds input size (%d elements)", length)
+ }
+ elemOp(instr, state, noValue)
+ }
+}
+
+// ignoreArray discards the data for an array value with no destination.
+func (dec *Decoder) ignoreArray(state *decoderState, elemOp decOp, length int) {
+ if n := state.decodeUint(); n != uint64(length) {
+ errorf("length mismatch in ignoreArray")
+ }
+ dec.ignoreArrayHelper(state, elemOp, length)
+}
+
+// ignoreMap discards the data for a map value with no destination.
+func (dec *Decoder) ignoreMap(state *decoderState, keyOp, elemOp decOp) {
+ n := int(state.decodeUint())
+ keyInstr := &decInstr{keyOp, 0, nil, errors.New("no error")}
+ elemInstr := &decInstr{elemOp, 0, nil, errors.New("no error")}
+ for i := 0; i < n; i++ {
+ keyOp(keyInstr, state, noValue)
+ elemOp(elemInstr, state, noValue)
+ }
+}
+
+// decodeSlice decodes a slice and stores it in value.
+// Slices are encoded as an unsigned length followed by the elements.
+func (dec *Decoder) decodeSlice(state *decoderState, value reflect.Value, elemOp decOp, ovfl error, helper decHelper) {
+ u := state.decodeUint()
+ typ := value.Type()
+ size := uint64(typ.Elem().Size())
+ nBytes := u * size
+ n := int(u)
+ // Take care with overflow in this calculation.
+ if n < 0 || uint64(n) != u || nBytes > tooBig || (size > 0 && nBytes/size != u) {
+ // We don't check n against buffer length here because if it's a slice
+ // of interfaces, there will be buffer reloads.
+ errorf("%s slice too big: %d elements of %d bytes", typ.Elem(), u, size)
+ }
+ if value.Cap() < n {
+ safe := saferio.SliceCap(reflect.Zero(reflect.PtrTo(typ.Elem())).Interface(), uint64(n))
+ if safe < 0 {
+ errorf("%s slice too big: %d elements of %d bytes", typ.Elem(), u, size)
+ }
+ value.Set(reflect.MakeSlice(typ, safe, safe))
+ } else {
+ value.SetLen(n)
+ }
+ dec.decodeArrayHelper(state, value, elemOp, n, ovfl, helper)
+}
+
+// ignoreSlice skips over the data for a slice value with no destination.
+func (dec *Decoder) ignoreSlice(state *decoderState, elemOp decOp) {
+ dec.ignoreArrayHelper(state, elemOp, int(state.decodeUint()))
+}
+
+// decodeInterface decodes an interface value and stores it in value.
+// Interfaces are encoded as the name of a concrete type followed by a value.
+// If the name is empty, the value is nil and no value is sent.
+func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, value reflect.Value) {
+ // Read the name of the concrete type.
+ nr := state.decodeUint()
+ if nr > 1<<31 { // zero is permissible for anonymous types
+ errorf("invalid type name length %d", nr)
+ }
+ if nr > uint64(state.b.Len()) {
+ errorf("invalid type name length %d: exceeds input size", nr)
+ }
+ n := int(nr)
+ name := state.b.Bytes()[:n]
+ state.b.Drop(n)
+ // Allocate the destination interface value.
+ if len(name) == 0 {
+ // Copy the nil interface value to the target.
+ value.SetZero()
+ return
+ }
+ if len(name) > 1024 {
+ errorf("name too long (%d bytes): %.20q...", len(name), name)
+ }
+ // The concrete type must be registered.
+ typi, ok := nameToConcreteType.Load(string(name))
+ if !ok {
+ errorf("name not registered for interface: %q", name)
+ }
+ typ := typi.(reflect.Type)
+
+ // Read the type id of the concrete value.
+ concreteId := dec.decodeTypeSequence(true)
+ if concreteId < 0 {
+ error_(dec.err)
+ }
+ // Byte count of value is next; we don't care what it is (it's there
+ // in case we want to ignore the value by skipping it completely).
+ state.decodeUint()
+ // Read the concrete value.
+ v := allocValue(typ)
+ dec.decodeValue(concreteId, v)
+ if dec.err != nil {
+ error_(dec.err)
+ }
+ // Assign the concrete value to the interface.
+ // Tread carefully; it might not satisfy the interface.
+ if !typ.AssignableTo(ityp) {
+ errorf("%s is not assignable to type %s", typ, ityp)
+ }
+ // Copy the interface value to the target.
+ value.Set(v)
+}
+
+// ignoreInterface discards the data for an interface value with no destination.
+func (dec *Decoder) ignoreInterface(state *decoderState) {
+ // Read the name of the concrete type.
+ n, ok := state.getLength()
+ if !ok {
+ errorf("bad interface encoding: name too large for buffer")
+ }
+ bn := state.b.Len()
+ if bn < n {
+ errorf("invalid interface value length %d: exceeds input size %d", n, bn)
+ }
+ state.b.Drop(n)
+ id := dec.decodeTypeSequence(true)
+ if id < 0 {
+ error_(dec.err)
+ }
+ // At this point, the decoder buffer contains a delimited value. Just toss it.
+ n, ok = state.getLength()
+ if !ok {
+ errorf("bad interface encoding: data length too large for buffer")
+ }
+ state.b.Drop(n)
+}
+
+// decodeGobDecoder decodes something implementing the GobDecoder interface.
+// The data is encoded as a byte slice.
+func (dec *Decoder) decodeGobDecoder(ut *userTypeInfo, state *decoderState, value reflect.Value) {
+ // Read the bytes for the value.
+ n, ok := state.getLength()
+ if !ok {
+ errorf("GobDecoder: length too large for buffer")
+ }
+ b := state.b.Bytes()
+ if len(b) < n {
+ errorf("GobDecoder: invalid data length %d: exceeds input size %d", n, len(b))
+ }
+ b = b[:n]
+ state.b.Drop(n)
+ var err error
+ // We know it's one of these.
+ switch ut.externalDec {
+ case xGob:
+ err = value.Interface().(GobDecoder).GobDecode(b)
+ case xBinary:
+ err = value.Interface().(encoding.BinaryUnmarshaler).UnmarshalBinary(b)
+ case xText:
+ err = value.Interface().(encoding.TextUnmarshaler).UnmarshalText(b)
+ }
+ if err != nil {
+ error_(err)
+ }
+}
+
+// ignoreGobDecoder discards the data for a GobDecoder value with no destination.
+func (dec *Decoder) ignoreGobDecoder(state *decoderState) {
+ // Read the bytes for the value.
+ n, ok := state.getLength()
+ if !ok {
+ errorf("GobDecoder: length too large for buffer")
+ }
+ bn := state.b.Len()
+ if bn < n {
+ errorf("GobDecoder: invalid data length %d: exceeds input size %d", n, bn)
+ }
+ state.b.Drop(n)
+}
+
+// Index by Go types.
+var decOpTable = [...]decOp{
+ reflect.Bool: decBool,
+ reflect.Int8: decInt8,
+ reflect.Int16: decInt16,
+ reflect.Int32: decInt32,
+ reflect.Int64: decInt64,
+ reflect.Uint8: decUint8,
+ reflect.Uint16: decUint16,
+ reflect.Uint32: decUint32,
+ reflect.Uint64: decUint64,
+ reflect.Float32: decFloat32,
+ reflect.Float64: decFloat64,
+ reflect.Complex64: decComplex64,
+ reflect.Complex128: decComplex128,
+ reflect.String: decString,
+}
+
+// Indexed by gob types. tComplex will be added during type.init().
+var decIgnoreOpMap = map[typeId]decOp{
+ tBool: ignoreUint,
+ tInt: ignoreUint,
+ tUint: ignoreUint,
+ tFloat: ignoreUint,
+ tBytes: ignoreUint8Array,
+ tString: ignoreUint8Array,
+ tComplex: ignoreTwoUints,
+}
+
+// decOpFor returns the decoding op for the base type under rt and
+// the indirection count to reach it.
+func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProgress map[reflect.Type]*decOp) *decOp {
+ ut := userType(rt)
+ // If the type implements GobEncoder, we handle it without further processing.
+ if ut.externalDec != 0 {
+ return dec.gobDecodeOpFor(ut)
+ }
+
+ // If this type is already in progress, it's a recursive type (e.g. map[string]*T).
+ // Return the pointer to the op we're already building.
+ if opPtr := inProgress[rt]; opPtr != nil {
+ return opPtr
+ }
+ typ := ut.base
+ var op decOp
+ k := typ.Kind()
+ if int(k) < len(decOpTable) {
+ op = decOpTable[k]
+ }
+ if op == nil {
+ inProgress[rt] = &op
+ // Special cases
+ switch t := typ; t.Kind() {
+ case reflect.Array:
+ name = "element of " + name
+ elemId := dec.wireType[wireId].ArrayT.Elem
+ elemOp := dec.decOpFor(elemId, t.Elem(), name, inProgress)
+ ovfl := overflow(name)
+ helper := decArrayHelper[t.Elem().Kind()]
+ op = func(i *decInstr, state *decoderState, value reflect.Value) {
+ state.dec.decodeArray(state, value, *elemOp, t.Len(), ovfl, helper)
+ }
+
+ case reflect.Map:
+ keyId := dec.wireType[wireId].MapT.Key
+ elemId := dec.wireType[wireId].MapT.Elem
+ keyOp := dec.decOpFor(keyId, t.Key(), "key of "+name, inProgress)
+ elemOp := dec.decOpFor(elemId, t.Elem(), "element of "+name, inProgress)
+ ovfl := overflow(name)
+ op = func(i *decInstr, state *decoderState, value reflect.Value) {
+ state.dec.decodeMap(t, state, value, *keyOp, *elemOp, ovfl)
+ }
+
+ case reflect.Slice:
+ name = "element of " + name
+ if t.Elem().Kind() == reflect.Uint8 {
+ op = decUint8Slice
+ break
+ }
+ var elemId typeId
+ if tt := builtinIdToType(wireId); tt != nil {
+ elemId = tt.(*sliceType).Elem
+ } else {
+ elemId = dec.wireType[wireId].SliceT.Elem
+ }
+ elemOp := dec.decOpFor(elemId, t.Elem(), name, inProgress)
+ ovfl := overflow(name)
+ helper := decSliceHelper[t.Elem().Kind()]
+ op = func(i *decInstr, state *decoderState, value reflect.Value) {
+ state.dec.decodeSlice(state, value, *elemOp, ovfl, helper)
+ }
+
+ case reflect.Struct:
+ // Generate a closure that calls out to the engine for the nested type.
+ ut := userType(typ)
+ enginePtr, err := dec.getDecEnginePtr(wireId, ut)
+ if err != nil {
+ error_(err)
+ }
+ op = func(i *decInstr, state *decoderState, value reflect.Value) {
+ // indirect through enginePtr to delay evaluation for recursive structs.
+ dec.decodeStruct(*enginePtr, value)
+ }
+ case reflect.Interface:
+ op = func(i *decInstr, state *decoderState, value reflect.Value) {
+ state.dec.decodeInterface(t, state, value)
+ }
+ }
+ }
+ if op == nil {
+ errorf("decode can't handle type %s", rt)
+ }
+ return &op
+}
+
+var maxIgnoreNestingDepth = 10000
+
+// decIgnoreOpFor returns the decoding op for a field that has no destination.
+func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp, depth int) *decOp {
+ if depth > maxIgnoreNestingDepth {
+ error_(errors.New("invalid nesting depth"))
+ }
+ // If this type is already in progress, it's a recursive type (e.g. map[string]*T).
+ // Return the pointer to the op we're already building.
+ if opPtr := inProgress[wireId]; opPtr != nil {
+ return opPtr
+ }
+ op, ok := decIgnoreOpMap[wireId]
+ if !ok {
+ inProgress[wireId] = &op
+ if wireId == tInterface {
+ // Special case because it's a method: the ignored item might
+ // define types and we need to record their state in the decoder.
+ op = func(i *decInstr, state *decoderState, value reflect.Value) {
+ state.dec.ignoreInterface(state)
+ }
+ return &op
+ }
+ // Special cases
+ wire := dec.wireType[wireId]
+ switch {
+ case wire == nil:
+ errorf("bad data: undefined type %s", wireId.string())
+ case wire.ArrayT != nil:
+ elemId := wire.ArrayT.Elem
+ elemOp := dec.decIgnoreOpFor(elemId, inProgress, depth+1)
+ op = func(i *decInstr, state *decoderState, value reflect.Value) {
+ state.dec.ignoreArray(state, *elemOp, wire.ArrayT.Len)
+ }
+
+ case wire.MapT != nil:
+ keyId := dec.wireType[wireId].MapT.Key
+ elemId := dec.wireType[wireId].MapT.Elem
+ keyOp := dec.decIgnoreOpFor(keyId, inProgress, depth+1)
+ elemOp := dec.decIgnoreOpFor(elemId, inProgress, depth+1)
+ op = func(i *decInstr, state *decoderState, value reflect.Value) {
+ state.dec.ignoreMap(state, *keyOp, *elemOp)
+ }
+
+ case wire.SliceT != nil:
+ elemId := wire.SliceT.Elem
+ elemOp := dec.decIgnoreOpFor(elemId, inProgress, depth+1)
+ op = func(i *decInstr, state *decoderState, value reflect.Value) {
+ state.dec.ignoreSlice(state, *elemOp)
+ }
+
+ case wire.StructT != nil:
+ // Generate a closure that calls out to the engine for the nested type.
+ enginePtr, err := dec.getIgnoreEnginePtr(wireId)
+ if err != nil {
+ error_(err)
+ }
+ op = func(i *decInstr, state *decoderState, value reflect.Value) {
+ // indirect through enginePtr to delay evaluation for recursive structs
+ state.dec.ignoreStruct(*enginePtr)
+ }
+
+ case wire.GobEncoderT != nil, wire.BinaryMarshalerT != nil, wire.TextMarshalerT != nil:
+ op = func(i *decInstr, state *decoderState, value reflect.Value) {
+ state.dec.ignoreGobDecoder(state)
+ }
+ }
+ }
+ if op == nil {
+ errorf("bad data: ignore can't handle type %s", wireId.string())
+ }
+ return &op
+}
+
+// gobDecodeOpFor returns the op for a type that is known to implement
+// GobDecoder.
+func (dec *Decoder) gobDecodeOpFor(ut *userTypeInfo) *decOp {
+ rcvrType := ut.user
+ if ut.decIndir == -1 {
+ rcvrType = reflect.PointerTo(rcvrType)
+ } else if ut.decIndir > 0 {
+ for i := int8(0); i < ut.decIndir; i++ {
+ rcvrType = rcvrType.Elem()
+ }
+ }
+ var op decOp
+ op = func(i *decInstr, state *decoderState, value reflect.Value) {
+ // We now have the base type. We need its address if the receiver is a pointer.
+ if value.Kind() != reflect.Pointer && rcvrType.Kind() == reflect.Pointer {
+ value = value.Addr()
+ }
+ state.dec.decodeGobDecoder(ut, state, value)
+ }
+ return &op
+}
+
+// compatibleType asks: Are these two gob Types compatible?
+// Answers the question for basic types, arrays, maps and slices, plus
+// GobEncoder/Decoder pairs.
+// Structs are considered ok; fields will be checked later.
+func (dec *Decoder) compatibleType(fr reflect.Type, fw typeId, inProgress map[reflect.Type]typeId) bool {
+ if rhs, ok := inProgress[fr]; ok {
+ return rhs == fw
+ }
+ inProgress[fr] = fw
+ ut := userType(fr)
+ wire, ok := dec.wireType[fw]
+ // If wire was encoded with an encoding method, fr must have that method.
+ // And if not, it must not.
+ // At most one of the booleans in ut is set.
+ // We could possibly relax this constraint in the future in order to
+ // choose the decoding method using the data in the wireType.
+ // The parentheses look odd but are correct.
+ if (ut.externalDec == xGob) != (ok && wire.GobEncoderT != nil) ||
+ (ut.externalDec == xBinary) != (ok && wire.BinaryMarshalerT != nil) ||
+ (ut.externalDec == xText) != (ok && wire.TextMarshalerT != nil) {
+ return false
+ }
+ if ut.externalDec != 0 { // This test trumps all others.
+ return true
+ }
+ switch t := ut.base; t.Kind() {
+ default:
+ // chan, etc: cannot handle.
+ return false
+ case reflect.Bool:
+ return fw == tBool
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return fw == tInt
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return fw == tUint
+ case reflect.Float32, reflect.Float64:
+ return fw == tFloat
+ case reflect.Complex64, reflect.Complex128:
+ return fw == tComplex
+ case reflect.String:
+ return fw == tString
+ case reflect.Interface:
+ return fw == tInterface
+ case reflect.Array:
+ if !ok || wire.ArrayT == nil {
+ return false
+ }
+ array := wire.ArrayT
+ return t.Len() == array.Len && dec.compatibleType(t.Elem(), array.Elem, inProgress)
+ case reflect.Map:
+ if !ok || wire.MapT == nil {
+ return false
+ }
+ MapType := wire.MapT
+ return dec.compatibleType(t.Key(), MapType.Key, inProgress) && dec.compatibleType(t.Elem(), MapType.Elem, inProgress)
+ case reflect.Slice:
+ // Is it an array of bytes?
+ if t.Elem().Kind() == reflect.Uint8 {
+ return fw == tBytes
+ }
+ // Extract and compare element types.
+ var sw *sliceType
+ if tt := builtinIdToType(fw); tt != nil {
+ sw, _ = tt.(*sliceType)
+ } else if wire != nil {
+ sw = wire.SliceT
+ }
+ elem := userType(t.Elem()).base
+ return sw != nil && dec.compatibleType(elem, sw.Elem, inProgress)
+ case reflect.Struct:
+ return true
+ }
+}
+
+// typeString returns a human-readable description of the type identified by remoteId.
+func (dec *Decoder) typeString(remoteId typeId) string {
+ typeLock.Lock()
+ defer typeLock.Unlock()
+ if t := idToType(remoteId); t != nil {
+ // globally known type.
+ return t.string()
+ }
+ return dec.wireType[remoteId].string()
+}
+
+// compileSingle compiles the decoder engine for a non-struct top-level value, including
+// GobDecoders.
+func (dec *Decoder) compileSingle(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) {
+ rt := ut.user
+ engine = new(decEngine)
+ engine.instr = make([]decInstr, 1) // one item
+ name := rt.String() // best we can do
+ if !dec.compatibleType(rt, remoteId, make(map[reflect.Type]typeId)) {
+ remoteType := dec.typeString(remoteId)
+ // Common confusing case: local interface type, remote concrete type.
+ if ut.base.Kind() == reflect.Interface && remoteId != tInterface {
+ return nil, errors.New("gob: local interface type " + name + " can only be decoded from remote interface type; received concrete type " + remoteType)
+ }
+ return nil, errors.New("gob: decoding into local type " + name + ", received remote type " + remoteType)
+ }
+ op := dec.decOpFor(remoteId, rt, name, make(map[reflect.Type]*decOp))
+ ovfl := errors.New(`value for "` + name + `" out of range`)
+ engine.instr[singletonField] = decInstr{*op, singletonField, nil, ovfl}
+ engine.numInstr = 1
+ return
+}
+
+// compileIgnoreSingle compiles the decoder engine for a non-struct top-level value that will be discarded.
+func (dec *Decoder) compileIgnoreSingle(remoteId typeId) *decEngine {
+ engine := new(decEngine)
+ engine.instr = make([]decInstr, 1) // one item
+ op := dec.decIgnoreOpFor(remoteId, make(map[typeId]*decOp), 0)
+ ovfl := overflow(dec.typeString(remoteId))
+ engine.instr[0] = decInstr{*op, 0, nil, ovfl}
+ engine.numInstr = 1
+ return engine
+}
+
+// compileDec compiles the decoder engine for a value. If the value is not a struct,
+// it calls out to compileSingle.
+func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) {
+ defer catchError(&err)
+ rt := ut.base
+ srt := rt
+ if srt.Kind() != reflect.Struct || ut.externalDec != 0 {
+ return dec.compileSingle(remoteId, ut)
+ }
+ var wireStruct *structType
+ // Builtin types can come from global pool; the rest must be defined by the decoder.
+ // Also we know we're decoding a struct now, so the client must have sent one.
+ if t := builtinIdToType(remoteId); t != nil {
+ wireStruct, _ = t.(*structType)
+ } else {
+ wire := dec.wireType[remoteId]
+ if wire == nil {
+ error_(errBadType)
+ }
+ wireStruct = wire.StructT
+ }
+ if wireStruct == nil {
+ errorf("type mismatch in decoder: want struct type %s; got non-struct", rt)
+ }
+ engine = new(decEngine)
+ engine.instr = make([]decInstr, len(wireStruct.Field))
+ seen := make(map[reflect.Type]*decOp)
+ // Loop over the fields of the wire type.
+ for fieldnum := 0; fieldnum < len(wireStruct.Field); fieldnum++ {
+ wireField := wireStruct.Field[fieldnum]
+ if wireField.Name == "" {
+ errorf("empty name for remote field of type %s", wireStruct.Name)
+ }
+ ovfl := overflow(wireField.Name)
+ // Find the field of the local type with the same name.
+ localField, present := srt.FieldByName(wireField.Name)
+ // TODO(r): anonymous names
+ if !present || !isExported(wireField.Name) {
+ op := dec.decIgnoreOpFor(wireField.Id, make(map[typeId]*decOp), 0)
+ engine.instr[fieldnum] = decInstr{*op, fieldnum, nil, ovfl}
+ continue
+ }
+ if !dec.compatibleType(localField.Type, wireField.Id, make(map[reflect.Type]typeId)) {
+ errorf("wrong type (%s) for received field %s.%s", localField.Type, wireStruct.Name, wireField.Name)
+ }
+ op := dec.decOpFor(wireField.Id, localField.Type, localField.Name, seen)
+ engine.instr[fieldnum] = decInstr{*op, fieldnum, localField.Index, ovfl}
+ engine.numInstr++
+ }
+ return
+}
+
+// getDecEnginePtr returns the engine for the specified type.
+func (dec *Decoder) getDecEnginePtr(remoteId typeId, ut *userTypeInfo) (enginePtr **decEngine, err error) {
+ rt := ut.user
+ decoderMap, ok := dec.decoderCache[rt]
+ if !ok {
+ decoderMap = make(map[typeId]**decEngine)
+ dec.decoderCache[rt] = decoderMap
+ }
+ if enginePtr, ok = decoderMap[remoteId]; !ok {
+ // To handle recursive types, mark this engine as underway before compiling.
+ enginePtr = new(*decEngine)
+ decoderMap[remoteId] = enginePtr
+ *enginePtr, err = dec.compileDec(remoteId, ut)
+ if err != nil {
+ delete(decoderMap, remoteId)
+ }
+ }
+ return
+}
+
+// emptyStruct is the type we compile into when ignoring a struct value.
+type emptyStruct struct{}
+
+var emptyStructType = reflect.TypeOf((*emptyStruct)(nil)).Elem()
+
+// getIgnoreEnginePtr returns the engine for the specified type when the value is to be discarded.
+func (dec *Decoder) getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err error) {
+ var ok bool
+ if enginePtr, ok = dec.ignorerCache[wireId]; !ok {
+ // To handle recursive types, mark this engine as underway before compiling.
+ enginePtr = new(*decEngine)
+ dec.ignorerCache[wireId] = enginePtr
+ wire := dec.wireType[wireId]
+ if wire != nil && wire.StructT != nil {
+ *enginePtr, err = dec.compileDec(wireId, userType(emptyStructType))
+ } else {
+ *enginePtr = dec.compileIgnoreSingle(wireId)
+ }
+ if err != nil {
+ delete(dec.ignorerCache, wireId)
+ }
+ }
+ return
+}
+
+// decodeValue decodes the data stream representing a value and stores it in value.
+func (dec *Decoder) decodeValue(wireId typeId, value reflect.Value) {
+ defer catchError(&dec.err)
+ // If the value is nil, it means we should just ignore this item.
+ if !value.IsValid() {
+ dec.decodeIgnoredValue(wireId)
+ return
+ }
+ // Dereference down to the underlying type.
+ ut := userType(value.Type())
+ base := ut.base
+ var enginePtr **decEngine
+ enginePtr, dec.err = dec.getDecEnginePtr(wireId, ut)
+ if dec.err != nil {
+ return
+ }
+ value = decAlloc(value)
+ engine := *enginePtr
+ if st := base; st.Kind() == reflect.Struct && ut.externalDec == 0 {
+ wt := dec.wireType[wireId]
+ if engine.numInstr == 0 && st.NumField() > 0 &&
+ wt != nil && len(wt.StructT.Field) > 0 {
+ name := base.Name()
+ errorf("type mismatch: no fields matched compiling decoder for %s", name)
+ }
+ dec.decodeStruct(engine, value)
+ } else {
+ dec.decodeSingle(engine, value)
+ }
+}
+
+// decodeIgnoredValue decodes the data stream representing a value of the specified type and discards it.
+func (dec *Decoder) decodeIgnoredValue(wireId typeId) {
+ var enginePtr **decEngine
+ enginePtr, dec.err = dec.getIgnoreEnginePtr(wireId)
+ if dec.err != nil {
+ return
+ }
+ wire := dec.wireType[wireId]
+ if wire != nil && wire.StructT != nil {
+ dec.ignoreStruct(*enginePtr)
+ } else {
+ dec.ignoreSingle(*enginePtr)
+ }
+}
+
+const (
+ intBits = 32 << (^uint(0) >> 63)
+ uintptrBits = 32 << (^uintptr(0) >> 63)
+)
+
+func init() {
+ var iop, uop decOp
+ switch intBits {
+ case 32:
+ iop = decInt32
+ uop = decUint32
+ case 64:
+ iop = decInt64
+ uop = decUint64
+ default:
+ panic("gob: unknown size of int/uint")
+ }
+ decOpTable[reflect.Int] = iop
+ decOpTable[reflect.Uint] = uop
+
+ // Finally uintptr
+ switch uintptrBits {
+ case 32:
+ uop = decUint32
+ case 64:
+ uop = decUint64
+ default:
+ panic("gob: unknown size of uintptr")
+ }
+ decOpTable[reflect.Uintptr] = uop
+}
+
+// Gob depends on being able to take the address
+// of zeroed Values it creates, so use this wrapper instead
+// of the standard reflect.Zero.
+// Each call allocates once.
+func allocValue(t reflect.Type) reflect.Value {
+ return reflect.New(t).Elem()
+}
diff --git a/contrib/go/_std_1.20/src/encoding/gob/decoder.go b/contrib/go/_std_1.21/src/encoding/gob/decoder.go
index 5b77adc7e8..5b77adc7e8 100644
--- a/contrib/go/_std_1.20/src/encoding/gob/decoder.go
+++ b/contrib/go/_std_1.21/src/encoding/gob/decoder.go
diff --git a/contrib/go/_std_1.21/src/encoding/gob/doc.go b/contrib/go/_std_1.21/src/encoding/gob/doc.go
new file mode 100644
index 0000000000..53c47e7d00
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/gob/doc.go
@@ -0,0 +1,423 @@
+// Copyright 2009 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 gob manages streams of gobs - binary values exchanged between an
+Encoder (transmitter) and a Decoder (receiver). A typical use is transporting
+arguments and results of remote procedure calls (RPCs) such as those provided by
+[net/rpc].
+
+The implementation compiles a custom codec for each data type in the stream and
+is most efficient when a single Encoder is used to transmit a stream of values,
+amortizing the cost of compilation.
+
+# Basics
+
+A stream of gobs is self-describing. Each data item in the stream is preceded by
+a specification of its type, expressed in terms of a small set of predefined
+types. Pointers are not transmitted, but the things they point to are
+transmitted; that is, the values are flattened. Nil pointers are not permitted,
+as they have no value. Recursive types work fine, but
+recursive values (data with cycles) are problematic. This may change.
+
+To use gobs, create an Encoder and present it with a series of data items as
+values or addresses that can be dereferenced to values. The Encoder makes sure
+all type information is sent before it is needed. At the receive side, a
+Decoder retrieves values from the encoded stream and unpacks them into local
+variables.
+
+# Types and Values
+
+The source and destination values/types need not correspond exactly. For structs,
+fields (identified by name) that are in the source but absent from the receiving
+variable will be ignored. Fields that are in the receiving variable but missing
+from the transmitted type or value will be ignored in the destination. If a field
+with the same name is present in both, their types must be compatible. Both the
+receiver and transmitter will do all necessary indirection and dereferencing to
+convert between gobs and actual Go values. For instance, a gob type that is
+schematically,
+
+ struct { A, B int }
+
+can be sent from or received into any of these Go types:
+
+ struct { A, B int } // the same
+ *struct { A, B int } // extra indirection of the struct
+ struct { *A, **B int } // extra indirection of the fields
+ struct { A, B int64 } // different concrete value type; see below
+
+It may also be received into any of these:
+
+ struct { A, B int } // the same
+ struct { B, A int } // ordering doesn't matter; matching is by name
+ struct { A, B, C int } // extra field (C) ignored
+ struct { B int } // missing field (A) ignored; data will be dropped
+ struct { B, C int } // missing field (A) ignored; extra field (C) ignored.
+
+Attempting to receive into these types will draw a decode error:
+
+ struct { A int; B uint } // change of signedness for B
+ struct { A int; B float } // change of type for B
+ struct { } // no field names in common
+ struct { C, D int } // no field names in common
+
+Integers are transmitted two ways: arbitrary precision signed integers or
+arbitrary precision unsigned integers. There is no int8, int16 etc.
+discrimination in the gob format; there are only signed and unsigned integers. As
+described below, the transmitter sends the value in a variable-length encoding;
+the receiver accepts the value and stores it in the destination variable.
+Floating-point numbers are always sent using IEEE-754 64-bit precision (see
+below).
+
+Signed integers may be received into any signed integer variable: int, int16, etc.;
+unsigned integers may be received into any unsigned integer variable; and floating
+point values may be received into any floating point variable. However,
+the destination variable must be able to represent the value or the decode
+operation will fail.
+
+Structs, arrays and slices are also supported. Structs encode and decode only
+exported fields. Strings and arrays of bytes are supported with a special,
+efficient representation (see below). When a slice is decoded, if the existing
+slice has capacity the slice will be extended in place; if not, a new array is
+allocated. Regardless, the length of the resulting slice reports the number of
+elements decoded.
+
+In general, if allocation is required, the decoder will allocate memory. If not,
+it will update the destination variables with values read from the stream. It does
+not initialize them first, so if the destination is a compound value such as a
+map, struct, or slice, the decoded values will be merged elementwise into the
+existing variables.
+
+Functions and channels will not be sent in a gob. Attempting to encode such a value
+at the top level will fail. A struct field of chan or func type is treated exactly
+like an unexported field and is ignored.
+
+Gob can encode a value of any type implementing the GobEncoder or
+encoding.BinaryMarshaler interfaces by calling the corresponding method,
+in that order of preference.
+
+Gob can decode a value of any type implementing the GobDecoder or
+encoding.BinaryUnmarshaler interfaces by calling the corresponding method,
+again in that order of preference.
+
+# Encoding Details
+
+This section documents the encoding, details that are not important for most
+users. Details are presented bottom-up.
+
+An unsigned integer is sent one of two ways. If it is less than 128, it is sent
+as a byte with that value. Otherwise it is sent as a minimal-length big-endian
+(high byte first) byte stream holding the value, preceded by one byte holding the
+byte count, negated. Thus 0 is transmitted as (00), 7 is transmitted as (07) and
+256 is transmitted as (FE 01 00).
+
+A boolean is encoded within an unsigned integer: 0 for false, 1 for true.
+
+A signed integer, i, is encoded within an unsigned integer, u. Within u, bits 1
+upward contain the value; bit 0 says whether they should be complemented upon
+receipt. The encode algorithm looks like this:
+
+ var u uint
+ if i < 0 {
+ u = (^uint(i) << 1) | 1 // complement i, bit 0 is 1
+ } else {
+ u = (uint(i) << 1) // do not complement i, bit 0 is 0
+ }
+ encodeUnsigned(u)
+
+The low bit is therefore analogous to a sign bit, but making it the complement bit
+instead guarantees that the largest negative integer is not a special case. For
+example, -129=^128=(^256>>1) encodes as (FE 01 01).
+
+Floating-point numbers are always sent as a representation of a float64 value.
+That value is converted to a uint64 using math.Float64bits. The uint64 is then
+byte-reversed and sent as a regular unsigned integer. The byte-reversal means the
+exponent and high-precision part of the mantissa go first. Since the low bits are
+often zero, this can save encoding bytes. For instance, 17.0 is encoded in only
+three bytes (FE 31 40).
+
+Strings and slices of bytes are sent as an unsigned count followed by that many
+uninterpreted bytes of the value.
+
+All other slices and arrays are sent as an unsigned count followed by that many
+elements using the standard gob encoding for their type, recursively.
+
+Maps are sent as an unsigned count followed by that many key, element
+pairs. Empty but non-nil maps are sent, so if the receiver has not allocated
+one already, one will always be allocated on receipt unless the transmitted map
+is nil and not at the top level.
+
+In slices and arrays, as well as maps, all elements, even zero-valued elements,
+are transmitted, even if all the elements are zero.
+
+Structs are sent as a sequence of (field number, field value) pairs. The field
+value is sent using the standard gob encoding for its type, recursively. If a
+field has the zero value for its type (except for arrays; see above), it is omitted
+from the transmission. The field number is defined by the type of the encoded
+struct: the first field of the encoded type is field 0, the second is field 1,
+etc. When encoding a value, the field numbers are delta encoded for efficiency
+and the fields are always sent in order of increasing field number; the deltas are
+therefore unsigned. The initialization for the delta encoding sets the field
+number to -1, so an unsigned integer field 0 with value 7 is transmitted as unsigned
+delta = 1, unsigned value = 7 or (01 07). Finally, after all the fields have been
+sent a terminating mark denotes the end of the struct. That mark is a delta=0
+value, which has representation (00).
+
+Interface types are not checked for compatibility; all interface types are
+treated, for transmission, as members of a single "interface" type, analogous to
+int or []byte - in effect they're all treated as interface{}. Interface values
+are transmitted as a string identifying the concrete type being sent (a name
+that must be pre-defined by calling Register), followed by a byte count of the
+length of the following data (so the value can be skipped if it cannot be
+stored), followed by the usual encoding of concrete (dynamic) value stored in
+the interface value. (A nil interface value is identified by the empty string
+and transmits no value.) Upon receipt, the decoder verifies that the unpacked
+concrete item satisfies the interface of the receiving variable.
+
+If a value is passed to Encode and the type is not a struct (or pointer to struct,
+etc.), for simplicity of processing it is represented as a struct of one field.
+The only visible effect of this is to encode a zero byte after the value, just as
+after the last field of an encoded struct, so that the decode algorithm knows when
+the top-level value is complete.
+
+The representation of types is described below. When a type is defined on a given
+connection between an Encoder and Decoder, it is assigned a signed integer type
+id. When Encoder.Encode(v) is called, it makes sure there is an id assigned for
+the type of v and all its elements and then it sends the pair (typeid, encoded-v)
+where typeid is the type id of the encoded type of v and encoded-v is the gob
+encoding of the value v.
+
+To define a type, the encoder chooses an unused, positive type id and sends the
+pair (-type id, encoded-type) where encoded-type is the gob encoding of a wireType
+description, constructed from these types:
+
+ type wireType struct {
+ ArrayT *ArrayType
+ SliceT *SliceType
+ StructT *StructType
+ MapT *MapType
+ GobEncoderT *gobEncoderType
+ BinaryMarshalerT *gobEncoderType
+ TextMarshalerT *gobEncoderType
+
+ }
+ type arrayType struct {
+ CommonType
+ Elem typeId
+ Len int
+ }
+ type CommonType struct {
+ Name string // the name of the struct type
+ Id int // the id of the type, repeated so it's inside the type
+ }
+ type sliceType struct {
+ CommonType
+ Elem typeId
+ }
+ type structType struct {
+ CommonType
+ Field []*fieldType // the fields of the struct.
+ }
+ type fieldType struct {
+ Name string // the name of the field.
+ Id int // the type id of the field, which must be already defined
+ }
+ type mapType struct {
+ CommonType
+ Key typeId
+ Elem typeId
+ }
+ type gobEncoderType struct {
+ CommonType
+ }
+
+If there are nested type ids, the types for all inner type ids must be defined
+before the top-level type id is used to describe an encoded-v.
+
+For simplicity in setup, the connection is defined to understand these types a
+priori, as well as the basic gob types int, uint, etc. Their ids are:
+
+ bool 1
+ int 2
+ uint 3
+ float 4
+ []byte 5
+ string 6
+ complex 7
+ interface 8
+ // gap for reserved ids.
+ WireType 16
+ ArrayType 17
+ CommonType 18
+ SliceType 19
+ StructType 20
+ FieldType 21
+ // 22 is slice of fieldType.
+ MapType 23
+
+Finally, each message created by a call to Encode is preceded by an encoded
+unsigned integer count of the number of bytes remaining in the message. After
+the initial type name, interface values are wrapped the same way; in effect, the
+interface value acts like a recursive invocation of Encode.
+
+In summary, a gob stream looks like
+
+ (byteCount (-type id, encoding of a wireType)* (type id, encoding of a value))*
+
+where * signifies zero or more repetitions and the type id of a value must
+be predefined or be defined before the value in the stream.
+
+Compatibility: Any future changes to the package will endeavor to maintain
+compatibility with streams encoded using previous versions. That is, any released
+version of this package should be able to decode data written with any previously
+released version, subject to issues such as security fixes. See the Go compatibility
+document for background: https://golang.org/doc/go1compat
+
+See "Gobs of data" for a design discussion of the gob wire format:
+https://blog.golang.org/gobs-of-data
+
+# Security
+
+This package is not designed to be hardened against adversarial inputs, and is
+outside the scope of https://go.dev/security/policy. In particular, the Decoder
+does only basic sanity checking on decoded input sizes, and its limits are not
+configurable. Care should be taken when decoding gob data from untrusted
+sources, which may consume significant resources.
+*/
+package gob
+
+/*
+Grammar:
+
+Tokens starting with a lower case letter are terminals; int(n)
+and uint(n) represent the signed/unsigned encodings of the value n.
+
+GobStream:
+ DelimitedMessage*
+DelimitedMessage:
+ uint(lengthOfMessage) Message
+Message:
+ TypeSequence TypedValue
+TypeSequence
+ (TypeDefinition DelimitedTypeDefinition*)?
+DelimitedTypeDefinition:
+ uint(lengthOfTypeDefinition) TypeDefinition
+TypedValue:
+ int(typeId) Value
+TypeDefinition:
+ int(-typeId) encodingOfWireType
+Value:
+ SingletonValue | StructValue
+SingletonValue:
+ uint(0) FieldValue
+FieldValue:
+ builtinValue | ArrayValue | MapValue | SliceValue | StructValue | InterfaceValue
+InterfaceValue:
+ NilInterfaceValue | NonNilInterfaceValue
+NilInterfaceValue:
+ uint(0)
+NonNilInterfaceValue:
+ ConcreteTypeName TypeSequence InterfaceContents
+ConcreteTypeName:
+ uint(lengthOfName) [already read=n] name
+InterfaceContents:
+ int(concreteTypeId) DelimitedValue
+DelimitedValue:
+ uint(length) Value
+ArrayValue:
+ uint(n) FieldValue*n [n elements]
+MapValue:
+ uint(n) (FieldValue FieldValue)*n [n (key, value) pairs]
+SliceValue:
+ uint(n) FieldValue*n [n elements]
+StructValue:
+ (uint(fieldDelta) FieldValue)*
+*/
+
+/*
+For implementers and the curious, here is an encoded example. Given
+ type Point struct {X, Y int}
+and the value
+ p := Point{22, 33}
+the bytes transmitted that encode p will be:
+ 1f ff 81 03 01 01 05 50 6f 69 6e 74 01 ff 82 00
+ 01 02 01 01 58 01 04 00 01 01 59 01 04 00 00 00
+ 07 ff 82 01 2c 01 42 00
+They are determined as follows.
+
+Since this is the first transmission of type Point, the type descriptor
+for Point itself must be sent before the value. This is the first type
+we've sent on this Encoder, so it has type id 65 (0 through 64 are
+reserved).
+
+ 1f // This item (a type descriptor) is 31 bytes long.
+ ff 81 // The negative of the id for the type we're defining, -65.
+ // This is one byte (indicated by FF = -1) followed by
+ // ^-65<<1 | 1. The low 1 bit signals to complement the
+ // rest upon receipt.
+
+ // Now we send a type descriptor, which is itself a struct (wireType).
+ // The type of wireType itself is known (it's built in, as is the type of
+ // all its components), so we just need to send a *value* of type wireType
+ // that represents type "Point".
+ // Here starts the encoding of that value.
+ // Set the field number implicitly to -1; this is done at the beginning
+ // of every struct, including nested structs.
+ 03 // Add 3 to field number; now 2 (wireType.structType; this is a struct).
+ // structType starts with an embedded CommonType, which appears
+ // as a regular structure here too.
+ 01 // add 1 to field number (now 0); start of embedded CommonType.
+ 01 // add 1 to field number (now 0, the name of the type)
+ 05 // string is (unsigned) 5 bytes long
+ 50 6f 69 6e 74 // wireType.structType.CommonType.name = "Point"
+ 01 // add 1 to field number (now 1, the id of the type)
+ ff 82 // wireType.structType.CommonType._id = 65
+ 00 // end of embedded wiretype.structType.CommonType struct
+ 01 // add 1 to field number (now 1, the field array in wireType.structType)
+ 02 // There are two fields in the type (len(structType.field))
+ 01 // Start of first field structure; add 1 to get field number 0: field[0].name
+ 01 // 1 byte
+ 58 // structType.field[0].name = "X"
+ 01 // Add 1 to get field number 1: field[0].id
+ 04 // structType.field[0].typeId is 2 (signed int).
+ 00 // End of structType.field[0]; start structType.field[1]; set field number to -1.
+ 01 // Add 1 to get field number 0: field[1].name
+ 01 // 1 byte
+ 59 // structType.field[1].name = "Y"
+ 01 // Add 1 to get field number 1: field[1].id
+ 04 // struct.Type.field[1].typeId is 2 (signed int).
+ 00 // End of structType.field[1]; end of structType.field.
+ 00 // end of wireType.structType structure
+ 00 // end of wireType structure
+
+Now we can send the Point value. Again the field number resets to -1:
+
+ 07 // this value is 7 bytes long
+ ff 82 // the type number, 65 (1 byte (-FF) followed by 65<<1)
+ 01 // add one to field number, yielding field 0
+ 2c // encoding of signed "22" (0x2c = 44 = 22<<1); Point.x = 22
+ 01 // add one to field number, yielding field 1
+ 42 // encoding of signed "33" (0x42 = 66 = 33<<1); Point.y = 33
+ 00 // end of structure
+
+The type encoding is long and fairly intricate but we send it only once.
+If p is transmitted a second time, the type is already known so the
+output will be just:
+
+ 07 ff 82 01 2c 01 42 00
+
+A single non-struct value at top level is transmitted like a field with
+delta tag 0. For instance, a signed integer with value 3 presented as
+the argument to Encode will emit:
+
+ 03 04 00 06
+
+Which represents:
+
+ 03 // this value is 3 bytes long
+ 04 // the type number, 2, represents an integer
+ 00 // tag delta 0
+ 06 // value 3
+
+*/
diff --git a/contrib/go/_std_1.20/src/encoding/gob/enc_helpers.go b/contrib/go/_std_1.21/src/encoding/gob/enc_helpers.go
index c3b4ca8972..c3b4ca8972 100644
--- a/contrib/go/_std_1.20/src/encoding/gob/enc_helpers.go
+++ b/contrib/go/_std_1.21/src/encoding/gob/enc_helpers.go
diff --git a/contrib/go/_std_1.21/src/encoding/gob/encode.go b/contrib/go/_std_1.21/src/encoding/gob/encode.go
new file mode 100644
index 0000000000..5f4d2539fa
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/gob/encode.go
@@ -0,0 +1,670 @@
+// Copyright 2009 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.
+
+//go:generate go run encgen.go -output enc_helpers.go
+
+package gob
+
+import (
+ "encoding"
+ "encoding/binary"
+ "math"
+ "math/bits"
+ "reflect"
+ "sync"
+)
+
+const uint64Size = 8
+
+type encHelper func(state *encoderState, v reflect.Value) bool
+
+// encoderState is the global execution state of an instance of the encoder.
+// Field numbers are delta encoded and always increase. The field
+// number is initialized to -1 so 0 comes out as delta(1). A delta of
+// 0 terminates the structure.
+type encoderState struct {
+ enc *Encoder
+ b *encBuffer
+ sendZero bool // encoding an array element or map key/value pair; send zero values
+ fieldnum int // the last field number written.
+ buf [1 + uint64Size]byte // buffer used by the encoder; here to avoid allocation.
+ next *encoderState // for free list
+}
+
+// encBuffer is an extremely simple, fast implementation of a write-only byte buffer.
+// It never returns a non-nil error, but Write returns an error value so it matches io.Writer.
+type encBuffer struct {
+ data []byte
+ scratch [64]byte
+}
+
+var encBufferPool = sync.Pool{
+ New: func() any {
+ e := new(encBuffer)
+ e.data = e.scratch[0:0]
+ return e
+ },
+}
+
+func (e *encBuffer) writeByte(c byte) {
+ e.data = append(e.data, c)
+}
+
+func (e *encBuffer) Write(p []byte) (int, error) {
+ e.data = append(e.data, p...)
+ return len(p), nil
+}
+
+func (e *encBuffer) WriteString(s string) {
+ e.data = append(e.data, s...)
+}
+
+func (e *encBuffer) Len() int {
+ return len(e.data)
+}
+
+func (e *encBuffer) Bytes() []byte {
+ return e.data
+}
+
+func (e *encBuffer) Reset() {
+ if len(e.data) >= tooBig {
+ e.data = e.scratch[0:0]
+ } else {
+ e.data = e.data[0:0]
+ }
+}
+
+func (enc *Encoder) newEncoderState(b *encBuffer) *encoderState {
+ e := enc.freeList
+ if e == nil {
+ e = new(encoderState)
+ e.enc = enc
+ } else {
+ enc.freeList = e.next
+ }
+ e.sendZero = false
+ e.fieldnum = 0
+ e.b = b
+ if len(b.data) == 0 {
+ b.data = b.scratch[0:0]
+ }
+ return e
+}
+
+func (enc *Encoder) freeEncoderState(e *encoderState) {
+ e.next = enc.freeList
+ enc.freeList = e
+}
+
+// Unsigned integers have a two-state encoding. If the number is less
+// than 128 (0 through 0x7F), its value is written directly.
+// Otherwise the value is written in big-endian byte order preceded
+// by the byte length, negated.
+
+// encodeUint writes an encoded unsigned integer to state.b.
+func (state *encoderState) encodeUint(x uint64) {
+ if x <= 0x7F {
+ state.b.writeByte(uint8(x))
+ return
+ }
+
+ binary.BigEndian.PutUint64(state.buf[1:], x)
+ bc := bits.LeadingZeros64(x) >> 3 // 8 - bytelen(x)
+ state.buf[bc] = uint8(bc - uint64Size) // and then we subtract 8 to get -bytelen(x)
+
+ state.b.Write(state.buf[bc : uint64Size+1])
+}
+
+// encodeInt writes an encoded signed integer to state.w.
+// The low bit of the encoding says whether to bit complement the (other bits of the)
+// uint to recover the int.
+func (state *encoderState) encodeInt(i int64) {
+ var x uint64
+ if i < 0 {
+ x = uint64(^i<<1) | 1
+ } else {
+ x = uint64(i << 1)
+ }
+ state.encodeUint(x)
+}
+
+// encOp is the signature of an encoding operator for a given type.
+type encOp func(i *encInstr, state *encoderState, v reflect.Value)
+
+// The 'instructions' of the encoding machine
+type encInstr struct {
+ op encOp
+ field int // field number in input
+ index []int // struct index
+ indir int // how many pointer indirections to reach the value in the struct
+}
+
+// update emits a field number and updates the state to record its value for delta encoding.
+// If the instruction pointer is nil, it does nothing
+func (state *encoderState) update(instr *encInstr) {
+ if instr != nil {
+ state.encodeUint(uint64(instr.field - state.fieldnum))
+ state.fieldnum = instr.field
+ }
+}
+
+// Each encoder for a composite is responsible for handling any
+// indirections associated with the elements of the data structure.
+// If any pointer so reached is nil, no bytes are written. If the
+// data item is zero, no bytes are written. Single values - ints,
+// strings etc. - are indirected before calling their encoders.
+// Otherwise, the output (for a scalar) is the field number, as an
+// encoded integer, followed by the field data in its appropriate
+// format.
+
+// encIndirect dereferences pv indir times and returns the result.
+func encIndirect(pv reflect.Value, indir int) reflect.Value {
+ for ; indir > 0; indir-- {
+ if pv.IsNil() {
+ break
+ }
+ pv = pv.Elem()
+ }
+ return pv
+}
+
+// encBool encodes the bool referenced by v as an unsigned 0 or 1.
+func encBool(i *encInstr, state *encoderState, v reflect.Value) {
+ b := v.Bool()
+ if b || state.sendZero {
+ state.update(i)
+ if b {
+ state.encodeUint(1)
+ } else {
+ state.encodeUint(0)
+ }
+ }
+}
+
+// encInt encodes the signed integer (int int8 int16 int32 int64) referenced by v.
+func encInt(i *encInstr, state *encoderState, v reflect.Value) {
+ value := v.Int()
+ if value != 0 || state.sendZero {
+ state.update(i)
+ state.encodeInt(value)
+ }
+}
+
+// encUint encodes the unsigned integer (uint uint8 uint16 uint32 uint64 uintptr) referenced by v.
+func encUint(i *encInstr, state *encoderState, v reflect.Value) {
+ value := v.Uint()
+ if value != 0 || state.sendZero {
+ state.update(i)
+ state.encodeUint(value)
+ }
+}
+
+// floatBits returns a uint64 holding the bits of a floating-point number.
+// Floating-point numbers are transmitted as uint64s holding the bits
+// of the underlying representation. They are sent byte-reversed, with
+// the exponent end coming out first, so integer floating point numbers
+// (for example) transmit more compactly. This routine does the
+// swizzling.
+func floatBits(f float64) uint64 {
+ u := math.Float64bits(f)
+ return bits.ReverseBytes64(u)
+}
+
+// encFloat encodes the floating point value (float32 float64) referenced by v.
+func encFloat(i *encInstr, state *encoderState, v reflect.Value) {
+ f := v.Float()
+ if f != 0 || state.sendZero {
+ bits := floatBits(f)
+ state.update(i)
+ state.encodeUint(bits)
+ }
+}
+
+// encComplex encodes the complex value (complex64 complex128) referenced by v.
+// Complex numbers are just a pair of floating-point numbers, real part first.
+func encComplex(i *encInstr, state *encoderState, v reflect.Value) {
+ c := v.Complex()
+ if c != 0+0i || state.sendZero {
+ rpart := floatBits(real(c))
+ ipart := floatBits(imag(c))
+ state.update(i)
+ state.encodeUint(rpart)
+ state.encodeUint(ipart)
+ }
+}
+
+// encUint8Array encodes the byte array referenced by v.
+// Byte arrays are encoded as an unsigned count followed by the raw bytes.
+func encUint8Array(i *encInstr, state *encoderState, v reflect.Value) {
+ b := v.Bytes()
+ if len(b) > 0 || state.sendZero {
+ state.update(i)
+ state.encodeUint(uint64(len(b)))
+ state.b.Write(b)
+ }
+}
+
+// encString encodes the string referenced by v.
+// Strings are encoded as an unsigned count followed by the raw bytes.
+func encString(i *encInstr, state *encoderState, v reflect.Value) {
+ s := v.String()
+ if len(s) > 0 || state.sendZero {
+ state.update(i)
+ state.encodeUint(uint64(len(s)))
+ state.b.WriteString(s)
+ }
+}
+
+// encStructTerminator encodes the end of an encoded struct
+// as delta field number of 0.
+func encStructTerminator(i *encInstr, state *encoderState, v reflect.Value) {
+ state.encodeUint(0)
+}
+
+// Execution engine
+
+// encEngine an array of instructions indexed by field number of the encoding
+// data, typically a struct. It is executed top to bottom, walking the struct.
+type encEngine struct {
+ instr []encInstr
+}
+
+const singletonField = 0
+
+// valid reports whether the value is valid and a non-nil pointer.
+// (Slices, maps, and chans take care of themselves.)
+func valid(v reflect.Value) bool {
+ switch v.Kind() {
+ case reflect.Invalid:
+ return false
+ case reflect.Pointer:
+ return !v.IsNil()
+ }
+ return true
+}
+
+// encodeSingle encodes a single top-level non-struct value.
+func (enc *Encoder) encodeSingle(b *encBuffer, engine *encEngine, value reflect.Value) {
+ state := enc.newEncoderState(b)
+ defer enc.freeEncoderState(state)
+ state.fieldnum = singletonField
+ // There is no surrounding struct to frame the transmission, so we must
+ // generate data even if the item is zero. To do this, set sendZero.
+ state.sendZero = true
+ instr := &engine.instr[singletonField]
+ if instr.indir > 0 {
+ value = encIndirect(value, instr.indir)
+ }
+ if valid(value) {
+ instr.op(instr, state, value)
+ }
+}
+
+// encodeStruct encodes a single struct value.
+func (enc *Encoder) encodeStruct(b *encBuffer, engine *encEngine, value reflect.Value) {
+ if !valid(value) {
+ return
+ }
+ state := enc.newEncoderState(b)
+ defer enc.freeEncoderState(state)
+ state.fieldnum = -1
+ for i := 0; i < len(engine.instr); i++ {
+ instr := &engine.instr[i]
+ if i >= value.NumField() {
+ // encStructTerminator
+ instr.op(instr, state, reflect.Value{})
+ break
+ }
+ field := value.FieldByIndex(instr.index)
+ if instr.indir > 0 {
+ field = encIndirect(field, instr.indir)
+ // TODO: Is field guaranteed valid? If so we could avoid this check.
+ if !valid(field) {
+ continue
+ }
+ }
+ instr.op(instr, state, field)
+ }
+}
+
+// encodeArray encodes an array.
+func (enc *Encoder) encodeArray(b *encBuffer, value reflect.Value, op encOp, elemIndir int, length int, helper encHelper) {
+ state := enc.newEncoderState(b)
+ defer enc.freeEncoderState(state)
+ state.fieldnum = -1
+ state.sendZero = true
+ state.encodeUint(uint64(length))
+ if helper != nil && helper(state, value) {
+ return
+ }
+ for i := 0; i < length; i++ {
+ elem := value.Index(i)
+ if elemIndir > 0 {
+ elem = encIndirect(elem, elemIndir)
+ // TODO: Is elem guaranteed valid? If so we could avoid this check.
+ if !valid(elem) {
+ errorf("encodeArray: nil element")
+ }
+ }
+ op(nil, state, elem)
+ }
+}
+
+// encodeReflectValue is a helper for maps. It encodes the value v.
+func encodeReflectValue(state *encoderState, v reflect.Value, op encOp, indir int) {
+ for i := 0; i < indir && v.IsValid(); i++ {
+ v = reflect.Indirect(v)
+ }
+ if !v.IsValid() {
+ errorf("encodeReflectValue: nil element")
+ }
+ op(nil, state, v)
+}
+
+// encodeMap encodes a map as unsigned count followed by key:value pairs.
+func (enc *Encoder) encodeMap(b *encBuffer, mv reflect.Value, keyOp, elemOp encOp, keyIndir, elemIndir int) {
+ state := enc.newEncoderState(b)
+ state.fieldnum = -1
+ state.sendZero = true
+ state.encodeUint(uint64(mv.Len()))
+ mi := mv.MapRange()
+ for mi.Next() {
+ encodeReflectValue(state, mi.Key(), keyOp, keyIndir)
+ encodeReflectValue(state, mi.Value(), elemOp, elemIndir)
+ }
+ enc.freeEncoderState(state)
+}
+
+// encodeInterface encodes the interface value iv.
+// To send an interface, we send a string identifying the concrete type, followed
+// by the type identifier (which might require defining that type right now), followed
+// by the concrete value. A nil value gets sent as the empty string for the name,
+// followed by no value.
+func (enc *Encoder) encodeInterface(b *encBuffer, iv reflect.Value) {
+ // Gobs can encode nil interface values but not typed interface
+ // values holding nil pointers, since nil pointers point to no value.
+ elem := iv.Elem()
+ if elem.Kind() == reflect.Pointer && elem.IsNil() {
+ errorf("gob: cannot encode nil pointer of type %s inside interface", iv.Elem().Type())
+ }
+ state := enc.newEncoderState(b)
+ state.fieldnum = -1
+ state.sendZero = true
+ if iv.IsNil() {
+ state.encodeUint(0)
+ return
+ }
+
+ ut := userType(iv.Elem().Type())
+ namei, ok := concreteTypeToName.Load(ut.base)
+ if !ok {
+ errorf("type not registered for interface: %s", ut.base)
+ }
+ name := namei.(string)
+
+ // Send the name.
+ state.encodeUint(uint64(len(name)))
+ state.b.WriteString(name)
+ // Define the type id if necessary.
+ enc.sendTypeDescriptor(enc.writer(), state, ut)
+ // Send the type id.
+ enc.sendTypeId(state, ut)
+ // Encode the value into a new buffer. Any nested type definitions
+ // should be written to b, before the encoded value.
+ enc.pushWriter(b)
+ data := encBufferPool.Get().(*encBuffer)
+ data.Write(spaceForLength)
+ enc.encode(data, elem, ut)
+ if enc.err != nil {
+ error_(enc.err)
+ }
+ enc.popWriter()
+ enc.writeMessage(b, data)
+ data.Reset()
+ encBufferPool.Put(data)
+ if enc.err != nil {
+ error_(enc.err)
+ }
+ enc.freeEncoderState(state)
+}
+
+// encodeGobEncoder encodes a value that implements the GobEncoder interface.
+// The data is sent as a byte array.
+func (enc *Encoder) encodeGobEncoder(b *encBuffer, ut *userTypeInfo, v reflect.Value) {
+ // TODO: should we catch panics from the called method?
+
+ var data []byte
+ var err error
+ // We know it's one of these.
+ switch ut.externalEnc {
+ case xGob:
+ data, err = v.Interface().(GobEncoder).GobEncode()
+ case xBinary:
+ data, err = v.Interface().(encoding.BinaryMarshaler).MarshalBinary()
+ case xText:
+ data, err = v.Interface().(encoding.TextMarshaler).MarshalText()
+ }
+ if err != nil {
+ error_(err)
+ }
+ state := enc.newEncoderState(b)
+ state.fieldnum = -1
+ state.encodeUint(uint64(len(data)))
+ state.b.Write(data)
+ enc.freeEncoderState(state)
+}
+
+var encOpTable = [...]encOp{
+ reflect.Bool: encBool,
+ reflect.Int: encInt,
+ reflect.Int8: encInt,
+ reflect.Int16: encInt,
+ reflect.Int32: encInt,
+ reflect.Int64: encInt,
+ reflect.Uint: encUint,
+ reflect.Uint8: encUint,
+ reflect.Uint16: encUint,
+ reflect.Uint32: encUint,
+ reflect.Uint64: encUint,
+ reflect.Uintptr: encUint,
+ reflect.Float32: encFloat,
+ reflect.Float64: encFloat,
+ reflect.Complex64: encComplex,
+ reflect.Complex128: encComplex,
+ reflect.String: encString,
+}
+
+// encOpFor returns (a pointer to) the encoding op for the base type under rt and
+// the indirection count to reach it.
+func encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp, building map[*typeInfo]bool) (*encOp, int) {
+ ut := userType(rt)
+ // If the type implements GobEncoder, we handle it without further processing.
+ if ut.externalEnc != 0 {
+ return gobEncodeOpFor(ut)
+ }
+ // If this type is already in progress, it's a recursive type (e.g. map[string]*T).
+ // Return the pointer to the op we're already building.
+ if opPtr := inProgress[rt]; opPtr != nil {
+ return opPtr, ut.indir
+ }
+ typ := ut.base
+ indir := ut.indir
+ k := typ.Kind()
+ var op encOp
+ if int(k) < len(encOpTable) {
+ op = encOpTable[k]
+ }
+ if op == nil {
+ inProgress[rt] = &op
+ // Special cases
+ switch t := typ; t.Kind() {
+ case reflect.Slice:
+ if t.Elem().Kind() == reflect.Uint8 {
+ op = encUint8Array
+ break
+ }
+ // Slices have a header; we decode it to find the underlying array.
+ elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
+ helper := encSliceHelper[t.Elem().Kind()]
+ op = func(i *encInstr, state *encoderState, slice reflect.Value) {
+ if !state.sendZero && slice.Len() == 0 {
+ return
+ }
+ state.update(i)
+ state.enc.encodeArray(state.b, slice, *elemOp, elemIndir, slice.Len(), helper)
+ }
+ case reflect.Array:
+ // True arrays have size in the type.
+ elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
+ helper := encArrayHelper[t.Elem().Kind()]
+ op = func(i *encInstr, state *encoderState, array reflect.Value) {
+ state.update(i)
+ state.enc.encodeArray(state.b, array, *elemOp, elemIndir, array.Len(), helper)
+ }
+ case reflect.Map:
+ keyOp, keyIndir := encOpFor(t.Key(), inProgress, building)
+ elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
+ op = func(i *encInstr, state *encoderState, mv reflect.Value) {
+ // We send zero-length (but non-nil) maps because the
+ // receiver might want to use the map. (Maps don't use append.)
+ if !state.sendZero && mv.IsNil() {
+ return
+ }
+ state.update(i)
+ state.enc.encodeMap(state.b, mv, *keyOp, *elemOp, keyIndir, elemIndir)
+ }
+ case reflect.Struct:
+ // Generate a closure that calls out to the engine for the nested type.
+ getEncEngine(userType(typ), building)
+ info := mustGetTypeInfo(typ)
+ op = func(i *encInstr, state *encoderState, sv reflect.Value) {
+ state.update(i)
+ // indirect through info to delay evaluation for recursive structs
+ enc := info.encoder.Load()
+ state.enc.encodeStruct(state.b, enc, sv)
+ }
+ case reflect.Interface:
+ op = func(i *encInstr, state *encoderState, iv reflect.Value) {
+ if !state.sendZero && (!iv.IsValid() || iv.IsNil()) {
+ return
+ }
+ state.update(i)
+ state.enc.encodeInterface(state.b, iv)
+ }
+ }
+ }
+ if op == nil {
+ errorf("can't happen: encode type %s", rt)
+ }
+ return &op, indir
+}
+
+// gobEncodeOpFor returns the op for a type that is known to implement GobEncoder.
+func gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) {
+ rt := ut.user
+ if ut.encIndir == -1 {
+ rt = reflect.PointerTo(rt)
+ } else if ut.encIndir > 0 {
+ for i := int8(0); i < ut.encIndir; i++ {
+ rt = rt.Elem()
+ }
+ }
+ var op encOp
+ op = func(i *encInstr, state *encoderState, v reflect.Value) {
+ if ut.encIndir == -1 {
+ // Need to climb up one level to turn value into pointer.
+ if !v.CanAddr() {
+ errorf("unaddressable value of type %s", rt)
+ }
+ v = v.Addr()
+ }
+ if !state.sendZero && v.IsZero() {
+ return
+ }
+ state.update(i)
+ state.enc.encodeGobEncoder(state.b, ut, v)
+ }
+ return &op, int(ut.encIndir) // encIndir: op will get called with p == address of receiver.
+}
+
+// compileEnc returns the engine to compile the type.
+func compileEnc(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
+ srt := ut.base
+ engine := new(encEngine)
+ seen := make(map[reflect.Type]*encOp)
+ rt := ut.base
+ if ut.externalEnc != 0 {
+ rt = ut.user
+ }
+ if ut.externalEnc == 0 && srt.Kind() == reflect.Struct {
+ for fieldNum, wireFieldNum := 0, 0; fieldNum < srt.NumField(); fieldNum++ {
+ f := srt.Field(fieldNum)
+ if !isSent(&f) {
+ continue
+ }
+ op, indir := encOpFor(f.Type, seen, building)
+ engine.instr = append(engine.instr, encInstr{*op, wireFieldNum, f.Index, indir})
+ wireFieldNum++
+ }
+ if srt.NumField() > 0 && len(engine.instr) == 0 {
+ errorf("type %s has no exported fields", rt)
+ }
+ engine.instr = append(engine.instr, encInstr{encStructTerminator, 0, nil, 0})
+ } else {
+ engine.instr = make([]encInstr, 1)
+ op, indir := encOpFor(rt, seen, building)
+ engine.instr[0] = encInstr{*op, singletonField, nil, indir}
+ }
+ return engine
+}
+
+// getEncEngine returns the engine to compile the type.
+func getEncEngine(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
+ info, err := getTypeInfo(ut)
+ if err != nil {
+ error_(err)
+ }
+ enc := info.encoder.Load()
+ if enc == nil {
+ enc = buildEncEngine(info, ut, building)
+ }
+ return enc
+}
+
+func buildEncEngine(info *typeInfo, ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
+ // Check for recursive types.
+ if building != nil && building[info] {
+ return nil
+ }
+ info.encInit.Lock()
+ defer info.encInit.Unlock()
+ enc := info.encoder.Load()
+ if enc == nil {
+ if building == nil {
+ building = make(map[*typeInfo]bool)
+ }
+ building[info] = true
+ enc = compileEnc(ut, building)
+ info.encoder.Store(enc)
+ }
+ return enc
+}
+
+func (enc *Encoder) encode(b *encBuffer, value reflect.Value, ut *userTypeInfo) {
+ defer catchError(&enc.err)
+ engine := getEncEngine(ut, nil)
+ indir := ut.indir
+ if ut.externalEnc != 0 {
+ indir = int(ut.encIndir)
+ }
+ for i := 0; i < indir; i++ {
+ value = reflect.Indirect(value)
+ }
+ if ut.externalEnc == 0 && value.Type().Kind() == reflect.Struct {
+ enc.encodeStruct(b, engine, value)
+ } else {
+ enc.encodeSingle(b, engine, value)
+ }
+}
diff --git a/contrib/go/_std_1.21/src/encoding/gob/encoder.go b/contrib/go/_std_1.21/src/encoding/gob/encoder.go
new file mode 100644
index 0000000000..aa413939d4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/gob/encoder.go
@@ -0,0 +1,258 @@
+// Copyright 2009 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 gob
+
+import (
+ "errors"
+ "io"
+ "reflect"
+ "sync"
+)
+
+// An Encoder manages the transmission of type and data information to the
+// other side of a connection. It is safe for concurrent use by multiple
+// goroutines.
+type Encoder struct {
+ mutex sync.Mutex // each item must be sent atomically
+ w []io.Writer // where to send the data
+ sent map[reflect.Type]typeId // which types we've already sent
+ countState *encoderState // stage for writing counts
+ freeList *encoderState // list of free encoderStates; avoids reallocation
+ byteBuf encBuffer // buffer for top-level encoderState
+ err error
+}
+
+// Before we encode a message, we reserve space at the head of the
+// buffer in which to encode its length. This means we can use the
+// buffer to assemble the message without another allocation.
+const maxLength = 9 // Maximum size of an encoded length.
+var spaceForLength = make([]byte, maxLength)
+
+// NewEncoder returns a new encoder that will transmit on the io.Writer.
+func NewEncoder(w io.Writer) *Encoder {
+ enc := new(Encoder)
+ enc.w = []io.Writer{w}
+ enc.sent = make(map[reflect.Type]typeId)
+ enc.countState = enc.newEncoderState(new(encBuffer))
+ return enc
+}
+
+// writer() returns the innermost writer the encoder is using
+func (enc *Encoder) writer() io.Writer {
+ return enc.w[len(enc.w)-1]
+}
+
+// pushWriter adds a writer to the encoder.
+func (enc *Encoder) pushWriter(w io.Writer) {
+ enc.w = append(enc.w, w)
+}
+
+// popWriter pops the innermost writer.
+func (enc *Encoder) popWriter() {
+ enc.w = enc.w[0 : len(enc.w)-1]
+}
+
+func (enc *Encoder) setError(err error) {
+ if enc.err == nil { // remember the first.
+ enc.err = err
+ }
+}
+
+// writeMessage sends the data item preceded by an unsigned count of its length.
+func (enc *Encoder) writeMessage(w io.Writer, b *encBuffer) {
+ // Space has been reserved for the length at the head of the message.
+ // This is a little dirty: we grab the slice from the bytes.Buffer and massage
+ // it by hand.
+ message := b.Bytes()
+ messageLen := len(message) - maxLength
+ // Length cannot be bigger than the decoder can handle.
+ if messageLen >= tooBig {
+ enc.setError(errors.New("gob: encoder: message too big"))
+ return
+ }
+ // Encode the length.
+ enc.countState.b.Reset()
+ enc.countState.encodeUint(uint64(messageLen))
+ // Copy the length to be a prefix of the message.
+ offset := maxLength - enc.countState.b.Len()
+ copy(message[offset:], enc.countState.b.Bytes())
+ // Write the data.
+ _, err := w.Write(message[offset:])
+ // Drain the buffer and restore the space at the front for the count of the next message.
+ b.Reset()
+ b.Write(spaceForLength)
+ if err != nil {
+ enc.setError(err)
+ }
+}
+
+// sendActualType sends the requested type, without further investigation, unless
+// it's been sent before.
+func (enc *Encoder) sendActualType(w io.Writer, state *encoderState, ut *userTypeInfo, actual reflect.Type) (sent bool) {
+ if _, alreadySent := enc.sent[actual]; alreadySent {
+ return false
+ }
+ info, err := getTypeInfo(ut)
+ if err != nil {
+ enc.setError(err)
+ return
+ }
+ // Send the pair (-id, type)
+ // Id:
+ state.encodeInt(-int64(info.id))
+ // Type:
+ enc.encode(state.b, reflect.ValueOf(info.wire), wireTypeUserInfo)
+ enc.writeMessage(w, state.b)
+ if enc.err != nil {
+ return
+ }
+
+ // Remember we've sent this type, both what the user gave us and the base type.
+ enc.sent[ut.base] = info.id
+ if ut.user != ut.base {
+ enc.sent[ut.user] = info.id
+ }
+ // Now send the inner types
+ switch st := actual; st.Kind() {
+ case reflect.Struct:
+ for i := 0; i < st.NumField(); i++ {
+ if isExported(st.Field(i).Name) {
+ enc.sendType(w, state, st.Field(i).Type)
+ }
+ }
+ case reflect.Array, reflect.Slice:
+ enc.sendType(w, state, st.Elem())
+ case reflect.Map:
+ enc.sendType(w, state, st.Key())
+ enc.sendType(w, state, st.Elem())
+ }
+ return true
+}
+
+// sendType sends the type info to the other side, if necessary.
+func (enc *Encoder) sendType(w io.Writer, state *encoderState, origt reflect.Type) (sent bool) {
+ ut := userType(origt)
+ if ut.externalEnc != 0 {
+ // The rules are different: regardless of the underlying type's representation,
+ // we need to tell the other side that the base type is a GobEncoder.
+ return enc.sendActualType(w, state, ut, ut.base)
+ }
+
+ // It's a concrete value, so drill down to the base type.
+ switch rt := ut.base; rt.Kind() {
+ default:
+ // Basic types and interfaces do not need to be described.
+ return
+ case reflect.Slice:
+ // If it's []uint8, don't send; it's considered basic.
+ if rt.Elem().Kind() == reflect.Uint8 {
+ return
+ }
+ // Otherwise we do send.
+ break
+ case reflect.Array:
+ // arrays must be sent so we know their lengths and element types.
+ break
+ case reflect.Map:
+ // maps must be sent so we know their lengths and key/value types.
+ break
+ case reflect.Struct:
+ // structs must be sent so we know their fields.
+ break
+ case reflect.Chan, reflect.Func:
+ // If we get here, it's a field of a struct; ignore it.
+ return
+ }
+
+ return enc.sendActualType(w, state, ut, ut.base)
+}
+
+// Encode transmits the data item represented by the empty interface value,
+// guaranteeing that all necessary type information has been transmitted first.
+// Passing a nil pointer to Encoder will panic, as they cannot be transmitted by gob.
+func (enc *Encoder) Encode(e any) error {
+ return enc.EncodeValue(reflect.ValueOf(e))
+}
+
+// sendTypeDescriptor makes sure the remote side knows about this type.
+// It will send a descriptor if this is the first time the type has been
+// sent.
+func (enc *Encoder) sendTypeDescriptor(w io.Writer, state *encoderState, ut *userTypeInfo) {
+ // Make sure the type is known to the other side.
+ // First, have we already sent this type?
+ rt := ut.base
+ if ut.externalEnc != 0 {
+ rt = ut.user
+ }
+ if _, alreadySent := enc.sent[rt]; !alreadySent {
+ // No, so send it.
+ sent := enc.sendType(w, state, rt)
+ if enc.err != nil {
+ return
+ }
+ // If the type info has still not been transmitted, it means we have
+ // a singleton basic type (int, []byte etc.) at top level. We don't
+ // need to send the type info but we do need to update enc.sent.
+ if !sent {
+ info, err := getTypeInfo(ut)
+ if err != nil {
+ enc.setError(err)
+ return
+ }
+ enc.sent[rt] = info.id
+ }
+ }
+}
+
+// sendTypeId sends the id, which must have already been defined.
+func (enc *Encoder) sendTypeId(state *encoderState, ut *userTypeInfo) {
+ // Identify the type of this top-level value.
+ state.encodeInt(int64(enc.sent[ut.base]))
+}
+
+// EncodeValue transmits the data item represented by the reflection value,
+// guaranteeing that all necessary type information has been transmitted first.
+// Passing a nil pointer to EncodeValue will panic, as they cannot be transmitted by gob.
+func (enc *Encoder) EncodeValue(value reflect.Value) error {
+ if value.Kind() == reflect.Invalid {
+ return errors.New("gob: cannot encode nil value")
+ }
+ if value.Kind() == reflect.Pointer && value.IsNil() {
+ panic("gob: cannot encode nil pointer of type " + value.Type().String())
+ }
+
+ // Make sure we're single-threaded through here, so multiple
+ // goroutines can share an encoder.
+ enc.mutex.Lock()
+ defer enc.mutex.Unlock()
+
+ // Remove any nested writers remaining due to previous errors.
+ enc.w = enc.w[0:1]
+
+ ut, err := validUserType(value.Type())
+ if err != nil {
+ return err
+ }
+
+ enc.err = nil
+ enc.byteBuf.Reset()
+ enc.byteBuf.Write(spaceForLength)
+ state := enc.newEncoderState(&enc.byteBuf)
+
+ enc.sendTypeDescriptor(enc.writer(), state, ut)
+ enc.sendTypeId(state, ut)
+ if enc.err != nil {
+ return enc.err
+ }
+
+ // Encode the object.
+ enc.encode(state.b, value, ut)
+ if enc.err == nil {
+ enc.writeMessage(enc.writer(), state.b)
+ }
+
+ enc.freeEncoderState(state)
+ return enc.err
+}
diff --git a/contrib/go/_std_1.20/src/encoding/gob/error.go b/contrib/go/_std_1.21/src/encoding/gob/error.go
index 9c614e3e3f..9c614e3e3f 100644
--- a/contrib/go/_std_1.20/src/encoding/gob/error.go
+++ b/contrib/go/_std_1.21/src/encoding/gob/error.go
diff --git a/contrib/go/_std_1.21/src/encoding/gob/type.go b/contrib/go/_std_1.21/src/encoding/gob/type.go
new file mode 100644
index 0000000000..bd7d91994c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/gob/type.go
@@ -0,0 +1,944 @@
+// Copyright 2009 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 gob
+
+import (
+ "encoding"
+ "errors"
+ "fmt"
+ "os"
+ "reflect"
+ "sync"
+ "sync/atomic"
+ "unicode"
+ "unicode/utf8"
+)
+
+// userTypeInfo stores the information associated with a type the user has handed
+// to the package. It's computed once and stored in a map keyed by reflection
+// type.
+type userTypeInfo struct {
+ user reflect.Type // the type the user handed us
+ base reflect.Type // the base type after all indirections
+ indir int // number of indirections to reach the base type
+ externalEnc int // xGob, xBinary, or xText
+ externalDec int // xGob, xBinary or xText
+ encIndir int8 // number of indirections to reach the receiver type; may be negative
+ decIndir int8 // number of indirections to reach the receiver type; may be negative
+}
+
+// externalEncoding bits
+const (
+ xGob = 1 + iota // GobEncoder or GobDecoder
+ xBinary // encoding.BinaryMarshaler or encoding.BinaryUnmarshaler
+ xText // encoding.TextMarshaler or encoding.TextUnmarshaler
+)
+
+var userTypeCache sync.Map // map[reflect.Type]*userTypeInfo
+
+// validUserType returns, and saves, the information associated with user-provided type rt.
+// If the user type is not valid, err will be non-nil. To be used when the error handler
+// is not set up.
+func validUserType(rt reflect.Type) (*userTypeInfo, error) {
+ if ui, ok := userTypeCache.Load(rt); ok {
+ return ui.(*userTypeInfo), nil
+ }
+
+ // Construct a new userTypeInfo and atomically add it to the userTypeCache.
+ // If we lose the race, we'll waste a little CPU and create a little garbage
+ // but return the existing value anyway.
+
+ ut := new(userTypeInfo)
+ ut.base = rt
+ ut.user = rt
+ // A type that is just a cycle of pointers (such as type T *T) cannot
+ // be represented in gobs, which need some concrete data. We use a
+ // cycle detection algorithm from Knuth, Vol 2, Section 3.1, Ex 6,
+ // pp 539-540. As we step through indirections, run another type at
+ // half speed. If they meet up, there's a cycle.
+ slowpoke := ut.base // walks half as fast as ut.base
+ for {
+ pt := ut.base
+ if pt.Kind() != reflect.Pointer {
+ break
+ }
+ ut.base = pt.Elem()
+ if ut.base == slowpoke { // ut.base lapped slowpoke
+ // recursive pointer type.
+ return nil, errors.New("can't represent recursive pointer type " + ut.base.String())
+ }
+ if ut.indir%2 == 0 {
+ slowpoke = slowpoke.Elem()
+ }
+ ut.indir++
+ }
+
+ if ok, indir := implementsInterface(ut.user, gobEncoderInterfaceType); ok {
+ ut.externalEnc, ut.encIndir = xGob, indir
+ } else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok {
+ ut.externalEnc, ut.encIndir = xBinary, indir
+ }
+
+ // NOTE(rsc): Would like to allow MarshalText here, but results in incompatibility
+ // with older encodings for net.IP. See golang.org/issue/6760.
+ // } else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
+ // ut.externalEnc, ut.encIndir = xText, indir
+ // }
+
+ if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok {
+ ut.externalDec, ut.decIndir = xGob, indir
+ } else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok {
+ ut.externalDec, ut.decIndir = xBinary, indir
+ }
+
+ // See note above.
+ // } else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
+ // ut.externalDec, ut.decIndir = xText, indir
+ // }
+
+ ui, _ := userTypeCache.LoadOrStore(rt, ut)
+ return ui.(*userTypeInfo), nil
+}
+
+var (
+ gobEncoderInterfaceType = reflect.TypeOf((*GobEncoder)(nil)).Elem()
+ gobDecoderInterfaceType = reflect.TypeOf((*GobDecoder)(nil)).Elem()
+ binaryMarshalerInterfaceType = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem()
+ binaryUnmarshalerInterfaceType = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem()
+ textMarshalerInterfaceType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
+ textUnmarshalerInterfaceType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+
+ wireTypeType = reflect.TypeOf((*wireType)(nil)).Elem()
+)
+
+// implementsInterface reports whether the type implements the
+// gobEncoder/gobDecoder interface.
+// It also returns the number of indirections required to get to the
+// implementation.
+func implementsInterface(typ, gobEncDecType reflect.Type) (success bool, indir int8) {
+ if typ == nil {
+ return
+ }
+ rt := typ
+ // The type might be a pointer and we need to keep
+ // dereferencing to the base type until we find an implementation.
+ for {
+ if rt.Implements(gobEncDecType) {
+ return true, indir
+ }
+ if p := rt; p.Kind() == reflect.Pointer {
+ indir++
+ if indir > 100 { // insane number of indirections
+ return false, 0
+ }
+ rt = p.Elem()
+ continue
+ }
+ break
+ }
+ // No luck yet, but if this is a base type (non-pointer), the pointer might satisfy.
+ if typ.Kind() != reflect.Pointer {
+ // Not a pointer, but does the pointer work?
+ if reflect.PointerTo(typ).Implements(gobEncDecType) {
+ return true, -1
+ }
+ }
+ return false, 0
+}
+
+// userType returns, and saves, the information associated with user-provided type rt.
+// If the user type is not valid, it calls error.
+func userType(rt reflect.Type) *userTypeInfo {
+ ut, err := validUserType(rt)
+ if err != nil {
+ error_(err)
+ }
+ return ut
+}
+
+// A typeId represents a gob Type as an integer that can be passed on the wire.
+// Internally, typeIds are used as keys to a map to recover the underlying type info.
+type typeId int32
+
+var typeLock sync.Mutex // set while building a type
+const firstUserId = 64 // lowest id number granted to user
+
+type gobType interface {
+ id() typeId
+ setId(id typeId)
+ name() string
+ string() string // not public; only for debugging
+ safeString(seen map[typeId]bool) string
+}
+
+var (
+ types = make(map[reflect.Type]gobType, 32)
+ idToTypeSlice = make([]gobType, 1, firstUserId)
+ builtinIdToTypeSlice [firstUserId]gobType // set in init() after builtins are established
+)
+
+func idToType(id typeId) gobType {
+ if id < 0 || int(id) >= len(idToTypeSlice) {
+ return nil
+ }
+ return idToTypeSlice[id]
+}
+
+func builtinIdToType(id typeId) gobType {
+ if id < 0 || int(id) >= len(builtinIdToTypeSlice) {
+ return nil
+ }
+ return builtinIdToTypeSlice[id]
+}
+
+func setTypeId(typ gobType) {
+ // When building recursive types, someone may get there before us.
+ if typ.id() != 0 {
+ return
+ }
+ nextId := typeId(len(idToTypeSlice))
+ typ.setId(nextId)
+ idToTypeSlice = append(idToTypeSlice, typ)
+}
+
+func (t typeId) gobType() gobType {
+ if t == 0 {
+ return nil
+ }
+ return idToType(t)
+}
+
+// string returns the string representation of the type associated with the typeId.
+func (t typeId) string() string {
+ if t.gobType() == nil {
+ return "<nil>"
+ }
+ return t.gobType().string()
+}
+
+// Name returns the name of the type associated with the typeId.
+func (t typeId) name() string {
+ if t.gobType() == nil {
+ return "<nil>"
+ }
+ return t.gobType().name()
+}
+
+// CommonType holds elements of all types.
+// It is a historical artifact, kept for binary compatibility and exported
+// only for the benefit of the package's encoding of type descriptors. It is
+// not intended for direct use by clients.
+type CommonType struct {
+ Name string
+ Id typeId
+}
+
+func (t *CommonType) id() typeId { return t.Id }
+
+func (t *CommonType) setId(id typeId) { t.Id = id }
+
+func (t *CommonType) string() string { return t.Name }
+
+func (t *CommonType) safeString(seen map[typeId]bool) string {
+ return t.Name
+}
+
+func (t *CommonType) name() string { return t.Name }
+
+// Create and check predefined types
+// The string for tBytes is "bytes" not "[]byte" to signify its specialness.
+
+var (
+ // Primordial types, needed during initialization.
+ // Always passed as pointers so the interface{} type
+ // goes through without losing its interfaceness.
+ tBool = bootstrapType("bool", (*bool)(nil))
+ tInt = bootstrapType("int", (*int)(nil))
+ tUint = bootstrapType("uint", (*uint)(nil))
+ tFloat = bootstrapType("float", (*float64)(nil))
+ tBytes = bootstrapType("bytes", (*[]byte)(nil))
+ tString = bootstrapType("string", (*string)(nil))
+ tComplex = bootstrapType("complex", (*complex128)(nil))
+ tInterface = bootstrapType("interface", (*any)(nil))
+ // Reserve some Ids for compatible expansion
+ tReserved7 = bootstrapType("_reserved1", (*struct{ r7 int })(nil))
+ tReserved6 = bootstrapType("_reserved1", (*struct{ r6 int })(nil))
+ tReserved5 = bootstrapType("_reserved1", (*struct{ r5 int })(nil))
+ tReserved4 = bootstrapType("_reserved1", (*struct{ r4 int })(nil))
+ tReserved3 = bootstrapType("_reserved1", (*struct{ r3 int })(nil))
+ tReserved2 = bootstrapType("_reserved1", (*struct{ r2 int })(nil))
+ tReserved1 = bootstrapType("_reserved1", (*struct{ r1 int })(nil))
+)
+
+// Predefined because it's needed by the Decoder
+var tWireType = mustGetTypeInfo(wireTypeType).id
+var wireTypeUserInfo *userTypeInfo // userTypeInfo of wireType
+
+func init() {
+ // Some magic numbers to make sure there are no surprises.
+ checkId(16, tWireType)
+ checkId(17, mustGetTypeInfo(reflect.TypeOf((*arrayType)(nil)).Elem()).id)
+ checkId(18, mustGetTypeInfo(reflect.TypeOf((*CommonType)(nil)).Elem()).id)
+ checkId(19, mustGetTypeInfo(reflect.TypeOf((*sliceType)(nil)).Elem()).id)
+ checkId(20, mustGetTypeInfo(reflect.TypeOf((*structType)(nil)).Elem()).id)
+ checkId(21, mustGetTypeInfo(reflect.TypeOf((*fieldType)(nil)).Elem()).id)
+ checkId(23, mustGetTypeInfo(reflect.TypeOf((*mapType)(nil)).Elem()).id)
+
+ copy(builtinIdToTypeSlice[:], idToTypeSlice)
+
+ // Move the id space upwards to allow for growth in the predefined world
+ // without breaking existing files.
+ if nextId := len(idToTypeSlice); nextId > firstUserId {
+ panic(fmt.Sprintln("nextId too large:", nextId))
+ }
+ idToTypeSlice = idToTypeSlice[:firstUserId]
+ registerBasics()
+ wireTypeUserInfo = userType(wireTypeType)
+}
+
+// Array type
+type arrayType struct {
+ CommonType
+ Elem typeId
+ Len int
+}
+
+func newArrayType(name string) *arrayType {
+ a := &arrayType{CommonType{Name: name}, 0, 0}
+ return a
+}
+
+func (a *arrayType) init(elem gobType, len int) {
+ // Set our type id before evaluating the element's, in case it's our own.
+ setTypeId(a)
+ a.Elem = elem.id()
+ a.Len = len
+}
+
+func (a *arrayType) safeString(seen map[typeId]bool) string {
+ if seen[a.Id] {
+ return a.Name
+ }
+ seen[a.Id] = true
+ return fmt.Sprintf("[%d]%s", a.Len, a.Elem.gobType().safeString(seen))
+}
+
+func (a *arrayType) string() string { return a.safeString(make(map[typeId]bool)) }
+
+// GobEncoder type (something that implements the GobEncoder interface)
+type gobEncoderType struct {
+ CommonType
+}
+
+func newGobEncoderType(name string) *gobEncoderType {
+ g := &gobEncoderType{CommonType{Name: name}}
+ setTypeId(g)
+ return g
+}
+
+func (g *gobEncoderType) safeString(seen map[typeId]bool) string {
+ return g.Name
+}
+
+func (g *gobEncoderType) string() string { return g.Name }
+
+// Map type
+type mapType struct {
+ CommonType
+ Key typeId
+ Elem typeId
+}
+
+func newMapType(name string) *mapType {
+ m := &mapType{CommonType{Name: name}, 0, 0}
+ return m
+}
+
+func (m *mapType) init(key, elem gobType) {
+ // Set our type id before evaluating the element's, in case it's our own.
+ setTypeId(m)
+ m.Key = key.id()
+ m.Elem = elem.id()
+}
+
+func (m *mapType) safeString(seen map[typeId]bool) string {
+ if seen[m.Id] {
+ return m.Name
+ }
+ seen[m.Id] = true
+ key := m.Key.gobType().safeString(seen)
+ elem := m.Elem.gobType().safeString(seen)
+ return fmt.Sprintf("map[%s]%s", key, elem)
+}
+
+func (m *mapType) string() string { return m.safeString(make(map[typeId]bool)) }
+
+// Slice type
+type sliceType struct {
+ CommonType
+ Elem typeId
+}
+
+func newSliceType(name string) *sliceType {
+ s := &sliceType{CommonType{Name: name}, 0}
+ return s
+}
+
+func (s *sliceType) init(elem gobType) {
+ // Set our type id before evaluating the element's, in case it's our own.
+ setTypeId(s)
+ // See the comments about ids in newTypeObject. Only slices and
+ // structs have mutual recursion.
+ if elem.id() == 0 {
+ setTypeId(elem)
+ }
+ s.Elem = elem.id()
+}
+
+func (s *sliceType) safeString(seen map[typeId]bool) string {
+ if seen[s.Id] {
+ return s.Name
+ }
+ seen[s.Id] = true
+ return fmt.Sprintf("[]%s", s.Elem.gobType().safeString(seen))
+}
+
+func (s *sliceType) string() string { return s.safeString(make(map[typeId]bool)) }
+
+// Struct type
+type fieldType struct {
+ Name string
+ Id typeId
+}
+
+type structType struct {
+ CommonType
+ Field []fieldType
+}
+
+func (s *structType) safeString(seen map[typeId]bool) string {
+ if s == nil {
+ return "<nil>"
+ }
+ if _, ok := seen[s.Id]; ok {
+ return s.Name
+ }
+ seen[s.Id] = true
+ str := s.Name + " = struct { "
+ for _, f := range s.Field {
+ str += fmt.Sprintf("%s %s; ", f.Name, f.Id.gobType().safeString(seen))
+ }
+ str += "}"
+ return str
+}
+
+func (s *structType) string() string { return s.safeString(make(map[typeId]bool)) }
+
+func newStructType(name string) *structType {
+ s := &structType{CommonType{Name: name}, nil}
+ // For historical reasons we set the id here rather than init.
+ // See the comment in newTypeObject for details.
+ setTypeId(s)
+ return s
+}
+
+// newTypeObject allocates a gobType for the reflection type rt.
+// Unless ut represents a GobEncoder, rt should be the base type
+// of ut.
+// This is only called from the encoding side. The decoding side
+// works through typeIds and userTypeInfos alone.
+func newTypeObject(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
+ // Does this type implement GobEncoder?
+ if ut.externalEnc != 0 {
+ return newGobEncoderType(name), nil
+ }
+ var err error
+ var type0, type1 gobType
+ defer func() {
+ if err != nil {
+ delete(types, rt)
+ }
+ }()
+ // Install the top-level type before the subtypes (e.g. struct before
+ // fields) so recursive types can be constructed safely.
+ switch t := rt; t.Kind() {
+ // All basic types are easy: they are predefined.
+ case reflect.Bool:
+ return tBool.gobType(), nil
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return tInt.gobType(), nil
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return tUint.gobType(), nil
+
+ case reflect.Float32, reflect.Float64:
+ return tFloat.gobType(), nil
+
+ case reflect.Complex64, reflect.Complex128:
+ return tComplex.gobType(), nil
+
+ case reflect.String:
+ return tString.gobType(), nil
+
+ case reflect.Interface:
+ return tInterface.gobType(), nil
+
+ case reflect.Array:
+ at := newArrayType(name)
+ types[rt] = at
+ type0, err = getBaseType("", t.Elem())
+ if err != nil {
+ return nil, err
+ }
+ // Historical aside:
+ // For arrays, maps, and slices, we set the type id after the elements
+ // are constructed. This is to retain the order of type id allocation after
+ // a fix made to handle recursive types, which changed the order in
+ // which types are built. Delaying the setting in this way preserves
+ // type ids while allowing recursive types to be described. Structs,
+ // done below, were already handling recursion correctly so they
+ // assign the top-level id before those of the field.
+ at.init(type0, t.Len())
+ return at, nil
+
+ case reflect.Map:
+ mt := newMapType(name)
+ types[rt] = mt
+ type0, err = getBaseType("", t.Key())
+ if err != nil {
+ return nil, err
+ }
+ type1, err = getBaseType("", t.Elem())
+ if err != nil {
+ return nil, err
+ }
+ mt.init(type0, type1)
+ return mt, nil
+
+ case reflect.Slice:
+ // []byte == []uint8 is a special case
+ if t.Elem().Kind() == reflect.Uint8 {
+ return tBytes.gobType(), nil
+ }
+ st := newSliceType(name)
+ types[rt] = st
+ type0, err = getBaseType(t.Elem().Name(), t.Elem())
+ if err != nil {
+ return nil, err
+ }
+ st.init(type0)
+ return st, nil
+
+ case reflect.Struct:
+ st := newStructType(name)
+ types[rt] = st
+ idToTypeSlice[st.id()] = st
+ for i := 0; i < t.NumField(); i++ {
+ f := t.Field(i)
+ if !isSent(&f) {
+ continue
+ }
+ typ := userType(f.Type).base
+ tname := typ.Name()
+ if tname == "" {
+ t := userType(f.Type).base
+ tname = t.String()
+ }
+ gt, err := getBaseType(tname, f.Type)
+ if err != nil {
+ return nil, err
+ }
+ // Some mutually recursive types can cause us to be here while
+ // still defining the element. Fix the element type id here.
+ // We could do this more neatly by setting the id at the start of
+ // building every type, but that would break binary compatibility.
+ if gt.id() == 0 {
+ setTypeId(gt)
+ }
+ st.Field = append(st.Field, fieldType{f.Name, gt.id()})
+ }
+ return st, nil
+
+ default:
+ return nil, errors.New("gob NewTypeObject can't handle type: " + rt.String())
+ }
+}
+
+// isExported reports whether this is an exported - upper case - name.
+func isExported(name string) bool {
+ rune, _ := utf8.DecodeRuneInString(name)
+ return unicode.IsUpper(rune)
+}
+
+// isSent reports whether this struct field is to be transmitted.
+// It will be transmitted only if it is exported and not a chan or func field
+// or pointer to chan or func.
+func isSent(field *reflect.StructField) bool {
+ if !isExported(field.Name) {
+ return false
+ }
+ // If the field is a chan or func or pointer thereto, don't send it.
+ // That is, treat it like an unexported field.
+ typ := field.Type
+ for typ.Kind() == reflect.Pointer {
+ typ = typ.Elem()
+ }
+ if typ.Kind() == reflect.Chan || typ.Kind() == reflect.Func {
+ return false
+ }
+ return true
+}
+
+// getBaseType returns the Gob type describing the given reflect.Type's base type.
+// typeLock must be held.
+func getBaseType(name string, rt reflect.Type) (gobType, error) {
+ ut := userType(rt)
+ return getType(name, ut, ut.base)
+}
+
+// getType returns the Gob type describing the given reflect.Type.
+// Should be called only when handling GobEncoders/Decoders,
+// which may be pointers. All other types are handled through the
+// base type, never a pointer.
+// typeLock must be held.
+func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
+ typ, present := types[rt]
+ if present {
+ return typ, nil
+ }
+ typ, err := newTypeObject(name, ut, rt)
+ if err == nil {
+ types[rt] = typ
+ }
+ return typ, err
+}
+
+func checkId(want, got typeId) {
+ if want != got {
+ fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(got), int(want))
+ panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string())
+ }
+}
+
+// used for building the basic types; called only from init(). the incoming
+// interface always refers to a pointer.
+func bootstrapType(name string, e any) typeId {
+ rt := reflect.TypeOf(e).Elem()
+ _, present := types[rt]
+ if present {
+ panic("bootstrap type already present: " + name + ", " + rt.String())
+ }
+ typ := &CommonType{Name: name}
+ types[rt] = typ
+ setTypeId(typ)
+ return typ.id()
+}
+
+// Representation of the information we send and receive about this type.
+// Each value we send is preceded by its type definition: an encoded int.
+// However, the very first time we send the value, we first send the pair
+// (-id, wireType).
+// For bootstrapping purposes, we assume that the recipient knows how
+// to decode a wireType; it is exactly the wireType struct here, interpreted
+// using the gob rules for sending a structure, except that we assume the
+// ids for wireType and structType etc. are known. The relevant pieces
+// are built in encode.go's init() function.
+// To maintain binary compatibility, if you extend this type, always put
+// the new fields last.
+type wireType struct {
+ ArrayT *arrayType
+ SliceT *sliceType
+ StructT *structType
+ MapT *mapType
+ GobEncoderT *gobEncoderType
+ BinaryMarshalerT *gobEncoderType
+ TextMarshalerT *gobEncoderType
+}
+
+func (w *wireType) string() string {
+ const unknown = "unknown type"
+ if w == nil {
+ return unknown
+ }
+ switch {
+ case w.ArrayT != nil:
+ return w.ArrayT.Name
+ case w.SliceT != nil:
+ return w.SliceT.Name
+ case w.StructT != nil:
+ return w.StructT.Name
+ case w.MapT != nil:
+ return w.MapT.Name
+ case w.GobEncoderT != nil:
+ return w.GobEncoderT.Name
+ case w.BinaryMarshalerT != nil:
+ return w.BinaryMarshalerT.Name
+ case w.TextMarshalerT != nil:
+ return w.TextMarshalerT.Name
+ }
+ return unknown
+}
+
+type typeInfo struct {
+ id typeId
+ encInit sync.Mutex // protects creation of encoder
+ encoder atomic.Pointer[encEngine]
+ wire wireType
+}
+
+// typeInfoMap is an atomic pointer to map[reflect.Type]*typeInfo.
+// It's updated copy-on-write. Readers just do an atomic load
+// to get the current version of the map. Writers make a full copy of
+// the map and atomically update the pointer to point to the new map.
+// Under heavy read contention, this is significantly faster than a map
+// protected by a mutex.
+var typeInfoMap atomic.Value
+
+// typeInfoMapInit is used instead of typeInfoMap during init time,
+// as types are registered sequentially during init and we can save
+// the overhead of making map copies.
+// It is saved to typeInfoMap and set to nil before init finishes.
+var typeInfoMapInit = make(map[reflect.Type]*typeInfo, 16)
+
+func lookupTypeInfo(rt reflect.Type) *typeInfo {
+ if m := typeInfoMapInit; m != nil {
+ return m[rt]
+ }
+ m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
+ return m[rt]
+}
+
+func getTypeInfo(ut *userTypeInfo) (*typeInfo, error) {
+ rt := ut.base
+ if ut.externalEnc != 0 {
+ // We want the user type, not the base type.
+ rt = ut.user
+ }
+ if info := lookupTypeInfo(rt); info != nil {
+ return info, nil
+ }
+ return buildTypeInfo(ut, rt)
+}
+
+// buildTypeInfo constructs the type information for the type
+// and stores it in the type info map.
+func buildTypeInfo(ut *userTypeInfo, rt reflect.Type) (*typeInfo, error) {
+ typeLock.Lock()
+ defer typeLock.Unlock()
+
+ if info := lookupTypeInfo(rt); info != nil {
+ return info, nil
+ }
+
+ gt, err := getBaseType(rt.Name(), rt)
+ if err != nil {
+ return nil, err
+ }
+ info := &typeInfo{id: gt.id()}
+
+ if ut.externalEnc != 0 {
+ userType, err := getType(rt.Name(), ut, rt)
+ if err != nil {
+ return nil, err
+ }
+ gt := userType.id().gobType().(*gobEncoderType)
+ switch ut.externalEnc {
+ case xGob:
+ info.wire.GobEncoderT = gt
+ case xBinary:
+ info.wire.BinaryMarshalerT = gt
+ case xText:
+ info.wire.TextMarshalerT = gt
+ }
+ rt = ut.user
+ } else {
+ t := info.id.gobType()
+ switch typ := rt; typ.Kind() {
+ case reflect.Array:
+ info.wire.ArrayT = t.(*arrayType)
+ case reflect.Map:
+ info.wire.MapT = t.(*mapType)
+ case reflect.Slice:
+ // []byte == []uint8 is a special case handled separately
+ if typ.Elem().Kind() != reflect.Uint8 {
+ info.wire.SliceT = t.(*sliceType)
+ }
+ case reflect.Struct:
+ info.wire.StructT = t.(*structType)
+ }
+ }
+
+ if m := typeInfoMapInit; m != nil {
+ m[rt] = info
+ return info, nil
+ }
+
+ // Create new map with old contents plus new entry.
+ m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
+ newm := make(map[reflect.Type]*typeInfo, len(m))
+ for k, v := range m {
+ newm[k] = v
+ }
+ newm[rt] = info
+ typeInfoMap.Store(newm)
+ return info, nil
+}
+
+// Called only when a panic is acceptable and unexpected.
+func mustGetTypeInfo(rt reflect.Type) *typeInfo {
+ t, err := getTypeInfo(userType(rt))
+ if err != nil {
+ panic("getTypeInfo: " + err.Error())
+ }
+ return t
+}
+
+// GobEncoder is the interface describing data that provides its own
+// representation for encoding values for transmission to a GobDecoder.
+// A type that implements GobEncoder and GobDecoder has complete
+// control over the representation of its data and may therefore
+// contain things such as private fields, channels, and functions,
+// which are not usually transmissible in gob streams.
+//
+// Note: Since gobs can be stored permanently, it is good design
+// to guarantee the encoding used by a GobEncoder is stable as the
+// software evolves. For instance, it might make sense for GobEncode
+// to include a version number in the encoding.
+type GobEncoder interface {
+ // GobEncode returns a byte slice representing the encoding of the
+ // receiver for transmission to a GobDecoder, usually of the same
+ // concrete type.
+ GobEncode() ([]byte, error)
+}
+
+// GobDecoder is the interface describing data that provides its own
+// routine for decoding transmitted values sent by a GobEncoder.
+type GobDecoder interface {
+ // GobDecode overwrites the receiver, which must be a pointer,
+ // with the value represented by the byte slice, which was written
+ // by GobEncode, usually for the same concrete type.
+ GobDecode([]byte) error
+}
+
+var (
+ nameToConcreteType sync.Map // map[string]reflect.Type
+ concreteTypeToName sync.Map // map[reflect.Type]string
+)
+
+// RegisterName is like Register but uses the provided name rather than the
+// type's default.
+func RegisterName(name string, value any) {
+ if name == "" {
+ // reserved for nil
+ panic("attempt to register empty name")
+ }
+
+ ut := userType(reflect.TypeOf(value))
+
+ // Check for incompatible duplicates. The name must refer to the
+ // same user type, and vice versa.
+
+ // Store the name and type provided by the user....
+ if t, dup := nameToConcreteType.LoadOrStore(name, reflect.TypeOf(value)); dup && t != ut.user {
+ panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", name, t, ut.user))
+ }
+
+ // but the flattened type in the type table, since that's what decode needs.
+ if n, dup := concreteTypeToName.LoadOrStore(ut.base, name); dup && n != name {
+ nameToConcreteType.Delete(name)
+ panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", ut.user, n, name))
+ }
+}
+
+// Register records a type, identified by a value for that type, under its
+// internal type name. That name will identify the concrete type of a value
+// sent or received as an interface variable. Only types that will be
+// transferred as implementations of interface values need to be registered.
+// Expecting to be used only during initialization, it panics if the mapping
+// between types and names is not a bijection.
+func Register(value any) {
+ // Default to printed representation for unnamed types
+ rt := reflect.TypeOf(value)
+ name := rt.String()
+
+ // But for named types (or pointers to them), qualify with import path (but see inner comment).
+ // Dereference one pointer looking for a named type.
+ star := ""
+ if rt.Name() == "" {
+ if pt := rt; pt.Kind() == reflect.Pointer {
+ star = "*"
+ // NOTE: The following line should be rt = pt.Elem() to implement
+ // what the comment above claims, but fixing it would break compatibility
+ // with existing gobs.
+ //
+ // Given package p imported as "full/p" with these definitions:
+ // package p
+ // type T1 struct { ... }
+ // this table shows the intended and actual strings used by gob to
+ // name the types:
+ //
+ // Type Correct string Actual string
+ //
+ // T1 full/p.T1 full/p.T1
+ // *T1 *full/p.T1 *p.T1
+ //
+ // The missing full path cannot be fixed without breaking existing gob decoders.
+ rt = pt
+ }
+ }
+ if rt.Name() != "" {
+ if rt.PkgPath() == "" {
+ name = star + rt.Name()
+ } else {
+ name = star + rt.PkgPath() + "." + rt.Name()
+ }
+ }
+
+ RegisterName(name, value)
+}
+
+func registerBasics() {
+ Register(int(0))
+ Register(int8(0))
+ Register(int16(0))
+ Register(int32(0))
+ Register(int64(0))
+ Register(uint(0))
+ Register(uint8(0))
+ Register(uint16(0))
+ Register(uint32(0))
+ Register(uint64(0))
+ Register(float32(0))
+ Register(float64(0))
+ Register(complex64(0i))
+ Register(complex128(0i))
+ Register(uintptr(0))
+ Register(false)
+ Register("")
+ Register([]byte(nil))
+ Register([]int(nil))
+ Register([]int8(nil))
+ Register([]int16(nil))
+ Register([]int32(nil))
+ Register([]int64(nil))
+ Register([]uint(nil))
+ Register([]uint8(nil))
+ Register([]uint16(nil))
+ Register([]uint32(nil))
+ Register([]uint64(nil))
+ Register([]float32(nil))
+ Register([]float64(nil))
+ Register([]complex64(nil))
+ Register([]complex128(nil))
+ Register([]uintptr(nil))
+ Register([]bool(nil))
+ Register([]string(nil))
+}
+
+func init() {
+ typeInfoMap.Store(typeInfoMapInit)
+ typeInfoMapInit = nil
+}
diff --git a/contrib/go/_std_1.21/src/encoding/gob/ya.make b/contrib/go/_std_1.21/src/encoding/gob/ya.make
new file mode 100644
index 0000000000..b938a1e9fc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/gob/ya.make
@@ -0,0 +1,32 @@
+GO_LIBRARY()
+
+SRCS(
+ dec_helpers.go
+ decode.go
+ decoder.go
+ doc.go
+ enc_helpers.go
+ encode.go
+ encoder.go
+ error.go
+ type.go
+)
+
+GO_TEST_SRCS(
+ codec_test.go
+ encoder_test.go
+ gobencdec_test.go
+ timing_test.go
+ type_test.go
+)
+
+GO_XTEST_SRCS(
+ example_encdec_test.go
+ example_interface_test.go
+ example_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/encoding/hex/hex.go b/contrib/go/_std_1.21/src/encoding/hex/hex.go
index 375f583170..375f583170 100644
--- a/contrib/go/_std_1.20/src/encoding/hex/hex.go
+++ b/contrib/go/_std_1.21/src/encoding/hex/hex.go
diff --git a/contrib/go/_std_1.21/src/encoding/hex/ya.make b/contrib/go/_std_1.21/src/encoding/hex/ya.make
new file mode 100644
index 0000000000..eb9affc90a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/hex/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ hex.go
+)
+
+GO_TEST_SRCS(hex_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/encoding/json/decode.go b/contrib/go/_std_1.21/src/encoding/json/decode.go
new file mode 100644
index 0000000000..53470d8c88
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/json/decode.go
@@ -0,0 +1,1291 @@
+// Copyright 2010 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.
+
+// Represents JSON data structure using native Go types: booleans, floats,
+// strings, arrays, and maps.
+
+package json
+
+import (
+ "encoding"
+ "encoding/base64"
+ "fmt"
+ "reflect"
+ "strconv"
+ "strings"
+ "unicode"
+ "unicode/utf16"
+ "unicode/utf8"
+)
+
+// Unmarshal parses the JSON-encoded data and stores the result
+// in the value pointed to by v. If v is nil or not a pointer,
+// Unmarshal returns an InvalidUnmarshalError.
+//
+// Unmarshal uses the inverse of the encodings that
+// Marshal uses, allocating maps, slices, and pointers as necessary,
+// with the following additional rules:
+//
+// To unmarshal JSON into a pointer, Unmarshal first handles the case of
+// the JSON being the JSON literal null. In that case, Unmarshal sets
+// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into
+// the value pointed at by the pointer. If the pointer is nil, Unmarshal
+// allocates a new value for it to point to.
+//
+// To unmarshal JSON into a value implementing the Unmarshaler interface,
+// Unmarshal calls that value's UnmarshalJSON method, including
+// when the input is a JSON null.
+// Otherwise, if the value implements encoding.TextUnmarshaler
+// and the input is a JSON quoted string, Unmarshal calls that value's
+// UnmarshalText method with the unquoted form of the string.
+//
+// To unmarshal JSON into a struct, Unmarshal matches incoming object
+// keys to the keys used by Marshal (either the struct field name or its tag),
+// preferring an exact match but also accepting a case-insensitive match. By
+// default, object keys which don't have a corresponding struct field are
+// ignored (see Decoder.DisallowUnknownFields for an alternative).
+//
+// To unmarshal JSON into an interface value,
+// Unmarshal stores one of these in the interface value:
+//
+// bool, for JSON booleans
+// float64, for JSON numbers
+// string, for JSON strings
+// []interface{}, for JSON arrays
+// map[string]interface{}, for JSON objects
+// nil for JSON null
+//
+// To unmarshal a JSON array into a slice, Unmarshal resets the slice length
+// to zero and then appends each element to the slice.
+// As a special case, to unmarshal an empty JSON array into a slice,
+// Unmarshal replaces the slice with a new empty slice.
+//
+// To unmarshal a JSON array into a Go array, Unmarshal decodes
+// JSON array elements into corresponding Go array elements.
+// If the Go array is smaller than the JSON array,
+// the additional JSON array elements are discarded.
+// If the JSON array is smaller than the Go array,
+// the additional Go array elements are set to zero values.
+//
+// To unmarshal a JSON object into a map, Unmarshal first establishes a map to
+// use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal
+// reuses the existing map, keeping existing entries. Unmarshal then stores
+// key-value pairs from the JSON object into the map. The map's key type must
+// either be any string type, an integer, implement json.Unmarshaler, or
+// implement encoding.TextUnmarshaler.
+//
+// If the JSON-encoded data contain a syntax error, Unmarshal returns a SyntaxError.
+//
+// If a JSON value is not appropriate for a given target type,
+// or if a JSON number overflows the target type, Unmarshal
+// skips that field and completes the unmarshaling as best it can.
+// If no more serious errors are encountered, Unmarshal returns
+// an UnmarshalTypeError describing the earliest such error. In any
+// case, it's not guaranteed that all the remaining fields following
+// the problematic one will be unmarshaled into the target object.
+//
+// The JSON null value unmarshals into an interface, map, pointer, or slice
+// by setting that Go value to nil. Because null is often used in JSON to mean
+// “not present,” unmarshaling a JSON null into any other Go type has no effect
+// on the value and produces no error.
+//
+// When unmarshaling quoted strings, invalid UTF-8 or
+// invalid UTF-16 surrogate pairs are not treated as an error.
+// Instead, they are replaced by the Unicode replacement
+// character U+FFFD.
+func Unmarshal(data []byte, v any) error {
+ // Check for well-formedness.
+ // Avoids filling out half a data structure
+ // before discovering a JSON syntax error.
+ var d decodeState
+ err := checkValid(data, &d.scan)
+ if err != nil {
+ return err
+ }
+
+ d.init(data)
+ return d.unmarshal(v)
+}
+
+// Unmarshaler is the interface implemented by types
+// that can unmarshal a JSON description of themselves.
+// The input can be assumed to be a valid encoding of
+// a JSON value. UnmarshalJSON must copy the JSON data
+// if it wishes to retain the data after returning.
+//
+// By convention, to approximate the behavior of Unmarshal itself,
+// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.
+type Unmarshaler interface {
+ UnmarshalJSON([]byte) error
+}
+
+// An UnmarshalTypeError describes a JSON value that was
+// not appropriate for a value of a specific Go type.
+type UnmarshalTypeError struct {
+ Value string // description of JSON value - "bool", "array", "number -5"
+ Type reflect.Type // type of Go value it could not be assigned to
+ Offset int64 // error occurred after reading Offset bytes
+ Struct string // name of the struct type containing the field
+ Field string // the full path from root node to the field
+}
+
+func (e *UnmarshalTypeError) Error() string {
+ if e.Struct != "" || e.Field != "" {
+ return "json: cannot unmarshal " + e.Value + " into Go struct field " + e.Struct + "." + e.Field + " of type " + e.Type.String()
+ }
+ return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String()
+}
+
+// An UnmarshalFieldError describes a JSON object key that
+// led to an unexported (and therefore unwritable) struct field.
+//
+// Deprecated: No longer used; kept for compatibility.
+type UnmarshalFieldError struct {
+ Key string
+ Type reflect.Type
+ Field reflect.StructField
+}
+
+func (e *UnmarshalFieldError) Error() string {
+ return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String()
+}
+
+// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
+// (The argument to Unmarshal must be a non-nil pointer.)
+type InvalidUnmarshalError struct {
+ Type reflect.Type
+}
+
+func (e *InvalidUnmarshalError) Error() string {
+ if e.Type == nil {
+ return "json: Unmarshal(nil)"
+ }
+
+ if e.Type.Kind() != reflect.Pointer {
+ return "json: Unmarshal(non-pointer " + e.Type.String() + ")"
+ }
+ return "json: Unmarshal(nil " + e.Type.String() + ")"
+}
+
+func (d *decodeState) unmarshal(v any) error {
+ rv := reflect.ValueOf(v)
+ if rv.Kind() != reflect.Pointer || rv.IsNil() {
+ return &InvalidUnmarshalError{reflect.TypeOf(v)}
+ }
+
+ d.scan.reset()
+ d.scanWhile(scanSkipSpace)
+ // We decode rv not rv.Elem because the Unmarshaler interface
+ // test must be applied at the top level of the value.
+ err := d.value(rv)
+ if err != nil {
+ return d.addErrorContext(err)
+ }
+ return d.savedError
+}
+
+// A Number represents a JSON number literal.
+type Number string
+
+// String returns the literal text of the number.
+func (n Number) String() string { return string(n) }
+
+// Float64 returns the number as a float64.
+func (n Number) Float64() (float64, error) {
+ return strconv.ParseFloat(string(n), 64)
+}
+
+// Int64 returns the number as an int64.
+func (n Number) Int64() (int64, error) {
+ return strconv.ParseInt(string(n), 10, 64)
+}
+
+// An errorContext provides context for type errors during decoding.
+type errorContext struct {
+ Struct reflect.Type
+ FieldStack []string
+}
+
+// decodeState represents the state while decoding a JSON value.
+type decodeState struct {
+ data []byte
+ off int // next read offset in data
+ opcode int // last read result
+ scan scanner
+ errorContext *errorContext
+ savedError error
+ useNumber bool
+ disallowUnknownFields bool
+}
+
+// readIndex returns the position of the last byte read.
+func (d *decodeState) readIndex() int {
+ return d.off - 1
+}
+
+// phasePanicMsg is used as a panic message when we end up with something that
+// shouldn't happen. It can indicate a bug in the JSON decoder, or that
+// something is editing the data slice while the decoder executes.
+const phasePanicMsg = "JSON decoder out of sync - data changing underfoot?"
+
+func (d *decodeState) init(data []byte) *decodeState {
+ d.data = data
+ d.off = 0
+ d.savedError = nil
+ if d.errorContext != nil {
+ d.errorContext.Struct = nil
+ // Reuse the allocated space for the FieldStack slice.
+ d.errorContext.FieldStack = d.errorContext.FieldStack[:0]
+ }
+ return d
+}
+
+// saveError saves the first err it is called with,
+// for reporting at the end of the unmarshal.
+func (d *decodeState) saveError(err error) {
+ if d.savedError == nil {
+ d.savedError = d.addErrorContext(err)
+ }
+}
+
+// addErrorContext returns a new error enhanced with information from d.errorContext
+func (d *decodeState) addErrorContext(err error) error {
+ if d.errorContext != nil && (d.errorContext.Struct != nil || len(d.errorContext.FieldStack) > 0) {
+ switch err := err.(type) {
+ case *UnmarshalTypeError:
+ err.Struct = d.errorContext.Struct.Name()
+ err.Field = strings.Join(d.errorContext.FieldStack, ".")
+ }
+ }
+ return err
+}
+
+// skip scans to the end of what was started.
+func (d *decodeState) skip() {
+ s, data, i := &d.scan, d.data, d.off
+ depth := len(s.parseState)
+ for {
+ op := s.step(s, data[i])
+ i++
+ if len(s.parseState) < depth {
+ d.off = i
+ d.opcode = op
+ return
+ }
+ }
+}
+
+// scanNext processes the byte at d.data[d.off].
+func (d *decodeState) scanNext() {
+ if d.off < len(d.data) {
+ d.opcode = d.scan.step(&d.scan, d.data[d.off])
+ d.off++
+ } else {
+ d.opcode = d.scan.eof()
+ d.off = len(d.data) + 1 // mark processed EOF with len+1
+ }
+}
+
+// scanWhile processes bytes in d.data[d.off:] until it
+// receives a scan code not equal to op.
+func (d *decodeState) scanWhile(op int) {
+ s, data, i := &d.scan, d.data, d.off
+ for i < len(data) {
+ newOp := s.step(s, data[i])
+ i++
+ if newOp != op {
+ d.opcode = newOp
+ d.off = i
+ return
+ }
+ }
+
+ d.off = len(data) + 1 // mark processed EOF with len+1
+ d.opcode = d.scan.eof()
+}
+
+// rescanLiteral is similar to scanWhile(scanContinue), but it specialises the
+// common case where we're decoding a literal. The decoder scans the input
+// twice, once for syntax errors and to check the length of the value, and the
+// second to perform the decoding.
+//
+// Only in the second step do we use decodeState to tokenize literals, so we
+// know there aren't any syntax errors. We can take advantage of that knowledge,
+// and scan a literal's bytes much more quickly.
+func (d *decodeState) rescanLiteral() {
+ data, i := d.data, d.off
+Switch:
+ switch data[i-1] {
+ case '"': // string
+ for ; i < len(data); i++ {
+ switch data[i] {
+ case '\\':
+ i++ // escaped char
+ case '"':
+ i++ // tokenize the closing quote too
+ break Switch
+ }
+ }
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-': // number
+ for ; i < len(data); i++ {
+ switch data[i] {
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '.', 'e', 'E', '+', '-':
+ default:
+ break Switch
+ }
+ }
+ case 't': // true
+ i += len("rue")
+ case 'f': // false
+ i += len("alse")
+ case 'n': // null
+ i += len("ull")
+ }
+ if i < len(data) {
+ d.opcode = stateEndValue(&d.scan, data[i])
+ } else {
+ d.opcode = scanEnd
+ }
+ d.off = i + 1
+}
+
+// value consumes a JSON value from d.data[d.off-1:], decoding into v, and
+// reads the following byte ahead. If v is invalid, the value is discarded.
+// The first byte of the value has been read already.
+func (d *decodeState) value(v reflect.Value) error {
+ switch d.opcode {
+ default:
+ panic(phasePanicMsg)
+
+ case scanBeginArray:
+ if v.IsValid() {
+ if err := d.array(v); err != nil {
+ return err
+ }
+ } else {
+ d.skip()
+ }
+ d.scanNext()
+
+ case scanBeginObject:
+ if v.IsValid() {
+ if err := d.object(v); err != nil {
+ return err
+ }
+ } else {
+ d.skip()
+ }
+ d.scanNext()
+
+ case scanBeginLiteral:
+ // All bytes inside literal return scanContinue op code.
+ start := d.readIndex()
+ d.rescanLiteral()
+
+ if v.IsValid() {
+ if err := d.literalStore(d.data[start:d.readIndex()], v, false); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+type unquotedValue struct{}
+
+// valueQuoted is like value but decodes a
+// quoted string literal or literal null into an interface value.
+// If it finds anything other than a quoted string literal or null,
+// valueQuoted returns unquotedValue{}.
+func (d *decodeState) valueQuoted() any {
+ switch d.opcode {
+ default:
+ panic(phasePanicMsg)
+
+ case scanBeginArray, scanBeginObject:
+ d.skip()
+ d.scanNext()
+
+ case scanBeginLiteral:
+ v := d.literalInterface()
+ switch v.(type) {
+ case nil, string:
+ return v
+ }
+ }
+ return unquotedValue{}
+}
+
+// indirect walks down v allocating pointers as needed,
+// until it gets to a non-pointer.
+// If it encounters an Unmarshaler, indirect stops and returns that.
+// If decodingNull is true, indirect stops at the first settable pointer so it
+// can be set to nil.
+func indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
+ // Issue #24153 indicates that it is generally not a guaranteed property
+ // that you may round-trip a reflect.Value by calling Value.Addr().Elem()
+ // and expect the value to still be settable for values derived from
+ // unexported embedded struct fields.
+ //
+ // The logic below effectively does this when it first addresses the value
+ // (to satisfy possible pointer methods) and continues to dereference
+ // subsequent pointers as necessary.
+ //
+ // After the first round-trip, we set v back to the original value to
+ // preserve the original RW flags contained in reflect.Value.
+ v0 := v
+ haveAddr := false
+
+ // If v is a named type and is addressable,
+ // start with its address, so that if the type has pointer methods,
+ // we find them.
+ if v.Kind() != reflect.Pointer && v.Type().Name() != "" && v.CanAddr() {
+ haveAddr = true
+ v = v.Addr()
+ }
+ for {
+ // Load value from interface, but only if the result will be
+ // usefully addressable.
+ if v.Kind() == reflect.Interface && !v.IsNil() {
+ e := v.Elem()
+ if e.Kind() == reflect.Pointer && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Pointer) {
+ haveAddr = false
+ v = e
+ continue
+ }
+ }
+
+ if v.Kind() != reflect.Pointer {
+ break
+ }
+
+ if decodingNull && v.CanSet() {
+ break
+ }
+
+ // Prevent infinite loop if v is an interface pointing to its own address:
+ // var v interface{}
+ // v = &v
+ if v.Elem().Kind() == reflect.Interface && v.Elem().Elem() == v {
+ v = v.Elem()
+ break
+ }
+ if v.IsNil() {
+ v.Set(reflect.New(v.Type().Elem()))
+ }
+ if v.Type().NumMethod() > 0 && v.CanInterface() {
+ if u, ok := v.Interface().(Unmarshaler); ok {
+ return u, nil, reflect.Value{}
+ }
+ if !decodingNull {
+ if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
+ return nil, u, reflect.Value{}
+ }
+ }
+ }
+
+ if haveAddr {
+ v = v0 // restore original value after round-trip Value.Addr().Elem()
+ haveAddr = false
+ } else {
+ v = v.Elem()
+ }
+ }
+ return nil, nil, v
+}
+
+// array consumes an array from d.data[d.off-1:], decoding into v.
+// The first byte of the array ('[') has been read already.
+func (d *decodeState) array(v reflect.Value) error {
+ // Check for unmarshaler.
+ u, ut, pv := indirect(v, false)
+ if u != nil {
+ start := d.readIndex()
+ d.skip()
+ return u.UnmarshalJSON(d.data[start:d.off])
+ }
+ if ut != nil {
+ d.saveError(&UnmarshalTypeError{Value: "array", Type: v.Type(), Offset: int64(d.off)})
+ d.skip()
+ return nil
+ }
+ v = pv
+
+ // Check type of target.
+ switch v.Kind() {
+ case reflect.Interface:
+ if v.NumMethod() == 0 {
+ // Decoding into nil interface? Switch to non-reflect code.
+ ai := d.arrayInterface()
+ v.Set(reflect.ValueOf(ai))
+ return nil
+ }
+ // Otherwise it's invalid.
+ fallthrough
+ default:
+ d.saveError(&UnmarshalTypeError{Value: "array", Type: v.Type(), Offset: int64(d.off)})
+ d.skip()
+ return nil
+ case reflect.Array, reflect.Slice:
+ break
+ }
+
+ i := 0
+ for {
+ // Look ahead for ] - can only happen on first iteration.
+ d.scanWhile(scanSkipSpace)
+ if d.opcode == scanEndArray {
+ break
+ }
+
+ // Expand slice length, growing the slice if necessary.
+ if v.Kind() == reflect.Slice {
+ if i >= v.Cap() {
+ v.Grow(1)
+ }
+ if i >= v.Len() {
+ v.SetLen(i + 1)
+ }
+ }
+
+ if i < v.Len() {
+ // Decode into element.
+ if err := d.value(v.Index(i)); err != nil {
+ return err
+ }
+ } else {
+ // Ran out of fixed array: skip.
+ if err := d.value(reflect.Value{}); err != nil {
+ return err
+ }
+ }
+ i++
+
+ // Next token must be , or ].
+ if d.opcode == scanSkipSpace {
+ d.scanWhile(scanSkipSpace)
+ }
+ if d.opcode == scanEndArray {
+ break
+ }
+ if d.opcode != scanArrayValue {
+ panic(phasePanicMsg)
+ }
+ }
+
+ if i < v.Len() {
+ if v.Kind() == reflect.Array {
+ for ; i < v.Len(); i++ {
+ v.Index(i).SetZero() // zero remainder of array
+ }
+ } else {
+ v.SetLen(i) // truncate the slice
+ }
+ }
+ if i == 0 && v.Kind() == reflect.Slice {
+ v.Set(reflect.MakeSlice(v.Type(), 0, 0))
+ }
+ return nil
+}
+
+var nullLiteral = []byte("null")
+var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+
+// object consumes an object from d.data[d.off-1:], decoding into v.
+// The first byte ('{') of the object has been read already.
+func (d *decodeState) object(v reflect.Value) error {
+ // Check for unmarshaler.
+ u, ut, pv := indirect(v, false)
+ if u != nil {
+ start := d.readIndex()
+ d.skip()
+ return u.UnmarshalJSON(d.data[start:d.off])
+ }
+ if ut != nil {
+ d.saveError(&UnmarshalTypeError{Value: "object", Type: v.Type(), Offset: int64(d.off)})
+ d.skip()
+ return nil
+ }
+ v = pv
+ t := v.Type()
+
+ // Decoding into nil interface? Switch to non-reflect code.
+ if v.Kind() == reflect.Interface && v.NumMethod() == 0 {
+ oi := d.objectInterface()
+ v.Set(reflect.ValueOf(oi))
+ return nil
+ }
+
+ var fields structFields
+
+ // Check type of target:
+ // struct or
+ // map[T1]T2 where T1 is string, an integer type,
+ // or an encoding.TextUnmarshaler
+ switch v.Kind() {
+ case reflect.Map:
+ // Map key must either have string kind, have an integer kind,
+ // or be an encoding.TextUnmarshaler.
+ switch t.Key().Kind() {
+ case reflect.String,
+ reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+ reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ default:
+ if !reflect.PointerTo(t.Key()).Implements(textUnmarshalerType) {
+ d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)})
+ d.skip()
+ return nil
+ }
+ }
+ if v.IsNil() {
+ v.Set(reflect.MakeMap(t))
+ }
+ case reflect.Struct:
+ fields = cachedTypeFields(t)
+ // ok
+ default:
+ d.saveError(&UnmarshalTypeError{Value: "object", Type: t, Offset: int64(d.off)})
+ d.skip()
+ return nil
+ }
+
+ var mapElem reflect.Value
+ var origErrorContext errorContext
+ if d.errorContext != nil {
+ origErrorContext = *d.errorContext
+ }
+
+ for {
+ // Read opening " of string key or closing }.
+ d.scanWhile(scanSkipSpace)
+ if d.opcode == scanEndObject {
+ // closing } - can only happen on first iteration.
+ break
+ }
+ if d.opcode != scanBeginLiteral {
+ panic(phasePanicMsg)
+ }
+
+ // Read key.
+ start := d.readIndex()
+ d.rescanLiteral()
+ item := d.data[start:d.readIndex()]
+ key, ok := unquoteBytes(item)
+ if !ok {
+ panic(phasePanicMsg)
+ }
+
+ // Figure out field corresponding to key.
+ var subv reflect.Value
+ destring := false // whether the value is wrapped in a string to be decoded first
+
+ if v.Kind() == reflect.Map {
+ elemType := t.Elem()
+ if !mapElem.IsValid() {
+ mapElem = reflect.New(elemType).Elem()
+ } else {
+ mapElem.SetZero()
+ }
+ subv = mapElem
+ } else {
+ f := fields.byExactName[string(key)]
+ if f == nil {
+ f = fields.byFoldedName[string(foldName(key))]
+ }
+ if f != nil {
+ subv = v
+ destring = f.quoted
+ for _, i := range f.index {
+ if subv.Kind() == reflect.Pointer {
+ if subv.IsNil() {
+ // If a struct embeds a pointer to an unexported type,
+ // it is not possible to set a newly allocated value
+ // since the field is unexported.
+ //
+ // See https://golang.org/issue/21357
+ if !subv.CanSet() {
+ d.saveError(fmt.Errorf("json: cannot set embedded pointer to unexported struct: %v", subv.Type().Elem()))
+ // Invalidate subv to ensure d.value(subv) skips over
+ // the JSON value without assigning it to subv.
+ subv = reflect.Value{}
+ destring = false
+ break
+ }
+ subv.Set(reflect.New(subv.Type().Elem()))
+ }
+ subv = subv.Elem()
+ }
+ subv = subv.Field(i)
+ }
+ if d.errorContext == nil {
+ d.errorContext = new(errorContext)
+ }
+ d.errorContext.FieldStack = append(d.errorContext.FieldStack, f.name)
+ d.errorContext.Struct = t
+ } else if d.disallowUnknownFields {
+ d.saveError(fmt.Errorf("json: unknown field %q", key))
+ }
+ }
+
+ // Read : before value.
+ if d.opcode == scanSkipSpace {
+ d.scanWhile(scanSkipSpace)
+ }
+ if d.opcode != scanObjectKey {
+ panic(phasePanicMsg)
+ }
+ d.scanWhile(scanSkipSpace)
+
+ if destring {
+ switch qv := d.valueQuoted().(type) {
+ case nil:
+ if err := d.literalStore(nullLiteral, subv, false); err != nil {
+ return err
+ }
+ case string:
+ if err := d.literalStore([]byte(qv), subv, true); err != nil {
+ return err
+ }
+ default:
+ d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", subv.Type()))
+ }
+ } else {
+ if err := d.value(subv); err != nil {
+ return err
+ }
+ }
+
+ // Write value back to map;
+ // if using struct, subv points into struct already.
+ if v.Kind() == reflect.Map {
+ kt := t.Key()
+ var kv reflect.Value
+ switch {
+ case reflect.PointerTo(kt).Implements(textUnmarshalerType):
+ kv = reflect.New(kt)
+ if err := d.literalStore(item, kv, true); err != nil {
+ return err
+ }
+ kv = kv.Elem()
+ case kt.Kind() == reflect.String:
+ kv = reflect.ValueOf(key).Convert(kt)
+ default:
+ switch kt.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ s := string(key)
+ n, err := strconv.ParseInt(s, 10, 64)
+ if err != nil || reflect.Zero(kt).OverflowInt(n) {
+ d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)})
+ break
+ }
+ kv = reflect.ValueOf(n).Convert(kt)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ s := string(key)
+ n, err := strconv.ParseUint(s, 10, 64)
+ if err != nil || reflect.Zero(kt).OverflowUint(n) {
+ d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: kt, Offset: int64(start + 1)})
+ break
+ }
+ kv = reflect.ValueOf(n).Convert(kt)
+ default:
+ panic("json: Unexpected key type") // should never occur
+ }
+ }
+ if kv.IsValid() {
+ v.SetMapIndex(kv, subv)
+ }
+ }
+
+ // Next token must be , or }.
+ if d.opcode == scanSkipSpace {
+ d.scanWhile(scanSkipSpace)
+ }
+ if d.errorContext != nil {
+ // Reset errorContext to its original state.
+ // Keep the same underlying array for FieldStack, to reuse the
+ // space and avoid unnecessary allocs.
+ d.errorContext.FieldStack = d.errorContext.FieldStack[:len(origErrorContext.FieldStack)]
+ d.errorContext.Struct = origErrorContext.Struct
+ }
+ if d.opcode == scanEndObject {
+ break
+ }
+ if d.opcode != scanObjectValue {
+ panic(phasePanicMsg)
+ }
+ }
+ return nil
+}
+
+// convertNumber converts the number literal s to a float64 or a Number
+// depending on the setting of d.useNumber.
+func (d *decodeState) convertNumber(s string) (any, error) {
+ if d.useNumber {
+ return Number(s), nil
+ }
+ f, err := strconv.ParseFloat(s, 64)
+ if err != nil {
+ return nil, &UnmarshalTypeError{Value: "number " + s, Type: reflect.TypeOf(0.0), Offset: int64(d.off)}
+ }
+ return f, nil
+}
+
+var numberType = reflect.TypeOf(Number(""))
+
+// literalStore decodes a literal stored in item into v.
+//
+// fromQuoted indicates whether this literal came from unwrapping a
+// string from the ",string" struct tag option. this is used only to
+// produce more helpful error messages.
+func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) error {
+ // Check for unmarshaler.
+ if len(item) == 0 {
+ //Empty string given
+ d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+ return nil
+ }
+ isNull := item[0] == 'n' // null
+ u, ut, pv := indirect(v, isNull)
+ if u != nil {
+ return u.UnmarshalJSON(item)
+ }
+ if ut != nil {
+ if item[0] != '"' {
+ if fromQuoted {
+ d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+ return nil
+ }
+ val := "number"
+ switch item[0] {
+ case 'n':
+ val = "null"
+ case 't', 'f':
+ val = "bool"
+ }
+ d.saveError(&UnmarshalTypeError{Value: val, Type: v.Type(), Offset: int64(d.readIndex())})
+ return nil
+ }
+ s, ok := unquoteBytes(item)
+ if !ok {
+ if fromQuoted {
+ return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
+ }
+ panic(phasePanicMsg)
+ }
+ return ut.UnmarshalText(s)
+ }
+
+ v = pv
+
+ switch c := item[0]; c {
+ case 'n': // null
+ // The main parser checks that only true and false can reach here,
+ // but if this was a quoted string input, it could be anything.
+ if fromQuoted && string(item) != "null" {
+ d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+ break
+ }
+ switch v.Kind() {
+ case reflect.Interface, reflect.Pointer, reflect.Map, reflect.Slice:
+ v.SetZero()
+ // otherwise, ignore null for primitives/string
+ }
+ case 't', 'f': // true, false
+ value := item[0] == 't'
+ // The main parser checks that only true and false can reach here,
+ // but if this was a quoted string input, it could be anything.
+ if fromQuoted && string(item) != "true" && string(item) != "false" {
+ d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+ break
+ }
+ switch v.Kind() {
+ default:
+ if fromQuoted {
+ d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+ } else {
+ d.saveError(&UnmarshalTypeError{Value: "bool", Type: v.Type(), Offset: int64(d.readIndex())})
+ }
+ case reflect.Bool:
+ v.SetBool(value)
+ case reflect.Interface:
+ if v.NumMethod() == 0 {
+ v.Set(reflect.ValueOf(value))
+ } else {
+ d.saveError(&UnmarshalTypeError{Value: "bool", Type: v.Type(), Offset: int64(d.readIndex())})
+ }
+ }
+
+ case '"': // string
+ s, ok := unquoteBytes(item)
+ if !ok {
+ if fromQuoted {
+ return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
+ }
+ panic(phasePanicMsg)
+ }
+ switch v.Kind() {
+ default:
+ d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())})
+ case reflect.Slice:
+ if v.Type().Elem().Kind() != reflect.Uint8 {
+ d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())})
+ break
+ }
+ b := make([]byte, base64.StdEncoding.DecodedLen(len(s)))
+ n, err := base64.StdEncoding.Decode(b, s)
+ if err != nil {
+ d.saveError(err)
+ break
+ }
+ v.SetBytes(b[:n])
+ case reflect.String:
+ if v.Type() == numberType && !isValidNumber(string(s)) {
+ return fmt.Errorf("json: invalid number literal, trying to unmarshal %q into Number", item)
+ }
+ v.SetString(string(s))
+ case reflect.Interface:
+ if v.NumMethod() == 0 {
+ v.Set(reflect.ValueOf(string(s)))
+ } else {
+ d.saveError(&UnmarshalTypeError{Value: "string", Type: v.Type(), Offset: int64(d.readIndex())})
+ }
+ }
+
+ default: // number
+ if c != '-' && (c < '0' || c > '9') {
+ if fromQuoted {
+ return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
+ }
+ panic(phasePanicMsg)
+ }
+ s := string(item)
+ switch v.Kind() {
+ default:
+ if v.Kind() == reflect.String && v.Type() == numberType {
+ // s must be a valid number, because it's
+ // already been tokenized.
+ v.SetString(s)
+ break
+ }
+ if fromQuoted {
+ return fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type())
+ }
+ d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())})
+ case reflect.Interface:
+ n, err := d.convertNumber(s)
+ if err != nil {
+ d.saveError(err)
+ break
+ }
+ if v.NumMethod() != 0 {
+ d.saveError(&UnmarshalTypeError{Value: "number", Type: v.Type(), Offset: int64(d.readIndex())})
+ break
+ }
+ v.Set(reflect.ValueOf(n))
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ n, err := strconv.ParseInt(s, 10, 64)
+ if err != nil || v.OverflowInt(n) {
+ d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())})
+ break
+ }
+ v.SetInt(n)
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ n, err := strconv.ParseUint(s, 10, 64)
+ if err != nil || v.OverflowUint(n) {
+ d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())})
+ break
+ }
+ v.SetUint(n)
+
+ case reflect.Float32, reflect.Float64:
+ n, err := strconv.ParseFloat(s, v.Type().Bits())
+ if err != nil || v.OverflowFloat(n) {
+ d.saveError(&UnmarshalTypeError{Value: "number " + s, Type: v.Type(), Offset: int64(d.readIndex())})
+ break
+ }
+ v.SetFloat(n)
+ }
+ }
+ return nil
+}
+
+// The xxxInterface routines build up a value to be stored
+// in an empty interface. They are not strictly necessary,
+// but they avoid the weight of reflection in this common case.
+
+// valueInterface is like value but returns interface{}
+func (d *decodeState) valueInterface() (val any) {
+ switch d.opcode {
+ default:
+ panic(phasePanicMsg)
+ case scanBeginArray:
+ val = d.arrayInterface()
+ d.scanNext()
+ case scanBeginObject:
+ val = d.objectInterface()
+ d.scanNext()
+ case scanBeginLiteral:
+ val = d.literalInterface()
+ }
+ return
+}
+
+// arrayInterface is like array but returns []interface{}.
+func (d *decodeState) arrayInterface() []any {
+ var v = make([]any, 0)
+ for {
+ // Look ahead for ] - can only happen on first iteration.
+ d.scanWhile(scanSkipSpace)
+ if d.opcode == scanEndArray {
+ break
+ }
+
+ v = append(v, d.valueInterface())
+
+ // Next token must be , or ].
+ if d.opcode == scanSkipSpace {
+ d.scanWhile(scanSkipSpace)
+ }
+ if d.opcode == scanEndArray {
+ break
+ }
+ if d.opcode != scanArrayValue {
+ panic(phasePanicMsg)
+ }
+ }
+ return v
+}
+
+// objectInterface is like object but returns map[string]interface{}.
+func (d *decodeState) objectInterface() map[string]any {
+ m := make(map[string]any)
+ for {
+ // Read opening " of string key or closing }.
+ d.scanWhile(scanSkipSpace)
+ if d.opcode == scanEndObject {
+ // closing } - can only happen on first iteration.
+ break
+ }
+ if d.opcode != scanBeginLiteral {
+ panic(phasePanicMsg)
+ }
+
+ // Read string key.
+ start := d.readIndex()
+ d.rescanLiteral()
+ item := d.data[start:d.readIndex()]
+ key, ok := unquote(item)
+ if !ok {
+ panic(phasePanicMsg)
+ }
+
+ // Read : before value.
+ if d.opcode == scanSkipSpace {
+ d.scanWhile(scanSkipSpace)
+ }
+ if d.opcode != scanObjectKey {
+ panic(phasePanicMsg)
+ }
+ d.scanWhile(scanSkipSpace)
+
+ // Read value.
+ m[key] = d.valueInterface()
+
+ // Next token must be , or }.
+ if d.opcode == scanSkipSpace {
+ d.scanWhile(scanSkipSpace)
+ }
+ if d.opcode == scanEndObject {
+ break
+ }
+ if d.opcode != scanObjectValue {
+ panic(phasePanicMsg)
+ }
+ }
+ return m
+}
+
+// literalInterface consumes and returns a literal from d.data[d.off-1:] and
+// it reads the following byte ahead. The first byte of the literal has been
+// read already (that's how the caller knows it's a literal).
+func (d *decodeState) literalInterface() any {
+ // All bytes inside literal return scanContinue op code.
+ start := d.readIndex()
+ d.rescanLiteral()
+
+ item := d.data[start:d.readIndex()]
+
+ switch c := item[0]; c {
+ case 'n': // null
+ return nil
+
+ case 't', 'f': // true, false
+ return c == 't'
+
+ case '"': // string
+ s, ok := unquote(item)
+ if !ok {
+ panic(phasePanicMsg)
+ }
+ return s
+
+ default: // number
+ if c != '-' && (c < '0' || c > '9') {
+ panic(phasePanicMsg)
+ }
+ n, err := d.convertNumber(string(item))
+ if err != nil {
+ d.saveError(err)
+ }
+ return n
+ }
+}
+
+// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
+// or it returns -1.
+func getu4(s []byte) rune {
+ if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
+ return -1
+ }
+ var r rune
+ for _, c := range s[2:6] {
+ switch {
+ case '0' <= c && c <= '9':
+ c = c - '0'
+ case 'a' <= c && c <= 'f':
+ c = c - 'a' + 10
+ case 'A' <= c && c <= 'F':
+ c = c - 'A' + 10
+ default:
+ return -1
+ }
+ r = r*16 + rune(c)
+ }
+ return r
+}
+
+// unquote converts a quoted JSON string literal s into an actual string t.
+// The rules are different than for Go, so cannot use strconv.Unquote.
+func unquote(s []byte) (t string, ok bool) {
+ s, ok = unquoteBytes(s)
+ t = string(s)
+ return
+}
+
+func unquoteBytes(s []byte) (t []byte, ok bool) {
+ if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
+ return
+ }
+ s = s[1 : len(s)-1]
+
+ // Check for unusual characters. If there are none,
+ // then no unquoting is needed, so return a slice of the
+ // original bytes.
+ r := 0
+ for r < len(s) {
+ c := s[r]
+ if c == '\\' || c == '"' || c < ' ' {
+ break
+ }
+ if c < utf8.RuneSelf {
+ r++
+ continue
+ }
+ rr, size := utf8.DecodeRune(s[r:])
+ if rr == utf8.RuneError && size == 1 {
+ break
+ }
+ r += size
+ }
+ if r == len(s) {
+ return s, true
+ }
+
+ b := make([]byte, len(s)+2*utf8.UTFMax)
+ w := copy(b, s[0:r])
+ for r < len(s) {
+ // Out of room? Can only happen if s is full of
+ // malformed UTF-8 and we're replacing each
+ // byte with RuneError.
+ if w >= len(b)-2*utf8.UTFMax {
+ nb := make([]byte, (len(b)+utf8.UTFMax)*2)
+ copy(nb, b[0:w])
+ b = nb
+ }
+ switch c := s[r]; {
+ case c == '\\':
+ r++
+ if r >= len(s) {
+ return
+ }
+ switch s[r] {
+ default:
+ return
+ case '"', '\\', '/', '\'':
+ b[w] = s[r]
+ r++
+ w++
+ case 'b':
+ b[w] = '\b'
+ r++
+ w++
+ case 'f':
+ b[w] = '\f'
+ r++
+ w++
+ case 'n':
+ b[w] = '\n'
+ r++
+ w++
+ case 'r':
+ b[w] = '\r'
+ r++
+ w++
+ case 't':
+ b[w] = '\t'
+ r++
+ w++
+ case 'u':
+ r--
+ rr := getu4(s[r:])
+ if rr < 0 {
+ return
+ }
+ r += 6
+ if utf16.IsSurrogate(rr) {
+ rr1 := getu4(s[r:])
+ if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {
+ // A valid pair; consume.
+ r += 6
+ w += utf8.EncodeRune(b[w:], dec)
+ break
+ }
+ // Invalid surrogate; fall back to replacement rune.
+ rr = unicode.ReplacementChar
+ }
+ w += utf8.EncodeRune(b[w:], rr)
+ }
+
+ // Quote, control characters are invalid.
+ case c == '"', c < ' ':
+ return
+
+ // ASCII
+ case c < utf8.RuneSelf:
+ b[w] = c
+ r++
+ w++
+
+ // Coerce to well-formed UTF-8.
+ default:
+ rr, size := utf8.DecodeRune(s[r:])
+ r += size
+ w += utf8.EncodeRune(b[w:], rr)
+ }
+ }
+ return b[0:w], true
+}
diff --git a/contrib/go/_std_1.21/src/encoding/json/encode.go b/contrib/go/_std_1.21/src/encoding/json/encode.go
new file mode 100644
index 0000000000..6da0bd9c4a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/json/encode.go
@@ -0,0 +1,1283 @@
+// Copyright 2010 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 json implements encoding and decoding of JSON as defined in
+// RFC 7159. The mapping between JSON and Go values is described
+// in the documentation for the Marshal and Unmarshal functions.
+//
+// See "JSON and Go" for an introduction to this package:
+// https://golang.org/doc/articles/json_and_go.html
+package json
+
+import (
+ "bytes"
+ "encoding"
+ "encoding/base64"
+ "fmt"
+ "math"
+ "reflect"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "unicode"
+ "unicode/utf8"
+)
+
+// Marshal returns the JSON encoding of v.
+//
+// Marshal traverses the value v recursively.
+// If an encountered value implements the Marshaler interface
+// and is not a nil pointer, Marshal calls its MarshalJSON method
+// to produce JSON. If no MarshalJSON method is present but the
+// value implements encoding.TextMarshaler instead, Marshal calls
+// its MarshalText method and encodes the result as a JSON string.
+// The nil pointer exception is not strictly necessary
+// but mimics a similar, necessary exception in the behavior of
+// UnmarshalJSON.
+//
+// Otherwise, Marshal uses the following type-dependent default encodings:
+//
+// Boolean values encode as JSON booleans.
+//
+// Floating point, integer, and Number values encode as JSON numbers.
+// NaN and +/-Inf values will return an [UnsupportedValueError].
+//
+// String values encode as JSON strings coerced to valid UTF-8,
+// replacing invalid bytes with the Unicode replacement rune.
+// So that the JSON will be safe to embed inside HTML <script> tags,
+// the string is encoded using HTMLEscape,
+// which replaces "<", ">", "&", U+2028, and U+2029 are escaped
+// to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029".
+// This replacement can be disabled when using an Encoder,
+// by calling SetEscapeHTML(false).
+//
+// Array and slice values encode as JSON arrays, except that
+// []byte encodes as a base64-encoded string, and a nil slice
+// encodes as the null JSON value.
+//
+// Struct values encode as JSON objects.
+// Each exported struct field becomes a member of the object, using the
+// field name as the object key, unless the field is omitted for one of the
+// reasons given below.
+//
+// The encoding of each struct field can be customized by the format string
+// stored under the "json" key in the struct field's tag.
+// The format string gives the name of the field, possibly followed by a
+// comma-separated list of options. The name may be empty in order to
+// specify options without overriding the default field name.
+//
+// The "omitempty" option specifies that the field should be omitted
+// from the encoding if the field has an empty value, defined as
+// false, 0, a nil pointer, a nil interface value, and any empty array,
+// slice, map, or string.
+//
+// As a special case, if the field tag is "-", the field is always omitted.
+// Note that a field with name "-" can still be generated using the tag "-,".
+//
+// Examples of struct field tags and their meanings:
+//
+// // Field appears in JSON as key "myName".
+// Field int `json:"myName"`
+//
+// // Field appears in JSON as key "myName" and
+// // the field is omitted from the object if its value is empty,
+// // as defined above.
+// Field int `json:"myName,omitempty"`
+//
+// // Field appears in JSON as key "Field" (the default), but
+// // the field is skipped if empty.
+// // Note the leading comma.
+// Field int `json:",omitempty"`
+//
+// // Field is ignored by this package.
+// Field int `json:"-"`
+//
+// // Field appears in JSON as key "-".
+// Field int `json:"-,"`
+//
+// The "string" option signals that a field is stored as JSON inside a
+// JSON-encoded string. It applies only to fields of string, floating point,
+// integer, or boolean types. This extra level of encoding is sometimes used
+// when communicating with JavaScript programs:
+//
+// Int64String int64 `json:",string"`
+//
+// The key name will be used if it's a non-empty string consisting of
+// only Unicode letters, digits, and ASCII punctuation except quotation
+// marks, backslash, and comma.
+//
+// Anonymous struct fields are usually marshaled as if their inner exported fields
+// were fields in the outer struct, subject to the usual Go visibility rules amended
+// as described in the next paragraph.
+// An anonymous struct field with a name given in its JSON tag is treated as
+// having that name, rather than being anonymous.
+// An anonymous struct field of interface type is treated the same as having
+// that type as its name, rather than being anonymous.
+//
+// The Go visibility rules for struct fields are amended for JSON when
+// deciding which field to marshal or unmarshal. If there are
+// multiple fields at the same level, and that level is the least
+// nested (and would therefore be the nesting level selected by the
+// usual Go rules), the following extra rules apply:
+//
+// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,
+// even if there are multiple untagged fields that would otherwise conflict.
+//
+// 2) If there is exactly one field (tagged or not according to the first rule), that is selected.
+//
+// 3) Otherwise there are multiple fields, and all are ignored; no error occurs.
+//
+// Handling of anonymous struct fields is new in Go 1.1.
+// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of
+// an anonymous struct field in both current and earlier versions, give the field
+// a JSON tag of "-".
+//
+// Map values encode as JSON objects. The map's key type must either be a
+// string, an integer type, or implement encoding.TextMarshaler. The map keys
+// are sorted and used as JSON object keys by applying the following rules,
+// subject to the UTF-8 coercion described for string values above:
+// - keys of any string type are used directly
+// - encoding.TextMarshalers are marshaled
+// - integer keys are converted to strings
+//
+// Pointer values encode as the value pointed to.
+// A nil pointer encodes as the null JSON value.
+//
+// Interface values encode as the value contained in the interface.
+// A nil interface value encodes as the null JSON value.
+//
+// Channel, complex, and function values cannot be encoded in JSON.
+// Attempting to encode such a value causes Marshal to return
+// an UnsupportedTypeError.
+//
+// JSON cannot represent cyclic data structures and Marshal does not
+// handle them. Passing cyclic structures to Marshal will result in
+// an error.
+func Marshal(v any) ([]byte, error) {
+ e := newEncodeState()
+ defer encodeStatePool.Put(e)
+
+ err := e.marshal(v, encOpts{escapeHTML: true})
+ if err != nil {
+ return nil, err
+ }
+ buf := append([]byte(nil), e.Bytes()...)
+
+ return buf, nil
+}
+
+// MarshalIndent is like Marshal but applies Indent to format the output.
+// Each JSON element in the output will begin on a new line beginning with prefix
+// followed by one or more copies of indent according to the indentation nesting.
+func MarshalIndent(v any, prefix, indent string) ([]byte, error) {
+ b, err := Marshal(v)
+ if err != nil {
+ return nil, err
+ }
+ b2 := make([]byte, 0, indentGrowthFactor*len(b))
+ b2, err = appendIndent(b2, b, prefix, indent)
+ if err != nil {
+ return nil, err
+ }
+ return b2, nil
+}
+
+// Marshaler is the interface implemented by types that
+// can marshal themselves into valid JSON.
+type Marshaler interface {
+ MarshalJSON() ([]byte, error)
+}
+
+// An UnsupportedTypeError is returned by Marshal when attempting
+// to encode an unsupported value type.
+type UnsupportedTypeError struct {
+ Type reflect.Type
+}
+
+func (e *UnsupportedTypeError) Error() string {
+ return "json: unsupported type: " + e.Type.String()
+}
+
+// An UnsupportedValueError is returned by Marshal when attempting
+// to encode an unsupported value.
+type UnsupportedValueError struct {
+ Value reflect.Value
+ Str string
+}
+
+func (e *UnsupportedValueError) Error() string {
+ return "json: unsupported value: " + e.Str
+}
+
+// Before Go 1.2, an InvalidUTF8Error was returned by Marshal when
+// attempting to encode a string value with invalid UTF-8 sequences.
+// As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by
+// replacing invalid bytes with the Unicode replacement rune U+FFFD.
+//
+// Deprecated: No longer used; kept for compatibility.
+type InvalidUTF8Error struct {
+ S string // the whole string value that caused the error
+}
+
+func (e *InvalidUTF8Error) Error() string {
+ return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
+}
+
+// A MarshalerError represents an error from calling a MarshalJSON or MarshalText method.
+type MarshalerError struct {
+ Type reflect.Type
+ Err error
+ sourceFunc string
+}
+
+func (e *MarshalerError) Error() string {
+ srcFunc := e.sourceFunc
+ if srcFunc == "" {
+ srcFunc = "MarshalJSON"
+ }
+ return "json: error calling " + srcFunc +
+ " for type " + e.Type.String() +
+ ": " + e.Err.Error()
+}
+
+// Unwrap returns the underlying error.
+func (e *MarshalerError) Unwrap() error { return e.Err }
+
+var hex = "0123456789abcdef"
+
+// An encodeState encodes JSON into a bytes.Buffer.
+type encodeState struct {
+ bytes.Buffer // accumulated output
+
+ // Keep track of what pointers we've seen in the current recursive call
+ // path, to avoid cycles that could lead to a stack overflow. Only do
+ // the relatively expensive map operations if ptrLevel is larger than
+ // startDetectingCyclesAfter, so that we skip the work if we're within a
+ // reasonable amount of nested pointers deep.
+ ptrLevel uint
+ ptrSeen map[any]struct{}
+}
+
+const startDetectingCyclesAfter = 1000
+
+var encodeStatePool sync.Pool
+
+func newEncodeState() *encodeState {
+ if v := encodeStatePool.Get(); v != nil {
+ e := v.(*encodeState)
+ e.Reset()
+ if len(e.ptrSeen) > 0 {
+ panic("ptrEncoder.encode should have emptied ptrSeen via defers")
+ }
+ e.ptrLevel = 0
+ return e
+ }
+ return &encodeState{ptrSeen: make(map[any]struct{})}
+}
+
+// jsonError is an error wrapper type for internal use only.
+// Panics with errors are wrapped in jsonError so that the top-level recover
+// can distinguish intentional panics from this package.
+type jsonError struct{ error }
+
+func (e *encodeState) marshal(v any, opts encOpts) (err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ if je, ok := r.(jsonError); ok {
+ err = je.error
+ } else {
+ panic(r)
+ }
+ }
+ }()
+ e.reflectValue(reflect.ValueOf(v), opts)
+ return nil
+}
+
+// error aborts the encoding by panicking with err wrapped in jsonError.
+func (e *encodeState) error(err error) {
+ panic(jsonError{err})
+}
+
+func isEmptyValue(v reflect.Value) bool {
+ switch v.Kind() {
+ case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+ return v.Len() == 0
+ case reflect.Bool:
+ return v.Bool() == false
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return v.Int() == 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return v.Uint() == 0
+ case reflect.Float32, reflect.Float64:
+ return v.Float() == 0
+ case reflect.Interface, reflect.Pointer:
+ return v.IsNil()
+ }
+ return false
+}
+
+func (e *encodeState) reflectValue(v reflect.Value, opts encOpts) {
+ valueEncoder(v)(e, v, opts)
+}
+
+type encOpts struct {
+ // quoted causes primitive fields to be encoded inside JSON strings.
+ quoted bool
+ // escapeHTML causes '<', '>', and '&' to be escaped in JSON strings.
+ escapeHTML bool
+}
+
+type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts)
+
+var encoderCache sync.Map // map[reflect.Type]encoderFunc
+
+func valueEncoder(v reflect.Value) encoderFunc {
+ if !v.IsValid() {
+ return invalidValueEncoder
+ }
+ return typeEncoder(v.Type())
+}
+
+func typeEncoder(t reflect.Type) encoderFunc {
+ if fi, ok := encoderCache.Load(t); ok {
+ return fi.(encoderFunc)
+ }
+
+ // To deal with recursive types, populate the map with an
+ // indirect func before we build it. This type waits on the
+ // real func (f) to be ready and then calls it. This indirect
+ // func is only used for recursive types.
+ var (
+ wg sync.WaitGroup
+ f encoderFunc
+ )
+ wg.Add(1)
+ fi, loaded := encoderCache.LoadOrStore(t, encoderFunc(func(e *encodeState, v reflect.Value, opts encOpts) {
+ wg.Wait()
+ f(e, v, opts)
+ }))
+ if loaded {
+ return fi.(encoderFunc)
+ }
+
+ // Compute the real encoder and replace the indirect func with it.
+ f = newTypeEncoder(t, true)
+ wg.Done()
+ encoderCache.Store(t, f)
+ return f
+}
+
+var (
+ marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
+ textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
+)
+
+// newTypeEncoder constructs an encoderFunc for a type.
+// The returned encoder only checks CanAddr when allowAddr is true.
+func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
+ // If we have a non-pointer value whose type implements
+ // Marshaler with a value receiver, then we're better off taking
+ // the address of the value - otherwise we end up with an
+ // allocation as we cast the value to an interface.
+ if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(marshalerType) {
+ return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))
+ }
+ if t.Implements(marshalerType) {
+ return marshalerEncoder
+ }
+ if t.Kind() != reflect.Pointer && allowAddr && reflect.PointerTo(t).Implements(textMarshalerType) {
+ return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))
+ }
+ if t.Implements(textMarshalerType) {
+ return textMarshalerEncoder
+ }
+
+ switch t.Kind() {
+ case reflect.Bool:
+ return boolEncoder
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return intEncoder
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return uintEncoder
+ case reflect.Float32:
+ return float32Encoder
+ case reflect.Float64:
+ return float64Encoder
+ case reflect.String:
+ return stringEncoder
+ case reflect.Interface:
+ return interfaceEncoder
+ case reflect.Struct:
+ return newStructEncoder(t)
+ case reflect.Map:
+ return newMapEncoder(t)
+ case reflect.Slice:
+ return newSliceEncoder(t)
+ case reflect.Array:
+ return newArrayEncoder(t)
+ case reflect.Pointer:
+ return newPtrEncoder(t)
+ default:
+ return unsupportedTypeEncoder
+ }
+}
+
+func invalidValueEncoder(e *encodeState, v reflect.Value, _ encOpts) {
+ e.WriteString("null")
+}
+
+func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+ if v.Kind() == reflect.Pointer && v.IsNil() {
+ e.WriteString("null")
+ return
+ }
+ m, ok := v.Interface().(Marshaler)
+ if !ok {
+ e.WriteString("null")
+ return
+ }
+ b, err := m.MarshalJSON()
+ if err == nil {
+ e.Grow(len(b))
+ out := e.AvailableBuffer()
+ out, err = appendCompact(out, b, opts.escapeHTML)
+ e.Buffer.Write(out)
+ }
+ if err != nil {
+ e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
+ }
+}
+
+func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+ va := v.Addr()
+ if va.IsNil() {
+ e.WriteString("null")
+ return
+ }
+ m := va.Interface().(Marshaler)
+ b, err := m.MarshalJSON()
+ if err == nil {
+ e.Grow(len(b))
+ out := e.AvailableBuffer()
+ out, err = appendCompact(out, b, opts.escapeHTML)
+ e.Buffer.Write(out)
+ }
+ if err != nil {
+ e.error(&MarshalerError{v.Type(), err, "MarshalJSON"})
+ }
+}
+
+func textMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+ if v.Kind() == reflect.Pointer && v.IsNil() {
+ e.WriteString("null")
+ return
+ }
+ m, ok := v.Interface().(encoding.TextMarshaler)
+ if !ok {
+ e.WriteString("null")
+ return
+ }
+ b, err := m.MarshalText()
+ if err != nil {
+ e.error(&MarshalerError{v.Type(), err, "MarshalText"})
+ }
+ e.Write(appendString(e.AvailableBuffer(), b, opts.escapeHTML))
+}
+
+func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+ va := v.Addr()
+ if va.IsNil() {
+ e.WriteString("null")
+ return
+ }
+ m := va.Interface().(encoding.TextMarshaler)
+ b, err := m.MarshalText()
+ if err != nil {
+ e.error(&MarshalerError{v.Type(), err, "MarshalText"})
+ }
+ e.Write(appendString(e.AvailableBuffer(), b, opts.escapeHTML))
+}
+
+func boolEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+ b := e.AvailableBuffer()
+ b = mayAppendQuote(b, opts.quoted)
+ b = strconv.AppendBool(b, v.Bool())
+ b = mayAppendQuote(b, opts.quoted)
+ e.Write(b)
+}
+
+func intEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+ b := e.AvailableBuffer()
+ b = mayAppendQuote(b, opts.quoted)
+ b = strconv.AppendInt(b, v.Int(), 10)
+ b = mayAppendQuote(b, opts.quoted)
+ e.Write(b)
+}
+
+func uintEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+ b := e.AvailableBuffer()
+ b = mayAppendQuote(b, opts.quoted)
+ b = strconv.AppendUint(b, v.Uint(), 10)
+ b = mayAppendQuote(b, opts.quoted)
+ e.Write(b)
+}
+
+type floatEncoder int // number of bits
+
+func (bits floatEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+ f := v.Float()
+ if math.IsInf(f, 0) || math.IsNaN(f) {
+ e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))})
+ }
+
+ // Convert as if by ES6 number to string conversion.
+ // This matches most other JSON generators.
+ // See golang.org/issue/6384 and golang.org/issue/14135.
+ // Like fmt %g, but the exponent cutoffs are different
+ // and exponents themselves are not padded to two digits.
+ b := e.AvailableBuffer()
+ b = mayAppendQuote(b, opts.quoted)
+ abs := math.Abs(f)
+ fmt := byte('f')
+ // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
+ if abs != 0 {
+ if bits == 64 && (abs < 1e-6 || abs >= 1e21) || bits == 32 && (float32(abs) < 1e-6 || float32(abs) >= 1e21) {
+ fmt = 'e'
+ }
+ }
+ b = strconv.AppendFloat(b, f, fmt, -1, int(bits))
+ if fmt == 'e' {
+ // clean up e-09 to e-9
+ n := len(b)
+ if n >= 4 && b[n-4] == 'e' && b[n-3] == '-' && b[n-2] == '0' {
+ b[n-2] = b[n-1]
+ b = b[:n-1]
+ }
+ }
+ b = mayAppendQuote(b, opts.quoted)
+ e.Write(b)
+}
+
+var (
+ float32Encoder = (floatEncoder(32)).encode
+ float64Encoder = (floatEncoder(64)).encode
+)
+
+func stringEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+ if v.Type() == numberType {
+ numStr := v.String()
+ // In Go1.5 the empty string encodes to "0", while this is not a valid number literal
+ // we keep compatibility so check validity after this.
+ if numStr == "" {
+ numStr = "0" // Number's zero-val
+ }
+ if !isValidNumber(numStr) {
+ e.error(fmt.Errorf("json: invalid number literal %q", numStr))
+ }
+ b := e.AvailableBuffer()
+ b = mayAppendQuote(b, opts.quoted)
+ b = append(b, numStr...)
+ b = mayAppendQuote(b, opts.quoted)
+ e.Write(b)
+ return
+ }
+ if opts.quoted {
+ b := appendString(nil, v.String(), opts.escapeHTML)
+ e.Write(appendString(e.AvailableBuffer(), b, false)) // no need to escape again since it is already escaped
+ } else {
+ e.Write(appendString(e.AvailableBuffer(), v.String(), opts.escapeHTML))
+ }
+}
+
+// isValidNumber reports whether s is a valid JSON number literal.
+func isValidNumber(s string) bool {
+ // This function implements the JSON numbers grammar.
+ // See https://tools.ietf.org/html/rfc7159#section-6
+ // and https://www.json.org/img/number.png
+
+ if s == "" {
+ return false
+ }
+
+ // Optional -
+ if s[0] == '-' {
+ s = s[1:]
+ if s == "" {
+ return false
+ }
+ }
+
+ // Digits
+ switch {
+ default:
+ return false
+
+ case s[0] == '0':
+ s = s[1:]
+
+ case '1' <= s[0] && s[0] <= '9':
+ s = s[1:]
+ for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+ s = s[1:]
+ }
+ }
+
+ // . followed by 1 or more digits.
+ if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
+ s = s[2:]
+ for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+ s = s[1:]
+ }
+ }
+
+ // e or E followed by an optional - or + and
+ // 1 or more digits.
+ if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
+ s = s[1:]
+ if s[0] == '+' || s[0] == '-' {
+ s = s[1:]
+ if s == "" {
+ return false
+ }
+ }
+ for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
+ s = s[1:]
+ }
+ }
+
+ // Make sure we are at the end.
+ return s == ""
+}
+
+func interfaceEncoder(e *encodeState, v reflect.Value, opts encOpts) {
+ if v.IsNil() {
+ e.WriteString("null")
+ return
+ }
+ e.reflectValue(v.Elem(), opts)
+}
+
+func unsupportedTypeEncoder(e *encodeState, v reflect.Value, _ encOpts) {
+ e.error(&UnsupportedTypeError{v.Type()})
+}
+
+type structEncoder struct {
+ fields structFields
+}
+
+type structFields struct {
+ list []field
+ byExactName map[string]*field
+ byFoldedName map[string]*field
+}
+
+func (se structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+ next := byte('{')
+FieldLoop:
+ for i := range se.fields.list {
+ f := &se.fields.list[i]
+
+ // Find the nested struct field by following f.index.
+ fv := v
+ for _, i := range f.index {
+ if fv.Kind() == reflect.Pointer {
+ if fv.IsNil() {
+ continue FieldLoop
+ }
+ fv = fv.Elem()
+ }
+ fv = fv.Field(i)
+ }
+
+ if f.omitEmpty && isEmptyValue(fv) {
+ continue
+ }
+ e.WriteByte(next)
+ next = ','
+ if opts.escapeHTML {
+ e.WriteString(f.nameEscHTML)
+ } else {
+ e.WriteString(f.nameNonEsc)
+ }
+ opts.quoted = f.quoted
+ f.encoder(e, fv, opts)
+ }
+ if next == '{' {
+ e.WriteString("{}")
+ } else {
+ e.WriteByte('}')
+ }
+}
+
+func newStructEncoder(t reflect.Type) encoderFunc {
+ se := structEncoder{fields: cachedTypeFields(t)}
+ return se.encode
+}
+
+type mapEncoder struct {
+ elemEnc encoderFunc
+}
+
+func (me mapEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+ if v.IsNil() {
+ e.WriteString("null")
+ return
+ }
+ if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
+ // We're a large number of nested ptrEncoder.encode calls deep;
+ // start checking if we've run into a pointer cycle.
+ ptr := v.UnsafePointer()
+ if _, ok := e.ptrSeen[ptr]; ok {
+ e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
+ }
+ e.ptrSeen[ptr] = struct{}{}
+ defer delete(e.ptrSeen, ptr)
+ }
+ e.WriteByte('{')
+
+ // Extract and sort the keys.
+ sv := make([]reflectWithString, v.Len())
+ mi := v.MapRange()
+ for i := 0; mi.Next(); i++ {
+ sv[i].k = mi.Key()
+ sv[i].v = mi.Value()
+ if err := sv[i].resolve(); err != nil {
+ e.error(fmt.Errorf("json: encoding error for type %q: %q", v.Type().String(), err.Error()))
+ }
+ }
+ sort.Slice(sv, func(i, j int) bool { return sv[i].ks < sv[j].ks })
+
+ for i, kv := range sv {
+ if i > 0 {
+ e.WriteByte(',')
+ }
+ e.Write(appendString(e.AvailableBuffer(), kv.ks, opts.escapeHTML))
+ e.WriteByte(':')
+ me.elemEnc(e, kv.v, opts)
+ }
+ e.WriteByte('}')
+ e.ptrLevel--
+}
+
+func newMapEncoder(t reflect.Type) encoderFunc {
+ switch t.Key().Kind() {
+ case reflect.String,
+ reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+ reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ default:
+ if !t.Key().Implements(textMarshalerType) {
+ return unsupportedTypeEncoder
+ }
+ }
+ me := mapEncoder{typeEncoder(t.Elem())}
+ return me.encode
+}
+
+func encodeByteSlice(e *encodeState, v reflect.Value, _ encOpts) {
+ if v.IsNil() {
+ e.WriteString("null")
+ return
+ }
+ s := v.Bytes()
+ encodedLen := base64.StdEncoding.EncodedLen(len(s))
+ e.Grow(len(`"`) + encodedLen + len(`"`))
+
+ // TODO(https://go.dev/issue/53693): Use base64.Encoding.AppendEncode.
+ b := e.AvailableBuffer()
+ b = append(b, '"')
+ base64.StdEncoding.Encode(b[len(b):][:encodedLen], s)
+ b = b[:len(b)+encodedLen]
+ b = append(b, '"')
+ e.Write(b)
+}
+
+// sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil.
+type sliceEncoder struct {
+ arrayEnc encoderFunc
+}
+
+func (se sliceEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+ if v.IsNil() {
+ e.WriteString("null")
+ return
+ }
+ if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
+ // We're a large number of nested ptrEncoder.encode calls deep;
+ // start checking if we've run into a pointer cycle.
+ // Here we use a struct to memorize the pointer to the first element of the slice
+ // and its length.
+ ptr := struct {
+ ptr interface{} // always an unsafe.Pointer, but avoids a dependency on package unsafe
+ len int
+ }{v.UnsafePointer(), v.Len()}
+ if _, ok := e.ptrSeen[ptr]; ok {
+ e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
+ }
+ e.ptrSeen[ptr] = struct{}{}
+ defer delete(e.ptrSeen, ptr)
+ }
+ se.arrayEnc(e, v, opts)
+ e.ptrLevel--
+}
+
+func newSliceEncoder(t reflect.Type) encoderFunc {
+ // Byte slices get special treatment; arrays don't.
+ if t.Elem().Kind() == reflect.Uint8 {
+ p := reflect.PointerTo(t.Elem())
+ if !p.Implements(marshalerType) && !p.Implements(textMarshalerType) {
+ return encodeByteSlice
+ }
+ }
+ enc := sliceEncoder{newArrayEncoder(t)}
+ return enc.encode
+}
+
+type arrayEncoder struct {
+ elemEnc encoderFunc
+}
+
+func (ae arrayEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+ e.WriteByte('[')
+ n := v.Len()
+ for i := 0; i < n; i++ {
+ if i > 0 {
+ e.WriteByte(',')
+ }
+ ae.elemEnc(e, v.Index(i), opts)
+ }
+ e.WriteByte(']')
+}
+
+func newArrayEncoder(t reflect.Type) encoderFunc {
+ enc := arrayEncoder{typeEncoder(t.Elem())}
+ return enc.encode
+}
+
+type ptrEncoder struct {
+ elemEnc encoderFunc
+}
+
+func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+ if v.IsNil() {
+ e.WriteString("null")
+ return
+ }
+ if e.ptrLevel++; e.ptrLevel > startDetectingCyclesAfter {
+ // We're a large number of nested ptrEncoder.encode calls deep;
+ // start checking if we've run into a pointer cycle.
+ ptr := v.Interface()
+ if _, ok := e.ptrSeen[ptr]; ok {
+ e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})
+ }
+ e.ptrSeen[ptr] = struct{}{}
+ defer delete(e.ptrSeen, ptr)
+ }
+ pe.elemEnc(e, v.Elem(), opts)
+ e.ptrLevel--
+}
+
+func newPtrEncoder(t reflect.Type) encoderFunc {
+ enc := ptrEncoder{typeEncoder(t.Elem())}
+ return enc.encode
+}
+
+type condAddrEncoder struct {
+ canAddrEnc, elseEnc encoderFunc
+}
+
+func (ce condAddrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {
+ if v.CanAddr() {
+ ce.canAddrEnc(e, v, opts)
+ } else {
+ ce.elseEnc(e, v, opts)
+ }
+}
+
+// newCondAddrEncoder returns an encoder that checks whether its value
+// CanAddr and delegates to canAddrEnc if so, else to elseEnc.
+func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc {
+ enc := condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}
+ return enc.encode
+}
+
+func isValidTag(s string) bool {
+ if s == "" {
+ return false
+ }
+ for _, c := range s {
+ switch {
+ case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c):
+ // Backslash and quote chars are reserved, but
+ // otherwise any punctuation chars are allowed
+ // in a tag name.
+ case !unicode.IsLetter(c) && !unicode.IsDigit(c):
+ return false
+ }
+ }
+ return true
+}
+
+func typeByIndex(t reflect.Type, index []int) reflect.Type {
+ for _, i := range index {
+ if t.Kind() == reflect.Pointer {
+ t = t.Elem()
+ }
+ t = t.Field(i).Type
+ }
+ return t
+}
+
+type reflectWithString struct {
+ k reflect.Value
+ v reflect.Value
+ ks string
+}
+
+func (w *reflectWithString) resolve() error {
+ if w.k.Kind() == reflect.String {
+ w.ks = w.k.String()
+ return nil
+ }
+ if tm, ok := w.k.Interface().(encoding.TextMarshaler); ok {
+ if w.k.Kind() == reflect.Pointer && w.k.IsNil() {
+ return nil
+ }
+ buf, err := tm.MarshalText()
+ w.ks = string(buf)
+ return err
+ }
+ switch w.k.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ w.ks = strconv.FormatInt(w.k.Int(), 10)
+ return nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ w.ks = strconv.FormatUint(w.k.Uint(), 10)
+ return nil
+ }
+ panic("unexpected map key type")
+}
+
+func appendString[Bytes []byte | string](dst []byte, src Bytes, escapeHTML bool) []byte {
+ dst = append(dst, '"')
+ start := 0
+ for i := 0; i < len(src); {
+ if b := src[i]; b < utf8.RuneSelf {
+ if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) {
+ i++
+ continue
+ }
+ dst = append(dst, src[start:i]...)
+ switch b {
+ case '\\', '"':
+ dst = append(dst, '\\', b)
+ case '\n':
+ dst = append(dst, '\\', 'n')
+ case '\r':
+ dst = append(dst, '\\', 'r')
+ case '\t':
+ dst = append(dst, '\\', 't')
+ default:
+ // This encodes bytes < 0x20 except for \t, \n and \r.
+ // If escapeHTML is set, it also escapes <, >, and &
+ // because they can lead to security holes when
+ // user-controlled strings are rendered into JSON
+ // and served to some browsers.
+ dst = append(dst, '\\', 'u', '0', '0', hex[b>>4], hex[b&0xF])
+ }
+ i++
+ start = i
+ continue
+ }
+ // TODO(https://go.dev/issue/56948): Use generic utf8 functionality.
+ // For now, cast only a small portion of byte slices to a string
+ // so that it can be stack allocated. This slows down []byte slightly
+ // due to the extra copy, but keeps string performance roughly the same.
+ n := len(src) - i
+ if n > utf8.UTFMax {
+ n = utf8.UTFMax
+ }
+ c, size := utf8.DecodeRuneInString(string(src[i : i+n]))
+ if c == utf8.RuneError && size == 1 {
+ dst = append(dst, src[start:i]...)
+ dst = append(dst, `\ufffd`...)
+ i += size
+ start = i
+ continue
+ }
+ // U+2028 is LINE SEPARATOR.
+ // U+2029 is PARAGRAPH SEPARATOR.
+ // They are both technically valid characters in JSON strings,
+ // but don't work in JSONP, which has to be evaluated as JavaScript,
+ // and can lead to security holes there. It is valid JSON to
+ // escape them, so we do so unconditionally.
+ // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+ if c == '\u2028' || c == '\u2029' {
+ dst = append(dst, src[start:i]...)
+ dst = append(dst, '\\', 'u', '2', '0', '2', hex[c&0xF])
+ i += size
+ start = i
+ continue
+ }
+ i += size
+ }
+ dst = append(dst, src[start:]...)
+ dst = append(dst, '"')
+ return dst
+}
+
+// A field represents a single field found in a struct.
+type field struct {
+ name string
+ nameBytes []byte // []byte(name)
+
+ nameNonEsc string // `"` + name + `":`
+ nameEscHTML string // `"` + HTMLEscape(name) + `":`
+
+ tag bool
+ index []int
+ typ reflect.Type
+ omitEmpty bool
+ quoted bool
+
+ encoder encoderFunc
+}
+
+// byIndex sorts field by index sequence.
+type byIndex []field
+
+func (x byIndex) Len() int { return len(x) }
+
+func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+func (x byIndex) Less(i, j int) bool {
+ for k, xik := range x[i].index {
+ if k >= len(x[j].index) {
+ return false
+ }
+ if xik != x[j].index[k] {
+ return xik < x[j].index[k]
+ }
+ }
+ return len(x[i].index) < len(x[j].index)
+}
+
+// typeFields returns a list of fields that JSON should recognize for the given type.
+// The algorithm is breadth-first search over the set of structs to include - the top struct
+// and then any reachable anonymous structs.
+func typeFields(t reflect.Type) structFields {
+ // Anonymous fields to explore at the current level and the next.
+ current := []field{}
+ next := []field{{typ: t}}
+
+ // Count of queued names for current level and the next.
+ var count, nextCount map[reflect.Type]int
+
+ // Types already visited at an earlier level.
+ visited := map[reflect.Type]bool{}
+
+ // Fields found.
+ var fields []field
+
+ // Buffer to run appendHTMLEscape on field names.
+ var nameEscBuf []byte
+
+ for len(next) > 0 {
+ current, next = next, current[:0]
+ count, nextCount = nextCount, map[reflect.Type]int{}
+
+ for _, f := range current {
+ if visited[f.typ] {
+ continue
+ }
+ visited[f.typ] = true
+
+ // Scan f.typ for fields to include.
+ for i := 0; i < f.typ.NumField(); i++ {
+ sf := f.typ.Field(i)
+ if sf.Anonymous {
+ t := sf.Type
+ if t.Kind() == reflect.Pointer {
+ t = t.Elem()
+ }
+ if !sf.IsExported() && t.Kind() != reflect.Struct {
+ // Ignore embedded fields of unexported non-struct types.
+ continue
+ }
+ // Do not ignore embedded fields of unexported struct types
+ // since they may have exported fields.
+ } else if !sf.IsExported() {
+ // Ignore unexported non-embedded fields.
+ continue
+ }
+ tag := sf.Tag.Get("json")
+ if tag == "-" {
+ continue
+ }
+ name, opts := parseTag(tag)
+ if !isValidTag(name) {
+ name = ""
+ }
+ index := make([]int, len(f.index)+1)
+ copy(index, f.index)
+ index[len(f.index)] = i
+
+ ft := sf.Type
+ if ft.Name() == "" && ft.Kind() == reflect.Pointer {
+ // Follow pointer.
+ ft = ft.Elem()
+ }
+
+ // Only strings, floats, integers, and booleans can be quoted.
+ quoted := false
+ if opts.Contains("string") {
+ switch ft.Kind() {
+ case reflect.Bool,
+ reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+ reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,
+ reflect.Float32, reflect.Float64,
+ reflect.String:
+ quoted = true
+ }
+ }
+
+ // Record found field and index sequence.
+ if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
+ tagged := name != ""
+ if name == "" {
+ name = sf.Name
+ }
+ field := field{
+ name: name,
+ tag: tagged,
+ index: index,
+ typ: ft,
+ omitEmpty: opts.Contains("omitempty"),
+ quoted: quoted,
+ }
+ field.nameBytes = []byte(field.name)
+
+ // Build nameEscHTML and nameNonEsc ahead of time.
+ nameEscBuf = appendHTMLEscape(nameEscBuf[:0], field.nameBytes)
+ field.nameEscHTML = `"` + string(nameEscBuf) + `":`
+ field.nameNonEsc = `"` + field.name + `":`
+
+ fields = append(fields, field)
+ if count[f.typ] > 1 {
+ // If there were multiple instances, add a second,
+ // so that the annihilation code will see a duplicate.
+ // It only cares about the distinction between 1 or 2,
+ // so don't bother generating any more copies.
+ fields = append(fields, fields[len(fields)-1])
+ }
+ continue
+ }
+
+ // Record new anonymous struct to explore in next round.
+ nextCount[ft]++
+ if nextCount[ft] == 1 {
+ next = append(next, field{name: ft.Name(), index: index, typ: ft})
+ }
+ }
+ }
+ }
+
+ sort.Slice(fields, func(i, j int) bool {
+ x := fields
+ // sort field by name, breaking ties with depth, then
+ // breaking ties with "name came from json tag", then
+ // breaking ties with index sequence.
+ if x[i].name != x[j].name {
+ return x[i].name < x[j].name
+ }
+ if len(x[i].index) != len(x[j].index) {
+ return len(x[i].index) < len(x[j].index)
+ }
+ if x[i].tag != x[j].tag {
+ return x[i].tag
+ }
+ return byIndex(x).Less(i, j)
+ })
+
+ // Delete all fields that are hidden by the Go rules for embedded fields,
+ // except that fields with JSON tags are promoted.
+
+ // The fields are sorted in primary order of name, secondary order
+ // of field index length. Loop over names; for each name, delete
+ // hidden fields by choosing the one dominant field that survives.
+ out := fields[:0]
+ for advance, i := 0, 0; i < len(fields); i += advance {
+ // One iteration per name.
+ // Find the sequence of fields with the name of this first field.
+ fi := fields[i]
+ name := fi.name
+ for advance = 1; i+advance < len(fields); advance++ {
+ fj := fields[i+advance]
+ if fj.name != name {
+ break
+ }
+ }
+ if advance == 1 { // Only one field with this name
+ out = append(out, fi)
+ continue
+ }
+ dominant, ok := dominantField(fields[i : i+advance])
+ if ok {
+ out = append(out, dominant)
+ }
+ }
+
+ fields = out
+ sort.Sort(byIndex(fields))
+
+ for i := range fields {
+ f := &fields[i]
+ f.encoder = typeEncoder(typeByIndex(t, f.index))
+ }
+ exactNameIndex := make(map[string]*field, len(fields))
+ foldedNameIndex := make(map[string]*field, len(fields))
+ for i, field := range fields {
+ exactNameIndex[field.name] = &fields[i]
+ // For historical reasons, first folded match takes precedence.
+ if _, ok := foldedNameIndex[string(foldName(field.nameBytes))]; !ok {
+ foldedNameIndex[string(foldName(field.nameBytes))] = &fields[i]
+ }
+ }
+ return structFields{fields, exactNameIndex, foldedNameIndex}
+}
+
+// dominantField looks through the fields, all of which are known to
+// have the same name, to find the single field that dominates the
+// others using Go's embedding rules, modified by the presence of
+// JSON tags. If there are multiple top-level fields, the boolean
+// will be false: This condition is an error in Go and we skip all
+// the fields.
+func dominantField(fields []field) (field, bool) {
+ // The fields are sorted in increasing index-length order, then by presence of tag.
+ // That means that the first field is the dominant one. We need only check
+ // for error cases: two fields at top level, either both tagged or neither tagged.
+ if len(fields) > 1 && len(fields[0].index) == len(fields[1].index) && fields[0].tag == fields[1].tag {
+ return field{}, false
+ }
+ return fields[0], true
+}
+
+var fieldCache sync.Map // map[reflect.Type]structFields
+
+// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
+func cachedTypeFields(t reflect.Type) structFields {
+ if f, ok := fieldCache.Load(t); ok {
+ return f.(structFields)
+ }
+ f, _ := fieldCache.LoadOrStore(t, typeFields(t))
+ return f.(structFields)
+}
+
+func mayAppendQuote(b []byte, quoted bool) []byte {
+ if quoted {
+ b = append(b, '"')
+ }
+ return b
+}
diff --git a/contrib/go/_std_1.21/src/encoding/json/fold.go b/contrib/go/_std_1.21/src/encoding/json/fold.go
new file mode 100644
index 0000000000..c4c671b527
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/json/fold.go
@@ -0,0 +1,48 @@
+// Copyright 2013 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 json
+
+import (
+ "unicode"
+ "unicode/utf8"
+)
+
+// foldName returns a folded string such that foldName(x) == foldName(y)
+// is identical to bytes.EqualFold(x, y).
+func foldName(in []byte) []byte {
+ // This is inlinable to take advantage of "function outlining".
+ var arr [32]byte // large enough for most JSON names
+ return appendFoldedName(arr[:0], in)
+}
+
+func appendFoldedName(out, in []byte) []byte {
+ for i := 0; i < len(in); {
+ // Handle single-byte ASCII.
+ if c := in[i]; c < utf8.RuneSelf {
+ if 'a' <= c && c <= 'z' {
+ c -= 'a' - 'A'
+ }
+ out = append(out, c)
+ i++
+ continue
+ }
+ // Handle multi-byte Unicode.
+ r, n := utf8.DecodeRune(in[i:])
+ out = utf8.AppendRune(out, foldRune(r))
+ i += n
+ }
+ return out
+}
+
+// foldRune is returns the smallest rune for all runes in the same fold set.
+func foldRune(r rune) rune {
+ for {
+ r2 := unicode.SimpleFold(r)
+ if r2 <= r {
+ return r2
+ }
+ r = r2
+ }
+}
diff --git a/contrib/go/_std_1.21/src/encoding/json/indent.go b/contrib/go/_std_1.21/src/encoding/json/indent.go
new file mode 100644
index 0000000000..26bb5d2e47
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/json/indent.go
@@ -0,0 +1,174 @@
+// Copyright 2010 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 json
+
+import "bytes"
+
+// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
+// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
+// so that the JSON will be safe to embed inside HTML <script> tags.
+// For historical reasons, web browsers don't honor standard HTML
+// escaping within <script> tags, so an alternative JSON encoding must be used.
+func HTMLEscape(dst *bytes.Buffer, src []byte) {
+ dst.Grow(len(src))
+ dst.Write(appendHTMLEscape(dst.AvailableBuffer(), src))
+}
+
+func appendHTMLEscape(dst, src []byte) []byte {
+ // The characters can only appear in string literals,
+ // so just scan the string one byte at a time.
+ start := 0
+ for i, c := range src {
+ if c == '<' || c == '>' || c == '&' {
+ dst = append(dst, src[start:i]...)
+ dst = append(dst, '\\', 'u', '0', '0', hex[c>>4], hex[c&0xF])
+ start = i + 1
+ }
+ // Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
+ if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
+ dst = append(dst, src[start:i]...)
+ dst = append(dst, '\\', 'u', '2', '0', '2', hex[src[i+2]&0xF])
+ start = i + len("\u2029")
+ }
+ }
+ return append(dst, src[start:]...)
+}
+
+// Compact appends to dst the JSON-encoded src with
+// insignificant space characters elided.
+func Compact(dst *bytes.Buffer, src []byte) error {
+ dst.Grow(len(src))
+ b := dst.AvailableBuffer()
+ b, err := appendCompact(b, src, false)
+ dst.Write(b)
+ return err
+}
+
+func appendCompact(dst, src []byte, escape bool) ([]byte, error) {
+ origLen := len(dst)
+ scan := newScanner()
+ defer freeScanner(scan)
+ start := 0
+ for i, c := range src {
+ if escape && (c == '<' || c == '>' || c == '&') {
+ dst = append(dst, src[start:i]...)
+ dst = append(dst, '\\', 'u', '0', '0', hex[c>>4], hex[c&0xF])
+ start = i + 1
+ }
+ // Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
+ if escape && c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
+ dst = append(dst, src[start:i]...)
+ dst = append(dst, '\\', 'u', '2', '0', '2', hex[src[i+2]&0xF])
+ start = i + len("\u2029")
+ }
+ v := scan.step(scan, c)
+ if v >= scanSkipSpace {
+ if v == scanError {
+ break
+ }
+ dst = append(dst, src[start:i]...)
+ start = i + 1
+ }
+ }
+ if scan.eof() == scanError {
+ return dst[:origLen], scan.err
+ }
+ dst = append(dst, src[start:]...)
+ return dst, nil
+}
+
+func appendNewline(dst []byte, prefix, indent string, depth int) []byte {
+ dst = append(dst, '\n')
+ dst = append(dst, prefix...)
+ for i := 0; i < depth; i++ {
+ dst = append(dst, indent...)
+ }
+ return dst
+}
+
+// indentGrowthFactor specifies the growth factor of indenting JSON input.
+// Empirically, the growth factor was measured to be between 1.4x to 1.8x
+// for some set of compacted JSON with the indent being a single tab.
+// Specify a growth factor slightly larger than what is observed
+// to reduce probability of allocation in appendIndent.
+// A factor no higher than 2 ensures that wasted space never exceeds 50%.
+const indentGrowthFactor = 2
+
+// Indent appends to dst an indented form of the JSON-encoded src.
+// Each element in a JSON object or array begins on a new,
+// indented line beginning with prefix followed by one or more
+// copies of indent according to the indentation nesting.
+// The data appended to dst does not begin with the prefix nor
+// any indentation, to make it easier to embed inside other formatted JSON data.
+// Although leading space characters (space, tab, carriage return, newline)
+// at the beginning of src are dropped, trailing space characters
+// at the end of src are preserved and copied to dst.
+// For example, if src has no trailing spaces, neither will dst;
+// if src ends in a trailing newline, so will dst.
+func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error {
+ dst.Grow(indentGrowthFactor * len(src))
+ b := dst.AvailableBuffer()
+ b, err := appendIndent(b, src, prefix, indent)
+ dst.Write(b)
+ return err
+}
+
+func appendIndent(dst, src []byte, prefix, indent string) ([]byte, error) {
+ origLen := len(dst)
+ scan := newScanner()
+ defer freeScanner(scan)
+ needIndent := false
+ depth := 0
+ for _, c := range src {
+ scan.bytes++
+ v := scan.step(scan, c)
+ if v == scanSkipSpace {
+ continue
+ }
+ if v == scanError {
+ break
+ }
+ if needIndent && v != scanEndObject && v != scanEndArray {
+ needIndent = false
+ depth++
+ dst = appendNewline(dst, prefix, indent, depth)
+ }
+
+ // Emit semantically uninteresting bytes
+ // (in particular, punctuation in strings) unmodified.
+ if v == scanContinue {
+ dst = append(dst, c)
+ continue
+ }
+
+ // Add spacing around real punctuation.
+ switch c {
+ case '{', '[':
+ // delay indent so that empty object and array are formatted as {} and [].
+ needIndent = true
+ dst = append(dst, c)
+ case ',':
+ dst = append(dst, c)
+ dst = appendNewline(dst, prefix, indent, depth)
+ case ':':
+ dst = append(dst, c, ' ')
+ case '}', ']':
+ if needIndent {
+ // suppress indent in empty object/array
+ needIndent = false
+ } else {
+ depth--
+ dst = appendNewline(dst, prefix, indent, depth)
+ }
+ dst = append(dst, c)
+ default:
+ dst = append(dst, c)
+ }
+ }
+ if scan.eof() == scanError {
+ return dst[:origLen], scan.err
+ }
+ return dst, nil
+}
diff --git a/contrib/go/_std_1.20/src/encoding/json/scanner.go b/contrib/go/_std_1.21/src/encoding/json/scanner.go
index 4c43f5f98c..4c43f5f98c 100644
--- a/contrib/go/_std_1.20/src/encoding/json/scanner.go
+++ b/contrib/go/_std_1.21/src/encoding/json/scanner.go
diff --git a/contrib/go/_std_1.21/src/encoding/json/stream.go b/contrib/go/_std_1.21/src/encoding/json/stream.go
new file mode 100644
index 0000000000..b4146a359e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/json/stream.go
@@ -0,0 +1,511 @@
+// Copyright 2010 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 json
+
+import (
+ "bytes"
+ "errors"
+ "io"
+)
+
+// A Decoder reads and decodes JSON values from an input stream.
+type Decoder struct {
+ r io.Reader
+ buf []byte
+ d decodeState
+ scanp int // start of unread data in buf
+ scanned int64 // amount of data already scanned
+ scan scanner
+ err error
+
+ tokenState int
+ tokenStack []int
+}
+
+// NewDecoder returns a new decoder that reads from r.
+//
+// The decoder introduces its own buffering and may
+// read data from r beyond the JSON values requested.
+func NewDecoder(r io.Reader) *Decoder {
+ return &Decoder{r: r}
+}
+
+// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
+// Number instead of as a float64.
+func (dec *Decoder) UseNumber() { dec.d.useNumber = true }
+
+// DisallowUnknownFields causes the Decoder to return an error when the destination
+// is a struct and the input contains object keys which do not match any
+// non-ignored, exported fields in the destination.
+func (dec *Decoder) DisallowUnknownFields() { dec.d.disallowUnknownFields = true }
+
+// Decode reads the next JSON-encoded value from its
+// input and stores it in the value pointed to by v.
+//
+// See the documentation for Unmarshal for details about
+// the conversion of JSON into a Go value.
+func (dec *Decoder) Decode(v any) error {
+ if dec.err != nil {
+ return dec.err
+ }
+
+ if err := dec.tokenPrepareForDecode(); err != nil {
+ return err
+ }
+
+ if !dec.tokenValueAllowed() {
+ return &SyntaxError{msg: "not at beginning of value", Offset: dec.InputOffset()}
+ }
+
+ // Read whole value into buffer.
+ n, err := dec.readValue()
+ if err != nil {
+ return err
+ }
+ dec.d.init(dec.buf[dec.scanp : dec.scanp+n])
+ dec.scanp += n
+
+ // Don't save err from unmarshal into dec.err:
+ // the connection is still usable since we read a complete JSON
+ // object from it before the error happened.
+ err = dec.d.unmarshal(v)
+
+ // fixup token streaming state
+ dec.tokenValueEnd()
+
+ return err
+}
+
+// Buffered returns a reader of the data remaining in the Decoder's
+// buffer. The reader is valid until the next call to Decode.
+func (dec *Decoder) Buffered() io.Reader {
+ return bytes.NewReader(dec.buf[dec.scanp:])
+}
+
+// readValue reads a JSON value into dec.buf.
+// It returns the length of the encoding.
+func (dec *Decoder) readValue() (int, error) {
+ dec.scan.reset()
+
+ scanp := dec.scanp
+ var err error
+Input:
+ // help the compiler see that scanp is never negative, so it can remove
+ // some bounds checks below.
+ for scanp >= 0 {
+
+ // Look in the buffer for a new value.
+ for ; scanp < len(dec.buf); scanp++ {
+ c := dec.buf[scanp]
+ dec.scan.bytes++
+ switch dec.scan.step(&dec.scan, c) {
+ case scanEnd:
+ // scanEnd is delayed one byte so we decrement
+ // the scanner bytes count by 1 to ensure that
+ // this value is correct in the next call of Decode.
+ dec.scan.bytes--
+ break Input
+ case scanEndObject, scanEndArray:
+ // scanEnd is delayed one byte.
+ // We might block trying to get that byte from src,
+ // so instead invent a space byte.
+ if stateEndValue(&dec.scan, ' ') == scanEnd {
+ scanp++
+ break Input
+ }
+ case scanError:
+ dec.err = dec.scan.err
+ return 0, dec.scan.err
+ }
+ }
+
+ // Did the last read have an error?
+ // Delayed until now to allow buffer scan.
+ if err != nil {
+ if err == io.EOF {
+ if dec.scan.step(&dec.scan, ' ') == scanEnd {
+ break Input
+ }
+ if nonSpace(dec.buf) {
+ err = io.ErrUnexpectedEOF
+ }
+ }
+ dec.err = err
+ return 0, err
+ }
+
+ n := scanp - dec.scanp
+ err = dec.refill()
+ scanp = dec.scanp + n
+ }
+ return scanp - dec.scanp, nil
+}
+
+func (dec *Decoder) refill() error {
+ // Make room to read more into the buffer.
+ // First slide down data already consumed.
+ if dec.scanp > 0 {
+ dec.scanned += int64(dec.scanp)
+ n := copy(dec.buf, dec.buf[dec.scanp:])
+ dec.buf = dec.buf[:n]
+ dec.scanp = 0
+ }
+
+ // Grow buffer if not large enough.
+ const minRead = 512
+ if cap(dec.buf)-len(dec.buf) < minRead {
+ newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
+ copy(newBuf, dec.buf)
+ dec.buf = newBuf
+ }
+
+ // Read. Delay error for next iteration (after scan).
+ n, err := dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
+ dec.buf = dec.buf[0 : len(dec.buf)+n]
+
+ return err
+}
+
+func nonSpace(b []byte) bool {
+ for _, c := range b {
+ if !isSpace(c) {
+ return true
+ }
+ }
+ return false
+}
+
+// An Encoder writes JSON values to an output stream.
+type Encoder struct {
+ w io.Writer
+ err error
+ escapeHTML bool
+
+ indentBuf []byte
+ indentPrefix string
+ indentValue string
+}
+
+// NewEncoder returns a new encoder that writes to w.
+func NewEncoder(w io.Writer) *Encoder {
+ return &Encoder{w: w, escapeHTML: true}
+}
+
+// Encode writes the JSON encoding of v to the stream,
+// followed by a newline character.
+//
+// See the documentation for Marshal for details about the
+// conversion of Go values to JSON.
+func (enc *Encoder) Encode(v any) error {
+ if enc.err != nil {
+ return enc.err
+ }
+
+ e := newEncodeState()
+ defer encodeStatePool.Put(e)
+
+ err := e.marshal(v, encOpts{escapeHTML: enc.escapeHTML})
+ if err != nil {
+ return err
+ }
+
+ // Terminate each value with a newline.
+ // This makes the output look a little nicer
+ // when debugging, and some kind of space
+ // is required if the encoded value was a number,
+ // so that the reader knows there aren't more
+ // digits coming.
+ e.WriteByte('\n')
+
+ b := e.Bytes()
+ if enc.indentPrefix != "" || enc.indentValue != "" {
+ enc.indentBuf, err = appendIndent(enc.indentBuf[:0], b, enc.indentPrefix, enc.indentValue)
+ if err != nil {
+ return err
+ }
+ b = enc.indentBuf
+ }
+ if _, err = enc.w.Write(b); err != nil {
+ enc.err = err
+ }
+ return err
+}
+
+// SetIndent instructs the encoder to format each subsequent encoded
+// value as if indented by the package-level function Indent(dst, src, prefix, indent).
+// Calling SetIndent("", "") disables indentation.
+func (enc *Encoder) SetIndent(prefix, indent string) {
+ enc.indentPrefix = prefix
+ enc.indentValue = indent
+}
+
+// SetEscapeHTML specifies whether problematic HTML characters
+// should be escaped inside JSON quoted strings.
+// The default behavior is to escape &, <, and > to \u0026, \u003c, and \u003e
+// to avoid certain safety problems that can arise when embedding JSON in HTML.
+//
+// In non-HTML settings where the escaping interferes with the readability
+// of the output, SetEscapeHTML(false) disables this behavior.
+func (enc *Encoder) SetEscapeHTML(on bool) {
+ enc.escapeHTML = on
+}
+
+// RawMessage is a raw encoded JSON value.
+// It implements Marshaler and Unmarshaler and can
+// be used to delay JSON decoding or precompute a JSON encoding.
+type RawMessage []byte
+
+// MarshalJSON returns m as the JSON encoding of m.
+func (m RawMessage) MarshalJSON() ([]byte, error) {
+ if m == nil {
+ return []byte("null"), nil
+ }
+ return m, nil
+}
+
+// UnmarshalJSON sets *m to a copy of data.
+func (m *RawMessage) UnmarshalJSON(data []byte) error {
+ if m == nil {
+ return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
+ }
+ *m = append((*m)[0:0], data...)
+ return nil
+}
+
+var _ Marshaler = (*RawMessage)(nil)
+var _ Unmarshaler = (*RawMessage)(nil)
+
+// A Token holds a value of one of these types:
+//
+// Delim, for the four JSON delimiters [ ] { }
+// bool, for JSON booleans
+// float64, for JSON numbers
+// Number, for JSON numbers
+// string, for JSON string literals
+// nil, for JSON null
+type Token any
+
+const (
+ tokenTopValue = iota
+ tokenArrayStart
+ tokenArrayValue
+ tokenArrayComma
+ tokenObjectStart
+ tokenObjectKey
+ tokenObjectColon
+ tokenObjectValue
+ tokenObjectComma
+)
+
+// advance tokenstate from a separator state to a value state
+func (dec *Decoder) tokenPrepareForDecode() error {
+ // Note: Not calling peek before switch, to avoid
+ // putting peek into the standard Decode path.
+ // peek is only called when using the Token API.
+ switch dec.tokenState {
+ case tokenArrayComma:
+ c, err := dec.peek()
+ if err != nil {
+ return err
+ }
+ if c != ',' {
+ return &SyntaxError{"expected comma after array element", dec.InputOffset()}
+ }
+ dec.scanp++
+ dec.tokenState = tokenArrayValue
+ case tokenObjectColon:
+ c, err := dec.peek()
+ if err != nil {
+ return err
+ }
+ if c != ':' {
+ return &SyntaxError{"expected colon after object key", dec.InputOffset()}
+ }
+ dec.scanp++
+ dec.tokenState = tokenObjectValue
+ }
+ return nil
+}
+
+func (dec *Decoder) tokenValueAllowed() bool {
+ switch dec.tokenState {
+ case tokenTopValue, tokenArrayStart, tokenArrayValue, tokenObjectValue:
+ return true
+ }
+ return false
+}
+
+func (dec *Decoder) tokenValueEnd() {
+ switch dec.tokenState {
+ case tokenArrayStart, tokenArrayValue:
+ dec.tokenState = tokenArrayComma
+ case tokenObjectValue:
+ dec.tokenState = tokenObjectComma
+ }
+}
+
+// A Delim is a JSON array or object delimiter, one of [ ] { or }.
+type Delim rune
+
+func (d Delim) String() string {
+ return string(d)
+}
+
+// Token returns the next JSON token in the input stream.
+// At the end of the input stream, Token returns nil, io.EOF.
+//
+// Token guarantees that the delimiters [ ] { } it returns are
+// properly nested and matched: if Token encounters an unexpected
+// delimiter in the input, it will return an error.
+//
+// The input stream consists of basic JSON values—bool, string,
+// number, and null—along with delimiters [ ] { } of type Delim
+// to mark the start and end of arrays and objects.
+// Commas and colons are elided.
+func (dec *Decoder) Token() (Token, error) {
+ for {
+ c, err := dec.peek()
+ if err != nil {
+ return nil, err
+ }
+ switch c {
+ case '[':
+ if !dec.tokenValueAllowed() {
+ return dec.tokenError(c)
+ }
+ dec.scanp++
+ dec.tokenStack = append(dec.tokenStack, dec.tokenState)
+ dec.tokenState = tokenArrayStart
+ return Delim('['), nil
+
+ case ']':
+ if dec.tokenState != tokenArrayStart && dec.tokenState != tokenArrayComma {
+ return dec.tokenError(c)
+ }
+ dec.scanp++
+ dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
+ dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
+ dec.tokenValueEnd()
+ return Delim(']'), nil
+
+ case '{':
+ if !dec.tokenValueAllowed() {
+ return dec.tokenError(c)
+ }
+ dec.scanp++
+ dec.tokenStack = append(dec.tokenStack, dec.tokenState)
+ dec.tokenState = tokenObjectStart
+ return Delim('{'), nil
+
+ case '}':
+ if dec.tokenState != tokenObjectStart && dec.tokenState != tokenObjectComma {
+ return dec.tokenError(c)
+ }
+ dec.scanp++
+ dec.tokenState = dec.tokenStack[len(dec.tokenStack)-1]
+ dec.tokenStack = dec.tokenStack[:len(dec.tokenStack)-1]
+ dec.tokenValueEnd()
+ return Delim('}'), nil
+
+ case ':':
+ if dec.tokenState != tokenObjectColon {
+ return dec.tokenError(c)
+ }
+ dec.scanp++
+ dec.tokenState = tokenObjectValue
+ continue
+
+ case ',':
+ if dec.tokenState == tokenArrayComma {
+ dec.scanp++
+ dec.tokenState = tokenArrayValue
+ continue
+ }
+ if dec.tokenState == tokenObjectComma {
+ dec.scanp++
+ dec.tokenState = tokenObjectKey
+ continue
+ }
+ return dec.tokenError(c)
+
+ case '"':
+ if dec.tokenState == tokenObjectStart || dec.tokenState == tokenObjectKey {
+ var x string
+ old := dec.tokenState
+ dec.tokenState = tokenTopValue
+ err := dec.Decode(&x)
+ dec.tokenState = old
+ if err != nil {
+ return nil, err
+ }
+ dec.tokenState = tokenObjectColon
+ return x, nil
+ }
+ fallthrough
+
+ default:
+ if !dec.tokenValueAllowed() {
+ return dec.tokenError(c)
+ }
+ var x any
+ if err := dec.Decode(&x); err != nil {
+ return nil, err
+ }
+ return x, nil
+ }
+ }
+}
+
+func (dec *Decoder) tokenError(c byte) (Token, error) {
+ var context string
+ switch dec.tokenState {
+ case tokenTopValue:
+ context = " looking for beginning of value"
+ case tokenArrayStart, tokenArrayValue, tokenObjectValue:
+ context = " looking for beginning of value"
+ case tokenArrayComma:
+ context = " after array element"
+ case tokenObjectKey:
+ context = " looking for beginning of object key string"
+ case tokenObjectColon:
+ context = " after object key"
+ case tokenObjectComma:
+ context = " after object key:value pair"
+ }
+ return nil, &SyntaxError{"invalid character " + quoteChar(c) + context, dec.InputOffset()}
+}
+
+// More reports whether there is another element in the
+// current array or object being parsed.
+func (dec *Decoder) More() bool {
+ c, err := dec.peek()
+ return err == nil && c != ']' && c != '}'
+}
+
+func (dec *Decoder) peek() (byte, error) {
+ var err error
+ for {
+ for i := dec.scanp; i < len(dec.buf); i++ {
+ c := dec.buf[i]
+ if isSpace(c) {
+ continue
+ }
+ dec.scanp = i
+ return c, nil
+ }
+ // buffer has been scanned, now report any error
+ if err != nil {
+ return 0, err
+ }
+ err = dec.refill()
+ }
+}
+
+// InputOffset returns the input stream byte offset of the current decoder position.
+// The offset gives the location of the end of the most recently returned token
+// and the beginning of the next token.
+func (dec *Decoder) InputOffset() int64 {
+ return dec.scanned + int64(dec.scanp)
+}
diff --git a/contrib/go/_std_1.20/src/encoding/json/tables.go b/contrib/go/_std_1.21/src/encoding/json/tables.go
index 10acdc18c6..10acdc18c6 100644
--- a/contrib/go/_std_1.20/src/encoding/json/tables.go
+++ b/contrib/go/_std_1.21/src/encoding/json/tables.go
diff --git a/contrib/go/_std_1.20/src/encoding/json/tags.go b/contrib/go/_std_1.21/src/encoding/json/tags.go
index b490328f4c..b490328f4c 100644
--- a/contrib/go/_std_1.20/src/encoding/json/tags.go
+++ b/contrib/go/_std_1.21/src/encoding/json/tags.go
diff --git a/contrib/go/_std_1.21/src/encoding/json/ya.make b/contrib/go/_std_1.21/src/encoding/json/ya.make
new file mode 100644
index 0000000000..e58c78891a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/json/ya.make
@@ -0,0 +1,36 @@
+GO_LIBRARY()
+
+SRCS(
+ decode.go
+ encode.go
+ fold.go
+ indent.go
+ scanner.go
+ stream.go
+ tables.go
+ tags.go
+)
+
+GO_TEST_SRCS(
+ bench_test.go
+ decode_test.go
+ encode_test.go
+ fold_test.go
+ fuzz_test.go
+ number_test.go
+ scanner_test.go
+ stream_test.go
+ tagkey_test.go
+ tags_test.go
+)
+
+GO_XTEST_SRCS(
+ example_marshaling_test.go
+ example_test.go
+ example_text_marshaling_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/encoding/pem/pem.go b/contrib/go/_std_1.21/src/encoding/pem/pem.go
index d26e4c8399..d26e4c8399 100644
--- a/contrib/go/_std_1.20/src/encoding/pem/pem.go
+++ b/contrib/go/_std_1.21/src/encoding/pem/pem.go
diff --git a/contrib/go/_std_1.21/src/encoding/pem/ya.make b/contrib/go/_std_1.21/src/encoding/pem/ya.make
new file mode 100644
index 0000000000..40282eae30
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/pem/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ pem.go
+)
+
+GO_TEST_SRCS(pem_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/encoding/xml/marshal.go b/contrib/go/_std_1.21/src/encoding/xml/marshal.go
new file mode 100644
index 0000000000..ae39846f5b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/xml/marshal.go
@@ -0,0 +1,1135 @@
+// Copyright 2011 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 xml
+
+import (
+ "bufio"
+ "bytes"
+ "encoding"
+ "errors"
+ "fmt"
+ "io"
+ "reflect"
+ "strconv"
+ "strings"
+)
+
+const (
+ // Header is a generic XML header suitable for use with the output of Marshal.
+ // This is not automatically added to any output of this package,
+ // it is provided as a convenience.
+ Header = `<?xml version="1.0" encoding="UTF-8"?>` + "\n"
+)
+
+// Marshal returns the XML encoding of v.
+//
+// Marshal handles an array or slice by marshaling each of the elements.
+// Marshal handles a pointer by marshaling the value it points at or, if the
+// pointer is nil, by writing nothing. Marshal handles an interface value by
+// marshaling the value it contains or, if the interface value is nil, by
+// writing nothing. Marshal handles all other data by writing one or more XML
+// elements containing the data.
+//
+// The name for the XML elements is taken from, in order of preference:
+// - the tag on the XMLName field, if the data is a struct
+// - the value of the XMLName field of type Name
+// - the tag of the struct field used to obtain the data
+// - the name of the struct field used to obtain the data
+// - the name of the marshaled type
+//
+// The XML element for a struct contains marshaled elements for each of the
+// exported fields of the struct, with these exceptions:
+// - the XMLName field, described above, is omitted.
+// - a field with tag "-" is omitted.
+// - a field with tag "name,attr" becomes an attribute with
+// the given name in the XML element.
+// - a field with tag ",attr" becomes an attribute with the
+// field name in the XML element.
+// - a field with tag ",chardata" is written as character data,
+// not as an XML element.
+// - a field with tag ",cdata" is written as character data
+// wrapped in one or more <![CDATA[ ... ]]> tags, not as an XML element.
+// - a field with tag ",innerxml" is written verbatim, not subject
+// to the usual marshaling procedure.
+// - a field with tag ",comment" is written as an XML comment, not
+// subject to the usual marshaling procedure. It must not contain
+// the "--" string within it.
+// - a field with a tag including the "omitempty" option is omitted
+// if the field value is empty. The empty values are false, 0, any
+// nil pointer or interface value, and any array, slice, map, or
+// string of length zero.
+// - an anonymous struct field is handled as if the fields of its
+// value were part of the outer struct.
+// - a field implementing Marshaler is written by calling its MarshalXML
+// method.
+// - a field implementing encoding.TextMarshaler is written by encoding the
+// result of its MarshalText method as text.
+//
+// If a field uses a tag "a>b>c", then the element c will be nested inside
+// parent elements a and b. Fields that appear next to each other that name
+// the same parent will be enclosed in one XML element.
+//
+// If the XML name for a struct field is defined by both the field tag and the
+// struct's XMLName field, the names must match.
+//
+// See MarshalIndent for an example.
+//
+// Marshal will return an error if asked to marshal a channel, function, or map.
+func Marshal(v any) ([]byte, error) {
+ var b bytes.Buffer
+ enc := NewEncoder(&b)
+ if err := enc.Encode(v); err != nil {
+ return nil, err
+ }
+ if err := enc.Close(); err != nil {
+ return nil, err
+ }
+ return b.Bytes(), nil
+}
+
+// Marshaler is the interface implemented by objects that can marshal
+// themselves into valid XML elements.
+//
+// MarshalXML encodes the receiver as zero or more XML elements.
+// By convention, arrays or slices are typically encoded as a sequence
+// of elements, one per entry.
+// Using start as the element tag is not required, but doing so
+// will enable Unmarshal to match the XML elements to the correct
+// struct field.
+// One common implementation strategy is to construct a separate
+// value with a layout corresponding to the desired XML and then
+// to encode it using e.EncodeElement.
+// Another common strategy is to use repeated calls to e.EncodeToken
+// to generate the XML output one token at a time.
+// The sequence of encoded tokens must make up zero or more valid
+// XML elements.
+type Marshaler interface {
+ MarshalXML(e *Encoder, start StartElement) error
+}
+
+// MarshalerAttr is the interface implemented by objects that can marshal
+// themselves into valid XML attributes.
+//
+// MarshalXMLAttr returns an XML attribute with the encoded value of the receiver.
+// Using name as the attribute name is not required, but doing so
+// will enable Unmarshal to match the attribute to the correct
+// struct field.
+// If MarshalXMLAttr returns the zero attribute Attr{}, no attribute
+// will be generated in the output.
+// MarshalXMLAttr is used only for struct fields with the
+// "attr" option in the field tag.
+type MarshalerAttr interface {
+ MarshalXMLAttr(name Name) (Attr, error)
+}
+
+// MarshalIndent works like Marshal, but each XML element begins on a new
+// indented line that starts with prefix and is followed by one or more
+// copies of indent according to the nesting depth.
+func MarshalIndent(v any, prefix, indent string) ([]byte, error) {
+ var b bytes.Buffer
+ enc := NewEncoder(&b)
+ enc.Indent(prefix, indent)
+ if err := enc.Encode(v); err != nil {
+ return nil, err
+ }
+ if err := enc.Close(); err != nil {
+ return nil, err
+ }
+ return b.Bytes(), nil
+}
+
+// An Encoder writes XML data to an output stream.
+type Encoder struct {
+ p printer
+}
+
+// NewEncoder returns a new encoder that writes to w.
+func NewEncoder(w io.Writer) *Encoder {
+ e := &Encoder{printer{w: bufio.NewWriter(w)}}
+ e.p.encoder = e
+ return e
+}
+
+// Indent sets the encoder to generate XML in which each element
+// begins on a new indented line that starts with prefix and is followed by
+// one or more copies of indent according to the nesting depth.
+func (enc *Encoder) Indent(prefix, indent string) {
+ enc.p.prefix = prefix
+ enc.p.indent = indent
+}
+
+// Encode writes the XML encoding of v to the stream.
+//
+// See the documentation for Marshal for details about the conversion
+// of Go values to XML.
+//
+// Encode calls Flush before returning.
+func (enc *Encoder) Encode(v any) error {
+ err := enc.p.marshalValue(reflect.ValueOf(v), nil, nil)
+ if err != nil {
+ return err
+ }
+ return enc.p.w.Flush()
+}
+
+// EncodeElement writes the XML encoding of v to the stream,
+// using start as the outermost tag in the encoding.
+//
+// See the documentation for Marshal for details about the conversion
+// of Go values to XML.
+//
+// EncodeElement calls Flush before returning.
+func (enc *Encoder) EncodeElement(v any, start StartElement) error {
+ err := enc.p.marshalValue(reflect.ValueOf(v), nil, &start)
+ if err != nil {
+ return err
+ }
+ return enc.p.w.Flush()
+}
+
+var (
+ begComment = []byte("<!--")
+ endComment = []byte("-->")
+ endProcInst = []byte("?>")
+)
+
+// EncodeToken writes the given XML token to the stream.
+// It returns an error if StartElement and EndElement tokens are not properly matched.
+//
+// EncodeToken does not call Flush, because usually it is part of a larger operation
+// such as Encode or EncodeElement (or a custom Marshaler's MarshalXML invoked
+// during those), and those will call Flush when finished.
+// Callers that create an Encoder and then invoke EncodeToken directly, without
+// using Encode or EncodeElement, need to call Flush when finished to ensure
+// that the XML is written to the underlying writer.
+//
+// EncodeToken allows writing a ProcInst with Target set to "xml" only as the first token
+// in the stream.
+func (enc *Encoder) EncodeToken(t Token) error {
+
+ p := &enc.p
+ switch t := t.(type) {
+ case StartElement:
+ if err := p.writeStart(&t); err != nil {
+ return err
+ }
+ case EndElement:
+ if err := p.writeEnd(t.Name); err != nil {
+ return err
+ }
+ case CharData:
+ escapeText(p, t, false)
+ case Comment:
+ if bytes.Contains(t, endComment) {
+ return fmt.Errorf("xml: EncodeToken of Comment containing --> marker")
+ }
+ p.WriteString("<!--")
+ p.Write(t)
+ p.WriteString("-->")
+ return p.cachedWriteError()
+ case ProcInst:
+ // First token to be encoded which is also a ProcInst with target of xml
+ // is the xml declaration. The only ProcInst where target of xml is allowed.
+ if t.Target == "xml" && p.w.Buffered() != 0 {
+ return fmt.Errorf("xml: EncodeToken of ProcInst xml target only valid for xml declaration, first token encoded")
+ }
+ if !isNameString(t.Target) {
+ return fmt.Errorf("xml: EncodeToken of ProcInst with invalid Target")
+ }
+ if bytes.Contains(t.Inst, endProcInst) {
+ return fmt.Errorf("xml: EncodeToken of ProcInst containing ?> marker")
+ }
+ p.WriteString("<?")
+ p.WriteString(t.Target)
+ if len(t.Inst) > 0 {
+ p.WriteByte(' ')
+ p.Write(t.Inst)
+ }
+ p.WriteString("?>")
+ case Directive:
+ if !isValidDirective(t) {
+ return fmt.Errorf("xml: EncodeToken of Directive containing wrong < or > markers")
+ }
+ p.WriteString("<!")
+ p.Write(t)
+ p.WriteString(">")
+ default:
+ return fmt.Errorf("xml: EncodeToken of invalid token type")
+
+ }
+ return p.cachedWriteError()
+}
+
+// isValidDirective reports whether dir is a valid directive text,
+// meaning angle brackets are matched, ignoring comments and strings.
+func isValidDirective(dir Directive) bool {
+ var (
+ depth int
+ inquote uint8
+ incomment bool
+ )
+ for i, c := range dir {
+ switch {
+ case incomment:
+ if c == '>' {
+ if n := 1 + i - len(endComment); n >= 0 && bytes.Equal(dir[n:i+1], endComment) {
+ incomment = false
+ }
+ }
+ // Just ignore anything in comment
+ case inquote != 0:
+ if c == inquote {
+ inquote = 0
+ }
+ // Just ignore anything within quotes
+ case c == '\'' || c == '"':
+ inquote = c
+ case c == '<':
+ if i+len(begComment) < len(dir) && bytes.Equal(dir[i:i+len(begComment)], begComment) {
+ incomment = true
+ } else {
+ depth++
+ }
+ case c == '>':
+ if depth == 0 {
+ return false
+ }
+ depth--
+ }
+ }
+ return depth == 0 && inquote == 0 && !incomment
+}
+
+// Flush flushes any buffered XML to the underlying writer.
+// See the EncodeToken documentation for details about when it is necessary.
+func (enc *Encoder) Flush() error {
+ return enc.p.w.Flush()
+}
+
+// Close the Encoder, indicating that no more data will be written. It flushes
+// any buffered XML to the underlying writer and returns an error if the
+// written XML is invalid (e.g. by containing unclosed elements).
+func (enc *Encoder) Close() error {
+ return enc.p.Close()
+}
+
+type printer struct {
+ w *bufio.Writer
+ encoder *Encoder
+ seq int
+ indent string
+ prefix string
+ depth int
+ indentedIn bool
+ putNewline bool
+ attrNS map[string]string // map prefix -> name space
+ attrPrefix map[string]string // map name space -> prefix
+ prefixes []string
+ tags []Name
+ closed bool
+ err error
+}
+
+// createAttrPrefix finds the name space prefix attribute to use for the given name space,
+// defining a new prefix if necessary. It returns the prefix.
+func (p *printer) createAttrPrefix(url string) string {
+ if prefix := p.attrPrefix[url]; prefix != "" {
+ return prefix
+ }
+
+ // The "http://www.w3.org/XML/1998/namespace" name space is predefined as "xml"
+ // and must be referred to that way.
+ // (The "http://www.w3.org/2000/xmlns/" name space is also predefined as "xmlns",
+ // but users should not be trying to use that one directly - that's our job.)
+ if url == xmlURL {
+ return xmlPrefix
+ }
+
+ // Need to define a new name space.
+ if p.attrPrefix == nil {
+ p.attrPrefix = make(map[string]string)
+ p.attrNS = make(map[string]string)
+ }
+
+ // Pick a name. We try to use the final element of the path
+ // but fall back to _.
+ prefix := strings.TrimRight(url, "/")
+ if i := strings.LastIndex(prefix, "/"); i >= 0 {
+ prefix = prefix[i+1:]
+ }
+ if prefix == "" || !isName([]byte(prefix)) || strings.Contains(prefix, ":") {
+ prefix = "_"
+ }
+ // xmlanything is reserved and any variant of it regardless of
+ // case should be matched, so:
+ // (('X'|'x') ('M'|'m') ('L'|'l'))
+ // See Section 2.3 of https://www.w3.org/TR/REC-xml/
+ if len(prefix) >= 3 && strings.EqualFold(prefix[:3], "xml") {
+ prefix = "_" + prefix
+ }
+ if p.attrNS[prefix] != "" {
+ // Name is taken. Find a better one.
+ for p.seq++; ; p.seq++ {
+ if id := prefix + "_" + strconv.Itoa(p.seq); p.attrNS[id] == "" {
+ prefix = id
+ break
+ }
+ }
+ }
+
+ p.attrPrefix[url] = prefix
+ p.attrNS[prefix] = url
+
+ p.WriteString(`xmlns:`)
+ p.WriteString(prefix)
+ p.WriteString(`="`)
+ EscapeText(p, []byte(url))
+ p.WriteString(`" `)
+
+ p.prefixes = append(p.prefixes, prefix)
+
+ return prefix
+}
+
+// deleteAttrPrefix removes an attribute name space prefix.
+func (p *printer) deleteAttrPrefix(prefix string) {
+ delete(p.attrPrefix, p.attrNS[prefix])
+ delete(p.attrNS, prefix)
+}
+
+func (p *printer) markPrefix() {
+ p.prefixes = append(p.prefixes, "")
+}
+
+func (p *printer) popPrefix() {
+ for len(p.prefixes) > 0 {
+ prefix := p.prefixes[len(p.prefixes)-1]
+ p.prefixes = p.prefixes[:len(p.prefixes)-1]
+ if prefix == "" {
+ break
+ }
+ p.deleteAttrPrefix(prefix)
+ }
+}
+
+var (
+ marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
+ marshalerAttrType = reflect.TypeOf((*MarshalerAttr)(nil)).Elem()
+ textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
+)
+
+// marshalValue writes one or more XML elements representing val.
+// If val was obtained from a struct field, finfo must have its details.
+func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplate *StartElement) error {
+ if startTemplate != nil && startTemplate.Name.Local == "" {
+ return fmt.Errorf("xml: EncodeElement of StartElement with missing name")
+ }
+
+ if !val.IsValid() {
+ return nil
+ }
+ if finfo != nil && finfo.flags&fOmitEmpty != 0 && isEmptyValue(val) {
+ return nil
+ }
+
+ // Drill into interfaces and pointers.
+ // This can turn into an infinite loop given a cyclic chain,
+ // but it matches the Go 1 behavior.
+ for val.Kind() == reflect.Interface || val.Kind() == reflect.Pointer {
+ if val.IsNil() {
+ return nil
+ }
+ val = val.Elem()
+ }
+
+ kind := val.Kind()
+ typ := val.Type()
+
+ // Check for marshaler.
+ if val.CanInterface() && typ.Implements(marshalerType) {
+ return p.marshalInterface(val.Interface().(Marshaler), defaultStart(typ, finfo, startTemplate))
+ }
+ if val.CanAddr() {
+ pv := val.Addr()
+ if pv.CanInterface() && pv.Type().Implements(marshalerType) {
+ return p.marshalInterface(pv.Interface().(Marshaler), defaultStart(pv.Type(), finfo, startTemplate))
+ }
+ }
+
+ // Check for text marshaler.
+ if val.CanInterface() && typ.Implements(textMarshalerType) {
+ return p.marshalTextInterface(val.Interface().(encoding.TextMarshaler), defaultStart(typ, finfo, startTemplate))
+ }
+ if val.CanAddr() {
+ pv := val.Addr()
+ if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
+ return p.marshalTextInterface(pv.Interface().(encoding.TextMarshaler), defaultStart(pv.Type(), finfo, startTemplate))
+ }
+ }
+
+ // Slices and arrays iterate over the elements. They do not have an enclosing tag.
+ if (kind == reflect.Slice || kind == reflect.Array) && typ.Elem().Kind() != reflect.Uint8 {
+ for i, n := 0, val.Len(); i < n; i++ {
+ if err := p.marshalValue(val.Index(i), finfo, startTemplate); err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+
+ tinfo, err := getTypeInfo(typ)
+ if err != nil {
+ return err
+ }
+
+ // Create start element.
+ // Precedence for the XML element name is:
+ // 0. startTemplate
+ // 1. XMLName field in underlying struct;
+ // 2. field name/tag in the struct field; and
+ // 3. type name
+ var start StartElement
+
+ if startTemplate != nil {
+ start.Name = startTemplate.Name
+ start.Attr = append(start.Attr, startTemplate.Attr...)
+ } else if tinfo.xmlname != nil {
+ xmlname := tinfo.xmlname
+ if xmlname.name != "" {
+ start.Name.Space, start.Name.Local = xmlname.xmlns, xmlname.name
+ } else {
+ fv := xmlname.value(val, dontInitNilPointers)
+ if v, ok := fv.Interface().(Name); ok && v.Local != "" {
+ start.Name = v
+ }
+ }
+ }
+ if start.Name.Local == "" && finfo != nil {
+ start.Name.Space, start.Name.Local = finfo.xmlns, finfo.name
+ }
+ if start.Name.Local == "" {
+ name := typ.Name()
+ if i := strings.IndexByte(name, '['); i >= 0 {
+ // Truncate generic instantiation name. See issue 48318.
+ name = name[:i]
+ }
+ if name == "" {
+ return &UnsupportedTypeError{typ}
+ }
+ start.Name.Local = name
+ }
+
+ // Attributes
+ for i := range tinfo.fields {
+ finfo := &tinfo.fields[i]
+ if finfo.flags&fAttr == 0 {
+ continue
+ }
+ fv := finfo.value(val, dontInitNilPointers)
+
+ if finfo.flags&fOmitEmpty != 0 && (!fv.IsValid() || isEmptyValue(fv)) {
+ continue
+ }
+
+ if fv.Kind() == reflect.Interface && fv.IsNil() {
+ continue
+ }
+
+ name := Name{Space: finfo.xmlns, Local: finfo.name}
+ if err := p.marshalAttr(&start, name, fv); err != nil {
+ return err
+ }
+ }
+
+ // If a empty name was found, namespace is overridden with an empty space
+ if tinfo.xmlname != nil && start.Name.Space == "" &&
+ tinfo.xmlname.xmlns == "" && tinfo.xmlname.name == "" &&
+ len(p.tags) != 0 && p.tags[len(p.tags)-1].Space != "" {
+ start.Attr = append(start.Attr, Attr{Name{"", xmlnsPrefix}, ""})
+ }
+ if err := p.writeStart(&start); err != nil {
+ return err
+ }
+
+ if val.Kind() == reflect.Struct {
+ err = p.marshalStruct(tinfo, val)
+ } else {
+ s, b, err1 := p.marshalSimple(typ, val)
+ if err1 != nil {
+ err = err1
+ } else if b != nil {
+ EscapeText(p, b)
+ } else {
+ p.EscapeString(s)
+ }
+ }
+ if err != nil {
+ return err
+ }
+
+ if err := p.writeEnd(start.Name); err != nil {
+ return err
+ }
+
+ return p.cachedWriteError()
+}
+
+// marshalAttr marshals an attribute with the given name and value, adding to start.Attr.
+func (p *printer) marshalAttr(start *StartElement, name Name, val reflect.Value) error {
+ if val.CanInterface() && val.Type().Implements(marshalerAttrType) {
+ attr, err := val.Interface().(MarshalerAttr).MarshalXMLAttr(name)
+ if err != nil {
+ return err
+ }
+ if attr.Name.Local != "" {
+ start.Attr = append(start.Attr, attr)
+ }
+ return nil
+ }
+
+ if val.CanAddr() {
+ pv := val.Addr()
+ if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) {
+ attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name)
+ if err != nil {
+ return err
+ }
+ if attr.Name.Local != "" {
+ start.Attr = append(start.Attr, attr)
+ }
+ return nil
+ }
+ }
+
+ if val.CanInterface() && val.Type().Implements(textMarshalerType) {
+ text, err := val.Interface().(encoding.TextMarshaler).MarshalText()
+ if err != nil {
+ return err
+ }
+ start.Attr = append(start.Attr, Attr{name, string(text)})
+ return nil
+ }
+
+ if val.CanAddr() {
+ pv := val.Addr()
+ if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
+ text, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
+ if err != nil {
+ return err
+ }
+ start.Attr = append(start.Attr, Attr{name, string(text)})
+ return nil
+ }
+ }
+
+ // Dereference or skip nil pointer, interface values.
+ switch val.Kind() {
+ case reflect.Pointer, reflect.Interface:
+ if val.IsNil() {
+ return nil
+ }
+ val = val.Elem()
+ }
+
+ // Walk slices.
+ if val.Kind() == reflect.Slice && val.Type().Elem().Kind() != reflect.Uint8 {
+ n := val.Len()
+ for i := 0; i < n; i++ {
+ if err := p.marshalAttr(start, name, val.Index(i)); err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+
+ if val.Type() == attrType {
+ start.Attr = append(start.Attr, val.Interface().(Attr))
+ return nil
+ }
+
+ s, b, err := p.marshalSimple(val.Type(), val)
+ if err != nil {
+ return err
+ }
+ if b != nil {
+ s = string(b)
+ }
+ start.Attr = append(start.Attr, Attr{name, s})
+ return nil
+}
+
+// defaultStart returns the default start element to use,
+// given the reflect type, field info, and start template.
+func defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement {
+ var start StartElement
+ // Precedence for the XML element name is as above,
+ // except that we do not look inside structs for the first field.
+ if startTemplate != nil {
+ start.Name = startTemplate.Name
+ start.Attr = append(start.Attr, startTemplate.Attr...)
+ } else if finfo != nil && finfo.name != "" {
+ start.Name.Local = finfo.name
+ start.Name.Space = finfo.xmlns
+ } else if typ.Name() != "" {
+ start.Name.Local = typ.Name()
+ } else {
+ // Must be a pointer to a named type,
+ // since it has the Marshaler methods.
+ start.Name.Local = typ.Elem().Name()
+ }
+ return start
+}
+
+// marshalInterface marshals a Marshaler interface value.
+func (p *printer) marshalInterface(val Marshaler, start StartElement) error {
+ // Push a marker onto the tag stack so that MarshalXML
+ // cannot close the XML tags that it did not open.
+ p.tags = append(p.tags, Name{})
+ n := len(p.tags)
+
+ err := val.MarshalXML(p.encoder, start)
+ if err != nil {
+ return err
+ }
+
+ // Make sure MarshalXML closed all its tags. p.tags[n-1] is the mark.
+ if len(p.tags) > n {
+ return fmt.Errorf("xml: %s.MarshalXML wrote invalid XML: <%s> not closed", receiverType(val), p.tags[len(p.tags)-1].Local)
+ }
+ p.tags = p.tags[:n-1]
+ return nil
+}
+
+// marshalTextInterface marshals a TextMarshaler interface value.
+func (p *printer) marshalTextInterface(val encoding.TextMarshaler, start StartElement) error {
+ if err := p.writeStart(&start); err != nil {
+ return err
+ }
+ text, err := val.MarshalText()
+ if err != nil {
+ return err
+ }
+ EscapeText(p, text)
+ return p.writeEnd(start.Name)
+}
+
+// writeStart writes the given start element.
+func (p *printer) writeStart(start *StartElement) error {
+ if start.Name.Local == "" {
+ return fmt.Errorf("xml: start tag with no name")
+ }
+
+ p.tags = append(p.tags, start.Name)
+ p.markPrefix()
+
+ p.writeIndent(1)
+ p.WriteByte('<')
+ p.WriteString(start.Name.Local)
+
+ if start.Name.Space != "" {
+ p.WriteString(` xmlns="`)
+ p.EscapeString(start.Name.Space)
+ p.WriteByte('"')
+ }
+
+ // Attributes
+ for _, attr := range start.Attr {
+ name := attr.Name
+ if name.Local == "" {
+ continue
+ }
+ p.WriteByte(' ')
+ if name.Space != "" {
+ p.WriteString(p.createAttrPrefix(name.Space))
+ p.WriteByte(':')
+ }
+ p.WriteString(name.Local)
+ p.WriteString(`="`)
+ p.EscapeString(attr.Value)
+ p.WriteByte('"')
+ }
+ p.WriteByte('>')
+ return nil
+}
+
+func (p *printer) writeEnd(name Name) error {
+ if name.Local == "" {
+ return fmt.Errorf("xml: end tag with no name")
+ }
+ if len(p.tags) == 0 || p.tags[len(p.tags)-1].Local == "" {
+ return fmt.Errorf("xml: end tag </%s> without start tag", name.Local)
+ }
+ if top := p.tags[len(p.tags)-1]; top != name {
+ if top.Local != name.Local {
+ return fmt.Errorf("xml: end tag </%s> does not match start tag <%s>", name.Local, top.Local)
+ }
+ return fmt.Errorf("xml: end tag </%s> in namespace %s does not match start tag <%s> in namespace %s", name.Local, name.Space, top.Local, top.Space)
+ }
+ p.tags = p.tags[:len(p.tags)-1]
+
+ p.writeIndent(-1)
+ p.WriteByte('<')
+ p.WriteByte('/')
+ p.WriteString(name.Local)
+ p.WriteByte('>')
+ p.popPrefix()
+ return nil
+}
+
+func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []byte, error) {
+ switch val.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return strconv.FormatInt(val.Int(), 10), nil, nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return strconv.FormatUint(val.Uint(), 10), nil, nil
+ case reflect.Float32, reflect.Float64:
+ return strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits()), nil, nil
+ case reflect.String:
+ return val.String(), nil, nil
+ case reflect.Bool:
+ return strconv.FormatBool(val.Bool()), nil, nil
+ case reflect.Array:
+ if typ.Elem().Kind() != reflect.Uint8 {
+ break
+ }
+ // [...]byte
+ var bytes []byte
+ if val.CanAddr() {
+ bytes = val.Slice(0, val.Len()).Bytes()
+ } else {
+ bytes = make([]byte, val.Len())
+ reflect.Copy(reflect.ValueOf(bytes), val)
+ }
+ return "", bytes, nil
+ case reflect.Slice:
+ if typ.Elem().Kind() != reflect.Uint8 {
+ break
+ }
+ // []byte
+ return "", val.Bytes(), nil
+ }
+ return "", nil, &UnsupportedTypeError{typ}
+}
+
+var ddBytes = []byte("--")
+
+// indirect drills into interfaces and pointers, returning the pointed-at value.
+// If it encounters a nil interface or pointer, indirect returns that nil value.
+// This can turn into an infinite loop given a cyclic chain,
+// but it matches the Go 1 behavior.
+func indirect(vf reflect.Value) reflect.Value {
+ for vf.Kind() == reflect.Interface || vf.Kind() == reflect.Pointer {
+ if vf.IsNil() {
+ return vf
+ }
+ vf = vf.Elem()
+ }
+ return vf
+}
+
+func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error {
+ s := parentStack{p: p}
+ for i := range tinfo.fields {
+ finfo := &tinfo.fields[i]
+ if finfo.flags&fAttr != 0 {
+ continue
+ }
+ vf := finfo.value(val, dontInitNilPointers)
+ if !vf.IsValid() {
+ // The field is behind an anonymous struct field that's
+ // nil. Skip it.
+ continue
+ }
+
+ switch finfo.flags & fMode {
+ case fCDATA, fCharData:
+ emit := EscapeText
+ if finfo.flags&fMode == fCDATA {
+ emit = emitCDATA
+ }
+ if err := s.trim(finfo.parents); err != nil {
+ return err
+ }
+ if vf.CanInterface() && vf.Type().Implements(textMarshalerType) {
+ data, err := vf.Interface().(encoding.TextMarshaler).MarshalText()
+ if err != nil {
+ return err
+ }
+ if err := emit(p, data); err != nil {
+ return err
+ }
+ continue
+ }
+ if vf.CanAddr() {
+ pv := vf.Addr()
+ if pv.CanInterface() && pv.Type().Implements(textMarshalerType) {
+ data, err := pv.Interface().(encoding.TextMarshaler).MarshalText()
+ if err != nil {
+ return err
+ }
+ if err := emit(p, data); err != nil {
+ return err
+ }
+ continue
+ }
+ }
+
+ var scratch [64]byte
+ vf = indirect(vf)
+ switch vf.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ if err := emit(p, strconv.AppendInt(scratch[:0], vf.Int(), 10)); err != nil {
+ return err
+ }
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ if err := emit(p, strconv.AppendUint(scratch[:0], vf.Uint(), 10)); err != nil {
+ return err
+ }
+ case reflect.Float32, reflect.Float64:
+ if err := emit(p, strconv.AppendFloat(scratch[:0], vf.Float(), 'g', -1, vf.Type().Bits())); err != nil {
+ return err
+ }
+ case reflect.Bool:
+ if err := emit(p, strconv.AppendBool(scratch[:0], vf.Bool())); err != nil {
+ return err
+ }
+ case reflect.String:
+ if err := emit(p, []byte(vf.String())); err != nil {
+ return err
+ }
+ case reflect.Slice:
+ if elem, ok := vf.Interface().([]byte); ok {
+ if err := emit(p, elem); err != nil {
+ return err
+ }
+ }
+ }
+ continue
+
+ case fComment:
+ if err := s.trim(finfo.parents); err != nil {
+ return err
+ }
+ vf = indirect(vf)
+ k := vf.Kind()
+ if !(k == reflect.String || k == reflect.Slice && vf.Type().Elem().Kind() == reflect.Uint8) {
+ return fmt.Errorf("xml: bad type for comment field of %s", val.Type())
+ }
+ if vf.Len() == 0 {
+ continue
+ }
+ p.writeIndent(0)
+ p.WriteString("<!--")
+ dashDash := false
+ dashLast := false
+ switch k {
+ case reflect.String:
+ s := vf.String()
+ dashDash = strings.Contains(s, "--")
+ dashLast = s[len(s)-1] == '-'
+ if !dashDash {
+ p.WriteString(s)
+ }
+ case reflect.Slice:
+ b := vf.Bytes()
+ dashDash = bytes.Contains(b, ddBytes)
+ dashLast = b[len(b)-1] == '-'
+ if !dashDash {
+ p.Write(b)
+ }
+ default:
+ panic("can't happen")
+ }
+ if dashDash {
+ return fmt.Errorf(`xml: comments must not contain "--"`)
+ }
+ if dashLast {
+ // "--->" is invalid grammar. Make it "- -->"
+ p.WriteByte(' ')
+ }
+ p.WriteString("-->")
+ continue
+
+ case fInnerXML:
+ vf = indirect(vf)
+ iface := vf.Interface()
+ switch raw := iface.(type) {
+ case []byte:
+ p.Write(raw)
+ continue
+ case string:
+ p.WriteString(raw)
+ continue
+ }
+
+ case fElement, fElement | fAny:
+ if err := s.trim(finfo.parents); err != nil {
+ return err
+ }
+ if len(finfo.parents) > len(s.stack) {
+ if vf.Kind() != reflect.Pointer && vf.Kind() != reflect.Interface || !vf.IsNil() {
+ if err := s.push(finfo.parents[len(s.stack):]); err != nil {
+ return err
+ }
+ }
+ }
+ }
+ if err := p.marshalValue(vf, finfo, nil); err != nil {
+ return err
+ }
+ }
+ s.trim(nil)
+ return p.cachedWriteError()
+}
+
+// Write implements io.Writer
+func (p *printer) Write(b []byte) (n int, err error) {
+ if p.closed && p.err == nil {
+ p.err = errors.New("use of closed Encoder")
+ }
+ if p.err == nil {
+ n, p.err = p.w.Write(b)
+ }
+ return n, p.err
+}
+
+// WriteString implements io.StringWriter
+func (p *printer) WriteString(s string) (n int, err error) {
+ if p.closed && p.err == nil {
+ p.err = errors.New("use of closed Encoder")
+ }
+ if p.err == nil {
+ n, p.err = p.w.WriteString(s)
+ }
+ return n, p.err
+}
+
+// WriteByte implements io.ByteWriter
+func (p *printer) WriteByte(c byte) error {
+ if p.closed && p.err == nil {
+ p.err = errors.New("use of closed Encoder")
+ }
+ if p.err == nil {
+ p.err = p.w.WriteByte(c)
+ }
+ return p.err
+}
+
+// Close the Encoder, indicating that no more data will be written. It flushes
+// any buffered XML to the underlying writer and returns an error if the
+// written XML is invalid (e.g. by containing unclosed elements).
+func (p *printer) Close() error {
+ if p.closed {
+ return nil
+ }
+ p.closed = true
+ if err := p.w.Flush(); err != nil {
+ return err
+ }
+ if len(p.tags) > 0 {
+ return fmt.Errorf("unclosed tag <%s>", p.tags[len(p.tags)-1].Local)
+ }
+ return nil
+}
+
+// return the bufio Writer's cached write error
+func (p *printer) cachedWriteError() error {
+ _, err := p.Write(nil)
+ return err
+}
+
+func (p *printer) writeIndent(depthDelta int) {
+ if len(p.prefix) == 0 && len(p.indent) == 0 {
+ return
+ }
+ if depthDelta < 0 {
+ p.depth--
+ if p.indentedIn {
+ p.indentedIn = false
+ return
+ }
+ p.indentedIn = false
+ }
+ if p.putNewline {
+ p.WriteByte('\n')
+ } else {
+ p.putNewline = true
+ }
+ if len(p.prefix) > 0 {
+ p.WriteString(p.prefix)
+ }
+ if len(p.indent) > 0 {
+ for i := 0; i < p.depth; i++ {
+ p.WriteString(p.indent)
+ }
+ }
+ if depthDelta > 0 {
+ p.depth++
+ p.indentedIn = true
+ }
+}
+
+type parentStack struct {
+ p *printer
+ stack []string
+}
+
+// trim updates the XML context to match the longest common prefix of the stack
+// and the given parents. A closing tag will be written for every parent
+// popped. Passing a zero slice or nil will close all the elements.
+func (s *parentStack) trim(parents []string) error {
+ split := 0
+ for ; split < len(parents) && split < len(s.stack); split++ {
+ if parents[split] != s.stack[split] {
+ break
+ }
+ }
+ for i := len(s.stack) - 1; i >= split; i-- {
+ if err := s.p.writeEnd(Name{Local: s.stack[i]}); err != nil {
+ return err
+ }
+ }
+ s.stack = s.stack[:split]
+ return nil
+}
+
+// push adds parent elements to the stack and writes open tags.
+func (s *parentStack) push(parents []string) error {
+ for i := 0; i < len(parents); i++ {
+ if err := s.p.writeStart(&StartElement{Name: Name{Local: parents[i]}}); err != nil {
+ return err
+ }
+ }
+ s.stack = append(s.stack, parents...)
+ return nil
+}
+
+// UnsupportedTypeError is returned when Marshal encounters a type
+// that cannot be converted into XML.
+type UnsupportedTypeError struct {
+ Type reflect.Type
+}
+
+func (e *UnsupportedTypeError) Error() string {
+ return "xml: unsupported type: " + e.Type.String()
+}
+
+func isEmptyValue(v reflect.Value) bool {
+ switch v.Kind() {
+ case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+ return v.Len() == 0
+ case reflect.Bool:
+ return !v.Bool()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return v.Int() == 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return v.Uint() == 0
+ case reflect.Float32, reflect.Float64:
+ return v.Float() == 0
+ case reflect.Interface, reflect.Pointer:
+ return v.IsNil()
+ }
+ return false
+}
diff --git a/contrib/go/_std_1.21/src/encoding/xml/read.go b/contrib/go/_std_1.21/src/encoding/xml/read.go
new file mode 100644
index 0000000000..c1c843e4c0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/xml/read.go
@@ -0,0 +1,777 @@
+// Copyright 2009 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 xml
+
+import (
+ "bytes"
+ "encoding"
+ "errors"
+ "fmt"
+ "reflect"
+ "runtime"
+ "strconv"
+ "strings"
+)
+
+// BUG(rsc): Mapping between XML elements and data structures is inherently flawed:
+// an XML element is an order-dependent collection of anonymous
+// values, while a data structure is an order-independent collection
+// of named values.
+// See package json for a textual representation more suitable
+// to data structures.
+
+// Unmarshal parses the XML-encoded data and stores the result in
+// the value pointed to by v, which must be an arbitrary struct,
+// slice, or string. Well-formed data that does not fit into v is
+// discarded.
+//
+// Because Unmarshal uses the reflect package, it can only assign
+// to exported (upper case) fields. Unmarshal uses a case-sensitive
+// comparison to match XML element names to tag values and struct
+// field names.
+//
+// Unmarshal maps an XML element to a struct using the following rules.
+// In the rules, the tag of a field refers to the value associated with the
+// key 'xml' in the struct field's tag (see the example above).
+//
+// - If the struct has a field of type []byte or string with tag
+// ",innerxml", Unmarshal accumulates the raw XML nested inside the
+// element in that field. The rest of the rules still apply.
+//
+// - If the struct has a field named XMLName of type Name,
+// Unmarshal records the element name in that field.
+//
+// - If the XMLName field has an associated tag of the form
+// "name" or "namespace-URL name", the XML element must have
+// the given name (and, optionally, name space) or else Unmarshal
+// returns an error.
+//
+// - If the XML element has an attribute whose name matches a
+// struct field name with an associated tag containing ",attr" or
+// the explicit name in a struct field tag of the form "name,attr",
+// Unmarshal records the attribute value in that field.
+//
+// - If the XML element has an attribute not handled by the previous
+// rule and the struct has a field with an associated tag containing
+// ",any,attr", Unmarshal records the attribute value in the first
+// such field.
+//
+// - If the XML element contains character data, that data is
+// accumulated in the first struct field that has tag ",chardata".
+// The struct field may have type []byte or string.
+// If there is no such field, the character data is discarded.
+//
+// - If the XML element contains comments, they are accumulated in
+// the first struct field that has tag ",comment". The struct
+// field may have type []byte or string. If there is no such
+// field, the comments are discarded.
+//
+// - If the XML element contains a sub-element whose name matches
+// the prefix of a tag formatted as "a" or "a>b>c", unmarshal
+// will descend into the XML structure looking for elements with the
+// given names, and will map the innermost elements to that struct
+// field. A tag starting with ">" is equivalent to one starting
+// with the field name followed by ">".
+//
+// - If the XML element contains a sub-element whose name matches
+// a struct field's XMLName tag and the struct field has no
+// explicit name tag as per the previous rule, unmarshal maps
+// the sub-element to that struct field.
+//
+// - If the XML element contains a sub-element whose name matches a
+// field without any mode flags (",attr", ",chardata", etc), Unmarshal
+// maps the sub-element to that struct field.
+//
+// - If the XML element contains a sub-element that hasn't matched any
+// of the above rules and the struct has a field with tag ",any",
+// unmarshal maps the sub-element to that struct field.
+//
+// - An anonymous struct field is handled as if the fields of its
+// value were part of the outer struct.
+//
+// - A struct field with tag "-" is never unmarshaled into.
+//
+// If Unmarshal encounters a field type that implements the Unmarshaler
+// interface, Unmarshal calls its UnmarshalXML method to produce the value from
+// the XML element. Otherwise, if the value implements
+// encoding.TextUnmarshaler, Unmarshal calls that value's UnmarshalText method.
+//
+// Unmarshal maps an XML element to a string or []byte by saving the
+// concatenation of that element's character data in the string or
+// []byte. The saved []byte is never nil.
+//
+// Unmarshal maps an attribute value to a string or []byte by saving
+// the value in the string or slice.
+//
+// Unmarshal maps an attribute value to an Attr by saving the attribute,
+// including its name, in the Attr.
+//
+// Unmarshal maps an XML element or attribute value to a slice by
+// extending the length of the slice and mapping the element or attribute
+// to the newly created value.
+//
+// Unmarshal maps an XML element or attribute value to a bool by
+// setting it to the boolean value represented by the string. Whitespace
+// is trimmed and ignored.
+//
+// Unmarshal maps an XML element or attribute value to an integer or
+// floating-point field by setting the field to the result of
+// interpreting the string value in decimal. There is no check for
+// overflow. Whitespace is trimmed and ignored.
+//
+// Unmarshal maps an XML element to a Name by recording the element
+// name.
+//
+// Unmarshal maps an XML element to a pointer by setting the pointer
+// to a freshly allocated value and then mapping the element to that value.
+//
+// A missing element or empty attribute value will be unmarshaled as a zero value.
+// If the field is a slice, a zero value will be appended to the field. Otherwise, the
+// field will be set to its zero value.
+func Unmarshal(data []byte, v any) error {
+ return NewDecoder(bytes.NewReader(data)).Decode(v)
+}
+
+// Decode works like Unmarshal, except it reads the decoder
+// stream to find the start element.
+func (d *Decoder) Decode(v any) error {
+ return d.DecodeElement(v, nil)
+}
+
+// DecodeElement works like Unmarshal except that it takes
+// a pointer to the start XML element to decode into v.
+// It is useful when a client reads some raw XML tokens itself
+// but also wants to defer to Unmarshal for some elements.
+func (d *Decoder) DecodeElement(v any, start *StartElement) error {
+ val := reflect.ValueOf(v)
+ if val.Kind() != reflect.Pointer {
+ return errors.New("non-pointer passed to Unmarshal")
+ }
+
+ if val.IsNil() {
+ return errors.New("nil pointer passed to Unmarshal")
+ }
+ return d.unmarshal(val.Elem(), start, 0)
+}
+
+// An UnmarshalError represents an error in the unmarshaling process.
+type UnmarshalError string
+
+func (e UnmarshalError) Error() string { return string(e) }
+
+// Unmarshaler is the interface implemented by objects that can unmarshal
+// an XML element description of themselves.
+//
+// UnmarshalXML decodes a single XML element
+// beginning with the given start element.
+// If it returns an error, the outer call to Unmarshal stops and
+// returns that error.
+// UnmarshalXML must consume exactly one XML element.
+// One common implementation strategy is to unmarshal into
+// a separate value with a layout matching the expected XML
+// using d.DecodeElement, and then to copy the data from
+// that value into the receiver.
+// Another common strategy is to use d.Token to process the
+// XML object one token at a time.
+// UnmarshalXML may not use d.RawToken.
+type Unmarshaler interface {
+ UnmarshalXML(d *Decoder, start StartElement) error
+}
+
+// UnmarshalerAttr is the interface implemented by objects that can unmarshal
+// an XML attribute description of themselves.
+//
+// UnmarshalXMLAttr decodes a single XML attribute.
+// If it returns an error, the outer call to Unmarshal stops and
+// returns that error.
+// UnmarshalXMLAttr is used only for struct fields with the
+// "attr" option in the field tag.
+type UnmarshalerAttr interface {
+ UnmarshalXMLAttr(attr Attr) error
+}
+
+// receiverType returns the receiver type to use in an expression like "%s.MethodName".
+func receiverType(val any) string {
+ t := reflect.TypeOf(val)
+ if t.Name() != "" {
+ return t.String()
+ }
+ return "(" + t.String() + ")"
+}
+
+// unmarshalInterface unmarshals a single XML element into val.
+// start is the opening tag of the element.
+func (d *Decoder) unmarshalInterface(val Unmarshaler, start *StartElement) error {
+ // Record that decoder must stop at end tag corresponding to start.
+ d.pushEOF()
+
+ d.unmarshalDepth++
+ err := val.UnmarshalXML(d, *start)
+ d.unmarshalDepth--
+ if err != nil {
+ d.popEOF()
+ return err
+ }
+
+ if !d.popEOF() {
+ return fmt.Errorf("xml: %s.UnmarshalXML did not consume entire <%s> element", receiverType(val), start.Name.Local)
+ }
+
+ return nil
+}
+
+// unmarshalTextInterface unmarshals a single XML element into val.
+// The chardata contained in the element (but not its children)
+// is passed to the text unmarshaler.
+func (d *Decoder) unmarshalTextInterface(val encoding.TextUnmarshaler) error {
+ var buf []byte
+ depth := 1
+ for depth > 0 {
+ t, err := d.Token()
+ if err != nil {
+ return err
+ }
+ switch t := t.(type) {
+ case CharData:
+ if depth == 1 {
+ buf = append(buf, t...)
+ }
+ case StartElement:
+ depth++
+ case EndElement:
+ depth--
+ }
+ }
+ return val.UnmarshalText(buf)
+}
+
+// unmarshalAttr unmarshals a single XML attribute into val.
+func (d *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error {
+ if val.Kind() == reflect.Pointer {
+ if val.IsNil() {
+ val.Set(reflect.New(val.Type().Elem()))
+ }
+ val = val.Elem()
+ }
+ if val.CanInterface() && val.Type().Implements(unmarshalerAttrType) {
+ // This is an unmarshaler with a non-pointer receiver,
+ // so it's likely to be incorrect, but we do what we're told.
+ return val.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr)
+ }
+ if val.CanAddr() {
+ pv := val.Addr()
+ if pv.CanInterface() && pv.Type().Implements(unmarshalerAttrType) {
+ return pv.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr)
+ }
+ }
+
+ // Not an UnmarshalerAttr; try encoding.TextUnmarshaler.
+ if val.CanInterface() && val.Type().Implements(textUnmarshalerType) {
+ // This is an unmarshaler with a non-pointer receiver,
+ // so it's likely to be incorrect, but we do what we're told.
+ return val.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value))
+ }
+ if val.CanAddr() {
+ pv := val.Addr()
+ if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
+ return pv.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value))
+ }
+ }
+
+ if val.Type().Kind() == reflect.Slice && val.Type().Elem().Kind() != reflect.Uint8 {
+ // Slice of element values.
+ // Grow slice.
+ n := val.Len()
+ val.Grow(1)
+ val.SetLen(n + 1)
+
+ // Recur to read element into slice.
+ if err := d.unmarshalAttr(val.Index(n), attr); err != nil {
+ val.SetLen(n)
+ return err
+ }
+ return nil
+ }
+
+ if val.Type() == attrType {
+ val.Set(reflect.ValueOf(attr))
+ return nil
+ }
+
+ return copyValue(val, []byte(attr.Value))
+}
+
+var (
+ attrType = reflect.TypeOf(Attr{})
+ unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
+ unmarshalerAttrType = reflect.TypeOf((*UnmarshalerAttr)(nil)).Elem()
+ textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+)
+
+const (
+ maxUnmarshalDepth = 10000
+ maxUnmarshalDepthWasm = 5000 // go.dev/issue/56498
+)
+
+var errUnmarshalDepth = errors.New("exceeded max depth")
+
+// Unmarshal a single XML element into val.
+func (d *Decoder) unmarshal(val reflect.Value, start *StartElement, depth int) error {
+ if depth >= maxUnmarshalDepth || runtime.GOARCH == "wasm" && depth >= maxUnmarshalDepthWasm {
+ return errUnmarshalDepth
+ }
+ // Find start element if we need it.
+ if start == nil {
+ for {
+ tok, err := d.Token()
+ if err != nil {
+ return err
+ }
+ if t, ok := tok.(StartElement); ok {
+ start = &t
+ break
+ }
+ }
+ }
+
+ // Load value from interface, but only if the result will be
+ // usefully addressable.
+ if val.Kind() == reflect.Interface && !val.IsNil() {
+ e := val.Elem()
+ if e.Kind() == reflect.Pointer && !e.IsNil() {
+ val = e
+ }
+ }
+
+ if val.Kind() == reflect.Pointer {
+ if val.IsNil() {
+ val.Set(reflect.New(val.Type().Elem()))
+ }
+ val = val.Elem()
+ }
+
+ if val.CanInterface() && val.Type().Implements(unmarshalerType) {
+ // This is an unmarshaler with a non-pointer receiver,
+ // so it's likely to be incorrect, but we do what we're told.
+ return d.unmarshalInterface(val.Interface().(Unmarshaler), start)
+ }
+
+ if val.CanAddr() {
+ pv := val.Addr()
+ if pv.CanInterface() && pv.Type().Implements(unmarshalerType) {
+ return d.unmarshalInterface(pv.Interface().(Unmarshaler), start)
+ }
+ }
+
+ if val.CanInterface() && val.Type().Implements(textUnmarshalerType) {
+ return d.unmarshalTextInterface(val.Interface().(encoding.TextUnmarshaler))
+ }
+
+ if val.CanAddr() {
+ pv := val.Addr()
+ if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
+ return d.unmarshalTextInterface(pv.Interface().(encoding.TextUnmarshaler))
+ }
+ }
+
+ var (
+ data []byte
+ saveData reflect.Value
+ comment []byte
+ saveComment reflect.Value
+ saveXML reflect.Value
+ saveXMLIndex int
+ saveXMLData []byte
+ saveAny reflect.Value
+ sv reflect.Value
+ tinfo *typeInfo
+ err error
+ )
+
+ switch v := val; v.Kind() {
+ default:
+ return errors.New("unknown type " + v.Type().String())
+
+ case reflect.Interface:
+ // TODO: For now, simply ignore the field. In the near
+ // future we may choose to unmarshal the start
+ // element on it, if not nil.
+ return d.Skip()
+
+ case reflect.Slice:
+ typ := v.Type()
+ if typ.Elem().Kind() == reflect.Uint8 {
+ // []byte
+ saveData = v
+ break
+ }
+
+ // Slice of element values.
+ // Grow slice.
+ n := v.Len()
+ v.Grow(1)
+ v.SetLen(n + 1)
+
+ // Recur to read element into slice.
+ if err := d.unmarshal(v.Index(n), start, depth+1); err != nil {
+ v.SetLen(n)
+ return err
+ }
+ return nil
+
+ case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.String:
+ saveData = v
+
+ case reflect.Struct:
+ typ := v.Type()
+ if typ == nameType {
+ v.Set(reflect.ValueOf(start.Name))
+ break
+ }
+
+ sv = v
+ tinfo, err = getTypeInfo(typ)
+ if err != nil {
+ return err
+ }
+
+ // Validate and assign element name.
+ if tinfo.xmlname != nil {
+ finfo := tinfo.xmlname
+ if finfo.name != "" && finfo.name != start.Name.Local {
+ return UnmarshalError("expected element type <" + finfo.name + "> but have <" + start.Name.Local + ">")
+ }
+ if finfo.xmlns != "" && finfo.xmlns != start.Name.Space {
+ e := "expected element <" + finfo.name + "> in name space " + finfo.xmlns + " but have "
+ if start.Name.Space == "" {
+ e += "no name space"
+ } else {
+ e += start.Name.Space
+ }
+ return UnmarshalError(e)
+ }
+ fv := finfo.value(sv, initNilPointers)
+ if _, ok := fv.Interface().(Name); ok {
+ fv.Set(reflect.ValueOf(start.Name))
+ }
+ }
+
+ // Assign attributes.
+ for _, a := range start.Attr {
+ handled := false
+ any := -1
+ for i := range tinfo.fields {
+ finfo := &tinfo.fields[i]
+ switch finfo.flags & fMode {
+ case fAttr:
+ strv := finfo.value(sv, initNilPointers)
+ if a.Name.Local == finfo.name && (finfo.xmlns == "" || finfo.xmlns == a.Name.Space) {
+ if err := d.unmarshalAttr(strv, a); err != nil {
+ return err
+ }
+ handled = true
+ }
+
+ case fAny | fAttr:
+ if any == -1 {
+ any = i
+ }
+ }
+ }
+ if !handled && any >= 0 {
+ finfo := &tinfo.fields[any]
+ strv := finfo.value(sv, initNilPointers)
+ if err := d.unmarshalAttr(strv, a); err != nil {
+ return err
+ }
+ }
+ }
+
+ // Determine whether we need to save character data or comments.
+ for i := range tinfo.fields {
+ finfo := &tinfo.fields[i]
+ switch finfo.flags & fMode {
+ case fCDATA, fCharData:
+ if !saveData.IsValid() {
+ saveData = finfo.value(sv, initNilPointers)
+ }
+
+ case fComment:
+ if !saveComment.IsValid() {
+ saveComment = finfo.value(sv, initNilPointers)
+ }
+
+ case fAny, fAny | fElement:
+ if !saveAny.IsValid() {
+ saveAny = finfo.value(sv, initNilPointers)
+ }
+
+ case fInnerXML:
+ if !saveXML.IsValid() {
+ saveXML = finfo.value(sv, initNilPointers)
+ if d.saved == nil {
+ saveXMLIndex = 0
+ d.saved = new(bytes.Buffer)
+ } else {
+ saveXMLIndex = d.savedOffset()
+ }
+ }
+ }
+ }
+ }
+
+ // Find end element.
+ // Process sub-elements along the way.
+Loop:
+ for {
+ var savedOffset int
+ if saveXML.IsValid() {
+ savedOffset = d.savedOffset()
+ }
+ tok, err := d.Token()
+ if err != nil {
+ return err
+ }
+ switch t := tok.(type) {
+ case StartElement:
+ consumed := false
+ if sv.IsValid() {
+ // unmarshalPath can call unmarshal, so we need to pass the depth through so that
+ // we can continue to enforce the maximum recursion limit.
+ consumed, err = d.unmarshalPath(tinfo, sv, nil, &t, depth)
+ if err != nil {
+ return err
+ }
+ if !consumed && saveAny.IsValid() {
+ consumed = true
+ if err := d.unmarshal(saveAny, &t, depth+1); err != nil {
+ return err
+ }
+ }
+ }
+ if !consumed {
+ if err := d.Skip(); err != nil {
+ return err
+ }
+ }
+
+ case EndElement:
+ if saveXML.IsValid() {
+ saveXMLData = d.saved.Bytes()[saveXMLIndex:savedOffset]
+ if saveXMLIndex == 0 {
+ d.saved = nil
+ }
+ }
+ break Loop
+
+ case CharData:
+ if saveData.IsValid() {
+ data = append(data, t...)
+ }
+
+ case Comment:
+ if saveComment.IsValid() {
+ comment = append(comment, t...)
+ }
+ }
+ }
+
+ if saveData.IsValid() && saveData.CanInterface() && saveData.Type().Implements(textUnmarshalerType) {
+ if err := saveData.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil {
+ return err
+ }
+ saveData = reflect.Value{}
+ }
+
+ if saveData.IsValid() && saveData.CanAddr() {
+ pv := saveData.Addr()
+ if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) {
+ if err := pv.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil {
+ return err
+ }
+ saveData = reflect.Value{}
+ }
+ }
+
+ if err := copyValue(saveData, data); err != nil {
+ return err
+ }
+
+ switch t := saveComment; t.Kind() {
+ case reflect.String:
+ t.SetString(string(comment))
+ case reflect.Slice:
+ t.Set(reflect.ValueOf(comment))
+ }
+
+ switch t := saveXML; t.Kind() {
+ case reflect.String:
+ t.SetString(string(saveXMLData))
+ case reflect.Slice:
+ if t.Type().Elem().Kind() == reflect.Uint8 {
+ t.Set(reflect.ValueOf(saveXMLData))
+ }
+ }
+
+ return nil
+}
+
+func copyValue(dst reflect.Value, src []byte) (err error) {
+ dst0 := dst
+
+ if dst.Kind() == reflect.Pointer {
+ if dst.IsNil() {
+ dst.Set(reflect.New(dst.Type().Elem()))
+ }
+ dst = dst.Elem()
+ }
+
+ // Save accumulated data.
+ switch dst.Kind() {
+ case reflect.Invalid:
+ // Probably a comment.
+ default:
+ return errors.New("cannot unmarshal into " + dst0.Type().String())
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ if len(src) == 0 {
+ dst.SetInt(0)
+ return nil
+ }
+ itmp, err := strconv.ParseInt(strings.TrimSpace(string(src)), 10, dst.Type().Bits())
+ if err != nil {
+ return err
+ }
+ dst.SetInt(itmp)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ if len(src) == 0 {
+ dst.SetUint(0)
+ return nil
+ }
+ utmp, err := strconv.ParseUint(strings.TrimSpace(string(src)), 10, dst.Type().Bits())
+ if err != nil {
+ return err
+ }
+ dst.SetUint(utmp)
+ case reflect.Float32, reflect.Float64:
+ if len(src) == 0 {
+ dst.SetFloat(0)
+ return nil
+ }
+ ftmp, err := strconv.ParseFloat(strings.TrimSpace(string(src)), dst.Type().Bits())
+ if err != nil {
+ return err
+ }
+ dst.SetFloat(ftmp)
+ case reflect.Bool:
+ if len(src) == 0 {
+ dst.SetBool(false)
+ return nil
+ }
+ value, err := strconv.ParseBool(strings.TrimSpace(string(src)))
+ if err != nil {
+ return err
+ }
+ dst.SetBool(value)
+ case reflect.String:
+ dst.SetString(string(src))
+ case reflect.Slice:
+ if len(src) == 0 {
+ // non-nil to flag presence
+ src = []byte{}
+ }
+ dst.SetBytes(src)
+ }
+ return nil
+}
+
+// unmarshalPath walks down an XML structure looking for wanted
+// paths, and calls unmarshal on them.
+// The consumed result tells whether XML elements have been consumed
+// from the Decoder until start's matching end element, or if it's
+// still untouched because start is uninteresting for sv's fields.
+func (d *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []string, start *StartElement, depth int) (consumed bool, err error) {
+ recurse := false
+Loop:
+ for i := range tinfo.fields {
+ finfo := &tinfo.fields[i]
+ if finfo.flags&fElement == 0 || len(finfo.parents) < len(parents) || finfo.xmlns != "" && finfo.xmlns != start.Name.Space {
+ continue
+ }
+ for j := range parents {
+ if parents[j] != finfo.parents[j] {
+ continue Loop
+ }
+ }
+ if len(finfo.parents) == len(parents) && finfo.name == start.Name.Local {
+ // It's a perfect match, unmarshal the field.
+ return true, d.unmarshal(finfo.value(sv, initNilPointers), start, depth+1)
+ }
+ if len(finfo.parents) > len(parents) && finfo.parents[len(parents)] == start.Name.Local {
+ // It's a prefix for the field. Break and recurse
+ // since it's not ok for one field path to be itself
+ // the prefix for another field path.
+ recurse = true
+
+ // We can reuse the same slice as long as we
+ // don't try to append to it.
+ parents = finfo.parents[:len(parents)+1]
+ break
+ }
+ }
+ if !recurse {
+ // We have no business with this element.
+ return false, nil
+ }
+ // The element is not a perfect match for any field, but one
+ // or more fields have the path to this element as a parent
+ // prefix. Recurse and attempt to match these.
+ for {
+ var tok Token
+ tok, err = d.Token()
+ if err != nil {
+ return true, err
+ }
+ switch t := tok.(type) {
+ case StartElement:
+ // the recursion depth of unmarshalPath is limited to the path length specified
+ // by the struct field tag, so we don't increment the depth here.
+ consumed2, err := d.unmarshalPath(tinfo, sv, parents, &t, depth)
+ if err != nil {
+ return true, err
+ }
+ if !consumed2 {
+ if err := d.Skip(); err != nil {
+ return true, err
+ }
+ }
+ case EndElement:
+ return true, nil
+ }
+ }
+}
+
+// Skip reads tokens until it has consumed the end element
+// matching the most recent start element already consumed,
+// skipping nested structures.
+// It returns nil if it finds an end element matching the start
+// element; otherwise it returns an error describing the problem.
+func (d *Decoder) Skip() error {
+ var depth int64
+ for {
+ tok, err := d.Token()
+ if err != nil {
+ return err
+ }
+ switch tok.(type) {
+ case StartElement:
+ depth++
+ case EndElement:
+ if depth == 0 {
+ return nil
+ }
+ depth--
+ }
+ }
+}
diff --git a/contrib/go/_std_1.20/src/encoding/xml/typeinfo.go b/contrib/go/_std_1.21/src/encoding/xml/typeinfo.go
index 2f123fdbb4..2f123fdbb4 100644
--- a/contrib/go/_std_1.20/src/encoding/xml/typeinfo.go
+++ b/contrib/go/_std_1.21/src/encoding/xml/typeinfo.go
diff --git a/contrib/go/_std_1.21/src/encoding/xml/xml.go b/contrib/go/_std_1.21/src/encoding/xml/xml.go
new file mode 100644
index 0000000000..d121986944
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/xml/xml.go
@@ -0,0 +1,2060 @@
+// Copyright 2009 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 xml implements a simple XML 1.0 parser that
+// understands XML name spaces.
+package xml
+
+// References:
+// Annotated XML spec: https://www.xml.com/axml/testaxml.htm
+// XML name spaces: https://www.w3.org/TR/REC-xml-names/
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "strconv"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+)
+
+// A SyntaxError represents a syntax error in the XML input stream.
+type SyntaxError struct {
+ Msg string
+ Line int
+}
+
+func (e *SyntaxError) Error() string {
+ return "XML syntax error on line " + strconv.Itoa(e.Line) + ": " + e.Msg
+}
+
+// A Name represents an XML name (Local) annotated
+// with a name space identifier (Space).
+// In tokens returned by Decoder.Token, the Space identifier
+// is given as a canonical URL, not the short prefix used
+// in the document being parsed.
+type Name struct {
+ Space, Local string
+}
+
+// An Attr represents an attribute in an XML element (Name=Value).
+type Attr struct {
+ Name Name
+ Value string
+}
+
+// A Token is an interface holding one of the token types:
+// StartElement, EndElement, CharData, Comment, ProcInst, or Directive.
+type Token any
+
+// A StartElement represents an XML start element.
+type StartElement struct {
+ Name Name
+ Attr []Attr
+}
+
+// Copy creates a new copy of StartElement.
+func (e StartElement) Copy() StartElement {
+ attrs := make([]Attr, len(e.Attr))
+ copy(attrs, e.Attr)
+ e.Attr = attrs
+ return e
+}
+
+// End returns the corresponding XML end element.
+func (e StartElement) End() EndElement {
+ return EndElement{e.Name}
+}
+
+// An EndElement represents an XML end element.
+type EndElement struct {
+ Name Name
+}
+
+// A CharData represents XML character data (raw text),
+// in which XML escape sequences have been replaced by
+// the characters they represent.
+type CharData []byte
+
+// Copy creates a new copy of CharData.
+func (c CharData) Copy() CharData { return CharData(bytes.Clone(c)) }
+
+// A Comment represents an XML comment of the form <!--comment-->.
+// The bytes do not include the <!-- and --> comment markers.
+type Comment []byte
+
+// Copy creates a new copy of Comment.
+func (c Comment) Copy() Comment { return Comment(bytes.Clone(c)) }
+
+// A ProcInst represents an XML processing instruction of the form <?target inst?>
+type ProcInst struct {
+ Target string
+ Inst []byte
+}
+
+// Copy creates a new copy of ProcInst.
+func (p ProcInst) Copy() ProcInst {
+ p.Inst = bytes.Clone(p.Inst)
+ return p
+}
+
+// A Directive represents an XML directive of the form <!text>.
+// The bytes do not include the <! and > markers.
+type Directive []byte
+
+// Copy creates a new copy of Directive.
+func (d Directive) Copy() Directive { return Directive(bytes.Clone(d)) }
+
+// CopyToken returns a copy of a Token.
+func CopyToken(t Token) Token {
+ switch v := t.(type) {
+ case CharData:
+ return v.Copy()
+ case Comment:
+ return v.Copy()
+ case Directive:
+ return v.Copy()
+ case ProcInst:
+ return v.Copy()
+ case StartElement:
+ return v.Copy()
+ }
+ return t
+}
+
+// A TokenReader is anything that can decode a stream of XML tokens, including a
+// Decoder.
+//
+// When Token encounters an error or end-of-file condition after successfully
+// reading a token, it returns the token. It may return the (non-nil) error from
+// the same call or return the error (and a nil token) from a subsequent call.
+// An instance of this general case is that a TokenReader returning a non-nil
+// token at the end of the token stream may return either io.EOF or a nil error.
+// The next Read should return nil, io.EOF.
+//
+// Implementations of Token are discouraged from returning a nil token with a
+// nil error. Callers should treat a return of nil, nil as indicating that
+// nothing happened; in particular it does not indicate EOF.
+type TokenReader interface {
+ Token() (Token, error)
+}
+
+// A Decoder represents an XML parser reading a particular input stream.
+// The parser assumes that its input is encoded in UTF-8.
+type Decoder struct {
+ // Strict defaults to true, enforcing the requirements
+ // of the XML specification.
+ // If set to false, the parser allows input containing common
+ // mistakes:
+ // * If an element is missing an end tag, the parser invents
+ // end tags as necessary to keep the return values from Token
+ // properly balanced.
+ // * In attribute values and character data, unknown or malformed
+ // character entities (sequences beginning with &) are left alone.
+ //
+ // Setting:
+ //
+ // d.Strict = false
+ // d.AutoClose = xml.HTMLAutoClose
+ // d.Entity = xml.HTMLEntity
+ //
+ // creates a parser that can handle typical HTML.
+ //
+ // Strict mode does not enforce the requirements of the XML name spaces TR.
+ // In particular it does not reject name space tags using undefined prefixes.
+ // Such tags are recorded with the unknown prefix as the name space URL.
+ Strict bool
+
+ // When Strict == false, AutoClose indicates a set of elements to
+ // consider closed immediately after they are opened, regardless
+ // of whether an end element is present.
+ AutoClose []string
+
+ // Entity can be used to map non-standard entity names to string replacements.
+ // The parser behaves as if these standard mappings are present in the map,
+ // regardless of the actual map content:
+ //
+ // "lt": "<",
+ // "gt": ">",
+ // "amp": "&",
+ // "apos": "'",
+ // "quot": `"`,
+ Entity map[string]string
+
+ // CharsetReader, if non-nil, defines a function to generate
+ // charset-conversion readers, converting from the provided
+ // non-UTF-8 charset into UTF-8. If CharsetReader is nil or
+ // returns an error, parsing stops with an error. One of the
+ // CharsetReader's result values must be non-nil.
+ CharsetReader func(charset string, input io.Reader) (io.Reader, error)
+
+ // DefaultSpace sets the default name space used for unadorned tags,
+ // as if the entire XML stream were wrapped in an element containing
+ // the attribute xmlns="DefaultSpace".
+ DefaultSpace string
+
+ r io.ByteReader
+ t TokenReader
+ buf bytes.Buffer
+ saved *bytes.Buffer
+ stk *stack
+ free *stack
+ needClose bool
+ toClose Name
+ nextToken Token
+ nextByte int
+ ns map[string]string
+ err error
+ line int
+ linestart int64
+ offset int64
+ unmarshalDepth int
+}
+
+// NewDecoder creates a new XML parser reading from r.
+// If r does not implement io.ByteReader, NewDecoder will
+// do its own buffering.
+func NewDecoder(r io.Reader) *Decoder {
+ d := &Decoder{
+ ns: make(map[string]string),
+ nextByte: -1,
+ line: 1,
+ Strict: true,
+ }
+ d.switchToReader(r)
+ return d
+}
+
+// NewTokenDecoder creates a new XML parser using an underlying token stream.
+func NewTokenDecoder(t TokenReader) *Decoder {
+ // Is it already a Decoder?
+ if d, ok := t.(*Decoder); ok {
+ return d
+ }
+ d := &Decoder{
+ ns: make(map[string]string),
+ t: t,
+ nextByte: -1,
+ line: 1,
+ Strict: true,
+ }
+ return d
+}
+
+// Token returns the next XML token in the input stream.
+// At the end of the input stream, Token returns nil, io.EOF.
+//
+// Slices of bytes in the returned token data refer to the
+// parser's internal buffer and remain valid only until the next
+// call to Token. To acquire a copy of the bytes, call CopyToken
+// or the token's Copy method.
+//
+// Token expands self-closing elements such as <br>
+// into separate start and end elements returned by successive calls.
+//
+// Token guarantees that the StartElement and EndElement
+// tokens it returns are properly nested and matched:
+// if Token encounters an unexpected end element
+// or EOF before all expected end elements,
+// it will return an error.
+//
+// If CharsetReader is called and returns an error,
+// the error is wrapped and returned.
+//
+// Token implements XML name spaces as described by
+// https://www.w3.org/TR/REC-xml-names/. Each of the
+// Name structures contained in the Token has the Space
+// set to the URL identifying its name space when known.
+// If Token encounters an unrecognized name space prefix,
+// it uses the prefix as the Space rather than report an error.
+func (d *Decoder) Token() (Token, error) {
+ var t Token
+ var err error
+ if d.stk != nil && d.stk.kind == stkEOF {
+ return nil, io.EOF
+ }
+ if d.nextToken != nil {
+ t = d.nextToken
+ d.nextToken = nil
+ } else {
+ if t, err = d.rawToken(); t == nil && err != nil {
+ if err == io.EOF && d.stk != nil && d.stk.kind != stkEOF {
+ err = d.syntaxError("unexpected EOF")
+ }
+ return nil, err
+ }
+ // We still have a token to process, so clear any
+ // errors (e.g. EOF) and proceed.
+ err = nil
+ }
+ if !d.Strict {
+ if t1, ok := d.autoClose(t); ok {
+ d.nextToken = t
+ t = t1
+ }
+ }
+ switch t1 := t.(type) {
+ case StartElement:
+ // In XML name spaces, the translations listed in the
+ // attributes apply to the element name and
+ // to the other attribute names, so process
+ // the translations first.
+ for _, a := range t1.Attr {
+ if a.Name.Space == xmlnsPrefix {
+ v, ok := d.ns[a.Name.Local]
+ d.pushNs(a.Name.Local, v, ok)
+ d.ns[a.Name.Local] = a.Value
+ }
+ if a.Name.Space == "" && a.Name.Local == xmlnsPrefix {
+ // Default space for untagged names
+ v, ok := d.ns[""]
+ d.pushNs("", v, ok)
+ d.ns[""] = a.Value
+ }
+ }
+
+ d.pushElement(t1.Name)
+ d.translate(&t1.Name, true)
+ for i := range t1.Attr {
+ d.translate(&t1.Attr[i].Name, false)
+ }
+ t = t1
+
+ case EndElement:
+ if !d.popElement(&t1) {
+ return nil, d.err
+ }
+ t = t1
+ }
+ return t, err
+}
+
+const (
+ xmlURL = "http://www.w3.org/XML/1998/namespace"
+ xmlnsPrefix = "xmlns"
+ xmlPrefix = "xml"
+)
+
+// Apply name space translation to name n.
+// The default name space (for Space=="")
+// applies only to element names, not to attribute names.
+func (d *Decoder) translate(n *Name, isElementName bool) {
+ switch {
+ case n.Space == xmlnsPrefix:
+ return
+ case n.Space == "" && !isElementName:
+ return
+ case n.Space == xmlPrefix:
+ n.Space = xmlURL
+ case n.Space == "" && n.Local == xmlnsPrefix:
+ return
+ }
+ if v, ok := d.ns[n.Space]; ok {
+ n.Space = v
+ } else if n.Space == "" {
+ n.Space = d.DefaultSpace
+ }
+}
+
+func (d *Decoder) switchToReader(r io.Reader) {
+ // Get efficient byte at a time reader.
+ // Assume that if reader has its own
+ // ReadByte, it's efficient enough.
+ // Otherwise, use bufio.
+ if rb, ok := r.(io.ByteReader); ok {
+ d.r = rb
+ } else {
+ d.r = bufio.NewReader(r)
+ }
+}
+
+// Parsing state - stack holds old name space translations
+// and the current set of open elements. The translations to pop when
+// ending a given tag are *below* it on the stack, which is
+// more work but forced on us by XML.
+type stack struct {
+ next *stack
+ kind int
+ name Name
+ ok bool
+}
+
+const (
+ stkStart = iota
+ stkNs
+ stkEOF
+)
+
+func (d *Decoder) push(kind int) *stack {
+ s := d.free
+ if s != nil {
+ d.free = s.next
+ } else {
+ s = new(stack)
+ }
+ s.next = d.stk
+ s.kind = kind
+ d.stk = s
+ return s
+}
+
+func (d *Decoder) pop() *stack {
+ s := d.stk
+ if s != nil {
+ d.stk = s.next
+ s.next = d.free
+ d.free = s
+ }
+ return s
+}
+
+// Record that after the current element is finished
+// (that element is already pushed on the stack)
+// Token should return EOF until popEOF is called.
+func (d *Decoder) pushEOF() {
+ // Walk down stack to find Start.
+ // It might not be the top, because there might be stkNs
+ // entries above it.
+ start := d.stk
+ for start.kind != stkStart {
+ start = start.next
+ }
+ // The stkNs entries below a start are associated with that
+ // element too; skip over them.
+ for start.next != nil && start.next.kind == stkNs {
+ start = start.next
+ }
+ s := d.free
+ if s != nil {
+ d.free = s.next
+ } else {
+ s = new(stack)
+ }
+ s.kind = stkEOF
+ s.next = start.next
+ start.next = s
+}
+
+// Undo a pushEOF.
+// The element must have been finished, so the EOF should be at the top of the stack.
+func (d *Decoder) popEOF() bool {
+ if d.stk == nil || d.stk.kind != stkEOF {
+ return false
+ }
+ d.pop()
+ return true
+}
+
+// Record that we are starting an element with the given name.
+func (d *Decoder) pushElement(name Name) {
+ s := d.push(stkStart)
+ s.name = name
+}
+
+// Record that we are changing the value of ns[local].
+// The old value is url, ok.
+func (d *Decoder) pushNs(local string, url string, ok bool) {
+ s := d.push(stkNs)
+ s.name.Local = local
+ s.name.Space = url
+ s.ok = ok
+}
+
+// Creates a SyntaxError with the current line number.
+func (d *Decoder) syntaxError(msg string) error {
+ return &SyntaxError{Msg: msg, Line: d.line}
+}
+
+// Record that we are ending an element with the given name.
+// The name must match the record at the top of the stack,
+// which must be a pushElement record.
+// After popping the element, apply any undo records from
+// the stack to restore the name translations that existed
+// before we saw this element.
+func (d *Decoder) popElement(t *EndElement) bool {
+ s := d.pop()
+ name := t.Name
+ switch {
+ case s == nil || s.kind != stkStart:
+ d.err = d.syntaxError("unexpected end element </" + name.Local + ">")
+ return false
+ case s.name.Local != name.Local:
+ if !d.Strict {
+ d.needClose = true
+ d.toClose = t.Name
+ t.Name = s.name
+ return true
+ }
+ d.err = d.syntaxError("element <" + s.name.Local + "> closed by </" + name.Local + ">")
+ return false
+ case s.name.Space != name.Space:
+ d.err = d.syntaxError("element <" + s.name.Local + "> in space " + s.name.Space +
+ " closed by </" + name.Local + "> in space " + name.Space)
+ return false
+ }
+
+ d.translate(&t.Name, true)
+
+ // Pop stack until a Start or EOF is on the top, undoing the
+ // translations that were associated with the element we just closed.
+ for d.stk != nil && d.stk.kind != stkStart && d.stk.kind != stkEOF {
+ s := d.pop()
+ if s.ok {
+ d.ns[s.name.Local] = s.name.Space
+ } else {
+ delete(d.ns, s.name.Local)
+ }
+ }
+
+ return true
+}
+
+// If the top element on the stack is autoclosing and
+// t is not the end tag, invent the end tag.
+func (d *Decoder) autoClose(t Token) (Token, bool) {
+ if d.stk == nil || d.stk.kind != stkStart {
+ return nil, false
+ }
+ for _, s := range d.AutoClose {
+ if strings.EqualFold(s, d.stk.name.Local) {
+ // This one should be auto closed if t doesn't close it.
+ et, ok := t.(EndElement)
+ if !ok || !strings.EqualFold(et.Name.Local, d.stk.name.Local) {
+ return EndElement{d.stk.name}, true
+ }
+ break
+ }
+ }
+ return nil, false
+}
+
+var errRawToken = errors.New("xml: cannot use RawToken from UnmarshalXML method")
+
+// RawToken is like Token but does not verify that
+// start and end elements match and does not translate
+// name space prefixes to their corresponding URLs.
+func (d *Decoder) RawToken() (Token, error) {
+ if d.unmarshalDepth > 0 {
+ return nil, errRawToken
+ }
+ return d.rawToken()
+}
+
+func (d *Decoder) rawToken() (Token, error) {
+ if d.t != nil {
+ return d.t.Token()
+ }
+ if d.err != nil {
+ return nil, d.err
+ }
+ if d.needClose {
+ // The last element we read was self-closing and
+ // we returned just the StartElement half.
+ // Return the EndElement half now.
+ d.needClose = false
+ return EndElement{d.toClose}, nil
+ }
+
+ b, ok := d.getc()
+ if !ok {
+ return nil, d.err
+ }
+
+ if b != '<' {
+ // Text section.
+ d.ungetc(b)
+ data := d.text(-1, false)
+ if data == nil {
+ return nil, d.err
+ }
+ return CharData(data), nil
+ }
+
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ switch b {
+ case '/':
+ // </: End element
+ var name Name
+ if name, ok = d.nsname(); !ok {
+ if d.err == nil {
+ d.err = d.syntaxError("expected element name after </")
+ }
+ return nil, d.err
+ }
+ d.space()
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ if b != '>' {
+ d.err = d.syntaxError("invalid characters between </" + name.Local + " and >")
+ return nil, d.err
+ }
+ return EndElement{name}, nil
+
+ case '?':
+ // <?: Processing instruction.
+ var target string
+ if target, ok = d.name(); !ok {
+ if d.err == nil {
+ d.err = d.syntaxError("expected target name after <?")
+ }
+ return nil, d.err
+ }
+ d.space()
+ d.buf.Reset()
+ var b0 byte
+ for {
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ d.buf.WriteByte(b)
+ if b0 == '?' && b == '>' {
+ break
+ }
+ b0 = b
+ }
+ data := d.buf.Bytes()
+ data = data[0 : len(data)-2] // chop ?>
+
+ if target == "xml" {
+ content := string(data)
+ ver := procInst("version", content)
+ if ver != "" && ver != "1.0" {
+ d.err = fmt.Errorf("xml: unsupported version %q; only version 1.0 is supported", ver)
+ return nil, d.err
+ }
+ enc := procInst("encoding", content)
+ if enc != "" && enc != "utf-8" && enc != "UTF-8" && !strings.EqualFold(enc, "utf-8") {
+ if d.CharsetReader == nil {
+ d.err = fmt.Errorf("xml: encoding %q declared but Decoder.CharsetReader is nil", enc)
+ return nil, d.err
+ }
+ newr, err := d.CharsetReader(enc, d.r.(io.Reader))
+ if err != nil {
+ d.err = fmt.Errorf("xml: opening charset %q: %w", enc, err)
+ return nil, d.err
+ }
+ if newr == nil {
+ panic("CharsetReader returned a nil Reader for charset " + enc)
+ }
+ d.switchToReader(newr)
+ }
+ }
+ return ProcInst{target, data}, nil
+
+ case '!':
+ // <!: Maybe comment, maybe CDATA.
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ switch b {
+ case '-': // <!-
+ // Probably <!-- for a comment.
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ if b != '-' {
+ d.err = d.syntaxError("invalid sequence <!- not part of <!--")
+ return nil, d.err
+ }
+ // Look for terminator.
+ d.buf.Reset()
+ var b0, b1 byte
+ for {
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ d.buf.WriteByte(b)
+ if b0 == '-' && b1 == '-' {
+ if b != '>' {
+ d.err = d.syntaxError(
+ `invalid sequence "--" not allowed in comments`)
+ return nil, d.err
+ }
+ break
+ }
+ b0, b1 = b1, b
+ }
+ data := d.buf.Bytes()
+ data = data[0 : len(data)-3] // chop -->
+ return Comment(data), nil
+
+ case '[': // <![
+ // Probably <![CDATA[.
+ for i := 0; i < 6; i++ {
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ if b != "CDATA["[i] {
+ d.err = d.syntaxError("invalid <![ sequence")
+ return nil, d.err
+ }
+ }
+ // Have <![CDATA[. Read text until ]]>.
+ data := d.text(-1, true)
+ if data == nil {
+ return nil, d.err
+ }
+ return CharData(data), nil
+ }
+
+ // Probably a directive: <!DOCTYPE ...>, <!ENTITY ...>, etc.
+ // We don't care, but accumulate for caller. Quoted angle
+ // brackets do not count for nesting.
+ d.buf.Reset()
+ d.buf.WriteByte(b)
+ inquote := uint8(0)
+ depth := 0
+ for {
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ if inquote == 0 && b == '>' && depth == 0 {
+ break
+ }
+ HandleB:
+ d.buf.WriteByte(b)
+ switch {
+ case b == inquote:
+ inquote = 0
+
+ case inquote != 0:
+ // in quotes, no special action
+
+ case b == '\'' || b == '"':
+ inquote = b
+
+ case b == '>' && inquote == 0:
+ depth--
+
+ case b == '<' && inquote == 0:
+ // Look for <!-- to begin comment.
+ s := "!--"
+ for i := 0; i < len(s); i++ {
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ if b != s[i] {
+ for j := 0; j < i; j++ {
+ d.buf.WriteByte(s[j])
+ }
+ depth++
+ goto HandleB
+ }
+ }
+
+ // Remove < that was written above.
+ d.buf.Truncate(d.buf.Len() - 1)
+
+ // Look for terminator.
+ var b0, b1 byte
+ for {
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ if b0 == '-' && b1 == '-' && b == '>' {
+ break
+ }
+ b0, b1 = b1, b
+ }
+
+ // Replace the comment with a space in the returned Directive
+ // body, so that markup parts that were separated by the comment
+ // (like a "<" and a "!") don't get joined when re-encoding the
+ // Directive, taking new semantic meaning.
+ d.buf.WriteByte(' ')
+ }
+ }
+ return Directive(d.buf.Bytes()), nil
+ }
+
+ // Must be an open element like <a href="foo">
+ d.ungetc(b)
+
+ var (
+ name Name
+ empty bool
+ attr []Attr
+ )
+ if name, ok = d.nsname(); !ok {
+ if d.err == nil {
+ d.err = d.syntaxError("expected element name after <")
+ }
+ return nil, d.err
+ }
+
+ attr = []Attr{}
+ for {
+ d.space()
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ if b == '/' {
+ empty = true
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ if b != '>' {
+ d.err = d.syntaxError("expected /> in element")
+ return nil, d.err
+ }
+ break
+ }
+ if b == '>' {
+ break
+ }
+ d.ungetc(b)
+
+ a := Attr{}
+ if a.Name, ok = d.nsname(); !ok {
+ if d.err == nil {
+ d.err = d.syntaxError("expected attribute name in element")
+ }
+ return nil, d.err
+ }
+ d.space()
+ if b, ok = d.mustgetc(); !ok {
+ return nil, d.err
+ }
+ if b != '=' {
+ if d.Strict {
+ d.err = d.syntaxError("attribute name without = in element")
+ return nil, d.err
+ }
+ d.ungetc(b)
+ a.Value = a.Name.Local
+ } else {
+ d.space()
+ data := d.attrval()
+ if data == nil {
+ return nil, d.err
+ }
+ a.Value = string(data)
+ }
+ attr = append(attr, a)
+ }
+ if empty {
+ d.needClose = true
+ d.toClose = name
+ }
+ return StartElement{name, attr}, nil
+}
+
+func (d *Decoder) attrval() []byte {
+ b, ok := d.mustgetc()
+ if !ok {
+ return nil
+ }
+ // Handle quoted attribute values
+ if b == '"' || b == '\'' {
+ return d.text(int(b), false)
+ }
+ // Handle unquoted attribute values for strict parsers
+ if d.Strict {
+ d.err = d.syntaxError("unquoted or missing attribute value in element")
+ return nil
+ }
+ // Handle unquoted attribute values for unstrict parsers
+ d.ungetc(b)
+ d.buf.Reset()
+ for {
+ b, ok = d.mustgetc()
+ if !ok {
+ return nil
+ }
+ // https://www.w3.org/TR/REC-html40/intro/sgmltut.html#h-3.2.2
+ if 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z' ||
+ '0' <= b && b <= '9' || b == '_' || b == ':' || b == '-' {
+ d.buf.WriteByte(b)
+ } else {
+ d.ungetc(b)
+ break
+ }
+ }
+ return d.buf.Bytes()
+}
+
+// Skip spaces if any
+func (d *Decoder) space() {
+ for {
+ b, ok := d.getc()
+ if !ok {
+ return
+ }
+ switch b {
+ case ' ', '\r', '\n', '\t':
+ default:
+ d.ungetc(b)
+ return
+ }
+ }
+}
+
+// Read a single byte.
+// If there is no byte to read, return ok==false
+// and leave the error in d.err.
+// Maintain line number.
+func (d *Decoder) getc() (b byte, ok bool) {
+ if d.err != nil {
+ return 0, false
+ }
+ if d.nextByte >= 0 {
+ b = byte(d.nextByte)
+ d.nextByte = -1
+ } else {
+ b, d.err = d.r.ReadByte()
+ if d.err != nil {
+ return 0, false
+ }
+ if d.saved != nil {
+ d.saved.WriteByte(b)
+ }
+ }
+ if b == '\n' {
+ d.line++
+ d.linestart = d.offset + 1
+ }
+ d.offset++
+ return b, true
+}
+
+// InputOffset returns the input stream byte offset of the current decoder position.
+// The offset gives the location of the end of the most recently returned token
+// and the beginning of the next token.
+func (d *Decoder) InputOffset() int64 {
+ return d.offset
+}
+
+// InputPos returns the line of the current decoder position and the 1 based
+// input position of the line. The position gives the location of the end of the
+// most recently returned token.
+func (d *Decoder) InputPos() (line, column int) {
+ return d.line, int(d.offset-d.linestart) + 1
+}
+
+// Return saved offset.
+// If we did ungetc (nextByte >= 0), have to back up one.
+func (d *Decoder) savedOffset() int {
+ n := d.saved.Len()
+ if d.nextByte >= 0 {
+ n--
+ }
+ return n
+}
+
+// Must read a single byte.
+// If there is no byte to read,
+// set d.err to SyntaxError("unexpected EOF")
+// and return ok==false
+func (d *Decoder) mustgetc() (b byte, ok bool) {
+ if b, ok = d.getc(); !ok {
+ if d.err == io.EOF {
+ d.err = d.syntaxError("unexpected EOF")
+ }
+ }
+ return
+}
+
+// Unread a single byte.
+func (d *Decoder) ungetc(b byte) {
+ if b == '\n' {
+ d.line--
+ }
+ d.nextByte = int(b)
+ d.offset--
+}
+
+var entity = map[string]rune{
+ "lt": '<',
+ "gt": '>',
+ "amp": '&',
+ "apos": '\'',
+ "quot": '"',
+}
+
+// Read plain text section (XML calls it character data).
+// If quote >= 0, we are in a quoted string and need to find the matching quote.
+// If cdata == true, we are in a <![CDATA[ section and need to find ]]>.
+// On failure return nil and leave the error in d.err.
+func (d *Decoder) text(quote int, cdata bool) []byte {
+ var b0, b1 byte
+ var trunc int
+ d.buf.Reset()
+Input:
+ for {
+ b, ok := d.getc()
+ if !ok {
+ if cdata {
+ if d.err == io.EOF {
+ d.err = d.syntaxError("unexpected EOF in CDATA section")
+ }
+ return nil
+ }
+ break Input
+ }
+
+ // <![CDATA[ section ends with ]]>.
+ // It is an error for ]]> to appear in ordinary text.
+ if b0 == ']' && b1 == ']' && b == '>' {
+ if cdata {
+ trunc = 2
+ break Input
+ }
+ d.err = d.syntaxError("unescaped ]]> not in CDATA section")
+ return nil
+ }
+
+ // Stop reading text if we see a <.
+ if b == '<' && !cdata {
+ if quote >= 0 {
+ d.err = d.syntaxError("unescaped < inside quoted string")
+ return nil
+ }
+ d.ungetc('<')
+ break Input
+ }
+ if quote >= 0 && b == byte(quote) {
+ break Input
+ }
+ if b == '&' && !cdata {
+ // Read escaped character expression up to semicolon.
+ // XML in all its glory allows a document to define and use
+ // its own character names with <!ENTITY ...> directives.
+ // Parsers are required to recognize lt, gt, amp, apos, and quot
+ // even if they have not been declared.
+ before := d.buf.Len()
+ d.buf.WriteByte('&')
+ var ok bool
+ var text string
+ var haveText bool
+ if b, ok = d.mustgetc(); !ok {
+ return nil
+ }
+ if b == '#' {
+ d.buf.WriteByte(b)
+ if b, ok = d.mustgetc(); !ok {
+ return nil
+ }
+ base := 10
+ if b == 'x' {
+ base = 16
+ d.buf.WriteByte(b)
+ if b, ok = d.mustgetc(); !ok {
+ return nil
+ }
+ }
+ start := d.buf.Len()
+ for '0' <= b && b <= '9' ||
+ base == 16 && 'a' <= b && b <= 'f' ||
+ base == 16 && 'A' <= b && b <= 'F' {
+ d.buf.WriteByte(b)
+ if b, ok = d.mustgetc(); !ok {
+ return nil
+ }
+ }
+ if b != ';' {
+ d.ungetc(b)
+ } else {
+ s := string(d.buf.Bytes()[start:])
+ d.buf.WriteByte(';')
+ n, err := strconv.ParseUint(s, base, 64)
+ if err == nil && n <= unicode.MaxRune {
+ text = string(rune(n))
+ haveText = true
+ }
+ }
+ } else {
+ d.ungetc(b)
+ if !d.readName() {
+ if d.err != nil {
+ return nil
+ }
+ }
+ if b, ok = d.mustgetc(); !ok {
+ return nil
+ }
+ if b != ';' {
+ d.ungetc(b)
+ } else {
+ name := d.buf.Bytes()[before+1:]
+ d.buf.WriteByte(';')
+ if isName(name) {
+ s := string(name)
+ if r, ok := entity[s]; ok {
+ text = string(r)
+ haveText = true
+ } else if d.Entity != nil {
+ text, haveText = d.Entity[s]
+ }
+ }
+ }
+ }
+
+ if haveText {
+ d.buf.Truncate(before)
+ d.buf.WriteString(text)
+ b0, b1 = 0, 0
+ continue Input
+ }
+ if !d.Strict {
+ b0, b1 = 0, 0
+ continue Input
+ }
+ ent := string(d.buf.Bytes()[before:])
+ if ent[len(ent)-1] != ';' {
+ ent += " (no semicolon)"
+ }
+ d.err = d.syntaxError("invalid character entity " + ent)
+ return nil
+ }
+
+ // We must rewrite unescaped \r and \r\n into \n.
+ if b == '\r' {
+ d.buf.WriteByte('\n')
+ } else if b1 == '\r' && b == '\n' {
+ // Skip \r\n--we already wrote \n.
+ } else {
+ d.buf.WriteByte(b)
+ }
+
+ b0, b1 = b1, b
+ }
+ data := d.buf.Bytes()
+ data = data[0 : len(data)-trunc]
+
+ // Inspect each rune for being a disallowed character.
+ buf := data
+ for len(buf) > 0 {
+ r, size := utf8.DecodeRune(buf)
+ if r == utf8.RuneError && size == 1 {
+ d.err = d.syntaxError("invalid UTF-8")
+ return nil
+ }
+ buf = buf[size:]
+ if !isInCharacterRange(r) {
+ d.err = d.syntaxError(fmt.Sprintf("illegal character code %U", r))
+ return nil
+ }
+ }
+
+ return data
+}
+
+// Decide whether the given rune is in the XML Character Range, per
+// the Char production of https://www.xml.com/axml/testaxml.htm,
+// Section 2.2 Characters.
+func isInCharacterRange(r rune) (inrange bool) {
+ return r == 0x09 ||
+ r == 0x0A ||
+ r == 0x0D ||
+ r >= 0x20 && r <= 0xD7FF ||
+ r >= 0xE000 && r <= 0xFFFD ||
+ r >= 0x10000 && r <= 0x10FFFF
+}
+
+// Get name space name: name with a : stuck in the middle.
+// The part before the : is the name space identifier.
+func (d *Decoder) nsname() (name Name, ok bool) {
+ s, ok := d.name()
+ if !ok {
+ return
+ }
+ if strings.Count(s, ":") > 1 {
+ return name, false
+ } else if space, local, ok := strings.Cut(s, ":"); !ok || space == "" || local == "" {
+ name.Local = s
+ } else {
+ name.Space = space
+ name.Local = local
+ }
+ return name, true
+}
+
+// Get name: /first(first|second)*/
+// Do not set d.err if the name is missing (unless unexpected EOF is received):
+// let the caller provide better context.
+func (d *Decoder) name() (s string, ok bool) {
+ d.buf.Reset()
+ if !d.readName() {
+ return "", false
+ }
+
+ // Now we check the characters.
+ b := d.buf.Bytes()
+ if !isName(b) {
+ d.err = d.syntaxError("invalid XML name: " + string(b))
+ return "", false
+ }
+ return string(b), true
+}
+
+// Read a name and append its bytes to d.buf.
+// The name is delimited by any single-byte character not valid in names.
+// All multi-byte characters are accepted; the caller must check their validity.
+func (d *Decoder) readName() (ok bool) {
+ var b byte
+ if b, ok = d.mustgetc(); !ok {
+ return
+ }
+ if b < utf8.RuneSelf && !isNameByte(b) {
+ d.ungetc(b)
+ return false
+ }
+ d.buf.WriteByte(b)
+
+ for {
+ if b, ok = d.mustgetc(); !ok {
+ return
+ }
+ if b < utf8.RuneSelf && !isNameByte(b) {
+ d.ungetc(b)
+ break
+ }
+ d.buf.WriteByte(b)
+ }
+ return true
+}
+
+func isNameByte(c byte) bool {
+ return 'A' <= c && c <= 'Z' ||
+ 'a' <= c && c <= 'z' ||
+ '0' <= c && c <= '9' ||
+ c == '_' || c == ':' || c == '.' || c == '-'
+}
+
+func isName(s []byte) bool {
+ if len(s) == 0 {
+ return false
+ }
+ c, n := utf8.DecodeRune(s)
+ if c == utf8.RuneError && n == 1 {
+ return false
+ }
+ if !unicode.Is(first, c) {
+ return false
+ }
+ for n < len(s) {
+ s = s[n:]
+ c, n = utf8.DecodeRune(s)
+ if c == utf8.RuneError && n == 1 {
+ return false
+ }
+ if !unicode.Is(first, c) && !unicode.Is(second, c) {
+ return false
+ }
+ }
+ return true
+}
+
+func isNameString(s string) bool {
+ if len(s) == 0 {
+ return false
+ }
+ c, n := utf8.DecodeRuneInString(s)
+ if c == utf8.RuneError && n == 1 {
+ return false
+ }
+ if !unicode.Is(first, c) {
+ return false
+ }
+ for n < len(s) {
+ s = s[n:]
+ c, n = utf8.DecodeRuneInString(s)
+ if c == utf8.RuneError && n == 1 {
+ return false
+ }
+ if !unicode.Is(first, c) && !unicode.Is(second, c) {
+ return false
+ }
+ }
+ return true
+}
+
+// These tables were generated by cut and paste from Appendix B of
+// the XML spec at https://www.xml.com/axml/testaxml.htm
+// and then reformatting. First corresponds to (Letter | '_' | ':')
+// and second corresponds to NameChar.
+
+var first = &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {0x003A, 0x003A, 1},
+ {0x0041, 0x005A, 1},
+ {0x005F, 0x005F, 1},
+ {0x0061, 0x007A, 1},
+ {0x00C0, 0x00D6, 1},
+ {0x00D8, 0x00F6, 1},
+ {0x00F8, 0x00FF, 1},
+ {0x0100, 0x0131, 1},
+ {0x0134, 0x013E, 1},
+ {0x0141, 0x0148, 1},
+ {0x014A, 0x017E, 1},
+ {0x0180, 0x01C3, 1},
+ {0x01CD, 0x01F0, 1},
+ {0x01F4, 0x01F5, 1},
+ {0x01FA, 0x0217, 1},
+ {0x0250, 0x02A8, 1},
+ {0x02BB, 0x02C1, 1},
+ {0x0386, 0x0386, 1},
+ {0x0388, 0x038A, 1},
+ {0x038C, 0x038C, 1},
+ {0x038E, 0x03A1, 1},
+ {0x03A3, 0x03CE, 1},
+ {0x03D0, 0x03D6, 1},
+ {0x03DA, 0x03E0, 2},
+ {0x03E2, 0x03F3, 1},
+ {0x0401, 0x040C, 1},
+ {0x040E, 0x044F, 1},
+ {0x0451, 0x045C, 1},
+ {0x045E, 0x0481, 1},
+ {0x0490, 0x04C4, 1},
+ {0x04C7, 0x04C8, 1},
+ {0x04CB, 0x04CC, 1},
+ {0x04D0, 0x04EB, 1},
+ {0x04EE, 0x04F5, 1},
+ {0x04F8, 0x04F9, 1},
+ {0x0531, 0x0556, 1},
+ {0x0559, 0x0559, 1},
+ {0x0561, 0x0586, 1},
+ {0x05D0, 0x05EA, 1},
+ {0x05F0, 0x05F2, 1},
+ {0x0621, 0x063A, 1},
+ {0x0641, 0x064A, 1},
+ {0x0671, 0x06B7, 1},
+ {0x06BA, 0x06BE, 1},
+ {0x06C0, 0x06CE, 1},
+ {0x06D0, 0x06D3, 1},
+ {0x06D5, 0x06D5, 1},
+ {0x06E5, 0x06E6, 1},
+ {0x0905, 0x0939, 1},
+ {0x093D, 0x093D, 1},
+ {0x0958, 0x0961, 1},
+ {0x0985, 0x098C, 1},
+ {0x098F, 0x0990, 1},
+ {0x0993, 0x09A8, 1},
+ {0x09AA, 0x09B0, 1},
+ {0x09B2, 0x09B2, 1},
+ {0x09B6, 0x09B9, 1},
+ {0x09DC, 0x09DD, 1},
+ {0x09DF, 0x09E1, 1},
+ {0x09F0, 0x09F1, 1},
+ {0x0A05, 0x0A0A, 1},
+ {0x0A0F, 0x0A10, 1},
+ {0x0A13, 0x0A28, 1},
+ {0x0A2A, 0x0A30, 1},
+ {0x0A32, 0x0A33, 1},
+ {0x0A35, 0x0A36, 1},
+ {0x0A38, 0x0A39, 1},
+ {0x0A59, 0x0A5C, 1},
+ {0x0A5E, 0x0A5E, 1},
+ {0x0A72, 0x0A74, 1},
+ {0x0A85, 0x0A8B, 1},
+ {0x0A8D, 0x0A8D, 1},
+ {0x0A8F, 0x0A91, 1},
+ {0x0A93, 0x0AA8, 1},
+ {0x0AAA, 0x0AB0, 1},
+ {0x0AB2, 0x0AB3, 1},
+ {0x0AB5, 0x0AB9, 1},
+ {0x0ABD, 0x0AE0, 0x23},
+ {0x0B05, 0x0B0C, 1},
+ {0x0B0F, 0x0B10, 1},
+ {0x0B13, 0x0B28, 1},
+ {0x0B2A, 0x0B30, 1},
+ {0x0B32, 0x0B33, 1},
+ {0x0B36, 0x0B39, 1},
+ {0x0B3D, 0x0B3D, 1},
+ {0x0B5C, 0x0B5D, 1},
+ {0x0B5F, 0x0B61, 1},
+ {0x0B85, 0x0B8A, 1},
+ {0x0B8E, 0x0B90, 1},
+ {0x0B92, 0x0B95, 1},
+ {0x0B99, 0x0B9A, 1},
+ {0x0B9C, 0x0B9C, 1},
+ {0x0B9E, 0x0B9F, 1},
+ {0x0BA3, 0x0BA4, 1},
+ {0x0BA8, 0x0BAA, 1},
+ {0x0BAE, 0x0BB5, 1},
+ {0x0BB7, 0x0BB9, 1},
+ {0x0C05, 0x0C0C, 1},
+ {0x0C0E, 0x0C10, 1},
+ {0x0C12, 0x0C28, 1},
+ {0x0C2A, 0x0C33, 1},
+ {0x0C35, 0x0C39, 1},
+ {0x0C60, 0x0C61, 1},
+ {0x0C85, 0x0C8C, 1},
+ {0x0C8E, 0x0C90, 1},
+ {0x0C92, 0x0CA8, 1},
+ {0x0CAA, 0x0CB3, 1},
+ {0x0CB5, 0x0CB9, 1},
+ {0x0CDE, 0x0CDE, 1},
+ {0x0CE0, 0x0CE1, 1},
+ {0x0D05, 0x0D0C, 1},
+ {0x0D0E, 0x0D10, 1},
+ {0x0D12, 0x0D28, 1},
+ {0x0D2A, 0x0D39, 1},
+ {0x0D60, 0x0D61, 1},
+ {0x0E01, 0x0E2E, 1},
+ {0x0E30, 0x0E30, 1},
+ {0x0E32, 0x0E33, 1},
+ {0x0E40, 0x0E45, 1},
+ {0x0E81, 0x0E82, 1},
+ {0x0E84, 0x0E84, 1},
+ {0x0E87, 0x0E88, 1},
+ {0x0E8A, 0x0E8D, 3},
+ {0x0E94, 0x0E97, 1},
+ {0x0E99, 0x0E9F, 1},
+ {0x0EA1, 0x0EA3, 1},
+ {0x0EA5, 0x0EA7, 2},
+ {0x0EAA, 0x0EAB, 1},
+ {0x0EAD, 0x0EAE, 1},
+ {0x0EB0, 0x0EB0, 1},
+ {0x0EB2, 0x0EB3, 1},
+ {0x0EBD, 0x0EBD, 1},
+ {0x0EC0, 0x0EC4, 1},
+ {0x0F40, 0x0F47, 1},
+ {0x0F49, 0x0F69, 1},
+ {0x10A0, 0x10C5, 1},
+ {0x10D0, 0x10F6, 1},
+ {0x1100, 0x1100, 1},
+ {0x1102, 0x1103, 1},
+ {0x1105, 0x1107, 1},
+ {0x1109, 0x1109, 1},
+ {0x110B, 0x110C, 1},
+ {0x110E, 0x1112, 1},
+ {0x113C, 0x1140, 2},
+ {0x114C, 0x1150, 2},
+ {0x1154, 0x1155, 1},
+ {0x1159, 0x1159, 1},
+ {0x115F, 0x1161, 1},
+ {0x1163, 0x1169, 2},
+ {0x116D, 0x116E, 1},
+ {0x1172, 0x1173, 1},
+ {0x1175, 0x119E, 0x119E - 0x1175},
+ {0x11A8, 0x11AB, 0x11AB - 0x11A8},
+ {0x11AE, 0x11AF, 1},
+ {0x11B7, 0x11B8, 1},
+ {0x11BA, 0x11BA, 1},
+ {0x11BC, 0x11C2, 1},
+ {0x11EB, 0x11F0, 0x11F0 - 0x11EB},
+ {0x11F9, 0x11F9, 1},
+ {0x1E00, 0x1E9B, 1},
+ {0x1EA0, 0x1EF9, 1},
+ {0x1F00, 0x1F15, 1},
+ {0x1F18, 0x1F1D, 1},
+ {0x1F20, 0x1F45, 1},
+ {0x1F48, 0x1F4D, 1},
+ {0x1F50, 0x1F57, 1},
+ {0x1F59, 0x1F5B, 0x1F5B - 0x1F59},
+ {0x1F5D, 0x1F5D, 1},
+ {0x1F5F, 0x1F7D, 1},
+ {0x1F80, 0x1FB4, 1},
+ {0x1FB6, 0x1FBC, 1},
+ {0x1FBE, 0x1FBE, 1},
+ {0x1FC2, 0x1FC4, 1},
+ {0x1FC6, 0x1FCC, 1},
+ {0x1FD0, 0x1FD3, 1},
+ {0x1FD6, 0x1FDB, 1},
+ {0x1FE0, 0x1FEC, 1},
+ {0x1FF2, 0x1FF4, 1},
+ {0x1FF6, 0x1FFC, 1},
+ {0x2126, 0x2126, 1},
+ {0x212A, 0x212B, 1},
+ {0x212E, 0x212E, 1},
+ {0x2180, 0x2182, 1},
+ {0x3007, 0x3007, 1},
+ {0x3021, 0x3029, 1},
+ {0x3041, 0x3094, 1},
+ {0x30A1, 0x30FA, 1},
+ {0x3105, 0x312C, 1},
+ {0x4E00, 0x9FA5, 1},
+ {0xAC00, 0xD7A3, 1},
+ },
+}
+
+var second = &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {0x002D, 0x002E, 1},
+ {0x0030, 0x0039, 1},
+ {0x00B7, 0x00B7, 1},
+ {0x02D0, 0x02D1, 1},
+ {0x0300, 0x0345, 1},
+ {0x0360, 0x0361, 1},
+ {0x0387, 0x0387, 1},
+ {0x0483, 0x0486, 1},
+ {0x0591, 0x05A1, 1},
+ {0x05A3, 0x05B9, 1},
+ {0x05BB, 0x05BD, 1},
+ {0x05BF, 0x05BF, 1},
+ {0x05C1, 0x05C2, 1},
+ {0x05C4, 0x0640, 0x0640 - 0x05C4},
+ {0x064B, 0x0652, 1},
+ {0x0660, 0x0669, 1},
+ {0x0670, 0x0670, 1},
+ {0x06D6, 0x06DC, 1},
+ {0x06DD, 0x06DF, 1},
+ {0x06E0, 0x06E4, 1},
+ {0x06E7, 0x06E8, 1},
+ {0x06EA, 0x06ED, 1},
+ {0x06F0, 0x06F9, 1},
+ {0x0901, 0x0903, 1},
+ {0x093C, 0x093C, 1},
+ {0x093E, 0x094C, 1},
+ {0x094D, 0x094D, 1},
+ {0x0951, 0x0954, 1},
+ {0x0962, 0x0963, 1},
+ {0x0966, 0x096F, 1},
+ {0x0981, 0x0983, 1},
+ {0x09BC, 0x09BC, 1},
+ {0x09BE, 0x09BF, 1},
+ {0x09C0, 0x09C4, 1},
+ {0x09C7, 0x09C8, 1},
+ {0x09CB, 0x09CD, 1},
+ {0x09D7, 0x09D7, 1},
+ {0x09E2, 0x09E3, 1},
+ {0x09E6, 0x09EF, 1},
+ {0x0A02, 0x0A3C, 0x3A},
+ {0x0A3E, 0x0A3F, 1},
+ {0x0A40, 0x0A42, 1},
+ {0x0A47, 0x0A48, 1},
+ {0x0A4B, 0x0A4D, 1},
+ {0x0A66, 0x0A6F, 1},
+ {0x0A70, 0x0A71, 1},
+ {0x0A81, 0x0A83, 1},
+ {0x0ABC, 0x0ABC, 1},
+ {0x0ABE, 0x0AC5, 1},
+ {0x0AC7, 0x0AC9, 1},
+ {0x0ACB, 0x0ACD, 1},
+ {0x0AE6, 0x0AEF, 1},
+ {0x0B01, 0x0B03, 1},
+ {0x0B3C, 0x0B3C, 1},
+ {0x0B3E, 0x0B43, 1},
+ {0x0B47, 0x0B48, 1},
+ {0x0B4B, 0x0B4D, 1},
+ {0x0B56, 0x0B57, 1},
+ {0x0B66, 0x0B6F, 1},
+ {0x0B82, 0x0B83, 1},
+ {0x0BBE, 0x0BC2, 1},
+ {0x0BC6, 0x0BC8, 1},
+ {0x0BCA, 0x0BCD, 1},
+ {0x0BD7, 0x0BD7, 1},
+ {0x0BE7, 0x0BEF, 1},
+ {0x0C01, 0x0C03, 1},
+ {0x0C3E, 0x0C44, 1},
+ {0x0C46, 0x0C48, 1},
+ {0x0C4A, 0x0C4D, 1},
+ {0x0C55, 0x0C56, 1},
+ {0x0C66, 0x0C6F, 1},
+ {0x0C82, 0x0C83, 1},
+ {0x0CBE, 0x0CC4, 1},
+ {0x0CC6, 0x0CC8, 1},
+ {0x0CCA, 0x0CCD, 1},
+ {0x0CD5, 0x0CD6, 1},
+ {0x0CE6, 0x0CEF, 1},
+ {0x0D02, 0x0D03, 1},
+ {0x0D3E, 0x0D43, 1},
+ {0x0D46, 0x0D48, 1},
+ {0x0D4A, 0x0D4D, 1},
+ {0x0D57, 0x0D57, 1},
+ {0x0D66, 0x0D6F, 1},
+ {0x0E31, 0x0E31, 1},
+ {0x0E34, 0x0E3A, 1},
+ {0x0E46, 0x0E46, 1},
+ {0x0E47, 0x0E4E, 1},
+ {0x0E50, 0x0E59, 1},
+ {0x0EB1, 0x0EB1, 1},
+ {0x0EB4, 0x0EB9, 1},
+ {0x0EBB, 0x0EBC, 1},
+ {0x0EC6, 0x0EC6, 1},
+ {0x0EC8, 0x0ECD, 1},
+ {0x0ED0, 0x0ED9, 1},
+ {0x0F18, 0x0F19, 1},
+ {0x0F20, 0x0F29, 1},
+ {0x0F35, 0x0F39, 2},
+ {0x0F3E, 0x0F3F, 1},
+ {0x0F71, 0x0F84, 1},
+ {0x0F86, 0x0F8B, 1},
+ {0x0F90, 0x0F95, 1},
+ {0x0F97, 0x0F97, 1},
+ {0x0F99, 0x0FAD, 1},
+ {0x0FB1, 0x0FB7, 1},
+ {0x0FB9, 0x0FB9, 1},
+ {0x20D0, 0x20DC, 1},
+ {0x20E1, 0x3005, 0x3005 - 0x20E1},
+ {0x302A, 0x302F, 1},
+ {0x3031, 0x3035, 1},
+ {0x3099, 0x309A, 1},
+ {0x309D, 0x309E, 1},
+ {0x30FC, 0x30FE, 1},
+ },
+}
+
+// HTMLEntity is an entity map containing translations for the
+// standard HTML entity characters.
+//
+// See the Decoder.Strict and Decoder.Entity fields' documentation.
+var HTMLEntity map[string]string = htmlEntity
+
+var htmlEntity = map[string]string{
+ /*
+ hget http://www.w3.org/TR/html4/sgml/entities.html |
+ ssam '
+ ,y /\&gt;/ x/\&lt;(.|\n)+/ s/\n/ /g
+ ,x v/^\&lt;!ENTITY/d
+ ,s/\&lt;!ENTITY ([^ ]+) .*U\+([0-9A-F][0-9A-F][0-9A-F][0-9A-F]) .+/ "\1": "\\u\2",/g
+ '
+ */
+ "nbsp": "\u00A0",
+ "iexcl": "\u00A1",
+ "cent": "\u00A2",
+ "pound": "\u00A3",
+ "curren": "\u00A4",
+ "yen": "\u00A5",
+ "brvbar": "\u00A6",
+ "sect": "\u00A7",
+ "uml": "\u00A8",
+ "copy": "\u00A9",
+ "ordf": "\u00AA",
+ "laquo": "\u00AB",
+ "not": "\u00AC",
+ "shy": "\u00AD",
+ "reg": "\u00AE",
+ "macr": "\u00AF",
+ "deg": "\u00B0",
+ "plusmn": "\u00B1",
+ "sup2": "\u00B2",
+ "sup3": "\u00B3",
+ "acute": "\u00B4",
+ "micro": "\u00B5",
+ "para": "\u00B6",
+ "middot": "\u00B7",
+ "cedil": "\u00B8",
+ "sup1": "\u00B9",
+ "ordm": "\u00BA",
+ "raquo": "\u00BB",
+ "frac14": "\u00BC",
+ "frac12": "\u00BD",
+ "frac34": "\u00BE",
+ "iquest": "\u00BF",
+ "Agrave": "\u00C0",
+ "Aacute": "\u00C1",
+ "Acirc": "\u00C2",
+ "Atilde": "\u00C3",
+ "Auml": "\u00C4",
+ "Aring": "\u00C5",
+ "AElig": "\u00C6",
+ "Ccedil": "\u00C7",
+ "Egrave": "\u00C8",
+ "Eacute": "\u00C9",
+ "Ecirc": "\u00CA",
+ "Euml": "\u00CB",
+ "Igrave": "\u00CC",
+ "Iacute": "\u00CD",
+ "Icirc": "\u00CE",
+ "Iuml": "\u00CF",
+ "ETH": "\u00D0",
+ "Ntilde": "\u00D1",
+ "Ograve": "\u00D2",
+ "Oacute": "\u00D3",
+ "Ocirc": "\u00D4",
+ "Otilde": "\u00D5",
+ "Ouml": "\u00D6",
+ "times": "\u00D7",
+ "Oslash": "\u00D8",
+ "Ugrave": "\u00D9",
+ "Uacute": "\u00DA",
+ "Ucirc": "\u00DB",
+ "Uuml": "\u00DC",
+ "Yacute": "\u00DD",
+ "THORN": "\u00DE",
+ "szlig": "\u00DF",
+ "agrave": "\u00E0",
+ "aacute": "\u00E1",
+ "acirc": "\u00E2",
+ "atilde": "\u00E3",
+ "auml": "\u00E4",
+ "aring": "\u00E5",
+ "aelig": "\u00E6",
+ "ccedil": "\u00E7",
+ "egrave": "\u00E8",
+ "eacute": "\u00E9",
+ "ecirc": "\u00EA",
+ "euml": "\u00EB",
+ "igrave": "\u00EC",
+ "iacute": "\u00ED",
+ "icirc": "\u00EE",
+ "iuml": "\u00EF",
+ "eth": "\u00F0",
+ "ntilde": "\u00F1",
+ "ograve": "\u00F2",
+ "oacute": "\u00F3",
+ "ocirc": "\u00F4",
+ "otilde": "\u00F5",
+ "ouml": "\u00F6",
+ "divide": "\u00F7",
+ "oslash": "\u00F8",
+ "ugrave": "\u00F9",
+ "uacute": "\u00FA",
+ "ucirc": "\u00FB",
+ "uuml": "\u00FC",
+ "yacute": "\u00FD",
+ "thorn": "\u00FE",
+ "yuml": "\u00FF",
+ "fnof": "\u0192",
+ "Alpha": "\u0391",
+ "Beta": "\u0392",
+ "Gamma": "\u0393",
+ "Delta": "\u0394",
+ "Epsilon": "\u0395",
+ "Zeta": "\u0396",
+ "Eta": "\u0397",
+ "Theta": "\u0398",
+ "Iota": "\u0399",
+ "Kappa": "\u039A",
+ "Lambda": "\u039B",
+ "Mu": "\u039C",
+ "Nu": "\u039D",
+ "Xi": "\u039E",
+ "Omicron": "\u039F",
+ "Pi": "\u03A0",
+ "Rho": "\u03A1",
+ "Sigma": "\u03A3",
+ "Tau": "\u03A4",
+ "Upsilon": "\u03A5",
+ "Phi": "\u03A6",
+ "Chi": "\u03A7",
+ "Psi": "\u03A8",
+ "Omega": "\u03A9",
+ "alpha": "\u03B1",
+ "beta": "\u03B2",
+ "gamma": "\u03B3",
+ "delta": "\u03B4",
+ "epsilon": "\u03B5",
+ "zeta": "\u03B6",
+ "eta": "\u03B7",
+ "theta": "\u03B8",
+ "iota": "\u03B9",
+ "kappa": "\u03BA",
+ "lambda": "\u03BB",
+ "mu": "\u03BC",
+ "nu": "\u03BD",
+ "xi": "\u03BE",
+ "omicron": "\u03BF",
+ "pi": "\u03C0",
+ "rho": "\u03C1",
+ "sigmaf": "\u03C2",
+ "sigma": "\u03C3",
+ "tau": "\u03C4",
+ "upsilon": "\u03C5",
+ "phi": "\u03C6",
+ "chi": "\u03C7",
+ "psi": "\u03C8",
+ "omega": "\u03C9",
+ "thetasym": "\u03D1",
+ "upsih": "\u03D2",
+ "piv": "\u03D6",
+ "bull": "\u2022",
+ "hellip": "\u2026",
+ "prime": "\u2032",
+ "Prime": "\u2033",
+ "oline": "\u203E",
+ "frasl": "\u2044",
+ "weierp": "\u2118",
+ "image": "\u2111",
+ "real": "\u211C",
+ "trade": "\u2122",
+ "alefsym": "\u2135",
+ "larr": "\u2190",
+ "uarr": "\u2191",
+ "rarr": "\u2192",
+ "darr": "\u2193",
+ "harr": "\u2194",
+ "crarr": "\u21B5",
+ "lArr": "\u21D0",
+ "uArr": "\u21D1",
+ "rArr": "\u21D2",
+ "dArr": "\u21D3",
+ "hArr": "\u21D4",
+ "forall": "\u2200",
+ "part": "\u2202",
+ "exist": "\u2203",
+ "empty": "\u2205",
+ "nabla": "\u2207",
+ "isin": "\u2208",
+ "notin": "\u2209",
+ "ni": "\u220B",
+ "prod": "\u220F",
+ "sum": "\u2211",
+ "minus": "\u2212",
+ "lowast": "\u2217",
+ "radic": "\u221A",
+ "prop": "\u221D",
+ "infin": "\u221E",
+ "ang": "\u2220",
+ "and": "\u2227",
+ "or": "\u2228",
+ "cap": "\u2229",
+ "cup": "\u222A",
+ "int": "\u222B",
+ "there4": "\u2234",
+ "sim": "\u223C",
+ "cong": "\u2245",
+ "asymp": "\u2248",
+ "ne": "\u2260",
+ "equiv": "\u2261",
+ "le": "\u2264",
+ "ge": "\u2265",
+ "sub": "\u2282",
+ "sup": "\u2283",
+ "nsub": "\u2284",
+ "sube": "\u2286",
+ "supe": "\u2287",
+ "oplus": "\u2295",
+ "otimes": "\u2297",
+ "perp": "\u22A5",
+ "sdot": "\u22C5",
+ "lceil": "\u2308",
+ "rceil": "\u2309",
+ "lfloor": "\u230A",
+ "rfloor": "\u230B",
+ "lang": "\u2329",
+ "rang": "\u232A",
+ "loz": "\u25CA",
+ "spades": "\u2660",
+ "clubs": "\u2663",
+ "hearts": "\u2665",
+ "diams": "\u2666",
+ "quot": "\u0022",
+ "amp": "\u0026",
+ "lt": "\u003C",
+ "gt": "\u003E",
+ "OElig": "\u0152",
+ "oelig": "\u0153",
+ "Scaron": "\u0160",
+ "scaron": "\u0161",
+ "Yuml": "\u0178",
+ "circ": "\u02C6",
+ "tilde": "\u02DC",
+ "ensp": "\u2002",
+ "emsp": "\u2003",
+ "thinsp": "\u2009",
+ "zwnj": "\u200C",
+ "zwj": "\u200D",
+ "lrm": "\u200E",
+ "rlm": "\u200F",
+ "ndash": "\u2013",
+ "mdash": "\u2014",
+ "lsquo": "\u2018",
+ "rsquo": "\u2019",
+ "sbquo": "\u201A",
+ "ldquo": "\u201C",
+ "rdquo": "\u201D",
+ "bdquo": "\u201E",
+ "dagger": "\u2020",
+ "Dagger": "\u2021",
+ "permil": "\u2030",
+ "lsaquo": "\u2039",
+ "rsaquo": "\u203A",
+ "euro": "\u20AC",
+}
+
+// HTMLAutoClose is the set of HTML elements that
+// should be considered to close automatically.
+//
+// See the Decoder.Strict and Decoder.Entity fields' documentation.
+var HTMLAutoClose []string = htmlAutoClose
+
+var htmlAutoClose = []string{
+ /*
+ hget http://www.w3.org/TR/html4/loose.dtd |
+ 9 sed -n 's/<!ELEMENT ([^ ]*) +- O EMPTY.+/ "\1",/p' | tr A-Z a-z
+ */
+ "basefont",
+ "br",
+ "area",
+ "link",
+ "img",
+ "param",
+ "hr",
+ "input",
+ "col",
+ "frame",
+ "isindex",
+ "base",
+ "meta",
+}
+
+var (
+ escQuot = []byte("&#34;") // shorter than "&quot;"
+ escApos = []byte("&#39;") // shorter than "&apos;"
+ escAmp = []byte("&amp;")
+ escLT = []byte("&lt;")
+ escGT = []byte("&gt;")
+ escTab = []byte("&#x9;")
+ escNL = []byte("&#xA;")
+ escCR = []byte("&#xD;")
+ escFFFD = []byte("\uFFFD") // Unicode replacement character
+)
+
+// EscapeText writes to w the properly escaped XML equivalent
+// of the plain text data s.
+func EscapeText(w io.Writer, s []byte) error {
+ return escapeText(w, s, true)
+}
+
+// escapeText writes to w the properly escaped XML equivalent
+// of the plain text data s. If escapeNewline is true, newline
+// characters will be escaped.
+func escapeText(w io.Writer, s []byte, escapeNewline bool) error {
+ var esc []byte
+ last := 0
+ for i := 0; i < len(s); {
+ r, width := utf8.DecodeRune(s[i:])
+ i += width
+ switch r {
+ case '"':
+ esc = escQuot
+ case '\'':
+ esc = escApos
+ case '&':
+ esc = escAmp
+ case '<':
+ esc = escLT
+ case '>':
+ esc = escGT
+ case '\t':
+ esc = escTab
+ case '\n':
+ if !escapeNewline {
+ continue
+ }
+ esc = escNL
+ case '\r':
+ esc = escCR
+ default:
+ if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
+ esc = escFFFD
+ break
+ }
+ continue
+ }
+ if _, err := w.Write(s[last : i-width]); err != nil {
+ return err
+ }
+ if _, err := w.Write(esc); err != nil {
+ return err
+ }
+ last = i
+ }
+ _, err := w.Write(s[last:])
+ return err
+}
+
+// EscapeString writes to p the properly escaped XML equivalent
+// of the plain text data s.
+func (p *printer) EscapeString(s string) {
+ var esc []byte
+ last := 0
+ for i := 0; i < len(s); {
+ r, width := utf8.DecodeRuneInString(s[i:])
+ i += width
+ switch r {
+ case '"':
+ esc = escQuot
+ case '\'':
+ esc = escApos
+ case '&':
+ esc = escAmp
+ case '<':
+ esc = escLT
+ case '>':
+ esc = escGT
+ case '\t':
+ esc = escTab
+ case '\n':
+ esc = escNL
+ case '\r':
+ esc = escCR
+ default:
+ if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
+ esc = escFFFD
+ break
+ }
+ continue
+ }
+ p.WriteString(s[last : i-width])
+ p.Write(esc)
+ last = i
+ }
+ p.WriteString(s[last:])
+}
+
+// Escape is like EscapeText but omits the error return value.
+// It is provided for backwards compatibility with Go 1.0.
+// Code targeting Go 1.1 or later should use EscapeText.
+func Escape(w io.Writer, s []byte) {
+ EscapeText(w, s)
+}
+
+var (
+ cdataStart = []byte("<![CDATA[")
+ cdataEnd = []byte("]]>")
+ cdataEscape = []byte("]]]]><![CDATA[>")
+)
+
+// emitCDATA writes to w the CDATA-wrapped plain text data s.
+// It escapes CDATA directives nested in s.
+func emitCDATA(w io.Writer, s []byte) error {
+ if len(s) == 0 {
+ return nil
+ }
+ if _, err := w.Write(cdataStart); err != nil {
+ return err
+ }
+
+ for {
+ before, after, ok := bytes.Cut(s, cdataEnd)
+ if !ok {
+ break
+ }
+ // Found a nested CDATA directive end.
+ if _, err := w.Write(before); err != nil {
+ return err
+ }
+ if _, err := w.Write(cdataEscape); err != nil {
+ return err
+ }
+ s = after
+ }
+
+ if _, err := w.Write(s); err != nil {
+ return err
+ }
+
+ _, err := w.Write(cdataEnd)
+ return err
+}
+
+// procInst parses the `param="..."` or `param='...'`
+// value out of the provided string, returning "" if not found.
+func procInst(param, s string) string {
+ // TODO: this parsing is somewhat lame and not exact.
+ // It works for all actual cases, though.
+ param = param + "="
+ _, v, _ := strings.Cut(s, param)
+ if v == "" {
+ return ""
+ }
+ if v[0] != '\'' && v[0] != '"' {
+ return ""
+ }
+ unquote, _, ok := strings.Cut(v[1:], v[:1])
+ if !ok {
+ return ""
+ }
+ return unquote
+}
diff --git a/contrib/go/_std_1.21/src/encoding/xml/ya.make b/contrib/go/_std_1.21/src/encoding/xml/ya.make
new file mode 100644
index 0000000000..332fa04160
--- /dev/null
+++ b/contrib/go/_std_1.21/src/encoding/xml/ya.make
@@ -0,0 +1,26 @@
+GO_LIBRARY()
+
+SRCS(
+ marshal.go
+ read.go
+ typeinfo.go
+ xml.go
+)
+
+GO_TEST_SRCS(
+ atom_test.go
+ marshal_test.go
+ read_test.go
+ xml_test.go
+)
+
+GO_XTEST_SRCS(
+ example_marshaling_test.go
+ example_test.go
+ example_text_marshaling_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/encoding/ya.make b/contrib/go/_std_1.21/src/encoding/ya.make
index 7f4caa9e47..7f4caa9e47 100644
--- a/contrib/go/_std_1.20/src/encoding/ya.make
+++ b/contrib/go/_std_1.21/src/encoding/ya.make
diff --git a/contrib/go/_std_1.21/src/errors/errors.go b/contrib/go/_std_1.21/src/errors/errors.go
new file mode 100644
index 0000000000..41397774d3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/errors/errors.go
@@ -0,0 +1,87 @@
+// Copyright 2011 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 errors implements functions to manipulate errors.
+//
+// The [New] function creates errors whose only content is a text message.
+//
+// An error e wraps another error if e's type has one of the methods
+//
+// Unwrap() error
+// Unwrap() []error
+//
+// If e.Unwrap() returns a non-nil error w or a slice containing w,
+// then we say that e wraps w. A nil error returned from e.Unwrap()
+// indicates that e does not wrap any error. It is invalid for an
+// Unwrap method to return an []error containing a nil error value.
+//
+// An easy way to create wrapped errors is to call [fmt.Errorf] and apply
+// the %w verb to the error argument:
+//
+// wrapsErr := fmt.Errorf("... %w ...", ..., err, ...)
+//
+// Successive unwrapping of an error creates a tree. The [Is] and [As]
+// functions inspect an error's tree by examining first the error
+// itself followed by the tree of each of its children in turn
+// (pre-order, depth-first traversal).
+//
+// Is examines the tree of its first argument looking for an error that
+// matches the second. It reports whether it finds a match. It should be
+// used in preference to simple equality checks:
+//
+// if errors.Is(err, fs.ErrExist)
+//
+// is preferable to
+//
+// if err == fs.ErrExist
+//
+// because the former will succeed if err wraps [io/fs.ErrExist].
+//
+// As examines the tree of its first argument looking for an error that can be
+// assigned to its second argument, which must be a pointer. If it succeeds, it
+// performs the assignment and returns true. Otherwise, it returns false. The form
+//
+// var perr *fs.PathError
+// if errors.As(err, &perr) {
+// fmt.Println(perr.Path)
+// }
+//
+// is preferable to
+//
+// if perr, ok := err.(*fs.PathError); ok {
+// fmt.Println(perr.Path)
+// }
+//
+// because the former will succeed if err wraps an [*io/fs.PathError].
+package errors
+
+// New returns an error that formats as the given text.
+// Each call to New returns a distinct error value even if the text is identical.
+func New(text string) error {
+ return &errorString{text}
+}
+
+// errorString is a trivial implementation of error.
+type errorString struct {
+ s string
+}
+
+func (e *errorString) Error() string {
+ return e.s
+}
+
+// ErrUnsupported indicates that a requested operation cannot be performed,
+// because it is unsupported. For example, a call to [os.Link] when using a
+// file system that does not support hard links.
+//
+// Functions and methods should not return this error but should instead
+// return an error including appropriate context that satisfies
+//
+// errors.Is(err, errors.ErrUnsupported)
+//
+// either by directly wrapping ErrUnsupported or by implementing an Is method.
+//
+// Functions and methods should document the cases in which an error
+// wrapping this will be returned.
+var ErrUnsupported = New("unsupported operation")
diff --git a/contrib/go/_std_1.21/src/errors/join.go b/contrib/go/_std_1.21/src/errors/join.go
new file mode 100644
index 0000000000..1c486d591e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/errors/join.go
@@ -0,0 +1,53 @@
+// Copyright 2022 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 errors
+
+// Join returns an error that wraps the given errors.
+// Any nil error values are discarded.
+// Join returns nil if every value in errs is nil.
+// The error formats as the concatenation of the strings obtained
+// by calling the Error method of each element of errs, with a newline
+// between each string.
+//
+// A non-nil error returned by Join implements the Unwrap() []error method.
+func Join(errs ...error) error {
+ n := 0
+ for _, err := range errs {
+ if err != nil {
+ n++
+ }
+ }
+ if n == 0 {
+ return nil
+ }
+ e := &joinError{
+ errs: make([]error, 0, n),
+ }
+ for _, err := range errs {
+ if err != nil {
+ e.errs = append(e.errs, err)
+ }
+ }
+ return e
+}
+
+type joinError struct {
+ errs []error
+}
+
+func (e *joinError) Error() string {
+ var b []byte
+ for i, err := range e.errs {
+ if i > 0 {
+ b = append(b, '\n')
+ }
+ b = append(b, err.Error()...)
+ }
+ return string(b)
+}
+
+func (e *joinError) Unwrap() []error {
+ return e.errs
+}
diff --git a/contrib/go/_std_1.21/src/errors/wrap.go b/contrib/go/_std_1.21/src/errors/wrap.go
new file mode 100644
index 0000000000..2c934eed5a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/errors/wrap.go
@@ -0,0 +1,136 @@
+// Copyright 2018 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 errors
+
+import (
+ "internal/reflectlite"
+)
+
+// Unwrap returns the result of calling the Unwrap method on err, if err's
+// type contains an Unwrap method returning error.
+// Otherwise, Unwrap returns nil.
+//
+// Unwrap only calls a method of the form "Unwrap() error".
+// In particular Unwrap does not unwrap errors returned by [Join].
+func Unwrap(err error) error {
+ u, ok := err.(interface {
+ Unwrap() error
+ })
+ if !ok {
+ return nil
+ }
+ return u.Unwrap()
+}
+
+// Is reports whether any error in err's tree matches target.
+//
+// The tree consists of err itself, followed by the errors obtained by repeatedly
+// calling Unwrap. When err wraps multiple errors, Is examines err followed by a
+// depth-first traversal of its children.
+//
+// An error is considered to match a target if it is equal to that target or if
+// it implements a method Is(error) bool such that Is(target) returns true.
+//
+// An error type might provide an Is method so it can be treated as equivalent
+// to an existing error. For example, if MyError defines
+//
+// func (m MyError) Is(target error) bool { return target == fs.ErrExist }
+//
+// then Is(MyError{}, fs.ErrExist) returns true. See [syscall.Errno.Is] for
+// an example in the standard library. An Is method should only shallowly
+// compare err and the target and not call Unwrap on either.
+func Is(err, target error) bool {
+ if target == nil {
+ return err == target
+ }
+
+ isComparable := reflectlite.TypeOf(target).Comparable()
+ for {
+ if isComparable && err == target {
+ return true
+ }
+ if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
+ return true
+ }
+ switch x := err.(type) {
+ case interface{ Unwrap() error }:
+ err = x.Unwrap()
+ if err == nil {
+ return false
+ }
+ case interface{ Unwrap() []error }:
+ for _, err := range x.Unwrap() {
+ if Is(err, target) {
+ return true
+ }
+ }
+ return false
+ default:
+ return false
+ }
+ }
+}
+
+// As finds the first error in err's tree that matches target, and if one is found, sets
+// target to that error value and returns true. Otherwise, it returns false.
+//
+// The tree consists of err itself, followed by the errors obtained by repeatedly
+// calling Unwrap. When err wraps multiple errors, As examines err followed by a
+// depth-first traversal of its children.
+//
+// An error matches target if the error's concrete value is assignable to the value
+// pointed to by target, or if the error has a method As(interface{}) bool such that
+// As(target) returns true. In the latter case, the As method is responsible for
+// setting target.
+//
+// An error type might provide an As method so it can be treated as if it were a
+// different error type.
+//
+// As panics if target is not a non-nil pointer to either a type that implements
+// error, or to any interface type.
+func As(err error, target any) bool {
+ if err == nil {
+ return false
+ }
+ if target == nil {
+ panic("errors: target cannot be nil")
+ }
+ val := reflectlite.ValueOf(target)
+ typ := val.Type()
+ if typ.Kind() != reflectlite.Ptr || val.IsNil() {
+ panic("errors: target must be a non-nil pointer")
+ }
+ targetType := typ.Elem()
+ if targetType.Kind() != reflectlite.Interface && !targetType.Implements(errorType) {
+ panic("errors: *target must be interface or implement error")
+ }
+ for {
+ if reflectlite.TypeOf(err).AssignableTo(targetType) {
+ val.Elem().Set(reflectlite.ValueOf(err))
+ return true
+ }
+ if x, ok := err.(interface{ As(any) bool }); ok && x.As(target) {
+ return true
+ }
+ switch x := err.(type) {
+ case interface{ Unwrap() error }:
+ err = x.Unwrap()
+ if err == nil {
+ return false
+ }
+ case interface{ Unwrap() []error }:
+ for _, err := range x.Unwrap() {
+ if As(err, target) {
+ return true
+ }
+ }
+ return false
+ default:
+ return false
+ }
+ }
+}
+
+var errorType = reflectlite.TypeOf((*error)(nil)).Elem()
diff --git a/contrib/go/_std_1.21/src/errors/ya.make b/contrib/go/_std_1.21/src/errors/ya.make
new file mode 100644
index 0000000000..628659c01f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/errors/ya.make
@@ -0,0 +1,19 @@
+GO_LIBRARY()
+
+SRCS(
+ errors.go
+ join.go
+ wrap.go
+)
+
+GO_XTEST_SRCS(
+ errors_test.go
+ example_test.go
+ join_test.go
+ wrap_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/expvar/expvar.go b/contrib/go/_std_1.21/src/expvar/expvar.go
index 300d8c2676..300d8c2676 100644
--- a/contrib/go/_std_1.20/src/expvar/expvar.go
+++ b/contrib/go/_std_1.21/src/expvar/expvar.go
diff --git a/contrib/go/_std_1.21/src/expvar/ya.make b/contrib/go/_std_1.21/src/expvar/ya.make
new file mode 100644
index 0000000000..06dfbfc8bc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/expvar/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ expvar.go
+)
+
+GO_TEST_SRCS(expvar_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/flag/flag.go b/contrib/go/_std_1.21/src/flag/flag.go
new file mode 100644
index 0000000000..9d3e8d32a5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/flag/flag.go
@@ -0,0 +1,1231 @@
+// Copyright 2009 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 flag implements command-line flag parsing.
+
+# Usage
+
+Define flags using flag.String(), Bool(), Int(), etc.
+
+This declares an integer flag, -n, stored in the pointer nFlag, with type *int:
+
+ import "flag"
+ var nFlag = flag.Int("n", 1234, "help message for flag n")
+
+If you like, you can bind the flag to a variable using the Var() functions.
+
+ var flagvar int
+ func init() {
+ flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
+ }
+
+Or you can create custom flags that satisfy the Value interface (with
+pointer receivers) and couple them to flag parsing by
+
+ flag.Var(&flagVal, "name", "help message for flagname")
+
+For such flags, the default value is just the initial value of the variable.
+
+After all flags are defined, call
+
+ flag.Parse()
+
+to parse the command line into the defined flags.
+
+Flags may then be used directly. If you're using the flags themselves,
+they are all pointers; if you bind to variables, they're values.
+
+ fmt.Println("ip has value ", *ip)
+ fmt.Println("flagvar has value ", flagvar)
+
+After parsing, the arguments following the flags are available as the
+slice flag.Args() or individually as flag.Arg(i).
+The arguments are indexed from 0 through flag.NArg()-1.
+
+# Command line flag syntax
+
+The following forms are permitted:
+
+ -flag
+ --flag // double dashes are also permitted
+ -flag=x
+ -flag x // non-boolean flags only
+
+One or two dashes may be used; they are equivalent.
+The last form is not permitted for boolean flags because the
+meaning of the command
+
+ cmd -x *
+
+where * is a Unix shell wildcard, will change if there is a file
+called 0, false, etc. You must use the -flag=false form to turn
+off a boolean flag.
+
+Flag parsing stops just before the first non-flag argument
+("-" is a non-flag argument) or after the terminator "--".
+
+Integer flags accept 1234, 0664, 0x1234 and may be negative.
+Boolean flags may be:
+
+ 1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False
+
+Duration flags accept any input valid for time.ParseDuration.
+
+The default set of command-line flags is controlled by
+top-level functions. The FlagSet type allows one to define
+independent sets of flags, such as to implement subcommands
+in a command-line interface. The methods of FlagSet are
+analogous to the top-level functions for the command-line
+flag set.
+*/
+package flag
+
+import (
+ "encoding"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "reflect"
+ "runtime"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// ErrHelp is the error returned if the -help or -h flag is invoked
+// but no such flag is defined.
+var ErrHelp = errors.New("flag: help requested")
+
+// errParse is returned by Set if a flag's value fails to parse, such as with an invalid integer for Int.
+// It then gets wrapped through failf to provide more information.
+var errParse = errors.New("parse error")
+
+// errRange is returned by Set if a flag's value is out of range.
+// It then gets wrapped through failf to provide more information.
+var errRange = errors.New("value out of range")
+
+func numError(err error) error {
+ ne, ok := err.(*strconv.NumError)
+ if !ok {
+ return err
+ }
+ if ne.Err == strconv.ErrSyntax {
+ return errParse
+ }
+ if ne.Err == strconv.ErrRange {
+ return errRange
+ }
+ return err
+}
+
+// -- bool Value
+type boolValue bool
+
+func newBoolValue(val bool, p *bool) *boolValue {
+ *p = val
+ return (*boolValue)(p)
+}
+
+func (b *boolValue) Set(s string) error {
+ v, err := strconv.ParseBool(s)
+ if err != nil {
+ err = errParse
+ }
+ *b = boolValue(v)
+ return err
+}
+
+func (b *boolValue) Get() any { return bool(*b) }
+
+func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) }
+
+func (b *boolValue) IsBoolFlag() bool { return true }
+
+// optional interface to indicate boolean flags that can be
+// supplied without "=value" text
+type boolFlag interface {
+ Value
+ IsBoolFlag() bool
+}
+
+// -- int Value
+type intValue int
+
+func newIntValue(val int, p *int) *intValue {
+ *p = val
+ return (*intValue)(p)
+}
+
+func (i *intValue) Set(s string) error {
+ v, err := strconv.ParseInt(s, 0, strconv.IntSize)
+ if err != nil {
+ err = numError(err)
+ }
+ *i = intValue(v)
+ return err
+}
+
+func (i *intValue) Get() any { return int(*i) }
+
+func (i *intValue) String() string { return strconv.Itoa(int(*i)) }
+
+// -- int64 Value
+type int64Value int64
+
+func newInt64Value(val int64, p *int64) *int64Value {
+ *p = val
+ return (*int64Value)(p)
+}
+
+func (i *int64Value) Set(s string) error {
+ v, err := strconv.ParseInt(s, 0, 64)
+ if err != nil {
+ err = numError(err)
+ }
+ *i = int64Value(v)
+ return err
+}
+
+func (i *int64Value) Get() any { return int64(*i) }
+
+func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) }
+
+// -- uint Value
+type uintValue uint
+
+func newUintValue(val uint, p *uint) *uintValue {
+ *p = val
+ return (*uintValue)(p)
+}
+
+func (i *uintValue) Set(s string) error {
+ v, err := strconv.ParseUint(s, 0, strconv.IntSize)
+ if err != nil {
+ err = numError(err)
+ }
+ *i = uintValue(v)
+ return err
+}
+
+func (i *uintValue) Get() any { return uint(*i) }
+
+func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) }
+
+// -- uint64 Value
+type uint64Value uint64
+
+func newUint64Value(val uint64, p *uint64) *uint64Value {
+ *p = val
+ return (*uint64Value)(p)
+}
+
+func (i *uint64Value) Set(s string) error {
+ v, err := strconv.ParseUint(s, 0, 64)
+ if err != nil {
+ err = numError(err)
+ }
+ *i = uint64Value(v)
+ return err
+}
+
+func (i *uint64Value) Get() any { return uint64(*i) }
+
+func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
+
+// -- string Value
+type stringValue string
+
+func newStringValue(val string, p *string) *stringValue {
+ *p = val
+ return (*stringValue)(p)
+}
+
+func (s *stringValue) Set(val string) error {
+ *s = stringValue(val)
+ return nil
+}
+
+func (s *stringValue) Get() any { return string(*s) }
+
+func (s *stringValue) String() string { return string(*s) }
+
+// -- float64 Value
+type float64Value float64
+
+func newFloat64Value(val float64, p *float64) *float64Value {
+ *p = val
+ return (*float64Value)(p)
+}
+
+func (f *float64Value) Set(s string) error {
+ v, err := strconv.ParseFloat(s, 64)
+ if err != nil {
+ err = numError(err)
+ }
+ *f = float64Value(v)
+ return err
+}
+
+func (f *float64Value) Get() any { return float64(*f) }
+
+func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) }
+
+// -- time.Duration Value
+type durationValue time.Duration
+
+func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
+ *p = val
+ return (*durationValue)(p)
+}
+
+func (d *durationValue) Set(s string) error {
+ v, err := time.ParseDuration(s)
+ if err != nil {
+ err = errParse
+ }
+ *d = durationValue(v)
+ return err
+}
+
+func (d *durationValue) Get() any { return time.Duration(*d) }
+
+func (d *durationValue) String() string { return (*time.Duration)(d).String() }
+
+// -- encoding.TextUnmarshaler Value
+type textValue struct{ p encoding.TextUnmarshaler }
+
+func newTextValue(val encoding.TextMarshaler, p encoding.TextUnmarshaler) textValue {
+ ptrVal := reflect.ValueOf(p)
+ if ptrVal.Kind() != reflect.Ptr {
+ panic("variable value type must be a pointer")
+ }
+ defVal := reflect.ValueOf(val)
+ if defVal.Kind() == reflect.Ptr {
+ defVal = defVal.Elem()
+ }
+ if defVal.Type() != ptrVal.Type().Elem() {
+ panic(fmt.Sprintf("default type does not match variable type: %v != %v", defVal.Type(), ptrVal.Type().Elem()))
+ }
+ ptrVal.Elem().Set(defVal)
+ return textValue{p}
+}
+
+func (v textValue) Set(s string) error {
+ return v.p.UnmarshalText([]byte(s))
+}
+
+func (v textValue) Get() interface{} {
+ return v.p
+}
+
+func (v textValue) String() string {
+ if m, ok := v.p.(encoding.TextMarshaler); ok {
+ if b, err := m.MarshalText(); err == nil {
+ return string(b)
+ }
+ }
+ return ""
+}
+
+// -- func Value
+type funcValue func(string) error
+
+func (f funcValue) Set(s string) error { return f(s) }
+
+func (f funcValue) String() string { return "" }
+
+// -- boolFunc Value
+type boolFuncValue func(string) error
+
+func (f boolFuncValue) Set(s string) error { return f(s) }
+
+func (f boolFuncValue) String() string { return "" }
+
+func (f boolFuncValue) IsBoolFlag() bool { return true }
+
+// Value is the interface to the dynamic value stored in a flag.
+// (The default value is represented as a string.)
+//
+// If a Value has an IsBoolFlag() bool method returning true,
+// the command-line parser makes -name equivalent to -name=true
+// rather than using the next command-line argument.
+//
+// Set is called once, in command line order, for each flag present.
+// The flag package may call the String method with a zero-valued receiver,
+// such as a nil pointer.
+type Value interface {
+ String() string
+ Set(string) error
+}
+
+// Getter is an interface that allows the contents of a Value to be retrieved.
+// It wraps the Value interface, rather than being part of it, because it
+// appeared after Go 1 and its compatibility rules. All Value types provided
+// by this package satisfy the Getter interface, except the type used by Func.
+type Getter interface {
+ Value
+ Get() any
+}
+
+// ErrorHandling defines how FlagSet.Parse behaves if the parse fails.
+type ErrorHandling int
+
+// These constants cause FlagSet.Parse to behave as described if the parse fails.
+const (
+ ContinueOnError ErrorHandling = iota // Return a descriptive error.
+ ExitOnError // Call os.Exit(2) or for -h/-help Exit(0).
+ PanicOnError // Call panic with a descriptive error.
+)
+
+// A FlagSet represents a set of defined flags. The zero value of a FlagSet
+// has no name and has ContinueOnError error handling.
+//
+// Flag names must be unique within a FlagSet. An attempt to define a flag whose
+// name is already in use will cause a panic.
+type FlagSet struct {
+ // Usage is the function called when an error occurs while parsing flags.
+ // The field is a function (not a method) that may be changed to point to
+ // a custom error handler. What happens after Usage is called depends
+ // on the ErrorHandling setting; for the command line, this defaults
+ // to ExitOnError, which exits the program after calling Usage.
+ Usage func()
+
+ name string
+ parsed bool
+ actual map[string]*Flag
+ formal map[string]*Flag
+ args []string // arguments after flags
+ errorHandling ErrorHandling
+ output io.Writer // nil means stderr; use Output() accessor
+ undef map[string]string // flags which didn't exist at the time of Set
+}
+
+// A Flag represents the state of a flag.
+type Flag struct {
+ Name string // name as it appears on command line
+ Usage string // help message
+ Value Value // value as set
+ DefValue string // default value (as text); for usage message
+}
+
+// sortFlags returns the flags as a slice in lexicographical sorted order.
+func sortFlags(flags map[string]*Flag) []*Flag {
+ result := make([]*Flag, len(flags))
+ i := 0
+ for _, f := range flags {
+ result[i] = f
+ i++
+ }
+ sort.Slice(result, func(i, j int) bool {
+ return result[i].Name < result[j].Name
+ })
+ return result
+}
+
+// Output returns the destination for usage and error messages. os.Stderr is returned if
+// output was not set or was set to nil.
+func (f *FlagSet) Output() io.Writer {
+ if f.output == nil {
+ return os.Stderr
+ }
+ return f.output
+}
+
+// Name returns the name of the flag set.
+func (f *FlagSet) Name() string {
+ return f.name
+}
+
+// ErrorHandling returns the error handling behavior of the flag set.
+func (f *FlagSet) ErrorHandling() ErrorHandling {
+ return f.errorHandling
+}
+
+// SetOutput sets the destination for usage and error messages.
+// If output is nil, os.Stderr is used.
+func (f *FlagSet) SetOutput(output io.Writer) {
+ f.output = output
+}
+
+// VisitAll visits the flags in lexicographical order, calling fn for each.
+// It visits all flags, even those not set.
+func (f *FlagSet) VisitAll(fn func(*Flag)) {
+ for _, flag := range sortFlags(f.formal) {
+ fn(flag)
+ }
+}
+
+// VisitAll visits the command-line flags in lexicographical order, calling
+// fn for each. It visits all flags, even those not set.
+func VisitAll(fn func(*Flag)) {
+ CommandLine.VisitAll(fn)
+}
+
+// Visit visits the flags in lexicographical order, calling fn for each.
+// It visits only those flags that have been set.
+func (f *FlagSet) Visit(fn func(*Flag)) {
+ for _, flag := range sortFlags(f.actual) {
+ fn(flag)
+ }
+}
+
+// Visit visits the command-line flags in lexicographical order, calling fn
+// for each. It visits only those flags that have been set.
+func Visit(fn func(*Flag)) {
+ CommandLine.Visit(fn)
+}
+
+// Lookup returns the Flag structure of the named flag, returning nil if none exists.
+func (f *FlagSet) Lookup(name string) *Flag {
+ return f.formal[name]
+}
+
+// Lookup returns the Flag structure of the named command-line flag,
+// returning nil if none exists.
+func Lookup(name string) *Flag {
+ return CommandLine.formal[name]
+}
+
+// Set sets the value of the named flag.
+func (f *FlagSet) Set(name, value string) error {
+ return f.set(name, value)
+}
+func (f *FlagSet) set(name, value string) error {
+ flag, ok := f.formal[name]
+ if !ok {
+ // Remember that a flag that isn't defined is being set.
+ // We return an error in this case, but in addition if
+ // subsequently that flag is defined, we want to panic
+ // at the definition point.
+ // This is a problem which occurs if both the definition
+ // and the Set call are in init code and for whatever
+ // reason the init code changes evaluation order.
+ // See issue 57411.
+ _, file, line, ok := runtime.Caller(2)
+ if !ok {
+ file = "?"
+ line = 0
+ }
+ if f.undef == nil {
+ f.undef = map[string]string{}
+ }
+ f.undef[name] = fmt.Sprintf("%s:%d", file, line)
+
+ return fmt.Errorf("no such flag -%v", name)
+ }
+ err := flag.Value.Set(value)
+ if err != nil {
+ return err
+ }
+ if f.actual == nil {
+ f.actual = make(map[string]*Flag)
+ }
+ f.actual[name] = flag
+ return nil
+}
+
+// Set sets the value of the named command-line flag.
+func Set(name, value string) error {
+ return CommandLine.set(name, value)
+}
+
+// isZeroValue determines whether the string represents the zero
+// value for a flag.
+func isZeroValue(flag *Flag, value string) (ok bool, err error) {
+ // Build a zero value of the flag's Value type, and see if the
+ // result of calling its String method equals the value passed in.
+ // This works unless the Value type is itself an interface type.
+ typ := reflect.TypeOf(flag.Value)
+ var z reflect.Value
+ if typ.Kind() == reflect.Pointer {
+ z = reflect.New(typ.Elem())
+ } else {
+ z = reflect.Zero(typ)
+ }
+ // Catch panics calling the String method, which shouldn't prevent the
+ // usage message from being printed, but that we should report to the
+ // user so that they know to fix their code.
+ defer func() {
+ if e := recover(); e != nil {
+ if typ.Kind() == reflect.Pointer {
+ typ = typ.Elem()
+ }
+ err = fmt.Errorf("panic calling String method on zero %v for flag %s: %v", typ, flag.Name, e)
+ }
+ }()
+ return value == z.Interface().(Value).String(), nil
+}
+
+// UnquoteUsage extracts a back-quoted name from the usage
+// string for a flag and returns it and the un-quoted usage.
+// Given "a `name` to show" it returns ("name", "a name to show").
+// If there are no back quotes, the name is an educated guess of the
+// type of the flag's value, or the empty string if the flag is boolean.
+func UnquoteUsage(flag *Flag) (name string, usage string) {
+ // Look for a back-quoted name, but avoid the strings package.
+ usage = flag.Usage
+ for i := 0; i < len(usage); i++ {
+ if usage[i] == '`' {
+ for j := i + 1; j < len(usage); j++ {
+ if usage[j] == '`' {
+ name = usage[i+1 : j]
+ usage = usage[:i] + name + usage[j+1:]
+ return name, usage
+ }
+ }
+ break // Only one back quote; use type name.
+ }
+ }
+ // No explicit name, so use type if we can find one.
+ name = "value"
+ switch fv := flag.Value.(type) {
+ case boolFlag:
+ if fv.IsBoolFlag() {
+ name = ""
+ }
+ case *durationValue:
+ name = "duration"
+ case *float64Value:
+ name = "float"
+ case *intValue, *int64Value:
+ name = "int"
+ case *stringValue:
+ name = "string"
+ case *uintValue, *uint64Value:
+ name = "uint"
+ }
+ return
+}
+
+// PrintDefaults prints, to standard error unless configured otherwise, the
+// default values of all defined command-line flags in the set. See the
+// documentation for the global function PrintDefaults for more information.
+func (f *FlagSet) PrintDefaults() {
+ var isZeroValueErrs []error
+ f.VisitAll(func(flag *Flag) {
+ var b strings.Builder
+ fmt.Fprintf(&b, " -%s", flag.Name) // Two spaces before -; see next two comments.
+ name, usage := UnquoteUsage(flag)
+ if len(name) > 0 {
+ b.WriteString(" ")
+ b.WriteString(name)
+ }
+ // Boolean flags of one ASCII letter are so common we
+ // treat them specially, putting their usage on the same line.
+ if b.Len() <= 4 { // space, space, '-', 'x'.
+ b.WriteString("\t")
+ } else {
+ // Four spaces before the tab triggers good alignment
+ // for both 4- and 8-space tab stops.
+ b.WriteString("\n \t")
+ }
+ b.WriteString(strings.ReplaceAll(usage, "\n", "\n \t"))
+
+ // Print the default value only if it differs to the zero value
+ // for this flag type.
+ if isZero, err := isZeroValue(flag, flag.DefValue); err != nil {
+ isZeroValueErrs = append(isZeroValueErrs, err)
+ } else if !isZero {
+ if _, ok := flag.Value.(*stringValue); ok {
+ // put quotes on the value
+ fmt.Fprintf(&b, " (default %q)", flag.DefValue)
+ } else {
+ fmt.Fprintf(&b, " (default %v)", flag.DefValue)
+ }
+ }
+ fmt.Fprint(f.Output(), b.String(), "\n")
+ })
+ // If calling String on any zero flag.Values triggered a panic, print
+ // the messages after the full set of defaults so that the programmer
+ // knows to fix the panic.
+ if errs := isZeroValueErrs; len(errs) > 0 {
+ fmt.Fprintln(f.Output())
+ for _, err := range errs {
+ fmt.Fprintln(f.Output(), err)
+ }
+ }
+}
+
+// PrintDefaults prints, to standard error unless configured otherwise,
+// a usage message showing the default settings of all defined
+// command-line flags.
+// For an integer valued flag x, the default output has the form
+//
+// -x int
+// usage-message-for-x (default 7)
+//
+// The usage message will appear on a separate line for anything but
+// a bool flag with a one-byte name. For bool flags, the type is
+// omitted and if the flag name is one byte the usage message appears
+// on the same line. The parenthetical default is omitted if the
+// default is the zero value for the type. The listed type, here int,
+// can be changed by placing a back-quoted name in the flag's usage
+// string; the first such item in the message is taken to be a parameter
+// name to show in the message and the back quotes are stripped from
+// the message when displayed. For instance, given
+//
+// flag.String("I", "", "search `directory` for include files")
+//
+// the output will be
+//
+// -I directory
+// search directory for include files.
+//
+// To change the destination for flag messages, call CommandLine.SetOutput.
+func PrintDefaults() {
+ CommandLine.PrintDefaults()
+}
+
+// defaultUsage is the default function to print a usage message.
+func (f *FlagSet) defaultUsage() {
+ if f.name == "" {
+ fmt.Fprintf(f.Output(), "Usage:\n")
+ } else {
+ fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)
+ }
+ f.PrintDefaults()
+}
+
+// NOTE: Usage is not just defaultUsage(CommandLine)
+// because it serves (via godoc flag Usage) as the example
+// for how to write your own usage function.
+
+// Usage prints a usage message documenting all defined command-line flags
+// to CommandLine's output, which by default is os.Stderr.
+// It is called when an error occurs while parsing flags.
+// The function is a variable that may be changed to point to a custom function.
+// By default it prints a simple header and calls PrintDefaults; for details about the
+// format of the output and how to control it, see the documentation for PrintDefaults.
+// Custom usage functions may choose to exit the program; by default exiting
+// happens anyway as the command line's error handling strategy is set to
+// ExitOnError.
+var Usage = func() {
+ fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0])
+ PrintDefaults()
+}
+
+// NFlag returns the number of flags that have been set.
+func (f *FlagSet) NFlag() int { return len(f.actual) }
+
+// NFlag returns the number of command-line flags that have been set.
+func NFlag() int { return len(CommandLine.actual) }
+
+// Arg returns the i'th argument. Arg(0) is the first remaining argument
+// after flags have been processed. Arg returns an empty string if the
+// requested element does not exist.
+func (f *FlagSet) Arg(i int) string {
+ if i < 0 || i >= len(f.args) {
+ return ""
+ }
+ return f.args[i]
+}
+
+// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
+// after flags have been processed. Arg returns an empty string if the
+// requested element does not exist.
+func Arg(i int) string {
+ return CommandLine.Arg(i)
+}
+
+// NArg is the number of arguments remaining after flags have been processed.
+func (f *FlagSet) NArg() int { return len(f.args) }
+
+// NArg is the number of arguments remaining after flags have been processed.
+func NArg() int { return len(CommandLine.args) }
+
+// Args returns the non-flag arguments.
+func (f *FlagSet) Args() []string { return f.args }
+
+// Args returns the non-flag command-line arguments.
+func Args() []string { return CommandLine.args }
+
+// BoolVar defines a bool flag with specified name, default value, and usage string.
+// The argument p points to a bool variable in which to store the value of the flag.
+func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
+ f.Var(newBoolValue(value, p), name, usage)
+}
+
+// BoolVar defines a bool flag with specified name, default value, and usage string.
+// The argument p points to a bool variable in which to store the value of the flag.
+func BoolVar(p *bool, name string, value bool, usage string) {
+ CommandLine.Var(newBoolValue(value, p), name, usage)
+}
+
+// Bool defines a bool flag with specified name, default value, and usage string.
+// The return value is the address of a bool variable that stores the value of the flag.
+func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
+ p := new(bool)
+ f.BoolVar(p, name, value, usage)
+ return p
+}
+
+// Bool defines a bool flag with specified name, default value, and usage string.
+// The return value is the address of a bool variable that stores the value of the flag.
+func Bool(name string, value bool, usage string) *bool {
+ return CommandLine.Bool(name, value, usage)
+}
+
+// IntVar defines an int flag with specified name, default value, and usage string.
+// The argument p points to an int variable in which to store the value of the flag.
+func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
+ f.Var(newIntValue(value, p), name, usage)
+}
+
+// IntVar defines an int flag with specified name, default value, and usage string.
+// The argument p points to an int variable in which to store the value of the flag.
+func IntVar(p *int, name string, value int, usage string) {
+ CommandLine.Var(newIntValue(value, p), name, usage)
+}
+
+// Int defines an int flag with specified name, default value, and usage string.
+// The return value is the address of an int variable that stores the value of the flag.
+func (f *FlagSet) Int(name string, value int, usage string) *int {
+ p := new(int)
+ f.IntVar(p, name, value, usage)
+ return p
+}
+
+// Int defines an int flag with specified name, default value, and usage string.
+// The return value is the address of an int variable that stores the value of the flag.
+func Int(name string, value int, usage string) *int {
+ return CommandLine.Int(name, value, usage)
+}
+
+// Int64Var defines an int64 flag with specified name, default value, and usage string.
+// The argument p points to an int64 variable in which to store the value of the flag.
+func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
+ f.Var(newInt64Value(value, p), name, usage)
+}
+
+// Int64Var defines an int64 flag with specified name, default value, and usage string.
+// The argument p points to an int64 variable in which to store the value of the flag.
+func Int64Var(p *int64, name string, value int64, usage string) {
+ CommandLine.Var(newInt64Value(value, p), name, usage)
+}
+
+// Int64 defines an int64 flag with specified name, default value, and usage string.
+// The return value is the address of an int64 variable that stores the value of the flag.
+func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
+ p := new(int64)
+ f.Int64Var(p, name, value, usage)
+ return p
+}
+
+// Int64 defines an int64 flag with specified name, default value, and usage string.
+// The return value is the address of an int64 variable that stores the value of the flag.
+func Int64(name string, value int64, usage string) *int64 {
+ return CommandLine.Int64(name, value, usage)
+}
+
+// UintVar defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint variable in which to store the value of the flag.
+func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
+ f.Var(newUintValue(value, p), name, usage)
+}
+
+// UintVar defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint variable in which to store the value of the flag.
+func UintVar(p *uint, name string, value uint, usage string) {
+ CommandLine.Var(newUintValue(value, p), name, usage)
+}
+
+// Uint defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint variable that stores the value of the flag.
+func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
+ p := new(uint)
+ f.UintVar(p, name, value, usage)
+ return p
+}
+
+// Uint defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint variable that stores the value of the flag.
+func Uint(name string, value uint, usage string) *uint {
+ return CommandLine.Uint(name, value, usage)
+}
+
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
+// The argument p points to a uint64 variable in which to store the value of the flag.
+func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
+ f.Var(newUint64Value(value, p), name, usage)
+}
+
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
+// The argument p points to a uint64 variable in which to store the value of the flag.
+func Uint64Var(p *uint64, name string, value uint64, usage string) {
+ CommandLine.Var(newUint64Value(value, p), name, usage)
+}
+
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
+// The return value is the address of a uint64 variable that stores the value of the flag.
+func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
+ p := new(uint64)
+ f.Uint64Var(p, name, value, usage)
+ return p
+}
+
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
+// The return value is the address of a uint64 variable that stores the value of the flag.
+func Uint64(name string, value uint64, usage string) *uint64 {
+ return CommandLine.Uint64(name, value, usage)
+}
+
+// StringVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a string variable in which to store the value of the flag.
+func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
+ f.Var(newStringValue(value, p), name, usage)
+}
+
+// StringVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a string variable in which to store the value of the flag.
+func StringVar(p *string, name string, value string, usage string) {
+ CommandLine.Var(newStringValue(value, p), name, usage)
+}
+
+// String defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a string variable that stores the value of the flag.
+func (f *FlagSet) String(name string, value string, usage string) *string {
+ p := new(string)
+ f.StringVar(p, name, value, usage)
+ return p
+}
+
+// String defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a string variable that stores the value of the flag.
+func String(name string, value string, usage string) *string {
+ return CommandLine.String(name, value, usage)
+}
+
+// Float64Var defines a float64 flag with specified name, default value, and usage string.
+// The argument p points to a float64 variable in which to store the value of the flag.
+func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
+ f.Var(newFloat64Value(value, p), name, usage)
+}
+
+// Float64Var defines a float64 flag with specified name, default value, and usage string.
+// The argument p points to a float64 variable in which to store the value of the flag.
+func Float64Var(p *float64, name string, value float64, usage string) {
+ CommandLine.Var(newFloat64Value(value, p), name, usage)
+}
+
+// Float64 defines a float64 flag with specified name, default value, and usage string.
+// The return value is the address of a float64 variable that stores the value of the flag.
+func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
+ p := new(float64)
+ f.Float64Var(p, name, value, usage)
+ return p
+}
+
+// Float64 defines a float64 flag with specified name, default value, and usage string.
+// The return value is the address of a float64 variable that stores the value of the flag.
+func Float64(name string, value float64, usage string) *float64 {
+ return CommandLine.Float64(name, value, usage)
+}
+
+// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
+// The argument p points to a time.Duration variable in which to store the value of the flag.
+// The flag accepts a value acceptable to time.ParseDuration.
+func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
+ f.Var(newDurationValue(value, p), name, usage)
+}
+
+// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
+// The argument p points to a time.Duration variable in which to store the value of the flag.
+// The flag accepts a value acceptable to time.ParseDuration.
+func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
+ CommandLine.Var(newDurationValue(value, p), name, usage)
+}
+
+// Duration defines a time.Duration flag with specified name, default value, and usage string.
+// The return value is the address of a time.Duration variable that stores the value of the flag.
+// The flag accepts a value acceptable to time.ParseDuration.
+func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
+ p := new(time.Duration)
+ f.DurationVar(p, name, value, usage)
+ return p
+}
+
+// Duration defines a time.Duration flag with specified name, default value, and usage string.
+// The return value is the address of a time.Duration variable that stores the value of the flag.
+// The flag accepts a value acceptable to time.ParseDuration.
+func Duration(name string, value time.Duration, usage string) *time.Duration {
+ return CommandLine.Duration(name, value, usage)
+}
+
+// TextVar defines a flag with a specified name, default value, and usage string.
+// The argument p must be a pointer to a variable that will hold the value
+// of the flag, and p must implement encoding.TextUnmarshaler.
+// If the flag is used, the flag value will be passed to p's UnmarshalText method.
+// The type of the default value must be the same as the type of p.
+func (f *FlagSet) TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) {
+ f.Var(newTextValue(value, p), name, usage)
+}
+
+// TextVar defines a flag with a specified name, default value, and usage string.
+// The argument p must be a pointer to a variable that will hold the value
+// of the flag, and p must implement encoding.TextUnmarshaler.
+// If the flag is used, the flag value will be passed to p's UnmarshalText method.
+// The type of the default value must be the same as the type of p.
+func TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) {
+ CommandLine.Var(newTextValue(value, p), name, usage)
+}
+
+// Func defines a flag with the specified name and usage string.
+// Each time the flag is seen, fn is called with the value of the flag.
+// If fn returns a non-nil error, it will be treated as a flag value parsing error.
+func (f *FlagSet) Func(name, usage string, fn func(string) error) {
+ f.Var(funcValue(fn), name, usage)
+}
+
+// Func defines a flag with the specified name and usage string.
+// Each time the flag is seen, fn is called with the value of the flag.
+// If fn returns a non-nil error, it will be treated as a flag value parsing error.
+func Func(name, usage string, fn func(string) error) {
+ CommandLine.Func(name, usage, fn)
+}
+
+// BoolFunc defines a flag with the specified name and usage string without requiring values.
+// Each time the flag is seen, fn is called with the value of the flag.
+// If fn returns a non-nil error, it will be treated as a flag value parsing error.
+func (f *FlagSet) BoolFunc(name, usage string, fn func(string) error) {
+ f.Var(boolFuncValue(fn), name, usage)
+}
+
+// BoolFunc defines a flag with the specified name and usage string without requiring values.
+// Each time the flag is seen, fn is called with the value of the flag.
+// If fn returns a non-nil error, it will be treated as a flag value parsing error.
+func BoolFunc(name, usage string, fn func(string) error) {
+ CommandLine.BoolFunc(name, usage, fn)
+}
+
+// Var defines a flag with the specified name and usage string. The type and
+// value of the flag are represented by the first argument, of type Value, which
+// typically holds a user-defined implementation of Value. For instance, the
+// caller could create a flag that turns a comma-separated string into a slice
+// of strings by giving the slice the methods of Value; in particular, Set would
+// decompose the comma-separated string into the slice.
+func (f *FlagSet) Var(value Value, name string, usage string) {
+ // Flag must not begin "-" or contain "=".
+ if strings.HasPrefix(name, "-") {
+ panic(f.sprintf("flag %q begins with -", name))
+ } else if strings.Contains(name, "=") {
+ panic(f.sprintf("flag %q contains =", name))
+ }
+
+ // Remember the default value as a string; it won't change.
+ flag := &Flag{name, usage, value, value.String()}
+ _, alreadythere := f.formal[name]
+ if alreadythere {
+ var msg string
+ if f.name == "" {
+ msg = f.sprintf("flag redefined: %s", name)
+ } else {
+ msg = f.sprintf("%s flag redefined: %s", f.name, name)
+ }
+ panic(msg) // Happens only if flags are declared with identical names
+ }
+ if pos := f.undef[name]; pos != "" {
+ panic(fmt.Sprintf("flag %s set at %s before being defined", name, pos))
+ }
+ if f.formal == nil {
+ f.formal = make(map[string]*Flag)
+ }
+ f.formal[name] = flag
+}
+
+// Var defines a flag with the specified name and usage string. The type and
+// value of the flag are represented by the first argument, of type Value, which
+// typically holds a user-defined implementation of Value. For instance, the
+// caller could create a flag that turns a comma-separated string into a slice
+// of strings by giving the slice the methods of Value; in particular, Set would
+// decompose the comma-separated string into the slice.
+func Var(value Value, name string, usage string) {
+ CommandLine.Var(value, name, usage)
+}
+
+// sprintf formats the message, prints it to output, and returns it.
+func (f *FlagSet) sprintf(format string, a ...any) string {
+ msg := fmt.Sprintf(format, a...)
+ fmt.Fprintln(f.Output(), msg)
+ return msg
+}
+
+// failf prints to standard error a formatted error and usage message and
+// returns the error.
+func (f *FlagSet) failf(format string, a ...any) error {
+ msg := f.sprintf(format, a...)
+ f.usage()
+ return errors.New(msg)
+}
+
+// usage calls the Usage method for the flag set if one is specified,
+// or the appropriate default usage function otherwise.
+func (f *FlagSet) usage() {
+ if f.Usage == nil {
+ f.defaultUsage()
+ } else {
+ f.Usage()
+ }
+}
+
+// parseOne parses one flag. It reports whether a flag was seen.
+func (f *FlagSet) parseOne() (bool, error) {
+ if len(f.args) == 0 {
+ return false, nil
+ }
+ s := f.args[0]
+ if len(s) < 2 || s[0] != '-' {
+ return false, nil
+ }
+ numMinuses := 1
+ if s[1] == '-' {
+ numMinuses++
+ if len(s) == 2 { // "--" terminates the flags
+ f.args = f.args[1:]
+ return false, nil
+ }
+ }
+ name := s[numMinuses:]
+ if len(name) == 0 || name[0] == '-' || name[0] == '=' {
+ return false, f.failf("bad flag syntax: %s", s)
+ }
+
+ // it's a flag. does it have an argument?
+ f.args = f.args[1:]
+ hasValue := false
+ value := ""
+ for i := 1; i < len(name); i++ { // equals cannot be first
+ if name[i] == '=' {
+ value = name[i+1:]
+ hasValue = true
+ name = name[0:i]
+ break
+ }
+ }
+
+ flag, ok := f.formal[name]
+ if !ok {
+ if name == "help" || name == "h" { // special case for nice help message.
+ f.usage()
+ return false, ErrHelp
+ }
+ return false, f.failf("flag provided but not defined: -%s", name)
+ }
+
+ if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
+ if hasValue {
+ if err := fv.Set(value); err != nil {
+ return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
+ }
+ } else {
+ if err := fv.Set("true"); err != nil {
+ return false, f.failf("invalid boolean flag %s: %v", name, err)
+ }
+ }
+ } else {
+ // It must have a value, which might be the next argument.
+ if !hasValue && len(f.args) > 0 {
+ // value is the next arg
+ hasValue = true
+ value, f.args = f.args[0], f.args[1:]
+ }
+ if !hasValue {
+ return false, f.failf("flag needs an argument: -%s", name)
+ }
+ if err := flag.Value.Set(value); err != nil {
+ return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
+ }
+ }
+ if f.actual == nil {
+ f.actual = make(map[string]*Flag)
+ }
+ f.actual[name] = flag
+ return true, nil
+}
+
+// Parse parses flag definitions from the argument list, which should not
+// include the command name. Must be called after all flags in the FlagSet
+// are defined and before flags are accessed by the program.
+// The return value will be ErrHelp if -help or -h were set but not defined.
+func (f *FlagSet) Parse(arguments []string) error {
+ f.parsed = true
+ f.args = arguments
+ for {
+ seen, err := f.parseOne()
+ if seen {
+ continue
+ }
+ if err == nil {
+ break
+ }
+ switch f.errorHandling {
+ case ContinueOnError:
+ return err
+ case ExitOnError:
+ if err == ErrHelp {
+ os.Exit(0)
+ }
+ os.Exit(2)
+ case PanicOnError:
+ panic(err)
+ }
+ }
+ return nil
+}
+
+// Parsed reports whether f.Parse has been called.
+func (f *FlagSet) Parsed() bool {
+ return f.parsed
+}
+
+// Parse parses the command-line flags from os.Args[1:]. Must be called
+// after all flags are defined and before flags are accessed by the program.
+func Parse() {
+ // Ignore errors; CommandLine is set for ExitOnError.
+ CommandLine.Parse(os.Args[1:])
+}
+
+// Parsed reports whether the command-line flags have been parsed.
+func Parsed() bool {
+ return CommandLine.Parsed()
+}
+
+// CommandLine is the default set of command-line flags, parsed from os.Args.
+// The top-level functions such as BoolVar, Arg, and so on are wrappers for the
+// methods of CommandLine.
+var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
+
+func init() {
+ // Override generic FlagSet default Usage with call to global Usage.
+ // Note: This is not CommandLine.Usage = Usage,
+ // because we want any eventual call to use any updated value of Usage,
+ // not the value it has when this line is run.
+ CommandLine.Usage = commandLineUsage
+}
+
+func commandLineUsage() {
+ Usage()
+}
+
+// NewFlagSet returns a new, empty flag set with the specified name and
+// error handling property. If the name is not empty, it will be printed
+// in the default usage message and in error messages.
+func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
+ f := &FlagSet{
+ name: name,
+ errorHandling: errorHandling,
+ }
+ f.Usage = f.defaultUsage
+ return f
+}
+
+// Init sets the name and error handling property for a flag set.
+// By default, the zero FlagSet uses an empty name and the
+// ContinueOnError error handling policy.
+func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
+ f.name = name
+ f.errorHandling = errorHandling
+}
diff --git a/contrib/go/_std_1.21/src/flag/ya.make b/contrib/go/_std_1.21/src/flag/ya.make
new file mode 100644
index 0000000000..821469a8a4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/flag/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ flag.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ example_func_test.go
+ example_test.go
+ example_textvar_test.go
+ example_value_test.go
+ flag_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/fmt/doc.go b/contrib/go/_std_1.21/src/fmt/doc.go
index 9785ed9526..9785ed9526 100644
--- a/contrib/go/_std_1.20/src/fmt/doc.go
+++ b/contrib/go/_std_1.21/src/fmt/doc.go
diff --git a/contrib/go/_std_1.20/src/fmt/errors.go b/contrib/go/_std_1.21/src/fmt/errors.go
index 1fbd39f8f1..1fbd39f8f1 100644
--- a/contrib/go/_std_1.20/src/fmt/errors.go
+++ b/contrib/go/_std_1.21/src/fmt/errors.go
diff --git a/contrib/go/_std_1.20/src/fmt/format.go b/contrib/go/_std_1.21/src/fmt/format.go
index 617f78f15e..617f78f15e 100644
--- a/contrib/go/_std_1.20/src/fmt/format.go
+++ b/contrib/go/_std_1.21/src/fmt/format.go
diff --git a/contrib/go/_std_1.21/src/fmt/print.go b/contrib/go/_std_1.21/src/fmt/print.go
new file mode 100644
index 0000000000..9c3bd3efec
--- /dev/null
+++ b/contrib/go/_std_1.21/src/fmt/print.go
@@ -0,0 +1,1226 @@
+// Copyright 2009 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 fmt
+
+import (
+ "internal/fmtsort"
+ "io"
+ "os"
+ "reflect"
+ "strconv"
+ "sync"
+ "unicode/utf8"
+)
+
+// Strings for use with buffer.WriteString.
+// This is less overhead than using buffer.Write with byte arrays.
+const (
+ commaSpaceString = ", "
+ nilAngleString = "<nil>"
+ nilParenString = "(nil)"
+ nilString = "nil"
+ mapString = "map["
+ percentBangString = "%!"
+ missingString = "(MISSING)"
+ badIndexString = "(BADINDEX)"
+ panicString = "(PANIC="
+ extraString = "%!(EXTRA "
+ badWidthString = "%!(BADWIDTH)"
+ badPrecString = "%!(BADPREC)"
+ noVerbString = "%!(NOVERB)"
+ invReflectString = "<invalid reflect.Value>"
+)
+
+// State represents the printer state passed to custom formatters.
+// It provides access to the io.Writer interface plus information about
+// the flags and options for the operand's format specifier.
+type State interface {
+ // Write is the function to call to emit formatted output to be printed.
+ Write(b []byte) (n int, err error)
+ // Width returns the value of the width option and whether it has been set.
+ Width() (wid int, ok bool)
+ // Precision returns the value of the precision option and whether it has been set.
+ Precision() (prec int, ok bool)
+
+ // Flag reports whether the flag c, a character, has been set.
+ Flag(c int) bool
+}
+
+// Formatter is implemented by any value that has a Format method.
+// The implementation controls how State and rune are interpreted,
+// and may call Sprint() or Fprint(f) etc. to generate its output.
+type Formatter interface {
+ Format(f State, verb rune)
+}
+
+// Stringer is implemented by any value that has a String method,
+// which defines the “native” format for that value.
+// The String method is used to print values passed as an operand
+// to any format that accepts a string or to an unformatted printer
+// such as Print.
+type Stringer interface {
+ String() string
+}
+
+// GoStringer is implemented by any value that has a GoString method,
+// which defines the Go syntax for that value.
+// The GoString method is used to print values passed as an operand
+// to a %#v format.
+type GoStringer interface {
+ GoString() string
+}
+
+// FormatString returns a string representing the fully qualified formatting
+// directive captured by the State, followed by the argument verb. (State does not
+// itself contain the verb.) The result has a leading percent sign followed by any
+// flags, the width, and the precision. Missing flags, width, and precision are
+// omitted. This function allows a Formatter to reconstruct the original
+// directive triggering the call to Format.
+func FormatString(state State, verb rune) string {
+ var tmp [16]byte // Use a local buffer.
+ b := append(tmp[:0], '%')
+ for _, c := range " +-#0" { // All known flags
+ if state.Flag(int(c)) { // The argument is an int for historical reasons.
+ b = append(b, byte(c))
+ }
+ }
+ if w, ok := state.Width(); ok {
+ b = strconv.AppendInt(b, int64(w), 10)
+ }
+ if p, ok := state.Precision(); ok {
+ b = append(b, '.')
+ b = strconv.AppendInt(b, int64(p), 10)
+ }
+ b = utf8.AppendRune(b, verb)
+ return string(b)
+}
+
+// Use simple []byte instead of bytes.Buffer to avoid large dependency.
+type buffer []byte
+
+func (b *buffer) write(p []byte) {
+ *b = append(*b, p...)
+}
+
+func (b *buffer) writeString(s string) {
+ *b = append(*b, s...)
+}
+
+func (b *buffer) writeByte(c byte) {
+ *b = append(*b, c)
+}
+
+func (bp *buffer) writeRune(r rune) {
+ *bp = utf8.AppendRune(*bp, r)
+}
+
+// pp is used to store a printer's state and is reused with sync.Pool to avoid allocations.
+type pp struct {
+ buf buffer
+
+ // arg holds the current item, as an interface{}.
+ arg any
+
+ // value is used instead of arg for reflect values.
+ value reflect.Value
+
+ // fmt is used to format basic items such as integers or strings.
+ fmt fmt
+
+ // reordered records whether the format string used argument reordering.
+ reordered bool
+ // goodArgNum records whether the most recent reordering directive was valid.
+ goodArgNum bool
+ // panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion.
+ panicking bool
+ // erroring is set when printing an error string to guard against calling handleMethods.
+ erroring bool
+ // wrapErrs is set when the format string may contain a %w verb.
+ wrapErrs bool
+ // wrappedErrs records the targets of the %w verb.
+ wrappedErrs []int
+}
+
+var ppFree = sync.Pool{
+ New: func() any { return new(pp) },
+}
+
+// newPrinter allocates a new pp struct or grabs a cached one.
+func newPrinter() *pp {
+ p := ppFree.Get().(*pp)
+ p.panicking = false
+ p.erroring = false
+ p.wrapErrs = false
+ p.fmt.init(&p.buf)
+ return p
+}
+
+// free saves used pp structs in ppFree; avoids an allocation per invocation.
+func (p *pp) free() {
+ // Proper usage of a sync.Pool requires each entry to have approximately
+ // the same memory cost. To obtain this property when the stored type
+ // contains a variably-sized buffer, we add a hard limit on the maximum
+ // buffer to place back in the pool. If the buffer is larger than the
+ // limit, we drop the buffer and recycle just the printer.
+ //
+ // See https://golang.org/issue/23199.
+ if cap(p.buf) > 64*1024 {
+ p.buf = nil
+ } else {
+ p.buf = p.buf[:0]
+ }
+ if cap(p.wrappedErrs) > 8 {
+ p.wrappedErrs = nil
+ }
+
+ p.arg = nil
+ p.value = reflect.Value{}
+ p.wrappedErrs = p.wrappedErrs[:0]
+ ppFree.Put(p)
+}
+
+func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
+
+func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
+
+func (p *pp) Flag(b int) bool {
+ switch b {
+ case '-':
+ return p.fmt.minus
+ case '+':
+ return p.fmt.plus || p.fmt.plusV
+ case '#':
+ return p.fmt.sharp || p.fmt.sharpV
+ case ' ':
+ return p.fmt.space
+ case '0':
+ return p.fmt.zero
+ }
+ return false
+}
+
+// Implement Write so we can call Fprintf on a pp (through State), for
+// recursive use in custom verbs.
+func (p *pp) Write(b []byte) (ret int, err error) {
+ p.buf.write(b)
+ return len(b), nil
+}
+
+// Implement WriteString so that we can call io.WriteString
+// on a pp (through state), for efficiency.
+func (p *pp) WriteString(s string) (ret int, err error) {
+ p.buf.writeString(s)
+ return len(s), nil
+}
+
+// These routines end in 'f' and take a format string.
+
+// Fprintf formats according to a format specifier and writes to w.
+// It returns the number of bytes written and any write error encountered.
+func Fprintf(w io.Writer, format string, a ...any) (n int, err error) {
+ p := newPrinter()
+ p.doPrintf(format, a)
+ n, err = w.Write(p.buf)
+ p.free()
+ return
+}
+
+// Printf formats according to a format specifier and writes to standard output.
+// It returns the number of bytes written and any write error encountered.
+func Printf(format string, a ...any) (n int, err error) {
+ return Fprintf(os.Stdout, format, a...)
+}
+
+// Sprintf formats according to a format specifier and returns the resulting string.
+func Sprintf(format string, a ...any) string {
+ p := newPrinter()
+ p.doPrintf(format, a)
+ s := string(p.buf)
+ p.free()
+ return s
+}
+
+// Appendf formats according to a format specifier, appends the result to the byte
+// slice, and returns the updated slice.
+func Appendf(b []byte, format string, a ...any) []byte {
+ p := newPrinter()
+ p.doPrintf(format, a)
+ b = append(b, p.buf...)
+ p.free()
+ return b
+}
+
+// These routines do not take a format string
+
+// Fprint formats using the default formats for its operands and writes to w.
+// Spaces are added between operands when neither is a string.
+// It returns the number of bytes written and any write error encountered.
+func Fprint(w io.Writer, a ...any) (n int, err error) {
+ p := newPrinter()
+ p.doPrint(a)
+ n, err = w.Write(p.buf)
+ p.free()
+ return
+}
+
+// Print formats using the default formats for its operands and writes to standard output.
+// Spaces are added between operands when neither is a string.
+// It returns the number of bytes written and any write error encountered.
+func Print(a ...any) (n int, err error) {
+ return Fprint(os.Stdout, a...)
+}
+
+// Sprint formats using the default formats for its operands and returns the resulting string.
+// Spaces are added between operands when neither is a string.
+func Sprint(a ...any) string {
+ p := newPrinter()
+ p.doPrint(a)
+ s := string(p.buf)
+ p.free()
+ return s
+}
+
+// Append formats using the default formats for its operands, appends the result to
+// the byte slice, and returns the updated slice.
+func Append(b []byte, a ...any) []byte {
+ p := newPrinter()
+ p.doPrint(a)
+ b = append(b, p.buf...)
+ p.free()
+ return b
+}
+
+// These routines end in 'ln', do not take a format string,
+// always add spaces between operands, and add a newline
+// after the last operand.
+
+// Fprintln formats using the default formats for its operands and writes to w.
+// Spaces are always added between operands and a newline is appended.
+// It returns the number of bytes written and any write error encountered.
+func Fprintln(w io.Writer, a ...any) (n int, err error) {
+ p := newPrinter()
+ p.doPrintln(a)
+ n, err = w.Write(p.buf)
+ p.free()
+ return
+}
+
+// Println formats using the default formats for its operands and writes to standard output.
+// Spaces are always added between operands and a newline is appended.
+// It returns the number of bytes written and any write error encountered.
+func Println(a ...any) (n int, err error) {
+ return Fprintln(os.Stdout, a...)
+}
+
+// Sprintln formats using the default formats for its operands and returns the resulting string.
+// Spaces are always added between operands and a newline is appended.
+func Sprintln(a ...any) string {
+ p := newPrinter()
+ p.doPrintln(a)
+ s := string(p.buf)
+ p.free()
+ return s
+}
+
+// Appendln formats using the default formats for its operands, appends the result
+// to the byte slice, and returns the updated slice. Spaces are always added
+// between operands and a newline is appended.
+func Appendln(b []byte, a ...any) []byte {
+ p := newPrinter()
+ p.doPrintln(a)
+ b = append(b, p.buf...)
+ p.free()
+ return b
+}
+
+// getField gets the i'th field of the struct value.
+// If the field is itself is an interface, return a value for
+// the thing inside the interface, not the interface itself.
+func getField(v reflect.Value, i int) reflect.Value {
+ val := v.Field(i)
+ if val.Kind() == reflect.Interface && !val.IsNil() {
+ val = val.Elem()
+ }
+ return val
+}
+
+// tooLarge reports whether the magnitude of the integer is
+// too large to be used as a formatting width or precision.
+func tooLarge(x int) bool {
+ const max int = 1e6
+ return x > max || x < -max
+}
+
+// parsenum converts ASCII to integer. num is 0 (and isnum is false) if no number present.
+func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
+ if start >= end {
+ return 0, false, end
+ }
+ for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
+ if tooLarge(num) {
+ return 0, false, end // Overflow; crazy long number most likely.
+ }
+ num = num*10 + int(s[newi]-'0')
+ isnum = true
+ }
+ return
+}
+
+func (p *pp) unknownType(v reflect.Value) {
+ if !v.IsValid() {
+ p.buf.writeString(nilAngleString)
+ return
+ }
+ p.buf.writeByte('?')
+ p.buf.writeString(v.Type().String())
+ p.buf.writeByte('?')
+}
+
+func (p *pp) badVerb(verb rune) {
+ p.erroring = true
+ p.buf.writeString(percentBangString)
+ p.buf.writeRune(verb)
+ p.buf.writeByte('(')
+ switch {
+ case p.arg != nil:
+ p.buf.writeString(reflect.TypeOf(p.arg).String())
+ p.buf.writeByte('=')
+ p.printArg(p.arg, 'v')
+ case p.value.IsValid():
+ p.buf.writeString(p.value.Type().String())
+ p.buf.writeByte('=')
+ p.printValue(p.value, 'v', 0)
+ default:
+ p.buf.writeString(nilAngleString)
+ }
+ p.buf.writeByte(')')
+ p.erroring = false
+}
+
+func (p *pp) fmtBool(v bool, verb rune) {
+ switch verb {
+ case 't', 'v':
+ p.fmt.fmtBoolean(v)
+ default:
+ p.badVerb(verb)
+ }
+}
+
+// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
+// not, as requested, by temporarily setting the sharp flag.
+func (p *pp) fmt0x64(v uint64, leading0x bool) {
+ sharp := p.fmt.sharp
+ p.fmt.sharp = leading0x
+ p.fmt.fmtInteger(v, 16, unsigned, 'v', ldigits)
+ p.fmt.sharp = sharp
+}
+
+// fmtInteger formats a signed or unsigned integer.
+func (p *pp) fmtInteger(v uint64, isSigned bool, verb rune) {
+ switch verb {
+ case 'v':
+ if p.fmt.sharpV && !isSigned {
+ p.fmt0x64(v, true)
+ } else {
+ p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
+ }
+ case 'd':
+ p.fmt.fmtInteger(v, 10, isSigned, verb, ldigits)
+ case 'b':
+ p.fmt.fmtInteger(v, 2, isSigned, verb, ldigits)
+ case 'o', 'O':
+ p.fmt.fmtInteger(v, 8, isSigned, verb, ldigits)
+ case 'x':
+ p.fmt.fmtInteger(v, 16, isSigned, verb, ldigits)
+ case 'X':
+ p.fmt.fmtInteger(v, 16, isSigned, verb, udigits)
+ case 'c':
+ p.fmt.fmtC(v)
+ case 'q':
+ p.fmt.fmtQc(v)
+ case 'U':
+ p.fmt.fmtUnicode(v)
+ default:
+ p.badVerb(verb)
+ }
+}
+
+// fmtFloat formats a float. The default precision for each verb
+// is specified as last argument in the call to fmt_float.
+func (p *pp) fmtFloat(v float64, size int, verb rune) {
+ switch verb {
+ case 'v':
+ p.fmt.fmtFloat(v, size, 'g', -1)
+ case 'b', 'g', 'G', 'x', 'X':
+ p.fmt.fmtFloat(v, size, verb, -1)
+ case 'f', 'e', 'E':
+ p.fmt.fmtFloat(v, size, verb, 6)
+ case 'F':
+ p.fmt.fmtFloat(v, size, 'f', 6)
+ default:
+ p.badVerb(verb)
+ }
+}
+
+// fmtComplex formats a complex number v with
+// r = real(v) and j = imag(v) as (r+ji) using
+// fmtFloat for r and j formatting.
+func (p *pp) fmtComplex(v complex128, size int, verb rune) {
+ // Make sure any unsupported verbs are found before the
+ // calls to fmtFloat to not generate an incorrect error string.
+ switch verb {
+ case 'v', 'b', 'g', 'G', 'x', 'X', 'f', 'F', 'e', 'E':
+ oldPlus := p.fmt.plus
+ p.buf.writeByte('(')
+ p.fmtFloat(real(v), size/2, verb)
+ // Imaginary part always has a sign.
+ p.fmt.plus = true
+ p.fmtFloat(imag(v), size/2, verb)
+ p.buf.writeString("i)")
+ p.fmt.plus = oldPlus
+ default:
+ p.badVerb(verb)
+ }
+}
+
+func (p *pp) fmtString(v string, verb rune) {
+ switch verb {
+ case 'v':
+ if p.fmt.sharpV {
+ p.fmt.fmtQ(v)
+ } else {
+ p.fmt.fmtS(v)
+ }
+ case 's':
+ p.fmt.fmtS(v)
+ case 'x':
+ p.fmt.fmtSx(v, ldigits)
+ case 'X':
+ p.fmt.fmtSx(v, udigits)
+ case 'q':
+ p.fmt.fmtQ(v)
+ default:
+ p.badVerb(verb)
+ }
+}
+
+func (p *pp) fmtBytes(v []byte, verb rune, typeString string) {
+ switch verb {
+ case 'v', 'd':
+ if p.fmt.sharpV {
+ p.buf.writeString(typeString)
+ if v == nil {
+ p.buf.writeString(nilParenString)
+ return
+ }
+ p.buf.writeByte('{')
+ for i, c := range v {
+ if i > 0 {
+ p.buf.writeString(commaSpaceString)
+ }
+ p.fmt0x64(uint64(c), true)
+ }
+ p.buf.writeByte('}')
+ } else {
+ p.buf.writeByte('[')
+ for i, c := range v {
+ if i > 0 {
+ p.buf.writeByte(' ')
+ }
+ p.fmt.fmtInteger(uint64(c), 10, unsigned, verb, ldigits)
+ }
+ p.buf.writeByte(']')
+ }
+ case 's':
+ p.fmt.fmtBs(v)
+ case 'x':
+ p.fmt.fmtBx(v, ldigits)
+ case 'X':
+ p.fmt.fmtBx(v, udigits)
+ case 'q':
+ p.fmt.fmtQ(string(v))
+ default:
+ p.printValue(reflect.ValueOf(v), verb, 0)
+ }
+}
+
+func (p *pp) fmtPointer(value reflect.Value, verb rune) {
+ var u uintptr
+ switch value.Kind() {
+ case reflect.Chan, reflect.Func, reflect.Map, reflect.Pointer, reflect.Slice, reflect.UnsafePointer:
+ u = value.Pointer()
+ default:
+ p.badVerb(verb)
+ return
+ }
+
+ switch verb {
+ case 'v':
+ if p.fmt.sharpV {
+ p.buf.writeByte('(')
+ p.buf.writeString(value.Type().String())
+ p.buf.writeString(")(")
+ if u == 0 {
+ p.buf.writeString(nilString)
+ } else {
+ p.fmt0x64(uint64(u), true)
+ }
+ p.buf.writeByte(')')
+ } else {
+ if u == 0 {
+ p.fmt.padString(nilAngleString)
+ } else {
+ p.fmt0x64(uint64(u), !p.fmt.sharp)
+ }
+ }
+ case 'p':
+ p.fmt0x64(uint64(u), !p.fmt.sharp)
+ case 'b', 'o', 'd', 'x', 'X':
+ p.fmtInteger(uint64(u), unsigned, verb)
+ default:
+ p.badVerb(verb)
+ }
+}
+
+func (p *pp) catchPanic(arg any, verb rune, method string) {
+ if err := recover(); err != nil {
+ // If it's a nil pointer, just say "<nil>". The likeliest causes are a
+ // Stringer that fails to guard against nil or a nil pointer for a
+ // value receiver, and in either case, "<nil>" is a nice result.
+ if v := reflect.ValueOf(arg); v.Kind() == reflect.Pointer && v.IsNil() {
+ p.buf.writeString(nilAngleString)
+ return
+ }
+ // Otherwise print a concise panic message. Most of the time the panic
+ // value will print itself nicely.
+ if p.panicking {
+ // Nested panics; the recursion in printArg cannot succeed.
+ panic(err)
+ }
+
+ oldFlags := p.fmt.fmtFlags
+ // For this output we want default behavior.
+ p.fmt.clearflags()
+
+ p.buf.writeString(percentBangString)
+ p.buf.writeRune(verb)
+ p.buf.writeString(panicString)
+ p.buf.writeString(method)
+ p.buf.writeString(" method: ")
+ p.panicking = true
+ p.printArg(err, 'v')
+ p.panicking = false
+ p.buf.writeByte(')')
+
+ p.fmt.fmtFlags = oldFlags
+ }
+}
+
+func (p *pp) handleMethods(verb rune) (handled bool) {
+ if p.erroring {
+ return
+ }
+ if verb == 'w' {
+ // It is invalid to use %w other than with Errorf or with a non-error arg.
+ _, ok := p.arg.(error)
+ if !ok || !p.wrapErrs {
+ p.badVerb(verb)
+ return true
+ }
+ // If the arg is a Formatter, pass 'v' as the verb to it.
+ verb = 'v'
+ }
+
+ // Is it a Formatter?
+ if formatter, ok := p.arg.(Formatter); ok {
+ handled = true
+ defer p.catchPanic(p.arg, verb, "Format")
+ formatter.Format(p, verb)
+ return
+ }
+
+ // If we're doing Go syntax and the argument knows how to supply it, take care of it now.
+ if p.fmt.sharpV {
+ if stringer, ok := p.arg.(GoStringer); ok {
+ handled = true
+ defer p.catchPanic(p.arg, verb, "GoString")
+ // Print the result of GoString unadorned.
+ p.fmt.fmtS(stringer.GoString())
+ return
+ }
+ } else {
+ // If a string is acceptable according to the format, see if
+ // the value satisfies one of the string-valued interfaces.
+ // Println etc. set verb to %v, which is "stringable".
+ switch verb {
+ case 'v', 's', 'x', 'X', 'q':
+ // Is it an error or Stringer?
+ // The duplication in the bodies is necessary:
+ // setting handled and deferring catchPanic
+ // must happen before calling the method.
+ switch v := p.arg.(type) {
+ case error:
+ handled = true
+ defer p.catchPanic(p.arg, verb, "Error")
+ p.fmtString(v.Error(), verb)
+ return
+
+ case Stringer:
+ handled = true
+ defer p.catchPanic(p.arg, verb, "String")
+ p.fmtString(v.String(), verb)
+ return
+ }
+ }
+ }
+ return false
+}
+
+func (p *pp) printArg(arg any, verb rune) {
+ p.arg = arg
+ p.value = reflect.Value{}
+
+ if arg == nil {
+ switch verb {
+ case 'T', 'v':
+ p.fmt.padString(nilAngleString)
+ default:
+ p.badVerb(verb)
+ }
+ return
+ }
+
+ // Special processing considerations.
+ // %T (the value's type) and %p (its address) are special; we always do them first.
+ switch verb {
+ case 'T':
+ p.fmt.fmtS(reflect.TypeOf(arg).String())
+ return
+ case 'p':
+ p.fmtPointer(reflect.ValueOf(arg), 'p')
+ return
+ }
+
+ // Some types can be done without reflection.
+ switch f := arg.(type) {
+ case bool:
+ p.fmtBool(f, verb)
+ case float32:
+ p.fmtFloat(float64(f), 32, verb)
+ case float64:
+ p.fmtFloat(f, 64, verb)
+ case complex64:
+ p.fmtComplex(complex128(f), 64, verb)
+ case complex128:
+ p.fmtComplex(f, 128, verb)
+ case int:
+ p.fmtInteger(uint64(f), signed, verb)
+ case int8:
+ p.fmtInteger(uint64(f), signed, verb)
+ case int16:
+ p.fmtInteger(uint64(f), signed, verb)
+ case int32:
+ p.fmtInteger(uint64(f), signed, verb)
+ case int64:
+ p.fmtInteger(uint64(f), signed, verb)
+ case uint:
+ p.fmtInteger(uint64(f), unsigned, verb)
+ case uint8:
+ p.fmtInteger(uint64(f), unsigned, verb)
+ case uint16:
+ p.fmtInteger(uint64(f), unsigned, verb)
+ case uint32:
+ p.fmtInteger(uint64(f), unsigned, verb)
+ case uint64:
+ p.fmtInteger(f, unsigned, verb)
+ case uintptr:
+ p.fmtInteger(uint64(f), unsigned, verb)
+ case string:
+ p.fmtString(f, verb)
+ case []byte:
+ p.fmtBytes(f, verb, "[]byte")
+ case reflect.Value:
+ // Handle extractable values with special methods
+ // since printValue does not handle them at depth 0.
+ if f.IsValid() && f.CanInterface() {
+ p.arg = f.Interface()
+ if p.handleMethods(verb) {
+ return
+ }
+ }
+ p.printValue(f, verb, 0)
+ default:
+ // If the type is not simple, it might have methods.
+ if !p.handleMethods(verb) {
+ // Need to use reflection, since the type had no
+ // interface methods that could be used for formatting.
+ p.printValue(reflect.ValueOf(f), verb, 0)
+ }
+ }
+}
+
+// printValue is similar to printArg but starts with a reflect value, not an interface{} value.
+// It does not handle 'p' and 'T' verbs because these should have been already handled by printArg.
+func (p *pp) printValue(value reflect.Value, verb rune, depth int) {
+ // Handle values with special methods if not already handled by printArg (depth == 0).
+ if depth > 0 && value.IsValid() && value.CanInterface() {
+ p.arg = value.Interface()
+ if p.handleMethods(verb) {
+ return
+ }
+ }
+ p.arg = nil
+ p.value = value
+
+ switch f := value; value.Kind() {
+ case reflect.Invalid:
+ if depth == 0 {
+ p.buf.writeString(invReflectString)
+ } else {
+ switch verb {
+ case 'v':
+ p.buf.writeString(nilAngleString)
+ default:
+ p.badVerb(verb)
+ }
+ }
+ case reflect.Bool:
+ p.fmtBool(f.Bool(), verb)
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p.fmtInteger(uint64(f.Int()), signed, verb)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p.fmtInteger(f.Uint(), unsigned, verb)
+ case reflect.Float32:
+ p.fmtFloat(f.Float(), 32, verb)
+ case reflect.Float64:
+ p.fmtFloat(f.Float(), 64, verb)
+ case reflect.Complex64:
+ p.fmtComplex(f.Complex(), 64, verb)
+ case reflect.Complex128:
+ p.fmtComplex(f.Complex(), 128, verb)
+ case reflect.String:
+ p.fmtString(f.String(), verb)
+ case reflect.Map:
+ if p.fmt.sharpV {
+ p.buf.writeString(f.Type().String())
+ if f.IsNil() {
+ p.buf.writeString(nilParenString)
+ return
+ }
+ p.buf.writeByte('{')
+ } else {
+ p.buf.writeString(mapString)
+ }
+ sorted := fmtsort.Sort(f)
+ for i, key := range sorted.Key {
+ if i > 0 {
+ if p.fmt.sharpV {
+ p.buf.writeString(commaSpaceString)
+ } else {
+ p.buf.writeByte(' ')
+ }
+ }
+ p.printValue(key, verb, depth+1)
+ p.buf.writeByte(':')
+ p.printValue(sorted.Value[i], verb, depth+1)
+ }
+ if p.fmt.sharpV {
+ p.buf.writeByte('}')
+ } else {
+ p.buf.writeByte(']')
+ }
+ case reflect.Struct:
+ if p.fmt.sharpV {
+ p.buf.writeString(f.Type().String())
+ }
+ p.buf.writeByte('{')
+ for i := 0; i < f.NumField(); i++ {
+ if i > 0 {
+ if p.fmt.sharpV {
+ p.buf.writeString(commaSpaceString)
+ } else {
+ p.buf.writeByte(' ')
+ }
+ }
+ if p.fmt.plusV || p.fmt.sharpV {
+ if name := f.Type().Field(i).Name; name != "" {
+ p.buf.writeString(name)
+ p.buf.writeByte(':')
+ }
+ }
+ p.printValue(getField(f, i), verb, depth+1)
+ }
+ p.buf.writeByte('}')
+ case reflect.Interface:
+ value := f.Elem()
+ if !value.IsValid() {
+ if p.fmt.sharpV {
+ p.buf.writeString(f.Type().String())
+ p.buf.writeString(nilParenString)
+ } else {
+ p.buf.writeString(nilAngleString)
+ }
+ } else {
+ p.printValue(value, verb, depth+1)
+ }
+ case reflect.Array, reflect.Slice:
+ switch verb {
+ case 's', 'q', 'x', 'X':
+ // Handle byte and uint8 slices and arrays special for the above verbs.
+ t := f.Type()
+ if t.Elem().Kind() == reflect.Uint8 {
+ var bytes []byte
+ if f.Kind() == reflect.Slice {
+ bytes = f.Bytes()
+ } else if f.CanAddr() {
+ bytes = f.Slice(0, f.Len()).Bytes()
+ } else {
+ // We have an array, but we cannot Slice() a non-addressable array,
+ // so we build a slice by hand. This is a rare case but it would be nice
+ // if reflection could help a little more.
+ bytes = make([]byte, f.Len())
+ for i := range bytes {
+ bytes[i] = byte(f.Index(i).Uint())
+ }
+ }
+ p.fmtBytes(bytes, verb, t.String())
+ return
+ }
+ }
+ if p.fmt.sharpV {
+ p.buf.writeString(f.Type().String())
+ if f.Kind() == reflect.Slice && f.IsNil() {
+ p.buf.writeString(nilParenString)
+ return
+ }
+ p.buf.writeByte('{')
+ for i := 0; i < f.Len(); i++ {
+ if i > 0 {
+ p.buf.writeString(commaSpaceString)
+ }
+ p.printValue(f.Index(i), verb, depth+1)
+ }
+ p.buf.writeByte('}')
+ } else {
+ p.buf.writeByte('[')
+ for i := 0; i < f.Len(); i++ {
+ if i > 0 {
+ p.buf.writeByte(' ')
+ }
+ p.printValue(f.Index(i), verb, depth+1)
+ }
+ p.buf.writeByte(']')
+ }
+ case reflect.Pointer:
+ // pointer to array or slice or struct? ok at top level
+ // but not embedded (avoid loops)
+ if depth == 0 && f.Pointer() != 0 {
+ switch a := f.Elem(); a.Kind() {
+ case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map:
+ p.buf.writeByte('&')
+ p.printValue(a, verb, depth+1)
+ return
+ }
+ }
+ fallthrough
+ case reflect.Chan, reflect.Func, reflect.UnsafePointer:
+ p.fmtPointer(f, verb)
+ default:
+ p.unknownType(f)
+ }
+}
+
+// intFromArg gets the argNumth element of a. On return, isInt reports whether the argument has integer type.
+func intFromArg(a []any, argNum int) (num int, isInt bool, newArgNum int) {
+ newArgNum = argNum
+ if argNum < len(a) {
+ num, isInt = a[argNum].(int) // Almost always OK.
+ if !isInt {
+ // Work harder.
+ switch v := reflect.ValueOf(a[argNum]); v.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ n := v.Int()
+ if int64(int(n)) == n {
+ num = int(n)
+ isInt = true
+ }
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ n := v.Uint()
+ if int64(n) >= 0 && uint64(int(n)) == n {
+ num = int(n)
+ isInt = true
+ }
+ default:
+ // Already 0, false.
+ }
+ }
+ newArgNum = argNum + 1
+ if tooLarge(num) {
+ num = 0
+ isInt = false
+ }
+ }
+ return
+}
+
+// parseArgNumber returns the value of the bracketed number, minus 1
+// (explicit argument numbers are one-indexed but we want zero-indexed).
+// The opening bracket is known to be present at format[0].
+// The returned values are the index, the number of bytes to consume
+// up to the closing paren, if present, and whether the number parsed
+// ok. The bytes to consume will be 1 if no closing paren is present.
+func parseArgNumber(format string) (index int, wid int, ok bool) {
+ // There must be at least 3 bytes: [n].
+ if len(format) < 3 {
+ return 0, 1, false
+ }
+
+ // Find closing bracket.
+ for i := 1; i < len(format); i++ {
+ if format[i] == ']' {
+ width, ok, newi := parsenum(format, 1, i)
+ if !ok || newi != i {
+ return 0, i + 1, false
+ }
+ return width - 1, i + 1, true // arg numbers are one-indexed and skip paren.
+ }
+ }
+ return 0, 1, false
+}
+
+// argNumber returns the next argument to evaluate, which is either the value of the passed-in
+// argNum or the value of the bracketed integer that begins format[i:]. It also returns
+// the new value of i, that is, the index of the next byte of the format to process.
+func (p *pp) argNumber(argNum int, format string, i int, numArgs int) (newArgNum, newi int, found bool) {
+ if len(format) <= i || format[i] != '[' {
+ return argNum, i, false
+ }
+ p.reordered = true
+ index, wid, ok := parseArgNumber(format[i:])
+ if ok && 0 <= index && index < numArgs {
+ return index, i + wid, true
+ }
+ p.goodArgNum = false
+ return argNum, i + wid, ok
+}
+
+func (p *pp) badArgNum(verb rune) {
+ p.buf.writeString(percentBangString)
+ p.buf.writeRune(verb)
+ p.buf.writeString(badIndexString)
+}
+
+func (p *pp) missingArg(verb rune) {
+ p.buf.writeString(percentBangString)
+ p.buf.writeRune(verb)
+ p.buf.writeString(missingString)
+}
+
+func (p *pp) doPrintf(format string, a []any) {
+ end := len(format)
+ argNum := 0 // we process one argument per non-trivial format
+ afterIndex := false // previous item in format was an index like [3].
+ p.reordered = false
+formatLoop:
+ for i := 0; i < end; {
+ p.goodArgNum = true
+ lasti := i
+ for i < end && format[i] != '%' {
+ i++
+ }
+ if i > lasti {
+ p.buf.writeString(format[lasti:i])
+ }
+ if i >= end {
+ // done processing format string
+ break
+ }
+
+ // Process one verb
+ i++
+
+ // Do we have flags?
+ p.fmt.clearflags()
+ simpleFormat:
+ for ; i < end; i++ {
+ c := format[i]
+ switch c {
+ case '#':
+ p.fmt.sharp = true
+ case '0':
+ p.fmt.zero = !p.fmt.minus // Only allow zero padding to the left.
+ case '+':
+ p.fmt.plus = true
+ case '-':
+ p.fmt.minus = true
+ p.fmt.zero = false // Do not pad with zeros to the right.
+ case ' ':
+ p.fmt.space = true
+ default:
+ // Fast path for common case of ascii lower case simple verbs
+ // without precision or width or argument indices.
+ if 'a' <= c && c <= 'z' && argNum < len(a) {
+ switch c {
+ case 'w':
+ p.wrappedErrs = append(p.wrappedErrs, argNum)
+ fallthrough
+ case 'v':
+ // Go syntax
+ p.fmt.sharpV = p.fmt.sharp
+ p.fmt.sharp = false
+ // Struct-field syntax
+ p.fmt.plusV = p.fmt.plus
+ p.fmt.plus = false
+ }
+ p.printArg(a[argNum], rune(c))
+ argNum++
+ i++
+ continue formatLoop
+ }
+ // Format is more complex than simple flags and a verb or is malformed.
+ break simpleFormat
+ }
+ }
+
+ // Do we have an explicit argument index?
+ argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
+
+ // Do we have width?
+ if i < end && format[i] == '*' {
+ i++
+ p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum)
+
+ if !p.fmt.widPresent {
+ p.buf.writeString(badWidthString)
+ }
+
+ // We have a negative width, so take its value and ensure
+ // that the minus flag is set
+ if p.fmt.wid < 0 {
+ p.fmt.wid = -p.fmt.wid
+ p.fmt.minus = true
+ p.fmt.zero = false // Do not pad with zeros to the right.
+ }
+ afterIndex = false
+ } else {
+ p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
+ if afterIndex && p.fmt.widPresent { // "%[3]2d"
+ p.goodArgNum = false
+ }
+ }
+
+ // Do we have precision?
+ if i+1 < end && format[i] == '.' {
+ i++
+ if afterIndex { // "%[3].2d"
+ p.goodArgNum = false
+ }
+ argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
+ if i < end && format[i] == '*' {
+ i++
+ p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum)
+ // Negative precision arguments don't make sense
+ if p.fmt.prec < 0 {
+ p.fmt.prec = 0
+ p.fmt.precPresent = false
+ }
+ if !p.fmt.precPresent {
+ p.buf.writeString(badPrecString)
+ }
+ afterIndex = false
+ } else {
+ p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i, end)
+ if !p.fmt.precPresent {
+ p.fmt.prec = 0
+ p.fmt.precPresent = true
+ }
+ }
+ }
+
+ if !afterIndex {
+ argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
+ }
+
+ if i >= end {
+ p.buf.writeString(noVerbString)
+ break
+ }
+
+ verb, size := rune(format[i]), 1
+ if verb >= utf8.RuneSelf {
+ verb, size = utf8.DecodeRuneInString(format[i:])
+ }
+ i += size
+
+ switch {
+ case verb == '%': // Percent does not absorb operands and ignores f.wid and f.prec.
+ p.buf.writeByte('%')
+ case !p.goodArgNum:
+ p.badArgNum(verb)
+ case argNum >= len(a): // No argument left over to print for the current verb.
+ p.missingArg(verb)
+ case verb == 'w':
+ p.wrappedErrs = append(p.wrappedErrs, argNum)
+ fallthrough
+ case verb == 'v':
+ // Go syntax
+ p.fmt.sharpV = p.fmt.sharp
+ p.fmt.sharp = false
+ // Struct-field syntax
+ p.fmt.plusV = p.fmt.plus
+ p.fmt.plus = false
+ fallthrough
+ default:
+ p.printArg(a[argNum], verb)
+ argNum++
+ }
+ }
+
+ // Check for extra arguments unless the call accessed the arguments
+ // out of order, in which case it's too expensive to detect if they've all
+ // been used and arguably OK if they're not.
+ if !p.reordered && argNum < len(a) {
+ p.fmt.clearflags()
+ p.buf.writeString(extraString)
+ for i, arg := range a[argNum:] {
+ if i > 0 {
+ p.buf.writeString(commaSpaceString)
+ }
+ if arg == nil {
+ p.buf.writeString(nilAngleString)
+ } else {
+ p.buf.writeString(reflect.TypeOf(arg).String())
+ p.buf.writeByte('=')
+ p.printArg(arg, 'v')
+ }
+ }
+ p.buf.writeByte(')')
+ }
+}
+
+func (p *pp) doPrint(a []any) {
+ prevString := false
+ for argNum, arg := range a {
+ isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
+ // Add a space between two non-string arguments.
+ if argNum > 0 && !isString && !prevString {
+ p.buf.writeByte(' ')
+ }
+ p.printArg(arg, 'v')
+ prevString = isString
+ }
+}
+
+// doPrintln is like doPrint but always adds a space between arguments
+// and a newline after the last argument.
+func (p *pp) doPrintln(a []any) {
+ for argNum, arg := range a {
+ if argNum > 0 {
+ p.buf.writeByte(' ')
+ }
+ p.printArg(arg, 'v')
+ }
+ p.buf.writeByte('\n')
+}
diff --git a/contrib/go/_std_1.21/src/fmt/scan.go b/contrib/go/_std_1.21/src/fmt/scan.go
new file mode 100644
index 0000000000..5dd0971642
--- /dev/null
+++ b/contrib/go/_std_1.21/src/fmt/scan.go
@@ -0,0 +1,1238 @@
+// Copyright 2010 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 fmt
+
+import (
+ "errors"
+ "io"
+ "math"
+ "os"
+ "reflect"
+ "strconv"
+ "sync"
+ "unicode/utf8"
+)
+
+// ScanState represents the scanner state passed to custom scanners.
+// Scanners may do rune-at-a-time scanning or ask the ScanState
+// to discover the next space-delimited token.
+type ScanState interface {
+ // ReadRune reads the next rune (Unicode code point) from the input.
+ // If invoked during Scanln, Fscanln, or Sscanln, ReadRune() will
+ // return EOF after returning the first '\n' or when reading beyond
+ // the specified width.
+ ReadRune() (r rune, size int, err error)
+ // UnreadRune causes the next call to ReadRune to return the same rune.
+ UnreadRune() error
+ // SkipSpace skips space in the input. Newlines are treated appropriately
+ // for the operation being performed; see the package documentation
+ // for more information.
+ SkipSpace()
+ // Token skips space in the input if skipSpace is true, then returns the
+ // run of Unicode code points c satisfying f(c). If f is nil,
+ // !unicode.IsSpace(c) is used; that is, the token will hold non-space
+ // characters. Newlines are treated appropriately for the operation being
+ // performed; see the package documentation for more information.
+ // The returned slice points to shared data that may be overwritten
+ // by the next call to Token, a call to a Scan function using the ScanState
+ // as input, or when the calling Scan method returns.
+ Token(skipSpace bool, f func(rune) bool) (token []byte, err error)
+ // Width returns the value of the width option and whether it has been set.
+ // The unit is Unicode code points.
+ Width() (wid int, ok bool)
+ // Because ReadRune is implemented by the interface, Read should never be
+ // called by the scanning routines and a valid implementation of
+ // ScanState may choose always to return an error from Read.
+ Read(buf []byte) (n int, err error)
+}
+
+// Scanner is implemented by any value that has a Scan method, which scans
+// the input for the representation of a value and stores the result in the
+// receiver, which must be a pointer to be useful. The Scan method is called
+// for any argument to Scan, Scanf, or Scanln that implements it.
+type Scanner interface {
+ Scan(state ScanState, verb rune) error
+}
+
+// Scan scans text read from standard input, storing successive
+// space-separated values into successive arguments. Newlines count
+// as space. It returns the number of items successfully scanned.
+// If that is less than the number of arguments, err will report why.
+func Scan(a ...any) (n int, err error) {
+ return Fscan(os.Stdin, a...)
+}
+
+// Scanln is similar to Scan, but stops scanning at a newline and
+// after the final item there must be a newline or EOF.
+func Scanln(a ...any) (n int, err error) {
+ return Fscanln(os.Stdin, a...)
+}
+
+// Scanf scans text read from standard input, storing successive
+// space-separated values into successive arguments as determined by
+// the format. It returns the number of items successfully scanned.
+// If that is less than the number of arguments, err will report why.
+// Newlines in the input must match newlines in the format.
+// The one exception: the verb %c always scans the next rune in the
+// input, even if it is a space (or tab etc.) or newline.
+func Scanf(format string, a ...any) (n int, err error) {
+ return Fscanf(os.Stdin, format, a...)
+}
+
+type stringReader string
+
+func (r *stringReader) Read(b []byte) (n int, err error) {
+ n = copy(b, *r)
+ *r = (*r)[n:]
+ if n == 0 {
+ err = io.EOF
+ }
+ return
+}
+
+// Sscan scans the argument string, storing successive space-separated
+// values into successive arguments. Newlines count as space. It
+// returns the number of items successfully scanned. If that is less
+// than the number of arguments, err will report why.
+func Sscan(str string, a ...any) (n int, err error) {
+ return Fscan((*stringReader)(&str), a...)
+}
+
+// Sscanln is similar to Sscan, but stops scanning at a newline and
+// after the final item there must be a newline or EOF.
+func Sscanln(str string, a ...any) (n int, err error) {
+ return Fscanln((*stringReader)(&str), a...)
+}
+
+// Sscanf scans the argument string, storing successive space-separated
+// values into successive arguments as determined by the format. It
+// returns the number of items successfully parsed.
+// Newlines in the input must match newlines in the format.
+func Sscanf(str string, format string, a ...any) (n int, err error) {
+ return Fscanf((*stringReader)(&str), format, a...)
+}
+
+// Fscan scans text read from r, storing successive space-separated
+// values into successive arguments. Newlines count as space. It
+// returns the number of items successfully scanned. If that is less
+// than the number of arguments, err will report why.
+func Fscan(r io.Reader, a ...any) (n int, err error) {
+ s, old := newScanState(r, true, false)
+ n, err = s.doScan(a)
+ s.free(old)
+ return
+}
+
+// Fscanln is similar to Fscan, but stops scanning at a newline and
+// after the final item there must be a newline or EOF.
+func Fscanln(r io.Reader, a ...any) (n int, err error) {
+ s, old := newScanState(r, false, true)
+ n, err = s.doScan(a)
+ s.free(old)
+ return
+}
+
+// Fscanf scans text read from r, storing successive space-separated
+// values into successive arguments as determined by the format. It
+// returns the number of items successfully parsed.
+// Newlines in the input must match newlines in the format.
+func Fscanf(r io.Reader, format string, a ...any) (n int, err error) {
+ s, old := newScanState(r, false, false)
+ n, err = s.doScanf(format, a)
+ s.free(old)
+ return
+}
+
+// scanError represents an error generated by the scanning software.
+// It's used as a unique signature to identify such errors when recovering.
+type scanError struct {
+ err error
+}
+
+const eof = -1
+
+// ss is the internal implementation of ScanState.
+type ss struct {
+ rs io.RuneScanner // where to read input
+ buf buffer // token accumulator
+ count int // runes consumed so far.
+ atEOF bool // already read EOF
+ ssave
+}
+
+// ssave holds the parts of ss that need to be
+// saved and restored on recursive scans.
+type ssave struct {
+ validSave bool // is or was a part of an actual ss.
+ nlIsEnd bool // whether newline terminates scan
+ nlIsSpace bool // whether newline counts as white space
+ argLimit int // max value of ss.count for this arg; argLimit <= limit
+ limit int // max value of ss.count.
+ maxWid int // width of this arg.
+}
+
+// The Read method is only in ScanState so that ScanState
+// satisfies io.Reader. It will never be called when used as
+// intended, so there is no need to make it actually work.
+func (s *ss) Read(buf []byte) (n int, err error) {
+ return 0, errors.New("ScanState's Read should not be called. Use ReadRune")
+}
+
+func (s *ss) ReadRune() (r rune, size int, err error) {
+ if s.atEOF || s.count >= s.argLimit {
+ err = io.EOF
+ return
+ }
+
+ r, size, err = s.rs.ReadRune()
+ if err == nil {
+ s.count++
+ if s.nlIsEnd && r == '\n' {
+ s.atEOF = true
+ }
+ } else if err == io.EOF {
+ s.atEOF = true
+ }
+ return
+}
+
+func (s *ss) Width() (wid int, ok bool) {
+ if s.maxWid == hugeWid {
+ return 0, false
+ }
+ return s.maxWid, true
+}
+
+// The public method returns an error; this private one panics.
+// If getRune reaches EOF, the return value is EOF (-1).
+func (s *ss) getRune() (r rune) {
+ r, _, err := s.ReadRune()
+ if err != nil {
+ if err == io.EOF {
+ return eof
+ }
+ s.error(err)
+ }
+ return
+}
+
+// mustReadRune turns io.EOF into a panic(io.ErrUnexpectedEOF).
+// It is called in cases such as string scanning where an EOF is a
+// syntax error.
+func (s *ss) mustReadRune() (r rune) {
+ r = s.getRune()
+ if r == eof {
+ s.error(io.ErrUnexpectedEOF)
+ }
+ return
+}
+
+func (s *ss) UnreadRune() error {
+ s.rs.UnreadRune()
+ s.atEOF = false
+ s.count--
+ return nil
+}
+
+func (s *ss) error(err error) {
+ panic(scanError{err})
+}
+
+func (s *ss) errorString(err string) {
+ panic(scanError{errors.New(err)})
+}
+
+func (s *ss) Token(skipSpace bool, f func(rune) bool) (tok []byte, err error) {
+ defer func() {
+ if e := recover(); e != nil {
+ if se, ok := e.(scanError); ok {
+ err = se.err
+ } else {
+ panic(e)
+ }
+ }
+ }()
+ if f == nil {
+ f = notSpace
+ }
+ s.buf = s.buf[:0]
+ tok = s.token(skipSpace, f)
+ return
+}
+
+// space is a copy of the unicode.White_Space ranges,
+// to avoid depending on package unicode.
+var space = [][2]uint16{
+ {0x0009, 0x000d},
+ {0x0020, 0x0020},
+ {0x0085, 0x0085},
+ {0x00a0, 0x00a0},
+ {0x1680, 0x1680},
+ {0x2000, 0x200a},
+ {0x2028, 0x2029},
+ {0x202f, 0x202f},
+ {0x205f, 0x205f},
+ {0x3000, 0x3000},
+}
+
+func isSpace(r rune) bool {
+ if r >= 1<<16 {
+ return false
+ }
+ rx := uint16(r)
+ for _, rng := range space {
+ if rx < rng[0] {
+ return false
+ }
+ if rx <= rng[1] {
+ return true
+ }
+ }
+ return false
+}
+
+// notSpace is the default scanning function used in Token.
+func notSpace(r rune) bool {
+ return !isSpace(r)
+}
+
+// readRune is a structure to enable reading UTF-8 encoded code points
+// from an io.Reader. It is used if the Reader given to the scanner does
+// not already implement io.RuneScanner.
+type readRune struct {
+ reader io.Reader
+ buf [utf8.UTFMax]byte // used only inside ReadRune
+ pending int // number of bytes in pendBuf; only >0 for bad UTF-8
+ pendBuf [utf8.UTFMax]byte // bytes left over
+ peekRune rune // if >=0 next rune; when <0 is ^(previous Rune)
+}
+
+// readByte returns the next byte from the input, which may be
+// left over from a previous read if the UTF-8 was ill-formed.
+func (r *readRune) readByte() (b byte, err error) {
+ if r.pending > 0 {
+ b = r.pendBuf[0]
+ copy(r.pendBuf[0:], r.pendBuf[1:])
+ r.pending--
+ return
+ }
+ n, err := io.ReadFull(r.reader, r.pendBuf[:1])
+ if n != 1 {
+ return 0, err
+ }
+ return r.pendBuf[0], err
+}
+
+// ReadRune returns the next UTF-8 encoded code point from the
+// io.Reader inside r.
+func (r *readRune) ReadRune() (rr rune, size int, err error) {
+ if r.peekRune >= 0 {
+ rr = r.peekRune
+ r.peekRune = ^r.peekRune
+ size = utf8.RuneLen(rr)
+ return
+ }
+ r.buf[0], err = r.readByte()
+ if err != nil {
+ return
+ }
+ if r.buf[0] < utf8.RuneSelf { // fast check for common ASCII case
+ rr = rune(r.buf[0])
+ size = 1 // Known to be 1.
+ // Flip the bits of the rune so it's available to UnreadRune.
+ r.peekRune = ^rr
+ return
+ }
+ var n int
+ for n = 1; !utf8.FullRune(r.buf[:n]); n++ {
+ r.buf[n], err = r.readByte()
+ if err != nil {
+ if err == io.EOF {
+ err = nil
+ break
+ }
+ return
+ }
+ }
+ rr, size = utf8.DecodeRune(r.buf[:n])
+ if size < n { // an error, save the bytes for the next read
+ copy(r.pendBuf[r.pending:], r.buf[size:n])
+ r.pending += n - size
+ }
+ // Flip the bits of the rune so it's available to UnreadRune.
+ r.peekRune = ^rr
+ return
+}
+
+func (r *readRune) UnreadRune() error {
+ if r.peekRune >= 0 {
+ return errors.New("fmt: scanning called UnreadRune with no rune available")
+ }
+ // Reverse bit flip of previously read rune to obtain valid >=0 state.
+ r.peekRune = ^r.peekRune
+ return nil
+}
+
+var ssFree = sync.Pool{
+ New: func() any { return new(ss) },
+}
+
+// newScanState allocates a new ss struct or grab a cached one.
+func newScanState(r io.Reader, nlIsSpace, nlIsEnd bool) (s *ss, old ssave) {
+ s = ssFree.Get().(*ss)
+ if rs, ok := r.(io.RuneScanner); ok {
+ s.rs = rs
+ } else {
+ s.rs = &readRune{reader: r, peekRune: -1}
+ }
+ s.nlIsSpace = nlIsSpace
+ s.nlIsEnd = nlIsEnd
+ s.atEOF = false
+ s.limit = hugeWid
+ s.argLimit = hugeWid
+ s.maxWid = hugeWid
+ s.validSave = true
+ s.count = 0
+ return
+}
+
+// free saves used ss structs in ssFree; avoid an allocation per invocation.
+func (s *ss) free(old ssave) {
+ // If it was used recursively, just restore the old state.
+ if old.validSave {
+ s.ssave = old
+ return
+ }
+ // Don't hold on to ss structs with large buffers.
+ if cap(s.buf) > 1024 {
+ return
+ }
+ s.buf = s.buf[:0]
+ s.rs = nil
+ ssFree.Put(s)
+}
+
+// SkipSpace provides Scan methods the ability to skip space and newline
+// characters in keeping with the current scanning mode set by format strings
+// and Scan/Scanln.
+func (s *ss) SkipSpace() {
+ for {
+ r := s.getRune()
+ if r == eof {
+ return
+ }
+ if r == '\r' && s.peek("\n") {
+ continue
+ }
+ if r == '\n' {
+ if s.nlIsSpace {
+ continue
+ }
+ s.errorString("unexpected newline")
+ return
+ }
+ if !isSpace(r) {
+ s.UnreadRune()
+ break
+ }
+ }
+}
+
+// token returns the next space-delimited string from the input. It
+// skips white space. For Scanln, it stops at newlines. For Scan,
+// newlines are treated as spaces.
+func (s *ss) token(skipSpace bool, f func(rune) bool) []byte {
+ if skipSpace {
+ s.SkipSpace()
+ }
+ // read until white space or newline
+ for {
+ r := s.getRune()
+ if r == eof {
+ break
+ }
+ if !f(r) {
+ s.UnreadRune()
+ break
+ }
+ s.buf.writeRune(r)
+ }
+ return s.buf
+}
+
+var errComplex = errors.New("syntax error scanning complex number")
+var errBool = errors.New("syntax error scanning boolean")
+
+func indexRune(s string, r rune) int {
+ for i, c := range s {
+ if c == r {
+ return i
+ }
+ }
+ return -1
+}
+
+// consume reads the next rune in the input and reports whether it is in the ok string.
+// If accept is true, it puts the character into the input token.
+func (s *ss) consume(ok string, accept bool) bool {
+ r := s.getRune()
+ if r == eof {
+ return false
+ }
+ if indexRune(ok, r) >= 0 {
+ if accept {
+ s.buf.writeRune(r)
+ }
+ return true
+ }
+ if r != eof && accept {
+ s.UnreadRune()
+ }
+ return false
+}
+
+// peek reports whether the next character is in the ok string, without consuming it.
+func (s *ss) peek(ok string) bool {
+ r := s.getRune()
+ if r != eof {
+ s.UnreadRune()
+ }
+ return indexRune(ok, r) >= 0
+}
+
+func (s *ss) notEOF() {
+ // Guarantee there is data to be read.
+ if r := s.getRune(); r == eof {
+ panic(io.EOF)
+ }
+ s.UnreadRune()
+}
+
+// accept checks the next rune in the input. If it's a byte (sic) in the string, it puts it in the
+// buffer and returns true. Otherwise it return false.
+func (s *ss) accept(ok string) bool {
+ return s.consume(ok, true)
+}
+
+// okVerb verifies that the verb is present in the list, setting s.err appropriately if not.
+func (s *ss) okVerb(verb rune, okVerbs, typ string) bool {
+ for _, v := range okVerbs {
+ if v == verb {
+ return true
+ }
+ }
+ s.errorString("bad verb '%" + string(verb) + "' for " + typ)
+ return false
+}
+
+// scanBool returns the value of the boolean represented by the next token.
+func (s *ss) scanBool(verb rune) bool {
+ s.SkipSpace()
+ s.notEOF()
+ if !s.okVerb(verb, "tv", "boolean") {
+ return false
+ }
+ // Syntax-checking a boolean is annoying. We're not fastidious about case.
+ switch s.getRune() {
+ case '0':
+ return false
+ case '1':
+ return true
+ case 't', 'T':
+ if s.accept("rR") && (!s.accept("uU") || !s.accept("eE")) {
+ s.error(errBool)
+ }
+ return true
+ case 'f', 'F':
+ if s.accept("aA") && (!s.accept("lL") || !s.accept("sS") || !s.accept("eE")) {
+ s.error(errBool)
+ }
+ return false
+ }
+ return false
+}
+
+// Numerical elements
+const (
+ binaryDigits = "01"
+ octalDigits = "01234567"
+ decimalDigits = "0123456789"
+ hexadecimalDigits = "0123456789aAbBcCdDeEfF"
+ sign = "+-"
+ period = "."
+ exponent = "eEpP"
+)
+
+// getBase returns the numeric base represented by the verb and its digit string.
+func (s *ss) getBase(verb rune) (base int, digits string) {
+ s.okVerb(verb, "bdoUxXv", "integer") // sets s.err
+ base = 10
+ digits = decimalDigits
+ switch verb {
+ case 'b':
+ base = 2
+ digits = binaryDigits
+ case 'o':
+ base = 8
+ digits = octalDigits
+ case 'x', 'X', 'U':
+ base = 16
+ digits = hexadecimalDigits
+ }
+ return
+}
+
+// scanNumber returns the numerical string with specified digits starting here.
+func (s *ss) scanNumber(digits string, haveDigits bool) string {
+ if !haveDigits {
+ s.notEOF()
+ if !s.accept(digits) {
+ s.errorString("expected integer")
+ }
+ }
+ for s.accept(digits) {
+ }
+ return string(s.buf)
+}
+
+// scanRune returns the next rune value in the input.
+func (s *ss) scanRune(bitSize int) int64 {
+ s.notEOF()
+ r := s.getRune()
+ n := uint(bitSize)
+ x := (int64(r) << (64 - n)) >> (64 - n)
+ if x != int64(r) {
+ s.errorString("overflow on character value " + string(r))
+ }
+ return int64(r)
+}
+
+// scanBasePrefix reports whether the integer begins with a base prefix
+// and returns the base, digit string, and whether a zero was found.
+// It is called only if the verb is %v.
+func (s *ss) scanBasePrefix() (base int, digits string, zeroFound bool) {
+ if !s.peek("0") {
+ return 0, decimalDigits + "_", false
+ }
+ s.accept("0")
+ // Special cases for 0, 0b, 0o, 0x.
+ switch {
+ case s.peek("bB"):
+ s.consume("bB", true)
+ return 0, binaryDigits + "_", true
+ case s.peek("oO"):
+ s.consume("oO", true)
+ return 0, octalDigits + "_", true
+ case s.peek("xX"):
+ s.consume("xX", true)
+ return 0, hexadecimalDigits + "_", true
+ default:
+ return 0, octalDigits + "_", true
+ }
+}
+
+// scanInt returns the value of the integer represented by the next
+// token, checking for overflow. Any error is stored in s.err.
+func (s *ss) scanInt(verb rune, bitSize int) int64 {
+ if verb == 'c' {
+ return s.scanRune(bitSize)
+ }
+ s.SkipSpace()
+ s.notEOF()
+ base, digits := s.getBase(verb)
+ haveDigits := false
+ if verb == 'U' {
+ if !s.consume("U", false) || !s.consume("+", false) {
+ s.errorString("bad unicode format ")
+ }
+ } else {
+ s.accept(sign) // If there's a sign, it will be left in the token buffer.
+ if verb == 'v' {
+ base, digits, haveDigits = s.scanBasePrefix()
+ }
+ }
+ tok := s.scanNumber(digits, haveDigits)
+ i, err := strconv.ParseInt(tok, base, 64)
+ if err != nil {
+ s.error(err)
+ }
+ n := uint(bitSize)
+ x := (i << (64 - n)) >> (64 - n)
+ if x != i {
+ s.errorString("integer overflow on token " + tok)
+ }
+ return i
+}
+
+// scanUint returns the value of the unsigned integer represented
+// by the next token, checking for overflow. Any error is stored in s.err.
+func (s *ss) scanUint(verb rune, bitSize int) uint64 {
+ if verb == 'c' {
+ return uint64(s.scanRune(bitSize))
+ }
+ s.SkipSpace()
+ s.notEOF()
+ base, digits := s.getBase(verb)
+ haveDigits := false
+ if verb == 'U' {
+ if !s.consume("U", false) || !s.consume("+", false) {
+ s.errorString("bad unicode format ")
+ }
+ } else if verb == 'v' {
+ base, digits, haveDigits = s.scanBasePrefix()
+ }
+ tok := s.scanNumber(digits, haveDigits)
+ i, err := strconv.ParseUint(tok, base, 64)
+ if err != nil {
+ s.error(err)
+ }
+ n := uint(bitSize)
+ x := (i << (64 - n)) >> (64 - n)
+ if x != i {
+ s.errorString("unsigned integer overflow on token " + tok)
+ }
+ return i
+}
+
+// floatToken returns the floating-point number starting here, no longer than swid
+// if the width is specified. It's not rigorous about syntax because it doesn't check that
+// we have at least some digits, but Atof will do that.
+func (s *ss) floatToken() string {
+ s.buf = s.buf[:0]
+ // NaN?
+ if s.accept("nN") && s.accept("aA") && s.accept("nN") {
+ return string(s.buf)
+ }
+ // leading sign?
+ s.accept(sign)
+ // Inf?
+ if s.accept("iI") && s.accept("nN") && s.accept("fF") {
+ return string(s.buf)
+ }
+ digits := decimalDigits + "_"
+ exp := exponent
+ if s.accept("0") && s.accept("xX") {
+ digits = hexadecimalDigits + "_"
+ exp = "pP"
+ }
+ // digits?
+ for s.accept(digits) {
+ }
+ // decimal point?
+ if s.accept(period) {
+ // fraction?
+ for s.accept(digits) {
+ }
+ }
+ // exponent?
+ if s.accept(exp) {
+ // leading sign?
+ s.accept(sign)
+ // digits?
+ for s.accept(decimalDigits + "_") {
+ }
+ }
+ return string(s.buf)
+}
+
+// complexTokens returns the real and imaginary parts of the complex number starting here.
+// The number might be parenthesized and has the format (N+Ni) where N is a floating-point
+// number and there are no spaces within.
+func (s *ss) complexTokens() (real, imag string) {
+ // TODO: accept N and Ni independently?
+ parens := s.accept("(")
+ real = s.floatToken()
+ s.buf = s.buf[:0]
+ // Must now have a sign.
+ if !s.accept("+-") {
+ s.error(errComplex)
+ }
+ // Sign is now in buffer
+ imagSign := string(s.buf)
+ imag = s.floatToken()
+ if !s.accept("i") {
+ s.error(errComplex)
+ }
+ if parens && !s.accept(")") {
+ s.error(errComplex)
+ }
+ return real, imagSign + imag
+}
+
+func hasX(s string) bool {
+ for i := 0; i < len(s); i++ {
+ if s[i] == 'x' || s[i] == 'X' {
+ return true
+ }
+ }
+ return false
+}
+
+// convertFloat converts the string to a float64value.
+func (s *ss) convertFloat(str string, n int) float64 {
+ // strconv.ParseFloat will handle "+0x1.fp+2",
+ // but we have to implement our non-standard
+ // decimal+binary exponent mix (1.2p4) ourselves.
+ if p := indexRune(str, 'p'); p >= 0 && !hasX(str) {
+ // Atof doesn't handle power-of-2 exponents,
+ // but they're easy to evaluate.
+ f, err := strconv.ParseFloat(str[:p], n)
+ if err != nil {
+ // Put full string into error.
+ if e, ok := err.(*strconv.NumError); ok {
+ e.Num = str
+ }
+ s.error(err)
+ }
+ m, err := strconv.Atoi(str[p+1:])
+ if err != nil {
+ // Put full string into error.
+ if e, ok := err.(*strconv.NumError); ok {
+ e.Num = str
+ }
+ s.error(err)
+ }
+ return math.Ldexp(f, m)
+ }
+ f, err := strconv.ParseFloat(str, n)
+ if err != nil {
+ s.error(err)
+ }
+ return f
+}
+
+// scanComplex converts the next token to a complex128 value.
+// The atof argument is a type-specific reader for the underlying type.
+// If we're reading complex64, atof will parse float32s and convert them
+// to float64's to avoid reproducing this code for each complex type.
+func (s *ss) scanComplex(verb rune, n int) complex128 {
+ if !s.okVerb(verb, floatVerbs, "complex") {
+ return 0
+ }
+ s.SkipSpace()
+ s.notEOF()
+ sreal, simag := s.complexTokens()
+ real := s.convertFloat(sreal, n/2)
+ imag := s.convertFloat(simag, n/2)
+ return complex(real, imag)
+}
+
+// convertString returns the string represented by the next input characters.
+// The format of the input is determined by the verb.
+func (s *ss) convertString(verb rune) (str string) {
+ if !s.okVerb(verb, "svqxX", "string") {
+ return ""
+ }
+ s.SkipSpace()
+ s.notEOF()
+ switch verb {
+ case 'q':
+ str = s.quotedString()
+ case 'x', 'X':
+ str = s.hexString()
+ default:
+ str = string(s.token(true, notSpace)) // %s and %v just return the next word
+ }
+ return
+}
+
+// quotedString returns the double- or back-quoted string represented by the next input characters.
+func (s *ss) quotedString() string {
+ s.notEOF()
+ quote := s.getRune()
+ switch quote {
+ case '`':
+ // Back-quoted: Anything goes until EOF or back quote.
+ for {
+ r := s.mustReadRune()
+ if r == quote {
+ break
+ }
+ s.buf.writeRune(r)
+ }
+ return string(s.buf)
+ case '"':
+ // Double-quoted: Include the quotes and let strconv.Unquote do the backslash escapes.
+ s.buf.writeByte('"')
+ for {
+ r := s.mustReadRune()
+ s.buf.writeRune(r)
+ if r == '\\' {
+ // In a legal backslash escape, no matter how long, only the character
+ // immediately after the escape can itself be a backslash or quote.
+ // Thus we only need to protect the first character after the backslash.
+ s.buf.writeRune(s.mustReadRune())
+ } else if r == '"' {
+ break
+ }
+ }
+ result, err := strconv.Unquote(string(s.buf))
+ if err != nil {
+ s.error(err)
+ }
+ return result
+ default:
+ s.errorString("expected quoted string")
+ }
+ return ""
+}
+
+// hexDigit returns the value of the hexadecimal digit.
+func hexDigit(d rune) (int, bool) {
+ digit := int(d)
+ switch digit {
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ return digit - '0', true
+ case 'a', 'b', 'c', 'd', 'e', 'f':
+ return 10 + digit - 'a', true
+ case 'A', 'B', 'C', 'D', 'E', 'F':
+ return 10 + digit - 'A', true
+ }
+ return -1, false
+}
+
+// hexByte returns the next hex-encoded (two-character) byte from the input.
+// It returns ok==false if the next bytes in the input do not encode a hex byte.
+// If the first byte is hex and the second is not, processing stops.
+func (s *ss) hexByte() (b byte, ok bool) {
+ rune1 := s.getRune()
+ if rune1 == eof {
+ return
+ }
+ value1, ok := hexDigit(rune1)
+ if !ok {
+ s.UnreadRune()
+ return
+ }
+ value2, ok := hexDigit(s.mustReadRune())
+ if !ok {
+ s.errorString("illegal hex digit")
+ return
+ }
+ return byte(value1<<4 | value2), true
+}
+
+// hexString returns the space-delimited hexpair-encoded string.
+func (s *ss) hexString() string {
+ s.notEOF()
+ for {
+ b, ok := s.hexByte()
+ if !ok {
+ break
+ }
+ s.buf.writeByte(b)
+ }
+ if len(s.buf) == 0 {
+ s.errorString("no hex data for %x string")
+ return ""
+ }
+ return string(s.buf)
+}
+
+const (
+ floatVerbs = "beEfFgGv"
+
+ hugeWid = 1 << 30
+
+ intBits = 32 << (^uint(0) >> 63)
+ uintptrBits = 32 << (^uintptr(0) >> 63)
+)
+
+// scanPercent scans a literal percent character.
+func (s *ss) scanPercent() {
+ s.SkipSpace()
+ s.notEOF()
+ if !s.accept("%") {
+ s.errorString("missing literal %")
+ }
+}
+
+// scanOne scans a single value, deriving the scanner from the type of the argument.
+func (s *ss) scanOne(verb rune, arg any) {
+ s.buf = s.buf[:0]
+ var err error
+ // If the parameter has its own Scan method, use that.
+ if v, ok := arg.(Scanner); ok {
+ err = v.Scan(s, verb)
+ if err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ s.error(err)
+ }
+ return
+ }
+
+ switch v := arg.(type) {
+ case *bool:
+ *v = s.scanBool(verb)
+ case *complex64:
+ *v = complex64(s.scanComplex(verb, 64))
+ case *complex128:
+ *v = s.scanComplex(verb, 128)
+ case *int:
+ *v = int(s.scanInt(verb, intBits))
+ case *int8:
+ *v = int8(s.scanInt(verb, 8))
+ case *int16:
+ *v = int16(s.scanInt(verb, 16))
+ case *int32:
+ *v = int32(s.scanInt(verb, 32))
+ case *int64:
+ *v = s.scanInt(verb, 64)
+ case *uint:
+ *v = uint(s.scanUint(verb, intBits))
+ case *uint8:
+ *v = uint8(s.scanUint(verb, 8))
+ case *uint16:
+ *v = uint16(s.scanUint(verb, 16))
+ case *uint32:
+ *v = uint32(s.scanUint(verb, 32))
+ case *uint64:
+ *v = s.scanUint(verb, 64)
+ case *uintptr:
+ *v = uintptr(s.scanUint(verb, uintptrBits))
+ // Floats are tricky because you want to scan in the precision of the result, not
+ // scan in high precision and convert, in order to preserve the correct error condition.
+ case *float32:
+ if s.okVerb(verb, floatVerbs, "float32") {
+ s.SkipSpace()
+ s.notEOF()
+ *v = float32(s.convertFloat(s.floatToken(), 32))
+ }
+ case *float64:
+ if s.okVerb(verb, floatVerbs, "float64") {
+ s.SkipSpace()
+ s.notEOF()
+ *v = s.convertFloat(s.floatToken(), 64)
+ }
+ case *string:
+ *v = s.convertString(verb)
+ case *[]byte:
+ // We scan to string and convert so we get a copy of the data.
+ // If we scanned to bytes, the slice would point at the buffer.
+ *v = []byte(s.convertString(verb))
+ default:
+ val := reflect.ValueOf(v)
+ ptr := val
+ if ptr.Kind() != reflect.Pointer {
+ s.errorString("type not a pointer: " + val.Type().String())
+ return
+ }
+ switch v := ptr.Elem(); v.Kind() {
+ case reflect.Bool:
+ v.SetBool(s.scanBool(verb))
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ v.SetInt(s.scanInt(verb, v.Type().Bits()))
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ v.SetUint(s.scanUint(verb, v.Type().Bits()))
+ case reflect.String:
+ v.SetString(s.convertString(verb))
+ case reflect.Slice:
+ // For now, can only handle (renamed) []byte.
+ typ := v.Type()
+ if typ.Elem().Kind() != reflect.Uint8 {
+ s.errorString("can't scan type: " + val.Type().String())
+ }
+ str := s.convertString(verb)
+ v.Set(reflect.MakeSlice(typ, len(str), len(str)))
+ for i := 0; i < len(str); i++ {
+ v.Index(i).SetUint(uint64(str[i]))
+ }
+ case reflect.Float32, reflect.Float64:
+ s.SkipSpace()
+ s.notEOF()
+ v.SetFloat(s.convertFloat(s.floatToken(), v.Type().Bits()))
+ case reflect.Complex64, reflect.Complex128:
+ v.SetComplex(s.scanComplex(verb, v.Type().Bits()))
+ default:
+ s.errorString("can't scan type: " + val.Type().String())
+ }
+ }
+}
+
+// errorHandler turns local panics into error returns.
+func errorHandler(errp *error) {
+ if e := recover(); e != nil {
+ if se, ok := e.(scanError); ok { // catch local error
+ *errp = se.err
+ } else if eof, ok := e.(error); ok && eof == io.EOF { // out of input
+ *errp = eof
+ } else {
+ panic(e)
+ }
+ }
+}
+
+// doScan does the real work for scanning without a format string.
+func (s *ss) doScan(a []any) (numProcessed int, err error) {
+ defer errorHandler(&err)
+ for _, arg := range a {
+ s.scanOne('v', arg)
+ numProcessed++
+ }
+ // Check for newline (or EOF) if required (Scanln etc.).
+ if s.nlIsEnd {
+ for {
+ r := s.getRune()
+ if r == '\n' || r == eof {
+ break
+ }
+ if !isSpace(r) {
+ s.errorString("expected newline")
+ break
+ }
+ }
+ }
+ return
+}
+
+// advance determines whether the next characters in the input match
+// those of the format. It returns the number of bytes (sic) consumed
+// in the format. All runs of space characters in either input or
+// format behave as a single space. Newlines are special, though:
+// newlines in the format must match those in the input and vice versa.
+// This routine also handles the %% case. If the return value is zero,
+// either format starts with a % (with no following %) or the input
+// is empty. If it is negative, the input did not match the string.
+func (s *ss) advance(format string) (i int) {
+ for i < len(format) {
+ fmtc, w := utf8.DecodeRuneInString(format[i:])
+
+ // Space processing.
+ // In the rest of this comment "space" means spaces other than newline.
+ // Newline in the format matches input of zero or more spaces and then newline or end-of-input.
+ // Spaces in the format before the newline are collapsed into the newline.
+ // Spaces in the format after the newline match zero or more spaces after the corresponding input newline.
+ // Other spaces in the format match input of one or more spaces or end-of-input.
+ if isSpace(fmtc) {
+ newlines := 0
+ trailingSpace := false
+ for isSpace(fmtc) && i < len(format) {
+ if fmtc == '\n' {
+ newlines++
+ trailingSpace = false
+ } else {
+ trailingSpace = true
+ }
+ i += w
+ fmtc, w = utf8.DecodeRuneInString(format[i:])
+ }
+ for j := 0; j < newlines; j++ {
+ inputc := s.getRune()
+ for isSpace(inputc) && inputc != '\n' {
+ inputc = s.getRune()
+ }
+ if inputc != '\n' && inputc != eof {
+ s.errorString("newline in format does not match input")
+ }
+ }
+ if trailingSpace {
+ inputc := s.getRune()
+ if newlines == 0 {
+ // If the trailing space stood alone (did not follow a newline),
+ // it must find at least one space to consume.
+ if !isSpace(inputc) && inputc != eof {
+ s.errorString("expected space in input to match format")
+ }
+ if inputc == '\n' {
+ s.errorString("newline in input does not match format")
+ }
+ }
+ for isSpace(inputc) && inputc != '\n' {
+ inputc = s.getRune()
+ }
+ if inputc != eof {
+ s.UnreadRune()
+ }
+ }
+ continue
+ }
+
+ // Verbs.
+ if fmtc == '%' {
+ // % at end of string is an error.
+ if i+w == len(format) {
+ s.errorString("missing verb: % at end of format string")
+ }
+ // %% acts like a real percent
+ nextc, _ := utf8.DecodeRuneInString(format[i+w:]) // will not match % if string is empty
+ if nextc != '%' {
+ return
+ }
+ i += w // skip the first %
+ }
+
+ // Literals.
+ inputc := s.mustReadRune()
+ if fmtc != inputc {
+ s.UnreadRune()
+ return -1
+ }
+ i += w
+ }
+ return
+}
+
+// doScanf does the real work when scanning with a format string.
+// At the moment, it handles only pointers to basic types.
+func (s *ss) doScanf(format string, a []any) (numProcessed int, err error) {
+ defer errorHandler(&err)
+ end := len(format) - 1
+ // We process one item per non-trivial format
+ for i := 0; i <= end; {
+ w := s.advance(format[i:])
+ if w > 0 {
+ i += w
+ continue
+ }
+ // Either we failed to advance, we have a percent character, or we ran out of input.
+ if format[i] != '%' {
+ // Can't advance format. Why not?
+ if w < 0 {
+ s.errorString("input does not match format")
+ }
+ // Otherwise at EOF; "too many operands" error handled below
+ break
+ }
+ i++ // % is one byte
+
+ // do we have 20 (width)?
+ var widPresent bool
+ s.maxWid, widPresent, i = parsenum(format, i, end)
+ if !widPresent {
+ s.maxWid = hugeWid
+ }
+
+ c, w := utf8.DecodeRuneInString(format[i:])
+ i += w
+
+ if c != 'c' {
+ s.SkipSpace()
+ }
+ if c == '%' {
+ s.scanPercent()
+ continue // Do not consume an argument.
+ }
+ s.argLimit = s.limit
+ if f := s.count + s.maxWid; f < s.argLimit {
+ s.argLimit = f
+ }
+
+ if numProcessed >= len(a) { // out of operands
+ s.errorString("too few operands for format '%" + format[i-w:] + "'")
+ break
+ }
+ arg := a[numProcessed]
+
+ s.scanOne(c, arg)
+ numProcessed++
+ s.argLimit = s.limit
+ }
+ if numProcessed < len(a) {
+ s.errorString("too many operands")
+ }
+ return
+}
diff --git a/contrib/go/_std_1.21/src/fmt/ya.make b/contrib/go/_std_1.21/src/fmt/ya.make
new file mode 100644
index 0000000000..89172965e6
--- /dev/null
+++ b/contrib/go/_std_1.21/src/fmt/ya.make
@@ -0,0 +1,27 @@
+GO_LIBRARY()
+
+SRCS(
+ doc.go
+ errors.go
+ format.go
+ print.go
+ scan.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ errors_test.go
+ example_test.go
+ fmt_test.go
+ gostringer_example_test.go
+ scan_test.go
+ state_test.go
+ stringer_example_test.go
+ stringer_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/go/ast/ast.go b/contrib/go/_std_1.21/src/go/ast/ast.go
new file mode 100644
index 0000000000..c439052610
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/ast/ast.go
@@ -0,0 +1,1112 @@
+// Copyright 2009 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 ast declares the types used to represent syntax trees for Go
+// packages.
+package ast
+
+import (
+ "go/token"
+ "strings"
+)
+
+// ----------------------------------------------------------------------------
+// Interfaces
+//
+// There are 3 main classes of nodes: Expressions and type nodes,
+// statement nodes, and declaration nodes. The node names usually
+// match the corresponding Go spec production names to which they
+// correspond. The node fields correspond to the individual parts
+// of the respective productions.
+//
+// All nodes contain position information marking the beginning of
+// the corresponding source text segment; it is accessible via the
+// Pos accessor method. Nodes may contain additional position info
+// for language constructs where comments may be found between parts
+// of the construct (typically any larger, parenthesized subpart).
+// That position information is needed to properly position comments
+// when printing the construct.
+
+// All node types implement the Node interface.
+type Node interface {
+ Pos() token.Pos // position of first character belonging to the node
+ End() token.Pos // position of first character immediately after the node
+}
+
+// All expression nodes implement the Expr interface.
+type Expr interface {
+ Node
+ exprNode()
+}
+
+// All statement nodes implement the Stmt interface.
+type Stmt interface {
+ Node
+ stmtNode()
+}
+
+// All declaration nodes implement the Decl interface.
+type Decl interface {
+ Node
+ declNode()
+}
+
+// ----------------------------------------------------------------------------
+// Comments
+
+// A Comment node represents a single //-style or /*-style comment.
+//
+// The Text field contains the comment text without carriage returns (\r) that
+// may have been present in the source. Because a comment's end position is
+// computed using len(Text), the position reported by End() does not match the
+// true source end position for comments containing carriage returns.
+type Comment struct {
+ Slash token.Pos // position of "/" starting the comment
+ Text string // comment text (excluding '\n' for //-style comments)
+}
+
+func (c *Comment) Pos() token.Pos { return c.Slash }
+func (c *Comment) End() token.Pos { return token.Pos(int(c.Slash) + len(c.Text)) }
+
+// A CommentGroup represents a sequence of comments
+// with no other tokens and no empty lines between.
+type CommentGroup struct {
+ List []*Comment // len(List) > 0
+}
+
+func (g *CommentGroup) Pos() token.Pos { return g.List[0].Pos() }
+func (g *CommentGroup) End() token.Pos { return g.List[len(g.List)-1].End() }
+
+func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' }
+
+func stripTrailingWhitespace(s string) string {
+ i := len(s)
+ for i > 0 && isWhitespace(s[i-1]) {
+ i--
+ }
+ return s[0:i]
+}
+
+// Text returns the text of the comment.
+// Comment markers (//, /*, and */), the first space of a line comment, and
+// leading and trailing empty lines are removed.
+// Comment directives like "//line" and "//go:noinline" are also removed.
+// Multiple empty lines are reduced to one, and trailing space on lines is trimmed.
+// Unless the result is empty, it is newline-terminated.
+func (g *CommentGroup) Text() string {
+ if g == nil {
+ return ""
+ }
+ comments := make([]string, len(g.List))
+ for i, c := range g.List {
+ comments[i] = c.Text
+ }
+
+ lines := make([]string, 0, 10) // most comments are less than 10 lines
+ for _, c := range comments {
+ // Remove comment markers.
+ // The parser has given us exactly the comment text.
+ switch c[1] {
+ case '/':
+ //-style comment (no newline at the end)
+ c = c[2:]
+ if len(c) == 0 {
+ // empty line
+ break
+ }
+ if c[0] == ' ' {
+ // strip first space - required for Example tests
+ c = c[1:]
+ break
+ }
+ if isDirective(c) {
+ // Ignore //go:noinline, //line, and so on.
+ continue
+ }
+ case '*':
+ /*-style comment */
+ c = c[2 : len(c)-2]
+ }
+
+ // Split on newlines.
+ cl := strings.Split(c, "\n")
+
+ // Walk lines, stripping trailing white space and adding to list.
+ for _, l := range cl {
+ lines = append(lines, stripTrailingWhitespace(l))
+ }
+ }
+
+ // Remove leading blank lines; convert runs of
+ // interior blank lines to a single blank line.
+ n := 0
+ for _, line := range lines {
+ if line != "" || n > 0 && lines[n-1] != "" {
+ lines[n] = line
+ n++
+ }
+ }
+ lines = lines[0:n]
+
+ // Add final "" entry to get trailing newline from Join.
+ if n > 0 && lines[n-1] != "" {
+ lines = append(lines, "")
+ }
+
+ return strings.Join(lines, "\n")
+}
+
+// isDirective reports whether c is a comment directive.
+// This code is also in go/printer.
+func isDirective(c string) bool {
+ // "//line " is a line directive.
+ // "//extern " is for gccgo.
+ // "//export " is for cgo.
+ // (The // has been removed.)
+ if strings.HasPrefix(c, "line ") || strings.HasPrefix(c, "extern ") || strings.HasPrefix(c, "export ") {
+ return true
+ }
+
+ // "//[a-z0-9]+:[a-z0-9]"
+ // (The // has been removed.)
+ colon := strings.Index(c, ":")
+ if colon <= 0 || colon+1 >= len(c) {
+ return false
+ }
+ for i := 0; i <= colon+1; i++ {
+ if i == colon {
+ continue
+ }
+ b := c[i]
+ if !('a' <= b && b <= 'z' || '0' <= b && b <= '9') {
+ return false
+ }
+ }
+ return true
+}
+
+// ----------------------------------------------------------------------------
+// Expressions and types
+
+// A Field represents a Field declaration list in a struct type,
+// a method list in an interface type, or a parameter/result declaration
+// in a signature.
+// Field.Names is nil for unnamed parameters (parameter lists which only contain types)
+// and embedded struct fields. In the latter case, the field name is the type name.
+type Field struct {
+ Doc *CommentGroup // associated documentation; or nil
+ Names []*Ident // field/method/(type) parameter names; or nil
+ Type Expr // field/method/parameter type; or nil
+ Tag *BasicLit // field tag; or nil
+ Comment *CommentGroup // line comments; or nil
+}
+
+func (f *Field) Pos() token.Pos {
+ if len(f.Names) > 0 {
+ return f.Names[0].Pos()
+ }
+ if f.Type != nil {
+ return f.Type.Pos()
+ }
+ return token.NoPos
+}
+
+func (f *Field) End() token.Pos {
+ if f.Tag != nil {
+ return f.Tag.End()
+ }
+ if f.Type != nil {
+ return f.Type.End()
+ }
+ if len(f.Names) > 0 {
+ return f.Names[len(f.Names)-1].End()
+ }
+ return token.NoPos
+}
+
+// A FieldList represents a list of Fields, enclosed by parentheses,
+// curly braces, or square brackets.
+type FieldList struct {
+ Opening token.Pos // position of opening parenthesis/brace/bracket, if any
+ List []*Field // field list; or nil
+ Closing token.Pos // position of closing parenthesis/brace/bracket, if any
+}
+
+func (f *FieldList) Pos() token.Pos {
+ if f.Opening.IsValid() {
+ return f.Opening
+ }
+ // the list should not be empty in this case;
+ // be conservative and guard against bad ASTs
+ if len(f.List) > 0 {
+ return f.List[0].Pos()
+ }
+ return token.NoPos
+}
+
+func (f *FieldList) End() token.Pos {
+ if f.Closing.IsValid() {
+ return f.Closing + 1
+ }
+ // the list should not be empty in this case;
+ // be conservative and guard against bad ASTs
+ if n := len(f.List); n > 0 {
+ return f.List[n-1].End()
+ }
+ return token.NoPos
+}
+
+// NumFields returns the number of parameters or struct fields represented by a FieldList.
+func (f *FieldList) NumFields() int {
+ n := 0
+ if f != nil {
+ for _, g := range f.List {
+ m := len(g.Names)
+ if m == 0 {
+ m = 1
+ }
+ n += m
+ }
+ }
+ return n
+}
+
+// An expression is represented by a tree consisting of one
+// or more of the following concrete expression nodes.
+type (
+ // A BadExpr node is a placeholder for an expression containing
+ // syntax errors for which a correct expression node cannot be
+ // created.
+ //
+ BadExpr struct {
+ From, To token.Pos // position range of bad expression
+ }
+
+ // An Ident node represents an identifier.
+ Ident struct {
+ NamePos token.Pos // identifier position
+ Name string // identifier name
+ Obj *Object // denoted object; or nil
+ }
+
+ // An Ellipsis node stands for the "..." type in a
+ // parameter list or the "..." length in an array type.
+ //
+ Ellipsis struct {
+ Ellipsis token.Pos // position of "..."
+ Elt Expr // ellipsis element type (parameter lists only); or nil
+ }
+
+ // A BasicLit node represents a literal of basic type.
+ BasicLit struct {
+ ValuePos token.Pos // literal position
+ Kind token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING
+ Value string // literal string; e.g. 42, 0x7f, 3.14, 1e-9, 2.4i, 'a', '\x7f', "foo" or `\m\n\o`
+ }
+
+ // A FuncLit node represents a function literal.
+ FuncLit struct {
+ Type *FuncType // function type
+ Body *BlockStmt // function body
+ }
+
+ // A CompositeLit node represents a composite literal.
+ CompositeLit struct {
+ Type Expr // literal type; or nil
+ Lbrace token.Pos // position of "{"
+ Elts []Expr // list of composite elements; or nil
+ Rbrace token.Pos // position of "}"
+ Incomplete bool // true if (source) expressions are missing in the Elts list
+ }
+
+ // A ParenExpr node represents a parenthesized expression.
+ ParenExpr struct {
+ Lparen token.Pos // position of "("
+ X Expr // parenthesized expression
+ Rparen token.Pos // position of ")"
+ }
+
+ // A SelectorExpr node represents an expression followed by a selector.
+ SelectorExpr struct {
+ X Expr // expression
+ Sel *Ident // field selector
+ }
+
+ // An IndexExpr node represents an expression followed by an index.
+ IndexExpr struct {
+ X Expr // expression
+ Lbrack token.Pos // position of "["
+ Index Expr // index expression
+ Rbrack token.Pos // position of "]"
+ }
+
+ // An IndexListExpr node represents an expression followed by multiple
+ // indices.
+ IndexListExpr struct {
+ X Expr // expression
+ Lbrack token.Pos // position of "["
+ Indices []Expr // index expressions
+ Rbrack token.Pos // position of "]"
+ }
+
+ // A SliceExpr node represents an expression followed by slice indices.
+ SliceExpr struct {
+ X Expr // expression
+ Lbrack token.Pos // position of "["
+ Low Expr // begin of slice range; or nil
+ High Expr // end of slice range; or nil
+ Max Expr // maximum capacity of slice; or nil
+ Slice3 bool // true if 3-index slice (2 colons present)
+ Rbrack token.Pos // position of "]"
+ }
+
+ // A TypeAssertExpr node represents an expression followed by a
+ // type assertion.
+ //
+ TypeAssertExpr struct {
+ X Expr // expression
+ Lparen token.Pos // position of "("
+ Type Expr // asserted type; nil means type switch X.(type)
+ Rparen token.Pos // position of ")"
+ }
+
+ // A CallExpr node represents an expression followed by an argument list.
+ CallExpr struct {
+ Fun Expr // function expression
+ Lparen token.Pos // position of "("
+ Args []Expr // function arguments; or nil
+ Ellipsis token.Pos // position of "..." (token.NoPos if there is no "...")
+ Rparen token.Pos // position of ")"
+ }
+
+ // A StarExpr node represents an expression of the form "*" Expression.
+ // Semantically it could be a unary "*" expression, or a pointer type.
+ //
+ StarExpr struct {
+ Star token.Pos // position of "*"
+ X Expr // operand
+ }
+
+ // A UnaryExpr node represents a unary expression.
+ // Unary "*" expressions are represented via StarExpr nodes.
+ //
+ UnaryExpr struct {
+ OpPos token.Pos // position of Op
+ Op token.Token // operator
+ X Expr // operand
+ }
+
+ // A BinaryExpr node represents a binary expression.
+ BinaryExpr struct {
+ X Expr // left operand
+ OpPos token.Pos // position of Op
+ Op token.Token // operator
+ Y Expr // right operand
+ }
+
+ // A KeyValueExpr node represents (key : value) pairs
+ // in composite literals.
+ //
+ KeyValueExpr struct {
+ Key Expr
+ Colon token.Pos // position of ":"
+ Value Expr
+ }
+)
+
+// The direction of a channel type is indicated by a bit
+// mask including one or both of the following constants.
+type ChanDir int
+
+const (
+ SEND ChanDir = 1 << iota
+ RECV
+)
+
+// A type is represented by a tree consisting of one
+// or more of the following type-specific expression
+// nodes.
+type (
+ // An ArrayType node represents an array or slice type.
+ ArrayType struct {
+ Lbrack token.Pos // position of "["
+ Len Expr // Ellipsis node for [...]T array types, nil for slice types
+ Elt Expr // element type
+ }
+
+ // A StructType node represents a struct type.
+ StructType struct {
+ Struct token.Pos // position of "struct" keyword
+ Fields *FieldList // list of field declarations
+ Incomplete bool // true if (source) fields are missing in the Fields list
+ }
+
+ // Pointer types are represented via StarExpr nodes.
+
+ // A FuncType node represents a function type.
+ FuncType struct {
+ Func token.Pos // position of "func" keyword (token.NoPos if there is no "func")
+ TypeParams *FieldList // type parameters; or nil
+ Params *FieldList // (incoming) parameters; non-nil
+ Results *FieldList // (outgoing) results; or nil
+ }
+
+ // An InterfaceType node represents an interface type.
+ InterfaceType struct {
+ Interface token.Pos // position of "interface" keyword
+ Methods *FieldList // list of embedded interfaces, methods, or types
+ Incomplete bool // true if (source) methods or types are missing in the Methods list
+ }
+
+ // A MapType node represents a map type.
+ MapType struct {
+ Map token.Pos // position of "map" keyword
+ Key Expr
+ Value Expr
+ }
+
+ // A ChanType node represents a channel type.
+ ChanType struct {
+ Begin token.Pos // position of "chan" keyword or "<-" (whichever comes first)
+ Arrow token.Pos // position of "<-" (token.NoPos if there is no "<-")
+ Dir ChanDir // channel direction
+ Value Expr // value type
+ }
+)
+
+// Pos and End implementations for expression/type nodes.
+
+func (x *BadExpr) Pos() token.Pos { return x.From }
+func (x *Ident) Pos() token.Pos { return x.NamePos }
+func (x *Ellipsis) Pos() token.Pos { return x.Ellipsis }
+func (x *BasicLit) Pos() token.Pos { return x.ValuePos }
+func (x *FuncLit) Pos() token.Pos { return x.Type.Pos() }
+func (x *CompositeLit) Pos() token.Pos {
+ if x.Type != nil {
+ return x.Type.Pos()
+ }
+ return x.Lbrace
+}
+func (x *ParenExpr) Pos() token.Pos { return x.Lparen }
+func (x *SelectorExpr) Pos() token.Pos { return x.X.Pos() }
+func (x *IndexExpr) Pos() token.Pos { return x.X.Pos() }
+func (x *IndexListExpr) Pos() token.Pos { return x.X.Pos() }
+func (x *SliceExpr) Pos() token.Pos { return x.X.Pos() }
+func (x *TypeAssertExpr) Pos() token.Pos { return x.X.Pos() }
+func (x *CallExpr) Pos() token.Pos { return x.Fun.Pos() }
+func (x *StarExpr) Pos() token.Pos { return x.Star }
+func (x *UnaryExpr) Pos() token.Pos { return x.OpPos }
+func (x *BinaryExpr) Pos() token.Pos { return x.X.Pos() }
+func (x *KeyValueExpr) Pos() token.Pos { return x.Key.Pos() }
+func (x *ArrayType) Pos() token.Pos { return x.Lbrack }
+func (x *StructType) Pos() token.Pos { return x.Struct }
+func (x *FuncType) Pos() token.Pos {
+ if x.Func.IsValid() || x.Params == nil { // see issue 3870
+ return x.Func
+ }
+ return x.Params.Pos() // interface method declarations have no "func" keyword
+}
+func (x *InterfaceType) Pos() token.Pos { return x.Interface }
+func (x *MapType) Pos() token.Pos { return x.Map }
+func (x *ChanType) Pos() token.Pos { return x.Begin }
+
+func (x *BadExpr) End() token.Pos { return x.To }
+func (x *Ident) End() token.Pos { return token.Pos(int(x.NamePos) + len(x.Name)) }
+func (x *Ellipsis) End() token.Pos {
+ if x.Elt != nil {
+ return x.Elt.End()
+ }
+ return x.Ellipsis + 3 // len("...")
+}
+func (x *BasicLit) End() token.Pos { return token.Pos(int(x.ValuePos) + len(x.Value)) }
+func (x *FuncLit) End() token.Pos { return x.Body.End() }
+func (x *CompositeLit) End() token.Pos { return x.Rbrace + 1 }
+func (x *ParenExpr) End() token.Pos { return x.Rparen + 1 }
+func (x *SelectorExpr) End() token.Pos { return x.Sel.End() }
+func (x *IndexExpr) End() token.Pos { return x.Rbrack + 1 }
+func (x *IndexListExpr) End() token.Pos { return x.Rbrack + 1 }
+func (x *SliceExpr) End() token.Pos { return x.Rbrack + 1 }
+func (x *TypeAssertExpr) End() token.Pos { return x.Rparen + 1 }
+func (x *CallExpr) End() token.Pos { return x.Rparen + 1 }
+func (x *StarExpr) End() token.Pos { return x.X.End() }
+func (x *UnaryExpr) End() token.Pos { return x.X.End() }
+func (x *BinaryExpr) End() token.Pos { return x.Y.End() }
+func (x *KeyValueExpr) End() token.Pos { return x.Value.End() }
+func (x *ArrayType) End() token.Pos { return x.Elt.End() }
+func (x *StructType) End() token.Pos { return x.Fields.End() }
+func (x *FuncType) End() token.Pos {
+ if x.Results != nil {
+ return x.Results.End()
+ }
+ return x.Params.End()
+}
+func (x *InterfaceType) End() token.Pos { return x.Methods.End() }
+func (x *MapType) End() token.Pos { return x.Value.End() }
+func (x *ChanType) End() token.Pos { return x.Value.End() }
+
+// exprNode() ensures that only expression/type nodes can be
+// assigned to an Expr.
+func (*BadExpr) exprNode() {}
+func (*Ident) exprNode() {}
+func (*Ellipsis) exprNode() {}
+func (*BasicLit) exprNode() {}
+func (*FuncLit) exprNode() {}
+func (*CompositeLit) exprNode() {}
+func (*ParenExpr) exprNode() {}
+func (*SelectorExpr) exprNode() {}
+func (*IndexExpr) exprNode() {}
+func (*IndexListExpr) exprNode() {}
+func (*SliceExpr) exprNode() {}
+func (*TypeAssertExpr) exprNode() {}
+func (*CallExpr) exprNode() {}
+func (*StarExpr) exprNode() {}
+func (*UnaryExpr) exprNode() {}
+func (*BinaryExpr) exprNode() {}
+func (*KeyValueExpr) exprNode() {}
+
+func (*ArrayType) exprNode() {}
+func (*StructType) exprNode() {}
+func (*FuncType) exprNode() {}
+func (*InterfaceType) exprNode() {}
+func (*MapType) exprNode() {}
+func (*ChanType) exprNode() {}
+
+// ----------------------------------------------------------------------------
+// Convenience functions for Idents
+
+// NewIdent creates a new Ident without position.
+// Useful for ASTs generated by code other than the Go parser.
+func NewIdent(name string) *Ident { return &Ident{token.NoPos, name, nil} }
+
+// IsExported reports whether name starts with an upper-case letter.
+func IsExported(name string) bool { return token.IsExported(name) }
+
+// IsExported reports whether id starts with an upper-case letter.
+func (id *Ident) IsExported() bool { return token.IsExported(id.Name) }
+
+func (id *Ident) String() string {
+ if id != nil {
+ return id.Name
+ }
+ return "<nil>"
+}
+
+// ----------------------------------------------------------------------------
+// Statements
+
+// A statement is represented by a tree consisting of one
+// or more of the following concrete statement nodes.
+type (
+ // A BadStmt node is a placeholder for statements containing
+ // syntax errors for which no correct statement nodes can be
+ // created.
+ //
+ BadStmt struct {
+ From, To token.Pos // position range of bad statement
+ }
+
+ // A DeclStmt node represents a declaration in a statement list.
+ DeclStmt struct {
+ Decl Decl // *GenDecl with CONST, TYPE, or VAR token
+ }
+
+ // An EmptyStmt node represents an empty statement.
+ // The "position" of the empty statement is the position
+ // of the immediately following (explicit or implicit) semicolon.
+ //
+ EmptyStmt struct {
+ Semicolon token.Pos // position of following ";"
+ Implicit bool // if set, ";" was omitted in the source
+ }
+
+ // A LabeledStmt node represents a labeled statement.
+ LabeledStmt struct {
+ Label *Ident
+ Colon token.Pos // position of ":"
+ Stmt Stmt
+ }
+
+ // An ExprStmt node represents a (stand-alone) expression
+ // in a statement list.
+ //
+ ExprStmt struct {
+ X Expr // expression
+ }
+
+ // A SendStmt node represents a send statement.
+ SendStmt struct {
+ Chan Expr
+ Arrow token.Pos // position of "<-"
+ Value Expr
+ }
+
+ // An IncDecStmt node represents an increment or decrement statement.
+ IncDecStmt struct {
+ X Expr
+ TokPos token.Pos // position of Tok
+ Tok token.Token // INC or DEC
+ }
+
+ // An AssignStmt node represents an assignment or
+ // a short variable declaration.
+ //
+ AssignStmt struct {
+ Lhs []Expr
+ TokPos token.Pos // position of Tok
+ Tok token.Token // assignment token, DEFINE
+ Rhs []Expr
+ }
+
+ // A GoStmt node represents a go statement.
+ GoStmt struct {
+ Go token.Pos // position of "go" keyword
+ Call *CallExpr
+ }
+
+ // A DeferStmt node represents a defer statement.
+ DeferStmt struct {
+ Defer token.Pos // position of "defer" keyword
+ Call *CallExpr
+ }
+
+ // A ReturnStmt node represents a return statement.
+ ReturnStmt struct {
+ Return token.Pos // position of "return" keyword
+ Results []Expr // result expressions; or nil
+ }
+
+ // A BranchStmt node represents a break, continue, goto,
+ // or fallthrough statement.
+ //
+ BranchStmt struct {
+ TokPos token.Pos // position of Tok
+ Tok token.Token // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
+ Label *Ident // label name; or nil
+ }
+
+ // A BlockStmt node represents a braced statement list.
+ BlockStmt struct {
+ Lbrace token.Pos // position of "{"
+ List []Stmt
+ Rbrace token.Pos // position of "}", if any (may be absent due to syntax error)
+ }
+
+ // An IfStmt node represents an if statement.
+ IfStmt struct {
+ If token.Pos // position of "if" keyword
+ Init Stmt // initialization statement; or nil
+ Cond Expr // condition
+ Body *BlockStmt
+ Else Stmt // else branch; or nil
+ }
+
+ // A CaseClause represents a case of an expression or type switch statement.
+ CaseClause struct {
+ Case token.Pos // position of "case" or "default" keyword
+ List []Expr // list of expressions or types; nil means default case
+ Colon token.Pos // position of ":"
+ Body []Stmt // statement list; or nil
+ }
+
+ // A SwitchStmt node represents an expression switch statement.
+ SwitchStmt struct {
+ Switch token.Pos // position of "switch" keyword
+ Init Stmt // initialization statement; or nil
+ Tag Expr // tag expression; or nil
+ Body *BlockStmt // CaseClauses only
+ }
+
+ // A TypeSwitchStmt node represents a type switch statement.
+ TypeSwitchStmt struct {
+ Switch token.Pos // position of "switch" keyword
+ Init Stmt // initialization statement; or nil
+ Assign Stmt // x := y.(type) or y.(type)
+ Body *BlockStmt // CaseClauses only
+ }
+
+ // A CommClause node represents a case of a select statement.
+ CommClause struct {
+ Case token.Pos // position of "case" or "default" keyword
+ Comm Stmt // send or receive statement; nil means default case
+ Colon token.Pos // position of ":"
+ Body []Stmt // statement list; or nil
+ }
+
+ // A SelectStmt node represents a select statement.
+ SelectStmt struct {
+ Select token.Pos // position of "select" keyword
+ Body *BlockStmt // CommClauses only
+ }
+
+ // A ForStmt represents a for statement.
+ ForStmt struct {
+ For token.Pos // position of "for" keyword
+ Init Stmt // initialization statement; or nil
+ Cond Expr // condition; or nil
+ Post Stmt // post iteration statement; or nil
+ Body *BlockStmt
+ }
+
+ // A RangeStmt represents a for statement with a range clause.
+ RangeStmt struct {
+ For token.Pos // position of "for" keyword
+ Key, Value Expr // Key, Value may be nil
+ TokPos token.Pos // position of Tok; invalid if Key == nil
+ Tok token.Token // ILLEGAL if Key == nil, ASSIGN, DEFINE
+ Range token.Pos // position of "range" keyword
+ X Expr // value to range over
+ Body *BlockStmt
+ }
+)
+
+// Pos and End implementations for statement nodes.
+
+func (s *BadStmt) Pos() token.Pos { return s.From }
+func (s *DeclStmt) Pos() token.Pos { return s.Decl.Pos() }
+func (s *EmptyStmt) Pos() token.Pos { return s.Semicolon }
+func (s *LabeledStmt) Pos() token.Pos { return s.Label.Pos() }
+func (s *ExprStmt) Pos() token.Pos { return s.X.Pos() }
+func (s *SendStmt) Pos() token.Pos { return s.Chan.Pos() }
+func (s *IncDecStmt) Pos() token.Pos { return s.X.Pos() }
+func (s *AssignStmt) Pos() token.Pos { return s.Lhs[0].Pos() }
+func (s *GoStmt) Pos() token.Pos { return s.Go }
+func (s *DeferStmt) Pos() token.Pos { return s.Defer }
+func (s *ReturnStmt) Pos() token.Pos { return s.Return }
+func (s *BranchStmt) Pos() token.Pos { return s.TokPos }
+func (s *BlockStmt) Pos() token.Pos { return s.Lbrace }
+func (s *IfStmt) Pos() token.Pos { return s.If }
+func (s *CaseClause) Pos() token.Pos { return s.Case }
+func (s *SwitchStmt) Pos() token.Pos { return s.Switch }
+func (s *TypeSwitchStmt) Pos() token.Pos { return s.Switch }
+func (s *CommClause) Pos() token.Pos { return s.Case }
+func (s *SelectStmt) Pos() token.Pos { return s.Select }
+func (s *ForStmt) Pos() token.Pos { return s.For }
+func (s *RangeStmt) Pos() token.Pos { return s.For }
+
+func (s *BadStmt) End() token.Pos { return s.To }
+func (s *DeclStmt) End() token.Pos { return s.Decl.End() }
+func (s *EmptyStmt) End() token.Pos {
+ if s.Implicit {
+ return s.Semicolon
+ }
+ return s.Semicolon + 1 /* len(";") */
+}
+func (s *LabeledStmt) End() token.Pos { return s.Stmt.End() }
+func (s *ExprStmt) End() token.Pos { return s.X.End() }
+func (s *SendStmt) End() token.Pos { return s.Value.End() }
+func (s *IncDecStmt) End() token.Pos {
+ return s.TokPos + 2 /* len("++") */
+}
+func (s *AssignStmt) End() token.Pos { return s.Rhs[len(s.Rhs)-1].End() }
+func (s *GoStmt) End() token.Pos { return s.Call.End() }
+func (s *DeferStmt) End() token.Pos { return s.Call.End() }
+func (s *ReturnStmt) End() token.Pos {
+ if n := len(s.Results); n > 0 {
+ return s.Results[n-1].End()
+ }
+ return s.Return + 6 // len("return")
+}
+func (s *BranchStmt) End() token.Pos {
+ if s.Label != nil {
+ return s.Label.End()
+ }
+ return token.Pos(int(s.TokPos) + len(s.Tok.String()))
+}
+func (s *BlockStmt) End() token.Pos {
+ if s.Rbrace.IsValid() {
+ return s.Rbrace + 1
+ }
+ if n := len(s.List); n > 0 {
+ return s.List[n-1].End()
+ }
+ return s.Lbrace + 1
+}
+func (s *IfStmt) End() token.Pos {
+ if s.Else != nil {
+ return s.Else.End()
+ }
+ return s.Body.End()
+}
+func (s *CaseClause) End() token.Pos {
+ if n := len(s.Body); n > 0 {
+ return s.Body[n-1].End()
+ }
+ return s.Colon + 1
+}
+func (s *SwitchStmt) End() token.Pos { return s.Body.End() }
+func (s *TypeSwitchStmt) End() token.Pos { return s.Body.End() }
+func (s *CommClause) End() token.Pos {
+ if n := len(s.Body); n > 0 {
+ return s.Body[n-1].End()
+ }
+ return s.Colon + 1
+}
+func (s *SelectStmt) End() token.Pos { return s.Body.End() }
+func (s *ForStmt) End() token.Pos { return s.Body.End() }
+func (s *RangeStmt) End() token.Pos { return s.Body.End() }
+
+// stmtNode() ensures that only statement nodes can be
+// assigned to a Stmt.
+func (*BadStmt) stmtNode() {}
+func (*DeclStmt) stmtNode() {}
+func (*EmptyStmt) stmtNode() {}
+func (*LabeledStmt) stmtNode() {}
+func (*ExprStmt) stmtNode() {}
+func (*SendStmt) stmtNode() {}
+func (*IncDecStmt) stmtNode() {}
+func (*AssignStmt) stmtNode() {}
+func (*GoStmt) stmtNode() {}
+func (*DeferStmt) stmtNode() {}
+func (*ReturnStmt) stmtNode() {}
+func (*BranchStmt) stmtNode() {}
+func (*BlockStmt) stmtNode() {}
+func (*IfStmt) stmtNode() {}
+func (*CaseClause) stmtNode() {}
+func (*SwitchStmt) stmtNode() {}
+func (*TypeSwitchStmt) stmtNode() {}
+func (*CommClause) stmtNode() {}
+func (*SelectStmt) stmtNode() {}
+func (*ForStmt) stmtNode() {}
+func (*RangeStmt) stmtNode() {}
+
+// ----------------------------------------------------------------------------
+// Declarations
+
+// A Spec node represents a single (non-parenthesized) import,
+// constant, type, or variable declaration.
+type (
+ // The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec.
+ Spec interface {
+ Node
+ specNode()
+ }
+
+ // An ImportSpec node represents a single package import.
+ ImportSpec struct {
+ Doc *CommentGroup // associated documentation; or nil
+ Name *Ident // local package name (including "."); or nil
+ Path *BasicLit // import path
+ Comment *CommentGroup // line comments; or nil
+ EndPos token.Pos // end of spec (overrides Path.Pos if nonzero)
+ }
+
+ // A ValueSpec node represents a constant or variable declaration
+ // (ConstSpec or VarSpec production).
+ //
+ ValueSpec struct {
+ Doc *CommentGroup // associated documentation; or nil
+ Names []*Ident // value names (len(Names) > 0)
+ Type Expr // value type; or nil
+ Values []Expr // initial values; or nil
+ Comment *CommentGroup // line comments; or nil
+ }
+
+ // A TypeSpec node represents a type declaration (TypeSpec production).
+ TypeSpec struct {
+ Doc *CommentGroup // associated documentation; or nil
+ Name *Ident // type name
+ TypeParams *FieldList // type parameters; or nil
+ Assign token.Pos // position of '=', if any
+ Type Expr // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes
+ Comment *CommentGroup // line comments; or nil
+ }
+)
+
+// Pos and End implementations for spec nodes.
+
+func (s *ImportSpec) Pos() token.Pos {
+ if s.Name != nil {
+ return s.Name.Pos()
+ }
+ return s.Path.Pos()
+}
+func (s *ValueSpec) Pos() token.Pos { return s.Names[0].Pos() }
+func (s *TypeSpec) Pos() token.Pos { return s.Name.Pos() }
+
+func (s *ImportSpec) End() token.Pos {
+ if s.EndPos != 0 {
+ return s.EndPos
+ }
+ return s.Path.End()
+}
+
+func (s *ValueSpec) End() token.Pos {
+ if n := len(s.Values); n > 0 {
+ return s.Values[n-1].End()
+ }
+ if s.Type != nil {
+ return s.Type.End()
+ }
+ return s.Names[len(s.Names)-1].End()
+}
+func (s *TypeSpec) End() token.Pos { return s.Type.End() }
+
+// specNode() ensures that only spec nodes can be
+// assigned to a Spec.
+func (*ImportSpec) specNode() {}
+func (*ValueSpec) specNode() {}
+func (*TypeSpec) specNode() {}
+
+// A declaration is represented by one of the following declaration nodes.
+type (
+ // A BadDecl node is a placeholder for a declaration containing
+ // syntax errors for which a correct declaration node cannot be
+ // created.
+ //
+ BadDecl struct {
+ From, To token.Pos // position range of bad declaration
+ }
+
+ // A GenDecl node (generic declaration node) represents an import,
+ // constant, type or variable declaration. A valid Lparen position
+ // (Lparen.IsValid()) indicates a parenthesized declaration.
+ //
+ // Relationship between Tok value and Specs element type:
+ //
+ // token.IMPORT *ImportSpec
+ // token.CONST *ValueSpec
+ // token.TYPE *TypeSpec
+ // token.VAR *ValueSpec
+ //
+ GenDecl struct {
+ Doc *CommentGroup // associated documentation; or nil
+ TokPos token.Pos // position of Tok
+ Tok token.Token // IMPORT, CONST, TYPE, or VAR
+ Lparen token.Pos // position of '(', if any
+ Specs []Spec
+ Rparen token.Pos // position of ')', if any
+ }
+
+ // A FuncDecl node represents a function declaration.
+ FuncDecl struct {
+ Doc *CommentGroup // associated documentation; or nil
+ Recv *FieldList // receiver (methods); or nil (functions)
+ Name *Ident // function/method name
+ Type *FuncType // function signature: type and value parameters, results, and position of "func" keyword
+ Body *BlockStmt // function body; or nil for external (non-Go) function
+ }
+)
+
+// Pos and End implementations for declaration nodes.
+
+func (d *BadDecl) Pos() token.Pos { return d.From }
+func (d *GenDecl) Pos() token.Pos { return d.TokPos }
+func (d *FuncDecl) Pos() token.Pos { return d.Type.Pos() }
+
+func (d *BadDecl) End() token.Pos { return d.To }
+func (d *GenDecl) End() token.Pos {
+ if d.Rparen.IsValid() {
+ return d.Rparen + 1
+ }
+ return d.Specs[0].End()
+}
+func (d *FuncDecl) End() token.Pos {
+ if d.Body != nil {
+ return d.Body.End()
+ }
+ return d.Type.End()
+}
+
+// declNode() ensures that only declaration nodes can be
+// assigned to a Decl.
+func (*BadDecl) declNode() {}
+func (*GenDecl) declNode() {}
+func (*FuncDecl) declNode() {}
+
+// ----------------------------------------------------------------------------
+// Files and packages
+
+// A File node represents a Go source file.
+//
+// The Comments list contains all comments in the source file in order of
+// appearance, including the comments that are pointed to from other nodes
+// via Doc and Comment fields.
+//
+// For correct printing of source code containing comments (using packages
+// go/format and go/printer), special care must be taken to update comments
+// when a File's syntax tree is modified: For printing, comments are interspersed
+// between tokens based on their position. If syntax tree nodes are
+// removed or moved, relevant comments in their vicinity must also be removed
+// (from the File.Comments list) or moved accordingly (by updating their
+// positions). A CommentMap may be used to facilitate some of these operations.
+//
+// Whether and how a comment is associated with a node depends on the
+// interpretation of the syntax tree by the manipulating program: Except for Doc
+// and Comment comments directly associated with nodes, the remaining comments
+// are "free-floating" (see also issues #18593, #20744).
+type File struct {
+ Doc *CommentGroup // associated documentation; or nil
+ Package token.Pos // position of "package" keyword
+ Name *Ident // package name
+ Decls []Decl // top-level declarations; or nil
+
+ FileStart, FileEnd token.Pos // start and end of entire file
+ Scope *Scope // package scope (this file only)
+ Imports []*ImportSpec // imports in this file
+ Unresolved []*Ident // unresolved identifiers in this file
+ Comments []*CommentGroup // list of all comments in the source file
+ GoVersion string // minimum Go version required by //go:build or // +build directives
+}
+
+// Pos returns the position of the package declaration.
+// (Use FileStart for the start of the entire file.)
+func (f *File) Pos() token.Pos { return f.Package }
+
+// End returns the end of the last declaration in the file.
+// (Use FileEnd for the end of the entire file.)
+func (f *File) End() token.Pos {
+ if n := len(f.Decls); n > 0 {
+ return f.Decls[n-1].End()
+ }
+ return f.Name.End()
+}
+
+// A Package node represents a set of source files
+// collectively building a Go package.
+type Package struct {
+ Name string // package name
+ Scope *Scope // package scope across all files
+ Imports map[string]*Object // map of package id -> package object
+ Files map[string]*File // Go source files by filename
+}
+
+func (p *Package) Pos() token.Pos { return token.NoPos }
+func (p *Package) End() token.Pos { return token.NoPos }
+
+// IsGenerated reports whether the file was generated by a program,
+// not handwritten, by detecting the special comment described
+// at https://go.dev/s/generatedcode.
+//
+// The syntax tree must have been parsed with the ParseComments flag.
+// Example:
+//
+// f, err := parser.ParseFile(fset, filename, src, parser.ParseComments|parser.PackageClauseOnly)
+// if err != nil { ... }
+// gen := ast.IsGenerated(f)
+func IsGenerated(file *File) bool {
+ _, ok := generator(file)
+ return ok
+}
+
+func generator(file *File) (string, bool) {
+ for _, group := range file.Comments {
+ for _, comment := range group.List {
+ if comment.Pos() > file.Package {
+ break // after package declaration
+ }
+ // opt: check Contains first to avoid unnecessary array allocation in Split.
+ const prefix = "// Code generated "
+ if strings.Contains(comment.Text, prefix) {
+ for _, line := range strings.Split(comment.Text, "\n") {
+ if rest, ok := strings.CutPrefix(line, prefix); ok {
+ if gen, ok := strings.CutSuffix(rest, " DO NOT EDIT."); ok {
+ return gen, true
+ }
+ }
+ }
+ }
+ }
+ }
+ return "", false
+}
diff --git a/contrib/go/_std_1.20/src/go/ast/commentmap.go b/contrib/go/_std_1.21/src/go/ast/commentmap.go
index 4196e475d9..4196e475d9 100644
--- a/contrib/go/_std_1.20/src/go/ast/commentmap.go
+++ b/contrib/go/_std_1.21/src/go/ast/commentmap.go
diff --git a/contrib/go/_std_1.21/src/go/ast/filter.go b/contrib/go/_std_1.21/src/go/ast/filter.go
new file mode 100644
index 0000000000..c9e733a5a5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/ast/filter.go
@@ -0,0 +1,495 @@
+// Copyright 2009 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 ast
+
+import (
+ "go/token"
+ "sort"
+)
+
+// ----------------------------------------------------------------------------
+// Export filtering
+
+// exportFilter is a special filter function to extract exported nodes.
+func exportFilter(name string) bool {
+ return IsExported(name)
+}
+
+// FileExports trims the AST for a Go source file in place such that
+// only exported nodes remain: all top-level identifiers which are not exported
+// and their associated information (such as type, initial value, or function
+// body) are removed. Non-exported fields and methods of exported types are
+// stripped. The File.Comments list is not changed.
+//
+// FileExports reports whether there are exported declarations.
+func FileExports(src *File) bool {
+ return filterFile(src, exportFilter, true)
+}
+
+// PackageExports trims the AST for a Go package in place such that
+// only exported nodes remain. The pkg.Files list is not changed, so that
+// file names and top-level package comments don't get lost.
+//
+// PackageExports reports whether there are exported declarations;
+// it returns false otherwise.
+func PackageExports(pkg *Package) bool {
+ return filterPackage(pkg, exportFilter, true)
+}
+
+// ----------------------------------------------------------------------------
+// General filtering
+
+type Filter func(string) bool
+
+func filterIdentList(list []*Ident, f Filter) []*Ident {
+ j := 0
+ for _, x := range list {
+ if f(x.Name) {
+ list[j] = x
+ j++
+ }
+ }
+ return list[0:j]
+}
+
+// fieldName assumes that x is the type of an anonymous field and
+// returns the corresponding field name. If x is not an acceptable
+// anonymous field, the result is nil.
+func fieldName(x Expr) *Ident {
+ switch t := x.(type) {
+ case *Ident:
+ return t
+ case *SelectorExpr:
+ if _, ok := t.X.(*Ident); ok {
+ return t.Sel
+ }
+ case *StarExpr:
+ return fieldName(t.X)
+ }
+ return nil
+}
+
+func filterFieldList(fields *FieldList, filter Filter, export bool) (removedFields bool) {
+ if fields == nil {
+ return false
+ }
+ list := fields.List
+ j := 0
+ for _, f := range list {
+ keepField := false
+ if len(f.Names) == 0 {
+ // anonymous field
+ name := fieldName(f.Type)
+ keepField = name != nil && filter(name.Name)
+ } else {
+ n := len(f.Names)
+ f.Names = filterIdentList(f.Names, filter)
+ if len(f.Names) < n {
+ removedFields = true
+ }
+ keepField = len(f.Names) > 0
+ }
+ if keepField {
+ if export {
+ filterType(f.Type, filter, export)
+ }
+ list[j] = f
+ j++
+ }
+ }
+ if j < len(list) {
+ removedFields = true
+ }
+ fields.List = list[0:j]
+ return
+}
+
+func filterCompositeLit(lit *CompositeLit, filter Filter, export bool) {
+ n := len(lit.Elts)
+ lit.Elts = filterExprList(lit.Elts, filter, export)
+ if len(lit.Elts) < n {
+ lit.Incomplete = true
+ }
+}
+
+func filterExprList(list []Expr, filter Filter, export bool) []Expr {
+ j := 0
+ for _, exp := range list {
+ switch x := exp.(type) {
+ case *CompositeLit:
+ filterCompositeLit(x, filter, export)
+ case *KeyValueExpr:
+ if x, ok := x.Key.(*Ident); ok && !filter(x.Name) {
+ continue
+ }
+ if x, ok := x.Value.(*CompositeLit); ok {
+ filterCompositeLit(x, filter, export)
+ }
+ }
+ list[j] = exp
+ j++
+ }
+ return list[0:j]
+}
+
+func filterParamList(fields *FieldList, filter Filter, export bool) bool {
+ if fields == nil {
+ return false
+ }
+ var b bool
+ for _, f := range fields.List {
+ if filterType(f.Type, filter, export) {
+ b = true
+ }
+ }
+ return b
+}
+
+func filterType(typ Expr, f Filter, export bool) bool {
+ switch t := typ.(type) {
+ case *Ident:
+ return f(t.Name)
+ case *ParenExpr:
+ return filterType(t.X, f, export)
+ case *ArrayType:
+ return filterType(t.Elt, f, export)
+ case *StructType:
+ if filterFieldList(t.Fields, f, export) {
+ t.Incomplete = true
+ }
+ return len(t.Fields.List) > 0
+ case *FuncType:
+ b1 := filterParamList(t.Params, f, export)
+ b2 := filterParamList(t.Results, f, export)
+ return b1 || b2
+ case *InterfaceType:
+ if filterFieldList(t.Methods, f, export) {
+ t.Incomplete = true
+ }
+ return len(t.Methods.List) > 0
+ case *MapType:
+ b1 := filterType(t.Key, f, export)
+ b2 := filterType(t.Value, f, export)
+ return b1 || b2
+ case *ChanType:
+ return filterType(t.Value, f, export)
+ }
+ return false
+}
+
+func filterSpec(spec Spec, f Filter, export bool) bool {
+ switch s := spec.(type) {
+ case *ValueSpec:
+ s.Names = filterIdentList(s.Names, f)
+ s.Values = filterExprList(s.Values, f, export)
+ if len(s.Names) > 0 {
+ if export {
+ filterType(s.Type, f, export)
+ }
+ return true
+ }
+ case *TypeSpec:
+ if f(s.Name.Name) {
+ if export {
+ filterType(s.Type, f, export)
+ }
+ return true
+ }
+ if !export {
+ // For general filtering (not just exports),
+ // filter type even if name is not filtered
+ // out.
+ // If the type contains filtered elements,
+ // keep the declaration.
+ return filterType(s.Type, f, export)
+ }
+ }
+ return false
+}
+
+func filterSpecList(list []Spec, f Filter, export bool) []Spec {
+ j := 0
+ for _, s := range list {
+ if filterSpec(s, f, export) {
+ list[j] = s
+ j++
+ }
+ }
+ return list[0:j]
+}
+
+// FilterDecl trims the AST for a Go declaration in place by removing
+// all names (including struct field and interface method names, but
+// not from parameter lists) that don't pass through the filter f.
+//
+// FilterDecl reports whether there are any declared names left after
+// filtering.
+func FilterDecl(decl Decl, f Filter) bool {
+ return filterDecl(decl, f, false)
+}
+
+func filterDecl(decl Decl, f Filter, export bool) bool {
+ switch d := decl.(type) {
+ case *GenDecl:
+ d.Specs = filterSpecList(d.Specs, f, export)
+ return len(d.Specs) > 0
+ case *FuncDecl:
+ return f(d.Name.Name)
+ }
+ return false
+}
+
+// FilterFile trims the AST for a Go file in place by removing all
+// names from top-level declarations (including struct field and
+// interface method names, but not from parameter lists) that don't
+// pass through the filter f. If the declaration is empty afterwards,
+// the declaration is removed from the AST. Import declarations are
+// always removed. The File.Comments list is not changed.
+//
+// FilterFile reports whether there are any top-level declarations
+// left after filtering.
+func FilterFile(src *File, f Filter) bool {
+ return filterFile(src, f, false)
+}
+
+func filterFile(src *File, f Filter, export bool) bool {
+ j := 0
+ for _, d := range src.Decls {
+ if filterDecl(d, f, export) {
+ src.Decls[j] = d
+ j++
+ }
+ }
+ src.Decls = src.Decls[0:j]
+ return j > 0
+}
+
+// FilterPackage trims the AST for a Go package in place by removing
+// all names from top-level declarations (including struct field and
+// interface method names, but not from parameter lists) that don't
+// pass through the filter f. If the declaration is empty afterwards,
+// the declaration is removed from the AST. The pkg.Files list is not
+// changed, so that file names and top-level package comments don't get
+// lost.
+//
+// FilterPackage reports whether there are any top-level declarations
+// left after filtering.
+func FilterPackage(pkg *Package, f Filter) bool {
+ return filterPackage(pkg, f, false)
+}
+
+func filterPackage(pkg *Package, f Filter, export bool) bool {
+ hasDecls := false
+ for _, src := range pkg.Files {
+ if filterFile(src, f, export) {
+ hasDecls = true
+ }
+ }
+ return hasDecls
+}
+
+// ----------------------------------------------------------------------------
+// Merging of package files
+
+// The MergeMode flags control the behavior of MergePackageFiles.
+type MergeMode uint
+
+const (
+ // If set, duplicate function declarations are excluded.
+ FilterFuncDuplicates MergeMode = 1 << iota
+ // If set, comments that are not associated with a specific
+ // AST node (as Doc or Comment) are excluded.
+ FilterUnassociatedComments
+ // If set, duplicate import declarations are excluded.
+ FilterImportDuplicates
+)
+
+// nameOf returns the function (foo) or method name (foo.bar) for
+// the given function declaration. If the AST is incorrect for the
+// receiver, it assumes a function instead.
+func nameOf(f *FuncDecl) string {
+ if r := f.Recv; r != nil && len(r.List) == 1 {
+ // looks like a correct receiver declaration
+ t := r.List[0].Type
+ // dereference pointer receiver types
+ if p, _ := t.(*StarExpr); p != nil {
+ t = p.X
+ }
+ // the receiver type must be a type name
+ if p, _ := t.(*Ident); p != nil {
+ return p.Name + "." + f.Name.Name
+ }
+ // otherwise assume a function instead
+ }
+ return f.Name.Name
+}
+
+// separator is an empty //-style comment that is interspersed between
+// different comment groups when they are concatenated into a single group
+var separator = &Comment{token.NoPos, "//"}
+
+// MergePackageFiles creates a file AST by merging the ASTs of the
+// files belonging to a package. The mode flags control merging behavior.
+func MergePackageFiles(pkg *Package, mode MergeMode) *File {
+ // Count the number of package docs, comments and declarations across
+ // all package files. Also, compute sorted list of filenames, so that
+ // subsequent iterations can always iterate in the same order.
+ ndocs := 0
+ ncomments := 0
+ ndecls := 0
+ filenames := make([]string, len(pkg.Files))
+ var minPos, maxPos token.Pos
+ i := 0
+ for filename, f := range pkg.Files {
+ filenames[i] = filename
+ i++
+ if f.Doc != nil {
+ ndocs += len(f.Doc.List) + 1 // +1 for separator
+ }
+ ncomments += len(f.Comments)
+ ndecls += len(f.Decls)
+ if i == 0 || f.FileStart < minPos {
+ minPos = f.FileStart
+ }
+ if i == 0 || f.FileEnd > maxPos {
+ maxPos = f.FileEnd
+ }
+ }
+ sort.Strings(filenames)
+
+ // Collect package comments from all package files into a single
+ // CommentGroup - the collected package documentation. In general
+ // there should be only one file with a package comment; but it's
+ // better to collect extra comments than drop them on the floor.
+ var doc *CommentGroup
+ var pos token.Pos
+ if ndocs > 0 {
+ list := make([]*Comment, ndocs-1) // -1: no separator before first group
+ i := 0
+ for _, filename := range filenames {
+ f := pkg.Files[filename]
+ if f.Doc != nil {
+ if i > 0 {
+ // not the first group - add separator
+ list[i] = separator
+ i++
+ }
+ for _, c := range f.Doc.List {
+ list[i] = c
+ i++
+ }
+ if f.Package > pos {
+ // Keep the maximum package clause position as
+ // position for the package clause of the merged
+ // files.
+ pos = f.Package
+ }
+ }
+ }
+ doc = &CommentGroup{list}
+ }
+
+ // Collect declarations from all package files.
+ var decls []Decl
+ if ndecls > 0 {
+ decls = make([]Decl, ndecls)
+ funcs := make(map[string]int) // map of func name -> decls index
+ i := 0 // current index
+ n := 0 // number of filtered entries
+ for _, filename := range filenames {
+ f := pkg.Files[filename]
+ for _, d := range f.Decls {
+ if mode&FilterFuncDuplicates != 0 {
+ // A language entity may be declared multiple
+ // times in different package files; only at
+ // build time declarations must be unique.
+ // For now, exclude multiple declarations of
+ // functions - keep the one with documentation.
+ //
+ // TODO(gri): Expand this filtering to other
+ // entities (const, type, vars) if
+ // multiple declarations are common.
+ if f, isFun := d.(*FuncDecl); isFun {
+ name := nameOf(f)
+ if j, exists := funcs[name]; exists {
+ // function declared already
+ if decls[j] != nil && decls[j].(*FuncDecl).Doc == nil {
+ // existing declaration has no documentation;
+ // ignore the existing declaration
+ decls[j] = nil
+ } else {
+ // ignore the new declaration
+ d = nil
+ }
+ n++ // filtered an entry
+ } else {
+ funcs[name] = i
+ }
+ }
+ }
+ decls[i] = d
+ i++
+ }
+ }
+
+ // Eliminate nil entries from the decls list if entries were
+ // filtered. We do this using a 2nd pass in order to not disturb
+ // the original declaration order in the source (otherwise, this
+ // would also invalidate the monotonically increasing position
+ // info within a single file).
+ if n > 0 {
+ i = 0
+ for _, d := range decls {
+ if d != nil {
+ decls[i] = d
+ i++
+ }
+ }
+ decls = decls[0:i]
+ }
+ }
+
+ // Collect import specs from all package files.
+ var imports []*ImportSpec
+ if mode&FilterImportDuplicates != 0 {
+ seen := make(map[string]bool)
+ for _, filename := range filenames {
+ f := pkg.Files[filename]
+ for _, imp := range f.Imports {
+ if path := imp.Path.Value; !seen[path] {
+ // TODO: consider handling cases where:
+ // - 2 imports exist with the same import path but
+ // have different local names (one should probably
+ // keep both of them)
+ // - 2 imports exist but only one has a comment
+ // - 2 imports exist and they both have (possibly
+ // different) comments
+ imports = append(imports, imp)
+ seen[path] = true
+ }
+ }
+ }
+ } else {
+ // Iterate over filenames for deterministic order.
+ for _, filename := range filenames {
+ f := pkg.Files[filename]
+ imports = append(imports, f.Imports...)
+ }
+ }
+
+ // Collect comments from all package files.
+ var comments []*CommentGroup
+ if mode&FilterUnassociatedComments == 0 {
+ comments = make([]*CommentGroup, ncomments)
+ i := 0
+ for _, filename := range filenames {
+ f := pkg.Files[filename]
+ i += copy(comments[i:], f.Comments)
+ }
+ }
+
+ // TODO(gri) need to compute unresolved identifiers!
+ return &File{doc, pos, NewIdent(pkg.Name), decls, minPos, maxPos, pkg.Scope, imports, nil, comments, ""}
+}
diff --git a/contrib/go/_std_1.20/src/go/ast/import.go b/contrib/go/_std_1.21/src/go/ast/import.go
index 7fdf137d14..7fdf137d14 100644
--- a/contrib/go/_std_1.20/src/go/ast/import.go
+++ b/contrib/go/_std_1.21/src/go/ast/import.go
diff --git a/contrib/go/_std_1.20/src/go/ast/print.go b/contrib/go/_std_1.21/src/go/ast/print.go
index 85e6943928..85e6943928 100644
--- a/contrib/go/_std_1.20/src/go/ast/print.go
+++ b/contrib/go/_std_1.21/src/go/ast/print.go
diff --git a/contrib/go/_std_1.20/src/go/ast/resolve.go b/contrib/go/_std_1.21/src/go/ast/resolve.go
index 970aa88ad6..970aa88ad6 100644
--- a/contrib/go/_std_1.20/src/go/ast/resolve.go
+++ b/contrib/go/_std_1.21/src/go/ast/resolve.go
diff --git a/contrib/go/_std_1.20/src/go/ast/scope.go b/contrib/go/_std_1.21/src/go/ast/scope.go
index 8882212007..8882212007 100644
--- a/contrib/go/_std_1.20/src/go/ast/scope.go
+++ b/contrib/go/_std_1.21/src/go/ast/scope.go
diff --git a/contrib/go/_std_1.20/src/go/ast/walk.go b/contrib/go/_std_1.21/src/go/ast/walk.go
index a293c99a10..a293c99a10 100644
--- a/contrib/go/_std_1.20/src/go/ast/walk.go
+++ b/contrib/go/_std_1.21/src/go/ast/walk.go
diff --git a/contrib/go/_std_1.21/src/go/ast/ya.make b/contrib/go/_std_1.21/src/go/ast/ya.make
new file mode 100644
index 0000000000..a33c289ab9
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/ast/ya.make
@@ -0,0 +1,29 @@
+GO_LIBRARY()
+
+SRCS(
+ ast.go
+ commentmap.go
+ filter.go
+ import.go
+ print.go
+ resolve.go
+ scope.go
+ walk.go
+)
+
+GO_TEST_SRCS(
+ ast_test.go
+ print_test.go
+)
+
+GO_XTEST_SRCS(
+ commentmap_test.go
+ example_test.go
+ filter_test.go
+ issues_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/go/build/build.go b/contrib/go/_std_1.21/src/go/build/build.go
new file mode 100644
index 0000000000..dd6cdc903a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/build/build.go
@@ -0,0 +1,2036 @@
+// Copyright 2011 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 build
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "go/ast"
+ "go/build/constraint"
+ "go/doc"
+ "go/token"
+ "internal/buildcfg"
+ "internal/godebug"
+ "internal/goroot"
+ "internal/goversion"
+ "internal/platform"
+ "io"
+ "io/fs"
+ "os"
+ "os/exec"
+ pathpkg "path"
+ "path/filepath"
+ "runtime"
+ "sort"
+ "strconv"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+)
+
+// A Context specifies the supporting context for a build.
+type Context struct {
+ GOARCH string // target architecture
+ GOOS string // target operating system
+ GOROOT string // Go root
+ GOPATH string // Go paths
+
+ // Dir is the caller's working directory, or the empty string to use
+ // the current directory of the running process. In module mode, this is used
+ // to locate the main module.
+ //
+ // If Dir is non-empty, directories passed to Import and ImportDir must
+ // be absolute.
+ Dir string
+
+ CgoEnabled bool // whether cgo files are included
+ UseAllFiles bool // use files regardless of go:build lines, file names
+ Compiler string // compiler to assume when computing target paths
+
+ // The build, tool, and release tags specify build constraints
+ // that should be considered satisfied when processing go:build lines.
+ // Clients creating a new context may customize BuildTags, which
+ // defaults to empty, but it is usually an error to customize ToolTags or ReleaseTags.
+ // ToolTags defaults to build tags appropriate to the current Go toolchain configuration.
+ // ReleaseTags defaults to the list of Go releases the current release is compatible with.
+ // BuildTags is not set for the Default build Context.
+ // In addition to the BuildTags, ToolTags, and ReleaseTags, build constraints
+ // consider the values of GOARCH and GOOS as satisfied tags.
+ // The last element in ReleaseTags is assumed to be the current release.
+ BuildTags []string
+ ToolTags []string
+ ReleaseTags []string
+
+ // The install suffix specifies a suffix to use in the name of the installation
+ // directory. By default it is empty, but custom builds that need to keep
+ // their outputs separate can set InstallSuffix to do so. For example, when
+ // using the race detector, the go command uses InstallSuffix = "race", so
+ // that on a Linux/386 system, packages are written to a directory named
+ // "linux_386_race" instead of the usual "linux_386".
+ InstallSuffix string
+
+ // By default, Import uses the operating system's file system calls
+ // to read directories and files. To read from other sources,
+ // callers can set the following functions. They all have default
+ // behaviors that use the local file system, so clients need only set
+ // the functions whose behaviors they wish to change.
+
+ // JoinPath joins the sequence of path fragments into a single path.
+ // If JoinPath is nil, Import uses filepath.Join.
+ JoinPath func(elem ...string) string
+
+ // SplitPathList splits the path list into a slice of individual paths.
+ // If SplitPathList is nil, Import uses filepath.SplitList.
+ SplitPathList func(list string) []string
+
+ // IsAbsPath reports whether path is an absolute path.
+ // If IsAbsPath is nil, Import uses filepath.IsAbs.
+ IsAbsPath func(path string) bool
+
+ // IsDir reports whether the path names a directory.
+ // If IsDir is nil, Import calls os.Stat and uses the result's IsDir method.
+ IsDir func(path string) bool
+
+ // HasSubdir reports whether dir is lexically a subdirectory of
+ // root, perhaps multiple levels below. It does not try to check
+ // whether dir exists.
+ // If so, HasSubdir sets rel to a slash-separated path that
+ // can be joined to root to produce a path equivalent to dir.
+ // If HasSubdir is nil, Import uses an implementation built on
+ // filepath.EvalSymlinks.
+ HasSubdir func(root, dir string) (rel string, ok bool)
+
+ // ReadDir returns a slice of fs.FileInfo, sorted by Name,
+ // describing the content of the named directory.
+ // If ReadDir is nil, Import uses os.ReadDir.
+ ReadDir func(dir string) ([]fs.FileInfo, error)
+
+ // OpenFile opens a file (not a directory) for reading.
+ // If OpenFile is nil, Import uses os.Open.
+ OpenFile func(path string) (io.ReadCloser, error)
+}
+
+// joinPath calls ctxt.JoinPath (if not nil) or else filepath.Join.
+func (ctxt *Context) joinPath(elem ...string) string {
+ if f := ctxt.JoinPath; f != nil {
+ return f(elem...)
+ }
+ return filepath.Join(elem...)
+}
+
+// splitPathList calls ctxt.SplitPathList (if not nil) or else filepath.SplitList.
+func (ctxt *Context) splitPathList(s string) []string {
+ if f := ctxt.SplitPathList; f != nil {
+ return f(s)
+ }
+ return filepath.SplitList(s)
+}
+
+// isAbsPath calls ctxt.IsAbsPath (if not nil) or else filepath.IsAbs.
+func (ctxt *Context) isAbsPath(path string) bool {
+ if f := ctxt.IsAbsPath; f != nil {
+ return f(path)
+ }
+ return filepath.IsAbs(path)
+}
+
+// isDir calls ctxt.IsDir (if not nil) or else uses os.Stat.
+func (ctxt *Context) isDir(path string) bool {
+ if f := ctxt.IsDir; f != nil {
+ return f(path)
+ }
+ fi, err := os.Stat(path)
+ return err == nil && fi.IsDir()
+}
+
+// hasSubdir calls ctxt.HasSubdir (if not nil) or else uses
+// the local file system to answer the question.
+func (ctxt *Context) hasSubdir(root, dir string) (rel string, ok bool) {
+ if f := ctxt.HasSubdir; f != nil {
+ return f(root, dir)
+ }
+
+ // Try using paths we received.
+ if rel, ok = hasSubdir(root, dir); ok {
+ return
+ }
+
+ // Try expanding symlinks and comparing
+ // expanded against unexpanded and
+ // expanded against expanded.
+ rootSym, _ := filepath.EvalSymlinks(root)
+ dirSym, _ := filepath.EvalSymlinks(dir)
+
+ if rel, ok = hasSubdir(rootSym, dir); ok {
+ return
+ }
+ if rel, ok = hasSubdir(root, dirSym); ok {
+ return
+ }
+ return hasSubdir(rootSym, dirSym)
+}
+
+// hasSubdir reports if dir is within root by performing lexical analysis only.
+func hasSubdir(root, dir string) (rel string, ok bool) {
+ const sep = string(filepath.Separator)
+ root = filepath.Clean(root)
+ if !strings.HasSuffix(root, sep) {
+ root += sep
+ }
+ dir = filepath.Clean(dir)
+ after, found := strings.CutPrefix(dir, root)
+ if !found {
+ return "", false
+ }
+ return filepath.ToSlash(after), true
+}
+
+// readDir calls ctxt.ReadDir (if not nil) or else os.ReadDir.
+func (ctxt *Context) readDir(path string) ([]fs.DirEntry, error) {
+ // TODO: add a fs.DirEntry version of Context.ReadDir
+ if f := ctxt.ReadDir; f != nil {
+ fis, err := f(path)
+ if err != nil {
+ return nil, err
+ }
+ des := make([]fs.DirEntry, len(fis))
+ for i, fi := range fis {
+ des[i] = fs.FileInfoToDirEntry(fi)
+ }
+ return des, nil
+ }
+ return os.ReadDir(path)
+}
+
+// openFile calls ctxt.OpenFile (if not nil) or else os.Open.
+func (ctxt *Context) openFile(path string) (io.ReadCloser, error) {
+ if fn := ctxt.OpenFile; fn != nil {
+ return fn(path)
+ }
+
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, err // nil interface
+ }
+ return f, nil
+}
+
+// isFile determines whether path is a file by trying to open it.
+// It reuses openFile instead of adding another function to the
+// list in Context.
+func (ctxt *Context) isFile(path string) bool {
+ f, err := ctxt.openFile(path)
+ if err != nil {
+ return false
+ }
+ f.Close()
+ return true
+}
+
+// gopath returns the list of Go path directories.
+func (ctxt *Context) gopath() []string {
+ var all []string
+ for _, p := range ctxt.splitPathList(ctxt.GOPATH) {
+ if p == "" || p == ctxt.GOROOT {
+ // Empty paths are uninteresting.
+ // If the path is the GOROOT, ignore it.
+ // People sometimes set GOPATH=$GOROOT.
+ // Do not get confused by this common mistake.
+ continue
+ }
+ if strings.HasPrefix(p, "~") {
+ // Path segments starting with ~ on Unix are almost always
+ // users who have incorrectly quoted ~ while setting GOPATH,
+ // preventing it from expanding to $HOME.
+ // The situation is made more confusing by the fact that
+ // bash allows quoted ~ in $PATH (most shells do not).
+ // Do not get confused by this, and do not try to use the path.
+ // It does not exist, and printing errors about it confuses
+ // those users even more, because they think "sure ~ exists!".
+ // The go command diagnoses this situation and prints a
+ // useful error.
+ // On Windows, ~ is used in short names, such as c:\progra~1
+ // for c:\program files.
+ continue
+ }
+ all = append(all, p)
+ }
+ return all
+}
+
+// SrcDirs returns a list of package source root directories.
+// It draws from the current Go root and Go path but omits directories
+// that do not exist.
+func (ctxt *Context) SrcDirs() []string {
+ var all []string
+ if ctxt.GOROOT != "" && ctxt.Compiler != "gccgo" {
+ dir := ctxt.joinPath(ctxt.GOROOT, "src")
+ if ctxt.isDir(dir) {
+ all = append(all, dir)
+ }
+ }
+ for _, p := range ctxt.gopath() {
+ dir := ctxt.joinPath(p, "src")
+ if ctxt.isDir(dir) {
+ all = append(all, dir)
+ }
+ }
+ return all
+}
+
+// Default is the default Context for builds.
+// It uses the GOARCH, GOOS, GOROOT, and GOPATH environment variables
+// if set, or else the compiled code's GOARCH, GOOS, and GOROOT.
+var Default Context = defaultContext()
+
+func defaultGOPATH() string {
+ env := "HOME"
+ if runtime.GOOS == "windows" {
+ env = "USERPROFILE"
+ } else if runtime.GOOS == "plan9" {
+ env = "home"
+ }
+ if home := os.Getenv(env); home != "" {
+ def := filepath.Join(home, "go")
+ if filepath.Clean(def) == filepath.Clean(runtime.GOROOT()) {
+ // Don't set the default GOPATH to GOROOT,
+ // as that will trigger warnings from the go tool.
+ return ""
+ }
+ return def
+ }
+ return ""
+}
+
+var defaultToolTags, defaultReleaseTags []string
+
+func defaultContext() Context {
+ var c Context
+
+ c.GOARCH = buildcfg.GOARCH
+ c.GOOS = buildcfg.GOOS
+ if goroot := runtime.GOROOT(); goroot != "" {
+ c.GOROOT = filepath.Clean(goroot)
+ }
+ c.GOPATH = envOr("GOPATH", defaultGOPATH())
+ c.Compiler = runtime.Compiler
+ c.ToolTags = append(c.ToolTags, buildcfg.ToolTags...)
+
+ defaultToolTags = append([]string{}, c.ToolTags...) // our own private copy
+
+ // Each major Go release in the Go 1.x series adds a new
+ // "go1.x" release tag. That is, the go1.x tag is present in
+ // all releases >= Go 1.x. Code that requires Go 1.x or later
+ // should say "go:build go1.x", and code that should only be
+ // built before Go 1.x (perhaps it is the stub to use in that
+ // case) should say "go:build !go1.x".
+ // The last element in ReleaseTags is the current release.
+ for i := 1; i <= goversion.Version; i++ {
+ c.ReleaseTags = append(c.ReleaseTags, "go1."+strconv.Itoa(i))
+ }
+
+ defaultReleaseTags = append([]string{}, c.ReleaseTags...) // our own private copy
+
+ env := os.Getenv("CGO_ENABLED")
+ if env == "" {
+ env = defaultCGO_ENABLED
+ }
+ switch env {
+ case "1":
+ c.CgoEnabled = true
+ case "0":
+ c.CgoEnabled = false
+ default:
+ // cgo must be explicitly enabled for cross compilation builds
+ if runtime.GOARCH == c.GOARCH && runtime.GOOS == c.GOOS {
+ c.CgoEnabled = platform.CgoSupported(c.GOOS, c.GOARCH)
+ break
+ }
+ c.CgoEnabled = false
+ }
+
+ return c
+}
+
+func envOr(name, def string) string {
+ s := os.Getenv(name)
+ if s == "" {
+ return def
+ }
+ return s
+}
+
+// An ImportMode controls the behavior of the Import method.
+type ImportMode uint
+
+const (
+ // If FindOnly is set, Import stops after locating the directory
+ // that should contain the sources for a package. It does not
+ // read any files in the directory.
+ FindOnly ImportMode = 1 << iota
+
+ // If AllowBinary is set, Import can be satisfied by a compiled
+ // package object without corresponding sources.
+ //
+ // Deprecated:
+ // The supported way to create a compiled-only package is to
+ // write source code containing a //go:binary-only-package comment at
+ // the top of the file. Such a package will be recognized
+ // regardless of this flag setting (because it has source code)
+ // and will have BinaryOnly set to true in the returned Package.
+ AllowBinary
+
+ // If ImportComment is set, parse import comments on package statements.
+ // Import returns an error if it finds a comment it cannot understand
+ // or finds conflicting comments in multiple source files.
+ // See golang.org/s/go14customimport for more information.
+ ImportComment
+
+ // By default, Import searches vendor directories
+ // that apply in the given source directory before searching
+ // the GOROOT and GOPATH roots.
+ // If an Import finds and returns a package using a vendor
+ // directory, the resulting ImportPath is the complete path
+ // to the package, including the path elements leading up
+ // to and including "vendor".
+ // For example, if Import("y", "x/subdir", 0) finds
+ // "x/vendor/y", the returned package's ImportPath is "x/vendor/y",
+ // not plain "y".
+ // See golang.org/s/go15vendor for more information.
+ //
+ // Setting IgnoreVendor ignores vendor directories.
+ //
+ // In contrast to the package's ImportPath,
+ // the returned package's Imports, TestImports, and XTestImports
+ // are always the exact import paths from the source files:
+ // Import makes no attempt to resolve or check those paths.
+ IgnoreVendor
+)
+
+// A Package describes the Go package found in a directory.
+type Package struct {
+ Dir string // directory containing package sources
+ Name string // package name
+ ImportComment string // path in import comment on package statement
+ Doc string // documentation synopsis
+ ImportPath string // import path of package ("" if unknown)
+ Root string // root of Go tree where this package lives
+ SrcRoot string // package source root directory ("" if unknown)
+ PkgRoot string // package install root directory ("" if unknown)
+ PkgTargetRoot string // architecture dependent install root directory ("" if unknown)
+ BinDir string // command install directory ("" if unknown)
+ Goroot bool // package found in Go root
+ PkgObj string // installed .a file
+ AllTags []string // tags that can influence file selection in this directory
+ ConflictDir string // this directory shadows Dir in $GOPATH
+ BinaryOnly bool // cannot be rebuilt from source (has //go:binary-only-package comment)
+
+ // Source files
+ GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+ CgoFiles []string // .go source files that import "C"
+ IgnoredGoFiles []string // .go source files ignored for this build (including ignored _test.go files)
+ InvalidGoFiles []string // .go source files with detected problems (parse error, wrong package name, and so on)
+ IgnoredOtherFiles []string // non-.go source files ignored for this build
+ CFiles []string // .c source files
+ CXXFiles []string // .cc, .cpp and .cxx source files
+ MFiles []string // .m (Objective-C) source files
+ HFiles []string // .h, .hh, .hpp and .hxx source files
+ FFiles []string // .f, .F, .for and .f90 Fortran source files
+ SFiles []string // .s source files
+ SwigFiles []string // .swig files
+ SwigCXXFiles []string // .swigcxx files
+ SysoFiles []string // .syso system object files to add to archive
+
+ // Cgo directives
+ CgoCFLAGS []string // Cgo CFLAGS directives
+ CgoCPPFLAGS []string // Cgo CPPFLAGS directives
+ CgoCXXFLAGS []string // Cgo CXXFLAGS directives
+ CgoFFLAGS []string // Cgo FFLAGS directives
+ CgoLDFLAGS []string // Cgo LDFLAGS directives
+ CgoPkgConfig []string // Cgo pkg-config directives
+
+ // Test information
+ TestGoFiles []string // _test.go files in package
+ XTestGoFiles []string // _test.go files outside package
+
+ // Go directive comments (//go:zzz...) found in source files.
+ Directives []Directive
+ TestDirectives []Directive
+ XTestDirectives []Directive
+
+ // Dependency information
+ Imports []string // import paths from GoFiles, CgoFiles
+ ImportPos map[string][]token.Position // line information for Imports
+ TestImports []string // import paths from TestGoFiles
+ TestImportPos map[string][]token.Position // line information for TestImports
+ XTestImports []string // import paths from XTestGoFiles
+ XTestImportPos map[string][]token.Position // line information for XTestImports
+
+ // //go:embed patterns found in Go source files
+ // For example, if a source file says
+ // //go:embed a* b.c
+ // then the list will contain those two strings as separate entries.
+ // (See package embed for more details about //go:embed.)
+ EmbedPatterns []string // patterns from GoFiles, CgoFiles
+ EmbedPatternPos map[string][]token.Position // line information for EmbedPatterns
+ TestEmbedPatterns []string // patterns from TestGoFiles
+ TestEmbedPatternPos map[string][]token.Position // line information for TestEmbedPatterns
+ XTestEmbedPatterns []string // patterns from XTestGoFiles
+ XTestEmbedPatternPos map[string][]token.Position // line information for XTestEmbedPatternPos
+}
+
+// A Directive is a Go directive comment (//go:zzz...) found in a source file.
+type Directive struct {
+ Text string // full line comment including leading slashes
+ Pos token.Position // position of comment
+}
+
+// IsCommand reports whether the package is considered a
+// command to be installed (not just a library).
+// Packages named "main" are treated as commands.
+func (p *Package) IsCommand() bool {
+ return p.Name == "main"
+}
+
+// ImportDir is like Import but processes the Go package found in
+// the named directory.
+func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error) {
+ return ctxt.Import(".", dir, mode)
+}
+
+// NoGoError is the error used by Import to describe a directory
+// containing no buildable Go source files. (It may still contain
+// test files, files hidden by build tags, and so on.)
+type NoGoError struct {
+ Dir string
+}
+
+func (e *NoGoError) Error() string {
+ return "no buildable Go source files in " + e.Dir
+}
+
+// MultiplePackageError describes a directory containing
+// multiple buildable Go source files for multiple packages.
+type MultiplePackageError struct {
+ Dir string // directory containing files
+ Packages []string // package names found
+ Files []string // corresponding files: Files[i] declares package Packages[i]
+}
+
+func (e *MultiplePackageError) Error() string {
+ // Error string limited to two entries for compatibility.
+ return fmt.Sprintf("found packages %s (%s) and %s (%s) in %s", e.Packages[0], e.Files[0], e.Packages[1], e.Files[1], e.Dir)
+}
+
+func nameExt(name string) string {
+ i := strings.LastIndex(name, ".")
+ if i < 0 {
+ return ""
+ }
+ return name[i:]
+}
+
+var installgoroot = godebug.New("installgoroot")
+
+// Import returns details about the Go package named by the import path,
+// interpreting local import paths relative to the srcDir directory.
+// If the path is a local import path naming a package that can be imported
+// using a standard import path, the returned package will set p.ImportPath
+// to that path.
+//
+// In the directory containing the package, .go, .c, .h, and .s files are
+// considered part of the package except for:
+//
+// - .go files in package documentation
+// - files starting with _ or . (likely editor temporary files)
+// - files with build constraints not satisfied by the context
+//
+// If an error occurs, Import returns a non-nil error and a non-nil
+// *Package containing partial information.
+func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error) {
+ p := &Package{
+ ImportPath: path,
+ }
+ if path == "" {
+ return p, fmt.Errorf("import %q: invalid import path", path)
+ }
+
+ var pkgtargetroot string
+ var pkga string
+ var pkgerr error
+ suffix := ""
+ if ctxt.InstallSuffix != "" {
+ suffix = "_" + ctxt.InstallSuffix
+ }
+ switch ctxt.Compiler {
+ case "gccgo":
+ pkgtargetroot = "pkg/gccgo_" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
+ case "gc":
+ pkgtargetroot = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
+ default:
+ // Save error for end of function.
+ pkgerr = fmt.Errorf("import %q: unknown compiler %q", path, ctxt.Compiler)
+ }
+ setPkga := func() {
+ switch ctxt.Compiler {
+ case "gccgo":
+ dir, elem := pathpkg.Split(p.ImportPath)
+ pkga = pkgtargetroot + "/" + dir + "lib" + elem + ".a"
+ case "gc":
+ pkga = pkgtargetroot + "/" + p.ImportPath + ".a"
+ }
+ }
+ setPkga()
+
+ binaryOnly := false
+ if IsLocalImport(path) {
+ pkga = "" // local imports have no installed path
+ if srcDir == "" {
+ return p, fmt.Errorf("import %q: import relative to unknown directory", path)
+ }
+ if !ctxt.isAbsPath(path) {
+ p.Dir = ctxt.joinPath(srcDir, path)
+ }
+ // p.Dir directory may or may not exist. Gather partial information first, check if it exists later.
+ // Determine canonical import path, if any.
+ // Exclude results where the import path would include /testdata/.
+ inTestdata := func(sub string) bool {
+ return strings.Contains(sub, "/testdata/") || strings.HasSuffix(sub, "/testdata") || strings.HasPrefix(sub, "testdata/") || sub == "testdata"
+ }
+ if ctxt.GOROOT != "" {
+ root := ctxt.joinPath(ctxt.GOROOT, "src")
+ if sub, ok := ctxt.hasSubdir(root, p.Dir); ok && !inTestdata(sub) {
+ p.Goroot = true
+ p.ImportPath = sub
+ p.Root = ctxt.GOROOT
+ setPkga() // p.ImportPath changed
+ goto Found
+ }
+ }
+ all := ctxt.gopath()
+ for i, root := range all {
+ rootsrc := ctxt.joinPath(root, "src")
+ if sub, ok := ctxt.hasSubdir(rootsrc, p.Dir); ok && !inTestdata(sub) {
+ // We found a potential import path for dir,
+ // but check that using it wouldn't find something
+ // else first.
+ if ctxt.GOROOT != "" && ctxt.Compiler != "gccgo" {
+ if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) {
+ p.ConflictDir = dir
+ goto Found
+ }
+ }
+ for _, earlyRoot := range all[:i] {
+ if dir := ctxt.joinPath(earlyRoot, "src", sub); ctxt.isDir(dir) {
+ p.ConflictDir = dir
+ goto Found
+ }
+ }
+
+ // sub would not name some other directory instead of this one.
+ // Record it.
+ p.ImportPath = sub
+ p.Root = root
+ setPkga() // p.ImportPath changed
+ goto Found
+ }
+ }
+ // It's okay that we didn't find a root containing dir.
+ // Keep going with the information we have.
+ } else {
+ if strings.HasPrefix(path, "/") {
+ return p, fmt.Errorf("import %q: cannot import absolute path", path)
+ }
+
+ if err := ctxt.importGo(p, path, srcDir, mode); err == nil {
+ goto Found
+ } else if err != errNoModules {
+ return p, err
+ }
+
+ gopath := ctxt.gopath() // needed twice below; avoid computing many times
+
+ // tried records the location of unsuccessful package lookups
+ var tried struct {
+ vendor []string
+ goroot string
+ gopath []string
+ }
+
+ // Vendor directories get first chance to satisfy import.
+ if mode&IgnoreVendor == 0 && srcDir != "" {
+ searchVendor := func(root string, isGoroot bool) bool {
+ sub, ok := ctxt.hasSubdir(root, srcDir)
+ if !ok || !strings.HasPrefix(sub, "src/") || strings.Contains(sub, "/testdata/") {
+ return false
+ }
+ for {
+ vendor := ctxt.joinPath(root, sub, "vendor")
+ if ctxt.isDir(vendor) {
+ dir := ctxt.joinPath(vendor, path)
+ if ctxt.isDir(dir) && hasGoFiles(ctxt, dir) {
+ p.Dir = dir
+ p.ImportPath = strings.TrimPrefix(pathpkg.Join(sub, "vendor", path), "src/")
+ p.Goroot = isGoroot
+ p.Root = root
+ setPkga() // p.ImportPath changed
+ return true
+ }
+ tried.vendor = append(tried.vendor, dir)
+ }
+ i := strings.LastIndex(sub, "/")
+ if i < 0 {
+ break
+ }
+ sub = sub[:i]
+ }
+ return false
+ }
+ if ctxt.Compiler != "gccgo" && ctxt.GOROOT != "" && searchVendor(ctxt.GOROOT, true) {
+ goto Found
+ }
+ for _, root := range gopath {
+ if searchVendor(root, false) {
+ goto Found
+ }
+ }
+ }
+
+ // Determine directory from import path.
+ if ctxt.GOROOT != "" {
+ // If the package path starts with "vendor/", only search GOROOT before
+ // GOPATH if the importer is also within GOROOT. That way, if the user has
+ // vendored in a package that is subsequently included in the standard
+ // distribution, they'll continue to pick up their own vendored copy.
+ gorootFirst := srcDir == "" || !strings.HasPrefix(path, "vendor/")
+ if !gorootFirst {
+ _, gorootFirst = ctxt.hasSubdir(ctxt.GOROOT, srcDir)
+ }
+ if gorootFirst {
+ dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
+ if ctxt.Compiler != "gccgo" {
+ isDir := ctxt.isDir(dir)
+ binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
+ if isDir || binaryOnly {
+ p.Dir = dir
+ p.Goroot = true
+ p.Root = ctxt.GOROOT
+ goto Found
+ }
+ }
+ tried.goroot = dir
+ }
+ if ctxt.Compiler == "gccgo" && goroot.IsStandardPackage(ctxt.GOROOT, ctxt.Compiler, path) {
+ // TODO(bcmills): Setting p.Dir here is misleading, because gccgo
+ // doesn't actually load its standard-library packages from this
+ // directory. See if we can leave it unset.
+ p.Dir = ctxt.joinPath(ctxt.GOROOT, "src", path)
+ p.Goroot = true
+ p.Root = ctxt.GOROOT
+ goto Found
+ }
+ }
+ for _, root := range gopath {
+ dir := ctxt.joinPath(root, "src", path)
+ isDir := ctxt.isDir(dir)
+ binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(root, pkga))
+ if isDir || binaryOnly {
+ p.Dir = dir
+ p.Root = root
+ goto Found
+ }
+ tried.gopath = append(tried.gopath, dir)
+ }
+
+ // If we tried GOPATH first due to a "vendor/" prefix, fall back to GOPATH.
+ // That way, the user can still get useful results from 'go list' for
+ // standard-vendored paths passed on the command line.
+ if ctxt.GOROOT != "" && tried.goroot == "" {
+ dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
+ if ctxt.Compiler != "gccgo" {
+ isDir := ctxt.isDir(dir)
+ binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
+ if isDir || binaryOnly {
+ p.Dir = dir
+ p.Goroot = true
+ p.Root = ctxt.GOROOT
+ goto Found
+ }
+ }
+ tried.goroot = dir
+ }
+
+ // package was not found
+ var paths []string
+ format := "\t%s (vendor tree)"
+ for _, dir := range tried.vendor {
+ paths = append(paths, fmt.Sprintf(format, dir))
+ format = "\t%s"
+ }
+ if tried.goroot != "" {
+ paths = append(paths, fmt.Sprintf("\t%s (from $GOROOT)", tried.goroot))
+ } else {
+ paths = append(paths, "\t($GOROOT not set)")
+ }
+ format = "\t%s (from $GOPATH)"
+ for _, dir := range tried.gopath {
+ paths = append(paths, fmt.Sprintf(format, dir))
+ format = "\t%s"
+ }
+ if len(tried.gopath) == 0 {
+ paths = append(paths, "\t($GOPATH not set. For more details see: 'go help gopath')")
+ }
+ return p, fmt.Errorf("cannot find package %q in any of:\n%s", path, strings.Join(paths, "\n"))
+ }
+
+Found:
+ if p.Root != "" {
+ p.SrcRoot = ctxt.joinPath(p.Root, "src")
+ p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
+ p.BinDir = ctxt.joinPath(p.Root, "bin")
+ if pkga != "" {
+ // Always set PkgTargetRoot. It might be used when building in shared
+ // mode.
+ p.PkgTargetRoot = ctxt.joinPath(p.Root, pkgtargetroot)
+
+ // Set the install target if applicable.
+ if !p.Goroot || (installgoroot.Value() == "all" && p.ImportPath != "unsafe" && p.ImportPath != "builtin") {
+ if p.Goroot {
+ installgoroot.IncNonDefault()
+ }
+ p.PkgObj = ctxt.joinPath(p.Root, pkga)
+ }
+ }
+ }
+
+ // If it's a local import path, by the time we get here, we still haven't checked
+ // that p.Dir directory exists. This is the right time to do that check.
+ // We can't do it earlier, because we want to gather partial information for the
+ // non-nil *Package returned when an error occurs.
+ // We need to do this before we return early on FindOnly flag.
+ if IsLocalImport(path) && !ctxt.isDir(p.Dir) {
+ if ctxt.Compiler == "gccgo" && p.Goroot {
+ // gccgo has no sources for GOROOT packages.
+ return p, nil
+ }
+
+ // package was not found
+ return p, fmt.Errorf("cannot find package %q in:\n\t%s", p.ImportPath, p.Dir)
+ }
+
+ if mode&FindOnly != 0 {
+ return p, pkgerr
+ }
+ if binaryOnly && (mode&AllowBinary) != 0 {
+ return p, pkgerr
+ }
+
+ if ctxt.Compiler == "gccgo" && p.Goroot {
+ // gccgo has no sources for GOROOT packages.
+ return p, nil
+ }
+
+ dirs, err := ctxt.readDir(p.Dir)
+ if err != nil {
+ return p, err
+ }
+
+ var badGoError error
+ badGoFiles := make(map[string]bool)
+ badGoFile := func(name string, err error) {
+ if badGoError == nil {
+ badGoError = err
+ }
+ if !badGoFiles[name] {
+ p.InvalidGoFiles = append(p.InvalidGoFiles, name)
+ badGoFiles[name] = true
+ }
+ }
+
+ var Sfiles []string // files with ".S"(capital S)/.sx(capital s equivalent for case insensitive filesystems)
+ var firstFile, firstCommentFile string
+ embedPos := make(map[string][]token.Position)
+ testEmbedPos := make(map[string][]token.Position)
+ xTestEmbedPos := make(map[string][]token.Position)
+ importPos := make(map[string][]token.Position)
+ testImportPos := make(map[string][]token.Position)
+ xTestImportPos := make(map[string][]token.Position)
+ allTags := make(map[string]bool)
+ fset := token.NewFileSet()
+ for _, d := range dirs {
+ if d.IsDir() {
+ continue
+ }
+ if d.Type() == fs.ModeSymlink {
+ if ctxt.isDir(ctxt.joinPath(p.Dir, d.Name())) {
+ // Symlinks to directories are not source files.
+ continue
+ }
+ }
+
+ name := d.Name()
+ ext := nameExt(name)
+
+ info, err := ctxt.matchFile(p.Dir, name, allTags, &p.BinaryOnly, fset)
+ if err != nil && strings.HasSuffix(name, ".go") {
+ badGoFile(name, err)
+ continue
+ }
+ if info == nil {
+ if strings.HasPrefix(name, "_") || strings.HasPrefix(name, ".") {
+ // not due to build constraints - don't report
+ } else if ext == ".go" {
+ p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
+ } else if fileListForExt(p, ext) != nil {
+ p.IgnoredOtherFiles = append(p.IgnoredOtherFiles, name)
+ }
+ continue
+ }
+
+ // Going to save the file. For non-Go files, can stop here.
+ switch ext {
+ case ".go":
+ // keep going
+ case ".S", ".sx":
+ // special case for cgo, handled at end
+ Sfiles = append(Sfiles, name)
+ continue
+ default:
+ if list := fileListForExt(p, ext); list != nil {
+ *list = append(*list, name)
+ }
+ continue
+ }
+
+ data, filename := info.header, info.name
+
+ if info.parseErr != nil {
+ badGoFile(name, info.parseErr)
+ // Fall through: we might still have a partial AST in info.parsed,
+ // and we want to list files with parse errors anyway.
+ }
+
+ var pkg string
+ if info.parsed != nil {
+ pkg = info.parsed.Name.Name
+ if pkg == "documentation" {
+ p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
+ continue
+ }
+ }
+
+ isTest := strings.HasSuffix(name, "_test.go")
+ isXTest := false
+ if isTest && strings.HasSuffix(pkg, "_test") && p.Name != pkg {
+ isXTest = true
+ pkg = pkg[:len(pkg)-len("_test")]
+ }
+
+ if p.Name == "" {
+ p.Name = pkg
+ firstFile = name
+ } else if pkg != p.Name {
+ // TODO(#45999): The choice of p.Name is arbitrary based on file iteration
+ // order. Instead of resolving p.Name arbitrarily, we should clear out the
+ // existing name and mark the existing files as also invalid.
+ badGoFile(name, &MultiplePackageError{
+ Dir: p.Dir,
+ Packages: []string{p.Name, pkg},
+ Files: []string{firstFile, name},
+ })
+ }
+ // Grab the first package comment as docs, provided it is not from a test file.
+ if info.parsed != nil && info.parsed.Doc != nil && p.Doc == "" && !isTest && !isXTest {
+ p.Doc = doc.Synopsis(info.parsed.Doc.Text())
+ }
+
+ if mode&ImportComment != 0 {
+ qcom, line := findImportComment(data)
+ if line != 0 {
+ com, err := strconv.Unquote(qcom)
+ if err != nil {
+ badGoFile(name, fmt.Errorf("%s:%d: cannot parse import comment", filename, line))
+ } else if p.ImportComment == "" {
+ p.ImportComment = com
+ firstCommentFile = name
+ } else if p.ImportComment != com {
+ badGoFile(name, fmt.Errorf("found import comments %q (%s) and %q (%s) in %s", p.ImportComment, firstCommentFile, com, name, p.Dir))
+ }
+ }
+ }
+
+ // Record imports and information about cgo.
+ isCgo := false
+ for _, imp := range info.imports {
+ if imp.path == "C" {
+ if isTest {
+ badGoFile(name, fmt.Errorf("use of cgo in test %s not supported", filename))
+ continue
+ }
+ isCgo = true
+ if imp.doc != nil {
+ if err := ctxt.saveCgo(filename, p, imp.doc); err != nil {
+ badGoFile(name, err)
+ }
+ }
+ }
+ }
+
+ var fileList *[]string
+ var importMap, embedMap map[string][]token.Position
+ var directives *[]Directive
+ switch {
+ case isCgo:
+ allTags["cgo"] = true
+ if ctxt.CgoEnabled {
+ fileList = &p.CgoFiles
+ importMap = importPos
+ embedMap = embedPos
+ directives = &p.Directives
+ } else {
+ // Ignore imports and embeds from cgo files if cgo is disabled.
+ fileList = &p.IgnoredGoFiles
+ }
+ case isXTest:
+ fileList = &p.XTestGoFiles
+ importMap = xTestImportPos
+ embedMap = xTestEmbedPos
+ directives = &p.XTestDirectives
+ case isTest:
+ fileList = &p.TestGoFiles
+ importMap = testImportPos
+ embedMap = testEmbedPos
+ directives = &p.TestDirectives
+ default:
+ fileList = &p.GoFiles
+ importMap = importPos
+ embedMap = embedPos
+ directives = &p.Directives
+ }
+ *fileList = append(*fileList, name)
+ if importMap != nil {
+ for _, imp := range info.imports {
+ importMap[imp.path] = append(importMap[imp.path], fset.Position(imp.pos))
+ }
+ }
+ if embedMap != nil {
+ for _, emb := range info.embeds {
+ embedMap[emb.pattern] = append(embedMap[emb.pattern], emb.pos)
+ }
+ }
+ if directives != nil {
+ *directives = append(*directives, info.directives...)
+ }
+ }
+
+ for tag := range allTags {
+ p.AllTags = append(p.AllTags, tag)
+ }
+ sort.Strings(p.AllTags)
+
+ p.EmbedPatterns, p.EmbedPatternPos = cleanDecls(embedPos)
+ p.TestEmbedPatterns, p.TestEmbedPatternPos = cleanDecls(testEmbedPos)
+ p.XTestEmbedPatterns, p.XTestEmbedPatternPos = cleanDecls(xTestEmbedPos)
+
+ p.Imports, p.ImportPos = cleanDecls(importPos)
+ p.TestImports, p.TestImportPos = cleanDecls(testImportPos)
+ p.XTestImports, p.XTestImportPos = cleanDecls(xTestImportPos)
+
+ // add the .S/.sx files only if we are using cgo
+ // (which means gcc will compile them).
+ // The standard assemblers expect .s files.
+ if len(p.CgoFiles) > 0 {
+ p.SFiles = append(p.SFiles, Sfiles...)
+ sort.Strings(p.SFiles)
+ } else {
+ p.IgnoredOtherFiles = append(p.IgnoredOtherFiles, Sfiles...)
+ sort.Strings(p.IgnoredOtherFiles)
+ }
+
+ if badGoError != nil {
+ return p, badGoError
+ }
+ if len(p.GoFiles)+len(p.CgoFiles)+len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
+ return p, &NoGoError{p.Dir}
+ }
+ return p, pkgerr
+}
+
+func fileListForExt(p *Package, ext string) *[]string {
+ switch ext {
+ case ".c":
+ return &p.CFiles
+ case ".cc", ".cpp", ".cxx":
+ return &p.CXXFiles
+ case ".m":
+ return &p.MFiles
+ case ".h", ".hh", ".hpp", ".hxx":
+ return &p.HFiles
+ case ".f", ".F", ".for", ".f90":
+ return &p.FFiles
+ case ".s", ".S", ".sx":
+ return &p.SFiles
+ case ".swig":
+ return &p.SwigFiles
+ case ".swigcxx":
+ return &p.SwigCXXFiles
+ case ".syso":
+ return &p.SysoFiles
+ }
+ return nil
+}
+
+func uniq(list []string) []string {
+ if list == nil {
+ return nil
+ }
+ out := make([]string, len(list))
+ copy(out, list)
+ sort.Strings(out)
+ uniq := out[:0]
+ for _, x := range out {
+ if len(uniq) == 0 || uniq[len(uniq)-1] != x {
+ uniq = append(uniq, x)
+ }
+ }
+ return uniq
+}
+
+var errNoModules = errors.New("not using modules")
+
+// importGo checks whether it can use the go command to find the directory for path.
+// If using the go command is not appropriate, importGo returns errNoModules.
+// Otherwise, importGo tries using the go command and reports whether that succeeded.
+// Using the go command lets build.Import and build.Context.Import find code
+// in Go modules. In the long term we want tools to use go/packages (currently golang.org/x/tools/go/packages),
+// which will also use the go command.
+// Invoking the go command here is not very efficient in that it computes information
+// about the requested package and all dependencies and then only reports about the requested package.
+// Then we reinvoke it for every dependency. But this is still better than not working at all.
+// See golang.org/issue/26504.
+func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode) error {
+ // To invoke the go command,
+ // we must not being doing special things like AllowBinary or IgnoreVendor,
+ // and all the file system callbacks must be nil (we're meant to use the local file system).
+ if mode&AllowBinary != 0 || mode&IgnoreVendor != 0 ||
+ ctxt.JoinPath != nil || ctxt.SplitPathList != nil || ctxt.IsAbsPath != nil || ctxt.IsDir != nil || ctxt.HasSubdir != nil || ctxt.ReadDir != nil || ctxt.OpenFile != nil || !equal(ctxt.ToolTags, defaultToolTags) || !equal(ctxt.ReleaseTags, defaultReleaseTags) {
+ return errNoModules
+ }
+
+ // If ctxt.GOROOT is not set, we don't know which go command to invoke,
+ // and even if we did we might return packages in GOROOT that we wouldn't otherwise find
+ // (because we don't know to search in 'go env GOROOT' otherwise).
+ if ctxt.GOROOT == "" {
+ return errNoModules
+ }
+
+ // Predict whether module aware mode is enabled by checking the value of
+ // GO111MODULE and looking for a go.mod file in the source directory or
+ // one of its parents. Running 'go env GOMOD' in the source directory would
+ // give a canonical answer, but we'd prefer not to execute another command.
+ go111Module := os.Getenv("GO111MODULE")
+ switch go111Module {
+ case "off":
+ return errNoModules
+ default: // "", "on", "auto", anything else
+ // Maybe use modules.
+ }
+
+ if srcDir != "" {
+ var absSrcDir string
+ if filepath.IsAbs(srcDir) {
+ absSrcDir = srcDir
+ } else if ctxt.Dir != "" {
+ return fmt.Errorf("go/build: Dir is non-empty, so relative srcDir is not allowed: %v", srcDir)
+ } else {
+ // Find the absolute source directory. hasSubdir does not handle
+ // relative paths (and can't because the callbacks don't support this).
+ var err error
+ absSrcDir, err = filepath.Abs(srcDir)
+ if err != nil {
+ return errNoModules
+ }
+ }
+
+ // If the source directory is in GOROOT, then the in-process code works fine
+ // and we should keep using it. Moreover, the 'go list' approach below doesn't
+ // take standard-library vendoring into account and will fail.
+ if _, ok := ctxt.hasSubdir(filepath.Join(ctxt.GOROOT, "src"), absSrcDir); ok {
+ return errNoModules
+ }
+ }
+
+ // For efficiency, if path is a standard library package, let the usual lookup code handle it.
+ if dir := ctxt.joinPath(ctxt.GOROOT, "src", path); ctxt.isDir(dir) {
+ return errNoModules
+ }
+
+ // If GO111MODULE=auto, look to see if there is a go.mod.
+ // Since go1.13, it doesn't matter if we're inside GOPATH.
+ if go111Module == "auto" {
+ var (
+ parent string
+ err error
+ )
+ if ctxt.Dir == "" {
+ parent, err = os.Getwd()
+ if err != nil {
+ // A nonexistent working directory can't be in a module.
+ return errNoModules
+ }
+ } else {
+ parent, err = filepath.Abs(ctxt.Dir)
+ if err != nil {
+ // If the caller passed a bogus Dir explicitly, that's materially
+ // different from not having modules enabled.
+ return err
+ }
+ }
+ for {
+ if f, err := ctxt.openFile(ctxt.joinPath(parent, "go.mod")); err == nil {
+ buf := make([]byte, 100)
+ _, err := f.Read(buf)
+ f.Close()
+ if err == nil || err == io.EOF {
+ // go.mod exists and is readable (is a file, not a directory).
+ break
+ }
+ }
+ d := filepath.Dir(parent)
+ if len(d) >= len(parent) {
+ return errNoModules // reached top of file system, no go.mod
+ }
+ parent = d
+ }
+ }
+
+ goCmd := filepath.Join(ctxt.GOROOT, "bin", "go")
+ cmd := exec.Command(goCmd, "list", "-e", "-compiler="+ctxt.Compiler, "-tags="+strings.Join(ctxt.BuildTags, ","), "-installsuffix="+ctxt.InstallSuffix, "-f={{.Dir}}\n{{.ImportPath}}\n{{.Root}}\n{{.Goroot}}\n{{if .Error}}{{.Error}}{{end}}\n", "--", path)
+
+ if ctxt.Dir != "" {
+ cmd.Dir = ctxt.Dir
+ }
+
+ var stdout, stderr strings.Builder
+ cmd.Stdout = &stdout
+ cmd.Stderr = &stderr
+
+ cgo := "0"
+ if ctxt.CgoEnabled {
+ cgo = "1"
+ }
+ cmd.Env = append(cmd.Environ(),
+ "GOOS="+ctxt.GOOS,
+ "GOARCH="+ctxt.GOARCH,
+ "GOROOT="+ctxt.GOROOT,
+ "GOPATH="+ctxt.GOPATH,
+ "CGO_ENABLED="+cgo,
+ )
+
+ if err := cmd.Run(); err != nil {
+ return fmt.Errorf("go/build: go list %s: %v\n%s\n", path, err, stderr.String())
+ }
+
+ f := strings.SplitN(stdout.String(), "\n", 5)
+ if len(f) != 5 {
+ return fmt.Errorf("go/build: importGo %s: unexpected output:\n%s\n", path, stdout.String())
+ }
+ dir := f[0]
+ errStr := strings.TrimSpace(f[4])
+ if errStr != "" && dir == "" {
+ // If 'go list' could not locate the package (dir is empty),
+ // return the same error that 'go list' reported.
+ return errors.New(errStr)
+ }
+
+ // If 'go list' did locate the package, ignore the error.
+ // It was probably related to loading source files, and we'll
+ // encounter it ourselves shortly if the FindOnly flag isn't set.
+ p.Dir = dir
+ p.ImportPath = f[1]
+ p.Root = f[2]
+ p.Goroot = f[3] == "true"
+ return nil
+}
+
+func equal(x, y []string) bool {
+ if len(x) != len(y) {
+ return false
+ }
+ for i, xi := range x {
+ if xi != y[i] {
+ return false
+ }
+ }
+ return true
+}
+
+// hasGoFiles reports whether dir contains any files with names ending in .go.
+// For a vendor check we must exclude directories that contain no .go files.
+// Otherwise it is not possible to vendor just a/b/c and still import the
+// non-vendored a/b. See golang.org/issue/13832.
+func hasGoFiles(ctxt *Context, dir string) bool {
+ ents, _ := ctxt.readDir(dir)
+ for _, ent := range ents {
+ if !ent.IsDir() && strings.HasSuffix(ent.Name(), ".go") {
+ return true
+ }
+ }
+ return false
+}
+
+func findImportComment(data []byte) (s string, line int) {
+ // expect keyword package
+ word, data := parseWord(data)
+ if string(word) != "package" {
+ return "", 0
+ }
+
+ // expect package name
+ _, data = parseWord(data)
+
+ // now ready for import comment, a // or /* */ comment
+ // beginning and ending on the current line.
+ for len(data) > 0 && (data[0] == ' ' || data[0] == '\t' || data[0] == '\r') {
+ data = data[1:]
+ }
+
+ var comment []byte
+ switch {
+ case bytes.HasPrefix(data, slashSlash):
+ comment, _, _ = bytes.Cut(data[2:], newline)
+ case bytes.HasPrefix(data, slashStar):
+ var ok bool
+ comment, _, ok = bytes.Cut(data[2:], starSlash)
+ if !ok {
+ // malformed comment
+ return "", 0
+ }
+ if bytes.Contains(comment, newline) {
+ return "", 0
+ }
+ }
+ comment = bytes.TrimSpace(comment)
+
+ // split comment into `import`, `"pkg"`
+ word, arg := parseWord(comment)
+ if string(word) != "import" {
+ return "", 0
+ }
+
+ line = 1 + bytes.Count(data[:cap(data)-cap(arg)], newline)
+ return strings.TrimSpace(string(arg)), line
+}
+
+var (
+ slashSlash = []byte("//")
+ slashStar = []byte("/*")
+ starSlash = []byte("*/")
+ newline = []byte("\n")
+)
+
+// skipSpaceOrComment returns data with any leading spaces or comments removed.
+func skipSpaceOrComment(data []byte) []byte {
+ for len(data) > 0 {
+ switch data[0] {
+ case ' ', '\t', '\r', '\n':
+ data = data[1:]
+ continue
+ case '/':
+ if bytes.HasPrefix(data, slashSlash) {
+ i := bytes.Index(data, newline)
+ if i < 0 {
+ return nil
+ }
+ data = data[i+1:]
+ continue
+ }
+ if bytes.HasPrefix(data, slashStar) {
+ data = data[2:]
+ i := bytes.Index(data, starSlash)
+ if i < 0 {
+ return nil
+ }
+ data = data[i+2:]
+ continue
+ }
+ }
+ break
+ }
+ return data
+}
+
+// parseWord skips any leading spaces or comments in data
+// and then parses the beginning of data as an identifier or keyword,
+// returning that word and what remains after the word.
+func parseWord(data []byte) (word, rest []byte) {
+ data = skipSpaceOrComment(data)
+
+ // Parse past leading word characters.
+ rest = data
+ for {
+ r, size := utf8.DecodeRune(rest)
+ if unicode.IsLetter(r) || '0' <= r && r <= '9' || r == '_' {
+ rest = rest[size:]
+ continue
+ }
+ break
+ }
+
+ word = data[:len(data)-len(rest)]
+ if len(word) == 0 {
+ return nil, nil
+ }
+
+ return word, rest
+}
+
+// MatchFile reports whether the file with the given name in the given directory
+// matches the context and would be included in a Package created by ImportDir
+// of that directory.
+//
+// MatchFile considers the name of the file and may use ctxt.OpenFile to
+// read some or all of the file's content.
+func (ctxt *Context) MatchFile(dir, name string) (match bool, err error) {
+ info, err := ctxt.matchFile(dir, name, nil, nil, nil)
+ return info != nil, err
+}
+
+var dummyPkg Package
+
+// fileInfo records information learned about a file included in a build.
+type fileInfo struct {
+ name string // full name including dir
+ header []byte
+ fset *token.FileSet
+ parsed *ast.File
+ parseErr error
+ imports []fileImport
+ embeds []fileEmbed
+ directives []Directive
+}
+
+type fileImport struct {
+ path string
+ pos token.Pos
+ doc *ast.CommentGroup
+}
+
+type fileEmbed struct {
+ pattern string
+ pos token.Position
+}
+
+// matchFile determines whether the file with the given name in the given directory
+// should be included in the package being constructed.
+// If the file should be included, matchFile returns a non-nil *fileInfo (and a nil error).
+// Non-nil errors are reserved for unexpected problems.
+//
+// If name denotes a Go program, matchFile reads until the end of the
+// imports and returns that section of the file in the fileInfo's header field,
+// even though it only considers text until the first non-comment
+// for go:build lines.
+//
+// If allTags is non-nil, matchFile records any encountered build tag
+// by setting allTags[tag] = true.
+func (ctxt *Context) matchFile(dir, name string, allTags map[string]bool, binaryOnly *bool, fset *token.FileSet) (*fileInfo, error) {
+ if strings.HasPrefix(name, "_") ||
+ strings.HasPrefix(name, ".") {
+ return nil, nil
+ }
+
+ i := strings.LastIndex(name, ".")
+ if i < 0 {
+ i = len(name)
+ }
+ ext := name[i:]
+
+ if ext != ".go" && fileListForExt(&dummyPkg, ext) == nil {
+ // skip
+ return nil, nil
+ }
+
+ if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles {
+ return nil, nil
+ }
+
+ info := &fileInfo{name: ctxt.joinPath(dir, name), fset: fset}
+ if ext == ".syso" {
+ // binary, no reading
+ return info, nil
+ }
+
+ f, err := ctxt.openFile(info.name)
+ if err != nil {
+ return nil, err
+ }
+
+ if strings.HasSuffix(name, ".go") {
+ err = readGoInfo(f, info)
+ if strings.HasSuffix(name, "_test.go") {
+ binaryOnly = nil // ignore //go:binary-only-package comments in _test.go files
+ }
+ } else {
+ binaryOnly = nil // ignore //go:binary-only-package comments in non-Go sources
+ info.header, err = readComments(f)
+ }
+ f.Close()
+ if err != nil {
+ return info, fmt.Errorf("read %s: %v", info.name, err)
+ }
+
+ // Look for go:build comments to accept or reject the file.
+ ok, sawBinaryOnly, err := ctxt.shouldBuild(info.header, allTags)
+ if err != nil {
+ return nil, fmt.Errorf("%s: %v", name, err)
+ }
+ if !ok && !ctxt.UseAllFiles {
+ return nil, nil
+ }
+
+ if binaryOnly != nil && sawBinaryOnly {
+ *binaryOnly = true
+ }
+
+ return info, nil
+}
+
+func cleanDecls(m map[string][]token.Position) ([]string, map[string][]token.Position) {
+ all := make([]string, 0, len(m))
+ for path := range m {
+ all = append(all, path)
+ }
+ sort.Strings(all)
+ return all, m
+}
+
+// Import is shorthand for Default.Import.
+func Import(path, srcDir string, mode ImportMode) (*Package, error) {
+ return Default.Import(path, srcDir, mode)
+}
+
+// ImportDir is shorthand for Default.ImportDir.
+func ImportDir(dir string, mode ImportMode) (*Package, error) {
+ return Default.ImportDir(dir, mode)
+}
+
+var (
+ plusBuild = []byte("+build")
+
+ goBuildComment = []byte("//go:build")
+
+ errMultipleGoBuild = errors.New("multiple //go:build comments")
+)
+
+func isGoBuildComment(line []byte) bool {
+ if !bytes.HasPrefix(line, goBuildComment) {
+ return false
+ }
+ line = bytes.TrimSpace(line)
+ rest := line[len(goBuildComment):]
+ return len(rest) == 0 || len(bytes.TrimSpace(rest)) < len(rest)
+}
+
+// Special comment denoting a binary-only package.
+// See https://golang.org/design/2775-binary-only-packages
+// for more about the design of binary-only packages.
+var binaryOnlyComment = []byte("//go:binary-only-package")
+
+// shouldBuild reports whether it is okay to use this file,
+// The rule is that in the file's leading run of // comments
+// and blank lines, which must be followed by a blank line
+// (to avoid including a Go package clause doc comment),
+// lines beginning with '//go:build' are taken as build directives.
+//
+// The file is accepted only if each such line lists something
+// matching the file. For example:
+//
+// //go:build windows linux
+//
+// marks the file as applicable only on Windows and Linux.
+//
+// For each build tag it consults, shouldBuild sets allTags[tag] = true.
+//
+// shouldBuild reports whether the file should be built
+// and whether a //go:binary-only-package comment was found.
+func (ctxt *Context) shouldBuild(content []byte, allTags map[string]bool) (shouldBuild, binaryOnly bool, err error) {
+ // Identify leading run of // comments and blank lines,
+ // which must be followed by a blank line.
+ // Also identify any //go:build comments.
+ content, goBuild, sawBinaryOnly, err := parseFileHeader(content)
+ if err != nil {
+ return false, false, err
+ }
+
+ // If //go:build line is present, it controls.
+ // Otherwise fall back to +build processing.
+ switch {
+ case goBuild != nil:
+ x, err := constraint.Parse(string(goBuild))
+ if err != nil {
+ return false, false, fmt.Errorf("parsing //go:build line: %v", err)
+ }
+ shouldBuild = ctxt.eval(x, allTags)
+
+ default:
+ shouldBuild = true
+ p := content
+ for len(p) > 0 {
+ line := p
+ if i := bytes.IndexByte(line, '\n'); i >= 0 {
+ line, p = line[:i], p[i+1:]
+ } else {
+ p = p[len(p):]
+ }
+ line = bytes.TrimSpace(line)
+ if !bytes.HasPrefix(line, slashSlash) || !bytes.Contains(line, plusBuild) {
+ continue
+ }
+ text := string(line)
+ if !constraint.IsPlusBuild(text) {
+ continue
+ }
+ if x, err := constraint.Parse(text); err == nil {
+ if !ctxt.eval(x, allTags) {
+ shouldBuild = false
+ }
+ }
+ }
+ }
+
+ return shouldBuild, sawBinaryOnly, nil
+}
+
+func parseFileHeader(content []byte) (trimmed, goBuild []byte, sawBinaryOnly bool, err error) {
+ end := 0
+ p := content
+ ended := false // found non-blank, non-// line, so stopped accepting //go:build lines
+ inSlashStar := false // in /* */ comment
+
+Lines:
+ for len(p) > 0 {
+ line := p
+ if i := bytes.IndexByte(line, '\n'); i >= 0 {
+ line, p = line[:i], p[i+1:]
+ } else {
+ p = p[len(p):]
+ }
+ line = bytes.TrimSpace(line)
+ if len(line) == 0 && !ended { // Blank line
+ // Remember position of most recent blank line.
+ // When we find the first non-blank, non-// line,
+ // this "end" position marks the latest file position
+ // where a //go:build line can appear.
+ // (It must appear _before_ a blank line before the non-blank, non-// line.
+ // Yes, that's confusing, which is part of why we moved to //go:build lines.)
+ // Note that ended==false here means that inSlashStar==false,
+ // since seeing a /* would have set ended==true.
+ end = len(content) - len(p)
+ continue Lines
+ }
+ if !bytes.HasPrefix(line, slashSlash) { // Not comment line
+ ended = true
+ }
+
+ if !inSlashStar && isGoBuildComment(line) {
+ if goBuild != nil {
+ return nil, nil, false, errMultipleGoBuild
+ }
+ goBuild = line
+ }
+ if !inSlashStar && bytes.Equal(line, binaryOnlyComment) {
+ sawBinaryOnly = true
+ }
+
+ Comments:
+ for len(line) > 0 {
+ if inSlashStar {
+ if i := bytes.Index(line, starSlash); i >= 0 {
+ inSlashStar = false
+ line = bytes.TrimSpace(line[i+len(starSlash):])
+ continue Comments
+ }
+ continue Lines
+ }
+ if bytes.HasPrefix(line, slashSlash) {
+ continue Lines
+ }
+ if bytes.HasPrefix(line, slashStar) {
+ inSlashStar = true
+ line = bytes.TrimSpace(line[len(slashStar):])
+ continue Comments
+ }
+ // Found non-comment text.
+ break Lines
+ }
+ }
+
+ return content[:end], goBuild, sawBinaryOnly, nil
+}
+
+// saveCgo saves the information from the #cgo lines in the import "C" comment.
+// These lines set CFLAGS, CPPFLAGS, CXXFLAGS and LDFLAGS and pkg-config directives
+// that affect the way cgo's C code is built.
+func (ctxt *Context) saveCgo(filename string, di *Package, cg *ast.CommentGroup) error {
+ text := cg.Text()
+ for _, line := range strings.Split(text, "\n") {
+ orig := line
+
+ // Line is
+ // #cgo [GOOS/GOARCH...] LDFLAGS: stuff
+ //
+ line = strings.TrimSpace(line)
+ if len(line) < 5 || line[:4] != "#cgo" || (line[4] != ' ' && line[4] != '\t') {
+ continue
+ }
+
+ // Split at colon.
+ line, argstr, ok := strings.Cut(strings.TrimSpace(line[4:]), ":")
+ if !ok {
+ return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
+ }
+
+ // Parse GOOS/GOARCH stuff.
+ f := strings.Fields(line)
+ if len(f) < 1 {
+ return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
+ }
+
+ cond, verb := f[:len(f)-1], f[len(f)-1]
+ if len(cond) > 0 {
+ ok := false
+ for _, c := range cond {
+ if ctxt.matchAuto(c, nil) {
+ ok = true
+ break
+ }
+ }
+ if !ok {
+ continue
+ }
+ }
+
+ args, err := splitQuoted(argstr)
+ if err != nil {
+ return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
+ }
+ for i, arg := range args {
+ if arg, ok = expandSrcDir(arg, di.Dir); !ok {
+ return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg)
+ }
+ args[i] = arg
+ }
+
+ switch verb {
+ case "CFLAGS", "CPPFLAGS", "CXXFLAGS", "FFLAGS", "LDFLAGS":
+ // Change relative paths to absolute.
+ ctxt.makePathsAbsolute(args, di.Dir)
+ }
+
+ switch verb {
+ case "CFLAGS":
+ di.CgoCFLAGS = append(di.CgoCFLAGS, args...)
+ case "CPPFLAGS":
+ di.CgoCPPFLAGS = append(di.CgoCPPFLAGS, args...)
+ case "CXXFLAGS":
+ di.CgoCXXFLAGS = append(di.CgoCXXFLAGS, args...)
+ case "FFLAGS":
+ di.CgoFFLAGS = append(di.CgoFFLAGS, args...)
+ case "LDFLAGS":
+ di.CgoLDFLAGS = append(di.CgoLDFLAGS, args...)
+ case "pkg-config":
+ di.CgoPkgConfig = append(di.CgoPkgConfig, args...)
+ default:
+ return fmt.Errorf("%s: invalid #cgo verb: %s", filename, orig)
+ }
+ }
+ return nil
+}
+
+// expandSrcDir expands any occurrence of ${SRCDIR}, making sure
+// the result is safe for the shell.
+func expandSrcDir(str string, srcdir string) (string, bool) {
+ // "\" delimited paths cause safeCgoName to fail
+ // so convert native paths with a different delimiter
+ // to "/" before starting (eg: on windows).
+ srcdir = filepath.ToSlash(srcdir)
+
+ chunks := strings.Split(str, "${SRCDIR}")
+ if len(chunks) < 2 {
+ return str, safeCgoName(str)
+ }
+ ok := true
+ for _, chunk := range chunks {
+ ok = ok && (chunk == "" || safeCgoName(chunk))
+ }
+ ok = ok && (srcdir == "" || safeCgoName(srcdir))
+ res := strings.Join(chunks, srcdir)
+ return res, ok && res != ""
+}
+
+// makePathsAbsolute looks for compiler options that take paths and
+// makes them absolute. We do this because through the 1.8 release we
+// ran the compiler in the package directory, so any relative -I or -L
+// options would be relative to that directory. In 1.9 we changed to
+// running the compiler in the build directory, to get consistent
+// build results (issue #19964). To keep builds working, we change any
+// relative -I or -L options to be absolute.
+//
+// Using filepath.IsAbs and filepath.Join here means the results will be
+// different on different systems, but that's OK: -I and -L options are
+// inherently system-dependent.
+func (ctxt *Context) makePathsAbsolute(args []string, srcDir string) {
+ nextPath := false
+ for i, arg := range args {
+ if nextPath {
+ if !filepath.IsAbs(arg) {
+ args[i] = filepath.Join(srcDir, arg)
+ }
+ nextPath = false
+ } else if strings.HasPrefix(arg, "-I") || strings.HasPrefix(arg, "-L") {
+ if len(arg) == 2 {
+ nextPath = true
+ } else {
+ if !filepath.IsAbs(arg[2:]) {
+ args[i] = arg[:2] + filepath.Join(srcDir, arg[2:])
+ }
+ }
+ }
+ }
+}
+
+// NOTE: $ is not safe for the shell, but it is allowed here because of linker options like -Wl,$ORIGIN.
+// We never pass these arguments to a shell (just to programs we construct argv for), so this should be okay.
+// See golang.org/issue/6038.
+// The @ is for OS X. See golang.org/issue/13720.
+// The % is for Jenkins. See golang.org/issue/16959.
+// The ! is because module paths may use them. See golang.org/issue/26716.
+// The ~ and ^ are for sr.ht. See golang.org/issue/32260.
+const safeString = "+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$@%! ~^"
+
+func safeCgoName(s string) bool {
+ if s == "" {
+ return false
+ }
+ for i := 0; i < len(s); i++ {
+ if c := s[i]; c < utf8.RuneSelf && strings.IndexByte(safeString, c) < 0 {
+ return false
+ }
+ }
+ return true
+}
+
+// splitQuoted splits the string s around each instance of one or more consecutive
+// white space characters while taking into account quotes and escaping, and
+// returns an array of substrings of s or an empty list if s contains only white space.
+// Single quotes and double quotes are recognized to prevent splitting within the
+// quoted region, and are removed from the resulting substrings. If a quote in s
+// isn't closed err will be set and r will have the unclosed argument as the
+// last element. The backslash is used for escaping.
+//
+// For example, the following string:
+//
+// a b:"c d" 'e''f' "g\""
+//
+// Would be parsed as:
+//
+// []string{"a", "b:c d", "ef", `g"`}
+func splitQuoted(s string) (r []string, err error) {
+ var args []string
+ arg := make([]rune, len(s))
+ escaped := false
+ quoted := false
+ quote := '\x00'
+ i := 0
+ for _, rune := range s {
+ switch {
+ case escaped:
+ escaped = false
+ case rune == '\\':
+ escaped = true
+ continue
+ case quote != '\x00':
+ if rune == quote {
+ quote = '\x00'
+ continue
+ }
+ case rune == '"' || rune == '\'':
+ quoted = true
+ quote = rune
+ continue
+ case unicode.IsSpace(rune):
+ if quoted || i > 0 {
+ quoted = false
+ args = append(args, string(arg[:i]))
+ i = 0
+ }
+ continue
+ }
+ arg[i] = rune
+ i++
+ }
+ if quoted || i > 0 {
+ args = append(args, string(arg[:i]))
+ }
+ if quote != 0 {
+ err = errors.New("unclosed quote")
+ } else if escaped {
+ err = errors.New("unfinished escaping")
+ }
+ return args, err
+}
+
+// matchAuto interprets text as either a +build or //go:build expression (whichever works),
+// reporting whether the expression matches the build context.
+//
+// matchAuto is only used for testing of tag evaluation
+// and in #cgo lines, which accept either syntax.
+func (ctxt *Context) matchAuto(text string, allTags map[string]bool) bool {
+ if strings.ContainsAny(text, "&|()") {
+ text = "//go:build " + text
+ } else {
+ text = "// +build " + text
+ }
+ x, err := constraint.Parse(text)
+ if err != nil {
+ return false
+ }
+ return ctxt.eval(x, allTags)
+}
+
+func (ctxt *Context) eval(x constraint.Expr, allTags map[string]bool) bool {
+ return x.Eval(func(tag string) bool { return ctxt.matchTag(tag, allTags) })
+}
+
+// matchTag reports whether the name is one of:
+//
+// cgo (if cgo is enabled)
+// $GOOS
+// $GOARCH
+// ctxt.Compiler
+// linux (if GOOS = android)
+// solaris (if GOOS = illumos)
+// darwin (if GOOS = ios)
+// unix (if this is a Unix GOOS)
+// boringcrypto (if GOEXPERIMENT=boringcrypto is enabled)
+// tag (if tag is listed in ctxt.BuildTags, ctxt.ToolTags, or ctxt.ReleaseTags)
+//
+// It records all consulted tags in allTags.
+func (ctxt *Context) matchTag(name string, allTags map[string]bool) bool {
+ if allTags != nil {
+ allTags[name] = true
+ }
+
+ // special tags
+ if ctxt.CgoEnabled && name == "cgo" {
+ return true
+ }
+ if name == ctxt.GOOS || name == ctxt.GOARCH || name == ctxt.Compiler {
+ return true
+ }
+ if ctxt.GOOS == "android" && name == "linux" {
+ return true
+ }
+ if ctxt.GOOS == "illumos" && name == "solaris" {
+ return true
+ }
+ if ctxt.GOOS == "ios" && name == "darwin" {
+ return true
+ }
+ if name == "unix" && unixOS[ctxt.GOOS] {
+ return true
+ }
+ if name == "boringcrypto" {
+ name = "goexperiment.boringcrypto" // boringcrypto is an old name for goexperiment.boringcrypto
+ }
+
+ // other tags
+ for _, tag := range ctxt.BuildTags {
+ if tag == name {
+ return true
+ }
+ }
+ for _, tag := range ctxt.ToolTags {
+ if tag == name {
+ return true
+ }
+ }
+ for _, tag := range ctxt.ReleaseTags {
+ if tag == name {
+ return true
+ }
+ }
+
+ return false
+}
+
+// goodOSArchFile returns false if the name contains a $GOOS or $GOARCH
+// suffix which does not match the current system.
+// The recognized name formats are:
+//
+// name_$(GOOS).*
+// name_$(GOARCH).*
+// name_$(GOOS)_$(GOARCH).*
+// name_$(GOOS)_test.*
+// name_$(GOARCH)_test.*
+// name_$(GOOS)_$(GOARCH)_test.*
+//
+// Exceptions:
+// if GOOS=android, then files with GOOS=linux are also matched.
+// if GOOS=illumos, then files with GOOS=solaris are also matched.
+// if GOOS=ios, then files with GOOS=darwin are also matched.
+func (ctxt *Context) goodOSArchFile(name string, allTags map[string]bool) bool {
+ name, _, _ = strings.Cut(name, ".")
+
+ // Before Go 1.4, a file called "linux.go" would be equivalent to having a
+ // build tag "linux" in that file. For Go 1.4 and beyond, we require this
+ // auto-tagging to apply only to files with a non-empty prefix, so
+ // "foo_linux.go" is tagged but "linux.go" is not. This allows new operating
+ // systems, such as android, to arrive without breaking existing code with
+ // innocuous source code in "android.go". The easiest fix: cut everything
+ // in the name before the initial _.
+ i := strings.Index(name, "_")
+ if i < 0 {
+ return true
+ }
+ name = name[i:] // ignore everything before first _
+
+ l := strings.Split(name, "_")
+ if n := len(l); n > 0 && l[n-1] == "test" {
+ l = l[:n-1]
+ }
+ n := len(l)
+ if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] {
+ if allTags != nil {
+ // In case we short-circuit on l[n-1].
+ allTags[l[n-2]] = true
+ }
+ return ctxt.matchTag(l[n-1], allTags) && ctxt.matchTag(l[n-2], allTags)
+ }
+ if n >= 1 && (knownOS[l[n-1]] || knownArch[l[n-1]]) {
+ return ctxt.matchTag(l[n-1], allTags)
+ }
+ return true
+}
+
+// ToolDir is the directory containing build tools.
+var ToolDir = getToolDir()
+
+// IsLocalImport reports whether the import path is
+// a local import path, like ".", "..", "./foo", or "../foo".
+func IsLocalImport(path string) bool {
+ return path == "." || path == ".." ||
+ strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../")
+}
+
+// ArchChar returns "?" and an error.
+// In earlier versions of Go, the returned string was used to derive
+// the compiler and linker tool names, the default object file suffix,
+// and the default linker output name. As of Go 1.5, those strings
+// no longer vary by architecture; they are compile, link, .o, and a.out, respectively.
+func ArchChar(goarch string) (string, error) {
+ return "?", errors.New("architecture letter no longer used")
+}
diff --git a/contrib/go/_std_1.20/src/go/build/constraint/expr.go b/contrib/go/_std_1.21/src/go/build/constraint/expr.go
index 505cbffa4c..505cbffa4c 100644
--- a/contrib/go/_std_1.20/src/go/build/constraint/expr.go
+++ b/contrib/go/_std_1.21/src/go/build/constraint/expr.go
diff --git a/contrib/go/_std_1.21/src/go/build/constraint/vers.go b/contrib/go/_std_1.21/src/go/build/constraint/vers.go
new file mode 100644
index 0000000000..34c44dcf17
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/build/constraint/vers.go
@@ -0,0 +1,105 @@
+// Copyright 2023 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 constraint
+
+import (
+ "strconv"
+ "strings"
+)
+
+// GoVersion returns the minimum Go version implied by a given build expression.
+// If the expression can be satisfied without any Go version tags, GoVersion returns an empty string.
+//
+// For example:
+//
+// GoVersion(linux && go1.22) = "go1.22"
+// GoVersion((linux && go1.22) || (windows && go1.20)) = "go1.20" => go1.20
+// GoVersion(linux) = ""
+// GoVersion(linux || (windows && go1.22)) = ""
+// GoVersion(!go1.22) = ""
+//
+// GoVersion assumes that any tag or negated tag may independently be true,
+// so that its analysis can be purely structural, without SAT solving.
+// “Impossible” subexpressions may therefore affect the result.
+//
+// For example:
+//
+// GoVersion((linux && !linux && go1.20) || go1.21) = "go1.20"
+func GoVersion(x Expr) string {
+ v := minVersion(x, +1)
+ if v < 0 {
+ return ""
+ }
+ if v == 0 {
+ return "go1"
+ }
+ return "go1." + strconv.Itoa(v)
+}
+
+// minVersion returns the minimum Go major version (9 for go1.9)
+// implied by expression z, or if sign < 0, by expression !z.
+func minVersion(z Expr, sign int) int {
+ switch z := z.(type) {
+ default:
+ return -1
+ case *AndExpr:
+ op := andVersion
+ if sign < 0 {
+ op = orVersion
+ }
+ return op(minVersion(z.X, sign), minVersion(z.Y, sign))
+ case *OrExpr:
+ op := orVersion
+ if sign < 0 {
+ op = andVersion
+ }
+ return op(minVersion(z.X, sign), minVersion(z.Y, sign))
+ case *NotExpr:
+ return minVersion(z.X, -sign)
+ case *TagExpr:
+ if sign < 0 {
+ // !foo implies nothing
+ return -1
+ }
+ if z.Tag == "go1" {
+ return 0
+ }
+ _, v, _ := stringsCut(z.Tag, "go1.")
+ n, err := strconv.Atoi(v)
+ if err != nil {
+ // not a go1.N tag
+ return -1
+ }
+ return n
+ }
+}
+
+// TODO: Delete, replace calls with strings.Cut once Go bootstrap toolchain is bumped.
+func stringsCut(s, sep string) (before, after string, found bool) {
+ if i := strings.Index(s, sep); i >= 0 {
+ return s[:i], s[i+len(sep):], true
+ }
+ return s, "", false
+}
+
+// andVersion returns the minimum Go version
+// implied by the AND of two minimum Go versions,
+// which is the max of the versions.
+func andVersion(x, y int) int {
+ if x > y {
+ return x
+ }
+ return y
+}
+
+// orVersion returns the minimum Go version
+// implied by the OR of two minimum Go versions,
+// which is the min of the versions.
+func orVersion(x, y int) int {
+ if x < y {
+ return x
+ }
+ return y
+}
diff --git a/contrib/go/_std_1.21/src/go/build/constraint/ya.make b/contrib/go/_std_1.21/src/go/build/constraint/ya.make
new file mode 100644
index 0000000000..29b9c05c47
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/build/constraint/ya.make
@@ -0,0 +1,16 @@
+GO_LIBRARY()
+
+SRCS(
+ expr.go
+ vers.go
+)
+
+GO_TEST_SRCS(
+ expr_test.go
+ vers_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/go/build/doc.go b/contrib/go/_std_1.21/src/go/build/doc.go
index cd1d3fd33e..cd1d3fd33e 100644
--- a/contrib/go/_std_1.20/src/go/build/doc.go
+++ b/contrib/go/_std_1.21/src/go/build/doc.go
diff --git a/contrib/go/_std_1.20/src/go/build/gc.go b/contrib/go/_std_1.21/src/go/build/gc.go
index 434991f66e..434991f66e 100644
--- a/contrib/go/_std_1.20/src/go/build/gc.go
+++ b/contrib/go/_std_1.21/src/go/build/gc.go
diff --git a/contrib/go/_std_1.21/src/go/build/read.go b/contrib/go/_std_1.21/src/go/build/read.go
new file mode 100644
index 0000000000..52891975c1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/build/read.go
@@ -0,0 +1,612 @@
+// Copyright 2012 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 build
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/scanner"
+ "go/token"
+ "io"
+ "strconv"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+)
+
+type importReader struct {
+ b *bufio.Reader
+ buf []byte
+ peek byte
+ err error
+ eof bool
+ nerr int
+ pos token.Position
+}
+
+var bom = []byte{0xef, 0xbb, 0xbf}
+
+func newImportReader(name string, r io.Reader) *importReader {
+ b := bufio.NewReader(r)
+ // Remove leading UTF-8 BOM.
+ // Per https://golang.org/ref/spec#Source_code_representation:
+ // a compiler may ignore a UTF-8-encoded byte order mark (U+FEFF)
+ // if it is the first Unicode code point in the source text.
+ if leadingBytes, err := b.Peek(3); err == nil && bytes.Equal(leadingBytes, bom) {
+ b.Discard(3)
+ }
+ return &importReader{
+ b: b,
+ pos: token.Position{
+ Filename: name,
+ Line: 1,
+ Column: 1,
+ },
+ }
+}
+
+func isIdent(c byte) bool {
+ return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c >= utf8.RuneSelf
+}
+
+var (
+ errSyntax = errors.New("syntax error")
+ errNUL = errors.New("unexpected NUL in input")
+)
+
+// syntaxError records a syntax error, but only if an I/O error has not already been recorded.
+func (r *importReader) syntaxError() {
+ if r.err == nil {
+ r.err = errSyntax
+ }
+}
+
+// readByte reads the next byte from the input, saves it in buf, and returns it.
+// If an error occurs, readByte records the error in r.err and returns 0.
+func (r *importReader) readByte() byte {
+ c, err := r.b.ReadByte()
+ if err == nil {
+ r.buf = append(r.buf, c)
+ if c == 0 {
+ err = errNUL
+ }
+ }
+ if err != nil {
+ if err == io.EOF {
+ r.eof = true
+ } else if r.err == nil {
+ r.err = err
+ }
+ c = 0
+ }
+ return c
+}
+
+// readByteNoBuf is like readByte but doesn't buffer the byte.
+// It exhausts r.buf before reading from r.b.
+func (r *importReader) readByteNoBuf() byte {
+ var c byte
+ var err error
+ if len(r.buf) > 0 {
+ c = r.buf[0]
+ r.buf = r.buf[1:]
+ } else {
+ c, err = r.b.ReadByte()
+ if err == nil && c == 0 {
+ err = errNUL
+ }
+ }
+
+ if err != nil {
+ if err == io.EOF {
+ r.eof = true
+ } else if r.err == nil {
+ r.err = err
+ }
+ return 0
+ }
+ r.pos.Offset++
+ if c == '\n' {
+ r.pos.Line++
+ r.pos.Column = 1
+ } else {
+ r.pos.Column++
+ }
+ return c
+}
+
+// peekByte returns the next byte from the input reader but does not advance beyond it.
+// If skipSpace is set, peekByte skips leading spaces and comments.
+func (r *importReader) peekByte(skipSpace bool) byte {
+ if r.err != nil {
+ if r.nerr++; r.nerr > 10000 {
+ panic("go/build: import reader looping")
+ }
+ return 0
+ }
+
+ // Use r.peek as first input byte.
+ // Don't just return r.peek here: it might have been left by peekByte(false)
+ // and this might be peekByte(true).
+ c := r.peek
+ if c == 0 {
+ c = r.readByte()
+ }
+ for r.err == nil && !r.eof {
+ if skipSpace {
+ // For the purposes of this reader, semicolons are never necessary to
+ // understand the input and are treated as spaces.
+ switch c {
+ case ' ', '\f', '\t', '\r', '\n', ';':
+ c = r.readByte()
+ continue
+
+ case '/':
+ c = r.readByte()
+ if c == '/' {
+ for c != '\n' && r.err == nil && !r.eof {
+ c = r.readByte()
+ }
+ } else if c == '*' {
+ var c1 byte
+ for (c != '*' || c1 != '/') && r.err == nil {
+ if r.eof {
+ r.syntaxError()
+ }
+ c, c1 = c1, r.readByte()
+ }
+ } else {
+ r.syntaxError()
+ }
+ c = r.readByte()
+ continue
+ }
+ }
+ break
+ }
+ r.peek = c
+ return r.peek
+}
+
+// nextByte is like peekByte but advances beyond the returned byte.
+func (r *importReader) nextByte(skipSpace bool) byte {
+ c := r.peekByte(skipSpace)
+ r.peek = 0
+ return c
+}
+
+var goEmbed = []byte("go:embed")
+
+// findEmbed advances the input reader to the next //go:embed comment.
+// It reports whether it found a comment.
+// (Otherwise it found an error or EOF.)
+func (r *importReader) findEmbed(first bool) bool {
+ // The import block scan stopped after a non-space character,
+ // so the reader is not at the start of a line on the first call.
+ // After that, each //go:embed extraction leaves the reader
+ // at the end of a line.
+ startLine := !first
+ var c byte
+ for r.err == nil && !r.eof {
+ c = r.readByteNoBuf()
+ Reswitch:
+ switch c {
+ default:
+ startLine = false
+
+ case '\n':
+ startLine = true
+
+ case ' ', '\t':
+ // leave startLine alone
+
+ case '"':
+ startLine = false
+ for r.err == nil {
+ if r.eof {
+ r.syntaxError()
+ }
+ c = r.readByteNoBuf()
+ if c == '\\' {
+ r.readByteNoBuf()
+ if r.err != nil {
+ r.syntaxError()
+ return false
+ }
+ continue
+ }
+ if c == '"' {
+ c = r.readByteNoBuf()
+ goto Reswitch
+ }
+ }
+ goto Reswitch
+
+ case '`':
+ startLine = false
+ for r.err == nil {
+ if r.eof {
+ r.syntaxError()
+ }
+ c = r.readByteNoBuf()
+ if c == '`' {
+ c = r.readByteNoBuf()
+ goto Reswitch
+ }
+ }
+
+ case '\'':
+ startLine = false
+ for r.err == nil {
+ if r.eof {
+ r.syntaxError()
+ }
+ c = r.readByteNoBuf()
+ if c == '\\' {
+ r.readByteNoBuf()
+ if r.err != nil {
+ r.syntaxError()
+ return false
+ }
+ continue
+ }
+ if c == '\'' {
+ c = r.readByteNoBuf()
+ goto Reswitch
+ }
+ }
+
+ case '/':
+ c = r.readByteNoBuf()
+ switch c {
+ default:
+ startLine = false
+ goto Reswitch
+
+ case '*':
+ var c1 byte
+ for (c != '*' || c1 != '/') && r.err == nil {
+ if r.eof {
+ r.syntaxError()
+ }
+ c, c1 = c1, r.readByteNoBuf()
+ }
+ startLine = false
+
+ case '/':
+ if startLine {
+ // Try to read this as a //go:embed comment.
+ for i := range goEmbed {
+ c = r.readByteNoBuf()
+ if c != goEmbed[i] {
+ goto SkipSlashSlash
+ }
+ }
+ c = r.readByteNoBuf()
+ if c == ' ' || c == '\t' {
+ // Found one!
+ return true
+ }
+ }
+ SkipSlashSlash:
+ for c != '\n' && r.err == nil && !r.eof {
+ c = r.readByteNoBuf()
+ }
+ startLine = true
+ }
+ }
+ }
+ return false
+}
+
+// readKeyword reads the given keyword from the input.
+// If the keyword is not present, readKeyword records a syntax error.
+func (r *importReader) readKeyword(kw string) {
+ r.peekByte(true)
+ for i := 0; i < len(kw); i++ {
+ if r.nextByte(false) != kw[i] {
+ r.syntaxError()
+ return
+ }
+ }
+ if isIdent(r.peekByte(false)) {
+ r.syntaxError()
+ }
+}
+
+// readIdent reads an identifier from the input.
+// If an identifier is not present, readIdent records a syntax error.
+func (r *importReader) readIdent() {
+ c := r.peekByte(true)
+ if !isIdent(c) {
+ r.syntaxError()
+ return
+ }
+ for isIdent(r.peekByte(false)) {
+ r.peek = 0
+ }
+}
+
+// readString reads a quoted string literal from the input.
+// If an identifier is not present, readString records a syntax error.
+func (r *importReader) readString() {
+ switch r.nextByte(true) {
+ case '`':
+ for r.err == nil {
+ if r.nextByte(false) == '`' {
+ break
+ }
+ if r.eof {
+ r.syntaxError()
+ }
+ }
+ case '"':
+ for r.err == nil {
+ c := r.nextByte(false)
+ if c == '"' {
+ break
+ }
+ if r.eof || c == '\n' {
+ r.syntaxError()
+ }
+ if c == '\\' {
+ r.nextByte(false)
+ }
+ }
+ default:
+ r.syntaxError()
+ }
+}
+
+// readImport reads an import clause - optional identifier followed by quoted string -
+// from the input.
+func (r *importReader) readImport() {
+ c := r.peekByte(true)
+ if c == '.' {
+ r.peek = 0
+ } else if isIdent(c) {
+ r.readIdent()
+ }
+ r.readString()
+}
+
+// readComments is like io.ReadAll, except that it only reads the leading
+// block of comments in the file.
+func readComments(f io.Reader) ([]byte, error) {
+ r := newImportReader("", f)
+ r.peekByte(true)
+ if r.err == nil && !r.eof {
+ // Didn't reach EOF, so must have found a non-space byte. Remove it.
+ r.buf = r.buf[:len(r.buf)-1]
+ }
+ return r.buf, r.err
+}
+
+// readGoInfo expects a Go file as input and reads the file up to and including the import section.
+// It records what it learned in *info.
+// If info.fset is non-nil, readGoInfo parses the file and sets info.parsed, info.parseErr,
+// info.imports and info.embeds.
+//
+// It only returns an error if there are problems reading the file,
+// not for syntax errors in the file itself.
+func readGoInfo(f io.Reader, info *fileInfo) error {
+ r := newImportReader(info.name, f)
+
+ r.readKeyword("package")
+ r.readIdent()
+ for r.peekByte(true) == 'i' {
+ r.readKeyword("import")
+ if r.peekByte(true) == '(' {
+ r.nextByte(false)
+ for r.peekByte(true) != ')' && r.err == nil {
+ r.readImport()
+ }
+ r.nextByte(false)
+ } else {
+ r.readImport()
+ }
+ }
+
+ info.header = r.buf
+
+ // If we stopped successfully before EOF, we read a byte that told us we were done.
+ // Return all but that last byte, which would cause a syntax error if we let it through.
+ if r.err == nil && !r.eof {
+ info.header = r.buf[:len(r.buf)-1]
+ }
+
+ // If we stopped for a syntax error, consume the whole file so that
+ // we are sure we don't change the errors that go/parser returns.
+ if r.err == errSyntax {
+ r.err = nil
+ for r.err == nil && !r.eof {
+ r.readByte()
+ }
+ info.header = r.buf
+ }
+ if r.err != nil {
+ return r.err
+ }
+
+ if info.fset == nil {
+ return nil
+ }
+
+ // Parse file header & record imports.
+ info.parsed, info.parseErr = parser.ParseFile(info.fset, info.name, info.header, parser.ImportsOnly|parser.ParseComments)
+ if info.parseErr != nil {
+ return nil
+ }
+
+ hasEmbed := false
+ for _, decl := range info.parsed.Decls {
+ d, ok := decl.(*ast.GenDecl)
+ if !ok {
+ continue
+ }
+ for _, dspec := range d.Specs {
+ spec, ok := dspec.(*ast.ImportSpec)
+ if !ok {
+ continue
+ }
+ quoted := spec.Path.Value
+ path, err := strconv.Unquote(quoted)
+ if err != nil {
+ return fmt.Errorf("parser returned invalid quoted string: <%s>", quoted)
+ }
+ if !isValidImport(path) {
+ // The parser used to return a parse error for invalid import paths, but
+ // no longer does, so check for and create the error here instead.
+ info.parseErr = scanner.Error{Pos: info.fset.Position(spec.Pos()), Msg: "invalid import path: " + path}
+ info.imports = nil
+ return nil
+ }
+ if path == "embed" {
+ hasEmbed = true
+ }
+
+ doc := spec.Doc
+ if doc == nil && len(d.Specs) == 1 {
+ doc = d.Doc
+ }
+ info.imports = append(info.imports, fileImport{path, spec.Pos(), doc})
+ }
+ }
+
+ // Extract directives.
+ for _, group := range info.parsed.Comments {
+ if group.Pos() >= info.parsed.Package {
+ break
+ }
+ for _, c := range group.List {
+ if strings.HasPrefix(c.Text, "//go:") {
+ info.directives = append(info.directives, Directive{c.Text, info.fset.Position(c.Slash)})
+ }
+ }
+ }
+
+ // If the file imports "embed",
+ // we have to look for //go:embed comments
+ // in the remainder of the file.
+ // The compiler will enforce the mapping of comments to
+ // declared variables. We just need to know the patterns.
+ // If there were //go:embed comments earlier in the file
+ // (near the package statement or imports), the compiler
+ // will reject them. They can be (and have already been) ignored.
+ if hasEmbed {
+ var line []byte
+ for first := true; r.findEmbed(first); first = false {
+ line = line[:0]
+ pos := r.pos
+ for {
+ c := r.readByteNoBuf()
+ if c == '\n' || r.err != nil || r.eof {
+ break
+ }
+ line = append(line, c)
+ }
+ // Add args if line is well-formed.
+ // Ignore badly-formed lines - the compiler will report them when it finds them,
+ // and we can pretend they are not there to help go list succeed with what it knows.
+ embs, err := parseGoEmbed(string(line), pos)
+ if err == nil {
+ info.embeds = append(info.embeds, embs...)
+ }
+ }
+ }
+
+ return nil
+}
+
+// isValidImport checks if the import is a valid import using the more strict
+// checks allowed by the implementation restriction in https://go.dev/ref/spec#Import_declarations.
+// It was ported from the function of the same name that was removed from the
+// parser in CL 424855, when the parser stopped doing these checks.
+func isValidImport(s string) bool {
+ const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
+ for _, r := range s {
+ if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
+ return false
+ }
+ }
+ return s != ""
+}
+
+// parseGoEmbed parses the text following "//go:embed" to extract the glob patterns.
+// It accepts unquoted space-separated patterns as well as double-quoted and back-quoted Go strings.
+// This is based on a similar function in cmd/compile/internal/gc/noder.go;
+// this version calculates position information as well.
+func parseGoEmbed(args string, pos token.Position) ([]fileEmbed, error) {
+ trimBytes := func(n int) {
+ pos.Offset += n
+ pos.Column += utf8.RuneCountInString(args[:n])
+ args = args[n:]
+ }
+ trimSpace := func() {
+ trim := strings.TrimLeftFunc(args, unicode.IsSpace)
+ trimBytes(len(args) - len(trim))
+ }
+
+ var list []fileEmbed
+ for trimSpace(); args != ""; trimSpace() {
+ var path string
+ pathPos := pos
+ Switch:
+ switch args[0] {
+ default:
+ i := len(args)
+ for j, c := range args {
+ if unicode.IsSpace(c) {
+ i = j
+ break
+ }
+ }
+ path = args[:i]
+ trimBytes(i)
+
+ case '`':
+ var ok bool
+ path, _, ok = strings.Cut(args[1:], "`")
+ if !ok {
+ return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
+ }
+ trimBytes(1 + len(path) + 1)
+
+ case '"':
+ i := 1
+ for ; i < len(args); i++ {
+ if args[i] == '\\' {
+ i++
+ continue
+ }
+ if args[i] == '"' {
+ q, err := strconv.Unquote(args[:i+1])
+ if err != nil {
+ return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args[:i+1])
+ }
+ path = q
+ trimBytes(i + 1)
+ break Switch
+ }
+ }
+ if i >= len(args) {
+ return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
+ }
+ }
+
+ if args != "" {
+ r, _ := utf8.DecodeRuneInString(args)
+ if !unicode.IsSpace(r) {
+ return nil, fmt.Errorf("invalid quoted string in //go:embed: %s", args)
+ }
+ }
+ list = append(list, fileEmbed{path, pathPos})
+ }
+ return list, nil
+}
diff --git a/contrib/go/_std_1.21/src/go/build/syslist.go b/contrib/go/_std_1.21/src/go/build/syslist.go
new file mode 100644
index 0000000000..783bbe697a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/build/syslist.go
@@ -0,0 +1,81 @@
+// Copyright 2011 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 build
+
+// Note that this file is read by internal/goarch/gengoarch.go and by
+// internal/goos/gengoos.go. If you change this file, look at those
+// files as well.
+
+// knownOS is the list of past, present, and future known GOOS values.
+// Do not remove from this list, as it is used for filename matching.
+// If you add an entry to this list, look at unixOS, below.
+var knownOS = map[string]bool{
+ "aix": true,
+ "android": true,
+ "darwin": true,
+ "dragonfly": true,
+ "freebsd": true,
+ "hurd": true,
+ "illumos": true,
+ "ios": true,
+ "js": true,
+ "linux": true,
+ "nacl": true,
+ "netbsd": true,
+ "openbsd": true,
+ "plan9": true,
+ "solaris": true,
+ "wasip1": true,
+ "windows": true,
+ "zos": true,
+}
+
+// unixOS is the set of GOOS values matched by the "unix" build tag.
+// This is not used for filename matching.
+// This list also appears in cmd/dist/build.go and
+// cmd/go/internal/imports/build.go.
+var unixOS = map[string]bool{
+ "aix": true,
+ "android": true,
+ "darwin": true,
+ "dragonfly": true,
+ "freebsd": true,
+ "hurd": true,
+ "illumos": true,
+ "ios": true,
+ "linux": true,
+ "netbsd": true,
+ "openbsd": true,
+ "solaris": true,
+}
+
+// knownArch is the list of past, present, and future known GOARCH values.
+// Do not remove from this list, as it is used for filename matching.
+var knownArch = map[string]bool{
+ "386": true,
+ "amd64": true,
+ "amd64p32": true,
+ "arm": true,
+ "armbe": true,
+ "arm64": true,
+ "arm64be": true,
+ "loong64": true,
+ "mips": true,
+ "mipsle": true,
+ "mips64": true,
+ "mips64le": true,
+ "mips64p32": true,
+ "mips64p32le": true,
+ "ppc": true,
+ "ppc64": true,
+ "ppc64le": true,
+ "riscv": true,
+ "riscv64": true,
+ "s390": true,
+ "s390x": true,
+ "sparc": true,
+ "sparc64": true,
+ "wasm": true,
+}
diff --git a/contrib/go/_std_1.21/src/go/build/ya.make b/contrib/go/_std_1.21/src/go/build/ya.make
new file mode 100644
index 0000000000..798a634d96
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/build/ya.make
@@ -0,0 +1,23 @@
+GO_LIBRARY()
+
+SRCS(
+ build.go
+ doc.go
+ gc.go
+ read.go
+ syslist.go
+ zcgo.go
+)
+
+GO_TEST_SRCS(
+ build_test.go
+ deps_test.go
+ read_test.go
+ syslist_test.go
+)
+
+END()
+
+RECURSE(
+ constraint
+)
diff --git a/contrib/go/_std_1.21/src/go/build/zcgo.go b/contrib/go/_std_1.21/src/go/build/zcgo.go
new file mode 100644
index 0000000000..b8ecb6cdb8
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/build/zcgo.go
@@ -0,0 +1,5 @@
+// Code generated by go tool dist; DO NOT EDIT.
+
+package build
+
+const defaultCGO_ENABLED = ""
diff --git a/contrib/go/_std_1.20/src/go/constant/kind_string.go b/contrib/go/_std_1.21/src/go/constant/kind_string.go
index 700332511d..700332511d 100644
--- a/contrib/go/_std_1.20/src/go/constant/kind_string.go
+++ b/contrib/go/_std_1.21/src/go/constant/kind_string.go
diff --git a/contrib/go/_std_1.20/src/go/constant/value.go b/contrib/go/_std_1.21/src/go/constant/value.go
index ae300c7c13..ae300c7c13 100644
--- a/contrib/go/_std_1.20/src/go/constant/value.go
+++ b/contrib/go/_std_1.21/src/go/constant/value.go
diff --git a/contrib/go/_std_1.21/src/go/constant/ya.make b/contrib/go/_std_1.21/src/go/constant/ya.make
new file mode 100644
index 0000000000..a171bfae5c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/constant/ya.make
@@ -0,0 +1,15 @@
+GO_LIBRARY()
+
+SRCS(
+ kind_string.go
+ value.go
+)
+
+GO_TEST_SRCS(value_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/go/doc/comment.go b/contrib/go/_std_1.21/src/go/doc/comment.go
index 4f73664ba3..4f73664ba3 100644
--- a/contrib/go/_std_1.20/src/go/doc/comment.go
+++ b/contrib/go/_std_1.21/src/go/doc/comment.go
diff --git a/contrib/go/_std_1.20/src/go/doc/comment/doc.go b/contrib/go/_std_1.21/src/go/doc/comment/doc.go
index 45a476aa9a..45a476aa9a 100644
--- a/contrib/go/_std_1.20/src/go/doc/comment/doc.go
+++ b/contrib/go/_std_1.21/src/go/doc/comment/doc.go
diff --git a/contrib/go/_std_1.20/src/go/doc/comment/html.go b/contrib/go/_std_1.21/src/go/doc/comment/html.go
index bc076f6a58..bc076f6a58 100644
--- a/contrib/go/_std_1.20/src/go/doc/comment/html.go
+++ b/contrib/go/_std_1.21/src/go/doc/comment/html.go
diff --git a/contrib/go/_std_1.20/src/go/doc/comment/markdown.go b/contrib/go/_std_1.21/src/go/doc/comment/markdown.go
index d8550f2e39..d8550f2e39 100644
--- a/contrib/go/_std_1.20/src/go/doc/comment/markdown.go
+++ b/contrib/go/_std_1.21/src/go/doc/comment/markdown.go
diff --git a/contrib/go/_std_1.20/src/go/doc/comment/parse.go b/contrib/go/_std_1.21/src/go/doc/comment/parse.go
index 62a0f8f2bb..62a0f8f2bb 100644
--- a/contrib/go/_std_1.20/src/go/doc/comment/parse.go
+++ b/contrib/go/_std_1.21/src/go/doc/comment/parse.go
diff --git a/contrib/go/_std_1.21/src/go/doc/comment/print.go b/contrib/go/_std_1.21/src/go/doc/comment/print.go
new file mode 100644
index 0000000000..e1c070d5a5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/doc/comment/print.go
@@ -0,0 +1,288 @@
+// Copyright 2022 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 comment
+
+import (
+ "bytes"
+ "fmt"
+ "strings"
+)
+
+// A Printer is a doc comment printer.
+// The fields in the struct can be filled in before calling
+// any of the printing methods
+// in order to customize the details of the printing process.
+type Printer struct {
+ // HeadingLevel is the nesting level used for
+ // HTML and Markdown headings.
+ // If HeadingLevel is zero, it defaults to level 3,
+ // meaning to use <h3> and ###.
+ HeadingLevel int
+
+ // HeadingID is a function that computes the heading ID
+ // (anchor tag) to use for the heading h when generating
+ // HTML and Markdown. If HeadingID returns an empty string,
+ // then the heading ID is omitted.
+ // If HeadingID is nil, h.DefaultID is used.
+ HeadingID func(h *Heading) string
+
+ // DocLinkURL is a function that computes the URL for the given DocLink.
+ // If DocLinkURL is nil, then link.DefaultURL(p.DocLinkBaseURL) is used.
+ DocLinkURL func(link *DocLink) string
+
+ // DocLinkBaseURL is used when DocLinkURL is nil,
+ // passed to [DocLink.DefaultURL] to construct a DocLink's URL.
+ // See that method's documentation for details.
+ DocLinkBaseURL string
+
+ // TextPrefix is a prefix to print at the start of every line
+ // when generating text output using the Text method.
+ TextPrefix string
+
+ // TextCodePrefix is the prefix to print at the start of each
+ // preformatted (code block) line when generating text output,
+ // instead of (not in addition to) TextPrefix.
+ // If TextCodePrefix is the empty string, it defaults to TextPrefix+"\t".
+ TextCodePrefix string
+
+ // TextWidth is the maximum width text line to generate,
+ // measured in Unicode code points,
+ // excluding TextPrefix and the newline character.
+ // If TextWidth is zero, it defaults to 80 minus the number of code points in TextPrefix.
+ // If TextWidth is negative, there is no limit.
+ TextWidth int
+}
+
+func (p *Printer) headingLevel() int {
+ if p.HeadingLevel <= 0 {
+ return 3
+ }
+ return p.HeadingLevel
+}
+
+func (p *Printer) headingID(h *Heading) string {
+ if p.HeadingID == nil {
+ return h.DefaultID()
+ }
+ return p.HeadingID(h)
+}
+
+func (p *Printer) docLinkURL(link *DocLink) string {
+ if p.DocLinkURL != nil {
+ return p.DocLinkURL(link)
+ }
+ return link.DefaultURL(p.DocLinkBaseURL)
+}
+
+// DefaultURL constructs and returns the documentation URL for l,
+// using baseURL as a prefix for links to other packages.
+//
+// The possible forms returned by DefaultURL are:
+// - baseURL/ImportPath, for a link to another package
+// - baseURL/ImportPath#Name, for a link to a const, func, type, or var in another package
+// - baseURL/ImportPath#Recv.Name, for a link to a method in another package
+// - #Name, for a link to a const, func, type, or var in this package
+// - #Recv.Name, for a link to a method in this package
+//
+// If baseURL ends in a trailing slash, then DefaultURL inserts
+// a slash between ImportPath and # in the anchored forms.
+// For example, here are some baseURL values and URLs they can generate:
+//
+// "/pkg/" → "/pkg/math/#Sqrt"
+// "/pkg" → "/pkg/math#Sqrt"
+// "/" → "/math/#Sqrt"
+// "" → "/math#Sqrt"
+func (l *DocLink) DefaultURL(baseURL string) string {
+ if l.ImportPath != "" {
+ slash := ""
+ if strings.HasSuffix(baseURL, "/") {
+ slash = "/"
+ } else {
+ baseURL += "/"
+ }
+ switch {
+ case l.Name == "":
+ return baseURL + l.ImportPath + slash
+ case l.Recv != "":
+ return baseURL + l.ImportPath + slash + "#" + l.Recv + "." + l.Name
+ default:
+ return baseURL + l.ImportPath + slash + "#" + l.Name
+ }
+ }
+ if l.Recv != "" {
+ return "#" + l.Recv + "." + l.Name
+ }
+ return "#" + l.Name
+}
+
+// DefaultID returns the default anchor ID for the heading h.
+//
+// The default anchor ID is constructed by converting every
+// rune that is not alphanumeric ASCII to an underscore
+// and then adding the prefix “hdr-”.
+// For example, if the heading text is “Go Doc Comments”,
+// the default ID is “hdr-Go_Doc_Comments”.
+func (h *Heading) DefaultID() string {
+ // Note: The “hdr-” prefix is important to avoid DOM clobbering attacks.
+ // See https://pkg.go.dev/github.com/google/safehtml#Identifier.
+ var out strings.Builder
+ var p textPrinter
+ p.oneLongLine(&out, h.Text)
+ s := strings.TrimSpace(out.String())
+ if s == "" {
+ return ""
+ }
+ out.Reset()
+ out.WriteString("hdr-")
+ for _, r := range s {
+ if r < 0x80 && isIdentASCII(byte(r)) {
+ out.WriteByte(byte(r))
+ } else {
+ out.WriteByte('_')
+ }
+ }
+ return out.String()
+}
+
+type commentPrinter struct {
+ *Printer
+}
+
+// Comment returns the standard Go formatting of the Doc,
+// without any comment markers.
+func (p *Printer) Comment(d *Doc) []byte {
+ cp := &commentPrinter{Printer: p}
+ var out bytes.Buffer
+ for i, x := range d.Content {
+ if i > 0 && blankBefore(x) {
+ out.WriteString("\n")
+ }
+ cp.block(&out, x)
+ }
+
+ // Print one block containing all the link definitions that were used,
+ // and then a second block containing all the unused ones.
+ // This makes it easy to clean up the unused ones: gofmt and
+ // delete the final block. And it's a nice visual signal without
+ // affecting the way the comment formats for users.
+ for i := 0; i < 2; i++ {
+ used := i == 0
+ first := true
+ for _, def := range d.Links {
+ if def.Used == used {
+ if first {
+ out.WriteString("\n")
+ first = false
+ }
+ out.WriteString("[")
+ out.WriteString(def.Text)
+ out.WriteString("]: ")
+ out.WriteString(def.URL)
+ out.WriteString("\n")
+ }
+ }
+ }
+
+ return out.Bytes()
+}
+
+// blankBefore reports whether the block x requires a blank line before it.
+// All blocks do, except for Lists that return false from x.BlankBefore().
+func blankBefore(x Block) bool {
+ if x, ok := x.(*List); ok {
+ return x.BlankBefore()
+ }
+ return true
+}
+
+// block prints the block x to out.
+func (p *commentPrinter) block(out *bytes.Buffer, x Block) {
+ switch x := x.(type) {
+ default:
+ fmt.Fprintf(out, "?%T", x)
+
+ case *Paragraph:
+ p.text(out, "", x.Text)
+ out.WriteString("\n")
+
+ case *Heading:
+ out.WriteString("# ")
+ p.text(out, "", x.Text)
+ out.WriteString("\n")
+
+ case *Code:
+ md := x.Text
+ for md != "" {
+ var line string
+ line, md, _ = strings.Cut(md, "\n")
+ if line != "" {
+ out.WriteString("\t")
+ out.WriteString(line)
+ }
+ out.WriteString("\n")
+ }
+
+ case *List:
+ loose := x.BlankBetween()
+ for i, item := range x.Items {
+ if i > 0 && loose {
+ out.WriteString("\n")
+ }
+ out.WriteString(" ")
+ if item.Number == "" {
+ out.WriteString(" - ")
+ } else {
+ out.WriteString(item.Number)
+ out.WriteString(". ")
+ }
+ for i, blk := range item.Content {
+ const fourSpace = " "
+ if i > 0 {
+ out.WriteString("\n" + fourSpace)
+ }
+ p.text(out, fourSpace, blk.(*Paragraph).Text)
+ out.WriteString("\n")
+ }
+ }
+ }
+}
+
+// text prints the text sequence x to out.
+func (p *commentPrinter) text(out *bytes.Buffer, indent string, x []Text) {
+ for _, t := range x {
+ switch t := t.(type) {
+ case Plain:
+ p.indent(out, indent, string(t))
+ case Italic:
+ p.indent(out, indent, string(t))
+ case *Link:
+ if t.Auto {
+ p.text(out, indent, t.Text)
+ } else {
+ out.WriteString("[")
+ p.text(out, indent, t.Text)
+ out.WriteString("]")
+ }
+ case *DocLink:
+ out.WriteString("[")
+ p.text(out, indent, t.Text)
+ out.WriteString("]")
+ }
+ }
+}
+
+// indent prints s to out, indenting with the indent string
+// after each newline in s.
+func (p *commentPrinter) indent(out *bytes.Buffer, indent, s string) {
+ for s != "" {
+ line, rest, ok := strings.Cut(s, "\n")
+ out.WriteString(line)
+ if ok {
+ out.WriteString("\n")
+ out.WriteString(indent)
+ }
+ s = rest
+ }
+}
diff --git a/contrib/go/_std_1.21/src/go/doc/comment/std.go b/contrib/go/_std_1.21/src/go/doc/comment/std.go
new file mode 100644
index 0000000000..fd8c8ce3c2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/doc/comment/std.go
@@ -0,0 +1,47 @@
+// Copyright 2022 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.
+
+// Code generated by 'go generate' DO NOT EDIT.
+//go:generate ./mkstd.sh
+
+package comment
+
+var stdPkgs = []string{
+ "bufio",
+ "bytes",
+ "cmp",
+ "context",
+ "crypto",
+ "embed",
+ "encoding",
+ "errors",
+ "expvar",
+ "flag",
+ "fmt",
+ "hash",
+ "html",
+ "image",
+ "io",
+ "log",
+ "maps",
+ "math",
+ "mime",
+ "net",
+ "os",
+ "path",
+ "plugin",
+ "reflect",
+ "regexp",
+ "runtime",
+ "slices",
+ "sort",
+ "strconv",
+ "strings",
+ "sync",
+ "syscall",
+ "testing",
+ "time",
+ "unicode",
+ "unsafe",
+}
diff --git a/contrib/go/_std_1.20/src/go/doc/comment/text.go b/contrib/go/_std_1.21/src/go/doc/comment/text.go
index 6f9c2e201d..6f9c2e201d 100644
--- a/contrib/go/_std_1.20/src/go/doc/comment/text.go
+++ b/contrib/go/_std_1.21/src/go/doc/comment/text.go
diff --git a/contrib/go/_std_1.21/src/go/doc/comment/ya.make b/contrib/go/_std_1.21/src/go/doc/comment/ya.make
new file mode 100644
index 0000000000..f180560711
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/doc/comment/ya.make
@@ -0,0 +1,24 @@
+GO_LIBRARY()
+
+SRCS(
+ doc.go
+ html.go
+ markdown.go
+ parse.go
+ print.go
+ std.go
+ text.go
+)
+
+GO_TEST_SRCS(
+ old_test.go
+ parse_test.go
+ std_test.go
+ testdata_test.go
+ wrap_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/go/doc/doc.go b/contrib/go/_std_1.21/src/go/doc/doc.go
index eefadfa932..eefadfa932 100644
--- a/contrib/go/_std_1.20/src/go/doc/doc.go
+++ b/contrib/go/_std_1.21/src/go/doc/doc.go
diff --git a/contrib/go/_std_1.20/src/go/doc/example.go b/contrib/go/_std_1.21/src/go/doc/example.go
index 65ca88540f..65ca88540f 100644
--- a/contrib/go/_std_1.20/src/go/doc/example.go
+++ b/contrib/go/_std_1.21/src/go/doc/example.go
diff --git a/contrib/go/_std_1.20/src/go/doc/exports.go b/contrib/go/_std_1.21/src/go/doc/exports.go
index 655e889293..655e889293 100644
--- a/contrib/go/_std_1.20/src/go/doc/exports.go
+++ b/contrib/go/_std_1.21/src/go/doc/exports.go
diff --git a/contrib/go/_std_1.20/src/go/doc/filter.go b/contrib/go/_std_1.21/src/go/doc/filter.go
index f8d3e1fca2..f8d3e1fca2 100644
--- a/contrib/go/_std_1.20/src/go/doc/filter.go
+++ b/contrib/go/_std_1.21/src/go/doc/filter.go
diff --git a/contrib/go/_std_1.20/src/go/doc/reader.go b/contrib/go/_std_1.21/src/go/doc/reader.go
index 8f9fda41ff..8f9fda41ff 100644
--- a/contrib/go/_std_1.20/src/go/doc/reader.go
+++ b/contrib/go/_std_1.21/src/go/doc/reader.go
diff --git a/contrib/go/_std_1.20/src/go/doc/synopsis.go b/contrib/go/_std_1.21/src/go/doc/synopsis.go
index 3c9e7e9b9e..3c9e7e9b9e 100644
--- a/contrib/go/_std_1.20/src/go/doc/synopsis.go
+++ b/contrib/go/_std_1.21/src/go/doc/synopsis.go
diff --git a/contrib/go/_std_1.21/src/go/doc/ya.make b/contrib/go/_std_1.21/src/go/doc/ya.make
new file mode 100644
index 0000000000..2ec166490b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/doc/ya.make
@@ -0,0 +1,26 @@
+GO_LIBRARY()
+
+SRCS(
+ comment.go
+ doc.go
+ example.go
+ exports.go
+ filter.go
+ reader.go
+ synopsis.go
+)
+
+GO_TEST_SRCS(
+ comment_test.go
+ doc_test.go
+ example_internal_test.go
+ synopsis_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+ comment
+)
diff --git a/contrib/go/_std_1.20/src/go/format/format.go b/contrib/go/_std_1.21/src/go/format/format.go
index 3837cb4617..3837cb4617 100644
--- a/contrib/go/_std_1.20/src/go/format/format.go
+++ b/contrib/go/_std_1.21/src/go/format/format.go
diff --git a/contrib/go/_std_1.20/src/go/format/internal.go b/contrib/go/_std_1.21/src/go/format/internal.go
index 2f3b0e43ba..2f3b0e43ba 100644
--- a/contrib/go/_std_1.20/src/go/format/internal.go
+++ b/contrib/go/_std_1.21/src/go/format/internal.go
diff --git a/contrib/go/_std_1.21/src/go/format/ya.make b/contrib/go/_std_1.21/src/go/format/ya.make
new file mode 100644
index 0000000000..6add697f6e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/format/ya.make
@@ -0,0 +1,18 @@
+GO_LIBRARY()
+
+SRCS(
+ format.go
+ internal.go
+)
+
+GO_TEST_SRCS(format_test.go)
+
+GO_XTEST_SRCS(
+ benchmark_test.go
+ example_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/go/importer/importer.go b/contrib/go/_std_1.21/src/go/importer/importer.go
index 23118d366e..23118d366e 100644
--- a/contrib/go/_std_1.20/src/go/importer/importer.go
+++ b/contrib/go/_std_1.21/src/go/importer/importer.go
diff --git a/contrib/go/_std_1.21/src/go/importer/ya.make b/contrib/go/_std_1.21/src/go/importer/ya.make
new file mode 100644
index 0000000000..8330269260
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/importer/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ importer.go
+)
+
+GO_TEST_SRCS(importer_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/go/internal/gccgoimporter/ar.go b/contrib/go/_std_1.21/src/go/internal/gccgoimporter/ar.go
index 9df7934212..9df7934212 100644
--- a/contrib/go/_std_1.20/src/go/internal/gccgoimporter/ar.go
+++ b/contrib/go/_std_1.21/src/go/internal/gccgoimporter/ar.go
diff --git a/contrib/go/_std_1.20/src/go/internal/gccgoimporter/gccgoinstallation.go b/contrib/go/_std_1.21/src/go/internal/gccgoimporter/gccgoinstallation.go
index 8fc7ce3232..8fc7ce3232 100644
--- a/contrib/go/_std_1.20/src/go/internal/gccgoimporter/gccgoinstallation.go
+++ b/contrib/go/_std_1.21/src/go/internal/gccgoimporter/gccgoinstallation.go
diff --git a/contrib/go/_std_1.20/src/go/internal/gccgoimporter/importer.go b/contrib/go/_std_1.21/src/go/internal/gccgoimporter/importer.go
index 94f2defd8d..94f2defd8d 100644
--- a/contrib/go/_std_1.20/src/go/internal/gccgoimporter/importer.go
+++ b/contrib/go/_std_1.21/src/go/internal/gccgoimporter/importer.go
diff --git a/contrib/go/_std_1.20/src/go/internal/gccgoimporter/parser.go b/contrib/go/_std_1.21/src/go/internal/gccgoimporter/parser.go
index de9df0bbfb..de9df0bbfb 100644
--- a/contrib/go/_std_1.20/src/go/internal/gccgoimporter/parser.go
+++ b/contrib/go/_std_1.21/src/go/internal/gccgoimporter/parser.go
diff --git a/contrib/go/_std_1.21/src/go/internal/gccgoimporter/ya.make b/contrib/go/_std_1.21/src/go/internal/gccgoimporter/ya.make
new file mode 100644
index 0000000000..ee18a5aa79
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/internal/gccgoimporter/ya.make
@@ -0,0 +1,19 @@
+GO_LIBRARY()
+
+SRCS(
+ ar.go
+ gccgoinstallation.go
+ importer.go
+ parser.go
+)
+
+GO_TEST_SRCS(
+ gccgoinstallation_test.go
+ importer_test.go
+ parser_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/go/internal/gcimporter/exportdata.go b/contrib/go/_std_1.21/src/go/internal/gcimporter/exportdata.go
index 4aa22d7c92..4aa22d7c92 100644
--- a/contrib/go/_std_1.20/src/go/internal/gcimporter/exportdata.go
+++ b/contrib/go/_std_1.21/src/go/internal/gcimporter/exportdata.go
diff --git a/contrib/go/_std_1.21/src/go/internal/gcimporter/gcimporter.go b/contrib/go/_std_1.21/src/go/internal/gcimporter/gcimporter.go
new file mode 100644
index 0000000000..93b33d1510
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/internal/gcimporter/gcimporter.go
@@ -0,0 +1,248 @@
+// Copyright 2011 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 gcimporter implements Import for gc-generated object files.
+package gcimporter // import "go/internal/gcimporter"
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "go/build"
+ "go/token"
+ "go/types"
+ "internal/pkgbits"
+ "internal/saferio"
+ "io"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "sync"
+)
+
+// debugging/development support
+const debug = false
+
+var exportMap sync.Map // package dir → func() (string, bool)
+
+// lookupGorootExport returns the location of the export data
+// (normally found in the build cache, but located in GOROOT/pkg
+// in prior Go releases) for the package located in pkgDir.
+//
+// (We use the package's directory instead of its import path
+// mainly to simplify handling of the packages in src/vendor
+// and cmd/vendor.)
+func lookupGorootExport(pkgDir string) (string, bool) {
+ f, ok := exportMap.Load(pkgDir)
+ if !ok {
+ var (
+ listOnce sync.Once
+ exportPath string
+ )
+ f, _ = exportMap.LoadOrStore(pkgDir, func() (string, bool) {
+ listOnce.Do(func() {
+ cmd := exec.Command(filepath.Join(build.Default.GOROOT, "bin", "go"), "list", "-export", "-f", "{{.Export}}", pkgDir)
+ cmd.Dir = build.Default.GOROOT
+ cmd.Env = append(cmd.Environ(), "GOROOT="+build.Default.GOROOT)
+ var output []byte
+ output, err := cmd.Output()
+ if err != nil {
+ return
+ }
+
+ exports := strings.Split(string(bytes.TrimSpace(output)), "\n")
+ if len(exports) != 1 {
+ return
+ }
+
+ exportPath = exports[0]
+ })
+
+ return exportPath, exportPath != ""
+ })
+ }
+
+ return f.(func() (string, bool))()
+}
+
+var pkgExts = [...]string{".a", ".o"} // a file from the build cache will have no extension
+
+// FindPkg returns the filename and unique package id for an import
+// path based on package information provided by build.Import (using
+// the build.Default build.Context). A relative srcDir is interpreted
+// relative to the current working directory.
+// If no file was found, an empty filename is returned.
+func FindPkg(path, srcDir string) (filename, id string) {
+ if path == "" {
+ return
+ }
+
+ var noext string
+ switch {
+ default:
+ // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
+ // Don't require the source files to be present.
+ if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
+ srcDir = abs
+ }
+ bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
+ if bp.PkgObj == "" {
+ var ok bool
+ if bp.Goroot && bp.Dir != "" {
+ filename, ok = lookupGorootExport(bp.Dir)
+ }
+ if !ok {
+ id = path // make sure we have an id to print in error message
+ return
+ }
+ } else {
+ noext = strings.TrimSuffix(bp.PkgObj, ".a")
+ }
+ id = bp.ImportPath
+
+ case build.IsLocalImport(path):
+ // "./x" -> "/this/directory/x.ext", "/this/directory/x"
+ noext = filepath.Join(srcDir, path)
+ id = noext
+
+ case filepath.IsAbs(path):
+ // for completeness only - go/build.Import
+ // does not support absolute imports
+ // "/x" -> "/x.ext", "/x"
+ noext = path
+ id = path
+ }
+
+ if false { // for debugging
+ if path != id {
+ fmt.Printf("%s -> %s\n", path, id)
+ }
+ }
+
+ if filename != "" {
+ if f, err := os.Stat(filename); err == nil && !f.IsDir() {
+ return
+ }
+ }
+ // try extensions
+ for _, ext := range pkgExts {
+ filename = noext + ext
+ if f, err := os.Stat(filename); err == nil && !f.IsDir() {
+ return
+ }
+ }
+
+ filename = "" // not found
+ return
+}
+
+// Import imports a gc-generated package given its import path and srcDir, adds
+// the corresponding package object to the packages map, and returns the object.
+// The packages map must contain all packages already imported.
+func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
+ var rc io.ReadCloser
+ var id string
+ if lookup != nil {
+ // With custom lookup specified, assume that caller has
+ // converted path to a canonical import path for use in the map.
+ if path == "unsafe" {
+ return types.Unsafe, nil
+ }
+ id = path
+
+ // No need to re-import if the package was imported completely before.
+ if pkg = packages[id]; pkg != nil && pkg.Complete() {
+ return
+ }
+ f, err := lookup(path)
+ if err != nil {
+ return nil, err
+ }
+ rc = f
+ } else {
+ var filename string
+ filename, id = FindPkg(path, srcDir)
+ if filename == "" {
+ if path == "unsafe" {
+ return types.Unsafe, nil
+ }
+ return nil, fmt.Errorf("can't find import: %q", id)
+ }
+
+ // no need to re-import if the package was imported completely before
+ if pkg = packages[id]; pkg != nil && pkg.Complete() {
+ return
+ }
+
+ // open file
+ f, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ if err != nil {
+ // add file name to error
+ err = fmt.Errorf("%s: %v", filename, err)
+ }
+ }()
+ rc = f
+ }
+ defer rc.Close()
+
+ buf := bufio.NewReader(rc)
+ hdr, size, err := FindExportData(buf)
+ if err != nil {
+ return
+ }
+
+ switch hdr {
+ case "$$\n":
+ err = fmt.Errorf("import %q: old textual export format no longer supported (recompile library)", path)
+
+ case "$$B\n":
+ var exportFormat byte
+ if exportFormat, err = buf.ReadByte(); err != nil {
+ return
+ }
+ size--
+
+ // The unified export format starts with a 'u'; the indexed export
+ // format starts with an 'i'; and the older binary export format
+ // starts with a 'c', 'd', or 'v' (from "version"). Select
+ // appropriate importer.
+ switch exportFormat {
+ case 'u':
+ var data []byte
+ var r io.Reader = buf
+ if size >= 0 {
+ if data, err = saferio.ReadData(r, uint64(size)); err != nil {
+ return
+ }
+ } else if data, err = io.ReadAll(r); err != nil {
+ return
+ }
+ s := string(data)
+ s = s[:strings.LastIndex(s, "\n$$\n")]
+
+ input := pkgbits.NewPkgDecoder(id, s)
+ pkg = readUnifiedPackage(fset, nil, packages, input)
+ case 'i':
+ pkg, err = iImportData(fset, packages, buf, id)
+ default:
+ err = fmt.Errorf("import %q: old binary export format no longer supported (recompile library)", path)
+ }
+
+ default:
+ err = fmt.Errorf("import %q: unknown export data header: %q", path, hdr)
+ }
+
+ return
+}
+
+type byPath []*types.Package
+
+func (a byPath) Len() int { return len(a) }
+func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
diff --git a/contrib/go/_std_1.20/src/go/internal/gcimporter/iimport.go b/contrib/go/_std_1.21/src/go/internal/gcimporter/iimport.go
index 9e3c945b56..9e3c945b56 100644
--- a/contrib/go/_std_1.20/src/go/internal/gcimporter/iimport.go
+++ b/contrib/go/_std_1.21/src/go/internal/gcimporter/iimport.go
diff --git a/contrib/go/_std_1.20/src/go/internal/gcimporter/support.go b/contrib/go/_std_1.21/src/go/internal/gcimporter/support.go
index 7ed8c9a404..7ed8c9a404 100644
--- a/contrib/go/_std_1.20/src/go/internal/gcimporter/support.go
+++ b/contrib/go/_std_1.21/src/go/internal/gcimporter/support.go
diff --git a/contrib/go/_std_1.21/src/go/internal/gcimporter/ureader.go b/contrib/go/_std_1.21/src/go/internal/gcimporter/ureader.go
new file mode 100644
index 0000000000..ac85a415b1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/internal/gcimporter/ureader.go
@@ -0,0 +1,657 @@
+// 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 gcimporter
+
+import (
+ "go/token"
+ "go/types"
+ "internal/pkgbits"
+ "sort"
+)
+
+// A pkgReader holds the shared state for reading a unified IR package
+// description.
+type pkgReader struct {
+ pkgbits.PkgDecoder
+
+ fake fakeFileSet
+
+ ctxt *types.Context
+ imports map[string]*types.Package // previously imported packages, indexed by path
+
+ // lazily initialized arrays corresponding to the unified IR
+ // PosBase, Pkg, and Type sections, respectively.
+ posBases []string // position bases (i.e., file names)
+ pkgs []*types.Package
+ typs []types.Type
+
+ // laterFns holds functions that need to be invoked at the end of
+ // import reading.
+ laterFns []func()
+
+ // ifaces holds a list of constructed Interfaces, which need to have
+ // Complete called after importing is done.
+ ifaces []*types.Interface
+}
+
+// later adds a function to be invoked at the end of import reading.
+func (pr *pkgReader) later(fn func()) {
+ pr.laterFns = append(pr.laterFns, fn)
+}
+
+// readUnifiedPackage reads a package description from the given
+// unified IR export data decoder.
+func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package {
+ pr := pkgReader{
+ PkgDecoder: input,
+
+ fake: fakeFileSet{
+ fset: fset,
+ files: make(map[string]*fileInfo),
+ },
+
+ ctxt: ctxt,
+ imports: imports,
+
+ posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)),
+ pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)),
+ typs: make([]types.Type, input.NumElems(pkgbits.RelocType)),
+ }
+ defer pr.fake.setLines()
+
+ r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic)
+ pkg := r.pkg()
+ r.Bool() // TODO(mdempsky): Remove; was "has init"
+
+ for i, n := 0, r.Len(); i < n; i++ {
+ // As if r.obj(), but avoiding the Scope.Lookup call,
+ // to avoid eager loading of imports.
+ r.Sync(pkgbits.SyncObject)
+ assert(!r.Bool())
+ r.p.objIdx(r.Reloc(pkgbits.RelocObj))
+ assert(r.Len() == 0)
+ }
+
+ r.Sync(pkgbits.SyncEOF)
+
+ for _, fn := range pr.laterFns {
+ fn()
+ }
+
+ for _, iface := range pr.ifaces {
+ iface.Complete()
+ }
+
+ // Imports() of pkg are all of the transitive packages that were loaded.
+ var imps []*types.Package
+ for _, imp := range pr.pkgs {
+ if imp != nil && imp != pkg {
+ imps = append(imps, imp)
+ }
+ }
+ sort.Sort(byPath(imps))
+ pkg.SetImports(imps)
+
+ pkg.MarkComplete()
+ return pkg
+}
+
+// A reader holds the state for reading a single unified IR element
+// within a package.
+type reader struct {
+ pkgbits.Decoder
+
+ p *pkgReader
+
+ dict *readerDict
+}
+
+// A readerDict holds the state for type parameters that parameterize
+// the current unified IR element.
+type readerDict struct {
+ // bounds is a slice of typeInfos corresponding to the underlying
+ // bounds of the element's type parameters.
+ bounds []typeInfo
+
+ // tparams is a slice of the constructed TypeParams for the element.
+ tparams []*types.TypeParam
+
+ // devived is a slice of types derived from tparams, which may be
+ // instantiated while reading the current element.
+ derived []derivedInfo
+ derivedTypes []types.Type // lazily instantiated from derived
+}
+
+func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
+ return &reader{
+ Decoder: pr.NewDecoder(k, idx, marker),
+ p: pr,
+ }
+}
+
+func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader {
+ return &reader{
+ Decoder: pr.TempDecoder(k, idx, marker),
+ p: pr,
+ }
+}
+
+func (pr *pkgReader) retireReader(r *reader) {
+ pr.RetireDecoder(&r.Decoder)
+}
+
+// @@@ Positions
+
+func (r *reader) pos() token.Pos {
+ r.Sync(pkgbits.SyncPos)
+ if !r.Bool() {
+ return token.NoPos
+ }
+
+ // TODO(mdempsky): Delta encoding.
+ posBase := r.posBase()
+ line := r.Uint()
+ col := r.Uint()
+ return r.p.fake.pos(posBase, int(line), int(col))
+}
+
+func (r *reader) posBase() string {
+ return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase))
+}
+
+func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string {
+ if b := pr.posBases[idx]; b != "" {
+ return b
+ }
+
+ var filename string
+ {
+ r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase)
+
+ // Within types2, position bases have a lot more details (e.g.,
+ // keeping track of where //line directives appeared exactly).
+ //
+ // For go/types, we just track the file name.
+
+ filename = r.String()
+
+ if r.Bool() { // file base
+ // Was: "b = token.NewTrimmedFileBase(filename, true)"
+ } else { // line base
+ pos := r.pos()
+ line := r.Uint()
+ col := r.Uint()
+
+ // Was: "b = token.NewLineBase(pos, filename, true, line, col)"
+ _, _, _ = pos, line, col
+ }
+ pr.retireReader(r)
+ }
+ b := filename
+ pr.posBases[idx] = b
+ return b
+}
+
+// @@@ Packages
+
+func (r *reader) pkg() *types.Package {
+ r.Sync(pkgbits.SyncPkg)
+ return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg))
+}
+
+func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package {
+ // TODO(mdempsky): Consider using some non-nil pointer to indicate
+ // the universe scope, so we don't need to keep re-reading it.
+ if pkg := pr.pkgs[idx]; pkg != nil {
+ return pkg
+ }
+
+ pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg()
+ pr.pkgs[idx] = pkg
+ return pkg
+}
+
+func (r *reader) doPkg() *types.Package {
+ path := r.String()
+ switch path {
+ case "":
+ path = r.p.PkgPath()
+ case "builtin":
+ return nil // universe
+ case "unsafe":
+ return types.Unsafe
+ }
+
+ if pkg := r.p.imports[path]; pkg != nil {
+ return pkg
+ }
+
+ name := r.String()
+
+ pkg := types.NewPackage(path, name)
+ r.p.imports[path] = pkg
+
+ return pkg
+}
+
+// @@@ Types
+
+func (r *reader) typ() types.Type {
+ return r.p.typIdx(r.typInfo(), r.dict)
+}
+
+func (r *reader) typInfo() typeInfo {
+ r.Sync(pkgbits.SyncType)
+ if r.Bool() {
+ return typeInfo{idx: pkgbits.Index(r.Len()), derived: true}
+ }
+ return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false}
+}
+
+func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type {
+ idx := info.idx
+ var where *types.Type
+ if info.derived {
+ where = &dict.derivedTypes[idx]
+ idx = dict.derived[idx].idx
+ } else {
+ where = &pr.typs[idx]
+ }
+
+ if typ := *where; typ != nil {
+ return typ
+ }
+
+ var typ types.Type
+ {
+ r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx)
+ r.dict = dict
+
+ typ = r.doTyp()
+ assert(typ != nil)
+ pr.retireReader(r)
+ }
+ // See comment in pkgReader.typIdx explaining how this happens.
+ if prev := *where; prev != nil {
+ return prev
+ }
+
+ *where = typ
+ return typ
+}
+
+func (r *reader) doTyp() (res types.Type) {
+ switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag {
+ default:
+ errorf("unhandled type tag: %v", tag)
+ panic("unreachable")
+
+ case pkgbits.TypeBasic:
+ return types.Typ[r.Len()]
+
+ case pkgbits.TypeNamed:
+ obj, targs := r.obj()
+ name := obj.(*types.TypeName)
+ if len(targs) != 0 {
+ t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false)
+ return t
+ }
+ return name.Type()
+
+ case pkgbits.TypeTypeParam:
+ return r.dict.tparams[r.Len()]
+
+ case pkgbits.TypeArray:
+ len := int64(r.Uint64())
+ return types.NewArray(r.typ(), len)
+ case pkgbits.TypeChan:
+ dir := types.ChanDir(r.Len())
+ return types.NewChan(dir, r.typ())
+ case pkgbits.TypeMap:
+ return types.NewMap(r.typ(), r.typ())
+ case pkgbits.TypePointer:
+ return types.NewPointer(r.typ())
+ case pkgbits.TypeSignature:
+ return r.signature(nil, nil, nil)
+ case pkgbits.TypeSlice:
+ return types.NewSlice(r.typ())
+ case pkgbits.TypeStruct:
+ return r.structType()
+ case pkgbits.TypeInterface:
+ return r.interfaceType()
+ case pkgbits.TypeUnion:
+ return r.unionType()
+ }
+}
+
+func (r *reader) structType() *types.Struct {
+ fields := make([]*types.Var, r.Len())
+ var tags []string
+ for i := range fields {
+ pos := r.pos()
+ pkg, name := r.selector()
+ ftyp := r.typ()
+ tag := r.String()
+ embedded := r.Bool()
+
+ fields[i] = types.NewField(pos, pkg, name, ftyp, embedded)
+ if tag != "" {
+ for len(tags) < i {
+ tags = append(tags, "")
+ }
+ tags = append(tags, tag)
+ }
+ }
+ return types.NewStruct(fields, tags)
+}
+
+func (r *reader) unionType() *types.Union {
+ terms := make([]*types.Term, r.Len())
+ for i := range terms {
+ terms[i] = types.NewTerm(r.Bool(), r.typ())
+ }
+ return types.NewUnion(terms)
+}
+
+func (r *reader) interfaceType() *types.Interface {
+ methods := make([]*types.Func, r.Len())
+ embeddeds := make([]types.Type, r.Len())
+ implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool()
+
+ for i := range methods {
+ pos := r.pos()
+ pkg, name := r.selector()
+ mtyp := r.signature(nil, nil, nil)
+ methods[i] = types.NewFunc(pos, pkg, name, mtyp)
+ }
+
+ for i := range embeddeds {
+ embeddeds[i] = r.typ()
+ }
+
+ iface := types.NewInterfaceType(methods, embeddeds)
+ if implicit {
+ iface.MarkImplicit()
+ }
+
+ // We need to call iface.Complete(), but if there are any embedded
+ // defined types, then we may not have set their underlying
+ // interface type yet. So we need to defer calling Complete until
+ // after we've called SetUnderlying everywhere.
+ //
+ // TODO(mdempsky): After CL 424876 lands, it should be safe to call
+ // iface.Complete() immediately.
+ r.p.ifaces = append(r.p.ifaces, iface)
+
+ return iface
+}
+
+func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature {
+ r.Sync(pkgbits.SyncSignature)
+
+ params := r.params()
+ results := r.params()
+ variadic := r.Bool()
+
+ return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic)
+}
+
+func (r *reader) params() *types.Tuple {
+ r.Sync(pkgbits.SyncParams)
+
+ params := make([]*types.Var, r.Len())
+ for i := range params {
+ params[i] = r.param()
+ }
+
+ return types.NewTuple(params...)
+}
+
+func (r *reader) param() *types.Var {
+ r.Sync(pkgbits.SyncParam)
+
+ pos := r.pos()
+ pkg, name := r.localIdent()
+ typ := r.typ()
+
+ return types.NewParam(pos, pkg, name, typ)
+}
+
+// @@@ Objects
+
+func (r *reader) obj() (types.Object, []types.Type) {
+ r.Sync(pkgbits.SyncObject)
+
+ assert(!r.Bool())
+
+ pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj))
+ obj := pkgScope(pkg).Lookup(name)
+
+ targs := make([]types.Type, r.Len())
+ for i := range targs {
+ targs[i] = r.typ()
+ }
+
+ return obj, targs
+}
+
+func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) {
+
+ var objPkg *types.Package
+ var objName string
+ var tag pkgbits.CodeObj
+ {
+ rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1)
+
+ objPkg, objName = rname.qualifiedIdent()
+ assert(objName != "")
+
+ tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj))
+ pr.retireReader(rname)
+ }
+
+ if tag == pkgbits.ObjStub {
+ assert(objPkg == nil || objPkg == types.Unsafe)
+ return objPkg, objName
+ }
+
+ // Ignore local types promoted to global scope (#55110).
+ if _, suffix := splitVargenSuffix(objName); suffix != "" {
+ return objPkg, objName
+ }
+
+ if objPkg.Scope().Lookup(objName) == nil {
+ dict := pr.objDictIdx(idx)
+
+ r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1)
+ r.dict = dict
+
+ declare := func(obj types.Object) {
+ objPkg.Scope().Insert(obj)
+ }
+
+ switch tag {
+ default:
+ panic("weird")
+
+ case pkgbits.ObjAlias:
+ pos := r.pos()
+ typ := r.typ()
+ declare(types.NewTypeName(pos, objPkg, objName, typ))
+
+ case pkgbits.ObjConst:
+ pos := r.pos()
+ typ := r.typ()
+ val := r.Value()
+ declare(types.NewConst(pos, objPkg, objName, typ, val))
+
+ case pkgbits.ObjFunc:
+ pos := r.pos()
+ tparams := r.typeParamNames()
+ sig := r.signature(nil, nil, tparams)
+ declare(types.NewFunc(pos, objPkg, objName, sig))
+
+ case pkgbits.ObjType:
+ pos := r.pos()
+
+ obj := types.NewTypeName(pos, objPkg, objName, nil)
+ named := types.NewNamed(obj, nil, nil)
+ declare(obj)
+
+ named.SetTypeParams(r.typeParamNames())
+
+ underlying := r.typ().Underlying()
+
+ // If the underlying type is an interface, we need to
+ // duplicate its methods so we can replace the receiver
+ // parameter's type (#49906).
+ if iface, ok := underlying.(*types.Interface); ok && iface.NumExplicitMethods() != 0 {
+ methods := make([]*types.Func, iface.NumExplicitMethods())
+ for i := range methods {
+ fn := iface.ExplicitMethod(i)
+ sig := fn.Type().(*types.Signature)
+
+ recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named)
+ methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignature(recv, sig.Params(), sig.Results(), sig.Variadic()))
+ }
+
+ embeds := make([]types.Type, iface.NumEmbeddeds())
+ for i := range embeds {
+ embeds[i] = iface.EmbeddedType(i)
+ }
+
+ newIface := types.NewInterfaceType(methods, embeds)
+ r.p.ifaces = append(r.p.ifaces, newIface)
+ underlying = newIface
+ }
+
+ named.SetUnderlying(underlying)
+
+ for i, n := 0, r.Len(); i < n; i++ {
+ named.AddMethod(r.method())
+ }
+
+ case pkgbits.ObjVar:
+ pos := r.pos()
+ typ := r.typ()
+ declare(types.NewVar(pos, objPkg, objName, typ))
+ }
+ }
+
+ return objPkg, objName
+}
+
+func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict {
+
+ var dict readerDict
+
+ {
+ r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1)
+ if implicits := r.Len(); implicits != 0 {
+ errorf("unexpected object with %v implicit type parameter(s)", implicits)
+ }
+
+ dict.bounds = make([]typeInfo, r.Len())
+ for i := range dict.bounds {
+ dict.bounds[i] = r.typInfo()
+ }
+
+ dict.derived = make([]derivedInfo, r.Len())
+ dict.derivedTypes = make([]types.Type, len(dict.derived))
+ for i := range dict.derived {
+ dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()}
+ }
+
+ pr.retireReader(r)
+ }
+ // function references follow, but reader doesn't need those
+
+ return &dict
+}
+
+func (r *reader) typeParamNames() []*types.TypeParam {
+ r.Sync(pkgbits.SyncTypeParamNames)
+
+ // Note: This code assumes it only processes objects without
+ // implement type parameters. This is currently fine, because
+ // reader is only used to read in exported declarations, which are
+ // always package scoped.
+
+ if len(r.dict.bounds) == 0 {
+ return nil
+ }
+
+ // Careful: Type parameter lists may have cycles. To allow for this,
+ // we construct the type parameter list in two passes: first we
+ // create all the TypeNames and TypeParams, then we construct and
+ // set the bound type.
+
+ r.dict.tparams = make([]*types.TypeParam, len(r.dict.bounds))
+ for i := range r.dict.bounds {
+ pos := r.pos()
+ pkg, name := r.localIdent()
+
+ tname := types.NewTypeName(pos, pkg, name, nil)
+ r.dict.tparams[i] = types.NewTypeParam(tname, nil)
+ }
+
+ typs := make([]types.Type, len(r.dict.bounds))
+ for i, bound := range r.dict.bounds {
+ typs[i] = r.p.typIdx(bound, r.dict)
+ }
+
+ // TODO(mdempsky): This is subtle, elaborate further.
+ //
+ // We have to save tparams outside of the closure, because
+ // typeParamNames() can be called multiple times with the same
+ // dictionary instance.
+ //
+ // Also, this needs to happen later to make sure SetUnderlying has
+ // been called.
+ //
+ // TODO(mdempsky): Is it safe to have a single "later" slice or do
+ // we need to have multiple passes? See comments on CL 386002 and
+ // go.dev/issue/52104.
+ tparams := r.dict.tparams
+ r.p.later(func() {
+ for i, typ := range typs {
+ tparams[i].SetConstraint(typ)
+ }
+ })
+
+ return r.dict.tparams
+}
+
+func (r *reader) method() *types.Func {
+ r.Sync(pkgbits.SyncMethod)
+ pos := r.pos()
+ pkg, name := r.selector()
+
+ rparams := r.typeParamNames()
+ sig := r.signature(r.param(), rparams, nil)
+
+ _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go.
+ return types.NewFunc(pos, pkg, name, sig)
+}
+
+func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) }
+func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) }
+func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) }
+
+func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) {
+ r.Sync(marker)
+ return r.pkg(), r.String()
+}
+
+// pkgScope returns pkg.Scope().
+// If pkg is nil, it returns types.Universe instead.
+//
+// TODO(mdempsky): Remove after x/tools can depend on Go 1.19.
+func pkgScope(pkg *types.Package) *types.Scope {
+ if pkg != nil {
+ return pkg.Scope()
+ }
+ return types.Universe
+}
diff --git a/contrib/go/_std_1.21/src/go/internal/gcimporter/ya.make b/contrib/go/_std_1.21/src/go/internal/gcimporter/ya.make
new file mode 100644
index 0000000000..89bce373ac
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/internal/gcimporter/ya.make
@@ -0,0 +1,16 @@
+GO_LIBRARY()
+
+SRCS(
+ exportdata.go
+ gcimporter.go
+ iimport.go
+ support.go
+ ureader.go
+)
+
+GO_XTEST_SRCS(gcimporter_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/go/internal/srcimporter/srcimporter.go b/contrib/go/_std_1.21/src/go/internal/srcimporter/srcimporter.go
index 7563d9f34f..7563d9f34f 100644
--- a/contrib/go/_std_1.20/src/go/internal/srcimporter/srcimporter.go
+++ b/contrib/go/_std_1.21/src/go/internal/srcimporter/srcimporter.go
diff --git a/contrib/go/_std_1.21/src/go/internal/srcimporter/ya.make b/contrib/go/_std_1.21/src/go/internal/srcimporter/ya.make
new file mode 100644
index 0000000000..561a8e532e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/internal/srcimporter/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ srcimporter.go
+)
+
+GO_TEST_SRCS(srcimporter_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/go/internal/typeparams/typeparams.go b/contrib/go/_std_1.21/src/go/internal/typeparams/typeparams.go
index 3f84f2f0d0..3f84f2f0d0 100644
--- a/contrib/go/_std_1.20/src/go/internal/typeparams/typeparams.go
+++ b/contrib/go/_std_1.21/src/go/internal/typeparams/typeparams.go
diff --git a/contrib/go/_std_1.20/src/go/internal/typeparams/ya.make b/contrib/go/_std_1.21/src/go/internal/typeparams/ya.make
index 1ce7a7405a..1ce7a7405a 100644
--- a/contrib/go/_std_1.20/src/go/internal/typeparams/ya.make
+++ b/contrib/go/_std_1.21/src/go/internal/typeparams/ya.make
diff --git a/contrib/go/_std_1.20/src/go/parser/interface.go b/contrib/go/_std_1.21/src/go/parser/interface.go
index 73cb16272e..73cb16272e 100644
--- a/contrib/go/_std_1.20/src/go/parser/interface.go
+++ b/contrib/go/_std_1.21/src/go/parser/interface.go
diff --git a/contrib/go/_std_1.21/src/go/parser/parser.go b/contrib/go/_std_1.21/src/go/parser/parser.go
new file mode 100644
index 0000000000..e1d941eff3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/parser/parser.go
@@ -0,0 +1,2882 @@
+// Copyright 2009 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 parser implements a parser for Go source files. Input may be
+// provided in a variety of forms (see the various Parse* functions); the
+// output is an abstract syntax tree (AST) representing the Go source. The
+// parser is invoked through one of the Parse* functions.
+//
+// The parser accepts a larger language than is syntactically permitted by
+// the Go spec, for simplicity, and for improved robustness in the presence
+// of syntax errors. For instance, in method declarations, the receiver is
+// treated like an ordinary parameter list and thus may contain multiple
+// entries where the spec permits exactly one. Consequently, the corresponding
+// field in the AST (ast.FuncDecl.Recv) field is not restricted to one entry.
+package parser
+
+import (
+ "fmt"
+ "go/ast"
+ "go/build/constraint"
+ "go/internal/typeparams"
+ "go/scanner"
+ "go/token"
+ "strings"
+)
+
+// The parser structure holds the parser's internal state.
+type parser struct {
+ file *token.File
+ errors scanner.ErrorList
+ scanner scanner.Scanner
+
+ // Tracing/debugging
+ mode Mode // parsing mode
+ trace bool // == (mode&Trace != 0)
+ indent int // indentation used for tracing output
+
+ // Comments
+ comments []*ast.CommentGroup
+ leadComment *ast.CommentGroup // last lead comment
+ lineComment *ast.CommentGroup // last line comment
+ top bool // in top of file (before package clause)
+ goVersion string // minimum Go version found in //go:build comment
+
+ // Next token
+ pos token.Pos // token position
+ tok token.Token // one token look-ahead
+ lit string // token literal
+
+ // Error recovery
+ // (used to limit the number of calls to parser.advance
+ // w/o making scanning progress - avoids potential endless
+ // loops across multiple parser functions during error recovery)
+ syncPos token.Pos // last synchronization position
+ syncCnt int // number of parser.advance calls without progress
+
+ // Non-syntactic parser control
+ exprLev int // < 0: in control clause, >= 0: in expression
+ inRhs bool // if set, the parser is parsing a rhs expression
+
+ imports []*ast.ImportSpec // list of imports
+
+ // nestLev is used to track and limit the recursion depth
+ // during parsing.
+ nestLev int
+}
+
+func (p *parser) init(fset *token.FileSet, filename string, src []byte, mode Mode) {
+ p.file = fset.AddFile(filename, -1, len(src))
+ eh := func(pos token.Position, msg string) { p.errors.Add(pos, msg) }
+ p.scanner.Init(p.file, src, eh, scanner.ScanComments)
+
+ p.top = true
+ p.mode = mode
+ p.trace = mode&Trace != 0 // for convenience (p.trace is used frequently)
+ p.next()
+}
+
+// ----------------------------------------------------------------------------
+// Parsing support
+
+func (p *parser) printTrace(a ...any) {
+ const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
+ const n = len(dots)
+ pos := p.file.Position(p.pos)
+ fmt.Printf("%5d:%3d: ", pos.Line, pos.Column)
+ i := 2 * p.indent
+ for i > n {
+ fmt.Print(dots)
+ i -= n
+ }
+ // i <= n
+ fmt.Print(dots[0:i])
+ fmt.Println(a...)
+}
+
+func trace(p *parser, msg string) *parser {
+ p.printTrace(msg, "(")
+ p.indent++
+ return p
+}
+
+// Usage pattern: defer un(trace(p, "..."))
+func un(p *parser) {
+ p.indent--
+ p.printTrace(")")
+}
+
+// maxNestLev is the deepest we're willing to recurse during parsing
+const maxNestLev int = 1e5
+
+func incNestLev(p *parser) *parser {
+ p.nestLev++
+ if p.nestLev > maxNestLev {
+ p.error(p.pos, "exceeded max nesting depth")
+ panic(bailout{})
+ }
+ return p
+}
+
+// decNestLev is used to track nesting depth during parsing to prevent stack exhaustion.
+// It is used along with incNestLev in a similar fashion to how un and trace are used.
+func decNestLev(p *parser) {
+ p.nestLev--
+}
+
+// Advance to the next token.
+func (p *parser) next0() {
+ // Because of one-token look-ahead, print the previous token
+ // when tracing as it provides a more readable output. The
+ // very first token (!p.pos.IsValid()) is not initialized
+ // (it is token.ILLEGAL), so don't print it.
+ if p.trace && p.pos.IsValid() {
+ s := p.tok.String()
+ switch {
+ case p.tok.IsLiteral():
+ p.printTrace(s, p.lit)
+ case p.tok.IsOperator(), p.tok.IsKeyword():
+ p.printTrace("\"" + s + "\"")
+ default:
+ p.printTrace(s)
+ }
+ }
+
+ for {
+ p.pos, p.tok, p.lit = p.scanner.Scan()
+ if p.tok == token.COMMENT {
+ if p.top && strings.HasPrefix(p.lit, "//go:build") {
+ if x, err := constraint.Parse(p.lit); err == nil {
+ p.goVersion = constraint.GoVersion(x)
+ }
+ }
+ if p.mode&ParseComments == 0 {
+ continue
+ }
+ } else {
+ // Found a non-comment; top of file is over.
+ p.top = false
+ }
+ break
+ }
+}
+
+// Consume a comment and return it and the line on which it ends.
+func (p *parser) consumeComment() (comment *ast.Comment, endline int) {
+ // /*-style comments may end on a different line than where they start.
+ // Scan the comment for '\n' chars and adjust endline accordingly.
+ endline = p.file.Line(p.pos)
+ if p.lit[1] == '*' {
+ // don't use range here - no need to decode Unicode code points
+ for i := 0; i < len(p.lit); i++ {
+ if p.lit[i] == '\n' {
+ endline++
+ }
+ }
+ }
+
+ comment = &ast.Comment{Slash: p.pos, Text: p.lit}
+ p.next0()
+
+ return
+}
+
+// Consume a group of adjacent comments, add it to the parser's
+// comments list, and return it together with the line at which
+// the last comment in the group ends. A non-comment token or n
+// empty lines terminate a comment group.
+func (p *parser) consumeCommentGroup(n int) (comments *ast.CommentGroup, endline int) {
+ var list []*ast.Comment
+ endline = p.file.Line(p.pos)
+ for p.tok == token.COMMENT && p.file.Line(p.pos) <= endline+n {
+ var comment *ast.Comment
+ comment, endline = p.consumeComment()
+ list = append(list, comment)
+ }
+
+ // add comment group to the comments list
+ comments = &ast.CommentGroup{List: list}
+ p.comments = append(p.comments, comments)
+
+ return
+}
+
+// Advance to the next non-comment token. In the process, collect
+// any comment groups encountered, and remember the last lead and
+// line comments.
+//
+// A lead comment is a comment group that starts and ends in a
+// line without any other tokens and that is followed by a non-comment
+// token on the line immediately after the comment group.
+//
+// A line comment is a comment group that follows a non-comment
+// token on the same line, and that has no tokens after it on the line
+// where it ends.
+//
+// Lead and line comments may be considered documentation that is
+// stored in the AST.
+func (p *parser) next() {
+ p.leadComment = nil
+ p.lineComment = nil
+ prev := p.pos
+ p.next0()
+
+ if p.tok == token.COMMENT {
+ var comment *ast.CommentGroup
+ var endline int
+
+ if p.file.Line(p.pos) == p.file.Line(prev) {
+ // The comment is on same line as the previous token; it
+ // cannot be a lead comment but may be a line comment.
+ comment, endline = p.consumeCommentGroup(0)
+ if p.file.Line(p.pos) != endline || p.tok == token.SEMICOLON || p.tok == token.EOF {
+ // The next token is on a different line, thus
+ // the last comment group is a line comment.
+ p.lineComment = comment
+ }
+ }
+
+ // consume successor comments, if any
+ endline = -1
+ for p.tok == token.COMMENT {
+ comment, endline = p.consumeCommentGroup(1)
+ }
+
+ if endline+1 == p.file.Line(p.pos) {
+ // The next token is following on the line immediately after the
+ // comment group, thus the last comment group is a lead comment.
+ p.leadComment = comment
+ }
+ }
+}
+
+// A bailout panic is raised to indicate early termination. pos and msg are
+// only populated when bailing out of object resolution.
+type bailout struct {
+ pos token.Pos
+ msg string
+}
+
+func (p *parser) error(pos token.Pos, msg string) {
+ if p.trace {
+ defer un(trace(p, "error: "+msg))
+ }
+
+ epos := p.file.Position(pos)
+
+ // If AllErrors is not set, discard errors reported on the same line
+ // as the last recorded error and stop parsing if there are more than
+ // 10 errors.
+ if p.mode&AllErrors == 0 {
+ n := len(p.errors)
+ if n > 0 && p.errors[n-1].Pos.Line == epos.Line {
+ return // discard - likely a spurious error
+ }
+ if n > 10 {
+ panic(bailout{})
+ }
+ }
+
+ p.errors.Add(epos, msg)
+}
+
+func (p *parser) errorExpected(pos token.Pos, msg string) {
+ msg = "expected " + msg
+ if pos == p.pos {
+ // the error happened at the current position;
+ // make the error message more specific
+ switch {
+ case p.tok == token.SEMICOLON && p.lit == "\n":
+ msg += ", found newline"
+ case p.tok.IsLiteral():
+ // print 123 rather than 'INT', etc.
+ msg += ", found " + p.lit
+ default:
+ msg += ", found '" + p.tok.String() + "'"
+ }
+ }
+ p.error(pos, msg)
+}
+
+func (p *parser) expect(tok token.Token) token.Pos {
+ pos := p.pos
+ if p.tok != tok {
+ p.errorExpected(pos, "'"+tok.String()+"'")
+ }
+ p.next() // make progress
+ return pos
+}
+
+// expect2 is like expect, but it returns an invalid position
+// if the expected token is not found.
+func (p *parser) expect2(tok token.Token) (pos token.Pos) {
+ if p.tok == tok {
+ pos = p.pos
+ } else {
+ p.errorExpected(p.pos, "'"+tok.String()+"'")
+ }
+ p.next() // make progress
+ return
+}
+
+// expectClosing is like expect but provides a better error message
+// for the common case of a missing comma before a newline.
+func (p *parser) expectClosing(tok token.Token, context string) token.Pos {
+ if p.tok != tok && p.tok == token.SEMICOLON && p.lit == "\n" {
+ p.error(p.pos, "missing ',' before newline in "+context)
+ p.next()
+ }
+ return p.expect(tok)
+}
+
+// expectSemi consumes a semicolon and returns the applicable line comment.
+func (p *parser) expectSemi() (comment *ast.CommentGroup) {
+ // semicolon is optional before a closing ')' or '}'
+ if p.tok != token.RPAREN && p.tok != token.RBRACE {
+ switch p.tok {
+ case token.COMMA:
+ // permit a ',' instead of a ';' but complain
+ p.errorExpected(p.pos, "';'")
+ fallthrough
+ case token.SEMICOLON:
+ if p.lit == ";" {
+ // explicit semicolon
+ p.next()
+ comment = p.lineComment // use following comments
+ } else {
+ // artificial semicolon
+ comment = p.lineComment // use preceding comments
+ p.next()
+ }
+ return comment
+ default:
+ p.errorExpected(p.pos, "';'")
+ p.advance(stmtStart)
+ }
+ }
+ return nil
+}
+
+func (p *parser) atComma(context string, follow token.Token) bool {
+ if p.tok == token.COMMA {
+ return true
+ }
+ if p.tok != follow {
+ msg := "missing ','"
+ if p.tok == token.SEMICOLON && p.lit == "\n" {
+ msg += " before newline"
+ }
+ p.error(p.pos, msg+" in "+context)
+ return true // "insert" comma and continue
+ }
+ return false
+}
+
+func assert(cond bool, msg string) {
+ if !cond {
+ panic("go/parser internal error: " + msg)
+ }
+}
+
+// advance consumes tokens until the current token p.tok
+// is in the 'to' set, or token.EOF. For error recovery.
+func (p *parser) advance(to map[token.Token]bool) {
+ for ; p.tok != token.EOF; p.next() {
+ if to[p.tok] {
+ // Return only if parser made some progress since last
+ // sync or if it has not reached 10 advance calls without
+ // progress. Otherwise consume at least one token to
+ // avoid an endless parser loop (it is possible that
+ // both parseOperand and parseStmt call advance and
+ // correctly do not advance, thus the need for the
+ // invocation limit p.syncCnt).
+ if p.pos == p.syncPos && p.syncCnt < 10 {
+ p.syncCnt++
+ return
+ }
+ if p.pos > p.syncPos {
+ p.syncPos = p.pos
+ p.syncCnt = 0
+ return
+ }
+ // Reaching here indicates a parser bug, likely an
+ // incorrect token list in this function, but it only
+ // leads to skipping of possibly correct code if a
+ // previous error is present, and thus is preferred
+ // over a non-terminating parse.
+ }
+ }
+}
+
+var stmtStart = map[token.Token]bool{
+ token.BREAK: true,
+ token.CONST: true,
+ token.CONTINUE: true,
+ token.DEFER: true,
+ token.FALLTHROUGH: true,
+ token.FOR: true,
+ token.GO: true,
+ token.GOTO: true,
+ token.IF: true,
+ token.RETURN: true,
+ token.SELECT: true,
+ token.SWITCH: true,
+ token.TYPE: true,
+ token.VAR: true,
+}
+
+var declStart = map[token.Token]bool{
+ token.IMPORT: true,
+ token.CONST: true,
+ token.TYPE: true,
+ token.VAR: true,
+}
+
+var exprEnd = map[token.Token]bool{
+ token.COMMA: true,
+ token.COLON: true,
+ token.SEMICOLON: true,
+ token.RPAREN: true,
+ token.RBRACK: true,
+ token.RBRACE: true,
+}
+
+// safePos returns a valid file position for a given position: If pos
+// is valid to begin with, safePos returns pos. If pos is out-of-range,
+// safePos returns the EOF position.
+//
+// This is hack to work around "artificial" end positions in the AST which
+// are computed by adding 1 to (presumably valid) token positions. If the
+// token positions are invalid due to parse errors, the resulting end position
+// may be past the file's EOF position, which would lead to panics if used
+// later on.
+func (p *parser) safePos(pos token.Pos) (res token.Pos) {
+ defer func() {
+ if recover() != nil {
+ res = token.Pos(p.file.Base() + p.file.Size()) // EOF position
+ }
+ }()
+ _ = p.file.Offset(pos) // trigger a panic if position is out-of-range
+ return pos
+}
+
+// ----------------------------------------------------------------------------
+// Identifiers
+
+func (p *parser) parseIdent() *ast.Ident {
+ pos := p.pos
+ name := "_"
+ if p.tok == token.IDENT {
+ name = p.lit
+ p.next()
+ } else {
+ p.expect(token.IDENT) // use expect() error handling
+ }
+ return &ast.Ident{NamePos: pos, Name: name}
+}
+
+func (p *parser) parseIdentList() (list []*ast.Ident) {
+ if p.trace {
+ defer un(trace(p, "IdentList"))
+ }
+
+ list = append(list, p.parseIdent())
+ for p.tok == token.COMMA {
+ p.next()
+ list = append(list, p.parseIdent())
+ }
+
+ return
+}
+
+// ----------------------------------------------------------------------------
+// Common productions
+
+// If lhs is set, result list elements which are identifiers are not resolved.
+func (p *parser) parseExprList() (list []ast.Expr) {
+ if p.trace {
+ defer un(trace(p, "ExpressionList"))
+ }
+
+ list = append(list, p.parseExpr())
+ for p.tok == token.COMMA {
+ p.next()
+ list = append(list, p.parseExpr())
+ }
+
+ return
+}
+
+func (p *parser) parseList(inRhs bool) []ast.Expr {
+ old := p.inRhs
+ p.inRhs = inRhs
+ list := p.parseExprList()
+ p.inRhs = old
+ return list
+}
+
+// ----------------------------------------------------------------------------
+// Types
+
+func (p *parser) parseType() ast.Expr {
+ if p.trace {
+ defer un(trace(p, "Type"))
+ }
+
+ typ := p.tryIdentOrType()
+
+ if typ == nil {
+ pos := p.pos
+ p.errorExpected(pos, "type")
+ p.advance(exprEnd)
+ return &ast.BadExpr{From: pos, To: p.pos}
+ }
+
+ return typ
+}
+
+func (p *parser) parseQualifiedIdent(ident *ast.Ident) ast.Expr {
+ if p.trace {
+ defer un(trace(p, "QualifiedIdent"))
+ }
+
+ typ := p.parseTypeName(ident)
+ if p.tok == token.LBRACK {
+ typ = p.parseTypeInstance(typ)
+ }
+
+ return typ
+}
+
+// If the result is an identifier, it is not resolved.
+func (p *parser) parseTypeName(ident *ast.Ident) ast.Expr {
+ if p.trace {
+ defer un(trace(p, "TypeName"))
+ }
+
+ if ident == nil {
+ ident = p.parseIdent()
+ }
+
+ if p.tok == token.PERIOD {
+ // ident is a package name
+ p.next()
+ sel := p.parseIdent()
+ return &ast.SelectorExpr{X: ident, Sel: sel}
+ }
+
+ return ident
+}
+
+// "[" has already been consumed, and lbrack is its position.
+// If len != nil it is the already consumed array length.
+func (p *parser) parseArrayType(lbrack token.Pos, len ast.Expr) *ast.ArrayType {
+ if p.trace {
+ defer un(trace(p, "ArrayType"))
+ }
+
+ if len == nil {
+ p.exprLev++
+ // always permit ellipsis for more fault-tolerant parsing
+ if p.tok == token.ELLIPSIS {
+ len = &ast.Ellipsis{Ellipsis: p.pos}
+ p.next()
+ } else if p.tok != token.RBRACK {
+ len = p.parseRhs()
+ }
+ p.exprLev--
+ }
+ if p.tok == token.COMMA {
+ // Trailing commas are accepted in type parameter
+ // lists but not in array type declarations.
+ // Accept for better error handling but complain.
+ p.error(p.pos, "unexpected comma; expecting ]")
+ p.next()
+ }
+ p.expect(token.RBRACK)
+ elt := p.parseType()
+ return &ast.ArrayType{Lbrack: lbrack, Len: len, Elt: elt}
+}
+
+func (p *parser) parseArrayFieldOrTypeInstance(x *ast.Ident) (*ast.Ident, ast.Expr) {
+ if p.trace {
+ defer un(trace(p, "ArrayFieldOrTypeInstance"))
+ }
+
+ lbrack := p.expect(token.LBRACK)
+ trailingComma := token.NoPos // if valid, the position of a trailing comma preceding the ']'
+ var args []ast.Expr
+ if p.tok != token.RBRACK {
+ p.exprLev++
+ args = append(args, p.parseRhs())
+ for p.tok == token.COMMA {
+ comma := p.pos
+ p.next()
+ if p.tok == token.RBRACK {
+ trailingComma = comma
+ break
+ }
+ args = append(args, p.parseRhs())
+ }
+ p.exprLev--
+ }
+ rbrack := p.expect(token.RBRACK)
+
+ if len(args) == 0 {
+ // x []E
+ elt := p.parseType()
+ return x, &ast.ArrayType{Lbrack: lbrack, Elt: elt}
+ }
+
+ // x [P]E or x[P]
+ if len(args) == 1 {
+ elt := p.tryIdentOrType()
+ if elt != nil {
+ // x [P]E
+ if trailingComma.IsValid() {
+ // Trailing commas are invalid in array type fields.
+ p.error(trailingComma, "unexpected comma; expecting ]")
+ }
+ return x, &ast.ArrayType{Lbrack: lbrack, Len: args[0], Elt: elt}
+ }
+ }
+
+ // x[P], x[P1, P2], ...
+ return nil, typeparams.PackIndexExpr(x, lbrack, args, rbrack)
+}
+
+func (p *parser) parseFieldDecl() *ast.Field {
+ if p.trace {
+ defer un(trace(p, "FieldDecl"))
+ }
+
+ doc := p.leadComment
+
+ var names []*ast.Ident
+ var typ ast.Expr
+ switch p.tok {
+ case token.IDENT:
+ name := p.parseIdent()
+ if p.tok == token.PERIOD || p.tok == token.STRING || p.tok == token.SEMICOLON || p.tok == token.RBRACE {
+ // embedded type
+ typ = name
+ if p.tok == token.PERIOD {
+ typ = p.parseQualifiedIdent(name)
+ }
+ } else {
+ // name1, name2, ... T
+ names = []*ast.Ident{name}
+ for p.tok == token.COMMA {
+ p.next()
+ names = append(names, p.parseIdent())
+ }
+ // Careful dance: We don't know if we have an embedded instantiated
+ // type T[P1, P2, ...] or a field T of array type []E or [P]E.
+ if len(names) == 1 && p.tok == token.LBRACK {
+ name, typ = p.parseArrayFieldOrTypeInstance(name)
+ if name == nil {
+ names = nil
+ }
+ } else {
+ // T P
+ typ = p.parseType()
+ }
+ }
+ case token.MUL:
+ star := p.pos
+ p.next()
+ if p.tok == token.LPAREN {
+ // *(T)
+ p.error(p.pos, "cannot parenthesize embedded type")
+ p.next()
+ typ = p.parseQualifiedIdent(nil)
+ // expect closing ')' but no need to complain if missing
+ if p.tok == token.RPAREN {
+ p.next()
+ }
+ } else {
+ // *T
+ typ = p.parseQualifiedIdent(nil)
+ }
+ typ = &ast.StarExpr{Star: star, X: typ}
+
+ case token.LPAREN:
+ p.error(p.pos, "cannot parenthesize embedded type")
+ p.next()
+ if p.tok == token.MUL {
+ // (*T)
+ star := p.pos
+ p.next()
+ typ = &ast.StarExpr{Star: star, X: p.parseQualifiedIdent(nil)}
+ } else {
+ // (T)
+ typ = p.parseQualifiedIdent(nil)
+ }
+ // expect closing ')' but no need to complain if missing
+ if p.tok == token.RPAREN {
+ p.next()
+ }
+
+ default:
+ pos := p.pos
+ p.errorExpected(pos, "field name or embedded type")
+ p.advance(exprEnd)
+ typ = &ast.BadExpr{From: pos, To: p.pos}
+ }
+
+ var tag *ast.BasicLit
+ if p.tok == token.STRING {
+ tag = &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit}
+ p.next()
+ }
+
+ comment := p.expectSemi()
+
+ field := &ast.Field{Doc: doc, Names: names, Type: typ, Tag: tag, Comment: comment}
+ return field
+}
+
+func (p *parser) parseStructType() *ast.StructType {
+ if p.trace {
+ defer un(trace(p, "StructType"))
+ }
+
+ pos := p.expect(token.STRUCT)
+ lbrace := p.expect(token.LBRACE)
+ var list []*ast.Field
+ for p.tok == token.IDENT || p.tok == token.MUL || p.tok == token.LPAREN {
+ // a field declaration cannot start with a '(' but we accept
+ // it here for more robust parsing and better error messages
+ // (parseFieldDecl will check and complain if necessary)
+ list = append(list, p.parseFieldDecl())
+ }
+ rbrace := p.expect(token.RBRACE)
+
+ return &ast.StructType{
+ Struct: pos,
+ Fields: &ast.FieldList{
+ Opening: lbrace,
+ List: list,
+ Closing: rbrace,
+ },
+ }
+}
+
+func (p *parser) parsePointerType() *ast.StarExpr {
+ if p.trace {
+ defer un(trace(p, "PointerType"))
+ }
+
+ star := p.expect(token.MUL)
+ base := p.parseType()
+
+ return &ast.StarExpr{Star: star, X: base}
+}
+
+func (p *parser) parseDotsType() *ast.Ellipsis {
+ if p.trace {
+ defer un(trace(p, "DotsType"))
+ }
+
+ pos := p.expect(token.ELLIPSIS)
+ elt := p.parseType()
+
+ return &ast.Ellipsis{Ellipsis: pos, Elt: elt}
+}
+
+type field struct {
+ name *ast.Ident
+ typ ast.Expr
+}
+
+func (p *parser) parseParamDecl(name *ast.Ident, typeSetsOK bool) (f field) {
+ // TODO(rFindley) refactor to be more similar to paramDeclOrNil in the syntax
+ // package
+ if p.trace {
+ defer un(trace(p, "ParamDeclOrNil"))
+ }
+
+ ptok := p.tok
+ if name != nil {
+ p.tok = token.IDENT // force token.IDENT case in switch below
+ } else if typeSetsOK && p.tok == token.TILDE {
+ // "~" ...
+ return field{nil, p.embeddedElem(nil)}
+ }
+
+ switch p.tok {
+ case token.IDENT:
+ // name
+ if name != nil {
+ f.name = name
+ p.tok = ptok
+ } else {
+ f.name = p.parseIdent()
+ }
+ switch p.tok {
+ case token.IDENT, token.MUL, token.ARROW, token.FUNC, token.CHAN, token.MAP, token.STRUCT, token.INTERFACE, token.LPAREN:
+ // name type
+ f.typ = p.parseType()
+
+ case token.LBRACK:
+ // name "[" type1, ..., typeN "]" or name "[" n "]" type
+ f.name, f.typ = p.parseArrayFieldOrTypeInstance(f.name)
+
+ case token.ELLIPSIS:
+ // name "..." type
+ f.typ = p.parseDotsType()
+ return // don't allow ...type "|" ...
+
+ case token.PERIOD:
+ // name "." ...
+ f.typ = p.parseQualifiedIdent(f.name)
+ f.name = nil
+
+ case token.TILDE:
+ if typeSetsOK {
+ f.typ = p.embeddedElem(nil)
+ return
+ }
+
+ case token.OR:
+ if typeSetsOK {
+ // name "|" typeset
+ f.typ = p.embeddedElem(f.name)
+ f.name = nil
+ return
+ }
+ }
+
+ case token.MUL, token.ARROW, token.FUNC, token.LBRACK, token.CHAN, token.MAP, token.STRUCT, token.INTERFACE, token.LPAREN:
+ // type
+ f.typ = p.parseType()
+
+ case token.ELLIPSIS:
+ // "..." type
+ // (always accepted)
+ f.typ = p.parseDotsType()
+ return // don't allow ...type "|" ...
+
+ default:
+ // TODO(rfindley): this is incorrect in the case of type parameter lists
+ // (should be "']'" in that case)
+ p.errorExpected(p.pos, "')'")
+ p.advance(exprEnd)
+ }
+
+ // [name] type "|"
+ if typeSetsOK && p.tok == token.OR && f.typ != nil {
+ f.typ = p.embeddedElem(f.typ)
+ }
+
+ return
+}
+
+func (p *parser) parseParameterList(name0 *ast.Ident, typ0 ast.Expr, closing token.Token) (params []*ast.Field) {
+ if p.trace {
+ defer un(trace(p, "ParameterList"))
+ }
+
+ // Type parameters are the only parameter list closed by ']'.
+ tparams := closing == token.RBRACK
+ // Type set notation is ok in type parameter lists.
+ typeSetsOK := tparams
+
+ pos := p.pos
+ if name0 != nil {
+ pos = name0.Pos()
+ }
+
+ var list []field
+ var named int // number of parameters that have an explicit name and type
+
+ for name0 != nil || p.tok != closing && p.tok != token.EOF {
+ var par field
+ if typ0 != nil {
+ if typeSetsOK {
+ typ0 = p.embeddedElem(typ0)
+ }
+ par = field{name0, typ0}
+ } else {
+ par = p.parseParamDecl(name0, typeSetsOK)
+ }
+ name0 = nil // 1st name was consumed if present
+ typ0 = nil // 1st typ was consumed if present
+ if par.name != nil || par.typ != nil {
+ list = append(list, par)
+ if par.name != nil && par.typ != nil {
+ named++
+ }
+ }
+ if !p.atComma("parameter list", closing) {
+ break
+ }
+ p.next()
+ }
+
+ if len(list) == 0 {
+ return // not uncommon
+ }
+
+ // TODO(gri) parameter distribution and conversion to []*ast.Field
+ // can be combined and made more efficient
+
+ // distribute parameter types
+ if named == 0 {
+ // all unnamed => found names are type names
+ for i := 0; i < len(list); i++ {
+ par := &list[i]
+ if typ := par.name; typ != nil {
+ par.typ = typ
+ par.name = nil
+ }
+ }
+ if tparams {
+ p.error(pos, "type parameters must be named")
+ }
+ } else if named != len(list) {
+ // some named => all must be named
+ ok := true
+ var typ ast.Expr
+ missingName := pos
+ for i := len(list) - 1; i >= 0; i-- {
+ if par := &list[i]; par.typ != nil {
+ typ = par.typ
+ if par.name == nil {
+ ok = false
+ missingName = par.typ.Pos()
+ n := ast.NewIdent("_")
+ n.NamePos = typ.Pos() // correct position
+ par.name = n
+ }
+ } else if typ != nil {
+ par.typ = typ
+ } else {
+ // par.typ == nil && typ == nil => we only have a par.name
+ ok = false
+ missingName = par.name.Pos()
+ par.typ = &ast.BadExpr{From: par.name.Pos(), To: p.pos}
+ }
+ }
+ if !ok {
+ if tparams {
+ p.error(missingName, "type parameters must be named")
+ } else {
+ p.error(pos, "mixed named and unnamed parameters")
+ }
+ }
+ }
+
+ // convert list []*ast.Field
+ if named == 0 {
+ // parameter list consists of types only
+ for _, par := range list {
+ assert(par.typ != nil, "nil type in unnamed parameter list")
+ params = append(params, &ast.Field{Type: par.typ})
+ }
+ return
+ }
+
+ // parameter list consists of named parameters with types
+ var names []*ast.Ident
+ var typ ast.Expr
+ addParams := func() {
+ assert(typ != nil, "nil type in named parameter list")
+ field := &ast.Field{Names: names, Type: typ}
+ params = append(params, field)
+ names = nil
+ }
+ for _, par := range list {
+ if par.typ != typ {
+ if len(names) > 0 {
+ addParams()
+ }
+ typ = par.typ
+ }
+ names = append(names, par.name)
+ }
+ if len(names) > 0 {
+ addParams()
+ }
+ return
+}
+
+func (p *parser) parseParameters(acceptTParams bool) (tparams, params *ast.FieldList) {
+ if p.trace {
+ defer un(trace(p, "Parameters"))
+ }
+
+ if acceptTParams && p.tok == token.LBRACK {
+ opening := p.pos
+ p.next()
+ // [T any](params) syntax
+ list := p.parseParameterList(nil, nil, token.RBRACK)
+ rbrack := p.expect(token.RBRACK)
+ tparams = &ast.FieldList{Opening: opening, List: list, Closing: rbrack}
+ // Type parameter lists must not be empty.
+ if tparams.NumFields() == 0 {
+ p.error(tparams.Closing, "empty type parameter list")
+ tparams = nil // avoid follow-on errors
+ }
+ }
+
+ opening := p.expect(token.LPAREN)
+
+ var fields []*ast.Field
+ if p.tok != token.RPAREN {
+ fields = p.parseParameterList(nil, nil, token.RPAREN)
+ }
+
+ rparen := p.expect(token.RPAREN)
+ params = &ast.FieldList{Opening: opening, List: fields, Closing: rparen}
+
+ return
+}
+
+func (p *parser) parseResult() *ast.FieldList {
+ if p.trace {
+ defer un(trace(p, "Result"))
+ }
+
+ if p.tok == token.LPAREN {
+ _, results := p.parseParameters(false)
+ return results
+ }
+
+ typ := p.tryIdentOrType()
+ if typ != nil {
+ list := make([]*ast.Field, 1)
+ list[0] = &ast.Field{Type: typ}
+ return &ast.FieldList{List: list}
+ }
+
+ return nil
+}
+
+func (p *parser) parseFuncType() *ast.FuncType {
+ if p.trace {
+ defer un(trace(p, "FuncType"))
+ }
+
+ pos := p.expect(token.FUNC)
+ tparams, params := p.parseParameters(true)
+ if tparams != nil {
+ p.error(tparams.Pos(), "function type must have no type parameters")
+ }
+ results := p.parseResult()
+
+ return &ast.FuncType{Func: pos, Params: params, Results: results}
+}
+
+func (p *parser) parseMethodSpec() *ast.Field {
+ if p.trace {
+ defer un(trace(p, "MethodSpec"))
+ }
+
+ doc := p.leadComment
+ var idents []*ast.Ident
+ var typ ast.Expr
+ x := p.parseTypeName(nil)
+ if ident, _ := x.(*ast.Ident); ident != nil {
+ switch {
+ case p.tok == token.LBRACK:
+ // generic method or embedded instantiated type
+ lbrack := p.pos
+ p.next()
+ p.exprLev++
+ x := p.parseExpr()
+ p.exprLev--
+ if name0, _ := x.(*ast.Ident); name0 != nil && p.tok != token.COMMA && p.tok != token.RBRACK {
+ // generic method m[T any]
+ //
+ // Interface methods do not have type parameters. We parse them for a
+ // better error message and improved error recovery.
+ _ = p.parseParameterList(name0, nil, token.RBRACK)
+ _ = p.expect(token.RBRACK)
+ p.error(lbrack, "interface method must have no type parameters")
+
+ // TODO(rfindley) refactor to share code with parseFuncType.
+ _, params := p.parseParameters(false)
+ results := p.parseResult()
+ idents = []*ast.Ident{ident}
+ typ = &ast.FuncType{
+ Func: token.NoPos,
+ Params: params,
+ Results: results,
+ }
+ } else {
+ // embedded instantiated type
+ // TODO(rfindley) should resolve all identifiers in x.
+ list := []ast.Expr{x}
+ if p.atComma("type argument list", token.RBRACK) {
+ p.exprLev++
+ p.next()
+ for p.tok != token.RBRACK && p.tok != token.EOF {
+ list = append(list, p.parseType())
+ if !p.atComma("type argument list", token.RBRACK) {
+ break
+ }
+ p.next()
+ }
+ p.exprLev--
+ }
+ rbrack := p.expectClosing(token.RBRACK, "type argument list")
+ typ = typeparams.PackIndexExpr(ident, lbrack, list, rbrack)
+ }
+ case p.tok == token.LPAREN:
+ // ordinary method
+ // TODO(rfindley) refactor to share code with parseFuncType.
+ _, params := p.parseParameters(false)
+ results := p.parseResult()
+ idents = []*ast.Ident{ident}
+ typ = &ast.FuncType{Func: token.NoPos, Params: params, Results: results}
+ default:
+ // embedded type
+ typ = x
+ }
+ } else {
+ // embedded, possibly instantiated type
+ typ = x
+ if p.tok == token.LBRACK {
+ // embedded instantiated interface
+ typ = p.parseTypeInstance(typ)
+ }
+ }
+
+ // Comment is added at the callsite: the field below may joined with
+ // additional type specs using '|'.
+ // TODO(rfindley) this should be refactored.
+ // TODO(rfindley) add more tests for comment handling.
+ return &ast.Field{Doc: doc, Names: idents, Type: typ}
+}
+
+func (p *parser) embeddedElem(x ast.Expr) ast.Expr {
+ if p.trace {
+ defer un(trace(p, "EmbeddedElem"))
+ }
+ if x == nil {
+ x = p.embeddedTerm()
+ }
+ for p.tok == token.OR {
+ t := new(ast.BinaryExpr)
+ t.OpPos = p.pos
+ t.Op = token.OR
+ p.next()
+ t.X = x
+ t.Y = p.embeddedTerm()
+ x = t
+ }
+ return x
+}
+
+func (p *parser) embeddedTerm() ast.Expr {
+ if p.trace {
+ defer un(trace(p, "EmbeddedTerm"))
+ }
+ if p.tok == token.TILDE {
+ t := new(ast.UnaryExpr)
+ t.OpPos = p.pos
+ t.Op = token.TILDE
+ p.next()
+ t.X = p.parseType()
+ return t
+ }
+
+ t := p.tryIdentOrType()
+ if t == nil {
+ pos := p.pos
+ p.errorExpected(pos, "~ term or type")
+ p.advance(exprEnd)
+ return &ast.BadExpr{From: pos, To: p.pos}
+ }
+
+ return t
+}
+
+func (p *parser) parseInterfaceType() *ast.InterfaceType {
+ if p.trace {
+ defer un(trace(p, "InterfaceType"))
+ }
+
+ pos := p.expect(token.INTERFACE)
+ lbrace := p.expect(token.LBRACE)
+
+ var list []*ast.Field
+
+parseElements:
+ for {
+ switch {
+ case p.tok == token.IDENT:
+ f := p.parseMethodSpec()
+ if f.Names == nil {
+ f.Type = p.embeddedElem(f.Type)
+ }
+ f.Comment = p.expectSemi()
+ list = append(list, f)
+ case p.tok == token.TILDE:
+ typ := p.embeddedElem(nil)
+ comment := p.expectSemi()
+ list = append(list, &ast.Field{Type: typ, Comment: comment})
+ default:
+ if t := p.tryIdentOrType(); t != nil {
+ typ := p.embeddedElem(t)
+ comment := p.expectSemi()
+ list = append(list, &ast.Field{Type: typ, Comment: comment})
+ } else {
+ break parseElements
+ }
+ }
+ }
+
+ // TODO(rfindley): the error produced here could be improved, since we could
+ // accept an identifier, 'type', or a '}' at this point.
+ rbrace := p.expect(token.RBRACE)
+
+ return &ast.InterfaceType{
+ Interface: pos,
+ Methods: &ast.FieldList{
+ Opening: lbrace,
+ List: list,
+ Closing: rbrace,
+ },
+ }
+}
+
+func (p *parser) parseMapType() *ast.MapType {
+ if p.trace {
+ defer un(trace(p, "MapType"))
+ }
+
+ pos := p.expect(token.MAP)
+ p.expect(token.LBRACK)
+ key := p.parseType()
+ p.expect(token.RBRACK)
+ value := p.parseType()
+
+ return &ast.MapType{Map: pos, Key: key, Value: value}
+}
+
+func (p *parser) parseChanType() *ast.ChanType {
+ if p.trace {
+ defer un(trace(p, "ChanType"))
+ }
+
+ pos := p.pos
+ dir := ast.SEND | ast.RECV
+ var arrow token.Pos
+ if p.tok == token.CHAN {
+ p.next()
+ if p.tok == token.ARROW {
+ arrow = p.pos
+ p.next()
+ dir = ast.SEND
+ }
+ } else {
+ arrow = p.expect(token.ARROW)
+ p.expect(token.CHAN)
+ dir = ast.RECV
+ }
+ value := p.parseType()
+
+ return &ast.ChanType{Begin: pos, Arrow: arrow, Dir: dir, Value: value}
+}
+
+func (p *parser) parseTypeInstance(typ ast.Expr) ast.Expr {
+ if p.trace {
+ defer un(trace(p, "TypeInstance"))
+ }
+
+ opening := p.expect(token.LBRACK)
+ p.exprLev++
+ var list []ast.Expr
+ for p.tok != token.RBRACK && p.tok != token.EOF {
+ list = append(list, p.parseType())
+ if !p.atComma("type argument list", token.RBRACK) {
+ break
+ }
+ p.next()
+ }
+ p.exprLev--
+
+ closing := p.expectClosing(token.RBRACK, "type argument list")
+
+ if len(list) == 0 {
+ p.errorExpected(closing, "type argument list")
+ return &ast.IndexExpr{
+ X: typ,
+ Lbrack: opening,
+ Index: &ast.BadExpr{From: opening + 1, To: closing},
+ Rbrack: closing,
+ }
+ }
+
+ return typeparams.PackIndexExpr(typ, opening, list, closing)
+}
+
+func (p *parser) tryIdentOrType() ast.Expr {
+ defer decNestLev(incNestLev(p))
+
+ switch p.tok {
+ case token.IDENT:
+ typ := p.parseTypeName(nil)
+ if p.tok == token.LBRACK {
+ typ = p.parseTypeInstance(typ)
+ }
+ return typ
+ case token.LBRACK:
+ lbrack := p.expect(token.LBRACK)
+ return p.parseArrayType(lbrack, nil)
+ case token.STRUCT:
+ return p.parseStructType()
+ case token.MUL:
+ return p.parsePointerType()
+ case token.FUNC:
+ return p.parseFuncType()
+ case token.INTERFACE:
+ return p.parseInterfaceType()
+ case token.MAP:
+ return p.parseMapType()
+ case token.CHAN, token.ARROW:
+ return p.parseChanType()
+ case token.LPAREN:
+ lparen := p.pos
+ p.next()
+ typ := p.parseType()
+ rparen := p.expect(token.RPAREN)
+ return &ast.ParenExpr{Lparen: lparen, X: typ, Rparen: rparen}
+ }
+
+ // no type found
+ return nil
+}
+
+// ----------------------------------------------------------------------------
+// Blocks
+
+func (p *parser) parseStmtList() (list []ast.Stmt) {
+ if p.trace {
+ defer un(trace(p, "StatementList"))
+ }
+
+ for p.tok != token.CASE && p.tok != token.DEFAULT && p.tok != token.RBRACE && p.tok != token.EOF {
+ list = append(list, p.parseStmt())
+ }
+
+ return
+}
+
+func (p *parser) parseBody() *ast.BlockStmt {
+ if p.trace {
+ defer un(trace(p, "Body"))
+ }
+
+ lbrace := p.expect(token.LBRACE)
+ list := p.parseStmtList()
+ rbrace := p.expect2(token.RBRACE)
+
+ return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
+}
+
+func (p *parser) parseBlockStmt() *ast.BlockStmt {
+ if p.trace {
+ defer un(trace(p, "BlockStmt"))
+ }
+
+ lbrace := p.expect(token.LBRACE)
+ list := p.parseStmtList()
+ rbrace := p.expect2(token.RBRACE)
+
+ return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
+}
+
+// ----------------------------------------------------------------------------
+// Expressions
+
+func (p *parser) parseFuncTypeOrLit() ast.Expr {
+ if p.trace {
+ defer un(trace(p, "FuncTypeOrLit"))
+ }
+
+ typ := p.parseFuncType()
+ if p.tok != token.LBRACE {
+ // function type only
+ return typ
+ }
+
+ p.exprLev++
+ body := p.parseBody()
+ p.exprLev--
+
+ return &ast.FuncLit{Type: typ, Body: body}
+}
+
+// parseOperand may return an expression or a raw type (incl. array
+// types of the form [...]T). Callers must verify the result.
+func (p *parser) parseOperand() ast.Expr {
+ if p.trace {
+ defer un(trace(p, "Operand"))
+ }
+
+ switch p.tok {
+ case token.IDENT:
+ x := p.parseIdent()
+ return x
+
+ case token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING:
+ x := &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit}
+ p.next()
+ return x
+
+ case token.LPAREN:
+ lparen := p.pos
+ p.next()
+ p.exprLev++
+ x := p.parseRhs() // types may be parenthesized: (some type)
+ p.exprLev--
+ rparen := p.expect(token.RPAREN)
+ return &ast.ParenExpr{Lparen: lparen, X: x, Rparen: rparen}
+
+ case token.FUNC:
+ return p.parseFuncTypeOrLit()
+ }
+
+ if typ := p.tryIdentOrType(); typ != nil { // do not consume trailing type parameters
+ // could be type for composite literal or conversion
+ _, isIdent := typ.(*ast.Ident)
+ assert(!isIdent, "type cannot be identifier")
+ return typ
+ }
+
+ // we have an error
+ pos := p.pos
+ p.errorExpected(pos, "operand")
+ p.advance(stmtStart)
+ return &ast.BadExpr{From: pos, To: p.pos}
+}
+
+func (p *parser) parseSelector(x ast.Expr) ast.Expr {
+ if p.trace {
+ defer un(trace(p, "Selector"))
+ }
+
+ sel := p.parseIdent()
+
+ return &ast.SelectorExpr{X: x, Sel: sel}
+}
+
+func (p *parser) parseTypeAssertion(x ast.Expr) ast.Expr {
+ if p.trace {
+ defer un(trace(p, "TypeAssertion"))
+ }
+
+ lparen := p.expect(token.LPAREN)
+ var typ ast.Expr
+ if p.tok == token.TYPE {
+ // type switch: typ == nil
+ p.next()
+ } else {
+ typ = p.parseType()
+ }
+ rparen := p.expect(token.RPAREN)
+
+ return &ast.TypeAssertExpr{X: x, Type: typ, Lparen: lparen, Rparen: rparen}
+}
+
+func (p *parser) parseIndexOrSliceOrInstance(x ast.Expr) ast.Expr {
+ if p.trace {
+ defer un(trace(p, "parseIndexOrSliceOrInstance"))
+ }
+
+ lbrack := p.expect(token.LBRACK)
+ if p.tok == token.RBRACK {
+ // empty index, slice or index expressions are not permitted;
+ // accept them for parsing tolerance, but complain
+ p.errorExpected(p.pos, "operand")
+ rbrack := p.pos
+ p.next()
+ return &ast.IndexExpr{
+ X: x,
+ Lbrack: lbrack,
+ Index: &ast.BadExpr{From: rbrack, To: rbrack},
+ Rbrack: rbrack,
+ }
+ }
+ p.exprLev++
+
+ const N = 3 // change the 3 to 2 to disable 3-index slices
+ var args []ast.Expr
+ var index [N]ast.Expr
+ var colons [N - 1]token.Pos
+ if p.tok != token.COLON {
+ // We can't know if we have an index expression or a type instantiation;
+ // so even if we see a (named) type we are not going to be in type context.
+ index[0] = p.parseRhs()
+ }
+ ncolons := 0
+ switch p.tok {
+ case token.COLON:
+ // slice expression
+ for p.tok == token.COLON && ncolons < len(colons) {
+ colons[ncolons] = p.pos
+ ncolons++
+ p.next()
+ if p.tok != token.COLON && p.tok != token.RBRACK && p.tok != token.EOF {
+ index[ncolons] = p.parseRhs()
+ }
+ }
+ case token.COMMA:
+ // instance expression
+ args = append(args, index[0])
+ for p.tok == token.COMMA {
+ p.next()
+ if p.tok != token.RBRACK && p.tok != token.EOF {
+ args = append(args, p.parseType())
+ }
+ }
+ }
+
+ p.exprLev--
+ rbrack := p.expect(token.RBRACK)
+
+ if ncolons > 0 {
+ // slice expression
+ slice3 := false
+ if ncolons == 2 {
+ slice3 = true
+ // Check presence of middle and final index here rather than during type-checking
+ // to prevent erroneous programs from passing through gofmt (was issue 7305).
+ if index[1] == nil {
+ p.error(colons[0], "middle index required in 3-index slice")
+ index[1] = &ast.BadExpr{From: colons[0] + 1, To: colons[1]}
+ }
+ if index[2] == nil {
+ p.error(colons[1], "final index required in 3-index slice")
+ index[2] = &ast.BadExpr{From: colons[1] + 1, To: rbrack}
+ }
+ }
+ return &ast.SliceExpr{X: x, Lbrack: lbrack, Low: index[0], High: index[1], Max: index[2], Slice3: slice3, Rbrack: rbrack}
+ }
+
+ if len(args) == 0 {
+ // index expression
+ return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: index[0], Rbrack: rbrack}
+ }
+
+ // instance expression
+ return typeparams.PackIndexExpr(x, lbrack, args, rbrack)
+}
+
+func (p *parser) parseCallOrConversion(fun ast.Expr) *ast.CallExpr {
+ if p.trace {
+ defer un(trace(p, "CallOrConversion"))
+ }
+
+ lparen := p.expect(token.LPAREN)
+ p.exprLev++
+ var list []ast.Expr
+ var ellipsis token.Pos
+ for p.tok != token.RPAREN && p.tok != token.EOF && !ellipsis.IsValid() {
+ list = append(list, p.parseRhs()) // builtins may expect a type: make(some type, ...)
+ if p.tok == token.ELLIPSIS {
+ ellipsis = p.pos
+ p.next()
+ }
+ if !p.atComma("argument list", token.RPAREN) {
+ break
+ }
+ p.next()
+ }
+ p.exprLev--
+ rparen := p.expectClosing(token.RPAREN, "argument list")
+
+ return &ast.CallExpr{Fun: fun, Lparen: lparen, Args: list, Ellipsis: ellipsis, Rparen: rparen}
+}
+
+func (p *parser) parseValue() ast.Expr {
+ if p.trace {
+ defer un(trace(p, "Element"))
+ }
+
+ if p.tok == token.LBRACE {
+ return p.parseLiteralValue(nil)
+ }
+
+ x := p.parseExpr()
+
+ return x
+}
+
+func (p *parser) parseElement() ast.Expr {
+ if p.trace {
+ defer un(trace(p, "Element"))
+ }
+
+ x := p.parseValue()
+ if p.tok == token.COLON {
+ colon := p.pos
+ p.next()
+ x = &ast.KeyValueExpr{Key: x, Colon: colon, Value: p.parseValue()}
+ }
+
+ return x
+}
+
+func (p *parser) parseElementList() (list []ast.Expr) {
+ if p.trace {
+ defer un(trace(p, "ElementList"))
+ }
+
+ for p.tok != token.RBRACE && p.tok != token.EOF {
+ list = append(list, p.parseElement())
+ if !p.atComma("composite literal", token.RBRACE) {
+ break
+ }
+ p.next()
+ }
+
+ return
+}
+
+func (p *parser) parseLiteralValue(typ ast.Expr) ast.Expr {
+ if p.trace {
+ defer un(trace(p, "LiteralValue"))
+ }
+
+ lbrace := p.expect(token.LBRACE)
+ var elts []ast.Expr
+ p.exprLev++
+ if p.tok != token.RBRACE {
+ elts = p.parseElementList()
+ }
+ p.exprLev--
+ rbrace := p.expectClosing(token.RBRACE, "composite literal")
+ return &ast.CompositeLit{Type: typ, Lbrace: lbrace, Elts: elts, Rbrace: rbrace}
+}
+
+// If x is of the form (T), unparen returns unparen(T), otherwise it returns x.
+func unparen(x ast.Expr) ast.Expr {
+ if p, isParen := x.(*ast.ParenExpr); isParen {
+ x = unparen(p.X)
+ }
+ return x
+}
+
+func (p *parser) parsePrimaryExpr(x ast.Expr) ast.Expr {
+ if p.trace {
+ defer un(trace(p, "PrimaryExpr"))
+ }
+
+ if x == nil {
+ x = p.parseOperand()
+ }
+ // We track the nesting here rather than at the entry for the function,
+ // since it can iteratively produce a nested output, and we want to
+ // limit how deep a structure we generate.
+ var n int
+ defer func() { p.nestLev -= n }()
+ for n = 1; ; n++ {
+ incNestLev(p)
+ switch p.tok {
+ case token.PERIOD:
+ p.next()
+ switch p.tok {
+ case token.IDENT:
+ x = p.parseSelector(x)
+ case token.LPAREN:
+ x = p.parseTypeAssertion(x)
+ default:
+ pos := p.pos
+ p.errorExpected(pos, "selector or type assertion")
+ // TODO(rFindley) The check for token.RBRACE below is a targeted fix
+ // to error recovery sufficient to make the x/tools tests to
+ // pass with the new parsing logic introduced for type
+ // parameters. Remove this once error recovery has been
+ // more generally reconsidered.
+ if p.tok != token.RBRACE {
+ p.next() // make progress
+ }
+ sel := &ast.Ident{NamePos: pos, Name: "_"}
+ x = &ast.SelectorExpr{X: x, Sel: sel}
+ }
+ case token.LBRACK:
+ x = p.parseIndexOrSliceOrInstance(x)
+ case token.LPAREN:
+ x = p.parseCallOrConversion(x)
+ case token.LBRACE:
+ // operand may have returned a parenthesized complit
+ // type; accept it but complain if we have a complit
+ t := unparen(x)
+ // determine if '{' belongs to a composite literal or a block statement
+ switch t.(type) {
+ case *ast.BadExpr, *ast.Ident, *ast.SelectorExpr:
+ if p.exprLev < 0 {
+ return x
+ }
+ // x is possibly a composite literal type
+ case *ast.IndexExpr, *ast.IndexListExpr:
+ if p.exprLev < 0 {
+ return x
+ }
+ // x is possibly a composite literal type
+ case *ast.ArrayType, *ast.StructType, *ast.MapType:
+ // x is a composite literal type
+ default:
+ return x
+ }
+ if t != x {
+ p.error(t.Pos(), "cannot parenthesize type in composite literal")
+ // already progressed, no need to advance
+ }
+ x = p.parseLiteralValue(x)
+ default:
+ return x
+ }
+ }
+}
+
+func (p *parser) parseUnaryExpr() ast.Expr {
+ defer decNestLev(incNestLev(p))
+
+ if p.trace {
+ defer un(trace(p, "UnaryExpr"))
+ }
+
+ switch p.tok {
+ case token.ADD, token.SUB, token.NOT, token.XOR, token.AND, token.TILDE:
+ pos, op := p.pos, p.tok
+ p.next()
+ x := p.parseUnaryExpr()
+ return &ast.UnaryExpr{OpPos: pos, Op: op, X: x}
+
+ case token.ARROW:
+ // channel type or receive expression
+ arrow := p.pos
+ p.next()
+
+ // If the next token is token.CHAN we still don't know if it
+ // is a channel type or a receive operation - we only know
+ // once we have found the end of the unary expression. There
+ // are two cases:
+ //
+ // <- type => (<-type) must be channel type
+ // <- expr => <-(expr) is a receive from an expression
+ //
+ // In the first case, the arrow must be re-associated with
+ // the channel type parsed already:
+ //
+ // <- (chan type) => (<-chan type)
+ // <- (chan<- type) => (<-chan (<-type))
+
+ x := p.parseUnaryExpr()
+
+ // determine which case we have
+ if typ, ok := x.(*ast.ChanType); ok {
+ // (<-type)
+
+ // re-associate position info and <-
+ dir := ast.SEND
+ for ok && dir == ast.SEND {
+ if typ.Dir == ast.RECV {
+ // error: (<-type) is (<-(<-chan T))
+ p.errorExpected(typ.Arrow, "'chan'")
+ }
+ arrow, typ.Begin, typ.Arrow = typ.Arrow, arrow, arrow
+ dir, typ.Dir = typ.Dir, ast.RECV
+ typ, ok = typ.Value.(*ast.ChanType)
+ }
+ if dir == ast.SEND {
+ p.errorExpected(arrow, "channel type")
+ }
+
+ return x
+ }
+
+ // <-(expr)
+ return &ast.UnaryExpr{OpPos: arrow, Op: token.ARROW, X: x}
+
+ case token.MUL:
+ // pointer type or unary "*" expression
+ pos := p.pos
+ p.next()
+ x := p.parseUnaryExpr()
+ return &ast.StarExpr{Star: pos, X: x}
+ }
+
+ return p.parsePrimaryExpr(nil)
+}
+
+func (p *parser) tokPrec() (token.Token, int) {
+ tok := p.tok
+ if p.inRhs && tok == token.ASSIGN {
+ tok = token.EQL
+ }
+ return tok, tok.Precedence()
+}
+
+// parseBinaryExpr parses a (possibly) binary expression.
+// If x is non-nil, it is used as the left operand.
+//
+// TODO(rfindley): parseBinaryExpr has become overloaded. Consider refactoring.
+func (p *parser) parseBinaryExpr(x ast.Expr, prec1 int) ast.Expr {
+ if p.trace {
+ defer un(trace(p, "BinaryExpr"))
+ }
+
+ if x == nil {
+ x = p.parseUnaryExpr()
+ }
+ // We track the nesting here rather than at the entry for the function,
+ // since it can iteratively produce a nested output, and we want to
+ // limit how deep a structure we generate.
+ var n int
+ defer func() { p.nestLev -= n }()
+ for n = 1; ; n++ {
+ incNestLev(p)
+ op, oprec := p.tokPrec()
+ if oprec < prec1 {
+ return x
+ }
+ pos := p.expect(op)
+ y := p.parseBinaryExpr(nil, oprec+1)
+ x = &ast.BinaryExpr{X: x, OpPos: pos, Op: op, Y: y}
+ }
+}
+
+// The result may be a type or even a raw type ([...]int).
+func (p *parser) parseExpr() ast.Expr {
+ if p.trace {
+ defer un(trace(p, "Expression"))
+ }
+
+ return p.parseBinaryExpr(nil, token.LowestPrec+1)
+}
+
+func (p *parser) parseRhs() ast.Expr {
+ old := p.inRhs
+ p.inRhs = true
+ x := p.parseExpr()
+ p.inRhs = old
+ return x
+}
+
+// ----------------------------------------------------------------------------
+// Statements
+
+// Parsing modes for parseSimpleStmt.
+const (
+ basic = iota
+ labelOk
+ rangeOk
+)
+
+// parseSimpleStmt returns true as 2nd result if it parsed the assignment
+// of a range clause (with mode == rangeOk). The returned statement is an
+// assignment with a right-hand side that is a single unary expression of
+// the form "range x". No guarantees are given for the left-hand side.
+func (p *parser) parseSimpleStmt(mode int) (ast.Stmt, bool) {
+ if p.trace {
+ defer un(trace(p, "SimpleStmt"))
+ }
+
+ x := p.parseList(false)
+
+ switch p.tok {
+ case
+ token.DEFINE, token.ASSIGN, token.ADD_ASSIGN,
+ token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
+ token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN,
+ token.XOR_ASSIGN, token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN:
+ // assignment statement, possibly part of a range clause
+ pos, tok := p.pos, p.tok
+ p.next()
+ var y []ast.Expr
+ isRange := false
+ if mode == rangeOk && p.tok == token.RANGE && (tok == token.DEFINE || tok == token.ASSIGN) {
+ pos := p.pos
+ p.next()
+ y = []ast.Expr{&ast.UnaryExpr{OpPos: pos, Op: token.RANGE, X: p.parseRhs()}}
+ isRange = true
+ } else {
+ y = p.parseList(true)
+ }
+ return &ast.AssignStmt{Lhs: x, TokPos: pos, Tok: tok, Rhs: y}, isRange
+ }
+
+ if len(x) > 1 {
+ p.errorExpected(x[0].Pos(), "1 expression")
+ // continue with first expression
+ }
+
+ switch p.tok {
+ case token.COLON:
+ // labeled statement
+ colon := p.pos
+ p.next()
+ if label, isIdent := x[0].(*ast.Ident); mode == labelOk && isIdent {
+ // Go spec: The scope of a label is the body of the function
+ // in which it is declared and excludes the body of any nested
+ // function.
+ stmt := &ast.LabeledStmt{Label: label, Colon: colon, Stmt: p.parseStmt()}
+ return stmt, false
+ }
+ // The label declaration typically starts at x[0].Pos(), but the label
+ // declaration may be erroneous due to a token after that position (and
+ // before the ':'). If SpuriousErrors is not set, the (only) error
+ // reported for the line is the illegal label error instead of the token
+ // before the ':' that caused the problem. Thus, use the (latest) colon
+ // position for error reporting.
+ p.error(colon, "illegal label declaration")
+ return &ast.BadStmt{From: x[0].Pos(), To: colon + 1}, false
+
+ case token.ARROW:
+ // send statement
+ arrow := p.pos
+ p.next()
+ y := p.parseRhs()
+ return &ast.SendStmt{Chan: x[0], Arrow: arrow, Value: y}, false
+
+ case token.INC, token.DEC:
+ // increment or decrement
+ s := &ast.IncDecStmt{X: x[0], TokPos: p.pos, Tok: p.tok}
+ p.next()
+ return s, false
+ }
+
+ // expression
+ return &ast.ExprStmt{X: x[0]}, false
+}
+
+func (p *parser) parseCallExpr(callType string) *ast.CallExpr {
+ x := p.parseRhs() // could be a conversion: (some type)(x)
+ if t := unparen(x); t != x {
+ p.error(x.Pos(), fmt.Sprintf("expression in %s must not be parenthesized", callType))
+ x = t
+ }
+ if call, isCall := x.(*ast.CallExpr); isCall {
+ return call
+ }
+ if _, isBad := x.(*ast.BadExpr); !isBad {
+ // only report error if it's a new one
+ p.error(p.safePos(x.End()), fmt.Sprintf("expression in %s must be function call", callType))
+ }
+ return nil
+}
+
+func (p *parser) parseGoStmt() ast.Stmt {
+ if p.trace {
+ defer un(trace(p, "GoStmt"))
+ }
+
+ pos := p.expect(token.GO)
+ call := p.parseCallExpr("go")
+ p.expectSemi()
+ if call == nil {
+ return &ast.BadStmt{From: pos, To: pos + 2} // len("go")
+ }
+
+ return &ast.GoStmt{Go: pos, Call: call}
+}
+
+func (p *parser) parseDeferStmt() ast.Stmt {
+ if p.trace {
+ defer un(trace(p, "DeferStmt"))
+ }
+
+ pos := p.expect(token.DEFER)
+ call := p.parseCallExpr("defer")
+ p.expectSemi()
+ if call == nil {
+ return &ast.BadStmt{From: pos, To: pos + 5} // len("defer")
+ }
+
+ return &ast.DeferStmt{Defer: pos, Call: call}
+}
+
+func (p *parser) parseReturnStmt() *ast.ReturnStmt {
+ if p.trace {
+ defer un(trace(p, "ReturnStmt"))
+ }
+
+ pos := p.pos
+ p.expect(token.RETURN)
+ var x []ast.Expr
+ if p.tok != token.SEMICOLON && p.tok != token.RBRACE {
+ x = p.parseList(true)
+ }
+ p.expectSemi()
+
+ return &ast.ReturnStmt{Return: pos, Results: x}
+}
+
+func (p *parser) parseBranchStmt(tok token.Token) *ast.BranchStmt {
+ if p.trace {
+ defer un(trace(p, "BranchStmt"))
+ }
+
+ pos := p.expect(tok)
+ var label *ast.Ident
+ if tok != token.FALLTHROUGH && p.tok == token.IDENT {
+ label = p.parseIdent()
+ }
+ p.expectSemi()
+
+ return &ast.BranchStmt{TokPos: pos, Tok: tok, Label: label}
+}
+
+func (p *parser) makeExpr(s ast.Stmt, want string) ast.Expr {
+ if s == nil {
+ return nil
+ }
+ if es, isExpr := s.(*ast.ExprStmt); isExpr {
+ return es.X
+ }
+ found := "simple statement"
+ if _, isAss := s.(*ast.AssignStmt); isAss {
+ found = "assignment"
+ }
+ p.error(s.Pos(), fmt.Sprintf("expected %s, found %s (missing parentheses around composite literal?)", want, found))
+ return &ast.BadExpr{From: s.Pos(), To: p.safePos(s.End())}
+}
+
+// parseIfHeader is an adjusted version of parser.header
+// in cmd/compile/internal/syntax/parser.go, which has
+// been tuned for better error handling.
+func (p *parser) parseIfHeader() (init ast.Stmt, cond ast.Expr) {
+ if p.tok == token.LBRACE {
+ p.error(p.pos, "missing condition in if statement")
+ cond = &ast.BadExpr{From: p.pos, To: p.pos}
+ return
+ }
+ // p.tok != token.LBRACE
+
+ prevLev := p.exprLev
+ p.exprLev = -1
+
+ if p.tok != token.SEMICOLON {
+ // accept potential variable declaration but complain
+ if p.tok == token.VAR {
+ p.next()
+ p.error(p.pos, "var declaration not allowed in if initializer")
+ }
+ init, _ = p.parseSimpleStmt(basic)
+ }
+
+ var condStmt ast.Stmt
+ var semi struct {
+ pos token.Pos
+ lit string // ";" or "\n"; valid if pos.IsValid()
+ }
+ if p.tok != token.LBRACE {
+ if p.tok == token.SEMICOLON {
+ semi.pos = p.pos
+ semi.lit = p.lit
+ p.next()
+ } else {
+ p.expect(token.SEMICOLON)
+ }
+ if p.tok != token.LBRACE {
+ condStmt, _ = p.parseSimpleStmt(basic)
+ }
+ } else {
+ condStmt = init
+ init = nil
+ }
+
+ if condStmt != nil {
+ cond = p.makeExpr(condStmt, "boolean expression")
+ } else if semi.pos.IsValid() {
+ if semi.lit == "\n" {
+ p.error(semi.pos, "unexpected newline, expecting { after if clause")
+ } else {
+ p.error(semi.pos, "missing condition in if statement")
+ }
+ }
+
+ // make sure we have a valid AST
+ if cond == nil {
+ cond = &ast.BadExpr{From: p.pos, To: p.pos}
+ }
+
+ p.exprLev = prevLev
+ return
+}
+
+func (p *parser) parseIfStmt() *ast.IfStmt {
+ defer decNestLev(incNestLev(p))
+
+ if p.trace {
+ defer un(trace(p, "IfStmt"))
+ }
+
+ pos := p.expect(token.IF)
+
+ init, cond := p.parseIfHeader()
+ body := p.parseBlockStmt()
+
+ var else_ ast.Stmt
+ if p.tok == token.ELSE {
+ p.next()
+ switch p.tok {
+ case token.IF:
+ else_ = p.parseIfStmt()
+ case token.LBRACE:
+ else_ = p.parseBlockStmt()
+ p.expectSemi()
+ default:
+ p.errorExpected(p.pos, "if statement or block")
+ else_ = &ast.BadStmt{From: p.pos, To: p.pos}
+ }
+ } else {
+ p.expectSemi()
+ }
+
+ return &ast.IfStmt{If: pos, Init: init, Cond: cond, Body: body, Else: else_}
+}
+
+func (p *parser) parseCaseClause() *ast.CaseClause {
+ if p.trace {
+ defer un(trace(p, "CaseClause"))
+ }
+
+ pos := p.pos
+ var list []ast.Expr
+ if p.tok == token.CASE {
+ p.next()
+ list = p.parseList(true)
+ } else {
+ p.expect(token.DEFAULT)
+ }
+
+ colon := p.expect(token.COLON)
+ body := p.parseStmtList()
+
+ return &ast.CaseClause{Case: pos, List: list, Colon: colon, Body: body}
+}
+
+func isTypeSwitchAssert(x ast.Expr) bool {
+ a, ok := x.(*ast.TypeAssertExpr)
+ return ok && a.Type == nil
+}
+
+func (p *parser) isTypeSwitchGuard(s ast.Stmt) bool {
+ switch t := s.(type) {
+ case *ast.ExprStmt:
+ // x.(type)
+ return isTypeSwitchAssert(t.X)
+ case *ast.AssignStmt:
+ // v := x.(type)
+ if len(t.Lhs) == 1 && len(t.Rhs) == 1 && isTypeSwitchAssert(t.Rhs[0]) {
+ switch t.Tok {
+ case token.ASSIGN:
+ // permit v = x.(type) but complain
+ p.error(t.TokPos, "expected ':=', found '='")
+ fallthrough
+ case token.DEFINE:
+ return true
+ }
+ }
+ }
+ return false
+}
+
+func (p *parser) parseSwitchStmt() ast.Stmt {
+ if p.trace {
+ defer un(trace(p, "SwitchStmt"))
+ }
+
+ pos := p.expect(token.SWITCH)
+
+ var s1, s2 ast.Stmt
+ if p.tok != token.LBRACE {
+ prevLev := p.exprLev
+ p.exprLev = -1
+ if p.tok != token.SEMICOLON {
+ s2, _ = p.parseSimpleStmt(basic)
+ }
+ if p.tok == token.SEMICOLON {
+ p.next()
+ s1 = s2
+ s2 = nil
+ if p.tok != token.LBRACE {
+ // A TypeSwitchGuard may declare a variable in addition
+ // to the variable declared in the initial SimpleStmt.
+ // Introduce extra scope to avoid redeclaration errors:
+ //
+ // switch t := 0; t := x.(T) { ... }
+ //
+ // (this code is not valid Go because the first t
+ // cannot be accessed and thus is never used, the extra
+ // scope is needed for the correct error message).
+ //
+ // If we don't have a type switch, s2 must be an expression.
+ // Having the extra nested but empty scope won't affect it.
+ s2, _ = p.parseSimpleStmt(basic)
+ }
+ }
+ p.exprLev = prevLev
+ }
+
+ typeSwitch := p.isTypeSwitchGuard(s2)
+ lbrace := p.expect(token.LBRACE)
+ var list []ast.Stmt
+ for p.tok == token.CASE || p.tok == token.DEFAULT {
+ list = append(list, p.parseCaseClause())
+ }
+ rbrace := p.expect(token.RBRACE)
+ p.expectSemi()
+ body := &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
+
+ if typeSwitch {
+ return &ast.TypeSwitchStmt{Switch: pos, Init: s1, Assign: s2, Body: body}
+ }
+
+ return &ast.SwitchStmt{Switch: pos, Init: s1, Tag: p.makeExpr(s2, "switch expression"), Body: body}
+}
+
+func (p *parser) parseCommClause() *ast.CommClause {
+ if p.trace {
+ defer un(trace(p, "CommClause"))
+ }
+
+ pos := p.pos
+ var comm ast.Stmt
+ if p.tok == token.CASE {
+ p.next()
+ lhs := p.parseList(false)
+ if p.tok == token.ARROW {
+ // SendStmt
+ if len(lhs) > 1 {
+ p.errorExpected(lhs[0].Pos(), "1 expression")
+ // continue with first expression
+ }
+ arrow := p.pos
+ p.next()
+ rhs := p.parseRhs()
+ comm = &ast.SendStmt{Chan: lhs[0], Arrow: arrow, Value: rhs}
+ } else {
+ // RecvStmt
+ if tok := p.tok; tok == token.ASSIGN || tok == token.DEFINE {
+ // RecvStmt with assignment
+ if len(lhs) > 2 {
+ p.errorExpected(lhs[0].Pos(), "1 or 2 expressions")
+ // continue with first two expressions
+ lhs = lhs[0:2]
+ }
+ pos := p.pos
+ p.next()
+ rhs := p.parseRhs()
+ comm = &ast.AssignStmt{Lhs: lhs, TokPos: pos, Tok: tok, Rhs: []ast.Expr{rhs}}
+ } else {
+ // lhs must be single receive operation
+ if len(lhs) > 1 {
+ p.errorExpected(lhs[0].Pos(), "1 expression")
+ // continue with first expression
+ }
+ comm = &ast.ExprStmt{X: lhs[0]}
+ }
+ }
+ } else {
+ p.expect(token.DEFAULT)
+ }
+
+ colon := p.expect(token.COLON)
+ body := p.parseStmtList()
+
+ return &ast.CommClause{Case: pos, Comm: comm, Colon: colon, Body: body}
+}
+
+func (p *parser) parseSelectStmt() *ast.SelectStmt {
+ if p.trace {
+ defer un(trace(p, "SelectStmt"))
+ }
+
+ pos := p.expect(token.SELECT)
+ lbrace := p.expect(token.LBRACE)
+ var list []ast.Stmt
+ for p.tok == token.CASE || p.tok == token.DEFAULT {
+ list = append(list, p.parseCommClause())
+ }
+ rbrace := p.expect(token.RBRACE)
+ p.expectSemi()
+ body := &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
+
+ return &ast.SelectStmt{Select: pos, Body: body}
+}
+
+func (p *parser) parseForStmt() ast.Stmt {
+ if p.trace {
+ defer un(trace(p, "ForStmt"))
+ }
+
+ pos := p.expect(token.FOR)
+
+ var s1, s2, s3 ast.Stmt
+ var isRange bool
+ if p.tok != token.LBRACE {
+ prevLev := p.exprLev
+ p.exprLev = -1
+ if p.tok != token.SEMICOLON {
+ if p.tok == token.RANGE {
+ // "for range x" (nil lhs in assignment)
+ pos := p.pos
+ p.next()
+ y := []ast.Expr{&ast.UnaryExpr{OpPos: pos, Op: token.RANGE, X: p.parseRhs()}}
+ s2 = &ast.AssignStmt{Rhs: y}
+ isRange = true
+ } else {
+ s2, isRange = p.parseSimpleStmt(rangeOk)
+ }
+ }
+ if !isRange && p.tok == token.SEMICOLON {
+ p.next()
+ s1 = s2
+ s2 = nil
+ if p.tok != token.SEMICOLON {
+ s2, _ = p.parseSimpleStmt(basic)
+ }
+ p.expectSemi()
+ if p.tok != token.LBRACE {
+ s3, _ = p.parseSimpleStmt(basic)
+ }
+ }
+ p.exprLev = prevLev
+ }
+
+ body := p.parseBlockStmt()
+ p.expectSemi()
+
+ if isRange {
+ as := s2.(*ast.AssignStmt)
+ // check lhs
+ var key, value ast.Expr
+ switch len(as.Lhs) {
+ case 0:
+ // nothing to do
+ case 1:
+ key = as.Lhs[0]
+ case 2:
+ key, value = as.Lhs[0], as.Lhs[1]
+ default:
+ p.errorExpected(as.Lhs[len(as.Lhs)-1].Pos(), "at most 2 expressions")
+ return &ast.BadStmt{From: pos, To: p.safePos(body.End())}
+ }
+ // parseSimpleStmt returned a right-hand side that
+ // is a single unary expression of the form "range x"
+ x := as.Rhs[0].(*ast.UnaryExpr).X
+ return &ast.RangeStmt{
+ For: pos,
+ Key: key,
+ Value: value,
+ TokPos: as.TokPos,
+ Tok: as.Tok,
+ Range: as.Rhs[0].Pos(),
+ X: x,
+ Body: body,
+ }
+ }
+
+ // regular for statement
+ return &ast.ForStmt{
+ For: pos,
+ Init: s1,
+ Cond: p.makeExpr(s2, "boolean or range expression"),
+ Post: s3,
+ Body: body,
+ }
+}
+
+func (p *parser) parseStmt() (s ast.Stmt) {
+ defer decNestLev(incNestLev(p))
+
+ if p.trace {
+ defer un(trace(p, "Statement"))
+ }
+
+ switch p.tok {
+ case token.CONST, token.TYPE, token.VAR:
+ s = &ast.DeclStmt{Decl: p.parseDecl(stmtStart)}
+ case
+ // tokens that may start an expression
+ token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING, token.FUNC, token.LPAREN, // operands
+ token.LBRACK, token.STRUCT, token.MAP, token.CHAN, token.INTERFACE, // composite types
+ token.ADD, token.SUB, token.MUL, token.AND, token.XOR, token.ARROW, token.NOT: // unary operators
+ s, _ = p.parseSimpleStmt(labelOk)
+ // because of the required look-ahead, labeled statements are
+ // parsed by parseSimpleStmt - don't expect a semicolon after
+ // them
+ if _, isLabeledStmt := s.(*ast.LabeledStmt); !isLabeledStmt {
+ p.expectSemi()
+ }
+ case token.GO:
+ s = p.parseGoStmt()
+ case token.DEFER:
+ s = p.parseDeferStmt()
+ case token.RETURN:
+ s = p.parseReturnStmt()
+ case token.BREAK, token.CONTINUE, token.GOTO, token.FALLTHROUGH:
+ s = p.parseBranchStmt(p.tok)
+ case token.LBRACE:
+ s = p.parseBlockStmt()
+ p.expectSemi()
+ case token.IF:
+ s = p.parseIfStmt()
+ case token.SWITCH:
+ s = p.parseSwitchStmt()
+ case token.SELECT:
+ s = p.parseSelectStmt()
+ case token.FOR:
+ s = p.parseForStmt()
+ case token.SEMICOLON:
+ // Is it ever possible to have an implicit semicolon
+ // producing an empty statement in a valid program?
+ // (handle correctly anyway)
+ s = &ast.EmptyStmt{Semicolon: p.pos, Implicit: p.lit == "\n"}
+ p.next()
+ case token.RBRACE:
+ // a semicolon may be omitted before a closing "}"
+ s = &ast.EmptyStmt{Semicolon: p.pos, Implicit: true}
+ default:
+ // no statement found
+ pos := p.pos
+ p.errorExpected(pos, "statement")
+ p.advance(stmtStart)
+ s = &ast.BadStmt{From: pos, To: p.pos}
+ }
+
+ return
+}
+
+// ----------------------------------------------------------------------------
+// Declarations
+
+type parseSpecFunction func(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec
+
+func (p *parser) parseImportSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.Spec {
+ if p.trace {
+ defer un(trace(p, "ImportSpec"))
+ }
+
+ var ident *ast.Ident
+ switch p.tok {
+ case token.IDENT:
+ ident = p.parseIdent()
+ case token.PERIOD:
+ ident = &ast.Ident{NamePos: p.pos, Name: "."}
+ p.next()
+ }
+
+ pos := p.pos
+ var path string
+ if p.tok == token.STRING {
+ path = p.lit
+ p.next()
+ } else if p.tok.IsLiteral() {
+ p.error(pos, "import path must be a string")
+ p.next()
+ } else {
+ p.error(pos, "missing import path")
+ p.advance(exprEnd)
+ }
+ comment := p.expectSemi()
+
+ // collect imports
+ spec := &ast.ImportSpec{
+ Doc: doc,
+ Name: ident,
+ Path: &ast.BasicLit{ValuePos: pos, Kind: token.STRING, Value: path},
+ Comment: comment,
+ }
+ p.imports = append(p.imports, spec)
+
+ return spec
+}
+
+func (p *parser) parseValueSpec(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec {
+ if p.trace {
+ defer un(trace(p, keyword.String()+"Spec"))
+ }
+
+ idents := p.parseIdentList()
+ var typ ast.Expr
+ var values []ast.Expr
+ switch keyword {
+ case token.CONST:
+ // always permit optional type and initialization for more tolerant parsing
+ if p.tok != token.EOF && p.tok != token.SEMICOLON && p.tok != token.RPAREN {
+ typ = p.tryIdentOrType()
+ if p.tok == token.ASSIGN {
+ p.next()
+ values = p.parseList(true)
+ }
+ }
+ case token.VAR:
+ if p.tok != token.ASSIGN {
+ typ = p.parseType()
+ }
+ if p.tok == token.ASSIGN {
+ p.next()
+ values = p.parseList(true)
+ }
+ default:
+ panic("unreachable")
+ }
+ comment := p.expectSemi()
+
+ spec := &ast.ValueSpec{
+ Doc: doc,
+ Names: idents,
+ Type: typ,
+ Values: values,
+ Comment: comment,
+ }
+ return spec
+}
+
+func (p *parser) parseGenericType(spec *ast.TypeSpec, openPos token.Pos, name0 *ast.Ident, typ0 ast.Expr) {
+ if p.trace {
+ defer un(trace(p, "parseGenericType"))
+ }
+
+ list := p.parseParameterList(name0, typ0, token.RBRACK)
+ closePos := p.expect(token.RBRACK)
+ spec.TypeParams = &ast.FieldList{Opening: openPos, List: list, Closing: closePos}
+ // Let the type checker decide whether to accept type parameters on aliases:
+ // see issue #46477.
+ if p.tok == token.ASSIGN {
+ // type alias
+ spec.Assign = p.pos
+ p.next()
+ }
+ spec.Type = p.parseType()
+}
+
+func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.Spec {
+ if p.trace {
+ defer un(trace(p, "TypeSpec"))
+ }
+
+ name := p.parseIdent()
+ spec := &ast.TypeSpec{Doc: doc, Name: name}
+
+ if p.tok == token.LBRACK {
+ // spec.Name "[" ...
+ // array/slice type or type parameter list
+ lbrack := p.pos
+ p.next()
+ if p.tok == token.IDENT {
+ // We may have an array type or a type parameter list.
+ // In either case we expect an expression x (which may
+ // just be a name, or a more complex expression) which
+ // we can analyze further.
+ //
+ // A type parameter list may have a type bound starting
+ // with a "[" as in: P []E. In that case, simply parsing
+ // an expression would lead to an error: P[] is invalid.
+ // But since index or slice expressions are never constant
+ // and thus invalid array length expressions, if the name
+ // is followed by "[" it must be the start of an array or
+ // slice constraint. Only if we don't see a "[" do we
+ // need to parse a full expression. Notably, name <- x
+ // is not a concern because name <- x is a statement and
+ // not an expression.
+ var x ast.Expr = p.parseIdent()
+ if p.tok != token.LBRACK {
+ // To parse the expression starting with name, expand
+ // the call sequence we would get by passing in name
+ // to parser.expr, and pass in name to parsePrimaryExpr.
+ p.exprLev++
+ lhs := p.parsePrimaryExpr(x)
+ x = p.parseBinaryExpr(lhs, token.LowestPrec+1)
+ p.exprLev--
+ }
+ // Analyze expression x. If we can split x into a type parameter
+ // name, possibly followed by a type parameter type, we consider
+ // this the start of a type parameter list, with some caveats:
+ // a single name followed by "]" tilts the decision towards an
+ // array declaration; a type parameter type that could also be
+ // an ordinary expression but which is followed by a comma tilts
+ // the decision towards a type parameter list.
+ if pname, ptype := extractName(x, p.tok == token.COMMA); pname != nil && (ptype != nil || p.tok != token.RBRACK) {
+ // spec.Name "[" pname ...
+ // spec.Name "[" pname ptype ...
+ // spec.Name "[" pname ptype "," ...
+ p.parseGenericType(spec, lbrack, pname, ptype) // ptype may be nil
+ } else {
+ // spec.Name "[" pname "]" ...
+ // spec.Name "[" x ...
+ spec.Type = p.parseArrayType(lbrack, x)
+ }
+ } else {
+ // array type
+ spec.Type = p.parseArrayType(lbrack, nil)
+ }
+ } else {
+ // no type parameters
+ if p.tok == token.ASSIGN {
+ // type alias
+ spec.Assign = p.pos
+ p.next()
+ }
+ spec.Type = p.parseType()
+ }
+
+ spec.Comment = p.expectSemi()
+
+ return spec
+}
+
+// extractName splits the expression x into (name, expr) if syntactically
+// x can be written as name expr. The split only happens if expr is a type
+// element (per the isTypeElem predicate) or if force is set.
+// If x is just a name, the result is (name, nil). If the split succeeds,
+// the result is (name, expr). Otherwise the result is (nil, x).
+// Examples:
+//
+// x force name expr
+// ------------------------------------
+// P*[]int T/F P *[]int
+// P*E T P *E
+// P*E F nil P*E
+// P([]int) T/F P []int
+// P(E) T P E
+// P(E) F nil P(E)
+// P*E|F|~G T/F P *E|F|~G
+// P*E|F|G T P *E|F|G
+// P*E|F|G F nil P*E|F|G
+func extractName(x ast.Expr, force bool) (*ast.Ident, ast.Expr) {
+ switch x := x.(type) {
+ case *ast.Ident:
+ return x, nil
+ case *ast.BinaryExpr:
+ switch x.Op {
+ case token.MUL:
+ if name, _ := x.X.(*ast.Ident); name != nil && (force || isTypeElem(x.Y)) {
+ // x = name *x.Y
+ return name, &ast.StarExpr{Star: x.OpPos, X: x.Y}
+ }
+ case token.OR:
+ if name, lhs := extractName(x.X, force || isTypeElem(x.Y)); name != nil && lhs != nil {
+ // x = name lhs|x.Y
+ op := *x
+ op.X = lhs
+ return name, &op
+ }
+ }
+ case *ast.CallExpr:
+ if name, _ := x.Fun.(*ast.Ident); name != nil {
+ if len(x.Args) == 1 && x.Ellipsis == token.NoPos && (force || isTypeElem(x.Args[0])) {
+ // x = name "(" x.ArgList[0] ")"
+ return name, x.Args[0]
+ }
+ }
+ }
+ return nil, x
+}
+
+// isTypeElem reports whether x is a (possibly parenthesized) type element expression.
+// The result is false if x could be a type element OR an ordinary (value) expression.
+func isTypeElem(x ast.Expr) bool {
+ switch x := x.(type) {
+ case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType:
+ return true
+ case *ast.BinaryExpr:
+ return isTypeElem(x.X) || isTypeElem(x.Y)
+ case *ast.UnaryExpr:
+ return x.Op == token.TILDE
+ case *ast.ParenExpr:
+ return isTypeElem(x.X)
+ }
+ return false
+}
+
+func (p *parser) parseGenDecl(keyword token.Token, f parseSpecFunction) *ast.GenDecl {
+ if p.trace {
+ defer un(trace(p, "GenDecl("+keyword.String()+")"))
+ }
+
+ doc := p.leadComment
+ pos := p.expect(keyword)
+ var lparen, rparen token.Pos
+ var list []ast.Spec
+ if p.tok == token.LPAREN {
+ lparen = p.pos
+ p.next()
+ for iota := 0; p.tok != token.RPAREN && p.tok != token.EOF; iota++ {
+ list = append(list, f(p.leadComment, keyword, iota))
+ }
+ rparen = p.expect(token.RPAREN)
+ p.expectSemi()
+ } else {
+ list = append(list, f(nil, keyword, 0))
+ }
+
+ return &ast.GenDecl{
+ Doc: doc,
+ TokPos: pos,
+ Tok: keyword,
+ Lparen: lparen,
+ Specs: list,
+ Rparen: rparen,
+ }
+}
+
+func (p *parser) parseFuncDecl() *ast.FuncDecl {
+ if p.trace {
+ defer un(trace(p, "FunctionDecl"))
+ }
+
+ doc := p.leadComment
+ pos := p.expect(token.FUNC)
+
+ var recv *ast.FieldList
+ if p.tok == token.LPAREN {
+ _, recv = p.parseParameters(false)
+ }
+
+ ident := p.parseIdent()
+
+ tparams, params := p.parseParameters(true)
+ if recv != nil && tparams != nil {
+ // Method declarations do not have type parameters. We parse them for a
+ // better error message and improved error recovery.
+ p.error(tparams.Opening, "method must have no type parameters")
+ tparams = nil
+ }
+ results := p.parseResult()
+
+ var body *ast.BlockStmt
+ switch p.tok {
+ case token.LBRACE:
+ body = p.parseBody()
+ p.expectSemi()
+ case token.SEMICOLON:
+ p.next()
+ if p.tok == token.LBRACE {
+ // opening { of function declaration on next line
+ p.error(p.pos, "unexpected semicolon or newline before {")
+ body = p.parseBody()
+ p.expectSemi()
+ }
+ default:
+ p.expectSemi()
+ }
+
+ decl := &ast.FuncDecl{
+ Doc: doc,
+ Recv: recv,
+ Name: ident,
+ Type: &ast.FuncType{
+ Func: pos,
+ TypeParams: tparams,
+ Params: params,
+ Results: results,
+ },
+ Body: body,
+ }
+ return decl
+}
+
+func (p *parser) parseDecl(sync map[token.Token]bool) ast.Decl {
+ if p.trace {
+ defer un(trace(p, "Declaration"))
+ }
+
+ var f parseSpecFunction
+ switch p.tok {
+ case token.IMPORT:
+ f = p.parseImportSpec
+
+ case token.CONST, token.VAR:
+ f = p.parseValueSpec
+
+ case token.TYPE:
+ f = p.parseTypeSpec
+
+ case token.FUNC:
+ return p.parseFuncDecl()
+
+ default:
+ pos := p.pos
+ p.errorExpected(pos, "declaration")
+ p.advance(sync)
+ return &ast.BadDecl{From: pos, To: p.pos}
+ }
+
+ return p.parseGenDecl(p.tok, f)
+}
+
+// ----------------------------------------------------------------------------
+// Source files
+
+func (p *parser) parseFile() *ast.File {
+ if p.trace {
+ defer un(trace(p, "File"))
+ }
+
+ // Don't bother parsing the rest if we had errors scanning the first token.
+ // Likely not a Go source file at all.
+ if p.errors.Len() != 0 {
+ return nil
+ }
+
+ // package clause
+ doc := p.leadComment
+ pos := p.expect(token.PACKAGE)
+ // Go spec: The package clause is not a declaration;
+ // the package name does not appear in any scope.
+ ident := p.parseIdent()
+ if ident.Name == "_" && p.mode&DeclarationErrors != 0 {
+ p.error(p.pos, "invalid package name _")
+ }
+ p.expectSemi()
+
+ // Don't bother parsing the rest if we had errors parsing the package clause.
+ // Likely not a Go source file at all.
+ if p.errors.Len() != 0 {
+ return nil
+ }
+
+ var decls []ast.Decl
+ if p.mode&PackageClauseOnly == 0 {
+ // import decls
+ for p.tok == token.IMPORT {
+ decls = append(decls, p.parseGenDecl(token.IMPORT, p.parseImportSpec))
+ }
+
+ if p.mode&ImportsOnly == 0 {
+ // rest of package body
+ prev := token.IMPORT
+ for p.tok != token.EOF {
+ // Continue to accept import declarations for error tolerance, but complain.
+ if p.tok == token.IMPORT && prev != token.IMPORT {
+ p.error(p.pos, "imports must appear before other declarations")
+ }
+ prev = p.tok
+
+ decls = append(decls, p.parseDecl(declStart))
+ }
+ }
+ }
+
+ f := &ast.File{
+ Doc: doc,
+ Package: pos,
+ Name: ident,
+ Decls: decls,
+ FileStart: token.Pos(p.file.Base()),
+ FileEnd: token.Pos(p.file.Base() + p.file.Size()),
+ Imports: p.imports,
+ Comments: p.comments,
+ GoVersion: p.goVersion,
+ }
+ var declErr func(token.Pos, string)
+ if p.mode&DeclarationErrors != 0 {
+ declErr = p.error
+ }
+ if p.mode&SkipObjectResolution == 0 {
+ resolveFile(f, p.file, declErr)
+ }
+
+ return f
+}
diff --git a/contrib/go/_std_1.20/src/go/parser/resolver.go b/contrib/go/_std_1.21/src/go/parser/resolver.go
index f8ff618eba..f8ff618eba 100644
--- a/contrib/go/_std_1.20/src/go/parser/resolver.go
+++ b/contrib/go/_std_1.21/src/go/parser/resolver.go
diff --git a/contrib/go/_std_1.21/src/go/parser/ya.make b/contrib/go/_std_1.21/src/go/parser/ya.make
new file mode 100644
index 0000000000..0c3e76597f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/parser/ya.make
@@ -0,0 +1,22 @@
+GO_LIBRARY()
+
+SRCS(
+ interface.go
+ parser.go
+ resolver.go
+)
+
+GO_TEST_SRCS(
+ error_test.go
+ parser_test.go
+ performance_test.go
+ resolver_test.go
+ short_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/go/printer/comment.go b/contrib/go/_std_1.21/src/go/printer/comment.go
index 9012714939..9012714939 100644
--- a/contrib/go/_std_1.20/src/go/printer/comment.go
+++ b/contrib/go/_std_1.21/src/go/printer/comment.go
diff --git a/contrib/go/_std_1.20/src/go/printer/gobuild.go b/contrib/go/_std_1.21/src/go/printer/gobuild.go
index f00492d077..f00492d077 100644
--- a/contrib/go/_std_1.20/src/go/printer/gobuild.go
+++ b/contrib/go/_std_1.21/src/go/printer/gobuild.go
diff --git a/contrib/go/_std_1.20/src/go/printer/nodes.go b/contrib/go/_std_1.21/src/go/printer/nodes.go
index e41ffc1958..e41ffc1958 100644
--- a/contrib/go/_std_1.20/src/go/printer/nodes.go
+++ b/contrib/go/_std_1.21/src/go/printer/nodes.go
diff --git a/contrib/go/_std_1.21/src/go/printer/printer.go b/contrib/go/_std_1.21/src/go/printer/printer.go
new file mode 100644
index 0000000000..5cf4e4bb5f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/printer/printer.go
@@ -0,0 +1,1436 @@
+// Copyright 2009 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 printer implements printing of AST nodes.
+package printer
+
+import (
+ "fmt"
+ "go/ast"
+ "go/build/constraint"
+ "go/token"
+ "io"
+ "os"
+ "strings"
+ "sync"
+ "text/tabwriter"
+ "unicode"
+)
+
+const (
+ maxNewlines = 2 // max. number of newlines between source text
+ debug = false // enable for debugging
+ infinity = 1 << 30
+)
+
+type whiteSpace byte
+
+const (
+ ignore = whiteSpace(0)
+ blank = whiteSpace(' ')
+ vtab = whiteSpace('\v')
+ newline = whiteSpace('\n')
+ formfeed = whiteSpace('\f')
+ indent = whiteSpace('>')
+ unindent = whiteSpace('<')
+)
+
+// A pmode value represents the current printer mode.
+type pmode int
+
+const (
+ noExtraBlank pmode = 1 << iota // disables extra blank after /*-style comment
+ noExtraLinebreak // disables extra line break after /*-style comment
+)
+
+type commentInfo struct {
+ cindex int // current comment index
+ comment *ast.CommentGroup // = printer.comments[cindex]; or nil
+ commentOffset int // = printer.posFor(printer.comments[cindex].List[0].Pos()).Offset; or infinity
+ commentNewline bool // true if the comment group contains newlines
+}
+
+type printer struct {
+ // Configuration (does not change after initialization)
+ Config
+ fset *token.FileSet
+
+ // Current state
+ output []byte // raw printer result
+ indent int // current indentation
+ level int // level == 0: outside composite literal; level > 0: inside composite literal
+ mode pmode // current printer mode
+ endAlignment bool // if set, terminate alignment immediately
+ impliedSemi bool // if set, a linebreak implies a semicolon
+ lastTok token.Token // last token printed (token.ILLEGAL if it's whitespace)
+ prevOpen token.Token // previous non-brace "open" token (, [, or token.ILLEGAL
+ wsbuf []whiteSpace // delayed white space
+ goBuild []int // start index of all //go:build comments in output
+ plusBuild []int // start index of all // +build comments in output
+
+ // Positions
+ // The out position differs from the pos position when the result
+ // formatting differs from the source formatting (in the amount of
+ // white space). If there's a difference and SourcePos is set in
+ // ConfigMode, //line directives are used in the output to restore
+ // original source positions for a reader.
+ pos token.Position // current position in AST (source) space
+ out token.Position // current position in output space
+ last token.Position // value of pos after calling writeString
+ linePtr *int // if set, record out.Line for the next token in *linePtr
+ sourcePosErr error // if non-nil, the first error emitting a //line directive
+
+ // The list of all source comments, in order of appearance.
+ comments []*ast.CommentGroup // may be nil
+ useNodeComments bool // if not set, ignore lead and line comments of nodes
+
+ // Information about p.comments[p.cindex]; set up by nextComment.
+ commentInfo
+
+ // Cache of already computed node sizes.
+ nodeSizes map[ast.Node]int
+
+ // Cache of most recently computed line position.
+ cachedPos token.Pos
+ cachedLine int // line corresponding to cachedPos
+}
+
+func (p *printer) internalError(msg ...any) {
+ if debug {
+ fmt.Print(p.pos.String() + ": ")
+ fmt.Println(msg...)
+ panic("go/printer")
+ }
+}
+
+// commentsHaveNewline reports whether a list of comments belonging to
+// an *ast.CommentGroup contains newlines. Because the position information
+// may only be partially correct, we also have to read the comment text.
+func (p *printer) commentsHaveNewline(list []*ast.Comment) bool {
+ // len(list) > 0
+ line := p.lineFor(list[0].Pos())
+ for i, c := range list {
+ if i > 0 && p.lineFor(list[i].Pos()) != line {
+ // not all comments on the same line
+ return true
+ }
+ if t := c.Text; len(t) >= 2 && (t[1] == '/' || strings.Contains(t, "\n")) {
+ return true
+ }
+ }
+ _ = line
+ return false
+}
+
+func (p *printer) nextComment() {
+ for p.cindex < len(p.comments) {
+ c := p.comments[p.cindex]
+ p.cindex++
+ if list := c.List; len(list) > 0 {
+ p.comment = c
+ p.commentOffset = p.posFor(list[0].Pos()).Offset
+ p.commentNewline = p.commentsHaveNewline(list)
+ return
+ }
+ // we should not reach here (correct ASTs don't have empty
+ // ast.CommentGroup nodes), but be conservative and try again
+ }
+ // no more comments
+ p.commentOffset = infinity
+}
+
+// commentBefore reports whether the current comment group occurs
+// before the next position in the source code and printing it does
+// not introduce implicit semicolons.
+func (p *printer) commentBefore(next token.Position) bool {
+ return p.commentOffset < next.Offset && (!p.impliedSemi || !p.commentNewline)
+}
+
+// commentSizeBefore returns the estimated size of the
+// comments on the same line before the next position.
+func (p *printer) commentSizeBefore(next token.Position) int {
+ // save/restore current p.commentInfo (p.nextComment() modifies it)
+ defer func(info commentInfo) {
+ p.commentInfo = info
+ }(p.commentInfo)
+
+ size := 0
+ for p.commentBefore(next) {
+ for _, c := range p.comment.List {
+ size += len(c.Text)
+ }
+ p.nextComment()
+ }
+ return size
+}
+
+// recordLine records the output line number for the next non-whitespace
+// token in *linePtr. It is used to compute an accurate line number for a
+// formatted construct, independent of pending (not yet emitted) whitespace
+// or comments.
+func (p *printer) recordLine(linePtr *int) {
+ p.linePtr = linePtr
+}
+
+// linesFrom returns the number of output lines between the current
+// output line and the line argument, ignoring any pending (not yet
+// emitted) whitespace or comments. It is used to compute an accurate
+// size (in number of lines) for a formatted construct.
+func (p *printer) linesFrom(line int) int {
+ return p.out.Line - line
+}
+
+func (p *printer) posFor(pos token.Pos) token.Position {
+ // not used frequently enough to cache entire token.Position
+ return p.fset.PositionFor(pos, false /* absolute position */)
+}
+
+func (p *printer) lineFor(pos token.Pos) int {
+ if pos != p.cachedPos {
+ p.cachedPos = pos
+ p.cachedLine = p.fset.PositionFor(pos, false /* absolute position */).Line
+ }
+ return p.cachedLine
+}
+
+// writeLineDirective writes a //line directive if necessary.
+func (p *printer) writeLineDirective(pos token.Position) {
+ if pos.IsValid() && (p.out.Line != pos.Line || p.out.Filename != pos.Filename) {
+ if strings.ContainsAny(pos.Filename, "\r\n") {
+ if p.sourcePosErr == nil {
+ p.sourcePosErr = fmt.Errorf("go/printer: source filename contains unexpected newline character: %q", pos.Filename)
+ }
+ return
+ }
+
+ p.output = append(p.output, tabwriter.Escape) // protect '\n' in //line from tabwriter interpretation
+ p.output = append(p.output, fmt.Sprintf("//line %s:%d\n", pos.Filename, pos.Line)...)
+ p.output = append(p.output, tabwriter.Escape)
+ // p.out must match the //line directive
+ p.out.Filename = pos.Filename
+ p.out.Line = pos.Line
+ }
+}
+
+// writeIndent writes indentation.
+func (p *printer) writeIndent() {
+ // use "hard" htabs - indentation columns
+ // must not be discarded by the tabwriter
+ n := p.Config.Indent + p.indent // include base indentation
+ for i := 0; i < n; i++ {
+ p.output = append(p.output, '\t')
+ }
+
+ // update positions
+ p.pos.Offset += n
+ p.pos.Column += n
+ p.out.Column += n
+}
+
+// writeByte writes ch n times to p.output and updates p.pos.
+// Only used to write formatting (white space) characters.
+func (p *printer) writeByte(ch byte, n int) {
+ if p.endAlignment {
+ // Ignore any alignment control character;
+ // and at the end of the line, break with
+ // a formfeed to indicate termination of
+ // existing columns.
+ switch ch {
+ case '\t', '\v':
+ ch = ' '
+ case '\n', '\f':
+ ch = '\f'
+ p.endAlignment = false
+ }
+ }
+
+ if p.out.Column == 1 {
+ // no need to write line directives before white space
+ p.writeIndent()
+ }
+
+ for i := 0; i < n; i++ {
+ p.output = append(p.output, ch)
+ }
+
+ // update positions
+ p.pos.Offset += n
+ if ch == '\n' || ch == '\f' {
+ p.pos.Line += n
+ p.out.Line += n
+ p.pos.Column = 1
+ p.out.Column = 1
+ return
+ }
+ p.pos.Column += n
+ p.out.Column += n
+}
+
+// writeString writes the string s to p.output and updates p.pos, p.out,
+// and p.last. If isLit is set, s is escaped w/ tabwriter.Escape characters
+// to protect s from being interpreted by the tabwriter.
+//
+// Note: writeString is only used to write Go tokens, literals, and
+// comments, all of which must be written literally. Thus, it is correct
+// to always set isLit = true. However, setting it explicitly only when
+// needed (i.e., when we don't know that s contains no tabs or line breaks)
+// avoids processing extra escape characters and reduces run time of the
+// printer benchmark by up to 10%.
+func (p *printer) writeString(pos token.Position, s string, isLit bool) {
+ if p.out.Column == 1 {
+ if p.Config.Mode&SourcePos != 0 {
+ p.writeLineDirective(pos)
+ }
+ p.writeIndent()
+ }
+
+ if pos.IsValid() {
+ // update p.pos (if pos is invalid, continue with existing p.pos)
+ // Note: Must do this after handling line beginnings because
+ // writeIndent updates p.pos if there's indentation, but p.pos
+ // is the position of s.
+ p.pos = pos
+ }
+
+ if isLit {
+ // Protect s such that is passes through the tabwriter
+ // unchanged. Note that valid Go programs cannot contain
+ // tabwriter.Escape bytes since they do not appear in legal
+ // UTF-8 sequences.
+ p.output = append(p.output, tabwriter.Escape)
+ }
+
+ if debug {
+ p.output = append(p.output, fmt.Sprintf("/*%s*/", pos)...) // do not update p.pos!
+ }
+ p.output = append(p.output, s...)
+
+ // update positions
+ nlines := 0
+ var li int // index of last newline; valid if nlines > 0
+ for i := 0; i < len(s); i++ {
+ // Raw string literals may contain any character except back quote (`).
+ if ch := s[i]; ch == '\n' || ch == '\f' {
+ // account for line break
+ nlines++
+ li = i
+ // A line break inside a literal will break whatever column
+ // formatting is in place; ignore any further alignment through
+ // the end of the line.
+ p.endAlignment = true
+ }
+ }
+ p.pos.Offset += len(s)
+ if nlines > 0 {
+ p.pos.Line += nlines
+ p.out.Line += nlines
+ c := len(s) - li
+ p.pos.Column = c
+ p.out.Column = c
+ } else {
+ p.pos.Column += len(s)
+ p.out.Column += len(s)
+ }
+
+ if isLit {
+ p.output = append(p.output, tabwriter.Escape)
+ }
+
+ p.last = p.pos
+}
+
+// writeCommentPrefix writes the whitespace before a comment.
+// If there is any pending whitespace, it consumes as much of
+// it as is likely to help position the comment nicely.
+// pos is the comment position, next the position of the item
+// after all pending comments, prev is the previous comment in
+// a group of comments (or nil), and tok is the next token.
+func (p *printer) writeCommentPrefix(pos, next token.Position, prev *ast.Comment, tok token.Token) {
+ if len(p.output) == 0 {
+ // the comment is the first item to be printed - don't write any whitespace
+ return
+ }
+
+ if pos.IsValid() && pos.Filename != p.last.Filename {
+ // comment in a different file - separate with newlines
+ p.writeByte('\f', maxNewlines)
+ return
+ }
+
+ if pos.Line == p.last.Line && (prev == nil || prev.Text[1] != '/') {
+ // comment on the same line as last item:
+ // separate with at least one separator
+ hasSep := false
+ if prev == nil {
+ // first comment of a comment group
+ j := 0
+ for i, ch := range p.wsbuf {
+ switch ch {
+ case blank:
+ // ignore any blanks before a comment
+ p.wsbuf[i] = ignore
+ continue
+ case vtab:
+ // respect existing tabs - important
+ // for proper formatting of commented structs
+ hasSep = true
+ continue
+ case indent:
+ // apply pending indentation
+ continue
+ }
+ j = i
+ break
+ }
+ p.writeWhitespace(j)
+ }
+ // make sure there is at least one separator
+ if !hasSep {
+ sep := byte('\t')
+ if pos.Line == next.Line {
+ // next item is on the same line as the comment
+ // (which must be a /*-style comment): separate
+ // with a blank instead of a tab
+ sep = ' '
+ }
+ p.writeByte(sep, 1)
+ }
+
+ } else {
+ // comment on a different line:
+ // separate with at least one line break
+ droppedLinebreak := false
+ j := 0
+ for i, ch := range p.wsbuf {
+ switch ch {
+ case blank, vtab:
+ // ignore any horizontal whitespace before line breaks
+ p.wsbuf[i] = ignore
+ continue
+ case indent:
+ // apply pending indentation
+ continue
+ case unindent:
+ // if this is not the last unindent, apply it
+ // as it is (likely) belonging to the last
+ // construct (e.g., a multi-line expression list)
+ // and is not part of closing a block
+ if i+1 < len(p.wsbuf) && p.wsbuf[i+1] == unindent {
+ continue
+ }
+ // if the next token is not a closing }, apply the unindent
+ // if it appears that the comment is aligned with the
+ // token; otherwise assume the unindent is part of a
+ // closing block and stop (this scenario appears with
+ // comments before a case label where the comments
+ // apply to the next case instead of the current one)
+ if tok != token.RBRACE && pos.Column == next.Column {
+ continue
+ }
+ case newline, formfeed:
+ p.wsbuf[i] = ignore
+ droppedLinebreak = prev == nil // record only if first comment of a group
+ }
+ j = i
+ break
+ }
+ p.writeWhitespace(j)
+
+ // determine number of linebreaks before the comment
+ n := 0
+ if pos.IsValid() && p.last.IsValid() {
+ n = pos.Line - p.last.Line
+ if n < 0 { // should never happen
+ n = 0
+ }
+ }
+
+ // at the package scope level only (p.indent == 0),
+ // add an extra newline if we dropped one before:
+ // this preserves a blank line before documentation
+ // comments at the package scope level (issue 2570)
+ if p.indent == 0 && droppedLinebreak {
+ n++
+ }
+
+ // make sure there is at least one line break
+ // if the previous comment was a line comment
+ if n == 0 && prev != nil && prev.Text[1] == '/' {
+ n = 1
+ }
+
+ if n > 0 {
+ // use formfeeds to break columns before a comment;
+ // this is analogous to using formfeeds to separate
+ // individual lines of /*-style comments
+ p.writeByte('\f', nlimit(n))
+ }
+ }
+}
+
+// Returns true if s contains only white space
+// (only tabs and blanks can appear in the printer's context).
+func isBlank(s string) bool {
+ for i := 0; i < len(s); i++ {
+ if s[i] > ' ' {
+ return false
+ }
+ }
+ return true
+}
+
+// commonPrefix returns the common prefix of a and b.
+func commonPrefix(a, b string) string {
+ i := 0
+ for i < len(a) && i < len(b) && a[i] == b[i] && (a[i] <= ' ' || a[i] == '*') {
+ i++
+ }
+ return a[0:i]
+}
+
+// trimRight returns s with trailing whitespace removed.
+func trimRight(s string) string {
+ return strings.TrimRightFunc(s, unicode.IsSpace)
+}
+
+// stripCommonPrefix removes a common prefix from /*-style comment lines (unless no
+// comment line is indented, all but the first line have some form of space prefix).
+// The prefix is computed using heuristics such that is likely that the comment
+// contents are nicely laid out after re-printing each line using the printer's
+// current indentation.
+func stripCommonPrefix(lines []string) {
+ if len(lines) <= 1 {
+ return // at most one line - nothing to do
+ }
+ // len(lines) > 1
+
+ // The heuristic in this function tries to handle a few
+ // common patterns of /*-style comments: Comments where
+ // the opening /* and closing */ are aligned and the
+ // rest of the comment text is aligned and indented with
+ // blanks or tabs, cases with a vertical "line of stars"
+ // on the left, and cases where the closing */ is on the
+ // same line as the last comment text.
+
+ // Compute maximum common white prefix of all but the first,
+ // last, and blank lines, and replace blank lines with empty
+ // lines (the first line starts with /* and has no prefix).
+ // In cases where only the first and last lines are not blank,
+ // such as two-line comments, or comments where all inner lines
+ // are blank, consider the last line for the prefix computation
+ // since otherwise the prefix would be empty.
+ //
+ // Note that the first and last line are never empty (they
+ // contain the opening /* and closing */ respectively) and
+ // thus they can be ignored by the blank line check.
+ prefix := ""
+ prefixSet := false
+ if len(lines) > 2 {
+ for i, line := range lines[1 : len(lines)-1] {
+ if isBlank(line) {
+ lines[1+i] = "" // range starts with lines[1]
+ } else {
+ if !prefixSet {
+ prefix = line
+ prefixSet = true
+ }
+ prefix = commonPrefix(prefix, line)
+ }
+
+ }
+ }
+ // If we don't have a prefix yet, consider the last line.
+ if !prefixSet {
+ line := lines[len(lines)-1]
+ prefix = commonPrefix(line, line)
+ }
+
+ /*
+ * Check for vertical "line of stars" and correct prefix accordingly.
+ */
+ lineOfStars := false
+ if p, _, ok := strings.Cut(prefix, "*"); ok {
+ // remove trailing blank from prefix so stars remain aligned
+ prefix = strings.TrimSuffix(p, " ")
+ lineOfStars = true
+ } else {
+ // No line of stars present.
+ // Determine the white space on the first line after the /*
+ // and before the beginning of the comment text, assume two
+ // blanks instead of the /* unless the first character after
+ // the /* is a tab. If the first comment line is empty but
+ // for the opening /*, assume up to 3 blanks or a tab. This
+ // whitespace may be found as suffix in the common prefix.
+ first := lines[0]
+ if isBlank(first[2:]) {
+ // no comment text on the first line:
+ // reduce prefix by up to 3 blanks or a tab
+ // if present - this keeps comment text indented
+ // relative to the /* and */'s if it was indented
+ // in the first place
+ i := len(prefix)
+ for n := 0; n < 3 && i > 0 && prefix[i-1] == ' '; n++ {
+ i--
+ }
+ if i == len(prefix) && i > 0 && prefix[i-1] == '\t' {
+ i--
+ }
+ prefix = prefix[0:i]
+ } else {
+ // comment text on the first line
+ suffix := make([]byte, len(first))
+ n := 2 // start after opening /*
+ for n < len(first) && first[n] <= ' ' {
+ suffix[n] = first[n]
+ n++
+ }
+ if n > 2 && suffix[2] == '\t' {
+ // assume the '\t' compensates for the /*
+ suffix = suffix[2:n]
+ } else {
+ // otherwise assume two blanks
+ suffix[0], suffix[1] = ' ', ' '
+ suffix = suffix[0:n]
+ }
+ // Shorten the computed common prefix by the length of
+ // suffix, if it is found as suffix of the prefix.
+ prefix = strings.TrimSuffix(prefix, string(suffix))
+ }
+ }
+
+ // Handle last line: If it only contains a closing */, align it
+ // with the opening /*, otherwise align the text with the other
+ // lines.
+ last := lines[len(lines)-1]
+ closing := "*/"
+ before, _, _ := strings.Cut(last, closing) // closing always present
+ if isBlank(before) {
+ // last line only contains closing */
+ if lineOfStars {
+ closing = " */" // add blank to align final star
+ }
+ lines[len(lines)-1] = prefix + closing
+ } else {
+ // last line contains more comment text - assume
+ // it is aligned like the other lines and include
+ // in prefix computation
+ prefix = commonPrefix(prefix, last)
+ }
+
+ // Remove the common prefix from all but the first and empty lines.
+ for i, line := range lines {
+ if i > 0 && line != "" {
+ lines[i] = line[len(prefix):]
+ }
+ }
+}
+
+func (p *printer) writeComment(comment *ast.Comment) {
+ text := comment.Text
+ pos := p.posFor(comment.Pos())
+
+ const linePrefix = "//line "
+ if strings.HasPrefix(text, linePrefix) && (!pos.IsValid() || pos.Column == 1) {
+ // Possibly a //-style line directive.
+ // Suspend indentation temporarily to keep line directive valid.
+ defer func(indent int) { p.indent = indent }(p.indent)
+ p.indent = 0
+ }
+
+ // shortcut common case of //-style comments
+ if text[1] == '/' {
+ if constraint.IsGoBuild(text) {
+ p.goBuild = append(p.goBuild, len(p.output))
+ } else if constraint.IsPlusBuild(text) {
+ p.plusBuild = append(p.plusBuild, len(p.output))
+ }
+ p.writeString(pos, trimRight(text), true)
+ return
+ }
+
+ // for /*-style comments, print line by line and let the
+ // write function take care of the proper indentation
+ lines := strings.Split(text, "\n")
+
+ // The comment started in the first column but is going
+ // to be indented. For an idempotent result, add indentation
+ // to all lines such that they look like they were indented
+ // before - this will make sure the common prefix computation
+ // is the same independent of how many times formatting is
+ // applied (was issue 1835).
+ if pos.IsValid() && pos.Column == 1 && p.indent > 0 {
+ for i, line := range lines[1:] {
+ lines[1+i] = " " + line
+ }
+ }
+
+ stripCommonPrefix(lines)
+
+ // write comment lines, separated by formfeed,
+ // without a line break after the last line
+ for i, line := range lines {
+ if i > 0 {
+ p.writeByte('\f', 1)
+ pos = p.pos
+ }
+ if len(line) > 0 {
+ p.writeString(pos, trimRight(line), true)
+ }
+ }
+}
+
+// writeCommentSuffix writes a line break after a comment if indicated
+// and processes any leftover indentation information. If a line break
+// is needed, the kind of break (newline vs formfeed) depends on the
+// pending whitespace. The writeCommentSuffix result indicates if a
+// newline was written or if a formfeed was dropped from the whitespace
+// buffer.
+func (p *printer) writeCommentSuffix(needsLinebreak bool) (wroteNewline, droppedFF bool) {
+ for i, ch := range p.wsbuf {
+ switch ch {
+ case blank, vtab:
+ // ignore trailing whitespace
+ p.wsbuf[i] = ignore
+ case indent, unindent:
+ // don't lose indentation information
+ case newline, formfeed:
+ // if we need a line break, keep exactly one
+ // but remember if we dropped any formfeeds
+ if needsLinebreak {
+ needsLinebreak = false
+ wroteNewline = true
+ } else {
+ if ch == formfeed {
+ droppedFF = true
+ }
+ p.wsbuf[i] = ignore
+ }
+ }
+ }
+ p.writeWhitespace(len(p.wsbuf))
+
+ // make sure we have a line break
+ if needsLinebreak {
+ p.writeByte('\n', 1)
+ wroteNewline = true
+ }
+
+ return
+}
+
+// containsLinebreak reports whether the whitespace buffer contains any line breaks.
+func (p *printer) containsLinebreak() bool {
+ for _, ch := range p.wsbuf {
+ if ch == newline || ch == formfeed {
+ return true
+ }
+ }
+ return false
+}
+
+// intersperseComments consumes all comments that appear before the next token
+// tok and prints it together with the buffered whitespace (i.e., the whitespace
+// that needs to be written before the next token). A heuristic is used to mix
+// the comments and whitespace. The intersperseComments result indicates if a
+// newline was written or if a formfeed was dropped from the whitespace buffer.
+func (p *printer) intersperseComments(next token.Position, tok token.Token) (wroteNewline, droppedFF bool) {
+ var last *ast.Comment
+ for p.commentBefore(next) {
+ list := p.comment.List
+ changed := false
+ if p.lastTok != token.IMPORT && // do not rewrite cgo's import "C" comments
+ p.posFor(p.comment.Pos()).Column == 1 &&
+ p.posFor(p.comment.End()+1) == next {
+ // Unindented comment abutting next token position:
+ // a top-level doc comment.
+ list = formatDocComment(list)
+ changed = true
+
+ if len(p.comment.List) > 0 && len(list) == 0 {
+ // The doc comment was removed entirely.
+ // Keep preceding whitespace.
+ p.writeCommentPrefix(p.posFor(p.comment.Pos()), next, last, tok)
+ // Change print state to continue at next.
+ p.pos = next
+ p.last = next
+ // There can't be any more comments.
+ p.nextComment()
+ return p.writeCommentSuffix(false)
+ }
+ }
+ for _, c := range list {
+ p.writeCommentPrefix(p.posFor(c.Pos()), next, last, tok)
+ p.writeComment(c)
+ last = c
+ }
+ // In case list was rewritten, change print state to where
+ // the original list would have ended.
+ if len(p.comment.List) > 0 && changed {
+ last = p.comment.List[len(p.comment.List)-1]
+ p.pos = p.posFor(last.End())
+ p.last = p.pos
+ }
+ p.nextComment()
+ }
+
+ if last != nil {
+ // If the last comment is a /*-style comment and the next item
+ // follows on the same line but is not a comma, and not a "closing"
+ // token immediately following its corresponding "opening" token,
+ // add an extra separator unless explicitly disabled. Use a blank
+ // as separator unless we have pending linebreaks, they are not
+ // disabled, and we are outside a composite literal, in which case
+ // we want a linebreak (issue 15137).
+ // TODO(gri) This has become overly complicated. We should be able
+ // to track whether we're inside an expression or statement and
+ // use that information to decide more directly.
+ needsLinebreak := false
+ if p.mode&noExtraBlank == 0 &&
+ last.Text[1] == '*' && p.lineFor(last.Pos()) == next.Line &&
+ tok != token.COMMA &&
+ (tok != token.RPAREN || p.prevOpen == token.LPAREN) &&
+ (tok != token.RBRACK || p.prevOpen == token.LBRACK) {
+ if p.containsLinebreak() && p.mode&noExtraLinebreak == 0 && p.level == 0 {
+ needsLinebreak = true
+ } else {
+ p.writeByte(' ', 1)
+ }
+ }
+ // Ensure that there is a line break after a //-style comment,
+ // before EOF, and before a closing '}' unless explicitly disabled.
+ if last.Text[1] == '/' ||
+ tok == token.EOF ||
+ tok == token.RBRACE && p.mode&noExtraLinebreak == 0 {
+ needsLinebreak = true
+ }
+ return p.writeCommentSuffix(needsLinebreak)
+ }
+
+ // no comment was written - we should never reach here since
+ // intersperseComments should not be called in that case
+ p.internalError("intersperseComments called without pending comments")
+ return
+}
+
+// writeWhitespace writes the first n whitespace entries.
+func (p *printer) writeWhitespace(n int) {
+ // write entries
+ for i := 0; i < n; i++ {
+ switch ch := p.wsbuf[i]; ch {
+ case ignore:
+ // ignore!
+ case indent:
+ p.indent++
+ case unindent:
+ p.indent--
+ if p.indent < 0 {
+ p.internalError("negative indentation:", p.indent)
+ p.indent = 0
+ }
+ case newline, formfeed:
+ // A line break immediately followed by a "correcting"
+ // unindent is swapped with the unindent - this permits
+ // proper label positioning. If a comment is between
+ // the line break and the label, the unindent is not
+ // part of the comment whitespace prefix and the comment
+ // will be positioned correctly indented.
+ if i+1 < n && p.wsbuf[i+1] == unindent {
+ // Use a formfeed to terminate the current section.
+ // Otherwise, a long label name on the next line leading
+ // to a wide column may increase the indentation column
+ // of lines before the label; effectively leading to wrong
+ // indentation.
+ p.wsbuf[i], p.wsbuf[i+1] = unindent, formfeed
+ i-- // do it again
+ continue
+ }
+ fallthrough
+ default:
+ p.writeByte(byte(ch), 1)
+ }
+ }
+
+ // shift remaining entries down
+ l := copy(p.wsbuf, p.wsbuf[n:])
+ p.wsbuf = p.wsbuf[:l]
+}
+
+// ----------------------------------------------------------------------------
+// Printing interface
+
+// nlimit limits n to maxNewlines.
+func nlimit(n int) int {
+ if n > maxNewlines {
+ n = maxNewlines
+ }
+ return n
+}
+
+func mayCombine(prev token.Token, next byte) (b bool) {
+ switch prev {
+ case token.INT:
+ b = next == '.' // 1.
+ case token.ADD:
+ b = next == '+' // ++
+ case token.SUB:
+ b = next == '-' // --
+ case token.QUO:
+ b = next == '*' // /*
+ case token.LSS:
+ b = next == '-' || next == '<' // <- or <<
+ case token.AND:
+ b = next == '&' || next == '^' // && or &^
+ }
+ return
+}
+
+func (p *printer) setPos(pos token.Pos) {
+ if pos.IsValid() {
+ p.pos = p.posFor(pos) // accurate position of next item
+ }
+}
+
+// print prints a list of "items" (roughly corresponding to syntactic
+// tokens, but also including whitespace and formatting information).
+// It is the only print function that should be called directly from
+// any of the AST printing functions in nodes.go.
+//
+// Whitespace is accumulated until a non-whitespace token appears. Any
+// comments that need to appear before that token are printed first,
+// taking into account the amount and structure of any pending white-
+// space for best comment placement. Then, any leftover whitespace is
+// printed, followed by the actual token.
+func (p *printer) print(args ...any) {
+ for _, arg := range args {
+ // information about the current arg
+ var data string
+ var isLit bool
+ var impliedSemi bool // value for p.impliedSemi after this arg
+
+ // record previous opening token, if any
+ switch p.lastTok {
+ case token.ILLEGAL:
+ // ignore (white space)
+ case token.LPAREN, token.LBRACK:
+ p.prevOpen = p.lastTok
+ default:
+ // other tokens followed any opening token
+ p.prevOpen = token.ILLEGAL
+ }
+
+ switch x := arg.(type) {
+ case pmode:
+ // toggle printer mode
+ p.mode ^= x
+ continue
+
+ case whiteSpace:
+ if x == ignore {
+ // don't add ignore's to the buffer; they
+ // may screw up "correcting" unindents (see
+ // LabeledStmt)
+ continue
+ }
+ i := len(p.wsbuf)
+ if i == cap(p.wsbuf) {
+ // Whitespace sequences are very short so this should
+ // never happen. Handle gracefully (but possibly with
+ // bad comment placement) if it does happen.
+ p.writeWhitespace(i)
+ i = 0
+ }
+ p.wsbuf = p.wsbuf[0 : i+1]
+ p.wsbuf[i] = x
+ if x == newline || x == formfeed {
+ // newlines affect the current state (p.impliedSemi)
+ // and not the state after printing arg (impliedSemi)
+ // because comments can be interspersed before the arg
+ // in this case
+ p.impliedSemi = false
+ }
+ p.lastTok = token.ILLEGAL
+ continue
+
+ case *ast.Ident:
+ data = x.Name
+ impliedSemi = true
+ p.lastTok = token.IDENT
+
+ case *ast.BasicLit:
+ data = x.Value
+ isLit = true
+ impliedSemi = true
+ p.lastTok = x.Kind
+
+ case token.Token:
+ s := x.String()
+ if mayCombine(p.lastTok, s[0]) {
+ // the previous and the current token must be
+ // separated by a blank otherwise they combine
+ // into a different incorrect token sequence
+ // (except for token.INT followed by a '.' this
+ // should never happen because it is taken care
+ // of via binary expression formatting)
+ if len(p.wsbuf) != 0 {
+ p.internalError("whitespace buffer not empty")
+ }
+ p.wsbuf = p.wsbuf[0:1]
+ p.wsbuf[0] = ' '
+ }
+ data = s
+ // some keywords followed by a newline imply a semicolon
+ switch x {
+ case token.BREAK, token.CONTINUE, token.FALLTHROUGH, token.RETURN,
+ token.INC, token.DEC, token.RPAREN, token.RBRACK, token.RBRACE:
+ impliedSemi = true
+ }
+ p.lastTok = x
+
+ case string:
+ // incorrect AST - print error message
+ data = x
+ isLit = true
+ impliedSemi = true
+ p.lastTok = token.STRING
+
+ default:
+ fmt.Fprintf(os.Stderr, "print: unsupported argument %v (%T)\n", arg, arg)
+ panic("go/printer type")
+ }
+ // data != ""
+
+ next := p.pos // estimated/accurate position of next item
+ wroteNewline, droppedFF := p.flush(next, p.lastTok)
+
+ // intersperse extra newlines if present in the source and
+ // if they don't cause extra semicolons (don't do this in
+ // flush as it will cause extra newlines at the end of a file)
+ if !p.impliedSemi {
+ n := nlimit(next.Line - p.pos.Line)
+ // don't exceed maxNewlines if we already wrote one
+ if wroteNewline && n == maxNewlines {
+ n = maxNewlines - 1
+ }
+ if n > 0 {
+ ch := byte('\n')
+ if droppedFF {
+ ch = '\f' // use formfeed since we dropped one before
+ }
+ p.writeByte(ch, n)
+ impliedSemi = false
+ }
+ }
+
+ // the next token starts now - record its line number if requested
+ if p.linePtr != nil {
+ *p.linePtr = p.out.Line
+ p.linePtr = nil
+ }
+
+ p.writeString(next, data, isLit)
+ p.impliedSemi = impliedSemi
+ }
+}
+
+// flush prints any pending comments and whitespace occurring textually
+// before the position of the next token tok. The flush result indicates
+// if a newline was written or if a formfeed was dropped from the whitespace
+// buffer.
+func (p *printer) flush(next token.Position, tok token.Token) (wroteNewline, droppedFF bool) {
+ if p.commentBefore(next) {
+ // if there are comments before the next item, intersperse them
+ wroteNewline, droppedFF = p.intersperseComments(next, tok)
+ } else {
+ // otherwise, write any leftover whitespace
+ p.writeWhitespace(len(p.wsbuf))
+ }
+ return
+}
+
+// getDoc returns the ast.CommentGroup associated with n, if any.
+func getDoc(n ast.Node) *ast.CommentGroup {
+ switch n := n.(type) {
+ case *ast.Field:
+ return n.Doc
+ case *ast.ImportSpec:
+ return n.Doc
+ case *ast.ValueSpec:
+ return n.Doc
+ case *ast.TypeSpec:
+ return n.Doc
+ case *ast.GenDecl:
+ return n.Doc
+ case *ast.FuncDecl:
+ return n.Doc
+ case *ast.File:
+ return n.Doc
+ }
+ return nil
+}
+
+func getLastComment(n ast.Node) *ast.CommentGroup {
+ switch n := n.(type) {
+ case *ast.Field:
+ return n.Comment
+ case *ast.ImportSpec:
+ return n.Comment
+ case *ast.ValueSpec:
+ return n.Comment
+ case *ast.TypeSpec:
+ return n.Comment
+ case *ast.GenDecl:
+ if len(n.Specs) > 0 {
+ return getLastComment(n.Specs[len(n.Specs)-1])
+ }
+ case *ast.File:
+ if len(n.Comments) > 0 {
+ return n.Comments[len(n.Comments)-1]
+ }
+ }
+ return nil
+}
+
+func (p *printer) printNode(node any) error {
+ // unpack *CommentedNode, if any
+ var comments []*ast.CommentGroup
+ if cnode, ok := node.(*CommentedNode); ok {
+ node = cnode.Node
+ comments = cnode.Comments
+ }
+
+ if comments != nil {
+ // commented node - restrict comment list to relevant range
+ n, ok := node.(ast.Node)
+ if !ok {
+ goto unsupported
+ }
+ beg := n.Pos()
+ end := n.End()
+ // if the node has associated documentation,
+ // include that commentgroup in the range
+ // (the comment list is sorted in the order
+ // of the comment appearance in the source code)
+ if doc := getDoc(n); doc != nil {
+ beg = doc.Pos()
+ }
+ if com := getLastComment(n); com != nil {
+ if e := com.End(); e > end {
+ end = e
+ }
+ }
+ // token.Pos values are global offsets, we can
+ // compare them directly
+ i := 0
+ for i < len(comments) && comments[i].End() < beg {
+ i++
+ }
+ j := i
+ for j < len(comments) && comments[j].Pos() < end {
+ j++
+ }
+ if i < j {
+ p.comments = comments[i:j]
+ }
+ } else if n, ok := node.(*ast.File); ok {
+ // use ast.File comments, if any
+ p.comments = n.Comments
+ }
+
+ // if there are no comments, use node comments
+ p.useNodeComments = p.comments == nil
+
+ // get comments ready for use
+ p.nextComment()
+
+ p.print(pmode(0))
+
+ // format node
+ switch n := node.(type) {
+ case ast.Expr:
+ p.expr(n)
+ case ast.Stmt:
+ // A labeled statement will un-indent to position the label.
+ // Set p.indent to 1 so we don't get indent "underflow".
+ if _, ok := n.(*ast.LabeledStmt); ok {
+ p.indent = 1
+ }
+ p.stmt(n, false)
+ case ast.Decl:
+ p.decl(n)
+ case ast.Spec:
+ p.spec(n, 1, false)
+ case []ast.Stmt:
+ // A labeled statement will un-indent to position the label.
+ // Set p.indent to 1 so we don't get indent "underflow".
+ for _, s := range n {
+ if _, ok := s.(*ast.LabeledStmt); ok {
+ p.indent = 1
+ }
+ }
+ p.stmtList(n, 0, false)
+ case []ast.Decl:
+ p.declList(n)
+ case *ast.File:
+ p.file(n)
+ default:
+ goto unsupported
+ }
+
+ return p.sourcePosErr
+
+unsupported:
+ return fmt.Errorf("go/printer: unsupported node type %T", node)
+}
+
+// ----------------------------------------------------------------------------
+// Trimmer
+
+// A trimmer is an io.Writer filter for stripping tabwriter.Escape
+// characters, trailing blanks and tabs, and for converting formfeed
+// and vtab characters into newlines and htabs (in case no tabwriter
+// is used). Text bracketed by tabwriter.Escape characters is passed
+// through unchanged.
+type trimmer struct {
+ output io.Writer
+ state int
+ space []byte
+}
+
+// trimmer is implemented as a state machine.
+// It can be in one of the following states:
+const (
+ inSpace = iota // inside space
+ inEscape // inside text bracketed by tabwriter.Escapes
+ inText // inside text
+)
+
+func (p *trimmer) resetSpace() {
+ p.state = inSpace
+ p.space = p.space[0:0]
+}
+
+// Design note: It is tempting to eliminate extra blanks occurring in
+// whitespace in this function as it could simplify some
+// of the blanks logic in the node printing functions.
+// However, this would mess up any formatting done by
+// the tabwriter.
+
+var aNewline = []byte("\n")
+
+func (p *trimmer) Write(data []byte) (n int, err error) {
+ // invariants:
+ // p.state == inSpace:
+ // p.space is unwritten
+ // p.state == inEscape, inText:
+ // data[m:n] is unwritten
+ m := 0
+ var b byte
+ for n, b = range data {
+ if b == '\v' {
+ b = '\t' // convert to htab
+ }
+ switch p.state {
+ case inSpace:
+ switch b {
+ case '\t', ' ':
+ p.space = append(p.space, b)
+ case '\n', '\f':
+ p.resetSpace() // discard trailing space
+ _, err = p.output.Write(aNewline)
+ case tabwriter.Escape:
+ _, err = p.output.Write(p.space)
+ p.state = inEscape
+ m = n + 1 // +1: skip tabwriter.Escape
+ default:
+ _, err = p.output.Write(p.space)
+ p.state = inText
+ m = n
+ }
+ case inEscape:
+ if b == tabwriter.Escape {
+ _, err = p.output.Write(data[m:n])
+ p.resetSpace()
+ }
+ case inText:
+ switch b {
+ case '\t', ' ':
+ _, err = p.output.Write(data[m:n])
+ p.resetSpace()
+ p.space = append(p.space, b)
+ case '\n', '\f':
+ _, err = p.output.Write(data[m:n])
+ p.resetSpace()
+ if err == nil {
+ _, err = p.output.Write(aNewline)
+ }
+ case tabwriter.Escape:
+ _, err = p.output.Write(data[m:n])
+ p.state = inEscape
+ m = n + 1 // +1: skip tabwriter.Escape
+ }
+ default:
+ panic("unreachable")
+ }
+ if err != nil {
+ return
+ }
+ }
+ n = len(data)
+
+ switch p.state {
+ case inEscape, inText:
+ _, err = p.output.Write(data[m:n])
+ p.resetSpace()
+ }
+
+ return
+}
+
+// ----------------------------------------------------------------------------
+// Public interface
+
+// A Mode value is a set of flags (or 0). They control printing.
+type Mode uint
+
+const (
+ RawFormat Mode = 1 << iota // do not use a tabwriter; if set, UseSpaces is ignored
+ TabIndent // use tabs for indentation independent of UseSpaces
+ UseSpaces // use spaces instead of tabs for alignment
+ SourcePos // emit //line directives to preserve original source positions
+)
+
+// The mode below is not included in printer's public API because
+// editing code text is deemed out of scope. Because this mode is
+// unexported, it's also possible to modify or remove it based on
+// the evolving needs of go/format and cmd/gofmt without breaking
+// users. See discussion in CL 240683.
+const (
+ // normalizeNumbers means to canonicalize number
+ // literal prefixes and exponents while printing.
+ //
+ // This value is known in and used by go/format and cmd/gofmt.
+ // It is currently more convenient and performant for those
+ // packages to apply number normalization during printing,
+ // rather than by modifying the AST in advance.
+ normalizeNumbers Mode = 1 << 30
+)
+
+// A Config node controls the output of Fprint.
+type Config struct {
+ Mode Mode // default: 0
+ Tabwidth int // default: 8
+ Indent int // default: 0 (all code is indented at least by this much)
+}
+
+var printerPool = sync.Pool{
+ New: func() any {
+ return &printer{
+ // Whitespace sequences are short.
+ wsbuf: make([]whiteSpace, 0, 16),
+ // We start the printer with a 16K output buffer, which is currently
+ // larger than about 80% of Go files in the standard library.
+ output: make([]byte, 0, 16<<10),
+ }
+ },
+}
+
+func newPrinter(cfg *Config, fset *token.FileSet, nodeSizes map[ast.Node]int) *printer {
+ p := printerPool.Get().(*printer)
+ *p = printer{
+ Config: *cfg,
+ fset: fset,
+ pos: token.Position{Line: 1, Column: 1},
+ out: token.Position{Line: 1, Column: 1},
+ wsbuf: p.wsbuf[:0],
+ nodeSizes: nodeSizes,
+ cachedPos: -1,
+ output: p.output[:0],
+ }
+ return p
+}
+
+func (p *printer) free() {
+ // Hard limit on buffer size; see https://golang.org/issue/23199.
+ if cap(p.output) > 64<<10 {
+ return
+ }
+
+ printerPool.Put(p)
+}
+
+// fprint implements Fprint and takes a nodesSizes map for setting up the printer state.
+func (cfg *Config) fprint(output io.Writer, fset *token.FileSet, node any, nodeSizes map[ast.Node]int) (err error) {
+ // print node
+ p := newPrinter(cfg, fset, nodeSizes)
+ defer p.free()
+ if err = p.printNode(node); err != nil {
+ return
+ }
+ // print outstanding comments
+ p.impliedSemi = false // EOF acts like a newline
+ p.flush(token.Position{Offset: infinity, Line: infinity}, token.EOF)
+
+ // output is buffered in p.output now.
+ // fix //go:build and // +build comments if needed.
+ p.fixGoBuildLines()
+
+ // redirect output through a trimmer to eliminate trailing whitespace
+ // (Input to a tabwriter must be untrimmed since trailing tabs provide
+ // formatting information. The tabwriter could provide trimming
+ // functionality but no tabwriter is used when RawFormat is set.)
+ output = &trimmer{output: output}
+
+ // redirect output through a tabwriter if necessary
+ if cfg.Mode&RawFormat == 0 {
+ minwidth := cfg.Tabwidth
+
+ padchar := byte('\t')
+ if cfg.Mode&UseSpaces != 0 {
+ padchar = ' '
+ }
+
+ twmode := tabwriter.DiscardEmptyColumns
+ if cfg.Mode&TabIndent != 0 {
+ minwidth = 0
+ twmode |= tabwriter.TabIndent
+ }
+
+ output = tabwriter.NewWriter(output, minwidth, cfg.Tabwidth, 1, padchar, twmode)
+ }
+
+ // write printer result via tabwriter/trimmer to output
+ if _, err = output.Write(p.output); err != nil {
+ return
+ }
+
+ // flush tabwriter, if any
+ if tw, _ := output.(*tabwriter.Writer); tw != nil {
+ err = tw.Flush()
+ }
+
+ return
+}
+
+// A CommentedNode bundles an AST node and corresponding comments.
+// It may be provided as argument to any of the Fprint functions.
+type CommentedNode struct {
+ Node any // *ast.File, or ast.Expr, ast.Decl, ast.Spec, or ast.Stmt
+ Comments []*ast.CommentGroup
+}
+
+// Fprint "pretty-prints" an AST node to output for a given configuration cfg.
+// Position information is interpreted relative to the file set fset.
+// The node type must be *ast.File, *CommentedNode, []ast.Decl, []ast.Stmt,
+// or assignment-compatible to ast.Expr, ast.Decl, ast.Spec, or ast.Stmt.
+func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node any) error {
+ return cfg.fprint(output, fset, node, make(map[ast.Node]int))
+}
+
+// Fprint "pretty-prints" an AST node to output.
+// It calls Config.Fprint with default settings.
+// Note that gofmt uses tabs for indentation but spaces for alignment;
+// use format.Node (package go/format) for output that matches gofmt.
+func Fprint(output io.Writer, fset *token.FileSet, node any) error {
+ return (&Config{Tabwidth: 8}).Fprint(output, fset, node)
+}
diff --git a/contrib/go/_std_1.21/src/go/printer/ya.make b/contrib/go/_std_1.21/src/go/printer/ya.make
new file mode 100644
index 0000000000..2ffd5c0cf0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/printer/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ comment.go
+ gobuild.go
+ nodes.go
+ printer.go
+)
+
+GO_TEST_SRCS(
+ performance_test.go
+ printer_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/go/scanner/errors.go b/contrib/go/_std_1.21/src/go/scanner/errors.go
index 3e9c365cca..3e9c365cca 100644
--- a/contrib/go/_std_1.20/src/go/scanner/errors.go
+++ b/contrib/go/_std_1.21/src/go/scanner/errors.go
diff --git a/contrib/go/_std_1.21/src/go/scanner/scanner.go b/contrib/go/_std_1.21/src/go/scanner/scanner.go
new file mode 100644
index 0000000000..75f835d310
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/scanner/scanner.go
@@ -0,0 +1,958 @@
+// Copyright 2009 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 scanner implements a scanner for Go source text.
+// It takes a []byte as source which can then be tokenized
+// through repeated calls to the Scan method.
+package scanner
+
+import (
+ "bytes"
+ "fmt"
+ "go/token"
+ "path/filepath"
+ "strconv"
+ "unicode"
+ "unicode/utf8"
+)
+
+// An ErrorHandler may be provided to Scanner.Init. If a syntax error is
+// encountered and a handler was installed, the handler is called with a
+// position and an error message. The position points to the beginning of
+// the offending token.
+type ErrorHandler func(pos token.Position, msg string)
+
+// A Scanner holds the scanner's internal state while processing
+// a given text. It can be allocated as part of another data
+// structure but must be initialized via Init before use.
+type Scanner struct {
+ // immutable state
+ file *token.File // source file handle
+ dir string // directory portion of file.Name()
+ src []byte // source
+ err ErrorHandler // error reporting; or nil
+ mode Mode // scanning mode
+
+ // scanning state
+ ch rune // current character
+ offset int // character offset
+ rdOffset int // reading offset (position after current character)
+ lineOffset int // current line offset
+ insertSemi bool // insert a semicolon before next newline
+ nlPos token.Pos // position of newline in preceding comment
+
+ // public state - ok to modify
+ ErrorCount int // number of errors encountered
+}
+
+const (
+ bom = 0xFEFF // byte order mark, only permitted as very first character
+ eof = -1 // end of file
+)
+
+// Read the next Unicode char into s.ch.
+// s.ch < 0 means end-of-file.
+//
+// For optimization, there is some overlap between this method and
+// s.scanIdentifier.
+func (s *Scanner) next() {
+ if s.rdOffset < len(s.src) {
+ s.offset = s.rdOffset
+ if s.ch == '\n' {
+ s.lineOffset = s.offset
+ s.file.AddLine(s.offset)
+ }
+ r, w := rune(s.src[s.rdOffset]), 1
+ switch {
+ case r == 0:
+ s.error(s.offset, "illegal character NUL")
+ case r >= utf8.RuneSelf:
+ // not ASCII
+ r, w = utf8.DecodeRune(s.src[s.rdOffset:])
+ if r == utf8.RuneError && w == 1 {
+ s.error(s.offset, "illegal UTF-8 encoding")
+ } else if r == bom && s.offset > 0 {
+ s.error(s.offset, "illegal byte order mark")
+ }
+ }
+ s.rdOffset += w
+ s.ch = r
+ } else {
+ s.offset = len(s.src)
+ if s.ch == '\n' {
+ s.lineOffset = s.offset
+ s.file.AddLine(s.offset)
+ }
+ s.ch = eof
+ }
+}
+
+// peek returns the byte following the most recently read character without
+// advancing the scanner. If the scanner is at EOF, peek returns 0.
+func (s *Scanner) peek() byte {
+ if s.rdOffset < len(s.src) {
+ return s.src[s.rdOffset]
+ }
+ return 0
+}
+
+// A mode value is a set of flags (or 0).
+// They control scanner behavior.
+type Mode uint
+
+const (
+ ScanComments Mode = 1 << iota // return comments as COMMENT tokens
+ dontInsertSemis // do not automatically insert semicolons - for testing only
+)
+
+// Init prepares the scanner s to tokenize the text src by setting the
+// scanner at the beginning of src. The scanner uses the file set file
+// for position information and it adds line information for each line.
+// It is ok to re-use the same file when re-scanning the same file as
+// line information which is already present is ignored. Init causes a
+// panic if the file size does not match the src size.
+//
+// Calls to Scan will invoke the error handler err if they encounter a
+// syntax error and err is not nil. Also, for each error encountered,
+// the Scanner field ErrorCount is incremented by one. The mode parameter
+// determines how comments are handled.
+//
+// Note that Init may call err if there is an error in the first character
+// of the file.
+func (s *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode Mode) {
+ // Explicitly initialize all fields since a scanner may be reused.
+ if file.Size() != len(src) {
+ panic(fmt.Sprintf("file size (%d) does not match src len (%d)", file.Size(), len(src)))
+ }
+ s.file = file
+ s.dir, _ = filepath.Split(file.Name())
+ s.src = src
+ s.err = err
+ s.mode = mode
+
+ s.ch = ' '
+ s.offset = 0
+ s.rdOffset = 0
+ s.lineOffset = 0
+ s.insertSemi = false
+ s.ErrorCount = 0
+
+ s.next()
+ if s.ch == bom {
+ s.next() // ignore BOM at file beginning
+ }
+}
+
+func (s *Scanner) error(offs int, msg string) {
+ if s.err != nil {
+ s.err(s.file.Position(s.file.Pos(offs)), msg)
+ }
+ s.ErrorCount++
+}
+
+func (s *Scanner) errorf(offs int, format string, args ...any) {
+ s.error(offs, fmt.Sprintf(format, args...))
+}
+
+// scanComment returns the text of the comment and (if nonzero)
+// the offset of the first newline within it, which implies a
+// /*...*/ comment.
+func (s *Scanner) scanComment() (string, int) {
+ // initial '/' already consumed; s.ch == '/' || s.ch == '*'
+ offs := s.offset - 1 // position of initial '/'
+ next := -1 // position immediately following the comment; < 0 means invalid comment
+ numCR := 0
+ nlOffset := 0 // offset of first newline within /*...*/ comment
+
+ if s.ch == '/' {
+ //-style comment
+ // (the final '\n' is not considered part of the comment)
+ s.next()
+ for s.ch != '\n' && s.ch >= 0 {
+ if s.ch == '\r' {
+ numCR++
+ }
+ s.next()
+ }
+ // if we are at '\n', the position following the comment is afterwards
+ next = s.offset
+ if s.ch == '\n' {
+ next++
+ }
+ goto exit
+ }
+
+ /*-style comment */
+ s.next()
+ for s.ch >= 0 {
+ ch := s.ch
+ if ch == '\r' {
+ numCR++
+ } else if ch == '\n' && nlOffset == 0 {
+ nlOffset = s.offset
+ }
+ s.next()
+ if ch == '*' && s.ch == '/' {
+ s.next()
+ next = s.offset
+ goto exit
+ }
+ }
+
+ s.error(offs, "comment not terminated")
+
+exit:
+ lit := s.src[offs:s.offset]
+
+ // On Windows, a (//-comment) line may end in "\r\n".
+ // Remove the final '\r' before analyzing the text for
+ // line directives (matching the compiler). Remove any
+ // other '\r' afterwards (matching the pre-existing be-
+ // havior of the scanner).
+ if numCR > 0 && len(lit) >= 2 && lit[1] == '/' && lit[len(lit)-1] == '\r' {
+ lit = lit[:len(lit)-1]
+ numCR--
+ }
+
+ // interpret line directives
+ // (//line directives must start at the beginning of the current line)
+ if next >= 0 /* implies valid comment */ && (lit[1] == '*' || offs == s.lineOffset) && bytes.HasPrefix(lit[2:], prefix) {
+ s.updateLineInfo(next, offs, lit)
+ }
+
+ if numCR > 0 {
+ lit = stripCR(lit, lit[1] == '*')
+ }
+
+ return string(lit), nlOffset
+}
+
+var prefix = []byte("line ")
+
+// updateLineInfo parses the incoming comment text at offset offs
+// as a line directive. If successful, it updates the line info table
+// for the position next per the line directive.
+func (s *Scanner) updateLineInfo(next, offs int, text []byte) {
+ // extract comment text
+ if text[1] == '*' {
+ text = text[:len(text)-2] // lop off trailing "*/"
+ }
+ text = text[7:] // lop off leading "//line " or "/*line "
+ offs += 7
+
+ i, n, ok := trailingDigits(text)
+ if i == 0 {
+ return // ignore (not a line directive)
+ }
+ // i > 0
+
+ if !ok {
+ // text has a suffix :xxx but xxx is not a number
+ s.error(offs+i, "invalid line number: "+string(text[i:]))
+ return
+ }
+
+ // Put a cap on the maximum size of line and column numbers.
+ // 30 bits allows for some additional space before wrapping an int32.
+ // Keep this consistent with cmd/compile/internal/syntax.PosMax.
+ const maxLineCol = 1 << 30
+ var line, col int
+ i2, n2, ok2 := trailingDigits(text[:i-1])
+ if ok2 {
+ //line filename:line:col
+ i, i2 = i2, i
+ line, col = n2, n
+ if col == 0 || col > maxLineCol {
+ s.error(offs+i2, "invalid column number: "+string(text[i2:]))
+ return
+ }
+ text = text[:i2-1] // lop off ":col"
+ } else {
+ //line filename:line
+ line = n
+ }
+
+ if line == 0 || line > maxLineCol {
+ s.error(offs+i, "invalid line number: "+string(text[i:]))
+ return
+ }
+
+ // If we have a column (//line filename:line:col form),
+ // an empty filename means to use the previous filename.
+ filename := string(text[:i-1]) // lop off ":line", and trim white space
+ if filename == "" && ok2 {
+ filename = s.file.Position(s.file.Pos(offs)).Filename
+ } else if filename != "" {
+ // Put a relative filename in the current directory.
+ // This is for compatibility with earlier releases.
+ // See issue 26671.
+ filename = filepath.Clean(filename)
+ if !filepath.IsAbs(filename) {
+ filename = filepath.Join(s.dir, filename)
+ }
+ }
+
+ s.file.AddLineColumnInfo(next, filename, line, col)
+}
+
+func trailingDigits(text []byte) (int, int, bool) {
+ i := bytes.LastIndexByte(text, ':') // look from right (Windows filenames may contain ':')
+ if i < 0 {
+ return 0, 0, false // no ":"
+ }
+ // i >= 0
+ n, err := strconv.ParseUint(string(text[i+1:]), 10, 0)
+ return i + 1, int(n), err == nil
+}
+
+func isLetter(ch rune) bool {
+ return 'a' <= lower(ch) && lower(ch) <= 'z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch)
+}
+
+func isDigit(ch rune) bool {
+ return isDecimal(ch) || ch >= utf8.RuneSelf && unicode.IsDigit(ch)
+}
+
+// scanIdentifier reads the string of valid identifier characters at s.offset.
+// It must only be called when s.ch is known to be a valid letter.
+//
+// Be careful when making changes to this function: it is optimized and affects
+// scanning performance significantly.
+func (s *Scanner) scanIdentifier() string {
+ offs := s.offset
+
+ // Optimize for the common case of an ASCII identifier.
+ //
+ // Ranging over s.src[s.rdOffset:] lets us avoid some bounds checks, and
+ // avoids conversions to runes.
+ //
+ // In case we encounter a non-ASCII character, fall back on the slower path
+ // of calling into s.next().
+ for rdOffset, b := range s.src[s.rdOffset:] {
+ if 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z' || b == '_' || '0' <= b && b <= '9' {
+ // Avoid assigning a rune for the common case of an ascii character.
+ continue
+ }
+ s.rdOffset += rdOffset
+ if 0 < b && b < utf8.RuneSelf {
+ // Optimization: we've encountered an ASCII character that's not a letter
+ // or number. Avoid the call into s.next() and corresponding set up.
+ //
+ // Note that s.next() does some line accounting if s.ch is '\n', so this
+ // shortcut is only possible because we know that the preceding character
+ // is not '\n'.
+ s.ch = rune(b)
+ s.offset = s.rdOffset
+ s.rdOffset++
+ goto exit
+ }
+ // We know that the preceding character is valid for an identifier because
+ // scanIdentifier is only called when s.ch is a letter, so calling s.next()
+ // at s.rdOffset resets the scanner state.
+ s.next()
+ for isLetter(s.ch) || isDigit(s.ch) {
+ s.next()
+ }
+ goto exit
+ }
+ s.offset = len(s.src)
+ s.rdOffset = len(s.src)
+ s.ch = eof
+
+exit:
+ return string(s.src[offs:s.offset])
+}
+
+func digitVal(ch rune) int {
+ switch {
+ case '0' <= ch && ch <= '9':
+ return int(ch - '0')
+ case 'a' <= lower(ch) && lower(ch) <= 'f':
+ return int(lower(ch) - 'a' + 10)
+ }
+ return 16 // larger than any legal digit val
+}
+
+func lower(ch rune) rune { return ('a' - 'A') | ch } // returns lower-case ch iff ch is ASCII letter
+func isDecimal(ch rune) bool { return '0' <= ch && ch <= '9' }
+func isHex(ch rune) bool { return '0' <= ch && ch <= '9' || 'a' <= lower(ch) && lower(ch) <= 'f' }
+
+// digits accepts the sequence { digit | '_' }.
+// If base <= 10, digits accepts any decimal digit but records
+// the offset (relative to the source start) of a digit >= base
+// in *invalid, if *invalid < 0.
+// digits returns a bitset describing whether the sequence contained
+// digits (bit 0 is set), or separators '_' (bit 1 is set).
+func (s *Scanner) digits(base int, invalid *int) (digsep int) {
+ if base <= 10 {
+ max := rune('0' + base)
+ for isDecimal(s.ch) || s.ch == '_' {
+ ds := 1
+ if s.ch == '_' {
+ ds = 2
+ } else if s.ch >= max && *invalid < 0 {
+ *invalid = s.offset // record invalid rune offset
+ }
+ digsep |= ds
+ s.next()
+ }
+ } else {
+ for isHex(s.ch) || s.ch == '_' {
+ ds := 1
+ if s.ch == '_' {
+ ds = 2
+ }
+ digsep |= ds
+ s.next()
+ }
+ }
+ return
+}
+
+func (s *Scanner) scanNumber() (token.Token, string) {
+ offs := s.offset
+ tok := token.ILLEGAL
+
+ base := 10 // number base
+ prefix := rune(0) // one of 0 (decimal), '0' (0-octal), 'x', 'o', or 'b'
+ digsep := 0 // bit 0: digit present, bit 1: '_' present
+ invalid := -1 // index of invalid digit in literal, or < 0
+
+ // integer part
+ if s.ch != '.' {
+ tok = token.INT
+ if s.ch == '0' {
+ s.next()
+ switch lower(s.ch) {
+ case 'x':
+ s.next()
+ base, prefix = 16, 'x'
+ case 'o':
+ s.next()
+ base, prefix = 8, 'o'
+ case 'b':
+ s.next()
+ base, prefix = 2, 'b'
+ default:
+ base, prefix = 8, '0'
+ digsep = 1 // leading 0
+ }
+ }
+ digsep |= s.digits(base, &invalid)
+ }
+
+ // fractional part
+ if s.ch == '.' {
+ tok = token.FLOAT
+ if prefix == 'o' || prefix == 'b' {
+ s.error(s.offset, "invalid radix point in "+litname(prefix))
+ }
+ s.next()
+ digsep |= s.digits(base, &invalid)
+ }
+
+ if digsep&1 == 0 {
+ s.error(s.offset, litname(prefix)+" has no digits")
+ }
+
+ // exponent
+ if e := lower(s.ch); e == 'e' || e == 'p' {
+ switch {
+ case e == 'e' && prefix != 0 && prefix != '0':
+ s.errorf(s.offset, "%q exponent requires decimal mantissa", s.ch)
+ case e == 'p' && prefix != 'x':
+ s.errorf(s.offset, "%q exponent requires hexadecimal mantissa", s.ch)
+ }
+ s.next()
+ tok = token.FLOAT
+ if s.ch == '+' || s.ch == '-' {
+ s.next()
+ }
+ ds := s.digits(10, nil)
+ digsep |= ds
+ if ds&1 == 0 {
+ s.error(s.offset, "exponent has no digits")
+ }
+ } else if prefix == 'x' && tok == token.FLOAT {
+ s.error(s.offset, "hexadecimal mantissa requires a 'p' exponent")
+ }
+
+ // suffix 'i'
+ if s.ch == 'i' {
+ tok = token.IMAG
+ s.next()
+ }
+
+ lit := string(s.src[offs:s.offset])
+ if tok == token.INT && invalid >= 0 {
+ s.errorf(invalid, "invalid digit %q in %s", lit[invalid-offs], litname(prefix))
+ }
+ if digsep&2 != 0 {
+ if i := invalidSep(lit); i >= 0 {
+ s.error(offs+i, "'_' must separate successive digits")
+ }
+ }
+
+ return tok, lit
+}
+
+func litname(prefix rune) string {
+ switch prefix {
+ case 'x':
+ return "hexadecimal literal"
+ case 'o', '0':
+ return "octal literal"
+ case 'b':
+ return "binary literal"
+ }
+ return "decimal literal"
+}
+
+// invalidSep returns the index of the first invalid separator in x, or -1.
+func invalidSep(x string) int {
+ x1 := ' ' // prefix char, we only care if it's 'x'
+ d := '.' // digit, one of '_', '0' (a digit), or '.' (anything else)
+ i := 0
+
+ // a prefix counts as a digit
+ if len(x) >= 2 && x[0] == '0' {
+ x1 = lower(rune(x[1]))
+ if x1 == 'x' || x1 == 'o' || x1 == 'b' {
+ d = '0'
+ i = 2
+ }
+ }
+
+ // mantissa and exponent
+ for ; i < len(x); i++ {
+ p := d // previous digit
+ d = rune(x[i])
+ switch {
+ case d == '_':
+ if p != '0' {
+ return i
+ }
+ case isDecimal(d) || x1 == 'x' && isHex(d):
+ d = '0'
+ default:
+ if p == '_' {
+ return i - 1
+ }
+ d = '.'
+ }
+ }
+ if d == '_' {
+ return len(x) - 1
+ }
+
+ return -1
+}
+
+// scanEscape parses an escape sequence where rune is the accepted
+// escaped quote. In case of a syntax error, it stops at the offending
+// character (without consuming it) and returns false. Otherwise
+// it returns true.
+func (s *Scanner) scanEscape(quote rune) bool {
+ offs := s.offset
+
+ var n int
+ var base, max uint32
+ switch s.ch {
+ case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
+ s.next()
+ return true
+ case '0', '1', '2', '3', '4', '5', '6', '7':
+ n, base, max = 3, 8, 255
+ case 'x':
+ s.next()
+ n, base, max = 2, 16, 255
+ case 'u':
+ s.next()
+ n, base, max = 4, 16, unicode.MaxRune
+ case 'U':
+ s.next()
+ n, base, max = 8, 16, unicode.MaxRune
+ default:
+ msg := "unknown escape sequence"
+ if s.ch < 0 {
+ msg = "escape sequence not terminated"
+ }
+ s.error(offs, msg)
+ return false
+ }
+
+ var x uint32
+ for n > 0 {
+ d := uint32(digitVal(s.ch))
+ if d >= base {
+ msg := fmt.Sprintf("illegal character %#U in escape sequence", s.ch)
+ if s.ch < 0 {
+ msg = "escape sequence not terminated"
+ }
+ s.error(s.offset, msg)
+ return false
+ }
+ x = x*base + d
+ s.next()
+ n--
+ }
+
+ if x > max || 0xD800 <= x && x < 0xE000 {
+ s.error(offs, "escape sequence is invalid Unicode code point")
+ return false
+ }
+
+ return true
+}
+
+func (s *Scanner) scanRune() string {
+ // '\'' opening already consumed
+ offs := s.offset - 1
+
+ valid := true
+ n := 0
+ for {
+ ch := s.ch
+ if ch == '\n' || ch < 0 {
+ // only report error if we don't have one already
+ if valid {
+ s.error(offs, "rune literal not terminated")
+ valid = false
+ }
+ break
+ }
+ s.next()
+ if ch == '\'' {
+ break
+ }
+ n++
+ if ch == '\\' {
+ if !s.scanEscape('\'') {
+ valid = false
+ }
+ // continue to read to closing quote
+ }
+ }
+
+ if valid && n != 1 {
+ s.error(offs, "illegal rune literal")
+ }
+
+ return string(s.src[offs:s.offset])
+}
+
+func (s *Scanner) scanString() string {
+ // '"' opening already consumed
+ offs := s.offset - 1
+
+ for {
+ ch := s.ch
+ if ch == '\n' || ch < 0 {
+ s.error(offs, "string literal not terminated")
+ break
+ }
+ s.next()
+ if ch == '"' {
+ break
+ }
+ if ch == '\\' {
+ s.scanEscape('"')
+ }
+ }
+
+ return string(s.src[offs:s.offset])
+}
+
+func stripCR(b []byte, comment bool) []byte {
+ c := make([]byte, len(b))
+ i := 0
+ for j, ch := range b {
+ // In a /*-style comment, don't strip \r from *\r/ (incl.
+ // sequences of \r from *\r\r...\r/) since the resulting
+ // */ would terminate the comment too early unless the \r
+ // is immediately following the opening /* in which case
+ // it's ok because /*/ is not closed yet (issue #11151).
+ if ch != '\r' || comment && i > len("/*") && c[i-1] == '*' && j+1 < len(b) && b[j+1] == '/' {
+ c[i] = ch
+ i++
+ }
+ }
+ return c[:i]
+}
+
+func (s *Scanner) scanRawString() string {
+ // '`' opening already consumed
+ offs := s.offset - 1
+
+ hasCR := false
+ for {
+ ch := s.ch
+ if ch < 0 {
+ s.error(offs, "raw string literal not terminated")
+ break
+ }
+ s.next()
+ if ch == '`' {
+ break
+ }
+ if ch == '\r' {
+ hasCR = true
+ }
+ }
+
+ lit := s.src[offs:s.offset]
+ if hasCR {
+ lit = stripCR(lit, false)
+ }
+
+ return string(lit)
+}
+
+func (s *Scanner) skipWhitespace() {
+ for s.ch == ' ' || s.ch == '\t' || s.ch == '\n' && !s.insertSemi || s.ch == '\r' {
+ s.next()
+ }
+}
+
+// Helper functions for scanning multi-byte tokens such as >> += >>= .
+// Different routines recognize different length tok_i based on matches
+// of ch_i. If a token ends in '=', the result is tok1 or tok3
+// respectively. Otherwise, the result is tok0 if there was no other
+// matching character, or tok2 if the matching character was ch2.
+
+func (s *Scanner) switch2(tok0, tok1 token.Token) token.Token {
+ if s.ch == '=' {
+ s.next()
+ return tok1
+ }
+ return tok0
+}
+
+func (s *Scanner) switch3(tok0, tok1 token.Token, ch2 rune, tok2 token.Token) token.Token {
+ if s.ch == '=' {
+ s.next()
+ return tok1
+ }
+ if s.ch == ch2 {
+ s.next()
+ return tok2
+ }
+ return tok0
+}
+
+func (s *Scanner) switch4(tok0, tok1 token.Token, ch2 rune, tok2, tok3 token.Token) token.Token {
+ if s.ch == '=' {
+ s.next()
+ return tok1
+ }
+ if s.ch == ch2 {
+ s.next()
+ if s.ch == '=' {
+ s.next()
+ return tok3
+ }
+ return tok2
+ }
+ return tok0
+}
+
+// Scan scans the next token and returns the token position, the token,
+// and its literal string if applicable. The source end is indicated by
+// token.EOF.
+//
+// If the returned token is a literal (token.IDENT, token.INT, token.FLOAT,
+// token.IMAG, token.CHAR, token.STRING) or token.COMMENT, the literal string
+// has the corresponding value.
+//
+// If the returned token is a keyword, the literal string is the keyword.
+//
+// If the returned token is token.SEMICOLON, the corresponding
+// literal string is ";" if the semicolon was present in the source,
+// and "\n" if the semicolon was inserted because of a newline or
+// at EOF.
+//
+// If the returned token is token.ILLEGAL, the literal string is the
+// offending character.
+//
+// In all other cases, Scan returns an empty literal string.
+//
+// For more tolerant parsing, Scan will return a valid token if
+// possible even if a syntax error was encountered. Thus, even
+// if the resulting token sequence contains no illegal tokens,
+// a client may not assume that no error occurred. Instead it
+// must check the scanner's ErrorCount or the number of calls
+// of the error handler, if there was one installed.
+//
+// Scan adds line information to the file added to the file
+// set with Init. Token positions are relative to that file
+// and thus relative to the file set.
+func (s *Scanner) Scan() (pos token.Pos, tok token.Token, lit string) {
+scanAgain:
+ if s.nlPos.IsValid() {
+ // Return artificial ';' token after /*...*/ comment
+ // containing newline, at position of first newline.
+ pos, tok, lit = s.nlPos, token.SEMICOLON, "\n"
+ s.nlPos = token.NoPos
+ return
+ }
+
+ s.skipWhitespace()
+
+ // current token start
+ pos = s.file.Pos(s.offset)
+
+ // determine token value
+ insertSemi := false
+ switch ch := s.ch; {
+ case isLetter(ch):
+ lit = s.scanIdentifier()
+ if len(lit) > 1 {
+ // keywords are longer than one letter - avoid lookup otherwise
+ tok = token.Lookup(lit)
+ switch tok {
+ case token.IDENT, token.BREAK, token.CONTINUE, token.FALLTHROUGH, token.RETURN:
+ insertSemi = true
+ }
+ } else {
+ insertSemi = true
+ tok = token.IDENT
+ }
+ case isDecimal(ch) || ch == '.' && isDecimal(rune(s.peek())):
+ insertSemi = true
+ tok, lit = s.scanNumber()
+ default:
+ s.next() // always make progress
+ switch ch {
+ case eof:
+ if s.insertSemi {
+ s.insertSemi = false // EOF consumed
+ return pos, token.SEMICOLON, "\n"
+ }
+ tok = token.EOF
+ case '\n':
+ // we only reach here if s.insertSemi was
+ // set in the first place and exited early
+ // from s.skipWhitespace()
+ s.insertSemi = false // newline consumed
+ return pos, token.SEMICOLON, "\n"
+ case '"':
+ insertSemi = true
+ tok = token.STRING
+ lit = s.scanString()
+ case '\'':
+ insertSemi = true
+ tok = token.CHAR
+ lit = s.scanRune()
+ case '`':
+ insertSemi = true
+ tok = token.STRING
+ lit = s.scanRawString()
+ case ':':
+ tok = s.switch2(token.COLON, token.DEFINE)
+ case '.':
+ // fractions starting with a '.' are handled by outer switch
+ tok = token.PERIOD
+ if s.ch == '.' && s.peek() == '.' {
+ s.next()
+ s.next() // consume last '.'
+ tok = token.ELLIPSIS
+ }
+ case ',':
+ tok = token.COMMA
+ case ';':
+ tok = token.SEMICOLON
+ lit = ";"
+ case '(':
+ tok = token.LPAREN
+ case ')':
+ insertSemi = true
+ tok = token.RPAREN
+ case '[':
+ tok = token.LBRACK
+ case ']':
+ insertSemi = true
+ tok = token.RBRACK
+ case '{':
+ tok = token.LBRACE
+ case '}':
+ insertSemi = true
+ tok = token.RBRACE
+ case '+':
+ tok = s.switch3(token.ADD, token.ADD_ASSIGN, '+', token.INC)
+ if tok == token.INC {
+ insertSemi = true
+ }
+ case '-':
+ tok = s.switch3(token.SUB, token.SUB_ASSIGN, '-', token.DEC)
+ if tok == token.DEC {
+ insertSemi = true
+ }
+ case '*':
+ tok = s.switch2(token.MUL, token.MUL_ASSIGN)
+ case '/':
+ if s.ch == '/' || s.ch == '*' {
+ // comment
+ comment, nlOffset := s.scanComment()
+ if s.insertSemi && nlOffset != 0 {
+ // For /*...*/ containing \n, return
+ // COMMENT then artificial SEMICOLON.
+ s.nlPos = s.file.Pos(nlOffset)
+ s.insertSemi = false
+ } else {
+ insertSemi = s.insertSemi // preserve insertSemi info
+ }
+ if s.mode&ScanComments == 0 {
+ // skip comment
+ goto scanAgain
+ }
+ tok = token.COMMENT
+ lit = comment
+ } else {
+ // division
+ tok = s.switch2(token.QUO, token.QUO_ASSIGN)
+ }
+ case '%':
+ tok = s.switch2(token.REM, token.REM_ASSIGN)
+ case '^':
+ tok = s.switch2(token.XOR, token.XOR_ASSIGN)
+ case '<':
+ if s.ch == '-' {
+ s.next()
+ tok = token.ARROW
+ } else {
+ tok = s.switch4(token.LSS, token.LEQ, '<', token.SHL, token.SHL_ASSIGN)
+ }
+ case '>':
+ tok = s.switch4(token.GTR, token.GEQ, '>', token.SHR, token.SHR_ASSIGN)
+ case '=':
+ tok = s.switch2(token.ASSIGN, token.EQL)
+ case '!':
+ tok = s.switch2(token.NOT, token.NEQ)
+ case '&':
+ if s.ch == '^' {
+ s.next()
+ tok = s.switch2(token.AND_NOT, token.AND_NOT_ASSIGN)
+ } else {
+ tok = s.switch3(token.AND, token.AND_ASSIGN, '&', token.LAND)
+ }
+ case '|':
+ tok = s.switch3(token.OR, token.OR_ASSIGN, '|', token.LOR)
+ case '~':
+ tok = token.TILDE
+ default:
+ // next reports unexpected BOMs - don't repeat
+ if ch != bom {
+ s.errorf(s.file.Offset(pos), "illegal character %#U", ch)
+ }
+ insertSemi = s.insertSemi // preserve insertSemi info
+ tok = token.ILLEGAL
+ lit = string(ch)
+ }
+ }
+ if s.mode&dontInsertSemis == 0 {
+ s.insertSemi = insertSemi
+ }
+
+ return
+}
diff --git a/contrib/go/_std_1.21/src/go/scanner/ya.make b/contrib/go/_std_1.21/src/go/scanner/ya.make
new file mode 100644
index 0000000000..50a8b5b5de
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/scanner/ya.make
@@ -0,0 +1,15 @@
+GO_LIBRARY()
+
+SRCS(
+ errors.go
+ scanner.go
+)
+
+GO_TEST_SRCS(scanner_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/go/token/position.go b/contrib/go/_std_1.21/src/go/token/position.go
new file mode 100644
index 0000000000..a644382886
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/token/position.go
@@ -0,0 +1,565 @@
+// Copyright 2010 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 token
+
+import (
+ "fmt"
+ "sort"
+ "strconv"
+ "sync"
+ "sync/atomic"
+)
+
+// -----------------------------------------------------------------------------
+// Positions
+
+// Position describes an arbitrary source position
+// including the file, line, and column location.
+// A Position is valid if the line number is > 0.
+type Position struct {
+ Filename string // filename, if any
+ Offset int // offset, starting at 0
+ Line int // line number, starting at 1
+ Column int // column number, starting at 1 (byte count)
+}
+
+// IsValid reports whether the position is valid.
+func (pos *Position) IsValid() bool { return pos.Line > 0 }
+
+// String returns a string in one of several forms:
+//
+// file:line:column valid position with file name
+// file:line valid position with file name but no column (column == 0)
+// line:column valid position without file name
+// line valid position without file name and no column (column == 0)
+// file invalid position with file name
+// - invalid position without file name
+func (pos Position) String() string {
+ s := pos.Filename
+ if pos.IsValid() {
+ if s != "" {
+ s += ":"
+ }
+ s += strconv.Itoa(pos.Line)
+ if pos.Column != 0 {
+ s += fmt.Sprintf(":%d", pos.Column)
+ }
+ }
+ if s == "" {
+ s = "-"
+ }
+ return s
+}
+
+// Pos is a compact encoding of a source position within a file set.
+// It can be converted into a Position for a more convenient, but much
+// larger, representation.
+//
+// The Pos value for a given file is a number in the range [base, base+size],
+// where base and size are specified when a file is added to the file set.
+// The difference between a Pos value and the corresponding file base
+// corresponds to the byte offset of that position (represented by the Pos value)
+// from the beginning of the file. Thus, the file base offset is the Pos value
+// representing the first byte in the file.
+//
+// To create the Pos value for a specific source offset (measured in bytes),
+// first add the respective file to the current file set using FileSet.AddFile
+// and then call File.Pos(offset) for that file. Given a Pos value p
+// for a specific file set fset, the corresponding Position value is
+// obtained by calling fset.Position(p).
+//
+// Pos values can be compared directly with the usual comparison operators:
+// If two Pos values p and q are in the same file, comparing p and q is
+// equivalent to comparing the respective source file offsets. If p and q
+// are in different files, p < q is true if the file implied by p was added
+// to the respective file set before the file implied by q.
+type Pos int
+
+// The zero value for Pos is NoPos; there is no file and line information
+// associated with it, and NoPos.IsValid() is false. NoPos is always
+// smaller than any other Pos value. The corresponding Position value
+// for NoPos is the zero value for Position.
+const NoPos Pos = 0
+
+// IsValid reports whether the position is valid.
+func (p Pos) IsValid() bool {
+ return p != NoPos
+}
+
+// -----------------------------------------------------------------------------
+// File
+
+// A File is a handle for a file belonging to a FileSet.
+// A File has a name, size, and line offset table.
+type File struct {
+ name string // file name as provided to AddFile
+ base int // Pos value range for this file is [base...base+size]
+ size int // file size as provided to AddFile
+
+ // lines and infos are protected by mutex
+ mutex sync.Mutex
+ lines []int // lines contains the offset of the first character for each line (the first entry is always 0)
+ infos []lineInfo
+}
+
+// Name returns the file name of file f as registered with AddFile.
+func (f *File) Name() string {
+ return f.name
+}
+
+// Base returns the base offset of file f as registered with AddFile.
+func (f *File) Base() int {
+ return f.base
+}
+
+// Size returns the size of file f as registered with AddFile.
+func (f *File) Size() int {
+ return f.size
+}
+
+// LineCount returns the number of lines in file f.
+func (f *File) LineCount() int {
+ f.mutex.Lock()
+ n := len(f.lines)
+ f.mutex.Unlock()
+ return n
+}
+
+// AddLine adds the line offset for a new line.
+// The line offset must be larger than the offset for the previous line
+// and smaller than the file size; otherwise the line offset is ignored.
+func (f *File) AddLine(offset int) {
+ f.mutex.Lock()
+ if i := len(f.lines); (i == 0 || f.lines[i-1] < offset) && offset < f.size {
+ f.lines = append(f.lines, offset)
+ }
+ f.mutex.Unlock()
+}
+
+// MergeLine merges a line with the following line. It is akin to replacing
+// the newline character at the end of the line with a space (to not change the
+// remaining offsets). To obtain the line number, consult e.g. Position.Line.
+// MergeLine will panic if given an invalid line number.
+func (f *File) MergeLine(line int) {
+ if line < 1 {
+ panic(fmt.Sprintf("invalid line number %d (should be >= 1)", line))
+ }
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+ if line >= len(f.lines) {
+ panic(fmt.Sprintf("invalid line number %d (should be < %d)", line, len(f.lines)))
+ }
+ // To merge the line numbered <line> with the line numbered <line+1>,
+ // we need to remove the entry in lines corresponding to the line
+ // numbered <line+1>. The entry in lines corresponding to the line
+ // numbered <line+1> is located at index <line>, since indices in lines
+ // are 0-based and line numbers are 1-based.
+ copy(f.lines[line:], f.lines[line+1:])
+ f.lines = f.lines[:len(f.lines)-1]
+}
+
+// Lines returns the effective line offset table of the form described by SetLines.
+// Callers must not mutate the result.
+func (f *File) Lines() []int {
+ f.mutex.Lock()
+ lines := f.lines
+ f.mutex.Unlock()
+ return lines
+}
+
+// SetLines sets the line offsets for a file and reports whether it succeeded.
+// The line offsets are the offsets of the first character of each line;
+// for instance for the content "ab\nc\n" the line offsets are {0, 3}.
+// An empty file has an empty line offset table.
+// Each line offset must be larger than the offset for the previous line
+// and smaller than the file size; otherwise SetLines fails and returns
+// false.
+// Callers must not mutate the provided slice after SetLines returns.
+func (f *File) SetLines(lines []int) bool {
+ // verify validity of lines table
+ size := f.size
+ for i, offset := range lines {
+ if i > 0 && offset <= lines[i-1] || size <= offset {
+ return false
+ }
+ }
+
+ // set lines table
+ f.mutex.Lock()
+ f.lines = lines
+ f.mutex.Unlock()
+ return true
+}
+
+// SetLinesForContent sets the line offsets for the given file content.
+// It ignores position-altering //line comments.
+func (f *File) SetLinesForContent(content []byte) {
+ var lines []int
+ line := 0
+ for offset, b := range content {
+ if line >= 0 {
+ lines = append(lines, line)
+ }
+ line = -1
+ if b == '\n' {
+ line = offset + 1
+ }
+ }
+
+ // set lines table
+ f.mutex.Lock()
+ f.lines = lines
+ f.mutex.Unlock()
+}
+
+// LineStart returns the Pos value of the start of the specified line.
+// It ignores any alternative positions set using AddLineColumnInfo.
+// LineStart panics if the 1-based line number is invalid.
+func (f *File) LineStart(line int) Pos {
+ if line < 1 {
+ panic(fmt.Sprintf("invalid line number %d (should be >= 1)", line))
+ }
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+ if line > len(f.lines) {
+ panic(fmt.Sprintf("invalid line number %d (should be < %d)", line, len(f.lines)))
+ }
+ return Pos(f.base + f.lines[line-1])
+}
+
+// A lineInfo object describes alternative file, line, and column
+// number information (such as provided via a //line directive)
+// for a given file offset.
+type lineInfo struct {
+ // fields are exported to make them accessible to gob
+ Offset int
+ Filename string
+ Line, Column int
+}
+
+// AddLineInfo is like AddLineColumnInfo with a column = 1 argument.
+// It is here for backward-compatibility for code prior to Go 1.11.
+func (f *File) AddLineInfo(offset int, filename string, line int) {
+ f.AddLineColumnInfo(offset, filename, line, 1)
+}
+
+// AddLineColumnInfo adds alternative file, line, and column number
+// information for a given file offset. The offset must be larger
+// than the offset for the previously added alternative line info
+// and smaller than the file size; otherwise the information is
+// ignored.
+//
+// AddLineColumnInfo is typically used to register alternative position
+// information for line directives such as //line filename:line:column.
+func (f *File) AddLineColumnInfo(offset int, filename string, line, column int) {
+ f.mutex.Lock()
+ if i := len(f.infos); (i == 0 || f.infos[i-1].Offset < offset) && offset < f.size {
+ f.infos = append(f.infos, lineInfo{offset, filename, line, column})
+ }
+ f.mutex.Unlock()
+}
+
+// Pos returns the Pos value for the given file offset;
+// the offset must be <= f.Size().
+// f.Pos(f.Offset(p)) == p.
+func (f *File) Pos(offset int) Pos {
+ if offset > f.size {
+ panic(fmt.Sprintf("invalid file offset %d (should be <= %d)", offset, f.size))
+ }
+ return Pos(f.base + offset)
+}
+
+// Offset returns the offset for the given file position p;
+// p must be a valid Pos value in that file.
+// f.Offset(f.Pos(offset)) == offset.
+func (f *File) Offset(p Pos) int {
+ if int(p) < f.base || int(p) > f.base+f.size {
+ panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d])", p, f.base, f.base+f.size))
+ }
+ return int(p) - f.base
+}
+
+// Line returns the line number for the given file position p;
+// p must be a Pos value in that file or NoPos.
+func (f *File) Line(p Pos) int {
+ return f.Position(p).Line
+}
+
+func searchLineInfos(a []lineInfo, x int) int {
+ return sort.Search(len(a), func(i int) bool { return a[i].Offset > x }) - 1
+}
+
+// unpack returns the filename and line and column number for a file offset.
+// If adjusted is set, unpack will return the filename and line information
+// possibly adjusted by //line comments; otherwise those comments are ignored.
+func (f *File) unpack(offset int, adjusted bool) (filename string, line, column int) {
+ f.mutex.Lock()
+ filename = f.name
+ if i := searchInts(f.lines, offset); i >= 0 {
+ line, column = i+1, offset-f.lines[i]+1
+ }
+ if adjusted && len(f.infos) > 0 {
+ // few files have extra line infos
+ if i := searchLineInfos(f.infos, offset); i >= 0 {
+ alt := &f.infos[i]
+ filename = alt.Filename
+ if i := searchInts(f.lines, alt.Offset); i >= 0 {
+ // i+1 is the line at which the alternative position was recorded
+ d := line - (i + 1) // line distance from alternative position base
+ line = alt.Line + d
+ if alt.Column == 0 {
+ // alternative column is unknown => relative column is unknown
+ // (the current specification for line directives requires
+ // this to apply until the next PosBase/line directive,
+ // not just until the new newline)
+ column = 0
+ } else if d == 0 {
+ // the alternative position base is on the current line
+ // => column is relative to alternative column
+ column = alt.Column + (offset - alt.Offset)
+ }
+ }
+ }
+ }
+ // TODO(mvdan): move Unlock back under Lock with a defer statement once
+ // https://go.dev/issue/38471 is fixed to remove the performance penalty.
+ f.mutex.Unlock()
+ return
+}
+
+func (f *File) position(p Pos, adjusted bool) (pos Position) {
+ offset := int(p) - f.base
+ pos.Offset = offset
+ pos.Filename, pos.Line, pos.Column = f.unpack(offset, adjusted)
+ return
+}
+
+// PositionFor returns the Position value for the given file position p.
+// If adjusted is set, the position may be adjusted by position-altering
+// //line comments; otherwise those comments are ignored.
+// p must be a Pos value in f or NoPos.
+func (f *File) PositionFor(p Pos, adjusted bool) (pos Position) {
+ if p != NoPos {
+ if int(p) < f.base || int(p) > f.base+f.size {
+ panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d])", p, f.base, f.base+f.size))
+ }
+ pos = f.position(p, adjusted)
+ }
+ return
+}
+
+// Position returns the Position value for the given file position p.
+// Calling f.Position(p) is equivalent to calling f.PositionFor(p, true).
+func (f *File) Position(p Pos) (pos Position) {
+ return f.PositionFor(p, true)
+}
+
+// -----------------------------------------------------------------------------
+// FileSet
+
+// A FileSet represents a set of source files.
+// Methods of file sets are synchronized; multiple goroutines
+// may invoke them concurrently.
+//
+// The byte offsets for each file in a file set are mapped into
+// distinct (integer) intervals, one interval [base, base+size]
+// per file. Base represents the first byte in the file, and size
+// is the corresponding file size. A Pos value is a value in such
+// an interval. By determining the interval a Pos value belongs
+// to, the file, its file base, and thus the byte offset (position)
+// the Pos value is representing can be computed.
+//
+// When adding a new file, a file base must be provided. That can
+// be any integer value that is past the end of any interval of any
+// file already in the file set. For convenience, FileSet.Base provides
+// such a value, which is simply the end of the Pos interval of the most
+// recently added file, plus one. Unless there is a need to extend an
+// interval later, using the FileSet.Base should be used as argument
+// for FileSet.AddFile.
+//
+// A File may be removed from a FileSet when it is no longer needed.
+// This may reduce memory usage in a long-running application.
+type FileSet struct {
+ mutex sync.RWMutex // protects the file set
+ base int // base offset for the next file
+ files []*File // list of files in the order added to the set
+ last atomic.Pointer[File] // cache of last file looked up
+}
+
+// NewFileSet creates a new file set.
+func NewFileSet() *FileSet {
+ return &FileSet{
+ base: 1, // 0 == NoPos
+ }
+}
+
+// Base returns the minimum base offset that must be provided to
+// AddFile when adding the next file.
+func (s *FileSet) Base() int {
+ s.mutex.RLock()
+ b := s.base
+ s.mutex.RUnlock()
+ return b
+}
+
+// AddFile adds a new file with a given filename, base offset, and file size
+// to the file set s and returns the file. Multiple files may have the same
+// name. The base offset must not be smaller than the FileSet's Base(), and
+// size must not be negative. As a special case, if a negative base is provided,
+// the current value of the FileSet's Base() is used instead.
+//
+// Adding the file will set the file set's Base() value to base + size + 1
+// as the minimum base value for the next file. The following relationship
+// exists between a Pos value p for a given file offset offs:
+//
+// int(p) = base + offs
+//
+// with offs in the range [0, size] and thus p in the range [base, base+size].
+// For convenience, File.Pos may be used to create file-specific position
+// values from a file offset.
+func (s *FileSet) AddFile(filename string, base, size int) *File {
+ // Allocate f outside the critical section.
+ f := &File{name: filename, size: size, lines: []int{0}}
+
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+ if base < 0 {
+ base = s.base
+ }
+ if base < s.base {
+ panic(fmt.Sprintf("invalid base %d (should be >= %d)", base, s.base))
+ }
+ f.base = base
+ if size < 0 {
+ panic(fmt.Sprintf("invalid size %d (should be >= 0)", size))
+ }
+ // base >= s.base && size >= 0
+ base += size + 1 // +1 because EOF also has a position
+ if base < 0 {
+ panic("token.Pos offset overflow (> 2G of source code in file set)")
+ }
+ // add the file to the file set
+ s.base = base
+ s.files = append(s.files, f)
+ s.last.Store(f)
+ return f
+}
+
+// RemoveFile removes a file from the FileSet so that subsequent
+// queries for its Pos interval yield a negative result.
+// This reduces the memory usage of a long-lived FileSet that
+// encounters an unbounded stream of files.
+//
+// Removing a file that does not belong to the set has no effect.
+func (s *FileSet) RemoveFile(file *File) {
+ s.last.CompareAndSwap(file, nil) // clear last file cache
+
+ s.mutex.Lock()
+ defer s.mutex.Unlock()
+
+ if i := searchFiles(s.files, file.base); i >= 0 && s.files[i] == file {
+ last := &s.files[len(s.files)-1]
+ s.files = append(s.files[:i], s.files[i+1:]...)
+ *last = nil // don't prolong lifetime when popping last element
+ }
+}
+
+// Iterate calls f for the files in the file set in the order they were added
+// until f returns false.
+func (s *FileSet) Iterate(f func(*File) bool) {
+ for i := 0; ; i++ {
+ var file *File
+ s.mutex.RLock()
+ if i < len(s.files) {
+ file = s.files[i]
+ }
+ s.mutex.RUnlock()
+ if file == nil || !f(file) {
+ break
+ }
+ }
+}
+
+func searchFiles(a []*File, x int) int {
+ return sort.Search(len(a), func(i int) bool { return a[i].base > x }) - 1
+}
+
+func (s *FileSet) file(p Pos) *File {
+ // common case: p is in last file.
+ if f := s.last.Load(); f != nil && f.base <= int(p) && int(p) <= f.base+f.size {
+ return f
+ }
+
+ s.mutex.RLock()
+ defer s.mutex.RUnlock()
+
+ // p is not in last file - search all files
+ if i := searchFiles(s.files, int(p)); i >= 0 {
+ f := s.files[i]
+ // f.base <= int(p) by definition of searchFiles
+ if int(p) <= f.base+f.size {
+ // Update cache of last file. A race is ok,
+ // but an exclusive lock causes heavy contention.
+ s.last.Store(f)
+ return f
+ }
+ }
+ return nil
+}
+
+// File returns the file that contains the position p.
+// If no such file is found (for instance for p == NoPos),
+// the result is nil.
+func (s *FileSet) File(p Pos) (f *File) {
+ if p != NoPos {
+ f = s.file(p)
+ }
+ return
+}
+
+// PositionFor converts a Pos p in the fileset into a Position value.
+// If adjusted is set, the position may be adjusted by position-altering
+// //line comments; otherwise those comments are ignored.
+// p must be a Pos value in s or NoPos.
+func (s *FileSet) PositionFor(p Pos, adjusted bool) (pos Position) {
+ if p != NoPos {
+ if f := s.file(p); f != nil {
+ return f.position(p, adjusted)
+ }
+ }
+ return
+}
+
+// Position converts a Pos p in the fileset into a Position value.
+// Calling s.Position(p) is equivalent to calling s.PositionFor(p, true).
+func (s *FileSet) Position(p Pos) (pos Position) {
+ return s.PositionFor(p, true)
+}
+
+// -----------------------------------------------------------------------------
+// Helper functions
+
+func searchInts(a []int, x int) int {
+ // This function body is a manually inlined version of:
+ //
+ // return sort.Search(len(a), func(i int) bool { return a[i] > x }) - 1
+ //
+ // With better compiler optimizations, this may not be needed in the
+ // future, but at the moment this change improves the go/printer
+ // benchmark performance by ~30%. This has a direct impact on the
+ // speed of gofmt and thus seems worthwhile (2011-04-29).
+ // TODO(gri): Remove this when compilers have caught up.
+ i, j := 0, len(a)
+ for i < j {
+ h := int(uint(i+j) >> 1) // avoid overflow when computing h
+ // i ≤ h < j
+ if a[h] <= x {
+ i = h + 1
+ } else {
+ j = h
+ }
+ }
+ return i - 1
+}
diff --git a/contrib/go/_std_1.20/src/go/token/serialize.go b/contrib/go/_std_1.21/src/go/token/serialize.go
index 04a48d90f8..04a48d90f8 100644
--- a/contrib/go/_std_1.20/src/go/token/serialize.go
+++ b/contrib/go/_std_1.21/src/go/token/serialize.go
diff --git a/contrib/go/_std_1.20/src/go/token/token.go b/contrib/go/_std_1.21/src/go/token/token.go
index 3ae10d823c..3ae10d823c 100644
--- a/contrib/go/_std_1.20/src/go/token/token.go
+++ b/contrib/go/_std_1.21/src/go/token/token.go
diff --git a/contrib/go/_std_1.21/src/go/token/ya.make b/contrib/go/_std_1.21/src/go/token/ya.make
new file mode 100644
index 0000000000..ddac5ca927
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/token/ya.make
@@ -0,0 +1,21 @@
+GO_LIBRARY()
+
+SRCS(
+ position.go
+ serialize.go
+ token.go
+)
+
+GO_TEST_SRCS(
+ position_bench_test.go
+ position_test.go
+ serialize_test.go
+ token_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/go/types/api.go b/contrib/go/_std_1.21/src/go/types/api.go
new file mode 100644
index 0000000000..ad4c1a2e9f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/api.go
@@ -0,0 +1,503 @@
+// Copyright 2012 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 types declares the data types and implements
+// the algorithms for type-checking of Go packages. Use
+// Config.Check to invoke the type checker for a package.
+// Alternatively, create a new type checker with NewChecker
+// and invoke it incrementally by calling Checker.Files.
+//
+// Type-checking consists of several interdependent phases:
+//
+// Name resolution maps each identifier (ast.Ident) in the program to the
+// language object (Object) it denotes.
+// Use Info.{Defs,Uses,Implicits} for the results of name resolution.
+//
+// Constant folding computes the exact constant value (constant.Value)
+// for every expression (ast.Expr) that is a compile-time constant.
+// Use Info.Types[expr].Value for the results of constant folding.
+//
+// Type inference computes the type (Type) of every expression (ast.Expr)
+// and checks for compliance with the language specification.
+// Use Info.Types[expr].Type for the results of type inference.
+//
+// For a tutorial, see https://golang.org/s/types-tutorial.
+package types
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/constant"
+ "go/token"
+ . "internal/types/errors"
+)
+
+// An Error describes a type-checking error; it implements the error interface.
+// A "soft" error is an error that still permits a valid interpretation of a
+// package (such as "unused variable"); "hard" errors may lead to unpredictable
+// behavior if ignored.
+type Error struct {
+ Fset *token.FileSet // file set for interpretation of Pos
+ Pos token.Pos // error position
+ Msg string // error message
+ Soft bool // if set, error is "soft"
+
+ // go116code is a future API, unexported as the set of error codes is large
+ // and likely to change significantly during experimentation. Tools wishing
+ // to preview this feature may read go116code using reflection (see
+ // errorcodes_test.go), but beware that there is no guarantee of future
+ // compatibility.
+ go116code Code
+ go116start token.Pos
+ go116end token.Pos
+}
+
+// Error returns an error string formatted as follows:
+// filename:line:column: message
+func (err Error) Error() string {
+ return fmt.Sprintf("%s: %s", err.Fset.Position(err.Pos), err.Msg)
+}
+
+// An ArgumentError holds an error associated with an argument index.
+type ArgumentError struct {
+ Index int
+ Err error
+}
+
+func (e *ArgumentError) Error() string { return e.Err.Error() }
+func (e *ArgumentError) Unwrap() error { return e.Err }
+
+// An Importer resolves import paths to Packages.
+//
+// CAUTION: This interface does not support the import of locally
+// vendored packages. See https://golang.org/s/go15vendor.
+// If possible, external implementations should implement ImporterFrom.
+type Importer interface {
+ // Import returns the imported package for the given import path.
+ // The semantics is like for ImporterFrom.ImportFrom except that
+ // dir and mode are ignored (since they are not present).
+ Import(path string) (*Package, error)
+}
+
+// ImportMode is reserved for future use.
+type ImportMode int
+
+// An ImporterFrom resolves import paths to packages; it
+// supports vendoring per https://golang.org/s/go15vendor.
+// Use go/importer to obtain an ImporterFrom implementation.
+type ImporterFrom interface {
+ // Importer is present for backward-compatibility. Calling
+ // Import(path) is the same as calling ImportFrom(path, "", 0);
+ // i.e., locally vendored packages may not be found.
+ // The types package does not call Import if an ImporterFrom
+ // is present.
+ Importer
+
+ // ImportFrom returns the imported package for the given import
+ // path when imported by a package file located in dir.
+ // If the import failed, besides returning an error, ImportFrom
+ // is encouraged to cache and return a package anyway, if one
+ // was created. This will reduce package inconsistencies and
+ // follow-on type checker errors due to the missing package.
+ // The mode value must be 0; it is reserved for future use.
+ // Two calls to ImportFrom with the same path and dir must
+ // return the same package.
+ ImportFrom(path, dir string, mode ImportMode) (*Package, error)
+}
+
+// A Config specifies the configuration for type checking.
+// The zero value for Config is a ready-to-use default configuration.
+type Config struct {
+ // Context is the context used for resolving global identifiers. If nil, the
+ // type checker will initialize this field with a newly created context.
+ Context *Context
+
+ // GoVersion describes the accepted Go language version. The string must
+ // start with a prefix of the form "go%d.%d" (e.g. "go1.20", "go1.21rc1", or
+ // "go1.21.0") or it must be empty; an empty string disables Go language
+ // version checks. If the format is invalid, invoking the type checker will
+ // result in an error.
+ GoVersion string
+
+ // If IgnoreFuncBodies is set, function bodies are not
+ // type-checked.
+ IgnoreFuncBodies bool
+
+ // If FakeImportC is set, `import "C"` (for packages requiring Cgo)
+ // declares an empty "C" package and errors are omitted for qualified
+ // identifiers referring to package C (which won't find an object).
+ // This feature is intended for the standard library cmd/api tool.
+ //
+ // Caution: Effects may be unpredictable due to follow-on errors.
+ // Do not use casually!
+ FakeImportC bool
+
+ // If go115UsesCgo is set, the type checker expects the
+ // _cgo_gotypes.go file generated by running cmd/cgo to be
+ // provided as a package source file. Qualified identifiers
+ // referring to package C will be resolved to cgo-provided
+ // declarations within _cgo_gotypes.go.
+ //
+ // It is an error to set both FakeImportC and go115UsesCgo.
+ go115UsesCgo bool
+
+ // If _Trace is set, a debug trace is printed to stdout.
+ _Trace bool
+
+ // If Error != nil, it is called with each error found
+ // during type checking; err has dynamic type Error.
+ // Secondary errors (for instance, to enumerate all types
+ // involved in an invalid recursive type declaration) have
+ // error strings that start with a '\t' character.
+ // If Error == nil, type-checking stops with the first
+ // error found.
+ Error func(err error)
+
+ // An importer is used to import packages referred to from
+ // import declarations.
+ // If the installed importer implements ImporterFrom, the type
+ // checker calls ImportFrom instead of Import.
+ // The type checker reports an error if an importer is needed
+ // but none was installed.
+ Importer Importer
+
+ // If Sizes != nil, it provides the sizing functions for package unsafe.
+ // Otherwise SizesFor("gc", "amd64") is used instead.
+ Sizes Sizes
+
+ // If DisableUnusedImportCheck is set, packages are not checked
+ // for unused imports.
+ DisableUnusedImportCheck bool
+
+ // If a non-empty _ErrorURL format string is provided, it is used
+ // to format an error URL link that is appended to the first line
+ // of an error message. ErrorURL must be a format string containing
+ // exactly one "%s" format, e.g. "[go.dev/e/%s]".
+ _ErrorURL string
+}
+
+func srcimporter_setUsesCgo(conf *Config) {
+ conf.go115UsesCgo = true
+}
+
+// Info holds result type information for a type-checked package.
+// Only the information for which a map is provided is collected.
+// If the package has type errors, the collected information may
+// be incomplete.
+type Info struct {
+ // Types maps expressions to their types, and for constant
+ // expressions, also their values. Invalid expressions are
+ // omitted.
+ //
+ // For (possibly parenthesized) identifiers denoting built-in
+ // functions, the recorded signatures are call-site specific:
+ // if the call result is not a constant, the recorded type is
+ // an argument-specific signature. Otherwise, the recorded type
+ // is invalid.
+ //
+ // The Types map does not record the type of every identifier,
+ // only those that appear where an arbitrary expression is
+ // permitted. For instance, the identifier f in a selector
+ // expression x.f is found only in the Selections map, the
+ // identifier z in a variable declaration 'var z int' is found
+ // only in the Defs map, and identifiers denoting packages in
+ // qualified identifiers are collected in the Uses map.
+ Types map[ast.Expr]TypeAndValue
+
+ // Instances maps identifiers denoting generic types or functions to their
+ // type arguments and instantiated type.
+ //
+ // For example, Instances will map the identifier for 'T' in the type
+ // instantiation T[int, string] to the type arguments [int, string] and
+ // resulting instantiated *Named type. Given a generic function
+ // func F[A any](A), Instances will map the identifier for 'F' in the call
+ // expression F(int(1)) to the inferred type arguments [int], and resulting
+ // instantiated *Signature.
+ //
+ // Invariant: Instantiating Uses[id].Type() with Instances[id].TypeArgs
+ // results in an equivalent of Instances[id].Type.
+ Instances map[*ast.Ident]Instance
+
+ // Defs maps identifiers to the objects they define (including
+ // package names, dots "." of dot-imports, and blank "_" identifiers).
+ // For identifiers that do not denote objects (e.g., the package name
+ // in package clauses, or symbolic variables t in t := x.(type) of
+ // type switch headers), the corresponding objects are nil.
+ //
+ // For an embedded field, Defs returns the field *Var it defines.
+ //
+ // Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos()
+ Defs map[*ast.Ident]Object
+
+ // Uses maps identifiers to the objects they denote.
+ //
+ // For an embedded field, Uses returns the *TypeName it denotes.
+ //
+ // Invariant: Uses[id].Pos() != id.Pos()
+ Uses map[*ast.Ident]Object
+
+ // Implicits maps nodes to their implicitly declared objects, if any.
+ // The following node and object types may appear:
+ //
+ // node declared object
+ //
+ // *ast.ImportSpec *PkgName for imports without renames
+ // *ast.CaseClause type-specific *Var for each type switch case clause (incl. default)
+ // *ast.Field anonymous parameter *Var (incl. unnamed results)
+ //
+ Implicits map[ast.Node]Object
+
+ // Selections maps selector expressions (excluding qualified identifiers)
+ // to their corresponding selections.
+ Selections map[*ast.SelectorExpr]*Selection
+
+ // Scopes maps ast.Nodes to the scopes they define. Package scopes are not
+ // associated with a specific node but with all files belonging to a package.
+ // Thus, the package scope can be found in the type-checked Package object.
+ // Scopes nest, with the Universe scope being the outermost scope, enclosing
+ // the package scope, which contains (one or more) files scopes, which enclose
+ // function scopes which in turn enclose statement and function literal scopes.
+ // Note that even though package-level functions are declared in the package
+ // scope, the function scopes are embedded in the file scope of the file
+ // containing the function declaration.
+ //
+ // The following node types may appear in Scopes:
+ //
+ // *ast.File
+ // *ast.FuncType
+ // *ast.TypeSpec
+ // *ast.BlockStmt
+ // *ast.IfStmt
+ // *ast.SwitchStmt
+ // *ast.TypeSwitchStmt
+ // *ast.CaseClause
+ // *ast.CommClause
+ // *ast.ForStmt
+ // *ast.RangeStmt
+ //
+ Scopes map[ast.Node]*Scope
+
+ // InitOrder is the list of package-level initializers in the order in which
+ // they must be executed. Initializers referring to variables related by an
+ // initialization dependency appear in topological order, the others appear
+ // in source order. Variables without an initialization expression do not
+ // appear in this list.
+ InitOrder []*Initializer
+}
+
+func (info *Info) recordTypes() bool {
+ return info.Types != nil
+}
+
+// TypeOf returns the type of expression e, or nil if not found.
+// Precondition: the Types, Uses and Defs maps are populated.
+func (info *Info) TypeOf(e ast.Expr) Type {
+ if t, ok := info.Types[e]; ok {
+ return t.Type
+ }
+ if id, _ := e.(*ast.Ident); id != nil {
+ if obj := info.ObjectOf(id); obj != nil {
+ return obj.Type()
+ }
+ }
+ return nil
+}
+
+// ObjectOf returns the object denoted by the specified id,
+// or nil if not found.
+//
+// If id is an embedded struct field, ObjectOf returns the field (*Var)
+// it defines, not the type (*TypeName) it uses.
+//
+// Precondition: the Uses and Defs maps are populated.
+func (info *Info) ObjectOf(id *ast.Ident) Object {
+ if obj := info.Defs[id]; obj != nil {
+ return obj
+ }
+ return info.Uses[id]
+}
+
+// TypeAndValue reports the type and value (for constants)
+// of the corresponding expression.
+type TypeAndValue struct {
+ mode operandMode
+ Type Type
+ Value constant.Value
+}
+
+// IsVoid reports whether the corresponding expression
+// is a function call without results.
+func (tv TypeAndValue) IsVoid() bool {
+ return tv.mode == novalue
+}
+
+// IsType reports whether the corresponding expression specifies a type.
+func (tv TypeAndValue) IsType() bool {
+ return tv.mode == typexpr
+}
+
+// IsBuiltin reports whether the corresponding expression denotes
+// a (possibly parenthesized) built-in function.
+func (tv TypeAndValue) IsBuiltin() bool {
+ return tv.mode == builtin
+}
+
+// IsValue reports whether the corresponding expression is a value.
+// Builtins are not considered values. Constant values have a non-
+// nil Value.
+func (tv TypeAndValue) IsValue() bool {
+ switch tv.mode {
+ case constant_, variable, mapindex, value, commaok, commaerr:
+ return true
+ }
+ return false
+}
+
+// IsNil reports whether the corresponding expression denotes the
+// predeclared value nil.
+func (tv TypeAndValue) IsNil() bool {
+ return tv.mode == value && tv.Type == Typ[UntypedNil]
+}
+
+// Addressable reports whether the corresponding expression
+// is addressable (https://golang.org/ref/spec#Address_operators).
+func (tv TypeAndValue) Addressable() bool {
+ return tv.mode == variable
+}
+
+// Assignable reports whether the corresponding expression
+// is assignable to (provided a value of the right type).
+func (tv TypeAndValue) Assignable() bool {
+ return tv.mode == variable || tv.mode == mapindex
+}
+
+// HasOk reports whether the corresponding expression may be
+// used on the rhs of a comma-ok assignment.
+func (tv TypeAndValue) HasOk() bool {
+ return tv.mode == commaok || tv.mode == mapindex
+}
+
+// Instance reports the type arguments and instantiated type for type and
+// function instantiations. For type instantiations, Type will be of dynamic
+// type *Named. For function instantiations, Type will be of dynamic type
+// *Signature.
+type Instance struct {
+ TypeArgs *TypeList
+ Type Type
+}
+
+// An Initializer describes a package-level variable, or a list of variables in case
+// of a multi-valued initialization expression, and the corresponding initialization
+// expression.
+type Initializer struct {
+ Lhs []*Var // var Lhs = Rhs
+ Rhs ast.Expr
+}
+
+func (init *Initializer) String() string {
+ var buf bytes.Buffer
+ for i, lhs := range init.Lhs {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ buf.WriteString(lhs.Name())
+ }
+ buf.WriteString(" = ")
+ WriteExpr(&buf, init.Rhs)
+ return buf.String()
+}
+
+// Check type-checks a package and returns the resulting package object and
+// the first error if any. Additionally, if info != nil, Check populates each
+// of the non-nil maps in the Info struct.
+//
+// The package is marked as complete if no errors occurred, otherwise it is
+// incomplete. See Config.Error for controlling behavior in the presence of
+// errors.
+//
+// The package is specified by a list of *ast.Files and corresponding
+// file set, and the package path the package is identified with.
+// The clean path must not be empty or dot (".").
+func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, info *Info) (*Package, error) {
+ pkg := NewPackage(path, "")
+ return pkg, NewChecker(conf, fset, pkg, info).Files(files)
+}
+
+// AssertableTo reports whether a value of type V can be asserted to have type T.
+//
+// The behavior of AssertableTo is unspecified in three cases:
+// - if T is Typ[Invalid]
+// - if V is a generalized interface; i.e., an interface that may only be used
+// as a type constraint in Go code
+// - if T is an uninstantiated generic type
+func AssertableTo(V *Interface, T Type) bool {
+ // Checker.newAssertableTo suppresses errors for invalid types, so we need special
+ // handling here.
+ if T.Underlying() == Typ[Invalid] {
+ return false
+ }
+ return (*Checker)(nil).newAssertableTo(nopos, V, T, nil)
+}
+
+// AssignableTo reports whether a value of type V is assignable to a variable
+// of type T.
+//
+// The behavior of AssignableTo is unspecified if V or T is Typ[Invalid] or an
+// uninstantiated generic type.
+func AssignableTo(V, T Type) bool {
+ x := operand{mode: value, typ: V}
+ ok, _ := x.assignableTo(nil, T, nil) // check not needed for non-constant x
+ return ok
+}
+
+// ConvertibleTo reports whether a value of type V is convertible to a value of
+// type T.
+//
+// The behavior of ConvertibleTo is unspecified if V or T is Typ[Invalid] or an
+// uninstantiated generic type.
+func ConvertibleTo(V, T Type) bool {
+ x := operand{mode: value, typ: V}
+ return x.convertibleTo(nil, T, nil) // check not needed for non-constant x
+}
+
+// Implements reports whether type V implements interface T.
+//
+// The behavior of Implements is unspecified if V is Typ[Invalid] or an uninstantiated
+// generic type.
+func Implements(V Type, T *Interface) bool {
+ if T.Empty() {
+ // All types (even Typ[Invalid]) implement the empty interface.
+ return true
+ }
+ // Checker.implements suppresses errors for invalid types, so we need special
+ // handling here.
+ if V.Underlying() == Typ[Invalid] {
+ return false
+ }
+ return (*Checker)(nil).implements(0, V, T, false, nil)
+}
+
+// Satisfies reports whether type V satisfies the constraint T.
+//
+// The behavior of Satisfies is unspecified if V is Typ[Invalid] or an uninstantiated
+// generic type.
+func Satisfies(V Type, T *Interface) bool {
+ return (*Checker)(nil).implements(0, V, T, true, nil)
+}
+
+// Identical reports whether x and y are identical types.
+// Receivers of Signature types are ignored.
+func Identical(x, y Type) bool {
+ var c comparer
+ return c.identical(x, y, nil)
+}
+
+// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored.
+// Receivers of Signature types are ignored.
+func IdenticalIgnoreTags(x, y Type) bool {
+ var c comparer
+ c.ignoreTags = true
+ return c.identical(x, y, nil)
+}
diff --git a/contrib/go/_std_1.21/src/go/types/array.go b/contrib/go/_std_1.21/src/go/types/array.go
new file mode 100644
index 0000000000..f19ce6e528
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/array.go
@@ -0,0 +1,27 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2011 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 types
+
+// An Array represents an array type.
+type Array struct {
+ len int64
+ elem Type
+}
+
+// NewArray returns a new array type for the given element type and length.
+// A negative length indicates an unknown length.
+func NewArray(elem Type, len int64) *Array { return &Array{len: len, elem: elem} }
+
+// Len returns the length of array a.
+// A negative result indicates an unknown length.
+func (a *Array) Len() int64 { return a.len }
+
+// Elem returns element type of array a.
+func (a *Array) Elem() Type { return a.elem }
+
+func (a *Array) Underlying() Type { return a }
+func (a *Array) String() string { return TypeString(a, nil) }
diff --git a/contrib/go/_std_1.21/src/go/types/assignments.go b/contrib/go/_std_1.21/src/go/types/assignments.go
new file mode 100644
index 0000000000..1ea51142e0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/assignments.go
@@ -0,0 +1,565 @@
+// Copyright 2013 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.
+
+// This file implements initialization and assignment checks.
+
+package types
+
+import (
+ "fmt"
+ "go/ast"
+ . "internal/types/errors"
+ "strings"
+)
+
+// assignment reports whether x can be assigned to a variable of type T,
+// if necessary by attempting to convert untyped values to the appropriate
+// type. context describes the context in which the assignment takes place.
+// Use T == nil to indicate assignment to an untyped blank identifier.
+// If the assignment check fails, x.mode is set to invalid.
+func (check *Checker) assignment(x *operand, T Type, context string) {
+ check.singleValue(x)
+
+ switch x.mode {
+ case invalid:
+ return // error reported before
+ case constant_, variable, mapindex, value, commaok, commaerr:
+ // ok
+ default:
+ // we may get here because of other problems (go.dev/issue/39634, crash 12)
+ // TODO(gri) do we need a new "generic" error code here?
+ check.errorf(x, IncompatibleAssign, "cannot assign %s to %s in %s", x, T, context)
+ x.mode = invalid
+ return
+ }
+
+ if isUntyped(x.typ) {
+ target := T
+ // spec: "If an untyped constant is assigned to a variable of interface
+ // type or the blank identifier, the constant is first converted to type
+ // bool, rune, int, float64, complex128 or string respectively, depending
+ // on whether the value is a boolean, rune, integer, floating-point,
+ // complex, or string constant."
+ if T == nil || isNonTypeParamInterface(T) {
+ if T == nil && x.typ == Typ[UntypedNil] {
+ check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
+ x.mode = invalid
+ return
+ }
+ target = Default(x.typ)
+ }
+ newType, val, code := check.implicitTypeAndValue(x, target)
+ if code != 0 {
+ msg := check.sprintf("cannot use %s as %s value in %s", x, target, context)
+ switch code {
+ case TruncatedFloat:
+ msg += " (truncated)"
+ case NumericOverflow:
+ msg += " (overflows)"
+ default:
+ code = IncompatibleAssign
+ }
+ check.error(x, code, msg)
+ x.mode = invalid
+ return
+ }
+ if val != nil {
+ x.val = val
+ check.updateExprVal(x.expr, val)
+ }
+ if newType != x.typ {
+ x.typ = newType
+ check.updateExprType(x.expr, newType, false)
+ }
+ }
+ // x.typ is typed
+
+ // A generic (non-instantiated) function value cannot be assigned to a variable.
+ if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
+ check.errorf(x, WrongTypeArgCount, "cannot use generic function %s without instantiation in %s", x, context)
+ x.mode = invalid
+ return
+ }
+
+ // spec: "If a left-hand side is the blank identifier, any typed or
+ // non-constant value except for the predeclared identifier nil may
+ // be assigned to it."
+ if T == nil {
+ return
+ }
+
+ cause := ""
+ if ok, code := x.assignableTo(check, T, &cause); !ok {
+ if cause != "" {
+ check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, cause)
+ } else {
+ check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
+ }
+ x.mode = invalid
+ }
+}
+
+func (check *Checker) initConst(lhs *Const, x *operand) {
+ if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
+ if lhs.typ == nil {
+ lhs.typ = Typ[Invalid]
+ }
+ return
+ }
+
+ // rhs must be a constant
+ if x.mode != constant_ {
+ check.errorf(x, InvalidConstInit, "%s is not constant", x)
+ if lhs.typ == nil {
+ lhs.typ = Typ[Invalid]
+ }
+ return
+ }
+ assert(isConstType(x.typ))
+
+ // If the lhs doesn't have a type yet, use the type of x.
+ if lhs.typ == nil {
+ lhs.typ = x.typ
+ }
+
+ check.assignment(x, lhs.typ, "constant declaration")
+ if x.mode == invalid {
+ return
+ }
+
+ lhs.val = x.val
+}
+
+// initVar checks the initialization lhs = x in a variable declaration.
+// If lhs doesn't have a type yet, it is given the type of x,
+// or Typ[Invalid] in case of an error.
+// If the initialization check fails, x.mode is set to invalid.
+func (check *Checker) initVar(lhs *Var, x *operand, context string) {
+ if x.mode == invalid || x.typ == Typ[Invalid] || lhs.typ == Typ[Invalid] {
+ if lhs.typ == nil {
+ lhs.typ = Typ[Invalid]
+ }
+ x.mode = invalid
+ return
+ }
+
+ // If lhs doesn't have a type yet, use the type of x.
+ if lhs.typ == nil {
+ typ := x.typ
+ if isUntyped(typ) {
+ // convert untyped types to default types
+ if typ == Typ[UntypedNil] {
+ check.errorf(x, UntypedNilUse, "use of untyped nil in %s", context)
+ lhs.typ = Typ[Invalid]
+ x.mode = invalid
+ return
+ }
+ typ = Default(typ)
+ }
+ lhs.typ = typ
+ }
+
+ check.assignment(x, lhs.typ, context)
+}
+
+// lhsVar checks a lhs variable in an assignment and returns its type.
+// lhsVar takes care of not counting a lhs identifier as a "use" of
+// that identifier. The result is nil if it is the blank identifier,
+// and Typ[Invalid] if it is an invalid lhs expression.
+func (check *Checker) lhsVar(lhs ast.Expr) Type {
+ // Determine if the lhs is a (possibly parenthesized) identifier.
+ ident, _ := unparen(lhs).(*ast.Ident)
+
+ // Don't evaluate lhs if it is the blank identifier.
+ if ident != nil && ident.Name == "_" {
+ check.recordDef(ident, nil)
+ return nil
+ }
+
+ // If the lhs is an identifier denoting a variable v, this reference
+ // is not a 'use' of v. Remember current value of v.used and restore
+ // after evaluating the lhs via check.expr.
+ var v *Var
+ var v_used bool
+ if ident != nil {
+ if obj := check.lookup(ident.Name); obj != nil {
+ // It's ok to mark non-local variables, but ignore variables
+ // from other packages to avoid potential race conditions with
+ // dot-imported variables.
+ if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
+ v = w
+ v_used = v.used
+ }
+ }
+ }
+
+ var x operand
+ check.expr(nil, &x, lhs)
+
+ if v != nil {
+ v.used = v_used // restore v.used
+ }
+
+ if x.mode == invalid || x.typ == Typ[Invalid] {
+ return Typ[Invalid]
+ }
+
+ // spec: "Each left-hand side operand must be addressable, a map index
+ // expression, or the blank identifier. Operands may be parenthesized."
+ switch x.mode {
+ case invalid:
+ return Typ[Invalid]
+ case variable, mapindex:
+ // ok
+ default:
+ if sel, ok := x.expr.(*ast.SelectorExpr); ok {
+ var op operand
+ check.expr(nil, &op, sel.X)
+ if op.mode == mapindex {
+ check.errorf(&x, UnaddressableFieldAssign, "cannot assign to struct field %s in map", ExprString(x.expr))
+ return Typ[Invalid]
+ }
+ }
+ check.errorf(&x, UnassignableOperand, "cannot assign to %s (neither addressable nor a map index expression)", x.expr)
+ return Typ[Invalid]
+ }
+
+ return x.typ
+}
+
+// assignVar checks the assignment lhs = rhs (if x == nil), or lhs = x (if x != nil).
+// If x != nil, it must be the evaluation of rhs (and rhs will be ignored).
+// If the assignment check fails and x != nil, x.mode is set to invalid.
+func (check *Checker) assignVar(lhs, rhs ast.Expr, x *operand) {
+ T := check.lhsVar(lhs) // nil if lhs is _
+ if T == Typ[Invalid] {
+ if x != nil {
+ x.mode = invalid
+ } else {
+ check.use(rhs)
+ }
+ return
+ }
+
+ if x == nil {
+ x = new(operand)
+ check.expr(T, x, rhs)
+ }
+
+ context := "assignment"
+ if T == nil {
+ context = "assignment to _ identifier"
+ }
+ check.assignment(x, T, context)
+}
+
+// operandTypes returns the list of types for the given operands.
+func operandTypes(list []*operand) (res []Type) {
+ for _, x := range list {
+ res = append(res, x.typ)
+ }
+ return res
+}
+
+// varTypes returns the list of types for the given variables.
+func varTypes(list []*Var) (res []Type) {
+ for _, x := range list {
+ res = append(res, x.typ)
+ }
+ return res
+}
+
+// typesSummary returns a string of the form "(t1, t2, ...)" where the
+// ti's are user-friendly string representations for the given types.
+// If variadic is set and the last type is a slice, its string is of
+// the form "...E" where E is the slice's element type.
+func (check *Checker) typesSummary(list []Type, variadic bool) string {
+ var res []string
+ for i, t := range list {
+ var s string
+ switch {
+ case t == nil:
+ fallthrough // should not happen but be cautious
+ case t == Typ[Invalid]:
+ s = "unknown type"
+ case isUntyped(t):
+ if isNumeric(t) {
+ // Do not imply a specific type requirement:
+ // "have number, want float64" is better than
+ // "have untyped int, want float64" or
+ // "have int, want float64".
+ s = "number"
+ } else {
+ // If we don't have a number, omit the "untyped" qualifier
+ // for compactness.
+ s = strings.Replace(t.(*Basic).name, "untyped ", "", -1)
+ }
+ case variadic && i == len(list)-1:
+ s = check.sprintf("...%s", t.(*Slice).elem)
+ }
+ if s == "" {
+ s = check.sprintf("%s", t)
+ }
+ res = append(res, s)
+ }
+ return "(" + strings.Join(res, ", ") + ")"
+}
+
+func measure(x int, unit string) string {
+ if x != 1 {
+ unit += "s"
+ }
+ return fmt.Sprintf("%d %s", x, unit)
+}
+
+func (check *Checker) assignError(rhs []ast.Expr, l, r int) {
+ vars := measure(l, "variable")
+ vals := measure(r, "value")
+ rhs0 := rhs[0]
+
+ if len(rhs) == 1 {
+ if call, _ := unparen(rhs0).(*ast.CallExpr); call != nil {
+ check.errorf(rhs0, WrongAssignCount, "assignment mismatch: %s but %s returns %s", vars, call.Fun, vals)
+ return
+ }
+ }
+ check.errorf(rhs0, WrongAssignCount, "assignment mismatch: %s but %s", vars, vals)
+}
+
+func (check *Checker) returnError(at positioner, lhs []*Var, rhs []*operand) {
+ l, r := len(lhs), len(rhs)
+ qualifier := "not enough"
+ if r > l {
+ at = rhs[l] // report at first extra value
+ qualifier = "too many"
+ } else if r > 0 {
+ at = rhs[r-1] // report at last value
+ }
+ var err error_
+ err.code = WrongResultCount
+ err.errorf(at.Pos(), "%s return values", qualifier)
+ err.errorf(nopos, "have %s", check.typesSummary(operandTypes(rhs), false))
+ err.errorf(nopos, "want %s", check.typesSummary(varTypes(lhs), false))
+ check.report(&err)
+}
+
+// initVars type-checks assignments of initialization expressions orig_rhs
+// to variables lhs.
+// If returnStmt is non-nil, initVars type-checks the implicit assignment
+// of result expressions orig_rhs to function result parameters lhs.
+func (check *Checker) initVars(lhs []*Var, orig_rhs []ast.Expr, returnStmt ast.Stmt) {
+ context := "assignment"
+ if returnStmt != nil {
+ context = "return statement"
+ }
+
+ l, r := len(lhs), len(orig_rhs)
+
+ // If l == 1 and the rhs is a single call, for a better
+ // error message don't handle it as n:n mapping below.
+ isCall := false
+ if r == 1 {
+ _, isCall = unparen(orig_rhs[0]).(*ast.CallExpr)
+ }
+
+ // If we have a n:n mapping from lhs variable to rhs expression,
+ // each value can be assigned to its corresponding variable.
+ if l == r && !isCall {
+ var x operand
+ for i, lhs := range lhs {
+ check.expr(lhs.typ, &x, orig_rhs[i])
+ check.initVar(lhs, &x, context)
+ }
+ return
+ }
+
+ // If we don't have an n:n mapping, the rhs must be a single expression
+ // resulting in 2 or more values; otherwise we have an assignment mismatch.
+ if r != 1 {
+ // Only report a mismatch error if there are no other errors on the rhs.
+ if check.use(orig_rhs...) {
+ if returnStmt != nil {
+ rhs := check.exprList(orig_rhs)
+ check.returnError(returnStmt, lhs, rhs)
+ } else {
+ check.assignError(orig_rhs, l, r)
+ }
+ }
+ // ensure that LHS variables have a type
+ for _, v := range lhs {
+ if v.typ == nil {
+ v.typ = Typ[Invalid]
+ }
+ }
+ return
+ }
+
+ rhs, commaOk := check.multiExpr(orig_rhs[0], l == 2 && returnStmt == nil)
+ r = len(rhs)
+ if l == r {
+ for i, lhs := range lhs {
+ check.initVar(lhs, rhs[i], context)
+ }
+ // Only record comma-ok expression if both initializations succeeded
+ // (go.dev/issue/59371).
+ if commaOk && rhs[0].mode != invalid && rhs[1].mode != invalid {
+ check.recordCommaOkTypes(orig_rhs[0], rhs)
+ }
+ return
+ }
+
+ // In all other cases we have an assignment mismatch.
+ // Only report a mismatch error if there are no other errors on the rhs.
+ if rhs[0].mode != invalid {
+ if returnStmt != nil {
+ check.returnError(returnStmt, lhs, rhs)
+ } else {
+ check.assignError(orig_rhs, l, r)
+ }
+ }
+ // ensure that LHS variables have a type
+ for _, v := range lhs {
+ if v.typ == nil {
+ v.typ = Typ[Invalid]
+ }
+ }
+ // orig_rhs[0] was already evaluated
+}
+
+// assignVars type-checks assignments of expressions orig_rhs to variables lhs.
+func (check *Checker) assignVars(lhs, orig_rhs []ast.Expr) {
+ l, r := len(lhs), len(orig_rhs)
+
+ // If l == 1 and the rhs is a single call, for a better
+ // error message don't handle it as n:n mapping below.
+ isCall := false
+ if r == 1 {
+ _, isCall = unparen(orig_rhs[0]).(*ast.CallExpr)
+ }
+
+ // If we have a n:n mapping from lhs variable to rhs expression,
+ // each value can be assigned to its corresponding variable.
+ if l == r && !isCall {
+ for i, lhs := range lhs {
+ check.assignVar(lhs, orig_rhs[i], nil)
+ }
+ return
+ }
+
+ // If we don't have an n:n mapping, the rhs must be a single expression
+ // resulting in 2 or more values; otherwise we have an assignment mismatch.
+ if r != 1 {
+ // Only report a mismatch error if there are no other errors on the lhs or rhs.
+ okLHS := check.useLHS(lhs...)
+ okRHS := check.use(orig_rhs...)
+ if okLHS && okRHS {
+ check.assignError(orig_rhs, l, r)
+ }
+ return
+ }
+
+ rhs, commaOk := check.multiExpr(orig_rhs[0], l == 2)
+ r = len(rhs)
+ if l == r {
+ for i, lhs := range lhs {
+ check.assignVar(lhs, nil, rhs[i])
+ }
+ // Only record comma-ok expression if both assignments succeeded
+ // (go.dev/issue/59371).
+ if commaOk && rhs[0].mode != invalid && rhs[1].mode != invalid {
+ check.recordCommaOkTypes(orig_rhs[0], rhs)
+ }
+ return
+ }
+
+ // In all other cases we have an assignment mismatch.
+ // Only report a mismatch error if there are no other errors on the rhs.
+ if rhs[0].mode != invalid {
+ check.assignError(orig_rhs, l, r)
+ }
+ check.useLHS(lhs...)
+ // orig_rhs[0] was already evaluated
+}
+
+func (check *Checker) shortVarDecl(pos positioner, lhs, rhs []ast.Expr) {
+ top := len(check.delayed)
+ scope := check.scope
+
+ // collect lhs variables
+ seen := make(map[string]bool, len(lhs))
+ lhsVars := make([]*Var, len(lhs))
+ newVars := make([]*Var, 0, len(lhs))
+ hasErr := false
+ for i, lhs := range lhs {
+ ident, _ := lhs.(*ast.Ident)
+ if ident == nil {
+ check.useLHS(lhs)
+ // TODO(rFindley) this is redundant with a parser error. Consider omitting?
+ check.errorf(lhs, BadDecl, "non-name %s on left side of :=", lhs)
+ hasErr = true
+ continue
+ }
+
+ name := ident.Name
+ if name != "_" {
+ if seen[name] {
+ check.errorf(lhs, RepeatedDecl, "%s repeated on left side of :=", lhs)
+ hasErr = true
+ continue
+ }
+ seen[name] = true
+ }
+
+ // Use the correct obj if the ident is redeclared. The
+ // variable's scope starts after the declaration; so we
+ // must use Scope.Lookup here and call Scope.Insert
+ // (via check.declare) later.
+ if alt := scope.Lookup(name); alt != nil {
+ check.recordUse(ident, alt)
+ // redeclared object must be a variable
+ if obj, _ := alt.(*Var); obj != nil {
+ lhsVars[i] = obj
+ } else {
+ check.errorf(lhs, UnassignableOperand, "cannot assign to %s", lhs)
+ hasErr = true
+ }
+ continue
+ }
+
+ // declare new variable
+ obj := NewVar(ident.Pos(), check.pkg, name, nil)
+ lhsVars[i] = obj
+ if name != "_" {
+ newVars = append(newVars, obj)
+ }
+ check.recordDef(ident, obj)
+ }
+
+ // create dummy variables where the lhs is invalid
+ for i, obj := range lhsVars {
+ if obj == nil {
+ lhsVars[i] = NewVar(lhs[i].Pos(), check.pkg, "_", nil)
+ }
+ }
+
+ check.initVars(lhsVars, rhs, nil)
+
+ // process function literals in rhs expressions before scope changes
+ check.processDelayed(top)
+
+ if len(newVars) == 0 && !hasErr {
+ check.softErrorf(pos, NoNewVar, "no new variables on left side of :=")
+ return
+ }
+
+ // declare new variables
+ // spec: "The scope of a constant or variable identifier declared inside
+ // a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl
+ // for short variable declarations) and ends at the end of the innermost
+ // containing block."
+ scopePos := rhs[len(rhs)-1].End()
+ for _, obj := range newVars {
+ check.declare(scope, nil, obj, scopePos) // id = nil: recordDef already called
+ }
+}
diff --git a/contrib/go/_std_1.21/src/go/types/basic.go b/contrib/go/_std_1.21/src/go/types/basic.go
new file mode 100644
index 0000000000..d483616413
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/basic.go
@@ -0,0 +1,84 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2011 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 types
+
+// BasicKind describes the kind of basic type.
+type BasicKind int
+
+const (
+ Invalid BasicKind = iota // type is invalid
+
+ // predeclared types
+ Bool
+ Int
+ Int8
+ Int16
+ Int32
+ Int64
+ Uint
+ Uint8
+ Uint16
+ Uint32
+ Uint64
+ Uintptr
+ Float32
+ Float64
+ Complex64
+ Complex128
+ String
+ UnsafePointer
+
+ // types for untyped values
+ UntypedBool
+ UntypedInt
+ UntypedRune
+ UntypedFloat
+ UntypedComplex
+ UntypedString
+ UntypedNil
+
+ // aliases
+ Byte = Uint8
+ Rune = Int32
+)
+
+// BasicInfo is a set of flags describing properties of a basic type.
+type BasicInfo int
+
+// Properties of basic types.
+const (
+ IsBoolean BasicInfo = 1 << iota
+ IsInteger
+ IsUnsigned
+ IsFloat
+ IsComplex
+ IsString
+ IsUntyped
+
+ IsOrdered = IsInteger | IsFloat | IsString
+ IsNumeric = IsInteger | IsFloat | IsComplex
+ IsConstType = IsBoolean | IsNumeric | IsString
+)
+
+// A Basic represents a basic type.
+type Basic struct {
+ kind BasicKind
+ info BasicInfo
+ name string
+}
+
+// Kind returns the kind of basic type b.
+func (b *Basic) Kind() BasicKind { return b.kind }
+
+// Info returns information about properties of basic type b.
+func (b *Basic) Info() BasicInfo { return b.info }
+
+// Name returns the name of basic type b.
+func (b *Basic) Name() string { return b.name }
+
+func (b *Basic) Underlying() Type { return b }
+func (b *Basic) String() string { return TypeString(b, nil) }
diff --git a/contrib/go/_std_1.21/src/go/types/builtins.go b/contrib/go/_std_1.21/src/go/types/builtins.go
new file mode 100644
index 0000000000..11eacef806
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/builtins.go
@@ -0,0 +1,1046 @@
+// Copyright 2012 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.
+
+// This file implements typechecking of builtin function calls.
+
+package types
+
+import (
+ "go/ast"
+ "go/constant"
+ "go/token"
+ . "internal/types/errors"
+)
+
+// builtin type-checks a call to the built-in specified by id and
+// reports whether the call is valid, with *x holding the result;
+// but x.expr is not set. If the call is invalid, the result is
+// false, and *x is undefined.
+func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) {
+ argList := call.Args
+
+ // append is the only built-in that permits the use of ... for the last argument
+ bin := predeclaredFuncs[id]
+ if call.Ellipsis.IsValid() && id != _Append {
+ check.errorf(atPos(call.Ellipsis),
+ InvalidDotDotDot,
+ invalidOp+"invalid use of ... with built-in %s", bin.name)
+ check.use(argList...)
+ return
+ }
+
+ // For len(x) and cap(x) we need to know if x contains any function calls or
+ // receive operations. Save/restore current setting and set hasCallOrRecv to
+ // false for the evaluation of x so that we can check it afterwards.
+ // Note: We must do this _before_ calling exprList because exprList evaluates
+ // all arguments.
+ if id == _Len || id == _Cap {
+ defer func(b bool) {
+ check.hasCallOrRecv = b
+ }(check.hasCallOrRecv)
+ check.hasCallOrRecv = false
+ }
+
+ // Evaluate arguments for built-ins that use ordinary (value) arguments.
+ // For built-ins with special argument handling (make, new, etc.),
+ // evaluation is done by the respective built-in code.
+ var args []*operand // not valid for _Make, _New, _Offsetof, _Trace
+ var nargs int
+ switch id {
+ default:
+ // check all arguments
+ args = check.exprList(argList)
+ nargs = len(args)
+ for _, a := range args {
+ if a.mode == invalid {
+ return
+ }
+ }
+ // first argument is always in x
+ if nargs > 0 {
+ *x = *args[0]
+ }
+ case _Make, _New, _Offsetof, _Trace:
+ // arguments require special handling
+ nargs = len(argList)
+ }
+
+ // check argument count
+ {
+ msg := ""
+ if nargs < bin.nargs {
+ msg = "not enough"
+ } else if !bin.variadic && nargs > bin.nargs {
+ msg = "too many"
+ }
+ if msg != "" {
+ check.errorf(inNode(call, call.Rparen), WrongArgCount, invalidOp+"%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs)
+ return
+ }
+ }
+
+ switch id {
+ case _Append:
+ // append(s S, x ...T) S, where T is the element type of S
+ // spec: "The variadic function append appends zero or more values x to s of type
+ // S, which must be a slice type, and returns the resulting slice, also of type S.
+ // The values x are passed to a parameter of type ...T where T is the element type
+ // of S and the respective parameter passing rules apply."
+ S := x.typ
+ var T Type
+ if s, _ := coreType(S).(*Slice); s != nil {
+ T = s.elem
+ } else {
+ var cause string
+ switch {
+ case x.isNil():
+ cause = "have untyped nil"
+ case isTypeParam(S):
+ if u := coreType(S); u != nil {
+ cause = check.sprintf("%s has core type %s", x, u)
+ } else {
+ cause = check.sprintf("%s has no core type", x)
+ }
+ default:
+ cause = check.sprintf("have %s", x)
+ }
+ // don't use invalidArg prefix here as it would repeat "argument" in the error message
+ check.errorf(x, InvalidAppend, "first argument to append must be a slice; %s", cause)
+ return
+ }
+
+ // spec: "As a special case, append also accepts a first argument assignable
+ // to type []byte with a second argument of string type followed by ... .
+ // This form appends the bytes of the string.
+ if nargs == 2 && call.Ellipsis.IsValid() {
+ if ok, _ := x.assignableTo(check, NewSlice(universeByte), nil); ok {
+ y := args[1]
+ if t := coreString(y.typ); t != nil && isString(t) {
+ if check.recordTypes() {
+ sig := makeSig(S, S, y.typ)
+ sig.variadic = true
+ check.recordBuiltinType(call.Fun, sig)
+ }
+ x.mode = value
+ x.typ = S
+ break
+ }
+ }
+ }
+
+ // check general case by creating custom signature
+ sig := makeSig(S, S, NewSlice(T)) // []T required for variadic signature
+ sig.variadic = true
+ check.arguments(call, sig, nil, nil, args, nil, nil) // discard result (we know the result type)
+ // ok to continue even if check.arguments reported errors
+
+ x.mode = value
+ x.typ = S
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, sig)
+ }
+
+ case _Cap, _Len:
+ // cap(x)
+ // len(x)
+ mode := invalid
+ var val constant.Value
+ switch t := arrayPtrDeref(under(x.typ)).(type) {
+ case *Basic:
+ if isString(t) && id == _Len {
+ if x.mode == constant_ {
+ mode = constant_
+ val = constant.MakeInt64(int64(len(constant.StringVal(x.val))))
+ } else {
+ mode = value
+ }
+ }
+
+ case *Array:
+ mode = value
+ // spec: "The expressions len(s) and cap(s) are constants
+ // if the type of s is an array or pointer to an array and
+ // the expression s does not contain channel receives or
+ // function calls; in this case s is not evaluated."
+ if !check.hasCallOrRecv {
+ mode = constant_
+ if t.len >= 0 {
+ val = constant.MakeInt64(t.len)
+ } else {
+ val = constant.MakeUnknown()
+ }
+ }
+
+ case *Slice, *Chan:
+ mode = value
+
+ case *Map:
+ if id == _Len {
+ mode = value
+ }
+
+ case *Interface:
+ if !isTypeParam(x.typ) {
+ break
+ }
+ if t.typeSet().underIs(func(t Type) bool {
+ switch t := arrayPtrDeref(t).(type) {
+ case *Basic:
+ if isString(t) && id == _Len {
+ return true
+ }
+ case *Array, *Slice, *Chan:
+ return true
+ case *Map:
+ if id == _Len {
+ return true
+ }
+ }
+ return false
+ }) {
+ mode = value
+ }
+ }
+
+ if mode == invalid {
+ // avoid error if underlying type is invalid
+ if under(x.typ) != Typ[Invalid] {
+ code := InvalidCap
+ if id == _Len {
+ code = InvalidLen
+ }
+ check.errorf(x, code, invalidArg+"%s for %s", x, bin.name)
+ }
+ return
+ }
+
+ // record the signature before changing x.typ
+ if check.recordTypes() && mode != constant_ {
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ))
+ }
+
+ x.mode = mode
+ x.typ = Typ[Int]
+ x.val = val
+
+ case _Clear:
+ // clear(m)
+ check.verifyVersionf(call.Fun, go1_21, "clear")
+
+ if !underIs(x.typ, func(u Type) bool {
+ switch u.(type) {
+ case *Map, *Slice:
+ return true
+ }
+ check.errorf(x, InvalidClear, invalidArg+"cannot clear %s: argument must be (or constrained by) map or slice", x)
+ return false
+ }) {
+ return
+ }
+
+ x.mode = novalue
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
+ }
+
+ case _Close:
+ // close(c)
+ if !underIs(x.typ, func(u Type) bool {
+ uch, _ := u.(*Chan)
+ if uch == nil {
+ check.errorf(x, InvalidClose, invalidOp+"cannot close non-channel %s", x)
+ return false
+ }
+ if uch.dir == RecvOnly {
+ check.errorf(x, InvalidClose, invalidOp+"cannot close receive-only channel %s", x)
+ return false
+ }
+ return true
+ }) {
+ return
+ }
+ x.mode = novalue
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(nil, x.typ))
+ }
+
+ case _Complex:
+ // complex(x, y floatT) complexT
+ y := args[1]
+
+ // convert or check untyped arguments
+ d := 0
+ if isUntyped(x.typ) {
+ d |= 1
+ }
+ if isUntyped(y.typ) {
+ d |= 2
+ }
+ switch d {
+ case 0:
+ // x and y are typed => nothing to do
+ case 1:
+ // only x is untyped => convert to type of y
+ check.convertUntyped(x, y.typ)
+ case 2:
+ // only y is untyped => convert to type of x
+ check.convertUntyped(y, x.typ)
+ case 3:
+ // x and y are untyped =>
+ // 1) if both are constants, convert them to untyped
+ // floating-point numbers if possible,
+ // 2) if one of them is not constant (possible because
+ // it contains a shift that is yet untyped), convert
+ // both of them to float64 since they must have the
+ // same type to succeed (this will result in an error
+ // because shifts of floats are not permitted)
+ if x.mode == constant_ && y.mode == constant_ {
+ toFloat := func(x *operand) {
+ if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
+ x.typ = Typ[UntypedFloat]
+ }
+ }
+ toFloat(x)
+ toFloat(y)
+ } else {
+ check.convertUntyped(x, Typ[Float64])
+ check.convertUntyped(y, Typ[Float64])
+ // x and y should be invalid now, but be conservative
+ // and check below
+ }
+ }
+ if x.mode == invalid || y.mode == invalid {
+ return
+ }
+
+ // both argument types must be identical
+ if !Identical(x.typ, y.typ) {
+ check.errorf(x, InvalidComplex, invalidOp+"%v (mismatched types %s and %s)", call, x.typ, y.typ)
+ return
+ }
+
+ // the argument types must be of floating-point type
+ // (applyTypeFunc never calls f with a type parameter)
+ f := func(typ Type) Type {
+ assert(!isTypeParam(typ))
+ if t, _ := under(typ).(*Basic); t != nil {
+ switch t.kind {
+ case Float32:
+ return Typ[Complex64]
+ case Float64:
+ return Typ[Complex128]
+ case UntypedFloat:
+ return Typ[UntypedComplex]
+ }
+ }
+ return nil
+ }
+ resTyp := check.applyTypeFunc(f, x, id)
+ if resTyp == nil {
+ check.errorf(x, InvalidComplex, invalidArg+"arguments have type %s, expected floating-point", x.typ)
+ return
+ }
+
+ // if both arguments are constants, the result is a constant
+ if x.mode == constant_ && y.mode == constant_ {
+ x.val = constant.BinaryOp(constant.ToFloat(x.val), token.ADD, constant.MakeImag(constant.ToFloat(y.val)))
+ } else {
+ x.mode = value
+ }
+
+ if check.recordTypes() && x.mode != constant_ {
+ check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
+ }
+
+ x.typ = resTyp
+
+ case _Copy:
+ // copy(x, y []T) int
+ dst, _ := coreType(x.typ).(*Slice)
+
+ y := args[1]
+ src0 := coreString(y.typ)
+ if src0 != nil && isString(src0) {
+ src0 = NewSlice(universeByte)
+ }
+ src, _ := src0.(*Slice)
+
+ if dst == nil || src == nil {
+ check.errorf(x, InvalidCopy, invalidArg+"copy expects slice arguments; found %s and %s", x, y)
+ return
+ }
+
+ if !Identical(dst.elem, src.elem) {
+ check.errorf(x, InvalidCopy, invalidArg+"arguments to copy %s and %s have different element types %s and %s", x, y, dst.elem, src.elem)
+ return
+ }
+
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
+ }
+ x.mode = value
+ x.typ = Typ[Int]
+
+ case _Delete:
+ // delete(map_, key)
+ // map_ must be a map type or a type parameter describing map types.
+ // The key cannot be a type parameter for now.
+ map_ := x.typ
+ var key Type
+ if !underIs(map_, func(u Type) bool {
+ map_, _ := u.(*Map)
+ if map_ == nil {
+ check.errorf(x, InvalidDelete, invalidArg+"%s is not a map", x)
+ return false
+ }
+ if key != nil && !Identical(map_.key, key) {
+ check.errorf(x, InvalidDelete, invalidArg+"maps of %s must have identical key types", x)
+ return false
+ }
+ key = map_.key
+ return true
+ }) {
+ return
+ }
+
+ *x = *args[1] // key
+ check.assignment(x, key, "argument to delete")
+ if x.mode == invalid {
+ return
+ }
+
+ x.mode = novalue
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(nil, map_, key))
+ }
+
+ case _Imag, _Real:
+ // imag(complexT) floatT
+ // real(complexT) floatT
+
+ // convert or check untyped argument
+ if isUntyped(x.typ) {
+ if x.mode == constant_ {
+ // an untyped constant number can always be considered
+ // as a complex constant
+ if isNumeric(x.typ) {
+ x.typ = Typ[UntypedComplex]
+ }
+ } else {
+ // an untyped non-constant argument may appear if
+ // it contains a (yet untyped non-constant) shift
+ // expression: convert it to complex128 which will
+ // result in an error (shift of complex value)
+ check.convertUntyped(x, Typ[Complex128])
+ // x should be invalid now, but be conservative and check
+ if x.mode == invalid {
+ return
+ }
+ }
+ }
+
+ // the argument must be of complex type
+ // (applyTypeFunc never calls f with a type parameter)
+ f := func(typ Type) Type {
+ assert(!isTypeParam(typ))
+ if t, _ := under(typ).(*Basic); t != nil {
+ switch t.kind {
+ case Complex64:
+ return Typ[Float32]
+ case Complex128:
+ return Typ[Float64]
+ case UntypedComplex:
+ return Typ[UntypedFloat]
+ }
+ }
+ return nil
+ }
+ resTyp := check.applyTypeFunc(f, x, id)
+ if resTyp == nil {
+ code := InvalidImag
+ if id == _Real {
+ code = InvalidReal
+ }
+ check.errorf(x, code, invalidArg+"argument has type %s, expected complex type", x.typ)
+ return
+ }
+
+ // if the argument is a constant, the result is a constant
+ if x.mode == constant_ {
+ if id == _Real {
+ x.val = constant.Real(x.val)
+ } else {
+ x.val = constant.Imag(x.val)
+ }
+ } else {
+ x.mode = value
+ }
+
+ if check.recordTypes() && x.mode != constant_ {
+ check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
+ }
+
+ x.typ = resTyp
+
+ case _Make:
+ // make(T, n)
+ // make(T, n, m)
+ // (no argument evaluated yet)
+ arg0 := argList[0]
+ T := check.varType(arg0)
+ if T == Typ[Invalid] {
+ return
+ }
+
+ var min int // minimum number of arguments
+ switch coreType(T).(type) {
+ case *Slice:
+ min = 2
+ case *Map, *Chan:
+ min = 1
+ case nil:
+ check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s: no core type", arg0)
+ return
+ default:
+ check.errorf(arg0, InvalidMake, invalidArg+"cannot make %s; type must be slice, map, or channel", arg0)
+ return
+ }
+ if nargs < min || min+1 < nargs {
+ check.errorf(call, WrongArgCount, invalidOp+"%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
+ return
+ }
+
+ types := []Type{T}
+ var sizes []int64 // constant integer arguments, if any
+ for _, arg := range argList[1:] {
+ typ, size := check.index(arg, -1) // ok to continue with typ == Typ[Invalid]
+ types = append(types, typ)
+ if size >= 0 {
+ sizes = append(sizes, size)
+ }
+ }
+ if len(sizes) == 2 && sizes[0] > sizes[1] {
+ check.error(argList[1], SwappedMakeArgs, invalidArg+"length and capacity swapped")
+ // safe to continue
+ }
+ x.mode = value
+ x.typ = T
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
+ }
+
+ case _Max, _Min:
+ // max(x, ...)
+ // min(x, ...)
+ check.verifyVersionf(call.Fun, go1_21, bin.name)
+
+ op := token.LSS
+ if id == _Max {
+ op = token.GTR
+ }
+
+ for i, a := range args {
+ if a.mode == invalid {
+ return
+ }
+
+ if !allOrdered(a.typ) {
+ check.errorf(a, InvalidMinMaxOperand, invalidArg+"%s cannot be ordered", a)
+ return
+ }
+
+ // The first argument is already in x and there's nothing left to do.
+ if i > 0 {
+ check.matchTypes(x, a)
+ if x.mode == invalid {
+ return
+ }
+
+ if !Identical(x.typ, a.typ) {
+ check.errorf(a, MismatchedTypes, invalidArg+"mismatched types %s (previous argument) and %s (type of %s)", x.typ, a.typ, a.expr)
+ return
+ }
+
+ if x.mode == constant_ && a.mode == constant_ {
+ if constant.Compare(a.val, op, x.val) {
+ *x = *a
+ }
+ } else {
+ x.mode = value
+ }
+ }
+ }
+
+ // If nargs == 1, make sure x.mode is either a value or a constant.
+ if x.mode != constant_ {
+ x.mode = value
+ // A value must not be untyped.
+ check.assignment(x, &emptyInterface, "argument to "+bin.name)
+ if x.mode == invalid {
+ return
+ }
+ }
+
+ // Use the final type computed above for all arguments.
+ for _, a := range args {
+ check.updateExprType(a.expr, x.typ, true)
+ }
+
+ if check.recordTypes() && x.mode != constant_ {
+ types := make([]Type, nargs)
+ for i := range types {
+ types[i] = x.typ
+ }
+ check.recordBuiltinType(call.Fun, makeSig(x.typ, types...))
+ }
+
+ case _New:
+ // new(T)
+ // (no argument evaluated yet)
+ T := check.varType(argList[0])
+ if T == Typ[Invalid] {
+ return
+ }
+
+ x.mode = value
+ x.typ = &Pointer{base: T}
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
+ }
+
+ case _Panic:
+ // panic(x)
+ // record panic call if inside a function with result parameters
+ // (for use in Checker.isTerminating)
+ if check.sig != nil && check.sig.results.Len() > 0 {
+ // function has result parameters
+ p := check.isPanic
+ if p == nil {
+ // allocate lazily
+ p = make(map[*ast.CallExpr]bool)
+ check.isPanic = p
+ }
+ p[call] = true
+ }
+
+ check.assignment(x, &emptyInterface, "argument to panic")
+ if x.mode == invalid {
+ return
+ }
+
+ x.mode = novalue
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
+ }
+
+ case _Print, _Println:
+ // print(x, y, ...)
+ // println(x, y, ...)
+ var params []Type
+ if nargs > 0 {
+ params = make([]Type, nargs)
+ for i, a := range args {
+ check.assignment(a, nil, "argument to "+predeclaredFuncs[id].name)
+ if a.mode == invalid {
+ return
+ }
+ params[i] = a.typ
+ }
+ }
+
+ x.mode = novalue
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(nil, params...))
+ }
+
+ case _Recover:
+ // recover() interface{}
+ x.mode = value
+ x.typ = &emptyInterface
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(x.typ))
+ }
+
+ case _Add:
+ // unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer
+ check.verifyVersionf(call.Fun, go1_17, "unsafe.Add")
+
+ check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add")
+ if x.mode == invalid {
+ return
+ }
+
+ y := args[1]
+ if !check.isValidIndex(y, InvalidUnsafeAdd, "length", true) {
+ return
+ }
+
+ x.mode = value
+ x.typ = Typ[UnsafePointer]
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(x.typ, x.typ, y.typ))
+ }
+
+ case _Alignof:
+ // unsafe.Alignof(x T) uintptr
+ check.assignment(x, nil, "argument to unsafe.Alignof")
+ if x.mode == invalid {
+ return
+ }
+
+ if hasVarSize(x.typ, nil) {
+ x.mode = value
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
+ }
+ } else {
+ x.mode = constant_
+ x.val = constant.MakeInt64(check.conf.alignof(x.typ))
+ // result is constant - no need to record signature
+ }
+ x.typ = Typ[Uintptr]
+
+ case _Offsetof:
+ // unsafe.Offsetof(x T) uintptr, where x must be a selector
+ // (no argument evaluated yet)
+ arg0 := argList[0]
+ selx, _ := unparen(arg0).(*ast.SelectorExpr)
+ if selx == nil {
+ check.errorf(arg0, BadOffsetofSyntax, invalidArg+"%s is not a selector expression", arg0)
+ check.use(arg0)
+ return
+ }
+
+ check.expr(nil, x, selx.X)
+ if x.mode == invalid {
+ return
+ }
+
+ base := derefStructPtr(x.typ)
+ sel := selx.Sel.Name
+ obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
+ switch obj.(type) {
+ case nil:
+ check.errorf(x, MissingFieldOrMethod, invalidArg+"%s has no single field %s", base, sel)
+ return
+ case *Func:
+ // TODO(gri) Using derefStructPtr may result in methods being found
+ // that don't actually exist. An error either way, but the error
+ // message is confusing. See: https://play.golang.org/p/al75v23kUy ,
+ // but go/types reports: "invalid argument: x.m is a method value".
+ check.errorf(arg0, InvalidOffsetof, invalidArg+"%s is a method value", arg0)
+ return
+ }
+ if indirect {
+ check.errorf(x, InvalidOffsetof, invalidArg+"field %s is embedded via a pointer in %s", sel, base)
+ return
+ }
+
+ // TODO(gri) Should we pass x.typ instead of base (and have indirect report if derefStructPtr indirected)?
+ check.recordSelection(selx, FieldVal, base, obj, index, false)
+
+ // record the selector expression (was bug - go.dev/issue/47895)
+ {
+ mode := value
+ if x.mode == variable || indirect {
+ mode = variable
+ }
+ check.record(&operand{mode, selx, obj.Type(), nil, 0})
+ }
+
+ // The field offset is considered a variable even if the field is declared before
+ // the part of the struct which is variable-sized. This makes both the rules
+ // simpler and also permits (or at least doesn't prevent) a compiler from re-
+ // arranging struct fields if it wanted to.
+ if hasVarSize(base, nil) {
+ x.mode = value
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], obj.Type()))
+ }
+ } else {
+ offs := check.conf.offsetof(base, index)
+ if offs < 0 {
+ check.errorf(x, TypeTooLarge, "%s is too large", x)
+ return
+ }
+ x.mode = constant_
+ x.val = constant.MakeInt64(offs)
+ // result is constant - no need to record signature
+ }
+ x.typ = Typ[Uintptr]
+
+ case _Sizeof:
+ // unsafe.Sizeof(x T) uintptr
+ check.assignment(x, nil, "argument to unsafe.Sizeof")
+ if x.mode == invalid {
+ return
+ }
+
+ if hasVarSize(x.typ, nil) {
+ x.mode = value
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(Typ[Uintptr], x.typ))
+ }
+ } else {
+ size := check.conf.sizeof(x.typ)
+ if size < 0 {
+ check.errorf(x, TypeTooLarge, "%s is too large", x)
+ return
+ }
+ x.mode = constant_
+ x.val = constant.MakeInt64(size)
+ // result is constant - no need to record signature
+ }
+ x.typ = Typ[Uintptr]
+
+ case _Slice:
+ // unsafe.Slice(ptr *T, len IntegerType) []T
+ check.verifyVersionf(call.Fun, go1_17, "unsafe.Slice")
+
+ ptr, _ := under(x.typ).(*Pointer) // TODO(gri) should this be coreType rather than under?
+ if ptr == nil {
+ check.errorf(x, InvalidUnsafeSlice, invalidArg+"%s is not a pointer", x)
+ return
+ }
+
+ y := args[1]
+ if !check.isValidIndex(y, InvalidUnsafeSlice, "length", false) {
+ return
+ }
+
+ x.mode = value
+ x.typ = NewSlice(ptr.base)
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(x.typ, ptr, y.typ))
+ }
+
+ case _SliceData:
+ // unsafe.SliceData(slice []T) *T
+ check.verifyVersionf(call.Fun, go1_20, "unsafe.SliceData")
+
+ slice, _ := under(x.typ).(*Slice) // TODO(gri) should this be coreType rather than under?
+ if slice == nil {
+ check.errorf(x, InvalidUnsafeSliceData, invalidArg+"%s is not a slice", x)
+ return
+ }
+
+ x.mode = value
+ x.typ = NewPointer(slice.elem)
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(x.typ, slice))
+ }
+
+ case _String:
+ // unsafe.String(ptr *byte, len IntegerType) string
+ check.verifyVersionf(call.Fun, go1_20, "unsafe.String")
+
+ check.assignment(x, NewPointer(universeByte), "argument to unsafe.String")
+ if x.mode == invalid {
+ return
+ }
+
+ y := args[1]
+ if !check.isValidIndex(y, InvalidUnsafeString, "length", false) {
+ return
+ }
+
+ x.mode = value
+ x.typ = Typ[String]
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(x.typ, NewPointer(universeByte), y.typ))
+ }
+
+ case _StringData:
+ // unsafe.StringData(str string) *byte
+ check.verifyVersionf(call.Fun, go1_20, "unsafe.StringData")
+
+ check.assignment(x, Typ[String], "argument to unsafe.StringData")
+ if x.mode == invalid {
+ return
+ }
+
+ x.mode = value
+ x.typ = NewPointer(universeByte)
+ if check.recordTypes() {
+ check.recordBuiltinType(call.Fun, makeSig(x.typ, Typ[String]))
+ }
+
+ case _Assert:
+ // assert(pred) causes a typechecker error if pred is false.
+ // The result of assert is the value of pred if there is no error.
+ // Note: assert is only available in self-test mode.
+ if x.mode != constant_ || !isBoolean(x.typ) {
+ check.errorf(x, Test, invalidArg+"%s is not a boolean constant", x)
+ return
+ }
+ if x.val.Kind() != constant.Bool {
+ check.errorf(x, Test, "internal error: value of %s should be a boolean constant", x)
+ return
+ }
+ if !constant.BoolVal(x.val) {
+ check.errorf(call, Test, "%v failed", call)
+ // compile-time assertion failure - safe to continue
+ }
+ // result is constant - no need to record signature
+
+ case _Trace:
+ // trace(x, y, z, ...) dumps the positions, expressions, and
+ // values of its arguments. The result of trace is the value
+ // of the first argument.
+ // Note: trace is only available in self-test mode.
+ // (no argument evaluated yet)
+ if nargs == 0 {
+ check.dump("%v: trace() without arguments", call.Pos())
+ x.mode = novalue
+ break
+ }
+ var t operand
+ x1 := x
+ for _, arg := range argList {
+ check.rawExpr(nil, x1, arg, nil, false) // permit trace for types, e.g.: new(trace(T))
+ check.dump("%v: %s", x1.Pos(), x1)
+ x1 = &t // use incoming x only for first argument
+ }
+ if x.mode == invalid {
+ return
+ }
+ // trace is only available in test mode - no need to record signature
+
+ default:
+ unreachable()
+ }
+
+ assert(x.mode != invalid)
+ return true
+}
+
+// hasVarSize reports if the size of type t is variable due to type parameters
+// or if the type is infinitely-sized due to a cycle for which the type has not
+// yet been checked.
+func hasVarSize(t Type, seen map[*Named]bool) (varSized bool) {
+ // Cycles are only possible through *Named types.
+ // The seen map is used to detect cycles and track
+ // the results of previously seen types.
+ if named, _ := t.(*Named); named != nil {
+ if v, ok := seen[named]; ok {
+ return v
+ }
+ if seen == nil {
+ seen = make(map[*Named]bool)
+ }
+ seen[named] = true // possibly cyclic until proven otherwise
+ defer func() {
+ seen[named] = varSized // record final determination for named
+ }()
+ }
+
+ switch u := under(t).(type) {
+ case *Array:
+ return hasVarSize(u.elem, seen)
+ case *Struct:
+ for _, f := range u.fields {
+ if hasVarSize(f.typ, seen) {
+ return true
+ }
+ }
+ case *Interface:
+ return isTypeParam(t)
+ case *Named, *Union:
+ unreachable()
+ }
+ return false
+}
+
+// applyTypeFunc applies f to x. If x is a type parameter,
+// the result is a type parameter constrained by an new
+// interface bound. The type bounds for that interface
+// are computed by applying f to each of the type bounds
+// of x. If any of these applications of f return nil,
+// applyTypeFunc returns nil.
+// If x is not a type parameter, the result is f(x).
+func (check *Checker) applyTypeFunc(f func(Type) Type, x *operand, id builtinId) Type {
+ if tp, _ := x.typ.(*TypeParam); tp != nil {
+ // Test if t satisfies the requirements for the argument
+ // type and collect possible result types at the same time.
+ var terms []*Term
+ if !tp.is(func(t *term) bool {
+ if t == nil {
+ return false
+ }
+ if r := f(t.typ); r != nil {
+ terms = append(terms, NewTerm(t.tilde, r))
+ return true
+ }
+ return false
+ }) {
+ return nil
+ }
+
+ // We can type-check this fine but we're introducing a synthetic
+ // type parameter for the result. It's not clear what the API
+ // implications are here. Report an error for 1.18 (see go.dev/issue/50912),
+ // but continue type-checking.
+ var code Code
+ switch id {
+ case _Real:
+ code = InvalidReal
+ case _Imag:
+ code = InvalidImag
+ case _Complex:
+ code = InvalidComplex
+ default:
+ unreachable()
+ }
+ check.softErrorf(x, code, "%s not supported as argument to %s for go1.18 (see go.dev/issue/50937)", x, predeclaredFuncs[id].name)
+
+ // Construct a suitable new type parameter for the result type.
+ // The type parameter is placed in the current package so export/import
+ // works as expected.
+ tpar := NewTypeName(nopos, check.pkg, tp.obj.name, nil)
+ ptyp := check.newTypeParam(tpar, NewInterfaceType(nil, []Type{NewUnion(terms)})) // assigns type to tpar as a side-effect
+ ptyp.index = tp.index
+
+ return ptyp
+ }
+
+ return f(x.typ)
+}
+
+// makeSig makes a signature for the given argument and result types.
+// Default types are used for untyped arguments, and res may be nil.
+func makeSig(res Type, args ...Type) *Signature {
+ list := make([]*Var, len(args))
+ for i, param := range args {
+ list[i] = NewVar(nopos, nil, "", Default(param))
+ }
+ params := NewTuple(list...)
+ var result *Tuple
+ if res != nil {
+ assert(!isUntyped(res))
+ result = NewTuple(NewVar(nopos, nil, "", res))
+ }
+ return &Signature{params: params, results: result}
+}
+
+// arrayPtrDeref returns A if typ is of the form *A and A is an array;
+// otherwise it returns typ.
+func arrayPtrDeref(typ Type) Type {
+ if p, ok := typ.(*Pointer); ok {
+ if a, _ := under(p.base).(*Array); a != nil {
+ return a
+ }
+ }
+ return typ
+}
+
+// unparen returns e with any enclosing parentheses stripped.
+func unparen(e ast.Expr) ast.Expr {
+ for {
+ p, ok := e.(*ast.ParenExpr)
+ if !ok {
+ return e
+ }
+ e = p.X
+ }
+}
diff --git a/contrib/go/_std_1.21/src/go/types/call.go b/contrib/go/_std_1.21/src/go/types/call.go
new file mode 100644
index 0000000000..8a3cec7309
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/call.go
@@ -0,0 +1,1037 @@
+// Copyright 2013 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.
+
+// This file implements typechecking of call and selector expressions.
+
+package types
+
+import (
+ "go/ast"
+ "go/internal/typeparams"
+ "go/token"
+ . "internal/types/errors"
+ "strings"
+ "unicode"
+)
+
+// funcInst type-checks a function instantiation.
+// The incoming x must be a generic function.
+// If ix != nil, it provides some or all of the type arguments (ix.Indices).
+// If target type tsig != nil, the signature may be used to infer missing type
+// arguments of x, if any. At least one of tsig or inst must be provided.
+//
+// There are two modes of operation:
+//
+// 1. If infer == true, funcInst infers missing type arguments as needed and
+// instantiates the function x. The returned results are nil.
+//
+// 2. If infer == false and inst provides all type arguments, funcInst
+// instantiates the function x. The returned results are nil.
+// If inst doesn't provide enough type arguments, funcInst returns the
+// available arguments and the corresponding expression list; x remains
+// unchanged.
+//
+// If an error (other than a version error) occurs in any case, it is reported
+// and x.mode is set to invalid.
+func (check *Checker) funcInst(tsig *Signature, pos token.Pos, x *operand, ix *typeparams.IndexExpr, infer bool) ([]Type, []ast.Expr) {
+ assert(tsig != nil || ix != nil)
+
+ var instErrPos positioner
+ if ix != nil {
+ instErrPos = inNode(ix.Orig, ix.Lbrack)
+ } else {
+ instErrPos = atPos(pos)
+ }
+ versionErr := !check.verifyVersionf(instErrPos, go1_18, "function instantiation")
+
+ // targs and xlist are the type arguments and corresponding type expressions, or nil.
+ var targs []Type
+ var xlist []ast.Expr
+ if ix != nil {
+ xlist = ix.Indices
+ targs = check.typeList(xlist)
+ if targs == nil {
+ x.mode = invalid
+ x.expr = ix
+ return nil, nil
+ }
+ assert(len(targs) == len(xlist))
+ }
+
+ // Check the number of type arguments (got) vs number of type parameters (want).
+ // Note that x is a function value, not a type expression, so we don't need to
+ // call under below.
+ sig := x.typ.(*Signature)
+ got, want := len(targs), sig.TypeParams().Len()
+ if got > want {
+ // Providing too many type arguments is always an error.
+ check.errorf(ix.Indices[got-1], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
+ x.mode = invalid
+ x.expr = ix.Orig
+ return nil, nil
+ }
+
+ if got < want {
+ if !infer {
+ return targs, xlist
+ }
+
+ // If the uninstantiated or partially instantiated function x is used in
+ // an assignment (tsig != nil), infer missing type arguments by treating
+ // the assignment
+ //
+ // var tvar tsig = x
+ //
+ // like a call g(tvar) of the synthetic generic function g
+ //
+ // func g[type_parameters_of_x](func_type_of_x)
+ //
+ var args []*operand
+ var params []*Var
+ if tsig != nil && sig.tparams != nil {
+ if !versionErr && !check.allowVersion(check.pkg, instErrPos, go1_21) {
+ if ix != nil {
+ check.versionErrorf(instErrPos, go1_21, "partially instantiated function in assignment")
+ } else {
+ check.versionErrorf(instErrPos, go1_21, "implicitly instantiated function in assignment")
+ }
+ }
+ gsig := NewSignatureType(nil, nil, nil, sig.params, sig.results, sig.variadic)
+ params = []*Var{NewVar(x.Pos(), check.pkg, "", gsig)}
+ // The type of the argument operand is tsig, which is the type of the LHS in an assignment
+ // or the result type in a return statement. Create a pseudo-expression for that operand
+ // that makes sense when reported in error messages from infer, below.
+ expr := ast.NewIdent("variable in assignment")
+ expr.NamePos = x.Pos() // correct position
+ args = []*operand{{mode: value, expr: expr, typ: tsig}}
+ }
+
+ // Rename type parameters to avoid problems with recursive instantiations.
+ // Note that NewTuple(params...) below is (*Tuple)(nil) if len(params) == 0, as desired.
+ tparams, params2 := check.renameTParams(pos, sig.TypeParams().list(), NewTuple(params...))
+
+ targs = check.infer(atPos(pos), tparams, targs, params2.(*Tuple), args)
+ if targs == nil {
+ // error was already reported
+ x.mode = invalid
+ x.expr = ix // TODO(gri) is this correct?
+ return nil, nil
+ }
+ got = len(targs)
+ }
+ assert(got == want)
+
+ // instantiate function signature
+ expr := x.expr // if we don't have an index expression, keep the existing expression of x
+ if ix != nil {
+ expr = ix.Orig
+ }
+ sig = check.instantiateSignature(x.Pos(), expr, sig, targs, xlist)
+
+ x.typ = sig
+ x.mode = value
+ x.expr = expr
+ return nil, nil
+}
+
+func (check *Checker) instantiateSignature(pos token.Pos, expr ast.Expr, typ *Signature, targs []Type, xlist []ast.Expr) (res *Signature) {
+ assert(check != nil)
+ assert(len(targs) == typ.TypeParams().Len())
+
+ if check.conf._Trace {
+ check.trace(pos, "-- instantiating signature %s with %s", typ, targs)
+ check.indent++
+ defer func() {
+ check.indent--
+ check.trace(pos, "=> %s (under = %s)", res, res.Underlying())
+ }()
+ }
+
+ inst := check.instance(pos, typ, targs, nil, check.context()).(*Signature)
+ assert(inst.TypeParams().Len() == 0) // signature is not generic anymore
+ check.recordInstance(expr, targs, inst)
+ assert(len(xlist) <= len(targs))
+
+ // verify instantiation lazily (was go.dev/issue/50450)
+ check.later(func() {
+ tparams := typ.TypeParams().list()
+ if i, err := check.verify(pos, tparams, targs, check.context()); err != nil {
+ // best position for error reporting
+ pos := pos
+ if i < len(xlist) {
+ pos = xlist[i].Pos()
+ }
+ check.softErrorf(atPos(pos), InvalidTypeArg, "%s", err)
+ } else {
+ check.mono.recordInstance(check.pkg, pos, tparams, targs, xlist)
+ }
+ }).describef(atPos(pos), "verify instantiation")
+
+ return inst
+}
+
+func (check *Checker) callExpr(x *operand, call *ast.CallExpr) exprKind {
+ ix := typeparams.UnpackIndexExpr(call.Fun)
+ if ix != nil {
+ if check.indexExpr(x, ix) {
+ // Delay function instantiation to argument checking,
+ // where we combine type and value arguments for type
+ // inference.
+ assert(x.mode == value)
+ } else {
+ ix = nil
+ }
+ x.expr = call.Fun
+ check.record(x)
+ } else {
+ check.exprOrType(x, call.Fun, true)
+ }
+ // x.typ may be generic
+
+ switch x.mode {
+ case invalid:
+ check.use(call.Args...)
+ x.expr = call
+ return statement
+
+ case typexpr:
+ // conversion
+ check.nonGeneric(nil, x)
+ if x.mode == invalid {
+ return conversion
+ }
+ T := x.typ
+ x.mode = invalid
+ switch n := len(call.Args); n {
+ case 0:
+ check.errorf(inNode(call, call.Rparen), WrongArgCount, "missing argument in conversion to %s", T)
+ case 1:
+ check.expr(nil, x, call.Args[0])
+ if x.mode != invalid {
+ if call.Ellipsis.IsValid() {
+ check.errorf(call.Args[0], BadDotDotDotSyntax, "invalid use of ... in conversion to %s", T)
+ break
+ }
+ if t, _ := under(T).(*Interface); t != nil && !isTypeParam(T) {
+ if !t.IsMethodSet() {
+ check.errorf(call, MisplacedConstraintIface, "cannot use interface %s in conversion (contains specific type constraints or is comparable)", T)
+ break
+ }
+ }
+ check.conversion(x, T)
+ }
+ default:
+ check.use(call.Args...)
+ check.errorf(call.Args[n-1], WrongArgCount, "too many arguments in conversion to %s", T)
+ }
+ x.expr = call
+ return conversion
+
+ case builtin:
+ // no need to check for non-genericity here
+ id := x.id
+ if !check.builtin(x, call, id) {
+ x.mode = invalid
+ }
+ x.expr = call
+ // a non-constant result implies a function call
+ if x.mode != invalid && x.mode != constant_ {
+ check.hasCallOrRecv = true
+ }
+ return predeclaredFuncs[id].kind
+ }
+
+ // ordinary function/method call
+ // signature may be generic
+ cgocall := x.mode == cgofunc
+
+ // a type parameter may be "called" if all types have the same signature
+ sig, _ := coreType(x.typ).(*Signature)
+ if sig == nil {
+ check.errorf(x, InvalidCall, invalidOp+"cannot call non-function %s", x)
+ x.mode = invalid
+ x.expr = call
+ return statement
+ }
+
+ // Capture wasGeneric before sig is potentially instantiated below.
+ wasGeneric := sig.TypeParams().Len() > 0
+
+ // evaluate type arguments, if any
+ var xlist []ast.Expr
+ var targs []Type
+ if ix != nil {
+ xlist = ix.Indices
+ targs = check.typeList(xlist)
+ if targs == nil {
+ check.use(call.Args...)
+ x.mode = invalid
+ x.expr = call
+ return statement
+ }
+ assert(len(targs) == len(xlist))
+
+ // check number of type arguments (got) vs number of type parameters (want)
+ got, want := len(targs), sig.TypeParams().Len()
+ if got > want {
+ check.errorf(xlist[want], WrongTypeArgCount, "got %d type arguments but want %d", got, want)
+ check.use(call.Args...)
+ x.mode = invalid
+ x.expr = call
+ return statement
+ }
+
+ // If sig is generic and all type arguments are provided, preempt function
+ // argument type inference by explicitly instantiating the signature. This
+ // ensures that we record accurate type information for sig, even if there
+ // is an error checking its arguments (for example, if an incorrect number
+ // of arguments is supplied).
+ if got == want && want > 0 {
+ check.verifyVersionf(atPos(ix.Lbrack), go1_18, "function instantiation")
+ sig = check.instantiateSignature(ix.Pos(), ix.Orig, sig, targs, xlist)
+ // targs have been consumed; proceed with checking arguments of the
+ // non-generic signature.
+ targs = nil
+ xlist = nil
+ }
+ }
+
+ // evaluate arguments
+ args, atargs, atxlist := check.genericExprList(call.Args)
+ sig = check.arguments(call, sig, targs, xlist, args, atargs, atxlist)
+
+ if wasGeneric && sig.TypeParams().Len() == 0 {
+ // Update the recorded type of call.Fun to its instantiated type.
+ check.recordTypeAndValue(call.Fun, value, sig, nil)
+ }
+
+ // determine result
+ switch sig.results.Len() {
+ case 0:
+ x.mode = novalue
+ case 1:
+ if cgocall {
+ x.mode = commaerr
+ } else {
+ x.mode = value
+ }
+ x.typ = sig.results.vars[0].typ // unpack tuple
+ default:
+ x.mode = value
+ x.typ = sig.results
+ }
+ x.expr = call
+ check.hasCallOrRecv = true
+
+ // if type inference failed, a parameterized result must be invalidated
+ // (operands cannot have a parameterized type)
+ if x.mode == value && sig.TypeParams().Len() > 0 && isParameterized(sig.TypeParams().list(), x.typ) {
+ x.mode = invalid
+ }
+
+ return statement
+}
+
+// exprList evaluates a list of expressions and returns the corresponding operands.
+// A single-element expression list may evaluate to multiple operands.
+func (check *Checker) exprList(elist []ast.Expr) (xlist []*operand) {
+ if n := len(elist); n == 1 {
+ xlist, _ = check.multiExpr(elist[0], false)
+ } else if n > 1 {
+ // multiple (possibly invalid) values
+ xlist = make([]*operand, n)
+ for i, e := range elist {
+ var x operand
+ check.expr(nil, &x, e)
+ xlist[i] = &x
+ }
+ }
+ return
+}
+
+// genericExprList is like exprList but result operands may be uninstantiated or partially
+// instantiated generic functions (where constraint information is insufficient to infer
+// the missing type arguments) for Go 1.21 and later.
+// For each non-generic or uninstantiated generic operand, the corresponding targsList and
+// xlistList elements do not exist (targsList and xlistList are nil) or the elements are nil.
+// For each partially instantiated generic function operand, the corresponding targsList and
+// xlistList elements are the operand's partial type arguments and type expression lists.
+func (check *Checker) genericExprList(elist []ast.Expr) (resList []*operand, targsList [][]Type, xlistList [][]ast.Expr) {
+ if debug {
+ defer func() {
+ // targsList and xlistList must have matching lengths
+ assert(len(targsList) == len(xlistList))
+ // type arguments must only exist for partially instantiated functions
+ for i, x := range resList {
+ if i < len(targsList) {
+ if n := len(targsList[i]); n > 0 {
+ // x must be a partially instantiated function
+ assert(n < x.typ.(*Signature).TypeParams().Len())
+ }
+ }
+ }
+ }()
+ }
+
+ // Before Go 1.21, uninstantiated or partially instantiated argument functions are
+ // nor permitted. Checker.funcInst must infer missing type arguments in that case.
+ infer := true // for -lang < go1.21
+ n := len(elist)
+ if n > 0 && check.allowVersion(check.pkg, elist[0], go1_21) {
+ infer = false
+ }
+
+ if n == 1 {
+ // single value (possibly a partially instantiated function), or a multi-valued expression
+ e := elist[0]
+ var x operand
+ if ix := typeparams.UnpackIndexExpr(e); ix != nil && check.indexExpr(&x, ix) {
+ // x is a generic function.
+ targs, xlist := check.funcInst(nil, x.Pos(), &x, ix, infer)
+ if targs != nil {
+ // x was not instantiated: collect the (partial) type arguments.
+ targsList = [][]Type{targs}
+ xlistList = [][]ast.Expr{xlist}
+ // Update x.expr so that we can record the partially instantiated function.
+ x.expr = ix.Orig
+ } else {
+ // x was instantiated: we must record it here because we didn't
+ // use the usual expression evaluators.
+ check.record(&x)
+ }
+ resList = []*operand{&x}
+ } else {
+ // x is not a function instantiation (it may still be a generic function).
+ check.rawExpr(nil, &x, e, nil, true)
+ check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr)
+ if t, ok := x.typ.(*Tuple); ok && x.mode != invalid {
+ // x is a function call returning multiple values; it cannot be generic.
+ resList = make([]*operand, t.Len())
+ for i, v := range t.vars {
+ resList[i] = &operand{mode: value, expr: e, typ: v.typ}
+ }
+ } else {
+ // x is exactly one value (possibly invalid or uninstantiated generic function).
+ resList = []*operand{&x}
+ }
+ }
+ } else if n > 1 {
+ // multiple values
+ resList = make([]*operand, n)
+ targsList = make([][]Type, n)
+ xlistList = make([][]ast.Expr, n)
+ for i, e := range elist {
+ var x operand
+ if ix := typeparams.UnpackIndexExpr(e); ix != nil && check.indexExpr(&x, ix) {
+ // x is a generic function.
+ targs, xlist := check.funcInst(nil, x.Pos(), &x, ix, infer)
+ if targs != nil {
+ // x was not instantiated: collect the (partial) type arguments.
+ targsList[i] = targs
+ xlistList[i] = xlist
+ // Update x.expr so that we can record the partially instantiated function.
+ x.expr = ix.Orig
+ } else {
+ // x was instantiated: we must record it here because we didn't
+ // use the usual expression evaluators.
+ check.record(&x)
+ }
+ } else {
+ // x is exactly one value (possibly invalid or uninstantiated generic function).
+ check.genericExpr(&x, e)
+ }
+ resList[i] = &x
+ }
+ }
+
+ return
+}
+
+// arguments type-checks arguments passed to a function call with the given signature.
+// The function and its arguments may be generic, and possibly partially instantiated.
+// targs and xlist are the function's type arguments (and corresponding expressions).
+// args are the function arguments. If an argument args[i] is a partially instantiated
+// generic function, atargs[i] and atxlist[i] are the corresponding type arguments
+// (and corresponding expressions).
+// If the callee is variadic, arguments adjusts its signature to match the provided
+// arguments. The type parameters and arguments of the callee and all its arguments
+// are used together to infer any missing type arguments, and the callee and argument
+// functions are instantiated as necessary.
+// The result signature is the (possibly adjusted and instantiated) function signature.
+// If an error occurred, the result signature is the incoming sig.
+func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type, xlist []ast.Expr, args []*operand, atargs [][]Type, atxlist [][]ast.Expr) (rsig *Signature) {
+ rsig = sig
+
+ // Function call argument/parameter count requirements
+ //
+ // | standard call | dotdotdot call |
+ // --------------+------------------+----------------+
+ // standard func | nargs == npars | invalid |
+ // --------------+------------------+----------------+
+ // variadic func | nargs >= npars-1 | nargs == npars |
+ // --------------+------------------+----------------+
+
+ nargs := len(args)
+ npars := sig.params.Len()
+ ddd := call.Ellipsis.IsValid()
+
+ // set up parameters
+ sigParams := sig.params // adjusted for variadic functions (may be nil for empty parameter lists!)
+ adjusted := false // indicates if sigParams is different from sig.params
+ if sig.variadic {
+ if ddd {
+ // variadic_func(a, b, c...)
+ if len(call.Args) == 1 && nargs > 1 {
+ // f()... is not permitted if f() is multi-valued
+ check.errorf(inNode(call, call.Ellipsis), InvalidDotDotDot, "cannot use ... with %d-valued %s", nargs, call.Args[0])
+ return
+ }
+ } else {
+ // variadic_func(a, b, c)
+ if nargs >= npars-1 {
+ // Create custom parameters for arguments: keep
+ // the first npars-1 parameters and add one for
+ // each argument mapping to the ... parameter.
+ vars := make([]*Var, npars-1) // npars > 0 for variadic functions
+ copy(vars, sig.params.vars)
+ last := sig.params.vars[npars-1]
+ typ := last.typ.(*Slice).elem
+ for len(vars) < nargs {
+ vars = append(vars, NewParam(last.pos, last.pkg, last.name, typ))
+ }
+ sigParams = NewTuple(vars...) // possibly nil!
+ adjusted = true
+ npars = nargs
+ } else {
+ // nargs < npars-1
+ npars-- // for correct error message below
+ }
+ }
+ } else {
+ if ddd {
+ // standard_func(a, b, c...)
+ check.errorf(inNode(call, call.Ellipsis), NonVariadicDotDotDot, "cannot use ... in call to non-variadic %s", call.Fun)
+ return
+ }
+ // standard_func(a, b, c)
+ }
+
+ // check argument count
+ if nargs != npars {
+ var at positioner = call
+ qualifier := "not enough"
+ if nargs > npars {
+ at = args[npars].expr // report at first extra argument
+ qualifier = "too many"
+ } else {
+ at = atPos(call.Rparen) // report at closing )
+ }
+ // take care of empty parameter lists represented by nil tuples
+ var params []*Var
+ if sig.params != nil {
+ params = sig.params.vars
+ }
+ err := newErrorf(at, WrongArgCount, "%s arguments in call to %s", qualifier, call.Fun)
+ err.errorf(nopos, "have %s", check.typesSummary(operandTypes(args), false))
+ err.errorf(nopos, "want %s", check.typesSummary(varTypes(params), sig.variadic))
+ check.report(err)
+ return
+ }
+
+ // collect type parameters of callee and generic function arguments
+ var tparams []*TypeParam
+
+ // collect type parameters of callee
+ n := sig.TypeParams().Len()
+ if n > 0 {
+ if !check.allowVersion(check.pkg, call, go1_18) {
+ switch call.Fun.(type) {
+ case *ast.IndexExpr, *ast.IndexListExpr:
+ ix := typeparams.UnpackIndexExpr(call.Fun)
+ check.versionErrorf(inNode(call.Fun, ix.Lbrack), go1_18, "function instantiation")
+ default:
+ check.versionErrorf(inNode(call, call.Lparen), go1_18, "implicit function instantiation")
+ }
+ }
+ // rename type parameters to avoid problems with recursive calls
+ var tmp Type
+ tparams, tmp = check.renameTParams(call.Pos(), sig.TypeParams().list(), sigParams)
+ sigParams = tmp.(*Tuple)
+ // make sure targs and tparams have the same length
+ for len(targs) < len(tparams) {
+ targs = append(targs, nil)
+ }
+ }
+ assert(len(tparams) == len(targs))
+
+ // collect type parameters from generic function arguments
+ var genericArgs []int // indices of generic function arguments
+ if enableReverseTypeInference {
+ for i, arg := range args {
+ // generic arguments cannot have a defined (*Named) type - no need for underlying type below
+ if asig, _ := arg.typ.(*Signature); asig != nil && asig.TypeParams().Len() > 0 {
+ // Rename type parameters for cases like f(g, g); this gives each
+ // generic function argument a unique type identity (go.dev/issues/59956).
+ // TODO(gri) Consider only doing this if a function argument appears
+ // multiple times, which is rare (possible optimization).
+ atparams, tmp := check.renameTParams(call.Pos(), asig.TypeParams().list(), asig)
+ asig = tmp.(*Signature)
+ asig.tparams = &TypeParamList{atparams} // renameTParams doesn't touch associated type parameters
+ arg.typ = asig // new type identity for the function argument
+ tparams = append(tparams, atparams...)
+ // add partial list of type arguments, if any
+ if i < len(atargs) {
+ targs = append(targs, atargs[i]...)
+ }
+ // make sure targs and tparams have the same length
+ for len(targs) < len(tparams) {
+ targs = append(targs, nil)
+ }
+ genericArgs = append(genericArgs, i)
+ }
+ }
+ }
+ assert(len(tparams) == len(targs))
+
+ // at the moment we only support implicit instantiations of argument functions
+ _ = len(genericArgs) > 0 && check.verifyVersionf(args[genericArgs[0]], go1_21, "implicitly instantiated function as argument")
+
+ // tparams holds the type parameters of the callee and generic function arguments, if any:
+ // the first n type parameters belong to the callee, followed by mi type parameters for each
+ // of the generic function arguments, where mi = args[i].typ.(*Signature).TypeParams().Len().
+
+ // infer missing type arguments of callee and function arguments
+ if len(tparams) > 0 {
+ targs = check.infer(call, tparams, targs, sigParams, args)
+ if targs == nil {
+ // TODO(gri) If infer inferred the first targs[:n], consider instantiating
+ // the call signature for better error messages/gopls behavior.
+ // Perhaps instantiate as much as we can, also for arguments.
+ // This will require changes to how infer returns its results.
+ return // error already reported
+ }
+
+ // update result signature: instantiate if needed
+ if n > 0 {
+ rsig = check.instantiateSignature(call.Pos(), call.Fun, sig, targs[:n], xlist)
+ // If the callee's parameter list was adjusted we need to update (instantiate)
+ // it separately. Otherwise we can simply use the result signature's parameter
+ // list.
+ if adjusted {
+ sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams[:n], targs[:n]), nil, check.context()).(*Tuple)
+ } else {
+ sigParams = rsig.params
+ }
+ }
+
+ // compute argument signatures: instantiate if needed
+ j := n
+ for _, i := range genericArgs {
+ arg := args[i]
+ asig := arg.typ.(*Signature)
+ k := j + asig.TypeParams().Len()
+ // targs[j:k] are the inferred type arguments for asig
+ arg.typ = check.instantiateSignature(call.Pos(), arg.expr, asig, targs[j:k], nil) // TODO(gri) provide xlist if possible (partial instantiations)
+ check.record(arg) // record here because we didn't use the usual expr evaluators
+ j = k
+ }
+ }
+
+ // check arguments
+ if len(args) > 0 {
+ context := check.sprintf("argument to %s", call.Fun)
+ for i, a := range args {
+ check.assignment(a, sigParams.vars[i].typ, context)
+ }
+ }
+
+ return
+}
+
+var cgoPrefixes = [...]string{
+ "_Ciconst_",
+ "_Cfconst_",
+ "_Csconst_",
+ "_Ctype_",
+ "_Cvar_", // actually a pointer to the var
+ "_Cfpvar_fp_",
+ "_Cfunc_",
+ "_Cmacro_", // function to evaluate the expanded expression
+}
+
+func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *Named, wantType bool) {
+ // these must be declared before the "goto Error" statements
+ var (
+ obj Object
+ index []int
+ indirect bool
+ )
+
+ sel := e.Sel.Name
+ // If the identifier refers to a package, handle everything here
+ // so we don't need a "package" mode for operands: package names
+ // can only appear in qualified identifiers which are mapped to
+ // selector expressions.
+ if ident, ok := e.X.(*ast.Ident); ok {
+ obj := check.lookup(ident.Name)
+ if pname, _ := obj.(*PkgName); pname != nil {
+ assert(pname.pkg == check.pkg)
+ check.recordUse(ident, pname)
+ pname.used = true
+ pkg := pname.imported
+
+ var exp Object
+ funcMode := value
+ if pkg.cgo {
+ // cgo special cases C.malloc: it's
+ // rewritten to _CMalloc and does not
+ // support two-result calls.
+ if sel == "malloc" {
+ sel = "_CMalloc"
+ } else {
+ funcMode = cgofunc
+ }
+ for _, prefix := range cgoPrefixes {
+ // cgo objects are part of the current package (in file
+ // _cgo_gotypes.go). Use regular lookup.
+ _, exp = check.scope.LookupParent(prefix+sel, check.pos)
+ if exp != nil {
+ break
+ }
+ }
+ if exp == nil {
+ check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", ast.Expr(e)) // cast to ast.Expr to silence vet
+ goto Error
+ }
+ check.objDecl(exp, nil)
+ } else {
+ exp = pkg.scope.Lookup(sel)
+ if exp == nil {
+ if !pkg.fake {
+ check.errorf(e.Sel, UndeclaredImportedName, "undefined: %s", ast.Expr(e))
+ }
+ goto Error
+ }
+ if !exp.Exported() {
+ check.errorf(e.Sel, UnexportedName, "%s not exported by package %s", sel, pkg.name)
+ // ok to continue
+ }
+ }
+ check.recordUse(e.Sel, exp)
+
+ // Simplified version of the code for *ast.Idents:
+ // - imported objects are always fully initialized
+ switch exp := exp.(type) {
+ case *Const:
+ assert(exp.Val() != nil)
+ x.mode = constant_
+ x.typ = exp.typ
+ x.val = exp.val
+ case *TypeName:
+ x.mode = typexpr
+ x.typ = exp.typ
+ case *Var:
+ x.mode = variable
+ x.typ = exp.typ
+ if pkg.cgo && strings.HasPrefix(exp.name, "_Cvar_") {
+ x.typ = x.typ.(*Pointer).base
+ }
+ case *Func:
+ x.mode = funcMode
+ x.typ = exp.typ
+ if pkg.cgo && strings.HasPrefix(exp.name, "_Cmacro_") {
+ x.mode = value
+ x.typ = x.typ.(*Signature).results.vars[0].typ
+ }
+ case *Builtin:
+ x.mode = builtin
+ x.typ = exp.typ
+ x.id = exp.id
+ default:
+ check.dump("%v: unexpected object %v", e.Sel.Pos(), exp)
+ unreachable()
+ }
+ x.expr = e
+ return
+ }
+ }
+
+ check.exprOrType(x, e.X, false)
+ switch x.mode {
+ case typexpr:
+ // don't crash for "type T T.x" (was go.dev/issue/51509)
+ if def != nil && x.typ == def {
+ check.cycleError([]Object{def.obj})
+ goto Error
+ }
+ case builtin:
+ // types2 uses the position of '.' for the error
+ check.errorf(e.Sel, UncalledBuiltin, "cannot select on %s", x)
+ goto Error
+ case invalid:
+ goto Error
+ }
+
+ // Avoid crashing when checking an invalid selector in a method declaration
+ // (i.e., where def is not set):
+ //
+ // type S[T any] struct{}
+ // type V = S[any]
+ // func (fs *S[T]) M(x V.M) {}
+ //
+ // All codepaths below return a non-type expression. If we get here while
+ // expecting a type expression, it is an error.
+ //
+ // See go.dev/issue/57522 for more details.
+ //
+ // TODO(rfindley): We should do better by refusing to check selectors in all cases where
+ // x.typ is incomplete.
+ if wantType {
+ check.errorf(e.Sel, NotAType, "%s is not a type", ast.Expr(e))
+ goto Error
+ }
+
+ obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
+ if obj == nil {
+ // Don't report another error if the underlying type was invalid (go.dev/issue/49541).
+ if under(x.typ) == Typ[Invalid] {
+ goto Error
+ }
+
+ if index != nil {
+ // TODO(gri) should provide actual type where the conflict happens
+ check.errorf(e.Sel, AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel)
+ goto Error
+ }
+
+ if indirect {
+ if x.mode == typexpr {
+ check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ, sel, x.typ, sel)
+ } else {
+ check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
+ }
+ goto Error
+ }
+
+ var why string
+ if isInterfacePtr(x.typ) {
+ why = check.interfacePtrError(x.typ)
+ } else {
+ why = check.sprintf("type %s has no field or method %s", x.typ, sel)
+ // Check if capitalization of sel matters and provide better error message in that case.
+ // TODO(gri) This code only looks at the first character but LookupFieldOrMethod should
+ // have an (internal) mechanism for case-insensitive lookup that we should use
+ // instead (see types2).
+ if len(sel) > 0 {
+ var changeCase string
+ if r := rune(sel[0]); unicode.IsUpper(r) {
+ changeCase = string(unicode.ToLower(r)) + sel[1:]
+ } else {
+ changeCase = string(unicode.ToUpper(r)) + sel[1:]
+ }
+ if obj, _, _ = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, changeCase); obj != nil {
+ why += ", but does have " + changeCase
+ }
+ }
+ }
+ check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
+ goto Error
+ }
+
+ // methods may not have a fully set up signature yet
+ if m, _ := obj.(*Func); m != nil {
+ check.objDecl(m, nil)
+ }
+
+ if x.mode == typexpr {
+ // method expression
+ m, _ := obj.(*Func)
+ if m == nil {
+ // TODO(gri) should check if capitalization of sel matters and provide better error message in that case
+ check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
+ goto Error
+ }
+
+ check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
+
+ sig := m.typ.(*Signature)
+ if sig.recv == nil {
+ check.error(e, InvalidDeclCycle, "illegal cycle in method declaration")
+ goto Error
+ }
+
+ // the receiver type becomes the type of the first function
+ // argument of the method expression's function type
+ var params []*Var
+ if sig.params != nil {
+ params = sig.params.vars
+ }
+ // Be consistent about named/unnamed parameters. This is not needed
+ // for type-checking, but the newly constructed signature may appear
+ // in an error message and then have mixed named/unnamed parameters.
+ // (An alternative would be to not print parameter names in errors,
+ // but it's useful to see them; this is cheap and method expressions
+ // are rare.)
+ name := ""
+ if len(params) > 0 && params[0].name != "" {
+ // name needed
+ name = sig.recv.name
+ if name == "" {
+ name = "_"
+ }
+ }
+ params = append([]*Var{NewVar(sig.recv.pos, sig.recv.pkg, name, x.typ)}, params...)
+ x.mode = value
+ x.typ = &Signature{
+ tparams: sig.tparams,
+ params: NewTuple(params...),
+ results: sig.results,
+ variadic: sig.variadic,
+ }
+
+ check.addDeclDep(m)
+
+ } else {
+ // regular selector
+ switch obj := obj.(type) {
+ case *Var:
+ check.recordSelection(e, FieldVal, x.typ, obj, index, indirect)
+ if x.mode == variable || indirect {
+ x.mode = variable
+ } else {
+ x.mode = value
+ }
+ x.typ = obj.typ
+
+ case *Func:
+ // TODO(gri) If we needed to take into account the receiver's
+ // addressability, should we report the type &(x.typ) instead?
+ check.recordSelection(e, MethodVal, x.typ, obj, index, indirect)
+
+ // TODO(gri) The verification pass below is disabled for now because
+ // method sets don't match method lookup in some cases.
+ // For instance, if we made a copy above when creating a
+ // custom method for a parameterized received type, the
+ // method set method doesn't match (no copy there). There
+ /// may be other situations.
+ disabled := true
+ if !disabled && debug {
+ // Verify that LookupFieldOrMethod and MethodSet.Lookup agree.
+ // TODO(gri) This only works because we call LookupFieldOrMethod
+ // _before_ calling NewMethodSet: LookupFieldOrMethod completes
+ // any incomplete interfaces so they are available to NewMethodSet
+ // (which assumes that interfaces have been completed already).
+ typ := x.typ
+ if x.mode == variable {
+ // If typ is not an (unnamed) pointer or an interface,
+ // use *typ instead, because the method set of *typ
+ // includes the methods of typ.
+ // Variables are addressable, so we can always take their
+ // address.
+ if _, ok := typ.(*Pointer); !ok && !IsInterface(typ) {
+ typ = &Pointer{base: typ}
+ }
+ }
+ // If we created a synthetic pointer type above, we will throw
+ // away the method set computed here after use.
+ // TODO(gri) Method set computation should probably always compute
+ // both, the value and the pointer receiver method set and represent
+ // them in a single structure.
+ // TODO(gri) Consider also using a method set cache for the lifetime
+ // of checker once we rely on MethodSet lookup instead of individual
+ // lookup.
+ mset := NewMethodSet(typ)
+ if m := mset.Lookup(check.pkg, sel); m == nil || m.obj != obj {
+ check.dump("%v: (%s).%v -> %s", e.Pos(), typ, obj.name, m)
+ check.dump("%s\n", mset)
+ // Caution: MethodSets are supposed to be used externally
+ // only (after all interface types were completed). It's
+ // now possible that we get here incorrectly. Not urgent
+ // to fix since we only run this code in debug mode.
+ // TODO(gri) fix this eventually.
+ panic("method sets and lookup don't agree")
+ }
+ }
+
+ x.mode = value
+
+ // remove receiver
+ sig := *obj.typ.(*Signature)
+ sig.recv = nil
+ x.typ = &sig
+
+ check.addDeclDep(obj)
+
+ default:
+ unreachable()
+ }
+ }
+
+ // everything went well
+ x.expr = e
+ return
+
+Error:
+ x.mode = invalid
+ x.expr = e
+}
+
+// use type-checks each argument.
+// Useful to make sure expressions are evaluated
+// (and variables are "used") in the presence of
+// other errors. Arguments may be nil.
+// Reports if all arguments evaluated without error.
+func (check *Checker) use(args ...ast.Expr) bool { return check.useN(args, false) }
+
+// useLHS is like use, but doesn't "use" top-level identifiers.
+// It should be called instead of use if the arguments are
+// expressions on the lhs of an assignment.
+func (check *Checker) useLHS(args ...ast.Expr) bool { return check.useN(args, true) }
+
+func (check *Checker) useN(args []ast.Expr, lhs bool) bool {
+ ok := true
+ for _, e := range args {
+ if !check.use1(e, lhs) {
+ ok = false
+ }
+ }
+ return ok
+}
+
+func (check *Checker) use1(e ast.Expr, lhs bool) bool {
+ var x operand
+ x.mode = value // anything but invalid
+ switch n := unparen(e).(type) {
+ case nil:
+ // nothing to do
+ case *ast.Ident:
+ // don't report an error evaluating blank
+ if n.Name == "_" {
+ break
+ }
+ // If the lhs is an identifier denoting a variable v, this assignment
+ // is not a 'use' of v. Remember current value of v.used and restore
+ // after evaluating the lhs via check.rawExpr.
+ var v *Var
+ var v_used bool
+ if lhs {
+ if _, obj := check.scope.LookupParent(n.Name, nopos); obj != nil {
+ // It's ok to mark non-local variables, but ignore variables
+ // from other packages to avoid potential race conditions with
+ // dot-imported variables.
+ if w, _ := obj.(*Var); w != nil && w.pkg == check.pkg {
+ v = w
+ v_used = v.used
+ }
+ }
+ }
+ check.exprOrType(&x, n, true)
+ if v != nil {
+ v.used = v_used // restore v.used
+ }
+ default:
+ check.rawExpr(nil, &x, e, nil, true)
+ }
+ return x.mode != invalid
+}
diff --git a/contrib/go/_std_1.21/src/go/types/chan.go b/contrib/go/_std_1.21/src/go/types/chan.go
new file mode 100644
index 0000000000..940620067c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/chan.go
@@ -0,0 +1,37 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2011 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 types
+
+// A Chan represents a channel type.
+type Chan struct {
+ dir ChanDir
+ elem Type
+}
+
+// A ChanDir value indicates a channel direction.
+type ChanDir int
+
+// The direction of a channel is indicated by one of these constants.
+const (
+ SendRecv ChanDir = iota
+ SendOnly
+ RecvOnly
+)
+
+// NewChan returns a new channel type for the given direction and element type.
+func NewChan(dir ChanDir, elem Type) *Chan {
+ return &Chan{dir: dir, elem: elem}
+}
+
+// Dir returns the direction of channel c.
+func (c *Chan) Dir() ChanDir { return c.dir }
+
+// Elem returns the element type of channel c.
+func (c *Chan) Elem() Type { return c.elem }
+
+func (c *Chan) Underlying() Type { return c }
+func (c *Chan) String() string { return TypeString(c, nil) }
diff --git a/contrib/go/_std_1.21/src/go/types/check.go b/contrib/go/_std_1.21/src/go/types/check.go
new file mode 100644
index 0000000000..3b0f5e4fdf
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/check.go
@@ -0,0 +1,634 @@
+// Copyright 2011 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.
+
+// This file implements the Check function, which drives type-checking.
+
+package types
+
+import (
+ "errors"
+ "fmt"
+ "go/ast"
+ "go/constant"
+ "go/token"
+ "internal/goversion"
+ . "internal/types/errors"
+)
+
+// nopos indicates an unknown position
+var nopos token.Pos
+
+// debugging/development support
+const debug = false // leave on during development
+
+// exprInfo stores information about an untyped expression.
+type exprInfo struct {
+ isLhs bool // expression is lhs operand of a shift with delayed type-check
+ mode operandMode
+ typ *Basic
+ val constant.Value // constant value; or nil (if not a constant)
+}
+
+// An environment represents the environment within which an object is
+// type-checked.
+type environment struct {
+ decl *declInfo // package-level declaration whose init expression/function body is checked
+ scope *Scope // top-most scope for lookups
+ pos token.Pos // if valid, identifiers are looked up as if at position pos (used by Eval)
+ iota constant.Value // value of iota in a constant declaration; nil otherwise
+ errpos positioner // if set, identifier position of a constant with inherited initializer
+ inTParamList bool // set if inside a type parameter list
+ sig *Signature // function signature if inside a function; nil otherwise
+ isPanic map[*ast.CallExpr]bool // set of panic call expressions (used for termination check)
+ hasLabel bool // set if a function makes use of labels (only ~1% of functions); unused outside functions
+ hasCallOrRecv bool // set if an expression contains a function call or channel receive operation
+}
+
+// lookup looks up name in the current environment and returns the matching object, or nil.
+func (env *environment) lookup(name string) Object {
+ _, obj := env.scope.LookupParent(name, env.pos)
+ return obj
+}
+
+// An importKey identifies an imported package by import path and source directory
+// (directory containing the file containing the import). In practice, the directory
+// may always be the same, or may not matter. Given an (import path, directory), an
+// importer must always return the same package (but given two different import paths,
+// an importer may still return the same package by mapping them to the same package
+// paths).
+type importKey struct {
+ path, dir string
+}
+
+// A dotImportKey describes a dot-imported object in the given scope.
+type dotImportKey struct {
+ scope *Scope
+ name string
+}
+
+// An action describes a (delayed) action.
+type action struct {
+ f func() // action to be executed
+ desc *actionDesc // action description; may be nil, requires debug to be set
+}
+
+// If debug is set, describef sets a printf-formatted description for action a.
+// Otherwise, it is a no-op.
+func (a *action) describef(pos positioner, format string, args ...any) {
+ if debug {
+ a.desc = &actionDesc{pos, format, args}
+ }
+}
+
+// An actionDesc provides information on an action.
+// For debugging only.
+type actionDesc struct {
+ pos positioner
+ format string
+ args []any
+}
+
+// A Checker maintains the state of the type checker.
+// It must be created with NewChecker.
+type Checker struct {
+ // package information
+ // (initialized by NewChecker, valid for the life-time of checker)
+ conf *Config
+ ctxt *Context // context for de-duplicating instances
+ fset *token.FileSet
+ pkg *Package
+ *Info
+ version version // accepted language version
+ nextID uint64 // unique Id for type parameters (first valid Id is 1)
+ objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info
+ impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package
+ valids instanceLookup // valid *Named (incl. instantiated) types per the validType check
+
+ // pkgPathMap maps package names to the set of distinct import paths we've
+ // seen for that name, anywhere in the import graph. It is used for
+ // disambiguating package names in error messages.
+ //
+ // pkgPathMap is allocated lazily, so that we don't pay the price of building
+ // it on the happy path. seenPkgMap tracks the packages that we've already
+ // walked.
+ pkgPathMap map[string]map[string]bool
+ seenPkgMap map[*Package]bool
+
+ // information collected during type-checking of a set of package files
+ // (initialized by Files, valid only for the duration of check.Files;
+ // maps and lists are allocated on demand)
+ files []*ast.File // package files
+ posVers map[*token.File]version // Pos -> Go version mapping
+ imports []*PkgName // list of imported packages
+ dotImportMap map[dotImportKey]*PkgName // maps dot-imported objects to the package they were dot-imported through
+ recvTParamMap map[*ast.Ident]*TypeParam // maps blank receiver type parameters to their type
+ brokenAliases map[*TypeName]bool // set of aliases with broken (not yet determined) types
+ unionTypeSets map[*Union]*_TypeSet // computed type sets for union types
+ mono monoGraph // graph for detecting non-monomorphizable instantiation loops
+
+ firstErr error // first error encountered
+ methods map[*TypeName][]*Func // maps package scope type names to associated non-blank (non-interface) methods
+ untyped map[ast.Expr]exprInfo // map of expressions without final type
+ delayed []action // stack of delayed action segments; segments are processed in FIFO order
+ objPath []Object // path of object dependencies during type inference (for cycle reporting)
+ cleaners []cleaner // list of types that may need a final cleanup at the end of type-checking
+
+ // environment within which the current object is type-checked (valid only
+ // for the duration of type-checking a specific object)
+ environment
+
+ // debugging
+ indent int // indentation for tracing
+}
+
+// addDeclDep adds the dependency edge (check.decl -> to) if check.decl exists
+func (check *Checker) addDeclDep(to Object) {
+ from := check.decl
+ if from == nil {
+ return // not in a package-level init expression
+ }
+ if _, found := check.objMap[to]; !found {
+ return // to is not a package-level object
+ }
+ from.addDep(to)
+}
+
+// brokenAlias records that alias doesn't have a determined type yet.
+// It also sets alias.typ to Typ[Invalid].
+func (check *Checker) brokenAlias(alias *TypeName) {
+ if check.brokenAliases == nil {
+ check.brokenAliases = make(map[*TypeName]bool)
+ }
+ check.brokenAliases[alias] = true
+ alias.typ = Typ[Invalid]
+}
+
+// validAlias records that alias has the valid type typ (possibly Typ[Invalid]).
+func (check *Checker) validAlias(alias *TypeName, typ Type) {
+ delete(check.brokenAliases, alias)
+ alias.typ = typ
+}
+
+// isBrokenAlias reports whether alias doesn't have a determined type yet.
+func (check *Checker) isBrokenAlias(alias *TypeName) bool {
+ return alias.typ == Typ[Invalid] && check.brokenAliases[alias]
+}
+
+func (check *Checker) rememberUntyped(e ast.Expr, lhs bool, mode operandMode, typ *Basic, val constant.Value) {
+ m := check.untyped
+ if m == nil {
+ m = make(map[ast.Expr]exprInfo)
+ check.untyped = m
+ }
+ m[e] = exprInfo{lhs, mode, typ, val}
+}
+
+// later pushes f on to the stack of actions that will be processed later;
+// either at the end of the current statement, or in case of a local constant
+// or variable declaration, before the constant or variable is in scope
+// (so that f still sees the scope before any new declarations).
+// later returns the pushed action so one can provide a description
+// via action.describef for debugging, if desired.
+func (check *Checker) later(f func()) *action {
+ i := len(check.delayed)
+ check.delayed = append(check.delayed, action{f: f})
+ return &check.delayed[i]
+}
+
+// push pushes obj onto the object path and returns its index in the path.
+func (check *Checker) push(obj Object) int {
+ check.objPath = append(check.objPath, obj)
+ return len(check.objPath) - 1
+}
+
+// pop pops and returns the topmost object from the object path.
+func (check *Checker) pop() Object {
+ i := len(check.objPath) - 1
+ obj := check.objPath[i]
+ check.objPath[i] = nil
+ check.objPath = check.objPath[:i]
+ return obj
+}
+
+type cleaner interface {
+ cleanup()
+}
+
+// needsCleanup records objects/types that implement the cleanup method
+// which will be called at the end of type-checking.
+func (check *Checker) needsCleanup(c cleaner) {
+ check.cleaners = append(check.cleaners, c)
+}
+
+// NewChecker returns a new Checker instance for a given package.
+// Package files may be added incrementally via checker.Files.
+func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Checker {
+ // make sure we have a configuration
+ if conf == nil {
+ conf = new(Config)
+ }
+
+ // make sure we have an info struct
+ if info == nil {
+ info = new(Info)
+ }
+
+ // Note: clients may call NewChecker with the Unsafe package, which is
+ // globally shared and must not be mutated. Therefore NewChecker must not
+ // mutate *pkg.
+ //
+ // (previously, pkg.goVersion was mutated here: go.dev/issue/61212)
+
+ return &Checker{
+ conf: conf,
+ ctxt: conf.Context,
+ fset: fset,
+ pkg: pkg,
+ Info: info,
+ objMap: make(map[Object]*declInfo),
+ impMap: make(map[importKey]*Package),
+ }
+}
+
+// initFiles initializes the files-specific portion of checker.
+// The provided files must all belong to the same package.
+func (check *Checker) initFiles(files []*ast.File) {
+ // start with a clean slate (check.Files may be called multiple times)
+ check.files = nil
+ check.imports = nil
+ check.dotImportMap = nil
+
+ check.firstErr = nil
+ check.methods = nil
+ check.untyped = nil
+ check.delayed = nil
+ check.objPath = nil
+ check.cleaners = nil
+
+ // determine package name and collect valid files
+ pkg := check.pkg
+ for _, file := range files {
+ switch name := file.Name.Name; pkg.name {
+ case "":
+ if name != "_" {
+ pkg.name = name
+ } else {
+ check.error(file.Name, BlankPkgName, "invalid package name _")
+ }
+ fallthrough
+
+ case name:
+ check.files = append(check.files, file)
+
+ default:
+ check.errorf(atPos(file.Package), MismatchedPkgName, "package %s; expected %s", name, pkg.name)
+ // ignore this file
+ }
+ }
+
+ for _, file := range check.files {
+ v, _ := parseGoVersion(file.GoVersion)
+ if v.major > 0 {
+ if v.equal(check.version) {
+ continue
+ }
+ // Go 1.21 introduced the feature of setting the go.mod
+ // go line to an early version of Go and allowing //go:build lines
+ // to “upgrade” the Go version in a given file.
+ // We can do that backwards compatibly.
+ // Go 1.21 also introduced the feature of allowing //go:build lines
+ // to “downgrade” the Go version in a given file.
+ // That can't be done compatibly in general, since before the
+ // build lines were ignored and code got the module's Go version.
+ // To work around this, downgrades are only allowed when the
+ // module's Go version is Go 1.21 or later.
+ // If there is no check.version, then we don't really know what Go version to apply.
+ // Legacy tools may do this, and they historically have accepted everything.
+ // Preserve that behavior by ignoring //go:build constraints entirely in that case.
+ if (v.before(check.version) && check.version.before(version{1, 21})) || check.version.equal(version{0, 0}) {
+ continue
+ }
+ if check.posVers == nil {
+ check.posVers = make(map[*token.File]version)
+ }
+ check.posVers[check.fset.File(file.FileStart)] = v
+ }
+ }
+}
+
+// A posVers records that the file starting at pos declares the Go version vers.
+type posVers struct {
+ pos token.Pos
+ vers version
+}
+
+// A bailout panic is used for early termination.
+type bailout struct{}
+
+func (check *Checker) handleBailout(err *error) {
+ switch p := recover().(type) {
+ case nil, bailout:
+ // normal return or early exit
+ *err = check.firstErr
+ default:
+ // re-panic
+ panic(p)
+ }
+}
+
+// Files checks the provided files as part of the checker's package.
+func (check *Checker) Files(files []*ast.File) error { return check.checkFiles(files) }
+
+var errBadCgo = errors.New("cannot use FakeImportC and go115UsesCgo together")
+
+func (check *Checker) checkFiles(files []*ast.File) (err error) {
+ if check.pkg == Unsafe {
+ // Defensive handling for Unsafe, which cannot be type checked, and must
+ // not be mutated. See https://go.dev/issue/61212 for an example of where
+ // Unsafe is passed to NewChecker.
+ return nil
+ }
+
+ check.version, err = parseGoVersion(check.conf.GoVersion)
+ if err != nil {
+ return err
+ }
+ if check.version.after(version{1, goversion.Version}) {
+ return fmt.Errorf("package requires newer Go version %v", check.version)
+ }
+ if check.conf.FakeImportC && check.conf.go115UsesCgo {
+ return errBadCgo
+ }
+
+ defer check.handleBailout(&err)
+
+ print := func(msg string) {
+ if check.conf._Trace {
+ fmt.Println()
+ fmt.Println(msg)
+ }
+ }
+
+ print("== initFiles ==")
+ check.initFiles(files)
+
+ print("== collectObjects ==")
+ check.collectObjects()
+
+ print("== packageObjects ==")
+ check.packageObjects()
+
+ print("== processDelayed ==")
+ check.processDelayed(0) // incl. all functions
+
+ print("== cleanup ==")
+ check.cleanup()
+
+ print("== initOrder ==")
+ check.initOrder()
+
+ if !check.conf.DisableUnusedImportCheck {
+ print("== unusedImports ==")
+ check.unusedImports()
+ }
+
+ print("== recordUntyped ==")
+ check.recordUntyped()
+
+ if check.firstErr == nil {
+ // TODO(mdempsky): Ensure monomorph is safe when errors exist.
+ check.monomorph()
+ }
+
+ check.pkg.goVersion = check.conf.GoVersion
+ check.pkg.complete = true
+
+ // no longer needed - release memory
+ check.imports = nil
+ check.dotImportMap = nil
+ check.pkgPathMap = nil
+ check.seenPkgMap = nil
+ check.recvTParamMap = nil
+ check.brokenAliases = nil
+ check.unionTypeSets = nil
+ check.ctxt = nil
+
+ // TODO(rFindley) There's more memory we should release at this point.
+
+ return
+}
+
+// processDelayed processes all delayed actions pushed after top.
+func (check *Checker) processDelayed(top int) {
+ // If each delayed action pushes a new action, the
+ // stack will continue to grow during this loop.
+ // However, it is only processing functions (which
+ // are processed in a delayed fashion) that may
+ // add more actions (such as nested functions), so
+ // this is a sufficiently bounded process.
+ for i := top; i < len(check.delayed); i++ {
+ a := &check.delayed[i]
+ if check.conf._Trace {
+ if a.desc != nil {
+ check.trace(a.desc.pos.Pos(), "-- "+a.desc.format, a.desc.args...)
+ } else {
+ check.trace(nopos, "-- delayed %p", a.f)
+ }
+ }
+ a.f() // may append to check.delayed
+ if check.conf._Trace {
+ fmt.Println()
+ }
+ }
+ assert(top <= len(check.delayed)) // stack must not have shrunk
+ check.delayed = check.delayed[:top]
+}
+
+// cleanup runs cleanup for all collected cleaners.
+func (check *Checker) cleanup() {
+ // Don't use a range clause since Named.cleanup may add more cleaners.
+ for i := 0; i < len(check.cleaners); i++ {
+ check.cleaners[i].cleanup()
+ }
+ check.cleaners = nil
+}
+
+func (check *Checker) record(x *operand) {
+ // convert x into a user-friendly set of values
+ // TODO(gri) this code can be simplified
+ var typ Type
+ var val constant.Value
+ switch x.mode {
+ case invalid:
+ typ = Typ[Invalid]
+ case novalue:
+ typ = (*Tuple)(nil)
+ case constant_:
+ typ = x.typ
+ val = x.val
+ default:
+ typ = x.typ
+ }
+ assert(x.expr != nil && typ != nil)
+
+ if isUntyped(typ) {
+ // delay type and value recording until we know the type
+ // or until the end of type checking
+ check.rememberUntyped(x.expr, false, x.mode, typ.(*Basic), val)
+ } else {
+ check.recordTypeAndValue(x.expr, x.mode, typ, val)
+ }
+}
+
+func (check *Checker) recordUntyped() {
+ if !debug && check.Types == nil {
+ return // nothing to do
+ }
+
+ for x, info := range check.untyped {
+ if debug && isTyped(info.typ) {
+ check.dump("%v: %s (type %s) is typed", x.Pos(), x, info.typ)
+ unreachable()
+ }
+ check.recordTypeAndValue(x, info.mode, info.typ, info.val)
+ }
+}
+
+func (check *Checker) recordTypeAndValue(x ast.Expr, mode operandMode, typ Type, val constant.Value) {
+ assert(x != nil)
+ assert(typ != nil)
+ if mode == invalid {
+ return // omit
+ }
+ if mode == constant_ {
+ assert(val != nil)
+ // We check allBasic(typ, IsConstType) here as constant expressions may be
+ // recorded as type parameters.
+ assert(typ == Typ[Invalid] || allBasic(typ, IsConstType))
+ }
+ if m := check.Types; m != nil {
+ m[x] = TypeAndValue{mode, typ, val}
+ }
+}
+
+func (check *Checker) recordBuiltinType(f ast.Expr, sig *Signature) {
+ // f must be a (possibly parenthesized, possibly qualified)
+ // identifier denoting a built-in (including unsafe's non-constant
+ // functions Add and Slice): record the signature for f and possible
+ // children.
+ for {
+ check.recordTypeAndValue(f, builtin, sig, nil)
+ switch p := f.(type) {
+ case *ast.Ident, *ast.SelectorExpr:
+ return // we're done
+ case *ast.ParenExpr:
+ f = p.X
+ default:
+ unreachable()
+ }
+ }
+}
+
+// recordCommaOkTypes updates recorded types to reflect that x is used in a commaOk context
+// (and therefore has tuple type).
+func (check *Checker) recordCommaOkTypes(x ast.Expr, a []*operand) {
+ assert(x != nil)
+ assert(len(a) == 2)
+ if a[0].mode == invalid {
+ return
+ }
+ t0, t1 := a[0].typ, a[1].typ
+ assert(isTyped(t0) && isTyped(t1) && (isBoolean(t1) || t1 == universeError))
+ if m := check.Types; m != nil {
+ for {
+ tv := m[x]
+ assert(tv.Type != nil) // should have been recorded already
+ pos := x.Pos()
+ tv.Type = NewTuple(
+ NewVar(pos, check.pkg, "", t0),
+ NewVar(pos, check.pkg, "", t1),
+ )
+ m[x] = tv
+ // if x is a parenthesized expression (p.X), update p.X
+ p, _ := x.(*ast.ParenExpr)
+ if p == nil {
+ break
+ }
+ x = p.X
+ }
+ }
+}
+
+// recordInstance records instantiation information into check.Info, if the
+// Instances map is non-nil. The given expr must be an ident, selector, or
+// index (list) expr with ident or selector operand.
+//
+// TODO(rfindley): the expr parameter is fragile. See if we can access the
+// instantiated identifier in some other way.
+func (check *Checker) recordInstance(expr ast.Expr, targs []Type, typ Type) {
+ ident := instantiatedIdent(expr)
+ assert(ident != nil)
+ assert(typ != nil)
+ if m := check.Instances; m != nil {
+ m[ident] = Instance{newTypeList(targs), typ}
+ }
+}
+
+func instantiatedIdent(expr ast.Expr) *ast.Ident {
+ var selOrIdent ast.Expr
+ switch e := expr.(type) {
+ case *ast.IndexExpr:
+ selOrIdent = e.X
+ case *ast.IndexListExpr:
+ selOrIdent = e.X
+ case *ast.SelectorExpr, *ast.Ident:
+ selOrIdent = e
+ }
+ switch x := selOrIdent.(type) {
+ case *ast.Ident:
+ return x
+ case *ast.SelectorExpr:
+ return x.Sel
+ }
+ panic("instantiated ident not found")
+}
+
+func (check *Checker) recordDef(id *ast.Ident, obj Object) {
+ assert(id != nil)
+ if m := check.Defs; m != nil {
+ m[id] = obj
+ }
+}
+
+func (check *Checker) recordUse(id *ast.Ident, obj Object) {
+ assert(id != nil)
+ assert(obj != nil)
+ if m := check.Uses; m != nil {
+ m[id] = obj
+ }
+}
+
+func (check *Checker) recordImplicit(node ast.Node, obj Object) {
+ assert(node != nil)
+ assert(obj != nil)
+ if m := check.Implicits; m != nil {
+ m[node] = obj
+ }
+}
+
+func (check *Checker) recordSelection(x *ast.SelectorExpr, kind SelectionKind, recv Type, obj Object, index []int, indirect bool) {
+ assert(obj != nil && (recv == nil || len(index) > 0))
+ check.recordUse(x.Sel, obj)
+ if m := check.Selections; m != nil {
+ m[x] = &Selection{kind, recv, obj, index, indirect}
+ }
+}
+
+func (check *Checker) recordScope(node ast.Node, scope *Scope) {
+ assert(node != nil)
+ assert(scope != nil)
+ if m := check.Scopes; m != nil {
+ m[node] = scope
+ }
+}
diff --git a/contrib/go/_std_1.21/src/go/types/const.go b/contrib/go/_std_1.21/src/go/types/const.go
new file mode 100644
index 0000000000..bffea146a0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/const.go
@@ -0,0 +1,307 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2023 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.
+
+// This file implements functions for untyped constant operands.
+
+package types
+
+import (
+ "go/constant"
+ "go/token"
+ . "internal/types/errors"
+ "math"
+)
+
+// overflow checks that the constant x is representable by its type.
+// For untyped constants, it checks that the value doesn't become
+// arbitrarily large.
+func (check *Checker) overflow(x *operand, opPos token.Pos) {
+ assert(x.mode == constant_)
+
+ if x.val.Kind() == constant.Unknown {
+ // TODO(gri) We should report exactly what went wrong. At the
+ // moment we don't have the (go/constant) API for that.
+ // See also TODO in go/constant/value.go.
+ check.error(atPos(opPos), InvalidConstVal, "constant result is not representable")
+ return
+ }
+
+ // Typed constants must be representable in
+ // their type after each constant operation.
+ // x.typ cannot be a type parameter (type
+ // parameters cannot be constant types).
+ if isTyped(x.typ) {
+ check.representable(x, under(x.typ).(*Basic))
+ return
+ }
+
+ // Untyped integer values must not grow arbitrarily.
+ const prec = 512 // 512 is the constant precision
+ if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
+ op := opName(x.expr)
+ if op != "" {
+ op += " "
+ }
+ check.errorf(atPos(opPos), InvalidConstVal, "constant %soverflow", op)
+ x.val = constant.MakeUnknown()
+ }
+}
+
+// representableConst reports whether x can be represented as
+// value of the given basic type and for the configuration
+// provided (only needed for int/uint sizes).
+//
+// If rounded != nil, *rounded is set to the rounded value of x for
+// representable floating-point and complex values, and to an Int
+// value for integer values; it is left alone otherwise.
+// It is ok to provide the addressof the first argument for rounded.
+//
+// The check parameter may be nil if representableConst is invoked
+// (indirectly) through an exported API call (AssignableTo, ConvertibleTo)
+// because we don't need the Checker's config for those calls.
+func representableConst(x constant.Value, check *Checker, typ *Basic, rounded *constant.Value) bool {
+ if x.Kind() == constant.Unknown {
+ return true // avoid follow-up errors
+ }
+
+ var conf *Config
+ if check != nil {
+ conf = check.conf
+ }
+
+ sizeof := func(T Type) int64 {
+ s := conf.sizeof(T)
+ return s
+ }
+
+ switch {
+ case isInteger(typ):
+ x := constant.ToInt(x)
+ if x.Kind() != constant.Int {
+ return false
+ }
+ if rounded != nil {
+ *rounded = x
+ }
+ if x, ok := constant.Int64Val(x); ok {
+ switch typ.kind {
+ case Int:
+ var s = uint(sizeof(typ)) * 8
+ return int64(-1)<<(s-1) <= x && x <= int64(1)<<(s-1)-1
+ case Int8:
+ const s = 8
+ return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+ case Int16:
+ const s = 16
+ return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+ case Int32:
+ const s = 32
+ return -1<<(s-1) <= x && x <= 1<<(s-1)-1
+ case Int64, UntypedInt:
+ return true
+ case Uint, Uintptr:
+ if s := uint(sizeof(typ)) * 8; s < 64 {
+ return 0 <= x && x <= int64(1)<<s-1
+ }
+ return 0 <= x
+ case Uint8:
+ const s = 8
+ return 0 <= x && x <= 1<<s-1
+ case Uint16:
+ const s = 16
+ return 0 <= x && x <= 1<<s-1
+ case Uint32:
+ const s = 32
+ return 0 <= x && x <= 1<<s-1
+ case Uint64:
+ return 0 <= x
+ default:
+ unreachable()
+ }
+ }
+ // x does not fit into int64
+ switch n := constant.BitLen(x); typ.kind {
+ case Uint, Uintptr:
+ var s = uint(sizeof(typ)) * 8
+ return constant.Sign(x) >= 0 && n <= int(s)
+ case Uint64:
+ return constant.Sign(x) >= 0 && n <= 64
+ case UntypedInt:
+ return true
+ }
+
+ case isFloat(typ):
+ x := constant.ToFloat(x)
+ if x.Kind() != constant.Float {
+ return false
+ }
+ switch typ.kind {
+ case Float32:
+ if rounded == nil {
+ return fitsFloat32(x)
+ }
+ r := roundFloat32(x)
+ if r != nil {
+ *rounded = r
+ return true
+ }
+ case Float64:
+ if rounded == nil {
+ return fitsFloat64(x)
+ }
+ r := roundFloat64(x)
+ if r != nil {
+ *rounded = r
+ return true
+ }
+ case UntypedFloat:
+ return true
+ default:
+ unreachable()
+ }
+
+ case isComplex(typ):
+ x := constant.ToComplex(x)
+ if x.Kind() != constant.Complex {
+ return false
+ }
+ switch typ.kind {
+ case Complex64:
+ if rounded == nil {
+ return fitsFloat32(constant.Real(x)) && fitsFloat32(constant.Imag(x))
+ }
+ re := roundFloat32(constant.Real(x))
+ im := roundFloat32(constant.Imag(x))
+ if re != nil && im != nil {
+ *rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+ return true
+ }
+ case Complex128:
+ if rounded == nil {
+ return fitsFloat64(constant.Real(x)) && fitsFloat64(constant.Imag(x))
+ }
+ re := roundFloat64(constant.Real(x))
+ im := roundFloat64(constant.Imag(x))
+ if re != nil && im != nil {
+ *rounded = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
+ return true
+ }
+ case UntypedComplex:
+ return true
+ default:
+ unreachable()
+ }
+
+ case isString(typ):
+ return x.Kind() == constant.String
+
+ case isBoolean(typ):
+ return x.Kind() == constant.Bool
+ }
+
+ return false
+}
+
+func fitsFloat32(x constant.Value) bool {
+ f32, _ := constant.Float32Val(x)
+ f := float64(f32)
+ return !math.IsInf(f, 0)
+}
+
+func roundFloat32(x constant.Value) constant.Value {
+ f32, _ := constant.Float32Val(x)
+ f := float64(f32)
+ if !math.IsInf(f, 0) {
+ return constant.MakeFloat64(f)
+ }
+ return nil
+}
+
+func fitsFloat64(x constant.Value) bool {
+ f, _ := constant.Float64Val(x)
+ return !math.IsInf(f, 0)
+}
+
+func roundFloat64(x constant.Value) constant.Value {
+ f, _ := constant.Float64Val(x)
+ if !math.IsInf(f, 0) {
+ return constant.MakeFloat64(f)
+ }
+ return nil
+}
+
+// representable checks that a constant operand is representable in the given
+// basic type.
+func (check *Checker) representable(x *operand, typ *Basic) {
+ v, code := check.representation(x, typ)
+ if code != 0 {
+ check.invalidConversion(code, x, typ)
+ x.mode = invalid
+ return
+ }
+ assert(v != nil)
+ x.val = v
+}
+
+// representation returns the representation of the constant operand x as the
+// basic type typ.
+//
+// If no such representation is possible, it returns a non-zero error code.
+func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, Code) {
+ assert(x.mode == constant_)
+ v := x.val
+ if !representableConst(x.val, check, typ, &v) {
+ if isNumeric(x.typ) && isNumeric(typ) {
+ // numeric conversion : error msg
+ //
+ // integer -> integer : overflows
+ // integer -> float : overflows (actually not possible)
+ // float -> integer : truncated
+ // float -> float : overflows
+ //
+ if !isInteger(x.typ) && isInteger(typ) {
+ return nil, TruncatedFloat
+ } else {
+ return nil, NumericOverflow
+ }
+ }
+ return nil, InvalidConstVal
+ }
+ return v, 0
+}
+
+func (check *Checker) invalidConversion(code Code, x *operand, target Type) {
+ msg := "cannot convert %s to type %s"
+ switch code {
+ case TruncatedFloat:
+ msg = "%s truncated to %s"
+ case NumericOverflow:
+ msg = "%s overflows %s"
+ }
+ check.errorf(x, code, msg, x, target)
+}
+
+// convertUntyped attempts to set the type of an untyped value to the target type.
+func (check *Checker) convertUntyped(x *operand, target Type) {
+ newType, val, code := check.implicitTypeAndValue(x, target)
+ if code != 0 {
+ t := target
+ if !isTypeParam(target) {
+ t = safeUnderlying(target)
+ }
+ check.invalidConversion(code, x, t)
+ x.mode = invalid
+ return
+ }
+ if val != nil {
+ x.val = val
+ check.updateExprVal(x.expr, val)
+ }
+ if newType != x.typ {
+ x.typ = newType
+ check.updateExprType(x.expr, newType, false)
+ }
+}
diff --git a/contrib/go/_std_1.21/src/go/types/context.go b/contrib/go/_std_1.21/src/go/types/context.go
new file mode 100644
index 0000000000..56368e1060
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/context.go
@@ -0,0 +1,146 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// 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 types
+
+import (
+ "bytes"
+ "fmt"
+ "strconv"
+ "strings"
+ "sync"
+)
+
+// This file contains a definition of the type-checking context; an opaque type
+// that may be supplied by users during instantiation.
+//
+// Contexts serve two purposes:
+// - reduce the duplication of identical instances
+// - short-circuit instantiation cycles
+//
+// For the latter purpose, we must always have a context during instantiation,
+// whether or not it is supplied by the user. For both purposes, it must be the
+// case that hashing a pointer-identical type produces consistent results
+// (somewhat obviously).
+//
+// However, neither of these purposes require that our hash is perfect, and so
+// this was not an explicit design goal of the context type. In fact, due to
+// concurrent use it is convenient not to guarantee de-duplication.
+//
+// Nevertheless, in the future it could be helpful to allow users to leverage
+// contexts to canonicalize instances, and it would probably be possible to
+// achieve such a guarantee.
+
+// A Context is an opaque type checking context. It may be used to share
+// identical type instances across type-checked packages or calls to
+// Instantiate. Contexts are safe for concurrent use.
+//
+// The use of a shared context does not guarantee that identical instances are
+// deduplicated in all cases.
+type Context struct {
+ mu sync.Mutex
+ typeMap map[string][]ctxtEntry // type hash -> instances entries
+ nextID int // next unique ID
+ originIDs map[Type]int // origin type -> unique ID
+}
+
+type ctxtEntry struct {
+ orig Type
+ targs []Type
+ instance Type // = orig[targs]
+}
+
+// NewContext creates a new Context.
+func NewContext() *Context {
+ return &Context{
+ typeMap: make(map[string][]ctxtEntry),
+ originIDs: make(map[Type]int),
+ }
+}
+
+// instanceHash returns a string representation of typ instantiated with targs.
+// The hash should be a perfect hash, though out of caution the type checker
+// does not assume this. The result is guaranteed to not contain blanks.
+func (ctxt *Context) instanceHash(orig Type, targs []Type) string {
+ assert(ctxt != nil)
+ assert(orig != nil)
+ var buf bytes.Buffer
+
+ h := newTypeHasher(&buf, ctxt)
+ h.string(strconv.Itoa(ctxt.getID(orig)))
+ // Because we've already written the unique origin ID this call to h.typ is
+ // unnecessary, but we leave it for hash readability. It can be removed later
+ // if performance is an issue.
+ h.typ(orig)
+ if len(targs) > 0 {
+ // TODO(rfindley): consider asserting on isGeneric(typ) here, if and when
+ // isGeneric handles *Signature types.
+ h.typeList(targs)
+ }
+
+ return strings.Replace(buf.String(), " ", "#", -1) // ReplaceAll is not available in Go1.4
+}
+
+// lookup returns an existing instantiation of orig with targs, if it exists.
+// Otherwise, it returns nil.
+func (ctxt *Context) lookup(h string, orig Type, targs []Type) Type {
+ ctxt.mu.Lock()
+ defer ctxt.mu.Unlock()
+
+ for _, e := range ctxt.typeMap[h] {
+ if identicalInstance(orig, targs, e.orig, e.targs) {
+ return e.instance
+ }
+ if debug {
+ // Panic during development to surface any imperfections in our hash.
+ panic(fmt.Sprintf("non-identical instances: (orig: %s, targs: %v) and %s", orig, targs, e.instance))
+ }
+ }
+
+ return nil
+}
+
+// update de-duplicates n against previously seen types with the hash h. If an
+// identical type is found with the type hash h, the previously seen type is
+// returned. Otherwise, n is returned, and recorded in the Context for the hash
+// h.
+func (ctxt *Context) update(h string, orig Type, targs []Type, inst Type) Type {
+ assert(inst != nil)
+
+ ctxt.mu.Lock()
+ defer ctxt.mu.Unlock()
+
+ for _, e := range ctxt.typeMap[h] {
+ if inst == nil || Identical(inst, e.instance) {
+ return e.instance
+ }
+ if debug {
+ // Panic during development to surface any imperfections in our hash.
+ panic(fmt.Sprintf("%s and %s are not identical", inst, e.instance))
+ }
+ }
+
+ ctxt.typeMap[h] = append(ctxt.typeMap[h], ctxtEntry{
+ orig: orig,
+ targs: targs,
+ instance: inst,
+ })
+
+ return inst
+}
+
+// getID returns a unique ID for the type t.
+func (ctxt *Context) getID(t Type) int {
+ ctxt.mu.Lock()
+ defer ctxt.mu.Unlock()
+ id, ok := ctxt.originIDs[t]
+ if !ok {
+ id = ctxt.nextID
+ ctxt.originIDs[t] = id
+ ctxt.nextID++
+ }
+ return id
+}
diff --git a/contrib/go/_std_1.21/src/go/types/conversions.go b/contrib/go/_std_1.21/src/go/types/conversions.go
new file mode 100644
index 0000000000..2fa3f92837
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/conversions.go
@@ -0,0 +1,296 @@
+// Copyright 2012 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.
+
+// This file implements typechecking of conversions.
+
+package types
+
+import (
+ "go/constant"
+ . "internal/types/errors"
+ "unicode"
+)
+
+// conversion type-checks the conversion T(x).
+// The result is in x.
+func (check *Checker) conversion(x *operand, T Type) {
+ constArg := x.mode == constant_
+
+ constConvertibleTo := func(T Type, val *constant.Value) bool {
+ switch t, _ := under(T).(*Basic); {
+ case t == nil:
+ // nothing to do
+ case representableConst(x.val, check, t, val):
+ return true
+ case isInteger(x.typ) && isString(t):
+ codepoint := unicode.ReplacementChar
+ if i, ok := constant.Uint64Val(x.val); ok && i <= unicode.MaxRune {
+ codepoint = rune(i)
+ }
+ if val != nil {
+ *val = constant.MakeString(string(codepoint))
+ }
+ return true
+ }
+ return false
+ }
+
+ var ok bool
+ var cause string
+ switch {
+ case constArg && isConstType(T):
+ // constant conversion
+ ok = constConvertibleTo(T, &x.val)
+ case constArg && isTypeParam(T):
+ // x is convertible to T if it is convertible
+ // to each specific type in the type set of T.
+ // If T's type set is empty, or if it doesn't
+ // have specific types, constant x cannot be
+ // converted.
+ ok = T.(*TypeParam).underIs(func(u Type) bool {
+ // u is nil if there are no specific type terms
+ if u == nil {
+ cause = check.sprintf("%s does not contain specific types", T)
+ return false
+ }
+ if isString(x.typ) && isBytesOrRunes(u) {
+ return true
+ }
+ if !constConvertibleTo(u, nil) {
+ cause = check.sprintf("cannot convert %s to type %s (in %s)", x, u, T)
+ return false
+ }
+ return true
+ })
+ x.mode = value // type parameters are not constants
+ case x.convertibleTo(check, T, &cause):
+ // non-constant conversion
+ ok = true
+ x.mode = value
+ }
+
+ if !ok {
+ if cause != "" {
+ check.errorf(x, InvalidConversion, "cannot convert %s to type %s: %s", x, T, cause)
+ } else {
+ check.errorf(x, InvalidConversion, "cannot convert %s to type %s", x, T)
+ }
+ x.mode = invalid
+ return
+ }
+
+ // The conversion argument types are final. For untyped values the
+ // conversion provides the type, per the spec: "A constant may be
+ // given a type explicitly by a constant declaration or conversion,...".
+ if isUntyped(x.typ) {
+ final := T
+ // - For conversions to interfaces, use the argument's default type.
+ // - For conversions of untyped constants to non-constant types, also
+ // use the default type (e.g., []byte("foo") should report string
+ // not []byte as type for the constant "foo").
+ // - Keep untyped nil for untyped nil arguments.
+ // - For constant integer to string conversions, keep the argument type.
+ // (See also the TODO below.)
+ if isNonTypeParamInterface(T) || constArg && !isConstType(T) || x.isNil() {
+ final = Default(x.typ) // default type of untyped nil is untyped nil
+ } else if x.mode == constant_ && isInteger(x.typ) && allString(T) {
+ final = x.typ
+ }
+ check.updateExprType(x.expr, final, true)
+ }
+
+ x.typ = T
+}
+
+// TODO(gri) convertibleTo checks if T(x) is valid. It assumes that the type
+// of x is fully known, but that's not the case for say string(1<<s + 1.0):
+// Here, the type of 1<<s + 1.0 will be UntypedFloat which will lead to the
+// (correct!) refusal of the conversion. But the reported error is essentially
+// "cannot convert untyped float value to string", yet the correct error (per
+// the spec) is that we cannot shift a floating-point value: 1 in 1<<s should
+// be converted to UntypedFloat because of the addition of 1.0. Fixing this
+// is tricky because we'd have to run updateExprType on the argument first.
+// (go.dev/issue/21982.)
+
+// convertibleTo reports whether T(x) is valid. In the failure case, *cause
+// may be set to the cause for the failure.
+// The check parameter may be nil if convertibleTo is invoked through an
+// exported API call, i.e., when all methods have been type-checked.
+func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool {
+ // "x is assignable to T"
+ if ok, _ := x.assignableTo(check, T, cause); ok {
+ return true
+ }
+
+ // "V and T have identical underlying types if tags are ignored
+ // and V and T are not type parameters"
+ V := x.typ
+ Vu := under(V)
+ Tu := under(T)
+ Vp, _ := V.(*TypeParam)
+ Tp, _ := T.(*TypeParam)
+ if IdenticalIgnoreTags(Vu, Tu) && Vp == nil && Tp == nil {
+ return true
+ }
+
+ // "V and T are unnamed pointer types and their pointer base types
+ // have identical underlying types if tags are ignored
+ // and their pointer base types are not type parameters"
+ if V, ok := V.(*Pointer); ok {
+ if T, ok := T.(*Pointer); ok {
+ if IdenticalIgnoreTags(under(V.base), under(T.base)) && !isTypeParam(V.base) && !isTypeParam(T.base) {
+ return true
+ }
+ }
+ }
+
+ // "V and T are both integer or floating point types"
+ if isIntegerOrFloat(Vu) && isIntegerOrFloat(Tu) {
+ return true
+ }
+
+ // "V and T are both complex types"
+ if isComplex(Vu) && isComplex(Tu) {
+ return true
+ }
+
+ // "V is an integer or a slice of bytes or runes and T is a string type"
+ if (isInteger(Vu) || isBytesOrRunes(Vu)) && isString(Tu) {
+ return true
+ }
+
+ // "V is a string and T is a slice of bytes or runes"
+ if isString(Vu) && isBytesOrRunes(Tu) {
+ return true
+ }
+
+ // package unsafe:
+ // "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
+ if (isPointer(Vu) || isUintptr(Vu)) && isUnsafePointer(Tu) {
+ return true
+ }
+ // "and vice versa"
+ if isUnsafePointer(Vu) && (isPointer(Tu) || isUintptr(Tu)) {
+ return true
+ }
+
+ // "V is a slice, T is an array or pointer-to-array type,
+ // and the slice and array types have identical element types."
+ if s, _ := Vu.(*Slice); s != nil {
+ switch a := Tu.(type) {
+ case *Array:
+ if Identical(s.Elem(), a.Elem()) {
+ if check == nil || check.allowVersion(check.pkg, x, go1_20) {
+ return true
+ }
+ // check != nil
+ if cause != nil {
+ // TODO(gri) consider restructuring versionErrorf so we can use it here and below
+ *cause = "conversion of slices to arrays requires go1.20 or later"
+ }
+ return false
+ }
+ case *Pointer:
+ if a, _ := under(a.Elem()).(*Array); a != nil {
+ if Identical(s.Elem(), a.Elem()) {
+ if check == nil || check.allowVersion(check.pkg, x, go1_17) {
+ return true
+ }
+ // check != nil
+ if cause != nil {
+ *cause = "conversion of slices to array pointers requires go1.17 or later"
+ }
+ return false
+ }
+ }
+ }
+ }
+
+ // optimization: if we don't have type parameters, we're done
+ if Vp == nil && Tp == nil {
+ return false
+ }
+
+ errorf := func(format string, args ...any) {
+ if check != nil && cause != nil {
+ msg := check.sprintf(format, args...)
+ if *cause != "" {
+ msg += "\n\t" + *cause
+ }
+ *cause = msg
+ }
+ }
+
+ // generic cases with specific type terms
+ // (generic operands cannot be constants, so we can ignore x.val)
+ switch {
+ case Vp != nil && Tp != nil:
+ x := *x // don't clobber outer x
+ return Vp.is(func(V *term) bool {
+ if V == nil {
+ return false // no specific types
+ }
+ x.typ = V.typ
+ return Tp.is(func(T *term) bool {
+ if T == nil {
+ return false // no specific types
+ }
+ if !x.convertibleTo(check, T.typ, cause) {
+ errorf("cannot convert %s (in %s) to type %s (in %s)", V.typ, Vp, T.typ, Tp)
+ return false
+ }
+ return true
+ })
+ })
+ case Vp != nil:
+ x := *x // don't clobber outer x
+ return Vp.is(func(V *term) bool {
+ if V == nil {
+ return false // no specific types
+ }
+ x.typ = V.typ
+ if !x.convertibleTo(check, T, cause) {
+ errorf("cannot convert %s (in %s) to type %s", V.typ, Vp, T)
+ return false
+ }
+ return true
+ })
+ case Tp != nil:
+ return Tp.is(func(T *term) bool {
+ if T == nil {
+ return false // no specific types
+ }
+ if !x.convertibleTo(check, T.typ, cause) {
+ errorf("cannot convert %s to type %s (in %s)", x.typ, T.typ, Tp)
+ return false
+ }
+ return true
+ })
+ }
+
+ return false
+}
+
+func isUintptr(typ Type) bool {
+ t, _ := under(typ).(*Basic)
+ return t != nil && t.kind == Uintptr
+}
+
+func isUnsafePointer(typ Type) bool {
+ t, _ := under(typ).(*Basic)
+ return t != nil && t.kind == UnsafePointer
+}
+
+func isPointer(typ Type) bool {
+ _, ok := under(typ).(*Pointer)
+ return ok
+}
+
+func isBytesOrRunes(typ Type) bool {
+ if s, _ := under(typ).(*Slice); s != nil {
+ t, _ := under(s.elem).(*Basic)
+ return t != nil && (t.kind == Byte || t.kind == Rune)
+ }
+ return false
+}
diff --git a/contrib/go/_std_1.21/src/go/types/decl.go b/contrib/go/_std_1.21/src/go/types/decl.go
new file mode 100644
index 0000000000..af8ec8435e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/decl.go
@@ -0,0 +1,932 @@
+// Copyright 2014 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 types
+
+import (
+ "fmt"
+ "go/ast"
+ "go/constant"
+ "go/token"
+ . "internal/types/errors"
+)
+
+func (check *Checker) reportAltDecl(obj Object) {
+ if pos := obj.Pos(); pos.IsValid() {
+ // We use "other" rather than "previous" here because
+ // the first declaration seen may not be textually
+ // earlier in the source.
+ check.errorf(obj, DuplicateDecl, "\tother declaration of %s", obj.Name()) // secondary error, \t indented
+ }
+}
+
+func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) {
+ // spec: "The blank identifier, represented by the underscore
+ // character _, may be used in a declaration like any other
+ // identifier but the declaration does not introduce a new
+ // binding."
+ if obj.Name() != "_" {
+ if alt := scope.Insert(obj); alt != nil {
+ check.errorf(obj, DuplicateDecl, "%s redeclared in this block", obj.Name())
+ check.reportAltDecl(alt)
+ return
+ }
+ obj.setScopePos(pos)
+ }
+ if id != nil {
+ check.recordDef(id, obj)
+ }
+}
+
+// pathString returns a string of the form a->b-> ... ->g for a path [a, b, ... g].
+func pathString(path []Object) string {
+ var s string
+ for i, p := range path {
+ if i > 0 {
+ s += "->"
+ }
+ s += p.Name()
+ }
+ return s
+}
+
+// objDecl type-checks the declaration of obj in its respective (file) environment.
+// For the meaning of def, see Checker.definedType, in typexpr.go.
+func (check *Checker) objDecl(obj Object, def *Named) {
+ if check.conf._Trace && obj.Type() == nil {
+ if check.indent == 0 {
+ fmt.Println() // empty line between top-level objects for readability
+ }
+ check.trace(obj.Pos(), "-- checking %s (%s, objPath = %s)", obj, obj.color(), pathString(check.objPath))
+ check.indent++
+ defer func() {
+ check.indent--
+ check.trace(obj.Pos(), "=> %s (%s)", obj, obj.color())
+ }()
+ }
+
+ // Checking the declaration of obj means inferring its type
+ // (and possibly its value, for constants).
+ // An object's type (and thus the object) may be in one of
+ // three states which are expressed by colors:
+ //
+ // - an object whose type is not yet known is painted white (initial color)
+ // - an object whose type is in the process of being inferred is painted grey
+ // - an object whose type is fully inferred is painted black
+ //
+ // During type inference, an object's color changes from white to grey
+ // to black (pre-declared objects are painted black from the start).
+ // A black object (i.e., its type) can only depend on (refer to) other black
+ // ones. White and grey objects may depend on white and black objects.
+ // A dependency on a grey object indicates a cycle which may or may not be
+ // valid.
+ //
+ // When objects turn grey, they are pushed on the object path (a stack);
+ // they are popped again when they turn black. Thus, if a grey object (a
+ // cycle) is encountered, it is on the object path, and all the objects
+ // it depends on are the remaining objects on that path. Color encoding
+ // is such that the color value of a grey object indicates the index of
+ // that object in the object path.
+
+ // During type-checking, white objects may be assigned a type without
+ // traversing through objDecl; e.g., when initializing constants and
+ // variables. Update the colors of those objects here (rather than
+ // everywhere where we set the type) to satisfy the color invariants.
+ if obj.color() == white && obj.Type() != nil {
+ obj.setColor(black)
+ return
+ }
+
+ switch obj.color() {
+ case white:
+ assert(obj.Type() == nil)
+ // All color values other than white and black are considered grey.
+ // Because black and white are < grey, all values >= grey are grey.
+ // Use those values to encode the object's index into the object path.
+ obj.setColor(grey + color(check.push(obj)))
+ defer func() {
+ check.pop().setColor(black)
+ }()
+
+ case black:
+ assert(obj.Type() != nil)
+ return
+
+ default:
+ // Color values other than white or black are considered grey.
+ fallthrough
+
+ case grey:
+ // We have a (possibly invalid) cycle.
+ // In the existing code, this is marked by a non-nil type
+ // for the object except for constants and variables whose
+ // type may be non-nil (known), or nil if it depends on the
+ // not-yet known initialization value.
+ // In the former case, set the type to Typ[Invalid] because
+ // we have an initialization cycle. The cycle error will be
+ // reported later, when determining initialization order.
+ // TODO(gri) Report cycle here and simplify initialization
+ // order code.
+ switch obj := obj.(type) {
+ case *Const:
+ if !check.validCycle(obj) || obj.typ == nil {
+ obj.typ = Typ[Invalid]
+ }
+
+ case *Var:
+ if !check.validCycle(obj) || obj.typ == nil {
+ obj.typ = Typ[Invalid]
+ }
+
+ case *TypeName:
+ if !check.validCycle(obj) {
+ // break cycle
+ // (without this, calling underlying()
+ // below may lead to an endless loop
+ // if we have a cycle for a defined
+ // (*Named) type)
+ obj.typ = Typ[Invalid]
+ }
+
+ case *Func:
+ if !check.validCycle(obj) {
+ // Don't set obj.typ to Typ[Invalid] here
+ // because plenty of code type-asserts that
+ // functions have a *Signature type. Grey
+ // functions have their type set to an empty
+ // signature which makes it impossible to
+ // initialize a variable with the function.
+ }
+
+ default:
+ unreachable()
+ }
+ assert(obj.Type() != nil)
+ return
+ }
+
+ d := check.objMap[obj]
+ if d == nil {
+ check.dump("%v: %s should have been declared", obj.Pos(), obj)
+ unreachable()
+ }
+
+ // save/restore current environment and set up object environment
+ defer func(env environment) {
+ check.environment = env
+ }(check.environment)
+ check.environment = environment{
+ scope: d.file,
+ }
+
+ // Const and var declarations must not have initialization
+ // cycles. We track them by remembering the current declaration
+ // in check.decl. Initialization expressions depending on other
+ // consts, vars, or functions, add dependencies to the current
+ // check.decl.
+ switch obj := obj.(type) {
+ case *Const:
+ check.decl = d // new package-level const decl
+ check.constDecl(obj, d.vtyp, d.init, d.inherited)
+ case *Var:
+ check.decl = d // new package-level var decl
+ check.varDecl(obj, d.lhs, d.vtyp, d.init)
+ case *TypeName:
+ // invalid recursive types are detected via path
+ check.typeDecl(obj, d.tdecl, def)
+ check.collectMethods(obj) // methods can only be added to top-level types
+ case *Func:
+ // functions may be recursive - no need to track dependencies
+ check.funcDecl(obj, d)
+ default:
+ unreachable()
+ }
+}
+
+// validCycle checks if the cycle starting with obj is valid and
+// reports an error if it is not.
+func (check *Checker) validCycle(obj Object) (valid bool) {
+ // The object map contains the package scope objects and the non-interface methods.
+ if debug {
+ info := check.objMap[obj]
+ inObjMap := info != nil && (info.fdecl == nil || info.fdecl.Recv == nil) // exclude methods
+ isPkgObj := obj.Parent() == check.pkg.scope
+ if isPkgObj != inObjMap {
+ check.dump("%v: inconsistent object map for %s (isPkgObj = %v, inObjMap = %v)", obj.Pos(), obj, isPkgObj, inObjMap)
+ unreachable()
+ }
+ }
+
+ // Count cycle objects.
+ assert(obj.color() >= grey)
+ start := obj.color() - grey // index of obj in objPath
+ cycle := check.objPath[start:]
+ tparCycle := false // if set, the cycle is through a type parameter list
+ nval := 0 // number of (constant or variable) values in the cycle; valid if !generic
+ ndef := 0 // number of type definitions in the cycle; valid if !generic
+loop:
+ for _, obj := range cycle {
+ switch obj := obj.(type) {
+ case *Const, *Var:
+ nval++
+ case *TypeName:
+ // If we reach a generic type that is part of a cycle
+ // and we are in a type parameter list, we have a cycle
+ // through a type parameter list, which is invalid.
+ if check.inTParamList && isGeneric(obj.typ) {
+ tparCycle = true
+ break loop
+ }
+
+ // Determine if the type name is an alias or not. For
+ // package-level objects, use the object map which
+ // provides syntactic information (which doesn't rely
+ // on the order in which the objects are set up). For
+ // local objects, we can rely on the order, so use
+ // the object's predicate.
+ // TODO(gri) It would be less fragile to always access
+ // the syntactic information. We should consider storing
+ // this information explicitly in the object.
+ var alias bool
+ if d := check.objMap[obj]; d != nil {
+ alias = d.tdecl.Assign.IsValid() // package-level object
+ } else {
+ alias = obj.IsAlias() // function local object
+ }
+ if !alias {
+ ndef++
+ }
+ case *Func:
+ // ignored for now
+ default:
+ unreachable()
+ }
+ }
+
+ if check.conf._Trace {
+ check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", pathString(cycle), obj.Name(), len(cycle))
+ if tparCycle {
+ check.trace(obj.Pos(), "## cycle contains: generic type in a type parameter list")
+ } else {
+ check.trace(obj.Pos(), "## cycle contains: %d values, %d type definitions", nval, ndef)
+ }
+ defer func() {
+ if valid {
+ check.trace(obj.Pos(), "=> cycle is valid")
+ } else {
+ check.trace(obj.Pos(), "=> error: cycle is invalid")
+ }
+ }()
+ }
+
+ if !tparCycle {
+ // A cycle involving only constants and variables is invalid but we
+ // ignore them here because they are reported via the initialization
+ // cycle check.
+ if nval == len(cycle) {
+ return true
+ }
+
+ // A cycle involving only types (and possibly functions) must have at least
+ // one type definition to be permitted: If there is no type definition, we
+ // have a sequence of alias type names which will expand ad infinitum.
+ if nval == 0 && ndef > 0 {
+ return true
+ }
+ }
+
+ check.cycleError(cycle)
+ return false
+}
+
+// cycleError reports a declaration cycle starting with
+// the object in cycle that is "first" in the source.
+func (check *Checker) cycleError(cycle []Object) {
+ // name returns the (possibly qualified) object name.
+ // This is needed because with generic types, cycles
+ // may refer to imported types. See go.dev/issue/50788.
+ // TODO(gri) Thus functionality is used elsewhere. Factor it out.
+ name := func(obj Object) string {
+ return packagePrefix(obj.Pkg(), check.qualifier) + obj.Name()
+ }
+
+ // TODO(gri) Should we start with the last (rather than the first) object in the cycle
+ // since that is the earliest point in the source where we start seeing the
+ // cycle? That would be more consistent with other error messages.
+ i := firstInSrc(cycle)
+ obj := cycle[i]
+ objName := name(obj)
+ // If obj is a type alias, mark it as valid (not broken) in order to avoid follow-on errors.
+ tname, _ := obj.(*TypeName)
+ if tname != nil && tname.IsAlias() {
+ check.validAlias(tname, Typ[Invalid])
+ }
+
+ // report a more concise error for self references
+ if len(cycle) == 1 {
+ if tname != nil {
+ check.errorf(obj, InvalidDeclCycle, "invalid recursive type: %s refers to itself", objName)
+ } else {
+ check.errorf(obj, InvalidDeclCycle, "invalid cycle in declaration: %s refers to itself", objName)
+ }
+ return
+ }
+
+ if tname != nil {
+ check.errorf(obj, InvalidDeclCycle, "invalid recursive type %s", objName)
+ } else {
+ check.errorf(obj, InvalidDeclCycle, "invalid cycle in declaration of %s", objName)
+ }
+ for range cycle {
+ check.errorf(obj, InvalidDeclCycle, "\t%s refers to", objName) // secondary error, \t indented
+ i++
+ if i >= len(cycle) {
+ i = 0
+ }
+ obj = cycle[i]
+ objName = name(obj)
+ }
+ check.errorf(obj, InvalidDeclCycle, "\t%s", objName)
+}
+
+// firstInSrc reports the index of the object with the "smallest"
+// source position in path. path must not be empty.
+func firstInSrc(path []Object) int {
+ fst, pos := 0, path[0].Pos()
+ for i, t := range path[1:] {
+ if cmpPos(t.Pos(), pos) < 0 {
+ fst, pos = i+1, t.Pos()
+ }
+ }
+ return fst
+}
+
+type (
+ decl interface {
+ node() ast.Node
+ }
+
+ importDecl struct{ spec *ast.ImportSpec }
+ constDecl struct {
+ spec *ast.ValueSpec
+ iota int
+ typ ast.Expr
+ init []ast.Expr
+ inherited bool
+ }
+ varDecl struct{ spec *ast.ValueSpec }
+ typeDecl struct{ spec *ast.TypeSpec }
+ funcDecl struct{ decl *ast.FuncDecl }
+)
+
+func (d importDecl) node() ast.Node { return d.spec }
+func (d constDecl) node() ast.Node { return d.spec }
+func (d varDecl) node() ast.Node { return d.spec }
+func (d typeDecl) node() ast.Node { return d.spec }
+func (d funcDecl) node() ast.Node { return d.decl }
+
+func (check *Checker) walkDecls(decls []ast.Decl, f func(decl)) {
+ for _, d := range decls {
+ check.walkDecl(d, f)
+ }
+}
+
+func (check *Checker) walkDecl(d ast.Decl, f func(decl)) {
+ switch d := d.(type) {
+ case *ast.BadDecl:
+ // ignore
+ case *ast.GenDecl:
+ var last *ast.ValueSpec // last ValueSpec with type or init exprs seen
+ for iota, s := range d.Specs {
+ switch s := s.(type) {
+ case *ast.ImportSpec:
+ f(importDecl{s})
+ case *ast.ValueSpec:
+ switch d.Tok {
+ case token.CONST:
+ // determine which initialization expressions to use
+ inherited := true
+ switch {
+ case s.Type != nil || len(s.Values) > 0:
+ last = s
+ inherited = false
+ case last == nil:
+ last = new(ast.ValueSpec) // make sure last exists
+ inherited = false
+ }
+ check.arityMatch(s, last)
+ f(constDecl{spec: s, iota: iota, typ: last.Type, init: last.Values, inherited: inherited})
+ case token.VAR:
+ check.arityMatch(s, nil)
+ f(varDecl{s})
+ default:
+ check.errorf(s, InvalidSyntaxTree, "invalid token %s", d.Tok)
+ }
+ case *ast.TypeSpec:
+ f(typeDecl{s})
+ default:
+ check.errorf(s, InvalidSyntaxTree, "unknown ast.Spec node %T", s)
+ }
+ }
+ case *ast.FuncDecl:
+ f(funcDecl{d})
+ default:
+ check.errorf(d, InvalidSyntaxTree, "unknown ast.Decl node %T", d)
+ }
+}
+
+func (check *Checker) constDecl(obj *Const, typ, init ast.Expr, inherited bool) {
+ assert(obj.typ == nil)
+
+ // use the correct value of iota
+ defer func(iota constant.Value, errpos positioner) {
+ check.iota = iota
+ check.errpos = errpos
+ }(check.iota, check.errpos)
+ check.iota = obj.val
+ check.errpos = nil
+
+ // provide valid constant value under all circumstances
+ obj.val = constant.MakeUnknown()
+
+ // determine type, if any
+ if typ != nil {
+ t := check.typ(typ)
+ if !isConstType(t) {
+ // don't report an error if the type is an invalid C (defined) type
+ // (go.dev/issue/22090)
+ if under(t) != Typ[Invalid] {
+ check.errorf(typ, InvalidConstType, "invalid constant type %s", t)
+ }
+ obj.typ = Typ[Invalid]
+ return
+ }
+ obj.typ = t
+ }
+
+ // check initialization
+ var x operand
+ if init != nil {
+ if inherited {
+ // The initialization expression is inherited from a previous
+ // constant declaration, and (error) positions refer to that
+ // expression and not the current constant declaration. Use
+ // the constant identifier position for any errors during
+ // init expression evaluation since that is all we have
+ // (see issues go.dev/issue/42991, go.dev/issue/42992).
+ check.errpos = atPos(obj.pos)
+ }
+ check.expr(nil, &x, init)
+ }
+ check.initConst(obj, &x)
+}
+
+func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
+ assert(obj.typ == nil)
+
+ // determine type, if any
+ if typ != nil {
+ obj.typ = check.varType(typ)
+ // We cannot spread the type to all lhs variables if there
+ // are more than one since that would mark them as checked
+ // (see Checker.objDecl) and the assignment of init exprs,
+ // if any, would not be checked.
+ //
+ // TODO(gri) If we have no init expr, we should distribute
+ // a given type otherwise we need to re-evalate the type
+ // expr for each lhs variable, leading to duplicate work.
+ }
+
+ // check initialization
+ if init == nil {
+ if typ == nil {
+ // error reported before by arityMatch
+ obj.typ = Typ[Invalid]
+ }
+ return
+ }
+
+ if lhs == nil || len(lhs) == 1 {
+ assert(lhs == nil || lhs[0] == obj)
+ var x operand
+ check.expr(obj.typ, &x, init)
+ check.initVar(obj, &x, "variable declaration")
+ return
+ }
+
+ if debug {
+ // obj must be one of lhs
+ found := false
+ for _, lhs := range lhs {
+ if obj == lhs {
+ found = true
+ break
+ }
+ }
+ if !found {
+ panic("inconsistent lhs")
+ }
+ }
+
+ // We have multiple variables on the lhs and one init expr.
+ // Make sure all variables have been given the same type if
+ // one was specified, otherwise they assume the type of the
+ // init expression values (was go.dev/issue/15755).
+ if typ != nil {
+ for _, lhs := range lhs {
+ lhs.typ = obj.typ
+ }
+ }
+
+ check.initVars(lhs, []ast.Expr{init}, nil)
+}
+
+// isImportedConstraint reports whether typ is an imported type constraint.
+func (check *Checker) isImportedConstraint(typ Type) bool {
+ named, _ := typ.(*Named)
+ if named == nil || named.obj.pkg == check.pkg || named.obj.pkg == nil {
+ return false
+ }
+ u, _ := named.under().(*Interface)
+ return u != nil && !u.IsMethodSet()
+}
+
+func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
+ assert(obj.typ == nil)
+
+ var rhs Type
+ check.later(func() {
+ if t, _ := obj.typ.(*Named); t != nil { // type may be invalid
+ check.validType(t)
+ }
+ // If typ is local, an error was already reported where typ is specified/defined.
+ _ = check.isImportedConstraint(rhs) && check.verifyVersionf(tdecl.Type, go1_18, "using type constraint %s", rhs)
+ }).describef(obj, "validType(%s)", obj.Name())
+
+ alias := tdecl.Assign.IsValid()
+ if alias && tdecl.TypeParams.NumFields() != 0 {
+ // The parser will ensure this but we may still get an invalid AST.
+ // Complain and continue as regular type definition.
+ check.error(atPos(tdecl.Assign), BadDecl, "generic type cannot be alias")
+ alias = false
+ }
+
+ // alias declaration
+ if alias {
+ check.verifyVersionf(atPos(tdecl.Assign), go1_9, "type aliases")
+ check.brokenAlias(obj)
+ rhs = check.typ(tdecl.Type)
+ check.validAlias(obj, rhs)
+ return
+ }
+
+ // type definition or generic type declaration
+ named := check.newNamed(obj, nil, nil)
+ def.setUnderlying(named)
+
+ if tdecl.TypeParams != nil {
+ check.openScope(tdecl, "type parameters")
+ defer check.closeScope()
+ check.collectTypeParams(&named.tparams, tdecl.TypeParams)
+ }
+
+ // determine underlying type of named
+ rhs = check.definedType(tdecl.Type, named)
+ assert(rhs != nil)
+ named.fromRHS = rhs
+
+ // If the underlying type was not set while type-checking the right-hand
+ // side, it is invalid and an error should have been reported elsewhere.
+ if named.underlying == nil {
+ named.underlying = Typ[Invalid]
+ }
+
+ // Disallow a lone type parameter as the RHS of a type declaration (go.dev/issue/45639).
+ // We don't need this restriction anymore if we make the underlying type of a type
+ // parameter its constraint interface: if the RHS is a lone type parameter, we will
+ // use its underlying type (like we do for any RHS in a type declaration), and its
+ // underlying type is an interface and the type declaration is well defined.
+ if isTypeParam(rhs) {
+ check.error(tdecl.Type, MisplacedTypeParam, "cannot use a type parameter as RHS in type declaration")
+ named.underlying = Typ[Invalid]
+ }
+}
+
+func (check *Checker) collectTypeParams(dst **TypeParamList, list *ast.FieldList) {
+ var tparams []*TypeParam
+ // Declare type parameters up-front, with empty interface as type bound.
+ // The scope of type parameters starts at the beginning of the type parameter
+ // list (so we can have mutually recursive parameterized interfaces).
+ for _, f := range list.List {
+ tparams = check.declareTypeParams(tparams, f.Names)
+ }
+
+ // Set the type parameters before collecting the type constraints because
+ // the parameterized type may be used by the constraints (go.dev/issue/47887).
+ // Example: type T[P T[P]] interface{}
+ *dst = bindTParams(tparams)
+
+ // Signal to cycle detection that we are in a type parameter list.
+ // We can only be inside one type parameter list at any given time:
+ // function closures may appear inside a type parameter list but they
+ // cannot be generic, and their bodies are processed in delayed and
+ // sequential fashion. Note that with each new declaration, we save
+ // the existing environment and restore it when done; thus inTPList is
+ // true exactly only when we are in a specific type parameter list.
+ assert(!check.inTParamList)
+ check.inTParamList = true
+ defer func() {
+ check.inTParamList = false
+ }()
+
+ index := 0
+ for _, f := range list.List {
+ var bound Type
+ // NOTE: we may be able to assert that f.Type != nil here, but this is not
+ // an invariant of the AST, so we are cautious.
+ if f.Type != nil {
+ bound = check.bound(f.Type)
+ if isTypeParam(bound) {
+ // We may be able to allow this since it is now well-defined what
+ // the underlying type and thus type set of a type parameter is.
+ // But we may need some additional form of cycle detection within
+ // type parameter lists.
+ check.error(f.Type, MisplacedTypeParam, "cannot use a type parameter as constraint")
+ bound = Typ[Invalid]
+ }
+ } else {
+ bound = Typ[Invalid]
+ }
+ for i := range f.Names {
+ tparams[index+i].bound = bound
+ }
+ index += len(f.Names)
+ }
+}
+
+func (check *Checker) bound(x ast.Expr) Type {
+ // A type set literal of the form ~T and A|B may only appear as constraint;
+ // embed it in an implicit interface so that only interface type-checking
+ // needs to take care of such type expressions.
+ wrap := false
+ switch op := x.(type) {
+ case *ast.UnaryExpr:
+ wrap = op.Op == token.TILDE
+ case *ast.BinaryExpr:
+ wrap = op.Op == token.OR
+ }
+ if wrap {
+ x = &ast.InterfaceType{Methods: &ast.FieldList{List: []*ast.Field{{Type: x}}}}
+ t := check.typ(x)
+ // mark t as implicit interface if all went well
+ if t, _ := t.(*Interface); t != nil {
+ t.implicit = true
+ }
+ return t
+ }
+ return check.typ(x)
+}
+
+func (check *Checker) declareTypeParams(tparams []*TypeParam, names []*ast.Ident) []*TypeParam {
+ // Use Typ[Invalid] for the type constraint to ensure that a type
+ // is present even if the actual constraint has not been assigned
+ // yet.
+ // TODO(gri) Need to systematically review all uses of type parameter
+ // constraints to make sure we don't rely on them if they
+ // are not properly set yet.
+ for _, name := range names {
+ tname := NewTypeName(name.Pos(), check.pkg, name.Name, nil)
+ tpar := check.newTypeParam(tname, Typ[Invalid]) // assigns type to tpar as a side-effect
+ check.declare(check.scope, name, tname, check.scope.pos) // TODO(gri) check scope position
+ tparams = append(tparams, tpar)
+ }
+
+ if check.conf._Trace && len(names) > 0 {
+ check.trace(names[0].Pos(), "type params = %v", tparams[len(tparams)-len(names):])
+ }
+
+ return tparams
+}
+
+func (check *Checker) collectMethods(obj *TypeName) {
+ // get associated methods
+ // (Checker.collectObjects only collects methods with non-blank names;
+ // Checker.resolveBaseTypeName ensures that obj is not an alias name
+ // if it has attached methods.)
+ methods := check.methods[obj]
+ if methods == nil {
+ return
+ }
+ delete(check.methods, obj)
+ assert(!check.objMap[obj].tdecl.Assign.IsValid()) // don't use TypeName.IsAlias (requires fully set up object)
+
+ // use an objset to check for name conflicts
+ var mset objset
+
+ // spec: "If the base type is a struct type, the non-blank method
+ // and field names must be distinct."
+ base, _ := obj.typ.(*Named) // shouldn't fail but be conservative
+ if base != nil {
+ assert(base.TypeArgs().Len() == 0) // collectMethods should not be called on an instantiated type
+
+ // See go.dev/issue/52529: we must delay the expansion of underlying here, as
+ // base may not be fully set-up.
+ check.later(func() {
+ check.checkFieldUniqueness(base)
+ }).describef(obj, "verifying field uniqueness for %v", base)
+
+ // Checker.Files may be called multiple times; additional package files
+ // may add methods to already type-checked types. Add pre-existing methods
+ // so that we can detect redeclarations.
+ for i := 0; i < base.NumMethods(); i++ {
+ m := base.Method(i)
+ assert(m.name != "_")
+ assert(mset.insert(m) == nil)
+ }
+ }
+
+ // add valid methods
+ for _, m := range methods {
+ // spec: "For a base type, the non-blank names of methods bound
+ // to it must be unique."
+ assert(m.name != "_")
+ if alt := mset.insert(m); alt != nil {
+ if alt.Pos().IsValid() {
+ check.errorf(m, DuplicateMethod, "method %s.%s already declared at %s", obj.Name(), m.name, alt.Pos())
+ } else {
+ check.errorf(m, DuplicateMethod, "method %s.%s already declared", obj.Name(), m.name)
+ }
+ continue
+ }
+
+ if base != nil {
+ base.AddMethod(m)
+ }
+ }
+}
+
+func (check *Checker) checkFieldUniqueness(base *Named) {
+ if t, _ := base.under().(*Struct); t != nil {
+ var mset objset
+ for i := 0; i < base.NumMethods(); i++ {
+ m := base.Method(i)
+ assert(m.name != "_")
+ assert(mset.insert(m) == nil)
+ }
+
+ // Check that any non-blank field names of base are distinct from its
+ // method names.
+ for _, fld := range t.fields {
+ if fld.name != "_" {
+ if alt := mset.insert(fld); alt != nil {
+ // Struct fields should already be unique, so we should only
+ // encounter an alternate via collision with a method name.
+ _ = alt.(*Func)
+
+ // For historical consistency, we report the primary error on the
+ // method, and the alt decl on the field.
+ check.errorf(alt, DuplicateFieldAndMethod, "field and method with the same name %s", fld.name)
+ check.reportAltDecl(fld)
+ }
+ }
+ }
+ }
+}
+
+func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
+ assert(obj.typ == nil)
+
+ // func declarations cannot use iota
+ assert(check.iota == nil)
+
+ sig := new(Signature)
+ obj.typ = sig // guard against cycles
+
+ // Avoid cycle error when referring to method while type-checking the signature.
+ // This avoids a nuisance in the best case (non-parameterized receiver type) and
+ // since the method is not a type, we get an error. If we have a parameterized
+ // receiver type, instantiating the receiver type leads to the instantiation of
+ // its methods, and we don't want a cycle error in that case.
+ // TODO(gri) review if this is correct and/or whether we still need this?
+ saved := obj.color_
+ obj.color_ = black
+ fdecl := decl.fdecl
+ check.funcType(sig, fdecl.Recv, fdecl.Type)
+ obj.color_ = saved
+
+ if fdecl.Type.TypeParams.NumFields() > 0 && fdecl.Body == nil {
+ check.softErrorf(fdecl.Name, BadDecl, "generic function is missing function body")
+ }
+
+ // function body must be type-checked after global declarations
+ // (functions implemented elsewhere have no body)
+ if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
+ check.later(func() {
+ check.funcBody(decl, obj.name, sig, fdecl.Body, nil)
+ }).describef(obj, "func %s", obj.name)
+ }
+}
+
+func (check *Checker) declStmt(d ast.Decl) {
+ pkg := check.pkg
+
+ check.walkDecl(d, func(d decl) {
+ switch d := d.(type) {
+ case constDecl:
+ top := len(check.delayed)
+
+ // declare all constants
+ lhs := make([]*Const, len(d.spec.Names))
+ for i, name := range d.spec.Names {
+ obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(d.iota)))
+ lhs[i] = obj
+
+ var init ast.Expr
+ if i < len(d.init) {
+ init = d.init[i]
+ }
+
+ check.constDecl(obj, d.typ, init, d.inherited)
+ }
+
+ // process function literals in init expressions before scope changes
+ check.processDelayed(top)
+
+ // spec: "The scope of a constant or variable identifier declared
+ // inside a function begins at the end of the ConstSpec or VarSpec
+ // (ShortVarDecl for short variable declarations) and ends at the
+ // end of the innermost containing block."
+ scopePos := d.spec.End()
+ for i, name := range d.spec.Names {
+ check.declare(check.scope, name, lhs[i], scopePos)
+ }
+
+ case varDecl:
+ top := len(check.delayed)
+
+ lhs0 := make([]*Var, len(d.spec.Names))
+ for i, name := range d.spec.Names {
+ lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil)
+ }
+
+ // initialize all variables
+ for i, obj := range lhs0 {
+ var lhs []*Var
+ var init ast.Expr
+ switch len(d.spec.Values) {
+ case len(d.spec.Names):
+ // lhs and rhs match
+ init = d.spec.Values[i]
+ case 1:
+ // rhs is expected to be a multi-valued expression
+ lhs = lhs0
+ init = d.spec.Values[0]
+ default:
+ if i < len(d.spec.Values) {
+ init = d.spec.Values[i]
+ }
+ }
+ check.varDecl(obj, lhs, d.spec.Type, init)
+ if len(d.spec.Values) == 1 {
+ // If we have a single lhs variable we are done either way.
+ // If we have a single rhs expression, it must be a multi-
+ // valued expression, in which case handling the first lhs
+ // variable will cause all lhs variables to have a type
+ // assigned, and we are done as well.
+ if debug {
+ for _, obj := range lhs0 {
+ assert(obj.typ != nil)
+ }
+ }
+ break
+ }
+ }
+
+ // process function literals in init expressions before scope changes
+ check.processDelayed(top)
+
+ // declare all variables
+ // (only at this point are the variable scopes (parents) set)
+ scopePos := d.spec.End() // see constant declarations
+ for i, name := range d.spec.Names {
+ // see constant declarations
+ check.declare(check.scope, name, lhs0[i], scopePos)
+ }
+
+ case typeDecl:
+ obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil)
+ // spec: "The scope of a type identifier declared inside a function
+ // begins at the identifier in the TypeSpec and ends at the end of
+ // the innermost containing block."
+ scopePos := d.spec.Name.Pos()
+ check.declare(check.scope, d.spec.Name, obj, scopePos)
+ // mark and unmark type before calling typeDecl; its type is still nil (see Checker.objDecl)
+ obj.setColor(grey + color(check.push(obj)))
+ check.typeDecl(obj, d.spec, nil)
+ check.pop().setColor(black)
+ default:
+ check.errorf(d.node(), InvalidSyntaxTree, "unknown ast.Decl node %T", d.node())
+ }
+ })
+}
diff --git a/contrib/go/_std_1.21/src/go/types/errors.go b/contrib/go/_std_1.21/src/go/types/errors.go
new file mode 100644
index 0000000000..14d0383e37
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/errors.go
@@ -0,0 +1,400 @@
+// Copyright 2012 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.
+
+// This file implements various error reporters.
+
+package types
+
+import (
+ "bytes"
+ "fmt"
+ "go/ast"
+ "go/token"
+ . "internal/types/errors"
+ "runtime"
+ "strconv"
+ "strings"
+)
+
+func assert(p bool) {
+ if !p {
+ msg := "assertion failed"
+ // Include information about the assertion location. Due to panic recovery,
+ // this location is otherwise buried in the middle of the panicking stack.
+ if _, file, line, ok := runtime.Caller(1); ok {
+ msg = fmt.Sprintf("%s:%d: %s", file, line, msg)
+ }
+ panic(msg)
+ }
+}
+
+func unreachable() {
+ panic("unreachable")
+}
+
+// An error_ represents a type-checking error.
+// To report an error_, call Checker.report.
+type error_ struct {
+ desc []errorDesc
+ code Code
+ soft bool // TODO(gri) eventually determine this from an error code
+}
+
+// An errorDesc describes part of a type-checking error.
+type errorDesc struct {
+ posn positioner
+ format string
+ args []interface{}
+}
+
+func (err *error_) empty() bool {
+ return err.desc == nil
+}
+
+func (err *error_) pos() token.Pos {
+ if err.empty() {
+ return nopos
+ }
+ return err.desc[0].posn.Pos()
+}
+
+func (err *error_) msg(fset *token.FileSet, qf Qualifier) string {
+ if err.empty() {
+ return "no error"
+ }
+ var buf strings.Builder
+ for i := range err.desc {
+ p := &err.desc[i]
+ if i > 0 {
+ fmt.Fprint(&buf, "\n\t")
+ if p.posn.Pos().IsValid() {
+ fmt.Fprintf(&buf, "%s: ", fset.Position(p.posn.Pos()))
+ }
+ }
+ buf.WriteString(sprintf(fset, qf, false, p.format, p.args...))
+ }
+ return buf.String()
+}
+
+// String is for testing.
+func (err *error_) String() string {
+ if err.empty() {
+ return "no error"
+ }
+ return fmt.Sprintf("%d: %s", err.pos(), err.msg(nil, nil))
+}
+
+// errorf adds formatted error information to err.
+// It may be called multiple times to provide additional information.
+func (err *error_) errorf(at token.Pos, format string, args ...interface{}) {
+ err.desc = append(err.desc, errorDesc{atPos(at), format, args})
+}
+
+func (check *Checker) qualifier(pkg *Package) string {
+ // Qualify the package unless it's the package being type-checked.
+ if pkg != check.pkg {
+ if check.pkgPathMap == nil {
+ check.pkgPathMap = make(map[string]map[string]bool)
+ check.seenPkgMap = make(map[*Package]bool)
+ check.markImports(check.pkg)
+ }
+ // If the same package name was used by multiple packages, display the full path.
+ if len(check.pkgPathMap[pkg.name]) > 1 {
+ return strconv.Quote(pkg.path)
+ }
+ return pkg.name
+ }
+ return ""
+}
+
+// markImports recursively walks pkg and its imports, to record unique import
+// paths in pkgPathMap.
+func (check *Checker) markImports(pkg *Package) {
+ if check.seenPkgMap[pkg] {
+ return
+ }
+ check.seenPkgMap[pkg] = true
+
+ forName, ok := check.pkgPathMap[pkg.name]
+ if !ok {
+ forName = make(map[string]bool)
+ check.pkgPathMap[pkg.name] = forName
+ }
+ forName[pkg.path] = true
+
+ for _, imp := range pkg.imports {
+ check.markImports(imp)
+ }
+}
+
+// check may be nil.
+func (check *Checker) sprintf(format string, args ...any) string {
+ var fset *token.FileSet
+ var qf Qualifier
+ if check != nil {
+ fset = check.fset
+ qf = check.qualifier
+ }
+ return sprintf(fset, qf, false, format, args...)
+}
+
+func sprintf(fset *token.FileSet, qf Qualifier, tpSubscripts bool, format string, args ...any) string {
+ for i, arg := range args {
+ switch a := arg.(type) {
+ case nil:
+ arg = "<nil>"
+ case operand:
+ panic("got operand instead of *operand")
+ case *operand:
+ arg = operandString(a, qf)
+ case token.Pos:
+ if fset != nil {
+ arg = fset.Position(a).String()
+ }
+ case ast.Expr:
+ arg = ExprString(a)
+ case []ast.Expr:
+ var buf bytes.Buffer
+ buf.WriteByte('[')
+ writeExprList(&buf, a)
+ buf.WriteByte(']')
+ arg = buf.String()
+ case Object:
+ arg = ObjectString(a, qf)
+ case Type:
+ var buf bytes.Buffer
+ w := newTypeWriter(&buf, qf)
+ w.tpSubscripts = tpSubscripts
+ w.typ(a)
+ arg = buf.String()
+ case []Type:
+ var buf bytes.Buffer
+ w := newTypeWriter(&buf, qf)
+ w.tpSubscripts = tpSubscripts
+ buf.WriteByte('[')
+ for i, x := range a {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ w.typ(x)
+ }
+ buf.WriteByte(']')
+ arg = buf.String()
+ case []*TypeParam:
+ var buf bytes.Buffer
+ w := newTypeWriter(&buf, qf)
+ w.tpSubscripts = tpSubscripts
+ buf.WriteByte('[')
+ for i, x := range a {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ w.typ(x)
+ }
+ buf.WriteByte(']')
+ arg = buf.String()
+ }
+ args[i] = arg
+ }
+ return fmt.Sprintf(format, args...)
+}
+
+func (check *Checker) trace(pos token.Pos, format string, args ...any) {
+ fmt.Printf("%s:\t%s%s\n",
+ check.fset.Position(pos),
+ strings.Repeat(". ", check.indent),
+ sprintf(check.fset, check.qualifier, true, format, args...),
+ )
+}
+
+// dump is only needed for debugging
+func (check *Checker) dump(format string, args ...any) {
+ fmt.Println(sprintf(check.fset, check.qualifier, true, format, args...))
+}
+
+// Report records the error pointed to by errp, setting check.firstError if
+// necessary.
+func (check *Checker) report(errp *error_) {
+ if errp.empty() {
+ panic("empty error details")
+ }
+
+ msg := errp.msg(check.fset, check.qualifier)
+ switch errp.code {
+ case InvalidSyntaxTree:
+ msg = "invalid AST: " + msg
+ case 0:
+ panic("no error code provided")
+ }
+
+ // If we have an URL for error codes, add a link to the first line.
+ if errp.code != 0 && check.conf._ErrorURL != "" {
+ u := fmt.Sprintf(check.conf._ErrorURL, errp.code)
+ if i := strings.Index(msg, "\n"); i >= 0 {
+ msg = msg[:i] + u + msg[i:]
+ } else {
+ msg += u
+ }
+ }
+
+ span := spanOf(errp.desc[0].posn)
+ e := Error{
+ Fset: check.fset,
+ Pos: span.pos,
+ Msg: msg,
+ Soft: errp.soft,
+ go116code: errp.code,
+ go116start: span.start,
+ go116end: span.end,
+ }
+
+ // Cheap trick: Don't report errors with messages containing
+ // "invalid operand" or "invalid type" as those tend to be
+ // follow-on errors which don't add useful information. Only
+ // exclude them if these strings are not at the beginning,
+ // and only if we have at least one error already reported.
+ isInvalidErr := strings.Index(e.Msg, "invalid operand") > 0 || strings.Index(e.Msg, "invalid type") > 0
+ if check.firstErr != nil && isInvalidErr {
+ return
+ }
+
+ e.Msg = stripAnnotations(e.Msg)
+ if check.errpos != nil {
+ // If we have an internal error and the errpos override is set, use it to
+ // augment our error positioning.
+ // TODO(rFindley) we may also want to augment the error message and refer
+ // to the position (pos) in the original expression.
+ span := spanOf(check.errpos)
+ e.Pos = span.pos
+ e.go116start = span.start
+ e.go116end = span.end
+ }
+ err := e
+
+ if check.firstErr == nil {
+ check.firstErr = err
+ }
+
+ if check.conf._Trace {
+ pos := e.Pos
+ msg := e.Msg
+ check.trace(pos, "ERROR: %s", msg)
+ }
+
+ f := check.conf.Error
+ if f == nil {
+ panic(bailout{}) // report only first error
+ }
+ f(err)
+}
+
+const (
+ invalidArg = "invalid argument: "
+ invalidOp = "invalid operation: "
+)
+
+// newErrorf creates a new error_ for later reporting with check.report.
+func newErrorf(at positioner, code Code, format string, args ...any) *error_ {
+ return &error_{
+ desc: []errorDesc{{at, format, args}},
+ code: code,
+ }
+}
+
+func (check *Checker) error(at positioner, code Code, msg string) {
+ check.report(newErrorf(at, code, "%s", msg))
+}
+
+func (check *Checker) errorf(at positioner, code Code, format string, args ...any) {
+ check.report(newErrorf(at, code, format, args...))
+}
+
+func (check *Checker) softErrorf(at positioner, code Code, format string, args ...any) {
+ err := newErrorf(at, code, format, args...)
+ err.soft = true
+ check.report(err)
+}
+
+func (check *Checker) versionErrorf(at positioner, v version, format string, args ...interface{}) {
+ msg := check.sprintf(format, args...)
+ var err *error_
+ err = newErrorf(at, UnsupportedFeature, "%s requires %s or later", msg, v)
+ check.report(err)
+}
+
+// The positioner interface is used to extract the position of type-checker
+// errors.
+type positioner interface {
+ Pos() token.Pos
+}
+
+// posSpan holds a position range along with a highlighted position within that
+// range. This is used for positioning errors, with pos by convention being the
+// first position in the source where the error is known to exist, and start
+// and end defining the full span of syntax being considered when the error was
+// detected. Invariant: start <= pos < end || start == pos == end.
+type posSpan struct {
+ start, pos, end token.Pos
+}
+
+func (e posSpan) Pos() token.Pos {
+ return e.pos
+}
+
+// inNode creates a posSpan for the given node.
+// Invariant: node.Pos() <= pos < node.End() (node.End() is the position of the
+// first byte after node within the source).
+func inNode(node ast.Node, pos token.Pos) posSpan {
+ start, end := node.Pos(), node.End()
+ if debug {
+ assert(start <= pos && pos < end)
+ }
+ return posSpan{start, pos, end}
+}
+
+// atPos wraps a token.Pos to implement the positioner interface.
+type atPos token.Pos
+
+func (s atPos) Pos() token.Pos {
+ return token.Pos(s)
+}
+
+// spanOf extracts an error span from the given positioner. By default this is
+// the trivial span starting and ending at pos, but this span is expanded when
+// the argument naturally corresponds to a span of source code.
+func spanOf(at positioner) posSpan {
+ switch x := at.(type) {
+ case nil:
+ panic("nil positioner")
+ case posSpan:
+ return x
+ case ast.Node:
+ pos := x.Pos()
+ return posSpan{pos, pos, x.End()}
+ case *operand:
+ if x.expr != nil {
+ pos := x.Pos()
+ return posSpan{pos, pos, x.expr.End()}
+ }
+ return posSpan{nopos, nopos, nopos}
+ default:
+ pos := at.Pos()
+ return posSpan{pos, pos, pos}
+ }
+}
+
+// stripAnnotations removes internal (type) annotations from s.
+func stripAnnotations(s string) string {
+ var buf strings.Builder
+ for _, r := range s {
+ // strip #'s and subscript digits
+ if r < '₀' || '₀'+10 <= r { // '₀' == U+2080
+ buf.WriteRune(r)
+ }
+ }
+ if buf.Len() < len(s) {
+ return buf.String()
+ }
+ return s
+}
diff --git a/contrib/go/_std_1.21/src/go/types/eval.go b/contrib/go/_std_1.21/src/go/types/eval.go
new file mode 100644
index 0000000000..ff2af58b30
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/eval.go
@@ -0,0 +1,99 @@
+// Copyright 2013 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 types
+
+import (
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/token"
+)
+
+// Eval returns the type and, if constant, the value for the
+// expression expr, evaluated at position pos of package pkg,
+// which must have been derived from type-checking an AST with
+// complete position information relative to the provided file
+// set.
+//
+// The meaning of the parameters fset, pkg, and pos is the
+// same as in CheckExpr. An error is returned if expr cannot
+// be parsed successfully, or the resulting expr AST cannot be
+// type-checked.
+func Eval(fset *token.FileSet, pkg *Package, pos token.Pos, expr string) (_ TypeAndValue, err error) {
+ // parse expressions
+ node, err := parser.ParseExprFrom(fset, "eval", expr, 0)
+ if err != nil {
+ return TypeAndValue{}, err
+ }
+
+ info := &Info{
+ Types: make(map[ast.Expr]TypeAndValue),
+ }
+ err = CheckExpr(fset, pkg, pos, node, info)
+ return info.Types[node], err
+}
+
+// CheckExpr type checks the expression expr as if it had appeared at position
+// pos of package pkg. Type information about the expression is recorded in
+// info. The expression may be an identifier denoting an uninstantiated generic
+// function or type.
+//
+// If pkg == nil, the Universe scope is used and the provided
+// position pos is ignored. If pkg != nil, and pos is invalid,
+// the package scope is used. Otherwise, pos must belong to the
+// package.
+//
+// An error is returned if pos is not within the package or
+// if the node cannot be type-checked.
+//
+// Note: Eval and CheckExpr should not be used instead of running Check
+// to compute types and values, but in addition to Check, as these
+// functions ignore the context in which an expression is used (e.g., an
+// assignment). Thus, top-level untyped constants will return an
+// untyped type rather than the respective context-specific type.
+func CheckExpr(fset *token.FileSet, pkg *Package, pos token.Pos, expr ast.Expr, info *Info) (err error) {
+ // determine scope
+ var scope *Scope
+ if pkg == nil {
+ scope = Universe
+ pos = nopos
+ } else if !pos.IsValid() {
+ scope = pkg.scope
+ } else {
+ // The package scope extent (position information) may be
+ // incorrect (files spread across a wide range of fset
+ // positions) - ignore it and just consider its children
+ // (file scopes).
+ for _, fscope := range pkg.scope.children {
+ if scope = fscope.Innermost(pos); scope != nil {
+ break
+ }
+ }
+ if scope == nil || debug {
+ s := scope
+ for s != nil && s != pkg.scope {
+ s = s.parent
+ }
+ // s == nil || s == pkg.scope
+ if s == nil {
+ return fmt.Errorf("no position %s found in package %s", fset.Position(pos), pkg.name)
+ }
+ }
+ }
+
+ // initialize checker
+ check := NewChecker(nil, fset, pkg, info)
+ check.scope = scope
+ check.pos = pos
+ defer check.handleBailout(&err)
+
+ // evaluate node
+ var x operand
+ check.rawExpr(nil, &x, expr, nil, true) // allow generic expressions
+ check.processDelayed(0) // incl. all functions
+ check.recordUntyped()
+
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/go/types/expr.go b/contrib/go/_std_1.21/src/go/types/expr.go
new file mode 100644
index 0000000000..fd776c2350
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/expr.go
@@ -0,0 +1,1601 @@
+// Copyright 2012 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.
+
+// This file implements typechecking of expressions.
+
+package types
+
+import (
+ "fmt"
+ "go/ast"
+ "go/constant"
+ "go/internal/typeparams"
+ "go/token"
+ . "internal/types/errors"
+)
+
+/*
+Basic algorithm:
+
+Expressions are checked recursively, top down. Expression checker functions
+are generally of the form:
+
+ func f(x *operand, e *ast.Expr, ...)
+
+where e is the expression to be checked, and x is the result of the check.
+The check performed by f may fail in which case x.mode == invalid, and
+related error messages will have been issued by f.
+
+If a hint argument is present, it is the composite literal element type
+of an outer composite literal; it is used to type-check composite literal
+elements that have no explicit type specification in the source
+(e.g.: []T{{...}, {...}}, the hint is the type T in this case).
+
+All expressions are checked via rawExpr, which dispatches according
+to expression kind. Upon returning, rawExpr is recording the types and
+constant values for all expressions that have an untyped type (those types
+may change on the way up in the expression tree). Usually these are constants,
+but the results of comparisons or non-constant shifts of untyped constants
+may also be untyped, but not constant.
+
+Untyped expressions may eventually become fully typed (i.e., not untyped),
+typically when the value is assigned to a variable, or is used otherwise.
+The updateExprType method is used to record this final type and update
+the recorded types: the type-checked expression tree is again traversed down,
+and the new type is propagated as needed. Untyped constant expression values
+that become fully typed must now be representable by the full type (constant
+sub-expression trees are left alone except for their roots). This mechanism
+ensures that a client sees the actual (run-time) type an untyped value would
+have. It also permits type-checking of lhs shift operands "as if the shift
+were not present": when updateExprType visits an untyped lhs shift operand
+and assigns it it's final type, that type must be an integer type, and a
+constant lhs must be representable as an integer.
+
+When an expression gets its final type, either on the way out from rawExpr,
+on the way down in updateExprType, or at the end of the type checker run,
+the type (and constant value, if any) is recorded via Info.Types, if present.
+*/
+
+type opPredicates map[token.Token]func(Type) bool
+
+var unaryOpPredicates opPredicates
+
+func init() {
+ // Setting unaryOpPredicates in init avoids declaration cycles.
+ unaryOpPredicates = opPredicates{
+ token.ADD: allNumeric,
+ token.SUB: allNumeric,
+ token.XOR: allInteger,
+ token.NOT: allBoolean,
+ }
+}
+
+func (check *Checker) op(m opPredicates, x *operand, op token.Token) bool {
+ if pred := m[op]; pred != nil {
+ if !pred(x.typ) {
+ check.errorf(x, UndefinedOp, invalidOp+"operator %s not defined on %s", op, x)
+ return false
+ }
+ } else {
+ check.errorf(x, InvalidSyntaxTree, "unknown operator %s", op)
+ return false
+ }
+ return true
+}
+
+// opName returns the name of the operation if x is an operation
+// that might overflow; otherwise it returns the empty string.
+func opName(e ast.Expr) string {
+ switch e := e.(type) {
+ case *ast.BinaryExpr:
+ if int(e.Op) < len(op2str2) {
+ return op2str2[e.Op]
+ }
+ case *ast.UnaryExpr:
+ if int(e.Op) < len(op2str1) {
+ return op2str1[e.Op]
+ }
+ }
+ return ""
+}
+
+var op2str1 = [...]string{
+ token.XOR: "bitwise complement",
+}
+
+// This is only used for operations that may cause overflow.
+var op2str2 = [...]string{
+ token.ADD: "addition",
+ token.SUB: "subtraction",
+ token.XOR: "bitwise XOR",
+ token.MUL: "multiplication",
+ token.SHL: "shift",
+}
+
+// If typ is a type parameter, underIs returns the result of typ.underIs(f).
+// Otherwise, underIs returns the result of f(under(typ)).
+func underIs(typ Type, f func(Type) bool) bool {
+ if tpar, _ := typ.(*TypeParam); tpar != nil {
+ return tpar.underIs(f)
+ }
+ return f(under(typ))
+}
+
+// The unary expression e may be nil. It's passed in for better error messages only.
+func (check *Checker) unary(x *operand, e *ast.UnaryExpr) {
+ check.expr(nil, x, e.X)
+ if x.mode == invalid {
+ return
+ }
+
+ op := e.Op
+ switch op {
+ case token.AND:
+ // spec: "As an exception to the addressability
+ // requirement x may also be a composite literal."
+ if _, ok := unparen(e.X).(*ast.CompositeLit); !ok && x.mode != variable {
+ check.errorf(x, UnaddressableOperand, invalidOp+"cannot take address of %s", x)
+ x.mode = invalid
+ return
+ }
+ x.mode = value
+ x.typ = &Pointer{base: x.typ}
+ return
+
+ case token.ARROW:
+ u := coreType(x.typ)
+ if u == nil {
+ check.errorf(x, InvalidReceive, invalidOp+"cannot receive from %s (no core type)", x)
+ x.mode = invalid
+ return
+ }
+ ch, _ := u.(*Chan)
+ if ch == nil {
+ check.errorf(x, InvalidReceive, invalidOp+"cannot receive from non-channel %s", x)
+ x.mode = invalid
+ return
+ }
+ if ch.dir == SendOnly {
+ check.errorf(x, InvalidReceive, invalidOp+"cannot receive from send-only channel %s", x)
+ x.mode = invalid
+ return
+ }
+
+ x.mode = commaok
+ x.typ = ch.elem
+ check.hasCallOrRecv = true
+ return
+
+ case token.TILDE:
+ // Provide a better error position and message than what check.op below would do.
+ if !allInteger(x.typ) {
+ check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint")
+ x.mode = invalid
+ return
+ }
+ check.error(e, UndefinedOp, "cannot use ~ outside of interface or type constraint (use ^ for bitwise complement)")
+ op = token.XOR
+ }
+
+ if !check.op(unaryOpPredicates, x, op) {
+ x.mode = invalid
+ return
+ }
+
+ if x.mode == constant_ {
+ if x.val.Kind() == constant.Unknown {
+ // nothing to do (and don't cause an error below in the overflow check)
+ return
+ }
+ var prec uint
+ if isUnsigned(x.typ) {
+ prec = uint(check.conf.sizeof(x.typ) * 8)
+ }
+ x.val = constant.UnaryOp(op, x.val, prec)
+ x.expr = e
+ check.overflow(x, x.Pos())
+ return
+ }
+
+ x.mode = value
+ // x.typ remains unchanged
+}
+
+func isShift(op token.Token) bool {
+ return op == token.SHL || op == token.SHR
+}
+
+func isComparison(op token.Token) bool {
+ // Note: tokens are not ordered well to make this much easier
+ switch op {
+ case token.EQL, token.NEQ, token.LSS, token.LEQ, token.GTR, token.GEQ:
+ return true
+ }
+ return false
+}
+
+// updateExprType updates the type of x to typ and invokes itself
+// recursively for the operands of x, depending on expression kind.
+// If typ is still an untyped and not the final type, updateExprType
+// only updates the recorded untyped type for x and possibly its
+// operands. Otherwise (i.e., typ is not an untyped type anymore,
+// or it is the final type for x), the type and value are recorded.
+// Also, if x is a constant, it must be representable as a value of typ,
+// and if x is the (formerly untyped) lhs operand of a non-constant
+// shift, it must be an integer value.
+func (check *Checker) updateExprType(x ast.Expr, typ Type, final bool) {
+ check.updateExprType0(nil, x, typ, final)
+}
+
+func (check *Checker) updateExprType0(parent, x ast.Expr, typ Type, final bool) {
+ old, found := check.untyped[x]
+ if !found {
+ return // nothing to do
+ }
+
+ // update operands of x if necessary
+ switch x := x.(type) {
+ case *ast.BadExpr,
+ *ast.FuncLit,
+ *ast.CompositeLit,
+ *ast.IndexExpr,
+ *ast.SliceExpr,
+ *ast.TypeAssertExpr,
+ *ast.StarExpr,
+ *ast.KeyValueExpr,
+ *ast.ArrayType,
+ *ast.StructType,
+ *ast.FuncType,
+ *ast.InterfaceType,
+ *ast.MapType,
+ *ast.ChanType:
+ // These expression are never untyped - nothing to do.
+ // The respective sub-expressions got their final types
+ // upon assignment or use.
+ if debug {
+ check.dump("%v: found old type(%s): %s (new: %s)", x.Pos(), x, old.typ, typ)
+ unreachable()
+ }
+ return
+
+ case *ast.CallExpr:
+ // Resulting in an untyped constant (e.g., built-in complex).
+ // The respective calls take care of calling updateExprType
+ // for the arguments if necessary.
+
+ case *ast.Ident, *ast.BasicLit, *ast.SelectorExpr:
+ // An identifier denoting a constant, a constant literal,
+ // or a qualified identifier (imported untyped constant).
+ // No operands to take care of.
+
+ case *ast.ParenExpr:
+ check.updateExprType0(x, x.X, typ, final)
+
+ case *ast.UnaryExpr:
+ // If x is a constant, the operands were constants.
+ // The operands don't need to be updated since they
+ // never get "materialized" into a typed value. If
+ // left in the untyped map, they will be processed
+ // at the end of the type check.
+ if old.val != nil {
+ break
+ }
+ check.updateExprType0(x, x.X, typ, final)
+
+ case *ast.BinaryExpr:
+ if old.val != nil {
+ break // see comment for unary expressions
+ }
+ if isComparison(x.Op) {
+ // The result type is independent of operand types
+ // and the operand types must have final types.
+ } else if isShift(x.Op) {
+ // The result type depends only on lhs operand.
+ // The rhs type was updated when checking the shift.
+ check.updateExprType0(x, x.X, typ, final)
+ } else {
+ // The operand types match the result type.
+ check.updateExprType0(x, x.X, typ, final)
+ check.updateExprType0(x, x.Y, typ, final)
+ }
+
+ default:
+ unreachable()
+ }
+
+ // If the new type is not final and still untyped, just
+ // update the recorded type.
+ if !final && isUntyped(typ) {
+ old.typ = under(typ).(*Basic)
+ check.untyped[x] = old
+ return
+ }
+
+ // Otherwise we have the final (typed or untyped type).
+ // Remove it from the map of yet untyped expressions.
+ delete(check.untyped, x)
+
+ if old.isLhs {
+ // If x is the lhs of a shift, its final type must be integer.
+ // We already know from the shift check that it is representable
+ // as an integer if it is a constant.
+ if !allInteger(typ) {
+ check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s (type %s) must be integer", x, typ)
+ return
+ }
+ // Even if we have an integer, if the value is a constant we
+ // still must check that it is representable as the specific
+ // int type requested (was go.dev/issue/22969). Fall through here.
+ }
+ if old.val != nil {
+ // If x is a constant, it must be representable as a value of typ.
+ c := operand{old.mode, x, old.typ, old.val, 0}
+ check.convertUntyped(&c, typ)
+ if c.mode == invalid {
+ return
+ }
+ }
+
+ // Everything's fine, record final type and value for x.
+ check.recordTypeAndValue(x, old.mode, typ, old.val)
+}
+
+// updateExprVal updates the value of x to val.
+func (check *Checker) updateExprVal(x ast.Expr, val constant.Value) {
+ if info, ok := check.untyped[x]; ok {
+ info.val = val
+ check.untyped[x] = info
+ }
+}
+
+// implicitTypeAndValue returns the implicit type of x when used in a context
+// where the target type is expected. If no such implicit conversion is
+// possible, it returns a nil Type and non-zero error code.
+//
+// If x is a constant operand, the returned constant.Value will be the
+// representation of x in this context.
+func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, Code) {
+ if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
+ return x.typ, nil, 0
+ }
+ // x is untyped
+
+ if isUntyped(target) {
+ // both x and target are untyped
+ if m := maxType(x.typ, target); m != nil {
+ return m, nil, 0
+ }
+ return nil, nil, InvalidUntypedConversion
+ }
+
+ switch u := under(target).(type) {
+ case *Basic:
+ if x.mode == constant_ {
+ v, code := check.representation(x, u)
+ if code != 0 {
+ return nil, nil, code
+ }
+ return target, v, code
+ }
+ // Non-constant untyped values may appear as the
+ // result of comparisons (untyped bool), intermediate
+ // (delayed-checked) rhs operands of shifts, and as
+ // the value nil.
+ switch x.typ.(*Basic).kind {
+ case UntypedBool:
+ if !isBoolean(target) {
+ return nil, nil, InvalidUntypedConversion
+ }
+ case UntypedInt, UntypedRune, UntypedFloat, UntypedComplex:
+ if !isNumeric(target) {
+ return nil, nil, InvalidUntypedConversion
+ }
+ case UntypedString:
+ // Non-constant untyped string values are not permitted by the spec and
+ // should not occur during normal typechecking passes, but this path is
+ // reachable via the AssignableTo API.
+ if !isString(target) {
+ return nil, nil, InvalidUntypedConversion
+ }
+ case UntypedNil:
+ // Unsafe.Pointer is a basic type that includes nil.
+ if !hasNil(target) {
+ return nil, nil, InvalidUntypedConversion
+ }
+ // Preserve the type of nil as UntypedNil: see go.dev/issue/13061.
+ return Typ[UntypedNil], nil, 0
+ default:
+ return nil, nil, InvalidUntypedConversion
+ }
+ case *Interface:
+ if isTypeParam(target) {
+ if !u.typeSet().underIs(func(u Type) bool {
+ if u == nil {
+ return false
+ }
+ t, _, _ := check.implicitTypeAndValue(x, u)
+ return t != nil
+ }) {
+ return nil, nil, InvalidUntypedConversion
+ }
+ // keep nil untyped (was bug go.dev/issue/39755)
+ if x.isNil() {
+ return Typ[UntypedNil], nil, 0
+ }
+ break
+ }
+ // Values must have concrete dynamic types. If the value is nil,
+ // keep it untyped (this is important for tools such as go vet which
+ // need the dynamic type for argument checking of say, print
+ // functions)
+ if x.isNil() {
+ return Typ[UntypedNil], nil, 0
+ }
+ // cannot assign untyped values to non-empty interfaces
+ if !u.Empty() {
+ return nil, nil, InvalidUntypedConversion
+ }
+ return Default(x.typ), nil, 0
+ case *Pointer, *Signature, *Slice, *Map, *Chan:
+ if !x.isNil() {
+ return nil, nil, InvalidUntypedConversion
+ }
+ // Keep nil untyped - see comment for interfaces, above.
+ return Typ[UntypedNil], nil, 0
+ default:
+ return nil, nil, InvalidUntypedConversion
+ }
+ return target, nil, 0
+}
+
+// If switchCase is true, the operator op is ignored.
+func (check *Checker) comparison(x, y *operand, op token.Token, switchCase bool) {
+ // Avoid spurious errors if any of the operands has an invalid type (go.dev/issue/54405).
+ if x.typ == Typ[Invalid] || y.typ == Typ[Invalid] {
+ x.mode = invalid
+ return
+ }
+
+ if switchCase {
+ op = token.EQL
+ }
+
+ errOp := x // operand for which error is reported, if any
+ cause := "" // specific error cause, if any
+
+ // spec: "In any comparison, the first operand must be assignable
+ // to the type of the second operand, or vice versa."
+ code := MismatchedTypes
+ ok, _ := x.assignableTo(check, y.typ, nil)
+ if !ok {
+ ok, _ = y.assignableTo(check, x.typ, nil)
+ }
+ if !ok {
+ // Report the error on the 2nd operand since we only
+ // know after seeing the 2nd operand whether we have
+ // a type mismatch.
+ errOp = y
+ cause = check.sprintf("mismatched types %s and %s", x.typ, y.typ)
+ goto Error
+ }
+
+ // check if comparison is defined for operands
+ code = UndefinedOp
+ switch op {
+ case token.EQL, token.NEQ:
+ // spec: "The equality operators == and != apply to operands that are comparable."
+ switch {
+ case x.isNil() || y.isNil():
+ // Comparison against nil requires that the other operand type has nil.
+ typ := x.typ
+ if x.isNil() {
+ typ = y.typ
+ }
+ if !hasNil(typ) {
+ // This case should only be possible for "nil == nil".
+ // Report the error on the 2nd operand since we only
+ // know after seeing the 2nd operand whether we have
+ // an invalid comparison.
+ errOp = y
+ goto Error
+ }
+
+ case !Comparable(x.typ):
+ errOp = x
+ cause = check.incomparableCause(x.typ)
+ goto Error
+
+ case !Comparable(y.typ):
+ errOp = y
+ cause = check.incomparableCause(y.typ)
+ goto Error
+ }
+
+ case token.LSS, token.LEQ, token.GTR, token.GEQ:
+ // spec: The ordering operators <, <=, >, and >= apply to operands that are ordered."
+ switch {
+ case !allOrdered(x.typ):
+ errOp = x
+ goto Error
+ case !allOrdered(y.typ):
+ errOp = y
+ goto Error
+ }
+
+ default:
+ unreachable()
+ }
+
+ // comparison is ok
+ if x.mode == constant_ && y.mode == constant_ {
+ x.val = constant.MakeBool(constant.Compare(x.val, op, y.val))
+ // The operands are never materialized; no need to update
+ // their types.
+ } else {
+ x.mode = value
+ // The operands have now their final types, which at run-
+ // time will be materialized. Update the expression trees.
+ // If the current types are untyped, the materialized type
+ // is the respective default type.
+ check.updateExprType(x.expr, Default(x.typ), true)
+ check.updateExprType(y.expr, Default(y.typ), true)
+ }
+
+ // spec: "Comparison operators compare two operands and yield
+ // an untyped boolean value."
+ x.typ = Typ[UntypedBool]
+ return
+
+Error:
+ // We have an offending operand errOp and possibly an error cause.
+ if cause == "" {
+ if isTypeParam(x.typ) || isTypeParam(y.typ) {
+ // TODO(gri) should report the specific type causing the problem, if any
+ if !isTypeParam(x.typ) {
+ errOp = y
+ }
+ cause = check.sprintf("type parameter %s is not comparable with %s", errOp.typ, op)
+ } else {
+ cause = check.sprintf("operator %s not defined on %s", op, check.kindString(errOp.typ)) // catch-all
+ }
+ }
+ if switchCase {
+ check.errorf(x, code, "invalid case %s in switch on %s (%s)", x.expr, y.expr, cause) // error position always at 1st operand
+ } else {
+ check.errorf(errOp, code, invalidOp+"%s %s %s (%s)", x.expr, op, y.expr, cause)
+ }
+ x.mode = invalid
+}
+
+// incomparableCause returns a more specific cause why typ is not comparable.
+// If there is no more specific cause, the result is "".
+func (check *Checker) incomparableCause(typ Type) string {
+ switch under(typ).(type) {
+ case *Slice, *Signature, *Map:
+ return check.kindString(typ) + " can only be compared to nil"
+ }
+ // see if we can extract a more specific error
+ var cause string
+ comparable(typ, true, nil, func(format string, args ...interface{}) {
+ cause = check.sprintf(format, args...)
+ })
+ return cause
+}
+
+// kindString returns the type kind as a string.
+func (check *Checker) kindString(typ Type) string {
+ switch under(typ).(type) {
+ case *Array:
+ return "array"
+ case *Slice:
+ return "slice"
+ case *Struct:
+ return "struct"
+ case *Pointer:
+ return "pointer"
+ case *Signature:
+ return "func"
+ case *Interface:
+ if isTypeParam(typ) {
+ return check.sprintf("type parameter %s", typ)
+ }
+ return "interface"
+ case *Map:
+ return "map"
+ case *Chan:
+ return "chan"
+ default:
+ return check.sprintf("%s", typ) // catch-all
+ }
+}
+
+// If e != nil, it must be the shift expression; it may be nil for non-constant shifts.
+func (check *Checker) shift(x, y *operand, e ast.Expr, op token.Token) {
+ // TODO(gri) This function seems overly complex. Revisit.
+
+ var xval constant.Value
+ if x.mode == constant_ {
+ xval = constant.ToInt(x.val)
+ }
+
+ if allInteger(x.typ) || isUntyped(x.typ) && xval != nil && xval.Kind() == constant.Int {
+ // The lhs is of integer type or an untyped constant representable
+ // as an integer. Nothing to do.
+ } else {
+ // shift has no chance
+ check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
+ x.mode = invalid
+ return
+ }
+
+ // spec: "The right operand in a shift expression must have integer type
+ // or be an untyped constant representable by a value of type uint."
+
+ // Check that constants are representable by uint, but do not convert them
+ // (see also go.dev/issue/47243).
+ var yval constant.Value
+ if y.mode == constant_ {
+ // Provide a good error message for negative shift counts.
+ yval = constant.ToInt(y.val) // consider -1, 1.0, but not -1.1
+ if yval.Kind() == constant.Int && constant.Sign(yval) < 0 {
+ check.errorf(y, InvalidShiftCount, invalidOp+"negative shift count %s", y)
+ x.mode = invalid
+ return
+ }
+
+ if isUntyped(y.typ) {
+ // Caution: Check for representability here, rather than in the switch
+ // below, because isInteger includes untyped integers (was bug go.dev/issue/43697).
+ check.representable(y, Typ[Uint])
+ if y.mode == invalid {
+ x.mode = invalid
+ return
+ }
+ }
+ } else {
+ // Check that RHS is otherwise at least of integer type.
+ switch {
+ case allInteger(y.typ):
+ if !allUnsigned(y.typ) && !check.verifyVersionf(y, go1_13, invalidOp+"signed shift count %s", y) {
+ x.mode = invalid
+ return
+ }
+ case isUntyped(y.typ):
+ // This is incorrect, but preserves pre-existing behavior.
+ // See also go.dev/issue/47410.
+ check.convertUntyped(y, Typ[Uint])
+ if y.mode == invalid {
+ x.mode = invalid
+ return
+ }
+ default:
+ check.errorf(y, InvalidShiftCount, invalidOp+"shift count %s must be integer", y)
+ x.mode = invalid
+ return
+ }
+ }
+
+ if x.mode == constant_ {
+ if y.mode == constant_ {
+ // if either x or y has an unknown value, the result is unknown
+ if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
+ x.val = constant.MakeUnknown()
+ // ensure the correct type - see comment below
+ if !isInteger(x.typ) {
+ x.typ = Typ[UntypedInt]
+ }
+ return
+ }
+ // rhs must be within reasonable bounds in constant shifts
+ const shiftBound = 1023 - 1 + 52 // so we can express smallestFloat64 (see go.dev/issue/44057)
+ s, ok := constant.Uint64Val(yval)
+ if !ok || s > shiftBound {
+ check.errorf(y, InvalidShiftCount, invalidOp+"invalid shift count %s", y)
+ x.mode = invalid
+ return
+ }
+ // The lhs is representable as an integer but may not be an integer
+ // (e.g., 2.0, an untyped float) - this can only happen for untyped
+ // non-integer numeric constants. Correct the type so that the shift
+ // result is of integer type.
+ if !isInteger(x.typ) {
+ x.typ = Typ[UntypedInt]
+ }
+ // x is a constant so xval != nil and it must be of Int kind.
+ x.val = constant.Shift(xval, op, uint(s))
+ x.expr = e
+ opPos := x.Pos()
+ if b, _ := e.(*ast.BinaryExpr); b != nil {
+ opPos = b.OpPos
+ }
+ check.overflow(x, opPos)
+ return
+ }
+
+ // non-constant shift with constant lhs
+ if isUntyped(x.typ) {
+ // spec: "If the left operand of a non-constant shift
+ // expression is an untyped constant, the type of the
+ // constant is what it would be if the shift expression
+ // were replaced by its left operand alone.".
+ //
+ // Delay operand checking until we know the final type
+ // by marking the lhs expression as lhs shift operand.
+ //
+ // Usually (in correct programs), the lhs expression
+ // is in the untyped map. However, it is possible to
+ // create incorrect programs where the same expression
+ // is evaluated twice (via a declaration cycle) such
+ // that the lhs expression type is determined in the
+ // first round and thus deleted from the map, and then
+ // not found in the second round (double insertion of
+ // the same expr node still just leads to one entry for
+ // that node, and it can only be deleted once).
+ // Be cautious and check for presence of entry.
+ // Example: var e, f = int(1<<""[f]) // go.dev/issue/11347
+ if info, found := check.untyped[x.expr]; found {
+ info.isLhs = true
+ check.untyped[x.expr] = info
+ }
+ // keep x's type
+ x.mode = value
+ return
+ }
+ }
+
+ // non-constant shift - lhs must be an integer
+ if !allInteger(x.typ) {
+ check.errorf(x, InvalidShiftOperand, invalidOp+"shifted operand %s must be integer", x)
+ x.mode = invalid
+ return
+ }
+
+ x.mode = value
+}
+
+var binaryOpPredicates opPredicates
+
+func init() {
+ // Setting binaryOpPredicates in init avoids declaration cycles.
+ binaryOpPredicates = opPredicates{
+ token.ADD: allNumericOrString,
+ token.SUB: allNumeric,
+ token.MUL: allNumeric,
+ token.QUO: allNumeric,
+ token.REM: allInteger,
+
+ token.AND: allInteger,
+ token.OR: allInteger,
+ token.XOR: allInteger,
+ token.AND_NOT: allInteger,
+
+ token.LAND: allBoolean,
+ token.LOR: allBoolean,
+ }
+}
+
+// If e != nil, it must be the binary expression; it may be nil for non-constant expressions
+// (when invoked for an assignment operation where the binary expression is implicit).
+func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token.Token, opPos token.Pos) {
+ var y operand
+
+ check.expr(nil, x, lhs)
+ check.expr(nil, &y, rhs)
+
+ if x.mode == invalid {
+ return
+ }
+ if y.mode == invalid {
+ x.mode = invalid
+ x.expr = y.expr
+ return
+ }
+
+ if isShift(op) {
+ check.shift(x, &y, e, op)
+ return
+ }
+
+ check.matchTypes(x, &y)
+ if x.mode == invalid {
+ return
+ }
+
+ if isComparison(op) {
+ check.comparison(x, &y, op, false)
+ return
+ }
+
+ if !Identical(x.typ, y.typ) {
+ // only report an error if we have valid types
+ // (otherwise we had an error reported elsewhere already)
+ if x.typ != Typ[Invalid] && y.typ != Typ[Invalid] {
+ var posn positioner = x
+ if e != nil {
+ posn = e
+ }
+ if e != nil {
+ check.errorf(posn, MismatchedTypes, invalidOp+"%s (mismatched types %s and %s)", e, x.typ, y.typ)
+ } else {
+ check.errorf(posn, MismatchedTypes, invalidOp+"%s %s= %s (mismatched types %s and %s)", lhs, op, rhs, x.typ, y.typ)
+ }
+ }
+ x.mode = invalid
+ return
+ }
+
+ if !check.op(binaryOpPredicates, x, op) {
+ x.mode = invalid
+ return
+ }
+
+ if op == token.QUO || op == token.REM {
+ // check for zero divisor
+ if (x.mode == constant_ || allInteger(x.typ)) && y.mode == constant_ && constant.Sign(y.val) == 0 {
+ check.error(&y, DivByZero, invalidOp+"division by zero")
+ x.mode = invalid
+ return
+ }
+
+ // check for divisor underflow in complex division (see go.dev/issue/20227)
+ if x.mode == constant_ && y.mode == constant_ && isComplex(x.typ) {
+ re, im := constant.Real(y.val), constant.Imag(y.val)
+ re2, im2 := constant.BinaryOp(re, token.MUL, re), constant.BinaryOp(im, token.MUL, im)
+ if constant.Sign(re2) == 0 && constant.Sign(im2) == 0 {
+ check.error(&y, DivByZero, invalidOp+"division by zero")
+ x.mode = invalid
+ return
+ }
+ }
+ }
+
+ if x.mode == constant_ && y.mode == constant_ {
+ // if either x or y has an unknown value, the result is unknown
+ if x.val.Kind() == constant.Unknown || y.val.Kind() == constant.Unknown {
+ x.val = constant.MakeUnknown()
+ // x.typ is unchanged
+ return
+ }
+ // force integer division of integer operands
+ if op == token.QUO && isInteger(x.typ) {
+ op = token.QUO_ASSIGN
+ }
+ x.val = constant.BinaryOp(x.val, op, y.val)
+ x.expr = e
+ check.overflow(x, opPos)
+ return
+ }
+
+ x.mode = value
+ // x.typ is unchanged
+}
+
+// matchTypes attempts to convert any untyped types x and y such that they match.
+// If an error occurs, x.mode is set to invalid.
+func (check *Checker) matchTypes(x, y *operand) {
+ // mayConvert reports whether the operands x and y may
+ // possibly have matching types after converting one
+ // untyped operand to the type of the other.
+ // If mayConvert returns true, we try to convert the
+ // operands to each other's types, and if that fails
+ // we report a conversion failure.
+ // If mayConvert returns false, we continue without an
+ // attempt at conversion, and if the operand types are
+ // not compatible, we report a type mismatch error.
+ mayConvert := func(x, y *operand) bool {
+ // If both operands are typed, there's no need for an implicit conversion.
+ if isTyped(x.typ) && isTyped(y.typ) {
+ return false
+ }
+ // An untyped operand may convert to its default type when paired with an empty interface
+ // TODO(gri) This should only matter for comparisons (the only binary operation that is
+ // valid with interfaces), but in that case the assignability check should take
+ // care of the conversion. Verify and possibly eliminate this extra test.
+ if isNonTypeParamInterface(x.typ) || isNonTypeParamInterface(y.typ) {
+ return true
+ }
+ // A boolean type can only convert to another boolean type.
+ if allBoolean(x.typ) != allBoolean(y.typ) {
+ return false
+ }
+ // A string type can only convert to another string type.
+ if allString(x.typ) != allString(y.typ) {
+ return false
+ }
+ // Untyped nil can only convert to a type that has a nil.
+ if x.isNil() {
+ return hasNil(y.typ)
+ }
+ if y.isNil() {
+ return hasNil(x.typ)
+ }
+ // An untyped operand cannot convert to a pointer.
+ // TODO(gri) generalize to type parameters
+ if isPointer(x.typ) || isPointer(y.typ) {
+ return false
+ }
+ return true
+ }
+
+ if mayConvert(x, y) {
+ check.convertUntyped(x, y.typ)
+ if x.mode == invalid {
+ return
+ }
+ check.convertUntyped(y, x.typ)
+ if y.mode == invalid {
+ x.mode = invalid
+ return
+ }
+ }
+}
+
+// exprKind describes the kind of an expression; the kind
+// determines if an expression is valid in 'statement context'.
+type exprKind int
+
+const (
+ conversion exprKind = iota
+ expression
+ statement
+)
+
+// TODO(gri) In rawExpr below, consider using T instead of hint and
+// some sort of "operation mode" instead of allowGeneric.
+// May be clearer and less error-prone.
+
+// rawExpr typechecks expression e and initializes x with the expression
+// value or type. If an error occurred, x.mode is set to invalid.
+// If a non-nil target type T is given and e is a generic function
+// or function call, T is used to infer the type arguments for e.
+// If hint != nil, it is the type of a composite literal element.
+// If allowGeneric is set, the operand type may be an uninstantiated
+// parameterized type or function value.
+func (check *Checker) rawExpr(T Type, x *operand, e ast.Expr, hint Type, allowGeneric bool) exprKind {
+ if check.conf._Trace {
+ check.trace(e.Pos(), "-- expr %s", e)
+ check.indent++
+ defer func() {
+ check.indent--
+ check.trace(e.Pos(), "=> %s", x)
+ }()
+ }
+
+ kind := check.exprInternal(T, x, e, hint)
+
+ if !allowGeneric {
+ check.nonGeneric(T, x)
+ }
+
+ check.record(x)
+
+ return kind
+}
+
+// If x is a generic type, or a generic function whose type arguments cannot be inferred
+// from a non-nil target type T, nonGeneric reports an error and invalidates x.mode and x.typ.
+// Otherwise it leaves x alone.
+func (check *Checker) nonGeneric(T Type, x *operand) {
+ if x.mode == invalid || x.mode == novalue {
+ return
+ }
+ var what string
+ switch t := x.typ.(type) {
+ case *Named:
+ if isGeneric(t) {
+ what = "type"
+ }
+ case *Signature:
+ if t.tparams != nil {
+ if enableReverseTypeInference && T != nil {
+ if tsig, _ := under(T).(*Signature); tsig != nil {
+ check.funcInst(tsig, x.Pos(), x, nil, true)
+ return
+ }
+ }
+ what = "function"
+ }
+ }
+ if what != "" {
+ check.errorf(x.expr, WrongTypeArgCount, "cannot use generic %s %s without instantiation", what, x.expr)
+ x.mode = invalid
+ x.typ = Typ[Invalid]
+ }
+}
+
+// exprInternal contains the core of type checking of expressions.
+// Must only be called by rawExpr.
+// (See rawExpr for an explanation of the parameters.)
+func (check *Checker) exprInternal(T Type, x *operand, e ast.Expr, hint Type) exprKind {
+ // make sure x has a valid state in case of bailout
+ // (was go.dev/issue/5770)
+ x.mode = invalid
+ x.typ = Typ[Invalid]
+
+ switch e := e.(type) {
+ case *ast.BadExpr:
+ goto Error // error was reported before
+
+ case *ast.Ident:
+ check.ident(x, e, nil, false)
+
+ case *ast.Ellipsis:
+ // ellipses are handled explicitly where they are legal
+ // (array composite literals and parameter lists)
+ check.error(e, BadDotDotDotSyntax, "invalid use of '...'")
+ goto Error
+
+ case *ast.BasicLit:
+ switch e.Kind {
+ case token.INT, token.FLOAT, token.IMAG:
+ check.langCompat(e)
+ // The max. mantissa precision for untyped numeric values
+ // is 512 bits, or 4048 bits for each of the two integer
+ // parts of a fraction for floating-point numbers that are
+ // represented accurately in the go/constant package.
+ // Constant literals that are longer than this many bits
+ // are not meaningful; and excessively long constants may
+ // consume a lot of space and time for a useless conversion.
+ // Cap constant length with a generous upper limit that also
+ // allows for separators between all digits.
+ const limit = 10000
+ if len(e.Value) > limit {
+ check.errorf(e, InvalidConstVal, "excessively long constant: %s... (%d chars)", e.Value[:10], len(e.Value))
+ goto Error
+ }
+ }
+ x.setConst(e.Kind, e.Value)
+ if x.mode == invalid {
+ // The parser already establishes syntactic correctness.
+ // If we reach here it's because of number under-/overflow.
+ // TODO(gri) setConst (and in turn the go/constant package)
+ // should return an error describing the issue.
+ check.errorf(e, InvalidConstVal, "malformed constant: %s", e.Value)
+ goto Error
+ }
+ // Ensure that integer values don't overflow (go.dev/issue/54280).
+ check.overflow(x, e.Pos())
+
+ case *ast.FuncLit:
+ if sig, ok := check.typ(e.Type).(*Signature); ok {
+ if !check.conf.IgnoreFuncBodies && e.Body != nil {
+ // Anonymous functions are considered part of the
+ // init expression/func declaration which contains
+ // them: use existing package-level declaration info.
+ decl := check.decl // capture for use in closure below
+ iota := check.iota // capture for use in closure below (go.dev/issue/22345)
+ // Don't type-check right away because the function may
+ // be part of a type definition to which the function
+ // body refers. Instead, type-check as soon as possible,
+ // but before the enclosing scope contents changes (go.dev/issue/22992).
+ check.later(func() {
+ check.funcBody(decl, "<function literal>", sig, e.Body, iota)
+ }).describef(e, "func literal")
+ }
+ x.mode = value
+ x.typ = sig
+ } else {
+ check.errorf(e, InvalidSyntaxTree, "invalid function literal %s", e)
+ goto Error
+ }
+
+ case *ast.CompositeLit:
+ var typ, base Type
+
+ switch {
+ case e.Type != nil:
+ // composite literal type present - use it
+ // [...]T array types may only appear with composite literals.
+ // Check for them here so we don't have to handle ... in general.
+ if atyp, _ := e.Type.(*ast.ArrayType); atyp != nil && atyp.Len != nil {
+ if ellip, _ := atyp.Len.(*ast.Ellipsis); ellip != nil && ellip.Elt == nil {
+ // We have an "open" [...]T array type.
+ // Create a new ArrayType with unknown length (-1)
+ // and finish setting it up after analyzing the literal.
+ typ = &Array{len: -1, elem: check.varType(atyp.Elt)}
+ base = typ
+ break
+ }
+ }
+ typ = check.typ(e.Type)
+ base = typ
+
+ case hint != nil:
+ // no composite literal type present - use hint (element type of enclosing type)
+ typ = hint
+ base, _ = deref(coreType(typ)) // *T implies &T{}
+ if base == nil {
+ check.errorf(e, InvalidLit, "invalid composite literal element type %s (no core type)", typ)
+ goto Error
+ }
+
+ default:
+ // TODO(gri) provide better error messages depending on context
+ check.error(e, UntypedLit, "missing type in composite literal")
+ goto Error
+ }
+
+ switch utyp := coreType(base).(type) {
+ case *Struct:
+ // Prevent crash if the struct referred to is not yet set up.
+ // See analogous comment for *Array.
+ if utyp.fields == nil {
+ check.error(e, InvalidTypeCycle, "invalid recursive type")
+ goto Error
+ }
+ if len(e.Elts) == 0 {
+ break
+ }
+ // Convention for error messages on invalid struct literals:
+ // we mention the struct type only if it clarifies the error
+ // (e.g., a duplicate field error doesn't need the struct type).
+ fields := utyp.fields
+ if _, ok := e.Elts[0].(*ast.KeyValueExpr); ok {
+ // all elements must have keys
+ visited := make([]bool, len(fields))
+ for _, e := range e.Elts {
+ kv, _ := e.(*ast.KeyValueExpr)
+ if kv == nil {
+ check.error(e, MixedStructLit, "mixture of field:value and value elements in struct literal")
+ continue
+ }
+ key, _ := kv.Key.(*ast.Ident)
+ // do all possible checks early (before exiting due to errors)
+ // so we don't drop information on the floor
+ check.expr(nil, x, kv.Value)
+ if key == nil {
+ check.errorf(kv, InvalidLitField, "invalid field name %s in struct literal", kv.Key)
+ continue
+ }
+ i := fieldIndex(utyp.fields, check.pkg, key.Name)
+ if i < 0 {
+ check.errorf(kv, MissingLitField, "unknown field %s in struct literal of type %s", key.Name, base)
+ continue
+ }
+ fld := fields[i]
+ check.recordUse(key, fld)
+ etyp := fld.typ
+ check.assignment(x, etyp, "struct literal")
+ // 0 <= i < len(fields)
+ if visited[i] {
+ check.errorf(kv, DuplicateLitField, "duplicate field name %s in struct literal", key.Name)
+ continue
+ }
+ visited[i] = true
+ }
+ } else {
+ // no element must have a key
+ for i, e := range e.Elts {
+ if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
+ check.error(kv, MixedStructLit, "mixture of field:value and value elements in struct literal")
+ continue
+ }
+ check.expr(nil, x, e)
+ if i >= len(fields) {
+ check.errorf(x, InvalidStructLit, "too many values in struct literal of type %s", base)
+ break // cannot continue
+ }
+ // i < len(fields)
+ fld := fields[i]
+ if !fld.Exported() && fld.pkg != check.pkg {
+ check.errorf(x,
+ UnexportedLitField,
+ "implicit assignment to unexported field %s in struct literal of type %s", fld.name, base)
+ continue
+ }
+ etyp := fld.typ
+ check.assignment(x, etyp, "struct literal")
+ }
+ if len(e.Elts) < len(fields) {
+ check.errorf(inNode(e, e.Rbrace), InvalidStructLit, "too few values in struct literal of type %s", base)
+ // ok to continue
+ }
+ }
+
+ case *Array:
+ // Prevent crash if the array referred to is not yet set up. Was go.dev/issue/18643.
+ // This is a stop-gap solution. Should use Checker.objPath to report entire
+ // path starting with earliest declaration in the source. TODO(gri) fix this.
+ if utyp.elem == nil {
+ check.error(e, InvalidTypeCycle, "invalid recursive type")
+ goto Error
+ }
+ n := check.indexedElts(e.Elts, utyp.elem, utyp.len)
+ // If we have an array of unknown length (usually [...]T arrays, but also
+ // arrays [n]T where n is invalid) set the length now that we know it and
+ // record the type for the array (usually done by check.typ which is not
+ // called for [...]T). We handle [...]T arrays and arrays with invalid
+ // length the same here because it makes sense to "guess" the length for
+ // the latter if we have a composite literal; e.g. for [n]int{1, 2, 3}
+ // where n is invalid for some reason, it seems fair to assume it should
+ // be 3 (see also Checked.arrayLength and go.dev/issue/27346).
+ if utyp.len < 0 {
+ utyp.len = n
+ // e.Type is missing if we have a composite literal element
+ // that is itself a composite literal with omitted type. In
+ // that case there is nothing to record (there is no type in
+ // the source at that point).
+ if e.Type != nil {
+ check.recordTypeAndValue(e.Type, typexpr, utyp, nil)
+ }
+ }
+
+ case *Slice:
+ // Prevent crash if the slice referred to is not yet set up.
+ // See analogous comment for *Array.
+ if utyp.elem == nil {
+ check.error(e, InvalidTypeCycle, "invalid recursive type")
+ goto Error
+ }
+ check.indexedElts(e.Elts, utyp.elem, -1)
+
+ case *Map:
+ // Prevent crash if the map referred to is not yet set up.
+ // See analogous comment for *Array.
+ if utyp.key == nil || utyp.elem == nil {
+ check.error(e, InvalidTypeCycle, "invalid recursive type")
+ goto Error
+ }
+ // If the map key type is an interface (but not a type parameter),
+ // the type of a constant key must be considered when checking for
+ // duplicates.
+ keyIsInterface := isNonTypeParamInterface(utyp.key)
+ visited := make(map[any][]Type, len(e.Elts))
+ for _, e := range e.Elts {
+ kv, _ := e.(*ast.KeyValueExpr)
+ if kv == nil {
+ check.error(e, MissingLitKey, "missing key in map literal")
+ continue
+ }
+ check.exprWithHint(x, kv.Key, utyp.key)
+ check.assignment(x, utyp.key, "map literal")
+ if x.mode == invalid {
+ continue
+ }
+ if x.mode == constant_ {
+ duplicate := false
+ xkey := keyVal(x.val)
+ if keyIsInterface {
+ for _, vtyp := range visited[xkey] {
+ if Identical(vtyp, x.typ) {
+ duplicate = true
+ break
+ }
+ }
+ visited[xkey] = append(visited[xkey], x.typ)
+ } else {
+ _, duplicate = visited[xkey]
+ visited[xkey] = nil
+ }
+ if duplicate {
+ check.errorf(x, DuplicateLitKey, "duplicate key %s in map literal", x.val)
+ continue
+ }
+ }
+ check.exprWithHint(x, kv.Value, utyp.elem)
+ check.assignment(x, utyp.elem, "map literal")
+ }
+
+ default:
+ // when "using" all elements unpack KeyValueExpr
+ // explicitly because check.use doesn't accept them
+ for _, e := range e.Elts {
+ if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
+ // Ideally, we should also "use" kv.Key but we can't know
+ // if it's an externally defined struct key or not. Going
+ // forward anyway can lead to other errors. Give up instead.
+ e = kv.Value
+ }
+ check.use(e)
+ }
+ // if utyp is invalid, an error was reported before
+ if utyp != Typ[Invalid] {
+ check.errorf(e, InvalidLit, "invalid composite literal type %s", typ)
+ goto Error
+ }
+ }
+
+ x.mode = value
+ x.typ = typ
+
+ case *ast.ParenExpr:
+ // type inference doesn't go past parentheses (targe type T = nil)
+ kind := check.rawExpr(nil, x, e.X, nil, false)
+ x.expr = e
+ return kind
+
+ case *ast.SelectorExpr:
+ check.selector(x, e, nil, false)
+
+ case *ast.IndexExpr, *ast.IndexListExpr:
+ ix := typeparams.UnpackIndexExpr(e)
+ if check.indexExpr(x, ix) {
+ var tsig *Signature
+ if enableReverseTypeInference && T != nil {
+ tsig, _ = under(T).(*Signature)
+ }
+ check.funcInst(tsig, e.Pos(), x, ix, true)
+ }
+ if x.mode == invalid {
+ goto Error
+ }
+
+ case *ast.SliceExpr:
+ check.sliceExpr(x, e)
+ if x.mode == invalid {
+ goto Error
+ }
+
+ case *ast.TypeAssertExpr:
+ check.expr(nil, x, e.X)
+ if x.mode == invalid {
+ goto Error
+ }
+ // x.(type) expressions are handled explicitly in type switches
+ if e.Type == nil {
+ // Don't use invalidAST because this can occur in the AST produced by
+ // go/parser.
+ check.error(e, BadTypeKeyword, "use of .(type) outside type switch")
+ goto Error
+ }
+ if isTypeParam(x.typ) {
+ check.errorf(x, InvalidAssert, invalidOp+"cannot use type assertion on type parameter value %s", x)
+ goto Error
+ }
+ if _, ok := under(x.typ).(*Interface); !ok {
+ check.errorf(x, InvalidAssert, invalidOp+"%s is not an interface", x)
+ goto Error
+ }
+ T := check.varType(e.Type)
+ if T == Typ[Invalid] {
+ goto Error
+ }
+ check.typeAssertion(e, x, T, false)
+ x.mode = commaok
+ x.typ = T
+
+ case *ast.CallExpr:
+ return check.callExpr(x, e)
+
+ case *ast.StarExpr:
+ check.exprOrType(x, e.X, false)
+ switch x.mode {
+ case invalid:
+ goto Error
+ case typexpr:
+ check.validVarType(e.X, x.typ)
+ x.typ = &Pointer{base: x.typ}
+ default:
+ var base Type
+ if !underIs(x.typ, func(u Type) bool {
+ p, _ := u.(*Pointer)
+ if p == nil {
+ check.errorf(x, InvalidIndirection, invalidOp+"cannot indirect %s", x)
+ return false
+ }
+ if base != nil && !Identical(p.base, base) {
+ check.errorf(x, InvalidIndirection, invalidOp+"pointers of %s must have identical base types", x)
+ return false
+ }
+ base = p.base
+ return true
+ }) {
+ goto Error
+ }
+ x.mode = variable
+ x.typ = base
+ }
+
+ case *ast.UnaryExpr:
+ check.unary(x, e)
+ if x.mode == invalid {
+ goto Error
+ }
+ if e.Op == token.ARROW {
+ x.expr = e
+ return statement // receive operations may appear in statement context
+ }
+
+ case *ast.BinaryExpr:
+ check.binary(x, e, e.X, e.Y, e.Op, e.OpPos)
+ if x.mode == invalid {
+ goto Error
+ }
+
+ case *ast.KeyValueExpr:
+ // key:value expressions are handled in composite literals
+ check.error(e, InvalidSyntaxTree, "no key:value expected")
+ goto Error
+
+ case *ast.ArrayType, *ast.StructType, *ast.FuncType,
+ *ast.InterfaceType, *ast.MapType, *ast.ChanType:
+ x.mode = typexpr
+ x.typ = check.typ(e)
+ // Note: rawExpr (caller of exprInternal) will call check.recordTypeAndValue
+ // even though check.typ has already called it. This is fine as both
+ // times the same expression and type are recorded. It is also not a
+ // performance issue because we only reach here for composite literal
+ // types, which are comparatively rare.
+
+ default:
+ panic(fmt.Sprintf("%s: unknown expression type %T", check.fset.Position(e.Pos()), e))
+ }
+
+ // everything went well
+ x.expr = e
+ return expression
+
+Error:
+ x.mode = invalid
+ x.expr = e
+ return statement // avoid follow-up errors
+}
+
+// keyVal maps a complex, float, integer, string or boolean constant value
+// to the corresponding complex128, float64, int64, uint64, string, or bool
+// Go value if possible; otherwise it returns x.
+// A complex constant that can be represented as a float (such as 1.2 + 0i)
+// is returned as a floating point value; if a floating point value can be
+// represented as an integer (such as 1.0) it is returned as an integer value.
+// This ensures that constants of different kind but equal value (such as
+// 1.0 + 0i, 1.0, 1) result in the same value.
+func keyVal(x constant.Value) interface{} {
+ switch x.Kind() {
+ case constant.Complex:
+ f := constant.ToFloat(x)
+ if f.Kind() != constant.Float {
+ r, _ := constant.Float64Val(constant.Real(x))
+ i, _ := constant.Float64Val(constant.Imag(x))
+ return complex(r, i)
+ }
+ x = f
+ fallthrough
+ case constant.Float:
+ i := constant.ToInt(x)
+ if i.Kind() != constant.Int {
+ v, _ := constant.Float64Val(x)
+ return v
+ }
+ x = i
+ fallthrough
+ case constant.Int:
+ if v, ok := constant.Int64Val(x); ok {
+ return v
+ }
+ if v, ok := constant.Uint64Val(x); ok {
+ return v
+ }
+ case constant.String:
+ return constant.StringVal(x)
+ case constant.Bool:
+ return constant.BoolVal(x)
+ }
+ return x
+}
+
+// typeAssertion checks x.(T). The type of x must be an interface.
+func (check *Checker) typeAssertion(e ast.Expr, x *operand, T Type, typeSwitch bool) {
+ var cause string
+ if check.assertableTo(x.typ, T, &cause) {
+ return // success
+ }
+
+ if typeSwitch {
+ check.errorf(e, ImpossibleAssert, "impossible type switch case: %s\n\t%s cannot have dynamic type %s %s", e, x, T, cause)
+ return
+ }
+
+ check.errorf(e, ImpossibleAssert, "impossible type assertion: %s\n\t%s does not implement %s %s", e, T, x.typ, cause)
+}
+
+// expr typechecks expression e and initializes x with the expression value.
+// If a non-nil target type T is given and e is a generic function
+// or function call, T is used to infer the type arguments for e.
+// The result must be a single value.
+// If an error occurred, x.mode is set to invalid.
+func (check *Checker) expr(T Type, x *operand, e ast.Expr) {
+ check.rawExpr(T, x, e, nil, false)
+ check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
+ check.singleValue(x)
+}
+
+// genericExpr is like expr but the result may also be generic.
+func (check *Checker) genericExpr(x *operand, e ast.Expr) {
+ check.rawExpr(nil, x, e, nil, true)
+ check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
+ check.singleValue(x)
+}
+
+// multiExpr typechecks e and returns its value (or values) in list.
+// If allowCommaOk is set and e is a map index, comma-ok, or comma-err
+// expression, the result is a two-element list containing the value
+// of e, and an untyped bool value or an error value, respectively.
+// If an error occurred, list[0] is not valid.
+func (check *Checker) multiExpr(e ast.Expr, allowCommaOk bool) (list []*operand, commaOk bool) {
+ var x operand
+ check.rawExpr(nil, &x, e, nil, false)
+ check.exclude(&x, 1<<novalue|1<<builtin|1<<typexpr)
+
+ if t, ok := x.typ.(*Tuple); ok && x.mode != invalid {
+ // multiple values
+ list = make([]*operand, t.Len())
+ for i, v := range t.vars {
+ list[i] = &operand{mode: value, expr: e, typ: v.typ}
+ }
+ return
+ }
+
+ // exactly one (possibly invalid or comma-ok) value
+ list = []*operand{&x}
+ if allowCommaOk && (x.mode == mapindex || x.mode == commaok || x.mode == commaerr) {
+ x2 := &operand{mode: value, expr: e, typ: Typ[UntypedBool]}
+ if x.mode == commaerr {
+ x2.typ = universeError
+ }
+ list = append(list, x2)
+ commaOk = true
+ }
+
+ return
+}
+
+// exprWithHint typechecks expression e and initializes x with the expression value;
+// hint is the type of a composite literal element.
+// If an error occurred, x.mode is set to invalid.
+func (check *Checker) exprWithHint(x *operand, e ast.Expr, hint Type) {
+ assert(hint != nil)
+ check.rawExpr(nil, x, e, hint, false)
+ check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
+ check.singleValue(x)
+}
+
+// exprOrType typechecks expression or type e and initializes x with the expression value or type.
+// If allowGeneric is set, the operand type may be an uninstantiated parameterized type or function
+// value.
+// If an error occurred, x.mode is set to invalid.
+func (check *Checker) exprOrType(x *operand, e ast.Expr, allowGeneric bool) {
+ check.rawExpr(nil, x, e, nil, allowGeneric)
+ check.exclude(x, 1<<novalue)
+ check.singleValue(x)
+}
+
+// exclude reports an error if x.mode is in modeset and sets x.mode to invalid.
+// The modeset may contain any of 1<<novalue, 1<<builtin, 1<<typexpr.
+func (check *Checker) exclude(x *operand, modeset uint) {
+ if modeset&(1<<x.mode) != 0 {
+ var msg string
+ var code Code
+ switch x.mode {
+ case novalue:
+ if modeset&(1<<typexpr) != 0 {
+ msg = "%s used as value"
+ } else {
+ msg = "%s used as value or type"
+ }
+ code = TooManyValues
+ case builtin:
+ msg = "%s must be called"
+ code = UncalledBuiltin
+ case typexpr:
+ msg = "%s is not an expression"
+ code = NotAnExpr
+ default:
+ unreachable()
+ }
+ check.errorf(x, code, msg, x)
+ x.mode = invalid
+ }
+}
+
+// singleValue reports an error if x describes a tuple and sets x.mode to invalid.
+func (check *Checker) singleValue(x *operand) {
+ if x.mode == value {
+ // tuple types are never named - no need for underlying type below
+ if t, ok := x.typ.(*Tuple); ok {
+ assert(t.Len() != 1)
+ check.errorf(x, TooManyValues, "multiple-value %s in single-value context", x)
+ x.mode = invalid
+ }
+ }
+}
diff --git a/contrib/go/_std_1.20/src/go/types/exprstring.go b/contrib/go/_std_1.21/src/go/types/exprstring.go
index 3cdf30fba1..3cdf30fba1 100644
--- a/contrib/go/_std_1.20/src/go/types/exprstring.go
+++ b/contrib/go/_std_1.21/src/go/types/exprstring.go
diff --git a/contrib/go/_std_1.21/src/go/types/gccgosizes.go b/contrib/go/_std_1.21/src/go/types/gccgosizes.go
new file mode 100644
index 0000000000..9152c811e1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/gccgosizes.go
@@ -0,0 +1,43 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This is a copy of the file generated during the gccgo build process.
+// Last update 2019-01-22.
+
+package types
+
+var gccgoArchSizes = map[string]*StdSizes{
+ "386": {4, 4},
+ "alpha": {8, 8},
+ "amd64": {8, 8},
+ "amd64p32": {4, 8},
+ "arm": {4, 8},
+ "armbe": {4, 8},
+ "arm64": {8, 8},
+ "arm64be": {8, 8},
+ "ia64": {8, 8},
+ "loong64": {8, 8},
+ "m68k": {4, 2},
+ "mips": {4, 8},
+ "mipsle": {4, 8},
+ "mips64": {8, 8},
+ "mips64le": {8, 8},
+ "mips64p32": {4, 8},
+ "mips64p32le": {4, 8},
+ "nios2": {4, 8},
+ "ppc": {4, 8},
+ "ppc64": {8, 8},
+ "ppc64le": {8, 8},
+ "riscv": {4, 8},
+ "riscv64": {8, 8},
+ "s390": {4, 8},
+ "s390x": {8, 8},
+ "sh": {4, 8},
+ "shbe": {4, 8},
+ "sparc": {4, 8},
+ "sparc64": {8, 8},
+ "wasm": {8, 8},
+}
diff --git a/contrib/go/_std_1.21/src/go/types/generate.go b/contrib/go/_std_1.21/src/go/types/generate.go
new file mode 100644
index 0000000000..7fec743170
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/generate.go
@@ -0,0 +1,8 @@
+// Copyright 2023 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.
+
+// This file exists only to drive go:generate.
+//go:generate go test -run=Generate -write=all
+
+package types
diff --git a/contrib/go/_std_1.21/src/go/types/index.go b/contrib/go/_std_1.21/src/go/types/index.go
new file mode 100644
index 0000000000..c1c0f40e87
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/index.go
@@ -0,0 +1,457 @@
+// 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.
+
+// This file implements typechecking of index/slice expressions.
+
+package types
+
+import (
+ "go/ast"
+ "go/constant"
+ "go/internal/typeparams"
+ . "internal/types/errors"
+)
+
+// If e is a valid function instantiation, indexExpr returns true.
+// In that case x represents the uninstantiated function value and
+// it is the caller's responsibility to instantiate the function.
+func (check *Checker) indexExpr(x *operand, e *typeparams.IndexExpr) (isFuncInst bool) {
+ check.exprOrType(x, e.X, true)
+ // x may be generic
+
+ switch x.mode {
+ case invalid:
+ check.use(e.Indices...)
+ return false
+
+ case typexpr:
+ // type instantiation
+ x.mode = invalid
+ // TODO(gri) here we re-evaluate e.X - try to avoid this
+ x.typ = check.varType(e.Orig)
+ if x.typ != Typ[Invalid] {
+ x.mode = typexpr
+ }
+ return false
+
+ case value:
+ if sig, _ := under(x.typ).(*Signature); sig != nil && sig.TypeParams().Len() > 0 {
+ // function instantiation
+ return true
+ }
+ }
+
+ // x should not be generic at this point, but be safe and check
+ check.nonGeneric(nil, x)
+ if x.mode == invalid {
+ return false
+ }
+
+ // ordinary index expression
+ valid := false
+ length := int64(-1) // valid if >= 0
+ switch typ := under(x.typ).(type) {
+ case *Basic:
+ if isString(typ) {
+ valid = true
+ if x.mode == constant_ {
+ length = int64(len(constant.StringVal(x.val)))
+ }
+ // an indexed string always yields a byte value
+ // (not a constant) even if the string and the
+ // index are constant
+ x.mode = value
+ x.typ = universeByte // use 'byte' name
+ }
+
+ case *Array:
+ valid = true
+ length = typ.len
+ if x.mode != variable {
+ x.mode = value
+ }
+ x.typ = typ.elem
+
+ case *Pointer:
+ if typ, _ := under(typ.base).(*Array); typ != nil {
+ valid = true
+ length = typ.len
+ x.mode = variable
+ x.typ = typ.elem
+ }
+
+ case *Slice:
+ valid = true
+ x.mode = variable
+ x.typ = typ.elem
+
+ case *Map:
+ index := check.singleIndex(e)
+ if index == nil {
+ x.mode = invalid
+ return false
+ }
+ var key operand
+ check.expr(nil, &key, index)
+ check.assignment(&key, typ.key, "map index")
+ // ok to continue even if indexing failed - map element type is known
+ x.mode = mapindex
+ x.typ = typ.elem
+ x.expr = e.Orig
+ return false
+
+ case *Interface:
+ if !isTypeParam(x.typ) {
+ break
+ }
+ // TODO(gri) report detailed failure cause for better error messages
+ var key, elem Type // key != nil: we must have all maps
+ mode := variable // non-maps result mode
+ // TODO(gri) factor out closure and use it for non-typeparam cases as well
+ if typ.typeSet().underIs(func(u Type) bool {
+ l := int64(-1) // valid if >= 0
+ var k, e Type // k is only set for maps
+ switch t := u.(type) {
+ case *Basic:
+ if isString(t) {
+ e = universeByte
+ mode = value
+ }
+ case *Array:
+ l = t.len
+ e = t.elem
+ if x.mode != variable {
+ mode = value
+ }
+ case *Pointer:
+ if t, _ := under(t.base).(*Array); t != nil {
+ l = t.len
+ e = t.elem
+ }
+ case *Slice:
+ e = t.elem
+ case *Map:
+ k = t.key
+ e = t.elem
+ }
+ if e == nil {
+ return false
+ }
+ if elem == nil {
+ // first type
+ length = l
+ key, elem = k, e
+ return true
+ }
+ // all map keys must be identical (incl. all nil)
+ // (that is, we cannot mix maps with other types)
+ if !Identical(key, k) {
+ return false
+ }
+ // all element types must be identical
+ if !Identical(elem, e) {
+ return false
+ }
+ // track the minimal length for arrays, if any
+ if l >= 0 && l < length {
+ length = l
+ }
+ return true
+ }) {
+ // For maps, the index expression must be assignable to the map key type.
+ if key != nil {
+ index := check.singleIndex(e)
+ if index == nil {
+ x.mode = invalid
+ return false
+ }
+ var k operand
+ check.expr(nil, &k, index)
+ check.assignment(&k, key, "map index")
+ // ok to continue even if indexing failed - map element type is known
+ x.mode = mapindex
+ x.typ = elem
+ x.expr = e
+ return false
+ }
+
+ // no maps
+ valid = true
+ x.mode = mode
+ x.typ = elem
+ }
+ }
+
+ if !valid {
+ // types2 uses the position of '[' for the error
+ check.errorf(x, NonIndexableOperand, invalidOp+"cannot index %s", x)
+ check.use(e.Indices...)
+ x.mode = invalid
+ return false
+ }
+
+ index := check.singleIndex(e)
+ if index == nil {
+ x.mode = invalid
+ return false
+ }
+
+ // In pathological (invalid) cases (e.g.: type T1 [][[]T1{}[0][0]]T0)
+ // the element type may be accessed before it's set. Make sure we have
+ // a valid type.
+ if x.typ == nil {
+ x.typ = Typ[Invalid]
+ }
+
+ check.index(index, length)
+ return false
+}
+
+func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
+ check.expr(nil, x, e.X)
+ if x.mode == invalid {
+ check.use(e.Low, e.High, e.Max)
+ return
+ }
+
+ valid := false
+ length := int64(-1) // valid if >= 0
+ switch u := coreString(x.typ).(type) {
+ case nil:
+ check.errorf(x, NonSliceableOperand, invalidOp+"cannot slice %s: %s has no core type", x, x.typ)
+ x.mode = invalid
+ return
+
+ case *Basic:
+ if isString(u) {
+ if e.Slice3 {
+ at := e.Max
+ if at == nil {
+ at = e // e.Index[2] should be present but be careful
+ }
+ check.error(at, InvalidSliceExpr, invalidOp+"3-index slice of string")
+ x.mode = invalid
+ return
+ }
+ valid = true
+ if x.mode == constant_ {
+ length = int64(len(constant.StringVal(x.val)))
+ }
+ // spec: "For untyped string operands the result
+ // is a non-constant value of type string."
+ if isUntyped(x.typ) {
+ x.typ = Typ[String]
+ }
+ }
+
+ case *Array:
+ valid = true
+ length = u.len
+ if x.mode != variable {
+ check.errorf(x, NonSliceableOperand, invalidOp+"cannot slice %s (value not addressable)", x)
+ x.mode = invalid
+ return
+ }
+ x.typ = &Slice{elem: u.elem}
+
+ case *Pointer:
+ if u, _ := under(u.base).(*Array); u != nil {
+ valid = true
+ length = u.len
+ x.typ = &Slice{elem: u.elem}
+ }
+
+ case *Slice:
+ valid = true
+ // x.typ doesn't change
+ }
+
+ if !valid {
+ check.errorf(x, NonSliceableOperand, invalidOp+"cannot slice %s", x)
+ x.mode = invalid
+ return
+ }
+
+ x.mode = value
+
+ // spec: "Only the first index may be omitted; it defaults to 0."
+ if e.Slice3 && (e.High == nil || e.Max == nil) {
+ check.error(inNode(e, e.Rbrack), InvalidSyntaxTree, "2nd and 3rd index required in 3-index slice")
+ x.mode = invalid
+ return
+ }
+
+ // check indices
+ var ind [3]int64
+ for i, expr := range []ast.Expr{e.Low, e.High, e.Max} {
+ x := int64(-1)
+ switch {
+ case expr != nil:
+ // The "capacity" is only known statically for strings, arrays,
+ // and pointers to arrays, and it is the same as the length for
+ // those types.
+ max := int64(-1)
+ if length >= 0 {
+ max = length + 1
+ }
+ if _, v := check.index(expr, max); v >= 0 {
+ x = v
+ }
+ case i == 0:
+ // default is 0 for the first index
+ x = 0
+ case length >= 0:
+ // default is length (== capacity) otherwise
+ x = length
+ }
+ ind[i] = x
+ }
+
+ // constant indices must be in range
+ // (check.index already checks that existing indices >= 0)
+L:
+ for i, x := range ind[:len(ind)-1] {
+ if x > 0 {
+ for j, y := range ind[i+1:] {
+ if y >= 0 && y < x {
+ // The value y corresponds to the expression e.Index[i+1+j].
+ // Because y >= 0, it must have been set from the expression
+ // when checking indices and thus e.Index[i+1+j] is not nil.
+ at := []ast.Expr{e.Low, e.High, e.Max}[i+1+j]
+ check.errorf(at, SwappedSliceIndices, "invalid slice indices: %d < %d", y, x)
+ break L // only report one error, ok to continue
+ }
+ }
+ }
+ }
+}
+
+// singleIndex returns the (single) index from the index expression e.
+// If the index is missing, or if there are multiple indices, an error
+// is reported and the result is nil.
+func (check *Checker) singleIndex(expr *typeparams.IndexExpr) ast.Expr {
+ if len(expr.Indices) == 0 {
+ check.errorf(expr.Orig, InvalidSyntaxTree, "index expression %v with 0 indices", expr)
+ return nil
+ }
+ if len(expr.Indices) > 1 {
+ // TODO(rFindley) should this get a distinct error code?
+ check.error(expr.Indices[1], InvalidIndex, invalidOp+"more than one index")
+ }
+ return expr.Indices[0]
+}
+
+// index checks an index expression for validity.
+// If max >= 0, it is the upper bound for index.
+// If the result typ is != Typ[Invalid], index is valid and typ is its (possibly named) integer type.
+// If the result val >= 0, index is valid and val is its constant int value.
+func (check *Checker) index(index ast.Expr, max int64) (typ Type, val int64) {
+ typ = Typ[Invalid]
+ val = -1
+
+ var x operand
+ check.expr(nil, &x, index)
+ if !check.isValidIndex(&x, InvalidIndex, "index", false) {
+ return
+ }
+
+ if x.mode != constant_ {
+ return x.typ, -1
+ }
+
+ if x.val.Kind() == constant.Unknown {
+ return
+ }
+
+ v, ok := constant.Int64Val(x.val)
+ assert(ok)
+ if max >= 0 && v >= max {
+ check.errorf(&x, InvalidIndex, invalidArg+"index %s out of bounds [0:%d]", x.val.String(), max)
+ return
+ }
+
+ // 0 <= v [ && v < max ]
+ return x.typ, v
+}
+
+func (check *Checker) isValidIndex(x *operand, code Code, what string, allowNegative bool) bool {
+ if x.mode == invalid {
+ return false
+ }
+
+ // spec: "a constant index that is untyped is given type int"
+ check.convertUntyped(x, Typ[Int])
+ if x.mode == invalid {
+ return false
+ }
+
+ // spec: "the index x must be of integer type or an untyped constant"
+ if !allInteger(x.typ) {
+ check.errorf(x, code, invalidArg+"%s %s must be integer", what, x)
+ return false
+ }
+
+ if x.mode == constant_ {
+ // spec: "a constant index must be non-negative ..."
+ if !allowNegative && constant.Sign(x.val) < 0 {
+ check.errorf(x, code, invalidArg+"%s %s must not be negative", what, x)
+ return false
+ }
+
+ // spec: "... and representable by a value of type int"
+ if !representableConst(x.val, check, Typ[Int], &x.val) {
+ check.errorf(x, code, invalidArg+"%s %s overflows int", what, x)
+ return false
+ }
+ }
+
+ return true
+}
+
+// indexedElts checks the elements (elts) of an array or slice composite literal
+// against the literal's element type (typ), and the element indices against
+// the literal length if known (length >= 0). It returns the length of the
+// literal (maximum index value + 1).
+func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 {
+ visited := make(map[int64]bool, len(elts))
+ var index, max int64
+ for _, e := range elts {
+ // determine and check index
+ validIndex := false
+ eval := e
+ if kv, _ := e.(*ast.KeyValueExpr); kv != nil {
+ if typ, i := check.index(kv.Key, length); typ != Typ[Invalid] {
+ if i >= 0 {
+ index = i
+ validIndex = true
+ } else {
+ check.errorf(e, InvalidLitIndex, "index %s must be integer constant", kv.Key)
+ }
+ }
+ eval = kv.Value
+ } else if length >= 0 && index >= length {
+ check.errorf(e, OversizeArrayLit, "index %d is out of bounds (>= %d)", index, length)
+ } else {
+ validIndex = true
+ }
+
+ // if we have a valid index, check for duplicate entries
+ if validIndex {
+ if visited[index] {
+ check.errorf(e, DuplicateLitKey, "duplicate index %d in array or slice literal", index)
+ }
+ visited[index] = true
+ }
+ index++
+ if index > max {
+ max = index
+ }
+
+ // check element against composite literal element type
+ var x operand
+ check.exprWithHint(&x, eval, typ)
+ check.assignment(&x, typ, "array or slice literal")
+ }
+ return max
+}
diff --git a/contrib/go/_std_1.21/src/go/types/infer.go b/contrib/go/_std_1.21/src/go/types/infer.go
new file mode 100644
index 0000000000..cb7634415b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/infer.go
@@ -0,0 +1,768 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2018 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.
+
+// This file implements type parameter inference.
+
+package types
+
+import (
+ "fmt"
+ "go/token"
+ . "internal/types/errors"
+ "strings"
+)
+
+// If enableReverseTypeInference is set, uninstantiated and
+// partially instantiated generic functions may be assigned
+// (incl. returned) to variables of function type and type
+// inference will attempt to infer the missing type arguments.
+// Available with go1.21.
+const enableReverseTypeInference = true // disable for debugging
+
+// infer attempts to infer the complete set of type arguments for generic function instantiation/call
+// based on the given type parameters tparams, type arguments targs, function parameters params, and
+// function arguments args, if any. There must be at least one type parameter, no more type arguments
+// than type parameters, and params and args must match in number (incl. zero).
+// If successful, infer returns the complete list of given and inferred type arguments, one for each
+// type parameter. Otherwise the result is nil and appropriate errors will be reported.
+func (check *Checker) infer(posn positioner, tparams []*TypeParam, targs []Type, params *Tuple, args []*operand) (inferred []Type) {
+ if debug {
+ defer func() {
+ assert(inferred == nil || len(inferred) == len(tparams) && !containsNil(inferred))
+ }()
+ }
+
+ if traceInference {
+ check.dump("== infer : %s%s ➞ %s", tparams, params, targs) // aligned with rename print below
+ defer func() {
+ check.dump("=> %s ➞ %s\n", tparams, inferred)
+ }()
+ }
+
+ // There must be at least one type parameter, and no more type arguments than type parameters.
+ n := len(tparams)
+ assert(n > 0 && len(targs) <= n)
+
+ // Parameters and arguments must match in number.
+ assert(params.Len() == len(args))
+
+ // If we already have all type arguments, we're done.
+ if len(targs) == n && !containsNil(targs) {
+ return targs
+ }
+
+ // Make sure we have a "full" list of type arguments, some of which may
+ // be nil (unknown). Make a copy so as to not clobber the incoming slice.
+ if len(targs) < n {
+ targs2 := make([]Type, n)
+ copy(targs2, targs)
+ targs = targs2
+ }
+ // len(targs) == n
+
+ // Continue with the type arguments we have. Avoid matching generic
+ // parameters that already have type arguments against function arguments:
+ // It may fail because matching uses type identity while parameter passing
+ // uses assignment rules. Instantiate the parameter list with the type
+ // arguments we have, and continue with that parameter list.
+
+ // Substitute type arguments for their respective type parameters in params,
+ // if any. Note that nil targs entries are ignored by check.subst.
+ // We do this for better error messages; it's not needed for correctness.
+ // For instance, given:
+ //
+ // func f[P, Q any](P, Q) {}
+ //
+ // func _(s string) {
+ // f[int](s, s) // ERROR
+ // }
+ //
+ // With substitution, we get the error:
+ // "cannot use s (variable of type string) as int value in argument to f[int]"
+ //
+ // Without substitution we get the (worse) error:
+ // "type string of s does not match inferred type int for P"
+ // even though the type int was provided (not inferred) for P.
+ //
+ // TODO(gri) We might be able to finesse this in the error message reporting
+ // (which only happens in case of an error) and then avoid doing
+ // the substitution (which always happens).
+ if params.Len() > 0 {
+ smap := makeSubstMap(tparams, targs)
+ params = check.subst(nopos, params, smap, nil, check.context()).(*Tuple)
+ }
+
+ // Unify parameter and argument types for generic parameters with typed arguments
+ // and collect the indices of generic parameters with untyped arguments.
+ // Terminology: generic parameter = function parameter with a type-parameterized type
+ u := newUnifier(tparams, targs, check.allowVersion(check.pkg, posn, go1_21))
+
+ errorf := func(kind string, tpar, targ Type, arg *operand) {
+ // provide a better error message if we can
+ targs := u.inferred(tparams)
+ if targs[0] == nil {
+ // The first type parameter couldn't be inferred.
+ // If none of them could be inferred, don't try
+ // to provide the inferred type in the error msg.
+ allFailed := true
+ for _, targ := range targs {
+ if targ != nil {
+ allFailed = false
+ break
+ }
+ }
+ if allFailed {
+ check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match %s (cannot infer %s)", kind, targ, arg.expr, tpar, typeParamsString(tparams))
+ return
+ }
+ }
+ smap := makeSubstMap(tparams, targs)
+ // TODO(gri): pass a poser here, rather than arg.Pos().
+ inferred := check.subst(arg.Pos(), tpar, smap, nil, check.context())
+ // CannotInferTypeArgs indicates a failure of inference, though the actual
+ // error may be better attributed to a user-provided type argument (hence
+ // InvalidTypeArg). We can't differentiate these cases, so fall back on
+ // the more general CannotInferTypeArgs.
+ if inferred != tpar {
+ check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match inferred type %s for %s", kind, targ, arg.expr, inferred, tpar)
+ } else {
+ check.errorf(arg, CannotInferTypeArgs, "%s %s of %s does not match %s", kind, targ, arg.expr, tpar)
+ }
+ }
+
+ // indices of generic parameters with untyped arguments, for later use
+ var untyped []int
+
+ // --- 1 ---
+ // use information from function arguments
+
+ if traceInference {
+ u.tracef("== function parameters: %s", params)
+ u.tracef("-- function arguments : %s", args)
+ }
+
+ for i, arg := range args {
+ if arg.mode == invalid {
+ // An error was reported earlier. Ignore this arg
+ // and continue, we may still be able to infer all
+ // targs resulting in fewer follow-on errors.
+ // TODO(gri) determine if we still need this check
+ continue
+ }
+ par := params.At(i)
+ if isParameterized(tparams, par.typ) || isParameterized(tparams, arg.typ) {
+ // Function parameters are always typed. Arguments may be untyped.
+ // Collect the indices of untyped arguments and handle them later.
+ if isTyped(arg.typ) {
+ if !u.unify(par.typ, arg.typ, assign) {
+ errorf("type", par.typ, arg.typ, arg)
+ return nil
+ }
+ } else if _, ok := par.typ.(*TypeParam); ok && !arg.isNil() {
+ // Since default types are all basic (i.e., non-composite) types, an
+ // untyped argument will never match a composite parameter type; the
+ // only parameter type it can possibly match against is a *TypeParam.
+ // Thus, for untyped arguments we only need to look at parameter types
+ // that are single type parameters.
+ // Also, untyped nils don't have a default type and can be ignored.
+ untyped = append(untyped, i)
+ }
+ }
+ }
+
+ if traceInference {
+ inferred := u.inferred(tparams)
+ u.tracef("=> %s ➞ %s\n", tparams, inferred)
+ }
+
+ // --- 2 ---
+ // use information from type parameter constraints
+
+ if traceInference {
+ u.tracef("== type parameters: %s", tparams)
+ }
+
+ // Unify type parameters with their constraints as long
+ // as progress is being made.
+ //
+ // This is an O(n^2) algorithm where n is the number of
+ // type parameters: if there is progress, at least one
+ // type argument is inferred per iteration, and we have
+ // a doubly nested loop.
+ //
+ // In practice this is not a problem because the number
+ // of type parameters tends to be very small (< 5 or so).
+ // (It should be possible for unification to efficiently
+ // signal newly inferred type arguments; then the loops
+ // here could handle the respective type parameters only,
+ // but that will come at a cost of extra complexity which
+ // may not be worth it.)
+ for i := 0; ; i++ {
+ nn := u.unknowns()
+ if traceInference {
+ if i > 0 {
+ fmt.Println()
+ }
+ u.tracef("-- iteration %d", i)
+ }
+
+ for _, tpar := range tparams {
+ tx := u.at(tpar)
+ core, single := coreTerm(tpar)
+ if traceInference {
+ u.tracef("-- type parameter %s = %s: core(%s) = %s, single = %v", tpar, tx, tpar, core, single)
+ }
+
+ // If there is a core term (i.e., a core type with tilde information)
+ // unify the type parameter with the core type.
+ if core != nil {
+ // A type parameter can be unified with its core type in two cases.
+ switch {
+ case tx != nil:
+ // The corresponding type argument tx is known. There are 2 cases:
+ // 1) If the core type has a tilde, per spec requirement for tilde
+ // elements, the core type is an underlying (literal) type.
+ // And because of the tilde, the underlying type of tx must match
+ // against the core type.
+ // But because unify automatically matches a defined type against
+ // an underlying literal type, we can simply unify tx with the
+ // core type.
+ // 2) If the core type doesn't have a tilde, we also must unify tx
+ // with the core type.
+ if !u.unify(tx, core.typ, 0) {
+ // TODO(gri) Type parameters that appear in the constraint and
+ // for which we have type arguments inferred should
+ // use those type arguments for a better error message.
+ check.errorf(posn, CannotInferTypeArgs, "%s (type %s) does not satisfy %s", tpar, tx, tpar.Constraint())
+ return nil
+ }
+ case single && !core.tilde:
+ // The corresponding type argument tx is unknown and there's a single
+ // specific type and no tilde.
+ // In this case the type argument must be that single type; set it.
+ u.set(tpar, core.typ)
+ }
+ } else {
+ if tx != nil {
+ // We don't have a core type, but the type argument tx is known.
+ // It must have (at least) all the methods of the type constraint,
+ // and the method signatures must unify; otherwise tx cannot satisfy
+ // the constraint.
+ // TODO(gri) Now that unification handles interfaces, this code can
+ // be reduced to calling u.unify(tx, tpar.iface(), assign)
+ // (which will compare signatures exactly as we do below).
+ // We leave it as is for now because missingMethod provides
+ // a failure cause which allows for a better error message.
+ // Eventually, unify should return an error with cause.
+ var cause string
+ constraint := tpar.iface()
+ if m, _ := check.missingMethod(tx, constraint, true, func(x, y Type) bool { return u.unify(x, y, exact) }, &cause); m != nil {
+ // TODO(gri) better error message (see TODO above)
+ check.errorf(posn, CannotInferTypeArgs, "%s (type %s) does not satisfy %s %s", tpar, tx, tpar.Constraint(), cause)
+ return nil
+ }
+ }
+ }
+ }
+
+ if u.unknowns() == nn {
+ break // no progress
+ }
+ }
+
+ if traceInference {
+ inferred := u.inferred(tparams)
+ u.tracef("=> %s ➞ %s\n", tparams, inferred)
+ }
+
+ // --- 3 ---
+ // use information from untyped constants
+
+ if traceInference {
+ u.tracef("== untyped arguments: %v", untyped)
+ }
+
+ // Some generic parameters with untyped arguments may have been given a type by now.
+ // Collect all remaining parameters that don't have a type yet and determine the
+ // maximum untyped type for each of those parameters, if possible.
+ var maxUntyped map[*TypeParam]Type // lazily allocated (we may not need it)
+ for _, index := range untyped {
+ tpar := params.At(index).typ.(*TypeParam) // is type parameter by construction of untyped
+ if u.at(tpar) == nil {
+ arg := args[index] // arg corresponding to tpar
+ if maxUntyped == nil {
+ maxUntyped = make(map[*TypeParam]Type)
+ }
+ max := maxUntyped[tpar]
+ if max == nil {
+ max = arg.typ
+ } else {
+ m := maxType(max, arg.typ)
+ if m == nil {
+ check.errorf(arg, CannotInferTypeArgs, "mismatched types %s and %s (cannot infer %s)", max, arg.typ, tpar)
+ return nil
+ }
+ max = m
+ }
+ maxUntyped[tpar] = max
+ }
+ }
+ // maxUntyped contains the maximum untyped type for each type parameter
+ // which doesn't have a type yet. Set the respective default types.
+ for tpar, typ := range maxUntyped {
+ d := Default(typ)
+ assert(isTyped(d))
+ u.set(tpar, d)
+ }
+
+ // --- simplify ---
+
+ // u.inferred(tparams) now contains the incoming type arguments plus any additional type
+ // arguments which were inferred. The inferred non-nil entries may still contain
+ // references to other type parameters found in constraints.
+ // For instance, for [A any, B interface{ []C }, C interface{ *A }], if A == int
+ // was given, unification produced the type list [int, []C, *A]. We eliminate the
+ // remaining type parameters by substituting the type parameters in this type list
+ // until nothing changes anymore.
+ inferred = u.inferred(tparams)
+ if debug {
+ for i, targ := range targs {
+ assert(targ == nil || inferred[i] == targ)
+ }
+ }
+
+ // The data structure of each (provided or inferred) type represents a graph, where
+ // each node corresponds to a type and each (directed) vertex points to a component
+ // type. The substitution process described above repeatedly replaces type parameter
+ // nodes in these graphs with the graphs of the types the type parameters stand for,
+ // which creates a new (possibly bigger) graph for each type.
+ // The substitution process will not stop if the replacement graph for a type parameter
+ // also contains that type parameter.
+ // For instance, for [A interface{ *A }], without any type argument provided for A,
+ // unification produces the type list [*A]. Substituting A in *A with the value for
+ // A will lead to infinite expansion by producing [**A], [****A], [********A], etc.,
+ // because the graph A -> *A has a cycle through A.
+ // Generally, cycles may occur across multiple type parameters and inferred types
+ // (for instance, consider [P interface{ *Q }, Q interface{ func(P) }]).
+ // We eliminate cycles by walking the graphs for all type parameters. If a cycle
+ // through a type parameter is detected, killCycles nils out the respective type
+ // (in the inferred list) which kills the cycle, and marks the corresponding type
+ // parameter as not inferred.
+ //
+ // TODO(gri) If useful, we could report the respective cycle as an error. We don't
+ // do this now because type inference will fail anyway, and furthermore,
+ // constraints with cycles of this kind cannot currently be satisfied by
+ // any user-supplied type. But should that change, reporting an error
+ // would be wrong.
+ killCycles(tparams, inferred)
+
+ // dirty tracks the indices of all types that may still contain type parameters.
+ // We know that nil type entries and entries corresponding to provided (non-nil)
+ // type arguments are clean, so exclude them from the start.
+ var dirty []int
+ for i, typ := range inferred {
+ if typ != nil && (i >= len(targs) || targs[i] == nil) {
+ dirty = append(dirty, i)
+ }
+ }
+
+ for len(dirty) > 0 {
+ if traceInference {
+ u.tracef("-- simplify %s ➞ %s", tparams, inferred)
+ }
+ // TODO(gri) Instead of creating a new substMap for each iteration,
+ // provide an update operation for substMaps and only change when
+ // needed. Optimization.
+ smap := makeSubstMap(tparams, inferred)
+ n := 0
+ for _, index := range dirty {
+ t0 := inferred[index]
+ if t1 := check.subst(nopos, t0, smap, nil, check.context()); t1 != t0 {
+ // t0 was simplified to t1.
+ // If t0 was a generic function, but the simplified signature t1 does
+ // not contain any type parameters anymore, the function is not generic
+ // anymore. Remove it's type parameters. (go.dev/issue/59953)
+ // Note that if t0 was a signature, t1 must be a signature, and t1
+ // can only be a generic signature if it originated from a generic
+ // function argument. Those signatures are never defined types and
+ // thus there is no need to call under below.
+ // TODO(gri) Consider doing this in Checker.subst.
+ // Then this would fall out automatically here and also
+ // in instantiation (where we also explicitly nil out
+ // type parameters). See the *Signature TODO in subst.
+ if sig, _ := t1.(*Signature); sig != nil && sig.TypeParams().Len() > 0 && !isParameterized(tparams, sig) {
+ sig.tparams = nil
+ }
+ inferred[index] = t1
+ dirty[n] = index
+ n++
+ }
+ }
+ dirty = dirty[:n]
+ }
+
+ // Once nothing changes anymore, we may still have type parameters left;
+ // e.g., a constraint with core type *P may match a type parameter Q but
+ // we don't have any type arguments to fill in for *P or Q (go.dev/issue/45548).
+ // Don't let such inferences escape; instead treat them as unresolved.
+ for i, typ := range inferred {
+ if typ == nil || isParameterized(tparams, typ) {
+ obj := tparams[i].obj
+ check.errorf(posn, CannotInferTypeArgs, "cannot infer %s (%s)", obj.name, obj.pos)
+ return nil
+ }
+ }
+
+ return
+}
+
+// containsNil reports whether list contains a nil entry.
+func containsNil(list []Type) bool {
+ for _, t := range list {
+ if t == nil {
+ return true
+ }
+ }
+ return false
+}
+
+// renameTParams renames the type parameters in the given type such that each type
+// parameter is given a new identity. renameTParams returns the new type parameters
+// and updated type. If the result type is unchanged from the argument type, none
+// of the type parameters in tparams occurred in the type.
+// If typ is a generic function, type parameters held with typ are not changed and
+// must be updated separately if desired.
+// The positions is only used for debug traces.
+func (check *Checker) renameTParams(pos token.Pos, tparams []*TypeParam, typ Type) ([]*TypeParam, Type) {
+ // For the purpose of type inference we must differentiate type parameters
+ // occurring in explicit type or value function arguments from the type
+ // parameters we are solving for via unification because they may be the
+ // same in self-recursive calls:
+ //
+ // func f[P constraint](x P) {
+ // f(x)
+ // }
+ //
+ // In this example, without type parameter renaming, the P used in the
+ // instantiation f[P] has the same pointer identity as the P we are trying
+ // to solve for through type inference. This causes problems for type
+ // unification. Because any such self-recursive call is equivalent to
+ // a mutually recursive call, type parameter renaming can be used to
+ // create separate, disentangled type parameters. The above example
+ // can be rewritten into the following equivalent code:
+ //
+ // func f[P constraint](x P) {
+ // f2(x)
+ // }
+ //
+ // func f2[P2 constraint](x P2) {
+ // f(x)
+ // }
+ //
+ // Type parameter renaming turns the first example into the second
+ // example by renaming the type parameter P into P2.
+ if len(tparams) == 0 {
+ return nil, typ // nothing to do
+ }
+
+ tparams2 := make([]*TypeParam, len(tparams))
+ for i, tparam := range tparams {
+ tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
+ tparams2[i] = NewTypeParam(tname, nil)
+ tparams2[i].index = tparam.index // == i
+ }
+
+ renameMap := makeRenameMap(tparams, tparams2)
+ for i, tparam := range tparams {
+ tparams2[i].bound = check.subst(pos, tparam.bound, renameMap, nil, check.context())
+ }
+
+ return tparams2, check.subst(pos, typ, renameMap, nil, check.context())
+}
+
+// typeParamsString produces a string containing all the type parameter names
+// in list suitable for human consumption.
+func typeParamsString(list []*TypeParam) string {
+ // common cases
+ n := len(list)
+ switch n {
+ case 0:
+ return ""
+ case 1:
+ return list[0].obj.name
+ case 2:
+ return list[0].obj.name + " and " + list[1].obj.name
+ }
+
+ // general case (n > 2)
+ var buf strings.Builder
+ for i, tname := range list[:n-1] {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ buf.WriteString(tname.obj.name)
+ }
+ buf.WriteString(", and ")
+ buf.WriteString(list[n-1].obj.name)
+ return buf.String()
+}
+
+// isParameterized reports whether typ contains any of the type parameters of tparams.
+// If typ is a generic function, isParameterized ignores the type parameter declarations;
+// it only considers the signature proper (incoming and result parameters).
+func isParameterized(tparams []*TypeParam, typ Type) bool {
+ w := tpWalker{
+ tparams: tparams,
+ seen: make(map[Type]bool),
+ }
+ return w.isParameterized(typ)
+}
+
+type tpWalker struct {
+ tparams []*TypeParam
+ seen map[Type]bool
+}
+
+func (w *tpWalker) isParameterized(typ Type) (res bool) {
+ // detect cycles
+ if x, ok := w.seen[typ]; ok {
+ return x
+ }
+ w.seen[typ] = false
+ defer func() {
+ w.seen[typ] = res
+ }()
+
+ switch t := typ.(type) {
+ case *Basic:
+ // nothing to do
+
+ case *Array:
+ return w.isParameterized(t.elem)
+
+ case *Slice:
+ return w.isParameterized(t.elem)
+
+ case *Struct:
+ return w.varList(t.fields)
+
+ case *Pointer:
+ return w.isParameterized(t.base)
+
+ case *Tuple:
+ // This case does not occur from within isParameterized
+ // because tuples only appear in signatures where they
+ // are handled explicitly. But isParameterized is also
+ // called by Checker.callExpr with a function result tuple
+ // if instantiation failed (go.dev/issue/59890).
+ return t != nil && w.varList(t.vars)
+
+ case *Signature:
+ // t.tparams may not be nil if we are looking at a signature
+ // of a generic function type (or an interface method) that is
+ // part of the type we're testing. We don't care about these type
+ // parameters.
+ // Similarly, the receiver of a method may declare (rather than
+ // use) type parameters, we don't care about those either.
+ // Thus, we only need to look at the input and result parameters.
+ return t.params != nil && w.varList(t.params.vars) || t.results != nil && w.varList(t.results.vars)
+
+ case *Interface:
+ tset := t.typeSet()
+ for _, m := range tset.methods {
+ if w.isParameterized(m.typ) {
+ return true
+ }
+ }
+ return tset.is(func(t *term) bool {
+ return t != nil && w.isParameterized(t.typ)
+ })
+
+ case *Map:
+ return w.isParameterized(t.key) || w.isParameterized(t.elem)
+
+ case *Chan:
+ return w.isParameterized(t.elem)
+
+ case *Named:
+ for _, t := range t.TypeArgs().list() {
+ if w.isParameterized(t) {
+ return true
+ }
+ }
+
+ case *TypeParam:
+ return tparamIndex(w.tparams, t) >= 0
+
+ default:
+ panic(fmt.Sprintf("unexpected %T", typ))
+ }
+
+ return false
+}
+
+func (w *tpWalker) varList(list []*Var) bool {
+ for _, v := range list {
+ if w.isParameterized(v.typ) {
+ return true
+ }
+ }
+ return false
+}
+
+// If the type parameter has a single specific type S, coreTerm returns (S, true).
+// Otherwise, if tpar has a core type T, it returns a term corresponding to that
+// core type and false. In that case, if any term of tpar has a tilde, the core
+// term has a tilde. In all other cases coreTerm returns (nil, false).
+func coreTerm(tpar *TypeParam) (*term, bool) {
+ n := 0
+ var single *term // valid if n == 1
+ var tilde bool
+ tpar.is(func(t *term) bool {
+ if t == nil {
+ assert(n == 0)
+ return false // no terms
+ }
+ n++
+ single = t
+ if t.tilde {
+ tilde = true
+ }
+ return true
+ })
+ if n == 1 {
+ if debug {
+ assert(debug && under(single.typ) == coreType(tpar))
+ }
+ return single, true
+ }
+ if typ := coreType(tpar); typ != nil {
+ // A core type is always an underlying type.
+ // If any term of tpar has a tilde, we don't
+ // have a precise core type and we must return
+ // a tilde as well.
+ return &term{tilde, typ}, false
+ }
+ return nil, false
+}
+
+// killCycles walks through the given type parameters and looks for cycles
+// created by type parameters whose inferred types refer back to that type
+// parameter, either directly or indirectly. If such a cycle is detected,
+// it is killed by setting the corresponding inferred type to nil.
+//
+// TODO(gri) Determine if we can simply abort inference as soon as we have
+// found a single cycle.
+func killCycles(tparams []*TypeParam, inferred []Type) {
+ w := cycleFinder{tparams, inferred, make(map[Type]bool)}
+ for _, t := range tparams {
+ w.typ(t) // t != nil
+ }
+}
+
+type cycleFinder struct {
+ tparams []*TypeParam
+ inferred []Type
+ seen map[Type]bool
+}
+
+func (w *cycleFinder) typ(typ Type) {
+ if w.seen[typ] {
+ // We have seen typ before. If it is one of the type parameters
+ // in w.tparams, iterative substitution will lead to infinite expansion.
+ // Nil out the corresponding type which effectively kills the cycle.
+ if tpar, _ := typ.(*TypeParam); tpar != nil {
+ if i := tparamIndex(w.tparams, tpar); i >= 0 {
+ // cycle through tpar
+ w.inferred[i] = nil
+ }
+ }
+ // If we don't have one of our type parameters, the cycle is due
+ // to an ordinary recursive type and we can just stop walking it.
+ return
+ }
+ w.seen[typ] = true
+ defer delete(w.seen, typ)
+
+ switch t := typ.(type) {
+ case *Basic:
+ // nothing to do
+
+ case *Array:
+ w.typ(t.elem)
+
+ case *Slice:
+ w.typ(t.elem)
+
+ case *Struct:
+ w.varList(t.fields)
+
+ case *Pointer:
+ w.typ(t.base)
+
+ // case *Tuple:
+ // This case should not occur because tuples only appear
+ // in signatures where they are handled explicitly.
+
+ case *Signature:
+ if t.params != nil {
+ w.varList(t.params.vars)
+ }
+ if t.results != nil {
+ w.varList(t.results.vars)
+ }
+
+ case *Union:
+ for _, t := range t.terms {
+ w.typ(t.typ)
+ }
+
+ case *Interface:
+ for _, m := range t.methods {
+ w.typ(m.typ)
+ }
+ for _, t := range t.embeddeds {
+ w.typ(t)
+ }
+
+ case *Map:
+ w.typ(t.key)
+ w.typ(t.elem)
+
+ case *Chan:
+ w.typ(t.elem)
+
+ case *Named:
+ for _, tpar := range t.TypeArgs().list() {
+ w.typ(tpar)
+ }
+
+ case *TypeParam:
+ if i := tparamIndex(w.tparams, t); i >= 0 && w.inferred[i] != nil {
+ w.typ(w.inferred[i])
+ }
+
+ default:
+ panic(fmt.Sprintf("unexpected %T", typ))
+ }
+}
+
+func (w *cycleFinder) varList(list []*Var) {
+ for _, v := range list {
+ w.typ(v.typ)
+ }
+}
+
+// If tpar is a type parameter in list, tparamIndex returns the index
+// of the type parameter in list. Otherwise the result is < 0.
+func tparamIndex(list []*TypeParam, tpar *TypeParam) int {
+ for i, p := range list {
+ if p == tpar {
+ return i
+ }
+ }
+ return -1
+}
diff --git a/contrib/go/_std_1.20/src/go/types/initorder.go b/contrib/go/_std_1.21/src/go/types/initorder.go
index 9ee176fbdb..9ee176fbdb 100644
--- a/contrib/go/_std_1.20/src/go/types/initorder.go
+++ b/contrib/go/_std_1.21/src/go/types/initorder.go
diff --git a/contrib/go/_std_1.21/src/go/types/instantiate.go b/contrib/go/_std_1.21/src/go/types/instantiate.go
new file mode 100644
index 0000000000..088b4338fc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/instantiate.go
@@ -0,0 +1,359 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// 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.
+
+// This file implements instantiation of generic types
+// through substitution of type parameters by type arguments.
+
+package types
+
+import (
+ "errors"
+ "fmt"
+ "go/token"
+ . "internal/types/errors"
+)
+
+// Instantiate instantiates the type orig with the given type arguments targs.
+// orig must be a *Named or a *Signature type. If there is no error, the
+// resulting Type is an instantiated type of the same kind (either a *Named or
+// a *Signature). Methods attached to a *Named type are also instantiated, and
+// associated with a new *Func that has the same position as the original
+// method, but nil function scope.
+//
+// If ctxt is non-nil, it may be used to de-duplicate the instance against
+// previous instances with the same identity. As a special case, generic
+// *Signature origin types are only considered identical if they are pointer
+// equivalent, so that instantiating distinct (but possibly identical)
+// signatures will yield different instances. The use of a shared context does
+// not guarantee that identical instances are deduplicated in all cases.
+//
+// If validate is set, Instantiate verifies that the number of type arguments
+// and parameters match, and that the type arguments satisfy their
+// corresponding type constraints. If verification fails, the resulting error
+// may wrap an *ArgumentError indicating which type argument did not satisfy
+// its corresponding type parameter constraint, and why.
+//
+// If validate is not set, Instantiate does not verify the type argument count
+// or whether the type arguments satisfy their constraints. Instantiate is
+// guaranteed to not return an error, but may panic. Specifically, for
+// *Signature types, Instantiate will panic immediately if the type argument
+// count is incorrect; for *Named types, a panic may occur later inside the
+// *Named API.
+func Instantiate(ctxt *Context, orig Type, targs []Type, validate bool) (Type, error) {
+ if ctxt == nil {
+ ctxt = NewContext()
+ }
+ if validate {
+ var tparams []*TypeParam
+ switch t := orig.(type) {
+ case *Named:
+ tparams = t.TypeParams().list()
+ case *Signature:
+ tparams = t.TypeParams().list()
+ }
+ if len(targs) != len(tparams) {
+ return nil, fmt.Errorf("got %d type arguments but %s has %d type parameters", len(targs), orig, len(tparams))
+ }
+ if i, err := (*Checker)(nil).verify(nopos, tparams, targs, ctxt); err != nil {
+ return nil, &ArgumentError{i, err}
+ }
+ }
+
+ inst := (*Checker)(nil).instance(nopos, orig, targs, nil, ctxt)
+ return inst, nil
+}
+
+// instance instantiates the given original (generic) function or type with the
+// provided type arguments and returns the resulting instance. If an identical
+// instance exists already in the given contexts, it returns that instance,
+// otherwise it creates a new one.
+//
+// If expanding is non-nil, it is the Named instance type currently being
+// expanded. If ctxt is non-nil, it is the context associated with the current
+// type-checking pass or call to Instantiate. At least one of expanding or ctxt
+// must be non-nil.
+//
+// For Named types the resulting instance may be unexpanded.
+func (check *Checker) instance(pos token.Pos, orig Type, targs []Type, expanding *Named, ctxt *Context) (res Type) {
+ // The order of the contexts below matters: we always prefer instances in the
+ // expanding instance context in order to preserve reference cycles.
+ //
+ // Invariant: if expanding != nil, the returned instance will be the instance
+ // recorded in expanding.inst.ctxt.
+ var ctxts []*Context
+ if expanding != nil {
+ ctxts = append(ctxts, expanding.inst.ctxt)
+ }
+ if ctxt != nil {
+ ctxts = append(ctxts, ctxt)
+ }
+ assert(len(ctxts) > 0)
+
+ // Compute all hashes; hashes may differ across contexts due to different
+ // unique IDs for Named types within the hasher.
+ hashes := make([]string, len(ctxts))
+ for i, ctxt := range ctxts {
+ hashes[i] = ctxt.instanceHash(orig, targs)
+ }
+
+ // If local is non-nil, updateContexts return the type recorded in
+ // local.
+ updateContexts := func(res Type) Type {
+ for i := len(ctxts) - 1; i >= 0; i-- {
+ res = ctxts[i].update(hashes[i], orig, targs, res)
+ }
+ return res
+ }
+
+ // typ may already have been instantiated with identical type arguments. In
+ // that case, re-use the existing instance.
+ for i, ctxt := range ctxts {
+ if inst := ctxt.lookup(hashes[i], orig, targs); inst != nil {
+ return updateContexts(inst)
+ }
+ }
+
+ switch orig := orig.(type) {
+ case *Named:
+ res = check.newNamedInstance(pos, orig, targs, expanding) // substituted lazily
+
+ case *Signature:
+ assert(expanding == nil) // function instances cannot be reached from Named types
+
+ tparams := orig.TypeParams()
+ if !check.validateTArgLen(pos, tparams.Len(), len(targs)) {
+ return Typ[Invalid]
+ }
+ if tparams.Len() == 0 {
+ return orig // nothing to do (minor optimization)
+ }
+ sig := check.subst(pos, orig, makeSubstMap(tparams.list(), targs), nil, ctxt).(*Signature)
+ // If the signature doesn't use its type parameters, subst
+ // will not make a copy. In that case, make a copy now (so
+ // we can set tparams to nil w/o causing side-effects).
+ if sig == orig {
+ copy := *sig
+ sig = &copy
+ }
+ // After instantiating a generic signature, it is not generic
+ // anymore; we need to set tparams to nil.
+ sig.tparams = nil
+ res = sig
+
+ default:
+ // only types and functions can be generic
+ panic(fmt.Sprintf("%v: cannot instantiate %v", pos, orig))
+ }
+
+ // Update all contexts; it's possible that we've lost a race.
+ return updateContexts(res)
+}
+
+// validateTArgLen verifies that the length of targs and tparams matches,
+// reporting an error if not. If validation fails and check is nil,
+// validateTArgLen panics.
+func (check *Checker) validateTArgLen(pos token.Pos, ntparams, ntargs int) bool {
+ if ntargs != ntparams {
+ // TODO(gri) provide better error message
+ if check != nil {
+ check.errorf(atPos(pos), WrongTypeArgCount, "got %d arguments but %d type parameters", ntargs, ntparams)
+ return false
+ }
+ panic(fmt.Sprintf("%v: got %d arguments but %d type parameters", pos, ntargs, ntparams))
+ }
+ return true
+}
+
+func (check *Checker) verify(pos token.Pos, tparams []*TypeParam, targs []Type, ctxt *Context) (int, error) {
+ smap := makeSubstMap(tparams, targs)
+ for i, tpar := range tparams {
+ // Ensure that we have a (possibly implicit) interface as type bound (go.dev/issue/51048).
+ tpar.iface()
+ // The type parameter bound is parameterized with the same type parameters
+ // as the instantiated type; before we can use it for bounds checking we
+ // need to instantiate it with the type arguments with which we instantiated
+ // the parameterized type.
+ bound := check.subst(pos, tpar.bound, smap, nil, ctxt)
+ var cause string
+ if !check.implements(pos, targs[i], bound, true, &cause) {
+ return i, errors.New(cause)
+ }
+ }
+ return -1, nil
+}
+
+// implements checks if V implements T. The receiver may be nil if implements
+// is called through an exported API call such as AssignableTo. If constraint
+// is set, T is a type constraint.
+//
+// If the provided cause is non-nil, it may be set to an error string
+// explaining why V does not implement (or satisfy, for constraints) T.
+func (check *Checker) implements(pos token.Pos, V, T Type, constraint bool, cause *string) bool {
+ Vu := under(V)
+ Tu := under(T)
+ if Vu == Typ[Invalid] || Tu == Typ[Invalid] {
+ return true // avoid follow-on errors
+ }
+ if p, _ := Vu.(*Pointer); p != nil && under(p.base) == Typ[Invalid] {
+ return true // avoid follow-on errors (see go.dev/issue/49541 for an example)
+ }
+
+ verb := "implement"
+ if constraint {
+ verb = "satisfy"
+ }
+
+ Ti, _ := Tu.(*Interface)
+ if Ti == nil {
+ if cause != nil {
+ var detail string
+ if isInterfacePtr(Tu) {
+ detail = check.sprintf("type %s is pointer to interface, not interface", T)
+ } else {
+ detail = check.sprintf("%s is not an interface", T)
+ }
+ *cause = check.sprintf("%s does not %s %s (%s)", V, verb, T, detail)
+ }
+ return false
+ }
+
+ // Every type satisfies the empty interface.
+ if Ti.Empty() {
+ return true
+ }
+ // T is not the empty interface (i.e., the type set of T is restricted)
+
+ // An interface V with an empty type set satisfies any interface.
+ // (The empty set is a subset of any set.)
+ Vi, _ := Vu.(*Interface)
+ if Vi != nil && Vi.typeSet().IsEmpty() {
+ return true
+ }
+ // type set of V is not empty
+
+ // No type with non-empty type set satisfies the empty type set.
+ if Ti.typeSet().IsEmpty() {
+ if cause != nil {
+ *cause = check.sprintf("cannot %s %s (empty type set)", verb, T)
+ }
+ return false
+ }
+
+ // V must implement T's methods, if any.
+ if m, _ := check.missingMethod(V, T, true, Identical, cause); m != nil /* !Implements(V, T) */ {
+ if cause != nil {
+ *cause = check.sprintf("%s does not %s %s %s", V, verb, T, *cause)
+ }
+ return false
+ }
+
+ // Only check comparability if we don't have a more specific error.
+ checkComparability := func() bool {
+ if !Ti.IsComparable() {
+ return true
+ }
+ // If T is comparable, V must be comparable.
+ // If V is strictly comparable, we're done.
+ if comparable(V, false /* strict comparability */, nil, nil) {
+ return true
+ }
+ // For constraint satisfaction, use dynamic (spec) comparability
+ // so that ordinary, non-type parameter interfaces implement comparable.
+ if constraint && comparable(V, true /* spec comparability */, nil, nil) {
+ // V is comparable if we are at Go 1.20 or higher.
+ if check == nil || check.allowVersion(check.pkg, atPos(pos), go1_20) { // atPos needed so that go/types generate passes
+ return true
+ }
+ if cause != nil {
+ *cause = check.sprintf("%s to %s comparable requires go1.20 or later", V, verb)
+ }
+ return false
+ }
+ if cause != nil {
+ *cause = check.sprintf("%s does not %s comparable", V, verb)
+ }
+ return false
+ }
+
+ // V must also be in the set of types of T, if any.
+ // Constraints with empty type sets were already excluded above.
+ if !Ti.typeSet().hasTerms() {
+ return checkComparability() // nothing to do
+ }
+
+ // If V is itself an interface, each of its possible types must be in the set
+ // of T types (i.e., the V type set must be a subset of the T type set).
+ // Interfaces V with empty type sets were already excluded above.
+ if Vi != nil {
+ if !Vi.typeSet().subsetOf(Ti.typeSet()) {
+ // TODO(gri) report which type is missing
+ if cause != nil {
+ *cause = check.sprintf("%s does not %s %s", V, verb, T)
+ }
+ return false
+ }
+ return checkComparability()
+ }
+
+ // Otherwise, V's type must be included in the iface type set.
+ var alt Type
+ if Ti.typeSet().is(func(t *term) bool {
+ if !t.includes(V) {
+ // If V ∉ t.typ but V ∈ ~t.typ then remember this type
+ // so we can suggest it as an alternative in the error
+ // message.
+ if alt == nil && !t.tilde && Identical(t.typ, under(t.typ)) {
+ tt := *t
+ tt.tilde = true
+ if tt.includes(V) {
+ alt = t.typ
+ }
+ }
+ return true
+ }
+ return false
+ }) {
+ if cause != nil {
+ var detail string
+ switch {
+ case alt != nil:
+ detail = check.sprintf("possibly missing ~ for %s in %s", alt, T)
+ case mentions(Ti, V):
+ detail = check.sprintf("%s mentions %s, but %s is not in the type set of %s", T, V, V, T)
+ default:
+ detail = check.sprintf("%s missing in %s", V, Ti.typeSet().terms)
+ }
+ *cause = check.sprintf("%s does not %s %s (%s)", V, verb, T, detail)
+ }
+ return false
+ }
+
+ return checkComparability()
+}
+
+// mentions reports whether type T "mentions" typ in an (embedded) element or term
+// of T (whether typ is in the type set of T or not). For better error messages.
+func mentions(T, typ Type) bool {
+ switch T := T.(type) {
+ case *Interface:
+ for _, e := range T.embeddeds {
+ if mentions(e, typ) {
+ return true
+ }
+ }
+ case *Union:
+ for _, t := range T.terms {
+ if mentions(t.typ, typ) {
+ return true
+ }
+ }
+ default:
+ if Identical(T, typ) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/contrib/go/_std_1.21/src/go/types/interface.go b/contrib/go/_std_1.21/src/go/types/interface.go
new file mode 100644
index 0000000000..f2bb15e84b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/interface.go
@@ -0,0 +1,233 @@
+// 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 types
+
+import (
+ "go/ast"
+ "go/token"
+ . "internal/types/errors"
+)
+
+// ----------------------------------------------------------------------------
+// API
+
+// An Interface represents an interface type.
+type Interface struct {
+ check *Checker // for error reporting; nil once type set is computed
+ methods []*Func // ordered list of explicitly declared methods
+ embeddeds []Type // ordered list of explicitly embedded elements
+ embedPos *[]token.Pos // positions of embedded elements; or nil (for error messages) - use pointer to save space
+ implicit bool // interface is wrapper for type set literal (non-interface T, ~T, or A|B)
+ complete bool // indicates that obj, methods, and embeddeds are set and type set can be computed
+
+ tset *_TypeSet // type set described by this interface, computed lazily
+}
+
+// typeSet returns the type set for interface t.
+func (t *Interface) typeSet() *_TypeSet { return computeInterfaceTypeSet(t.check, nopos, t) }
+
+// emptyInterface represents the empty (completed) interface
+var emptyInterface = Interface{complete: true, tset: &topTypeSet}
+
+// NewInterface returns a new interface for the given methods and embedded types.
+// NewInterface takes ownership of the provided methods and may modify their types
+// by setting missing receivers.
+//
+// Deprecated: Use NewInterfaceType instead which allows arbitrary embedded types.
+func NewInterface(methods []*Func, embeddeds []*Named) *Interface {
+ tnames := make([]Type, len(embeddeds))
+ for i, t := range embeddeds {
+ tnames[i] = t
+ }
+ return NewInterfaceType(methods, tnames)
+}
+
+// NewInterfaceType returns a new interface for the given methods and embedded
+// types. NewInterfaceType takes ownership of the provided methods and may
+// modify their types by setting missing receivers.
+//
+// To avoid race conditions, the interface's type set should be computed before
+// concurrent use of the interface, by explicitly calling Complete.
+func NewInterfaceType(methods []*Func, embeddeds []Type) *Interface {
+ if len(methods) == 0 && len(embeddeds) == 0 {
+ return &emptyInterface
+ }
+
+ // set method receivers if necessary
+ typ := (*Checker)(nil).newInterface()
+ for _, m := range methods {
+ if sig := m.typ.(*Signature); sig.recv == nil {
+ sig.recv = NewVar(m.pos, m.pkg, "", typ)
+ }
+ }
+
+ // sort for API stability
+ sortMethods(methods)
+
+ typ.methods = methods
+ typ.embeddeds = embeddeds
+ typ.complete = true
+
+ return typ
+}
+
+// check may be nil
+func (check *Checker) newInterface() *Interface {
+ typ := &Interface{check: check}
+ if check != nil {
+ check.needsCleanup(typ)
+ }
+ return typ
+}
+
+// MarkImplicit marks the interface t as implicit, meaning this interface
+// corresponds to a constraint literal such as ~T or A|B without explicit
+// interface embedding. MarkImplicit should be called before any concurrent use
+// of implicit interfaces.
+func (t *Interface) MarkImplicit() {
+ t.implicit = true
+}
+
+// NumExplicitMethods returns the number of explicitly declared methods of interface t.
+func (t *Interface) NumExplicitMethods() int { return len(t.methods) }
+
+// ExplicitMethod returns the i'th explicitly declared method of interface t for 0 <= i < t.NumExplicitMethods().
+// The methods are ordered by their unique Id.
+func (t *Interface) ExplicitMethod(i int) *Func { return t.methods[i] }
+
+// NumEmbeddeds returns the number of embedded types in interface t.
+func (t *Interface) NumEmbeddeds() int { return len(t.embeddeds) }
+
+// Embedded returns the i'th embedded defined (*Named) type of interface t for 0 <= i < t.NumEmbeddeds().
+// The result is nil if the i'th embedded type is not a defined type.
+//
+// Deprecated: Use EmbeddedType which is not restricted to defined (*Named) types.
+func (t *Interface) Embedded(i int) *Named { tname, _ := t.embeddeds[i].(*Named); return tname }
+
+// EmbeddedType returns the i'th embedded type of interface t for 0 <= i < t.NumEmbeddeds().
+func (t *Interface) EmbeddedType(i int) Type { return t.embeddeds[i] }
+
+// NumMethods returns the total number of methods of interface t.
+func (t *Interface) NumMethods() int { return t.typeSet().NumMethods() }
+
+// Method returns the i'th method of interface t for 0 <= i < t.NumMethods().
+// The methods are ordered by their unique Id.
+func (t *Interface) Method(i int) *Func { return t.typeSet().Method(i) }
+
+// Empty reports whether t is the empty interface.
+func (t *Interface) Empty() bool { return t.typeSet().IsAll() }
+
+// IsComparable reports whether each type in interface t's type set is comparable.
+func (t *Interface) IsComparable() bool { return t.typeSet().IsComparable(nil) }
+
+// IsMethodSet reports whether the interface t is fully described by its method
+// set.
+func (t *Interface) IsMethodSet() bool { return t.typeSet().IsMethodSet() }
+
+// IsImplicit reports whether the interface t is a wrapper for a type set literal.
+func (t *Interface) IsImplicit() bool { return t.implicit }
+
+// Complete computes the interface's type set. It must be called by users of
+// NewInterfaceType and NewInterface after the interface's embedded types are
+// fully defined and before using the interface type in any way other than to
+// form other types. The interface must not contain duplicate methods or a
+// panic occurs. Complete returns the receiver.
+//
+// Interface types that have been completed are safe for concurrent use.
+func (t *Interface) Complete() *Interface {
+ if !t.complete {
+ t.complete = true
+ }
+ t.typeSet() // checks if t.tset is already set
+ return t
+}
+
+func (t *Interface) Underlying() Type { return t }
+func (t *Interface) String() string { return TypeString(t, nil) }
+
+// ----------------------------------------------------------------------------
+// Implementation
+
+func (t *Interface) cleanup() {
+ t.check = nil
+ t.embedPos = nil
+}
+
+func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, def *Named) {
+ addEmbedded := func(pos token.Pos, typ Type) {
+ ityp.embeddeds = append(ityp.embeddeds, typ)
+ if ityp.embedPos == nil {
+ ityp.embedPos = new([]token.Pos)
+ }
+ *ityp.embedPos = append(*ityp.embedPos, pos)
+ }
+
+ for _, f := range iface.Methods.List {
+ if len(f.Names) == 0 {
+ addEmbedded(f.Type.Pos(), parseUnion(check, f.Type))
+ continue
+ }
+ // f.Name != nil
+
+ // We have a method with name f.Names[0].
+ name := f.Names[0]
+ if name.Name == "_" {
+ check.error(name, BlankIfaceMethod, "methods must have a unique non-blank name")
+ continue // ignore
+ }
+
+ typ := check.typ(f.Type)
+ sig, _ := typ.(*Signature)
+ if sig == nil {
+ if typ != Typ[Invalid] {
+ check.errorf(f.Type, InvalidSyntaxTree, "%s is not a method signature", typ)
+ }
+ continue // ignore
+ }
+
+ // Always type-check method type parameters but complain if they are not enabled.
+ // (This extra check is needed here because interface method signatures don't have
+ // a receiver specification.)
+ if sig.tparams != nil {
+ var at positioner = f.Type
+ if ftyp, _ := f.Type.(*ast.FuncType); ftyp != nil && ftyp.TypeParams != nil {
+ at = ftyp.TypeParams
+ }
+ check.error(at, InvalidMethodTypeParams, "methods cannot have type parameters")
+ }
+
+ // use named receiver type if available (for better error messages)
+ var recvTyp Type = ityp
+ if def != nil {
+ recvTyp = def
+ }
+ sig.recv = NewVar(name.Pos(), check.pkg, "", recvTyp)
+
+ m := NewFunc(name.Pos(), check.pkg, name.Name, sig)
+ check.recordDef(name, m)
+ ityp.methods = append(ityp.methods, m)
+ }
+
+ // All methods and embedded elements for this interface are collected;
+ // i.e., this interface may be used in a type set computation.
+ ityp.complete = true
+
+ if len(ityp.methods) == 0 && len(ityp.embeddeds) == 0 {
+ // empty interface
+ ityp.tset = &topTypeSet
+ return
+ }
+
+ // sort for API stability
+ sortMethods(ityp.methods)
+ // (don't sort embeddeds: they must correspond to *embedPos entries)
+
+ // Compute type set as soon as possible to report any errors.
+ // Subsequent uses of type sets will use this computed type
+ // set and won't need to pass in a *Checker.
+ check.later(func() {
+ computeInterfaceTypeSet(check, iface.Pos(), ityp)
+ }).describef(iface, "compute type set for %s", ityp)
+}
diff --git a/contrib/go/_std_1.20/src/go/types/labels.go b/contrib/go/_std_1.21/src/go/types/labels.go
index 5ee941e369..5ee941e369 100644
--- a/contrib/go/_std_1.20/src/go/types/labels.go
+++ b/contrib/go/_std_1.21/src/go/types/labels.go
diff --git a/contrib/go/_std_1.21/src/go/types/lookup.go b/contrib/go/_std_1.21/src/go/types/lookup.go
new file mode 100644
index 0000000000..d96dd86e5e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/lookup.go
@@ -0,0 +1,587 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2013 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.
+
+// This file implements various field and method lookup functions.
+
+package types
+
+import (
+ "bytes"
+ "go/token"
+ "strings"
+)
+
+// Internal use of LookupFieldOrMethod: If the obj result is a method
+// associated with a concrete (non-interface) type, the method's signature
+// may not be fully set up. Call Checker.objDecl(obj, nil) before accessing
+// the method's type.
+
+// LookupFieldOrMethod looks up a field or method with given package and name
+// in T and returns the corresponding *Var or *Func, an index sequence, and a
+// bool indicating if there were any pointer indirections on the path to the
+// field or method. If addressable is set, T is the type of an addressable
+// variable (only matters for method lookups). T must not be nil.
+//
+// The last index entry is the field or method index in the (possibly embedded)
+// type where the entry was found, either:
+//
+// 1. the list of declared methods of a named type; or
+// 2. the list of all methods (method set) of an interface type; or
+// 3. the list of fields of a struct type.
+//
+// The earlier index entries are the indices of the embedded struct fields
+// traversed to get to the found entry, starting at depth 0.
+//
+// If no entry is found, a nil object is returned. In this case, the returned
+// index and indirect values have the following meaning:
+//
+// - If index != nil, the index sequence points to an ambiguous entry
+// (the same name appeared more than once at the same embedding level).
+//
+// - If indirect is set, a method with a pointer receiver type was found
+// but there was no pointer on the path from the actual receiver type to
+// the method's formal receiver base type, nor was the receiver addressable.
+func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
+ if T == nil {
+ panic("LookupFieldOrMethod on nil type")
+ }
+
+ // Methods cannot be associated to a named pointer type.
+ // (spec: "The type denoted by T is called the receiver base type;
+ // it must not be a pointer or interface type and it must be declared
+ // in the same package as the method.").
+ // Thus, if we have a named pointer type, proceed with the underlying
+ // pointer type but discard the result if it is a method since we would
+ // not have found it for T (see also go.dev/issue/8590).
+ if t, _ := T.(*Named); t != nil {
+ if p, _ := t.Underlying().(*Pointer); p != nil {
+ obj, index, indirect = lookupFieldOrMethodImpl(p, false, pkg, name, false)
+ if _, ok := obj.(*Func); ok {
+ return nil, nil, false
+ }
+ return
+ }
+ }
+
+ obj, index, indirect = lookupFieldOrMethodImpl(T, addressable, pkg, name, false)
+
+ // If we didn't find anything and if we have a type parameter with a core type,
+ // see if there is a matching field (but not a method, those need to be declared
+ // explicitly in the constraint). If the constraint is a named pointer type (see
+ // above), we are ok here because only fields are accepted as results.
+ const enableTParamFieldLookup = false // see go.dev/issue/51576
+ if enableTParamFieldLookup && obj == nil && isTypeParam(T) {
+ if t := coreType(T); t != nil {
+ obj, index, indirect = lookupFieldOrMethodImpl(t, addressable, pkg, name, false)
+ if _, ok := obj.(*Var); !ok {
+ obj, index, indirect = nil, nil, false // accept fields (variables) only
+ }
+ }
+ }
+ return
+}
+
+// lookupFieldOrMethodImpl is the implementation of LookupFieldOrMethod.
+// Notably, in contrast to LookupFieldOrMethod, it won't find struct fields
+// in base types of defined (*Named) pointer types T. For instance, given
+// the declaration:
+//
+// type T *struct{f int}
+//
+// lookupFieldOrMethodImpl won't find the field f in the defined (*Named) type T
+// (methods on T are not permitted in the first place).
+//
+// Thus, lookupFieldOrMethodImpl should only be called by LookupFieldOrMethod
+// and missingMethod (the latter doesn't care about struct fields).
+//
+// If foldCase is true, method names are considered equal if they are equal
+// with case folding.
+//
+// The resulting object may not be fully type-checked.
+func lookupFieldOrMethodImpl(T Type, addressable bool, pkg *Package, name string, foldCase bool) (obj Object, index []int, indirect bool) {
+ // WARNING: The code in this function is extremely subtle - do not modify casually!
+
+ if name == "_" {
+ return // blank fields/methods are never found
+ }
+
+ // Importantly, we must not call under before the call to deref below (nor
+ // does deref call under), as doing so could incorrectly result in finding
+ // methods of the pointer base type when T is a (*Named) pointer type.
+ typ, isPtr := deref(T)
+
+ // *typ where typ is an interface (incl. a type parameter) has no methods.
+ if isPtr {
+ if _, ok := under(typ).(*Interface); ok {
+ return
+ }
+ }
+
+ // Start with typ as single entry at shallowest depth.
+ current := []embeddedType{{typ, nil, isPtr, false}}
+
+ // seen tracks named types that we have seen already, allocated lazily.
+ // Used to avoid endless searches in case of recursive types.
+ //
+ // We must use a lookup on identity rather than a simple map[*Named]bool as
+ // instantiated types may be identical but not equal.
+ var seen instanceLookup
+
+ // search current depth
+ for len(current) > 0 {
+ var next []embeddedType // embedded types found at current depth
+
+ // look for (pkg, name) in all types at current depth
+ for _, e := range current {
+ typ := e.typ
+
+ // If we have a named type, we may have associated methods.
+ // Look for those first.
+ if named, _ := typ.(*Named); named != nil {
+ if alt := seen.lookup(named); alt != nil {
+ // We have seen this type before, at a more shallow depth
+ // (note that multiples of this type at the current depth
+ // were consolidated before). The type at that depth shadows
+ // this same type at the current depth, so we can ignore
+ // this one.
+ continue
+ }
+ seen.add(named)
+
+ // look for a matching attached method
+ if i, m := named.lookupMethod(pkg, name, foldCase); m != nil {
+ // potential match
+ // caution: method may not have a proper signature yet
+ index = concat(e.index, i)
+ if obj != nil || e.multiples {
+ return nil, index, false // collision
+ }
+ obj = m
+ indirect = e.indirect
+ continue // we can't have a matching field or interface method
+ }
+ }
+
+ switch t := under(typ).(type) {
+ case *Struct:
+ // look for a matching field and collect embedded types
+ for i, f := range t.fields {
+ if f.sameId(pkg, name) {
+ assert(f.typ != nil)
+ index = concat(e.index, i)
+ if obj != nil || e.multiples {
+ return nil, index, false // collision
+ }
+ obj = f
+ indirect = e.indirect
+ continue // we can't have a matching interface method
+ }
+ // Collect embedded struct fields for searching the next
+ // lower depth, but only if we have not seen a match yet
+ // (if we have a match it is either the desired field or
+ // we have a name collision on the same depth; in either
+ // case we don't need to look further).
+ // Embedded fields are always of the form T or *T where
+ // T is a type name. If e.typ appeared multiple times at
+ // this depth, f.typ appears multiple times at the next
+ // depth.
+ if obj == nil && f.embedded {
+ typ, isPtr := deref(f.typ)
+ // TODO(gri) optimization: ignore types that can't
+ // have fields or methods (only Named, Struct, and
+ // Interface types need to be considered).
+ next = append(next, embeddedType{typ, concat(e.index, i), e.indirect || isPtr, e.multiples})
+ }
+ }
+
+ case *Interface:
+ // look for a matching method (interface may be a type parameter)
+ if i, m := t.typeSet().LookupMethod(pkg, name, foldCase); m != nil {
+ assert(m.typ != nil)
+ index = concat(e.index, i)
+ if obj != nil || e.multiples {
+ return nil, index, false // collision
+ }
+ obj = m
+ indirect = e.indirect
+ }
+ }
+ }
+
+ if obj != nil {
+ // found a potential match
+ // spec: "A method call x.m() is valid if the method set of (the type of) x
+ // contains m and the argument list can be assigned to the parameter
+ // list of m. If x is addressable and &x's method set contains m, x.m()
+ // is shorthand for (&x).m()".
+ if f, _ := obj.(*Func); f != nil {
+ // determine if method has a pointer receiver
+ if f.hasPtrRecv() && !indirect && !addressable {
+ return nil, nil, true // pointer/addressable receiver required
+ }
+ }
+ return
+ }
+
+ current = consolidateMultiples(next)
+ }
+
+ return nil, nil, false // not found
+}
+
+// embeddedType represents an embedded type
+type embeddedType struct {
+ typ Type
+ index []int // embedded field indices, starting with index at depth 0
+ indirect bool // if set, there was a pointer indirection on the path to this field
+ multiples bool // if set, typ appears multiple times at this depth
+}
+
+// consolidateMultiples collects multiple list entries with the same type
+// into a single entry marked as containing multiples. The result is the
+// consolidated list.
+func consolidateMultiples(list []embeddedType) []embeddedType {
+ if len(list) <= 1 {
+ return list // at most one entry - nothing to do
+ }
+
+ n := 0 // number of entries w/ unique type
+ prev := make(map[Type]int) // index at which type was previously seen
+ for _, e := range list {
+ if i, found := lookupType(prev, e.typ); found {
+ list[i].multiples = true
+ // ignore this entry
+ } else {
+ prev[e.typ] = n
+ list[n] = e
+ n++
+ }
+ }
+ return list[:n]
+}
+
+func lookupType(m map[Type]int, typ Type) (int, bool) {
+ // fast path: maybe the types are equal
+ if i, found := m[typ]; found {
+ return i, true
+ }
+
+ for t, i := range m {
+ if Identical(t, typ) {
+ return i, true
+ }
+ }
+
+ return 0, false
+}
+
+type instanceLookup struct {
+ // buf is used to avoid allocating the map m in the common case of a small
+ // number of instances.
+ buf [3]*Named
+ m map[*Named][]*Named
+}
+
+func (l *instanceLookup) lookup(inst *Named) *Named {
+ for _, t := range l.buf {
+ if t != nil && Identical(inst, t) {
+ return t
+ }
+ }
+ for _, t := range l.m[inst.Origin()] {
+ if Identical(inst, t) {
+ return t
+ }
+ }
+ return nil
+}
+
+func (l *instanceLookup) add(inst *Named) {
+ for i, t := range l.buf {
+ if t == nil {
+ l.buf[i] = inst
+ return
+ }
+ }
+ if l.m == nil {
+ l.m = make(map[*Named][]*Named)
+ }
+ insts := l.m[inst.Origin()]
+ l.m[inst.Origin()] = append(insts, inst)
+}
+
+// MissingMethod returns (nil, false) if V implements T, otherwise it
+// returns a missing method required by T and whether it is missing or
+// just has the wrong type: either a pointer receiver or wrong signature.
+//
+// For non-interface types V, or if static is set, V implements T if all
+// methods of T are present in V. Otherwise (V is an interface and static
+// is not set), MissingMethod only checks that methods of T which are also
+// present in V have matching types (e.g., for a type assertion x.(T) where
+// x is of interface type V).
+func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) {
+ return (*Checker)(nil).missingMethod(V, T, static, Identical, nil)
+}
+
+// missingMethod is like MissingMethod but accepts a *Checker as receiver,
+// a comparator equivalent for type comparison, and a *string for error causes.
+// The receiver may be nil if missingMethod is invoked through an exported
+// API call (such as MissingMethod), i.e., when all methods have been type-
+// checked.
+// The underlying type of T must be an interface; T (rather than its under-
+// lying type) is used for better error messages (reported through *cause).
+// The comparator is used to compare signatures.
+// If a method is missing and cause is not nil, *cause describes the error.
+func (check *Checker) missingMethod(V, T Type, static bool, equivalent func(x, y Type) bool, cause *string) (method *Func, wrongType bool) {
+ methods := under(T).(*Interface).typeSet().methods // T must be an interface
+ if len(methods) == 0 {
+ return nil, false
+ }
+
+ const (
+ ok = iota
+ notFound
+ wrongName
+ wrongSig
+ ambigSel
+ ptrRecv
+ field
+ )
+
+ state := ok
+ var m *Func // method on T we're trying to implement
+ var f *Func // method on V, if found (state is one of ok, wrongName, wrongSig)
+
+ if u, _ := under(V).(*Interface); u != nil {
+ tset := u.typeSet()
+ for _, m = range methods {
+ _, f = tset.LookupMethod(m.pkg, m.name, false)
+
+ if f == nil {
+ if !static {
+ continue
+ }
+ state = notFound
+ break
+ }
+
+ if !equivalent(f.typ, m.typ) {
+ state = wrongSig
+ break
+ }
+ }
+ } else {
+ for _, m = range methods {
+ obj, index, indirect := lookupFieldOrMethodImpl(V, false, m.pkg, m.name, false)
+
+ // check if m is ambiguous, on *V, or on V with case-folding
+ if obj == nil {
+ switch {
+ case index != nil:
+ state = ambigSel
+ case indirect:
+ state = ptrRecv
+ default:
+ state = notFound
+ obj, _, _ = lookupFieldOrMethodImpl(V, false, m.pkg, m.name, true /* fold case */)
+ f, _ = obj.(*Func)
+ if f != nil {
+ state = wrongName
+ }
+ }
+ break
+ }
+
+ // we must have a method (not a struct field)
+ f, _ = obj.(*Func)
+ if f == nil {
+ state = field
+ break
+ }
+
+ // methods may not have a fully set up signature yet
+ if check != nil {
+ check.objDecl(f, nil)
+ }
+
+ if !equivalent(f.typ, m.typ) {
+ state = wrongSig
+ break
+ }
+ }
+ }
+
+ if state == ok {
+ return nil, false
+ }
+
+ if cause != nil {
+ if f != nil {
+ // This method may be formatted in funcString below, so must have a fully
+ // set up signature.
+ if check != nil {
+ check.objDecl(f, nil)
+ }
+ }
+ switch state {
+ case notFound:
+ switch {
+ case isInterfacePtr(V):
+ *cause = "(" + check.interfacePtrError(V) + ")"
+ case isInterfacePtr(T):
+ *cause = "(" + check.interfacePtrError(T) + ")"
+ default:
+ *cause = check.sprintf("(missing method %s)", m.Name())
+ }
+ case wrongName:
+ fs, ms := check.funcString(f, false), check.funcString(m, false)
+ *cause = check.sprintf("(missing method %s)\n\t\thave %s\n\t\twant %s",
+ m.Name(), fs, ms)
+ case wrongSig:
+ fs, ms := check.funcString(f, false), check.funcString(m, false)
+ if fs == ms {
+ // Don't report "want Foo, have Foo".
+ // Add package information to disambiguate (go.dev/issue/54258).
+ fs, ms = check.funcString(f, true), check.funcString(m, true)
+ }
+ *cause = check.sprintf("(wrong type for method %s)\n\t\thave %s\n\t\twant %s",
+ m.Name(), fs, ms)
+ case ambigSel:
+ *cause = check.sprintf("(ambiguous selector %s.%s)", V, m.Name())
+ case ptrRecv:
+ *cause = check.sprintf("(method %s has pointer receiver)", m.Name())
+ case field:
+ *cause = check.sprintf("(%s.%s is a field, not a method)", V, m.Name())
+ default:
+ unreachable()
+ }
+ }
+
+ return m, state == wrongSig || state == ptrRecv
+}
+
+func isInterfacePtr(T Type) bool {
+ p, _ := under(T).(*Pointer)
+ return p != nil && IsInterface(p.base)
+}
+
+// check may be nil.
+func (check *Checker) interfacePtrError(T Type) string {
+ assert(isInterfacePtr(T))
+ if p, _ := under(T).(*Pointer); isTypeParam(p.base) {
+ return check.sprintf("type %s is pointer to type parameter, not type parameter", T)
+ }
+ return check.sprintf("type %s is pointer to interface, not interface", T)
+}
+
+// funcString returns a string of the form name + signature for f.
+// check may be nil.
+func (check *Checker) funcString(f *Func, pkgInfo bool) string {
+ buf := bytes.NewBufferString(f.name)
+ var qf Qualifier
+ if check != nil && !pkgInfo {
+ qf = check.qualifier
+ }
+ w := newTypeWriter(buf, qf)
+ w.pkgInfo = pkgInfo
+ w.paramNames = false
+ w.signature(f.typ.(*Signature))
+ return buf.String()
+}
+
+// assertableTo reports whether a value of type V can be asserted to have type T.
+// The receiver may be nil if assertableTo is invoked through an exported API call
+// (such as AssertableTo), i.e., when all methods have been type-checked.
+// The underlying type of V must be an interface.
+// If the result is false and cause is not nil, *cause describes the error.
+// TODO(gri) replace calls to this function with calls to newAssertableTo.
+func (check *Checker) assertableTo(V, T Type, cause *string) bool {
+ // no static check is required if T is an interface
+ // spec: "If T is an interface type, x.(T) asserts that the
+ // dynamic type of x implements the interface T."
+ if IsInterface(T) {
+ return true
+ }
+ // TODO(gri) fix this for generalized interfaces
+ m, _ := check.missingMethod(T, V, false, Identical, cause)
+ return m == nil
+}
+
+// newAssertableTo reports whether a value of type V can be asserted to have type T.
+// It also implements behavior for interfaces that currently are only permitted
+// in constraint position (we have not yet defined that behavior in the spec).
+// The underlying type of V must be an interface.
+// If the result is false and cause is not nil, *cause is set to the error cause.
+func (check *Checker) newAssertableTo(pos token.Pos, V, T Type, cause *string) bool {
+ // no static check is required if T is an interface
+ // spec: "If T is an interface type, x.(T) asserts that the
+ // dynamic type of x implements the interface T."
+ if IsInterface(T) {
+ return true
+ }
+ return check.implements(pos, T, V, false, cause)
+}
+
+// deref dereferences typ if it is a *Pointer (but not a *Named type
+// with an underlying pointer type!) and returns its base and true.
+// Otherwise it returns (typ, false).
+func deref(typ Type) (Type, bool) {
+ if p, _ := typ.(*Pointer); p != nil {
+ // p.base should never be nil, but be conservative
+ if p.base == nil {
+ if debug {
+ panic("pointer with nil base type (possibly due to an invalid cyclic declaration)")
+ }
+ return Typ[Invalid], true
+ }
+ return p.base, true
+ }
+ return typ, false
+}
+
+// derefStructPtr dereferences typ if it is a (named or unnamed) pointer to a
+// (named or unnamed) struct and returns its base. Otherwise it returns typ.
+func derefStructPtr(typ Type) Type {
+ if p, _ := under(typ).(*Pointer); p != nil {
+ if _, ok := under(p.base).(*Struct); ok {
+ return p.base
+ }
+ }
+ return typ
+}
+
+// concat returns the result of concatenating list and i.
+// The result does not share its underlying array with list.
+func concat(list []int, i int) []int {
+ var t []int
+ t = append(t, list...)
+ return append(t, i)
+}
+
+// fieldIndex returns the index for the field with matching package and name, or a value < 0.
+func fieldIndex(fields []*Var, pkg *Package, name string) int {
+ if name != "_" {
+ for i, f := range fields {
+ if f.sameId(pkg, name) {
+ return i
+ }
+ }
+ }
+ return -1
+}
+
+// lookupMethod returns the index of and method with matching package and name, or (-1, nil).
+// If foldCase is true, method names are considered equal if they are equal with case folding.
+func lookupMethod(methods []*Func, pkg *Package, name string, foldCase bool) (int, *Func) {
+ if name != "_" {
+ for i, m := range methods {
+ if (m.name == name || foldCase && strings.EqualFold(m.name, name)) && m.sameId(pkg, m.name) {
+ return i, m
+ }
+ }
+ }
+ return -1, nil
+}
diff --git a/contrib/go/_std_1.21/src/go/types/map.go b/contrib/go/_std_1.21/src/go/types/map.go
new file mode 100644
index 0000000000..febb0d3a0b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/map.go
@@ -0,0 +1,26 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2011 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 types
+
+// A Map represents a map type.
+type Map struct {
+ key, elem Type
+}
+
+// NewMap returns a new map for the given key and element types.
+func NewMap(key, elem Type) *Map {
+ return &Map{key: key, elem: elem}
+}
+
+// Key returns the key type of map m.
+func (m *Map) Key() Type { return m.key }
+
+// Elem returns the element type of map m.
+func (m *Map) Elem() Type { return m.elem }
+
+func (t *Map) Underlying() Type { return t }
+func (t *Map) String() string { return TypeString(t, nil) }
diff --git a/contrib/go/_std_1.21/src/go/types/methodset.go b/contrib/go/_std_1.21/src/go/types/methodset.go
new file mode 100644
index 0000000000..0d9d9b4817
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/methodset.go
@@ -0,0 +1,246 @@
+// Copyright 2013 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.
+
+// This file implements method sets.
+
+package types
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+)
+
+// A MethodSet is an ordered set of concrete or abstract (interface) methods;
+// a method is a MethodVal selection, and they are ordered by ascending m.Obj().Id().
+// The zero value for a MethodSet is a ready-to-use empty method set.
+type MethodSet struct {
+ list []*Selection
+}
+
+func (s *MethodSet) String() string {
+ if s.Len() == 0 {
+ return "MethodSet {}"
+ }
+
+ var buf strings.Builder
+ fmt.Fprintln(&buf, "MethodSet {")
+ for _, f := range s.list {
+ fmt.Fprintf(&buf, "\t%s\n", f)
+ }
+ fmt.Fprintln(&buf, "}")
+ return buf.String()
+}
+
+// Len returns the number of methods in s.
+func (s *MethodSet) Len() int { return len(s.list) }
+
+// At returns the i'th method in s for 0 <= i < s.Len().
+func (s *MethodSet) At(i int) *Selection { return s.list[i] }
+
+// Lookup returns the method with matching package and name, or nil if not found.
+func (s *MethodSet) Lookup(pkg *Package, name string) *Selection {
+ if s.Len() == 0 {
+ return nil
+ }
+
+ key := Id(pkg, name)
+ i := sort.Search(len(s.list), func(i int) bool {
+ m := s.list[i]
+ return m.obj.Id() >= key
+ })
+ if i < len(s.list) {
+ m := s.list[i]
+ if m.obj.Id() == key {
+ return m
+ }
+ }
+ return nil
+}
+
+// Shared empty method set.
+var emptyMethodSet MethodSet
+
+// Note: NewMethodSet is intended for external use only as it
+// requires interfaces to be complete. It may be used
+// internally if LookupFieldOrMethod completed the same
+// interfaces beforehand.
+
+// NewMethodSet returns the method set for the given type T.
+// It always returns a non-nil method set, even if it is empty.
+func NewMethodSet(T Type) *MethodSet {
+ // WARNING: The code in this function is extremely subtle - do not modify casually!
+ // This function and lookupFieldOrMethod should be kept in sync.
+
+ // TODO(rfindley) confirm that this code is in sync with lookupFieldOrMethod
+ // with respect to type params.
+
+ // Methods cannot be associated with a named pointer type.
+ // (spec: "The type denoted by T is called the receiver base type;
+ // it must not be a pointer or interface type and it must be declared
+ // in the same package as the method.").
+ if t, _ := T.(*Named); t != nil && isPointer(t) {
+ return &emptyMethodSet
+ }
+
+ // method set up to the current depth, allocated lazily
+ var base methodSet
+
+ typ, isPtr := deref(T)
+
+ // *typ where typ is an interface has no methods.
+ if isPtr && IsInterface(typ) {
+ return &emptyMethodSet
+ }
+
+ // Start with typ as single entry at shallowest depth.
+ current := []embeddedType{{typ, nil, isPtr, false}}
+
+ // seen tracks named types that we have seen already, allocated lazily.
+ // Used to avoid endless searches in case of recursive types.
+ //
+ // We must use a lookup on identity rather than a simple map[*Named]bool as
+ // instantiated types may be identical but not equal.
+ var seen instanceLookup
+
+ // collect methods at current depth
+ for len(current) > 0 {
+ var next []embeddedType // embedded types found at current depth
+
+ // field and method sets at current depth, indexed by names (Id's), and allocated lazily
+ var fset map[string]bool // we only care about the field names
+ var mset methodSet
+
+ for _, e := range current {
+ typ := e.typ
+
+ // If we have a named type, we may have associated methods.
+ // Look for those first.
+ if named, _ := typ.(*Named); named != nil {
+ if alt := seen.lookup(named); alt != nil {
+ // We have seen this type before, at a more shallow depth
+ // (note that multiples of this type at the current depth
+ // were consolidated before). The type at that depth shadows
+ // this same type at the current depth, so we can ignore
+ // this one.
+ continue
+ }
+ seen.add(named)
+
+ for i := 0; i < named.NumMethods(); i++ {
+ mset = mset.addOne(named.Method(i), concat(e.index, i), e.indirect, e.multiples)
+ }
+ }
+
+ switch t := under(typ).(type) {
+ case *Struct:
+ for i, f := range t.fields {
+ if fset == nil {
+ fset = make(map[string]bool)
+ }
+ fset[f.Id()] = true
+
+ // Embedded fields are always of the form T or *T where
+ // T is a type name. If typ appeared multiple times at
+ // this depth, f.Type appears multiple times at the next
+ // depth.
+ if f.embedded {
+ typ, isPtr := deref(f.typ)
+ // TODO(gri) optimization: ignore types that can't
+ // have fields or methods (only Named, Struct, and
+ // Interface types need to be considered).
+ next = append(next, embeddedType{typ, concat(e.index, i), e.indirect || isPtr, e.multiples})
+ }
+ }
+
+ case *Interface:
+ mset = mset.add(t.typeSet().methods, e.index, true, e.multiples)
+ }
+ }
+
+ // Add methods and collisions at this depth to base if no entries with matching
+ // names exist already.
+ for k, m := range mset {
+ if _, found := base[k]; !found {
+ // Fields collide with methods of the same name at this depth.
+ if fset[k] {
+ m = nil // collision
+ }
+ if base == nil {
+ base = make(methodSet)
+ }
+ base[k] = m
+ }
+ }
+
+ // Add all (remaining) fields at this depth as collisions (since they will
+ // hide any method further down) if no entries with matching names exist already.
+ for k := range fset {
+ if _, found := base[k]; !found {
+ if base == nil {
+ base = make(methodSet)
+ }
+ base[k] = nil // collision
+ }
+ }
+
+ current = consolidateMultiples(next)
+ }
+
+ if len(base) == 0 {
+ return &emptyMethodSet
+ }
+
+ // collect methods
+ var list []*Selection
+ for _, m := range base {
+ if m != nil {
+ m.recv = T
+ list = append(list, m)
+ }
+ }
+ // sort by unique name
+ sort.Slice(list, func(i, j int) bool {
+ return list[i].obj.Id() < list[j].obj.Id()
+ })
+ return &MethodSet{list}
+}
+
+// A methodSet is a set of methods and name collisions.
+// A collision indicates that multiple methods with the
+// same unique id, or a field with that id appeared.
+type methodSet map[string]*Selection // a nil entry indicates a name collision
+
+// Add adds all functions in list to the method set s.
+// If multiples is set, every function in list appears multiple times
+// and is treated as a collision.
+func (s methodSet) add(list []*Func, index []int, indirect bool, multiples bool) methodSet {
+ if len(list) == 0 {
+ return s
+ }
+ for i, f := range list {
+ s = s.addOne(f, concat(index, i), indirect, multiples)
+ }
+ return s
+}
+
+func (s methodSet) addOne(f *Func, index []int, indirect bool, multiples bool) methodSet {
+ if s == nil {
+ s = make(methodSet)
+ }
+ key := f.Id()
+ // if f is not in the set, add it
+ if !multiples {
+ // TODO(gri) A found method may not be added because it's not in the method set
+ // (!indirect && f.hasPtrRecv()). A 2nd method on the same level may be in the method
+ // set and may not collide with the first one, thus leading to a false positive.
+ // Is that possible? Investigate.
+ if _, found := s[key]; !found && (indirect || !f.hasPtrRecv()) {
+ s[key] = &Selection{MethodVal, nil, f, index, indirect}
+ return s
+ }
+ }
+ s[key] = nil // collision
+ return s
+}
diff --git a/contrib/go/_std_1.21/src/go/types/mono.go b/contrib/go/_std_1.21/src/go/types/mono.go
new file mode 100644
index 0000000000..ebf4d8cef7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/mono.go
@@ -0,0 +1,337 @@
+// 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 types
+
+import (
+ "go/ast"
+ "go/token"
+ . "internal/types/errors"
+)
+
+// This file implements a check to validate that a Go package doesn't
+// have unbounded recursive instantiation, which is not compatible
+// with compilers using static instantiation (such as
+// monomorphization).
+//
+// It implements a sort of "type flow" analysis by detecting which
+// type parameters are instantiated with other type parameters (or
+// types derived thereof). A package cannot be statically instantiated
+// if the graph has any cycles involving at least one derived type.
+//
+// Concretely, we construct a directed, weighted graph. Vertices are
+// used to represent type parameters as well as some defined
+// types. Edges are used to represent how types depend on each other:
+//
+// * Everywhere a type-parameterized function or type is instantiated,
+// we add edges to each type parameter from the vertices (if any)
+// representing each type parameter or defined type referenced by
+// the type argument. If the type argument is just the referenced
+// type itself, then the edge has weight 0, otherwise 1.
+//
+// * For every defined type declared within a type-parameterized
+// function or method, we add an edge of weight 1 to the defined
+// type from each ambient type parameter.
+//
+// For example, given:
+//
+// func f[A, B any]() {
+// type T int
+// f[T, map[A]B]()
+// }
+//
+// we construct vertices representing types A, B, and T. Because of
+// declaration "type T int", we construct edges T<-A and T<-B with
+// weight 1; and because of instantiation "f[T, map[A]B]" we construct
+// edges A<-T with weight 0, and B<-A and B<-B with weight 1.
+//
+// Finally, we look for any positive-weight cycles. Zero-weight cycles
+// are allowed because static instantiation will reach a fixed point.
+
+type monoGraph struct {
+ vertices []monoVertex
+ edges []monoEdge
+
+ // canon maps method receiver type parameters to their respective
+ // receiver type's type parameters.
+ canon map[*TypeParam]*TypeParam
+
+ // nameIdx maps a defined type or (canonical) type parameter to its
+ // vertex index.
+ nameIdx map[*TypeName]int
+}
+
+type monoVertex struct {
+ weight int // weight of heaviest known path to this vertex
+ pre int // previous edge (if any) in the above path
+ len int // length of the above path
+
+ // obj is the defined type or type parameter represented by this
+ // vertex.
+ obj *TypeName
+}
+
+type monoEdge struct {
+ dst, src int
+ weight int
+
+ pos token.Pos
+ typ Type
+}
+
+func (check *Checker) monomorph() {
+ // We detect unbounded instantiation cycles using a variant of
+ // Bellman-Ford's algorithm. Namely, instead of always running |V|
+ // iterations, we run until we either reach a fixed point or we've
+ // found a path of length |V|. This allows us to terminate earlier
+ // when there are no cycles, which should be the common case.
+
+ again := true
+ for again {
+ again = false
+
+ for i, edge := range check.mono.edges {
+ src := &check.mono.vertices[edge.src]
+ dst := &check.mono.vertices[edge.dst]
+
+ // N.B., we're looking for the greatest weight paths, unlike
+ // typical Bellman-Ford.
+ w := src.weight + edge.weight
+ if w <= dst.weight {
+ continue
+ }
+
+ dst.pre = i
+ dst.len = src.len + 1
+ if dst.len == len(check.mono.vertices) {
+ check.reportInstanceLoop(edge.dst)
+ return
+ }
+
+ dst.weight = w
+ again = true
+ }
+ }
+}
+
+func (check *Checker) reportInstanceLoop(v int) {
+ var stack []int
+ seen := make([]bool, len(check.mono.vertices))
+
+ // We have a path that contains a cycle and ends at v, but v may
+ // only be reachable from the cycle, not on the cycle itself. We
+ // start by walking backwards along the path until we find a vertex
+ // that appears twice.
+ for !seen[v] {
+ stack = append(stack, v)
+ seen[v] = true
+ v = check.mono.edges[check.mono.vertices[v].pre].src
+ }
+
+ // Trim any vertices we visited before visiting v the first
+ // time. Since v is the first vertex we found within the cycle, any
+ // vertices we visited earlier cannot be part of the cycle.
+ for stack[0] != v {
+ stack = stack[1:]
+ }
+
+ // TODO(mdempsky): Pivot stack so we report the cycle from the top?
+
+ obj0 := check.mono.vertices[v].obj
+ check.error(obj0, InvalidInstanceCycle, "instantiation cycle:")
+
+ qf := RelativeTo(check.pkg)
+ for _, v := range stack {
+ edge := check.mono.edges[check.mono.vertices[v].pre]
+ obj := check.mono.vertices[edge.dst].obj
+
+ switch obj.Type().(type) {
+ default:
+ panic("unexpected type")
+ case *Named:
+ check.errorf(atPos(edge.pos), InvalidInstanceCycle, "\t%s implicitly parameterized by %s", obj.Name(), TypeString(edge.typ, qf)) // secondary error, \t indented
+ case *TypeParam:
+ check.errorf(atPos(edge.pos), InvalidInstanceCycle, "\t%s instantiated as %s", obj.Name(), TypeString(edge.typ, qf)) // secondary error, \t indented
+ }
+ }
+}
+
+// recordCanon records that tpar is the canonical type parameter
+// corresponding to method type parameter mpar.
+func (w *monoGraph) recordCanon(mpar, tpar *TypeParam) {
+ if w.canon == nil {
+ w.canon = make(map[*TypeParam]*TypeParam)
+ }
+ w.canon[mpar] = tpar
+}
+
+// recordInstance records that the given type parameters were
+// instantiated with the corresponding type arguments.
+func (w *monoGraph) recordInstance(pkg *Package, pos token.Pos, tparams []*TypeParam, targs []Type, xlist []ast.Expr) {
+ for i, tpar := range tparams {
+ pos := pos
+ if i < len(xlist) {
+ pos = xlist[i].Pos()
+ }
+ w.assign(pkg, pos, tpar, targs[i])
+ }
+}
+
+// assign records that tpar was instantiated as targ at pos.
+func (w *monoGraph) assign(pkg *Package, pos token.Pos, tpar *TypeParam, targ Type) {
+ // Go generics do not have an analog to C++`s template-templates,
+ // where a template parameter can itself be an instantiable
+ // template. So any instantiation cycles must occur within a single
+ // package. Accordingly, we can ignore instantiations of imported
+ // type parameters.
+ //
+ // TODO(mdempsky): Push this check up into recordInstance? All type
+ // parameters in a list will appear in the same package.
+ if tpar.Obj().Pkg() != pkg {
+ return
+ }
+
+ // flow adds an edge from vertex src representing that typ flows to tpar.
+ flow := func(src int, typ Type) {
+ weight := 1
+ if typ == targ {
+ weight = 0
+ }
+
+ w.addEdge(w.typeParamVertex(tpar), src, weight, pos, targ)
+ }
+
+ // Recursively walk the type argument to find any defined types or
+ // type parameters.
+ var do func(typ Type)
+ do = func(typ Type) {
+ switch typ := typ.(type) {
+ default:
+ panic("unexpected type")
+
+ case *TypeParam:
+ assert(typ.Obj().Pkg() == pkg)
+ flow(w.typeParamVertex(typ), typ)
+
+ case *Named:
+ if src := w.localNamedVertex(pkg, typ.Origin()); src >= 0 {
+ flow(src, typ)
+ }
+
+ targs := typ.TypeArgs()
+ for i := 0; i < targs.Len(); i++ {
+ do(targs.At(i))
+ }
+
+ case *Array:
+ do(typ.Elem())
+ case *Basic:
+ // ok
+ case *Chan:
+ do(typ.Elem())
+ case *Map:
+ do(typ.Key())
+ do(typ.Elem())
+ case *Pointer:
+ do(typ.Elem())
+ case *Slice:
+ do(typ.Elem())
+
+ case *Interface:
+ for i := 0; i < typ.NumMethods(); i++ {
+ do(typ.Method(i).Type())
+ }
+ case *Signature:
+ tuple := func(tup *Tuple) {
+ for i := 0; i < tup.Len(); i++ {
+ do(tup.At(i).Type())
+ }
+ }
+ tuple(typ.Params())
+ tuple(typ.Results())
+ case *Struct:
+ for i := 0; i < typ.NumFields(); i++ {
+ do(typ.Field(i).Type())
+ }
+ }
+ }
+ do(targ)
+}
+
+// localNamedVertex returns the index of the vertex representing
+// named, or -1 if named doesn't need representation.
+func (w *monoGraph) localNamedVertex(pkg *Package, named *Named) int {
+ obj := named.Obj()
+ if obj.Pkg() != pkg {
+ return -1 // imported type
+ }
+
+ root := pkg.Scope()
+ if obj.Parent() == root {
+ return -1 // package scope, no ambient type parameters
+ }
+
+ if idx, ok := w.nameIdx[obj]; ok {
+ return idx
+ }
+
+ idx := -1
+
+ // Walk the type definition's scope to find any ambient type
+ // parameters that it's implicitly parameterized by.
+ for scope := obj.Parent(); scope != root; scope = scope.Parent() {
+ for _, elem := range scope.elems {
+ if elem, ok := elem.(*TypeName); ok && !elem.IsAlias() && cmpPos(elem.Pos(), obj.Pos()) < 0 {
+ if tpar, ok := elem.Type().(*TypeParam); ok {
+ if idx < 0 {
+ idx = len(w.vertices)
+ w.vertices = append(w.vertices, monoVertex{obj: obj})
+ }
+
+ w.addEdge(idx, w.typeParamVertex(tpar), 1, obj.Pos(), tpar)
+ }
+ }
+ }
+ }
+
+ if w.nameIdx == nil {
+ w.nameIdx = make(map[*TypeName]int)
+ }
+ w.nameIdx[obj] = idx
+ return idx
+}
+
+// typeParamVertex returns the index of the vertex representing tpar.
+func (w *monoGraph) typeParamVertex(tpar *TypeParam) int {
+ if x, ok := w.canon[tpar]; ok {
+ tpar = x
+ }
+
+ obj := tpar.Obj()
+
+ if idx, ok := w.nameIdx[obj]; ok {
+ return idx
+ }
+
+ if w.nameIdx == nil {
+ w.nameIdx = make(map[*TypeName]int)
+ }
+
+ idx := len(w.vertices)
+ w.vertices = append(w.vertices, monoVertex{obj: obj})
+ w.nameIdx[obj] = idx
+ return idx
+}
+
+func (w *monoGraph) addEdge(dst, src, weight int, pos token.Pos, typ Type) {
+ // TODO(mdempsky): Deduplicate redundant edges?
+ w.edges = append(w.edges, monoEdge{
+ dst: dst,
+ src: src,
+ weight: weight,
+
+ pos: pos,
+ typ: typ,
+ })
+}
diff --git a/contrib/go/_std_1.21/src/go/types/named.go b/contrib/go/_std_1.21/src/go/types/named.go
new file mode 100644
index 0000000000..413eaada27
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/named.go
@@ -0,0 +1,658 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2011 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 types
+
+import (
+ "go/token"
+ "sync"
+ "sync/atomic"
+)
+
+// Type-checking Named types is subtle, because they may be recursively
+// defined, and because their full details may be spread across multiple
+// declarations (via methods). For this reason they are type-checked lazily,
+// to avoid information being accessed before it is complete.
+//
+// Conceptually, it is helpful to think of named types as having two distinct
+// sets of information:
+// - "LHS" information, defining their identity: Obj() and TypeArgs()
+// - "RHS" information, defining their details: TypeParams(), Underlying(),
+// and methods.
+//
+// In this taxonomy, LHS information is available immediately, but RHS
+// information is lazy. Specifically, a named type N may be constructed in any
+// of the following ways:
+// 1. type-checked from the source
+// 2. loaded eagerly from export data
+// 3. loaded lazily from export data (when using unified IR)
+// 4. instantiated from a generic type
+//
+// In cases 1, 3, and 4, it is possible that the underlying type or methods of
+// N may not be immediately available.
+// - During type-checking, we allocate N before type-checking its underlying
+// type or methods, so that we may resolve recursive references.
+// - When loading from export data, we may load its methods and underlying
+// type lazily using a provided load function.
+// - After instantiating, we lazily expand the underlying type and methods
+// (note that instances may be created while still in the process of
+// type-checking the original type declaration).
+//
+// In cases 3 and 4 this lazy construction may also occur concurrently, due to
+// concurrent use of the type checker API (after type checking or importing has
+// finished). It is critical that we keep track of state, so that Named types
+// are constructed exactly once and so that we do not access their details too
+// soon.
+//
+// We achieve this by tracking state with an atomic state variable, and
+// guarding potentially concurrent calculations with a mutex. At any point in
+// time this state variable determines which data on N may be accessed. As
+// state monotonically progresses, any data available at state M may be
+// accessed without acquiring the mutex at state N, provided N >= M.
+//
+// GLOSSARY: Here are a few terms used in this file to describe Named types:
+// - We say that a Named type is "instantiated" if it has been constructed by
+// instantiating a generic named type with type arguments.
+// - We say that a Named type is "declared" if it corresponds to a type
+// declaration in the source. Instantiated named types correspond to a type
+// instantiation in the source, not a declaration. But their Origin type is
+// a declared type.
+// - We say that a Named type is "resolved" if its RHS information has been
+// loaded or fully type-checked. For Named types constructed from export
+// data, this may involve invoking a loader function to extract information
+// from export data. For instantiated named types this involves reading
+// information from their origin.
+// - We say that a Named type is "expanded" if it is an instantiated type and
+// type parameters in its underlying type and methods have been substituted
+// with the type arguments from the instantiation. A type may be partially
+// expanded if some but not all of these details have been substituted.
+// Similarly, we refer to these individual details (underlying type or
+// method) as being "expanded".
+// - When all information is known for a named type, we say it is "complete".
+//
+// Some invariants to keep in mind: each declared Named type has a single
+// corresponding object, and that object's type is the (possibly generic) Named
+// type. Declared Named types are identical if and only if their pointers are
+// identical. On the other hand, multiple instantiated Named types may be
+// identical even though their pointers are not identical. One has to use
+// Identical to compare them. For instantiated named types, their obj is a
+// synthetic placeholder that records their position of the corresponding
+// instantiation in the source (if they were constructed during type checking).
+//
+// To prevent infinite expansion of named instances that are created outside of
+// type-checking, instances share a Context with other instances created during
+// their expansion. Via the pidgeonhole principle, this guarantees that in the
+// presence of a cycle of named types, expansion will eventually find an
+// existing instance in the Context and short-circuit the expansion.
+//
+// Once an instance is complete, we can nil out this shared Context to unpin
+// memory, though this Context may still be held by other incomplete instances
+// in its "lineage".
+
+// A Named represents a named (defined) type.
+type Named struct {
+ check *Checker // non-nil during type-checking; nil otherwise
+ obj *TypeName // corresponding declared object for declared types; see above for instantiated types
+
+ // fromRHS holds the type (on RHS of declaration) this *Named type is derived
+ // from (for cycle reporting). Only used by validType, and therefore does not
+ // require synchronization.
+ fromRHS Type
+
+ // information for instantiated types; nil otherwise
+ inst *instance
+
+ mu sync.Mutex // guards all fields below
+ state_ uint32 // the current state of this type; must only be accessed atomically
+ underlying Type // possibly a *Named during setup; never a *Named once set up completely
+ tparams *TypeParamList // type parameters, or nil
+
+ // methods declared for this type (not the method set of this type)
+ // Signatures are type-checked lazily.
+ // For non-instantiated types, this is a fully populated list of methods. For
+ // instantiated types, methods are individually expanded when they are first
+ // accessed.
+ methods []*Func
+
+ // loader may be provided to lazily load type parameters, underlying type, and methods.
+ loader func(*Named) (tparams []*TypeParam, underlying Type, methods []*Func)
+}
+
+// instance holds information that is only necessary for instantiated named
+// types.
+type instance struct {
+ orig *Named // original, uninstantiated type
+ targs *TypeList // type arguments
+ expandedMethods int // number of expanded methods; expandedMethods <= len(orig.methods)
+ ctxt *Context // local Context; set to nil after full expansion
+}
+
+// namedState represents the possible states that a named type may assume.
+type namedState uint32
+
+const (
+ unresolved namedState = iota // tparams, underlying type and methods might be unavailable
+ resolved // resolve has run; methods might be incomplete (for instances)
+ complete // all data is known
+)
+
+// NewNamed returns a new named type for the given type name, underlying type, and associated methods.
+// If the given type name obj doesn't have a type yet, its type is set to the returned named type.
+// The underlying type must not be a *Named.
+func NewNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
+ if _, ok := underlying.(*Named); ok {
+ panic("underlying type must not be *Named")
+ }
+ return (*Checker)(nil).newNamed(obj, underlying, methods)
+}
+
+// resolve resolves the type parameters, methods, and underlying type of n.
+// This information may be loaded from a provided loader function, or computed
+// from an origin type (in the case of instances).
+//
+// After resolution, the type parameters, methods, and underlying type of n are
+// accessible; but if n is an instantiated type, its methods may still be
+// unexpanded.
+func (n *Named) resolve() *Named {
+ if n.state() >= resolved { // avoid locking below
+ return n
+ }
+
+ // TODO(rfindley): if n.check is non-nil we can avoid locking here, since
+ // type-checking is not concurrent. Evaluate if this is worth doing.
+ n.mu.Lock()
+ defer n.mu.Unlock()
+
+ if n.state() >= resolved {
+ return n
+ }
+
+ if n.inst != nil {
+ assert(n.underlying == nil) // n is an unresolved instance
+ assert(n.loader == nil) // instances are created by instantiation, in which case n.loader is nil
+
+ orig := n.inst.orig
+ orig.resolve()
+ underlying := n.expandUnderlying()
+
+ n.tparams = orig.tparams
+ n.underlying = underlying
+ n.fromRHS = orig.fromRHS // for cycle detection
+
+ if len(orig.methods) == 0 {
+ n.setState(complete) // nothing further to do
+ n.inst.ctxt = nil
+ } else {
+ n.setState(resolved)
+ }
+ return n
+ }
+
+ // TODO(mdempsky): Since we're passing n to the loader anyway
+ // (necessary because types2 expects the receiver type for methods
+ // on defined interface types to be the Named rather than the
+ // underlying Interface), maybe it should just handle calling
+ // SetTypeParams, SetUnderlying, and AddMethod instead? Those
+ // methods would need to support reentrant calls though. It would
+ // also make the API more future-proof towards further extensions.
+ if n.loader != nil {
+ assert(n.underlying == nil)
+ assert(n.TypeArgs().Len() == 0) // instances are created by instantiation, in which case n.loader is nil
+
+ tparams, underlying, methods := n.loader(n)
+
+ n.tparams = bindTParams(tparams)
+ n.underlying = underlying
+ n.fromRHS = underlying // for cycle detection
+ n.methods = methods
+ n.loader = nil
+ }
+
+ n.setState(complete)
+ return n
+}
+
+// state atomically accesses the current state of the receiver.
+func (n *Named) state() namedState {
+ return namedState(atomic.LoadUint32(&n.state_))
+}
+
+// setState atomically stores the given state for n.
+// Must only be called while holding n.mu.
+func (n *Named) setState(state namedState) {
+ atomic.StoreUint32(&n.state_, uint32(state))
+}
+
+// newNamed is like NewNamed but with a *Checker receiver and additional orig argument.
+func (check *Checker) newNamed(obj *TypeName, underlying Type, methods []*Func) *Named {
+ typ := &Named{check: check, obj: obj, fromRHS: underlying, underlying: underlying, methods: methods}
+ if obj.typ == nil {
+ obj.typ = typ
+ }
+ // Ensure that typ is always sanity-checked.
+ if check != nil {
+ check.needsCleanup(typ)
+ }
+ return typ
+}
+
+// newNamedInstance creates a new named instance for the given origin and type
+// arguments, recording pos as the position of its synthetic object (for error
+// reporting).
+//
+// If set, expanding is the named type instance currently being expanded, that
+// led to the creation of this instance.
+func (check *Checker) newNamedInstance(pos token.Pos, orig *Named, targs []Type, expanding *Named) *Named {
+ assert(len(targs) > 0)
+
+ obj := NewTypeName(pos, orig.obj.pkg, orig.obj.name, nil)
+ inst := &instance{orig: orig, targs: newTypeList(targs)}
+
+ // Only pass the expanding context to the new instance if their packages
+ // match. Since type reference cycles are only possible within a single
+ // package, this is sufficient for the purposes of short-circuiting cycles.
+ // Avoiding passing the context in other cases prevents unnecessary coupling
+ // of types across packages.
+ if expanding != nil && expanding.Obj().pkg == obj.pkg {
+ inst.ctxt = expanding.inst.ctxt
+ }
+ typ := &Named{check: check, obj: obj, inst: inst}
+ obj.typ = typ
+ // Ensure that typ is always sanity-checked.
+ if check != nil {
+ check.needsCleanup(typ)
+ }
+ return typ
+}
+
+func (t *Named) cleanup() {
+ assert(t.inst == nil || t.inst.orig.inst == nil)
+ // Ensure that every defined type created in the course of type-checking has
+ // either non-*Named underlying type, or is unexpanded.
+ //
+ // This guarantees that we don't leak any types whose underlying type is
+ // *Named, because any unexpanded instances will lazily compute their
+ // underlying type by substituting in the underlying type of their origin.
+ // The origin must have either been imported or type-checked and expanded
+ // here, and in either case its underlying type will be fully expanded.
+ switch t.underlying.(type) {
+ case nil:
+ if t.TypeArgs().Len() == 0 {
+ panic("nil underlying")
+ }
+ case *Named:
+ t.under() // t.under may add entries to check.cleaners
+ }
+ t.check = nil
+}
+
+// Obj returns the type name for the declaration defining the named type t. For
+// instantiated types, this is same as the type name of the origin type.
+func (t *Named) Obj() *TypeName {
+ if t.inst == nil {
+ return t.obj
+ }
+ return t.inst.orig.obj
+}
+
+// Origin returns the generic type from which the named type t is
+// instantiated. If t is not an instantiated type, the result is t.
+func (t *Named) Origin() *Named {
+ if t.inst == nil {
+ return t
+ }
+ return t.inst.orig
+}
+
+// TypeParams returns the type parameters of the named type t, or nil.
+// The result is non-nil for an (originally) generic type even if it is instantiated.
+func (t *Named) TypeParams() *TypeParamList { return t.resolve().tparams }
+
+// SetTypeParams sets the type parameters of the named type t.
+// t must not have type arguments.
+func (t *Named) SetTypeParams(tparams []*TypeParam) {
+ assert(t.inst == nil)
+ t.resolve().tparams = bindTParams(tparams)
+}
+
+// TypeArgs returns the type arguments used to instantiate the named type t.
+func (t *Named) TypeArgs() *TypeList {
+ if t.inst == nil {
+ return nil
+ }
+ return t.inst.targs
+}
+
+// NumMethods returns the number of explicit methods defined for t.
+func (t *Named) NumMethods() int {
+ return len(t.Origin().resolve().methods)
+}
+
+// Method returns the i'th method of named type t for 0 <= i < t.NumMethods().
+//
+// For an ordinary or instantiated type t, the receiver base type of this
+// method is the named type t. For an uninstantiated generic type t, each
+// method receiver is instantiated with its receiver type parameters.
+func (t *Named) Method(i int) *Func {
+ t.resolve()
+
+ if t.state() >= complete {
+ return t.methods[i]
+ }
+
+ assert(t.inst != nil) // only instances should have incomplete methods
+ orig := t.inst.orig
+
+ t.mu.Lock()
+ defer t.mu.Unlock()
+
+ if len(t.methods) != len(orig.methods) {
+ assert(len(t.methods) == 0)
+ t.methods = make([]*Func, len(orig.methods))
+ }
+
+ if t.methods[i] == nil {
+ assert(t.inst.ctxt != nil) // we should still have a context remaining from the resolution phase
+ t.methods[i] = t.expandMethod(i)
+ t.inst.expandedMethods++
+
+ // Check if we've created all methods at this point. If we have, mark the
+ // type as fully expanded.
+ if t.inst.expandedMethods == len(orig.methods) {
+ t.setState(complete)
+ t.inst.ctxt = nil // no need for a context anymore
+ }
+ }
+
+ return t.methods[i]
+}
+
+// expandMethod substitutes type arguments in the i'th method for an
+// instantiated receiver.
+func (t *Named) expandMethod(i int) *Func {
+ // t.orig.methods is not lazy. origm is the method instantiated with its
+ // receiver type parameters (the "origin" method).
+ origm := t.inst.orig.Method(i)
+ assert(origm != nil)
+
+ check := t.check
+ // Ensure that the original method is type-checked.
+ if check != nil {
+ check.objDecl(origm, nil)
+ }
+
+ origSig := origm.typ.(*Signature)
+ rbase, _ := deref(origSig.Recv().Type())
+
+ // If rbase is t, then origm is already the instantiated method we're looking
+ // for. In this case, we return origm to preserve the invariant that
+ // traversing Method->Receiver Type->Method should get back to the same
+ // method.
+ //
+ // This occurs if t is instantiated with the receiver type parameters, as in
+ // the use of m in func (r T[_]) m() { r.m() }.
+ if rbase == t {
+ return origm
+ }
+
+ sig := origSig
+ // We can only substitute if we have a correspondence between type arguments
+ // and type parameters. This check is necessary in the presence of invalid
+ // code.
+ if origSig.RecvTypeParams().Len() == t.inst.targs.Len() {
+ smap := makeSubstMap(origSig.RecvTypeParams().list(), t.inst.targs.list())
+ var ctxt *Context
+ if check != nil {
+ ctxt = check.context()
+ }
+ sig = check.subst(origm.pos, origSig, smap, t, ctxt).(*Signature)
+ }
+
+ if sig == origSig {
+ // No substitution occurred, but we still need to create a new signature to
+ // hold the instantiated receiver.
+ copy := *origSig
+ sig = &copy
+ }
+
+ var rtyp Type
+ if origm.hasPtrRecv() {
+ rtyp = NewPointer(t)
+ } else {
+ rtyp = t
+ }
+
+ sig.recv = substVar(origSig.recv, rtyp)
+ return substFunc(origm, sig)
+}
+
+// SetUnderlying sets the underlying type and marks t as complete.
+// t must not have type arguments.
+func (t *Named) SetUnderlying(underlying Type) {
+ assert(t.inst == nil)
+ if underlying == nil {
+ panic("underlying type must not be nil")
+ }
+ if _, ok := underlying.(*Named); ok {
+ panic("underlying type must not be *Named")
+ }
+ t.resolve().underlying = underlying
+ if t.fromRHS == nil {
+ t.fromRHS = underlying // for cycle detection
+ }
+}
+
+// AddMethod adds method m unless it is already in the method list.
+// t must not have type arguments.
+func (t *Named) AddMethod(m *Func) {
+ assert(t.inst == nil)
+ t.resolve()
+ if i, _ := lookupMethod(t.methods, m.pkg, m.name, false); i < 0 {
+ t.methods = append(t.methods, m)
+ }
+}
+
+func (t *Named) Underlying() Type { return t.resolve().underlying }
+func (t *Named) String() string { return TypeString(t, nil) }
+
+// ----------------------------------------------------------------------------
+// Implementation
+//
+// TODO(rfindley): reorganize the loading and expansion methods under this
+// heading.
+
+// under returns the expanded underlying type of n0; possibly by following
+// forward chains of named types. If an underlying type is found, resolve
+// the chain by setting the underlying type for each defined type in the
+// chain before returning it. If no underlying type is found or a cycle
+// is detected, the result is Typ[Invalid]. If a cycle is detected and
+// n0.check != nil, the cycle is reported.
+//
+// This is necessary because the underlying type of named may be itself a
+// named type that is incomplete:
+//
+// type (
+// A B
+// B *C
+// C A
+// )
+//
+// The type of C is the (named) type of A which is incomplete,
+// and which has as its underlying type the named type B.
+func (n0 *Named) under() Type {
+ u := n0.Underlying()
+
+ // If the underlying type of a defined type is not a defined
+ // (incl. instance) type, then that is the desired underlying
+ // type.
+ var n1 *Named
+ switch u1 := u.(type) {
+ case nil:
+ // After expansion via Underlying(), we should never encounter a nil
+ // underlying.
+ panic("nil underlying")
+ default:
+ // common case
+ return u
+ case *Named:
+ // handled below
+ n1 = u1
+ }
+
+ if n0.check == nil {
+ panic("Named.check == nil but type is incomplete")
+ }
+
+ // Invariant: after this point n0 as well as any named types in its
+ // underlying chain should be set up when this function exits.
+ check := n0.check
+ n := n0
+
+ seen := make(map[*Named]int) // types that need their underlying type resolved
+ var path []Object // objects encountered, for cycle reporting
+
+loop:
+ for {
+ seen[n] = len(seen)
+ path = append(path, n.obj)
+ n = n1
+ if i, ok := seen[n]; ok {
+ // cycle
+ check.cycleError(path[i:])
+ u = Typ[Invalid]
+ break
+ }
+ u = n.Underlying()
+ switch u1 := u.(type) {
+ case nil:
+ u = Typ[Invalid]
+ break loop
+ default:
+ break loop
+ case *Named:
+ // Continue collecting *Named types in the chain.
+ n1 = u1
+ }
+ }
+
+ for n := range seen {
+ // We should never have to update the underlying type of an imported type;
+ // those underlying types should have been resolved during the import.
+ // Also, doing so would lead to a race condition (was go.dev/issue/31749).
+ // Do this check always, not just in debug mode (it's cheap).
+ if n.obj.pkg != check.pkg {
+ panic("imported type with unresolved underlying type")
+ }
+ n.underlying = u
+ }
+
+ return u
+}
+
+func (n *Named) setUnderlying(typ Type) {
+ if n != nil {
+ n.underlying = typ
+ }
+}
+
+func (n *Named) lookupMethod(pkg *Package, name string, foldCase bool) (int, *Func) {
+ n.resolve()
+ // If n is an instance, we may not have yet instantiated all of its methods.
+ // Look up the method index in orig, and only instantiate method at the
+ // matching index (if any).
+ i, _ := lookupMethod(n.Origin().methods, pkg, name, foldCase)
+ if i < 0 {
+ return -1, nil
+ }
+ // For instances, m.Method(i) will be different from the orig method.
+ return i, n.Method(i)
+}
+
+// context returns the type-checker context.
+func (check *Checker) context() *Context {
+ if check.ctxt == nil {
+ check.ctxt = NewContext()
+ }
+ return check.ctxt
+}
+
+// expandUnderlying substitutes type arguments in the underlying type n.orig,
+// returning the result. Returns Typ[Invalid] if there was an error.
+func (n *Named) expandUnderlying() Type {
+ check := n.check
+ if check != nil && check.conf._Trace {
+ check.trace(n.obj.pos, "-- Named.expandUnderlying %s", n)
+ check.indent++
+ defer func() {
+ check.indent--
+ check.trace(n.obj.pos, "=> %s (tparams = %s, under = %s)", n, n.tparams.list(), n.underlying)
+ }()
+ }
+
+ assert(n.inst.orig.underlying != nil)
+ if n.inst.ctxt == nil {
+ n.inst.ctxt = NewContext()
+ }
+
+ orig := n.inst.orig
+ targs := n.inst.targs
+
+ if _, unexpanded := orig.underlying.(*Named); unexpanded {
+ // We should only get a Named underlying type here during type checking
+ // (for example, in recursive type declarations).
+ assert(check != nil)
+ }
+
+ if orig.tparams.Len() != targs.Len() {
+ // Mismatching arg and tparam length may be checked elsewhere.
+ return Typ[Invalid]
+ }
+
+ // Ensure that an instance is recorded before substituting, so that we
+ // resolve n for any recursive references.
+ h := n.inst.ctxt.instanceHash(orig, targs.list())
+ n2 := n.inst.ctxt.update(h, orig, n.TypeArgs().list(), n)
+ assert(n == n2)
+
+ smap := makeSubstMap(orig.tparams.list(), targs.list())
+ var ctxt *Context
+ if check != nil {
+ ctxt = check.context()
+ }
+ underlying := n.check.subst(n.obj.pos, orig.underlying, smap, n, ctxt)
+ // If the underlying type of n is an interface, we need to set the receiver of
+ // its methods accurately -- we set the receiver of interface methods on
+ // the RHS of a type declaration to the defined type.
+ if iface, _ := underlying.(*Interface); iface != nil {
+ if methods, copied := replaceRecvType(iface.methods, orig, n); copied {
+ // If the underlying type doesn't actually use type parameters, it's
+ // possible that it wasn't substituted. In this case we need to create
+ // a new *Interface before modifying receivers.
+ if iface == orig.underlying {
+ old := iface
+ iface = check.newInterface()
+ iface.embeddeds = old.embeddeds
+ iface.complete = old.complete
+ iface.implicit = old.implicit // should be false but be conservative
+ underlying = iface
+ }
+ iface.methods = methods
+ }
+ }
+
+ return underlying
+}
+
+// safeUnderlying returns the underlying type of typ without expanding
+// instances, to avoid infinite recursion.
+//
+// TODO(rfindley): eliminate this function or give it a better name.
+func safeUnderlying(typ Type) Type {
+ if t, _ := typ.(*Named); t != nil {
+ return t.underlying
+ }
+ return typ.Underlying()
+}
diff --git a/contrib/go/_std_1.21/src/go/types/object.go b/contrib/go/_std_1.21/src/go/types/object.go
new file mode 100644
index 0000000000..e47ef2ebec
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/object.go
@@ -0,0 +1,613 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2013 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 types
+
+import (
+ "bytes"
+ "fmt"
+ "go/constant"
+ "go/token"
+ "unicode"
+ "unicode/utf8"
+)
+
+// An Object describes a named language entity such as a package,
+// constant, type, variable, function (incl. methods), or label.
+// All objects implement the Object interface.
+type Object interface {
+ Parent() *Scope // scope in which this object is declared; nil for methods and struct fields
+ Pos() token.Pos // position of object identifier in declaration
+ Pkg() *Package // package to which this object belongs; nil for labels and objects in the Universe scope
+ Name() string // package local object name
+ Type() Type // object type
+ Exported() bool // reports whether the name starts with a capital letter
+ Id() string // object name if exported, qualified name if not exported (see func Id)
+
+ // String returns a human-readable string of the object.
+ String() string
+
+ // order reflects a package-level object's source order: if object
+ // a is before object b in the source, then a.order() < b.order().
+ // order returns a value > 0 for package-level objects; it returns
+ // 0 for all other objects (including objects in file scopes).
+ order() uint32
+
+ // color returns the object's color.
+ color() color
+
+ // setType sets the type of the object.
+ setType(Type)
+
+ // setOrder sets the order number of the object. It must be > 0.
+ setOrder(uint32)
+
+ // setColor sets the object's color. It must not be white.
+ setColor(color color)
+
+ // setParent sets the parent scope of the object.
+ setParent(*Scope)
+
+ // sameId reports whether obj.Id() and Id(pkg, name) are the same.
+ sameId(pkg *Package, name string) bool
+
+ // scopePos returns the start position of the scope of this Object
+ scopePos() token.Pos
+
+ // setScopePos sets the start position of the scope for this Object.
+ setScopePos(pos token.Pos)
+}
+
+func isExported(name string) bool {
+ ch, _ := utf8.DecodeRuneInString(name)
+ return unicode.IsUpper(ch)
+}
+
+// Id returns name if it is exported, otherwise it
+// returns the name qualified with the package path.
+func Id(pkg *Package, name string) string {
+ if isExported(name) {
+ return name
+ }
+ // unexported names need the package path for differentiation
+ // (if there's no package, make sure we don't start with '.'
+ // as that may change the order of methods between a setup
+ // inside a package and outside a package - which breaks some
+ // tests)
+ path := "_"
+ // pkg is nil for objects in Universe scope and possibly types
+ // introduced via Eval (see also comment in object.sameId)
+ if pkg != nil && pkg.path != "" {
+ path = pkg.path
+ }
+ return path + "." + name
+}
+
+// An object implements the common parts of an Object.
+type object struct {
+ parent *Scope
+ pos token.Pos
+ pkg *Package
+ name string
+ typ Type
+ order_ uint32
+ color_ color
+ scopePos_ token.Pos
+}
+
+// color encodes the color of an object (see Checker.objDecl for details).
+type color uint32
+
+// An object may be painted in one of three colors.
+// Color values other than white or black are considered grey.
+const (
+ white color = iota
+ black
+ grey // must be > white and black
+)
+
+func (c color) String() string {
+ switch c {
+ case white:
+ return "white"
+ case black:
+ return "black"
+ default:
+ return "grey"
+ }
+}
+
+// colorFor returns the (initial) color for an object depending on
+// whether its type t is known or not.
+func colorFor(t Type) color {
+ if t != nil {
+ return black
+ }
+ return white
+}
+
+// Parent returns the scope in which the object is declared.
+// The result is nil for methods and struct fields.
+func (obj *object) Parent() *Scope { return obj.parent }
+
+// Pos returns the declaration position of the object's identifier.
+func (obj *object) Pos() token.Pos { return obj.pos }
+
+// Pkg returns the package to which the object belongs.
+// The result is nil for labels and objects in the Universe scope.
+func (obj *object) Pkg() *Package { return obj.pkg }
+
+// Name returns the object's (package-local, unqualified) name.
+func (obj *object) Name() string { return obj.name }
+
+// Type returns the object's type.
+func (obj *object) Type() Type { return obj.typ }
+
+// Exported reports whether the object is exported (starts with a capital letter).
+// It doesn't take into account whether the object is in a local (function) scope
+// or not.
+func (obj *object) Exported() bool { return isExported(obj.name) }
+
+// Id is a wrapper for Id(obj.Pkg(), obj.Name()).
+func (obj *object) Id() string { return Id(obj.pkg, obj.name) }
+
+func (obj *object) String() string { panic("abstract") }
+func (obj *object) order() uint32 { return obj.order_ }
+func (obj *object) color() color { return obj.color_ }
+func (obj *object) scopePos() token.Pos { return obj.scopePos_ }
+
+func (obj *object) setParent(parent *Scope) { obj.parent = parent }
+func (obj *object) setType(typ Type) { obj.typ = typ }
+func (obj *object) setOrder(order uint32) { assert(order > 0); obj.order_ = order }
+func (obj *object) setColor(color color) { assert(color != white); obj.color_ = color }
+func (obj *object) setScopePos(pos token.Pos) { obj.scopePos_ = pos }
+
+func (obj *object) sameId(pkg *Package, name string) bool {
+ // spec:
+ // "Two identifiers are different if they are spelled differently,
+ // or if they appear in different packages and are not exported.
+ // Otherwise, they are the same."
+ if name != obj.name {
+ return false
+ }
+ // obj.Name == name
+ if obj.Exported() {
+ return true
+ }
+ // not exported, so packages must be the same (pkg == nil for
+ // fields in Universe scope; this can only happen for types
+ // introduced via Eval)
+ if pkg == nil || obj.pkg == nil {
+ return pkg == obj.pkg
+ }
+ // pkg != nil && obj.pkg != nil
+ return pkg.path == obj.pkg.path
+}
+
+// less reports whether object a is ordered before object b.
+//
+// Objects are ordered nil before non-nil, exported before
+// non-exported, then by name, and finally (for non-exported
+// functions) by package path.
+func (a *object) less(b *object) bool {
+ if a == b {
+ return false
+ }
+
+ // Nil before non-nil.
+ if a == nil {
+ return true
+ }
+ if b == nil {
+ return false
+ }
+
+ // Exported functions before non-exported.
+ ea := isExported(a.name)
+ eb := isExported(b.name)
+ if ea != eb {
+ return ea
+ }
+
+ // Order by name and then (for non-exported names) by package.
+ if a.name != b.name {
+ return a.name < b.name
+ }
+ if !ea {
+ return a.pkg.path < b.pkg.path
+ }
+
+ return false
+}
+
+// A PkgName represents an imported Go package.
+// PkgNames don't have a type.
+type PkgName struct {
+ object
+ imported *Package
+ used bool // set if the package was used
+}
+
+// NewPkgName returns a new PkgName object representing an imported package.
+// The remaining arguments set the attributes found with all Objects.
+func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName {
+ return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, nopos}, imported, false}
+}
+
+// Imported returns the package that was imported.
+// It is distinct from Pkg(), which is the package containing the import statement.
+func (obj *PkgName) Imported() *Package { return obj.imported }
+
+// A Const represents a declared constant.
+type Const struct {
+ object
+ val constant.Value
+}
+
+// NewConst returns a new constant with value val.
+// The remaining arguments set the attributes found with all Objects.
+func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
+ return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, val}
+}
+
+// Val returns the constant's value.
+func (obj *Const) Val() constant.Value { return obj.val }
+
+func (*Const) isDependency() {} // a constant may be a dependency of an initialization expression
+
+// A TypeName represents a name for a (defined or alias) type.
+type TypeName struct {
+ object
+}
+
+// NewTypeName returns a new type name denoting the given typ.
+// The remaining arguments set the attributes found with all Objects.
+//
+// The typ argument may be a defined (Named) type or an alias type.
+// It may also be nil such that the returned TypeName can be used as
+// argument for NewNamed, which will set the TypeName's type as a side-
+// effect.
+func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName {
+ return &TypeName{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
+}
+
+// NewTypeNameLazy returns a new defined type like NewTypeName, but it
+// lazily calls resolve to finish constructing the Named object.
+func _NewTypeNameLazy(pos token.Pos, pkg *Package, name string, load func(named *Named) (tparams []*TypeParam, underlying Type, methods []*Func)) *TypeName {
+ obj := NewTypeName(pos, pkg, name, nil)
+ NewNamed(obj, nil, nil).loader = load
+ return obj
+}
+
+// IsAlias reports whether obj is an alias name for a type.
+func (obj *TypeName) IsAlias() bool {
+ switch t := obj.typ.(type) {
+ case nil:
+ return false
+ case *Basic:
+ // unsafe.Pointer is not an alias.
+ if obj.pkg == Unsafe {
+ return false
+ }
+ // Any user-defined type name for a basic type is an alias for a
+ // basic type (because basic types are pre-declared in the Universe
+ // scope, outside any package scope), and so is any type name with
+ // a different name than the name of the basic type it refers to.
+ // Additionally, we need to look for "byte" and "rune" because they
+ // are aliases but have the same names (for better error messages).
+ return obj.pkg != nil || t.name != obj.name || t == universeByte || t == universeRune
+ case *Named:
+ return obj != t.obj
+ case *TypeParam:
+ return obj != t.obj
+ default:
+ return true
+ }
+}
+
+// A Variable represents a declared variable (including function parameters and results, and struct fields).
+type Var struct {
+ object
+ embedded bool // if set, the variable is an embedded struct field, and name is the type name
+ isField bool // var is struct field
+ used bool // set if the variable was used
+ origin *Var // if non-nil, the Var from which this one was instantiated
+}
+
+// NewVar returns a new variable.
+// The arguments set the attributes found with all Objects.
+func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var {
+ return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
+}
+
+// NewParam returns a new variable representing a function parameter.
+func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var {
+ return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, used: true} // parameters are always 'used'
+}
+
+// NewField returns a new variable representing a struct field.
+// For embedded fields, the name is the unqualified type name
+// under which the field is accessible.
+func NewField(pos token.Pos, pkg *Package, name string, typ Type, embedded bool) *Var {
+ return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, embedded: embedded, isField: true}
+}
+
+// Anonymous reports whether the variable is an embedded field.
+// Same as Embedded; only present for backward-compatibility.
+func (obj *Var) Anonymous() bool { return obj.embedded }
+
+// Embedded reports whether the variable is an embedded field.
+func (obj *Var) Embedded() bool { return obj.embedded }
+
+// IsField reports whether the variable is a struct field.
+func (obj *Var) IsField() bool { return obj.isField }
+
+// Origin returns the canonical Var for its receiver, i.e. the Var object
+// recorded in Info.Defs.
+//
+// For synthetic Vars created during instantiation (such as struct fields or
+// function parameters that depend on type arguments), this will be the
+// corresponding Var on the generic (uninstantiated) type. For all other Vars
+// Origin returns the receiver.
+func (obj *Var) Origin() *Var {
+ if obj.origin != nil {
+ return obj.origin
+ }
+ return obj
+}
+
+func (*Var) isDependency() {} // a variable may be a dependency of an initialization expression
+
+// A Func represents a declared function, concrete method, or abstract
+// (interface) method. Its Type() is always a *Signature.
+// An abstract method may belong to many interfaces due to embedding.
+type Func struct {
+ object
+ hasPtrRecv_ bool // only valid for methods that don't have a type yet; use hasPtrRecv() to read
+ origin *Func // if non-nil, the Func from which this one was instantiated
+}
+
+// NewFunc returns a new function with the given signature, representing
+// the function's type.
+func NewFunc(pos token.Pos, pkg *Package, name string, sig *Signature) *Func {
+ // don't store a (typed) nil signature
+ var typ Type
+ if sig != nil {
+ typ = sig
+ }
+ return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, false, nil}
+}
+
+// FullName returns the package- or receiver-type-qualified name of
+// function or method obj.
+func (obj *Func) FullName() string {
+ var buf bytes.Buffer
+ writeFuncName(&buf, obj, nil)
+ return buf.String()
+}
+
+// Scope returns the scope of the function's body block.
+// The result is nil for imported or instantiated functions and methods
+// (but there is also no mechanism to get to an instantiated function).
+func (obj *Func) Scope() *Scope { return obj.typ.(*Signature).scope }
+
+// Origin returns the canonical Func for its receiver, i.e. the Func object
+// recorded in Info.Defs.
+//
+// For synthetic functions created during instantiation (such as methods on an
+// instantiated Named type or interface methods that depend on type arguments),
+// this will be the corresponding Func on the generic (uninstantiated) type.
+// For all other Funcs Origin returns the receiver.
+func (obj *Func) Origin() *Func {
+ if obj.origin != nil {
+ return obj.origin
+ }
+ return obj
+}
+
+// hasPtrRecv reports whether the receiver is of the form *T for the given method obj.
+func (obj *Func) hasPtrRecv() bool {
+ // If a method's receiver type is set, use that as the source of truth for the receiver.
+ // Caution: Checker.funcDecl (decl.go) marks a function by setting its type to an empty
+ // signature. We may reach here before the signature is fully set up: we must explicitly
+ // check if the receiver is set (we cannot just look for non-nil obj.typ).
+ if sig, _ := obj.typ.(*Signature); sig != nil && sig.recv != nil {
+ _, isPtr := deref(sig.recv.typ)
+ return isPtr
+ }
+
+ // If a method's type is not set it may be a method/function that is:
+ // 1) client-supplied (via NewFunc with no signature), or
+ // 2) internally created but not yet type-checked.
+ // For case 1) we can't do anything; the client must know what they are doing.
+ // For case 2) we can use the information gathered by the resolver.
+ return obj.hasPtrRecv_
+}
+
+func (*Func) isDependency() {} // a function may be a dependency of an initialization expression
+
+// A Label represents a declared label.
+// Labels don't have a type.
+type Label struct {
+ object
+ used bool // set if the label was used
+}
+
+// NewLabel returns a new label.
+func NewLabel(pos token.Pos, pkg *Package, name string) *Label {
+ return &Label{object{pos: pos, pkg: pkg, name: name, typ: Typ[Invalid], color_: black}, false}
+}
+
+// A Builtin represents a built-in function.
+// Builtins don't have a valid type.
+type Builtin struct {
+ object
+ id builtinId
+}
+
+func newBuiltin(id builtinId) *Builtin {
+ return &Builtin{object{name: predeclaredFuncs[id].name, typ: Typ[Invalid], color_: black}, id}
+}
+
+// Nil represents the predeclared value nil.
+type Nil struct {
+ object
+}
+
+func writeObject(buf *bytes.Buffer, obj Object, qf Qualifier) {
+ var tname *TypeName
+ typ := obj.Type()
+
+ switch obj := obj.(type) {
+ case *PkgName:
+ fmt.Fprintf(buf, "package %s", obj.Name())
+ if path := obj.imported.path; path != "" && path != obj.name {
+ fmt.Fprintf(buf, " (%q)", path)
+ }
+ return
+
+ case *Const:
+ buf.WriteString("const")
+
+ case *TypeName:
+ tname = obj
+ buf.WriteString("type")
+ if isTypeParam(typ) {
+ buf.WriteString(" parameter")
+ }
+
+ case *Var:
+ if obj.isField {
+ buf.WriteString("field")
+ } else {
+ buf.WriteString("var")
+ }
+
+ case *Func:
+ buf.WriteString("func ")
+ writeFuncName(buf, obj, qf)
+ if typ != nil {
+ WriteSignature(buf, typ.(*Signature), qf)
+ }
+ return
+
+ case *Label:
+ buf.WriteString("label")
+ typ = nil
+
+ case *Builtin:
+ buf.WriteString("builtin")
+ typ = nil
+
+ case *Nil:
+ buf.WriteString("nil")
+ return
+
+ default:
+ panic(fmt.Sprintf("writeObject(%T)", obj))
+ }
+
+ buf.WriteByte(' ')
+
+ // For package-level objects, qualify the name.
+ if obj.Pkg() != nil && obj.Pkg().scope.Lookup(obj.Name()) == obj {
+ buf.WriteString(packagePrefix(obj.Pkg(), qf))
+ }
+ buf.WriteString(obj.Name())
+
+ if typ == nil {
+ return
+ }
+
+ if tname != nil {
+ switch t := typ.(type) {
+ case *Basic:
+ // Don't print anything more for basic types since there's
+ // no more information.
+ return
+ case *Named:
+ if t.TypeParams().Len() > 0 {
+ newTypeWriter(buf, qf).tParamList(t.TypeParams().list())
+ }
+ }
+ if tname.IsAlias() {
+ buf.WriteString(" =")
+ } else if t, _ := typ.(*TypeParam); t != nil {
+ typ = t.bound
+ } else {
+ // TODO(gri) should this be fromRHS for *Named?
+ typ = under(typ)
+ }
+ }
+
+ // Special handling for any: because WriteType will format 'any' as 'any',
+ // resulting in the object string `type any = any` rather than `type any =
+ // interface{}`. To avoid this, swap in a different empty interface.
+ if obj == universeAny {
+ assert(Identical(typ, &emptyInterface))
+ typ = &emptyInterface
+ }
+
+ buf.WriteByte(' ')
+ WriteType(buf, typ, qf)
+}
+
+func packagePrefix(pkg *Package, qf Qualifier) string {
+ if pkg == nil {
+ return ""
+ }
+ var s string
+ if qf != nil {
+ s = qf(pkg)
+ } else {
+ s = pkg.Path()
+ }
+ if s != "" {
+ s += "."
+ }
+ return s
+}
+
+// ObjectString returns the string form of obj.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func ObjectString(obj Object, qf Qualifier) string {
+ var buf bytes.Buffer
+ writeObject(&buf, obj, qf)
+ return buf.String()
+}
+
+func (obj *PkgName) String() string { return ObjectString(obj, nil) }
+func (obj *Const) String() string { return ObjectString(obj, nil) }
+func (obj *TypeName) String() string { return ObjectString(obj, nil) }
+func (obj *Var) String() string { return ObjectString(obj, nil) }
+func (obj *Func) String() string { return ObjectString(obj, nil) }
+func (obj *Label) String() string { return ObjectString(obj, nil) }
+func (obj *Builtin) String() string { return ObjectString(obj, nil) }
+func (obj *Nil) String() string { return ObjectString(obj, nil) }
+
+func writeFuncName(buf *bytes.Buffer, f *Func, qf Qualifier) {
+ if f.typ != nil {
+ sig := f.typ.(*Signature)
+ if recv := sig.Recv(); recv != nil {
+ buf.WriteByte('(')
+ if _, ok := recv.Type().(*Interface); ok {
+ // gcimporter creates abstract methods of
+ // named interfaces using the interface type
+ // (not the named type) as the receiver.
+ // Don't print it in full.
+ buf.WriteString("interface")
+ } else {
+ WriteType(buf, recv.Type(), qf)
+ }
+ buf.WriteByte(')')
+ buf.WriteByte('.')
+ } else if f.pkg != nil {
+ buf.WriteString(packagePrefix(f.pkg, qf))
+ }
+ }
+ buf.WriteString(f.name)
+}
diff --git a/contrib/go/_std_1.21/src/go/types/objset.go b/contrib/go/_std_1.21/src/go/types/objset.go
new file mode 100644
index 0000000000..e6ea37566e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/objset.go
@@ -0,0 +1,33 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2013 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.
+
+// This file implements objsets.
+//
+// An objset is similar to a Scope but objset elements
+// are identified by their unique id, instead of their
+// object name.
+
+package types
+
+// An objset is a set of objects identified by their unique id.
+// The zero value for objset is a ready-to-use empty objset.
+type objset map[string]Object // initialized lazily
+
+// insert attempts to insert an object obj into objset s.
+// If s already contains an alternative object alt with
+// the same name, insert leaves s unchanged and returns alt.
+// Otherwise it inserts obj and returns nil.
+func (s *objset) insert(obj Object) Object {
+ id := obj.Id()
+ if alt := (*s)[id]; alt != nil {
+ return alt
+ }
+ if *s == nil {
+ *s = make(map[string]Object)
+ }
+ (*s)[id] = obj
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/go/types/operand.go b/contrib/go/_std_1.21/src/go/types/operand.go
new file mode 100644
index 0000000000..d7719fdaaf
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/operand.go
@@ -0,0 +1,374 @@
+// Copyright 2012 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.
+
+// This file defines operands and associated operations.
+
+package types
+
+import (
+ "bytes"
+ "go/ast"
+ "go/constant"
+ "go/token"
+ . "internal/types/errors"
+)
+
+// An operandMode specifies the (addressing) mode of an operand.
+type operandMode byte
+
+const (
+ invalid operandMode = iota // operand is invalid
+ novalue // operand represents no value (result of a function call w/o result)
+ builtin // operand is a built-in function
+ typexpr // operand is a type
+ constant_ // operand is a constant; the operand's typ is a Basic type
+ variable // operand is an addressable variable
+ mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
+ value // operand is a computed value
+ commaok // like value, but operand may be used in a comma,ok expression
+ commaerr // like commaok, but second value is error, not boolean
+ cgofunc // operand is a cgo function
+)
+
+var operandModeString = [...]string{
+ invalid: "invalid operand",
+ novalue: "no value",
+ builtin: "built-in",
+ typexpr: "type",
+ constant_: "constant",
+ variable: "variable",
+ mapindex: "map index expression",
+ value: "value",
+ commaok: "comma, ok expression",
+ commaerr: "comma, error expression",
+ cgofunc: "cgo function",
+}
+
+// An operand represents an intermediate value during type checking.
+// Operands have an (addressing) mode, the expression evaluating to
+// the operand, the operand's type, a value for constants, and an id
+// for built-in functions.
+// The zero value of operand is a ready to use invalid operand.
+type operand struct {
+ mode operandMode
+ expr ast.Expr
+ typ Type
+ val constant.Value
+ id builtinId
+}
+
+// Pos returns the position of the expression corresponding to x.
+// If x is invalid the position is nopos.
+func (x *operand) Pos() token.Pos {
+ // x.expr may not be set if x is invalid
+ if x.expr == nil {
+ return nopos
+ }
+ return x.expr.Pos()
+}
+
+// Operand string formats
+// (not all "untyped" cases can appear due to the type system,
+// but they fall out naturally here)
+//
+// mode format
+//
+// invalid <expr> ( <mode> )
+// novalue <expr> ( <mode> )
+// builtin <expr> ( <mode> )
+// typexpr <expr> ( <mode> )
+//
+// constant <expr> (<untyped kind> <mode> )
+// constant <expr> ( <mode> of type <typ>)
+// constant <expr> (<untyped kind> <mode> <val> )
+// constant <expr> ( <mode> <val> of type <typ>)
+//
+// variable <expr> (<untyped kind> <mode> )
+// variable <expr> ( <mode> of type <typ>)
+//
+// mapindex <expr> (<untyped kind> <mode> )
+// mapindex <expr> ( <mode> of type <typ>)
+//
+// value <expr> (<untyped kind> <mode> )
+// value <expr> ( <mode> of type <typ>)
+//
+// commaok <expr> (<untyped kind> <mode> )
+// commaok <expr> ( <mode> of type <typ>)
+//
+// commaerr <expr> (<untyped kind> <mode> )
+// commaerr <expr> ( <mode> of type <typ>)
+//
+// cgofunc <expr> (<untyped kind> <mode> )
+// cgofunc <expr> ( <mode> of type <typ>)
+func operandString(x *operand, qf Qualifier) string {
+ // special-case nil
+ if x.mode == value && x.typ == Typ[UntypedNil] {
+ return "nil"
+ }
+
+ var buf bytes.Buffer
+
+ var expr string
+ if x.expr != nil {
+ expr = ExprString(x.expr)
+ } else {
+ switch x.mode {
+ case builtin:
+ expr = predeclaredFuncs[x.id].name
+ case typexpr:
+ expr = TypeString(x.typ, qf)
+ case constant_:
+ expr = x.val.String()
+ }
+ }
+
+ // <expr> (
+ if expr != "" {
+ buf.WriteString(expr)
+ buf.WriteString(" (")
+ }
+
+ // <untyped kind>
+ hasType := false
+ switch x.mode {
+ case invalid, novalue, builtin, typexpr:
+ // no type
+ default:
+ // should have a type, but be cautious (don't crash during printing)
+ if x.typ != nil {
+ if isUntyped(x.typ) {
+ buf.WriteString(x.typ.(*Basic).name)
+ buf.WriteByte(' ')
+ break
+ }
+ hasType = true
+ }
+ }
+
+ // <mode>
+ buf.WriteString(operandModeString[x.mode])
+
+ // <val>
+ if x.mode == constant_ {
+ if s := x.val.String(); s != expr {
+ buf.WriteByte(' ')
+ buf.WriteString(s)
+ }
+ }
+
+ // <typ>
+ if hasType {
+ if x.typ != Typ[Invalid] {
+ var intro string
+ if isGeneric(x.typ) {
+ intro = " of generic type "
+ } else {
+ intro = " of type "
+ }
+ buf.WriteString(intro)
+ WriteType(&buf, x.typ, qf)
+ if tpar, _ := x.typ.(*TypeParam); tpar != nil {
+ buf.WriteString(" constrained by ")
+ WriteType(&buf, tpar.bound, qf) // do not compute interface type sets here
+ // If we have the type set and it's empty, say so for better error messages.
+ if hasEmptyTypeset(tpar) {
+ buf.WriteString(" with empty type set")
+ }
+ }
+ } else {
+ buf.WriteString(" with invalid type")
+ }
+ }
+
+ // )
+ if expr != "" {
+ buf.WriteByte(')')
+ }
+
+ return buf.String()
+}
+
+func (x *operand) String() string {
+ return operandString(x, nil)
+}
+
+// setConst sets x to the untyped constant for literal lit.
+func (x *operand) setConst(tok token.Token, lit string) {
+ var kind BasicKind
+ switch tok {
+ case token.INT:
+ kind = UntypedInt
+ case token.FLOAT:
+ kind = UntypedFloat
+ case token.IMAG:
+ kind = UntypedComplex
+ case token.CHAR:
+ kind = UntypedRune
+ case token.STRING:
+ kind = UntypedString
+ default:
+ unreachable()
+ }
+
+ val := constant.MakeFromLiteral(lit, tok, 0)
+ if val.Kind() == constant.Unknown {
+ x.mode = invalid
+ x.typ = Typ[Invalid]
+ return
+ }
+ x.mode = constant_
+ x.typ = Typ[kind]
+ x.val = val
+}
+
+// isNil reports whether x is the (untyped) nil value.
+func (x *operand) isNil() bool { return x.mode == value && x.typ == Typ[UntypedNil] }
+
+// assignableTo reports whether x is assignable to a variable of type T. If the
+// result is false and a non-nil cause is provided, it may be set to a more
+// detailed explanation of the failure (result != ""). The returned error code
+// is only valid if the (first) result is false. The check parameter may be nil
+// if assignableTo is invoked through an exported API call, i.e., when all
+// methods have been type-checked.
+func (x *operand) assignableTo(check *Checker, T Type, cause *string) (bool, Code) {
+ if x.mode == invalid || T == Typ[Invalid] {
+ return true, 0 // avoid spurious errors
+ }
+
+ V := x.typ
+
+ // x's type is identical to T
+ if Identical(V, T) {
+ return true, 0
+ }
+
+ Vu := under(V)
+ Tu := under(T)
+ Vp, _ := V.(*TypeParam)
+ Tp, _ := T.(*TypeParam)
+
+ // x is an untyped value representable by a value of type T.
+ if isUntyped(Vu) {
+ assert(Vp == nil)
+ if Tp != nil {
+ // T is a type parameter: x is assignable to T if it is
+ // representable by each specific type in the type set of T.
+ return Tp.is(func(t *term) bool {
+ if t == nil {
+ return false
+ }
+ // A term may be a tilde term but the underlying
+ // type of an untyped value doesn't change so we
+ // don't need to do anything special.
+ newType, _, _ := check.implicitTypeAndValue(x, t.typ)
+ return newType != nil
+ }), IncompatibleAssign
+ }
+ newType, _, _ := check.implicitTypeAndValue(x, T)
+ return newType != nil, IncompatibleAssign
+ }
+ // Vu is typed
+
+ // x's type V and T have identical underlying types
+ // and at least one of V or T is not a named type
+ // and neither V nor T is a type parameter.
+ if Identical(Vu, Tu) && (!hasName(V) || !hasName(T)) && Vp == nil && Tp == nil {
+ return true, 0
+ }
+
+ // T is an interface type, but not a type parameter, and V implements T.
+ // Also handle the case where T is a pointer to an interface so that we get
+ // the Checker.implements error cause.
+ if _, ok := Tu.(*Interface); ok && Tp == nil || isInterfacePtr(Tu) {
+ if check.implements(x.Pos(), V, T, false, cause) {
+ return true, 0
+ }
+ // V doesn't implement T but V may still be assignable to T if V
+ // is a type parameter; do not report an error in that case yet.
+ if Vp == nil {
+ return false, InvalidIfaceAssign
+ }
+ if cause != nil {
+ *cause = ""
+ }
+ }
+
+ // If V is an interface, check if a missing type assertion is the problem.
+ if Vi, _ := Vu.(*Interface); Vi != nil && Vp == nil {
+ if check.implements(x.Pos(), T, V, false, nil) {
+ // T implements V, so give hint about type assertion.
+ if cause != nil {
+ *cause = "need type assertion"
+ }
+ return false, IncompatibleAssign
+ }
+ }
+
+ // x is a bidirectional channel value, T is a channel
+ // type, x's type V and T have identical element types,
+ // and at least one of V or T is not a named type.
+ if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv {
+ if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) {
+ return !hasName(V) || !hasName(T), InvalidChanAssign
+ }
+ }
+
+ // optimization: if we don't have type parameters, we're done
+ if Vp == nil && Tp == nil {
+ return false, IncompatibleAssign
+ }
+
+ errorf := func(format string, args ...any) {
+ if check != nil && cause != nil {
+ msg := check.sprintf(format, args...)
+ if *cause != "" {
+ msg += "\n\t" + *cause
+ }
+ *cause = msg
+ }
+ }
+
+ // x's type V is not a named type and T is a type parameter, and
+ // x is assignable to each specific type in T's type set.
+ if !hasName(V) && Tp != nil {
+ ok := false
+ code := IncompatibleAssign
+ Tp.is(func(T *term) bool {
+ if T == nil {
+ return false // no specific types
+ }
+ ok, code = x.assignableTo(check, T.typ, cause)
+ if !ok {
+ errorf("cannot assign %s to %s (in %s)", x.typ, T.typ, Tp)
+ return false
+ }
+ return true
+ })
+ return ok, code
+ }
+
+ // x's type V is a type parameter and T is not a named type,
+ // and values x' of each specific type in V's type set are
+ // assignable to T.
+ if Vp != nil && !hasName(T) {
+ x := *x // don't clobber outer x
+ ok := false
+ code := IncompatibleAssign
+ Vp.is(func(V *term) bool {
+ if V == nil {
+ return false // no specific types
+ }
+ x.typ = V.typ
+ ok, code = x.assignableTo(check, T, cause)
+ if !ok {
+ errorf("cannot assign %s (in %s) to %s", V.typ, Vp, T)
+ return false
+ }
+ return true
+ })
+ return ok, code
+ }
+
+ return false, IncompatibleAssign
+}
diff --git a/contrib/go/_std_1.21/src/go/types/package.go b/contrib/go/_std_1.21/src/go/types/package.go
new file mode 100644
index 0000000000..0f52d5f489
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/package.go
@@ -0,0 +1,82 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2013 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 types
+
+import (
+ "fmt"
+)
+
+// A Package describes a Go package.
+type Package struct {
+ path string
+ name string
+ scope *Scope
+ imports []*Package
+ complete bool
+ fake bool // scope lookup errors are silently dropped if package is fake (internal use only)
+ cgo bool // uses of this package will be rewritten into uses of declarations from _cgo_gotypes.go
+ goVersion string // minimum Go version required for package (by Config.GoVersion, typically from go.mod)
+}
+
+// NewPackage returns a new Package for the given package path and name.
+// The package is not complete and contains no explicit imports.
+func NewPackage(path, name string) *Package {
+ scope := NewScope(Universe, nopos, nopos, fmt.Sprintf("package %q", path))
+ return &Package{path: path, name: name, scope: scope}
+}
+
+// Path returns the package path.
+func (pkg *Package) Path() string { return pkg.path }
+
+// Name returns the package name.
+func (pkg *Package) Name() string { return pkg.name }
+
+// SetName sets the package name.
+func (pkg *Package) SetName(name string) { pkg.name = name }
+
+// GoVersion returns the minimum Go version required by this package.
+// If the minimum version is unknown, GoVersion returns the empty string.
+// Individual source files may specify a different minimum Go version,
+// as reported in the [go/ast.File.GoVersion] field.
+func (pkg *Package) GoVersion() string { return pkg.goVersion }
+
+// Scope returns the (complete or incomplete) package scope
+// holding the objects declared at package level (TypeNames,
+// Consts, Vars, and Funcs).
+// For a nil pkg receiver, Scope returns the Universe scope.
+func (pkg *Package) Scope() *Scope {
+ if pkg != nil {
+ return pkg.scope
+ }
+ return Universe
+}
+
+// A package is complete if its scope contains (at least) all
+// exported objects; otherwise it is incomplete.
+func (pkg *Package) Complete() bool { return pkg.complete }
+
+// MarkComplete marks a package as complete.
+func (pkg *Package) MarkComplete() { pkg.complete = true }
+
+// Imports returns the list of packages directly imported by
+// pkg; the list is in source order.
+//
+// If pkg was loaded from export data, Imports includes packages that
+// provide package-level objects referenced by pkg. This may be more or
+// less than the set of packages directly imported by pkg's source code.
+//
+// If pkg uses cgo and the FakeImportC configuration option
+// was enabled, the imports list may contain a fake "C" package.
+func (pkg *Package) Imports() []*Package { return pkg.imports }
+
+// SetImports sets the list of explicitly imported packages to list.
+// It is the caller's responsibility to make sure list elements are unique.
+func (pkg *Package) SetImports(list []*Package) { pkg.imports = list }
+
+func (pkg *Package) String() string {
+ return fmt.Sprintf("package %s (%q)", pkg.name, pkg.path)
+}
diff --git a/contrib/go/_std_1.21/src/go/types/pointer.go b/contrib/go/_std_1.21/src/go/types/pointer.go
new file mode 100644
index 0000000000..5b45ab7755
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/pointer.go
@@ -0,0 +1,21 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2011 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 types
+
+// A Pointer represents a pointer type.
+type Pointer struct {
+ base Type // element type
+}
+
+// NewPointer returns a new pointer type for the given element (base) type.
+func NewPointer(elem Type) *Pointer { return &Pointer{base: elem} }
+
+// Elem returns the element type for the given pointer p.
+func (p *Pointer) Elem() Type { return p.base }
+
+func (p *Pointer) Underlying() Type { return p }
+func (p *Pointer) String() string { return TypeString(p, nil) }
diff --git a/contrib/go/_std_1.21/src/go/types/predicates.go b/contrib/go/_std_1.21/src/go/types/predicates.go
new file mode 100644
index 0000000000..b821b584c1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/predicates.go
@@ -0,0 +1,534 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2012 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.
+
+// This file implements commonly used type predicates.
+
+package types
+
+// The isX predicates below report whether t is an X.
+// If t is a type parameter the result is false; i.e.,
+// these predicates don't look inside a type parameter.
+
+func isBoolean(t Type) bool { return isBasic(t, IsBoolean) }
+func isInteger(t Type) bool { return isBasic(t, IsInteger) }
+func isUnsigned(t Type) bool { return isBasic(t, IsUnsigned) }
+func isFloat(t Type) bool { return isBasic(t, IsFloat) }
+func isComplex(t Type) bool { return isBasic(t, IsComplex) }
+func isNumeric(t Type) bool { return isBasic(t, IsNumeric) }
+func isString(t Type) bool { return isBasic(t, IsString) }
+func isIntegerOrFloat(t Type) bool { return isBasic(t, IsInteger|IsFloat) }
+func isConstType(t Type) bool { return isBasic(t, IsConstType) }
+
+// isBasic reports whether under(t) is a basic type with the specified info.
+// If t is a type parameter the result is false; i.e.,
+// isBasic does not look inside a type parameter.
+func isBasic(t Type, info BasicInfo) bool {
+ u, _ := under(t).(*Basic)
+ return u != nil && u.info&info != 0
+}
+
+// The allX predicates below report whether t is an X.
+// If t is a type parameter the result is true if isX is true
+// for all specified types of the type parameter's type set.
+// allX is an optimized version of isX(coreType(t)) (which
+// is the same as underIs(t, isX)).
+
+func allBoolean(t Type) bool { return allBasic(t, IsBoolean) }
+func allInteger(t Type) bool { return allBasic(t, IsInteger) }
+func allUnsigned(t Type) bool { return allBasic(t, IsUnsigned) }
+func allNumeric(t Type) bool { return allBasic(t, IsNumeric) }
+func allString(t Type) bool { return allBasic(t, IsString) }
+func allOrdered(t Type) bool { return allBasic(t, IsOrdered) }
+func allNumericOrString(t Type) bool { return allBasic(t, IsNumeric|IsString) }
+
+// allBasic reports whether under(t) is a basic type with the specified info.
+// If t is a type parameter, the result is true if isBasic(t, info) is true
+// for all specific types of the type parameter's type set.
+// allBasic(t, info) is an optimized version of isBasic(coreType(t), info).
+func allBasic(t Type, info BasicInfo) bool {
+ if tpar, _ := t.(*TypeParam); tpar != nil {
+ return tpar.is(func(t *term) bool { return t != nil && isBasic(t.typ, info) })
+ }
+ return isBasic(t, info)
+}
+
+// hasName reports whether t has a name. This includes
+// predeclared types, defined types, and type parameters.
+// hasName may be called with types that are not fully set up.
+func hasName(t Type) bool {
+ switch t.(type) {
+ case *Basic, *Named, *TypeParam:
+ return true
+ }
+ return false
+}
+
+// isTypeLit reports whether t is a type literal.
+// This includes all non-defined types, but also basic types.
+// isTypeLit may be called with types that are not fully set up.
+func isTypeLit(t Type) bool {
+ switch t.(type) {
+ case *Named, *TypeParam:
+ return false
+ }
+ return true
+}
+
+// isTyped reports whether t is typed; i.e., not an untyped
+// constant or boolean. isTyped may be called with types that
+// are not fully set up.
+func isTyped(t Type) bool {
+ // isTyped is called with types that are not fully
+ // set up. Must not call under()!
+ b, _ := t.(*Basic)
+ return b == nil || b.info&IsUntyped == 0
+}
+
+// isUntyped(t) is the same as !isTyped(t).
+func isUntyped(t Type) bool {
+ return !isTyped(t)
+}
+
+// IsInterface reports whether t is an interface type.
+func IsInterface(t Type) bool {
+ _, ok := under(t).(*Interface)
+ return ok
+}
+
+// isNonTypeParamInterface reports whether t is an interface type but not a type parameter.
+func isNonTypeParamInterface(t Type) bool {
+ return !isTypeParam(t) && IsInterface(t)
+}
+
+// isTypeParam reports whether t is a type parameter.
+func isTypeParam(t Type) bool {
+ _, ok := t.(*TypeParam)
+ return ok
+}
+
+// hasEmptyTypeset reports whether t is a type parameter with an empty type set.
+// The function does not force the computation of the type set and so is safe to
+// use anywhere, but it may report a false negative if the type set has not been
+// computed yet.
+func hasEmptyTypeset(t Type) bool {
+ if tpar, _ := t.(*TypeParam); tpar != nil && tpar.bound != nil {
+ iface, _ := safeUnderlying(tpar.bound).(*Interface)
+ return iface != nil && iface.tset != nil && iface.tset.IsEmpty()
+ }
+ return false
+}
+
+// isGeneric reports whether a type is a generic, uninstantiated type
+// (generic signatures are not included).
+// TODO(gri) should we include signatures or assert that they are not present?
+func isGeneric(t Type) bool {
+ // A parameterized type is only generic if it doesn't have an instantiation already.
+ named, _ := t.(*Named)
+ return named != nil && named.obj != nil && named.inst == nil && named.TypeParams().Len() > 0
+}
+
+// Comparable reports whether values of type T are comparable.
+func Comparable(T Type) bool {
+ return comparable(T, true, nil, nil)
+}
+
+// If dynamic is set, non-type parameter interfaces are always comparable.
+// If reportf != nil, it may be used to report why T is not comparable.
+func comparable(T Type, dynamic bool, seen map[Type]bool, reportf func(string, ...interface{})) bool {
+ if seen[T] {
+ return true
+ }
+ if seen == nil {
+ seen = make(map[Type]bool)
+ }
+ seen[T] = true
+
+ switch t := under(T).(type) {
+ case *Basic:
+ // assume invalid types to be comparable
+ // to avoid follow-up errors
+ return t.kind != UntypedNil
+ case *Pointer, *Chan:
+ return true
+ case *Struct:
+ for _, f := range t.fields {
+ if !comparable(f.typ, dynamic, seen, nil) {
+ if reportf != nil {
+ reportf("struct containing %s cannot be compared", f.typ)
+ }
+ return false
+ }
+ }
+ return true
+ case *Array:
+ if !comparable(t.elem, dynamic, seen, nil) {
+ if reportf != nil {
+ reportf("%s cannot be compared", t)
+ }
+ return false
+ }
+ return true
+ case *Interface:
+ if dynamic && !isTypeParam(T) || t.typeSet().IsComparable(seen) {
+ return true
+ }
+ if reportf != nil {
+ if t.typeSet().IsEmpty() {
+ reportf("empty type set")
+ } else {
+ reportf("incomparable types in type set")
+ }
+ }
+ // fallthrough
+ }
+ return false
+}
+
+// hasNil reports whether type t includes the nil value.
+func hasNil(t Type) bool {
+ switch u := under(t).(type) {
+ case *Basic:
+ return u.kind == UnsafePointer
+ case *Slice, *Pointer, *Signature, *Map, *Chan:
+ return true
+ case *Interface:
+ return !isTypeParam(t) || u.typeSet().underIs(func(u Type) bool {
+ return u != nil && hasNil(u)
+ })
+ }
+ return false
+}
+
+// An ifacePair is a node in a stack of interface type pairs compared for identity.
+type ifacePair struct {
+ x, y *Interface
+ prev *ifacePair
+}
+
+func (p *ifacePair) identical(q *ifacePair) bool {
+ return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
+}
+
+// A comparer is used to compare types.
+type comparer struct {
+ ignoreTags bool // if set, identical ignores struct tags
+ ignoreInvalids bool // if set, identical treats an invalid type as identical to any type
+}
+
+// For changes to this code the corresponding changes should be made to unifier.nify.
+func (c *comparer) identical(x, y Type, p *ifacePair) bool {
+ if x == y {
+ return true
+ }
+
+ if c.ignoreInvalids && (x == Typ[Invalid] || y == Typ[Invalid]) {
+ return true
+ }
+
+ switch x := x.(type) {
+ case *Basic:
+ // Basic types are singletons except for the rune and byte
+ // aliases, thus we cannot solely rely on the x == y check
+ // above. See also comment in TypeName.IsAlias.
+ if y, ok := y.(*Basic); ok {
+ return x.kind == y.kind
+ }
+
+ case *Array:
+ // Two array types are identical if they have identical element types
+ // and the same array length.
+ if y, ok := y.(*Array); ok {
+ // If one or both array lengths are unknown (< 0) due to some error,
+ // assume they are the same to avoid spurious follow-on errors.
+ return (x.len < 0 || y.len < 0 || x.len == y.len) && c.identical(x.elem, y.elem, p)
+ }
+
+ case *Slice:
+ // Two slice types are identical if they have identical element types.
+ if y, ok := y.(*Slice); ok {
+ return c.identical(x.elem, y.elem, p)
+ }
+
+ case *Struct:
+ // Two struct types are identical if they have the same sequence of fields,
+ // and if corresponding fields have the same names, and identical types,
+ // and identical tags. Two embedded fields are considered to have the same
+ // name. Lower-case field names from different packages are always different.
+ if y, ok := y.(*Struct); ok {
+ if x.NumFields() == y.NumFields() {
+ for i, f := range x.fields {
+ g := y.fields[i]
+ if f.embedded != g.embedded ||
+ !c.ignoreTags && x.Tag(i) != y.Tag(i) ||
+ !f.sameId(g.pkg, g.name) ||
+ !c.identical(f.typ, g.typ, p) {
+ return false
+ }
+ }
+ return true
+ }
+ }
+
+ case *Pointer:
+ // Two pointer types are identical if they have identical base types.
+ if y, ok := y.(*Pointer); ok {
+ return c.identical(x.base, y.base, p)
+ }
+
+ case *Tuple:
+ // Two tuples types are identical if they have the same number of elements
+ // and corresponding elements have identical types.
+ if y, ok := y.(*Tuple); ok {
+ if x.Len() == y.Len() {
+ if x != nil {
+ for i, v := range x.vars {
+ w := y.vars[i]
+ if !c.identical(v.typ, w.typ, p) {
+ return false
+ }
+ }
+ }
+ return true
+ }
+ }
+
+ case *Signature:
+ y, _ := y.(*Signature)
+ if y == nil {
+ return false
+ }
+
+ // Two function types are identical if they have the same number of
+ // parameters and result values, corresponding parameter and result types
+ // are identical, and either both functions are variadic or neither is.
+ // Parameter and result names are not required to match, and type
+ // parameters are considered identical modulo renaming.
+
+ if x.TypeParams().Len() != y.TypeParams().Len() {
+ return false
+ }
+
+ // In the case of generic signatures, we will substitute in yparams and
+ // yresults.
+ yparams := y.params
+ yresults := y.results
+
+ if x.TypeParams().Len() > 0 {
+ // We must ignore type parameter names when comparing x and y. The
+ // easiest way to do this is to substitute x's type parameters for y's.
+ xtparams := x.TypeParams().list()
+ ytparams := y.TypeParams().list()
+
+ var targs []Type
+ for i := range xtparams {
+ targs = append(targs, x.TypeParams().At(i))
+ }
+ smap := makeSubstMap(ytparams, targs)
+
+ var check *Checker // ok to call subst on a nil *Checker
+ ctxt := NewContext() // need a non-nil Context for the substitution below
+
+ // Constraints must be pair-wise identical, after substitution.
+ for i, xtparam := range xtparams {
+ ybound := check.subst(nopos, ytparams[i].bound, smap, nil, ctxt)
+ if !c.identical(xtparam.bound, ybound, p) {
+ return false
+ }
+ }
+
+ yparams = check.subst(nopos, y.params, smap, nil, ctxt).(*Tuple)
+ yresults = check.subst(nopos, y.results, smap, nil, ctxt).(*Tuple)
+ }
+
+ return x.variadic == y.variadic &&
+ c.identical(x.params, yparams, p) &&
+ c.identical(x.results, yresults, p)
+
+ case *Union:
+ if y, _ := y.(*Union); y != nil {
+ // TODO(rfindley): can this be reached during type checking? If so,
+ // consider passing a type set map.
+ unionSets := make(map[*Union]*_TypeSet)
+ xset := computeUnionTypeSet(nil, unionSets, nopos, x)
+ yset := computeUnionTypeSet(nil, unionSets, nopos, y)
+ return xset.terms.equal(yset.terms)
+ }
+
+ case *Interface:
+ // Two interface types are identical if they describe the same type sets.
+ // With the existing implementation restriction, this simplifies to:
+ //
+ // Two interface types are identical if they have the same set of methods with
+ // the same names and identical function types, and if any type restrictions
+ // are the same. Lower-case method names from different packages are always
+ // different. The order of the methods is irrelevant.
+ if y, ok := y.(*Interface); ok {
+ xset := x.typeSet()
+ yset := y.typeSet()
+ if xset.comparable != yset.comparable {
+ return false
+ }
+ if !xset.terms.equal(yset.terms) {
+ return false
+ }
+ a := xset.methods
+ b := yset.methods
+ if len(a) == len(b) {
+ // Interface types are the only types where cycles can occur
+ // that are not "terminated" via named types; and such cycles
+ // can only be created via method parameter types that are
+ // anonymous interfaces (directly or indirectly) embedding
+ // the current interface. Example:
+ //
+ // type T interface {
+ // m() interface{T}
+ // }
+ //
+ // If two such (differently named) interfaces are compared,
+ // endless recursion occurs if the cycle is not detected.
+ //
+ // If x and y were compared before, they must be equal
+ // (if they were not, the recursion would have stopped);
+ // search the ifacePair stack for the same pair.
+ //
+ // This is a quadratic algorithm, but in practice these stacks
+ // are extremely short (bounded by the nesting depth of interface
+ // type declarations that recur via parameter types, an extremely
+ // rare occurrence). An alternative implementation might use a
+ // "visited" map, but that is probably less efficient overall.
+ q := &ifacePair{x, y, p}
+ for p != nil {
+ if p.identical(q) {
+ return true // same pair was compared before
+ }
+ p = p.prev
+ }
+ if debug {
+ assertSortedMethods(a)
+ assertSortedMethods(b)
+ }
+ for i, f := range a {
+ g := b[i]
+ if f.Id() != g.Id() || !c.identical(f.typ, g.typ, q) {
+ return false
+ }
+ }
+ return true
+ }
+ }
+
+ case *Map:
+ // Two map types are identical if they have identical key and value types.
+ if y, ok := y.(*Map); ok {
+ return c.identical(x.key, y.key, p) && c.identical(x.elem, y.elem, p)
+ }
+
+ case *Chan:
+ // Two channel types are identical if they have identical value types
+ // and the same direction.
+ if y, ok := y.(*Chan); ok {
+ return x.dir == y.dir && c.identical(x.elem, y.elem, p)
+ }
+
+ case *Named:
+ // Two named types are identical if their type names originate
+ // in the same type declaration; if they are instantiated they
+ // must have identical type argument lists.
+ if y, ok := y.(*Named); ok {
+ // check type arguments before origins to match unifier
+ // (for correct source code we need to do all checks so
+ // order doesn't matter)
+ xargs := x.TypeArgs().list()
+ yargs := y.TypeArgs().list()
+ if len(xargs) != len(yargs) {
+ return false
+ }
+ for i, xarg := range xargs {
+ if !Identical(xarg, yargs[i]) {
+ return false
+ }
+ }
+ return indenticalOrigin(x, y)
+ }
+
+ case *TypeParam:
+ // nothing to do (x and y being equal is caught in the very beginning of this function)
+
+ case nil:
+ // avoid a crash in case of nil type
+
+ default:
+ unreachable()
+ }
+
+ return false
+}
+
+// identicalOrigin reports whether x and y originated in the same declaration.
+func indenticalOrigin(x, y *Named) bool {
+ // TODO(gri) is this correct?
+ return x.Origin().obj == y.Origin().obj
+}
+
+// identicalInstance reports if two type instantiations are identical.
+// Instantiations are identical if their origin and type arguments are
+// identical.
+func identicalInstance(xorig Type, xargs []Type, yorig Type, yargs []Type) bool {
+ if len(xargs) != len(yargs) {
+ return false
+ }
+
+ for i, xa := range xargs {
+ if !Identical(xa, yargs[i]) {
+ return false
+ }
+ }
+
+ return Identical(xorig, yorig)
+}
+
+// Default returns the default "typed" type for an "untyped" type;
+// it returns the incoming type for all other types. The default type
+// for untyped nil is untyped nil.
+func Default(t Type) Type {
+ if t, ok := t.(*Basic); ok {
+ switch t.kind {
+ case UntypedBool:
+ return Typ[Bool]
+ case UntypedInt:
+ return Typ[Int]
+ case UntypedRune:
+ return universeRune // use 'rune' name
+ case UntypedFloat:
+ return Typ[Float64]
+ case UntypedComplex:
+ return Typ[Complex128]
+ case UntypedString:
+ return Typ[String]
+ }
+ }
+ return t
+}
+
+// maxType returns the "largest" type that encompasses both x and y.
+// If x and y are different untyped numeric types, the result is the type of x or y
+// that appears later in this list: integer, rune, floating-point, complex.
+// Otherwise, if x != y, the result is nil.
+func maxType(x, y Type) Type {
+ // We only care about untyped types (for now), so == is good enough.
+ // TODO(gri) investigate generalizing this function to simplify code elsewhere
+ if x == y {
+ return x
+ }
+ if isUntyped(x) && isUntyped(y) && isNumeric(x) && isNumeric(y) {
+ // untyped types are basic types
+ if x.(*Basic).kind > y.(*Basic).kind {
+ return x
+ }
+ return y
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/go/types/resolver.go b/contrib/go/_std_1.21/src/go/types/resolver.go
new file mode 100644
index 0000000000..6397b394d1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/resolver.go
@@ -0,0 +1,751 @@
+// Copyright 2013 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 types
+
+import (
+ "fmt"
+ "go/ast"
+ "go/constant"
+ "go/internal/typeparams"
+ "go/token"
+ . "internal/types/errors"
+ "sort"
+ "strconv"
+ "strings"
+ "unicode"
+)
+
+// A declInfo describes a package-level const, type, var, or func declaration.
+type declInfo struct {
+ file *Scope // scope of file containing this declaration
+ lhs []*Var // lhs of n:1 variable declarations, or nil
+ vtyp ast.Expr // type, or nil (for const and var declarations only)
+ init ast.Expr // init/orig expression, or nil (for const and var declarations only)
+ inherited bool // if set, the init expression is inherited from a previous constant declaration
+ tdecl *ast.TypeSpec // type declaration, or nil
+ fdecl *ast.FuncDecl // func declaration, or nil
+
+ // The deps field tracks initialization expression dependencies.
+ deps map[Object]bool // lazily initialized
+}
+
+// hasInitializer reports whether the declared object has an initialization
+// expression or function body.
+func (d *declInfo) hasInitializer() bool {
+ return d.init != nil || d.fdecl != nil && d.fdecl.Body != nil
+}
+
+// addDep adds obj to the set of objects d's init expression depends on.
+func (d *declInfo) addDep(obj Object) {
+ m := d.deps
+ if m == nil {
+ m = make(map[Object]bool)
+ d.deps = m
+ }
+ m[obj] = true
+}
+
+// arityMatch checks that the lhs and rhs of a const or var decl
+// have the appropriate number of names and init exprs. For const
+// decls, init is the value spec providing the init exprs; for
+// var decls, init is nil (the init exprs are in s in this case).
+func (check *Checker) arityMatch(s, init *ast.ValueSpec) {
+ l := len(s.Names)
+ r := len(s.Values)
+ if init != nil {
+ r = len(init.Values)
+ }
+
+ const code = WrongAssignCount
+ switch {
+ case init == nil && r == 0:
+ // var decl w/o init expr
+ if s.Type == nil {
+ check.error(s, code, "missing type or init expr")
+ }
+ case l < r:
+ if l < len(s.Values) {
+ // init exprs from s
+ n := s.Values[l]
+ check.errorf(n, code, "extra init expr %s", n)
+ // TODO(gri) avoid declared and not used error here
+ } else {
+ // init exprs "inherited"
+ check.errorf(s, code, "extra init expr at %s", check.fset.Position(init.Pos()))
+ // TODO(gri) avoid declared and not used error here
+ }
+ case l > r && (init != nil || r != 1):
+ n := s.Names[r]
+ check.errorf(n, code, "missing init expr for %s", n)
+ }
+}
+
+func validatedImportPath(path string) (string, error) {
+ s, err := strconv.Unquote(path)
+ if err != nil {
+ return "", err
+ }
+ if s == "" {
+ return "", fmt.Errorf("empty string")
+ }
+ const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
+ for _, r := range s {
+ if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
+ return s, fmt.Errorf("invalid character %#U", r)
+ }
+ }
+ return s, nil
+}
+
+// declarePkgObj declares obj in the package scope, records its ident -> obj mapping,
+// and updates check.objMap. The object must not be a function or method.
+func (check *Checker) declarePkgObj(ident *ast.Ident, obj Object, d *declInfo) {
+ assert(ident.Name == obj.Name())
+
+ // spec: "A package-scope or file-scope identifier with name init
+ // may only be declared to be a function with this (func()) signature."
+ if ident.Name == "init" {
+ check.error(ident, InvalidInitDecl, "cannot declare init - must be func")
+ return
+ }
+
+ // spec: "The main package must have package name main and declare
+ // a function main that takes no arguments and returns no value."
+ if ident.Name == "main" && check.pkg.name == "main" {
+ check.error(ident, InvalidMainDecl, "cannot declare main - must be func")
+ return
+ }
+
+ check.declare(check.pkg.scope, ident, obj, nopos)
+ check.objMap[obj] = d
+ obj.setOrder(uint32(len(check.objMap)))
+}
+
+// filename returns a filename suitable for debugging output.
+func (check *Checker) filename(fileNo int) string {
+ file := check.files[fileNo]
+ if pos := file.Pos(); pos.IsValid() {
+ return check.fset.File(pos).Name()
+ }
+ return fmt.Sprintf("file[%d]", fileNo)
+}
+
+func (check *Checker) importPackage(at positioner, path, dir string) *Package {
+ // If we already have a package for the given (path, dir)
+ // pair, use it instead of doing a full import.
+ // Checker.impMap only caches packages that are marked Complete
+ // or fake (dummy packages for failed imports). Incomplete but
+ // non-fake packages do require an import to complete them.
+ key := importKey{path, dir}
+ imp := check.impMap[key]
+ if imp != nil {
+ return imp
+ }
+
+ // no package yet => import it
+ if path == "C" && (check.conf.FakeImportC || check.conf.go115UsesCgo) {
+ imp = NewPackage("C", "C")
+ imp.fake = true // package scope is not populated
+ imp.cgo = check.conf.go115UsesCgo
+ } else {
+ // ordinary import
+ var err error
+ if importer := check.conf.Importer; importer == nil {
+ err = fmt.Errorf("Config.Importer not installed")
+ } else if importerFrom, ok := importer.(ImporterFrom); ok {
+ imp, err = importerFrom.ImportFrom(path, dir, 0)
+ if imp == nil && err == nil {
+ err = fmt.Errorf("Config.Importer.ImportFrom(%s, %s, 0) returned nil but no error", path, dir)
+ }
+ } else {
+ imp, err = importer.Import(path)
+ if imp == nil && err == nil {
+ err = fmt.Errorf("Config.Importer.Import(%s) returned nil but no error", path)
+ }
+ }
+ // make sure we have a valid package name
+ // (errors here can only happen through manipulation of packages after creation)
+ if err == nil && imp != nil && (imp.name == "_" || imp.name == "") {
+ err = fmt.Errorf("invalid package name: %q", imp.name)
+ imp = nil // create fake package below
+ }
+ if err != nil {
+ check.errorf(at, BrokenImport, "could not import %s (%s)", path, err)
+ if imp == nil {
+ // create a new fake package
+ // come up with a sensible package name (heuristic)
+ name := path
+ if i := len(name); i > 0 && name[i-1] == '/' {
+ name = name[:i-1]
+ }
+ if i := strings.LastIndex(name, "/"); i >= 0 {
+ name = name[i+1:]
+ }
+ imp = NewPackage(path, name)
+ }
+ // continue to use the package as best as we can
+ imp.fake = true // avoid follow-up lookup failures
+ }
+ }
+
+ // package should be complete or marked fake, but be cautious
+ if imp.complete || imp.fake {
+ check.impMap[key] = imp
+ // Once we've formatted an error message, keep the pkgPathMap
+ // up-to-date on subsequent imports. It is used for package
+ // qualification in error messages.
+ if check.pkgPathMap != nil {
+ check.markImports(imp)
+ }
+ return imp
+ }
+
+ // something went wrong (importer may have returned incomplete package without error)
+ return nil
+}
+
+// collectObjects collects all file and package objects and inserts them
+// into their respective scopes. It also performs imports and associates
+// methods with receiver base type names.
+func (check *Checker) collectObjects() {
+ pkg := check.pkg
+
+ // pkgImports is the set of packages already imported by any package file seen
+ // so far. Used to avoid duplicate entries in pkg.imports. Allocate and populate
+ // it (pkg.imports may not be empty if we are checking test files incrementally).
+ // Note that pkgImports is keyed by package (and thus package path), not by an
+ // importKey value. Two different importKey values may map to the same package
+ // which is why we cannot use the check.impMap here.
+ var pkgImports = make(map[*Package]bool)
+ for _, imp := range pkg.imports {
+ pkgImports[imp] = true
+ }
+
+ type methodInfo struct {
+ obj *Func // method
+ ptr bool // true if pointer receiver
+ recv *ast.Ident // receiver type name
+ }
+ var methods []methodInfo // collected methods with valid receivers and non-blank _ names
+ var fileScopes []*Scope
+ for fileNo, file := range check.files {
+ // The package identifier denotes the current package,
+ // but there is no corresponding package object.
+ check.recordDef(file.Name, nil)
+
+ // Use the actual source file extent rather than *ast.File extent since the
+ // latter doesn't include comments which appear at the start or end of the file.
+ // Be conservative and use the *ast.File extent if we don't have a *token.File.
+ pos, end := file.Pos(), file.End()
+ if f := check.fset.File(file.Pos()); f != nil {
+ pos, end = token.Pos(f.Base()), token.Pos(f.Base()+f.Size())
+ }
+ fileScope := NewScope(pkg.scope, pos, end, check.filename(fileNo))
+ fileScopes = append(fileScopes, fileScope)
+ check.recordScope(file, fileScope)
+
+ // determine file directory, necessary to resolve imports
+ // FileName may be "" (typically for tests) in which case
+ // we get "." as the directory which is what we would want.
+ fileDir := dir(check.fset.Position(file.Name.Pos()).Filename)
+
+ check.walkDecls(file.Decls, func(d decl) {
+ switch d := d.(type) {
+ case importDecl:
+ // import package
+ if d.spec.Path.Value == "" {
+ return // error reported by parser
+ }
+ path, err := validatedImportPath(d.spec.Path.Value)
+ if err != nil {
+ check.errorf(d.spec.Path, BadImportPath, "invalid import path (%s)", err)
+ return
+ }
+
+ imp := check.importPackage(d.spec.Path, path, fileDir)
+ if imp == nil {
+ return
+ }
+
+ // local name overrides imported package name
+ name := imp.name
+ if d.spec.Name != nil {
+ name = d.spec.Name.Name
+ if path == "C" {
+ // match 1.17 cmd/compile (not prescribed by spec)
+ check.error(d.spec.Name, ImportCRenamed, `cannot rename import "C"`)
+ return
+ }
+ }
+
+ if name == "init" {
+ check.error(d.spec, InvalidInitDecl, "cannot import package as init - init must be a func")
+ return
+ }
+
+ // add package to list of explicit imports
+ // (this functionality is provided as a convenience
+ // for clients; it is not needed for type-checking)
+ if !pkgImports[imp] {
+ pkgImports[imp] = true
+ pkg.imports = append(pkg.imports, imp)
+ }
+
+ pkgName := NewPkgName(d.spec.Pos(), pkg, name, imp)
+ if d.spec.Name != nil {
+ // in a dot-import, the dot represents the package
+ check.recordDef(d.spec.Name, pkgName)
+ } else {
+ check.recordImplicit(d.spec, pkgName)
+ }
+
+ if imp.fake {
+ // match 1.17 cmd/compile (not prescribed by spec)
+ pkgName.used = true
+ }
+
+ // add import to file scope
+ check.imports = append(check.imports, pkgName)
+ if name == "." {
+ // dot-import
+ if check.dotImportMap == nil {
+ check.dotImportMap = make(map[dotImportKey]*PkgName)
+ }
+ // merge imported scope with file scope
+ for name, obj := range imp.scope.elems {
+ // Note: Avoid eager resolve(name, obj) here, so we only
+ // resolve dot-imported objects as needed.
+
+ // A package scope may contain non-exported objects,
+ // do not import them!
+ if token.IsExported(name) {
+ // declare dot-imported object
+ // (Do not use check.declare because it modifies the object
+ // via Object.setScopePos, which leads to a race condition;
+ // the object may be imported into more than one file scope
+ // concurrently. See go.dev/issue/32154.)
+ if alt := fileScope.Lookup(name); alt != nil {
+ check.errorf(d.spec.Name, DuplicateDecl, "%s redeclared in this block", alt.Name())
+ check.reportAltDecl(alt)
+ } else {
+ fileScope.insert(name, obj)
+ check.dotImportMap[dotImportKey{fileScope, name}] = pkgName
+ }
+ }
+ }
+ } else {
+ // declare imported package object in file scope
+ // (no need to provide s.Name since we called check.recordDef earlier)
+ check.declare(fileScope, nil, pkgName, nopos)
+ }
+ case constDecl:
+ // declare all constants
+ for i, name := range d.spec.Names {
+ obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(d.iota)))
+
+ var init ast.Expr
+ if i < len(d.init) {
+ init = d.init[i]
+ }
+
+ d := &declInfo{file: fileScope, vtyp: d.typ, init: init, inherited: d.inherited}
+ check.declarePkgObj(name, obj, d)
+ }
+
+ case varDecl:
+ lhs := make([]*Var, len(d.spec.Names))
+ // If there's exactly one rhs initializer, use
+ // the same declInfo d1 for all lhs variables
+ // so that each lhs variable depends on the same
+ // rhs initializer (n:1 var declaration).
+ var d1 *declInfo
+ if len(d.spec.Values) == 1 {
+ // The lhs elements are only set up after the for loop below,
+ // but that's ok because declareVar only collects the declInfo
+ // for a later phase.
+ d1 = &declInfo{file: fileScope, lhs: lhs, vtyp: d.spec.Type, init: d.spec.Values[0]}
+ }
+
+ // declare all variables
+ for i, name := range d.spec.Names {
+ obj := NewVar(name.Pos(), pkg, name.Name, nil)
+ lhs[i] = obj
+
+ di := d1
+ if di == nil {
+ // individual assignments
+ var init ast.Expr
+ if i < len(d.spec.Values) {
+ init = d.spec.Values[i]
+ }
+ di = &declInfo{file: fileScope, vtyp: d.spec.Type, init: init}
+ }
+
+ check.declarePkgObj(name, obj, di)
+ }
+ case typeDecl:
+ _ = d.spec.TypeParams.NumFields() != 0 && check.verifyVersionf(d.spec.TypeParams.List[0], go1_18, "type parameter")
+ obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil)
+ check.declarePkgObj(d.spec.Name, obj, &declInfo{file: fileScope, tdecl: d.spec})
+ case funcDecl:
+ name := d.decl.Name.Name
+ obj := NewFunc(d.decl.Name.Pos(), pkg, name, nil)
+ hasTParamError := false // avoid duplicate type parameter errors
+ if d.decl.Recv.NumFields() == 0 {
+ // regular function
+ if d.decl.Recv != nil {
+ check.error(d.decl.Recv, BadRecv, "method has no receiver")
+ // treat as function
+ }
+ if name == "init" || (name == "main" && check.pkg.name == "main") {
+ code := InvalidInitDecl
+ if name == "main" {
+ code = InvalidMainDecl
+ }
+ if d.decl.Type.TypeParams.NumFields() != 0 {
+ check.softErrorf(d.decl.Type.TypeParams.List[0], code, "func %s must have no type parameters", name)
+ hasTParamError = true
+ }
+ if t := d.decl.Type; t.Params.NumFields() != 0 || t.Results != nil {
+ // TODO(rFindley) Should this be a hard error?
+ check.softErrorf(d.decl.Name, code, "func %s must have no arguments and no return values", name)
+ }
+ }
+ if name == "init" {
+ // don't declare init functions in the package scope - they are invisible
+ obj.parent = pkg.scope
+ check.recordDef(d.decl.Name, obj)
+ // init functions must have a body
+ if d.decl.Body == nil {
+ // TODO(gri) make this error message consistent with the others above
+ check.softErrorf(obj, MissingInitBody, "missing function body")
+ }
+ } else {
+ check.declare(pkg.scope, d.decl.Name, obj, nopos)
+ }
+ } else {
+ // method
+
+ // TODO(rFindley) earlier versions of this code checked that methods
+ // have no type parameters, but this is checked later
+ // when type checking the function type. Confirm that
+ // we don't need to check tparams here.
+
+ ptr, recv, _ := check.unpackRecv(d.decl.Recv.List[0].Type, false)
+ // (Methods with invalid receiver cannot be associated to a type, and
+ // methods with blank _ names are never found; no need to collect any
+ // of them. They will still be type-checked with all the other functions.)
+ if recv != nil && name != "_" {
+ methods = append(methods, methodInfo{obj, ptr, recv})
+ }
+ check.recordDef(d.decl.Name, obj)
+ }
+ _ = d.decl.Type.TypeParams.NumFields() != 0 && !hasTParamError && check.verifyVersionf(d.decl.Type.TypeParams.List[0], go1_18, "type parameter")
+ info := &declInfo{file: fileScope, fdecl: d.decl}
+ // Methods are not package-level objects but we still track them in the
+ // object map so that we can handle them like regular functions (if the
+ // receiver is invalid); also we need their fdecl info when associating
+ // them with their receiver base type, below.
+ check.objMap[obj] = info
+ obj.setOrder(uint32(len(check.objMap)))
+ }
+ })
+ }
+
+ // verify that objects in package and file scopes have different names
+ for _, scope := range fileScopes {
+ for name, obj := range scope.elems {
+ if alt := pkg.scope.Lookup(name); alt != nil {
+ obj = resolve(name, obj)
+ if pkg, ok := obj.(*PkgName); ok {
+ check.errorf(alt, DuplicateDecl, "%s already declared through import of %s", alt.Name(), pkg.Imported())
+ check.reportAltDecl(pkg)
+ } else {
+ check.errorf(alt, DuplicateDecl, "%s already declared through dot-import of %s", alt.Name(), obj.Pkg())
+ // TODO(gri) dot-imported objects don't have a position; reportAltDecl won't print anything
+ check.reportAltDecl(obj)
+ }
+ }
+ }
+ }
+
+ // Now that we have all package scope objects and all methods,
+ // associate methods with receiver base type name where possible.
+ // Ignore methods that have an invalid receiver. They will be
+ // type-checked later, with regular functions.
+ if methods == nil {
+ return // nothing to do
+ }
+ check.methods = make(map[*TypeName][]*Func)
+ for i := range methods {
+ m := &methods[i]
+ // Determine the receiver base type and associate m with it.
+ ptr, base := check.resolveBaseTypeName(m.ptr, m.recv, fileScopes)
+ if base != nil {
+ m.obj.hasPtrRecv_ = ptr
+ check.methods[base] = append(check.methods[base], m.obj)
+ }
+ }
+}
+
+// unpackRecv unpacks a receiver type and returns its components: ptr indicates whether
+// rtyp is a pointer receiver, rname is the receiver type name, and tparams are its
+// type parameters, if any. The type parameters are only unpacked if unpackParams is
+// set. If rname is nil, the receiver is unusable (i.e., the source has a bug which we
+// cannot easily work around).
+func (check *Checker) unpackRecv(rtyp ast.Expr, unpackParams bool) (ptr bool, rname *ast.Ident, tparams []*ast.Ident) {
+L: // unpack receiver type
+ // This accepts invalid receivers such as ***T and does not
+ // work for other invalid receivers, but we don't care. The
+ // validity of receiver expressions is checked elsewhere.
+ for {
+ switch t := rtyp.(type) {
+ case *ast.ParenExpr:
+ rtyp = t.X
+ case *ast.StarExpr:
+ ptr = true
+ rtyp = t.X
+ default:
+ break L
+ }
+ }
+
+ // unpack type parameters, if any
+ switch rtyp.(type) {
+ case *ast.IndexExpr, *ast.IndexListExpr:
+ ix := typeparams.UnpackIndexExpr(rtyp)
+ rtyp = ix.X
+ if unpackParams {
+ for _, arg := range ix.Indices {
+ var par *ast.Ident
+ switch arg := arg.(type) {
+ case *ast.Ident:
+ par = arg
+ case *ast.BadExpr:
+ // ignore - error already reported by parser
+ case nil:
+ check.error(ix.Orig, InvalidSyntaxTree, "parameterized receiver contains nil parameters")
+ default:
+ check.errorf(arg, BadDecl, "receiver type parameter %s must be an identifier", arg)
+ }
+ if par == nil {
+ par = &ast.Ident{NamePos: arg.Pos(), Name: "_"}
+ }
+ tparams = append(tparams, par)
+ }
+ }
+ }
+
+ // unpack receiver name
+ if name, _ := rtyp.(*ast.Ident); name != nil {
+ rname = name
+ }
+
+ return
+}
+
+// resolveBaseTypeName returns the non-alias base type name for typ, and whether
+// there was a pointer indirection to get to it. The base type name must be declared
+// in package scope, and there can be at most one pointer indirection. If no such type
+// name exists, the returned base is nil.
+func (check *Checker) resolveBaseTypeName(seenPtr bool, typ ast.Expr, fileScopes []*Scope) (ptr bool, base *TypeName) {
+ // Algorithm: Starting from a type expression, which may be a name,
+ // we follow that type through alias declarations until we reach a
+ // non-alias type name. If we encounter anything but pointer types or
+ // parentheses we're done. If we encounter more than one pointer type
+ // we're done.
+ ptr = seenPtr
+ var seen map[*TypeName]bool
+ for {
+ // Note: this differs from types2, but is necessary. The syntax parser
+ // strips unnecessary parens.
+ typ = unparen(typ)
+
+ // check if we have a pointer type
+ if pexpr, _ := typ.(*ast.StarExpr); pexpr != nil {
+ // if we've already seen a pointer, we're done
+ if ptr {
+ return false, nil
+ }
+ ptr = true
+ typ = unparen(pexpr.X) // continue with pointer base type
+ }
+
+ // typ must be a name, or a C.name cgo selector.
+ var name string
+ switch typ := typ.(type) {
+ case *ast.Ident:
+ name = typ.Name
+ case *ast.SelectorExpr:
+ // C.struct_foo is a valid type name for packages using cgo.
+ //
+ // Detect this case, and adjust name so that the correct TypeName is
+ // resolved below.
+ if ident, _ := typ.X.(*ast.Ident); ident != nil && ident.Name == "C" {
+ // Check whether "C" actually resolves to an import of "C", by looking
+ // in the appropriate file scope.
+ var obj Object
+ for _, scope := range fileScopes {
+ if scope.Contains(ident.Pos()) {
+ obj = scope.Lookup(ident.Name)
+ }
+ }
+ // If Config.go115UsesCgo is set, the typechecker will resolve Cgo
+ // selectors to their cgo name. We must do the same here.
+ if pname, _ := obj.(*PkgName); pname != nil {
+ if pname.imported.cgo { // only set if Config.go115UsesCgo is set
+ name = "_Ctype_" + typ.Sel.Name
+ }
+ }
+ }
+ if name == "" {
+ return false, nil
+ }
+ default:
+ return false, nil
+ }
+
+ // name must denote an object found in the current package scope
+ // (note that dot-imported objects are not in the package scope!)
+ obj := check.pkg.scope.Lookup(name)
+ if obj == nil {
+ return false, nil
+ }
+
+ // the object must be a type name...
+ tname, _ := obj.(*TypeName)
+ if tname == nil {
+ return false, nil
+ }
+
+ // ... which we have not seen before
+ if seen[tname] {
+ return false, nil
+ }
+
+ // we're done if tdecl defined tname as a new type
+ // (rather than an alias)
+ tdecl := check.objMap[tname].tdecl // must exist for objects in package scope
+ if !tdecl.Assign.IsValid() {
+ return ptr, tname
+ }
+
+ // otherwise, continue resolving
+ typ = tdecl.Type
+ if seen == nil {
+ seen = make(map[*TypeName]bool)
+ }
+ seen[tname] = true
+ }
+}
+
+// packageObjects typechecks all package objects, but not function bodies.
+func (check *Checker) packageObjects() {
+ // process package objects in source order for reproducible results
+ objList := make([]Object, len(check.objMap))
+ i := 0
+ for obj := range check.objMap {
+ objList[i] = obj
+ i++
+ }
+ sort.Sort(inSourceOrder(objList))
+
+ // add new methods to already type-checked types (from a prior Checker.Files call)
+ for _, obj := range objList {
+ if obj, _ := obj.(*TypeName); obj != nil && obj.typ != nil {
+ check.collectMethods(obj)
+ }
+ }
+
+ // We process non-alias type declarations first, followed by alias declarations,
+ // and then everything else. This appears to avoid most situations where the type
+ // of an alias is needed before it is available.
+ // There may still be cases where this is not good enough (see also go.dev/issue/25838).
+ // In those cases Checker.ident will report an error ("invalid use of type alias").
+ var aliasList []*TypeName
+ var othersList []Object // everything that's not a type
+ // phase 1: non-alias type declarations
+ for _, obj := range objList {
+ if tname, _ := obj.(*TypeName); tname != nil {
+ if check.objMap[tname].tdecl.Assign.IsValid() {
+ aliasList = append(aliasList, tname)
+ } else {
+ check.objDecl(obj, nil)
+ }
+ } else {
+ othersList = append(othersList, obj)
+ }
+ }
+ // phase 2: alias type declarations
+ for _, obj := range aliasList {
+ check.objDecl(obj, nil)
+ }
+ // phase 3: all other declarations
+ for _, obj := range othersList {
+ check.objDecl(obj, nil)
+ }
+
+ // At this point we may have a non-empty check.methods map; this means that not all
+ // entries were deleted at the end of typeDecl because the respective receiver base
+ // types were not found. In that case, an error was reported when declaring those
+ // methods. We can now safely discard this map.
+ check.methods = nil
+}
+
+// inSourceOrder implements the sort.Sort interface.
+type inSourceOrder []Object
+
+func (a inSourceOrder) Len() int { return len(a) }
+func (a inSourceOrder) Less(i, j int) bool { return a[i].order() < a[j].order() }
+func (a inSourceOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+// unusedImports checks for unused imports.
+func (check *Checker) unusedImports() {
+ // If function bodies are not checked, packages' uses are likely missing - don't check.
+ if check.conf.IgnoreFuncBodies {
+ return
+ }
+
+ // spec: "It is illegal (...) to directly import a package without referring to
+ // any of its exported identifiers. To import a package solely for its side-effects
+ // (initialization), use the blank identifier as explicit package name."
+
+ for _, obj := range check.imports {
+ if !obj.used && obj.name != "_" {
+ check.errorUnusedPkg(obj)
+ }
+ }
+}
+
+func (check *Checker) errorUnusedPkg(obj *PkgName) {
+ // If the package was imported with a name other than the final
+ // import path element, show it explicitly in the error message.
+ // Note that this handles both renamed imports and imports of
+ // packages containing unconventional package declarations.
+ // Note that this uses / always, even on Windows, because Go import
+ // paths always use forward slashes.
+ path := obj.imported.path
+ elem := path
+ if i := strings.LastIndex(elem, "/"); i >= 0 {
+ elem = elem[i+1:]
+ }
+ if obj.name == "" || obj.name == "." || obj.name == elem {
+ check.softErrorf(obj, UnusedImport, "%q imported and not used", path)
+ } else {
+ check.softErrorf(obj, UnusedImport, "%q imported as %s and not used", path, obj.name)
+ }
+}
+
+// dir makes a good-faith attempt to return the directory
+// portion of path. If path is empty, the result is ".".
+// (Per the go/build package dependency tests, we cannot import
+// path/filepath and simply use filepath.Dir.)
+func dir(path string) string {
+ if i := strings.LastIndexAny(path, `/\`); i > 0 {
+ return path[:i]
+ }
+ // i <= 0
+ return "."
+}
diff --git a/contrib/go/_std_1.20/src/go/types/return.go b/contrib/go/_std_1.21/src/go/types/return.go
index ee8c41a431..ee8c41a431 100644
--- a/contrib/go/_std_1.20/src/go/types/return.go
+++ b/contrib/go/_std_1.21/src/go/types/return.go
diff --git a/contrib/go/_std_1.21/src/go/types/scope.go b/contrib/go/_std_1.21/src/go/types/scope.go
new file mode 100644
index 0000000000..bf646f6882
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/scope.go
@@ -0,0 +1,294 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2013 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.
+
+// This file implements Scopes.
+
+package types
+
+import (
+ "fmt"
+ "go/token"
+ "io"
+ "sort"
+ "strings"
+ "sync"
+)
+
+// A Scope maintains a set of objects and links to its containing
+// (parent) and contained (children) scopes. Objects may be inserted
+// and looked up by name. The zero value for Scope is a ready-to-use
+// empty scope.
+type Scope struct {
+ parent *Scope
+ children []*Scope
+ number int // parent.children[number-1] is this scope; 0 if there is no parent
+ elems map[string]Object // lazily allocated
+ pos, end token.Pos // scope extent; may be invalid
+ comment string // for debugging only
+ isFunc bool // set if this is a function scope (internal use only)
+}
+
+// NewScope returns a new, empty scope contained in the given parent
+// scope, if any. The comment is for debugging only.
+func NewScope(parent *Scope, pos, end token.Pos, comment string) *Scope {
+ s := &Scope{parent, nil, 0, nil, pos, end, comment, false}
+ // don't add children to Universe scope!
+ if parent != nil && parent != Universe {
+ parent.children = append(parent.children, s)
+ s.number = len(parent.children)
+ }
+ return s
+}
+
+// Parent returns the scope's containing (parent) scope.
+func (s *Scope) Parent() *Scope { return s.parent }
+
+// Len returns the number of scope elements.
+func (s *Scope) Len() int { return len(s.elems) }
+
+// Names returns the scope's element names in sorted order.
+func (s *Scope) Names() []string {
+ names := make([]string, len(s.elems))
+ i := 0
+ for name := range s.elems {
+ names[i] = name
+ i++
+ }
+ sort.Strings(names)
+ return names
+}
+
+// NumChildren returns the number of scopes nested in s.
+func (s *Scope) NumChildren() int { return len(s.children) }
+
+// Child returns the i'th child scope for 0 <= i < NumChildren().
+func (s *Scope) Child(i int) *Scope { return s.children[i] }
+
+// Lookup returns the object in scope s with the given name if such an
+// object exists; otherwise the result is nil.
+func (s *Scope) Lookup(name string) Object {
+ return resolve(name, s.elems[name])
+}
+
+// LookupParent follows the parent chain of scopes starting with s until
+// it finds a scope where Lookup(name) returns a non-nil object, and then
+// returns that scope and object. If a valid position pos is provided,
+// only objects that were declared at or before pos are considered.
+// If no such scope and object exists, the result is (nil, nil).
+//
+// Note that obj.Parent() may be different from the returned scope if the
+// object was inserted into the scope and already had a parent at that
+// time (see Insert). This can only happen for dot-imported objects
+// whose scope is the scope of the package that exported them.
+func (s *Scope) LookupParent(name string, pos token.Pos) (*Scope, Object) {
+ for ; s != nil; s = s.parent {
+ if obj := s.Lookup(name); obj != nil && (!pos.IsValid() || cmpPos(obj.scopePos(), pos) <= 0) {
+ return s, obj
+ }
+ }
+ return nil, nil
+}
+
+// Insert attempts to insert an object obj into scope s.
+// If s already contains an alternative object alt with
+// the same name, Insert leaves s unchanged and returns alt.
+// Otherwise it inserts obj, sets the object's parent scope
+// if not already set, and returns nil.
+func (s *Scope) Insert(obj Object) Object {
+ name := obj.Name()
+ if alt := s.Lookup(name); alt != nil {
+ return alt
+ }
+ s.insert(name, obj)
+ if obj.Parent() == nil {
+ obj.setParent(s)
+ }
+ return nil
+}
+
+// InsertLazy is like Insert, but allows deferring construction of the
+// inserted object until it's accessed with Lookup. The Object
+// returned by resolve must have the same name as given to InsertLazy.
+// If s already contains an alternative object with the same name,
+// InsertLazy leaves s unchanged and returns false. Otherwise it
+// records the binding and returns true. The object's parent scope
+// will be set to s after resolve is called.
+func (s *Scope) _InsertLazy(name string, resolve func() Object) bool {
+ if s.elems[name] != nil {
+ return false
+ }
+ s.insert(name, &lazyObject{parent: s, resolve: resolve})
+ return true
+}
+
+func (s *Scope) insert(name string, obj Object) {
+ if s.elems == nil {
+ s.elems = make(map[string]Object)
+ }
+ s.elems[name] = obj
+}
+
+// Squash merges s with its parent scope p by adding all
+// objects of s to p, adding all children of s to the
+// children of p, and removing s from p's children.
+// The function f is called for each object obj in s which
+// has an object alt in p. s should be discarded after
+// having been squashed.
+func (s *Scope) squash(err func(obj, alt Object)) {
+ p := s.parent
+ assert(p != nil)
+ for name, obj := range s.elems {
+ obj = resolve(name, obj)
+ obj.setParent(nil)
+ if alt := p.Insert(obj); alt != nil {
+ err(obj, alt)
+ }
+ }
+
+ j := -1 // index of s in p.children
+ for i, ch := range p.children {
+ if ch == s {
+ j = i
+ break
+ }
+ }
+ assert(j >= 0)
+ k := len(p.children) - 1
+ p.children[j] = p.children[k]
+ p.children = p.children[:k]
+
+ p.children = append(p.children, s.children...)
+
+ s.children = nil
+ s.elems = nil
+}
+
+// Pos and End describe the scope's source code extent [pos, end).
+// The results are guaranteed to be valid only if the type-checked
+// AST has complete position information. The extent is undefined
+// for Universe and package scopes.
+func (s *Scope) Pos() token.Pos { return s.pos }
+func (s *Scope) End() token.Pos { return s.end }
+
+// Contains reports whether pos is within the scope's extent.
+// The result is guaranteed to be valid only if the type-checked
+// AST has complete position information.
+func (s *Scope) Contains(pos token.Pos) bool {
+ return cmpPos(s.pos, pos) <= 0 && cmpPos(pos, s.end) < 0
+}
+
+// Innermost returns the innermost (child) scope containing
+// pos. If pos is not within any scope, the result is nil.
+// The result is also nil for the Universe scope.
+// The result is guaranteed to be valid only if the type-checked
+// AST has complete position information.
+func (s *Scope) Innermost(pos token.Pos) *Scope {
+ // Package scopes do not have extents since they may be
+ // discontiguous, so iterate over the package's files.
+ if s.parent == Universe {
+ for _, s := range s.children {
+ if inner := s.Innermost(pos); inner != nil {
+ return inner
+ }
+ }
+ }
+
+ if s.Contains(pos) {
+ for _, s := range s.children {
+ if s.Contains(pos) {
+ return s.Innermost(pos)
+ }
+ }
+ return s
+ }
+ return nil
+}
+
+// WriteTo writes a string representation of the scope to w,
+// with the scope elements sorted by name.
+// The level of indentation is controlled by n >= 0, with
+// n == 0 for no indentation.
+// If recurse is set, it also writes nested (children) scopes.
+func (s *Scope) WriteTo(w io.Writer, n int, recurse bool) {
+ const ind = ". "
+ indn := strings.Repeat(ind, n)
+
+ fmt.Fprintf(w, "%s%s scope %p {\n", indn, s.comment, s)
+
+ indn1 := indn + ind
+ for _, name := range s.Names() {
+ fmt.Fprintf(w, "%s%s\n", indn1, s.Lookup(name))
+ }
+
+ if recurse {
+ for _, s := range s.children {
+ s.WriteTo(w, n+1, recurse)
+ }
+ }
+
+ fmt.Fprintf(w, "%s}\n", indn)
+}
+
+// String returns a string representation of the scope, for debugging.
+func (s *Scope) String() string {
+ var buf strings.Builder
+ s.WriteTo(&buf, 0, false)
+ return buf.String()
+}
+
+// A lazyObject represents an imported Object that has not been fully
+// resolved yet by its importer.
+type lazyObject struct {
+ parent *Scope
+ resolve func() Object
+ obj Object
+ once sync.Once
+}
+
+// resolve returns the Object represented by obj, resolving lazy
+// objects as appropriate.
+func resolve(name string, obj Object) Object {
+ if lazy, ok := obj.(*lazyObject); ok {
+ lazy.once.Do(func() {
+ obj := lazy.resolve()
+
+ if _, ok := obj.(*lazyObject); ok {
+ panic("recursive lazy object")
+ }
+ if obj.Name() != name {
+ panic("lazy object has unexpected name")
+ }
+
+ if obj.Parent() == nil {
+ obj.setParent(lazy.parent)
+ }
+ lazy.obj = obj
+ })
+
+ obj = lazy.obj
+ }
+ return obj
+}
+
+// stub implementations so *lazyObject implements Object and we can
+// store them directly into Scope.elems.
+func (*lazyObject) Parent() *Scope { panic("unreachable") }
+func (*lazyObject) Pos() token.Pos { panic("unreachable") }
+func (*lazyObject) Pkg() *Package { panic("unreachable") }
+func (*lazyObject) Name() string { panic("unreachable") }
+func (*lazyObject) Type() Type { panic("unreachable") }
+func (*lazyObject) Exported() bool { panic("unreachable") }
+func (*lazyObject) Id() string { panic("unreachable") }
+func (*lazyObject) String() string { panic("unreachable") }
+func (*lazyObject) order() uint32 { panic("unreachable") }
+func (*lazyObject) color() color { panic("unreachable") }
+func (*lazyObject) setType(Type) { panic("unreachable") }
+func (*lazyObject) setOrder(uint32) { panic("unreachable") }
+func (*lazyObject) setColor(color color) { panic("unreachable") }
+func (*lazyObject) setParent(*Scope) { panic("unreachable") }
+func (*lazyObject) sameId(pkg *Package, name string) bool { panic("unreachable") }
+func (*lazyObject) scopePos() token.Pos { panic("unreachable") }
+func (*lazyObject) setScopePos(pos token.Pos) { panic("unreachable") }
diff --git a/contrib/go/_std_1.21/src/go/types/selection.go b/contrib/go/_std_1.21/src/go/types/selection.go
new file mode 100644
index 0000000000..c79e13c6eb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/selection.go
@@ -0,0 +1,144 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2013 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.
+
+// This file implements Selections.
+
+package types
+
+import (
+ "bytes"
+ "fmt"
+)
+
+// SelectionKind describes the kind of a selector expression x.f
+// (excluding qualified identifiers).
+type SelectionKind int
+
+const (
+ FieldVal SelectionKind = iota // x.f is a struct field selector
+ MethodVal // x.f is a method selector
+ MethodExpr // x.f is a method expression
+)
+
+// A Selection describes a selector expression x.f.
+// For the declarations:
+//
+// type T struct{ x int; E }
+// type E struct{}
+// func (e E) m() {}
+// var p *T
+//
+// the following relations exist:
+//
+// Selector Kind Recv Obj Type Index Indirect
+//
+// p.x FieldVal T x int {0} true
+// p.m MethodVal *T m func() {1, 0} true
+// T.m MethodExpr T m func(T) {1, 0} false
+type Selection struct {
+ kind SelectionKind
+ recv Type // type of x
+ obj Object // object denoted by x.f
+ index []int // path from x to x.f
+ indirect bool // set if there was any pointer indirection on the path
+}
+
+// Kind returns the selection kind.
+func (s *Selection) Kind() SelectionKind { return s.kind }
+
+// Recv returns the type of x in x.f.
+func (s *Selection) Recv() Type { return s.recv }
+
+// Obj returns the object denoted by x.f; a *Var for
+// a field selection, and a *Func in all other cases.
+func (s *Selection) Obj() Object { return s.obj }
+
+// Type returns the type of x.f, which may be different from the type of f.
+// See Selection for more information.
+func (s *Selection) Type() Type {
+ switch s.kind {
+ case MethodVal:
+ // The type of x.f is a method with its receiver type set
+ // to the type of x.
+ sig := *s.obj.(*Func).typ.(*Signature)
+ recv := *sig.recv
+ recv.typ = s.recv
+ sig.recv = &recv
+ return &sig
+
+ case MethodExpr:
+ // The type of x.f is a function (without receiver)
+ // and an additional first argument with the same type as x.
+ // TODO(gri) Similar code is already in call.go - factor!
+ // TODO(gri) Compute this eagerly to avoid allocations.
+ sig := *s.obj.(*Func).typ.(*Signature)
+ arg0 := *sig.recv
+ sig.recv = nil
+ arg0.typ = s.recv
+ var params []*Var
+ if sig.params != nil {
+ params = sig.params.vars
+ }
+ sig.params = NewTuple(append([]*Var{&arg0}, params...)...)
+ return &sig
+ }
+
+ // In all other cases, the type of x.f is the type of x.
+ return s.obj.Type()
+}
+
+// Index describes the path from x to f in x.f.
+// The last index entry is the field or method index of the type declaring f;
+// either:
+//
+// 1. the list of declared methods of a named type; or
+// 2. the list of methods of an interface type; or
+// 3. the list of fields of a struct type.
+//
+// The earlier index entries are the indices of the embedded fields implicitly
+// traversed to get from (the type of) x to f, starting at embedding depth 0.
+func (s *Selection) Index() []int { return s.index }
+
+// Indirect reports whether any pointer indirection was required to get from
+// x to f in x.f.
+func (s *Selection) Indirect() bool { return s.indirect }
+
+func (s *Selection) String() string { return SelectionString(s, nil) }
+
+// SelectionString returns the string form of s.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+//
+// Examples:
+//
+// "field (T) f int"
+// "method (T) f(X) Y"
+// "method expr (T) f(X) Y"
+func SelectionString(s *Selection, qf Qualifier) string {
+ var k string
+ switch s.kind {
+ case FieldVal:
+ k = "field "
+ case MethodVal:
+ k = "method "
+ case MethodExpr:
+ k = "method expr "
+ default:
+ unreachable()
+ }
+ var buf bytes.Buffer
+ buf.WriteString(k)
+ buf.WriteByte('(')
+ WriteType(&buf, s.Recv(), qf)
+ fmt.Fprintf(&buf, ") %s", s.obj.Name())
+ if T := s.Type(); s.kind == FieldVal {
+ buf.WriteByte(' ')
+ WriteType(&buf, T, qf)
+ } else {
+ WriteSignature(&buf, T.(*Signature), qf)
+ }
+ return buf.String()
+}
diff --git a/contrib/go/_std_1.21/src/go/types/signature.go b/contrib/go/_std_1.21/src/go/types/signature.go
new file mode 100644
index 0000000000..8285f1b3d4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/signature.go
@@ -0,0 +1,320 @@
+// 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 types
+
+import (
+ "fmt"
+ "go/ast"
+ . "internal/types/errors"
+)
+
+// ----------------------------------------------------------------------------
+// API
+
+// A Signature represents a (non-builtin) function or method type.
+// The receiver is ignored when comparing signatures for identity.
+type Signature struct {
+ // We need to keep the scope in Signature (rather than passing it around
+ // and store it in the Func Object) because when type-checking a function
+ // literal we call the general type checker which returns a general Type.
+ // We then unpack the *Signature and use the scope for the literal body.
+ rparams *TypeParamList // receiver type parameters from left to right, or nil
+ tparams *TypeParamList // type parameters from left to right, or nil
+ scope *Scope // function scope for package-local and non-instantiated signatures; nil otherwise
+ recv *Var // nil if not a method
+ params *Tuple // (incoming) parameters from left to right; or nil
+ results *Tuple // (outgoing) results from left to right; or nil
+ variadic bool // true if the last parameter's type is of the form ...T (or string, for append built-in only)
+}
+
+// NewSignature returns a new function type for the given receiver, parameters,
+// and results, either of which may be nil. If variadic is set, the function
+// is variadic, it must have at least one parameter, and the last parameter
+// must be of unnamed slice type.
+//
+// Deprecated: Use NewSignatureType instead which allows for type parameters.
+func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature {
+ return NewSignatureType(recv, nil, nil, params, results, variadic)
+}
+
+// NewSignatureType creates a new function type for the given receiver,
+// receiver type parameters, type parameters, parameters, and results. If
+// variadic is set, params must hold at least one parameter and the last
+// parameter's core type must be of unnamed slice or bytestring type.
+// If recv is non-nil, typeParams must be empty. If recvTypeParams is
+// non-empty, recv must be non-nil.
+func NewSignatureType(recv *Var, recvTypeParams, typeParams []*TypeParam, params, results *Tuple, variadic bool) *Signature {
+ if variadic {
+ n := params.Len()
+ if n == 0 {
+ panic("variadic function must have at least one parameter")
+ }
+ core := coreString(params.At(n - 1).typ)
+ if _, ok := core.(*Slice); !ok && !isString(core) {
+ panic(fmt.Sprintf("got %s, want variadic parameter with unnamed slice type or string as core type", core.String()))
+ }
+ }
+ sig := &Signature{recv: recv, params: params, results: results, variadic: variadic}
+ if len(recvTypeParams) != 0 {
+ if recv == nil {
+ panic("function with receiver type parameters must have a receiver")
+ }
+ sig.rparams = bindTParams(recvTypeParams)
+ }
+ if len(typeParams) != 0 {
+ if recv != nil {
+ panic("function with type parameters cannot have a receiver")
+ }
+ sig.tparams = bindTParams(typeParams)
+ }
+ return sig
+}
+
+// Recv returns the receiver of signature s (if a method), or nil if a
+// function. It is ignored when comparing signatures for identity.
+//
+// For an abstract method, Recv returns the enclosing interface either
+// as a *Named or an *Interface. Due to embedding, an interface may
+// contain methods whose receiver type is a different interface.
+func (s *Signature) Recv() *Var { return s.recv }
+
+// TypeParams returns the type parameters of signature s, or nil.
+func (s *Signature) TypeParams() *TypeParamList { return s.tparams }
+
+// RecvTypeParams returns the receiver type parameters of signature s, or nil.
+func (s *Signature) RecvTypeParams() *TypeParamList { return s.rparams }
+
+// Params returns the parameters of signature s, or nil.
+func (s *Signature) Params() *Tuple { return s.params }
+
+// Results returns the results of signature s, or nil.
+func (s *Signature) Results() *Tuple { return s.results }
+
+// Variadic reports whether the signature s is variadic.
+func (s *Signature) Variadic() bool { return s.variadic }
+
+func (t *Signature) Underlying() Type { return t }
+func (t *Signature) String() string { return TypeString(t, nil) }
+
+// ----------------------------------------------------------------------------
+// Implementation
+
+// funcType type-checks a function or method type.
+func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) {
+ check.openScope(ftyp, "function")
+ check.scope.isFunc = true
+ check.recordScope(ftyp, check.scope)
+ sig.scope = check.scope
+ defer check.closeScope()
+
+ if recvPar != nil && len(recvPar.List) > 0 {
+ // collect generic receiver type parameters, if any
+ // - a receiver type parameter is like any other type parameter, except that it is declared implicitly
+ // - the receiver specification acts as local declaration for its type parameters, which may be blank
+ _, rname, rparams := check.unpackRecv(recvPar.List[0].Type, true)
+ if len(rparams) > 0 {
+ tparams := check.declareTypeParams(nil, rparams)
+ sig.rparams = bindTParams(tparams)
+ // Blank identifiers don't get declared, so naive type-checking of the
+ // receiver type expression would fail in Checker.collectParams below,
+ // when Checker.ident cannot resolve the _ to a type.
+ //
+ // Checker.recvTParamMap maps these blank identifiers to their type parameter
+ // types, so that they may be resolved in Checker.ident when they fail
+ // lookup in the scope.
+ for i, p := range rparams {
+ if p.Name == "_" {
+ if check.recvTParamMap == nil {
+ check.recvTParamMap = make(map[*ast.Ident]*TypeParam)
+ }
+ check.recvTParamMap[p] = tparams[i]
+ }
+ }
+ // determine receiver type to get its type parameters
+ // and the respective type parameter bounds
+ var recvTParams []*TypeParam
+ if rname != nil {
+ // recv should be a Named type (otherwise an error is reported elsewhere)
+ // Also: Don't report an error via genericType since it will be reported
+ // again when we type-check the signature.
+ // TODO(gri) maybe the receiver should be marked as invalid instead?
+ if recv, _ := check.genericType(rname, nil).(*Named); recv != nil {
+ recvTParams = recv.TypeParams().list()
+ }
+ }
+ // provide type parameter bounds
+ if len(tparams) == len(recvTParams) {
+ smap := makeRenameMap(recvTParams, tparams)
+ for i, tpar := range tparams {
+ recvTPar := recvTParams[i]
+ check.mono.recordCanon(tpar, recvTPar)
+ // recvTPar.bound is (possibly) parameterized in the context of the
+ // receiver type declaration. Substitute parameters for the current
+ // context.
+ tpar.bound = check.subst(tpar.obj.pos, recvTPar.bound, smap, nil, check.context())
+ }
+ } else if len(tparams) < len(recvTParams) {
+ // Reporting an error here is a stop-gap measure to avoid crashes in the
+ // compiler when a type parameter/argument cannot be inferred later. It
+ // may lead to follow-on errors (see issues go.dev/issue/51339, go.dev/issue/51343).
+ // TODO(gri) find a better solution
+ got := measure(len(tparams), "type parameter")
+ check.errorf(recvPar, BadRecv, "got %s, but receiver base type declares %d", got, len(recvTParams))
+ }
+ }
+ }
+
+ if ftyp.TypeParams != nil {
+ check.collectTypeParams(&sig.tparams, ftyp.TypeParams)
+ // Always type-check method type parameters but complain that they are not allowed.
+ // (A separate check is needed when type-checking interface method signatures because
+ // they don't have a receiver specification.)
+ if recvPar != nil {
+ check.error(ftyp.TypeParams, InvalidMethodTypeParams, "methods cannot have type parameters")
+ }
+ }
+
+ // Value (non-type) parameters' scope starts in the function body. Use a temporary scope for their
+ // declarations and then squash that scope into the parent scope (and report any redeclarations at
+ // that time).
+ scope := NewScope(check.scope, nopos, nopos, "function body (temp. scope)")
+ recvList, _ := check.collectParams(scope, recvPar, false)
+ params, variadic := check.collectParams(scope, ftyp.Params, true)
+ results, _ := check.collectParams(scope, ftyp.Results, false)
+ scope.squash(func(obj, alt Object) {
+ check.errorf(obj, DuplicateDecl, "%s redeclared in this block", obj.Name())
+ check.reportAltDecl(alt)
+ })
+
+ if recvPar != nil {
+ // recv parameter list present (may be empty)
+ // spec: "The receiver is specified via an extra parameter section preceding the
+ // method name. That parameter section must declare a single parameter, the receiver."
+ var recv *Var
+ switch len(recvList) {
+ case 0:
+ // error reported by resolver
+ recv = NewParam(nopos, nil, "", Typ[Invalid]) // ignore recv below
+ default:
+ // more than one receiver
+ check.error(recvList[len(recvList)-1], InvalidRecv, "method has multiple receivers")
+ fallthrough // continue with first receiver
+ case 1:
+ recv = recvList[0]
+ }
+ sig.recv = recv
+
+ // Delay validation of receiver type as it may cause premature expansion
+ // of types the receiver type is dependent on (see issues go.dev/issue/51232, go.dev/issue/51233).
+ check.later(func() {
+ // spec: "The receiver type must be of the form T or *T where T is a type name."
+ rtyp, _ := deref(recv.typ)
+ if rtyp == Typ[Invalid] {
+ return // error was reported before
+ }
+ // spec: "The type denoted by T is called the receiver base type; it must not
+ // be a pointer or interface type and it must be declared in the same package
+ // as the method."
+ switch T := rtyp.(type) {
+ case *Named:
+ // The receiver type may be an instantiated type referred to
+ // by an alias (which cannot have receiver parameters for now).
+ if T.TypeArgs() != nil && sig.RecvTypeParams() == nil {
+ check.errorf(recv, InvalidRecv, "cannot define new methods on instantiated type %s", rtyp)
+ break
+ }
+ if T.obj.pkg != check.pkg {
+ check.errorf(recv, InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
+ break
+ }
+ var cause string
+ switch u := T.under().(type) {
+ case *Basic:
+ // unsafe.Pointer is treated like a regular pointer
+ if u.kind == UnsafePointer {
+ cause = "unsafe.Pointer"
+ }
+ case *Pointer, *Interface:
+ cause = "pointer or interface type"
+ case *TypeParam:
+ // The underlying type of a receiver base type cannot be a
+ // type parameter: "type T[P any] P" is not a valid declaration.
+ unreachable()
+ }
+ if cause != "" {
+ check.errorf(recv, InvalidRecv, "invalid receiver type %s (%s)", rtyp, cause)
+ }
+ case *Basic:
+ check.errorf(recv, InvalidRecv, "cannot define new methods on non-local type %s", rtyp)
+ default:
+ check.errorf(recv, InvalidRecv, "invalid receiver type %s", recv.typ)
+ }
+ }).describef(recv, "validate receiver %s", recv)
+ }
+
+ sig.params = NewTuple(params...)
+ sig.results = NewTuple(results...)
+ sig.variadic = variadic
+}
+
+// collectParams declares the parameters of list in scope and returns the corresponding
+// variable list.
+func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, variadic bool) {
+ if list == nil {
+ return
+ }
+
+ var named, anonymous bool
+ for i, field := range list.List {
+ ftype := field.Type
+ if t, _ := ftype.(*ast.Ellipsis); t != nil {
+ ftype = t.Elt
+ if variadicOk && i == len(list.List)-1 && len(field.Names) <= 1 {
+ variadic = true
+ } else {
+ check.softErrorf(t, MisplacedDotDotDot, "can only use ... with final parameter in list")
+ // ignore ... and continue
+ }
+ }
+ typ := check.varType(ftype)
+ // The parser ensures that f.Tag is nil and we don't
+ // care if a constructed AST contains a non-nil tag.
+ if len(field.Names) > 0 {
+ // named parameter
+ for _, name := range field.Names {
+ if name.Name == "" {
+ check.error(name, InvalidSyntaxTree, "anonymous parameter")
+ // ok to continue
+ }
+ par := NewParam(name.Pos(), check.pkg, name.Name, typ)
+ check.declare(scope, name, par, scope.pos)
+ params = append(params, par)
+ }
+ named = true
+ } else {
+ // anonymous parameter
+ par := NewParam(ftype.Pos(), check.pkg, "", typ)
+ check.recordImplicit(field, par)
+ params = append(params, par)
+ anonymous = true
+ }
+ }
+
+ if named && anonymous {
+ check.error(list, InvalidSyntaxTree, "list contains both named and anonymous parameters")
+ // ok to continue
+ }
+
+ // For a variadic function, change the last parameter's type from T to []T.
+ // Since we type-checked T rather than ...T, we also need to retro-actively
+ // record the type for ...T.
+ if variadic {
+ last := params[len(params)-1]
+ last.typ = &Slice{elem: last.typ}
+ check.recordTypeAndValue(list.List[len(list.List)-1].Type, typexpr, last.typ, nil)
+ }
+
+ return
+}
diff --git a/contrib/go/_std_1.21/src/go/types/sizes.go b/contrib/go/_std_1.21/src/go/types/sizes.go
new file mode 100644
index 0000000000..2dcaebe402
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/sizes.go
@@ -0,0 +1,345 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2013 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.
+
+// This file implements Sizes.
+
+package types
+
+// Sizes defines the sizing functions for package unsafe.
+type Sizes interface {
+ // Alignof returns the alignment of a variable of type T.
+ // Alignof must implement the alignment guarantees required by the spec.
+ // The result must be >= 1.
+ Alignof(T Type) int64
+
+ // Offsetsof returns the offsets of the given struct fields, in bytes.
+ // Offsetsof must implement the offset guarantees required by the spec.
+ // A negative entry in the result indicates that the struct is too large.
+ Offsetsof(fields []*Var) []int64
+
+ // Sizeof returns the size of a variable of type T.
+ // Sizeof must implement the size guarantees required by the spec.
+ // A negative result indicates that T is too large.
+ Sizeof(T Type) int64
+}
+
+// StdSizes is a convenience type for creating commonly used Sizes.
+// It makes the following simplifying assumptions:
+//
+// - The size of explicitly sized basic types (int16, etc.) is the
+// specified size.
+// - The size of strings and interfaces is 2*WordSize.
+// - The size of slices is 3*WordSize.
+// - The size of an array of n elements corresponds to the size of
+// a struct of n consecutive fields of the array's element type.
+// - The size of a struct is the offset of the last field plus that
+// field's size. As with all element types, if the struct is used
+// in an array its size must first be aligned to a multiple of the
+// struct's alignment.
+// - All other types have size WordSize.
+// - Arrays and structs are aligned per spec definition; all other
+// types are naturally aligned with a maximum alignment MaxAlign.
+//
+// *StdSizes implements Sizes.
+type StdSizes struct {
+ WordSize int64 // word size in bytes - must be >= 4 (32bits)
+ MaxAlign int64 // maximum alignment in bytes - must be >= 1
+}
+
+func (s *StdSizes) Alignof(T Type) (result int64) {
+ defer func() {
+ assert(result >= 1)
+ }()
+
+ // For arrays and structs, alignment is defined in terms
+ // of alignment of the elements and fields, respectively.
+ switch t := under(T).(type) {
+ case *Array:
+ // spec: "For a variable x of array type: unsafe.Alignof(x)
+ // is the same as unsafe.Alignof(x[0]), but at least 1."
+ return s.Alignof(t.elem)
+ case *Struct:
+ if len(t.fields) == 0 && _IsSyncAtomicAlign64(T) {
+ // Special case: sync/atomic.align64 is an
+ // empty struct we recognize as a signal that
+ // the struct it contains must be
+ // 64-bit-aligned.
+ //
+ // This logic is equivalent to the logic in
+ // cmd/compile/internal/types/size.go:calcStructOffset
+ return 8
+ }
+
+ // spec: "For a variable x of struct type: unsafe.Alignof(x)
+ // is the largest of the values unsafe.Alignof(x.f) for each
+ // field f of x, but at least 1."
+ max := int64(1)
+ for _, f := range t.fields {
+ if a := s.Alignof(f.typ); a > max {
+ max = a
+ }
+ }
+ return max
+ case *Slice, *Interface:
+ // Multiword data structures are effectively structs
+ // in which each element has size WordSize.
+ // Type parameters lead to variable sizes/alignments;
+ // StdSizes.Alignof won't be called for them.
+ assert(!isTypeParam(T))
+ return s.WordSize
+ case *Basic:
+ // Strings are like slices and interfaces.
+ if t.Info()&IsString != 0 {
+ return s.WordSize
+ }
+ case *TypeParam, *Union:
+ unreachable()
+ }
+ a := s.Sizeof(T) // may be 0 or negative
+ // spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
+ if a < 1 {
+ return 1
+ }
+ // complex{64,128} are aligned like [2]float{32,64}.
+ if isComplex(T) {
+ a /= 2
+ }
+ if a > s.MaxAlign {
+ return s.MaxAlign
+ }
+ return a
+}
+
+func _IsSyncAtomicAlign64(T Type) bool {
+ named, ok := T.(*Named)
+ if !ok {
+ return false
+ }
+ obj := named.Obj()
+ return obj.Name() == "align64" &&
+ obj.Pkg() != nil &&
+ (obj.Pkg().Path() == "sync/atomic" ||
+ obj.Pkg().Path() == "runtime/internal/atomic")
+}
+
+func (s *StdSizes) Offsetsof(fields []*Var) []int64 {
+ offsets := make([]int64, len(fields))
+ var offs int64
+ for i, f := range fields {
+ if offs < 0 {
+ // all remaining offsets are too large
+ offsets[i] = -1
+ continue
+ }
+ // offs >= 0
+ a := s.Alignof(f.typ)
+ offs = align(offs, a) // possibly < 0 if align overflows
+ offsets[i] = offs
+ if d := s.Sizeof(f.typ); d >= 0 && offs >= 0 {
+ offs += d // ok to overflow to < 0
+ } else {
+ offs = -1 // f.typ or offs is too large
+ }
+ }
+ return offsets
+}
+
+var basicSizes = [...]byte{
+ Bool: 1,
+ Int8: 1,
+ Int16: 2,
+ Int32: 4,
+ Int64: 8,
+ Uint8: 1,
+ Uint16: 2,
+ Uint32: 4,
+ Uint64: 8,
+ Float32: 4,
+ Float64: 8,
+ Complex64: 8,
+ Complex128: 16,
+}
+
+func (s *StdSizes) Sizeof(T Type) int64 {
+ switch t := under(T).(type) {
+ case *Basic:
+ assert(isTyped(T))
+ k := t.kind
+ if int(k) < len(basicSizes) {
+ if s := basicSizes[k]; s > 0 {
+ return int64(s)
+ }
+ }
+ if k == String {
+ return s.WordSize * 2
+ }
+ case *Array:
+ n := t.len
+ if n <= 0 {
+ return 0
+ }
+ // n > 0
+ esize := s.Sizeof(t.elem)
+ if esize < 0 {
+ return -1 // element too large
+ }
+ if esize == 0 {
+ return 0 // 0-size element
+ }
+ // esize > 0
+ a := s.Alignof(t.elem)
+ ea := align(esize, a) // possibly < 0 if align overflows
+ if ea < 0 {
+ return -1
+ }
+ // ea >= 1
+ n1 := n - 1 // n1 >= 0
+ // Final size is ea*n1 + esize; and size must be <= maxInt64.
+ const maxInt64 = 1<<63 - 1
+ if n1 > 0 && ea > maxInt64/n1 {
+ return -1 // ea*n1 overflows
+ }
+ return ea*n1 + esize // may still overflow to < 0 which is ok
+ case *Slice:
+ return s.WordSize * 3
+ case *Struct:
+ n := t.NumFields()
+ if n == 0 {
+ return 0
+ }
+ offsets := s.Offsetsof(t.fields)
+ offs := offsets[n-1]
+ size := s.Sizeof(t.fields[n-1].typ)
+ if offs < 0 || size < 0 {
+ return -1 // type too large
+ }
+ return offs + size // may overflow to < 0 which is ok
+ case *Interface:
+ // Type parameters lead to variable sizes/alignments;
+ // StdSizes.Sizeof won't be called for them.
+ assert(!isTypeParam(T))
+ return s.WordSize * 2
+ case *TypeParam, *Union:
+ unreachable()
+ }
+ return s.WordSize // catch-all
+}
+
+// common architecture word sizes and alignments
+var gcArchSizes = map[string]*StdSizes{
+ "386": {4, 4},
+ "amd64": {8, 8},
+ "amd64p32": {4, 8},
+ "arm": {4, 4},
+ "arm64": {8, 8},
+ "loong64": {8, 8},
+ "mips": {4, 4},
+ "mipsle": {4, 4},
+ "mips64": {8, 8},
+ "mips64le": {8, 8},
+ "ppc64": {8, 8},
+ "ppc64le": {8, 8},
+ "riscv64": {8, 8},
+ "s390x": {8, 8},
+ "sparc64": {8, 8},
+ "wasm": {8, 8},
+ // When adding more architectures here,
+ // update the doc string of SizesFor below.
+}
+
+// SizesFor returns the Sizes used by a compiler for an architecture.
+// The result is nil if a compiler/architecture pair is not known.
+//
+// Supported architectures for compiler "gc":
+// "386", "amd64", "amd64p32", "arm", "arm64", "loong64", "mips", "mipsle",
+// "mips64", "mips64le", "ppc64", "ppc64le", "riscv64", "s390x", "sparc64", "wasm".
+func SizesFor(compiler, arch string) Sizes {
+ var m map[string]*StdSizes
+ switch compiler {
+ case "gc":
+ m = gcArchSizes
+ case "gccgo":
+ m = gccgoArchSizes
+ default:
+ return nil
+ }
+ s, ok := m[arch]
+ if !ok {
+ return nil
+ }
+ return s
+}
+
+// stdSizes is used if Config.Sizes == nil.
+var stdSizes = SizesFor("gc", "amd64")
+
+func (conf *Config) alignof(T Type) int64 {
+ f := stdSizes.Alignof
+ if conf.Sizes != nil {
+ f = conf.Sizes.Alignof
+ }
+ if a := f(T); a >= 1 {
+ return a
+ }
+ panic("implementation of alignof returned an alignment < 1")
+}
+
+func (conf *Config) offsetsof(T *Struct) []int64 {
+ var offsets []int64
+ if T.NumFields() > 0 {
+ // compute offsets on demand
+ f := stdSizes.Offsetsof
+ if conf.Sizes != nil {
+ f = conf.Sizes.Offsetsof
+ }
+ offsets = f(T.fields)
+ // sanity checks
+ if len(offsets) != T.NumFields() {
+ panic("implementation of offsetsof returned the wrong number of offsets")
+ }
+ }
+ return offsets
+}
+
+// offsetof returns the offset of the field specified via
+// the index sequence relative to T. All embedded fields
+// must be structs (rather than pointers to structs).
+// If the offset is too large (because T is too large),
+// the result is negative.
+func (conf *Config) offsetof(T Type, index []int) int64 {
+ var offs int64
+ for _, i := range index {
+ s := under(T).(*Struct)
+ d := conf.offsetsof(s)[i]
+ if d < 0 {
+ return -1
+ }
+ offs += d
+ if offs < 0 {
+ return -1
+ }
+ T = s.fields[i].typ
+ }
+ return offs
+}
+
+// sizeof returns the size of T.
+// If T is too large, the result is negative.
+func (conf *Config) sizeof(T Type) int64 {
+ f := stdSizes.Sizeof
+ if conf.Sizes != nil {
+ f = conf.Sizes.Sizeof
+ }
+ return f(T)
+}
+
+// align returns the smallest y >= x such that y % a == 0.
+// a must be within 1 and 8 and it must be a power of 2.
+// The result may be negative due to overflow.
+func align(x, a int64) int64 {
+ assert(x >= 0 && 1 <= a && a <= 8 && a&(a-1) == 0)
+ return (x + a - 1) &^ (a - 1)
+}
diff --git a/contrib/go/_std_1.21/src/go/types/slice.go b/contrib/go/_std_1.21/src/go/types/slice.go
new file mode 100644
index 0000000000..934549c2d4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/slice.go
@@ -0,0 +1,21 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2011 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 types
+
+// A Slice represents a slice type.
+type Slice struct {
+ elem Type
+}
+
+// NewSlice returns a new slice type for the given element type.
+func NewSlice(elem Type) *Slice { return &Slice{elem: elem} }
+
+// Elem returns the element type of slice s.
+func (s *Slice) Elem() Type { return s.elem }
+
+func (s *Slice) Underlying() Type { return s }
+func (s *Slice) String() string { return TypeString(s, nil) }
diff --git a/contrib/go/_std_1.21/src/go/types/stmt.go b/contrib/go/_std_1.21/src/go/types/stmt.go
new file mode 100644
index 0000000000..7869f37077
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/stmt.go
@@ -0,0 +1,962 @@
+// Copyright 2012 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.
+
+// This file implements typechecking of statements.
+
+package types
+
+import (
+ "go/ast"
+ "go/constant"
+ "go/token"
+ . "internal/types/errors"
+ "sort"
+)
+
+func (check *Checker) funcBody(decl *declInfo, name string, sig *Signature, body *ast.BlockStmt, iota constant.Value) {
+ if check.conf.IgnoreFuncBodies {
+ panic("function body not ignored")
+ }
+
+ if check.conf._Trace {
+ check.trace(body.Pos(), "-- %s: %s", name, sig)
+ }
+
+ // set function scope extent
+ sig.scope.pos = body.Pos()
+ sig.scope.end = body.End()
+
+ // save/restore current environment and set up function environment
+ // (and use 0 indentation at function start)
+ defer func(env environment, indent int) {
+ check.environment = env
+ check.indent = indent
+ }(check.environment, check.indent)
+ check.environment = environment{
+ decl: decl,
+ scope: sig.scope,
+ iota: iota,
+ sig: sig,
+ }
+ check.indent = 0
+
+ check.stmtList(0, body.List)
+
+ if check.hasLabel {
+ check.labels(body)
+ }
+
+ if sig.results.Len() > 0 && !check.isTerminating(body, "") {
+ check.error(atPos(body.Rbrace), MissingReturn, "missing return")
+ }
+
+ // spec: "Implementation restriction: A compiler may make it illegal to
+ // declare a variable inside a function body if the variable is never used."
+ check.usage(sig.scope)
+}
+
+func (check *Checker) usage(scope *Scope) {
+ var unused []*Var
+ for name, elem := range scope.elems {
+ elem = resolve(name, elem)
+ if v, _ := elem.(*Var); v != nil && !v.used {
+ unused = append(unused, v)
+ }
+ }
+ sort.Slice(unused, func(i, j int) bool {
+ return cmpPos(unused[i].pos, unused[j].pos) < 0
+ })
+ for _, v := range unused {
+ check.softErrorf(v, UnusedVar, "%s declared and not used", v.name)
+ }
+
+ for _, scope := range scope.children {
+ // Don't go inside function literal scopes a second time;
+ // they are handled explicitly by funcBody.
+ if !scope.isFunc {
+ check.usage(scope)
+ }
+ }
+}
+
+// stmtContext is a bitset describing which
+// control-flow statements are permissible,
+// and provides additional context information
+// for better error messages.
+type stmtContext uint
+
+const (
+ // permissible control-flow statements
+ breakOk stmtContext = 1 << iota
+ continueOk
+ fallthroughOk
+
+ // additional context information
+ finalSwitchCase
+ inTypeSwitch
+)
+
+func (check *Checker) simpleStmt(s ast.Stmt) {
+ if s != nil {
+ check.stmt(0, s)
+ }
+}
+
+func trimTrailingEmptyStmts(list []ast.Stmt) []ast.Stmt {
+ for i := len(list); i > 0; i-- {
+ if _, ok := list[i-1].(*ast.EmptyStmt); !ok {
+ return list[:i]
+ }
+ }
+ return nil
+}
+
+func (check *Checker) stmtList(ctxt stmtContext, list []ast.Stmt) {
+ ok := ctxt&fallthroughOk != 0
+ inner := ctxt &^ fallthroughOk
+ list = trimTrailingEmptyStmts(list) // trailing empty statements are "invisible" to fallthrough analysis
+ for i, s := range list {
+ inner := inner
+ if ok && i+1 == len(list) {
+ inner |= fallthroughOk
+ }
+ check.stmt(inner, s)
+ }
+}
+
+func (check *Checker) multipleDefaults(list []ast.Stmt) {
+ var first ast.Stmt
+ for _, s := range list {
+ var d ast.Stmt
+ switch c := s.(type) {
+ case *ast.CaseClause:
+ if len(c.List) == 0 {
+ d = s
+ }
+ case *ast.CommClause:
+ if c.Comm == nil {
+ d = s
+ }
+ default:
+ check.error(s, InvalidSyntaxTree, "case/communication clause expected")
+ }
+ if d != nil {
+ if first != nil {
+ check.errorf(d, DuplicateDefault, "multiple defaults (first at %s)", check.fset.Position(first.Pos()))
+ } else {
+ first = d
+ }
+ }
+ }
+}
+
+func (check *Checker) openScope(node ast.Node, comment string) {
+ scope := NewScope(check.scope, node.Pos(), node.End(), comment)
+ check.recordScope(node, scope)
+ check.scope = scope
+}
+
+func (check *Checker) closeScope() {
+ check.scope = check.scope.Parent()
+}
+
+func assignOp(op token.Token) token.Token {
+ // token_test.go verifies the token ordering this function relies on
+ if token.ADD_ASSIGN <= op && op <= token.AND_NOT_ASSIGN {
+ return op + (token.ADD - token.ADD_ASSIGN)
+ }
+ return token.ILLEGAL
+}
+
+func (check *Checker) suspendedCall(keyword string, call *ast.CallExpr) {
+ var x operand
+ var msg string
+ var code Code
+ switch check.rawExpr(nil, &x, call, nil, false) {
+ case conversion:
+ msg = "requires function call, not conversion"
+ code = InvalidDefer
+ if keyword == "go" {
+ code = InvalidGo
+ }
+ case expression:
+ msg = "discards result of"
+ code = UnusedResults
+ case statement:
+ return
+ default:
+ unreachable()
+ }
+ check.errorf(&x, code, "%s %s %s", keyword, msg, &x)
+}
+
+// goVal returns the Go value for val, or nil.
+func goVal(val constant.Value) any {
+ // val should exist, but be conservative and check
+ if val == nil {
+ return nil
+ }
+ // Match implementation restriction of other compilers.
+ // gc only checks duplicates for integer, floating-point
+ // and string values, so only create Go values for these
+ // types.
+ switch val.Kind() {
+ case constant.Int:
+ if x, ok := constant.Int64Val(val); ok {
+ return x
+ }
+ if x, ok := constant.Uint64Val(val); ok {
+ return x
+ }
+ case constant.Float:
+ if x, ok := constant.Float64Val(val); ok {
+ return x
+ }
+ case constant.String:
+ return constant.StringVal(val)
+ }
+ return nil
+}
+
+// A valueMap maps a case value (of a basic Go type) to a list of positions
+// where the same case value appeared, together with the corresponding case
+// types.
+// Since two case values may have the same "underlying" value but different
+// types we need to also check the value's types (e.g., byte(1) vs myByte(1))
+// when the switch expression is of interface type.
+type (
+ valueMap map[any][]valueType // underlying Go value -> valueType
+ valueType struct {
+ pos token.Pos
+ typ Type
+ }
+)
+
+func (check *Checker) caseValues(x *operand, values []ast.Expr, seen valueMap) {
+L:
+ for _, e := range values {
+ var v operand
+ check.expr(nil, &v, e)
+ if x.mode == invalid || v.mode == invalid {
+ continue L
+ }
+ check.convertUntyped(&v, x.typ)
+ if v.mode == invalid {
+ continue L
+ }
+ // Order matters: By comparing v against x, error positions are at the case values.
+ res := v // keep original v unchanged
+ check.comparison(&res, x, token.EQL, true)
+ if res.mode == invalid {
+ continue L
+ }
+ if v.mode != constant_ {
+ continue L // we're done
+ }
+ // look for duplicate values
+ if val := goVal(v.val); val != nil {
+ // look for duplicate types for a given value
+ // (quadratic algorithm, but these lists tend to be very short)
+ for _, vt := range seen[val] {
+ if Identical(v.typ, vt.typ) {
+ check.errorf(&v, DuplicateCase, "duplicate case %s in expression switch", &v)
+ check.error(atPos(vt.pos), DuplicateCase, "\tprevious case") // secondary error, \t indented
+ continue L
+ }
+ }
+ seen[val] = append(seen[val], valueType{v.Pos(), v.typ})
+ }
+ }
+}
+
+// isNil reports whether the expression e denotes the predeclared value nil.
+func (check *Checker) isNil(e ast.Expr) bool {
+ // The only way to express the nil value is by literally writing nil (possibly in parentheses).
+ if name, _ := unparen(e).(*ast.Ident); name != nil {
+ _, ok := check.lookup(name.Name).(*Nil)
+ return ok
+ }
+ return false
+}
+
+// If the type switch expression is invalid, x is nil.
+func (check *Checker) caseTypes(x *operand, types []ast.Expr, seen map[Type]ast.Expr) (T Type) {
+ var dummy operand
+L:
+ for _, e := range types {
+ // The spec allows the value nil instead of a type.
+ if check.isNil(e) {
+ T = nil
+ check.expr(nil, &dummy, e) // run e through expr so we get the usual Info recordings
+ } else {
+ T = check.varType(e)
+ if T == Typ[Invalid] {
+ continue L
+ }
+ }
+ // look for duplicate types
+ // (quadratic algorithm, but type switches tend to be reasonably small)
+ for t, other := range seen {
+ if T == nil && t == nil || T != nil && t != nil && Identical(T, t) {
+ // talk about "case" rather than "type" because of nil case
+ Ts := "nil"
+ if T != nil {
+ Ts = TypeString(T, check.qualifier)
+ }
+ check.errorf(e, DuplicateCase, "duplicate case %s in type switch", Ts)
+ check.error(other, DuplicateCase, "\tprevious case") // secondary error, \t indented
+ continue L
+ }
+ }
+ seen[T] = e
+ if x != nil && T != nil {
+ check.typeAssertion(e, x, T, true)
+ }
+ }
+ return
+}
+
+// TODO(gri) Once we are certain that typeHash is correct in all situations, use this version of caseTypes instead.
+// (Currently it may be possible that different types have identical names and import paths due to ImporterFrom.)
+//
+// func (check *Checker) caseTypes(x *operand, xtyp *Interface, types []ast.Expr, seen map[string]ast.Expr) (T Type) {
+// var dummy operand
+// L:
+// for _, e := range types {
+// // The spec allows the value nil instead of a type.
+// var hash string
+// if check.isNil(e) {
+// check.expr(nil, &dummy, e) // run e through expr so we get the usual Info recordings
+// T = nil
+// hash = "<nil>" // avoid collision with a type named nil
+// } else {
+// T = check.varType(e)
+// if T == Typ[Invalid] {
+// continue L
+// }
+// hash = typeHash(T, nil)
+// }
+// // look for duplicate types
+// if other := seen[hash]; other != nil {
+// // talk about "case" rather than "type" because of nil case
+// Ts := "nil"
+// if T != nil {
+// Ts = TypeString(T, check.qualifier)
+// }
+// var err error_
+// err.code = DuplicateCase
+// err.errorf(e, "duplicate case %s in type switch", Ts)
+// err.errorf(other, "previous case")
+// check.report(&err)
+// continue L
+// }
+// seen[hash] = e
+// if T != nil {
+// check.typeAssertion(e.Pos(), x, xtyp, T)
+// }
+// }
+// return
+// }
+
+// stmt typechecks statement s.
+func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
+ // statements must end with the same top scope as they started with
+ if debug {
+ defer func(scope *Scope) {
+ // don't check if code is panicking
+ if p := recover(); p != nil {
+ panic(p)
+ }
+ assert(scope == check.scope)
+ }(check.scope)
+ }
+
+ // process collected function literals before scope changes
+ defer check.processDelayed(len(check.delayed))
+
+ // reset context for statements of inner blocks
+ inner := ctxt &^ (fallthroughOk | finalSwitchCase | inTypeSwitch)
+
+ switch s := s.(type) {
+ case *ast.BadStmt, *ast.EmptyStmt:
+ // ignore
+
+ case *ast.DeclStmt:
+ check.declStmt(s.Decl)
+
+ case *ast.LabeledStmt:
+ check.hasLabel = true
+ check.stmt(ctxt, s.Stmt)
+
+ case *ast.ExprStmt:
+ // spec: "With the exception of specific built-in functions,
+ // function and method calls and receive operations can appear
+ // in statement context. Such statements may be parenthesized."
+ var x operand
+ kind := check.rawExpr(nil, &x, s.X, nil, false)
+ var msg string
+ var code Code
+ switch x.mode {
+ default:
+ if kind == statement {
+ return
+ }
+ msg = "is not used"
+ code = UnusedExpr
+ case builtin:
+ msg = "must be called"
+ code = UncalledBuiltin
+ case typexpr:
+ msg = "is not an expression"
+ code = NotAnExpr
+ }
+ check.errorf(&x, code, "%s %s", &x, msg)
+
+ case *ast.SendStmt:
+ var ch, val operand
+ check.expr(nil, &ch, s.Chan)
+ check.expr(nil, &val, s.Value)
+ if ch.mode == invalid || val.mode == invalid {
+ return
+ }
+ u := coreType(ch.typ)
+ if u == nil {
+ check.errorf(inNode(s, s.Arrow), InvalidSend, invalidOp+"cannot send to %s: no core type", &ch)
+ return
+ }
+ uch, _ := u.(*Chan)
+ if uch == nil {
+ check.errorf(inNode(s, s.Arrow), InvalidSend, invalidOp+"cannot send to non-channel %s", &ch)
+ return
+ }
+ if uch.dir == RecvOnly {
+ check.errorf(inNode(s, s.Arrow), InvalidSend, invalidOp+"cannot send to receive-only channel %s", &ch)
+ return
+ }
+ check.assignment(&val, uch.elem, "send")
+
+ case *ast.IncDecStmt:
+ var op token.Token
+ switch s.Tok {
+ case token.INC:
+ op = token.ADD
+ case token.DEC:
+ op = token.SUB
+ default:
+ check.errorf(inNode(s, s.TokPos), InvalidSyntaxTree, "unknown inc/dec operation %s", s.Tok)
+ return
+ }
+
+ var x operand
+ check.expr(nil, &x, s.X)
+ if x.mode == invalid {
+ return
+ }
+ if !allNumeric(x.typ) {
+ check.errorf(s.X, NonNumericIncDec, invalidOp+"%s%s (non-numeric type %s)", s.X, s.Tok, x.typ)
+ return
+ }
+
+ Y := &ast.BasicLit{ValuePos: s.X.Pos(), Kind: token.INT, Value: "1"} // use x's position
+ check.binary(&x, nil, s.X, Y, op, s.TokPos)
+ if x.mode == invalid {
+ return
+ }
+ check.assignVar(s.X, nil, &x)
+
+ case *ast.AssignStmt:
+ switch s.Tok {
+ case token.ASSIGN, token.DEFINE:
+ if len(s.Lhs) == 0 {
+ check.error(s, InvalidSyntaxTree, "missing lhs in assignment")
+ return
+ }
+ if s.Tok == token.DEFINE {
+ check.shortVarDecl(inNode(s, s.TokPos), s.Lhs, s.Rhs)
+ } else {
+ // regular assignment
+ check.assignVars(s.Lhs, s.Rhs)
+ }
+
+ default:
+ // assignment operations
+ if len(s.Lhs) != 1 || len(s.Rhs) != 1 {
+ check.errorf(inNode(s, s.TokPos), MultiValAssignOp, "assignment operation %s requires single-valued expressions", s.Tok)
+ return
+ }
+ op := assignOp(s.Tok)
+ if op == token.ILLEGAL {
+ check.errorf(atPos(s.TokPos), InvalidSyntaxTree, "unknown assignment operation %s", s.Tok)
+ return
+ }
+ var x operand
+ check.binary(&x, nil, s.Lhs[0], s.Rhs[0], op, s.TokPos)
+ if x.mode == invalid {
+ return
+ }
+ check.assignVar(s.Lhs[0], nil, &x)
+ }
+
+ case *ast.GoStmt:
+ check.suspendedCall("go", s.Call)
+
+ case *ast.DeferStmt:
+ check.suspendedCall("defer", s.Call)
+
+ case *ast.ReturnStmt:
+ res := check.sig.results
+ // Return with implicit results allowed for function with named results.
+ // (If one is named, all are named.)
+ if len(s.Results) == 0 && res.Len() > 0 && res.vars[0].name != "" {
+ // spec: "Implementation restriction: A compiler may disallow an empty expression
+ // list in a "return" statement if a different entity (constant, type, or variable)
+ // with the same name as a result parameter is in scope at the place of the return."
+ for _, obj := range res.vars {
+ if alt := check.lookup(obj.name); alt != nil && alt != obj {
+ check.errorf(s, OutOfScopeResult, "result parameter %s not in scope at return", obj.name)
+ check.errorf(alt, OutOfScopeResult, "\tinner declaration of %s", obj)
+ // ok to continue
+ }
+ }
+ } else {
+ var lhs []*Var
+ if res.Len() > 0 {
+ lhs = res.vars
+ }
+ check.initVars(lhs, s.Results, s)
+ }
+
+ case *ast.BranchStmt:
+ if s.Label != nil {
+ check.hasLabel = true
+ return // checked in 2nd pass (check.labels)
+ }
+ switch s.Tok {
+ case token.BREAK:
+ if ctxt&breakOk == 0 {
+ check.error(s, MisplacedBreak, "break not in for, switch, or select statement")
+ }
+ case token.CONTINUE:
+ if ctxt&continueOk == 0 {
+ check.error(s, MisplacedContinue, "continue not in for statement")
+ }
+ case token.FALLTHROUGH:
+ if ctxt&fallthroughOk == 0 {
+ var msg string
+ switch {
+ case ctxt&finalSwitchCase != 0:
+ msg = "cannot fallthrough final case in switch"
+ case ctxt&inTypeSwitch != 0:
+ msg = "cannot fallthrough in type switch"
+ default:
+ msg = "fallthrough statement out of place"
+ }
+ check.error(s, MisplacedFallthrough, msg)
+ }
+ default:
+ check.errorf(s, InvalidSyntaxTree, "branch statement: %s", s.Tok)
+ }
+
+ case *ast.BlockStmt:
+ check.openScope(s, "block")
+ defer check.closeScope()
+
+ check.stmtList(inner, s.List)
+
+ case *ast.IfStmt:
+ check.openScope(s, "if")
+ defer check.closeScope()
+
+ check.simpleStmt(s.Init)
+ var x operand
+ check.expr(nil, &x, s.Cond)
+ if x.mode != invalid && !allBoolean(x.typ) {
+ check.error(s.Cond, InvalidCond, "non-boolean condition in if statement")
+ }
+ check.stmt(inner, s.Body)
+ // The parser produces a correct AST but if it was modified
+ // elsewhere the else branch may be invalid. Check again.
+ switch s.Else.(type) {
+ case nil, *ast.BadStmt:
+ // valid or error already reported
+ case *ast.IfStmt, *ast.BlockStmt:
+ check.stmt(inner, s.Else)
+ default:
+ check.error(s.Else, InvalidSyntaxTree, "invalid else branch in if statement")
+ }
+
+ case *ast.SwitchStmt:
+ inner |= breakOk
+ check.openScope(s, "switch")
+ defer check.closeScope()
+
+ check.simpleStmt(s.Init)
+ var x operand
+ if s.Tag != nil {
+ check.expr(nil, &x, s.Tag)
+ // By checking assignment of x to an invisible temporary
+ // (as a compiler would), we get all the relevant checks.
+ check.assignment(&x, nil, "switch expression")
+ if x.mode != invalid && !Comparable(x.typ) && !hasNil(x.typ) {
+ check.errorf(&x, InvalidExprSwitch, "cannot switch on %s (%s is not comparable)", &x, x.typ)
+ x.mode = invalid
+ }
+ } else {
+ // spec: "A missing switch expression is
+ // equivalent to the boolean value true."
+ x.mode = constant_
+ x.typ = Typ[Bool]
+ x.val = constant.MakeBool(true)
+ x.expr = &ast.Ident{NamePos: s.Body.Lbrace, Name: "true"}
+ }
+
+ check.multipleDefaults(s.Body.List)
+
+ seen := make(valueMap) // map of seen case values to positions and types
+ for i, c := range s.Body.List {
+ clause, _ := c.(*ast.CaseClause)
+ if clause == nil {
+ check.error(c, InvalidSyntaxTree, "incorrect expression switch case")
+ continue
+ }
+ check.caseValues(&x, clause.List, seen)
+ check.openScope(clause, "case")
+ inner := inner
+ if i+1 < len(s.Body.List) {
+ inner |= fallthroughOk
+ } else {
+ inner |= finalSwitchCase
+ }
+ check.stmtList(inner, clause.Body)
+ check.closeScope()
+ }
+
+ case *ast.TypeSwitchStmt:
+ inner |= breakOk | inTypeSwitch
+ check.openScope(s, "type switch")
+ defer check.closeScope()
+
+ check.simpleStmt(s.Init)
+
+ // A type switch guard must be of the form:
+ //
+ // TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
+ //
+ // The parser is checking syntactic correctness;
+ // remaining syntactic errors are considered AST errors here.
+ // TODO(gri) better factoring of error handling (invalid ASTs)
+ //
+ var lhs *ast.Ident // lhs identifier or nil
+ var rhs ast.Expr
+ switch guard := s.Assign.(type) {
+ case *ast.ExprStmt:
+ rhs = guard.X
+ case *ast.AssignStmt:
+ if len(guard.Lhs) != 1 || guard.Tok != token.DEFINE || len(guard.Rhs) != 1 {
+ check.error(s, InvalidSyntaxTree, "incorrect form of type switch guard")
+ return
+ }
+
+ lhs, _ = guard.Lhs[0].(*ast.Ident)
+ if lhs == nil {
+ check.error(s, InvalidSyntaxTree, "incorrect form of type switch guard")
+ return
+ }
+
+ if lhs.Name == "_" {
+ // _ := x.(type) is an invalid short variable declaration
+ check.softErrorf(lhs, NoNewVar, "no new variable on left side of :=")
+ lhs = nil // avoid declared and not used error below
+ } else {
+ check.recordDef(lhs, nil) // lhs variable is implicitly declared in each cause clause
+ }
+
+ rhs = guard.Rhs[0]
+
+ default:
+ check.error(s, InvalidSyntaxTree, "incorrect form of type switch guard")
+ return
+ }
+
+ // rhs must be of the form: expr.(type) and expr must be an ordinary interface
+ expr, _ := rhs.(*ast.TypeAssertExpr)
+ if expr == nil || expr.Type != nil {
+ check.error(s, InvalidSyntaxTree, "incorrect form of type switch guard")
+ return
+ }
+ var x operand
+ check.expr(nil, &x, expr.X)
+ if x.mode == invalid {
+ return
+ }
+ // TODO(gri) we may want to permit type switches on type parameter values at some point
+ var sx *operand // switch expression against which cases are compared against; nil if invalid
+ if isTypeParam(x.typ) {
+ check.errorf(&x, InvalidTypeSwitch, "cannot use type switch on type parameter value %s", &x)
+ } else {
+ if _, ok := under(x.typ).(*Interface); ok {
+ sx = &x
+ } else {
+ check.errorf(&x, InvalidTypeSwitch, "%s is not an interface", &x)
+ }
+ }
+
+ check.multipleDefaults(s.Body.List)
+
+ var lhsVars []*Var // list of implicitly declared lhs variables
+ seen := make(map[Type]ast.Expr) // map of seen types to positions
+ for _, s := range s.Body.List {
+ clause, _ := s.(*ast.CaseClause)
+ if clause == nil {
+ check.error(s, InvalidSyntaxTree, "incorrect type switch case")
+ continue
+ }
+ // Check each type in this type switch case.
+ T := check.caseTypes(sx, clause.List, seen)
+ check.openScope(clause, "case")
+ // If lhs exists, declare a corresponding variable in the case-local scope.
+ if lhs != nil {
+ // spec: "The TypeSwitchGuard may include a short variable declaration.
+ // When that form is used, the variable is declared at the beginning of
+ // the implicit block in each clause. In clauses with a case listing
+ // exactly one type, the variable has that type; otherwise, the variable
+ // has the type of the expression in the TypeSwitchGuard."
+ if len(clause.List) != 1 || T == nil {
+ T = x.typ
+ }
+ obj := NewVar(lhs.Pos(), check.pkg, lhs.Name, T)
+ scopePos := clause.Pos() + token.Pos(len("default")) // for default clause (len(List) == 0)
+ if n := len(clause.List); n > 0 {
+ scopePos = clause.List[n-1].End()
+ }
+ check.declare(check.scope, nil, obj, scopePos)
+ check.recordImplicit(clause, obj)
+ // For the "declared and not used" error, all lhs variables act as
+ // one; i.e., if any one of them is 'used', all of them are 'used'.
+ // Collect them for later analysis.
+ lhsVars = append(lhsVars, obj)
+ }
+ check.stmtList(inner, clause.Body)
+ check.closeScope()
+ }
+
+ // If lhs exists, we must have at least one lhs variable that was used.
+ if lhs != nil {
+ var used bool
+ for _, v := range lhsVars {
+ if v.used {
+ used = true
+ }
+ v.used = true // avoid usage error when checking entire function
+ }
+ if !used {
+ check.softErrorf(lhs, UnusedVar, "%s declared and not used", lhs.Name)
+ }
+ }
+
+ case *ast.SelectStmt:
+ inner |= breakOk
+
+ check.multipleDefaults(s.Body.List)
+
+ for _, s := range s.Body.List {
+ clause, _ := s.(*ast.CommClause)
+ if clause == nil {
+ continue // error reported before
+ }
+
+ // clause.Comm must be a SendStmt, RecvStmt, or default case
+ valid := false
+ var rhs ast.Expr // rhs of RecvStmt, or nil
+ switch s := clause.Comm.(type) {
+ case nil, *ast.SendStmt:
+ valid = true
+ case *ast.AssignStmt:
+ if len(s.Rhs) == 1 {
+ rhs = s.Rhs[0]
+ }
+ case *ast.ExprStmt:
+ rhs = s.X
+ }
+
+ // if present, rhs must be a receive operation
+ if rhs != nil {
+ if x, _ := unparen(rhs).(*ast.UnaryExpr); x != nil && x.Op == token.ARROW {
+ valid = true
+ }
+ }
+
+ if !valid {
+ check.error(clause.Comm, InvalidSelectCase, "select case must be send or receive (possibly with assignment)")
+ continue
+ }
+
+ check.openScope(s, "case")
+ if clause.Comm != nil {
+ check.stmt(inner, clause.Comm)
+ }
+ check.stmtList(inner, clause.Body)
+ check.closeScope()
+ }
+
+ case *ast.ForStmt:
+ inner |= breakOk | continueOk
+ check.openScope(s, "for")
+ defer check.closeScope()
+
+ check.simpleStmt(s.Init)
+ if s.Cond != nil {
+ var x operand
+ check.expr(nil, &x, s.Cond)
+ if x.mode != invalid && !allBoolean(x.typ) {
+ check.error(s.Cond, InvalidCond, "non-boolean condition in for statement")
+ }
+ }
+ check.simpleStmt(s.Post)
+ // spec: "The init statement may be a short variable
+ // declaration, but the post statement must not."
+ if s, _ := s.Post.(*ast.AssignStmt); s != nil && s.Tok == token.DEFINE {
+ check.softErrorf(s, InvalidPostDecl, "cannot declare in post statement")
+ // Don't call useLHS here because we want to use the lhs in
+ // this erroneous statement so that we don't get errors about
+ // these lhs variables being declared and not used.
+ check.use(s.Lhs...) // avoid follow-up errors
+ }
+ check.stmt(inner, s.Body)
+
+ case *ast.RangeStmt:
+ inner |= breakOk | continueOk
+
+ // check expression to iterate over
+ var x operand
+ check.expr(nil, &x, s.X)
+
+ // determine key/value types
+ var key, val Type
+ if x.mode != invalid {
+ // Ranging over a type parameter is permitted if it has a core type.
+ var cause string
+ u := coreType(x.typ)
+ switch t := u.(type) {
+ case nil:
+ cause = check.sprintf("%s has no core type", x.typ)
+ case *Chan:
+ if s.Value != nil {
+ check.softErrorf(s.Value, InvalidIterVar, "range over %s permits only one iteration variable", &x)
+ // ok to continue
+ }
+ if t.dir == SendOnly {
+ cause = "receive from send-only channel"
+ }
+ }
+ key, val = rangeKeyVal(u)
+ if key == nil || cause != "" {
+ if cause == "" {
+ check.softErrorf(&x, InvalidRangeExpr, "cannot range over %s", &x)
+ } else {
+ check.softErrorf(&x, InvalidRangeExpr, "cannot range over %s (%s)", &x, cause)
+ }
+ // ok to continue
+ }
+ }
+
+ // Open the for-statement block scope now, after the range clause.
+ // Iteration variables declared with := need to go in this scope (was go.dev/issue/51437).
+ check.openScope(s, "range")
+ defer check.closeScope()
+
+ // check assignment to/declaration of iteration variables
+ // (irregular assignment, cannot easily map to existing assignment checks)
+
+ // lhs expressions and initialization value (rhs) types
+ lhs := [2]ast.Expr{s.Key, s.Value}
+ rhs := [2]Type{key, val} // key, val may be nil
+
+ if s.Tok == token.DEFINE {
+ // short variable declaration
+ var vars []*Var
+ for i, lhs := range lhs {
+ if lhs == nil {
+ continue
+ }
+
+ // determine lhs variable
+ var obj *Var
+ if ident, _ := lhs.(*ast.Ident); ident != nil {
+ // declare new variable
+ name := ident.Name
+ obj = NewVar(ident.Pos(), check.pkg, name, nil)
+ check.recordDef(ident, obj)
+ // _ variables don't count as new variables
+ if name != "_" {
+ vars = append(vars, obj)
+ }
+ } else {
+ check.errorf(lhs, InvalidSyntaxTree, "cannot declare %s", lhs)
+ obj = NewVar(lhs.Pos(), check.pkg, "_", nil) // dummy variable
+ }
+
+ // initialize lhs variable
+ if typ := rhs[i]; typ != nil {
+ x.mode = value
+ x.expr = lhs // we don't have a better rhs expression to use here
+ x.typ = typ
+ check.initVar(obj, &x, "range clause")
+ } else {
+ obj.typ = Typ[Invalid]
+ obj.used = true // don't complain about unused variable
+ }
+ }
+
+ // declare variables
+ if len(vars) > 0 {
+ scopePos := s.Body.Pos()
+ for _, obj := range vars {
+ check.declare(check.scope, nil /* recordDef already called */, obj, scopePos)
+ }
+ } else {
+ check.error(inNode(s, s.TokPos), NoNewVar, "no new variables on left side of :=")
+ }
+ } else {
+ // ordinary assignment
+ for i, lhs := range lhs {
+ if lhs == nil {
+ continue
+ }
+ if typ := rhs[i]; typ != nil {
+ x.mode = value
+ x.expr = lhs // we don't have a better rhs expression to use here
+ x.typ = typ
+ check.assignVar(lhs, nil, &x)
+ }
+ }
+ }
+
+ check.stmt(inner, s.Body)
+
+ default:
+ check.error(s, InvalidSyntaxTree, "invalid statement")
+ }
+}
+
+// rangeKeyVal returns the key and value type produced by a range clause
+// over an expression of type typ. If the range clause is not permitted
+// the results are nil.
+func rangeKeyVal(typ Type) (key, val Type) {
+ switch typ := arrayPtrDeref(typ).(type) {
+ case *Basic:
+ if isString(typ) {
+ return Typ[Int], universeRune // use 'rune' name
+ }
+ case *Array:
+ return Typ[Int], typ.elem
+ case *Slice:
+ return Typ[Int], typ.elem
+ case *Map:
+ return typ.key, typ.elem
+ case *Chan:
+ return typ.elem, Typ[Invalid]
+ }
+ return
+}
diff --git a/contrib/go/_std_1.21/src/go/types/struct.go b/contrib/go/_std_1.21/src/go/types/struct.go
new file mode 100644
index 0000000000..7247a25719
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/struct.go
@@ -0,0 +1,218 @@
+// 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 types
+
+import (
+ "go/ast"
+ "go/token"
+ . "internal/types/errors"
+ "strconv"
+)
+
+// ----------------------------------------------------------------------------
+// API
+
+// A Struct represents a struct type.
+type Struct struct {
+ fields []*Var // fields != nil indicates the struct is set up (possibly with len(fields) == 0)
+ tags []string // field tags; nil if there are no tags
+}
+
+// NewStruct returns a new struct with the given fields and corresponding field tags.
+// If a field with index i has a tag, tags[i] must be that tag, but len(tags) may be
+// only as long as required to hold the tag with the largest index i. Consequently,
+// if no field has a tag, tags may be nil.
+func NewStruct(fields []*Var, tags []string) *Struct {
+ var fset objset
+ for _, f := range fields {
+ if f.name != "_" && fset.insert(f) != nil {
+ panic("multiple fields with the same name")
+ }
+ }
+ if len(tags) > len(fields) {
+ panic("more tags than fields")
+ }
+ s := &Struct{fields: fields, tags: tags}
+ s.markComplete()
+ return s
+}
+
+// NumFields returns the number of fields in the struct (including blank and embedded fields).
+func (s *Struct) NumFields() int { return len(s.fields) }
+
+// Field returns the i'th field for 0 <= i < NumFields().
+func (s *Struct) Field(i int) *Var { return s.fields[i] }
+
+// Tag returns the i'th field tag for 0 <= i < NumFields().
+func (s *Struct) Tag(i int) string {
+ if i < len(s.tags) {
+ return s.tags[i]
+ }
+ return ""
+}
+
+func (t *Struct) Underlying() Type { return t }
+func (t *Struct) String() string { return TypeString(t, nil) }
+
+// ----------------------------------------------------------------------------
+// Implementation
+
+func (s *Struct) markComplete() {
+ if s.fields == nil {
+ s.fields = make([]*Var, 0)
+ }
+}
+
+func (check *Checker) structType(styp *Struct, e *ast.StructType) {
+ list := e.Fields
+ if list == nil {
+ styp.markComplete()
+ return
+ }
+
+ // struct fields and tags
+ var fields []*Var
+ var tags []string
+
+ // for double-declaration checks
+ var fset objset
+
+ // current field typ and tag
+ var typ Type
+ var tag string
+ add := func(ident *ast.Ident, embedded bool, pos token.Pos) {
+ if tag != "" && tags == nil {
+ tags = make([]string, len(fields))
+ }
+ if tags != nil {
+ tags = append(tags, tag)
+ }
+
+ name := ident.Name
+ fld := NewField(pos, check.pkg, name, typ, embedded)
+ // spec: "Within a struct, non-blank field names must be unique."
+ if name == "_" || check.declareInSet(&fset, pos, fld) {
+ fields = append(fields, fld)
+ check.recordDef(ident, fld)
+ }
+ }
+
+ // addInvalid adds an embedded field of invalid type to the struct for
+ // fields with errors; this keeps the number of struct fields in sync
+ // with the source as long as the fields are _ or have different names
+ // (go.dev/issue/25627).
+ addInvalid := func(ident *ast.Ident, pos token.Pos) {
+ typ = Typ[Invalid]
+ tag = ""
+ add(ident, true, pos)
+ }
+
+ for _, f := range list.List {
+ typ = check.varType(f.Type)
+ tag = check.tag(f.Tag)
+ if len(f.Names) > 0 {
+ // named fields
+ for _, name := range f.Names {
+ add(name, false, name.Pos())
+ }
+ } else {
+ // embedded field
+ // spec: "An embedded type must be specified as a type name T or as a
+ // pointer to a non-interface type name *T, and T itself may not be a
+ // pointer type."
+ pos := f.Type.Pos() // position of type, for errors
+ name := embeddedFieldIdent(f.Type)
+ if name == nil {
+ check.errorf(f.Type, InvalidSyntaxTree, "embedded field type %s has no name", f.Type)
+ name = ast.NewIdent("_")
+ name.NamePos = pos
+ addInvalid(name, pos)
+ continue
+ }
+ add(name, true, name.Pos()) // struct{p.T} field has position of T
+
+ // Because we have a name, typ must be of the form T or *T, where T is the name
+ // of a (named or alias) type, and t (= deref(typ)) must be the type of T.
+ // We must delay this check to the end because we don't want to instantiate
+ // (via under(t)) a possibly incomplete type.
+
+ // for use in the closure below
+ embeddedTyp := typ
+ embeddedPos := f.Type
+
+ check.later(func() {
+ t, isPtr := deref(embeddedTyp)
+ switch u := under(t).(type) {
+ case *Basic:
+ if t == Typ[Invalid] {
+ // error was reported before
+ return
+ }
+ // unsafe.Pointer is treated like a regular pointer
+ if u.kind == UnsafePointer {
+ check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer")
+ }
+ case *Pointer:
+ check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be a pointer")
+ case *Interface:
+ if isTypeParam(t) {
+ // The error code here is inconsistent with other error codes for
+ // invalid embedding, because this restriction may be relaxed in the
+ // future, and so it did not warrant a new error code.
+ check.error(embeddedPos, MisplacedTypeParam, "embedded field type cannot be a (pointer to a) type parameter")
+ break
+ }
+ if isPtr {
+ check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface")
+ }
+ }
+ }).describef(embeddedPos, "check embedded type %s", embeddedTyp)
+ }
+ }
+
+ styp.fields = fields
+ styp.tags = tags
+ styp.markComplete()
+}
+
+func embeddedFieldIdent(e ast.Expr) *ast.Ident {
+ switch e := e.(type) {
+ case *ast.Ident:
+ return e
+ case *ast.StarExpr:
+ // *T is valid, but **T is not
+ if _, ok := e.X.(*ast.StarExpr); !ok {
+ return embeddedFieldIdent(e.X)
+ }
+ case *ast.SelectorExpr:
+ return e.Sel
+ case *ast.IndexExpr:
+ return embeddedFieldIdent(e.X)
+ case *ast.IndexListExpr:
+ return embeddedFieldIdent(e.X)
+ }
+ return nil // invalid embedded field
+}
+
+func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool {
+ if alt := oset.insert(obj); alt != nil {
+ check.errorf(atPos(pos), DuplicateDecl, "%s redeclared", obj.Name())
+ check.reportAltDecl(alt)
+ return false
+ }
+ return true
+}
+
+func (check *Checker) tag(t *ast.BasicLit) string {
+ if t != nil {
+ if t.Kind == token.STRING {
+ if val, err := strconv.Unquote(t.Value); err == nil {
+ return val
+ }
+ }
+ check.errorf(t, InvalidSyntaxTree, "incorrect tag syntax: %q", t.Value)
+ }
+ return ""
+}
diff --git a/contrib/go/_std_1.21/src/go/types/subst.go b/contrib/go/_std_1.21/src/go/types/subst.go
new file mode 100644
index 0000000000..30c48e1bad
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/subst.go
@@ -0,0 +1,423 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2018 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.
+
+// This file implements type parameter substitution.
+
+package types
+
+import (
+ "go/token"
+)
+
+type substMap map[*TypeParam]Type
+
+// makeSubstMap creates a new substitution map mapping tpars[i] to targs[i].
+// If targs[i] is nil, tpars[i] is not substituted.
+func makeSubstMap(tpars []*TypeParam, targs []Type) substMap {
+ assert(len(tpars) == len(targs))
+ proj := make(substMap, len(tpars))
+ for i, tpar := range tpars {
+ proj[tpar] = targs[i]
+ }
+ return proj
+}
+
+// makeRenameMap is like makeSubstMap, but creates a map used to rename type
+// parameters in from with the type parameters in to.
+func makeRenameMap(from, to []*TypeParam) substMap {
+ assert(len(from) == len(to))
+ proj := make(substMap, len(from))
+ for i, tpar := range from {
+ proj[tpar] = to[i]
+ }
+ return proj
+}
+
+func (m substMap) empty() bool {
+ return len(m) == 0
+}
+
+func (m substMap) lookup(tpar *TypeParam) Type {
+ if t := m[tpar]; t != nil {
+ return t
+ }
+ return tpar
+}
+
+// subst returns the type typ with its type parameters tpars replaced by the
+// corresponding type arguments targs, recursively. subst doesn't modify the
+// incoming type. If a substitution took place, the result type is different
+// from the incoming type.
+//
+// If expanding is non-nil, it is the instance type currently being expanded.
+// One of expanding or ctxt must be non-nil.
+func (check *Checker) subst(pos token.Pos, typ Type, smap substMap, expanding *Named, ctxt *Context) Type {
+ assert(expanding != nil || ctxt != nil)
+
+ if smap.empty() {
+ return typ
+ }
+
+ // common cases
+ switch t := typ.(type) {
+ case *Basic:
+ return typ // nothing to do
+ case *TypeParam:
+ return smap.lookup(t)
+ }
+
+ // general case
+ subst := subster{
+ pos: pos,
+ smap: smap,
+ check: check,
+ expanding: expanding,
+ ctxt: ctxt,
+ }
+ return subst.typ(typ)
+}
+
+type subster struct {
+ pos token.Pos
+ smap substMap
+ check *Checker // nil if called via Instantiate
+ expanding *Named // if non-nil, the instance that is being expanded
+ ctxt *Context
+}
+
+func (subst *subster) typ(typ Type) Type {
+ switch t := typ.(type) {
+ case nil:
+ // Call typOrNil if it's possible that typ is nil.
+ panic("nil typ")
+
+ case *Basic:
+ // nothing to do
+
+ case *Array:
+ elem := subst.typOrNil(t.elem)
+ if elem != t.elem {
+ return &Array{len: t.len, elem: elem}
+ }
+
+ case *Slice:
+ elem := subst.typOrNil(t.elem)
+ if elem != t.elem {
+ return &Slice{elem: elem}
+ }
+
+ case *Struct:
+ if fields, copied := subst.varList(t.fields); copied {
+ s := &Struct{fields: fields, tags: t.tags}
+ s.markComplete()
+ return s
+ }
+
+ case *Pointer:
+ base := subst.typ(t.base)
+ if base != t.base {
+ return &Pointer{base: base}
+ }
+
+ case *Tuple:
+ return subst.tuple(t)
+
+ case *Signature:
+ // Preserve the receiver: it is handled during *Interface and *Named type
+ // substitution.
+ //
+ // Naively doing the substitution here can lead to an infinite recursion in
+ // the case where the receiver is an interface. For example, consider the
+ // following declaration:
+ //
+ // type T[A any] struct { f interface{ m() } }
+ //
+ // In this case, the type of f is an interface that is itself the receiver
+ // type of all of its methods. Because we have no type name to break
+ // cycles, substituting in the recv results in an infinite loop of
+ // recv->interface->recv->interface->...
+ recv := t.recv
+
+ params := subst.tuple(t.params)
+ results := subst.tuple(t.results)
+ if params != t.params || results != t.results {
+ return &Signature{
+ rparams: t.rparams,
+ // TODO(gri) why can't we nil out tparams here, rather than in instantiate?
+ tparams: t.tparams,
+ // instantiated signatures have a nil scope
+ recv: recv,
+ params: params,
+ results: results,
+ variadic: t.variadic,
+ }
+ }
+
+ case *Union:
+ terms, copied := subst.termlist(t.terms)
+ if copied {
+ // term list substitution may introduce duplicate terms (unlikely but possible).
+ // This is ok; lazy type set computation will determine the actual type set
+ // in normal form.
+ return &Union{terms}
+ }
+
+ case *Interface:
+ methods, mcopied := subst.funcList(t.methods)
+ embeddeds, ecopied := subst.typeList(t.embeddeds)
+ if mcopied || ecopied {
+ iface := subst.check.newInterface()
+ iface.embeddeds = embeddeds
+ iface.implicit = t.implicit
+ iface.complete = t.complete
+ // If we've changed the interface type, we may need to replace its
+ // receiver if the receiver type is the original interface. Receivers of
+ // *Named type are replaced during named type expansion.
+ //
+ // Notably, it's possible to reach here and not create a new *Interface,
+ // even though the receiver type may be parameterized. For example:
+ //
+ // type T[P any] interface{ m() }
+ //
+ // In this case the interface will not be substituted here, because its
+ // method signatures do not depend on the type parameter P, but we still
+ // need to create new interface methods to hold the instantiated
+ // receiver. This is handled by Named.expandUnderlying.
+ iface.methods, _ = replaceRecvType(methods, t, iface)
+ return iface
+ }
+
+ case *Map:
+ key := subst.typ(t.key)
+ elem := subst.typ(t.elem)
+ if key != t.key || elem != t.elem {
+ return &Map{key: key, elem: elem}
+ }
+
+ case *Chan:
+ elem := subst.typ(t.elem)
+ if elem != t.elem {
+ return &Chan{dir: t.dir, elem: elem}
+ }
+
+ case *Named:
+ // dump is for debugging
+ dump := func(string, ...interface{}) {}
+ if subst.check != nil && subst.check.conf._Trace {
+ subst.check.indent++
+ defer func() {
+ subst.check.indent--
+ }()
+ dump = func(format string, args ...interface{}) {
+ subst.check.trace(subst.pos, format, args...)
+ }
+ }
+
+ // subst is called during expansion, so in this function we need to be
+ // careful not to call any methods that would cause t to be expanded: doing
+ // so would result in deadlock.
+ //
+ // So we call t.Origin().TypeParams() rather than t.TypeParams().
+ orig := t.Origin()
+ n := orig.TypeParams().Len()
+ if n == 0 {
+ dump(">>> %s is not parameterized", t)
+ return t // type is not parameterized
+ }
+
+ var newTArgs []Type
+ if t.TypeArgs().Len() != n {
+ return Typ[Invalid] // error reported elsewhere
+ }
+
+ // already instantiated
+ dump(">>> %s already instantiated", t)
+ // For each (existing) type argument targ, determine if it needs
+ // to be substituted; i.e., if it is or contains a type parameter
+ // that has a type argument for it.
+ for i, targ := range t.TypeArgs().list() {
+ dump(">>> %d targ = %s", i, targ)
+ new_targ := subst.typ(targ)
+ if new_targ != targ {
+ dump(">>> substituted %d targ %s => %s", i, targ, new_targ)
+ if newTArgs == nil {
+ newTArgs = make([]Type, n)
+ copy(newTArgs, t.TypeArgs().list())
+ }
+ newTArgs[i] = new_targ
+ }
+ }
+
+ if newTArgs == nil {
+ dump(">>> nothing to substitute in %s", t)
+ return t // nothing to substitute
+ }
+
+ // Create a new instance and populate the context to avoid endless
+ // recursion. The position used here is irrelevant because validation only
+ // occurs on t (we don't call validType on named), but we use subst.pos to
+ // help with debugging.
+ return subst.check.instance(subst.pos, orig, newTArgs, subst.expanding, subst.ctxt)
+
+ case *TypeParam:
+ return subst.smap.lookup(t)
+
+ default:
+ unreachable()
+ }
+
+ return typ
+}
+
+// typOrNil is like typ but if the argument is nil it is replaced with Typ[Invalid].
+// A nil type may appear in pathological cases such as type T[P any] []func(_ T([]_))
+// where an array/slice element is accessed before it is set up.
+func (subst *subster) typOrNil(typ Type) Type {
+ if typ == nil {
+ return Typ[Invalid]
+ }
+ return subst.typ(typ)
+}
+
+func (subst *subster) var_(v *Var) *Var {
+ if v != nil {
+ if typ := subst.typ(v.typ); typ != v.typ {
+ return substVar(v, typ)
+ }
+ }
+ return v
+}
+
+func substVar(v *Var, typ Type) *Var {
+ copy := *v
+ copy.typ = typ
+ copy.origin = v.Origin()
+ return &copy
+}
+
+func (subst *subster) tuple(t *Tuple) *Tuple {
+ if t != nil {
+ if vars, copied := subst.varList(t.vars); copied {
+ return &Tuple{vars: vars}
+ }
+ }
+ return t
+}
+
+func (subst *subster) varList(in []*Var) (out []*Var, copied bool) {
+ out = in
+ for i, v := range in {
+ if w := subst.var_(v); w != v {
+ if !copied {
+ // first variable that got substituted => allocate new out slice
+ // and copy all variables
+ new := make([]*Var, len(in))
+ copy(new, out)
+ out = new
+ copied = true
+ }
+ out[i] = w
+ }
+ }
+ return
+}
+
+func (subst *subster) func_(f *Func) *Func {
+ if f != nil {
+ if typ := subst.typ(f.typ); typ != f.typ {
+ return substFunc(f, typ)
+ }
+ }
+ return f
+}
+
+func substFunc(f *Func, typ Type) *Func {
+ copy := *f
+ copy.typ = typ
+ copy.origin = f.Origin()
+ return &copy
+}
+
+func (subst *subster) funcList(in []*Func) (out []*Func, copied bool) {
+ out = in
+ for i, f := range in {
+ if g := subst.func_(f); g != f {
+ if !copied {
+ // first function that got substituted => allocate new out slice
+ // and copy all functions
+ new := make([]*Func, len(in))
+ copy(new, out)
+ out = new
+ copied = true
+ }
+ out[i] = g
+ }
+ }
+ return
+}
+
+func (subst *subster) typeList(in []Type) (out []Type, copied bool) {
+ out = in
+ for i, t := range in {
+ if u := subst.typ(t); u != t {
+ if !copied {
+ // first function that got substituted => allocate new out slice
+ // and copy all functions
+ new := make([]Type, len(in))
+ copy(new, out)
+ out = new
+ copied = true
+ }
+ out[i] = u
+ }
+ }
+ return
+}
+
+func (subst *subster) termlist(in []*Term) (out []*Term, copied bool) {
+ out = in
+ for i, t := range in {
+ if u := subst.typ(t.typ); u != t.typ {
+ if !copied {
+ // first function that got substituted => allocate new out slice
+ // and copy all functions
+ new := make([]*Term, len(in))
+ copy(new, out)
+ out = new
+ copied = true
+ }
+ out[i] = NewTerm(t.tilde, u)
+ }
+ }
+ return
+}
+
+// replaceRecvType updates any function receivers that have type old to have
+// type new. It does not modify the input slice; if modifications are required,
+// the input slice and any affected signatures will be copied before mutating.
+//
+// The resulting out slice contains the updated functions, and copied reports
+// if anything was modified.
+func replaceRecvType(in []*Func, old, new Type) (out []*Func, copied bool) {
+ out = in
+ for i, method := range in {
+ sig := method.Type().(*Signature)
+ if sig.recv != nil && sig.recv.Type() == old {
+ if !copied {
+ // Allocate a new methods slice before mutating for the first time.
+ // This is defensive, as we may share methods across instantiations of
+ // a given interface type if they do not get substituted.
+ out = make([]*Func, len(in))
+ copy(out, in)
+ copied = true
+ }
+ newsig := *sig
+ newsig.recv = substVar(sig.recv, new)
+ out[i] = substFunc(method, &newsig)
+ }
+ }
+ return
+}
diff --git a/contrib/go/_std_1.21/src/go/types/termlist.go b/contrib/go/_std_1.21/src/go/types/termlist.go
new file mode 100644
index 0000000000..9bc631c0e6
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/termlist.go
@@ -0,0 +1,163 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// 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 types
+
+import "strings"
+
+// A termlist represents the type set represented by the union
+// t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn.
+// A termlist is in normal form if all terms are disjoint.
+// termlist operations don't require the operands to be in
+// normal form.
+type termlist []*term
+
+// allTermlist represents the set of all types.
+// It is in normal form.
+var allTermlist = termlist{new(term)}
+
+// termSep is the separator used between individual terms.
+const termSep = " | "
+
+// String prints the termlist exactly (without normalization).
+func (xl termlist) String() string {
+ if len(xl) == 0 {
+ return "∅"
+ }
+ var buf strings.Builder
+ for i, x := range xl {
+ if i > 0 {
+ buf.WriteString(termSep)
+ }
+ buf.WriteString(x.String())
+ }
+ return buf.String()
+}
+
+// isEmpty reports whether the termlist xl represents the empty set of types.
+func (xl termlist) isEmpty() bool {
+ // If there's a non-nil term, the entire list is not empty.
+ // If the termlist is in normal form, this requires at most
+ // one iteration.
+ for _, x := range xl {
+ if x != nil {
+ return false
+ }
+ }
+ return true
+}
+
+// isAll reports whether the termlist xl represents the set of all types.
+func (xl termlist) isAll() bool {
+ // If there's a 𝓤 term, the entire list is 𝓤.
+ // If the termlist is in normal form, this requires at most
+ // one iteration.
+ for _, x := range xl {
+ if x != nil && x.typ == nil {
+ return true
+ }
+ }
+ return false
+}
+
+// norm returns the normal form of xl.
+func (xl termlist) norm() termlist {
+ // Quadratic algorithm, but good enough for now.
+ // TODO(gri) fix asymptotic performance
+ used := make([]bool, len(xl))
+ var rl termlist
+ for i, xi := range xl {
+ if xi == nil || used[i] {
+ continue
+ }
+ for j := i + 1; j < len(xl); j++ {
+ xj := xl[j]
+ if xj == nil || used[j] {
+ continue
+ }
+ if u1, u2 := xi.union(xj); u2 == nil {
+ // If we encounter a 𝓤 term, the entire list is 𝓤.
+ // Exit early.
+ // (Note that this is not just an optimization;
+ // if we continue, we may end up with a 𝓤 term
+ // and other terms and the result would not be
+ // in normal form.)
+ if u1.typ == nil {
+ return allTermlist
+ }
+ xi = u1
+ used[j] = true // xj is now unioned into xi - ignore it in future iterations
+ }
+ }
+ rl = append(rl, xi)
+ }
+ return rl
+}
+
+// union returns the union xl ∪ yl.
+func (xl termlist) union(yl termlist) termlist {
+ return append(xl, yl...).norm()
+}
+
+// intersect returns the intersection xl ∩ yl.
+func (xl termlist) intersect(yl termlist) termlist {
+ if xl.isEmpty() || yl.isEmpty() {
+ return nil
+ }
+
+ // Quadratic algorithm, but good enough for now.
+ // TODO(gri) fix asymptotic performance
+ var rl termlist
+ for _, x := range xl {
+ for _, y := range yl {
+ if r := x.intersect(y); r != nil {
+ rl = append(rl, r)
+ }
+ }
+ }
+ return rl.norm()
+}
+
+// equal reports whether xl and yl represent the same type set.
+func (xl termlist) equal(yl termlist) bool {
+ // TODO(gri) this should be more efficient
+ return xl.subsetOf(yl) && yl.subsetOf(xl)
+}
+
+// includes reports whether t ∈ xl.
+func (xl termlist) includes(t Type) bool {
+ for _, x := range xl {
+ if x.includes(t) {
+ return true
+ }
+ }
+ return false
+}
+
+// supersetOf reports whether y ⊆ xl.
+func (xl termlist) supersetOf(y *term) bool {
+ for _, x := range xl {
+ if y.subsetOf(x) {
+ return true
+ }
+ }
+ return false
+}
+
+// subsetOf reports whether xl ⊆ yl.
+func (xl termlist) subsetOf(yl termlist) bool {
+ if yl.isEmpty() {
+ return xl.isEmpty()
+ }
+
+ // each term x of xl must be a subset of yl
+ for _, x := range xl {
+ if !yl.supersetOf(x) {
+ return false // x is not a subset yl
+ }
+ }
+ return true
+}
diff --git a/contrib/go/_std_1.21/src/go/types/tuple.go b/contrib/go/_std_1.21/src/go/types/tuple.go
new file mode 100644
index 0000000000..e5e3914bb2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/tuple.go
@@ -0,0 +1,36 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2011 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 types
+
+// A Tuple represents an ordered list of variables; a nil *Tuple is a valid (empty) tuple.
+// Tuples are used as components of signatures and to represent the type of multiple
+// assignments; they are not first class types of Go.
+type Tuple struct {
+ vars []*Var
+}
+
+// NewTuple returns a new tuple for the given variables.
+func NewTuple(x ...*Var) *Tuple {
+ if len(x) > 0 {
+ return &Tuple{vars: x}
+ }
+ return nil
+}
+
+// Len returns the number variables of tuple t.
+func (t *Tuple) Len() int {
+ if t != nil {
+ return len(t.vars)
+ }
+ return 0
+}
+
+// At returns the i'th variable of tuple t.
+func (t *Tuple) At(i int) *Var { return t.vars[i] }
+
+func (t *Tuple) Underlying() Type { return t }
+func (t *Tuple) String() string { return TypeString(t, nil) }
diff --git a/contrib/go/_std_1.21/src/go/types/type.go b/contrib/go/_std_1.21/src/go/types/type.go
new file mode 100644
index 0000000000..f6bd75908f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/type.go
@@ -0,0 +1,15 @@
+// Copyright 2011 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 types
+
+// A Type represents a type of Go.
+// All types implement the Type interface.
+type Type interface {
+ // Underlying returns the underlying type of a type.
+ Underlying() Type
+
+ // String returns a string representation of a type.
+ String() string
+}
diff --git a/contrib/go/_std_1.21/src/go/types/typelists.go b/contrib/go/_std_1.21/src/go/types/typelists.go
new file mode 100644
index 0000000000..c000de2272
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/typelists.go
@@ -0,0 +1,71 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// 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 types
+
+// TypeParamList holds a list of type parameters.
+type TypeParamList struct{ tparams []*TypeParam }
+
+// Len returns the number of type parameters in the list.
+// It is safe to call on a nil receiver.
+func (l *TypeParamList) Len() int { return len(l.list()) }
+
+// At returns the i'th type parameter in the list.
+func (l *TypeParamList) At(i int) *TypeParam { return l.tparams[i] }
+
+// list is for internal use where we expect a []*TypeParam.
+// TODO(rfindley): list should probably be eliminated: we can pass around a
+// TypeParamList instead.
+func (l *TypeParamList) list() []*TypeParam {
+ if l == nil {
+ return nil
+ }
+ return l.tparams
+}
+
+// TypeList holds a list of types.
+type TypeList struct{ types []Type }
+
+// newTypeList returns a new TypeList with the types in list.
+func newTypeList(list []Type) *TypeList {
+ if len(list) == 0 {
+ return nil
+ }
+ return &TypeList{list}
+}
+
+// Len returns the number of types in the list.
+// It is safe to call on a nil receiver.
+func (l *TypeList) Len() int { return len(l.list()) }
+
+// At returns the i'th type in the list.
+func (l *TypeList) At(i int) Type { return l.types[i] }
+
+// list is for internal use where we expect a []Type.
+// TODO(rfindley): list should probably be eliminated: we can pass around a
+// TypeList instead.
+func (l *TypeList) list() []Type {
+ if l == nil {
+ return nil
+ }
+ return l.types
+}
+
+// ----------------------------------------------------------------------------
+// Implementation
+
+func bindTParams(list []*TypeParam) *TypeParamList {
+ if len(list) == 0 {
+ return nil
+ }
+ for i, typ := range list {
+ if typ.index >= 0 {
+ panic("type parameter bound more than once")
+ }
+ typ.index = i
+ }
+ return &TypeParamList{tparams: list}
+}
diff --git a/contrib/go/_std_1.21/src/go/types/typeparam.go b/contrib/go/_std_1.21/src/go/types/typeparam.go
new file mode 100644
index 0000000000..763fcc61f0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/typeparam.go
@@ -0,0 +1,158 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2011 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 types
+
+import "sync/atomic"
+
+// Note: This is a uint32 rather than a uint64 because the
+// respective 64 bit atomic instructions are not available
+// on all platforms.
+var lastID uint32
+
+// nextID returns a value increasing monotonically by 1 with
+// each call, starting with 1. It may be called concurrently.
+func nextID() uint64 { return uint64(atomic.AddUint32(&lastID, 1)) }
+
+// A TypeParam represents a type parameter type.
+type TypeParam struct {
+ check *Checker // for lazy type bound completion
+ id uint64 // unique id, for debugging only
+ obj *TypeName // corresponding type name
+ index int // type parameter index in source order, starting at 0
+ bound Type // any type, but underlying is eventually *Interface for correct programs (see TypeParam.iface)
+}
+
+// NewTypeParam returns a new TypeParam. Type parameters may be set on a Named
+// or Signature type by calling SetTypeParams. Setting a type parameter on more
+// than one type will result in a panic.
+//
+// The constraint argument can be nil, and set later via SetConstraint. If the
+// constraint is non-nil, it must be fully defined.
+func NewTypeParam(obj *TypeName, constraint Type) *TypeParam {
+ return (*Checker)(nil).newTypeParam(obj, constraint)
+}
+
+// check may be nil
+func (check *Checker) newTypeParam(obj *TypeName, constraint Type) *TypeParam {
+ // Always increment lastID, even if it is not used.
+ id := nextID()
+ if check != nil {
+ check.nextID++
+ id = check.nextID
+ }
+ typ := &TypeParam{check: check, id: id, obj: obj, index: -1, bound: constraint}
+ if obj.typ == nil {
+ obj.typ = typ
+ }
+ // iface may mutate typ.bound, so we must ensure that iface() is called
+ // at least once before the resulting TypeParam escapes.
+ if check != nil {
+ check.needsCleanup(typ)
+ } else if constraint != nil {
+ typ.iface()
+ }
+ return typ
+}
+
+// Obj returns the type name for the type parameter t.
+func (t *TypeParam) Obj() *TypeName { return t.obj }
+
+// Index returns the index of the type param within its param list, or -1 if
+// the type parameter has not yet been bound to a type.
+func (t *TypeParam) Index() int {
+ return t.index
+}
+
+// Constraint returns the type constraint specified for t.
+func (t *TypeParam) Constraint() Type {
+ return t.bound
+}
+
+// SetConstraint sets the type constraint for t.
+//
+// It must be called by users of NewTypeParam after the bound's underlying is
+// fully defined, and before using the type parameter in any way other than to
+// form other types. Once SetConstraint returns the receiver, t is safe for
+// concurrent use.
+func (t *TypeParam) SetConstraint(bound Type) {
+ if bound == nil {
+ panic("nil constraint")
+ }
+ t.bound = bound
+ // iface may mutate t.bound (if bound is not an interface), so ensure that
+ // this is done before returning.
+ t.iface()
+}
+
+func (t *TypeParam) Underlying() Type {
+ return t.iface()
+}
+
+func (t *TypeParam) String() string { return TypeString(t, nil) }
+
+// ----------------------------------------------------------------------------
+// Implementation
+
+func (t *TypeParam) cleanup() {
+ t.iface()
+ t.check = nil
+}
+
+// iface returns the constraint interface of t.
+func (t *TypeParam) iface() *Interface {
+ bound := t.bound
+
+ // determine constraint interface
+ var ityp *Interface
+ switch u := under(bound).(type) {
+ case *Basic:
+ if u == Typ[Invalid] {
+ // error is reported elsewhere
+ return &emptyInterface
+ }
+ case *Interface:
+ if isTypeParam(bound) {
+ // error is reported in Checker.collectTypeParams
+ return &emptyInterface
+ }
+ ityp = u
+ }
+
+ // If we don't have an interface, wrap constraint into an implicit interface.
+ if ityp == nil {
+ ityp = NewInterfaceType(nil, []Type{bound})
+ ityp.implicit = true
+ t.bound = ityp // update t.bound for next time (optimization)
+ }
+
+ // compute type set if necessary
+ if ityp.tset == nil {
+ // pos is used for tracing output; start with the type parameter position.
+ pos := t.obj.pos
+ // use the (original or possibly instantiated) type bound position if we have one
+ if n, _ := bound.(*Named); n != nil {
+ pos = n.obj.pos
+ }
+ computeInterfaceTypeSet(t.check, pos, ityp)
+ }
+
+ return ityp
+}
+
+// is calls f with the specific type terms of t's constraint and reports whether
+// all calls to f returned true. If there are no specific terms, is
+// returns the result of f(nil).
+func (t *TypeParam) is(f func(*term) bool) bool {
+ return t.iface().typeSet().is(f)
+}
+
+// underIs calls f with the underlying types of the specific type terms
+// of t's constraint and reports whether all calls to f returned true.
+// If there are no specific terms, underIs returns the result of f(nil).
+func (t *TypeParam) underIs(f func(Type) bool) bool {
+ return t.iface().typeSet().underIs(f)
+}
diff --git a/contrib/go/_std_1.21/src/go/types/typeset.go b/contrib/go/_std_1.21/src/go/types/typeset.go
new file mode 100644
index 0000000000..206aa3da08
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/typeset.go
@@ -0,0 +1,414 @@
+// 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 types
+
+import (
+ "go/token"
+ . "internal/types/errors"
+ "sort"
+ "strings"
+)
+
+// ----------------------------------------------------------------------------
+// API
+
+// A _TypeSet represents the type set of an interface.
+// Because of existing language restrictions, methods can be "factored out"
+// from the terms. The actual type set is the intersection of the type set
+// implied by the methods and the type set described by the terms and the
+// comparable bit. To test whether a type is included in a type set
+// ("implements" relation), the type must implement all methods _and_ be
+// an element of the type set described by the terms and the comparable bit.
+// If the term list describes the set of all types and comparable is true,
+// only comparable types are meant; in all other cases comparable is false.
+type _TypeSet struct {
+ methods []*Func // all methods of the interface; sorted by unique ID
+ terms termlist // type terms of the type set
+ comparable bool // invariant: !comparable || terms.isAll()
+}
+
+// IsEmpty reports whether type set s is the empty set.
+func (s *_TypeSet) IsEmpty() bool { return s.terms.isEmpty() }
+
+// IsAll reports whether type set s is the set of all types (corresponding to the empty interface).
+func (s *_TypeSet) IsAll() bool { return s.IsMethodSet() && len(s.methods) == 0 }
+
+// IsMethodSet reports whether the interface t is fully described by its method set.
+func (s *_TypeSet) IsMethodSet() bool { return !s.comparable && s.terms.isAll() }
+
+// IsComparable reports whether each type in the set is comparable.
+func (s *_TypeSet) IsComparable(seen map[Type]bool) bool {
+ if s.terms.isAll() {
+ return s.comparable
+ }
+ return s.is(func(t *term) bool {
+ return t != nil && comparable(t.typ, false, seen, nil)
+ })
+}
+
+// NumMethods returns the number of methods available.
+func (s *_TypeSet) NumMethods() int { return len(s.methods) }
+
+// Method returns the i'th method of type set s for 0 <= i < s.NumMethods().
+// The methods are ordered by their unique ID.
+func (s *_TypeSet) Method(i int) *Func { return s.methods[i] }
+
+// LookupMethod returns the index of and method with matching package and name, or (-1, nil).
+func (s *_TypeSet) LookupMethod(pkg *Package, name string, foldCase bool) (int, *Func) {
+ return lookupMethod(s.methods, pkg, name, foldCase)
+}
+
+func (s *_TypeSet) String() string {
+ switch {
+ case s.IsEmpty():
+ return "∅"
+ case s.IsAll():
+ return "𝓤"
+ }
+
+ hasMethods := len(s.methods) > 0
+ hasTerms := s.hasTerms()
+
+ var buf strings.Builder
+ buf.WriteByte('{')
+ if s.comparable {
+ buf.WriteString("comparable")
+ if hasMethods || hasTerms {
+ buf.WriteString("; ")
+ }
+ }
+ for i, m := range s.methods {
+ if i > 0 {
+ buf.WriteString("; ")
+ }
+ buf.WriteString(m.String())
+ }
+ if hasMethods && hasTerms {
+ buf.WriteString("; ")
+ }
+ if hasTerms {
+ buf.WriteString(s.terms.String())
+ }
+ buf.WriteString("}")
+ return buf.String()
+}
+
+// ----------------------------------------------------------------------------
+// Implementation
+
+// hasTerms reports whether the type set has specific type terms.
+func (s *_TypeSet) hasTerms() bool { return !s.terms.isEmpty() && !s.terms.isAll() }
+
+// subsetOf reports whether s1 ⊆ s2.
+func (s1 *_TypeSet) subsetOf(s2 *_TypeSet) bool { return s1.terms.subsetOf(s2.terms) }
+
+// TODO(gri) TypeSet.is and TypeSet.underIs should probably also go into termlist.go
+
+// is calls f with the specific type terms of s and reports whether
+// all calls to f returned true. If there are no specific terms, is
+// returns the result of f(nil).
+func (s *_TypeSet) is(f func(*term) bool) bool {
+ if !s.hasTerms() {
+ return f(nil)
+ }
+ for _, t := range s.terms {
+ assert(t.typ != nil)
+ if !f(t) {
+ return false
+ }
+ }
+ return true
+}
+
+// underIs calls f with the underlying types of the specific type terms
+// of s and reports whether all calls to f returned true. If there are
+// no specific terms, underIs returns the result of f(nil).
+func (s *_TypeSet) underIs(f func(Type) bool) bool {
+ if !s.hasTerms() {
+ return f(nil)
+ }
+ for _, t := range s.terms {
+ assert(t.typ != nil)
+ // x == under(x) for ~x terms
+ u := t.typ
+ if !t.tilde {
+ u = under(u)
+ }
+ if debug {
+ assert(Identical(u, under(u)))
+ }
+ if !f(u) {
+ return false
+ }
+ }
+ return true
+}
+
+// topTypeSet may be used as type set for the empty interface.
+var topTypeSet = _TypeSet{terms: allTermlist}
+
+// computeInterfaceTypeSet may be called with check == nil.
+func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_TypeSet {
+ if ityp.tset != nil {
+ return ityp.tset
+ }
+
+ // If the interface is not fully set up yet, the type set will
+ // not be complete, which may lead to errors when using the
+ // type set (e.g. missing method). Don't compute a partial type
+ // set (and don't store it!), so that we still compute the full
+ // type set eventually. Instead, return the top type set and
+ // let any follow-on errors play out.
+ //
+ // TODO(gri) Consider recording when this happens and reporting
+ // it as an error (but only if there were no other errors so to
+ // to not have unnecessary follow-on errors).
+ if !ityp.complete {
+ return &topTypeSet
+ }
+
+ if check != nil && check.conf._Trace {
+ // Types don't generally have position information.
+ // If we don't have a valid pos provided, try to use
+ // one close enough.
+ if !pos.IsValid() && len(ityp.methods) > 0 {
+ pos = ityp.methods[0].pos
+ }
+
+ check.trace(pos, "-- type set for %s", ityp)
+ check.indent++
+ defer func() {
+ check.indent--
+ check.trace(pos, "=> %s ", ityp.typeSet())
+ }()
+ }
+
+ // An infinitely expanding interface (due to a cycle) is detected
+ // elsewhere (Checker.validType), so here we simply assume we only
+ // have valid interfaces. Mark the interface as complete to avoid
+ // infinite recursion if the validType check occurs later for some
+ // reason.
+ ityp.tset = &_TypeSet{terms: allTermlist} // TODO(gri) is this sufficient?
+
+ var unionSets map[*Union]*_TypeSet
+ if check != nil {
+ if check.unionTypeSets == nil {
+ check.unionTypeSets = make(map[*Union]*_TypeSet)
+ }
+ unionSets = check.unionTypeSets
+ } else {
+ unionSets = make(map[*Union]*_TypeSet)
+ }
+
+ // Methods of embedded interfaces are collected unchanged; i.e., the identity
+ // of a method I.m's Func Object of an interface I is the same as that of
+ // the method m in an interface that embeds interface I. On the other hand,
+ // if a method is embedded via multiple overlapping embedded interfaces, we
+ // don't provide a guarantee which "original m" got chosen for the embedding
+ // interface. See also go.dev/issue/34421.
+ //
+ // If we don't care to provide this identity guarantee anymore, instead of
+ // reusing the original method in embeddings, we can clone the method's Func
+ // Object and give it the position of a corresponding embedded interface. Then
+ // we can get rid of the mpos map below and simply use the cloned method's
+ // position.
+
+ var seen objset
+ var allMethods []*Func
+ mpos := make(map[*Func]token.Pos) // method specification or method embedding position, for good error messages
+ addMethod := func(pos token.Pos, m *Func, explicit bool) {
+ switch other := seen.insert(m); {
+ case other == nil:
+ allMethods = append(allMethods, m)
+ mpos[m] = pos
+ case explicit:
+ if check != nil {
+ check.errorf(atPos(pos), DuplicateDecl, "duplicate method %s", m.name)
+ check.errorf(atPos(mpos[other.(*Func)]), DuplicateDecl, "\tother declaration of %s", m.name) // secondary error, \t indented
+ }
+ default:
+ // We have a duplicate method name in an embedded (not explicitly declared) method.
+ // Check method signatures after all types are computed (go.dev/issue/33656).
+ // If we're pre-go1.14 (overlapping embeddings are not permitted), report that
+ // error here as well (even though we could do it eagerly) because it's the same
+ // error message.
+ if check != nil {
+ check.later(func() {
+ if !check.allowVersion(m.pkg, atPos(pos), go1_14) || !Identical(m.typ, other.Type()) {
+ check.errorf(atPos(pos), DuplicateDecl, "duplicate method %s", m.name)
+ check.errorf(atPos(mpos[other.(*Func)]), DuplicateDecl, "\tother declaration of %s", m.name) // secondary error, \t indented
+ }
+ }).describef(atPos(pos), "duplicate method check for %s", m.name)
+ }
+ }
+ }
+
+ for _, m := range ityp.methods {
+ addMethod(m.pos, m, true)
+ }
+
+ // collect embedded elements
+ allTerms := allTermlist
+ allComparable := false
+ for i, typ := range ityp.embeddeds {
+ // The embedding position is nil for imported interfaces
+ // and also for interface copies after substitution (but
+ // in that case we don't need to report errors again).
+ var pos token.Pos // embedding position
+ if ityp.embedPos != nil {
+ pos = (*ityp.embedPos)[i]
+ }
+ var comparable bool
+ var terms termlist
+ switch u := under(typ).(type) {
+ case *Interface:
+ // For now we don't permit type parameters as constraints.
+ assert(!isTypeParam(typ))
+ tset := computeInterfaceTypeSet(check, pos, u)
+ // If typ is local, an error was already reported where typ is specified/defined.
+ if check != nil && check.isImportedConstraint(typ) && !check.verifyVersionf(atPos(pos), go1_18, "embedding constraint interface %s", typ) {
+ continue
+ }
+ comparable = tset.comparable
+ for _, m := range tset.methods {
+ addMethod(pos, m, false) // use embedding position pos rather than m.pos
+ }
+ terms = tset.terms
+ case *Union:
+ if check != nil && !check.verifyVersionf(atPos(pos), go1_18, "embedding interface element %s", u) {
+ continue
+ }
+ tset := computeUnionTypeSet(check, unionSets, pos, u)
+ if tset == &invalidTypeSet {
+ continue // ignore invalid unions
+ }
+ assert(!tset.comparable)
+ assert(len(tset.methods) == 0)
+ terms = tset.terms
+ default:
+ if u == Typ[Invalid] {
+ continue
+ }
+ if check != nil && !check.verifyVersionf(atPos(pos), go1_18, "embedding non-interface type %s", typ) {
+ continue
+ }
+ terms = termlist{{false, typ}}
+ }
+
+ // The type set of an interface is the intersection of the type sets of all its elements.
+ // Due to language restrictions, only embedded interfaces can add methods, they are handled
+ // separately. Here we only need to intersect the term lists and comparable bits.
+ allTerms, allComparable = intersectTermLists(allTerms, allComparable, terms, comparable)
+ }
+ ityp.embedPos = nil // not needed anymore (errors have been reported)
+
+ ityp.tset.comparable = allComparable
+ if len(allMethods) != 0 {
+ sortMethods(allMethods)
+ ityp.tset.methods = allMethods
+ }
+ ityp.tset.terms = allTerms
+
+ return ityp.tset
+}
+
+// TODO(gri) The intersectTermLists function belongs to the termlist implementation.
+// The comparable type set may also be best represented as a term (using
+// a special type).
+
+// intersectTermLists computes the intersection of two term lists and respective comparable bits.
+// xcomp, ycomp are valid only if xterms.isAll() and yterms.isAll() respectively.
+func intersectTermLists(xterms termlist, xcomp bool, yterms termlist, ycomp bool) (termlist, bool) {
+ terms := xterms.intersect(yterms)
+ // If one of xterms or yterms is marked as comparable,
+ // the result must only include comparable types.
+ comp := xcomp || ycomp
+ if comp && !terms.isAll() {
+ // only keep comparable terms
+ i := 0
+ for _, t := range terms {
+ assert(t.typ != nil)
+ if comparable(t.typ, false /* strictly comparable */, nil, nil) {
+ terms[i] = t
+ i++
+ }
+ }
+ terms = terms[:i]
+ if !terms.isAll() {
+ comp = false
+ }
+ }
+ assert(!comp || terms.isAll()) // comparable invariant
+ return terms, comp
+}
+
+func sortMethods(list []*Func) {
+ sort.Sort(byUniqueMethodName(list))
+}
+
+func assertSortedMethods(list []*Func) {
+ if !debug {
+ panic("assertSortedMethods called outside debug mode")
+ }
+ if !sort.IsSorted(byUniqueMethodName(list)) {
+ panic("methods not sorted")
+ }
+}
+
+// byUniqueMethodName method lists can be sorted by their unique method names.
+type byUniqueMethodName []*Func
+
+func (a byUniqueMethodName) Len() int { return len(a) }
+func (a byUniqueMethodName) Less(i, j int) bool { return a[i].less(&a[j].object) }
+func (a byUniqueMethodName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+
+// invalidTypeSet is a singleton type set to signal an invalid type set
+// due to an error. It's also a valid empty type set, so consumers of
+// type sets may choose to ignore it.
+var invalidTypeSet _TypeSet
+
+// computeUnionTypeSet may be called with check == nil.
+// The result is &invalidTypeSet if the union overflows.
+func computeUnionTypeSet(check *Checker, unionSets map[*Union]*_TypeSet, pos token.Pos, utyp *Union) *_TypeSet {
+ if tset, _ := unionSets[utyp]; tset != nil {
+ return tset
+ }
+
+ // avoid infinite recursion (see also computeInterfaceTypeSet)
+ unionSets[utyp] = new(_TypeSet)
+
+ var allTerms termlist
+ for _, t := range utyp.terms {
+ var terms termlist
+ u := under(t.typ)
+ if ui, _ := u.(*Interface); ui != nil {
+ // For now we don't permit type parameters as constraints.
+ assert(!isTypeParam(t.typ))
+ terms = computeInterfaceTypeSet(check, pos, ui).terms
+ } else if u == Typ[Invalid] {
+ continue
+ } else {
+ if t.tilde && !Identical(t.typ, u) {
+ // There is no underlying type which is t.typ.
+ // The corresponding type set is empty.
+ t = nil // ∅ term
+ }
+ terms = termlist{(*term)(t)}
+ }
+ // The type set of a union expression is the union
+ // of the type sets of each term.
+ allTerms = allTerms.union(terms)
+ if len(allTerms) > maxTermCount {
+ if check != nil {
+ check.errorf(atPos(pos), InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
+ }
+ unionSets[utyp] = &invalidTypeSet
+ return unionSets[utyp]
+ }
+ }
+ unionSets[utyp].terms = allTerms
+
+ return unionSets[utyp]
+}
diff --git a/contrib/go/_std_1.21/src/go/types/typestring.go b/contrib/go/_std_1.21/src/go/types/typestring.go
new file mode 100644
index 0000000000..9615e24157
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/typestring.go
@@ -0,0 +1,500 @@
+// Copyright 2013 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.
+
+// This file implements printing of types.
+
+package types
+
+import (
+ "bytes"
+ "fmt"
+ "go/token"
+ "sort"
+ "strconv"
+ "strings"
+ "unicode/utf8"
+)
+
+// A Qualifier controls how named package-level objects are printed in
+// calls to TypeString, ObjectString, and SelectionString.
+//
+// These three formatting routines call the Qualifier for each
+// package-level object O, and if the Qualifier returns a non-empty
+// string p, the object is printed in the form p.O.
+// If it returns an empty string, only the object name O is printed.
+//
+// Using a nil Qualifier is equivalent to using (*Package).Path: the
+// object is qualified by the import path, e.g., "encoding/json.Marshal".
+type Qualifier func(*Package) string
+
+// RelativeTo returns a Qualifier that fully qualifies members of
+// all packages other than pkg.
+func RelativeTo(pkg *Package) Qualifier {
+ if pkg == nil {
+ return nil
+ }
+ return func(other *Package) string {
+ if pkg == other {
+ return "" // same package; unqualified
+ }
+ return other.Path()
+ }
+}
+
+// TypeString returns the string representation of typ.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func TypeString(typ Type, qf Qualifier) string {
+ var buf bytes.Buffer
+ WriteType(&buf, typ, qf)
+ return buf.String()
+}
+
+// WriteType writes the string representation of typ to buf.
+// The Qualifier controls the printing of
+// package-level objects, and may be nil.
+func WriteType(buf *bytes.Buffer, typ Type, qf Qualifier) {
+ newTypeWriter(buf, qf).typ(typ)
+}
+
+// WriteSignature writes the representation of the signature sig to buf,
+// without a leading "func" keyword. The Qualifier controls the printing
+// of package-level objects, and may be nil.
+func WriteSignature(buf *bytes.Buffer, sig *Signature, qf Qualifier) {
+ newTypeWriter(buf, qf).signature(sig)
+}
+
+type typeWriter struct {
+ buf *bytes.Buffer
+ seen map[Type]bool
+ qf Qualifier
+ ctxt *Context // if non-nil, we are type hashing
+ tparams *TypeParamList // local type parameters
+ paramNames bool // if set, write function parameter names, otherwise, write types only
+ tpSubscripts bool // if set, write type parameter indices as subscripts
+ pkgInfo bool // package-annotate first unexported-type field to avoid confusing type description
+}
+
+func newTypeWriter(buf *bytes.Buffer, qf Qualifier) *typeWriter {
+ return &typeWriter{buf, make(map[Type]bool), qf, nil, nil, true, false, false}
+}
+
+func newTypeHasher(buf *bytes.Buffer, ctxt *Context) *typeWriter {
+ assert(ctxt != nil)
+ return &typeWriter{buf, make(map[Type]bool), nil, ctxt, nil, false, false, false}
+}
+
+func (w *typeWriter) byte(b byte) {
+ if w.ctxt != nil {
+ if b == ' ' {
+ b = '#'
+ }
+ w.buf.WriteByte(b)
+ return
+ }
+ w.buf.WriteByte(b)
+ if b == ',' || b == ';' {
+ w.buf.WriteByte(' ')
+ }
+}
+
+func (w *typeWriter) string(s string) {
+ w.buf.WriteString(s)
+}
+
+func (w *typeWriter) error(msg string) {
+ if w.ctxt != nil {
+ panic(msg)
+ }
+ w.buf.WriteString("<" + msg + ">")
+}
+
+func (w *typeWriter) typ(typ Type) {
+ if w.seen[typ] {
+ w.error("cycle to " + goTypeName(typ))
+ return
+ }
+ w.seen[typ] = true
+ defer delete(w.seen, typ)
+
+ switch t := typ.(type) {
+ case nil:
+ w.error("nil")
+
+ case *Basic:
+ // exported basic types go into package unsafe
+ // (currently this is just unsafe.Pointer)
+ if token.IsExported(t.name) {
+ if obj, _ := Unsafe.scope.Lookup(t.name).(*TypeName); obj != nil {
+ w.typeName(obj)
+ break
+ }
+ }
+ w.string(t.name)
+
+ case *Array:
+ w.byte('[')
+ w.string(strconv.FormatInt(t.len, 10))
+ w.byte(']')
+ w.typ(t.elem)
+
+ case *Slice:
+ w.string("[]")
+ w.typ(t.elem)
+
+ case *Struct:
+ w.string("struct{")
+ for i, f := range t.fields {
+ if i > 0 {
+ w.byte(';')
+ }
+
+ // If disambiguating one struct for another, look for the first unexported field.
+ // Do this first in case of nested structs; tag the first-outermost field.
+ pkgAnnotate := false
+ if w.qf == nil && w.pkgInfo && !token.IsExported(f.name) {
+ // note for embedded types, type name is field name, and "string" etc are lower case hence unexported.
+ pkgAnnotate = true
+ w.pkgInfo = false // only tag once
+ }
+
+ // This doesn't do the right thing for embedded type
+ // aliases where we should print the alias name, not
+ // the aliased type (see go.dev/issue/44410).
+ if !f.embedded {
+ w.string(f.name)
+ w.byte(' ')
+ }
+ w.typ(f.typ)
+ if pkgAnnotate {
+ w.string(" /* package ")
+ w.string(f.pkg.Path())
+ w.string(" */ ")
+ }
+ if tag := t.Tag(i); tag != "" {
+ w.byte(' ')
+ // TODO(rfindley) If tag contains blanks, replacing them with '#'
+ // in Context.TypeHash may produce another tag
+ // accidentally.
+ w.string(strconv.Quote(tag))
+ }
+ }
+ w.byte('}')
+
+ case *Pointer:
+ w.byte('*')
+ w.typ(t.base)
+
+ case *Tuple:
+ w.tuple(t, false)
+
+ case *Signature:
+ w.string("func")
+ w.signature(t)
+
+ case *Union:
+ // Unions only appear as (syntactic) embedded elements
+ // in interfaces and syntactically cannot be empty.
+ if t.Len() == 0 {
+ w.error("empty union")
+ break
+ }
+ for i, t := range t.terms {
+ if i > 0 {
+ w.string(termSep)
+ }
+ if t.tilde {
+ w.byte('~')
+ }
+ w.typ(t.typ)
+ }
+
+ case *Interface:
+ if w.ctxt == nil {
+ if t == universeAny.Type() {
+ // When not hashing, we can try to improve type strings by writing "any"
+ // for a type that is pointer-identical to universeAny. This logic should
+ // be deprecated by more robust handling for aliases.
+ w.string("any")
+ break
+ }
+ if t == universeComparable.Type().(*Named).underlying {
+ w.string("interface{comparable}")
+ break
+ }
+ }
+ if t.implicit {
+ if len(t.methods) == 0 && len(t.embeddeds) == 1 {
+ w.typ(t.embeddeds[0])
+ break
+ }
+ // Something's wrong with the implicit interface.
+ // Print it as such and continue.
+ w.string("/* implicit */ ")
+ }
+ w.string("interface{")
+ first := true
+ if w.ctxt != nil {
+ w.typeSet(t.typeSet())
+ } else {
+ for _, m := range t.methods {
+ if !first {
+ w.byte(';')
+ }
+ first = false
+ w.string(m.name)
+ w.signature(m.typ.(*Signature))
+ }
+ for _, typ := range t.embeddeds {
+ if !first {
+ w.byte(';')
+ }
+ first = false
+ w.typ(typ)
+ }
+ }
+ w.byte('}')
+
+ case *Map:
+ w.string("map[")
+ w.typ(t.key)
+ w.byte(']')
+ w.typ(t.elem)
+
+ case *Chan:
+ var s string
+ var parens bool
+ switch t.dir {
+ case SendRecv:
+ s = "chan "
+ // chan (<-chan T) requires parentheses
+ if c, _ := t.elem.(*Chan); c != nil && c.dir == RecvOnly {
+ parens = true
+ }
+ case SendOnly:
+ s = "chan<- "
+ case RecvOnly:
+ s = "<-chan "
+ default:
+ w.error("unknown channel direction")
+ }
+ w.string(s)
+ if parens {
+ w.byte('(')
+ }
+ w.typ(t.elem)
+ if parens {
+ w.byte(')')
+ }
+
+ case *Named:
+ // If hashing, write a unique prefix for t to represent its identity, since
+ // named type identity is pointer identity.
+ if w.ctxt != nil {
+ w.string(strconv.Itoa(w.ctxt.getID(t)))
+ }
+ w.typeName(t.obj) // when hashing written for readability of the hash only
+ if t.inst != nil {
+ // instantiated type
+ w.typeList(t.inst.targs.list())
+ } else if w.ctxt == nil && t.TypeParams().Len() != 0 { // For type hashing, don't need to format the TypeParams
+ // parameterized type
+ w.tParamList(t.TypeParams().list())
+ }
+
+ case *TypeParam:
+ if t.obj == nil {
+ w.error("unnamed type parameter")
+ break
+ }
+ if i := tparamIndex(w.tparams.list(), t); i >= 0 {
+ // The names of type parameters that are declared by the type being
+ // hashed are not part of the type identity. Replace them with a
+ // placeholder indicating their index.
+ w.string(fmt.Sprintf("$%d", i))
+ } else {
+ w.string(t.obj.name)
+ if w.tpSubscripts || w.ctxt != nil {
+ w.string(subscript(t.id))
+ }
+ // If the type parameter name is the same as a predeclared object
+ // (say int), point out where it is declared to avoid confusing
+ // error messages. This doesn't need to be super-elegant; we just
+ // need a clear indication that this is not a predeclared name.
+ // Note: types2 prints position information here - we can't do
+ // that because we don't have a token.FileSet accessible.
+ if w.ctxt == nil && Universe.Lookup(t.obj.name) != nil {
+ w.string("/* type parameter */")
+ }
+ }
+
+ default:
+ // For externally defined implementations of Type.
+ // Note: In this case cycles won't be caught.
+ w.string(t.String())
+ }
+}
+
+// typeSet writes a canonical hash for an interface type set.
+func (w *typeWriter) typeSet(s *_TypeSet) {
+ assert(w.ctxt != nil)
+ first := true
+ for _, m := range s.methods {
+ if !first {
+ w.byte(';')
+ }
+ first = false
+ w.string(m.name)
+ w.signature(m.typ.(*Signature))
+ }
+ switch {
+ case s.terms.isAll():
+ // nothing to do
+ case s.terms.isEmpty():
+ w.string(s.terms.String())
+ default:
+ var termHashes []string
+ for _, term := range s.terms {
+ // terms are not canonically sorted, so we sort their hashes instead.
+ var buf bytes.Buffer
+ if term.tilde {
+ buf.WriteByte('~')
+ }
+ newTypeHasher(&buf, w.ctxt).typ(term.typ)
+ termHashes = append(termHashes, buf.String())
+ }
+ sort.Strings(termHashes)
+ if !first {
+ w.byte(';')
+ }
+ w.string(strings.Join(termHashes, "|"))
+ }
+}
+
+func (w *typeWriter) typeList(list []Type) {
+ w.byte('[')
+ for i, typ := range list {
+ if i > 0 {
+ w.byte(',')
+ }
+ w.typ(typ)
+ }
+ w.byte(']')
+}
+
+func (w *typeWriter) tParamList(list []*TypeParam) {
+ w.byte('[')
+ var prev Type
+ for i, tpar := range list {
+ // Determine the type parameter and its constraint.
+ // list is expected to hold type parameter names,
+ // but don't crash if that's not the case.
+ if tpar == nil {
+ w.error("nil type parameter")
+ continue
+ }
+ if i > 0 {
+ if tpar.bound != prev {
+ // bound changed - write previous one before advancing
+ w.byte(' ')
+ w.typ(prev)
+ }
+ w.byte(',')
+ }
+ prev = tpar.bound
+ w.typ(tpar)
+ }
+ if prev != nil {
+ w.byte(' ')
+ w.typ(prev)
+ }
+ w.byte(']')
+}
+
+func (w *typeWriter) typeName(obj *TypeName) {
+ w.string(packagePrefix(obj.pkg, w.qf))
+ w.string(obj.name)
+}
+
+func (w *typeWriter) tuple(tup *Tuple, variadic bool) {
+ w.byte('(')
+ if tup != nil {
+ for i, v := range tup.vars {
+ if i > 0 {
+ w.byte(',')
+ }
+ // parameter names are ignored for type identity and thus type hashes
+ if w.ctxt == nil && v.name != "" && w.paramNames {
+ w.string(v.name)
+ w.byte(' ')
+ }
+ typ := v.typ
+ if variadic && i == len(tup.vars)-1 {
+ if s, ok := typ.(*Slice); ok {
+ w.string("...")
+ typ = s.elem
+ } else {
+ // special case:
+ // append(s, "foo"...) leads to signature func([]byte, string...)
+ if t, _ := under(typ).(*Basic); t == nil || t.kind != String {
+ w.error("expected string type")
+ continue
+ }
+ w.typ(typ)
+ w.string("...")
+ continue
+ }
+ }
+ w.typ(typ)
+ }
+ }
+ w.byte(')')
+}
+
+func (w *typeWriter) signature(sig *Signature) {
+ if sig.TypeParams().Len() != 0 {
+ if w.ctxt != nil {
+ assert(w.tparams == nil)
+ w.tparams = sig.TypeParams()
+ defer func() {
+ w.tparams = nil
+ }()
+ }
+ w.tParamList(sig.TypeParams().list())
+ }
+
+ w.tuple(sig.params, sig.variadic)
+
+ n := sig.results.Len()
+ if n == 0 {
+ // no result
+ return
+ }
+
+ w.byte(' ')
+ if n == 1 && (w.ctxt != nil || sig.results.vars[0].name == "") {
+ // single unnamed result (if type hashing, name must be ignored)
+ w.typ(sig.results.vars[0].typ)
+ return
+ }
+
+ // multiple or named result(s)
+ w.tuple(sig.results, false)
+}
+
+// subscript returns the decimal (utf8) representation of x using subscript digits.
+func subscript(x uint64) string {
+ const w = len("₀") // all digits 0...9 have the same utf8 width
+ var buf [32 * w]byte
+ i := len(buf)
+ for {
+ i -= w
+ utf8.EncodeRune(buf[i:], '₀'+rune(x%10)) // '₀' == U+2080
+ x /= 10
+ if x == 0 {
+ break
+ }
+ }
+ return string(buf[i:])
+}
diff --git a/contrib/go/_std_1.21/src/go/types/typeterm.go b/contrib/go/_std_1.21/src/go/types/typeterm.go
new file mode 100644
index 0000000000..c86442c43f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/typeterm.go
@@ -0,0 +1,167 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// 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 types
+
+// A term describes elementary type sets:
+//
+// ∅: (*term)(nil) == ∅ // set of no types (empty set)
+// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse)
+// T: &term{false, T} == {T} // set of type T
+// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t
+type term struct {
+ tilde bool // valid if typ != nil
+ typ Type
+}
+
+func (x *term) String() string {
+ switch {
+ case x == nil:
+ return "∅"
+ case x.typ == nil:
+ return "𝓤"
+ case x.tilde:
+ return "~" + x.typ.String()
+ default:
+ return x.typ.String()
+ }
+}
+
+// equal reports whether x and y represent the same type set.
+func (x *term) equal(y *term) bool {
+ // easy cases
+ switch {
+ case x == nil || y == nil:
+ return x == y
+ case x.typ == nil || y.typ == nil:
+ return x.typ == y.typ
+ }
+ // ∅ ⊂ x, y ⊂ 𝓤
+
+ return x.tilde == y.tilde && Identical(x.typ, y.typ)
+}
+
+// union returns the union x ∪ y: zero, one, or two non-nil terms.
+func (x *term) union(y *term) (_, _ *term) {
+ // easy cases
+ switch {
+ case x == nil && y == nil:
+ return nil, nil // ∅ ∪ ∅ == ∅
+ case x == nil:
+ return y, nil // ∅ ∪ y == y
+ case y == nil:
+ return x, nil // x ∪ ∅ == x
+ case x.typ == nil:
+ return x, nil // 𝓤 ∪ y == 𝓤
+ case y.typ == nil:
+ return y, nil // x ∪ 𝓤 == 𝓤
+ }
+ // ∅ ⊂ x, y ⊂ 𝓤
+
+ if x.disjoint(y) {
+ return x, y // x ∪ y == (x, y) if x ∩ y == ∅
+ }
+ // x.typ == y.typ
+
+ // ~t ∪ ~t == ~t
+ // ~t ∪ T == ~t
+ // T ∪ ~t == ~t
+ // T ∪ T == T
+ if x.tilde || !y.tilde {
+ return x, nil
+ }
+ return y, nil
+}
+
+// intersect returns the intersection x ∩ y.
+func (x *term) intersect(y *term) *term {
+ // easy cases
+ switch {
+ case x == nil || y == nil:
+ return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅
+ case x.typ == nil:
+ return y // 𝓤 ∩ y == y
+ case y.typ == nil:
+ return x // x ∩ 𝓤 == x
+ }
+ // ∅ ⊂ x, y ⊂ 𝓤
+
+ if x.disjoint(y) {
+ return nil // x ∩ y == ∅ if x ∩ y == ∅
+ }
+ // x.typ == y.typ
+
+ // ~t ∩ ~t == ~t
+ // ~t ∩ T == T
+ // T ∩ ~t == T
+ // T ∩ T == T
+ if !x.tilde || y.tilde {
+ return x
+ }
+ return y
+}
+
+// includes reports whether t ∈ x.
+func (x *term) includes(t Type) bool {
+ // easy cases
+ switch {
+ case x == nil:
+ return false // t ∈ ∅ == false
+ case x.typ == nil:
+ return true // t ∈ 𝓤 == true
+ }
+ // ∅ ⊂ x ⊂ 𝓤
+
+ u := t
+ if x.tilde {
+ u = under(u)
+ }
+ return Identical(x.typ, u)
+}
+
+// subsetOf reports whether x ⊆ y.
+func (x *term) subsetOf(y *term) bool {
+ // easy cases
+ switch {
+ case x == nil:
+ return true // ∅ ⊆ y == true
+ case y == nil:
+ return false // x ⊆ ∅ == false since x != ∅
+ case y.typ == nil:
+ return true // x ⊆ 𝓤 == true
+ case x.typ == nil:
+ return false // 𝓤 ⊆ y == false since y != 𝓤
+ }
+ // ∅ ⊂ x, y ⊂ 𝓤
+
+ if x.disjoint(y) {
+ return false // x ⊆ y == false if x ∩ y == ∅
+ }
+ // x.typ == y.typ
+
+ // ~t ⊆ ~t == true
+ // ~t ⊆ T == false
+ // T ⊆ ~t == true
+ // T ⊆ T == true
+ return !x.tilde || y.tilde
+}
+
+// disjoint reports whether x ∩ y == ∅.
+// x.typ and y.typ must not be nil.
+func (x *term) disjoint(y *term) bool {
+ if debug && (x.typ == nil || y.typ == nil) {
+ panic("invalid argument(s)")
+ }
+ ux := x.typ
+ if y.tilde {
+ ux = under(ux)
+ }
+ uy := y.typ
+ if x.tilde {
+ uy = under(uy)
+ }
+ return !Identical(ux, uy)
+}
diff --git a/contrib/go/_std_1.21/src/go/types/typexpr.go b/contrib/go/_std_1.21/src/go/types/typexpr.go
new file mode 100644
index 0000000000..ca390ab922
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/typexpr.go
@@ -0,0 +1,522 @@
+// Copyright 2013 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.
+
+// This file implements type-checking of identifiers and type expressions.
+
+package types
+
+import (
+ "fmt"
+ "go/ast"
+ "go/constant"
+ "go/internal/typeparams"
+ . "internal/types/errors"
+ "strings"
+)
+
+// ident type-checks identifier e and initializes x with the value or type of e.
+// If an error occurred, x.mode is set to invalid.
+// For the meaning of def, see Checker.definedType, below.
+// If wantType is set, the identifier e is expected to denote a type.
+func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, wantType bool) {
+ x.mode = invalid
+ x.expr = e
+
+ // Note that we cannot use check.lookup here because the returned scope
+ // may be different from obj.Parent(). See also Scope.LookupParent doc.
+ scope, obj := check.scope.LookupParent(e.Name, check.pos)
+ switch obj {
+ case nil:
+ if e.Name == "_" {
+ // Blank identifiers are never declared, but the current identifier may
+ // be a placeholder for a receiver type parameter. In this case we can
+ // resolve its type and object from Checker.recvTParamMap.
+ if tpar := check.recvTParamMap[e]; tpar != nil {
+ x.mode = typexpr
+ x.typ = tpar
+ } else {
+ check.error(e, InvalidBlank, "cannot use _ as value or type")
+ }
+ } else {
+ check.errorf(e, UndeclaredName, "undefined: %s", e.Name)
+ }
+ return
+ case universeAny, universeComparable:
+ if !check.verifyVersionf(e, go1_18, "predeclared %s", e.Name) {
+ return // avoid follow-on errors
+ }
+ }
+ check.recordUse(e, obj)
+
+ // Type-check the object.
+ // Only call Checker.objDecl if the object doesn't have a type yet
+ // (in which case we must actually determine it) or the object is a
+ // TypeName and we also want a type (in which case we might detect
+ // a cycle which needs to be reported). Otherwise we can skip the
+ // call and avoid a possible cycle error in favor of the more
+ // informative "not a type/value" error that this function's caller
+ // will issue (see go.dev/issue/25790).
+ typ := obj.Type()
+ if _, gotType := obj.(*TypeName); typ == nil || gotType && wantType {
+ check.objDecl(obj, def)
+ typ = obj.Type() // type must have been assigned by Checker.objDecl
+ }
+ assert(typ != nil)
+
+ // The object may have been dot-imported.
+ // If so, mark the respective package as used.
+ // (This code is only needed for dot-imports. Without them,
+ // we only have to mark variables, see *Var case below).
+ if pkgName := check.dotImportMap[dotImportKey{scope, obj.Name()}]; pkgName != nil {
+ pkgName.used = true
+ }
+
+ switch obj := obj.(type) {
+ case *PkgName:
+ check.errorf(e, InvalidPkgUse, "use of package %s not in selector", obj.name)
+ return
+
+ case *Const:
+ check.addDeclDep(obj)
+ if typ == Typ[Invalid] {
+ return
+ }
+ if obj == universeIota {
+ if check.iota == nil {
+ check.error(e, InvalidIota, "cannot use iota outside constant declaration")
+ return
+ }
+ x.val = check.iota
+ } else {
+ x.val = obj.val
+ }
+ assert(x.val != nil)
+ x.mode = constant_
+
+ case *TypeName:
+ if check.isBrokenAlias(obj) {
+ check.errorf(e, InvalidDeclCycle, "invalid use of type alias %s in recursive type (see go.dev/issue/50729)", obj.name)
+ return
+ }
+ x.mode = typexpr
+
+ case *Var:
+ // It's ok to mark non-local variables, but ignore variables
+ // from other packages to avoid potential race conditions with
+ // dot-imported variables.
+ if obj.pkg == check.pkg {
+ obj.used = true
+ }
+ check.addDeclDep(obj)
+ if typ == Typ[Invalid] {
+ return
+ }
+ x.mode = variable
+
+ case *Func:
+ check.addDeclDep(obj)
+ x.mode = value
+
+ case *Builtin:
+ x.id = obj.id
+ x.mode = builtin
+
+ case *Nil:
+ x.mode = value
+
+ default:
+ unreachable()
+ }
+
+ x.typ = typ
+}
+
+// typ type-checks the type expression e and returns its type, or Typ[Invalid].
+// The type must not be an (uninstantiated) generic type.
+func (check *Checker) typ(e ast.Expr) Type {
+ return check.definedType(e, nil)
+}
+
+// varType type-checks the type expression e and returns its type, or Typ[Invalid].
+// The type must not be an (uninstantiated) generic type and it must not be a
+// constraint interface.
+func (check *Checker) varType(e ast.Expr) Type {
+ typ := check.definedType(e, nil)
+ check.validVarType(e, typ)
+ return typ
+}
+
+// validVarType reports an error if typ is a constraint interface.
+// The expression e is used for error reporting, if any.
+func (check *Checker) validVarType(e ast.Expr, typ Type) {
+ // If we have a type parameter there's nothing to do.
+ if isTypeParam(typ) {
+ return
+ }
+
+ // We don't want to call under() or complete interfaces while we are in
+ // the middle of type-checking parameter declarations that might belong
+ // to interface methods. Delay this check to the end of type-checking.
+ check.later(func() {
+ if t, _ := under(typ).(*Interface); t != nil {
+ tset := computeInterfaceTypeSet(check, e.Pos(), t) // TODO(gri) is this the correct position?
+ if !tset.IsMethodSet() {
+ if tset.comparable {
+ check.softErrorf(e, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface is (or embeds) comparable", typ)
+ } else {
+ check.softErrorf(e, MisplacedConstraintIface, "cannot use type %s outside a type constraint: interface contains type constraints", typ)
+ }
+ }
+ }
+ }).describef(e, "check var type %s", typ)
+}
+
+// definedType is like typ but also accepts a type name def.
+// If def != nil, e is the type specification for the defined type def, declared
+// in a type declaration, and def.underlying will be set to the type of e before
+// any components of e are type-checked.
+func (check *Checker) definedType(e ast.Expr, def *Named) Type {
+ typ := check.typInternal(e, def)
+ assert(isTyped(typ))
+ if isGeneric(typ) {
+ check.errorf(e, WrongTypeArgCount, "cannot use generic type %s without instantiation", typ)
+ typ = Typ[Invalid]
+ }
+ check.recordTypeAndValue(e, typexpr, typ, nil)
+ return typ
+}
+
+// genericType is like typ but the type must be an (uninstantiated) generic
+// type. If cause is non-nil and the type expression was a valid type but not
+// generic, cause will be populated with a message describing the error.
+func (check *Checker) genericType(e ast.Expr, cause *string) Type {
+ typ := check.typInternal(e, nil)
+ assert(isTyped(typ))
+ if typ != Typ[Invalid] && !isGeneric(typ) {
+ if cause != nil {
+ *cause = check.sprintf("%s is not a generic type", typ)
+ }
+ typ = Typ[Invalid]
+ }
+ // TODO(gri) what is the correct call below?
+ check.recordTypeAndValue(e, typexpr, typ, nil)
+ return typ
+}
+
+// goTypeName returns the Go type name for typ and
+// removes any occurrences of "types." from that name.
+func goTypeName(typ Type) string {
+ return strings.ReplaceAll(fmt.Sprintf("%T", typ), "types.", "")
+}
+
+// typInternal drives type checking of types.
+// Must only be called by definedType or genericType.
+func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
+ if check.conf._Trace {
+ check.trace(e0.Pos(), "-- type %s", e0)
+ check.indent++
+ defer func() {
+ check.indent--
+ var under Type
+ if T != nil {
+ // Calling under() here may lead to endless instantiations.
+ // Test case: type T[P any] *T[P]
+ under = safeUnderlying(T)
+ }
+ if T == under {
+ check.trace(e0.Pos(), "=> %s // %s", T, goTypeName(T))
+ } else {
+ check.trace(e0.Pos(), "=> %s (under = %s) // %s", T, under, goTypeName(T))
+ }
+ }()
+ }
+
+ switch e := e0.(type) {
+ case *ast.BadExpr:
+ // ignore - error reported before
+
+ case *ast.Ident:
+ var x operand
+ check.ident(&x, e, def, true)
+
+ switch x.mode {
+ case typexpr:
+ typ := x.typ
+ def.setUnderlying(typ)
+ return typ
+ case invalid:
+ // ignore - error reported before
+ case novalue:
+ check.errorf(&x, NotAType, "%s used as type", &x)
+ default:
+ check.errorf(&x, NotAType, "%s is not a type", &x)
+ }
+
+ case *ast.SelectorExpr:
+ var x operand
+ check.selector(&x, e, def, true)
+
+ switch x.mode {
+ case typexpr:
+ typ := x.typ
+ def.setUnderlying(typ)
+ return typ
+ case invalid:
+ // ignore - error reported before
+ case novalue:
+ check.errorf(&x, NotAType, "%s used as type", &x)
+ default:
+ check.errorf(&x, NotAType, "%s is not a type", &x)
+ }
+
+ case *ast.IndexExpr, *ast.IndexListExpr:
+ ix := typeparams.UnpackIndexExpr(e)
+ check.verifyVersionf(inNode(e, ix.Lbrack), go1_18, "type instantiation")
+ return check.instantiatedType(ix, def)
+
+ case *ast.ParenExpr:
+ // Generic types must be instantiated before they can be used in any form.
+ // Consequently, generic types cannot be parenthesized.
+ return check.definedType(e.X, def)
+
+ case *ast.ArrayType:
+ if e.Len == nil {
+ typ := new(Slice)
+ def.setUnderlying(typ)
+ typ.elem = check.varType(e.Elt)
+ return typ
+ }
+
+ typ := new(Array)
+ def.setUnderlying(typ)
+ // Provide a more specific error when encountering a [...] array
+ // rather than leaving it to the handling of the ... expression.
+ if _, ok := e.Len.(*ast.Ellipsis); ok {
+ check.error(e.Len, BadDotDotDotSyntax, "invalid use of [...] array (outside a composite literal)")
+ typ.len = -1
+ } else {
+ typ.len = check.arrayLength(e.Len)
+ }
+ typ.elem = check.varType(e.Elt)
+ if typ.len >= 0 {
+ return typ
+ }
+ // report error if we encountered [...]
+
+ case *ast.Ellipsis:
+ // dots are handled explicitly where they are legal
+ // (array composite literals and parameter lists)
+ check.error(e, InvalidDotDotDot, "invalid use of '...'")
+ check.use(e.Elt)
+
+ case *ast.StructType:
+ typ := new(Struct)
+ def.setUnderlying(typ)
+ check.structType(typ, e)
+ return typ
+
+ case *ast.StarExpr:
+ typ := new(Pointer)
+ typ.base = Typ[Invalid] // avoid nil base in invalid recursive type declaration
+ def.setUnderlying(typ)
+ typ.base = check.varType(e.X)
+ return typ
+
+ case *ast.FuncType:
+ typ := new(Signature)
+ def.setUnderlying(typ)
+ check.funcType(typ, nil, e)
+ return typ
+
+ case *ast.InterfaceType:
+ typ := check.newInterface()
+ def.setUnderlying(typ)
+ check.interfaceType(typ, e, def)
+ return typ
+
+ case *ast.MapType:
+ typ := new(Map)
+ def.setUnderlying(typ)
+
+ typ.key = check.varType(e.Key)
+ typ.elem = check.varType(e.Value)
+
+ // spec: "The comparison operators == and != must be fully defined
+ // for operands of the key type; thus the key type must not be a
+ // function, map, or slice."
+ //
+ // Delay this check because it requires fully setup types;
+ // it is safe to continue in any case (was go.dev/issue/6667).
+ check.later(func() {
+ if !Comparable(typ.key) {
+ var why string
+ if isTypeParam(typ.key) {
+ why = " (missing comparable constraint)"
+ }
+ check.errorf(e.Key, IncomparableMapKey, "invalid map key type %s%s", typ.key, why)
+ }
+ }).describef(e.Key, "check map key %s", typ.key)
+
+ return typ
+
+ case *ast.ChanType:
+ typ := new(Chan)
+ def.setUnderlying(typ)
+
+ dir := SendRecv
+ switch e.Dir {
+ case ast.SEND | ast.RECV:
+ // nothing to do
+ case ast.SEND:
+ dir = SendOnly
+ case ast.RECV:
+ dir = RecvOnly
+ default:
+ check.errorf(e, InvalidSyntaxTree, "unknown channel direction %d", e.Dir)
+ // ok to continue
+ }
+
+ typ.dir = dir
+ typ.elem = check.varType(e.Value)
+ return typ
+
+ default:
+ check.errorf(e0, NotAType, "%s is not a type", e0)
+ check.use(e0)
+ }
+
+ typ := Typ[Invalid]
+ def.setUnderlying(typ)
+ return typ
+}
+
+func (check *Checker) instantiatedType(ix *typeparams.IndexExpr, def *Named) (res Type) {
+ if check.conf._Trace {
+ check.trace(ix.Pos(), "-- instantiating type %s with %s", ix.X, ix.Indices)
+ check.indent++
+ defer func() {
+ check.indent--
+ // Don't format the underlying here. It will always be nil.
+ check.trace(ix.Pos(), "=> %s", res)
+ }()
+ }
+
+ var cause string
+ gtyp := check.genericType(ix.X, &cause)
+ if cause != "" {
+ check.errorf(ix.Orig, NotAGenericType, invalidOp+"%s (%s)", ix.Orig, cause)
+ }
+ if gtyp == Typ[Invalid] {
+ return gtyp // error already reported
+ }
+
+ orig, _ := gtyp.(*Named)
+ if orig == nil {
+ panic(fmt.Sprintf("%v: cannot instantiate %v", ix.Pos(), gtyp))
+ }
+
+ // evaluate arguments
+ targs := check.typeList(ix.Indices)
+ if targs == nil {
+ def.setUnderlying(Typ[Invalid]) // avoid errors later due to lazy instantiation
+ return Typ[Invalid]
+ }
+
+ // create the instance
+ inst := check.instance(ix.Pos(), orig, targs, nil, check.context()).(*Named)
+ def.setUnderlying(inst)
+
+ // orig.tparams may not be set up, so we need to do expansion later.
+ check.later(func() {
+ // This is an instance from the source, not from recursive substitution,
+ // and so it must be resolved during type-checking so that we can report
+ // errors.
+ check.recordInstance(ix.Orig, inst.TypeArgs().list(), inst)
+
+ if check.validateTArgLen(ix.Pos(), inst.TypeParams().Len(), inst.TypeArgs().Len()) {
+ if i, err := check.verify(ix.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), check.context()); err != nil {
+ // best position for error reporting
+ pos := ix.Pos()
+ if i < len(ix.Indices) {
+ pos = ix.Indices[i].Pos()
+ }
+ check.softErrorf(atPos(pos), InvalidTypeArg, err.Error())
+ } else {
+ check.mono.recordInstance(check.pkg, ix.Pos(), inst.TypeParams().list(), inst.TypeArgs().list(), ix.Indices)
+ }
+ }
+
+ // TODO(rfindley): remove this call: we don't need to call validType here,
+ // as cycles can only occur for types used inside a Named type declaration,
+ // and so it suffices to call validType from declared types.
+ check.validType(inst)
+ }).describef(ix, "resolve instance %s", inst)
+
+ return inst
+}
+
+// arrayLength type-checks the array length expression e
+// and returns the constant length >= 0, or a value < 0
+// to indicate an error (and thus an unknown length).
+func (check *Checker) arrayLength(e ast.Expr) int64 {
+ // If e is an identifier, the array declaration might be an
+ // attempt at a parameterized type declaration with missing
+ // constraint. Provide an error message that mentions array
+ // length.
+ if name, _ := e.(*ast.Ident); name != nil {
+ obj := check.lookup(name.Name)
+ if obj == nil {
+ check.errorf(name, InvalidArrayLen, "undefined array length %s or missing type constraint", name.Name)
+ return -1
+ }
+ if _, ok := obj.(*Const); !ok {
+ check.errorf(name, InvalidArrayLen, "invalid array length %s", name.Name)
+ return -1
+ }
+ }
+
+ var x operand
+ check.expr(nil, &x, e)
+ if x.mode != constant_ {
+ if x.mode != invalid {
+ check.errorf(&x, InvalidArrayLen, "array length %s must be constant", &x)
+ }
+ return -1
+ }
+
+ if isUntyped(x.typ) || isInteger(x.typ) {
+ if val := constant.ToInt(x.val); val.Kind() == constant.Int {
+ if representableConst(val, check, Typ[Int], nil) {
+ if n, ok := constant.Int64Val(val); ok && n >= 0 {
+ return n
+ }
+ }
+ }
+ }
+
+ var msg string
+ if isInteger(x.typ) {
+ msg = "invalid array length %s"
+ } else {
+ msg = "array length %s must be integer"
+ }
+ check.errorf(&x, InvalidArrayLen, msg, &x)
+ return -1
+}
+
+// typeList provides the list of types corresponding to the incoming expression list.
+// If an error occurred, the result is nil, but all list elements were type-checked.
+func (check *Checker) typeList(list []ast.Expr) []Type {
+ res := make([]Type, len(list)) // res != nil even if len(list) == 0
+ for i, x := range list {
+ t := check.varType(x)
+ if t == Typ[Invalid] {
+ res = nil
+ }
+ if res != nil {
+ res[i] = t
+ }
+ }
+ return res
+}
diff --git a/contrib/go/_std_1.21/src/go/types/under.go b/contrib/go/_std_1.21/src/go/types/under.go
new file mode 100644
index 0000000000..f17d3bcda4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/under.go
@@ -0,0 +1,116 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2011 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 types
+
+// under returns the true expanded underlying type.
+// If it doesn't exist, the result is Typ[Invalid].
+// under must only be called when a type is known
+// to be fully set up.
+func under(t Type) Type {
+ if t, _ := t.(*Named); t != nil {
+ return t.under()
+ }
+ return t.Underlying()
+}
+
+// If t is not a type parameter, coreType returns the underlying type.
+// If t is a type parameter, coreType returns the single underlying
+// type of all types in its type set if it exists, or nil otherwise. If the
+// type set contains only unrestricted and restricted channel types (with
+// identical element types), the single underlying type is the restricted
+// channel type if the restrictions are always the same, or nil otherwise.
+func coreType(t Type) Type {
+ tpar, _ := t.(*TypeParam)
+ if tpar == nil {
+ return under(t)
+ }
+
+ var su Type
+ if tpar.underIs(func(u Type) bool {
+ if u == nil {
+ return false
+ }
+ if su != nil {
+ u = match(su, u)
+ if u == nil {
+ return false
+ }
+ }
+ // su == nil || match(su, u) != nil
+ su = u
+ return true
+ }) {
+ return su
+ }
+ return nil
+}
+
+// coreString is like coreType but also considers []byte
+// and strings as identical. In this case, if successful and we saw
+// a string, the result is of type (possibly untyped) string.
+func coreString(t Type) Type {
+ tpar, _ := t.(*TypeParam)
+ if tpar == nil {
+ return under(t) // string or untyped string
+ }
+
+ var su Type
+ hasString := false
+ if tpar.underIs(func(u Type) bool {
+ if u == nil {
+ return false
+ }
+ if isString(u) {
+ u = NewSlice(universeByte)
+ hasString = true
+ }
+ if su != nil {
+ u = match(su, u)
+ if u == nil {
+ return false
+ }
+ }
+ // su == nil || match(su, u) != nil
+ su = u
+ return true
+ }) {
+ if hasString {
+ return Typ[String]
+ }
+ return su
+ }
+ return nil
+}
+
+// If x and y are identical, match returns x.
+// If x and y are identical channels but for their direction
+// and one of them is unrestricted, match returns the channel
+// with the restricted direction.
+// In all other cases, match returns nil.
+func match(x, y Type) Type {
+ // Common case: we don't have channels.
+ if Identical(x, y) {
+ return x
+ }
+
+ // We may have channels that differ in direction only.
+ if x, _ := x.(*Chan); x != nil {
+ if y, _ := y.(*Chan); y != nil && Identical(x.elem, y.elem) {
+ // We have channels that differ in direction only.
+ // If there's an unrestricted channel, select the restricted one.
+ switch {
+ case x.dir == SendRecv:
+ return y
+ case y.dir == SendRecv:
+ return x
+ }
+ }
+ }
+
+ // types are different
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/go/types/unify.go b/contrib/go/_std_1.21/src/go/types/unify.go
new file mode 100644
index 0000000000..6680d97b86
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/unify.go
@@ -0,0 +1,795 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// 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.
+
+// This file implements type unification.
+//
+// Type unification attempts to make two types x and y structurally
+// equivalent by determining the types for a given list of (bound)
+// type parameters which may occur within x and y. If x and y are
+// structurally different (say []T vs chan T), or conflicting
+// types are determined for type parameters, unification fails.
+// If unification succeeds, as a side-effect, the types of the
+// bound type parameters may be determined.
+//
+// Unification typically requires multiple calls u.unify(x, y) to
+// a given unifier u, with various combinations of types x and y.
+// In each call, additional type parameter types may be determined
+// as a side effect and recorded in u.
+// If a call fails (returns false), unification fails.
+//
+// In the unification context, structural equivalence of two types
+// ignores the difference between a defined type and its underlying
+// type if one type is a defined type and the other one is not.
+// It also ignores the difference between an (external, unbound)
+// type parameter and its core type.
+// If two types are not structurally equivalent, they cannot be Go
+// identical types. On the other hand, if they are structurally
+// equivalent, they may be Go identical or at least assignable, or
+// they may be in the type set of a constraint.
+// Whether they indeed are identical or assignable is determined
+// upon instantiation and function argument passing.
+
+package types
+
+import (
+ "bytes"
+ "fmt"
+ "sort"
+ "strings"
+)
+
+const (
+ // Upper limit for recursion depth. Used to catch infinite recursions
+ // due to implementation issues (e.g., see issues go.dev/issue/48619, go.dev/issue/48656).
+ unificationDepthLimit = 50
+
+ // Whether to panic when unificationDepthLimit is reached.
+ // If disabled, a recursion depth overflow results in a (quiet)
+ // unification failure.
+ panicAtUnificationDepthLimit = true
+
+ // If enableCoreTypeUnification is set, unification will consider
+ // the core types, if any, of non-local (unbound) type parameters.
+ enableCoreTypeUnification = true
+
+ // If traceInference is set, unification will print a trace of its operation.
+ // Interpretation of trace:
+ // x ≡ y attempt to unify types x and y
+ // p ➞ y type parameter p is set to type y (p is inferred to be y)
+ // p ⇄ q type parameters p and q match (p is inferred to be q and vice versa)
+ // x ≢ y types x and y cannot be unified
+ // [p, q, ...] ➞ [x, y, ...] mapping from type parameters to types
+ traceInference = false
+)
+
+// A unifier maintains a list of type parameters and
+// corresponding types inferred for each type parameter.
+// A unifier is created by calling newUnifier.
+type unifier struct {
+ // handles maps each type parameter to its inferred type through
+ // an indirection *Type called (inferred type) "handle".
+ // Initially, each type parameter has its own, separate handle,
+ // with a nil (i.e., not yet inferred) type.
+ // After a type parameter P is unified with a type parameter Q,
+ // P and Q share the same handle (and thus type). This ensures
+ // that inferring the type for a given type parameter P will
+ // automatically infer the same type for all other parameters
+ // unified (joined) with P.
+ handles map[*TypeParam]*Type
+ depth int // recursion depth during unification
+ enableInterfaceInference bool // use shared methods for better inference
+}
+
+// newUnifier returns a new unifier initialized with the given type parameter
+// and corresponding type argument lists. The type argument list may be shorter
+// than the type parameter list, and it may contain nil types. Matching type
+// parameters and arguments must have the same index.
+func newUnifier(tparams []*TypeParam, targs []Type, enableInterfaceInference bool) *unifier {
+ assert(len(tparams) >= len(targs))
+ handles := make(map[*TypeParam]*Type, len(tparams))
+ // Allocate all handles up-front: in a correct program, all type parameters
+ // must be resolved and thus eventually will get a handle.
+ // Also, sharing of handles caused by unified type parameters is rare and
+ // so it's ok to not optimize for that case (and delay handle allocation).
+ for i, x := range tparams {
+ var t Type
+ if i < len(targs) {
+ t = targs[i]
+ }
+ handles[x] = &t
+ }
+ return &unifier{handles, 0, enableInterfaceInference}
+}
+
+// unifyMode controls the behavior of the unifier.
+type unifyMode uint
+
+const (
+ // If assign is set, we are unifying types involved in an assignment:
+ // they may match inexactly at the top, but element types must match
+ // exactly.
+ assign unifyMode = 1 << iota
+
+ // If exact is set, types unify if they are identical (or can be
+ // made identical with suitable arguments for type parameters).
+ // Otherwise, a named type and a type literal unify if their
+ // underlying types unify, channel directions are ignored, and
+ // if there is an interface, the other type must implement the
+ // interface.
+ exact
+)
+
+func (m unifyMode) String() string {
+ switch m {
+ case 0:
+ return "inexact"
+ case assign:
+ return "assign"
+ case exact:
+ return "exact"
+ case assign | exact:
+ return "assign, exact"
+ }
+ return fmt.Sprintf("mode %d", m)
+}
+
+// unify attempts to unify x and y and reports whether it succeeded.
+// As a side-effect, types may be inferred for type parameters.
+// The mode parameter controls how types are compared.
+func (u *unifier) unify(x, y Type, mode unifyMode) bool {
+ return u.nify(x, y, mode, nil)
+}
+
+func (u *unifier) tracef(format string, args ...interface{}) {
+ fmt.Println(strings.Repeat(". ", u.depth) + sprintf(nil, nil, true, format, args...))
+}
+
+// String returns a string representation of the current mapping
+// from type parameters to types.
+func (u *unifier) String() string {
+ // sort type parameters for reproducible strings
+ tparams := make(typeParamsById, len(u.handles))
+ i := 0
+ for tpar := range u.handles {
+ tparams[i] = tpar
+ i++
+ }
+ sort.Sort(tparams)
+
+ var buf bytes.Buffer
+ w := newTypeWriter(&buf, nil)
+ w.byte('[')
+ for i, x := range tparams {
+ if i > 0 {
+ w.string(", ")
+ }
+ w.typ(x)
+ w.string(": ")
+ w.typ(u.at(x))
+ }
+ w.byte(']')
+ return buf.String()
+}
+
+type typeParamsById []*TypeParam
+
+func (s typeParamsById) Len() int { return len(s) }
+func (s typeParamsById) Less(i, j int) bool { return s[i].id < s[j].id }
+func (s typeParamsById) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+// join unifies the given type parameters x and y.
+// If both type parameters already have a type associated with them
+// and they are not joined, join fails and returns false.
+func (u *unifier) join(x, y *TypeParam) bool {
+ if traceInference {
+ u.tracef("%s ⇄ %s", x, y)
+ }
+ switch hx, hy := u.handles[x], u.handles[y]; {
+ case hx == hy:
+ // Both type parameters already share the same handle. Nothing to do.
+ case *hx != nil && *hy != nil:
+ // Both type parameters have (possibly different) inferred types. Cannot join.
+ return false
+ case *hx != nil:
+ // Only type parameter x has an inferred type. Use handle of x.
+ u.setHandle(y, hx)
+ // This case is treated like the default case.
+ // case *hy != nil:
+ // // Only type parameter y has an inferred type. Use handle of y.
+ // u.setHandle(x, hy)
+ default:
+ // Neither type parameter has an inferred type. Use handle of y.
+ u.setHandle(x, hy)
+ }
+ return true
+}
+
+// asTypeParam returns x.(*TypeParam) if x is a type parameter recorded with u.
+// Otherwise, the result is nil.
+func (u *unifier) asTypeParam(x Type) *TypeParam {
+ if x, _ := x.(*TypeParam); x != nil {
+ if _, found := u.handles[x]; found {
+ return x
+ }
+ }
+ return nil
+}
+
+// setHandle sets the handle for type parameter x
+// (and all its joined type parameters) to h.
+func (u *unifier) setHandle(x *TypeParam, h *Type) {
+ hx := u.handles[x]
+ assert(hx != nil)
+ for y, hy := range u.handles {
+ if hy == hx {
+ u.handles[y] = h
+ }
+ }
+}
+
+// at returns the (possibly nil) type for type parameter x.
+func (u *unifier) at(x *TypeParam) Type {
+ return *u.handles[x]
+}
+
+// set sets the type t for type parameter x;
+// t must not be nil.
+func (u *unifier) set(x *TypeParam, t Type) {
+ assert(t != nil)
+ if traceInference {
+ u.tracef("%s ➞ %s", x, t)
+ }
+ *u.handles[x] = t
+}
+
+// unknowns returns the number of type parameters for which no type has been set yet.
+func (u *unifier) unknowns() int {
+ n := 0
+ for _, h := range u.handles {
+ if *h == nil {
+ n++
+ }
+ }
+ return n
+}
+
+// inferred returns the list of inferred types for the given type parameter list.
+// The result is never nil and has the same length as tparams; result types that
+// could not be inferred are nil. Corresponding type parameters and result types
+// have identical indices.
+func (u *unifier) inferred(tparams []*TypeParam) []Type {
+ list := make([]Type, len(tparams))
+ for i, x := range tparams {
+ list[i] = u.at(x)
+ }
+ return list
+}
+
+// asInterface returns the underlying type of x as an interface if
+// it is a non-type parameter interface. Otherwise it returns nil.
+func asInterface(x Type) (i *Interface) {
+ if _, ok := x.(*TypeParam); !ok {
+ i, _ = under(x).(*Interface)
+ }
+ return i
+}
+
+// nify implements the core unification algorithm which is an
+// adapted version of Checker.identical. For changes to that
+// code the corresponding changes should be made here.
+// Must not be called directly from outside the unifier.
+func (u *unifier) nify(x, y Type, mode unifyMode, p *ifacePair) (result bool) {
+ u.depth++
+ if traceInference {
+ u.tracef("%s ≡ %s\t// %s", x, y, mode)
+ }
+ defer func() {
+ if traceInference && !result {
+ u.tracef("%s ≢ %s", x, y)
+ }
+ u.depth--
+ }()
+
+ // nothing to do if x == y
+ if x == y {
+ return true
+ }
+
+ // Stop gap for cases where unification fails.
+ if u.depth > unificationDepthLimit {
+ if traceInference {
+ u.tracef("depth %d >= %d", u.depth, unificationDepthLimit)
+ }
+ if panicAtUnificationDepthLimit {
+ panic("unification reached recursion depth limit")
+ }
+ return false
+ }
+
+ // Unification is symmetric, so we can swap the operands.
+ // Ensure that if we have at least one
+ // - defined type, make sure one is in y
+ // - type parameter recorded with u, make sure one is in x
+ if _, ok := x.(*Named); ok || u.asTypeParam(y) != nil {
+ if traceInference {
+ u.tracef("%s ≡ %s\t// swap", y, x)
+ }
+ x, y = y, x
+ }
+
+ // Unification will fail if we match a defined type against a type literal.
+ // If we are matching types in an assignment, at the top-level, types with
+ // the same type structure are permitted as long as at least one of them
+ // is not a defined type. To accommodate for that possibility, we continue
+ // unification with the underlying type of a defined type if the other type
+ // is a type literal. This is controlled by the exact unification mode.
+ // We also continue if the other type is a basic type because basic types
+ // are valid underlying types and may appear as core types of type constraints.
+ // If we exclude them, inferred defined types for type parameters may not
+ // match against the core types of their constraints (even though they might
+ // correctly match against some of the types in the constraint's type set).
+ // Finally, if unification (incorrectly) succeeds by matching the underlying
+ // type of a defined type against a basic type (because we include basic types
+ // as type literals here), and if that leads to an incorrectly inferred type,
+ // we will fail at function instantiation or argument assignment time.
+ //
+ // If we have at least one defined type, there is one in y.
+ if ny, _ := y.(*Named); mode&exact == 0 && ny != nil && isTypeLit(x) && !(u.enableInterfaceInference && IsInterface(x)) {
+ if traceInference {
+ u.tracef("%s ≡ under %s", x, ny)
+ }
+ y = ny.under()
+ // Per the spec, a defined type cannot have an underlying type
+ // that is a type parameter.
+ assert(!isTypeParam(y))
+ // x and y may be identical now
+ if x == y {
+ return true
+ }
+ }
+
+ // Cases where at least one of x or y is a type parameter recorded with u.
+ // If we have at least one type parameter, there is one in x.
+ // If we have exactly one type parameter, because it is in x,
+ // isTypeLit(x) is false and y was not changed above. In other
+ // words, if y was a defined type, it is still a defined type
+ // (relevant for the logic below).
+ switch px, py := u.asTypeParam(x), u.asTypeParam(y); {
+ case px != nil && py != nil:
+ // both x and y are type parameters
+ if u.join(px, py) {
+ return true
+ }
+ // both x and y have an inferred type - they must match
+ return u.nify(u.at(px), u.at(py), mode, p)
+
+ case px != nil:
+ // x is a type parameter, y is not
+ if x := u.at(px); x != nil {
+ // x has an inferred type which must match y
+ if u.nify(x, y, mode, p) {
+ // We have a match, possibly through underlying types.
+ xi := asInterface(x)
+ yi := asInterface(y)
+ _, xn := x.(*Named)
+ _, yn := y.(*Named)
+ // If we have two interfaces, what to do depends on
+ // whether they are named and their method sets.
+ if xi != nil && yi != nil {
+ // Both types are interfaces.
+ // If both types are defined types, they must be identical
+ // because unification doesn't know which type has the "right" name.
+ if xn && yn {
+ return Identical(x, y)
+ }
+ // In all other cases, the method sets must match.
+ // The types unified so we know that corresponding methods
+ // match and we can simply compare the number of methods.
+ // TODO(gri) We may be able to relax this rule and select
+ // the more general interface. But if one of them is a defined
+ // type, it's not clear how to choose and whether we introduce
+ // an order dependency or not. Requiring the same method set
+ // is conservative.
+ if len(xi.typeSet().methods) != len(yi.typeSet().methods) {
+ return false
+ }
+ } else if xi != nil || yi != nil {
+ // One but not both of them are interfaces.
+ // In this case, either x or y could be viable matches for the corresponding
+ // type parameter, which means choosing either introduces an order dependence.
+ // Therefore, we must fail unification (go.dev/issue/60933).
+ return false
+ }
+ // If we have inexact unification and one of x or y is a defined type, select the
+ // defined type. This ensures that in a series of types, all matching against the
+ // same type parameter, we infer a defined type if there is one, independent of
+ // order. Type inference or assignment may fail, which is ok.
+ // Selecting a defined type, if any, ensures that we don't lose the type name;
+ // and since we have inexact unification, a value of equally named or matching
+ // undefined type remains assignable (go.dev/issue/43056).
+ //
+ // Similarly, if we have inexact unification and there are no defined types but
+ // channel types, select a directed channel, if any. This ensures that in a series
+ // of unnamed types, all matching against the same type parameter, we infer the
+ // directed channel if there is one, independent of order.
+ // Selecting a directional channel, if any, ensures that a value of another
+ // inexactly unifying channel type remains assignable (go.dev/issue/62157).
+ //
+ // If we have multiple defined channel types, they are either identical or we
+ // have assignment conflicts, so we can ignore directionality in this case.
+ //
+ // If we have defined and literal channel types, a defined type wins to avoid
+ // order dependencies.
+ if mode&exact == 0 {
+ switch {
+ case xn:
+ // x is a defined type: nothing to do.
+ case yn:
+ // x is not a defined type and y is a defined type: select y.
+ u.set(px, y)
+ default:
+ // Neither x nor y are defined types.
+ if yc, _ := under(y).(*Chan); yc != nil && yc.dir != SendRecv {
+ // y is a directed channel type: select y.
+ u.set(px, y)
+ }
+ }
+ }
+ return true
+ }
+ return false
+ }
+ // otherwise, infer type from y
+ u.set(px, y)
+ return true
+ }
+
+ // x != y if we get here
+ assert(x != y)
+
+ // Type elements (array, slice, etc. elements) use emode for unification.
+ // Element types must match exactly if the types are used in an assignment.
+ emode := mode
+ if mode&assign != 0 {
+ emode |= exact
+ }
+
+ // If u.EnableInterfaceInference is set and we don't require exact unification,
+ // if both types are interfaces, one interface must have a subset of the
+ // methods of the other and corresponding method signatures must unify.
+ // If only one type is an interface, all its methods must be present in the
+ // other type and corresponding method signatures must unify.
+ if u.enableInterfaceInference && mode&exact == 0 {
+ // One or both interfaces may be defined types.
+ // Look under the name, but not under type parameters (go.dev/issue/60564).
+ xi := asInterface(x)
+ yi := asInterface(y)
+ // If we have two interfaces, check the type terms for equivalence,
+ // and unify common methods if possible.
+ if xi != nil && yi != nil {
+ xset := xi.typeSet()
+ yset := yi.typeSet()
+ if xset.comparable != yset.comparable {
+ return false
+ }
+ // For now we require terms to be equal.
+ // We should be able to relax this as well, eventually.
+ if !xset.terms.equal(yset.terms) {
+ return false
+ }
+ // Interface types are the only types where cycles can occur
+ // that are not "terminated" via named types; and such cycles
+ // can only be created via method parameter types that are
+ // anonymous interfaces (directly or indirectly) embedding
+ // the current interface. Example:
+ //
+ // type T interface {
+ // m() interface{T}
+ // }
+ //
+ // If two such (differently named) interfaces are compared,
+ // endless recursion occurs if the cycle is not detected.
+ //
+ // If x and y were compared before, they must be equal
+ // (if they were not, the recursion would have stopped);
+ // search the ifacePair stack for the same pair.
+ //
+ // This is a quadratic algorithm, but in practice these stacks
+ // are extremely short (bounded by the nesting depth of interface
+ // type declarations that recur via parameter types, an extremely
+ // rare occurrence). An alternative implementation might use a
+ // "visited" map, but that is probably less efficient overall.
+ q := &ifacePair{xi, yi, p}
+ for p != nil {
+ if p.identical(q) {
+ return true // same pair was compared before
+ }
+ p = p.prev
+ }
+ // The method set of x must be a subset of the method set
+ // of y or vice versa, and the common methods must unify.
+ xmethods := xset.methods
+ ymethods := yset.methods
+ // The smaller method set must be the subset, if it exists.
+ if len(xmethods) > len(ymethods) {
+ xmethods, ymethods = ymethods, xmethods
+ }
+ // len(xmethods) <= len(ymethods)
+ // Collect the ymethods in a map for quick lookup.
+ ymap := make(map[string]*Func, len(ymethods))
+ for _, ym := range ymethods {
+ ymap[ym.Id()] = ym
+ }
+ // All xmethods must exist in ymethods and corresponding signatures must unify.
+ for _, xm := range xmethods {
+ if ym := ymap[xm.Id()]; ym == nil || !u.nify(xm.typ, ym.typ, exact, p) {
+ return false
+ }
+ }
+ return true
+ }
+
+ // We don't have two interfaces. If we have one, make sure it's in xi.
+ if yi != nil {
+ xi = yi
+ y = x
+ }
+
+ // If we have one interface, at a minimum each of the interface methods
+ // must be implemented and thus unify with a corresponding method from
+ // the non-interface type, otherwise unification fails.
+ if xi != nil {
+ // All xi methods must exist in y and corresponding signatures must unify.
+ xmethods := xi.typeSet().methods
+ for _, xm := range xmethods {
+ obj, _, _ := LookupFieldOrMethod(y, false, xm.pkg, xm.name)
+ if ym, _ := obj.(*Func); ym == nil || !u.nify(xm.typ, ym.typ, exact, p) {
+ return false
+ }
+ }
+ return true
+ }
+ }
+
+ // Unless we have exact unification, neither x nor y are interfaces now.
+ // Except for unbound type parameters (see below), x and y must be structurally
+ // equivalent to unify.
+
+ // If we get here and x or y is a type parameter, they are unbound
+ // (not recorded with the unifier).
+ // Ensure that if we have at least one type parameter, it is in x
+ // (the earlier swap checks for _recorded_ type parameters only).
+ // This ensures that the switch switches on the type parameter.
+ //
+ // TODO(gri) Factor out type parameter handling from the switch.
+ if isTypeParam(y) {
+ if traceInference {
+ u.tracef("%s ≡ %s\t// swap", y, x)
+ }
+ x, y = y, x
+ }
+
+ switch x := x.(type) {
+ case *Basic:
+ // Basic types are singletons except for the rune and byte
+ // aliases, thus we cannot solely rely on the x == y check
+ // above. See also comment in TypeName.IsAlias.
+ if y, ok := y.(*Basic); ok {
+ return x.kind == y.kind
+ }
+
+ case *Array:
+ // Two array types unify if they have the same array length
+ // and their element types unify.
+ if y, ok := y.(*Array); ok {
+ // If one or both array lengths are unknown (< 0) due to some error,
+ // assume they are the same to avoid spurious follow-on errors.
+ return (x.len < 0 || y.len < 0 || x.len == y.len) && u.nify(x.elem, y.elem, emode, p)
+ }
+
+ case *Slice:
+ // Two slice types unify if their element types unify.
+ if y, ok := y.(*Slice); ok {
+ return u.nify(x.elem, y.elem, emode, p)
+ }
+
+ case *Struct:
+ // Two struct types unify if they have the same sequence of fields,
+ // and if corresponding fields have the same names, their (field) types unify,
+ // and they have identical tags. Two embedded fields are considered to have the same
+ // name. Lower-case field names from different packages are always different.
+ if y, ok := y.(*Struct); ok {
+ if x.NumFields() == y.NumFields() {
+ for i, f := range x.fields {
+ g := y.fields[i]
+ if f.embedded != g.embedded ||
+ x.Tag(i) != y.Tag(i) ||
+ !f.sameId(g.pkg, g.name) ||
+ !u.nify(f.typ, g.typ, emode, p) {
+ return false
+ }
+ }
+ return true
+ }
+ }
+
+ case *Pointer:
+ // Two pointer types unify if their base types unify.
+ if y, ok := y.(*Pointer); ok {
+ return u.nify(x.base, y.base, emode, p)
+ }
+
+ case *Tuple:
+ // Two tuples types unify if they have the same number of elements
+ // and the types of corresponding elements unify.
+ if y, ok := y.(*Tuple); ok {
+ if x.Len() == y.Len() {
+ if x != nil {
+ for i, v := range x.vars {
+ w := y.vars[i]
+ if !u.nify(v.typ, w.typ, mode, p) {
+ return false
+ }
+ }
+ }
+ return true
+ }
+ }
+
+ case *Signature:
+ // Two function types unify if they have the same number of parameters
+ // and result values, corresponding parameter and result types unify,
+ // and either both functions are variadic or neither is.
+ // Parameter and result names are not required to match.
+ // TODO(gri) handle type parameters or document why we can ignore them.
+ if y, ok := y.(*Signature); ok {
+ return x.variadic == y.variadic &&
+ u.nify(x.params, y.params, emode, p) &&
+ u.nify(x.results, y.results, emode, p)
+ }
+
+ case *Interface:
+ assert(!u.enableInterfaceInference || mode&exact != 0) // handled before this switch
+
+ // Two interface types unify if they have the same set of methods with
+ // the same names, and corresponding function types unify.
+ // Lower-case method names from different packages are always different.
+ // The order of the methods is irrelevant.
+ if y, ok := y.(*Interface); ok {
+ xset := x.typeSet()
+ yset := y.typeSet()
+ if xset.comparable != yset.comparable {
+ return false
+ }
+ if !xset.terms.equal(yset.terms) {
+ return false
+ }
+ a := xset.methods
+ b := yset.methods
+ if len(a) == len(b) {
+ // Interface types are the only types where cycles can occur
+ // that are not "terminated" via named types; and such cycles
+ // can only be created via method parameter types that are
+ // anonymous interfaces (directly or indirectly) embedding
+ // the current interface. Example:
+ //
+ // type T interface {
+ // m() interface{T}
+ // }
+ //
+ // If two such (differently named) interfaces are compared,
+ // endless recursion occurs if the cycle is not detected.
+ //
+ // If x and y were compared before, they must be equal
+ // (if they were not, the recursion would have stopped);
+ // search the ifacePair stack for the same pair.
+ //
+ // This is a quadratic algorithm, but in practice these stacks
+ // are extremely short (bounded by the nesting depth of interface
+ // type declarations that recur via parameter types, an extremely
+ // rare occurrence). An alternative implementation might use a
+ // "visited" map, but that is probably less efficient overall.
+ q := &ifacePair{x, y, p}
+ for p != nil {
+ if p.identical(q) {
+ return true // same pair was compared before
+ }
+ p = p.prev
+ }
+ if debug {
+ assertSortedMethods(a)
+ assertSortedMethods(b)
+ }
+ for i, f := range a {
+ g := b[i]
+ if f.Id() != g.Id() || !u.nify(f.typ, g.typ, exact, q) {
+ return false
+ }
+ }
+ return true
+ }
+ }
+
+ case *Map:
+ // Two map types unify if their key and value types unify.
+ if y, ok := y.(*Map); ok {
+ return u.nify(x.key, y.key, emode, p) && u.nify(x.elem, y.elem, emode, p)
+ }
+
+ case *Chan:
+ // Two channel types unify if their value types unify
+ // and if they have the same direction.
+ // The channel direction is ignored for inexact unification.
+ if y, ok := y.(*Chan); ok {
+ return (mode&exact == 0 || x.dir == y.dir) && u.nify(x.elem, y.elem, emode, p)
+ }
+
+ case *Named:
+ // Two named types unify if their type names originate in the same type declaration.
+ // If they are instantiated, their type argument lists must unify.
+ if y, ok := y.(*Named); ok {
+ // Check type arguments before origins so they unify
+ // even if the origins don't match; for better error
+ // messages (see go.dev/issue/53692).
+ xargs := x.TypeArgs().list()
+ yargs := y.TypeArgs().list()
+ if len(xargs) != len(yargs) {
+ return false
+ }
+ for i, xarg := range xargs {
+ if !u.nify(xarg, yargs[i], mode, p) {
+ return false
+ }
+ }
+ return indenticalOrigin(x, y)
+ }
+
+ case *TypeParam:
+ // x must be an unbound type parameter (see comment above).
+ if debug {
+ assert(u.asTypeParam(x) == nil)
+ }
+ // By definition, a valid type argument must be in the type set of
+ // the respective type constraint. Therefore, the type argument's
+ // underlying type must be in the set of underlying types of that
+ // constraint. If there is a single such underlying type, it's the
+ // constraint's core type. It must match the type argument's under-
+ // lying type, irrespective of whether the actual type argument,
+ // which may be a defined type, is actually in the type set (that
+ // will be determined at instantiation time).
+ // Thus, if we have the core type of an unbound type parameter,
+ // we know the structure of the possible types satisfying such
+ // parameters. Use that core type for further unification
+ // (see go.dev/issue/50755 for a test case).
+ if enableCoreTypeUnification {
+ // Because the core type is always an underlying type,
+ // unification will take care of matching against a
+ // defined or literal type automatically.
+ // If y is also an unbound type parameter, we will end
+ // up here again with x and y swapped, so we don't
+ // need to take care of that case separately.
+ if cx := coreType(x); cx != nil {
+ if traceInference {
+ u.tracef("core %s ≡ %s", x, y)
+ }
+ // If y is a defined type, it may not match against cx which
+ // is an underlying type (incl. int, string, etc.). Use assign
+ // mode here so that the unifier automatically takes under(y)
+ // if necessary.
+ return u.nify(cx, y, assign, p)
+ }
+ }
+ // x != y and there's nothing to do
+
+ case nil:
+ // avoid a crash in case of nil type
+
+ default:
+ panic(sprintf(nil, nil, true, "u.nify(%s, %s, %d)", x, y, mode))
+ }
+
+ return false
+}
diff --git a/contrib/go/_std_1.21/src/go/types/union.go b/contrib/go/_std_1.21/src/go/types/union.go
new file mode 100644
index 0000000000..085f507ad3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/union.go
@@ -0,0 +1,200 @@
+// 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 types
+
+import (
+ "go/ast"
+ "go/token"
+ . "internal/types/errors"
+)
+
+// ----------------------------------------------------------------------------
+// API
+
+// A Union represents a union of terms embedded in an interface.
+type Union struct {
+ terms []*Term // list of syntactical terms (not a canonicalized termlist)
+}
+
+// NewUnion returns a new Union type with the given terms.
+// It is an error to create an empty union; they are syntactically not possible.
+func NewUnion(terms []*Term) *Union {
+ if len(terms) == 0 {
+ panic("empty union")
+ }
+ return &Union{terms}
+}
+
+func (u *Union) Len() int { return len(u.terms) }
+func (u *Union) Term(i int) *Term { return u.terms[i] }
+
+func (u *Union) Underlying() Type { return u }
+func (u *Union) String() string { return TypeString(u, nil) }
+
+// A Term represents a term in a Union.
+type Term term
+
+// NewTerm returns a new union term.
+func NewTerm(tilde bool, typ Type) *Term { return &Term{tilde, typ} }
+
+func (t *Term) Tilde() bool { return t.tilde }
+func (t *Term) Type() Type { return t.typ }
+func (t *Term) String() string { return (*term)(t).String() }
+
+// ----------------------------------------------------------------------------
+// Implementation
+
+// Avoid excessive type-checking times due to quadratic termlist operations.
+const maxTermCount = 100
+
+// parseUnion parses uexpr as a union of expressions.
+// The result is a Union type, or Typ[Invalid] for some errors.
+func parseUnion(check *Checker, uexpr ast.Expr) Type {
+ blist, tlist := flattenUnion(nil, uexpr)
+ assert(len(blist) == len(tlist)-1)
+
+ var terms []*Term
+
+ var u Type
+ for i, x := range tlist {
+ term := parseTilde(check, x)
+ if len(tlist) == 1 && !term.tilde {
+ // Single type. Ok to return early because all relevant
+ // checks have been performed in parseTilde (no need to
+ // run through term validity check below).
+ return term.typ // typ already recorded through check.typ in parseTilde
+ }
+ if len(terms) >= maxTermCount {
+ if u != Typ[Invalid] {
+ check.errorf(x, InvalidUnion, "cannot handle more than %d union terms (implementation limitation)", maxTermCount)
+ u = Typ[Invalid]
+ }
+ } else {
+ terms = append(terms, term)
+ u = &Union{terms}
+ }
+
+ if i > 0 {
+ check.recordTypeAndValue(blist[i-1], typexpr, u, nil)
+ }
+ }
+
+ if u == Typ[Invalid] {
+ return u
+ }
+
+ // Check validity of terms.
+ // Do this check later because it requires types to be set up.
+ // Note: This is a quadratic algorithm, but unions tend to be short.
+ check.later(func() {
+ for i, t := range terms {
+ if t.typ == Typ[Invalid] {
+ continue
+ }
+
+ u := under(t.typ)
+ f, _ := u.(*Interface)
+ if t.tilde {
+ if f != nil {
+ check.errorf(tlist[i], InvalidUnion, "invalid use of ~ (%s is an interface)", t.typ)
+ continue // don't report another error for t
+ }
+
+ if !Identical(u, t.typ) {
+ check.errorf(tlist[i], InvalidUnion, "invalid use of ~ (underlying type of %s is %s)", t.typ, u)
+ continue
+ }
+ }
+
+ // Stand-alone embedded interfaces are ok and are handled by the single-type case
+ // in the beginning. Embedded interfaces with tilde are excluded above. If we reach
+ // here, we must have at least two terms in the syntactic term list (but not necessarily
+ // in the term list of the union's type set).
+ if f != nil {
+ tset := f.typeSet()
+ switch {
+ case tset.NumMethods() != 0:
+ check.errorf(tlist[i], InvalidUnion, "cannot use %s in union (%s contains methods)", t, t)
+ case t.typ == universeComparable.Type():
+ check.error(tlist[i], InvalidUnion, "cannot use comparable in union")
+ case tset.comparable:
+ check.errorf(tlist[i], InvalidUnion, "cannot use %s in union (%s embeds comparable)", t, t)
+ }
+ continue // terms with interface types are not subject to the no-overlap rule
+ }
+
+ // Report overlapping (non-disjoint) terms such as
+ // a|a, a|~a, ~a|~a, and ~a|A (where under(A) == a).
+ if j := overlappingTerm(terms[:i], t); j >= 0 {
+ check.softErrorf(tlist[i], InvalidUnion, "overlapping terms %s and %s", t, terms[j])
+ }
+ }
+ }).describef(uexpr, "check term validity %s", uexpr)
+
+ return u
+}
+
+func parseTilde(check *Checker, tx ast.Expr) *Term {
+ x := tx
+ var tilde bool
+ if op, _ := x.(*ast.UnaryExpr); op != nil && op.Op == token.TILDE {
+ x = op.X
+ tilde = true
+ }
+ typ := check.typ(x)
+ // Embedding stand-alone type parameters is not permitted (go.dev/issue/47127).
+ // We don't need this restriction anymore if we make the underlying type of a type
+ // parameter its constraint interface: if we embed a lone type parameter, we will
+ // simply use its underlying type (like we do for other named, embedded interfaces),
+ // and since the underlying type is an interface the embedding is well defined.
+ if isTypeParam(typ) {
+ if tilde {
+ check.errorf(x, MisplacedTypeParam, "type in term %s cannot be a type parameter", tx)
+ } else {
+ check.error(x, MisplacedTypeParam, "term cannot be a type parameter")
+ }
+ typ = Typ[Invalid]
+ }
+ term := NewTerm(tilde, typ)
+ if tilde {
+ check.recordTypeAndValue(tx, typexpr, &Union{[]*Term{term}}, nil)
+ }
+ return term
+}
+
+// overlappingTerm reports the index of the term x in terms which is
+// overlapping (not disjoint) from y. The result is < 0 if there is no
+// such term. The type of term y must not be an interface, and terms
+// with an interface type are ignored in the terms list.
+func overlappingTerm(terms []*Term, y *Term) int {
+ assert(!IsInterface(y.typ))
+ for i, x := range terms {
+ if IsInterface(x.typ) {
+ continue
+ }
+ // disjoint requires non-nil, non-top arguments,
+ // and non-interface types as term types.
+ if debug {
+ if x == nil || x.typ == nil || y == nil || y.typ == nil {
+ panic("empty or top union term")
+ }
+ }
+ if !(*term)(x).disjoint((*term)(y)) {
+ return i
+ }
+ }
+ return -1
+}
+
+// flattenUnion walks a union type expression of the form A | B | C | ...,
+// extracting both the binary exprs (blist) and leaf types (tlist).
+func flattenUnion(list []ast.Expr, x ast.Expr) (blist, tlist []ast.Expr) {
+ if o, _ := x.(*ast.BinaryExpr); o != nil && o.Op == token.OR {
+ blist, tlist = flattenUnion(list, o.X)
+ blist = append(blist, o)
+ x = o.Y
+ }
+ return blist, append(tlist, x)
+}
diff --git a/contrib/go/_std_1.21/src/go/types/universe.go b/contrib/go/_std_1.21/src/go/types/universe.go
new file mode 100644
index 0000000000..cc4d42d98c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/universe.go
@@ -0,0 +1,290 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2011 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.
+
+// This file sets up the universe scope and the unsafe package.
+
+package types
+
+import (
+ "go/constant"
+ "strings"
+)
+
+// The Universe scope contains all predeclared objects of Go.
+// It is the outermost scope of any chain of nested scopes.
+var Universe *Scope
+
+// The Unsafe package is the package returned by an importer
+// for the import path "unsafe".
+var Unsafe *Package
+
+var (
+ universeIota Object
+ universeByte Type // uint8 alias, but has name "byte"
+ universeRune Type // int32 alias, but has name "rune"
+ universeAny Object
+ universeError Type
+ universeComparable Object
+)
+
+// Typ contains the predeclared *Basic types indexed by their
+// corresponding BasicKind.
+//
+// The *Basic type for Typ[Byte] will have the name "uint8".
+// Use Universe.Lookup("byte").Type() to obtain the specific
+// alias basic type named "byte" (and analogous for "rune").
+var Typ = []*Basic{
+ Invalid: {Invalid, 0, "invalid type"},
+
+ Bool: {Bool, IsBoolean, "bool"},
+ Int: {Int, IsInteger, "int"},
+ Int8: {Int8, IsInteger, "int8"},
+ Int16: {Int16, IsInteger, "int16"},
+ Int32: {Int32, IsInteger, "int32"},
+ Int64: {Int64, IsInteger, "int64"},
+ Uint: {Uint, IsInteger | IsUnsigned, "uint"},
+ Uint8: {Uint8, IsInteger | IsUnsigned, "uint8"},
+ Uint16: {Uint16, IsInteger | IsUnsigned, "uint16"},
+ Uint32: {Uint32, IsInteger | IsUnsigned, "uint32"},
+ Uint64: {Uint64, IsInteger | IsUnsigned, "uint64"},
+ Uintptr: {Uintptr, IsInteger | IsUnsigned, "uintptr"},
+ Float32: {Float32, IsFloat, "float32"},
+ Float64: {Float64, IsFloat, "float64"},
+ Complex64: {Complex64, IsComplex, "complex64"},
+ Complex128: {Complex128, IsComplex, "complex128"},
+ String: {String, IsString, "string"},
+ UnsafePointer: {UnsafePointer, 0, "Pointer"},
+
+ UntypedBool: {UntypedBool, IsBoolean | IsUntyped, "untyped bool"},
+ UntypedInt: {UntypedInt, IsInteger | IsUntyped, "untyped int"},
+ UntypedRune: {UntypedRune, IsInteger | IsUntyped, "untyped rune"},
+ UntypedFloat: {UntypedFloat, IsFloat | IsUntyped, "untyped float"},
+ UntypedComplex: {UntypedComplex, IsComplex | IsUntyped, "untyped complex"},
+ UntypedString: {UntypedString, IsString | IsUntyped, "untyped string"},
+ UntypedNil: {UntypedNil, IsUntyped, "untyped nil"},
+}
+
+var aliases = [...]*Basic{
+ {Byte, IsInteger | IsUnsigned, "byte"},
+ {Rune, IsInteger, "rune"},
+}
+
+func defPredeclaredTypes() {
+ for _, t := range Typ {
+ def(NewTypeName(nopos, nil, t.name, t))
+ }
+ for _, t := range aliases {
+ def(NewTypeName(nopos, nil, t.name, t))
+ }
+
+ // type any = interface{}
+ // Note: don't use &emptyInterface for the type of any. Using a unique
+ // pointer allows us to detect any and format it as "any" rather than
+ // interface{}, which clarifies user-facing error messages significantly.
+ def(NewTypeName(nopos, nil, "any", &Interface{complete: true, tset: &topTypeSet}))
+
+ // type error interface{ Error() string }
+ {
+ obj := NewTypeName(nopos, nil, "error", nil)
+ obj.setColor(black)
+ typ := NewNamed(obj, nil, nil)
+
+ // error.Error() string
+ recv := NewVar(nopos, nil, "", typ)
+ res := NewVar(nopos, nil, "", Typ[String])
+ sig := NewSignatureType(recv, nil, nil, nil, NewTuple(res), false)
+ err := NewFunc(nopos, nil, "Error", sig)
+
+ // interface{ Error() string }
+ ityp := &Interface{methods: []*Func{err}, complete: true}
+ computeInterfaceTypeSet(nil, nopos, ityp) // prevent races due to lazy computation of tset
+
+ typ.SetUnderlying(ityp)
+ def(obj)
+ }
+
+ // type comparable interface{} // marked as comparable
+ {
+ obj := NewTypeName(nopos, nil, "comparable", nil)
+ obj.setColor(black)
+ typ := NewNamed(obj, nil, nil)
+
+ // interface{} // marked as comparable
+ ityp := &Interface{complete: true, tset: &_TypeSet{nil, allTermlist, true}}
+
+ typ.SetUnderlying(ityp)
+ def(obj)
+ }
+}
+
+var predeclaredConsts = [...]struct {
+ name string
+ kind BasicKind
+ val constant.Value
+}{
+ {"true", UntypedBool, constant.MakeBool(true)},
+ {"false", UntypedBool, constant.MakeBool(false)},
+ {"iota", UntypedInt, constant.MakeInt64(0)},
+}
+
+func defPredeclaredConsts() {
+ for _, c := range predeclaredConsts {
+ def(NewConst(nopos, nil, c.name, Typ[c.kind], c.val))
+ }
+}
+
+func defPredeclaredNil() {
+ def(&Nil{object{name: "nil", typ: Typ[UntypedNil], color_: black}})
+}
+
+// A builtinId is the id of a builtin function.
+type builtinId int
+
+const (
+ // universe scope
+ _Append builtinId = iota
+ _Cap
+ _Clear
+ _Close
+ _Complex
+ _Copy
+ _Delete
+ _Imag
+ _Len
+ _Make
+ _Max
+ _Min
+ _New
+ _Panic
+ _Print
+ _Println
+ _Real
+ _Recover
+
+ // package unsafe
+ _Add
+ _Alignof
+ _Offsetof
+ _Sizeof
+ _Slice
+ _SliceData
+ _String
+ _StringData
+
+ // testing support
+ _Assert
+ _Trace
+)
+
+var predeclaredFuncs = [...]struct {
+ name string
+ nargs int
+ variadic bool
+ kind exprKind
+}{
+ _Append: {"append", 1, true, expression},
+ _Cap: {"cap", 1, false, expression},
+ _Clear: {"clear", 1, false, statement},
+ _Close: {"close", 1, false, statement},
+ _Complex: {"complex", 2, false, expression},
+ _Copy: {"copy", 2, false, statement},
+ _Delete: {"delete", 2, false, statement},
+ _Imag: {"imag", 1, false, expression},
+ _Len: {"len", 1, false, expression},
+ _Make: {"make", 1, true, expression},
+ // To disable max/min, remove the next two lines.
+ _Max: {"max", 1, true, expression},
+ _Min: {"min", 1, true, expression},
+ _New: {"new", 1, false, expression},
+ _Panic: {"panic", 1, false, statement},
+ _Print: {"print", 0, true, statement},
+ _Println: {"println", 0, true, statement},
+ _Real: {"real", 1, false, expression},
+ _Recover: {"recover", 0, false, statement},
+
+ _Add: {"Add", 2, false, expression},
+ _Alignof: {"Alignof", 1, false, expression},
+ _Offsetof: {"Offsetof", 1, false, expression},
+ _Sizeof: {"Sizeof", 1, false, expression},
+ _Slice: {"Slice", 2, false, expression},
+ _SliceData: {"SliceData", 1, false, expression},
+ _String: {"String", 2, false, expression},
+ _StringData: {"StringData", 1, false, expression},
+
+ _Assert: {"assert", 1, false, statement},
+ _Trace: {"trace", 0, true, statement},
+}
+
+func defPredeclaredFuncs() {
+ for i := range predeclaredFuncs {
+ id := builtinId(i)
+ if id == _Assert || id == _Trace {
+ continue // only define these in testing environment
+ }
+ def(newBuiltin(id))
+ }
+}
+
+// DefPredeclaredTestFuncs defines the assert and trace built-ins.
+// These built-ins are intended for debugging and testing of this
+// package only.
+func DefPredeclaredTestFuncs() {
+ if Universe.Lookup("assert") != nil {
+ return // already defined
+ }
+ def(newBuiltin(_Assert))
+ def(newBuiltin(_Trace))
+}
+
+func init() {
+ Universe = NewScope(nil, nopos, nopos, "universe")
+ Unsafe = NewPackage("unsafe", "unsafe")
+ Unsafe.complete = true
+
+ defPredeclaredTypes()
+ defPredeclaredConsts()
+ defPredeclaredNil()
+ defPredeclaredFuncs()
+
+ universeIota = Universe.Lookup("iota")
+ universeByte = Universe.Lookup("byte").Type()
+ universeRune = Universe.Lookup("rune").Type()
+ universeAny = Universe.Lookup("any")
+ universeError = Universe.Lookup("error").Type()
+ universeComparable = Universe.Lookup("comparable")
+}
+
+// Objects with names containing blanks are internal and not entered into
+// a scope. Objects with exported names are inserted in the unsafe package
+// scope; other objects are inserted in the universe scope.
+func def(obj Object) {
+ assert(obj.color() == black)
+ name := obj.Name()
+ if strings.Contains(name, " ") {
+ return // nothing to do
+ }
+ // fix Obj link for named types
+ if typ, _ := obj.Type().(*Named); typ != nil {
+ typ.obj = obj.(*TypeName)
+ }
+ // exported identifiers go into package unsafe
+ scope := Universe
+ if obj.Exported() {
+ scope = Unsafe.scope
+ // set Pkg field
+ switch obj := obj.(type) {
+ case *TypeName:
+ obj.pkg = Unsafe
+ case *Builtin:
+ obj.pkg = Unsafe
+ default:
+ unreachable()
+ }
+ }
+ if scope.Insert(obj) != nil {
+ panic("double declaration of predeclared identifier")
+ }
+}
diff --git a/contrib/go/_std_1.21/src/go/types/util.go b/contrib/go/_std_1.21/src/go/types/util.go
new file mode 100644
index 0000000000..87e1240010
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/util.go
@@ -0,0 +1,22 @@
+// Copyright 2023 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.
+
+// This file contains various functionality that is
+// different between go/types and types2. Factoring
+// out this code allows more of the rest of the code
+// to be shared.
+
+package types
+
+import "go/token"
+
+// cmpPos compares the positions p and q and returns a result r as follows:
+//
+// r < 0: p is before q
+// r == 0: p and q are the same position (but may not be identical)
+// r > 0: p is after q
+//
+// If p and q are in different files, p is before q if the filename
+// of p sorts lexicographically before the filename of q.
+func cmpPos(p, q token.Pos) int { return int(p - q) }
diff --git a/contrib/go/_std_1.21/src/go/types/validtype.go b/contrib/go/_std_1.21/src/go/types/validtype.go
new file mode 100644
index 0000000000..d915fef825
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/validtype.go
@@ -0,0 +1,258 @@
+// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.
+
+// Copyright 2022 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 types
+
+// validType verifies that the given type does not "expand" indefinitely
+// producing a cycle in the type graph.
+// (Cycles involving alias types, as in "type A = [10]A" are detected
+// earlier, via the objDecl cycle detection mechanism.)
+func (check *Checker) validType(typ *Named) {
+ check.validType0(typ, nil, nil)
+}
+
+// validType0 checks if the given type is valid. If typ is a type parameter
+// its value is looked up in the type argument list of the instantiated
+// (enclosing) type, if it exists. Otherwise the type parameter must be from
+// an enclosing function and can be ignored.
+// The nest list describes the stack (the "nest in memory") of types which
+// contain (or embed in the case of interfaces) other types. For instance, a
+// struct named S which contains a field of named type F contains (the memory
+// of) F in S, leading to the nest S->F. If a type appears in its own nest
+// (say S->F->S) we have an invalid recursive type. The path list is the full
+// path of named types in a cycle, it is only needed for error reporting.
+func (check *Checker) validType0(typ Type, nest, path []*Named) bool {
+ switch t := typ.(type) {
+ case nil:
+ // We should never see a nil type but be conservative and panic
+ // only in debug mode.
+ if debug {
+ panic("validType0(nil)")
+ }
+
+ case *Array:
+ return check.validType0(t.elem, nest, path)
+
+ case *Struct:
+ for _, f := range t.fields {
+ if !check.validType0(f.typ, nest, path) {
+ return false
+ }
+ }
+
+ case *Union:
+ for _, t := range t.terms {
+ if !check.validType0(t.typ, nest, path) {
+ return false
+ }
+ }
+
+ case *Interface:
+ for _, etyp := range t.embeddeds {
+ if !check.validType0(etyp, nest, path) {
+ return false
+ }
+ }
+
+ case *Named:
+ // Exit early if we already know t is valid.
+ // This is purely an optimization but it prevents excessive computation
+ // times in pathological cases such as testdata/fixedbugs/issue6977.go.
+ // (Note: The valids map could also be allocated locally, once for each
+ // validType call.)
+ if check.valids.lookup(t) != nil {
+ break
+ }
+
+ // Don't report a 2nd error if we already know the type is invalid
+ // (e.g., if a cycle was detected earlier, via under).
+ // Note: ensure that t.orig is fully resolved by calling Underlying().
+ if t.Underlying() == Typ[Invalid] {
+ return false
+ }
+
+ // If the current type t is also found in nest, (the memory of) t is
+ // embedded in itself, indicating an invalid recursive type.
+ for _, e := range nest {
+ if Identical(e, t) {
+ // We have a cycle. If t != t.Origin() then t is an instance of
+ // the generic type t.Origin(). Because t is in the nest, t must
+ // occur within the definition (RHS) of the generic type t.Origin(),
+ // directly or indirectly, after expansion of the RHS.
+ // Therefore t.Origin() must be invalid, no matter how it is
+ // instantiated since the instantiation t of t.Origin() happens
+ // inside t.Origin()'s RHS and thus is always the same and always
+ // present.
+ // Therefore we can mark the underlying of both t and t.Origin()
+ // as invalid. If t is not an instance of a generic type, t and
+ // t.Origin() are the same.
+ // Furthermore, because we check all types in a package for validity
+ // before type checking is complete, any exported type that is invalid
+ // will have an invalid underlying type and we can't reach here with
+ // such a type (invalid types are excluded above).
+ // Thus, if we reach here with a type t, both t and t.Origin() (if
+ // different in the first place) must be from the current package;
+ // they cannot have been imported.
+ // Therefore it is safe to change their underlying types; there is
+ // no chance for a race condition (the types of the current package
+ // are not yet available to other goroutines).
+ assert(t.obj.pkg == check.pkg)
+ assert(t.Origin().obj.pkg == check.pkg)
+ t.underlying = Typ[Invalid]
+ t.Origin().underlying = Typ[Invalid]
+
+ // Find the starting point of the cycle and report it.
+ // Because each type in nest must also appear in path (see invariant below),
+ // type t must be in path since it was found in nest. But not every type in path
+ // is in nest. Specifically t may appear in path with an earlier index than the
+ // index of t in nest. Search again.
+ for start, p := range path {
+ if Identical(p, t) {
+ check.cycleError(makeObjList(path[start:]))
+ return false
+ }
+ }
+ panic("cycle start not found")
+ }
+ }
+
+ // No cycle was found. Check the RHS of t.
+ // Every type added to nest is also added to path; thus every type that is in nest
+ // must also be in path (invariant). But not every type in path is in nest, since
+ // nest may be pruned (see below, *TypeParam case).
+ if !check.validType0(t.Origin().fromRHS, append(nest, t), append(path, t)) {
+ return false
+ }
+
+ check.valids.add(t) // t is valid
+
+ case *TypeParam:
+ // A type parameter stands for the type (argument) it was instantiated with.
+ // Check the corresponding type argument for validity if we are in an
+ // instantiated type.
+ if len(nest) > 0 {
+ inst := nest[len(nest)-1] // the type instance
+ // Find the corresponding type argument for the type parameter
+ // and proceed with checking that type argument.
+ for i, tparam := range inst.TypeParams().list() {
+ // The type parameter and type argument lists should
+ // match in length but be careful in case of errors.
+ if t == tparam && i < inst.TypeArgs().Len() {
+ targ := inst.TypeArgs().At(i)
+ // The type argument must be valid in the enclosing
+ // type (where inst was instantiated), hence we must
+ // check targ's validity in the type nest excluding
+ // the current (instantiated) type (see the example
+ // at the end of this file).
+ // For error reporting we keep the full path.
+ return check.validType0(targ, nest[:len(nest)-1], path)
+ }
+ }
+ }
+ }
+
+ return true
+}
+
+// makeObjList returns the list of type name objects for the given
+// list of named types.
+func makeObjList(tlist []*Named) []Object {
+ olist := make([]Object, len(tlist))
+ for i, t := range tlist {
+ olist[i] = t.obj
+ }
+ return olist
+}
+
+// Here is an example illustrating why we need to exclude the
+// instantiated type from nest when evaluating the validity of
+// a type parameter. Given the declarations
+//
+// var _ A[A[string]]
+//
+// type A[P any] struct { _ B[P] }
+// type B[P any] struct { _ P }
+//
+// we want to determine if the type A[A[string]] is valid.
+// We start evaluating A[A[string]] outside any type nest:
+//
+// A[A[string]]
+// nest =
+// path =
+//
+// The RHS of A is now evaluated in the A[A[string]] nest:
+//
+// struct{_ B[P₁]}
+// nest = A[A[string]]
+// path = A[A[string]]
+//
+// The struct has a single field of type B[P₁] with which
+// we continue:
+//
+// B[P₁]
+// nest = A[A[string]]
+// path = A[A[string]]
+//
+// struct{_ P₂}
+// nest = A[A[string]]->B[P]
+// path = A[A[string]]->B[P]
+//
+// Eventually we reach the type parameter P of type B (P₂):
+//
+// P₂
+// nest = A[A[string]]->B[P]
+// path = A[A[string]]->B[P]
+//
+// The type argument for P of B is the type parameter P of A (P₁).
+// It must be evaluated in the type nest that existed when B was
+// instantiated:
+//
+// P₁
+// nest = A[A[string]] <== type nest at B's instantiation time
+// path = A[A[string]]->B[P]
+//
+// If we'd use the current nest it would correspond to the path
+// which will be wrong as we will see shortly. P's type argument
+// is A[string], which again must be evaluated in the type nest
+// that existed when A was instantiated with A[string]. That type
+// nest is empty:
+//
+// A[string]
+// nest = <== type nest at A's instantiation time
+// path = A[A[string]]->B[P]
+//
+// Evaluation then proceeds as before for A[string]:
+//
+// struct{_ B[P₁]}
+// nest = A[string]
+// path = A[A[string]]->B[P]->A[string]
+//
+// Now we reach B[P] again. If we had not adjusted nest, it would
+// correspond to path, and we would find B[P] in nest, indicating
+// a cycle, which would clearly be wrong since there's no cycle in
+// A[string]:
+//
+// B[P₁]
+// nest = A[string]
+// path = A[A[string]]->B[P]->A[string] <== path contains B[P]!
+//
+// But because we use the correct type nest, evaluation proceeds without
+// errors and we get the evaluation sequence:
+//
+// struct{_ P₂}
+// nest = A[string]->B[P]
+// path = A[A[string]]->B[P]->A[string]->B[P]
+// P₂
+// nest = A[string]->B[P]
+// path = A[A[string]]->B[P]->A[string]->B[P]
+// P₁
+// nest = A[string]
+// path = A[A[string]]->B[P]->A[string]->B[P]
+// string
+// nest =
+// path = A[A[string]]->B[P]->A[string]->B[P]
+//
+// At this point we're done and A[A[string]] and is valid.
diff --git a/contrib/go/_std_1.21/src/go/types/version.go b/contrib/go/_std_1.21/src/go/types/version.go
new file mode 100644
index 0000000000..108d9b34a0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/version.go
@@ -0,0 +1,154 @@
+// 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 types
+
+import (
+ "fmt"
+ "go/ast"
+ "go/token"
+ "strings"
+)
+
+// A version represents a released Go version.
+type version struct {
+ major, minor int
+}
+
+func (v version) String() string {
+ return fmt.Sprintf("go%d.%d", v.major, v.minor)
+}
+
+func (v version) equal(u version) bool {
+ return v.major == u.major && v.minor == u.minor
+}
+
+func (v version) before(u version) bool {
+ return v.major < u.major || v.major == u.major && v.minor < u.minor
+}
+
+func (v version) after(u version) bool {
+ return v.major > u.major || v.major == u.major && v.minor > u.minor
+}
+
+// Go versions that introduced language changes.
+var (
+ go0_0 = version{0, 0} // no version specified
+ go1_9 = version{1, 9}
+ go1_13 = version{1, 13}
+ go1_14 = version{1, 14}
+ go1_17 = version{1, 17}
+ go1_18 = version{1, 18}
+ go1_20 = version{1, 20}
+ go1_21 = version{1, 21}
+)
+
+// parseGoVersion parses a Go version string (such as "go1.12")
+// and returns the version, or an error. If s is the empty
+// string, the version is 0.0.
+func parseGoVersion(s string) (v version, err error) {
+ bad := func() (version, error) {
+ return version{}, fmt.Errorf("invalid Go version syntax %q", s)
+ }
+ if s == "" {
+ return
+ }
+ if !strings.HasPrefix(s, "go") {
+ return bad()
+ }
+ s = s[len("go"):]
+ i := 0
+ for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
+ if i >= 10 || i == 0 && s[i] == '0' {
+ return bad()
+ }
+ v.major = 10*v.major + int(s[i]) - '0'
+ }
+ if i > 0 && i == len(s) {
+ return
+ }
+ if i == 0 || s[i] != '.' {
+ return bad()
+ }
+ s = s[i+1:]
+ if s == "0" {
+ // We really should not accept "go1.0",
+ // but we didn't reject it from the start
+ // and there are now programs that use it.
+ // So accept it.
+ return
+ }
+ i = 0
+ for ; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
+ if i >= 10 || i == 0 && s[i] == '0' {
+ return bad()
+ }
+ v.minor = 10*v.minor + int(s[i]) - '0'
+ }
+ // Accept any suffix after the minor number.
+ // We are only looking for the language version (major.minor)
+ // but want to accept any valid Go version, like go1.21.0
+ // and go1.21rc2.
+ return
+}
+
+// langCompat reports an error if the representation of a numeric
+// literal is not compatible with the current language version.
+func (check *Checker) langCompat(lit *ast.BasicLit) {
+ s := lit.Value
+ if len(s) <= 2 || check.allowVersion(check.pkg, lit, go1_13) {
+ return
+ }
+ // len(s) > 2
+ if strings.Contains(s, "_") {
+ check.versionErrorf(lit, go1_13, "underscores in numeric literals")
+ return
+ }
+ if s[0] != '0' {
+ return
+ }
+ radix := s[1]
+ if radix == 'b' || radix == 'B' {
+ check.versionErrorf(lit, go1_13, "binary literals")
+ return
+ }
+ if radix == 'o' || radix == 'O' {
+ check.versionErrorf(lit, go1_13, "0o/0O-style octal literals")
+ return
+ }
+ if lit.Kind != token.INT && (radix == 'x' || radix == 'X') {
+ check.versionErrorf(lit, go1_13, "hexadecimal floating-point literals")
+ }
+}
+
+// allowVersion reports whether the given package
+// is allowed to use version major.minor.
+func (check *Checker) allowVersion(pkg *Package, at positioner, v version) bool {
+ // We assume that imported packages have all been checked,
+ // so we only have to check for the local package.
+ if pkg != check.pkg {
+ return true
+ }
+
+ // If the source file declares its Go version, use that to decide.
+ if check.posVers != nil {
+ if src, ok := check.posVers[check.fset.File(at.Pos())]; ok && src.major >= 1 {
+ return !src.before(v)
+ }
+ }
+
+ // Otherwise fall back to the version in the checker.
+ return check.version.equal(go0_0) || !check.version.before(v)
+}
+
+// verifyVersionf is like allowVersion but also accepts a format string and arguments
+// which are used to report a version error if allowVersion returns false. It uses the
+// current package.
+func (check *Checker) verifyVersionf(at positioner, v version, format string, args ...interface{}) bool {
+ if !check.allowVersion(check.pkg, at, v) {
+ check.versionErrorf(at, v, format, args...)
+ return false
+ }
+ return true
+}
diff --git a/contrib/go/_std_1.21/src/go/types/ya.make b/contrib/go/_std_1.21/src/go/types/ya.make
new file mode 100644
index 0000000000..65f693557a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/go/types/ya.make
@@ -0,0 +1,108 @@
+GO_LIBRARY()
+
+SRCS(
+ api.go
+ array.go
+ assignments.go
+ basic.go
+ builtins.go
+ call.go
+ chan.go
+ check.go
+ const.go
+ context.go
+ conversions.go
+ decl.go
+ errors.go
+ eval.go
+ expr.go
+ exprstring.go
+ gccgosizes.go
+ generate.go
+ index.go
+ infer.go
+ initorder.go
+ instantiate.go
+ interface.go
+ labels.go
+ lookup.go
+ map.go
+ methodset.go
+ mono.go
+ named.go
+ object.go
+ objset.go
+ operand.go
+ package.go
+ pointer.go
+ predicates.go
+ resolver.go
+ return.go
+ scope.go
+ selection.go
+ signature.go
+ sizes.go
+ slice.go
+ stmt.go
+ struct.go
+ subst.go
+ termlist.go
+ tuple.go
+ type.go
+ typelists.go
+ typeparam.go
+ typeset.go
+ typestring.go
+ typeterm.go
+ typexpr.go
+ under.go
+ unify.go
+ union.go
+ universe.go
+ util.go
+ validtype.go
+ version.go
+)
+
+GO_TEST_SRCS(
+ context_test.go
+ errors_test.go
+ sizeof_test.go
+ termlist_test.go
+ token_test.go
+ typeset_test.go
+ typeterm_test.go
+ util_test.go
+ version_test.go
+)
+
+GO_XTEST_SRCS(
+ api_test.go
+ builtins_test.go
+ check_test.go
+ commentMap_test.go
+ errorcalls_test.go
+ eval_test.go
+ example_test.go
+ exprstring_test.go
+ generate_test.go
+ hilbert_test.go
+ instantiate_test.go
+ issues_test.go
+ lookup_test.go
+ main_test.go
+ methodset_test.go
+ mono_test.go
+ named_test.go
+ object_test.go
+ resolver_test.go
+ self_test.go
+ sizes_test.go
+ stdlib_test.go
+ typestring_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/hash/adler32/adler32.go b/contrib/go/_std_1.21/src/hash/adler32/adler32.go
index 38d644d1ee..38d644d1ee 100644
--- a/contrib/go/_std_1.20/src/hash/adler32/adler32.go
+++ b/contrib/go/_std_1.21/src/hash/adler32/adler32.go
diff --git a/contrib/go/_std_1.21/src/hash/adler32/ya.make b/contrib/go/_std_1.21/src/hash/adler32/ya.make
new file mode 100644
index 0000000000..71d064724f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/hash/adler32/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ adler32.go
+)
+
+GO_TEST_SRCS(adler32_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/hash/crc32/crc32.go b/contrib/go/_std_1.21/src/hash/crc32/crc32.go
index e828089308..e828089308 100644
--- a/contrib/go/_std_1.20/src/hash/crc32/crc32.go
+++ b/contrib/go/_std_1.21/src/hash/crc32/crc32.go
diff --git a/contrib/go/_std_1.20/src/hash/crc32/crc32_amd64.go b/contrib/go/_std_1.21/src/hash/crc32/crc32_amd64.go
index 6be129f5dd..6be129f5dd 100644
--- a/contrib/go/_std_1.20/src/hash/crc32/crc32_amd64.go
+++ b/contrib/go/_std_1.21/src/hash/crc32/crc32_amd64.go
diff --git a/contrib/go/_std_1.20/src/hash/crc32/crc32_amd64.s b/contrib/go/_std_1.21/src/hash/crc32/crc32_amd64.s
index 6af6c253a7..6af6c253a7 100644
--- a/contrib/go/_std_1.20/src/hash/crc32/crc32_amd64.s
+++ b/contrib/go/_std_1.21/src/hash/crc32/crc32_amd64.s
diff --git a/contrib/go/_std_1.20/src/hash/crc32/crc32_arm64.go b/contrib/go/_std_1.21/src/hash/crc32/crc32_arm64.go
index 9674b76a27..9674b76a27 100644
--- a/contrib/go/_std_1.20/src/hash/crc32/crc32_arm64.go
+++ b/contrib/go/_std_1.21/src/hash/crc32/crc32_arm64.go
diff --git a/contrib/go/_std_1.20/src/hash/crc32/crc32_arm64.s b/contrib/go/_std_1.21/src/hash/crc32/crc32_arm64.s
index 85a113f9de..85a113f9de 100644
--- a/contrib/go/_std_1.20/src/hash/crc32/crc32_arm64.s
+++ b/contrib/go/_std_1.21/src/hash/crc32/crc32_arm64.s
diff --git a/contrib/go/_std_1.20/src/hash/crc32/crc32_generic.go b/contrib/go/_std_1.21/src/hash/crc32/crc32_generic.go
index abacbb663d..abacbb663d 100644
--- a/contrib/go/_std_1.20/src/hash/crc32/crc32_generic.go
+++ b/contrib/go/_std_1.21/src/hash/crc32/crc32_generic.go
diff --git a/contrib/go/_std_1.21/src/hash/crc32/ya.make b/contrib/go/_std_1.21/src/hash/crc32/ya.make
new file mode 100644
index 0000000000..95c3996f3b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/hash/crc32/ya.make
@@ -0,0 +1,29 @@
+GO_LIBRARY()
+
+SRCS(
+ crc32.go
+ crc32_generic.go
+)
+
+GO_TEST_SRCS(crc32_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+IF (ARCH_X86_64)
+ SRCS(
+ crc32_amd64.go
+ crc32_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ crc32_arm64.go
+ crc32_arm64.s
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/hash/crc64/crc64.go b/contrib/go/_std_1.21/src/hash/crc64/crc64.go
index 26b2573c8e..26b2573c8e 100644
--- a/contrib/go/_std_1.20/src/hash/crc64/crc64.go
+++ b/contrib/go/_std_1.21/src/hash/crc64/crc64.go
diff --git a/contrib/go/_std_1.21/src/hash/crc64/ya.make b/contrib/go/_std_1.21/src/hash/crc64/ya.make
new file mode 100644
index 0000000000..b0c4cf07a5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/hash/crc64/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ crc64.go
+)
+
+GO_TEST_SRCS(crc64_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/hash/fnv/fnv.go b/contrib/go/_std_1.21/src/hash/fnv/fnv.go
index 0fce177cb3..0fce177cb3 100644
--- a/contrib/go/_std_1.20/src/hash/fnv/fnv.go
+++ b/contrib/go/_std_1.21/src/hash/fnv/fnv.go
diff --git a/contrib/go/_std_1.21/src/hash/fnv/ya.make b/contrib/go/_std_1.21/src/hash/fnv/ya.make
new file mode 100644
index 0000000000..1e22830518
--- /dev/null
+++ b/contrib/go/_std_1.21/src/hash/fnv/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ fnv.go
+)
+
+GO_TEST_SRCS(fnv_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/hash/hash.go b/contrib/go/_std_1.21/src/hash/hash.go
index 62cf6a4518..62cf6a4518 100644
--- a/contrib/go/_std_1.20/src/hash/hash.go
+++ b/contrib/go/_std_1.21/src/hash/hash.go
diff --git a/contrib/go/_std_1.21/src/hash/maphash/maphash.go b/contrib/go/_std_1.21/src/hash/maphash/maphash.go
new file mode 100644
index 0000000000..c2e9e400b9
--- /dev/null
+++ b/contrib/go/_std_1.21/src/hash/maphash/maphash.go
@@ -0,0 +1,277 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package maphash provides hash functions on byte sequences.
+// These hash functions are intended to be used to implement hash tables or
+// other data structures that need to map arbitrary strings or byte
+// sequences to a uniform distribution on unsigned 64-bit integers.
+// Each different instance of a hash table or data structure should use its own Seed.
+//
+// The hash functions are not cryptographically secure.
+// (See crypto/sha256 and crypto/sha512 for cryptographic use.)
+package maphash
+
+// A Seed is a random value that selects the specific hash function
+// computed by a Hash. If two Hashes use the same Seeds, they
+// will compute the same hash values for any given input.
+// If two Hashes use different Seeds, they are very likely to compute
+// distinct hash values for any given input.
+//
+// A Seed must be initialized by calling MakeSeed.
+// The zero seed is uninitialized and not valid for use with Hash's SetSeed method.
+//
+// Each Seed value is local to a single process and cannot be serialized
+// or otherwise recreated in a different process.
+type Seed struct {
+ s uint64
+}
+
+// Bytes returns the hash of b with the given seed.
+//
+// Bytes is equivalent to, but more convenient and efficient than:
+//
+// var h Hash
+// h.SetSeed(seed)
+// h.Write(b)
+// return h.Sum64()
+func Bytes(seed Seed, b []byte) uint64 {
+ state := seed.s
+ if state == 0 {
+ panic("maphash: use of uninitialized Seed")
+ }
+
+ if len(b) > bufSize {
+ b = b[:len(b):len(b)] // merge len and cap calculations when reslicing
+ for len(b) > bufSize {
+ state = rthash(b[:bufSize], state)
+ b = b[bufSize:]
+ }
+ }
+ return rthash(b, state)
+}
+
+// String returns the hash of s with the given seed.
+//
+// String is equivalent to, but more convenient and efficient than:
+//
+// var h Hash
+// h.SetSeed(seed)
+// h.WriteString(s)
+// return h.Sum64()
+func String(seed Seed, s string) uint64 {
+ state := seed.s
+ if state == 0 {
+ panic("maphash: use of uninitialized Seed")
+ }
+ for len(s) > bufSize {
+ state = rthashString(s[:bufSize], state)
+ s = s[bufSize:]
+ }
+ return rthashString(s, state)
+}
+
+// A Hash computes a seeded hash of a byte sequence.
+//
+// The zero Hash is a valid Hash ready to use.
+// A zero Hash chooses a random seed for itself during
+// the first call to a Reset, Write, Seed, or Sum64 method.
+// For control over the seed, use SetSeed.
+//
+// The computed hash values depend only on the initial seed and
+// the sequence of bytes provided to the Hash object, not on the way
+// in which the bytes are provided. For example, the three sequences
+//
+// h.Write([]byte{'f','o','o'})
+// h.WriteByte('f'); h.WriteByte('o'); h.WriteByte('o')
+// h.WriteString("foo")
+//
+// all have the same effect.
+//
+// Hashes are intended to be collision-resistant, even for situations
+// where an adversary controls the byte sequences being hashed.
+//
+// A Hash is not safe for concurrent use by multiple goroutines, but a Seed is.
+// If multiple goroutines must compute the same seeded hash,
+// each can declare its own Hash and call SetSeed with a common Seed.
+type Hash struct {
+ _ [0]func() // not comparable
+ seed Seed // initial seed used for this hash
+ state Seed // current hash of all flushed bytes
+ buf [bufSize]byte // unflushed byte buffer
+ n int // number of unflushed bytes
+}
+
+// bufSize is the size of the Hash write buffer.
+// The buffer ensures that writes depend only on the sequence of bytes,
+// not the sequence of WriteByte/Write/WriteString calls,
+// by always calling rthash with a full buffer (except for the tail).
+const bufSize = 128
+
+// initSeed seeds the hash if necessary.
+// initSeed is called lazily before any operation that actually uses h.seed/h.state.
+// Note that this does not include Write/WriteByte/WriteString in the case
+// where they only add to h.buf. (If they write too much, they call h.flush,
+// which does call h.initSeed.)
+func (h *Hash) initSeed() {
+ if h.seed.s == 0 {
+ seed := MakeSeed()
+ h.seed = seed
+ h.state = seed
+ }
+}
+
+// WriteByte adds b to the sequence of bytes hashed by h.
+// It never fails; the error result is for implementing io.ByteWriter.
+func (h *Hash) WriteByte(b byte) error {
+ if h.n == len(h.buf) {
+ h.flush()
+ }
+ h.buf[h.n] = b
+ h.n++
+ return nil
+}
+
+// Write adds b to the sequence of bytes hashed by h.
+// It always writes all of b and never fails; the count and error result are for implementing io.Writer.
+func (h *Hash) Write(b []byte) (int, error) {
+ size := len(b)
+ // Deal with bytes left over in h.buf.
+ // h.n <= bufSize is always true.
+ // Checking it is ~free and it lets the compiler eliminate a bounds check.
+ if h.n > 0 && h.n <= bufSize {
+ k := copy(h.buf[h.n:], b)
+ h.n += k
+ if h.n < bufSize {
+ // Copied the entirety of b to h.buf.
+ return size, nil
+ }
+ b = b[k:]
+ h.flush()
+ // No need to set h.n = 0 here; it happens just before exit.
+ }
+ // Process as many full buffers as possible, without copying, and calling initSeed only once.
+ if len(b) > bufSize {
+ h.initSeed()
+ for len(b) > bufSize {
+ h.state.s = rthash(b[:bufSize], h.state.s)
+ b = b[bufSize:]
+ }
+ }
+ // Copy the tail.
+ copy(h.buf[:], b)
+ h.n = len(b)
+ return size, nil
+}
+
+// WriteString adds the bytes of s to the sequence of bytes hashed by h.
+// It always writes all of s and never fails; the count and error result are for implementing io.StringWriter.
+func (h *Hash) WriteString(s string) (int, error) {
+ // WriteString mirrors Write. See Write for comments.
+ size := len(s)
+ if h.n > 0 && h.n <= bufSize {
+ k := copy(h.buf[h.n:], s)
+ h.n += k
+ if h.n < bufSize {
+ return size, nil
+ }
+ s = s[k:]
+ h.flush()
+ }
+ if len(s) > bufSize {
+ h.initSeed()
+ for len(s) > bufSize {
+ h.state.s = rthashString(s[:bufSize], h.state.s)
+ s = s[bufSize:]
+ }
+ }
+ copy(h.buf[:], s)
+ h.n = len(s)
+ return size, nil
+}
+
+// Seed returns h's seed value.
+func (h *Hash) Seed() Seed {
+ h.initSeed()
+ return h.seed
+}
+
+// SetSeed sets h to use seed, which must have been returned by MakeSeed
+// or by another Hash's Seed method.
+// Two Hash objects with the same seed behave identically.
+// Two Hash objects with different seeds will very likely behave differently.
+// Any bytes added to h before this call will be discarded.
+func (h *Hash) SetSeed(seed Seed) {
+ if seed.s == 0 {
+ panic("maphash: use of uninitialized Seed")
+ }
+ h.seed = seed
+ h.state = seed
+ h.n = 0
+}
+
+// Reset discards all bytes added to h.
+// (The seed remains the same.)
+func (h *Hash) Reset() {
+ h.initSeed()
+ h.state = h.seed
+ h.n = 0
+}
+
+// precondition: buffer is full.
+func (h *Hash) flush() {
+ if h.n != len(h.buf) {
+ panic("maphash: flush of partially full buffer")
+ }
+ h.initSeed()
+ h.state.s = rthash(h.buf[:h.n], h.state.s)
+ h.n = 0
+}
+
+// Sum64 returns h's current 64-bit value, which depends on
+// h's seed and the sequence of bytes added to h since the
+// last call to Reset or SetSeed.
+//
+// All bits of the Sum64 result are close to uniformly and
+// independently distributed, so it can be safely reduced
+// by using bit masking, shifting, or modular arithmetic.
+func (h *Hash) Sum64() uint64 {
+ h.initSeed()
+ return rthash(h.buf[:h.n], h.state.s)
+}
+
+// MakeSeed returns a new random seed.
+func MakeSeed() Seed {
+ var s uint64
+ for {
+ s = randUint64()
+ // We use seed 0 to indicate an uninitialized seed/hash,
+ // so keep trying until we get a non-zero seed.
+ if s != 0 {
+ break
+ }
+ }
+ return Seed{s: s}
+}
+
+// Sum appends the hash's current 64-bit value to b.
+// It exists for implementing hash.Hash.
+// For direct calls, it is more efficient to use Sum64.
+func (h *Hash) Sum(b []byte) []byte {
+ x := h.Sum64()
+ return append(b,
+ byte(x>>0),
+ byte(x>>8),
+ byte(x>>16),
+ byte(x>>24),
+ byte(x>>32),
+ byte(x>>40),
+ byte(x>>48),
+ byte(x>>56))
+}
+
+// Size returns h's hash value size, 8 bytes.
+func (h *Hash) Size() int { return 8 }
+
+// BlockSize returns h's block size.
+func (h *Hash) BlockSize() int { return len(h.buf) }
diff --git a/contrib/go/_std_1.21/src/hash/maphash/maphash_runtime.go b/contrib/go/_std_1.21/src/hash/maphash/maphash_runtime.go
new file mode 100644
index 0000000000..98097ff9c3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/hash/maphash/maphash_runtime.go
@@ -0,0 +1,43 @@
+// Copyright 2023 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.
+
+//go:build !purego
+
+package maphash
+
+import (
+ "unsafe"
+)
+
+//go:linkname runtime_fastrand64 runtime.fastrand64
+func runtime_fastrand64() uint64
+
+//go:linkname runtime_memhash runtime.memhash
+//go:noescape
+func runtime_memhash(p unsafe.Pointer, seed, s uintptr) uintptr
+
+func rthash(buf []byte, seed uint64) uint64 {
+ if len(buf) == 0 {
+ return seed
+ }
+ len := len(buf)
+ // The runtime hasher only works on uintptr. For 64-bit
+ // architectures, we use the hasher directly. Otherwise,
+ // we use two parallel hashers on the lower and upper 32 bits.
+ if unsafe.Sizeof(uintptr(0)) == 8 {
+ return uint64(runtime_memhash(unsafe.Pointer(&buf[0]), uintptr(seed), uintptr(len)))
+ }
+ lo := runtime_memhash(unsafe.Pointer(&buf[0]), uintptr(seed), uintptr(len))
+ hi := runtime_memhash(unsafe.Pointer(&buf[0]), uintptr(seed>>32), uintptr(len))
+ return uint64(hi)<<32 | uint64(lo)
+}
+
+func rthashString(s string, state uint64) uint64 {
+ buf := unsafe.Slice(unsafe.StringData(s), len(s))
+ return rthash(buf, state)
+}
+
+func randUint64() uint64 {
+ return runtime_fastrand64()
+}
diff --git a/contrib/go/_std_1.21/src/hash/maphash/ya.make b/contrib/go/_std_1.21/src/hash/maphash/ya.make
new file mode 100644
index 0000000000..5d66f4fba3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/hash/maphash/ya.make
@@ -0,0 +1,18 @@
+GO_LIBRARY()
+
+SRCS(
+ maphash.go
+ maphash_runtime.go
+)
+
+GO_TEST_SRCS(
+ maphash_test.go
+ smhasher_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/hash/ya.make b/contrib/go/_std_1.21/src/hash/ya.make
new file mode 100644
index 0000000000..7c2306b5dd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/hash/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ hash.go
+)
+
+GO_XTEST_SRCS(
+ example_test.go
+ marshal_test.go
+)
+
+END()
+
+RECURSE(
+ adler32
+ crc32
+ crc64
+ fnv
+ maphash
+)
diff --git a/contrib/go/_std_1.20/src/html/entity.go b/contrib/go/_std_1.21/src/html/entity.go
index f0f9a6a973..f0f9a6a973 100644
--- a/contrib/go/_std_1.20/src/html/entity.go
+++ b/contrib/go/_std_1.21/src/html/entity.go
diff --git a/contrib/go/_std_1.20/src/html/escape.go b/contrib/go/_std_1.21/src/html/escape.go
index 1dc12873b0..1dc12873b0 100644
--- a/contrib/go/_std_1.20/src/html/escape.go
+++ b/contrib/go/_std_1.21/src/html/escape.go
diff --git a/contrib/go/_std_1.20/src/html/template/attr.go b/contrib/go/_std_1.21/src/html/template/attr.go
index 6c52211fed..6c52211fed 100644
--- a/contrib/go/_std_1.20/src/html/template/attr.go
+++ b/contrib/go/_std_1.21/src/html/template/attr.go
diff --git a/contrib/go/_std_1.21/src/html/template/attr_string.go b/contrib/go/_std_1.21/src/html/template/attr_string.go
new file mode 100644
index 0000000000..51c3f26208
--- /dev/null
+++ b/contrib/go/_std_1.21/src/html/template/attr_string.go
@@ -0,0 +1,28 @@
+// Code generated by "stringer -type attr"; DO NOT EDIT.
+
+package template
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[attrNone-0]
+ _ = x[attrScript-1]
+ _ = x[attrScriptType-2]
+ _ = x[attrStyle-3]
+ _ = x[attrURL-4]
+ _ = x[attrSrcset-5]
+}
+
+const _attr_name = "attrNoneattrScriptattrScriptTypeattrStyleattrURLattrSrcset"
+
+var _attr_index = [...]uint8{0, 8, 18, 32, 41, 48, 58}
+
+func (i attr) String() string {
+ if i >= attr(len(_attr_index)-1) {
+ return "attr(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _attr_name[_attr_index[i]:_attr_index[i+1]]
+}
diff --git a/contrib/go/_std_1.20/src/html/template/content.go b/contrib/go/_std_1.21/src/html/template/content.go
index 49d2f261af..49d2f261af 100644
--- a/contrib/go/_std_1.20/src/html/template/content.go
+++ b/contrib/go/_std_1.21/src/html/template/content.go
diff --git a/contrib/go/_std_1.21/src/html/template/context.go b/contrib/go/_std_1.21/src/html/template/context.go
new file mode 100644
index 0000000000..7987713c65
--- /dev/null
+++ b/contrib/go/_std_1.21/src/html/template/context.go
@@ -0,0 +1,286 @@
+// Copyright 2011 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 template
+
+import (
+ "fmt"
+ "text/template/parse"
+)
+
+// context describes the state an HTML parser must be in when it reaches the
+// portion of HTML produced by evaluating a particular template node.
+//
+// The zero value of type context is the start context for a template that
+// produces an HTML fragment as defined at
+// https://www.w3.org/TR/html5/syntax.html#the-end
+// where the context element is null.
+type context struct {
+ state state
+ delim delim
+ urlPart urlPart
+ jsCtx jsCtx
+ attr attr
+ element element
+ n parse.Node // for range break/continue
+ err *Error
+}
+
+func (c context) String() string {
+ var err error
+ if c.err != nil {
+ err = c.err
+ }
+ return fmt.Sprintf("{%v %v %v %v %v %v %v}", c.state, c.delim, c.urlPart, c.jsCtx, c.attr, c.element, err)
+}
+
+// eq reports whether two contexts are equal.
+func (c context) eq(d context) bool {
+ return c.state == d.state &&
+ c.delim == d.delim &&
+ c.urlPart == d.urlPart &&
+ c.jsCtx == d.jsCtx &&
+ c.attr == d.attr &&
+ c.element == d.element &&
+ c.err == d.err
+}
+
+// mangle produces an identifier that includes a suffix that distinguishes it
+// from template names mangled with different contexts.
+func (c context) mangle(templateName string) string {
+ // The mangled name for the default context is the input templateName.
+ if c.state == stateText {
+ return templateName
+ }
+ s := templateName + "$htmltemplate_" + c.state.String()
+ if c.delim != delimNone {
+ s += "_" + c.delim.String()
+ }
+ if c.urlPart != urlPartNone {
+ s += "_" + c.urlPart.String()
+ }
+ if c.jsCtx != jsCtxRegexp {
+ s += "_" + c.jsCtx.String()
+ }
+ if c.attr != attrNone {
+ s += "_" + c.attr.String()
+ }
+ if c.element != elementNone {
+ s += "_" + c.element.String()
+ }
+ return s
+}
+
+// state describes a high-level HTML parser state.
+//
+// It bounds the top of the element stack, and by extension the HTML insertion
+// mode, but also contains state that does not correspond to anything in the
+// HTML5 parsing algorithm because a single token production in the HTML
+// grammar may contain embedded actions in a template. For instance, the quoted
+// HTML attribute produced by
+//
+// <div title="Hello {{.World}}">
+//
+// is a single token in HTML's grammar but in a template spans several nodes.
+type state uint8
+
+//go:generate stringer -type state
+
+const (
+ // stateText is parsed character data. An HTML parser is in
+ // this state when its parse position is outside an HTML tag,
+ // directive, comment, and special element body.
+ stateText state = iota
+ // stateTag occurs before an HTML attribute or the end of a tag.
+ stateTag
+ // stateAttrName occurs inside an attribute name.
+ // It occurs between the ^'s in ` ^name^ = value`.
+ stateAttrName
+ // stateAfterName occurs after an attr name has ended but before any
+ // equals sign. It occurs between the ^'s in ` name^ ^= value`.
+ stateAfterName
+ // stateBeforeValue occurs after the equals sign but before the value.
+ // It occurs between the ^'s in ` name =^ ^value`.
+ stateBeforeValue
+ // stateHTMLCmt occurs inside an <!-- HTML comment -->.
+ stateHTMLCmt
+ // stateRCDATA occurs inside an RCDATA element (<textarea> or <title>)
+ // as described at https://www.w3.org/TR/html5/syntax.html#elements-0
+ stateRCDATA
+ // stateAttr occurs inside an HTML attribute whose content is text.
+ stateAttr
+ // stateURL occurs inside an HTML attribute whose content is a URL.
+ stateURL
+ // stateSrcset occurs inside an HTML srcset attribute.
+ stateSrcset
+ // stateJS occurs inside an event handler or script element.
+ stateJS
+ // stateJSDqStr occurs inside a JavaScript double quoted string.
+ stateJSDqStr
+ // stateJSSqStr occurs inside a JavaScript single quoted string.
+ stateJSSqStr
+ // stateJSBqStr occurs inside a JavaScript back quoted string.
+ stateJSBqStr
+ // stateJSRegexp occurs inside a JavaScript regexp literal.
+ stateJSRegexp
+ // stateJSBlockCmt occurs inside a JavaScript /* block comment */.
+ stateJSBlockCmt
+ // stateJSLineCmt occurs inside a JavaScript // line comment.
+ stateJSLineCmt
+ // stateJSHTMLOpenCmt occurs inside a JavaScript <!-- HTML-like comment.
+ stateJSHTMLOpenCmt
+ // stateJSHTMLCloseCmt occurs inside a JavaScript --> HTML-like comment.
+ stateJSHTMLCloseCmt
+ // stateCSS occurs inside a <style> element or style attribute.
+ stateCSS
+ // stateCSSDqStr occurs inside a CSS double quoted string.
+ stateCSSDqStr
+ // stateCSSSqStr occurs inside a CSS single quoted string.
+ stateCSSSqStr
+ // stateCSSDqURL occurs inside a CSS double quoted url("...").
+ stateCSSDqURL
+ // stateCSSSqURL occurs inside a CSS single quoted url('...').
+ stateCSSSqURL
+ // stateCSSURL occurs inside a CSS unquoted url(...).
+ stateCSSURL
+ // stateCSSBlockCmt occurs inside a CSS /* block comment */.
+ stateCSSBlockCmt
+ // stateCSSLineCmt occurs inside a CSS // line comment.
+ stateCSSLineCmt
+ // stateError is an infectious error state outside any valid
+ // HTML/CSS/JS construct.
+ stateError
+ // stateDead marks unreachable code after a {{break}} or {{continue}}.
+ stateDead
+)
+
+// isComment is true for any state that contains content meant for template
+// authors & maintainers, not for end-users or machines.
+func isComment(s state) bool {
+ switch s {
+ case stateHTMLCmt, stateJSBlockCmt, stateJSLineCmt, stateJSHTMLOpenCmt, stateJSHTMLCloseCmt, stateCSSBlockCmt, stateCSSLineCmt:
+ return true
+ }
+ return false
+}
+
+// isInTag return whether s occurs solely inside an HTML tag.
+func isInTag(s state) bool {
+ switch s {
+ case stateTag, stateAttrName, stateAfterName, stateBeforeValue, stateAttr:
+ return true
+ }
+ return false
+}
+
+// isInScriptLiteral returns true if s is one of the literal states within a
+// <script> tag, and as such occurances of "<!--", "<script", and "</script"
+// need to be treated specially.
+func isInScriptLiteral(s state) bool {
+ // Ignore the comment states (stateJSBlockCmt, stateJSLineCmt,
+ // stateJSHTMLOpenCmt, stateJSHTMLCloseCmt) because their content is already
+ // omitted from the output.
+ switch s {
+ case stateJSDqStr, stateJSSqStr, stateJSBqStr, stateJSRegexp:
+ return true
+ }
+ return false
+}
+
+// delim is the delimiter that will end the current HTML attribute.
+type delim uint8
+
+//go:generate stringer -type delim
+
+const (
+ // delimNone occurs outside any attribute.
+ delimNone delim = iota
+ // delimDoubleQuote occurs when a double quote (") closes the attribute.
+ delimDoubleQuote
+ // delimSingleQuote occurs when a single quote (') closes the attribute.
+ delimSingleQuote
+ // delimSpaceOrTagEnd occurs when a space or right angle bracket (>)
+ // closes the attribute.
+ delimSpaceOrTagEnd
+)
+
+// urlPart identifies a part in an RFC 3986 hierarchical URL to allow different
+// encoding strategies.
+type urlPart uint8
+
+//go:generate stringer -type urlPart
+
+const (
+ // urlPartNone occurs when not in a URL, or possibly at the start:
+ // ^ in "^http://auth/path?k=v#frag".
+ urlPartNone urlPart = iota
+ // urlPartPreQuery occurs in the scheme, authority, or path; between the
+ // ^s in "h^ttp://auth/path^?k=v#frag".
+ urlPartPreQuery
+ // urlPartQueryOrFrag occurs in the query portion between the ^s in
+ // "http://auth/path?^k=v#frag^".
+ urlPartQueryOrFrag
+ // urlPartUnknown occurs due to joining of contexts both before and
+ // after the query separator.
+ urlPartUnknown
+)
+
+// jsCtx determines whether a '/' starts a regular expression literal or a
+// division operator.
+type jsCtx uint8
+
+//go:generate stringer -type jsCtx
+
+const (
+ // jsCtxRegexp occurs where a '/' would start a regexp literal.
+ jsCtxRegexp jsCtx = iota
+ // jsCtxDivOp occurs where a '/' would start a division operator.
+ jsCtxDivOp
+ // jsCtxUnknown occurs where a '/' is ambiguous due to context joining.
+ jsCtxUnknown
+)
+
+// element identifies the HTML element when inside a start tag or special body.
+// Certain HTML element (for example <script> and <style>) have bodies that are
+// treated differently from stateText so the element type is necessary to
+// transition into the correct context at the end of a tag and to identify the
+// end delimiter for the body.
+type element uint8
+
+//go:generate stringer -type element
+
+const (
+ // elementNone occurs outside a special tag or special element body.
+ elementNone element = iota
+ // elementScript corresponds to the raw text <script> element
+ // with JS MIME type or no type attribute.
+ elementScript
+ // elementStyle corresponds to the raw text <style> element.
+ elementStyle
+ // elementTextarea corresponds to the RCDATA <textarea> element.
+ elementTextarea
+ // elementTitle corresponds to the RCDATA <title> element.
+ elementTitle
+)
+
+//go:generate stringer -type attr
+
+// attr identifies the current HTML attribute when inside the attribute,
+// that is, starting from stateAttrName until stateTag/stateText (exclusive).
+type attr uint8
+
+const (
+ // attrNone corresponds to a normal attribute or no attribute.
+ attrNone attr = iota
+ // attrScript corresponds to an event handler attribute.
+ attrScript
+ // attrScriptType corresponds to the type attribute in script HTML element
+ attrScriptType
+ // attrStyle corresponds to the style attribute whose value is CSS.
+ attrStyle
+ // attrURL corresponds to an attribute whose value is a URL.
+ attrURL
+ // attrSrcset corresponds to a srcset attribute.
+ attrSrcset
+)
diff --git a/contrib/go/_std_1.20/src/html/template/css.go b/contrib/go/_std_1.21/src/html/template/css.go
index f650d8b3e8..f650d8b3e8 100644
--- a/contrib/go/_std_1.20/src/html/template/css.go
+++ b/contrib/go/_std_1.21/src/html/template/css.go
diff --git a/contrib/go/_std_1.21/src/html/template/delim_string.go b/contrib/go/_std_1.21/src/html/template/delim_string.go
new file mode 100644
index 0000000000..8d82850223
--- /dev/null
+++ b/contrib/go/_std_1.21/src/html/template/delim_string.go
@@ -0,0 +1,26 @@
+// Code generated by "stringer -type delim"; DO NOT EDIT.
+
+package template
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[delimNone-0]
+ _ = x[delimDoubleQuote-1]
+ _ = x[delimSingleQuote-2]
+ _ = x[delimSpaceOrTagEnd-3]
+}
+
+const _delim_name = "delimNonedelimDoubleQuotedelimSingleQuotedelimSpaceOrTagEnd"
+
+var _delim_index = [...]uint8{0, 9, 25, 41, 59}
+
+func (i delim) String() string {
+ if i >= delim(len(_delim_index)-1) {
+ return "delim(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _delim_name[_delim_index[i]:_delim_index[i+1]]
+}
diff --git a/contrib/go/_std_1.21/src/html/template/doc.go b/contrib/go/_std_1.21/src/html/template/doc.go
new file mode 100644
index 0000000000..672d42ba32
--- /dev/null
+++ b/contrib/go/_std_1.21/src/html/template/doc.go
@@ -0,0 +1,242 @@
+// Copyright 2011 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 template (html/template) implements data-driven templates for
+generating HTML output safe against code injection. It provides the
+same interface as [text/template] and should be used instead of
+[text/template] whenever the output is HTML.
+
+The documentation here focuses on the security features of the package.
+For information about how to program the templates themselves, see the
+documentation for [text/template].
+
+# Introduction
+
+This package wraps [text/template] so you can share its template API
+to parse and execute HTML templates safely.
+
+ tmpl, err := template.New("name").Parse(...)
+ // Error checking elided
+ err = tmpl.Execute(out, data)
+
+If successful, tmpl will now be injection-safe. Otherwise, err is an error
+defined in the docs for ErrorCode.
+
+HTML templates treat data values as plain text which should be encoded so they
+can be safely embedded in an HTML document. The escaping is contextual, so
+actions can appear within JavaScript, CSS, and URI contexts.
+
+The security model used by this package assumes that template authors are
+trusted, while Execute's data parameter is not. More details are
+provided below.
+
+Example
+
+ import "text/template"
+ ...
+ t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
+ err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")
+
+produces
+
+ Hello, <script>alert('you have been pwned')</script>!
+
+but the contextual autoescaping in html/template
+
+ import "html/template"
+ ...
+ t, err := template.New("foo").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
+ err = t.ExecuteTemplate(out, "T", "<script>alert('you have been pwned')</script>")
+
+produces safe, escaped HTML output
+
+ Hello, &lt;script&gt;alert(&#39;you have been pwned&#39;)&lt;/script&gt;!
+
+# Contexts
+
+This package understands HTML, CSS, JavaScript, and URIs. It adds sanitizing
+functions to each simple action pipeline, so given the excerpt
+
+ <a href="/search?q={{.}}">{{.}}</a>
+
+At parse time each {{.}} is overwritten to add escaping functions as necessary.
+In this case it becomes
+
+ <a href="/search?q={{. | urlescaper | attrescaper}}">{{. | htmlescaper}}</a>
+
+where urlescaper, attrescaper, and htmlescaper are aliases for internal escaping
+functions.
+
+For these internal escaping functions, if an action pipeline evaluates to
+a nil interface value, it is treated as though it were an empty string.
+
+# Namespaced and data- attributes
+
+Attributes with a namespace are treated as if they had no namespace.
+Given the excerpt
+
+ <a my:href="{{.}}"></a>
+
+At parse time the attribute will be treated as if it were just "href".
+So at parse time the template becomes:
+
+ <a my:href="{{. | urlescaper | attrescaper}}"></a>
+
+Similarly to attributes with namespaces, attributes with a "data-" prefix are
+treated as if they had no "data-" prefix. So given
+
+ <a data-href="{{.}}"></a>
+
+At parse time this becomes
+
+ <a data-href="{{. | urlescaper | attrescaper}}"></a>
+
+If an attribute has both a namespace and a "data-" prefix, only the namespace
+will be removed when determining the context. For example
+
+ <a my:data-href="{{.}}"></a>
+
+This is handled as if "my:data-href" was just "data-href" and not "href" as
+it would be if the "data-" prefix were to be ignored too. Thus at parse
+time this becomes just
+
+ <a my:data-href="{{. | attrescaper}}"></a>
+
+As a special case, attributes with the namespace "xmlns" are always treated
+as containing URLs. Given the excerpts
+
+ <a xmlns:title="{{.}}"></a>
+ <a xmlns:href="{{.}}"></a>
+ <a xmlns:onclick="{{.}}"></a>
+
+At parse time they become:
+
+ <a xmlns:title="{{. | urlescaper | attrescaper}}"></a>
+ <a xmlns:href="{{. | urlescaper | attrescaper}}"></a>
+ <a xmlns:onclick="{{. | urlescaper | attrescaper}}"></a>
+
+# Errors
+
+See the documentation of ErrorCode for details.
+
+# A fuller picture
+
+The rest of this package comment may be skipped on first reading; it includes
+details necessary to understand escaping contexts and error messages. Most users
+will not need to understand these details.
+
+# Contexts
+
+Assuming {{.}} is `O'Reilly: How are <i>you</i>?`, the table below shows
+how {{.}} appears when used in the context to the left.
+
+ Context {{.}} After
+ {{.}} O'Reilly: How are &lt;i&gt;you&lt;/i&gt;?
+ <a title='{{.}}'> O&#39;Reilly: How are you?
+ <a href="/{{.}}"> O&#39;Reilly: How are %3ci%3eyou%3c/i%3e?
+ <a href="?q={{.}}"> O&#39;Reilly%3a%20How%20are%3ci%3e...%3f
+ <a onx='f("{{.}}")'> O\x27Reilly: How are \x3ci\x3eyou...?
+ <a onx='f({{.}})'> "O\x27Reilly: How are \x3ci\x3eyou...?"
+ <a onx='pattern = /{{.}}/;'> O\x27Reilly: How are \x3ci\x3eyou...\x3f
+
+If used in an unsafe context, then the value might be filtered out:
+
+ Context {{.}} After
+ <a href="{{.}}"> #ZgotmplZ
+
+since "O'Reilly:" is not an allowed protocol like "http:".
+
+If {{.}} is the innocuous word, `left`, then it can appear more widely,
+
+ Context {{.}} After
+ {{.}} left
+ <a title='{{.}}'> left
+ <a href='{{.}}'> left
+ <a href='/{{.}}'> left
+ <a href='?dir={{.}}'> left
+ <a style="border-{{.}}: 4px"> left
+ <a style="align: {{.}}"> left
+ <a style="background: '{{.}}'> left
+ <a style="background: url('{{.}}')> left
+ <style>p.{{.}} {color:red}</style> left
+
+Non-string values can be used in JavaScript contexts.
+If {{.}} is
+
+ struct{A,B string}{ "foo", "bar" }
+
+in the escaped template
+
+ <script>var pair = {{.}};</script>
+
+then the template output is
+
+ <script>var pair = {"A": "foo", "B": "bar"};</script>
+
+See package json to understand how non-string content is marshaled for
+embedding in JavaScript contexts.
+
+# Typed Strings
+
+By default, this package assumes that all pipelines produce a plain text string.
+It adds escaping pipeline stages necessary to correctly and safely embed that
+plain text string in the appropriate context.
+
+When a data value is not plain text, you can make sure it is not over-escaped
+by marking it with its type.
+
+Types HTML, JS, URL, and others from content.go can carry safe content that is
+exempted from escaping.
+
+The template
+
+ Hello, {{.}}!
+
+can be invoked with
+
+ tmpl.Execute(out, template.HTML(`<b>World</b>`))
+
+to produce
+
+ Hello, <b>World</b>!
+
+instead of the
+
+ Hello, &lt;b&gt;World&lt;b&gt;!
+
+that would have been produced if {{.}} was a regular string.
+
+# Security Model
+
+https://rawgit.com/mikesamuel/sanitized-jquery-templates/trunk/safetemplate.html#problem_definition defines "safe" as used by this package.
+
+This package assumes that template authors are trusted, that Execute's data
+parameter is not, and seeks to preserve the properties below in the face
+of untrusted data:
+
+Structure Preservation Property:
+"... when a template author writes an HTML tag in a safe templating language,
+the browser will interpret the corresponding portion of the output as a tag
+regardless of the values of untrusted data, and similarly for other structures
+such as attribute boundaries and JS and CSS string boundaries."
+
+Code Effect Property:
+"... only code specified by the template author should run as a result of
+injecting the template output into a page and all code specified by the
+template author should run as a result of the same."
+
+Least Surprise Property:
+"A developer (or code reviewer) familiar with HTML, CSS, and JavaScript, who
+knows that contextual autoescaping happens should be able to look at a {{.}}
+and correctly infer what sanitization happens."
+
+As a consequence of the Least Surprise Property, template actions within an
+ECMAScript 6 template literal are disabled by default.
+Handling string interpolation within these literals is rather complex resulting
+in no clear safe way to support it.
+To re-enable template actions within ECMAScript 6 template literals, use the
+GODEBUG=jstmpllitinterp=1 environment variable.
+*/
+package template
diff --git a/contrib/go/_std_1.21/src/html/template/element_string.go b/contrib/go/_std_1.21/src/html/template/element_string.go
new file mode 100644
index 0000000000..db286655aa
--- /dev/null
+++ b/contrib/go/_std_1.21/src/html/template/element_string.go
@@ -0,0 +1,27 @@
+// Code generated by "stringer -type element"; DO NOT EDIT.
+
+package template
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[elementNone-0]
+ _ = x[elementScript-1]
+ _ = x[elementStyle-2]
+ _ = x[elementTextarea-3]
+ _ = x[elementTitle-4]
+}
+
+const _element_name = "elementNoneelementScriptelementStyleelementTextareaelementTitle"
+
+var _element_index = [...]uint8{0, 11, 24, 36, 51, 63}
+
+func (i element) String() string {
+ if i >= element(len(_element_index)-1) {
+ return "element(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _element_name[_element_index[i]:_element_index[i+1]]
+}
diff --git a/contrib/go/_std_1.21/src/html/template/error.go b/contrib/go/_std_1.21/src/html/template/error.go
new file mode 100644
index 0000000000..a763924d4a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/html/template/error.go
@@ -0,0 +1,244 @@
+// Copyright 2011 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 template
+
+import (
+ "fmt"
+ "text/template/parse"
+)
+
+// Error describes a problem encountered during template Escaping.
+type Error struct {
+ // ErrorCode describes the kind of error.
+ ErrorCode ErrorCode
+ // Node is the node that caused the problem, if known.
+ // If not nil, it overrides Name and Line.
+ Node parse.Node
+ // Name is the name of the template in which the error was encountered.
+ Name string
+ // Line is the line number of the error in the template source or 0.
+ Line int
+ // Description is a human-readable description of the problem.
+ Description string
+}
+
+// ErrorCode is a code for a kind of error.
+type ErrorCode int
+
+// We define codes for each error that manifests while escaping templates, but
+// escaped templates may also fail at runtime.
+//
+// Output: "ZgotmplZ"
+// Example:
+//
+// <img src="{{.X}}">
+// where {{.X}} evaluates to `javascript:...`
+//
+// Discussion:
+//
+// "ZgotmplZ" is a special value that indicates that unsafe content reached a
+// CSS or URL context at runtime. The output of the example will be
+// <img src="#ZgotmplZ">
+// If the data comes from a trusted source, use content types to exempt it
+// from filtering: URL(`javascript:...`).
+const (
+ // OK indicates the lack of an error.
+ OK ErrorCode = iota
+
+ // ErrAmbigContext: "... appears in an ambiguous context within a URL"
+ // Example:
+ // <a href="
+ // {{if .C}}
+ // /path/
+ // {{else}}
+ // /search?q=
+ // {{end}}
+ // {{.X}}
+ // ">
+ // Discussion:
+ // {{.X}} is in an ambiguous URL context since, depending on {{.C}},
+ // it may be either a URL suffix or a query parameter.
+ // Moving {{.X}} into the condition removes the ambiguity:
+ // <a href="{{if .C}}/path/{{.X}}{{else}}/search?q={{.X}}">
+ ErrAmbigContext
+
+ // ErrBadHTML: "expected space, attr name, or end of tag, but got ...",
+ // "... in unquoted attr", "... in attribute name"
+ // Example:
+ // <a href = /search?q=foo>
+ // <href=foo>
+ // <form na<e=...>
+ // <option selected<
+ // Discussion:
+ // This is often due to a typo in an HTML element, but some runes
+ // are banned in tag names, attribute names, and unquoted attribute
+ // values because they can tickle parser ambiguities.
+ // Quoting all attributes is the best policy.
+ ErrBadHTML
+
+ // ErrBranchEnd: "{{if}} branches end in different contexts"
+ // Example:
+ // {{if .C}}<a href="{{end}}{{.X}}
+ // Discussion:
+ // Package html/template statically examines each path through an
+ // {{if}}, {{range}}, or {{with}} to escape any following pipelines.
+ // The example is ambiguous since {{.X}} might be an HTML text node,
+ // or a URL prefix in an HTML attribute. The context of {{.X}} is
+ // used to figure out how to escape it, but that context depends on
+ // the run-time value of {{.C}} which is not statically known.
+ //
+ // The problem is usually something like missing quotes or angle
+ // brackets, or can be avoided by refactoring to put the two contexts
+ // into different branches of an if, range or with. If the problem
+ // is in a {{range}} over a collection that should never be empty,
+ // adding a dummy {{else}} can help.
+ ErrBranchEnd
+
+ // ErrEndContext: "... ends in a non-text context: ..."
+ // Examples:
+ // <div
+ // <div title="no close quote>
+ // <script>f()
+ // Discussion:
+ // Executed templates should produce a DocumentFragment of HTML.
+ // Templates that end without closing tags will trigger this error.
+ // Templates that should not be used in an HTML context or that
+ // produce incomplete Fragments should not be executed directly.
+ //
+ // {{define "main"}} <script>{{template "helper"}}</script> {{end}}
+ // {{define "helper"}} document.write(' <div title=" ') {{end}}
+ //
+ // "helper" does not produce a valid document fragment, so should
+ // not be Executed directly.
+ ErrEndContext
+
+ // ErrNoSuchTemplate: "no such template ..."
+ // Examples:
+ // {{define "main"}}<div {{template "attrs"}}>{{end}}
+ // {{define "attrs"}}href="{{.URL}}"{{end}}
+ // Discussion:
+ // Package html/template looks through template calls to compute the
+ // context.
+ // Here the {{.URL}} in "attrs" must be treated as a URL when called
+ // from "main", but you will get this error if "attrs" is not defined
+ // when "main" is parsed.
+ ErrNoSuchTemplate
+
+ // ErrOutputContext: "cannot compute output context for template ..."
+ // Examples:
+ // {{define "t"}}{{if .T}}{{template "t" .T}}{{end}}{{.H}}",{{end}}
+ // Discussion:
+ // A recursive template does not end in the same context in which it
+ // starts, and a reliable output context cannot be computed.
+ // Look for typos in the named template.
+ // If the template should not be called in the named start context,
+ // look for calls to that template in unexpected contexts.
+ // Maybe refactor recursive templates to not be recursive.
+ ErrOutputContext
+
+ // ErrPartialCharset: "unfinished JS regexp charset in ..."
+ // Example:
+ // <script>var pattern = /foo[{{.Chars}}]/</script>
+ // Discussion:
+ // Package html/template does not support interpolation into regular
+ // expression literal character sets.
+ ErrPartialCharset
+
+ // ErrPartialEscape: "unfinished escape sequence in ..."
+ // Example:
+ // <script>alert("\{{.X}}")</script>
+ // Discussion:
+ // Package html/template does not support actions following a
+ // backslash.
+ // This is usually an error and there are better solutions; for
+ // example
+ // <script>alert("{{.X}}")</script>
+ // should work, and if {{.X}} is a partial escape sequence such as
+ // "xA0", mark the whole sequence as safe content: JSStr(`\xA0`)
+ ErrPartialEscape
+
+ // ErrRangeLoopReentry: "on range loop re-entry: ..."
+ // Example:
+ // <script>var x = [{{range .}}'{{.}},{{end}}]</script>
+ // Discussion:
+ // If an iteration through a range would cause it to end in a
+ // different context than an earlier pass, there is no single context.
+ // In the example, there is missing a quote, so it is not clear
+ // whether {{.}} is meant to be inside a JS string or in a JS value
+ // context. The second iteration would produce something like
+ //
+ // <script>var x = ['firstValue,'secondValue]</script>
+ ErrRangeLoopReentry
+
+ // ErrSlashAmbig: '/' could start a division or regexp.
+ // Example:
+ // <script>
+ // {{if .C}}var x = 1{{end}}
+ // /-{{.N}}/i.test(x) ? doThis : doThat();
+ // </script>
+ // Discussion:
+ // The example above could produce `var x = 1/-2/i.test(s)...`
+ // in which the first '/' is a mathematical division operator or it
+ // could produce `/-2/i.test(s)` in which the first '/' starts a
+ // regexp literal.
+ // Look for missing semicolons inside branches, and maybe add
+ // parentheses to make it clear which interpretation you intend.
+ ErrSlashAmbig
+
+ // ErrPredefinedEscaper: "predefined escaper ... disallowed in template"
+ // Example:
+ // <div class={{. | html}}>Hello<div>
+ // Discussion:
+ // Package html/template already contextually escapes all pipelines to
+ // produce HTML output safe against code injection. Manually escaping
+ // pipeline output using the predefined escapers "html" or "urlquery" is
+ // unnecessary, and may affect the correctness or safety of the escaped
+ // pipeline output in Go 1.8 and earlier.
+ //
+ // In most cases, such as the given example, this error can be resolved by
+ // simply removing the predefined escaper from the pipeline and letting the
+ // contextual autoescaper handle the escaping of the pipeline. In other
+ // instances, where the predefined escaper occurs in the middle of a
+ // pipeline where subsequent commands expect escaped input, e.g.
+ // {{.X | html | makeALink}}
+ // where makeALink does
+ // return `<a href="`+input+`">link</a>`
+ // consider refactoring the surrounding template to make use of the
+ // contextual autoescaper, i.e.
+ // <a href="{{.X}}">link</a>
+ //
+ // To ease migration to Go 1.9 and beyond, "html" and "urlquery" will
+ // continue to be allowed as the last command in a pipeline. However, if the
+ // pipeline occurs in an unquoted attribute value context, "html" is
+ // disallowed. Avoid using "html" and "urlquery" entirely in new templates.
+ ErrPredefinedEscaper
+
+ // ErrJSTemplate: "... appears in a JS template literal"
+ // Example:
+ // <script>var tmpl = `{{.Interp}}`</script>
+ // Discussion:
+ // Package html/template does not support actions inside of JS template
+ // literals.
+ ErrJSTemplate
+)
+
+func (e *Error) Error() string {
+ switch {
+ case e.Node != nil:
+ loc, _ := (*parse.Tree)(nil).ErrorContext(e.Node)
+ return fmt.Sprintf("html/template:%s: %s", loc, e.Description)
+ case e.Line != 0:
+ return fmt.Sprintf("html/template:%s:%d: %s", e.Name, e.Line, e.Description)
+ case e.Name != "":
+ return fmt.Sprintf("html/template:%s: %s", e.Name, e.Description)
+ }
+ return "html/template: " + e.Description
+}
+
+// errorf creates an error given a format string f and args.
+// The template Name still needs to be supplied.
+func errorf(k ErrorCode, node parse.Node, line int, f string, args ...any) *Error {
+ return &Error{k, node, "", line, fmt.Sprintf(f, args...)}
+}
diff --git a/contrib/go/_std_1.21/src/html/template/escape.go b/contrib/go/_std_1.21/src/html/template/escape.go
new file mode 100644
index 0000000000..01f6303a44
--- /dev/null
+++ b/contrib/go/_std_1.21/src/html/template/escape.go
@@ -0,0 +1,1008 @@
+// Copyright 2011 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 template
+
+import (
+ "bytes"
+ "fmt"
+ "html"
+ "internal/godebug"
+ "io"
+ "regexp"
+ "text/template"
+ "text/template/parse"
+)
+
+// escapeTemplate rewrites the named template, which must be
+// associated with t, to guarantee that the output of any of the named
+// templates is properly escaped. If no error is returned, then the named templates have
+// been modified. Otherwise the named templates have been rendered
+// unusable.
+func escapeTemplate(tmpl *Template, node parse.Node, name string) error {
+ c, _ := tmpl.esc.escapeTree(context{}, node, name, 0)
+ var err error
+ if c.err != nil {
+ err, c.err.Name = c.err, name
+ } else if c.state != stateText {
+ err = &Error{ErrEndContext, nil, name, 0, fmt.Sprintf("ends in a non-text context: %v", c)}
+ }
+ if err != nil {
+ // Prevent execution of unsafe templates.
+ if t := tmpl.set[name]; t != nil {
+ t.escapeErr = err
+ t.text.Tree = nil
+ t.Tree = nil
+ }
+ return err
+ }
+ tmpl.esc.commit()
+ if t := tmpl.set[name]; t != nil {
+ t.escapeErr = escapeOK
+ t.Tree = t.text.Tree
+ }
+ return nil
+}
+
+// evalArgs formats the list of arguments into a string. It is equivalent to
+// fmt.Sprint(args...), except that it dereferences all pointers.
+func evalArgs(args ...any) string {
+ // Optimization for simple common case of a single string argument.
+ if len(args) == 1 {
+ if s, ok := args[0].(string); ok {
+ return s
+ }
+ }
+ for i, arg := range args {
+ args[i] = indirectToStringerOrError(arg)
+ }
+ return fmt.Sprint(args...)
+}
+
+// funcMap maps command names to functions that render their inputs safe.
+var funcMap = template.FuncMap{
+ "_html_template_attrescaper": attrEscaper,
+ "_html_template_commentescaper": commentEscaper,
+ "_html_template_cssescaper": cssEscaper,
+ "_html_template_cssvaluefilter": cssValueFilter,
+ "_html_template_htmlnamefilter": htmlNameFilter,
+ "_html_template_htmlescaper": htmlEscaper,
+ "_html_template_jsregexpescaper": jsRegexpEscaper,
+ "_html_template_jsstrescaper": jsStrEscaper,
+ "_html_template_jsvalescaper": jsValEscaper,
+ "_html_template_nospaceescaper": htmlNospaceEscaper,
+ "_html_template_rcdataescaper": rcdataEscaper,
+ "_html_template_srcsetescaper": srcsetFilterAndEscaper,
+ "_html_template_urlescaper": urlEscaper,
+ "_html_template_urlfilter": urlFilter,
+ "_html_template_urlnormalizer": urlNormalizer,
+ "_eval_args_": evalArgs,
+}
+
+// escaper collects type inferences about templates and changes needed to make
+// templates injection safe.
+type escaper struct {
+ // ns is the nameSpace that this escaper is associated with.
+ ns *nameSpace
+ // output[templateName] is the output context for a templateName that
+ // has been mangled to include its input context.
+ output map[string]context
+ // derived[c.mangle(name)] maps to a template derived from the template
+ // named name templateName for the start context c.
+ derived map[string]*template.Template
+ // called[templateName] is a set of called mangled template names.
+ called map[string]bool
+ // xxxNodeEdits are the accumulated edits to apply during commit.
+ // Such edits are not applied immediately in case a template set
+ // executes a given template in different escaping contexts.
+ actionNodeEdits map[*parse.ActionNode][]string
+ templateNodeEdits map[*parse.TemplateNode]string
+ textNodeEdits map[*parse.TextNode][]byte
+ // rangeContext holds context about the current range loop.
+ rangeContext *rangeContext
+}
+
+// rangeContext holds information about the current range loop.
+type rangeContext struct {
+ outer *rangeContext // outer loop
+ breaks []context // context at each break action
+ continues []context // context at each continue action
+}
+
+// makeEscaper creates a blank escaper for the given set.
+func makeEscaper(n *nameSpace) escaper {
+ return escaper{
+ n,
+ map[string]context{},
+ map[string]*template.Template{},
+ map[string]bool{},
+ map[*parse.ActionNode][]string{},
+ map[*parse.TemplateNode]string{},
+ map[*parse.TextNode][]byte{},
+ nil,
+ }
+}
+
+// filterFailsafe is an innocuous word that is emitted in place of unsafe values
+// by sanitizer functions. It is not a keyword in any programming language,
+// contains no special characters, is not empty, and when it appears in output
+// it is distinct enough that a developer can find the source of the problem
+// via a search engine.
+const filterFailsafe = "ZgotmplZ"
+
+// escape escapes a template node.
+func (e *escaper) escape(c context, n parse.Node) context {
+ switch n := n.(type) {
+ case *parse.ActionNode:
+ return e.escapeAction(c, n)
+ case *parse.BreakNode:
+ c.n = n
+ e.rangeContext.breaks = append(e.rangeContext.breaks, c)
+ return context{state: stateDead}
+ case *parse.CommentNode:
+ return c
+ case *parse.ContinueNode:
+ c.n = n
+ e.rangeContext.continues = append(e.rangeContext.breaks, c)
+ return context{state: stateDead}
+ case *parse.IfNode:
+ return e.escapeBranch(c, &n.BranchNode, "if")
+ case *parse.ListNode:
+ return e.escapeList(c, n)
+ case *parse.RangeNode:
+ return e.escapeBranch(c, &n.BranchNode, "range")
+ case *parse.TemplateNode:
+ return e.escapeTemplate(c, n)
+ case *parse.TextNode:
+ return e.escapeText(c, n)
+ case *parse.WithNode:
+ return e.escapeBranch(c, &n.BranchNode, "with")
+ }
+ panic("escaping " + n.String() + " is unimplemented")
+}
+
+var debugAllowActionJSTmpl = godebug.New("jstmpllitinterp")
+
+// escapeAction escapes an action template node.
+func (e *escaper) escapeAction(c context, n *parse.ActionNode) context {
+ if len(n.Pipe.Decl) != 0 {
+ // A local variable assignment, not an interpolation.
+ return c
+ }
+ c = nudge(c)
+ // Check for disallowed use of predefined escapers in the pipeline.
+ for pos, idNode := range n.Pipe.Cmds {
+ node, ok := idNode.Args[0].(*parse.IdentifierNode)
+ if !ok {
+ // A predefined escaper "esc" will never be found as an identifier in a
+ // Chain or Field node, since:
+ // - "esc.x ..." is invalid, since predefined escapers return strings, and
+ // strings do not have methods, keys or fields.
+ // - "... .esc" is invalid, since predefined escapers are global functions,
+ // not methods or fields of any types.
+ // Therefore, it is safe to ignore these two node types.
+ continue
+ }
+ ident := node.Ident
+ if _, ok := predefinedEscapers[ident]; ok {
+ if pos < len(n.Pipe.Cmds)-1 ||
+ c.state == stateAttr && c.delim == delimSpaceOrTagEnd && ident == "html" {
+ return context{
+ state: stateError,
+ err: errorf(ErrPredefinedEscaper, n, n.Line, "predefined escaper %q disallowed in template", ident),
+ }
+ }
+ }
+ }
+ s := make([]string, 0, 3)
+ switch c.state {
+ case stateError:
+ return c
+ case stateURL, stateCSSDqStr, stateCSSSqStr, stateCSSDqURL, stateCSSSqURL, stateCSSURL:
+ switch c.urlPart {
+ case urlPartNone:
+ s = append(s, "_html_template_urlfilter")
+ fallthrough
+ case urlPartPreQuery:
+ switch c.state {
+ case stateCSSDqStr, stateCSSSqStr:
+ s = append(s, "_html_template_cssescaper")
+ default:
+ s = append(s, "_html_template_urlnormalizer")
+ }
+ case urlPartQueryOrFrag:
+ s = append(s, "_html_template_urlescaper")
+ case urlPartUnknown:
+ return context{
+ state: stateError,
+ err: errorf(ErrAmbigContext, n, n.Line, "%s appears in an ambiguous context within a URL", n),
+ }
+ default:
+ panic(c.urlPart.String())
+ }
+ case stateJS:
+ s = append(s, "_html_template_jsvalescaper")
+ // A slash after a value starts a div operator.
+ c.jsCtx = jsCtxDivOp
+ case stateJSDqStr, stateJSSqStr:
+ s = append(s, "_html_template_jsstrescaper")
+ case stateJSBqStr:
+ if debugAllowActionJSTmpl.Value() == "1" {
+ debugAllowActionJSTmpl.IncNonDefault()
+ s = append(s, "_html_template_jsstrescaper")
+ } else {
+ return context{
+ state: stateError,
+ err: errorf(ErrJSTemplate, n, n.Line, "%s appears in a JS template literal", n),
+ }
+ }
+ case stateJSRegexp:
+ s = append(s, "_html_template_jsregexpescaper")
+ case stateCSS:
+ s = append(s, "_html_template_cssvaluefilter")
+ case stateText:
+ s = append(s, "_html_template_htmlescaper")
+ case stateRCDATA:
+ s = append(s, "_html_template_rcdataescaper")
+ case stateAttr:
+ // Handled below in delim check.
+ case stateAttrName, stateTag:
+ c.state = stateAttrName
+ s = append(s, "_html_template_htmlnamefilter")
+ case stateSrcset:
+ s = append(s, "_html_template_srcsetescaper")
+ default:
+ if isComment(c.state) {
+ s = append(s, "_html_template_commentescaper")
+ } else {
+ panic("unexpected state " + c.state.String())
+ }
+ }
+ switch c.delim {
+ case delimNone:
+ // No extra-escaping needed for raw text content.
+ case delimSpaceOrTagEnd:
+ s = append(s, "_html_template_nospaceescaper")
+ default:
+ s = append(s, "_html_template_attrescaper")
+ }
+ e.editActionNode(n, s)
+ return c
+}
+
+// ensurePipelineContains ensures that the pipeline ends with the commands with
+// the identifiers in s in order. If the pipeline ends with a predefined escaper
+// (i.e. "html" or "urlquery"), merge it with the identifiers in s.
+func ensurePipelineContains(p *parse.PipeNode, s []string) {
+ if len(s) == 0 {
+ // Do not rewrite pipeline if we have no escapers to insert.
+ return
+ }
+ // Precondition: p.Cmds contains at most one predefined escaper and the
+ // escaper will be present at p.Cmds[len(p.Cmds)-1]. This precondition is
+ // always true because of the checks in escapeAction.
+ pipelineLen := len(p.Cmds)
+ if pipelineLen > 0 {
+ lastCmd := p.Cmds[pipelineLen-1]
+ if idNode, ok := lastCmd.Args[0].(*parse.IdentifierNode); ok {
+ if esc := idNode.Ident; predefinedEscapers[esc] {
+ // Pipeline ends with a predefined escaper.
+ if len(p.Cmds) == 1 && len(lastCmd.Args) > 1 {
+ // Special case: pipeline is of the form {{ esc arg1 arg2 ... argN }},
+ // where esc is the predefined escaper, and arg1...argN are its arguments.
+ // Convert this into the equivalent form
+ // {{ _eval_args_ arg1 arg2 ... argN | esc }}, so that esc can be easily
+ // merged with the escapers in s.
+ lastCmd.Args[0] = parse.NewIdentifier("_eval_args_").SetTree(nil).SetPos(lastCmd.Args[0].Position())
+ p.Cmds = appendCmd(p.Cmds, newIdentCmd(esc, p.Position()))
+ pipelineLen++
+ }
+ // If any of the commands in s that we are about to insert is equivalent
+ // to the predefined escaper, use the predefined escaper instead.
+ dup := false
+ for i, escaper := range s {
+ if escFnsEq(esc, escaper) {
+ s[i] = idNode.Ident
+ dup = true
+ }
+ }
+ if dup {
+ // The predefined escaper will already be inserted along with the
+ // escapers in s, so do not copy it to the rewritten pipeline.
+ pipelineLen--
+ }
+ }
+ }
+ }
+ // Rewrite the pipeline, creating the escapers in s at the end of the pipeline.
+ newCmds := make([]*parse.CommandNode, pipelineLen, pipelineLen+len(s))
+ insertedIdents := make(map[string]bool)
+ for i := 0; i < pipelineLen; i++ {
+ cmd := p.Cmds[i]
+ newCmds[i] = cmd
+ if idNode, ok := cmd.Args[0].(*parse.IdentifierNode); ok {
+ insertedIdents[normalizeEscFn(idNode.Ident)] = true
+ }
+ }
+ for _, name := range s {
+ if !insertedIdents[normalizeEscFn(name)] {
+ // When two templates share an underlying parse tree via the use of
+ // AddParseTree and one template is executed after the other, this check
+ // ensures that escapers that were already inserted into the pipeline on
+ // the first escaping pass do not get inserted again.
+ newCmds = appendCmd(newCmds, newIdentCmd(name, p.Position()))
+ }
+ }
+ p.Cmds = newCmds
+}
+
+// predefinedEscapers contains template predefined escapers that are equivalent
+// to some contextual escapers. Keep in sync with equivEscapers.
+var predefinedEscapers = map[string]bool{
+ "html": true,
+ "urlquery": true,
+}
+
+// equivEscapers matches contextual escapers to equivalent predefined
+// template escapers.
+var equivEscapers = map[string]string{
+ // The following pairs of HTML escapers provide equivalent security
+ // guarantees, since they all escape '\000', '\'', '"', '&', '<', and '>'.
+ "_html_template_attrescaper": "html",
+ "_html_template_htmlescaper": "html",
+ "_html_template_rcdataescaper": "html",
+ // These two URL escapers produce URLs safe for embedding in a URL query by
+ // percent-encoding all the reserved characters specified in RFC 3986 Section
+ // 2.2
+ "_html_template_urlescaper": "urlquery",
+ // These two functions are not actually equivalent; urlquery is stricter as it
+ // escapes reserved characters (e.g. '#'), while _html_template_urlnormalizer
+ // does not. It is therefore only safe to replace _html_template_urlnormalizer
+ // with urlquery (this happens in ensurePipelineContains), but not the otherI've
+ // way around. We keep this entry around to preserve the behavior of templates
+ // written before Go 1.9, which might depend on this substitution taking place.
+ "_html_template_urlnormalizer": "urlquery",
+}
+
+// escFnsEq reports whether the two escaping functions are equivalent.
+func escFnsEq(a, b string) bool {
+ return normalizeEscFn(a) == normalizeEscFn(b)
+}
+
+// normalizeEscFn(a) is equal to normalizeEscFn(b) for any pair of names of
+// escaper functions a and b that are equivalent.
+func normalizeEscFn(e string) string {
+ if norm := equivEscapers[e]; norm != "" {
+ return norm
+ }
+ return e
+}
+
+// redundantFuncs[a][b] implies that funcMap[b](funcMap[a](x)) == funcMap[a](x)
+// for all x.
+var redundantFuncs = map[string]map[string]bool{
+ "_html_template_commentescaper": {
+ "_html_template_attrescaper": true,
+ "_html_template_htmlescaper": true,
+ },
+ "_html_template_cssescaper": {
+ "_html_template_attrescaper": true,
+ },
+ "_html_template_jsregexpescaper": {
+ "_html_template_attrescaper": true,
+ },
+ "_html_template_jsstrescaper": {
+ "_html_template_attrescaper": true,
+ },
+ "_html_template_urlescaper": {
+ "_html_template_urlnormalizer": true,
+ },
+}
+
+// appendCmd appends the given command to the end of the command pipeline
+// unless it is redundant with the last command.
+func appendCmd(cmds []*parse.CommandNode, cmd *parse.CommandNode) []*parse.CommandNode {
+ if n := len(cmds); n != 0 {
+ last, okLast := cmds[n-1].Args[0].(*parse.IdentifierNode)
+ next, okNext := cmd.Args[0].(*parse.IdentifierNode)
+ if okLast && okNext && redundantFuncs[last.Ident][next.Ident] {
+ return cmds
+ }
+ }
+ return append(cmds, cmd)
+}
+
+// newIdentCmd produces a command containing a single identifier node.
+func newIdentCmd(identifier string, pos parse.Pos) *parse.CommandNode {
+ return &parse.CommandNode{
+ NodeType: parse.NodeCommand,
+ Args: []parse.Node{parse.NewIdentifier(identifier).SetTree(nil).SetPos(pos)}, // TODO: SetTree.
+ }
+}
+
+// nudge returns the context that would result from following empty string
+// transitions from the input context.
+// For example, parsing:
+//
+// `<a href=`
+//
+// will end in context{stateBeforeValue, attrURL}, but parsing one extra rune:
+//
+// `<a href=x`
+//
+// will end in context{stateURL, delimSpaceOrTagEnd, ...}.
+// There are two transitions that happen when the 'x' is seen:
+// (1) Transition from a before-value state to a start-of-value state without
+//
+// consuming any character.
+//
+// (2) Consume 'x' and transition past the first value character.
+// In this case, nudging produces the context after (1) happens.
+func nudge(c context) context {
+ switch c.state {
+ case stateTag:
+ // In `<foo {{.}}`, the action should emit an attribute.
+ c.state = stateAttrName
+ case stateBeforeValue:
+ // In `<foo bar={{.}}`, the action is an undelimited value.
+ c.state, c.delim, c.attr = attrStartStates[c.attr], delimSpaceOrTagEnd, attrNone
+ case stateAfterName:
+ // In `<foo bar {{.}}`, the action is an attribute name.
+ c.state, c.attr = stateAttrName, attrNone
+ }
+ return c
+}
+
+// join joins the two contexts of a branch template node. The result is an
+// error context if either of the input contexts are error contexts, or if the
+// input contexts differ.
+func join(a, b context, node parse.Node, nodeName string) context {
+ if a.state == stateError {
+ return a
+ }
+ if b.state == stateError {
+ return b
+ }
+ if a.state == stateDead {
+ return b
+ }
+ if b.state == stateDead {
+ return a
+ }
+ if a.eq(b) {
+ return a
+ }
+
+ c := a
+ c.urlPart = b.urlPart
+ if c.eq(b) {
+ // The contexts differ only by urlPart.
+ c.urlPart = urlPartUnknown
+ return c
+ }
+
+ c = a
+ c.jsCtx = b.jsCtx
+ if c.eq(b) {
+ // The contexts differ only by jsCtx.
+ c.jsCtx = jsCtxUnknown
+ return c
+ }
+
+ // Allow a nudged context to join with an unnudged one.
+ // This means that
+ // <p title={{if .C}}{{.}}{{end}}
+ // ends in an unquoted value state even though the else branch
+ // ends in stateBeforeValue.
+ if c, d := nudge(a), nudge(b); !(c.eq(a) && d.eq(b)) {
+ if e := join(c, d, node, nodeName); e.state != stateError {
+ return e
+ }
+ }
+
+ return context{
+ state: stateError,
+ err: errorf(ErrBranchEnd, node, 0, "{{%s}} branches end in different contexts: %v, %v", nodeName, a, b),
+ }
+}
+
+// escapeBranch escapes a branch template node: "if", "range" and "with".
+func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName string) context {
+ if nodeName == "range" {
+ e.rangeContext = &rangeContext{outer: e.rangeContext}
+ }
+ c0 := e.escapeList(c, n.List)
+ if nodeName == "range" {
+ if c0.state != stateError {
+ c0 = joinRange(c0, e.rangeContext)
+ }
+ e.rangeContext = e.rangeContext.outer
+ if c0.state == stateError {
+ return c0
+ }
+
+ // The "true" branch of a "range" node can execute multiple times.
+ // We check that executing n.List once results in the same context
+ // as executing n.List twice.
+ e.rangeContext = &rangeContext{outer: e.rangeContext}
+ c1, _ := e.escapeListConditionally(c0, n.List, nil)
+ c0 = join(c0, c1, n, nodeName)
+ if c0.state == stateError {
+ e.rangeContext = e.rangeContext.outer
+ // Make clear that this is a problem on loop re-entry
+ // since developers tend to overlook that branch when
+ // debugging templates.
+ c0.err.Line = n.Line
+ c0.err.Description = "on range loop re-entry: " + c0.err.Description
+ return c0
+ }
+ c0 = joinRange(c0, e.rangeContext)
+ e.rangeContext = e.rangeContext.outer
+ if c0.state == stateError {
+ return c0
+ }
+ }
+ c1 := e.escapeList(c, n.ElseList)
+ return join(c0, c1, n, nodeName)
+}
+
+func joinRange(c0 context, rc *rangeContext) context {
+ // Merge contexts at break and continue statements into overall body context.
+ // In theory we could treat breaks differently from continues, but for now it is
+ // enough to treat them both as going back to the start of the loop (which may then stop).
+ for _, c := range rc.breaks {
+ c0 = join(c0, c, c.n, "range")
+ if c0.state == stateError {
+ c0.err.Line = c.n.(*parse.BreakNode).Line
+ c0.err.Description = "at range loop break: " + c0.err.Description
+ return c0
+ }
+ }
+ for _, c := range rc.continues {
+ c0 = join(c0, c, c.n, "range")
+ if c0.state == stateError {
+ c0.err.Line = c.n.(*parse.ContinueNode).Line
+ c0.err.Description = "at range loop continue: " + c0.err.Description
+ return c0
+ }
+ }
+ return c0
+}
+
+// escapeList escapes a list template node.
+func (e *escaper) escapeList(c context, n *parse.ListNode) context {
+ if n == nil {
+ return c
+ }
+ for _, m := range n.Nodes {
+ c = e.escape(c, m)
+ if c.state == stateDead {
+ break
+ }
+ }
+ return c
+}
+
+// escapeListConditionally escapes a list node but only preserves edits and
+// inferences in e if the inferences and output context satisfy filter.
+// It returns the best guess at an output context, and the result of the filter
+// which is the same as whether e was updated.
+func (e *escaper) escapeListConditionally(c context, n *parse.ListNode, filter func(*escaper, context) bool) (context, bool) {
+ e1 := makeEscaper(e.ns)
+ e1.rangeContext = e.rangeContext
+ // Make type inferences available to f.
+ for k, v := range e.output {
+ e1.output[k] = v
+ }
+ c = e1.escapeList(c, n)
+ ok := filter != nil && filter(&e1, c)
+ if ok {
+ // Copy inferences and edits from e1 back into e.
+ for k, v := range e1.output {
+ e.output[k] = v
+ }
+ for k, v := range e1.derived {
+ e.derived[k] = v
+ }
+ for k, v := range e1.called {
+ e.called[k] = v
+ }
+ for k, v := range e1.actionNodeEdits {
+ e.editActionNode(k, v)
+ }
+ for k, v := range e1.templateNodeEdits {
+ e.editTemplateNode(k, v)
+ }
+ for k, v := range e1.textNodeEdits {
+ e.editTextNode(k, v)
+ }
+ }
+ return c, ok
+}
+
+// escapeTemplate escapes a {{template}} call node.
+func (e *escaper) escapeTemplate(c context, n *parse.TemplateNode) context {
+ c, name := e.escapeTree(c, n, n.Name, n.Line)
+ if name != n.Name {
+ e.editTemplateNode(n, name)
+ }
+ return c
+}
+
+// escapeTree escapes the named template starting in the given context as
+// necessary and returns its output context.
+func (e *escaper) escapeTree(c context, node parse.Node, name string, line int) (context, string) {
+ // Mangle the template name with the input context to produce a reliable
+ // identifier.
+ dname := c.mangle(name)
+ e.called[dname] = true
+ if out, ok := e.output[dname]; ok {
+ // Already escaped.
+ return out, dname
+ }
+ t := e.template(name)
+ if t == nil {
+ // Two cases: The template exists but is empty, or has never been mentioned at
+ // all. Distinguish the cases in the error messages.
+ if e.ns.set[name] != nil {
+ return context{
+ state: stateError,
+ err: errorf(ErrNoSuchTemplate, node, line, "%q is an incomplete or empty template", name),
+ }, dname
+ }
+ return context{
+ state: stateError,
+ err: errorf(ErrNoSuchTemplate, node, line, "no such template %q", name),
+ }, dname
+ }
+ if dname != name {
+ // Use any template derived during an earlier call to escapeTemplate
+ // with different top level templates, or clone if necessary.
+ dt := e.template(dname)
+ if dt == nil {
+ dt = template.New(dname)
+ dt.Tree = &parse.Tree{Name: dname, Root: t.Root.CopyList()}
+ e.derived[dname] = dt
+ }
+ t = dt
+ }
+ return e.computeOutCtx(c, t), dname
+}
+
+// computeOutCtx takes a template and its start context and computes the output
+// context while storing any inferences in e.
+func (e *escaper) computeOutCtx(c context, t *template.Template) context {
+ // Propagate context over the body.
+ c1, ok := e.escapeTemplateBody(c, t)
+ if !ok {
+ // Look for a fixed point by assuming c1 as the output context.
+ if c2, ok2 := e.escapeTemplateBody(c1, t); ok2 {
+ c1, ok = c2, true
+ }
+ // Use c1 as the error context if neither assumption worked.
+ }
+ if !ok && c1.state != stateError {
+ return context{
+ state: stateError,
+ err: errorf(ErrOutputContext, t.Tree.Root, 0, "cannot compute output context for template %s", t.Name()),
+ }
+ }
+ return c1
+}
+
+// escapeTemplateBody escapes the given template assuming the given output
+// context, and returns the best guess at the output context and whether the
+// assumption was correct.
+func (e *escaper) escapeTemplateBody(c context, t *template.Template) (context, bool) {
+ filter := func(e1 *escaper, c1 context) bool {
+ if c1.state == stateError {
+ // Do not update the input escaper, e.
+ return false
+ }
+ if !e1.called[t.Name()] {
+ // If t is not recursively called, then c1 is an
+ // accurate output context.
+ return true
+ }
+ // c1 is accurate if it matches our assumed output context.
+ return c.eq(c1)
+ }
+ // We need to assume an output context so that recursive template calls
+ // take the fast path out of escapeTree instead of infinitely recurring.
+ // Naively assuming that the input context is the same as the output
+ // works >90% of the time.
+ e.output[t.Name()] = c
+ return e.escapeListConditionally(c, t.Tree.Root, filter)
+}
+
+// delimEnds maps each delim to a string of characters that terminate it.
+var delimEnds = [...]string{
+ delimDoubleQuote: `"`,
+ delimSingleQuote: "'",
+ // Determined empirically by running the below in various browsers.
+ // var div = document.createElement("DIV");
+ // for (var i = 0; i < 0x10000; ++i) {
+ // div.innerHTML = "<span title=x" + String.fromCharCode(i) + "-bar>";
+ // if (div.getElementsByTagName("SPAN")[0].title.indexOf("bar") < 0)
+ // document.write("<p>U+" + i.toString(16));
+ // }
+ delimSpaceOrTagEnd: " \t\n\f\r>",
+}
+
+var (
+ // Per WHATWG HTML specification, section 4.12.1.3, there are extremely
+ // complicated rules for how to handle the set of opening tags <!--,
+ // <script, and </script when they appear in JS literals (i.e. strings,
+ // regexs, and comments). The specification suggests a simple solution,
+ // rather than implementing the arcane ABNF, which involves simply escaping
+ // the opening bracket with \x3C. We use the below regex for this, since it
+ // makes doing the case-insensitive find-replace much simpler.
+ specialScriptTagRE = regexp.MustCompile("(?i)<(script|/script|!--)")
+ specialScriptTagReplacement = []byte("\\x3C$1")
+)
+
+func containsSpecialScriptTag(s []byte) bool {
+ return specialScriptTagRE.Match(s)
+}
+
+func escapeSpecialScriptTags(s []byte) []byte {
+ return specialScriptTagRE.ReplaceAll(s, specialScriptTagReplacement)
+}
+
+var doctypeBytes = []byte("<!DOCTYPE")
+
+// escapeText escapes a text template node.
+func (e *escaper) escapeText(c context, n *parse.TextNode) context {
+ s, written, i, b := n.Text, 0, 0, new(bytes.Buffer)
+ for i != len(s) {
+ c1, nread := contextAfterText(c, s[i:])
+ i1 := i + nread
+ if c.state == stateText || c.state == stateRCDATA {
+ end := i1
+ if c1.state != c.state {
+ for j := end - 1; j >= i; j-- {
+ if s[j] == '<' {
+ end = j
+ break
+ }
+ }
+ }
+ for j := i; j < end; j++ {
+ if s[j] == '<' && !bytes.HasPrefix(bytes.ToUpper(s[j:]), doctypeBytes) {
+ b.Write(s[written:j])
+ b.WriteString("&lt;")
+ written = j + 1
+ }
+ }
+ } else if isComment(c.state) && c.delim == delimNone {
+ switch c.state {
+ case stateJSBlockCmt:
+ // https://es5.github.io/#x7.4:
+ // "Comments behave like white space and are
+ // discarded except that, if a MultiLineComment
+ // contains a line terminator character, then
+ // the entire comment is considered to be a
+ // LineTerminator for purposes of parsing by
+ // the syntactic grammar."
+ if bytes.ContainsAny(s[written:i1], "\n\r\u2028\u2029") {
+ b.WriteByte('\n')
+ } else {
+ b.WriteByte(' ')
+ }
+ case stateCSSBlockCmt:
+ b.WriteByte(' ')
+ }
+ written = i1
+ }
+ if c.state != c1.state && isComment(c1.state) && c1.delim == delimNone {
+ // Preserve the portion between written and the comment start.
+ cs := i1 - 2
+ if c1.state == stateHTMLCmt || c1.state == stateJSHTMLOpenCmt {
+ // "<!--" instead of "/*" or "//"
+ cs -= 2
+ } else if c1.state == stateJSHTMLCloseCmt {
+ // "-->" instead of "/*" or "//"
+ cs -= 1
+ }
+ b.Write(s[written:cs])
+ written = i1
+ }
+ if isInScriptLiteral(c.state) && containsSpecialScriptTag(s[i:i1]) {
+ b.Write(s[written:i])
+ b.Write(escapeSpecialScriptTags(s[i:i1]))
+ written = i1
+ }
+ if i == i1 && c.state == c1.state {
+ panic(fmt.Sprintf("infinite loop from %v to %v on %q..%q", c, c1, s[:i], s[i:]))
+ }
+ c, i = c1, i1
+ }
+
+ if written != 0 && c.state != stateError {
+ if !isComment(c.state) || c.delim != delimNone {
+ b.Write(n.Text[written:])
+ }
+ e.editTextNode(n, b.Bytes())
+ }
+ return c
+}
+
+// contextAfterText starts in context c, consumes some tokens from the front of
+// s, then returns the context after those tokens and the unprocessed suffix.
+func contextAfterText(c context, s []byte) (context, int) {
+ if c.delim == delimNone {
+ c1, i := tSpecialTagEnd(c, s)
+ if i == 0 {
+ // A special end tag (`</script>`) has been seen and
+ // all content preceding it has been consumed.
+ return c1, 0
+ }
+ // Consider all content up to any end tag.
+ return transitionFunc[c.state](c, s[:i])
+ }
+
+ // We are at the beginning of an attribute value.
+
+ i := bytes.IndexAny(s, delimEnds[c.delim])
+ if i == -1 {
+ i = len(s)
+ }
+ if c.delim == delimSpaceOrTagEnd {
+ // https://www.w3.org/TR/html5/syntax.html#attribute-value-(unquoted)-state
+ // lists the runes below as error characters.
+ // Error out because HTML parsers may differ on whether
+ // "<a id= onclick=f(" ends inside id's or onclick's value,
+ // "<a class=`foo " ends inside a value,
+ // "<a style=font:'Arial'" needs open-quote fixup.
+ // IE treats '`' as a quotation character.
+ if j := bytes.IndexAny(s[:i], "\"'<=`"); j >= 0 {
+ return context{
+ state: stateError,
+ err: errorf(ErrBadHTML, nil, 0, "%q in unquoted attr: %q", s[j:j+1], s[:i]),
+ }, len(s)
+ }
+ }
+ if i == len(s) {
+ // Remain inside the attribute.
+ // Decode the value so non-HTML rules can easily handle
+ // <button onclick="alert(&quot;Hi!&quot;)">
+ // without having to entity decode token boundaries.
+ for u := []byte(html.UnescapeString(string(s))); len(u) != 0; {
+ c1, i1 := transitionFunc[c.state](c, u)
+ c, u = c1, u[i1:]
+ }
+ return c, len(s)
+ }
+
+ element := c.element
+
+ // If this is a non-JS "type" attribute inside "script" tag, do not treat the contents as JS.
+ if c.state == stateAttr && c.element == elementScript && c.attr == attrScriptType && !isJSType(string(s[:i])) {
+ element = elementNone
+ }
+
+ if c.delim != delimSpaceOrTagEnd {
+ // Consume any quote.
+ i++
+ }
+ // On exiting an attribute, we discard all state information
+ // except the state and element.
+ return context{state: stateTag, element: element}, i
+}
+
+// editActionNode records a change to an action pipeline for later commit.
+func (e *escaper) editActionNode(n *parse.ActionNode, cmds []string) {
+ if _, ok := e.actionNodeEdits[n]; ok {
+ panic(fmt.Sprintf("node %s shared between templates", n))
+ }
+ e.actionNodeEdits[n] = cmds
+}
+
+// editTemplateNode records a change to a {{template}} callee for later commit.
+func (e *escaper) editTemplateNode(n *parse.TemplateNode, callee string) {
+ if _, ok := e.templateNodeEdits[n]; ok {
+ panic(fmt.Sprintf("node %s shared between templates", n))
+ }
+ e.templateNodeEdits[n] = callee
+}
+
+// editTextNode records a change to a text node for later commit.
+func (e *escaper) editTextNode(n *parse.TextNode, text []byte) {
+ if _, ok := e.textNodeEdits[n]; ok {
+ panic(fmt.Sprintf("node %s shared between templates", n))
+ }
+ e.textNodeEdits[n] = text
+}
+
+// commit applies changes to actions and template calls needed to contextually
+// autoescape content and adds any derived templates to the set.
+func (e *escaper) commit() {
+ for name := range e.output {
+ e.template(name).Funcs(funcMap)
+ }
+ // Any template from the name space associated with this escaper can be used
+ // to add derived templates to the underlying text/template name space.
+ tmpl := e.arbitraryTemplate()
+ for _, t := range e.derived {
+ if _, err := tmpl.text.AddParseTree(t.Name(), t.Tree); err != nil {
+ panic("error adding derived template")
+ }
+ }
+ for n, s := range e.actionNodeEdits {
+ ensurePipelineContains(n.Pipe, s)
+ }
+ for n, name := range e.templateNodeEdits {
+ n.Name = name
+ }
+ for n, s := range e.textNodeEdits {
+ n.Text = s
+ }
+ // Reset state that is specific to this commit so that the same changes are
+ // not re-applied to the template on subsequent calls to commit.
+ e.called = make(map[string]bool)
+ e.actionNodeEdits = make(map[*parse.ActionNode][]string)
+ e.templateNodeEdits = make(map[*parse.TemplateNode]string)
+ e.textNodeEdits = make(map[*parse.TextNode][]byte)
+}
+
+// template returns the named template given a mangled template name.
+func (e *escaper) template(name string) *template.Template {
+ // Any template from the name space associated with this escaper can be used
+ // to look up templates in the underlying text/template name space.
+ t := e.arbitraryTemplate().text.Lookup(name)
+ if t == nil {
+ t = e.derived[name]
+ }
+ return t
+}
+
+// arbitraryTemplate returns an arbitrary template from the name space
+// associated with e and panics if no templates are found.
+func (e *escaper) arbitraryTemplate() *Template {
+ for _, t := range e.ns.set {
+ return t
+ }
+ panic("no templates in name space")
+}
+
+// Forwarding functions so that clients need only import this package
+// to reach the general escaping functions of text/template.
+
+// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
+func HTMLEscape(w io.Writer, b []byte) {
+ template.HTMLEscape(w, b)
+}
+
+// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
+func HTMLEscapeString(s string) string {
+ return template.HTMLEscapeString(s)
+}
+
+// HTMLEscaper returns the escaped HTML equivalent of the textual
+// representation of its arguments.
+func HTMLEscaper(args ...any) string {
+ return template.HTMLEscaper(args...)
+}
+
+// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
+func JSEscape(w io.Writer, b []byte) {
+ template.JSEscape(w, b)
+}
+
+// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
+func JSEscapeString(s string) string {
+ return template.JSEscapeString(s)
+}
+
+// JSEscaper returns the escaped JavaScript equivalent of the textual
+// representation of its arguments.
+func JSEscaper(args ...any) string {
+ return template.JSEscaper(args...)
+}
+
+// URLQueryEscaper returns the escaped value of the textual representation of
+// its arguments in a form suitable for embedding in a URL query.
+func URLQueryEscaper(args ...any) string {
+ return template.URLQueryEscaper(args...)
+}
diff --git a/contrib/go/_std_1.20/src/html/template/html.go b/contrib/go/_std_1.21/src/html/template/html.go
index a181699a5b..a181699a5b 100644
--- a/contrib/go/_std_1.20/src/html/template/html.go
+++ b/contrib/go/_std_1.21/src/html/template/html.go
diff --git a/contrib/go/_std_1.20/src/html/template/js.go b/contrib/go/_std_1.21/src/html/template/js.go
index 4e05c14557..4e05c14557 100644
--- a/contrib/go/_std_1.20/src/html/template/js.go
+++ b/contrib/go/_std_1.21/src/html/template/js.go
diff --git a/contrib/go/_std_1.20/src/html/template/jsctx_string.go b/contrib/go/_std_1.21/src/html/template/jsctx_string.go
index 23948934c9..23948934c9 100644
--- a/contrib/go/_std_1.20/src/html/template/jsctx_string.go
+++ b/contrib/go/_std_1.21/src/html/template/jsctx_string.go
diff --git a/contrib/go/_std_1.21/src/html/template/state_string.go b/contrib/go/_std_1.21/src/html/template/state_string.go
new file mode 100644
index 0000000000..be7a920511
--- /dev/null
+++ b/contrib/go/_std_1.21/src/html/template/state_string.go
@@ -0,0 +1,51 @@
+// Code generated by "stringer -type state"; DO NOT EDIT.
+
+package template
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[stateText-0]
+ _ = x[stateTag-1]
+ _ = x[stateAttrName-2]
+ _ = x[stateAfterName-3]
+ _ = x[stateBeforeValue-4]
+ _ = x[stateHTMLCmt-5]
+ _ = x[stateRCDATA-6]
+ _ = x[stateAttr-7]
+ _ = x[stateURL-8]
+ _ = x[stateSrcset-9]
+ _ = x[stateJS-10]
+ _ = x[stateJSDqStr-11]
+ _ = x[stateJSSqStr-12]
+ _ = x[stateJSBqStr-13]
+ _ = x[stateJSRegexp-14]
+ _ = x[stateJSBlockCmt-15]
+ _ = x[stateJSLineCmt-16]
+ _ = x[stateJSHTMLOpenCmt-17]
+ _ = x[stateJSHTMLCloseCmt-18]
+ _ = x[stateCSS-19]
+ _ = x[stateCSSDqStr-20]
+ _ = x[stateCSSSqStr-21]
+ _ = x[stateCSSDqURL-22]
+ _ = x[stateCSSSqURL-23]
+ _ = x[stateCSSURL-24]
+ _ = x[stateCSSBlockCmt-25]
+ _ = x[stateCSSLineCmt-26]
+ _ = x[stateError-27]
+ _ = x[stateDead-28]
+}
+
+const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSBqStrstateJSRegexpstateJSBlockCmtstateJSLineCmtstateJSHTMLOpenCmtstateJSHTMLCloseCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead"
+
+var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 154, 167, 182, 196, 214, 233, 241, 254, 267, 280, 293, 304, 320, 335, 345, 354}
+
+func (i state) String() string {
+ if i >= state(len(_state_index)-1) {
+ return "state(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _state_name[_state_index[i]:_state_index[i+1]]
+}
diff --git a/contrib/go/_std_1.20/src/html/template/template.go b/contrib/go/_std_1.21/src/html/template/template.go
index 30b64dff04..30b64dff04 100644
--- a/contrib/go/_std_1.20/src/html/template/template.go
+++ b/contrib/go/_std_1.21/src/html/template/template.go
diff --git a/contrib/go/_std_1.21/src/html/template/transition.go b/contrib/go/_std_1.21/src/html/template/transition.go
new file mode 100644
index 0000000000..432c365d3c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/html/template/transition.go
@@ -0,0 +1,634 @@
+// Copyright 2011 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 template
+
+import (
+ "bytes"
+ "strings"
+)
+
+// transitionFunc is the array of context transition functions for text nodes.
+// A transition function takes a context and template text input, and returns
+// the updated context and the number of bytes consumed from the front of the
+// input.
+var transitionFunc = [...]func(context, []byte) (context, int){
+ stateText: tText,
+ stateTag: tTag,
+ stateAttrName: tAttrName,
+ stateAfterName: tAfterName,
+ stateBeforeValue: tBeforeValue,
+ stateHTMLCmt: tHTMLCmt,
+ stateRCDATA: tSpecialTagEnd,
+ stateAttr: tAttr,
+ stateURL: tURL,
+ stateSrcset: tURL,
+ stateJS: tJS,
+ stateJSDqStr: tJSDelimited,
+ stateJSSqStr: tJSDelimited,
+ stateJSBqStr: tJSDelimited,
+ stateJSRegexp: tJSDelimited,
+ stateJSBlockCmt: tBlockCmt,
+ stateJSLineCmt: tLineCmt,
+ stateJSHTMLOpenCmt: tLineCmt,
+ stateJSHTMLCloseCmt: tLineCmt,
+ stateCSS: tCSS,
+ stateCSSDqStr: tCSSStr,
+ stateCSSSqStr: tCSSStr,
+ stateCSSDqURL: tCSSStr,
+ stateCSSSqURL: tCSSStr,
+ stateCSSURL: tCSSStr,
+ stateCSSBlockCmt: tBlockCmt,
+ stateCSSLineCmt: tLineCmt,
+ stateError: tError,
+}
+
+var commentStart = []byte("<!--")
+var commentEnd = []byte("-->")
+
+// tText is the context transition function for the text state.
+func tText(c context, s []byte) (context, int) {
+ k := 0
+ for {
+ i := k + bytes.IndexByte(s[k:], '<')
+ if i < k || i+1 == len(s) {
+ return c, len(s)
+ } else if i+4 <= len(s) && bytes.Equal(commentStart, s[i:i+4]) {
+ return context{state: stateHTMLCmt}, i + 4
+ }
+ i++
+ end := false
+ if s[i] == '/' {
+ if i+1 == len(s) {
+ return c, len(s)
+ }
+ end, i = true, i+1
+ }
+ j, e := eatTagName(s, i)
+ if j != i {
+ if end {
+ e = elementNone
+ }
+ // We've found an HTML tag.
+ return context{state: stateTag, element: e}, j
+ }
+ k = j
+ }
+}
+
+var elementContentType = [...]state{
+ elementNone: stateText,
+ elementScript: stateJS,
+ elementStyle: stateCSS,
+ elementTextarea: stateRCDATA,
+ elementTitle: stateRCDATA,
+}
+
+// tTag is the context transition function for the tag state.
+func tTag(c context, s []byte) (context, int) {
+ // Find the attribute name.
+ i := eatWhiteSpace(s, 0)
+ if i == len(s) {
+ return c, len(s)
+ }
+ if s[i] == '>' {
+ return context{
+ state: elementContentType[c.element],
+ element: c.element,
+ }, i + 1
+ }
+ j, err := eatAttrName(s, i)
+ if err != nil {
+ return context{state: stateError, err: err}, len(s)
+ }
+ state, attr := stateTag, attrNone
+ if i == j {
+ return context{
+ state: stateError,
+ err: errorf(ErrBadHTML, nil, 0, "expected space, attr name, or end of tag, but got %q", s[i:]),
+ }, len(s)
+ }
+
+ attrName := strings.ToLower(string(s[i:j]))
+ if c.element == elementScript && attrName == "type" {
+ attr = attrScriptType
+ } else {
+ switch attrType(attrName) {
+ case contentTypeURL:
+ attr = attrURL
+ case contentTypeCSS:
+ attr = attrStyle
+ case contentTypeJS:
+ attr = attrScript
+ case contentTypeSrcset:
+ attr = attrSrcset
+ }
+ }
+
+ if j == len(s) {
+ state = stateAttrName
+ } else {
+ state = stateAfterName
+ }
+ return context{state: state, element: c.element, attr: attr}, j
+}
+
+// tAttrName is the context transition function for stateAttrName.
+func tAttrName(c context, s []byte) (context, int) {
+ i, err := eatAttrName(s, 0)
+ if err != nil {
+ return context{state: stateError, err: err}, len(s)
+ } else if i != len(s) {
+ c.state = stateAfterName
+ }
+ return c, i
+}
+
+// tAfterName is the context transition function for stateAfterName.
+func tAfterName(c context, s []byte) (context, int) {
+ // Look for the start of the value.
+ i := eatWhiteSpace(s, 0)
+ if i == len(s) {
+ return c, len(s)
+ } else if s[i] != '=' {
+ // Occurs due to tag ending '>', and valueless attribute.
+ c.state = stateTag
+ return c, i
+ }
+ c.state = stateBeforeValue
+ // Consume the "=".
+ return c, i + 1
+}
+
+var attrStartStates = [...]state{
+ attrNone: stateAttr,
+ attrScript: stateJS,
+ attrScriptType: stateAttr,
+ attrStyle: stateCSS,
+ attrURL: stateURL,
+ attrSrcset: stateSrcset,
+}
+
+// tBeforeValue is the context transition function for stateBeforeValue.
+func tBeforeValue(c context, s []byte) (context, int) {
+ i := eatWhiteSpace(s, 0)
+ if i == len(s) {
+ return c, len(s)
+ }
+ // Find the attribute delimiter.
+ delim := delimSpaceOrTagEnd
+ switch s[i] {
+ case '\'':
+ delim, i = delimSingleQuote, i+1
+ case '"':
+ delim, i = delimDoubleQuote, i+1
+ }
+ c.state, c.delim = attrStartStates[c.attr], delim
+ return c, i
+}
+
+// tHTMLCmt is the context transition function for stateHTMLCmt.
+func tHTMLCmt(c context, s []byte) (context, int) {
+ if i := bytes.Index(s, commentEnd); i != -1 {
+ return context{}, i + 3
+ }
+ return c, len(s)
+}
+
+// specialTagEndMarkers maps element types to the character sequence that
+// case-insensitively signals the end of the special tag body.
+var specialTagEndMarkers = [...][]byte{
+ elementScript: []byte("script"),
+ elementStyle: []byte("style"),
+ elementTextarea: []byte("textarea"),
+ elementTitle: []byte("title"),
+}
+
+var (
+ specialTagEndPrefix = []byte("</")
+ tagEndSeparators = []byte("> \t\n\f/")
+)
+
+// tSpecialTagEnd is the context transition function for raw text and RCDATA
+// element states.
+func tSpecialTagEnd(c context, s []byte) (context, int) {
+ if c.element != elementNone {
+ // script end tags ("</script") within script literals are ignored, so that
+ // we can properly escape them.
+ if c.element == elementScript && (isInScriptLiteral(c.state) || isComment(c.state)) {
+ return c, len(s)
+ }
+ if i := indexTagEnd(s, specialTagEndMarkers[c.element]); i != -1 {
+ return context{}, i
+ }
+ }
+ return c, len(s)
+}
+
+// indexTagEnd finds the index of a special tag end in a case insensitive way, or returns -1
+func indexTagEnd(s []byte, tag []byte) int {
+ res := 0
+ plen := len(specialTagEndPrefix)
+ for len(s) > 0 {
+ // Try to find the tag end prefix first
+ i := bytes.Index(s, specialTagEndPrefix)
+ if i == -1 {
+ return i
+ }
+ s = s[i+plen:]
+ // Try to match the actual tag if there is still space for it
+ if len(tag) <= len(s) && bytes.EqualFold(tag, s[:len(tag)]) {
+ s = s[len(tag):]
+ // Check the tag is followed by a proper separator
+ if len(s) > 0 && bytes.IndexByte(tagEndSeparators, s[0]) != -1 {
+ return res + i
+ }
+ res += len(tag)
+ }
+ res += i + plen
+ }
+ return -1
+}
+
+// tAttr is the context transition function for the attribute state.
+func tAttr(c context, s []byte) (context, int) {
+ return c, len(s)
+}
+
+// tURL is the context transition function for the URL state.
+func tURL(c context, s []byte) (context, int) {
+ if bytes.ContainsAny(s, "#?") {
+ c.urlPart = urlPartQueryOrFrag
+ } else if len(s) != eatWhiteSpace(s, 0) && c.urlPart == urlPartNone {
+ // HTML5 uses "Valid URL potentially surrounded by spaces" for
+ // attrs: https://www.w3.org/TR/html5/index.html#attributes-1
+ c.urlPart = urlPartPreQuery
+ }
+ return c, len(s)
+}
+
+// tJS is the context transition function for the JS state.
+func tJS(c context, s []byte) (context, int) {
+ i := bytes.IndexAny(s, "\"`'/<-#")
+ if i == -1 {
+ // Entire input is non string, comment, regexp tokens.
+ c.jsCtx = nextJSCtx(s, c.jsCtx)
+ return c, len(s)
+ }
+ c.jsCtx = nextJSCtx(s[:i], c.jsCtx)
+ switch s[i] {
+ case '"':
+ c.state, c.jsCtx = stateJSDqStr, jsCtxRegexp
+ case '\'':
+ c.state, c.jsCtx = stateJSSqStr, jsCtxRegexp
+ case '`':
+ c.state, c.jsCtx = stateJSBqStr, jsCtxRegexp
+ case '/':
+ switch {
+ case i+1 < len(s) && s[i+1] == '/':
+ c.state, i = stateJSLineCmt, i+1
+ case i+1 < len(s) && s[i+1] == '*':
+ c.state, i = stateJSBlockCmt, i+1
+ case c.jsCtx == jsCtxRegexp:
+ c.state = stateJSRegexp
+ case c.jsCtx == jsCtxDivOp:
+ c.jsCtx = jsCtxRegexp
+ default:
+ return context{
+ state: stateError,
+ err: errorf(ErrSlashAmbig, nil, 0, "'/' could start a division or regexp: %.32q", s[i:]),
+ }, len(s)
+ }
+ // ECMAScript supports HTML style comments for legacy reasons, see Appendix
+ // B.1.1 "HTML-like Comments". The handling of these comments is somewhat
+ // confusing. Multi-line comments are not supported, i.e. anything on lines
+ // between the opening and closing tokens is not considered a comment, but
+ // anything following the opening or closing token, on the same line, is
+ // ignored. As such we simply treat any line prefixed with "<!--" or "-->"
+ // as if it were actually prefixed with "//" and move on.
+ case '<':
+ if i+3 < len(s) && bytes.Equal(commentStart, s[i:i+4]) {
+ c.state, i = stateJSHTMLOpenCmt, i+3
+ }
+ case '-':
+ if i+2 < len(s) && bytes.Equal(commentEnd, s[i:i+3]) {
+ c.state, i = stateJSHTMLCloseCmt, i+2
+ }
+ // ECMAScript also supports "hashbang" comment lines, see Section 12.5.
+ case '#':
+ if i+1 < len(s) && s[i+1] == '!' {
+ c.state, i = stateJSLineCmt, i+1
+ }
+ default:
+ panic("unreachable")
+ }
+ return c, i + 1
+}
+
+// tJSDelimited is the context transition function for the JS string and regexp
+// states.
+func tJSDelimited(c context, s []byte) (context, int) {
+ specials := `\"`
+ switch c.state {
+ case stateJSSqStr:
+ specials = `\'`
+ case stateJSBqStr:
+ specials = "`\\"
+ case stateJSRegexp:
+ specials = `\/[]`
+ }
+
+ k, inCharset := 0, false
+ for {
+ i := k + bytes.IndexAny(s[k:], specials)
+ if i < k {
+ break
+ }
+ switch s[i] {
+ case '\\':
+ i++
+ if i == len(s) {
+ return context{
+ state: stateError,
+ err: errorf(ErrPartialEscape, nil, 0, "unfinished escape sequence in JS string: %q", s),
+ }, len(s)
+ }
+ case '[':
+ inCharset = true
+ case ']':
+ inCharset = false
+ case '/':
+ // If "</script" appears in a regex literal, the '/' should not
+ // close the regex literal, and it will later be escaped to
+ // "\x3C/script" in escapeText.
+ if i > 0 && i+7 <= len(s) && bytes.Compare(bytes.ToLower(s[i-1:i+7]), []byte("</script")) == 0 {
+ i++
+ } else if !inCharset {
+ c.state, c.jsCtx = stateJS, jsCtxDivOp
+ return c, i + 1
+ }
+ default:
+ // end delimiter
+ if !inCharset {
+ c.state, c.jsCtx = stateJS, jsCtxDivOp
+ return c, i + 1
+ }
+ }
+ k = i + 1
+ }
+
+ if inCharset {
+ // This can be fixed by making context richer if interpolation
+ // into charsets is desired.
+ return context{
+ state: stateError,
+ err: errorf(ErrPartialCharset, nil, 0, "unfinished JS regexp charset: %q", s),
+ }, len(s)
+ }
+
+ return c, len(s)
+}
+
+var blockCommentEnd = []byte("*/")
+
+// tBlockCmt is the context transition function for /*comment*/ states.
+func tBlockCmt(c context, s []byte) (context, int) {
+ i := bytes.Index(s, blockCommentEnd)
+ if i == -1 {
+ return c, len(s)
+ }
+ switch c.state {
+ case stateJSBlockCmt:
+ c.state = stateJS
+ case stateCSSBlockCmt:
+ c.state = stateCSS
+ default:
+ panic(c.state.String())
+ }
+ return c, i + 2
+}
+
+// tLineCmt is the context transition function for //comment states, and the JS HTML-like comment state.
+func tLineCmt(c context, s []byte) (context, int) {
+ var lineTerminators string
+ var endState state
+ switch c.state {
+ case stateJSLineCmt, stateJSHTMLOpenCmt, stateJSHTMLCloseCmt:
+ lineTerminators, endState = "\n\r\u2028\u2029", stateJS
+ case stateCSSLineCmt:
+ lineTerminators, endState = "\n\f\r", stateCSS
+ // Line comments are not part of any published CSS standard but
+ // are supported by the 4 major browsers.
+ // This defines line comments as
+ // LINECOMMENT ::= "//" [^\n\f\d]*
+ // since https://www.w3.org/TR/css3-syntax/#SUBTOK-nl defines
+ // newlines:
+ // nl ::= #xA | #xD #xA | #xD | #xC
+ default:
+ panic(c.state.String())
+ }
+
+ i := bytes.IndexAny(s, lineTerminators)
+ if i == -1 {
+ return c, len(s)
+ }
+ c.state = endState
+ // Per section 7.4 of EcmaScript 5 : https://es5.github.io/#x7.4
+ // "However, the LineTerminator at the end of the line is not
+ // considered to be part of the single-line comment; it is
+ // recognized separately by the lexical grammar and becomes part
+ // of the stream of input elements for the syntactic grammar."
+ return c, i
+}
+
+// tCSS is the context transition function for the CSS state.
+func tCSS(c context, s []byte) (context, int) {
+ // CSS quoted strings are almost never used except for:
+ // (1) URLs as in background: "/foo.png"
+ // (2) Multiword font-names as in font-family: "Times New Roman"
+ // (3) List separators in content values as in inline-lists:
+ // <style>
+ // ul.inlineList { list-style: none; padding:0 }
+ // ul.inlineList > li { display: inline }
+ // ul.inlineList > li:before { content: ", " }
+ // ul.inlineList > li:first-child:before { content: "" }
+ // </style>
+ // <ul class=inlineList><li>One<li>Two<li>Three</ul>
+ // (4) Attribute value selectors as in a[href="http://example.com/"]
+ //
+ // We conservatively treat all strings as URLs, but make some
+ // allowances to avoid confusion.
+ //
+ // In (1), our conservative assumption is justified.
+ // In (2), valid font names do not contain ':', '?', or '#', so our
+ // conservative assumption is fine since we will never transition past
+ // urlPartPreQuery.
+ // In (3), our protocol heuristic should not be tripped, and there
+ // should not be non-space content after a '?' or '#', so as long as
+ // we only %-encode RFC 3986 reserved characters we are ok.
+ // In (4), we should URL escape for URL attributes, and for others we
+ // have the attribute name available if our conservative assumption
+ // proves problematic for real code.
+
+ k := 0
+ for {
+ i := k + bytes.IndexAny(s[k:], `("'/`)
+ if i < k {
+ return c, len(s)
+ }
+ switch s[i] {
+ case '(':
+ // Look for url to the left.
+ p := bytes.TrimRight(s[:i], "\t\n\f\r ")
+ if endsWithCSSKeyword(p, "url") {
+ j := len(s) - len(bytes.TrimLeft(s[i+1:], "\t\n\f\r "))
+ switch {
+ case j != len(s) && s[j] == '"':
+ c.state, j = stateCSSDqURL, j+1
+ case j != len(s) && s[j] == '\'':
+ c.state, j = stateCSSSqURL, j+1
+ default:
+ c.state = stateCSSURL
+ }
+ return c, j
+ }
+ case '/':
+ if i+1 < len(s) {
+ switch s[i+1] {
+ case '/':
+ c.state = stateCSSLineCmt
+ return c, i + 2
+ case '*':
+ c.state = stateCSSBlockCmt
+ return c, i + 2
+ }
+ }
+ case '"':
+ c.state = stateCSSDqStr
+ return c, i + 1
+ case '\'':
+ c.state = stateCSSSqStr
+ return c, i + 1
+ }
+ k = i + 1
+ }
+}
+
+// tCSSStr is the context transition function for the CSS string and URL states.
+func tCSSStr(c context, s []byte) (context, int) {
+ var endAndEsc string
+ switch c.state {
+ case stateCSSDqStr, stateCSSDqURL:
+ endAndEsc = `\"`
+ case stateCSSSqStr, stateCSSSqURL:
+ endAndEsc = `\'`
+ case stateCSSURL:
+ // Unquoted URLs end with a newline or close parenthesis.
+ // The below includes the wc (whitespace character) and nl.
+ endAndEsc = "\\\t\n\f\r )"
+ default:
+ panic(c.state.String())
+ }
+
+ k := 0
+ for {
+ i := k + bytes.IndexAny(s[k:], endAndEsc)
+ if i < k {
+ c, nread := tURL(c, decodeCSS(s[k:]))
+ return c, k + nread
+ }
+ if s[i] == '\\' {
+ i++
+ if i == len(s) {
+ return context{
+ state: stateError,
+ err: errorf(ErrPartialEscape, nil, 0, "unfinished escape sequence in CSS string: %q", s),
+ }, len(s)
+ }
+ } else {
+ c.state = stateCSS
+ return c, i + 1
+ }
+ c, _ = tURL(c, decodeCSS(s[:i+1]))
+ k = i + 1
+ }
+}
+
+// tError is the context transition function for the error state.
+func tError(c context, s []byte) (context, int) {
+ return c, len(s)
+}
+
+// eatAttrName returns the largest j such that s[i:j] is an attribute name.
+// It returns an error if s[i:] does not look like it begins with an
+// attribute name, such as encountering a quote mark without a preceding
+// equals sign.
+func eatAttrName(s []byte, i int) (int, *Error) {
+ for j := i; j < len(s); j++ {
+ switch s[j] {
+ case ' ', '\t', '\n', '\f', '\r', '=', '>':
+ return j, nil
+ case '\'', '"', '<':
+ // These result in a parse warning in HTML5 and are
+ // indicative of serious problems if seen in an attr
+ // name in a template.
+ return -1, errorf(ErrBadHTML, nil, 0, "%q in attribute name: %.32q", s[j:j+1], s)
+ default:
+ // No-op.
+ }
+ }
+ return len(s), nil
+}
+
+var elementNameMap = map[string]element{
+ "script": elementScript,
+ "style": elementStyle,
+ "textarea": elementTextarea,
+ "title": elementTitle,
+}
+
+// asciiAlpha reports whether c is an ASCII letter.
+func asciiAlpha(c byte) bool {
+ return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
+}
+
+// asciiAlphaNum reports whether c is an ASCII letter or digit.
+func asciiAlphaNum(c byte) bool {
+ return asciiAlpha(c) || '0' <= c && c <= '9'
+}
+
+// eatTagName returns the largest j such that s[i:j] is a tag name and the tag type.
+func eatTagName(s []byte, i int) (int, element) {
+ if i == len(s) || !asciiAlpha(s[i]) {
+ return i, elementNone
+ }
+ j := i + 1
+ for j < len(s) {
+ x := s[j]
+ if asciiAlphaNum(x) {
+ j++
+ continue
+ }
+ // Allow "x-y" or "x:y" but not "x-", "-y", or "x--y".
+ if (x == ':' || x == '-') && j+1 < len(s) && asciiAlphaNum(s[j+1]) {
+ j += 2
+ continue
+ }
+ break
+ }
+ return j, elementNameMap[strings.ToLower(string(s[i:j]))]
+}
+
+// eatWhiteSpace returns the largest j such that s[i:j] is white space.
+func eatWhiteSpace(s []byte, i int) int {
+ for j := i; j < len(s); j++ {
+ switch s[j] {
+ case ' ', '\t', '\n', '\f', '\r':
+ // No-op.
+ default:
+ return j
+ }
+ }
+ return len(s)
+}
diff --git a/contrib/go/_std_1.20/src/html/template/url.go b/contrib/go/_std_1.21/src/html/template/url.go
index 7820561dc0..7820561dc0 100644
--- a/contrib/go/_std_1.20/src/html/template/url.go
+++ b/contrib/go/_std_1.21/src/html/template/url.go
diff --git a/contrib/go/_std_1.21/src/html/template/urlpart_string.go b/contrib/go/_std_1.21/src/html/template/urlpart_string.go
new file mode 100644
index 0000000000..7bc957e81d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/html/template/urlpart_string.go
@@ -0,0 +1,26 @@
+// Code generated by "stringer -type urlPart"; DO NOT EDIT.
+
+package template
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[urlPartNone-0]
+ _ = x[urlPartPreQuery-1]
+ _ = x[urlPartQueryOrFrag-2]
+ _ = x[urlPartUnknown-3]
+}
+
+const _urlPart_name = "urlPartNoneurlPartPreQueryurlPartQueryOrFragurlPartUnknown"
+
+var _urlPart_index = [...]uint8{0, 11, 26, 44, 58}
+
+func (i urlPart) String() string {
+ if i >= urlPart(len(_urlPart_index)-1) {
+ return "urlPart(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _urlPart_name[_urlPart_index[i]:_urlPart_index[i+1]]
+}
diff --git a/contrib/go/_std_1.21/src/html/template/ya.make b/contrib/go/_std_1.21/src/html/template/ya.make
new file mode 100644
index 0000000000..c36aa473fb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/html/template/ya.make
@@ -0,0 +1,46 @@
+GO_LIBRARY()
+
+SRCS(
+ attr.go
+ attr_string.go
+ content.go
+ context.go
+ css.go
+ delim_string.go
+ doc.go
+ element_string.go
+ error.go
+ escape.go
+ html.go
+ js.go
+ jsctx_string.go
+ state_string.go
+ template.go
+ transition.go
+ url.go
+ urlpart_string.go
+)
+
+GO_TEST_SRCS(
+ clone_test.go
+ content_test.go
+ css_test.go
+ escape_test.go
+ exec_test.go
+ html_test.go
+ js_test.go
+ multi_test.go
+ transition_test.go
+ url_test.go
+)
+
+GO_XTEST_SRCS(
+ example_test.go
+ examplefiles_test.go
+ template_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/html/ya.make b/contrib/go/_std_1.21/src/html/ya.make
new file mode 100644
index 0000000000..8615ae33dc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/html/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ entity.go
+ escape.go
+)
+
+GO_TEST_SRCS(
+ entity_test.go
+ escape_test.go
+ fuzz_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+ template
+)
diff --git a/contrib/go/_std_1.20/src/image/color/color.go b/contrib/go/_std_1.21/src/image/color/color.go
index 8895839140..8895839140 100644
--- a/contrib/go/_std_1.20/src/image/color/color.go
+++ b/contrib/go/_std_1.21/src/image/color/color.go
diff --git a/contrib/go/_std_1.21/src/image/color/ya.make b/contrib/go/_std_1.21/src/image/color/ya.make
new file mode 100644
index 0000000000..0a5a4dab7d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/image/color/ya.make
@@ -0,0 +1,17 @@
+GO_LIBRARY()
+
+SRCS(
+ color.go
+ ycbcr.go
+)
+
+GO_TEST_SRCS(
+ color_test.go
+ ycbcr_test.go
+)
+
+END()
+
+RECURSE(
+ palette
+)
diff --git a/contrib/go/_std_1.20/src/image/color/ycbcr.go b/contrib/go/_std_1.21/src/image/color/ycbcr.go
index 8b6d508588..8b6d508588 100644
--- a/contrib/go/_std_1.20/src/image/color/ycbcr.go
+++ b/contrib/go/_std_1.21/src/image/color/ycbcr.go
diff --git a/contrib/go/_std_1.20/src/image/format.go b/contrib/go/_std_1.21/src/image/format.go
index 51d7ad9021..51d7ad9021 100644
--- a/contrib/go/_std_1.20/src/image/format.go
+++ b/contrib/go/_std_1.21/src/image/format.go
diff --git a/contrib/go/_std_1.20/src/image/geom.go b/contrib/go/_std_1.21/src/image/geom.go
index e71aa61187..e71aa61187 100644
--- a/contrib/go/_std_1.20/src/image/geom.go
+++ b/contrib/go/_std_1.21/src/image/geom.go
diff --git a/contrib/go/_std_1.20/src/image/image.go b/contrib/go/_std_1.21/src/image/image.go
index dfb70d4eaf..dfb70d4eaf 100644
--- a/contrib/go/_std_1.20/src/image/image.go
+++ b/contrib/go/_std_1.21/src/image/image.go
diff --git a/contrib/go/_std_1.20/src/image/names.go b/contrib/go/_std_1.21/src/image/names.go
index 17b06588ac..17b06588ac 100644
--- a/contrib/go/_std_1.20/src/image/names.go
+++ b/contrib/go/_std_1.21/src/image/names.go
diff --git a/contrib/go/_std_1.21/src/image/ya.make b/contrib/go/_std_1.21/src/image/ya.make
new file mode 100644
index 0000000000..b74f64f96a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/image/ya.make
@@ -0,0 +1,31 @@
+GO_LIBRARY()
+
+SRCS(
+ format.go
+ geom.go
+ image.go
+ names.go
+ ycbcr.go
+)
+
+GO_TEST_SRCS(
+ geom_test.go
+ image_test.go
+ ycbcr_test.go
+)
+
+GO_XTEST_SRCS(
+ decode_example_test.go
+ decode_test.go
+)
+
+END()
+
+RECURSE(
+ color
+ draw
+ gif
+ internal
+ jpeg
+ png
+)
diff --git a/contrib/go/_std_1.20/src/image/ycbcr.go b/contrib/go/_std_1.21/src/image/ycbcr.go
index 78f5ebe1d8..78f5ebe1d8 100644
--- a/contrib/go/_std_1.20/src/image/ycbcr.go
+++ b/contrib/go/_std_1.21/src/image/ycbcr.go
diff --git a/contrib/go/_std_1.21/src/internal/abi/abi.go b/contrib/go/_std_1.21/src/internal/abi/abi.go
new file mode 100644
index 0000000000..e1c8adccc7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/abi/abi.go
@@ -0,0 +1,102 @@
+// 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 abi
+
+import (
+ "internal/goarch"
+ "unsafe"
+)
+
+// RegArgs is a struct that has space for each argument
+// and return value register on the current architecture.
+//
+// Assembly code knows the layout of the first two fields
+// of RegArgs.
+//
+// RegArgs also contains additional space to hold pointers
+// when it may not be safe to keep them only in the integer
+// register space otherwise.
+type RegArgs struct {
+ // Values in these slots should be precisely the bit-by-bit
+ // representation of how they would appear in a register.
+ //
+ // This means that on big endian arches, integer values should
+ // be in the top bits of the slot. Floats are usually just
+ // directly represented, but some architectures treat narrow
+ // width floating point values specially (e.g. they're promoted
+ // first, or they need to be NaN-boxed).
+ Ints [IntArgRegs]uintptr // untyped integer registers
+ Floats [FloatArgRegs]uint64 // untyped float registers
+
+ // Fields above this point are known to assembly.
+
+ // Ptrs is a space that duplicates Ints but with pointer type,
+ // used to make pointers passed or returned in registers
+ // visible to the GC by making the type unsafe.Pointer.
+ Ptrs [IntArgRegs]unsafe.Pointer
+
+ // ReturnIsPtr is a bitmap that indicates which registers
+ // contain or will contain pointers on the return path from
+ // a reflectcall. The i'th bit indicates whether the i'th
+ // register contains or will contain a valid Go pointer.
+ ReturnIsPtr IntArgRegBitmap
+}
+
+func (r *RegArgs) Dump() {
+ print("Ints:")
+ for _, x := range r.Ints {
+ print(" ", x)
+ }
+ println()
+ print("Floats:")
+ for _, x := range r.Floats {
+ print(" ", x)
+ }
+ println()
+ print("Ptrs:")
+ for _, x := range r.Ptrs {
+ print(" ", x)
+ }
+ println()
+}
+
+// IntRegArgAddr returns a pointer inside of r.Ints[reg] that is appropriately
+// offset for an argument of size argSize.
+//
+// argSize must be non-zero, fit in a register, and a power-of-two.
+//
+// This method is a helper for dealing with the endianness of different CPU
+// architectures, since sub-word-sized arguments in big endian architectures
+// need to be "aligned" to the upper edge of the register to be interpreted
+// by the CPU correctly.
+func (r *RegArgs) IntRegArgAddr(reg int, argSize uintptr) unsafe.Pointer {
+ if argSize > goarch.PtrSize || argSize == 0 || argSize&(argSize-1) != 0 {
+ panic("invalid argSize")
+ }
+ offset := uintptr(0)
+ if goarch.BigEndian {
+ offset = goarch.PtrSize - argSize
+ }
+ return unsafe.Pointer(uintptr(unsafe.Pointer(&r.Ints[reg])) + offset)
+}
+
+// IntArgRegBitmap is a bitmap large enough to hold one bit per
+// integer argument/return register.
+type IntArgRegBitmap [(IntArgRegs + 7) / 8]uint8
+
+// Set sets the i'th bit of the bitmap to 1.
+func (b *IntArgRegBitmap) Set(i int) {
+ b[i/8] |= uint8(1) << (i % 8)
+}
+
+// Get returns whether the i'th bit of the bitmap is set.
+//
+// nosplit because it's called in extremely sensitive contexts, like
+// on the reflectcall return path.
+//
+//go:nosplit
+func (b *IntArgRegBitmap) Get(i int) bool {
+ return b[i/8]&(uint8(1)<<(i%8)) != 0
+}
diff --git a/contrib/go/_std_1.20/src/internal/abi/abi_amd64.go b/contrib/go/_std_1.21/src/internal/abi/abi_amd64.go
index d3c5678223..d3c5678223 100644
--- a/contrib/go/_std_1.20/src/internal/abi/abi_amd64.go
+++ b/contrib/go/_std_1.21/src/internal/abi/abi_amd64.go
diff --git a/contrib/go/_std_1.20/src/internal/abi/abi_arm64.go b/contrib/go/_std_1.21/src/internal/abi/abi_arm64.go
index 4dc51431bf..4dc51431bf 100644
--- a/contrib/go/_std_1.20/src/internal/abi/abi_arm64.go
+++ b/contrib/go/_std_1.21/src/internal/abi/abi_arm64.go
diff --git a/contrib/go/_std_1.20/src/internal/abi/abi_test.s b/contrib/go/_std_1.21/src/internal/abi/abi_test.s
index 93ace3ef48..93ace3ef48 100644
--- a/contrib/go/_std_1.20/src/internal/abi/abi_test.s
+++ b/contrib/go/_std_1.21/src/internal/abi/abi_test.s
diff --git a/contrib/go/_std_1.21/src/internal/abi/compiletype.go b/contrib/go/_std_1.21/src/internal/abi/compiletype.go
new file mode 100644
index 0000000000..d92addec25
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/abi/compiletype.go
@@ -0,0 +1,167 @@
+// Copyright 2023 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 abi
+
+// These functions are the build-time version of the Go type data structures.
+
+// Their contents must be kept in sync with their definitions.
+// Because the host and target type sizes can differ, the compiler and
+// linker cannot use the host information that they might get from
+// either unsafe.Sizeof and Alignof, nor runtime, reflect, or reflectlite.
+
+// CommonSize returns sizeof(Type) for a compilation target with a given ptrSize
+func CommonSize(ptrSize int) int { return 4*ptrSize + 8 + 8 }
+
+// StructFieldSize returns sizeof(StructField) for a compilation target with a given ptrSize
+func StructFieldSize(ptrSize int) int { return 3 * ptrSize }
+
+// UncommonSize returns sizeof(UncommonType). This currently does not depend on ptrSize.
+// This exported function is in an internal package, so it may change to depend on ptrSize in the future.
+func UncommonSize() uint64 { return 4 + 2 + 2 + 4 + 4 }
+
+// IMethodSize returns sizeof(IMethod) for a compilation target with a given ptrSize
+func IMethodSize(ptrSize int) int { return 4 + 4 }
+
+// KindOff returns the offset of Type.Kind_ for a compilation target with a given ptrSize
+func KindOff(ptrSize int) int { return 2*ptrSize + 7 }
+
+// SizeOff returns the offset of Type.Size_ for a compilation target with a given ptrSize
+func SizeOff(ptrSize int) int { return 0 }
+
+// PtrBytes returns the offset of Type.PtrBytes for a compilation target with a given ptrSize
+func PtrBytesOff(ptrSize int) int { return ptrSize }
+
+// TFlagOff returns the offset of Type.TFlag for a compilation target with a given ptrSize
+func TFlagOff(ptrSize int) int { return 2*ptrSize + 4 }
+
+// Offset is for computing offsets of type data structures at compile/link time;
+// the target platform may not be the host platform. Its state includes the
+// current offset, necessary alignment for the sequence of types, and the size
+// of pointers and alignment of slices, interfaces, and strings (this is for tearing-
+// resistant access to these types, if/when that is supported).
+type Offset struct {
+ off uint64 // the current offset
+ align uint8 // the required alignmentof the container
+ ptrSize uint8 // the size of a pointer in bytes
+ sliceAlign uint8 // the alignment of slices (and interfaces and strings)
+}
+
+// NewOffset returns a new Offset with offset 0 and alignment 1.
+func NewOffset(ptrSize uint8, twoWordAlignSlices bool) Offset {
+ if twoWordAlignSlices {
+ return Offset{off: 0, align: 1, ptrSize: ptrSize, sliceAlign: 2 * ptrSize}
+ }
+ return Offset{off: 0, align: 1, ptrSize: ptrSize, sliceAlign: ptrSize}
+}
+
+func assertIsAPowerOfTwo(x uint8) {
+ if x == 0 {
+ panic("Zero is not a power of two")
+ }
+ if x&-x == x {
+ return
+ }
+ panic("Not a power of two")
+}
+
+// InitializedOffset returns a new Offset with specified offset, alignment, pointer size, and slice alignment.
+func InitializedOffset(off int, align uint8, ptrSize uint8, twoWordAlignSlices bool) Offset {
+ assertIsAPowerOfTwo(align)
+ o0 := NewOffset(ptrSize, twoWordAlignSlices)
+ o0.off = uint64(off)
+ o0.align = align
+ return o0
+}
+
+func (o Offset) align_(a uint8) Offset {
+ o.off = (o.off + uint64(a) - 1) & ^(uint64(a) - 1)
+ if o.align < a {
+ o.align = a
+ }
+ return o
+}
+
+// Align returns the offset obtained by aligning offset to a multiple of a.
+// a must be a power of two.
+func (o Offset) Align(a uint8) Offset {
+ assertIsAPowerOfTwo(a)
+ return o.align_(a)
+}
+
+// plus returns the offset obtained by appending a power-of-2-sized-and-aligned object to o.
+func (o Offset) plus(x uint64) Offset {
+ o = o.align_(uint8(x))
+ o.off += x
+ return o
+}
+
+// D8 returns the offset obtained by appending an 8-bit field to o.
+func (o Offset) D8() Offset {
+ return o.plus(1)
+}
+
+// D16 returns the offset obtained by appending a 16-bit field to o.
+func (o Offset) D16() Offset {
+ return o.plus(2)
+}
+
+// D32 returns the offset obtained by appending a 32-bit field to o.
+func (o Offset) D32() Offset {
+ return o.plus(4)
+}
+
+// D64 returns the offset obtained by appending a 64-bit field to o.
+func (o Offset) D64() Offset {
+ return o.plus(8)
+}
+
+// D64 returns the offset obtained by appending a pointer field to o.
+func (o Offset) P() Offset {
+ if o.ptrSize == 0 {
+ panic("This offset has no defined pointer size")
+ }
+ return o.plus(uint64(o.ptrSize))
+}
+
+// Slice returns the offset obtained by appending a slice field to o.
+func (o Offset) Slice() Offset {
+ o = o.align_(o.sliceAlign)
+ o.off += 3 * uint64(o.ptrSize)
+ // There's been discussion of whether slices should be 2-word aligned to allow
+ // use of aligned 2-word load/store to prevent tearing, this is future proofing.
+ // In general, for purposes of struct layout (and very likely default C layout
+ // compatibility) the "size" of a Go type is rounded up to its alignment.
+ return o.Align(o.sliceAlign)
+}
+
+// String returns the offset obtained by appending a string field to o.
+func (o Offset) String() Offset {
+ o = o.align_(o.sliceAlign)
+ o.off += 2 * uint64(o.ptrSize)
+ return o // We "know" it needs no further alignment
+}
+
+// Interface returns the offset obtained by appending an interface field to o.
+func (o Offset) Interface() Offset {
+ o = o.align_(o.sliceAlign)
+ o.off += 2 * uint64(o.ptrSize)
+ return o // We "know" it needs no further alignment
+}
+
+// Offset returns the struct-aligned offset (size) of o.
+// This is at least as large as the current internal offset; it may be larger.
+func (o Offset) Offset() uint64 {
+ return o.Align(o.align).off
+}
+
+func (o Offset) PlusUncommon() Offset {
+ o.off += UncommonSize()
+ return o
+}
+
+// CommonOffset returns the Offset to the data after the common portion of type data structures.
+func CommonOffset(ptrSize int, twoWordAlignSlices bool) Offset {
+ return InitializedOffset(CommonSize(ptrSize), uint8(ptrSize), uint8(ptrSize), twoWordAlignSlices)
+}
diff --git a/contrib/go/_std_1.21/src/internal/abi/funcpc.go b/contrib/go/_std_1.21/src/internal/abi/funcpc.go
new file mode 100644
index 0000000000..e038d36584
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/abi/funcpc.go
@@ -0,0 +1,31 @@
+// Copyright 2023 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.
+
+//go:build !gccgo
+
+package abi
+
+// FuncPC* intrinsics.
+//
+// CAREFUL: In programs with plugins, FuncPC* can return different values
+// for the same function (because there are actually multiple copies of
+// the same function in the address space). To be safe, don't use the
+// results of this function in any == expression. It is only safe to
+// use the result as an address at which to start executing code.
+
+// FuncPCABI0 returns the entry PC of the function f, which must be a
+// direct reference of a function defined as ABI0. Otherwise it is a
+// compile-time error.
+//
+// Implemented as a compile intrinsic.
+func FuncPCABI0(f interface{}) uintptr
+
+// FuncPCABIInternal returns the entry PC of the function f. If f is a
+// direct reference of a function, it must be defined as ABIInternal.
+// Otherwise it is a compile-time error. If f is not a direct reference
+// of a defined function, it assumes that f is a func value. Otherwise
+// the behavior is undefined.
+//
+// Implemented as a compile intrinsic.
+func FuncPCABIInternal(f interface{}) uintptr
diff --git a/contrib/go/_std_1.21/src/internal/abi/map.go b/contrib/go/_std_1.21/src/internal/abi/map.go
new file mode 100644
index 0000000000..e5b0a0bb6f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/abi/map.go
@@ -0,0 +1,14 @@
+// Copyright 2023 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 abi
+
+// Map constants common to several packages
+// runtime/runtime-gdb.py:MapTypePrinter contains its own copy
+const (
+ MapBucketCountBits = 3 // log2 of number of elements in a bucket.
+ MapBucketCount = 1 << MapBucketCountBits
+ MapMaxKeyBytes = 128 // Must fit in a uint8.
+ MapMaxElemBytes = 128 // Must fit in a uint8.
+)
diff --git a/contrib/go/_std_1.21/src/internal/abi/stack.go b/contrib/go/_std_1.21/src/internal/abi/stack.go
new file mode 100644
index 0000000000..8e3327ee48
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/abi/stack.go
@@ -0,0 +1,33 @@
+// Copyright 2023 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 abi
+
+const (
+ // StackNosplitBase is the base maximum number of bytes that a chain of
+ // NOSPLIT functions can use.
+ //
+ // This value must be multiplied by the stack guard multiplier, so do not
+ // use it directly. See runtime/stack.go:stackNosplit and
+ // cmd/internal/objabi/stack.go:StackNosplit.
+ StackNosplitBase = 800
+
+ // We have three different sequences for stack bounds checks, depending on
+ // whether the stack frame of a function is small, big, or huge.
+
+ // After a stack split check the SP is allowed to be StackSmall bytes below
+ // the stack guard.
+ //
+ // Functions that need frames <= StackSmall can perform the stack check
+ // using a single comparison directly between the stack guard and the SP
+ // because we ensure that StackSmall bytes of stack space are available
+ // beyond the stack guard.
+ StackSmall = 128
+
+ // Functions that need frames <= StackBig can assume that neither
+ // SP-framesize nor stackGuard-StackSmall will underflow, and thus use a
+ // more efficient check. In order to ensure this, StackBig must be <= the
+ // size of the unmapped space at zero.
+ StackBig = 4096
+)
diff --git a/contrib/go/_std_1.21/src/internal/abi/stub.s b/contrib/go/_std_1.21/src/internal/abi/stub.s
new file mode 100644
index 0000000000..5bad98d744
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/abi/stub.s
@@ -0,0 +1,7 @@
+// Copyright 2023 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.
+
+// This file silences errors about body-less functions
+// that are provided by intrinsics in the latest version of the compiler,
+// but may not be known to the bootstrap compiler.
diff --git a/contrib/go/_std_1.21/src/internal/abi/symtab.go b/contrib/go/_std_1.21/src/internal/abi/symtab.go
new file mode 100644
index 0000000000..bf6ea82f1c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/abi/symtab.go
@@ -0,0 +1,106 @@
+// Copyright 2023 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 abi
+
+// A FuncFlag records bits about a function, passed to the runtime.
+type FuncFlag uint8
+
+const (
+ // FuncFlagTopFrame indicates a function that appears at the top of its stack.
+ // The traceback routine stop at such a function and consider that a
+ // successful, complete traversal of the stack.
+ // Examples of TopFrame functions include goexit, which appears
+ // at the top of a user goroutine stack, and mstart, which appears
+ // at the top of a system goroutine stack.
+ FuncFlagTopFrame FuncFlag = 1 << iota
+
+ // FuncFlagSPWrite indicates a function that writes an arbitrary value to SP
+ // (any write other than adding or subtracting a constant amount).
+ // The traceback routines cannot encode such changes into the
+ // pcsp tables, so the function traceback cannot safely unwind past
+ // SPWrite functions. Stopping at an SPWrite function is considered
+ // to be an incomplete unwinding of the stack. In certain contexts
+ // (in particular garbage collector stack scans) that is a fatal error.
+ FuncFlagSPWrite
+
+ // FuncFlagAsm indicates that a function was implemented in assembly.
+ FuncFlagAsm
+)
+
+// A FuncID identifies particular functions that need to be treated
+// specially by the runtime.
+// Note that in some situations involving plugins, there may be multiple
+// copies of a particular special runtime function.
+type FuncID uint8
+
+const (
+ // If you add a FuncID, you probably also want to add an entry to the map in
+ // ../../cmd/internal/objabi/funcid.go
+
+ FuncIDNormal FuncID = iota // not a special function
+ FuncID_abort
+ FuncID_asmcgocall
+ FuncID_asyncPreempt
+ FuncID_cgocallback
+ FuncID_debugCallV2
+ FuncID_gcBgMarkWorker
+ FuncID_goexit
+ FuncID_gogo
+ FuncID_gopanic
+ FuncID_handleAsyncEvent
+ FuncID_mcall
+ FuncID_morestack
+ FuncID_mstart
+ FuncID_panicwrap
+ FuncID_rt0_go
+ FuncID_runfinq
+ FuncID_runtime_main
+ FuncID_sigpanic
+ FuncID_systemstack
+ FuncID_systemstack_switch
+ FuncIDWrapper // any autogenerated code (hash/eq algorithms, method wrappers, etc.)
+)
+
+// ArgsSizeUnknown is set in Func.argsize to mark all functions
+// whose argument size is unknown (C vararg functions, and
+// assembly code without an explicit specification).
+// This value is generated by the compiler, assembler, or linker.
+const ArgsSizeUnknown = -0x80000000
+
+// IDs for PCDATA and FUNCDATA tables in Go binaries.
+//
+// These must agree with ../../../runtime/funcdata.h.
+const (
+ PCDATA_UnsafePoint = 0
+ PCDATA_StackMapIndex = 1
+ PCDATA_InlTreeIndex = 2
+ PCDATA_ArgLiveIndex = 3
+
+ FUNCDATA_ArgsPointerMaps = 0
+ FUNCDATA_LocalsPointerMaps = 1
+ FUNCDATA_StackObjects = 2
+ FUNCDATA_InlTree = 3
+ FUNCDATA_OpenCodedDeferInfo = 4
+ FUNCDATA_ArgInfo = 5
+ FUNCDATA_ArgLiveInfo = 6
+ FUNCDATA_WrapInfo = 7
+)
+
+// Special values for the PCDATA_UnsafePoint table.
+const (
+ UnsafePointSafe = -1 // Safe for async preemption
+ UnsafePointUnsafe = -2 // Unsafe for async preemption
+
+ // UnsafePointRestart1(2) apply on a sequence of instructions, within
+ // which if an async preemption happens, we should back off the PC
+ // to the start of the sequence when resuming.
+ // We need two so we can distinguish the start/end of the sequence
+ // in case that two sequences are next to each other.
+ UnsafePointRestart1 = -3
+ UnsafePointRestart2 = -4
+
+ // Like UnsafePointRestart1, but back to function entry if async preempted.
+ UnsafePointRestartAtEntry = -5
+)
diff --git a/contrib/go/_std_1.21/src/internal/abi/type.go b/contrib/go/_std_1.21/src/internal/abi/type.go
new file mode 100644
index 0000000000..4794f5a51e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/abi/type.go
@@ -0,0 +1,712 @@
+// Copyright 2023 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 abi
+
+import (
+ "unsafe"
+)
+
+// Type is the runtime representation of a Go type.
+//
+// Type is also referenced implicitly
+// (in the form of expressions involving constants and arch.PtrSize)
+// in cmd/compile/internal/reflectdata/reflect.go
+// and cmd/link/internal/ld/decodesym.go
+// (e.g. data[2*arch.PtrSize+4] references the TFlag field)
+// unsafe.OffsetOf(Type{}.TFlag) cannot be used directly in those
+// places because it varies with cross compilation and experiments.
+type Type struct {
+ Size_ uintptr
+ PtrBytes uintptr // number of (prefix) bytes in the type that can contain pointers
+ Hash uint32 // hash of type; avoids computation in hash tables
+ TFlag TFlag // extra type information flags
+ Align_ uint8 // alignment of variable with this type
+ FieldAlign_ uint8 // alignment of struct field with this type
+ Kind_ uint8 // enumeration for C
+ // function for comparing objects of this type
+ // (ptr to object A, ptr to object B) -> ==?
+ Equal func(unsafe.Pointer, unsafe.Pointer) bool
+ // GCData stores the GC type data for the garbage collector.
+ // If the KindGCProg bit is set in kind, GCData is a GC program.
+ // Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
+ GCData *byte
+ Str NameOff // string form
+ PtrToThis TypeOff // type for pointer to this type, may be zero
+}
+
+// A Kind represents the specific kind of type that a Type represents.
+// The zero Kind is not a valid kind.
+type Kind uint
+
+const (
+ Invalid Kind = iota
+ Bool
+ Int
+ Int8
+ Int16
+ Int32
+ Int64
+ Uint
+ Uint8
+ Uint16
+ Uint32
+ Uint64
+ Uintptr
+ Float32
+ Float64
+ Complex64
+ Complex128
+ Array
+ Chan
+ Func
+ Interface
+ Map
+ Pointer
+ Slice
+ String
+ Struct
+ UnsafePointer
+)
+
+const (
+ // TODO (khr, drchase) why aren't these in TFlag? Investigate, fix if possible.
+ KindDirectIface = 1 << 5
+ KindGCProg = 1 << 6 // Type.gc points to GC program
+ KindMask = (1 << 5) - 1
+)
+
+// TFlag is used by a Type to signal what extra type information is
+// available in the memory directly following the Type value.
+type TFlag uint8
+
+const (
+ // TFlagUncommon means that there is a data with a type, UncommonType,
+ // just beyond the shared-per-type common data. That is, the data
+ // for struct types will store their UncommonType at one offset, the
+ // data for interface types will store their UncommonType at a different
+ // offset. UncommonType is always accessed via a pointer that is computed
+ // using trust-us-we-are-the-implementors pointer arithmetic.
+ //
+ // For example, if t.Kind() == Struct and t.tflag&TFlagUncommon != 0,
+ // then t has UncommonType data and it can be accessed as:
+ //
+ // type structTypeUncommon struct {
+ // structType
+ // u UncommonType
+ // }
+ // u := &(*structTypeUncommon)(unsafe.Pointer(t)).u
+ TFlagUncommon TFlag = 1 << 0
+
+ // TFlagExtraStar means the name in the str field has an
+ // extraneous '*' prefix. This is because for most types T in
+ // a program, the type *T also exists and reusing the str data
+ // saves binary size.
+ TFlagExtraStar TFlag = 1 << 1
+
+ // TFlagNamed means the type has a name.
+ TFlagNamed TFlag = 1 << 2
+
+ // TFlagRegularMemory means that equal and hash functions can treat
+ // this type as a single region of t.size bytes.
+ TFlagRegularMemory TFlag = 1 << 3
+)
+
+// NameOff is the offset to a name from moduledata.types. See resolveNameOff in runtime.
+type NameOff int32
+
+// TypeOff is the offset to a type from moduledata.types. See resolveTypeOff in runtime.
+type TypeOff int32
+
+// TextOff is an offset from the top of a text section. See (rtype).textOff in runtime.
+type TextOff int32
+
+// String returns the name of k.
+func (k Kind) String() string {
+ if int(k) < len(kindNames) {
+ return kindNames[k]
+ }
+ return kindNames[0]
+}
+
+var kindNames = []string{
+ Invalid: "invalid",
+ Bool: "bool",
+ Int: "int",
+ Int8: "int8",
+ Int16: "int16",
+ Int32: "int32",
+ Int64: "int64",
+ Uint: "uint",
+ Uint8: "uint8",
+ Uint16: "uint16",
+ Uint32: "uint32",
+ Uint64: "uint64",
+ Uintptr: "uintptr",
+ Float32: "float32",
+ Float64: "float64",
+ Complex64: "complex64",
+ Complex128: "complex128",
+ Array: "array",
+ Chan: "chan",
+ Func: "func",
+ Interface: "interface",
+ Map: "map",
+ Pointer: "ptr",
+ Slice: "slice",
+ String: "string",
+ Struct: "struct",
+ UnsafePointer: "unsafe.Pointer",
+}
+
+func (t *Type) Kind() Kind { return Kind(t.Kind_ & KindMask) }
+
+func (t *Type) HasName() bool {
+ return t.TFlag&TFlagNamed != 0
+}
+
+func (t *Type) Pointers() bool { return t.PtrBytes != 0 }
+
+// IfaceIndir reports whether t is stored indirectly in an interface value.
+func (t *Type) IfaceIndir() bool {
+ return t.Kind_&KindDirectIface == 0
+}
+
+// isDirectIface reports whether t is stored directly in an interface value.
+func (t *Type) IsDirectIface() bool {
+ return t.Kind_&KindDirectIface != 0
+}
+
+func (t *Type) GcSlice(begin, end uintptr) []byte {
+ return unsafeSliceFor(t.GCData, int(end))[begin:]
+}
+
+// Method on non-interface type
+type Method struct {
+ Name NameOff // name of method
+ Mtyp TypeOff // method type (without receiver)
+ Ifn TextOff // fn used in interface call (one-word receiver)
+ Tfn TextOff // fn used for normal method call
+}
+
+// UncommonType is present only for defined types or types with methods
+// (if T is a defined type, the uncommonTypes for T and *T have methods).
+// Using a pointer to this struct reduces the overall size required
+// to describe a non-defined type with no methods.
+type UncommonType struct {
+ PkgPath NameOff // import path; empty for built-in types like int, string
+ Mcount uint16 // number of methods
+ Xcount uint16 // number of exported methods
+ Moff uint32 // offset from this uncommontype to [mcount]Method
+ _ uint32 // unused
+}
+
+func (t *UncommonType) Methods() []Method {
+ if t.Mcount == 0 {
+ return nil
+ }
+ return (*[1 << 16]Method)(addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.mcount > 0"))[:t.Mcount:t.Mcount]
+}
+
+func (t *UncommonType) ExportedMethods() []Method {
+ if t.Xcount == 0 {
+ return nil
+ }
+ return (*[1 << 16]Method)(addChecked(unsafe.Pointer(t), uintptr(t.Moff), "t.xcount > 0"))[:t.Xcount:t.Xcount]
+}
+
+// addChecked returns p+x.
+//
+// The whySafe string is ignored, so that the function still inlines
+// as efficiently as p+x, but all call sites should use the string to
+// record why the addition is safe, which is to say why the addition
+// does not cause x to advance to the very end of p's allocation
+// and therefore point incorrectly at the next block in memory.
+func addChecked(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
+ return unsafe.Pointer(uintptr(p) + x)
+}
+
+// Imethod represents a method on an interface type
+type Imethod struct {
+ Name NameOff // name of method
+ Typ TypeOff // .(*FuncType) underneath
+}
+
+// ArrayType represents a fixed array type.
+type ArrayType struct {
+ Type
+ Elem *Type // array element type
+ Slice *Type // slice type
+ Len uintptr
+}
+
+// Len returns the length of t if t is an array type, otherwise 0
+func (t *Type) Len() int {
+ if t.Kind() == Array {
+ return int((*ArrayType)(unsafe.Pointer(t)).Len)
+ }
+ return 0
+}
+
+func (t *Type) Common() *Type {
+ return t
+}
+
+type ChanDir int
+
+const (
+ RecvDir ChanDir = 1 << iota // <-chan
+ SendDir // chan<-
+ BothDir = RecvDir | SendDir // chan
+ InvalidDir ChanDir = 0
+)
+
+// ChanType represents a channel type
+type ChanType struct {
+ Type
+ Elem *Type
+ Dir ChanDir
+}
+
+type structTypeUncommon struct {
+ StructType
+ u UncommonType
+}
+
+// ChanDir returns the direction of t if t is a channel type, otherwise InvalidDir (0).
+func (t *Type) ChanDir() ChanDir {
+ if t.Kind() == Chan {
+ ch := (*ChanType)(unsafe.Pointer(t))
+ return ch.Dir
+ }
+ return InvalidDir
+}
+
+// Uncommon returns a pointer to T's "uncommon" data if there is any, otherwise nil
+func (t *Type) Uncommon() *UncommonType {
+ if t.TFlag&TFlagUncommon == 0 {
+ return nil
+ }
+ switch t.Kind() {
+ case Struct:
+ return &(*structTypeUncommon)(unsafe.Pointer(t)).u
+ case Pointer:
+ type u struct {
+ PtrType
+ u UncommonType
+ }
+ return &(*u)(unsafe.Pointer(t)).u
+ case Func:
+ type u struct {
+ FuncType
+ u UncommonType
+ }
+ return &(*u)(unsafe.Pointer(t)).u
+ case Slice:
+ type u struct {
+ SliceType
+ u UncommonType
+ }
+ return &(*u)(unsafe.Pointer(t)).u
+ case Array:
+ type u struct {
+ ArrayType
+ u UncommonType
+ }
+ return &(*u)(unsafe.Pointer(t)).u
+ case Chan:
+ type u struct {
+ ChanType
+ u UncommonType
+ }
+ return &(*u)(unsafe.Pointer(t)).u
+ case Map:
+ type u struct {
+ MapType
+ u UncommonType
+ }
+ return &(*u)(unsafe.Pointer(t)).u
+ case Interface:
+ type u struct {
+ InterfaceType
+ u UncommonType
+ }
+ return &(*u)(unsafe.Pointer(t)).u
+ default:
+ type u struct {
+ Type
+ u UncommonType
+ }
+ return &(*u)(unsafe.Pointer(t)).u
+ }
+}
+
+// Elem returns the element type for t if t is an array, channel, map, pointer, or slice, otherwise nil.
+func (t *Type) Elem() *Type {
+ switch t.Kind() {
+ case Array:
+ tt := (*ArrayType)(unsafe.Pointer(t))
+ return tt.Elem
+ case Chan:
+ tt := (*ChanType)(unsafe.Pointer(t))
+ return tt.Elem
+ case Map:
+ tt := (*MapType)(unsafe.Pointer(t))
+ return tt.Elem
+ case Pointer:
+ tt := (*PtrType)(unsafe.Pointer(t))
+ return tt.Elem
+ case Slice:
+ tt := (*SliceType)(unsafe.Pointer(t))
+ return tt.Elem
+ }
+ return nil
+}
+
+// StructType returns t cast to a *StructType, or nil if its tag does not match.
+func (t *Type) StructType() *StructType {
+ if t.Kind() != Struct {
+ return nil
+ }
+ return (*StructType)(unsafe.Pointer(t))
+}
+
+// MapType returns t cast to a *MapType, or nil if its tag does not match.
+func (t *Type) MapType() *MapType {
+ if t.Kind() != Map {
+ return nil
+ }
+ return (*MapType)(unsafe.Pointer(t))
+}
+
+// ArrayType returns t cast to a *ArrayType, or nil if its tag does not match.
+func (t *Type) ArrayType() *ArrayType {
+ if t.Kind() != Array {
+ return nil
+ }
+ return (*ArrayType)(unsafe.Pointer(t))
+}
+
+// FuncType returns t cast to a *FuncType, or nil if its tag does not match.
+func (t *Type) FuncType() *FuncType {
+ if t.Kind() != Func {
+ return nil
+ }
+ return (*FuncType)(unsafe.Pointer(t))
+}
+
+// InterfaceType returns t cast to a *InterfaceType, or nil if its tag does not match.
+func (t *Type) InterfaceType() *InterfaceType {
+ if t.Kind() != Interface {
+ return nil
+ }
+ return (*InterfaceType)(unsafe.Pointer(t))
+}
+
+// Size returns the size of data with type t.
+func (t *Type) Size() uintptr { return t.Size_ }
+
+// Align returns the alignment of data with type t.
+func (t *Type) Align() int { return int(t.Align_) }
+
+func (t *Type) FieldAlign() int { return int(t.FieldAlign_) }
+
+type InterfaceType struct {
+ Type
+ PkgPath Name // import path
+ Methods []Imethod // sorted by hash
+}
+
+func (t *Type) ExportedMethods() []Method {
+ ut := t.Uncommon()
+ if ut == nil {
+ return nil
+ }
+ return ut.ExportedMethods()
+}
+
+func (t *Type) NumMethod() int {
+ if t.Kind() == Interface {
+ tt := (*InterfaceType)(unsafe.Pointer(t))
+ return tt.NumMethod()
+ }
+ return len(t.ExportedMethods())
+}
+
+// NumMethod returns the number of interface methods in the type's method set.
+func (t *InterfaceType) NumMethod() int { return len(t.Methods) }
+
+type MapType struct {
+ Type
+ Key *Type
+ Elem *Type
+ Bucket *Type // internal type representing a hash bucket
+ // function for hashing keys (ptr to key, seed) -> hash
+ Hasher func(unsafe.Pointer, uintptr) uintptr
+ KeySize uint8 // size of key slot
+ ValueSize uint8 // size of elem slot
+ BucketSize uint16 // size of bucket
+ Flags uint32
+}
+
+// Note: flag values must match those used in the TMAP case
+// in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
+func (mt *MapType) IndirectKey() bool { // store ptr to key instead of key itself
+ return mt.Flags&1 != 0
+}
+func (mt *MapType) IndirectElem() bool { // store ptr to elem instead of elem itself
+ return mt.Flags&2 != 0
+}
+func (mt *MapType) ReflexiveKey() bool { // true if k==k for all keys
+ return mt.Flags&4 != 0
+}
+func (mt *MapType) NeedKeyUpdate() bool { // true if we need to update key on an overwrite
+ return mt.Flags&8 != 0
+}
+func (mt *MapType) HashMightPanic() bool { // true if hash function might panic
+ return mt.Flags&16 != 0
+}
+
+func (t *Type) Key() *Type {
+ if t.Kind() == Map {
+ return (*MapType)(unsafe.Pointer(t)).Key
+ }
+ return nil
+}
+
+type SliceType struct {
+ Type
+ Elem *Type // slice element type
+}
+
+// funcType represents a function type.
+//
+// A *Type for each in and out parameter is stored in an array that
+// directly follows the funcType (and possibly its uncommonType). So
+// a function type with one method, one input, and one output is:
+//
+// struct {
+// funcType
+// uncommonType
+// [2]*rtype // [0] is in, [1] is out
+// }
+type FuncType struct {
+ Type
+ InCount uint16
+ OutCount uint16 // top bit is set if last input parameter is ...
+}
+
+func (t *FuncType) In(i int) *Type {
+ return t.InSlice()[i]
+}
+
+func (t *FuncType) NumIn() int {
+ return int(t.InCount)
+}
+
+func (t *FuncType) NumOut() int {
+ return int(t.OutCount & (1<<15 - 1))
+}
+
+func (t *FuncType) Out(i int) *Type {
+ return (t.OutSlice()[i])
+}
+
+func (t *FuncType) InSlice() []*Type {
+ uadd := unsafe.Sizeof(*t)
+ if t.TFlag&TFlagUncommon != 0 {
+ uadd += unsafe.Sizeof(UncommonType{})
+ }
+ if t.InCount == 0 {
+ return nil
+ }
+ return (*[1 << 16]*Type)(addChecked(unsafe.Pointer(t), uadd, "t.inCount > 0"))[:t.InCount:t.InCount]
+}
+func (t *FuncType) OutSlice() []*Type {
+ outCount := uint16(t.NumOut())
+ if outCount == 0 {
+ return nil
+ }
+ uadd := unsafe.Sizeof(*t)
+ if t.TFlag&TFlagUncommon != 0 {
+ uadd += unsafe.Sizeof(UncommonType{})
+ }
+ return (*[1 << 17]*Type)(addChecked(unsafe.Pointer(t), uadd, "outCount > 0"))[t.InCount : t.InCount+outCount : t.InCount+outCount]
+}
+
+func (t *FuncType) IsVariadic() bool {
+ return t.OutCount&(1<<15) != 0
+}
+
+type PtrType struct {
+ Type
+ Elem *Type // pointer element (pointed at) type
+}
+
+type StructField struct {
+ Name Name // name is always non-empty
+ Typ *Type // type of field
+ Offset uintptr // byte offset of field
+}
+
+func (f *StructField) Embedded() bool {
+ return f.Name.IsEmbedded()
+}
+
+type StructType struct {
+ Type
+ PkgPath Name
+ Fields []StructField
+}
+
+// Name is an encoded type Name with optional extra data.
+//
+// The first byte is a bit field containing:
+//
+// 1<<0 the name is exported
+// 1<<1 tag data follows the name
+// 1<<2 pkgPath nameOff follows the name and tag
+// 1<<3 the name is of an embedded (a.k.a. anonymous) field
+//
+// Following that, there is a varint-encoded length of the name,
+// followed by the name itself.
+//
+// If tag data is present, it also has a varint-encoded length
+// followed by the tag itself.
+//
+// If the import path follows, then 4 bytes at the end of
+// the data form a nameOff. The import path is only set for concrete
+// methods that are defined in a different package than their type.
+//
+// If a name starts with "*", then the exported bit represents
+// whether the pointed to type is exported.
+//
+// Note: this encoding must match here and in:
+// cmd/compile/internal/reflectdata/reflect.go
+// cmd/link/internal/ld/decodesym.go
+
+type Name struct {
+ Bytes *byte
+}
+
+// DataChecked does pointer arithmetic on n's Bytes, and that arithmetic is asserted to
+// be safe for the reason in whySafe (which can appear in a backtrace, etc.)
+func (n Name) DataChecked(off int, whySafe string) *byte {
+ return (*byte)(addChecked(unsafe.Pointer(n.Bytes), uintptr(off), whySafe))
+}
+
+// Data does pointer arithmetic on n's Bytes, and that arithmetic is asserted to
+// be safe because the runtime made the call (other packages use DataChecked)
+func (n Name) Data(off int) *byte {
+ return (*byte)(addChecked(unsafe.Pointer(n.Bytes), uintptr(off), "the runtime doesn't need to give you a reason"))
+}
+
+// IsExported returns "is n exported?"
+func (n Name) IsExported() bool {
+ return (*n.Bytes)&(1<<0) != 0
+}
+
+// HasTag returns true iff there is tag data following this name
+func (n Name) HasTag() bool {
+ return (*n.Bytes)&(1<<1) != 0
+}
+
+// IsEmbedded returns true iff n is embedded (an anonymous field).
+func (n Name) IsEmbedded() bool {
+ return (*n.Bytes)&(1<<3) != 0
+}
+
+// ReadVarint parses a varint as encoded by encoding/binary.
+// It returns the number of encoded bytes and the encoded value.
+func (n Name) ReadVarint(off int) (int, int) {
+ v := 0
+ for i := 0; ; i++ {
+ x := *n.DataChecked(off+i, "read varint")
+ v += int(x&0x7f) << (7 * i)
+ if x&0x80 == 0 {
+ return i + 1, v
+ }
+ }
+}
+
+// IsBlank indicates whether n is "_".
+func (n Name) IsBlank() bool {
+ if n.Bytes == nil {
+ return false
+ }
+ _, l := n.ReadVarint(1)
+ return l == 1 && *n.Data(2) == '_'
+}
+
+// writeVarint writes n to buf in varint form. Returns the
+// number of bytes written. n must be nonnegative.
+// Writes at most 10 bytes.
+func writeVarint(buf []byte, n int) int {
+ for i := 0; ; i++ {
+ b := byte(n & 0x7f)
+ n >>= 7
+ if n == 0 {
+ buf[i] = b
+ return i + 1
+ }
+ buf[i] = b | 0x80
+ }
+}
+
+// Name returns the tag string for n, or empty if there is none.
+func (n Name) Name() string {
+ if n.Bytes == nil {
+ return ""
+ }
+ i, l := n.ReadVarint(1)
+ return unsafeStringFor(n.DataChecked(1+i, "non-empty string"), l)
+}
+
+// Tag returns the tag string for n, or empty if there is none.
+func (n Name) Tag() string {
+ if !n.HasTag() {
+ return ""
+ }
+ i, l := n.ReadVarint(1)
+ i2, l2 := n.ReadVarint(1 + i + l)
+ return unsafeStringFor(n.DataChecked(1+i+l+i2, "non-empty string"), l2)
+}
+
+func NewName(n, tag string, exported, embedded bool) Name {
+ if len(n) >= 1<<29 {
+ panic("abi.NewName: name too long: " + n[:1024] + "...")
+ }
+ if len(tag) >= 1<<29 {
+ panic("abi.NewName: tag too long: " + tag[:1024] + "...")
+ }
+ var nameLen [10]byte
+ var tagLen [10]byte
+ nameLenLen := writeVarint(nameLen[:], len(n))
+ tagLenLen := writeVarint(tagLen[:], len(tag))
+
+ var bits byte
+ l := 1 + nameLenLen + len(n)
+ if exported {
+ bits |= 1 << 0
+ }
+ if len(tag) > 0 {
+ l += tagLenLen + len(tag)
+ bits |= 1 << 1
+ }
+ if embedded {
+ bits |= 1 << 3
+ }
+
+ b := make([]byte, l)
+ b[0] = bits
+ copy(b[1:], nameLen[:nameLenLen])
+ copy(b[1+nameLenLen:], n)
+ if len(tag) > 0 {
+ tb := b[1+nameLenLen+len(n):]
+ copy(tb, tagLen[:tagLenLen])
+ copy(tb[tagLenLen:], tag)
+ }
+
+ return Name{Bytes: &b[0]}
+}
diff --git a/contrib/go/_std_1.21/src/internal/abi/unsafestring_go120.go b/contrib/go/_std_1.21/src/internal/abi/unsafestring_go120.go
new file mode 100644
index 0000000000..93ff8eacc8
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/abi/unsafestring_go120.go
@@ -0,0 +1,18 @@
+// Copyright 2023 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.
+
+//go:build go1.20
+// +build go1.20
+
+package abi
+
+import "unsafe"
+
+func unsafeStringFor(b *byte, l int) string {
+ return unsafe.String(b, l)
+}
+
+func unsafeSliceFor(b *byte, l int) []byte {
+ return unsafe.Slice(b, l)
+}
diff --git a/contrib/go/_std_1.21/src/internal/abi/ya.make b/contrib/go/_std_1.21/src/internal/abi/ya.make
new file mode 100644
index 0000000000..2b68cbebfb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/abi/ya.make
@@ -0,0 +1,35 @@
+GO_LIBRARY()
+
+SRCS(
+ abi.go
+ abi_test.s
+ compiletype.go
+ funcpc.go
+ map.go
+ stack.go
+ stub.s
+ symtab.go
+ type.go
+ unsafestring_go120.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(abi_test.go)
+
+IF (ARCH_X86_64)
+ SRCS(
+ abi_amd64.go
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ abi_arm64.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/internal/bisect/bisect.go b/contrib/go/_std_1.21/src/internal/bisect/bisect.go
new file mode 100644
index 0000000000..48c796e54a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/bisect/bisect.go
@@ -0,0 +1,795 @@
+// Copyright 2023 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 bisect can be used by compilers and other programs
+// to serve as a target for the bisect debugging tool.
+// See [golang.org/x/tools/cmd/bisect] for details about using the tool.
+//
+// To be a bisect target, allowing bisect to help determine which of a set of independent
+// changes provokes a failure, a program needs to:
+//
+// 1. Define a way to accept a change pattern on its command line or in its environment.
+// The most common mechanism is a command-line flag.
+// The pattern can be passed to [New] to create a [Matcher], the compiled form of a pattern.
+//
+// 2. Assign each change a unique ID. One possibility is to use a sequence number,
+// but the most common mechanism is to hash some kind of identifying information
+// like the file and line number where the change might be applied.
+// [Hash] hashes its arguments to compute an ID.
+//
+// 3. Enable each change that the pattern says should be enabled.
+// The [Matcher.ShouldEnable] method answers this question for a given change ID.
+//
+// 4. Print a report identifying each change that the pattern says should be printed.
+// The [Matcher.ShouldPrint] method answers this question for a given change ID.
+// The report consists of one more lines on standard error or standard output
+// that contain a “match marker”. [Marker] returns the match marker for a given ID.
+// When bisect reports a change as causing the failure, it identifies the change
+// by printing the report lines with the match marker removed.
+//
+// # Example Usage
+//
+// A program starts by defining how it receives the pattern. In this example, we will assume a flag.
+// The next step is to compile the pattern:
+//
+// m, err := bisect.New(patternFlag)
+// if err != nil {
+// log.Fatal(err)
+// }
+//
+// Then, each time a potential change is considered, the program computes
+// a change ID by hashing identifying information (source file and line, in this case)
+// and then calls m.ShouldPrint and m.ShouldEnable to decide whether to
+// print and enable the change, respectively. The two can return different values
+// depending on whether bisect is trying to find a minimal set of changes to
+// disable or to enable to provoke the failure.
+//
+// It is usually helpful to write a helper function that accepts the identifying information
+// and then takes care of hashing, printing, and reporting whether the identified change
+// should be enabled. For example, a helper for changes identified by a file and line number
+// would be:
+//
+// func ShouldEnable(file string, line int) {
+// h := bisect.Hash(file, line)
+// if m.ShouldPrint(h) {
+// fmt.Fprintf(os.Stderr, "%v %s:%d\n", bisect.Marker(h), file, line)
+// }
+// return m.ShouldEnable(h)
+// }
+//
+// Finally, note that New returns a nil Matcher when there is no pattern,
+// meaning that the target is not running under bisect at all,
+// so all changes should be enabled and none should be printed.
+// In that common case, the computation of the hash can be avoided entirely
+// by checking for m == nil first:
+//
+// func ShouldEnable(file string, line int) bool {
+// if m == nil {
+// return false
+// }
+// h := bisect.Hash(file, line)
+// if m.ShouldPrint(h) {
+// fmt.Fprintf(os.Stderr, "%v %s:%d\n", bisect.Marker(h), file, line)
+// }
+// return m.ShouldEnable(h)
+// }
+//
+// When the identifying information is expensive to format, this code can call
+// [Matcher.MarkerOnly] to find out whether short report lines containing only the
+// marker are permitted for a given run. (Bisect permits such lines when it is
+// still exploring the space of possible changes and will not be showing the
+// output to the user.) If so, the client can choose to print only the marker:
+//
+// func ShouldEnable(file string, line int) bool {
+// if m == nil {
+// return false
+// }
+// h := bisect.Hash(file, line)
+// if m.ShouldPrint(h) {
+// if m.MarkerOnly() {
+// bisect.PrintMarker(os.Stderr)
+// } else {
+// fmt.Fprintf(os.Stderr, "%v %s:%d\n", bisect.Marker(h), file, line)
+// }
+// }
+// return m.ShouldEnable(h)
+// }
+//
+// This specific helper – deciding whether to enable a change identified by
+// file and line number and printing about the change when necessary – is
+// provided by the [Matcher.FileLine] method.
+//
+// Another common usage is deciding whether to make a change in a function
+// based on the caller's stack, to identify the specific calling contexts that the
+// change breaks. The [Matcher.Stack] method takes care of obtaining the stack,
+// printing it when necessary, and reporting whether to enable the change
+// based on that stack.
+//
+// # Pattern Syntax
+//
+// Patterns are generated by the bisect tool and interpreted by [New].
+// Users should not have to understand the patterns except when
+// debugging a target's bisect support or debugging the bisect tool itself.
+//
+// The pattern syntax selecting a change is a sequence of bit strings
+// separated by + and - operators. Each bit string denotes the set of
+// changes with IDs ending in those bits, + is set addition, - is set subtraction,
+// and the expression is evaluated in the usual left-to-right order.
+// The special binary number “y” denotes the set of all changes,
+// standing in for the empty bit string.
+// In the expression, all the + operators must appear before all the - operators.
+// A leading + adds to an empty set. A leading - subtracts from the set of all
+// possible suffixes.
+//
+// For example:
+//
+// - “01+10” and “+01+10” both denote the set of changes
+// with IDs ending with the bits 01 or 10.
+//
+// - “01+10-1001” denotes the set of changes with IDs
+// ending with the bits 01 or 10, but excluding those ending in 1001.
+//
+// - “-01-1000” and “y-01-1000 both denote the set of all changes
+// with IDs not ending in 01 nor 1000.
+//
+// - “0+1-01+001” is not a valid pattern, because all the + operators do not
+// appear before all the - operators.
+//
+// In the syntaxes described so far, the pattern specifies the changes to
+// enable and report. If a pattern is prefixed by a “!”, the meaning
+// changes: the pattern specifies the changes to DISABLE and report. This
+// mode of operation is needed when a program passes with all changes
+// enabled but fails with no changes enabled. In this case, bisect
+// searches for minimal sets of changes to disable.
+// Put another way, the leading “!” inverts the result from [Matcher.ShouldEnable]
+// but does not invert the result from [Matcher.ShouldPrint].
+//
+// As a convenience for manual debugging, “n” is an alias for “!y”,
+// meaning to disable and report all changes.
+//
+// Finally, a leading “v” in the pattern indicates that the reports will be shown
+// to the user of bisect to describe the changes involved in a failure.
+// At the API level, the leading “v” causes [Matcher.Visible] to return true.
+// See the next section for details.
+//
+// # Match Reports
+//
+// The target program must enable only those changed matched
+// by the pattern, and it must print a match report for each such change.
+// A match report consists of one or more lines of text that will be
+// printed by the bisect tool to describe a change implicated in causing
+// a failure. Each line in the report for a given change must contain a
+// match marker with that change ID, as returned by [Marker].
+// The markers are elided when displaying the lines to the user.
+//
+// A match marker has the form “[bisect-match 0x1234]” where
+// 0x1234 is the change ID in hexadecimal.
+// An alternate form is “[bisect-match 010101]”, giving the change ID in binary.
+//
+// When [Matcher.Visible] returns false, the match reports are only
+// being processed by bisect to learn the set of enabled changes,
+// not shown to the user, meaning that each report can be a match
+// marker on a line by itself, eliding the usual textual description.
+// When the textual description is expensive to compute,
+// checking [Matcher.Visible] can help the avoid that expense
+// in most runs.
+package bisect
+
+import (
+ "runtime"
+ "sync"
+ "sync/atomic"
+ "unsafe"
+)
+
+// New creates and returns a new Matcher implementing the given pattern.
+// The pattern syntax is defined in the package doc comment.
+//
+// In addition to the pattern syntax syntax, New("") returns nil, nil.
+// The nil *Matcher is valid for use: it returns true from ShouldEnable
+// and false from ShouldPrint for all changes. Callers can avoid calling
+// [Hash], [Matcher.ShouldEnable], and [Matcher.ShouldPrint] entirely
+// when they recognize the nil Matcher.
+func New(pattern string) (*Matcher, error) {
+ if pattern == "" {
+ return nil, nil
+ }
+
+ m := new(Matcher)
+
+ p := pattern
+ // Special case for leading 'q' so that 'qn' quietly disables, e.g. fmahash=qn to disable fma
+ // Any instance of 'v' disables 'q'.
+ if len(p) > 0 && p[0] == 'q' {
+ m.quiet = true
+ p = p[1:]
+ if p == "" {
+ return nil, &parseError{"invalid pattern syntax: " + pattern}
+ }
+ }
+ // Allow multiple v, so that “bisect cmd vPATTERN” can force verbose all the time.
+ for len(p) > 0 && p[0] == 'v' {
+ m.verbose = true
+ m.quiet = false
+ p = p[1:]
+ if p == "" {
+ return nil, &parseError{"invalid pattern syntax: " + pattern}
+ }
+ }
+
+ // Allow multiple !, each negating the last, so that “bisect cmd !PATTERN” works
+ // even when bisect chooses to add its own !.
+ m.enable = true
+ for len(p) > 0 && p[0] == '!' {
+ m.enable = !m.enable
+ p = p[1:]
+ if p == "" {
+ return nil, &parseError{"invalid pattern syntax: " + pattern}
+ }
+ }
+
+ if p == "n" {
+ // n is an alias for !y.
+ m.enable = !m.enable
+ p = "y"
+ }
+
+ // Parse actual pattern syntax.
+ result := true
+ bits := uint64(0)
+ start := 0
+ wid := 1 // 1-bit (binary); sometimes 4-bit (hex)
+ for i := 0; i <= len(p); i++ {
+ // Imagine a trailing - at the end of the pattern to flush final suffix
+ c := byte('-')
+ if i < len(p) {
+ c = p[i]
+ }
+ if i == start && wid == 1 && c == 'x' { // leading x for hex
+ start = i + 1
+ wid = 4
+ continue
+ }
+ switch c {
+ default:
+ return nil, &parseError{"invalid pattern syntax: " + pattern}
+ case '2', '3', '4', '5', '6', '7', '8', '9':
+ if wid != 4 {
+ return nil, &parseError{"invalid pattern syntax: " + pattern}
+ }
+ fallthrough
+ case '0', '1':
+ bits <<= wid
+ bits |= uint64(c - '0')
+ case 'a', 'b', 'c', 'd', 'e', 'f', 'A', 'B', 'C', 'D', 'E', 'F':
+ if wid != 4 {
+ return nil, &parseError{"invalid pattern syntax: " + pattern}
+ }
+ bits <<= 4
+ bits |= uint64(c&^0x20 - 'A' + 10)
+ case 'y':
+ if i+1 < len(p) && (p[i+1] == '0' || p[i+1] == '1') {
+ return nil, &parseError{"invalid pattern syntax: " + pattern}
+ }
+ bits = 0
+ case '+', '-':
+ if c == '+' && result == false {
+ // Have already seen a -. Should be - from here on.
+ return nil, &parseError{"invalid pattern syntax (+ after -): " + pattern}
+ }
+ if i > 0 {
+ n := (i - start) * wid
+ if n > 64 {
+ return nil, &parseError{"pattern bits too long: " + pattern}
+ }
+ if n <= 0 {
+ return nil, &parseError{"invalid pattern syntax: " + pattern}
+ }
+ if p[start] == 'y' {
+ n = 0
+ }
+ mask := uint64(1)<<n - 1
+ m.list = append(m.list, cond{mask, bits, result})
+ } else if c == '-' {
+ // leading - subtracts from complete set
+ m.list = append(m.list, cond{0, 0, true})
+ }
+ bits = 0
+ result = c == '+'
+ start = i + 1
+ wid = 1
+ }
+ }
+ return m, nil
+}
+
+// A Matcher is the parsed, compiled form of a PATTERN string.
+// The nil *Matcher is valid: it has all changes enabled but none reported.
+type Matcher struct {
+ verbose bool // annotate reporting with human-helpful information
+ quiet bool // disables all reporting. reset if verbose is true. use case is -d=fmahash=qn
+ enable bool // when true, list is for “enable and report” (when false, “disable and report”)
+ list []cond // conditions; later ones win over earlier ones
+ dedup atomicPointerDedup
+}
+
+// atomicPointerDedup is an atomic.Pointer[dedup],
+// but we are avoiding using Go 1.19's atomic.Pointer
+// until the bootstrap toolchain can be relied upon to have it.
+type atomicPointerDedup struct {
+ p unsafe.Pointer
+}
+
+func (p *atomicPointerDedup) Load() *dedup {
+ return (*dedup)(atomic.LoadPointer(&p.p))
+}
+
+func (p *atomicPointerDedup) CompareAndSwap(old, new *dedup) bool {
+ return atomic.CompareAndSwapPointer(&p.p, unsafe.Pointer(old), unsafe.Pointer(new))
+}
+
+// A cond is a single condition in the matcher.
+// Given an input id, if id&mask == bits, return the result.
+type cond struct {
+ mask uint64
+ bits uint64
+ result bool
+}
+
+// MarkerOnly reports whether it is okay to print only the marker for
+// a given change, omitting the identifying information.
+// MarkerOnly returns true when bisect is using the printed reports
+// only for an intermediate search step, not for showing to users.
+func (m *Matcher) MarkerOnly() bool {
+ return !m.verbose
+}
+
+// ShouldEnable reports whether the change with the given id should be enabled.
+func (m *Matcher) ShouldEnable(id uint64) bool {
+ if m == nil {
+ return true
+ }
+ return m.matchResult(id) == m.enable
+}
+
+// ShouldPrint reports whether to print identifying information about the change with the given id.
+func (m *Matcher) ShouldPrint(id uint64) bool {
+ if m == nil || m.quiet {
+ return false
+ }
+ return m.matchResult(id)
+}
+
+// matchResult returns the result from the first condition that matches id.
+func (m *Matcher) matchResult(id uint64) bool {
+ for i := len(m.list) - 1; i >= 0; i-- {
+ c := &m.list[i]
+ if id&c.mask == c.bits {
+ return c.result
+ }
+ }
+ return false
+}
+
+// FileLine reports whether the change identified by file and line should be enabled.
+// If the change should be printed, FileLine prints a one-line report to w.
+func (m *Matcher) FileLine(w Writer, file string, line int) bool {
+ if m == nil {
+ return true
+ }
+ return m.fileLine(w, file, line)
+}
+
+// fileLine does the real work for FileLine.
+// This lets FileLine's body handle m == nil and potentially be inlined.
+func (m *Matcher) fileLine(w Writer, file string, line int) bool {
+ h := Hash(file, line)
+ if m.ShouldPrint(h) {
+ if m.MarkerOnly() {
+ PrintMarker(w, h)
+ } else {
+ printFileLine(w, h, file, line)
+ }
+ }
+ return m.ShouldEnable(h)
+}
+
+// printFileLine prints a non-marker-only report for file:line to w.
+func printFileLine(w Writer, h uint64, file string, line int) error {
+ const markerLen = 40 // overestimate
+ b := make([]byte, 0, markerLen+len(file)+24)
+ b = AppendMarker(b, h)
+ b = appendFileLine(b, file, line)
+ b = append(b, '\n')
+ _, err := w.Write(b)
+ return err
+}
+
+// appendFileLine appends file:line to dst, returning the extended slice.
+func appendFileLine(dst []byte, file string, line int) []byte {
+ dst = append(dst, file...)
+ dst = append(dst, ':')
+ u := uint(line)
+ if line < 0 {
+ dst = append(dst, '-')
+ u = -u
+ }
+ var buf [24]byte
+ i := len(buf)
+ for i == len(buf) || u > 0 {
+ i--
+ buf[i] = '0' + byte(u%10)
+ u /= 10
+ }
+ dst = append(dst, buf[i:]...)
+ return dst
+}
+
+// MatchStack assigns the current call stack a change ID.
+// If the stack should be printed, MatchStack prints it.
+// Then MatchStack reports whether a change at the current call stack should be enabled.
+func (m *Matcher) Stack(w Writer) bool {
+ if m == nil {
+ return true
+ }
+ return m.stack(w)
+}
+
+// stack does the real work for Stack.
+// This lets stack's body handle m == nil and potentially be inlined.
+func (m *Matcher) stack(w Writer) bool {
+ const maxStack = 16
+ var stk [maxStack]uintptr
+ n := runtime.Callers(2, stk[:])
+ // caller #2 is not for printing; need it to normalize PCs if ASLR.
+ if n <= 1 {
+ return false
+ }
+
+ base := stk[0]
+ // normalize PCs
+ for i := range stk[:n] {
+ stk[i] -= base
+ }
+
+ h := Hash(stk[:n])
+ if m.ShouldPrint(h) {
+ var d *dedup
+ for {
+ d = m.dedup.Load()
+ if d != nil {
+ break
+ }
+ d = new(dedup)
+ if m.dedup.CompareAndSwap(nil, d) {
+ break
+ }
+ }
+
+ if m.MarkerOnly() {
+ if !d.seenLossy(h) {
+ PrintMarker(w, h)
+ }
+ } else {
+ if !d.seen(h) {
+ // Restore PCs in stack for printing
+ for i := range stk[:n] {
+ stk[i] += base
+ }
+ printStack(w, h, stk[1:n])
+ }
+ }
+ }
+ return m.ShouldEnable(h)
+
+}
+
+// Writer is the same interface as io.Writer.
+// It is duplicated here to avoid importing io.
+type Writer interface {
+ Write([]byte) (int, error)
+}
+
+// PrintMarker prints to w a one-line report containing only the marker for h.
+// It is appropriate to use when [Matcher.ShouldPrint] and [Matcher.MarkerOnly] both return true.
+func PrintMarker(w Writer, h uint64) error {
+ var buf [50]byte
+ b := AppendMarker(buf[:], h)
+ b = append(b, '\n')
+ _, err := w.Write(b)
+ return err
+}
+
+// printStack prints to w a multi-line report containing a formatting of the call stack stk,
+// with each line preceded by the marker for h.
+func printStack(w Writer, h uint64, stk []uintptr) error {
+ buf := make([]byte, 0, 2048)
+
+ var prefixBuf [100]byte
+ prefix := AppendMarker(prefixBuf[:0], h)
+
+ frames := runtime.CallersFrames(stk)
+ for {
+ f, more := frames.Next()
+ buf = append(buf, prefix...)
+ buf = append(buf, f.Func.Name()...)
+ buf = append(buf, "()\n"...)
+ buf = append(buf, prefix...)
+ buf = append(buf, '\t')
+ buf = appendFileLine(buf, f.File, f.Line)
+ buf = append(buf, '\n')
+ if !more {
+ break
+ }
+ }
+ buf = append(buf, prefix...)
+ buf = append(buf, '\n')
+ _, err := w.Write(buf)
+ return err
+}
+
+// Marker returns the match marker text to use on any line reporting details
+// about a match of the given ID.
+// It always returns the hexadecimal format.
+func Marker(id uint64) string {
+ return string(AppendMarker(nil, id))
+}
+
+// AppendMarker is like [Marker] but appends the marker to dst.
+func AppendMarker(dst []byte, id uint64) []byte {
+ const prefix = "[bisect-match 0x"
+ var buf [len(prefix) + 16 + 1]byte
+ copy(buf[:], prefix)
+ for i := 0; i < 16; i++ {
+ buf[len(prefix)+i] = "0123456789abcdef"[id>>60]
+ id <<= 4
+ }
+ buf[len(prefix)+16] = ']'
+ return append(dst, buf[:]...)
+}
+
+// CutMarker finds the first match marker in line and removes it,
+// returning the shortened line (with the marker removed),
+// the ID from the match marker,
+// and whether a marker was found at all.
+// If there is no marker, CutMarker returns line, 0, false.
+func CutMarker(line string) (short string, id uint64, ok bool) {
+ // Find first instance of prefix.
+ prefix := "[bisect-match "
+ i := 0
+ for ; ; i++ {
+ if i >= len(line)-len(prefix) {
+ return line, 0, false
+ }
+ if line[i] == '[' && line[i:i+len(prefix)] == prefix {
+ break
+ }
+ }
+
+ // Scan to ].
+ j := i + len(prefix)
+ for j < len(line) && line[j] != ']' {
+ j++
+ }
+ if j >= len(line) {
+ return line, 0, false
+ }
+
+ // Parse id.
+ idstr := line[i+len(prefix) : j]
+ if len(idstr) >= 3 && idstr[:2] == "0x" {
+ // parse hex
+ if len(idstr) > 2+16 { // max 0x + 16 digits
+ return line, 0, false
+ }
+ for i := 2; i < len(idstr); i++ {
+ id <<= 4
+ switch c := idstr[i]; {
+ case '0' <= c && c <= '9':
+ id |= uint64(c - '0')
+ case 'a' <= c && c <= 'f':
+ id |= uint64(c - 'a' + 10)
+ case 'A' <= c && c <= 'F':
+ id |= uint64(c - 'A' + 10)
+ }
+ }
+ } else {
+ if idstr == "" || len(idstr) > 64 { // min 1 digit, max 64 digits
+ return line, 0, false
+ }
+ // parse binary
+ for i := 0; i < len(idstr); i++ {
+ id <<= 1
+ switch c := idstr[i]; c {
+ default:
+ return line, 0, false
+ case '0', '1':
+ id |= uint64(c - '0')
+ }
+ }
+ }
+
+ // Construct shortened line.
+ // Remove at most one space from around the marker,
+ // so that "foo [marker] bar" shortens to "foo bar".
+ j++ // skip ]
+ if i > 0 && line[i-1] == ' ' {
+ i--
+ } else if j < len(line) && line[j] == ' ' {
+ j++
+ }
+ short = line[:i] + line[j:]
+ return short, id, true
+}
+
+// Hash computes a hash of the data arguments,
+// each of which must be of type string, byte, int, uint, int32, uint32, int64, uint64, uintptr, or a slice of one of those types.
+func Hash(data ...any) uint64 {
+ h := offset64
+ for _, v := range data {
+ switch v := v.(type) {
+ default:
+ // Note: Not printing the type, because reflect.ValueOf(v)
+ // would make the interfaces prepared by the caller escape
+ // and therefore allocate. This way, Hash(file, line) runs
+ // without any allocation. It should be clear from the
+ // source code calling Hash what the bad argument was.
+ panic("bisect.Hash: unexpected argument type")
+ case string:
+ h = fnvString(h, v)
+ case byte:
+ h = fnv(h, v)
+ case int:
+ h = fnvUint64(h, uint64(v))
+ case uint:
+ h = fnvUint64(h, uint64(v))
+ case int32:
+ h = fnvUint32(h, uint32(v))
+ case uint32:
+ h = fnvUint32(h, v)
+ case int64:
+ h = fnvUint64(h, uint64(v))
+ case uint64:
+ h = fnvUint64(h, v)
+ case uintptr:
+ h = fnvUint64(h, uint64(v))
+ case []string:
+ for _, x := range v {
+ h = fnvString(h, x)
+ }
+ case []byte:
+ for _, x := range v {
+ h = fnv(h, x)
+ }
+ case []int:
+ for _, x := range v {
+ h = fnvUint64(h, uint64(x))
+ }
+ case []uint:
+ for _, x := range v {
+ h = fnvUint64(h, uint64(x))
+ }
+ case []int32:
+ for _, x := range v {
+ h = fnvUint32(h, uint32(x))
+ }
+ case []uint32:
+ for _, x := range v {
+ h = fnvUint32(h, x)
+ }
+ case []int64:
+ for _, x := range v {
+ h = fnvUint64(h, uint64(x))
+ }
+ case []uint64:
+ for _, x := range v {
+ h = fnvUint64(h, x)
+ }
+ case []uintptr:
+ for _, x := range v {
+ h = fnvUint64(h, uint64(x))
+ }
+ }
+ }
+ return h
+}
+
+// Trivial error implementation, here to avoid importing errors.
+
+// parseError is a trivial error implementation,
+// defined here to avoid importing errors.
+type parseError struct{ text string }
+
+func (e *parseError) Error() string { return e.text }
+
+// FNV-1a implementation. See Go's hash/fnv/fnv.go.
+// Copied here for simplicity (can handle integers more directly)
+// and to avoid importing hash/fnv.
+
+const (
+ offset64 uint64 = 14695981039346656037
+ prime64 uint64 = 1099511628211
+)
+
+func fnv(h uint64, x byte) uint64 {
+ h ^= uint64(x)
+ h *= prime64
+ return h
+}
+
+func fnvString(h uint64, x string) uint64 {
+ for i := 0; i < len(x); i++ {
+ h ^= uint64(x[i])
+ h *= prime64
+ }
+ return h
+}
+
+func fnvUint64(h uint64, x uint64) uint64 {
+ for i := 0; i < 8; i++ {
+ h ^= uint64(x & 0xFF)
+ x >>= 8
+ h *= prime64
+ }
+ return h
+}
+
+func fnvUint32(h uint64, x uint32) uint64 {
+ for i := 0; i < 4; i++ {
+ h ^= uint64(x & 0xFF)
+ x >>= 8
+ h *= prime64
+ }
+ return h
+}
+
+// A dedup is a deduplicator for call stacks, so that we only print
+// a report for new call stacks, not for call stacks we've already
+// reported.
+//
+// It has two modes: an approximate but lock-free mode that
+// may still emit some duplicates, and a precise mode that uses
+// a lock and never emits duplicates.
+type dedup struct {
+ // 128-entry 4-way, lossy cache for seenLossy
+ recent [128][4]uint64
+
+ // complete history for seen
+ mu sync.Mutex
+ m map[uint64]bool
+}
+
+// seen records that h has now been seen and reports whether it was seen before.
+// When seen returns false, the caller is expected to print a report for h.
+func (d *dedup) seen(h uint64) bool {
+ d.mu.Lock()
+ if d.m == nil {
+ d.m = make(map[uint64]bool)
+ }
+ seen := d.m[h]
+ d.m[h] = true
+ d.mu.Unlock()
+ return seen
+}
+
+// seenLossy is a variant of seen that avoids a lock by using a cache of recently seen hashes.
+// Each cache entry is N-way set-associative: h can appear in any of the slots.
+// If h does not appear in any of them, then it is inserted into a random slot,
+// overwriting whatever was there before.
+func (d *dedup) seenLossy(h uint64) bool {
+ cache := &d.recent[uint(h)%uint(len(d.recent))]
+ for i := 0; i < len(cache); i++ {
+ if atomic.LoadUint64(&cache[i]) == h {
+ return true
+ }
+ }
+
+ // Compute index in set to evict as hash of current set.
+ ch := offset64
+ for _, x := range cache {
+ ch = fnvUint64(ch, x)
+ }
+ atomic.StoreUint64(&cache[uint(ch)%uint(len(cache))], h)
+ return false
+}
diff --git a/contrib/go/_std_1.21/src/internal/bisect/ya.make b/contrib/go/_std_1.21/src/internal/bisect/ya.make
new file mode 100644
index 0000000000..00ed5f737d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/bisect/ya.make
@@ -0,0 +1,7 @@
+GO_LIBRARY()
+
+SRCS(
+ bisect.go
+)
+
+END()
diff --git a/contrib/go/_std_1.21/src/internal/buildcfg/cfg.go b/contrib/go/_std_1.21/src/internal/buildcfg/cfg.go
new file mode 100644
index 0000000000..b97b9c1b53
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/buildcfg/cfg.go
@@ -0,0 +1,235 @@
+// 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 buildcfg provides access to the build configuration
+// described by the current environment. It is for use by build tools
+// such as cmd/go or cmd/compile and for setting up go/build's Default context.
+//
+// Note that it does NOT provide access to the build configuration used to
+// build the currently-running binary. For that, use runtime.GOOS etc
+// as well as internal/goexperiment.
+package buildcfg
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "strings"
+)
+
+var (
+ GOROOT = runtime.GOROOT() // cached for efficiency
+ GOARCH = envOr("GOARCH", defaultGOARCH)
+ GOOS = envOr("GOOS", defaultGOOS)
+ GO386 = envOr("GO386", defaultGO386)
+ GOAMD64 = goamd64()
+ GOARM = goarm()
+ GOMIPS = gomips()
+ GOMIPS64 = gomips64()
+ GOPPC64 = goppc64()
+ GOWASM = gowasm()
+ ToolTags = toolTags()
+ GO_LDSO = defaultGO_LDSO
+ Version = version
+)
+
+// Error is one of the errors found (if any) in the build configuration.
+var Error error
+
+// Check exits the program with a fatal error if Error is non-nil.
+func Check() {
+ if Error != nil {
+ fmt.Fprintf(os.Stderr, "%s: %v\n", filepath.Base(os.Args[0]), Error)
+ os.Exit(2)
+ }
+}
+
+func envOr(key, value string) string {
+ if x := os.Getenv(key); x != "" {
+ return x
+ }
+ return value
+}
+
+func goamd64() int {
+ switch v := envOr("GOAMD64", defaultGOAMD64); v {
+ case "v1":
+ return 1
+ case "v2":
+ return 2
+ case "v3":
+ return 3
+ case "v4":
+ return 4
+ }
+ Error = fmt.Errorf("invalid GOAMD64: must be v1, v2, v3, v4")
+ return int(defaultGOAMD64[len("v")] - '0')
+}
+
+func goarm() int {
+ def := defaultGOARM
+ if GOOS == "android" && GOARCH == "arm" {
+ // Android arm devices always support GOARM=7.
+ def = "7"
+ }
+ switch v := envOr("GOARM", def); v {
+ case "5":
+ return 5
+ case "6":
+ return 6
+ case "7":
+ return 7
+ }
+ Error = fmt.Errorf("invalid GOARM: must be 5, 6, 7")
+ return int(def[0] - '0')
+}
+
+func gomips() string {
+ switch v := envOr("GOMIPS", defaultGOMIPS); v {
+ case "hardfloat", "softfloat":
+ return v
+ }
+ Error = fmt.Errorf("invalid GOMIPS: must be hardfloat, softfloat")
+ return defaultGOMIPS
+}
+
+func gomips64() string {
+ switch v := envOr("GOMIPS64", defaultGOMIPS64); v {
+ case "hardfloat", "softfloat":
+ return v
+ }
+ Error = fmt.Errorf("invalid GOMIPS64: must be hardfloat, softfloat")
+ return defaultGOMIPS64
+}
+
+func goppc64() int {
+ switch v := envOr("GOPPC64", defaultGOPPC64); v {
+ case "power8":
+ return 8
+ case "power9":
+ return 9
+ case "power10":
+ return 10
+ }
+ Error = fmt.Errorf("invalid GOPPC64: must be power8, power9, power10")
+ return int(defaultGOPPC64[len("power")] - '0')
+}
+
+type gowasmFeatures struct {
+ SatConv bool
+ SignExt bool
+}
+
+func (f gowasmFeatures) String() string {
+ var flags []string
+ if f.SatConv {
+ flags = append(flags, "satconv")
+ }
+ if f.SignExt {
+ flags = append(flags, "signext")
+ }
+ return strings.Join(flags, ",")
+}
+
+func gowasm() (f gowasmFeatures) {
+ for _, opt := range strings.Split(envOr("GOWASM", ""), ",") {
+ switch opt {
+ case "satconv":
+ f.SatConv = true
+ case "signext":
+ f.SignExt = true
+ case "":
+ // ignore
+ default:
+ Error = fmt.Errorf("invalid GOWASM: no such feature %q", opt)
+ }
+ }
+ return
+}
+
+func Getgoextlinkenabled() string {
+ return envOr("GO_EXTLINK_ENABLED", defaultGO_EXTLINK_ENABLED)
+}
+
+func toolTags() []string {
+ tags := experimentTags()
+ tags = append(tags, gogoarchTags()...)
+ return tags
+}
+
+func experimentTags() []string {
+ var list []string
+ // For each experiment that has been enabled in the toolchain, define a
+ // build tag with the same name but prefixed by "goexperiment." which can be
+ // used for compiling alternative files for the experiment. This allows
+ // changes for the experiment, like extra struct fields in the runtime,
+ // without affecting the base non-experiment code at all.
+ for _, exp := range Experiment.Enabled() {
+ list = append(list, "goexperiment."+exp)
+ }
+ return list
+}
+
+// GOGOARCH returns the name and value of the GO$GOARCH setting.
+// For example, if GOARCH is "amd64" it might return "GOAMD64", "v2".
+func GOGOARCH() (name, value string) {
+ switch GOARCH {
+ case "386":
+ return "GO386", GO386
+ case "amd64":
+ return "GOAMD64", fmt.Sprintf("v%d", GOAMD64)
+ case "arm":
+ return "GOARM", strconv.Itoa(GOARM)
+ case "mips", "mipsle":
+ return "GOMIPS", GOMIPS
+ case "mips64", "mips64le":
+ return "GOMIPS64", GOMIPS64
+ case "ppc64", "ppc64le":
+ return "GOPPC64", fmt.Sprintf("power%d", GOPPC64)
+ case "wasm":
+ return "GOWASM", GOWASM.String()
+ }
+ return "", ""
+}
+
+func gogoarchTags() []string {
+ switch GOARCH {
+ case "386":
+ return []string{GOARCH + "." + GO386}
+ case "amd64":
+ var list []string
+ for i := 1; i <= GOAMD64; i++ {
+ list = append(list, fmt.Sprintf("%s.v%d", GOARCH, i))
+ }
+ return list
+ case "arm":
+ var list []string
+ for i := 5; i <= GOARM; i++ {
+ list = append(list, fmt.Sprintf("%s.%d", GOARCH, i))
+ }
+ return list
+ case "mips", "mipsle":
+ return []string{GOARCH + "." + GOMIPS}
+ case "mips64", "mips64le":
+ return []string{GOARCH + "." + GOMIPS64}
+ case "ppc64", "ppc64le":
+ var list []string
+ for i := 8; i <= GOPPC64; i++ {
+ list = append(list, fmt.Sprintf("%s.power%d", GOARCH, i))
+ }
+ return list
+ case "wasm":
+ var list []string
+ if GOWASM.SatConv {
+ list = append(list, GOARCH+".satconv")
+ }
+ if GOWASM.SignExt {
+ list = append(list, GOARCH+".signext")
+ }
+ return list
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/internal/buildcfg/exp.go b/contrib/go/_std_1.21/src/internal/buildcfg/exp.go
new file mode 100644
index 0000000000..34fad035e9
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/buildcfg/exp.go
@@ -0,0 +1,189 @@
+// 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 buildcfg
+
+import (
+ "fmt"
+ "internal/goexperiment"
+ "reflect"
+ "strings"
+)
+
+// ExperimentFlags represents a set of GOEXPERIMENT flags relative to a baseline
+// (platform-default) experiment configuration.
+type ExperimentFlags struct {
+ goexperiment.Flags
+ baseline goexperiment.Flags
+}
+
+// Experiment contains the toolchain experiments enabled for the
+// current build.
+//
+// (This is not necessarily the set of experiments the compiler itself
+// was built with.)
+//
+// experimentBaseline specifies the experiment flags that are enabled by
+// default in the current toolchain. This is, in effect, the "control"
+// configuration and any variation from this is an experiment.
+var Experiment ExperimentFlags = func() ExperimentFlags {
+ flags, err := ParseGOEXPERIMENT(GOOS, GOARCH, envOr("GOEXPERIMENT", defaultGOEXPERIMENT))
+ if err != nil {
+ Error = err
+ return ExperimentFlags{}
+ }
+ return *flags
+}()
+
+// DefaultGOEXPERIMENT is the embedded default GOEXPERIMENT string.
+// It is not guaranteed to be canonical.
+const DefaultGOEXPERIMENT = defaultGOEXPERIMENT
+
+// FramePointerEnabled enables the use of platform conventions for
+// saving frame pointers.
+//
+// This used to be an experiment, but now it's always enabled on
+// platforms that support it.
+//
+// Note: must agree with runtime.framepointer_enabled.
+var FramePointerEnabled = GOARCH == "amd64" || GOARCH == "arm64"
+
+// ParseGOEXPERIMENT parses a (GOOS, GOARCH, GOEXPERIMENT)
+// configuration tuple and returns the enabled and baseline experiment
+// flag sets.
+//
+// TODO(mdempsky): Move to internal/goexperiment.
+func ParseGOEXPERIMENT(goos, goarch, goexp string) (*ExperimentFlags, error) {
+ // regabiSupported is set to true on platforms where register ABI is
+ // supported and enabled by default.
+ // regabiAlwaysOn is set to true on platforms where register ABI is
+ // always on.
+ var regabiSupported, regabiAlwaysOn bool
+ switch goarch {
+ case "amd64", "arm64", "ppc64le", "ppc64", "riscv64":
+ regabiAlwaysOn = true
+ regabiSupported = true
+ }
+
+ baseline := goexperiment.Flags{
+ RegabiWrappers: regabiSupported,
+ RegabiArgs: regabiSupported,
+ CoverageRedesign: true,
+ }
+
+ // Start with the statically enabled set of experiments.
+ flags := &ExperimentFlags{
+ Flags: baseline,
+ baseline: baseline,
+ }
+
+ // Pick up any changes to the baseline configuration from the
+ // GOEXPERIMENT environment. This can be set at make.bash time
+ // and overridden at build time.
+ if goexp != "" {
+ // Create a map of known experiment names.
+ names := make(map[string]func(bool))
+ rv := reflect.ValueOf(&flags.Flags).Elem()
+ rt := rv.Type()
+ for i := 0; i < rt.NumField(); i++ {
+ field := rv.Field(i)
+ names[strings.ToLower(rt.Field(i).Name)] = field.SetBool
+ }
+
+ // "regabi" is an alias for all working regabi
+ // subexperiments, and not an experiment itself. Doing
+ // this as an alias make both "regabi" and "noregabi"
+ // do the right thing.
+ names["regabi"] = func(v bool) {
+ flags.RegabiWrappers = v
+ flags.RegabiArgs = v
+ }
+
+ // Parse names.
+ for _, f := range strings.Split(goexp, ",") {
+ if f == "" {
+ continue
+ }
+ if f == "none" {
+ // GOEXPERIMENT=none disables all experiment flags.
+ // This is used by cmd/dist, which doesn't know how
+ // to build with any experiment flags.
+ flags.Flags = goexperiment.Flags{}
+ continue
+ }
+ val := true
+ if strings.HasPrefix(f, "no") {
+ f, val = f[2:], false
+ }
+ set, ok := names[f]
+ if !ok {
+ return nil, fmt.Errorf("unknown GOEXPERIMENT %s", f)
+ }
+ set(val)
+ }
+ }
+
+ if regabiAlwaysOn {
+ flags.RegabiWrappers = true
+ flags.RegabiArgs = true
+ }
+ // regabi is only supported on amd64, arm64, riscv64, ppc64 and ppc64le.
+ if !regabiSupported {
+ flags.RegabiWrappers = false
+ flags.RegabiArgs = false
+ }
+ // Check regabi dependencies.
+ if flags.RegabiArgs && !flags.RegabiWrappers {
+ return nil, fmt.Errorf("GOEXPERIMENT regabiargs requires regabiwrappers")
+ }
+ return flags, nil
+}
+
+// String returns the canonical GOEXPERIMENT string to enable this experiment
+// configuration. (Experiments in the same state as in the baseline are elided.)
+func (exp *ExperimentFlags) String() string {
+ return strings.Join(expList(&exp.Flags, &exp.baseline, false), ",")
+}
+
+// expList returns the list of lower-cased experiment names for
+// experiments that differ from base. base may be nil to indicate no
+// experiments. If all is true, then include all experiment flags,
+// regardless of base.
+func expList(exp, base *goexperiment.Flags, all bool) []string {
+ var list []string
+ rv := reflect.ValueOf(exp).Elem()
+ var rBase reflect.Value
+ if base != nil {
+ rBase = reflect.ValueOf(base).Elem()
+ }
+ rt := rv.Type()
+ for i := 0; i < rt.NumField(); i++ {
+ name := strings.ToLower(rt.Field(i).Name)
+ val := rv.Field(i).Bool()
+ baseVal := false
+ if base != nil {
+ baseVal = rBase.Field(i).Bool()
+ }
+ if all || val != baseVal {
+ if val {
+ list = append(list, name)
+ } else {
+ list = append(list, "no"+name)
+ }
+ }
+ }
+ return list
+}
+
+// Enabled returns a list of enabled experiments, as
+// lower-cased experiment names.
+func (exp *ExperimentFlags) Enabled() []string {
+ return expList(&exp.Flags, nil, false)
+}
+
+// All returns a list of all experiment settings.
+// Disabled experiments appear in the list prefixed by "no".
+func (exp *ExperimentFlags) All() []string {
+ return expList(&exp.Flags, nil, true)
+}
diff --git a/contrib/go/_std_1.21/src/internal/buildcfg/ya.make b/contrib/go/_std_1.21/src/internal/buildcfg/ya.make
new file mode 100644
index 0000000000..bc23ca1b37
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/buildcfg/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ cfg.go
+ exp.go
+ zbootstrap.go
+)
+
+GO_TEST_SRCS(cfg_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go b/contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go
new file mode 100644
index 0000000000..f5b4f3486b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/buildcfg/zbootstrap.go
@@ -0,0 +1,18 @@
+// Code generated by go tool dist; DO NOT EDIT.
+
+package buildcfg
+
+import "runtime"
+
+const defaultGO386 = `sse2`
+const defaultGOAMD64 = `v1`
+const defaultGOARM = `7`
+const defaultGOMIPS = `hardfloat`
+const defaultGOMIPS64 = `hardfloat`
+const defaultGOPPC64 = `power8`
+const defaultGOEXPERIMENT = ``
+const defaultGO_EXTLINK_ENABLED = ``
+const defaultGO_LDSO = ``
+const version = `go1.21.3`
+const defaultGOOS = runtime.GOOS
+const defaultGOARCH = runtime.GOARCH
diff --git a/contrib/go/_std_1.21/src/internal/bytealg/bytealg.go b/contrib/go/_std_1.21/src/internal/bytealg/bytealg.go
new file mode 100644
index 0000000000..28f2742c0e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/bytealg/bytealg.go
@@ -0,0 +1,155 @@
+// Copyright 2018 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 bytealg
+
+import (
+ "internal/cpu"
+ "unsafe"
+)
+
+// Offsets into internal/cpu records for use in assembly.
+const (
+ offsetX86HasSSE42 = unsafe.Offsetof(cpu.X86.HasSSE42)
+ offsetX86HasAVX2 = unsafe.Offsetof(cpu.X86.HasAVX2)
+ offsetX86HasPOPCNT = unsafe.Offsetof(cpu.X86.HasPOPCNT)
+
+ offsetS390xHasVX = unsafe.Offsetof(cpu.S390X.HasVX)
+
+ offsetPPC64HasPOWER9 = unsafe.Offsetof(cpu.PPC64.IsPOWER9)
+)
+
+// MaxLen is the maximum length of the string to be searched for (argument b) in Index.
+// If MaxLen is not 0, make sure MaxLen >= 4.
+var MaxLen int
+
+// FIXME: the logic of HashStrBytes, HashStrRevBytes, IndexRabinKarpBytes and HashStr, HashStrRev,
+// IndexRabinKarp are exactly the same, except that the types are different. Can we eliminate
+// three of them without causing allocation?
+
+// PrimeRK is the prime base used in Rabin-Karp algorithm.
+const PrimeRK = 16777619
+
+// HashStrBytes returns the hash and the appropriate multiplicative
+// factor for use in Rabin-Karp algorithm.
+func HashStrBytes(sep []byte) (uint32, uint32) {
+ hash := uint32(0)
+ for i := 0; i < len(sep); i++ {
+ hash = hash*PrimeRK + uint32(sep[i])
+ }
+ var pow, sq uint32 = 1, PrimeRK
+ for i := len(sep); i > 0; i >>= 1 {
+ if i&1 != 0 {
+ pow *= sq
+ }
+ sq *= sq
+ }
+ return hash, pow
+}
+
+// HashStr returns the hash and the appropriate multiplicative
+// factor for use in Rabin-Karp algorithm.
+func HashStr(sep string) (uint32, uint32) {
+ hash := uint32(0)
+ for i := 0; i < len(sep); i++ {
+ hash = hash*PrimeRK + uint32(sep[i])
+ }
+ var pow, sq uint32 = 1, PrimeRK
+ for i := len(sep); i > 0; i >>= 1 {
+ if i&1 != 0 {
+ pow *= sq
+ }
+ sq *= sq
+ }
+ return hash, pow
+}
+
+// HashStrRevBytes returns the hash of the reverse of sep and the
+// appropriate multiplicative factor for use in Rabin-Karp algorithm.
+func HashStrRevBytes(sep []byte) (uint32, uint32) {
+ hash := uint32(0)
+ for i := len(sep) - 1; i >= 0; i-- {
+ hash = hash*PrimeRK + uint32(sep[i])
+ }
+ var pow, sq uint32 = 1, PrimeRK
+ for i := len(sep); i > 0; i >>= 1 {
+ if i&1 != 0 {
+ pow *= sq
+ }
+ sq *= sq
+ }
+ return hash, pow
+}
+
+// HashStrRev returns the hash of the reverse of sep and the
+// appropriate multiplicative factor for use in Rabin-Karp algorithm.
+func HashStrRev(sep string) (uint32, uint32) {
+ hash := uint32(0)
+ for i := len(sep) - 1; i >= 0; i-- {
+ hash = hash*PrimeRK + uint32(sep[i])
+ }
+ var pow, sq uint32 = 1, PrimeRK
+ for i := len(sep); i > 0; i >>= 1 {
+ if i&1 != 0 {
+ pow *= sq
+ }
+ sq *= sq
+ }
+ return hash, pow
+}
+
+// IndexRabinKarpBytes uses the Rabin-Karp search algorithm to return the index of the
+// first occurrence of substr in s, or -1 if not present.
+func IndexRabinKarpBytes(s, sep []byte) int {
+ // Rabin-Karp search
+ hashsep, pow := HashStrBytes(sep)
+ n := len(sep)
+ var h uint32
+ for i := 0; i < n; i++ {
+ h = h*PrimeRK + uint32(s[i])
+ }
+ if h == hashsep && Equal(s[:n], sep) {
+ return 0
+ }
+ for i := n; i < len(s); {
+ h *= PrimeRK
+ h += uint32(s[i])
+ h -= pow * uint32(s[i-n])
+ i++
+ if h == hashsep && Equal(s[i-n:i], sep) {
+ return i - n
+ }
+ }
+ return -1
+}
+
+// IndexRabinKarp uses the Rabin-Karp search algorithm to return the index of the
+// first occurrence of substr in s, or -1 if not present.
+func IndexRabinKarp(s, substr string) int {
+ // Rabin-Karp search
+ hashss, pow := HashStr(substr)
+ n := len(substr)
+ var h uint32
+ for i := 0; i < n; i++ {
+ h = h*PrimeRK + uint32(s[i])
+ }
+ if h == hashss && s[:n] == substr {
+ return 0
+ }
+ for i := n; i < len(s); {
+ h *= PrimeRK
+ h += uint32(s[i])
+ h -= pow * uint32(s[i-n])
+ i++
+ if h == hashss && s[i-n:i] == substr {
+ return i - n
+ }
+ }
+ return -1
+}
+
+// MakeNoZero makes a slice of length and capacity n without zeroing the bytes.
+// It is the caller's responsibility to ensure uninitialized bytes
+// do not leak to the end user.
+func MakeNoZero(n int) []byte
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/compare_amd64.s b/contrib/go/_std_1.21/src/internal/bytealg/compare_amd64.s
index fdd015f560..fdd015f560 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/compare_amd64.s
+++ b/contrib/go/_std_1.21/src/internal/bytealg/compare_amd64.s
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/compare_arm64.s b/contrib/go/_std_1.21/src/internal/bytealg/compare_arm64.s
index cc02c464e8..cc02c464e8 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/compare_arm64.s
+++ b/contrib/go/_std_1.21/src/internal/bytealg/compare_arm64.s
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/compare_native.go b/contrib/go/_std_1.21/src/internal/bytealg/compare_native.go
index e016430075..e016430075 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/compare_native.go
+++ b/contrib/go/_std_1.21/src/internal/bytealg/compare_native.go
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/count_amd64.s b/contrib/go/_std_1.21/src/internal/bytealg/count_amd64.s
index efb17f84b7..efb17f84b7 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/count_amd64.s
+++ b/contrib/go/_std_1.21/src/internal/bytealg/count_amd64.s
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/count_arm64.s b/contrib/go/_std_1.21/src/internal/bytealg/count_arm64.s
index 8cd703d943..8cd703d943 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/count_arm64.s
+++ b/contrib/go/_std_1.21/src/internal/bytealg/count_arm64.s
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/count_native.go b/contrib/go/_std_1.21/src/internal/bytealg/count_native.go
index 90189c9fe0..90189c9fe0 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/count_native.go
+++ b/contrib/go/_std_1.21/src/internal/bytealg/count_native.go
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/equal_amd64.s b/contrib/go/_std_1.21/src/internal/bytealg/equal_amd64.s
index d178a33779..d178a33779 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/equal_amd64.s
+++ b/contrib/go/_std_1.21/src/internal/bytealg/equal_amd64.s
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/equal_arm64.s b/contrib/go/_std_1.21/src/internal/bytealg/equal_arm64.s
index d3aabba587..d3aabba587 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/equal_arm64.s
+++ b/contrib/go/_std_1.21/src/internal/bytealg/equal_arm64.s
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/equal_generic.go b/contrib/go/_std_1.21/src/internal/bytealg/equal_generic.go
index 59bdf8fdd5..59bdf8fdd5 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/equal_generic.go
+++ b/contrib/go/_std_1.21/src/internal/bytealg/equal_generic.go
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/equal_native.go b/contrib/go/_std_1.21/src/internal/bytealg/equal_native.go
index cf3a245bc0..cf3a245bc0 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/equal_native.go
+++ b/contrib/go/_std_1.21/src/internal/bytealg/equal_native.go
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/index_amd64.go b/contrib/go/_std_1.21/src/internal/bytealg/index_amd64.go
index c7a1941e5f..c7a1941e5f 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/index_amd64.go
+++ b/contrib/go/_std_1.21/src/internal/bytealg/index_amd64.go
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/index_amd64.s b/contrib/go/_std_1.21/src/internal/bytealg/index_amd64.s
index 04314917b8..04314917b8 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/index_amd64.s
+++ b/contrib/go/_std_1.21/src/internal/bytealg/index_amd64.s
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/index_arm64.go b/contrib/go/_std_1.21/src/internal/bytealg/index_arm64.go
index e87c109519..e87c109519 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/index_arm64.go
+++ b/contrib/go/_std_1.21/src/internal/bytealg/index_arm64.go
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/index_arm64.s b/contrib/go/_std_1.21/src/internal/bytealg/index_arm64.s
index 3a551a72da..3a551a72da 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/index_arm64.s
+++ b/contrib/go/_std_1.21/src/internal/bytealg/index_arm64.s
diff --git a/contrib/go/_std_1.21/src/internal/bytealg/index_native.go b/contrib/go/_std_1.21/src/internal/bytealg/index_native.go
new file mode 100644
index 0000000000..59c93f9d12
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/bytealg/index_native.go
@@ -0,0 +1,19 @@
+// Copyright 2018 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.
+
+//go:build amd64 || arm64 || s390x || ppc64le || ppc64
+
+package bytealg
+
+// Index returns the index of the first instance of b in a, or -1 if b is not present in a.
+// Requires 2 <= len(b) <= MaxLen.
+//
+//go:noescape
+func Index(a, b []byte) int
+
+// IndexString returns the index of the first instance of b in a, or -1 if b is not present in a.
+// Requires 2 <= len(b) <= MaxLen.
+//
+//go:noescape
+func IndexString(a, b string) int
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/indexbyte_amd64.s b/contrib/go/_std_1.21/src/internal/bytealg/indexbyte_amd64.s
index 1ca70e39e2..1ca70e39e2 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/indexbyte_amd64.s
+++ b/contrib/go/_std_1.21/src/internal/bytealg/indexbyte_amd64.s
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/indexbyte_arm64.s b/contrib/go/_std_1.21/src/internal/bytealg/indexbyte_arm64.s
index 40843fbc5b..40843fbc5b 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/indexbyte_arm64.s
+++ b/contrib/go/_std_1.21/src/internal/bytealg/indexbyte_arm64.s
diff --git a/contrib/go/_std_1.20/src/internal/bytealg/indexbyte_native.go b/contrib/go/_std_1.21/src/internal/bytealg/indexbyte_native.go
index c5bb2df5ea..c5bb2df5ea 100644
--- a/contrib/go/_std_1.20/src/internal/bytealg/indexbyte_native.go
+++ b/contrib/go/_std_1.21/src/internal/bytealg/indexbyte_native.go
diff --git a/contrib/go/_std_1.21/src/internal/bytealg/ya.make b/contrib/go/_std_1.21/src/internal/bytealg/ya.make
new file mode 100644
index 0000000000..46b7e68a11
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/bytealg/ya.make
@@ -0,0 +1,35 @@
+GO_LIBRARY()
+
+SRCS(
+ bytealg.go
+ compare_native.go
+ count_native.go
+ equal_generic.go
+ equal_native.go
+ index_native.go
+ indexbyte_native.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ compare_amd64.s
+ count_amd64.s
+ equal_amd64.s
+ index_amd64.go
+ index_amd64.s
+ indexbyte_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ compare_arm64.s
+ count_arm64.s
+ equal_arm64.s
+ index_arm64.go
+ index_arm64.s
+ indexbyte_arm64.s
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.20/src/internal/coverage/calloc/batchcounteralloc.go b/contrib/go/_std_1.21/src/internal/coverage/calloc/batchcounteralloc.go
index 2b6495d7a2..2b6495d7a2 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/calloc/batchcounteralloc.go
+++ b/contrib/go/_std_1.21/src/internal/coverage/calloc/batchcounteralloc.go
diff --git a/contrib/go/_std_1.20/src/internal/coverage/calloc/ya.make b/contrib/go/_std_1.21/src/internal/coverage/calloc/ya.make
index 96d1e6e2bc..96d1e6e2bc 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/calloc/ya.make
+++ b/contrib/go/_std_1.21/src/internal/coverage/calloc/ya.make
diff --git a/contrib/go/_std_1.21/src/internal/coverage/cformat/format.go b/contrib/go/_std_1.21/src/internal/coverage/cformat/format.go
new file mode 100644
index 0000000000..7e7a2778c7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/cformat/format.go
@@ -0,0 +1,352 @@
+// Copyright 2022 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 cformat
+
+// This package provides apis for producing human-readable summaries
+// of coverage data (e.g. a coverage percentage for a given package or
+// set of packages) and for writing data in the legacy test format
+// emitted by "go test -coverprofile=<outfile>".
+//
+// The model for using these apis is to create a Formatter object,
+// then make a series of calls to SetPackage and AddUnit passing in
+// data read from coverage meta-data and counter-data files. E.g.
+//
+// myformatter := cformat.NewFormatter()
+// ...
+// for each package P in meta-data file: {
+// myformatter.SetPackage(P)
+// for each function F in P: {
+// for each coverable unit U in F: {
+// myformatter.AddUnit(U)
+// }
+// }
+// }
+// myformatter.EmitPercent(os.Stdout, "", true, true)
+// myformatter.EmitTextual(somefile)
+//
+// These apis are linked into tests that are built with "-cover", and
+// called at the end of test execution to produce text output or
+// emit coverage percentages.
+
+import (
+ "fmt"
+ "internal/coverage"
+ "internal/coverage/cmerge"
+ "io"
+ "sort"
+ "text/tabwriter"
+)
+
+type Formatter struct {
+ // Maps import path to package state.
+ pm map[string]*pstate
+ // Records current package being visited.
+ pkg string
+ // Pointer to current package state.
+ p *pstate
+ // Counter mode.
+ cm coverage.CounterMode
+}
+
+// pstate records package-level coverage data state:
+// - a table of functions (file/fname/literal)
+// - a map recording the index/ID of each func encountered so far
+// - a table storing execution count for the coverable units in each func
+type pstate struct {
+ // slice of unique functions
+ funcs []fnfile
+ // maps function to index in slice above (index acts as function ID)
+ funcTable map[fnfile]uint32
+
+ // A table storing coverage counts for each coverable unit.
+ unitTable map[extcu]uint32
+}
+
+// extcu encapsulates a coverable unit within some function.
+type extcu struct {
+ fnfid uint32 // index into p.funcs slice
+ coverage.CoverableUnit
+}
+
+// fnfile is a function-name/file-name tuple.
+type fnfile struct {
+ file string
+ fname string
+ lit bool
+}
+
+func NewFormatter(cm coverage.CounterMode) *Formatter {
+ return &Formatter{
+ pm: make(map[string]*pstate),
+ cm: cm,
+ }
+}
+
+// SetPackage tells the formatter that we're about to visit the
+// coverage data for the package with the specified import path.
+// Note that it's OK to call SetPackage more than once with the
+// same import path; counter data values will be accumulated.
+func (fm *Formatter) SetPackage(importpath string) {
+ if importpath == fm.pkg {
+ return
+ }
+ fm.pkg = importpath
+ ps, ok := fm.pm[importpath]
+ if !ok {
+ ps = new(pstate)
+ fm.pm[importpath] = ps
+ ps.unitTable = make(map[extcu]uint32)
+ ps.funcTable = make(map[fnfile]uint32)
+ }
+ fm.p = ps
+}
+
+// AddUnit passes info on a single coverable unit (file, funcname,
+// literal flag, range of lines, and counter value) to the formatter.
+// Counter values will be accumulated where appropriate.
+func (fm *Formatter) AddUnit(file string, fname string, isfnlit bool, unit coverage.CoverableUnit, count uint32) {
+ if fm.p == nil {
+ panic("AddUnit invoked before SetPackage")
+ }
+ fkey := fnfile{file: file, fname: fname, lit: isfnlit}
+ idx, ok := fm.p.funcTable[fkey]
+ if !ok {
+ idx = uint32(len(fm.p.funcs))
+ fm.p.funcs = append(fm.p.funcs, fkey)
+ fm.p.funcTable[fkey] = idx
+ }
+ ukey := extcu{fnfid: idx, CoverableUnit: unit}
+ pcount := fm.p.unitTable[ukey]
+ var result uint32
+ if fm.cm == coverage.CtrModeSet {
+ if count != 0 || pcount != 0 {
+ result = 1
+ }
+ } else {
+ // Use saturating arithmetic.
+ result, _ = cmerge.SaturatingAdd(pcount, count)
+ }
+ fm.p.unitTable[ukey] = result
+}
+
+// sortUnits sorts a slice of extcu objects in a package according to
+// source position information (e.g. file and line). Note that we don't
+// include function name as part of the sorting criteria, the thinking
+// being that is better to provide things in the original source order.
+func (p *pstate) sortUnits(units []extcu) {
+ sort.Slice(units, func(i, j int) bool {
+ ui := units[i]
+ uj := units[j]
+ ifile := p.funcs[ui.fnfid].file
+ jfile := p.funcs[uj.fnfid].file
+ if ifile != jfile {
+ return ifile < jfile
+ }
+ // NB: not taking function literal flag into account here (no
+ // need, since other fields are guaranteed to be distinct).
+ if units[i].StLine != units[j].StLine {
+ return units[i].StLine < units[j].StLine
+ }
+ if units[i].EnLine != units[j].EnLine {
+ return units[i].EnLine < units[j].EnLine
+ }
+ if units[i].StCol != units[j].StCol {
+ return units[i].StCol < units[j].StCol
+ }
+ if units[i].EnCol != units[j].EnCol {
+ return units[i].EnCol < units[j].EnCol
+ }
+ return units[i].NxStmts < units[j].NxStmts
+ })
+}
+
+// EmitTextual writes the accumulated coverage data in the legacy
+// cmd/cover text format to the writer 'w'. We sort the data items by
+// importpath, source file, and line number before emitting (this sorting
+// is not explicitly mandated by the format, but seems like a good idea
+// for repeatable/deterministic dumps).
+func (fm *Formatter) EmitTextual(w io.Writer) error {
+ if fm.cm == coverage.CtrModeInvalid {
+ panic("internal error, counter mode unset")
+ }
+ if _, err := fmt.Fprintf(w, "mode: %s\n", fm.cm.String()); err != nil {
+ return err
+ }
+ pkgs := make([]string, 0, len(fm.pm))
+ for importpath := range fm.pm {
+ pkgs = append(pkgs, importpath)
+ }
+ sort.Strings(pkgs)
+ for _, importpath := range pkgs {
+ p := fm.pm[importpath]
+ units := make([]extcu, 0, len(p.unitTable))
+ for u := range p.unitTable {
+ units = append(units, u)
+ }
+ p.sortUnits(units)
+ for _, u := range units {
+ count := p.unitTable[u]
+ file := p.funcs[u.fnfid].file
+ if _, err := fmt.Fprintf(w, "%s:%d.%d,%d.%d %d %d\n",
+ file, u.StLine, u.StCol,
+ u.EnLine, u.EnCol, u.NxStmts, count); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// EmitPercent writes out a "percentage covered" string to the writer 'w'.
+func (fm *Formatter) EmitPercent(w io.Writer, covpkgs string, noteEmpty bool, aggregate bool) error {
+ pkgs := make([]string, 0, len(fm.pm))
+ for importpath := range fm.pm {
+ pkgs = append(pkgs, importpath)
+ }
+
+ rep := func(cov, tot uint64) error {
+ if tot != 0 {
+ if _, err := fmt.Fprintf(w, "coverage: %.1f%% of statements%s\n",
+ 100.0*float64(cov)/float64(tot), covpkgs); err != nil {
+ return err
+ }
+ } else if noteEmpty {
+ if _, err := fmt.Fprintf(w, "coverage: [no statements]\n"); err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+
+ sort.Strings(pkgs)
+ var totalStmts, coveredStmts uint64
+ for _, importpath := range pkgs {
+ p := fm.pm[importpath]
+ if !aggregate {
+ totalStmts, coveredStmts = 0, 0
+ }
+ for unit, count := range p.unitTable {
+ nx := uint64(unit.NxStmts)
+ totalStmts += nx
+ if count != 0 {
+ coveredStmts += nx
+ }
+ }
+ if !aggregate {
+ if _, err := fmt.Fprintf(w, "\t%s\t\t", importpath); err != nil {
+ return err
+ }
+ if err := rep(coveredStmts, totalStmts); err != nil {
+ return err
+ }
+ }
+ }
+ if aggregate {
+ if err := rep(coveredStmts, totalStmts); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// EmitFuncs writes out a function-level summary to the writer 'w'. A
+// note on handling function literals: although we collect coverage
+// data for unnamed literals, it probably does not make sense to
+// include them in the function summary since there isn't any good way
+// to name them (this is also consistent with the legacy cmd/cover
+// implementation). We do want to include their counts in the overall
+// summary however.
+func (fm *Formatter) EmitFuncs(w io.Writer) error {
+ if fm.cm == coverage.CtrModeInvalid {
+ panic("internal error, counter mode unset")
+ }
+ perc := func(covered, total uint64) float64 {
+ if total == 0 {
+ total = 1
+ }
+ return 100.0 * float64(covered) / float64(total)
+ }
+ tabber := tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
+ defer tabber.Flush()
+ allStmts := uint64(0)
+ covStmts := uint64(0)
+
+ pkgs := make([]string, 0, len(fm.pm))
+ for importpath := range fm.pm {
+ pkgs = append(pkgs, importpath)
+ }
+ sort.Strings(pkgs)
+
+ // Emit functions for each package, sorted by import path.
+ for _, importpath := range pkgs {
+ p := fm.pm[importpath]
+ if len(p.unitTable) == 0 {
+ continue
+ }
+ units := make([]extcu, 0, len(p.unitTable))
+ for u := range p.unitTable {
+ units = append(units, u)
+ }
+
+ // Within a package, sort the units, then walk through the
+ // sorted array. Each time we hit a new function, emit the
+ // summary entry for the previous function, then make one last
+ // emit call at the end of the loop.
+ p.sortUnits(units)
+ fname := ""
+ ffile := ""
+ flit := false
+ var fline uint32
+ var cstmts, tstmts uint64
+ captureFuncStart := func(u extcu) {
+ fname = p.funcs[u.fnfid].fname
+ ffile = p.funcs[u.fnfid].file
+ flit = p.funcs[u.fnfid].lit
+ fline = u.StLine
+ }
+ emitFunc := func(u extcu) error {
+ // Don't emit entries for function literals (see discussion
+ // in function header comment above).
+ if !flit {
+ if _, err := fmt.Fprintf(tabber, "%s:%d:\t%s\t%.1f%%\n",
+ ffile, fline, fname, perc(cstmts, tstmts)); err != nil {
+ return err
+ }
+ }
+ captureFuncStart(u)
+ allStmts += tstmts
+ covStmts += cstmts
+ tstmts = 0
+ cstmts = 0
+ return nil
+ }
+ for k, u := range units {
+ if k == 0 {
+ captureFuncStart(u)
+ } else {
+ if fname != p.funcs[u.fnfid].fname {
+ // New function; emit entry for previous one.
+ if err := emitFunc(u); err != nil {
+ return err
+ }
+ }
+ }
+ tstmts += uint64(u.NxStmts)
+ count := p.unitTable[u]
+ if count != 0 {
+ cstmts += uint64(u.NxStmts)
+ }
+ }
+ if err := emitFunc(extcu{}); err != nil {
+ return err
+ }
+ }
+ if _, err := fmt.Fprintf(tabber, "%s\t%s\t%.1f%%\n",
+ "total", "(statements)", perc(covStmts, allStmts)); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/internal/coverage/cformat/ya.make b/contrib/go/_std_1.21/src/internal/coverage/cformat/ya.make
new file mode 100644
index 0000000000..ec6645a0ba
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/cformat/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ format.go
+)
+
+GO_XTEST_SRCS(fmt_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/internal/coverage/cmddefs.go b/contrib/go/_std_1.21/src/internal/coverage/cmddefs.go
new file mode 100644
index 0000000000..49376a4665
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/cmddefs.go
@@ -0,0 +1,87 @@
+// Copyright 2022 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 coverage
+
+// CoverPkgConfig is a bundle of information passed from the Go
+// command to the cover command during "go build -cover" runs. The
+// Go command creates and fills in a struct as below, then passes
+// file containing the encoded JSON for the struct to the "cover"
+// tool when instrumenting the source files in a Go package.
+type CoverPkgConfig struct {
+ // File into which cmd/cover should emit summary info
+ // when instrumentation is complete.
+ OutConfig string
+
+ // Import path for the package being instrumented.
+ PkgPath string
+
+ // Package name.
+ PkgName string
+
+ // Instrumentation granularity: one of "perfunc" or "perblock" (default)
+ Granularity string
+
+ // Module path for this package (empty if no go.mod in use)
+ ModulePath string
+
+ // Local mode indicates we're doing a coverage build or test of a
+ // package selected via local import path, e.g. "./..." or
+ // "./foo/bar" as opposed to a non-relative import path. See the
+ // corresponding field in cmd/go's PackageInternal struct for more
+ // info.
+ Local bool
+}
+
+// CoverFixupConfig contains annotations/notes generated by the
+// cmd/cover tool (during instrumentation) to be passed on to the
+// compiler when the instrumented code is compiled. The cmd/cover tool
+// creates a struct of this type, JSON-encodes it, and emits the
+// result to a file, which the Go command then passes to the compiler
+// when the instrumented package is built.
+type CoverFixupConfig struct {
+ // Name of the variable (created by cmd/cover) containing the
+ // encoded meta-data for the package.
+ MetaVar string
+
+ // Length of the meta-data.
+ MetaLen int
+
+ // Hash computed by cmd/cover of the meta-data.
+ MetaHash string
+
+ // Instrumentation strategy. For now this is always set to
+ // "normal", but in the future we may add new values (for example,
+ // if panic paths are instrumented, or if the instrumenter
+ // eliminates redundant counters).
+ Strategy string
+
+ // Prefix assigned to the names of counter variables generated
+ // during instrumentation by cmd/cover.
+ CounterPrefix string
+
+ // Name chosen for the package ID variable generated during
+ // instrumentation.
+ PkgIdVar string
+
+ // Counter mode (e.g. set/count/atomic)
+ CounterMode string
+
+ // Counter granularity (perblock or perfunc).
+ CounterGranularity string
+}
+
+// MetaFilePaths contains information generated by the Go command and
+// the read in by coverage test support functions within an executing
+// "go test -cover" binary.
+type MetaFileCollection struct {
+ ImportPaths []string
+ MetaFileFragments []string
+}
+
+// Name of file within the "go test -cover" temp coverdir directory
+// containing a list of meta-data files for packages being tested
+// in a "go test -coverpkg=... ..." run. This constant is shared
+// by the Go command and by the coverage runtime.
+const MetaFilesFileName = "metafiles.txt"
diff --git a/contrib/go/_std_1.21/src/internal/coverage/cmerge/merge.go b/contrib/go/_std_1.21/src/internal/coverage/cmerge/merge.go
new file mode 100644
index 0000000000..1339803d08
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/cmerge/merge.go
@@ -0,0 +1,127 @@
+// Copyright 2022 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 cmerge
+
+// package cmerge provides a few small utility APIs for helping
+// with merging of counter data for a given function.
+
+import (
+ "fmt"
+ "internal/coverage"
+ "math"
+)
+
+type ModeMergePolicy uint8
+
+const (
+ ModeMergeStrict ModeMergePolicy = iota
+ ModeMergeRelaxed
+)
+
+// Merger provides state and methods to help manage the process of
+// merging together coverage counter data for a given function, for
+// tools that need to implicitly merge counter as they read multiple
+// coverage counter data files.
+type Merger struct {
+ cmode coverage.CounterMode
+ cgran coverage.CounterGranularity
+ policy ModeMergePolicy
+ overflow bool
+}
+
+func (cm *Merger) SetModeMergePolicy(policy ModeMergePolicy) {
+ cm.policy = policy
+}
+
+// MergeCounters takes the counter values in 'src' and merges them
+// into 'dst' according to the correct counter mode.
+func (m *Merger) MergeCounters(dst, src []uint32) (error, bool) {
+ if len(src) != len(dst) {
+ return fmt.Errorf("merging counters: len(dst)=%d len(src)=%d", len(dst), len(src)), false
+ }
+ if m.cmode == coverage.CtrModeSet {
+ for i := 0; i < len(src); i++ {
+ if src[i] != 0 {
+ dst[i] = 1
+ }
+ }
+ } else {
+ for i := 0; i < len(src); i++ {
+ dst[i] = m.SaturatingAdd(dst[i], src[i])
+ }
+ }
+ ovf := m.overflow
+ m.overflow = false
+ return nil, ovf
+}
+
+// Saturating add does a saturating addition of 'dst' and 'src',
+// returning added value or math.MaxUint32 if there is an overflow.
+// Overflows are recorded in case the client needs to track them.
+func (m *Merger) SaturatingAdd(dst, src uint32) uint32 {
+ result, overflow := SaturatingAdd(dst, src)
+ if overflow {
+ m.overflow = true
+ }
+ return result
+}
+
+// Saturating add does a saturating addition of 'dst' and 'src',
+// returning added value or math.MaxUint32 plus an overflow flag.
+func SaturatingAdd(dst, src uint32) (uint32, bool) {
+ d, s := uint64(dst), uint64(src)
+ sum := d + s
+ overflow := false
+ if uint64(uint32(sum)) != sum {
+ overflow = true
+ sum = math.MaxUint32
+ }
+ return uint32(sum), overflow
+}
+
+// SetModeAndGranularity records the counter mode and granularity for
+// the current merge. In the specific case of merging across coverage
+// data files from different binaries, where we're combining data from
+// more than one meta-data file, we need to check for and resolve
+// mode/granularity clashes.
+func (cm *Merger) SetModeAndGranularity(mdf string, cmode coverage.CounterMode, cgran coverage.CounterGranularity) error {
+ if cm.cmode == coverage.CtrModeInvalid {
+ // Set merger mode based on what we're seeing here.
+ cm.cmode = cmode
+ cm.cgran = cgran
+ } else {
+ // Granularity clashes are always errors.
+ if cm.cgran != cgran {
+ return fmt.Errorf("counter granularity clash while reading meta-data file %s: previous file had %s, new file has %s", mdf, cm.cgran.String(), cgran.String())
+ }
+ // Mode clashes are treated as errors if we're using the
+ // default strict policy.
+ if cm.cmode != cmode {
+ if cm.policy == ModeMergeStrict {
+ return fmt.Errorf("counter mode clash while reading meta-data file %s: previous file had %s, new file has %s", mdf, cm.cmode.String(), cmode.String())
+ }
+ // In the case of a relaxed mode merge policy, upgrade
+ // mode if needed.
+ if cm.cmode < cmode {
+ cm.cmode = cmode
+ }
+ }
+ }
+ return nil
+}
+
+func (cm *Merger) ResetModeAndGranularity() {
+ cm.cmode = coverage.CtrModeInvalid
+ cm.cgran = coverage.CtrGranularityInvalid
+ cm.overflow = false
+}
+
+func (cm *Merger) Mode() coverage.CounterMode {
+ return cm.cmode
+}
+
+func (cm *Merger) Granularity() coverage.CounterGranularity {
+ return cm.cgran
+}
diff --git a/contrib/go/_std_1.21/src/internal/coverage/cmerge/ya.make b/contrib/go/_std_1.21/src/internal/coverage/cmerge/ya.make
new file mode 100644
index 0000000000..b9a0d083a6
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/cmerge/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ merge.go
+)
+
+GO_XTEST_SRCS(merge_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/internal/coverage/decodecounter/decodecounterfile.go b/contrib/go/_std_1.21/src/internal/coverage/decodecounter/decodecounterfile.go
new file mode 100644
index 0000000000..83934fe68b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/decodecounter/decodecounterfile.go
@@ -0,0 +1,373 @@
+// 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 decodecounter
+
+import (
+ "encoding/binary"
+ "fmt"
+ "internal/coverage"
+ "internal/coverage/slicereader"
+ "internal/coverage/stringtab"
+ "io"
+ "os"
+ "strconv"
+ "unsafe"
+)
+
+// This file contains helpers for reading counter data files created
+// during the executions of a coverage-instrumented binary.
+
+type CounterDataReader struct {
+ stab *stringtab.Reader
+ args map[string]string
+ osargs []string
+ goarch string // GOARCH setting from run that produced counter data
+ goos string // GOOS setting from run that produced counter data
+ mr io.ReadSeeker
+ hdr coverage.CounterFileHeader
+ ftr coverage.CounterFileFooter
+ shdr coverage.CounterSegmentHeader
+ u32b []byte
+ u8b []byte
+ fcnCount uint32
+ segCount uint32
+ debug bool
+}
+
+func NewCounterDataReader(fn string, rs io.ReadSeeker) (*CounterDataReader, error) {
+ cdr := &CounterDataReader{
+ mr: rs,
+ u32b: make([]byte, 4),
+ u8b: make([]byte, 1),
+ }
+ // Read header
+ if err := binary.Read(rs, binary.LittleEndian, &cdr.hdr); err != nil {
+ return nil, err
+ }
+ if cdr.debug {
+ fmt.Fprintf(os.Stderr, "=-= counter file header: %+v\n", cdr.hdr)
+ }
+ if !checkMagic(cdr.hdr.Magic) {
+ return nil, fmt.Errorf("invalid magic string: not a counter data file")
+ }
+ if cdr.hdr.Version > coverage.CounterFileVersion {
+ return nil, fmt.Errorf("version data incompatibility: reader is %d data is %d", coverage.CounterFileVersion, cdr.hdr.Version)
+ }
+
+ // Read footer.
+ if err := cdr.readFooter(); err != nil {
+ return nil, err
+ }
+ // Seek back to just past the file header.
+ hsz := int64(unsafe.Sizeof(cdr.hdr))
+ if _, err := cdr.mr.Seek(hsz, io.SeekStart); err != nil {
+ return nil, err
+ }
+ // Read preamble for first segment.
+ if err := cdr.readSegmentPreamble(); err != nil {
+ return nil, err
+ }
+ return cdr, nil
+}
+
+func checkMagic(v [4]byte) bool {
+ g := coverage.CovCounterMagic
+ return v[0] == g[0] && v[1] == g[1] && v[2] == g[2] && v[3] == g[3]
+}
+
+func (cdr *CounterDataReader) readFooter() error {
+ ftrSize := int64(unsafe.Sizeof(cdr.ftr))
+ if _, err := cdr.mr.Seek(-ftrSize, io.SeekEnd); err != nil {
+ return err
+ }
+ if err := binary.Read(cdr.mr, binary.LittleEndian, &cdr.ftr); err != nil {
+ return err
+ }
+ if !checkMagic(cdr.ftr.Magic) {
+ return fmt.Errorf("invalid magic string (not a counter data file)")
+ }
+ if cdr.ftr.NumSegments == 0 {
+ return fmt.Errorf("invalid counter data file (no segments)")
+ }
+ return nil
+}
+
+// readSegmentPreamble reads and consumes the segment header, segment string
+// table, and segment args table.
+func (cdr *CounterDataReader) readSegmentPreamble() error {
+ // Read segment header.
+ if err := binary.Read(cdr.mr, binary.LittleEndian, &cdr.shdr); err != nil {
+ return err
+ }
+ if cdr.debug {
+ fmt.Fprintf(os.Stderr, "=-= read counter segment header: %+v", cdr.shdr)
+ fmt.Fprintf(os.Stderr, " FcnEntries=0x%x StrTabLen=0x%x ArgsLen=0x%x\n",
+ cdr.shdr.FcnEntries, cdr.shdr.StrTabLen, cdr.shdr.ArgsLen)
+ }
+
+ // Read string table and args.
+ if err := cdr.readStringTable(); err != nil {
+ return err
+ }
+ if err := cdr.readArgs(); err != nil {
+ return err
+ }
+ // Seek past any padding to bring us up to a 4-byte boundary.
+ if of, err := cdr.mr.Seek(0, io.SeekCurrent); err != nil {
+ return err
+ } else {
+ rem := of % 4
+ if rem != 0 {
+ pad := 4 - rem
+ if _, err := cdr.mr.Seek(pad, io.SeekCurrent); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func (cdr *CounterDataReader) readStringTable() error {
+ b := make([]byte, cdr.shdr.StrTabLen)
+ nr, err := cdr.mr.Read(b)
+ if err != nil {
+ return err
+ }
+ if nr != int(cdr.shdr.StrTabLen) {
+ return fmt.Errorf("error: short read on string table")
+ }
+ slr := slicereader.NewReader(b, false /* not readonly */)
+ cdr.stab = stringtab.NewReader(slr)
+ cdr.stab.Read()
+ return nil
+}
+
+func (cdr *CounterDataReader) readArgs() error {
+ b := make([]byte, cdr.shdr.ArgsLen)
+ nr, err := cdr.mr.Read(b)
+ if err != nil {
+ return err
+ }
+ if nr != int(cdr.shdr.ArgsLen) {
+ return fmt.Errorf("error: short read on args table")
+ }
+ slr := slicereader.NewReader(b, false /* not readonly */)
+ sget := func() (string, error) {
+ kidx := slr.ReadULEB128()
+ if int(kidx) >= cdr.stab.Entries() {
+ return "", fmt.Errorf("malformed string table ref")
+ }
+ return cdr.stab.Get(uint32(kidx)), nil
+ }
+ nents := slr.ReadULEB128()
+ cdr.args = make(map[string]string, int(nents))
+ for i := uint64(0); i < nents; i++ {
+ k, errk := sget()
+ if errk != nil {
+ return errk
+ }
+ v, errv := sget()
+ if errv != nil {
+ return errv
+ }
+ if _, ok := cdr.args[k]; ok {
+ return fmt.Errorf("malformed args table")
+ }
+ cdr.args[k] = v
+ }
+ if argcs, ok := cdr.args["argc"]; ok {
+ argc, err := strconv.Atoi(argcs)
+ if err != nil {
+ return fmt.Errorf("malformed argc in counter data file args section")
+ }
+ cdr.osargs = make([]string, 0, argc)
+ for i := 0; i < argc; i++ {
+ arg := cdr.args[fmt.Sprintf("argv%d", i)]
+ cdr.osargs = append(cdr.osargs, arg)
+ }
+ }
+ if goos, ok := cdr.args["GOOS"]; ok {
+ cdr.goos = goos
+ }
+ if goarch, ok := cdr.args["GOARCH"]; ok {
+ cdr.goarch = goarch
+ }
+ return nil
+}
+
+// OsArgs returns the program arguments (saved from os.Args during
+// the run of the instrumented binary) read from the counter
+// data file. Not all coverage data files will have os.Args values;
+// for example, if a data file is produced by merging coverage
+// data from two distinct runs, no os args will be available (an
+// empty list is returned).
+func (cdr *CounterDataReader) OsArgs() []string {
+ return cdr.osargs
+}
+
+// Goos returns the GOOS setting in effect for the "-cover" binary
+// that produced this counter data file. The GOOS value may be
+// empty in the case where the counter data file was produced
+// from a merge in which more than one GOOS value was present.
+func (cdr *CounterDataReader) Goos() string {
+ return cdr.goos
+}
+
+// Goarch returns the GOARCH setting in effect for the "-cover" binary
+// that produced this counter data file. The GOARCH value may be
+// empty in the case where the counter data file was produced
+// from a merge in which more than one GOARCH value was present.
+func (cdr *CounterDataReader) Goarch() string {
+ return cdr.goarch
+}
+
+// FuncPayload encapsulates the counter data payload for a single
+// function as read from a counter data file.
+type FuncPayload struct {
+ PkgIdx uint32
+ FuncIdx uint32
+ Counters []uint32
+}
+
+// NumSegments returns the number of execution segments in the file.
+func (cdr *CounterDataReader) NumSegments() uint32 {
+ return cdr.ftr.NumSegments
+}
+
+// BeginNextSegment sets up the reader to read the next segment,
+// returning TRUE if we do have another segment to read, or FALSE
+// if we're done with all the segments (also an error if
+// something went wrong).
+func (cdr *CounterDataReader) BeginNextSegment() (bool, error) {
+ if cdr.segCount >= cdr.ftr.NumSegments {
+ return false, nil
+ }
+ cdr.segCount++
+ cdr.fcnCount = 0
+ // Seek past footer from last segment.
+ ftrSize := int64(unsafe.Sizeof(cdr.ftr))
+ if _, err := cdr.mr.Seek(ftrSize, io.SeekCurrent); err != nil {
+ return false, err
+ }
+ // Read preamble for this segment.
+ if err := cdr.readSegmentPreamble(); err != nil {
+ return false, err
+ }
+ return true, nil
+}
+
+// NumFunctionsInSegment returns the number of live functions
+// in the currently selected segment.
+func (cdr *CounterDataReader) NumFunctionsInSegment() uint32 {
+ return uint32(cdr.shdr.FcnEntries)
+}
+
+const supportDeadFunctionsInCounterData = false
+
+// NextFunc reads data for the next function in this current segment
+// into "p", returning TRUE if the read was successful or FALSE
+// if we've read all the functions already (also an error if
+// something went wrong with the read or we hit a premature
+// EOF).
+func (cdr *CounterDataReader) NextFunc(p *FuncPayload) (bool, error) {
+ if cdr.fcnCount >= uint32(cdr.shdr.FcnEntries) {
+ return false, nil
+ }
+ cdr.fcnCount++
+ var rdu32 func() (uint32, error)
+ if cdr.hdr.CFlavor == coverage.CtrULeb128 {
+ rdu32 = func() (uint32, error) {
+ var shift uint
+ var value uint64
+ for {
+ _, err := cdr.mr.Read(cdr.u8b)
+ if err != nil {
+ return 0, err
+ }
+ b := cdr.u8b[0]
+ value |= (uint64(b&0x7F) << shift)
+ if b&0x80 == 0 {
+ break
+ }
+ shift += 7
+ }
+ return uint32(value), nil
+ }
+ } else if cdr.hdr.CFlavor == coverage.CtrRaw {
+ if cdr.hdr.BigEndian {
+ rdu32 = func() (uint32, error) {
+ n, err := cdr.mr.Read(cdr.u32b)
+ if err != nil {
+ return 0, err
+ }
+ if n != 4 {
+ return 0, io.EOF
+ }
+ return binary.BigEndian.Uint32(cdr.u32b), nil
+ }
+ } else {
+ rdu32 = func() (uint32, error) {
+ n, err := cdr.mr.Read(cdr.u32b)
+ if err != nil {
+ return 0, err
+ }
+ if n != 4 {
+ return 0, io.EOF
+ }
+ return binary.LittleEndian.Uint32(cdr.u32b), nil
+ }
+ }
+ } else {
+ panic("internal error: unknown counter flavor")
+ }
+
+ // Alternative/experimental path: one way we could handling writing
+ // out counter data would be to just memcpy the counter segment
+ // out to a file, meaning that a region in the counter memory
+ // corresponding to a dead (never-executed) function would just be
+ // zeroes. The code path below handles this case.
+ var nc uint32
+ var err error
+ if supportDeadFunctionsInCounterData {
+ for {
+ nc, err = rdu32()
+ if err == io.EOF {
+ return false, io.EOF
+ } else if err != nil {
+ break
+ }
+ if nc != 0 {
+ break
+ }
+ }
+ } else {
+ nc, err = rdu32()
+ }
+ if err != nil {
+ return false, err
+ }
+
+ // Read package and func indices.
+ p.PkgIdx, err = rdu32()
+ if err != nil {
+ return false, err
+ }
+ p.FuncIdx, err = rdu32()
+ if err != nil {
+ return false, err
+ }
+ if cap(p.Counters) < 1024 {
+ p.Counters = make([]uint32, 0, 1024)
+ }
+ p.Counters = p.Counters[:0]
+ for i := uint32(0); i < nc; i++ {
+ v, err := rdu32()
+ if err != nil {
+ return false, err
+ }
+ p.Counters = append(p.Counters, v)
+ }
+ return true, nil
+}
diff --git a/contrib/go/_std_1.20/src/internal/coverage/decodecounter/ya.make b/contrib/go/_std_1.21/src/internal/coverage/decodecounter/ya.make
index d761ccb0cf..d761ccb0cf 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/decodecounter/ya.make
+++ b/contrib/go/_std_1.21/src/internal/coverage/decodecounter/ya.make
diff --git a/contrib/go/_std_1.21/src/internal/coverage/decodemeta/decode.go b/contrib/go/_std_1.21/src/internal/coverage/decodemeta/decode.go
new file mode 100644
index 0000000000..fa047c780b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/decodemeta/decode.go
@@ -0,0 +1,136 @@
+// 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 decodemeta
+
+// This package contains APIs and helpers for decoding a single package's
+// meta data "blob" emitted by the compiler when coverage instrumentation
+// is turned on.
+
+import (
+ "encoding/binary"
+ "fmt"
+ "internal/coverage"
+ "internal/coverage/slicereader"
+ "internal/coverage/stringtab"
+ "io"
+ "os"
+)
+
+// See comments in the encodecovmeta package for details on the format.
+
+type CoverageMetaDataDecoder struct {
+ r *slicereader.Reader
+ hdr coverage.MetaSymbolHeader
+ strtab *stringtab.Reader
+ tmp []byte
+ debug bool
+}
+
+func NewCoverageMetaDataDecoder(b []byte, readonly bool) (*CoverageMetaDataDecoder, error) {
+ slr := slicereader.NewReader(b, readonly)
+ x := &CoverageMetaDataDecoder{
+ r: slr,
+ tmp: make([]byte, 0, 256),
+ }
+ if err := x.readHeader(); err != nil {
+ return nil, err
+ }
+ if err := x.readStringTable(); err != nil {
+ return nil, err
+ }
+ return x, nil
+}
+
+func (d *CoverageMetaDataDecoder) readHeader() error {
+ if err := binary.Read(d.r, binary.LittleEndian, &d.hdr); err != nil {
+ return err
+ }
+ if d.debug {
+ fmt.Fprintf(os.Stderr, "=-= after readHeader: %+v\n", d.hdr)
+ }
+ return nil
+}
+
+func (d *CoverageMetaDataDecoder) readStringTable() error {
+ // Seek to the correct location to read the string table.
+ stringTableLocation := int64(coverage.CovMetaHeaderSize + 4*d.hdr.NumFuncs)
+ if _, err := d.r.Seek(stringTableLocation, io.SeekStart); err != nil {
+ return err
+ }
+
+ // Read the table itself.
+ d.strtab = stringtab.NewReader(d.r)
+ d.strtab.Read()
+ return nil
+}
+
+func (d *CoverageMetaDataDecoder) PackagePath() string {
+ return d.strtab.Get(d.hdr.PkgPath)
+}
+
+func (d *CoverageMetaDataDecoder) PackageName() string {
+ return d.strtab.Get(d.hdr.PkgName)
+}
+
+func (d *CoverageMetaDataDecoder) ModulePath() string {
+ return d.strtab.Get(d.hdr.ModulePath)
+}
+
+func (d *CoverageMetaDataDecoder) NumFuncs() uint32 {
+ return d.hdr.NumFuncs
+}
+
+// ReadFunc reads the coverage meta-data for the function with index
+// 'findex', filling it into the FuncDesc pointed to by 'f'.
+func (d *CoverageMetaDataDecoder) ReadFunc(fidx uint32, f *coverage.FuncDesc) error {
+ if fidx >= d.hdr.NumFuncs {
+ return fmt.Errorf("illegal function index")
+ }
+
+ // Seek to the correct location to read the function offset and read it.
+ funcOffsetLocation := int64(coverage.CovMetaHeaderSize + 4*fidx)
+ if _, err := d.r.Seek(funcOffsetLocation, io.SeekStart); err != nil {
+ return err
+ }
+ foff := d.r.ReadUint32()
+
+ // Check assumptions
+ if foff < uint32(funcOffsetLocation) || foff > d.hdr.Length {
+ return fmt.Errorf("malformed func offset %d", foff)
+ }
+
+ // Seek to the correct location to read the function.
+ floc := int64(foff)
+ if _, err := d.r.Seek(floc, io.SeekStart); err != nil {
+ return err
+ }
+
+ // Preamble containing number of units, file, and function.
+ numUnits := uint32(d.r.ReadULEB128())
+ fnameidx := uint32(d.r.ReadULEB128())
+ fileidx := uint32(d.r.ReadULEB128())
+
+ f.Srcfile = d.strtab.Get(fileidx)
+ f.Funcname = d.strtab.Get(fnameidx)
+
+ // Now the units
+ f.Units = f.Units[:0]
+ if cap(f.Units) < int(numUnits) {
+ f.Units = make([]coverage.CoverableUnit, 0, numUnits)
+ }
+ for k := uint32(0); k < numUnits; k++ {
+ f.Units = append(f.Units,
+ coverage.CoverableUnit{
+ StLine: uint32(d.r.ReadULEB128()),
+ StCol: uint32(d.r.ReadULEB128()),
+ EnLine: uint32(d.r.ReadULEB128()),
+ EnCol: uint32(d.r.ReadULEB128()),
+ NxStmts: uint32(d.r.ReadULEB128()),
+ })
+ }
+ lit := d.r.ReadULEB128()
+ f.Lit = lit != 0
+ return nil
+}
diff --git a/contrib/go/_std_1.20/src/internal/coverage/decodemeta/decodefile.go b/contrib/go/_std_1.21/src/internal/coverage/decodemeta/decodefile.go
index 6580dd5402..6580dd5402 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/decodemeta/decodefile.go
+++ b/contrib/go/_std_1.21/src/internal/coverage/decodemeta/decodefile.go
diff --git a/contrib/go/_std_1.20/src/internal/coverage/decodemeta/ya.make b/contrib/go/_std_1.21/src/internal/coverage/decodemeta/ya.make
index 60b27ce04e..60b27ce04e 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/decodemeta/ya.make
+++ b/contrib/go/_std_1.21/src/internal/coverage/decodemeta/ya.make
diff --git a/contrib/go/_std_1.21/src/internal/coverage/defs.go b/contrib/go/_std_1.21/src/internal/coverage/defs.go
new file mode 100644
index 0000000000..8751b9f878
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/defs.go
@@ -0,0 +1,374 @@
+// Copyright 2022 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 coverage
+
+// Types and constants related to the output files written
+// by code coverage tooling. When a coverage-instrumented binary
+// is run, it emits two output files: a meta-data output file, and
+// a counter data output file.
+
+//.....................................................................
+//
+// Meta-data definitions:
+//
+// The meta-data file is composed of a file header, a series of
+// meta-data blobs/sections (one per instrumented package), and an offsets
+// area storing the offsets of each section. Format of the meta-data
+// file looks like:
+//
+// --header----------
+// | magic: [4]byte magic string
+// | version
+// | total length of meta-data file in bytes
+// | numPkgs: number of package entries in file
+// | hash: [16]byte hash of entire meta-data payload
+// | offset to string table section
+// | length of string table
+// | number of entries in string table
+// | counter mode
+// | counter granularity
+// --package offsets table------
+// <offset to pkg 0>
+// <offset to pkg 1>
+// ...
+// --package lengths table------
+// <length of pkg 0>
+// <length of pkg 1>
+// ...
+// --string table------
+// <uleb128 len> 8
+// <data> "somestring"
+// ...
+// --package payloads------
+// <meta-symbol for pkg 0>
+// <meta-symbol for pkg 1>
+// ...
+//
+// Each package payload is a stand-alone blob emitted by the compiler,
+// and does not depend on anything else in the meta-data file. In
+// particular, each blob has it's own string table. Note that the
+// file-level string table is expected to be very short (most strings
+// will be in the meta-data blobs themselves).
+
+// CovMetaMagic holds the magic string for a meta-data file.
+var CovMetaMagic = [4]byte{'\x00', '\x63', '\x76', '\x6d'}
+
+// MetaFilePref is a prefix used when emitting meta-data files; these
+// files are of the form "covmeta.<hash>", where hash is a hash
+// computed from the hashes of all the package meta-data symbols in
+// the program.
+const MetaFilePref = "covmeta"
+
+// MetaFileVersion contains the current (most recent) meta-data file version.
+const MetaFileVersion = 1
+
+// MetaFileHeader stores file header information for a meta-data file.
+type MetaFileHeader struct {
+ Magic [4]byte
+ Version uint32
+ TotalLength uint64
+ Entries uint64
+ MetaFileHash [16]byte
+ StrTabOffset uint32
+ StrTabLength uint32
+ CMode CounterMode
+ CGranularity CounterGranularity
+ _ [6]byte // padding
+}
+
+// MetaSymbolHeader stores header information for a single
+// meta-data blob, e.g. the coverage meta-data payload
+// computed for a given Go package.
+type MetaSymbolHeader struct {
+ Length uint32 // size of meta-symbol payload in bytes
+ PkgName uint32 // string table index
+ PkgPath uint32 // string table index
+ ModulePath uint32 // string table index
+ MetaHash [16]byte
+ _ byte // currently unused
+ _ [3]byte // padding
+ NumFiles uint32
+ NumFuncs uint32
+}
+
+const CovMetaHeaderSize = 16 + 4 + 4 + 4 + 4 + 4 + 4 + 4 // keep in sync with above
+
+// As an example, consider the following Go package:
+//
+// 01: package p
+// 02:
+// 03: var v, w, z int
+// 04:
+// 05: func small(x, y int) int {
+// 06: v++
+// 07: // comment
+// 08: if y == 0 {
+// 09: return x
+// 10: }
+// 11: return (x << 1) ^ (9 / y)
+// 12: }
+// 13:
+// 14: func Medium(q, r int) int {
+// 15: s1 := small(q, r)
+// 16: z += s1
+// 17: s2 := small(r, q)
+// 18: w -= s2
+// 19: return w + z
+// 20: }
+//
+// The meta-data blob for the single package above might look like the
+// following:
+//
+// -- MetaSymbolHeader header----------
+// | size: size of this blob in bytes
+// | packagepath: <path to p>
+// | modulepath: <modpath for p>
+// | nfiles: 1
+// | nfunctions: 2
+// --func offsets table------
+// <offset to func 0>
+// <offset to func 1>
+// --string table (contains all files and functions)------
+// | <uleb128 len> 4
+// | <data> "p.go"
+// | <uleb128 len> 5
+// | <data> "small"
+// | <uleb128 len> 6
+// | <data> "Medium"
+// --func 0------
+// | <uleb128> num units: 3
+// | <uleb128> func name: S1 (index into string table)
+// | <uleb128> file: S0 (index into string table)
+// | <unit 0>: S0 L6 L8 2
+// | <unit 1>: S0 L9 L9 1
+// | <unit 2>: S0 L11 L11 1
+// --func 1------
+// | <uleb128> num units: 1
+// | <uleb128> func name: S2 (index into string table)
+// | <uleb128> file: S0 (index into string table)
+// | <unit 0>: S0 L15 L19 5
+// ---end-----------
+
+// The following types and constants used by the meta-data encoder/decoder.
+
+// FuncDesc encapsulates the meta-data definitions for a single Go function.
+// This version assumes that we're looking at a function before inlining;
+// if we want to capture a post-inlining view of the world, the
+// representations of source positions would need to be a good deal more
+// complicated.
+type FuncDesc struct {
+ Funcname string
+ Srcfile string
+ Units []CoverableUnit
+ Lit bool // true if this is a function literal
+}
+
+// CoverableUnit describes the source characteristics of a single
+// program unit for which we want to gather coverage info. Coverable
+// units are either "simple" or "intraline"; a "simple" coverable unit
+// corresponds to a basic block (region of straight-line code with no
+// jumps or control transfers). An "intraline" unit corresponds to a
+// logical clause nested within some other simple unit. A simple unit
+// will have a zero Parent value; for an intraline unit NxStmts will
+// be zero and Parent will be set to 1 plus the index of the
+// containing simple statement. Example:
+//
+// L7: q := 1
+// L8: x := (y == 101 || launch() == false)
+// L9: r := x * 2
+//
+// For the code above we would have three simple units (one for each
+// line), then an intraline unit describing the "launch() == false"
+// clause in line 8, with Parent pointing to the index of the line 8
+// unit in the units array.
+//
+// Note: in the initial version of the coverage revamp, only simple
+// units will be in use.
+type CoverableUnit struct {
+ StLine, StCol uint32
+ EnLine, EnCol uint32
+ NxStmts uint32
+ Parent uint32
+}
+
+// CounterMode tracks the "flavor" of the coverage counters being
+// used in a given coverage-instrumented program.
+type CounterMode uint8
+
+const (
+ CtrModeInvalid CounterMode = iota
+ CtrModeSet // "set" mode
+ CtrModeCount // "count" mode
+ CtrModeAtomic // "atomic" mode
+ CtrModeRegOnly // registration-only pseudo-mode
+ CtrModeTestMain // testmain pseudo-mode
+)
+
+func (cm CounterMode) String() string {
+ switch cm {
+ case CtrModeSet:
+ return "set"
+ case CtrModeCount:
+ return "count"
+ case CtrModeAtomic:
+ return "atomic"
+ case CtrModeRegOnly:
+ return "regonly"
+ case CtrModeTestMain:
+ return "testmain"
+ }
+ return "<invalid>"
+}
+
+func ParseCounterMode(mode string) CounterMode {
+ var cm CounterMode
+ switch mode {
+ case "set":
+ cm = CtrModeSet
+ case "count":
+ cm = CtrModeCount
+ case "atomic":
+ cm = CtrModeAtomic
+ case "regonly":
+ cm = CtrModeRegOnly
+ case "testmain":
+ cm = CtrModeTestMain
+ default:
+ cm = CtrModeInvalid
+ }
+ return cm
+}
+
+// CounterGranularity tracks the granularity of the coverage counters being
+// used in a given coverage-instrumented program.
+type CounterGranularity uint8
+
+const (
+ CtrGranularityInvalid CounterGranularity = iota
+ CtrGranularityPerBlock
+ CtrGranularityPerFunc
+)
+
+func (cm CounterGranularity) String() string {
+ switch cm {
+ case CtrGranularityPerBlock:
+ return "perblock"
+ case CtrGranularityPerFunc:
+ return "perfunc"
+ }
+ return "<invalid>"
+}
+
+//.....................................................................
+//
+// Counter data definitions:
+//
+
+// A counter data file is composed of a file header followed by one or
+// more "segments" (each segment representing a given run or partial
+// run of a give binary) followed by a footer.
+
+// CovCounterMagic holds the magic string for a coverage counter-data file.
+var CovCounterMagic = [4]byte{'\x00', '\x63', '\x77', '\x6d'}
+
+// CounterFileVersion stores the most recent counter data file version.
+const CounterFileVersion = 1
+
+// CounterFileHeader stores files header information for a counter-data file.
+type CounterFileHeader struct {
+ Magic [4]byte
+ Version uint32
+ MetaHash [16]byte
+ CFlavor CounterFlavor
+ BigEndian bool
+ _ [6]byte // padding
+}
+
+// CounterSegmentHeader encapsulates information about a specific
+// segment in a counter data file, which at the moment contains
+// counters data from a single execution of a coverage-instrumented
+// program. Following the segment header will be the string table and
+// args table, and then (possibly) padding bytes to bring the byte
+// size of the preamble up to a multiple of 4. Immediately following
+// that will be the counter payloads.
+//
+// The "args" section of a segment is used to store annotations
+// describing where the counter data came from; this section is
+// basically a series of key-value pairs (can be thought of as an
+// encoded 'map[string]string'). At the moment we only write os.Args()
+// data to this section, using pairs of the form "argc=<integer>",
+// "argv0=<os.Args[0]>", "argv1=<os.Args[1]>", and so on. In the
+// future the args table may also include things like GOOS/GOARCH
+// values, and/or tags indicating which tests were run to generate the
+// counter data.
+type CounterSegmentHeader struct {
+ FcnEntries uint64
+ StrTabLen uint32
+ ArgsLen uint32
+}
+
+// CounterFileFooter appears at the tail end of a counter data file,
+// and stores the number of segments it contains.
+type CounterFileFooter struct {
+ Magic [4]byte
+ _ [4]byte // padding
+ NumSegments uint32
+ _ [4]byte // padding
+}
+
+// CounterFilePref is the file prefix used when emitting coverage data
+// output files. CounterFileTemplate describes the format of the file
+// name: prefix followed by meta-file hash followed by process ID
+// followed by emit UnixNanoTime.
+const CounterFilePref = "covcounters"
+const CounterFileTempl = "%s.%x.%d.%d"
+const CounterFileRegexp = `^%s\.(\S+)\.(\d+)\.(\d+)+$`
+
+// CounterFlavor describes how function and counters are
+// stored/represented in the counter section of the file.
+type CounterFlavor uint8
+
+const (
+ // "Raw" representation: all values (pkg ID, func ID, num counters,
+ // and counters themselves) are stored as uint32's.
+ CtrRaw CounterFlavor = iota + 1
+
+ // "ULeb" representation: all values (pkg ID, func ID, num counters,
+ // and counters themselves) are stored with ULEB128 encoding.
+ CtrULeb128
+)
+
+func Round4(x int) int {
+ return (x + 3) &^ 3
+}
+
+//.....................................................................
+//
+// Runtime counter data definitions.
+//
+
+// At runtime within a coverage-instrumented program, the "counters"
+// object we associated with instrumented function can be thought of
+// as a struct of the following form:
+//
+// struct {
+// numCtrs uint32
+// pkgid uint32
+// funcid uint32
+// counterArray [numBlocks]uint32
+// }
+//
+// where "numCtrs" is the number of blocks / coverable units within the
+// function, "pkgid" is the unique index assigned to this package by
+// the runtime, "funcid" is the index of this function within its containing
+// package, and "counterArray" stores the actual counters.
+//
+// The counter variable itself is created not as a struct but as a flat
+// array of uint32's; we then use the offsets below to index into it.
+
+const NumCtrsOffset = 0
+const PkgIdOffset = 1
+const FuncIdOffset = 2
+const FirstCtrOffset = 3
diff --git a/contrib/go/_std_1.21/src/internal/coverage/encodecounter/encode.go b/contrib/go/_std_1.21/src/internal/coverage/encodecounter/encode.go
new file mode 100644
index 0000000000..59586730de
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/encodecounter/encode.go
@@ -0,0 +1,297 @@
+// 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 encodecounter
+
+import (
+ "bufio"
+ "encoding/binary"
+ "fmt"
+ "internal/coverage"
+ "internal/coverage/slicewriter"
+ "internal/coverage/stringtab"
+ "internal/coverage/uleb128"
+ "io"
+ "os"
+ "sort"
+)
+
+// This package contains APIs and helpers for encoding initial portions
+// of the counter data files emitted at runtime when coverage instrumentation
+// is enabled. Counter data files may contain multiple segments; the file
+// header and first segment are written via the "Write" method below, and
+// additional segments can then be added using "AddSegment".
+
+type CoverageDataWriter struct {
+ stab *stringtab.Writer
+ w *bufio.Writer
+ csh coverage.CounterSegmentHeader
+ tmp []byte
+ cflavor coverage.CounterFlavor
+ segs uint32
+ debug bool
+}
+
+func NewCoverageDataWriter(w io.Writer, flav coverage.CounterFlavor) *CoverageDataWriter {
+ r := &CoverageDataWriter{
+ stab: &stringtab.Writer{},
+ w: bufio.NewWriter(w),
+
+ tmp: make([]byte, 64),
+ cflavor: flav,
+ }
+ r.stab.InitWriter()
+ r.stab.Lookup("")
+ return r
+}
+
+// CounterVisitor describes a helper object used during counter file
+// writing; when writing counter data files, clients pass a
+// CounterVisitor to the write/emit routines, then the expectation is
+// that the VisitFuncs method will then invoke the callback "f" with
+// data for each function to emit to the file.
+type CounterVisitor interface {
+ VisitFuncs(f CounterVisitorFn) error
+}
+
+// CounterVisitorFn describes a callback function invoked when writing
+// coverage counter data.
+type CounterVisitorFn func(pkid uint32, funcid uint32, counters []uint32) error
+
+// Write writes the contents of the count-data file to the writer
+// previously supplied to NewCoverageDataWriter. Returns an error
+// if something went wrong somewhere with the write.
+func (cfw *CoverageDataWriter) Write(metaFileHash [16]byte, args map[string]string, visitor CounterVisitor) error {
+ if err := cfw.writeHeader(metaFileHash); err != nil {
+ return err
+ }
+ return cfw.AppendSegment(args, visitor)
+}
+
+func padToFourByteBoundary(ws *slicewriter.WriteSeeker) error {
+ sz := len(ws.BytesWritten())
+ zeros := []byte{0, 0, 0, 0}
+ rem := uint32(sz) % 4
+ if rem != 0 {
+ pad := zeros[:(4 - rem)]
+ if nw, err := ws.Write(pad); err != nil {
+ return err
+ } else if nw != len(pad) {
+ return fmt.Errorf("error: short write")
+ }
+ }
+ return nil
+}
+
+func (cfw *CoverageDataWriter) patchSegmentHeader(ws *slicewriter.WriteSeeker) error {
+ // record position
+ off, err := ws.Seek(0, io.SeekCurrent)
+ if err != nil {
+ return fmt.Errorf("error seeking in patchSegmentHeader: %v", err)
+ }
+ // seek back to start so that we can update the segment header
+ if _, err := ws.Seek(0, io.SeekStart); err != nil {
+ return fmt.Errorf("error seeking in patchSegmentHeader: %v", err)
+ }
+ if cfw.debug {
+ fmt.Fprintf(os.Stderr, "=-= writing counter segment header: %+v", cfw.csh)
+ }
+ if err := binary.Write(ws, binary.LittleEndian, cfw.csh); err != nil {
+ return err
+ }
+ // ... and finally return to the original offset.
+ if _, err := ws.Seek(off, io.SeekStart); err != nil {
+ return fmt.Errorf("error seeking in patchSegmentHeader: %v", err)
+ }
+ return nil
+}
+
+func (cfw *CoverageDataWriter) writeSegmentPreamble(args map[string]string, ws *slicewriter.WriteSeeker) error {
+ if err := binary.Write(ws, binary.LittleEndian, cfw.csh); err != nil {
+ return err
+ }
+ hdrsz := uint32(len(ws.BytesWritten()))
+
+ // Write string table and args to a byte slice (since we need
+ // to capture offsets at various points), then emit the slice
+ // once we are done.
+ cfw.stab.Freeze()
+ if err := cfw.stab.Write(ws); err != nil {
+ return err
+ }
+ cfw.csh.StrTabLen = uint32(len(ws.BytesWritten())) - hdrsz
+
+ akeys := make([]string, 0, len(args))
+ for k := range args {
+ akeys = append(akeys, k)
+ }
+ sort.Strings(akeys)
+
+ wrULEB128 := func(v uint) error {
+ cfw.tmp = cfw.tmp[:0]
+ cfw.tmp = uleb128.AppendUleb128(cfw.tmp, v)
+ if _, err := ws.Write(cfw.tmp); err != nil {
+ return err
+ }
+ return nil
+ }
+
+ // Count of arg pairs.
+ if err := wrULEB128(uint(len(args))); err != nil {
+ return err
+ }
+ // Arg pairs themselves.
+ for _, k := range akeys {
+ ki := uint(cfw.stab.Lookup(k))
+ if err := wrULEB128(ki); err != nil {
+ return err
+ }
+ v := args[k]
+ vi := uint(cfw.stab.Lookup(v))
+ if err := wrULEB128(vi); err != nil {
+ return err
+ }
+ }
+ if err := padToFourByteBoundary(ws); err != nil {
+ return err
+ }
+ cfw.csh.ArgsLen = uint32(len(ws.BytesWritten())) - (cfw.csh.StrTabLen + hdrsz)
+
+ return nil
+}
+
+// AppendSegment appends a new segment to a counter data, with a new
+// args section followed by a payload of counter data clauses.
+func (cfw *CoverageDataWriter) AppendSegment(args map[string]string, visitor CounterVisitor) error {
+ cfw.stab = &stringtab.Writer{}
+ cfw.stab.InitWriter()
+ cfw.stab.Lookup("")
+
+ var err error
+ for k, v := range args {
+ cfw.stab.Lookup(k)
+ cfw.stab.Lookup(v)
+ }
+
+ ws := &slicewriter.WriteSeeker{}
+ if err = cfw.writeSegmentPreamble(args, ws); err != nil {
+ return err
+ }
+ if err = cfw.writeCounters(visitor, ws); err != nil {
+ return err
+ }
+ if err = cfw.patchSegmentHeader(ws); err != nil {
+ return err
+ }
+ if err := cfw.writeBytes(ws.BytesWritten()); err != nil {
+ return err
+ }
+ if err = cfw.writeFooter(); err != nil {
+ return err
+ }
+ if err := cfw.w.Flush(); err != nil {
+ return fmt.Errorf("write error: %v", err)
+ }
+ cfw.stab = nil
+ return nil
+}
+
+func (cfw *CoverageDataWriter) writeHeader(metaFileHash [16]byte) error {
+ // Emit file header.
+ ch := coverage.CounterFileHeader{
+ Magic: coverage.CovCounterMagic,
+ Version: coverage.CounterFileVersion,
+ MetaHash: metaFileHash,
+ CFlavor: cfw.cflavor,
+ BigEndian: false,
+ }
+ if err := binary.Write(cfw.w, binary.LittleEndian, ch); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (cfw *CoverageDataWriter) writeBytes(b []byte) error {
+ if len(b) == 0 {
+ return nil
+ }
+ nw, err := cfw.w.Write(b)
+ if err != nil {
+ return fmt.Errorf("error writing counter data: %v", err)
+ }
+ if len(b) != nw {
+ return fmt.Errorf("error writing counter data: short write")
+ }
+ return nil
+}
+
+func (cfw *CoverageDataWriter) writeCounters(visitor CounterVisitor, ws *slicewriter.WriteSeeker) error {
+ // Notes:
+ // - this version writes everything little-endian, which means
+ // a call is needed to encode every value (expensive)
+ // - we may want to move to a model in which we just blast out
+ // all counters, or possibly mmap the file and do the write
+ // implicitly.
+ ctrb := make([]byte, 4)
+ wrval := func(val uint32) error {
+ var buf []byte
+ var towr int
+ if cfw.cflavor == coverage.CtrRaw {
+ binary.LittleEndian.PutUint32(ctrb, val)
+ buf = ctrb
+ towr = 4
+ } else if cfw.cflavor == coverage.CtrULeb128 {
+ cfw.tmp = cfw.tmp[:0]
+ cfw.tmp = uleb128.AppendUleb128(cfw.tmp, uint(val))
+ buf = cfw.tmp
+ towr = len(buf)
+ } else {
+ panic("internal error: bad counter flavor")
+ }
+ if sz, err := ws.Write(buf); err != nil {
+ return err
+ } else if sz != towr {
+ return fmt.Errorf("writing counters: short write")
+ }
+ return nil
+ }
+
+ // Write out entries for each live function.
+ emitter := func(pkid uint32, funcid uint32, counters []uint32) error {
+ cfw.csh.FcnEntries++
+ if err := wrval(uint32(len(counters))); err != nil {
+ return err
+ }
+
+ if err := wrval(pkid); err != nil {
+ return err
+ }
+
+ if err := wrval(funcid); err != nil {
+ return err
+ }
+ for _, val := range counters {
+ if err := wrval(val); err != nil {
+ return err
+ }
+ }
+ return nil
+ }
+ if err := visitor.VisitFuncs(emitter); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (cfw *CoverageDataWriter) writeFooter() error {
+ cfw.segs++
+ cf := coverage.CounterFileFooter{
+ Magic: coverage.CovCounterMagic,
+ NumSegments: cfw.segs,
+ }
+ if err := binary.Write(cfw.w, binary.LittleEndian, cf); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.20/src/internal/coverage/encodecounter/ya.make b/contrib/go/_std_1.21/src/internal/coverage/encodecounter/ya.make
index fb82cc2fd2..fb82cc2fd2 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/encodecounter/ya.make
+++ b/contrib/go/_std_1.21/src/internal/coverage/encodecounter/ya.make
diff --git a/contrib/go/_std_1.20/src/internal/coverage/encodemeta/encode.go b/contrib/go/_std_1.21/src/internal/coverage/encodemeta/encode.go
index d211c7c08e..d211c7c08e 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/encodemeta/encode.go
+++ b/contrib/go/_std_1.21/src/internal/coverage/encodemeta/encode.go
diff --git a/contrib/go/_std_1.20/src/internal/coverage/encodemeta/encodefile.go b/contrib/go/_std_1.21/src/internal/coverage/encodemeta/encodefile.go
index 38ae46e4f5..38ae46e4f5 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/encodemeta/encodefile.go
+++ b/contrib/go/_std_1.21/src/internal/coverage/encodemeta/encodefile.go
diff --git a/contrib/go/_std_1.20/src/internal/coverage/encodemeta/ya.make b/contrib/go/_std_1.21/src/internal/coverage/encodemeta/ya.make
index ecc0df9460..ecc0df9460 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/encodemeta/ya.make
+++ b/contrib/go/_std_1.21/src/internal/coverage/encodemeta/ya.make
diff --git a/contrib/go/_std_1.20/src/internal/coverage/pkid.go b/contrib/go/_std_1.21/src/internal/coverage/pkid.go
index 8ddd44d6bb..8ddd44d6bb 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/pkid.go
+++ b/contrib/go/_std_1.21/src/internal/coverage/pkid.go
diff --git a/contrib/go/_std_1.21/src/internal/coverage/pods/pods.go b/contrib/go/_std_1.21/src/internal/coverage/pods/pods.go
new file mode 100644
index 0000000000..e08f82ec59
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/pods/pods.go
@@ -0,0 +1,197 @@
+// Copyright 2022 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 pods
+
+import (
+ "fmt"
+ "internal/coverage"
+ "os"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strconv"
+)
+
+// Pod encapsulates a set of files emitted during the executions of a
+// coverage-instrumented binary. Each pod contains a single meta-data
+// file, and then 0 or more counter data files that refer to that
+// meta-data file. Pods are intended to simplify processing of
+// coverage output files in the case where we have several coverage
+// output directories containing output files derived from more
+// than one instrumented executable. In the case where the files that
+// make up a pod are spread out across multiple directories, each
+// element of the "Origins" field below will be populated with the
+// index of the originating directory for the corresponding counter
+// data file (within the slice of input dirs handed to CollectPods).
+// The ProcessIDs field will be populated with the process ID of each
+// data file in the CounterDataFiles slice.
+type Pod struct {
+ MetaFile string
+ CounterDataFiles []string
+ Origins []int
+ ProcessIDs []int
+}
+
+// CollectPods visits the files contained within the directories in
+// the list 'dirs', collects any coverage-related files, partitions
+// them into pods, and returns a list of the pods to the caller, along
+// with an error if something went wrong during directory/file
+// reading.
+//
+// CollectPods skips over any file that is not related to coverage
+// (e.g. avoids looking at things that are not meta-data files or
+// counter-data files). CollectPods also skips over 'orphaned' counter
+// data files (e.g. counter data files for which we can't find the
+// corresponding meta-data file). If "warn" is true, CollectPods will
+// issue warnings to stderr when it encounters non-fatal problems (for
+// orphans or a directory with no meta-data files).
+func CollectPods(dirs []string, warn bool) ([]Pod, error) {
+ files := []string{}
+ dirIndices := []int{}
+ for k, dir := range dirs {
+ dents, err := os.ReadDir(dir)
+ if err != nil {
+ return nil, err
+ }
+ for _, e := range dents {
+ if e.IsDir() {
+ continue
+ }
+ files = append(files, filepath.Join(dir, e.Name()))
+ dirIndices = append(dirIndices, k)
+ }
+ }
+ return collectPodsImpl(files, dirIndices, warn), nil
+}
+
+// CollectPodsFromFiles functions the same as "CollectPods" but
+// operates on an explicit list of files instead of a directory.
+func CollectPodsFromFiles(files []string, warn bool) []Pod {
+ return collectPodsImpl(files, nil, warn)
+}
+
+type fileWithAnnotations struct {
+ file string
+ origin int
+ pid int
+}
+
+type protoPod struct {
+ mf string
+ elements []fileWithAnnotations
+}
+
+// collectPodsImpl examines the specified list of files and picks out
+// subsets that correspond to coverage pods. The first stage in this
+// process is collecting a set { M1, M2, ... MN } where each M_k is a
+// distinct coverage meta-data file. We then create a single pod for
+// each meta-data file M_k, then find all of the counter data files
+// that refer to that meta-data file (recall that the counter data
+// file name incorporates the meta-data hash), and add the counter
+// data file to the appropriate pod.
+//
+// This process is complicated by the fact that we need to keep track
+// of directory indices for counter data files. Here is an example to
+// motivate:
+//
+// directory 1:
+//
+// M1 covmeta.9bbf1777f47b3fcacb05c38b035512d6
+// C1 covcounters.9bbf1777f47b3fcacb05c38b035512d6.1677673.1662138360208416486
+// C2 covcounters.9bbf1777f47b3fcacb05c38b035512d6.1677637.1662138359974441782
+//
+// directory 2:
+//
+// M2 covmeta.9bbf1777f47b3fcacb05c38b035512d6
+// C3 covcounters.9bbf1777f47b3fcacb05c38b035512d6.1677445.1662138360208416480
+// C4 covcounters.9bbf1777f47b3fcacb05c38b035512d6.1677677.1662138359974441781
+// M3 covmeta.a723844208cea2ae80c63482c78b2245
+// C5 covcounters.a723844208cea2ae80c63482c78b2245.3677445.1662138360208416480
+// C6 covcounters.a723844208cea2ae80c63482c78b2245.1877677.1662138359974441781
+//
+// In these two directories we have three meta-data files, but only
+// two are distinct, meaning that we'll wind up with two pods. The
+// first pod (with meta-file M1) will have four counter data files
+// (C1, C2, C3, C4) and the second pod will have two counter data files
+// (C5, C6).
+func collectPodsImpl(files []string, dirIndices []int, warn bool) []Pod {
+ metaRE := regexp.MustCompile(fmt.Sprintf(`^%s\.(\S+)$`, coverage.MetaFilePref))
+ mm := make(map[string]protoPod)
+ for _, f := range files {
+ base := filepath.Base(f)
+ if m := metaRE.FindStringSubmatch(base); m != nil {
+ tag := m[1]
+ // We need to allow for the possibility of duplicate
+ // meta-data files. If we hit this case, use the
+ // first encountered as the canonical version.
+ if _, ok := mm[tag]; !ok {
+ mm[tag] = protoPod{mf: f}
+ }
+ // FIXME: should probably check file length and hash here for
+ // the duplicate.
+ }
+ }
+ counterRE := regexp.MustCompile(fmt.Sprintf(coverage.CounterFileRegexp, coverage.CounterFilePref))
+ for k, f := range files {
+ base := filepath.Base(f)
+ if m := counterRE.FindStringSubmatch(base); m != nil {
+ tag := m[1] // meta hash
+ pid, err := strconv.Atoi(m[2])
+ if err != nil {
+ continue
+ }
+ if v, ok := mm[tag]; ok {
+ idx := -1
+ if dirIndices != nil {
+ idx = dirIndices[k]
+ }
+ fo := fileWithAnnotations{file: f, origin: idx, pid: pid}
+ v.elements = append(v.elements, fo)
+ mm[tag] = v
+ } else {
+ if warn {
+ warning("skipping orphaned counter file: %s", f)
+ }
+ }
+ }
+ }
+ if len(mm) == 0 {
+ if warn {
+ warning("no coverage data files found")
+ }
+ return nil
+ }
+ pods := make([]Pod, 0, len(mm))
+ for _, p := range mm {
+ sort.Slice(p.elements, func(i, j int) bool {
+ if p.elements[i].origin != p.elements[j].origin {
+ return p.elements[i].origin < p.elements[j].origin
+ }
+ return p.elements[i].file < p.elements[j].file
+ })
+ pod := Pod{
+ MetaFile: p.mf,
+ CounterDataFiles: make([]string, 0, len(p.elements)),
+ Origins: make([]int, 0, len(p.elements)),
+ ProcessIDs: make([]int, 0, len(p.elements)),
+ }
+ for _, e := range p.elements {
+ pod.CounterDataFiles = append(pod.CounterDataFiles, e.file)
+ pod.Origins = append(pod.Origins, e.origin)
+ pod.ProcessIDs = append(pod.ProcessIDs, e.pid)
+ }
+ pods = append(pods, pod)
+ }
+ sort.Slice(pods, func(i, j int) bool {
+ return pods[i].MetaFile < pods[j].MetaFile
+ })
+ return pods
+}
+
+func warning(s string, a ...interface{}) {
+ fmt.Fprintf(os.Stderr, "warning: ")
+ fmt.Fprintf(os.Stderr, s, a...)
+ fmt.Fprintf(os.Stderr, "\n")
+}
diff --git a/contrib/go/_std_1.21/src/internal/coverage/pods/ya.make b/contrib/go/_std_1.21/src/internal/coverage/pods/ya.make
new file mode 100644
index 0000000000..0d88aa13c6
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/pods/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ pods.go
+)
+
+GO_XTEST_SRCS(pods_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/coverage/rtcov/rtcov.go b/contrib/go/_std_1.21/src/internal/coverage/rtcov/rtcov.go
index bbb93acced..bbb93acced 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/rtcov/rtcov.go
+++ b/contrib/go/_std_1.21/src/internal/coverage/rtcov/rtcov.go
diff --git a/contrib/go/_std_1.20/src/internal/coverage/rtcov/ya.make b/contrib/go/_std_1.21/src/internal/coverage/rtcov/ya.make
index b686d3174e..b686d3174e 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/rtcov/ya.make
+++ b/contrib/go/_std_1.21/src/internal/coverage/rtcov/ya.make
diff --git a/contrib/go/_std_1.21/src/internal/coverage/slicereader/slicereader.go b/contrib/go/_std_1.21/src/internal/coverage/slicereader/slicereader.go
new file mode 100644
index 0000000000..d9f2a7eac4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/slicereader/slicereader.go
@@ -0,0 +1,123 @@
+// 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 slicereader
+
+import (
+ "encoding/binary"
+ "fmt"
+ "io"
+ "unsafe"
+)
+
+// This file contains the helper "SliceReader", a utility for
+// reading values from a byte slice that may or may not be backed
+// by a read-only mmap'd region.
+
+type Reader struct {
+ b []byte
+ readonly bool
+ off int64
+}
+
+func NewReader(b []byte, readonly bool) *Reader {
+ r := Reader{
+ b: b,
+ readonly: readonly,
+ }
+ return &r
+}
+
+func (r *Reader) Read(b []byte) (int, error) {
+ amt := len(b)
+ toread := r.b[r.off:]
+ if len(toread) < amt {
+ amt = len(toread)
+ }
+ copy(b, toread)
+ r.off += int64(amt)
+ return amt, nil
+}
+
+func (r *Reader) Seek(offset int64, whence int) (ret int64, err error) {
+ switch whence {
+ case io.SeekStart:
+ if offset < 0 || offset > int64(len(r.b)) {
+ return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", offset, len(r.b))
+ }
+ r.off = offset
+ return offset, nil
+ case io.SeekCurrent:
+ newoff := r.off + offset
+ if newoff < 0 || newoff > int64(len(r.b)) {
+ return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", newoff, len(r.b))
+ }
+ r.off = newoff
+ return r.off, nil
+ case io.SeekEnd:
+ newoff := int64(len(r.b)) + offset
+ if newoff < 0 || newoff > int64(len(r.b)) {
+ return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", newoff, len(r.b))
+ }
+ r.off = newoff
+ return r.off, nil
+ }
+ // other modes are not supported
+ return 0, fmt.Errorf("unsupported seek mode %d", whence)
+}
+
+func (r *Reader) Offset() int64 {
+ return r.off
+}
+
+func (r *Reader) ReadUint8() uint8 {
+ rv := uint8(r.b[int(r.off)])
+ r.off += 1
+ return rv
+}
+
+func (r *Reader) ReadUint32() uint32 {
+ end := int(r.off) + 4
+ rv := binary.LittleEndian.Uint32(r.b[int(r.off):end:end])
+ r.off += 4
+ return rv
+}
+
+func (r *Reader) ReadUint64() uint64 {
+ end := int(r.off) + 8
+ rv := binary.LittleEndian.Uint64(r.b[int(r.off):end:end])
+ r.off += 8
+ return rv
+}
+
+func (r *Reader) ReadULEB128() (value uint64) {
+ var shift uint
+
+ for {
+ b := r.b[r.off]
+ r.off++
+ value |= (uint64(b&0x7F) << shift)
+ if b&0x80 == 0 {
+ break
+ }
+ shift += 7
+ }
+ return
+}
+
+func (r *Reader) ReadString(len int64) string {
+ b := r.b[r.off : r.off+len]
+ r.off += len
+ if r.readonly {
+ return toString(b) // backed by RO memory, ok to make unsafe string
+ }
+ return string(b)
+}
+
+func toString(b []byte) string {
+ if len(b) == 0 {
+ return ""
+ }
+ return unsafe.String(&b[0], len(b))
+}
diff --git a/contrib/go/_std_1.21/src/internal/coverage/slicereader/ya.make b/contrib/go/_std_1.21/src/internal/coverage/slicereader/ya.make
new file mode 100644
index 0000000000..109b64c8be
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/slicereader/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ slicereader.go
+)
+
+GO_TEST_SRCS(slr_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/internal/coverage/slicewriter/slicewriter.go b/contrib/go/_std_1.21/src/internal/coverage/slicewriter/slicewriter.go
new file mode 100644
index 0000000000..460e9dc98c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/slicewriter/slicewriter.go
@@ -0,0 +1,80 @@
+// Copyright 2022 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 slicewriter
+
+import (
+ "fmt"
+ "io"
+)
+
+// WriteSeeker is a helper object that implements the io.WriteSeeker
+// interface. Clients can create a WriteSeeker, make a series of Write
+// calls to add data to it (and possibly Seek calls to update
+// previously written portions), then finally invoke BytesWritten() to
+// get a pointer to the constructed byte slice.
+type WriteSeeker struct {
+ payload []byte
+ off int64
+}
+
+func (sws *WriteSeeker) Write(p []byte) (n int, err error) {
+ amt := len(p)
+ towrite := sws.payload[sws.off:]
+ if len(towrite) < amt {
+ sws.payload = append(sws.payload, make([]byte, amt-len(towrite))...)
+ towrite = sws.payload[sws.off:]
+ }
+ copy(towrite, p)
+ sws.off += int64(amt)
+ return amt, nil
+}
+
+// Seek repositions the read/write position of the WriteSeeker within
+// its internally maintained slice. Note that it is not possible to
+// expand the size of the slice using SEEK_SET; trying to seek outside
+// the slice will result in an error.
+func (sws *WriteSeeker) Seek(offset int64, whence int) (int64, error) {
+ switch whence {
+ case io.SeekStart:
+ if sws.off != offset && (offset < 0 || offset > int64(len(sws.payload))) {
+ return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", offset, len(sws.payload))
+ }
+ sws.off = offset
+ return offset, nil
+ case io.SeekCurrent:
+ newoff := sws.off + offset
+ if newoff != sws.off && (newoff < 0 || newoff > int64(len(sws.payload))) {
+ return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", newoff, len(sws.payload))
+ }
+ sws.off += offset
+ return sws.off, nil
+ case io.SeekEnd:
+ newoff := int64(len(sws.payload)) + offset
+ if newoff != sws.off && (newoff < 0 || newoff > int64(len(sws.payload))) {
+ return 0, fmt.Errorf("invalid seek: new offset %d (out of range [0 %d]", newoff, len(sws.payload))
+ }
+ sws.off = newoff
+ return sws.off, nil
+ }
+ // other modes not supported
+ return 0, fmt.Errorf("unsupported seek mode %d", whence)
+}
+
+// BytesWritten returns the underlying byte slice for the WriteSeeker,
+// containing the data written to it via Write/Seek calls.
+func (sws *WriteSeeker) BytesWritten() []byte {
+ return sws.payload
+}
+
+func (sws *WriteSeeker) Read(p []byte) (n int, err error) {
+ amt := len(p)
+ toread := sws.payload[sws.off:]
+ if len(toread) < amt {
+ amt = len(toread)
+ }
+ copy(p, toread)
+ sws.off += int64(amt)
+ return amt, nil
+}
diff --git a/contrib/go/_std_1.21/src/internal/coverage/slicewriter/ya.make b/contrib/go/_std_1.21/src/internal/coverage/slicewriter/ya.make
new file mode 100644
index 0000000000..e4c1089366
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/slicewriter/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ slicewriter.go
+)
+
+GO_TEST_SRCS(slw_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/coverage/stringtab/stringtab.go b/contrib/go/_std_1.21/src/internal/coverage/stringtab/stringtab.go
index 156c8ad188..156c8ad188 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/stringtab/stringtab.go
+++ b/contrib/go/_std_1.21/src/internal/coverage/stringtab/stringtab.go
diff --git a/contrib/go/_std_1.20/src/internal/coverage/stringtab/ya.make b/contrib/go/_std_1.21/src/internal/coverage/stringtab/ya.make
index 805422b402..805422b402 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/stringtab/ya.make
+++ b/contrib/go/_std_1.21/src/internal/coverage/stringtab/ya.make
diff --git a/contrib/go/_std_1.20/src/internal/coverage/uleb128/uleb128.go b/contrib/go/_std_1.21/src/internal/coverage/uleb128/uleb128.go
index e5cd92a03e..e5cd92a03e 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/uleb128/uleb128.go
+++ b/contrib/go/_std_1.21/src/internal/coverage/uleb128/uleb128.go
diff --git a/contrib/go/_std_1.20/src/internal/coverage/uleb128/ya.make b/contrib/go/_std_1.21/src/internal/coverage/uleb128/ya.make
index 94fc7ea345..94fc7ea345 100644
--- a/contrib/go/_std_1.20/src/internal/coverage/uleb128/ya.make
+++ b/contrib/go/_std_1.21/src/internal/coverage/uleb128/ya.make
diff --git a/contrib/go/_std_1.21/src/internal/coverage/ya.make b/contrib/go/_std_1.21/src/internal/coverage/ya.make
new file mode 100644
index 0000000000..6e25235779
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/coverage/ya.make
@@ -0,0 +1,26 @@
+GO_LIBRARY()
+
+SRCS(
+ cmddefs.go
+ defs.go
+ pkid.go
+)
+
+END()
+
+RECURSE(
+ calloc
+ cformat
+ cmerge
+ decodecounter
+ decodemeta
+ encodecounter
+ encodemeta
+ pods
+ rtcov
+ slicereader
+ slicewriter
+ stringtab
+ test
+ uleb128
+)
diff --git a/contrib/go/_std_1.21/src/internal/cpu/cpu.go b/contrib/go/_std_1.21/src/internal/cpu/cpu.go
new file mode 100644
index 0000000000..1352810f42
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/cpu/cpu.go
@@ -0,0 +1,222 @@
+// Copyright 2017 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 cpu implements processor feature detection
+// used by the Go standard library.
+package cpu
+
+// DebugOptions is set to true by the runtime if the OS supports reading
+// GODEBUG early in runtime startup.
+// This should not be changed after it is initialized.
+var DebugOptions bool
+
+// CacheLinePad is used to pad structs to avoid false sharing.
+type CacheLinePad struct{ _ [CacheLinePadSize]byte }
+
+// CacheLineSize is the CPU's assumed cache line size.
+// There is currently no runtime detection of the real cache line size
+// so we use the constant per GOARCH CacheLinePadSize as an approximation.
+var CacheLineSize uintptr = CacheLinePadSize
+
+// The booleans in X86 contain the correspondingly named cpuid feature bit.
+// HasAVX and HasAVX2 are only set if the OS does support XMM and YMM registers
+// in addition to the cpuid feature bit being set.
+// The struct is padded to avoid false sharing.
+var X86 struct {
+ _ CacheLinePad
+ HasAES bool
+ HasADX bool
+ HasAVX bool
+ HasAVX2 bool
+ HasBMI1 bool
+ HasBMI2 bool
+ HasERMS bool
+ HasFMA bool
+ HasOSXSAVE bool
+ HasPCLMULQDQ bool
+ HasPOPCNT bool
+ HasRDTSCP bool
+ HasSHA bool
+ HasSSE3 bool
+ HasSSSE3 bool
+ HasSSE41 bool
+ HasSSE42 bool
+ _ CacheLinePad
+}
+
+// The booleans in ARM contain the correspondingly named cpu feature bit.
+// The struct is padded to avoid false sharing.
+var ARM struct {
+ _ CacheLinePad
+ HasVFPv4 bool
+ HasIDIVA bool
+ _ CacheLinePad
+}
+
+// The booleans in ARM64 contain the correspondingly named cpu feature bit.
+// The struct is padded to avoid false sharing.
+var ARM64 struct {
+ _ CacheLinePad
+ HasAES bool
+ HasPMULL bool
+ HasSHA1 bool
+ HasSHA2 bool
+ HasSHA512 bool
+ HasCRC32 bool
+ HasATOMICS bool
+ HasCPUID bool
+ IsNeoverse bool
+ _ CacheLinePad
+}
+
+var MIPS64X struct {
+ _ CacheLinePad
+ HasMSA bool // MIPS SIMD architecture
+ _ CacheLinePad
+}
+
+// For ppc64(le), it is safe to check only for ISA level starting on ISA v3.00,
+// since there are no optional categories. There are some exceptions that also
+// require kernel support to work (darn, scv), so there are feature bits for
+// those as well. The minimum processor requirement is POWER8 (ISA 2.07).
+// The struct is padded to avoid false sharing.
+var PPC64 struct {
+ _ CacheLinePad
+ HasDARN bool // Hardware random number generator (requires kernel enablement)
+ HasSCV bool // Syscall vectored (requires kernel enablement)
+ IsPOWER8 bool // ISA v2.07 (POWER8)
+ IsPOWER9 bool // ISA v3.00 (POWER9)
+ IsPOWER10 bool // ISA v3.1 (POWER10)
+ _ CacheLinePad
+}
+
+var S390X struct {
+ _ CacheLinePad
+ HasZARCH bool // z architecture mode is active [mandatory]
+ HasSTFLE bool // store facility list extended [mandatory]
+ HasLDISP bool // long (20-bit) displacements [mandatory]
+ HasEIMM bool // 32-bit immediates [mandatory]
+ HasDFP bool // decimal floating point
+ HasETF3EH bool // ETF-3 enhanced
+ HasMSA bool // message security assist (CPACF)
+ HasAES bool // KM-AES{128,192,256} functions
+ HasAESCBC bool // KMC-AES{128,192,256} functions
+ HasAESCTR bool // KMCTR-AES{128,192,256} functions
+ HasAESGCM bool // KMA-GCM-AES{128,192,256} functions
+ HasGHASH bool // KIMD-GHASH function
+ HasSHA1 bool // K{I,L}MD-SHA-1 functions
+ HasSHA256 bool // K{I,L}MD-SHA-256 functions
+ HasSHA512 bool // K{I,L}MD-SHA-512 functions
+ HasSHA3 bool // K{I,L}MD-SHA3-{224,256,384,512} and K{I,L}MD-SHAKE-{128,256} functions
+ HasVX bool // vector facility. Note: the runtime sets this when it processes auxv records.
+ HasVXE bool // vector-enhancements facility 1
+ HasKDSA bool // elliptic curve functions
+ HasECDSA bool // NIST curves
+ HasEDDSA bool // Edwards curves
+ _ CacheLinePad
+}
+
+// Initialize examines the processor and sets the relevant variables above.
+// This is called by the runtime package early in program initialization,
+// before normal init functions are run. env is set by runtime if the OS supports
+// cpu feature options in GODEBUG.
+func Initialize(env string) {
+ doinit()
+ processOptions(env)
+}
+
+// options contains the cpu debug options that can be used in GODEBUG.
+// Options are arch dependent and are added by the arch specific doinit functions.
+// Features that are mandatory for the specific GOARCH should not be added to options
+// (e.g. SSE2 on amd64).
+var options []option
+
+// Option names should be lower case. e.g. avx instead of AVX.
+type option struct {
+ Name string
+ Feature *bool
+ Specified bool // whether feature value was specified in GODEBUG
+ Enable bool // whether feature should be enabled
+}
+
+// processOptions enables or disables CPU feature values based on the parsed env string.
+// The env string is expected to be of the form cpu.feature1=value1,cpu.feature2=value2...
+// where feature names is one of the architecture specific list stored in the
+// cpu packages options variable and values are either 'on' or 'off'.
+// If env contains cpu.all=off then all cpu features referenced through the options
+// variable are disabled. Other feature names and values result in warning messages.
+func processOptions(env string) {
+field:
+ for env != "" {
+ field := ""
+ i := indexByte(env, ',')
+ if i < 0 {
+ field, env = env, ""
+ } else {
+ field, env = env[:i], env[i+1:]
+ }
+ if len(field) < 4 || field[:4] != "cpu." {
+ continue
+ }
+ i = indexByte(field, '=')
+ if i < 0 {
+ print("GODEBUG: no value specified for \"", field, "\"\n")
+ continue
+ }
+ key, value := field[4:i], field[i+1:] // e.g. "SSE2", "on"
+
+ var enable bool
+ switch value {
+ case "on":
+ enable = true
+ case "off":
+ enable = false
+ default:
+ print("GODEBUG: value \"", value, "\" not supported for cpu option \"", key, "\"\n")
+ continue field
+ }
+
+ if key == "all" {
+ for i := range options {
+ options[i].Specified = true
+ options[i].Enable = enable
+ }
+ continue field
+ }
+
+ for i := range options {
+ if options[i].Name == key {
+ options[i].Specified = true
+ options[i].Enable = enable
+ continue field
+ }
+ }
+
+ print("GODEBUG: unknown cpu feature \"", key, "\"\n")
+ }
+
+ for _, o := range options {
+ if !o.Specified {
+ continue
+ }
+
+ if o.Enable && !*o.Feature {
+ print("GODEBUG: can not enable \"", o.Name, "\", missing CPU support\n")
+ continue
+ }
+
+ *o.Feature = o.Enable
+ }
+}
+
+// indexByte returns the index of the first instance of c in s,
+// or -1 if c is not present in s.
+func indexByte(s string, c byte) int {
+ for i := 0; i < len(s); i++ {
+ if s[i] == c {
+ return i
+ }
+ }
+ return -1
+}
diff --git a/contrib/go/_std_1.20/src/internal/cpu/cpu.s b/contrib/go/_std_1.21/src/internal/cpu/cpu.s
index 3c770c132d..3c770c132d 100644
--- a/contrib/go/_std_1.20/src/internal/cpu/cpu.s
+++ b/contrib/go/_std_1.21/src/internal/cpu/cpu.s
diff --git a/contrib/go/_std_1.21/src/internal/cpu/cpu_arm64.go b/contrib/go/_std_1.21/src/internal/cpu/cpu_arm64.go
new file mode 100644
index 0000000000..4a302f27d5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/cpu/cpu_arm64.go
@@ -0,0 +1,69 @@
+// Copyright 2017 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 cpu
+
+// CacheLinePadSize is used to prevent false sharing of cache lines.
+// We choose 128 because Apple Silicon, a.k.a. M1, has 128-byte cache line size.
+// It doesn't cost much and is much more future-proof.
+const CacheLinePadSize = 128
+
+func doinit() {
+ options = []option{
+ {Name: "aes", Feature: &ARM64.HasAES},
+ {Name: "pmull", Feature: &ARM64.HasPMULL},
+ {Name: "sha1", Feature: &ARM64.HasSHA1},
+ {Name: "sha2", Feature: &ARM64.HasSHA2},
+ {Name: "sha512", Feature: &ARM64.HasSHA512},
+ {Name: "crc32", Feature: &ARM64.HasCRC32},
+ {Name: "atomics", Feature: &ARM64.HasATOMICS},
+ {Name: "cpuid", Feature: &ARM64.HasCPUID},
+ {Name: "isNeoverse", Feature: &ARM64.IsNeoverse},
+ }
+
+ // arm64 uses different ways to detect CPU features at runtime depending on the operating system.
+ osInit()
+}
+
+func getisar0() uint64
+
+func getMIDR() uint64
+
+func extractBits(data uint64, start, end uint) uint {
+ return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
+}
+
+func parseARM64SystemRegisters(isar0 uint64) {
+ // ID_AA64ISAR0_EL1
+ switch extractBits(isar0, 4, 7) {
+ case 1:
+ ARM64.HasAES = true
+ case 2:
+ ARM64.HasAES = true
+ ARM64.HasPMULL = true
+ }
+
+ switch extractBits(isar0, 8, 11) {
+ case 1:
+ ARM64.HasSHA1 = true
+ }
+
+ switch extractBits(isar0, 12, 15) {
+ case 1:
+ ARM64.HasSHA2 = true
+ case 2:
+ ARM64.HasSHA2 = true
+ ARM64.HasSHA512 = true
+ }
+
+ switch extractBits(isar0, 16, 19) {
+ case 1:
+ ARM64.HasCRC32 = true
+ }
+
+ switch extractBits(isar0, 20, 23) {
+ case 2:
+ ARM64.HasATOMICS = true
+ }
+}
diff --git a/contrib/go/_std_1.20/src/internal/cpu/cpu_arm64.s b/contrib/go/_std_1.21/src/internal/cpu/cpu_arm64.s
index d6e7f44373..d6e7f44373 100644
--- a/contrib/go/_std_1.20/src/internal/cpu/cpu_arm64.s
+++ b/contrib/go/_std_1.21/src/internal/cpu/cpu_arm64.s
diff --git a/contrib/go/_std_1.21/src/internal/cpu/cpu_arm64_hwcap.go b/contrib/go/_std_1.21/src/internal/cpu/cpu_arm64_hwcap.go
new file mode 100644
index 0000000000..2fabbb6edc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/cpu/cpu_arm64_hwcap.go
@@ -0,0 +1,66 @@
+// 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.
+
+//go:build arm64 && linux
+
+package cpu
+
+// HWCap may be initialized by archauxv and
+// should not be changed after it was initialized.
+var HWCap uint
+
+// HWCAP bits. These are exposed by Linux.
+const (
+ hwcap_AES = 1 << 3
+ hwcap_PMULL = 1 << 4
+ hwcap_SHA1 = 1 << 5
+ hwcap_SHA2 = 1 << 6
+ hwcap_CRC32 = 1 << 7
+ hwcap_ATOMICS = 1 << 8
+ hwcap_CPUID = 1 << 11
+ hwcap_SHA512 = 1 << 21
+)
+
+func hwcapInit(os string) {
+ // HWCap was populated by the runtime from the auxiliary vector.
+ // Use HWCap information since reading aarch64 system registers
+ // is not supported in user space on older linux kernels.
+ ARM64.HasAES = isSet(HWCap, hwcap_AES)
+ ARM64.HasPMULL = isSet(HWCap, hwcap_PMULL)
+ ARM64.HasSHA1 = isSet(HWCap, hwcap_SHA1)
+ ARM64.HasSHA2 = isSet(HWCap, hwcap_SHA2)
+ ARM64.HasCRC32 = isSet(HWCap, hwcap_CRC32)
+ ARM64.HasCPUID = isSet(HWCap, hwcap_CPUID)
+ ARM64.HasSHA512 = isSet(HWCap, hwcap_SHA512)
+
+ // The Samsung S9+ kernel reports support for atomics, but not all cores
+ // actually support them, resulting in SIGILL. See issue #28431.
+ // TODO(elias.naur): Only disable the optimization on bad chipsets on android.
+ ARM64.HasATOMICS = isSet(HWCap, hwcap_ATOMICS) && os != "android"
+
+ // Check to see if executing on a Neoverse core and in order to do that,
+ // check the AUXV for the CPUID bit. The getMIDR function executes an
+ // instruction which would normally be an illegal instruction, but it's
+ // trapped by the kernel, the value sanitized and then returned.
+ // Without the CPUID bit the kernel will not trap the instruction and the
+ // process will be terminated with SIGILL.
+ if ARM64.HasCPUID {
+ midr := getMIDR()
+ part_num := uint16((midr >> 4) & 0xfff)
+ implementor := byte((midr >> 24) & 0xff)
+
+ // d0c - NeoverseN1
+ // d40 - NeoverseV1
+ // d49 - NeoverseN2
+ // d4f - NeoverseV2
+ if implementor == 'A' && (part_num == 0xd0c || part_num == 0xd40 ||
+ part_num == 0xd49 || part_num == 0xd4f) {
+ ARM64.IsNeoverse = true
+ }
+ }
+}
+
+func isSet(hwc uint, value uint) bool {
+ return hwc&value != 0
+}
diff --git a/contrib/go/_std_1.20/src/internal/cpu/cpu_arm64_linux.go b/contrib/go/_std_1.21/src/internal/cpu/cpu_arm64_linux.go
index d746bdb063..d746bdb063 100644
--- a/contrib/go/_std_1.20/src/internal/cpu/cpu_arm64_linux.go
+++ b/contrib/go/_std_1.21/src/internal/cpu/cpu_arm64_linux.go
diff --git a/contrib/go/_std_1.20/src/internal/cpu/cpu_no_name.go b/contrib/go/_std_1.21/src/internal/cpu/cpu_no_name.go
index 2adfa1b709..2adfa1b709 100644
--- a/contrib/go/_std_1.20/src/internal/cpu/cpu_no_name.go
+++ b/contrib/go/_std_1.21/src/internal/cpu/cpu_no_name.go
diff --git a/contrib/go/_std_1.20/src/internal/cpu/cpu_x86.go b/contrib/go/_std_1.21/src/internal/cpu/cpu_x86.go
index 96b8ef92b5..96b8ef92b5 100644
--- a/contrib/go/_std_1.20/src/internal/cpu/cpu_x86.go
+++ b/contrib/go/_std_1.21/src/internal/cpu/cpu_x86.go
diff --git a/contrib/go/_std_1.20/src/internal/cpu/cpu_x86.s b/contrib/go/_std_1.21/src/internal/cpu/cpu_x86.s
index 2ee8eca248..2ee8eca248 100644
--- a/contrib/go/_std_1.20/src/internal/cpu/cpu_x86.s
+++ b/contrib/go/_std_1.21/src/internal/cpu/cpu_x86.s
diff --git a/contrib/go/_std_1.21/src/internal/cpu/ya.make b/contrib/go/_std_1.21/src/internal/cpu/ya.make
new file mode 100644
index 0000000000..3dce10848c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/cpu/ya.make
@@ -0,0 +1,53 @@
+GO_LIBRARY()
+
+SRCS(
+ cpu.go
+ cpu.s
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(cpu_test.go)
+
+IF (ARCH_X86_64)
+ SRCS(
+ cpu_x86.go
+ cpu_x86.s
+ )
+
+ GO_TEST_SRCS(export_x86_test.go)
+
+ GO_XTEST_SRCS(cpu_x86_test.go)
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ cpu_arm64.go
+ cpu_arm64.s
+ cpu_no_name.go
+ )
+ENDIF()
+
+IF (OS_LINUX AND ARCH_ARM64)
+ SRCS(
+ cpu_arm64_hwcap.go
+ cpu_arm64_linux.go
+ )
+ENDIF()
+
+IF (OS_DARWIN AND ARCH_ARM64)
+ SRCS(
+ cpu_arm64_darwin.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS AND ARCH_ARM64)
+ SRCS(
+ cpu_arm64_other.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/fmtsort/sort.go b/contrib/go/_std_1.21/src/internal/fmtsort/sort.go
index 278a89bd75..278a89bd75 100644
--- a/contrib/go/_std_1.20/src/internal/fmtsort/sort.go
+++ b/contrib/go/_std_1.21/src/internal/fmtsort/sort.go
diff --git a/contrib/go/_std_1.21/src/internal/fmtsort/ya.make b/contrib/go/_std_1.21/src/internal/fmtsort/ya.make
new file mode 100644
index 0000000000..62b8629227
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/fmtsort/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ sort.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(sort_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/counters_supported.go b/contrib/go/_std_1.21/src/internal/fuzz/counters_supported.go
index 79e27d27e1..79e27d27e1 100644
--- a/contrib/go/_std_1.20/src/internal/fuzz/counters_supported.go
+++ b/contrib/go/_std_1.21/src/internal/fuzz/counters_supported.go
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/coverage.go b/contrib/go/_std_1.21/src/internal/fuzz/coverage.go
index 0c5e17e3bb..0c5e17e3bb 100644
--- a/contrib/go/_std_1.20/src/internal/fuzz/coverage.go
+++ b/contrib/go/_std_1.21/src/internal/fuzz/coverage.go
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/encoding.go b/contrib/go/_std_1.21/src/internal/fuzz/encoding.go
index 270ef7a1a3..270ef7a1a3 100644
--- a/contrib/go/_std_1.20/src/internal/fuzz/encoding.go
+++ b/contrib/go/_std_1.21/src/internal/fuzz/encoding.go
diff --git a/contrib/go/_std_1.21/src/internal/fuzz/fuzz.go b/contrib/go/_std_1.21/src/internal/fuzz/fuzz.go
new file mode 100644
index 0000000000..fb4e1d3705
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/fuzz/fuzz.go
@@ -0,0 +1,1102 @@
+// 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 fuzz provides common fuzzing functionality for tests built with
+// "go test" and for programs that use fuzzing functionality in the testing
+// package.
+package fuzz
+
+import (
+ "bytes"
+ "context"
+ "crypto/sha256"
+ "errors"
+ "fmt"
+ "internal/godebug"
+ "io"
+ "math/bits"
+ "os"
+ "path/filepath"
+ "reflect"
+ "runtime"
+ "strings"
+ "time"
+)
+
+// CoordinateFuzzingOpts is a set of arguments for CoordinateFuzzing.
+// The zero value is valid for each field unless specified otherwise.
+type CoordinateFuzzingOpts struct {
+ // Log is a writer for logging progress messages and warnings.
+ // If nil, io.Discard will be used instead.
+ Log io.Writer
+
+ // Timeout is the amount of wall clock time to spend fuzzing after the corpus
+ // has loaded. If zero, there will be no time limit.
+ Timeout time.Duration
+
+ // Limit is the number of random values to generate and test. If zero,
+ // there will be no limit on the number of generated values.
+ Limit int64
+
+ // MinimizeTimeout is the amount of wall clock time to spend minimizing
+ // after discovering a crasher. If zero, there will be no time limit. If
+ // MinimizeTimeout and MinimizeLimit are both zero, then minimization will
+ // be disabled.
+ MinimizeTimeout time.Duration
+
+ // MinimizeLimit is the maximum number of calls to the fuzz function to be
+ // made while minimizing after finding a crash. If zero, there will be no
+ // limit. Calls to the fuzz function made when minimizing also count toward
+ // Limit. If MinimizeTimeout and MinimizeLimit are both zero, then
+ // minimization will be disabled.
+ MinimizeLimit int64
+
+ // parallel is the number of worker processes to run in parallel. If zero,
+ // CoordinateFuzzing will run GOMAXPROCS workers.
+ Parallel int
+
+ // Seed is a list of seed values added by the fuzz target with testing.F.Add
+ // and in testdata.
+ Seed []CorpusEntry
+
+ // Types is the list of types which make up a corpus entry.
+ // Types must be set and must match values in Seed.
+ Types []reflect.Type
+
+ // CorpusDir is a directory where files containing values that crash the
+ // code being tested may be written. CorpusDir must be set.
+ CorpusDir string
+
+ // CacheDir is a directory containing additional "interesting" values.
+ // The fuzzer may derive new values from these, and may write new values here.
+ CacheDir string
+}
+
+// CoordinateFuzzing creates several worker processes and communicates with
+// them to test random inputs that could trigger crashes and expose bugs.
+// The worker processes run the same binary in the same directory with the
+// same environment variables as the coordinator process. Workers also run
+// with the same arguments as the coordinator, except with the -test.fuzzworker
+// flag prepended to the argument list.
+//
+// If a crash occurs, the function will return an error containing information
+// about the crash, which can be reported to the user.
+func CoordinateFuzzing(ctx context.Context, opts CoordinateFuzzingOpts) (err error) {
+ if err := ctx.Err(); err != nil {
+ return err
+ }
+ if opts.Log == nil {
+ opts.Log = io.Discard
+ }
+ if opts.Parallel == 0 {
+ opts.Parallel = runtime.GOMAXPROCS(0)
+ }
+ if opts.Limit > 0 && int64(opts.Parallel) > opts.Limit {
+ // Don't start more workers than we need.
+ opts.Parallel = int(opts.Limit)
+ }
+
+ c, err := newCoordinator(opts)
+ if err != nil {
+ return err
+ }
+
+ if opts.Timeout > 0 {
+ var cancel func()
+ ctx, cancel = context.WithTimeout(ctx, opts.Timeout)
+ defer cancel()
+ }
+
+ // fuzzCtx is used to stop workers, for example, after finding a crasher.
+ fuzzCtx, cancelWorkers := context.WithCancel(ctx)
+ defer cancelWorkers()
+ doneC := ctx.Done()
+
+ // stop is called when a worker encounters a fatal error.
+ var fuzzErr error
+ stopping := false
+ stop := func(err error) {
+ if shouldPrintDebugInfo() {
+ _, file, line, ok := runtime.Caller(1)
+ if ok {
+ c.debugLogf("stop called at %s:%d. stopping: %t", file, line, stopping)
+ } else {
+ c.debugLogf("stop called at unknown. stopping: %t", stopping)
+ }
+ }
+
+ if err == fuzzCtx.Err() || isInterruptError(err) {
+ // Suppress cancellation errors and terminations due to SIGINT.
+ // The messages are not helpful since either the user triggered the error
+ // (with ^C) or another more helpful message will be printed (a crasher).
+ err = nil
+ }
+ if err != nil && (fuzzErr == nil || fuzzErr == ctx.Err()) {
+ fuzzErr = err
+ }
+ if stopping {
+ return
+ }
+ stopping = true
+ cancelWorkers()
+ doneC = nil
+ }
+
+ // Ensure that any crash we find is written to the corpus, even if an error
+ // or interruption occurs while minimizing it.
+ crashWritten := false
+ defer func() {
+ if c.crashMinimizing == nil || crashWritten {
+ return
+ }
+ werr := writeToCorpus(&c.crashMinimizing.entry, opts.CorpusDir)
+ if werr != nil {
+ err = fmt.Errorf("%w\n%v", err, werr)
+ return
+ }
+ if err == nil {
+ err = &crashError{
+ path: c.crashMinimizing.entry.Path,
+ err: errors.New(c.crashMinimizing.crasherMsg),
+ }
+ }
+ }()
+
+ // Start workers.
+ // TODO(jayconrod): do we want to support fuzzing different binaries?
+ dir := "" // same as self
+ binPath := os.Args[0]
+ args := append([]string{"-test.fuzzworker"}, os.Args[1:]...)
+ env := os.Environ() // same as self
+
+ errC := make(chan error)
+ workers := make([]*worker, opts.Parallel)
+ for i := range workers {
+ var err error
+ workers[i], err = newWorker(c, dir, binPath, args, env)
+ if err != nil {
+ return err
+ }
+ }
+ for i := range workers {
+ w := workers[i]
+ go func() {
+ err := w.coordinate(fuzzCtx)
+ if fuzzCtx.Err() != nil || isInterruptError(err) {
+ err = nil
+ }
+ cleanErr := w.cleanup()
+ if err == nil {
+ err = cleanErr
+ }
+ errC <- err
+ }()
+ }
+
+ // Main event loop.
+ // Do not return until all workers have terminated. We avoid a deadlock by
+ // receiving messages from workers even after ctx is cancelled.
+ activeWorkers := len(workers)
+ statTicker := time.NewTicker(3 * time.Second)
+ defer statTicker.Stop()
+ defer c.logStats()
+
+ c.logStats()
+ for {
+ // If there is an execution limit, and we've reached it, stop.
+ if c.opts.Limit > 0 && c.count >= c.opts.Limit {
+ stop(nil)
+ }
+
+ var inputC chan fuzzInput
+ input, ok := c.peekInput()
+ if ok && c.crashMinimizing == nil && !stopping {
+ inputC = c.inputC
+ }
+
+ var minimizeC chan fuzzMinimizeInput
+ minimizeInput, ok := c.peekMinimizeInput()
+ if ok && !stopping {
+ minimizeC = c.minimizeC
+ }
+
+ select {
+ case <-doneC:
+ // Interrupted, cancelled, or timed out.
+ // stop sets doneC to nil so we don't busy wait here.
+ stop(ctx.Err())
+
+ case err := <-errC:
+ // A worker terminated, possibly after encountering a fatal error.
+ stop(err)
+ activeWorkers--
+ if activeWorkers == 0 {
+ return fuzzErr
+ }
+
+ case result := <-c.resultC:
+ // Received response from worker.
+ if stopping {
+ break
+ }
+ c.updateStats(result)
+
+ if result.crasherMsg != "" {
+ if c.warmupRun() && result.entry.IsSeed {
+ target := filepath.Base(c.opts.CorpusDir)
+ fmt.Fprintf(c.opts.Log, "failure while testing seed corpus entry: %s/%s\n", target, testName(result.entry.Parent))
+ stop(errors.New(result.crasherMsg))
+ break
+ }
+ if c.canMinimize() && result.canMinimize {
+ if c.crashMinimizing != nil {
+ // This crash is not minimized, and another crash is being minimized.
+ // Ignore this one and wait for the other one to finish.
+ if shouldPrintDebugInfo() {
+ c.debugLogf("found unminimized crasher, skipping in favor of minimizable crasher")
+ }
+ break
+ }
+ // Found a crasher but haven't yet attempted to minimize it.
+ // Send it back to a worker for minimization. Disable inputC so
+ // other workers don't continue fuzzing.
+ c.crashMinimizing = &result
+ fmt.Fprintf(c.opts.Log, "fuzz: minimizing %d-byte failing input file\n", len(result.entry.Data))
+ c.queueForMinimization(result, nil)
+ } else if !crashWritten {
+ // Found a crasher that's either minimized or not minimizable.
+ // Write to corpus and stop.
+ err := writeToCorpus(&result.entry, opts.CorpusDir)
+ if err == nil {
+ crashWritten = true
+ err = &crashError{
+ path: result.entry.Path,
+ err: errors.New(result.crasherMsg),
+ }
+ }
+ if shouldPrintDebugInfo() {
+ c.debugLogf(
+ "found crasher, id: %s, parent: %s, gen: %d, size: %d, exec time: %s",
+ result.entry.Path,
+ result.entry.Parent,
+ result.entry.Generation,
+ len(result.entry.Data),
+ result.entryDuration,
+ )
+ }
+ stop(err)
+ }
+ } else if result.coverageData != nil {
+ if c.warmupRun() {
+ if shouldPrintDebugInfo() {
+ c.debugLogf(
+ "processed an initial input, id: %s, new bits: %d, size: %d, exec time: %s",
+ result.entry.Parent,
+ countBits(diffCoverage(c.coverageMask, result.coverageData)),
+ len(result.entry.Data),
+ result.entryDuration,
+ )
+ }
+ c.updateCoverage(result.coverageData)
+ c.warmupInputLeft--
+ if c.warmupInputLeft == 0 {
+ fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, gathering baseline coverage: %d/%d completed, now fuzzing with %d workers\n", c.elapsed(), c.warmupInputCount, c.warmupInputCount, c.opts.Parallel)
+ if shouldPrintDebugInfo() {
+ c.debugLogf(
+ "finished processing input corpus, entries: %d, initial coverage bits: %d",
+ len(c.corpus.entries),
+ countBits(c.coverageMask),
+ )
+ }
+ }
+ } else if keepCoverage := diffCoverage(c.coverageMask, result.coverageData); keepCoverage != nil {
+ // Found a value that expanded coverage.
+ // It's not a crasher, but we may want to add it to the on-disk
+ // corpus and prioritize it for future fuzzing.
+ // TODO(jayconrod, katiehockman): Prioritize fuzzing these
+ // values which expanded coverage, perhaps based on the
+ // number of new edges that this result expanded.
+ // TODO(jayconrod, katiehockman): Don't write a value that's already
+ // in the corpus.
+ if c.canMinimize() && result.canMinimize && c.crashMinimizing == nil {
+ // Send back to workers to find a smaller value that preserves
+ // at least one new coverage bit.
+ c.queueForMinimization(result, keepCoverage)
+ } else {
+ // Update the coordinator's coverage mask and save the value.
+ inputSize := len(result.entry.Data)
+ entryNew, err := c.addCorpusEntries(true, result.entry)
+ if err != nil {
+ stop(err)
+ break
+ }
+ if !entryNew {
+ if shouldPrintDebugInfo() {
+ c.debugLogf(
+ "ignoring duplicate input which increased coverage, id: %s",
+ result.entry.Path,
+ )
+ }
+ break
+ }
+ c.updateCoverage(keepCoverage)
+ c.inputQueue.enqueue(result.entry)
+ c.interestingCount++
+ if shouldPrintDebugInfo() {
+ c.debugLogf(
+ "new interesting input, id: %s, parent: %s, gen: %d, new bits: %d, total bits: %d, size: %d, exec time: %s",
+ result.entry.Path,
+ result.entry.Parent,
+ result.entry.Generation,
+ countBits(keepCoverage),
+ countBits(c.coverageMask),
+ inputSize,
+ result.entryDuration,
+ )
+ }
+ }
+ } else {
+ if shouldPrintDebugInfo() {
+ c.debugLogf(
+ "worker reported interesting input that doesn't expand coverage, id: %s, parent: %s, canMinimize: %t",
+ result.entry.Path,
+ result.entry.Parent,
+ result.canMinimize,
+ )
+ }
+ }
+ } else if c.warmupRun() {
+ // No error or coverage data was reported for this input during
+ // warmup, so continue processing results.
+ c.warmupInputLeft--
+ if c.warmupInputLeft == 0 {
+ fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, testing seed corpus: %d/%d completed, now fuzzing with %d workers\n", c.elapsed(), c.warmupInputCount, c.warmupInputCount, c.opts.Parallel)
+ if shouldPrintDebugInfo() {
+ c.debugLogf(
+ "finished testing-only phase, entries: %d",
+ len(c.corpus.entries),
+ )
+ }
+ }
+ }
+
+ case inputC <- input:
+ // Sent the next input to a worker.
+ c.sentInput(input)
+
+ case minimizeC <- minimizeInput:
+ // Sent the next input for minimization to a worker.
+ c.sentMinimizeInput(minimizeInput)
+
+ case <-statTicker.C:
+ c.logStats()
+ }
+ }
+
+ // TODO(jayconrod,katiehockman): if a crasher can't be written to the corpus,
+ // write to the cache instead.
+}
+
+// crashError wraps a crasher written to the seed corpus. It saves the name
+// of the file where the input causing the crasher was saved. The testing
+// framework uses this to report a command to re-run that specific input.
+type crashError struct {
+ path string
+ err error
+}
+
+func (e *crashError) Error() string {
+ return e.err.Error()
+}
+
+func (e *crashError) Unwrap() error {
+ return e.err
+}
+
+func (e *crashError) CrashPath() string {
+ return e.path
+}
+
+type corpus struct {
+ entries []CorpusEntry
+ hashes map[[sha256.Size]byte]bool
+}
+
+// addCorpusEntries adds entries to the corpus, and optionally writes the entries
+// to the cache directory. If an entry is already in the corpus it is skipped. If
+// all of the entries are unique, addCorpusEntries returns true and a nil error,
+// if at least one of the entries was a duplicate, it returns false and a nil error.
+func (c *coordinator) addCorpusEntries(addToCache bool, entries ...CorpusEntry) (bool, error) {
+ noDupes := true
+ for _, e := range entries {
+ data, err := corpusEntryData(e)
+ if err != nil {
+ return false, err
+ }
+ h := sha256.Sum256(data)
+ if c.corpus.hashes[h] {
+ noDupes = false
+ continue
+ }
+ if addToCache {
+ if err := writeToCorpus(&e, c.opts.CacheDir); err != nil {
+ return false, err
+ }
+ // For entries written to disk, we don't hold onto the bytes,
+ // since the corpus would consume a significant amount of
+ // memory.
+ e.Data = nil
+ }
+ c.corpus.hashes[h] = true
+ c.corpus.entries = append(c.corpus.entries, e)
+ }
+ return noDupes, nil
+}
+
+// CorpusEntry represents an individual input for fuzzing.
+//
+// We must use an equivalent type in the testing and testing/internal/testdeps
+// packages, but testing can't import this package directly, and we don't want
+// to export this type from testing. Instead, we use the same struct type and
+// use a type alias (not a defined type) for convenience.
+type CorpusEntry = struct {
+ Parent string
+
+ // Path is the path of the corpus file, if the entry was loaded from disk.
+ // For other entries, including seed values provided by f.Add, Path is the
+ // name of the test, e.g. seed#0 or its hash.
+ Path string
+
+ // Data is the raw input data. Data should only be populated for seed
+ // values. For on-disk corpus files, Data will be nil, as it will be loaded
+ // from disk using Path.
+ Data []byte
+
+ // Values is the unmarshaled values from a corpus file.
+ Values []any
+
+ Generation int
+
+ // IsSeed indicates whether this entry is part of the seed corpus.
+ IsSeed bool
+}
+
+// corpusEntryData returns the raw input bytes, either from the data struct
+// field, or from disk.
+func corpusEntryData(ce CorpusEntry) ([]byte, error) {
+ if ce.Data != nil {
+ return ce.Data, nil
+ }
+
+ return os.ReadFile(ce.Path)
+}
+
+type fuzzInput struct {
+ // entry is the value to test initially. The worker will randomly mutate
+ // values from this starting point.
+ entry CorpusEntry
+
+ // timeout is the time to spend fuzzing variations of this input,
+ // not including starting or cleaning up.
+ timeout time.Duration
+
+ // limit is the maximum number of calls to the fuzz function the worker may
+ // make. The worker may make fewer calls, for example, if it finds an
+ // error early. If limit is zero, there is no limit on calls to the
+ // fuzz function.
+ limit int64
+
+ // warmup indicates whether this is a warmup input before fuzzing begins. If
+ // true, the input should not be fuzzed.
+ warmup bool
+
+ // coverageData reflects the coordinator's current coverageMask.
+ coverageData []byte
+}
+
+type fuzzResult struct {
+ // entry is an interesting value or a crasher.
+ entry CorpusEntry
+
+ // crasherMsg is an error message from a crash. It's "" if no crash was found.
+ crasherMsg string
+
+ // canMinimize is true if the worker should attempt to minimize this result.
+ // It may be false because an attempt has already been made.
+ canMinimize bool
+
+ // coverageData is set if the worker found new coverage.
+ coverageData []byte
+
+ // limit is the number of values the coordinator asked the worker
+ // to test. 0 if there was no limit.
+ limit int64
+
+ // count is the number of values the worker actually tested.
+ count int64
+
+ // totalDuration is the time the worker spent testing inputs.
+ totalDuration time.Duration
+
+ // entryDuration is the time the worker spent execution an interesting result
+ entryDuration time.Duration
+}
+
+type fuzzMinimizeInput struct {
+ // entry is an interesting value or crasher to minimize.
+ entry CorpusEntry
+
+ // crasherMsg is an error message from a crash. It's "" if no crash was found.
+ // If set, the worker will attempt to find a smaller input that also produces
+ // an error, though not necessarily the same error.
+ crasherMsg string
+
+ // limit is the maximum number of calls to the fuzz function the worker may
+ // make. The worker may make fewer calls, for example, if it can't reproduce
+ // an error. If limit is zero, there is no limit on calls to the fuzz function.
+ limit int64
+
+ // timeout is the time to spend minimizing this input.
+ // A zero timeout means no limit.
+ timeout time.Duration
+
+ // keepCoverage is a set of coverage bits that entry found that were not in
+ // the coordinator's combined set. When minimizing, the worker should find an
+ // input that preserves at least one of these bits. keepCoverage is nil for
+ // crashing inputs.
+ keepCoverage []byte
+}
+
+// coordinator holds channels that workers can use to communicate with
+// the coordinator.
+type coordinator struct {
+ opts CoordinateFuzzingOpts
+
+ // startTime is the time we started the workers after loading the corpus.
+ // Used for logging.
+ startTime time.Time
+
+ // inputC is sent values to fuzz by the coordinator. Any worker may receive
+ // values from this channel. Workers send results to resultC.
+ inputC chan fuzzInput
+
+ // minimizeC is sent values to minimize by the coordinator. Any worker may
+ // receive values from this channel. Workers send results to resultC.
+ minimizeC chan fuzzMinimizeInput
+
+ // resultC is sent results of fuzzing by workers. The coordinator
+ // receives these. Multiple types of messages are allowed.
+ resultC chan fuzzResult
+
+ // count is the number of values fuzzed so far.
+ count int64
+
+ // countLastLog is the number of values fuzzed when the output was last
+ // logged.
+ countLastLog int64
+
+ // timeLastLog is the time at which the output was last logged.
+ timeLastLog time.Time
+
+ // interestingCount is the number of unique interesting values which have
+ // been found this execution.
+ interestingCount int
+
+ // warmupInputCount is the count of all entries in the corpus which will
+ // need to be received from workers to run once during warmup, but not fuzz.
+ // This could be for coverage data, or only for the purposes of verifying
+ // that the seed corpus doesn't have any crashers. See warmupRun.
+ warmupInputCount int
+
+ // warmupInputLeft is the number of entries in the corpus which still need
+ // to be received from workers to run once during warmup, but not fuzz.
+ // See warmupInputLeft.
+ warmupInputLeft int
+
+ // duration is the time spent fuzzing inside workers, not counting time
+ // starting up or tearing down.
+ duration time.Duration
+
+ // countWaiting is the number of fuzzing executions the coordinator is
+ // waiting on workers to complete.
+ countWaiting int64
+
+ // corpus is a set of interesting values, including the seed corpus and
+ // generated values that workers reported as interesting.
+ corpus corpus
+
+ // minimizationAllowed is true if one or more of the types of fuzz
+ // function's parameters can be minimized.
+ minimizationAllowed bool
+
+ // inputQueue is a queue of inputs that workers should try fuzzing. This is
+ // initially populated from the seed corpus and cached inputs. More inputs
+ // may be added as new coverage is discovered.
+ inputQueue queue
+
+ // minimizeQueue is a queue of inputs that caused errors or exposed new
+ // coverage. Workers should attempt to find smaller inputs that do the
+ // same thing.
+ minimizeQueue queue
+
+ // crashMinimizing is the crash that is currently being minimized.
+ crashMinimizing *fuzzResult
+
+ // coverageMask aggregates coverage that was found for all inputs in the
+ // corpus. Each byte represents a single basic execution block. Each set bit
+ // within the byte indicates that an input has triggered that block at least
+ // 1 << n times, where n is the position of the bit in the byte. For example, a
+ // value of 12 indicates that separate inputs have triggered this block
+ // between 4-7 times and 8-15 times.
+ coverageMask []byte
+}
+
+func newCoordinator(opts CoordinateFuzzingOpts) (*coordinator, error) {
+ // Make sure all of the seed corpus has marshalled data.
+ for i := range opts.Seed {
+ if opts.Seed[i].Data == nil && opts.Seed[i].Values != nil {
+ opts.Seed[i].Data = marshalCorpusFile(opts.Seed[i].Values...)
+ }
+ }
+ c := &coordinator{
+ opts: opts,
+ startTime: time.Now(),
+ inputC: make(chan fuzzInput),
+ minimizeC: make(chan fuzzMinimizeInput),
+ resultC: make(chan fuzzResult),
+ timeLastLog: time.Now(),
+ corpus: corpus{hashes: make(map[[sha256.Size]byte]bool)},
+ }
+ if err := c.readCache(); err != nil {
+ return nil, err
+ }
+ if opts.MinimizeLimit > 0 || opts.MinimizeTimeout > 0 {
+ for _, t := range opts.Types {
+ if isMinimizable(t) {
+ c.minimizationAllowed = true
+ break
+ }
+ }
+ }
+
+ covSize := len(coverage())
+ if covSize == 0 {
+ fmt.Fprintf(c.opts.Log, "warning: the test binary was not built with coverage instrumentation, so fuzzing will run without coverage guidance and may be inefficient\n")
+ // Even though a coverage-only run won't occur, we should still run all
+ // of the seed corpus to make sure there are no existing failures before
+ // we start fuzzing.
+ c.warmupInputCount = len(c.opts.Seed)
+ for _, e := range c.opts.Seed {
+ c.inputQueue.enqueue(e)
+ }
+ } else {
+ c.warmupInputCount = len(c.corpus.entries)
+ for _, e := range c.corpus.entries {
+ c.inputQueue.enqueue(e)
+ }
+ // Set c.coverageMask to a clean []byte full of zeros.
+ c.coverageMask = make([]byte, covSize)
+ }
+ c.warmupInputLeft = c.warmupInputCount
+
+ if len(c.corpus.entries) == 0 {
+ fmt.Fprintf(c.opts.Log, "warning: starting with empty corpus\n")
+ var vals []any
+ for _, t := range opts.Types {
+ vals = append(vals, zeroValue(t))
+ }
+ data := marshalCorpusFile(vals...)
+ h := sha256.Sum256(data)
+ name := fmt.Sprintf("%x", h[:4])
+ c.addCorpusEntries(false, CorpusEntry{Path: name, Data: data})
+ }
+
+ return c, nil
+}
+
+func (c *coordinator) updateStats(result fuzzResult) {
+ c.count += result.count
+ c.countWaiting -= result.limit
+ c.duration += result.totalDuration
+}
+
+func (c *coordinator) logStats() {
+ now := time.Now()
+ if c.warmupRun() {
+ runSoFar := c.warmupInputCount - c.warmupInputLeft
+ if coverageEnabled {
+ fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, gathering baseline coverage: %d/%d completed\n", c.elapsed(), runSoFar, c.warmupInputCount)
+ } else {
+ fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, testing seed corpus: %d/%d completed\n", c.elapsed(), runSoFar, c.warmupInputCount)
+ }
+ } else if c.crashMinimizing != nil {
+ fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, minimizing\n", c.elapsed())
+ } else {
+ rate := float64(c.count-c.countLastLog) / now.Sub(c.timeLastLog).Seconds()
+ if coverageEnabled {
+ total := c.warmupInputCount + c.interestingCount
+ fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, execs: %d (%.0f/sec), new interesting: %d (total: %d)\n", c.elapsed(), c.count, rate, c.interestingCount, total)
+ } else {
+ fmt.Fprintf(c.opts.Log, "fuzz: elapsed: %s, execs: %d (%.0f/sec)\n", c.elapsed(), c.count, rate)
+ }
+ }
+ c.countLastLog = c.count
+ c.timeLastLog = now
+}
+
+// peekInput returns the next value that should be sent to workers.
+// If the number of executions is limited, the returned value includes
+// a limit for one worker. If there are no executions left, peekInput returns
+// a zero value and false.
+//
+// peekInput doesn't actually remove the input from the queue. The caller
+// must call sentInput after sending the input.
+//
+// If the input queue is empty and the coverage/testing-only run has completed,
+// queue refills it from the corpus.
+func (c *coordinator) peekInput() (fuzzInput, bool) {
+ if c.opts.Limit > 0 && c.count+c.countWaiting >= c.opts.Limit {
+ // Already making the maximum number of calls to the fuzz function.
+ // Don't send more inputs right now.
+ return fuzzInput{}, false
+ }
+ if c.inputQueue.len == 0 {
+ if c.warmupRun() {
+ // Wait for coverage/testing-only run to finish before sending more
+ // inputs.
+ return fuzzInput{}, false
+ }
+ c.refillInputQueue()
+ }
+
+ entry, ok := c.inputQueue.peek()
+ if !ok {
+ panic("input queue empty after refill")
+ }
+ input := fuzzInput{
+ entry: entry.(CorpusEntry),
+ timeout: workerFuzzDuration,
+ warmup: c.warmupRun(),
+ }
+ if c.coverageMask != nil {
+ input.coverageData = bytes.Clone(c.coverageMask)
+ }
+ if input.warmup {
+ // No fuzzing will occur, but it should count toward the limit set by
+ // -fuzztime.
+ input.limit = 1
+ return input, true
+ }
+
+ if c.opts.Limit > 0 {
+ input.limit = c.opts.Limit / int64(c.opts.Parallel)
+ if c.opts.Limit%int64(c.opts.Parallel) > 0 {
+ input.limit++
+ }
+ remaining := c.opts.Limit - c.count - c.countWaiting
+ if input.limit > remaining {
+ input.limit = remaining
+ }
+ }
+ return input, true
+}
+
+// sentInput updates internal counters after an input is sent to c.inputC.
+func (c *coordinator) sentInput(input fuzzInput) {
+ c.inputQueue.dequeue()
+ c.countWaiting += input.limit
+}
+
+// refillInputQueue refills the input queue from the corpus after it becomes
+// empty.
+func (c *coordinator) refillInputQueue() {
+ for _, e := range c.corpus.entries {
+ c.inputQueue.enqueue(e)
+ }
+}
+
+// queueForMinimization creates a fuzzMinimizeInput from result and adds it
+// to the minimization queue to be sent to workers.
+func (c *coordinator) queueForMinimization(result fuzzResult, keepCoverage []byte) {
+ if shouldPrintDebugInfo() {
+ c.debugLogf(
+ "queueing input for minimization, id: %s, parent: %s, keepCoverage: %t, crasher: %t",
+ result.entry.Path,
+ result.entry.Parent,
+ keepCoverage != nil,
+ result.crasherMsg != "",
+ )
+ }
+ if result.crasherMsg != "" {
+ c.minimizeQueue.clear()
+ }
+
+ input := fuzzMinimizeInput{
+ entry: result.entry,
+ crasherMsg: result.crasherMsg,
+ keepCoverage: keepCoverage,
+ }
+ c.minimizeQueue.enqueue(input)
+}
+
+// peekMinimizeInput returns the next input that should be sent to workers for
+// minimization.
+func (c *coordinator) peekMinimizeInput() (fuzzMinimizeInput, bool) {
+ if !c.canMinimize() {
+ // Already making the maximum number of calls to the fuzz function.
+ // Don't send more inputs right now.
+ return fuzzMinimizeInput{}, false
+ }
+ v, ok := c.minimizeQueue.peek()
+ if !ok {
+ return fuzzMinimizeInput{}, false
+ }
+ input := v.(fuzzMinimizeInput)
+
+ if c.opts.MinimizeTimeout > 0 {
+ input.timeout = c.opts.MinimizeTimeout
+ }
+ if c.opts.MinimizeLimit > 0 {
+ input.limit = c.opts.MinimizeLimit
+ } else if c.opts.Limit > 0 {
+ if input.crasherMsg != "" {
+ input.limit = c.opts.Limit
+ } else {
+ input.limit = c.opts.Limit / int64(c.opts.Parallel)
+ if c.opts.Limit%int64(c.opts.Parallel) > 0 {
+ input.limit++
+ }
+ }
+ }
+ if c.opts.Limit > 0 {
+ remaining := c.opts.Limit - c.count - c.countWaiting
+ if input.limit > remaining {
+ input.limit = remaining
+ }
+ }
+ return input, true
+}
+
+// sentMinimizeInput removes an input from the minimization queue after it's
+// sent to minimizeC.
+func (c *coordinator) sentMinimizeInput(input fuzzMinimizeInput) {
+ c.minimizeQueue.dequeue()
+ c.countWaiting += input.limit
+}
+
+// warmupRun returns true while the coordinator is running inputs without
+// mutating them as a warmup before fuzzing. This could be to gather baseline
+// coverage data for entries in the corpus, or to test all of the seed corpus
+// for errors before fuzzing begins.
+//
+// The coordinator doesn't store coverage data in the cache with each input
+// because that data would be invalid when counter offsets in the test binary
+// change.
+//
+// When gathering coverage, the coordinator sends each entry to a worker to
+// gather coverage for that entry only, without fuzzing or minimizing. This
+// phase ends when all workers have finished, and the coordinator has a combined
+// coverage map.
+func (c *coordinator) warmupRun() bool {
+ return c.warmupInputLeft > 0
+}
+
+// updateCoverage sets bits in c.coverageMask that are set in newCoverage.
+// updateCoverage returns the number of newly set bits. See the comment on
+// coverageMask for the format.
+func (c *coordinator) updateCoverage(newCoverage []byte) int {
+ if len(newCoverage) != len(c.coverageMask) {
+ panic(fmt.Sprintf("number of coverage counters changed at runtime: %d, expected %d", len(newCoverage), len(c.coverageMask)))
+ }
+ newBitCount := 0
+ for i := range newCoverage {
+ diff := newCoverage[i] &^ c.coverageMask[i]
+ newBitCount += bits.OnesCount8(diff)
+ c.coverageMask[i] |= newCoverage[i]
+ }
+ return newBitCount
+}
+
+// canMinimize returns whether the coordinator should attempt to find smaller
+// inputs that reproduce a crash or new coverage.
+func (c *coordinator) canMinimize() bool {
+ return c.minimizationAllowed &&
+ (c.opts.Limit == 0 || c.count+c.countWaiting < c.opts.Limit)
+}
+
+func (c *coordinator) elapsed() time.Duration {
+ return time.Since(c.startTime).Round(1 * time.Second)
+}
+
+// readCache creates a combined corpus from seed values and values in the cache
+// (in GOCACHE/fuzz).
+//
+// TODO(fuzzing): need a mechanism that can remove values that
+// aren't useful anymore, for example, because they have the wrong type.
+func (c *coordinator) readCache() error {
+ if _, err := c.addCorpusEntries(false, c.opts.Seed...); err != nil {
+ return err
+ }
+ entries, err := ReadCorpus(c.opts.CacheDir, c.opts.Types)
+ if err != nil {
+ if _, ok := err.(*MalformedCorpusError); !ok {
+ // It's okay if some files in the cache directory are malformed and
+ // are not included in the corpus, but fail if it's an I/O error.
+ return err
+ }
+ // TODO(jayconrod,katiehockman): consider printing some kind of warning
+ // indicating the number of files which were skipped because they are
+ // malformed.
+ }
+ if _, err := c.addCorpusEntries(false, entries...); err != nil {
+ return err
+ }
+ return nil
+}
+
+// MalformedCorpusError is an error found while reading the corpus from the
+// filesystem. All of the errors are stored in the errs list. The testing
+// framework uses this to report malformed files in testdata.
+type MalformedCorpusError struct {
+ errs []error
+}
+
+func (e *MalformedCorpusError) Error() string {
+ var msgs []string
+ for _, s := range e.errs {
+ msgs = append(msgs, s.Error())
+ }
+ return strings.Join(msgs, "\n")
+}
+
+// ReadCorpus reads the corpus from the provided dir. The returned corpus
+// entries are guaranteed to match the given types. Any malformed files will
+// be saved in a MalformedCorpusError and returned, along with the most recent
+// error.
+func ReadCorpus(dir string, types []reflect.Type) ([]CorpusEntry, error) {
+ files, err := os.ReadDir(dir)
+ if os.IsNotExist(err) {
+ return nil, nil // No corpus to read
+ } else if err != nil {
+ return nil, fmt.Errorf("reading seed corpus from testdata: %v", err)
+ }
+ var corpus []CorpusEntry
+ var errs []error
+ for _, file := range files {
+ // TODO(jayconrod,katiehockman): determine when a file is a fuzzing input
+ // based on its name. We should only read files created by writeToCorpus.
+ // If we read ALL files, we won't be able to change the file format by
+ // changing the extension. We also won't be able to add files like
+ // README.txt explaining why the directory exists.
+ if file.IsDir() {
+ continue
+ }
+ filename := filepath.Join(dir, file.Name())
+ data, err := os.ReadFile(filename)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read corpus file: %v", err)
+ }
+ var vals []any
+ vals, err = readCorpusData(data, types)
+ if err != nil {
+ errs = append(errs, fmt.Errorf("%q: %v", filename, err))
+ continue
+ }
+ corpus = append(corpus, CorpusEntry{Path: filename, Values: vals})
+ }
+ if len(errs) > 0 {
+ return corpus, &MalformedCorpusError{errs: errs}
+ }
+ return corpus, nil
+}
+
+func readCorpusData(data []byte, types []reflect.Type) ([]any, error) {
+ vals, err := unmarshalCorpusFile(data)
+ if err != nil {
+ return nil, fmt.Errorf("unmarshal: %v", err)
+ }
+ if err = CheckCorpus(vals, types); err != nil {
+ return nil, err
+ }
+ return vals, nil
+}
+
+// CheckCorpus verifies that the types in vals match the expected types
+// provided.
+func CheckCorpus(vals []any, types []reflect.Type) error {
+ if len(vals) != len(types) {
+ return fmt.Errorf("wrong number of values in corpus entry: %d, want %d", len(vals), len(types))
+ }
+ valsT := make([]reflect.Type, len(vals))
+ for valsI, v := range vals {
+ valsT[valsI] = reflect.TypeOf(v)
+ }
+ for i := range types {
+ if valsT[i] != types[i] {
+ return fmt.Errorf("mismatched types in corpus entry: %v, want %v", valsT, types)
+ }
+ }
+ return nil
+}
+
+// writeToCorpus atomically writes the given bytes to a new file in testdata. If
+// the directory does not exist, it will create one. If the file already exists,
+// writeToCorpus will not rewrite it. writeToCorpus sets entry.Path to the new
+// file that was just written or an error if it failed.
+func writeToCorpus(entry *CorpusEntry, dir string) (err error) {
+ sum := fmt.Sprintf("%x", sha256.Sum256(entry.Data))[:16]
+ entry.Path = filepath.Join(dir, sum)
+ if err := os.MkdirAll(dir, 0777); err != nil {
+ return err
+ }
+ if err := os.WriteFile(entry.Path, entry.Data, 0666); err != nil {
+ os.Remove(entry.Path) // remove partially written file
+ return err
+ }
+ return nil
+}
+
+func testName(path string) string {
+ return filepath.Base(path)
+}
+
+func zeroValue(t reflect.Type) any {
+ for _, v := range zeroVals {
+ if reflect.TypeOf(v) == t {
+ return v
+ }
+ }
+ panic(fmt.Sprintf("unsupported type: %v", t))
+}
+
+var zeroVals []any = []any{
+ []byte(""),
+ string(""),
+ false,
+ byte(0),
+ rune(0),
+ float32(0),
+ float64(0),
+ int(0),
+ int8(0),
+ int16(0),
+ int32(0),
+ int64(0),
+ uint(0),
+ uint8(0),
+ uint16(0),
+ uint32(0),
+ uint64(0),
+}
+
+var debugInfo = godebug.New("#fuzzdebug").Value() == "1"
+
+func shouldPrintDebugInfo() bool {
+ return debugInfo
+}
+
+func (c *coordinator) debugLogf(format string, args ...any) {
+ t := time.Now().Format("2006-01-02 15:04:05.999999999")
+ fmt.Fprintf(c.opts.Log, t+" DEBUG "+format+"\n", args...)
+}
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/mem.go b/contrib/go/_std_1.21/src/internal/fuzz/mem.go
index 4155e4e83e..4155e4e83e 100644
--- a/contrib/go/_std_1.20/src/internal/fuzz/mem.go
+++ b/contrib/go/_std_1.21/src/internal/fuzz/mem.go
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/minimize.go b/contrib/go/_std_1.21/src/internal/fuzz/minimize.go
index 0e410fb86a..0e410fb86a 100644
--- a/contrib/go/_std_1.20/src/internal/fuzz/minimize.go
+++ b/contrib/go/_std_1.21/src/internal/fuzz/minimize.go
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/mutator.go b/contrib/go/_std_1.21/src/internal/fuzz/mutator.go
index bb960660ae..bb960660ae 100644
--- a/contrib/go/_std_1.20/src/internal/fuzz/mutator.go
+++ b/contrib/go/_std_1.21/src/internal/fuzz/mutator.go
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/mutators_byteslice.go b/contrib/go/_std_1.21/src/internal/fuzz/mutators_byteslice.go
index d9dab1df9f..d9dab1df9f 100644
--- a/contrib/go/_std_1.20/src/internal/fuzz/mutators_byteslice.go
+++ b/contrib/go/_std_1.21/src/internal/fuzz/mutators_byteslice.go
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/pcg.go b/contrib/go/_std_1.21/src/internal/fuzz/pcg.go
index c9ea0afcf8..c9ea0afcf8 100644
--- a/contrib/go/_std_1.20/src/internal/fuzz/pcg.go
+++ b/contrib/go/_std_1.21/src/internal/fuzz/pcg.go
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/queue.go b/contrib/go/_std_1.21/src/internal/fuzz/queue.go
index 195d6eb7b6..195d6eb7b6 100644
--- a/contrib/go/_std_1.20/src/internal/fuzz/queue.go
+++ b/contrib/go/_std_1.21/src/internal/fuzz/queue.go
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/sys_posix.go b/contrib/go/_std_1.21/src/internal/fuzz/sys_posix.go
index fec6054f67..fec6054f67 100644
--- a/contrib/go/_std_1.20/src/internal/fuzz/sys_posix.go
+++ b/contrib/go/_std_1.21/src/internal/fuzz/sys_posix.go
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/sys_windows.go b/contrib/go/_std_1.21/src/internal/fuzz/sys_windows.go
index aa85be7e1c..aa85be7e1c 100644
--- a/contrib/go/_std_1.20/src/internal/fuzz/sys_windows.go
+++ b/contrib/go/_std_1.21/src/internal/fuzz/sys_windows.go
diff --git a/contrib/go/_std_1.20/src/internal/fuzz/trace.go b/contrib/go/_std_1.21/src/internal/fuzz/trace.go
index b471914850..b471914850 100644
--- a/contrib/go/_std_1.20/src/internal/fuzz/trace.go
+++ b/contrib/go/_std_1.21/src/internal/fuzz/trace.go
diff --git a/contrib/go/_std_1.21/src/internal/fuzz/worker.go b/contrib/go/_std_1.21/src/internal/fuzz/worker.go
new file mode 100644
index 0000000000..c952670995
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/fuzz/worker.go
@@ -0,0 +1,1195 @@
+// 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 fuzz
+
+import (
+ "bytes"
+ "context"
+ "crypto/sha256"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "os/exec"
+ "reflect"
+ "runtime"
+ "sync"
+ "time"
+)
+
+const (
+ // workerFuzzDuration is the amount of time a worker can spend testing random
+ // variations of an input given by the coordinator.
+ workerFuzzDuration = 100 * time.Millisecond
+
+ // workerTimeoutDuration is the amount of time a worker can go without
+ // responding to the coordinator before being stopped.
+ workerTimeoutDuration = 1 * time.Second
+
+ // workerExitCode is used as an exit code by fuzz worker processes after an internal error.
+ // This distinguishes internal errors from uncontrolled panics and other crashes.
+ // Keep in sync with internal/fuzz.workerExitCode.
+ workerExitCode = 70
+
+ // workerSharedMemSize is the maximum size of the shared memory file used to
+ // communicate with workers. This limits the size of fuzz inputs.
+ workerSharedMemSize = 100 << 20 // 100 MB
+)
+
+// worker manages a worker process running a test binary. The worker object
+// exists only in the coordinator (the process started by 'go test -fuzz').
+// workerClient is used by the coordinator to send RPCs to the worker process,
+// which handles them with workerServer.
+type worker struct {
+ dir string // working directory, same as package directory
+ binPath string // path to test executable
+ args []string // arguments for test executable
+ env []string // environment for test executable
+
+ coordinator *coordinator
+
+ memMu chan *sharedMem // mutex guarding shared memory with worker; persists across processes.
+
+ cmd *exec.Cmd // current worker process
+ client *workerClient // used to communicate with worker process
+ waitErr error // last error returned by wait, set before termC is closed.
+ interrupted bool // true after stop interrupts a running worker.
+ termC chan struct{} // closed by wait when worker process terminates
+}
+
+func newWorker(c *coordinator, dir, binPath string, args, env []string) (*worker, error) {
+ mem, err := sharedMemTempFile(workerSharedMemSize)
+ if err != nil {
+ return nil, err
+ }
+ memMu := make(chan *sharedMem, 1)
+ memMu <- mem
+ return &worker{
+ dir: dir,
+ binPath: binPath,
+ args: args,
+ env: env[:len(env):len(env)], // copy on append to ensure workers don't overwrite each other.
+ coordinator: c,
+ memMu: memMu,
+ }, nil
+}
+
+// cleanup releases persistent resources associated with the worker.
+func (w *worker) cleanup() error {
+ mem := <-w.memMu
+ if mem == nil {
+ return nil
+ }
+ close(w.memMu)
+ return mem.Close()
+}
+
+// coordinate runs the test binary to perform fuzzing.
+//
+// coordinate loops until ctx is cancelled or a fatal error is encountered.
+// If a test process terminates unexpectedly while fuzzing, coordinate will
+// attempt to restart and continue unless the termination can be attributed
+// to an interruption (from a timer or the user).
+//
+// While looping, coordinate receives inputs from the coordinator, passes
+// those inputs to the worker process, then passes the results back to
+// the coordinator.
+func (w *worker) coordinate(ctx context.Context) error {
+ // Main event loop.
+ for {
+ // Start or restart the worker if it's not running.
+ if !w.isRunning() {
+ if err := w.startAndPing(ctx); err != nil {
+ return err
+ }
+ }
+
+ select {
+ case <-ctx.Done():
+ // Worker was told to stop.
+ err := w.stop()
+ if err != nil && !w.interrupted && !isInterruptError(err) {
+ return err
+ }
+ return ctx.Err()
+
+ case <-w.termC:
+ // Worker process terminated unexpectedly while waiting for input.
+ err := w.stop()
+ if w.interrupted {
+ panic("worker interrupted after unexpected termination")
+ }
+ if err == nil || isInterruptError(err) {
+ // Worker stopped, either by exiting with status 0 or after being
+ // interrupted with a signal that was not sent by the coordinator.
+ //
+ // When the user presses ^C, on POSIX platforms, SIGINT is delivered to
+ // all processes in the group concurrently, and the worker may see it
+ // before the coordinator. The worker should exit 0 gracefully (in
+ // theory).
+ //
+ // This condition is probably intended by the user, so suppress
+ // the error.
+ return nil
+ }
+ if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == workerExitCode {
+ // Worker exited with a code indicating F.Fuzz was not called correctly,
+ // for example, F.Fail was called first.
+ return fmt.Errorf("fuzzing process exited unexpectedly due to an internal failure: %w", err)
+ }
+ // Worker exited non-zero or was terminated by a non-interrupt
+ // signal (for example, SIGSEGV) while fuzzing.
+ return fmt.Errorf("fuzzing process hung or terminated unexpectedly: %w", err)
+ // TODO(jayconrod,katiehockman): if -keepfuzzing, restart worker.
+
+ case input := <-w.coordinator.inputC:
+ // Received input from coordinator.
+ args := fuzzArgs{
+ Limit: input.limit,
+ Timeout: input.timeout,
+ Warmup: input.warmup,
+ CoverageData: input.coverageData,
+ }
+ entry, resp, isInternalError, err := w.client.fuzz(ctx, input.entry, args)
+ canMinimize := true
+ if err != nil {
+ // Error communicating with worker.
+ w.stop()
+ if ctx.Err() != nil {
+ // Timeout or interruption.
+ return ctx.Err()
+ }
+ if w.interrupted {
+ // Communication error before we stopped the worker.
+ // Report an error, but don't record a crasher.
+ return fmt.Errorf("communicating with fuzzing process: %v", err)
+ }
+ if sig, ok := terminationSignal(w.waitErr); ok && !isCrashSignal(sig) {
+ // Worker terminated by a signal that probably wasn't caused by a
+ // specific input to the fuzz function. For example, on Linux,
+ // the kernel (OOM killer) may send SIGKILL to a process using a lot
+ // of memory. Or the shell might send SIGHUP when the terminal
+ // is closed. Don't record a crasher.
+ return fmt.Errorf("fuzzing process terminated by unexpected signal; no crash will be recorded: %v", w.waitErr)
+ }
+ if isInternalError {
+ // An internal error occurred which shouldn't be considered
+ // a crash.
+ return err
+ }
+ // Unexpected termination. Set error message and fall through.
+ // We'll restart the worker on the next iteration.
+ // Don't attempt to minimize this since it crashed the worker.
+ resp.Err = fmt.Sprintf("fuzzing process hung or terminated unexpectedly: %v", w.waitErr)
+ canMinimize = false
+ }
+ result := fuzzResult{
+ limit: input.limit,
+ count: resp.Count,
+ totalDuration: resp.TotalDuration,
+ entryDuration: resp.InterestingDuration,
+ entry: entry,
+ crasherMsg: resp.Err,
+ coverageData: resp.CoverageData,
+ canMinimize: canMinimize,
+ }
+ w.coordinator.resultC <- result
+
+ case input := <-w.coordinator.minimizeC:
+ // Received input to minimize from coordinator.
+ result, err := w.minimize(ctx, input)
+ if err != nil {
+ // Error minimizing. Send back the original input. If it didn't cause
+ // an error before, report it as causing an error now.
+ // TODO: double-check this is handled correctly when
+ // implementing -keepfuzzing.
+ result = fuzzResult{
+ entry: input.entry,
+ crasherMsg: input.crasherMsg,
+ canMinimize: false,
+ limit: input.limit,
+ }
+ if result.crasherMsg == "" {
+ result.crasherMsg = err.Error()
+ }
+ }
+ if shouldPrintDebugInfo() {
+ w.coordinator.debugLogf(
+ "input minimized, id: %s, original id: %s, crasher: %t, originally crasher: %t, minimizing took: %s",
+ result.entry.Path,
+ input.entry.Path,
+ result.crasherMsg != "",
+ input.crasherMsg != "",
+ result.totalDuration,
+ )
+ }
+ w.coordinator.resultC <- result
+ }
+ }
+}
+
+// minimize tells a worker process to attempt to find a smaller value that
+// either causes an error (if we started minimizing because we found an input
+// that causes an error) or preserves new coverage (if we started minimizing
+// because we found an input that expands coverage).
+func (w *worker) minimize(ctx context.Context, input fuzzMinimizeInput) (min fuzzResult, err error) {
+ if w.coordinator.opts.MinimizeTimeout != 0 {
+ var cancel func()
+ ctx, cancel = context.WithTimeout(ctx, w.coordinator.opts.MinimizeTimeout)
+ defer cancel()
+ }
+
+ args := minimizeArgs{
+ Limit: input.limit,
+ Timeout: input.timeout,
+ KeepCoverage: input.keepCoverage,
+ }
+ entry, resp, err := w.client.minimize(ctx, input.entry, args)
+ if err != nil {
+ // Error communicating with worker.
+ w.stop()
+ if ctx.Err() != nil || w.interrupted || isInterruptError(w.waitErr) {
+ // Worker was interrupted, possibly by the user pressing ^C.
+ // Normally, workers can handle interrupts and timeouts gracefully and
+ // will return without error. An error here indicates the worker
+ // may not have been in a good state, but the error won't be meaningful
+ // to the user. Just return the original crasher without logging anything.
+ return fuzzResult{
+ entry: input.entry,
+ crasherMsg: input.crasherMsg,
+ coverageData: input.keepCoverage,
+ canMinimize: false,
+ limit: input.limit,
+ }, nil
+ }
+ return fuzzResult{
+ entry: entry,
+ crasherMsg: fmt.Sprintf("fuzzing process hung or terminated unexpectedly while minimizing: %v", err),
+ canMinimize: false,
+ limit: input.limit,
+ count: resp.Count,
+ totalDuration: resp.Duration,
+ }, nil
+ }
+
+ if input.crasherMsg != "" && resp.Err == "" {
+ return fuzzResult{}, fmt.Errorf("attempted to minimize a crash but could not reproduce")
+ }
+
+ return fuzzResult{
+ entry: entry,
+ crasherMsg: resp.Err,
+ coverageData: resp.CoverageData,
+ canMinimize: false,
+ limit: input.limit,
+ count: resp.Count,
+ totalDuration: resp.Duration,
+ }, nil
+}
+
+func (w *worker) isRunning() bool {
+ return w.cmd != nil
+}
+
+// startAndPing starts the worker process and sends it a message to make sure it
+// can communicate.
+//
+// startAndPing returns an error if any part of this didn't work, including if
+// the context is expired or the worker process was interrupted before it
+// responded. Errors that happen after start but before the ping response
+// likely indicate that the worker did not call F.Fuzz or called F.Fail first.
+// We don't record crashers for these errors.
+func (w *worker) startAndPing(ctx context.Context) error {
+ if ctx.Err() != nil {
+ return ctx.Err()
+ }
+ if err := w.start(); err != nil {
+ return err
+ }
+ if err := w.client.ping(ctx); err != nil {
+ w.stop()
+ if ctx.Err() != nil {
+ return ctx.Err()
+ }
+ if isInterruptError(err) {
+ // User may have pressed ^C before worker responded.
+ return err
+ }
+ // TODO: record and return stderr.
+ return fmt.Errorf("fuzzing process terminated without fuzzing: %w", err)
+ }
+ return nil
+}
+
+// start runs a new worker process.
+//
+// If the process couldn't be started, start returns an error. Start won't
+// return later termination errors from the process if they occur.
+//
+// If the process starts successfully, start returns nil. stop must be called
+// once later to clean up, even if the process terminates on its own.
+//
+// When the process terminates, w.waitErr is set to the error (if any), and
+// w.termC is closed.
+func (w *worker) start() (err error) {
+ if w.isRunning() {
+ panic("worker already started")
+ }
+ w.waitErr = nil
+ w.interrupted = false
+ w.termC = nil
+
+ cmd := exec.Command(w.binPath, w.args...)
+ cmd.Dir = w.dir
+ cmd.Env = w.env[:len(w.env):len(w.env)] // copy on append to ensure workers don't overwrite each other.
+
+ // Create the "fuzz_in" and "fuzz_out" pipes so we can communicate with
+ // the worker. We don't use stdin and stdout, since the test binary may
+ // do something else with those.
+ //
+ // Each pipe has a reader and a writer. The coordinator writes to fuzzInW
+ // and reads from fuzzOutR. The worker inherits fuzzInR and fuzzOutW.
+ // The coordinator closes fuzzInR and fuzzOutW after starting the worker,
+ // since we have no further need of them.
+ fuzzInR, fuzzInW, err := os.Pipe()
+ if err != nil {
+ return err
+ }
+ defer fuzzInR.Close()
+ fuzzOutR, fuzzOutW, err := os.Pipe()
+ if err != nil {
+ fuzzInW.Close()
+ return err
+ }
+ defer fuzzOutW.Close()
+ setWorkerComm(cmd, workerComm{fuzzIn: fuzzInR, fuzzOut: fuzzOutW, memMu: w.memMu})
+
+ // Start the worker process.
+ if err := cmd.Start(); err != nil {
+ fuzzInW.Close()
+ fuzzOutR.Close()
+ return err
+ }
+
+ // Worker started successfully.
+ // After this, w.client owns fuzzInW and fuzzOutR, so w.client.Close must be
+ // called later by stop.
+ w.cmd = cmd
+ w.termC = make(chan struct{})
+ comm := workerComm{fuzzIn: fuzzInW, fuzzOut: fuzzOutR, memMu: w.memMu}
+ m := newMutator()
+ w.client = newWorkerClient(comm, m)
+
+ go func() {
+ w.waitErr = w.cmd.Wait()
+ close(w.termC)
+ }()
+
+ return nil
+}
+
+// stop tells the worker process to exit by closing w.client, then blocks until
+// it terminates. If the worker doesn't terminate after a short time, stop
+// signals it with os.Interrupt (where supported), then os.Kill.
+//
+// stop returns the error the process terminated with, if any (same as
+// w.waitErr).
+//
+// stop must be called at least once after start returns successfully, even if
+// the worker process terminates unexpectedly.
+func (w *worker) stop() error {
+ if w.termC == nil {
+ panic("worker was not started successfully")
+ }
+ select {
+ case <-w.termC:
+ // Worker already terminated.
+ if w.client == nil {
+ // stop already called.
+ return w.waitErr
+ }
+ // Possible unexpected termination.
+ w.client.Close()
+ w.cmd = nil
+ w.client = nil
+ return w.waitErr
+ default:
+ // Worker still running.
+ }
+
+ // Tell the worker to stop by closing fuzz_in. It won't actually stop until it
+ // finishes with earlier calls.
+ closeC := make(chan struct{})
+ go func() {
+ w.client.Close()
+ close(closeC)
+ }()
+
+ sig := os.Interrupt
+ if runtime.GOOS == "windows" {
+ // Per https://golang.org/pkg/os/#Signal, “Interrupt is not implemented on
+ // Windows; using it with os.Process.Signal will return an error.”
+ // Fall back to Kill instead.
+ sig = os.Kill
+ }
+
+ t := time.NewTimer(workerTimeoutDuration)
+ for {
+ select {
+ case <-w.termC:
+ // Worker terminated.
+ t.Stop()
+ <-closeC
+ w.cmd = nil
+ w.client = nil
+ return w.waitErr
+
+ case <-t.C:
+ // Timer fired before worker terminated.
+ w.interrupted = true
+ switch sig {
+ case os.Interrupt:
+ // Try to stop the worker with SIGINT and wait a little longer.
+ w.cmd.Process.Signal(sig)
+ sig = os.Kill
+ t.Reset(workerTimeoutDuration)
+
+ case os.Kill:
+ // Try to stop the worker with SIGKILL and keep waiting.
+ w.cmd.Process.Signal(sig)
+ sig = nil
+ t.Reset(workerTimeoutDuration)
+
+ case nil:
+ // Still waiting. Print a message to let the user know why.
+ fmt.Fprintf(w.coordinator.opts.Log, "waiting for fuzzing process to terminate...\n")
+ }
+ }
+ }
+}
+
+// RunFuzzWorker is called in a worker process to communicate with the
+// coordinator process in order to fuzz random inputs. RunFuzzWorker loops
+// until the coordinator tells it to stop.
+//
+// fn is a wrapper on the fuzz function. It may return an error to indicate
+// a given input "crashed". The coordinator will also record a crasher if
+// the function times out or terminates the process.
+//
+// RunFuzzWorker returns an error if it could not communicate with the
+// coordinator process.
+func RunFuzzWorker(ctx context.Context, fn func(CorpusEntry) error) error {
+ comm, err := getWorkerComm()
+ if err != nil {
+ return err
+ }
+ srv := &workerServer{
+ workerComm: comm,
+ fuzzFn: func(e CorpusEntry) (time.Duration, error) {
+ timer := time.AfterFunc(10*time.Second, func() {
+ panic("deadlocked!") // this error message won't be printed
+ })
+ defer timer.Stop()
+ start := time.Now()
+ err := fn(e)
+ return time.Since(start), err
+ },
+ m: newMutator(),
+ }
+ return srv.serve(ctx)
+}
+
+// call is serialized and sent from the coordinator on fuzz_in. It acts as
+// a minimalist RPC mechanism. Exactly one of its fields must be set to indicate
+// which method to call.
+type call struct {
+ Ping *pingArgs
+ Fuzz *fuzzArgs
+ Minimize *minimizeArgs
+}
+
+// minimizeArgs contains arguments to workerServer.minimize. The value to
+// minimize is already in shared memory.
+type minimizeArgs struct {
+ // Timeout is the time to spend minimizing. This may include time to start up,
+ // especially if the input causes the worker process to terminated, requiring
+ // repeated restarts.
+ Timeout time.Duration
+
+ // Limit is the maximum number of values to test, without spending more time
+ // than Duration. 0 indicates no limit.
+ Limit int64
+
+ // KeepCoverage is a set of coverage counters the worker should attempt to
+ // keep in minimized values. When provided, the worker will reject inputs that
+ // don't cause at least one of these bits to be set.
+ KeepCoverage []byte
+
+ // Index is the index of the fuzz target parameter to be minimized.
+ Index int
+}
+
+// minimizeResponse contains results from workerServer.minimize.
+type minimizeResponse struct {
+ // WroteToMem is true if the worker found a smaller input and wrote it to
+ // shared memory. If minimizeArgs.KeepCoverage was set, the minimized input
+ // preserved at least one coverage bit and did not cause an error.
+ // Otherwise, the minimized input caused some error, recorded in Err.
+ WroteToMem bool
+
+ // Err is the error string caused by the value in shared memory, if any.
+ Err string
+
+ // CoverageData is the set of coverage bits activated by the minimized value
+ // in shared memory. When set, it contains at least one bit from KeepCoverage.
+ // CoverageData will be nil if Err is set or if minimization failed.
+ CoverageData []byte
+
+ // Duration is the time spent minimizing, not including starting or cleaning up.
+ Duration time.Duration
+
+ // Count is the number of values tested.
+ Count int64
+}
+
+// fuzzArgs contains arguments to workerServer.fuzz. The value to fuzz is
+// passed in shared memory.
+type fuzzArgs struct {
+ // Timeout is the time to spend fuzzing, not including starting or
+ // cleaning up.
+ Timeout time.Duration
+
+ // Limit is the maximum number of values to test, without spending more time
+ // than Duration. 0 indicates no limit.
+ Limit int64
+
+ // Warmup indicates whether this is part of a warmup run, meaning that
+ // fuzzing should not occur. If coverageEnabled is true, then coverage data
+ // should be reported.
+ Warmup bool
+
+ // CoverageData is the coverage data. If set, the worker should update its
+ // local coverage data prior to fuzzing.
+ CoverageData []byte
+}
+
+// fuzzResponse contains results from workerServer.fuzz.
+type fuzzResponse struct {
+ // Duration is the time spent fuzzing, not including starting or cleaning up.
+ TotalDuration time.Duration
+ InterestingDuration time.Duration
+
+ // Count is the number of values tested.
+ Count int64
+
+ // CoverageData is set if the value in shared memory expands coverage
+ // and therefore may be interesting to the coordinator.
+ CoverageData []byte
+
+ // Err is the error string caused by the value in shared memory, which is
+ // non-empty if the value in shared memory caused a crash.
+ Err string
+
+ // InternalErr is the error string caused by an internal error in the
+ // worker. This shouldn't be considered a crasher.
+ InternalErr string
+}
+
+// pingArgs contains arguments to workerServer.ping.
+type pingArgs struct{}
+
+// pingResponse contains results from workerServer.ping.
+type pingResponse struct{}
+
+// workerComm holds pipes and shared memory used for communication
+// between the coordinator process (client) and a worker process (server).
+// These values are unique to each worker; they are shared only with the
+// coordinator, not with other workers.
+//
+// Access to shared memory is synchronized implicitly over the RPC protocol
+// implemented in workerServer and workerClient. During a call, the client
+// (worker) has exclusive access to shared memory; at other times, the server
+// (coordinator) has exclusive access.
+type workerComm struct {
+ fuzzIn, fuzzOut *os.File
+ memMu chan *sharedMem // mutex guarding shared memory
+}
+
+// workerServer is a minimalist RPC server, run by fuzz worker processes.
+// It allows the coordinator process (using workerClient) to call methods in a
+// worker process. This system allows the coordinator to run multiple worker
+// processes in parallel and to collect inputs that caused crashes from shared
+// memory after a worker process terminates unexpectedly.
+type workerServer struct {
+ workerComm
+ m *mutator
+
+ // coverageMask is the local coverage data for the worker. It is
+ // periodically updated to reflect the data in the coordinator when new
+ // coverage is found.
+ coverageMask []byte
+
+ // fuzzFn runs the worker's fuzz target on the given input and returns an
+ // error if it finds a crasher (the process may also exit or crash), and the
+ // time it took to run the input. It sets a deadline of 10 seconds, at which
+ // point it will panic with the assumption that the process is hanging or
+ // deadlocked.
+ fuzzFn func(CorpusEntry) (time.Duration, error)
+}
+
+// serve reads serialized RPC messages on fuzzIn. When serve receives a message,
+// it calls the corresponding method, then sends the serialized result back
+// on fuzzOut.
+//
+// serve handles RPC calls synchronously; it will not attempt to read a message
+// until the previous call has finished.
+//
+// serve returns errors that occurred when communicating over pipes. serve
+// does not return errors from method calls; those are passed through serialized
+// responses.
+func (ws *workerServer) serve(ctx context.Context) error {
+ enc := json.NewEncoder(ws.fuzzOut)
+ dec := json.NewDecoder(&contextReader{ctx: ctx, r: ws.fuzzIn})
+ for {
+ var c call
+ if err := dec.Decode(&c); err != nil {
+ if err == io.EOF || err == ctx.Err() {
+ return nil
+ } else {
+ return err
+ }
+ }
+
+ var resp any
+ switch {
+ case c.Fuzz != nil:
+ resp = ws.fuzz(ctx, *c.Fuzz)
+ case c.Minimize != nil:
+ resp = ws.minimize(ctx, *c.Minimize)
+ case c.Ping != nil:
+ resp = ws.ping(ctx, *c.Ping)
+ default:
+ return errors.New("no arguments provided for any call")
+ }
+
+ if err := enc.Encode(resp); err != nil {
+ return err
+ }
+ }
+}
+
+// chainedMutations is how many mutations are applied before the worker
+// resets the input to it's original state.
+// NOTE: this number was picked without much thought. It is low enough that
+// it seems to create a significant diversity in mutated inputs. We may want
+// to consider looking into this more closely once we have a proper performance
+// testing framework. Another option is to randomly pick the number of chained
+// mutations on each invocation of the workerServer.fuzz method (this appears to
+// be what libFuzzer does, although there seems to be no documentation which
+// explains why this choice was made.)
+const chainedMutations = 5
+
+// fuzz runs the test function on random variations of the input value in shared
+// memory for a limited duration or number of iterations.
+//
+// fuzz returns early if it finds an input that crashes the fuzz function (with
+// fuzzResponse.Err set) or an input that expands coverage (with
+// fuzzResponse.InterestingDuration set).
+//
+// fuzz does not modify the input in shared memory. Instead, it saves the
+// initial PRNG state in shared memory and increments a counter in shared
+// memory before each call to the test function. The caller may reconstruct
+// the crashing input with this information, since the PRNG is deterministic.
+func (ws *workerServer) fuzz(ctx context.Context, args fuzzArgs) (resp fuzzResponse) {
+ if args.CoverageData != nil {
+ if ws.coverageMask != nil && len(args.CoverageData) != len(ws.coverageMask) {
+ resp.InternalErr = fmt.Sprintf("unexpected size for CoverageData: got %d, expected %d", len(args.CoverageData), len(ws.coverageMask))
+ return resp
+ }
+ ws.coverageMask = args.CoverageData
+ }
+ start := time.Now()
+ defer func() { resp.TotalDuration = time.Since(start) }()
+
+ if args.Timeout != 0 {
+ var cancel func()
+ ctx, cancel = context.WithTimeout(ctx, args.Timeout)
+ defer cancel()
+ }
+ mem := <-ws.memMu
+ ws.m.r.save(&mem.header().randState, &mem.header().randInc)
+ defer func() {
+ resp.Count = mem.header().count
+ ws.memMu <- mem
+ }()
+ if args.Limit > 0 && mem.header().count >= args.Limit {
+ resp.InternalErr = fmt.Sprintf("mem.header().count %d already exceeds args.Limit %d", mem.header().count, args.Limit)
+ return resp
+ }
+
+ originalVals, err := unmarshalCorpusFile(mem.valueCopy())
+ if err != nil {
+ resp.InternalErr = err.Error()
+ return resp
+ }
+ vals := make([]any, len(originalVals))
+ copy(vals, originalVals)
+
+ shouldStop := func() bool {
+ return args.Limit > 0 && mem.header().count >= args.Limit
+ }
+ fuzzOnce := func(entry CorpusEntry) (dur time.Duration, cov []byte, errMsg string) {
+ mem.header().count++
+ var err error
+ dur, err = ws.fuzzFn(entry)
+ if err != nil {
+ errMsg = err.Error()
+ if errMsg == "" {
+ errMsg = "fuzz function failed with no input"
+ }
+ return dur, nil, errMsg
+ }
+ if ws.coverageMask != nil && countNewCoverageBits(ws.coverageMask, coverageSnapshot) > 0 {
+ return dur, coverageSnapshot, ""
+ }
+ return dur, nil, ""
+ }
+
+ if args.Warmup {
+ dur, _, errMsg := fuzzOnce(CorpusEntry{Values: vals})
+ if errMsg != "" {
+ resp.Err = errMsg
+ return resp
+ }
+ resp.InterestingDuration = dur
+ if coverageEnabled {
+ resp.CoverageData = coverageSnapshot
+ }
+ return resp
+ }
+
+ for {
+ select {
+ case <-ctx.Done():
+ return resp
+ default:
+ if mem.header().count%chainedMutations == 0 {
+ copy(vals, originalVals)
+ ws.m.r.save(&mem.header().randState, &mem.header().randInc)
+ }
+ ws.m.mutate(vals, cap(mem.valueRef()))
+
+ entry := CorpusEntry{Values: vals}
+ dur, cov, errMsg := fuzzOnce(entry)
+ if errMsg != "" {
+ resp.Err = errMsg
+ return resp
+ }
+ if cov != nil {
+ resp.CoverageData = cov
+ resp.InterestingDuration = dur
+ return resp
+ }
+ if shouldStop() {
+ return resp
+ }
+ }
+ }
+}
+
+func (ws *workerServer) minimize(ctx context.Context, args minimizeArgs) (resp minimizeResponse) {
+ start := time.Now()
+ defer func() { resp.Duration = time.Since(start) }()
+ mem := <-ws.memMu
+ defer func() { ws.memMu <- mem }()
+ vals, err := unmarshalCorpusFile(mem.valueCopy())
+ if err != nil {
+ panic(err)
+ }
+ inpHash := sha256.Sum256(mem.valueCopy())
+ if args.Timeout != 0 {
+ var cancel func()
+ ctx, cancel = context.WithTimeout(ctx, args.Timeout)
+ defer cancel()
+ }
+
+ // Minimize the values in vals, then write to shared memory. We only write
+ // to shared memory after completing minimization.
+ success, err := ws.minimizeInput(ctx, vals, mem, args)
+ if success {
+ writeToMem(vals, mem)
+ outHash := sha256.Sum256(mem.valueCopy())
+ mem.header().rawInMem = false
+ resp.WroteToMem = true
+ if err != nil {
+ resp.Err = err.Error()
+ } else {
+ // If the values didn't change during minimization then coverageSnapshot is likely
+ // a dirty snapshot which represents the very last step of minimization, not the
+ // coverage for the initial input. In that case just return the coverage we were
+ // given initially, since it more accurately represents the coverage map for the
+ // input we are returning.
+ if outHash != inpHash {
+ resp.CoverageData = coverageSnapshot
+ } else {
+ resp.CoverageData = args.KeepCoverage
+ }
+ }
+ }
+ return resp
+}
+
+// minimizeInput applies a series of minimizing transformations on the provided
+// vals, ensuring that each minimization still causes an error, or keeps
+// coverage, in fuzzFn. It uses the context to determine how long to run,
+// stopping once closed. It returns a bool indicating whether minimization was
+// successful and an error if one was found.
+func (ws *workerServer) minimizeInput(ctx context.Context, vals []any, mem *sharedMem, args minimizeArgs) (success bool, retErr error) {
+ keepCoverage := args.KeepCoverage
+ memBytes := mem.valueRef()
+ bPtr := &memBytes
+ count := &mem.header().count
+ shouldStop := func() bool {
+ return ctx.Err() != nil ||
+ (args.Limit > 0 && *count >= args.Limit)
+ }
+ if shouldStop() {
+ return false, nil
+ }
+
+ // Check that the original value preserves coverage or causes an error.
+ // If not, then whatever caused us to think the value was interesting may
+ // have been a flake, and we can't minimize it.
+ *count++
+ _, retErr = ws.fuzzFn(CorpusEntry{Values: vals})
+ if keepCoverage != nil {
+ if !hasCoverageBit(keepCoverage, coverageSnapshot) || retErr != nil {
+ return false, nil
+ }
+ } else if retErr == nil {
+ return false, nil
+ }
+ mem.header().rawInMem = true
+
+ // tryMinimized runs the fuzz function with candidate replacing the value
+ // at index valI. tryMinimized returns whether the input with candidate is
+ // interesting for the same reason as the original input: it returns
+ // an error if one was expected, or it preserves coverage.
+ tryMinimized := func(candidate []byte) bool {
+ prev := vals[args.Index]
+ switch prev.(type) {
+ case []byte:
+ vals[args.Index] = candidate
+ case string:
+ vals[args.Index] = string(candidate)
+ default:
+ panic("impossible")
+ }
+ copy(*bPtr, candidate)
+ *bPtr = (*bPtr)[:len(candidate)]
+ mem.setValueLen(len(candidate))
+ *count++
+ _, err := ws.fuzzFn(CorpusEntry{Values: vals})
+ if err != nil {
+ retErr = err
+ if keepCoverage != nil {
+ // Now that we've found a crash, that's more important than any
+ // minimization of interesting inputs that was being done. Clear out
+ // keepCoverage to only minimize the crash going forward.
+ keepCoverage = nil
+ }
+ return true
+ }
+ // Minimization should preserve coverage bits.
+ if keepCoverage != nil && isCoverageSubset(keepCoverage, coverageSnapshot) {
+ return true
+ }
+ vals[args.Index] = prev
+ return false
+ }
+ switch v := vals[args.Index].(type) {
+ case string:
+ minimizeBytes([]byte(v), tryMinimized, shouldStop)
+ case []byte:
+ minimizeBytes(v, tryMinimized, shouldStop)
+ default:
+ panic("impossible")
+ }
+ return true, retErr
+}
+
+func writeToMem(vals []any, mem *sharedMem) {
+ b := marshalCorpusFile(vals...)
+ mem.setValue(b)
+}
+
+// ping does nothing. The coordinator calls this method to ensure the worker
+// has called F.Fuzz and can communicate.
+func (ws *workerServer) ping(ctx context.Context, args pingArgs) pingResponse {
+ return pingResponse{}
+}
+
+// workerClient is a minimalist RPC client. The coordinator process uses a
+// workerClient to call methods in each worker process (handled by
+// workerServer).
+type workerClient struct {
+ workerComm
+ m *mutator
+
+ // mu is the mutex protecting the workerComm.fuzzIn pipe. This must be
+ // locked before making calls to the workerServer. It prevents
+ // workerClient.Close from closing fuzzIn while workerClient methods are
+ // writing to it concurrently, and prevents multiple callers from writing to
+ // fuzzIn concurrently.
+ mu sync.Mutex
+}
+
+func newWorkerClient(comm workerComm, m *mutator) *workerClient {
+ return &workerClient{workerComm: comm, m: m}
+}
+
+// Close shuts down the connection to the RPC server (the worker process) by
+// closing fuzz_in. Close drains fuzz_out (avoiding a SIGPIPE in the worker),
+// and closes it after the worker process closes the other end.
+func (wc *workerClient) Close() error {
+ wc.mu.Lock()
+ defer wc.mu.Unlock()
+
+ // Close fuzzIn. This signals to the server that there are no more calls,
+ // and it should exit.
+ if err := wc.fuzzIn.Close(); err != nil {
+ wc.fuzzOut.Close()
+ return err
+ }
+
+ // Drain fuzzOut and close it. When the server exits, the kernel will close
+ // its end of fuzzOut, and we'll get EOF.
+ if _, err := io.Copy(io.Discard, wc.fuzzOut); err != nil {
+ wc.fuzzOut.Close()
+ return err
+ }
+ return wc.fuzzOut.Close()
+}
+
+// errSharedMemClosed is returned by workerClient methods that cannot access
+// shared memory because it was closed and unmapped by another goroutine. That
+// can happen when worker.cleanup is called in the worker goroutine while a
+// workerClient.fuzz call runs concurrently.
+//
+// This error should not be reported. It indicates the operation was
+// interrupted.
+var errSharedMemClosed = errors.New("internal error: shared memory was closed and unmapped")
+
+// minimize tells the worker to call the minimize method. See
+// workerServer.minimize.
+func (wc *workerClient) minimize(ctx context.Context, entryIn CorpusEntry, args minimizeArgs) (entryOut CorpusEntry, resp minimizeResponse, retErr error) {
+ wc.mu.Lock()
+ defer wc.mu.Unlock()
+
+ mem, ok := <-wc.memMu
+ if !ok {
+ return CorpusEntry{}, minimizeResponse{}, errSharedMemClosed
+ }
+ defer func() { wc.memMu <- mem }()
+ mem.header().count = 0
+ inp, err := corpusEntryData(entryIn)
+ if err != nil {
+ return CorpusEntry{}, minimizeResponse{}, err
+ }
+ mem.setValue(inp)
+ entryOut = entryIn
+ entryOut.Values, err = unmarshalCorpusFile(inp)
+ if err != nil {
+ return CorpusEntry{}, minimizeResponse{}, fmt.Errorf("workerClient.minimize unmarshaling provided value: %v", err)
+ }
+ for i, v := range entryOut.Values {
+ if !isMinimizable(reflect.TypeOf(v)) {
+ continue
+ }
+
+ wc.memMu <- mem
+ args.Index = i
+ c := call{Minimize: &args}
+ callErr := wc.callLocked(ctx, c, &resp)
+ mem, ok = <-wc.memMu
+ if !ok {
+ return CorpusEntry{}, minimizeResponse{}, errSharedMemClosed
+ }
+
+ if callErr != nil {
+ retErr = callErr
+ if !mem.header().rawInMem {
+ // An unrecoverable error occurred before minimization began.
+ return entryIn, minimizeResponse{}, retErr
+ }
+ // An unrecoverable error occurred during minimization. mem now
+ // holds the raw, unmarshalled bytes of entryIn.Values[i] that
+ // caused the error.
+ switch entryOut.Values[i].(type) {
+ case string:
+ entryOut.Values[i] = string(mem.valueCopy())
+ case []byte:
+ entryOut.Values[i] = mem.valueCopy()
+ default:
+ panic("impossible")
+ }
+ entryOut.Data = marshalCorpusFile(entryOut.Values...)
+ // Stop minimizing; another unrecoverable error is likely to occur.
+ break
+ }
+
+ if resp.WroteToMem {
+ // Minimization succeeded, and mem holds the marshaled data.
+ entryOut.Data = mem.valueCopy()
+ entryOut.Values, err = unmarshalCorpusFile(entryOut.Data)
+ if err != nil {
+ return CorpusEntry{}, minimizeResponse{}, fmt.Errorf("workerClient.minimize unmarshaling minimized value: %v", err)
+ }
+ }
+
+ // Prepare for next iteration of the loop.
+ if args.Timeout != 0 {
+ args.Timeout -= resp.Duration
+ if args.Timeout <= 0 {
+ break
+ }
+ }
+ if args.Limit != 0 {
+ args.Limit -= mem.header().count
+ if args.Limit <= 0 {
+ break
+ }
+ }
+ }
+ resp.Count = mem.header().count
+ h := sha256.Sum256(entryOut.Data)
+ entryOut.Path = fmt.Sprintf("%x", h[:4])
+ return entryOut, resp, retErr
+}
+
+// fuzz tells the worker to call the fuzz method. See workerServer.fuzz.
+func (wc *workerClient) fuzz(ctx context.Context, entryIn CorpusEntry, args fuzzArgs) (entryOut CorpusEntry, resp fuzzResponse, isInternalError bool, err error) {
+ wc.mu.Lock()
+ defer wc.mu.Unlock()
+
+ mem, ok := <-wc.memMu
+ if !ok {
+ return CorpusEntry{}, fuzzResponse{}, true, errSharedMemClosed
+ }
+ mem.header().count = 0
+ inp, err := corpusEntryData(entryIn)
+ if err != nil {
+ wc.memMu <- mem
+ return CorpusEntry{}, fuzzResponse{}, true, err
+ }
+ mem.setValue(inp)
+ wc.memMu <- mem
+
+ c := call{Fuzz: &args}
+ callErr := wc.callLocked(ctx, c, &resp)
+ if resp.InternalErr != "" {
+ return CorpusEntry{}, fuzzResponse{}, true, errors.New(resp.InternalErr)
+ }
+ mem, ok = <-wc.memMu
+ if !ok {
+ return CorpusEntry{}, fuzzResponse{}, true, errSharedMemClosed
+ }
+ defer func() { wc.memMu <- mem }()
+ resp.Count = mem.header().count
+
+ if !bytes.Equal(inp, mem.valueRef()) {
+ return CorpusEntry{}, fuzzResponse{}, true, errors.New("workerServer.fuzz modified input")
+ }
+ needEntryOut := callErr != nil || resp.Err != "" ||
+ (!args.Warmup && resp.CoverageData != nil)
+ if needEntryOut {
+ valuesOut, err := unmarshalCorpusFile(inp)
+ if err != nil {
+ return CorpusEntry{}, fuzzResponse{}, true, fmt.Errorf("unmarshaling fuzz input value after call: %v", err)
+ }
+ wc.m.r.restore(mem.header().randState, mem.header().randInc)
+ if !args.Warmup {
+ // Only mutate the valuesOut if fuzzing actually occurred.
+ numMutations := ((resp.Count - 1) % chainedMutations) + 1
+ for i := int64(0); i < numMutations; i++ {
+ wc.m.mutate(valuesOut, cap(mem.valueRef()))
+ }
+ }
+ dataOut := marshalCorpusFile(valuesOut...)
+
+ h := sha256.Sum256(dataOut)
+ name := fmt.Sprintf("%x", h[:4])
+ entryOut = CorpusEntry{
+ Parent: entryIn.Path,
+ Path: name,
+ Data: dataOut,
+ Generation: entryIn.Generation + 1,
+ }
+ if args.Warmup {
+ // The bytes weren't mutated, so if entryIn was a seed corpus value,
+ // then entryOut is too.
+ entryOut.IsSeed = entryIn.IsSeed
+ }
+ }
+
+ return entryOut, resp, false, callErr
+}
+
+// ping tells the worker to call the ping method. See workerServer.ping.
+func (wc *workerClient) ping(ctx context.Context) error {
+ wc.mu.Lock()
+ defer wc.mu.Unlock()
+ c := call{Ping: &pingArgs{}}
+ var resp pingResponse
+ return wc.callLocked(ctx, c, &resp)
+}
+
+// callLocked sends an RPC from the coordinator to the worker process and waits
+// for the response. The callLocked may be cancelled with ctx.
+func (wc *workerClient) callLocked(ctx context.Context, c call, resp any) (err error) {
+ enc := json.NewEncoder(wc.fuzzIn)
+ dec := json.NewDecoder(&contextReader{ctx: ctx, r: wc.fuzzOut})
+ if err := enc.Encode(c); err != nil {
+ return err
+ }
+ return dec.Decode(resp)
+}
+
+// contextReader wraps a Reader with a Context. If the context is cancelled
+// while the underlying reader is blocked, Read returns immediately.
+//
+// This is useful for reading from a pipe. Closing a pipe file descriptor does
+// not unblock pending Reads on that file descriptor. All copies of the pipe's
+// other file descriptor (the write end) must be closed in all processes that
+// inherit it. This is difficult to do correctly in the situation we care about
+// (process group termination).
+type contextReader struct {
+ ctx context.Context
+ r io.Reader
+}
+
+func (cr *contextReader) Read(b []byte) (int, error) {
+ if ctxErr := cr.ctx.Err(); ctxErr != nil {
+ return 0, ctxErr
+ }
+ done := make(chan struct{})
+
+ // This goroutine may stay blocked after Read returns because the underlying
+ // read is blocked.
+ var n int
+ var err error
+ go func() {
+ n, err = cr.r.Read(b)
+ close(done)
+ }()
+
+ select {
+ case <-cr.ctx.Done():
+ return 0, cr.ctx.Err()
+ case <-done:
+ return n, err
+ }
+}
diff --git a/contrib/go/_std_1.21/src/internal/fuzz/ya.make b/contrib/go/_std_1.21/src/internal/fuzz/ya.make
new file mode 100644
index 0000000000..f881437b8b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/fuzz/ya.make
@@ -0,0 +1,48 @@
+GO_LIBRARY()
+
+SRCS(
+ counters_supported.go
+ coverage.go
+ encoding.go
+ fuzz.go
+ mem.go
+ minimize.go
+ mutator.go
+ mutators_byteslice.go
+ pcg.go
+ queue.go
+ trace.go
+ worker.go
+)
+
+GO_TEST_SRCS(
+ encoding_test.go
+ minimize_test.go
+ mutator_test.go
+ mutators_byteslice_test.go
+ queue_test.go
+ worker_test.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ sys_posix.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ sys_posix.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ sys_windows.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/goarch/goarch.go b/contrib/go/_std_1.21/src/internal/goarch/goarch.go
index 3dda62fadc..3dda62fadc 100644
--- a/contrib/go/_std_1.20/src/internal/goarch/goarch.go
+++ b/contrib/go/_std_1.21/src/internal/goarch/goarch.go
diff --git a/contrib/go/_std_1.20/src/internal/goarch/goarch_amd64.go b/contrib/go/_std_1.21/src/internal/goarch/goarch_amd64.go
index 911e3e7242..911e3e7242 100644
--- a/contrib/go/_std_1.20/src/internal/goarch/goarch_amd64.go
+++ b/contrib/go/_std_1.21/src/internal/goarch/goarch_amd64.go
diff --git a/contrib/go/_std_1.20/src/internal/goarch/goarch_arm64.go b/contrib/go/_std_1.21/src/internal/goarch/goarch_arm64.go
index 85d0b47639..85d0b47639 100644
--- a/contrib/go/_std_1.20/src/internal/goarch/goarch_arm64.go
+++ b/contrib/go/_std_1.21/src/internal/goarch/goarch_arm64.go
diff --git a/contrib/go/_std_1.21/src/internal/goarch/ya.make b/contrib/go/_std_1.21/src/internal/goarch/ya.make
new file mode 100644
index 0000000000..29769ed82c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goarch/ya.make
@@ -0,0 +1,21 @@
+GO_LIBRARY()
+
+SRCS(
+ goarch.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ goarch_amd64.go
+ zgoarch_amd64.go
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ goarch_arm64.go
+ zgoarch_arm64.go
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.20/src/internal/goarch/zgoarch_amd64.go b/contrib/go/_std_1.21/src/internal/goarch/zgoarch_amd64.go
index 7926392b77..7926392b77 100644
--- a/contrib/go/_std_1.20/src/internal/goarch/zgoarch_amd64.go
+++ b/contrib/go/_std_1.21/src/internal/goarch/zgoarch_amd64.go
diff --git a/contrib/go/_std_1.20/src/internal/goarch/zgoarch_arm64.go b/contrib/go/_std_1.21/src/internal/goarch/zgoarch_arm64.go
index ad342d79c9..ad342d79c9 100644
--- a/contrib/go/_std_1.20/src/internal/goarch/zgoarch_arm64.go
+++ b/contrib/go/_std_1.21/src/internal/goarch/zgoarch_arm64.go
diff --git a/contrib/go/_std_1.21/src/internal/godebug/godebug.go b/contrib/go/_std_1.21/src/internal/godebug/godebug.go
new file mode 100644
index 0000000000..1265ed7e1e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/godebug/godebug.go
@@ -0,0 +1,291 @@
+// 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 godebug makes the settings in the $GODEBUG environment variable
+// available to other packages. These settings are often used for compatibility
+// tweaks, when we need to change a default behavior but want to let users
+// opt back in to the original. For example GODEBUG=http2server=0 disables
+// HTTP/2 support in the net/http server.
+//
+// In typical usage, code should declare a Setting as a global
+// and then call Value each time the current setting value is needed:
+//
+// var http2server = godebug.New("http2server")
+//
+// func ServeConn(c net.Conn) {
+// if http2server.Value() == "0" {
+// disallow HTTP/2
+// ...
+// }
+// ...
+// }
+//
+// Each time a non-default setting causes a change in program behavior,
+// code should call [Setting.IncNonDefault] to increment a counter that can
+// be reported by [runtime/metrics.Read].
+// Note that counters used with IncNonDefault must be added to
+// various tables in other packages. See the [Setting.IncNonDefault]
+// documentation for details.
+package godebug
+
+// Note: Be careful about new imports here. Any package
+// that internal/godebug imports cannot itself import internal/godebug,
+// meaning it cannot introduce a GODEBUG setting of its own.
+// We keep imports to the absolute bare minimum.
+import (
+ "internal/bisect"
+ "internal/godebugs"
+ "sync"
+ "sync/atomic"
+ "unsafe"
+ _ "unsafe" // go:linkname
+
+)
+
+// A Setting is a single setting in the $GODEBUG environment variable.
+type Setting struct {
+ name string
+ once sync.Once
+ *setting
+}
+
+type setting struct {
+ value atomic.Pointer[value]
+ nonDefaultOnce sync.Once
+ nonDefault atomic.Uint64
+ info *godebugs.Info
+}
+
+type value struct {
+ text string
+ bisect *bisect.Matcher
+}
+
+// New returns a new Setting for the $GODEBUG setting with the given name.
+//
+// GODEBUGs meant for use by end users must be listed in ../godebugs/table.go,
+// which is used for generating and checking various documentation.
+// If the name is not listed in that table, New will succeed but calling Value
+// on the returned Setting will panic.
+// To disable that panic for access to an undocumented setting,
+// prefix the name with a #, as in godebug.New("#gofsystrace").
+// The # is a signal to New but not part of the key used in $GODEBUG.
+func New(name string) *Setting {
+ return &Setting{name: name}
+}
+
+// Name returns the name of the setting.
+func (s *Setting) Name() string {
+ if s.name != "" && s.name[0] == '#' {
+ return s.name[1:]
+ }
+ return s.name
+}
+
+// Undocumented reports whether this is an undocumented setting.
+func (s *Setting) Undocumented() bool {
+ return s.name != "" && s.name[0] == '#'
+}
+
+// String returns a printable form for the setting: name=value.
+func (s *Setting) String() string {
+ return s.Name() + "=" + s.Value()
+}
+
+// IncNonDefault increments the non-default behavior counter
+// associated with the given setting.
+// This counter is exposed in the runtime/metrics value
+// /godebug/non-default-behavior/<name>:events.
+//
+// Note that Value must be called at least once before IncNonDefault.
+func (s *Setting) IncNonDefault() {
+ s.nonDefaultOnce.Do(s.register)
+ s.nonDefault.Add(1)
+}
+
+func (s *Setting) register() {
+ if s.info == nil || s.info.Opaque {
+ panic("godebug: unexpected IncNonDefault of " + s.name)
+ }
+ registerMetric("/godebug/non-default-behavior/"+s.Name()+":events", s.nonDefault.Load)
+}
+
+// cache is a cache of all the GODEBUG settings,
+// a locked map[string]*atomic.Pointer[string].
+//
+// All Settings with the same name share a single
+// *atomic.Pointer[string], so that when GODEBUG
+// changes only that single atomic string pointer
+// needs to be updated.
+//
+// A name appears in the values map either if it is the
+// name of a Setting for which Value has been called
+// at least once, or if the name has ever appeared in
+// a name=value pair in the $GODEBUG environment variable.
+// Once entered into the map, the name is never removed.
+var cache sync.Map // name string -> value *atomic.Pointer[string]
+
+var empty value
+
+// Value returns the current value for the GODEBUG setting s.
+//
+// Value maintains an internal cache that is synchronized
+// with changes to the $GODEBUG environment variable,
+// making Value efficient to call as frequently as needed.
+// Clients should therefore typically not attempt their own
+// caching of Value's result.
+func (s *Setting) Value() string {
+ s.once.Do(func() {
+ s.setting = lookup(s.Name())
+ if s.info == nil && !s.Undocumented() {
+ panic("godebug: Value of name not listed in godebugs.All: " + s.name)
+ }
+ })
+ v := *s.value.Load()
+ if v.bisect != nil && !v.bisect.Stack(&stderr) {
+ return ""
+ }
+ return v.text
+}
+
+// lookup returns the unique *setting value for the given name.
+func lookup(name string) *setting {
+ if v, ok := cache.Load(name); ok {
+ return v.(*setting)
+ }
+ s := new(setting)
+ s.info = godebugs.Lookup(name)
+ s.value.Store(&empty)
+ if v, loaded := cache.LoadOrStore(name, s); loaded {
+ // Lost race: someone else created it. Use theirs.
+ return v.(*setting)
+ }
+
+ return s
+}
+
+// setUpdate is provided by package runtime.
+// It calls update(def, env), where def is the default GODEBUG setting
+// and env is the current value of the $GODEBUG environment variable.
+// After that first call, the runtime calls update(def, env)
+// again each time the environment variable changes
+// (due to use of os.Setenv, for example).
+//
+//go:linkname setUpdate
+func setUpdate(update func(string, string))
+
+// registerMetric is provided by package runtime.
+// It forwards registrations to runtime/metrics.
+//
+//go:linkname registerMetric
+func registerMetric(name string, read func() uint64)
+
+// setNewIncNonDefault is provided by package runtime.
+// The runtime can do
+//
+// inc := newNonDefaultInc(name)
+//
+// instead of
+//
+// inc := godebug.New(name).IncNonDefault
+//
+// since it cannot import godebug.
+//
+//go:linkname setNewIncNonDefault
+func setNewIncNonDefault(newIncNonDefault func(string) func())
+
+func init() {
+ setUpdate(update)
+ setNewIncNonDefault(newIncNonDefault)
+}
+
+func newIncNonDefault(name string) func() {
+ s := New(name)
+ s.Value()
+ return s.IncNonDefault
+}
+
+var updateMu sync.Mutex
+
+// update records an updated GODEBUG setting.
+// def is the default GODEBUG setting for the running binary,
+// and env is the current value of the $GODEBUG environment variable.
+func update(def, env string) {
+ updateMu.Lock()
+ defer updateMu.Unlock()
+
+ // Update all the cached values, creating new ones as needed.
+ // We parse the environment variable first, so that any settings it has
+ // are already locked in place (did[name] = true) before we consider
+ // the defaults.
+ did := make(map[string]bool)
+ parse(did, env)
+ parse(did, def)
+
+ // Clear any cached values that are no longer present.
+ cache.Range(func(name, s any) bool {
+ if !did[name.(string)] {
+ s.(*setting).value.Store(&empty)
+ }
+ return true
+ })
+}
+
+// parse parses the GODEBUG setting string s,
+// which has the form k=v,k2=v2,k3=v3.
+// Later settings override earlier ones.
+// Parse only updates settings k=v for which did[k] = false.
+// It also sets did[k] = true for settings that it updates.
+// Each value v can also have the form v#pattern,
+// in which case the GODEBUG is only enabled for call stacks
+// matching pattern, for use with golang.org/x/tools/cmd/bisect.
+func parse(did map[string]bool, s string) {
+ // Scan the string backward so that later settings are used
+ // and earlier settings are ignored.
+ // Note that a forward scan would cause cached values
+ // to temporarily use the ignored value before being
+ // updated to the "correct" one.
+ end := len(s)
+ eq := -1
+ for i := end - 1; i >= -1; i-- {
+ if i == -1 || s[i] == ',' {
+ if eq >= 0 {
+ name, arg := s[i+1:eq], s[eq+1:end]
+ if !did[name] {
+ did[name] = true
+ v := &value{text: arg}
+ for j := 0; j < len(arg); j++ {
+ if arg[j] == '#' {
+ v.text = arg[:j]
+ v.bisect, _ = bisect.New(arg[j+1:])
+ break
+ }
+ }
+ lookup(name).value.Store(v)
+ }
+ }
+ eq = -1
+ end = i
+ } else if s[i] == '=' {
+ eq = i
+ }
+ }
+}
+
+type runtimeStderr struct{}
+
+var stderr runtimeStderr
+
+func (*runtimeStderr) Write(b []byte) (int, error) {
+ if len(b) > 0 {
+ write(2, unsafe.Pointer(&b[0]), int32(len(b)))
+ }
+ return len(b), nil
+}
+
+// Since we cannot import os or syscall, use the runtime's write function
+// to print to standard error.
+//
+//go:linkname write runtime.write
+func write(fd uintptr, p unsafe.Pointer, n int32) int32
diff --git a/contrib/go/_std_1.21/src/internal/godebug/ya.make b/contrib/go/_std_1.21/src/internal/godebug/ya.make
new file mode 100644
index 0000000000..091394342a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/godebug/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ godebug.go
+)
+
+GO_XTEST_SRCS(godebug_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/internal/godebugs/table.go b/contrib/go/_std_1.21/src/internal/godebugs/table.go
new file mode 100644
index 0000000000..b1711d9ef2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/godebugs/table.go
@@ -0,0 +1,69 @@
+// Copyright 2023 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 godebugs provides a table of known GODEBUG settings,
+// for use by a variety of other packages, including internal/godebug,
+// runtime, runtime/metrics, and cmd/go/internal/load.
+package godebugs
+
+// An Info describes a single known GODEBUG setting.
+type Info struct {
+ Name string // name of the setting ("panicnil")
+ Package string // package that uses the setting ("runtime")
+ Changed int // minor version when default changed, if any; 21 means Go 1.21
+ Old string // value that restores behavior prior to Changed
+ Opaque bool // setting does not export information to runtime/metrics using [internal/godebug.Setting.IncNonDefault]
+}
+
+// All is the table of known settings, sorted by Name.
+//
+// Note: After adding entries to this table, run 'go generate runtime/metrics'
+// to update the runtime/metrics doc comment.
+// (Otherwise the runtime/metrics test will fail.)
+//
+// Note: After adding entries to this table, update the list in doc/godebug.md as well.
+// (Otherwise the test in this package will fail.)
+var All = []Info{
+ {Name: "execerrdot", Package: "os/exec"},
+ {Name: "gocachehash", Package: "cmd/go"},
+ {Name: "gocachetest", Package: "cmd/go"},
+ {Name: "gocacheverify", Package: "cmd/go"},
+ {Name: "http2client", Package: "net/http"},
+ {Name: "http2debug", Package: "net/http", Opaque: true},
+ {Name: "http2server", Package: "net/http"},
+ {Name: "installgoroot", Package: "go/build"},
+ {Name: "jstmpllitinterp", Package: "html/template"},
+ //{Name: "multipartfiles", Package: "mime/multipart"},
+ {Name: "multipartmaxheaders", Package: "mime/multipart"},
+ {Name: "multipartmaxparts", Package: "mime/multipart"},
+ {Name: "multipathtcp", Package: "net"},
+ {Name: "netdns", Package: "net", Opaque: true},
+ {Name: "panicnil", Package: "runtime", Changed: 21, Old: "1"},
+ {Name: "randautoseed", Package: "math/rand"},
+ {Name: "tarinsecurepath", Package: "archive/tar"},
+ {Name: "tlsmaxrsasize", Package: "crypto/tls"},
+ {Name: "x509sha1", Package: "crypto/x509"},
+ {Name: "x509usefallbackroots", Package: "crypto/x509"},
+ {Name: "zipinsecurepath", Package: "archive/zip"},
+}
+
+// Lookup returns the Info with the given name.
+func Lookup(name string) *Info {
+ // binary search, avoiding import of sort.
+ lo := 0
+ hi := len(All)
+ for lo < hi {
+ m := lo + (hi-lo)>>1
+ mid := All[m].Name
+ if name == mid {
+ return &All[m]
+ }
+ if name < mid {
+ hi = m
+ } else {
+ lo = m + 1
+ }
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/internal/godebugs/ya.make b/contrib/go/_std_1.21/src/internal/godebugs/ya.make
new file mode 100644
index 0000000000..bbf68c703f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/godebugs/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ table.go
+)
+
+GO_XTEST_SRCS(godebugs_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/exp_arenas_off.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_arenas_off.go
index 9e40ebc37b..9e40ebc37b 100644
--- a/contrib/go/_std_1.20/src/internal/goexperiment/exp_arenas_off.go
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_arenas_off.go
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/exp_boringcrypto_off.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_boringcrypto_off.go
index 020c75bd53..020c75bd53 100644
--- a/contrib/go/_std_1.20/src/internal/goexperiment/exp_boringcrypto_off.go
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_boringcrypto_off.go
diff --git a/contrib/go/_std_1.21/src/internal/goexperiment/exp_cacheprog_off.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_cacheprog_off.go
new file mode 100644
index 0000000000..29aa869823
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_cacheprog_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.cacheprog
+// +build !goexperiment.cacheprog
+
+package goexperiment
+
+const CacheProg = false
+const CacheProgInt = 0
diff --git a/contrib/go/_std_1.21/src/internal/goexperiment/exp_cgocheck2_off.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_cgocheck2_off.go
new file mode 100644
index 0000000000..77aa538309
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_cgocheck2_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.cgocheck2
+// +build !goexperiment.cgocheck2
+
+package goexperiment
+
+const CgoCheck2 = false
+const CgoCheck2Int = 0
diff --git a/contrib/go/_std_1.21/src/internal/goexperiment/exp_coverageredesign_on.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_coverageredesign_on.go
new file mode 100644
index 0000000000..330a234f20
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_coverageredesign_on.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build goexperiment.coverageredesign
+// +build goexperiment.coverageredesign
+
+package goexperiment
+
+const CoverageRedesign = true
+const CoverageRedesignInt = 1
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/exp_fieldtrack_off.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_fieldtrack_off.go
index e5e132660e..e5e132660e 100644
--- a/contrib/go/_std_1.20/src/internal/goexperiment/exp_fieldtrack_off.go
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_fieldtrack_off.go
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/exp_heapminimum512kib_off.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_heapminimum512kib_off.go
index 09da431b40..09da431b40 100644
--- a/contrib/go/_std_1.20/src/internal/goexperiment/exp_heapminimum512kib_off.go
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_heapminimum512kib_off.go
diff --git a/contrib/go/_std_1.21/src/internal/goexperiment/exp_loopvar_off.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_loopvar_off.go
new file mode 100644
index 0000000000..1cd7ee15d7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_loopvar_off.go
@@ -0,0 +1,9 @@
+// Code generated by mkconsts.go. DO NOT EDIT.
+
+//go:build !goexperiment.loopvar
+// +build !goexperiment.loopvar
+
+package goexperiment
+
+const LoopVar = false
+const LoopVarInt = 0
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/exp_pagetrace_off.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_pagetrace_off.go
index 789e88332d..789e88332d 100644
--- a/contrib/go/_std_1.20/src/internal/goexperiment/exp_pagetrace_off.go
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_pagetrace_off.go
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/exp_preemptibleloops_off.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_preemptibleloops_off.go
index 7a26088e80..7a26088e80 100644
--- a/contrib/go/_std_1.20/src/internal/goexperiment/exp_preemptibleloops_off.go
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_preemptibleloops_off.go
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/exp_regabiargs_on.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_regabiargs_on.go
index 9b26f3c9cb..9b26f3c9cb 100644
--- a/contrib/go/_std_1.20/src/internal/goexperiment/exp_regabiargs_on.go
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_regabiargs_on.go
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/exp_regabiwrappers_on.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_regabiwrappers_on.go
index 11ffffbbff..11ffffbbff 100644
--- a/contrib/go/_std_1.20/src/internal/goexperiment/exp_regabiwrappers_on.go
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_regabiwrappers_on.go
diff --git a/contrib/go/_std_1.20/src/internal/goexperiment/exp_staticlockranking_off.go b/contrib/go/_std_1.21/src/internal/goexperiment/exp_staticlockranking_off.go
index 3d546c04b4..3d546c04b4 100644
--- a/contrib/go/_std_1.20/src/internal/goexperiment/exp_staticlockranking_off.go
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/exp_staticlockranking_off.go
diff --git a/contrib/go/_std_1.21/src/internal/goexperiment/flags.go b/contrib/go/_std_1.21/src/internal/goexperiment/flags.go
new file mode 100644
index 0000000000..ae3cbaf89f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/flags.go
@@ -0,0 +1,112 @@
+// 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 goexperiment implements support for toolchain experiments.
+//
+// Toolchain experiments are controlled by the GOEXPERIMENT
+// environment variable. GOEXPERIMENT is a comma-separated list of
+// experiment names. GOEXPERIMENT can be set at make.bash time, which
+// sets the default experiments for binaries built with the tool
+// chain; or it can be set at build time. GOEXPERIMENT can also be set
+// to "none", which disables any experiments that were enabled at
+// make.bash time.
+//
+// Experiments are exposed to the build in the following ways:
+//
+// - Build tag goexperiment.x is set if experiment x (lower case) is
+// enabled.
+//
+// - For each experiment x (in camel case), this package contains a
+// boolean constant x and an integer constant xInt.
+//
+// - In runtime assembly, the macro GOEXPERIMENT_x is defined if
+// experiment x (lower case) is enabled.
+//
+// In the toolchain, the set of experiments enabled for the current
+// build should be accessed via objabi.Experiment.
+//
+// The set of experiments is included in the output of runtime.Version()
+// and "go version <binary>" if it differs from the default experiments.
+//
+// For the set of experiments supported by the current toolchain, see
+// "go doc goexperiment.Flags".
+//
+// Note that this package defines the set of experiments (in Flags)
+// and records the experiments that were enabled when the package
+// was compiled (as boolean and integer constants).
+//
+// Note especially that this package does not itself change behavior
+// at run time based on the GOEXPERIMENT variable.
+// The code used in builds to interpret the GOEXPERIMENT variable
+// is in the separate package internal/buildcfg.
+package goexperiment
+
+//go:generate go run mkconsts.go
+
+// Flags is the set of experiments that can be enabled or disabled in
+// the current toolchain.
+//
+// When specified in the GOEXPERIMENT environment variable or as build
+// tags, experiments use the strings.ToLower of their field name.
+//
+// For the baseline experimental configuration, see
+// objabi.experimentBaseline.
+//
+// If you change this struct definition, run "go generate".
+type Flags struct {
+ FieldTrack bool
+ PreemptibleLoops bool
+ StaticLockRanking bool
+ BoringCrypto bool
+
+ // Regabi is split into several sub-experiments that can be
+ // enabled individually. Not all combinations work.
+ // The "regabi" GOEXPERIMENT is an alias for all "working"
+ // subexperiments.
+
+ // RegabiWrappers enables ABI wrappers for calling between
+ // ABI0 and ABIInternal functions. Without this, the ABIs are
+ // assumed to be identical so cross-ABI calls are direct.
+ RegabiWrappers bool
+ // RegabiArgs enables register arguments/results in all
+ // compiled Go functions.
+ //
+ // Requires wrappers (to do ABI translation), and reflect (so
+ // reflection calls use registers).
+ RegabiArgs bool
+
+ // HeapMinimum512KiB reduces the minimum heap size to 512 KiB.
+ //
+ // This was originally reduced as part of PacerRedesign, but
+ // has been broken out to its own experiment that is disabled
+ // by default.
+ HeapMinimum512KiB bool
+
+ // CoverageRedesign enables the new compiler-based code coverage
+ // tooling.
+ CoverageRedesign bool
+
+ // Arenas causes the "arena" standard library package to be visible
+ // to the outside world.
+ Arenas bool
+
+ // PageTrace enables GODEBUG=pagetrace=/path/to/result. This feature
+ // is a GOEXPERIMENT due to a security risk with setuid binaries:
+ // this compels the Go runtime to write to some arbitrary file, which
+ // may be exploited.
+ PageTrace bool
+
+ // CgoCheck2 enables an expensive cgo rule checker.
+ // When this experiment is enabled, cgo rule checks occur regardless
+ // of the GODEBUG=cgocheck setting provided at runtime.
+ CgoCheck2 bool
+
+ // LoopVar changes loop semantics so that each iteration gets its own
+ // copy of the iteration variable.
+ LoopVar bool
+
+ // CacheProg adds support to cmd/go to use a child process to implement
+ // the build cache; see https://github.com/golang/go/issues/59719.
+ CacheProg bool
+}
diff --git a/contrib/go/_std_1.21/src/internal/goexperiment/ya.make b/contrib/go/_std_1.21/src/internal/goexperiment/ya.make
new file mode 100644
index 0000000000..8b59c0307f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goexperiment/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ exp_arenas_off.go
+ exp_boringcrypto_off.go
+ exp_cacheprog_off.go
+ exp_cgocheck2_off.go
+ exp_coverageredesign_on.go
+ exp_fieldtrack_off.go
+ exp_heapminimum512kib_off.go
+ exp_loopvar_off.go
+ exp_pagetrace_off.go
+ exp_preemptibleloops_off.go
+ exp_regabiargs_on.go
+ exp_regabiwrappers_on.go
+ exp_staticlockranking_off.go
+ flags.go
+)
+
+END()
diff --git a/contrib/go/_std_1.20/src/internal/goos/goos.go b/contrib/go/_std_1.21/src/internal/goos/goos.go
index 02dc9688cb..02dc9688cb 100644
--- a/contrib/go/_std_1.20/src/internal/goos/goos.go
+++ b/contrib/go/_std_1.21/src/internal/goos/goos.go
diff --git a/contrib/go/_std_1.20/src/internal/goos/nonunix.go b/contrib/go/_std_1.21/src/internal/goos/nonunix.go
index 2ba5c8555a..2ba5c8555a 100644
--- a/contrib/go/_std_1.20/src/internal/goos/nonunix.go
+++ b/contrib/go/_std_1.21/src/internal/goos/nonunix.go
diff --git a/contrib/go/_std_1.20/src/internal/goos/unix.go b/contrib/go/_std_1.21/src/internal/goos/unix.go
index 6cfd5ef675..6cfd5ef675 100644
--- a/contrib/go/_std_1.20/src/internal/goos/unix.go
+++ b/contrib/go/_std_1.21/src/internal/goos/unix.go
diff --git a/contrib/go/_std_1.21/src/internal/goos/ya.make b/contrib/go/_std_1.21/src/internal/goos/ya.make
new file mode 100644
index 0000000000..abfc3c1a3f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goos/ya.make
@@ -0,0 +1,28 @@
+GO_LIBRARY()
+
+SRCS(
+ goos.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ unix.go
+ zgoos_linux.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ unix.go
+ zgoos_darwin.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ nonunix.go
+ zgoos_windows.go
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.21/src/internal/goos/zgoos_darwin.go b/contrib/go/_std_1.21/src/internal/goos/zgoos_darwin.go
new file mode 100644
index 0000000000..10b1499895
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goos/zgoos_darwin.go
@@ -0,0 +1,26 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+//go:build !ios && darwin
+
+package goos
+
+const GOOS = `darwin`
+
+const IsAix = 0
+const IsAndroid = 0
+const IsDarwin = 1
+const IsDragonfly = 0
+const IsFreebsd = 0
+const IsHurd = 0
+const IsIllumos = 0
+const IsIos = 0
+const IsJs = 0
+const IsLinux = 0
+const IsNacl = 0
+const IsNetbsd = 0
+const IsOpenbsd = 0
+const IsPlan9 = 0
+const IsSolaris = 0
+const IsWasip1 = 0
+const IsWindows = 0
+const IsZos = 0
diff --git a/contrib/go/_std_1.21/src/internal/goos/zgoos_linux.go b/contrib/go/_std_1.21/src/internal/goos/zgoos_linux.go
new file mode 100644
index 0000000000..6f4d4e0753
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goos/zgoos_linux.go
@@ -0,0 +1,26 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+//go:build !android && linux
+
+package goos
+
+const GOOS = `linux`
+
+const IsAix = 0
+const IsAndroid = 0
+const IsDarwin = 0
+const IsDragonfly = 0
+const IsFreebsd = 0
+const IsHurd = 0
+const IsIllumos = 0
+const IsIos = 0
+const IsJs = 0
+const IsLinux = 1
+const IsNacl = 0
+const IsNetbsd = 0
+const IsOpenbsd = 0
+const IsPlan9 = 0
+const IsSolaris = 0
+const IsWasip1 = 0
+const IsWindows = 0
+const IsZos = 0
diff --git a/contrib/go/_std_1.21/src/internal/goos/zgoos_windows.go b/contrib/go/_std_1.21/src/internal/goos/zgoos_windows.go
new file mode 100644
index 0000000000..f89f4cf829
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goos/zgoos_windows.go
@@ -0,0 +1,26 @@
+// Code generated by gengoos.go using 'go generate'. DO NOT EDIT.
+
+//go:build windows
+
+package goos
+
+const GOOS = `windows`
+
+const IsAix = 0
+const IsAndroid = 0
+const IsDarwin = 0
+const IsDragonfly = 0
+const IsFreebsd = 0
+const IsHurd = 0
+const IsIllumos = 0
+const IsIos = 0
+const IsJs = 0
+const IsLinux = 0
+const IsNacl = 0
+const IsNetbsd = 0
+const IsOpenbsd = 0
+const IsPlan9 = 0
+const IsSolaris = 0
+const IsWasip1 = 0
+const IsWindows = 1
+const IsZos = 0
diff --git a/contrib/go/_std_1.21/src/internal/goroot/gc.go b/contrib/go/_std_1.21/src/internal/goroot/gc.go
new file mode 100644
index 0000000000..c0216f4ea5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goroot/gc.go
@@ -0,0 +1,131 @@
+// Copyright 2018 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.
+
+//go:build gc
+
+package goroot
+
+import (
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "sync"
+)
+
+// IsStandardPackage reports whether path is a standard package,
+// given goroot and compiler.
+func IsStandardPackage(goroot, compiler, path string) bool {
+ switch compiler {
+ case "gc":
+ dir := filepath.Join(goroot, "src", path)
+ info, err := os.Stat(dir)
+ return err == nil && info.IsDir()
+ case "gccgo":
+ return gccgoSearch.isStandard(path)
+ default:
+ panic("unknown compiler " + compiler)
+ }
+}
+
+// gccgoSearch holds the gccgo search directories.
+type gccgoDirs struct {
+ once sync.Once
+ dirs []string
+}
+
+// gccgoSearch is used to check whether a gccgo package exists in the
+// standard library.
+var gccgoSearch gccgoDirs
+
+// init finds the gccgo search directories. If this fails it leaves dirs == nil.
+func (gd *gccgoDirs) init() {
+ gccgo := os.Getenv("GCCGO")
+ if gccgo == "" {
+ gccgo = "gccgo"
+ }
+ bin, err := exec.LookPath(gccgo)
+ if err != nil {
+ return
+ }
+
+ allDirs, err := exec.Command(bin, "-print-search-dirs").Output()
+ if err != nil {
+ return
+ }
+ versionB, err := exec.Command(bin, "-dumpversion").Output()
+ if err != nil {
+ return
+ }
+ version := strings.TrimSpace(string(versionB))
+ machineB, err := exec.Command(bin, "-dumpmachine").Output()
+ if err != nil {
+ return
+ }
+ machine := strings.TrimSpace(string(machineB))
+
+ dirsEntries := strings.Split(string(allDirs), "\n")
+ const prefix = "libraries: ="
+ var dirs []string
+ for _, dirEntry := range dirsEntries {
+ if strings.HasPrefix(dirEntry, prefix) {
+ dirs = filepath.SplitList(strings.TrimPrefix(dirEntry, prefix))
+ break
+ }
+ }
+ if len(dirs) == 0 {
+ return
+ }
+
+ var lastDirs []string
+ for _, dir := range dirs {
+ goDir := filepath.Join(dir, "go", version)
+ if fi, err := os.Stat(goDir); err == nil && fi.IsDir() {
+ gd.dirs = append(gd.dirs, goDir)
+ goDir = filepath.Join(goDir, machine)
+ if fi, err = os.Stat(goDir); err == nil && fi.IsDir() {
+ gd.dirs = append(gd.dirs, goDir)
+ }
+ }
+ if fi, err := os.Stat(dir); err == nil && fi.IsDir() {
+ lastDirs = append(lastDirs, dir)
+ }
+ }
+ gd.dirs = append(gd.dirs, lastDirs...)
+}
+
+// isStandard reports whether path is a standard library for gccgo.
+func (gd *gccgoDirs) isStandard(path string) bool {
+ // Quick check: if the first path component has a '.', it's not
+ // in the standard library. This skips most GOPATH directories.
+ i := strings.Index(path, "/")
+ if i < 0 {
+ i = len(path)
+ }
+ if strings.Contains(path[:i], ".") {
+ return false
+ }
+
+ if path == "unsafe" {
+ // Special case.
+ return true
+ }
+
+ gd.once.Do(gd.init)
+ if gd.dirs == nil {
+ // We couldn't find the gccgo search directories.
+ // Best guess, since the first component did not contain
+ // '.', is that this is a standard library package.
+ return true
+ }
+
+ for _, dir := range gd.dirs {
+ full := filepath.Join(dir, path) + ".gox"
+ if fi, err := os.Stat(full); err == nil && !fi.IsDir() {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/contrib/go/_std_1.21/src/internal/goroot/ya.make b/contrib/go/_std_1.21/src/internal/goroot/ya.make
new file mode 100644
index 0000000000..900d6431be
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goroot/ya.make
@@ -0,0 +1,7 @@
+GO_LIBRARY()
+
+SRCS(
+ gc.go
+)
+
+END()
diff --git a/contrib/go/_std_1.21/src/internal/goversion/goversion.go b/contrib/go/_std_1.21/src/internal/goversion/goversion.go
new file mode 100644
index 0000000000..5a52f9eac8
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/goversion/goversion.go
@@ -0,0 +1,12 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package goversion
+
+// Version is the Go 1.x version which is currently
+// in development and will eventually get released.
+//
+// It should be updated at the start of each development cycle to be
+// the version of the next Go 1.x release. See golang.org/issue/40705.
+const Version = 21
diff --git a/contrib/go/_std_1.20/src/internal/goversion/ya.make b/contrib/go/_std_1.21/src/internal/goversion/ya.make
index dee4610577..dee4610577 100644
--- a/contrib/go/_std_1.20/src/internal/goversion/ya.make
+++ b/contrib/go/_std_1.21/src/internal/goversion/ya.make
diff --git a/contrib/go/_std_1.21/src/internal/intern/intern.go b/contrib/go/_std_1.21/src/internal/intern/intern.go
new file mode 100644
index 0000000000..2f97c2e669
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/intern/intern.go
@@ -0,0 +1,181 @@
+// 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 intern lets you make smaller comparable values by boxing
+// a larger comparable value (such as a 16 byte string header) down
+// into a globally unique 8 byte pointer.
+//
+// The globally unique pointers are garbage collected with weak
+// references and finalizers. This package hides that.
+package intern
+
+import (
+ "internal/godebug"
+ "runtime"
+ "sync"
+ "unsafe"
+)
+
+// A Value pointer is the handle to an underlying comparable value.
+// See func Get for how Value pointers may be used.
+type Value struct {
+ _ [0]func() // prevent people from accidentally using value type as comparable
+ cmpVal any
+ // resurrected is guarded by mu (for all instances of Value).
+ // It is set true whenever v is synthesized from a uintptr.
+ resurrected bool
+}
+
+// Get returns the comparable value passed to the Get func
+// that returned v.
+func (v *Value) Get() any { return v.cmpVal }
+
+// key is a key in our global value map.
+// It contains type-specialized fields to avoid allocations
+// when converting common types to empty interfaces.
+type key struct {
+ s string
+ cmpVal any
+ // isString reports whether key contains a string.
+ // Without it, the zero value of key is ambiguous.
+ isString bool
+}
+
+// keyFor returns a key to use with cmpVal.
+func keyFor(cmpVal any) key {
+ if s, ok := cmpVal.(string); ok {
+ return key{s: s, isString: true}
+ }
+ return key{cmpVal: cmpVal}
+}
+
+// Value returns a *Value built from k.
+func (k key) Value() *Value {
+ if k.isString {
+ return &Value{cmpVal: k.s}
+ }
+ return &Value{cmpVal: k.cmpVal}
+}
+
+var (
+ // mu guards valMap, a weakref map of *Value by underlying value.
+ // It also guards the resurrected field of all *Values.
+ mu sync.Mutex
+ valMap = map[key]uintptr{} // to uintptr(*Value)
+ valSafe = safeMap() // non-nil in safe+leaky mode
+)
+
+var intern = godebug.New("#intern")
+
+// safeMap returns a non-nil map if we're in safe-but-leaky mode,
+// as controlled by GODEBUG=intern=leaky
+func safeMap() map[key]*Value {
+ if intern.Value() == "leaky" {
+ return map[key]*Value{}
+ }
+ return nil
+}
+
+// Get returns a pointer representing the comparable value cmpVal.
+//
+// The returned pointer will be the same for Get(v) and Get(v2)
+// if and only if v == v2, and can be used as a map key.
+func Get(cmpVal any) *Value {
+ return get(keyFor(cmpVal))
+}
+
+// GetByString is identical to Get, except that it is specialized for strings.
+// This avoids an allocation from putting a string into an interface{}
+// to pass as an argument to Get.
+func GetByString(s string) *Value {
+ return get(key{s: s, isString: true})
+}
+
+// We play unsafe games that violate Go's rules (and assume a non-moving
+// collector). So we quiet Go here.
+// See the comment below Get for more implementation details.
+//
+//go:nocheckptr
+func get(k key) *Value {
+ mu.Lock()
+ defer mu.Unlock()
+
+ var v *Value
+ if valSafe != nil {
+ v = valSafe[k]
+ } else if addr, ok := valMap[k]; ok {
+ v = (*Value)(unsafe.Pointer(addr))
+ v.resurrected = true
+ }
+ if v != nil {
+ return v
+ }
+ v = k.Value()
+ if valSafe != nil {
+ valSafe[k] = v
+ } else {
+ // SetFinalizer before uintptr conversion (theoretical concern;
+ // see https://github.com/go4org/intern/issues/13)
+ runtime.SetFinalizer(v, finalize)
+ valMap[k] = uintptr(unsafe.Pointer(v))
+ }
+ return v
+}
+
+func finalize(v *Value) {
+ mu.Lock()
+ defer mu.Unlock()
+ if v.resurrected {
+ // We lost the race. Somebody resurrected it while we
+ // were about to finalize it. Try again next round.
+ v.resurrected = false
+ runtime.SetFinalizer(v, finalize)
+ return
+ }
+ delete(valMap, keyFor(v.cmpVal))
+}
+
+// Interning is simple if you don't require that unused values be
+// garbage collectable. But we do require that; we don't want to be
+// DOS vector. We do this by using a uintptr to hide the pointer from
+// the garbage collector, and using a finalizer to eliminate the
+// pointer when no other code is using it.
+//
+// The obvious implementation of this is to use a
+// map[interface{}]uintptr-of-*interface{}, and set up a finalizer to
+// delete from the map. Unfortunately, this is racy. Because pointers
+// are being created in violation of Go's unsafety rules, it's
+// possible to create a pointer to a value concurrently with the GC
+// concluding that the value can be collected. There are other races
+// that break the equality invariant as well, but the use-after-free
+// will cause a runtime crash.
+//
+// To make this work, the finalizer needs to know that no references
+// have been unsafely created since the finalizer was set up. To do
+// this, values carry a "resurrected" sentinel, which gets set
+// whenever a pointer is unsafely created. If the finalizer encounters
+// the sentinel, it clears the sentinel and delays collection for one
+// additional GC cycle, by re-installing itself as finalizer. This
+// ensures that the unsafely created pointer is visible to the GC, and
+// will correctly prevent collection.
+//
+// This technique does mean that interned values that get reused take
+// at least 3 GC cycles to fully collect (1 to clear the sentinel, 1
+// to clean up the unsafe map, 1 to be actually deleted).
+//
+// @ianlancetaylor commented in
+// https://github.com/golang/go/issues/41303#issuecomment-717401656
+// that it is possible to implement weak references in terms of
+// finalizers without unsafe. Unfortunately, the approach he outlined
+// does not work here, for two reasons. First, there is no way to
+// construct a strong pointer out of a weak pointer; our map stores
+// weak pointers, but we must return strong pointers to callers.
+// Second, and more fundamentally, we must return not just _a_ strong
+// pointer to callers, but _the same_ strong pointer to callers. In
+// order to return _the same_ strong pointer to callers, we must track
+// it, which is exactly what we cannot do with strong pointers.
+//
+// See https://github.com/inetaf/netaddr/issues/53 for more
+// discussion, and https://github.com/go4org/intern/issues/2 for an
+// illustration of the subtleties at play.
diff --git a/contrib/go/_std_1.21/src/internal/intern/ya.make b/contrib/go/_std_1.21/src/internal/intern/ya.make
new file mode 100644
index 0000000000..5c4dda0f56
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/intern/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ intern.go
+)
+
+GO_TEST_SRCS(intern_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/itoa/itoa.go b/contrib/go/_std_1.21/src/internal/itoa/itoa.go
index c6062d9fe1..c6062d9fe1 100644
--- a/contrib/go/_std_1.20/src/internal/itoa/itoa.go
+++ b/contrib/go/_std_1.21/src/internal/itoa/itoa.go
diff --git a/contrib/go/_std_1.21/src/internal/itoa/ya.make b/contrib/go/_std_1.21/src/internal/itoa/ya.make
new file mode 100644
index 0000000000..b17c3533f6
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/itoa/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ itoa.go
+)
+
+GO_XTEST_SRCS(itoa_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/lazyregexp/lazyre.go b/contrib/go/_std_1.21/src/internal/lazyregexp/lazyre.go
index 2681af35af..2681af35af 100644
--- a/contrib/go/_std_1.20/src/internal/lazyregexp/lazyre.go
+++ b/contrib/go/_std_1.21/src/internal/lazyregexp/lazyre.go
diff --git a/contrib/go/_std_1.20/src/internal/lazyregexp/ya.make b/contrib/go/_std_1.21/src/internal/lazyregexp/ya.make
index 7753ef8e7d..7753ef8e7d 100644
--- a/contrib/go/_std_1.20/src/internal/lazyregexp/ya.make
+++ b/contrib/go/_std_1.21/src/internal/lazyregexp/ya.make
diff --git a/contrib/go/_std_1.20/src/internal/nettrace/nettrace.go b/contrib/go/_std_1.21/src/internal/nettrace/nettrace.go
index 0a2bf925e9..0a2bf925e9 100644
--- a/contrib/go/_std_1.20/src/internal/nettrace/nettrace.go
+++ b/contrib/go/_std_1.21/src/internal/nettrace/nettrace.go
diff --git a/contrib/go/_std_1.20/src/internal/nettrace/ya.make b/contrib/go/_std_1.21/src/internal/nettrace/ya.make
index 11bebb95db..11bebb95db 100644
--- a/contrib/go/_std_1.20/src/internal/nettrace/ya.make
+++ b/contrib/go/_std_1.21/src/internal/nettrace/ya.make
diff --git a/contrib/go/_std_1.20/src/internal/oserror/errors.go b/contrib/go/_std_1.21/src/internal/oserror/errors.go
index 28a1ab32d3..28a1ab32d3 100644
--- a/contrib/go/_std_1.20/src/internal/oserror/errors.go
+++ b/contrib/go/_std_1.21/src/internal/oserror/errors.go
diff --git a/contrib/go/_std_1.20/src/internal/oserror/ya.make b/contrib/go/_std_1.21/src/internal/oserror/ya.make
index 22a9f40703..22a9f40703 100644
--- a/contrib/go/_std_1.20/src/internal/oserror/ya.make
+++ b/contrib/go/_std_1.21/src/internal/oserror/ya.make
diff --git a/contrib/go/_std_1.20/src/internal/pkgbits/codes.go b/contrib/go/_std_1.21/src/internal/pkgbits/codes.go
index f0cabde96e..f0cabde96e 100644
--- a/contrib/go/_std_1.20/src/internal/pkgbits/codes.go
+++ b/contrib/go/_std_1.21/src/internal/pkgbits/codes.go
diff --git a/contrib/go/_std_1.20/src/internal/pkgbits/decoder.go b/contrib/go/_std_1.21/src/internal/pkgbits/decoder.go
index 4fe024d4f1..4fe024d4f1 100644
--- a/contrib/go/_std_1.20/src/internal/pkgbits/decoder.go
+++ b/contrib/go/_std_1.21/src/internal/pkgbits/decoder.go
diff --git a/contrib/go/_std_1.20/src/internal/pkgbits/doc.go b/contrib/go/_std_1.21/src/internal/pkgbits/doc.go
index 4862e39049..4862e39049 100644
--- a/contrib/go/_std_1.20/src/internal/pkgbits/doc.go
+++ b/contrib/go/_std_1.21/src/internal/pkgbits/doc.go
diff --git a/contrib/go/_std_1.20/src/internal/pkgbits/encoder.go b/contrib/go/_std_1.21/src/internal/pkgbits/encoder.go
index 70a2cbae51..70a2cbae51 100644
--- a/contrib/go/_std_1.20/src/internal/pkgbits/encoder.go
+++ b/contrib/go/_std_1.21/src/internal/pkgbits/encoder.go
diff --git a/contrib/go/_std_1.20/src/internal/pkgbits/flags.go b/contrib/go/_std_1.21/src/internal/pkgbits/flags.go
index 654222745f..654222745f 100644
--- a/contrib/go/_std_1.20/src/internal/pkgbits/flags.go
+++ b/contrib/go/_std_1.21/src/internal/pkgbits/flags.go
diff --git a/contrib/go/_std_1.20/src/internal/pkgbits/reloc.go b/contrib/go/_std_1.21/src/internal/pkgbits/reloc.go
index fcdfb97ca9..fcdfb97ca9 100644
--- a/contrib/go/_std_1.20/src/internal/pkgbits/reloc.go
+++ b/contrib/go/_std_1.21/src/internal/pkgbits/reloc.go
diff --git a/contrib/go/_std_1.20/src/internal/pkgbits/support.go b/contrib/go/_std_1.21/src/internal/pkgbits/support.go
index f7579dfdc4..f7579dfdc4 100644
--- a/contrib/go/_std_1.20/src/internal/pkgbits/support.go
+++ b/contrib/go/_std_1.21/src/internal/pkgbits/support.go
diff --git a/contrib/go/_std_1.20/src/internal/pkgbits/sync.go b/contrib/go/_std_1.21/src/internal/pkgbits/sync.go
index 1520b73afb..1520b73afb 100644
--- a/contrib/go/_std_1.20/src/internal/pkgbits/sync.go
+++ b/contrib/go/_std_1.21/src/internal/pkgbits/sync.go
diff --git a/contrib/go/_std_1.21/src/internal/pkgbits/syncmarker_string.go b/contrib/go/_std_1.21/src/internal/pkgbits/syncmarker_string.go
new file mode 100644
index 0000000000..582ad56d3e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/pkgbits/syncmarker_string.go
@@ -0,0 +1,92 @@
+// Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT.
+
+package pkgbits
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[SyncEOF-1]
+ _ = x[SyncBool-2]
+ _ = x[SyncInt64-3]
+ _ = x[SyncUint64-4]
+ _ = x[SyncString-5]
+ _ = x[SyncValue-6]
+ _ = x[SyncVal-7]
+ _ = x[SyncRelocs-8]
+ _ = x[SyncReloc-9]
+ _ = x[SyncUseReloc-10]
+ _ = x[SyncPublic-11]
+ _ = x[SyncPos-12]
+ _ = x[SyncPosBase-13]
+ _ = x[SyncObject-14]
+ _ = x[SyncObject1-15]
+ _ = x[SyncPkg-16]
+ _ = x[SyncPkgDef-17]
+ _ = x[SyncMethod-18]
+ _ = x[SyncType-19]
+ _ = x[SyncTypeIdx-20]
+ _ = x[SyncTypeParamNames-21]
+ _ = x[SyncSignature-22]
+ _ = x[SyncParams-23]
+ _ = x[SyncParam-24]
+ _ = x[SyncCodeObj-25]
+ _ = x[SyncSym-26]
+ _ = x[SyncLocalIdent-27]
+ _ = x[SyncSelector-28]
+ _ = x[SyncPrivate-29]
+ _ = x[SyncFuncExt-30]
+ _ = x[SyncVarExt-31]
+ _ = x[SyncTypeExt-32]
+ _ = x[SyncPragma-33]
+ _ = x[SyncExprList-34]
+ _ = x[SyncExprs-35]
+ _ = x[SyncExpr-36]
+ _ = x[SyncExprType-37]
+ _ = x[SyncAssign-38]
+ _ = x[SyncOp-39]
+ _ = x[SyncFuncLit-40]
+ _ = x[SyncCompLit-41]
+ _ = x[SyncDecl-42]
+ _ = x[SyncFuncBody-43]
+ _ = x[SyncOpenScope-44]
+ _ = x[SyncCloseScope-45]
+ _ = x[SyncCloseAnotherScope-46]
+ _ = x[SyncDeclNames-47]
+ _ = x[SyncDeclName-48]
+ _ = x[SyncStmts-49]
+ _ = x[SyncBlockStmt-50]
+ _ = x[SyncIfStmt-51]
+ _ = x[SyncForStmt-52]
+ _ = x[SyncSwitchStmt-53]
+ _ = x[SyncRangeStmt-54]
+ _ = x[SyncCaseClause-55]
+ _ = x[SyncCommClause-56]
+ _ = x[SyncSelectStmt-57]
+ _ = x[SyncDecls-58]
+ _ = x[SyncLabeledStmt-59]
+ _ = x[SyncUseObjLocal-60]
+ _ = x[SyncAddLocal-61]
+ _ = x[SyncLinkname-62]
+ _ = x[SyncStmt1-63]
+ _ = x[SyncStmtsEnd-64]
+ _ = x[SyncLabel-65]
+ _ = x[SyncOptLabel-66]
+ _ = x[SyncMultiExpr-67]
+ _ = x[SyncRType-68]
+ _ = x[SyncConvRTTI-69]
+}
+
+const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabelMultiExprRTypeConvRTTI"
+
+var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458, 467, 472, 480}
+
+func (i SyncMarker) String() string {
+ i -= 1
+ if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) {
+ return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")"
+ }
+ return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]]
+}
diff --git a/contrib/go/_std_1.20/src/internal/pkgbits/ya.make b/contrib/go/_std_1.21/src/internal/pkgbits/ya.make
index 977ae560cd..977ae560cd 100644
--- a/contrib/go/_std_1.20/src/internal/pkgbits/ya.make
+++ b/contrib/go/_std_1.21/src/internal/pkgbits/ya.make
diff --git a/contrib/go/_std_1.21/src/internal/platform/supported.go b/contrib/go/_std_1.21/src/internal/platform/supported.go
new file mode 100644
index 0000000000..230a952d2d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/platform/supported.go
@@ -0,0 +1,286 @@
+// Copyright 2018 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.
+
+//go:generate go test . -run=TestGenerated -fix
+
+package platform
+
+// An OSArch is a pair of GOOS and GOARCH values indicating a platform.
+type OSArch struct {
+ GOOS, GOARCH string
+}
+
+func (p OSArch) String() string {
+ return p.GOOS + "/" + p.GOARCH
+}
+
+// RaceDetectorSupported reports whether goos/goarch supports the race
+// detector. There is a copy of this function in cmd/dist/test.go.
+// Race detector only supports 48-bit VMA on arm64. But it will always
+// return true for arm64, because we don't have VMA size information during
+// the compile time.
+func RaceDetectorSupported(goos, goarch string) bool {
+ switch goos {
+ case "linux":
+ return goarch == "amd64" || goarch == "ppc64le" || goarch == "arm64" || goarch == "s390x"
+ case "darwin":
+ return goarch == "amd64" || goarch == "arm64"
+ case "freebsd", "netbsd", "openbsd", "windows":
+ return goarch == "amd64"
+ default:
+ return false
+ }
+}
+
+// MSanSupported reports whether goos/goarch supports the memory
+// sanitizer option.
+func MSanSupported(goos, goarch string) bool {
+ switch goos {
+ case "linux":
+ return goarch == "amd64" || goarch == "arm64"
+ case "freebsd":
+ return goarch == "amd64"
+ default:
+ return false
+ }
+}
+
+// ASanSupported reports whether goos/goarch supports the address
+// sanitizer option.
+func ASanSupported(goos, goarch string) bool {
+ switch goos {
+ case "linux":
+ return goarch == "arm64" || goarch == "amd64" || goarch == "riscv64" || goarch == "ppc64le"
+ default:
+ return false
+ }
+}
+
+// FuzzSupported reports whether goos/goarch supports fuzzing
+// ('go test -fuzz=.').
+func FuzzSupported(goos, goarch string) bool {
+ switch goos {
+ case "darwin", "freebsd", "linux", "windows":
+ return true
+ default:
+ return false
+ }
+}
+
+// FuzzInstrumented reports whether fuzzing on goos/goarch uses coverage
+// instrumentation. (FuzzInstrumented implies FuzzSupported.)
+func FuzzInstrumented(goos, goarch string) bool {
+ switch goarch {
+ case "amd64", "arm64":
+ // TODO(#14565): support more architectures.
+ return FuzzSupported(goos, goarch)
+ default:
+ return false
+ }
+}
+
+// MustLinkExternal reports whether goos/goarch requires external linking
+// with or without cgo dependencies.
+func MustLinkExternal(goos, goarch string, withCgo bool) bool {
+ if withCgo {
+ switch goarch {
+ case "loong64",
+ "mips", "mipsle", "mips64", "mips64le",
+ "riscv64":
+ // Internally linking cgo is incomplete on some architectures.
+ // https://go.dev/issue/14449
+ return true
+ case "arm64":
+ if goos == "windows" {
+ // windows/arm64 internal linking is not implemented.
+ return true
+ }
+ case "ppc64":
+ // Big Endian PPC64 cgo internal linking is not implemented for aix or linux.
+ // https://go.dev/issue/8912
+ return true
+ }
+
+ switch goos {
+ case "android":
+ return true
+ case "dragonfly":
+ // It seems that on Dragonfly thread local storage is
+ // set up by the dynamic linker, so internal cgo linking
+ // doesn't work. Test case is "go test runtime/cgo".
+ return true
+ }
+ }
+
+ switch goos {
+ case "android":
+ if goarch != "arm64" {
+ return true
+ }
+ case "ios":
+ if goarch == "arm64" {
+ return true
+ }
+ }
+ return false
+}
+
+// BuildModeSupported reports whether goos/goarch supports the given build mode
+// using the given compiler.
+// There is a copy of this function in cmd/dist/test.go.
+func BuildModeSupported(compiler, buildmode, goos, goarch string) bool {
+ if compiler == "gccgo" {
+ return true
+ }
+
+ if _, ok := distInfo[OSArch{goos, goarch}]; !ok {
+ return false // platform unrecognized
+ }
+
+ platform := goos + "/" + goarch
+ switch buildmode {
+ case "archive":
+ return true
+
+ case "c-archive":
+ switch goos {
+ case "aix", "darwin", "ios", "windows":
+ return true
+ case "linux":
+ switch goarch {
+ case "386", "amd64", "arm", "armbe", "arm64", "arm64be", "loong64", "ppc64le", "riscv64", "s390x":
+ // linux/ppc64 not supported because it does
+ // not support external linking mode yet.
+ return true
+ default:
+ // Other targets do not support -shared,
+ // per ParseFlags in
+ // cmd/compile/internal/base/flag.go.
+ // For c-archive the Go tool passes -shared,
+ // so that the result is suitable for inclusion
+ // in a PIE or shared library.
+ return false
+ }
+ case "freebsd":
+ return goarch == "amd64"
+ }
+ return false
+
+ case "c-shared":
+ switch platform {
+ case "linux/amd64", "linux/arm", "linux/arm64", "linux/loong64", "linux/386", "linux/ppc64le", "linux/riscv64", "linux/s390x",
+ "android/amd64", "android/arm", "android/arm64", "android/386",
+ "freebsd/amd64",
+ "darwin/amd64", "darwin/arm64",
+ "windows/amd64", "windows/386", "windows/arm64":
+ return true
+ }
+ return false
+
+ case "default":
+ return true
+
+ case "exe":
+ return true
+
+ case "pie":
+ switch platform {
+ case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/loong64", "linux/ppc64le", "linux/riscv64", "linux/s390x",
+ "android/amd64", "android/arm", "android/arm64", "android/386",
+ "freebsd/amd64",
+ "darwin/amd64", "darwin/arm64",
+ "ios/amd64", "ios/arm64",
+ "aix/ppc64",
+ "windows/386", "windows/amd64", "windows/arm", "windows/arm64":
+ return true
+ }
+ return false
+
+ case "shared":
+ switch platform {
+ case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
+ return true
+ }
+ return false
+
+ case "plugin":
+ switch platform {
+ case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x", "linux/ppc64le",
+ "android/amd64", "android/386",
+ "darwin/amd64", "darwin/arm64",
+ "freebsd/amd64":
+ return true
+ }
+ return false
+
+ default:
+ return false
+ }
+}
+
+func InternalLinkPIESupported(goos, goarch string) bool {
+ switch goos + "/" + goarch {
+ case "android/arm64",
+ "darwin/amd64", "darwin/arm64",
+ "linux/amd64", "linux/arm64", "linux/ppc64le",
+ "windows/386", "windows/amd64", "windows/arm", "windows/arm64":
+ return true
+ }
+ return false
+}
+
+// DefaultPIE reports whether goos/goarch produces a PIE binary when using the
+// "default" buildmode. On Windows this is affected by -race,
+// so force the caller to pass that in to centralize that choice.
+func DefaultPIE(goos, goarch string, isRace bool) bool {
+ switch goos {
+ case "android", "ios":
+ return true
+ case "windows":
+ if isRace {
+ // PIE is not supported with -race on windows;
+ // see https://go.dev/cl/416174.
+ return false
+ }
+ return true
+ case "darwin":
+ return goarch == "arm64"
+ }
+ return false
+}
+
+// ExecutableHasDWARF reports whether the linked executable includes DWARF
+// symbols on goos/goarch.
+func ExecutableHasDWARF(goos, goarch string) bool {
+ switch goos {
+ case "plan9", "ios":
+ return false
+ }
+ return true
+}
+
+// osArchInfo describes information about an OSArch extracted from cmd/dist and
+// stored in the generated distInfo map.
+type osArchInfo struct {
+ CgoSupported bool
+ FirstClass bool
+ Broken bool
+}
+
+// CgoSupported reports whether goos/goarch supports cgo.
+func CgoSupported(goos, goarch string) bool {
+ return distInfo[OSArch{goos, goarch}].CgoSupported
+}
+
+// FirstClass reports whether goos/goarch is considered a “first class” port.
+// (See https://go.dev/wiki/PortingPolicy#first-class-ports.)
+func FirstClass(goos, goarch string) bool {
+ return distInfo[OSArch{goos, goarch}].FirstClass
+}
+
+// Broken reportsr whether goos/goarch is considered a broken port.
+// (See https://go.dev/wiki/PortingPolicy#broken-ports.)
+func Broken(goos, goarch string) bool {
+ return distInfo[OSArch{goos, goarch}].Broken
+}
diff --git a/contrib/go/_std_1.21/src/internal/platform/ya.make b/contrib/go/_std_1.21/src/internal/platform/ya.make
new file mode 100644
index 0000000000..7ed14d13ef
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/platform/ya.make
@@ -0,0 +1,13 @@
+GO_LIBRARY()
+
+SRCS(
+ supported.go
+ zosarch.go
+)
+
+GO_XTEST_SRCS(zosarch_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/internal/platform/zosarch.go b/contrib/go/_std_1.21/src/internal/platform/zosarch.go
new file mode 100644
index 0000000000..7f5a290332
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/platform/zosarch.go
@@ -0,0 +1,114 @@
+// Code generated by go test internal/platform -fix. DO NOT EDIT.
+
+// To change the information in this file, edit the cgoEnabled and/or firstClass
+// maps in cmd/dist/build.go, then run 'go generate internal/platform'.
+
+package platform
+
+// List is the list of all valid GOOS/GOARCH combinations,
+// including known-broken ports.
+var List = []OSArch{
+ {"aix", "ppc64"},
+ {"android", "386"},
+ {"android", "amd64"},
+ {"android", "arm"},
+ {"android", "arm64"},
+ {"darwin", "amd64"},
+ {"darwin", "arm64"},
+ {"dragonfly", "amd64"},
+ {"freebsd", "386"},
+ {"freebsd", "amd64"},
+ {"freebsd", "arm"},
+ {"freebsd", "arm64"},
+ {"freebsd", "riscv64"},
+ {"illumos", "amd64"},
+ {"ios", "amd64"},
+ {"ios", "arm64"},
+ {"js", "wasm"},
+ {"linux", "386"},
+ {"linux", "amd64"},
+ {"linux", "arm"},
+ {"linux", "arm64"},
+ {"linux", "loong64"},
+ {"linux", "mips"},
+ {"linux", "mips64"},
+ {"linux", "mips64le"},
+ {"linux", "mipsle"},
+ {"linux", "ppc64"},
+ {"linux", "ppc64le"},
+ {"linux", "riscv64"},
+ {"linux", "s390x"},
+ {"linux", "sparc64"},
+ {"netbsd", "386"},
+ {"netbsd", "amd64"},
+ {"netbsd", "arm"},
+ {"netbsd", "arm64"},
+ {"openbsd", "386"},
+ {"openbsd", "amd64"},
+ {"openbsd", "arm"},
+ {"openbsd", "arm64"},
+ {"openbsd", "mips64"},
+ {"openbsd", "ppc64"},
+ {"plan9", "386"},
+ {"plan9", "amd64"},
+ {"plan9", "arm"},
+ {"solaris", "amd64"},
+ {"wasip1", "wasm"},
+ {"windows", "386"},
+ {"windows", "amd64"},
+ {"windows", "arm"},
+ {"windows", "arm64"},
+}
+
+var distInfo = map[OSArch]osArchInfo{
+ {"aix", "ppc64"}: {CgoSupported: true},
+ {"android", "386"}: {CgoSupported: true},
+ {"android", "amd64"}: {CgoSupported: true},
+ {"android", "arm"}: {CgoSupported: true},
+ {"android", "arm64"}: {CgoSupported: true},
+ {"darwin", "amd64"}: {CgoSupported: true, FirstClass: true},
+ {"darwin", "arm64"}: {CgoSupported: true, FirstClass: true},
+ {"dragonfly", "amd64"}: {CgoSupported: true},
+ {"freebsd", "386"}: {CgoSupported: true},
+ {"freebsd", "amd64"}: {CgoSupported: true},
+ {"freebsd", "arm"}: {CgoSupported: true},
+ {"freebsd", "arm64"}: {CgoSupported: true},
+ {"freebsd", "riscv64"}: {CgoSupported: true},
+ {"illumos", "amd64"}: {CgoSupported: true},
+ {"ios", "amd64"}: {CgoSupported: true},
+ {"ios", "arm64"}: {CgoSupported: true},
+ {"js", "wasm"}: {},
+ {"linux", "386"}: {CgoSupported: true, FirstClass: true},
+ {"linux", "amd64"}: {CgoSupported: true, FirstClass: true},
+ {"linux", "arm"}: {CgoSupported: true, FirstClass: true},
+ {"linux", "arm64"}: {CgoSupported: true, FirstClass: true},
+ {"linux", "loong64"}: {CgoSupported: true},
+ {"linux", "mips"}: {CgoSupported: true},
+ {"linux", "mips64"}: {CgoSupported: true},
+ {"linux", "mips64le"}: {CgoSupported: true},
+ {"linux", "mipsle"}: {CgoSupported: true},
+ {"linux", "ppc64"}: {},
+ {"linux", "ppc64le"}: {CgoSupported: true},
+ {"linux", "riscv64"}: {CgoSupported: true},
+ {"linux", "s390x"}: {CgoSupported: true},
+ {"linux", "sparc64"}: {CgoSupported: true, Broken: true},
+ {"netbsd", "386"}: {CgoSupported: true},
+ {"netbsd", "amd64"}: {CgoSupported: true},
+ {"netbsd", "arm"}: {CgoSupported: true},
+ {"netbsd", "arm64"}: {CgoSupported: true},
+ {"openbsd", "386"}: {CgoSupported: true},
+ {"openbsd", "amd64"}: {CgoSupported: true},
+ {"openbsd", "arm"}: {CgoSupported: true},
+ {"openbsd", "arm64"}: {CgoSupported: true},
+ {"openbsd", "mips64"}: {CgoSupported: true, Broken: true},
+ {"openbsd", "ppc64"}: {Broken: true},
+ {"plan9", "386"}: {},
+ {"plan9", "amd64"}: {},
+ {"plan9", "arm"}: {},
+ {"solaris", "amd64"}: {CgoSupported: true},
+ {"wasip1", "wasm"}: {},
+ {"windows", "386"}: {CgoSupported: true, FirstClass: true},
+ {"windows", "amd64"}: {CgoSupported: true, FirstClass: true},
+ {"windows", "arm"}: {},
+ {"windows", "arm64"}: {CgoSupported: true},
+}
diff --git a/contrib/go/_std_1.20/src/internal/poll/copy_file_range_linux.go b/contrib/go/_std_1.21/src/internal/poll/copy_file_range_linux.go
index ba33f5145d..ba33f5145d 100644
--- a/contrib/go/_std_1.20/src/internal/poll/copy_file_range_linux.go
+++ b/contrib/go/_std_1.21/src/internal/poll/copy_file_range_linux.go
diff --git a/contrib/go/_std_1.21/src/internal/poll/errno_unix.go b/contrib/go/_std_1.21/src/internal/poll/errno_unix.go
new file mode 100644
index 0000000000..d1a18abda4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/errno_unix.go
@@ -0,0 +1,33 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix || wasip1
+
+package poll
+
+import "syscall"
+
+// Do the interface allocations only once for common
+// Errno values.
+var (
+ errEAGAIN error = syscall.EAGAIN
+ errEINVAL error = syscall.EINVAL
+ errENOENT error = syscall.ENOENT
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return nil
+ case syscall.EAGAIN:
+ return errEAGAIN
+ case syscall.EINVAL:
+ return errEINVAL
+ case syscall.ENOENT:
+ return errENOENT
+ }
+ return e
+}
diff --git a/contrib/go/_std_1.20/src/internal/poll/errno_windows.go b/contrib/go/_std_1.21/src/internal/poll/errno_windows.go
index 63814793fd..63814793fd 100644
--- a/contrib/go/_std_1.20/src/internal/poll/errno_windows.go
+++ b/contrib/go/_std_1.21/src/internal/poll/errno_windows.go
diff --git a/contrib/go/_std_1.20/src/internal/poll/fd.go b/contrib/go/_std_1.21/src/internal/poll/fd.go
index ef61d0cb3f..ef61d0cb3f 100644
--- a/contrib/go/_std_1.20/src/internal/poll/fd.go
+++ b/contrib/go/_std_1.21/src/internal/poll/fd.go
diff --git a/contrib/go/_std_1.21/src/internal/poll/fd_fsync_darwin.go b/contrib/go/_std_1.21/src/internal/poll/fd_fsync_darwin.go
new file mode 100644
index 0000000000..731b7fd5bd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/fd_fsync_darwin.go
@@ -0,0 +1,24 @@
+// Copyright 2018 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 poll
+
+import (
+ "internal/syscall/unix"
+ "syscall"
+)
+
+// Fsync invokes SYS_FCNTL with SYS_FULLFSYNC because
+// on OS X, SYS_FSYNC doesn't fully flush contents to disk.
+// See Issue #26650 as well as the man page for fsync on OS X.
+func (fd *FD) Fsync() error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return ignoringEINTR(func() error {
+ _, err := unix.Fcntl(fd.Sysfd, syscall.F_FULLFSYNC, 0)
+ return err
+ })
+}
diff --git a/contrib/go/_std_1.21/src/internal/poll/fd_fsync_posix.go b/contrib/go/_std_1.21/src/internal/poll/fd_fsync_posix.go
new file mode 100644
index 0000000000..469ca75b62
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/fd_fsync_posix.go
@@ -0,0 +1,20 @@
+// Copyright 2018 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.
+
+//go:build aix || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris || wasip1
+
+package poll
+
+import "syscall"
+
+// Fsync wraps syscall.Fsync.
+func (fd *FD) Fsync() error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return ignoringEINTR(func() error {
+ return syscall.Fsync(fd.Sysfd)
+ })
+}
diff --git a/contrib/go/_std_1.20/src/internal/poll/fd_fsync_windows.go b/contrib/go/_std_1.21/src/internal/poll/fd_fsync_windows.go
index fb1211985d..fb1211985d 100644
--- a/contrib/go/_std_1.20/src/internal/poll/fd_fsync_windows.go
+++ b/contrib/go/_std_1.21/src/internal/poll/fd_fsync_windows.go
diff --git a/contrib/go/_std_1.20/src/internal/poll/fd_mutex.go b/contrib/go/_std_1.21/src/internal/poll/fd_mutex.go
index 0a8ee6f0d4..0a8ee6f0d4 100644
--- a/contrib/go/_std_1.20/src/internal/poll/fd_mutex.go
+++ b/contrib/go/_std_1.21/src/internal/poll/fd_mutex.go
diff --git a/contrib/go/_std_1.20/src/internal/poll/fd_opendir_darwin.go b/contrib/go/_std_1.21/src/internal/poll/fd_opendir_darwin.go
index 81cfb29079..81cfb29079 100644
--- a/contrib/go/_std_1.20/src/internal/poll/fd_opendir_darwin.go
+++ b/contrib/go/_std_1.21/src/internal/poll/fd_opendir_darwin.go
diff --git a/contrib/go/_std_1.21/src/internal/poll/fd_poll_runtime.go b/contrib/go/_std_1.21/src/internal/poll/fd_poll_runtime.go
new file mode 100644
index 0000000000..c80d0086f2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/fd_poll_runtime.go
@@ -0,0 +1,170 @@
+// Copyright 2013 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.
+
+//go:build unix || windows || wasip1
+
+package poll
+
+import (
+ "errors"
+ "sync"
+ "syscall"
+ "time"
+ _ "unsafe" // for go:linkname
+
+)
+
+// runtimeNano returns the current value of the runtime clock in nanoseconds.
+//
+//go:linkname runtimeNano runtime.nanotime
+func runtimeNano() int64
+
+func runtime_pollServerInit()
+func runtime_pollOpen(fd uintptr) (uintptr, int)
+func runtime_pollClose(ctx uintptr)
+func runtime_pollWait(ctx uintptr, mode int) int
+func runtime_pollWaitCanceled(ctx uintptr, mode int)
+func runtime_pollReset(ctx uintptr, mode int) int
+func runtime_pollSetDeadline(ctx uintptr, d int64, mode int)
+func runtime_pollUnblock(ctx uintptr)
+func runtime_isPollServerDescriptor(fd uintptr) bool
+
+type pollDesc struct {
+ runtimeCtx uintptr
+}
+
+var serverInit sync.Once
+
+func (pd *pollDesc) init(fd *FD) error {
+ serverInit.Do(runtime_pollServerInit)
+ ctx, errno := runtime_pollOpen(uintptr(fd.Sysfd))
+ if errno != 0 {
+ return errnoErr(syscall.Errno(errno))
+ }
+ pd.runtimeCtx = ctx
+ return nil
+}
+
+func (pd *pollDesc) close() {
+ if pd.runtimeCtx == 0 {
+ return
+ }
+ runtime_pollClose(pd.runtimeCtx)
+ pd.runtimeCtx = 0
+}
+
+// Evict evicts fd from the pending list, unblocking any I/O running on fd.
+func (pd *pollDesc) evict() {
+ if pd.runtimeCtx == 0 {
+ return
+ }
+ runtime_pollUnblock(pd.runtimeCtx)
+}
+
+func (pd *pollDesc) prepare(mode int, isFile bool) error {
+ if pd.runtimeCtx == 0 {
+ return nil
+ }
+ res := runtime_pollReset(pd.runtimeCtx, mode)
+ return convertErr(res, isFile)
+}
+
+func (pd *pollDesc) prepareRead(isFile bool) error {
+ return pd.prepare('r', isFile)
+}
+
+func (pd *pollDesc) prepareWrite(isFile bool) error {
+ return pd.prepare('w', isFile)
+}
+
+func (pd *pollDesc) wait(mode int, isFile bool) error {
+ if pd.runtimeCtx == 0 {
+ return errors.New("waiting for unsupported file type")
+ }
+ res := runtime_pollWait(pd.runtimeCtx, mode)
+ return convertErr(res, isFile)
+}
+
+func (pd *pollDesc) waitRead(isFile bool) error {
+ return pd.wait('r', isFile)
+}
+
+func (pd *pollDesc) waitWrite(isFile bool) error {
+ return pd.wait('w', isFile)
+}
+
+func (pd *pollDesc) waitCanceled(mode int) {
+ if pd.runtimeCtx == 0 {
+ return
+ }
+ runtime_pollWaitCanceled(pd.runtimeCtx, mode)
+}
+
+func (pd *pollDesc) pollable() bool {
+ return pd.runtimeCtx != 0
+}
+
+// Error values returned by runtime_pollReset and runtime_pollWait.
+// These must match the values in runtime/netpoll.go.
+const (
+ pollNoError = 0
+ pollErrClosing = 1
+ pollErrTimeout = 2
+ pollErrNotPollable = 3
+)
+
+func convertErr(res int, isFile bool) error {
+ switch res {
+ case pollNoError:
+ return nil
+ case pollErrClosing:
+ return errClosing(isFile)
+ case pollErrTimeout:
+ return ErrDeadlineExceeded
+ case pollErrNotPollable:
+ return ErrNotPollable
+ }
+ println("unreachable: ", res)
+ panic("unreachable")
+}
+
+// SetDeadline sets the read and write deadlines associated with fd.
+func (fd *FD) SetDeadline(t time.Time) error {
+ return setDeadlineImpl(fd, t, 'r'+'w')
+}
+
+// SetReadDeadline sets the read deadline associated with fd.
+func (fd *FD) SetReadDeadline(t time.Time) error {
+ return setDeadlineImpl(fd, t, 'r')
+}
+
+// SetWriteDeadline sets the write deadline associated with fd.
+func (fd *FD) SetWriteDeadline(t time.Time) error {
+ return setDeadlineImpl(fd, t, 'w')
+}
+
+func setDeadlineImpl(fd *FD, t time.Time, mode int) error {
+ var d int64
+ if !t.IsZero() {
+ d = int64(time.Until(t))
+ if d == 0 {
+ d = -1 // don't confuse deadline right now with no deadline
+ }
+ }
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ if fd.pd.runtimeCtx == 0 {
+ return ErrNoDeadline
+ }
+ runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode)
+ return nil
+}
+
+// IsPollDescriptor reports whether fd is the descriptor being used by the poller.
+// This is only used for testing.
+func IsPollDescriptor(fd uintptr) bool {
+ return runtime_isPollServerDescriptor(fd)
+}
diff --git a/contrib/go/_std_1.21/src/internal/poll/fd_posix.go b/contrib/go/_std_1.21/src/internal/poll/fd_posix.go
new file mode 100644
index 0000000000..5bd333b4da
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/fd_posix.go
@@ -0,0 +1,79 @@
+// Copyright 2009 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package poll
+
+import (
+ "io"
+ "syscall"
+)
+
+// eofError returns io.EOF when fd is available for reading end of
+// file.
+func (fd *FD) eofError(n int, err error) error {
+ if n == 0 && err == nil && fd.ZeroReadIsEOF {
+ return io.EOF
+ }
+ return err
+}
+
+// Shutdown wraps syscall.Shutdown.
+func (fd *FD) Shutdown(how int) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return syscall.Shutdown(fd.Sysfd, how)
+}
+
+// Fchown wraps syscall.Fchown.
+func (fd *FD) Fchown(uid, gid int) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return ignoringEINTR(func() error {
+ return syscall.Fchown(fd.Sysfd, uid, gid)
+ })
+}
+
+// Ftruncate wraps syscall.Ftruncate.
+func (fd *FD) Ftruncate(size int64) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return ignoringEINTR(func() error {
+ return syscall.Ftruncate(fd.Sysfd, size)
+ })
+}
+
+// RawControl invokes the user-defined function f for a non-IO
+// operation.
+func (fd *FD) RawControl(f func(uintptr)) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ f(uintptr(fd.Sysfd))
+ return nil
+}
+
+// ignoringEINTR makes a function call and repeats it if it returns
+// an EINTR error. This appears to be required even though we install all
+// signal handlers with SA_RESTART: see #22838, #38033, #38836, #40846.
+// Also #20400 and #36644 are issues in which a signal handler is
+// installed without setting SA_RESTART. None of these are the common case,
+// but there are enough of them that it seems that we can't avoid
+// an EINTR loop.
+func ignoringEINTR(fn func() error) error {
+ for {
+ err := fn()
+ if err != syscall.EINTR {
+ return err
+ }
+ }
+}
diff --git a/contrib/go/_std_1.21/src/internal/poll/fd_unix.go b/contrib/go/_std_1.21/src/internal/poll/fd_unix.go
new file mode 100644
index 0000000000..61c2338305
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/fd_unix.go
@@ -0,0 +1,741 @@
+// Copyright 2017 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package poll
+
+import (
+ "internal/syscall/unix"
+ "io"
+ "sync/atomic"
+ "syscall"
+)
+
+// FD is a file descriptor. The net and os packages use this type as a
+// field of a larger type representing a network connection or OS file.
+type FD struct {
+ // Lock sysfd and serialize access to Read and Write methods.
+ fdmu fdMutex
+
+ // System file descriptor. Immutable until Close.
+ Sysfd int
+
+ // Platform dependent state of the file descriptor.
+ SysFile
+
+ // I/O poller.
+ pd pollDesc
+
+ // Semaphore signaled when file is closed.
+ csema uint32
+
+ // Non-zero if this file has been set to blocking mode.
+ isBlocking uint32
+
+ // Whether this is a streaming descriptor, as opposed to a
+ // packet-based descriptor like a UDP socket. Immutable.
+ IsStream bool
+
+ // Whether a zero byte read indicates EOF. This is false for a
+ // message based socket connection.
+ ZeroReadIsEOF bool
+
+ // Whether this is a file rather than a network socket.
+ isFile bool
+}
+
+// Init initializes the FD. The Sysfd field should already be set.
+// This can be called multiple times on a single FD.
+// The net argument is a network name from the net package (e.g., "tcp"),
+// or "file".
+// Set pollable to true if fd should be managed by runtime netpoll.
+func (fd *FD) Init(net string, pollable bool) error {
+ fd.SysFile.init()
+
+ // We don't actually care about the various network types.
+ if net == "file" {
+ fd.isFile = true
+ }
+ if !pollable {
+ fd.isBlocking = 1
+ return nil
+ }
+ err := fd.pd.init(fd)
+ if err != nil {
+ // If we could not initialize the runtime poller,
+ // assume we are using blocking mode.
+ fd.isBlocking = 1
+ }
+ return err
+}
+
+// Destroy closes the file descriptor. This is called when there are
+// no remaining references.
+func (fd *FD) destroy() error {
+ // Poller may want to unregister fd in readiness notification mechanism,
+ // so this must be executed before CloseFunc.
+ fd.pd.close()
+
+ err := fd.SysFile.destroy(fd.Sysfd)
+
+ fd.Sysfd = -1
+ runtime_Semrelease(&fd.csema)
+ return err
+}
+
+// Close closes the FD. The underlying file descriptor is closed by the
+// destroy method when there are no remaining references.
+func (fd *FD) Close() error {
+ if !fd.fdmu.increfAndClose() {
+ return errClosing(fd.isFile)
+ }
+
+ // Unblock any I/O. Once it all unblocks and returns,
+ // so that it cannot be referring to fd.sysfd anymore,
+ // the final decref will close fd.sysfd. This should happen
+ // fairly quickly, since all the I/O is non-blocking, and any
+ // attempts to block in the pollDesc will return errClosing(fd.isFile).
+ fd.pd.evict()
+
+ // The call to decref will call destroy if there are no other
+ // references.
+ err := fd.decref()
+
+ // Wait until the descriptor is closed. If this was the only
+ // reference, it is already closed. Only wait if the file has
+ // not been set to blocking mode, as otherwise any current I/O
+ // may be blocking, and that would block the Close.
+ // No need for an atomic read of isBlocking, increfAndClose means
+ // we have exclusive access to fd.
+ if fd.isBlocking == 0 {
+ runtime_Semacquire(&fd.csema)
+ }
+
+ return err
+}
+
+// SetBlocking puts the file into blocking mode.
+func (fd *FD) SetBlocking() error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ // Atomic store so that concurrent calls to SetBlocking
+ // do not cause a race condition. isBlocking only ever goes
+ // from 0 to 1 so there is no real race here.
+ atomic.StoreUint32(&fd.isBlocking, 1)
+ return syscall.SetNonblock(fd.Sysfd, false)
+}
+
+// Darwin and FreeBSD can't read or write 2GB+ files at a time,
+// even on 64-bit systems.
+// The same is true of socket implementations on many systems.
+// See golang.org/issue/7812 and golang.org/issue/16266.
+// Use 1GB instead of, say, 2GB-1, to keep subsequent reads aligned.
+const maxRW = 1 << 30
+
+// Read implements io.Reader.
+func (fd *FD) Read(p []byte) (int, error) {
+ if err := fd.readLock(); err != nil {
+ return 0, err
+ }
+ defer fd.readUnlock()
+ if len(p) == 0 {
+ // If the caller wanted a zero byte read, return immediately
+ // without trying (but after acquiring the readLock).
+ // Otherwise syscall.Read returns 0, nil which looks like
+ // io.EOF.
+ // TODO(bradfitz): make it wait for readability? (Issue 15735)
+ return 0, nil
+ }
+ if err := fd.pd.prepareRead(fd.isFile); err != nil {
+ return 0, err
+ }
+ if fd.IsStream && len(p) > maxRW {
+ p = p[:maxRW]
+ }
+ for {
+ n, err := ignoringEINTRIO(syscall.Read, fd.Sysfd, p)
+ if err != nil {
+ n = 0
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitRead(fd.isFile); err == nil {
+ continue
+ }
+ }
+ }
+ err = fd.eofError(n, err)
+ return n, err
+ }
+}
+
+// Pread wraps the pread system call.
+func (fd *FD) Pread(p []byte, off int64) (int, error) {
+ // Call incref, not readLock, because since pread specifies the
+ // offset it is independent from other reads.
+ // Similarly, using the poller doesn't make sense for pread.
+ if err := fd.incref(); err != nil {
+ return 0, err
+ }
+ if fd.IsStream && len(p) > maxRW {
+ p = p[:maxRW]
+ }
+ var (
+ n int
+ err error
+ )
+ for {
+ n, err = syscall.Pread(fd.Sysfd, p, off)
+ if err != syscall.EINTR {
+ break
+ }
+ }
+ if err != nil {
+ n = 0
+ }
+ fd.decref()
+ err = fd.eofError(n, err)
+ return n, err
+}
+
+// ReadFrom wraps the recvfrom network call.
+func (fd *FD) ReadFrom(p []byte) (int, syscall.Sockaddr, error) {
+ if err := fd.readLock(); err != nil {
+ return 0, nil, err
+ }
+ defer fd.readUnlock()
+ if err := fd.pd.prepareRead(fd.isFile); err != nil {
+ return 0, nil, err
+ }
+ for {
+ n, sa, err := syscall.Recvfrom(fd.Sysfd, p, 0)
+ if err != nil {
+ if err == syscall.EINTR {
+ continue
+ }
+ n = 0
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitRead(fd.isFile); err == nil {
+ continue
+ }
+ }
+ }
+ err = fd.eofError(n, err)
+ return n, sa, err
+ }
+}
+
+// ReadFromInet4 wraps the recvfrom network call for IPv4.
+func (fd *FD) ReadFromInet4(p []byte, from *syscall.SockaddrInet4) (int, error) {
+ if err := fd.readLock(); err != nil {
+ return 0, err
+ }
+ defer fd.readUnlock()
+ if err := fd.pd.prepareRead(fd.isFile); err != nil {
+ return 0, err
+ }
+ for {
+ n, err := unix.RecvfromInet4(fd.Sysfd, p, 0, from)
+ if err != nil {
+ if err == syscall.EINTR {
+ continue
+ }
+ n = 0
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitRead(fd.isFile); err == nil {
+ continue
+ }
+ }
+ }
+ err = fd.eofError(n, err)
+ return n, err
+ }
+}
+
+// ReadFromInet6 wraps the recvfrom network call for IPv6.
+func (fd *FD) ReadFromInet6(p []byte, from *syscall.SockaddrInet6) (int, error) {
+ if err := fd.readLock(); err != nil {
+ return 0, err
+ }
+ defer fd.readUnlock()
+ if err := fd.pd.prepareRead(fd.isFile); err != nil {
+ return 0, err
+ }
+ for {
+ n, err := unix.RecvfromInet6(fd.Sysfd, p, 0, from)
+ if err != nil {
+ if err == syscall.EINTR {
+ continue
+ }
+ n = 0
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitRead(fd.isFile); err == nil {
+ continue
+ }
+ }
+ }
+ err = fd.eofError(n, err)
+ return n, err
+ }
+}
+
+// ReadMsg wraps the recvmsg network call.
+func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) {
+ if err := fd.readLock(); err != nil {
+ return 0, 0, 0, nil, err
+ }
+ defer fd.readUnlock()
+ if err := fd.pd.prepareRead(fd.isFile); err != nil {
+ return 0, 0, 0, nil, err
+ }
+ for {
+ n, oobn, sysflags, sa, err := syscall.Recvmsg(fd.Sysfd, p, oob, flags)
+ if err != nil {
+ if err == syscall.EINTR {
+ continue
+ }
+ // TODO(dfc) should n and oobn be set to 0
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitRead(fd.isFile); err == nil {
+ continue
+ }
+ }
+ }
+ err = fd.eofError(n, err)
+ return n, oobn, sysflags, sa, err
+ }
+}
+
+// ReadMsgInet4 is ReadMsg, but specialized for syscall.SockaddrInet4.
+func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) {
+ if err := fd.readLock(); err != nil {
+ return 0, 0, 0, err
+ }
+ defer fd.readUnlock()
+ if err := fd.pd.prepareRead(fd.isFile); err != nil {
+ return 0, 0, 0, err
+ }
+ for {
+ n, oobn, sysflags, err := unix.RecvmsgInet4(fd.Sysfd, p, oob, flags, sa4)
+ if err != nil {
+ if err == syscall.EINTR {
+ continue
+ }
+ // TODO(dfc) should n and oobn be set to 0
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitRead(fd.isFile); err == nil {
+ continue
+ }
+ }
+ }
+ err = fd.eofError(n, err)
+ return n, oobn, sysflags, err
+ }
+}
+
+// ReadMsgInet6 is ReadMsg, but specialized for syscall.SockaddrInet6.
+func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) {
+ if err := fd.readLock(); err != nil {
+ return 0, 0, 0, err
+ }
+ defer fd.readUnlock()
+ if err := fd.pd.prepareRead(fd.isFile); err != nil {
+ return 0, 0, 0, err
+ }
+ for {
+ n, oobn, sysflags, err := unix.RecvmsgInet6(fd.Sysfd, p, oob, flags, sa6)
+ if err != nil {
+ if err == syscall.EINTR {
+ continue
+ }
+ // TODO(dfc) should n and oobn be set to 0
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitRead(fd.isFile); err == nil {
+ continue
+ }
+ }
+ }
+ err = fd.eofError(n, err)
+ return n, oobn, sysflags, err
+ }
+}
+
+// Write implements io.Writer.
+func (fd *FD) Write(p []byte) (int, error) {
+ if err := fd.writeLock(); err != nil {
+ return 0, err
+ }
+ defer fd.writeUnlock()
+ if err := fd.pd.prepareWrite(fd.isFile); err != nil {
+ return 0, err
+ }
+ var nn int
+ for {
+ max := len(p)
+ if fd.IsStream && max-nn > maxRW {
+ max = nn + maxRW
+ }
+ n, err := ignoringEINTRIO(syscall.Write, fd.Sysfd, p[nn:max])
+ if n > 0 {
+ nn += n
+ }
+ if nn == len(p) {
+ return nn, err
+ }
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitWrite(fd.isFile); err == nil {
+ continue
+ }
+ }
+ if err != nil {
+ return nn, err
+ }
+ if n == 0 {
+ return nn, io.ErrUnexpectedEOF
+ }
+ }
+}
+
+// Pwrite wraps the pwrite system call.
+func (fd *FD) Pwrite(p []byte, off int64) (int, error) {
+ // Call incref, not writeLock, because since pwrite specifies the
+ // offset it is independent from other writes.
+ // Similarly, using the poller doesn't make sense for pwrite.
+ if err := fd.incref(); err != nil {
+ return 0, err
+ }
+ defer fd.decref()
+ var nn int
+ for {
+ max := len(p)
+ if fd.IsStream && max-nn > maxRW {
+ max = nn + maxRW
+ }
+ n, err := syscall.Pwrite(fd.Sysfd, p[nn:max], off+int64(nn))
+ if err == syscall.EINTR {
+ continue
+ }
+ if n > 0 {
+ nn += n
+ }
+ if nn == len(p) {
+ return nn, err
+ }
+ if err != nil {
+ return nn, err
+ }
+ if n == 0 {
+ return nn, io.ErrUnexpectedEOF
+ }
+ }
+}
+
+// WriteToInet4 wraps the sendto network call for IPv4 addresses.
+func (fd *FD) WriteToInet4(p []byte, sa *syscall.SockaddrInet4) (int, error) {
+ if err := fd.writeLock(); err != nil {
+ return 0, err
+ }
+ defer fd.writeUnlock()
+ if err := fd.pd.prepareWrite(fd.isFile); err != nil {
+ return 0, err
+ }
+ for {
+ err := unix.SendtoInet4(fd.Sysfd, p, 0, sa)
+ if err == syscall.EINTR {
+ continue
+ }
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitWrite(fd.isFile); err == nil {
+ continue
+ }
+ }
+ if err != nil {
+ return 0, err
+ }
+ return len(p), nil
+ }
+}
+
+// WriteToInet6 wraps the sendto network call for IPv6 addresses.
+func (fd *FD) WriteToInet6(p []byte, sa *syscall.SockaddrInet6) (int, error) {
+ if err := fd.writeLock(); err != nil {
+ return 0, err
+ }
+ defer fd.writeUnlock()
+ if err := fd.pd.prepareWrite(fd.isFile); err != nil {
+ return 0, err
+ }
+ for {
+ err := unix.SendtoInet6(fd.Sysfd, p, 0, sa)
+ if err == syscall.EINTR {
+ continue
+ }
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitWrite(fd.isFile); err == nil {
+ continue
+ }
+ }
+ if err != nil {
+ return 0, err
+ }
+ return len(p), nil
+ }
+}
+
+// WriteTo wraps the sendto network call.
+func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) {
+ if err := fd.writeLock(); err != nil {
+ return 0, err
+ }
+ defer fd.writeUnlock()
+ if err := fd.pd.prepareWrite(fd.isFile); err != nil {
+ return 0, err
+ }
+ for {
+ err := syscall.Sendto(fd.Sysfd, p, 0, sa)
+ if err == syscall.EINTR {
+ continue
+ }
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitWrite(fd.isFile); err == nil {
+ continue
+ }
+ }
+ if err != nil {
+ return 0, err
+ }
+ return len(p), nil
+ }
+}
+
+// WriteMsg wraps the sendmsg network call.
+func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
+ if err := fd.writeLock(); err != nil {
+ return 0, 0, err
+ }
+ defer fd.writeUnlock()
+ if err := fd.pd.prepareWrite(fd.isFile); err != nil {
+ return 0, 0, err
+ }
+ for {
+ n, err := syscall.SendmsgN(fd.Sysfd, p, oob, sa, 0)
+ if err == syscall.EINTR {
+ continue
+ }
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitWrite(fd.isFile); err == nil {
+ continue
+ }
+ }
+ if err != nil {
+ return n, 0, err
+ }
+ return n, len(oob), err
+ }
+}
+
+// WriteMsgInet4 is WriteMsg specialized for syscall.SockaddrInet4.
+func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (int, int, error) {
+ if err := fd.writeLock(); err != nil {
+ return 0, 0, err
+ }
+ defer fd.writeUnlock()
+ if err := fd.pd.prepareWrite(fd.isFile); err != nil {
+ return 0, 0, err
+ }
+ for {
+ n, err := unix.SendmsgNInet4(fd.Sysfd, p, oob, sa, 0)
+ if err == syscall.EINTR {
+ continue
+ }
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitWrite(fd.isFile); err == nil {
+ continue
+ }
+ }
+ if err != nil {
+ return n, 0, err
+ }
+ return n, len(oob), err
+ }
+}
+
+// WriteMsgInet6 is WriteMsg specialized for syscall.SockaddrInet6.
+func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (int, int, error) {
+ if err := fd.writeLock(); err != nil {
+ return 0, 0, err
+ }
+ defer fd.writeUnlock()
+ if err := fd.pd.prepareWrite(fd.isFile); err != nil {
+ return 0, 0, err
+ }
+ for {
+ n, err := unix.SendmsgNInet6(fd.Sysfd, p, oob, sa, 0)
+ if err == syscall.EINTR {
+ continue
+ }
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitWrite(fd.isFile); err == nil {
+ continue
+ }
+ }
+ if err != nil {
+ return n, 0, err
+ }
+ return n, len(oob), err
+ }
+}
+
+// Accept wraps the accept network call.
+func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) {
+ if err := fd.readLock(); err != nil {
+ return -1, nil, "", err
+ }
+ defer fd.readUnlock()
+
+ if err := fd.pd.prepareRead(fd.isFile); err != nil {
+ return -1, nil, "", err
+ }
+ for {
+ s, rsa, errcall, err := accept(fd.Sysfd)
+ if err == nil {
+ return s, rsa, "", err
+ }
+ switch err {
+ case syscall.EINTR:
+ continue
+ case syscall.EAGAIN:
+ if fd.pd.pollable() {
+ if err = fd.pd.waitRead(fd.isFile); err == nil {
+ continue
+ }
+ }
+ case syscall.ECONNABORTED:
+ // This means that a socket on the listen
+ // queue was closed before we Accept()ed it;
+ // it's a silly error, so try again.
+ continue
+ }
+ return -1, nil, errcall, err
+ }
+}
+
+// Fchmod wraps syscall.Fchmod.
+func (fd *FD) Fchmod(mode uint32) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return ignoringEINTR(func() error {
+ return syscall.Fchmod(fd.Sysfd, mode)
+ })
+}
+
+// Fstat wraps syscall.Fstat
+func (fd *FD) Fstat(s *syscall.Stat_t) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return ignoringEINTR(func() error {
+ return syscall.Fstat(fd.Sysfd, s)
+ })
+}
+
+// dupCloexecUnsupported indicates whether F_DUPFD_CLOEXEC is supported by the kernel.
+var dupCloexecUnsupported atomic.Bool
+
+// DupCloseOnExec dups fd and marks it close-on-exec.
+func DupCloseOnExec(fd int) (int, string, error) {
+ if syscall.F_DUPFD_CLOEXEC != 0 && !dupCloexecUnsupported.Load() {
+ r0, err := unix.Fcntl(fd, syscall.F_DUPFD_CLOEXEC, 0)
+ if err == nil {
+ return r0, "", nil
+ }
+ switch err {
+ case syscall.EINVAL, syscall.ENOSYS:
+ // Old kernel, or js/wasm (which returns
+ // ENOSYS). Fall back to the portable way from
+ // now on.
+ dupCloexecUnsupported.Store(true)
+ default:
+ return -1, "fcntl", err
+ }
+ }
+ return dupCloseOnExecOld(fd)
+}
+
+// Dup duplicates the file descriptor.
+func (fd *FD) Dup() (int, string, error) {
+ if err := fd.incref(); err != nil {
+ return -1, "", err
+ }
+ defer fd.decref()
+ return DupCloseOnExec(fd.Sysfd)
+}
+
+// On Unix variants only, expose the IO event for the net code.
+
+// WaitWrite waits until data can be read from fd.
+func (fd *FD) WaitWrite() error {
+ return fd.pd.waitWrite(fd.isFile)
+}
+
+// WriteOnce is for testing only. It makes a single write call.
+func (fd *FD) WriteOnce(p []byte) (int, error) {
+ if err := fd.writeLock(); err != nil {
+ return 0, err
+ }
+ defer fd.writeUnlock()
+ return ignoringEINTRIO(syscall.Write, fd.Sysfd, p)
+}
+
+// RawRead invokes the user-defined function f for a read operation.
+func (fd *FD) RawRead(f func(uintptr) bool) error {
+ if err := fd.readLock(); err != nil {
+ return err
+ }
+ defer fd.readUnlock()
+ if err := fd.pd.prepareRead(fd.isFile); err != nil {
+ return err
+ }
+ for {
+ if f(uintptr(fd.Sysfd)) {
+ return nil
+ }
+ if err := fd.pd.waitRead(fd.isFile); err != nil {
+ return err
+ }
+ }
+}
+
+// RawWrite invokes the user-defined function f for a write operation.
+func (fd *FD) RawWrite(f func(uintptr) bool) error {
+ if err := fd.writeLock(); err != nil {
+ return err
+ }
+ defer fd.writeUnlock()
+ if err := fd.pd.prepareWrite(fd.isFile); err != nil {
+ return err
+ }
+ for {
+ if f(uintptr(fd.Sysfd)) {
+ return nil
+ }
+ if err := fd.pd.waitWrite(fd.isFile); err != nil {
+ return err
+ }
+ }
+}
+
+// ignoringEINTRIO is like ignoringEINTR, but just for IO calls.
+func ignoringEINTRIO(fn func(fd int, p []byte) (int, error), fd int, p []byte) (int, error) {
+ for {
+ n, err := fn(fd, p)
+ if err != syscall.EINTR {
+ return n, err
+ }
+ }
+}
diff --git a/contrib/go/_std_1.21/src/internal/poll/fd_unixjs.go b/contrib/go/_std_1.21/src/internal/poll/fd_unixjs.go
new file mode 100644
index 0000000000..090974d2b0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/fd_unixjs.go
@@ -0,0 +1,79 @@
+// Copyright 2023 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.
+
+//go:build unix || (js && wasm)
+
+package poll
+
+import "syscall"
+
+type SysFile struct {
+ // Writev cache.
+ iovecs *[]syscall.Iovec
+}
+
+func (s *SysFile) init() {}
+
+func (s *SysFile) destroy(fd int) error {
+ // We don't use ignoringEINTR here because POSIX does not define
+ // whether the descriptor is closed if close returns EINTR.
+ // If the descriptor is indeed closed, using a loop would race
+ // with some other goroutine opening a new descriptor.
+ // (The Linux kernel guarantees that it is closed on an EINTR error.)
+ return CloseFunc(fd)
+}
+
+// dupCloseOnExecOld is the traditional way to dup an fd and
+// set its O_CLOEXEC bit, using two system calls.
+func dupCloseOnExecOld(fd int) (int, string, error) {
+ syscall.ForkLock.RLock()
+ defer syscall.ForkLock.RUnlock()
+ newfd, err := syscall.Dup(fd)
+ if err != nil {
+ return -1, "dup", err
+ }
+ syscall.CloseOnExec(newfd)
+ return newfd, "", nil
+}
+
+// Fchdir wraps syscall.Fchdir.
+func (fd *FD) Fchdir() error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return syscall.Fchdir(fd.Sysfd)
+}
+
+// ReadDirent wraps syscall.ReadDirent.
+// We treat this like an ordinary system call rather than a call
+// that tries to fill the buffer.
+func (fd *FD) ReadDirent(buf []byte) (int, error) {
+ if err := fd.incref(); err != nil {
+ return 0, err
+ }
+ defer fd.decref()
+ for {
+ n, err := ignoringEINTRIO(syscall.ReadDirent, fd.Sysfd, buf)
+ if err != nil {
+ n = 0
+ if err == syscall.EAGAIN && fd.pd.pollable() {
+ if err = fd.pd.waitRead(fd.isFile); err == nil {
+ continue
+ }
+ }
+ }
+ // Do not call eofError; caller does not expect to see io.EOF.
+ return n, err
+ }
+}
+
+// Seek wraps syscall.Seek.
+func (fd *FD) Seek(offset int64, whence int) (int64, error) {
+ if err := fd.incref(); err != nil {
+ return 0, err
+ }
+ defer fd.decref()
+ return syscall.Seek(fd.Sysfd, offset, whence)
+}
diff --git a/contrib/go/_std_1.21/src/internal/poll/fd_windows.go b/contrib/go/_std_1.21/src/internal/poll/fd_windows.go
new file mode 100644
index 0000000000..9df39edced
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/fd_windows.go
@@ -0,0 +1,1332 @@
+// Copyright 2017 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 poll
+
+import (
+ "errors"
+ "internal/race"
+ "internal/syscall/windows"
+ "io"
+ "sync"
+ "syscall"
+ "unicode/utf16"
+ "unicode/utf8"
+ "unsafe"
+)
+
+var (
+ initErr error
+ ioSync uint64
+)
+
+// This package uses the SetFileCompletionNotificationModes Windows
+// API to skip calling GetQueuedCompletionStatus if an IO operation
+// completes synchronously. There is a known bug where
+// SetFileCompletionNotificationModes crashes on some systems (see
+// https://support.microsoft.com/kb/2568167 for details).
+
+var useSetFileCompletionNotificationModes bool // determines is SetFileCompletionNotificationModes is present and safe to use
+
+// checkSetFileCompletionNotificationModes verifies that
+// SetFileCompletionNotificationModes Windows API is present
+// on the system and is safe to use.
+// See https://support.microsoft.com/kb/2568167 for details.
+func checkSetFileCompletionNotificationModes() {
+ err := syscall.LoadSetFileCompletionNotificationModes()
+ if err != nil {
+ return
+ }
+ protos := [2]int32{syscall.IPPROTO_TCP, 0}
+ var buf [32]syscall.WSAProtocolInfo
+ len := uint32(unsafe.Sizeof(buf))
+ n, err := syscall.WSAEnumProtocols(&protos[0], &buf[0], &len)
+ if err != nil {
+ return
+ }
+ for i := int32(0); i < n; i++ {
+ if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 {
+ return
+ }
+ }
+ useSetFileCompletionNotificationModes = true
+}
+
+func init() {
+ var d syscall.WSAData
+ e := syscall.WSAStartup(uint32(0x202), &d)
+ if e != nil {
+ initErr = e
+ }
+ checkSetFileCompletionNotificationModes()
+}
+
+// operation contains superset of data necessary to perform all async IO.
+type operation struct {
+ // Used by IOCP interface, it must be first field
+ // of the struct, as our code rely on it.
+ o syscall.Overlapped
+
+ // fields used by runtime.netpoll
+ runtimeCtx uintptr
+ mode int32
+ errno int32
+ qty uint32
+
+ // fields used only by net package
+ fd *FD
+ buf syscall.WSABuf
+ msg windows.WSAMsg
+ sa syscall.Sockaddr
+ rsa *syscall.RawSockaddrAny
+ rsan int32
+ handle syscall.Handle
+ flags uint32
+ bufs []syscall.WSABuf
+}
+
+func (o *operation) InitBuf(buf []byte) {
+ o.buf.Len = uint32(len(buf))
+ o.buf.Buf = nil
+ if len(buf) != 0 {
+ o.buf.Buf = &buf[0]
+ }
+}
+
+func (o *operation) InitBufs(buf *[][]byte) {
+ if o.bufs == nil {
+ o.bufs = make([]syscall.WSABuf, 0, len(*buf))
+ } else {
+ o.bufs = o.bufs[:0]
+ }
+ for _, b := range *buf {
+ if len(b) == 0 {
+ o.bufs = append(o.bufs, syscall.WSABuf{})
+ continue
+ }
+ for len(b) > maxRW {
+ o.bufs = append(o.bufs, syscall.WSABuf{Len: maxRW, Buf: &b[0]})
+ b = b[maxRW:]
+ }
+ if len(b) > 0 {
+ o.bufs = append(o.bufs, syscall.WSABuf{Len: uint32(len(b)), Buf: &b[0]})
+ }
+ }
+}
+
+// ClearBufs clears all pointers to Buffers parameter captured
+// by InitBufs, so it can be released by garbage collector.
+func (o *operation) ClearBufs() {
+ for i := range o.bufs {
+ o.bufs[i].Buf = nil
+ }
+ o.bufs = o.bufs[:0]
+}
+
+func (o *operation) InitMsg(p []byte, oob []byte) {
+ o.InitBuf(p)
+ o.msg.Buffers = &o.buf
+ o.msg.BufferCount = 1
+
+ o.msg.Name = nil
+ o.msg.Namelen = 0
+
+ o.msg.Flags = 0
+ o.msg.Control.Len = uint32(len(oob))
+ o.msg.Control.Buf = nil
+ if len(oob) != 0 {
+ o.msg.Control.Buf = &oob[0]
+ }
+}
+
+// execIO executes a single IO operation o. It submits and cancels
+// IO in the current thread for systems where Windows CancelIoEx API
+// is available. Alternatively, it passes the request onto
+// runtime netpoll and waits for completion or cancels request.
+func execIO(o *operation, submit func(o *operation) error) (int, error) {
+ if o.fd.pd.runtimeCtx == 0 {
+ return 0, errors.New("internal error: polling on unsupported descriptor type")
+ }
+
+ fd := o.fd
+ // Notify runtime netpoll about starting IO.
+ err := fd.pd.prepare(int(o.mode), fd.isFile)
+ if err != nil {
+ return 0, err
+ }
+ // Start IO.
+ err = submit(o)
+ switch err {
+ case nil:
+ // IO completed immediately
+ if o.fd.skipSyncNotif {
+ // No completion message will follow, so return immediately.
+ return int(o.qty), nil
+ }
+ // Need to get our completion message anyway.
+ case syscall.ERROR_IO_PENDING:
+ // IO started, and we have to wait for its completion.
+ err = nil
+ default:
+ return 0, err
+ }
+ // Wait for our request to complete.
+ err = fd.pd.wait(int(o.mode), fd.isFile)
+ if err == nil {
+ // All is good. Extract our IO results and return.
+ if o.errno != 0 {
+ err = syscall.Errno(o.errno)
+ // More data available. Return back the size of received data.
+ if err == syscall.ERROR_MORE_DATA || err == windows.WSAEMSGSIZE {
+ return int(o.qty), err
+ }
+ return 0, err
+ }
+ return int(o.qty), nil
+ }
+ // IO is interrupted by "close" or "timeout"
+ netpollErr := err
+ switch netpollErr {
+ case ErrNetClosing, ErrFileClosing, ErrDeadlineExceeded:
+ // will deal with those.
+ default:
+ panic("unexpected runtime.netpoll error: " + netpollErr.Error())
+ }
+ // Cancel our request.
+ err = syscall.CancelIoEx(fd.Sysfd, &o.o)
+ // Assuming ERROR_NOT_FOUND is returned, if IO is completed.
+ if err != nil && err != syscall.ERROR_NOT_FOUND {
+ // TODO(brainman): maybe do something else, but panic.
+ panic(err)
+ }
+ // Wait for cancellation to complete.
+ fd.pd.waitCanceled(int(o.mode))
+ if o.errno != 0 {
+ err = syscall.Errno(o.errno)
+ if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled
+ err = netpollErr
+ }
+ return 0, err
+ }
+ // We issued a cancellation request. But, it seems, IO operation succeeded
+ // before the cancellation request run. We need to treat the IO operation as
+ // succeeded (the bytes are actually sent/recv from network).
+ return int(o.qty), nil
+}
+
+// FD is a file descriptor. The net and os packages embed this type in
+// a larger type representing a network connection or OS file.
+type FD struct {
+ // Lock sysfd and serialize access to Read and Write methods.
+ fdmu fdMutex
+
+ // System file descriptor. Immutable until Close.
+ Sysfd syscall.Handle
+
+ // Read operation.
+ rop operation
+ // Write operation.
+ wop operation
+
+ // I/O poller.
+ pd pollDesc
+
+ // Used to implement pread/pwrite.
+ l sync.Mutex
+
+ // For console I/O.
+ lastbits []byte // first few bytes of the last incomplete rune in last write
+ readuint16 []uint16 // buffer to hold uint16s obtained with ReadConsole
+ readbyte []byte // buffer to hold decoding of readuint16 from utf16 to utf8
+ readbyteOffset int // readbyte[readOffset:] is yet to be consumed with file.Read
+
+ // Semaphore signaled when file is closed.
+ csema uint32
+
+ skipSyncNotif bool
+
+ // Whether this is a streaming descriptor, as opposed to a
+ // packet-based descriptor like a UDP socket.
+ IsStream bool
+
+ // Whether a zero byte read indicates EOF. This is false for a
+ // message based socket connection.
+ ZeroReadIsEOF bool
+
+ // Whether this is a file rather than a network socket.
+ isFile bool
+
+ // The kind of this file.
+ kind fileKind
+}
+
+// fileKind describes the kind of file.
+type fileKind byte
+
+const (
+ kindNet fileKind = iota
+ kindFile
+ kindConsole
+ kindPipe
+)
+
+// logInitFD is set by tests to enable file descriptor initialization logging.
+var logInitFD func(net string, fd *FD, err error)
+
+// Init initializes the FD. The Sysfd field should already be set.
+// This can be called multiple times on a single FD.
+// The net argument is a network name from the net package (e.g., "tcp"),
+// or "file" or "console" or "dir".
+// Set pollable to true if fd should be managed by runtime netpoll.
+func (fd *FD) Init(net string, pollable bool) (string, error) {
+ if initErr != nil {
+ return "", initErr
+ }
+
+ switch net {
+ case "file", "dir":
+ fd.kind = kindFile
+ case "console":
+ fd.kind = kindConsole
+ case "pipe":
+ fd.kind = kindPipe
+ case "tcp", "tcp4", "tcp6",
+ "udp", "udp4", "udp6",
+ "ip", "ip4", "ip6",
+ "unix", "unixgram", "unixpacket":
+ fd.kind = kindNet
+ default:
+ return "", errors.New("internal error: unknown network type " + net)
+ }
+ fd.isFile = fd.kind != kindNet
+
+ var err error
+ if pollable {
+ // Only call init for a network socket.
+ // This means that we don't add files to the runtime poller.
+ // Adding files to the runtime poller can confuse matters
+ // if the user is doing their own overlapped I/O.
+ // See issue #21172.
+ //
+ // In general the code below avoids calling the execIO
+ // function for non-network sockets. If some method does
+ // somehow call execIO, then execIO, and therefore the
+ // calling method, will return an error, because
+ // fd.pd.runtimeCtx will be 0.
+ err = fd.pd.init(fd)
+ }
+ if logInitFD != nil {
+ logInitFD(net, fd, err)
+ }
+ if err != nil {
+ return "", err
+ }
+ if pollable && useSetFileCompletionNotificationModes {
+ // We do not use events, so we can skip them always.
+ flags := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE)
+ switch net {
+ case "tcp", "tcp4", "tcp6",
+ "udp", "udp4", "udp6":
+ flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
+ }
+ err := syscall.SetFileCompletionNotificationModes(fd.Sysfd, flags)
+ if err == nil && flags&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 {
+ fd.skipSyncNotif = true
+ }
+ }
+ // Disable SIO_UDP_CONNRESET behavior.
+ // http://support.microsoft.com/kb/263823
+ switch net {
+ case "udp", "udp4", "udp6":
+ ret := uint32(0)
+ flag := uint32(0)
+ size := uint32(unsafe.Sizeof(flag))
+ err := syscall.WSAIoctl(fd.Sysfd, syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0)
+ if err != nil {
+ return "wsaioctl", err
+ }
+ }
+ fd.rop.mode = 'r'
+ fd.wop.mode = 'w'
+ fd.rop.fd = fd
+ fd.wop.fd = fd
+ fd.rop.runtimeCtx = fd.pd.runtimeCtx
+ fd.wop.runtimeCtx = fd.pd.runtimeCtx
+ return "", nil
+}
+
+func (fd *FD) destroy() error {
+ if fd.Sysfd == syscall.InvalidHandle {
+ return syscall.EINVAL
+ }
+ // Poller may want to unregister fd in readiness notification mechanism,
+ // so this must be executed before fd.CloseFunc.
+ fd.pd.close()
+ var err error
+ switch fd.kind {
+ case kindNet:
+ // The net package uses the CloseFunc variable for testing.
+ err = CloseFunc(fd.Sysfd)
+ default:
+ err = syscall.CloseHandle(fd.Sysfd)
+ }
+ fd.Sysfd = syscall.InvalidHandle
+ runtime_Semrelease(&fd.csema)
+ return err
+}
+
+// Close closes the FD. The underlying file descriptor is closed by
+// the destroy method when there are no remaining references.
+func (fd *FD) Close() error {
+ if !fd.fdmu.increfAndClose() {
+ return errClosing(fd.isFile)
+ }
+ if fd.kind == kindPipe {
+ syscall.CancelIoEx(fd.Sysfd, nil)
+ }
+ // unblock pending reader and writer
+ fd.pd.evict()
+ err := fd.decref()
+ // Wait until the descriptor is closed. If this was the only
+ // reference, it is already closed.
+ runtime_Semacquire(&fd.csema)
+ return err
+}
+
+// Windows ReadFile and WSARecv use DWORD (uint32) parameter to pass buffer length.
+// This prevents us reading blocks larger than 4GB.
+// See golang.org/issue/26923.
+const maxRW = 1 << 30 // 1GB is large enough and keeps subsequent reads aligned
+
+// Read implements io.Reader.
+func (fd *FD) Read(buf []byte) (int, error) {
+ if err := fd.readLock(); err != nil {
+ return 0, err
+ }
+ defer fd.readUnlock()
+
+ if len(buf) > maxRW {
+ buf = buf[:maxRW]
+ }
+
+ var n int
+ var err error
+ if fd.isFile {
+ fd.l.Lock()
+ defer fd.l.Unlock()
+ switch fd.kind {
+ case kindConsole:
+ n, err = fd.readConsole(buf)
+ default:
+ n, err = syscall.Read(fd.Sysfd, buf)
+ if fd.kind == kindPipe && err == syscall.ERROR_OPERATION_ABORTED {
+ // Close uses CancelIoEx to interrupt concurrent I/O for pipes.
+ // If the fd is a pipe and the Read was interrupted by CancelIoEx,
+ // we assume it is interrupted by Close.
+ err = ErrFileClosing
+ }
+ }
+ if err != nil {
+ n = 0
+ }
+ } else {
+ o := &fd.rop
+ o.InitBuf(buf)
+ n, err = execIO(o, func(o *operation) error {
+ return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
+ })
+ if race.Enabled {
+ race.Acquire(unsafe.Pointer(&ioSync))
+ }
+ }
+ if len(buf) != 0 {
+ err = fd.eofError(n, err)
+ }
+ return n, err
+}
+
+var ReadConsole = syscall.ReadConsole // changed for testing
+
+// readConsole reads utf16 characters from console File,
+// encodes them into utf8 and stores them in buffer b.
+// It returns the number of utf8 bytes read and an error, if any.
+func (fd *FD) readConsole(b []byte) (int, error) {
+ if len(b) == 0 {
+ return 0, nil
+ }
+
+ if fd.readuint16 == nil {
+ // Note: syscall.ReadConsole fails for very large buffers.
+ // The limit is somewhere around (but not exactly) 16384.
+ // Stay well below.
+ fd.readuint16 = make([]uint16, 0, 10000)
+ fd.readbyte = make([]byte, 0, 4*cap(fd.readuint16))
+ }
+
+ for fd.readbyteOffset >= len(fd.readbyte) {
+ n := cap(fd.readuint16) - len(fd.readuint16)
+ if n > len(b) {
+ n = len(b)
+ }
+ var nw uint32
+ err := ReadConsole(fd.Sysfd, &fd.readuint16[:len(fd.readuint16)+1][len(fd.readuint16)], uint32(n), &nw, nil)
+ if err != nil {
+ return 0, err
+ }
+ uint16s := fd.readuint16[:len(fd.readuint16)+int(nw)]
+ fd.readuint16 = fd.readuint16[:0]
+ buf := fd.readbyte[:0]
+ for i := 0; i < len(uint16s); i++ {
+ r := rune(uint16s[i])
+ if utf16.IsSurrogate(r) {
+ if i+1 == len(uint16s) {
+ if nw > 0 {
+ // Save half surrogate pair for next time.
+ fd.readuint16 = fd.readuint16[:1]
+ fd.readuint16[0] = uint16(r)
+ break
+ }
+ r = utf8.RuneError
+ } else {
+ r = utf16.DecodeRune(r, rune(uint16s[i+1]))
+ if r != utf8.RuneError {
+ i++
+ }
+ }
+ }
+ buf = utf8.AppendRune(buf, r)
+ }
+ fd.readbyte = buf
+ fd.readbyteOffset = 0
+ if nw == 0 {
+ break
+ }
+ }
+
+ src := fd.readbyte[fd.readbyteOffset:]
+ var i int
+ for i = 0; i < len(src) && i < len(b); i++ {
+ x := src[i]
+ if x == 0x1A { // Ctrl-Z
+ if i == 0 {
+ fd.readbyteOffset++
+ }
+ break
+ }
+ b[i] = x
+ }
+ fd.readbyteOffset += i
+ return i, nil
+}
+
+// Pread emulates the Unix pread system call.
+func (fd *FD) Pread(b []byte, off int64) (int, error) {
+ if fd.kind == kindPipe {
+ // Pread does not work with pipes
+ return 0, syscall.ESPIPE
+ }
+ // Call incref, not readLock, because since pread specifies the
+ // offset it is independent from other reads.
+ if err := fd.incref(); err != nil {
+ return 0, err
+ }
+ defer fd.decref()
+
+ if len(b) > maxRW {
+ b = b[:maxRW]
+ }
+
+ fd.l.Lock()
+ defer fd.l.Unlock()
+ curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent)
+ if e != nil {
+ return 0, e
+ }
+ defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart)
+ o := syscall.Overlapped{
+ OffsetHigh: uint32(off >> 32),
+ Offset: uint32(off),
+ }
+ var done uint32
+ e = syscall.ReadFile(fd.Sysfd, b, &done, &o)
+ if e != nil {
+ done = 0
+ if e == syscall.ERROR_HANDLE_EOF {
+ e = io.EOF
+ }
+ }
+ if len(b) != 0 {
+ e = fd.eofError(int(done), e)
+ }
+ return int(done), e
+}
+
+// ReadFrom wraps the recvfrom network call.
+func (fd *FD) ReadFrom(buf []byte) (int, syscall.Sockaddr, error) {
+ if len(buf) == 0 {
+ return 0, nil, nil
+ }
+ if len(buf) > maxRW {
+ buf = buf[:maxRW]
+ }
+ if err := fd.readLock(); err != nil {
+ return 0, nil, err
+ }
+ defer fd.readUnlock()
+ o := &fd.rop
+ o.InitBuf(buf)
+ n, err := execIO(o, func(o *operation) error {
+ if o.rsa == nil {
+ o.rsa = new(syscall.RawSockaddrAny)
+ }
+ o.rsan = int32(unsafe.Sizeof(*o.rsa))
+ return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
+ })
+ err = fd.eofError(n, err)
+ if err != nil {
+ return n, nil, err
+ }
+ sa, _ := o.rsa.Sockaddr()
+ return n, sa, nil
+}
+
+// ReadFromInet4 wraps the recvfrom network call for IPv4.
+func (fd *FD) ReadFromInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) {
+ if len(buf) == 0 {
+ return 0, nil
+ }
+ if len(buf) > maxRW {
+ buf = buf[:maxRW]
+ }
+ if err := fd.readLock(); err != nil {
+ return 0, err
+ }
+ defer fd.readUnlock()
+ o := &fd.rop
+ o.InitBuf(buf)
+ n, err := execIO(o, func(o *operation) error {
+ if o.rsa == nil {
+ o.rsa = new(syscall.RawSockaddrAny)
+ }
+ o.rsan = int32(unsafe.Sizeof(*o.rsa))
+ return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
+ })
+ err = fd.eofError(n, err)
+ if err != nil {
+ return n, err
+ }
+ rawToSockaddrInet4(o.rsa, sa4)
+ return n, err
+}
+
+// ReadFromInet6 wraps the recvfrom network call for IPv6.
+func (fd *FD) ReadFromInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) {
+ if len(buf) == 0 {
+ return 0, nil
+ }
+ if len(buf) > maxRW {
+ buf = buf[:maxRW]
+ }
+ if err := fd.readLock(); err != nil {
+ return 0, err
+ }
+ defer fd.readUnlock()
+ o := &fd.rop
+ o.InitBuf(buf)
+ n, err := execIO(o, func(o *operation) error {
+ if o.rsa == nil {
+ o.rsa = new(syscall.RawSockaddrAny)
+ }
+ o.rsan = int32(unsafe.Sizeof(*o.rsa))
+ return syscall.WSARecvFrom(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
+ })
+ err = fd.eofError(n, err)
+ if err != nil {
+ return n, err
+ }
+ rawToSockaddrInet6(o.rsa, sa6)
+ return n, err
+}
+
+// Write implements io.Writer.
+func (fd *FD) Write(buf []byte) (int, error) {
+ if err := fd.writeLock(); err != nil {
+ return 0, err
+ }
+ defer fd.writeUnlock()
+ if fd.isFile {
+ fd.l.Lock()
+ defer fd.l.Unlock()
+ }
+
+ ntotal := 0
+ for len(buf) > 0 {
+ b := buf
+ if len(b) > maxRW {
+ b = b[:maxRW]
+ }
+ var n int
+ var err error
+ if fd.isFile {
+ switch fd.kind {
+ case kindConsole:
+ n, err = fd.writeConsole(b)
+ default:
+ n, err = syscall.Write(fd.Sysfd, b)
+ if fd.kind == kindPipe && err == syscall.ERROR_OPERATION_ABORTED {
+ // Close uses CancelIoEx to interrupt concurrent I/O for pipes.
+ // If the fd is a pipe and the Write was interrupted by CancelIoEx,
+ // we assume it is interrupted by Close.
+ err = ErrFileClosing
+ }
+ }
+ if err != nil {
+ n = 0
+ }
+ } else {
+ if race.Enabled {
+ race.ReleaseMerge(unsafe.Pointer(&ioSync))
+ }
+ o := &fd.wop
+ o.InitBuf(b)
+ n, err = execIO(o, func(o *operation) error {
+ return syscall.WSASend(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil)
+ })
+ }
+ ntotal += n
+ if err != nil {
+ return ntotal, err
+ }
+ buf = buf[n:]
+ }
+ return ntotal, nil
+}
+
+// writeConsole writes len(b) bytes to the console File.
+// It returns the number of bytes written and an error, if any.
+func (fd *FD) writeConsole(b []byte) (int, error) {
+ n := len(b)
+ runes := make([]rune, 0, 256)
+ if len(fd.lastbits) > 0 {
+ b = append(fd.lastbits, b...)
+ fd.lastbits = nil
+
+ }
+ for len(b) >= utf8.UTFMax || utf8.FullRune(b) {
+ r, l := utf8.DecodeRune(b)
+ runes = append(runes, r)
+ b = b[l:]
+ }
+ if len(b) > 0 {
+ fd.lastbits = make([]byte, len(b))
+ copy(fd.lastbits, b)
+ }
+ // syscall.WriteConsole seems to fail, if given large buffer.
+ // So limit the buffer to 16000 characters. This number was
+ // discovered by experimenting with syscall.WriteConsole.
+ const maxWrite = 16000
+ for len(runes) > 0 {
+ m := len(runes)
+ if m > maxWrite {
+ m = maxWrite
+ }
+ chunk := runes[:m]
+ runes = runes[m:]
+ uint16s := utf16.Encode(chunk)
+ for len(uint16s) > 0 {
+ var written uint32
+ err := syscall.WriteConsole(fd.Sysfd, &uint16s[0], uint32(len(uint16s)), &written, nil)
+ if err != nil {
+ return 0, err
+ }
+ uint16s = uint16s[written:]
+ }
+ }
+ return n, nil
+}
+
+// Pwrite emulates the Unix pwrite system call.
+func (fd *FD) Pwrite(buf []byte, off int64) (int, error) {
+ if fd.kind == kindPipe {
+ // Pwrite does not work with pipes
+ return 0, syscall.ESPIPE
+ }
+ // Call incref, not writeLock, because since pwrite specifies the
+ // offset it is independent from other writes.
+ if err := fd.incref(); err != nil {
+ return 0, err
+ }
+ defer fd.decref()
+
+ fd.l.Lock()
+ defer fd.l.Unlock()
+ curoffset, e := syscall.Seek(fd.Sysfd, 0, io.SeekCurrent)
+ if e != nil {
+ return 0, e
+ }
+ defer syscall.Seek(fd.Sysfd, curoffset, io.SeekStart)
+
+ ntotal := 0
+ for len(buf) > 0 {
+ b := buf
+ if len(b) > maxRW {
+ b = b[:maxRW]
+ }
+ var n uint32
+ o := syscall.Overlapped{
+ OffsetHigh: uint32(off >> 32),
+ Offset: uint32(off),
+ }
+ e = syscall.WriteFile(fd.Sysfd, b, &n, &o)
+ ntotal += int(n)
+ if e != nil {
+ return ntotal, e
+ }
+ buf = buf[n:]
+ off += int64(n)
+ }
+ return ntotal, nil
+}
+
+// Writev emulates the Unix writev system call.
+func (fd *FD) Writev(buf *[][]byte) (int64, error) {
+ if len(*buf) == 0 {
+ return 0, nil
+ }
+ if err := fd.writeLock(); err != nil {
+ return 0, err
+ }
+ defer fd.writeUnlock()
+ if race.Enabled {
+ race.ReleaseMerge(unsafe.Pointer(&ioSync))
+ }
+ o := &fd.wop
+ o.InitBufs(buf)
+ n, err := execIO(o, func(o *operation) error {
+ return syscall.WSASend(o.fd.Sysfd, &o.bufs[0], uint32(len(o.bufs)), &o.qty, 0, &o.o, nil)
+ })
+ o.ClearBufs()
+ TestHookDidWritev(n)
+ consume(buf, int64(n))
+ return int64(n), err
+}
+
+// WriteTo wraps the sendto network call.
+func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) {
+ if err := fd.writeLock(); err != nil {
+ return 0, err
+ }
+ defer fd.writeUnlock()
+
+ if len(buf) == 0 {
+ // handle zero-byte payload
+ o := &fd.wop
+ o.InitBuf(buf)
+ o.sa = sa
+ n, err := execIO(o, func(o *operation) error {
+ return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
+ })
+ return n, err
+ }
+
+ ntotal := 0
+ for len(buf) > 0 {
+ b := buf
+ if len(b) > maxRW {
+ b = b[:maxRW]
+ }
+ o := &fd.wop
+ o.InitBuf(b)
+ o.sa = sa
+ n, err := execIO(o, func(o *operation) error {
+ return syscall.WSASendto(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
+ })
+ ntotal += int(n)
+ if err != nil {
+ return ntotal, err
+ }
+ buf = buf[n:]
+ }
+ return ntotal, nil
+}
+
+// WriteToInet4 is WriteTo, specialized for syscall.SockaddrInet4.
+func (fd *FD) WriteToInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error) {
+ if err := fd.writeLock(); err != nil {
+ return 0, err
+ }
+ defer fd.writeUnlock()
+
+ if len(buf) == 0 {
+ // handle zero-byte payload
+ o := &fd.wop
+ o.InitBuf(buf)
+ n, err := execIO(o, func(o *operation) error {
+ return windows.WSASendtoInet4(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa4, &o.o, nil)
+ })
+ return n, err
+ }
+
+ ntotal := 0
+ for len(buf) > 0 {
+ b := buf
+ if len(b) > maxRW {
+ b = b[:maxRW]
+ }
+ o := &fd.wop
+ o.InitBuf(b)
+ n, err := execIO(o, func(o *operation) error {
+ return windows.WSASendtoInet4(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa4, &o.o, nil)
+ })
+ ntotal += int(n)
+ if err != nil {
+ return ntotal, err
+ }
+ buf = buf[n:]
+ }
+ return ntotal, nil
+}
+
+// WriteToInet6 is WriteTo, specialized for syscall.SockaddrInet6.
+func (fd *FD) WriteToInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error) {
+ if err := fd.writeLock(); err != nil {
+ return 0, err
+ }
+ defer fd.writeUnlock()
+
+ if len(buf) == 0 {
+ // handle zero-byte payload
+ o := &fd.wop
+ o.InitBuf(buf)
+ n, err := execIO(o, func(o *operation) error {
+ return windows.WSASendtoInet6(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa6, &o.o, nil)
+ })
+ return n, err
+ }
+
+ ntotal := 0
+ for len(buf) > 0 {
+ b := buf
+ if len(b) > maxRW {
+ b = b[:maxRW]
+ }
+ o := &fd.wop
+ o.InitBuf(b)
+ n, err := execIO(o, func(o *operation) error {
+ return windows.WSASendtoInet6(o.fd.Sysfd, &o.buf, 1, &o.qty, 0, sa6, &o.o, nil)
+ })
+ ntotal += int(n)
+ if err != nil {
+ return ntotal, err
+ }
+ buf = buf[n:]
+ }
+ return ntotal, nil
+}
+
+// Call ConnectEx. This doesn't need any locking, since it is only
+// called when the descriptor is first created. This is here rather
+// than in the net package so that it can use fd.wop.
+func (fd *FD) ConnectEx(ra syscall.Sockaddr) error {
+ o := &fd.wop
+ o.sa = ra
+ _, err := execIO(o, func(o *operation) error {
+ return ConnectExFunc(o.fd.Sysfd, o.sa, nil, 0, nil, &o.o)
+ })
+ return err
+}
+
+func (fd *FD) acceptOne(s syscall.Handle, rawsa []syscall.RawSockaddrAny, o *operation) (string, error) {
+ // Submit accept request.
+ o.handle = s
+ o.rsan = int32(unsafe.Sizeof(rawsa[0]))
+ _, err := execIO(o, func(o *operation) error {
+ return AcceptFunc(o.fd.Sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
+ })
+ if err != nil {
+ CloseFunc(s)
+ return "acceptex", err
+ }
+
+ // Inherit properties of the listening socket.
+ err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.Sysfd)), int32(unsafe.Sizeof(fd.Sysfd)))
+ if err != nil {
+ CloseFunc(s)
+ return "setsockopt", err
+ }
+
+ return "", nil
+}
+
+// Accept handles accepting a socket. The sysSocket parameter is used
+// to allocate the net socket.
+func (fd *FD) Accept(sysSocket func() (syscall.Handle, error)) (syscall.Handle, []syscall.RawSockaddrAny, uint32, string, error) {
+ if err := fd.readLock(); err != nil {
+ return syscall.InvalidHandle, nil, 0, "", err
+ }
+ defer fd.readUnlock()
+
+ o := &fd.rop
+ var rawsa [2]syscall.RawSockaddrAny
+ for {
+ s, err := sysSocket()
+ if err != nil {
+ return syscall.InvalidHandle, nil, 0, "", err
+ }
+
+ errcall, err := fd.acceptOne(s, rawsa[:], o)
+ if err == nil {
+ return s, rawsa[:], uint32(o.rsan), "", nil
+ }
+
+ // Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is
+ // returned here. These happen if connection reset is received
+ // before AcceptEx could complete. These errors relate to new
+ // connection, not to AcceptEx, so ignore broken connection and
+ // try AcceptEx again for more connections.
+ errno, ok := err.(syscall.Errno)
+ if !ok {
+ return syscall.InvalidHandle, nil, 0, errcall, err
+ }
+ switch errno {
+ case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET:
+ // ignore these and try again
+ default:
+ return syscall.InvalidHandle, nil, 0, errcall, err
+ }
+ }
+}
+
+// Seek wraps syscall.Seek.
+func (fd *FD) Seek(offset int64, whence int) (int64, error) {
+ if fd.kind == kindPipe {
+ return 0, syscall.ESPIPE
+ }
+ if err := fd.incref(); err != nil {
+ return 0, err
+ }
+ defer fd.decref()
+
+ fd.l.Lock()
+ defer fd.l.Unlock()
+
+ return syscall.Seek(fd.Sysfd, offset, whence)
+}
+
+// Fchmod updates syscall.ByHandleFileInformation.Fileattributes when needed.
+func (fd *FD) Fchmod(mode uint32) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+
+ var d syscall.ByHandleFileInformation
+ if err := syscall.GetFileInformationByHandle(fd.Sysfd, &d); err != nil {
+ return err
+ }
+ attrs := d.FileAttributes
+ if mode&syscall.S_IWRITE != 0 {
+ attrs &^= syscall.FILE_ATTRIBUTE_READONLY
+ } else {
+ attrs |= syscall.FILE_ATTRIBUTE_READONLY
+ }
+ if attrs == d.FileAttributes {
+ return nil
+ }
+
+ var du windows.FILE_BASIC_INFO
+ du.FileAttributes = attrs
+ l := uint32(unsafe.Sizeof(d))
+ return windows.SetFileInformationByHandle(fd.Sysfd, windows.FileBasicInfo, uintptr(unsafe.Pointer(&du)), l)
+}
+
+// Fchdir wraps syscall.Fchdir.
+func (fd *FD) Fchdir() error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return syscall.Fchdir(fd.Sysfd)
+}
+
+// GetFileType wraps syscall.GetFileType.
+func (fd *FD) GetFileType() (uint32, error) {
+ if err := fd.incref(); err != nil {
+ return 0, err
+ }
+ defer fd.decref()
+ return syscall.GetFileType(fd.Sysfd)
+}
+
+// GetFileInformationByHandle wraps GetFileInformationByHandle.
+func (fd *FD) GetFileInformationByHandle(data *syscall.ByHandleFileInformation) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return syscall.GetFileInformationByHandle(fd.Sysfd, data)
+}
+
+// RawRead invokes the user-defined function f for a read operation.
+func (fd *FD) RawRead(f func(uintptr) bool) error {
+ if err := fd.readLock(); err != nil {
+ return err
+ }
+ defer fd.readUnlock()
+ for {
+ if f(uintptr(fd.Sysfd)) {
+ return nil
+ }
+
+ // Use a zero-byte read as a way to get notified when this
+ // socket is readable. h/t https://stackoverflow.com/a/42019668/332798
+ o := &fd.rop
+ o.InitBuf(nil)
+ if !fd.IsStream {
+ o.flags |= windows.MSG_PEEK
+ }
+ _, err := execIO(o, func(o *operation) error {
+ return syscall.WSARecv(o.fd.Sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
+ })
+ if err == windows.WSAEMSGSIZE {
+ // expected with a 0-byte peek, ignore.
+ } else if err != nil {
+ return err
+ }
+ }
+}
+
+// RawWrite invokes the user-defined function f for a write operation.
+func (fd *FD) RawWrite(f func(uintptr) bool) error {
+ if err := fd.writeLock(); err != nil {
+ return err
+ }
+ defer fd.writeUnlock()
+
+ if f(uintptr(fd.Sysfd)) {
+ return nil
+ }
+
+ // TODO(tmm1): find a way to detect socket writability
+ return syscall.EWINDOWS
+}
+
+func sockaddrInet4ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) int32 {
+ *rsa = syscall.RawSockaddrAny{}
+ raw := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
+ raw.Family = syscall.AF_INET
+ p := (*[2]byte)(unsafe.Pointer(&raw.Port))
+ p[0] = byte(sa.Port >> 8)
+ p[1] = byte(sa.Port)
+ raw.Addr = sa.Addr
+ return int32(unsafe.Sizeof(*raw))
+}
+
+func sockaddrInet6ToRaw(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) int32 {
+ *rsa = syscall.RawSockaddrAny{}
+ raw := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
+ raw.Family = syscall.AF_INET6
+ p := (*[2]byte)(unsafe.Pointer(&raw.Port))
+ p[0] = byte(sa.Port >> 8)
+ p[1] = byte(sa.Port)
+ raw.Scope_id = sa.ZoneId
+ raw.Addr = sa.Addr
+ return int32(unsafe.Sizeof(*raw))
+}
+
+func rawToSockaddrInet4(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) {
+ pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
+ p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ sa.Port = int(p[0])<<8 + int(p[1])
+ sa.Addr = pp.Addr
+}
+
+func rawToSockaddrInet6(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) {
+ pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
+ p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ sa.Port = int(p[0])<<8 + int(p[1])
+ sa.ZoneId = pp.Scope_id
+ sa.Addr = pp.Addr
+}
+
+func sockaddrToRaw(rsa *syscall.RawSockaddrAny, sa syscall.Sockaddr) (int32, error) {
+ switch sa := sa.(type) {
+ case *syscall.SockaddrInet4:
+ sz := sockaddrInet4ToRaw(rsa, sa)
+ return sz, nil
+ case *syscall.SockaddrInet6:
+ sz := sockaddrInet6ToRaw(rsa, sa)
+ return sz, nil
+ default:
+ return 0, syscall.EWINDOWS
+ }
+}
+
+// ReadMsg wraps the WSARecvMsg network call.
+func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.Sockaddr, error) {
+ if err := fd.readLock(); err != nil {
+ return 0, 0, 0, nil, err
+ }
+ defer fd.readUnlock()
+
+ if len(p) > maxRW {
+ p = p[:maxRW]
+ }
+
+ o := &fd.rop
+ o.InitMsg(p, oob)
+ if o.rsa == nil {
+ o.rsa = new(syscall.RawSockaddrAny)
+ }
+ o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
+ o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
+ o.msg.Flags = uint32(flags)
+ n, err := execIO(o, func(o *operation) error {
+ return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
+ })
+ err = fd.eofError(n, err)
+ var sa syscall.Sockaddr
+ if err == nil {
+ sa, err = o.rsa.Sockaddr()
+ }
+ return n, int(o.msg.Control.Len), int(o.msg.Flags), sa, err
+}
+
+// ReadMsgInet4 is ReadMsg, but specialized to return a syscall.SockaddrInet4.
+func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) {
+ if err := fd.readLock(); err != nil {
+ return 0, 0, 0, err
+ }
+ defer fd.readUnlock()
+
+ if len(p) > maxRW {
+ p = p[:maxRW]
+ }
+
+ o := &fd.rop
+ o.InitMsg(p, oob)
+ if o.rsa == nil {
+ o.rsa = new(syscall.RawSockaddrAny)
+ }
+ o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
+ o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
+ o.msg.Flags = uint32(flags)
+ n, err := execIO(o, func(o *operation) error {
+ return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
+ })
+ err = fd.eofError(n, err)
+ if err == nil {
+ rawToSockaddrInet4(o.rsa, sa4)
+ }
+ return n, int(o.msg.Control.Len), int(o.msg.Flags), err
+}
+
+// ReadMsgInet6 is ReadMsg, but specialized to return a syscall.SockaddrInet6.
+func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) {
+ if err := fd.readLock(); err != nil {
+ return 0, 0, 0, err
+ }
+ defer fd.readUnlock()
+
+ if len(p) > maxRW {
+ p = p[:maxRW]
+ }
+
+ o := &fd.rop
+ o.InitMsg(p, oob)
+ if o.rsa == nil {
+ o.rsa = new(syscall.RawSockaddrAny)
+ }
+ o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
+ o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
+ o.msg.Flags = uint32(flags)
+ n, err := execIO(o, func(o *operation) error {
+ return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
+ })
+ err = fd.eofError(n, err)
+ if err == nil {
+ rawToSockaddrInet6(o.rsa, sa6)
+ }
+ return n, int(o.msg.Control.Len), int(o.msg.Flags), err
+}
+
+// WriteMsg wraps the WSASendMsg network call.
+func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
+ if len(p) > maxRW {
+ return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
+ }
+
+ if err := fd.writeLock(); err != nil {
+ return 0, 0, err
+ }
+ defer fd.writeUnlock()
+
+ o := &fd.wop
+ o.InitMsg(p, oob)
+ if sa != nil {
+ if o.rsa == nil {
+ o.rsa = new(syscall.RawSockaddrAny)
+ }
+ len, err := sockaddrToRaw(o.rsa, sa)
+ if err != nil {
+ return 0, 0, err
+ }
+ o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
+ o.msg.Namelen = len
+ }
+ n, err := execIO(o, func(o *operation) error {
+ return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
+ })
+ return n, int(o.msg.Control.Len), err
+}
+
+// WriteMsgInet4 is WriteMsg specialized for syscall.SockaddrInet4.
+func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (int, int, error) {
+ if len(p) > maxRW {
+ return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
+ }
+
+ if err := fd.writeLock(); err != nil {
+ return 0, 0, err
+ }
+ defer fd.writeUnlock()
+
+ o := &fd.wop
+ o.InitMsg(p, oob)
+ if o.rsa == nil {
+ o.rsa = new(syscall.RawSockaddrAny)
+ }
+ len := sockaddrInet4ToRaw(o.rsa, sa)
+ o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
+ o.msg.Namelen = len
+ n, err := execIO(o, func(o *operation) error {
+ return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
+ })
+ return n, int(o.msg.Control.Len), err
+}
+
+// WriteMsgInet6 is WriteMsg specialized for syscall.SockaddrInet6.
+func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (int, int, error) {
+ if len(p) > maxRW {
+ return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
+ }
+
+ if err := fd.writeLock(); err != nil {
+ return 0, 0, err
+ }
+ defer fd.writeUnlock()
+
+ o := &fd.wop
+ o.InitMsg(p, oob)
+ if o.rsa == nil {
+ o.rsa = new(syscall.RawSockaddrAny)
+ }
+ len := sockaddrInet6ToRaw(o.rsa, sa)
+ o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
+ o.msg.Namelen = len
+ n, err := execIO(o, func(o *operation) error {
+ return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
+ })
+ return n, int(o.msg.Control.Len), err
+}
diff --git a/contrib/go/_std_1.20/src/internal/poll/fd_writev_libc.go b/contrib/go/_std_1.21/src/internal/poll/fd_writev_libc.go
index 1b35bd9052..1b35bd9052 100644
--- a/contrib/go/_std_1.20/src/internal/poll/fd_writev_libc.go
+++ b/contrib/go/_std_1.21/src/internal/poll/fd_writev_libc.go
diff --git a/contrib/go/_std_1.20/src/internal/poll/fd_writev_unix.go b/contrib/go/_std_1.21/src/internal/poll/fd_writev_unix.go
index 005638b06f..005638b06f 100644
--- a/contrib/go/_std_1.20/src/internal/poll/fd_writev_unix.go
+++ b/contrib/go/_std_1.21/src/internal/poll/fd_writev_unix.go
diff --git a/contrib/go/_std_1.20/src/internal/poll/hook_cloexec.go b/contrib/go/_std_1.21/src/internal/poll/hook_cloexec.go
index 5b3cdcec28..5b3cdcec28 100644
--- a/contrib/go/_std_1.20/src/internal/poll/hook_cloexec.go
+++ b/contrib/go/_std_1.21/src/internal/poll/hook_cloexec.go
diff --git a/contrib/go/_std_1.21/src/internal/poll/hook_unix.go b/contrib/go/_std_1.21/src/internal/poll/hook_unix.go
new file mode 100644
index 0000000000..b3f4f9eb17
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/hook_unix.go
@@ -0,0 +1,15 @@
+// Copyright 2017 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package poll
+
+import "syscall"
+
+// CloseFunc is used to hook the close call.
+var CloseFunc func(int) error = syscall.Close
+
+// AcceptFunc is used to hook the accept call.
+var AcceptFunc func(int) (int, syscall.Sockaddr, error) = syscall.Accept
diff --git a/contrib/go/_std_1.20/src/internal/poll/hook_windows.go b/contrib/go/_std_1.21/src/internal/poll/hook_windows.go
index 0bd950ebe4..0bd950ebe4 100644
--- a/contrib/go/_std_1.20/src/internal/poll/hook_windows.go
+++ b/contrib/go/_std_1.21/src/internal/poll/hook_windows.go
diff --git a/contrib/go/_std_1.20/src/internal/poll/iovec_unix.go b/contrib/go/_std_1.21/src/internal/poll/iovec_unix.go
index 3f2833e728..3f2833e728 100644
--- a/contrib/go/_std_1.20/src/internal/poll/iovec_unix.go
+++ b/contrib/go/_std_1.21/src/internal/poll/iovec_unix.go
diff --git a/contrib/go/_std_1.20/src/internal/poll/sendfile_bsd.go b/contrib/go/_std_1.21/src/internal/poll/sendfile_bsd.go
index 89315a8c67..89315a8c67 100644
--- a/contrib/go/_std_1.20/src/internal/poll/sendfile_bsd.go
+++ b/contrib/go/_std_1.21/src/internal/poll/sendfile_bsd.go
diff --git a/contrib/go/_std_1.20/src/internal/poll/sendfile_linux.go b/contrib/go/_std_1.21/src/internal/poll/sendfile_linux.go
index cc31969a43..cc31969a43 100644
--- a/contrib/go/_std_1.20/src/internal/poll/sendfile_linux.go
+++ b/contrib/go/_std_1.21/src/internal/poll/sendfile_linux.go
diff --git a/contrib/go/_std_1.21/src/internal/poll/sendfile_windows.go b/contrib/go/_std_1.21/src/internal/poll/sendfile_windows.go
new file mode 100644
index 0000000000..8c3353bc6f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/sendfile_windows.go
@@ -0,0 +1,84 @@
+// Copyright 2011 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 poll
+
+import (
+ "io"
+ "syscall"
+)
+
+// SendFile wraps the TransmitFile call.
+func SendFile(fd *FD, src syscall.Handle, n int64) (written int64, err error) {
+ if fd.kind == kindPipe {
+ // TransmitFile does not work with pipes
+ return 0, syscall.ESPIPE
+ }
+ if ft, _ := syscall.GetFileType(src); ft == syscall.FILE_TYPE_PIPE {
+ return 0, syscall.ESPIPE
+ }
+
+ if err := fd.writeLock(); err != nil {
+ return 0, err
+ }
+ defer fd.writeUnlock()
+
+ o := &fd.wop
+ o.handle = src
+
+ // TODO(brainman): skip calling syscall.Seek if OS allows it
+ curpos, err := syscall.Seek(o.handle, 0, io.SeekCurrent)
+ if err != nil {
+ return 0, err
+ }
+
+ if n <= 0 { // We don't know the size of the file so infer it.
+ // Find the number of bytes offset from curpos until the end of the file.
+ n, err = syscall.Seek(o.handle, -curpos, io.SeekEnd)
+ if err != nil {
+ return
+ }
+ // Now seek back to the original position.
+ if _, err = syscall.Seek(o.handle, curpos, io.SeekStart); err != nil {
+ return
+ }
+ }
+
+ // TransmitFile can be invoked in one call with at most
+ // 2,147,483,646 bytes: the maximum value for a 32-bit integer minus 1.
+ // See https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-transmitfile
+ const maxChunkSizePerCall = int64(0x7fffffff - 1)
+
+ for n > 0 {
+ chunkSize := maxChunkSizePerCall
+ if chunkSize > n {
+ chunkSize = n
+ }
+
+ o.qty = uint32(chunkSize)
+ o.o.Offset = uint32(curpos)
+ o.o.OffsetHigh = uint32(curpos >> 32)
+
+ nw, err := execIO(o, func(o *operation) error {
+ return syscall.TransmitFile(o.fd.Sysfd, o.handle, o.qty, 0, &o.o, nil, syscall.TF_WRITE_BEHIND)
+ })
+ if err != nil {
+ return written, err
+ }
+
+ curpos += int64(nw)
+
+ // Some versions of Windows (Windows 10 1803) do not set
+ // file position after TransmitFile completes.
+ // So just use Seek to set file position.
+ if _, err = syscall.Seek(o.handle, curpos, io.SeekStart); err != nil {
+ return written, err
+ }
+
+ n -= int64(nw)
+ written += int64(nw)
+ }
+
+ return
+}
diff --git a/contrib/go/_std_1.21/src/internal/poll/sock_cloexec.go b/contrib/go/_std_1.21/src/internal/poll/sock_cloexec.go
new file mode 100644
index 0000000000..361c11bc57
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/sock_cloexec.go
@@ -0,0 +1,49 @@
+// Copyright 2013 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.
+
+// This file implements accept for platforms that provide a fast path for
+// setting SetNonblock and CloseOnExec.
+
+//go:build dragonfly || freebsd || (linux && !arm) || netbsd || openbsd || solaris
+
+package poll
+
+import "syscall"
+
+// Wrapper around the accept system call that marks the returned file
+// descriptor as nonblocking and close-on-exec.
+func accept(s int) (int, syscall.Sockaddr, string, error) {
+ ns, sa, err := Accept4Func(s, syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC)
+ // TODO: We can remove the fallback on Linux and *BSD,
+ // as currently supported versions all support accept4
+ // with SOCK_CLOEXEC, but Solaris does not. See issue #59359.
+ switch err {
+ case nil:
+ return ns, sa, "", nil
+ default: // errors other than the ones listed
+ return -1, sa, "accept4", err
+ case syscall.ENOSYS: // syscall missing
+ case syscall.EINVAL: // some Linux use this instead of ENOSYS
+ case syscall.EACCES: // some Linux use this instead of ENOSYS
+ case syscall.EFAULT: // some Linux use this instead of ENOSYS
+ }
+
+ // See ../syscall/exec_unix.go for description of ForkLock.
+ // It is probably okay to hold the lock across syscall.Accept
+ // because we have put fd.sysfd into non-blocking mode.
+ // However, a call to the File method will put it back into
+ // blocking mode. We can't take that risk, so no use of ForkLock here.
+ ns, sa, err = AcceptFunc(s)
+ if err == nil {
+ syscall.CloseOnExec(ns)
+ }
+ if err != nil {
+ return -1, nil, "accept", err
+ }
+ if err = syscall.SetNonblock(ns, true); err != nil {
+ CloseFunc(ns)
+ return -1, nil, "setnonblock", err
+ }
+ return ns, sa, "", nil
+}
diff --git a/contrib/go/_std_1.21/src/internal/poll/sockopt.go b/contrib/go/_std_1.21/src/internal/poll/sockopt.go
new file mode 100644
index 0000000000..a87a9e6413
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/sockopt.go
@@ -0,0 +1,45 @@
+// Copyright 2009 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.
+
+//go:build unix || windows
+
+package poll
+
+import "syscall"
+
+// SetsockoptInt wraps the setsockopt network call with an int argument.
+func (fd *FD) SetsockoptInt(level, name, arg int) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return syscall.SetsockoptInt(fd.Sysfd, level, name, arg)
+}
+
+// SetsockoptInet4Addr wraps the setsockopt network call with an IPv4 address.
+func (fd *FD) SetsockoptInet4Addr(level, name int, arg [4]byte) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return syscall.SetsockoptInet4Addr(fd.Sysfd, level, name, arg)
+}
+
+// SetsockoptLinger wraps the setsockopt network call with a Linger argument.
+func (fd *FD) SetsockoptLinger(level, name int, l *syscall.Linger) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+ return syscall.SetsockoptLinger(fd.Sysfd, level, name, l)
+}
+
+// GetsockoptInt wraps the getsockopt network call with an int argument.
+func (fd *FD) GetsockoptInt(level, name int) (int, error) {
+ if err := fd.incref(); err != nil {
+ return -1, err
+ }
+ defer fd.decref()
+ return syscall.GetsockoptInt(fd.Sysfd, level, name)
+}
diff --git a/contrib/go/_std_1.20/src/internal/poll/sockopt_linux.go b/contrib/go/_std_1.21/src/internal/poll/sockopt_linux.go
index bc79c350ac..bc79c350ac 100644
--- a/contrib/go/_std_1.20/src/internal/poll/sockopt_linux.go
+++ b/contrib/go/_std_1.21/src/internal/poll/sockopt_linux.go
diff --git a/contrib/go/_std_1.20/src/internal/poll/sockopt_unix.go b/contrib/go/_std_1.21/src/internal/poll/sockopt_unix.go
index 9cba44da9d..9cba44da9d 100644
--- a/contrib/go/_std_1.20/src/internal/poll/sockopt_unix.go
+++ b/contrib/go/_std_1.21/src/internal/poll/sockopt_unix.go
diff --git a/contrib/go/_std_1.20/src/internal/poll/sockopt_windows.go b/contrib/go/_std_1.21/src/internal/poll/sockopt_windows.go
index dd5fb70bab..dd5fb70bab 100644
--- a/contrib/go/_std_1.20/src/internal/poll/sockopt_windows.go
+++ b/contrib/go/_std_1.21/src/internal/poll/sockopt_windows.go
diff --git a/contrib/go/_std_1.20/src/internal/poll/sockoptip.go b/contrib/go/_std_1.21/src/internal/poll/sockoptip.go
index 41955e1fda..41955e1fda 100644
--- a/contrib/go/_std_1.20/src/internal/poll/sockoptip.go
+++ b/contrib/go/_std_1.21/src/internal/poll/sockoptip.go
diff --git a/contrib/go/_std_1.21/src/internal/poll/splice_linux.go b/contrib/go/_std_1.21/src/internal/poll/splice_linux.go
new file mode 100644
index 0000000000..9505c5dcfc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/splice_linux.go
@@ -0,0 +1,233 @@
+// Copyright 2018 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 poll
+
+import (
+ "internal/syscall/unix"
+ "runtime"
+ "sync"
+ "syscall"
+ "unsafe"
+)
+
+const (
+ // maxSpliceSize is the maximum amount of data Splice asks
+ // the kernel to move in a single call to splice(2).
+ // We use 1MB as Splice writes data through a pipe, and 1MB is the default maximum pipe buffer size,
+ // which is determined by /proc/sys/fs/pipe-max-size.
+ maxSpliceSize = 1 << 20
+)
+
+// Splice transfers at most remain bytes of data from src to dst, using the
+// splice system call to minimize copies of data from and to userspace.
+//
+// Splice gets a pipe buffer from the pool or creates a new one if needed, to serve as a buffer for the data transfer.
+// src and dst must both be stream-oriented sockets.
+//
+// If err != nil, sc is the system call which caused the error.
+func Splice(dst, src *FD, remain int64) (written int64, handled bool, sc string, err error) {
+ p, sc, err := getPipe()
+ if err != nil {
+ return 0, false, sc, err
+ }
+ defer putPipe(p)
+ var inPipe, n int
+ for err == nil && remain > 0 {
+ max := maxSpliceSize
+ if int64(max) > remain {
+ max = int(remain)
+ }
+ inPipe, err = spliceDrain(p.wfd, src, max)
+ // The operation is considered handled if splice returns no
+ // error, or an error other than EINVAL. An EINVAL means the
+ // kernel does not support splice for the socket type of src.
+ // The failed syscall does not consume any data so it is safe
+ // to fall back to a generic copy.
+ //
+ // spliceDrain should never return EAGAIN, so if err != nil,
+ // Splice cannot continue.
+ //
+ // If inPipe == 0 && err == nil, src is at EOF, and the
+ // transfer is complete.
+ handled = handled || (err != syscall.EINVAL)
+ if err != nil || inPipe == 0 {
+ break
+ }
+ p.data += inPipe
+
+ n, err = splicePump(dst, p.rfd, inPipe)
+ if n > 0 {
+ written += int64(n)
+ remain -= int64(n)
+ p.data -= n
+ }
+ }
+ if err != nil {
+ return written, handled, "splice", err
+ }
+ return written, true, "", nil
+}
+
+// spliceDrain moves data from a socket to a pipe.
+//
+// Invariant: when entering spliceDrain, the pipe is empty. It is either in its
+// initial state, or splicePump has emptied it previously.
+//
+// Given this, spliceDrain can reasonably assume that the pipe is ready for
+// writing, so if splice returns EAGAIN, it must be because the socket is not
+// ready for reading.
+//
+// If spliceDrain returns (0, nil), src is at EOF.
+func spliceDrain(pipefd int, sock *FD, max int) (int, error) {
+ if err := sock.readLock(); err != nil {
+ return 0, err
+ }
+ defer sock.readUnlock()
+ if err := sock.pd.prepareRead(sock.isFile); err != nil {
+ return 0, err
+ }
+ for {
+ n, err := splice(pipefd, sock.Sysfd, max, 0)
+ if err == syscall.EINTR {
+ continue
+ }
+ if err != syscall.EAGAIN {
+ return n, err
+ }
+ if sock.pd.pollable() {
+ if err := sock.pd.waitRead(sock.isFile); err != nil {
+ return n, err
+ }
+ }
+ }
+}
+
+// splicePump moves all the buffered data from a pipe to a socket.
+//
+// Invariant: when entering splicePump, there are exactly inPipe
+// bytes of data in the pipe, from a previous call to spliceDrain.
+//
+// By analogy to the condition from spliceDrain, splicePump
+// only needs to poll the socket for readiness, if splice returns
+// EAGAIN.
+//
+// If splicePump cannot move all the data in a single call to
+// splice(2), it loops over the buffered data until it has written
+// all of it to the socket. This behavior is similar to the Write
+// step of an io.Copy in userspace.
+func splicePump(sock *FD, pipefd int, inPipe int) (int, error) {
+ if err := sock.writeLock(); err != nil {
+ return 0, err
+ }
+ defer sock.writeUnlock()
+ if err := sock.pd.prepareWrite(sock.isFile); err != nil {
+ return 0, err
+ }
+ written := 0
+ for inPipe > 0 {
+ n, err := splice(sock.Sysfd, pipefd, inPipe, 0)
+ // Here, the condition n == 0 && err == nil should never be
+ // observed, since Splice controls the write side of the pipe.
+ if n > 0 {
+ inPipe -= n
+ written += n
+ continue
+ }
+ if err != syscall.EAGAIN {
+ return written, err
+ }
+ if sock.pd.pollable() {
+ if err := sock.pd.waitWrite(sock.isFile); err != nil {
+ return written, err
+ }
+ }
+ }
+ return written, nil
+}
+
+// splice wraps the splice system call. Since the current implementation
+// only uses splice on sockets and pipes, the offset arguments are unused.
+// splice returns int instead of int64, because callers never ask it to
+// move more data in a single call than can fit in an int32.
+func splice(out int, in int, max int, flags int) (int, error) {
+ n, err := syscall.Splice(in, nil, out, nil, max, flags)
+ return int(n), err
+}
+
+type splicePipeFields struct {
+ rfd int
+ wfd int
+ data int
+}
+
+type splicePipe struct {
+ splicePipeFields
+
+ // We want to use a finalizer, so ensure that the size is
+ // large enough to not use the tiny allocator.
+ _ [24 - unsafe.Sizeof(splicePipeFields{})%24]byte
+}
+
+// splicePipePool caches pipes to avoid high-frequency construction and destruction of pipe buffers.
+// The garbage collector will free all pipes in the sync.Pool periodically, thus we need to set up
+// a finalizer for each pipe to close its file descriptors before the actual GC.
+var splicePipePool = sync.Pool{New: newPoolPipe}
+
+func newPoolPipe() any {
+ // Discard the error which occurred during the creation of pipe buffer,
+ // redirecting the data transmission to the conventional way utilizing read() + write() as a fallback.
+ p := newPipe()
+ if p == nil {
+ return nil
+ }
+ runtime.SetFinalizer(p, destroyPipe)
+ return p
+}
+
+// getPipe tries to acquire a pipe buffer from the pool or create a new one with newPipe() if it gets nil from the cache.
+//
+// Note that it may fail to create a new pipe buffer by newPipe(), in which case getPipe() will return a generic error
+// and system call name splice in a string as the indication.
+func getPipe() (*splicePipe, string, error) {
+ v := splicePipePool.Get()
+ if v == nil {
+ return nil, "splice", syscall.EINVAL
+ }
+ return v.(*splicePipe), "", nil
+}
+
+func putPipe(p *splicePipe) {
+ // If there is still data left in the pipe,
+ // then close and discard it instead of putting it back into the pool.
+ if p.data != 0 {
+ runtime.SetFinalizer(p, nil)
+ destroyPipe(p)
+ return
+ }
+ splicePipePool.Put(p)
+}
+
+// newPipe sets up a pipe for a splice operation.
+func newPipe() *splicePipe {
+ var fds [2]int
+ if err := syscall.Pipe2(fds[:], syscall.O_CLOEXEC|syscall.O_NONBLOCK); err != nil {
+ return nil
+ }
+
+ // Splice will loop writing maxSpliceSize bytes from the source to the pipe,
+ // and then write those bytes from the pipe to the destination.
+ // Set the pipe buffer size to maxSpliceSize to optimize that.
+ // Ignore errors here, as a smaller buffer size will work,
+ // although it will require more system calls.
+ unix.Fcntl(fds[0], syscall.F_SETPIPE_SZ, maxSpliceSize)
+
+ return &splicePipe{splicePipeFields: splicePipeFields{rfd: fds[0], wfd: fds[1]}}
+}
+
+// destroyPipe destroys a pipe.
+func destroyPipe(p *splicePipe) {
+ CloseFunc(p.rfd)
+ CloseFunc(p.wfd)
+}
diff --git a/contrib/go/_std_1.21/src/internal/poll/sys_cloexec.go b/contrib/go/_std_1.21/src/internal/poll/sys_cloexec.go
new file mode 100644
index 0000000000..2c5da7d3fe
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/sys_cloexec.go
@@ -0,0 +1,36 @@
+// Copyright 2013 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.
+
+// This file implements accept for platforms that do not provide a fast path for
+// setting SetNonblock and CloseOnExec.
+
+//go:build aix || darwin || (js && wasm) || wasip1
+
+package poll
+
+import (
+ "syscall"
+)
+
+// Wrapper around the accept system call that marks the returned file
+// descriptor as nonblocking and close-on-exec.
+func accept(s int) (int, syscall.Sockaddr, string, error) {
+ // See ../syscall/exec_unix.go for description of ForkLock.
+ // It is probably okay to hold the lock across syscall.Accept
+ // because we have put fd.sysfd into non-blocking mode.
+ // However, a call to the File method will put it back into
+ // blocking mode. We can't take that risk, so no use of ForkLock here.
+ ns, sa, err := AcceptFunc(s)
+ if err == nil {
+ syscall.CloseOnExec(ns)
+ }
+ if err != nil {
+ return -1, nil, "accept", err
+ }
+ if err = syscall.SetNonblock(ns, true); err != nil {
+ CloseFunc(ns)
+ return -1, nil, "setnonblock", err
+ }
+ return ns, sa, "", nil
+}
diff --git a/contrib/go/_std_1.20/src/internal/poll/writev.go b/contrib/go/_std_1.21/src/internal/poll/writev.go
index 75c8b642b5..75c8b642b5 100644
--- a/contrib/go/_std_1.20/src/internal/poll/writev.go
+++ b/contrib/go/_std_1.21/src/internal/poll/writev.go
diff --git a/contrib/go/_std_1.21/src/internal/poll/ya.make b/contrib/go/_std_1.21/src/internal/poll/ya.make
new file mode 100644
index 0000000000..33bfc70d87
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/poll/ya.make
@@ -0,0 +1,92 @@
+GO_LIBRARY()
+
+SRCS(
+ fd.go
+ fd_mutex.go
+ fd_poll_runtime.go
+ fd_posix.go
+ sockopt.go
+ sockoptip.go
+)
+
+GO_TEST_SRCS(
+ export_posix_test.go
+ export_test.go
+)
+
+GO_XTEST_SRCS(
+ error_test.go
+ fd_mutex_test.go
+ fd_posix_test.go
+ read_test.go
+ writev_test.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ copy_file_range_linux.go
+ errno_unix.go
+ fd_fsync_posix.go
+ fd_unix.go
+ fd_unixjs.go
+ fd_writev_unix.go
+ hook_cloexec.go
+ hook_unix.go
+ iovec_unix.go
+ sendfile_linux.go
+ sock_cloexec.go
+ sockopt_linux.go
+ sockopt_unix.go
+ splice_linux.go
+ writev.go
+ )
+
+ GO_TEST_SRCS(export_linux_test.go)
+
+ GO_XTEST_SRCS(
+ error_linux_test.go
+ splice_linux_test.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ errno_unix.go
+ fd_fsync_darwin.go
+ fd_opendir_darwin.go
+ fd_unix.go
+ fd_unixjs.go
+ fd_writev_libc.go
+ hook_unix.go
+ iovec_unix.go
+ sendfile_bsd.go
+ sockopt_unix.go
+ sys_cloexec.go
+ writev.go
+ )
+
+ GO_XTEST_SRCS(error_stub_test.go)
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ errno_windows.go
+ fd_fsync_windows.go
+ fd_windows.go
+ hook_windows.go
+ sendfile_windows.go
+ sockopt_windows.go
+ )
+
+ GO_TEST_SRCS(export_windows_test.go)
+
+ GO_XTEST_SRCS(
+ error_stub_test.go
+ fd_windows_test.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/profile/encode.go b/contrib/go/_std_1.21/src/internal/profile/encode.go
index 77d77f1dfb..77d77f1dfb 100644
--- a/contrib/go/_std_1.20/src/internal/profile/encode.go
+++ b/contrib/go/_std_1.21/src/internal/profile/encode.go
diff --git a/contrib/go/_std_1.20/src/internal/profile/filter.go b/contrib/go/_std_1.21/src/internal/profile/filter.go
index 141dd1f405..141dd1f405 100644
--- a/contrib/go/_std_1.20/src/internal/profile/filter.go
+++ b/contrib/go/_std_1.21/src/internal/profile/filter.go
diff --git a/contrib/go/_std_1.21/src/internal/profile/legacy_profile.go b/contrib/go/_std_1.21/src/internal/profile/legacy_profile.go
new file mode 100644
index 0000000000..373a6c04ca
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/profile/legacy_profile.go
@@ -0,0 +1,1268 @@
+// Copyright 2014 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.
+
+// This file implements parsers to convert legacy profiles into the
+// profile.proto format.
+
+package profile
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "internal/lazyregexp"
+ "io"
+ "math"
+ "strconv"
+ "strings"
+)
+
+var (
+ countStartRE = lazyregexp.New(`\A(\w+) profile: total \d+\n\z`)
+ countRE = lazyregexp.New(`\A(\d+) @(( 0x[0-9a-f]+)+)\n\z`)
+
+ heapHeaderRE = lazyregexp.New(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] *@ *(heap[_a-z0-9]*)/?(\d*)`)
+ heapSampleRE = lazyregexp.New(`(-?\d+): *(-?\d+) *\[ *(\d+): *(\d+) *] @([ x0-9a-f]*)`)
+
+ contentionSampleRE = lazyregexp.New(`(\d+) *(\d+) @([ x0-9a-f]*)`)
+
+ hexNumberRE = lazyregexp.New(`0x[0-9a-f]+`)
+
+ growthHeaderRE = lazyregexp.New(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ growthz`)
+
+ fragmentationHeaderRE = lazyregexp.New(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ fragmentationz`)
+
+ threadzStartRE = lazyregexp.New(`--- threadz \d+ ---`)
+ threadStartRE = lazyregexp.New(`--- Thread ([[:xdigit:]]+) \(name: (.*)/(\d+)\) stack: ---`)
+
+ procMapsRE = lazyregexp.New(`([[:xdigit:]]+)-([[:xdigit:]]+)\s+([-rwxp]+)\s+([[:xdigit:]]+)\s+([[:xdigit:]]+):([[:xdigit:]]+)\s+([[:digit:]]+)\s*(\S+)?`)
+
+ briefMapsRE = lazyregexp.New(`\s*([[:xdigit:]]+)-([[:xdigit:]]+):\s*(\S+)(\s.*@)?([[:xdigit:]]+)?`)
+
+ // LegacyHeapAllocated instructs the heapz parsers to use the
+ // allocated memory stats instead of the default in-use memory. Note
+ // that tcmalloc doesn't provide all allocated memory, only in-use
+ // stats.
+ LegacyHeapAllocated bool
+)
+
+func isSpaceOrComment(line string) bool {
+ trimmed := strings.TrimSpace(line)
+ return len(trimmed) == 0 || trimmed[0] == '#'
+}
+
+// parseGoCount parses a Go count profile (e.g., threadcreate or
+// goroutine) and returns a new Profile.
+func parseGoCount(b []byte) (*Profile, error) {
+ r := bytes.NewBuffer(b)
+
+ var line string
+ var err error
+ for {
+ // Skip past comments and empty lines seeking a real header.
+ line, err = r.ReadString('\n')
+ if err != nil {
+ return nil, err
+ }
+ if !isSpaceOrComment(line) {
+ break
+ }
+ }
+
+ m := countStartRE.FindStringSubmatch(line)
+ if m == nil {
+ return nil, errUnrecognized
+ }
+ profileType := m[1]
+ p := &Profile{
+ PeriodType: &ValueType{Type: profileType, Unit: "count"},
+ Period: 1,
+ SampleType: []*ValueType{{Type: profileType, Unit: "count"}},
+ }
+ locations := make(map[uint64]*Location)
+ for {
+ line, err = r.ReadString('\n')
+ if err != nil {
+ if err == io.EOF {
+ break
+ }
+ return nil, err
+ }
+ if isSpaceOrComment(line) {
+ continue
+ }
+ if strings.HasPrefix(line, "---") {
+ break
+ }
+ m := countRE.FindStringSubmatch(line)
+ if m == nil {
+ return nil, errMalformed
+ }
+ n, err := strconv.ParseInt(m[1], 0, 64)
+ if err != nil {
+ return nil, errMalformed
+ }
+ fields := strings.Fields(m[2])
+ locs := make([]*Location, 0, len(fields))
+ for _, stk := range fields {
+ addr, err := strconv.ParseUint(stk, 0, 64)
+ if err != nil {
+ return nil, errMalformed
+ }
+ // Adjust all frames by -1 to land on the call instruction.
+ addr--
+ loc := locations[addr]
+ if loc == nil {
+ loc = &Location{
+ Address: addr,
+ }
+ locations[addr] = loc
+ p.Location = append(p.Location, loc)
+ }
+ locs = append(locs, loc)
+ }
+ p.Sample = append(p.Sample, &Sample{
+ Location: locs,
+ Value: []int64{n},
+ })
+ }
+
+ if err = parseAdditionalSections(strings.TrimSpace(line), r, p); err != nil {
+ return nil, err
+ }
+ return p, nil
+}
+
+// remapLocationIDs ensures there is a location for each address
+// referenced by a sample, and remaps the samples to point to the new
+// location ids.
+func (p *Profile) remapLocationIDs() {
+ seen := make(map[*Location]bool, len(p.Location))
+ var locs []*Location
+
+ for _, s := range p.Sample {
+ for _, l := range s.Location {
+ if seen[l] {
+ continue
+ }
+ l.ID = uint64(len(locs) + 1)
+ locs = append(locs, l)
+ seen[l] = true
+ }
+ }
+ p.Location = locs
+}
+
+func (p *Profile) remapFunctionIDs() {
+ seen := make(map[*Function]bool, len(p.Function))
+ var fns []*Function
+
+ for _, l := range p.Location {
+ for _, ln := range l.Line {
+ fn := ln.Function
+ if fn == nil || seen[fn] {
+ continue
+ }
+ fn.ID = uint64(len(fns) + 1)
+ fns = append(fns, fn)
+ seen[fn] = true
+ }
+ }
+ p.Function = fns
+}
+
+// remapMappingIDs matches location addresses with existing mappings
+// and updates them appropriately. This is O(N*M), if this ever shows
+// up as a bottleneck, evaluate sorting the mappings and doing a
+// binary search, which would make it O(N*log(M)).
+func (p *Profile) remapMappingIDs() {
+ if len(p.Mapping) == 0 {
+ return
+ }
+
+ // Some profile handlers will incorrectly set regions for the main
+ // executable if its section is remapped. Fix them through heuristics.
+
+ // Remove the initial mapping if named '/anon_hugepage' and has a
+ // consecutive adjacent mapping.
+ if m := p.Mapping[0]; strings.HasPrefix(m.File, "/anon_hugepage") {
+ if len(p.Mapping) > 1 && m.Limit == p.Mapping[1].Start {
+ p.Mapping = p.Mapping[1:]
+ }
+ }
+
+ for _, l := range p.Location {
+ if a := l.Address; a != 0 {
+ for _, m := range p.Mapping {
+ if m.Start <= a && a < m.Limit {
+ l.Mapping = m
+ break
+ }
+ }
+ }
+ }
+
+ // Reset all mapping IDs.
+ for i, m := range p.Mapping {
+ m.ID = uint64(i + 1)
+ }
+}
+
+var cpuInts = []func([]byte) (uint64, []byte){
+ get32l,
+ get32b,
+ get64l,
+ get64b,
+}
+
+func get32l(b []byte) (uint64, []byte) {
+ if len(b) < 4 {
+ return 0, nil
+ }
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24, b[4:]
+}
+
+func get32b(b []byte) (uint64, []byte) {
+ if len(b) < 4 {
+ return 0, nil
+ }
+ return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24, b[4:]
+}
+
+func get64l(b []byte) (uint64, []byte) {
+ if len(b) < 8 {
+ return 0, nil
+ }
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56, b[8:]
+}
+
+func get64b(b []byte) (uint64, []byte) {
+ if len(b) < 8 {
+ return 0, nil
+ }
+ return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56, b[8:]
+}
+
+// ParseTracebacks parses a set of tracebacks and returns a newly
+// populated profile. It will accept any text file and generate a
+// Profile out of it with any hex addresses it can identify, including
+// a process map if it can recognize one. Each sample will include a
+// tag "source" with the addresses recognized in string format.
+func ParseTracebacks(b []byte) (*Profile, error) {
+ r := bytes.NewBuffer(b)
+
+ p := &Profile{
+ PeriodType: &ValueType{Type: "trace", Unit: "count"},
+ Period: 1,
+ SampleType: []*ValueType{
+ {Type: "trace", Unit: "count"},
+ },
+ }
+
+ var sources []string
+ var sloc []*Location
+
+ locs := make(map[uint64]*Location)
+ for {
+ l, err := r.ReadString('\n')
+ if err != nil {
+ if err != io.EOF {
+ return nil, err
+ }
+ if l == "" {
+ break
+ }
+ }
+ if sectionTrigger(l) == memoryMapSection {
+ break
+ }
+ if s, addrs := extractHexAddresses(l); len(s) > 0 {
+ for _, addr := range addrs {
+ // Addresses from stack traces point to the next instruction after
+ // each call. Adjust by -1 to land somewhere on the actual call.
+ addr--
+ loc := locs[addr]
+ if locs[addr] == nil {
+ loc = &Location{
+ Address: addr,
+ }
+ p.Location = append(p.Location, loc)
+ locs[addr] = loc
+ }
+ sloc = append(sloc, loc)
+ }
+
+ sources = append(sources, s...)
+ } else {
+ if len(sources) > 0 || len(sloc) > 0 {
+ addTracebackSample(sloc, sources, p)
+ sloc, sources = nil, nil
+ }
+ }
+ }
+
+ // Add final sample to save any leftover data.
+ if len(sources) > 0 || len(sloc) > 0 {
+ addTracebackSample(sloc, sources, p)
+ }
+
+ if err := p.ParseMemoryMap(r); err != nil {
+ return nil, err
+ }
+ return p, nil
+}
+
+func addTracebackSample(l []*Location, s []string, p *Profile) {
+ p.Sample = append(p.Sample,
+ &Sample{
+ Value: []int64{1},
+ Location: l,
+ Label: map[string][]string{"source": s},
+ })
+}
+
+// parseCPU parses a profilez legacy profile and returns a newly
+// populated Profile.
+//
+// The general format for profilez samples is a sequence of words in
+// binary format. The first words are a header with the following data:
+//
+// 1st word -- 0
+// 2nd word -- 3
+// 3rd word -- 0 if a c++ application, 1 if a java application.
+// 4th word -- Sampling period (in microseconds).
+// 5th word -- Padding.
+func parseCPU(b []byte) (*Profile, error) {
+ var parse func([]byte) (uint64, []byte)
+ var n1, n2, n3, n4, n5 uint64
+ for _, parse = range cpuInts {
+ var tmp []byte
+ n1, tmp = parse(b)
+ n2, tmp = parse(tmp)
+ n3, tmp = parse(tmp)
+ n4, tmp = parse(tmp)
+ n5, tmp = parse(tmp)
+
+ if tmp != nil && n1 == 0 && n2 == 3 && n3 == 0 && n4 > 0 && n5 == 0 {
+ b = tmp
+ return cpuProfile(b, int64(n4), parse)
+ }
+ }
+ return nil, errUnrecognized
+}
+
+// cpuProfile returns a new Profile from C++ profilez data.
+// b is the profile bytes after the header, period is the profiling
+// period, and parse is a function to parse 8-byte chunks from the
+// profile in its native endianness.
+func cpuProfile(b []byte, period int64, parse func(b []byte) (uint64, []byte)) (*Profile, error) {
+ p := &Profile{
+ Period: period * 1000,
+ PeriodType: &ValueType{Type: "cpu", Unit: "nanoseconds"},
+ SampleType: []*ValueType{
+ {Type: "samples", Unit: "count"},
+ {Type: "cpu", Unit: "nanoseconds"},
+ },
+ }
+ var err error
+ if b, _, err = parseCPUSamples(b, parse, true, p); err != nil {
+ return nil, err
+ }
+
+ // If all samples have the same second-to-the-bottom frame, it
+ // strongly suggests that it is an uninteresting artifact of
+ // measurement -- a stack frame pushed by the signal handler. The
+ // bottom frame is always correct as it is picked up from the signal
+ // structure, not the stack. Check if this is the case and if so,
+ // remove.
+ if len(p.Sample) > 1 && len(p.Sample[0].Location) > 1 {
+ allSame := true
+ id1 := p.Sample[0].Location[1].Address
+ for _, s := range p.Sample {
+ if len(s.Location) < 2 || id1 != s.Location[1].Address {
+ allSame = false
+ break
+ }
+ }
+ if allSame {
+ for _, s := range p.Sample {
+ s.Location = append(s.Location[:1], s.Location[2:]...)
+ }
+ }
+ }
+
+ if err := p.ParseMemoryMap(bytes.NewBuffer(b)); err != nil {
+ return nil, err
+ }
+ return p, nil
+}
+
+// parseCPUSamples parses a collection of profilez samples from a
+// profile.
+//
+// profilez samples are a repeated sequence of stack frames of the
+// form:
+//
+// 1st word -- The number of times this stack was encountered.
+// 2nd word -- The size of the stack (StackSize).
+// 3rd word -- The first address on the stack.
+// ...
+// StackSize + 2 -- The last address on the stack
+//
+// The last stack trace is of the form:
+//
+// 1st word -- 0
+// 2nd word -- 1
+// 3rd word -- 0
+//
+// Addresses from stack traces may point to the next instruction after
+// each call. Optionally adjust by -1 to land somewhere on the actual
+// call (except for the leaf, which is not a call).
+func parseCPUSamples(b []byte, parse func(b []byte) (uint64, []byte), adjust bool, p *Profile) ([]byte, map[uint64]*Location, error) {
+ locs := make(map[uint64]*Location)
+ for len(b) > 0 {
+ var count, nstk uint64
+ count, b = parse(b)
+ nstk, b = parse(b)
+ if b == nil || nstk > uint64(len(b)/4) {
+ return nil, nil, errUnrecognized
+ }
+ var sloc []*Location
+ addrs := make([]uint64, nstk)
+ for i := 0; i < int(nstk); i++ {
+ addrs[i], b = parse(b)
+ }
+
+ if count == 0 && nstk == 1 && addrs[0] == 0 {
+ // End of data marker
+ break
+ }
+ for i, addr := range addrs {
+ if adjust && i > 0 {
+ addr--
+ }
+ loc := locs[addr]
+ if loc == nil {
+ loc = &Location{
+ Address: addr,
+ }
+ locs[addr] = loc
+ p.Location = append(p.Location, loc)
+ }
+ sloc = append(sloc, loc)
+ }
+ p.Sample = append(p.Sample,
+ &Sample{
+ Value: []int64{int64(count), int64(count) * p.Period},
+ Location: sloc,
+ })
+ }
+ // Reached the end without finding the EOD marker.
+ return b, locs, nil
+}
+
+// parseHeap parses a heapz legacy or a growthz profile and
+// returns a newly populated Profile.
+func parseHeap(b []byte) (p *Profile, err error) {
+ r := bytes.NewBuffer(b)
+ l, err := r.ReadString('\n')
+ if err != nil {
+ return nil, errUnrecognized
+ }
+
+ sampling := ""
+
+ if header := heapHeaderRE.FindStringSubmatch(l); header != nil {
+ p = &Profile{
+ SampleType: []*ValueType{
+ {Type: "objects", Unit: "count"},
+ {Type: "space", Unit: "bytes"},
+ },
+ PeriodType: &ValueType{Type: "objects", Unit: "bytes"},
+ }
+
+ var period int64
+ if len(header[6]) > 0 {
+ if period, err = strconv.ParseInt(header[6], 10, 64); err != nil {
+ return nil, errUnrecognized
+ }
+ }
+
+ switch header[5] {
+ case "heapz_v2", "heap_v2":
+ sampling, p.Period = "v2", period
+ case "heapprofile":
+ sampling, p.Period = "", 1
+ case "heap":
+ sampling, p.Period = "v2", period/2
+ default:
+ return nil, errUnrecognized
+ }
+ } else if header = growthHeaderRE.FindStringSubmatch(l); header != nil {
+ p = &Profile{
+ SampleType: []*ValueType{
+ {Type: "objects", Unit: "count"},
+ {Type: "space", Unit: "bytes"},
+ },
+ PeriodType: &ValueType{Type: "heapgrowth", Unit: "count"},
+ Period: 1,
+ }
+ } else if header = fragmentationHeaderRE.FindStringSubmatch(l); header != nil {
+ p = &Profile{
+ SampleType: []*ValueType{
+ {Type: "objects", Unit: "count"},
+ {Type: "space", Unit: "bytes"},
+ },
+ PeriodType: &ValueType{Type: "allocations", Unit: "count"},
+ Period: 1,
+ }
+ } else {
+ return nil, errUnrecognized
+ }
+
+ if LegacyHeapAllocated {
+ for _, st := range p.SampleType {
+ st.Type = "alloc_" + st.Type
+ }
+ } else {
+ for _, st := range p.SampleType {
+ st.Type = "inuse_" + st.Type
+ }
+ }
+
+ locs := make(map[uint64]*Location)
+ for {
+ l, err = r.ReadString('\n')
+ if err != nil {
+ if err != io.EOF {
+ return nil, err
+ }
+
+ if l == "" {
+ break
+ }
+ }
+
+ if isSpaceOrComment(l) {
+ continue
+ }
+ l = strings.TrimSpace(l)
+
+ if sectionTrigger(l) != unrecognizedSection {
+ break
+ }
+
+ value, blocksize, addrs, err := parseHeapSample(l, p.Period, sampling)
+ if err != nil {
+ return nil, err
+ }
+ var sloc []*Location
+ for _, addr := range addrs {
+ // Addresses from stack traces point to the next instruction after
+ // each call. Adjust by -1 to land somewhere on the actual call.
+ addr--
+ loc := locs[addr]
+ if locs[addr] == nil {
+ loc = &Location{
+ Address: addr,
+ }
+ p.Location = append(p.Location, loc)
+ locs[addr] = loc
+ }
+ sloc = append(sloc, loc)
+ }
+
+ p.Sample = append(p.Sample, &Sample{
+ Value: value,
+ Location: sloc,
+ NumLabel: map[string][]int64{"bytes": {blocksize}},
+ })
+ }
+
+ if err = parseAdditionalSections(l, r, p); err != nil {
+ return nil, err
+ }
+ return p, nil
+}
+
+// parseHeapSample parses a single row from a heap profile into a new Sample.
+func parseHeapSample(line string, rate int64, sampling string) (value []int64, blocksize int64, addrs []uint64, err error) {
+ sampleData := heapSampleRE.FindStringSubmatch(line)
+ if len(sampleData) != 6 {
+ return value, blocksize, addrs, fmt.Errorf("unexpected number of sample values: got %d, want 6", len(sampleData))
+ }
+
+ // Use first two values by default; tcmalloc sampling generates the
+ // same value for both, only the older heap-profile collect separate
+ // stats for in-use and allocated objects.
+ valueIndex := 1
+ if LegacyHeapAllocated {
+ valueIndex = 3
+ }
+
+ var v1, v2 int64
+ if v1, err = strconv.ParseInt(sampleData[valueIndex], 10, 64); err != nil {
+ return value, blocksize, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
+ }
+ if v2, err = strconv.ParseInt(sampleData[valueIndex+1], 10, 64); err != nil {
+ return value, blocksize, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
+ }
+
+ if v1 == 0 {
+ if v2 != 0 {
+ return value, blocksize, addrs, fmt.Errorf("allocation count was 0 but allocation bytes was %d", v2)
+ }
+ } else {
+ blocksize = v2 / v1
+ if sampling == "v2" {
+ v1, v2 = scaleHeapSample(v1, v2, rate)
+ }
+ }
+
+ value = []int64{v1, v2}
+ addrs = parseHexAddresses(sampleData[5])
+
+ return value, blocksize, addrs, nil
+}
+
+// extractHexAddresses extracts hex numbers from a string and returns
+// them, together with their numeric value, in a slice.
+func extractHexAddresses(s string) ([]string, []uint64) {
+ hexStrings := hexNumberRE.FindAllString(s, -1)
+ var ids []uint64
+ for _, s := range hexStrings {
+ if id, err := strconv.ParseUint(s, 0, 64); err == nil {
+ ids = append(ids, id)
+ } else {
+ // Do not expect any parsing failures due to the regexp matching.
+ panic("failed to parse hex value:" + s)
+ }
+ }
+ return hexStrings, ids
+}
+
+// parseHexAddresses parses hex numbers from a string and returns them
+// in a slice.
+func parseHexAddresses(s string) []uint64 {
+ _, ids := extractHexAddresses(s)
+ return ids
+}
+
+// scaleHeapSample adjusts the data from a heapz Sample to
+// account for its probability of appearing in the collected
+// data. heapz profiles are a sampling of the memory allocations
+// requests in a program. We estimate the unsampled value by dividing
+// each collected sample by its probability of appearing in the
+// profile. heapz v2 profiles rely on a poisson process to determine
+// which samples to collect, based on the desired average collection
+// rate R. The probability of a sample of size S to appear in that
+// profile is 1-exp(-S/R).
+func scaleHeapSample(count, size, rate int64) (int64, int64) {
+ if count == 0 || size == 0 {
+ return 0, 0
+ }
+
+ if rate <= 1 {
+ // if rate==1 all samples were collected so no adjustment is needed.
+ // if rate<1 treat as unknown and skip scaling.
+ return count, size
+ }
+
+ avgSize := float64(size) / float64(count)
+ scale := 1 / (1 - math.Exp(-avgSize/float64(rate)))
+
+ return int64(float64(count) * scale), int64(float64(size) * scale)
+}
+
+// parseContention parses a mutex or contention profile. There are 2 cases:
+// "--- contentionz " for legacy C++ profiles (and backwards compatibility)
+// "--- mutex:" or "--- contention:" for profiles generated by the Go runtime.
+// This code converts the text output from runtime into a *Profile. (In the future
+// the runtime might write a serialized Profile directly making this unnecessary.)
+func parseContention(b []byte) (*Profile, error) {
+ r := bytes.NewBuffer(b)
+ var l string
+ var err error
+ for {
+ // Skip past comments and empty lines seeking a real header.
+ l, err = r.ReadString('\n')
+ if err != nil {
+ return nil, err
+ }
+ if !isSpaceOrComment(l) {
+ break
+ }
+ }
+
+ if strings.HasPrefix(l, "--- contentionz ") {
+ return parseCppContention(r)
+ } else if strings.HasPrefix(l, "--- mutex:") {
+ return parseCppContention(r)
+ } else if strings.HasPrefix(l, "--- contention:") {
+ return parseCppContention(r)
+ }
+ return nil, errUnrecognized
+}
+
+// parseCppContention parses the output from synchronization_profiling.cc
+// for backward compatibility, and the compatible (non-debug) block profile
+// output from the Go runtime.
+func parseCppContention(r *bytes.Buffer) (*Profile, error) {
+ p := &Profile{
+ PeriodType: &ValueType{Type: "contentions", Unit: "count"},
+ Period: 1,
+ SampleType: []*ValueType{
+ {Type: "contentions", Unit: "count"},
+ {Type: "delay", Unit: "nanoseconds"},
+ },
+ }
+
+ var cpuHz int64
+ var l string
+ var err error
+ // Parse text of the form "attribute = value" before the samples.
+ const delimiter = '='
+ for {
+ l, err = r.ReadString('\n')
+ if err != nil {
+ if err != io.EOF {
+ return nil, err
+ }
+
+ if l == "" {
+ break
+ }
+ }
+ if isSpaceOrComment(l) {
+ continue
+ }
+
+ if l = strings.TrimSpace(l); l == "" {
+ continue
+ }
+
+ if strings.HasPrefix(l, "---") {
+ break
+ }
+
+ index := strings.IndexByte(l, delimiter)
+ if index < 0 {
+ break
+ }
+ key := l[:index]
+ val := l[index+1:]
+
+ key, val = strings.TrimSpace(key), strings.TrimSpace(val)
+ var err error
+ switch key {
+ case "cycles/second":
+ if cpuHz, err = strconv.ParseInt(val, 0, 64); err != nil {
+ return nil, errUnrecognized
+ }
+ case "sampling period":
+ if p.Period, err = strconv.ParseInt(val, 0, 64); err != nil {
+ return nil, errUnrecognized
+ }
+ case "ms since reset":
+ ms, err := strconv.ParseInt(val, 0, 64)
+ if err != nil {
+ return nil, errUnrecognized
+ }
+ p.DurationNanos = ms * 1000 * 1000
+ case "format":
+ // CPP contentionz profiles don't have format.
+ return nil, errUnrecognized
+ case "resolution":
+ // CPP contentionz profiles don't have resolution.
+ return nil, errUnrecognized
+ case "discarded samples":
+ default:
+ return nil, errUnrecognized
+ }
+ }
+
+ locs := make(map[uint64]*Location)
+ for {
+ if !isSpaceOrComment(l) {
+ if l = strings.TrimSpace(l); strings.HasPrefix(l, "---") {
+ break
+ }
+ value, addrs, err := parseContentionSample(l, p.Period, cpuHz)
+ if err != nil {
+ return nil, err
+ }
+ var sloc []*Location
+ for _, addr := range addrs {
+ // Addresses from stack traces point to the next instruction after
+ // each call. Adjust by -1 to land somewhere on the actual call.
+ addr--
+ loc := locs[addr]
+ if locs[addr] == nil {
+ loc = &Location{
+ Address: addr,
+ }
+ p.Location = append(p.Location, loc)
+ locs[addr] = loc
+ }
+ sloc = append(sloc, loc)
+ }
+ p.Sample = append(p.Sample, &Sample{
+ Value: value,
+ Location: sloc,
+ })
+ }
+
+ if l, err = r.ReadString('\n'); err != nil {
+ if err != io.EOF {
+ return nil, err
+ }
+ if l == "" {
+ break
+ }
+ }
+ }
+
+ if err = parseAdditionalSections(l, r, p); err != nil {
+ return nil, err
+ }
+
+ return p, nil
+}
+
+// parseContentionSample parses a single row from a contention profile
+// into a new Sample.
+func parseContentionSample(line string, period, cpuHz int64) (value []int64, addrs []uint64, err error) {
+ sampleData := contentionSampleRE.FindStringSubmatch(line)
+ if sampleData == nil {
+ return value, addrs, errUnrecognized
+ }
+
+ v1, err := strconv.ParseInt(sampleData[1], 10, 64)
+ if err != nil {
+ return value, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
+ }
+ v2, err := strconv.ParseInt(sampleData[2], 10, 64)
+ if err != nil {
+ return value, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
+ }
+
+ // Unsample values if period and cpuHz are available.
+ // - Delays are scaled to cycles and then to nanoseconds.
+ // - Contentions are scaled to cycles.
+ if period > 0 {
+ if cpuHz > 0 {
+ cpuGHz := float64(cpuHz) / 1e9
+ v1 = int64(float64(v1) * float64(period) / cpuGHz)
+ }
+ v2 = v2 * period
+ }
+
+ value = []int64{v2, v1}
+ addrs = parseHexAddresses(sampleData[3])
+
+ return value, addrs, nil
+}
+
+// parseThread parses a Threadz profile and returns a new Profile.
+func parseThread(b []byte) (*Profile, error) {
+ r := bytes.NewBuffer(b)
+
+ var line string
+ var err error
+ for {
+ // Skip past comments and empty lines seeking a real header.
+ line, err = r.ReadString('\n')
+ if err != nil {
+ return nil, err
+ }
+ if !isSpaceOrComment(line) {
+ break
+ }
+ }
+
+ if m := threadzStartRE.FindStringSubmatch(line); m != nil {
+ // Advance over initial comments until first stack trace.
+ for {
+ line, err = r.ReadString('\n')
+ if err != nil {
+ if err != io.EOF {
+ return nil, err
+ }
+
+ if line == "" {
+ break
+ }
+ }
+ if sectionTrigger(line) != unrecognizedSection || line[0] == '-' {
+ break
+ }
+ }
+ } else if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 {
+ return nil, errUnrecognized
+ }
+
+ p := &Profile{
+ SampleType: []*ValueType{{Type: "thread", Unit: "count"}},
+ PeriodType: &ValueType{Type: "thread", Unit: "count"},
+ Period: 1,
+ }
+
+ locs := make(map[uint64]*Location)
+ // Recognize each thread and populate profile samples.
+ for sectionTrigger(line) == unrecognizedSection {
+ if strings.HasPrefix(line, "---- no stack trace for") {
+ line = ""
+ break
+ }
+ if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 {
+ return nil, errUnrecognized
+ }
+
+ var addrs []uint64
+ line, addrs, err = parseThreadSample(r)
+ if err != nil {
+ return nil, errUnrecognized
+ }
+ if len(addrs) == 0 {
+ // We got a --same as previous threads--. Bump counters.
+ if len(p.Sample) > 0 {
+ s := p.Sample[len(p.Sample)-1]
+ s.Value[0]++
+ }
+ continue
+ }
+
+ var sloc []*Location
+ for _, addr := range addrs {
+ // Addresses from stack traces point to the next instruction after
+ // each call. Adjust by -1 to land somewhere on the actual call.
+ addr--
+ loc := locs[addr]
+ if locs[addr] == nil {
+ loc = &Location{
+ Address: addr,
+ }
+ p.Location = append(p.Location, loc)
+ locs[addr] = loc
+ }
+ sloc = append(sloc, loc)
+ }
+
+ p.Sample = append(p.Sample, &Sample{
+ Value: []int64{1},
+ Location: sloc,
+ })
+ }
+
+ if err = parseAdditionalSections(line, r, p); err != nil {
+ return nil, err
+ }
+
+ return p, nil
+}
+
+// parseThreadSample parses a symbolized or unsymbolized stack trace.
+// Returns the first line after the traceback, the sample (or nil if
+// it hits a 'same-as-previous' marker) and an error.
+func parseThreadSample(b *bytes.Buffer) (nextl string, addrs []uint64, err error) {
+ var l string
+ sameAsPrevious := false
+ for {
+ if l, err = b.ReadString('\n'); err != nil {
+ if err != io.EOF {
+ return "", nil, err
+ }
+ if l == "" {
+ break
+ }
+ }
+ if l = strings.TrimSpace(l); l == "" {
+ continue
+ }
+
+ if strings.HasPrefix(l, "---") {
+ break
+ }
+ if strings.Contains(l, "same as previous thread") {
+ sameAsPrevious = true
+ continue
+ }
+
+ addrs = append(addrs, parseHexAddresses(l)...)
+ }
+
+ if sameAsPrevious {
+ return l, nil, nil
+ }
+ return l, addrs, nil
+}
+
+// parseAdditionalSections parses any additional sections in the
+// profile, ignoring any unrecognized sections.
+func parseAdditionalSections(l string, b *bytes.Buffer, p *Profile) (err error) {
+ for {
+ if sectionTrigger(l) == memoryMapSection {
+ break
+ }
+ // Ignore any unrecognized sections.
+ if l, err := b.ReadString('\n'); err != nil {
+ if err != io.EOF {
+ return err
+ }
+ if l == "" {
+ break
+ }
+ }
+ }
+ return p.ParseMemoryMap(b)
+}
+
+// ParseMemoryMap parses a memory map in the format of
+// /proc/self/maps, and overrides the mappings in the current profile.
+// It renumbers the samples and locations in the profile correspondingly.
+func (p *Profile) ParseMemoryMap(rd io.Reader) error {
+ b := bufio.NewReader(rd)
+
+ var attrs []string
+ var r *strings.Replacer
+ const delimiter = '='
+ for {
+ l, err := b.ReadString('\n')
+ if err != nil {
+ if err != io.EOF {
+ return err
+ }
+ if l == "" {
+ break
+ }
+ }
+ if l = strings.TrimSpace(l); l == "" {
+ continue
+ }
+
+ if r != nil {
+ l = r.Replace(l)
+ }
+ m, err := parseMappingEntry(l)
+ if err != nil {
+ if err == errUnrecognized {
+ // Recognize assignments of the form: attr=value, and replace
+ // $attr with value on subsequent mappings.
+ idx := strings.IndexByte(l, delimiter)
+ if idx >= 0 {
+ attr := l[:idx]
+ value := l[idx+1:]
+ attrs = append(attrs, "$"+strings.TrimSpace(attr), strings.TrimSpace(value))
+ r = strings.NewReplacer(attrs...)
+ }
+ // Ignore any unrecognized entries
+ continue
+ }
+ return err
+ }
+ if m == nil || (m.File == "" && len(p.Mapping) != 0) {
+ // In some cases the first entry may include the address range
+ // but not the name of the file. It should be followed by
+ // another entry with the name.
+ continue
+ }
+ if len(p.Mapping) == 1 && p.Mapping[0].File == "" {
+ // Update the name if this is the entry following that empty one.
+ p.Mapping[0].File = m.File
+ continue
+ }
+ p.Mapping = append(p.Mapping, m)
+ }
+ p.remapLocationIDs()
+ p.remapFunctionIDs()
+ p.remapMappingIDs()
+ return nil
+}
+
+func parseMappingEntry(l string) (*Mapping, error) {
+ mapping := &Mapping{}
+ var err error
+ if me := procMapsRE.FindStringSubmatch(l); len(me) == 9 {
+ if !strings.Contains(me[3], "x") {
+ // Skip non-executable entries.
+ return nil, nil
+ }
+ if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil {
+ return nil, errUnrecognized
+ }
+ if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil {
+ return nil, errUnrecognized
+ }
+ if me[4] != "" {
+ if mapping.Offset, err = strconv.ParseUint(me[4], 16, 64); err != nil {
+ return nil, errUnrecognized
+ }
+ }
+ mapping.File = me[8]
+ return mapping, nil
+ }
+
+ if me := briefMapsRE.FindStringSubmatch(l); len(me) == 6 {
+ if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil {
+ return nil, errUnrecognized
+ }
+ if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil {
+ return nil, errUnrecognized
+ }
+ mapping.File = me[3]
+ if me[5] != "" {
+ if mapping.Offset, err = strconv.ParseUint(me[5], 16, 64); err != nil {
+ return nil, errUnrecognized
+ }
+ }
+ return mapping, nil
+ }
+
+ return nil, errUnrecognized
+}
+
+type sectionType int
+
+const (
+ unrecognizedSection sectionType = iota
+ memoryMapSection
+)
+
+var memoryMapTriggers = []string{
+ "--- Memory map: ---",
+ "MAPPED_LIBRARIES:",
+}
+
+func sectionTrigger(line string) sectionType {
+ for _, trigger := range memoryMapTriggers {
+ if strings.Contains(line, trigger) {
+ return memoryMapSection
+ }
+ }
+ return unrecognizedSection
+}
+
+func (p *Profile) addLegacyFrameInfo() {
+ switch {
+ case isProfileType(p, heapzSampleTypes) ||
+ isProfileType(p, heapzInUseSampleTypes) ||
+ isProfileType(p, heapzAllocSampleTypes):
+ p.DropFrames, p.KeepFrames = allocRxStr, allocSkipRxStr
+ case isProfileType(p, contentionzSampleTypes):
+ p.DropFrames, p.KeepFrames = lockRxStr, ""
+ default:
+ p.DropFrames, p.KeepFrames = cpuProfilerRxStr, ""
+ }
+}
+
+var heapzSampleTypes = []string{"allocations", "size"} // early Go pprof profiles
+var heapzInUseSampleTypes = []string{"inuse_objects", "inuse_space"}
+var heapzAllocSampleTypes = []string{"alloc_objects", "alloc_space"}
+var contentionzSampleTypes = []string{"contentions", "delay"}
+
+func isProfileType(p *Profile, t []string) bool {
+ st := p.SampleType
+ if len(st) != len(t) {
+ return false
+ }
+
+ for i := range st {
+ if st[i].Type != t[i] {
+ return false
+ }
+ }
+ return true
+}
+
+var allocRxStr = strings.Join([]string{
+ // POSIX entry points.
+ `calloc`,
+ `cfree`,
+ `malloc`,
+ `free`,
+ `memalign`,
+ `do_memalign`,
+ `(__)?posix_memalign`,
+ `pvalloc`,
+ `valloc`,
+ `realloc`,
+
+ // TC malloc.
+ `tcmalloc::.*`,
+ `tc_calloc`,
+ `tc_cfree`,
+ `tc_malloc`,
+ `tc_free`,
+ `tc_memalign`,
+ `tc_posix_memalign`,
+ `tc_pvalloc`,
+ `tc_valloc`,
+ `tc_realloc`,
+ `tc_new`,
+ `tc_delete`,
+ `tc_newarray`,
+ `tc_deletearray`,
+ `tc_new_nothrow`,
+ `tc_newarray_nothrow`,
+
+ // Memory-allocation routines on OS X.
+ `malloc_zone_malloc`,
+ `malloc_zone_calloc`,
+ `malloc_zone_valloc`,
+ `malloc_zone_realloc`,
+ `malloc_zone_memalign`,
+ `malloc_zone_free`,
+
+ // Go runtime
+ `runtime\..*`,
+
+ // Other misc. memory allocation routines
+ `BaseArena::.*`,
+ `(::)?do_malloc_no_errno`,
+ `(::)?do_malloc_pages`,
+ `(::)?do_malloc`,
+ `DoSampledAllocation`,
+ `MallocedMemBlock::MallocedMemBlock`,
+ `_M_allocate`,
+ `__builtin_(vec_)?delete`,
+ `__builtin_(vec_)?new`,
+ `__gnu_cxx::new_allocator::allocate`,
+ `__libc_malloc`,
+ `__malloc_alloc_template::allocate`,
+ `allocate`,
+ `cpp_alloc`,
+ `operator new(\[\])?`,
+ `simple_alloc::allocate`,
+}, `|`)
+
+var allocSkipRxStr = strings.Join([]string{
+ // Preserve Go runtime frames that appear in the middle/bottom of
+ // the stack.
+ `runtime\.panic`,
+ `runtime\.reflectcall`,
+ `runtime\.call[0-9]*`,
+}, `|`)
+
+var cpuProfilerRxStr = strings.Join([]string{
+ `ProfileData::Add`,
+ `ProfileData::prof_handler`,
+ `CpuProfiler::prof_handler`,
+ `__pthread_sighandler`,
+ `__restore`,
+}, `|`)
+
+var lockRxStr = strings.Join([]string{
+ `RecordLockProfileData`,
+ `(base::)?RecordLockProfileData.*`,
+ `(base::)?SubmitMutexProfileData.*`,
+ `(base::)?SubmitSpinLockProfileData.*`,
+ `(Mutex::)?AwaitCommon.*`,
+ `(Mutex::)?Unlock.*`,
+ `(Mutex::)?UnlockSlow.*`,
+ `(Mutex::)?ReaderUnlock.*`,
+ `(MutexLock::)?~MutexLock.*`,
+ `(SpinLock::)?Unlock.*`,
+ `(SpinLock::)?SlowUnlock.*`,
+ `(SpinLockHolder::)?~SpinLockHolder.*`,
+}, `|`)
diff --git a/contrib/go/_std_1.20/src/internal/profile/merge.go b/contrib/go/_std_1.21/src/internal/profile/merge.go
index 3ea7d4cf42..3ea7d4cf42 100644
--- a/contrib/go/_std_1.20/src/internal/profile/merge.go
+++ b/contrib/go/_std_1.21/src/internal/profile/merge.go
diff --git a/contrib/go/_std_1.21/src/internal/profile/profile.go b/contrib/go/_std_1.21/src/internal/profile/profile.go
new file mode 100644
index 0000000000..c779bb2b11
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/profile/profile.go
@@ -0,0 +1,613 @@
+// Copyright 2014 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 profile provides a representation of
+// github.com/google/pprof/proto/profile.proto and
+// methods to encode/decode/merge profiles in this format.
+package profile
+
+import (
+ "bytes"
+ "compress/gzip"
+ "fmt"
+ "internal/lazyregexp"
+ "io"
+ "strings"
+ "time"
+)
+
+// Profile is an in-memory representation of profile.proto.
+type Profile struct {
+ SampleType []*ValueType
+ DefaultSampleType string
+ Sample []*Sample
+ Mapping []*Mapping
+ Location []*Location
+ Function []*Function
+ Comments []string
+
+ DropFrames string
+ KeepFrames string
+
+ TimeNanos int64
+ DurationNanos int64
+ PeriodType *ValueType
+ Period int64
+
+ commentX []int64
+ dropFramesX int64
+ keepFramesX int64
+ stringTable []string
+ defaultSampleTypeX int64
+}
+
+// ValueType corresponds to Profile.ValueType
+type ValueType struct {
+ Type string // cpu, wall, inuse_space, etc
+ Unit string // seconds, nanoseconds, bytes, etc
+
+ typeX int64
+ unitX int64
+}
+
+// Sample corresponds to Profile.Sample
+type Sample struct {
+ Location []*Location
+ Value []int64
+ Label map[string][]string
+ NumLabel map[string][]int64
+ NumUnit map[string][]string
+
+ locationIDX []uint64
+ labelX []Label
+}
+
+// Label corresponds to Profile.Label
+type Label struct {
+ keyX int64
+ // Exactly one of the two following values must be set
+ strX int64
+ numX int64 // Integer value for this label
+}
+
+// Mapping corresponds to Profile.Mapping
+type Mapping struct {
+ ID uint64
+ Start uint64
+ Limit uint64
+ Offset uint64
+ File string
+ BuildID string
+ HasFunctions bool
+ HasFilenames bool
+ HasLineNumbers bool
+ HasInlineFrames bool
+
+ fileX int64
+ buildIDX int64
+}
+
+// Location corresponds to Profile.Location
+type Location struct {
+ ID uint64
+ Mapping *Mapping
+ Address uint64
+ Line []Line
+ IsFolded bool
+
+ mappingIDX uint64
+}
+
+// Line corresponds to Profile.Line
+type Line struct {
+ Function *Function
+ Line int64
+
+ functionIDX uint64
+}
+
+// Function corresponds to Profile.Function
+type Function struct {
+ ID uint64
+ Name string
+ SystemName string
+ Filename string
+ StartLine int64
+
+ nameX int64
+ systemNameX int64
+ filenameX int64
+}
+
+// Parse parses a profile and checks for its validity. The input
+// may be a gzip-compressed encoded protobuf or one of many legacy
+// profile formats which may be unsupported in the future.
+func Parse(r io.Reader) (*Profile, error) {
+ orig, err := io.ReadAll(r)
+ if err != nil {
+ return nil, err
+ }
+
+ var p *Profile
+ if len(orig) >= 2 && orig[0] == 0x1f && orig[1] == 0x8b {
+ gz, err := gzip.NewReader(bytes.NewBuffer(orig))
+ if err != nil {
+ return nil, fmt.Errorf("decompressing profile: %v", err)
+ }
+ data, err := io.ReadAll(gz)
+ if err != nil {
+ return nil, fmt.Errorf("decompressing profile: %v", err)
+ }
+ orig = data
+ }
+ if p, err = parseUncompressed(orig); err != nil {
+ if p, err = parseLegacy(orig); err != nil {
+ return nil, fmt.Errorf("parsing profile: %v", err)
+ }
+ }
+
+ if err := p.CheckValid(); err != nil {
+ return nil, fmt.Errorf("malformed profile: %v", err)
+ }
+ return p, nil
+}
+
+var errUnrecognized = fmt.Errorf("unrecognized profile format")
+var errMalformed = fmt.Errorf("malformed profile format")
+
+func parseLegacy(data []byte) (*Profile, error) {
+ parsers := []func([]byte) (*Profile, error){
+ parseCPU,
+ parseHeap,
+ parseGoCount, // goroutine, threadcreate
+ parseThread,
+ parseContention,
+ }
+
+ for _, parser := range parsers {
+ p, err := parser(data)
+ if err == nil {
+ p.setMain()
+ p.addLegacyFrameInfo()
+ return p, nil
+ }
+ if err != errUnrecognized {
+ return nil, err
+ }
+ }
+ return nil, errUnrecognized
+}
+
+func parseUncompressed(data []byte) (*Profile, error) {
+ p := &Profile{}
+ if err := unmarshal(data, p); err != nil {
+ return nil, err
+ }
+
+ if err := p.postDecode(); err != nil {
+ return nil, err
+ }
+
+ return p, nil
+}
+
+var libRx = lazyregexp.New(`([.]so$|[.]so[._][0-9]+)`)
+
+// setMain scans Mapping entries and guesses which entry is main
+// because legacy profiles don't obey the convention of putting main
+// first.
+func (p *Profile) setMain() {
+ for i := 0; i < len(p.Mapping); i++ {
+ file := strings.TrimSpace(strings.ReplaceAll(p.Mapping[i].File, "(deleted)", ""))
+ if len(file) == 0 {
+ continue
+ }
+ if len(libRx.FindStringSubmatch(file)) > 0 {
+ continue
+ }
+ if strings.HasPrefix(file, "[") {
+ continue
+ }
+ // Swap what we guess is main to position 0.
+ p.Mapping[i], p.Mapping[0] = p.Mapping[0], p.Mapping[i]
+ break
+ }
+}
+
+// Write writes the profile as a gzip-compressed marshaled protobuf.
+func (p *Profile) Write(w io.Writer) error {
+ p.preEncode()
+ b := marshal(p)
+ zw := gzip.NewWriter(w)
+ defer zw.Close()
+ _, err := zw.Write(b)
+ return err
+}
+
+// CheckValid tests whether the profile is valid. Checks include, but are
+// not limited to:
+// - len(Profile.Sample[n].value) == len(Profile.value_unit)
+// - Sample.id has a corresponding Profile.Location
+func (p *Profile) CheckValid() error {
+ // Check that sample values are consistent
+ sampleLen := len(p.SampleType)
+ if sampleLen == 0 && len(p.Sample) != 0 {
+ return fmt.Errorf("missing sample type information")
+ }
+ for _, s := range p.Sample {
+ if len(s.Value) != sampleLen {
+ return fmt.Errorf("mismatch: sample has: %d values vs. %d types", len(s.Value), len(p.SampleType))
+ }
+ }
+
+ // Check that all mappings/locations/functions are in the tables
+ // Check that there are no duplicate ids
+ mappings := make(map[uint64]*Mapping, len(p.Mapping))
+ for _, m := range p.Mapping {
+ if m.ID == 0 {
+ return fmt.Errorf("found mapping with reserved ID=0")
+ }
+ if mappings[m.ID] != nil {
+ return fmt.Errorf("multiple mappings with same id: %d", m.ID)
+ }
+ mappings[m.ID] = m
+ }
+ functions := make(map[uint64]*Function, len(p.Function))
+ for _, f := range p.Function {
+ if f.ID == 0 {
+ return fmt.Errorf("found function with reserved ID=0")
+ }
+ if functions[f.ID] != nil {
+ return fmt.Errorf("multiple functions with same id: %d", f.ID)
+ }
+ functions[f.ID] = f
+ }
+ locations := make(map[uint64]*Location, len(p.Location))
+ for _, l := range p.Location {
+ if l.ID == 0 {
+ return fmt.Errorf("found location with reserved id=0")
+ }
+ if locations[l.ID] != nil {
+ return fmt.Errorf("multiple locations with same id: %d", l.ID)
+ }
+ locations[l.ID] = l
+ if m := l.Mapping; m != nil {
+ if m.ID == 0 || mappings[m.ID] != m {
+ return fmt.Errorf("inconsistent mapping %p: %d", m, m.ID)
+ }
+ }
+ for _, ln := range l.Line {
+ if f := ln.Function; f != nil {
+ if f.ID == 0 || functions[f.ID] != f {
+ return fmt.Errorf("inconsistent function %p: %d", f, f.ID)
+ }
+ }
+ }
+ }
+ return nil
+}
+
+// Aggregate merges the locations in the profile into equivalence
+// classes preserving the request attributes. It also updates the
+// samples to point to the merged locations.
+func (p *Profile) Aggregate(inlineFrame, function, filename, linenumber, address bool) error {
+ for _, m := range p.Mapping {
+ m.HasInlineFrames = m.HasInlineFrames && inlineFrame
+ m.HasFunctions = m.HasFunctions && function
+ m.HasFilenames = m.HasFilenames && filename
+ m.HasLineNumbers = m.HasLineNumbers && linenumber
+ }
+
+ // Aggregate functions
+ if !function || !filename {
+ for _, f := range p.Function {
+ if !function {
+ f.Name = ""
+ f.SystemName = ""
+ }
+ if !filename {
+ f.Filename = ""
+ }
+ }
+ }
+
+ // Aggregate locations
+ if !inlineFrame || !address || !linenumber {
+ for _, l := range p.Location {
+ if !inlineFrame && len(l.Line) > 1 {
+ l.Line = l.Line[len(l.Line)-1:]
+ }
+ if !linenumber {
+ for i := range l.Line {
+ l.Line[i].Line = 0
+ }
+ }
+ if !address {
+ l.Address = 0
+ }
+ }
+ }
+
+ return p.CheckValid()
+}
+
+// Print dumps a text representation of a profile. Intended mainly
+// for debugging purposes.
+func (p *Profile) String() string {
+
+ ss := make([]string, 0, len(p.Sample)+len(p.Mapping)+len(p.Location))
+ if pt := p.PeriodType; pt != nil {
+ ss = append(ss, fmt.Sprintf("PeriodType: %s %s", pt.Type, pt.Unit))
+ }
+ ss = append(ss, fmt.Sprintf("Period: %d", p.Period))
+ if p.TimeNanos != 0 {
+ ss = append(ss, fmt.Sprintf("Time: %v", time.Unix(0, p.TimeNanos)))
+ }
+ if p.DurationNanos != 0 {
+ ss = append(ss, fmt.Sprintf("Duration: %v", time.Duration(p.DurationNanos)))
+ }
+
+ ss = append(ss, "Samples:")
+ var sh1 string
+ for _, s := range p.SampleType {
+ sh1 = sh1 + fmt.Sprintf("%s/%s ", s.Type, s.Unit)
+ }
+ ss = append(ss, strings.TrimSpace(sh1))
+ for _, s := range p.Sample {
+ var sv string
+ for _, v := range s.Value {
+ sv = fmt.Sprintf("%s %10d", sv, v)
+ }
+ sv = sv + ": "
+ for _, l := range s.Location {
+ sv = sv + fmt.Sprintf("%d ", l.ID)
+ }
+ ss = append(ss, sv)
+ const labelHeader = " "
+ if len(s.Label) > 0 {
+ ls := labelHeader
+ for k, v := range s.Label {
+ ls = ls + fmt.Sprintf("%s:%v ", k, v)
+ }
+ ss = append(ss, ls)
+ }
+ if len(s.NumLabel) > 0 {
+ ls := labelHeader
+ for k, v := range s.NumLabel {
+ ls = ls + fmt.Sprintf("%s:%v ", k, v)
+ }
+ ss = append(ss, ls)
+ }
+ }
+
+ ss = append(ss, "Locations")
+ for _, l := range p.Location {
+ locStr := fmt.Sprintf("%6d: %#x ", l.ID, l.Address)
+ if m := l.Mapping; m != nil {
+ locStr = locStr + fmt.Sprintf("M=%d ", m.ID)
+ }
+ if len(l.Line) == 0 {
+ ss = append(ss, locStr)
+ }
+ for li := range l.Line {
+ lnStr := "??"
+ if fn := l.Line[li].Function; fn != nil {
+ lnStr = fmt.Sprintf("%s %s:%d s=%d",
+ fn.Name,
+ fn.Filename,
+ l.Line[li].Line,
+ fn.StartLine)
+ if fn.Name != fn.SystemName {
+ lnStr = lnStr + "(" + fn.SystemName + ")"
+ }
+ }
+ ss = append(ss, locStr+lnStr)
+ // Do not print location details past the first line
+ locStr = " "
+ }
+ }
+
+ ss = append(ss, "Mappings")
+ for _, m := range p.Mapping {
+ bits := ""
+ if m.HasFunctions {
+ bits += "[FN]"
+ }
+ if m.HasFilenames {
+ bits += "[FL]"
+ }
+ if m.HasLineNumbers {
+ bits += "[LN]"
+ }
+ if m.HasInlineFrames {
+ bits += "[IN]"
+ }
+ ss = append(ss, fmt.Sprintf("%d: %#x/%#x/%#x %s %s %s",
+ m.ID,
+ m.Start, m.Limit, m.Offset,
+ m.File,
+ m.BuildID,
+ bits))
+ }
+
+ return strings.Join(ss, "\n") + "\n"
+}
+
+// Merge adds profile p adjusted by ratio r into profile p. Profiles
+// must be compatible (same Type and SampleType).
+// TODO(rsilvera): consider normalizing the profiles based on the
+// total samples collected.
+func (p *Profile) Merge(pb *Profile, r float64) error {
+ if err := p.Compatible(pb); err != nil {
+ return err
+ }
+
+ pb = pb.Copy()
+
+ // Keep the largest of the two periods.
+ if pb.Period > p.Period {
+ p.Period = pb.Period
+ }
+
+ p.DurationNanos += pb.DurationNanos
+
+ p.Mapping = append(p.Mapping, pb.Mapping...)
+ for i, m := range p.Mapping {
+ m.ID = uint64(i + 1)
+ }
+ p.Location = append(p.Location, pb.Location...)
+ for i, l := range p.Location {
+ l.ID = uint64(i + 1)
+ }
+ p.Function = append(p.Function, pb.Function...)
+ for i, f := range p.Function {
+ f.ID = uint64(i + 1)
+ }
+
+ if r != 1.0 {
+ for _, s := range pb.Sample {
+ for i, v := range s.Value {
+ s.Value[i] = int64((float64(v) * r))
+ }
+ }
+ }
+ p.Sample = append(p.Sample, pb.Sample...)
+ return p.CheckValid()
+}
+
+// Compatible determines if two profiles can be compared/merged.
+// returns nil if the profiles are compatible; otherwise an error with
+// details on the incompatibility.
+func (p *Profile) Compatible(pb *Profile) error {
+ if !compatibleValueTypes(p.PeriodType, pb.PeriodType) {
+ return fmt.Errorf("incompatible period types %v and %v", p.PeriodType, pb.PeriodType)
+ }
+
+ if len(p.SampleType) != len(pb.SampleType) {
+ return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType)
+ }
+
+ for i := range p.SampleType {
+ if !compatibleValueTypes(p.SampleType[i], pb.SampleType[i]) {
+ return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType)
+ }
+ }
+
+ return nil
+}
+
+// HasFunctions determines if all locations in this profile have
+// symbolized function information.
+func (p *Profile) HasFunctions() bool {
+ for _, l := range p.Location {
+ if l.Mapping == nil || !l.Mapping.HasFunctions {
+ return false
+ }
+ }
+ return true
+}
+
+// HasFileLines determines if all locations in this profile have
+// symbolized file and line number information.
+func (p *Profile) HasFileLines() bool {
+ for _, l := range p.Location {
+ if l.Mapping == nil || (!l.Mapping.HasFilenames || !l.Mapping.HasLineNumbers) {
+ return false
+ }
+ }
+ return true
+}
+
+func compatibleValueTypes(v1, v2 *ValueType) bool {
+ if v1 == nil || v2 == nil {
+ return true // No grounds to disqualify.
+ }
+ return v1.Type == v2.Type && v1.Unit == v2.Unit
+}
+
+// Copy makes a fully independent copy of a profile.
+func (p *Profile) Copy() *Profile {
+ p.preEncode()
+ b := marshal(p)
+
+ pp := &Profile{}
+ if err := unmarshal(b, pp); err != nil {
+ panic(err)
+ }
+ if err := pp.postDecode(); err != nil {
+ panic(err)
+ }
+
+ return pp
+}
+
+// Demangler maps symbol names to a human-readable form. This may
+// include C++ demangling and additional simplification. Names that
+// are not demangled may be missing from the resulting map.
+type Demangler func(name []string) (map[string]string, error)
+
+// Demangle attempts to demangle and optionally simplify any function
+// names referenced in the profile. It works on a best-effort basis:
+// it will silently preserve the original names in case of any errors.
+func (p *Profile) Demangle(d Demangler) error {
+ // Collect names to demangle.
+ var names []string
+ for _, fn := range p.Function {
+ names = append(names, fn.SystemName)
+ }
+
+ // Update profile with demangled names.
+ demangled, err := d(names)
+ if err != nil {
+ return err
+ }
+ for _, fn := range p.Function {
+ if dd, ok := demangled[fn.SystemName]; ok {
+ fn.Name = dd
+ }
+ }
+ return nil
+}
+
+// Empty reports whether the profile contains no samples.
+func (p *Profile) Empty() bool {
+ return len(p.Sample) == 0
+}
+
+// Scale multiplies all sample values in a profile by a constant.
+func (p *Profile) Scale(ratio float64) {
+ if ratio == 1 {
+ return
+ }
+ ratios := make([]float64, len(p.SampleType))
+ for i := range p.SampleType {
+ ratios[i] = ratio
+ }
+ p.ScaleN(ratios)
+}
+
+// ScaleN multiplies each sample values in a sample by a different amount.
+func (p *Profile) ScaleN(ratios []float64) error {
+ if len(p.SampleType) != len(ratios) {
+ return fmt.Errorf("mismatched scale ratios, got %d, want %d", len(ratios), len(p.SampleType))
+ }
+ allOnes := true
+ for _, r := range ratios {
+ if r != 1 {
+ allOnes = false
+ break
+ }
+ }
+ if allOnes {
+ return nil
+ }
+ for _, s := range p.Sample {
+ for i, v := range s.Value {
+ if ratios[i] != 1 {
+ s.Value[i] = int64(float64(v) * ratios[i])
+ }
+ }
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.20/src/internal/profile/proto.go b/contrib/go/_std_1.21/src/internal/profile/proto.go
index 58ff0ad2e0..58ff0ad2e0 100644
--- a/contrib/go/_std_1.20/src/internal/profile/proto.go
+++ b/contrib/go/_std_1.21/src/internal/profile/proto.go
diff --git a/contrib/go/_std_1.20/src/internal/profile/prune.go b/contrib/go/_std_1.21/src/internal/profile/prune.go
index 1924fada7a..1924fada7a 100644
--- a/contrib/go/_std_1.20/src/internal/profile/prune.go
+++ b/contrib/go/_std_1.21/src/internal/profile/prune.go
diff --git a/contrib/go/_std_1.21/src/internal/profile/ya.make b/contrib/go/_std_1.21/src/internal/profile/ya.make
new file mode 100644
index 0000000000..9eca6a0cef
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/profile/ya.make
@@ -0,0 +1,21 @@
+GO_LIBRARY()
+
+SRCS(
+ encode.go
+ filter.go
+ legacy_profile.go
+ merge.go
+ profile.go
+ proto.go
+ prune.go
+)
+
+GO_TEST_SRCS(
+ profile_test.go
+ proto_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/race/doc.go b/contrib/go/_std_1.21/src/internal/race/doc.go
index 8fa44ce6f1..8fa44ce6f1 100644
--- a/contrib/go/_std_1.20/src/internal/race/doc.go
+++ b/contrib/go/_std_1.21/src/internal/race/doc.go
diff --git a/contrib/go/_std_1.20/src/internal/race/norace.go b/contrib/go/_std_1.21/src/internal/race/norace.go
index 67b1305713..67b1305713 100644
--- a/contrib/go/_std_1.20/src/internal/race/norace.go
+++ b/contrib/go/_std_1.21/src/internal/race/norace.go
diff --git a/contrib/go/_std_1.21/src/internal/race/ya.make b/contrib/go/_std_1.21/src/internal/race/ya.make
new file mode 100644
index 0000000000..583bdcac52
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/race/ya.make
@@ -0,0 +1,24 @@
+GO_LIBRARY()
+
+SRCS(
+ doc.go
+)
+
+IF (RACE)
+ IF (CGO_ENABLED OR OS_DARWIN)
+ SRCS(
+ race.go
+ )
+ ELSE()
+ SRCS(
+ norace.go
+ )
+ ENDIF()
+ELSE()
+ SRCS(
+ norace.go
+ )
+ENDIF()
+
+
+END()
diff --git a/contrib/go/_std_1.20/src/internal/reflectlite/asm.s b/contrib/go/_std_1.21/src/internal/reflectlite/asm.s
index a7b69b65ba..a7b69b65ba 100644
--- a/contrib/go/_std_1.20/src/internal/reflectlite/asm.s
+++ b/contrib/go/_std_1.21/src/internal/reflectlite/asm.s
diff --git a/contrib/go/_std_1.21/src/internal/reflectlite/swapper.go b/contrib/go/_std_1.21/src/internal/reflectlite/swapper.go
new file mode 100644
index 0000000000..ac17d9bbc4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/reflectlite/swapper.go
@@ -0,0 +1,78 @@
+// Copyright 2016 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 reflectlite
+
+import (
+ "internal/goarch"
+ "internal/unsafeheader"
+ "unsafe"
+)
+
+// Swapper returns a function that swaps the elements in the provided
+// slice.
+//
+// Swapper panics if the provided interface is not a slice.
+func Swapper(slice any) func(i, j int) {
+ v := ValueOf(slice)
+ if v.Kind() != Slice {
+ panic(&ValueError{Method: "Swapper", Kind: v.Kind()})
+ }
+ // Fast path for slices of size 0 and 1. Nothing to swap.
+ switch v.Len() {
+ case 0:
+ return func(i, j int) { panic("reflect: slice index out of range") }
+ case 1:
+ return func(i, j int) {
+ if i != 0 || j != 0 {
+ panic("reflect: slice index out of range")
+ }
+ }
+ }
+
+ typ := v.Type().Elem().common()
+ size := typ.Size()
+ hasPtr := typ.PtrBytes != 0
+
+ // Some common & small cases, without using memmove:
+ if hasPtr {
+ if size == goarch.PtrSize {
+ ps := *(*[]unsafe.Pointer)(v.ptr)
+ return func(i, j int) { ps[i], ps[j] = ps[j], ps[i] }
+ }
+ if typ.Kind() == String {
+ ss := *(*[]string)(v.ptr)
+ return func(i, j int) { ss[i], ss[j] = ss[j], ss[i] }
+ }
+ } else {
+ switch size {
+ case 8:
+ is := *(*[]int64)(v.ptr)
+ return func(i, j int) { is[i], is[j] = is[j], is[i] }
+ case 4:
+ is := *(*[]int32)(v.ptr)
+ return func(i, j int) { is[i], is[j] = is[j], is[i] }
+ case 2:
+ is := *(*[]int16)(v.ptr)
+ return func(i, j int) { is[i], is[j] = is[j], is[i] }
+ case 1:
+ is := *(*[]int8)(v.ptr)
+ return func(i, j int) { is[i], is[j] = is[j], is[i] }
+ }
+ }
+
+ s := (*unsafeheader.Slice)(v.ptr)
+ tmp := unsafe_New(typ) // swap scratch space
+
+ return func(i, j int) {
+ if uint(i) >= uint(s.Len) || uint(j) >= uint(s.Len) {
+ panic("reflect: slice index out of range")
+ }
+ val1 := arrayAt(s.Data, i, size, "i < s.Len")
+ val2 := arrayAt(s.Data, j, size, "j < s.Len")
+ typedmemmove(typ, tmp, val1)
+ typedmemmove(typ, val1, val2)
+ typedmemmove(typ, val2, tmp)
+ }
+}
diff --git a/contrib/go/_std_1.21/src/internal/reflectlite/type.go b/contrib/go/_std_1.21/src/internal/reflectlite/type.go
new file mode 100644
index 0000000000..f13ce8fc62
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/reflectlite/type.go
@@ -0,0 +1,659 @@
+// Copyright 2009 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 reflectlite implements lightweight version of reflect, not using
+// any package except for "runtime", "unsafe", and "internal/abi"
+package reflectlite
+
+import (
+ "internal/abi"
+ "unsafe"
+)
+
+// Type is the representation of a Go type.
+//
+// Not all methods apply to all kinds of types. Restrictions,
+// if any, are noted in the documentation for each method.
+// Use the Kind method to find out the kind of type before
+// calling kind-specific methods. Calling a method
+// inappropriate to the kind of type causes a run-time panic.
+//
+// Type values are comparable, such as with the == operator,
+// so they can be used as map keys.
+// Two Type values are equal if they represent identical types.
+type Type interface {
+ // Methods applicable to all types.
+
+ // Name returns the type's name within its package for a defined type.
+ // For other (non-defined) types it returns the empty string.
+ Name() string
+
+ // PkgPath returns a defined type's package path, that is, the import path
+ // that uniquely identifies the package, such as "encoding/base64".
+ // If the type was predeclared (string, error) or not defined (*T, struct{},
+ // []int, or A where A is an alias for a non-defined type), the package path
+ // will be the empty string.
+ PkgPath() string
+
+ // Size returns the number of bytes needed to store
+ // a value of the given type; it is analogous to unsafe.Sizeof.
+ Size() uintptr
+
+ // Kind returns the specific kind of this type.
+ Kind() Kind
+
+ // Implements reports whether the type implements the interface type u.
+ Implements(u Type) bool
+
+ // AssignableTo reports whether a value of the type is assignable to type u.
+ AssignableTo(u Type) bool
+
+ // Comparable reports whether values of this type are comparable.
+ Comparable() bool
+
+ // String returns a string representation of the type.
+ // The string representation may use shortened package names
+ // (e.g., base64 instead of "encoding/base64") and is not
+ // guaranteed to be unique among types. To test for type identity,
+ // compare the Types directly.
+ String() string
+
+ // Elem returns a type's element type.
+ // It panics if the type's Kind is not Ptr.
+ Elem() Type
+
+ common() *abi.Type
+ uncommon() *uncommonType
+}
+
+/*
+ * These data structures are known to the compiler (../../cmd/internal/reflectdata/reflect.go).
+ * A few are known to ../runtime/type.go to convey to debuggers.
+ * They are also known to ../runtime/type.go.
+ */
+
+// A Kind represents the specific kind of type that a Type represents.
+// The zero Kind is not a valid kind.
+type Kind = abi.Kind
+
+const Ptr = abi.Pointer
+
+const (
+ // Import-and-export these constants as necessary
+ Interface = abi.Interface
+ Slice = abi.Slice
+ String = abi.String
+ Struct = abi.Struct
+)
+
+type nameOff = abi.NameOff
+type typeOff = abi.TypeOff
+type textOff = abi.TextOff
+
+type rtype struct {
+ *abi.Type
+}
+
+// uncommonType is present only for defined types or types with methods
+// (if T is a defined type, the uncommonTypes for T and *T have methods).
+// Using a pointer to this struct reduces the overall size required
+// to describe a non-defined type with no methods.
+type uncommonType = abi.UncommonType
+
+// arrayType represents a fixed array type.
+type arrayType = abi.ArrayType
+
+// chanType represents a channel type.
+type chanType = abi.ChanType
+
+type funcType = abi.FuncType
+
+type interfaceType = abi.InterfaceType
+
+// mapType represents a map type.
+type mapType struct {
+ rtype
+ Key *abi.Type // map key type
+ Elem *abi.Type // map element (value) type
+ Bucket *abi.Type // internal bucket structure
+ // function for hashing keys (ptr to key, seed) -> hash
+ Hasher func(unsafe.Pointer, uintptr) uintptr
+ KeySize uint8 // size of key slot
+ ValueSize uint8 // size of value slot
+ BucketSize uint16 // size of bucket
+ Flags uint32
+}
+
+// ptrType represents a pointer type.
+type ptrType = abi.PtrType
+
+// sliceType represents a slice type.
+type sliceType = abi.SliceType
+
+// structType represents a struct type.
+type structType = abi.StructType
+
+// name is an encoded type name with optional extra data.
+//
+// The first byte is a bit field containing:
+//
+// 1<<0 the name is exported
+// 1<<1 tag data follows the name
+// 1<<2 pkgPath nameOff follows the name and tag
+//
+// The next two bytes are the data length:
+//
+// l := uint16(data[1])<<8 | uint16(data[2])
+//
+// Bytes [3:3+l] are the string data.
+//
+// If tag data follows then bytes 3+l and 3+l+1 are the tag length,
+// with the data following.
+//
+// If the import path follows, then 4 bytes at the end of
+// the data form a nameOff. The import path is only set for concrete
+// methods that are defined in a different package than their type.
+//
+// If a name starts with "*", then the exported bit represents
+// whether the pointed to type is exported.
+type name struct {
+ bytes *byte
+}
+
+func (n name) data(off int, whySafe string) *byte {
+ return (*byte)(add(unsafe.Pointer(n.bytes), uintptr(off), whySafe))
+}
+
+func (n name) isExported() bool {
+ return (*n.bytes)&(1<<0) != 0
+}
+
+func (n name) hasTag() bool {
+ return (*n.bytes)&(1<<1) != 0
+}
+
+func (n name) embedded() bool {
+ return (*n.bytes)&(1<<3) != 0
+}
+
+// readVarint parses a varint as encoded by encoding/binary.
+// It returns the number of encoded bytes and the encoded value.
+func (n name) readVarint(off int) (int, int) {
+ v := 0
+ for i := 0; ; i++ {
+ x := *n.data(off+i, "read varint")
+ v += int(x&0x7f) << (7 * i)
+ if x&0x80 == 0 {
+ return i + 1, v
+ }
+ }
+}
+
+func (n name) name() string {
+ if n.bytes == nil {
+ return ""
+ }
+ i, l := n.readVarint(1)
+ return unsafe.String(n.data(1+i, "non-empty string"), l)
+}
+
+func (n name) tag() string {
+ if !n.hasTag() {
+ return ""
+ }
+ i, l := n.readVarint(1)
+ i2, l2 := n.readVarint(1 + i + l)
+ return unsafe.String(n.data(1+i+l+i2, "non-empty string"), l2)
+}
+
+func pkgPath(n abi.Name) string {
+ if n.Bytes == nil || *n.DataChecked(0, "name flag field")&(1<<2) == 0 {
+ return ""
+ }
+ i, l := n.ReadVarint(1)
+ off := 1 + i + l
+ if n.HasTag() {
+ i2, l2 := n.ReadVarint(off)
+ off += i2 + l2
+ }
+ var nameOff int32
+ // Note that this field may not be aligned in memory,
+ // so we cannot use a direct int32 assignment here.
+ copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.DataChecked(off, "name offset field")))[:])
+ pkgPathName := name{(*byte)(resolveTypeOff(unsafe.Pointer(n.Bytes), nameOff))}
+ return pkgPathName.name()
+}
+
+/*
+ * The compiler knows the exact layout of all the data structures above.
+ * The compiler does not know about the data structures and methods below.
+ */
+
+// resolveNameOff resolves a name offset from a base pointer.
+// The (*rtype).nameOff method is a convenience wrapper for this function.
+// Implemented in the runtime package.
+func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
+
+// resolveTypeOff resolves an *rtype offset from a base type.
+// The (*rtype).typeOff method is a convenience wrapper for this function.
+// Implemented in the runtime package.
+func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
+
+func (t rtype) nameOff(off nameOff) abi.Name {
+ return abi.Name{Bytes: (*byte)(resolveNameOff(unsafe.Pointer(t.Type), int32(off)))}
+}
+
+func (t rtype) typeOff(off typeOff) *abi.Type {
+ return (*abi.Type)(resolveTypeOff(unsafe.Pointer(t.Type), int32(off)))
+}
+
+func (t rtype) uncommon() *uncommonType {
+ return t.Uncommon()
+}
+
+func (t rtype) String() string {
+ s := t.nameOff(t.Str).Name()
+ if t.TFlag&abi.TFlagExtraStar != 0 {
+ return s[1:]
+ }
+ return s
+}
+
+func (t rtype) common() *abi.Type { return t.Type }
+
+func (t rtype) exportedMethods() []abi.Method {
+ ut := t.uncommon()
+ if ut == nil {
+ return nil
+ }
+ return ut.ExportedMethods()
+}
+
+func (t rtype) NumMethod() int {
+ tt := t.Type.InterfaceType()
+ if tt != nil {
+ return tt.NumMethod()
+ }
+ return len(t.exportedMethods())
+}
+
+func (t rtype) PkgPath() string {
+ if t.TFlag&abi.TFlagNamed == 0 {
+ return ""
+ }
+ ut := t.uncommon()
+ if ut == nil {
+ return ""
+ }
+ return t.nameOff(ut.PkgPath).Name()
+}
+
+func (t rtype) Name() string {
+ if !t.HasName() {
+ return ""
+ }
+ s := t.String()
+ i := len(s) - 1
+ sqBrackets := 0
+ for i >= 0 && (s[i] != '.' || sqBrackets != 0) {
+ switch s[i] {
+ case ']':
+ sqBrackets++
+ case '[':
+ sqBrackets--
+ }
+ i--
+ }
+ return s[i+1:]
+}
+
+func toRType(t *abi.Type) rtype {
+ return rtype{t}
+}
+
+func elem(t *abi.Type) *abi.Type {
+ et := t.Elem()
+ if et != nil {
+ return et
+ }
+ panic("reflect: Elem of invalid type " + toRType(t).String())
+}
+
+func (t rtype) Elem() Type {
+ return toType(elem(t.common()))
+}
+
+func (t rtype) In(i int) Type {
+ tt := t.Type.FuncType()
+ if tt == nil {
+ panic("reflect: In of non-func type")
+ }
+ return toType(tt.InSlice()[i])
+}
+
+func (t rtype) Key() Type {
+ tt := t.Type.MapType()
+ if tt == nil {
+ panic("reflect: Key of non-map type")
+ }
+ return toType(tt.Key)
+}
+
+func (t rtype) Len() int {
+ tt := t.Type.ArrayType()
+ if tt == nil {
+ panic("reflect: Len of non-array type")
+ }
+ return int(tt.Len)
+}
+
+func (t rtype) NumField() int {
+ tt := t.Type.StructType()
+ if tt == nil {
+ panic("reflect: NumField of non-struct type")
+ }
+ return len(tt.Fields)
+}
+
+func (t rtype) NumIn() int {
+ tt := t.Type.FuncType()
+ if tt == nil {
+ panic("reflect: NumIn of non-func type")
+ }
+ return int(tt.InCount)
+}
+
+func (t rtype) NumOut() int {
+ tt := t.Type.FuncType()
+ if tt == nil {
+ panic("reflect: NumOut of non-func type")
+ }
+ return tt.NumOut()
+}
+
+func (t rtype) Out(i int) Type {
+ tt := t.Type.FuncType()
+ if tt == nil {
+ panic("reflect: Out of non-func type")
+ }
+ return toType(tt.OutSlice()[i])
+}
+
+// add returns p+x.
+//
+// The whySafe string is ignored, so that the function still inlines
+// as efficiently as p+x, but all call sites should use the string to
+// record why the addition is safe, which is to say why the addition
+// does not cause x to advance to the very end of p's allocation
+// and therefore point incorrectly at the next block in memory.
+func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
+ return unsafe.Pointer(uintptr(p) + x)
+}
+
+// TypeOf returns the reflection Type that represents the dynamic type of i.
+// If i is a nil interface value, TypeOf returns nil.
+func TypeOf(i any) Type {
+ eface := *(*emptyInterface)(unsafe.Pointer(&i))
+ return toType(eface.typ)
+}
+
+func (t rtype) Implements(u Type) bool {
+ if u == nil {
+ panic("reflect: nil type passed to Type.Implements")
+ }
+ if u.Kind() != Interface {
+ panic("reflect: non-interface type passed to Type.Implements")
+ }
+ return implements(u.common(), t.common())
+}
+
+func (t rtype) AssignableTo(u Type) bool {
+ if u == nil {
+ panic("reflect: nil type passed to Type.AssignableTo")
+ }
+ uu := u.common()
+ tt := t.common()
+ return directlyAssignable(uu, tt) || implements(uu, tt)
+}
+
+func (t rtype) Comparable() bool {
+ return t.Equal != nil
+}
+
+// implements reports whether the type V implements the interface type T.
+func implements(T, V *abi.Type) bool {
+ t := T.InterfaceType()
+ if t == nil {
+ return false
+ }
+ if len(t.Methods) == 0 {
+ return true
+ }
+ rT := toRType(T)
+ rV := toRType(V)
+
+ // The same algorithm applies in both cases, but the
+ // method tables for an interface type and a concrete type
+ // are different, so the code is duplicated.
+ // In both cases the algorithm is a linear scan over the two
+ // lists - T's methods and V's methods - simultaneously.
+ // Since method tables are stored in a unique sorted order
+ // (alphabetical, with no duplicate method names), the scan
+ // through V's methods must hit a match for each of T's
+ // methods along the way, or else V does not implement T.
+ // This lets us run the scan in overall linear time instead of
+ // the quadratic time a naive search would require.
+ // See also ../runtime/iface.go.
+ if V.Kind() == Interface {
+ v := (*interfaceType)(unsafe.Pointer(V))
+ i := 0
+ for j := 0; j < len(v.Methods); j++ {
+ tm := &t.Methods[i]
+ tmName := rT.nameOff(tm.Name)
+ vm := &v.Methods[j]
+ vmName := rV.nameOff(vm.Name)
+ if vmName.Name() == tmName.Name() && rV.typeOff(vm.Typ) == rT.typeOff(tm.Typ) {
+ if !tmName.IsExported() {
+ tmPkgPath := pkgPath(tmName)
+ if tmPkgPath == "" {
+ tmPkgPath = t.PkgPath.Name()
+ }
+ vmPkgPath := pkgPath(vmName)
+ if vmPkgPath == "" {
+ vmPkgPath = v.PkgPath.Name()
+ }
+ if tmPkgPath != vmPkgPath {
+ continue
+ }
+ }
+ if i++; i >= len(t.Methods) {
+ return true
+ }
+ }
+ }
+ return false
+ }
+
+ v := V.Uncommon()
+ if v == nil {
+ return false
+ }
+ i := 0
+ vmethods := v.Methods()
+ for j := 0; j < int(v.Mcount); j++ {
+ tm := &t.Methods[i]
+ tmName := rT.nameOff(tm.Name)
+ vm := vmethods[j]
+ vmName := rV.nameOff(vm.Name)
+ if vmName.Name() == tmName.Name() && rV.typeOff(vm.Mtyp) == rT.typeOff(tm.Typ) {
+ if !tmName.IsExported() {
+ tmPkgPath := pkgPath(tmName)
+ if tmPkgPath == "" {
+ tmPkgPath = t.PkgPath.Name()
+ }
+ vmPkgPath := pkgPath(vmName)
+ if vmPkgPath == "" {
+ vmPkgPath = rV.nameOff(v.PkgPath).Name()
+ }
+ if tmPkgPath != vmPkgPath {
+ continue
+ }
+ }
+ if i++; i >= len(t.Methods) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// directlyAssignable reports whether a value x of type V can be directly
+// assigned (using memmove) to a value of type T.
+// https://golang.org/doc/go_spec.html#Assignability
+// Ignoring the interface rules (implemented elsewhere)
+// and the ideal constant rules (no ideal constants at run time).
+func directlyAssignable(T, V *abi.Type) bool {
+ // x's type V is identical to T?
+ if T == V {
+ return true
+ }
+
+ // Otherwise at least one of T and V must not be defined
+ // and they must have the same kind.
+ if T.HasName() && V.HasName() || T.Kind() != V.Kind() {
+ return false
+ }
+
+ // x's type T and V must have identical underlying types.
+ return haveIdenticalUnderlyingType(T, V, true)
+}
+
+func haveIdenticalType(T, V *abi.Type, cmpTags bool) bool {
+ if cmpTags {
+ return T == V
+ }
+
+ if toRType(T).Name() != toRType(V).Name() || T.Kind() != V.Kind() {
+ return false
+ }
+
+ return haveIdenticalUnderlyingType(T, V, false)
+}
+
+func haveIdenticalUnderlyingType(T, V *abi.Type, cmpTags bool) bool {
+ if T == V {
+ return true
+ }
+
+ kind := T.Kind()
+ if kind != V.Kind() {
+ return false
+ }
+
+ // Non-composite types of equal kind have same underlying type
+ // (the predefined instance of the type).
+ if abi.Bool <= kind && kind <= abi.Complex128 || kind == abi.String || kind == abi.UnsafePointer {
+ return true
+ }
+
+ // Composite types.
+ switch kind {
+ case abi.Array:
+ return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
+
+ case abi.Chan:
+ // Special case:
+ // x is a bidirectional channel value, T is a channel type,
+ // and x's type V and T have identical element types.
+ if V.ChanDir() == abi.BothDir && haveIdenticalType(T.Elem(), V.Elem(), cmpTags) {
+ return true
+ }
+
+ // Otherwise continue test for identical underlying type.
+ return V.ChanDir() == T.ChanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
+
+ case abi.Func:
+ t := (*funcType)(unsafe.Pointer(T))
+ v := (*funcType)(unsafe.Pointer(V))
+ if t.OutCount != v.OutCount || t.InCount != v.InCount {
+ return false
+ }
+ for i := 0; i < t.NumIn(); i++ {
+ if !haveIdenticalType(t.In(i), v.In(i), cmpTags) {
+ return false
+ }
+ }
+ for i := 0; i < t.NumOut(); i++ {
+ if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) {
+ return false
+ }
+ }
+ return true
+
+ case Interface:
+ t := (*interfaceType)(unsafe.Pointer(T))
+ v := (*interfaceType)(unsafe.Pointer(V))
+ if len(t.Methods) == 0 && len(v.Methods) == 0 {
+ return true
+ }
+ // Might have the same methods but still
+ // need a run time conversion.
+ return false
+
+ case abi.Map:
+ return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
+
+ case Ptr, abi.Slice:
+ return haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
+
+ case abi.Struct:
+ t := (*structType)(unsafe.Pointer(T))
+ v := (*structType)(unsafe.Pointer(V))
+ if len(t.Fields) != len(v.Fields) {
+ return false
+ }
+ if t.PkgPath.Name() != v.PkgPath.Name() {
+ return false
+ }
+ for i := range t.Fields {
+ tf := &t.Fields[i]
+ vf := &v.Fields[i]
+ if tf.Name.Name() != vf.Name.Name() {
+ return false
+ }
+ if !haveIdenticalType(tf.Typ, vf.Typ, cmpTags) {
+ return false
+ }
+ if cmpTags && tf.Name.Tag() != vf.Name.Tag() {
+ return false
+ }
+ if tf.Offset != vf.Offset {
+ return false
+ }
+ if tf.Embedded() != vf.Embedded() {
+ return false
+ }
+ }
+ return true
+ }
+
+ return false
+}
+
+// toType converts from a *rtype to a Type that can be returned
+// to the client of package reflect. In gc, the only concern is that
+// a nil *rtype must be replaced by a nil Type, but in gccgo this
+// function takes care of ensuring that multiple *rtype for the same
+// type are coalesced into a single Type.
+func toType(t *abi.Type) Type {
+ if t == nil {
+ return nil
+ }
+ return toRType(t)
+}
+
+// ifaceIndir reports whether t is stored indirectly in an interface value.
+func ifaceIndir(t *abi.Type) bool {
+ return t.Kind_&abi.KindDirectIface == 0
+}
diff --git a/contrib/go/_std_1.21/src/internal/reflectlite/value.go b/contrib/go/_std_1.21/src/internal/reflectlite/value.go
new file mode 100644
index 0000000000..eb79894842
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/reflectlite/value.go
@@ -0,0 +1,478 @@
+// Copyright 2009 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 reflectlite
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "internal/unsafeheader"
+ "runtime"
+ "unsafe"
+)
+
+// Value is the reflection interface to a Go value.
+//
+// Not all methods apply to all kinds of values. Restrictions,
+// if any, are noted in the documentation for each method.
+// Use the Kind method to find out the kind of value before
+// calling kind-specific methods. Calling a method
+// inappropriate to the kind of type causes a run time panic.
+//
+// The zero Value represents no value.
+// Its IsValid method returns false, its Kind method returns Invalid,
+// its String method returns "<invalid Value>", and all other methods panic.
+// Most functions and methods never return an invalid value.
+// If one does, its documentation states the conditions explicitly.
+//
+// A Value can be used concurrently by multiple goroutines provided that
+// the underlying Go value can be used concurrently for the equivalent
+// direct operations.
+//
+// To compare two Values, compare the results of the Interface method.
+// Using == on two Values does not compare the underlying values
+// they represent.
+type Value struct {
+ // typ holds the type of the value represented by a Value.
+ typ *abi.Type
+
+ // Pointer-valued data or, if flagIndir is set, pointer to data.
+ // Valid when either flagIndir is set or typ.pointers() is true.
+ ptr unsafe.Pointer
+
+ // flag holds metadata about the value.
+ // The lowest bits are flag bits:
+ // - flagStickyRO: obtained via unexported not embedded field, so read-only
+ // - flagEmbedRO: obtained via unexported embedded field, so read-only
+ // - flagIndir: val holds a pointer to the data
+ // - flagAddr: v.CanAddr is true (implies flagIndir)
+ // Value cannot represent method values.
+ // The next five bits give the Kind of the value.
+ // This repeats typ.Kind() except for method values.
+ // The remaining 23+ bits give a method number for method values.
+ // If flag.kind() != Func, code can assume that flagMethod is unset.
+ // If ifaceIndir(typ), code can assume that flagIndir is set.
+ flag
+
+ // A method value represents a curried method invocation
+ // like r.Read for some receiver r. The typ+val+flag bits describe
+ // the receiver r, but the flag's Kind bits say Func (methods are
+ // functions), and the top bits of the flag give the method number
+ // in r's type's method table.
+}
+
+type flag uintptr
+
+const (
+ flagKindWidth = 5 // there are 27 kinds
+ flagKindMask flag = 1<<flagKindWidth - 1
+ flagStickyRO flag = 1 << 5
+ flagEmbedRO flag = 1 << 6
+ flagIndir flag = 1 << 7
+ flagAddr flag = 1 << 8
+ flagMethod flag = 1 << 9
+ flagMethodShift = 10
+ flagRO flag = flagStickyRO | flagEmbedRO
+)
+
+func (f flag) kind() Kind {
+ return Kind(f & flagKindMask)
+}
+
+func (f flag) ro() flag {
+ if f&flagRO != 0 {
+ return flagStickyRO
+ }
+ return 0
+}
+
+// pointer returns the underlying pointer represented by v.
+// v.Kind() must be Pointer, Map, Chan, Func, or UnsafePointer
+func (v Value) pointer() unsafe.Pointer {
+ if v.typ.Size() != goarch.PtrSize || !v.typ.Pointers() {
+ panic("can't call pointer on a non-pointer Value")
+ }
+ if v.flag&flagIndir != 0 {
+ return *(*unsafe.Pointer)(v.ptr)
+ }
+ return v.ptr
+}
+
+// packEface converts v to the empty interface.
+func packEface(v Value) any {
+ t := v.typ
+ var i any
+ e := (*emptyInterface)(unsafe.Pointer(&i))
+ // First, fill in the data portion of the interface.
+ switch {
+ case ifaceIndir(t):
+ if v.flag&flagIndir == 0 {
+ panic("bad indir")
+ }
+ // Value is indirect, and so is the interface we're making.
+ ptr := v.ptr
+ if v.flag&flagAddr != 0 {
+ // TODO: pass safe boolean from valueInterface so
+ // we don't need to copy if safe==true?
+ c := unsafe_New(t)
+ typedmemmove(t, c, ptr)
+ ptr = c
+ }
+ e.word = ptr
+ case v.flag&flagIndir != 0:
+ // Value is indirect, but interface is direct. We need
+ // to load the data at v.ptr into the interface data word.
+ e.word = *(*unsafe.Pointer)(v.ptr)
+ default:
+ // Value is direct, and so is the interface.
+ e.word = v.ptr
+ }
+ // Now, fill in the type portion. We're very careful here not
+ // to have any operation between the e.word and e.typ assignments
+ // that would let the garbage collector observe the partially-built
+ // interface value.
+ e.typ = t
+ return i
+}
+
+// unpackEface converts the empty interface i to a Value.
+func unpackEface(i any) Value {
+ e := (*emptyInterface)(unsafe.Pointer(&i))
+ // NOTE: don't read e.word until we know whether it is really a pointer or not.
+ t := e.typ
+ if t == nil {
+ return Value{}
+ }
+ f := flag(t.Kind())
+ if ifaceIndir(t) {
+ f |= flagIndir
+ }
+ return Value{t, e.word, f}
+}
+
+// A ValueError occurs when a Value method is invoked on
+// a Value that does not support it. Such cases are documented
+// in the description of each method.
+type ValueError struct {
+ Method string
+ Kind Kind
+}
+
+func (e *ValueError) Error() string {
+ if e.Kind == 0 {
+ return "reflect: call of " + e.Method + " on zero Value"
+ }
+ return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
+}
+
+// methodName returns the name of the calling method,
+// assumed to be two stack frames above.
+func methodName() string {
+ pc, _, _, _ := runtime.Caller(2)
+ f := runtime.FuncForPC(pc)
+ if f == nil {
+ return "unknown method"
+ }
+ return f.Name()
+}
+
+// emptyInterface is the header for an interface{} value.
+type emptyInterface struct {
+ typ *abi.Type
+ word unsafe.Pointer
+}
+
+// mustBeExported panics if f records that the value was obtained using
+// an unexported field.
+func (f flag) mustBeExported() {
+ if f == 0 {
+ panic(&ValueError{methodName(), 0})
+ }
+ if f&flagRO != 0 {
+ panic("reflect: " + methodName() + " using value obtained using unexported field")
+ }
+}
+
+// mustBeAssignable panics if f records that the value is not assignable,
+// which is to say that either it was obtained using an unexported field
+// or it is not addressable.
+func (f flag) mustBeAssignable() {
+ if f == 0 {
+ panic(&ValueError{methodName(), abi.Invalid})
+ }
+ // Assignable if addressable and not read-only.
+ if f&flagRO != 0 {
+ panic("reflect: " + methodName() + " using value obtained using unexported field")
+ }
+ if f&flagAddr == 0 {
+ panic("reflect: " + methodName() + " using unaddressable value")
+ }
+}
+
+// CanSet reports whether the value of v can be changed.
+// A Value can be changed only if it is addressable and was not
+// obtained by the use of unexported struct fields.
+// If CanSet returns false, calling Set or any type-specific
+// setter (e.g., SetBool, SetInt) will panic.
+func (v Value) CanSet() bool {
+ return v.flag&(flagAddr|flagRO) == flagAddr
+}
+
+// Elem returns the value that the interface v contains
+// or that the pointer v points to.
+// It panics if v's Kind is not Interface or Pointer.
+// It returns the zero Value if v is nil.
+func (v Value) Elem() Value {
+ k := v.kind()
+ switch k {
+ case abi.Interface:
+ var eface any
+ if v.typ.NumMethod() == 0 {
+ eface = *(*any)(v.ptr)
+ } else {
+ eface = (any)(*(*interface {
+ M()
+ })(v.ptr))
+ }
+ x := unpackEface(eface)
+ if x.flag != 0 {
+ x.flag |= v.flag.ro()
+ }
+ return x
+ case abi.Pointer:
+ ptr := v.ptr
+ if v.flag&flagIndir != 0 {
+ ptr = *(*unsafe.Pointer)(ptr)
+ }
+ // The returned value's address is v's value.
+ if ptr == nil {
+ return Value{}
+ }
+ tt := (*ptrType)(unsafe.Pointer(v.typ))
+ typ := tt.Elem
+ fl := v.flag&flagRO | flagIndir | flagAddr
+ fl |= flag(typ.Kind())
+ return Value{typ, ptr, fl}
+ }
+ panic(&ValueError{"reflectlite.Value.Elem", v.kind()})
+}
+
+func valueInterface(v Value) any {
+ if v.flag == 0 {
+ panic(&ValueError{"reflectlite.Value.Interface", 0})
+ }
+
+ if v.kind() == abi.Interface {
+ // Special case: return the element inside the interface.
+ // Empty interface has one layout, all interfaces with
+ // methods have a second layout.
+ if v.numMethod() == 0 {
+ return *(*any)(v.ptr)
+ }
+ return *(*interface {
+ M()
+ })(v.ptr)
+ }
+
+ // TODO: pass safe to packEface so we don't need to copy if safe==true?
+ return packEface(v)
+}
+
+// IsNil reports whether its argument v is nil. The argument must be
+// a chan, func, interface, map, pointer, or slice value; if it is
+// not, IsNil panics. Note that IsNil is not always equivalent to a
+// regular comparison with nil in Go. For example, if v was created
+// by calling ValueOf with an uninitialized interface variable i,
+// i==nil will be true but v.IsNil will panic as v will be the zero
+// Value.
+func (v Value) IsNil() bool {
+ k := v.kind()
+ switch k {
+ case abi.Chan, abi.Func, abi.Map, abi.Pointer, abi.UnsafePointer:
+ // if v.flag&flagMethod != 0 {
+ // return false
+ // }
+ ptr := v.ptr
+ if v.flag&flagIndir != 0 {
+ ptr = *(*unsafe.Pointer)(ptr)
+ }
+ return ptr == nil
+ case abi.Interface, abi.Slice:
+ // Both interface and slice are nil if first word is 0.
+ // Both are always bigger than a word; assume flagIndir.
+ return *(*unsafe.Pointer)(v.ptr) == nil
+ }
+ panic(&ValueError{"reflectlite.Value.IsNil", v.kind()})
+}
+
+// IsValid reports whether v represents a value.
+// It returns false if v is the zero Value.
+// If IsValid returns false, all other methods except String panic.
+// Most functions and methods never return an invalid Value.
+// If one does, its documentation states the conditions explicitly.
+func (v Value) IsValid() bool {
+ return v.flag != 0
+}
+
+// Kind returns v's Kind.
+// If v is the zero Value (IsValid returns false), Kind returns Invalid.
+func (v Value) Kind() Kind {
+ return v.kind()
+}
+
+// implemented in runtime:
+func chanlen(unsafe.Pointer) int
+func maplen(unsafe.Pointer) int
+
+// Len returns v's length.
+// It panics if v's Kind is not Array, Chan, Map, Slice, or String.
+func (v Value) Len() int {
+ k := v.kind()
+ switch k {
+ case abi.Array:
+ tt := (*arrayType)(unsafe.Pointer(v.typ))
+ return int(tt.Len)
+ case abi.Chan:
+ return chanlen(v.pointer())
+ case abi.Map:
+ return maplen(v.pointer())
+ case abi.Slice:
+ // Slice is bigger than a word; assume flagIndir.
+ return (*unsafeheader.Slice)(v.ptr).Len
+ case abi.String:
+ // String is bigger than a word; assume flagIndir.
+ return (*unsafeheader.String)(v.ptr).Len
+ }
+ panic(&ValueError{"reflect.Value.Len", v.kind()})
+}
+
+// NumMethod returns the number of exported methods in the value's method set.
+func (v Value) numMethod() int {
+ if v.typ == nil {
+ panic(&ValueError{"reflectlite.Value.NumMethod", abi.Invalid})
+ }
+ return v.typ.NumMethod()
+}
+
+// Set assigns x to the value v.
+// It panics if CanSet returns false.
+// As in Go, x's value must be assignable to v's type.
+func (v Value) Set(x Value) {
+ v.mustBeAssignable()
+ x.mustBeExported() // do not let unexported x leak
+ var target unsafe.Pointer
+ if v.kind() == abi.Interface {
+ target = v.ptr
+ }
+ x = x.assignTo("reflectlite.Set", v.typ, target)
+ if x.flag&flagIndir != 0 {
+ typedmemmove(v.typ, v.ptr, x.ptr)
+ } else {
+ *(*unsafe.Pointer)(v.ptr) = x.ptr
+ }
+}
+
+// Type returns v's type.
+func (v Value) Type() Type {
+ f := v.flag
+ if f == 0 {
+ panic(&ValueError{"reflectlite.Value.Type", abi.Invalid})
+ }
+ // Method values not supported.
+ return toRType(v.typ)
+}
+
+/*
+ * constructors
+ */
+
+// implemented in package runtime
+func unsafe_New(*abi.Type) unsafe.Pointer
+
+// ValueOf returns a new Value initialized to the concrete value
+// stored in the interface i. ValueOf(nil) returns the zero Value.
+func ValueOf(i any) Value {
+ if i == nil {
+ return Value{}
+ }
+
+ // TODO: Maybe allow contents of a Value to live on the stack.
+ // For now we make the contents always escape to the heap. It
+ // makes life easier in a few places (see chanrecv/mapassign
+ // comment below).
+ escapes(i)
+
+ return unpackEface(i)
+}
+
+// assignTo returns a value v that can be assigned directly to typ.
+// It panics if v is not assignable to typ.
+// For a conversion to an interface type, target is a suggested scratch space to use.
+func (v Value) assignTo(context string, dst *abi.Type, target unsafe.Pointer) Value {
+ // if v.flag&flagMethod != 0 {
+ // v = makeMethodValue(context, v)
+ // }
+
+ switch {
+ case directlyAssignable(dst, v.typ):
+ // Overwrite type so that they match.
+ // Same memory layout, so no harm done.
+ fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
+ fl |= flag(dst.Kind())
+ return Value{dst, v.ptr, fl}
+
+ case implements(dst, v.typ):
+ if target == nil {
+ target = unsafe_New(dst)
+ }
+ if v.Kind() == abi.Interface && v.IsNil() {
+ // A nil ReadWriter passed to nil Reader is OK,
+ // but using ifaceE2I below will panic.
+ // Avoid the panic by returning a nil dst (e.g., Reader) explicitly.
+ return Value{dst, nil, flag(abi.Interface)}
+ }
+ x := valueInterface(v)
+ if dst.NumMethod() == 0 {
+ *(*any)(target) = x
+ } else {
+ ifaceE2I(dst, x, target)
+ }
+ return Value{dst, target, flagIndir | flag(abi.Interface)}
+ }
+
+ // Failed.
+ panic(context + ": value of type " + toRType(v.typ).String() + " is not assignable to type " + toRType(dst).String())
+}
+
+// arrayAt returns the i-th element of p,
+// an array whose elements are eltSize bytes wide.
+// The array pointed at by p must have at least i+1 elements:
+// it is invalid (but impossible to check here) to pass i >= len,
+// because then the result will point outside the array.
+// whySafe must explain why i < len. (Passing "i < len" is fine;
+// the benefit is to surface this assumption at the call site.)
+func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
+ return add(p, uintptr(i)*eltSize, "i < len")
+}
+
+func ifaceE2I(t *abi.Type, src any, dst unsafe.Pointer)
+
+// typedmemmove copies a value of type t to dst from src.
+//
+//go:noescape
+func typedmemmove(t *abi.Type, dst, src unsafe.Pointer)
+
+// Dummy annotation marking that the value x escapes,
+// for use in cases where the reflect code is so clever that
+// the compiler cannot follow.
+func escapes(x any) {
+ if dummy.b {
+ dummy.x = x
+ }
+}
+
+var dummy struct {
+ b bool
+ x any
+}
diff --git a/contrib/go/_std_1.21/src/internal/reflectlite/ya.make b/contrib/go/_std_1.21/src/internal/reflectlite/ya.make
new file mode 100644
index 0000000000..522f75df00
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/reflectlite/ya.make
@@ -0,0 +1,22 @@
+GO_LIBRARY()
+
+SRCS(
+ asm.s
+ swapper.go
+ type.go
+ value.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ all_test.go
+ reflect_mirror_test.go
+ set_test.go
+ tostring_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/safefilepath/path.go b/contrib/go/_std_1.21/src/internal/safefilepath/path.go
index 0f0a270c30..0f0a270c30 100644
--- a/contrib/go/_std_1.20/src/internal/safefilepath/path.go
+++ b/contrib/go/_std_1.21/src/internal/safefilepath/path.go
diff --git a/contrib/go/_std_1.20/src/internal/safefilepath/path_other.go b/contrib/go/_std_1.21/src/internal/safefilepath/path_other.go
index 974e7751a2..974e7751a2 100644
--- a/contrib/go/_std_1.20/src/internal/safefilepath/path_other.go
+++ b/contrib/go/_std_1.21/src/internal/safefilepath/path_other.go
diff --git a/contrib/go/_std_1.20/src/internal/safefilepath/path_windows.go b/contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go
index 909c150edc..909c150edc 100644
--- a/contrib/go/_std_1.20/src/internal/safefilepath/path_windows.go
+++ b/contrib/go/_std_1.21/src/internal/safefilepath/path_windows.go
diff --git a/contrib/go/_std_1.21/src/internal/safefilepath/ya.make b/contrib/go/_std_1.21/src/internal/safefilepath/ya.make
new file mode 100644
index 0000000000..e295083570
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/safefilepath/ya.make
@@ -0,0 +1,30 @@
+GO_LIBRARY()
+
+SRCS(
+ path.go
+)
+
+GO_XTEST_SRCS(path_test.go)
+
+IF (OS_LINUX)
+ SRCS(
+ path_other.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ path_other.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ path_windows.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/saferio/io.go b/contrib/go/_std_1.21/src/internal/saferio/io.go
index 66cc044c74..66cc044c74 100644
--- a/contrib/go/_std_1.20/src/internal/saferio/io.go
+++ b/contrib/go/_std_1.21/src/internal/saferio/io.go
diff --git a/contrib/go/_std_1.21/src/internal/saferio/ya.make b/contrib/go/_std_1.21/src/internal/saferio/ya.make
new file mode 100644
index 0000000000..88c409fd91
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/saferio/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ io.go
+)
+
+GO_TEST_SRCS(io_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/singleflight/singleflight.go b/contrib/go/_std_1.21/src/internal/singleflight/singleflight.go
index d0e6d2f84a..d0e6d2f84a 100644
--- a/contrib/go/_std_1.20/src/internal/singleflight/singleflight.go
+++ b/contrib/go/_std_1.21/src/internal/singleflight/singleflight.go
diff --git a/contrib/go/_std_1.21/src/internal/singleflight/ya.make b/contrib/go/_std_1.21/src/internal/singleflight/ya.make
new file mode 100644
index 0000000000..9d1db31207
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/singleflight/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ singleflight.go
+)
+
+GO_TEST_SRCS(singleflight_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/syscall/execenv/execenv_default.go b/contrib/go/_std_1.21/src/internal/syscall/execenv/execenv_default.go
index 335647c638..335647c638 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/execenv/execenv_default.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/execenv/execenv_default.go
diff --git a/contrib/go/_std_1.21/src/internal/syscall/execenv/execenv_windows.go b/contrib/go/_std_1.21/src/internal/syscall/execenv/execenv_windows.go
new file mode 100644
index 0000000000..2a89ed1f58
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/execenv/execenv_windows.go
@@ -0,0 +1,47 @@
+// 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.
+
+//go:build windows
+
+package execenv
+
+import (
+ "internal/syscall/windows"
+ "syscall"
+ "unsafe"
+)
+
+// Default will return the default environment
+// variables based on the process attributes
+// provided.
+//
+// If the process attributes contain a token, then
+// the environment variables will be sourced from
+// the defaults for that user token, otherwise they
+// will be sourced from syscall.Environ().
+func Default(sys *syscall.SysProcAttr) (env []string, err error) {
+ if sys == nil || sys.Token == 0 {
+ return syscall.Environ(), nil
+ }
+ var blockp *uint16
+ err = windows.CreateEnvironmentBlock(&blockp, sys.Token, false)
+ if err != nil {
+ return nil, err
+ }
+ defer windows.DestroyEnvironmentBlock(blockp)
+
+ const size = unsafe.Sizeof(*blockp)
+ for *blockp != 0 { // environment block ends with empty string
+ // find NUL terminator
+ end := unsafe.Add(unsafe.Pointer(blockp), size)
+ for *(*uint16)(end) != 0 {
+ end = unsafe.Add(end, size)
+ }
+
+ entry := unsafe.Slice(blockp, (uintptr(end)-uintptr(unsafe.Pointer(blockp)))/2)
+ env = append(env, syscall.UTF16ToString(entry))
+ blockp = (*uint16)(unsafe.Add(end, size))
+ }
+ return
+}
diff --git a/contrib/go/_std_1.21/src/internal/syscall/execenv/ya.make b/contrib/go/_std_1.21/src/internal/syscall/execenv/ya.make
new file mode 100644
index 0000000000..9cb1fb5ed7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/execenv/ya.make
@@ -0,0 +1,21 @@
+GO_LIBRARY()
+
+IF (OS_LINUX)
+ SRCS(
+ execenv_default.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ execenv_default.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ execenv_windows.go
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/asm_darwin.s b/contrib/go/_std_1.21/src/internal/syscall/unix/asm_darwin.s
index 8662c2846f..8662c2846f 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/asm_darwin.s
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/asm_darwin.s
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/at.go b/contrib/go/_std_1.21/src/internal/syscall/unix/at.go
index cfb6e410b1..cfb6e410b1 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/at.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/at.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/at_fstatat.go b/contrib/go/_std_1.21/src/internal/syscall/unix/at_fstatat.go
index 8f25fe9f64..8f25fe9f64 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/at_fstatat.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/at_fstatat.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/at_libc2.go b/contrib/go/_std_1.21/src/internal/syscall/unix/at_libc2.go
index 4eeb7717ed..4eeb7717ed 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/at_libc2.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/at_libc2.go
diff --git a/contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_darwin.go b/contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_darwin.go
new file mode 100644
index 0000000000..208ff34d03
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_darwin.go
@@ -0,0 +1,10 @@
+// Copyright 2018 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 unix
+
+const AT_REMOVEDIR = 0x80
+const AT_SYMLINK_NOFOLLOW = 0x0020
+
+const UTIME_OMIT = -0x2
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_fstatat_linux.go b/contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_fstatat_linux.go
index 73a3da5bff..73a3da5bff 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_fstatat_linux.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_fstatat_linux.go
diff --git a/contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_linux.go b/contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_linux.go
new file mode 100644
index 0000000000..7c3b15c303
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_linux.go
@@ -0,0 +1,19 @@
+// Copyright 2018 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 unix
+
+import "syscall"
+
+const unlinkatTrap uintptr = syscall.SYS_UNLINKAT
+const openatTrap uintptr = syscall.SYS_OPENAT
+
+const (
+ AT_EACCESS = 0x200
+ AT_FDCWD = -0x64
+ AT_REMOVEDIR = 0x200
+ AT_SYMLINK_NOFOLLOW = 0x100
+
+ UTIME_OMIT = 0x3ffffffe
+)
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go b/contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go
index 76edf67522..76edf67522 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/constants.go b/contrib/go/_std_1.21/src/internal/syscall/unix/constants.go
index e324589705..e324589705 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/constants.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/constants.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/copy_file_range_linux.go b/contrib/go/_std_1.21/src/internal/syscall/unix/copy_file_range_linux.go
index cf0a279a7a..cf0a279a7a 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/copy_file_range_linux.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/copy_file_range_linux.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/eaccess_linux.go b/contrib/go/_std_1.21/src/internal/syscall/unix/eaccess_linux.go
index 5695a5e4ce..5695a5e4ce 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/eaccess_linux.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/eaccess_linux.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/eaccess_other.go b/contrib/go/_std_1.21/src/internal/syscall/unix/eaccess_other.go
index 23be118297..23be118297 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/eaccess_other.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/eaccess_other.go
diff --git a/contrib/go/_std_1.21/src/internal/syscall/unix/fcntl_unix.go b/contrib/go/_std_1.21/src/internal/syscall/unix/fcntl_unix.go
new file mode 100644
index 0000000000..8422637dac
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/fcntl_unix.go
@@ -0,0 +1,26 @@
+// Copyright 2023 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.
+
+//go:build unix
+
+package unix
+
+import (
+ "syscall"
+ _ "unsafe" // for go:linkname
+
+)
+
+// Implemented in the runtime package.
+//
+//go:linkname fcntl runtime.fcntl
+func fcntl(fd int32, cmd int32, arg int32) (int32, int32)
+
+func Fcntl(fd int, cmd int, arg int) (int, error) {
+ val, errno := fcntl(int32(fd), int32(cmd), int32(arg))
+ if val == -1 {
+ return int(val), syscall.Errno(errno)
+ }
+ return int(val), nil
+}
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/getentropy_darwin.go b/contrib/go/_std_1.21/src/internal/syscall/unix/getentropy_darwin.go
index 834099ffed..834099ffed 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/getentropy_darwin.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/getentropy_darwin.go
diff --git a/contrib/go/_std_1.21/src/internal/syscall/unix/getrandom.go b/contrib/go/_std_1.21/src/internal/syscall/unix/getrandom.go
new file mode 100644
index 0000000000..e83f0cd6f9
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/getrandom.go
@@ -0,0 +1,39 @@
+// 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.
+
+//go:build dragonfly || freebsd || linux
+
+package unix
+
+import (
+ "sync/atomic"
+ "syscall"
+ "unsafe"
+)
+
+var getrandomUnsupported atomic.Bool
+
+// GetRandomFlag is a flag supported by the getrandom system call.
+type GetRandomFlag uintptr
+
+// GetRandom calls the getrandom system call.
+func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) {
+ if len(p) == 0 {
+ return 0, nil
+ }
+ if getrandomUnsupported.Load() {
+ return 0, syscall.ENOSYS
+ }
+ r1, _, errno := syscall.Syscall(getrandomTrap,
+ uintptr(unsafe.Pointer(&p[0])),
+ uintptr(len(p)),
+ uintptr(flags))
+ if errno != 0 {
+ if errno == syscall.ENOSYS {
+ getrandomUnsupported.Store(true)
+ }
+ return 0, errno
+ }
+ return int(r1), nil
+}
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/getrandom_linux.go b/contrib/go/_std_1.21/src/internal/syscall/unix/getrandom_linux.go
index 8ccd8d328a..8ccd8d328a 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/getrandom_linux.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/getrandom_linux.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/kernel_version_linux.go b/contrib/go/_std_1.21/src/internal/syscall/unix/kernel_version_linux.go
index 71e8aa4c57..71e8aa4c57 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/kernel_version_linux.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/kernel_version_linux.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/kernel_version_other.go b/contrib/go/_std_1.21/src/internal/syscall/unix/kernel_version_other.go
index 00af9f2ba0..00af9f2ba0 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/kernel_version_other.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/kernel_version_other.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/net.go b/contrib/go/_std_1.21/src/internal/syscall/unix/net.go
index 5618d40ae0..5618d40ae0 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/net.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/net.go
diff --git a/contrib/go/_std_1.21/src/internal/syscall/unix/net_darwin.go b/contrib/go/_std_1.21/src/internal/syscall/unix/net_darwin.go
new file mode 100644
index 0000000000..5601b49750
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/net_darwin.go
@@ -0,0 +1,162 @@
+// Copyright 2022 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 unix
+
+import (
+ "internal/abi"
+ "syscall"
+ "unsafe"
+)
+
+const (
+ AI_CANONNAME = 0x2
+ AI_ALL = 0x100
+ AI_V4MAPPED = 0x800
+ AI_MASK = 0x1407
+
+ EAI_AGAIN = 2
+ EAI_NODATA = 7
+ EAI_NONAME = 8
+ EAI_SYSTEM = 11
+ EAI_OVERFLOW = 14
+
+ NI_NAMEREQD = 4
+)
+
+type Addrinfo struct {
+ Flags int32
+ Family int32
+ Socktype int32
+ Protocol int32
+ Addrlen uint32
+ Canonname *byte
+ Addr *syscall.RawSockaddr
+ Next *Addrinfo
+}
+
+//go:cgo_ldflag "-lresolv"
+
+//go:cgo_import_dynamic libc_getaddrinfo getaddrinfo "/usr/lib/libSystem.B.dylib"
+func libc_getaddrinfo_trampoline()
+
+func Getaddrinfo(hostname, servname *byte, hints *Addrinfo, res **Addrinfo) (int, error) {
+ gerrno, _, errno := syscall_syscall6(abi.FuncPCABI0(libc_getaddrinfo_trampoline),
+ uintptr(unsafe.Pointer(hostname)),
+ uintptr(unsafe.Pointer(servname)),
+ uintptr(unsafe.Pointer(hints)),
+ uintptr(unsafe.Pointer(res)),
+ 0,
+ 0)
+ var err error
+ if errno != 0 {
+ err = errno
+ }
+ return int(gerrno), err
+}
+
+//go:cgo_import_dynamic libc_freeaddrinfo freeaddrinfo "/usr/lib/libSystem.B.dylib"
+func libc_freeaddrinfo_trampoline()
+
+func Freeaddrinfo(ai *Addrinfo) {
+ syscall_syscall6(abi.FuncPCABI0(libc_freeaddrinfo_trampoline),
+ uintptr(unsafe.Pointer(ai)),
+ 0, 0, 0, 0, 0)
+}
+
+//go:cgo_import_dynamic libc_getnameinfo getnameinfo "/usr/lib/libSystem.B.dylib"
+func libc_getnameinfo_trampoline()
+
+func Getnameinfo(sa *syscall.RawSockaddr, salen int, host *byte, hostlen int, serv *byte, servlen int, flags int) (int, error) {
+ gerrno, _, errno := syscall_syscall9(abi.FuncPCABI0(libc_getnameinfo_trampoline),
+ uintptr(unsafe.Pointer(sa)),
+ uintptr(salen),
+ uintptr(unsafe.Pointer(host)),
+ uintptr(hostlen),
+ uintptr(unsafe.Pointer(serv)),
+ uintptr(servlen),
+ uintptr(flags),
+ 0,
+ 0)
+ var err error
+ if errno != 0 {
+ err = errno
+ }
+ return int(gerrno), err
+}
+
+//go:cgo_import_dynamic libc_gai_strerror gai_strerror "/usr/lib/libSystem.B.dylib"
+func libc_gai_strerror_trampoline()
+
+func GaiStrerror(ecode int) string {
+ r1, _, _ := syscall_syscall(abi.FuncPCABI0(libc_gai_strerror_trampoline),
+ uintptr(ecode),
+ 0, 0)
+ return GoString((*byte)(unsafe.Pointer(r1)))
+}
+
+// Implemented in the runtime package.
+func gostring(*byte) string
+
+func GoString(p *byte) string {
+ return gostring(p)
+}
+
+//go:linkname syscall_syscall syscall.syscall
+func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+//go:linkname syscall_syscallPtr syscall.syscallPtr
+func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+//go:linkname syscall_syscall6 syscall.syscall6
+func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+//go:linkname syscall_syscall6X syscall.syscall6X
+func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+//go:linkname syscall_syscall9 syscall.syscall9
+func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err syscall.Errno)
+
+type ResState struct {
+ unexported [69]uintptr
+}
+
+//go:cgo_import_dynamic libresolv_res_9_ninit res_9_ninit "/usr/lib/libresolv.9.dylib"
+func libresolv_res_9_ninit_trampoline()
+
+func ResNinit(state *ResState) error {
+ _, _, errno := syscall_syscall(abi.FuncPCABI0(libresolv_res_9_ninit_trampoline),
+ uintptr(unsafe.Pointer(state)),
+ 0, 0)
+ if errno != 0 {
+ return errno
+ }
+ return nil
+}
+
+//go:cgo_import_dynamic libresolv_res_9_nclose res_9_nclose "/usr/lib/libresolv.9.dylib"
+func libresolv_res_9_nclose_trampoline()
+
+func ResNclose(state *ResState) {
+ syscall_syscall(abi.FuncPCABI0(libresolv_res_9_nclose_trampoline),
+ uintptr(unsafe.Pointer(state)),
+ 0, 0)
+}
+
+//go:cgo_import_dynamic libresolv_res_9_nsearch res_9_nsearch "/usr/lib/libresolv.9.dylib"
+func libresolv_res_9_nsearch_trampoline()
+
+func ResNsearch(state *ResState, dname *byte, class, typ int, ans *byte, anslen int) (int, error) {
+ r1, _, errno := syscall_syscall6(abi.FuncPCABI0(libresolv_res_9_nsearch_trampoline),
+ uintptr(unsafe.Pointer(state)),
+ uintptr(unsafe.Pointer(dname)),
+ uintptr(class),
+ uintptr(typ),
+ uintptr(unsafe.Pointer(ans)),
+ uintptr(anslen))
+ if errno != 0 {
+ return 0, errno
+ }
+ return int(int32(r1)), nil
+}
diff --git a/contrib/go/_std_1.21/src/internal/syscall/unix/nonblocking_unix.go b/contrib/go/_std_1.21/src/internal/syscall/unix/nonblocking_unix.go
new file mode 100644
index 0000000000..fc0bc27916
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/nonblocking_unix.go
@@ -0,0 +1,21 @@
+// Copyright 2018 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.
+
+//go:build unix
+
+package unix
+
+import "syscall"
+
+func IsNonblock(fd int) (nonblocking bool, err error) {
+ flag, e1 := Fcntl(fd, syscall.F_GETFL, 0)
+ if e1 != nil {
+ return false, e1
+ }
+ return flag&syscall.O_NONBLOCK != 0, nil
+}
+
+func HasNonblockFlag(flag int) bool {
+ return flag&syscall.O_NONBLOCK != 0
+}
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/pty_darwin.go b/contrib/go/_std_1.21/src/internal/syscall/unix/pty_darwin.go
index b43321a42e..b43321a42e 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/pty_darwin.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/pty_darwin.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/sysnum_linux_amd64.go b/contrib/go/_std_1.21/src/internal/syscall/unix/sysnum_linux_amd64.go
index ae5239ebfb..ae5239ebfb 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/sysnum_linux_amd64.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/sysnum_linux_amd64.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/sysnum_linux_generic.go b/contrib/go/_std_1.21/src/internal/syscall/unix/sysnum_linux_generic.go
index 8c132c6bf5..8c132c6bf5 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/sysnum_linux_generic.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/sysnum_linux_generic.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/unix/user_darwin.go b/contrib/go/_std_1.21/src/internal/syscall/unix/user_darwin.go
index d05acdaa49..d05acdaa49 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/unix/user_darwin.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/user_darwin.go
diff --git a/contrib/go/_std_1.21/src/internal/syscall/unix/ya.make b/contrib/go/_std_1.21/src/internal/syscall/unix/ya.make
new file mode 100644
index 0000000000..cffec636f4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/unix/ya.make
@@ -0,0 +1,64 @@
+GO_LIBRARY()
+
+BUILD_ONLY_IF(WARNING OS_DARWIN OR OS_LINUX)
+
+IF (OS_DARWIN)
+ CGO_LDFLAGS(
+ -lresolv
+ )
+
+ SRCS(
+ asm_darwin.s
+ at_libc2.go
+ at_sysnum_darwin.go
+ constants.go
+ eaccess_other.go
+ fcntl_unix.go
+ getentropy_darwin.go
+ kernel_version_other.go
+ net.go
+ net_darwin.go
+ nonblocking_unix.go
+ pty_darwin.go
+ user_darwin.go
+ )
+ENDIF()
+
+IF (OS_LINUX)
+ SRCS(
+ at.go
+ at_fstatat.go
+ at_sysnum_linux.go
+ constants.go
+ copy_file_range_linux.go
+ eaccess_linux.go
+ fcntl_unix.go
+ getrandom.go
+ getrandom_linux.go
+ kernel_version_linux.go
+ net.go
+ nonblocking_unix.go
+ )
+
+ IF (ARCH_ARM64)
+ SRCS(
+ at_sysnum_fstatat_linux.go
+ sysnum_linux_generic.go
+ )
+ ENDIF()
+
+ IF (ARCH_X86_64)
+ SRCS(
+ at_sysnum_newfstatat_linux.go
+ sysnum_linux_amd64.go
+ )
+ ENDIF()
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ kernel_version_other.go
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/memory_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/memory_windows.go
index 8fb34cf349..8fb34cf349 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/memory_windows.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/memory_windows.go
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/net_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/net_windows.go
new file mode 100644
index 0000000000..42c600c144
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/net_windows.go
@@ -0,0 +1,40 @@
+// 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 windows
+
+import (
+ "sync"
+ "syscall"
+ _ "unsafe"
+)
+
+//go:linkname WSASendtoInet4 syscall.wsaSendtoInet4
+//go:noescape
+func WSASendtoInet4(s syscall.Handle, bufs *syscall.WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *syscall.SockaddrInet4, overlapped *syscall.Overlapped, croutine *byte) (err error)
+
+//go:linkname WSASendtoInet6 syscall.wsaSendtoInet6
+//go:noescape
+func WSASendtoInet6(s syscall.Handle, bufs *syscall.WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *syscall.SockaddrInet6, overlapped *syscall.Overlapped, croutine *byte) (err error)
+
+const (
+ SIO_TCP_INITIAL_RTO = syscall.IOC_IN | syscall.IOC_VENDOR | 17
+ TCP_INITIAL_RTO_UNSPECIFIED_RTT = ^uint16(0)
+ TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS = ^uint8(1)
+)
+
+type TCP_INITIAL_RTO_PARAMETERS struct {
+ Rtt uint16
+ MaxSynRetransmissions uint8
+}
+
+var Support_TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS = sync.OnceValue(func() bool {
+ var maj, min, build uint32
+ rtlGetNtVersionNumbers(&maj, &min, &build)
+ return maj >= 10 && build&0xffff >= 16299
+})
+
+//go:linkname rtlGetNtVersionNumbers syscall.rtlGetNtVersionNumbers
+//go:noescape
+func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32)
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/psapi_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/psapi_windows.go
index b138e658a9..b138e658a9 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/psapi_windows.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/psapi_windows.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/registry/key.go b/contrib/go/_std_1.21/src/internal/syscall/windows/registry/key.go
index ce6397f1e2..ce6397f1e2 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/registry/key.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/registry/key.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/registry/syscall.go b/contrib/go/_std_1.21/src/internal/syscall/windows/registry/syscall.go
index cb315adade..cb315adade 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/registry/syscall.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/registry/syscall.go
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/registry/value.go b/contrib/go/_std_1.21/src/internal/syscall/windows/registry/value.go
new file mode 100644
index 0000000000..7dfee0330f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/registry/value.go
@@ -0,0 +1,372 @@
+// Copyright 2015 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.
+
+//go:build windows
+
+package registry
+
+import (
+ "errors"
+ "syscall"
+ "unicode/utf16"
+ "unsafe"
+)
+
+const (
+ // Registry value types.
+ NONE = 0
+ SZ = 1
+ EXPAND_SZ = 2
+ BINARY = 3
+ DWORD = 4
+ DWORD_BIG_ENDIAN = 5
+ LINK = 6
+ MULTI_SZ = 7
+ RESOURCE_LIST = 8
+ FULL_RESOURCE_DESCRIPTOR = 9
+ RESOURCE_REQUIREMENTS_LIST = 10
+ QWORD = 11
+)
+
+var (
+ // ErrShortBuffer is returned when the buffer was too short for the operation.
+ ErrShortBuffer = syscall.ERROR_MORE_DATA
+
+ // ErrNotExist is returned when a registry key or value does not exist.
+ ErrNotExist = syscall.ERROR_FILE_NOT_FOUND
+
+ // ErrUnexpectedType is returned by Get*Value when the value's type was unexpected.
+ ErrUnexpectedType = errors.New("unexpected key value type")
+)
+
+// GetValue retrieves the type and data for the specified value associated
+// with an open key k. It fills up buffer buf and returns the retrieved
+// byte count n. If buf is too small to fit the stored value it returns
+// ErrShortBuffer error along with the required buffer size n.
+// If no buffer is provided, it returns true and actual buffer size n.
+// If no buffer is provided, GetValue returns the value's type only.
+// If the value does not exist, the error returned is ErrNotExist.
+//
+// GetValue is a low level function. If value's type is known, use the appropriate
+// Get*Value function instead.
+func (k Key) GetValue(name string, buf []byte) (n int, valtype uint32, err error) {
+ pname, err := syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return 0, 0, err
+ }
+ var pbuf *byte
+ if len(buf) > 0 {
+ pbuf = (*byte)(unsafe.Pointer(&buf[0]))
+ }
+ l := uint32(len(buf))
+ err = syscall.RegQueryValueEx(syscall.Handle(k), pname, nil, &valtype, pbuf, &l)
+ if err != nil {
+ return int(l), valtype, err
+ }
+ return int(l), valtype, nil
+}
+
+func (k Key) getValue(name string, buf []byte) (date []byte, valtype uint32, err error) {
+ p, err := syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return nil, 0, err
+ }
+ var t uint32
+ n := uint32(len(buf))
+ for {
+ err = syscall.RegQueryValueEx(syscall.Handle(k), p, nil, &t, (*byte)(unsafe.Pointer(&buf[0])), &n)
+ if err == nil {
+ return buf[:n], t, nil
+ }
+ if err != syscall.ERROR_MORE_DATA {
+ return nil, 0, err
+ }
+ if n <= uint32(len(buf)) {
+ return nil, 0, err
+ }
+ buf = make([]byte, n)
+ }
+}
+
+// GetStringValue retrieves the string value for the specified
+// value name associated with an open key k. It also returns the value's type.
+// If value does not exist, GetStringValue returns ErrNotExist.
+// If value is not SZ or EXPAND_SZ, it will return the correct value
+// type and ErrUnexpectedType.
+func (k Key) GetStringValue(name string) (val string, valtype uint32, err error) {
+ data, typ, err2 := k.getValue(name, make([]byte, 64))
+ if err2 != nil {
+ return "", typ, err2
+ }
+ switch typ {
+ case SZ, EXPAND_SZ:
+ default:
+ return "", typ, ErrUnexpectedType
+ }
+ if len(data) == 0 {
+ return "", typ, nil
+ }
+ u := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[: len(data)/2 : len(data)/2]
+ return syscall.UTF16ToString(u), typ, nil
+}
+
+// GetMUIStringValue retrieves the localized string value for
+// the specified value name associated with an open key k.
+// If the value name doesn't exist or the localized string value
+// can't be resolved, GetMUIStringValue returns ErrNotExist.
+// GetMUIStringValue panics if the system doesn't support
+// regLoadMUIString; use LoadRegLoadMUIString to check if
+// regLoadMUIString is supported before calling this function.
+func (k Key) GetMUIStringValue(name string) (string, error) {
+ pname, err := syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return "", err
+ }
+
+ buf := make([]uint16, 1024)
+ var buflen uint32
+ var pdir *uint16
+
+ err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
+ if err == syscall.ERROR_FILE_NOT_FOUND { // Try fallback path
+
+ // Try to resolve the string value using the system directory as
+ // a DLL search path; this assumes the string value is of the form
+ // @[path]\dllname,-strID but with no path given, e.g. @tzres.dll,-320.
+
+ // This approach works with tzres.dll but may have to be revised
+ // in the future to allow callers to provide custom search paths.
+
+ var s string
+ s, err = ExpandString("%SystemRoot%\\system32\\")
+ if err != nil {
+ return "", err
+ }
+ pdir, err = syscall.UTF16PtrFromString(s)
+ if err != nil {
+ return "", err
+ }
+
+ err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
+ }
+
+ for err == syscall.ERROR_MORE_DATA { // Grow buffer if needed
+ if buflen <= uint32(len(buf)) {
+ break // Buffer not growing, assume race; break
+ }
+ buf = make([]uint16, buflen)
+ err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
+ }
+
+ if err != nil {
+ return "", err
+ }
+
+ return syscall.UTF16ToString(buf), nil
+}
+
+// ExpandString expands environment-variable strings and replaces
+// them with the values defined for the current user.
+// Use ExpandString to expand EXPAND_SZ strings.
+func ExpandString(value string) (string, error) {
+ if value == "" {
+ return "", nil
+ }
+ p, err := syscall.UTF16PtrFromString(value)
+ if err != nil {
+ return "", err
+ }
+ r := make([]uint16, 100)
+ for {
+ n, err := expandEnvironmentStrings(p, &r[0], uint32(len(r)))
+ if err != nil {
+ return "", err
+ }
+ if n <= uint32(len(r)) {
+ return syscall.UTF16ToString(r[:n]), nil
+ }
+ r = make([]uint16, n)
+ }
+}
+
+// GetStringsValue retrieves the []string value for the specified
+// value name associated with an open key k. It also returns the value's type.
+// If value does not exist, GetStringsValue returns ErrNotExist.
+// If value is not MULTI_SZ, it will return the correct value
+// type and ErrUnexpectedType.
+func (k Key) GetStringsValue(name string) (val []string, valtype uint32, err error) {
+ data, typ, err2 := k.getValue(name, make([]byte, 64))
+ if err2 != nil {
+ return nil, typ, err2
+ }
+ if typ != MULTI_SZ {
+ return nil, typ, ErrUnexpectedType
+ }
+ if len(data) == 0 {
+ return nil, typ, nil
+ }
+ p := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[: len(data)/2 : len(data)/2]
+ if len(p) == 0 {
+ return nil, typ, nil
+ }
+ if p[len(p)-1] == 0 {
+ p = p[:len(p)-1] // remove terminating null
+ }
+ val = make([]string, 0, 5)
+ from := 0
+ for i, c := range p {
+ if c == 0 {
+ val = append(val, syscall.UTF16ToString(p[from:i]))
+ from = i + 1
+ }
+ }
+ return val, typ, nil
+}
+
+// GetIntegerValue retrieves the integer value for the specified
+// value name associated with an open key k. It also returns the value's type.
+// If value does not exist, GetIntegerValue returns ErrNotExist.
+// If value is not DWORD or QWORD, it will return the correct value
+// type and ErrUnexpectedType.
+func (k Key) GetIntegerValue(name string) (val uint64, valtype uint32, err error) {
+ data, typ, err2 := k.getValue(name, make([]byte, 8))
+ if err2 != nil {
+ return 0, typ, err2
+ }
+ switch typ {
+ case DWORD:
+ if len(data) != 4 {
+ return 0, typ, errors.New("DWORD value is not 4 bytes long")
+ }
+ return uint64(*(*uint32)(unsafe.Pointer(&data[0]))), DWORD, nil
+ case QWORD:
+ if len(data) != 8 {
+ return 0, typ, errors.New("QWORD value is not 8 bytes long")
+ }
+ return uint64(*(*uint64)(unsafe.Pointer(&data[0]))), QWORD, nil
+ default:
+ return 0, typ, ErrUnexpectedType
+ }
+}
+
+// GetBinaryValue retrieves the binary value for the specified
+// value name associated with an open key k. It also returns the value's type.
+// If value does not exist, GetBinaryValue returns ErrNotExist.
+// If value is not BINARY, it will return the correct value
+// type and ErrUnexpectedType.
+func (k Key) GetBinaryValue(name string) (val []byte, valtype uint32, err error) {
+ data, typ, err2 := k.getValue(name, make([]byte, 64))
+ if err2 != nil {
+ return nil, typ, err2
+ }
+ if typ != BINARY {
+ return nil, typ, ErrUnexpectedType
+ }
+ return data, typ, nil
+}
+
+func (k Key) setValue(name string, valtype uint32, data []byte) error {
+ p, err := syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return err
+ }
+ if len(data) == 0 {
+ return regSetValueEx(syscall.Handle(k), p, 0, valtype, nil, 0)
+ }
+ return regSetValueEx(syscall.Handle(k), p, 0, valtype, &data[0], uint32(len(data)))
+}
+
+// SetDWordValue sets the data and type of a name value
+// under key k to value and DWORD.
+func (k Key) SetDWordValue(name string, value uint32) error {
+ return k.setValue(name, DWORD, (*[4]byte)(unsafe.Pointer(&value))[:])
+}
+
+// SetQWordValue sets the data and type of a name value
+// under key k to value and QWORD.
+func (k Key) SetQWordValue(name string, value uint64) error {
+ return k.setValue(name, QWORD, (*[8]byte)(unsafe.Pointer(&value))[:])
+}
+
+func (k Key) setStringValue(name string, valtype uint32, value string) error {
+ v, err := syscall.UTF16FromString(value)
+ if err != nil {
+ return err
+ }
+ buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[: len(v)*2 : len(v)*2]
+ return k.setValue(name, valtype, buf)
+}
+
+// SetStringValue sets the data and type of a name value
+// under key k to value and SZ. The value must not contain a zero byte.
+func (k Key) SetStringValue(name, value string) error {
+ return k.setStringValue(name, SZ, value)
+}
+
+// SetExpandStringValue sets the data and type of a name value
+// under key k to value and EXPAND_SZ. The value must not contain a zero byte.
+func (k Key) SetExpandStringValue(name, value string) error {
+ return k.setStringValue(name, EXPAND_SZ, value)
+}
+
+// SetStringsValue sets the data and type of a name value
+// under key k to value and MULTI_SZ. The value strings
+// must not contain a zero byte.
+func (k Key) SetStringsValue(name string, value []string) error {
+ ss := ""
+ for _, s := range value {
+ for i := 0; i < len(s); i++ {
+ if s[i] == 0 {
+ return errors.New("string cannot have 0 inside")
+ }
+ }
+ ss += s + "\x00"
+ }
+ v := utf16.Encode([]rune(ss + "\x00"))
+ buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[: len(v)*2 : len(v)*2]
+ return k.setValue(name, MULTI_SZ, buf)
+}
+
+// SetBinaryValue sets the data and type of a name value
+// under key k to value and BINARY.
+func (k Key) SetBinaryValue(name string, value []byte) error {
+ return k.setValue(name, BINARY, value)
+}
+
+// DeleteValue removes a named value from the key k.
+func (k Key) DeleteValue(name string) error {
+ return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name))
+}
+
+// ReadValueNames returns the value names of key k.
+func (k Key) ReadValueNames() ([]string, error) {
+ ki, err := k.Stat()
+ if err != nil {
+ return nil, err
+ }
+ names := make([]string, 0, ki.ValueCount)
+ buf := make([]uint16, ki.MaxValueNameLen+1) // extra room for terminating null character
+loopItems:
+ for i := uint32(0); ; i++ {
+ l := uint32(len(buf))
+ for {
+ err := regEnumValue(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
+ if err == nil {
+ break
+ }
+ if err == syscall.ERROR_MORE_DATA {
+ // Double buffer size and try again.
+ l = uint32(2 * len(buf))
+ buf = make([]uint16, l)
+ continue
+ }
+ if err == _ERROR_NO_MORE_ITEMS {
+ break loopItems
+ }
+ return names, err
+ }
+ names = append(names, syscall.UTF16ToString(buf[:l]))
+ }
+ return names, nil
+}
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/registry/ya.make b/contrib/go/_std_1.21/src/internal/syscall/windows/registry/ya.make
new file mode 100644
index 0000000000..77018f9451
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/registry/ya.make
@@ -0,0 +1,24 @@
+GO_LIBRARY()
+
+BUILD_ONLY_IF(
+ WARNING
+ OS_WINDOWS
+)
+
+IF (OS_WINDOWS)
+ SRCS(
+ key.go
+ syscall.go
+ value.go
+ zsyscall_windows.go
+ )
+
+ GO_TEST_SRCS(export_test.go)
+
+ GO_XTEST_SRCS(registry_test.go)
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/registry/zsyscall_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/registry/zsyscall_windows.go
index cab1319374..cab1319374 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/registry/zsyscall_windows.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/registry/zsyscall_windows.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/reparse_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go
index 6e111392f0..6e111392f0 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/reparse_windows.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/reparse_windows.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/security_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/security_windows.go
index 4a2dfc0c73..4a2dfc0c73 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/security_windows.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/security_windows.go
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/symlink_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/symlink_windows.go
index b64d058d13..b64d058d13 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/symlink_windows.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/symlink_windows.go
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go
new file mode 100644
index 0000000000..892b878d16
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/syscall_windows.go
@@ -0,0 +1,379 @@
+// Copyright 2014 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 windows
+
+import (
+ "sync"
+ "syscall"
+ "unsafe"
+)
+
+// UTF16PtrToString is like UTF16ToString, but takes *uint16
+// as a parameter instead of []uint16.
+func UTF16PtrToString(p *uint16) string {
+ if p == nil {
+ return ""
+ }
+ end := unsafe.Pointer(p)
+ n := 0
+ for *(*uint16)(end) != 0 {
+ end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p))
+ n++
+ }
+ return syscall.UTF16ToString(unsafe.Slice(p, n))
+}
+
+const (
+ ERROR_BAD_LENGTH syscall.Errno = 24
+ ERROR_SHARING_VIOLATION syscall.Errno = 32
+ ERROR_LOCK_VIOLATION syscall.Errno = 33
+ ERROR_NOT_SUPPORTED syscall.Errno = 50
+ ERROR_CALL_NOT_IMPLEMENTED syscall.Errno = 120
+ ERROR_INVALID_NAME syscall.Errno = 123
+ ERROR_LOCK_FAILED syscall.Errno = 167
+ ERROR_NO_UNICODE_TRANSLATION syscall.Errno = 1113
+)
+
+const GAA_FLAG_INCLUDE_PREFIX = 0x00000010
+
+const (
+ IF_TYPE_OTHER = 1
+ IF_TYPE_ETHERNET_CSMACD = 6
+ IF_TYPE_ISO88025_TOKENRING = 9
+ IF_TYPE_PPP = 23
+ IF_TYPE_SOFTWARE_LOOPBACK = 24
+ IF_TYPE_ATM = 37
+ IF_TYPE_IEEE80211 = 71
+ IF_TYPE_TUNNEL = 131
+ IF_TYPE_IEEE1394 = 144
+)
+
+type SocketAddress struct {
+ Sockaddr *syscall.RawSockaddrAny
+ SockaddrLength int32
+}
+
+type IpAdapterUnicastAddress struct {
+ Length uint32
+ Flags uint32
+ Next *IpAdapterUnicastAddress
+ Address SocketAddress
+ PrefixOrigin int32
+ SuffixOrigin int32
+ DadState int32
+ ValidLifetime uint32
+ PreferredLifetime uint32
+ LeaseLifetime uint32
+ OnLinkPrefixLength uint8
+}
+
+type IpAdapterAnycastAddress struct {
+ Length uint32
+ Flags uint32
+ Next *IpAdapterAnycastAddress
+ Address SocketAddress
+}
+
+type IpAdapterMulticastAddress struct {
+ Length uint32
+ Flags uint32
+ Next *IpAdapterMulticastAddress
+ Address SocketAddress
+}
+
+type IpAdapterDnsServerAdapter struct {
+ Length uint32
+ Reserved uint32
+ Next *IpAdapterDnsServerAdapter
+ Address SocketAddress
+}
+
+type IpAdapterPrefix struct {
+ Length uint32
+ Flags uint32
+ Next *IpAdapterPrefix
+ Address SocketAddress
+ PrefixLength uint32
+}
+
+type IpAdapterAddresses struct {
+ Length uint32
+ IfIndex uint32
+ Next *IpAdapterAddresses
+ AdapterName *byte
+ FirstUnicastAddress *IpAdapterUnicastAddress
+ FirstAnycastAddress *IpAdapterAnycastAddress
+ FirstMulticastAddress *IpAdapterMulticastAddress
+ FirstDnsServerAddress *IpAdapterDnsServerAdapter
+ DnsSuffix *uint16
+ Description *uint16
+ FriendlyName *uint16
+ PhysicalAddress [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
+ PhysicalAddressLength uint32
+ Flags uint32
+ Mtu uint32
+ IfType uint32
+ OperStatus uint32
+ Ipv6IfIndex uint32
+ ZoneIndices [16]uint32
+ FirstPrefix *IpAdapterPrefix
+ /* more fields might be present here. */
+}
+
+type SecurityAttributes struct {
+ Length uint16
+ SecurityDescriptor uintptr
+ InheritHandle bool
+}
+
+type FILE_BASIC_INFO struct {
+ CreationTime syscall.Filetime
+ LastAccessTime syscall.Filetime
+ LastWriteTime syscall.Filetime
+ ChangedTime syscall.Filetime
+ FileAttributes uint32
+}
+
+const (
+ IfOperStatusUp = 1
+ IfOperStatusDown = 2
+ IfOperStatusTesting = 3
+ IfOperStatusUnknown = 4
+ IfOperStatusDormant = 5
+ IfOperStatusNotPresent = 6
+ IfOperStatusLowerLayerDown = 7
+)
+
+//sys GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) = iphlpapi.GetAdaptersAddresses
+//sys GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
+//sys MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) = MoveFileExW
+//sys GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) = kernel32.GetModuleFileNameW
+//sys SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf uintptr, bufsize uint32) (err error) = kernel32.SetFileInformationByHandle
+//sys VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) = kernel32.VirtualQuery
+//sys GetTempPath2(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPath2W
+
+const (
+ // flags for CreateToolhelp32Snapshot
+ TH32CS_SNAPMODULE = 0x08
+ TH32CS_SNAPMODULE32 = 0x10
+)
+
+const MAX_MODULE_NAME32 = 255
+
+type ModuleEntry32 struct {
+ Size uint32
+ ModuleID uint32
+ ProcessID uint32
+ GlblcntUsage uint32
+ ProccntUsage uint32
+ ModBaseAddr uintptr
+ ModBaseSize uint32
+ ModuleHandle syscall.Handle
+ Module [MAX_MODULE_NAME32 + 1]uint16
+ ExePath [syscall.MAX_PATH]uint16
+}
+
+const SizeofModuleEntry32 = unsafe.Sizeof(ModuleEntry32{})
+
+//sys Module32First(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW
+//sys Module32Next(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32NextW
+
+const (
+ WSA_FLAG_OVERLAPPED = 0x01
+ WSA_FLAG_NO_HANDLE_INHERIT = 0x80
+
+ WSAEMSGSIZE syscall.Errno = 10040
+
+ MSG_PEEK = 0x2
+ MSG_TRUNC = 0x0100
+ MSG_CTRUNC = 0x0200
+
+ socket_error = uintptr(^uint32(0))
+)
+
+var WSAID_WSASENDMSG = syscall.GUID{
+ Data1: 0xa441e712,
+ Data2: 0x754f,
+ Data3: 0x43ca,
+ Data4: [8]byte{0x84, 0xa7, 0x0d, 0xee, 0x44, 0xcf, 0x60, 0x6d},
+}
+
+var WSAID_WSARECVMSG = syscall.GUID{
+ Data1: 0xf689d7c8,
+ Data2: 0x6f1f,
+ Data3: 0x436b,
+ Data4: [8]byte{0x8a, 0x53, 0xe5, 0x4f, 0xe3, 0x51, 0xc3, 0x22},
+}
+
+var sendRecvMsgFunc struct {
+ once sync.Once
+ sendAddr uintptr
+ recvAddr uintptr
+ err error
+}
+
+type WSAMsg struct {
+ Name syscall.Pointer
+ Namelen int32
+ Buffers *syscall.WSABuf
+ BufferCount uint32
+ Control syscall.WSABuf
+ Flags uint32
+}
+
+//sys WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = ws2_32.WSASocketW
+
+func loadWSASendRecvMsg() error {
+ sendRecvMsgFunc.once.Do(func() {
+ var s syscall.Handle
+ s, sendRecvMsgFunc.err = syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP)
+ if sendRecvMsgFunc.err != nil {
+ return
+ }
+ defer syscall.CloseHandle(s)
+ var n uint32
+ sendRecvMsgFunc.err = syscall.WSAIoctl(s,
+ syscall.SIO_GET_EXTENSION_FUNCTION_POINTER,
+ (*byte)(unsafe.Pointer(&WSAID_WSARECVMSG)),
+ uint32(unsafe.Sizeof(WSAID_WSARECVMSG)),
+ (*byte)(unsafe.Pointer(&sendRecvMsgFunc.recvAddr)),
+ uint32(unsafe.Sizeof(sendRecvMsgFunc.recvAddr)),
+ &n, nil, 0)
+ if sendRecvMsgFunc.err != nil {
+ return
+ }
+ sendRecvMsgFunc.err = syscall.WSAIoctl(s,
+ syscall.SIO_GET_EXTENSION_FUNCTION_POINTER,
+ (*byte)(unsafe.Pointer(&WSAID_WSASENDMSG)),
+ uint32(unsafe.Sizeof(WSAID_WSASENDMSG)),
+ (*byte)(unsafe.Pointer(&sendRecvMsgFunc.sendAddr)),
+ uint32(unsafe.Sizeof(sendRecvMsgFunc.sendAddr)),
+ &n, nil, 0)
+ })
+ return sendRecvMsgFunc.err
+}
+
+func WSASendMsg(fd syscall.Handle, msg *WSAMsg, flags uint32, bytesSent *uint32, overlapped *syscall.Overlapped, croutine *byte) error {
+ err := loadWSASendRecvMsg()
+ if err != nil {
+ return err
+ }
+ r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.sendAddr, 6, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(flags), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+ if r1 == socket_error {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return err
+}
+
+func WSARecvMsg(fd syscall.Handle, msg *WSAMsg, bytesReceived *uint32, overlapped *syscall.Overlapped, croutine *byte) error {
+ err := loadWSASendRecvMsg()
+ if err != nil {
+ return err
+ }
+ r1, _, e1 := syscall.Syscall6(sendRecvMsgFunc.recvAddr, 5, uintptr(fd), uintptr(unsafe.Pointer(msg)), uintptr(unsafe.Pointer(bytesReceived)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0)
+ if r1 == socket_error {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = syscall.EINVAL
+ }
+ }
+ return err
+}
+
+const (
+ ComputerNameNetBIOS = 0
+ ComputerNameDnsHostname = 1
+ ComputerNameDnsDomain = 2
+ ComputerNameDnsFullyQualified = 3
+ ComputerNamePhysicalNetBIOS = 4
+ ComputerNamePhysicalDnsHostname = 5
+ ComputerNamePhysicalDnsDomain = 6
+ ComputerNamePhysicalDnsFullyQualified = 7
+ ComputerNameMax = 8
+
+ MOVEFILE_REPLACE_EXISTING = 0x1
+ MOVEFILE_COPY_ALLOWED = 0x2
+ MOVEFILE_DELAY_UNTIL_REBOOT = 0x4
+ MOVEFILE_WRITE_THROUGH = 0x8
+ MOVEFILE_CREATE_HARDLINK = 0x10
+ MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20
+)
+
+func Rename(oldpath, newpath string) error {
+ from, err := syscall.UTF16PtrFromString(oldpath)
+ if err != nil {
+ return err
+ }
+ to, err := syscall.UTF16PtrFromString(newpath)
+ if err != nil {
+ return err
+ }
+ return MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING)
+}
+
+//sys LockFileEx(file syscall.Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.LockFileEx
+//sys UnlockFileEx(file syscall.Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) = kernel32.UnlockFileEx
+
+const (
+ LOCKFILE_FAIL_IMMEDIATELY = 0x00000001
+ LOCKFILE_EXCLUSIVE_LOCK = 0x00000002
+)
+
+const MB_ERR_INVALID_CHARS = 8
+
+//sys GetACP() (acp uint32) = kernel32.GetACP
+//sys GetConsoleCP() (ccp uint32) = kernel32.GetConsoleCP
+//sys MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) = kernel32.MultiByteToWideChar
+//sys GetCurrentThread() (pseudoHandle syscall.Handle, err error) = kernel32.GetCurrentThread
+
+const STYPE_DISKTREE = 0x00
+
+type SHARE_INFO_2 struct {
+ Netname *uint16
+ Type uint32
+ Remark *uint16
+ Permissions uint32
+ MaxUses uint32
+ CurrentUses uint32
+ Path *uint16
+ Passwd *uint16
+}
+
+//sys NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) = netapi32.NetShareAdd
+//sys NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) = netapi32.NetShareDel
+
+const (
+ FILE_NAME_NORMALIZED = 0x0
+ FILE_NAME_OPENED = 0x8
+
+ VOLUME_NAME_DOS = 0x0
+ VOLUME_NAME_GUID = 0x1
+ VOLUME_NAME_NONE = 0x4
+ VOLUME_NAME_NT = 0x2
+)
+
+//sys GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) = kernel32.GetFinalPathNameByHandleW
+
+func LoadGetFinalPathNameByHandle() error {
+ return procGetFinalPathNameByHandleW.Find()
+}
+
+func ErrorLoadingGetTempPath2() error {
+ return procGetTempPath2W.Find()
+}
+
+//sys CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) = userenv.CreateEnvironmentBlock
+//sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock
+//sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW
+
+//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036
+
+//sys RtlLookupFunctionEntry(pc uintptr, baseAddress *uintptr, table *byte) (ret uintptr) = kernel32.RtlLookupFunctionEntry
+//sys RtlVirtualUnwind(handlerType uint32, baseAddress uintptr, pc uintptr, entry uintptr, ctxt uintptr, data *uintptr, frame *uintptr, ctxptrs *byte) (ret uintptr) = kernel32.RtlVirtualUnwind
diff --git a/contrib/go/_std_1.20/src/internal/syscall/windows/sysdll/sysdll.go b/contrib/go/_std_1.21/src/internal/syscall/windows/sysdll/sysdll.go
index e79fd19edc..e79fd19edc 100644
--- a/contrib/go/_std_1.20/src/internal/syscall/windows/sysdll/sysdll.go
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/sysdll/sysdll.go
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/sysdll/ya.make b/contrib/go/_std_1.21/src/internal/syscall/windows/sysdll/ya.make
new file mode 100644
index 0000000000..39d2280ec6
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/sysdll/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+BUILD_ONLY_IF(
+ WARNING
+ OS_WINDOWS
+)
+
+IF (OS_WINDOWS)
+ SRCS(
+ sysdll.go
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/ya.make b/contrib/go/_std_1.21/src/internal/syscall/windows/ya.make
new file mode 100644
index 0000000000..00477394ac
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/ya.make
@@ -0,0 +1,33 @@
+GO_LIBRARY()
+
+BUILD_ONLY_IF(
+ WARNING
+ OS_WINDOWS
+)
+
+IF (OS_WINDOWS)
+ SRCS(
+ memory_windows.go
+ net_windows.go
+ psapi_windows.go
+ reparse_windows.go
+ security_windows.go
+ symlink_windows.go
+ syscall_windows.go
+ zsyscall_windows.go
+ )
+
+ GO_XTEST_SRCS(exec_windows_test.go)
+ENDIF()
+
+END()
+
+RECURSE(
+)
+
+IF (OS_WINDOWS)
+ RECURSE(
+ registry
+ sysdll
+ )
+ENDIF()
diff --git a/contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go b/contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go
new file mode 100644
index 0000000000..a5c246b773
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/syscall/windows/zsyscall_windows.go
@@ -0,0 +1,388 @@
+// Code generated by 'go generate'; DO NOT EDIT.
+
+package windows
+
+import (
+ "internal/syscall/windows/sysdll"
+ "syscall"
+ "unsafe"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = syscall.EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
+var (
+ modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll"))
+ modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll"))
+ modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll"))
+ modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll"))
+ modpsapi = syscall.NewLazyDLL(sysdll.Add("psapi.dll"))
+ moduserenv = syscall.NewLazyDLL(sysdll.Add("userenv.dll"))
+ modws2_32 = syscall.NewLazyDLL(sysdll.Add("ws2_32.dll"))
+
+ procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
+ procDuplicateTokenEx = modadvapi32.NewProc("DuplicateTokenEx")
+ procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
+ procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
+ procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
+ procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
+ procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation")
+ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036")
+ procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses")
+ procCreateEventW = modkernel32.NewProc("CreateEventW")
+ procGetACP = modkernel32.NewProc("GetACP")
+ procGetComputerNameExW = modkernel32.NewProc("GetComputerNameExW")
+ procGetConsoleCP = modkernel32.NewProc("GetConsoleCP")
+ procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
+ procGetFileInformationByHandleEx = modkernel32.NewProc("GetFileInformationByHandleEx")
+ procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW")
+ procGetModuleFileNameW = modkernel32.NewProc("GetModuleFileNameW")
+ procGetTempPath2W = modkernel32.NewProc("GetTempPath2W")
+ procLockFileEx = modkernel32.NewProc("LockFileEx")
+ procModule32FirstW = modkernel32.NewProc("Module32FirstW")
+ procModule32NextW = modkernel32.NewProc("Module32NextW")
+ procMoveFileExW = modkernel32.NewProc("MoveFileExW")
+ procMultiByteToWideChar = modkernel32.NewProc("MultiByteToWideChar")
+ procRtlLookupFunctionEntry = modkernel32.NewProc("RtlLookupFunctionEntry")
+ procRtlVirtualUnwind = modkernel32.NewProc("RtlVirtualUnwind")
+ procSetFileInformationByHandle = modkernel32.NewProc("SetFileInformationByHandle")
+ procUnlockFileEx = modkernel32.NewProc("UnlockFileEx")
+ procVirtualQuery = modkernel32.NewProc("VirtualQuery")
+ procNetShareAdd = modnetapi32.NewProc("NetShareAdd")
+ procNetShareDel = modnetapi32.NewProc("NetShareDel")
+ procNetUserGetLocalGroups = modnetapi32.NewProc("NetUserGetLocalGroups")
+ procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
+ procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
+ procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
+ procGetProfilesDirectoryW = moduserenv.NewProc("GetProfilesDirectoryW")
+ procWSASocketW = modws2_32.NewProc("WSASocketW")
+)
+
+func adjustTokenPrivileges(token syscall.Token, disableAllPrivileges bool, newstate *TOKEN_PRIVILEGES, buflen uint32, prevstate *TOKEN_PRIVILEGES, returnlen *uint32) (ret uint32, err error) {
+ var _p0 uint32
+ if disableAllPrivileges {
+ _p0 = 1
+ }
+ r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(newstate)), uintptr(buflen), uintptr(unsafe.Pointer(prevstate)), uintptr(unsafe.Pointer(returnlen)))
+ ret = uint32(r0)
+ if true {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func DuplicateTokenEx(hExistingToken syscall.Token, dwDesiredAccess uint32, lpTokenAttributes *syscall.SecurityAttributes, impersonationLevel uint32, tokenType TokenType, phNewToken *syscall.Token) (err error) {
+ r1, _, e1 := syscall.Syscall6(procDuplicateTokenEx.Addr(), 6, uintptr(hExistingToken), uintptr(dwDesiredAccess), uintptr(unsafe.Pointer(lpTokenAttributes)), uintptr(impersonationLevel), uintptr(tokenType), uintptr(unsafe.Pointer(phNewToken)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func ImpersonateSelf(impersonationlevel uint32) (err error) {
+ r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(impersonationlevel), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func LookupPrivilegeValue(systemname *uint16, name *uint16, luid *LUID) (err error) {
+ r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemname)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func OpenThreadToken(h syscall.Handle, access uint32, openasself bool, token *syscall.Token) (err error) {
+ var _p0 uint32
+ if openasself {
+ _p0 = 1
+ }
+ r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(h), uintptr(access), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func RevertToSelf() (err error) {
+ r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func SetTokenInformation(tokenHandle syscall.Token, tokenInformationClass uint32, tokenInformation uintptr, tokenInformationLength uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procSetTokenInformation.Addr(), 4, uintptr(tokenHandle), uintptr(tokenInformationClass), uintptr(tokenInformation), uintptr(tokenInformationLength), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func RtlGenRandom(buf []byte) (err error) {
+ var _p0 *byte
+ if len(buf) > 0 {
+ _p0 = &buf[0]
+ }
+ r1, _, e1 := syscall.Syscall(procSystemFunction036.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetAdaptersAddresses(family uint32, flags uint32, reserved uintptr, adapterAddresses *IpAdapterAddresses, sizePointer *uint32) (errcode error) {
+ r0, _, _ := syscall.Syscall6(procGetAdaptersAddresses.Addr(), 5, uintptr(family), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(adapterAddresses)), uintptr(unsafe.Pointer(sizePointer)), 0)
+ if r0 != 0 {
+ errcode = syscall.Errno(r0)
+ }
+ return
+}
+
+func CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) {
+ r0, _, e1 := syscall.Syscall6(procCreateEventW.Addr(), 4, uintptr(unsafe.Pointer(eventAttrs)), uintptr(manualReset), uintptr(initialState), uintptr(unsafe.Pointer(name)), 0, 0)
+ handle = syscall.Handle(r0)
+ if handle == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetACP() (acp uint32) {
+ r0, _, _ := syscall.Syscall(procGetACP.Addr(), 0, 0, 0, 0)
+ acp = uint32(r0)
+ return
+}
+
+func GetComputerNameEx(nameformat uint32, buf *uint16, n *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall(procGetComputerNameExW.Addr(), 3, uintptr(nameformat), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetConsoleCP() (ccp uint32) {
+ r0, _, _ := syscall.Syscall(procGetConsoleCP.Addr(), 0, 0, 0, 0)
+ ccp = uint32(r0)
+ return
+}
+
+func GetCurrentThread() (pseudoHandle syscall.Handle, err error) {
+ r0, _, e1 := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
+ pseudoHandle = syscall.Handle(r0)
+ if pseudoHandle == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetFileInformationByHandleEx(handle syscall.Handle, class uint32, info *byte, bufsize uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(), 4, uintptr(handle), uintptr(class), uintptr(unsafe.Pointer(info)), uintptr(bufsize), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetFinalPathNameByHandle(file syscall.Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) {
+ r0, _, e1 := syscall.Syscall6(procGetFinalPathNameByHandleW.Addr(), 4, uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags), 0, 0)
+ n = uint32(r0)
+ if n == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetModuleFileName(module syscall.Handle, fn *uint16, len uint32) (n uint32, err error) {
+ r0, _, e1 := syscall.Syscall(procGetModuleFileNameW.Addr(), 3, uintptr(module), uintptr(unsafe.Pointer(fn)), uintptr(len))
+ n = uint32(r0)
+ if n == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetTempPath2(buflen uint32, buf *uint16) (n uint32, err error) {
+ r0, _, e1 := syscall.Syscall(procGetTempPath2W.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
+ n = uint32(r0)
+ if n == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func LockFileEx(file syscall.Handle, flags uint32, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) {
+ r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(file), uintptr(flags), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func Module32First(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) {
+ r1, _, e1 := syscall.Syscall(procModule32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func Module32Next(snapshot syscall.Handle, moduleEntry *ModuleEntry32) (err error) {
+ r1, _, e1 := syscall.Syscall(procModule32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(moduleEntry)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func MoveFileEx(from *uint16, to *uint16, flags uint32) (err error) {
+ r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func MultiByteToWideChar(codePage uint32, dwFlags uint32, str *byte, nstr int32, wchar *uint16, nwchar int32) (nwrite int32, err error) {
+ r0, _, e1 := syscall.Syscall6(procMultiByteToWideChar.Addr(), 6, uintptr(codePage), uintptr(dwFlags), uintptr(unsafe.Pointer(str)), uintptr(nstr), uintptr(unsafe.Pointer(wchar)), uintptr(nwchar))
+ nwrite = int32(r0)
+ if nwrite == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func RtlLookupFunctionEntry(pc uintptr, baseAddress *uintptr, table *byte) (ret uintptr) {
+ r0, _, _ := syscall.Syscall(procRtlLookupFunctionEntry.Addr(), 3, uintptr(pc), uintptr(unsafe.Pointer(baseAddress)), uintptr(unsafe.Pointer(table)))
+ ret = uintptr(r0)
+ return
+}
+
+func RtlVirtualUnwind(handlerType uint32, baseAddress uintptr, pc uintptr, entry uintptr, ctxt uintptr, data *uintptr, frame *uintptr, ctxptrs *byte) (ret uintptr) {
+ r0, _, _ := syscall.Syscall9(procRtlVirtualUnwind.Addr(), 8, uintptr(handlerType), uintptr(baseAddress), uintptr(pc), uintptr(entry), uintptr(ctxt), uintptr(unsafe.Pointer(data)), uintptr(unsafe.Pointer(frame)), uintptr(unsafe.Pointer(ctxptrs)), 0)
+ ret = uintptr(r0)
+ return
+}
+
+func SetFileInformationByHandle(handle syscall.Handle, fileInformationClass uint32, buf uintptr, bufsize uint32) (err error) {
+ r1, _, e1 := syscall.Syscall6(procSetFileInformationByHandle.Addr(), 4, uintptr(handle), uintptr(fileInformationClass), uintptr(buf), uintptr(bufsize), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func UnlockFileEx(file syscall.Handle, reserved uint32, bytesLow uint32, bytesHigh uint32, overlapped *syscall.Overlapped) (err error) {
+ r1, _, e1 := syscall.Syscall6(procUnlockFileEx.Addr(), 5, uintptr(file), uintptr(reserved), uintptr(bytesLow), uintptr(bytesHigh), uintptr(unsafe.Pointer(overlapped)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func VirtualQuery(address uintptr, buffer *MemoryBasicInformation, length uintptr) (err error) {
+ r1, _, e1 := syscall.Syscall(procVirtualQuery.Addr(), 3, uintptr(address), uintptr(unsafe.Pointer(buffer)), uintptr(length))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func NetShareAdd(serverName *uint16, level uint32, buf *byte, parmErr *uint16) (neterr error) {
+ r0, _, _ := syscall.Syscall6(procNetShareAdd.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(level), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(parmErr)), 0, 0)
+ if r0 != 0 {
+ neterr = syscall.Errno(r0)
+ }
+ return
+}
+
+func NetShareDel(serverName *uint16, netName *uint16, reserved uint32) (neterr error) {
+ r0, _, _ := syscall.Syscall(procNetShareDel.Addr(), 3, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(netName)), uintptr(reserved))
+ if r0 != 0 {
+ neterr = syscall.Errno(r0)
+ }
+ return
+}
+
+func NetUserGetLocalGroups(serverName *uint16, userName *uint16, level uint32, flags uint32, buf **byte, prefMaxLen uint32, entriesRead *uint32, totalEntries *uint32) (neterr error) {
+ r0, _, _ := syscall.Syscall9(procNetUserGetLocalGroups.Addr(), 8, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(flags), uintptr(unsafe.Pointer(buf)), uintptr(prefMaxLen), uintptr(unsafe.Pointer(entriesRead)), uintptr(unsafe.Pointer(totalEntries)), 0)
+ if r0 != 0 {
+ neterr = syscall.Errno(r0)
+ }
+ return
+}
+
+func GetProcessMemoryInfo(handle syscall.Handle, memCounters *PROCESS_MEMORY_COUNTERS, cb uint32) (err error) {
+ r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(memCounters)), uintptr(cb))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CreateEnvironmentBlock(block **uint16, token syscall.Token, inheritExisting bool) (err error) {
+ var _p0 uint32
+ if inheritExisting {
+ _p0 = 1
+ }
+ r1, _, e1 := syscall.Syscall(procCreateEnvironmentBlock.Addr(), 3, uintptr(unsafe.Pointer(block)), uintptr(token), uintptr(_p0))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func DestroyEnvironmentBlock(block *uint16) (err error) {
+ r1, _, e1 := syscall.Syscall(procDestroyEnvironmentBlock.Addr(), 1, uintptr(unsafe.Pointer(block)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetProfilesDirectory(dir *uint16, dirLen *uint32) (err error) {
+ r1, _, e1 := syscall.Syscall(procGetProfilesDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func WSASocket(af int32, typ int32, protocol int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (handle syscall.Handle, err error) {
+ r0, _, e1 := syscall.Syscall6(procWSASocketW.Addr(), 6, uintptr(af), uintptr(typ), uintptr(protocol), uintptr(unsafe.Pointer(protinfo)), uintptr(group), uintptr(flags))
+ handle = syscall.Handle(r0)
+ if handle == syscall.InvalidHandle {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/contrib/go/_std_1.20/src/internal/sysinfo/sysinfo.go b/contrib/go/_std_1.21/src/internal/sysinfo/sysinfo.go
index 961be7abae..961be7abae 100644
--- a/contrib/go/_std_1.20/src/internal/sysinfo/sysinfo.go
+++ b/contrib/go/_std_1.21/src/internal/sysinfo/sysinfo.go
diff --git a/contrib/go/_std_1.20/src/internal/sysinfo/ya.make b/contrib/go/_std_1.21/src/internal/sysinfo/ya.make
index 734edbe953..734edbe953 100644
--- a/contrib/go/_std_1.20/src/internal/sysinfo/ya.make
+++ b/contrib/go/_std_1.21/src/internal/sysinfo/ya.make
diff --git a/contrib/go/_std_1.20/src/internal/testlog/exit.go b/contrib/go/_std_1.21/src/internal/testlog/exit.go
index e15defdb5b..e15defdb5b 100644
--- a/contrib/go/_std_1.20/src/internal/testlog/exit.go
+++ b/contrib/go/_std_1.21/src/internal/testlog/exit.go
diff --git a/contrib/go/_std_1.20/src/internal/testlog/log.go b/contrib/go/_std_1.21/src/internal/testlog/log.go
index 3c5f780ac4..3c5f780ac4 100644
--- a/contrib/go/_std_1.20/src/internal/testlog/log.go
+++ b/contrib/go/_std_1.21/src/internal/testlog/log.go
diff --git a/contrib/go/_std_1.20/src/internal/testlog/ya.make b/contrib/go/_std_1.21/src/internal/testlog/ya.make
index b135ad33f0..b135ad33f0 100644
--- a/contrib/go/_std_1.20/src/internal/testlog/ya.make
+++ b/contrib/go/_std_1.21/src/internal/testlog/ya.make
diff --git a/contrib/go/_std_1.21/src/internal/types/errors/code_string.go b/contrib/go/_std_1.21/src/internal/types/errors/code_string.go
new file mode 100644
index 0000000000..719fc73a5a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/types/errors/code_string.go
@@ -0,0 +1,199 @@
+// Code generated by "stringer -type Code codes.go"; DO NOT EDIT.
+
+package errors
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[InvalidSyntaxTree - -1]
+ _ = x[Test-1]
+ _ = x[BlankPkgName-2]
+ _ = x[MismatchedPkgName-3]
+ _ = x[InvalidPkgUse-4]
+ _ = x[BadImportPath-5]
+ _ = x[BrokenImport-6]
+ _ = x[ImportCRenamed-7]
+ _ = x[UnusedImport-8]
+ _ = x[InvalidInitCycle-9]
+ _ = x[DuplicateDecl-10]
+ _ = x[InvalidDeclCycle-11]
+ _ = x[InvalidTypeCycle-12]
+ _ = x[InvalidConstInit-13]
+ _ = x[InvalidConstVal-14]
+ _ = x[InvalidConstType-15]
+ _ = x[UntypedNilUse-16]
+ _ = x[WrongAssignCount-17]
+ _ = x[UnassignableOperand-18]
+ _ = x[NoNewVar-19]
+ _ = x[MultiValAssignOp-20]
+ _ = x[InvalidIfaceAssign-21]
+ _ = x[InvalidChanAssign-22]
+ _ = x[IncompatibleAssign-23]
+ _ = x[UnaddressableFieldAssign-24]
+ _ = x[NotAType-25]
+ _ = x[InvalidArrayLen-26]
+ _ = x[BlankIfaceMethod-27]
+ _ = x[IncomparableMapKey-28]
+ _ = x[InvalidPtrEmbed-30]
+ _ = x[BadRecv-31]
+ _ = x[InvalidRecv-32]
+ _ = x[DuplicateFieldAndMethod-33]
+ _ = x[DuplicateMethod-34]
+ _ = x[InvalidBlank-35]
+ _ = x[InvalidIota-36]
+ _ = x[MissingInitBody-37]
+ _ = x[InvalidInitSig-38]
+ _ = x[InvalidInitDecl-39]
+ _ = x[InvalidMainDecl-40]
+ _ = x[TooManyValues-41]
+ _ = x[NotAnExpr-42]
+ _ = x[TruncatedFloat-43]
+ _ = x[NumericOverflow-44]
+ _ = x[UndefinedOp-45]
+ _ = x[MismatchedTypes-46]
+ _ = x[DivByZero-47]
+ _ = x[NonNumericIncDec-48]
+ _ = x[UnaddressableOperand-49]
+ _ = x[InvalidIndirection-50]
+ _ = x[NonIndexableOperand-51]
+ _ = x[InvalidIndex-52]
+ _ = x[SwappedSliceIndices-53]
+ _ = x[NonSliceableOperand-54]
+ _ = x[InvalidSliceExpr-55]
+ _ = x[InvalidShiftCount-56]
+ _ = x[InvalidShiftOperand-57]
+ _ = x[InvalidReceive-58]
+ _ = x[InvalidSend-59]
+ _ = x[DuplicateLitKey-60]
+ _ = x[MissingLitKey-61]
+ _ = x[InvalidLitIndex-62]
+ _ = x[OversizeArrayLit-63]
+ _ = x[MixedStructLit-64]
+ _ = x[InvalidStructLit-65]
+ _ = x[MissingLitField-66]
+ _ = x[DuplicateLitField-67]
+ _ = x[UnexportedLitField-68]
+ _ = x[InvalidLitField-69]
+ _ = x[UntypedLit-70]
+ _ = x[InvalidLit-71]
+ _ = x[AmbiguousSelector-72]
+ _ = x[UndeclaredImportedName-73]
+ _ = x[UnexportedName-74]
+ _ = x[UndeclaredName-75]
+ _ = x[MissingFieldOrMethod-76]
+ _ = x[BadDotDotDotSyntax-77]
+ _ = x[NonVariadicDotDotDot-78]
+ _ = x[MisplacedDotDotDot-79]
+ _ = x[InvalidDotDotDot-81]
+ _ = x[UncalledBuiltin-82]
+ _ = x[InvalidAppend-83]
+ _ = x[InvalidCap-84]
+ _ = x[InvalidClose-85]
+ _ = x[InvalidCopy-86]
+ _ = x[InvalidComplex-87]
+ _ = x[InvalidDelete-88]
+ _ = x[InvalidImag-89]
+ _ = x[InvalidLen-90]
+ _ = x[SwappedMakeArgs-91]
+ _ = x[InvalidMake-92]
+ _ = x[InvalidReal-93]
+ _ = x[InvalidAssert-94]
+ _ = x[ImpossibleAssert-95]
+ _ = x[InvalidConversion-96]
+ _ = x[InvalidUntypedConversion-97]
+ _ = x[BadOffsetofSyntax-98]
+ _ = x[InvalidOffsetof-99]
+ _ = x[UnusedExpr-100]
+ _ = x[UnusedVar-101]
+ _ = x[MissingReturn-102]
+ _ = x[WrongResultCount-103]
+ _ = x[OutOfScopeResult-104]
+ _ = x[InvalidCond-105]
+ _ = x[InvalidPostDecl-106]
+ _ = x[InvalidIterVar-108]
+ _ = x[InvalidRangeExpr-109]
+ _ = x[MisplacedBreak-110]
+ _ = x[MisplacedContinue-111]
+ _ = x[MisplacedFallthrough-112]
+ _ = x[DuplicateCase-113]
+ _ = x[DuplicateDefault-114]
+ _ = x[BadTypeKeyword-115]
+ _ = x[InvalidTypeSwitch-116]
+ _ = x[InvalidExprSwitch-117]
+ _ = x[InvalidSelectCase-118]
+ _ = x[UndeclaredLabel-119]
+ _ = x[DuplicateLabel-120]
+ _ = x[MisplacedLabel-121]
+ _ = x[UnusedLabel-122]
+ _ = x[JumpOverDecl-123]
+ _ = x[JumpIntoBlock-124]
+ _ = x[InvalidMethodExpr-125]
+ _ = x[WrongArgCount-126]
+ _ = x[InvalidCall-127]
+ _ = x[UnusedResults-128]
+ _ = x[InvalidDefer-129]
+ _ = x[InvalidGo-130]
+ _ = x[BadDecl-131]
+ _ = x[RepeatedDecl-132]
+ _ = x[InvalidUnsafeAdd-133]
+ _ = x[InvalidUnsafeSlice-134]
+ _ = x[UnsupportedFeature-135]
+ _ = x[NotAGenericType-136]
+ _ = x[WrongTypeArgCount-137]
+ _ = x[CannotInferTypeArgs-138]
+ _ = x[InvalidTypeArg-139]
+ _ = x[InvalidInstanceCycle-140]
+ _ = x[InvalidUnion-141]
+ _ = x[MisplacedConstraintIface-142]
+ _ = x[InvalidMethodTypeParams-143]
+ _ = x[MisplacedTypeParam-144]
+ _ = x[InvalidUnsafeSliceData-145]
+ _ = x[InvalidUnsafeString-146]
+ _ = x[InvalidClear-148]
+ _ = x[TypeTooLarge-149]
+ _ = x[InvalidMinMaxOperand-150]
+}
+
+const (
+ _Code_name_0 = "InvalidSyntaxTree"
+ _Code_name_1 = "TestBlankPkgNameMismatchedPkgNameInvalidPkgUseBadImportPathBrokenImportImportCRenamedUnusedImportInvalidInitCycleDuplicateDeclInvalidDeclCycleInvalidTypeCycleInvalidConstInitInvalidConstValInvalidConstTypeUntypedNilUseWrongAssignCountUnassignableOperandNoNewVarMultiValAssignOpInvalidIfaceAssignInvalidChanAssignIncompatibleAssignUnaddressableFieldAssignNotATypeInvalidArrayLenBlankIfaceMethodIncomparableMapKey"
+ _Code_name_2 = "InvalidPtrEmbedBadRecvInvalidRecvDuplicateFieldAndMethodDuplicateMethodInvalidBlankInvalidIotaMissingInitBodyInvalidInitSigInvalidInitDeclInvalidMainDeclTooManyValuesNotAnExprTruncatedFloatNumericOverflowUndefinedOpMismatchedTypesDivByZeroNonNumericIncDecUnaddressableOperandInvalidIndirectionNonIndexableOperandInvalidIndexSwappedSliceIndicesNonSliceableOperandInvalidSliceExprInvalidShiftCountInvalidShiftOperandInvalidReceiveInvalidSendDuplicateLitKeyMissingLitKeyInvalidLitIndexOversizeArrayLitMixedStructLitInvalidStructLitMissingLitFieldDuplicateLitFieldUnexportedLitFieldInvalidLitFieldUntypedLitInvalidLitAmbiguousSelectorUndeclaredImportedNameUnexportedNameUndeclaredNameMissingFieldOrMethodBadDotDotDotSyntaxNonVariadicDotDotDotMisplacedDotDotDot"
+ _Code_name_3 = "InvalidDotDotDotUncalledBuiltinInvalidAppendInvalidCapInvalidCloseInvalidCopyInvalidComplexInvalidDeleteInvalidImagInvalidLenSwappedMakeArgsInvalidMakeInvalidRealInvalidAssertImpossibleAssertInvalidConversionInvalidUntypedConversionBadOffsetofSyntaxInvalidOffsetofUnusedExprUnusedVarMissingReturnWrongResultCountOutOfScopeResultInvalidCondInvalidPostDecl"
+ _Code_name_4 = "InvalidIterVarInvalidRangeExprMisplacedBreakMisplacedContinueMisplacedFallthroughDuplicateCaseDuplicateDefaultBadTypeKeywordInvalidTypeSwitchInvalidExprSwitchInvalidSelectCaseUndeclaredLabelDuplicateLabelMisplacedLabelUnusedLabelJumpOverDeclJumpIntoBlockInvalidMethodExprWrongArgCountInvalidCallUnusedResultsInvalidDeferInvalidGoBadDeclRepeatedDeclInvalidUnsafeAddInvalidUnsafeSliceUnsupportedFeatureNotAGenericTypeWrongTypeArgCountCannotInferTypeArgsInvalidTypeArgInvalidInstanceCycleInvalidUnionMisplacedConstraintIfaceInvalidMethodTypeParamsMisplacedTypeParamInvalidUnsafeSliceDataInvalidUnsafeString"
+ _Code_name_5 = "InvalidClearTypeTooLargeInvalidMinMaxOperand"
+)
+
+var (
+ _Code_index_1 = [...]uint16{0, 4, 16, 33, 46, 59, 71, 85, 97, 113, 126, 142, 158, 174, 189, 205, 218, 234, 253, 261, 277, 295, 312, 330, 354, 362, 377, 393, 411}
+ _Code_index_2 = [...]uint16{0, 15, 22, 33, 56, 71, 83, 94, 109, 123, 138, 153, 166, 175, 189, 204, 215, 230, 239, 255, 275, 293, 312, 324, 343, 362, 378, 395, 414, 428, 439, 454, 467, 482, 498, 512, 528, 543, 560, 578, 593, 603, 613, 630, 652, 666, 680, 700, 718, 738, 756}
+ _Code_index_3 = [...]uint16{0, 16, 31, 44, 54, 66, 77, 91, 104, 115, 125, 140, 151, 162, 175, 191, 208, 232, 249, 264, 274, 283, 296, 312, 328, 339, 354}
+ _Code_index_4 = [...]uint16{0, 14, 30, 44, 61, 81, 94, 110, 124, 141, 158, 175, 190, 204, 218, 229, 241, 254, 271, 284, 295, 308, 320, 329, 336, 348, 364, 382, 400, 415, 432, 451, 465, 485, 497, 521, 544, 562, 584, 603}
+ _Code_index_5 = [...]uint8{0, 12, 24, 44}
+)
+
+func (i Code) String() string {
+ switch {
+ case i == -1:
+ return _Code_name_0
+ case 1 <= i && i <= 28:
+ i -= 1
+ return _Code_name_1[_Code_index_1[i]:_Code_index_1[i+1]]
+ case 30 <= i && i <= 79:
+ i -= 30
+ return _Code_name_2[_Code_index_2[i]:_Code_index_2[i+1]]
+ case 81 <= i && i <= 106:
+ i -= 81
+ return _Code_name_3[_Code_index_3[i]:_Code_index_3[i+1]]
+ case 108 <= i && i <= 146:
+ i -= 108
+ return _Code_name_4[_Code_index_4[i]:_Code_index_4[i+1]]
+ case 148 <= i && i <= 150:
+ i -= 148
+ return _Code_name_5[_Code_index_5[i]:_Code_index_5[i+1]]
+ default:
+ return "Code(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+}
diff --git a/contrib/go/_std_1.21/src/internal/types/errors/codes.go b/contrib/go/_std_1.21/src/internal/types/errors/codes.go
new file mode 100644
index 0000000000..62358c7e8c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/types/errors/codes.go
@@ -0,0 +1,1477 @@
+// 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 errors
+
+//go:generate stringer -type Code codes.go
+
+type Code int
+
+// This file defines the error codes that can be produced during type-checking.
+// Collectively, these codes provide an identifier that may be used to
+// implement special handling for certain types of errors.
+//
+// Error code values should not be changed: add new codes at the end.
+//
+// Error codes should be fine-grained enough that the exact nature of the error
+// can be easily determined, but coarse enough that they are not an
+// implementation detail of the type checking algorithm. As a rule-of-thumb,
+// errors should be considered equivalent if there is a theoretical refactoring
+// of the type checker in which they are emitted in exactly one place. For
+// example, the type checker emits different error messages for "too many
+// arguments" and "too few arguments", but one can imagine an alternative type
+// checker where this check instead just emits a single "wrong number of
+// arguments", so these errors should have the same code.
+//
+// Error code names should be as brief as possible while retaining accuracy and
+// distinctiveness. In most cases names should start with an adjective
+// describing the nature of the error (e.g. "invalid", "unused", "misplaced"),
+// and end with a noun identifying the relevant language object. For example,
+// "_DuplicateDecl" or "_InvalidSliceExpr". For brevity, naming follows the
+// convention that "bad" implies a problem with syntax, and "invalid" implies a
+// problem with types.
+
+const (
+ // InvalidSyntaxTree occurs if an invalid syntax tree is provided
+ // to the type checker. It should never happen.
+ InvalidSyntaxTree Code = -1
+)
+
+const (
+ // The zero Code value indicates an unset (invalid) error code.
+ _ Code = iota
+
+ // Test is reserved for errors that only apply while in self-test mode.
+ Test
+
+ // BlankPkgName occurs when a package name is the blank identifier "_".
+ //
+ // Per the spec:
+ // "The PackageName must not be the blank identifier."
+ //
+ // Example:
+ // package _
+ BlankPkgName
+
+ // MismatchedPkgName occurs when a file's package name doesn't match the
+ // package name already established by other files.
+ MismatchedPkgName
+
+ // InvalidPkgUse occurs when a package identifier is used outside of a
+ // selector expression.
+ //
+ // Example:
+ // import "fmt"
+ //
+ // var _ = fmt
+ InvalidPkgUse
+
+ // BadImportPath occurs when an import path is not valid.
+ BadImportPath
+
+ // BrokenImport occurs when importing a package fails.
+ //
+ // Example:
+ // import "amissingpackage"
+ BrokenImport
+
+ // ImportCRenamed occurs when the special import "C" is renamed. "C" is a
+ // pseudo-package, and must not be renamed.
+ //
+ // Example:
+ // import _ "C"
+ ImportCRenamed
+
+ // UnusedImport occurs when an import is unused.
+ //
+ // Example:
+ // import "fmt"
+ //
+ // func main() {}
+ UnusedImport
+
+ // InvalidInitCycle occurs when an invalid cycle is detected within the
+ // initialization graph.
+ //
+ // Example:
+ // var x int = f()
+ //
+ // func f() int { return x }
+ InvalidInitCycle
+
+ // DuplicateDecl occurs when an identifier is declared multiple times.
+ //
+ // Example:
+ // var x = 1
+ // var x = 2
+ DuplicateDecl
+
+ // InvalidDeclCycle occurs when a declaration cycle is not valid.
+ //
+ // Example:
+ // type S struct {
+ // S
+ // }
+ //
+ InvalidDeclCycle
+
+ // InvalidTypeCycle occurs when a cycle in type definitions results in a
+ // type that is not well-defined.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // type T [unsafe.Sizeof(T{})]int
+ InvalidTypeCycle
+
+ // InvalidConstInit occurs when a const declaration has a non-constant
+ // initializer.
+ //
+ // Example:
+ // var x int
+ // const _ = x
+ InvalidConstInit
+
+ // InvalidConstVal occurs when a const value cannot be converted to its
+ // target type.
+ //
+ // TODO(findleyr): this error code and example are not very clear. Consider
+ // removing it.
+ //
+ // Example:
+ // const _ = 1 << "hello"
+ InvalidConstVal
+
+ // InvalidConstType occurs when the underlying type in a const declaration
+ // is not a valid constant type.
+ //
+ // Example:
+ // const c *int = 4
+ InvalidConstType
+
+ // UntypedNilUse occurs when the predeclared (untyped) value nil is used to
+ // initialize a variable declared without an explicit type.
+ //
+ // Example:
+ // var x = nil
+ UntypedNilUse
+
+ // WrongAssignCount occurs when the number of values on the right-hand side
+ // of an assignment or initialization expression does not match the number
+ // of variables on the left-hand side.
+ //
+ // Example:
+ // var x = 1, 2
+ WrongAssignCount
+
+ // UnassignableOperand occurs when the left-hand side of an assignment is
+ // not assignable.
+ //
+ // Example:
+ // func f() {
+ // const c = 1
+ // c = 2
+ // }
+ UnassignableOperand
+
+ // NoNewVar occurs when a short variable declaration (':=') does not declare
+ // new variables.
+ //
+ // Example:
+ // func f() {
+ // x := 1
+ // x := 2
+ // }
+ NoNewVar
+
+ // MultiValAssignOp occurs when an assignment operation (+=, *=, etc) does
+ // not have single-valued left-hand or right-hand side.
+ //
+ // Per the spec:
+ // "In assignment operations, both the left- and right-hand expression lists
+ // must contain exactly one single-valued expression"
+ //
+ // Example:
+ // func f() int {
+ // x, y := 1, 2
+ // x, y += 1
+ // return x + y
+ // }
+ MultiValAssignOp
+
+ // InvalidIfaceAssign occurs when a value of type T is used as an
+ // interface, but T does not implement a method of the expected interface.
+ //
+ // Example:
+ // type I interface {
+ // f()
+ // }
+ //
+ // type T int
+ //
+ // var x I = T(1)
+ InvalidIfaceAssign
+
+ // InvalidChanAssign occurs when a chan assignment is invalid.
+ //
+ // Per the spec, a value x is assignable to a channel type T if:
+ // "x is a bidirectional channel value, T is a channel type, x's type V and
+ // T have identical element types, and at least one of V or T is not a
+ // defined type."
+ //
+ // Example:
+ // type T1 chan int
+ // type T2 chan int
+ //
+ // var x T1
+ // // Invalid assignment because both types are named
+ // var _ T2 = x
+ InvalidChanAssign
+
+ // IncompatibleAssign occurs when the type of the right-hand side expression
+ // in an assignment cannot be assigned to the type of the variable being
+ // assigned.
+ //
+ // Example:
+ // var x []int
+ // var _ int = x
+ IncompatibleAssign
+
+ // UnaddressableFieldAssign occurs when trying to assign to a struct field
+ // in a map value.
+ //
+ // Example:
+ // func f() {
+ // m := make(map[string]struct{i int})
+ // m["foo"].i = 42
+ // }
+ UnaddressableFieldAssign
+
+ // NotAType occurs when the identifier used as the underlying type in a type
+ // declaration or the right-hand side of a type alias does not denote a type.
+ //
+ // Example:
+ // var S = 2
+ //
+ // type T S
+ NotAType
+
+ // InvalidArrayLen occurs when an array length is not a constant value.
+ //
+ // Example:
+ // var n = 3
+ // var _ = [n]int{}
+ InvalidArrayLen
+
+ // BlankIfaceMethod occurs when a method name is '_'.
+ //
+ // Per the spec:
+ // "The name of each explicitly specified method must be unique and not
+ // blank."
+ //
+ // Example:
+ // type T interface {
+ // _(int)
+ // }
+ BlankIfaceMethod
+
+ // IncomparableMapKey occurs when a map key type does not support the == and
+ // != operators.
+ //
+ // Per the spec:
+ // "The comparison operators == and != must be fully defined for operands of
+ // the key type; thus the key type must not be a function, map, or slice."
+ //
+ // Example:
+ // var x map[T]int
+ //
+ // type T []int
+ IncomparableMapKey
+
+ // InvalidIfaceEmbed occurs when a non-interface type is embedded in an
+ // interface (for go 1.17 or earlier).
+ _ // not used anymore
+
+ // InvalidPtrEmbed occurs when an embedded field is of the pointer form *T,
+ // and T itself is itself a pointer, an unsafe.Pointer, or an interface.
+ //
+ // Per the spec:
+ // "An embedded field must be specified as a type name T or as a pointer to
+ // a non-interface type name *T, and T itself may not be a pointer type."
+ //
+ // Example:
+ // type T *int
+ //
+ // type S struct {
+ // *T
+ // }
+ InvalidPtrEmbed
+
+ // BadRecv occurs when a method declaration does not have exactly one
+ // receiver parameter.
+ //
+ // Example:
+ // func () _() {}
+ BadRecv
+
+ // InvalidRecv occurs when a receiver type expression is not of the form T
+ // or *T, or T is a pointer type.
+ //
+ // Example:
+ // type T struct {}
+ //
+ // func (**T) m() {}
+ InvalidRecv
+
+ // DuplicateFieldAndMethod occurs when an identifier appears as both a field
+ // and method name.
+ //
+ // Example:
+ // type T struct {
+ // m int
+ // }
+ //
+ // func (T) m() {}
+ DuplicateFieldAndMethod
+
+ // DuplicateMethod occurs when two methods on the same receiver type have
+ // the same name.
+ //
+ // Example:
+ // type T struct {}
+ // func (T) m() {}
+ // func (T) m(i int) int { return i }
+ DuplicateMethod
+
+ // InvalidBlank occurs when a blank identifier is used as a value or type.
+ //
+ // Per the spec:
+ // "The blank identifier may appear as an operand only on the left-hand side
+ // of an assignment."
+ //
+ // Example:
+ // var x = _
+ InvalidBlank
+
+ // InvalidIota occurs when the predeclared identifier iota is used outside
+ // of a constant declaration.
+ //
+ // Example:
+ // var x = iota
+ InvalidIota
+
+ // MissingInitBody occurs when an init function is missing its body.
+ //
+ // Example:
+ // func init()
+ MissingInitBody
+
+ // InvalidInitSig occurs when an init function declares parameters or
+ // results.
+ //
+ // Deprecated: no longer emitted by the type checker. _InvalidInitDecl is
+ // used instead.
+ InvalidInitSig
+
+ // InvalidInitDecl occurs when init is declared as anything other than a
+ // function.
+ //
+ // Example:
+ // var init = 1
+ //
+ // Example:
+ // func init() int { return 1 }
+ InvalidInitDecl
+
+ // InvalidMainDecl occurs when main is declared as anything other than a
+ // function, in a main package.
+ InvalidMainDecl
+
+ // TooManyValues occurs when a function returns too many values for the
+ // expression context in which it is used.
+ //
+ // Example:
+ // func ReturnTwo() (int, int) {
+ // return 1, 2
+ // }
+ //
+ // var x = ReturnTwo()
+ TooManyValues
+
+ // NotAnExpr occurs when a type expression is used where a value expression
+ // is expected.
+ //
+ // Example:
+ // type T struct {}
+ //
+ // func f() {
+ // T
+ // }
+ NotAnExpr
+
+ // TruncatedFloat occurs when a float constant is truncated to an integer
+ // value.
+ //
+ // Example:
+ // var _ int = 98.6
+ TruncatedFloat
+
+ // NumericOverflow occurs when a numeric constant overflows its target type.
+ //
+ // Example:
+ // var x int8 = 1000
+ NumericOverflow
+
+ // UndefinedOp occurs when an operator is not defined for the type(s) used
+ // in an operation.
+ //
+ // Example:
+ // var c = "a" - "b"
+ UndefinedOp
+
+ // MismatchedTypes occurs when operand types are incompatible in a binary
+ // operation.
+ //
+ // Example:
+ // var a = "hello"
+ // var b = 1
+ // var c = a - b
+ MismatchedTypes
+
+ // DivByZero occurs when a division operation is provable at compile
+ // time to be a division by zero.
+ //
+ // Example:
+ // const divisor = 0
+ // var x int = 1/divisor
+ DivByZero
+
+ // NonNumericIncDec occurs when an increment or decrement operator is
+ // applied to a non-numeric value.
+ //
+ // Example:
+ // func f() {
+ // var c = "c"
+ // c++
+ // }
+ NonNumericIncDec
+
+ // UnaddressableOperand occurs when the & operator is applied to an
+ // unaddressable expression.
+ //
+ // Example:
+ // var x = &1
+ UnaddressableOperand
+
+ // InvalidIndirection occurs when a non-pointer value is indirected via the
+ // '*' operator.
+ //
+ // Example:
+ // var x int
+ // var y = *x
+ InvalidIndirection
+
+ // NonIndexableOperand occurs when an index operation is applied to a value
+ // that cannot be indexed.
+ //
+ // Example:
+ // var x = 1
+ // var y = x[1]
+ NonIndexableOperand
+
+ // InvalidIndex occurs when an index argument is not of integer type,
+ // negative, or out-of-bounds.
+ //
+ // Example:
+ // var s = [...]int{1,2,3}
+ // var x = s[5]
+ //
+ // Example:
+ // var s = []int{1,2,3}
+ // var _ = s[-1]
+ //
+ // Example:
+ // var s = []int{1,2,3}
+ // var i string
+ // var _ = s[i]
+ InvalidIndex
+
+ // SwappedSliceIndices occurs when constant indices in a slice expression
+ // are decreasing in value.
+ //
+ // Example:
+ // var _ = []int{1,2,3}[2:1]
+ SwappedSliceIndices
+
+ // NonSliceableOperand occurs when a slice operation is applied to a value
+ // whose type is not sliceable, or is unaddressable.
+ //
+ // Example:
+ // var x = [...]int{1, 2, 3}[:1]
+ //
+ // Example:
+ // var x = 1
+ // var y = 1[:1]
+ NonSliceableOperand
+
+ // InvalidSliceExpr occurs when a three-index slice expression (a[x:y:z]) is
+ // applied to a string.
+ //
+ // Example:
+ // var s = "hello"
+ // var x = s[1:2:3]
+ InvalidSliceExpr
+
+ // InvalidShiftCount occurs when the right-hand side of a shift operation is
+ // either non-integer, negative, or too large.
+ //
+ // Example:
+ // var (
+ // x string
+ // y int = 1 << x
+ // )
+ InvalidShiftCount
+
+ // InvalidShiftOperand occurs when the shifted operand is not an integer.
+ //
+ // Example:
+ // var s = "hello"
+ // var x = s << 2
+ InvalidShiftOperand
+
+ // InvalidReceive occurs when there is a channel receive from a value that
+ // is either not a channel, or is a send-only channel.
+ //
+ // Example:
+ // func f() {
+ // var x = 1
+ // <-x
+ // }
+ InvalidReceive
+
+ // InvalidSend occurs when there is a channel send to a value that is not a
+ // channel, or is a receive-only channel.
+ //
+ // Example:
+ // func f() {
+ // var x = 1
+ // x <- "hello!"
+ // }
+ InvalidSend
+
+ // DuplicateLitKey occurs when an index is duplicated in a slice, array, or
+ // map literal.
+ //
+ // Example:
+ // var _ = []int{0:1, 0:2}
+ //
+ // Example:
+ // var _ = map[string]int{"a": 1, "a": 2}
+ DuplicateLitKey
+
+ // MissingLitKey occurs when a map literal is missing a key expression.
+ //
+ // Example:
+ // var _ = map[string]int{1}
+ MissingLitKey
+
+ // InvalidLitIndex occurs when the key in a key-value element of a slice or
+ // array literal is not an integer constant.
+ //
+ // Example:
+ // var i = 0
+ // var x = []string{i: "world"}
+ InvalidLitIndex
+
+ // OversizeArrayLit occurs when an array literal exceeds its length.
+ //
+ // Example:
+ // var _ = [2]int{1,2,3}
+ OversizeArrayLit
+
+ // MixedStructLit occurs when a struct literal contains a mix of positional
+ // and named elements.
+ //
+ // Example:
+ // var _ = struct{i, j int}{i: 1, 2}
+ MixedStructLit
+
+ // InvalidStructLit occurs when a positional struct literal has an incorrect
+ // number of values.
+ //
+ // Example:
+ // var _ = struct{i, j int}{1,2,3}
+ InvalidStructLit
+
+ // MissingLitField occurs when a struct literal refers to a field that does
+ // not exist on the struct type.
+ //
+ // Example:
+ // var _ = struct{i int}{j: 2}
+ MissingLitField
+
+ // DuplicateLitField occurs when a struct literal contains duplicated
+ // fields.
+ //
+ // Example:
+ // var _ = struct{i int}{i: 1, i: 2}
+ DuplicateLitField
+
+ // UnexportedLitField occurs when a positional struct literal implicitly
+ // assigns an unexported field of an imported type.
+ UnexportedLitField
+
+ // InvalidLitField occurs when a field name is not a valid identifier.
+ //
+ // Example:
+ // var _ = struct{i int}{1: 1}
+ InvalidLitField
+
+ // UntypedLit occurs when a composite literal omits a required type
+ // identifier.
+ //
+ // Example:
+ // type outer struct{
+ // inner struct { i int }
+ // }
+ //
+ // var _ = outer{inner: {1}}
+ UntypedLit
+
+ // InvalidLit occurs when a composite literal expression does not match its
+ // type.
+ //
+ // Example:
+ // type P *struct{
+ // x int
+ // }
+ // var _ = P {}
+ InvalidLit
+
+ // AmbiguousSelector occurs when a selector is ambiguous.
+ //
+ // Example:
+ // type E1 struct { i int }
+ // type E2 struct { i int }
+ // type T struct { E1; E2 }
+ //
+ // var x T
+ // var _ = x.i
+ AmbiguousSelector
+
+ // UndeclaredImportedName occurs when a package-qualified identifier is
+ // undeclared by the imported package.
+ //
+ // Example:
+ // import "go/types"
+ //
+ // var _ = types.NotAnActualIdentifier
+ UndeclaredImportedName
+
+ // UnexportedName occurs when a selector refers to an unexported identifier
+ // of an imported package.
+ //
+ // Example:
+ // import "reflect"
+ //
+ // type _ reflect.flag
+ UnexportedName
+
+ // UndeclaredName occurs when an identifier is not declared in the current
+ // scope.
+ //
+ // Example:
+ // var x T
+ UndeclaredName
+
+ // MissingFieldOrMethod occurs when a selector references a field or method
+ // that does not exist.
+ //
+ // Example:
+ // type T struct {}
+ //
+ // var x = T{}.f
+ MissingFieldOrMethod
+
+ // BadDotDotDotSyntax occurs when a "..." occurs in a context where it is
+ // not valid.
+ //
+ // Example:
+ // var _ = map[int][...]int{0: {}}
+ BadDotDotDotSyntax
+
+ // NonVariadicDotDotDot occurs when a "..." is used on the final argument to
+ // a non-variadic function.
+ //
+ // Example:
+ // func printArgs(s []string) {
+ // for _, a := range s {
+ // println(a)
+ // }
+ // }
+ //
+ // func f() {
+ // s := []string{"a", "b", "c"}
+ // printArgs(s...)
+ // }
+ NonVariadicDotDotDot
+
+ // MisplacedDotDotDot occurs when a "..." is used somewhere other than the
+ // final argument in a function declaration.
+ //
+ // Example:
+ // func f(...int, int)
+ MisplacedDotDotDot
+
+ _ // InvalidDotDotDotOperand was removed.
+
+ // InvalidDotDotDot occurs when a "..." is used in a non-variadic built-in
+ // function.
+ //
+ // Example:
+ // var s = []int{1, 2, 3}
+ // var l = len(s...)
+ InvalidDotDotDot
+
+ // UncalledBuiltin occurs when a built-in function is used as a
+ // function-valued expression, instead of being called.
+ //
+ // Per the spec:
+ // "The built-in functions do not have standard Go types, so they can only
+ // appear in call expressions; they cannot be used as function values."
+ //
+ // Example:
+ // var _ = copy
+ UncalledBuiltin
+
+ // InvalidAppend occurs when append is called with a first argument that is
+ // not a slice.
+ //
+ // Example:
+ // var _ = append(1, 2)
+ InvalidAppend
+
+ // InvalidCap occurs when an argument to the cap built-in function is not of
+ // supported type.
+ //
+ // See https://golang.org/ref/spec#Length_and_capacity for information on
+ // which underlying types are supported as arguments to cap and len.
+ //
+ // Example:
+ // var s = 2
+ // var x = cap(s)
+ InvalidCap
+
+ // InvalidClose occurs when close(...) is called with an argument that is
+ // not of channel type, or that is a receive-only channel.
+ //
+ // Example:
+ // func f() {
+ // var x int
+ // close(x)
+ // }
+ InvalidClose
+
+ // InvalidCopy occurs when the arguments are not of slice type or do not
+ // have compatible type.
+ //
+ // See https://golang.org/ref/spec#Appending_and_copying_slices for more
+ // information on the type requirements for the copy built-in.
+ //
+ // Example:
+ // func f() {
+ // var x []int
+ // y := []int64{1,2,3}
+ // copy(x, y)
+ // }
+ InvalidCopy
+
+ // InvalidComplex occurs when the complex built-in function is called with
+ // arguments with incompatible types.
+ //
+ // Example:
+ // var _ = complex(float32(1), float64(2))
+ InvalidComplex
+
+ // InvalidDelete occurs when the delete built-in function is called with a
+ // first argument that is not a map.
+ //
+ // Example:
+ // func f() {
+ // m := "hello"
+ // delete(m, "e")
+ // }
+ InvalidDelete
+
+ // InvalidImag occurs when the imag built-in function is called with an
+ // argument that does not have complex type.
+ //
+ // Example:
+ // var _ = imag(int(1))
+ InvalidImag
+
+ // InvalidLen occurs when an argument to the len built-in function is not of
+ // supported type.
+ //
+ // See https://golang.org/ref/spec#Length_and_capacity for information on
+ // which underlying types are supported as arguments to cap and len.
+ //
+ // Example:
+ // var s = 2
+ // var x = len(s)
+ InvalidLen
+
+ // SwappedMakeArgs occurs when make is called with three arguments, and its
+ // length argument is larger than its capacity argument.
+ //
+ // Example:
+ // var x = make([]int, 3, 2)
+ SwappedMakeArgs
+
+ // InvalidMake occurs when make is called with an unsupported type argument.
+ //
+ // See https://golang.org/ref/spec#Making_slices_maps_and_channels for
+ // information on the types that may be created using make.
+ //
+ // Example:
+ // var x = make(int)
+ InvalidMake
+
+ // InvalidReal occurs when the real built-in function is called with an
+ // argument that does not have complex type.
+ //
+ // Example:
+ // var _ = real(int(1))
+ InvalidReal
+
+ // InvalidAssert occurs when a type assertion is applied to a
+ // value that is not of interface type.
+ //
+ // Example:
+ // var x = 1
+ // var _ = x.(float64)
+ InvalidAssert
+
+ // ImpossibleAssert occurs for a type assertion x.(T) when the value x of
+ // interface cannot have dynamic type T, due to a missing or mismatching
+ // method on T.
+ //
+ // Example:
+ // type T int
+ //
+ // func (t *T) m() int { return int(*t) }
+ //
+ // type I interface { m() int }
+ //
+ // var x I
+ // var _ = x.(T)
+ ImpossibleAssert
+
+ // InvalidConversion occurs when the argument type cannot be converted to the
+ // target.
+ //
+ // See https://golang.org/ref/spec#Conversions for the rules of
+ // convertibility.
+ //
+ // Example:
+ // var x float64
+ // var _ = string(x)
+ InvalidConversion
+
+ // InvalidUntypedConversion occurs when there is no valid implicit
+ // conversion from an untyped value satisfying the type constraints of the
+ // context in which it is used.
+ //
+ // Example:
+ // var _ = 1 + []int{}
+ InvalidUntypedConversion
+
+ // BadOffsetofSyntax occurs when unsafe.Offsetof is called with an argument
+ // that is not a selector expression.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var x int
+ // var _ = unsafe.Offsetof(x)
+ BadOffsetofSyntax
+
+ // InvalidOffsetof occurs when unsafe.Offsetof is called with a method
+ // selector, rather than a field selector, or when the field is embedded via
+ // a pointer.
+ //
+ // Per the spec:
+ //
+ // "If f is an embedded field, it must be reachable without pointer
+ // indirections through fields of the struct. "
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // type T struct { f int }
+ // type S struct { *T }
+ // var s S
+ // var _ = unsafe.Offsetof(s.f)
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // type S struct{}
+ //
+ // func (S) m() {}
+ //
+ // var s S
+ // var _ = unsafe.Offsetof(s.m)
+ InvalidOffsetof
+
+ // UnusedExpr occurs when a side-effect free expression is used as a
+ // statement. Such a statement has no effect.
+ //
+ // Example:
+ // func f(i int) {
+ // i*i
+ // }
+ UnusedExpr
+
+ // UnusedVar occurs when a variable is declared but unused.
+ //
+ // Example:
+ // func f() {
+ // x := 1
+ // }
+ UnusedVar
+
+ // MissingReturn occurs when a function with results is missing a return
+ // statement.
+ //
+ // Example:
+ // func f() int {}
+ MissingReturn
+
+ // WrongResultCount occurs when a return statement returns an incorrect
+ // number of values.
+ //
+ // Example:
+ // func ReturnOne() int {
+ // return 1, 2
+ // }
+ WrongResultCount
+
+ // OutOfScopeResult occurs when the name of a value implicitly returned by
+ // an empty return statement is shadowed in a nested scope.
+ //
+ // Example:
+ // func factor(n int) (i int) {
+ // for i := 2; i < n; i++ {
+ // if n%i == 0 {
+ // return
+ // }
+ // }
+ // return 0
+ // }
+ OutOfScopeResult
+
+ // InvalidCond occurs when an if condition is not a boolean expression.
+ //
+ // Example:
+ // func checkReturn(i int) {
+ // if i {
+ // panic("non-zero return")
+ // }
+ // }
+ InvalidCond
+
+ // InvalidPostDecl occurs when there is a declaration in a for-loop post
+ // statement.
+ //
+ // Example:
+ // func f() {
+ // for i := 0; i < 10; j := 0 {}
+ // }
+ InvalidPostDecl
+
+ _ // InvalidChanRange was removed.
+
+ // InvalidIterVar occurs when two iteration variables are used while ranging
+ // over a channel.
+ //
+ // Example:
+ // func f(c chan int) {
+ // for k, v := range c {
+ // println(k, v)
+ // }
+ // }
+ InvalidIterVar
+
+ // InvalidRangeExpr occurs when the type of a range expression is not array,
+ // slice, string, map, or channel.
+ //
+ // Example:
+ // func f(i int) {
+ // for j := range i {
+ // println(j)
+ // }
+ // }
+ InvalidRangeExpr
+
+ // MisplacedBreak occurs when a break statement is not within a for, switch,
+ // or select statement of the innermost function definition.
+ //
+ // Example:
+ // func f() {
+ // break
+ // }
+ MisplacedBreak
+
+ // MisplacedContinue occurs when a continue statement is not within a for
+ // loop of the innermost function definition.
+ //
+ // Example:
+ // func sumeven(n int) int {
+ // proceed := func() {
+ // continue
+ // }
+ // sum := 0
+ // for i := 1; i <= n; i++ {
+ // if i % 2 != 0 {
+ // proceed()
+ // }
+ // sum += i
+ // }
+ // return sum
+ // }
+ MisplacedContinue
+
+ // MisplacedFallthrough occurs when a fallthrough statement is not within an
+ // expression switch.
+ //
+ // Example:
+ // func typename(i interface{}) string {
+ // switch i.(type) {
+ // case int64:
+ // fallthrough
+ // case int:
+ // return "int"
+ // }
+ // return "unsupported"
+ // }
+ MisplacedFallthrough
+
+ // DuplicateCase occurs when a type or expression switch has duplicate
+ // cases.
+ //
+ // Example:
+ // func printInt(i int) {
+ // switch i {
+ // case 1:
+ // println("one")
+ // case 1:
+ // println("One")
+ // }
+ // }
+ DuplicateCase
+
+ // DuplicateDefault occurs when a type or expression switch has multiple
+ // default clauses.
+ //
+ // Example:
+ // func printInt(i int) {
+ // switch i {
+ // case 1:
+ // println("one")
+ // default:
+ // println("One")
+ // default:
+ // println("1")
+ // }
+ // }
+ DuplicateDefault
+
+ // BadTypeKeyword occurs when a .(type) expression is used anywhere other
+ // than a type switch.
+ //
+ // Example:
+ // type I interface {
+ // m()
+ // }
+ // var t I
+ // var _ = t.(type)
+ BadTypeKeyword
+
+ // InvalidTypeSwitch occurs when .(type) is used on an expression that is
+ // not of interface type.
+ //
+ // Example:
+ // func f(i int) {
+ // switch x := i.(type) {}
+ // }
+ InvalidTypeSwitch
+
+ // InvalidExprSwitch occurs when a switch expression is not comparable.
+ //
+ // Example:
+ // func _() {
+ // var a struct{ _ func() }
+ // switch a /* ERROR cannot switch on a */ {
+ // }
+ // }
+ InvalidExprSwitch
+
+ // InvalidSelectCase occurs when a select case is not a channel send or
+ // receive.
+ //
+ // Example:
+ // func checkChan(c <-chan int) bool {
+ // select {
+ // case c:
+ // return true
+ // default:
+ // return false
+ // }
+ // }
+ InvalidSelectCase
+
+ // UndeclaredLabel occurs when an undeclared label is jumped to.
+ //
+ // Example:
+ // func f() {
+ // goto L
+ // }
+ UndeclaredLabel
+
+ // DuplicateLabel occurs when a label is declared more than once.
+ //
+ // Example:
+ // func f() int {
+ // L:
+ // L:
+ // return 1
+ // }
+ DuplicateLabel
+
+ // MisplacedLabel occurs when a break or continue label is not on a for,
+ // switch, or select statement.
+ //
+ // Example:
+ // func f() {
+ // L:
+ // a := []int{1,2,3}
+ // for _, e := range a {
+ // if e > 10 {
+ // break L
+ // }
+ // println(a)
+ // }
+ // }
+ MisplacedLabel
+
+ // UnusedLabel occurs when a label is declared and not used.
+ //
+ // Example:
+ // func f() {
+ // L:
+ // }
+ UnusedLabel
+
+ // JumpOverDecl occurs when a label jumps over a variable declaration.
+ //
+ // Example:
+ // func f() int {
+ // goto L
+ // x := 2
+ // L:
+ // x++
+ // return x
+ // }
+ JumpOverDecl
+
+ // JumpIntoBlock occurs when a forward jump goes to a label inside a nested
+ // block.
+ //
+ // Example:
+ // func f(x int) {
+ // goto L
+ // if x > 0 {
+ // L:
+ // print("inside block")
+ // }
+ // }
+ JumpIntoBlock
+
+ // InvalidMethodExpr occurs when a pointer method is called but the argument
+ // is not addressable.
+ //
+ // Example:
+ // type T struct {}
+ //
+ // func (*T) m() int { return 1 }
+ //
+ // var _ = T.m(T{})
+ InvalidMethodExpr
+
+ // WrongArgCount occurs when too few or too many arguments are passed by a
+ // function call.
+ //
+ // Example:
+ // func f(i int) {}
+ // var x = f()
+ WrongArgCount
+
+ // InvalidCall occurs when an expression is called that is not of function
+ // type.
+ //
+ // Example:
+ // var x = "x"
+ // var y = x()
+ InvalidCall
+
+ // UnusedResults occurs when a restricted expression-only built-in function
+ // is suspended via go or defer. Such a suspension discards the results of
+ // these side-effect free built-in functions, and therefore is ineffectual.
+ //
+ // Example:
+ // func f(a []int) int {
+ // defer len(a)
+ // return i
+ // }
+ UnusedResults
+
+ // InvalidDefer occurs when a deferred expression is not a function call,
+ // for example if the expression is a type conversion.
+ //
+ // Example:
+ // func f(i int) int {
+ // defer int32(i)
+ // return i
+ // }
+ InvalidDefer
+
+ // InvalidGo occurs when a go expression is not a function call, for example
+ // if the expression is a type conversion.
+ //
+ // Example:
+ // func f(i int) int {
+ // go int32(i)
+ // return i
+ // }
+ InvalidGo
+
+ // All codes below were added in Go 1.17.
+
+ // BadDecl occurs when a declaration has invalid syntax.
+ BadDecl
+
+ // RepeatedDecl occurs when an identifier occurs more than once on the left
+ // hand side of a short variable declaration.
+ //
+ // Example:
+ // func _() {
+ // x, y, y := 1, 2, 3
+ // }
+ RepeatedDecl
+
+ // InvalidUnsafeAdd occurs when unsafe.Add is called with a
+ // length argument that is not of integer type.
+ // It also occurs if it is used in a package compiled for a
+ // language version before go1.17.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var p unsafe.Pointer
+ // var _ = unsafe.Add(p, float64(1))
+ InvalidUnsafeAdd
+
+ // InvalidUnsafeSlice occurs when unsafe.Slice is called with a
+ // pointer argument that is not of pointer type or a length argument
+ // that is not of integer type, negative, or out of bounds.
+ // It also occurs if it is used in a package compiled for a language
+ // version before go1.17.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var x int
+ // var _ = unsafe.Slice(x, 1)
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var x int
+ // var _ = unsafe.Slice(&x, float64(1))
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var x int
+ // var _ = unsafe.Slice(&x, -1)
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var x int
+ // var _ = unsafe.Slice(&x, uint64(1) << 63)
+ InvalidUnsafeSlice
+
+ // All codes below were added in Go 1.18.
+
+ // UnsupportedFeature occurs when a language feature is used that is not
+ // supported at this Go version.
+ UnsupportedFeature
+
+ // NotAGenericType occurs when a non-generic type is used where a generic
+ // type is expected: in type or function instantiation.
+ //
+ // Example:
+ // type T int
+ //
+ // var _ T[int]
+ NotAGenericType
+
+ // WrongTypeArgCount occurs when a type or function is instantiated with an
+ // incorrect number of type arguments, including when a generic type or
+ // function is used without instantiation.
+ //
+ // Errors involving failed type inference are assigned other error codes.
+ //
+ // Example:
+ // type T[p any] int
+ //
+ // var _ T[int, string]
+ //
+ // Example:
+ // func f[T any]() {}
+ //
+ // var x = f
+ WrongTypeArgCount
+
+ // CannotInferTypeArgs occurs when type or function type argument inference
+ // fails to infer all type arguments.
+ //
+ // Example:
+ // func f[T any]() {}
+ //
+ // func _() {
+ // f()
+ // }
+ CannotInferTypeArgs
+
+ // InvalidTypeArg occurs when a type argument does not satisfy its
+ // corresponding type parameter constraints.
+ //
+ // Example:
+ // type T[P ~int] struct{}
+ //
+ // var _ T[string]
+ InvalidTypeArg // arguments? InferenceFailed
+
+ // InvalidInstanceCycle occurs when an invalid cycle is detected
+ // within the instantiation graph.
+ //
+ // Example:
+ // func f[T any]() { f[*T]() }
+ InvalidInstanceCycle
+
+ // InvalidUnion occurs when an embedded union or approximation element is
+ // not valid.
+ //
+ // Example:
+ // type _ interface {
+ // ~int | interface{ m() }
+ // }
+ InvalidUnion
+
+ // MisplacedConstraintIface occurs when a constraint-type interface is used
+ // outside of constraint position.
+ //
+ // Example:
+ // type I interface { ~int }
+ //
+ // var _ I
+ MisplacedConstraintIface
+
+ // InvalidMethodTypeParams occurs when methods have type parameters.
+ //
+ // It cannot be encountered with an AST parsed using go/parser.
+ InvalidMethodTypeParams
+
+ // MisplacedTypeParam occurs when a type parameter is used in a place where
+ // it is not permitted.
+ //
+ // Example:
+ // type T[P any] P
+ //
+ // Example:
+ // type T[P any] struct{ *P }
+ MisplacedTypeParam
+
+ // InvalidUnsafeSliceData occurs when unsafe.SliceData is called with
+ // an argument that is not of slice type. It also occurs if it is used
+ // in a package compiled for a language version before go1.20.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var x int
+ // var _ = unsafe.SliceData(x)
+ InvalidUnsafeSliceData
+
+ // InvalidUnsafeString occurs when unsafe.String is called with
+ // a length argument that is not of integer type, negative, or
+ // out of bounds. It also occurs if it is used in a package
+ // compiled for a language version before go1.20.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // var b [10]byte
+ // var _ = unsafe.String(&b[0], -1)
+ InvalidUnsafeString
+
+ // InvalidUnsafeStringData occurs if it is used in a package
+ // compiled for a language version before go1.20.
+ _ // not used anymore
+
+ // InvalidClear occurs when clear is called with an argument
+ // that is not of map or slice type.
+ //
+ // Example:
+ // func _(x int) {
+ // clear(x)
+ // }
+ InvalidClear
+
+ // TypeTooLarge occurs if unsafe.Sizeof or unsafe.Offsetof is
+ // called with an expression whose type is too large.
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // type E [1 << 31 - 1]int
+ // var a [1 << 31]E
+ // var _ = unsafe.Sizeof(a)
+ //
+ // Example:
+ // import "unsafe"
+ //
+ // type E [1 << 31 - 1]int
+ // var s struct {
+ // _ [1 << 31]E
+ // x int
+ // }
+ // var _ = unsafe.Offsetof(s.x)
+ TypeTooLarge
+
+ // InvalidMinMaxOperand occurs if min or max is called
+ // with an operand that cannot be ordered because it
+ // does not support the < operator.
+ //
+ // Example:
+ // const _ = min(true)
+ //
+ // Example:
+ // var s, t []byte
+ // var _ = max(s, t)
+ InvalidMinMaxOperand
+)
diff --git a/contrib/go/_std_1.21/src/internal/types/errors/ya.make b/contrib/go/_std_1.21/src/internal/types/errors/ya.make
new file mode 100644
index 0000000000..f4363060a8
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/types/errors/ya.make
@@ -0,0 +1,13 @@
+GO_LIBRARY()
+
+SRCS(
+ code_string.go
+ codes.go
+)
+
+GO_XTEST_SRCS(codes_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/internal/unsafeheader/unsafeheader.go b/contrib/go/_std_1.21/src/internal/unsafeheader/unsafeheader.go
index 6d092c629a..6d092c629a 100644
--- a/contrib/go/_std_1.20/src/internal/unsafeheader/unsafeheader.go
+++ b/contrib/go/_std_1.21/src/internal/unsafeheader/unsafeheader.go
diff --git a/contrib/go/_std_1.21/src/internal/unsafeheader/ya.make b/contrib/go/_std_1.21/src/internal/unsafeheader/ya.make
new file mode 100644
index 0000000000..268e61003d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/unsafeheader/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ unsafeheader.go
+)
+
+GO_XTEST_SRCS(unsafeheader_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/internal/xcoff/ar.go b/contrib/go/_std_1.21/src/internal/xcoff/ar.go
new file mode 100644
index 0000000000..9cbd50d149
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/xcoff/ar.go
@@ -0,0 +1,226 @@
+// Copyright 2018 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 xcoff
+
+import (
+ "encoding/binary"
+ "fmt"
+ "io"
+ "os"
+ "strconv"
+ "strings"
+)
+
+const (
+ SAIAMAG = 0x8
+ AIAFMAG = "`\n"
+ AIAMAG = "<aiaff>\n"
+ AIAMAGBIG = "<bigaf>\n"
+
+ // Sizeof
+ FL_HSZ_BIG = 0x80
+ AR_HSZ_BIG = 0x70
+)
+
+type bigarFileHeader struct {
+ Flmagic [SAIAMAG]byte // Archive magic string
+ Flmemoff [20]byte // Member table offset
+ Flgstoff [20]byte // 32-bits global symtab offset
+ Flgst64off [20]byte // 64-bits global symtab offset
+ Flfstmoff [20]byte // First member offset
+ Fllstmoff [20]byte // Last member offset
+ Flfreeoff [20]byte // First member on free list offset
+}
+
+type bigarMemberHeader struct {
+ Arsize [20]byte // File member size
+ Arnxtmem [20]byte // Next member pointer
+ Arprvmem [20]byte // Previous member pointer
+ Ardate [12]byte // File member date
+ Aruid [12]byte // File member uid
+ Argid [12]byte // File member gid
+ Armode [12]byte // File member mode (octal)
+ Arnamlen [4]byte // File member name length
+ // _ar_nam is removed because it's easier to get name without it.
+}
+
+// Archive represents an open AIX big archive.
+type Archive struct {
+ ArchiveHeader
+ Members []*Member
+
+ closer io.Closer
+}
+
+// MemberHeader holds information about a big archive file header
+type ArchiveHeader struct {
+ magic string
+}
+
+// Member represents a member of an AIX big archive.
+type Member struct {
+ MemberHeader
+ sr *io.SectionReader
+}
+
+// MemberHeader holds information about a big archive member
+type MemberHeader struct {
+ Name string
+ Size uint64
+}
+
+// OpenArchive opens the named archive using os.Open and prepares it for use
+// as an AIX big archive.
+func OpenArchive(name string) (*Archive, error) {
+ f, err := os.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ arch, err := NewArchive(f)
+ if err != nil {
+ f.Close()
+ return nil, err
+ }
+ arch.closer = f
+ return arch, nil
+}
+
+// Close closes the Archive.
+// If the Archive was created using NewArchive directly instead of OpenArchive,
+// Close has no effect.
+func (a *Archive) Close() error {
+ var err error
+ if a.closer != nil {
+ err = a.closer.Close()
+ a.closer = nil
+ }
+ return err
+}
+
+// NewArchive creates a new Archive for accessing an AIX big archive in an underlying reader.
+func NewArchive(r io.ReaderAt) (*Archive, error) {
+ parseDecimalBytes := func(b []byte) (int64, error) {
+ return strconv.ParseInt(strings.TrimSpace(string(b)), 10, 64)
+ }
+ sr := io.NewSectionReader(r, 0, 1<<63-1)
+
+ // Read File Header
+ var magic [SAIAMAG]byte
+ if _, err := sr.ReadAt(magic[:], 0); err != nil {
+ return nil, err
+ }
+
+ arch := new(Archive)
+ switch string(magic[:]) {
+ case AIAMAGBIG:
+ arch.magic = string(magic[:])
+ case AIAMAG:
+ return nil, fmt.Errorf("small AIX archive not supported")
+ default:
+ return nil, fmt.Errorf("unrecognised archive magic: 0x%x", magic)
+ }
+
+ var fhdr bigarFileHeader
+ if _, err := sr.Seek(0, io.SeekStart); err != nil {
+ return nil, err
+ }
+ if err := binary.Read(sr, binary.BigEndian, &fhdr); err != nil {
+ return nil, err
+ }
+
+ off, err := parseDecimalBytes(fhdr.Flfstmoff[:])
+ if err != nil {
+ return nil, fmt.Errorf("error parsing offset of first member in archive header(%q); %v", fhdr, err)
+ }
+
+ if off == 0 {
+ // Occurs if the archive is empty.
+ return arch, nil
+ }
+
+ lastoff, err := parseDecimalBytes(fhdr.Fllstmoff[:])
+ if err != nil {
+ return nil, fmt.Errorf("error parsing offset of first member in archive header(%q); %v", fhdr, err)
+ }
+
+ // Read members
+ for {
+ // Read Member Header
+ // The member header is normally 2 bytes larger. But it's easier
+ // to read the name if the header is read without _ar_nam.
+ // However, AIAFMAG must be read afterward.
+ if _, err := sr.Seek(off, io.SeekStart); err != nil {
+ return nil, err
+ }
+
+ var mhdr bigarMemberHeader
+ if err := binary.Read(sr, binary.BigEndian, &mhdr); err != nil {
+ return nil, err
+ }
+
+ member := new(Member)
+ arch.Members = append(arch.Members, member)
+
+ size, err := parseDecimalBytes(mhdr.Arsize[:])
+ if err != nil {
+ return nil, fmt.Errorf("error parsing size in member header(%q); %v", mhdr, err)
+ }
+ member.Size = uint64(size)
+
+ // Read name
+ namlen, err := parseDecimalBytes(mhdr.Arnamlen[:])
+ if err != nil {
+ return nil, fmt.Errorf("error parsing name length in member header(%q); %v", mhdr, err)
+ }
+ name := make([]byte, namlen)
+ if err := binary.Read(sr, binary.BigEndian, name); err != nil {
+ return nil, err
+ }
+ member.Name = string(name)
+
+ fileoff := off + AR_HSZ_BIG + namlen
+ if fileoff&1 != 0 {
+ fileoff++
+ if _, err := sr.Seek(1, io.SeekCurrent); err != nil {
+ return nil, err
+ }
+ }
+
+ // Read AIAFMAG string
+ var fmag [2]byte
+ if err := binary.Read(sr, binary.BigEndian, &fmag); err != nil {
+ return nil, err
+ }
+ if string(fmag[:]) != AIAFMAG {
+ return nil, fmt.Errorf("AIAFMAG not found after member header")
+ }
+
+ fileoff += 2 // Add the two bytes of AIAFMAG
+ member.sr = io.NewSectionReader(sr, fileoff, size)
+
+ if off == lastoff {
+ break
+ }
+ off, err = parseDecimalBytes(mhdr.Arnxtmem[:])
+ if err != nil {
+ return nil, fmt.Errorf("error parsing offset of first member in archive header(%q); %v", fhdr, err)
+ }
+
+ }
+
+ return arch, nil
+}
+
+// GetFile returns the XCOFF file defined by member name.
+// FIXME: This doesn't work if an archive has two members with the same
+// name which can occur if an archive has both 32-bits and 64-bits files.
+func (arch *Archive) GetFile(name string) (*File, error) {
+ for _, mem := range arch.Members {
+ if mem.Name == name {
+ return NewFile(mem.sr)
+ }
+ }
+ return nil, fmt.Errorf("unknown member %s in archive", name)
+}
diff --git a/contrib/go/_std_1.21/src/internal/xcoff/file.go b/contrib/go/_std_1.21/src/internal/xcoff/file.go
new file mode 100644
index 0000000000..9135822f22
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/xcoff/file.go
@@ -0,0 +1,697 @@
+// Copyright 2018 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 xcoff implements access to XCOFF (Extended Common Object File Format) files.
+package xcoff
+
+import (
+ "debug/dwarf"
+ "encoding/binary"
+ "fmt"
+ "internal/saferio"
+ "io"
+ "os"
+ "strings"
+)
+
+// SectionHeader holds information about an XCOFF section header.
+type SectionHeader struct {
+ Name string
+ VirtualAddress uint64
+ Size uint64
+ Type uint32
+ Relptr uint64
+ Nreloc uint32
+}
+
+type Section struct {
+ SectionHeader
+ Relocs []Reloc
+ io.ReaderAt
+ sr *io.SectionReader
+}
+
+// AuxiliaryCSect holds information about an XCOFF symbol in an AUX_CSECT entry.
+type AuxiliaryCSect struct {
+ Length int64
+ StorageMappingClass int
+ SymbolType int
+}
+
+// AuxiliaryFcn holds information about an XCOFF symbol in an AUX_FCN entry.
+type AuxiliaryFcn struct {
+ Size int64
+}
+
+type Symbol struct {
+ Name string
+ Value uint64
+ SectionNumber int
+ StorageClass int
+ AuxFcn AuxiliaryFcn
+ AuxCSect AuxiliaryCSect
+}
+
+type Reloc struct {
+ VirtualAddress uint64
+ Symbol *Symbol
+ Signed bool
+ InstructionFixed bool
+ Length uint8
+ Type uint8
+}
+
+// ImportedSymbol holds information about an imported XCOFF symbol.
+type ImportedSymbol struct {
+ Name string
+ Library string
+}
+
+// FileHeader holds information about an XCOFF file header.
+type FileHeader struct {
+ TargetMachine uint16
+}
+
+// A File represents an open XCOFF file.
+type File struct {
+ FileHeader
+ Sections []*Section
+ Symbols []*Symbol
+ StringTable []byte
+ LibraryPaths []string
+
+ closer io.Closer
+}
+
+// Open opens the named file using os.Open and prepares it for use as an XCOFF binary.
+func Open(name string) (*File, error) {
+ f, err := os.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ ff, err := NewFile(f)
+ if err != nil {
+ f.Close()
+ return nil, err
+ }
+ ff.closer = f
+ return ff, nil
+}
+
+// Close closes the File.
+// If the File was created using NewFile directly instead of Open,
+// Close has no effect.
+func (f *File) Close() error {
+ var err error
+ if f.closer != nil {
+ err = f.closer.Close()
+ f.closer = nil
+ }
+ return err
+}
+
+// Section returns the first section with the given name, or nil if no such
+// section exists.
+// Xcoff have section's name limited to 8 bytes. Some sections like .gosymtab
+// can be trunked but this method will still find them.
+func (f *File) Section(name string) *Section {
+ for _, s := range f.Sections {
+ if s.Name == name || (len(name) > 8 && s.Name == name[:8]) {
+ return s
+ }
+ }
+ return nil
+}
+
+// SectionByType returns the first section in f with the
+// given type, or nil if there is no such section.
+func (f *File) SectionByType(typ uint32) *Section {
+ for _, s := range f.Sections {
+ if s.Type == typ {
+ return s
+ }
+ }
+ return nil
+}
+
+// cstring converts ASCII byte sequence b to string.
+// It stops once it finds 0 or reaches end of b.
+func cstring(b []byte) string {
+ var i int
+ for i = 0; i < len(b) && b[i] != 0; i++ {
+ }
+ return string(b[:i])
+}
+
+// getString extracts a string from an XCOFF string table.
+func getString(st []byte, offset uint32) (string, bool) {
+ if offset < 4 || int(offset) >= len(st) {
+ return "", false
+ }
+ return cstring(st[offset:]), true
+}
+
+// NewFile creates a new File for accessing an XCOFF binary in an underlying reader.
+func NewFile(r io.ReaderAt) (*File, error) {
+ sr := io.NewSectionReader(r, 0, 1<<63-1)
+ // Read XCOFF target machine
+ var magic uint16
+ if err := binary.Read(sr, binary.BigEndian, &magic); err != nil {
+ return nil, err
+ }
+ if magic != U802TOCMAGIC && magic != U64_TOCMAGIC {
+ return nil, fmt.Errorf("unrecognised XCOFF magic: 0x%x", magic)
+ }
+
+ f := new(File)
+ f.TargetMachine = magic
+
+ // Read XCOFF file header
+ if _, err := sr.Seek(0, io.SeekStart); err != nil {
+ return nil, err
+ }
+ var nscns uint16
+ var symptr uint64
+ var nsyms uint32
+ var opthdr uint16
+ var hdrsz int
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ fhdr := new(FileHeader32)
+ if err := binary.Read(sr, binary.BigEndian, fhdr); err != nil {
+ return nil, err
+ }
+ nscns = fhdr.Fnscns
+ symptr = uint64(fhdr.Fsymptr)
+ nsyms = fhdr.Fnsyms
+ opthdr = fhdr.Fopthdr
+ hdrsz = FILHSZ_32
+ case U64_TOCMAGIC:
+ fhdr := new(FileHeader64)
+ if err := binary.Read(sr, binary.BigEndian, fhdr); err != nil {
+ return nil, err
+ }
+ nscns = fhdr.Fnscns
+ symptr = fhdr.Fsymptr
+ nsyms = fhdr.Fnsyms
+ opthdr = fhdr.Fopthdr
+ hdrsz = FILHSZ_64
+ }
+
+ if symptr == 0 || nsyms <= 0 {
+ return nil, fmt.Errorf("no symbol table")
+ }
+
+ // Read string table (located right after symbol table).
+ offset := symptr + uint64(nsyms)*SYMESZ
+ if _, err := sr.Seek(int64(offset), io.SeekStart); err != nil {
+ return nil, err
+ }
+ // The first 4 bytes contain the length (in bytes).
+ var l uint32
+ if err := binary.Read(sr, binary.BigEndian, &l); err != nil {
+ return nil, err
+ }
+ if l > 4 {
+ st, err := saferio.ReadDataAt(sr, uint64(l), int64(offset))
+ if err != nil {
+ return nil, err
+ }
+ f.StringTable = st
+ }
+
+ // Read section headers
+ if _, err := sr.Seek(int64(hdrsz)+int64(opthdr), io.SeekStart); err != nil {
+ return nil, err
+ }
+ c := saferio.SliceCap((**Section)(nil), uint64(nscns))
+ if c < 0 {
+ return nil, fmt.Errorf("too many XCOFF sections (%d)", nscns)
+ }
+ f.Sections = make([]*Section, 0, c)
+ for i := 0; i < int(nscns); i++ {
+ var scnptr uint64
+ s := new(Section)
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ shdr := new(SectionHeader32)
+ if err := binary.Read(sr, binary.BigEndian, shdr); err != nil {
+ return nil, err
+ }
+ s.Name = cstring(shdr.Sname[:])
+ s.VirtualAddress = uint64(shdr.Svaddr)
+ s.Size = uint64(shdr.Ssize)
+ scnptr = uint64(shdr.Sscnptr)
+ s.Type = shdr.Sflags
+ s.Relptr = uint64(shdr.Srelptr)
+ s.Nreloc = uint32(shdr.Snreloc)
+ case U64_TOCMAGIC:
+ shdr := new(SectionHeader64)
+ if err := binary.Read(sr, binary.BigEndian, shdr); err != nil {
+ return nil, err
+ }
+ s.Name = cstring(shdr.Sname[:])
+ s.VirtualAddress = shdr.Svaddr
+ s.Size = shdr.Ssize
+ scnptr = shdr.Sscnptr
+ s.Type = shdr.Sflags
+ s.Relptr = shdr.Srelptr
+ s.Nreloc = shdr.Snreloc
+ }
+ r2 := r
+ if scnptr == 0 { // .bss must have all 0s
+ r2 = zeroReaderAt{}
+ }
+ s.sr = io.NewSectionReader(r2, int64(scnptr), int64(s.Size))
+ s.ReaderAt = s.sr
+ f.Sections = append(f.Sections, s)
+ }
+
+ // Symbol map needed by relocation
+ var idxToSym = make(map[int]*Symbol)
+
+ // Read symbol table
+ if _, err := sr.Seek(int64(symptr), io.SeekStart); err != nil {
+ return nil, err
+ }
+ f.Symbols = make([]*Symbol, 0)
+ for i := 0; i < int(nsyms); i++ {
+ var numaux int
+ var ok, needAuxFcn bool
+ sym := new(Symbol)
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ se := new(SymEnt32)
+ if err := binary.Read(sr, binary.BigEndian, se); err != nil {
+ return nil, err
+ }
+ numaux = int(se.Nnumaux)
+ sym.SectionNumber = int(se.Nscnum)
+ sym.StorageClass = int(se.Nsclass)
+ sym.Value = uint64(se.Nvalue)
+ needAuxFcn = se.Ntype&SYM_TYPE_FUNC != 0 && numaux > 1
+ zeroes := binary.BigEndian.Uint32(se.Nname[:4])
+ if zeroes != 0 {
+ sym.Name = cstring(se.Nname[:])
+ } else {
+ offset := binary.BigEndian.Uint32(se.Nname[4:])
+ sym.Name, ok = getString(f.StringTable, offset)
+ if !ok {
+ goto skip
+ }
+ }
+ case U64_TOCMAGIC:
+ se := new(SymEnt64)
+ if err := binary.Read(sr, binary.BigEndian, se); err != nil {
+ return nil, err
+ }
+ numaux = int(se.Nnumaux)
+ sym.SectionNumber = int(se.Nscnum)
+ sym.StorageClass = int(se.Nsclass)
+ sym.Value = se.Nvalue
+ needAuxFcn = se.Ntype&SYM_TYPE_FUNC != 0 && numaux > 1
+ sym.Name, ok = getString(f.StringTable, se.Noffset)
+ if !ok {
+ goto skip
+ }
+ }
+ if sym.StorageClass != C_EXT && sym.StorageClass != C_WEAKEXT && sym.StorageClass != C_HIDEXT {
+ goto skip
+ }
+ // Must have at least one csect auxiliary entry.
+ if numaux < 1 || i+numaux >= int(nsyms) {
+ goto skip
+ }
+
+ if sym.SectionNumber > int(nscns) {
+ goto skip
+ }
+ if sym.SectionNumber == 0 {
+ sym.Value = 0
+ } else {
+ sym.Value -= f.Sections[sym.SectionNumber-1].VirtualAddress
+ }
+
+ idxToSym[i] = sym
+
+ // If this symbol is a function, it must retrieve its size from
+ // its AUX_FCN entry.
+ // It can happen that a function symbol doesn't have any AUX_FCN.
+ // In this case, needAuxFcn is false and their size will be set to 0.
+ if needAuxFcn {
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ aux := new(AuxFcn32)
+ if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
+ return nil, err
+ }
+ sym.AuxFcn.Size = int64(aux.Xfsize)
+ case U64_TOCMAGIC:
+ aux := new(AuxFcn64)
+ if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
+ return nil, err
+ }
+ sym.AuxFcn.Size = int64(aux.Xfsize)
+ }
+ }
+
+ // Read csect auxiliary entry (by convention, it is the last).
+ if !needAuxFcn {
+ if _, err := sr.Seek(int64(numaux-1)*SYMESZ, io.SeekCurrent); err != nil {
+ return nil, err
+ }
+ }
+ i += numaux
+ numaux = 0
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ aux := new(AuxCSect32)
+ if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
+ return nil, err
+ }
+ sym.AuxCSect.SymbolType = int(aux.Xsmtyp & 0x7)
+ sym.AuxCSect.StorageMappingClass = int(aux.Xsmclas)
+ sym.AuxCSect.Length = int64(aux.Xscnlen)
+ case U64_TOCMAGIC:
+ aux := new(AuxCSect64)
+ if err := binary.Read(sr, binary.BigEndian, aux); err != nil {
+ return nil, err
+ }
+ sym.AuxCSect.SymbolType = int(aux.Xsmtyp & 0x7)
+ sym.AuxCSect.StorageMappingClass = int(aux.Xsmclas)
+ sym.AuxCSect.Length = int64(aux.Xscnlenhi)<<32 | int64(aux.Xscnlenlo)
+ }
+ f.Symbols = append(f.Symbols, sym)
+ skip:
+ i += numaux // Skip auxiliary entries
+ if _, err := sr.Seek(int64(numaux)*SYMESZ, io.SeekCurrent); err != nil {
+ return nil, err
+ }
+ }
+
+ // Read relocations
+ // Only for .data or .text section
+ for sectNum, sect := range f.Sections {
+ if sect.Type != STYP_TEXT && sect.Type != STYP_DATA {
+ continue
+ }
+ if sect.Relptr == 0 {
+ continue
+ }
+ c := saferio.SliceCap((*Reloc)(nil), uint64(sect.Nreloc))
+ if c < 0 {
+ return nil, fmt.Errorf("too many relocs (%d) for section %d", sect.Nreloc, sectNum)
+ }
+ sect.Relocs = make([]Reloc, 0, c)
+ if _, err := sr.Seek(int64(sect.Relptr), io.SeekStart); err != nil {
+ return nil, err
+ }
+ for i := uint32(0); i < sect.Nreloc; i++ {
+ var reloc Reloc
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ rel := new(Reloc32)
+ if err := binary.Read(sr, binary.BigEndian, rel); err != nil {
+ return nil, err
+ }
+ reloc.VirtualAddress = uint64(rel.Rvaddr)
+ reloc.Symbol = idxToSym[int(rel.Rsymndx)]
+ reloc.Type = rel.Rtype
+ reloc.Length = rel.Rsize&0x3F + 1
+
+ if rel.Rsize&0x80 != 0 {
+ reloc.Signed = true
+ }
+ if rel.Rsize&0x40 != 0 {
+ reloc.InstructionFixed = true
+ }
+
+ case U64_TOCMAGIC:
+ rel := new(Reloc64)
+ if err := binary.Read(sr, binary.BigEndian, rel); err != nil {
+ return nil, err
+ }
+ reloc.VirtualAddress = rel.Rvaddr
+ reloc.Symbol = idxToSym[int(rel.Rsymndx)]
+ reloc.Type = rel.Rtype
+ reloc.Length = rel.Rsize&0x3F + 1
+ if rel.Rsize&0x80 != 0 {
+ reloc.Signed = true
+ }
+ if rel.Rsize&0x40 != 0 {
+ reloc.InstructionFixed = true
+ }
+ }
+
+ sect.Relocs = append(sect.Relocs, reloc)
+ }
+ }
+
+ return f, nil
+}
+
+// zeroReaderAt is ReaderAt that reads 0s.
+type zeroReaderAt struct{}
+
+// ReadAt writes len(p) 0s into p.
+func (w zeroReaderAt) ReadAt(p []byte, off int64) (n int, err error) {
+ for i := range p {
+ p[i] = 0
+ }
+ return len(p), nil
+}
+
+// Data reads and returns the contents of the XCOFF section s.
+func (s *Section) Data() ([]byte, error) {
+ dat := make([]byte, s.sr.Size())
+ n, err := s.sr.ReadAt(dat, 0)
+ if n == len(dat) {
+ err = nil
+ }
+ return dat[:n], err
+}
+
+// CSect reads and returns the contents of a csect.
+func (f *File) CSect(name string) []byte {
+ for _, sym := range f.Symbols {
+ if sym.Name == name && sym.AuxCSect.SymbolType == XTY_SD {
+ if i := sym.SectionNumber - 1; 0 <= i && i < len(f.Sections) {
+ s := f.Sections[i]
+ if sym.Value+uint64(sym.AuxCSect.Length) <= s.Size {
+ dat := make([]byte, sym.AuxCSect.Length)
+ _, err := s.sr.ReadAt(dat, int64(sym.Value))
+ if err != nil {
+ return nil
+ }
+ return dat
+ }
+ }
+ break
+ }
+ }
+ return nil
+}
+
+func (f *File) DWARF() (*dwarf.Data, error) {
+ // There are many other DWARF sections, but these
+ // are the ones the debug/dwarf package uses.
+ // Don't bother loading others.
+ var subtypes = [...]uint32{SSUBTYP_DWABREV, SSUBTYP_DWINFO, SSUBTYP_DWLINE, SSUBTYP_DWRNGES, SSUBTYP_DWSTR}
+ var dat [len(subtypes)][]byte
+ for i, subtype := range subtypes {
+ s := f.SectionByType(STYP_DWARF | subtype)
+ if s != nil {
+ b, err := s.Data()
+ if err != nil && uint64(len(b)) < s.Size {
+ return nil, err
+ }
+ dat[i] = b
+ }
+ }
+
+ abbrev, info, line, ranges, str := dat[0], dat[1], dat[2], dat[3], dat[4]
+ return dwarf.New(abbrev, nil, nil, info, line, nil, ranges, str)
+}
+
+// readImportID returns the import file IDs stored inside the .loader section.
+// Library name pattern is either path/base/member or base/member
+func (f *File) readImportIDs(s *Section) ([]string, error) {
+ // Read loader header
+ if _, err := s.sr.Seek(0, io.SeekStart); err != nil {
+ return nil, err
+ }
+ var istlen uint32
+ var nimpid uint32
+ var impoff uint64
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ lhdr := new(LoaderHeader32)
+ if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
+ return nil, err
+ }
+ istlen = lhdr.Listlen
+ nimpid = lhdr.Lnimpid
+ impoff = uint64(lhdr.Limpoff)
+ case U64_TOCMAGIC:
+ lhdr := new(LoaderHeader64)
+ if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
+ return nil, err
+ }
+ istlen = lhdr.Listlen
+ nimpid = lhdr.Lnimpid
+ impoff = lhdr.Limpoff
+ }
+
+ // Read loader import file ID table
+ if _, err := s.sr.Seek(int64(impoff), io.SeekStart); err != nil {
+ return nil, err
+ }
+ table := make([]byte, istlen)
+ if _, err := io.ReadFull(s.sr, table); err != nil {
+ return nil, err
+ }
+
+ offset := 0
+ // First import file ID is the default LIBPATH value
+ libpath := cstring(table[offset:])
+ f.LibraryPaths = strings.Split(libpath, ":")
+ offset += len(libpath) + 3 // 3 null bytes
+ all := make([]string, 0)
+ for i := 1; i < int(nimpid); i++ {
+ impidpath := cstring(table[offset:])
+ offset += len(impidpath) + 1
+ impidbase := cstring(table[offset:])
+ offset += len(impidbase) + 1
+ impidmem := cstring(table[offset:])
+ offset += len(impidmem) + 1
+ var path string
+ if len(impidpath) > 0 {
+ path = impidpath + "/" + impidbase + "/" + impidmem
+ } else {
+ path = impidbase + "/" + impidmem
+ }
+ all = append(all, path)
+ }
+
+ return all, nil
+}
+
+// ImportedSymbols returns the names of all symbols
+// referred to by the binary f that are expected to be
+// satisfied by other libraries at dynamic load time.
+// It does not return weak symbols.
+func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
+ s := f.SectionByType(STYP_LOADER)
+ if s == nil {
+ return nil, nil
+ }
+ // Read loader header
+ if _, err := s.sr.Seek(0, io.SeekStart); err != nil {
+ return nil, err
+ }
+ var stlen uint32
+ var stoff uint64
+ var nsyms uint32
+ var symoff uint64
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ lhdr := new(LoaderHeader32)
+ if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
+ return nil, err
+ }
+ stlen = lhdr.Lstlen
+ stoff = uint64(lhdr.Lstoff)
+ nsyms = lhdr.Lnsyms
+ symoff = LDHDRSZ_32
+ case U64_TOCMAGIC:
+ lhdr := new(LoaderHeader64)
+ if err := binary.Read(s.sr, binary.BigEndian, lhdr); err != nil {
+ return nil, err
+ }
+ stlen = lhdr.Lstlen
+ stoff = lhdr.Lstoff
+ nsyms = lhdr.Lnsyms
+ symoff = lhdr.Lsymoff
+ }
+
+ // Read loader section string table
+ if _, err := s.sr.Seek(int64(stoff), io.SeekStart); err != nil {
+ return nil, err
+ }
+ st := make([]byte, stlen)
+ if _, err := io.ReadFull(s.sr, st); err != nil {
+ return nil, err
+ }
+
+ // Read imported libraries
+ libs, err := f.readImportIDs(s)
+ if err != nil {
+ return nil, err
+ }
+
+ // Read loader symbol table
+ if _, err := s.sr.Seek(int64(symoff), io.SeekStart); err != nil {
+ return nil, err
+ }
+ all := make([]ImportedSymbol, 0)
+ for i := 0; i < int(nsyms); i++ {
+ var name string
+ var ifile uint32
+ var ok bool
+ switch f.TargetMachine {
+ case U802TOCMAGIC:
+ ldsym := new(LoaderSymbol32)
+ if err := binary.Read(s.sr, binary.BigEndian, ldsym); err != nil {
+ return nil, err
+ }
+ if ldsym.Lsmtype&0x40 == 0 {
+ continue // Imported symbols only
+ }
+ zeroes := binary.BigEndian.Uint32(ldsym.Lname[:4])
+ if zeroes != 0 {
+ name = cstring(ldsym.Lname[:])
+ } else {
+ offset := binary.BigEndian.Uint32(ldsym.Lname[4:])
+ name, ok = getString(st, offset)
+ if !ok {
+ continue
+ }
+ }
+ ifile = ldsym.Lifile
+ case U64_TOCMAGIC:
+ ldsym := new(LoaderSymbol64)
+ if err := binary.Read(s.sr, binary.BigEndian, ldsym); err != nil {
+ return nil, err
+ }
+ if ldsym.Lsmtype&0x40 == 0 {
+ continue // Imported symbols only
+ }
+ name, ok = getString(st, ldsym.Loffset)
+ if !ok {
+ continue
+ }
+ ifile = ldsym.Lifile
+ }
+ var sym ImportedSymbol
+ sym.Name = name
+ if ifile >= 1 && int(ifile) <= len(libs) {
+ sym.Library = libs[ifile-1]
+ }
+ all = append(all, sym)
+ }
+
+ return all, nil
+}
+
+// ImportedLibraries returns the names of all libraries
+// referred to by the binary f that are expected to be
+// linked with the binary at dynamic link time.
+func (f *File) ImportedLibraries() ([]string, error) {
+ s := f.SectionByType(STYP_LOADER)
+ if s == nil {
+ return nil, nil
+ }
+ all, err := f.readImportIDs(s)
+ return all, err
+}
diff --git a/contrib/go/_std_1.21/src/internal/xcoff/xcoff.go b/contrib/go/_std_1.21/src/internal/xcoff/xcoff.go
new file mode 100644
index 0000000000..db81542ed3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/xcoff/xcoff.go
@@ -0,0 +1,367 @@
+// Copyright 2018 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 xcoff
+
+// File Header.
+type FileHeader32 struct {
+ Fmagic uint16 // Target machine
+ Fnscns uint16 // Number of sections
+ Ftimedat uint32 // Time and date of file creation
+ Fsymptr uint32 // Byte offset to symbol table start
+ Fnsyms uint32 // Number of entries in symbol table
+ Fopthdr uint16 // Number of bytes in optional header
+ Fflags uint16 // Flags
+}
+
+type FileHeader64 struct {
+ Fmagic uint16 // Target machine
+ Fnscns uint16 // Number of sections
+ Ftimedat uint32 // Time and date of file creation
+ Fsymptr uint64 // Byte offset to symbol table start
+ Fopthdr uint16 // Number of bytes in optional header
+ Fflags uint16 // Flags
+ Fnsyms uint32 // Number of entries in symbol table
+}
+
+const (
+ FILHSZ_32 = 20
+ FILHSZ_64 = 24
+)
+const (
+ U802TOCMAGIC = 0737 // AIX 32-bit XCOFF
+ U64_TOCMAGIC = 0767 // AIX 64-bit XCOFF
+)
+
+// Flags that describe the type of the object file.
+const (
+ F_RELFLG = 0x0001
+ F_EXEC = 0x0002
+ F_LNNO = 0x0004
+ F_FDPR_PROF = 0x0010
+ F_FDPR_OPTI = 0x0020
+ F_DSA = 0x0040
+ F_VARPG = 0x0100
+ F_DYNLOAD = 0x1000
+ F_SHROBJ = 0x2000
+ F_LOADONLY = 0x4000
+)
+
+// Section Header.
+type SectionHeader32 struct {
+ Sname [8]byte // Section name
+ Spaddr uint32 // Physical address
+ Svaddr uint32 // Virtual address
+ Ssize uint32 // Section size
+ Sscnptr uint32 // Offset in file to raw data for section
+ Srelptr uint32 // Offset in file to relocation entries for section
+ Slnnoptr uint32 // Offset in file to line number entries for section
+ Snreloc uint16 // Number of relocation entries
+ Snlnno uint16 // Number of line number entries
+ Sflags uint32 // Flags to define the section type
+}
+
+type SectionHeader64 struct {
+ Sname [8]byte // Section name
+ Spaddr uint64 // Physical address
+ Svaddr uint64 // Virtual address
+ Ssize uint64 // Section size
+ Sscnptr uint64 // Offset in file to raw data for section
+ Srelptr uint64 // Offset in file to relocation entries for section
+ Slnnoptr uint64 // Offset in file to line number entries for section
+ Snreloc uint32 // Number of relocation entries
+ Snlnno uint32 // Number of line number entries
+ Sflags uint32 // Flags to define the section type
+ Spad uint32 // Needs to be 72 bytes long
+}
+
+// Flags defining the section type.
+const (
+ STYP_DWARF = 0x0010
+ STYP_TEXT = 0x0020
+ STYP_DATA = 0x0040
+ STYP_BSS = 0x0080
+ STYP_EXCEPT = 0x0100
+ STYP_INFO = 0x0200
+ STYP_TDATA = 0x0400
+ STYP_TBSS = 0x0800
+ STYP_LOADER = 0x1000
+ STYP_DEBUG = 0x2000
+ STYP_TYPCHK = 0x4000
+ STYP_OVRFLO = 0x8000
+)
+const (
+ SSUBTYP_DWINFO = 0x10000 // DWARF info section
+ SSUBTYP_DWLINE = 0x20000 // DWARF line-number section
+ SSUBTYP_DWPBNMS = 0x30000 // DWARF public names section
+ SSUBTYP_DWPBTYP = 0x40000 // DWARF public types section
+ SSUBTYP_DWARNGE = 0x50000 // DWARF aranges section
+ SSUBTYP_DWABREV = 0x60000 // DWARF abbreviation section
+ SSUBTYP_DWSTR = 0x70000 // DWARF strings section
+ SSUBTYP_DWRNGES = 0x80000 // DWARF ranges section
+ SSUBTYP_DWLOC = 0x90000 // DWARF location lists section
+ SSUBTYP_DWFRAME = 0xA0000 // DWARF frames section
+ SSUBTYP_DWMAC = 0xB0000 // DWARF macros section
+)
+
+// Symbol Table Entry.
+type SymEnt32 struct {
+ Nname [8]byte // Symbol name
+ Nvalue uint32 // Symbol value
+ Nscnum uint16 // Section number of symbol
+ Ntype uint16 // Basic and derived type specification
+ Nsclass uint8 // Storage class of symbol
+ Nnumaux uint8 // Number of auxiliary entries
+}
+
+type SymEnt64 struct {
+ Nvalue uint64 // Symbol value
+ Noffset uint32 // Offset of the name in string table or .debug section
+ Nscnum uint16 // Section number of symbol
+ Ntype uint16 // Basic and derived type specification
+ Nsclass uint8 // Storage class of symbol
+ Nnumaux uint8 // Number of auxiliary entries
+}
+
+const SYMESZ = 18
+
+const (
+ // Nscnum
+ N_DEBUG = -2
+ N_ABS = -1
+ N_UNDEF = 0
+
+ //Ntype
+ SYM_V_INTERNAL = 0x1000
+ SYM_V_HIDDEN = 0x2000
+ SYM_V_PROTECTED = 0x3000
+ SYM_V_EXPORTED = 0x4000
+ SYM_TYPE_FUNC = 0x0020 // is function
+)
+
+// Storage Class.
+const (
+ C_NULL = 0 // Symbol table entry marked for deletion
+ C_EXT = 2 // External symbol
+ C_STAT = 3 // Static symbol
+ C_BLOCK = 100 // Beginning or end of inner block
+ C_FCN = 101 // Beginning or end of function
+ C_FILE = 103 // Source file name and compiler information
+ C_HIDEXT = 107 // Unnamed external symbol
+ C_BINCL = 108 // Beginning of include file
+ C_EINCL = 109 // End of include file
+ C_WEAKEXT = 111 // Weak external symbol
+ C_DWARF = 112 // DWARF symbol
+ C_GSYM = 128 // Global variable
+ C_LSYM = 129 // Automatic variable allocated on stack
+ C_PSYM = 130 // Argument to subroutine allocated on stack
+ C_RSYM = 131 // Register variable
+ C_RPSYM = 132 // Argument to function or procedure stored in register
+ C_STSYM = 133 // Statically allocated symbol
+ C_BCOMM = 135 // Beginning of common block
+ C_ECOML = 136 // Local member of common block
+ C_ECOMM = 137 // End of common block
+ C_DECL = 140 // Declaration of object
+ C_ENTRY = 141 // Alternate entry
+ C_FUN = 142 // Function or procedure
+ C_BSTAT = 143 // Beginning of static block
+ C_ESTAT = 144 // End of static block
+ C_GTLS = 145 // Global thread-local variable
+ C_STTLS = 146 // Static thread-local variable
+)
+
+// File Auxiliary Entry
+type AuxFile64 struct {
+ Xfname [8]byte // Name or offset inside string table
+ Xftype uint8 // Source file string type
+ Xauxtype uint8 // Type of auxiliary entry
+}
+
+// Function Auxiliary Entry
+type AuxFcn32 struct {
+ Xexptr uint32 // File offset to exception table entry
+ Xfsize uint32 // Size of function in bytes
+ Xlnnoptr uint32 // File pointer to line number
+ Xendndx uint32 // Symbol table index of next entry
+ Xpad uint16 // Unused
+}
+type AuxFcn64 struct {
+ Xlnnoptr uint64 // File pointer to line number
+ Xfsize uint32 // Size of function in bytes
+ Xendndx uint32 // Symbol table index of next entry
+ Xpad uint8 // Unused
+ Xauxtype uint8 // Type of auxiliary entry
+}
+
+type AuxSect64 struct {
+ Xscnlen uint64 // section length
+ Xnreloc uint64 // Num RLDs
+ pad uint8
+ Xauxtype uint8 // Type of auxiliary entry
+}
+
+// csect Auxiliary Entry.
+type AuxCSect32 struct {
+ Xscnlen uint32 // Length or symbol table index
+ Xparmhash uint32 // Offset of parameter type-check string
+ Xsnhash uint16 // .typchk section number
+ Xsmtyp uint8 // Symbol alignment and type
+ Xsmclas uint8 // Storage-mapping class
+ Xstab uint32 // Reserved
+ Xsnstab uint16 // Reserved
+}
+
+type AuxCSect64 struct {
+ Xscnlenlo uint32 // Lower 4 bytes of length or symbol table index
+ Xparmhash uint32 // Offset of parameter type-check string
+ Xsnhash uint16 // .typchk section number
+ Xsmtyp uint8 // Symbol alignment and type
+ Xsmclas uint8 // Storage-mapping class
+ Xscnlenhi uint32 // Upper 4 bytes of length or symbol table index
+ Xpad uint8 // Unused
+ Xauxtype uint8 // Type of auxiliary entry
+}
+
+// Auxiliary type
+const (
+ _AUX_EXCEPT = 255
+ _AUX_FCN = 254
+ _AUX_SYM = 253
+ _AUX_FILE = 252
+ _AUX_CSECT = 251
+ _AUX_SECT = 250
+)
+
+// Symbol type field.
+const (
+ XTY_ER = 0 // External reference
+ XTY_SD = 1 // Section definition
+ XTY_LD = 2 // Label definition
+ XTY_CM = 3 // Common csect definition
+)
+
+// Defines for File auxiliary definitions: x_ftype field of x_file
+const (
+ XFT_FN = 0 // Source File Name
+ XFT_CT = 1 // Compile Time Stamp
+ XFT_CV = 2 // Compiler Version Number
+ XFT_CD = 128 // Compiler Defined Information
+)
+
+// Storage-mapping class.
+const (
+ XMC_PR = 0 // Program code
+ XMC_RO = 1 // Read-only constant
+ XMC_DB = 2 // Debug dictionary table
+ XMC_TC = 3 // TOC entry
+ XMC_UA = 4 // Unclassified
+ XMC_RW = 5 // Read/Write data
+ XMC_GL = 6 // Global linkage
+ XMC_XO = 7 // Extended operation
+ XMC_SV = 8 // 32-bit supervisor call descriptor
+ XMC_BS = 9 // BSS class
+ XMC_DS = 10 // Function descriptor
+ XMC_UC = 11 // Unnamed FORTRAN common
+ XMC_TC0 = 15 // TOC anchor
+ XMC_TD = 16 // Scalar data entry in the TOC
+ XMC_SV64 = 17 // 64-bit supervisor call descriptor
+ XMC_SV3264 = 18 // Supervisor call descriptor for both 32-bit and 64-bit
+ XMC_TL = 20 // Read/Write thread-local data
+ XMC_UL = 21 // Read/Write thread-local data (.tbss)
+ XMC_TE = 22 // TOC entry
+)
+
+// Loader Header.
+type LoaderHeader32 struct {
+ Lversion uint32 // Loader section version number
+ Lnsyms uint32 // Number of symbol table entries
+ Lnreloc uint32 // Number of relocation table entries
+ Listlen uint32 // Length of import file ID string table
+ Lnimpid uint32 // Number of import file IDs
+ Limpoff uint32 // Offset to start of import file IDs
+ Lstlen uint32 // Length of string table
+ Lstoff uint32 // Offset to start of string table
+}
+
+type LoaderHeader64 struct {
+ Lversion uint32 // Loader section version number
+ Lnsyms uint32 // Number of symbol table entries
+ Lnreloc uint32 // Number of relocation table entries
+ Listlen uint32 // Length of import file ID string table
+ Lnimpid uint32 // Number of import file IDs
+ Lstlen uint32 // Length of string table
+ Limpoff uint64 // Offset to start of import file IDs
+ Lstoff uint64 // Offset to start of string table
+ Lsymoff uint64 // Offset to start of symbol table
+ Lrldoff uint64 // Offset to start of relocation entries
+}
+
+const (
+ LDHDRSZ_32 = 32
+ LDHDRSZ_64 = 56
+)
+
+// Loader Symbol.
+type LoaderSymbol32 struct {
+ Lname [8]byte // Symbol name or byte offset into string table
+ Lvalue uint32 // Address field
+ Lscnum uint16 // Section number containing symbol
+ Lsmtype uint8 // Symbol type, export, import flags
+ Lsmclas uint8 // Symbol storage class
+ Lifile uint32 // Import file ID; ordinal of import file IDs
+ Lparm uint32 // Parameter type-check field
+}
+
+type LoaderSymbol64 struct {
+ Lvalue uint64 // Address field
+ Loffset uint32 // Byte offset into string table of symbol name
+ Lscnum uint16 // Section number containing symbol
+ Lsmtype uint8 // Symbol type, export, import flags
+ Lsmclas uint8 // Symbol storage class
+ Lifile uint32 // Import file ID; ordinal of import file IDs
+ Lparm uint32 // Parameter type-check field
+}
+
+type Reloc32 struct {
+ Rvaddr uint32 // (virtual) address of reference
+ Rsymndx uint32 // Index into symbol table
+ Rsize uint8 // Sign and reloc bit len
+ Rtype uint8 // Toc relocation type
+}
+
+type Reloc64 struct {
+ Rvaddr uint64 // (virtual) address of reference
+ Rsymndx uint32 // Index into symbol table
+ Rsize uint8 // Sign and reloc bit len
+ Rtype uint8 // Toc relocation type
+}
+
+const (
+ R_POS = 0x00 // A(sym) Positive Relocation
+ R_NEG = 0x01 // -A(sym) Negative Relocation
+ R_REL = 0x02 // A(sym-*) Relative to self
+ R_TOC = 0x03 // A(sym-TOC) Relative to TOC
+ R_TRL = 0x12 // A(sym-TOC) TOC Relative indirect load.
+
+ R_TRLA = 0x13 // A(sym-TOC) TOC Rel load address. modifiable inst
+ R_GL = 0x05 // A(external TOC of sym) Global Linkage
+ R_TCL = 0x06 // A(local TOC of sym) Local object TOC address
+ R_RL = 0x0C // A(sym) Pos indirect load. modifiable instruction
+ R_RLA = 0x0D // A(sym) Pos Load Address. modifiable instruction
+ R_REF = 0x0F // AL0(sym) Non relocating ref. No garbage collect
+ R_BA = 0x08 // A(sym) Branch absolute. Cannot modify instruction
+ R_RBA = 0x18 // A(sym) Branch absolute. modifiable instruction
+ R_BR = 0x0A // A(sym-*) Branch rel to self. non modifiable
+ R_RBR = 0x1A // A(sym-*) Branch rel to self. modifiable instr
+
+ R_TLS = 0x20 // General-dynamic reference to TLS symbol
+ R_TLS_IE = 0x21 // Initial-exec reference to TLS symbol
+ R_TLS_LD = 0x22 // Local-dynamic reference to TLS symbol
+ R_TLS_LE = 0x23 // Local-exec reference to TLS symbol
+ R_TLSM = 0x24 // Module reference to TLS symbol
+ R_TLSML = 0x25 // Module reference to local (own) module
+
+ R_TOCU = 0x30 // Relative to TOC - high order bits
+ R_TOCL = 0x31 // Relative to TOC - low order bits
+)
diff --git a/contrib/go/_std_1.21/src/internal/xcoff/ya.make b/contrib/go/_std_1.21/src/internal/xcoff/ya.make
new file mode 100644
index 0000000000..cd242eaf5f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/xcoff/ya.make
@@ -0,0 +1,17 @@
+GO_LIBRARY()
+
+SRCS(
+ ar.go
+ file.go
+ xcoff.go
+)
+
+GO_TEST_SRCS(
+ ar_test.go
+ file_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/internal/zstd/bits.go b/contrib/go/_std_1.21/src/internal/zstd/bits.go
new file mode 100644
index 0000000000..c9a2f70802
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/zstd/bits.go
@@ -0,0 +1,130 @@
+// Copyright 2023 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 zstd
+
+import (
+ "math/bits"
+)
+
+// block is the data for a single compressed block.
+// The data starts immediately after the 3 byte block header,
+// and is Block_Size bytes long.
+type block []byte
+
+// bitReader reads a bit stream going forward.
+type bitReader struct {
+ r *Reader // for error reporting
+ data block // the bits to read
+ off uint32 // current offset into data
+ bits uint32 // bits ready to be returned
+ cnt uint32 // number of valid bits in the bits field
+}
+
+// makeBitReader makes a bit reader starting at off.
+func (r *Reader) makeBitReader(data block, off int) bitReader {
+ return bitReader{
+ r: r,
+ data: data,
+ off: uint32(off),
+ }
+}
+
+// moreBits is called to read more bits.
+// This ensures that at least 16 bits are available.
+func (br *bitReader) moreBits() error {
+ for br.cnt < 16 {
+ if br.off >= uint32(len(br.data)) {
+ return br.r.makeEOFError(int(br.off))
+ }
+ c := br.data[br.off]
+ br.off++
+ br.bits |= uint32(c) << br.cnt
+ br.cnt += 8
+ }
+ return nil
+}
+
+// val is called to fetch a value of b bits.
+func (br *bitReader) val(b uint8) uint32 {
+ r := br.bits & ((1 << b) - 1)
+ br.bits >>= b
+ br.cnt -= uint32(b)
+ return r
+}
+
+// backup steps back to the last byte we used.
+func (br *bitReader) backup() {
+ for br.cnt >= 8 {
+ br.off--
+ br.cnt -= 8
+ }
+}
+
+// makeError returns an error at the current offset wrapping a string.
+func (br *bitReader) makeError(msg string) error {
+ return br.r.makeError(int(br.off), msg)
+}
+
+// reverseBitReader reads a bit stream in reverse.
+type reverseBitReader struct {
+ r *Reader // for error reporting
+ data block // the bits to read
+ off uint32 // current offset into data
+ start uint32 // start in data; we read backward to start
+ bits uint32 // bits ready to be returned
+ cnt uint32 // number of valid bits in bits field
+}
+
+// makeReverseBitReader makes a reverseBitReader reading backward
+// from off to start. The bitstream starts with a 1 bit in the last
+// byte, at off.
+func (r *Reader) makeReverseBitReader(data block, off, start int) (reverseBitReader, error) {
+ streamStart := data[off]
+ if streamStart == 0 {
+ return reverseBitReader{}, r.makeError(off, "zero byte at reverse bit stream start")
+ }
+ rbr := reverseBitReader{
+ r: r,
+ data: data,
+ off: uint32(off),
+ start: uint32(start),
+ bits: uint32(streamStart),
+ cnt: uint32(7 - bits.LeadingZeros8(streamStart)),
+ }
+ return rbr, nil
+}
+
+// val is called to fetch a value of b bits.
+func (rbr *reverseBitReader) val(b uint8) (uint32, error) {
+ if !rbr.fetch(b) {
+ return 0, rbr.r.makeEOFError(int(rbr.off))
+ }
+
+ rbr.cnt -= uint32(b)
+ v := (rbr.bits >> rbr.cnt) & ((1 << b) - 1)
+ return v, nil
+}
+
+// fetch is called to ensure that at least b bits are available.
+// It reports false if this can't be done,
+// in which case only rbr.cnt bits are available.
+func (rbr *reverseBitReader) fetch(b uint8) bool {
+ for rbr.cnt < uint32(b) {
+ if rbr.off <= rbr.start {
+ return false
+ }
+ rbr.off--
+ c := rbr.data[rbr.off]
+ rbr.bits <<= 8
+ rbr.bits |= uint32(c)
+ rbr.cnt += 8
+ }
+ return true
+}
+
+// makeError returns an error at the current offset wrapping a string.
+func (rbr *reverseBitReader) makeError(msg string) error {
+ return rbr.r.makeError(int(rbr.off), msg)
+}
diff --git a/contrib/go/_std_1.21/src/internal/zstd/block.go b/contrib/go/_std_1.21/src/internal/zstd/block.go
new file mode 100644
index 0000000000..bd3040ce83
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/zstd/block.go
@@ -0,0 +1,436 @@
+// Copyright 2023 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 zstd
+
+import (
+ "io"
+)
+
+// debug can be set in the source to print debug info using println.
+const debug = false
+
+// compressedBlock decompresses a compressed block, storing the decompressed
+// data in r.buffer. The blockSize argument is the compressed size.
+// RFC 3.1.1.3.
+func (r *Reader) compressedBlock(blockSize int) error {
+ if len(r.compressedBuf) >= blockSize {
+ r.compressedBuf = r.compressedBuf[:blockSize]
+ } else {
+ // We know that blockSize <= 128K,
+ // so this won't allocate an enormous amount.
+ need := blockSize - len(r.compressedBuf)
+ r.compressedBuf = append(r.compressedBuf, make([]byte, need)...)
+ }
+
+ if _, err := io.ReadFull(r.r, r.compressedBuf); err != nil {
+ return r.wrapNonEOFError(0, err)
+ }
+
+ data := block(r.compressedBuf)
+ off := 0
+ r.buffer = r.buffer[:0]
+
+ litoff, litbuf, err := r.readLiterals(data, off, r.literals[:0])
+ if err != nil {
+ return err
+ }
+ r.literals = litbuf
+
+ off = litoff
+
+ seqCount, off, err := r.initSeqs(data, off)
+ if err != nil {
+ return err
+ }
+
+ if seqCount == 0 {
+ // No sequences, just literals.
+ if off < len(data) {
+ return r.makeError(off, "extraneous data after no sequences")
+ }
+ if len(litbuf) == 0 {
+ return r.makeError(off, "no sequences and no literals")
+ }
+ r.buffer = append(r.buffer, litbuf...)
+ return nil
+ }
+
+ return r.execSeqs(data, off, litbuf, seqCount)
+}
+
+// seqCode is the kind of sequence codes we have to handle.
+type seqCode int
+
+const (
+ seqLiteral seqCode = iota
+ seqOffset
+ seqMatch
+)
+
+// seqCodeInfoData is the information needed to set up seqTables and
+// seqTableBits for a particular kind of sequence code.
+type seqCodeInfoData struct {
+ predefTable []fseBaselineEntry // predefined FSE
+ predefTableBits int // number of bits in predefTable
+ maxSym int // max symbol value in FSE
+ maxBits int // max bits for FSE
+
+ // toBaseline converts from an FSE table to an FSE baseline table.
+ toBaseline func(*Reader, int, []fseEntry, []fseBaselineEntry) error
+}
+
+// seqCodeInfo is the seqCodeInfoData for each kind of sequence code.
+var seqCodeInfo = [3]seqCodeInfoData{
+ seqLiteral: {
+ predefTable: predefinedLiteralTable[:],
+ predefTableBits: 6,
+ maxSym: 35,
+ maxBits: 9,
+ toBaseline: (*Reader).makeLiteralBaselineFSE,
+ },
+ seqOffset: {
+ predefTable: predefinedOffsetTable[:],
+ predefTableBits: 5,
+ maxSym: 31,
+ maxBits: 8,
+ toBaseline: (*Reader).makeOffsetBaselineFSE,
+ },
+ seqMatch: {
+ predefTable: predefinedMatchTable[:],
+ predefTableBits: 6,
+ maxSym: 52,
+ maxBits: 9,
+ toBaseline: (*Reader).makeMatchBaselineFSE,
+ },
+}
+
+// initSeqs reads the Sequences_Section_Header and sets up the FSE
+// tables used to read the sequence codes. It returns the number of
+// sequences and the new offset. RFC 3.1.1.3.2.1.
+func (r *Reader) initSeqs(data block, off int) (int, int, error) {
+ if off >= len(data) {
+ return 0, 0, r.makeEOFError(off)
+ }
+
+ seqHdr := data[off]
+ off++
+ if seqHdr == 0 {
+ return 0, off, nil
+ }
+
+ var seqCount int
+ if seqHdr < 128 {
+ seqCount = int(seqHdr)
+ } else if seqHdr < 255 {
+ if off >= len(data) {
+ return 0, 0, r.makeEOFError(off)
+ }
+ seqCount = ((int(seqHdr) - 128) << 8) + int(data[off])
+ off++
+ } else {
+ if off+1 >= len(data) {
+ return 0, 0, r.makeEOFError(off)
+ }
+ seqCount = int(data[off]) + (int(data[off+1]) << 8) + 0x7f00
+ off += 2
+ }
+
+ // Read the Symbol_Compression_Modes byte.
+
+ if off >= len(data) {
+ return 0, 0, r.makeEOFError(off)
+ }
+ symMode := data[off]
+ if symMode&3 != 0 {
+ return 0, 0, r.makeError(off, "invalid symbol compression mode")
+ }
+ off++
+
+ // Set up the FSE tables used to decode the sequence codes.
+
+ var err error
+ off, err = r.setSeqTable(data, off, seqLiteral, (symMode>>6)&3)
+ if err != nil {
+ return 0, 0, err
+ }
+
+ off, err = r.setSeqTable(data, off, seqOffset, (symMode>>4)&3)
+ if err != nil {
+ return 0, 0, err
+ }
+
+ off, err = r.setSeqTable(data, off, seqMatch, (symMode>>2)&3)
+ if err != nil {
+ return 0, 0, err
+ }
+
+ return seqCount, off, nil
+}
+
+// setSeqTable uses the Compression_Mode in mode to set up r.seqTables and
+// r.seqTableBits for kind. We store these in the Reader because one of
+// the modes simply reuses the value from the last block in the frame.
+func (r *Reader) setSeqTable(data block, off int, kind seqCode, mode byte) (int, error) {
+ info := &seqCodeInfo[kind]
+ switch mode {
+ case 0:
+ // Predefined_Mode
+ r.seqTables[kind] = info.predefTable
+ r.seqTableBits[kind] = uint8(info.predefTableBits)
+ return off, nil
+
+ case 1:
+ // RLE_Mode
+ if off >= len(data) {
+ return 0, r.makeEOFError(off)
+ }
+ rle := data[off]
+ off++
+
+ // Build a simple baseline table that always returns rle.
+
+ entry := []fseEntry{
+ {
+ sym: rle,
+ bits: 0,
+ base: 0,
+ },
+ }
+ if cap(r.seqTableBuffers[kind]) == 0 {
+ r.seqTableBuffers[kind] = make([]fseBaselineEntry, 1<<info.maxBits)
+ }
+ r.seqTableBuffers[kind] = r.seqTableBuffers[kind][:1]
+ if err := info.toBaseline(r, off, entry, r.seqTableBuffers[kind]); err != nil {
+ return 0, err
+ }
+
+ r.seqTables[kind] = r.seqTableBuffers[kind]
+ r.seqTableBits[kind] = 0
+ return off, nil
+
+ case 2:
+ // FSE_Compressed_Mode
+ if cap(r.fseScratch) < 1<<info.maxBits {
+ r.fseScratch = make([]fseEntry, 1<<info.maxBits)
+ }
+ r.fseScratch = r.fseScratch[:1<<info.maxBits]
+
+ tableBits, roff, err := r.readFSE(data, off, info.maxSym, info.maxBits, r.fseScratch)
+ if err != nil {
+ return 0, err
+ }
+ r.fseScratch = r.fseScratch[:1<<tableBits]
+
+ if cap(r.seqTableBuffers[kind]) == 0 {
+ r.seqTableBuffers[kind] = make([]fseBaselineEntry, 1<<info.maxBits)
+ }
+ r.seqTableBuffers[kind] = r.seqTableBuffers[kind][:1<<tableBits]
+
+ if err := info.toBaseline(r, roff, r.fseScratch, r.seqTableBuffers[kind]); err != nil {
+ return 0, err
+ }
+
+ r.seqTables[kind] = r.seqTableBuffers[kind]
+ r.seqTableBits[kind] = uint8(tableBits)
+ return roff, nil
+
+ case 3:
+ // Repeat_Mode
+ if len(r.seqTables[kind]) == 0 {
+ return 0, r.makeError(off, "missing repeat sequence FSE table")
+ }
+ return off, nil
+ }
+ panic("unreachable")
+}
+
+// execSeqs reads and executes the sequences. RFC 3.1.1.3.2.1.2.
+func (r *Reader) execSeqs(data block, off int, litbuf []byte, seqCount int) error {
+ // Set up the initial states for the sequence code readers.
+
+ rbr, err := r.makeReverseBitReader(data, len(data)-1, off)
+ if err != nil {
+ return err
+ }
+
+ literalState, err := rbr.val(r.seqTableBits[seqLiteral])
+ if err != nil {
+ return err
+ }
+
+ offsetState, err := rbr.val(r.seqTableBits[seqOffset])
+ if err != nil {
+ return err
+ }
+
+ matchState, err := rbr.val(r.seqTableBits[seqMatch])
+ if err != nil {
+ return err
+ }
+
+ // Read and perform all the sequences. RFC 3.1.1.4.
+
+ seq := 0
+ for seq < seqCount {
+ if len(r.buffer)+len(litbuf) > 128<<10 {
+ return rbr.makeError("uncompressed size too big")
+ }
+
+ ptoffset := &r.seqTables[seqOffset][offsetState]
+ ptmatch := &r.seqTables[seqMatch][matchState]
+ ptliteral := &r.seqTables[seqLiteral][literalState]
+
+ add, err := rbr.val(ptoffset.basebits)
+ if err != nil {
+ return err
+ }
+ offset := ptoffset.baseline + add
+
+ add, err = rbr.val(ptmatch.basebits)
+ if err != nil {
+ return err
+ }
+ match := ptmatch.baseline + add
+
+ add, err = rbr.val(ptliteral.basebits)
+ if err != nil {
+ return err
+ }
+ literal := ptliteral.baseline + add
+
+ // Handle repeat offsets. RFC 3.1.1.5.
+ // See the comment in makeOffsetBaselineFSE.
+ if ptoffset.basebits > 1 {
+ r.repeatedOffset3 = r.repeatedOffset2
+ r.repeatedOffset2 = r.repeatedOffset1
+ r.repeatedOffset1 = offset
+ } else {
+ if literal == 0 {
+ offset++
+ }
+ switch offset {
+ case 1:
+ offset = r.repeatedOffset1
+ case 2:
+ offset = r.repeatedOffset2
+ r.repeatedOffset2 = r.repeatedOffset1
+ r.repeatedOffset1 = offset
+ case 3:
+ offset = r.repeatedOffset3
+ r.repeatedOffset3 = r.repeatedOffset2
+ r.repeatedOffset2 = r.repeatedOffset1
+ r.repeatedOffset1 = offset
+ case 4:
+ offset = r.repeatedOffset1 - 1
+ r.repeatedOffset3 = r.repeatedOffset2
+ r.repeatedOffset2 = r.repeatedOffset1
+ r.repeatedOffset1 = offset
+ }
+ }
+
+ seq++
+ if seq < seqCount {
+ // Update the states.
+ add, err = rbr.val(ptliteral.bits)
+ if err != nil {
+ return err
+ }
+ literalState = uint32(ptliteral.base) + add
+
+ add, err = rbr.val(ptmatch.bits)
+ if err != nil {
+ return err
+ }
+ matchState = uint32(ptmatch.base) + add
+
+ add, err = rbr.val(ptoffset.bits)
+ if err != nil {
+ return err
+ }
+ offsetState = uint32(ptoffset.base) + add
+ }
+
+ // The next sequence is now in literal, offset, match.
+
+ if debug {
+ println("literal", literal, "offset", offset, "match", match)
+ }
+
+ // Copy literal bytes from litbuf.
+ if literal > uint32(len(litbuf)) {
+ return rbr.makeError("literal byte overflow")
+ }
+ if literal > 0 {
+ r.buffer = append(r.buffer, litbuf[:literal]...)
+ litbuf = litbuf[literal:]
+ }
+
+ if match > 0 {
+ if err := r.copyFromWindow(&rbr, offset, match); err != nil {
+ return err
+ }
+ }
+ }
+
+ if len(litbuf) > 0 {
+ r.buffer = append(r.buffer, litbuf...)
+ }
+
+ if rbr.cnt != 0 {
+ return r.makeError(off, "extraneous data after sequences")
+ }
+
+ return nil
+}
+
+// Copy match bytes from the decoded output, or the window, at offset.
+func (r *Reader) copyFromWindow(rbr *reverseBitReader, offset, match uint32) error {
+ if offset == 0 {
+ return rbr.makeError("invalid zero offset")
+ }
+
+ lenBlock := uint32(len(r.buffer))
+ if lenBlock < offset {
+ lenWindow := uint32(len(r.window))
+ windowOffset := offset - lenBlock
+ if windowOffset > lenWindow {
+ return rbr.makeError("offset past window")
+ }
+ from := lenWindow - windowOffset
+ if from+match <= lenWindow {
+ r.buffer = append(r.buffer, r.window[from:from+match]...)
+ return nil
+ }
+ r.buffer = append(r.buffer, r.window[from:]...)
+ copied := lenWindow - from
+ offset -= copied
+ match -= copied
+
+ if offset == 0 && match > 0 {
+ return rbr.makeError("invalid offset")
+ }
+ }
+
+ from := lenBlock - offset
+ if offset >= match {
+ r.buffer = append(r.buffer, r.buffer[from:from+match]...)
+ return nil
+ }
+
+ // We are being asked to copy data that we are adding to the
+ // buffer in the same copy.
+ for match > 0 {
+ var copy uint32
+ if offset >= match {
+ copy = match
+ } else {
+ copy = offset
+ }
+ r.buffer = append(r.buffer, r.buffer[from:from+copy]...)
+ match -= copy
+ from += copy
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/internal/zstd/fse.go b/contrib/go/_std_1.21/src/internal/zstd/fse.go
new file mode 100644
index 0000000000..ea661d4499
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/zstd/fse.go
@@ -0,0 +1,437 @@
+// Copyright 2023 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 zstd
+
+import (
+ "math/bits"
+)
+
+// fseEntry is one entry in an FSE table.
+type fseEntry struct {
+ sym uint8 // value that this entry records
+ bits uint8 // number of bits to read to determine next state
+ base uint16 // add those bits to this state to get the next state
+}
+
+// readFSE reads an FSE table from data starting at off.
+// maxSym is the maximum symbol value.
+// maxBits is the maximum number of bits permitted for symbols in the table.
+// The FSE is written into table, which must be at least 1<<maxBits in size.
+// This returns the number of bits in the FSE table and the new offset.
+// RFC 4.1.1.
+func (r *Reader) readFSE(data block, off, maxSym, maxBits int, table []fseEntry) (tableBits, roff int, err error) {
+ br := r.makeBitReader(data, off)
+ if err := br.moreBits(); err != nil {
+ return 0, 0, err
+ }
+
+ accuracyLog := int(br.val(4)) + 5
+ if accuracyLog > maxBits {
+ return 0, 0, br.makeError("FSE accuracy log too large")
+ }
+
+ // The number of remaining probabilities, plus 1.
+ // This determines the number of bits to be read for the next value.
+ remaining := (1 << accuracyLog) + 1
+
+ // The current difference between small and large values,
+ // which depends on the number of remaining values.
+ // Small values use 1 less bit.
+ threshold := 1 << accuracyLog
+
+ // The number of bits needed to compute threshold.
+ bitsNeeded := accuracyLog + 1
+
+ // The next character value.
+ sym := 0
+
+ // Whether the last count was 0.
+ prev0 := false
+
+ var norm [256]int16
+
+ for remaining > 1 && sym <= maxSym {
+ if err := br.moreBits(); err != nil {
+ return 0, 0, err
+ }
+
+ if prev0 {
+ // Previous count was 0, so there is a 2-bit
+ // repeat flag. If the 2-bit flag is 0b11,
+ // it adds 3 and then there is another repeat flag.
+ zsym := sym
+ for (br.bits & 0xfff) == 0xfff {
+ zsym += 3 * 6
+ br.bits >>= 12
+ br.cnt -= 12
+ if err := br.moreBits(); err != nil {
+ return 0, 0, err
+ }
+ }
+ for (br.bits & 3) == 3 {
+ zsym += 3
+ br.bits >>= 2
+ br.cnt -= 2
+ if err := br.moreBits(); err != nil {
+ return 0, 0, err
+ }
+ }
+
+ // We have at least 14 bits here,
+ // no need to call moreBits
+
+ zsym += int(br.val(2))
+
+ if zsym > maxSym {
+ return 0, 0, br.makeError("FSE symbol index overflow")
+ }
+
+ for ; sym < zsym; sym++ {
+ norm[uint8(sym)] = 0
+ }
+
+ prev0 = false
+ continue
+ }
+
+ max := (2*threshold - 1) - remaining
+ var count int
+ if int(br.bits&uint32(threshold-1)) < max {
+ // A small value.
+ count = int(br.bits & uint32((threshold - 1)))
+ br.bits >>= bitsNeeded - 1
+ br.cnt -= uint32(bitsNeeded - 1)
+ } else {
+ // A large value.
+ count = int(br.bits & uint32((2*threshold - 1)))
+ if count >= threshold {
+ count -= max
+ }
+ br.bits >>= bitsNeeded
+ br.cnt -= uint32(bitsNeeded)
+ }
+
+ count--
+ if count >= 0 {
+ remaining -= count
+ } else {
+ remaining--
+ }
+ if sym >= 256 {
+ return 0, 0, br.makeError("FSE sym overflow")
+ }
+ norm[uint8(sym)] = int16(count)
+ sym++
+
+ prev0 = count == 0
+
+ for remaining < threshold {
+ bitsNeeded--
+ threshold >>= 1
+ }
+ }
+
+ if remaining != 1 {
+ return 0, 0, br.makeError("too many symbols in FSE table")
+ }
+
+ for ; sym <= maxSym; sym++ {
+ norm[uint8(sym)] = 0
+ }
+
+ br.backup()
+
+ if err := r.buildFSE(off, norm[:maxSym+1], table, accuracyLog); err != nil {
+ return 0, 0, err
+ }
+
+ return accuracyLog, int(br.off), nil
+}
+
+// buildFSE builds an FSE decoding table from a list of probabilities.
+// The probabilities are in norm. next is scratch space. The number of bits
+// in the table is tableBits.
+func (r *Reader) buildFSE(off int, norm []int16, table []fseEntry, tableBits int) error {
+ tableSize := 1 << tableBits
+ highThreshold := tableSize - 1
+
+ var next [256]uint16
+
+ for i, n := range norm {
+ if n >= 0 {
+ next[uint8(i)] = uint16(n)
+ } else {
+ table[highThreshold].sym = uint8(i)
+ highThreshold--
+ next[uint8(i)] = 1
+ }
+ }
+
+ pos := 0
+ step := (tableSize >> 1) + (tableSize >> 3) + 3
+ mask := tableSize - 1
+ for i, n := range norm {
+ for j := 0; j < int(n); j++ {
+ table[pos].sym = uint8(i)
+ pos = (pos + step) & mask
+ for pos > highThreshold {
+ pos = (pos + step) & mask
+ }
+ }
+ }
+ if pos != 0 {
+ return r.makeError(off, "FSE count error")
+ }
+
+ for i := 0; i < tableSize; i++ {
+ sym := table[i].sym
+ nextState := next[sym]
+ next[sym]++
+
+ if nextState == 0 {
+ return r.makeError(off, "FSE state error")
+ }
+
+ highBit := 15 - bits.LeadingZeros16(nextState)
+
+ bits := tableBits - highBit
+ table[i].bits = uint8(bits)
+ table[i].base = (nextState << bits) - uint16(tableSize)
+ }
+
+ return nil
+}
+
+// fseBaselineEntry is an entry in an FSE baseline table.
+// We use these for literal/match/length values.
+// Those require mapping the symbol to a baseline value,
+// and then reading zero or more bits and adding the value to the baseline.
+// Rather than looking thees up in separate tables,
+// we convert the FSE table to an FSE baseline table.
+type fseBaselineEntry struct {
+ baseline uint32 // baseline for value that this entry represents
+ basebits uint8 // number of bits to read to add to baseline
+ bits uint8 // number of bits to read to determine next state
+ base uint16 // add the bits to this base to get the next state
+}
+
+// Given a literal length code, we need to read a number of bits and
+// add that to a baseline. For states 0 to 15 the baseline is the
+// state and the number of bits is zero. RFC 3.1.1.3.2.1.1.
+
+const literalLengthOffset = 16
+
+var literalLengthBase = []uint32{
+ 16 | (1 << 24),
+ 18 | (1 << 24),
+ 20 | (1 << 24),
+ 22 | (1 << 24),
+ 24 | (2 << 24),
+ 28 | (2 << 24),
+ 32 | (3 << 24),
+ 40 | (3 << 24),
+ 48 | (4 << 24),
+ 64 | (6 << 24),
+ 128 | (7 << 24),
+ 256 | (8 << 24),
+ 512 | (9 << 24),
+ 1024 | (10 << 24),
+ 2048 | (11 << 24),
+ 4096 | (12 << 24),
+ 8192 | (13 << 24),
+ 16384 | (14 << 24),
+ 32768 | (15 << 24),
+ 65536 | (16 << 24),
+}
+
+// makeLiteralBaselineFSE converts the literal length fseTable to baselineTable.
+func (r *Reader) makeLiteralBaselineFSE(off int, fseTable []fseEntry, baselineTable []fseBaselineEntry) error {
+ for i, e := range fseTable {
+ be := fseBaselineEntry{
+ bits: e.bits,
+ base: e.base,
+ }
+ if e.sym < literalLengthOffset {
+ be.baseline = uint32(e.sym)
+ be.basebits = 0
+ } else {
+ if e.sym > 35 {
+ return r.makeError(off, "FSE baseline symbol overflow")
+ }
+ idx := e.sym - literalLengthOffset
+ basebits := literalLengthBase[idx]
+ be.baseline = basebits & 0xffffff
+ be.basebits = uint8(basebits >> 24)
+ }
+ baselineTable[i] = be
+ }
+ return nil
+}
+
+// makeOffsetBaselineFSE converts the offset length fseTable to baselineTable.
+func (r *Reader) makeOffsetBaselineFSE(off int, fseTable []fseEntry, baselineTable []fseBaselineEntry) error {
+ for i, e := range fseTable {
+ be := fseBaselineEntry{
+ bits: e.bits,
+ base: e.base,
+ }
+ if e.sym > 31 {
+ return r.makeError(off, "FSE offset symbol overflow")
+ }
+
+ // The simple way to write this is
+ // be.baseline = 1 << e.sym
+ // be.basebits = e.sym
+ // That would give us an offset value that corresponds to
+ // the one described in the RFC. However, for offsets > 3
+ // we have to subtract 3. And for offset values 1, 2, 3
+ // we use a repeated offset.
+ //
+ // The baseline is always a power of 2, and is never 0,
+ // so for those low values we will see one entry that is
+ // baseline 1, basebits 0, and one entry that is baseline 2,
+ // basebits 1. All other entries will have baseline >= 4
+ // basebits >= 2.
+ //
+ // So we can check for RFC offset <= 3 by checking for
+ // basebits <= 1. That means that we can subtract 3 here
+ // and not worry about doing it in the hot loop.
+
+ be.baseline = 1 << e.sym
+ if e.sym >= 2 {
+ be.baseline -= 3
+ }
+ be.basebits = e.sym
+ baselineTable[i] = be
+ }
+ return nil
+}
+
+// Given a match length code, we need to read a number of bits and add
+// that to a baseline. For states 0 to 31 the baseline is state+3 and
+// the number of bits is zero. RFC 3.1.1.3.2.1.1.
+
+const matchLengthOffset = 32
+
+var matchLengthBase = []uint32{
+ 35 | (1 << 24),
+ 37 | (1 << 24),
+ 39 | (1 << 24),
+ 41 | (1 << 24),
+ 43 | (2 << 24),
+ 47 | (2 << 24),
+ 51 | (3 << 24),
+ 59 | (3 << 24),
+ 67 | (4 << 24),
+ 83 | (4 << 24),
+ 99 | (5 << 24),
+ 131 | (7 << 24),
+ 259 | (8 << 24),
+ 515 | (9 << 24),
+ 1027 | (10 << 24),
+ 2051 | (11 << 24),
+ 4099 | (12 << 24),
+ 8195 | (13 << 24),
+ 16387 | (14 << 24),
+ 32771 | (15 << 24),
+ 65539 | (16 << 24),
+}
+
+// makeMatchBaselineFSE converts the match length fseTable to baselineTable.
+func (r *Reader) makeMatchBaselineFSE(off int, fseTable []fseEntry, baselineTable []fseBaselineEntry) error {
+ for i, e := range fseTable {
+ be := fseBaselineEntry{
+ bits: e.bits,
+ base: e.base,
+ }
+ if e.sym < matchLengthOffset {
+ be.baseline = uint32(e.sym) + 3
+ be.basebits = 0
+ } else {
+ if e.sym > 52 {
+ return r.makeError(off, "FSE baseline symbol overflow")
+ }
+ idx := e.sym - matchLengthOffset
+ basebits := matchLengthBase[idx]
+ be.baseline = basebits & 0xffffff
+ be.basebits = uint8(basebits >> 24)
+ }
+ baselineTable[i] = be
+ }
+ return nil
+}
+
+// predefinedLiteralTable is the predefined table to use for literal lengths.
+// Generated from table in RFC 3.1.1.3.2.2.1.
+// Checked by TestPredefinedTables.
+var predefinedLiteralTable = [...]fseBaselineEntry{
+ {0, 0, 4, 0}, {0, 0, 4, 16}, {1, 0, 5, 32},
+ {3, 0, 5, 0}, {4, 0, 5, 0}, {6, 0, 5, 0},
+ {7, 0, 5, 0}, {9, 0, 5, 0}, {10, 0, 5, 0},
+ {12, 0, 5, 0}, {14, 0, 6, 0}, {16, 1, 5, 0},
+ {20, 1, 5, 0}, {22, 1, 5, 0}, {28, 2, 5, 0},
+ {32, 3, 5, 0}, {48, 4, 5, 0}, {64, 6, 5, 32},
+ {128, 7, 5, 0}, {256, 8, 6, 0}, {1024, 10, 6, 0},
+ {4096, 12, 6, 0}, {0, 0, 4, 32}, {1, 0, 4, 0},
+ {2, 0, 5, 0}, {4, 0, 5, 32}, {5, 0, 5, 0},
+ {7, 0, 5, 32}, {8, 0, 5, 0}, {10, 0, 5, 32},
+ {11, 0, 5, 0}, {13, 0, 6, 0}, {16, 1, 5, 32},
+ {18, 1, 5, 0}, {22, 1, 5, 32}, {24, 2, 5, 0},
+ {32, 3, 5, 32}, {40, 3, 5, 0}, {64, 6, 4, 0},
+ {64, 6, 4, 16}, {128, 7, 5, 32}, {512, 9, 6, 0},
+ {2048, 11, 6, 0}, {0, 0, 4, 48}, {1, 0, 4, 16},
+ {2, 0, 5, 32}, {3, 0, 5, 32}, {5, 0, 5, 32},
+ {6, 0, 5, 32}, {8, 0, 5, 32}, {9, 0, 5, 32},
+ {11, 0, 5, 32}, {12, 0, 5, 32}, {15, 0, 6, 0},
+ {18, 1, 5, 32}, {20, 1, 5, 32}, {24, 2, 5, 32},
+ {28, 2, 5, 32}, {40, 3, 5, 32}, {48, 4, 5, 32},
+ {65536, 16, 6, 0}, {32768, 15, 6, 0}, {16384, 14, 6, 0},
+ {8192, 13, 6, 0},
+}
+
+// predefinedOffsetTable is the predefined table to use for offsets.
+// Generated from table in RFC 3.1.1.3.2.2.3.
+// Checked by TestPredefinedTables.
+var predefinedOffsetTable = [...]fseBaselineEntry{
+ {1, 0, 5, 0}, {61, 6, 4, 0}, {509, 9, 5, 0},
+ {32765, 15, 5, 0}, {2097149, 21, 5, 0}, {5, 3, 5, 0},
+ {125, 7, 4, 0}, {4093, 12, 5, 0}, {262141, 18, 5, 0},
+ {8388605, 23, 5, 0}, {29, 5, 5, 0}, {253, 8, 4, 0},
+ {16381, 14, 5, 0}, {1048573, 20, 5, 0}, {1, 2, 5, 0},
+ {125, 7, 4, 16}, {2045, 11, 5, 0}, {131069, 17, 5, 0},
+ {4194301, 22, 5, 0}, {13, 4, 5, 0}, {253, 8, 4, 16},
+ {8189, 13, 5, 0}, {524285, 19, 5, 0}, {2, 1, 5, 0},
+ {61, 6, 4, 16}, {1021, 10, 5, 0}, {65533, 16, 5, 0},
+ {268435453, 28, 5, 0}, {134217725, 27, 5, 0}, {67108861, 26, 5, 0},
+ {33554429, 25, 5, 0}, {16777213, 24, 5, 0},
+}
+
+// predefinedMatchTable is the predefined table to use for match lengths.
+// Generated from table in RFC 3.1.1.3.2.2.2.
+// Checked by TestPredefinedTables.
+var predefinedMatchTable = [...]fseBaselineEntry{
+ {3, 0, 6, 0}, {4, 0, 4, 0}, {5, 0, 5, 32},
+ {6, 0, 5, 0}, {8, 0, 5, 0}, {9, 0, 5, 0},
+ {11, 0, 5, 0}, {13, 0, 6, 0}, {16, 0, 6, 0},
+ {19, 0, 6, 0}, {22, 0, 6, 0}, {25, 0, 6, 0},
+ {28, 0, 6, 0}, {31, 0, 6, 0}, {34, 0, 6, 0},
+ {37, 1, 6, 0}, {41, 1, 6, 0}, {47, 2, 6, 0},
+ {59, 3, 6, 0}, {83, 4, 6, 0}, {131, 7, 6, 0},
+ {515, 9, 6, 0}, {4, 0, 4, 16}, {5, 0, 4, 0},
+ {6, 0, 5, 32}, {7, 0, 5, 0}, {9, 0, 5, 32},
+ {10, 0, 5, 0}, {12, 0, 6, 0}, {15, 0, 6, 0},
+ {18, 0, 6, 0}, {21, 0, 6, 0}, {24, 0, 6, 0},
+ {27, 0, 6, 0}, {30, 0, 6, 0}, {33, 0, 6, 0},
+ {35, 1, 6, 0}, {39, 1, 6, 0}, {43, 2, 6, 0},
+ {51, 3, 6, 0}, {67, 4, 6, 0}, {99, 5, 6, 0},
+ {259, 8, 6, 0}, {4, 0, 4, 32}, {4, 0, 4, 48},
+ {5, 0, 4, 16}, {7, 0, 5, 32}, {8, 0, 5, 32},
+ {10, 0, 5, 32}, {11, 0, 5, 32}, {14, 0, 6, 0},
+ {17, 0, 6, 0}, {20, 0, 6, 0}, {23, 0, 6, 0},
+ {26, 0, 6, 0}, {29, 0, 6, 0}, {32, 0, 6, 0},
+ {65539, 16, 6, 0}, {32771, 15, 6, 0}, {16387, 14, 6, 0},
+ {8195, 13, 6, 0}, {4099, 12, 6, 0}, {2051, 11, 6, 0},
+ {1027, 10, 6, 0},
+}
diff --git a/contrib/go/_std_1.21/src/internal/zstd/huff.go b/contrib/go/_std_1.21/src/internal/zstd/huff.go
new file mode 100644
index 0000000000..452e24b760
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/zstd/huff.go
@@ -0,0 +1,204 @@
+// Copyright 2023 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 zstd
+
+import (
+ "io"
+ "math/bits"
+)
+
+// maxHuffmanBits is the largest possible Huffman table bits.
+const maxHuffmanBits = 11
+
+// readHuff reads Huffman table from data starting at off into table.
+// Each entry in a Huffman table is a pair of bytes.
+// The high byte is the encoded value. The low byte is the number
+// of bits used to encode that value. We index into the table
+// with a value of size tableBits. A value that requires fewer bits
+// appear in the table multiple times.
+// This returns the number of bits in the Huffman table and the new offset.
+// RFC 4.2.1.
+func (r *Reader) readHuff(data block, off int, table []uint16) (tableBits, roff int, err error) {
+ if off >= len(data) {
+ return 0, 0, r.makeEOFError(off)
+ }
+
+ hdr := data[off]
+ off++
+
+ var weights [256]uint8
+ var count int
+ if hdr < 128 {
+ // The table is compressed using an FSE. RFC 4.2.1.2.
+ if len(r.fseScratch) < 1<<6 {
+ r.fseScratch = make([]fseEntry, 1<<6)
+ }
+ fseBits, noff, err := r.readFSE(data, off, 255, 6, r.fseScratch)
+ if err != nil {
+ return 0, 0, err
+ }
+ fseTable := r.fseScratch
+
+ if off+int(hdr) > len(data) {
+ return 0, 0, r.makeEOFError(off)
+ }
+
+ rbr, err := r.makeReverseBitReader(data, off+int(hdr)-1, noff)
+ if err != nil {
+ return 0, 0, err
+ }
+
+ state1, err := rbr.val(uint8(fseBits))
+ if err != nil {
+ return 0, 0, err
+ }
+
+ state2, err := rbr.val(uint8(fseBits))
+ if err != nil {
+ return 0, 0, err
+ }
+
+ // There are two independent FSE streams, tracked by
+ // state1 and state2. We decode them alternately.
+
+ for {
+ pt := &fseTable[state1]
+ if !rbr.fetch(pt.bits) {
+ if count >= 254 {
+ return 0, 0, rbr.makeError("Huffman count overflow")
+ }
+ weights[count] = pt.sym
+ weights[count+1] = fseTable[state2].sym
+ count += 2
+ break
+ }
+
+ v, err := rbr.val(pt.bits)
+ if err != nil {
+ return 0, 0, err
+ }
+ state1 = uint32(pt.base) + v
+
+ if count >= 255 {
+ return 0, 0, rbr.makeError("Huffman count overflow")
+ }
+
+ weights[count] = pt.sym
+ count++
+
+ pt = &fseTable[state2]
+
+ if !rbr.fetch(pt.bits) {
+ if count >= 254 {
+ return 0, 0, rbr.makeError("Huffman count overflow")
+ }
+ weights[count] = pt.sym
+ weights[count+1] = fseTable[state1].sym
+ count += 2
+ break
+ }
+
+ v, err = rbr.val(pt.bits)
+ if err != nil {
+ return 0, 0, err
+ }
+ state2 = uint32(pt.base) + v
+
+ if count >= 255 {
+ return 0, 0, rbr.makeError("Huffman count overflow")
+ }
+
+ weights[count] = pt.sym
+ count++
+ }
+
+ off += int(hdr)
+ } else {
+ // The table is not compressed. Each weight is 4 bits.
+
+ count = int(hdr) - 127
+ if off+((count+1)/2) >= len(data) {
+ return 0, 0, io.ErrUnexpectedEOF
+ }
+ for i := 0; i < count; i += 2 {
+ b := data[off]
+ off++
+ weights[i] = b >> 4
+ weights[i+1] = b & 0xf
+ }
+ }
+
+ // RFC 4.2.1.3.
+
+ var weightMark [13]uint32
+ weightMask := uint32(0)
+ for _, w := range weights[:count] {
+ if w > 12 {
+ return 0, 0, r.makeError(off, "Huffman weight overflow")
+ }
+ weightMark[w]++
+ if w > 0 {
+ weightMask += 1 << (w - 1)
+ }
+ }
+ if weightMask == 0 {
+ return 0, 0, r.makeError(off, "bad Huffman weights")
+ }
+
+ tableBits = 32 - bits.LeadingZeros32(weightMask)
+ if tableBits > maxHuffmanBits {
+ return 0, 0, r.makeError(off, "bad Huffman weights")
+ }
+
+ if len(table) < 1<<tableBits {
+ return 0, 0, r.makeError(off, "Huffman table too small")
+ }
+
+ // Work out the last weight value, which is omitted because
+ // the weights must sum to a power of two.
+ left := (uint32(1) << tableBits) - weightMask
+ if left == 0 {
+ return 0, 0, r.makeError(off, "bad Huffman weights")
+ }
+ highBit := 31 - bits.LeadingZeros32(left)
+ if uint32(1)<<highBit != left {
+ return 0, 0, r.makeError(off, "bad Huffman weights")
+ }
+ if count >= 256 {
+ return 0, 0, r.makeError(off, "Huffman weight overflow")
+ }
+ weights[count] = uint8(highBit + 1)
+ count++
+ weightMark[highBit+1]++
+
+ if weightMark[1] < 2 || weightMark[1]&1 != 0 {
+ return 0, 0, r.makeError(off, "bad Huffman weights")
+ }
+
+ // Change weightMark from a count of weights to the index of
+ // the first symbol for that weight. We shift the indexes to
+ // also store how many we have seen so far,
+ next := uint32(0)
+ for i := 0; i < tableBits; i++ {
+ cur := next
+ next += weightMark[i+1] << i
+ weightMark[i+1] = cur
+ }
+
+ for i, w := range weights[:count] {
+ if w == 0 {
+ continue
+ }
+ length := uint32(1) << (w - 1)
+ tval := uint16(i)<<8 | (uint16(tableBits) + 1 - uint16(w))
+ start := weightMark[w]
+ for j := uint32(0); j < length; j++ {
+ table[start+j] = tval
+ }
+ weightMark[w] += length
+ }
+
+ return tableBits, off, nil
+}
diff --git a/contrib/go/_std_1.21/src/internal/zstd/literals.go b/contrib/go/_std_1.21/src/internal/zstd/literals.go
new file mode 100644
index 0000000000..b46d668f26
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/zstd/literals.go
@@ -0,0 +1,330 @@
+// Copyright 2023 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 zstd
+
+import (
+ "encoding/binary"
+)
+
+// readLiterals reads and decompresses the literals from data at off.
+// The literals are appended to outbuf, which is returned.
+// Also returns the new input offset. RFC 3.1.1.3.1.
+func (r *Reader) readLiterals(data block, off int, outbuf []byte) (int, []byte, error) {
+ if off >= len(data) {
+ return 0, nil, r.makeEOFError(off)
+ }
+
+ // Literals section header. RFC 3.1.1.3.1.1.
+ hdr := data[off]
+ off++
+
+ if (hdr&3) == 0 || (hdr&3) == 1 {
+ return r.readRawRLELiterals(data, off, hdr, outbuf)
+ } else {
+ return r.readHuffLiterals(data, off, hdr, outbuf)
+ }
+}
+
+// readRawRLELiterals reads and decompresses a Raw_Literals_Block or
+// a RLE_Literals_Block. RFC 3.1.1.3.1.1.
+func (r *Reader) readRawRLELiterals(data block, off int, hdr byte, outbuf []byte) (int, []byte, error) {
+ raw := (hdr & 3) == 0
+
+ var regeneratedSize int
+ switch (hdr >> 2) & 3 {
+ case 0, 2:
+ regeneratedSize = int(hdr >> 3)
+ case 1:
+ if off >= len(data) {
+ return 0, nil, r.makeEOFError(off)
+ }
+ regeneratedSize = int(hdr>>4) + (int(data[off]) << 4)
+ off++
+ case 3:
+ if off+1 >= len(data) {
+ return 0, nil, r.makeEOFError(off)
+ }
+ regeneratedSize = int(hdr>>4) + (int(data[off]) << 4) + (int(data[off+1]) << 12)
+ off += 2
+ }
+
+ // We are going to use the entire literal block in the output.
+ // The maximum size of one decompressed block is 128K,
+ // so we can't have more literals than that.
+ if regeneratedSize > 128<<10 {
+ return 0, nil, r.makeError(off, "literal size too large")
+ }
+
+ if raw {
+ // RFC 3.1.1.3.1.2.
+ if off+regeneratedSize > len(data) {
+ return 0, nil, r.makeError(off, "raw literal size too large")
+ }
+ outbuf = append(outbuf, data[off:off+regeneratedSize]...)
+ off += regeneratedSize
+ } else {
+ // RFC 3.1.1.3.1.3.
+ if off >= len(data) {
+ return 0, nil, r.makeError(off, "RLE literal missing")
+ }
+ rle := data[off]
+ off++
+ for i := 0; i < regeneratedSize; i++ {
+ outbuf = append(outbuf, rle)
+ }
+ }
+
+ return off, outbuf, nil
+}
+
+// readHuffLiterals reads and decompresses a Compressed_Literals_Block or
+// a Treeless_Literals_Block. RFC 3.1.1.3.1.4.
+func (r *Reader) readHuffLiterals(data block, off int, hdr byte, outbuf []byte) (int, []byte, error) {
+ var (
+ regeneratedSize int
+ compressedSize int
+ streams int
+ )
+ switch (hdr >> 2) & 3 {
+ case 0, 1:
+ if off+1 >= len(data) {
+ return 0, nil, r.makeEOFError(off)
+ }
+ regeneratedSize = (int(hdr) >> 4) | ((int(data[off]) & 0x3f) << 4)
+ compressedSize = (int(data[off]) >> 6) | (int(data[off+1]) << 2)
+ off += 2
+ if ((hdr >> 2) & 3) == 0 {
+ streams = 1
+ } else {
+ streams = 4
+ }
+ case 2:
+ if off+2 >= len(data) {
+ return 0, nil, r.makeEOFError(off)
+ }
+ regeneratedSize = (int(hdr) >> 4) | (int(data[off]) << 4) | ((int(data[off+1]) & 3) << 12)
+ compressedSize = (int(data[off+1]) >> 2) | (int(data[off+2]) << 6)
+ off += 3
+ streams = 4
+ case 3:
+ if off+3 >= len(data) {
+ return 0, nil, r.makeEOFError(off)
+ }
+ regeneratedSize = (int(hdr) >> 4) | (int(data[off]) << 4) | ((int(data[off+1]) & 0x3f) << 12)
+ compressedSize = (int(data[off+1]) >> 6) | (int(data[off+2]) << 2) | (int(data[off+3]) << 10)
+ off += 4
+ streams = 4
+ }
+
+ // We are going to use the entire literal block in the output.
+ // The maximum size of one decompressed block is 128K,
+ // so we can't have more literals than that.
+ if regeneratedSize > 128<<10 {
+ return 0, nil, r.makeError(off, "literal size too large")
+ }
+
+ roff := off + compressedSize
+ if roff > len(data) || roff < 0 {
+ return 0, nil, r.makeEOFError(off)
+ }
+
+ totalStreamsSize := compressedSize
+ if (hdr & 3) == 2 {
+ // Compressed_Literals_Block.
+ // Read new huffman tree.
+
+ if len(r.huffmanTable) < 1<<maxHuffmanBits {
+ r.huffmanTable = make([]uint16, 1<<maxHuffmanBits)
+ }
+
+ huffmanTableBits, hoff, err := r.readHuff(data, off, r.huffmanTable)
+ if err != nil {
+ return 0, nil, err
+ }
+ r.huffmanTableBits = huffmanTableBits
+
+ if totalStreamsSize < hoff-off {
+ return 0, nil, r.makeError(off, "Huffman table too big")
+ }
+ totalStreamsSize -= hoff - off
+ off = hoff
+ } else {
+ // Treeless_Literals_Block
+ // Reuse previous Huffman tree.
+ if r.huffmanTableBits == 0 {
+ return 0, nil, r.makeError(off, "missing literals Huffman tree")
+ }
+ }
+
+ // Decompress compressedSize bytes of data at off using the
+ // Huffman tree.
+
+ var err error
+ if streams == 1 {
+ outbuf, err = r.readLiteralsOneStream(data, off, totalStreamsSize, regeneratedSize, outbuf)
+ } else {
+ outbuf, err = r.readLiteralsFourStreams(data, off, totalStreamsSize, regeneratedSize, outbuf)
+ }
+
+ if err != nil {
+ return 0, nil, err
+ }
+
+ return roff, outbuf, nil
+}
+
+// readLiteralsOneStream reads a single stream of compressed literals.
+func (r *Reader) readLiteralsOneStream(data block, off, compressedSize, regeneratedSize int, outbuf []byte) ([]byte, error) {
+ // We let the reverse bit reader read earlier bytes,
+ // because the Huffman table ignores bits that it doesn't need.
+ rbr, err := r.makeReverseBitReader(data, off+compressedSize-1, off-2)
+ if err != nil {
+ return nil, err
+ }
+
+ huffTable := r.huffmanTable
+ huffBits := uint32(r.huffmanTableBits)
+ huffMask := (uint32(1) << huffBits) - 1
+
+ for i := 0; i < regeneratedSize; i++ {
+ if !rbr.fetch(uint8(huffBits)) {
+ return nil, rbr.makeError("literals Huffman stream out of bits")
+ }
+
+ var t uint16
+ idx := (rbr.bits >> (rbr.cnt - huffBits)) & huffMask
+ t = huffTable[idx]
+ outbuf = append(outbuf, byte(t>>8))
+ rbr.cnt -= uint32(t & 0xff)
+ }
+
+ return outbuf, nil
+}
+
+// readLiteralsFourStreams reads four interleaved streams of
+// compressed literals.
+func (r *Reader) readLiteralsFourStreams(data block, off, totalStreamsSize, regeneratedSize int, outbuf []byte) ([]byte, error) {
+ // Read the jump table to find out where the streams are.
+ // RFC 3.1.1.3.1.6.
+ if off+5 >= len(data) {
+ return nil, r.makeEOFError(off)
+ }
+ if totalStreamsSize < 6 {
+ return nil, r.makeError(off, "total streams size too small for jump table")
+ }
+
+ streamSize1 := binary.LittleEndian.Uint16(data[off:])
+ streamSize2 := binary.LittleEndian.Uint16(data[off+2:])
+ streamSize3 := binary.LittleEndian.Uint16(data[off+4:])
+ off += 6
+
+ tot := uint64(streamSize1) + uint64(streamSize2) + uint64(streamSize3)
+ if tot > uint64(totalStreamsSize)-6 {
+ return nil, r.makeEOFError(off)
+ }
+ streamSize4 := uint32(totalStreamsSize) - 6 - uint32(tot)
+
+ off--
+ off1 := off + int(streamSize1)
+ start1 := off + 1
+
+ off2 := off1 + int(streamSize2)
+ start2 := off1 + 1
+
+ off3 := off2 + int(streamSize3)
+ start3 := off2 + 1
+
+ off4 := off3 + int(streamSize4)
+ start4 := off3 + 1
+
+ // We let the reverse bit readers read earlier bytes,
+ // because the Huffman tables ignore bits that they don't need.
+
+ rbr1, err := r.makeReverseBitReader(data, off1, start1-2)
+ if err != nil {
+ return nil, err
+ }
+
+ rbr2, err := r.makeReverseBitReader(data, off2, start2-2)
+ if err != nil {
+ return nil, err
+ }
+
+ rbr3, err := r.makeReverseBitReader(data, off3, start3-2)
+ if err != nil {
+ return nil, err
+ }
+
+ rbr4, err := r.makeReverseBitReader(data, off4, start4-2)
+ if err != nil {
+ return nil, err
+ }
+
+ regeneratedStreamSize := (regeneratedSize + 3) / 4
+
+ out1 := len(outbuf)
+ out2 := out1 + regeneratedStreamSize
+ out3 := out2 + regeneratedStreamSize
+ out4 := out3 + regeneratedStreamSize
+
+ regeneratedStreamSize4 := regeneratedSize - regeneratedStreamSize*3
+
+ outbuf = append(outbuf, make([]byte, regeneratedSize)...)
+
+ huffTable := r.huffmanTable
+ huffBits := uint32(r.huffmanTableBits)
+ huffMask := (uint32(1) << huffBits) - 1
+
+ for i := 0; i < regeneratedStreamSize; i++ {
+ use4 := i < regeneratedStreamSize4
+
+ fetchHuff := func(rbr *reverseBitReader) (uint16, error) {
+ if !rbr.fetch(uint8(huffBits)) {
+ return 0, rbr.makeError("literals Huffman stream out of bits")
+ }
+ idx := (rbr.bits >> (rbr.cnt - huffBits)) & huffMask
+ return huffTable[idx], nil
+ }
+
+ t1, err := fetchHuff(&rbr1)
+ if err != nil {
+ return nil, err
+ }
+
+ t2, err := fetchHuff(&rbr2)
+ if err != nil {
+ return nil, err
+ }
+
+ t3, err := fetchHuff(&rbr3)
+ if err != nil {
+ return nil, err
+ }
+
+ if use4 {
+ t4, err := fetchHuff(&rbr4)
+ if err != nil {
+ return nil, err
+ }
+ outbuf[out4] = byte(t4 >> 8)
+ out4++
+ rbr4.cnt -= uint32(t4 & 0xff)
+ }
+
+ outbuf[out1] = byte(t1 >> 8)
+ out1++
+ rbr1.cnt -= uint32(t1 & 0xff)
+
+ outbuf[out2] = byte(t2 >> 8)
+ out2++
+ rbr2.cnt -= uint32(t2 & 0xff)
+
+ outbuf[out3] = byte(t3 >> 8)
+ out3++
+ rbr3.cnt -= uint32(t3 & 0xff)
+ }
+
+ return outbuf, nil
+}
diff --git a/contrib/go/_std_1.21/src/internal/zstd/xxhash.go b/contrib/go/_std_1.21/src/internal/zstd/xxhash.go
new file mode 100644
index 0000000000..4d579ee2d5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/zstd/xxhash.go
@@ -0,0 +1,148 @@
+// Copyright 2023 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 zstd
+
+import (
+ "encoding/binary"
+ "math/bits"
+)
+
+const (
+ xxhPrime64c1 = 0x9e3779b185ebca87
+ xxhPrime64c2 = 0xc2b2ae3d27d4eb4f
+ xxhPrime64c3 = 0x165667b19e3779f9
+ xxhPrime64c4 = 0x85ebca77c2b2ae63
+ xxhPrime64c5 = 0x27d4eb2f165667c5
+)
+
+// xxhash64 is the state of a xxHash-64 checksum.
+type xxhash64 struct {
+ len uint64 // total length hashed
+ v [4]uint64 // accumulators
+ buf [32]byte // buffer
+ cnt int // number of bytes in buffer
+}
+
+// reset discards the current state and prepares to compute a new hash.
+// We assume a seed of 0 since that is what zstd uses.
+func (xh *xxhash64) reset() {
+ xh.len = 0
+
+ // Separate addition for awkward constant overflow.
+ xh.v[0] = xxhPrime64c1
+ xh.v[0] += xxhPrime64c2
+
+ xh.v[1] = xxhPrime64c2
+ xh.v[2] = 0
+
+ // Separate negation for awkward constant overflow.
+ xh.v[3] = xxhPrime64c1
+ xh.v[3] = -xh.v[3]
+
+ for i := range xh.buf {
+ xh.buf[i] = 0
+ }
+ xh.cnt = 0
+}
+
+// update adds a buffer to the has.
+func (xh *xxhash64) update(b []byte) {
+ xh.len += uint64(len(b))
+
+ if xh.cnt+len(b) < len(xh.buf) {
+ copy(xh.buf[xh.cnt:], b)
+ xh.cnt += len(b)
+ return
+ }
+
+ if xh.cnt > 0 {
+ n := copy(xh.buf[xh.cnt:], b)
+ b = b[n:]
+ xh.v[0] = xh.round(xh.v[0], binary.LittleEndian.Uint64(xh.buf[:]))
+ xh.v[1] = xh.round(xh.v[1], binary.LittleEndian.Uint64(xh.buf[8:]))
+ xh.v[2] = xh.round(xh.v[2], binary.LittleEndian.Uint64(xh.buf[16:]))
+ xh.v[3] = xh.round(xh.v[3], binary.LittleEndian.Uint64(xh.buf[24:]))
+ xh.cnt = 0
+ }
+
+ for len(b) >= 32 {
+ xh.v[0] = xh.round(xh.v[0], binary.LittleEndian.Uint64(b))
+ xh.v[1] = xh.round(xh.v[1], binary.LittleEndian.Uint64(b[8:]))
+ xh.v[2] = xh.round(xh.v[2], binary.LittleEndian.Uint64(b[16:]))
+ xh.v[3] = xh.round(xh.v[3], binary.LittleEndian.Uint64(b[24:]))
+ b = b[32:]
+ }
+
+ if len(b) > 0 {
+ copy(xh.buf[:], b)
+ xh.cnt = len(b)
+ }
+}
+
+// digest returns the final hash value.
+func (xh *xxhash64) digest() uint64 {
+ var h64 uint64
+ if xh.len < 32 {
+ h64 = xh.v[2] + xxhPrime64c5
+ } else {
+ h64 = bits.RotateLeft64(xh.v[0], 1) +
+ bits.RotateLeft64(xh.v[1], 7) +
+ bits.RotateLeft64(xh.v[2], 12) +
+ bits.RotateLeft64(xh.v[3], 18)
+ h64 = xh.mergeRound(h64, xh.v[0])
+ h64 = xh.mergeRound(h64, xh.v[1])
+ h64 = xh.mergeRound(h64, xh.v[2])
+ h64 = xh.mergeRound(h64, xh.v[3])
+ }
+
+ h64 += xh.len
+
+ len := xh.len
+ len &= 31
+ buf := xh.buf[:]
+ for len >= 8 {
+ k1 := xh.round(0, binary.LittleEndian.Uint64(buf))
+ buf = buf[8:]
+ h64 ^= k1
+ h64 = bits.RotateLeft64(h64, 27)*xxhPrime64c1 + xxhPrime64c4
+ len -= 8
+ }
+ if len >= 4 {
+ h64 ^= uint64(binary.LittleEndian.Uint32(buf)) * xxhPrime64c1
+ buf = buf[4:]
+ h64 = bits.RotateLeft64(h64, 23)*xxhPrime64c2 + xxhPrime64c3
+ len -= 4
+ }
+ for len > 0 {
+ h64 ^= uint64(buf[0]) * xxhPrime64c5
+ buf = buf[1:]
+ h64 = bits.RotateLeft64(h64, 11) * xxhPrime64c1
+ len--
+ }
+
+ h64 ^= h64 >> 33
+ h64 *= xxhPrime64c2
+ h64 ^= h64 >> 29
+ h64 *= xxhPrime64c3
+ h64 ^= h64 >> 32
+
+ return h64
+}
+
+// round updates a value.
+func (xh *xxhash64) round(v, n uint64) uint64 {
+ v += n * xxhPrime64c2
+ v = bits.RotateLeft64(v, 31)
+ v *= xxhPrime64c1
+ return v
+}
+
+// mergeRound updates a value in the final round.
+func (xh *xxhash64) mergeRound(v, n uint64) uint64 {
+ n = xh.round(0, n)
+ v ^= n
+ v = v*xxhPrime64c1 + xxhPrime64c4
+ return v
+}
diff --git a/contrib/go/_std_1.21/src/internal/zstd/ya.make b/contrib/go/_std_1.21/src/internal/zstd/ya.make
new file mode 100644
index 0000000000..0290818f82
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/zstd/ya.make
@@ -0,0 +1,23 @@
+GO_LIBRARY()
+
+SRCS(
+ bits.go
+ block.go
+ fse.go
+ huff.go
+ literals.go
+ xxhash.go
+ zstd.go
+)
+
+GO_TEST_SRCS(
+ fse_test.go
+ fuzz_test.go
+ xxhash_test.go
+ zstd_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/internal/zstd/zstd.go b/contrib/go/_std_1.21/src/internal/zstd/zstd.go
new file mode 100644
index 0000000000..a8607893cd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/internal/zstd/zstd.go
@@ -0,0 +1,508 @@
+// Copyright 2023 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 zstd provides a decompressor for zstd streams,
+// described in RFC 8878. It does not support dictionaries.
+package zstd
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+)
+
+// fuzzing is a fuzzer hook set to true when fuzzing.
+// This is used to reject cases where we don't match zstd.
+var fuzzing = false
+
+// Reader implements [io.Reader] to read a zstd compressed stream.
+type Reader struct {
+ // The underlying Reader.
+ r io.Reader
+
+ // Whether we have read the frame header.
+ // This is of interest when buffer is empty.
+ // If true we expect to see a new block.
+ sawFrameHeader bool
+
+ // Whether the current frame expects a checksum.
+ hasChecksum bool
+
+ // Whether we have read at least one frame.
+ readOneFrame bool
+
+ // True if the frame size is not known.
+ frameSizeUnknown bool
+
+ // The number of uncompressed bytes remaining in the current frame.
+ // If frameSizeUnknown is true, this is not valid.
+ remainingFrameSize uint64
+
+ // The number of bytes read from r up to the start of the current
+ // block, for error reporting.
+ blockOffset int64
+
+ // Buffered decompressed data.
+ buffer []byte
+ // Current read offset in buffer.
+ off int
+
+ // The current repeated offsets.
+ repeatedOffset1 uint32
+ repeatedOffset2 uint32
+ repeatedOffset3 uint32
+
+ // The current Huffman tree used for compressing literals.
+ huffmanTable []uint16
+ huffmanTableBits int
+
+ // The window for back references.
+ windowSize int // maximum required window size
+ window []byte // window data
+
+ // A buffer available to hold a compressed block.
+ compressedBuf []byte
+
+ // A buffer for literals.
+ literals []byte
+
+ // Sequence decode FSE tables.
+ seqTables [3][]fseBaselineEntry
+ seqTableBits [3]uint8
+
+ // Buffers for sequence decode FSE tables.
+ seqTableBuffers [3][]fseBaselineEntry
+
+ // Scratch space used for small reads, to avoid allocation.
+ scratch [16]byte
+
+ // A scratch table for reading an FSE. Only temporarily valid.
+ fseScratch []fseEntry
+
+ // For checksum computation.
+ checksum xxhash64
+}
+
+// NewReader creates a new Reader that decompresses data from the given reader.
+func NewReader(input io.Reader) *Reader {
+ r := new(Reader)
+ r.Reset(input)
+ return r
+}
+
+// Reset discards the current state and starts reading a new stream from r.
+// This permits reusing a Reader rather than allocating a new one.
+func (r *Reader) Reset(input io.Reader) {
+ r.r = input
+
+ // Several fields are preserved to avoid allocation.
+ // Others are always set before they are used.
+ r.sawFrameHeader = false
+ r.hasChecksum = false
+ r.readOneFrame = false
+ r.frameSizeUnknown = false
+ r.remainingFrameSize = 0
+ r.blockOffset = 0
+ // buffer
+ r.off = 0
+ // repeatedOffset1
+ // repeatedOffset2
+ // repeatedOffset3
+ // huffmanTable
+ // huffmanTableBits
+ // windowSize
+ // window
+ // compressedBuf
+ // literals
+ // seqTables
+ // seqTableBits
+ // seqTableBuffers
+ // scratch
+ // fseScratch
+}
+
+// Read implements [io.Reader].
+func (r *Reader) Read(p []byte) (int, error) {
+ if err := r.refillIfNeeded(); err != nil {
+ return 0, err
+ }
+ n := copy(p, r.buffer[r.off:])
+ r.off += n
+ return n, nil
+}
+
+// ReadByte implements [io.ByteReader].
+func (r *Reader) ReadByte() (byte, error) {
+ if err := r.refillIfNeeded(); err != nil {
+ return 0, err
+ }
+ ret := r.buffer[r.off]
+ r.off++
+ return ret, nil
+}
+
+// refillIfNeeded reads the next block if necessary.
+func (r *Reader) refillIfNeeded() error {
+ for r.off >= len(r.buffer) {
+ if err := r.refill(); err != nil {
+ return err
+ }
+ r.off = 0
+ }
+ return nil
+}
+
+// refill reads and decompresses the next block.
+func (r *Reader) refill() error {
+ if !r.sawFrameHeader {
+ if err := r.readFrameHeader(); err != nil {
+ return err
+ }
+ }
+ return r.readBlock()
+}
+
+// readFrameHeader reads the frame header and prepares to read a block.
+func (r *Reader) readFrameHeader() error {
+retry:
+ relativeOffset := 0
+
+ // Read magic number. RFC 3.1.1.
+ if _, err := io.ReadFull(r.r, r.scratch[:4]); err != nil {
+ // We require that the stream contain at least one frame.
+ if err == io.EOF && !r.readOneFrame {
+ err = io.ErrUnexpectedEOF
+ }
+ return r.wrapError(relativeOffset, err)
+ }
+
+ if magic := binary.LittleEndian.Uint32(r.scratch[:4]); magic != 0xfd2fb528 {
+ if magic >= 0x184d2a50 && magic <= 0x184d2a5f {
+ // This is a skippable frame.
+ r.blockOffset += int64(relativeOffset) + 4
+ if err := r.skipFrame(); err != nil {
+ return err
+ }
+ goto retry
+ }
+
+ return r.makeError(relativeOffset, "invalid magic number")
+ }
+
+ relativeOffset += 4
+
+ // Read Frame_Header_Descriptor. RFC 3.1.1.1.1.
+ if _, err := io.ReadFull(r.r, r.scratch[:1]); err != nil {
+ return r.wrapNonEOFError(relativeOffset, err)
+ }
+ descriptor := r.scratch[0]
+
+ singleSegment := descriptor&(1<<5) != 0
+
+ fcsFieldSize := 1 << (descriptor >> 6)
+ if fcsFieldSize == 1 && !singleSegment {
+ fcsFieldSize = 0
+ }
+
+ var windowDescriptorSize int
+ if singleSegment {
+ windowDescriptorSize = 0
+ } else {
+ windowDescriptorSize = 1
+ }
+
+ if descriptor&(1<<3) != 0 {
+ return r.makeError(relativeOffset, "reserved bit set in frame header descriptor")
+ }
+
+ r.hasChecksum = descriptor&(1<<2) != 0
+ if r.hasChecksum {
+ r.checksum.reset()
+ }
+
+ if descriptor&3 != 0 {
+ return r.makeError(relativeOffset, "dictionaries are not supported")
+ }
+
+ relativeOffset++
+
+ headerSize := windowDescriptorSize + fcsFieldSize
+
+ if _, err := io.ReadFull(r.r, r.scratch[:headerSize]); err != nil {
+ return r.wrapNonEOFError(relativeOffset, err)
+ }
+
+ // Figure out the maximum amount of data we need to retain
+ // for backreferences.
+
+ if singleSegment {
+ // No window required, as all the data is in a single buffer.
+ r.windowSize = 0
+ } else {
+ // Window descriptor. RFC 3.1.1.1.2.
+ windowDescriptor := r.scratch[0]
+ exponent := uint64(windowDescriptor >> 3)
+ mantissa := uint64(windowDescriptor & 7)
+ windowLog := exponent + 10
+ windowBase := uint64(1) << windowLog
+ windowAdd := (windowBase / 8) * mantissa
+ windowSize := windowBase + windowAdd
+
+ // Default zstd sets limits on the window size.
+ if fuzzing && (windowLog > 31 || windowSize > 1<<27) {
+ return r.makeError(relativeOffset, "windowSize too large")
+ }
+
+ // RFC 8878 permits us to set an 8M max on window size.
+ if windowSize > 8<<20 {
+ windowSize = 8 << 20
+ }
+
+ r.windowSize = int(windowSize)
+ }
+
+ // Frame_Content_Size. RFC 3.1.1.4.
+ r.frameSizeUnknown = false
+ r.remainingFrameSize = 0
+ fb := r.scratch[windowDescriptorSize:]
+ switch fcsFieldSize {
+ case 0:
+ r.frameSizeUnknown = true
+ case 1:
+ r.remainingFrameSize = uint64(fb[0])
+ case 2:
+ r.remainingFrameSize = 256 + uint64(binary.LittleEndian.Uint16(fb))
+ case 4:
+ r.remainingFrameSize = uint64(binary.LittleEndian.Uint32(fb))
+ case 8:
+ r.remainingFrameSize = binary.LittleEndian.Uint64(fb)
+ default:
+ panic("unreachable")
+ }
+
+ relativeOffset += headerSize
+
+ r.sawFrameHeader = true
+ r.readOneFrame = true
+ r.blockOffset += int64(relativeOffset)
+
+ // Prepare to read blocks from the frame.
+ r.repeatedOffset1 = 1
+ r.repeatedOffset2 = 4
+ r.repeatedOffset3 = 8
+ r.huffmanTableBits = 0
+ r.window = r.window[:0]
+ r.seqTables[0] = nil
+ r.seqTables[1] = nil
+ r.seqTables[2] = nil
+
+ return nil
+}
+
+// skipFrame skips a skippable frame. RFC 3.1.2.
+func (r *Reader) skipFrame() error {
+ relativeOffset := 0
+
+ if _, err := io.ReadFull(r.r, r.scratch[:4]); err != nil {
+ return r.wrapNonEOFError(relativeOffset, err)
+ }
+
+ relativeOffset += 4
+
+ size := binary.LittleEndian.Uint32(r.scratch[:4])
+
+ if seeker, ok := r.r.(io.Seeker); ok {
+ if _, err := seeker.Seek(int64(size), io.SeekCurrent); err != nil {
+ return err
+ }
+ r.blockOffset += int64(relativeOffset) + int64(size)
+ return nil
+ }
+
+ var skip []byte
+ const chunk = 1 << 20 // 1M
+ for size >= chunk {
+ if len(skip) == 0 {
+ skip = make([]byte, chunk)
+ }
+ if _, err := io.ReadFull(r.r, skip); err != nil {
+ return r.wrapNonEOFError(relativeOffset, err)
+ }
+ relativeOffset += chunk
+ size -= chunk
+ }
+ if size > 0 {
+ if len(skip) == 0 {
+ skip = make([]byte, size)
+ }
+ if _, err := io.ReadFull(r.r, skip); err != nil {
+ return r.wrapNonEOFError(relativeOffset, err)
+ }
+ relativeOffset += int(size)
+ }
+
+ r.blockOffset += int64(relativeOffset)
+
+ return nil
+}
+
+// readBlock reads the next block from a frame.
+func (r *Reader) readBlock() error {
+ relativeOffset := 0
+
+ // Read Block_Header. RFC 3.1.1.2.
+ if _, err := io.ReadFull(r.r, r.scratch[:3]); err != nil {
+ return r.wrapNonEOFError(relativeOffset, err)
+ }
+
+ relativeOffset += 3
+
+ header := uint32(r.scratch[0]) | (uint32(r.scratch[1]) << 8) | (uint32(r.scratch[2]) << 16)
+
+ lastBlock := header&1 != 0
+ blockType := (header >> 1) & 3
+ blockSize := int(header >> 3)
+
+ // Maximum block size is smaller of window size and 128K.
+ // We don't record the window size for a single segment frame,
+ // so just use 128K. RFC 3.1.1.2.3, 3.1.1.2.4.
+ if blockSize > 128<<10 || (r.windowSize > 0 && blockSize > r.windowSize) {
+ return r.makeError(relativeOffset, "block size too large")
+ }
+
+ // Handle different block types. RFC 3.1.1.2.2.
+ switch blockType {
+ case 0:
+ r.setBufferSize(blockSize)
+ if _, err := io.ReadFull(r.r, r.buffer); err != nil {
+ return r.wrapNonEOFError(relativeOffset, err)
+ }
+ relativeOffset += blockSize
+ r.blockOffset += int64(relativeOffset)
+ case 1:
+ r.setBufferSize(blockSize)
+ if _, err := io.ReadFull(r.r, r.scratch[:1]); err != nil {
+ return r.wrapNonEOFError(relativeOffset, err)
+ }
+ relativeOffset++
+ v := r.scratch[0]
+ for i := range r.buffer {
+ r.buffer[i] = v
+ }
+ r.blockOffset += int64(relativeOffset)
+ case 2:
+ r.blockOffset += int64(relativeOffset)
+ if err := r.compressedBlock(blockSize); err != nil {
+ return err
+ }
+ r.blockOffset += int64(blockSize)
+ case 3:
+ return r.makeError(relativeOffset, "invalid block type")
+ }
+
+ if !r.frameSizeUnknown {
+ if uint64(len(r.buffer)) > r.remainingFrameSize {
+ return r.makeError(relativeOffset, "too many uncompressed bytes in frame")
+ }
+ r.remainingFrameSize -= uint64(len(r.buffer))
+ }
+
+ if r.hasChecksum {
+ r.checksum.update(r.buffer)
+ }
+
+ if !lastBlock {
+ r.saveWindow(r.buffer)
+ } else {
+ if !r.frameSizeUnknown && r.remainingFrameSize != 0 {
+ return r.makeError(relativeOffset, "not enough uncompressed bytes for frame")
+ }
+ // Check for checksum at end of frame. RFC 3.1.1.
+ if r.hasChecksum {
+ if _, err := io.ReadFull(r.r, r.scratch[:4]); err != nil {
+ return r.wrapNonEOFError(0, err)
+ }
+
+ inputChecksum := binary.LittleEndian.Uint32(r.scratch[:4])
+ dataChecksum := uint32(r.checksum.digest())
+ if inputChecksum != dataChecksum {
+ return r.wrapError(0, fmt.Errorf("invalid checksum: got %#x want %#x", dataChecksum, inputChecksum))
+ }
+
+ r.blockOffset += 4
+ }
+ r.sawFrameHeader = false
+ }
+
+ return nil
+}
+
+// setBufferSize sets the decompressed buffer size.
+// When this is called the buffer is empty.
+func (r *Reader) setBufferSize(size int) {
+ if cap(r.buffer) < size {
+ need := size - cap(r.buffer)
+ r.buffer = append(r.buffer[:cap(r.buffer)], make([]byte, need)...)
+ }
+ r.buffer = r.buffer[:size]
+}
+
+// saveWindow saves bytes in the backreference window.
+// TODO: use a circular buffer for less data movement.
+func (r *Reader) saveWindow(buf []byte) {
+ if r.windowSize == 0 {
+ return
+ }
+
+ if len(buf) >= r.windowSize {
+ from := len(buf) - r.windowSize
+ r.window = append(r.window[:0], buf[from:]...)
+ return
+ }
+
+ keep := r.windowSize - len(buf) // must be positive
+ if keep < len(r.window) {
+ remove := len(r.window) - keep
+ copy(r.window[:], r.window[remove:])
+ }
+
+ r.window = append(r.window, buf...)
+}
+
+// zstdError is an error while decompressing.
+type zstdError struct {
+ offset int64
+ err error
+}
+
+func (ze *zstdError) Error() string {
+ return fmt.Sprintf("zstd decompression error at %d: %v", ze.offset, ze.err)
+}
+
+func (ze *zstdError) Unwrap() error {
+ return ze.err
+}
+
+func (r *Reader) makeEOFError(off int) error {
+ return r.wrapError(off, io.ErrUnexpectedEOF)
+}
+
+func (r *Reader) wrapNonEOFError(off int, err error) error {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return r.wrapError(off, err)
+}
+
+func (r *Reader) makeError(off int, msg string) error {
+ return r.wrapError(off, errors.New(msg))
+}
+
+func (r *Reader) wrapError(off int, err error) error {
+ if err == io.EOF {
+ return err
+ }
+ return &zstdError{r.blockOffset + int64(off), err}
+}
diff --git a/contrib/go/_std_1.21/src/io/fs/format.go b/contrib/go/_std_1.21/src/io/fs/format.go
new file mode 100644
index 0000000000..f490341f6c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/io/fs/format.go
@@ -0,0 +1,76 @@
+// Copyright 2023 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 fs
+
+import (
+ "time"
+)
+
+// FormatFileInfo returns a formatted version of info for human readability.
+// Implementations of FileInfo can call this from a String method.
+// The output for a file named "hello.go", 100 bytes, mode 0o644, created
+// January 1, 1970 at noon is
+//
+// -rw-r--r-- 100 1970-01-01 12:00:00 hello.go
+func FormatFileInfo(info FileInfo) string {
+ name := info.Name()
+ b := make([]byte, 0, 40+len(name))
+ b = append(b, info.Mode().String()...)
+ b = append(b, ' ')
+
+ size := info.Size()
+ var usize uint64
+ if size >= 0 {
+ usize = uint64(size)
+ } else {
+ b = append(b, '-')
+ usize = uint64(-size)
+ }
+ var buf [20]byte
+ i := len(buf) - 1
+ for usize >= 10 {
+ q := usize / 10
+ buf[i] = byte('0' + usize - q*10)
+ i--
+ usize = q
+ }
+ buf[i] = byte('0' + usize)
+ b = append(b, buf[i:]...)
+ b = append(b, ' ')
+
+ b = append(b, info.ModTime().Format(time.DateTime)...)
+ b = append(b, ' ')
+
+ b = append(b, name...)
+ if info.IsDir() {
+ b = append(b, '/')
+ }
+
+ return string(b)
+}
+
+// FormatDirEntry returns a formatted version of dir for human readability.
+// Implementations of DirEntry can call this from a String method.
+// The outputs for a directory named subdir and a file named hello.go are:
+//
+// d subdir/
+// - hello.go
+func FormatDirEntry(dir DirEntry) string {
+ name := dir.Name()
+ b := make([]byte, 0, 5+len(name))
+
+ // The Type method does not return any permission bits,
+ // so strip them from the string.
+ mode := dir.Type().String()
+ mode = mode[:len(mode)-9]
+
+ b = append(b, mode...)
+ b = append(b, ' ')
+ b = append(b, name...)
+ if dir.IsDir() {
+ b = append(b, '/')
+ }
+ return string(b)
+}
diff --git a/contrib/go/_std_1.20/src/io/fs/fs.go b/contrib/go/_std_1.21/src/io/fs/fs.go
index 4ce4d1a528..4ce4d1a528 100644
--- a/contrib/go/_std_1.20/src/io/fs/fs.go
+++ b/contrib/go/_std_1.21/src/io/fs/fs.go
diff --git a/contrib/go/_std_1.20/src/io/fs/glob.go b/contrib/go/_std_1.21/src/io/fs/glob.go
index 0e529cd05d..0e529cd05d 100644
--- a/contrib/go/_std_1.20/src/io/fs/glob.go
+++ b/contrib/go/_std_1.21/src/io/fs/glob.go
diff --git a/contrib/go/_std_1.21/src/io/fs/readdir.go b/contrib/go/_std_1.21/src/io/fs/readdir.go
new file mode 100644
index 0000000000..42aca49516
--- /dev/null
+++ b/contrib/go/_std_1.21/src/io/fs/readdir.go
@@ -0,0 +1,81 @@
+// 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 fs
+
+import (
+ "errors"
+ "sort"
+)
+
+// ReadDirFS is the interface implemented by a file system
+// that provides an optimized implementation of ReadDir.
+type ReadDirFS interface {
+ FS
+
+ // ReadDir reads the named directory
+ // and returns a list of directory entries sorted by filename.
+ ReadDir(name string) ([]DirEntry, error)
+}
+
+// ReadDir reads the named directory
+// and returns a list of directory entries sorted by filename.
+//
+// If fs implements ReadDirFS, ReadDir calls fs.ReadDir.
+// Otherwise ReadDir calls fs.Open and uses ReadDir and Close
+// on the returned file.
+func ReadDir(fsys FS, name string) ([]DirEntry, error) {
+ if fsys, ok := fsys.(ReadDirFS); ok {
+ return fsys.ReadDir(name)
+ }
+
+ file, err := fsys.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ defer file.Close()
+
+ dir, ok := file.(ReadDirFile)
+ if !ok {
+ return nil, &PathError{Op: "readdir", Path: name, Err: errors.New("not implemented")}
+ }
+
+ list, err := dir.ReadDir(-1)
+ sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
+ return list, err
+}
+
+// dirInfo is a DirEntry based on a FileInfo.
+type dirInfo struct {
+ fileInfo FileInfo
+}
+
+func (di dirInfo) IsDir() bool {
+ return di.fileInfo.IsDir()
+}
+
+func (di dirInfo) Type() FileMode {
+ return di.fileInfo.Mode().Type()
+}
+
+func (di dirInfo) Info() (FileInfo, error) {
+ return di.fileInfo, nil
+}
+
+func (di dirInfo) Name() string {
+ return di.fileInfo.Name()
+}
+
+func (di dirInfo) String() string {
+ return FormatDirEntry(di)
+}
+
+// FileInfoToDirEntry returns a DirEntry that returns information from info.
+// If info is nil, FileInfoToDirEntry returns nil.
+func FileInfoToDirEntry(info FileInfo) DirEntry {
+ if info == nil {
+ return nil
+ }
+ return dirInfo{fileInfo: info}
+}
diff --git a/contrib/go/_std_1.20/src/io/fs/readfile.go b/contrib/go/_std_1.21/src/io/fs/readfile.go
index d3c181c0a9..d3c181c0a9 100644
--- a/contrib/go/_std_1.20/src/io/fs/readfile.go
+++ b/contrib/go/_std_1.21/src/io/fs/readfile.go
diff --git a/contrib/go/_std_1.20/src/io/fs/stat.go b/contrib/go/_std_1.21/src/io/fs/stat.go
index 735a6e3281..735a6e3281 100644
--- a/contrib/go/_std_1.20/src/io/fs/stat.go
+++ b/contrib/go/_std_1.21/src/io/fs/stat.go
diff --git a/contrib/go/_std_1.20/src/io/fs/sub.go b/contrib/go/_std_1.21/src/io/fs/sub.go
index ae20e030a9..ae20e030a9 100644
--- a/contrib/go/_std_1.20/src/io/fs/sub.go
+++ b/contrib/go/_std_1.21/src/io/fs/sub.go
diff --git a/contrib/go/_std_1.21/src/io/fs/walk.go b/contrib/go/_std_1.21/src/io/fs/walk.go
new file mode 100644
index 0000000000..baf559ebca
--- /dev/null
+++ b/contrib/go/_std_1.21/src/io/fs/walk.go
@@ -0,0 +1,141 @@
+// 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 fs
+
+import (
+ "errors"
+ "path"
+)
+
+// SkipDir is used as a return value from WalkDirFuncs to indicate that
+// the directory named in the call is to be skipped. It is not returned
+// as an error by any function.
+var SkipDir = errors.New("skip this directory")
+
+// SkipAll is used as a return value from WalkDirFuncs to indicate that
+// all remaining files and directories are to be skipped. It is not returned
+// as an error by any function.
+var SkipAll = errors.New("skip everything and stop the walk")
+
+// WalkDirFunc is the type of the function called by WalkDir to visit
+// each file or directory.
+//
+// The path argument contains the argument to WalkDir as a prefix.
+// That is, if WalkDir is called with root argument "dir" and finds a file
+// named "a" in that directory, the walk function will be called with
+// argument "dir/a".
+//
+// The d argument is the fs.DirEntry for the named path.
+//
+// The error result returned by the function controls how WalkDir
+// continues. If the function returns the special value SkipDir, WalkDir
+// skips the current directory (path if d.IsDir() is true, otherwise
+// path's parent directory). If the function returns the special value
+// SkipAll, WalkDir skips all remaining files and directories. Otherwise,
+// if the function returns a non-nil error, WalkDir stops entirely and
+// returns that error.
+//
+// The err argument reports an error related to path, signaling that
+// WalkDir will not walk into that directory. The function can decide how
+// to handle that error; as described earlier, returning the error will
+// cause WalkDir to stop walking the entire tree.
+//
+// WalkDir calls the function with a non-nil err argument in two cases.
+//
+// First, if the initial fs.Stat on the root directory fails, WalkDir
+// calls the function with path set to root, d set to nil, and err set to
+// the error from fs.Stat.
+//
+// Second, if a directory's ReadDir method fails, WalkDir calls the
+// function with path set to the directory's path, d set to an
+// fs.DirEntry describing the directory, and err set to the error from
+// ReadDir. In this second case, the function is called twice with the
+// path of the directory: the first call is before the directory read is
+// attempted and has err set to nil, giving the function a chance to
+// return SkipDir or SkipAll and avoid the ReadDir entirely. The second call
+// is after a failed ReadDir and reports the error from ReadDir.
+// (If ReadDir succeeds, there is no second call.)
+//
+// The differences between WalkDirFunc compared to filepath.WalkFunc are:
+//
+// - The second argument has type fs.DirEntry instead of fs.FileInfo.
+// - The function is called before reading a directory, to allow SkipDir
+// or SkipAll to bypass the directory read entirely or skip all remaining
+// files and directories respectively.
+// - If a directory read fails, the function is called a second time
+// for that directory to report the error.
+type WalkDirFunc func(path string, d DirEntry, err error) error
+
+// walkDir recursively descends path, calling walkDirFn.
+func walkDir(fsys FS, name string, d DirEntry, walkDirFn WalkDirFunc) error {
+ if err := walkDirFn(name, d, nil); err != nil || !d.IsDir() {
+ if err == SkipDir && d.IsDir() {
+ // Successfully skipped directory.
+ err = nil
+ }
+ return err
+ }
+
+ dirs, err := ReadDir(fsys, name)
+ if err != nil {
+ // Second call, to report ReadDir error.
+ err = walkDirFn(name, d, err)
+ if err != nil {
+ if err == SkipDir && d.IsDir() {
+ err = nil
+ }
+ return err
+ }
+ }
+
+ for _, d1 := range dirs {
+ name1 := path.Join(name, d1.Name())
+ if err := walkDir(fsys, name1, d1, walkDirFn); err != nil {
+ if err == SkipDir {
+ break
+ }
+ return err
+ }
+ }
+ return nil
+}
+
+// WalkDir walks the file tree rooted at root, calling fn for each file or
+// directory in the tree, including root.
+//
+// All errors that arise visiting files and directories are filtered by fn:
+// see the fs.WalkDirFunc documentation for details.
+//
+// The files are walked in lexical order, which makes the output deterministic
+// but requires WalkDir to read an entire directory into memory before proceeding
+// to walk that directory.
+//
+// WalkDir does not follow symbolic links found in directories,
+// but if root itself is a symbolic link, its target will be walked.
+func WalkDir(fsys FS, root string, fn WalkDirFunc) error {
+ info, err := Stat(fsys, root)
+ if err != nil {
+ err = fn(root, nil, err)
+ } else {
+ err = walkDir(fsys, root, &statDirEntry{info}, fn)
+ }
+ if err == SkipDir || err == SkipAll {
+ return nil
+ }
+ return err
+}
+
+type statDirEntry struct {
+ info FileInfo
+}
+
+func (d *statDirEntry) Name() string { return d.info.Name() }
+func (d *statDirEntry) IsDir() bool { return d.info.IsDir() }
+func (d *statDirEntry) Type() FileMode { return d.info.Mode().Type() }
+func (d *statDirEntry) Info() (FileInfo, error) { return d.info, nil }
+
+func (d *statDirEntry) String() string {
+ return FormatDirEntry(d)
+}
diff --git a/contrib/go/_std_1.21/src/io/fs/ya.make b/contrib/go/_std_1.21/src/io/fs/ya.make
new file mode 100644
index 0000000000..c675fefcd4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/io/fs/ya.make
@@ -0,0 +1,29 @@
+GO_LIBRARY()
+
+SRCS(
+ format.go
+ fs.go
+ glob.go
+ readdir.go
+ readfile.go
+ stat.go
+ sub.go
+ walk.go
+)
+
+GO_XTEST_SRCS(
+ example_test.go
+ format_test.go
+ fs_test.go
+ glob_test.go
+ readdir_test.go
+ readfile_test.go
+ stat_test.go
+ sub_test.go
+ walk_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/io/io.go b/contrib/go/_std_1.21/src/io/io.go
new file mode 100644
index 0000000000..01f36e0ce1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/io/io.go
@@ -0,0 +1,718 @@
+// Copyright 2009 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 io provides basic interfaces to I/O primitives.
+// Its primary job is to wrap existing implementations of such primitives,
+// such as those in package os, into shared public interfaces that
+// abstract the functionality, plus some other related primitives.
+//
+// Because these interfaces and primitives wrap lower-level operations with
+// various implementations, unless otherwise informed clients should not
+// assume they are safe for parallel execution.
+package io
+
+import (
+ "errors"
+ "sync"
+)
+
+// Seek whence values.
+const (
+ SeekStart = 0 // seek relative to the origin of the file
+ SeekCurrent = 1 // seek relative to the current offset
+ SeekEnd = 2 // seek relative to the end
+)
+
+// ErrShortWrite means that a write accepted fewer bytes than requested
+// but failed to return an explicit error.
+var ErrShortWrite = errors.New("short write")
+
+// errInvalidWrite means that a write returned an impossible count.
+var errInvalidWrite = errors.New("invalid write result")
+
+// ErrShortBuffer means that a read required a longer buffer than was provided.
+var ErrShortBuffer = errors.New("short buffer")
+
+// EOF is the error returned by Read when no more input is available.
+// (Read must return EOF itself, not an error wrapping EOF,
+// because callers will test for EOF using ==.)
+// Functions should return EOF only to signal a graceful end of input.
+// If the EOF occurs unexpectedly in a structured data stream,
+// the appropriate error is either ErrUnexpectedEOF or some other error
+// giving more detail.
+var EOF = errors.New("EOF")
+
+// ErrUnexpectedEOF means that EOF was encountered in the
+// middle of reading a fixed-size block or data structure.
+var ErrUnexpectedEOF = errors.New("unexpected EOF")
+
+// ErrNoProgress is returned by some clients of a Reader when
+// many calls to Read have failed to return any data or error,
+// usually the sign of a broken Reader implementation.
+var ErrNoProgress = errors.New("multiple Read calls return no data or error")
+
+// Reader is the interface that wraps the basic Read method.
+//
+// Read reads up to len(p) bytes into p. It returns the number of bytes
+// read (0 <= n <= len(p)) and any error encountered. Even if Read
+// returns n < len(p), it may use all of p as scratch space during the call.
+// If some data is available but not len(p) bytes, Read conventionally
+// returns what is available instead of waiting for more.
+//
+// When Read encounters an error or end-of-file condition after
+// successfully reading n > 0 bytes, it returns the number of
+// bytes read. It may return the (non-nil) error from the same call
+// or return the error (and n == 0) from a subsequent call.
+// An instance of this general case is that a Reader returning
+// a non-zero number of bytes at the end of the input stream may
+// return either err == EOF or err == nil. The next Read should
+// return 0, EOF.
+//
+// Callers should always process the n > 0 bytes returned before
+// considering the error err. Doing so correctly handles I/O errors
+// that happen after reading some bytes and also both of the
+// allowed EOF behaviors.
+//
+// If len(p) == 0, Read should always return n == 0. It may return a
+// non-nil error if some error condition is known, such as EOF.
+//
+// Implementations of Read are discouraged from returning a
+// zero byte count with a nil error, except when len(p) == 0.
+// Callers should treat a return of 0 and nil as indicating that
+// nothing happened; in particular it does not indicate EOF.
+//
+// Implementations must not retain p.
+type Reader interface {
+ Read(p []byte) (n int, err error)
+}
+
+// Writer is the interface that wraps the basic Write method.
+//
+// Write writes len(p) bytes from p to the underlying data stream.
+// It returns the number of bytes written from p (0 <= n <= len(p))
+// and any error encountered that caused the write to stop early.
+// Write must return a non-nil error if it returns n < len(p).
+// Write must not modify the slice data, even temporarily.
+//
+// Implementations must not retain p.
+type Writer interface {
+ Write(p []byte) (n int, err error)
+}
+
+// Closer is the interface that wraps the basic Close method.
+//
+// The behavior of Close after the first call is undefined.
+// Specific implementations may document their own behavior.
+type Closer interface {
+ Close() error
+}
+
+// Seeker is the interface that wraps the basic Seek method.
+//
+// Seek sets the offset for the next Read or Write to offset,
+// interpreted according to whence:
+// SeekStart means relative to the start of the file,
+// SeekCurrent means relative to the current offset, and
+// SeekEnd means relative to the end
+// (for example, offset = -2 specifies the penultimate byte of the file).
+// Seek returns the new offset relative to the start of the
+// file or an error, if any.
+//
+// Seeking to an offset before the start of the file is an error.
+// Seeking to any positive offset may be allowed, but if the new offset exceeds
+// the size of the underlying object the behavior of subsequent I/O operations
+// is implementation-dependent.
+type Seeker interface {
+ Seek(offset int64, whence int) (int64, error)
+}
+
+// ReadWriter is the interface that groups the basic Read and Write methods.
+type ReadWriter interface {
+ Reader
+ Writer
+}
+
+// ReadCloser is the interface that groups the basic Read and Close methods.
+type ReadCloser interface {
+ Reader
+ Closer
+}
+
+// WriteCloser is the interface that groups the basic Write and Close methods.
+type WriteCloser interface {
+ Writer
+ Closer
+}
+
+// ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.
+type ReadWriteCloser interface {
+ Reader
+ Writer
+ Closer
+}
+
+// ReadSeeker is the interface that groups the basic Read and Seek methods.
+type ReadSeeker interface {
+ Reader
+ Seeker
+}
+
+// ReadSeekCloser is the interface that groups the basic Read, Seek and Close
+// methods.
+type ReadSeekCloser interface {
+ Reader
+ Seeker
+ Closer
+}
+
+// WriteSeeker is the interface that groups the basic Write and Seek methods.
+type WriteSeeker interface {
+ Writer
+ Seeker
+}
+
+// ReadWriteSeeker is the interface that groups the basic Read, Write and Seek methods.
+type ReadWriteSeeker interface {
+ Reader
+ Writer
+ Seeker
+}
+
+// ReaderFrom is the interface that wraps the ReadFrom method.
+//
+// ReadFrom reads data from r until EOF or error.
+// The return value n is the number of bytes read.
+// Any error except EOF encountered during the read is also returned.
+//
+// The Copy function uses ReaderFrom if available.
+type ReaderFrom interface {
+ ReadFrom(r Reader) (n int64, err error)
+}
+
+// WriterTo is the interface that wraps the WriteTo method.
+//
+// WriteTo writes data to w until there's no more data to write or
+// when an error occurs. The return value n is the number of bytes
+// written. Any error encountered during the write is also returned.
+//
+// The Copy function uses WriterTo if available.
+type WriterTo interface {
+ WriteTo(w Writer) (n int64, err error)
+}
+
+// ReaderAt is the interface that wraps the basic ReadAt method.
+//
+// ReadAt reads len(p) bytes into p starting at offset off in the
+// underlying input source. It returns the number of bytes
+// read (0 <= n <= len(p)) and any error encountered.
+//
+// When ReadAt returns n < len(p), it returns a non-nil error
+// explaining why more bytes were not returned. In this respect,
+// ReadAt is stricter than Read.
+//
+// Even if ReadAt returns n < len(p), it may use all of p as scratch
+// space during the call. If some data is available but not len(p) bytes,
+// ReadAt blocks until either all the data is available or an error occurs.
+// In this respect ReadAt is different from Read.
+//
+// If the n = len(p) bytes returned by ReadAt are at the end of the
+// input source, ReadAt may return either err == EOF or err == nil.
+//
+// If ReadAt is reading from an input source with a seek offset,
+// ReadAt should not affect nor be affected by the underlying
+// seek offset.
+//
+// Clients of ReadAt can execute parallel ReadAt calls on the
+// same input source.
+//
+// Implementations must not retain p.
+type ReaderAt interface {
+ ReadAt(p []byte, off int64) (n int, err error)
+}
+
+// WriterAt is the interface that wraps the basic WriteAt method.
+//
+// WriteAt writes len(p) bytes from p to the underlying data stream
+// at offset off. It returns the number of bytes written from p (0 <= n <= len(p))
+// and any error encountered that caused the write to stop early.
+// WriteAt must return a non-nil error if it returns n < len(p).
+//
+// If WriteAt is writing to a destination with a seek offset,
+// WriteAt should not affect nor be affected by the underlying
+// seek offset.
+//
+// Clients of WriteAt can execute parallel WriteAt calls on the same
+// destination if the ranges do not overlap.
+//
+// Implementations must not retain p.
+type WriterAt interface {
+ WriteAt(p []byte, off int64) (n int, err error)
+}
+
+// ByteReader is the interface that wraps the ReadByte method.
+//
+// ReadByte reads and returns the next byte from the input or
+// any error encountered. If ReadByte returns an error, no input
+// byte was consumed, and the returned byte value is undefined.
+//
+// ReadByte provides an efficient interface for byte-at-time
+// processing. A Reader that does not implement ByteReader
+// can be wrapped using bufio.NewReader to add this method.
+type ByteReader interface {
+ ReadByte() (byte, error)
+}
+
+// ByteScanner is the interface that adds the UnreadByte method to the
+// basic ReadByte method.
+//
+// UnreadByte causes the next call to ReadByte to return the last byte read.
+// If the last operation was not a successful call to ReadByte, UnreadByte may
+// return an error, unread the last byte read (or the byte prior to the
+// last-unread byte), or (in implementations that support the Seeker interface)
+// seek to one byte before the current offset.
+type ByteScanner interface {
+ ByteReader
+ UnreadByte() error
+}
+
+// ByteWriter is the interface that wraps the WriteByte method.
+type ByteWriter interface {
+ WriteByte(c byte) error
+}
+
+// RuneReader is the interface that wraps the ReadRune method.
+//
+// ReadRune reads a single encoded Unicode character
+// and returns the rune and its size in bytes. If no character is
+// available, err will be set.
+type RuneReader interface {
+ ReadRune() (r rune, size int, err error)
+}
+
+// RuneScanner is the interface that adds the UnreadRune method to the
+// basic ReadRune method.
+//
+// UnreadRune causes the next call to ReadRune to return the last rune read.
+// If the last operation was not a successful call to ReadRune, UnreadRune may
+// return an error, unread the last rune read (or the rune prior to the
+// last-unread rune), or (in implementations that support the Seeker interface)
+// seek to the start of the rune before the current offset.
+type RuneScanner interface {
+ RuneReader
+ UnreadRune() error
+}
+
+// StringWriter is the interface that wraps the WriteString method.
+type StringWriter interface {
+ WriteString(s string) (n int, err error)
+}
+
+// WriteString writes the contents of the string s to w, which accepts a slice of bytes.
+// If w implements StringWriter, its WriteString method is invoked directly.
+// Otherwise, w.Write is called exactly once.
+func WriteString(w Writer, s string) (n int, err error) {
+ if sw, ok := w.(StringWriter); ok {
+ return sw.WriteString(s)
+ }
+ return w.Write([]byte(s))
+}
+
+// ReadAtLeast reads from r into buf until it has read at least min bytes.
+// It returns the number of bytes copied and an error if fewer bytes were read.
+// The error is EOF only if no bytes were read.
+// If an EOF happens after reading fewer than min bytes,
+// ReadAtLeast returns ErrUnexpectedEOF.
+// If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer.
+// On return, n >= min if and only if err == nil.
+// If r returns an error having read at least min bytes, the error is dropped.
+func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) {
+ if len(buf) < min {
+ return 0, ErrShortBuffer
+ }
+ for n < min && err == nil {
+ var nn int
+ nn, err = r.Read(buf[n:])
+ n += nn
+ }
+ if n >= min {
+ err = nil
+ } else if n > 0 && err == EOF {
+ err = ErrUnexpectedEOF
+ }
+ return
+}
+
+// ReadFull reads exactly len(buf) bytes from r into buf.
+// It returns the number of bytes copied and an error if fewer bytes were read.
+// The error is EOF only if no bytes were read.
+// If an EOF happens after reading some but not all the bytes,
+// ReadFull returns ErrUnexpectedEOF.
+// On return, n == len(buf) if and only if err == nil.
+// If r returns an error having read at least len(buf) bytes, the error is dropped.
+func ReadFull(r Reader, buf []byte) (n int, err error) {
+ return ReadAtLeast(r, buf, len(buf))
+}
+
+// CopyN copies n bytes (or until an error) from src to dst.
+// It returns the number of bytes copied and the earliest
+// error encountered while copying.
+// On return, written == n if and only if err == nil.
+//
+// If dst implements the ReaderFrom interface,
+// the copy is implemented using it.
+func CopyN(dst Writer, src Reader, n int64) (written int64, err error) {
+ written, err = Copy(dst, LimitReader(src, n))
+ if written == n {
+ return n, nil
+ }
+ if written < n && err == nil {
+ // src stopped early; must have been EOF.
+ err = EOF
+ }
+ return
+}
+
+// Copy copies from src to dst until either EOF is reached
+// on src or an error occurs. It returns the number of bytes
+// copied and the first error encountered while copying, if any.
+//
+// A successful Copy returns err == nil, not err == EOF.
+// Because Copy is defined to read from src until EOF, it does
+// not treat an EOF from Read as an error to be reported.
+//
+// If src implements the WriterTo interface,
+// the copy is implemented by calling src.WriteTo(dst).
+// Otherwise, if dst implements the ReaderFrom interface,
+// the copy is implemented by calling dst.ReadFrom(src).
+func Copy(dst Writer, src Reader) (written int64, err error) {
+ return copyBuffer(dst, src, nil)
+}
+
+// CopyBuffer is identical to Copy except that it stages through the
+// provided buffer (if one is required) rather than allocating a
+// temporary one. If buf is nil, one is allocated; otherwise if it has
+// zero length, CopyBuffer panics.
+//
+// If either src implements WriterTo or dst implements ReaderFrom,
+// buf will not be used to perform the copy.
+func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
+ if buf != nil && len(buf) == 0 {
+ panic("empty buffer in CopyBuffer")
+ }
+ return copyBuffer(dst, src, buf)
+}
+
+// copyBuffer is the actual implementation of Copy and CopyBuffer.
+// if buf is nil, one is allocated.
+func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
+ // If the reader has a WriteTo method, use it to do the copy.
+ // Avoids an allocation and a copy.
+ if wt, ok := src.(WriterTo); ok {
+ return wt.WriteTo(dst)
+ }
+ // Similarly, if the writer has a ReadFrom method, use it to do the copy.
+ if rt, ok := dst.(ReaderFrom); ok {
+ return rt.ReadFrom(src)
+ }
+ if buf == nil {
+ size := 32 * 1024
+ if l, ok := src.(*LimitedReader); ok && int64(size) > l.N {
+ if l.N < 1 {
+ size = 1
+ } else {
+ size = int(l.N)
+ }
+ }
+ buf = make([]byte, size)
+ }
+ for {
+ nr, er := src.Read(buf)
+ if nr > 0 {
+ nw, ew := dst.Write(buf[0:nr])
+ if nw < 0 || nr < nw {
+ nw = 0
+ if ew == nil {
+ ew = errInvalidWrite
+ }
+ }
+ written += int64(nw)
+ if ew != nil {
+ err = ew
+ break
+ }
+ if nr != nw {
+ err = ErrShortWrite
+ break
+ }
+ }
+ if er != nil {
+ if er != EOF {
+ err = er
+ }
+ break
+ }
+ }
+ return written, err
+}
+
+// LimitReader returns a Reader that reads from r
+// but stops with EOF after n bytes.
+// The underlying implementation is a *LimitedReader.
+func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} }
+
+// A LimitedReader reads from R but limits the amount of
+// data returned to just N bytes. Each call to Read
+// updates N to reflect the new amount remaining.
+// Read returns EOF when N <= 0 or when the underlying R returns EOF.
+type LimitedReader struct {
+ R Reader // underlying reader
+ N int64 // max bytes remaining
+}
+
+func (l *LimitedReader) Read(p []byte) (n int, err error) {
+ if l.N <= 0 {
+ return 0, EOF
+ }
+ if int64(len(p)) > l.N {
+ p = p[0:l.N]
+ }
+ n, err = l.R.Read(p)
+ l.N -= int64(n)
+ return
+}
+
+// NewSectionReader returns a SectionReader that reads from r
+// starting at offset off and stops with EOF after n bytes.
+func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader {
+ var remaining int64
+ const maxint64 = 1<<63 - 1
+ if off <= maxint64-n {
+ remaining = n + off
+ } else {
+ // Overflow, with no way to return error.
+ // Assume we can read up to an offset of 1<<63 - 1.
+ remaining = maxint64
+ }
+ return &SectionReader{r, off, off, remaining}
+}
+
+// SectionReader implements Read, Seek, and ReadAt on a section
+// of an underlying ReaderAt.
+type SectionReader struct {
+ r ReaderAt
+ base int64
+ off int64
+ limit int64
+}
+
+func (s *SectionReader) Read(p []byte) (n int, err error) {
+ if s.off >= s.limit {
+ return 0, EOF
+ }
+ if max := s.limit - s.off; int64(len(p)) > max {
+ p = p[0:max]
+ }
+ n, err = s.r.ReadAt(p, s.off)
+ s.off += int64(n)
+ return
+}
+
+var errWhence = errors.New("Seek: invalid whence")
+var errOffset = errors.New("Seek: invalid offset")
+
+func (s *SectionReader) Seek(offset int64, whence int) (int64, error) {
+ switch whence {
+ default:
+ return 0, errWhence
+ case SeekStart:
+ offset += s.base
+ case SeekCurrent:
+ offset += s.off
+ case SeekEnd:
+ offset += s.limit
+ }
+ if offset < s.base {
+ return 0, errOffset
+ }
+ s.off = offset
+ return offset - s.base, nil
+}
+
+func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error) {
+ if off < 0 || off >= s.limit-s.base {
+ return 0, EOF
+ }
+ off += s.base
+ if max := s.limit - off; int64(len(p)) > max {
+ p = p[0:max]
+ n, err = s.r.ReadAt(p, off)
+ if err == nil {
+ err = EOF
+ }
+ return n, err
+ }
+ return s.r.ReadAt(p, off)
+}
+
+// Size returns the size of the section in bytes.
+func (s *SectionReader) Size() int64 { return s.limit - s.base }
+
+// An OffsetWriter maps writes at offset base to offset base+off in the underlying writer.
+type OffsetWriter struct {
+ w WriterAt
+ base int64 // the original offset
+ off int64 // the current offset
+}
+
+// NewOffsetWriter returns an OffsetWriter that writes to w
+// starting at offset off.
+func NewOffsetWriter(w WriterAt, off int64) *OffsetWriter {
+ return &OffsetWriter{w, off, off}
+}
+
+func (o *OffsetWriter) Write(p []byte) (n int, err error) {
+ n, err = o.w.WriteAt(p, o.off)
+ o.off += int64(n)
+ return
+}
+
+func (o *OffsetWriter) WriteAt(p []byte, off int64) (n int, err error) {
+ if off < 0 {
+ return 0, errOffset
+ }
+
+ off += o.base
+ return o.w.WriteAt(p, off)
+}
+
+func (o *OffsetWriter) Seek(offset int64, whence int) (int64, error) {
+ switch whence {
+ default:
+ return 0, errWhence
+ case SeekStart:
+ offset += o.base
+ case SeekCurrent:
+ offset += o.off
+ }
+ if offset < o.base {
+ return 0, errOffset
+ }
+ o.off = offset
+ return offset - o.base, nil
+}
+
+// TeeReader returns a Reader that writes to w what it reads from r.
+// All reads from r performed through it are matched with
+// corresponding writes to w. There is no internal buffering -
+// the write must complete before the read completes.
+// Any error encountered while writing is reported as a read error.
+func TeeReader(r Reader, w Writer) Reader {
+ return &teeReader{r, w}
+}
+
+type teeReader struct {
+ r Reader
+ w Writer
+}
+
+func (t *teeReader) Read(p []byte) (n int, err error) {
+ n, err = t.r.Read(p)
+ if n > 0 {
+ if n, err := t.w.Write(p[:n]); err != nil {
+ return n, err
+ }
+ }
+ return
+}
+
+// Discard is a Writer on which all Write calls succeed
+// without doing anything.
+var Discard Writer = discard{}
+
+type discard struct{}
+
+// discard implements ReaderFrom as an optimization so Copy to
+// io.Discard can avoid doing unnecessary work.
+var _ ReaderFrom = discard{}
+
+func (discard) Write(p []byte) (int, error) {
+ return len(p), nil
+}
+
+func (discard) WriteString(s string) (int, error) {
+ return len(s), nil
+}
+
+var blackHolePool = sync.Pool{
+ New: func() any {
+ b := make([]byte, 8192)
+ return &b
+ },
+}
+
+func (discard) ReadFrom(r Reader) (n int64, err error) {
+ bufp := blackHolePool.Get().(*[]byte)
+ readSize := 0
+ for {
+ readSize, err = r.Read(*bufp)
+ n += int64(readSize)
+ if err != nil {
+ blackHolePool.Put(bufp)
+ if err == EOF {
+ return n, nil
+ }
+ return
+ }
+ }
+}
+
+// NopCloser returns a ReadCloser with a no-op Close method wrapping
+// the provided Reader r.
+// If r implements WriterTo, the returned ReadCloser will implement WriterTo
+// by forwarding calls to r.
+func NopCloser(r Reader) ReadCloser {
+ if _, ok := r.(WriterTo); ok {
+ return nopCloserWriterTo{r}
+ }
+ return nopCloser{r}
+}
+
+type nopCloser struct {
+ Reader
+}
+
+func (nopCloser) Close() error { return nil }
+
+type nopCloserWriterTo struct {
+ Reader
+}
+
+func (nopCloserWriterTo) Close() error { return nil }
+
+func (c nopCloserWriterTo) WriteTo(w Writer) (n int64, err error) {
+ return c.Reader.(WriterTo).WriteTo(w)
+}
+
+// ReadAll reads from r until an error or EOF and returns the data it read.
+// A successful call returns err == nil, not err == EOF. Because ReadAll is
+// defined to read from src until EOF, it does not treat an EOF from Read
+// as an error to be reported.
+func ReadAll(r Reader) ([]byte, error) {
+ b := make([]byte, 0, 512)
+ for {
+ n, err := r.Read(b[len(b):cap(b)])
+ b = b[:len(b)+n]
+ if err != nil {
+ if err == EOF {
+ err = nil
+ }
+ return b, err
+ }
+
+ if len(b) == cap(b) {
+ // Add more capacity (let append pick how much).
+ b = append(b, 0)[:len(b)]
+ }
+ }
+}
diff --git a/contrib/go/_std_1.21/src/io/ioutil/ioutil.go b/contrib/go/_std_1.21/src/io/ioutil/ioutil.go
new file mode 100644
index 0000000000..67768e54cf
--- /dev/null
+++ b/contrib/go/_std_1.21/src/io/ioutil/ioutil.go
@@ -0,0 +1,95 @@
+// Copyright 2009 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 ioutil implements some I/O utility functions.
+//
+// Deprecated: As of Go 1.16, the same functionality is now provided
+// by package [io] or package [os], and those implementations
+// should be preferred in new code.
+// See the specific function documentation for details.
+package ioutil
+
+import (
+ "io"
+ "io/fs"
+ "os"
+ "sort"
+)
+
+// ReadAll reads from r until an error or EOF and returns the data it read.
+// A successful call returns err == nil, not err == EOF. Because ReadAll is
+// defined to read from src until EOF, it does not treat an EOF from Read
+// as an error to be reported.
+//
+// Deprecated: As of Go 1.16, this function simply calls [io.ReadAll].
+func ReadAll(r io.Reader) ([]byte, error) {
+ return io.ReadAll(r)
+}
+
+// ReadFile reads the file named by filename and returns the contents.
+// A successful call returns err == nil, not err == EOF. Because ReadFile
+// reads the whole file, it does not treat an EOF from Read as an error
+// to be reported.
+//
+// Deprecated: As of Go 1.16, this function simply calls [os.ReadFile].
+func ReadFile(filename string) ([]byte, error) {
+ return os.ReadFile(filename)
+}
+
+// WriteFile writes data to a file named by filename.
+// If the file does not exist, WriteFile creates it with permissions perm
+// (before umask); otherwise WriteFile truncates it before writing, without changing permissions.
+//
+// Deprecated: As of Go 1.16, this function simply calls [os.WriteFile].
+func WriteFile(filename string, data []byte, perm fs.FileMode) error {
+ return os.WriteFile(filename, data, perm)
+}
+
+// ReadDir reads the directory named by dirname and returns
+// a list of fs.FileInfo for the directory's contents,
+// sorted by filename. If an error occurs reading the directory,
+// ReadDir returns no directory entries along with the error.
+//
+// Deprecated: As of Go 1.16, [os.ReadDir] is a more efficient and correct choice:
+// it returns a list of [fs.DirEntry] instead of [fs.FileInfo],
+// and it returns partial results in the case of an error
+// midway through reading a directory.
+//
+// If you must continue obtaining a list of [fs.FileInfo], you still can:
+//
+// entries, err := os.ReadDir(dirname)
+// if err != nil { ... }
+// infos := make([]fs.FileInfo, 0, len(entries))
+// for _, entry := range entries {
+// info, err := entry.Info()
+// if err != nil { ... }
+// infos = append(infos, info)
+// }
+func ReadDir(dirname string) ([]fs.FileInfo, error) {
+ f, err := os.Open(dirname)
+ if err != nil {
+ return nil, err
+ }
+ list, err := f.Readdir(-1)
+ f.Close()
+ if err != nil {
+ return nil, err
+ }
+ sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
+ return list, nil
+}
+
+// NopCloser returns a ReadCloser with a no-op Close method wrapping
+// the provided Reader r.
+//
+// Deprecated: As of Go 1.16, this function simply calls [io.NopCloser].
+func NopCloser(r io.Reader) io.ReadCloser {
+ return io.NopCloser(r)
+}
+
+// Discard is an io.Writer on which all Write calls succeed
+// without doing anything.
+//
+// Deprecated: As of Go 1.16, this value is simply [io.Discard].
+var Discard io.Writer = io.Discard
diff --git a/contrib/go/_std_1.21/src/io/ioutil/tempfile.go b/contrib/go/_std_1.21/src/io/ioutil/tempfile.go
new file mode 100644
index 0000000000..5360d96fd3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/io/ioutil/tempfile.go
@@ -0,0 +1,41 @@
+// Copyright 2010 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 ioutil
+
+import (
+ "os"
+)
+
+// TempFile creates a new temporary file in the directory dir,
+// opens the file for reading and writing, and returns the resulting *os.File.
+// The filename is generated by taking pattern and adding a random
+// string to the end. If pattern includes a "*", the random string
+// replaces the last "*".
+// If dir is the empty string, TempFile uses the default directory
+// for temporary files (see os.TempDir).
+// Multiple programs calling TempFile simultaneously
+// will not choose the same file. The caller can use f.Name()
+// to find the pathname of the file. It is the caller's responsibility
+// to remove the file when no longer needed.
+//
+// Deprecated: As of Go 1.17, this function simply calls [os.CreateTemp].
+func TempFile(dir, pattern string) (f *os.File, err error) {
+ return os.CreateTemp(dir, pattern)
+}
+
+// TempDir creates a new temporary directory in the directory dir.
+// The directory name is generated by taking pattern and applying a
+// random string to the end. If pattern includes a "*", the random string
+// replaces the last "*". TempDir returns the name of the new directory.
+// If dir is the empty string, TempDir uses the
+// default directory for temporary files (see os.TempDir).
+// Multiple programs calling TempDir simultaneously
+// will not choose the same directory. It is the caller's responsibility
+// to remove the directory when no longer needed.
+//
+// Deprecated: As of Go 1.17, this function simply calls [os.MkdirTemp].
+func TempDir(dir, pattern string) (name string, err error) {
+ return os.MkdirTemp(dir, pattern)
+}
diff --git a/contrib/go/_std_1.21/src/io/ioutil/ya.make b/contrib/go/_std_1.21/src/io/ioutil/ya.make
new file mode 100644
index 0000000000..346a3ec877
--- /dev/null
+++ b/contrib/go/_std_1.21/src/io/ioutil/ya.make
@@ -0,0 +1,17 @@
+GO_LIBRARY()
+
+SRCS(
+ ioutil.go
+ tempfile.go
+)
+
+GO_XTEST_SRCS(
+ example_test.go
+ ioutil_test.go
+ tempfile_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/io/multi.go b/contrib/go/_std_1.21/src/io/multi.go
index 07a9afffda..07a9afffda 100644
--- a/contrib/go/_std_1.20/src/io/multi.go
+++ b/contrib/go/_std_1.21/src/io/multi.go
diff --git a/contrib/go/_std_1.20/src/io/pipe.go b/contrib/go/_std_1.21/src/io/pipe.go
index 2724e3f7ab..2724e3f7ab 100644
--- a/contrib/go/_std_1.20/src/io/pipe.go
+++ b/contrib/go/_std_1.21/src/io/pipe.go
diff --git a/contrib/go/_std_1.21/src/io/ya.make b/contrib/go/_std_1.21/src/io/ya.make
new file mode 100644
index 0000000000..4cc4450518
--- /dev/null
+++ b/contrib/go/_std_1.21/src/io/ya.make
@@ -0,0 +1,23 @@
+GO_LIBRARY()
+
+SRCS(
+ io.go
+ multi.go
+ pipe.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ example_test.go
+ io_test.go
+ multi_test.go
+ pipe_test.go
+)
+
+END()
+
+RECURSE(
+ fs
+ ioutil
+)
diff --git a/contrib/go/_std_1.21/src/log/internal/internal.go b/contrib/go/_std_1.21/src/log/internal/internal.go
new file mode 100644
index 0000000000..d5af2c536c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/internal/internal.go
@@ -0,0 +1,12 @@
+// Copyright 2023 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 internal contains definitions used by both log and log/slog.
+package internal
+
+// DefaultOutput holds a function which calls the default log.Logger's
+// output function.
+// It allows slog.defaultHandler to call into an unexported function of
+// the log package.
+var DefaultOutput func(pc uintptr, data []byte) error
diff --git a/contrib/go/_std_1.21/src/log/internal/ya.make b/contrib/go/_std_1.21/src/log/internal/ya.make
new file mode 100644
index 0000000000..ad965301c0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/internal/ya.make
@@ -0,0 +1,7 @@
+GO_LIBRARY()
+
+SRCS(
+ internal.go
+)
+
+END()
diff --git a/contrib/go/_std_1.21/src/log/log.go b/contrib/go/_std_1.21/src/log/log.go
new file mode 100644
index 0000000000..9d5440ea3a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/log.go
@@ -0,0 +1,458 @@
+// Copyright 2009 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 log implements a simple logging package. It defines a type, Logger,
+// with methods for formatting output. It also has a predefined 'standard'
+// Logger accessible through helper functions Print[f|ln], Fatal[f|ln], and
+// Panic[f|ln], which are easier to use than creating a Logger manually.
+// That logger writes to standard error and prints the date and time
+// of each logged message.
+// Every log message is output on a separate line: if the message being
+// printed does not end in a newline, the logger will add one.
+// The Fatal functions call os.Exit(1) after writing the log message.
+// The Panic functions call panic after writing the log message.
+package log
+
+import (
+ "fmt"
+ "io"
+ "log/internal"
+ "os"
+ "runtime"
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+// These flags define which text to prefix to each log entry generated by the Logger.
+// Bits are or'ed together to control what's printed.
+// With the exception of the Lmsgprefix flag, there is no
+// control over the order they appear (the order listed here)
+// or the format they present (as described in the comments).
+// The prefix is followed by a colon only when Llongfile or Lshortfile
+// is specified.
+// For example, flags Ldate | Ltime (or LstdFlags) produce,
+//
+// 2009/01/23 01:23:23 message
+//
+// while flags Ldate | Ltime | Lmicroseconds | Llongfile produce,
+//
+// 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message
+const (
+ Ldate = 1 << iota // the date in the local time zone: 2009/01/23
+ Ltime // the time in the local time zone: 01:23:23
+ Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
+ Llongfile // full file name and line number: /a/b/c/d.go:23
+ Lshortfile // final file name element and line number: d.go:23. overrides Llongfile
+ LUTC // if Ldate or Ltime is set, use UTC rather than the local time zone
+ Lmsgprefix // move the "prefix" from the beginning of the line to before the message
+ LstdFlags = Ldate | Ltime // initial values for the standard logger
+)
+
+// A Logger represents an active logging object that generates lines of
+// output to an io.Writer. Each logging operation makes a single call to
+// the Writer's Write method. A Logger can be used simultaneously from
+// multiple goroutines; it guarantees to serialize access to the Writer.
+type Logger struct {
+ outMu sync.Mutex
+ out io.Writer // destination for output
+
+ prefix atomic.Pointer[string] // prefix on each line to identify the logger (but see Lmsgprefix)
+ flag atomic.Int32 // properties
+ isDiscard atomic.Bool
+}
+
+// New creates a new Logger. The out variable sets the
+// destination to which log data will be written.
+// The prefix appears at the beginning of each generated log line, or
+// after the log header if the Lmsgprefix flag is provided.
+// The flag argument defines the logging properties.
+func New(out io.Writer, prefix string, flag int) *Logger {
+ l := new(Logger)
+ l.SetOutput(out)
+ l.SetPrefix(prefix)
+ l.SetFlags(flag)
+ return l
+}
+
+// SetOutput sets the output destination for the logger.
+func (l *Logger) SetOutput(w io.Writer) {
+ l.outMu.Lock()
+ defer l.outMu.Unlock()
+ l.out = w
+ l.isDiscard.Store(w == io.Discard)
+}
+
+var std = New(os.Stderr, "", LstdFlags)
+
+// Default returns the standard logger used by the package-level output functions.
+func Default() *Logger { return std }
+
+// Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding.
+func itoa(buf *[]byte, i int, wid int) {
+ // Assemble decimal in reverse order.
+ var b [20]byte
+ bp := len(b) - 1
+ for i >= 10 || wid > 1 {
+ wid--
+ q := i / 10
+ b[bp] = byte('0' + i - q*10)
+ bp--
+ i = q
+ }
+ // i < 10
+ b[bp] = byte('0' + i)
+ *buf = append(*buf, b[bp:]...)
+}
+
+// formatHeader writes log header to buf in following order:
+// - l.prefix (if it's not blank and Lmsgprefix is unset),
+// - date and/or time (if corresponding flags are provided),
+// - file and line number (if corresponding flags are provided),
+// - l.prefix (if it's not blank and Lmsgprefix is set).
+func formatHeader(buf *[]byte, t time.Time, prefix string, flag int, file string, line int) {
+ if flag&Lmsgprefix == 0 {
+ *buf = append(*buf, prefix...)
+ }
+ if flag&(Ldate|Ltime|Lmicroseconds) != 0 {
+ if flag&LUTC != 0 {
+ t = t.UTC()
+ }
+ if flag&Ldate != 0 {
+ year, month, day := t.Date()
+ itoa(buf, year, 4)
+ *buf = append(*buf, '/')
+ itoa(buf, int(month), 2)
+ *buf = append(*buf, '/')
+ itoa(buf, day, 2)
+ *buf = append(*buf, ' ')
+ }
+ if flag&(Ltime|Lmicroseconds) != 0 {
+ hour, min, sec := t.Clock()
+ itoa(buf, hour, 2)
+ *buf = append(*buf, ':')
+ itoa(buf, min, 2)
+ *buf = append(*buf, ':')
+ itoa(buf, sec, 2)
+ if flag&Lmicroseconds != 0 {
+ *buf = append(*buf, '.')
+ itoa(buf, t.Nanosecond()/1e3, 6)
+ }
+ *buf = append(*buf, ' ')
+ }
+ }
+ if flag&(Lshortfile|Llongfile) != 0 {
+ if flag&Lshortfile != 0 {
+ short := file
+ for i := len(file) - 1; i > 0; i-- {
+ if file[i] == '/' {
+ short = file[i+1:]
+ break
+ }
+ }
+ file = short
+ }
+ *buf = append(*buf, file...)
+ *buf = append(*buf, ':')
+ itoa(buf, line, -1)
+ *buf = append(*buf, ": "...)
+ }
+ if flag&Lmsgprefix != 0 {
+ *buf = append(*buf, prefix...)
+ }
+}
+
+var bufferPool = sync.Pool{New: func() any { return new([]byte) }}
+
+func getBuffer() *[]byte {
+ p := bufferPool.Get().(*[]byte)
+ *p = (*p)[:0]
+ return p
+}
+
+func putBuffer(p *[]byte) {
+ // Proper usage of a sync.Pool requires each entry to have approximately
+ // the same memory cost. To obtain this property when the stored type
+ // contains a variably-sized buffer, we add a hard limit on the maximum buffer
+ // to place back in the pool.
+ //
+ // See https://go.dev/issue/23199
+ if cap(*p) > 64<<10 {
+ *p = nil
+ }
+ bufferPool.Put(p)
+}
+
+// Output writes the output for a logging event. The string s contains
+// the text to print after the prefix specified by the flags of the
+// Logger. A newline is appended if the last character of s is not
+// already a newline. Calldepth is used to recover the PC and is
+// provided for generality, although at the moment on all pre-defined
+// paths it will be 2.
+func (l *Logger) Output(calldepth int, s string) error {
+ calldepth++ // +1 for this frame.
+ return l.output(0, calldepth, func(b []byte) []byte {
+ return append(b, s...)
+ })
+}
+
+// output can take either a calldepth or a pc to get source line information.
+// It uses the pc if it is non-zero.
+func (l *Logger) output(pc uintptr, calldepth int, appendOutput func([]byte) []byte) error {
+ if l.isDiscard.Load() {
+ return nil
+ }
+
+ now := time.Now() // get this early.
+
+ // Load prefix and flag once so that their value is consistent within
+ // this call regardless of any concurrent changes to their value.
+ prefix := l.Prefix()
+ flag := l.Flags()
+
+ var file string
+ var line int
+ if flag&(Lshortfile|Llongfile) != 0 {
+ if pc == 0 {
+ var ok bool
+ _, file, line, ok = runtime.Caller(calldepth)
+ if !ok {
+ file = "???"
+ line = 0
+ }
+ } else {
+ fs := runtime.CallersFrames([]uintptr{pc})
+ f, _ := fs.Next()
+ file = f.File
+ if file == "" {
+ file = "???"
+ }
+ line = f.Line
+ }
+ }
+
+ buf := getBuffer()
+ defer putBuffer(buf)
+ formatHeader(buf, now, prefix, flag, file, line)
+ *buf = appendOutput(*buf)
+ if len(*buf) == 0 || (*buf)[len(*buf)-1] != '\n' {
+ *buf = append(*buf, '\n')
+ }
+
+ l.outMu.Lock()
+ defer l.outMu.Unlock()
+ _, err := l.out.Write(*buf)
+ return err
+}
+
+func init() {
+ internal.DefaultOutput = func(pc uintptr, data []byte) error {
+ return std.output(pc, 0, func(buf []byte) []byte {
+ return append(buf, data...)
+ })
+ }
+}
+
+// Print calls l.Output to print to the logger.
+// Arguments are handled in the manner of fmt.Print.
+func (l *Logger) Print(v ...any) {
+ l.output(0, 2, func(b []byte) []byte {
+ return fmt.Append(b, v...)
+ })
+}
+
+// Printf calls l.Output to print to the logger.
+// Arguments are handled in the manner of fmt.Printf.
+func (l *Logger) Printf(format string, v ...any) {
+ l.output(0, 2, func(b []byte) []byte {
+ return fmt.Appendf(b, format, v...)
+ })
+}
+
+// Println calls l.Output to print to the logger.
+// Arguments are handled in the manner of fmt.Println.
+func (l *Logger) Println(v ...any) {
+ l.output(0, 2, func(b []byte) []byte {
+ return fmt.Appendln(b, v...)
+ })
+}
+
+// Fatal is equivalent to l.Print() followed by a call to os.Exit(1).
+func (l *Logger) Fatal(v ...any) {
+ l.Output(2, fmt.Sprint(v...))
+ os.Exit(1)
+}
+
+// Fatalf is equivalent to l.Printf() followed by a call to os.Exit(1).
+func (l *Logger) Fatalf(format string, v ...any) {
+ l.Output(2, fmt.Sprintf(format, v...))
+ os.Exit(1)
+}
+
+// Fatalln is equivalent to l.Println() followed by a call to os.Exit(1).
+func (l *Logger) Fatalln(v ...any) {
+ l.Output(2, fmt.Sprintln(v...))
+ os.Exit(1)
+}
+
+// Panic is equivalent to l.Print() followed by a call to panic().
+func (l *Logger) Panic(v ...any) {
+ s := fmt.Sprint(v...)
+ l.Output(2, s)
+ panic(s)
+}
+
+// Panicf is equivalent to l.Printf() followed by a call to panic().
+func (l *Logger) Panicf(format string, v ...any) {
+ s := fmt.Sprintf(format, v...)
+ l.Output(2, s)
+ panic(s)
+}
+
+// Panicln is equivalent to l.Println() followed by a call to panic().
+func (l *Logger) Panicln(v ...any) {
+ s := fmt.Sprintln(v...)
+ l.Output(2, s)
+ panic(s)
+}
+
+// Flags returns the output flags for the logger.
+// The flag bits are Ldate, Ltime, and so on.
+func (l *Logger) Flags() int {
+ return int(l.flag.Load())
+}
+
+// SetFlags sets the output flags for the logger.
+// The flag bits are Ldate, Ltime, and so on.
+func (l *Logger) SetFlags(flag int) {
+ l.flag.Store(int32(flag))
+}
+
+// Prefix returns the output prefix for the logger.
+func (l *Logger) Prefix() string {
+ if p := l.prefix.Load(); p != nil {
+ return *p
+ }
+ return ""
+}
+
+// SetPrefix sets the output prefix for the logger.
+func (l *Logger) SetPrefix(prefix string) {
+ l.prefix.Store(&prefix)
+}
+
+// Writer returns the output destination for the logger.
+func (l *Logger) Writer() io.Writer {
+ l.outMu.Lock()
+ defer l.outMu.Unlock()
+ return l.out
+}
+
+// SetOutput sets the output destination for the standard logger.
+func SetOutput(w io.Writer) {
+ std.SetOutput(w)
+}
+
+// Flags returns the output flags for the standard logger.
+// The flag bits are Ldate, Ltime, and so on.
+func Flags() int {
+ return std.Flags()
+}
+
+// SetFlags sets the output flags for the standard logger.
+// The flag bits are Ldate, Ltime, and so on.
+func SetFlags(flag int) {
+ std.SetFlags(flag)
+}
+
+// Prefix returns the output prefix for the standard logger.
+func Prefix() string {
+ return std.Prefix()
+}
+
+// SetPrefix sets the output prefix for the standard logger.
+func SetPrefix(prefix string) {
+ std.SetPrefix(prefix)
+}
+
+// Writer returns the output destination for the standard logger.
+func Writer() io.Writer {
+ return std.Writer()
+}
+
+// These functions write to the standard logger.
+
+// Print calls Output to print to the standard logger.
+// Arguments are handled in the manner of fmt.Print.
+func Print(v ...any) {
+ std.output(0, 2, func(b []byte) []byte {
+ return fmt.Append(b, v...)
+ })
+}
+
+// Printf calls Output to print to the standard logger.
+// Arguments are handled in the manner of fmt.Printf.
+func Printf(format string, v ...any) {
+ std.output(0, 2, func(b []byte) []byte {
+ return fmt.Appendf(b, format, v...)
+ })
+}
+
+// Println calls Output to print to the standard logger.
+// Arguments are handled in the manner of fmt.Println.
+func Println(v ...any) {
+ std.output(0, 2, func(b []byte) []byte {
+ return fmt.Appendln(b, v...)
+ })
+}
+
+// Fatal is equivalent to Print() followed by a call to os.Exit(1).
+func Fatal(v ...any) {
+ std.Output(2, fmt.Sprint(v...))
+ os.Exit(1)
+}
+
+// Fatalf is equivalent to Printf() followed by a call to os.Exit(1).
+func Fatalf(format string, v ...any) {
+ std.Output(2, fmt.Sprintf(format, v...))
+ os.Exit(1)
+}
+
+// Fatalln is equivalent to Println() followed by a call to os.Exit(1).
+func Fatalln(v ...any) {
+ std.Output(2, fmt.Sprintln(v...))
+ os.Exit(1)
+}
+
+// Panic is equivalent to Print() followed by a call to panic().
+func Panic(v ...any) {
+ s := fmt.Sprint(v...)
+ std.Output(2, s)
+ panic(s)
+}
+
+// Panicf is equivalent to Printf() followed by a call to panic().
+func Panicf(format string, v ...any) {
+ s := fmt.Sprintf(format, v...)
+ std.Output(2, s)
+ panic(s)
+}
+
+// Panicln is equivalent to Println() followed by a call to panic().
+func Panicln(v ...any) {
+ s := fmt.Sprintln(v...)
+ std.Output(2, s)
+ panic(s)
+}
+
+// Output writes the output for a logging event. The string s contains
+// the text to print after the prefix specified by the flags of the
+// Logger. A newline is appended if the last character of s is not
+// already a newline. Calldepth is the count of the number of
+// frames to skip when computing the file name and line number
+// if Llongfile or Lshortfile is set; a value of 1 will print the details
+// for the caller of Output.
+func Output(calldepth int, s string) error {
+ return std.Output(calldepth+1, s) // +1 for this frame.
+}
diff --git a/contrib/go/_std_1.21/src/log/slog/attr.go b/contrib/go/_std_1.21/src/log/slog/attr.go
new file mode 100644
index 0000000000..90e343b319
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/attr.go
@@ -0,0 +1,102 @@
+// Copyright 2022 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 slog
+
+import (
+ "fmt"
+ "time"
+)
+
+// An Attr is a key-value pair.
+type Attr struct {
+ Key string
+ Value Value
+}
+
+// String returns an Attr for a string value.
+func String(key, value string) Attr {
+ return Attr{key, StringValue(value)}
+}
+
+// Int64 returns an Attr for an int64.
+func Int64(key string, value int64) Attr {
+ return Attr{key, Int64Value(value)}
+}
+
+// Int converts an int to an int64 and returns
+// an Attr with that value.
+func Int(key string, value int) Attr {
+ return Int64(key, int64(value))
+}
+
+// Uint64 returns an Attr for a uint64.
+func Uint64(key string, v uint64) Attr {
+ return Attr{key, Uint64Value(v)}
+}
+
+// Float64 returns an Attr for a floating-point number.
+func Float64(key string, v float64) Attr {
+ return Attr{key, Float64Value(v)}
+}
+
+// Bool returns an Attr for a bool.
+func Bool(key string, v bool) Attr {
+ return Attr{key, BoolValue(v)}
+}
+
+// Time returns an Attr for a time.Time.
+// It discards the monotonic portion.
+func Time(key string, v time.Time) Attr {
+ return Attr{key, TimeValue(v)}
+}
+
+// Duration returns an Attr for a time.Duration.
+func Duration(key string, v time.Duration) Attr {
+ return Attr{key, DurationValue(v)}
+}
+
+// Group returns an Attr for a Group Value.
+// The first argument is the key; the remaining arguments
+// are converted to Attrs as in [Logger.Log].
+//
+// Use Group to collect several key-value pairs under a single
+// key on a log line, or as the result of LogValue
+// in order to log a single value as multiple Attrs.
+func Group(key string, args ...any) Attr {
+ return Attr{key, GroupValue(argsToAttrSlice(args)...)}
+}
+
+func argsToAttrSlice(args []any) []Attr {
+ var (
+ attr Attr
+ attrs []Attr
+ )
+ for len(args) > 0 {
+ attr, args = argsToAttr(args)
+ attrs = append(attrs, attr)
+ }
+ return attrs
+}
+
+// Any returns an Attr for the supplied value.
+// See [AnyValue] for how values are treated.
+func Any(key string, value any) Attr {
+ return Attr{key, AnyValue(value)}
+}
+
+// Equal reports whether a and b have equal keys and values.
+func (a Attr) Equal(b Attr) bool {
+ return a.Key == b.Key && a.Value.Equal(b.Value)
+}
+
+func (a Attr) String() string {
+ return fmt.Sprintf("%s=%s", a.Key, a.Value)
+}
+
+// isEmpty reports whether a has an empty key and a nil value.
+// That can be written as Attr{} or Any("", nil).
+func (a Attr) isEmpty() bool {
+ return a.Key == "" && a.Value.num == 0 && a.Value.any == nil
+}
diff --git a/contrib/go/_std_1.21/src/log/slog/doc.go b/contrib/go/_std_1.21/src/log/slog/doc.go
new file mode 100644
index 0000000000..088df61c6d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/doc.go
@@ -0,0 +1,320 @@
+// Copyright 2022 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 slog provides structured logging,
+in which log records include a message,
+a severity level, and various other attributes
+expressed as key-value pairs.
+
+It defines a type, [Logger],
+which provides several methods (such as [Logger.Info] and [Logger.Error])
+for reporting events of interest.
+
+Each Logger is associated with a [Handler].
+A Logger output method creates a [Record] from the method arguments
+and passes it to the Handler, which decides how to handle it.
+There is a default Logger accessible through top-level functions
+(such as [Info] and [Error]) that call the corresponding Logger methods.
+
+A log record consists of a time, a level, a message, and a set of key-value
+pairs, where the keys are strings and the values may be of any type.
+As an example,
+
+ slog.Info("hello", "count", 3)
+
+creates a record containing the time of the call,
+a level of Info, the message "hello", and a single
+pair with key "count" and value 3.
+
+The [Info] top-level function calls the [Logger.Info] method on the default Logger.
+In addition to [Logger.Info], there are methods for Debug, Warn and Error levels.
+Besides these convenience methods for common levels,
+there is also a [Logger.Log] method which takes the level as an argument.
+Each of these methods has a corresponding top-level function that uses the
+default logger.
+
+The default handler formats the log record's message, time, level, and attributes
+as a string and passes it to the [log] package.
+
+ 2022/11/08 15:28:26 INFO hello count=3
+
+For more control over the output format, create a logger with a different handler.
+This statement uses [New] to create a new logger with a TextHandler
+that writes structured records in text form to standard error:
+
+ logger := slog.New(slog.NewTextHandler(os.Stderr, nil))
+
+[TextHandler] output is a sequence of key=value pairs, easily and unambiguously
+parsed by machine. This statement:
+
+ logger.Info("hello", "count", 3)
+
+produces this output:
+
+ time=2022-11-08T15:28:26.000-05:00 level=INFO msg=hello count=3
+
+The package also provides [JSONHandler], whose output is line-delimited JSON:
+
+ logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
+ logger.Info("hello", "count", 3)
+
+produces this output:
+
+ {"time":"2022-11-08T15:28:26.000000000-05:00","level":"INFO","msg":"hello","count":3}
+
+Both [TextHandler] and [JSONHandler] can be configured with [HandlerOptions].
+There are options for setting the minimum level (see Levels, below),
+displaying the source file and line of the log call, and
+modifying attributes before they are logged.
+
+Setting a logger as the default with
+
+ slog.SetDefault(logger)
+
+will cause the top-level functions like [Info] to use it.
+[SetDefault] also updates the default logger used by the [log] package,
+so that existing applications that use [log.Printf] and related functions
+will send log records to the logger's handler without needing to be rewritten.
+
+Some attributes are common to many log calls.
+For example, you may wish to include the URL or trace identifier of a server request
+with all log events arising from the request.
+Rather than repeat the attribute with every log call, you can use [Logger.With]
+to construct a new Logger containing the attributes:
+
+ logger2 := logger.With("url", r.URL)
+
+The arguments to With are the same key-value pairs used in [Logger.Info].
+The result is a new Logger with the same handler as the original, but additional
+attributes that will appear in the output of every call.
+
+# Levels
+
+A [Level] is an integer representing the importance or severity of a log event.
+The higher the level, the more severe the event.
+This package defines constants for the most common levels,
+but any int can be used as a level.
+
+In an application, you may wish to log messages only at a certain level or greater.
+One common configuration is to log messages at Info or higher levels,
+suppressing debug logging until it is needed.
+The built-in handlers can be configured with the minimum level to output by
+setting [HandlerOptions.Level].
+The program's `main` function typically does this.
+The default value is LevelInfo.
+
+Setting the [HandlerOptions.Level] field to a [Level] value
+fixes the handler's minimum level throughout its lifetime.
+Setting it to a [LevelVar] allows the level to be varied dynamically.
+A LevelVar holds a Level and is safe to read or write from multiple
+goroutines.
+To vary the level dynamically for an entire program, first initialize
+a global LevelVar:
+
+ var programLevel = new(slog.LevelVar) // Info by default
+
+Then use the LevelVar to construct a handler, and make it the default:
+
+ h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: programLevel})
+ slog.SetDefault(slog.New(h))
+
+Now the program can change its logging level with a single statement:
+
+ programLevel.Set(slog.LevelDebug)
+
+# Groups
+
+Attributes can be collected into groups.
+A group has a name that is used to qualify the names of its attributes.
+How this qualification is displayed depends on the handler.
+[TextHandler] separates the group and attribute names with a dot.
+[JSONHandler] treats each group as a separate JSON object, with the group name as the key.
+
+Use [Group] to create a Group attribute from a name and a list of key-value pairs:
+
+ slog.Group("request",
+ "method", r.Method,
+ "url", r.URL)
+
+TextHandler would display this group as
+
+ request.method=GET request.url=http://example.com
+
+JSONHandler would display it as
+
+ "request":{"method":"GET","url":"http://example.com"}
+
+Use [Logger.WithGroup] to qualify all of a Logger's output
+with a group name. Calling WithGroup on a Logger results in a
+new Logger with the same Handler as the original, but with all
+its attributes qualified by the group name.
+
+This can help prevent duplicate attribute keys in large systems,
+where subsystems might use the same keys.
+Pass each subsystem a different Logger with its own group name so that
+potential duplicates are qualified:
+
+ logger := slog.Default().With("id", systemID)
+ parserLogger := logger.WithGroup("parser")
+ parseInput(input, parserLogger)
+
+When parseInput logs with parserLogger, its keys will be qualified with "parser",
+so even if it uses the common key "id", the log line will have distinct keys.
+
+# Contexts
+
+Some handlers may wish to include information from the [context.Context] that is
+available at the call site. One example of such information
+is the identifier for the current span when tracing is enabled.
+
+The [Logger.Log] and [Logger.LogAttrs] methods take a context as a first
+argument, as do their corresponding top-level functions.
+
+Although the convenience methods on Logger (Info and so on) and the
+corresponding top-level functions do not take a context, the alternatives ending
+in "Context" do. For example,
+
+ slog.InfoContext(ctx, "message")
+
+It is recommended to pass a context to an output method if one is available.
+
+# Attrs and Values
+
+An [Attr] is a key-value pair. The Logger output methods accept Attrs as well as
+alternating keys and values. The statement
+
+ slog.Info("hello", slog.Int("count", 3))
+
+behaves the same as
+
+ slog.Info("hello", "count", 3)
+
+There are convenience constructors for [Attr] such as [Int], [String], and [Bool]
+for common types, as well as the function [Any] for constructing Attrs of any
+type.
+
+The value part of an Attr is a type called [Value].
+Like an [any], a Value can hold any Go value,
+but it can represent typical values, including all numbers and strings,
+without an allocation.
+
+For the most efficient log output, use [Logger.LogAttrs].
+It is similar to [Logger.Log] but accepts only Attrs, not alternating
+keys and values; this allows it, too, to avoid allocation.
+
+The call
+
+ logger.LogAttrs(ctx, slog.LevelInfo, "hello", slog.Int("count", 3))
+
+is the most efficient way to achieve the same output as
+
+ slog.Info("hello", "count", 3)
+
+# Customizing a type's logging behavior
+
+If a type implements the [LogValuer] interface, the [Value] returned from its LogValue
+method is used for logging. You can use this to control how values of the type
+appear in logs. For example, you can redact secret information like passwords,
+or gather a struct's fields in a Group. See the examples under [LogValuer] for
+details.
+
+A LogValue method may return a Value that itself implements [LogValuer]. The [Value.Resolve]
+method handles these cases carefully, avoiding infinite loops and unbounded recursion.
+Handler authors and others may wish to use Value.Resolve instead of calling LogValue directly.
+
+# Wrapping output methods
+
+The logger functions use reflection over the call stack to find the file name
+and line number of the logging call within the application. This can produce
+incorrect source information for functions that wrap slog. For instance, if you
+define this function in file mylog.go:
+
+ func Infof(format string, args ...any) {
+ slog.Default().Info(fmt.Sprintf(format, args...))
+ }
+
+and you call it like this in main.go:
+
+ Infof(slog.Default(), "hello, %s", "world")
+
+then slog will report the source file as mylog.go, not main.go.
+
+A correct implementation of Infof will obtain the source location
+(pc) and pass it to NewRecord.
+The Infof function in the package-level example called "wrapping"
+demonstrates how to do this.
+
+# Working with Records
+
+Sometimes a Handler will need to modify a Record
+before passing it on to another Handler or backend.
+A Record contains a mixture of simple public fields (e.g. Time, Level, Message)
+and hidden fields that refer to state (such as attributes) indirectly. This
+means that modifying a simple copy of a Record (e.g. by calling
+[Record.Add] or [Record.AddAttrs] to add attributes)
+may have unexpected effects on the original.
+Before modifying a Record, use [Record.Clone] to
+create a copy that shares no state with the original,
+or create a new Record with [NewRecord]
+and build up its Attrs by traversing the old ones with [Record.Attrs].
+
+# Performance considerations
+
+If profiling your application demonstrates that logging is taking significant time,
+the following suggestions may help.
+
+If many log lines have a common attribute, use [Logger.With] to create a Logger with
+that attribute. The built-in handlers will format that attribute only once, at the
+call to [Logger.With]. The [Handler] interface is designed to allow that optimization,
+and a well-written Handler should take advantage of it.
+
+The arguments to a log call are always evaluated, even if the log event is discarded.
+If possible, defer computation so that it happens only if the value is actually logged.
+For example, consider the call
+
+ slog.Info("starting request", "url", r.URL.String()) // may compute String unnecessarily
+
+The URL.String method will be called even if the logger discards Info-level events.
+Instead, pass the URL directly:
+
+ slog.Info("starting request", "url", &r.URL) // calls URL.String only if needed
+
+The built-in [TextHandler] will call its String method, but only
+if the log event is enabled.
+Avoiding the call to String also preserves the structure of the underlying value.
+For example [JSONHandler] emits the components of the parsed URL as a JSON object.
+If you want to avoid eagerly paying the cost of the String call
+without causing the handler to potentially inspect the structure of the value,
+wrap the value in a fmt.Stringer implementation that hides its Marshal methods.
+
+You can also use the [LogValuer] interface to avoid unnecessary work in disabled log
+calls. Say you need to log some expensive value:
+
+ slog.Debug("frobbing", "value", computeExpensiveValue(arg))
+
+Even if this line is disabled, computeExpensiveValue will be called.
+To avoid that, define a type implementing LogValuer:
+
+ type expensive struct { arg int }
+
+ func (e expensive) LogValue() slog.Value {
+ return slog.AnyValue(computeExpensiveValue(e.arg))
+ }
+
+Then use a value of that type in log calls:
+
+ slog.Debug("frobbing", "value", expensive{arg})
+
+Now computeExpensiveValue will only be called when the line is enabled.
+
+The built-in handlers acquire a lock before calling [io.Writer.Write]
+to ensure that each record is written in one piece. User-defined
+handlers are responsible for their own locking.
+
+# Writing a handler
+
+For a guide to writing a custom handler, see https://golang.org/s/slog-handler-guide.
+*/
+package slog
diff --git a/contrib/go/_std_1.21/src/log/slog/handler.go b/contrib/go/_std_1.21/src/log/slog/handler.go
new file mode 100644
index 0000000000..a73983cda3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/handler.go
@@ -0,0 +1,567 @@
+// Copyright 2022 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 slog
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "log/slog/internal/buffer"
+ "slices"
+ "strconv"
+ "sync"
+ "time"
+)
+
+// A Handler handles log records produced by a Logger..
+//
+// A typical handler may print log records to standard error,
+// or write them to a file or database, or perhaps augment them
+// with additional attributes and pass them on to another handler.
+//
+// Any of the Handler's methods may be called concurrently with itself
+// or with other methods. It is the responsibility of the Handler to
+// manage this concurrency.
+//
+// Users of the slog package should not invoke Handler methods directly.
+// They should use the methods of [Logger] instead.
+type Handler interface {
+ // Enabled reports whether the handler handles records at the given level.
+ // The handler ignores records whose level is lower.
+ // It is called early, before any arguments are processed,
+ // to save effort if the log event should be discarded.
+ // If called from a Logger method, the first argument is the context
+ // passed to that method, or context.Background() if nil was passed
+ // or the method does not take a context.
+ // The context is passed so Enabled can use its values
+ // to make a decision.
+ Enabled(context.Context, Level) bool
+
+ // Handle handles the Record.
+ // It will only be called when Enabled returns true.
+ // The Context argument is as for Enabled.
+ // It is present solely to provide Handlers access to the context's values.
+ // Canceling the context should not affect record processing.
+ // (Among other things, log messages may be necessary to debug a
+ // cancellation-related problem.)
+ //
+ // Handle methods that produce output should observe the following rules:
+ // - If r.Time is the zero time, ignore the time.
+ // - If r.PC is zero, ignore it.
+ // - Attr's values should be resolved.
+ // - If an Attr's key and value are both the zero value, ignore the Attr.
+ // This can be tested with attr.Equal(Attr{}).
+ // - If a group's key is empty, inline the group's Attrs.
+ // - If a group has no Attrs (even if it has a non-empty key),
+ // ignore it.
+ Handle(context.Context, Record) error
+
+ // WithAttrs returns a new Handler whose attributes consist of
+ // both the receiver's attributes and the arguments.
+ // The Handler owns the slice: it may retain, modify or discard it.
+ WithAttrs(attrs []Attr) Handler
+
+ // WithGroup returns a new Handler with the given group appended to
+ // the receiver's existing groups.
+ // The keys of all subsequent attributes, whether added by With or in a
+ // Record, should be qualified by the sequence of group names.
+ //
+ // How this qualification happens is up to the Handler, so long as
+ // this Handler's attribute keys differ from those of another Handler
+ // with a different sequence of group names.
+ //
+ // A Handler should treat WithGroup as starting a Group of Attrs that ends
+ // at the end of the log event. That is,
+ //
+ // logger.WithGroup("s").LogAttrs(level, msg, slog.Int("a", 1), slog.Int("b", 2))
+ //
+ // should behave like
+ //
+ // logger.LogAttrs(level, msg, slog.Group("s", slog.Int("a", 1), slog.Int("b", 2)))
+ //
+ // If the name is empty, WithGroup returns the receiver.
+ WithGroup(name string) Handler
+}
+
+type defaultHandler struct {
+ ch *commonHandler
+ // internal.DefaultOutput, except for testing
+ output func(pc uintptr, data []byte) error
+}
+
+func newDefaultHandler(output func(uintptr, []byte) error) *defaultHandler {
+ return &defaultHandler{
+ ch: &commonHandler{json: false},
+ output: output,
+ }
+}
+
+func (*defaultHandler) Enabled(_ context.Context, l Level) bool {
+ return l >= LevelInfo
+}
+
+// Collect the level, attributes and message in a string and
+// write it with the default log.Logger.
+// Let the log.Logger handle time and file/line.
+func (h *defaultHandler) Handle(ctx context.Context, r Record) error {
+ buf := buffer.New()
+ buf.WriteString(r.Level.String())
+ buf.WriteByte(' ')
+ buf.WriteString(r.Message)
+ state := h.ch.newHandleState(buf, true, " ")
+ defer state.free()
+ state.appendNonBuiltIns(r)
+ return h.output(r.PC, *buf)
+}
+
+func (h *defaultHandler) WithAttrs(as []Attr) Handler {
+ return &defaultHandler{h.ch.withAttrs(as), h.output}
+}
+
+func (h *defaultHandler) WithGroup(name string) Handler {
+ return &defaultHandler{h.ch.withGroup(name), h.output}
+}
+
+// HandlerOptions are options for a TextHandler or JSONHandler.
+// A zero HandlerOptions consists entirely of default values.
+type HandlerOptions struct {
+ // AddSource causes the handler to compute the source code position
+ // of the log statement and add a SourceKey attribute to the output.
+ AddSource bool
+
+ // Level reports the minimum record level that will be logged.
+ // The handler discards records with lower levels.
+ // If Level is nil, the handler assumes LevelInfo.
+ // The handler calls Level.Level for each record processed;
+ // to adjust the minimum level dynamically, use a LevelVar.
+ Level Leveler
+
+ // ReplaceAttr is called to rewrite each non-group attribute before it is logged.
+ // The attribute's value has been resolved (see [Value.Resolve]).
+ // If ReplaceAttr returns a zero Attr, the attribute is discarded.
+ //
+ // The built-in attributes with keys "time", "level", "source", and "msg"
+ // are passed to this function, except that time is omitted
+ // if zero, and source is omitted if AddSource is false.
+ //
+ // The first argument is a list of currently open groups that contain the
+ // Attr. It must not be retained or modified. ReplaceAttr is never called
+ // for Group attributes, only their contents. For example, the attribute
+ // list
+ //
+ // Int("a", 1), Group("g", Int("b", 2)), Int("c", 3)
+ //
+ // results in consecutive calls to ReplaceAttr with the following arguments:
+ //
+ // nil, Int("a", 1)
+ // []string{"g"}, Int("b", 2)
+ // nil, Int("c", 3)
+ //
+ // ReplaceAttr can be used to change the default keys of the built-in
+ // attributes, convert types (for example, to replace a `time.Time` with the
+ // integer seconds since the Unix epoch), sanitize personal information, or
+ // remove attributes from the output.
+ ReplaceAttr func(groups []string, a Attr) Attr
+}
+
+// Keys for "built-in" attributes.
+const (
+ // TimeKey is the key used by the built-in handlers for the time
+ // when the log method is called. The associated Value is a [time.Time].
+ TimeKey = "time"
+ // LevelKey is the key used by the built-in handlers for the level
+ // of the log call. The associated value is a [Level].
+ LevelKey = "level"
+ // MessageKey is the key used by the built-in handlers for the
+ // message of the log call. The associated value is a string.
+ MessageKey = "msg"
+ // SourceKey is the key used by the built-in handlers for the source file
+ // and line of the log call. The associated value is a string.
+ SourceKey = "source"
+)
+
+type commonHandler struct {
+ json bool // true => output JSON; false => output text
+ opts HandlerOptions
+ preformattedAttrs []byte
+ // groupPrefix is for the text handler only.
+ // It holds the prefix for groups that were already pre-formatted.
+ // A group will appear here when a call to WithGroup is followed by
+ // a call to WithAttrs.
+ groupPrefix string
+ groups []string // all groups started from WithGroup
+ nOpenGroups int // the number of groups opened in preformattedAttrs
+ mu *sync.Mutex
+ w io.Writer
+}
+
+func (h *commonHandler) clone() *commonHandler {
+ // We can't use assignment because we can't copy the mutex.
+ return &commonHandler{
+ json: h.json,
+ opts: h.opts,
+ preformattedAttrs: slices.Clip(h.preformattedAttrs),
+ groupPrefix: h.groupPrefix,
+ groups: slices.Clip(h.groups),
+ nOpenGroups: h.nOpenGroups,
+ w: h.w,
+ mu: h.mu, // mutex shared among all clones of this handler
+ }
+}
+
+// enabled reports whether l is greater than or equal to the
+// minimum level.
+func (h *commonHandler) enabled(l Level) bool {
+ minLevel := LevelInfo
+ if h.opts.Level != nil {
+ minLevel = h.opts.Level.Level()
+ }
+ return l >= minLevel
+}
+
+func (h *commonHandler) withAttrs(as []Attr) *commonHandler {
+ // We are going to ignore empty groups, so if the entire slice consists of
+ // them, there is nothing to do.
+ if countEmptyGroups(as) == len(as) {
+ return h
+ }
+ h2 := h.clone()
+ // Pre-format the attributes as an optimization.
+ state := h2.newHandleState((*buffer.Buffer)(&h2.preformattedAttrs), false, "")
+ defer state.free()
+ state.prefix.WriteString(h.groupPrefix)
+ if len(h2.preformattedAttrs) > 0 {
+ state.sep = h.attrSep()
+ }
+ state.openGroups()
+ for _, a := range as {
+ state.appendAttr(a)
+ }
+ // Remember the new prefix for later keys.
+ h2.groupPrefix = state.prefix.String()
+ // Remember how many opened groups are in preformattedAttrs,
+ // so we don't open them again when we handle a Record.
+ h2.nOpenGroups = len(h2.groups)
+ return h2
+}
+
+func (h *commonHandler) withGroup(name string) *commonHandler {
+ h2 := h.clone()
+ h2.groups = append(h2.groups, name)
+ return h2
+}
+
+// handle is the internal implementation of Handler.Handle
+// used by TextHandler and JSONHandler.
+func (h *commonHandler) handle(r Record) error {
+ state := h.newHandleState(buffer.New(), true, "")
+ defer state.free()
+ if h.json {
+ state.buf.WriteByte('{')
+ }
+ // Built-in attributes. They are not in a group.
+ stateGroups := state.groups
+ state.groups = nil // So ReplaceAttrs sees no groups instead of the pre groups.
+ rep := h.opts.ReplaceAttr
+ // time
+ if !r.Time.IsZero() {
+ key := TimeKey
+ val := r.Time.Round(0) // strip monotonic to match Attr behavior
+ if rep == nil {
+ state.appendKey(key)
+ state.appendTime(val)
+ } else {
+ state.appendAttr(Time(key, val))
+ }
+ }
+ // level
+ key := LevelKey
+ val := r.Level
+ if rep == nil {
+ state.appendKey(key)
+ state.appendString(val.String())
+ } else {
+ state.appendAttr(Any(key, val))
+ }
+ // source
+ if h.opts.AddSource {
+ state.appendAttr(Any(SourceKey, r.source()))
+ }
+ key = MessageKey
+ msg := r.Message
+ if rep == nil {
+ state.appendKey(key)
+ state.appendString(msg)
+ } else {
+ state.appendAttr(String(key, msg))
+ }
+ state.groups = stateGroups // Restore groups passed to ReplaceAttrs.
+ state.appendNonBuiltIns(r)
+ state.buf.WriteByte('\n')
+
+ h.mu.Lock()
+ defer h.mu.Unlock()
+ _, err := h.w.Write(*state.buf)
+ return err
+}
+
+func (s *handleState) appendNonBuiltIns(r Record) {
+ // preformatted Attrs
+ if len(s.h.preformattedAttrs) > 0 {
+ s.buf.WriteString(s.sep)
+ s.buf.Write(s.h.preformattedAttrs)
+ s.sep = s.h.attrSep()
+ }
+ // Attrs in Record -- unlike the built-in ones, they are in groups started
+ // from WithGroup.
+ // If the record has no Attrs, don't output any groups.
+ nOpenGroups := s.h.nOpenGroups
+ if r.NumAttrs() > 0 {
+ s.prefix.WriteString(s.h.groupPrefix)
+ s.openGroups()
+ nOpenGroups = len(s.h.groups)
+ r.Attrs(func(a Attr) bool {
+ s.appendAttr(a)
+ return true
+ })
+ }
+ if s.h.json {
+ // Close all open groups.
+ for range s.h.groups[:nOpenGroups] {
+ s.buf.WriteByte('}')
+ }
+ // Close the top-level object.
+ s.buf.WriteByte('}')
+ }
+}
+
+// attrSep returns the separator between attributes.
+func (h *commonHandler) attrSep() string {
+ if h.json {
+ return ","
+ }
+ return " "
+}
+
+// handleState holds state for a single call to commonHandler.handle.
+// The initial value of sep determines whether to emit a separator
+// before the next key, after which it stays true.
+type handleState struct {
+ h *commonHandler
+ buf *buffer.Buffer
+ freeBuf bool // should buf be freed?
+ sep string // separator to write before next key
+ prefix *buffer.Buffer // for text: key prefix
+ groups *[]string // pool-allocated slice of active groups, for ReplaceAttr
+}
+
+var groupPool = sync.Pool{New: func() any {
+ s := make([]string, 0, 10)
+ return &s
+}}
+
+func (h *commonHandler) newHandleState(buf *buffer.Buffer, freeBuf bool, sep string) handleState {
+ s := handleState{
+ h: h,
+ buf: buf,
+ freeBuf: freeBuf,
+ sep: sep,
+ prefix: buffer.New(),
+ }
+ if h.opts.ReplaceAttr != nil {
+ s.groups = groupPool.Get().(*[]string)
+ *s.groups = append(*s.groups, h.groups[:h.nOpenGroups]...)
+ }
+ return s
+}
+
+func (s *handleState) free() {
+ if s.freeBuf {
+ s.buf.Free()
+ }
+ if gs := s.groups; gs != nil {
+ *gs = (*gs)[:0]
+ groupPool.Put(gs)
+ }
+ s.prefix.Free()
+}
+
+func (s *handleState) openGroups() {
+ for _, n := range s.h.groups[s.h.nOpenGroups:] {
+ s.openGroup(n)
+ }
+}
+
+// Separator for group names and keys.
+const keyComponentSep = '.'
+
+// openGroup starts a new group of attributes
+// with the given name.
+func (s *handleState) openGroup(name string) {
+ if s.h.json {
+ s.appendKey(name)
+ s.buf.WriteByte('{')
+ s.sep = ""
+ } else {
+ s.prefix.WriteString(name)
+ s.prefix.WriteByte(keyComponentSep)
+ }
+ // Collect group names for ReplaceAttr.
+ if s.groups != nil {
+ *s.groups = append(*s.groups, name)
+ }
+}
+
+// closeGroup ends the group with the given name.
+func (s *handleState) closeGroup(name string) {
+ if s.h.json {
+ s.buf.WriteByte('}')
+ } else {
+ (*s.prefix) = (*s.prefix)[:len(*s.prefix)-len(name)-1 /* for keyComponentSep */]
+ }
+ s.sep = s.h.attrSep()
+ if s.groups != nil {
+ *s.groups = (*s.groups)[:len(*s.groups)-1]
+ }
+}
+
+// appendAttr appends the Attr's key and value using app.
+// It handles replacement and checking for an empty key.
+// after replacement).
+func (s *handleState) appendAttr(a Attr) {
+ if rep := s.h.opts.ReplaceAttr; rep != nil && a.Value.Kind() != KindGroup {
+ var gs []string
+ if s.groups != nil {
+ gs = *s.groups
+ }
+ // Resolve before calling ReplaceAttr, so the user doesn't have to.
+ a.Value = a.Value.Resolve()
+ a = rep(gs, a)
+ }
+ a.Value = a.Value.Resolve()
+ // Elide empty Attrs.
+ if a.isEmpty() {
+ return
+ }
+ // Special case: Source.
+ if v := a.Value; v.Kind() == KindAny {
+ if src, ok := v.Any().(*Source); ok {
+ if s.h.json {
+ a.Value = src.group()
+ } else {
+ a.Value = StringValue(fmt.Sprintf("%s:%d", src.File, src.Line))
+ }
+ }
+ }
+ if a.Value.Kind() == KindGroup {
+ attrs := a.Value.Group()
+ // Output only non-empty groups.
+ if len(attrs) > 0 {
+ // Inline a group with an empty key.
+ if a.Key != "" {
+ s.openGroup(a.Key)
+ }
+ for _, aa := range attrs {
+ s.appendAttr(aa)
+ }
+ if a.Key != "" {
+ s.closeGroup(a.Key)
+ }
+ }
+ } else {
+ s.appendKey(a.Key)
+ s.appendValue(a.Value)
+ }
+}
+
+func (s *handleState) appendError(err error) {
+ s.appendString(fmt.Sprintf("!ERROR:%v", err))
+}
+
+func (s *handleState) appendKey(key string) {
+ s.buf.WriteString(s.sep)
+ if s.prefix != nil && len(*s.prefix) > 0 {
+ // TODO: optimize by avoiding allocation.
+ s.appendString(string(*s.prefix) + key)
+ } else {
+ s.appendString(key)
+ }
+ if s.h.json {
+ s.buf.WriteByte(':')
+ } else {
+ s.buf.WriteByte('=')
+ }
+ s.sep = s.h.attrSep()
+}
+
+func (s *handleState) appendString(str string) {
+ if s.h.json {
+ s.buf.WriteByte('"')
+ *s.buf = appendEscapedJSONString(*s.buf, str)
+ s.buf.WriteByte('"')
+ } else {
+ // text
+ if needsQuoting(str) {
+ *s.buf = strconv.AppendQuote(*s.buf, str)
+ } else {
+ s.buf.WriteString(str)
+ }
+ }
+}
+
+func (s *handleState) appendValue(v Value) {
+ var err error
+ if s.h.json {
+ err = appendJSONValue(s, v)
+ } else {
+ err = appendTextValue(s, v)
+ }
+ if err != nil {
+ s.appendError(err)
+ }
+}
+
+func (s *handleState) appendTime(t time.Time) {
+ if s.h.json {
+ appendJSONTime(s, t)
+ } else {
+ writeTimeRFC3339Millis(s.buf, t)
+ }
+}
+
+// This takes half the time of Time.AppendFormat.
+func writeTimeRFC3339Millis(buf *buffer.Buffer, t time.Time) {
+ year, month, day := t.Date()
+ buf.WritePosIntWidth(year, 4)
+ buf.WriteByte('-')
+ buf.WritePosIntWidth(int(month), 2)
+ buf.WriteByte('-')
+ buf.WritePosIntWidth(day, 2)
+ buf.WriteByte('T')
+ hour, min, sec := t.Clock()
+ buf.WritePosIntWidth(hour, 2)
+ buf.WriteByte(':')
+ buf.WritePosIntWidth(min, 2)
+ buf.WriteByte(':')
+ buf.WritePosIntWidth(sec, 2)
+ ns := t.Nanosecond()
+ buf.WriteByte('.')
+ buf.WritePosIntWidth(ns/1e6, 3)
+ _, offsetSeconds := t.Zone()
+ if offsetSeconds == 0 {
+ buf.WriteByte('Z')
+ } else {
+ offsetMinutes := offsetSeconds / 60
+ if offsetMinutes < 0 {
+ buf.WriteByte('-')
+ offsetMinutes = -offsetMinutes
+ } else {
+ buf.WriteByte('+')
+ }
+ buf.WritePosIntWidth(offsetMinutes/60, 2)
+ buf.WriteByte(':')
+ buf.WritePosIntWidth(offsetMinutes%60, 2)
+ }
+}
diff --git a/contrib/go/_std_1.21/src/log/slog/internal/benchmarks/benchmarks.go b/contrib/go/_std_1.21/src/log/slog/internal/benchmarks/benchmarks.go
new file mode 100644
index 0000000000..3a28523beb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/internal/benchmarks/benchmarks.go
@@ -0,0 +1,50 @@
+// Copyright 2023 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 benchmarks contains benchmarks for slog.
+//
+// These benchmarks are loosely based on github.com/uber-go/zap/benchmarks.
+// They have the following desirable properties:
+//
+// - They test a complete log event, from the user's call to its return.
+//
+// - The benchmarked code is run concurrently in multiple goroutines, to
+// better simulate a real server (the most common environment for structured
+// logs).
+//
+// - Some handlers are optimistic versions of real handlers, doing real-world
+// tasks as fast as possible (and sometimes faster, in that an
+// implementation may not be concurrency-safe). This gives us an upper bound
+// on handler performance, so we can evaluate the (handler-independent) core
+// activity of the package in an end-to-end context without concern that a
+// slow handler implementation is skewing the results.
+//
+// - We also test the built-in handlers, for comparison.
+package benchmarks
+
+import (
+ "errors"
+ "log/slog"
+ "time"
+)
+
+const testMessage = "Test logging, but use a somewhat realistic message length."
+
+var (
+ testTime = time.Date(2022, time.May, 1, 0, 0, 0, 0, time.UTC)
+ testString = "7e3b3b2aaeff56a7108fe11e154200dd/7819479873059528190"
+ testInt = 32768
+ testDuration = 23 * time.Second
+ testError = errors.New("fail")
+)
+
+var testAttrs = []slog.Attr{
+ slog.String("string", testString),
+ slog.Int("status", testInt),
+ slog.Duration("duration", testDuration),
+ slog.Time("time", testTime),
+ slog.Any("error", testError),
+}
+
+const wantText = "time=1651363200 level=0 msg=Test logging, but use a somewhat realistic message length. string=7e3b3b2aaeff56a7108fe11e154200dd/7819479873059528190 status=32768 duration=23000000000 time=1651363200 error=fail\n"
diff --git a/contrib/go/_std_1.21/src/log/slog/internal/benchmarks/handlers.go b/contrib/go/_std_1.21/src/log/slog/internal/benchmarks/handlers.go
new file mode 100644
index 0000000000..091e2ddcca
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/internal/benchmarks/handlers.go
@@ -0,0 +1,148 @@
+// Copyright 2022 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 benchmarks
+
+// Handlers for benchmarking.
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "log/slog"
+ "log/slog/internal/buffer"
+ "strconv"
+ "time"
+)
+
+// A fastTextHandler writes a Record to an io.Writer in a format similar to
+// slog.TextHandler, but without quoting or locking. It has a few other
+// performance-motivated shortcuts, like writing times as seconds since the
+// epoch instead of strings.
+//
+// It is intended to represent a high-performance Handler that synchronously
+// writes text (as opposed to binary).
+type fastTextHandler struct {
+ w io.Writer
+}
+
+func newFastTextHandler(w io.Writer) slog.Handler {
+ return &fastTextHandler{w: w}
+}
+
+func (h *fastTextHandler) Enabled(context.Context, slog.Level) bool { return true }
+
+func (h *fastTextHandler) Handle(_ context.Context, r slog.Record) error {
+ buf := buffer.New()
+ defer buf.Free()
+
+ if !r.Time.IsZero() {
+ buf.WriteString("time=")
+ h.appendTime(buf, r.Time)
+ buf.WriteByte(' ')
+ }
+ buf.WriteString("level=")
+ *buf = strconv.AppendInt(*buf, int64(r.Level), 10)
+ buf.WriteByte(' ')
+ buf.WriteString("msg=")
+ buf.WriteString(r.Message)
+ r.Attrs(func(a slog.Attr) bool {
+ buf.WriteByte(' ')
+ buf.WriteString(a.Key)
+ buf.WriteByte('=')
+ h.appendValue(buf, a.Value)
+ return true
+ })
+ buf.WriteByte('\n')
+ _, err := h.w.Write(*buf)
+ return err
+}
+
+func (h *fastTextHandler) appendValue(buf *buffer.Buffer, v slog.Value) {
+ switch v.Kind() {
+ case slog.KindString:
+ buf.WriteString(v.String())
+ case slog.KindInt64:
+ *buf = strconv.AppendInt(*buf, v.Int64(), 10)
+ case slog.KindUint64:
+ *buf = strconv.AppendUint(*buf, v.Uint64(), 10)
+ case slog.KindFloat64:
+ *buf = strconv.AppendFloat(*buf, v.Float64(), 'g', -1, 64)
+ case slog.KindBool:
+ *buf = strconv.AppendBool(*buf, v.Bool())
+ case slog.KindDuration:
+ *buf = strconv.AppendInt(*buf, v.Duration().Nanoseconds(), 10)
+ case slog.KindTime:
+ h.appendTime(buf, v.Time())
+ case slog.KindAny:
+ a := v.Any()
+ switch a := a.(type) {
+ case error:
+ buf.WriteString(a.Error())
+ default:
+ fmt.Fprint(buf, a)
+ }
+ default:
+ panic(fmt.Sprintf("bad kind: %s", v.Kind()))
+ }
+}
+
+func (h *fastTextHandler) appendTime(buf *buffer.Buffer, t time.Time) {
+ *buf = strconv.AppendInt(*buf, t.Unix(), 10)
+}
+
+func (h *fastTextHandler) WithAttrs([]slog.Attr) slog.Handler {
+ panic("fastTextHandler: With unimplemented")
+}
+
+func (*fastTextHandler) WithGroup(string) slog.Handler {
+ panic("fastTextHandler: WithGroup unimplemented")
+}
+
+// An asyncHandler simulates a Handler that passes Records to a
+// background goroutine for processing.
+// Because sending to a channel can be expensive due to locking,
+// we simulate a lock-free queue by adding the Record to a ring buffer.
+// Omitting the locking makes this little more than a copy of the Record,
+// but that is a worthwhile thing to measure because Records are on the large
+// side. Since nothing actually reads from the ring buffer, it can handle an
+// arbitrary number of Records without either blocking or allocation.
+type asyncHandler struct {
+ ringBuffer [100]slog.Record
+ next int
+}
+
+func newAsyncHandler() *asyncHandler {
+ return &asyncHandler{}
+}
+
+func (*asyncHandler) Enabled(context.Context, slog.Level) bool { return true }
+
+func (h *asyncHandler) Handle(_ context.Context, r slog.Record) error {
+ h.ringBuffer[h.next] = r.Clone()
+ h.next = (h.next + 1) % len(h.ringBuffer)
+ return nil
+}
+
+func (*asyncHandler) WithAttrs([]slog.Attr) slog.Handler {
+ panic("asyncHandler: With unimplemented")
+}
+
+func (*asyncHandler) WithGroup(string) slog.Handler {
+ panic("asyncHandler: WithGroup unimplemented")
+}
+
+// A disabledHandler's Enabled method always returns false.
+type disabledHandler struct{}
+
+func (disabledHandler) Enabled(context.Context, slog.Level) bool { return false }
+func (disabledHandler) Handle(context.Context, slog.Record) error { panic("should not be called") }
+
+func (disabledHandler) WithAttrs([]slog.Attr) slog.Handler {
+ panic("disabledHandler: With unimplemented")
+}
+
+func (disabledHandler) WithGroup(string) slog.Handler {
+ panic("disabledHandler: WithGroup unimplemented")
+}
diff --git a/contrib/go/_std_1.21/src/log/slog/internal/benchmarks/ya.make b/contrib/go/_std_1.21/src/log/slog/internal/benchmarks/ya.make
new file mode 100644
index 0000000000..ba4a93789d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/internal/benchmarks/ya.make
@@ -0,0 +1,16 @@
+GO_LIBRARY()
+
+SRCS(
+ benchmarks.go
+ handlers.go
+)
+
+GO_TEST_SRCS(
+ benchmarks_test.go
+ handlers_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/log/slog/internal/buffer/buffer.go b/contrib/go/_std_1.21/src/log/slog/internal/buffer/buffer.go
new file mode 100644
index 0000000000..c4fcefd775
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/internal/buffer/buffer.go
@@ -0,0 +1,84 @@
+// Copyright 2022 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 buffer provides a pool-allocated byte buffer.
+package buffer
+
+import "sync"
+
+// buffer adapted from go/src/fmt/print.go
+type Buffer []byte
+
+// Having an initial size gives a dramatic speedup.
+var bufPool = sync.Pool{
+ New: func() any {
+ b := make([]byte, 0, 1024)
+ return (*Buffer)(&b)
+ },
+}
+
+func New() *Buffer {
+ return bufPool.Get().(*Buffer)
+}
+
+func (b *Buffer) Free() {
+ // To reduce peak allocation, return only smaller buffers to the pool.
+ const maxBufferSize = 16 << 10
+ if cap(*b) <= maxBufferSize {
+ *b = (*b)[:0]
+ bufPool.Put(b)
+ }
+}
+
+func (b *Buffer) Reset() {
+ *b = (*b)[:0]
+}
+
+func (b *Buffer) Write(p []byte) (int, error) {
+ *b = append(*b, p...)
+ return len(p), nil
+}
+
+func (b *Buffer) WriteString(s string) (int, error) {
+ *b = append(*b, s...)
+ return len(s), nil
+}
+
+func (b *Buffer) WriteByte(c byte) error {
+ *b = append(*b, c)
+ return nil
+}
+
+func (b *Buffer) WritePosInt(i int) {
+ b.WritePosIntWidth(i, 0)
+}
+
+// WritePosIntWidth writes non-negative integer i to the buffer, padded on the left
+// by zeroes to the given width. Use a width of 0 to omit padding.
+func (b *Buffer) WritePosIntWidth(i, width int) {
+ // Cheap integer to fixed-width decimal ASCII.
+ // Copied from log/log.go.
+
+ if i < 0 {
+ panic("negative int")
+ }
+
+ // Assemble decimal in reverse order.
+ var bb [20]byte
+ bp := len(bb) - 1
+ for i >= 10 || width > 1 {
+ width--
+ q := i / 10
+ bb[bp] = byte('0' + i - q*10)
+ bp--
+ i = q
+ }
+ // i < 10
+ bb[bp] = byte('0' + i)
+ b.Write(bb[bp:])
+}
+
+func (b *Buffer) String() string {
+ return string(*b)
+}
diff --git a/contrib/go/_std_1.21/src/log/slog/internal/buffer/ya.make b/contrib/go/_std_1.21/src/log/slog/internal/buffer/ya.make
new file mode 100644
index 0000000000..1314fcf7f7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/internal/buffer/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ buffer.go
+)
+
+GO_TEST_SRCS(buffer_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/log/slog/internal/ignorepc.go b/contrib/go/_std_1.21/src/log/slog/internal/ignorepc.go
new file mode 100644
index 0000000000..d1256426ff
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/internal/ignorepc.go
@@ -0,0 +1,9 @@
+// Copyright 2023 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 internal
+
+// If IgnorePC is true, do not invoke runtime.Callers to get the pc.
+// This is solely for benchmarking the slowdown from runtime.Callers.
+var IgnorePC = false
diff --git a/contrib/go/_std_1.21/src/log/slog/internal/slogtest/slogtest.go b/contrib/go/_std_1.21/src/log/slog/internal/slogtest/slogtest.go
new file mode 100644
index 0000000000..d587662844
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/internal/slogtest/slogtest.go
@@ -0,0 +1,18 @@
+// Copyright 2022 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 slogtest contains support functions for testing slog.
+package slogtest
+
+import "log/slog"
+
+// RemoveTime removes the top-level time attribute.
+// It is intended to be used as a ReplaceAttr function,
+// to make example output deterministic.
+func RemoveTime(groups []string, a slog.Attr) slog.Attr {
+ if a.Key == slog.TimeKey && len(groups) == 0 {
+ return slog.Attr{}
+ }
+ return a
+}
diff --git a/contrib/go/_std_1.21/src/log/slog/internal/slogtest/ya.make b/contrib/go/_std_1.21/src/log/slog/internal/slogtest/ya.make
new file mode 100644
index 0000000000..b1f265b22d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/internal/slogtest/ya.make
@@ -0,0 +1,7 @@
+GO_LIBRARY()
+
+SRCS(
+ slogtest.go
+)
+
+END()
diff --git a/contrib/go/_std_1.21/src/log/slog/internal/ya.make b/contrib/go/_std_1.21/src/log/slog/internal/ya.make
new file mode 100644
index 0000000000..68b4426437
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/internal/ya.make
@@ -0,0 +1,13 @@
+GO_LIBRARY()
+
+SRCS(
+ ignorepc.go
+)
+
+END()
+
+RECURSE(
+ benchmarks
+ buffer
+ slogtest
+)
diff --git a/contrib/go/_std_1.21/src/log/slog/json_handler.go b/contrib/go/_std_1.21/src/log/slog/json_handler.go
new file mode 100644
index 0000000000..1c51ab05ff
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/json_handler.go
@@ -0,0 +1,336 @@
+// Copyright 2022 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 slog
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "log/slog/internal/buffer"
+ "strconv"
+ "sync"
+ "time"
+ "unicode/utf8"
+)
+
+// JSONHandler is a Handler that writes Records to an io.Writer as
+// line-delimited JSON objects.
+type JSONHandler struct {
+ *commonHandler
+}
+
+// NewJSONHandler creates a JSONHandler that writes to w,
+// using the given options.
+// If opts is nil, the default options are used.
+func NewJSONHandler(w io.Writer, opts *HandlerOptions) *JSONHandler {
+ if opts == nil {
+ opts = &HandlerOptions{}
+ }
+ return &JSONHandler{
+ &commonHandler{
+ json: true,
+ w: w,
+ opts: *opts,
+ mu: &sync.Mutex{},
+ },
+ }
+}
+
+// Enabled reports whether the handler handles records at the given level.
+// The handler ignores records whose level is lower.
+func (h *JSONHandler) Enabled(_ context.Context, level Level) bool {
+ return h.commonHandler.enabled(level)
+}
+
+// WithAttrs returns a new JSONHandler whose attributes consists
+// of h's attributes followed by attrs.
+func (h *JSONHandler) WithAttrs(attrs []Attr) Handler {
+ return &JSONHandler{commonHandler: h.commonHandler.withAttrs(attrs)}
+}
+
+func (h *JSONHandler) WithGroup(name string) Handler {
+ return &JSONHandler{commonHandler: h.commonHandler.withGroup(name)}
+}
+
+// Handle formats its argument Record as a JSON object on a single line.
+//
+// If the Record's time is zero, the time is omitted.
+// Otherwise, the key is "time"
+// and the value is output as with json.Marshal.
+//
+// If the Record's level is zero, the level is omitted.
+// Otherwise, the key is "level"
+// and the value of [Level.String] is output.
+//
+// If the AddSource option is set and source information is available,
+// the key is "source", and the value is a record of type [Source].
+//
+// The message's key is "msg".
+//
+// To modify these or other attributes, or remove them from the output, use
+// [HandlerOptions.ReplaceAttr].
+//
+// Values are formatted as with an [encoding/json.Encoder] with SetEscapeHTML(false),
+// with two exceptions.
+//
+// First, an Attr whose Value is of type error is formatted as a string, by
+// calling its Error method. Only errors in Attrs receive this special treatment,
+// not errors embedded in structs, slices, maps or other data structures that
+// are processed by the encoding/json package.
+//
+// Second, an encoding failure does not cause Handle to return an error.
+// Instead, the error message is formatted as a string.
+//
+// Each call to Handle results in a single serialized call to io.Writer.Write.
+func (h *JSONHandler) Handle(_ context.Context, r Record) error {
+ return h.commonHandler.handle(r)
+}
+
+// Adapted from time.Time.MarshalJSON to avoid allocation.
+func appendJSONTime(s *handleState, t time.Time) {
+ if y := t.Year(); y < 0 || y >= 10000 {
+ // RFC 3339 is clear that years are 4 digits exactly.
+ // See golang.org/issue/4556#c15 for more discussion.
+ s.appendError(errors.New("time.Time year outside of range [0,9999]"))
+ }
+ s.buf.WriteByte('"')
+ *s.buf = t.AppendFormat(*s.buf, time.RFC3339Nano)
+ s.buf.WriteByte('"')
+}
+
+func appendJSONValue(s *handleState, v Value) error {
+ switch v.Kind() {
+ case KindString:
+ s.appendString(v.str())
+ case KindInt64:
+ *s.buf = strconv.AppendInt(*s.buf, v.Int64(), 10)
+ case KindUint64:
+ *s.buf = strconv.AppendUint(*s.buf, v.Uint64(), 10)
+ case KindFloat64:
+ // json.Marshal is funny about floats; it doesn't
+ // always match strconv.AppendFloat. So just call it.
+ // That's expensive, but floats are rare.
+ if err := appendJSONMarshal(s.buf, v.Float64()); err != nil {
+ return err
+ }
+ case KindBool:
+ *s.buf = strconv.AppendBool(*s.buf, v.Bool())
+ case KindDuration:
+ // Do what json.Marshal does.
+ *s.buf = strconv.AppendInt(*s.buf, int64(v.Duration()), 10)
+ case KindTime:
+ s.appendTime(v.Time())
+ case KindAny:
+ a := v.Any()
+ _, jm := a.(json.Marshaler)
+ if err, ok := a.(error); ok && !jm {
+ s.appendString(err.Error())
+ } else {
+ return appendJSONMarshal(s.buf, a)
+ }
+ default:
+ panic(fmt.Sprintf("bad kind: %s", v.Kind()))
+ }
+ return nil
+}
+
+func appendJSONMarshal(buf *buffer.Buffer, v any) error {
+ // Use a json.Encoder to avoid escaping HTML.
+ var bb bytes.Buffer
+ enc := json.NewEncoder(&bb)
+ enc.SetEscapeHTML(false)
+ if err := enc.Encode(v); err != nil {
+ return err
+ }
+ bs := bb.Bytes()
+ buf.Write(bs[:len(bs)-1]) // remove final newline
+ return nil
+}
+
+// appendEscapedJSONString escapes s for JSON and appends it to buf.
+// It does not surround the string in quotation marks.
+//
+// Modified from encoding/json/encode.go:encodeState.string,
+// with escapeHTML set to false.
+func appendEscapedJSONString(buf []byte, s string) []byte {
+ char := func(b byte) { buf = append(buf, b) }
+ str := func(s string) { buf = append(buf, s...) }
+
+ start := 0
+ for i := 0; i < len(s); {
+ if b := s[i]; b < utf8.RuneSelf {
+ if safeSet[b] {
+ i++
+ continue
+ }
+ if start < i {
+ str(s[start:i])
+ }
+ char('\\')
+ switch b {
+ case '\\', '"':
+ char(b)
+ case '\n':
+ char('n')
+ case '\r':
+ char('r')
+ case '\t':
+ char('t')
+ default:
+ // This encodes bytes < 0x20 except for \t, \n and \r.
+ str(`u00`)
+ char(hex[b>>4])
+ char(hex[b&0xF])
+ }
+ i++
+ start = i
+ continue
+ }
+ c, size := utf8.DecodeRuneInString(s[i:])
+ if c == utf8.RuneError && size == 1 {
+ if start < i {
+ str(s[start:i])
+ }
+ str(`\ufffd`)
+ i += size
+ start = i
+ continue
+ }
+ // U+2028 is LINE SEPARATOR.
+ // U+2029 is PARAGRAPH SEPARATOR.
+ // They are both technically valid characters in JSON strings,
+ // but don't work in JSONP, which has to be evaluated as JavaScript,
+ // and can lead to security holes there. It is valid JSON to
+ // escape them, so we do so unconditionally.
+ // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+ if c == '\u2028' || c == '\u2029' {
+ if start < i {
+ str(s[start:i])
+ }
+ str(`\u202`)
+ char(hex[c&0xF])
+ i += size
+ start = i
+ continue
+ }
+ i += size
+ }
+ if start < len(s) {
+ str(s[start:])
+ }
+ return buf
+}
+
+var hex = "0123456789abcdef"
+
+// Copied from encoding/json/tables.go.
+//
+// safeSet holds the value true if the ASCII character with the given array
+// position can be represented inside a JSON string without any further
+// escaping.
+//
+// All values are true except for the ASCII control characters (0-31), the
+// double quote ("), and the backslash character ("\").
+var safeSet = [utf8.RuneSelf]bool{
+ ' ': true,
+ '!': true,
+ '"': false,
+ '#': true,
+ '$': true,
+ '%': true,
+ '&': true,
+ '\'': true,
+ '(': true,
+ ')': true,
+ '*': true,
+ '+': true,
+ ',': true,
+ '-': true,
+ '.': true,
+ '/': true,
+ '0': true,
+ '1': true,
+ '2': true,
+ '3': true,
+ '4': true,
+ '5': true,
+ '6': true,
+ '7': true,
+ '8': true,
+ '9': true,
+ ':': true,
+ ';': true,
+ '<': true,
+ '=': true,
+ '>': true,
+ '?': true,
+ '@': true,
+ 'A': true,
+ 'B': true,
+ 'C': true,
+ 'D': true,
+ 'E': true,
+ 'F': true,
+ 'G': true,
+ 'H': true,
+ 'I': true,
+ 'J': true,
+ 'K': true,
+ 'L': true,
+ 'M': true,
+ 'N': true,
+ 'O': true,
+ 'P': true,
+ 'Q': true,
+ 'R': true,
+ 'S': true,
+ 'T': true,
+ 'U': true,
+ 'V': true,
+ 'W': true,
+ 'X': true,
+ 'Y': true,
+ 'Z': true,
+ '[': true,
+ '\\': false,
+ ']': true,
+ '^': true,
+ '_': true,
+ '`': true,
+ 'a': true,
+ 'b': true,
+ 'c': true,
+ 'd': true,
+ 'e': true,
+ 'f': true,
+ 'g': true,
+ 'h': true,
+ 'i': true,
+ 'j': true,
+ 'k': true,
+ 'l': true,
+ 'm': true,
+ 'n': true,
+ 'o': true,
+ 'p': true,
+ 'q': true,
+ 'r': true,
+ 's': true,
+ 't': true,
+ 'u': true,
+ 'v': true,
+ 'w': true,
+ 'x': true,
+ 'y': true,
+ 'z': true,
+ '{': true,
+ '|': true,
+ '}': true,
+ '~': true,
+ '\u007f': true,
+}
diff --git a/contrib/go/_std_1.21/src/log/slog/level.go b/contrib/go/_std_1.21/src/log/slog/level.go
new file mode 100644
index 0000000000..cd1213af64
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/level.go
@@ -0,0 +1,200 @@
+// Copyright 2022 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 slog
+
+import (
+ "errors"
+ "fmt"
+ "strconv"
+ "strings"
+ "sync/atomic"
+)
+
+// A Level is the importance or severity of a log event.
+// The higher the level, the more important or severe the event.
+type Level int
+
+// Level numbers are inherently arbitrary,
+// but we picked them to satisfy three constraints.
+// Any system can map them to another numbering scheme if it wishes.
+//
+// First, we wanted the default level to be Info, Since Levels are ints, Info is
+// the default value for int, zero.
+//
+// Second, we wanted to make it easy to use levels to specify logger verbosity.
+// Since a larger level means a more severe event, a logger that accepts events
+// with smaller (or more negative) level means a more verbose logger. Logger
+// verbosity is thus the negation of event severity, and the default verbosity
+// of 0 accepts all events at least as severe as INFO.
+//
+// Third, we wanted some room between levels to accommodate schemes with named
+// levels between ours. For example, Google Cloud Logging defines a Notice level
+// between Info and Warn. Since there are only a few of these intermediate
+// levels, the gap between the numbers need not be large. Our gap of 4 matches
+// OpenTelemetry's mapping. Subtracting 9 from an OpenTelemetry level in the
+// DEBUG, INFO, WARN and ERROR ranges converts it to the corresponding slog
+// Level range. OpenTelemetry also has the names TRACE and FATAL, which slog
+// does not. But those OpenTelemetry levels can still be represented as slog
+// Levels by using the appropriate integers.
+//
+// Names for common levels.
+const (
+ LevelDebug Level = -4
+ LevelInfo Level = 0
+ LevelWarn Level = 4
+ LevelError Level = 8
+)
+
+// String returns a name for the level.
+// If the level has a name, then that name
+// in uppercase is returned.
+// If the level is between named values, then
+// an integer is appended to the uppercased name.
+// Examples:
+//
+// LevelWarn.String() => "WARN"
+// (LevelInfo+2).String() => "INFO+2"
+func (l Level) String() string {
+ str := func(base string, val Level) string {
+ if val == 0 {
+ return base
+ }
+ return fmt.Sprintf("%s%+d", base, val)
+ }
+
+ switch {
+ case l < LevelInfo:
+ return str("DEBUG", l-LevelDebug)
+ case l < LevelWarn:
+ return str("INFO", l-LevelInfo)
+ case l < LevelError:
+ return str("WARN", l-LevelWarn)
+ default:
+ return str("ERROR", l-LevelError)
+ }
+}
+
+// MarshalJSON implements [encoding/json.Marshaler]
+// by quoting the output of [Level.String].
+func (l Level) MarshalJSON() ([]byte, error) {
+ // AppendQuote is sufficient for JSON-encoding all Level strings.
+ // They don't contain any runes that would produce invalid JSON
+ // when escaped.
+ return strconv.AppendQuote(nil, l.String()), nil
+}
+
+// UnmarshalJSON implements [encoding/json.Unmarshaler]
+// It accepts any string produced by [Level.MarshalJSON],
+// ignoring case.
+// It also accepts numeric offsets that would result in a different string on
+// output. For example, "Error-8" would marshal as "INFO".
+func (l *Level) UnmarshalJSON(data []byte) error {
+ s, err := strconv.Unquote(string(data))
+ if err != nil {
+ return err
+ }
+ return l.parse(s)
+}
+
+// MarshalText implements [encoding.TextMarshaler]
+// by calling [Level.String].
+func (l Level) MarshalText() ([]byte, error) {
+ return []byte(l.String()), nil
+}
+
+// UnmarshalText implements [encoding.TextUnmarshaler].
+// It accepts any string produced by [Level.MarshalText],
+// ignoring case.
+// It also accepts numeric offsets that would result in a different string on
+// output. For example, "Error-8" would marshal as "INFO".
+func (l *Level) UnmarshalText(data []byte) error {
+ return l.parse(string(data))
+}
+
+func (l *Level) parse(s string) (err error) {
+ defer func() {
+ if err != nil {
+ err = fmt.Errorf("slog: level string %q: %w", s, err)
+ }
+ }()
+
+ name := s
+ offset := 0
+ if i := strings.IndexAny(s, "+-"); i >= 0 {
+ name = s[:i]
+ offset, err = strconv.Atoi(s[i:])
+ if err != nil {
+ return err
+ }
+ }
+ switch strings.ToUpper(name) {
+ case "DEBUG":
+ *l = LevelDebug
+ case "INFO":
+ *l = LevelInfo
+ case "WARN":
+ *l = LevelWarn
+ case "ERROR":
+ *l = LevelError
+ default:
+ return errors.New("unknown name")
+ }
+ *l += Level(offset)
+ return nil
+}
+
+// Level returns the receiver.
+// It implements Leveler.
+func (l Level) Level() Level { return l }
+
+// A LevelVar is a Level variable, to allow a Handler level to change
+// dynamically.
+// It implements Leveler as well as a Set method,
+// and it is safe for use by multiple goroutines.
+// The zero LevelVar corresponds to LevelInfo.
+type LevelVar struct {
+ val atomic.Int64
+}
+
+// Level returns v's level.
+func (v *LevelVar) Level() Level {
+ return Level(int(v.val.Load()))
+}
+
+// Set sets v's level to l.
+func (v *LevelVar) Set(l Level) {
+ v.val.Store(int64(l))
+}
+
+func (v *LevelVar) String() string {
+ return fmt.Sprintf("LevelVar(%s)", v.Level())
+}
+
+// MarshalText implements [encoding.TextMarshaler]
+// by calling [Level.MarshalText].
+func (v *LevelVar) MarshalText() ([]byte, error) {
+ return v.Level().MarshalText()
+}
+
+// UnmarshalText implements [encoding.TextUnmarshaler]
+// by calling [Level.UnmarshalText].
+func (v *LevelVar) UnmarshalText(data []byte) error {
+ var l Level
+ if err := l.UnmarshalText(data); err != nil {
+ return err
+ }
+ v.Set(l)
+ return nil
+}
+
+// A Leveler provides a Level value.
+//
+// As Level itself implements Leveler, clients typically supply
+// a Level value wherever a Leveler is needed, such as in HandlerOptions.
+// Clients who need to vary the level dynamically can provide a more complex
+// Leveler implementation such as *LevelVar.
+type Leveler interface {
+ Level() Level
+}
diff --git a/contrib/go/_std_1.21/src/log/slog/logger.go b/contrib/go/_std_1.21/src/log/slog/logger.go
new file mode 100644
index 0000000000..a068085f47
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/logger.go
@@ -0,0 +1,296 @@
+// Copyright 2022 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 slog
+
+import (
+ "context"
+ "log"
+ loginternal "log/internal"
+ "log/slog/internal"
+ "runtime"
+ "sync/atomic"
+ "time"
+)
+
+var defaultLogger atomic.Value
+
+func init() {
+ defaultLogger.Store(New(newDefaultHandler(loginternal.DefaultOutput)))
+}
+
+// Default returns the default Logger.
+func Default() *Logger { return defaultLogger.Load().(*Logger) }
+
+// SetDefault makes l the default Logger.
+// After this call, output from the log package's default Logger
+// (as with [log.Print], etc.) will be logged at LevelInfo using l's Handler.
+func SetDefault(l *Logger) {
+ defaultLogger.Store(l)
+ // If the default's handler is a defaultHandler, then don't use a handleWriter,
+ // or we'll deadlock as they both try to acquire the log default mutex.
+ // The defaultHandler will use whatever the log default writer is currently
+ // set to, which is correct.
+ // This can occur with SetDefault(Default()).
+ // See TestSetDefault.
+ if _, ok := l.Handler().(*defaultHandler); !ok {
+ capturePC := log.Flags()&(log.Lshortfile|log.Llongfile) != 0
+ log.SetOutput(&handlerWriter{l.Handler(), LevelInfo, capturePC})
+ log.SetFlags(0) // we want just the log message, no time or location
+ }
+}
+
+// handlerWriter is an io.Writer that calls a Handler.
+// It is used to link the default log.Logger to the default slog.Logger.
+type handlerWriter struct {
+ h Handler
+ level Level
+ capturePC bool
+}
+
+func (w *handlerWriter) Write(buf []byte) (int, error) {
+ if !w.h.Enabled(context.Background(), w.level) {
+ return 0, nil
+ }
+ var pc uintptr
+ if !internal.IgnorePC && w.capturePC {
+ // skip [runtime.Callers, w.Write, Logger.Output, log.Print]
+ var pcs [1]uintptr
+ runtime.Callers(4, pcs[:])
+ pc = pcs[0]
+ }
+
+ // Remove final newline.
+ origLen := len(buf) // Report that the entire buf was written.
+ if len(buf) > 0 && buf[len(buf)-1] == '\n' {
+ buf = buf[:len(buf)-1]
+ }
+ r := NewRecord(time.Now(), w.level, string(buf), pc)
+ return origLen, w.h.Handle(context.Background(), r)
+}
+
+// A Logger records structured information about each call to its
+// Log, Debug, Info, Warn, and Error methods.
+// For each call, it creates a Record and passes it to a Handler.
+//
+// To create a new Logger, call [New] or a Logger method
+// that begins "With".
+type Logger struct {
+ handler Handler // for structured logging
+}
+
+func (l *Logger) clone() *Logger {
+ c := *l
+ return &c
+}
+
+// Handler returns l's Handler.
+func (l *Logger) Handler() Handler { return l.handler }
+
+// With returns a Logger that includes the given attributes
+// in each output operation. Arguments are converted to
+// attributes as if by [Logger.Log].
+func (l *Logger) With(args ...any) *Logger {
+ if len(args) == 0 {
+ return l
+ }
+ c := l.clone()
+ c.handler = l.handler.WithAttrs(argsToAttrSlice(args))
+ return c
+}
+
+// WithGroup returns a Logger that starts a group, if name is non-empty.
+// The keys of all attributes added to the Logger will be qualified by the given
+// name. (How that qualification happens depends on the [Handler.WithGroup]
+// method of the Logger's Handler.)
+//
+// If name is empty, WithGroup returns the receiver.
+func (l *Logger) WithGroup(name string) *Logger {
+ if name == "" {
+ return l
+ }
+ c := l.clone()
+ c.handler = l.handler.WithGroup(name)
+ return c
+
+}
+
+// New creates a new Logger with the given non-nil Handler.
+func New(h Handler) *Logger {
+ if h == nil {
+ panic("nil Handler")
+ }
+ return &Logger{handler: h}
+}
+
+// With calls Logger.With on the default logger.
+func With(args ...any) *Logger {
+ return Default().With(args...)
+}
+
+// Enabled reports whether l emits log records at the given context and level.
+func (l *Logger) Enabled(ctx context.Context, level Level) bool {
+ if ctx == nil {
+ ctx = context.Background()
+ }
+ return l.Handler().Enabled(ctx, level)
+}
+
+// NewLogLogger returns a new log.Logger such that each call to its Output method
+// dispatches a Record to the specified handler. The logger acts as a bridge from
+// the older log API to newer structured logging handlers.
+func NewLogLogger(h Handler, level Level) *log.Logger {
+ return log.New(&handlerWriter{h, level, true}, "", 0)
+}
+
+// Log emits a log record with the current time and the given level and message.
+// The Record's Attrs consist of the Logger's attributes followed by
+// the Attrs specified by args.
+//
+// The attribute arguments are processed as follows:
+// - If an argument is an Attr, it is used as is.
+// - If an argument is a string and this is not the last argument,
+// the following argument is treated as the value and the two are combined
+// into an Attr.
+// - Otherwise, the argument is treated as a value with key "!BADKEY".
+func (l *Logger) Log(ctx context.Context, level Level, msg string, args ...any) {
+ l.log(ctx, level, msg, args...)
+}
+
+// LogAttrs is a more efficient version of [Logger.Log] that accepts only Attrs.
+func (l *Logger) LogAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) {
+ l.logAttrs(ctx, level, msg, attrs...)
+}
+
+// Debug logs at LevelDebug.
+func (l *Logger) Debug(msg string, args ...any) {
+ l.log(context.Background(), LevelDebug, msg, args...)
+}
+
+// DebugContext logs at LevelDebug with the given context.
+func (l *Logger) DebugContext(ctx context.Context, msg string, args ...any) {
+ l.log(ctx, LevelDebug, msg, args...)
+}
+
+// Info logs at LevelInfo.
+func (l *Logger) Info(msg string, args ...any) {
+ l.log(context.Background(), LevelInfo, msg, args...)
+}
+
+// InfoContext logs at LevelInfo with the given context.
+func (l *Logger) InfoContext(ctx context.Context, msg string, args ...any) {
+ l.log(ctx, LevelInfo, msg, args...)
+}
+
+// Warn logs at LevelWarn.
+func (l *Logger) Warn(msg string, args ...any) {
+ l.log(context.Background(), LevelWarn, msg, args...)
+}
+
+// WarnContext logs at LevelWarn with the given context.
+func (l *Logger) WarnContext(ctx context.Context, msg string, args ...any) {
+ l.log(ctx, LevelWarn, msg, args...)
+}
+
+// Error logs at LevelError.
+func (l *Logger) Error(msg string, args ...any) {
+ l.log(context.Background(), LevelError, msg, args...)
+}
+
+// ErrorContext logs at LevelError with the given context.
+func (l *Logger) ErrorContext(ctx context.Context, msg string, args ...any) {
+ l.log(ctx, LevelError, msg, args...)
+}
+
+// log is the low-level logging method for methods that take ...any.
+// It must always be called directly by an exported logging method
+// or function, because it uses a fixed call depth to obtain the pc.
+func (l *Logger) log(ctx context.Context, level Level, msg string, args ...any) {
+ if !l.Enabled(ctx, level) {
+ return
+ }
+ var pc uintptr
+ if !internal.IgnorePC {
+ var pcs [1]uintptr
+ // skip [runtime.Callers, this function, this function's caller]
+ runtime.Callers(3, pcs[:])
+ pc = pcs[0]
+ }
+ r := NewRecord(time.Now(), level, msg, pc)
+ r.Add(args...)
+ if ctx == nil {
+ ctx = context.Background()
+ }
+ _ = l.Handler().Handle(ctx, r)
+}
+
+// logAttrs is like [Logger.log], but for methods that take ...Attr.
+func (l *Logger) logAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) {
+ if !l.Enabled(ctx, level) {
+ return
+ }
+ var pc uintptr
+ if !internal.IgnorePC {
+ var pcs [1]uintptr
+ // skip [runtime.Callers, this function, this function's caller]
+ runtime.Callers(3, pcs[:])
+ pc = pcs[0]
+ }
+ r := NewRecord(time.Now(), level, msg, pc)
+ r.AddAttrs(attrs...)
+ if ctx == nil {
+ ctx = context.Background()
+ }
+ _ = l.Handler().Handle(ctx, r)
+}
+
+// Debug calls Logger.Debug on the default logger.
+func Debug(msg string, args ...any) {
+ Default().log(context.Background(), LevelDebug, msg, args...)
+}
+
+// DebugContext calls Logger.DebugContext on the default logger.
+func DebugContext(ctx context.Context, msg string, args ...any) {
+ Default().log(ctx, LevelDebug, msg, args...)
+}
+
+// Info calls Logger.Info on the default logger.
+func Info(msg string, args ...any) {
+ Default().log(context.Background(), LevelInfo, msg, args...)
+}
+
+// InfoContext calls Logger.InfoContext on the default logger.
+func InfoContext(ctx context.Context, msg string, args ...any) {
+ Default().log(ctx, LevelInfo, msg, args...)
+}
+
+// Warn calls Logger.Warn on the default logger.
+func Warn(msg string, args ...any) {
+ Default().log(context.Background(), LevelWarn, msg, args...)
+}
+
+// WarnContext calls Logger.WarnContext on the default logger.
+func WarnContext(ctx context.Context, msg string, args ...any) {
+ Default().log(ctx, LevelWarn, msg, args...)
+}
+
+// Error calls Logger.Error on the default logger.
+func Error(msg string, args ...any) {
+ Default().log(context.Background(), LevelError, msg, args...)
+}
+
+// ErrorContext calls Logger.ErrorContext on the default logger.
+func ErrorContext(ctx context.Context, msg string, args ...any) {
+ Default().log(ctx, LevelError, msg, args...)
+}
+
+// Log calls Logger.Log on the default logger.
+func Log(ctx context.Context, level Level, msg string, args ...any) {
+ Default().log(ctx, level, msg, args...)
+}
+
+// LogAttrs calls Logger.LogAttrs on the default logger.
+func LogAttrs(ctx context.Context, level Level, msg string, attrs ...Attr) {
+ Default().logAttrs(ctx, level, msg, attrs...)
+}
diff --git a/contrib/go/_std_1.21/src/log/slog/record.go b/contrib/go/_std_1.21/src/log/slog/record.go
new file mode 100644
index 0000000000..67b76f34e1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/record.go
@@ -0,0 +1,225 @@
+// Copyright 2022 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 slog
+
+import (
+ "runtime"
+ "slices"
+ "time"
+)
+
+const nAttrsInline = 5
+
+// A Record holds information about a log event.
+// Copies of a Record share state.
+// Do not modify a Record after handing out a copy to it.
+// Call [NewRecord] to create a new Record.
+// Use [Record.Clone] to create a copy with no shared state.
+type Record struct {
+ // The time at which the output method (Log, Info, etc.) was called.
+ Time time.Time
+
+ // The log message.
+ Message string
+
+ // The level of the event.
+ Level Level
+
+ // The program counter at the time the record was constructed, as determined
+ // by runtime.Callers. If zero, no program counter is available.
+ //
+ // The only valid use for this value is as an argument to
+ // [runtime.CallersFrames]. In particular, it must not be passed to
+ // [runtime.FuncForPC].
+ PC uintptr
+
+ // Allocation optimization: an inline array sized to hold
+ // the majority of log calls (based on examination of open-source
+ // code). It holds the start of the list of Attrs.
+ front [nAttrsInline]Attr
+
+ // The number of Attrs in front.
+ nFront int
+
+ // The list of Attrs except for those in front.
+ // Invariants:
+ // - len(back) > 0 iff nFront == len(front)
+ // - Unused array elements are zero. Used to detect mistakes.
+ back []Attr
+}
+
+// NewRecord creates a Record from the given arguments.
+// Use [Record.AddAttrs] to add attributes to the Record.
+//
+// NewRecord is intended for logging APIs that want to support a [Handler] as
+// a backend.
+func NewRecord(t time.Time, level Level, msg string, pc uintptr) Record {
+ return Record{
+ Time: t,
+ Message: msg,
+ Level: level,
+ PC: pc,
+ }
+}
+
+// Clone returns a copy of the record with no shared state.
+// The original record and the clone can both be modified
+// without interfering with each other.
+func (r Record) Clone() Record {
+ r.back = slices.Clip(r.back) // prevent append from mutating shared array
+ return r
+}
+
+// NumAttrs returns the number of attributes in the Record.
+func (r Record) NumAttrs() int {
+ return r.nFront + len(r.back)
+}
+
+// Attrs calls f on each Attr in the Record.
+// Iteration stops if f returns false.
+func (r Record) Attrs(f func(Attr) bool) {
+ for i := 0; i < r.nFront; i++ {
+ if !f(r.front[i]) {
+ return
+ }
+ }
+ for _, a := range r.back {
+ if !f(a) {
+ return
+ }
+ }
+}
+
+// AddAttrs appends the given Attrs to the Record's list of Attrs.
+// It omits empty groups.
+func (r *Record) AddAttrs(attrs ...Attr) {
+ var i int
+ for i = 0; i < len(attrs) && r.nFront < len(r.front); i++ {
+ a := attrs[i]
+ if a.Value.isEmptyGroup() {
+ continue
+ }
+ r.front[r.nFront] = a
+ r.nFront++
+ }
+ // Check if a copy was modified by slicing past the end
+ // and seeing if the Attr there is non-zero.
+ if cap(r.back) > len(r.back) {
+ end := r.back[:len(r.back)+1][len(r.back)]
+ if !end.isEmpty() {
+ panic("copies of a slog.Record were both modified")
+ }
+ }
+ ne := countEmptyGroups(attrs[i:])
+ r.back = slices.Grow(r.back, len(attrs[i:])-ne)
+ for _, a := range attrs[i:] {
+ if !a.Value.isEmptyGroup() {
+ r.back = append(r.back, a)
+ }
+ }
+}
+
+// Add converts the args to Attrs as described in [Logger.Log],
+// then appends the Attrs to the Record's list of Attrs.
+// It omits empty groups.
+func (r *Record) Add(args ...any) {
+ var a Attr
+ for len(args) > 0 {
+ a, args = argsToAttr(args)
+ if a.Value.isEmptyGroup() {
+ continue
+ }
+ if r.nFront < len(r.front) {
+ r.front[r.nFront] = a
+ r.nFront++
+ } else {
+ if r.back == nil {
+ r.back = make([]Attr, 0, countAttrs(args))
+ }
+ r.back = append(r.back, a)
+ }
+ }
+
+}
+
+// countAttrs returns the number of Attrs that would be created from args.
+func countAttrs(args []any) int {
+ n := 0
+ for i := 0; i < len(args); i++ {
+ n++
+ if _, ok := args[i].(string); ok {
+ i++
+ }
+ }
+ return n
+}
+
+const badKey = "!BADKEY"
+
+// argsToAttr turns a prefix of the nonempty args slice into an Attr
+// and returns the unconsumed portion of the slice.
+// If args[0] is an Attr, it returns it.
+// If args[0] is a string, it treats the first two elements as
+// a key-value pair.
+// Otherwise, it treats args[0] as a value with a missing key.
+func argsToAttr(args []any) (Attr, []any) {
+ switch x := args[0].(type) {
+ case string:
+ if len(args) == 1 {
+ return String(badKey, x), nil
+ }
+ return Any(x, args[1]), args[2:]
+
+ case Attr:
+ return x, args[1:]
+
+ default:
+ return Any(badKey, x), args[1:]
+ }
+}
+
+// Source describes the location of a line of source code.
+type Source struct {
+ // Function is the package path-qualified function name containing the
+ // source line. If non-empty, this string uniquely identifies a single
+ // function in the program. This may be the empty string if not known.
+ Function string `json:"function"`
+ // File and Line are the file name and line number (1-based) of the source
+ // line. These may be the empty string and zero, respectively, if not known.
+ File string `json:"file"`
+ Line int `json:"line"`
+}
+
+// attrs returns the non-zero fields of s as a slice of attrs.
+// It is similar to a LogValue method, but we don't want Source
+// to implement LogValuer because it would be resolved before
+// the ReplaceAttr function was called.
+func (s *Source) group() Value {
+ var as []Attr
+ if s.Function != "" {
+ as = append(as, String("function", s.Function))
+ }
+ if s.File != "" {
+ as = append(as, String("file", s.File))
+ }
+ if s.Line != 0 {
+ as = append(as, Int("line", s.Line))
+ }
+ return GroupValue(as...)
+}
+
+// source returns a Source for the log event.
+// If the Record was created without the necessary information,
+// or if the location is unavailable, it returns a non-nil *Source
+// with zero fields.
+func (r Record) source() *Source {
+ fs := runtime.CallersFrames([]uintptr{r.PC})
+ f, _ := fs.Next()
+ return &Source{
+ Function: f.Function,
+ File: f.File,
+ Line: f.Line,
+ }
+}
diff --git a/contrib/go/_std_1.21/src/log/slog/text_handler.go b/contrib/go/_std_1.21/src/log/slog/text_handler.go
new file mode 100644
index 0000000000..58edb2f66d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/text_handler.go
@@ -0,0 +1,163 @@
+// Copyright 2022 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 slog
+
+import (
+ "context"
+ "encoding"
+ "fmt"
+ "io"
+ "reflect"
+ "strconv"
+ "sync"
+ "unicode"
+ "unicode/utf8"
+)
+
+// TextHandler is a Handler that writes Records to an io.Writer as a
+// sequence of key=value pairs separated by spaces and followed by a newline.
+type TextHandler struct {
+ *commonHandler
+}
+
+// NewTextHandler creates a TextHandler that writes to w,
+// using the given options.
+// If opts is nil, the default options are used.
+func NewTextHandler(w io.Writer, opts *HandlerOptions) *TextHandler {
+ if opts == nil {
+ opts = &HandlerOptions{}
+ }
+ return &TextHandler{
+ &commonHandler{
+ json: false,
+ w: w,
+ opts: *opts,
+ mu: &sync.Mutex{},
+ },
+ }
+}
+
+// Enabled reports whether the handler handles records at the given level.
+// The handler ignores records whose level is lower.
+func (h *TextHandler) Enabled(_ context.Context, level Level) bool {
+ return h.commonHandler.enabled(level)
+}
+
+// WithAttrs returns a new TextHandler whose attributes consists
+// of h's attributes followed by attrs.
+func (h *TextHandler) WithAttrs(attrs []Attr) Handler {
+ return &TextHandler{commonHandler: h.commonHandler.withAttrs(attrs)}
+}
+
+func (h *TextHandler) WithGroup(name string) Handler {
+ return &TextHandler{commonHandler: h.commonHandler.withGroup(name)}
+}
+
+// Handle formats its argument Record as a single line of space-separated
+// key=value items.
+//
+// If the Record's time is zero, the time is omitted.
+// Otherwise, the key is "time"
+// and the value is output in RFC3339 format with millisecond precision.
+//
+// If the Record's level is zero, the level is omitted.
+// Otherwise, the key is "level"
+// and the value of [Level.String] is output.
+//
+// If the AddSource option is set and source information is available,
+// the key is "source" and the value is output as FILE:LINE.
+//
+// The message's key is "msg".
+//
+// To modify these or other attributes, or remove them from the output, use
+// [HandlerOptions.ReplaceAttr].
+//
+// If a value implements [encoding.TextMarshaler], the result of MarshalText is
+// written. Otherwise, the result of fmt.Sprint is written.
+//
+// Keys and values are quoted with [strconv.Quote] if they contain Unicode space
+// characters, non-printing characters, '"' or '='.
+//
+// Keys inside groups consist of components (keys or group names) separated by
+// dots. No further escaping is performed.
+// Thus there is no way to determine from the key "a.b.c" whether there
+// are two groups "a" and "b" and a key "c", or a single group "a.b" and a key "c",
+// or single group "a" and a key "b.c".
+// If it is necessary to reconstruct the group structure of a key
+// even in the presence of dots inside components, use
+// [HandlerOptions.ReplaceAttr] to encode that information in the key.
+//
+// Each call to Handle results in a single serialized call to
+// io.Writer.Write.
+func (h *TextHandler) Handle(_ context.Context, r Record) error {
+ return h.commonHandler.handle(r)
+}
+
+func appendTextValue(s *handleState, v Value) error {
+ switch v.Kind() {
+ case KindString:
+ s.appendString(v.str())
+ case KindTime:
+ s.appendTime(v.time())
+ case KindAny:
+ if tm, ok := v.any.(encoding.TextMarshaler); ok {
+ data, err := tm.MarshalText()
+ if err != nil {
+ return err
+ }
+ // TODO: avoid the conversion to string.
+ s.appendString(string(data))
+ return nil
+ }
+ if bs, ok := byteSlice(v.any); ok {
+ // As of Go 1.19, this only allocates for strings longer than 32 bytes.
+ s.buf.WriteString(strconv.Quote(string(bs)))
+ return nil
+ }
+ s.appendString(fmt.Sprintf("%+v", v.Any()))
+ default:
+ *s.buf = v.append(*s.buf)
+ }
+ return nil
+}
+
+// byteSlice returns its argument as a []byte if the argument's
+// underlying type is []byte, along with a second return value of true.
+// Otherwise it returns nil, false.
+func byteSlice(a any) ([]byte, bool) {
+ if bs, ok := a.([]byte); ok {
+ return bs, true
+ }
+ // Like Printf's %s, we allow both the slice type and the byte element type to be named.
+ t := reflect.TypeOf(a)
+ if t != nil && t.Kind() == reflect.Slice && t.Elem().Kind() == reflect.Uint8 {
+ return reflect.ValueOf(a).Bytes(), true
+ }
+ return nil, false
+}
+
+func needsQuoting(s string) bool {
+ if len(s) == 0 {
+ return true
+ }
+ for i := 0; i < len(s); {
+ b := s[i]
+ if b < utf8.RuneSelf {
+ // Quote anything except a backslash that would need quoting in a
+ // JSON string, as well as space and '='
+ if b != '\\' && (b == ' ' || b == '=' || !safeSet[b]) {
+ return true
+ }
+ i++
+ continue
+ }
+ r, size := utf8.DecodeRuneInString(s[i:])
+ if r == utf8.RuneError || unicode.IsSpace(r) || !unicode.IsPrint(r) {
+ return true
+ }
+ i += size
+ }
+ return false
+}
diff --git a/contrib/go/_std_1.21/src/log/slog/value.go b/contrib/go/_std_1.21/src/log/slog/value.go
new file mode 100644
index 0000000000..224848f695
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/value.go
@@ -0,0 +1,520 @@
+// Copyright 2022 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 slog
+
+import (
+ "fmt"
+ "math"
+ "runtime"
+ "slices"
+ "strconv"
+ "strings"
+ "time"
+ "unsafe"
+)
+
+// A Value can represent any Go value, but unlike type any,
+// it can represent most small values without an allocation.
+// The zero Value corresponds to nil.
+type Value struct {
+ _ [0]func() // disallow ==
+ // num holds the value for Kinds Int64, Uint64, Float64, Bool and Duration,
+ // the string length for KindString, and nanoseconds since the epoch for KindTime.
+ num uint64
+ // If any is of type Kind, then the value is in num as described above.
+ // If any is of type *time.Location, then the Kind is Time and time.Time value
+ // can be constructed from the Unix nanos in num and the location (monotonic time
+ // is not preserved).
+ // If any is of type stringptr, then the Kind is String and the string value
+ // consists of the length in num and the pointer in any.
+ // Otherwise, the Kind is Any and any is the value.
+ // (This implies that Attrs cannot store values of type Kind, *time.Location
+ // or stringptr.)
+ any any
+}
+
+type (
+ stringptr *byte // used in Value.any when the Value is a string
+ groupptr *Attr // used in Value.any when the Value is a []Attr
+)
+
+// Kind is the kind of a Value.
+type Kind int
+
+// The following list is sorted alphabetically, but it's also important that
+// KindAny is 0 so that a zero Value represents nil.
+
+const (
+ KindAny Kind = iota
+ KindBool
+ KindDuration
+ KindFloat64
+ KindInt64
+ KindString
+ KindTime
+ KindUint64
+ KindGroup
+ KindLogValuer
+)
+
+var kindStrings = []string{
+ "Any",
+ "Bool",
+ "Duration",
+ "Float64",
+ "Int64",
+ "String",
+ "Time",
+ "Uint64",
+ "Group",
+ "LogValuer",
+}
+
+func (k Kind) String() string {
+ if k >= 0 && int(k) < len(kindStrings) {
+ return kindStrings[k]
+ }
+ return "<unknown slog.Kind>"
+}
+
+// Unexported version of Kind, just so we can store Kinds in Values.
+// (No user-provided value has this type.)
+type kind Kind
+
+// Kind returns v's Kind.
+func (v Value) Kind() Kind {
+ switch x := v.any.(type) {
+ case Kind:
+ return x
+ case stringptr:
+ return KindString
+ case timeLocation:
+ return KindTime
+ case groupptr:
+ return KindGroup
+ case LogValuer:
+ return KindLogValuer
+ case kind: // a kind is just a wrapper for a Kind
+ return KindAny
+ default:
+ return KindAny
+ }
+}
+
+//////////////// Constructors
+
+// StringValue returns a new Value for a string.
+func StringValue(value string) Value {
+ return Value{num: uint64(len(value)), any: stringptr(unsafe.StringData(value))}
+}
+
+// IntValue returns a Value for an int.
+func IntValue(v int) Value {
+ return Int64Value(int64(v))
+}
+
+// Int64Value returns a Value for an int64.
+func Int64Value(v int64) Value {
+ return Value{num: uint64(v), any: KindInt64}
+}
+
+// Uint64Value returns a Value for a uint64.
+func Uint64Value(v uint64) Value {
+ return Value{num: v, any: KindUint64}
+}
+
+// Float64Value returns a Value for a floating-point number.
+func Float64Value(v float64) Value {
+ return Value{num: math.Float64bits(v), any: KindFloat64}
+}
+
+// BoolValue returns a Value for a bool.
+func BoolValue(v bool) Value {
+ u := uint64(0)
+ if v {
+ u = 1
+ }
+ return Value{num: u, any: KindBool}
+}
+
+// Unexported version of *time.Location, just so we can store *time.Locations in
+// Values. (No user-provided value has this type.)
+type timeLocation *time.Location
+
+// TimeValue returns a Value for a time.Time.
+// It discards the monotonic portion.
+func TimeValue(v time.Time) Value {
+ if v.IsZero() {
+ // UnixNano on the zero time is undefined, so represent the zero time
+ // with a nil *time.Location instead. time.Time.Location method never
+ // returns nil, so a Value with any == timeLocation(nil) cannot be
+ // mistaken for any other Value, time.Time or otherwise.
+ return Value{any: timeLocation(nil)}
+ }
+ return Value{num: uint64(v.UnixNano()), any: timeLocation(v.Location())}
+}
+
+// DurationValue returns a Value for a time.Duration.
+func DurationValue(v time.Duration) Value {
+ return Value{num: uint64(v.Nanoseconds()), any: KindDuration}
+}
+
+// GroupValue returns a new Value for a list of Attrs.
+// The caller must not subsequently mutate the argument slice.
+func GroupValue(as ...Attr) Value {
+ // Remove empty groups.
+ // It is simpler overall to do this at construction than
+ // to check each Group recursively for emptiness.
+ if n := countEmptyGroups(as); n > 0 {
+ as2 := make([]Attr, 0, len(as)-n)
+ for _, a := range as {
+ if !a.Value.isEmptyGroup() {
+ as2 = append(as2, a)
+ }
+ }
+ as = as2
+ }
+ return Value{num: uint64(len(as)), any: groupptr(unsafe.SliceData(as))}
+}
+
+// countEmptyGroups returns the number of empty group values in its argument.
+func countEmptyGroups(as []Attr) int {
+ n := 0
+ for _, a := range as {
+ if a.Value.isEmptyGroup() {
+ n++
+ }
+ }
+ return n
+}
+
+// AnyValue returns a Value for the supplied value.
+//
+// If the supplied value is of type Value, it is returned
+// unmodified.
+//
+// Given a value of one of Go's predeclared string, bool, or
+// (non-complex) numeric types, AnyValue returns a Value of kind
+// String, Bool, Uint64, Int64, or Float64. The width of the
+// original numeric type is not preserved.
+//
+// Given a time.Time or time.Duration value, AnyValue returns a Value of kind
+// KindTime or KindDuration. The monotonic time is not preserved.
+//
+// For nil, or values of all other types, including named types whose
+// underlying type is numeric, AnyValue returns a value of kind KindAny.
+func AnyValue(v any) Value {
+ switch v := v.(type) {
+ case string:
+ return StringValue(v)
+ case int:
+ return Int64Value(int64(v))
+ case uint:
+ return Uint64Value(uint64(v))
+ case int64:
+ return Int64Value(v)
+ case uint64:
+ return Uint64Value(v)
+ case bool:
+ return BoolValue(v)
+ case time.Duration:
+ return DurationValue(v)
+ case time.Time:
+ return TimeValue(v)
+ case uint8:
+ return Uint64Value(uint64(v))
+ case uint16:
+ return Uint64Value(uint64(v))
+ case uint32:
+ return Uint64Value(uint64(v))
+ case uintptr:
+ return Uint64Value(uint64(v))
+ case int8:
+ return Int64Value(int64(v))
+ case int16:
+ return Int64Value(int64(v))
+ case int32:
+ return Int64Value(int64(v))
+ case float64:
+ return Float64Value(v)
+ case float32:
+ return Float64Value(float64(v))
+ case []Attr:
+ return GroupValue(v...)
+ case Kind:
+ return Value{any: kind(v)}
+ case Value:
+ return v
+ default:
+ return Value{any: v}
+ }
+}
+
+//////////////// Accessors
+
+// Any returns v's value as an any.
+func (v Value) Any() any {
+ switch v.Kind() {
+ case KindAny:
+ if k, ok := v.any.(kind); ok {
+ return Kind(k)
+ }
+ return v.any
+ case KindLogValuer:
+ return v.any
+ case KindGroup:
+ return v.group()
+ case KindInt64:
+ return int64(v.num)
+ case KindUint64:
+ return v.num
+ case KindFloat64:
+ return v.float()
+ case KindString:
+ return v.str()
+ case KindBool:
+ return v.bool()
+ case KindDuration:
+ return v.duration()
+ case KindTime:
+ return v.time()
+ default:
+ panic(fmt.Sprintf("bad kind: %s", v.Kind()))
+ }
+}
+
+// String returns Value's value as a string, formatted like fmt.Sprint. Unlike
+// the methods Int64, Float64, and so on, which panic if v is of the
+// wrong kind, String never panics.
+func (v Value) String() string {
+ if sp, ok := v.any.(stringptr); ok {
+ return unsafe.String(sp, v.num)
+ }
+ var buf []byte
+ return string(v.append(buf))
+}
+
+func (v Value) str() string {
+ return unsafe.String(v.any.(stringptr), v.num)
+}
+
+// Int64 returns v's value as an int64. It panics
+// if v is not a signed integer.
+func (v Value) Int64() int64 {
+ if g, w := v.Kind(), KindInt64; g != w {
+ panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
+ }
+ return int64(v.num)
+}
+
+// Uint64 returns v's value as a uint64. It panics
+// if v is not an unsigned integer.
+func (v Value) Uint64() uint64 {
+ if g, w := v.Kind(), KindUint64; g != w {
+ panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
+ }
+ return v.num
+}
+
+// Bool returns v's value as a bool. It panics
+// if v is not a bool.
+func (v Value) Bool() bool {
+ if g, w := v.Kind(), KindBool; g != w {
+ panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
+ }
+ return v.bool()
+}
+
+func (a Value) bool() bool {
+ return a.num == 1
+}
+
+// Duration returns v's value as a time.Duration. It panics
+// if v is not a time.Duration.
+func (a Value) Duration() time.Duration {
+ if g, w := a.Kind(), KindDuration; g != w {
+ panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
+ }
+
+ return a.duration()
+}
+
+func (a Value) duration() time.Duration {
+ return time.Duration(int64(a.num))
+}
+
+// Float64 returns v's value as a float64. It panics
+// if v is not a float64.
+func (v Value) Float64() float64 {
+ if g, w := v.Kind(), KindFloat64; g != w {
+ panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
+ }
+
+ return v.float()
+}
+
+func (a Value) float() float64 {
+ return math.Float64frombits(a.num)
+}
+
+// Time returns v's value as a time.Time. It panics
+// if v is not a time.Time.
+func (v Value) Time() time.Time {
+ if g, w := v.Kind(), KindTime; g != w {
+ panic(fmt.Sprintf("Value kind is %s, not %s", g, w))
+ }
+ return v.time()
+}
+
+func (v Value) time() time.Time {
+ loc := v.any.(timeLocation)
+ if loc == nil {
+ return time.Time{}
+ }
+ return time.Unix(0, int64(v.num)).In(loc)
+}
+
+// LogValuer returns v's value as a LogValuer. It panics
+// if v is not a LogValuer.
+func (v Value) LogValuer() LogValuer {
+ return v.any.(LogValuer)
+}
+
+// Group returns v's value as a []Attr.
+// It panics if v's Kind is not KindGroup.
+func (v Value) Group() []Attr {
+ if sp, ok := v.any.(groupptr); ok {
+ return unsafe.Slice((*Attr)(sp), v.num)
+ }
+ panic("Group: bad kind")
+}
+
+func (v Value) group() []Attr {
+ return unsafe.Slice((*Attr)(v.any.(groupptr)), v.num)
+}
+
+//////////////// Other
+
+// Equal reports whether v and w represent the same Go value.
+func (v Value) Equal(w Value) bool {
+ k1 := v.Kind()
+ k2 := w.Kind()
+ if k1 != k2 {
+ return false
+ }
+ switch k1 {
+ case KindInt64, KindUint64, KindBool, KindDuration:
+ return v.num == w.num
+ case KindString:
+ return v.str() == w.str()
+ case KindFloat64:
+ return v.float() == w.float()
+ case KindTime:
+ return v.time().Equal(w.time())
+ case KindAny, KindLogValuer:
+ return v.any == w.any // may panic if non-comparable
+ case KindGroup:
+ return slices.EqualFunc(v.group(), w.group(), Attr.Equal)
+ default:
+ panic(fmt.Sprintf("bad kind: %s", k1))
+ }
+}
+
+// isEmptyGroup reports whether v is a group that has no attributes.
+func (v Value) isEmptyGroup() bool {
+ if v.Kind() != KindGroup {
+ return false
+ }
+ // We do not need to recursively examine the group's Attrs for emptiness,
+ // because GroupValue removed them when the group was constructed, and
+ // groups are immutable.
+ return len(v.group()) == 0
+}
+
+// append appends a text representation of v to dst.
+// v is formatted as with fmt.Sprint.
+func (v Value) append(dst []byte) []byte {
+ switch v.Kind() {
+ case KindString:
+ return append(dst, v.str()...)
+ case KindInt64:
+ return strconv.AppendInt(dst, int64(v.num), 10)
+ case KindUint64:
+ return strconv.AppendUint(dst, v.num, 10)
+ case KindFloat64:
+ return strconv.AppendFloat(dst, v.float(), 'g', -1, 64)
+ case KindBool:
+ return strconv.AppendBool(dst, v.bool())
+ case KindDuration:
+ return append(dst, v.duration().String()...)
+ case KindTime:
+ return append(dst, v.time().String()...)
+ case KindGroup:
+ return fmt.Append(dst, v.group())
+ case KindAny, KindLogValuer:
+ return fmt.Append(dst, v.any)
+ default:
+ panic(fmt.Sprintf("bad kind: %s", v.Kind()))
+ }
+}
+
+// A LogValuer is any Go value that can convert itself into a Value for logging.
+//
+// This mechanism may be used to defer expensive operations until they are
+// needed, or to expand a single value into a sequence of components.
+type LogValuer interface {
+ LogValue() Value
+}
+
+const maxLogValues = 100
+
+// Resolve repeatedly calls LogValue on v while it implements LogValuer,
+// and returns the result.
+// If v resolves to a group, the group's attributes' values are not recursively
+// resolved.
+// If the number of LogValue calls exceeds a threshold, a Value containing an
+// error is returned.
+// Resolve's return value is guaranteed not to be of Kind KindLogValuer.
+func (v Value) Resolve() (rv Value) {
+ orig := v
+ defer func() {
+ if r := recover(); r != nil {
+ rv = AnyValue(fmt.Errorf("LogValue panicked\n%s", stack(3, 5)))
+ }
+ }()
+
+ for i := 0; i < maxLogValues; i++ {
+ if v.Kind() != KindLogValuer {
+ return v
+ }
+ v = v.LogValuer().LogValue()
+ }
+ err := fmt.Errorf("LogValue called too many times on Value of type %T", orig.Any())
+ return AnyValue(err)
+}
+
+func stack(skip, nFrames int) string {
+ pcs := make([]uintptr, nFrames+1)
+ n := runtime.Callers(skip+1, pcs)
+ if n == 0 {
+ return "(no stack)"
+ }
+ frames := runtime.CallersFrames(pcs[:n])
+ var b strings.Builder
+ i := 0
+ for {
+ frame, more := frames.Next()
+ fmt.Fprintf(&b, "called from %s (%s:%d)\n", frame.Function, frame.File, frame.Line)
+ if !more {
+ break
+ }
+ i++
+ if i >= nFrames {
+ fmt.Fprintf(&b, "(rest of stack elided)\n")
+ break
+ }
+ }
+ return b.String()
+}
diff --git a/contrib/go/_std_1.21/src/log/slog/ya.make b/contrib/go/_std_1.21/src/log/slog/ya.make
new file mode 100644
index 0000000000..f5eb6d4d51
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/slog/ya.make
@@ -0,0 +1,41 @@
+GO_LIBRARY()
+
+SRCS(
+ attr.go
+ doc.go
+ handler.go
+ json_handler.go
+ level.go
+ logger.go
+ record.go
+ text_handler.go
+ value.go
+)
+
+GO_TEST_SRCS(
+ attr_test.go
+ handler_test.go
+ json_handler_test.go
+ level_test.go
+ logger_test.go
+ record_test.go
+ text_handler_test.go
+ value_access_benchmark_test.go
+ value_test.go
+)
+
+GO_XTEST_SRCS(
+ example_custom_levels_test.go
+ example_level_handler_test.go
+ example_logvaluer_group_test.go
+ example_logvaluer_secret_test.go
+ example_test.go
+ example_wrap_test.go
+ slogtest_test.go
+)
+
+END()
+
+RECURSE(
+ internal
+)
diff --git a/contrib/go/_std_1.20/src/log/syslog/doc.go b/contrib/go/_std_1.21/src/log/syslog/doc.go
index 9a33eeb5d5..9a33eeb5d5 100644
--- a/contrib/go/_std_1.20/src/log/syslog/doc.go
+++ b/contrib/go/_std_1.21/src/log/syslog/doc.go
diff --git a/contrib/go/_std_1.20/src/log/syslog/syslog.go b/contrib/go/_std_1.21/src/log/syslog/syslog.go
index 03e5263d3e..03e5263d3e 100644
--- a/contrib/go/_std_1.20/src/log/syslog/syslog.go
+++ b/contrib/go/_std_1.21/src/log/syslog/syslog.go
diff --git a/contrib/go/_std_1.20/src/log/syslog/syslog_unix.go b/contrib/go/_std_1.21/src/log/syslog/syslog_unix.go
index f9cdcdc273..f9cdcdc273 100644
--- a/contrib/go/_std_1.20/src/log/syslog/syslog_unix.go
+++ b/contrib/go/_std_1.21/src/log/syslog/syslog_unix.go
diff --git a/contrib/go/_std_1.21/src/log/syslog/ya.make b/contrib/go/_std_1.21/src/log/syslog/ya.make
new file mode 100644
index 0000000000..1c4f5fd321
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/syslog/ya.make
@@ -0,0 +1,32 @@
+GO_LIBRARY()
+
+SRCS(
+ doc.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ syslog.go
+ syslog_unix.go
+ )
+
+ GO_TEST_SRCS(syslog_test.go)
+
+ GO_XTEST_SRCS(example_test.go)
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ syslog.go
+ syslog_unix.go
+ )
+
+ GO_TEST_SRCS(syslog_test.go)
+
+ GO_XTEST_SRCS(example_test.go)
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/log/ya.make b/contrib/go/_std_1.21/src/log/ya.make
new file mode 100644
index 0000000000..4d58d4ea0d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/log/ya.make
@@ -0,0 +1,17 @@
+GO_LIBRARY()
+
+SRCS(
+ log.go
+)
+
+GO_TEST_SRCS(log_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+ internal
+ slog
+ syslog
+)
diff --git a/contrib/go/_std_1.20/src/math/abs.go b/contrib/go/_std_1.21/src/math/abs.go
index 08be14548d..08be14548d 100644
--- a/contrib/go/_std_1.20/src/math/abs.go
+++ b/contrib/go/_std_1.21/src/math/abs.go
diff --git a/contrib/go/_std_1.20/src/math/acosh.go b/contrib/go/_std_1.21/src/math/acosh.go
index a85d003d3e..a85d003d3e 100644
--- a/contrib/go/_std_1.20/src/math/acosh.go
+++ b/contrib/go/_std_1.21/src/math/acosh.go
diff --git a/contrib/go/_std_1.20/src/math/asin.go b/contrib/go/_std_1.21/src/math/asin.go
index 8e1b2ab491..8e1b2ab491 100644
--- a/contrib/go/_std_1.20/src/math/asin.go
+++ b/contrib/go/_std_1.21/src/math/asin.go
diff --git a/contrib/go/_std_1.21/src/math/asinh.go b/contrib/go/_std_1.21/src/math/asinh.go
new file mode 100644
index 0000000000..d913239d1e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/asinh.go
@@ -0,0 +1,77 @@
+// Copyright 2010 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 math
+
+// The original C code, the long comment, and the constants
+// below are from FreeBSD's /usr/src/lib/msun/src/s_asinh.c
+// and came with this notice. The go code is a simplified
+// version of the original C.
+//
+// ====================================================
+// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+//
+// Developed at SunPro, a Sun Microsystems, Inc. business.
+// Permission to use, copy, modify, and distribute this
+// software is freely granted, provided that this notice
+// is preserved.
+// ====================================================
+//
+//
+// asinh(x)
+// Method :
+// Based on
+// asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
+// we have
+// asinh(x) := x if 1+x*x=1,
+// := sign(x)*(log(x)+ln2) for large |x|, else
+// := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else
+// := sign(x)*log1p(|x| + x**2/(1 + sqrt(1+x**2)))
+//
+
+// Asinh returns the inverse hyperbolic sine of x.
+//
+// Special cases are:
+//
+// Asinh(±0) = ±0
+// Asinh(±Inf) = ±Inf
+// Asinh(NaN) = NaN
+func Asinh(x float64) float64 {
+ if haveArchAsinh {
+ return archAsinh(x)
+ }
+ return asinh(x)
+}
+
+func asinh(x float64) float64 {
+ const (
+ Ln2 = 6.93147180559945286227e-01 // 0x3FE62E42FEFA39EF
+ NearZero = 1.0 / (1 << 28) // 2**-28
+ Large = 1 << 28 // 2**28
+ )
+ // special cases
+ if IsNaN(x) || IsInf(x, 0) {
+ return x
+ }
+ sign := false
+ if x < 0 {
+ x = -x
+ sign = true
+ }
+ var temp float64
+ switch {
+ case x > Large:
+ temp = Log(x) + Ln2 // |x| > 2**28
+ case x > 2:
+ temp = Log(2*x + 1/(Sqrt(x*x+1)+x)) // 2**28 > |x| > 2.0
+ case x < NearZero:
+ temp = x // |x| < 2**-28
+ default:
+ temp = Log1p(x + x*x/(1+Sqrt(1+x*x))) // 2.0 > |x| > 2**-28
+ }
+ if sign {
+ temp = -temp
+ }
+ return temp
+}
diff --git a/contrib/go/_std_1.20/src/math/atan.go b/contrib/go/_std_1.21/src/math/atan.go
index e722e99757..e722e99757 100644
--- a/contrib/go/_std_1.20/src/math/atan.go
+++ b/contrib/go/_std_1.21/src/math/atan.go
diff --git a/contrib/go/_std_1.20/src/math/atan2.go b/contrib/go/_std_1.21/src/math/atan2.go
index c324ed0a15..c324ed0a15 100644
--- a/contrib/go/_std_1.20/src/math/atan2.go
+++ b/contrib/go/_std_1.21/src/math/atan2.go
diff --git a/contrib/go/_std_1.20/src/math/atanh.go b/contrib/go/_std_1.21/src/math/atanh.go
index 9d594625a5..9d594625a5 100644
--- a/contrib/go/_std_1.20/src/math/atanh.go
+++ b/contrib/go/_std_1.21/src/math/atanh.go
diff --git a/contrib/go/_std_1.21/src/math/big/accuracy_string.go b/contrib/go/_std_1.21/src/math/big/accuracy_string.go
new file mode 100644
index 0000000000..aae923829d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/big/accuracy_string.go
@@ -0,0 +1,26 @@
+// Code generated by "stringer -type=Accuracy"; DO NOT EDIT.
+
+package big
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[Below - -1]
+ _ = x[Exact-0]
+ _ = x[Above-1]
+}
+
+const _Accuracy_name = "BelowExactAbove"
+
+var _Accuracy_index = [...]uint8{0, 5, 10, 15}
+
+func (i Accuracy) String() string {
+ i -= -1
+ if i < 0 || i >= Accuracy(len(_Accuracy_index)-1) {
+ return "Accuracy(" + strconv.FormatInt(int64(i+-1), 10) + ")"
+ }
+ return _Accuracy_name[_Accuracy_index[i]:_Accuracy_index[i+1]]
+}
diff --git a/contrib/go/_std_1.20/src/math/big/arith.go b/contrib/go/_std_1.21/src/math/big/arith.go
index 06e63e2574..06e63e2574 100644
--- a/contrib/go/_std_1.20/src/math/big/arith.go
+++ b/contrib/go/_std_1.21/src/math/big/arith.go
diff --git a/contrib/go/_std_1.20/src/math/big/arith_amd64.go b/contrib/go/_std_1.21/src/math/big/arith_amd64.go
index 89108fe149..89108fe149 100644
--- a/contrib/go/_std_1.20/src/math/big/arith_amd64.go
+++ b/contrib/go/_std_1.21/src/math/big/arith_amd64.go
diff --git a/contrib/go/_std_1.20/src/math/big/arith_amd64.s b/contrib/go/_std_1.21/src/math/big/arith_amd64.s
index b1e914c2bd..b1e914c2bd 100644
--- a/contrib/go/_std_1.20/src/math/big/arith_amd64.s
+++ b/contrib/go/_std_1.21/src/math/big/arith_amd64.s
diff --git a/contrib/go/_std_1.20/src/math/big/arith_arm64.s b/contrib/go/_std_1.21/src/math/big/arith_arm64.s
index addf2d64a1..addf2d64a1 100644
--- a/contrib/go/_std_1.20/src/math/big/arith_arm64.s
+++ b/contrib/go/_std_1.21/src/math/big/arith_arm64.s
diff --git a/contrib/go/_std_1.20/src/math/big/arith_decl.go b/contrib/go/_std_1.21/src/math/big/arith_decl.go
index 9b254f2213..9b254f2213 100644
--- a/contrib/go/_std_1.20/src/math/big/arith_decl.go
+++ b/contrib/go/_std_1.21/src/math/big/arith_decl.go
diff --git a/contrib/go/_std_1.20/src/math/big/decimal.go b/contrib/go/_std_1.21/src/math/big/decimal.go
index 716f03bfa4..716f03bfa4 100644
--- a/contrib/go/_std_1.20/src/math/big/decimal.go
+++ b/contrib/go/_std_1.21/src/math/big/decimal.go
diff --git a/contrib/go/_std_1.21/src/math/big/doc.go b/contrib/go/_std_1.21/src/math/big/doc.go
new file mode 100644
index 0000000000..fee5a65c7b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/big/doc.go
@@ -0,0 +1,98 @@
+// Copyright 2009 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 big implements arbitrary-precision arithmetic (big numbers).
+The following numeric types are supported:
+
+ Int signed integers
+ Rat rational numbers
+ Float floating-point numbers
+
+The zero value for an Int, Rat, or Float correspond to 0. Thus, new
+values can be declared in the usual ways and denote 0 without further
+initialization:
+
+ var x Int // &x is an *Int of value 0
+ var r = &Rat{} // r is a *Rat of value 0
+ y := new(Float) // y is a *Float of value 0
+
+Alternatively, new values can be allocated and initialized with factory
+functions of the form:
+
+ func NewT(v V) *T
+
+For instance, NewInt(x) returns an *Int set to the value of the int64
+argument x, NewRat(a, b) returns a *Rat set to the fraction a/b where
+a and b are int64 values, and NewFloat(f) returns a *Float initialized
+to the float64 argument f. More flexibility is provided with explicit
+setters, for instance:
+
+ var z1 Int
+ z1.SetUint64(123) // z1 := 123
+ z2 := new(Rat).SetFloat64(1.25) // z2 := 5/4
+ z3 := new(Float).SetInt(z1) // z3 := 123.0
+
+Setters, numeric operations and predicates are represented as methods of
+the form:
+
+ func (z *T) SetV(v V) *T // z = v
+ func (z *T) Unary(x *T) *T // z = unary x
+ func (z *T) Binary(x, y *T) *T // z = x binary y
+ func (x *T) Pred() P // p = pred(x)
+
+with T one of Int, Rat, or Float. For unary and binary operations, the
+result is the receiver (usually named z in that case; see below); if it
+is one of the operands x or y it may be safely overwritten (and its memory
+reused).
+
+Arithmetic expressions are typically written as a sequence of individual
+method calls, with each call corresponding to an operation. The receiver
+denotes the result and the method arguments are the operation's operands.
+For instance, given three *Int values a, b and c, the invocation
+
+ c.Add(a, b)
+
+computes the sum a + b and stores the result in c, overwriting whatever
+value was held in c before. Unless specified otherwise, operations permit
+aliasing of parameters, so it is perfectly ok to write
+
+ sum.Add(sum, x)
+
+to accumulate values x in a sum.
+
+(By always passing in a result value via the receiver, memory use can be
+much better controlled. Instead of having to allocate new memory for each
+result, an operation can reuse the space allocated for the result value,
+and overwrite that value with the new result in the process.)
+
+Notational convention: Incoming method parameters (including the receiver)
+are named consistently in the API to clarify their use. Incoming operands
+are usually named x, y, a, b, and so on, but never z. A parameter specifying
+the result is named z (typically the receiver).
+
+For instance, the arguments for (*Int).Add are named x and y, and because
+the receiver specifies the result destination, it is called z:
+
+ func (z *Int) Add(x, y *Int) *Int
+
+Methods of this form typically return the incoming receiver as well, to
+enable simple call chaining.
+
+Methods which don't require a result value to be passed in (for instance,
+Int.Sign), simply return the result. In this case, the receiver is typically
+the first operand, named x:
+
+ func (x *Int) Sign() int
+
+Various methods support conversions between strings and corresponding
+numeric values, and vice versa: *Int, *Rat, and *Float values implement
+the Stringer interface for a (default) string representation of the value,
+but also provide SetString methods to initialize a value from a string in
+a variety of supported formats (see the respective SetString documentation).
+
+Finally, *Int, *Rat, and *Float satisfy [fmt.Scanner] for scanning
+and (except for *Rat) the Formatter interface for formatted printing.
+*/
+package big
diff --git a/contrib/go/_std_1.21/src/math/big/float.go b/contrib/go/_std_1.21/src/math/big/float.go
new file mode 100644
index 0000000000..2f0635a03b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/big/float.go
@@ -0,0 +1,1736 @@
+// Copyright 2014 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.
+
+// This file implements multi-precision floating-point numbers.
+// Like in the GNU MPFR library (https://www.mpfr.org/), operands
+// can be of mixed precision. Unlike MPFR, the rounding mode is
+// not specified with each operation, but with each operand. The
+// rounding mode of the result operand determines the rounding
+// mode of an operation. This is a from-scratch implementation.
+
+package big
+
+import (
+ "fmt"
+ "math"
+ "math/bits"
+)
+
+const debugFloat = false // enable for debugging
+
+// A nonzero finite Float represents a multi-precision floating point number
+//
+// sign × mantissa × 2**exponent
+//
+// with 0.5 <= mantissa < 1.0, and MinExp <= exponent <= MaxExp.
+// A Float may also be zero (+0, -0) or infinite (+Inf, -Inf).
+// All Floats are ordered, and the ordering of two Floats x and y
+// is defined by x.Cmp(y).
+//
+// Each Float value also has a precision, rounding mode, and accuracy.
+// The precision is the maximum number of mantissa bits available to
+// represent the value. The rounding mode specifies how a result should
+// be rounded to fit into the mantissa bits, and accuracy describes the
+// rounding error with respect to the exact result.
+//
+// Unless specified otherwise, all operations (including setters) that
+// specify a *Float variable for the result (usually via the receiver
+// with the exception of MantExp), round the numeric result according
+// to the precision and rounding mode of the result variable.
+//
+// If the provided result precision is 0 (see below), it is set to the
+// precision of the argument with the largest precision value before any
+// rounding takes place, and the rounding mode remains unchanged. Thus,
+// uninitialized Floats provided as result arguments will have their
+// precision set to a reasonable value determined by the operands, and
+// their mode is the zero value for RoundingMode (ToNearestEven).
+//
+// By setting the desired precision to 24 or 53 and using matching rounding
+// mode (typically ToNearestEven), Float operations produce the same results
+// as the corresponding float32 or float64 IEEE-754 arithmetic for operands
+// that correspond to normal (i.e., not denormal) float32 or float64 numbers.
+// Exponent underflow and overflow lead to a 0 or an Infinity for different
+// values than IEEE-754 because Float exponents have a much larger range.
+//
+// The zero (uninitialized) value for a Float is ready to use and represents
+// the number +0.0 exactly, with precision 0 and rounding mode ToNearestEven.
+//
+// Operations always take pointer arguments (*Float) rather
+// than Float values, and each unique Float value requires
+// its own unique *Float pointer. To "copy" a Float value,
+// an existing (or newly allocated) Float must be set to
+// a new value using the Float.Set method; shallow copies
+// of Floats are not supported and may lead to errors.
+type Float struct {
+ prec uint32
+ mode RoundingMode
+ acc Accuracy
+ form form
+ neg bool
+ mant nat
+ exp int32
+}
+
+// An ErrNaN panic is raised by a Float operation that would lead to
+// a NaN under IEEE-754 rules. An ErrNaN implements the error interface.
+type ErrNaN struct {
+ msg string
+}
+
+func (err ErrNaN) Error() string {
+ return err.msg
+}
+
+// NewFloat allocates and returns a new Float set to x,
+// with precision 53 and rounding mode ToNearestEven.
+// NewFloat panics with ErrNaN if x is a NaN.
+func NewFloat(x float64) *Float {
+ if math.IsNaN(x) {
+ panic(ErrNaN{"NewFloat(NaN)"})
+ }
+ return new(Float).SetFloat64(x)
+}
+
+// Exponent and precision limits.
+const (
+ MaxExp = math.MaxInt32 // largest supported exponent
+ MinExp = math.MinInt32 // smallest supported exponent
+ MaxPrec = math.MaxUint32 // largest (theoretically) supported precision; likely memory-limited
+)
+
+// Internal representation: The mantissa bits x.mant of a nonzero finite
+// Float x are stored in a nat slice long enough to hold up to x.prec bits;
+// the slice may (but doesn't have to) be shorter if the mantissa contains
+// trailing 0 bits. x.mant is normalized if the msb of x.mant == 1 (i.e.,
+// the msb is shifted all the way "to the left"). Thus, if the mantissa has
+// trailing 0 bits or x.prec is not a multiple of the Word size _W,
+// x.mant[0] has trailing zero bits. The msb of the mantissa corresponds
+// to the value 0.5; the exponent x.exp shifts the binary point as needed.
+//
+// A zero or non-finite Float x ignores x.mant and x.exp.
+//
+// x form neg mant exp
+// ----------------------------------------------------------
+// ±0 zero sign - -
+// 0 < |x| < +Inf finite sign mantissa exponent
+// ±Inf inf sign - -
+
+// A form value describes the internal representation.
+type form byte
+
+// The form value order is relevant - do not change!
+const (
+ zero form = iota
+ finite
+ inf
+)
+
+// RoundingMode determines how a Float value is rounded to the
+// desired precision. Rounding may change the Float value; the
+// rounding error is described by the Float's Accuracy.
+type RoundingMode byte
+
+// These constants define supported rounding modes.
+const (
+ ToNearestEven RoundingMode = iota // == IEEE 754-2008 roundTiesToEven
+ ToNearestAway // == IEEE 754-2008 roundTiesToAway
+ ToZero // == IEEE 754-2008 roundTowardZero
+ AwayFromZero // no IEEE 754-2008 equivalent
+ ToNegativeInf // == IEEE 754-2008 roundTowardNegative
+ ToPositiveInf // == IEEE 754-2008 roundTowardPositive
+)
+
+//go:generate stringer -type=RoundingMode
+
+// Accuracy describes the rounding error produced by the most recent
+// operation that generated a Float value, relative to the exact value.
+type Accuracy int8
+
+// Constants describing the Accuracy of a Float.
+const (
+ Below Accuracy = -1
+ Exact Accuracy = 0
+ Above Accuracy = +1
+)
+
+//go:generate stringer -type=Accuracy
+
+// SetPrec sets z's precision to prec and returns the (possibly) rounded
+// value of z. Rounding occurs according to z's rounding mode if the mantissa
+// cannot be represented in prec bits without loss of precision.
+// SetPrec(0) maps all finite values to ±0; infinite values remain unchanged.
+// If prec > MaxPrec, it is set to MaxPrec.
+func (z *Float) SetPrec(prec uint) *Float {
+ z.acc = Exact // optimistically assume no rounding is needed
+
+ // special case
+ if prec == 0 {
+ z.prec = 0
+ if z.form == finite {
+ // truncate z to 0
+ z.acc = makeAcc(z.neg)
+ z.form = zero
+ }
+ return z
+ }
+
+ // general case
+ if prec > MaxPrec {
+ prec = MaxPrec
+ }
+ old := z.prec
+ z.prec = uint32(prec)
+ if z.prec < old {
+ z.round(0)
+ }
+ return z
+}
+
+func makeAcc(above bool) Accuracy {
+ if above {
+ return Above
+ }
+ return Below
+}
+
+// SetMode sets z's rounding mode to mode and returns an exact z.
+// z remains unchanged otherwise.
+// z.SetMode(z.Mode()) is a cheap way to set z's accuracy to Exact.
+func (z *Float) SetMode(mode RoundingMode) *Float {
+ z.mode = mode
+ z.acc = Exact
+ return z
+}
+
+// Prec returns the mantissa precision of x in bits.
+// The result may be 0 for |x| == 0 and |x| == Inf.
+func (x *Float) Prec() uint {
+ return uint(x.prec)
+}
+
+// MinPrec returns the minimum precision required to represent x exactly
+// (i.e., the smallest prec before x.SetPrec(prec) would start rounding x).
+// The result is 0 for |x| == 0 and |x| == Inf.
+func (x *Float) MinPrec() uint {
+ if x.form != finite {
+ return 0
+ }
+ return uint(len(x.mant))*_W - x.mant.trailingZeroBits()
+}
+
+// Mode returns the rounding mode of x.
+func (x *Float) Mode() RoundingMode {
+ return x.mode
+}
+
+// Acc returns the accuracy of x produced by the most recent
+// operation, unless explicitly documented otherwise by that
+// operation.
+func (x *Float) Acc() Accuracy {
+ return x.acc
+}
+
+// Sign returns:
+//
+// -1 if x < 0
+// 0 if x is ±0
+// +1 if x > 0
+func (x *Float) Sign() int {
+ if debugFloat {
+ x.validate()
+ }
+ if x.form == zero {
+ return 0
+ }
+ if x.neg {
+ return -1
+ }
+ return 1
+}
+
+// MantExp breaks x into its mantissa and exponent components
+// and returns the exponent. If a non-nil mant argument is
+// provided its value is set to the mantissa of x, with the
+// same precision and rounding mode as x. The components
+// satisfy x == mant × 2**exp, with 0.5 <= |mant| < 1.0.
+// Calling MantExp with a nil argument is an efficient way to
+// get the exponent of the receiver.
+//
+// Special cases are:
+//
+// ( ±0).MantExp(mant) = 0, with mant set to ±0
+// (±Inf).MantExp(mant) = 0, with mant set to ±Inf
+//
+// x and mant may be the same in which case x is set to its
+// mantissa value.
+func (x *Float) MantExp(mant *Float) (exp int) {
+ if debugFloat {
+ x.validate()
+ }
+ if x.form == finite {
+ exp = int(x.exp)
+ }
+ if mant != nil {
+ mant.Copy(x)
+ if mant.form == finite {
+ mant.exp = 0
+ }
+ }
+ return
+}
+
+func (z *Float) setExpAndRound(exp int64, sbit uint) {
+ if exp < MinExp {
+ // underflow
+ z.acc = makeAcc(z.neg)
+ z.form = zero
+ return
+ }
+
+ if exp > MaxExp {
+ // overflow
+ z.acc = makeAcc(!z.neg)
+ z.form = inf
+ return
+ }
+
+ z.form = finite
+ z.exp = int32(exp)
+ z.round(sbit)
+}
+
+// SetMantExp sets z to mant × 2**exp and returns z.
+// The result z has the same precision and rounding mode
+// as mant. SetMantExp is an inverse of MantExp but does
+// not require 0.5 <= |mant| < 1.0. Specifically, for a
+// given x of type *Float, SetMantExp relates to MantExp
+// as follows:
+//
+// mant := new(Float)
+// new(Float).SetMantExp(mant, x.MantExp(mant)).Cmp(x) == 0
+//
+// Special cases are:
+//
+// z.SetMantExp( ±0, exp) = ±0
+// z.SetMantExp(±Inf, exp) = ±Inf
+//
+// z and mant may be the same in which case z's exponent
+// is set to exp.
+func (z *Float) SetMantExp(mant *Float, exp int) *Float {
+ if debugFloat {
+ z.validate()
+ mant.validate()
+ }
+ z.Copy(mant)
+
+ if z.form == finite {
+ // 0 < |mant| < +Inf
+ z.setExpAndRound(int64(z.exp)+int64(exp), 0)
+ }
+ return z
+}
+
+// Signbit reports whether x is negative or negative zero.
+func (x *Float) Signbit() bool {
+ return x.neg
+}
+
+// IsInf reports whether x is +Inf or -Inf.
+func (x *Float) IsInf() bool {
+ return x.form == inf
+}
+
+// IsInt reports whether x is an integer.
+// ±Inf values are not integers.
+func (x *Float) IsInt() bool {
+ if debugFloat {
+ x.validate()
+ }
+ // special cases
+ if x.form != finite {
+ return x.form == zero
+ }
+ // x.form == finite
+ if x.exp <= 0 {
+ return false
+ }
+ // x.exp > 0
+ return x.prec <= uint32(x.exp) || x.MinPrec() <= uint(x.exp) // not enough bits for fractional mantissa
+}
+
+// debugging support
+func (x *Float) validate() {
+ if !debugFloat {
+ // avoid performance bugs
+ panic("validate called but debugFloat is not set")
+ }
+ if msg := x.validate0(); msg != "" {
+ panic(msg)
+ }
+}
+
+func (x *Float) validate0() string {
+ if x.form != finite {
+ return ""
+ }
+ m := len(x.mant)
+ if m == 0 {
+ return "nonzero finite number with empty mantissa"
+ }
+ const msb = 1 << (_W - 1)
+ if x.mant[m-1]&msb == 0 {
+ return fmt.Sprintf("msb not set in last word %#x of %s", x.mant[m-1], x.Text('p', 0))
+ }
+ if x.prec == 0 {
+ return "zero precision finite number"
+ }
+ return ""
+}
+
+// round rounds z according to z.mode to z.prec bits and sets z.acc accordingly.
+// sbit must be 0 or 1 and summarizes any "sticky bit" information one might
+// have before calling round. z's mantissa must be normalized (with the msb set)
+// or empty.
+//
+// CAUTION: The rounding modes ToNegativeInf, ToPositiveInf are affected by the
+// sign of z. For correct rounding, the sign of z must be set correctly before
+// calling round.
+func (z *Float) round(sbit uint) {
+ if debugFloat {
+ z.validate()
+ }
+
+ z.acc = Exact
+ if z.form != finite {
+ // ±0 or ±Inf => nothing left to do
+ return
+ }
+ // z.form == finite && len(z.mant) > 0
+ // m > 0 implies z.prec > 0 (checked by validate)
+
+ m := uint32(len(z.mant)) // present mantissa length in words
+ bits := m * _W // present mantissa bits; bits > 0
+ if bits <= z.prec {
+ // mantissa fits => nothing to do
+ return
+ }
+ // bits > z.prec
+
+ // Rounding is based on two bits: the rounding bit (rbit) and the
+ // sticky bit (sbit). The rbit is the bit immediately before the
+ // z.prec leading mantissa bits (the "0.5"). The sbit is set if any
+ // of the bits before the rbit are set (the "0.25", "0.125", etc.):
+ //
+ // rbit sbit => "fractional part"
+ //
+ // 0 0 == 0
+ // 0 1 > 0 , < 0.5
+ // 1 0 == 0.5
+ // 1 1 > 0.5, < 1.0
+
+ // bits > z.prec: mantissa too large => round
+ r := uint(bits - z.prec - 1) // rounding bit position; r >= 0
+ rbit := z.mant.bit(r) & 1 // rounding bit; be safe and ensure it's a single bit
+ // The sticky bit is only needed for rounding ToNearestEven
+ // or when the rounding bit is zero. Avoid computation otherwise.
+ if sbit == 0 && (rbit == 0 || z.mode == ToNearestEven) {
+ sbit = z.mant.sticky(r)
+ }
+ sbit &= 1 // be safe and ensure it's a single bit
+
+ // cut off extra words
+ n := (z.prec + (_W - 1)) / _W // mantissa length in words for desired precision
+ if m > n {
+ copy(z.mant, z.mant[m-n:]) // move n last words to front
+ z.mant = z.mant[:n]
+ }
+
+ // determine number of trailing zero bits (ntz) and compute lsb mask of mantissa's least-significant word
+ ntz := n*_W - z.prec // 0 <= ntz < _W
+ lsb := Word(1) << ntz
+
+ // round if result is inexact
+ if rbit|sbit != 0 {
+ // Make rounding decision: The result mantissa is truncated ("rounded down")
+ // by default. Decide if we need to increment, or "round up", the (unsigned)
+ // mantissa.
+ inc := false
+ switch z.mode {
+ case ToNegativeInf:
+ inc = z.neg
+ case ToZero:
+ // nothing to do
+ case ToNearestEven:
+ inc = rbit != 0 && (sbit != 0 || z.mant[0]&lsb != 0)
+ case ToNearestAway:
+ inc = rbit != 0
+ case AwayFromZero:
+ inc = true
+ case ToPositiveInf:
+ inc = !z.neg
+ default:
+ panic("unreachable")
+ }
+
+ // A positive result (!z.neg) is Above the exact result if we increment,
+ // and it's Below if we truncate (Exact results require no rounding).
+ // For a negative result (z.neg) it is exactly the opposite.
+ z.acc = makeAcc(inc != z.neg)
+
+ if inc {
+ // add 1 to mantissa
+ if addVW(z.mant, z.mant, lsb) != 0 {
+ // mantissa overflow => adjust exponent
+ if z.exp >= MaxExp {
+ // exponent overflow
+ z.form = inf
+ return
+ }
+ z.exp++
+ // adjust mantissa: divide by 2 to compensate for exponent adjustment
+ shrVU(z.mant, z.mant, 1)
+ // set msb == carry == 1 from the mantissa overflow above
+ const msb = 1 << (_W - 1)
+ z.mant[n-1] |= msb
+ }
+ }
+ }
+
+ // zero out trailing bits in least-significant word
+ z.mant[0] &^= lsb - 1
+
+ if debugFloat {
+ z.validate()
+ }
+}
+
+func (z *Float) setBits64(neg bool, x uint64) *Float {
+ if z.prec == 0 {
+ z.prec = 64
+ }
+ z.acc = Exact
+ z.neg = neg
+ if x == 0 {
+ z.form = zero
+ return z
+ }
+ // x != 0
+ z.form = finite
+ s := bits.LeadingZeros64(x)
+ z.mant = z.mant.setUint64(x << uint(s))
+ z.exp = int32(64 - s) // always fits
+ if z.prec < 64 {
+ z.round(0)
+ }
+ return z
+}
+
+// SetUint64 sets z to the (possibly rounded) value of x and returns z.
+// If z's precision is 0, it is changed to 64 (and rounding will have
+// no effect).
+func (z *Float) SetUint64(x uint64) *Float {
+ return z.setBits64(false, x)
+}
+
+// SetInt64 sets z to the (possibly rounded) value of x and returns z.
+// If z's precision is 0, it is changed to 64 (and rounding will have
+// no effect).
+func (z *Float) SetInt64(x int64) *Float {
+ u := x
+ if u < 0 {
+ u = -u
+ }
+ // We cannot simply call z.SetUint64(uint64(u)) and change
+ // the sign afterwards because the sign affects rounding.
+ return z.setBits64(x < 0, uint64(u))
+}
+
+// SetFloat64 sets z to the (possibly rounded) value of x and returns z.
+// If z's precision is 0, it is changed to 53 (and rounding will have
+// no effect). SetFloat64 panics with ErrNaN if x is a NaN.
+func (z *Float) SetFloat64(x float64) *Float {
+ if z.prec == 0 {
+ z.prec = 53
+ }
+ if math.IsNaN(x) {
+ panic(ErrNaN{"Float.SetFloat64(NaN)"})
+ }
+ z.acc = Exact
+ z.neg = math.Signbit(x) // handle -0, -Inf correctly
+ if x == 0 {
+ z.form = zero
+ return z
+ }
+ if math.IsInf(x, 0) {
+ z.form = inf
+ return z
+ }
+ // normalized x != 0
+ z.form = finite
+ fmant, exp := math.Frexp(x) // get normalized mantissa
+ z.mant = z.mant.setUint64(1<<63 | math.Float64bits(fmant)<<11)
+ z.exp = int32(exp) // always fits
+ if z.prec < 53 {
+ z.round(0)
+ }
+ return z
+}
+
+// fnorm normalizes mantissa m by shifting it to the left
+// such that the msb of the most-significant word (msw) is 1.
+// It returns the shift amount. It assumes that len(m) != 0.
+func fnorm(m nat) int64 {
+ if debugFloat && (len(m) == 0 || m[len(m)-1] == 0) {
+ panic("msw of mantissa is 0")
+ }
+ s := nlz(m[len(m)-1])
+ if s > 0 {
+ c := shlVU(m, m, s)
+ if debugFloat && c != 0 {
+ panic("nlz or shlVU incorrect")
+ }
+ }
+ return int64(s)
+}
+
+// SetInt sets z to the (possibly rounded) value of x and returns z.
+// If z's precision is 0, it is changed to the larger of x.BitLen()
+// or 64 (and rounding will have no effect).
+func (z *Float) SetInt(x *Int) *Float {
+ // TODO(gri) can be more efficient if z.prec > 0
+ // but small compared to the size of x, or if there
+ // are many trailing 0's.
+ bits := uint32(x.BitLen())
+ if z.prec == 0 {
+ z.prec = umax32(bits, 64)
+ }
+ z.acc = Exact
+ z.neg = x.neg
+ if len(x.abs) == 0 {
+ z.form = zero
+ return z
+ }
+ // x != 0
+ z.mant = z.mant.set(x.abs)
+ fnorm(z.mant)
+ z.setExpAndRound(int64(bits), 0)
+ return z
+}
+
+// SetRat sets z to the (possibly rounded) value of x and returns z.
+// If z's precision is 0, it is changed to the largest of a.BitLen(),
+// b.BitLen(), or 64; with x = a/b.
+func (z *Float) SetRat(x *Rat) *Float {
+ if x.IsInt() {
+ return z.SetInt(x.Num())
+ }
+ var a, b Float
+ a.SetInt(x.Num())
+ b.SetInt(x.Denom())
+ if z.prec == 0 {
+ z.prec = umax32(a.prec, b.prec)
+ }
+ return z.Quo(&a, &b)
+}
+
+// SetInf sets z to the infinite Float -Inf if signbit is
+// set, or +Inf if signbit is not set, and returns z. The
+// precision of z is unchanged and the result is always
+// Exact.
+func (z *Float) SetInf(signbit bool) *Float {
+ z.acc = Exact
+ z.form = inf
+ z.neg = signbit
+ return z
+}
+
+// Set sets z to the (possibly rounded) value of x and returns z.
+// If z's precision is 0, it is changed to the precision of x
+// before setting z (and rounding will have no effect).
+// Rounding is performed according to z's precision and rounding
+// mode; and z's accuracy reports the result error relative to the
+// exact (not rounded) result.
+func (z *Float) Set(x *Float) *Float {
+ if debugFloat {
+ x.validate()
+ }
+ z.acc = Exact
+ if z != x {
+ z.form = x.form
+ z.neg = x.neg
+ if x.form == finite {
+ z.exp = x.exp
+ z.mant = z.mant.set(x.mant)
+ }
+ if z.prec == 0 {
+ z.prec = x.prec
+ } else if z.prec < x.prec {
+ z.round(0)
+ }
+ }
+ return z
+}
+
+// Copy sets z to x, with the same precision, rounding mode, and
+// accuracy as x, and returns z. x is not changed even if z and
+// x are the same.
+func (z *Float) Copy(x *Float) *Float {
+ if debugFloat {
+ x.validate()
+ }
+ if z != x {
+ z.prec = x.prec
+ z.mode = x.mode
+ z.acc = x.acc
+ z.form = x.form
+ z.neg = x.neg
+ if z.form == finite {
+ z.mant = z.mant.set(x.mant)
+ z.exp = x.exp
+ }
+ }
+ return z
+}
+
+// msb32 returns the 32 most significant bits of x.
+func msb32(x nat) uint32 {
+ i := len(x) - 1
+ if i < 0 {
+ return 0
+ }
+ if debugFloat && x[i]&(1<<(_W-1)) == 0 {
+ panic("x not normalized")
+ }
+ switch _W {
+ case 32:
+ return uint32(x[i])
+ case 64:
+ return uint32(x[i] >> 32)
+ }
+ panic("unreachable")
+}
+
+// msb64 returns the 64 most significant bits of x.
+func msb64(x nat) uint64 {
+ i := len(x) - 1
+ if i < 0 {
+ return 0
+ }
+ if debugFloat && x[i]&(1<<(_W-1)) == 0 {
+ panic("x not normalized")
+ }
+ switch _W {
+ case 32:
+ v := uint64(x[i]) << 32
+ if i > 0 {
+ v |= uint64(x[i-1])
+ }
+ return v
+ case 64:
+ return uint64(x[i])
+ }
+ panic("unreachable")
+}
+
+// Uint64 returns the unsigned integer resulting from truncating x
+// towards zero. If 0 <= x <= math.MaxUint64, the result is Exact
+// if x is an integer and Below otherwise.
+// The result is (0, Above) for x < 0, and (math.MaxUint64, Below)
+// for x > math.MaxUint64.
+func (x *Float) Uint64() (uint64, Accuracy) {
+ if debugFloat {
+ x.validate()
+ }
+
+ switch x.form {
+ case finite:
+ if x.neg {
+ return 0, Above
+ }
+ // 0 < x < +Inf
+ if x.exp <= 0 {
+ // 0 < x < 1
+ return 0, Below
+ }
+ // 1 <= x < Inf
+ if x.exp <= 64 {
+ // u = trunc(x) fits into a uint64
+ u := msb64(x.mant) >> (64 - uint32(x.exp))
+ if x.MinPrec() <= 64 {
+ return u, Exact
+ }
+ return u, Below // x truncated
+ }
+ // x too large
+ return math.MaxUint64, Below
+
+ case zero:
+ return 0, Exact
+
+ case inf:
+ if x.neg {
+ return 0, Above
+ }
+ return math.MaxUint64, Below
+ }
+
+ panic("unreachable")
+}
+
+// Int64 returns the integer resulting from truncating x towards zero.
+// If math.MinInt64 <= x <= math.MaxInt64, the result is Exact if x is
+// an integer, and Above (x < 0) or Below (x > 0) otherwise.
+// The result is (math.MinInt64, Above) for x < math.MinInt64,
+// and (math.MaxInt64, Below) for x > math.MaxInt64.
+func (x *Float) Int64() (int64, Accuracy) {
+ if debugFloat {
+ x.validate()
+ }
+
+ switch x.form {
+ case finite:
+ // 0 < |x| < +Inf
+ acc := makeAcc(x.neg)
+ if x.exp <= 0 {
+ // 0 < |x| < 1
+ return 0, acc
+ }
+ // x.exp > 0
+
+ // 1 <= |x| < +Inf
+ if x.exp <= 63 {
+ // i = trunc(x) fits into an int64 (excluding math.MinInt64)
+ i := int64(msb64(x.mant) >> (64 - uint32(x.exp)))
+ if x.neg {
+ i = -i
+ }
+ if x.MinPrec() <= uint(x.exp) {
+ return i, Exact
+ }
+ return i, acc // x truncated
+ }
+ if x.neg {
+ // check for special case x == math.MinInt64 (i.e., x == -(0.5 << 64))
+ if x.exp == 64 && x.MinPrec() == 1 {
+ acc = Exact
+ }
+ return math.MinInt64, acc
+ }
+ // x too large
+ return math.MaxInt64, Below
+
+ case zero:
+ return 0, Exact
+
+ case inf:
+ if x.neg {
+ return math.MinInt64, Above
+ }
+ return math.MaxInt64, Below
+ }
+
+ panic("unreachable")
+}
+
+// Float32 returns the float32 value nearest to x. If x is too small to be
+// represented by a float32 (|x| < math.SmallestNonzeroFloat32), the result
+// is (0, Below) or (-0, Above), respectively, depending on the sign of x.
+// If x is too large to be represented by a float32 (|x| > math.MaxFloat32),
+// the result is (+Inf, Above) or (-Inf, Below), depending on the sign of x.
+func (x *Float) Float32() (float32, Accuracy) {
+ if debugFloat {
+ x.validate()
+ }
+
+ switch x.form {
+ case finite:
+ // 0 < |x| < +Inf
+
+ const (
+ fbits = 32 // float size
+ mbits = 23 // mantissa size (excluding implicit msb)
+ ebits = fbits - mbits - 1 // 8 exponent size
+ bias = 1<<(ebits-1) - 1 // 127 exponent bias
+ dmin = 1 - bias - mbits // -149 smallest unbiased exponent (denormal)
+ emin = 1 - bias // -126 smallest unbiased exponent (normal)
+ emax = bias // 127 largest unbiased exponent (normal)
+ )
+
+ // Float mantissa m is 0.5 <= m < 1.0; compute exponent e for float32 mantissa.
+ e := x.exp - 1 // exponent for normal mantissa m with 1.0 <= m < 2.0
+
+ // Compute precision p for float32 mantissa.
+ // If the exponent is too small, we have a denormal number before
+ // rounding and fewer than p mantissa bits of precision available
+ // (the exponent remains fixed but the mantissa gets shifted right).
+ p := mbits + 1 // precision of normal float
+ if e < emin {
+ // recompute precision
+ p = mbits + 1 - emin + int(e)
+ // If p == 0, the mantissa of x is shifted so much to the right
+ // that its msb falls immediately to the right of the float32
+ // mantissa space. In other words, if the smallest denormal is
+ // considered "1.0", for p == 0, the mantissa value m is >= 0.5.
+ // If m > 0.5, it is rounded up to 1.0; i.e., the smallest denormal.
+ // If m == 0.5, it is rounded down to even, i.e., 0.0.
+ // If p < 0, the mantissa value m is <= "0.25" which is never rounded up.
+ if p < 0 /* m <= 0.25 */ || p == 0 && x.mant.sticky(uint(len(x.mant))*_W-1) == 0 /* m == 0.5 */ {
+ // underflow to ±0
+ if x.neg {
+ var z float32
+ return -z, Above
+ }
+ return 0.0, Below
+ }
+ // otherwise, round up
+ // We handle p == 0 explicitly because it's easy and because
+ // Float.round doesn't support rounding to 0 bits of precision.
+ if p == 0 {
+ if x.neg {
+ return -math.SmallestNonzeroFloat32, Below
+ }
+ return math.SmallestNonzeroFloat32, Above
+ }
+ }
+ // p > 0
+
+ // round
+ var r Float
+ r.prec = uint32(p)
+ r.Set(x)
+ e = r.exp - 1
+
+ // Rounding may have caused r to overflow to ±Inf
+ // (rounding never causes underflows to 0).
+ // If the exponent is too large, also overflow to ±Inf.
+ if r.form == inf || e > emax {
+ // overflow
+ if x.neg {
+ return float32(math.Inf(-1)), Below
+ }
+ return float32(math.Inf(+1)), Above
+ }
+ // e <= emax
+
+ // Determine sign, biased exponent, and mantissa.
+ var sign, bexp, mant uint32
+ if x.neg {
+ sign = 1 << (fbits - 1)
+ }
+
+ // Rounding may have caused a denormal number to
+ // become normal. Check again.
+ if e < emin {
+ // denormal number: recompute precision
+ // Since rounding may have at best increased precision
+ // and we have eliminated p <= 0 early, we know p > 0.
+ // bexp == 0 for denormals
+ p = mbits + 1 - emin + int(e)
+ mant = msb32(r.mant) >> uint(fbits-p)
+ } else {
+ // normal number: emin <= e <= emax
+ bexp = uint32(e+bias) << mbits
+ mant = msb32(r.mant) >> ebits & (1<<mbits - 1) // cut off msb (implicit 1 bit)
+ }
+
+ return math.Float32frombits(sign | bexp | mant), r.acc
+
+ case zero:
+ if x.neg {
+ var z float32
+ return -z, Exact
+ }
+ return 0.0, Exact
+
+ case inf:
+ if x.neg {
+ return float32(math.Inf(-1)), Exact
+ }
+ return float32(math.Inf(+1)), Exact
+ }
+
+ panic("unreachable")
+}
+
+// Float64 returns the float64 value nearest to x. If x is too small to be
+// represented by a float64 (|x| < math.SmallestNonzeroFloat64), the result
+// is (0, Below) or (-0, Above), respectively, depending on the sign of x.
+// If x is too large to be represented by a float64 (|x| > math.MaxFloat64),
+// the result is (+Inf, Above) or (-Inf, Below), depending on the sign of x.
+func (x *Float) Float64() (float64, Accuracy) {
+ if debugFloat {
+ x.validate()
+ }
+
+ switch x.form {
+ case finite:
+ // 0 < |x| < +Inf
+
+ const (
+ fbits = 64 // float size
+ mbits = 52 // mantissa size (excluding implicit msb)
+ ebits = fbits - mbits - 1 // 11 exponent size
+ bias = 1<<(ebits-1) - 1 // 1023 exponent bias
+ dmin = 1 - bias - mbits // -1074 smallest unbiased exponent (denormal)
+ emin = 1 - bias // -1022 smallest unbiased exponent (normal)
+ emax = bias // 1023 largest unbiased exponent (normal)
+ )
+
+ // Float mantissa m is 0.5 <= m < 1.0; compute exponent e for float64 mantissa.
+ e := x.exp - 1 // exponent for normal mantissa m with 1.0 <= m < 2.0
+
+ // Compute precision p for float64 mantissa.
+ // If the exponent is too small, we have a denormal number before
+ // rounding and fewer than p mantissa bits of precision available
+ // (the exponent remains fixed but the mantissa gets shifted right).
+ p := mbits + 1 // precision of normal float
+ if e < emin {
+ // recompute precision
+ p = mbits + 1 - emin + int(e)
+ // If p == 0, the mantissa of x is shifted so much to the right
+ // that its msb falls immediately to the right of the float64
+ // mantissa space. In other words, if the smallest denormal is
+ // considered "1.0", for p == 0, the mantissa value m is >= 0.5.
+ // If m > 0.5, it is rounded up to 1.0; i.e., the smallest denormal.
+ // If m == 0.5, it is rounded down to even, i.e., 0.0.
+ // If p < 0, the mantissa value m is <= "0.25" which is never rounded up.
+ if p < 0 /* m <= 0.25 */ || p == 0 && x.mant.sticky(uint(len(x.mant))*_W-1) == 0 /* m == 0.5 */ {
+ // underflow to ±0
+ if x.neg {
+ var z float64
+ return -z, Above
+ }
+ return 0.0, Below
+ }
+ // otherwise, round up
+ // We handle p == 0 explicitly because it's easy and because
+ // Float.round doesn't support rounding to 0 bits of precision.
+ if p == 0 {
+ if x.neg {
+ return -math.SmallestNonzeroFloat64, Below
+ }
+ return math.SmallestNonzeroFloat64, Above
+ }
+ }
+ // p > 0
+
+ // round
+ var r Float
+ r.prec = uint32(p)
+ r.Set(x)
+ e = r.exp - 1
+
+ // Rounding may have caused r to overflow to ±Inf
+ // (rounding never causes underflows to 0).
+ // If the exponent is too large, also overflow to ±Inf.
+ if r.form == inf || e > emax {
+ // overflow
+ if x.neg {
+ return math.Inf(-1), Below
+ }
+ return math.Inf(+1), Above
+ }
+ // e <= emax
+
+ // Determine sign, biased exponent, and mantissa.
+ var sign, bexp, mant uint64
+ if x.neg {
+ sign = 1 << (fbits - 1)
+ }
+
+ // Rounding may have caused a denormal number to
+ // become normal. Check again.
+ if e < emin {
+ // denormal number: recompute precision
+ // Since rounding may have at best increased precision
+ // and we have eliminated p <= 0 early, we know p > 0.
+ // bexp == 0 for denormals
+ p = mbits + 1 - emin + int(e)
+ mant = msb64(r.mant) >> uint(fbits-p)
+ } else {
+ // normal number: emin <= e <= emax
+ bexp = uint64(e+bias) << mbits
+ mant = msb64(r.mant) >> ebits & (1<<mbits - 1) // cut off msb (implicit 1 bit)
+ }
+
+ return math.Float64frombits(sign | bexp | mant), r.acc
+
+ case zero:
+ if x.neg {
+ var z float64
+ return -z, Exact
+ }
+ return 0.0, Exact
+
+ case inf:
+ if x.neg {
+ return math.Inf(-1), Exact
+ }
+ return math.Inf(+1), Exact
+ }
+
+ panic("unreachable")
+}
+
+// Int returns the result of truncating x towards zero;
+// or nil if x is an infinity.
+// The result is Exact if x.IsInt(); otherwise it is Below
+// for x > 0, and Above for x < 0.
+// If a non-nil *Int argument z is provided, Int stores
+// the result in z instead of allocating a new Int.
+func (x *Float) Int(z *Int) (*Int, Accuracy) {
+ if debugFloat {
+ x.validate()
+ }
+
+ if z == nil && x.form <= finite {
+ z = new(Int)
+ }
+
+ switch x.form {
+ case finite:
+ // 0 < |x| < +Inf
+ acc := makeAcc(x.neg)
+ if x.exp <= 0 {
+ // 0 < |x| < 1
+ return z.SetInt64(0), acc
+ }
+ // x.exp > 0
+
+ // 1 <= |x| < +Inf
+ // determine minimum required precision for x
+ allBits := uint(len(x.mant)) * _W
+ exp := uint(x.exp)
+ if x.MinPrec() <= exp {
+ acc = Exact
+ }
+ // shift mantissa as needed
+ if z == nil {
+ z = new(Int)
+ }
+ z.neg = x.neg
+ switch {
+ case exp > allBits:
+ z.abs = z.abs.shl(x.mant, exp-allBits)
+ default:
+ z.abs = z.abs.set(x.mant)
+ case exp < allBits:
+ z.abs = z.abs.shr(x.mant, allBits-exp)
+ }
+ return z, acc
+
+ case zero:
+ return z.SetInt64(0), Exact
+
+ case inf:
+ return nil, makeAcc(x.neg)
+ }
+
+ panic("unreachable")
+}
+
+// Rat returns the rational number corresponding to x;
+// or nil if x is an infinity.
+// The result is Exact if x is not an Inf.
+// If a non-nil *Rat argument z is provided, Rat stores
+// the result in z instead of allocating a new Rat.
+func (x *Float) Rat(z *Rat) (*Rat, Accuracy) {
+ if debugFloat {
+ x.validate()
+ }
+
+ if z == nil && x.form <= finite {
+ z = new(Rat)
+ }
+
+ switch x.form {
+ case finite:
+ // 0 < |x| < +Inf
+ allBits := int32(len(x.mant)) * _W
+ // build up numerator and denominator
+ z.a.neg = x.neg
+ switch {
+ case x.exp > allBits:
+ z.a.abs = z.a.abs.shl(x.mant, uint(x.exp-allBits))
+ z.b.abs = z.b.abs[:0] // == 1 (see Rat)
+ // z already in normal form
+ default:
+ z.a.abs = z.a.abs.set(x.mant)
+ z.b.abs = z.b.abs[:0] // == 1 (see Rat)
+ // z already in normal form
+ case x.exp < allBits:
+ z.a.abs = z.a.abs.set(x.mant)
+ t := z.b.abs.setUint64(1)
+ z.b.abs = t.shl(t, uint(allBits-x.exp))
+ z.norm()
+ }
+ return z, Exact
+
+ case zero:
+ return z.SetInt64(0), Exact
+
+ case inf:
+ return nil, makeAcc(x.neg)
+ }
+
+ panic("unreachable")
+}
+
+// Abs sets z to the (possibly rounded) value |x| (the absolute value of x)
+// and returns z.
+func (z *Float) Abs(x *Float) *Float {
+ z.Set(x)
+ z.neg = false
+ return z
+}
+
+// Neg sets z to the (possibly rounded) value of x with its sign negated,
+// and returns z.
+func (z *Float) Neg(x *Float) *Float {
+ z.Set(x)
+ z.neg = !z.neg
+ return z
+}
+
+func validateBinaryOperands(x, y *Float) {
+ if !debugFloat {
+ // avoid performance bugs
+ panic("validateBinaryOperands called but debugFloat is not set")
+ }
+ if len(x.mant) == 0 {
+ panic("empty mantissa for x")
+ }
+ if len(y.mant) == 0 {
+ panic("empty mantissa for y")
+ }
+}
+
+// z = x + y, ignoring signs of x and y for the addition
+// but using the sign of z for rounding the result.
+// x and y must have a non-empty mantissa and valid exponent.
+func (z *Float) uadd(x, y *Float) {
+ // Note: This implementation requires 2 shifts most of the
+ // time. It is also inefficient if exponents or precisions
+ // differ by wide margins. The following article describes
+ // an efficient (but much more complicated) implementation
+ // compatible with the internal representation used here:
+ //
+ // Vincent Lefèvre: "The Generic Multiple-Precision Floating-
+ // Point Addition With Exact Rounding (as in the MPFR Library)"
+ // http://www.vinc17.net/research/papers/rnc6.pdf
+
+ if debugFloat {
+ validateBinaryOperands(x, y)
+ }
+
+ // compute exponents ex, ey for mantissa with "binary point"
+ // on the right (mantissa.0) - use int64 to avoid overflow
+ ex := int64(x.exp) - int64(len(x.mant))*_W
+ ey := int64(y.exp) - int64(len(y.mant))*_W
+
+ al := alias(z.mant, x.mant) || alias(z.mant, y.mant)
+
+ // TODO(gri) having a combined add-and-shift primitive
+ // could make this code significantly faster
+ switch {
+ case ex < ey:
+ if al {
+ t := nat(nil).shl(y.mant, uint(ey-ex))
+ z.mant = z.mant.add(x.mant, t)
+ } else {
+ z.mant = z.mant.shl(y.mant, uint(ey-ex))
+ z.mant = z.mant.add(x.mant, z.mant)
+ }
+ default:
+ // ex == ey, no shift needed
+ z.mant = z.mant.add(x.mant, y.mant)
+ case ex > ey:
+ if al {
+ t := nat(nil).shl(x.mant, uint(ex-ey))
+ z.mant = z.mant.add(t, y.mant)
+ } else {
+ z.mant = z.mant.shl(x.mant, uint(ex-ey))
+ z.mant = z.mant.add(z.mant, y.mant)
+ }
+ ex = ey
+ }
+ // len(z.mant) > 0
+
+ z.setExpAndRound(ex+int64(len(z.mant))*_W-fnorm(z.mant), 0)
+}
+
+// z = x - y for |x| > |y|, ignoring signs of x and y for the subtraction
+// but using the sign of z for rounding the result.
+// x and y must have a non-empty mantissa and valid exponent.
+func (z *Float) usub(x, y *Float) {
+ // This code is symmetric to uadd.
+ // We have not factored the common code out because
+ // eventually uadd (and usub) should be optimized
+ // by special-casing, and the code will diverge.
+
+ if debugFloat {
+ validateBinaryOperands(x, y)
+ }
+
+ ex := int64(x.exp) - int64(len(x.mant))*_W
+ ey := int64(y.exp) - int64(len(y.mant))*_W
+
+ al := alias(z.mant, x.mant) || alias(z.mant, y.mant)
+
+ switch {
+ case ex < ey:
+ if al {
+ t := nat(nil).shl(y.mant, uint(ey-ex))
+ z.mant = t.sub(x.mant, t)
+ } else {
+ z.mant = z.mant.shl(y.mant, uint(ey-ex))
+ z.mant = z.mant.sub(x.mant, z.mant)
+ }
+ default:
+ // ex == ey, no shift needed
+ z.mant = z.mant.sub(x.mant, y.mant)
+ case ex > ey:
+ if al {
+ t := nat(nil).shl(x.mant, uint(ex-ey))
+ z.mant = t.sub(t, y.mant)
+ } else {
+ z.mant = z.mant.shl(x.mant, uint(ex-ey))
+ z.mant = z.mant.sub(z.mant, y.mant)
+ }
+ ex = ey
+ }
+
+ // operands may have canceled each other out
+ if len(z.mant) == 0 {
+ z.acc = Exact
+ z.form = zero
+ z.neg = false
+ return
+ }
+ // len(z.mant) > 0
+
+ z.setExpAndRound(ex+int64(len(z.mant))*_W-fnorm(z.mant), 0)
+}
+
+// z = x * y, ignoring signs of x and y for the multiplication
+// but using the sign of z for rounding the result.
+// x and y must have a non-empty mantissa and valid exponent.
+func (z *Float) umul(x, y *Float) {
+ if debugFloat {
+ validateBinaryOperands(x, y)
+ }
+
+ // Note: This is doing too much work if the precision
+ // of z is less than the sum of the precisions of x
+ // and y which is often the case (e.g., if all floats
+ // have the same precision).
+ // TODO(gri) Optimize this for the common case.
+
+ e := int64(x.exp) + int64(y.exp)
+ if x == y {
+ z.mant = z.mant.sqr(x.mant)
+ } else {
+ z.mant = z.mant.mul(x.mant, y.mant)
+ }
+ z.setExpAndRound(e-fnorm(z.mant), 0)
+}
+
+// z = x / y, ignoring signs of x and y for the division
+// but using the sign of z for rounding the result.
+// x and y must have a non-empty mantissa and valid exponent.
+func (z *Float) uquo(x, y *Float) {
+ if debugFloat {
+ validateBinaryOperands(x, y)
+ }
+
+ // mantissa length in words for desired result precision + 1
+ // (at least one extra bit so we get the rounding bit after
+ // the division)
+ n := int(z.prec/_W) + 1
+
+ // compute adjusted x.mant such that we get enough result precision
+ xadj := x.mant
+ if d := n - len(x.mant) + len(y.mant); d > 0 {
+ // d extra words needed => add d "0 digits" to x
+ xadj = make(nat, len(x.mant)+d)
+ copy(xadj[d:], x.mant)
+ }
+ // TODO(gri): If we have too many digits (d < 0), we should be able
+ // to shorten x for faster division. But we must be extra careful
+ // with rounding in that case.
+
+ // Compute d before division since there may be aliasing of x.mant
+ // (via xadj) or y.mant with z.mant.
+ d := len(xadj) - len(y.mant)
+
+ // divide
+ var r nat
+ z.mant, r = z.mant.div(nil, xadj, y.mant)
+ e := int64(x.exp) - int64(y.exp) - int64(d-len(z.mant))*_W
+
+ // The result is long enough to include (at least) the rounding bit.
+ // If there's a non-zero remainder, the corresponding fractional part
+ // (if it were computed), would have a non-zero sticky bit (if it were
+ // zero, it couldn't have a non-zero remainder).
+ var sbit uint
+ if len(r) > 0 {
+ sbit = 1
+ }
+
+ z.setExpAndRound(e-fnorm(z.mant), sbit)
+}
+
+// ucmp returns -1, 0, or +1, depending on whether
+// |x| < |y|, |x| == |y|, or |x| > |y|.
+// x and y must have a non-empty mantissa and valid exponent.
+func (x *Float) ucmp(y *Float) int {
+ if debugFloat {
+ validateBinaryOperands(x, y)
+ }
+
+ switch {
+ case x.exp < y.exp:
+ return -1
+ case x.exp > y.exp:
+ return +1
+ }
+ // x.exp == y.exp
+
+ // compare mantissas
+ i := len(x.mant)
+ j := len(y.mant)
+ for i > 0 || j > 0 {
+ var xm, ym Word
+ if i > 0 {
+ i--
+ xm = x.mant[i]
+ }
+ if j > 0 {
+ j--
+ ym = y.mant[j]
+ }
+ switch {
+ case xm < ym:
+ return -1
+ case xm > ym:
+ return +1
+ }
+ }
+
+ return 0
+}
+
+// Handling of sign bit as defined by IEEE 754-2008, section 6.3:
+//
+// When neither the inputs nor result are NaN, the sign of a product or
+// quotient is the exclusive OR of the operands’ signs; the sign of a sum,
+// or of a difference x−y regarded as a sum x+(−y), differs from at most
+// one of the addends’ signs; and the sign of the result of conversions,
+// the quantize operation, the roundToIntegral operations, and the
+// roundToIntegralExact (see 5.3.1) is the sign of the first or only operand.
+// These rules shall apply even when operands or results are zero or infinite.
+//
+// When the sum of two operands with opposite signs (or the difference of
+// two operands with like signs) is exactly zero, the sign of that sum (or
+// difference) shall be +0 in all rounding-direction attributes except
+// roundTowardNegative; under that attribute, the sign of an exact zero
+// sum (or difference) shall be −0. However, x+x = x−(−x) retains the same
+// sign as x even when x is zero.
+//
+// See also: https://play.golang.org/p/RtH3UCt5IH
+
+// Add sets z to the rounded sum x+y and returns z. If z's precision is 0,
+// it is changed to the larger of x's or y's precision before the operation.
+// Rounding is performed according to z's precision and rounding mode; and
+// z's accuracy reports the result error relative to the exact (not rounded)
+// result. Add panics with ErrNaN if x and y are infinities with opposite
+// signs. The value of z is undefined in that case.
+func (z *Float) Add(x, y *Float) *Float {
+ if debugFloat {
+ x.validate()
+ y.validate()
+ }
+
+ if z.prec == 0 {
+ z.prec = umax32(x.prec, y.prec)
+ }
+
+ if x.form == finite && y.form == finite {
+ // x + y (common case)
+
+ // Below we set z.neg = x.neg, and when z aliases y this will
+ // change the y operand's sign. This is fine, because if an
+ // operand aliases the receiver it'll be overwritten, but we still
+ // want the original x.neg and y.neg values when we evaluate
+ // x.neg != y.neg, so we need to save y.neg before setting z.neg.
+ yneg := y.neg
+
+ z.neg = x.neg
+ if x.neg == yneg {
+ // x + y == x + y
+ // (-x) + (-y) == -(x + y)
+ z.uadd(x, y)
+ } else {
+ // x + (-y) == x - y == -(y - x)
+ // (-x) + y == y - x == -(x - y)
+ if x.ucmp(y) > 0 {
+ z.usub(x, y)
+ } else {
+ z.neg = !z.neg
+ z.usub(y, x)
+ }
+ }
+ if z.form == zero && z.mode == ToNegativeInf && z.acc == Exact {
+ z.neg = true
+ }
+ return z
+ }
+
+ if x.form == inf && y.form == inf && x.neg != y.neg {
+ // +Inf + -Inf
+ // -Inf + +Inf
+ // value of z is undefined but make sure it's valid
+ z.acc = Exact
+ z.form = zero
+ z.neg = false
+ panic(ErrNaN{"addition of infinities with opposite signs"})
+ }
+
+ if x.form == zero && y.form == zero {
+ // ±0 + ±0
+ z.acc = Exact
+ z.form = zero
+ z.neg = x.neg && y.neg // -0 + -0 == -0
+ return z
+ }
+
+ if x.form == inf || y.form == zero {
+ // ±Inf + y
+ // x + ±0
+ return z.Set(x)
+ }
+
+ // ±0 + y
+ // x + ±Inf
+ return z.Set(y)
+}
+
+// Sub sets z to the rounded difference x-y and returns z.
+// Precision, rounding, and accuracy reporting are as for Add.
+// Sub panics with ErrNaN if x and y are infinities with equal
+// signs. The value of z is undefined in that case.
+func (z *Float) Sub(x, y *Float) *Float {
+ if debugFloat {
+ x.validate()
+ y.validate()
+ }
+
+ if z.prec == 0 {
+ z.prec = umax32(x.prec, y.prec)
+ }
+
+ if x.form == finite && y.form == finite {
+ // x - y (common case)
+ yneg := y.neg
+ z.neg = x.neg
+ if x.neg != yneg {
+ // x - (-y) == x + y
+ // (-x) - y == -(x + y)
+ z.uadd(x, y)
+ } else {
+ // x - y == x - y == -(y - x)
+ // (-x) - (-y) == y - x == -(x - y)
+ if x.ucmp(y) > 0 {
+ z.usub(x, y)
+ } else {
+ z.neg = !z.neg
+ z.usub(y, x)
+ }
+ }
+ if z.form == zero && z.mode == ToNegativeInf && z.acc == Exact {
+ z.neg = true
+ }
+ return z
+ }
+
+ if x.form == inf && y.form == inf && x.neg == y.neg {
+ // +Inf - +Inf
+ // -Inf - -Inf
+ // value of z is undefined but make sure it's valid
+ z.acc = Exact
+ z.form = zero
+ z.neg = false
+ panic(ErrNaN{"subtraction of infinities with equal signs"})
+ }
+
+ if x.form == zero && y.form == zero {
+ // ±0 - ±0
+ z.acc = Exact
+ z.form = zero
+ z.neg = x.neg && !y.neg // -0 - +0 == -0
+ return z
+ }
+
+ if x.form == inf || y.form == zero {
+ // ±Inf - y
+ // x - ±0
+ return z.Set(x)
+ }
+
+ // ±0 - y
+ // x - ±Inf
+ return z.Neg(y)
+}
+
+// Mul sets z to the rounded product x*y and returns z.
+// Precision, rounding, and accuracy reporting are as for Add.
+// Mul panics with ErrNaN if one operand is zero and the other
+// operand an infinity. The value of z is undefined in that case.
+func (z *Float) Mul(x, y *Float) *Float {
+ if debugFloat {
+ x.validate()
+ y.validate()
+ }
+
+ if z.prec == 0 {
+ z.prec = umax32(x.prec, y.prec)
+ }
+
+ z.neg = x.neg != y.neg
+
+ if x.form == finite && y.form == finite {
+ // x * y (common case)
+ z.umul(x, y)
+ return z
+ }
+
+ z.acc = Exact
+ if x.form == zero && y.form == inf || x.form == inf && y.form == zero {
+ // ±0 * ±Inf
+ // ±Inf * ±0
+ // value of z is undefined but make sure it's valid
+ z.form = zero
+ z.neg = false
+ panic(ErrNaN{"multiplication of zero with infinity"})
+ }
+
+ if x.form == inf || y.form == inf {
+ // ±Inf * y
+ // x * ±Inf
+ z.form = inf
+ return z
+ }
+
+ // ±0 * y
+ // x * ±0
+ z.form = zero
+ return z
+}
+
+// Quo sets z to the rounded quotient x/y and returns z.
+// Precision, rounding, and accuracy reporting are as for Add.
+// Quo panics with ErrNaN if both operands are zero or infinities.
+// The value of z is undefined in that case.
+func (z *Float) Quo(x, y *Float) *Float {
+ if debugFloat {
+ x.validate()
+ y.validate()
+ }
+
+ if z.prec == 0 {
+ z.prec = umax32(x.prec, y.prec)
+ }
+
+ z.neg = x.neg != y.neg
+
+ if x.form == finite && y.form == finite {
+ // x / y (common case)
+ z.uquo(x, y)
+ return z
+ }
+
+ z.acc = Exact
+ if x.form == zero && y.form == zero || x.form == inf && y.form == inf {
+ // ±0 / ±0
+ // ±Inf / ±Inf
+ // value of z is undefined but make sure it's valid
+ z.form = zero
+ z.neg = false
+ panic(ErrNaN{"division of zero by zero or infinity by infinity"})
+ }
+
+ if x.form == zero || y.form == inf {
+ // ±0 / y
+ // x / ±Inf
+ z.form = zero
+ return z
+ }
+
+ // x / ±0
+ // ±Inf / y
+ z.form = inf
+ return z
+}
+
+// Cmp compares x and y and returns:
+//
+// -1 if x < y
+// 0 if x == y (incl. -0 == 0, -Inf == -Inf, and +Inf == +Inf)
+// +1 if x > y
+func (x *Float) Cmp(y *Float) int {
+ if debugFloat {
+ x.validate()
+ y.validate()
+ }
+
+ mx := x.ord()
+ my := y.ord()
+ switch {
+ case mx < my:
+ return -1
+ case mx > my:
+ return +1
+ }
+ // mx == my
+
+ // only if |mx| == 1 we have to compare the mantissae
+ switch mx {
+ case -1:
+ return y.ucmp(x)
+ case +1:
+ return x.ucmp(y)
+ }
+
+ return 0
+}
+
+// ord classifies x and returns:
+//
+// -2 if -Inf == x
+// -1 if -Inf < x < 0
+// 0 if x == 0 (signed or unsigned)
+// +1 if 0 < x < +Inf
+// +2 if x == +Inf
+func (x *Float) ord() int {
+ var m int
+ switch x.form {
+ case finite:
+ m = 1
+ case zero:
+ return 0
+ case inf:
+ m = 2
+ }
+ if x.neg {
+ m = -m
+ }
+ return m
+}
+
+func umax32(x, y uint32) uint32 {
+ if x > y {
+ return x
+ }
+ return y
+}
diff --git a/contrib/go/_std_1.21/src/math/big/floatconv.go b/contrib/go/_std_1.21/src/math/big/floatconv.go
new file mode 100644
index 0000000000..6501185fbe
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/big/floatconv.go
@@ -0,0 +1,302 @@
+// Copyright 2015 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.
+
+// This file implements string-to-Float conversion functions.
+
+package big
+
+import (
+ "fmt"
+ "io"
+ "strings"
+)
+
+var floatZero Float
+
+// SetString sets z to the value of s and returns z and a boolean indicating
+// success. s must be a floating-point number of the same format as accepted
+// by Parse, with base argument 0. The entire string (not just a prefix) must
+// be valid for success. If the operation failed, the value of z is undefined
+// but the returned value is nil.
+func (z *Float) SetString(s string) (*Float, bool) {
+ if f, _, err := z.Parse(s, 0); err == nil {
+ return f, true
+ }
+ return nil, false
+}
+
+// scan is like Parse but reads the longest possible prefix representing a valid
+// floating point number from an io.ByteScanner rather than a string. It serves
+// as the implementation of Parse. It does not recognize ±Inf and does not expect
+// EOF at the end.
+func (z *Float) scan(r io.ByteScanner, base int) (f *Float, b int, err error) {
+ prec := z.prec
+ if prec == 0 {
+ prec = 64
+ }
+
+ // A reasonable value in case of an error.
+ z.form = zero
+
+ // sign
+ z.neg, err = scanSign(r)
+ if err != nil {
+ return
+ }
+
+ // mantissa
+ var fcount int // fractional digit count; valid if <= 0
+ z.mant, b, fcount, err = z.mant.scan(r, base, true)
+ if err != nil {
+ return
+ }
+
+ // exponent
+ var exp int64
+ var ebase int
+ exp, ebase, err = scanExponent(r, true, base == 0)
+ if err != nil {
+ return
+ }
+
+ // special-case 0
+ if len(z.mant) == 0 {
+ z.prec = prec
+ z.acc = Exact
+ z.form = zero
+ f = z
+ return
+ }
+ // len(z.mant) > 0
+
+ // The mantissa may have a radix point (fcount <= 0) and there
+ // may be a nonzero exponent exp. The radix point amounts to a
+ // division by b**(-fcount). An exponent means multiplication by
+ // ebase**exp. Finally, mantissa normalization (shift left) requires
+ // a correcting multiplication by 2**(-shiftcount). Multiplications
+ // are commutative, so we can apply them in any order as long as there
+ // is no loss of precision. We only have powers of 2 and 10, and
+ // we split powers of 10 into the product of the same powers of
+ // 2 and 5. This reduces the size of the multiplication factor
+ // needed for base-10 exponents.
+
+ // normalize mantissa and determine initial exponent contributions
+ exp2 := int64(len(z.mant))*_W - fnorm(z.mant)
+ exp5 := int64(0)
+
+ // determine binary or decimal exponent contribution of radix point
+ if fcount < 0 {
+ // The mantissa has a radix point ddd.dddd; and
+ // -fcount is the number of digits to the right
+ // of '.'. Adjust relevant exponent accordingly.
+ d := int64(fcount)
+ switch b {
+ case 10:
+ exp5 = d
+ fallthrough // 10**e == 5**e * 2**e
+ case 2:
+ exp2 += d
+ case 8:
+ exp2 += d * 3 // octal digits are 3 bits each
+ case 16:
+ exp2 += d * 4 // hexadecimal digits are 4 bits each
+ default:
+ panic("unexpected mantissa base")
+ }
+ // fcount consumed - not needed anymore
+ }
+
+ // take actual exponent into account
+ switch ebase {
+ case 10:
+ exp5 += exp
+ fallthrough // see fallthrough above
+ case 2:
+ exp2 += exp
+ default:
+ panic("unexpected exponent base")
+ }
+ // exp consumed - not needed anymore
+
+ // apply 2**exp2
+ if MinExp <= exp2 && exp2 <= MaxExp {
+ z.prec = prec
+ z.form = finite
+ z.exp = int32(exp2)
+ f = z
+ } else {
+ err = fmt.Errorf("exponent overflow")
+ return
+ }
+
+ if exp5 == 0 {
+ // no decimal exponent contribution
+ z.round(0)
+ return
+ }
+ // exp5 != 0
+
+ // apply 5**exp5
+ p := new(Float).SetPrec(z.Prec() + 64) // use more bits for p -- TODO(gri) what is the right number?
+ if exp5 < 0 {
+ z.Quo(z, p.pow5(uint64(-exp5)))
+ } else {
+ z.Mul(z, p.pow5(uint64(exp5)))
+ }
+
+ return
+}
+
+// These powers of 5 fit into a uint64.
+//
+// for p, q := uint64(0), uint64(1); p < q; p, q = q, q*5 {
+// fmt.Println(q)
+// }
+var pow5tab = [...]uint64{
+ 1,
+ 5,
+ 25,
+ 125,
+ 625,
+ 3125,
+ 15625,
+ 78125,
+ 390625,
+ 1953125,
+ 9765625,
+ 48828125,
+ 244140625,
+ 1220703125,
+ 6103515625,
+ 30517578125,
+ 152587890625,
+ 762939453125,
+ 3814697265625,
+ 19073486328125,
+ 95367431640625,
+ 476837158203125,
+ 2384185791015625,
+ 11920928955078125,
+ 59604644775390625,
+ 298023223876953125,
+ 1490116119384765625,
+ 7450580596923828125,
+}
+
+// pow5 sets z to 5**n and returns z.
+// n must not be negative.
+func (z *Float) pow5(n uint64) *Float {
+ const m = uint64(len(pow5tab) - 1)
+ if n <= m {
+ return z.SetUint64(pow5tab[n])
+ }
+ // n > m
+
+ z.SetUint64(pow5tab[m])
+ n -= m
+
+ // use more bits for f than for z
+ // TODO(gri) what is the right number?
+ f := new(Float).SetPrec(z.Prec() + 64).SetUint64(5)
+
+ for n > 0 {
+ if n&1 != 0 {
+ z.Mul(z, f)
+ }
+ f.Mul(f, f)
+ n >>= 1
+ }
+
+ return z
+}
+
+// Parse parses s which must contain a text representation of a floating-
+// point number with a mantissa in the given conversion base (the exponent
+// is always a decimal number), or a string representing an infinite value.
+//
+// For base 0, an underscore character “_” may appear between a base
+// prefix and an adjacent digit, and between successive digits; such
+// underscores do not change the value of the number, or the returned
+// digit count. Incorrect placement of underscores is reported as an
+// error if there are no other errors. If base != 0, underscores are
+// not recognized and thus terminate scanning like any other character
+// that is not a valid radix point or digit.
+//
+// It sets z to the (possibly rounded) value of the corresponding floating-
+// point value, and returns z, the actual base b, and an error err, if any.
+// The entire string (not just a prefix) must be consumed for success.
+// If z's precision is 0, it is changed to 64 before rounding takes effect.
+// The number must be of the form:
+//
+// number = [ sign ] ( float | "inf" | "Inf" ) .
+// sign = "+" | "-" .
+// float = ( mantissa | prefix pmantissa ) [ exponent ] .
+// prefix = "0" [ "b" | "B" | "o" | "O" | "x" | "X" ] .
+// mantissa = digits "." [ digits ] | digits | "." digits .
+// pmantissa = [ "_" ] digits "." [ digits ] | [ "_" ] digits | "." digits .
+// exponent = ( "e" | "E" | "p" | "P" ) [ sign ] digits .
+// digits = digit { [ "_" ] digit } .
+// digit = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
+//
+// The base argument must be 0, 2, 8, 10, or 16. Providing an invalid base
+// argument will lead to a run-time panic.
+//
+// For base 0, the number prefix determines the actual base: A prefix of
+// “0b” or “0B” selects base 2, “0o” or “0O” selects base 8, and
+// “0x” or “0X” selects base 16. Otherwise, the actual base is 10 and
+// no prefix is accepted. The octal prefix "0" is not supported (a leading
+// "0" is simply considered a "0").
+//
+// A "p" or "P" exponent indicates a base 2 (rather than base 10) exponent;
+// for instance, "0x1.fffffffffffffp1023" (using base 0) represents the
+// maximum float64 value. For hexadecimal mantissae, the exponent character
+// must be one of 'p' or 'P', if present (an "e" or "E" exponent indicator
+// cannot be distinguished from a mantissa digit).
+//
+// The returned *Float f is nil and the value of z is valid but not
+// defined if an error is reported.
+func (z *Float) Parse(s string, base int) (f *Float, b int, err error) {
+ // scan doesn't handle ±Inf
+ if len(s) == 3 && (s == "Inf" || s == "inf") {
+ f = z.SetInf(false)
+ return
+ }
+ if len(s) == 4 && (s[0] == '+' || s[0] == '-') && (s[1:] == "Inf" || s[1:] == "inf") {
+ f = z.SetInf(s[0] == '-')
+ return
+ }
+
+ r := strings.NewReader(s)
+ if f, b, err = z.scan(r, base); err != nil {
+ return
+ }
+
+ // entire string must have been consumed
+ if ch, err2 := r.ReadByte(); err2 == nil {
+ err = fmt.Errorf("expected end of string, found %q", ch)
+ } else if err2 != io.EOF {
+ err = err2
+ }
+
+ return
+}
+
+// ParseFloat is like f.Parse(s, base) with f set to the given precision
+// and rounding mode.
+func ParseFloat(s string, base int, prec uint, mode RoundingMode) (f *Float, b int, err error) {
+ return new(Float).SetPrec(prec).SetMode(mode).Parse(s, base)
+}
+
+var _ fmt.Scanner = (*Float)(nil) // *Float must implement fmt.Scanner
+
+// Scan is a support routine for fmt.Scanner; it sets z to the value of
+// the scanned number. It accepts formats whose verbs are supported by
+// fmt.Scan for floating point values, which are:
+// 'b' (binary), 'e', 'E', 'f', 'F', 'g' and 'G'.
+// Scan doesn't handle ±Inf.
+func (z *Float) Scan(s fmt.ScanState, ch rune) error {
+ s.SkipSpace()
+ _, _, err := z.scan(byteReader{s}, 0)
+ return err
+}
diff --git a/contrib/go/_std_1.21/src/math/big/floatmarsh.go b/contrib/go/_std_1.21/src/math/big/floatmarsh.go
new file mode 100644
index 0000000000..2a78c69e34
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/big/floatmarsh.go
@@ -0,0 +1,131 @@
+// Copyright 2015 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.
+
+// This file implements encoding/decoding of Floats.
+
+package big
+
+import (
+ "encoding/binary"
+ "errors"
+ "fmt"
+)
+
+// Gob codec version. Permits backward-compatible changes to the encoding.
+const floatGobVersion byte = 1
+
+// GobEncode implements the gob.GobEncoder interface.
+// The Float value and all its attributes (precision,
+// rounding mode, accuracy) are marshaled.
+func (x *Float) GobEncode() ([]byte, error) {
+ if x == nil {
+ return nil, nil
+ }
+
+ // determine max. space (bytes) required for encoding
+ sz := 1 + 1 + 4 // version + mode|acc|form|neg (3+2+2+1bit) + prec
+ n := 0 // number of mantissa words
+ if x.form == finite {
+ // add space for mantissa and exponent
+ n = int((x.prec + (_W - 1)) / _W) // required mantissa length in words for given precision
+ // actual mantissa slice could be shorter (trailing 0's) or longer (unused bits):
+ // - if shorter, only encode the words present
+ // - if longer, cut off unused words when encoding in bytes
+ // (in practice, this should never happen since rounding
+ // takes care of it, but be safe and do it always)
+ if len(x.mant) < n {
+ n = len(x.mant)
+ }
+ // len(x.mant) >= n
+ sz += 4 + n*_S // exp + mant
+ }
+ buf := make([]byte, sz)
+
+ buf[0] = floatGobVersion
+ b := byte(x.mode&7)<<5 | byte((x.acc+1)&3)<<3 | byte(x.form&3)<<1
+ if x.neg {
+ b |= 1
+ }
+ buf[1] = b
+ binary.BigEndian.PutUint32(buf[2:], x.prec)
+
+ if x.form == finite {
+ binary.BigEndian.PutUint32(buf[6:], uint32(x.exp))
+ x.mant[len(x.mant)-n:].bytes(buf[10:]) // cut off unused trailing words
+ }
+
+ return buf, nil
+}
+
+// GobDecode implements the gob.GobDecoder interface.
+// The result is rounded per the precision and rounding mode of
+// z unless z's precision is 0, in which case z is set exactly
+// to the decoded value.
+func (z *Float) GobDecode(buf []byte) error {
+ if len(buf) == 0 {
+ // Other side sent a nil or default value.
+ *z = Float{}
+ return nil
+ }
+ if len(buf) < 6 {
+ return errors.New("Float.GobDecode: buffer too small")
+ }
+
+ if buf[0] != floatGobVersion {
+ return fmt.Errorf("Float.GobDecode: encoding version %d not supported", buf[0])
+ }
+
+ oldPrec := z.prec
+ oldMode := z.mode
+
+ b := buf[1]
+ z.mode = RoundingMode((b >> 5) & 7)
+ z.acc = Accuracy((b>>3)&3) - 1
+ z.form = form((b >> 1) & 3)
+ z.neg = b&1 != 0
+ z.prec = binary.BigEndian.Uint32(buf[2:])
+
+ if z.form == finite {
+ if len(buf) < 10 {
+ return errors.New("Float.GobDecode: buffer too small for finite form float")
+ }
+ z.exp = int32(binary.BigEndian.Uint32(buf[6:]))
+ z.mant = z.mant.setBytes(buf[10:])
+ }
+
+ if oldPrec != 0 {
+ z.mode = oldMode
+ z.SetPrec(uint(oldPrec))
+ }
+
+ if msg := z.validate0(); msg != "" {
+ return errors.New("Float.GobDecode: " + msg)
+ }
+
+ return nil
+}
+
+// MarshalText implements the encoding.TextMarshaler interface.
+// Only the Float value is marshaled (in full precision), other
+// attributes such as precision or accuracy are ignored.
+func (x *Float) MarshalText() (text []byte, err error) {
+ if x == nil {
+ return []byte("<nil>"), nil
+ }
+ var buf []byte
+ return x.Append(buf, 'g', -1), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface.
+// The result is rounded per the precision and rounding mode of z.
+// If z's precision is 0, it is changed to 64 before rounding takes
+// effect.
+func (z *Float) UnmarshalText(text []byte) error {
+ // TODO(gri): get rid of the []byte/string conversion
+ _, _, err := z.Parse(string(text), 0)
+ if err != nil {
+ err = fmt.Errorf("math/big: cannot unmarshal %q into a *big.Float (%v)", text, err)
+ }
+ return err
+}
diff --git a/contrib/go/_std_1.20/src/math/big/ftoa.go b/contrib/go/_std_1.21/src/math/big/ftoa.go
index 5506e6e425..5506e6e425 100644
--- a/contrib/go/_std_1.20/src/math/big/ftoa.go
+++ b/contrib/go/_std_1.21/src/math/big/ftoa.go
diff --git a/contrib/go/_std_1.21/src/math/big/int.go b/contrib/go/_std_1.21/src/math/big/int.go
new file mode 100644
index 0000000000..2cc3d7b441
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/big/int.go
@@ -0,0 +1,1321 @@
+// Copyright 2009 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.
+
+// This file implements signed multi-precision integers.
+
+package big
+
+import (
+ "fmt"
+ "io"
+ "math/rand"
+ "strings"
+)
+
+// An Int represents a signed multi-precision integer.
+// The zero value for an Int represents the value 0.
+//
+// Operations always take pointer arguments (*Int) rather
+// than Int values, and each unique Int value requires
+// its own unique *Int pointer. To "copy" an Int value,
+// an existing (or newly allocated) Int must be set to
+// a new value using the Int.Set method; shallow copies
+// of Ints are not supported and may lead to errors.
+//
+// Note that methods may leak the Int's value through timing side-channels.
+// Because of this and because of the scope and complexity of the
+// implementation, Int is not well-suited to implement cryptographic operations.
+// The standard library avoids exposing non-trivial Int methods to
+// attacker-controlled inputs and the determination of whether a bug in math/big
+// is considered a security vulnerability might depend on the impact on the
+// standard library.
+type Int struct {
+ neg bool // sign
+ abs nat // absolute value of the integer
+}
+
+var intOne = &Int{false, natOne}
+
+// Sign returns:
+//
+// -1 if x < 0
+// 0 if x == 0
+// +1 if x > 0
+func (x *Int) Sign() int {
+ // This function is used in cryptographic operations. It must not leak
+ // anything but the Int's sign and bit size through side-channels. Any
+ // changes must be reviewed by a security expert.
+ if len(x.abs) == 0 {
+ return 0
+ }
+ if x.neg {
+ return -1
+ }
+ return 1
+}
+
+// SetInt64 sets z to x and returns z.
+func (z *Int) SetInt64(x int64) *Int {
+ neg := false
+ if x < 0 {
+ neg = true
+ x = -x
+ }
+ z.abs = z.abs.setUint64(uint64(x))
+ z.neg = neg
+ return z
+}
+
+// SetUint64 sets z to x and returns z.
+func (z *Int) SetUint64(x uint64) *Int {
+ z.abs = z.abs.setUint64(x)
+ z.neg = false
+ return z
+}
+
+// NewInt allocates and returns a new Int set to x.
+func NewInt(x int64) *Int {
+ // This code is arranged to be inlineable and produce
+ // zero allocations when inlined. See issue 29951.
+ u := uint64(x)
+ if x < 0 {
+ u = -u
+ }
+ var abs []Word
+ if x == 0 {
+ } else if _W == 32 && u>>32 != 0 {
+ abs = []Word{Word(u), Word(u >> 32)}
+ } else {
+ abs = []Word{Word(u)}
+ }
+ return &Int{neg: x < 0, abs: abs}
+}
+
+// Set sets z to x and returns z.
+func (z *Int) Set(x *Int) *Int {
+ if z != x {
+ z.abs = z.abs.set(x.abs)
+ z.neg = x.neg
+ }
+ return z
+}
+
+// Bits provides raw (unchecked but fast) access to x by returning its
+// absolute value as a little-endian Word slice. The result and x share
+// the same underlying array.
+// Bits is intended to support implementation of missing low-level Int
+// functionality outside this package; it should be avoided otherwise.
+func (x *Int) Bits() []Word {
+ // This function is used in cryptographic operations. It must not leak
+ // anything but the Int's sign and bit size through side-channels. Any
+ // changes must be reviewed by a security expert.
+ return x.abs
+}
+
+// SetBits provides raw (unchecked but fast) access to z by setting its
+// value to abs, interpreted as a little-endian Word slice, and returning
+// z. The result and abs share the same underlying array.
+// SetBits is intended to support implementation of missing low-level Int
+// functionality outside this package; it should be avoided otherwise.
+func (z *Int) SetBits(abs []Word) *Int {
+ z.abs = nat(abs).norm()
+ z.neg = false
+ return z
+}
+
+// Abs sets z to |x| (the absolute value of x) and returns z.
+func (z *Int) Abs(x *Int) *Int {
+ z.Set(x)
+ z.neg = false
+ return z
+}
+
+// Neg sets z to -x and returns z.
+func (z *Int) Neg(x *Int) *Int {
+ z.Set(x)
+ z.neg = len(z.abs) > 0 && !z.neg // 0 has no sign
+ return z
+}
+
+// Add sets z to the sum x+y and returns z.
+func (z *Int) Add(x, y *Int) *Int {
+ neg := x.neg
+ if x.neg == y.neg {
+ // x + y == x + y
+ // (-x) + (-y) == -(x + y)
+ z.abs = z.abs.add(x.abs, y.abs)
+ } else {
+ // x + (-y) == x - y == -(y - x)
+ // (-x) + y == y - x == -(x - y)
+ if x.abs.cmp(y.abs) >= 0 {
+ z.abs = z.abs.sub(x.abs, y.abs)
+ } else {
+ neg = !neg
+ z.abs = z.abs.sub(y.abs, x.abs)
+ }
+ }
+ z.neg = len(z.abs) > 0 && neg // 0 has no sign
+ return z
+}
+
+// Sub sets z to the difference x-y and returns z.
+func (z *Int) Sub(x, y *Int) *Int {
+ neg := x.neg
+ if x.neg != y.neg {
+ // x - (-y) == x + y
+ // (-x) - y == -(x + y)
+ z.abs = z.abs.add(x.abs, y.abs)
+ } else {
+ // x - y == x - y == -(y - x)
+ // (-x) - (-y) == y - x == -(x - y)
+ if x.abs.cmp(y.abs) >= 0 {
+ z.abs = z.abs.sub(x.abs, y.abs)
+ } else {
+ neg = !neg
+ z.abs = z.abs.sub(y.abs, x.abs)
+ }
+ }
+ z.neg = len(z.abs) > 0 && neg // 0 has no sign
+ return z
+}
+
+// Mul sets z to the product x*y and returns z.
+func (z *Int) Mul(x, y *Int) *Int {
+ // x * y == x * y
+ // x * (-y) == -(x * y)
+ // (-x) * y == -(x * y)
+ // (-x) * (-y) == x * y
+ if x == y {
+ z.abs = z.abs.sqr(x.abs)
+ z.neg = false
+ return z
+ }
+ z.abs = z.abs.mul(x.abs, y.abs)
+ z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
+ return z
+}
+
+// MulRange sets z to the product of all integers
+// in the range [a, b] inclusively and returns z.
+// If a > b (empty range), the result is 1.
+func (z *Int) MulRange(a, b int64) *Int {
+ switch {
+ case a > b:
+ return z.SetInt64(1) // empty range
+ case a <= 0 && b >= 0:
+ return z.SetInt64(0) // range includes 0
+ }
+ // a <= b && (b < 0 || a > 0)
+
+ neg := false
+ if a < 0 {
+ neg = (b-a)&1 == 0
+ a, b = -b, -a
+ }
+
+ z.abs = z.abs.mulRange(uint64(a), uint64(b))
+ z.neg = neg
+ return z
+}
+
+// Binomial sets z to the binomial coefficient C(n, k) and returns z.
+func (z *Int) Binomial(n, k int64) *Int {
+ if k > n {
+ return z.SetInt64(0)
+ }
+ // reduce the number of multiplications by reducing k
+ if k > n-k {
+ k = n - k // C(n, k) == C(n, n-k)
+ }
+ // C(n, k) == n * (n-1) * ... * (n-k+1) / k * (k-1) * ... * 1
+ // == n * (n-1) * ... * (n-k+1) / 1 * (1+1) * ... * k
+ //
+ // Using the multiplicative formula produces smaller values
+ // at each step, requiring fewer allocations and computations:
+ //
+ // z = 1
+ // for i := 0; i < k; i = i+1 {
+ // z *= n-i
+ // z /= i+1
+ // }
+ //
+ // finally to avoid computing i+1 twice per loop:
+ //
+ // z = 1
+ // i := 0
+ // for i < k {
+ // z *= n-i
+ // i++
+ // z /= i
+ // }
+ var N, K, i, t Int
+ N.SetInt64(n)
+ K.SetInt64(k)
+ z.Set(intOne)
+ for i.Cmp(&K) < 0 {
+ z.Mul(z, t.Sub(&N, &i))
+ i.Add(&i, intOne)
+ z.Quo(z, &i)
+ }
+ return z
+}
+
+// Quo sets z to the quotient x/y for y != 0 and returns z.
+// If y == 0, a division-by-zero run-time panic occurs.
+// Quo implements truncated division (like Go); see QuoRem for more details.
+func (z *Int) Quo(x, y *Int) *Int {
+ z.abs, _ = z.abs.div(nil, x.abs, y.abs)
+ z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
+ return z
+}
+
+// Rem sets z to the remainder x%y for y != 0 and returns z.
+// If y == 0, a division-by-zero run-time panic occurs.
+// Rem implements truncated modulus (like Go); see QuoRem for more details.
+func (z *Int) Rem(x, y *Int) *Int {
+ _, z.abs = nat(nil).div(z.abs, x.abs, y.abs)
+ z.neg = len(z.abs) > 0 && x.neg // 0 has no sign
+ return z
+}
+
+// QuoRem sets z to the quotient x/y and r to the remainder x%y
+// and returns the pair (z, r) for y != 0.
+// If y == 0, a division-by-zero run-time panic occurs.
+//
+// QuoRem implements T-division and modulus (like Go):
+//
+// q = x/y with the result truncated to zero
+// r = x - y*q
+//
+// (See Daan Leijen, “Division and Modulus for Computer Scientists”.)
+// See DivMod for Euclidean division and modulus (unlike Go).
+func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int) {
+ z.abs, r.abs = z.abs.div(r.abs, x.abs, y.abs)
+ z.neg, r.neg = len(z.abs) > 0 && x.neg != y.neg, len(r.abs) > 0 && x.neg // 0 has no sign
+ return z, r
+}
+
+// Div sets z to the quotient x/y for y != 0 and returns z.
+// If y == 0, a division-by-zero run-time panic occurs.
+// Div implements Euclidean division (unlike Go); see DivMod for more details.
+func (z *Int) Div(x, y *Int) *Int {
+ y_neg := y.neg // z may be an alias for y
+ var r Int
+ z.QuoRem(x, y, &r)
+ if r.neg {
+ if y_neg {
+ z.Add(z, intOne)
+ } else {
+ z.Sub(z, intOne)
+ }
+ }
+ return z
+}
+
+// Mod sets z to the modulus x%y for y != 0 and returns z.
+// If y == 0, a division-by-zero run-time panic occurs.
+// Mod implements Euclidean modulus (unlike Go); see DivMod for more details.
+func (z *Int) Mod(x, y *Int) *Int {
+ y0 := y // save y
+ if z == y || alias(z.abs, y.abs) {
+ y0 = new(Int).Set(y)
+ }
+ var q Int
+ q.QuoRem(x, y, z)
+ if z.neg {
+ if y0.neg {
+ z.Sub(z, y0)
+ } else {
+ z.Add(z, y0)
+ }
+ }
+ return z
+}
+
+// DivMod sets z to the quotient x div y and m to the modulus x mod y
+// and returns the pair (z, m) for y != 0.
+// If y == 0, a division-by-zero run-time panic occurs.
+//
+// DivMod implements Euclidean division and modulus (unlike Go):
+//
+// q = x div y such that
+// m = x - y*q with 0 <= m < |y|
+//
+// (See Raymond T. Boute, “The Euclidean definition of the functions
+// div and mod”. ACM Transactions on Programming Languages and
+// Systems (TOPLAS), 14(2):127-144, New York, NY, USA, 4/1992.
+// ACM press.)
+// See QuoRem for T-division and modulus (like Go).
+func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) {
+ y0 := y // save y
+ if z == y || alias(z.abs, y.abs) {
+ y0 = new(Int).Set(y)
+ }
+ z.QuoRem(x, y, m)
+ if m.neg {
+ if y0.neg {
+ z.Add(z, intOne)
+ m.Sub(m, y0)
+ } else {
+ z.Sub(z, intOne)
+ m.Add(m, y0)
+ }
+ }
+ return z, m
+}
+
+// Cmp compares x and y and returns:
+//
+// -1 if x < y
+// 0 if x == y
+// +1 if x > y
+func (x *Int) Cmp(y *Int) (r int) {
+ // x cmp y == x cmp y
+ // x cmp (-y) == x
+ // (-x) cmp y == y
+ // (-x) cmp (-y) == -(x cmp y)
+ switch {
+ case x == y:
+ // nothing to do
+ case x.neg == y.neg:
+ r = x.abs.cmp(y.abs)
+ if x.neg {
+ r = -r
+ }
+ case x.neg:
+ r = -1
+ default:
+ r = 1
+ }
+ return
+}
+
+// CmpAbs compares the absolute values of x and y and returns:
+//
+// -1 if |x| < |y|
+// 0 if |x| == |y|
+// +1 if |x| > |y|
+func (x *Int) CmpAbs(y *Int) int {
+ return x.abs.cmp(y.abs)
+}
+
+// low32 returns the least significant 32 bits of x.
+func low32(x nat) uint32 {
+ if len(x) == 0 {
+ return 0
+ }
+ return uint32(x[0])
+}
+
+// low64 returns the least significant 64 bits of x.
+func low64(x nat) uint64 {
+ if len(x) == 0 {
+ return 0
+ }
+ v := uint64(x[0])
+ if _W == 32 && len(x) > 1 {
+ return uint64(x[1])<<32 | v
+ }
+ return v
+}
+
+// Int64 returns the int64 representation of x.
+// If x cannot be represented in an int64, the result is undefined.
+func (x *Int) Int64() int64 {
+ v := int64(low64(x.abs))
+ if x.neg {
+ v = -v
+ }
+ return v
+}
+
+// Uint64 returns the uint64 representation of x.
+// If x cannot be represented in a uint64, the result is undefined.
+func (x *Int) Uint64() uint64 {
+ return low64(x.abs)
+}
+
+// IsInt64 reports whether x can be represented as an int64.
+func (x *Int) IsInt64() bool {
+ if len(x.abs) <= 64/_W {
+ w := int64(low64(x.abs))
+ return w >= 0 || x.neg && w == -w
+ }
+ return false
+}
+
+// IsUint64 reports whether x can be represented as a uint64.
+func (x *Int) IsUint64() bool {
+ return !x.neg && len(x.abs) <= 64/_W
+}
+
+// Float64 returns the float64 value nearest x,
+// and an indication of any rounding that occurred.
+func (x *Int) Float64() (float64, Accuracy) {
+ n := x.abs.bitLen() // NB: still uses slow crypto impl!
+ if n == 0 {
+ return 0.0, Exact
+ }
+
+ // Fast path: no more than 53 significant bits.
+ if n <= 53 || n < 64 && n-int(x.abs.trailingZeroBits()) <= 53 {
+ f := float64(low64(x.abs))
+ if x.neg {
+ f = -f
+ }
+ return f, Exact
+ }
+
+ return new(Float).SetInt(x).Float64()
+}
+
+// SetString sets z to the value of s, interpreted in the given base,
+// and returns z and a boolean indicating success. The entire string
+// (not just a prefix) must be valid for success. If SetString fails,
+// the value of z is undefined but the returned value is nil.
+//
+// The base argument must be 0 or a value between 2 and MaxBase.
+// For base 0, the number prefix determines the actual base: A prefix of
+// “0b” or “0B” selects base 2, “0”, “0o” or “0O” selects base 8,
+// and “0x” or “0X” selects base 16. Otherwise, the selected base is 10
+// and no prefix is accepted.
+//
+// For bases <= 36, lower and upper case letters are considered the same:
+// The letters 'a' to 'z' and 'A' to 'Z' represent digit values 10 to 35.
+// For bases > 36, the upper case letters 'A' to 'Z' represent the digit
+// values 36 to 61.
+//
+// For base 0, an underscore character “_” may appear between a base
+// prefix and an adjacent digit, and between successive digits; such
+// underscores do not change the value of the number.
+// Incorrect placement of underscores is reported as an error if there
+// are no other errors. If base != 0, underscores are not recognized
+// and act like any other character that is not a valid digit.
+func (z *Int) SetString(s string, base int) (*Int, bool) {
+ return z.setFromScanner(strings.NewReader(s), base)
+}
+
+// setFromScanner implements SetString given an io.ByteScanner.
+// For documentation see comments of SetString.
+func (z *Int) setFromScanner(r io.ByteScanner, base int) (*Int, bool) {
+ if _, _, err := z.scan(r, base); err != nil {
+ return nil, false
+ }
+ // entire content must have been consumed
+ if _, err := r.ReadByte(); err != io.EOF {
+ return nil, false
+ }
+ return z, true // err == io.EOF => scan consumed all content of r
+}
+
+// SetBytes interprets buf as the bytes of a big-endian unsigned
+// integer, sets z to that value, and returns z.
+func (z *Int) SetBytes(buf []byte) *Int {
+ z.abs = z.abs.setBytes(buf)
+ z.neg = false
+ return z
+}
+
+// Bytes returns the absolute value of x as a big-endian byte slice.
+//
+// To use a fixed length slice, or a preallocated one, use FillBytes.
+func (x *Int) Bytes() []byte {
+ // This function is used in cryptographic operations. It must not leak
+ // anything but the Int's sign and bit size through side-channels. Any
+ // changes must be reviewed by a security expert.
+ buf := make([]byte, len(x.abs)*_S)
+ return buf[x.abs.bytes(buf):]
+}
+
+// FillBytes sets buf to the absolute value of x, storing it as a zero-extended
+// big-endian byte slice, and returns buf.
+//
+// If the absolute value of x doesn't fit in buf, FillBytes will panic.
+func (x *Int) FillBytes(buf []byte) []byte {
+ // Clear whole buffer. (This gets optimized into a memclr.)
+ for i := range buf {
+ buf[i] = 0
+ }
+ x.abs.bytes(buf)
+ return buf
+}
+
+// BitLen returns the length of the absolute value of x in bits.
+// The bit length of 0 is 0.
+func (x *Int) BitLen() int {
+ // This function is used in cryptographic operations. It must not leak
+ // anything but the Int's sign and bit size through side-channels. Any
+ // changes must be reviewed by a security expert.
+ return x.abs.bitLen()
+}
+
+// TrailingZeroBits returns the number of consecutive least significant zero
+// bits of |x|.
+func (x *Int) TrailingZeroBits() uint {
+ return x.abs.trailingZeroBits()
+}
+
+// Exp sets z = x**y mod |m| (i.e. the sign of m is ignored), and returns z.
+// If m == nil or m == 0, z = x**y unless y <= 0 then z = 1. If m != 0, y < 0,
+// and x and m are not relatively prime, z is unchanged and nil is returned.
+//
+// Modular exponentiation of inputs of a particular size is not a
+// cryptographically constant-time operation.
+func (z *Int) Exp(x, y, m *Int) *Int {
+ return z.exp(x, y, m, false)
+}
+
+func (z *Int) expSlow(x, y, m *Int) *Int {
+ return z.exp(x, y, m, true)
+}
+
+func (z *Int) exp(x, y, m *Int, slow bool) *Int {
+ // See Knuth, volume 2, section 4.6.3.
+ xWords := x.abs
+ if y.neg {
+ if m == nil || len(m.abs) == 0 {
+ return z.SetInt64(1)
+ }
+ // for y < 0: x**y mod m == (x**(-1))**|y| mod m
+ inverse := new(Int).ModInverse(x, m)
+ if inverse == nil {
+ return nil
+ }
+ xWords = inverse.abs
+ }
+ yWords := y.abs
+
+ var mWords nat
+ if m != nil {
+ if z == m || alias(z.abs, m.abs) {
+ m = new(Int).Set(m)
+ }
+ mWords = m.abs // m.abs may be nil for m == 0
+ }
+
+ z.abs = z.abs.expNN(xWords, yWords, mWords, slow)
+ z.neg = len(z.abs) > 0 && x.neg && len(yWords) > 0 && yWords[0]&1 == 1 // 0 has no sign
+ if z.neg && len(mWords) > 0 {
+ // make modulus result positive
+ z.abs = z.abs.sub(mWords, z.abs) // z == x**y mod |m| && 0 <= z < |m|
+ z.neg = false
+ }
+
+ return z
+}
+
+// GCD sets z to the greatest common divisor of a and b and returns z.
+// If x or y are not nil, GCD sets their value such that z = a*x + b*y.
+//
+// a and b may be positive, zero or negative. (Before Go 1.14 both had
+// to be > 0.) Regardless of the signs of a and b, z is always >= 0.
+//
+// If a == b == 0, GCD sets z = x = y = 0.
+//
+// If a == 0 and b != 0, GCD sets z = |b|, x = 0, y = sign(b) * 1.
+//
+// If a != 0 and b == 0, GCD sets z = |a|, x = sign(a) * 1, y = 0.
+func (z *Int) GCD(x, y, a, b *Int) *Int {
+ if len(a.abs) == 0 || len(b.abs) == 0 {
+ lenA, lenB, negA, negB := len(a.abs), len(b.abs), a.neg, b.neg
+ if lenA == 0 {
+ z.Set(b)
+ } else {
+ z.Set(a)
+ }
+ z.neg = false
+ if x != nil {
+ if lenA == 0 {
+ x.SetUint64(0)
+ } else {
+ x.SetUint64(1)
+ x.neg = negA
+ }
+ }
+ if y != nil {
+ if lenB == 0 {
+ y.SetUint64(0)
+ } else {
+ y.SetUint64(1)
+ y.neg = negB
+ }
+ }
+ return z
+ }
+
+ return z.lehmerGCD(x, y, a, b)
+}
+
+// lehmerSimulate attempts to simulate several Euclidean update steps
+// using the leading digits of A and B. It returns u0, u1, v0, v1
+// such that A and B can be updated as:
+//
+// A = u0*A + v0*B
+// B = u1*A + v1*B
+//
+// Requirements: A >= B and len(B.abs) >= 2
+// Since we are calculating with full words to avoid overflow,
+// we use 'even' to track the sign of the cosequences.
+// For even iterations: u0, v1 >= 0 && u1, v0 <= 0
+// For odd iterations: u0, v1 <= 0 && u1, v0 >= 0
+func lehmerSimulate(A, B *Int) (u0, u1, v0, v1 Word, even bool) {
+ // initialize the digits
+ var a1, a2, u2, v2 Word
+
+ m := len(B.abs) // m >= 2
+ n := len(A.abs) // n >= m >= 2
+
+ // extract the top Word of bits from A and B
+ h := nlz(A.abs[n-1])
+ a1 = A.abs[n-1]<<h | A.abs[n-2]>>(_W-h)
+ // B may have implicit zero words in the high bits if the lengths differ
+ switch {
+ case n == m:
+ a2 = B.abs[n-1]<<h | B.abs[n-2]>>(_W-h)
+ case n == m+1:
+ a2 = B.abs[n-2] >> (_W - h)
+ default:
+ a2 = 0
+ }
+
+ // Since we are calculating with full words to avoid overflow,
+ // we use 'even' to track the sign of the cosequences.
+ // For even iterations: u0, v1 >= 0 && u1, v0 <= 0
+ // For odd iterations: u0, v1 <= 0 && u1, v0 >= 0
+ // The first iteration starts with k=1 (odd).
+ even = false
+ // variables to track the cosequences
+ u0, u1, u2 = 0, 1, 0
+ v0, v1, v2 = 0, 0, 1
+
+ // Calculate the quotient and cosequences using Collins' stopping condition.
+ // Note that overflow of a Word is not possible when computing the remainder
+ // sequence and cosequences since the cosequence size is bounded by the input size.
+ // See section 4.2 of Jebelean for details.
+ for a2 >= v2 && a1-a2 >= v1+v2 {
+ q, r := a1/a2, a1%a2
+ a1, a2 = a2, r
+ u0, u1, u2 = u1, u2, u1+q*u2
+ v0, v1, v2 = v1, v2, v1+q*v2
+ even = !even
+ }
+ return
+}
+
+// lehmerUpdate updates the inputs A and B such that:
+//
+// A = u0*A + v0*B
+// B = u1*A + v1*B
+//
+// where the signs of u0, u1, v0, v1 are given by even
+// For even == true: u0, v1 >= 0 && u1, v0 <= 0
+// For even == false: u0, v1 <= 0 && u1, v0 >= 0
+// q, r, s, t are temporary variables to avoid allocations in the multiplication.
+func lehmerUpdate(A, B, q, r, s, t *Int, u0, u1, v0, v1 Word, even bool) {
+
+ t.abs = t.abs.setWord(u0)
+ s.abs = s.abs.setWord(v0)
+ t.neg = !even
+ s.neg = even
+
+ t.Mul(A, t)
+ s.Mul(B, s)
+
+ r.abs = r.abs.setWord(u1)
+ q.abs = q.abs.setWord(v1)
+ r.neg = even
+ q.neg = !even
+
+ r.Mul(A, r)
+ q.Mul(B, q)
+
+ A.Add(t, s)
+ B.Add(r, q)
+}
+
+// euclidUpdate performs a single step of the Euclidean GCD algorithm
+// if extended is true, it also updates the cosequence Ua, Ub.
+func euclidUpdate(A, B, Ua, Ub, q, r, s, t *Int, extended bool) {
+ q, r = q.QuoRem(A, B, r)
+
+ *A, *B, *r = *B, *r, *A
+
+ if extended {
+ // Ua, Ub = Ub, Ua - q*Ub
+ t.Set(Ub)
+ s.Mul(Ub, q)
+ Ub.Sub(Ua, s)
+ Ua.Set(t)
+ }
+}
+
+// lehmerGCD sets z to the greatest common divisor of a and b,
+// which both must be != 0, and returns z.
+// If x or y are not nil, their values are set such that z = a*x + b*y.
+// See Knuth, The Art of Computer Programming, Vol. 2, Section 4.5.2, Algorithm L.
+// This implementation uses the improved condition by Collins requiring only one
+// quotient and avoiding the possibility of single Word overflow.
+// See Jebelean, "Improving the multiprecision Euclidean algorithm",
+// Design and Implementation of Symbolic Computation Systems, pp 45-58.
+// The cosequences are updated according to Algorithm 10.45 from
+// Cohen et al. "Handbook of Elliptic and Hyperelliptic Curve Cryptography" pp 192.
+func (z *Int) lehmerGCD(x, y, a, b *Int) *Int {
+ var A, B, Ua, Ub *Int
+
+ A = new(Int).Abs(a)
+ B = new(Int).Abs(b)
+
+ extended := x != nil || y != nil
+
+ if extended {
+ // Ua (Ub) tracks how many times input a has been accumulated into A (B).
+ Ua = new(Int).SetInt64(1)
+ Ub = new(Int)
+ }
+
+ // temp variables for multiprecision update
+ q := new(Int)
+ r := new(Int)
+ s := new(Int)
+ t := new(Int)
+
+ // ensure A >= B
+ if A.abs.cmp(B.abs) < 0 {
+ A, B = B, A
+ Ub, Ua = Ua, Ub
+ }
+
+ // loop invariant A >= B
+ for len(B.abs) > 1 {
+ // Attempt to calculate in single-precision using leading words of A and B.
+ u0, u1, v0, v1, even := lehmerSimulate(A, B)
+
+ // multiprecision Step
+ if v0 != 0 {
+ // Simulate the effect of the single-precision steps using the cosequences.
+ // A = u0*A + v0*B
+ // B = u1*A + v1*B
+ lehmerUpdate(A, B, q, r, s, t, u0, u1, v0, v1, even)
+
+ if extended {
+ // Ua = u0*Ua + v0*Ub
+ // Ub = u1*Ua + v1*Ub
+ lehmerUpdate(Ua, Ub, q, r, s, t, u0, u1, v0, v1, even)
+ }
+
+ } else {
+ // Single-digit calculations failed to simulate any quotients.
+ // Do a standard Euclidean step.
+ euclidUpdate(A, B, Ua, Ub, q, r, s, t, extended)
+ }
+ }
+
+ if len(B.abs) > 0 {
+ // extended Euclidean algorithm base case if B is a single Word
+ if len(A.abs) > 1 {
+ // A is longer than a single Word, so one update is needed.
+ euclidUpdate(A, B, Ua, Ub, q, r, s, t, extended)
+ }
+ if len(B.abs) > 0 {
+ // A and B are both a single Word.
+ aWord, bWord := A.abs[0], B.abs[0]
+ if extended {
+ var ua, ub, va, vb Word
+ ua, ub = 1, 0
+ va, vb = 0, 1
+ even := true
+ for bWord != 0 {
+ q, r := aWord/bWord, aWord%bWord
+ aWord, bWord = bWord, r
+ ua, ub = ub, ua+q*ub
+ va, vb = vb, va+q*vb
+ even = !even
+ }
+
+ t.abs = t.abs.setWord(ua)
+ s.abs = s.abs.setWord(va)
+ t.neg = !even
+ s.neg = even
+
+ t.Mul(Ua, t)
+ s.Mul(Ub, s)
+
+ Ua.Add(t, s)
+ } else {
+ for bWord != 0 {
+ aWord, bWord = bWord, aWord%bWord
+ }
+ }
+ A.abs[0] = aWord
+ }
+ }
+ negA := a.neg
+ if y != nil {
+ // avoid aliasing b needed in the division below
+ if y == b {
+ B.Set(b)
+ } else {
+ B = b
+ }
+ // y = (z - a*x)/b
+ y.Mul(a, Ua) // y can safely alias a
+ if negA {
+ y.neg = !y.neg
+ }
+ y.Sub(A, y)
+ y.Div(y, B)
+ }
+
+ if x != nil {
+ *x = *Ua
+ if negA {
+ x.neg = !x.neg
+ }
+ }
+
+ *z = *A
+
+ return z
+}
+
+// Rand sets z to a pseudo-random number in [0, n) and returns z.
+//
+// As this uses the math/rand package, it must not be used for
+// security-sensitive work. Use crypto/rand.Int instead.
+func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int {
+ // z.neg is not modified before the if check, because z and n might alias.
+ if n.neg || len(n.abs) == 0 {
+ z.neg = false
+ z.abs = nil
+ return z
+ }
+ z.neg = false
+ z.abs = z.abs.random(rnd, n.abs, n.abs.bitLen())
+ return z
+}
+
+// ModInverse sets z to the multiplicative inverse of g in the ring ℤ/nℤ
+// and returns z. If g and n are not relatively prime, g has no multiplicative
+// inverse in the ring ℤ/nℤ. In this case, z is unchanged and the return value
+// is nil. If n == 0, a division-by-zero run-time panic occurs.
+func (z *Int) ModInverse(g, n *Int) *Int {
+ // GCD expects parameters a and b to be > 0.
+ if n.neg {
+ var n2 Int
+ n = n2.Neg(n)
+ }
+ if g.neg {
+ var g2 Int
+ g = g2.Mod(g, n)
+ }
+ var d, x Int
+ d.GCD(&x, nil, g, n)
+
+ // if and only if d==1, g and n are relatively prime
+ if d.Cmp(intOne) != 0 {
+ return nil
+ }
+
+ // x and y are such that g*x + n*y = 1, therefore x is the inverse element,
+ // but it may be negative, so convert to the range 0 <= z < |n|
+ if x.neg {
+ z.Add(&x, n)
+ } else {
+ z.Set(&x)
+ }
+ return z
+}
+
+func (z nat) modInverse(g, n nat) nat {
+ // TODO(rsc): ModInverse should be implemented in terms of this function.
+ return (&Int{abs: z}).ModInverse(&Int{abs: g}, &Int{abs: n}).abs
+}
+
+// Jacobi returns the Jacobi symbol (x/y), either +1, -1, or 0.
+// The y argument must be an odd integer.
+func Jacobi(x, y *Int) int {
+ if len(y.abs) == 0 || y.abs[0]&1 == 0 {
+ panic(fmt.Sprintf("big: invalid 2nd argument to Int.Jacobi: need odd integer but got %s", y.String()))
+ }
+
+ // We use the formulation described in chapter 2, section 2.4,
+ // "The Yacas Book of Algorithms":
+ // http://yacas.sourceforge.net/Algo.book.pdf
+
+ var a, b, c Int
+ a.Set(x)
+ b.Set(y)
+ j := 1
+
+ if b.neg {
+ if a.neg {
+ j = -1
+ }
+ b.neg = false
+ }
+
+ for {
+ if b.Cmp(intOne) == 0 {
+ return j
+ }
+ if len(a.abs) == 0 {
+ return 0
+ }
+ a.Mod(&a, &b)
+ if len(a.abs) == 0 {
+ return 0
+ }
+ // a > 0
+
+ // handle factors of 2 in 'a'
+ s := a.abs.trailingZeroBits()
+ if s&1 != 0 {
+ bmod8 := b.abs[0] & 7
+ if bmod8 == 3 || bmod8 == 5 {
+ j = -j
+ }
+ }
+ c.Rsh(&a, s) // a = 2^s*c
+
+ // swap numerator and denominator
+ if b.abs[0]&3 == 3 && c.abs[0]&3 == 3 {
+ j = -j
+ }
+ a.Set(&b)
+ b.Set(&c)
+ }
+}
+
+// modSqrt3Mod4 uses the identity
+//
+// (a^((p+1)/4))^2 mod p
+// == u^(p+1) mod p
+// == u^2 mod p
+//
+// to calculate the square root of any quadratic residue mod p quickly for 3
+// mod 4 primes.
+func (z *Int) modSqrt3Mod4Prime(x, p *Int) *Int {
+ e := new(Int).Add(p, intOne) // e = p + 1
+ e.Rsh(e, 2) // e = (p + 1) / 4
+ z.Exp(x, e, p) // z = x^e mod p
+ return z
+}
+
+// modSqrt5Mod8Prime uses Atkin's observation that 2 is not a square mod p
+//
+// alpha == (2*a)^((p-5)/8) mod p
+// beta == 2*a*alpha^2 mod p is a square root of -1
+// b == a*alpha*(beta-1) mod p is a square root of a
+//
+// to calculate the square root of any quadratic residue mod p quickly for 5
+// mod 8 primes.
+func (z *Int) modSqrt5Mod8Prime(x, p *Int) *Int {
+ // p == 5 mod 8 implies p = e*8 + 5
+ // e is the quotient and 5 the remainder on division by 8
+ e := new(Int).Rsh(p, 3) // e = (p - 5) / 8
+ tx := new(Int).Lsh(x, 1) // tx = 2*x
+ alpha := new(Int).Exp(tx, e, p)
+ beta := new(Int).Mul(alpha, alpha)
+ beta.Mod(beta, p)
+ beta.Mul(beta, tx)
+ beta.Mod(beta, p)
+ beta.Sub(beta, intOne)
+ beta.Mul(beta, x)
+ beta.Mod(beta, p)
+ beta.Mul(beta, alpha)
+ z.Mod(beta, p)
+ return z
+}
+
+// modSqrtTonelliShanks uses the Tonelli-Shanks algorithm to find the square
+// root of a quadratic residue modulo any prime.
+func (z *Int) modSqrtTonelliShanks(x, p *Int) *Int {
+ // Break p-1 into s*2^e such that s is odd.
+ var s Int
+ s.Sub(p, intOne)
+ e := s.abs.trailingZeroBits()
+ s.Rsh(&s, e)
+
+ // find some non-square n
+ var n Int
+ n.SetInt64(2)
+ for Jacobi(&n, p) != -1 {
+ n.Add(&n, intOne)
+ }
+
+ // Core of the Tonelli-Shanks algorithm. Follows the description in
+ // section 6 of "Square roots from 1; 24, 51, 10 to Dan Shanks" by Ezra
+ // Brown:
+ // https://www.maa.org/sites/default/files/pdf/upload_library/22/Polya/07468342.di020786.02p0470a.pdf
+ var y, b, g, t Int
+ y.Add(&s, intOne)
+ y.Rsh(&y, 1)
+ y.Exp(x, &y, p) // y = x^((s+1)/2)
+ b.Exp(x, &s, p) // b = x^s
+ g.Exp(&n, &s, p) // g = n^s
+ r := e
+ for {
+ // find the least m such that ord_p(b) = 2^m
+ var m uint
+ t.Set(&b)
+ for t.Cmp(intOne) != 0 {
+ t.Mul(&t, &t).Mod(&t, p)
+ m++
+ }
+
+ if m == 0 {
+ return z.Set(&y)
+ }
+
+ t.SetInt64(0).SetBit(&t, int(r-m-1), 1).Exp(&g, &t, p)
+ // t = g^(2^(r-m-1)) mod p
+ g.Mul(&t, &t).Mod(&g, p) // g = g^(2^(r-m)) mod p
+ y.Mul(&y, &t).Mod(&y, p)
+ b.Mul(&b, &g).Mod(&b, p)
+ r = m
+ }
+}
+
+// ModSqrt sets z to a square root of x mod p if such a square root exists, and
+// returns z. The modulus p must be an odd prime. If x is not a square mod p,
+// ModSqrt leaves z unchanged and returns nil. This function panics if p is
+// not an odd integer, its behavior is undefined if p is odd but not prime.
+func (z *Int) ModSqrt(x, p *Int) *Int {
+ switch Jacobi(x, p) {
+ case -1:
+ return nil // x is not a square mod p
+ case 0:
+ return z.SetInt64(0) // sqrt(0) mod p = 0
+ case 1:
+ break
+ }
+ if x.neg || x.Cmp(p) >= 0 { // ensure 0 <= x < p
+ x = new(Int).Mod(x, p)
+ }
+
+ switch {
+ case p.abs[0]%4 == 3:
+ // Check whether p is 3 mod 4, and if so, use the faster algorithm.
+ return z.modSqrt3Mod4Prime(x, p)
+ case p.abs[0]%8 == 5:
+ // Check whether p is 5 mod 8, use Atkin's algorithm.
+ return z.modSqrt5Mod8Prime(x, p)
+ default:
+ // Otherwise, use Tonelli-Shanks.
+ return z.modSqrtTonelliShanks(x, p)
+ }
+}
+
+// Lsh sets z = x << n and returns z.
+func (z *Int) Lsh(x *Int, n uint) *Int {
+ z.abs = z.abs.shl(x.abs, n)
+ z.neg = x.neg
+ return z
+}
+
+// Rsh sets z = x >> n and returns z.
+func (z *Int) Rsh(x *Int, n uint) *Int {
+ if x.neg {
+ // (-x) >> s == ^(x-1) >> s == ^((x-1) >> s) == -(((x-1) >> s) + 1)
+ t := z.abs.sub(x.abs, natOne) // no underflow because |x| > 0
+ t = t.shr(t, n)
+ z.abs = t.add(t, natOne)
+ z.neg = true // z cannot be zero if x is negative
+ return z
+ }
+
+ z.abs = z.abs.shr(x.abs, n)
+ z.neg = false
+ return z
+}
+
+// Bit returns the value of the i'th bit of x. That is, it
+// returns (x>>i)&1. The bit index i must be >= 0.
+func (x *Int) Bit(i int) uint {
+ if i == 0 {
+ // optimization for common case: odd/even test of x
+ if len(x.abs) > 0 {
+ return uint(x.abs[0] & 1) // bit 0 is same for -x
+ }
+ return 0
+ }
+ if i < 0 {
+ panic("negative bit index")
+ }
+ if x.neg {
+ t := nat(nil).sub(x.abs, natOne)
+ return t.bit(uint(i)) ^ 1
+ }
+
+ return x.abs.bit(uint(i))
+}
+
+// SetBit sets z to x, with x's i'th bit set to b (0 or 1).
+// That is, if b is 1 SetBit sets z = x | (1 << i);
+// if b is 0 SetBit sets z = x &^ (1 << i). If b is not 0 or 1,
+// SetBit will panic.
+func (z *Int) SetBit(x *Int, i int, b uint) *Int {
+ if i < 0 {
+ panic("negative bit index")
+ }
+ if x.neg {
+ t := z.abs.sub(x.abs, natOne)
+ t = t.setBit(t, uint(i), b^1)
+ z.abs = t.add(t, natOne)
+ z.neg = len(z.abs) > 0
+ return z
+ }
+ z.abs = z.abs.setBit(x.abs, uint(i), b)
+ z.neg = false
+ return z
+}
+
+// And sets z = x & y and returns z.
+func (z *Int) And(x, y *Int) *Int {
+ if x.neg == y.neg {
+ if x.neg {
+ // (-x) & (-y) == ^(x-1) & ^(y-1) == ^((x-1) | (y-1)) == -(((x-1) | (y-1)) + 1)
+ x1 := nat(nil).sub(x.abs, natOne)
+ y1 := nat(nil).sub(y.abs, natOne)
+ z.abs = z.abs.add(z.abs.or(x1, y1), natOne)
+ z.neg = true // z cannot be zero if x and y are negative
+ return z
+ }
+
+ // x & y == x & y
+ z.abs = z.abs.and(x.abs, y.abs)
+ z.neg = false
+ return z
+ }
+
+ // x.neg != y.neg
+ if x.neg {
+ x, y = y, x // & is symmetric
+ }
+
+ // x & (-y) == x & ^(y-1) == x &^ (y-1)
+ y1 := nat(nil).sub(y.abs, natOne)
+ z.abs = z.abs.andNot(x.abs, y1)
+ z.neg = false
+ return z
+}
+
+// AndNot sets z = x &^ y and returns z.
+func (z *Int) AndNot(x, y *Int) *Int {
+ if x.neg == y.neg {
+ if x.neg {
+ // (-x) &^ (-y) == ^(x-1) &^ ^(y-1) == ^(x-1) & (y-1) == (y-1) &^ (x-1)
+ x1 := nat(nil).sub(x.abs, natOne)
+ y1 := nat(nil).sub(y.abs, natOne)
+ z.abs = z.abs.andNot(y1, x1)
+ z.neg = false
+ return z
+ }
+
+ // x &^ y == x &^ y
+ z.abs = z.abs.andNot(x.abs, y.abs)
+ z.neg = false
+ return z
+ }
+
+ if x.neg {
+ // (-x) &^ y == ^(x-1) &^ y == ^(x-1) & ^y == ^((x-1) | y) == -(((x-1) | y) + 1)
+ x1 := nat(nil).sub(x.abs, natOne)
+ z.abs = z.abs.add(z.abs.or(x1, y.abs), natOne)
+ z.neg = true // z cannot be zero if x is negative and y is positive
+ return z
+ }
+
+ // x &^ (-y) == x &^ ^(y-1) == x & (y-1)
+ y1 := nat(nil).sub(y.abs, natOne)
+ z.abs = z.abs.and(x.abs, y1)
+ z.neg = false
+ return z
+}
+
+// Or sets z = x | y and returns z.
+func (z *Int) Or(x, y *Int) *Int {
+ if x.neg == y.neg {
+ if x.neg {
+ // (-x) | (-y) == ^(x-1) | ^(y-1) == ^((x-1) & (y-1)) == -(((x-1) & (y-1)) + 1)
+ x1 := nat(nil).sub(x.abs, natOne)
+ y1 := nat(nil).sub(y.abs, natOne)
+ z.abs = z.abs.add(z.abs.and(x1, y1), natOne)
+ z.neg = true // z cannot be zero if x and y are negative
+ return z
+ }
+
+ // x | y == x | y
+ z.abs = z.abs.or(x.abs, y.abs)
+ z.neg = false
+ return z
+ }
+
+ // x.neg != y.neg
+ if x.neg {
+ x, y = y, x // | is symmetric
+ }
+
+ // x | (-y) == x | ^(y-1) == ^((y-1) &^ x) == -(^((y-1) &^ x) + 1)
+ y1 := nat(nil).sub(y.abs, natOne)
+ z.abs = z.abs.add(z.abs.andNot(y1, x.abs), natOne)
+ z.neg = true // z cannot be zero if one of x or y is negative
+ return z
+}
+
+// Xor sets z = x ^ y and returns z.
+func (z *Int) Xor(x, y *Int) *Int {
+ if x.neg == y.neg {
+ if x.neg {
+ // (-x) ^ (-y) == ^(x-1) ^ ^(y-1) == (x-1) ^ (y-1)
+ x1 := nat(nil).sub(x.abs, natOne)
+ y1 := nat(nil).sub(y.abs, natOne)
+ z.abs = z.abs.xor(x1, y1)
+ z.neg = false
+ return z
+ }
+
+ // x ^ y == x ^ y
+ z.abs = z.abs.xor(x.abs, y.abs)
+ z.neg = false
+ return z
+ }
+
+ // x.neg != y.neg
+ if x.neg {
+ x, y = y, x // ^ is symmetric
+ }
+
+ // x ^ (-y) == x ^ ^(y-1) == ^(x ^ (y-1)) == -((x ^ (y-1)) + 1)
+ y1 := nat(nil).sub(y.abs, natOne)
+ z.abs = z.abs.add(z.abs.xor(x.abs, y1), natOne)
+ z.neg = true // z cannot be zero if only one of x or y is negative
+ return z
+}
+
+// Not sets z = ^x and returns z.
+func (z *Int) Not(x *Int) *Int {
+ if x.neg {
+ // ^(-x) == ^(^(x-1)) == x-1
+ z.abs = z.abs.sub(x.abs, natOne)
+ z.neg = false
+ return z
+ }
+
+ // ^x == -x-1 == -(x+1)
+ z.abs = z.abs.add(x.abs, natOne)
+ z.neg = true // z cannot be zero if x is positive
+ return z
+}
+
+// Sqrt sets z to ⌊√x⌋, the largest integer such that z² ≤ x, and returns z.
+// It panics if x is negative.
+func (z *Int) Sqrt(x *Int) *Int {
+ if x.neg {
+ panic("square root of negative number")
+ }
+ z.neg = false
+ z.abs = z.abs.sqrt(x.abs)
+ return z
+}
diff --git a/contrib/go/_std_1.20/src/math/big/intconv.go b/contrib/go/_std_1.21/src/math/big/intconv.go
index 04e8c24ed5..04e8c24ed5 100644
--- a/contrib/go/_std_1.20/src/math/big/intconv.go
+++ b/contrib/go/_std_1.21/src/math/big/intconv.go
diff --git a/contrib/go/_std_1.20/src/math/big/intmarsh.go b/contrib/go/_std_1.21/src/math/big/intmarsh.go
index ce429ffc11..ce429ffc11 100644
--- a/contrib/go/_std_1.20/src/math/big/intmarsh.go
+++ b/contrib/go/_std_1.21/src/math/big/intmarsh.go
diff --git a/contrib/go/_std_1.20/src/math/big/nat.go b/contrib/go/_std_1.21/src/math/big/nat.go
index 90ce6d19c4..90ce6d19c4 100644
--- a/contrib/go/_std_1.20/src/math/big/nat.go
+++ b/contrib/go/_std_1.21/src/math/big/nat.go
diff --git a/contrib/go/_std_1.20/src/math/big/natconv.go b/contrib/go/_std_1.21/src/math/big/natconv.go
index ce94f2cf72..ce94f2cf72 100644
--- a/contrib/go/_std_1.20/src/math/big/natconv.go
+++ b/contrib/go/_std_1.21/src/math/big/natconv.go
diff --git a/contrib/go/_std_1.20/src/math/big/natdiv.go b/contrib/go/_std_1.21/src/math/big/natdiv.go
index 14233a2ddb..14233a2ddb 100644
--- a/contrib/go/_std_1.20/src/math/big/natdiv.go
+++ b/contrib/go/_std_1.21/src/math/big/natdiv.go
diff --git a/contrib/go/_std_1.20/src/math/big/prime.go b/contrib/go/_std_1.21/src/math/big/prime.go
index 26688bbd64..26688bbd64 100644
--- a/contrib/go/_std_1.20/src/math/big/prime.go
+++ b/contrib/go/_std_1.21/src/math/big/prime.go
diff --git a/contrib/go/_std_1.20/src/math/big/rat.go b/contrib/go/_std_1.21/src/math/big/rat.go
index 700a643265..700a643265 100644
--- a/contrib/go/_std_1.20/src/math/big/rat.go
+++ b/contrib/go/_std_1.21/src/math/big/rat.go
diff --git a/contrib/go/_std_1.20/src/math/big/ratconv.go b/contrib/go/_std_1.21/src/math/big/ratconv.go
index 8537a6795f..8537a6795f 100644
--- a/contrib/go/_std_1.20/src/math/big/ratconv.go
+++ b/contrib/go/_std_1.21/src/math/big/ratconv.go
diff --git a/contrib/go/_std_1.20/src/math/big/ratmarsh.go b/contrib/go/_std_1.21/src/math/big/ratmarsh.go
index b69c59dfb6..b69c59dfb6 100644
--- a/contrib/go/_std_1.20/src/math/big/ratmarsh.go
+++ b/contrib/go/_std_1.21/src/math/big/ratmarsh.go
diff --git a/contrib/go/_std_1.21/src/math/big/roundingmode_string.go b/contrib/go/_std_1.21/src/math/big/roundingmode_string.go
new file mode 100644
index 0000000000..e2f13a63b7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/big/roundingmode_string.go
@@ -0,0 +1,28 @@
+// Code generated by "stringer -type=RoundingMode"; DO NOT EDIT.
+
+package big
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[ToNearestEven-0]
+ _ = x[ToNearestAway-1]
+ _ = x[ToZero-2]
+ _ = x[AwayFromZero-3]
+ _ = x[ToNegativeInf-4]
+ _ = x[ToPositiveInf-5]
+}
+
+const _RoundingMode_name = "ToNearestEvenToNearestAwayToZeroAwayFromZeroToNegativeInfToPositiveInf"
+
+var _RoundingMode_index = [...]uint8{0, 13, 26, 32, 44, 57, 70}
+
+func (i RoundingMode) String() string {
+ if i >= RoundingMode(len(_RoundingMode_index)-1) {
+ return "RoundingMode(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _RoundingMode_name[_RoundingMode_index[i]:_RoundingMode_index[i+1]]
+}
diff --git a/contrib/go/_std_1.20/src/math/big/sqrt.go b/contrib/go/_std_1.21/src/math/big/sqrt.go
index b4b03743f4..b4b03743f4 100644
--- a/contrib/go/_std_1.20/src/math/big/sqrt.go
+++ b/contrib/go/_std_1.21/src/math/big/sqrt.go
diff --git a/contrib/go/_std_1.21/src/math/big/ya.make b/contrib/go/_std_1.21/src/math/big/ya.make
new file mode 100644
index 0000000000..9e8286269d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/big/ya.make
@@ -0,0 +1,73 @@
+GO_LIBRARY()
+
+SRCS(
+ accuracy_string.go
+ arith.go
+ arith_decl.go
+ decimal.go
+ doc.go
+ float.go
+ floatconv.go
+ floatmarsh.go
+ ftoa.go
+ int.go
+ intconv.go
+ intmarsh.go
+ nat.go
+ natconv.go
+ natdiv.go
+ prime.go
+ rat.go
+ ratconv.go
+ ratmarsh.go
+ roundingmode_string.go
+ sqrt.go
+)
+
+GO_TEST_SRCS(
+ arith_test.go
+ bits_test.go
+ calibrate_test.go
+ decimal_test.go
+ float_test.go
+ floatconv_test.go
+ floatmarsh_test.go
+ gcd_test.go
+ hilbert_test.go
+ int_test.go
+ intconv_test.go
+ intmarsh_test.go
+ link_test.go
+ nat_test.go
+ natconv_test.go
+ prime_test.go
+ rat_test.go
+ ratconv_test.go
+ ratmarsh_test.go
+ sqrt_test.go
+)
+
+GO_XTEST_SRCS(
+ alias_test.go
+ example_rat_test.go
+ example_test.go
+ floatexample_test.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ arith_amd64.go
+ arith_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ arith_arm64.s
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/math/bits.go b/contrib/go/_std_1.21/src/math/bits.go
index c5cb93b159..c5cb93b159 100644
--- a/contrib/go/_std_1.20/src/math/bits.go
+++ b/contrib/go/_std_1.21/src/math/bits.go
diff --git a/contrib/go/_std_1.20/src/math/bits/bits.go b/contrib/go/_std_1.21/src/math/bits/bits.go
index c1c7b7978a..c1c7b7978a 100644
--- a/contrib/go/_std_1.20/src/math/bits/bits.go
+++ b/contrib/go/_std_1.21/src/math/bits/bits.go
diff --git a/contrib/go/_std_1.20/src/math/bits/bits_errors.go b/contrib/go/_std_1.21/src/math/bits/bits_errors.go
index 61cb5c9457..61cb5c9457 100644
--- a/contrib/go/_std_1.20/src/math/bits/bits_errors.go
+++ b/contrib/go/_std_1.21/src/math/bits/bits_errors.go
diff --git a/contrib/go/_std_1.20/src/math/bits/bits_tables.go b/contrib/go/_std_1.21/src/math/bits/bits_tables.go
index f869b8d5c3..f869b8d5c3 100644
--- a/contrib/go/_std_1.20/src/math/bits/bits_tables.go
+++ b/contrib/go/_std_1.21/src/math/bits/bits_tables.go
diff --git a/contrib/go/_std_1.21/src/math/bits/ya.make b/contrib/go/_std_1.21/src/math/bits/ya.make
new file mode 100644
index 0000000000..d8b74d5ee8
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/bits/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ bits.go
+ bits_errors.go
+ bits_tables.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ bits_test.go
+ example_math_test.go
+ example_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/math/cbrt.go b/contrib/go/_std_1.21/src/math/cbrt.go
index e5e9548cb1..e5e9548cb1 100644
--- a/contrib/go/_std_1.20/src/math/cbrt.go
+++ b/contrib/go/_std_1.21/src/math/cbrt.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/abs.go b/contrib/go/_std_1.21/src/math/cmplx/abs.go
index 2f89d1bcfc..2f89d1bcfc 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/abs.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/abs.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/asin.go b/contrib/go/_std_1.21/src/math/cmplx/asin.go
index 30d019e9d4..30d019e9d4 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/asin.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/asin.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/conj.go b/contrib/go/_std_1.21/src/math/cmplx/conj.go
index 34a4277c11..34a4277c11 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/conj.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/conj.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/exp.go b/contrib/go/_std_1.21/src/math/cmplx/exp.go
index d5d0a5d470..d5d0a5d470 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/exp.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/exp.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/isinf.go b/contrib/go/_std_1.21/src/math/cmplx/isinf.go
index 6273cd3a6c..6273cd3a6c 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/isinf.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/isinf.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/isnan.go b/contrib/go/_std_1.21/src/math/cmplx/isnan.go
index fed442cb48..fed442cb48 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/isnan.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/isnan.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/log.go b/contrib/go/_std_1.21/src/math/cmplx/log.go
index fd39c76cde..fd39c76cde 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/log.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/log.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/phase.go b/contrib/go/_std_1.21/src/math/cmplx/phase.go
index 03cece8a57..03cece8a57 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/phase.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/phase.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/polar.go b/contrib/go/_std_1.21/src/math/cmplx/polar.go
index 9b192bc624..9b192bc624 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/polar.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/polar.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/pow.go b/contrib/go/_std_1.21/src/math/cmplx/pow.go
index 666bba28c5..666bba28c5 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/pow.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/pow.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/rect.go b/contrib/go/_std_1.21/src/math/cmplx/rect.go
index bf94d787ea..bf94d787ea 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/rect.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/rect.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/sin.go b/contrib/go/_std_1.21/src/math/cmplx/sin.go
index 51cf40566d..51cf40566d 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/sin.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/sin.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/sqrt.go b/contrib/go/_std_1.21/src/math/cmplx/sqrt.go
index eddce2fdfb..eddce2fdfb 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/sqrt.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/sqrt.go
diff --git a/contrib/go/_std_1.20/src/math/cmplx/tan.go b/contrib/go/_std_1.21/src/math/cmplx/tan.go
index 67a1133a6f..67a1133a6f 100644
--- a/contrib/go/_std_1.20/src/math/cmplx/tan.go
+++ b/contrib/go/_std_1.21/src/math/cmplx/tan.go
diff --git a/contrib/go/_std_1.21/src/math/cmplx/ya.make b/contrib/go/_std_1.21/src/math/cmplx/ya.make
new file mode 100644
index 0000000000..26950e0f75
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/cmplx/ya.make
@@ -0,0 +1,30 @@
+GO_LIBRARY()
+
+SRCS(
+ abs.go
+ asin.go
+ conj.go
+ exp.go
+ isinf.go
+ isnan.go
+ log.go
+ phase.go
+ polar.go
+ pow.go
+ rect.go
+ sin.go
+ sqrt.go
+ tan.go
+)
+
+GO_TEST_SRCS(
+ cmath_test.go
+ huge_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/math/const.go b/contrib/go/_std_1.21/src/math/const.go
index b15e50e018..b15e50e018 100644
--- a/contrib/go/_std_1.20/src/math/const.go
+++ b/contrib/go/_std_1.21/src/math/const.go
diff --git a/contrib/go/_std_1.20/src/math/copysign.go b/contrib/go/_std_1.21/src/math/copysign.go
index 3a30afb413..3a30afb413 100644
--- a/contrib/go/_std_1.20/src/math/copysign.go
+++ b/contrib/go/_std_1.21/src/math/copysign.go
diff --git a/contrib/go/_std_1.21/src/math/dim.go b/contrib/go/_std_1.21/src/math/dim.go
new file mode 100644
index 0000000000..f369f70f00
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/dim.go
@@ -0,0 +1,100 @@
+// Copyright 2010 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 math
+
+// Dim returns the maximum of x-y or 0.
+//
+// Special cases are:
+//
+// Dim(+Inf, +Inf) = NaN
+// Dim(-Inf, -Inf) = NaN
+// Dim(x, NaN) = Dim(NaN, x) = NaN
+func Dim(x, y float64) float64 {
+ // The special cases result in NaN after the subtraction:
+ // +Inf - +Inf = NaN
+ // -Inf - -Inf = NaN
+ // NaN - y = NaN
+ // x - NaN = NaN
+ v := x - y
+ if v <= 0 {
+ // v is negative or 0
+ return 0
+ }
+ // v is positive or NaN
+ return v
+}
+
+// Max returns the larger of x or y.
+//
+// Special cases are:
+//
+// Max(x, +Inf) = Max(+Inf, x) = +Inf
+// Max(x, NaN) = Max(NaN, x) = NaN
+// Max(+0, ±0) = Max(±0, +0) = +0
+// Max(-0, -0) = -0
+//
+// Note that this differs from the built-in function max when called
+// with NaN and +Inf.
+func Max(x, y float64) float64 {
+ if haveArchMax {
+ return archMax(x, y)
+ }
+ return max(x, y)
+}
+
+func max(x, y float64) float64 {
+ // special cases
+ switch {
+ case IsInf(x, 1) || IsInf(y, 1):
+ return Inf(1)
+ case IsNaN(x) || IsNaN(y):
+ return NaN()
+ case x == 0 && x == y:
+ if Signbit(x) {
+ return y
+ }
+ return x
+ }
+ if x > y {
+ return x
+ }
+ return y
+}
+
+// Min returns the smaller of x or y.
+//
+// Special cases are:
+//
+// Min(x, -Inf) = Min(-Inf, x) = -Inf
+// Min(x, NaN) = Min(NaN, x) = NaN
+// Min(-0, ±0) = Min(±0, -0) = -0
+//
+// Note that this differs from the built-in function min when called
+// with NaN and -Inf.
+func Min(x, y float64) float64 {
+ if haveArchMin {
+ return archMin(x, y)
+ }
+ return min(x, y)
+}
+
+func min(x, y float64) float64 {
+ // special cases
+ switch {
+ case IsInf(x, -1) || IsInf(y, -1):
+ return Inf(-1)
+ case IsNaN(x) || IsNaN(y):
+ return NaN()
+ case x == 0 && x == y:
+ if Signbit(x) {
+ return x
+ }
+ return y
+ }
+ if x < y {
+ return x
+ }
+ return y
+}
diff --git a/contrib/go/_std_1.20/src/math/dim_amd64.s b/contrib/go/_std_1.21/src/math/dim_amd64.s
index 253f03b97e..253f03b97e 100644
--- a/contrib/go/_std_1.20/src/math/dim_amd64.s
+++ b/contrib/go/_std_1.21/src/math/dim_amd64.s
diff --git a/contrib/go/_std_1.20/src/math/dim_arm64.s b/contrib/go/_std_1.21/src/math/dim_arm64.s
index f112003dc0..f112003dc0 100644
--- a/contrib/go/_std_1.20/src/math/dim_arm64.s
+++ b/contrib/go/_std_1.21/src/math/dim_arm64.s
diff --git a/contrib/go/_std_1.20/src/math/dim_asm.go b/contrib/go/_std_1.21/src/math/dim_asm.go
index f4adbd0ae5..f4adbd0ae5 100644
--- a/contrib/go/_std_1.20/src/math/dim_asm.go
+++ b/contrib/go/_std_1.21/src/math/dim_asm.go
diff --git a/contrib/go/_std_1.20/src/math/erf.go b/contrib/go/_std_1.21/src/math/erf.go
index ba00c7d03e..ba00c7d03e 100644
--- a/contrib/go/_std_1.20/src/math/erf.go
+++ b/contrib/go/_std_1.21/src/math/erf.go
diff --git a/contrib/go/_std_1.20/src/math/erfinv.go b/contrib/go/_std_1.21/src/math/erfinv.go
index eed0feb42d..eed0feb42d 100644
--- a/contrib/go/_std_1.20/src/math/erfinv.go
+++ b/contrib/go/_std_1.21/src/math/erfinv.go
diff --git a/contrib/go/_std_1.20/src/math/exp.go b/contrib/go/_std_1.21/src/math/exp.go
index 760795f46f..760795f46f 100644
--- a/contrib/go/_std_1.20/src/math/exp.go
+++ b/contrib/go/_std_1.21/src/math/exp.go
diff --git a/contrib/go/_std_1.20/src/math/exp2_asm.go b/contrib/go/_std_1.21/src/math/exp2_asm.go
index c26b2c3fab..c26b2c3fab 100644
--- a/contrib/go/_std_1.20/src/math/exp2_asm.go
+++ b/contrib/go/_std_1.21/src/math/exp2_asm.go
diff --git a/contrib/go/_std_1.20/src/math/exp2_noasm.go b/contrib/go/_std_1.21/src/math/exp2_noasm.go
index c2b409329f..c2b409329f 100644
--- a/contrib/go/_std_1.20/src/math/exp2_noasm.go
+++ b/contrib/go/_std_1.21/src/math/exp2_noasm.go
diff --git a/contrib/go/_std_1.20/src/math/exp_amd64.go b/contrib/go/_std_1.21/src/math/exp_amd64.go
index 0f701b1d6d..0f701b1d6d 100644
--- a/contrib/go/_std_1.20/src/math/exp_amd64.go
+++ b/contrib/go/_std_1.21/src/math/exp_amd64.go
diff --git a/contrib/go/_std_1.20/src/math/exp_amd64.s b/contrib/go/_std_1.21/src/math/exp_amd64.s
index 02b71c81eb..02b71c81eb 100644
--- a/contrib/go/_std_1.20/src/math/exp_amd64.s
+++ b/contrib/go/_std_1.21/src/math/exp_amd64.s
diff --git a/contrib/go/_std_1.20/src/math/exp_arm64.s b/contrib/go/_std_1.21/src/math/exp_arm64.s
index 44673abefe..44673abefe 100644
--- a/contrib/go/_std_1.20/src/math/exp_arm64.s
+++ b/contrib/go/_std_1.21/src/math/exp_arm64.s
diff --git a/contrib/go/_std_1.20/src/math/exp_asm.go b/contrib/go/_std_1.21/src/math/exp_asm.go
index 424442845b..424442845b 100644
--- a/contrib/go/_std_1.20/src/math/exp_asm.go
+++ b/contrib/go/_std_1.21/src/math/exp_asm.go
diff --git a/contrib/go/_std_1.20/src/math/expm1.go b/contrib/go/_std_1.21/src/math/expm1.go
index ff1c82f524..ff1c82f524 100644
--- a/contrib/go/_std_1.20/src/math/expm1.go
+++ b/contrib/go/_std_1.21/src/math/expm1.go
diff --git a/contrib/go/_std_1.20/src/math/floor.go b/contrib/go/_std_1.21/src/math/floor.go
index cb5856424b..cb5856424b 100644
--- a/contrib/go/_std_1.20/src/math/floor.go
+++ b/contrib/go/_std_1.21/src/math/floor.go
diff --git a/contrib/go/_std_1.20/src/math/floor_amd64.s b/contrib/go/_std_1.21/src/math/floor_amd64.s
index 088049958a..088049958a 100644
--- a/contrib/go/_std_1.20/src/math/floor_amd64.s
+++ b/contrib/go/_std_1.21/src/math/floor_amd64.s
diff --git a/contrib/go/_std_1.20/src/math/floor_arm64.s b/contrib/go/_std_1.21/src/math/floor_arm64.s
index d9c5df7b24..d9c5df7b24 100644
--- a/contrib/go/_std_1.20/src/math/floor_arm64.s
+++ b/contrib/go/_std_1.21/src/math/floor_arm64.s
diff --git a/contrib/go/_std_1.20/src/math/floor_asm.go b/contrib/go/_std_1.21/src/math/floor_asm.go
index fb419d6da2..fb419d6da2 100644
--- a/contrib/go/_std_1.20/src/math/floor_asm.go
+++ b/contrib/go/_std_1.21/src/math/floor_asm.go
diff --git a/contrib/go/_std_1.21/src/math/fma.go b/contrib/go/_std_1.21/src/math/fma.go
new file mode 100644
index 0000000000..ba03fbe8a9
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/fma.go
@@ -0,0 +1,175 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package math
+
+import "math/bits"
+
+func zero(x uint64) uint64 {
+ if x == 0 {
+ return 1
+ }
+ return 0
+ // branchless:
+ // return ((x>>1 | x&1) - 1) >> 63
+}
+
+func nonzero(x uint64) uint64 {
+ if x != 0 {
+ return 1
+ }
+ return 0
+ // branchless:
+ // return 1 - ((x>>1|x&1)-1)>>63
+}
+
+func shl(u1, u2 uint64, n uint) (r1, r2 uint64) {
+ r1 = u1<<n | u2>>(64-n) | u2<<(n-64)
+ r2 = u2 << n
+ return
+}
+
+func shr(u1, u2 uint64, n uint) (r1, r2 uint64) {
+ r2 = u2>>n | u1<<(64-n) | u1>>(n-64)
+ r1 = u1 >> n
+ return
+}
+
+// shrcompress compresses the bottom n+1 bits of the two-word
+// value into a single bit. the result is equal to the value
+// shifted to the right by n, except the result's 0th bit is
+// set to the bitwise OR of the bottom n+1 bits.
+func shrcompress(u1, u2 uint64, n uint) (r1, r2 uint64) {
+ // TODO: Performance here is really sensitive to the
+ // order/placement of these branches. n == 0 is common
+ // enough to be in the fast path. Perhaps more measurement
+ // needs to be done to find the optimal order/placement?
+ switch {
+ case n == 0:
+ return u1, u2
+ case n == 64:
+ return 0, u1 | nonzero(u2)
+ case n >= 128:
+ return 0, nonzero(u1 | u2)
+ case n < 64:
+ r1, r2 = shr(u1, u2, n)
+ r2 |= nonzero(u2 & (1<<n - 1))
+ case n < 128:
+ r1, r2 = shr(u1, u2, n)
+ r2 |= nonzero(u1&(1<<(n-64)-1) | u2)
+ }
+ return
+}
+
+func lz(u1, u2 uint64) (l int32) {
+ l = int32(bits.LeadingZeros64(u1))
+ if l == 64 {
+ l += int32(bits.LeadingZeros64(u2))
+ }
+ return l
+}
+
+// split splits b into sign, biased exponent, and mantissa.
+// It adds the implicit 1 bit to the mantissa for normal values,
+// and normalizes subnormal values.
+func split(b uint64) (sign uint32, exp int32, mantissa uint64) {
+ sign = uint32(b >> 63)
+ exp = int32(b>>52) & mask
+ mantissa = b & fracMask
+
+ if exp == 0 {
+ // Normalize value if subnormal.
+ shift := uint(bits.LeadingZeros64(mantissa) - 11)
+ mantissa <<= shift
+ exp = 1 - int32(shift)
+ } else {
+ // Add implicit 1 bit
+ mantissa |= 1 << 52
+ }
+ return
+}
+
+// FMA returns x * y + z, computed with only one rounding.
+// (That is, FMA returns the fused multiply-add of x, y, and z.)
+func FMA(x, y, z float64) float64 {
+ bx, by, bz := Float64bits(x), Float64bits(y), Float64bits(z)
+
+ // Inf or NaN or zero involved. At most one rounding will occur.
+ if x == 0.0 || y == 0.0 || z == 0.0 || bx&uvinf == uvinf || by&uvinf == uvinf {
+ return x*y + z
+ }
+ // Handle non-finite z separately. Evaluating x*y+z where
+ // x and y are finite, but z is infinite, should always result in z.
+ if bz&uvinf == uvinf {
+ return z
+ }
+
+ // Inputs are (sub)normal.
+ // Split x, y, z into sign, exponent, mantissa.
+ xs, xe, xm := split(bx)
+ ys, ye, ym := split(by)
+ zs, ze, zm := split(bz)
+
+ // Compute product p = x*y as sign, exponent, two-word mantissa.
+ // Start with exponent. "is normal" bit isn't subtracted yet.
+ pe := xe + ye - bias + 1
+
+ // pm1:pm2 is the double-word mantissa for the product p.
+ // Shift left to leave top bit in product. Effectively
+ // shifts the 106-bit product to the left by 21.
+ pm1, pm2 := bits.Mul64(xm<<10, ym<<11)
+ zm1, zm2 := zm<<10, uint64(0)
+ ps := xs ^ ys // product sign
+
+ // normalize to 62nd bit
+ is62zero := uint((^pm1 >> 62) & 1)
+ pm1, pm2 = shl(pm1, pm2, is62zero)
+ pe -= int32(is62zero)
+
+ // Swap addition operands so |p| >= |z|
+ if pe < ze || pe == ze && pm1 < zm1 {
+ ps, pe, pm1, pm2, zs, ze, zm1, zm2 = zs, ze, zm1, zm2, ps, pe, pm1, pm2
+ }
+
+ // Special case: if p == -z the result is always +0 since neither operand is zero.
+ if ps != zs && pe == ze && pm1 == zm1 && pm2 == zm2 {
+ return 0
+ }
+
+ // Align significands
+ zm1, zm2 = shrcompress(zm1, zm2, uint(pe-ze))
+
+ // Compute resulting significands, normalizing if necessary.
+ var m, c uint64
+ if ps == zs {
+ // Adding (pm1:pm2) + (zm1:zm2)
+ pm2, c = bits.Add64(pm2, zm2, 0)
+ pm1, _ = bits.Add64(pm1, zm1, c)
+ pe -= int32(^pm1 >> 63)
+ pm1, m = shrcompress(pm1, pm2, uint(64+pm1>>63))
+ } else {
+ // Subtracting (pm1:pm2) - (zm1:zm2)
+ // TODO: should we special-case cancellation?
+ pm2, c = bits.Sub64(pm2, zm2, 0)
+ pm1, _ = bits.Sub64(pm1, zm1, c)
+ nz := lz(pm1, pm2)
+ pe -= nz
+ m, pm2 = shl(pm1, pm2, uint(nz-1))
+ m |= nonzero(pm2)
+ }
+
+ // Round and break ties to even
+ if pe > 1022+bias || pe == 1022+bias && (m+1<<9)>>63 == 1 {
+ // rounded value overflows exponent range
+ return Float64frombits(uint64(ps)<<63 | uvinf)
+ }
+ if pe < 0 {
+ n := uint(-pe)
+ m = m>>n | nonzero(m&(1<<n-1))
+ pe = 0
+ }
+ m = ((m + 1<<9) >> 10) & ^zero((m&(1<<10-1))^1<<9)
+ pe &= -int32(nonzero(m))
+ return Float64frombits(uint64(ps)<<63 + uint64(pe)<<52 + m)
+}
diff --git a/contrib/go/_std_1.20/src/math/frexp.go b/contrib/go/_std_1.21/src/math/frexp.go
index e194947e64..e194947e64 100644
--- a/contrib/go/_std_1.20/src/math/frexp.go
+++ b/contrib/go/_std_1.21/src/math/frexp.go
diff --git a/contrib/go/_std_1.20/src/math/gamma.go b/contrib/go/_std_1.21/src/math/gamma.go
index 86c6723258..86c6723258 100644
--- a/contrib/go/_std_1.20/src/math/gamma.go
+++ b/contrib/go/_std_1.21/src/math/gamma.go
diff --git a/contrib/go/_std_1.20/src/math/hypot.go b/contrib/go/_std_1.21/src/math/hypot.go
index 6ae70c1333..6ae70c1333 100644
--- a/contrib/go/_std_1.20/src/math/hypot.go
+++ b/contrib/go/_std_1.21/src/math/hypot.go
diff --git a/contrib/go/_std_1.20/src/math/hypot_amd64.s b/contrib/go/_std_1.21/src/math/hypot_amd64.s
index fe326c9281..fe326c9281 100644
--- a/contrib/go/_std_1.20/src/math/hypot_amd64.s
+++ b/contrib/go/_std_1.21/src/math/hypot_amd64.s
diff --git a/contrib/go/_std_1.20/src/math/hypot_asm.go b/contrib/go/_std_1.21/src/math/hypot_asm.go
index 852691037f..852691037f 100644
--- a/contrib/go/_std_1.20/src/math/hypot_asm.go
+++ b/contrib/go/_std_1.21/src/math/hypot_asm.go
diff --git a/contrib/go/_std_1.20/src/math/hypot_noasm.go b/contrib/go/_std_1.21/src/math/hypot_noasm.go
index 8b64812a1c..8b64812a1c 100644
--- a/contrib/go/_std_1.20/src/math/hypot_noasm.go
+++ b/contrib/go/_std_1.21/src/math/hypot_noasm.go
diff --git a/contrib/go/_std_1.20/src/math/j0.go b/contrib/go/_std_1.21/src/math/j0.go
index a311e18d62..a311e18d62 100644
--- a/contrib/go/_std_1.20/src/math/j0.go
+++ b/contrib/go/_std_1.21/src/math/j0.go
diff --git a/contrib/go/_std_1.20/src/math/j1.go b/contrib/go/_std_1.21/src/math/j1.go
index cc19e75b95..cc19e75b95 100644
--- a/contrib/go/_std_1.20/src/math/j1.go
+++ b/contrib/go/_std_1.21/src/math/j1.go
diff --git a/contrib/go/_std_1.20/src/math/jn.go b/contrib/go/_std_1.21/src/math/jn.go
index 3491692a96..3491692a96 100644
--- a/contrib/go/_std_1.20/src/math/jn.go
+++ b/contrib/go/_std_1.21/src/math/jn.go
diff --git a/contrib/go/_std_1.20/src/math/ldexp.go b/contrib/go/_std_1.21/src/math/ldexp.go
index df365c0b1a..df365c0b1a 100644
--- a/contrib/go/_std_1.20/src/math/ldexp.go
+++ b/contrib/go/_std_1.21/src/math/ldexp.go
diff --git a/contrib/go/_std_1.20/src/math/lgamma.go b/contrib/go/_std_1.21/src/math/lgamma.go
index 4058ad6631..4058ad6631 100644
--- a/contrib/go/_std_1.20/src/math/lgamma.go
+++ b/contrib/go/_std_1.21/src/math/lgamma.go
diff --git a/contrib/go/_std_1.20/src/math/log.go b/contrib/go/_std_1.21/src/math/log.go
index 695a545e7f..695a545e7f 100644
--- a/contrib/go/_std_1.20/src/math/log.go
+++ b/contrib/go/_std_1.21/src/math/log.go
diff --git a/contrib/go/_std_1.20/src/math/log10.go b/contrib/go/_std_1.21/src/math/log10.go
index e6916a53b6..e6916a53b6 100644
--- a/contrib/go/_std_1.20/src/math/log10.go
+++ b/contrib/go/_std_1.21/src/math/log10.go
diff --git a/contrib/go/_std_1.20/src/math/log1p.go b/contrib/go/_std_1.21/src/math/log1p.go
index 3a7b3854a8..3a7b3854a8 100644
--- a/contrib/go/_std_1.20/src/math/log1p.go
+++ b/contrib/go/_std_1.21/src/math/log1p.go
diff --git a/contrib/go/_std_1.21/src/math/log_amd64.s b/contrib/go/_std_1.21/src/math/log_amd64.s
new file mode 100644
index 0000000000..508df68a9b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/log_amd64.s
@@ -0,0 +1,112 @@
+// Copyright 2010 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.
+
+#include "textflag.h"
+
+#define HSqrt2 7.07106781186547524401e-01 // sqrt(2)/2
+#define Ln2Hi 6.93147180369123816490e-01 // 0x3fe62e42fee00000
+#define Ln2Lo 1.90821492927058770002e-10 // 0x3dea39ef35793c76
+#define L1 6.666666666666735130e-01 // 0x3FE5555555555593
+#define L2 3.999999999940941908e-01 // 0x3FD999999997FA04
+#define L3 2.857142874366239149e-01 // 0x3FD2492494229359
+#define L4 2.222219843214978396e-01 // 0x3FCC71C51D8E78AF
+#define L5 1.818357216161805012e-01 // 0x3FC7466496CB03DE
+#define L6 1.531383769920937332e-01 // 0x3FC39A09D078C69F
+#define L7 1.479819860511658591e-01 // 0x3FC2F112DF3E5244
+#define NaN 0x7FF8000000000001
+#define NegInf 0xFFF0000000000000
+#define PosInf 0x7FF0000000000000
+
+// func Log(x float64) float64
+TEXT ·archLog(SB),NOSPLIT,$0
+ // test bits for special cases
+ MOVQ x+0(FP), BX
+ MOVQ $~(1<<63), AX // sign bit mask
+ ANDQ BX, AX
+ JEQ isZero
+ MOVQ $0, AX
+ CMPQ AX, BX
+ JGT isNegative
+ MOVQ $PosInf, AX
+ CMPQ AX, BX
+ JLE isInfOrNaN
+ // f1, ki := math.Frexp(x); k := float64(ki)
+ MOVQ BX, X0
+ MOVQ $0x000FFFFFFFFFFFFF, AX
+ MOVQ AX, X2
+ ANDPD X0, X2
+ MOVSD $0.5, X0 // 0x3FE0000000000000
+ ORPD X0, X2 // X2= f1
+ SHRQ $52, BX
+ ANDL $0x7FF, BX
+ SUBL $0x3FE, BX
+ XORPS X1, X1 // break dependency for CVTSL2SD
+ CVTSL2SD BX, X1 // x1= k, x2= f1
+ // if f1 < math.Sqrt2/2 { k -= 1; f1 *= 2 }
+ MOVSD $HSqrt2, X0 // x0= 0.7071, x1= k, x2= f1
+ CMPSD X2, X0, 5 // cmpnlt; x0= 0 or ^0, x1= k, x2 = f1
+ MOVSD $1.0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 1
+ ANDPD X0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1
+ SUBSD X3, X1 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1
+ MOVSD $1.0, X0 // x0= 1, x1= k, x2= f1, x3= 0 or 1
+ ADDSD X0, X3 // x0= 1, x1= k, x2= f1, x3= 1 or 2
+ MULSD X3, X2 // x0= 1, x1= k, x2= f1
+ // f := f1 - 1
+ SUBSD X0, X2 // x1= k, x2= f
+ // s := f / (2 + f)
+ MOVSD $2.0, X0
+ ADDSD X2, X0
+ MOVAPD X2, X3
+ DIVSD X0, X3 // x1=k, x2= f, x3= s
+ // s2 := s * s
+ MOVAPD X3, X4 // x1= k, x2= f, x3= s
+ MULSD X4, X4 // x1= k, x2= f, x3= s, x4= s2
+ // s4 := s2 * s2
+ MOVAPD X4, X5 // x1= k, x2= f, x3= s, x4= s2
+ MULSD X5, X5 // x1= k, x2= f, x3= s, x4= s2, x5= s4
+ // t1 := s2 * (L1 + s4*(L3+s4*(L5+s4*L7)))
+ MOVSD $L7, X6
+ MULSD X5, X6
+ ADDSD $L5, X6
+ MULSD X5, X6
+ ADDSD $L3, X6
+ MULSD X5, X6
+ ADDSD $L1, X6
+ MULSD X6, X4 // x1= k, x2= f, x3= s, x4= t1, x5= s4
+ // t2 := s4 * (L2 + s4*(L4+s4*L6))
+ MOVSD $L6, X6
+ MULSD X5, X6
+ ADDSD $L4, X6
+ MULSD X5, X6
+ ADDSD $L2, X6
+ MULSD X6, X5 // x1= k, x2= f, x3= s, x4= t1, x5= t2
+ // R := t1 + t2
+ ADDSD X5, X4 // x1= k, x2= f, x3= s, x4= R
+ // hfsq := 0.5 * f * f
+ MOVSD $0.5, X0
+ MULSD X2, X0
+ MULSD X2, X0 // x0= hfsq, x1= k, x2= f, x3= s, x4= R
+ // return k*Ln2Hi - ((hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f)
+ ADDSD X0, X4 // x0= hfsq, x1= k, x2= f, x3= s, x4= hfsq+R
+ MULSD X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)
+ MOVSD $Ln2Lo, X4
+ MULSD X1, X4 // x4= k*Ln2Lo
+ ADDSD X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)+k*Ln2Lo
+ SUBSD X3, X0 // x0= hfsq-(s*(hfsq+R)+k*Ln2Lo), x1= k, x2= f
+ SUBSD X2, X0 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k
+ MULSD $Ln2Hi, X1 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k*Ln2Hi
+ SUBSD X0, X1 // x1= k*Ln2Hi-((hfsq-(s*(hfsq+R)+k*Ln2Lo))-f)
+ MOVSD X1, ret+8(FP)
+ RET
+isInfOrNaN:
+ MOVQ BX, ret+8(FP) // +Inf or NaN, return x
+ RET
+isNegative:
+ MOVQ $NaN, AX
+ MOVQ AX, ret+8(FP) // return NaN
+ RET
+isZero:
+ MOVQ $NegInf, AX
+ MOVQ AX, ret+8(FP) // return -Inf
+ RET
diff --git a/contrib/go/_std_1.20/src/math/log_asm.go b/contrib/go/_std_1.21/src/math/log_asm.go
index 848cce13b2..848cce13b2 100644
--- a/contrib/go/_std_1.20/src/math/log_asm.go
+++ b/contrib/go/_std_1.21/src/math/log_asm.go
diff --git a/contrib/go/_std_1.20/src/math/log_stub.go b/contrib/go/_std_1.21/src/math/log_stub.go
index d35992bf37..d35992bf37 100644
--- a/contrib/go/_std_1.20/src/math/log_stub.go
+++ b/contrib/go/_std_1.21/src/math/log_stub.go
diff --git a/contrib/go/_std_1.20/src/math/logb.go b/contrib/go/_std_1.21/src/math/logb.go
index 1a46464127..1a46464127 100644
--- a/contrib/go/_std_1.20/src/math/logb.go
+++ b/contrib/go/_std_1.21/src/math/logb.go
diff --git a/contrib/go/_std_1.20/src/math/mod.go b/contrib/go/_std_1.21/src/math/mod.go
index 6f24250cfb..6f24250cfb 100644
--- a/contrib/go/_std_1.20/src/math/mod.go
+++ b/contrib/go/_std_1.21/src/math/mod.go
diff --git a/contrib/go/_std_1.20/src/math/modf.go b/contrib/go/_std_1.21/src/math/modf.go
index 613a75fc9a..613a75fc9a 100644
--- a/contrib/go/_std_1.20/src/math/modf.go
+++ b/contrib/go/_std_1.21/src/math/modf.go
diff --git a/contrib/go/_std_1.20/src/math/modf_arm64.s b/contrib/go/_std_1.21/src/math/modf_arm64.s
index 1e4a329a4b..1e4a329a4b 100644
--- a/contrib/go/_std_1.20/src/math/modf_arm64.s
+++ b/contrib/go/_std_1.21/src/math/modf_arm64.s
diff --git a/contrib/go/_std_1.20/src/math/modf_asm.go b/contrib/go/_std_1.21/src/math/modf_asm.go
index c63be6cf36..c63be6cf36 100644
--- a/contrib/go/_std_1.20/src/math/modf_asm.go
+++ b/contrib/go/_std_1.21/src/math/modf_asm.go
diff --git a/contrib/go/_std_1.20/src/math/modf_noasm.go b/contrib/go/_std_1.21/src/math/modf_noasm.go
index 55c6a7f6e2..55c6a7f6e2 100644
--- a/contrib/go/_std_1.20/src/math/modf_noasm.go
+++ b/contrib/go/_std_1.21/src/math/modf_noasm.go
diff --git a/contrib/go/_std_1.20/src/math/nextafter.go b/contrib/go/_std_1.21/src/math/nextafter.go
index ec18d542d9..ec18d542d9 100644
--- a/contrib/go/_std_1.20/src/math/nextafter.go
+++ b/contrib/go/_std_1.21/src/math/nextafter.go
diff --git a/contrib/go/_std_1.21/src/math/pow.go b/contrib/go/_std_1.21/src/math/pow.go
new file mode 100644
index 0000000000..3f42945376
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/pow.go
@@ -0,0 +1,166 @@
+// Copyright 2009 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 math
+
+func isOddInt(x float64) bool {
+ if Abs(x) >= (1 << 53) {
+ // 1 << 53 is the largest exact integer in the float64 format.
+ // Any number outside this range will be truncated before the decimal point and therefore will always be
+ // an even integer.
+ // Without this check and if x overflows int64 the int64(xi) conversion below may produce incorrect results
+ // on some architectures (and does so on arm64). See issue #57465.
+ return false
+ }
+
+ xi, xf := Modf(x)
+ return xf == 0 && int64(xi)&1 == 1
+}
+
+// Special cases taken from FreeBSD's /usr/src/lib/msun/src/e_pow.c
+// updated by IEEE Std. 754-2008 "Section 9.2.1 Special values".
+
+// Pow returns x**y, the base-x exponential of y.
+//
+// Special cases are (in order):
+//
+// Pow(x, ±0) = 1 for any x
+// Pow(1, y) = 1 for any y
+// Pow(x, 1) = x for any x
+// Pow(NaN, y) = NaN
+// Pow(x, NaN) = NaN
+// Pow(±0, y) = ±Inf for y an odd integer < 0
+// Pow(±0, -Inf) = +Inf
+// Pow(±0, +Inf) = +0
+// Pow(±0, y) = +Inf for finite y < 0 and not an odd integer
+// Pow(±0, y) = ±0 for y an odd integer > 0
+// Pow(±0, y) = +0 for finite y > 0 and not an odd integer
+// Pow(-1, ±Inf) = 1
+// Pow(x, +Inf) = +Inf for |x| > 1
+// Pow(x, -Inf) = +0 for |x| > 1
+// Pow(x, +Inf) = +0 for |x| < 1
+// Pow(x, -Inf) = +Inf for |x| < 1
+// Pow(+Inf, y) = +Inf for y > 0
+// Pow(+Inf, y) = +0 for y < 0
+// Pow(-Inf, y) = Pow(-0, -y)
+// Pow(x, y) = NaN for finite x < 0 and finite non-integer y
+func Pow(x, y float64) float64 {
+ if haveArchPow {
+ return archPow(x, y)
+ }
+ return pow(x, y)
+}
+
+func pow(x, y float64) float64 {
+ switch {
+ case y == 0 || x == 1:
+ return 1
+ case y == 1:
+ return x
+ case IsNaN(x) || IsNaN(y):
+ return NaN()
+ case x == 0:
+ switch {
+ case y < 0:
+ if Signbit(x) && isOddInt(y) {
+ return Inf(-1)
+ }
+ return Inf(1)
+ case y > 0:
+ if Signbit(x) && isOddInt(y) {
+ return x
+ }
+ return 0
+ }
+ case IsInf(y, 0):
+ switch {
+ case x == -1:
+ return 1
+ case (Abs(x) < 1) == IsInf(y, 1):
+ return 0
+ default:
+ return Inf(1)
+ }
+ case IsInf(x, 0):
+ if IsInf(x, -1) {
+ return Pow(1/x, -y) // Pow(-0, -y)
+ }
+ switch {
+ case y < 0:
+ return 0
+ case y > 0:
+ return Inf(1)
+ }
+ case y == 0.5:
+ return Sqrt(x)
+ case y == -0.5:
+ return 1 / Sqrt(x)
+ }
+
+ yi, yf := Modf(Abs(y))
+ if yf != 0 && x < 0 {
+ return NaN()
+ }
+ if yi >= 1<<63 {
+ // yi is a large even int that will lead to overflow (or underflow to 0)
+ // for all x except -1 (x == 1 was handled earlier)
+ switch {
+ case x == -1:
+ return 1
+ case (Abs(x) < 1) == (y > 0):
+ return 0
+ default:
+ return Inf(1)
+ }
+ }
+
+ // ans = a1 * 2**ae (= 1 for now).
+ a1 := 1.0
+ ae := 0
+
+ // ans *= x**yf
+ if yf != 0 {
+ if yf > 0.5 {
+ yf--
+ yi++
+ }
+ a1 = Exp(yf * Log(x))
+ }
+
+ // ans *= x**yi
+ // by multiplying in successive squarings
+ // of x according to bits of yi.
+ // accumulate powers of two into exp.
+ x1, xe := Frexp(x)
+ for i := int64(yi); i != 0; i >>= 1 {
+ if xe < -1<<12 || 1<<12 < xe {
+ // catch xe before it overflows the left shift below
+ // Since i !=0 it has at least one bit still set, so ae will accumulate xe
+ // on at least one more iteration, ae += xe is a lower bound on ae
+ // the lower bound on ae exceeds the size of a float64 exp
+ // so the final call to Ldexp will produce under/overflow (0/Inf)
+ ae += xe
+ break
+ }
+ if i&1 == 1 {
+ a1 *= x1
+ ae += xe
+ }
+ x1 *= x1
+ xe <<= 1
+ if x1 < .5 {
+ x1 += x1
+ xe--
+ }
+ }
+
+ // ans = a1*2**ae
+ // if y < 0 { ans = 1 / ans }
+ // but in the opposite order
+ if y < 0 {
+ a1 = 1 / a1
+ ae = -ae
+ }
+ return Ldexp(a1, ae)
+}
diff --git a/contrib/go/_std_1.20/src/math/pow10.go b/contrib/go/_std_1.21/src/math/pow10.go
index c31ad8dbc7..c31ad8dbc7 100644
--- a/contrib/go/_std_1.20/src/math/pow10.go
+++ b/contrib/go/_std_1.21/src/math/pow10.go
diff --git a/contrib/go/_std_1.20/src/math/rand/exp.go b/contrib/go/_std_1.21/src/math/rand/exp.go
index c1162c19b6..c1162c19b6 100644
--- a/contrib/go/_std_1.20/src/math/rand/exp.go
+++ b/contrib/go/_std_1.21/src/math/rand/exp.go
diff --git a/contrib/go/_std_1.20/src/math/rand/normal.go b/contrib/go/_std_1.21/src/math/rand/normal.go
index 6654479a00..6654479a00 100644
--- a/contrib/go/_std_1.20/src/math/rand/normal.go
+++ b/contrib/go/_std_1.21/src/math/rand/normal.go
diff --git a/contrib/go/_std_1.21/src/math/rand/rand.go b/contrib/go/_std_1.21/src/math/rand/rand.go
new file mode 100644
index 0000000000..1a6a705be1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/rand/rand.go
@@ -0,0 +1,548 @@
+// Copyright 2009 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 rand implements pseudo-random number generators suitable for tasks
+// such as simulation, but it should not be used for security-sensitive work.
+//
+// Random numbers are generated by a [Source], usually wrapped in a [Rand].
+// Both types should be used by a single goroutine at a time: sharing among
+// multiple goroutines requires some kind of synchronization.
+//
+// Top-level functions, such as [Float64] and [Int],
+// are safe for concurrent use by multiple goroutines.
+//
+// This package's outputs might be easily predictable regardless of how it's
+// seeded. For random numbers suitable for security-sensitive work, see the
+// crypto/rand package.
+package rand
+
+import (
+ "internal/godebug"
+ "sync"
+ "sync/atomic"
+ _ "unsafe" // for go:linkname
+
+)
+
+// A Source represents a source of uniformly-distributed
+// pseudo-random int64 values in the range [0, 1<<63).
+//
+// A Source is not safe for concurrent use by multiple goroutines.
+type Source interface {
+ Int63() int64
+ Seed(seed int64)
+}
+
+// A Source64 is a Source that can also generate
+// uniformly-distributed pseudo-random uint64 values in
+// the range [0, 1<<64) directly.
+// If a Rand r's underlying Source s implements Source64,
+// then r.Uint64 returns the result of one call to s.Uint64
+// instead of making two calls to s.Int63.
+type Source64 interface {
+ Source
+ Uint64() uint64
+}
+
+// NewSource returns a new pseudo-random Source seeded with the given value.
+// Unlike the default Source used by top-level functions, this source is not
+// safe for concurrent use by multiple goroutines.
+// The returned Source implements Source64.
+func NewSource(seed int64) Source {
+ return newSource(seed)
+}
+
+func newSource(seed int64) *rngSource {
+ var rng rngSource
+ rng.Seed(seed)
+ return &rng
+}
+
+// A Rand is a source of random numbers.
+type Rand struct {
+ src Source
+ s64 Source64 // non-nil if src is source64
+
+ // readVal contains remainder of 63-bit integer used for bytes
+ // generation during most recent Read call.
+ // It is saved so next Read call can start where the previous
+ // one finished.
+ readVal int64
+ // readPos indicates the number of low-order bytes of readVal
+ // that are still valid.
+ readPos int8
+}
+
+// New returns a new Rand that uses random values from src
+// to generate other random values.
+func New(src Source) *Rand {
+ s64, _ := src.(Source64)
+ return &Rand{src: src, s64: s64}
+}
+
+// Seed uses the provided seed value to initialize the generator to a deterministic state.
+// Seed should not be called concurrently with any other Rand method.
+func (r *Rand) Seed(seed int64) {
+ if lk, ok := r.src.(*lockedSource); ok {
+ lk.seedPos(seed, &r.readPos)
+ return
+ }
+
+ r.src.Seed(seed)
+ r.readPos = 0
+}
+
+// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
+func (r *Rand) Int63() int64 { return r.src.Int63() }
+
+// Uint32 returns a pseudo-random 32-bit value as a uint32.
+func (r *Rand) Uint32() uint32 { return uint32(r.Int63() >> 31) }
+
+// Uint64 returns a pseudo-random 64-bit value as a uint64.
+func (r *Rand) Uint64() uint64 {
+ if r.s64 != nil {
+ return r.s64.Uint64()
+ }
+ return uint64(r.Int63())>>31 | uint64(r.Int63())<<32
+}
+
+// Int31 returns a non-negative pseudo-random 31-bit integer as an int32.
+func (r *Rand) Int31() int32 { return int32(r.Int63() >> 32) }
+
+// Int returns a non-negative pseudo-random int.
+func (r *Rand) Int() int {
+ u := uint(r.Int63())
+ return int(u << 1 >> 1) // clear sign bit if int == int32
+}
+
+// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n).
+// It panics if n <= 0.
+func (r *Rand) Int63n(n int64) int64 {
+ if n <= 0 {
+ panic("invalid argument to Int63n")
+ }
+ if n&(n-1) == 0 { // n is power of two, can mask
+ return r.Int63() & (n - 1)
+ }
+ max := int64((1 << 63) - 1 - (1<<63)%uint64(n))
+ v := r.Int63()
+ for v > max {
+ v = r.Int63()
+ }
+ return v % n
+}
+
+// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n).
+// It panics if n <= 0.
+func (r *Rand) Int31n(n int32) int32 {
+ if n <= 0 {
+ panic("invalid argument to Int31n")
+ }
+ if n&(n-1) == 0 { // n is power of two, can mask
+ return r.Int31() & (n - 1)
+ }
+ max := int32((1 << 31) - 1 - (1<<31)%uint32(n))
+ v := r.Int31()
+ for v > max {
+ v = r.Int31()
+ }
+ return v % n
+}
+
+// int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n).
+// n must be > 0, but int31n does not check this; the caller must ensure it.
+// int31n exists because Int31n is inefficient, but Go 1 compatibility
+// requires that the stream of values produced by math/rand remain unchanged.
+// int31n can thus only be used internally, by newly introduced APIs.
+//
+// For implementation details, see:
+// https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction
+// https://lemire.me/blog/2016/06/30/fast-random-shuffling
+func (r *Rand) int31n(n int32) int32 {
+ v := r.Uint32()
+ prod := uint64(v) * uint64(n)
+ low := uint32(prod)
+ if low < uint32(n) {
+ thresh := uint32(-n) % uint32(n)
+ for low < thresh {
+ v = r.Uint32()
+ prod = uint64(v) * uint64(n)
+ low = uint32(prod)
+ }
+ }
+ return int32(prod >> 32)
+}
+
+// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n).
+// It panics if n <= 0.
+func (r *Rand) Intn(n int) int {
+ if n <= 0 {
+ panic("invalid argument to Intn")
+ }
+ if n <= 1<<31-1 {
+ return int(r.Int31n(int32(n)))
+ }
+ return int(r.Int63n(int64(n)))
+}
+
+// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0).
+func (r *Rand) Float64() float64 {
+ // A clearer, simpler implementation would be:
+ // return float64(r.Int63n(1<<53)) / (1<<53)
+ // However, Go 1 shipped with
+ // return float64(r.Int63()) / (1 << 63)
+ // and we want to preserve that value stream.
+ //
+ // There is one bug in the value stream: r.Int63() may be so close
+ // to 1<<63 that the division rounds up to 1.0, and we've guaranteed
+ // that the result is always less than 1.0.
+ //
+ // We tried to fix this by mapping 1.0 back to 0.0, but since float64
+ // values near 0 are much denser than near 1, mapping 1 to 0 caused
+ // a theoretically significant overshoot in the probability of returning 0.
+ // Instead of that, if we round up to 1, just try again.
+ // Getting 1 only happens 1/2⁵³ of the time, so most clients
+ // will not observe it anyway.
+again:
+ f := float64(r.Int63()) / (1 << 63)
+ if f == 1 {
+ goto again // resample; this branch is taken O(never)
+ }
+ return f
+}
+
+// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0).
+func (r *Rand) Float32() float32 {
+ // Same rationale as in Float64: we want to preserve the Go 1 value
+ // stream except we want to fix it not to return 1.0
+ // This only happens 1/2²⁴ of the time (plus the 1/2⁵³ of the time in Float64).
+again:
+ f := float32(r.Float64())
+ if f == 1 {
+ goto again // resample; this branch is taken O(very rarely)
+ }
+ return f
+}
+
+// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers
+// in the half-open interval [0,n).
+func (r *Rand) Perm(n int) []int {
+ m := make([]int, n)
+ // In the following loop, the iteration when i=0 always swaps m[0] with m[0].
+ // A change to remove this useless iteration is to assign 1 to i in the init
+ // statement. But Perm also effects r. Making this change will affect
+ // the final state of r. So this change can't be made for compatibility
+ // reasons for Go 1.
+ for i := 0; i < n; i++ {
+ j := r.Intn(i + 1)
+ m[i] = m[j]
+ m[j] = i
+ }
+ return m
+}
+
+// Shuffle pseudo-randomizes the order of elements.
+// n is the number of elements. Shuffle panics if n < 0.
+// swap swaps the elements with indexes i and j.
+func (r *Rand) Shuffle(n int, swap func(i, j int)) {
+ if n < 0 {
+ panic("invalid argument to Shuffle")
+ }
+
+ // Fisher-Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
+ // Shuffle really ought not be called with n that doesn't fit in 32 bits.
+ // Not only will it take a very long time, but with 2³¹! possible permutations,
+ // there's no way that any PRNG can have a big enough internal state to
+ // generate even a minuscule percentage of the possible permutations.
+ // Nevertheless, the right API signature accepts an int n, so handle it as best we can.
+ i := n - 1
+ for ; i > 1<<31-1-1; i-- {
+ j := int(r.Int63n(int64(i + 1)))
+ swap(i, j)
+ }
+ for ; i > 0; i-- {
+ j := int(r.int31n(int32(i + 1)))
+ swap(i, j)
+ }
+}
+
+// Read generates len(p) random bytes and writes them into p. It
+// always returns len(p) and a nil error.
+// Read should not be called concurrently with any other Rand method.
+func (r *Rand) Read(p []byte) (n int, err error) {
+ switch src := r.src.(type) {
+ case *lockedSource:
+ return src.read(p, &r.readVal, &r.readPos)
+ case *fastSource:
+ return src.read(p, &r.readVal, &r.readPos)
+ }
+ return read(p, r.src, &r.readVal, &r.readPos)
+}
+
+func read(p []byte, src Source, readVal *int64, readPos *int8) (n int, err error) {
+ pos := *readPos
+ val := *readVal
+ rng, _ := src.(*rngSource)
+ for n = 0; n < len(p); n++ {
+ if pos == 0 {
+ if rng != nil {
+ val = rng.Int63()
+ } else {
+ val = src.Int63()
+ }
+ pos = 7
+ }
+ p[n] = byte(val)
+ val >>= 8
+ pos--
+ }
+ *readPos = pos
+ *readVal = val
+ return
+}
+
+/*
+ * Top-level convenience functions
+ */
+
+// globalRandGenerator is the source of random numbers for the top-level
+// convenience functions. When possible it uses the runtime fastrand64
+// function to avoid locking. This is not possible if the user called Seed,
+// either explicitly or implicitly via GODEBUG=randautoseed=0.
+var globalRandGenerator atomic.Pointer[Rand]
+
+var randautoseed = godebug.New("randautoseed")
+
+// globalRand returns the generator to use for the top-level convenience
+// functions.
+func globalRand() *Rand {
+ if r := globalRandGenerator.Load(); r != nil {
+ return r
+ }
+
+ // This is the first call. Initialize based on GODEBUG.
+ var r *Rand
+ if randautoseed.Value() == "0" {
+ randautoseed.IncNonDefault()
+ r = New(new(lockedSource))
+ r.Seed(1)
+ } else {
+ r = &Rand{
+ src: &fastSource{},
+ s64: &fastSource{},
+ }
+ }
+
+ if !globalRandGenerator.CompareAndSwap(nil, r) {
+ // Two different goroutines called some top-level
+ // function at the same time. While the results in
+ // that case are unpredictable, if we just use r here,
+ // and we are using a seed, we will most likely return
+ // the same value for both calls. That doesn't seem ideal.
+ // Just use the first one to get in.
+ return globalRandGenerator.Load()
+ }
+
+ return r
+}
+
+//go:linkname fastrand64
+func fastrand64() uint64
+
+// fastSource is an implementation of Source64 that uses the runtime
+// fastrand functions.
+type fastSource struct {
+ // The mutex is used to avoid race conditions in Read.
+ mu sync.Mutex
+}
+
+func (*fastSource) Int63() int64 {
+ return int64(fastrand64() & rngMask)
+}
+
+func (*fastSource) Seed(int64) {
+ panic("internal error: call to fastSource.Seed")
+}
+
+func (*fastSource) Uint64() uint64 {
+ return fastrand64()
+}
+
+func (fs *fastSource) read(p []byte, readVal *int64, readPos *int8) (n int, err error) {
+ fs.mu.Lock()
+ n, err = read(p, fs, readVal, readPos)
+ fs.mu.Unlock()
+ return
+}
+
+// Seed uses the provided seed value to initialize the default Source to a
+// deterministic state. Seed values that have the same remainder when
+// divided by 2³¹-1 generate the same pseudo-random sequence.
+// Seed, unlike the Rand.Seed method, is safe for concurrent use.
+//
+// If Seed is not called, the generator is seeded randomly at program startup.
+//
+// Prior to Go 1.20, the generator was seeded like Seed(1) at program startup.
+// To force the old behavior, call Seed(1) at program startup.
+// Alternately, set GODEBUG=randautoseed=0 in the environment
+// before making any calls to functions in this package.
+//
+// Deprecated: As of Go 1.20 there is no reason to call Seed with
+// a random value. Programs that call Seed with a known value to get
+// a specific sequence of results should use New(NewSource(seed)) to
+// obtain a local random generator.
+func Seed(seed int64) {
+ orig := globalRandGenerator.Load()
+
+ // If we are already using a lockedSource, we can just re-seed it.
+ if orig != nil {
+ if _, ok := orig.src.(*lockedSource); ok {
+ orig.Seed(seed)
+ return
+ }
+ }
+
+ // Otherwise either
+ // 1) orig == nil, which is the normal case when Seed is the first
+ // top-level function to be called, or
+ // 2) orig is already a fastSource, in which case we need to change
+ // to a lockedSource.
+ // Either way we do the same thing.
+
+ r := New(new(lockedSource))
+ r.Seed(seed)
+
+ if !globalRandGenerator.CompareAndSwap(orig, r) {
+ // Something changed underfoot. Retry to be safe.
+ Seed(seed)
+ }
+}
+
+// Int63 returns a non-negative pseudo-random 63-bit integer as an int64
+// from the default Source.
+func Int63() int64 { return globalRand().Int63() }
+
+// Uint32 returns a pseudo-random 32-bit value as a uint32
+// from the default Source.
+func Uint32() uint32 { return globalRand().Uint32() }
+
+// Uint64 returns a pseudo-random 64-bit value as a uint64
+// from the default Source.
+func Uint64() uint64 { return globalRand().Uint64() }
+
+// Int31 returns a non-negative pseudo-random 31-bit integer as an int32
+// from the default Source.
+func Int31() int32 { return globalRand().Int31() }
+
+// Int returns a non-negative pseudo-random int from the default Source.
+func Int() int { return globalRand().Int() }
+
+// Int63n returns, as an int64, a non-negative pseudo-random number in the half-open interval [0,n)
+// from the default Source.
+// It panics if n <= 0.
+func Int63n(n int64) int64 { return globalRand().Int63n(n) }
+
+// Int31n returns, as an int32, a non-negative pseudo-random number in the half-open interval [0,n)
+// from the default Source.
+// It panics if n <= 0.
+func Int31n(n int32) int32 { return globalRand().Int31n(n) }
+
+// Intn returns, as an int, a non-negative pseudo-random number in the half-open interval [0,n)
+// from the default Source.
+// It panics if n <= 0.
+func Intn(n int) int { return globalRand().Intn(n) }
+
+// Float64 returns, as a float64, a pseudo-random number in the half-open interval [0.0,1.0)
+// from the default Source.
+func Float64() float64 { return globalRand().Float64() }
+
+// Float32 returns, as a float32, a pseudo-random number in the half-open interval [0.0,1.0)
+// from the default Source.
+func Float32() float32 { return globalRand().Float32() }
+
+// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers
+// in the half-open interval [0,n) from the default Source.
+func Perm(n int) []int { return globalRand().Perm(n) }
+
+// Shuffle pseudo-randomizes the order of elements using the default Source.
+// n is the number of elements. Shuffle panics if n < 0.
+// swap swaps the elements with indexes i and j.
+func Shuffle(n int, swap func(i, j int)) { globalRand().Shuffle(n, swap) }
+
+// Read generates len(p) random bytes from the default Source and
+// writes them into p. It always returns len(p) and a nil error.
+// Read, unlike the Rand.Read method, is safe for concurrent use.
+//
+// Deprecated: For almost all use cases, crypto/rand.Read is more appropriate.
+func Read(p []byte) (n int, err error) { return globalRand().Read(p) }
+
+// NormFloat64 returns a normally distributed float64 in the range
+// [-math.MaxFloat64, +math.MaxFloat64] with
+// standard normal distribution (mean = 0, stddev = 1)
+// from the default Source.
+// To produce a different normal distribution, callers can
+// adjust the output using:
+//
+// sample = NormFloat64() * desiredStdDev + desiredMean
+func NormFloat64() float64 { return globalRand().NormFloat64() }
+
+// ExpFloat64 returns an exponentially distributed float64 in the range
+// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter
+// (lambda) is 1 and whose mean is 1/lambda (1) from the default Source.
+// To produce a distribution with a different rate parameter,
+// callers can adjust the output using:
+//
+// sample = ExpFloat64() / desiredRateParameter
+func ExpFloat64() float64 { return globalRand().ExpFloat64() }
+
+type lockedSource struct {
+ lk sync.Mutex
+ s *rngSource
+}
+
+func (r *lockedSource) Int63() (n int64) {
+ r.lk.Lock()
+ n = r.s.Int63()
+ r.lk.Unlock()
+ return
+}
+
+func (r *lockedSource) Uint64() (n uint64) {
+ r.lk.Lock()
+ n = r.s.Uint64()
+ r.lk.Unlock()
+ return
+}
+
+func (r *lockedSource) Seed(seed int64) {
+ r.lk.Lock()
+ r.seed(seed)
+ r.lk.Unlock()
+}
+
+// seedPos implements Seed for a lockedSource without a race condition.
+func (r *lockedSource) seedPos(seed int64, readPos *int8) {
+ r.lk.Lock()
+ r.seed(seed)
+ *readPos = 0
+ r.lk.Unlock()
+}
+
+// seed seeds the underlying source.
+// The caller must have locked r.lk.
+func (r *lockedSource) seed(seed int64) {
+ if r.s == nil {
+ r.s = newSource(seed)
+ } else {
+ r.s.Seed(seed)
+ }
+}
+
+// read implements Read for a lockedSource without a race condition.
+func (r *lockedSource) read(p []byte, readVal *int64, readPos *int8) (n int, err error) {
+ r.lk.Lock()
+ n, err = read(p, r.s, readVal, readPos)
+ r.lk.Unlock()
+ return
+}
diff --git a/contrib/go/_std_1.21/src/math/rand/rng.go b/contrib/go/_std_1.21/src/math/rand/rng.go
new file mode 100644
index 0000000000..1e4a9e014f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/rand/rng.go
@@ -0,0 +1,252 @@
+// Copyright 2009 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 rand
+
+/*
+ * Uniform distribution
+ *
+ * algorithm by
+ * DP Mitchell and JA Reeds
+ */
+
+const (
+ rngLen = 607
+ rngTap = 273
+ rngMax = 1 << 63
+ rngMask = rngMax - 1
+ int32max = (1 << 31) - 1
+)
+
+var (
+ // rngCooked used for seeding. See gen_cooked.go for details.
+ rngCooked [rngLen]int64 = [...]int64{
+ -4181792142133755926, -4576982950128230565, 1395769623340756751, 5333664234075297259,
+ -6347679516498800754, 9033628115061424579, 7143218595135194537, 4812947590706362721,
+ 7937252194349799378, 5307299880338848416, 8209348851763925077, -7107630437535961764,
+ 4593015457530856296, 8140875735541888011, -5903942795589686782, -603556388664454774,
+ -7496297993371156308, 113108499721038619, 4569519971459345583, -4160538177779461077,
+ -6835753265595711384, -6507240692498089696, 6559392774825876886, 7650093201692370310,
+ 7684323884043752161, -8965504200858744418, -2629915517445760644, 271327514973697897,
+ -6433985589514657524, 1065192797246149621, 3344507881999356393, -4763574095074709175,
+ 7465081662728599889, 1014950805555097187, -4773931307508785033, -5742262670416273165,
+ 2418672789110888383, 5796562887576294778, 4484266064449540171, 3738982361971787048,
+ -4699774852342421385, 10530508058128498, -589538253572429690, -6598062107225984180,
+ 8660405965245884302, 10162832508971942, -2682657355892958417, 7031802312784620857,
+ 6240911277345944669, 831864355460801054, -1218937899312622917, 2116287251661052151,
+ 2202309800992166967, 9161020366945053561, 4069299552407763864, 4936383537992622449,
+ 457351505131524928, -8881176990926596454, -6375600354038175299, -7155351920868399290,
+ 4368649989588021065, 887231587095185257, -3659780529968199312, -2407146836602825512,
+ 5616972787034086048, -751562733459939242, 1686575021641186857, -5177887698780513806,
+ -4979215821652996885, -1375154703071198421, 5632136521049761902, -8390088894796940536,
+ -193645528485698615, -5979788902190688516, -4907000935050298721, -285522056888777828,
+ -2776431630044341707, 1679342092332374735, 6050638460742422078, -2229851317345194226,
+ -1582494184340482199, 5881353426285907985, 812786550756860885, 4541845584483343330,
+ -6497901820577766722, 4980675660146853729, -4012602956251539747, -329088717864244987,
+ -2896929232104691526, 1495812843684243920, -2153620458055647789, 7370257291860230865,
+ -2466442761497833547, 4706794511633873654, -1398851569026877145, 8549875090542453214,
+ -9189721207376179652, -7894453601103453165, 7297902601803624459, 1011190183918857495,
+ -6985347000036920864, 5147159997473910359, -8326859945294252826, 2659470849286379941,
+ 6097729358393448602, -7491646050550022124, -5117116194870963097, -896216826133240300,
+ -745860416168701406, 5803876044675762232, -787954255994554146, -3234519180203704564,
+ -4507534739750823898, -1657200065590290694, 505808562678895611, -4153273856159712438,
+ -8381261370078904295, 572156825025677802, 1791881013492340891, 3393267094866038768,
+ -5444650186382539299, 2352769483186201278, -7930912453007408350, -325464993179687389,
+ -3441562999710612272, -6489413242825283295, 5092019688680754699, -227247482082248967,
+ 4234737173186232084, 5027558287275472836, 4635198586344772304, -536033143587636457,
+ 5907508150730407386, -8438615781380831356, 972392927514829904, -3801314342046600696,
+ -4064951393885491917, -174840358296132583, 2407211146698877100, -1640089820333676239,
+ 3940796514530962282, -5882197405809569433, 3095313889586102949, -1818050141166537098,
+ 5832080132947175283, 7890064875145919662, 8184139210799583195, -8073512175445549678,
+ -7758774793014564506, -4581724029666783935, 3516491885471466898, -8267083515063118116,
+ 6657089965014657519, 5220884358887979358, 1796677326474620641, 5340761970648932916,
+ 1147977171614181568, 5066037465548252321, 2574765911837859848, 1085848279845204775,
+ -5873264506986385449, 6116438694366558490, 2107701075971293812, -7420077970933506541,
+ 2469478054175558874, -1855128755834809824, -5431463669011098282, -9038325065738319171,
+ -6966276280341336160, 7217693971077460129, -8314322083775271549, 7196649268545224266,
+ -3585711691453906209, -5267827091426810625, 8057528650917418961, -5084103596553648165,
+ -2601445448341207749, -7850010900052094367, 6527366231383600011, 3507654575162700890,
+ 9202058512774729859, 1954818376891585542, -2582991129724600103, 8299563319178235687,
+ -5321504681635821435, 7046310742295574065, -2376176645520785576, -7650733936335907755,
+ 8850422670118399721, 3631909142291992901, 5158881091950831288, -6340413719511654215,
+ 4763258931815816403, 6280052734341785344, -4979582628649810958, 2043464728020827976,
+ -2678071570832690343, 4562580375758598164, 5495451168795427352, -7485059175264624713,
+ 553004618757816492, 6895160632757959823, -989748114590090637, 7139506338801360852,
+ -672480814466784139, 5535668688139305547, 2430933853350256242, -3821430778991574732,
+ -1063731997747047009, -3065878205254005442, 7632066283658143750, 6308328381617103346,
+ 3681878764086140361, 3289686137190109749, 6587997200611086848, 244714774258135476,
+ -5143583659437639708, 8090302575944624335, 2945117363431356361, -8359047641006034763,
+ 3009039260312620700, -793344576772241777, 401084700045993341, -1968749590416080887,
+ 4707864159563588614, -3583123505891281857, -3240864324164777915, -5908273794572565703,
+ -3719524458082857382, -5281400669679581926, 8118566580304798074, 3839261274019871296,
+ 7062410411742090847, -8481991033874568140, 6027994129690250817, -6725542042704711878,
+ -2971981702428546974, -7854441788951256975, 8809096399316380241, 6492004350391900708,
+ 2462145737463489636, -8818543617934476634, -5070345602623085213, -8961586321599299868,
+ -3758656652254704451, -8630661632476012791, 6764129236657751224, -709716318315418359,
+ -3403028373052861600, -8838073512170985897, -3999237033416576341, -2920240395515973663,
+ -2073249475545404416, 368107899140673753, -6108185202296464250, -6307735683270494757,
+ 4782583894627718279, 6718292300699989587, 8387085186914375220, 3387513132024756289,
+ 4654329375432538231, -292704475491394206, -3848998599978456535, 7623042350483453954,
+ 7725442901813263321, 9186225467561587250, -5132344747257272453, -6865740430362196008,
+ 2530936820058611833, 1636551876240043639, -3658707362519810009, 1452244145334316253,
+ -7161729655835084979, -7943791770359481772, 9108481583171221009, -3200093350120725999,
+ 5007630032676973346, 2153168792952589781, 6720334534964750538, -3181825545719981703,
+ 3433922409283786309, 2285479922797300912, 3110614940896576130, -2856812446131932915,
+ -3804580617188639299, 7163298419643543757, 4891138053923696990, 580618510277907015,
+ 1684034065251686769, 4429514767357295841, -8893025458299325803, -8103734041042601133,
+ 7177515271653460134, 4589042248470800257, -1530083407795771245, 143607045258444228,
+ 246994305896273627, -8356954712051676521, 6473547110565816071, 3092379936208876896,
+ 2058427839513754051, -4089587328327907870, 8785882556301281247, -3074039370013608197,
+ -637529855400303673, 6137678347805511274, -7152924852417805802, 5708223427705576541,
+ -3223714144396531304, 4358391411789012426, 325123008708389849, 6837621693887290924,
+ 4843721905315627004, -3212720814705499393, -3825019837890901156, 4602025990114250980,
+ 1044646352569048800, 9106614159853161675, -8394115921626182539, -4304087667751778808,
+ 2681532557646850893, 3681559472488511871, -3915372517896561773, -2889241648411946534,
+ -6564663803938238204, -8060058171802589521, 581945337509520675, 3648778920718647903,
+ -4799698790548231394, -7602572252857820065, 220828013409515943, -1072987336855386047,
+ 4287360518296753003, -4633371852008891965, 5513660857261085186, -2258542936462001533,
+ -8744380348503999773, 8746140185685648781, 228500091334420247, 1356187007457302238,
+ 3019253992034194581, 3152601605678500003, -8793219284148773595, 5559581553696971176,
+ 4916432985369275664, -8559797105120221417, -5802598197927043732, 2868348622579915573,
+ -7224052902810357288, -5894682518218493085, 2587672709781371173, -7706116723325376475,
+ 3092343956317362483, -5561119517847711700, 972445599196498113, -1558506600978816441,
+ 1708913533482282562, -2305554874185907314, -6005743014309462908, -6653329009633068701,
+ -483583197311151195, 2488075924621352812, -4529369641467339140, -4663743555056261452,
+ 2997203966153298104, 1282559373026354493, 240113143146674385, 8665713329246516443,
+ 628141331766346752, -4651421219668005332, -7750560848702540400, 7596648026010355826,
+ -3132152619100351065, 7834161864828164065, 7103445518877254909, 4390861237357459201,
+ -4780718172614204074, -319889632007444440, 622261699494173647, -3186110786557562560,
+ -8718967088789066690, -1948156510637662747, -8212195255998774408, -7028621931231314745,
+ 2623071828615234808, -4066058308780939700, -5484966924888173764, -6683604512778046238,
+ -6756087640505506466, 5256026990536851868, 7841086888628396109, 6640857538655893162,
+ -8021284697816458310, -7109857044414059830, -1689021141511844405, -4298087301956291063,
+ -4077748265377282003, -998231156719803476, 2719520354384050532, 9132346697815513771,
+ 4332154495710163773, -2085582442760428892, 6994721091344268833, -2556143461985726874,
+ -8567931991128098309, 59934747298466858, -3098398008776739403, -265597256199410390,
+ 2332206071942466437, -7522315324568406181, 3154897383618636503, -7585605855467168281,
+ -6762850759087199275, 197309393502684135, -8579694182469508493, 2543179307861934850,
+ 4350769010207485119, -4468719947444108136, -7207776534213261296, -1224312577878317200,
+ 4287946071480840813, 8362686366770308971, 6486469209321732151, -5605644191012979782,
+ -1669018511020473564, 4450022655153542367, -7618176296641240059, -3896357471549267421,
+ -4596796223304447488, -6531150016257070659, -8982326463137525940, -4125325062227681798,
+ -1306489741394045544, -8338554946557245229, 5329160409530630596, 7790979528857726136,
+ 4955070238059373407, -4304834761432101506, -6215295852904371179, 3007769226071157901,
+ -6753025801236972788, 8928702772696731736, 7856187920214445904, -4748497451462800923,
+ 7900176660600710914, -7082800908938549136, -6797926979589575837, -6737316883512927978,
+ 4186670094382025798, 1883939007446035042, -414705992779907823, 3734134241178479257,
+ 4065968871360089196, 6953124200385847784, -7917685222115876751, -7585632937840318161,
+ -5567246375906782599, -5256612402221608788, 3106378204088556331, -2894472214076325998,
+ 4565385105440252958, 1979884289539493806, -6891578849933910383, 3783206694208922581,
+ 8464961209802336085, 2843963751609577687, 3030678195484896323, -4429654462759003204,
+ 4459239494808162889, 402587895800087237, 8057891408711167515, 4541888170938985079,
+ 1042662272908816815, -3666068979732206850, 2647678726283249984, 2144477441549833761,
+ -3417019821499388721, -2105601033380872185, 5916597177708541638, -8760774321402454447,
+ 8833658097025758785, 5970273481425315300, 563813119381731307, -6455022486202078793,
+ 1598828206250873866, -4016978389451217698, -2988328551145513985, -6071154634840136312,
+ 8469693267274066490, 125672920241807416, -3912292412830714870, -2559617104544284221,
+ -486523741806024092, -4735332261862713930, 5923302823487327109, -9082480245771672572,
+ -1808429243461201518, 7990420780896957397, 4317817392807076702, 3625184369705367340,
+ -6482649271566653105, -3480272027152017464, -3225473396345736649, -368878695502291645,
+ -3981164001421868007, -8522033136963788610, 7609280429197514109, 3020985755112334161,
+ -2572049329799262942, 2635195723621160615, 5144520864246028816, -8188285521126945980,
+ 1567242097116389047, 8172389260191636581, -2885551685425483535, -7060359469858316883,
+ -6480181133964513127, -7317004403633452381, 6011544915663598137, 5932255307352610768,
+ 2241128460406315459, -8327867140638080220, 3094483003111372717, 4583857460292963101,
+ 9079887171656594975, -384082854924064405, -3460631649611717935, 4225072055348026230,
+ -7385151438465742745, 3801620336801580414, -399845416774701952, -7446754431269675473,
+ 7899055018877642622, 5421679761463003041, 5521102963086275121, -4975092593295409910,
+ 8735487530905098534, -7462844945281082830, -2080886987197029914, -1000715163927557685,
+ -4253840471931071485, -5828896094657903328, 6424174453260338141, 359248545074932887,
+ -5949720754023045210, -2426265837057637212, 3030918217665093212, -9077771202237461772,
+ -3186796180789149575, 740416251634527158, -2142944401404840226, 6951781370868335478,
+ 399922722363687927, -8928469722407522623, -1378421100515597285, -8343051178220066766,
+ -3030716356046100229, -8811767350470065420, 9026808440365124461, 6440783557497587732,
+ 4615674634722404292, 539897290441580544, 2096238225866883852, 8751955639408182687,
+ -7316147128802486205, 7381039757301768559, 6157238513393239656, -1473377804940618233,
+ 8629571604380892756, 5280433031239081479, 7101611890139813254, 2479018537985767835,
+ 7169176924412769570, -1281305539061572506, -7865612307799218120, 2278447439451174845,
+ 3625338785743880657, 6477479539006708521, 8976185375579272206, -3712000482142939688,
+ 1326024180520890843, 7537449876596048829, 5464680203499696154, 3189671183162196045,
+ 6346751753565857109, -8982212049534145501, -6127578587196093755, -245039190118465649,
+ -6320577374581628592, 7208698530190629697, 7276901792339343736, -7490986807540332668,
+ 4133292154170828382, 2918308698224194548, -7703910638917631350, -3929437324238184044,
+ -4300543082831323144, -6344160503358350167, 5896236396443472108, -758328221503023383,
+ -1894351639983151068, -307900319840287220, -6278469401177312761, -2171292963361310674,
+ 8382142935188824023, 9103922860780351547, 4152330101494654406,
+ }
+)
+
+type rngSource struct {
+ tap int // index into vec
+ feed int // index into vec
+ vec [rngLen]int64 // current feedback register
+}
+
+// seed rng x[n+1] = 48271 * x[n] mod (2**31 - 1)
+func seedrand(x int32) int32 {
+ const (
+ A = 48271
+ Q = 44488
+ R = 3399
+ )
+
+ hi := x / Q
+ lo := x % Q
+ x = A*lo - R*hi
+ if x < 0 {
+ x += int32max
+ }
+ return x
+}
+
+// Seed uses the provided seed value to initialize the generator to a deterministic state.
+func (rng *rngSource) Seed(seed int64) {
+ rng.tap = 0
+ rng.feed = rngLen - rngTap
+
+ seed = seed % int32max
+ if seed < 0 {
+ seed += int32max
+ }
+ if seed == 0 {
+ seed = 89482311
+ }
+
+ x := int32(seed)
+ for i := -20; i < rngLen; i++ {
+ x = seedrand(x)
+ if i >= 0 {
+ var u int64
+ u = int64(x) << 40
+ x = seedrand(x)
+ u ^= int64(x) << 20
+ x = seedrand(x)
+ u ^= int64(x)
+ u ^= rngCooked[i]
+ rng.vec[i] = u
+ }
+ }
+}
+
+// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
+func (rng *rngSource) Int63() int64 {
+ return int64(rng.Uint64() & rngMask)
+}
+
+// Uint64 returns a non-negative pseudo-random 64-bit integer as a uint64.
+func (rng *rngSource) Uint64() uint64 {
+ rng.tap--
+ if rng.tap < 0 {
+ rng.tap += rngLen
+ }
+
+ rng.feed--
+ if rng.feed < 0 {
+ rng.feed += rngLen
+ }
+
+ x := rng.vec[rng.feed] + rng.vec[rng.tap]
+ rng.vec[rng.feed] = x
+ return uint64(x)
+}
diff --git a/contrib/go/_std_1.21/src/math/rand/ya.make b/contrib/go/_std_1.21/src/math/rand/ya.make
new file mode 100644
index 0000000000..dff39546ab
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/rand/ya.make
@@ -0,0 +1,25 @@
+GO_LIBRARY()
+
+SRCS(
+ exp.go
+ normal.go
+ rand.go
+ rng.go
+ zipf.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ auto_test.go
+ default_test.go
+ example_test.go
+ race_test.go
+ rand_test.go
+ regress_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/math/rand/zipf.go b/contrib/go/_std_1.21/src/math/rand/zipf.go
index f04c814eb7..f04c814eb7 100644
--- a/contrib/go/_std_1.20/src/math/rand/zipf.go
+++ b/contrib/go/_std_1.21/src/math/rand/zipf.go
diff --git a/contrib/go/_std_1.20/src/math/remainder.go b/contrib/go/_std_1.21/src/math/remainder.go
index 8e99345c59..8e99345c59 100644
--- a/contrib/go/_std_1.20/src/math/remainder.go
+++ b/contrib/go/_std_1.21/src/math/remainder.go
diff --git a/contrib/go/_std_1.20/src/math/signbit.go b/contrib/go/_std_1.21/src/math/signbit.go
index f6e61d660e..f6e61d660e 100644
--- a/contrib/go/_std_1.20/src/math/signbit.go
+++ b/contrib/go/_std_1.21/src/math/signbit.go
diff --git a/contrib/go/_std_1.20/src/math/sin.go b/contrib/go/_std_1.21/src/math/sin.go
index 4793d7e7cd..4793d7e7cd 100644
--- a/contrib/go/_std_1.20/src/math/sin.go
+++ b/contrib/go/_std_1.21/src/math/sin.go
diff --git a/contrib/go/_std_1.20/src/math/sincos.go b/contrib/go/_std_1.21/src/math/sincos.go
index e3fb96094f..e3fb96094f 100644
--- a/contrib/go/_std_1.20/src/math/sincos.go
+++ b/contrib/go/_std_1.21/src/math/sincos.go
diff --git a/contrib/go/_std_1.20/src/math/sinh.go b/contrib/go/_std_1.21/src/math/sinh.go
index 78b3c299d6..78b3c299d6 100644
--- a/contrib/go/_std_1.20/src/math/sinh.go
+++ b/contrib/go/_std_1.21/src/math/sinh.go
diff --git a/contrib/go/_std_1.20/src/math/sqrt.go b/contrib/go/_std_1.21/src/math/sqrt.go
index 54929ebcaf..54929ebcaf 100644
--- a/contrib/go/_std_1.20/src/math/sqrt.go
+++ b/contrib/go/_std_1.21/src/math/sqrt.go
diff --git a/contrib/go/_std_1.20/src/math/stubs.go b/contrib/go/_std_1.21/src/math/stubs.go
index c4350d4b87..c4350d4b87 100644
--- a/contrib/go/_std_1.20/src/math/stubs.go
+++ b/contrib/go/_std_1.21/src/math/stubs.go
diff --git a/contrib/go/_std_1.20/src/math/tan.go b/contrib/go/_std_1.21/src/math/tan.go
index 8f6e71e82b..8f6e71e82b 100644
--- a/contrib/go/_std_1.20/src/math/tan.go
+++ b/contrib/go/_std_1.21/src/math/tan.go
diff --git a/contrib/go/_std_1.20/src/math/tanh.go b/contrib/go/_std_1.21/src/math/tanh.go
index 94ebc3b651..94ebc3b651 100644
--- a/contrib/go/_std_1.20/src/math/tanh.go
+++ b/contrib/go/_std_1.21/src/math/tanh.go
diff --git a/contrib/go/_std_1.20/src/math/trig_reduce.go b/contrib/go/_std_1.21/src/math/trig_reduce.go
index 5ecdd8375e..5ecdd8375e 100644
--- a/contrib/go/_std_1.20/src/math/trig_reduce.go
+++ b/contrib/go/_std_1.21/src/math/trig_reduce.go
diff --git a/contrib/go/_std_1.20/src/math/unsafe.go b/contrib/go/_std_1.21/src/math/unsafe.go
index e59f50ca62..e59f50ca62 100644
--- a/contrib/go/_std_1.20/src/math/unsafe.go
+++ b/contrib/go/_std_1.21/src/math/unsafe.go
diff --git a/contrib/go/_std_1.21/src/math/ya.make b/contrib/go/_std_1.21/src/math/ya.make
new file mode 100644
index 0000000000..b1198b75f7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/math/ya.make
@@ -0,0 +1,99 @@
+GO_LIBRARY()
+
+SRCS(
+ abs.go
+ acosh.go
+ asin.go
+ asinh.go
+ atan.go
+ atan2.go
+ atanh.go
+ bits.go
+ cbrt.go
+ const.go
+ copysign.go
+ dim.go
+ dim_asm.go
+ erf.go
+ erfinv.go
+ exp.go
+ exp_asm.go
+ expm1.go
+ floor.go
+ floor_asm.go
+ fma.go
+ frexp.go
+ gamma.go
+ hypot.go
+ j0.go
+ j1.go
+ jn.go
+ ldexp.go
+ lgamma.go
+ log.go
+ log10.go
+ log1p.go
+ logb.go
+ mod.go
+ modf.go
+ nextafter.go
+ pow.go
+ pow10.go
+ remainder.go
+ signbit.go
+ sin.go
+ sincos.go
+ sinh.go
+ sqrt.go
+ stubs.go
+ tan.go
+ tanh.go
+ trig_reduce.go
+ unsafe.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ all_test.go
+ const_test.go
+ example_test.go
+ huge_test.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ dim_amd64.s
+ exp2_noasm.go
+ exp_amd64.go
+ exp_amd64.s
+ floor_amd64.s
+ hypot_amd64.s
+ hypot_asm.go
+ log_amd64.s
+ log_asm.go
+ modf_noasm.go
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ dim_arm64.s
+ exp2_asm.go
+ exp_arm64.s
+ floor_arm64.s
+ hypot_noasm.go
+ log_stub.go
+ modf_arm64.s
+ modf_asm.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+ big
+ bits
+ cmplx
+ rand
+)
diff --git a/contrib/go/_std_1.20/src/mime/encodedword.go b/contrib/go/_std_1.21/src/mime/encodedword.go
index e6b470b1fb..e6b470b1fb 100644
--- a/contrib/go/_std_1.20/src/mime/encodedword.go
+++ b/contrib/go/_std_1.21/src/mime/encodedword.go
diff --git a/contrib/go/_std_1.20/src/mime/grammar.go b/contrib/go/_std_1.21/src/mime/grammar.go
index 6a6f71dbd4..6a6f71dbd4 100644
--- a/contrib/go/_std_1.20/src/mime/grammar.go
+++ b/contrib/go/_std_1.21/src/mime/grammar.go
diff --git a/contrib/go/_std_1.20/src/mime/mediatype.go b/contrib/go/_std_1.21/src/mime/mediatype.go
index bc8d417e62..bc8d417e62 100644
--- a/contrib/go/_std_1.20/src/mime/mediatype.go
+++ b/contrib/go/_std_1.21/src/mime/mediatype.go
diff --git a/contrib/go/_std_1.21/src/mime/multipart/formdata.go b/contrib/go/_std_1.21/src/mime/multipart/formdata.go
new file mode 100644
index 0000000000..85bad2a4cb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/mime/multipart/formdata.go
@@ -0,0 +1,306 @@
+// Copyright 2011 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 multipart
+
+import (
+ "bytes"
+ "errors"
+ "internal/godebug"
+ "io"
+ "math"
+ "net/textproto"
+ "os"
+ "strconv"
+)
+
+// ErrMessageTooLarge is returned by ReadForm if the message form
+// data is too large to be processed.
+var ErrMessageTooLarge = errors.New("multipart: message too large")
+
+// TODO(adg,bradfitz): find a way to unify the DoS-prevention strategy here
+// with that of the http package's ParseForm.
+
+// ReadForm parses an entire multipart message whose parts have
+// a Content-Disposition of "form-data".
+// It stores up to maxMemory bytes + 10MB (reserved for non-file parts)
+// in memory. File parts which can't be stored in memory will be stored on
+// disk in temporary files.
+// It returns ErrMessageTooLarge if all non-file parts can't be stored in
+// memory.
+func (r *Reader) ReadForm(maxMemory int64) (*Form, error) {
+ return r.readForm(maxMemory)
+}
+
+var (
+ multipartFiles = godebug.New("#multipartfiles") // TODO: document and remove #
+ multipartMaxParts = godebug.New("multipartmaxparts")
+)
+
+func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) {
+ form := &Form{make(map[string][]string), make(map[string][]*FileHeader)}
+ var (
+ file *os.File
+ fileOff int64
+ )
+ numDiskFiles := 0
+ combineFiles := true
+ if multipartFiles.Value() == "distinct" {
+ combineFiles = false
+ // multipartFiles.IncNonDefault() // TODO: uncomment after documenting
+ }
+ maxParts := 1000
+ if s := multipartMaxParts.Value(); s != "" {
+ if v, err := strconv.Atoi(s); err == nil && v >= 0 {
+ maxParts = v
+ multipartMaxParts.IncNonDefault()
+ }
+ }
+ maxHeaders := maxMIMEHeaders()
+
+ defer func() {
+ if file != nil {
+ if cerr := file.Close(); err == nil {
+ err = cerr
+ }
+ }
+ if combineFiles && numDiskFiles > 1 {
+ for _, fhs := range form.File {
+ for _, fh := range fhs {
+ fh.tmpshared = true
+ }
+ }
+ }
+ if err != nil {
+ form.RemoveAll()
+ if file != nil {
+ os.Remove(file.Name())
+ }
+ }
+ }()
+
+ // maxFileMemoryBytes is the maximum bytes of file data we will store in memory.
+ // Data past this limit is written to disk.
+ // This limit strictly applies to content, not metadata (filenames, MIME headers, etc.),
+ // since metadata is always stored in memory, not disk.
+ //
+ // maxMemoryBytes is the maximum bytes we will store in memory, including file content,
+ // non-file part values, metadata, and map entry overhead.
+ //
+ // We reserve an additional 10 MB in maxMemoryBytes for non-file data.
+ //
+ // The relationship between these parameters, as well as the overly-large and
+ // unconfigurable 10 MB added on to maxMemory, is unfortunate but difficult to change
+ // within the constraints of the API as documented.
+ maxFileMemoryBytes := maxMemory
+ if maxFileMemoryBytes == math.MaxInt64 {
+ maxFileMemoryBytes--
+ }
+ maxMemoryBytes := maxMemory + int64(10<<20)
+ if maxMemoryBytes <= 0 {
+ if maxMemory < 0 {
+ maxMemoryBytes = 0
+ } else {
+ maxMemoryBytes = math.MaxInt64
+ }
+ }
+ var copyBuf []byte
+ for {
+ p, err := r.nextPart(false, maxMemoryBytes, maxHeaders)
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return nil, err
+ }
+ if maxParts <= 0 {
+ return nil, ErrMessageTooLarge
+ }
+ maxParts--
+
+ name := p.FormName()
+ if name == "" {
+ continue
+ }
+ filename := p.FileName()
+
+ // Multiple values for the same key (one map entry, longer slice) are cheaper
+ // than the same number of values for different keys (many map entries), but
+ // using a consistent per-value cost for overhead is simpler.
+ const mapEntryOverhead = 200
+ maxMemoryBytes -= int64(len(name))
+ maxMemoryBytes -= mapEntryOverhead
+ if maxMemoryBytes < 0 {
+ // We can't actually take this path, since nextPart would already have
+ // rejected the MIME headers for being too large. Check anyway.
+ return nil, ErrMessageTooLarge
+ }
+
+ var b bytes.Buffer
+
+ if filename == "" {
+ // value, store as string in memory
+ n, err := io.CopyN(&b, p, maxMemoryBytes+1)
+ if err != nil && err != io.EOF {
+ return nil, err
+ }
+ maxMemoryBytes -= n
+ if maxMemoryBytes < 0 {
+ return nil, ErrMessageTooLarge
+ }
+ form.Value[name] = append(form.Value[name], b.String())
+ continue
+ }
+
+ // file, store in memory or on disk
+ const fileHeaderSize = 100
+ maxMemoryBytes -= mimeHeaderSize(p.Header)
+ maxMemoryBytes -= mapEntryOverhead
+ maxMemoryBytes -= fileHeaderSize
+ if maxMemoryBytes < 0 {
+ return nil, ErrMessageTooLarge
+ }
+ for _, v := range p.Header {
+ maxHeaders -= int64(len(v))
+ }
+ fh := &FileHeader{
+ Filename: filename,
+ Header: p.Header,
+ }
+ n, err := io.CopyN(&b, p, maxFileMemoryBytes+1)
+ if err != nil && err != io.EOF {
+ return nil, err
+ }
+ if n > maxFileMemoryBytes {
+ if file == nil {
+ file, err = os.CreateTemp(r.tempDir, "multipart-")
+ if err != nil {
+ return nil, err
+ }
+ }
+ numDiskFiles++
+ if _, err := file.Write(b.Bytes()); err != nil {
+ return nil, err
+ }
+ if copyBuf == nil {
+ copyBuf = make([]byte, 32*1024) // same buffer size as io.Copy uses
+ }
+ // os.File.ReadFrom will allocate its own copy buffer if we let io.Copy use it.
+ type writerOnly struct{ io.Writer }
+ remainingSize, err := io.CopyBuffer(writerOnly{file}, p, copyBuf)
+ if err != nil {
+ return nil, err
+ }
+ fh.tmpfile = file.Name()
+ fh.Size = int64(b.Len()) + remainingSize
+ fh.tmpoff = fileOff
+ fileOff += fh.Size
+ if !combineFiles {
+ if err := file.Close(); err != nil {
+ return nil, err
+ }
+ file = nil
+ }
+ } else {
+ fh.content = b.Bytes()
+ fh.Size = int64(len(fh.content))
+ maxFileMemoryBytes -= n
+ maxMemoryBytes -= n
+ }
+ form.File[name] = append(form.File[name], fh)
+ }
+
+ return form, nil
+}
+
+func mimeHeaderSize(h textproto.MIMEHeader) (size int64) {
+ size = 400
+ for k, vs := range h {
+ size += int64(len(k))
+ size += 200 // map entry overhead
+ for _, v := range vs {
+ size += int64(len(v))
+ }
+ }
+ return size
+}
+
+// Form is a parsed multipart form.
+// Its File parts are stored either in memory or on disk,
+// and are accessible via the *FileHeader's Open method.
+// Its Value parts are stored as strings.
+// Both are keyed by field name.
+type Form struct {
+ Value map[string][]string
+ File map[string][]*FileHeader
+}
+
+// RemoveAll removes any temporary files associated with a Form.
+func (f *Form) RemoveAll() error {
+ var err error
+ for _, fhs := range f.File {
+ for _, fh := range fhs {
+ if fh.tmpfile != "" {
+ e := os.Remove(fh.tmpfile)
+ if e != nil && !errors.Is(e, os.ErrNotExist) && err == nil {
+ err = e
+ }
+ }
+ }
+ }
+ return err
+}
+
+// A FileHeader describes a file part of a multipart request.
+type FileHeader struct {
+ Filename string
+ Header textproto.MIMEHeader
+ Size int64
+
+ content []byte
+ tmpfile string
+ tmpoff int64
+ tmpshared bool
+}
+
+// Open opens and returns the FileHeader's associated File.
+func (fh *FileHeader) Open() (File, error) {
+ if b := fh.content; b != nil {
+ r := io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b)))
+ return sectionReadCloser{r, nil}, nil
+ }
+ if fh.tmpshared {
+ f, err := os.Open(fh.tmpfile)
+ if err != nil {
+ return nil, err
+ }
+ r := io.NewSectionReader(f, fh.tmpoff, fh.Size)
+ return sectionReadCloser{r, f}, nil
+ }
+ return os.Open(fh.tmpfile)
+}
+
+// File is an interface to access the file part of a multipart message.
+// Its contents may be either stored in memory or on disk.
+// If stored on disk, the File's underlying concrete type will be an *os.File.
+type File interface {
+ io.Reader
+ io.ReaderAt
+ io.Seeker
+ io.Closer
+}
+
+// helper types to turn a []byte into a File
+
+type sectionReadCloser struct {
+ *io.SectionReader
+ io.Closer
+}
+
+func (rc sectionReadCloser) Close() error {
+ if rc.Closer != nil {
+ return rc.Closer.Close()
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/mime/multipart/multipart.go b/contrib/go/_std_1.21/src/mime/multipart/multipart.go
new file mode 100644
index 0000000000..da1f45810e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/mime/multipart/multipart.go
@@ -0,0 +1,488 @@
+// Copyright 2010 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 multipart implements MIME multipart parsing, as defined in RFC
+2046.
+
+The implementation is sufficient for HTTP (RFC 2388) and the multipart
+bodies generated by popular browsers.
+
+# Limits
+
+To protect against malicious inputs, this package sets limits on the size
+of the MIME data it processes.
+
+Reader.NextPart and Reader.NextRawPart limit the number of headers in a
+part to 10000 and Reader.ReadForm limits the total number of headers in all
+FileHeaders to 10000.
+These limits may be adjusted with the GODEBUG=multipartmaxheaders=<values>
+setting.
+
+Reader.ReadForm further limits the number of parts in a form to 1000.
+This limit may be adjusted with the GODEBUG=multipartmaxparts=<value>
+setting.
+*/
+package multipart
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "internal/godebug"
+ "io"
+ "mime"
+ "mime/quotedprintable"
+ "net/textproto"
+ "path/filepath"
+ "strconv"
+ "strings"
+)
+
+var emptyParams = make(map[string]string)
+
+// This constant needs to be at least 76 for this package to work correctly.
+// This is because \r\n--separator_of_len_70- would fill the buffer and it
+// wouldn't be safe to consume a single byte from it.
+const peekBufferSize = 4096
+
+// A Part represents a single part in a multipart body.
+type Part struct {
+ // The headers of the body, if any, with the keys canonicalized
+ // in the same fashion that the Go http.Request headers are.
+ // For example, "foo-bar" changes case to "Foo-Bar"
+ Header textproto.MIMEHeader
+
+ mr *Reader
+
+ disposition string
+ dispositionParams map[string]string
+
+ // r is either a reader directly reading from mr, or it's a
+ // wrapper around such a reader, decoding the
+ // Content-Transfer-Encoding
+ r io.Reader
+
+ n int // known data bytes waiting in mr.bufReader
+ total int64 // total data bytes read already
+ err error // error to return when n == 0
+ readErr error // read error observed from mr.bufReader
+}
+
+// FormName returns the name parameter if p has a Content-Disposition
+// of type "form-data". Otherwise it returns the empty string.
+func (p *Part) FormName() string {
+ // See https://tools.ietf.org/html/rfc2183 section 2 for EBNF
+ // of Content-Disposition value format.
+ if p.dispositionParams == nil {
+ p.parseContentDisposition()
+ }
+ if p.disposition != "form-data" {
+ return ""
+ }
+ return p.dispositionParams["name"]
+}
+
+// FileName returns the filename parameter of the Part's Content-Disposition
+// header. If not empty, the filename is passed through filepath.Base (which is
+// platform dependent) before being returned.
+func (p *Part) FileName() string {
+ if p.dispositionParams == nil {
+ p.parseContentDisposition()
+ }
+ filename := p.dispositionParams["filename"]
+ if filename == "" {
+ return ""
+ }
+ // RFC 7578, Section 4.2 requires that if a filename is provided, the
+ // directory path information must not be used.
+ return filepath.Base(filename)
+}
+
+func (p *Part) parseContentDisposition() {
+ v := p.Header.Get("Content-Disposition")
+ var err error
+ p.disposition, p.dispositionParams, err = mime.ParseMediaType(v)
+ if err != nil {
+ p.dispositionParams = emptyParams
+ }
+}
+
+// NewReader creates a new multipart Reader reading from r using the
+// given MIME boundary.
+//
+// The boundary is usually obtained from the "boundary" parameter of
+// the message's "Content-Type" header. Use mime.ParseMediaType to
+// parse such headers.
+func NewReader(r io.Reader, boundary string) *Reader {
+ b := []byte("\r\n--" + boundary + "--")
+ return &Reader{
+ bufReader: bufio.NewReaderSize(&stickyErrorReader{r: r}, peekBufferSize),
+ nl: b[:2],
+ nlDashBoundary: b[:len(b)-2],
+ dashBoundaryDash: b[2:],
+ dashBoundary: b[2 : len(b)-2],
+ }
+}
+
+// stickyErrorReader is an io.Reader which never calls Read on its
+// underlying Reader once an error has been seen. (the io.Reader
+// interface's contract promises nothing about the return values of
+// Read calls after an error, yet this package does do multiple Reads
+// after error)
+type stickyErrorReader struct {
+ r io.Reader
+ err error
+}
+
+func (r *stickyErrorReader) Read(p []byte) (n int, _ error) {
+ if r.err != nil {
+ return 0, r.err
+ }
+ n, r.err = r.r.Read(p)
+ return n, r.err
+}
+
+func newPart(mr *Reader, rawPart bool, maxMIMEHeaderSize, maxMIMEHeaders int64) (*Part, error) {
+ bp := &Part{
+ Header: make(map[string][]string),
+ mr: mr,
+ }
+ if err := bp.populateHeaders(maxMIMEHeaderSize, maxMIMEHeaders); err != nil {
+ return nil, err
+ }
+ bp.r = partReader{bp}
+
+ // rawPart is used to switch between Part.NextPart and Part.NextRawPart.
+ if !rawPart {
+ const cte = "Content-Transfer-Encoding"
+ if strings.EqualFold(bp.Header.Get(cte), "quoted-printable") {
+ bp.Header.Del(cte)
+ bp.r = quotedprintable.NewReader(bp.r)
+ }
+ }
+ return bp, nil
+}
+
+func (p *Part) populateHeaders(maxMIMEHeaderSize, maxMIMEHeaders int64) error {
+ r := textproto.NewReader(p.mr.bufReader)
+ header, err := readMIMEHeader(r, maxMIMEHeaderSize, maxMIMEHeaders)
+ if err == nil {
+ p.Header = header
+ }
+ // TODO: Add a distinguishable error to net/textproto.
+ if err != nil && err.Error() == "message too large" {
+ err = ErrMessageTooLarge
+ }
+ return err
+}
+
+// Read reads the body of a part, after its headers and before the
+// next part (if any) begins.
+func (p *Part) Read(d []byte) (n int, err error) {
+ return p.r.Read(d)
+}
+
+// partReader implements io.Reader by reading raw bytes directly from the
+// wrapped *Part, without doing any Transfer-Encoding decoding.
+type partReader struct {
+ p *Part
+}
+
+func (pr partReader) Read(d []byte) (int, error) {
+ p := pr.p
+ br := p.mr.bufReader
+
+ // Read into buffer until we identify some data to return,
+ // or we find a reason to stop (boundary or read error).
+ for p.n == 0 && p.err == nil {
+ peek, _ := br.Peek(br.Buffered())
+ p.n, p.err = scanUntilBoundary(peek, p.mr.dashBoundary, p.mr.nlDashBoundary, p.total, p.readErr)
+ if p.n == 0 && p.err == nil {
+ // Force buffered I/O to read more into buffer.
+ _, p.readErr = br.Peek(len(peek) + 1)
+ if p.readErr == io.EOF {
+ p.readErr = io.ErrUnexpectedEOF
+ }
+ }
+ }
+
+ // Read out from "data to return" part of buffer.
+ if p.n == 0 {
+ return 0, p.err
+ }
+ n := len(d)
+ if n > p.n {
+ n = p.n
+ }
+ n, _ = br.Read(d[:n])
+ p.total += int64(n)
+ p.n -= n
+ if p.n == 0 {
+ return n, p.err
+ }
+ return n, nil
+}
+
+// scanUntilBoundary scans buf to identify how much of it can be safely
+// returned as part of the Part body.
+// dashBoundary is "--boundary".
+// nlDashBoundary is "\r\n--boundary" or "\n--boundary", depending on what mode we are in.
+// The comments below (and the name) assume "\n--boundary", but either is accepted.
+// total is the number of bytes read out so far. If total == 0, then a leading "--boundary" is recognized.
+// readErr is the read error, if any, that followed reading the bytes in buf.
+// scanUntilBoundary returns the number of data bytes from buf that can be
+// returned as part of the Part body and also the error to return (if any)
+// once those data bytes are done.
+func scanUntilBoundary(buf, dashBoundary, nlDashBoundary []byte, total int64, readErr error) (int, error) {
+ if total == 0 {
+ // At beginning of body, allow dashBoundary.
+ if bytes.HasPrefix(buf, dashBoundary) {
+ switch matchAfterPrefix(buf, dashBoundary, readErr) {
+ case -1:
+ return len(dashBoundary), nil
+ case 0:
+ return 0, nil
+ case +1:
+ return 0, io.EOF
+ }
+ }
+ if bytes.HasPrefix(dashBoundary, buf) {
+ return 0, readErr
+ }
+ }
+
+ // Search for "\n--boundary".
+ if i := bytes.Index(buf, nlDashBoundary); i >= 0 {
+ switch matchAfterPrefix(buf[i:], nlDashBoundary, readErr) {
+ case -1:
+ return i + len(nlDashBoundary), nil
+ case 0:
+ return i, nil
+ case +1:
+ return i, io.EOF
+ }
+ }
+ if bytes.HasPrefix(nlDashBoundary, buf) {
+ return 0, readErr
+ }
+
+ // Otherwise, anything up to the final \n is not part of the boundary
+ // and so must be part of the body.
+ // Also if the section from the final \n onward is not a prefix of the boundary,
+ // it too must be part of the body.
+ i := bytes.LastIndexByte(buf, nlDashBoundary[0])
+ if i >= 0 && bytes.HasPrefix(nlDashBoundary, buf[i:]) {
+ return i, nil
+ }
+ return len(buf), readErr
+}
+
+// matchAfterPrefix checks whether buf should be considered to match the boundary.
+// The prefix is "--boundary" or "\r\n--boundary" or "\n--boundary",
+// and the caller has verified already that bytes.HasPrefix(buf, prefix) is true.
+//
+// matchAfterPrefix returns +1 if the buffer does match the boundary,
+// meaning the prefix is followed by a double dash, space, tab, cr, nl,
+// or end of input.
+// It returns -1 if the buffer definitely does NOT match the boundary,
+// meaning the prefix is followed by some other character.
+// For example, "--foobar" does not match "--foo".
+// It returns 0 more input needs to be read to make the decision,
+// meaning that len(buf) == len(prefix) and readErr == nil.
+func matchAfterPrefix(buf, prefix []byte, readErr error) int {
+ if len(buf) == len(prefix) {
+ if readErr != nil {
+ return +1
+ }
+ return 0
+ }
+ c := buf[len(prefix)]
+
+ if c == ' ' || c == '\t' || c == '\r' || c == '\n' {
+ return +1
+ }
+
+ // Try to detect boundaryDash
+ if c == '-' {
+ if len(buf) == len(prefix)+1 {
+ if readErr != nil {
+ // Prefix + "-" does not match
+ return -1
+ }
+ return 0
+ }
+ if buf[len(prefix)+1] == '-' {
+ return +1
+ }
+ }
+
+ return -1
+}
+
+func (p *Part) Close() error {
+ io.Copy(io.Discard, p)
+ return nil
+}
+
+// Reader is an iterator over parts in a MIME multipart body.
+// Reader's underlying parser consumes its input as needed. Seeking
+// isn't supported.
+type Reader struct {
+ bufReader *bufio.Reader
+ tempDir string // used in tests
+
+ currentPart *Part
+ partsRead int
+
+ nl []byte // "\r\n" or "\n" (set after seeing first boundary line)
+ nlDashBoundary []byte // nl + "--boundary"
+ dashBoundaryDash []byte // "--boundary--"
+ dashBoundary []byte // "--boundary"
+}
+
+// maxMIMEHeaderSize is the maximum size of a MIME header we will parse,
+// including header keys, values, and map overhead.
+const maxMIMEHeaderSize = 10 << 20
+
+// multipartMaxHeaders is the maximum number of header entries NextPart will return,
+// as well as the maximum combined total of header entries Reader.ReadForm will return
+// in FileHeaders.
+var multipartMaxHeaders = godebug.New("multipartmaxheaders")
+
+func maxMIMEHeaders() int64 {
+ if s := multipartMaxHeaders.Value(); s != "" {
+ if v, err := strconv.ParseInt(s, 10, 64); err == nil && v >= 0 {
+ multipartMaxHeaders.IncNonDefault()
+ return v
+ }
+ }
+ return 10000
+}
+
+// NextPart returns the next part in the multipart or an error.
+// When there are no more parts, the error io.EOF is returned.
+//
+// As a special case, if the "Content-Transfer-Encoding" header
+// has a value of "quoted-printable", that header is instead
+// hidden and the body is transparently decoded during Read calls.
+func (r *Reader) NextPart() (*Part, error) {
+ return r.nextPart(false, maxMIMEHeaderSize, maxMIMEHeaders())
+}
+
+// NextRawPart returns the next part in the multipart or an error.
+// When there are no more parts, the error io.EOF is returned.
+//
+// Unlike NextPart, it does not have special handling for
+// "Content-Transfer-Encoding: quoted-printable".
+func (r *Reader) NextRawPart() (*Part, error) {
+ return r.nextPart(true, maxMIMEHeaderSize, maxMIMEHeaders())
+}
+
+func (r *Reader) nextPart(rawPart bool, maxMIMEHeaderSize, maxMIMEHeaders int64) (*Part, error) {
+ if r.currentPart != nil {
+ r.currentPart.Close()
+ }
+ if string(r.dashBoundary) == "--" {
+ return nil, fmt.Errorf("multipart: boundary is empty")
+ }
+ expectNewPart := false
+ for {
+ line, err := r.bufReader.ReadSlice('\n')
+
+ if err == io.EOF && r.isFinalBoundary(line) {
+ // If the buffer ends in "--boundary--" without the
+ // trailing "\r\n", ReadSlice will return an error
+ // (since it's missing the '\n'), but this is a valid
+ // multipart EOF so we need to return io.EOF instead of
+ // a fmt-wrapped one.
+ return nil, io.EOF
+ }
+ if err != nil {
+ return nil, fmt.Errorf("multipart: NextPart: %w", err)
+ }
+
+ if r.isBoundaryDelimiterLine(line) {
+ r.partsRead++
+ bp, err := newPart(r, rawPart, maxMIMEHeaderSize, maxMIMEHeaders)
+ if err != nil {
+ return nil, err
+ }
+ r.currentPart = bp
+ return bp, nil
+ }
+
+ if r.isFinalBoundary(line) {
+ // Expected EOF
+ return nil, io.EOF
+ }
+
+ if expectNewPart {
+ return nil, fmt.Errorf("multipart: expecting a new Part; got line %q", string(line))
+ }
+
+ if r.partsRead == 0 {
+ // skip line
+ continue
+ }
+
+ // Consume the "\n" or "\r\n" separator between the
+ // body of the previous part and the boundary line we
+ // now expect will follow. (either a new part or the
+ // end boundary)
+ if bytes.Equal(line, r.nl) {
+ expectNewPart = true
+ continue
+ }
+
+ return nil, fmt.Errorf("multipart: unexpected line in Next(): %q", line)
+ }
+}
+
+// isFinalBoundary reports whether line is the final boundary line
+// indicating that all parts are over.
+// It matches `^--boundary--[ \t]*(\r\n)?$`
+func (r *Reader) isFinalBoundary(line []byte) bool {
+ if !bytes.HasPrefix(line, r.dashBoundaryDash) {
+ return false
+ }
+ rest := line[len(r.dashBoundaryDash):]
+ rest = skipLWSPChar(rest)
+ return len(rest) == 0 || bytes.Equal(rest, r.nl)
+}
+
+func (r *Reader) isBoundaryDelimiterLine(line []byte) (ret bool) {
+ // https://tools.ietf.org/html/rfc2046#section-5.1
+ // The boundary delimiter line is then defined as a line
+ // consisting entirely of two hyphen characters ("-",
+ // decimal value 45) followed by the boundary parameter
+ // value from the Content-Type header field, optional linear
+ // whitespace, and a terminating CRLF.
+ if !bytes.HasPrefix(line, r.dashBoundary) {
+ return false
+ }
+ rest := line[len(r.dashBoundary):]
+ rest = skipLWSPChar(rest)
+
+ // On the first part, see our lines are ending in \n instead of \r\n
+ // and switch into that mode if so. This is a violation of the spec,
+ // but occurs in practice.
+ if r.partsRead == 0 && len(rest) == 1 && rest[0] == '\n' {
+ r.nl = r.nl[1:]
+ r.nlDashBoundary = r.nlDashBoundary[1:]
+ }
+ return bytes.Equal(rest, r.nl)
+}
+
+// skipLWSPChar returns b with leading spaces and tabs removed.
+// RFC 822 defines:
+//
+// LWSP-char = SPACE / HTAB
+func skipLWSPChar(b []byte) []byte {
+ for len(b) > 0 && (b[0] == ' ' || b[0] == '\t') {
+ b = b[1:]
+ }
+ return b
+}
diff --git a/contrib/go/_std_1.20/src/mime/multipart/readmimeheader.go b/contrib/go/_std_1.21/src/mime/multipart/readmimeheader.go
index e6be490c8c..e6be490c8c 100644
--- a/contrib/go/_std_1.20/src/mime/multipart/readmimeheader.go
+++ b/contrib/go/_std_1.21/src/mime/multipart/readmimeheader.go
diff --git a/contrib/go/_std_1.20/src/mime/multipart/writer.go b/contrib/go/_std_1.21/src/mime/multipart/writer.go
index d1ff151a7d..d1ff151a7d 100644
--- a/contrib/go/_std_1.20/src/mime/multipart/writer.go
+++ b/contrib/go/_std_1.21/src/mime/multipart/writer.go
diff --git a/contrib/go/_std_1.21/src/mime/multipart/ya.make b/contrib/go/_std_1.21/src/mime/multipart/ya.make
new file mode 100644
index 0000000000..c5100de35b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/mime/multipart/ya.make
@@ -0,0 +1,21 @@
+GO_LIBRARY()
+
+SRCS(
+ formdata.go
+ multipart.go
+ readmimeheader.go
+ writer.go
+)
+
+GO_TEST_SRCS(
+ formdata_test.go
+ multipart_test.go
+ writer_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/mime/quotedprintable/reader.go b/contrib/go/_std_1.21/src/mime/quotedprintable/reader.go
index 4239625402..4239625402 100644
--- a/contrib/go/_std_1.20/src/mime/quotedprintable/reader.go
+++ b/contrib/go/_std_1.21/src/mime/quotedprintable/reader.go
diff --git a/contrib/go/_std_1.20/src/mime/quotedprintable/writer.go b/contrib/go/_std_1.21/src/mime/quotedprintable/writer.go
index 16ea0bf7d6..16ea0bf7d6 100644
--- a/contrib/go/_std_1.20/src/mime/quotedprintable/writer.go
+++ b/contrib/go/_std_1.21/src/mime/quotedprintable/writer.go
diff --git a/contrib/go/_std_1.21/src/mime/quotedprintable/ya.make b/contrib/go/_std_1.21/src/mime/quotedprintable/ya.make
new file mode 100644
index 0000000000..e2ae04e06e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/mime/quotedprintable/ya.make
@@ -0,0 +1,18 @@
+GO_LIBRARY()
+
+SRCS(
+ reader.go
+ writer.go
+)
+
+GO_TEST_SRCS(
+ reader_test.go
+ writer_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/mime/type.go b/contrib/go/_std_1.21/src/mime/type.go
index 465ecf0d59..465ecf0d59 100644
--- a/contrib/go/_std_1.20/src/mime/type.go
+++ b/contrib/go/_std_1.21/src/mime/type.go
diff --git a/contrib/go/_std_1.21/src/mime/type_unix.go b/contrib/go/_std_1.21/src/mime/type_unix.go
new file mode 100644
index 0000000000..90414c1a18
--- /dev/null
+++ b/contrib/go/_std_1.21/src/mime/type_unix.go
@@ -0,0 +1,126 @@
+// Copyright 2010 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package mime
+
+import (
+ "bufio"
+ "os"
+ "strings"
+)
+
+func init() {
+ osInitMime = initMimeUnix
+}
+
+// See https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-0.21.html
+// for the FreeDesktop Shared MIME-info Database specification.
+var mimeGlobs = []string{
+ "/usr/local/share/mime/globs2",
+ "/usr/share/mime/globs2",
+}
+
+// Common locations for mime.types files on unix.
+var typeFiles = []string{
+ "/etc/mime.types",
+ "/etc/apache2/mime.types",
+ "/etc/apache/mime.types",
+ "/etc/httpd/conf/mime.types",
+}
+
+func loadMimeGlobsFile(filename string) error {
+ f, err := os.Open(filename)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ // Each line should be of format: weight:mimetype:glob[:morefields...]
+ fields := strings.Split(scanner.Text(), ":")
+ if len(fields) < 3 || len(fields[0]) < 1 || len(fields[2]) < 3 {
+ continue
+ } else if fields[0][0] == '#' || fields[2][0] != '*' || fields[2][1] != '.' {
+ continue
+ }
+
+ extension := fields[2][1:]
+ if strings.ContainsAny(extension, "?*[") {
+ // Not a bare extension, but a glob. Ignore for now:
+ // - we do not have an implementation for this glob
+ // syntax (translation to path/filepath.Match could
+ // be possible)
+ // - support for globs with weight ordering would have
+ // performance impact to all lookups to support the
+ // rarely seen glob entries
+ // - trying to match glob metacharacters literally is
+ // not useful
+ continue
+ }
+ if _, ok := mimeTypes.Load(extension); ok {
+ // We've already seen this extension.
+ // The file is in weight order, so we keep
+ // the first entry that we see.
+ continue
+ }
+
+ setExtensionType(extension, fields[1])
+ }
+ if err := scanner.Err(); err != nil {
+ panic(err)
+ }
+ return nil
+}
+
+func loadMimeFile(filename string) {
+ f, err := os.Open(filename)
+ if err != nil {
+ return
+ }
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ fields := strings.Fields(scanner.Text())
+ if len(fields) <= 1 || fields[0][0] == '#' {
+ continue
+ }
+ mimeType := fields[0]
+ for _, ext := range fields[1:] {
+ if ext[0] == '#' {
+ break
+ }
+ setExtensionType("."+ext, mimeType)
+ }
+ }
+ if err := scanner.Err(); err != nil {
+ panic(err)
+ }
+}
+
+func initMimeUnix() {
+ for _, filename := range mimeGlobs {
+ if err := loadMimeGlobsFile(filename); err == nil {
+ return // Stop checking more files if mimetype database is found.
+ }
+ }
+
+ // Fallback if no system-generated mimetype database exists.
+ for _, filename := range typeFiles {
+ loadMimeFile(filename)
+ }
+}
+
+func initMimeForTests() map[string]string {
+ mimeGlobs = []string{""}
+ typeFiles = []string{"testdata/test.types"}
+ return map[string]string{
+ ".T1": "application/test",
+ ".t2": "text/test; charset=utf-8",
+ ".png": "image/png",
+ }
+}
diff --git a/contrib/go/_std_1.20/src/mime/type_windows.go b/contrib/go/_std_1.21/src/mime/type_windows.go
index 93802141c5..93802141c5 100644
--- a/contrib/go/_std_1.20/src/mime/type_windows.go
+++ b/contrib/go/_std_1.21/src/mime/type_windows.go
diff --git a/contrib/go/_std_1.21/src/mime/ya.make b/contrib/go/_std_1.21/src/mime/ya.make
new file mode 100644
index 0000000000..577565f24a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/mime/ya.make
@@ -0,0 +1,45 @@
+GO_LIBRARY()
+
+SRCS(
+ encodedword.go
+ grammar.go
+ mediatype.go
+ type.go
+)
+
+GO_TEST_SRCS(
+ encodedword_test.go
+ mediatype_test.go
+ type_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+IF (OS_LINUX)
+ SRCS(
+ type_unix.go
+ )
+
+ GO_TEST_SRCS(type_unix_test.go)
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ type_unix.go
+ )
+
+ GO_TEST_SRCS(type_unix_test.go)
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ type_windows.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+ multipart
+ quotedprintable
+)
diff --git a/contrib/go/_std_1.20/src/net/addrselect.go b/contrib/go/_std_1.21/src/net/addrselect.go
index 4f07032c4a..4f07032c4a 100644
--- a/contrib/go/_std_1.20/src/net/addrselect.go
+++ b/contrib/go/_std_1.21/src/net/addrselect.go
diff --git a/contrib/go/_std_1.20/src/net/cgo_darwin.go b/contrib/go/_std_1.21/src/net/cgo_darwin.go
index 129dd937fe..129dd937fe 100644
--- a/contrib/go/_std_1.20/src/net/cgo_darwin.go
+++ b/contrib/go/_std_1.21/src/net/cgo_darwin.go
diff --git a/contrib/go/_std_1.20/src/net/cgo_linux.go b/contrib/go/_std_1.21/src/net/cgo_linux.go
index de6e87f176..de6e87f176 100644
--- a/contrib/go/_std_1.20/src/net/cgo_linux.go
+++ b/contrib/go/_std_1.21/src/net/cgo_linux.go
diff --git a/contrib/go/_std_1.20/src/net/cgo_resnew.go b/contrib/go/_std_1.21/src/net/cgo_resnew.go
index 3f21c5c4c4..3f21c5c4c4 100644
--- a/contrib/go/_std_1.20/src/net/cgo_resnew.go
+++ b/contrib/go/_std_1.21/src/net/cgo_resnew.go
diff --git a/contrib/go/_std_1.20/src/net/cgo_socknew.go b/contrib/go/_std_1.21/src/net/cgo_socknew.go
index fbb9e10f34..fbb9e10f34 100644
--- a/contrib/go/_std_1.20/src/net/cgo_socknew.go
+++ b/contrib/go/_std_1.21/src/net/cgo_socknew.go
diff --git a/contrib/go/_std_1.21/src/net/cgo_unix.go b/contrib/go/_std_1.21/src/net/cgo_unix.go
new file mode 100644
index 0000000000..f10f3ea60b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/cgo_unix.go
@@ -0,0 +1,370 @@
+// Copyright 2011 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.
+
+// This file is called cgo_unix.go, but to allow syscalls-to-libc-based
+// implementations to share the code, it does not use cgo directly.
+// Instead of C.foo it uses _C_foo, which is defined in either
+// cgo_unix_cgo.go or cgo_unix_syscall.go
+
+//go:build !netgo && ((cgo && unix) || darwin)
+
+package net
+
+import (
+ "context"
+ "errors"
+ "net/netip"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/net/dns/dnsmessage"
+)
+
+// cgoAvailable set to true to indicate that the cgo resolver
+// is available on this system.
+const cgoAvailable = true
+
+// An addrinfoErrno represents a getaddrinfo, getnameinfo-specific
+// error number. It's a signed number and a zero value is a non-error
+// by convention.
+type addrinfoErrno int
+
+func (eai addrinfoErrno) Error() string { return _C_gai_strerror(_C_int(eai)) }
+func (eai addrinfoErrno) Temporary() bool { return eai == _C_EAI_AGAIN }
+func (eai addrinfoErrno) Timeout() bool { return false }
+
+// isAddrinfoErrno is just for testing purposes.
+func (eai addrinfoErrno) isAddrinfoErrno() {}
+
+// doBlockingWithCtx executes a blocking function in a separate goroutine when the provided
+// context is cancellable. It is intended for use with calls that don't support context
+// cancellation (cgo, syscalls). blocking func may still be running after this function finishes.
+func doBlockingWithCtx[T any](ctx context.Context, blocking func() (T, error)) (T, error) {
+ if ctx.Done() == nil {
+ return blocking()
+ }
+
+ type result struct {
+ res T
+ err error
+ }
+
+ res := make(chan result, 1)
+ go func() {
+ var r result
+ r.res, r.err = blocking()
+ res <- r
+ }()
+
+ select {
+ case r := <-res:
+ return r.res, r.err
+ case <-ctx.Done():
+ var zero T
+ return zero, mapErr(ctx.Err())
+ }
+}
+
+func cgoLookupHost(ctx context.Context, name string) (hosts []string, err error) {
+ addrs, err := cgoLookupIP(ctx, "ip", name)
+ if err != nil {
+ return nil, err
+ }
+ for _, addr := range addrs {
+ hosts = append(hosts, addr.String())
+ }
+ return hosts, nil
+}
+
+func cgoLookupPort(ctx context.Context, network, service string) (port int, err error) {
+ var hints _C_struct_addrinfo
+ switch network {
+ case "": // no hints
+ case "tcp", "tcp4", "tcp6":
+ *_C_ai_socktype(&hints) = _C_SOCK_STREAM
+ *_C_ai_protocol(&hints) = _C_IPPROTO_TCP
+ case "udp", "udp4", "udp6":
+ *_C_ai_socktype(&hints) = _C_SOCK_DGRAM
+ *_C_ai_protocol(&hints) = _C_IPPROTO_UDP
+ default:
+ return 0, &DNSError{Err: "unknown network", Name: network + "/" + service}
+ }
+ switch ipVersion(network) {
+ case '4':
+ *_C_ai_family(&hints) = _C_AF_INET
+ case '6':
+ *_C_ai_family(&hints) = _C_AF_INET6
+ }
+
+ return doBlockingWithCtx(ctx, func() (int, error) {
+ return cgoLookupServicePort(&hints, network, service)
+ })
+}
+
+func cgoLookupServicePort(hints *_C_struct_addrinfo, network, service string) (port int, err error) {
+ cservice, err := syscall.ByteSliceFromString(service)
+ if err != nil {
+ return 0, &DNSError{Err: err.Error(), Name: network + "/" + service}
+ }
+ // Lowercase the C service name.
+ for i, b := range cservice[:len(service)] {
+ cservice[i] = lowerASCII(b)
+ }
+ var res *_C_struct_addrinfo
+ gerrno, err := _C_getaddrinfo(nil, (*_C_char)(unsafe.Pointer(&cservice[0])), hints, &res)
+ if gerrno != 0 {
+ isTemporary := false
+ switch gerrno {
+ case _C_EAI_SYSTEM:
+ if err == nil { // see golang.org/issue/6232
+ err = syscall.EMFILE
+ }
+ default:
+ err = addrinfoErrno(gerrno)
+ isTemporary = addrinfoErrno(gerrno).Temporary()
+ }
+ return 0, &DNSError{Err: err.Error(), Name: network + "/" + service, IsTemporary: isTemporary}
+ }
+ defer _C_freeaddrinfo(res)
+
+ for r := res; r != nil; r = *_C_ai_next(r) {
+ switch *_C_ai_family(r) {
+ case _C_AF_INET:
+ sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(*_C_ai_addr(r)))
+ p := (*[2]byte)(unsafe.Pointer(&sa.Port))
+ return int(p[0])<<8 | int(p[1]), nil
+ case _C_AF_INET6:
+ sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(*_C_ai_addr(r)))
+ p := (*[2]byte)(unsafe.Pointer(&sa.Port))
+ return int(p[0])<<8 | int(p[1]), nil
+ }
+ }
+ return 0, &DNSError{Err: "unknown port", Name: network + "/" + service}
+}
+
+func cgoLookupHostIP(network, name string) (addrs []IPAddr, err error) {
+ acquireThread()
+ defer releaseThread()
+
+ var hints _C_struct_addrinfo
+ *_C_ai_flags(&hints) = cgoAddrInfoFlags
+ *_C_ai_socktype(&hints) = _C_SOCK_STREAM
+ *_C_ai_family(&hints) = _C_AF_UNSPEC
+ switch ipVersion(network) {
+ case '4':
+ *_C_ai_family(&hints) = _C_AF_INET
+ case '6':
+ *_C_ai_family(&hints) = _C_AF_INET6
+ }
+
+ h, err := syscall.BytePtrFromString(name)
+ if err != nil {
+ return nil, &DNSError{Err: err.Error(), Name: name}
+ }
+ var res *_C_struct_addrinfo
+ gerrno, err := _C_getaddrinfo((*_C_char)(unsafe.Pointer(h)), nil, &hints, &res)
+ if gerrno != 0 {
+ isErrorNoSuchHost := false
+ isTemporary := false
+ switch gerrno {
+ case _C_EAI_SYSTEM:
+ if err == nil {
+ // err should not be nil, but sometimes getaddrinfo returns
+ // gerrno == _C_EAI_SYSTEM with err == nil on Linux.
+ // The report claims that it happens when we have too many
+ // open files, so use syscall.EMFILE (too many open files in system).
+ // Most system calls would return ENFILE (too many open files),
+ // so at the least EMFILE should be easy to recognize if this
+ // comes up again. golang.org/issue/6232.
+ err = syscall.EMFILE
+ }
+ case _C_EAI_NONAME, _C_EAI_NODATA:
+ err = errNoSuchHost
+ isErrorNoSuchHost = true
+ default:
+ err = addrinfoErrno(gerrno)
+ isTemporary = addrinfoErrno(gerrno).Temporary()
+ }
+
+ return nil, &DNSError{Err: err.Error(), Name: name, IsNotFound: isErrorNoSuchHost, IsTemporary: isTemporary}
+ }
+ defer _C_freeaddrinfo(res)
+
+ for r := res; r != nil; r = *_C_ai_next(r) {
+ // We only asked for SOCK_STREAM, but check anyhow.
+ if *_C_ai_socktype(r) != _C_SOCK_STREAM {
+ continue
+ }
+ switch *_C_ai_family(r) {
+ case _C_AF_INET:
+ sa := (*syscall.RawSockaddrInet4)(unsafe.Pointer(*_C_ai_addr(r)))
+ addr := IPAddr{IP: copyIP(sa.Addr[:])}
+ addrs = append(addrs, addr)
+ case _C_AF_INET6:
+ sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(*_C_ai_addr(r)))
+ addr := IPAddr{IP: copyIP(sa.Addr[:]), Zone: zoneCache.name(int(sa.Scope_id))}
+ addrs = append(addrs, addr)
+ }
+ }
+ return addrs, nil
+}
+
+func cgoLookupIP(ctx context.Context, network, name string) (addrs []IPAddr, err error) {
+ return doBlockingWithCtx(ctx, func() ([]IPAddr, error) {
+ return cgoLookupHostIP(network, name)
+ })
+}
+
+// These are roughly enough for the following:
+//
+// Source Encoding Maximum length of single name entry
+// Unicast DNS ASCII or <=253 + a NUL terminator
+// Unicode in RFC 5892 252 * total number of labels + delimiters + a NUL terminator
+// Multicast DNS UTF-8 in RFC 5198 or <=253 + a NUL terminator
+// the same as unicast DNS ASCII <=253 + a NUL terminator
+// Local database various depends on implementation
+const (
+ nameinfoLen = 64
+ maxNameinfoLen = 4096
+)
+
+func cgoLookupPTR(ctx context.Context, addr string) (names []string, err error) {
+ ip, err := netip.ParseAddr(addr)
+ if err != nil {
+ return nil, &DNSError{Err: "invalid address", Name: addr}
+ }
+ sa, salen := cgoSockaddr(IP(ip.AsSlice()), ip.Zone())
+ if sa == nil {
+ return nil, &DNSError{Err: "invalid address " + ip.String(), Name: addr}
+ }
+
+ return doBlockingWithCtx(ctx, func() ([]string, error) {
+ return cgoLookupAddrPTR(addr, sa, salen)
+ })
+}
+
+func cgoLookupAddrPTR(addr string, sa *_C_struct_sockaddr, salen _C_socklen_t) (names []string, err error) {
+ acquireThread()
+ defer releaseThread()
+
+ var gerrno int
+ var b []byte
+ for l := nameinfoLen; l <= maxNameinfoLen; l *= 2 {
+ b = make([]byte, l)
+ gerrno, err = cgoNameinfoPTR(b, sa, salen)
+ if gerrno == 0 || gerrno != _C_EAI_OVERFLOW {
+ break
+ }
+ }
+ if gerrno != 0 {
+ isErrorNoSuchHost := false
+ isTemporary := false
+ switch gerrno {
+ case _C_EAI_SYSTEM:
+ if err == nil { // see golang.org/issue/6232
+ err = syscall.EMFILE
+ }
+ case _C_EAI_NONAME:
+ err = errNoSuchHost
+ isErrorNoSuchHost = true
+ default:
+ err = addrinfoErrno(gerrno)
+ isTemporary = addrinfoErrno(gerrno).Temporary()
+ }
+ return nil, &DNSError{Err: err.Error(), Name: addr, IsTemporary: isTemporary, IsNotFound: isErrorNoSuchHost}
+ }
+ for i := 0; i < len(b); i++ {
+ if b[i] == 0 {
+ b = b[:i]
+ break
+ }
+ }
+ return []string{absDomainName(string(b))}, nil
+}
+
+func cgoSockaddr(ip IP, zone string) (*_C_struct_sockaddr, _C_socklen_t) {
+ if ip4 := ip.To4(); ip4 != nil {
+ return cgoSockaddrInet4(ip4), _C_socklen_t(syscall.SizeofSockaddrInet4)
+ }
+ if ip6 := ip.To16(); ip6 != nil {
+ return cgoSockaddrInet6(ip6, zoneCache.index(zone)), _C_socklen_t(syscall.SizeofSockaddrInet6)
+ }
+ return nil, 0
+}
+
+func cgoLookupCNAME(ctx context.Context, name string) (cname string, err error, completed bool) {
+ resources, err := resSearch(ctx, name, int(dnsmessage.TypeCNAME), int(dnsmessage.ClassINET))
+ if err != nil {
+ return
+ }
+ cname, err = parseCNAMEFromResources(resources)
+ if err != nil {
+ return "", err, false
+ }
+ return cname, nil, true
+}
+
+// resSearch will make a call to the 'res_nsearch' routine in the C library
+// and parse the output as a slice of DNS resources.
+func resSearch(ctx context.Context, hostname string, rtype, class int) ([]dnsmessage.Resource, error) {
+ return doBlockingWithCtx(ctx, func() ([]dnsmessage.Resource, error) {
+ return cgoResSearch(hostname, rtype, class)
+ })
+}
+
+func cgoResSearch(hostname string, rtype, class int) ([]dnsmessage.Resource, error) {
+ acquireThread()
+ defer releaseThread()
+
+ state := (*_C_struct___res_state)(_C_malloc(unsafe.Sizeof(_C_struct___res_state{})))
+ defer _C_free(unsafe.Pointer(state))
+ if err := _C_res_ninit(state); err != nil {
+ return nil, errors.New("res_ninit failure: " + err.Error())
+ }
+ defer _C_res_nclose(state)
+
+ // Some res_nsearch implementations (like macOS) do not set errno.
+ // They set h_errno, which is not per-thread and useless to us.
+ // res_nsearch returns the size of the DNS response packet.
+ // But if the DNS response packet contains failure-like response codes,
+ // res_search returns -1 even though it has copied the packet into buf,
+ // giving us no way to find out how big the packet is.
+ // For now, we are willing to take res_search's word that there's nothing
+ // useful in the response, even though there *is* a response.
+ bufSize := maxDNSPacketSize
+ buf := (*_C_uchar)(_C_malloc(uintptr(bufSize)))
+ defer _C_free(unsafe.Pointer(buf))
+
+ s, err := syscall.BytePtrFromString(hostname)
+ if err != nil {
+ return nil, err
+ }
+
+ var size int
+ for {
+ size, _ = _C_res_nsearch(state, (*_C_char)(unsafe.Pointer(s)), class, rtype, buf, bufSize)
+ if size <= 0 || size > 0xffff {
+ return nil, errors.New("res_nsearch failure")
+ }
+ if size <= bufSize {
+ break
+ }
+
+ // Allocate a bigger buffer to fit the entire msg.
+ _C_free(unsafe.Pointer(buf))
+ bufSize = size
+ buf = (*_C_uchar)(_C_malloc(uintptr(bufSize)))
+ }
+
+ var p dnsmessage.Parser
+ if _, err := p.Start(unsafe.Slice((*byte)(unsafe.Pointer(buf)), size)); err != nil {
+ return nil, err
+ }
+ p.SkipAllQuestions()
+ resources, err := p.AllAnswers()
+ if err != nil {
+ return nil, err
+ }
+ return resources, nil
+}
diff --git a/contrib/go/_std_1.21/src/net/cgo_unix_cgo.go b/contrib/go/_std_1.21/src/net/cgo_unix_cgo.go
new file mode 100644
index 0000000000..d11f3e301a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/cgo_unix_cgo.go
@@ -0,0 +1,80 @@
+// Copyright 2022 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.
+
+//go:build cgo && !netgo && unix && !darwin
+
+package net
+
+/*
+#define _GNU_SOURCE
+
+#cgo CFLAGS: -fno-stack-protector
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifndef EAI_NODATA
+#define EAI_NODATA -5
+#endif
+
+// If nothing else defined EAI_OVERFLOW, make sure it has a value.
+#ifndef EAI_OVERFLOW
+#define EAI_OVERFLOW -12
+#endif
+*/
+import "C"
+import "unsafe"
+
+const (
+ _C_AF_INET = C.AF_INET
+ _C_AF_INET6 = C.AF_INET6
+ _C_AF_UNSPEC = C.AF_UNSPEC
+ _C_EAI_AGAIN = C.EAI_AGAIN
+ _C_EAI_NODATA = C.EAI_NODATA
+ _C_EAI_NONAME = C.EAI_NONAME
+ _C_EAI_OVERFLOW = C.EAI_OVERFLOW
+ _C_EAI_SYSTEM = C.EAI_SYSTEM
+ _C_IPPROTO_TCP = C.IPPROTO_TCP
+ _C_IPPROTO_UDP = C.IPPROTO_UDP
+ _C_SOCK_DGRAM = C.SOCK_DGRAM
+ _C_SOCK_STREAM = C.SOCK_STREAM
+)
+
+type (
+ _C_char = C.char
+ _C_uchar = C.uchar
+ _C_int = C.int
+ _C_uint = C.uint
+ _C_socklen_t = C.socklen_t
+ _C_struct_addrinfo = C.struct_addrinfo
+ _C_struct_sockaddr = C.struct_sockaddr
+)
+
+func _C_GoString(p *_C_char) string { return C.GoString(p) }
+func _C_malloc(n uintptr) unsafe.Pointer { return C.malloc(C.size_t(n)) }
+func _C_free(p unsafe.Pointer) { C.free(p) }
+
+func _C_ai_addr(ai *_C_struct_addrinfo) **_C_struct_sockaddr { return &ai.ai_addr }
+func _C_ai_family(ai *_C_struct_addrinfo) *_C_int { return &ai.ai_family }
+func _C_ai_flags(ai *_C_struct_addrinfo) *_C_int { return &ai.ai_flags }
+func _C_ai_next(ai *_C_struct_addrinfo) **_C_struct_addrinfo { return &ai.ai_next }
+func _C_ai_protocol(ai *_C_struct_addrinfo) *_C_int { return &ai.ai_protocol }
+func _C_ai_socktype(ai *_C_struct_addrinfo) *_C_int { return &ai.ai_socktype }
+
+func _C_freeaddrinfo(ai *_C_struct_addrinfo) {
+ C.freeaddrinfo(ai)
+}
+
+func _C_gai_strerror(eai _C_int) string {
+ return C.GoString(C.gai_strerror(eai))
+}
+
+func _C_getaddrinfo(hostname, servname *_C_char, hints *_C_struct_addrinfo, res **_C_struct_addrinfo) (int, error) {
+ x, err := C.getaddrinfo(hostname, servname, hints, res)
+ return int(x), err
+}
diff --git a/contrib/go/_std_1.21/src/net/cgo_unix_cgo_darwin.go b/contrib/go/_std_1.21/src/net/cgo_unix_cgo_darwin.go
new file mode 100644
index 0000000000..40d5e426f2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/cgo_unix_cgo_darwin.go
@@ -0,0 +1,21 @@
+// Copyright 2023 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.
+
+//go:build !netgo && cgo && darwin
+
+package net
+
+/*
+#include <resolv.h>
+*/
+import "C"
+
+import (
+ "internal/syscall/unix"
+ "unsafe"
+)
+
+// This will cause a compile error when the size of
+// unix.ResState is too small.
+type _ [unsafe.Sizeof(unix.ResState{}) - unsafe.Sizeof(C.struct___res_state{})]byte
diff --git a/contrib/go/_std_1.20/src/net/cgo_unix_cgo_res.go b/contrib/go/_std_1.21/src/net/cgo_unix_cgo_res.go
index 37bbc9a762..37bbc9a762 100644
--- a/contrib/go/_std_1.20/src/net/cgo_unix_cgo_res.go
+++ b/contrib/go/_std_1.21/src/net/cgo_unix_cgo_res.go
diff --git a/contrib/go/_std_1.21/src/net/cgo_unix_syscall.go b/contrib/go/_std_1.21/src/net/cgo_unix_syscall.go
new file mode 100644
index 0000000000..2eb8df1da6
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/cgo_unix_syscall.go
@@ -0,0 +1,102 @@
+// Copyright 2022 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.
+
+//go:build !netgo && darwin
+
+package net
+
+import (
+ "internal/syscall/unix"
+ "runtime"
+ "syscall"
+ "unsafe"
+)
+
+const (
+ _C_AF_INET = syscall.AF_INET
+ _C_AF_INET6 = syscall.AF_INET6
+ _C_AF_UNSPEC = syscall.AF_UNSPEC
+ _C_EAI_AGAIN = unix.EAI_AGAIN
+ _C_EAI_NONAME = unix.EAI_NONAME
+ _C_EAI_NODATA = unix.EAI_NODATA
+ _C_EAI_OVERFLOW = unix.EAI_OVERFLOW
+ _C_EAI_SYSTEM = unix.EAI_SYSTEM
+ _C_IPPROTO_TCP = syscall.IPPROTO_TCP
+ _C_IPPROTO_UDP = syscall.IPPROTO_UDP
+ _C_SOCK_DGRAM = syscall.SOCK_DGRAM
+ _C_SOCK_STREAM = syscall.SOCK_STREAM
+)
+
+type (
+ _C_char = byte
+ _C_int = int32
+ _C_uchar = byte
+ _C_uint = uint32
+ _C_socklen_t = int
+ _C_struct___res_state = unix.ResState
+ _C_struct_addrinfo = unix.Addrinfo
+ _C_struct_sockaddr = syscall.RawSockaddr
+)
+
+func _C_GoString(p *_C_char) string {
+ return unix.GoString(p)
+}
+
+func _C_free(p unsafe.Pointer) { runtime.KeepAlive(p) }
+
+func _C_malloc(n uintptr) unsafe.Pointer {
+ if n <= 0 {
+ n = 1
+ }
+ return unsafe.Pointer(&make([]byte, n)[0])
+}
+
+func _C_ai_addr(ai *_C_struct_addrinfo) **_C_struct_sockaddr { return &ai.Addr }
+func _C_ai_family(ai *_C_struct_addrinfo) *_C_int { return &ai.Family }
+func _C_ai_flags(ai *_C_struct_addrinfo) *_C_int { return &ai.Flags }
+func _C_ai_next(ai *_C_struct_addrinfo) **_C_struct_addrinfo { return &ai.Next }
+func _C_ai_protocol(ai *_C_struct_addrinfo) *_C_int { return &ai.Protocol }
+func _C_ai_socktype(ai *_C_struct_addrinfo) *_C_int { return &ai.Socktype }
+
+func _C_freeaddrinfo(ai *_C_struct_addrinfo) {
+ unix.Freeaddrinfo(ai)
+}
+
+func _C_gai_strerror(eai _C_int) string {
+ return unix.GaiStrerror(int(eai))
+}
+
+func _C_getaddrinfo(hostname, servname *byte, hints *_C_struct_addrinfo, res **_C_struct_addrinfo) (int, error) {
+ return unix.Getaddrinfo(hostname, servname, hints, res)
+}
+
+func _C_res_ninit(state *_C_struct___res_state) error {
+ unix.ResNinit(state)
+ return nil
+}
+
+func _C_res_nsearch(state *_C_struct___res_state, dname *_C_char, class, typ int, ans *_C_char, anslen int) (int, error) {
+ return unix.ResNsearch(state, dname, class, typ, ans, anslen)
+}
+
+func _C_res_nclose(state *_C_struct___res_state) {
+ unix.ResNclose(state)
+}
+
+func cgoNameinfoPTR(b []byte, sa *syscall.RawSockaddr, salen int) (int, error) {
+ gerrno, err := unix.Getnameinfo(sa, salen, &b[0], len(b), nil, 0, unix.NI_NAMEREQD)
+ return int(gerrno), err
+}
+
+func cgoSockaddrInet4(ip IP) *syscall.RawSockaddr {
+ sa := syscall.RawSockaddrInet4{Len: syscall.SizeofSockaddrInet4, Family: syscall.AF_INET}
+ copy(sa.Addr[:], ip)
+ return (*syscall.RawSockaddr)(unsafe.Pointer(&sa))
+}
+
+func cgoSockaddrInet6(ip IP, zone int) *syscall.RawSockaddr {
+ sa := syscall.RawSockaddrInet6{Len: syscall.SizeofSockaddrInet6, Family: syscall.AF_INET6, Scope_id: uint32(zone)}
+ copy(sa.Addr[:], ip)
+ return (*syscall.RawSockaddr)(unsafe.Pointer(&sa))
+}
diff --git a/contrib/go/_std_1.21/src/net/conf.go b/contrib/go/_std_1.21/src/net/conf.go
new file mode 100644
index 0000000000..77cc635592
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/conf.go
@@ -0,0 +1,523 @@
+// Copyright 2015 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.
+
+//go:build !js
+
+package net
+
+import (
+ "errors"
+ "internal/bytealg"
+ "internal/godebug"
+ "io/fs"
+ "os"
+ "runtime"
+ "sync"
+ "syscall"
+)
+
+// The net package's name resolution is rather complicated.
+// There are two main approaches, go and cgo.
+// The cgo resolver uses C functions like getaddrinfo.
+// The go resolver reads system files directly and
+// sends DNS packets directly to servers.
+//
+// The netgo build tag prefers the go resolver.
+// The netcgo build tag prefers the cgo resolver.
+//
+// The netgo build tag also prohibits the use of the cgo tool.
+// However, on Darwin, Plan 9, and Windows the cgo resolver is still available.
+// On those systems the cgo resolver does not require the cgo tool.
+// (The term "cgo resolver" was locked in by GODEBUG settings
+// at a time when the cgo resolver did require the cgo tool.)
+//
+// Adding netdns=go to GODEBUG will prefer the go resolver.
+// Adding netdns=cgo to GODEBUG will prefer the cgo resolver.
+//
+// The Resolver struct has a PreferGo field that user code
+// may set to prefer the go resolver. It is documented as being
+// equivalent to adding netdns=go to GODEBUG.
+//
+// When deciding which resolver to use, we first check the PreferGo field.
+// If that is not set, we check the GODEBUG setting.
+// If that is not set, we check the netgo or netcgo build tag.
+// If none of those are set, we normally prefer the go resolver by default.
+// However, if the cgo resolver is available,
+// there is a complex set of conditions for which we prefer the cgo resolver.
+//
+// Other files define the netGoBuildTag, netCgoBuildTag, and cgoAvailable
+// constants.
+
+// conf is used to determine name resolution configuration.
+type conf struct {
+ netGo bool // prefer go approach, based on build tag and GODEBUG
+ netCgo bool // prefer cgo approach, based on build tag and GODEBUG
+
+ dnsDebugLevel int // from GODEBUG
+
+ preferCgo bool // if no explicit preference, use cgo
+
+ goos string // copy of runtime.GOOS, used for testing
+ mdnsTest mdnsTest // assume /etc/mdns.allow exists, for testing
+}
+
+// mdnsTest is for testing only.
+type mdnsTest int
+
+const (
+ mdnsFromSystem mdnsTest = iota
+ mdnsAssumeExists
+ mdnsAssumeDoesNotExist
+)
+
+var (
+ confOnce sync.Once // guards init of confVal via initConfVal
+ confVal = &conf{goos: runtime.GOOS}
+)
+
+// systemConf returns the machine's network configuration.
+func systemConf() *conf {
+ confOnce.Do(initConfVal)
+ return confVal
+}
+
+// initConfVal initializes confVal based on the environment
+// that will not change during program execution.
+func initConfVal() {
+ dnsMode, debugLevel := goDebugNetDNS()
+ confVal.netGo = netGoBuildTag || dnsMode == "go"
+ confVal.netCgo = netCgoBuildTag || dnsMode == "cgo"
+ confVal.dnsDebugLevel = debugLevel
+
+ if confVal.dnsDebugLevel > 0 {
+ defer func() {
+ if confVal.dnsDebugLevel > 1 {
+ println("go package net: confVal.netCgo =", confVal.netCgo, " netGo =", confVal.netGo)
+ }
+ switch {
+ case confVal.netGo:
+ if netGoBuildTag {
+ println("go package net: built with netgo build tag; using Go's DNS resolver")
+ } else {
+ println("go package net: GODEBUG setting forcing use of Go's resolver")
+ }
+ case !cgoAvailable:
+ println("go package net: cgo resolver not supported; using Go's DNS resolver")
+ case confVal.netCgo || confVal.preferCgo:
+ println("go package net: using cgo DNS resolver")
+ default:
+ println("go package net: dynamic selection of DNS resolver")
+ }
+ }()
+ }
+
+ // The remainder of this function sets preferCgo based on
+ // conditions that will not change during program execution.
+
+ // By default, prefer the go resolver.
+ confVal.preferCgo = false
+
+ // If the cgo resolver is not available, we can't prefer it.
+ if !cgoAvailable {
+ return
+ }
+
+ // Some operating systems always prefer the cgo resolver.
+ if goosPrefersCgo() {
+ confVal.preferCgo = true
+ return
+ }
+
+ // The remaining checks are specific to Unix systems.
+ switch runtime.GOOS {
+ case "plan9", "windows", "js", "wasip1":
+ return
+ }
+
+ // If any environment-specified resolver options are specified,
+ // prefer the cgo resolver.
+ // Note that LOCALDOMAIN can change behavior merely by being
+ // specified with the empty string.
+ _, localDomainDefined := syscall.Getenv("LOCALDOMAIN")
+ if localDomainDefined || os.Getenv("RES_OPTIONS") != "" || os.Getenv("HOSTALIASES") != "" {
+ confVal.preferCgo = true
+ return
+ }
+
+ // OpenBSD apparently lets you override the location of resolv.conf
+ // with ASR_CONFIG. If we notice that, defer to libc.
+ if runtime.GOOS == "openbsd" && os.Getenv("ASR_CONFIG") != "" {
+ confVal.preferCgo = true
+ return
+ }
+}
+
+// goosPreferCgo reports whether the GOOS value passed in prefers
+// the cgo resolver.
+func goosPrefersCgo() bool {
+ switch runtime.GOOS {
+ // Historically on Windows and Plan 9 we prefer the
+ // cgo resolver (which doesn't use the cgo tool) rather than
+ // the go resolver. This is because originally these
+ // systems did not support the go resolver.
+ // Keep it this way for better compatibility.
+ // Perhaps we can revisit this some day.
+ case "windows", "plan9":
+ return true
+
+ // Darwin pops up annoying dialog boxes if programs try to
+ // do their own DNS requests, so prefer cgo.
+ case "darwin", "ios":
+ return true
+
+ // DNS requests don't work on Android, so prefer the cgo resolver.
+ // Issue #10714.
+ case "android":
+ return true
+
+ default:
+ return false
+ }
+}
+
+// mustUseGoResolver reports whether a DNS lookup of any sort is
+// required to use the go resolver. The provided Resolver is optional.
+// This will report true if the cgo resolver is not available.
+func (c *conf) mustUseGoResolver(r *Resolver) bool {
+ return c.netGo || r.preferGo() || !cgoAvailable
+}
+
+// addrLookupOrder determines which strategy to use to resolve addresses.
+// The provided Resolver is optional. nil means to not consider its options.
+// It also returns dnsConfig when it was used to determine the lookup order.
+func (c *conf) addrLookupOrder(r *Resolver, addr string) (ret hostLookupOrder, dnsConf *dnsConfig) {
+ if c.dnsDebugLevel > 1 {
+ defer func() {
+ print("go package net: addrLookupOrder(", addr, ") = ", ret.String(), "\n")
+ }()
+ }
+ return c.lookupOrder(r, "")
+}
+
+// hostLookupOrder determines which strategy to use to resolve hostname.
+// The provided Resolver is optional. nil means to not consider its options.
+// It also returns dnsConfig when it was used to determine the lookup order.
+func (c *conf) hostLookupOrder(r *Resolver, hostname string) (ret hostLookupOrder, dnsConf *dnsConfig) {
+ if c.dnsDebugLevel > 1 {
+ defer func() {
+ print("go package net: hostLookupOrder(", hostname, ") = ", ret.String(), "\n")
+ }()
+ }
+ return c.lookupOrder(r, hostname)
+}
+
+func (c *conf) lookupOrder(r *Resolver, hostname string) (ret hostLookupOrder, dnsConf *dnsConfig) {
+ // fallbackOrder is the order we return if we can't figure it out.
+ var fallbackOrder hostLookupOrder
+
+ var canUseCgo bool
+ if c.mustUseGoResolver(r) {
+ // Go resolver was explicitly requested
+ // or cgo resolver is not available.
+ // Figure out the order below.
+ switch c.goos {
+ case "windows":
+ // TODO(bradfitz): implement files-based
+ // lookup on Windows too? I guess /etc/hosts
+ // kinda exists on Windows. But for now, only
+ // do DNS.
+ fallbackOrder = hostLookupDNS
+ default:
+ fallbackOrder = hostLookupFilesDNS
+ }
+ canUseCgo = false
+ } else if c.netCgo {
+ // Cgo resolver was explicitly requested.
+ return hostLookupCgo, nil
+ } else if c.preferCgo {
+ // Given a choice, we prefer the cgo resolver.
+ return hostLookupCgo, nil
+ } else {
+ // Neither resolver was explicitly requested
+ // and we have no preference.
+
+ if bytealg.IndexByteString(hostname, '\\') != -1 || bytealg.IndexByteString(hostname, '%') != -1 {
+ // Don't deal with special form hostnames
+ // with backslashes or '%'.
+ return hostLookupCgo, nil
+ }
+
+ // If something is unrecognized, use cgo.
+ fallbackOrder = hostLookupCgo
+ canUseCgo = true
+ }
+
+ // On systems that don't use /etc/resolv.conf or /etc/nsswitch.conf, we are done.
+ switch c.goos {
+ case "windows", "plan9", "android", "ios":
+ return fallbackOrder, nil
+ }
+
+ // Try to figure out the order to use for searches.
+ // If we don't recognize something, use fallbackOrder.
+ // That will use cgo unless the Go resolver was explicitly requested.
+ // If we do figure out the order, return something other
+ // than fallbackOrder to use the Go resolver with that order.
+
+ dnsConf = getSystemDNSConfig()
+
+ if canUseCgo && dnsConf.err != nil && !errors.Is(dnsConf.err, fs.ErrNotExist) && !errors.Is(dnsConf.err, fs.ErrPermission) {
+ // We can't read the resolv.conf file, so use cgo if we can.
+ return hostLookupCgo, dnsConf
+ }
+
+ if canUseCgo && dnsConf.unknownOpt {
+ // We didn't recognize something in resolv.conf,
+ // so use cgo if we can.
+ return hostLookupCgo, dnsConf
+ }
+
+ // OpenBSD is unique and doesn't use nsswitch.conf.
+ // It also doesn't support mDNS.
+ if c.goos == "openbsd" {
+ // OpenBSD's resolv.conf manpage says that a
+ // non-existent resolv.conf means "lookup" defaults
+ // to only "files", without DNS lookups.
+ if errors.Is(dnsConf.err, fs.ErrNotExist) {
+ return hostLookupFiles, dnsConf
+ }
+
+ lookup := dnsConf.lookup
+ if len(lookup) == 0 {
+ // https://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/resolv.conf.5
+ // "If the lookup keyword is not used in the
+ // system's resolv.conf file then the assumed
+ // order is 'bind file'"
+ return hostLookupDNSFiles, dnsConf
+ }
+ if len(lookup) < 1 || len(lookup) > 2 {
+ // We don't recognize this format.
+ return fallbackOrder, dnsConf
+ }
+ switch lookup[0] {
+ case "bind":
+ if len(lookup) == 2 {
+ if lookup[1] == "file" {
+ return hostLookupDNSFiles, dnsConf
+ }
+ // Unrecognized.
+ return fallbackOrder, dnsConf
+ }
+ return hostLookupDNS, dnsConf
+ case "file":
+ if len(lookup) == 2 {
+ if lookup[1] == "bind" {
+ return hostLookupFilesDNS, dnsConf
+ }
+ // Unrecognized.
+ return fallbackOrder, dnsConf
+ }
+ return hostLookupFiles, dnsConf
+ default:
+ // Unrecognized.
+ return fallbackOrder, dnsConf
+ }
+
+ // We always return before this point.
+ // The code below is for non-OpenBSD.
+ }
+
+ // Canonicalize the hostname by removing any trailing dot.
+ if stringsHasSuffix(hostname, ".") {
+ hostname = hostname[:len(hostname)-1]
+ }
+ if canUseCgo && stringsHasSuffixFold(hostname, ".local") {
+ // Per RFC 6762, the ".local" TLD is special. And
+ // because Go's native resolver doesn't do mDNS or
+ // similar local resolution mechanisms, assume that
+ // libc might (via Avahi, etc) and use cgo.
+ return hostLookupCgo, dnsConf
+ }
+
+ nss := getSystemNSS()
+ srcs := nss.sources["hosts"]
+ // If /etc/nsswitch.conf doesn't exist or doesn't specify any
+ // sources for "hosts", assume Go's DNS will work fine.
+ if errors.Is(nss.err, fs.ErrNotExist) || (nss.err == nil && len(srcs) == 0) {
+ if canUseCgo && c.goos == "solaris" {
+ // illumos defaults to
+ // "nis [NOTFOUND=return] files",
+ // which the go resolver doesn't support.
+ return hostLookupCgo, dnsConf
+ }
+
+ return hostLookupFilesDNS, dnsConf
+ }
+ if nss.err != nil {
+ // We failed to parse or open nsswitch.conf, so
+ // we have nothing to base an order on.
+ return fallbackOrder, dnsConf
+ }
+
+ var hasDNSSource bool
+ var hasDNSSourceChecked bool
+
+ var filesSource, dnsSource bool
+ var first string
+ for i, src := range srcs {
+ if src.source == "files" || src.source == "dns" {
+ if canUseCgo && !src.standardCriteria() {
+ // non-standard; let libc deal with it.
+ return hostLookupCgo, dnsConf
+ }
+ if src.source == "files" {
+ filesSource = true
+ } else {
+ hasDNSSource = true
+ hasDNSSourceChecked = true
+ dnsSource = true
+ }
+ if first == "" {
+ first = src.source
+ }
+ continue
+ }
+
+ if canUseCgo {
+ switch {
+ case hostname != "" && src.source == "myhostname":
+ // Let the cgo resolver handle myhostname
+ // if we are looking up the local hostname.
+ if isLocalhost(hostname) || isGateway(hostname) || isOutbound(hostname) {
+ return hostLookupCgo, dnsConf
+ }
+ hn, err := getHostname()
+ if err != nil || stringsEqualFold(hostname, hn) {
+ return hostLookupCgo, dnsConf
+ }
+ continue
+ case hostname != "" && stringsHasPrefix(src.source, "mdns"):
+ // e.g. "mdns4", "mdns4_minimal"
+ // We already returned true before if it was *.local.
+ // libc wouldn't have found a hit on this anyway.
+
+ // We don't parse mdns.allow files. They're rare. If one
+ // exists, it might list other TLDs (besides .local) or even
+ // '*', so just let libc deal with it.
+ var haveMDNSAllow bool
+ switch c.mdnsTest {
+ case mdnsFromSystem:
+ _, err := os.Stat("/etc/mdns.allow")
+ if err != nil && !errors.Is(err, fs.ErrNotExist) {
+ // Let libc figure out what is going on.
+ return hostLookupCgo, dnsConf
+ }
+ haveMDNSAllow = err == nil
+ case mdnsAssumeExists:
+ haveMDNSAllow = true
+ case mdnsAssumeDoesNotExist:
+ haveMDNSAllow = false
+ }
+ if haveMDNSAllow {
+ return hostLookupCgo, dnsConf
+ }
+ continue
+ default:
+ // Some source we don't know how to deal with.
+ return hostLookupCgo, dnsConf
+ }
+ }
+
+ if !hasDNSSourceChecked {
+ hasDNSSourceChecked = true
+ for _, v := range srcs[i+1:] {
+ if v.source == "dns" {
+ hasDNSSource = true
+ break
+ }
+ }
+ }
+
+ // If we saw a source we don't recognize, which can only
+ // happen if we can't use the cgo resolver, treat it as DNS,
+ // but only when there is no dns in all other sources.
+ if !hasDNSSource {
+ dnsSource = true
+ if first == "" {
+ first = "dns"
+ }
+ }
+ }
+
+ // Cases where Go can handle it without cgo and C thread overhead,
+ // or where the Go resolver has been forced.
+ switch {
+ case filesSource && dnsSource:
+ if first == "files" {
+ return hostLookupFilesDNS, dnsConf
+ } else {
+ return hostLookupDNSFiles, dnsConf
+ }
+ case filesSource:
+ return hostLookupFiles, dnsConf
+ case dnsSource:
+ return hostLookupDNS, dnsConf
+ }
+
+ // Something weird. Fallback to the default.
+ return fallbackOrder, dnsConf
+}
+
+var netdns = godebug.New("netdns")
+
+// goDebugNetDNS parses the value of the GODEBUG "netdns" value.
+// The netdns value can be of the form:
+//
+// 1 // debug level 1
+// 2 // debug level 2
+// cgo // use cgo for DNS lookups
+// go // use go for DNS lookups
+// cgo+1 // use cgo for DNS lookups + debug level 1
+// 1+cgo // same
+// cgo+2 // same, but debug level 2
+//
+// etc.
+func goDebugNetDNS() (dnsMode string, debugLevel int) {
+ goDebug := netdns.Value()
+ parsePart := func(s string) {
+ if s == "" {
+ return
+ }
+ if '0' <= s[0] && s[0] <= '9' {
+ debugLevel, _, _ = dtoi(s)
+ } else {
+ dnsMode = s
+ }
+ }
+ if i := bytealg.IndexByteString(goDebug, '+'); i != -1 {
+ parsePart(goDebug[:i])
+ parsePart(goDebug[i+1:])
+ return
+ }
+ parsePart(goDebug)
+ return
+}
+
+// isLocalhost reports whether h should be considered a "localhost"
+// name for the myhostname NSS module.
+func isLocalhost(h string) bool {
+ return stringsEqualFold(h, "localhost") || stringsEqualFold(h, "localhost.localdomain") || stringsHasSuffixFold(h, ".localhost") || stringsHasSuffixFold(h, ".localhost.localdomain")
+}
+
+// isGateway reports whether h should be considered a "gateway"
+// name for the myhostname NSS module.
+func isGateway(h string) bool {
+ return stringsEqualFold(h, "_gateway")
+}
+
+// isOutbound reports whether h should be considered a "outbound"
+// name for the myhostname NSS module.
+func isOutbound(h string) bool {
+ return stringsEqualFold(h, "_outbound")
+}
diff --git a/contrib/go/_std_1.21/src/net/dial.go b/contrib/go/_std_1.21/src/net/dial.go
new file mode 100644
index 0000000000..79bc4958bb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/dial.go
@@ -0,0 +1,837 @@
+// Copyright 2010 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 net
+
+import (
+ "context"
+ "internal/godebug"
+ "internal/nettrace"
+ "syscall"
+ "time"
+)
+
+const (
+ // defaultTCPKeepAlive is a default constant value for TCPKeepAlive times
+ // See go.dev/issue/31510
+ defaultTCPKeepAlive = 15 * time.Second
+
+ // For the moment, MultiPath TCP is not used by default
+ // See go.dev/issue/56539
+ defaultMPTCPEnabled = false
+)
+
+var multipathtcp = godebug.New("multipathtcp")
+
+// mptcpStatus is a tristate for Multipath TCP, see go.dev/issue/56539
+type mptcpStatus uint8
+
+const (
+ // The value 0 is the system default, linked to defaultMPTCPEnabled
+ mptcpUseDefault mptcpStatus = iota
+ mptcpEnabled
+ mptcpDisabled
+)
+
+func (m *mptcpStatus) get() bool {
+ switch *m {
+ case mptcpEnabled:
+ return true
+ case mptcpDisabled:
+ return false
+ }
+
+ // If MPTCP is forced via GODEBUG=multipathtcp=1
+ if multipathtcp.Value() == "1" {
+ multipathtcp.IncNonDefault()
+
+ return true
+ }
+
+ return defaultMPTCPEnabled
+}
+
+func (m *mptcpStatus) set(use bool) {
+ if use {
+ *m = mptcpEnabled
+ } else {
+ *m = mptcpDisabled
+ }
+}
+
+// A Dialer contains options for connecting to an address.
+//
+// The zero value for each field is equivalent to dialing
+// without that option. Dialing with the zero value of Dialer
+// is therefore equivalent to just calling the Dial function.
+//
+// It is safe to call Dialer's methods concurrently.
+type Dialer struct {
+ // Timeout is the maximum amount of time a dial will wait for
+ // a connect to complete. If Deadline is also set, it may fail
+ // earlier.
+ //
+ // The default is no timeout.
+ //
+ // When using TCP and dialing a host name with multiple IP
+ // addresses, the timeout may be divided between them.
+ //
+ // With or without a timeout, the operating system may impose
+ // its own earlier timeout. For instance, TCP timeouts are
+ // often around 3 minutes.
+ Timeout time.Duration
+
+ // Deadline is the absolute point in time after which dials
+ // will fail. If Timeout is set, it may fail earlier.
+ // Zero means no deadline, or dependent on the operating system
+ // as with the Timeout option.
+ Deadline time.Time
+
+ // LocalAddr is the local address to use when dialing an
+ // address. The address must be of a compatible type for the
+ // network being dialed.
+ // If nil, a local address is automatically chosen.
+ LocalAddr Addr
+
+ // DualStack previously enabled RFC 6555 Fast Fallback
+ // support, also known as "Happy Eyeballs", in which IPv4 is
+ // tried soon if IPv6 appears to be misconfigured and
+ // hanging.
+ //
+ // Deprecated: Fast Fallback is enabled by default. To
+ // disable, set FallbackDelay to a negative value.
+ DualStack bool
+
+ // FallbackDelay specifies the length of time to wait before
+ // spawning a RFC 6555 Fast Fallback connection. That is, this
+ // is the amount of time to wait for IPv6 to succeed before
+ // assuming that IPv6 is misconfigured and falling back to
+ // IPv4.
+ //
+ // If zero, a default delay of 300ms is used.
+ // A negative value disables Fast Fallback support.
+ FallbackDelay time.Duration
+
+ // KeepAlive specifies the interval between keep-alive
+ // probes for an active network connection.
+ // If zero, keep-alive probes are sent with a default value
+ // (currently 15 seconds), if supported by the protocol and operating
+ // system. Network protocols or operating systems that do
+ // not support keep-alives ignore this field.
+ // If negative, keep-alive probes are disabled.
+ KeepAlive time.Duration
+
+ // Resolver optionally specifies an alternate resolver to use.
+ Resolver *Resolver
+
+ // Cancel is an optional channel whose closure indicates that
+ // the dial should be canceled. Not all types of dials support
+ // cancellation.
+ //
+ // Deprecated: Use DialContext instead.
+ Cancel <-chan struct{}
+
+ // If Control is not nil, it is called after creating the network
+ // connection but before actually dialing.
+ //
+ // Network and address parameters passed to Control function are not
+ // necessarily the ones passed to Dial. For example, passing "tcp" to Dial
+ // will cause the Control function to be called with "tcp4" or "tcp6".
+ //
+ // Control is ignored if ControlContext is not nil.
+ Control func(network, address string, c syscall.RawConn) error
+
+ // If ControlContext is not nil, it is called after creating the network
+ // connection but before actually dialing.
+ //
+ // Network and address parameters passed to ControlContext function are not
+ // necessarily the ones passed to Dial. For example, passing "tcp" to Dial
+ // will cause the ControlContext function to be called with "tcp4" or "tcp6".
+ //
+ // If ControlContext is not nil, Control is ignored.
+ ControlContext func(ctx context.Context, network, address string, c syscall.RawConn) error
+
+ // If mptcpStatus is set to a value allowing Multipath TCP (MPTCP) to be
+ // used, any call to Dial with "tcp(4|6)" as network will use MPTCP if
+ // supported by the operating system.
+ mptcpStatus mptcpStatus
+}
+
+func (d *Dialer) dualStack() bool { return d.FallbackDelay >= 0 }
+
+func minNonzeroTime(a, b time.Time) time.Time {
+ if a.IsZero() {
+ return b
+ }
+ if b.IsZero() || a.Before(b) {
+ return a
+ }
+ return b
+}
+
+// deadline returns the earliest of:
+// - now+Timeout
+// - d.Deadline
+// - the context's deadline
+//
+// Or zero, if none of Timeout, Deadline, or context's deadline is set.
+func (d *Dialer) deadline(ctx context.Context, now time.Time) (earliest time.Time) {
+ if d.Timeout != 0 { // including negative, for historical reasons
+ earliest = now.Add(d.Timeout)
+ }
+ if d, ok := ctx.Deadline(); ok {
+ earliest = minNonzeroTime(earliest, d)
+ }
+ return minNonzeroTime(earliest, d.Deadline)
+}
+
+func (d *Dialer) resolver() *Resolver {
+ if d.Resolver != nil {
+ return d.Resolver
+ }
+ return DefaultResolver
+}
+
+// partialDeadline returns the deadline to use for a single address,
+// when multiple addresses are pending.
+func partialDeadline(now, deadline time.Time, addrsRemaining int) (time.Time, error) {
+ if deadline.IsZero() {
+ return deadline, nil
+ }
+ timeRemaining := deadline.Sub(now)
+ if timeRemaining <= 0 {
+ return time.Time{}, errTimeout
+ }
+ // Tentatively allocate equal time to each remaining address.
+ timeout := timeRemaining / time.Duration(addrsRemaining)
+ // If the time per address is too short, steal from the end of the list.
+ const saneMinimum = 2 * time.Second
+ if timeout < saneMinimum {
+ if timeRemaining < saneMinimum {
+ timeout = timeRemaining
+ } else {
+ timeout = saneMinimum
+ }
+ }
+ return now.Add(timeout), nil
+}
+
+func (d *Dialer) fallbackDelay() time.Duration {
+ if d.FallbackDelay > 0 {
+ return d.FallbackDelay
+ } else {
+ return 300 * time.Millisecond
+ }
+}
+
+func parseNetwork(ctx context.Context, network string, needsProto bool) (afnet string, proto int, err error) {
+ i := last(network, ':')
+ if i < 0 { // no colon
+ switch network {
+ case "tcp", "tcp4", "tcp6":
+ case "udp", "udp4", "udp6":
+ case "ip", "ip4", "ip6":
+ if needsProto {
+ return "", 0, UnknownNetworkError(network)
+ }
+ case "unix", "unixgram", "unixpacket":
+ default:
+ return "", 0, UnknownNetworkError(network)
+ }
+ return network, 0, nil
+ }
+ afnet = network[:i]
+ switch afnet {
+ case "ip", "ip4", "ip6":
+ protostr := network[i+1:]
+ proto, i, ok := dtoi(protostr)
+ if !ok || i != len(protostr) {
+ proto, err = lookupProtocol(ctx, protostr)
+ if err != nil {
+ return "", 0, err
+ }
+ }
+ return afnet, proto, nil
+ }
+ return "", 0, UnknownNetworkError(network)
+}
+
+// resolveAddrList resolves addr using hint and returns a list of
+// addresses. The result contains at least one address when error is
+// nil.
+func (r *Resolver) resolveAddrList(ctx context.Context, op, network, addr string, hint Addr) (addrList, error) {
+ afnet, _, err := parseNetwork(ctx, network, true)
+ if err != nil {
+ return nil, err
+ }
+ if op == "dial" && addr == "" {
+ return nil, errMissingAddress
+ }
+ switch afnet {
+ case "unix", "unixgram", "unixpacket":
+ addr, err := ResolveUnixAddr(afnet, addr)
+ if err != nil {
+ return nil, err
+ }
+ if op == "dial" && hint != nil && addr.Network() != hint.Network() {
+ return nil, &AddrError{Err: "mismatched local address type", Addr: hint.String()}
+ }
+ return addrList{addr}, nil
+ }
+ addrs, err := r.internetAddrList(ctx, afnet, addr)
+ if err != nil || op != "dial" || hint == nil {
+ return addrs, err
+ }
+ var (
+ tcp *TCPAddr
+ udp *UDPAddr
+ ip *IPAddr
+ wildcard bool
+ )
+ switch hint := hint.(type) {
+ case *TCPAddr:
+ tcp = hint
+ wildcard = tcp.isWildcard()
+ case *UDPAddr:
+ udp = hint
+ wildcard = udp.isWildcard()
+ case *IPAddr:
+ ip = hint
+ wildcard = ip.isWildcard()
+ }
+ naddrs := addrs[:0]
+ for _, addr := range addrs {
+ if addr.Network() != hint.Network() {
+ return nil, &AddrError{Err: "mismatched local address type", Addr: hint.String()}
+ }
+ switch addr := addr.(type) {
+ case *TCPAddr:
+ if !wildcard && !addr.isWildcard() && !addr.IP.matchAddrFamily(tcp.IP) {
+ continue
+ }
+ naddrs = append(naddrs, addr)
+ case *UDPAddr:
+ if !wildcard && !addr.isWildcard() && !addr.IP.matchAddrFamily(udp.IP) {
+ continue
+ }
+ naddrs = append(naddrs, addr)
+ case *IPAddr:
+ if !wildcard && !addr.isWildcard() && !addr.IP.matchAddrFamily(ip.IP) {
+ continue
+ }
+ naddrs = append(naddrs, addr)
+ }
+ }
+ if len(naddrs) == 0 {
+ return nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: hint.String()}
+ }
+ return naddrs, nil
+}
+
+// MultipathTCP reports whether MPTCP will be used.
+//
+// This method doesn't check if MPTCP is supported by the operating
+// system or not.
+func (d *Dialer) MultipathTCP() bool {
+ return d.mptcpStatus.get()
+}
+
+// SetMultipathTCP directs the Dial methods to use, or not use, MPTCP,
+// if supported by the operating system. This method overrides the
+// system default and the GODEBUG=multipathtcp=... setting if any.
+//
+// If MPTCP is not available on the host or not supported by the server,
+// the Dial methods will fall back to TCP.
+func (d *Dialer) SetMultipathTCP(use bool) {
+ d.mptcpStatus.set(use)
+}
+
+// Dial connects to the address on the named network.
+//
+// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
+// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
+// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
+// "unixpacket".
+//
+// For TCP and UDP networks, the address has the form "host:port".
+// The host must be a literal IP address, or a host name that can be
+// resolved to IP addresses.
+// The port must be a literal port number or a service name.
+// If the host is a literal IPv6 address it must be enclosed in square
+// brackets, as in "[2001:db8::1]:80" or "[fe80::1%zone]:80".
+// The zone specifies the scope of the literal IPv6 address as defined
+// in RFC 4007.
+// The functions JoinHostPort and SplitHostPort manipulate a pair of
+// host and port in this form.
+// When using TCP, and the host resolves to multiple IP addresses,
+// Dial will try each IP address in order until one succeeds.
+//
+// Examples:
+//
+// Dial("tcp", "golang.org:http")
+// Dial("tcp", "192.0.2.1:http")
+// Dial("tcp", "198.51.100.1:80")
+// Dial("udp", "[2001:db8::1]:domain")
+// Dial("udp", "[fe80::1%lo0]:53")
+// Dial("tcp", ":80")
+//
+// For IP networks, the network must be "ip", "ip4" or "ip6" followed
+// by a colon and a literal protocol number or a protocol name, and
+// the address has the form "host". The host must be a literal IP
+// address or a literal IPv6 address with zone.
+// It depends on each operating system how the operating system
+// behaves with a non-well known protocol number such as "0" or "255".
+//
+// Examples:
+//
+// Dial("ip4:1", "192.0.2.1")
+// Dial("ip6:ipv6-icmp", "2001:db8::1")
+// Dial("ip6:58", "fe80::1%lo0")
+//
+// For TCP, UDP and IP networks, if the host is empty or a literal
+// unspecified IP address, as in ":80", "0.0.0.0:80" or "[::]:80" for
+// TCP and UDP, "", "0.0.0.0" or "::" for IP, the local system is
+// assumed.
+//
+// For Unix networks, the address must be a file system path.
+func Dial(network, address string) (Conn, error) {
+ var d Dialer
+ return d.Dial(network, address)
+}
+
+// DialTimeout acts like Dial but takes a timeout.
+//
+// The timeout includes name resolution, if required.
+// When using TCP, and the host in the address parameter resolves to
+// multiple IP addresses, the timeout is spread over each consecutive
+// dial, such that each is given an appropriate fraction of the time
+// to connect.
+//
+// See func Dial for a description of the network and address
+// parameters.
+func DialTimeout(network, address string, timeout time.Duration) (Conn, error) {
+ d := Dialer{Timeout: timeout}
+ return d.Dial(network, address)
+}
+
+// sysDialer contains a Dial's parameters and configuration.
+type sysDialer struct {
+ Dialer
+ network, address string
+ testHookDialTCP func(ctx context.Context, net string, laddr, raddr *TCPAddr) (*TCPConn, error)
+}
+
+// Dial connects to the address on the named network.
+//
+// See func Dial for a description of the network and address
+// parameters.
+//
+// Dial uses context.Background internally; to specify the context, use
+// DialContext.
+func (d *Dialer) Dial(network, address string) (Conn, error) {
+ return d.DialContext(context.Background(), network, address)
+}
+
+// DialContext connects to the address on the named network using
+// the provided context.
+//
+// The provided Context must be non-nil. If the context expires before
+// the connection is complete, an error is returned. Once successfully
+// connected, any expiration of the context will not affect the
+// connection.
+//
+// When using TCP, and the host in the address parameter resolves to multiple
+// network addresses, any dial timeout (from d.Timeout or ctx) is spread
+// over each consecutive dial, such that each is given an appropriate
+// fraction of the time to connect.
+// For example, if a host has 4 IP addresses and the timeout is 1 minute,
+// the connect to each single address will be given 15 seconds to complete
+// before trying the next one.
+//
+// See func Dial for a description of the network and address
+// parameters.
+func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error) {
+ if ctx == nil {
+ panic("nil context")
+ }
+ deadline := d.deadline(ctx, time.Now())
+ if !deadline.IsZero() {
+ if d, ok := ctx.Deadline(); !ok || deadline.Before(d) {
+ subCtx, cancel := context.WithDeadline(ctx, deadline)
+ defer cancel()
+ ctx = subCtx
+ }
+ }
+ if oldCancel := d.Cancel; oldCancel != nil {
+ subCtx, cancel := context.WithCancel(ctx)
+ defer cancel()
+ go func() {
+ select {
+ case <-oldCancel:
+ cancel()
+ case <-subCtx.Done():
+ }
+ }()
+ ctx = subCtx
+ }
+
+ // Shadow the nettrace (if any) during resolve so Connect events don't fire for DNS lookups.
+ resolveCtx := ctx
+ if trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace); trace != nil {
+ shadow := *trace
+ shadow.ConnectStart = nil
+ shadow.ConnectDone = nil
+ resolveCtx = context.WithValue(resolveCtx, nettrace.TraceKey{}, &shadow)
+ }
+
+ addrs, err := d.resolver().resolveAddrList(resolveCtx, "dial", network, address, d.LocalAddr)
+ if err != nil {
+ return nil, &OpError{Op: "dial", Net: network, Source: nil, Addr: nil, Err: err}
+ }
+
+ sd := &sysDialer{
+ Dialer: *d,
+ network: network,
+ address: address,
+ }
+
+ var primaries, fallbacks addrList
+ if d.dualStack() && network == "tcp" {
+ primaries, fallbacks = addrs.partition(isIPv4)
+ } else {
+ primaries = addrs
+ }
+
+ return sd.dialParallel(ctx, primaries, fallbacks)
+}
+
+// dialParallel races two copies of dialSerial, giving the first a
+// head start. It returns the first established connection and
+// closes the others. Otherwise it returns an error from the first
+// primary address.
+func (sd *sysDialer) dialParallel(ctx context.Context, primaries, fallbacks addrList) (Conn, error) {
+ if len(fallbacks) == 0 {
+ return sd.dialSerial(ctx, primaries)
+ }
+
+ returned := make(chan struct{})
+ defer close(returned)
+
+ type dialResult struct {
+ Conn
+ error
+ primary bool
+ done bool
+ }
+ results := make(chan dialResult) // unbuffered
+
+ startRacer := func(ctx context.Context, primary bool) {
+ ras := primaries
+ if !primary {
+ ras = fallbacks
+ }
+ c, err := sd.dialSerial(ctx, ras)
+ select {
+ case results <- dialResult{Conn: c, error: err, primary: primary, done: true}:
+ case <-returned:
+ if c != nil {
+ c.Close()
+ }
+ }
+ }
+
+ var primary, fallback dialResult
+
+ // Start the main racer.
+ primaryCtx, primaryCancel := context.WithCancel(ctx)
+ defer primaryCancel()
+ go startRacer(primaryCtx, true)
+
+ // Start the timer for the fallback racer.
+ fallbackTimer := time.NewTimer(sd.fallbackDelay())
+ defer fallbackTimer.Stop()
+
+ for {
+ select {
+ case <-fallbackTimer.C:
+ fallbackCtx, fallbackCancel := context.WithCancel(ctx)
+ defer fallbackCancel()
+ go startRacer(fallbackCtx, false)
+
+ case res := <-results:
+ if res.error == nil {
+ return res.Conn, nil
+ }
+ if res.primary {
+ primary = res
+ } else {
+ fallback = res
+ }
+ if primary.done && fallback.done {
+ return nil, primary.error
+ }
+ if res.primary && fallbackTimer.Stop() {
+ // If we were able to stop the timer, that means it
+ // was running (hadn't yet started the fallback), but
+ // we just got an error on the primary path, so start
+ // the fallback immediately (in 0 nanoseconds).
+ fallbackTimer.Reset(0)
+ }
+ }
+ }
+}
+
+// dialSerial connects to a list of addresses in sequence, returning
+// either the first successful connection, or the first error.
+func (sd *sysDialer) dialSerial(ctx context.Context, ras addrList) (Conn, error) {
+ var firstErr error // The error from the first address is most relevant.
+
+ for i, ra := range ras {
+ select {
+ case <-ctx.Done():
+ return nil, &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: mapErr(ctx.Err())}
+ default:
+ }
+
+ dialCtx := ctx
+ if deadline, hasDeadline := ctx.Deadline(); hasDeadline {
+ partialDeadline, err := partialDeadline(time.Now(), deadline, len(ras)-i)
+ if err != nil {
+ // Ran out of time.
+ if firstErr == nil {
+ firstErr = &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: err}
+ }
+ break
+ }
+ if partialDeadline.Before(deadline) {
+ var cancel context.CancelFunc
+ dialCtx, cancel = context.WithDeadline(ctx, partialDeadline)
+ defer cancel()
+ }
+ }
+
+ c, err := sd.dialSingle(dialCtx, ra)
+ if err == nil {
+ return c, nil
+ }
+ if firstErr == nil {
+ firstErr = err
+ }
+ }
+
+ if firstErr == nil {
+ firstErr = &OpError{Op: "dial", Net: sd.network, Source: nil, Addr: nil, Err: errMissingAddress}
+ }
+ return nil, firstErr
+}
+
+// dialSingle attempts to establish and returns a single connection to
+// the destination address.
+func (sd *sysDialer) dialSingle(ctx context.Context, ra Addr) (c Conn, err error) {
+ trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace)
+ if trace != nil {
+ raStr := ra.String()
+ if trace.ConnectStart != nil {
+ trace.ConnectStart(sd.network, raStr)
+ }
+ if trace.ConnectDone != nil {
+ defer func() { trace.ConnectDone(sd.network, raStr, err) }()
+ }
+ }
+ la := sd.LocalAddr
+ switch ra := ra.(type) {
+ case *TCPAddr:
+ la, _ := la.(*TCPAddr)
+ if sd.MultipathTCP() {
+ c, err = sd.dialMPTCP(ctx, la, ra)
+ } else {
+ c, err = sd.dialTCP(ctx, la, ra)
+ }
+ case *UDPAddr:
+ la, _ := la.(*UDPAddr)
+ c, err = sd.dialUDP(ctx, la, ra)
+ case *IPAddr:
+ la, _ := la.(*IPAddr)
+ c, err = sd.dialIP(ctx, la, ra)
+ case *UnixAddr:
+ la, _ := la.(*UnixAddr)
+ c, err = sd.dialUnix(ctx, la, ra)
+ default:
+ return nil, &OpError{Op: "dial", Net: sd.network, Source: la, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: sd.address}}
+ }
+ if err != nil {
+ return nil, &OpError{Op: "dial", Net: sd.network, Source: la, Addr: ra, Err: err} // c is non-nil interface containing nil pointer
+ }
+ return c, nil
+}
+
+// ListenConfig contains options for listening to an address.
+type ListenConfig struct {
+ // If Control is not nil, it is called after creating the network
+ // connection but before binding it to the operating system.
+ //
+ // Network and address parameters passed to Control method are not
+ // necessarily the ones passed to Listen. For example, passing "tcp" to
+ // Listen will cause the Control function to be called with "tcp4" or "tcp6".
+ Control func(network, address string, c syscall.RawConn) error
+
+ // KeepAlive specifies the keep-alive period for network
+ // connections accepted by this listener.
+ // If zero, keep-alives are enabled if supported by the protocol
+ // and operating system. Network protocols or operating systems
+ // that do not support keep-alives ignore this field.
+ // If negative, keep-alives are disabled.
+ KeepAlive time.Duration
+
+ // If mptcpStatus is set to a value allowing Multipath TCP (MPTCP) to be
+ // used, any call to Listen with "tcp(4|6)" as network will use MPTCP if
+ // supported by the operating system.
+ mptcpStatus mptcpStatus
+}
+
+// MultipathTCP reports whether MPTCP will be used.
+//
+// This method doesn't check if MPTCP is supported by the operating
+// system or not.
+func (lc *ListenConfig) MultipathTCP() bool {
+ return lc.mptcpStatus.get()
+}
+
+// SetMultipathTCP directs the Listen method to use, or not use, MPTCP,
+// if supported by the operating system. This method overrides the
+// system default and the GODEBUG=multipathtcp=... setting if any.
+//
+// If MPTCP is not available on the host or not supported by the client,
+// the Listen method will fall back to TCP.
+func (lc *ListenConfig) SetMultipathTCP(use bool) {
+ lc.mptcpStatus.set(use)
+}
+
+// Listen announces on the local network address.
+//
+// See func Listen for a description of the network and address
+// parameters.
+func (lc *ListenConfig) Listen(ctx context.Context, network, address string) (Listener, error) {
+ addrs, err := DefaultResolver.resolveAddrList(ctx, "listen", network, address, nil)
+ if err != nil {
+ return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: err}
+ }
+ sl := &sysListener{
+ ListenConfig: *lc,
+ network: network,
+ address: address,
+ }
+ var l Listener
+ la := addrs.first(isIPv4)
+ switch la := la.(type) {
+ case *TCPAddr:
+ if sl.MultipathTCP() {
+ l, err = sl.listenMPTCP(ctx, la)
+ } else {
+ l, err = sl.listenTCP(ctx, la)
+ }
+ case *UnixAddr:
+ l, err = sl.listenUnix(ctx, la)
+ default:
+ return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: address}}
+ }
+ if err != nil {
+ return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: err} // l is non-nil interface containing nil pointer
+ }
+ return l, nil
+}
+
+// ListenPacket announces on the local network address.
+//
+// See func ListenPacket for a description of the network and address
+// parameters.
+func (lc *ListenConfig) ListenPacket(ctx context.Context, network, address string) (PacketConn, error) {
+ addrs, err := DefaultResolver.resolveAddrList(ctx, "listen", network, address, nil)
+ if err != nil {
+ return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: err}
+ }
+ sl := &sysListener{
+ ListenConfig: *lc,
+ network: network,
+ address: address,
+ }
+ var c PacketConn
+ la := addrs.first(isIPv4)
+ switch la := la.(type) {
+ case *UDPAddr:
+ c, err = sl.listenUDP(ctx, la)
+ case *IPAddr:
+ c, err = sl.listenIP(ctx, la)
+ case *UnixAddr:
+ c, err = sl.listenUnixgram(ctx, la)
+ default:
+ return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: address}}
+ }
+ if err != nil {
+ return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: err} // c is non-nil interface containing nil pointer
+ }
+ return c, nil
+}
+
+// sysListener contains a Listen's parameters and configuration.
+type sysListener struct {
+ ListenConfig
+ network, address string
+}
+
+// Listen announces on the local network address.
+//
+// The network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
+//
+// For TCP networks, if the host in the address parameter is empty or
+// a literal unspecified IP address, Listen listens on all available
+// unicast and anycast IP addresses of the local system.
+// To only use IPv4, use network "tcp4".
+// The address can use a host name, but this is not recommended,
+// because it will create a listener for at most one of the host's IP
+// addresses.
+// If the port in the address parameter is empty or "0", as in
+// "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
+// The Addr method of Listener can be used to discover the chosen
+// port.
+//
+// See func Dial for a description of the network and address
+// parameters.
+//
+// Listen uses context.Background internally; to specify the context, use
+// ListenConfig.Listen.
+func Listen(network, address string) (Listener, error) {
+ var lc ListenConfig
+ return lc.Listen(context.Background(), network, address)
+}
+
+// ListenPacket announces on the local network address.
+//
+// The network must be "udp", "udp4", "udp6", "unixgram", or an IP
+// transport. The IP transports are "ip", "ip4", or "ip6" followed by
+// a colon and a literal protocol number or a protocol name, as in
+// "ip:1" or "ip:icmp".
+//
+// For UDP and IP networks, if the host in the address parameter is
+// empty or a literal unspecified IP address, ListenPacket listens on
+// all available IP addresses of the local system except multicast IP
+// addresses.
+// To only use IPv4, use network "udp4" or "ip4:proto".
+// The address can use a host name, but this is not recommended,
+// because it will create a listener for at most one of the host's IP
+// addresses.
+// If the port in the address parameter is empty or "0", as in
+// "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
+// The LocalAddr method of PacketConn can be used to discover the
+// chosen port.
+//
+// See func Dial for a description of the network and address
+// parameters.
+//
+// ListenPacket uses context.Background internally; to specify the context, use
+// ListenConfig.ListenPacket.
+func ListenPacket(network, address string) (PacketConn, error) {
+ var lc ListenConfig
+ return lc.ListenPacket(context.Background(), network, address)
+}
diff --git a/contrib/go/_std_1.20/src/net/dnsclient.go b/contrib/go/_std_1.21/src/net/dnsclient.go
index b609dbd468..b609dbd468 100644
--- a/contrib/go/_std_1.20/src/net/dnsclient.go
+++ b/contrib/go/_std_1.21/src/net/dnsclient.go
diff --git a/contrib/go/_std_1.21/src/net/dnsclient_unix.go b/contrib/go/_std_1.21/src/net/dnsclient_unix.go
new file mode 100644
index 0000000000..dab5144e5d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/dnsclient_unix.go
@@ -0,0 +1,879 @@
+// Copyright 2009 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.
+
+//go:build !js
+
+// DNS client: see RFC 1035.
+// Has to be linked into package net for Dial.
+
+// TODO(rsc):
+// Could potentially handle many outstanding lookups faster.
+// Random UDP source port (net.Dial should do that for us).
+// Random request IDs.
+
+package net
+
+import (
+ "context"
+ "errors"
+ "internal/itoa"
+ "io"
+ "os"
+ "runtime"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "golang.org/x/net/dns/dnsmessage"
+)
+
+const (
+ // to be used as a useTCP parameter to exchange
+ useTCPOnly = true
+ useUDPOrTCP = false
+
+ // Maximum DNS packet size.
+ // Value taken from https://dnsflagday.net/2020/.
+ maxDNSPacketSize = 1232
+)
+
+var (
+ errLameReferral = errors.New("lame referral")
+ errCannotUnmarshalDNSMessage = errors.New("cannot unmarshal DNS message")
+ errCannotMarshalDNSMessage = errors.New("cannot marshal DNS message")
+ errServerMisbehaving = errors.New("server misbehaving")
+ errInvalidDNSResponse = errors.New("invalid DNS response")
+ errNoAnswerFromDNSServer = errors.New("no answer from DNS server")
+
+ // errServerTemporarilyMisbehaving is like errServerMisbehaving, except
+ // that when it gets translated to a DNSError, the IsTemporary field
+ // gets set to true.
+ errServerTemporarilyMisbehaving = errors.New("server misbehaving")
+)
+
+func newRequest(q dnsmessage.Question, ad bool) (id uint16, udpReq, tcpReq []byte, err error) {
+ id = uint16(randInt())
+ b := dnsmessage.NewBuilder(make([]byte, 2, 514), dnsmessage.Header{ID: id, RecursionDesired: true, AuthenticData: ad})
+ if err := b.StartQuestions(); err != nil {
+ return 0, nil, nil, err
+ }
+ if err := b.Question(q); err != nil {
+ return 0, nil, nil, err
+ }
+
+ // Accept packets up to maxDNSPacketSize. RFC 6891.
+ if err := b.StartAdditionals(); err != nil {
+ return 0, nil, nil, err
+ }
+ var rh dnsmessage.ResourceHeader
+ if err := rh.SetEDNS0(maxDNSPacketSize, dnsmessage.RCodeSuccess, false); err != nil {
+ return 0, nil, nil, err
+ }
+ if err := b.OPTResource(rh, dnsmessage.OPTResource{}); err != nil {
+ return 0, nil, nil, err
+ }
+
+ tcpReq, err = b.Finish()
+ if err != nil {
+ return 0, nil, nil, err
+ }
+ udpReq = tcpReq[2:]
+ l := len(tcpReq) - 2
+ tcpReq[0] = byte(l >> 8)
+ tcpReq[1] = byte(l)
+ return id, udpReq, tcpReq, nil
+}
+
+func checkResponse(reqID uint16, reqQues dnsmessage.Question, respHdr dnsmessage.Header, respQues dnsmessage.Question) bool {
+ if !respHdr.Response {
+ return false
+ }
+ if reqID != respHdr.ID {
+ return false
+ }
+ if reqQues.Type != respQues.Type || reqQues.Class != respQues.Class || !equalASCIIName(reqQues.Name, respQues.Name) {
+ return false
+ }
+ return true
+}
+
+func dnsPacketRoundTrip(c Conn, id uint16, query dnsmessage.Question, b []byte) (dnsmessage.Parser, dnsmessage.Header, error) {
+ if _, err := c.Write(b); err != nil {
+ return dnsmessage.Parser{}, dnsmessage.Header{}, err
+ }
+
+ b = make([]byte, maxDNSPacketSize)
+ for {
+ n, err := c.Read(b)
+ if err != nil {
+ return dnsmessage.Parser{}, dnsmessage.Header{}, err
+ }
+ var p dnsmessage.Parser
+ // Ignore invalid responses as they may be malicious
+ // forgery attempts. Instead continue waiting until
+ // timeout. See golang.org/issue/13281.
+ h, err := p.Start(b[:n])
+ if err != nil {
+ continue
+ }
+ q, err := p.Question()
+ if err != nil || !checkResponse(id, query, h, q) {
+ continue
+ }
+ return p, h, nil
+ }
+}
+
+func dnsStreamRoundTrip(c Conn, id uint16, query dnsmessage.Question, b []byte) (dnsmessage.Parser, dnsmessage.Header, error) {
+ if _, err := c.Write(b); err != nil {
+ return dnsmessage.Parser{}, dnsmessage.Header{}, err
+ }
+
+ b = make([]byte, 1280) // 1280 is a reasonable initial size for IP over Ethernet, see RFC 4035
+ if _, err := io.ReadFull(c, b[:2]); err != nil {
+ return dnsmessage.Parser{}, dnsmessage.Header{}, err
+ }
+ l := int(b[0])<<8 | int(b[1])
+ if l > len(b) {
+ b = make([]byte, l)
+ }
+ n, err := io.ReadFull(c, b[:l])
+ if err != nil {
+ return dnsmessage.Parser{}, dnsmessage.Header{}, err
+ }
+ var p dnsmessage.Parser
+ h, err := p.Start(b[:n])
+ if err != nil {
+ return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotUnmarshalDNSMessage
+ }
+ q, err := p.Question()
+ if err != nil {
+ return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotUnmarshalDNSMessage
+ }
+ if !checkResponse(id, query, h, q) {
+ return dnsmessage.Parser{}, dnsmessage.Header{}, errInvalidDNSResponse
+ }
+ return p, h, nil
+}
+
+// exchange sends a query on the connection and hopes for a response.
+func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Question, timeout time.Duration, useTCP, ad bool) (dnsmessage.Parser, dnsmessage.Header, error) {
+ q.Class = dnsmessage.ClassINET
+ id, udpReq, tcpReq, err := newRequest(q, ad)
+ if err != nil {
+ return dnsmessage.Parser{}, dnsmessage.Header{}, errCannotMarshalDNSMessage
+ }
+ var networks []string
+ if useTCP {
+ networks = []string{"tcp"}
+ } else {
+ networks = []string{"udp", "tcp"}
+ }
+ for _, network := range networks {
+ ctx, cancel := context.WithDeadline(ctx, time.Now().Add(timeout))
+ defer cancel()
+
+ c, err := r.dial(ctx, network, server)
+ if err != nil {
+ return dnsmessage.Parser{}, dnsmessage.Header{}, err
+ }
+ if d, ok := ctx.Deadline(); ok && !d.IsZero() {
+ c.SetDeadline(d)
+ }
+ var p dnsmessage.Parser
+ var h dnsmessage.Header
+ if _, ok := c.(PacketConn); ok {
+ p, h, err = dnsPacketRoundTrip(c, id, q, udpReq)
+ } else {
+ p, h, err = dnsStreamRoundTrip(c, id, q, tcpReq)
+ }
+ c.Close()
+ if err != nil {
+ return dnsmessage.Parser{}, dnsmessage.Header{}, mapErr(err)
+ }
+ if err := p.SkipQuestion(); err != dnsmessage.ErrSectionDone {
+ return dnsmessage.Parser{}, dnsmessage.Header{}, errInvalidDNSResponse
+ }
+ if h.Truncated { // see RFC 5966
+ continue
+ }
+ return p, h, nil
+ }
+ return dnsmessage.Parser{}, dnsmessage.Header{}, errNoAnswerFromDNSServer
+}
+
+// checkHeader performs basic sanity checks on the header.
+func checkHeader(p *dnsmessage.Parser, h dnsmessage.Header) error {
+ if h.RCode == dnsmessage.RCodeNameError {
+ return errNoSuchHost
+ }
+
+ _, err := p.AnswerHeader()
+ if err != nil && err != dnsmessage.ErrSectionDone {
+ return errCannotUnmarshalDNSMessage
+ }
+
+ // libresolv continues to the next server when it receives
+ // an invalid referral response. See golang.org/issue/15434.
+ if h.RCode == dnsmessage.RCodeSuccess && !h.Authoritative && !h.RecursionAvailable && err == dnsmessage.ErrSectionDone {
+ return errLameReferral
+ }
+
+ if h.RCode != dnsmessage.RCodeSuccess && h.RCode != dnsmessage.RCodeNameError {
+ // None of the error codes make sense
+ // for the query we sent. If we didn't get
+ // a name error and we didn't get success,
+ // the server is behaving incorrectly or
+ // having temporary trouble.
+ if h.RCode == dnsmessage.RCodeServerFailure {
+ return errServerTemporarilyMisbehaving
+ }
+ return errServerMisbehaving
+ }
+
+ return nil
+}
+
+func skipToAnswer(p *dnsmessage.Parser, qtype dnsmessage.Type) error {
+ for {
+ h, err := p.AnswerHeader()
+ if err == dnsmessage.ErrSectionDone {
+ return errNoSuchHost
+ }
+ if err != nil {
+ return errCannotUnmarshalDNSMessage
+ }
+ if h.Type == qtype {
+ return nil
+ }
+ if err := p.SkipAnswer(); err != nil {
+ return errCannotUnmarshalDNSMessage
+ }
+ }
+}
+
+// Do a lookup for a single name, which must be rooted
+// (otherwise answer will not find the answers).
+func (r *Resolver) tryOneName(ctx context.Context, cfg *dnsConfig, name string, qtype dnsmessage.Type) (dnsmessage.Parser, string, error) {
+ var lastErr error
+ serverOffset := cfg.serverOffset()
+ sLen := uint32(len(cfg.servers))
+
+ n, err := dnsmessage.NewName(name)
+ if err != nil {
+ return dnsmessage.Parser{}, "", errCannotMarshalDNSMessage
+ }
+ q := dnsmessage.Question{
+ Name: n,
+ Type: qtype,
+ Class: dnsmessage.ClassINET,
+ }
+
+ for i := 0; i < cfg.attempts; i++ {
+ for j := uint32(0); j < sLen; j++ {
+ server := cfg.servers[(serverOffset+j)%sLen]
+
+ p, h, err := r.exchange(ctx, server, q, cfg.timeout, cfg.useTCP, cfg.trustAD)
+ if err != nil {
+ dnsErr := &DNSError{
+ Err: err.Error(),
+ Name: name,
+ Server: server,
+ }
+ if nerr, ok := err.(Error); ok && nerr.Timeout() {
+ dnsErr.IsTimeout = true
+ }
+ // Set IsTemporary for socket-level errors. Note that this flag
+ // may also be used to indicate a SERVFAIL response.
+ if _, ok := err.(*OpError); ok {
+ dnsErr.IsTemporary = true
+ }
+ lastErr = dnsErr
+ continue
+ }
+
+ if err := checkHeader(&p, h); err != nil {
+ dnsErr := &DNSError{
+ Err: err.Error(),
+ Name: name,
+ Server: server,
+ }
+ if err == errServerTemporarilyMisbehaving {
+ dnsErr.IsTemporary = true
+ }
+ if err == errNoSuchHost {
+ // The name does not exist, so trying
+ // another server won't help.
+
+ dnsErr.IsNotFound = true
+ return p, server, dnsErr
+ }
+ lastErr = dnsErr
+ continue
+ }
+
+ err = skipToAnswer(&p, qtype)
+ if err == nil {
+ return p, server, nil
+ }
+ lastErr = &DNSError{
+ Err: err.Error(),
+ Name: name,
+ Server: server,
+ }
+ if err == errNoSuchHost {
+ // The name does not exist, so trying another
+ // server won't help.
+
+ lastErr.(*DNSError).IsNotFound = true
+ return p, server, lastErr
+ }
+ }
+ }
+ return dnsmessage.Parser{}, "", lastErr
+}
+
+// A resolverConfig represents a DNS stub resolver configuration.
+type resolverConfig struct {
+ initOnce sync.Once // guards init of resolverConfig
+
+ // ch is used as a semaphore that only allows one lookup at a
+ // time to recheck resolv.conf.
+ ch chan struct{} // guards lastChecked and modTime
+ lastChecked time.Time // last time resolv.conf was checked
+
+ dnsConfig atomic.Pointer[dnsConfig] // parsed resolv.conf structure used in lookups
+}
+
+var resolvConf resolverConfig
+
+func getSystemDNSConfig() *dnsConfig {
+ resolvConf.tryUpdate("/etc/resolv.conf")
+ return resolvConf.dnsConfig.Load()
+}
+
+// init initializes conf and is only called via conf.initOnce.
+func (conf *resolverConfig) init() {
+ // Set dnsConfig and lastChecked so we don't parse
+ // resolv.conf twice the first time.
+ conf.dnsConfig.Store(dnsReadConfig("/etc/resolv.conf"))
+ conf.lastChecked = time.Now()
+
+ // Prepare ch so that only one update of resolverConfig may
+ // run at once.
+ conf.ch = make(chan struct{}, 1)
+}
+
+// tryUpdate tries to update conf with the named resolv.conf file.
+// The name variable only exists for testing. It is otherwise always
+// "/etc/resolv.conf".
+func (conf *resolverConfig) tryUpdate(name string) {
+ conf.initOnce.Do(conf.init)
+
+ if conf.dnsConfig.Load().noReload {
+ return
+ }
+
+ // Ensure only one update at a time checks resolv.conf.
+ if !conf.tryAcquireSema() {
+ return
+ }
+ defer conf.releaseSema()
+
+ now := time.Now()
+ if conf.lastChecked.After(now.Add(-5 * time.Second)) {
+ return
+ }
+ conf.lastChecked = now
+
+ switch runtime.GOOS {
+ case "windows":
+ // There's no file on disk, so don't bother checking
+ // and failing.
+ //
+ // The Windows implementation of dnsReadConfig (called
+ // below) ignores the name.
+ default:
+ var mtime time.Time
+ if fi, err := os.Stat(name); err == nil {
+ mtime = fi.ModTime()
+ }
+ if mtime.Equal(conf.dnsConfig.Load().mtime) {
+ return
+ }
+ }
+
+ dnsConf := dnsReadConfig(name)
+ conf.dnsConfig.Store(dnsConf)
+}
+
+func (conf *resolverConfig) tryAcquireSema() bool {
+ select {
+ case conf.ch <- struct{}{}:
+ return true
+ default:
+ return false
+ }
+}
+
+func (conf *resolverConfig) releaseSema() {
+ <-conf.ch
+}
+
+func (r *Resolver) lookup(ctx context.Context, name string, qtype dnsmessage.Type, conf *dnsConfig) (dnsmessage.Parser, string, error) {
+ if !isDomainName(name) {
+ // We used to use "invalid domain name" as the error,
+ // but that is a detail of the specific lookup mechanism.
+ // Other lookups might allow broader name syntax
+ // (for example Multicast DNS allows UTF-8; see RFC 6762).
+ // For consistency with libc resolvers, report no such host.
+ return dnsmessage.Parser{}, "", &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
+ }
+
+ if conf == nil {
+ conf = getSystemDNSConfig()
+ }
+
+ var (
+ p dnsmessage.Parser
+ server string
+ err error
+ )
+ for _, fqdn := range conf.nameList(name) {
+ p, server, err = r.tryOneName(ctx, conf, fqdn, qtype)
+ if err == nil {
+ break
+ }
+ if nerr, ok := err.(Error); ok && nerr.Temporary() && r.strictErrors() {
+ // If we hit a temporary error with StrictErrors enabled,
+ // stop immediately instead of trying more names.
+ break
+ }
+ }
+ if err == nil {
+ return p, server, nil
+ }
+ if err, ok := err.(*DNSError); ok {
+ // Show original name passed to lookup, not suffixed one.
+ // In general we might have tried many suffixes; showing
+ // just one is misleading. See also golang.org/issue/6324.
+ err.Name = name
+ }
+ return dnsmessage.Parser{}, "", err
+}
+
+// avoidDNS reports whether this is a hostname for which we should not
+// use DNS. Currently this includes only .onion, per RFC 7686. See
+// golang.org/issue/13705. Does not cover .local names (RFC 6762),
+// see golang.org/issue/16739.
+func avoidDNS(name string) bool {
+ if name == "" {
+ return true
+ }
+ if name[len(name)-1] == '.' {
+ name = name[:len(name)-1]
+ }
+ return stringsHasSuffixFold(name, ".onion")
+}
+
+// nameList returns a list of names for sequential DNS queries.
+func (conf *dnsConfig) nameList(name string) []string {
+ if avoidDNS(name) {
+ return nil
+ }
+
+ // Check name length (see isDomainName).
+ l := len(name)
+ rooted := l > 0 && name[l-1] == '.'
+ if l > 254 || l == 254 && !rooted {
+ return nil
+ }
+
+ // If name is rooted (trailing dot), try only that name.
+ if rooted {
+ return []string{name}
+ }
+
+ hasNdots := count(name, '.') >= conf.ndots
+ name += "."
+ l++
+
+ // Build list of search choices.
+ names := make([]string, 0, 1+len(conf.search))
+ // If name has enough dots, try unsuffixed first.
+ if hasNdots {
+ names = append(names, name)
+ }
+ // Try suffixes that are not too long (see isDomainName).
+ for _, suffix := range conf.search {
+ if l+len(suffix) <= 254 {
+ names = append(names, name+suffix)
+ }
+ }
+ // Try unsuffixed, if not tried first above.
+ if !hasNdots {
+ names = append(names, name)
+ }
+ return names
+}
+
+// hostLookupOrder specifies the order of LookupHost lookup strategies.
+// It is basically a simplified representation of nsswitch.conf.
+// "files" means /etc/hosts.
+type hostLookupOrder int
+
+const (
+ // hostLookupCgo means defer to cgo.
+ hostLookupCgo hostLookupOrder = iota
+ hostLookupFilesDNS // files first
+ hostLookupDNSFiles // dns first
+ hostLookupFiles // only files
+ hostLookupDNS // only DNS
+)
+
+var lookupOrderName = map[hostLookupOrder]string{
+ hostLookupCgo: "cgo",
+ hostLookupFilesDNS: "files,dns",
+ hostLookupDNSFiles: "dns,files",
+ hostLookupFiles: "files",
+ hostLookupDNS: "dns",
+}
+
+func (o hostLookupOrder) String() string {
+ if s, ok := lookupOrderName[o]; ok {
+ return s
+ }
+ return "hostLookupOrder=" + itoa.Itoa(int(o)) + "??"
+}
+
+func (r *Resolver) goLookupHostOrder(ctx context.Context, name string, order hostLookupOrder, conf *dnsConfig) (addrs []string, err error) {
+ if order == hostLookupFilesDNS || order == hostLookupFiles {
+ // Use entries from /etc/hosts if they match.
+ addrs, _ = lookupStaticHost(name)
+ if len(addrs) > 0 {
+ return
+ }
+
+ if order == hostLookupFiles {
+ return nil, &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
+ }
+ }
+ ips, _, err := r.goLookupIPCNAMEOrder(ctx, "ip", name, order, conf)
+ if err != nil {
+ return
+ }
+ addrs = make([]string, 0, len(ips))
+ for _, ip := range ips {
+ addrs = append(addrs, ip.String())
+ }
+ return
+}
+
+// lookup entries from /etc/hosts
+func goLookupIPFiles(name string) (addrs []IPAddr, canonical string) {
+ addr, canonical := lookupStaticHost(name)
+ for _, haddr := range addr {
+ haddr, zone := splitHostZone(haddr)
+ if ip := ParseIP(haddr); ip != nil {
+ addr := IPAddr{IP: ip, Zone: zone}
+ addrs = append(addrs, addr)
+ }
+ }
+ sortByRFC6724(addrs)
+ return addrs, canonical
+}
+
+// goLookupIP is the native Go implementation of LookupIP.
+// The libc versions are in cgo_*.go.
+func (r *Resolver) goLookupIP(ctx context.Context, network, host string) (addrs []IPAddr, err error) {
+ order, conf := systemConf().hostLookupOrder(r, host)
+ addrs, _, err = r.goLookupIPCNAMEOrder(ctx, network, host, order, conf)
+ return
+}
+
+func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name string, order hostLookupOrder, conf *dnsConfig) (addrs []IPAddr, cname dnsmessage.Name, err error) {
+ if order == hostLookupFilesDNS || order == hostLookupFiles {
+ var canonical string
+ addrs, canonical = goLookupIPFiles(name)
+
+ if len(addrs) > 0 {
+ var err error
+ cname, err = dnsmessage.NewName(canonical)
+ if err != nil {
+ return nil, dnsmessage.Name{}, err
+ }
+ return addrs, cname, nil
+ }
+
+ if order == hostLookupFiles {
+ return nil, dnsmessage.Name{}, &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
+ }
+ }
+
+ if !isDomainName(name) {
+ // See comment in func lookup above about use of errNoSuchHost.
+ return nil, dnsmessage.Name{}, &DNSError{Err: errNoSuchHost.Error(), Name: name, IsNotFound: true}
+ }
+ type result struct {
+ p dnsmessage.Parser
+ server string
+ error
+ }
+
+ if conf == nil {
+ conf = getSystemDNSConfig()
+ }
+
+ lane := make(chan result, 1)
+ qtypes := []dnsmessage.Type{dnsmessage.TypeA, dnsmessage.TypeAAAA}
+ if network == "CNAME" {
+ qtypes = append(qtypes, dnsmessage.TypeCNAME)
+ }
+ switch ipVersion(network) {
+ case '4':
+ qtypes = []dnsmessage.Type{dnsmessage.TypeA}
+ case '6':
+ qtypes = []dnsmessage.Type{dnsmessage.TypeAAAA}
+ }
+ var queryFn func(fqdn string, qtype dnsmessage.Type)
+ var responseFn func(fqdn string, qtype dnsmessage.Type) result
+ if conf.singleRequest {
+ queryFn = func(fqdn string, qtype dnsmessage.Type) {}
+ responseFn = func(fqdn string, qtype dnsmessage.Type) result {
+ dnsWaitGroup.Add(1)
+ defer dnsWaitGroup.Done()
+ p, server, err := r.tryOneName(ctx, conf, fqdn, qtype)
+ return result{p, server, err}
+ }
+ } else {
+ queryFn = func(fqdn string, qtype dnsmessage.Type) {
+ dnsWaitGroup.Add(1)
+ go func(qtype dnsmessage.Type) {
+ p, server, err := r.tryOneName(ctx, conf, fqdn, qtype)
+ lane <- result{p, server, err}
+ dnsWaitGroup.Done()
+ }(qtype)
+ }
+ responseFn = func(fqdn string, qtype dnsmessage.Type) result {
+ return <-lane
+ }
+ }
+ var lastErr error
+ for _, fqdn := range conf.nameList(name) {
+ for _, qtype := range qtypes {
+ queryFn(fqdn, qtype)
+ }
+ hitStrictError := false
+ for _, qtype := range qtypes {
+ result := responseFn(fqdn, qtype)
+ if result.error != nil {
+ if nerr, ok := result.error.(Error); ok && nerr.Temporary() && r.strictErrors() {
+ // This error will abort the nameList loop.
+ hitStrictError = true
+ lastErr = result.error
+ } else if lastErr == nil || fqdn == name+"." {
+ // Prefer error for original name.
+ lastErr = result.error
+ }
+ continue
+ }
+
+ // Presotto says it's okay to assume that servers listed in
+ // /etc/resolv.conf are recursive resolvers.
+ //
+ // We asked for recursion, so it should have included all the
+ // answers we need in this one packet.
+ //
+ // Further, RFC 1034 section 4.3.1 says that "the recursive
+ // response to a query will be... The answer to the query,
+ // possibly preface by one or more CNAME RRs that specify
+ // aliases encountered on the way to an answer."
+ //
+ // Therefore, we should be able to assume that we can ignore
+ // CNAMEs and that the A and AAAA records we requested are
+ // for the canonical name.
+
+ loop:
+ for {
+ h, err := result.p.AnswerHeader()
+ if err != nil && err != dnsmessage.ErrSectionDone {
+ lastErr = &DNSError{
+ Err: "cannot marshal DNS message",
+ Name: name,
+ Server: result.server,
+ }
+ }
+ if err != nil {
+ break
+ }
+ switch h.Type {
+ case dnsmessage.TypeA:
+ a, err := result.p.AResource()
+ if err != nil {
+ lastErr = &DNSError{
+ Err: "cannot marshal DNS message",
+ Name: name,
+ Server: result.server,
+ }
+ break loop
+ }
+ addrs = append(addrs, IPAddr{IP: IP(a.A[:])})
+ if cname.Length == 0 && h.Name.Length != 0 {
+ cname = h.Name
+ }
+
+ case dnsmessage.TypeAAAA:
+ aaaa, err := result.p.AAAAResource()
+ if err != nil {
+ lastErr = &DNSError{
+ Err: "cannot marshal DNS message",
+ Name: name,
+ Server: result.server,
+ }
+ break loop
+ }
+ addrs = append(addrs, IPAddr{IP: IP(aaaa.AAAA[:])})
+ if cname.Length == 0 && h.Name.Length != 0 {
+ cname = h.Name
+ }
+
+ case dnsmessage.TypeCNAME:
+ c, err := result.p.CNAMEResource()
+ if err != nil {
+ lastErr = &DNSError{
+ Err: "cannot marshal DNS message",
+ Name: name,
+ Server: result.server,
+ }
+ break loop
+ }
+ if cname.Length == 0 && c.CNAME.Length > 0 {
+ cname = c.CNAME
+ }
+
+ default:
+ if err := result.p.SkipAnswer(); err != nil {
+ lastErr = &DNSError{
+ Err: "cannot marshal DNS message",
+ Name: name,
+ Server: result.server,
+ }
+ break loop
+ }
+ continue
+ }
+ }
+ }
+ if hitStrictError {
+ // If either family hit an error with StrictErrors enabled,
+ // discard all addresses. This ensures that network flakiness
+ // cannot turn a dualstack hostname IPv4/IPv6-only.
+ addrs = nil
+ break
+ }
+ if len(addrs) > 0 || network == "CNAME" && cname.Length > 0 {
+ break
+ }
+ }
+ if lastErr, ok := lastErr.(*DNSError); ok {
+ // Show original name passed to lookup, not suffixed one.
+ // In general we might have tried many suffixes; showing
+ // just one is misleading. See also golang.org/issue/6324.
+ lastErr.Name = name
+ }
+ sortByRFC6724(addrs)
+ if len(addrs) == 0 && !(network == "CNAME" && cname.Length > 0) {
+ if order == hostLookupDNSFiles {
+ var canonical string
+ addrs, canonical = goLookupIPFiles(name)
+ if len(addrs) > 0 {
+ var err error
+ cname, err = dnsmessage.NewName(canonical)
+ if err != nil {
+ return nil, dnsmessage.Name{}, err
+ }
+ return addrs, cname, nil
+ }
+ }
+ if lastErr != nil {
+ return nil, dnsmessage.Name{}, lastErr
+ }
+ }
+ return addrs, cname, nil
+}
+
+// goLookupCNAME is the native Go (non-cgo) implementation of LookupCNAME.
+func (r *Resolver) goLookupCNAME(ctx context.Context, host string, order hostLookupOrder, conf *dnsConfig) (string, error) {
+ _, cname, err := r.goLookupIPCNAMEOrder(ctx, "CNAME", host, order, conf)
+ return cname.String(), err
+}
+
+// goLookupPTR is the native Go implementation of LookupAddr.
+func (r *Resolver) goLookupPTR(ctx context.Context, addr string, order hostLookupOrder, conf *dnsConfig) ([]string, error) {
+ if order == hostLookupFiles || order == hostLookupFilesDNS {
+ names := lookupStaticAddr(addr)
+ if len(names) > 0 {
+ return names, nil
+ }
+
+ if order == hostLookupFiles {
+ return nil, &DNSError{Err: errNoSuchHost.Error(), Name: addr, IsNotFound: true}
+ }
+ }
+
+ arpa, err := reverseaddr(addr)
+ if err != nil {
+ return nil, err
+ }
+ p, server, err := r.lookup(ctx, arpa, dnsmessage.TypePTR, conf)
+ if err != nil {
+ var dnsErr *DNSError
+ if errors.As(err, &dnsErr) && dnsErr.IsNotFound {
+ if order == hostLookupDNSFiles {
+ names := lookupStaticAddr(addr)
+ if len(names) > 0 {
+ return names, nil
+ }
+ }
+ }
+ return nil, err
+ }
+ var ptrs []string
+ for {
+ h, err := p.AnswerHeader()
+ if err == dnsmessage.ErrSectionDone {
+ break
+ }
+ if err != nil {
+ return nil, &DNSError{
+ Err: "cannot marshal DNS message",
+ Name: addr,
+ Server: server,
+ }
+ }
+ if h.Type != dnsmessage.TypePTR {
+ err := p.SkipAnswer()
+ if err != nil {
+ return nil, &DNSError{
+ Err: "cannot marshal DNS message",
+ Name: addr,
+ Server: server,
+ }
+ }
+ continue
+ }
+ ptr, err := p.PTRResource()
+ if err != nil {
+ return nil, &DNSError{
+ Err: "cannot marshal DNS message",
+ Name: addr,
+ Server: server,
+ }
+ }
+ ptrs = append(ptrs, ptr.PTR.String())
+
+ }
+
+ return ptrs, nil
+}
diff --git a/contrib/go/_std_1.20/src/net/dnsconfig.go b/contrib/go/_std_1.21/src/net/dnsconfig.go
index c86a70be5a..c86a70be5a 100644
--- a/contrib/go/_std_1.20/src/net/dnsconfig.go
+++ b/contrib/go/_std_1.21/src/net/dnsconfig.go
diff --git a/contrib/go/_std_1.21/src/net/dnsconfig_unix.go b/contrib/go/_std_1.21/src/net/dnsconfig_unix.go
new file mode 100644
index 0000000000..69b300410a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/dnsconfig_unix.go
@@ -0,0 +1,167 @@
+// Copyright 2009 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.
+
+//go:build !js && !windows
+
+// Read system DNS config from /etc/resolv.conf
+
+package net
+
+import (
+ "internal/bytealg"
+ "net/netip"
+ "time"
+)
+
+// See resolv.conf(5) on a Linux machine.
+func dnsReadConfig(filename string) *dnsConfig {
+ conf := &dnsConfig{
+ ndots: 1,
+ timeout: 5 * time.Second,
+ attempts: 2,
+ }
+ file, err := open(filename)
+ if err != nil {
+ conf.servers = defaultNS
+ conf.search = dnsDefaultSearch()
+ conf.err = err
+ return conf
+ }
+ defer file.close()
+ if fi, err := file.file.Stat(); err == nil {
+ conf.mtime = fi.ModTime()
+ } else {
+ conf.servers = defaultNS
+ conf.search = dnsDefaultSearch()
+ conf.err = err
+ return conf
+ }
+ for line, ok := file.readLine(); ok; line, ok = file.readLine() {
+ if len(line) > 0 && (line[0] == ';' || line[0] == '#') {
+ // comment.
+ continue
+ }
+ f := getFields(line)
+ if len(f) < 1 {
+ continue
+ }
+ switch f[0] {
+ case "nameserver": // add one name server
+ if len(f) > 1 && len(conf.servers) < 3 { // small, but the standard limit
+ // One more check: make sure server name is
+ // just an IP address. Otherwise we need DNS
+ // to look it up.
+ if _, err := netip.ParseAddr(f[1]); err == nil {
+ conf.servers = append(conf.servers, JoinHostPort(f[1], "53"))
+ }
+ }
+
+ case "domain": // set search path to just this domain
+ if len(f) > 1 {
+ conf.search = []string{ensureRooted(f[1])}
+ }
+
+ case "search": // set search path to given servers
+ conf.search = make([]string, 0, len(f)-1)
+ for i := 1; i < len(f); i++ {
+ name := ensureRooted(f[i])
+ if name == "." {
+ continue
+ }
+ conf.search = append(conf.search, name)
+ }
+
+ case "options": // magic options
+ for _, s := range f[1:] {
+ switch {
+ case hasPrefix(s, "ndots:"):
+ n, _, _ := dtoi(s[6:])
+ if n < 0 {
+ n = 0
+ } else if n > 15 {
+ n = 15
+ }
+ conf.ndots = n
+ case hasPrefix(s, "timeout:"):
+ n, _, _ := dtoi(s[8:])
+ if n < 1 {
+ n = 1
+ }
+ conf.timeout = time.Duration(n) * time.Second
+ case hasPrefix(s, "attempts:"):
+ n, _, _ := dtoi(s[9:])
+ if n < 1 {
+ n = 1
+ }
+ conf.attempts = n
+ case s == "rotate":
+ conf.rotate = true
+ case s == "single-request" || s == "single-request-reopen":
+ // Linux option:
+ // http://man7.org/linux/man-pages/man5/resolv.conf.5.html
+ // "By default, glibc performs IPv4 and IPv6 lookups in parallel [...]
+ // This option disables the behavior and makes glibc
+ // perform the IPv6 and IPv4 requests sequentially."
+ conf.singleRequest = true
+ case s == "use-vc" || s == "usevc" || s == "tcp":
+ // Linux (use-vc), FreeBSD (usevc) and OpenBSD (tcp) option:
+ // http://man7.org/linux/man-pages/man5/resolv.conf.5.html
+ // "Sets RES_USEVC in _res.options.
+ // This option forces the use of TCP for DNS resolutions."
+ // https://www.freebsd.org/cgi/man.cgi?query=resolv.conf&sektion=5&manpath=freebsd-release-ports
+ // https://man.openbsd.org/resolv.conf.5
+ conf.useTCP = true
+ case s == "trust-ad":
+ conf.trustAD = true
+ case s == "edns0":
+ // We use EDNS by default.
+ // Ignore this option.
+ case s == "no-reload":
+ conf.noReload = true
+ default:
+ conf.unknownOpt = true
+ }
+ }
+
+ case "lookup":
+ // OpenBSD option:
+ // https://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man5/resolv.conf.5
+ // "the legal space-separated values are: bind, file, yp"
+ conf.lookup = f[1:]
+
+ default:
+ conf.unknownOpt = true
+ }
+ }
+ if len(conf.servers) == 0 {
+ conf.servers = defaultNS
+ }
+ if len(conf.search) == 0 {
+ conf.search = dnsDefaultSearch()
+ }
+ return conf
+}
+
+func dnsDefaultSearch() []string {
+ hn, err := getHostname()
+ if err != nil {
+ // best effort
+ return nil
+ }
+ if i := bytealg.IndexByteString(hn, '.'); i >= 0 && i < len(hn)-1 {
+ return []string{ensureRooted(hn[i+1:])}
+ }
+ return nil
+}
+
+func hasPrefix(s, prefix string) bool {
+ return len(s) >= len(prefix) && s[:len(prefix)] == prefix
+}
+
+func ensureRooted(s string) string {
+ if len(s) > 0 && s[len(s)-1] == '.' {
+ return s
+ }
+ return s + "."
+}
diff --git a/contrib/go/_std_1.21/src/net/dnsconfig_windows.go b/contrib/go/_std_1.21/src/net/dnsconfig_windows.go
new file mode 100644
index 0000000000..f3d242366a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/dnsconfig_windows.go
@@ -0,0 +1,63 @@
+// Copyright 2022 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 net
+
+import (
+ "internal/syscall/windows"
+ "syscall"
+ "time"
+)
+
+func dnsReadConfig(ignoredFilename string) (conf *dnsConfig) {
+ conf = &dnsConfig{
+ ndots: 1,
+ timeout: 5 * time.Second,
+ attempts: 2,
+ }
+ defer func() {
+ if len(conf.servers) == 0 {
+ conf.servers = defaultNS
+ }
+ }()
+ aas, err := adapterAddresses()
+ if err != nil {
+ return
+ }
+ // TODO(bradfitz): this just collects all the DNS servers on all
+ // the interfaces in some random order. It should order it by
+ // default route, or only use the default route(s) instead.
+ // In practice, however, it mostly works.
+ for _, aa := range aas {
+ for dns := aa.FirstDnsServerAddress; dns != nil; dns = dns.Next {
+ // Only take interfaces whose OperStatus is IfOperStatusUp(0x01) into DNS configs.
+ if aa.OperStatus != windows.IfOperStatusUp {
+ continue
+ }
+ sa, err := dns.Address.Sockaddr.Sockaddr()
+ if err != nil {
+ continue
+ }
+ var ip IP
+ switch sa := sa.(type) {
+ case *syscall.SockaddrInet4:
+ ip = IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
+ case *syscall.SockaddrInet6:
+ ip = make(IP, IPv6len)
+ copy(ip, sa.Addr[:])
+ if ip[0] == 0xfe && ip[1] == 0xc0 {
+ // Ignore these fec0/10 ones. Windows seems to
+ // populate them as defaults on its misc rando
+ // interfaces.
+ continue
+ }
+ default:
+ // Unexpected type.
+ continue
+ }
+ conf.servers = append(conf.servers, JoinHostPort(ip.String(), "53"))
+ }
+ }
+ return conf
+}
diff --git a/contrib/go/_std_1.21/src/net/error_posix.go b/contrib/go/_std_1.21/src/net/error_posix.go
new file mode 100644
index 0000000000..c8dc069db4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/error_posix.go
@@ -0,0 +1,21 @@
+// Copyright 2017 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package net
+
+import (
+ "os"
+ "syscall"
+)
+
+// wrapSyscallError takes an error and a syscall name. If the error is
+// a syscall.Errno, it wraps it in an os.SyscallError using the syscall name.
+func wrapSyscallError(name string, err error) error {
+ if _, ok := err.(syscall.Errno); ok {
+ err = os.NewSyscallError(name, err)
+ }
+ return err
+}
diff --git a/contrib/go/_std_1.21/src/net/error_unix.go b/contrib/go/_std_1.21/src/net/error_unix.go
new file mode 100644
index 0000000000..d6948670b6
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/error_unix.go
@@ -0,0 +1,16 @@
+// Copyright 2018 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.
+
+//go:build unix || js || wasip1
+
+package net
+
+import "syscall"
+
+func isConnError(err error) bool {
+ if se, ok := err.(syscall.Errno); ok {
+ return se == syscall.ECONNRESET || se == syscall.ECONNABORTED
+ }
+ return false
+}
diff --git a/contrib/go/_std_1.20/src/net/error_windows.go b/contrib/go/_std_1.21/src/net/error_windows.go
index 570b97b278..570b97b278 100644
--- a/contrib/go/_std_1.20/src/net/error_windows.go
+++ b/contrib/go/_std_1.21/src/net/error_windows.go
diff --git a/contrib/go/_std_1.20/src/net/fd_posix.go b/contrib/go/_std_1.21/src/net/fd_posix.go
index ffb9bcf8b9..ffb9bcf8b9 100644
--- a/contrib/go/_std_1.20/src/net/fd_posix.go
+++ b/contrib/go/_std_1.21/src/net/fd_posix.go
diff --git a/contrib/go/_std_1.21/src/net/fd_unix.go b/contrib/go/_std_1.21/src/net/fd_unix.go
new file mode 100644
index 0000000000..a8d3a253a9
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/fd_unix.go
@@ -0,0 +1,206 @@
+// Copyright 2009 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.
+
+//go:build unix
+
+package net
+
+import (
+ "context"
+ "internal/poll"
+ "os"
+ "runtime"
+ "syscall"
+)
+
+const (
+ readSyscallName = "read"
+ readFromSyscallName = "recvfrom"
+ readMsgSyscallName = "recvmsg"
+ writeSyscallName = "write"
+ writeToSyscallName = "sendto"
+ writeMsgSyscallName = "sendmsg"
+)
+
+func newFD(sysfd, family, sotype int, net string) (*netFD, error) {
+ ret := &netFD{
+ pfd: poll.FD{
+ Sysfd: sysfd,
+ IsStream: sotype == syscall.SOCK_STREAM,
+ ZeroReadIsEOF: sotype != syscall.SOCK_DGRAM && sotype != syscall.SOCK_RAW,
+ },
+ family: family,
+ sotype: sotype,
+ net: net,
+ }
+ return ret, nil
+}
+
+func (fd *netFD) init() error {
+ return fd.pfd.Init(fd.net, true)
+}
+
+func (fd *netFD) name() string {
+ var ls, rs string
+ if fd.laddr != nil {
+ ls = fd.laddr.String()
+ }
+ if fd.raddr != nil {
+ rs = fd.raddr.String()
+ }
+ return fd.net + ":" + ls + "->" + rs
+}
+
+func (fd *netFD) connect(ctx context.Context, la, ra syscall.Sockaddr) (rsa syscall.Sockaddr, ret error) {
+ // Do not need to call fd.writeLock here,
+ // because fd is not yet accessible to user,
+ // so no concurrent operations are possible.
+ switch err := connectFunc(fd.pfd.Sysfd, ra); err {
+ case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
+ case nil, syscall.EISCONN:
+ select {
+ case <-ctx.Done():
+ return nil, mapErr(ctx.Err())
+ default:
+ }
+ if err := fd.pfd.Init(fd.net, true); err != nil {
+ return nil, err
+ }
+ runtime.KeepAlive(fd)
+ return nil, nil
+ case syscall.EINVAL:
+ // On Solaris and illumos we can see EINVAL if the socket has
+ // already been accepted and closed by the server. Treat this
+ // as a successful connection--writes to the socket will see
+ // EOF. For details and a test case in C see
+ // https://golang.org/issue/6828.
+ if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" {
+ return nil, nil
+ }
+ fallthrough
+ default:
+ return nil, os.NewSyscallError("connect", err)
+ }
+ if err := fd.pfd.Init(fd.net, true); err != nil {
+ return nil, err
+ }
+ if deadline, hasDeadline := ctx.Deadline(); hasDeadline {
+ fd.pfd.SetWriteDeadline(deadline)
+ defer fd.pfd.SetWriteDeadline(noDeadline)
+ }
+
+ // Start the "interrupter" goroutine, if this context might be canceled.
+ //
+ // The interrupter goroutine waits for the context to be done and
+ // interrupts the dial (by altering the fd's write deadline, which
+ // wakes up waitWrite).
+ ctxDone := ctx.Done()
+ if ctxDone != nil {
+ // Wait for the interrupter goroutine to exit before returning
+ // from connect.
+ done := make(chan struct{})
+ interruptRes := make(chan error)
+ defer func() {
+ close(done)
+ if ctxErr := <-interruptRes; ctxErr != nil && ret == nil {
+ // The interrupter goroutine called SetWriteDeadline,
+ // but the connect code below had returned from
+ // waitWrite already and did a successful connect (ret
+ // == nil). Because we've now poisoned the connection
+ // by making it unwritable, don't return a successful
+ // dial. This was issue 16523.
+ ret = mapErr(ctxErr)
+ fd.Close() // prevent a leak
+ }
+ }()
+ go func() {
+ select {
+ case <-ctxDone:
+ // Force the runtime's poller to immediately give up
+ // waiting for writability, unblocking waitWrite
+ // below.
+ fd.pfd.SetWriteDeadline(aLongTimeAgo)
+ testHookCanceledDial()
+ interruptRes <- ctx.Err()
+ case <-done:
+ interruptRes <- nil
+ }
+ }()
+ }
+
+ for {
+ // Performing multiple connect system calls on a
+ // non-blocking socket under Unix variants does not
+ // necessarily result in earlier errors being
+ // returned. Instead, once runtime-integrated network
+ // poller tells us that the socket is ready, get the
+ // SO_ERROR socket option to see if the connection
+ // succeeded or failed. See issue 7474 for further
+ // details.
+ if err := fd.pfd.WaitWrite(); err != nil {
+ select {
+ case <-ctxDone:
+ return nil, mapErr(ctx.Err())
+ default:
+ }
+ return nil, err
+ }
+ nerr, err := getsockoptIntFunc(fd.pfd.Sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
+ if err != nil {
+ return nil, os.NewSyscallError("getsockopt", err)
+ }
+ switch err := syscall.Errno(nerr); err {
+ case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
+ case syscall.EISCONN:
+ return nil, nil
+ case syscall.Errno(0):
+ // The runtime poller can wake us up spuriously;
+ // see issues 14548 and 19289. Check that we are
+ // really connected; if not, wait again.
+ if rsa, err := syscall.Getpeername(fd.pfd.Sysfd); err == nil {
+ return rsa, nil
+ }
+ default:
+ return nil, os.NewSyscallError("connect", err)
+ }
+ runtime.KeepAlive(fd)
+ }
+}
+
+func (fd *netFD) accept() (netfd *netFD, err error) {
+ d, rsa, errcall, err := fd.pfd.Accept()
+ if err != nil {
+ if errcall != "" {
+ err = wrapSyscallError(errcall, err)
+ }
+ return nil, err
+ }
+
+ if netfd, err = newFD(d, fd.family, fd.sotype, fd.net); err != nil {
+ poll.CloseFunc(d)
+ return nil, err
+ }
+ if err = netfd.init(); err != nil {
+ netfd.Close()
+ return nil, err
+ }
+ lsa, _ := syscall.Getsockname(netfd.pfd.Sysfd)
+ netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa))
+ return netfd, nil
+}
+
+// Defined in os package.
+func newUnixFile(fd int, name string) *os.File
+
+func (fd *netFD) dup() (f *os.File, err error) {
+ ns, call, err := fd.pfd.Dup()
+ if err != nil {
+ if call != "" {
+ err = os.NewSyscallError(call, err)
+ }
+ return nil, err
+ }
+
+ return newUnixFile(ns, fd.name()), nil
+}
diff --git a/contrib/go/_std_1.21/src/net/fd_windows.go b/contrib/go/_std_1.21/src/net/fd_windows.go
new file mode 100644
index 0000000000..eeb994dfd9
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/fd_windows.go
@@ -0,0 +1,205 @@
+// Copyright 2010 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 net
+
+import (
+ "context"
+ "internal/poll"
+ "internal/syscall/windows"
+ "os"
+ "runtime"
+ "syscall"
+ "unsafe"
+)
+
+const (
+ readSyscallName = "wsarecv"
+ readFromSyscallName = "wsarecvfrom"
+ readMsgSyscallName = "wsarecvmsg"
+ writeSyscallName = "wsasend"
+ writeToSyscallName = "wsasendto"
+ writeMsgSyscallName = "wsasendmsg"
+)
+
+// canUseConnectEx reports whether we can use the ConnectEx Windows API call
+// for the given network type.
+func canUseConnectEx(net string) bool {
+ switch net {
+ case "tcp", "tcp4", "tcp6":
+ return true
+ }
+ // ConnectEx windows API does not support connectionless sockets.
+ return false
+}
+
+func newFD(sysfd syscall.Handle, family, sotype int, net string) (*netFD, error) {
+ ret := &netFD{
+ pfd: poll.FD{
+ Sysfd: sysfd,
+ IsStream: sotype == syscall.SOCK_STREAM,
+ ZeroReadIsEOF: sotype != syscall.SOCK_DGRAM && sotype != syscall.SOCK_RAW,
+ },
+ family: family,
+ sotype: sotype,
+ net: net,
+ }
+ return ret, nil
+}
+
+func (fd *netFD) init() error {
+ errcall, err := fd.pfd.Init(fd.net, true)
+ if errcall != "" {
+ err = wrapSyscallError(errcall, err)
+ }
+ return err
+}
+
+// Always returns nil for connected peer address result.
+func (fd *netFD) connect(ctx context.Context, la, ra syscall.Sockaddr) (syscall.Sockaddr, error) {
+ // Do not need to call fd.writeLock here,
+ // because fd is not yet accessible to user,
+ // so no concurrent operations are possible.
+ if err := fd.init(); err != nil {
+ return nil, err
+ }
+ if deadline, ok := ctx.Deadline(); ok && !deadline.IsZero() {
+ fd.pfd.SetWriteDeadline(deadline)
+ defer fd.pfd.SetWriteDeadline(noDeadline)
+ }
+ if !canUseConnectEx(fd.net) {
+ err := connectFunc(fd.pfd.Sysfd, ra)
+ return nil, os.NewSyscallError("connect", err)
+ }
+ // ConnectEx windows API requires an unconnected, previously bound socket.
+ if la == nil {
+ switch ra.(type) {
+ case *syscall.SockaddrInet4:
+ la = &syscall.SockaddrInet4{}
+ case *syscall.SockaddrInet6:
+ la = &syscall.SockaddrInet6{}
+ default:
+ panic("unexpected type in connect")
+ }
+ if err := syscall.Bind(fd.pfd.Sysfd, la); err != nil {
+ return nil, os.NewSyscallError("bind", err)
+ }
+ }
+
+ var isloopback bool
+ switch ra := ra.(type) {
+ case *syscall.SockaddrInet4:
+ isloopback = ra.Addr[0] == 127
+ case *syscall.SockaddrInet6:
+ isloopback = ra.Addr == [16]byte(IPv6loopback)
+ default:
+ panic("unexpected type in connect")
+ }
+ if isloopback {
+ // This makes ConnectEx() fails faster if the target port on the localhost
+ // is not reachable, instead of waiting for 2s.
+ params := windows.TCP_INITIAL_RTO_PARAMETERS{
+ Rtt: windows.TCP_INITIAL_RTO_UNSPECIFIED_RTT, // use the default or overridden by the Administrator
+ MaxSynRetransmissions: 1, // minimum possible value before Windows 10.0.16299
+ }
+ if windows.Support_TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS() {
+ // In Windows 10.0.16299 TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS makes ConnectEx() fails instantly.
+ params.MaxSynRetransmissions = windows.TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS
+ }
+ var out uint32
+ // Don't abort the connection if WSAIoctl fails, as it is only an optimization.
+ // If it fails reliably, we expect TestDialClosedPortFailFast to detect it.
+ _ = fd.pfd.WSAIoctl(windows.SIO_TCP_INITIAL_RTO, (*byte)(unsafe.Pointer(&params)), uint32(unsafe.Sizeof(params)), nil, 0, &out, nil, 0)
+ }
+
+ // Wait for the goroutine converting context.Done into a write timeout
+ // to exist, otherwise our caller might cancel the context and
+ // cause fd.setWriteDeadline(aLongTimeAgo) to cancel a successful dial.
+ done := make(chan bool) // must be unbuffered
+ defer func() { done <- true }()
+ go func() {
+ select {
+ case <-ctx.Done():
+ // Force the runtime's poller to immediately give
+ // up waiting for writability.
+ fd.pfd.SetWriteDeadline(aLongTimeAgo)
+ <-done
+ case <-done:
+ }
+ }()
+
+ // Call ConnectEx API.
+ if err := fd.pfd.ConnectEx(ra); err != nil {
+ select {
+ case <-ctx.Done():
+ return nil, mapErr(ctx.Err())
+ default:
+ if _, ok := err.(syscall.Errno); ok {
+ err = os.NewSyscallError("connectex", err)
+ }
+ return nil, err
+ }
+ }
+ // Refresh socket properties.
+ return nil, os.NewSyscallError("setsockopt", syscall.Setsockopt(fd.pfd.Sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.pfd.Sysfd)), int32(unsafe.Sizeof(fd.pfd.Sysfd))))
+}
+
+func (c *conn) writeBuffers(v *Buffers) (int64, error) {
+ if !c.ok() {
+ return 0, syscall.EINVAL
+ }
+ n, err := c.fd.writeBuffers(v)
+ if err != nil {
+ return n, &OpError{Op: "wsasend", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return n, nil
+}
+
+func (fd *netFD) writeBuffers(buf *Buffers) (int64, error) {
+ n, err := fd.pfd.Writev((*[][]byte)(buf))
+ runtime.KeepAlive(fd)
+ return n, wrapSyscallError("wsasend", err)
+}
+
+func (fd *netFD) accept() (*netFD, error) {
+ s, rawsa, rsan, errcall, err := fd.pfd.Accept(func() (syscall.Handle, error) {
+ return sysSocket(fd.family, fd.sotype, 0)
+ })
+
+ if err != nil {
+ if errcall != "" {
+ err = wrapSyscallError(errcall, err)
+ }
+ return nil, err
+ }
+
+ // Associate our new socket with IOCP.
+ netfd, err := newFD(s, fd.family, fd.sotype, fd.net)
+ if err != nil {
+ poll.CloseFunc(s)
+ return nil, err
+ }
+ if err := netfd.init(); err != nil {
+ fd.Close()
+ return nil, err
+ }
+
+ // Get local and peer addr out of AcceptEx buffer.
+ var lrsa, rrsa *syscall.RawSockaddrAny
+ var llen, rlen int32
+ syscall.GetAcceptExSockaddrs((*byte)(unsafe.Pointer(&rawsa[0])),
+ 0, rsan, rsan, &lrsa, &llen, &rrsa, &rlen)
+ lsa, _ := lrsa.Sockaddr()
+ rsa, _ := rrsa.Sockaddr()
+
+ netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa))
+ return netfd, nil
+}
+
+// Unimplemented functions.
+
+func (fd *netFD) dup() (*os.File, error) {
+ // TODO: Implement this
+ return nil, syscall.EWINDOWS
+}
diff --git a/contrib/go/_std_1.20/src/net/file.go b/contrib/go/_std_1.21/src/net/file.go
index c13332c188..c13332c188 100644
--- a/contrib/go/_std_1.20/src/net/file.go
+++ b/contrib/go/_std_1.21/src/net/file.go
diff --git a/contrib/go/_std_1.20/src/net/file_unix.go b/contrib/go/_std_1.21/src/net/file_unix.go
index 8b9fc38916..8b9fc38916 100644
--- a/contrib/go/_std_1.20/src/net/file_unix.go
+++ b/contrib/go/_std_1.21/src/net/file_unix.go
diff --git a/contrib/go/_std_1.20/src/net/file_windows.go b/contrib/go/_std_1.21/src/net/file_windows.go
index 241fa17617..241fa17617 100644
--- a/contrib/go/_std_1.20/src/net/file_windows.go
+++ b/contrib/go/_std_1.21/src/net/file_windows.go
diff --git a/contrib/go/_std_1.20/src/net/hook.go b/contrib/go/_std_1.21/src/net/hook.go
index ea71803e22..ea71803e22 100644
--- a/contrib/go/_std_1.20/src/net/hook.go
+++ b/contrib/go/_std_1.21/src/net/hook.go
diff --git a/contrib/go/_std_1.21/src/net/hook_unix.go b/contrib/go/_std_1.21/src/net/hook_unix.go
new file mode 100644
index 0000000000..4e20f59218
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/hook_unix.go
@@ -0,0 +1,20 @@
+// Copyright 2015 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package net
+
+import "syscall"
+
+var (
+ testHookDialChannel = func() {} // for golang.org/issue/5349
+ testHookCanceledDial = func() {} // for golang.org/issue/16523
+
+ // Placeholders for socket system calls.
+ socketFunc func(int, int, int) (int, error) = syscall.Socket
+ connectFunc func(int, syscall.Sockaddr) error = syscall.Connect
+ listenFunc func(int, int) error = syscall.Listen
+ getsockoptIntFunc func(int, int, int) (int, error) = syscall.GetsockoptInt
+)
diff --git a/contrib/go/_std_1.20/src/net/hook_windows.go b/contrib/go/_std_1.21/src/net/hook_windows.go
index ab8656cbbf..ab8656cbbf 100644
--- a/contrib/go/_std_1.20/src/net/hook_windows.go
+++ b/contrib/go/_std_1.21/src/net/hook_windows.go
diff --git a/contrib/go/_std_1.21/src/net/hosts.go b/contrib/go/_std_1.21/src/net/hosts.go
new file mode 100644
index 0000000000..56e6674144
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/hosts.go
@@ -0,0 +1,165 @@
+// Copyright 2009 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 net
+
+import (
+ "errors"
+ "internal/bytealg"
+ "io/fs"
+ "net/netip"
+ "sync"
+ "time"
+)
+
+const cacheMaxAge = 5 * time.Second
+
+func parseLiteralIP(addr string) string {
+ ip, err := netip.ParseAddr(addr)
+ if err != nil {
+ return ""
+ }
+ return ip.String()
+}
+
+type byName struct {
+ addrs []string
+ canonicalName string
+}
+
+// hosts contains known host entries.
+var hosts struct {
+ sync.Mutex
+
+ // Key for the list of literal IP addresses must be a host
+ // name. It would be part of DNS labels, a FQDN or an absolute
+ // FQDN.
+ // For now the key is converted to lower case for convenience.
+ byName map[string]byName
+
+ // Key for the list of host names must be a literal IP address
+ // including IPv6 address with zone identifier.
+ // We don't support old-classful IP address notation.
+ byAddr map[string][]string
+
+ expire time.Time
+ path string
+ mtime time.Time
+ size int64
+}
+
+func readHosts() {
+ now := time.Now()
+ hp := testHookHostsPath
+
+ if now.Before(hosts.expire) && hosts.path == hp && len(hosts.byName) > 0 {
+ return
+ }
+ mtime, size, err := stat(hp)
+ if err == nil && hosts.path == hp && hosts.mtime.Equal(mtime) && hosts.size == size {
+ hosts.expire = now.Add(cacheMaxAge)
+ return
+ }
+
+ hs := make(map[string]byName)
+ is := make(map[string][]string)
+
+ file, err := open(hp)
+ if err != nil {
+ if !errors.Is(err, fs.ErrNotExist) && !errors.Is(err, fs.ErrPermission) {
+ return
+ }
+ }
+
+ if file != nil {
+ defer file.close()
+ for line, ok := file.readLine(); ok; line, ok = file.readLine() {
+ if i := bytealg.IndexByteString(line, '#'); i >= 0 {
+ // Discard comments.
+ line = line[0:i]
+ }
+ f := getFields(line)
+ if len(f) < 2 {
+ continue
+ }
+ addr := parseLiteralIP(f[0])
+ if addr == "" {
+ continue
+ }
+
+ var canonical string
+ for i := 1; i < len(f); i++ {
+ name := absDomainName(f[i])
+ h := []byte(f[i])
+ lowerASCIIBytes(h)
+ key := absDomainName(string(h))
+
+ if i == 1 {
+ canonical = key
+ }
+
+ is[addr] = append(is[addr], name)
+
+ if v, ok := hs[key]; ok {
+ hs[key] = byName{
+ addrs: append(v.addrs, addr),
+ canonicalName: v.canonicalName,
+ }
+ continue
+ }
+
+ hs[key] = byName{
+ addrs: []string{addr},
+ canonicalName: canonical,
+ }
+ }
+ }
+ }
+ // Update the data cache.
+ hosts.expire = now.Add(cacheMaxAge)
+ hosts.path = hp
+ hosts.byName = hs
+ hosts.byAddr = is
+ hosts.mtime = mtime
+ hosts.size = size
+}
+
+// lookupStaticHost looks up the addresses and the canonical name for the given host from /etc/hosts.
+func lookupStaticHost(host string) ([]string, string) {
+ hosts.Lock()
+ defer hosts.Unlock()
+ readHosts()
+ if len(hosts.byName) != 0 {
+ if hasUpperCase(host) {
+ lowerHost := []byte(host)
+ lowerASCIIBytes(lowerHost)
+ host = string(lowerHost)
+ }
+ if byName, ok := hosts.byName[absDomainName(host)]; ok {
+ ipsCp := make([]string, len(byName.addrs))
+ copy(ipsCp, byName.addrs)
+ return ipsCp, byName.canonicalName
+ }
+ }
+ return nil, ""
+}
+
+// lookupStaticAddr looks up the hosts for the given address from /etc/hosts.
+func lookupStaticAddr(addr string) []string {
+ hosts.Lock()
+ defer hosts.Unlock()
+ readHosts()
+ addr = parseLiteralIP(addr)
+ if addr == "" {
+ return nil
+ }
+ if len(hosts.byAddr) != 0 {
+ if hosts, ok := hosts.byAddr[addr]; ok {
+ hostsCp := make([]string, len(hosts))
+ copy(hostsCp, hosts)
+ return hostsCp
+ }
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.20/src/net/http/cgi/child.go b/contrib/go/_std_1.21/src/net/http/cgi/child.go
index 1411f0b8e8..1411f0b8e8 100644
--- a/contrib/go/_std_1.20/src/net/http/cgi/child.go
+++ b/contrib/go/_std_1.21/src/net/http/cgi/child.go
diff --git a/contrib/go/_std_1.21/src/net/http/cgi/host.go b/contrib/go/_std_1.21/src/net/http/cgi/host.go
new file mode 100644
index 0000000000..073952a7bd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/cgi/host.go
@@ -0,0 +1,413 @@
+// Copyright 2011 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.
+
+// This file implements the host side of CGI (being the webserver
+// parent process).
+
+// Package cgi implements CGI (Common Gateway Interface) as specified
+// in RFC 3875.
+//
+// Note that using CGI means starting a new process to handle each
+// request, which is typically less efficient than using a
+// long-running server. This package is intended primarily for
+// compatibility with existing systems.
+package cgi
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "log"
+ "net"
+ "net/http"
+ "net/textproto"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "runtime"
+ "strconv"
+ "strings"
+
+ "golang.org/x/net/http/httpguts"
+)
+
+var trailingPort = regexp.MustCompile(`:([0-9]+)$`)
+
+var osDefaultInheritEnv = func() []string {
+ switch runtime.GOOS {
+ case "darwin", "ios":
+ return []string{"DYLD_LIBRARY_PATH"}
+ case "android", "linux", "freebsd", "netbsd", "openbsd":
+ return []string{"LD_LIBRARY_PATH"}
+ case "hpux":
+ return []string{"LD_LIBRARY_PATH", "SHLIB_PATH"}
+ case "irix":
+ return []string{"LD_LIBRARY_PATH", "LD_LIBRARYN32_PATH", "LD_LIBRARY64_PATH"}
+ case "illumos", "solaris":
+ return []string{"LD_LIBRARY_PATH", "LD_LIBRARY_PATH_32", "LD_LIBRARY_PATH_64"}
+ case "windows":
+ return []string{"SystemRoot", "COMSPEC", "PATHEXT", "WINDIR"}
+ }
+ return nil
+}()
+
+// Handler runs an executable in a subprocess with a CGI environment.
+type Handler struct {
+ Path string // path to the CGI executable
+ Root string // root URI prefix of handler or empty for "/"
+
+ // Dir specifies the CGI executable's working directory.
+ // If Dir is empty, the base directory of Path is used.
+ // If Path has no base directory, the current working
+ // directory is used.
+ Dir string
+
+ Env []string // extra environment variables to set, if any, as "key=value"
+ InheritEnv []string // environment variables to inherit from host, as "key"
+ Logger *log.Logger // optional log for errors or nil to use log.Print
+ Args []string // optional arguments to pass to child process
+ Stderr io.Writer // optional stderr for the child process; nil means os.Stderr
+
+ // PathLocationHandler specifies the root http Handler that
+ // should handle internal redirects when the CGI process
+ // returns a Location header value starting with a "/", as
+ // specified in RFC 3875 § 6.3.2. This will likely be
+ // http.DefaultServeMux.
+ //
+ // If nil, a CGI response with a local URI path is instead sent
+ // back to the client and not redirected internally.
+ PathLocationHandler http.Handler
+}
+
+func (h *Handler) stderr() io.Writer {
+ if h.Stderr != nil {
+ return h.Stderr
+ }
+ return os.Stderr
+}
+
+// removeLeadingDuplicates remove leading duplicate in environments.
+// It's possible to override environment like following.
+//
+// cgi.Handler{
+// ...
+// Env: []string{"SCRIPT_FILENAME=foo.php"},
+// }
+func removeLeadingDuplicates(env []string) (ret []string) {
+ for i, e := range env {
+ found := false
+ if eq := strings.IndexByte(e, '='); eq != -1 {
+ keq := e[:eq+1] // "key="
+ for _, e2 := range env[i+1:] {
+ if strings.HasPrefix(e2, keq) {
+ found = true
+ break
+ }
+ }
+ }
+ if !found {
+ ret = append(ret, e)
+ }
+ }
+ return
+}
+
+func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+ root := h.Root
+ if root == "" {
+ root = "/"
+ }
+
+ if len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked" {
+ rw.WriteHeader(http.StatusBadRequest)
+ rw.Write([]byte("Chunked request bodies are not supported by CGI."))
+ return
+ }
+
+ pathInfo := req.URL.Path
+ if root != "/" && strings.HasPrefix(pathInfo, root) {
+ pathInfo = pathInfo[len(root):]
+ }
+
+ port := "80"
+ if matches := trailingPort.FindStringSubmatch(req.Host); len(matches) != 0 {
+ port = matches[1]
+ }
+
+ env := []string{
+ "SERVER_SOFTWARE=go",
+ "SERVER_PROTOCOL=HTTP/1.1",
+ "HTTP_HOST=" + req.Host,
+ "GATEWAY_INTERFACE=CGI/1.1",
+ "REQUEST_METHOD=" + req.Method,
+ "QUERY_STRING=" + req.URL.RawQuery,
+ "REQUEST_URI=" + req.URL.RequestURI(),
+ "PATH_INFO=" + pathInfo,
+ "SCRIPT_NAME=" + root,
+ "SCRIPT_FILENAME=" + h.Path,
+ "SERVER_PORT=" + port,
+ }
+
+ if remoteIP, remotePort, err := net.SplitHostPort(req.RemoteAddr); err == nil {
+ env = append(env, "REMOTE_ADDR="+remoteIP, "REMOTE_HOST="+remoteIP, "REMOTE_PORT="+remotePort)
+ } else {
+ // could not parse ip:port, let's use whole RemoteAddr and leave REMOTE_PORT undefined
+ env = append(env, "REMOTE_ADDR="+req.RemoteAddr, "REMOTE_HOST="+req.RemoteAddr)
+ }
+
+ if hostDomain, _, err := net.SplitHostPort(req.Host); err == nil {
+ env = append(env, "SERVER_NAME="+hostDomain)
+ } else {
+ env = append(env, "SERVER_NAME="+req.Host)
+ }
+
+ if req.TLS != nil {
+ env = append(env, "HTTPS=on")
+ }
+
+ for k, v := range req.Header {
+ k = strings.Map(upperCaseAndUnderscore, k)
+ if k == "PROXY" {
+ // See Issue 16405
+ continue
+ }
+ joinStr := ", "
+ if k == "COOKIE" {
+ joinStr = "; "
+ }
+ env = append(env, "HTTP_"+k+"="+strings.Join(v, joinStr))
+ }
+
+ if req.ContentLength > 0 {
+ env = append(env, fmt.Sprintf("CONTENT_LENGTH=%d", req.ContentLength))
+ }
+ if ctype := req.Header.Get("Content-Type"); ctype != "" {
+ env = append(env, "CONTENT_TYPE="+ctype)
+ }
+
+ envPath := os.Getenv("PATH")
+ if envPath == "" {
+ envPath = "/bin:/usr/bin:/usr/ucb:/usr/bsd:/usr/local/bin"
+ }
+ env = append(env, "PATH="+envPath)
+
+ for _, e := range h.InheritEnv {
+ if v := os.Getenv(e); v != "" {
+ env = append(env, e+"="+v)
+ }
+ }
+
+ for _, e := range osDefaultInheritEnv {
+ if v := os.Getenv(e); v != "" {
+ env = append(env, e+"="+v)
+ }
+ }
+
+ if h.Env != nil {
+ env = append(env, h.Env...)
+ }
+
+ env = removeLeadingDuplicates(env)
+
+ var cwd, path string
+ if h.Dir != "" {
+ path = h.Path
+ cwd = h.Dir
+ } else {
+ cwd, path = filepath.Split(h.Path)
+ }
+ if cwd == "" {
+ cwd = "."
+ }
+
+ internalError := func(err error) {
+ rw.WriteHeader(http.StatusInternalServerError)
+ h.printf("CGI error: %v", err)
+ }
+
+ cmd := &exec.Cmd{
+ Path: path,
+ Args: append([]string{h.Path}, h.Args...),
+ Dir: cwd,
+ Env: env,
+ Stderr: h.stderr(),
+ }
+ if req.ContentLength != 0 {
+ cmd.Stdin = req.Body
+ }
+ stdoutRead, err := cmd.StdoutPipe()
+ if err != nil {
+ internalError(err)
+ return
+ }
+
+ err = cmd.Start()
+ if err != nil {
+ internalError(err)
+ return
+ }
+ if hook := testHookStartProcess; hook != nil {
+ hook(cmd.Process)
+ }
+ defer cmd.Wait()
+ defer stdoutRead.Close()
+
+ linebody := bufio.NewReaderSize(stdoutRead, 1024)
+ headers := make(http.Header)
+ statusCode := 0
+ headerLines := 0
+ sawBlankLine := false
+ for {
+ line, isPrefix, err := linebody.ReadLine()
+ if isPrefix {
+ rw.WriteHeader(http.StatusInternalServerError)
+ h.printf("cgi: long header line from subprocess.")
+ return
+ }
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ rw.WriteHeader(http.StatusInternalServerError)
+ h.printf("cgi: error reading headers: %v", err)
+ return
+ }
+ if len(line) == 0 {
+ sawBlankLine = true
+ break
+ }
+ headerLines++
+ header, val, ok := strings.Cut(string(line), ":")
+ if !ok {
+ h.printf("cgi: bogus header line: %s", string(line))
+ continue
+ }
+ if !httpguts.ValidHeaderFieldName(header) {
+ h.printf("cgi: invalid header name: %q", header)
+ continue
+ }
+ val = textproto.TrimString(val)
+ switch {
+ case header == "Status":
+ if len(val) < 3 {
+ h.printf("cgi: bogus status (short): %q", val)
+ return
+ }
+ code, err := strconv.Atoi(val[0:3])
+ if err != nil {
+ h.printf("cgi: bogus status: %q", val)
+ h.printf("cgi: line was %q", line)
+ return
+ }
+ statusCode = code
+ default:
+ headers.Add(header, val)
+ }
+ }
+ if headerLines == 0 || !sawBlankLine {
+ rw.WriteHeader(http.StatusInternalServerError)
+ h.printf("cgi: no headers")
+ return
+ }
+
+ if loc := headers.Get("Location"); loc != "" {
+ if strings.HasPrefix(loc, "/") && h.PathLocationHandler != nil {
+ h.handleInternalRedirect(rw, req, loc)
+ return
+ }
+ if statusCode == 0 {
+ statusCode = http.StatusFound
+ }
+ }
+
+ if statusCode == 0 && headers.Get("Content-Type") == "" {
+ rw.WriteHeader(http.StatusInternalServerError)
+ h.printf("cgi: missing required Content-Type in headers")
+ return
+ }
+
+ if statusCode == 0 {
+ statusCode = http.StatusOK
+ }
+
+ // Copy headers to rw's headers, after we've decided not to
+ // go into handleInternalRedirect, which won't want its rw
+ // headers to have been touched.
+ for k, vv := range headers {
+ for _, v := range vv {
+ rw.Header().Add(k, v)
+ }
+ }
+
+ rw.WriteHeader(statusCode)
+
+ _, err = io.Copy(rw, linebody)
+ if err != nil {
+ h.printf("cgi: copy error: %v", err)
+ // And kill the child CGI process so we don't hang on
+ // the deferred cmd.Wait above if the error was just
+ // the client (rw) going away. If it was a read error
+ // (because the child died itself), then the extra
+ // kill of an already-dead process is harmless (the PID
+ // won't be reused until the Wait above).
+ cmd.Process.Kill()
+ }
+}
+
+func (h *Handler) printf(format string, v ...any) {
+ if h.Logger != nil {
+ h.Logger.Printf(format, v...)
+ } else {
+ log.Printf(format, v...)
+ }
+}
+
+func (h *Handler) handleInternalRedirect(rw http.ResponseWriter, req *http.Request, path string) {
+ url, err := req.URL.Parse(path)
+ if err != nil {
+ rw.WriteHeader(http.StatusInternalServerError)
+ h.printf("cgi: error resolving local URI path %q: %v", path, err)
+ return
+ }
+ // TODO: RFC 3875 isn't clear if only GET is supported, but it
+ // suggests so: "Note that any message-body attached to the
+ // request (such as for a POST request) may not be available
+ // to the resource that is the target of the redirect." We
+ // should do some tests against Apache to see how it handles
+ // POST, HEAD, etc. Does the internal redirect get the same
+ // method or just GET? What about incoming headers?
+ // (e.g. Cookies) Which headers, if any, are copied into the
+ // second request?
+ newReq := &http.Request{
+ Method: "GET",
+ URL: url,
+ Proto: "HTTP/1.1",
+ ProtoMajor: 1,
+ ProtoMinor: 1,
+ Header: make(http.Header),
+ Host: url.Host,
+ RemoteAddr: req.RemoteAddr,
+ TLS: req.TLS,
+ }
+ h.PathLocationHandler.ServeHTTP(rw, newReq)
+}
+
+func upperCaseAndUnderscore(r rune) rune {
+ switch {
+ case r >= 'a' && r <= 'z':
+ return r - ('a' - 'A')
+ case r == '-':
+ return '_'
+ case r == '=':
+ // Maybe not part of the CGI 'spec' but would mess up
+ // the environment in any case, as Go represents the
+ // environment as a slice of "key=value" strings.
+ return '_'
+ }
+ // TODO: other transformations in spec or practice?
+ return r
+}
+
+var testHookStartProcess func(*os.Process) // nil except for some tests
diff --git a/contrib/go/_std_1.21/src/net/http/cgi/ya.make b/contrib/go/_std_1.21/src/net/http/cgi/ya.make
new file mode 100644
index 0000000000..9ec9ddbccb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/cgi/ya.make
@@ -0,0 +1,18 @@
+GO_LIBRARY()
+
+SRCS(
+ child.go
+ host.go
+)
+
+GO_TEST_SRCS(
+ child_test.go
+ host_test.go
+ integration_test.go
+ posix_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/net/http/client.go b/contrib/go/_std_1.21/src/net/http/client.go
new file mode 100644
index 0000000000..2cab53a585
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/client.go
@@ -0,0 +1,1032 @@
+// Copyright 2009 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.
+
+// HTTP client. See RFC 7230 through 7235.
+//
+// This is the high-level Client interface.
+// The low-level implementation is in transport.go.
+
+package http
+
+import (
+ "context"
+ "crypto/tls"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "net/http/internal/ascii"
+ "net/url"
+ "reflect"
+ "sort"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+// A Client is an HTTP client. Its zero value (DefaultClient) is a
+// usable client that uses DefaultTransport.
+//
+// The Client's Transport typically has internal state (cached TCP
+// connections), so Clients should be reused instead of created as
+// needed. Clients are safe for concurrent use by multiple goroutines.
+//
+// A Client is higher-level than a RoundTripper (such as Transport)
+// and additionally handles HTTP details such as cookies and
+// redirects.
+//
+// When following redirects, the Client will forward all headers set on the
+// initial Request except:
+//
+// • when forwarding sensitive headers like "Authorization",
+// "WWW-Authenticate", and "Cookie" to untrusted targets.
+// These headers will be ignored when following a redirect to a domain
+// that is not a subdomain match or exact match of the initial domain.
+// For example, a redirect from "foo.com" to either "foo.com" or "sub.foo.com"
+// will forward the sensitive headers, but a redirect to "bar.com" will not.
+//
+// • when forwarding the "Cookie" header with a non-nil cookie Jar.
+// Since each redirect may mutate the state of the cookie jar,
+// a redirect may possibly alter a cookie set in the initial request.
+// When forwarding the "Cookie" header, any mutated cookies will be omitted,
+// with the expectation that the Jar will insert those mutated cookies
+// with the updated values (assuming the origin matches).
+// If Jar is nil, the initial cookies are forwarded without change.
+type Client struct {
+ // Transport specifies the mechanism by which individual
+ // HTTP requests are made.
+ // If nil, DefaultTransport is used.
+ Transport RoundTripper
+
+ // CheckRedirect specifies the policy for handling redirects.
+ // If CheckRedirect is not nil, the client calls it before
+ // following an HTTP redirect. The arguments req and via are
+ // the upcoming request and the requests made already, oldest
+ // first. If CheckRedirect returns an error, the Client's Get
+ // method returns both the previous Response (with its Body
+ // closed) and CheckRedirect's error (wrapped in a url.Error)
+ // instead of issuing the Request req.
+ // As a special case, if CheckRedirect returns ErrUseLastResponse,
+ // then the most recent response is returned with its body
+ // unclosed, along with a nil error.
+ //
+ // If CheckRedirect is nil, the Client uses its default policy,
+ // which is to stop after 10 consecutive requests.
+ CheckRedirect func(req *Request, via []*Request) error
+
+ // Jar specifies the cookie jar.
+ //
+ // The Jar is used to insert relevant cookies into every
+ // outbound Request and is updated with the cookie values
+ // of every inbound Response. The Jar is consulted for every
+ // redirect that the Client follows.
+ //
+ // If Jar is nil, cookies are only sent if they are explicitly
+ // set on the Request.
+ Jar CookieJar
+
+ // Timeout specifies a time limit for requests made by this
+ // Client. The timeout includes connection time, any
+ // redirects, and reading the response body. The timer remains
+ // running after Get, Head, Post, or Do return and will
+ // interrupt reading of the Response.Body.
+ //
+ // A Timeout of zero means no timeout.
+ //
+ // The Client cancels requests to the underlying Transport
+ // as if the Request's Context ended.
+ //
+ // For compatibility, the Client will also use the deprecated
+ // CancelRequest method on Transport if found. New
+ // RoundTripper implementations should use the Request's Context
+ // for cancellation instead of implementing CancelRequest.
+ Timeout time.Duration
+}
+
+// DefaultClient is the default Client and is used by Get, Head, and Post.
+var DefaultClient = &Client{}
+
+// RoundTripper is an interface representing the ability to execute a
+// single HTTP transaction, obtaining the Response for a given Request.
+//
+// A RoundTripper must be safe for concurrent use by multiple
+// goroutines.
+type RoundTripper interface {
+ // RoundTrip executes a single HTTP transaction, returning
+ // a Response for the provided Request.
+ //
+ // RoundTrip should not attempt to interpret the response. In
+ // particular, RoundTrip must return err == nil if it obtained
+ // a response, regardless of the response's HTTP status code.
+ // A non-nil err should be reserved for failure to obtain a
+ // response. Similarly, RoundTrip should not attempt to
+ // handle higher-level protocol details such as redirects,
+ // authentication, or cookies.
+ //
+ // RoundTrip should not modify the request, except for
+ // consuming and closing the Request's Body. RoundTrip may
+ // read fields of the request in a separate goroutine. Callers
+ // should not mutate or reuse the request until the Response's
+ // Body has been closed.
+ //
+ // RoundTrip must always close the body, including on errors,
+ // but depending on the implementation may do so in a separate
+ // goroutine even after RoundTrip returns. This means that
+ // callers wanting to reuse the body for subsequent requests
+ // must arrange to wait for the Close call before doing so.
+ //
+ // The Request's URL and Header fields must be initialized.
+ RoundTrip(*Request) (*Response, error)
+}
+
+// refererForURL returns a referer without any authentication info or
+// an empty string if lastReq scheme is https and newReq scheme is http.
+// If the referer was explicitly set, then it will continue to be used.
+func refererForURL(lastReq, newReq *url.URL, explicitRef string) string {
+ // https://tools.ietf.org/html/rfc7231#section-5.5.2
+ // "Clients SHOULD NOT include a Referer header field in a
+ // (non-secure) HTTP request if the referring page was
+ // transferred with a secure protocol."
+ if lastReq.Scheme == "https" && newReq.Scheme == "http" {
+ return ""
+ }
+ if explicitRef != "" {
+ return explicitRef
+ }
+
+ referer := lastReq.String()
+ if lastReq.User != nil {
+ // This is not very efficient, but is the best we can
+ // do without:
+ // - introducing a new method on URL
+ // - creating a race condition
+ // - copying the URL struct manually, which would cause
+ // maintenance problems down the line
+ auth := lastReq.User.String() + "@"
+ referer = strings.Replace(referer, auth, "", 1)
+ }
+ return referer
+}
+
+// didTimeout is non-nil only if err != nil.
+func (c *Client) send(req *Request, deadline time.Time) (resp *Response, didTimeout func() bool, err error) {
+ if c.Jar != nil {
+ for _, cookie := range c.Jar.Cookies(req.URL) {
+ req.AddCookie(cookie)
+ }
+ }
+ resp, didTimeout, err = send(req, c.transport(), deadline)
+ if err != nil {
+ return nil, didTimeout, err
+ }
+ if c.Jar != nil {
+ if rc := resp.Cookies(); len(rc) > 0 {
+ c.Jar.SetCookies(req.URL, rc)
+ }
+ }
+ return resp, nil, nil
+}
+
+func (c *Client) deadline() time.Time {
+ if c.Timeout > 0 {
+ return time.Now().Add(c.Timeout)
+ }
+ return time.Time{}
+}
+
+func (c *Client) transport() RoundTripper {
+ if c.Transport != nil {
+ return c.Transport
+ }
+ return DefaultTransport
+}
+
+// ErrSchemeMismatch is returned when a server returns an HTTP response to an HTTPS client.
+var ErrSchemeMismatch = errors.New("http: server gave HTTP response to HTTPS client")
+
+// send issues an HTTP request.
+// Caller should close resp.Body when done reading from it.
+func send(ireq *Request, rt RoundTripper, deadline time.Time) (resp *Response, didTimeout func() bool, err error) {
+ req := ireq // req is either the original request, or a modified fork
+
+ if rt == nil {
+ req.closeBody()
+ return nil, alwaysFalse, errors.New("http: no Client.Transport or DefaultTransport")
+ }
+
+ if req.URL == nil {
+ req.closeBody()
+ return nil, alwaysFalse, errors.New("http: nil Request.URL")
+ }
+
+ if req.RequestURI != "" {
+ req.closeBody()
+ return nil, alwaysFalse, errors.New("http: Request.RequestURI can't be set in client requests")
+ }
+
+ // forkReq forks req into a shallow clone of ireq the first
+ // time it's called.
+ forkReq := func() {
+ if ireq == req {
+ req = new(Request)
+ *req = *ireq // shallow clone
+ }
+ }
+
+ // Most the callers of send (Get, Post, et al) don't need
+ // Headers, leaving it uninitialized. We guarantee to the
+ // Transport that this has been initialized, though.
+ if req.Header == nil {
+ forkReq()
+ req.Header = make(Header)
+ }
+
+ if u := req.URL.User; u != nil && req.Header.Get("Authorization") == "" {
+ username := u.Username()
+ password, _ := u.Password()
+ forkReq()
+ req.Header = cloneOrMakeHeader(ireq.Header)
+ req.Header.Set("Authorization", "Basic "+basicAuth(username, password))
+ }
+
+ if !deadline.IsZero() {
+ forkReq()
+ }
+ stopTimer, didTimeout := setRequestCancel(req, rt, deadline)
+
+ resp, err = rt.RoundTrip(req)
+ if err != nil {
+ stopTimer()
+ if resp != nil {
+ log.Printf("RoundTripper returned a response & error; ignoring response")
+ }
+ if tlsErr, ok := err.(tls.RecordHeaderError); ok {
+ // If we get a bad TLS record header, check to see if the
+ // response looks like HTTP and give a more helpful error.
+ // See golang.org/issue/11111.
+ if string(tlsErr.RecordHeader[:]) == "HTTP/" {
+ err = ErrSchemeMismatch
+ }
+ }
+ return nil, didTimeout, err
+ }
+ if resp == nil {
+ return nil, didTimeout, fmt.Errorf("http: RoundTripper implementation (%T) returned a nil *Response with a nil error", rt)
+ }
+ if resp.Body == nil {
+ // The documentation on the Body field says “The http Client and Transport
+ // guarantee that Body is always non-nil, even on responses without a body
+ // or responses with a zero-length body.” Unfortunately, we didn't document
+ // that same constraint for arbitrary RoundTripper implementations, and
+ // RoundTripper implementations in the wild (mostly in tests) assume that
+ // they can use a nil Body to mean an empty one (similar to Request.Body).
+ // (See https://golang.org/issue/38095.)
+ //
+ // If the ContentLength allows the Body to be empty, fill in an empty one
+ // here to ensure that it is non-nil.
+ if resp.ContentLength > 0 && req.Method != "HEAD" {
+ return nil, didTimeout, fmt.Errorf("http: RoundTripper implementation (%T) returned a *Response with content length %d but a nil Body", rt, resp.ContentLength)
+ }
+ resp.Body = io.NopCloser(strings.NewReader(""))
+ }
+ if !deadline.IsZero() {
+ resp.Body = &cancelTimerBody{
+ stop: stopTimer,
+ rc: resp.Body,
+ reqDidTimeout: didTimeout,
+ }
+ }
+ return resp, nil, nil
+}
+
+// timeBeforeContextDeadline reports whether the non-zero Time t is
+// before ctx's deadline, if any. If ctx does not have a deadline, it
+// always reports true (the deadline is considered infinite).
+func timeBeforeContextDeadline(t time.Time, ctx context.Context) bool {
+ d, ok := ctx.Deadline()
+ if !ok {
+ return true
+ }
+ return t.Before(d)
+}
+
+// knownRoundTripperImpl reports whether rt is a RoundTripper that's
+// maintained by the Go team and known to implement the latest
+// optional semantics (notably contexts). The Request is used
+// to check whether this particular request is using an alternate protocol,
+// in which case we need to check the RoundTripper for that protocol.
+func knownRoundTripperImpl(rt RoundTripper, req *Request) bool {
+ switch t := rt.(type) {
+ case *Transport:
+ if altRT := t.alternateRoundTripper(req); altRT != nil {
+ return knownRoundTripperImpl(altRT, req)
+ }
+ return true
+ case *http2Transport, http2noDialH2RoundTripper:
+ return true
+ }
+ // There's a very minor chance of a false positive with this.
+ // Instead of detecting our golang.org/x/net/http2.Transport,
+ // it might detect a Transport type in a different http2
+ // package. But I know of none, and the only problem would be
+ // some temporarily leaked goroutines if the transport didn't
+ // support contexts. So this is a good enough heuristic:
+ if reflect.TypeOf(rt).String() == "*http2.Transport" {
+ return true
+ }
+ return false
+}
+
+// setRequestCancel sets req.Cancel and adds a deadline context to req
+// if deadline is non-zero. The RoundTripper's type is used to
+// determine whether the legacy CancelRequest behavior should be used.
+//
+// As background, there are three ways to cancel a request:
+// First was Transport.CancelRequest. (deprecated)
+// Second was Request.Cancel.
+// Third was Request.Context.
+// This function populates the second and third, and uses the first if it really needs to.
+func setRequestCancel(req *Request, rt RoundTripper, deadline time.Time) (stopTimer func(), didTimeout func() bool) {
+ if deadline.IsZero() {
+ return nop, alwaysFalse
+ }
+ knownTransport := knownRoundTripperImpl(rt, req)
+ oldCtx := req.Context()
+
+ if req.Cancel == nil && knownTransport {
+ // If they already had a Request.Context that's
+ // expiring sooner, do nothing:
+ if !timeBeforeContextDeadline(deadline, oldCtx) {
+ return nop, alwaysFalse
+ }
+
+ var cancelCtx func()
+ req.ctx, cancelCtx = context.WithDeadline(oldCtx, deadline)
+ return cancelCtx, func() bool { return time.Now().After(deadline) }
+ }
+ initialReqCancel := req.Cancel // the user's original Request.Cancel, if any
+
+ var cancelCtx func()
+ if timeBeforeContextDeadline(deadline, oldCtx) {
+ req.ctx, cancelCtx = context.WithDeadline(oldCtx, deadline)
+ }
+
+ cancel := make(chan struct{})
+ req.Cancel = cancel
+
+ doCancel := func() {
+ // The second way in the func comment above:
+ close(cancel)
+ // The first way, used only for RoundTripper
+ // implementations written before Go 1.5 or Go 1.6.
+ type canceler interface{ CancelRequest(*Request) }
+ if v, ok := rt.(canceler); ok {
+ v.CancelRequest(req)
+ }
+ }
+
+ stopTimerCh := make(chan struct{})
+ var once sync.Once
+ stopTimer = func() {
+ once.Do(func() {
+ close(stopTimerCh)
+ if cancelCtx != nil {
+ cancelCtx()
+ }
+ })
+ }
+
+ timer := time.NewTimer(time.Until(deadline))
+ var timedOut atomic.Bool
+
+ go func() {
+ select {
+ case <-initialReqCancel:
+ doCancel()
+ timer.Stop()
+ case <-timer.C:
+ timedOut.Store(true)
+ doCancel()
+ case <-stopTimerCh:
+ timer.Stop()
+ }
+ }()
+
+ return stopTimer, timedOut.Load
+}
+
+// See 2 (end of page 4) https://www.ietf.org/rfc/rfc2617.txt
+// "To receive authorization, the client sends the userid and password,
+// separated by a single colon (":") character, within a base64
+// encoded string in the credentials."
+// It is not meant to be urlencoded.
+func basicAuth(username, password string) string {
+ auth := username + ":" + password
+ return base64.StdEncoding.EncodeToString([]byte(auth))
+}
+
+// Get issues a GET to the specified URL. If the response is one of
+// the following redirect codes, Get follows the redirect, up to a
+// maximum of 10 redirects:
+//
+// 301 (Moved Permanently)
+// 302 (Found)
+// 303 (See Other)
+// 307 (Temporary Redirect)
+// 308 (Permanent Redirect)
+//
+// An error is returned if there were too many redirects or if there
+// was an HTTP protocol error. A non-2xx response doesn't cause an
+// error. Any returned error will be of type *url.Error. The url.Error
+// value's Timeout method will report true if the request timed out.
+//
+// When err is nil, resp always contains a non-nil resp.Body.
+// Caller should close resp.Body when done reading from it.
+//
+// Get is a wrapper around DefaultClient.Get.
+//
+// To make a request with custom headers, use NewRequest and
+// DefaultClient.Do.
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and DefaultClient.Do.
+func Get(url string) (resp *Response, err error) {
+ return DefaultClient.Get(url)
+}
+
+// Get issues a GET to the specified URL. If the response is one of the
+// following redirect codes, Get follows the redirect after calling the
+// Client's CheckRedirect function:
+//
+// 301 (Moved Permanently)
+// 302 (Found)
+// 303 (See Other)
+// 307 (Temporary Redirect)
+// 308 (Permanent Redirect)
+//
+// An error is returned if the Client's CheckRedirect function fails
+// or if there was an HTTP protocol error. A non-2xx response doesn't
+// cause an error. Any returned error will be of type *url.Error. The
+// url.Error value's Timeout method will report true if the request
+// timed out.
+//
+// When err is nil, resp always contains a non-nil resp.Body.
+// Caller should close resp.Body when done reading from it.
+//
+// To make a request with custom headers, use NewRequest and Client.Do.
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and Client.Do.
+func (c *Client) Get(url string) (resp *Response, err error) {
+ req, err := NewRequest("GET", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ return c.Do(req)
+}
+
+func alwaysFalse() bool { return false }
+
+// ErrUseLastResponse can be returned by Client.CheckRedirect hooks to
+// control how redirects are processed. If returned, the next request
+// is not sent and the most recent response is returned with its body
+// unclosed.
+var ErrUseLastResponse = errors.New("net/http: use last response")
+
+// checkRedirect calls either the user's configured CheckRedirect
+// function, or the default.
+func (c *Client) checkRedirect(req *Request, via []*Request) error {
+ fn := c.CheckRedirect
+ if fn == nil {
+ fn = defaultCheckRedirect
+ }
+ return fn(req, via)
+}
+
+// redirectBehavior describes what should happen when the
+// client encounters a 3xx status code from the server.
+func redirectBehavior(reqMethod string, resp *Response, ireq *Request) (redirectMethod string, shouldRedirect, includeBody bool) {
+ switch resp.StatusCode {
+ case 301, 302, 303:
+ redirectMethod = reqMethod
+ shouldRedirect = true
+ includeBody = false
+
+ // RFC 2616 allowed automatic redirection only with GET and
+ // HEAD requests. RFC 7231 lifts this restriction, but we still
+ // restrict other methods to GET to maintain compatibility.
+ // See Issue 18570.
+ if reqMethod != "GET" && reqMethod != "HEAD" {
+ redirectMethod = "GET"
+ }
+ case 307, 308:
+ redirectMethod = reqMethod
+ shouldRedirect = true
+ includeBody = true
+
+ if ireq.GetBody == nil && ireq.outgoingLength() != 0 {
+ // We had a request body, and 307/308 require
+ // re-sending it, but GetBody is not defined. So just
+ // return this response to the user instead of an
+ // error, like we did in Go 1.7 and earlier.
+ shouldRedirect = false
+ }
+ }
+ return redirectMethod, shouldRedirect, includeBody
+}
+
+// urlErrorOp returns the (*url.Error).Op value to use for the
+// provided (*Request).Method value.
+func urlErrorOp(method string) string {
+ if method == "" {
+ return "Get"
+ }
+ if lowerMethod, ok := ascii.ToLower(method); ok {
+ return method[:1] + lowerMethod[1:]
+ }
+ return method
+}
+
+// Do sends an HTTP request and returns an HTTP response, following
+// policy (such as redirects, cookies, auth) as configured on the
+// client.
+//
+// An error is returned if caused by client policy (such as
+// CheckRedirect), or failure to speak HTTP (such as a network
+// connectivity problem). A non-2xx status code doesn't cause an
+// error.
+//
+// If the returned error is nil, the Response will contain a non-nil
+// Body which the user is expected to close. If the Body is not both
+// read to EOF and closed, the Client's underlying RoundTripper
+// (typically Transport) may not be able to re-use a persistent TCP
+// connection to the server for a subsequent "keep-alive" request.
+//
+// The request Body, if non-nil, will be closed by the underlying
+// Transport, even on errors.
+//
+// On error, any Response can be ignored. A non-nil Response with a
+// non-nil error only occurs when CheckRedirect fails, and even then
+// the returned Response.Body is already closed.
+//
+// Generally Get, Post, or PostForm will be used instead of Do.
+//
+// If the server replies with a redirect, the Client first uses the
+// CheckRedirect function to determine whether the redirect should be
+// followed. If permitted, a 301, 302, or 303 redirect causes
+// subsequent requests to use HTTP method GET
+// (or HEAD if the original request was HEAD), with no body.
+// A 307 or 308 redirect preserves the original HTTP method and body,
+// provided that the Request.GetBody function is defined.
+// The NewRequest function automatically sets GetBody for common
+// standard library body types.
+//
+// Any returned error will be of type *url.Error. The url.Error
+// value's Timeout method will report true if the request timed out.
+func (c *Client) Do(req *Request) (*Response, error) {
+ return c.do(req)
+}
+
+var testHookClientDoResult func(retres *Response, reterr error)
+
+func (c *Client) do(req *Request) (retres *Response, reterr error) {
+ if testHookClientDoResult != nil {
+ defer func() { testHookClientDoResult(retres, reterr) }()
+ }
+ if req.URL == nil {
+ req.closeBody()
+ return nil, &url.Error{
+ Op: urlErrorOp(req.Method),
+ Err: errors.New("http: nil Request.URL"),
+ }
+ }
+
+ var (
+ deadline = c.deadline()
+ reqs []*Request
+ resp *Response
+ copyHeaders = c.makeHeadersCopier(req)
+ reqBodyClosed = false // have we closed the current req.Body?
+
+ // Redirect behavior:
+ redirectMethod string
+ includeBody bool
+ )
+ uerr := func(err error) error {
+ // the body may have been closed already by c.send()
+ if !reqBodyClosed {
+ req.closeBody()
+ }
+ var urlStr string
+ if resp != nil && resp.Request != nil {
+ urlStr = stripPassword(resp.Request.URL)
+ } else {
+ urlStr = stripPassword(req.URL)
+ }
+ return &url.Error{
+ Op: urlErrorOp(reqs[0].Method),
+ URL: urlStr,
+ Err: err,
+ }
+ }
+ for {
+ // For all but the first request, create the next
+ // request hop and replace req.
+ if len(reqs) > 0 {
+ loc := resp.Header.Get("Location")
+ if loc == "" {
+ // While most 3xx responses include a Location, it is not
+ // required and 3xx responses without a Location have been
+ // observed in the wild. See issues #17773 and #49281.
+ return resp, nil
+ }
+ u, err := req.URL.Parse(loc)
+ if err != nil {
+ resp.closeBody()
+ return nil, uerr(fmt.Errorf("failed to parse Location header %q: %v", loc, err))
+ }
+ host := ""
+ if req.Host != "" && req.Host != req.URL.Host {
+ // If the caller specified a custom Host header and the
+ // redirect location is relative, preserve the Host header
+ // through the redirect. See issue #22233.
+ if u, _ := url.Parse(loc); u != nil && !u.IsAbs() {
+ host = req.Host
+ }
+ }
+ ireq := reqs[0]
+ req = &Request{
+ Method: redirectMethod,
+ Response: resp,
+ URL: u,
+ Header: make(Header),
+ Host: host,
+ Cancel: ireq.Cancel,
+ ctx: ireq.ctx,
+ }
+ if includeBody && ireq.GetBody != nil {
+ req.Body, err = ireq.GetBody()
+ if err != nil {
+ resp.closeBody()
+ return nil, uerr(err)
+ }
+ req.ContentLength = ireq.ContentLength
+ }
+
+ // Copy original headers before setting the Referer,
+ // in case the user set Referer on their first request.
+ // If they really want to override, they can do it in
+ // their CheckRedirect func.
+ copyHeaders(req)
+
+ // Add the Referer header from the most recent
+ // request URL to the new one, if it's not https->http:
+ if ref := refererForURL(reqs[len(reqs)-1].URL, req.URL, req.Header.Get("Referer")); ref != "" {
+ req.Header.Set("Referer", ref)
+ }
+ err = c.checkRedirect(req, reqs)
+
+ // Sentinel error to let users select the
+ // previous response, without closing its
+ // body. See Issue 10069.
+ if err == ErrUseLastResponse {
+ return resp, nil
+ }
+
+ // Close the previous response's body. But
+ // read at least some of the body so if it's
+ // small the underlying TCP connection will be
+ // re-used. No need to check for errors: if it
+ // fails, the Transport won't reuse it anyway.
+ const maxBodySlurpSize = 2 << 10
+ if resp.ContentLength == -1 || resp.ContentLength <= maxBodySlurpSize {
+ io.CopyN(io.Discard, resp.Body, maxBodySlurpSize)
+ }
+ resp.Body.Close()
+
+ if err != nil {
+ // Special case for Go 1 compatibility: return both the response
+ // and an error if the CheckRedirect function failed.
+ // See https://golang.org/issue/3795
+ // The resp.Body has already been closed.
+ ue := uerr(err)
+ ue.(*url.Error).URL = loc
+ return resp, ue
+ }
+ }
+
+ reqs = append(reqs, req)
+ var err error
+ var didTimeout func() bool
+ if resp, didTimeout, err = c.send(req, deadline); err != nil {
+ // c.send() always closes req.Body
+ reqBodyClosed = true
+ if !deadline.IsZero() && didTimeout() {
+ err = &httpError{
+ err: err.Error() + " (Client.Timeout exceeded while awaiting headers)",
+ timeout: true,
+ }
+ }
+ return nil, uerr(err)
+ }
+
+ var shouldRedirect bool
+ redirectMethod, shouldRedirect, includeBody = redirectBehavior(req.Method, resp, reqs[0])
+ if !shouldRedirect {
+ return resp, nil
+ }
+
+ req.closeBody()
+ }
+}
+
+// makeHeadersCopier makes a function that copies headers from the
+// initial Request, ireq. For every redirect, this function must be called
+// so that it can copy headers into the upcoming Request.
+func (c *Client) makeHeadersCopier(ireq *Request) func(*Request) {
+ // The headers to copy are from the very initial request.
+ // We use a closured callback to keep a reference to these original headers.
+ var (
+ ireqhdr = cloneOrMakeHeader(ireq.Header)
+ icookies map[string][]*Cookie
+ )
+ if c.Jar != nil && ireq.Header.Get("Cookie") != "" {
+ icookies = make(map[string][]*Cookie)
+ for _, c := range ireq.Cookies() {
+ icookies[c.Name] = append(icookies[c.Name], c)
+ }
+ }
+
+ preq := ireq // The previous request
+ return func(req *Request) {
+ // If Jar is present and there was some initial cookies provided
+ // via the request header, then we may need to alter the initial
+ // cookies as we follow redirects since each redirect may end up
+ // modifying a pre-existing cookie.
+ //
+ // Since cookies already set in the request header do not contain
+ // information about the original domain and path, the logic below
+ // assumes any new set cookies override the original cookie
+ // regardless of domain or path.
+ //
+ // See https://golang.org/issue/17494
+ if c.Jar != nil && icookies != nil {
+ var changed bool
+ resp := req.Response // The response that caused the upcoming redirect
+ for _, c := range resp.Cookies() {
+ if _, ok := icookies[c.Name]; ok {
+ delete(icookies, c.Name)
+ changed = true
+ }
+ }
+ if changed {
+ ireqhdr.Del("Cookie")
+ var ss []string
+ for _, cs := range icookies {
+ for _, c := range cs {
+ ss = append(ss, c.Name+"="+c.Value)
+ }
+ }
+ sort.Strings(ss) // Ensure deterministic headers
+ ireqhdr.Set("Cookie", strings.Join(ss, "; "))
+ }
+ }
+
+ // Copy the initial request's Header values
+ // (at least the safe ones).
+ for k, vv := range ireqhdr {
+ if shouldCopyHeaderOnRedirect(k, preq.URL, req.URL) {
+ req.Header[k] = vv
+ }
+ }
+
+ preq = req // Update previous Request with the current request
+ }
+}
+
+func defaultCheckRedirect(req *Request, via []*Request) error {
+ if len(via) >= 10 {
+ return errors.New("stopped after 10 redirects")
+ }
+ return nil
+}
+
+// Post issues a POST to the specified URL.
+//
+// Caller should close resp.Body when done reading from it.
+//
+// If the provided body is an io.Closer, it is closed after the
+// request.
+//
+// Post is a wrapper around DefaultClient.Post.
+//
+// To set custom headers, use NewRequest and DefaultClient.Do.
+//
+// See the Client.Do method documentation for details on how redirects
+// are handled.
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and DefaultClient.Do.
+func Post(url, contentType string, body io.Reader) (resp *Response, err error) {
+ return DefaultClient.Post(url, contentType, body)
+}
+
+// Post issues a POST to the specified URL.
+//
+// Caller should close resp.Body when done reading from it.
+//
+// If the provided body is an io.Closer, it is closed after the
+// request.
+//
+// To set custom headers, use NewRequest and Client.Do.
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and Client.Do.
+//
+// See the Client.Do method documentation for details on how redirects
+// are handled.
+func (c *Client) Post(url, contentType string, body io.Reader) (resp *Response, err error) {
+ req, err := NewRequest("POST", url, body)
+ if err != nil {
+ return nil, err
+ }
+ req.Header.Set("Content-Type", contentType)
+ return c.Do(req)
+}
+
+// PostForm issues a POST to the specified URL, with data's keys and
+// values URL-encoded as the request body.
+//
+// The Content-Type header is set to application/x-www-form-urlencoded.
+// To set other headers, use NewRequest and DefaultClient.Do.
+//
+// When err is nil, resp always contains a non-nil resp.Body.
+// Caller should close resp.Body when done reading from it.
+//
+// PostForm is a wrapper around DefaultClient.PostForm.
+//
+// See the Client.Do method documentation for details on how redirects
+// are handled.
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and DefaultClient.Do.
+func PostForm(url string, data url.Values) (resp *Response, err error) {
+ return DefaultClient.PostForm(url, data)
+}
+
+// PostForm issues a POST to the specified URL,
+// with data's keys and values URL-encoded as the request body.
+//
+// The Content-Type header is set to application/x-www-form-urlencoded.
+// To set other headers, use NewRequest and Client.Do.
+//
+// When err is nil, resp always contains a non-nil resp.Body.
+// Caller should close resp.Body when done reading from it.
+//
+// See the Client.Do method documentation for details on how redirects
+// are handled.
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and Client.Do.
+func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) {
+ return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
+}
+
+// Head issues a HEAD to the specified URL. If the response is one of
+// the following redirect codes, Head follows the redirect, up to a
+// maximum of 10 redirects:
+//
+// 301 (Moved Permanently)
+// 302 (Found)
+// 303 (See Other)
+// 307 (Temporary Redirect)
+// 308 (Permanent Redirect)
+//
+// Head is a wrapper around DefaultClient.Head.
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and DefaultClient.Do.
+func Head(url string) (resp *Response, err error) {
+ return DefaultClient.Head(url)
+}
+
+// Head issues a HEAD to the specified URL. If the response is one of the
+// following redirect codes, Head follows the redirect after calling the
+// Client's CheckRedirect function:
+//
+// 301 (Moved Permanently)
+// 302 (Found)
+// 303 (See Other)
+// 307 (Temporary Redirect)
+// 308 (Permanent Redirect)
+//
+// To make a request with a specified context.Context, use NewRequestWithContext
+// and Client.Do.
+func (c *Client) Head(url string) (resp *Response, err error) {
+ req, err := NewRequest("HEAD", url, nil)
+ if err != nil {
+ return nil, err
+ }
+ return c.Do(req)
+}
+
+// CloseIdleConnections closes any connections on its Transport which
+// were previously connected from previous requests but are now
+// sitting idle in a "keep-alive" state. It does not interrupt any
+// connections currently in use.
+//
+// If the Client's Transport does not have a CloseIdleConnections method
+// then this method does nothing.
+func (c *Client) CloseIdleConnections() {
+ type closeIdler interface {
+ CloseIdleConnections()
+ }
+ if tr, ok := c.transport().(closeIdler); ok {
+ tr.CloseIdleConnections()
+ }
+}
+
+// cancelTimerBody is an io.ReadCloser that wraps rc with two features:
+// 1. On Read error or close, the stop func is called.
+// 2. On Read failure, if reqDidTimeout is true, the error is wrapped and
+// marked as net.Error that hit its timeout.
+type cancelTimerBody struct {
+ stop func() // stops the time.Timer waiting to cancel the request
+ rc io.ReadCloser
+ reqDidTimeout func() bool
+}
+
+func (b *cancelTimerBody) Read(p []byte) (n int, err error) {
+ n, err = b.rc.Read(p)
+ if err == nil {
+ return n, nil
+ }
+ if err == io.EOF {
+ return n, err
+ }
+ if b.reqDidTimeout() {
+ err = &httpError{
+ err: err.Error() + " (Client.Timeout or context cancellation while reading body)",
+ timeout: true,
+ }
+ }
+ return n, err
+}
+
+func (b *cancelTimerBody) Close() error {
+ err := b.rc.Close()
+ b.stop()
+ return err
+}
+
+func shouldCopyHeaderOnRedirect(headerKey string, initial, dest *url.URL) bool {
+ switch CanonicalHeaderKey(headerKey) {
+ case "Authorization", "Www-Authenticate", "Cookie", "Cookie2":
+ // Permit sending auth/cookie headers from "foo.com"
+ // to "sub.foo.com".
+
+ // Note that we don't send all cookies to subdomains
+ // automatically. This function is only used for
+ // Cookies set explicitly on the initial outgoing
+ // client request. Cookies automatically added via the
+ // CookieJar mechanism continue to follow each
+ // cookie's scope as set by Set-Cookie. But for
+ // outgoing requests with the Cookie header set
+ // directly, we don't know their scope, so we assume
+ // it's for *.domain.com.
+
+ ihost := idnaASCIIFromURL(initial)
+ dhost := idnaASCIIFromURL(dest)
+ return isDomainOrSubdomain(dhost, ihost)
+ }
+ // All other headers are copied:
+ return true
+}
+
+// isDomainOrSubdomain reports whether sub is a subdomain (or exact
+// match) of the parent domain.
+//
+// Both domains must already be in canonical form.
+func isDomainOrSubdomain(sub, parent string) bool {
+ if sub == parent {
+ return true
+ }
+ // If sub is "foo.example.com" and parent is "example.com",
+ // that means sub must end in "."+parent.
+ // Do it without allocating.
+ if !strings.HasSuffix(sub, parent) {
+ return false
+ }
+ return sub[len(sub)-len(parent)-1] == '.'
+}
+
+func stripPassword(u *url.URL) string {
+ _, passSet := u.User.Password()
+ if passSet {
+ return strings.Replace(u.String(), u.User.String()+"@", u.User.Username()+":***@", 1)
+ }
+ return u.String()
+}
diff --git a/contrib/go/_std_1.20/src/net/http/clone.go b/contrib/go/_std_1.21/src/net/http/clone.go
index 3a3375bff7..3a3375bff7 100644
--- a/contrib/go/_std_1.20/src/net/http/clone.go
+++ b/contrib/go/_std_1.21/src/net/http/clone.go
diff --git a/contrib/go/_std_1.20/src/net/http/cookie.go b/contrib/go/_std_1.21/src/net/http/cookie.go
index 912fde6b95..912fde6b95 100644
--- a/contrib/go/_std_1.20/src/net/http/cookie.go
+++ b/contrib/go/_std_1.21/src/net/http/cookie.go
diff --git a/contrib/go/_std_1.21/src/net/http/cookiejar/jar.go b/contrib/go/_std_1.21/src/net/http/cookiejar/jar.go
new file mode 100644
index 0000000000..273b54c84c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/cookiejar/jar.go
@@ -0,0 +1,540 @@
+// Copyright 2012 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 cookiejar implements an in-memory RFC 6265-compliant http.CookieJar.
+package cookiejar
+
+import (
+ "errors"
+ "fmt"
+ "net"
+ "net/http"
+ "net/http/internal/ascii"
+ "net/url"
+ "sort"
+ "strings"
+ "sync"
+ "time"
+)
+
+// PublicSuffixList provides the public suffix of a domain. For example:
+// - the public suffix of "example.com" is "com",
+// - the public suffix of "foo1.foo2.foo3.co.uk" is "co.uk", and
+// - the public suffix of "bar.pvt.k12.ma.us" is "pvt.k12.ma.us".
+//
+// Implementations of PublicSuffixList must be safe for concurrent use by
+// multiple goroutines.
+//
+// An implementation that always returns "" is valid and may be useful for
+// testing but it is not secure: it means that the HTTP server for foo.com can
+// set a cookie for bar.com.
+//
+// A public suffix list implementation is in the package
+// golang.org/x/net/publicsuffix.
+type PublicSuffixList interface {
+ // PublicSuffix returns the public suffix of domain.
+ //
+ // TODO: specify which of the caller and callee is responsible for IP
+ // addresses, for leading and trailing dots, for case sensitivity, and
+ // for IDN/Punycode.
+ PublicSuffix(domain string) string
+
+ // String returns a description of the source of this public suffix
+ // list. The description will typically contain something like a time
+ // stamp or version number.
+ String() string
+}
+
+// Options are the options for creating a new Jar.
+type Options struct {
+ // PublicSuffixList is the public suffix list that determines whether
+ // an HTTP server can set a cookie for a domain.
+ //
+ // A nil value is valid and may be useful for testing but it is not
+ // secure: it means that the HTTP server for foo.co.uk can set a cookie
+ // for bar.co.uk.
+ PublicSuffixList PublicSuffixList
+}
+
+// Jar implements the http.CookieJar interface from the net/http package.
+type Jar struct {
+ psList PublicSuffixList
+
+ // mu locks the remaining fields.
+ mu sync.Mutex
+
+ // entries is a set of entries, keyed by their eTLD+1 and subkeyed by
+ // their name/domain/path.
+ entries map[string]map[string]entry
+
+ // nextSeqNum is the next sequence number assigned to a new cookie
+ // created SetCookies.
+ nextSeqNum uint64
+}
+
+// New returns a new cookie jar. A nil *Options is equivalent to a zero
+// Options.
+func New(o *Options) (*Jar, error) {
+ jar := &Jar{
+ entries: make(map[string]map[string]entry),
+ }
+ if o != nil {
+ jar.psList = o.PublicSuffixList
+ }
+ return jar, nil
+}
+
+// entry is the internal representation of a cookie.
+//
+// This struct type is not used outside of this package per se, but the exported
+// fields are those of RFC 6265.
+type entry struct {
+ Name string
+ Value string
+ Domain string
+ Path string
+ SameSite string
+ Secure bool
+ HttpOnly bool
+ Persistent bool
+ HostOnly bool
+ Expires time.Time
+ Creation time.Time
+ LastAccess time.Time
+
+ // seqNum is a sequence number so that Cookies returns cookies in a
+ // deterministic order, even for cookies that have equal Path length and
+ // equal Creation time. This simplifies testing.
+ seqNum uint64
+}
+
+// id returns the domain;path;name triple of e as an id.
+func (e *entry) id() string {
+ return fmt.Sprintf("%s;%s;%s", e.Domain, e.Path, e.Name)
+}
+
+// shouldSend determines whether e's cookie qualifies to be included in a
+// request to host/path. It is the caller's responsibility to check if the
+// cookie is expired.
+func (e *entry) shouldSend(https bool, host, path string) bool {
+ return e.domainMatch(host) && e.pathMatch(path) && (https || !e.Secure)
+}
+
+// domainMatch checks whether e's Domain allows sending e back to host.
+// It differs from "domain-match" of RFC 6265 section 5.1.3 because we treat
+// a cookie with an IP address in the Domain always as a host cookie.
+func (e *entry) domainMatch(host string) bool {
+ if e.Domain == host {
+ return true
+ }
+ return !e.HostOnly && hasDotSuffix(host, e.Domain)
+}
+
+// pathMatch implements "path-match" according to RFC 6265 section 5.1.4.
+func (e *entry) pathMatch(requestPath string) bool {
+ if requestPath == e.Path {
+ return true
+ }
+ if strings.HasPrefix(requestPath, e.Path) {
+ if e.Path[len(e.Path)-1] == '/' {
+ return true // The "/any/" matches "/any/path" case.
+ } else if requestPath[len(e.Path)] == '/' {
+ return true // The "/any" matches "/any/path" case.
+ }
+ }
+ return false
+}
+
+// hasDotSuffix reports whether s ends in "."+suffix.
+func hasDotSuffix(s, suffix string) bool {
+ return len(s) > len(suffix) && s[len(s)-len(suffix)-1] == '.' && s[len(s)-len(suffix):] == suffix
+}
+
+// Cookies implements the Cookies method of the http.CookieJar interface.
+//
+// It returns an empty slice if the URL's scheme is not HTTP or HTTPS.
+func (j *Jar) Cookies(u *url.URL) (cookies []*http.Cookie) {
+ return j.cookies(u, time.Now())
+}
+
+// cookies is like Cookies but takes the current time as a parameter.
+func (j *Jar) cookies(u *url.URL, now time.Time) (cookies []*http.Cookie) {
+ if u.Scheme != "http" && u.Scheme != "https" {
+ return cookies
+ }
+ host, err := canonicalHost(u.Host)
+ if err != nil {
+ return cookies
+ }
+ key := jarKey(host, j.psList)
+
+ j.mu.Lock()
+ defer j.mu.Unlock()
+
+ submap := j.entries[key]
+ if submap == nil {
+ return cookies
+ }
+
+ https := u.Scheme == "https"
+ path := u.Path
+ if path == "" {
+ path = "/"
+ }
+
+ modified := false
+ var selected []entry
+ for id, e := range submap {
+ if e.Persistent && !e.Expires.After(now) {
+ delete(submap, id)
+ modified = true
+ continue
+ }
+ if !e.shouldSend(https, host, path) {
+ continue
+ }
+ e.LastAccess = now
+ submap[id] = e
+ selected = append(selected, e)
+ modified = true
+ }
+ if modified {
+ if len(submap) == 0 {
+ delete(j.entries, key)
+ } else {
+ j.entries[key] = submap
+ }
+ }
+
+ // sort according to RFC 6265 section 5.4 point 2: by longest
+ // path and then by earliest creation time.
+ sort.Slice(selected, func(i, j int) bool {
+ s := selected
+ if len(s[i].Path) != len(s[j].Path) {
+ return len(s[i].Path) > len(s[j].Path)
+ }
+ if ret := s[i].Creation.Compare(s[j].Creation); ret != 0 {
+ return ret < 0
+ }
+ return s[i].seqNum < s[j].seqNum
+ })
+ for _, e := range selected {
+ cookies = append(cookies, &http.Cookie{Name: e.Name, Value: e.Value})
+ }
+
+ return cookies
+}
+
+// SetCookies implements the SetCookies method of the http.CookieJar interface.
+//
+// It does nothing if the URL's scheme is not HTTP or HTTPS.
+func (j *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) {
+ j.setCookies(u, cookies, time.Now())
+}
+
+// setCookies is like SetCookies but takes the current time as parameter.
+func (j *Jar) setCookies(u *url.URL, cookies []*http.Cookie, now time.Time) {
+ if len(cookies) == 0 {
+ return
+ }
+ if u.Scheme != "http" && u.Scheme != "https" {
+ return
+ }
+ host, err := canonicalHost(u.Host)
+ if err != nil {
+ return
+ }
+ key := jarKey(host, j.psList)
+ defPath := defaultPath(u.Path)
+
+ j.mu.Lock()
+ defer j.mu.Unlock()
+
+ submap := j.entries[key]
+
+ modified := false
+ for _, cookie := range cookies {
+ e, remove, err := j.newEntry(cookie, now, defPath, host)
+ if err != nil {
+ continue
+ }
+ id := e.id()
+ if remove {
+ if submap != nil {
+ if _, ok := submap[id]; ok {
+ delete(submap, id)
+ modified = true
+ }
+ }
+ continue
+ }
+ if submap == nil {
+ submap = make(map[string]entry)
+ }
+
+ if old, ok := submap[id]; ok {
+ e.Creation = old.Creation
+ e.seqNum = old.seqNum
+ } else {
+ e.Creation = now
+ e.seqNum = j.nextSeqNum
+ j.nextSeqNum++
+ }
+ e.LastAccess = now
+ submap[id] = e
+ modified = true
+ }
+
+ if modified {
+ if len(submap) == 0 {
+ delete(j.entries, key)
+ } else {
+ j.entries[key] = submap
+ }
+ }
+}
+
+// canonicalHost strips port from host if present and returns the canonicalized
+// host name.
+func canonicalHost(host string) (string, error) {
+ var err error
+ if hasPort(host) {
+ host, _, err = net.SplitHostPort(host)
+ if err != nil {
+ return "", err
+ }
+ }
+ // Strip trailing dot from fully qualified domain names.
+ host = strings.TrimSuffix(host, ".")
+ encoded, err := toASCII(host)
+ if err != nil {
+ return "", err
+ }
+ // We know this is ascii, no need to check.
+ lower, _ := ascii.ToLower(encoded)
+ return lower, nil
+}
+
+// hasPort reports whether host contains a port number. host may be a host
+// name, an IPv4 or an IPv6 address.
+func hasPort(host string) bool {
+ colons := strings.Count(host, ":")
+ if colons == 0 {
+ return false
+ }
+ if colons == 1 {
+ return true
+ }
+ return host[0] == '[' && strings.Contains(host, "]:")
+}
+
+// jarKey returns the key to use for a jar.
+func jarKey(host string, psl PublicSuffixList) string {
+ if isIP(host) {
+ return host
+ }
+
+ var i int
+ if psl == nil {
+ i = strings.LastIndex(host, ".")
+ if i <= 0 {
+ return host
+ }
+ } else {
+ suffix := psl.PublicSuffix(host)
+ if suffix == host {
+ return host
+ }
+ i = len(host) - len(suffix)
+ if i <= 0 || host[i-1] != '.' {
+ // The provided public suffix list psl is broken.
+ // Storing cookies under host is a safe stopgap.
+ return host
+ }
+ // Only len(suffix) is used to determine the jar key from
+ // here on, so it is okay if psl.PublicSuffix("www.buggy.psl")
+ // returns "com" as the jar key is generated from host.
+ }
+ prevDot := strings.LastIndex(host[:i-1], ".")
+ return host[prevDot+1:]
+}
+
+// isIP reports whether host is an IP address.
+func isIP(host string) bool {
+ return net.ParseIP(host) != nil
+}
+
+// defaultPath returns the directory part of a URL's path according to
+// RFC 6265 section 5.1.4.
+func defaultPath(path string) string {
+ if len(path) == 0 || path[0] != '/' {
+ return "/" // Path is empty or malformed.
+ }
+
+ i := strings.LastIndex(path, "/") // Path starts with "/", so i != -1.
+ if i == 0 {
+ return "/" // Path has the form "/abc".
+ }
+ return path[:i] // Path is either of form "/abc/xyz" or "/abc/xyz/".
+}
+
+// newEntry creates an entry from an http.Cookie c. now is the current time and
+// is compared to c.Expires to determine deletion of c. defPath and host are the
+// default-path and the canonical host name of the URL c was received from.
+//
+// remove records whether the jar should delete this cookie, as it has already
+// expired with respect to now. In this case, e may be incomplete, but it will
+// be valid to call e.id (which depends on e's Name, Domain and Path).
+//
+// A malformed c.Domain will result in an error.
+func (j *Jar) newEntry(c *http.Cookie, now time.Time, defPath, host string) (e entry, remove bool, err error) {
+ e.Name = c.Name
+
+ if c.Path == "" || c.Path[0] != '/' {
+ e.Path = defPath
+ } else {
+ e.Path = c.Path
+ }
+
+ e.Domain, e.HostOnly, err = j.domainAndType(host, c.Domain)
+ if err != nil {
+ return e, false, err
+ }
+
+ // MaxAge takes precedence over Expires.
+ if c.MaxAge < 0 {
+ return e, true, nil
+ } else if c.MaxAge > 0 {
+ e.Expires = now.Add(time.Duration(c.MaxAge) * time.Second)
+ e.Persistent = true
+ } else {
+ if c.Expires.IsZero() {
+ e.Expires = endOfTime
+ e.Persistent = false
+ } else {
+ if !c.Expires.After(now) {
+ return e, true, nil
+ }
+ e.Expires = c.Expires
+ e.Persistent = true
+ }
+ }
+
+ e.Value = c.Value
+ e.Secure = c.Secure
+ e.HttpOnly = c.HttpOnly
+
+ switch c.SameSite {
+ case http.SameSiteDefaultMode:
+ e.SameSite = "SameSite"
+ case http.SameSiteStrictMode:
+ e.SameSite = "SameSite=Strict"
+ case http.SameSiteLaxMode:
+ e.SameSite = "SameSite=Lax"
+ }
+
+ return e, false, nil
+}
+
+var (
+ errIllegalDomain = errors.New("cookiejar: illegal cookie domain attribute")
+ errMalformedDomain = errors.New("cookiejar: malformed cookie domain attribute")
+ errNoHostname = errors.New("cookiejar: no host name available (IP only)")
+)
+
+// endOfTime is the time when session (non-persistent) cookies expire.
+// This instant is representable in most date/time formats (not just
+// Go's time.Time) and should be far enough in the future.
+var endOfTime = time.Date(9999, 12, 31, 23, 59, 59, 0, time.UTC)
+
+// domainAndType determines the cookie's domain and hostOnly attribute.
+func (j *Jar) domainAndType(host, domain string) (string, bool, error) {
+ if domain == "" {
+ // No domain attribute in the SetCookie header indicates a
+ // host cookie.
+ return host, true, nil
+ }
+
+ if isIP(host) {
+ // RFC 6265 is not super clear here, a sensible interpretation
+ // is that cookies with an IP address in the domain-attribute
+ // are allowed.
+
+ // RFC 6265 section 5.2.3 mandates to strip an optional leading
+ // dot in the domain-attribute before processing the cookie.
+ //
+ // Most browsers don't do that for IP addresses, only curl
+ // (version 7.54) and IE (version 11) do not reject a
+ // Set-Cookie: a=1; domain=.127.0.0.1
+ // This leading dot is optional and serves only as hint for
+ // humans to indicate that a cookie with "domain=.bbc.co.uk"
+ // would be sent to every subdomain of bbc.co.uk.
+ // It just doesn't make sense on IP addresses.
+ // The other processing and validation steps in RFC 6265 just
+ // collapse to:
+ if host != domain {
+ return "", false, errIllegalDomain
+ }
+
+ // According to RFC 6265 such cookies should be treated as
+ // domain cookies.
+ // As there are no subdomains of an IP address the treatment
+ // according to RFC 6265 would be exactly the same as that of
+ // a host-only cookie. Contemporary browsers (and curl) do
+ // allows such cookies but treat them as host-only cookies.
+ // So do we as it just doesn't make sense to label them as
+ // domain cookies when there is no domain; the whole notion of
+ // domain cookies requires a domain name to be well defined.
+ return host, true, nil
+ }
+
+ // From here on: If the cookie is valid, it is a domain cookie (with
+ // the one exception of a public suffix below).
+ // See RFC 6265 section 5.2.3.
+ if domain[0] == '.' {
+ domain = domain[1:]
+ }
+
+ if len(domain) == 0 || domain[0] == '.' {
+ // Received either "Domain=." or "Domain=..some.thing",
+ // both are illegal.
+ return "", false, errMalformedDomain
+ }
+
+ domain, isASCII := ascii.ToLower(domain)
+ if !isASCII {
+ // Received non-ASCII domain, e.g. "perché.com" instead of "xn--perch-fsa.com"
+ return "", false, errMalformedDomain
+ }
+
+ if domain[len(domain)-1] == '.' {
+ // We received stuff like "Domain=www.example.com.".
+ // Browsers do handle such stuff (actually differently) but
+ // RFC 6265 seems to be clear here (e.g. section 4.1.2.3) in
+ // requiring a reject. 4.1.2.3 is not normative, but
+ // "Domain Matching" (5.1.3) and "Canonicalized Host Names"
+ // (5.1.2) are.
+ return "", false, errMalformedDomain
+ }
+
+ // See RFC 6265 section 5.3 #5.
+ if j.psList != nil {
+ if ps := j.psList.PublicSuffix(domain); ps != "" && !hasDotSuffix(domain, ps) {
+ if host == domain {
+ // This is the one exception in which a cookie
+ // with a domain attribute is a host cookie.
+ return host, true, nil
+ }
+ return "", false, errIllegalDomain
+ }
+ }
+
+ // The domain must domain-match host: www.mycompany.com cannot
+ // set cookies for .ourcompetitors.com.
+ if host != domain && !hasDotSuffix(host, domain) {
+ return "", false, errIllegalDomain
+ }
+
+ return domain, false, nil
+}
diff --git a/contrib/go/_std_1.20/src/net/http/cookiejar/punycode.go b/contrib/go/_std_1.21/src/net/http/cookiejar/punycode.go
index c7f438dd00..c7f438dd00 100644
--- a/contrib/go/_std_1.20/src/net/http/cookiejar/punycode.go
+++ b/contrib/go/_std_1.21/src/net/http/cookiejar/punycode.go
diff --git a/contrib/go/_std_1.21/src/net/http/cookiejar/ya.make b/contrib/go/_std_1.21/src/net/http/cookiejar/ya.make
new file mode 100644
index 0000000000..6ae3951627
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/cookiejar/ya.make
@@ -0,0 +1,21 @@
+GO_LIBRARY()
+
+SRCS(
+ jar.go
+ punycode.go
+)
+
+GO_TEST_SRCS(
+ jar_test.go
+ punycode_test.go
+)
+
+GO_XTEST_SRCS(
+ dummy_publicsuffix_test.go
+ example_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/net/http/doc.go b/contrib/go/_std_1.21/src/net/http/doc.go
new file mode 100644
index 0000000000..d9e6aafb4e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/doc.go
@@ -0,0 +1,110 @@
+// Copyright 2011 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 http provides HTTP client and server implementations.
+
+Get, Head, Post, and PostForm make HTTP (or HTTPS) requests:
+
+ resp, err := http.Get("http://example.com/")
+ ...
+ resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
+ ...
+ resp, err := http.PostForm("http://example.com/form",
+ url.Values{"key": {"Value"}, "id": {"123"}})
+
+The caller must close the response body when finished with it:
+
+ resp, err := http.Get("http://example.com/")
+ if err != nil {
+ // handle error
+ }
+ defer resp.Body.Close()
+ body, err := io.ReadAll(resp.Body)
+ // ...
+
+# Clients and Transports
+
+For control over HTTP client headers, redirect policy, and other
+settings, create a Client:
+
+ client := &http.Client{
+ CheckRedirect: redirectPolicyFunc,
+ }
+
+ resp, err := client.Get("http://example.com")
+ // ...
+
+ req, err := http.NewRequest("GET", "http://example.com", nil)
+ // ...
+ req.Header.Add("If-None-Match", `W/"wyzzy"`)
+ resp, err := client.Do(req)
+ // ...
+
+For control over proxies, TLS configuration, keep-alives,
+compression, and other settings, create a Transport:
+
+ tr := &http.Transport{
+ MaxIdleConns: 10,
+ IdleConnTimeout: 30 * time.Second,
+ DisableCompression: true,
+ }
+ client := &http.Client{Transport: tr}
+ resp, err := client.Get("https://example.com")
+
+Clients and Transports are safe for concurrent use by multiple
+goroutines and for efficiency should only be created once and re-used.
+
+# Servers
+
+ListenAndServe starts an HTTP server with a given address and handler.
+The handler is usually nil, which means to use DefaultServeMux.
+Handle and HandleFunc add handlers to DefaultServeMux:
+
+ http.Handle("/foo", fooHandler)
+
+ http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
+ fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
+ })
+
+ log.Fatal(http.ListenAndServe(":8080", nil))
+
+More control over the server's behavior is available by creating a
+custom Server:
+
+ s := &http.Server{
+ Addr: ":8080",
+ Handler: myHandler,
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ MaxHeaderBytes: 1 << 20,
+ }
+ log.Fatal(s.ListenAndServe())
+
+# HTTP/2
+
+Starting with Go 1.6, the http package has transparent support for the
+HTTP/2 protocol when using HTTPS. Programs that must disable HTTP/2
+can do so by setting Transport.TLSNextProto (for clients) or
+Server.TLSNextProto (for servers) to a non-nil, empty
+map. Alternatively, the following GODEBUG settings are
+currently supported:
+
+ GODEBUG=http2client=0 # disable HTTP/2 client support
+ GODEBUG=http2server=0 # disable HTTP/2 server support
+ GODEBUG=http2debug=1 # enable verbose HTTP/2 debug logs
+ GODEBUG=http2debug=2 # ... even more verbose, with frame dumps
+
+Please report any issues before disabling HTTP/2 support: https://golang.org/s/http2bug
+
+The http package's Transport and Server both automatically enable
+HTTP/2 support for simple configurations. To enable HTTP/2 for more
+complex configurations, to use lower-level HTTP/2 features, or to use
+a newer version of Go's http2 package, import "golang.org/x/net/http2"
+directly and use its ConfigureTransport and/or ConfigureServer
+functions. Manually configuring HTTP/2 via the golang.org/x/net/http2
+package takes precedence over the net/http package's built-in HTTP/2
+support.
+*/
+package http
diff --git a/contrib/go/_std_1.20/src/net/http/fcgi/child.go b/contrib/go/_std_1.21/src/net/http/fcgi/child.go
index dc82bf7c3a..dc82bf7c3a 100644
--- a/contrib/go/_std_1.20/src/net/http/fcgi/child.go
+++ b/contrib/go/_std_1.21/src/net/http/fcgi/child.go
diff --git a/contrib/go/_std_1.21/src/net/http/fcgi/fcgi.go b/contrib/go/_std_1.21/src/net/http/fcgi/fcgi.go
new file mode 100644
index 0000000000..56f7d40789
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/fcgi/fcgi.go
@@ -0,0 +1,277 @@
+// Copyright 2011 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 fcgi implements the FastCGI protocol.
+//
+// See https://fast-cgi.github.io/ for an unofficial mirror of the
+// original documentation.
+//
+// Currently only the responder role is supported.
+package fcgi
+
+// This file defines the raw protocol and some utilities used by the child and
+// the host.
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "io"
+ "sync"
+)
+
+// recType is a record type, as defined by
+// https://web.archive.org/web/20150420080736/http://www.fastcgi.com/drupal/node/6?q=node/22#S8
+type recType uint8
+
+const (
+ typeBeginRequest recType = 1
+ typeAbortRequest recType = 2
+ typeEndRequest recType = 3
+ typeParams recType = 4
+ typeStdin recType = 5
+ typeStdout recType = 6
+ typeStderr recType = 7
+ typeData recType = 8
+ typeGetValues recType = 9
+ typeGetValuesResult recType = 10
+ typeUnknownType recType = 11
+)
+
+// keep the connection between web-server and responder open after request
+const flagKeepConn = 1
+
+const (
+ maxWrite = 65535 // maximum record body
+ maxPad = 255
+)
+
+const (
+ roleResponder = iota + 1 // only Responders are implemented.
+ roleAuthorizer
+ roleFilter
+)
+
+const (
+ statusRequestComplete = iota
+ statusCantMultiplex
+ statusOverloaded
+ statusUnknownRole
+)
+
+type header struct {
+ Version uint8
+ Type recType
+ Id uint16
+ ContentLength uint16
+ PaddingLength uint8
+ Reserved uint8
+}
+
+type beginRequest struct {
+ role uint16
+ flags uint8
+ reserved [5]uint8
+}
+
+func (br *beginRequest) read(content []byte) error {
+ if len(content) != 8 {
+ return errors.New("fcgi: invalid begin request record")
+ }
+ br.role = binary.BigEndian.Uint16(content)
+ br.flags = content[2]
+ return nil
+}
+
+// for padding so we don't have to allocate all the time
+// not synchronized because we don't care what the contents are
+var pad [maxPad]byte
+
+func (h *header) init(recType recType, reqId uint16, contentLength int) {
+ h.Version = 1
+ h.Type = recType
+ h.Id = reqId
+ h.ContentLength = uint16(contentLength)
+ h.PaddingLength = uint8(-contentLength & 7)
+}
+
+// conn sends records over rwc
+type conn struct {
+ mutex sync.Mutex
+ rwc io.ReadWriteCloser
+ closeErr error
+ closed bool
+
+ // to avoid allocations
+ buf bytes.Buffer
+ h header
+}
+
+func newConn(rwc io.ReadWriteCloser) *conn {
+ return &conn{rwc: rwc}
+}
+
+// Close closes the conn if it is not already closed.
+func (c *conn) Close() error {
+ c.mutex.Lock()
+ defer c.mutex.Unlock()
+ if !c.closed {
+ c.closeErr = c.rwc.Close()
+ c.closed = true
+ }
+ return c.closeErr
+}
+
+type record struct {
+ h header
+ buf [maxWrite + maxPad]byte
+}
+
+func (rec *record) read(r io.Reader) (err error) {
+ if err = binary.Read(r, binary.BigEndian, &rec.h); err != nil {
+ return err
+ }
+ if rec.h.Version != 1 {
+ return errors.New("fcgi: invalid header version")
+ }
+ n := int(rec.h.ContentLength) + int(rec.h.PaddingLength)
+ if _, err = io.ReadFull(r, rec.buf[:n]); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (r *record) content() []byte {
+ return r.buf[:r.h.ContentLength]
+}
+
+// writeRecord writes and sends a single record.
+func (c *conn) writeRecord(recType recType, reqId uint16, b []byte) error {
+ c.mutex.Lock()
+ defer c.mutex.Unlock()
+ c.buf.Reset()
+ c.h.init(recType, reqId, len(b))
+ if err := binary.Write(&c.buf, binary.BigEndian, c.h); err != nil {
+ return err
+ }
+ if _, err := c.buf.Write(b); err != nil {
+ return err
+ }
+ if _, err := c.buf.Write(pad[:c.h.PaddingLength]); err != nil {
+ return err
+ }
+ _, err := c.rwc.Write(c.buf.Bytes())
+ return err
+}
+
+func (c *conn) writeEndRequest(reqId uint16, appStatus int, protocolStatus uint8) error {
+ b := make([]byte, 8)
+ binary.BigEndian.PutUint32(b, uint32(appStatus))
+ b[4] = protocolStatus
+ return c.writeRecord(typeEndRequest, reqId, b)
+}
+
+func (c *conn) writePairs(recType recType, reqId uint16, pairs map[string]string) error {
+ w := newWriter(c, recType, reqId)
+ b := make([]byte, 8)
+ for k, v := range pairs {
+ n := encodeSize(b, uint32(len(k)))
+ n += encodeSize(b[n:], uint32(len(v)))
+ if _, err := w.Write(b[:n]); err != nil {
+ return err
+ }
+ if _, err := w.WriteString(k); err != nil {
+ return err
+ }
+ if _, err := w.WriteString(v); err != nil {
+ return err
+ }
+ }
+ w.Close()
+ return nil
+}
+
+func readSize(s []byte) (uint32, int) {
+ if len(s) == 0 {
+ return 0, 0
+ }
+ size, n := uint32(s[0]), 1
+ if size&(1<<7) != 0 {
+ if len(s) < 4 {
+ return 0, 0
+ }
+ n = 4
+ size = binary.BigEndian.Uint32(s)
+ size &^= 1 << 31
+ }
+ return size, n
+}
+
+func readString(s []byte, size uint32) string {
+ if size > uint32(len(s)) {
+ return ""
+ }
+ return string(s[:size])
+}
+
+func encodeSize(b []byte, size uint32) int {
+ if size > 127 {
+ size |= 1 << 31
+ binary.BigEndian.PutUint32(b, size)
+ return 4
+ }
+ b[0] = byte(size)
+ return 1
+}
+
+// bufWriter encapsulates bufio.Writer but also closes the underlying stream when
+// Closed.
+type bufWriter struct {
+ closer io.Closer
+ *bufio.Writer
+}
+
+func (w *bufWriter) Close() error {
+ if err := w.Writer.Flush(); err != nil {
+ w.closer.Close()
+ return err
+ }
+ return w.closer.Close()
+}
+
+func newWriter(c *conn, recType recType, reqId uint16) *bufWriter {
+ s := &streamWriter{c: c, recType: recType, reqId: reqId}
+ w := bufio.NewWriterSize(s, maxWrite)
+ return &bufWriter{s, w}
+}
+
+// streamWriter abstracts out the separation of a stream into discrete records.
+// It only writes maxWrite bytes at a time.
+type streamWriter struct {
+ c *conn
+ recType recType
+ reqId uint16
+}
+
+func (w *streamWriter) Write(p []byte) (int, error) {
+ nn := 0
+ for len(p) > 0 {
+ n := len(p)
+ if n > maxWrite {
+ n = maxWrite
+ }
+ if err := w.c.writeRecord(w.recType, w.reqId, p[:n]); err != nil {
+ return nn, err
+ }
+ nn += n
+ p = p[n:]
+ }
+ return nn, nil
+}
+
+func (w *streamWriter) Close() error {
+ // send empty record to close the stream
+ return w.c.writeRecord(w.recType, w.reqId, nil)
+}
diff --git a/contrib/go/_std_1.21/src/net/http/fcgi/ya.make b/contrib/go/_std_1.21/src/net/http/fcgi/ya.make
new file mode 100644
index 0000000000..cb757dc801
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/fcgi/ya.make
@@ -0,0 +1,13 @@
+GO_LIBRARY()
+
+SRCS(
+ child.go
+ fcgi.go
+)
+
+GO_TEST_SRCS(fcgi_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/net/http/filetransport.go b/contrib/go/_std_1.21/src/net/http/filetransport.go
index 94684b07a1..94684b07a1 100644
--- a/contrib/go/_std_1.20/src/net/http/filetransport.go
+++ b/contrib/go/_std_1.21/src/net/http/filetransport.go
diff --git a/contrib/go/_std_1.20/src/net/http/fs.go b/contrib/go/_std_1.21/src/net/http/fs.go
index 41e0b43ac8..41e0b43ac8 100644
--- a/contrib/go/_std_1.20/src/net/http/fs.go
+++ b/contrib/go/_std_1.21/src/net/http/fs.go
diff --git a/contrib/go/_std_1.21/src/net/http/h2_bundle.go b/contrib/go/_std_1.21/src/net/http/h2_bundle.go
new file mode 100644
index 0000000000..9cd6a3490f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/h2_bundle.go
@@ -0,0 +1,11492 @@
+//go:build !nethttpomithttp2
+// +build !nethttpomithttp2
+
+// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
+// $ bundle -o=h2_bundle.go -prefix=http2 -tags=!nethttpomithttp2 golang.org/x/net/http2
+
+// Package http2 implements the HTTP/2 protocol.
+//
+// This package is low-level and intended to be used directly by very
+// few people. Most users will use it indirectly through the automatic
+// use by the net/http package (from Go 1.6 and later).
+// For use in earlier Go versions see ConfigureServer. (Transport support
+// requires Go 1.6 or later)
+//
+// See https://http2.github.io/ for more information on HTTP/2.
+//
+// See https://http2.golang.org/ for a test server running this code.
+//
+
+package http
+
+import (
+ "bufio"
+ "bytes"
+ "compress/gzip"
+ "context"
+ "crypto/rand"
+ "crypto/tls"
+ "encoding/binary"
+ "errors"
+ "fmt"
+ "io"
+ "io/fs"
+ "log"
+ "math"
+ mathrand "math/rand"
+ "net"
+ "net/http/httptrace"
+ "net/textproto"
+ "net/url"
+ "os"
+ "reflect"
+ "runtime"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "golang.org/x/net/http/httpguts"
+ "golang.org/x/net/http2/hpack"
+ "golang.org/x/net/idna"
+)
+
+// The HTTP protocols are defined in terms of ASCII, not Unicode. This file
+// contains helper functions which may use Unicode-aware functions which would
+// otherwise be unsafe and could introduce vulnerabilities if used improperly.
+
+// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t
+// are equal, ASCII-case-insensitively.
+func http2asciiEqualFold(s, t string) bool {
+ if len(s) != len(t) {
+ return false
+ }
+ for i := 0; i < len(s); i++ {
+ if http2lower(s[i]) != http2lower(t[i]) {
+ return false
+ }
+ }
+ return true
+}
+
+// lower returns the ASCII lowercase version of b.
+func http2lower(b byte) byte {
+ if 'A' <= b && b <= 'Z' {
+ return b + ('a' - 'A')
+ }
+ return b
+}
+
+// isASCIIPrint returns whether s is ASCII and printable according to
+// https://tools.ietf.org/html/rfc20#section-4.2.
+func http2isASCIIPrint(s string) bool {
+ for i := 0; i < len(s); i++ {
+ if s[i] < ' ' || s[i] > '~' {
+ return false
+ }
+ }
+ return true
+}
+
+// asciiToLower returns the lowercase version of s if s is ASCII and printable,
+// and whether or not it was.
+func http2asciiToLower(s string) (lower string, ok bool) {
+ if !http2isASCIIPrint(s) {
+ return "", false
+ }
+ return strings.ToLower(s), true
+}
+
+// A list of the possible cipher suite ids. Taken from
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.txt
+
+const (
+ http2cipher_TLS_NULL_WITH_NULL_NULL uint16 = 0x0000
+ http2cipher_TLS_RSA_WITH_NULL_MD5 uint16 = 0x0001
+ http2cipher_TLS_RSA_WITH_NULL_SHA uint16 = 0x0002
+ http2cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0003
+ http2cipher_TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004
+ http2cipher_TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
+ http2cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x0006
+ http2cipher_TLS_RSA_WITH_IDEA_CBC_SHA uint16 = 0x0007
+ http2cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0008
+ http2cipher_TLS_RSA_WITH_DES_CBC_SHA uint16 = 0x0009
+ http2cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000A
+ http2cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000B
+ http2cipher_TLS_DH_DSS_WITH_DES_CBC_SHA uint16 = 0x000C
+ http2cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x000D
+ http2cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x000E
+ http2cipher_TLS_DH_RSA_WITH_DES_CBC_SHA uint16 = 0x000F
+ http2cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0010
+ http2cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0011
+ http2cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA uint16 = 0x0012
+ http2cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0x0013
+ http2cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0014
+ http2cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA uint16 = 0x0015
+ http2cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x0016
+ http2cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 uint16 = 0x0017
+ http2cipher_TLS_DH_anon_WITH_RC4_128_MD5 uint16 = 0x0018
+ http2cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0019
+ http2cipher_TLS_DH_anon_WITH_DES_CBC_SHA uint16 = 0x001A
+ http2cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0x001B
+ // Reserved uint16 = 0x001C-1D
+ http2cipher_TLS_KRB5_WITH_DES_CBC_SHA uint16 = 0x001E
+ http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA uint16 = 0x001F
+ http2cipher_TLS_KRB5_WITH_RC4_128_SHA uint16 = 0x0020
+ http2cipher_TLS_KRB5_WITH_IDEA_CBC_SHA uint16 = 0x0021
+ http2cipher_TLS_KRB5_WITH_DES_CBC_MD5 uint16 = 0x0022
+ http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5 uint16 = 0x0023
+ http2cipher_TLS_KRB5_WITH_RC4_128_MD5 uint16 = 0x0024
+ http2cipher_TLS_KRB5_WITH_IDEA_CBC_MD5 uint16 = 0x0025
+ http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA uint16 = 0x0026
+ http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA uint16 = 0x0027
+ http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA uint16 = 0x0028
+ http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 uint16 = 0x0029
+ http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 uint16 = 0x002A
+ http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5 uint16 = 0x002B
+ http2cipher_TLS_PSK_WITH_NULL_SHA uint16 = 0x002C
+ http2cipher_TLS_DHE_PSK_WITH_NULL_SHA uint16 = 0x002D
+ http2cipher_TLS_RSA_PSK_WITH_NULL_SHA uint16 = 0x002E
+ http2cipher_TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002F
+ http2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0030
+ http2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0031
+ http2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA uint16 = 0x0032
+ http2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0x0033
+ http2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA uint16 = 0x0034
+ http2cipher_TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
+ http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0036
+ http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0037
+ http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA uint16 = 0x0038
+ http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0039
+ http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA uint16 = 0x003A
+ http2cipher_TLS_RSA_WITH_NULL_SHA256 uint16 = 0x003B
+ http2cipher_TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003C
+ http2cipher_TLS_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x003D
+ http2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x003E
+ http2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003F
+ http2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 uint16 = 0x0040
+ http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0041
+ http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0042
+ http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0043
+ http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0044
+ http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0045
+ http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0046
+ // Reserved uint16 = 0x0047-4F
+ // Reserved uint16 = 0x0050-58
+ // Reserved uint16 = 0x0059-5C
+ // Unassigned uint16 = 0x005D-5F
+ // Reserved uint16 = 0x0060-66
+ http2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067
+ http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x0068
+ http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x0069
+ http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x006A
+ http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006B
+ http2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256 uint16 = 0x006C
+ http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256 uint16 = 0x006D
+ // Unassigned uint16 = 0x006E-83
+ http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0084
+ http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0085
+ http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0086
+ http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0087
+ http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0088
+ http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA uint16 = 0x0089
+ http2cipher_TLS_PSK_WITH_RC4_128_SHA uint16 = 0x008A
+ http2cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008B
+ http2cipher_TLS_PSK_WITH_AES_128_CBC_SHA uint16 = 0x008C
+ http2cipher_TLS_PSK_WITH_AES_256_CBC_SHA uint16 = 0x008D
+ http2cipher_TLS_DHE_PSK_WITH_RC4_128_SHA uint16 = 0x008E
+ http2cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x008F
+ http2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0090
+ http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0091
+ http2cipher_TLS_RSA_PSK_WITH_RC4_128_SHA uint16 = 0x0092
+ http2cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0x0093
+ http2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA uint16 = 0x0094
+ http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA uint16 = 0x0095
+ http2cipher_TLS_RSA_WITH_SEED_CBC_SHA uint16 = 0x0096
+ http2cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA uint16 = 0x0097
+ http2cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA uint16 = 0x0098
+ http2cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA uint16 = 0x0099
+ http2cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA uint16 = 0x009A
+ http2cipher_TLS_DH_anon_WITH_SEED_CBC_SHA uint16 = 0x009B
+ http2cipher_TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009C
+ http2cipher_TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009D
+ http2cipher_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009E
+ http2cipher_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009F
+ http2cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x00A0
+ http2cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x00A1
+ http2cipher_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A2
+ http2cipher_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A3
+ http2cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256 uint16 = 0x00A4
+ http2cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384 uint16 = 0x00A5
+ http2cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256 uint16 = 0x00A6
+ http2cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384 uint16 = 0x00A7
+ http2cipher_TLS_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00A8
+ http2cipher_TLS_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00A9
+ http2cipher_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AA
+ http2cipher_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AB
+ http2cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0x00AC
+ http2cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 uint16 = 0x00AD
+ http2cipher_TLS_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00AE
+ http2cipher_TLS_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00AF
+ http2cipher_TLS_PSK_WITH_NULL_SHA256 uint16 = 0x00B0
+ http2cipher_TLS_PSK_WITH_NULL_SHA384 uint16 = 0x00B1
+ http2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B2
+ http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B3
+ http2cipher_TLS_DHE_PSK_WITH_NULL_SHA256 uint16 = 0x00B4
+ http2cipher_TLS_DHE_PSK_WITH_NULL_SHA384 uint16 = 0x00B5
+ http2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0x00B6
+ http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0x00B7
+ http2cipher_TLS_RSA_PSK_WITH_NULL_SHA256 uint16 = 0x00B8
+ http2cipher_TLS_RSA_PSK_WITH_NULL_SHA384 uint16 = 0x00B9
+ http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BA
+ http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BB
+ http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BC
+ http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BD
+ http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BE
+ http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BF
+ http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C0
+ http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C1
+ http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C2
+ http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C3
+ http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C4
+ http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C5
+ // Unassigned uint16 = 0x00C6-FE
+ http2cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV uint16 = 0x00FF
+ // Unassigned uint16 = 0x01-55,*
+ http2cipher_TLS_FALLBACK_SCSV uint16 = 0x5600
+ // Unassigned uint16 = 0x5601 - 0xC000
+ http2cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA uint16 = 0xC001
+ http2cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA uint16 = 0xC002
+ http2cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC003
+ http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC004
+ http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC005
+ http2cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA uint16 = 0xC006
+ http2cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xC007
+ http2cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC008
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xC009
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xC00A
+ http2cipher_TLS_ECDH_RSA_WITH_NULL_SHA uint16 = 0xC00B
+ http2cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA uint16 = 0xC00C
+ http2cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC00D
+ http2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC00E
+ http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC00F
+ http2cipher_TLS_ECDHE_RSA_WITH_NULL_SHA uint16 = 0xC010
+ http2cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xC011
+ http2cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC012
+ http2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC013
+ http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC014
+ http2cipher_TLS_ECDH_anon_WITH_NULL_SHA uint16 = 0xC015
+ http2cipher_TLS_ECDH_anon_WITH_RC4_128_SHA uint16 = 0xC016
+ http2cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA uint16 = 0xC017
+ http2cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA uint16 = 0xC018
+ http2cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA uint16 = 0xC019
+ http2cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01A
+ http2cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01B
+ http2cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA uint16 = 0xC01C
+ http2cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA uint16 = 0xC01D
+ http2cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA uint16 = 0xC01E
+ http2cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA uint16 = 0xC01F
+ http2cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA uint16 = 0xC020
+ http2cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA uint16 = 0xC021
+ http2cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA uint16 = 0xC022
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC023
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC024
+ http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC025
+ http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC026
+ http2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC027
+ http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC028
+ http2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xC029
+ http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 uint16 = 0xC02A
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02B
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02C
+ http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02D
+ http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC02E
+ http2cipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC02F
+ http2cipher_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC030
+ http2cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xC031
+ http2cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xC032
+ http2cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA uint16 = 0xC033
+ http2cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA uint16 = 0xC034
+ http2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xC035
+ http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xC036
+ http2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 uint16 = 0xC037
+ http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 uint16 = 0xC038
+ http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA uint16 = 0xC039
+ http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256 uint16 = 0xC03A
+ http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384 uint16 = 0xC03B
+ http2cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03C
+ http2cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03D
+ http2cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC03E
+ http2cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC03F
+ http2cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC040
+ http2cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC041
+ http2cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC042
+ http2cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC043
+ http2cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC044
+ http2cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC045
+ http2cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC046
+ http2cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC047
+ http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC048
+ http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC049
+ http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04A
+ http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04B
+ http2cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04C
+ http2cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04D
+ http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC04E
+ http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC04F
+ http2cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC050
+ http2cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC051
+ http2cipher_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC052
+ http2cipher_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC053
+ http2cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC054
+ http2cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC055
+ http2cipher_TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC056
+ http2cipher_TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC057
+ http2cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC058
+ http2cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC059
+ http2cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05A
+ http2cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05B
+ http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05C
+ http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05D
+ http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC05E
+ http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC05F
+ http2cipher_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC060
+ http2cipher_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC061
+ http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC062
+ http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC063
+ http2cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC064
+ http2cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC065
+ http2cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC066
+ http2cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC067
+ http2cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC068
+ http2cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC069
+ http2cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06A
+ http2cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06B
+ http2cipher_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06C
+ http2cipher_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06D
+ http2cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 uint16 = 0xC06E
+ http2cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 uint16 = 0xC06F
+ http2cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 uint16 = 0xC070
+ http2cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 uint16 = 0xC071
+ http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC072
+ http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC073
+ http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC074
+ http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC075
+ http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC076
+ http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC077
+ http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC078
+ http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC079
+ http2cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07A
+ http2cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07B
+ http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07C
+ http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07D
+ http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC07E
+ http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC07F
+ http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC080
+ http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC081
+ http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC082
+ http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC083
+ http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC084
+ http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC085
+ http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC086
+ http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC087
+ http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC088
+ http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC089
+ http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08A
+ http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08B
+ http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08C
+ http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08D
+ http2cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC08E
+ http2cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC08F
+ http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC090
+ http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC091
+ http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC092
+ http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC093
+ http2cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC094
+ http2cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC095
+ http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC096
+ http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC097
+ http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC098
+ http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC099
+ http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC09A
+ http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC09B
+ http2cipher_TLS_RSA_WITH_AES_128_CCM uint16 = 0xC09C
+ http2cipher_TLS_RSA_WITH_AES_256_CCM uint16 = 0xC09D
+ http2cipher_TLS_DHE_RSA_WITH_AES_128_CCM uint16 = 0xC09E
+ http2cipher_TLS_DHE_RSA_WITH_AES_256_CCM uint16 = 0xC09F
+ http2cipher_TLS_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A0
+ http2cipher_TLS_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A1
+ http2cipher_TLS_DHE_RSA_WITH_AES_128_CCM_8 uint16 = 0xC0A2
+ http2cipher_TLS_DHE_RSA_WITH_AES_256_CCM_8 uint16 = 0xC0A3
+ http2cipher_TLS_PSK_WITH_AES_128_CCM uint16 = 0xC0A4
+ http2cipher_TLS_PSK_WITH_AES_256_CCM uint16 = 0xC0A5
+ http2cipher_TLS_DHE_PSK_WITH_AES_128_CCM uint16 = 0xC0A6
+ http2cipher_TLS_DHE_PSK_WITH_AES_256_CCM uint16 = 0xC0A7
+ http2cipher_TLS_PSK_WITH_AES_128_CCM_8 uint16 = 0xC0A8
+ http2cipher_TLS_PSK_WITH_AES_256_CCM_8 uint16 = 0xC0A9
+ http2cipher_TLS_PSK_DHE_WITH_AES_128_CCM_8 uint16 = 0xC0AA
+ http2cipher_TLS_PSK_DHE_WITH_AES_256_CCM_8 uint16 = 0xC0AB
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM uint16 = 0xC0AC
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM uint16 = 0xC0AD
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 uint16 = 0xC0AE
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 uint16 = 0xC0AF
+ // Unassigned uint16 = 0xC0B0-FF
+ // Unassigned uint16 = 0xC1-CB,*
+ // Unassigned uint16 = 0xCC00-A7
+ http2cipher_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA8
+ http2cipher_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA9
+ http2cipher_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAA
+ http2cipher_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAB
+ http2cipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAC
+ http2cipher_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAD
+ http2cipher_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCAE
+)
+
+// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec.
+// References:
+// https://tools.ietf.org/html/rfc7540#appendix-A
+// Reject cipher suites from Appendix A.
+// "This list includes those cipher suites that do not
+// offer an ephemeral key exchange and those that are
+// based on the TLS null, stream or block cipher type"
+func http2isBadCipher(cipher uint16) bool {
+ switch cipher {
+ case http2cipher_TLS_NULL_WITH_NULL_NULL,
+ http2cipher_TLS_RSA_WITH_NULL_MD5,
+ http2cipher_TLS_RSA_WITH_NULL_SHA,
+ http2cipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5,
+ http2cipher_TLS_RSA_WITH_RC4_128_MD5,
+ http2cipher_TLS_RSA_WITH_RC4_128_SHA,
+ http2cipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
+ http2cipher_TLS_RSA_WITH_IDEA_CBC_SHA,
+ http2cipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
+ http2cipher_TLS_RSA_WITH_DES_CBC_SHA,
+ http2cipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
+ http2cipher_TLS_DH_DSS_WITH_DES_CBC_SHA,
+ http2cipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
+ http2cipher_TLS_DH_RSA_WITH_DES_CBC_SHA,
+ http2cipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
+ http2cipher_TLS_DHE_DSS_WITH_DES_CBC_SHA,
+ http2cipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
+ http2cipher_TLS_DHE_RSA_WITH_DES_CBC_SHA,
+ http2cipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5,
+ http2cipher_TLS_DH_anon_WITH_RC4_128_MD5,
+ http2cipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
+ http2cipher_TLS_DH_anon_WITH_DES_CBC_SHA,
+ http2cipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_KRB5_WITH_DES_CBC_SHA,
+ http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_KRB5_WITH_RC4_128_SHA,
+ http2cipher_TLS_KRB5_WITH_IDEA_CBC_SHA,
+ http2cipher_TLS_KRB5_WITH_DES_CBC_MD5,
+ http2cipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5,
+ http2cipher_TLS_KRB5_WITH_RC4_128_MD5,
+ http2cipher_TLS_KRB5_WITH_IDEA_CBC_MD5,
+ http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA,
+ http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA,
+ http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA,
+ http2cipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5,
+ http2cipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5,
+ http2cipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5,
+ http2cipher_TLS_PSK_WITH_NULL_SHA,
+ http2cipher_TLS_DHE_PSK_WITH_NULL_SHA,
+ http2cipher_TLS_RSA_PSK_WITH_NULL_SHA,
+ http2cipher_TLS_RSA_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_RSA_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_RSA_WITH_NULL_SHA256,
+ http2cipher_TLS_RSA_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_RSA_WITH_AES_256_CBC_SHA256,
+ http2cipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
+ http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
+ http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
+ http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
+ http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
+ http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,
+ http2cipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256,
+ http2cipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256,
+ http2cipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,
+ http2cipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
+ http2cipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256,
+ http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
+ http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
+ http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
+ http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
+ http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
+ http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA,
+ http2cipher_TLS_PSK_WITH_RC4_128_SHA,
+ http2cipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_PSK_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_PSK_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_DHE_PSK_WITH_RC4_128_SHA,
+ http2cipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_RSA_PSK_WITH_RC4_128_SHA,
+ http2cipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_RSA_WITH_SEED_CBC_SHA,
+ http2cipher_TLS_DH_DSS_WITH_SEED_CBC_SHA,
+ http2cipher_TLS_DH_RSA_WITH_SEED_CBC_SHA,
+ http2cipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA,
+ http2cipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA,
+ http2cipher_TLS_DH_anon_WITH_SEED_CBC_SHA,
+ http2cipher_TLS_RSA_WITH_AES_128_GCM_SHA256,
+ http2cipher_TLS_RSA_WITH_AES_256_GCM_SHA384,
+ http2cipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256,
+ http2cipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384,
+ http2cipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256,
+ http2cipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384,
+ http2cipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256,
+ http2cipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384,
+ http2cipher_TLS_PSK_WITH_AES_128_GCM_SHA256,
+ http2cipher_TLS_PSK_WITH_AES_256_GCM_SHA384,
+ http2cipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,
+ http2cipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,
+ http2cipher_TLS_PSK_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_PSK_WITH_AES_256_CBC_SHA384,
+ http2cipher_TLS_PSK_WITH_NULL_SHA256,
+ http2cipher_TLS_PSK_WITH_NULL_SHA384,
+ http2cipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,
+ http2cipher_TLS_DHE_PSK_WITH_NULL_SHA256,
+ http2cipher_TLS_DHE_PSK_WITH_NULL_SHA384,
+ http2cipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,
+ http2cipher_TLS_RSA_PSK_WITH_NULL_SHA256,
+ http2cipher_TLS_RSA_PSK_WITH_NULL_SHA384,
+ http2cipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+ http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256,
+ http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+ http2cipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,
+ http2cipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
+ http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,
+ http2cipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV,
+ http2cipher_TLS_ECDH_ECDSA_WITH_NULL_SHA,
+ http2cipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
+ http2cipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA,
+ http2cipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+ http2cipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_ECDH_RSA_WITH_NULL_SHA,
+ http2cipher_TLS_ECDH_RSA_WITH_RC4_128_SHA,
+ http2cipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_ECDHE_RSA_WITH_NULL_SHA,
+ http2cipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+ http2cipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_ECDH_anon_WITH_NULL_SHA,
+ http2cipher_TLS_ECDH_anon_WITH_RC4_128_SHA,
+ http2cipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+ http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,
+ http2cipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
+ http2cipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,
+ http2cipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+ http2cipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
+ http2cipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+ http2cipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,
+ http2cipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA,
+ http2cipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,
+ http2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,
+ http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,
+ http2cipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
+ http2cipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,
+ http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA,
+ http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA256,
+ http2cipher_TLS_ECDHE_PSK_WITH_NULL_SHA384,
+ http2cipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256,
+ http2cipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384,
+ http2cipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256,
+ http2cipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384,
+ http2cipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256,
+ http2cipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384,
+ http2cipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256,
+ http2cipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384,
+ http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,
+ http2cipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,
+ http2cipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,
+ http2cipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,
+ http2cipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256,
+ http2cipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384,
+ http2cipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,
+ http2cipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,
+ http2cipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,
+ http2cipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,
+ http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
+ http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,
+ http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,
+ http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,
+ http2cipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,
+ http2cipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,
+ http2cipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
+ http2cipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
+ http2cipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256,
+ http2cipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384,
+ http2cipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256,
+ http2cipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384,
+ http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
+ http2cipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,
+ http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,
+ http2cipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,
+ http2cipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,
+ http2cipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,
+ http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,
+ http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,
+ http2cipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+ http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+ http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+ http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,
+ http2cipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,
+ http2cipher_TLS_RSA_WITH_AES_128_CCM,
+ http2cipher_TLS_RSA_WITH_AES_256_CCM,
+ http2cipher_TLS_RSA_WITH_AES_128_CCM_8,
+ http2cipher_TLS_RSA_WITH_AES_256_CCM_8,
+ http2cipher_TLS_PSK_WITH_AES_128_CCM,
+ http2cipher_TLS_PSK_WITH_AES_256_CCM,
+ http2cipher_TLS_PSK_WITH_AES_128_CCM_8,
+ http2cipher_TLS_PSK_WITH_AES_256_CCM_8:
+ return true
+ default:
+ return false
+ }
+}
+
+// ClientConnPool manages a pool of HTTP/2 client connections.
+type http2ClientConnPool interface {
+ // GetClientConn returns a specific HTTP/2 connection (usually
+ // a TLS-TCP connection) to an HTTP/2 server. On success, the
+ // returned ClientConn accounts for the upcoming RoundTrip
+ // call, so the caller should not omit it. If the caller needs
+ // to, ClientConn.RoundTrip can be called with a bogus
+ // new(http.Request) to release the stream reservation.
+ GetClientConn(req *Request, addr string) (*http2ClientConn, error)
+ MarkDead(*http2ClientConn)
+}
+
+// clientConnPoolIdleCloser is the interface implemented by ClientConnPool
+// implementations which can close their idle connections.
+type http2clientConnPoolIdleCloser interface {
+ http2ClientConnPool
+ closeIdleConnections()
+}
+
+var (
+ _ http2clientConnPoolIdleCloser = (*http2clientConnPool)(nil)
+ _ http2clientConnPoolIdleCloser = http2noDialClientConnPool{}
+)
+
+// TODO: use singleflight for dialing and addConnCalls?
+type http2clientConnPool struct {
+ t *http2Transport
+
+ mu sync.Mutex // TODO: maybe switch to RWMutex
+ // TODO: add support for sharing conns based on cert names
+ // (e.g. share conn for googleapis.com and appspot.com)
+ conns map[string][]*http2ClientConn // key is host:port
+ dialing map[string]*http2dialCall // currently in-flight dials
+ keys map[*http2ClientConn][]string
+ addConnCalls map[string]*http2addConnCall // in-flight addConnIfNeeded calls
+}
+
+func (p *http2clientConnPool) GetClientConn(req *Request, addr string) (*http2ClientConn, error) {
+ return p.getClientConn(req, addr, http2dialOnMiss)
+}
+
+const (
+ http2dialOnMiss = true
+ http2noDialOnMiss = false
+)
+
+func (p *http2clientConnPool) getClientConn(req *Request, addr string, dialOnMiss bool) (*http2ClientConn, error) {
+ // TODO(dneil): Dial a new connection when t.DisableKeepAlives is set?
+ if http2isConnectionCloseRequest(req) && dialOnMiss {
+ // It gets its own connection.
+ http2traceGetConn(req, addr)
+ const singleUse = true
+ cc, err := p.t.dialClientConn(req.Context(), addr, singleUse)
+ if err != nil {
+ return nil, err
+ }
+ return cc, nil
+ }
+ for {
+ p.mu.Lock()
+ for _, cc := range p.conns[addr] {
+ if cc.ReserveNewRequest() {
+ // When a connection is presented to us by the net/http package,
+ // the GetConn hook has already been called.
+ // Don't call it a second time here.
+ if !cc.getConnCalled {
+ http2traceGetConn(req, addr)
+ }
+ cc.getConnCalled = false
+ p.mu.Unlock()
+ return cc, nil
+ }
+ }
+ if !dialOnMiss {
+ p.mu.Unlock()
+ return nil, http2ErrNoCachedConn
+ }
+ http2traceGetConn(req, addr)
+ call := p.getStartDialLocked(req.Context(), addr)
+ p.mu.Unlock()
+ <-call.done
+ if http2shouldRetryDial(call, req) {
+ continue
+ }
+ cc, err := call.res, call.err
+ if err != nil {
+ return nil, err
+ }
+ if cc.ReserveNewRequest() {
+ return cc, nil
+ }
+ }
+}
+
+// dialCall is an in-flight Transport dial call to a host.
+type http2dialCall struct {
+ _ http2incomparable
+ p *http2clientConnPool
+ // the context associated with the request
+ // that created this dialCall
+ ctx context.Context
+ done chan struct{} // closed when done
+ res *http2ClientConn // valid after done is closed
+ err error // valid after done is closed
+}
+
+// requires p.mu is held.
+func (p *http2clientConnPool) getStartDialLocked(ctx context.Context, addr string) *http2dialCall {
+ if call, ok := p.dialing[addr]; ok {
+ // A dial is already in-flight. Don't start another.
+ return call
+ }
+ call := &http2dialCall{p: p, done: make(chan struct{}), ctx: ctx}
+ if p.dialing == nil {
+ p.dialing = make(map[string]*http2dialCall)
+ }
+ p.dialing[addr] = call
+ go call.dial(call.ctx, addr)
+ return call
+}
+
+// run in its own goroutine.
+func (c *http2dialCall) dial(ctx context.Context, addr string) {
+ const singleUse = false // shared conn
+ c.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse)
+
+ c.p.mu.Lock()
+ delete(c.p.dialing, addr)
+ if c.err == nil {
+ c.p.addConnLocked(addr, c.res)
+ }
+ c.p.mu.Unlock()
+
+ close(c.done)
+}
+
+// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't
+// already exist. It coalesces concurrent calls with the same key.
+// This is used by the http1 Transport code when it creates a new connection. Because
+// the http1 Transport doesn't de-dup TCP dials to outbound hosts (because it doesn't know
+// the protocol), it can get into a situation where it has multiple TLS connections.
+// This code decides which ones live or die.
+// The return value used is whether c was used.
+// c is never closed.
+func (p *http2clientConnPool) addConnIfNeeded(key string, t *http2Transport, c *tls.Conn) (used bool, err error) {
+ p.mu.Lock()
+ for _, cc := range p.conns[key] {
+ if cc.CanTakeNewRequest() {
+ p.mu.Unlock()
+ return false, nil
+ }
+ }
+ call, dup := p.addConnCalls[key]
+ if !dup {
+ if p.addConnCalls == nil {
+ p.addConnCalls = make(map[string]*http2addConnCall)
+ }
+ call = &http2addConnCall{
+ p: p,
+ done: make(chan struct{}),
+ }
+ p.addConnCalls[key] = call
+ go call.run(t, key, c)
+ }
+ p.mu.Unlock()
+
+ <-call.done
+ if call.err != nil {
+ return false, call.err
+ }
+ return !dup, nil
+}
+
+type http2addConnCall struct {
+ _ http2incomparable
+ p *http2clientConnPool
+ done chan struct{} // closed when done
+ err error
+}
+
+func (c *http2addConnCall) run(t *http2Transport, key string, tc *tls.Conn) {
+ cc, err := t.NewClientConn(tc)
+
+ p := c.p
+ p.mu.Lock()
+ if err != nil {
+ c.err = err
+ } else {
+ cc.getConnCalled = true // already called by the net/http package
+ p.addConnLocked(key, cc)
+ }
+ delete(p.addConnCalls, key)
+ p.mu.Unlock()
+ close(c.done)
+}
+
+// p.mu must be held
+func (p *http2clientConnPool) addConnLocked(key string, cc *http2ClientConn) {
+ for _, v := range p.conns[key] {
+ if v == cc {
+ return
+ }
+ }
+ if p.conns == nil {
+ p.conns = make(map[string][]*http2ClientConn)
+ }
+ if p.keys == nil {
+ p.keys = make(map[*http2ClientConn][]string)
+ }
+ p.conns[key] = append(p.conns[key], cc)
+ p.keys[cc] = append(p.keys[cc], key)
+}
+
+func (p *http2clientConnPool) MarkDead(cc *http2ClientConn) {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ for _, key := range p.keys[cc] {
+ vv, ok := p.conns[key]
+ if !ok {
+ continue
+ }
+ newList := http2filterOutClientConn(vv, cc)
+ if len(newList) > 0 {
+ p.conns[key] = newList
+ } else {
+ delete(p.conns, key)
+ }
+ }
+ delete(p.keys, cc)
+}
+
+func (p *http2clientConnPool) closeIdleConnections() {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ // TODO: don't close a cc if it was just added to the pool
+ // milliseconds ago and has never been used. There's currently
+ // a small race window with the HTTP/1 Transport's integration
+ // where it can add an idle conn just before using it, and
+ // somebody else can concurrently call CloseIdleConns and
+ // break some caller's RoundTrip.
+ for _, vv := range p.conns {
+ for _, cc := range vv {
+ cc.closeIfIdle()
+ }
+ }
+}
+
+func http2filterOutClientConn(in []*http2ClientConn, exclude *http2ClientConn) []*http2ClientConn {
+ out := in[:0]
+ for _, v := range in {
+ if v != exclude {
+ out = append(out, v)
+ }
+ }
+ // If we filtered it out, zero out the last item to prevent
+ // the GC from seeing it.
+ if len(in) != len(out) {
+ in[len(in)-1] = nil
+ }
+ return out
+}
+
+// noDialClientConnPool is an implementation of http2.ClientConnPool
+// which never dials. We let the HTTP/1.1 client dial and use its TLS
+// connection instead.
+type http2noDialClientConnPool struct{ *http2clientConnPool }
+
+func (p http2noDialClientConnPool) GetClientConn(req *Request, addr string) (*http2ClientConn, error) {
+ return p.getClientConn(req, addr, http2noDialOnMiss)
+}
+
+// shouldRetryDial reports whether the current request should
+// retry dialing after the call finished unsuccessfully, for example
+// if the dial was canceled because of a context cancellation or
+// deadline expiry.
+func http2shouldRetryDial(call *http2dialCall, req *Request) bool {
+ if call.err == nil {
+ // No error, no need to retry
+ return false
+ }
+ if call.ctx == req.Context() {
+ // If the call has the same context as the request, the dial
+ // should not be retried, since any cancellation will have come
+ // from this request.
+ return false
+ }
+ if !errors.Is(call.err, context.Canceled) && !errors.Is(call.err, context.DeadlineExceeded) {
+ // If the call error is not because of a context cancellation or a deadline expiry,
+ // the dial should not be retried.
+ return false
+ }
+ // Only retry if the error is a context cancellation error or deadline expiry
+ // and the context associated with the call was canceled or expired.
+ return call.ctx.Err() != nil
+}
+
+// Buffer chunks are allocated from a pool to reduce pressure on GC.
+// The maximum wasted space per dataBuffer is 2x the largest size class,
+// which happens when the dataBuffer has multiple chunks and there is
+// one unread byte in both the first and last chunks. We use a few size
+// classes to minimize overheads for servers that typically receive very
+// small request bodies.
+//
+// TODO: Benchmark to determine if the pools are necessary. The GC may have
+// improved enough that we can instead allocate chunks like this:
+// make([]byte, max(16<<10, expectedBytesRemaining))
+var (
+ http2dataChunkSizeClasses = []int{
+ 1 << 10,
+ 2 << 10,
+ 4 << 10,
+ 8 << 10,
+ 16 << 10,
+ }
+ http2dataChunkPools = [...]sync.Pool{
+ {New: func() interface{} { return make([]byte, 1<<10) }},
+ {New: func() interface{} { return make([]byte, 2<<10) }},
+ {New: func() interface{} { return make([]byte, 4<<10) }},
+ {New: func() interface{} { return make([]byte, 8<<10) }},
+ {New: func() interface{} { return make([]byte, 16<<10) }},
+ }
+)
+
+func http2getDataBufferChunk(size int64) []byte {
+ i := 0
+ for ; i < len(http2dataChunkSizeClasses)-1; i++ {
+ if size <= int64(http2dataChunkSizeClasses[i]) {
+ break
+ }
+ }
+ return http2dataChunkPools[i].Get().([]byte)
+}
+
+func http2putDataBufferChunk(p []byte) {
+ for i, n := range http2dataChunkSizeClasses {
+ if len(p) == n {
+ http2dataChunkPools[i].Put(p)
+ return
+ }
+ }
+ panic(fmt.Sprintf("unexpected buffer len=%v", len(p)))
+}
+
+// dataBuffer is an io.ReadWriter backed by a list of data chunks.
+// Each dataBuffer is used to read DATA frames on a single stream.
+// The buffer is divided into chunks so the server can limit the
+// total memory used by a single connection without limiting the
+// request body size on any single stream.
+type http2dataBuffer struct {
+ chunks [][]byte
+ r int // next byte to read is chunks[0][r]
+ w int // next byte to write is chunks[len(chunks)-1][w]
+ size int // total buffered bytes
+ expected int64 // we expect at least this many bytes in future Write calls (ignored if <= 0)
+}
+
+var http2errReadEmpty = errors.New("read from empty dataBuffer")
+
+// Read copies bytes from the buffer into p.
+// It is an error to read when no data is available.
+func (b *http2dataBuffer) Read(p []byte) (int, error) {
+ if b.size == 0 {
+ return 0, http2errReadEmpty
+ }
+ var ntotal int
+ for len(p) > 0 && b.size > 0 {
+ readFrom := b.bytesFromFirstChunk()
+ n := copy(p, readFrom)
+ p = p[n:]
+ ntotal += n
+ b.r += n
+ b.size -= n
+ // If the first chunk has been consumed, advance to the next chunk.
+ if b.r == len(b.chunks[0]) {
+ http2putDataBufferChunk(b.chunks[0])
+ end := len(b.chunks) - 1
+ copy(b.chunks[:end], b.chunks[1:])
+ b.chunks[end] = nil
+ b.chunks = b.chunks[:end]
+ b.r = 0
+ }
+ }
+ return ntotal, nil
+}
+
+func (b *http2dataBuffer) bytesFromFirstChunk() []byte {
+ if len(b.chunks) == 1 {
+ return b.chunks[0][b.r:b.w]
+ }
+ return b.chunks[0][b.r:]
+}
+
+// Len returns the number of bytes of the unread portion of the buffer.
+func (b *http2dataBuffer) Len() int {
+ return b.size
+}
+
+// Write appends p to the buffer.
+func (b *http2dataBuffer) Write(p []byte) (int, error) {
+ ntotal := len(p)
+ for len(p) > 0 {
+ // If the last chunk is empty, allocate a new chunk. Try to allocate
+ // enough to fully copy p plus any additional bytes we expect to
+ // receive. However, this may allocate less than len(p).
+ want := int64(len(p))
+ if b.expected > want {
+ want = b.expected
+ }
+ chunk := b.lastChunkOrAlloc(want)
+ n := copy(chunk[b.w:], p)
+ p = p[n:]
+ b.w += n
+ b.size += n
+ b.expected -= int64(n)
+ }
+ return ntotal, nil
+}
+
+func (b *http2dataBuffer) lastChunkOrAlloc(want int64) []byte {
+ if len(b.chunks) != 0 {
+ last := b.chunks[len(b.chunks)-1]
+ if b.w < len(last) {
+ return last
+ }
+ }
+ chunk := http2getDataBufferChunk(want)
+ b.chunks = append(b.chunks, chunk)
+ b.w = 0
+ return chunk
+}
+
+// An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec.
+type http2ErrCode uint32
+
+const (
+ http2ErrCodeNo http2ErrCode = 0x0
+ http2ErrCodeProtocol http2ErrCode = 0x1
+ http2ErrCodeInternal http2ErrCode = 0x2
+ http2ErrCodeFlowControl http2ErrCode = 0x3
+ http2ErrCodeSettingsTimeout http2ErrCode = 0x4
+ http2ErrCodeStreamClosed http2ErrCode = 0x5
+ http2ErrCodeFrameSize http2ErrCode = 0x6
+ http2ErrCodeRefusedStream http2ErrCode = 0x7
+ http2ErrCodeCancel http2ErrCode = 0x8
+ http2ErrCodeCompression http2ErrCode = 0x9
+ http2ErrCodeConnect http2ErrCode = 0xa
+ http2ErrCodeEnhanceYourCalm http2ErrCode = 0xb
+ http2ErrCodeInadequateSecurity http2ErrCode = 0xc
+ http2ErrCodeHTTP11Required http2ErrCode = 0xd
+)
+
+var http2errCodeName = map[http2ErrCode]string{
+ http2ErrCodeNo: "NO_ERROR",
+ http2ErrCodeProtocol: "PROTOCOL_ERROR",
+ http2ErrCodeInternal: "INTERNAL_ERROR",
+ http2ErrCodeFlowControl: "FLOW_CONTROL_ERROR",
+ http2ErrCodeSettingsTimeout: "SETTINGS_TIMEOUT",
+ http2ErrCodeStreamClosed: "STREAM_CLOSED",
+ http2ErrCodeFrameSize: "FRAME_SIZE_ERROR",
+ http2ErrCodeRefusedStream: "REFUSED_STREAM",
+ http2ErrCodeCancel: "CANCEL",
+ http2ErrCodeCompression: "COMPRESSION_ERROR",
+ http2ErrCodeConnect: "CONNECT_ERROR",
+ http2ErrCodeEnhanceYourCalm: "ENHANCE_YOUR_CALM",
+ http2ErrCodeInadequateSecurity: "INADEQUATE_SECURITY",
+ http2ErrCodeHTTP11Required: "HTTP_1_1_REQUIRED",
+}
+
+func (e http2ErrCode) String() string {
+ if s, ok := http2errCodeName[e]; ok {
+ return s
+ }
+ return fmt.Sprintf("unknown error code 0x%x", uint32(e))
+}
+
+func (e http2ErrCode) stringToken() string {
+ if s, ok := http2errCodeName[e]; ok {
+ return s
+ }
+ return fmt.Sprintf("ERR_UNKNOWN_%d", uint32(e))
+}
+
+// ConnectionError is an error that results in the termination of the
+// entire connection.
+type http2ConnectionError http2ErrCode
+
+func (e http2ConnectionError) Error() string {
+ return fmt.Sprintf("connection error: %s", http2ErrCode(e))
+}
+
+// StreamError is an error that only affects one stream within an
+// HTTP/2 connection.
+type http2StreamError struct {
+ StreamID uint32
+ Code http2ErrCode
+ Cause error // optional additional detail
+}
+
+// errFromPeer is a sentinel error value for StreamError.Cause to
+// indicate that the StreamError was sent from the peer over the wire
+// and wasn't locally generated in the Transport.
+var http2errFromPeer = errors.New("received from peer")
+
+func http2streamError(id uint32, code http2ErrCode) http2StreamError {
+ return http2StreamError{StreamID: id, Code: code}
+}
+
+func (e http2StreamError) Error() string {
+ if e.Cause != nil {
+ return fmt.Sprintf("stream error: stream ID %d; %v; %v", e.StreamID, e.Code, e.Cause)
+ }
+ return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code)
+}
+
+// 6.9.1 The Flow Control Window
+// "If a sender receives a WINDOW_UPDATE that causes a flow control
+// window to exceed this maximum it MUST terminate either the stream
+// or the connection, as appropriate. For streams, [...]; for the
+// connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code."
+type http2goAwayFlowError struct{}
+
+func (http2goAwayFlowError) Error() string { return "connection exceeded flow control window size" }
+
+// connError represents an HTTP/2 ConnectionError error code, along
+// with a string (for debugging) explaining why.
+//
+// Errors of this type are only returned by the frame parser functions
+// and converted into ConnectionError(Code), after stashing away
+// the Reason into the Framer's errDetail field, accessible via
+// the (*Framer).ErrorDetail method.
+type http2connError struct {
+ Code http2ErrCode // the ConnectionError error code
+ Reason string // additional reason
+}
+
+func (e http2connError) Error() string {
+ return fmt.Sprintf("http2: connection error: %v: %v", e.Code, e.Reason)
+}
+
+type http2pseudoHeaderError string
+
+func (e http2pseudoHeaderError) Error() string {
+ return fmt.Sprintf("invalid pseudo-header %q", string(e))
+}
+
+type http2duplicatePseudoHeaderError string
+
+func (e http2duplicatePseudoHeaderError) Error() string {
+ return fmt.Sprintf("duplicate pseudo-header %q", string(e))
+}
+
+type http2headerFieldNameError string
+
+func (e http2headerFieldNameError) Error() string {
+ return fmt.Sprintf("invalid header field name %q", string(e))
+}
+
+type http2headerFieldValueError string
+
+func (e http2headerFieldValueError) Error() string {
+ return fmt.Sprintf("invalid header field value for %q", string(e))
+}
+
+var (
+ http2errMixPseudoHeaderTypes = errors.New("mix of request and response pseudo headers")
+ http2errPseudoAfterRegular = errors.New("pseudo header field after regular")
+)
+
+// inflowMinRefresh is the minimum number of bytes we'll send for a
+// flow control window update.
+const http2inflowMinRefresh = 4 << 10
+
+// inflow accounts for an inbound flow control window.
+// It tracks both the latest window sent to the peer (used for enforcement)
+// and the accumulated unsent window.
+type http2inflow struct {
+ avail int32
+ unsent int32
+}
+
+// init sets the initial window.
+func (f *http2inflow) init(n int32) {
+ f.avail = n
+}
+
+// add adds n bytes to the window, with a maximum window size of max,
+// indicating that the peer can now send us more data.
+// For example, the user read from a {Request,Response} body and consumed
+// some of the buffered data, so the peer can now send more.
+// It returns the number of bytes to send in a WINDOW_UPDATE frame to the peer.
+// Window updates are accumulated and sent when the unsent capacity
+// is at least inflowMinRefresh or will at least double the peer's available window.
+func (f *http2inflow) add(n int) (connAdd int32) {
+ if n < 0 {
+ panic("negative update")
+ }
+ unsent := int64(f.unsent) + int64(n)
+ // "A sender MUST NOT allow a flow-control window to exceed 2^31-1 octets."
+ // RFC 7540 Section 6.9.1.
+ const maxWindow = 1<<31 - 1
+ if unsent+int64(f.avail) > maxWindow {
+ panic("flow control update exceeds maximum window size")
+ }
+ f.unsent = int32(unsent)
+ if f.unsent < http2inflowMinRefresh && f.unsent < f.avail {
+ // If there aren't at least inflowMinRefresh bytes of window to send,
+ // and this update won't at least double the window, buffer the update for later.
+ return 0
+ }
+ f.avail += f.unsent
+ f.unsent = 0
+ return int32(unsent)
+}
+
+// take attempts to take n bytes from the peer's flow control window.
+// It reports whether the window has available capacity.
+func (f *http2inflow) take(n uint32) bool {
+ if n > uint32(f.avail) {
+ return false
+ }
+ f.avail -= int32(n)
+ return true
+}
+
+// takeInflows attempts to take n bytes from two inflows,
+// typically connection-level and stream-level flows.
+// It reports whether both windows have available capacity.
+func http2takeInflows(f1, f2 *http2inflow, n uint32) bool {
+ if n > uint32(f1.avail) || n > uint32(f2.avail) {
+ return false
+ }
+ f1.avail -= int32(n)
+ f2.avail -= int32(n)
+ return true
+}
+
+// outflow is the outbound flow control window's size.
+type http2outflow struct {
+ _ http2incomparable
+
+ // n is the number of DATA bytes we're allowed to send.
+ // An outflow is kept both on a conn and a per-stream.
+ n int32
+
+ // conn points to the shared connection-level outflow that is
+ // shared by all streams on that conn. It is nil for the outflow
+ // that's on the conn directly.
+ conn *http2outflow
+}
+
+func (f *http2outflow) setConnFlow(cf *http2outflow) { f.conn = cf }
+
+func (f *http2outflow) available() int32 {
+ n := f.n
+ if f.conn != nil && f.conn.n < n {
+ n = f.conn.n
+ }
+ return n
+}
+
+func (f *http2outflow) take(n int32) {
+ if n > f.available() {
+ panic("internal error: took too much")
+ }
+ f.n -= n
+ if f.conn != nil {
+ f.conn.n -= n
+ }
+}
+
+// add adds n bytes (positive or negative) to the flow control window.
+// It returns false if the sum would exceed 2^31-1.
+func (f *http2outflow) add(n int32) bool {
+ sum := f.n + n
+ if (sum > n) == (f.n > 0) {
+ f.n = sum
+ return true
+ }
+ return false
+}
+
+const http2frameHeaderLen = 9
+
+var http2padZeros = make([]byte, 255) // zeros for padding
+
+// A FrameType is a registered frame type as defined in
+// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2
+type http2FrameType uint8
+
+const (
+ http2FrameData http2FrameType = 0x0
+ http2FrameHeaders http2FrameType = 0x1
+ http2FramePriority http2FrameType = 0x2
+ http2FrameRSTStream http2FrameType = 0x3
+ http2FrameSettings http2FrameType = 0x4
+ http2FramePushPromise http2FrameType = 0x5
+ http2FramePing http2FrameType = 0x6
+ http2FrameGoAway http2FrameType = 0x7
+ http2FrameWindowUpdate http2FrameType = 0x8
+ http2FrameContinuation http2FrameType = 0x9
+)
+
+var http2frameName = map[http2FrameType]string{
+ http2FrameData: "DATA",
+ http2FrameHeaders: "HEADERS",
+ http2FramePriority: "PRIORITY",
+ http2FrameRSTStream: "RST_STREAM",
+ http2FrameSettings: "SETTINGS",
+ http2FramePushPromise: "PUSH_PROMISE",
+ http2FramePing: "PING",
+ http2FrameGoAway: "GOAWAY",
+ http2FrameWindowUpdate: "WINDOW_UPDATE",
+ http2FrameContinuation: "CONTINUATION",
+}
+
+func (t http2FrameType) String() string {
+ if s, ok := http2frameName[t]; ok {
+ return s
+ }
+ return fmt.Sprintf("UNKNOWN_FRAME_TYPE_%d", uint8(t))
+}
+
+// Flags is a bitmask of HTTP/2 flags.
+// The meaning of flags varies depending on the frame type.
+type http2Flags uint8
+
+// Has reports whether f contains all (0 or more) flags in v.
+func (f http2Flags) Has(v http2Flags) bool {
+ return (f & v) == v
+}
+
+// Frame-specific FrameHeader flag bits.
+const (
+ // Data Frame
+ http2FlagDataEndStream http2Flags = 0x1
+ http2FlagDataPadded http2Flags = 0x8
+
+ // Headers Frame
+ http2FlagHeadersEndStream http2Flags = 0x1
+ http2FlagHeadersEndHeaders http2Flags = 0x4
+ http2FlagHeadersPadded http2Flags = 0x8
+ http2FlagHeadersPriority http2Flags = 0x20
+
+ // Settings Frame
+ http2FlagSettingsAck http2Flags = 0x1
+
+ // Ping Frame
+ http2FlagPingAck http2Flags = 0x1
+
+ // Continuation Frame
+ http2FlagContinuationEndHeaders http2Flags = 0x4
+
+ http2FlagPushPromiseEndHeaders http2Flags = 0x4
+ http2FlagPushPromisePadded http2Flags = 0x8
+)
+
+var http2flagName = map[http2FrameType]map[http2Flags]string{
+ http2FrameData: {
+ http2FlagDataEndStream: "END_STREAM",
+ http2FlagDataPadded: "PADDED",
+ },
+ http2FrameHeaders: {
+ http2FlagHeadersEndStream: "END_STREAM",
+ http2FlagHeadersEndHeaders: "END_HEADERS",
+ http2FlagHeadersPadded: "PADDED",
+ http2FlagHeadersPriority: "PRIORITY",
+ },
+ http2FrameSettings: {
+ http2FlagSettingsAck: "ACK",
+ },
+ http2FramePing: {
+ http2FlagPingAck: "ACK",
+ },
+ http2FrameContinuation: {
+ http2FlagContinuationEndHeaders: "END_HEADERS",
+ },
+ http2FramePushPromise: {
+ http2FlagPushPromiseEndHeaders: "END_HEADERS",
+ http2FlagPushPromisePadded: "PADDED",
+ },
+}
+
+// a frameParser parses a frame given its FrameHeader and payload
+// bytes. The length of payload will always equal fh.Length (which
+// might be 0).
+type http2frameParser func(fc *http2frameCache, fh http2FrameHeader, countError func(string), payload []byte) (http2Frame, error)
+
+var http2frameParsers = map[http2FrameType]http2frameParser{
+ http2FrameData: http2parseDataFrame,
+ http2FrameHeaders: http2parseHeadersFrame,
+ http2FramePriority: http2parsePriorityFrame,
+ http2FrameRSTStream: http2parseRSTStreamFrame,
+ http2FrameSettings: http2parseSettingsFrame,
+ http2FramePushPromise: http2parsePushPromise,
+ http2FramePing: http2parsePingFrame,
+ http2FrameGoAway: http2parseGoAwayFrame,
+ http2FrameWindowUpdate: http2parseWindowUpdateFrame,
+ http2FrameContinuation: http2parseContinuationFrame,
+}
+
+func http2typeFrameParser(t http2FrameType) http2frameParser {
+ if f := http2frameParsers[t]; f != nil {
+ return f
+ }
+ return http2parseUnknownFrame
+}
+
+// A FrameHeader is the 9 byte header of all HTTP/2 frames.
+//
+// See https://httpwg.org/specs/rfc7540.html#FrameHeader
+type http2FrameHeader struct {
+ valid bool // caller can access []byte fields in the Frame
+
+ // Type is the 1 byte frame type. There are ten standard frame
+ // types, but extension frame types may be written by WriteRawFrame
+ // and will be returned by ReadFrame (as UnknownFrame).
+ Type http2FrameType
+
+ // Flags are the 1 byte of 8 potential bit flags per frame.
+ // They are specific to the frame type.
+ Flags http2Flags
+
+ // Length is the length of the frame, not including the 9 byte header.
+ // The maximum size is one byte less than 16MB (uint24), but only
+ // frames up to 16KB are allowed without peer agreement.
+ Length uint32
+
+ // StreamID is which stream this frame is for. Certain frames
+ // are not stream-specific, in which case this field is 0.
+ StreamID uint32
+}
+
+// Header returns h. It exists so FrameHeaders can be embedded in other
+// specific frame types and implement the Frame interface.
+func (h http2FrameHeader) Header() http2FrameHeader { return h }
+
+func (h http2FrameHeader) String() string {
+ var buf bytes.Buffer
+ buf.WriteString("[FrameHeader ")
+ h.writeDebug(&buf)
+ buf.WriteByte(']')
+ return buf.String()
+}
+
+func (h http2FrameHeader) writeDebug(buf *bytes.Buffer) {
+ buf.WriteString(h.Type.String())
+ if h.Flags != 0 {
+ buf.WriteString(" flags=")
+ set := 0
+ for i := uint8(0); i < 8; i++ {
+ if h.Flags&(1<<i) == 0 {
+ continue
+ }
+ set++
+ if set > 1 {
+ buf.WriteByte('|')
+ }
+ name := http2flagName[h.Type][http2Flags(1<<i)]
+ if name != "" {
+ buf.WriteString(name)
+ } else {
+ fmt.Fprintf(buf, "0x%x", 1<<i)
+ }
+ }
+ }
+ if h.StreamID != 0 {
+ fmt.Fprintf(buf, " stream=%d", h.StreamID)
+ }
+ fmt.Fprintf(buf, " len=%d", h.Length)
+}
+
+func (h *http2FrameHeader) checkValid() {
+ if !h.valid {
+ panic("Frame accessor called on non-owned Frame")
+ }
+}
+
+func (h *http2FrameHeader) invalidate() { h.valid = false }
+
+// frame header bytes.
+// Used only by ReadFrameHeader.
+var http2fhBytes = sync.Pool{
+ New: func() interface{} {
+ buf := make([]byte, http2frameHeaderLen)
+ return &buf
+ },
+}
+
+// ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.
+// Most users should use Framer.ReadFrame instead.
+func http2ReadFrameHeader(r io.Reader) (http2FrameHeader, error) {
+ bufp := http2fhBytes.Get().(*[]byte)
+ defer http2fhBytes.Put(bufp)
+ return http2readFrameHeader(*bufp, r)
+}
+
+func http2readFrameHeader(buf []byte, r io.Reader) (http2FrameHeader, error) {
+ _, err := io.ReadFull(r, buf[:http2frameHeaderLen])
+ if err != nil {
+ return http2FrameHeader{}, err
+ }
+ return http2FrameHeader{
+ Length: (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])),
+ Type: http2FrameType(buf[3]),
+ Flags: http2Flags(buf[4]),
+ StreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1),
+ valid: true,
+ }, nil
+}
+
+// A Frame is the base interface implemented by all frame types.
+// Callers will generally type-assert the specific frame type:
+// *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc.
+//
+// Frames are only valid until the next call to Framer.ReadFrame.
+type http2Frame interface {
+ Header() http2FrameHeader
+
+ // invalidate is called by Framer.ReadFrame to make this
+ // frame's buffers as being invalid, since the subsequent
+ // frame will reuse them.
+ invalidate()
+}
+
+// A Framer reads and writes Frames.
+type http2Framer struct {
+ r io.Reader
+ lastFrame http2Frame
+ errDetail error
+
+ // countError is a non-nil func that's called on a frame parse
+ // error with some unique error path token. It's initialized
+ // from Transport.CountError or Server.CountError.
+ countError func(errToken string)
+
+ // lastHeaderStream is non-zero if the last frame was an
+ // unfinished HEADERS/CONTINUATION.
+ lastHeaderStream uint32
+
+ maxReadSize uint32
+ headerBuf [http2frameHeaderLen]byte
+
+ // TODO: let getReadBuf be configurable, and use a less memory-pinning
+ // allocator in server.go to minimize memory pinned for many idle conns.
+ // Will probably also need to make frame invalidation have a hook too.
+ getReadBuf func(size uint32) []byte
+ readBuf []byte // cache for default getReadBuf
+
+ maxWriteSize uint32 // zero means unlimited; TODO: implement
+
+ w io.Writer
+ wbuf []byte
+
+ // AllowIllegalWrites permits the Framer's Write methods to
+ // write frames that do not conform to the HTTP/2 spec. This
+ // permits using the Framer to test other HTTP/2
+ // implementations' conformance to the spec.
+ // If false, the Write methods will prefer to return an error
+ // rather than comply.
+ AllowIllegalWrites bool
+
+ // AllowIllegalReads permits the Framer's ReadFrame method
+ // to return non-compliant frames or frame orders.
+ // This is for testing and permits using the Framer to test
+ // other HTTP/2 implementations' conformance to the spec.
+ // It is not compatible with ReadMetaHeaders.
+ AllowIllegalReads bool
+
+ // ReadMetaHeaders if non-nil causes ReadFrame to merge
+ // HEADERS and CONTINUATION frames together and return
+ // MetaHeadersFrame instead.
+ ReadMetaHeaders *hpack.Decoder
+
+ // MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE.
+ // It's used only if ReadMetaHeaders is set; 0 means a sane default
+ // (currently 16MB)
+ // If the limit is hit, MetaHeadersFrame.Truncated is set true.
+ MaxHeaderListSize uint32
+
+ // TODO: track which type of frame & with which flags was sent
+ // last. Then return an error (unless AllowIllegalWrites) if
+ // we're in the middle of a header block and a
+ // non-Continuation or Continuation on a different stream is
+ // attempted to be written.
+
+ logReads, logWrites bool
+
+ debugFramer *http2Framer // only use for logging written writes
+ debugFramerBuf *bytes.Buffer
+ debugReadLoggerf func(string, ...interface{})
+ debugWriteLoggerf func(string, ...interface{})
+
+ frameCache *http2frameCache // nil if frames aren't reused (default)
+}
+
+func (fr *http2Framer) maxHeaderListSize() uint32 {
+ if fr.MaxHeaderListSize == 0 {
+ return 16 << 20 // sane default, per docs
+ }
+ return fr.MaxHeaderListSize
+}
+
+func (f *http2Framer) startWrite(ftype http2FrameType, flags http2Flags, streamID uint32) {
+ // Write the FrameHeader.
+ f.wbuf = append(f.wbuf[:0],
+ 0, // 3 bytes of length, filled in in endWrite
+ 0,
+ 0,
+ byte(ftype),
+ byte(flags),
+ byte(streamID>>24),
+ byte(streamID>>16),
+ byte(streamID>>8),
+ byte(streamID))
+}
+
+func (f *http2Framer) endWrite() error {
+ // Now that we know the final size, fill in the FrameHeader in
+ // the space previously reserved for it. Abuse append.
+ length := len(f.wbuf) - http2frameHeaderLen
+ if length >= (1 << 24) {
+ return http2ErrFrameTooLarge
+ }
+ _ = append(f.wbuf[:0],
+ byte(length>>16),
+ byte(length>>8),
+ byte(length))
+ if f.logWrites {
+ f.logWrite()
+ }
+
+ n, err := f.w.Write(f.wbuf)
+ if err == nil && n != len(f.wbuf) {
+ err = io.ErrShortWrite
+ }
+ return err
+}
+
+func (f *http2Framer) logWrite() {
+ if f.debugFramer == nil {
+ f.debugFramerBuf = new(bytes.Buffer)
+ f.debugFramer = http2NewFramer(nil, f.debugFramerBuf)
+ f.debugFramer.logReads = false // we log it ourselves, saying "wrote" below
+ // Let us read anything, even if we accidentally wrote it
+ // in the wrong order:
+ f.debugFramer.AllowIllegalReads = true
+ }
+ f.debugFramerBuf.Write(f.wbuf)
+ fr, err := f.debugFramer.ReadFrame()
+ if err != nil {
+ f.debugWriteLoggerf("http2: Framer %p: failed to decode just-written frame", f)
+ return
+ }
+ f.debugWriteLoggerf("http2: Framer %p: wrote %v", f, http2summarizeFrame(fr))
+}
+
+func (f *http2Framer) writeByte(v byte) { f.wbuf = append(f.wbuf, v) }
+
+func (f *http2Framer) writeBytes(v []byte) { f.wbuf = append(f.wbuf, v...) }
+
+func (f *http2Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }
+
+func (f *http2Framer) writeUint32(v uint32) {
+ f.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
+}
+
+const (
+ http2minMaxFrameSize = 1 << 14
+ http2maxFrameSize = 1<<24 - 1
+)
+
+// SetReuseFrames allows the Framer to reuse Frames.
+// If called on a Framer, Frames returned by calls to ReadFrame are only
+// valid until the next call to ReadFrame.
+func (fr *http2Framer) SetReuseFrames() {
+ if fr.frameCache != nil {
+ return
+ }
+ fr.frameCache = &http2frameCache{}
+}
+
+type http2frameCache struct {
+ dataFrame http2DataFrame
+}
+
+func (fc *http2frameCache) getDataFrame() *http2DataFrame {
+ if fc == nil {
+ return &http2DataFrame{}
+ }
+ return &fc.dataFrame
+}
+
+// NewFramer returns a Framer that writes frames to w and reads them from r.
+func http2NewFramer(w io.Writer, r io.Reader) *http2Framer {
+ fr := &http2Framer{
+ w: w,
+ r: r,
+ countError: func(string) {},
+ logReads: http2logFrameReads,
+ logWrites: http2logFrameWrites,
+ debugReadLoggerf: log.Printf,
+ debugWriteLoggerf: log.Printf,
+ }
+ fr.getReadBuf = func(size uint32) []byte {
+ if cap(fr.readBuf) >= int(size) {
+ return fr.readBuf[:size]
+ }
+ fr.readBuf = make([]byte, size)
+ return fr.readBuf
+ }
+ fr.SetMaxReadFrameSize(http2maxFrameSize)
+ return fr
+}
+
+// SetMaxReadFrameSize sets the maximum size of a frame
+// that will be read by a subsequent call to ReadFrame.
+// It is the caller's responsibility to advertise this
+// limit with a SETTINGS frame.
+func (fr *http2Framer) SetMaxReadFrameSize(v uint32) {
+ if v > http2maxFrameSize {
+ v = http2maxFrameSize
+ }
+ fr.maxReadSize = v
+}
+
+// ErrorDetail returns a more detailed error of the last error
+// returned by Framer.ReadFrame. For instance, if ReadFrame
+// returns a StreamError with code PROTOCOL_ERROR, ErrorDetail
+// will say exactly what was invalid. ErrorDetail is not guaranteed
+// to return a non-nil value and like the rest of the http2 package,
+// its return value is not protected by an API compatibility promise.
+// ErrorDetail is reset after the next call to ReadFrame.
+func (fr *http2Framer) ErrorDetail() error {
+ return fr.errDetail
+}
+
+// ErrFrameTooLarge is returned from Framer.ReadFrame when the peer
+// sends a frame that is larger than declared with SetMaxReadFrameSize.
+var http2ErrFrameTooLarge = errors.New("http2: frame too large")
+
+// terminalReadFrameError reports whether err is an unrecoverable
+// error from ReadFrame and no other frames should be read.
+func http2terminalReadFrameError(err error) bool {
+ if _, ok := err.(http2StreamError); ok {
+ return false
+ }
+ return err != nil
+}
+
+// ReadFrame reads a single frame. The returned Frame is only valid
+// until the next call to ReadFrame.
+//
+// If the frame is larger than previously set with SetMaxReadFrameSize, the
+// returned error is ErrFrameTooLarge. Other errors may be of type
+// ConnectionError, StreamError, or anything else from the underlying
+// reader.
+func (fr *http2Framer) ReadFrame() (http2Frame, error) {
+ fr.errDetail = nil
+ if fr.lastFrame != nil {
+ fr.lastFrame.invalidate()
+ }
+ fh, err := http2readFrameHeader(fr.headerBuf[:], fr.r)
+ if err != nil {
+ return nil, err
+ }
+ if fh.Length > fr.maxReadSize {
+ return nil, http2ErrFrameTooLarge
+ }
+ payload := fr.getReadBuf(fh.Length)
+ if _, err := io.ReadFull(fr.r, payload); err != nil {
+ return nil, err
+ }
+ f, err := http2typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload)
+ if err != nil {
+ if ce, ok := err.(http2connError); ok {
+ return nil, fr.connError(ce.Code, ce.Reason)
+ }
+ return nil, err
+ }
+ if err := fr.checkFrameOrder(f); err != nil {
+ return nil, err
+ }
+ if fr.logReads {
+ fr.debugReadLoggerf("http2: Framer %p: read %v", fr, http2summarizeFrame(f))
+ }
+ if fh.Type == http2FrameHeaders && fr.ReadMetaHeaders != nil {
+ return fr.readMetaFrame(f.(*http2HeadersFrame))
+ }
+ return f, nil
+}
+
+// connError returns ConnectionError(code) but first
+// stashes away a public reason to the caller can optionally relay it
+// to the peer before hanging up on them. This might help others debug
+// their implementations.
+func (fr *http2Framer) connError(code http2ErrCode, reason string) error {
+ fr.errDetail = errors.New(reason)
+ return http2ConnectionError(code)
+}
+
+// checkFrameOrder reports an error if f is an invalid frame to return
+// next from ReadFrame. Mostly it checks whether HEADERS and
+// CONTINUATION frames are contiguous.
+func (fr *http2Framer) checkFrameOrder(f http2Frame) error {
+ last := fr.lastFrame
+ fr.lastFrame = f
+ if fr.AllowIllegalReads {
+ return nil
+ }
+
+ fh := f.Header()
+ if fr.lastHeaderStream != 0 {
+ if fh.Type != http2FrameContinuation {
+ return fr.connError(http2ErrCodeProtocol,
+ fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d",
+ fh.Type, fh.StreamID,
+ last.Header().Type, fr.lastHeaderStream))
+ }
+ if fh.StreamID != fr.lastHeaderStream {
+ return fr.connError(http2ErrCodeProtocol,
+ fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d",
+ fh.StreamID, fr.lastHeaderStream))
+ }
+ } else if fh.Type == http2FrameContinuation {
+ return fr.connError(http2ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID))
+ }
+
+ switch fh.Type {
+ case http2FrameHeaders, http2FrameContinuation:
+ if fh.Flags.Has(http2FlagHeadersEndHeaders) {
+ fr.lastHeaderStream = 0
+ } else {
+ fr.lastHeaderStream = fh.StreamID
+ }
+ }
+
+ return nil
+}
+
+// A DataFrame conveys arbitrary, variable-length sequences of octets
+// associated with a stream.
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1
+type http2DataFrame struct {
+ http2FrameHeader
+ data []byte
+}
+
+func (f *http2DataFrame) StreamEnded() bool {
+ return f.http2FrameHeader.Flags.Has(http2FlagDataEndStream)
+}
+
+// Data returns the frame's data octets, not including any padding
+// size byte or padding suffix bytes.
+// The caller must not retain the returned memory past the next
+// call to ReadFrame.
+func (f *http2DataFrame) Data() []byte {
+ f.checkValid()
+ return f.data
+}
+
+func http2parseDataFrame(fc *http2frameCache, fh http2FrameHeader, countError func(string), payload []byte) (http2Frame, error) {
+ if fh.StreamID == 0 {
+ // DATA frames MUST be associated with a stream. If a
+ // DATA frame is received whose stream identifier
+ // field is 0x0, the recipient MUST respond with a
+ // connection error (Section 5.4.1) of type
+ // PROTOCOL_ERROR.
+ countError("frame_data_stream_0")
+ return nil, http2connError{http2ErrCodeProtocol, "DATA frame with stream ID 0"}
+ }
+ f := fc.getDataFrame()
+ f.http2FrameHeader = fh
+
+ var padSize byte
+ if fh.Flags.Has(http2FlagDataPadded) {
+ var err error
+ payload, padSize, err = http2readByte(payload)
+ if err != nil {
+ countError("frame_data_pad_byte_short")
+ return nil, err
+ }
+ }
+ if int(padSize) > len(payload) {
+ // If the length of the padding is greater than the
+ // length of the frame payload, the recipient MUST
+ // treat this as a connection error.
+ // Filed: https://github.com/http2/http2-spec/issues/610
+ countError("frame_data_pad_too_big")
+ return nil, http2connError{http2ErrCodeProtocol, "pad size larger than data payload"}
+ }
+ f.data = payload[:len(payload)-int(padSize)]
+ return f, nil
+}
+
+var (
+ http2errStreamID = errors.New("invalid stream ID")
+ http2errDepStreamID = errors.New("invalid dependent stream ID")
+ http2errPadLength = errors.New("pad length too large")
+ http2errPadBytes = errors.New("padding bytes must all be zeros unless AllowIllegalWrites is enabled")
+)
+
+func http2validStreamIDOrZero(streamID uint32) bool {
+ return streamID&(1<<31) == 0
+}
+
+func http2validStreamID(streamID uint32) bool {
+ return streamID != 0 && streamID&(1<<31) == 0
+}
+
+// WriteData writes a DATA frame.
+//
+// It will perform exactly one Write to the underlying Writer.
+// It is the caller's responsibility not to violate the maximum frame size
+// and to not call other Write methods concurrently.
+func (f *http2Framer) WriteData(streamID uint32, endStream bool, data []byte) error {
+ return f.WriteDataPadded(streamID, endStream, data, nil)
+}
+
+// WriteDataPadded writes a DATA frame with optional padding.
+//
+// If pad is nil, the padding bit is not sent.
+// The length of pad must not exceed 255 bytes.
+// The bytes of pad must all be zero, unless f.AllowIllegalWrites is set.
+//
+// It will perform exactly one Write to the underlying Writer.
+// It is the caller's responsibility not to violate the maximum frame size
+// and to not call other Write methods concurrently.
+func (f *http2Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
+ if err := f.startWriteDataPadded(streamID, endStream, data, pad); err != nil {
+ return err
+ }
+ return f.endWrite()
+}
+
+// startWriteDataPadded is WriteDataPadded, but only writes the frame to the Framer's internal buffer.
+// The caller should call endWrite to flush the frame to the underlying writer.
+func (f *http2Framer) startWriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {
+ if !http2validStreamID(streamID) && !f.AllowIllegalWrites {
+ return http2errStreamID
+ }
+ if len(pad) > 0 {
+ if len(pad) > 255 {
+ return http2errPadLength
+ }
+ if !f.AllowIllegalWrites {
+ for _, b := range pad {
+ if b != 0 {
+ // "Padding octets MUST be set to zero when sending."
+ return http2errPadBytes
+ }
+ }
+ }
+ }
+ var flags http2Flags
+ if endStream {
+ flags |= http2FlagDataEndStream
+ }
+ if pad != nil {
+ flags |= http2FlagDataPadded
+ }
+ f.startWrite(http2FrameData, flags, streamID)
+ if pad != nil {
+ f.wbuf = append(f.wbuf, byte(len(pad)))
+ }
+ f.wbuf = append(f.wbuf, data...)
+ f.wbuf = append(f.wbuf, pad...)
+ return nil
+}
+
+// A SettingsFrame conveys configuration parameters that affect how
+// endpoints communicate, such as preferences and constraints on peer
+// behavior.
+//
+// See https://httpwg.org/specs/rfc7540.html#SETTINGS
+type http2SettingsFrame struct {
+ http2FrameHeader
+ p []byte
+}
+
+func http2parseSettingsFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (http2Frame, error) {
+ if fh.Flags.Has(http2FlagSettingsAck) && fh.Length > 0 {
+ // When this (ACK 0x1) bit is set, the payload of the
+ // SETTINGS frame MUST be empty. Receipt of a
+ // SETTINGS frame with the ACK flag set and a length
+ // field value other than 0 MUST be treated as a
+ // connection error (Section 5.4.1) of type
+ // FRAME_SIZE_ERROR.
+ countError("frame_settings_ack_with_length")
+ return nil, http2ConnectionError(http2ErrCodeFrameSize)
+ }
+ if fh.StreamID != 0 {
+ // SETTINGS frames always apply to a connection,
+ // never a single stream. The stream identifier for a
+ // SETTINGS frame MUST be zero (0x0). If an endpoint
+ // receives a SETTINGS frame whose stream identifier
+ // field is anything other than 0x0, the endpoint MUST
+ // respond with a connection error (Section 5.4.1) of
+ // type PROTOCOL_ERROR.
+ countError("frame_settings_has_stream")
+ return nil, http2ConnectionError(http2ErrCodeProtocol)
+ }
+ if len(p)%6 != 0 {
+ countError("frame_settings_mod_6")
+ // Expecting even number of 6 byte settings.
+ return nil, http2ConnectionError(http2ErrCodeFrameSize)
+ }
+ f := &http2SettingsFrame{http2FrameHeader: fh, p: p}
+ if v, ok := f.Value(http2SettingInitialWindowSize); ok && v > (1<<31)-1 {
+ countError("frame_settings_window_size_too_big")
+ // Values above the maximum flow control window size of 2^31 - 1 MUST
+ // be treated as a connection error (Section 5.4.1) of type
+ // FLOW_CONTROL_ERROR.
+ return nil, http2ConnectionError(http2ErrCodeFlowControl)
+ }
+ return f, nil
+}
+
+func (f *http2SettingsFrame) IsAck() bool {
+ return f.http2FrameHeader.Flags.Has(http2FlagSettingsAck)
+}
+
+func (f *http2SettingsFrame) Value(id http2SettingID) (v uint32, ok bool) {
+ f.checkValid()
+ for i := 0; i < f.NumSettings(); i++ {
+ if s := f.Setting(i); s.ID == id {
+ return s.Val, true
+ }
+ }
+ return 0, false
+}
+
+// Setting returns the setting from the frame at the given 0-based index.
+// The index must be >= 0 and less than f.NumSettings().
+func (f *http2SettingsFrame) Setting(i int) http2Setting {
+ buf := f.p
+ return http2Setting{
+ ID: http2SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])),
+ Val: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]),
+ }
+}
+
+func (f *http2SettingsFrame) NumSettings() int { return len(f.p) / 6 }
+
+// HasDuplicates reports whether f contains any duplicate setting IDs.
+func (f *http2SettingsFrame) HasDuplicates() bool {
+ num := f.NumSettings()
+ if num == 0 {
+ return false
+ }
+ // If it's small enough (the common case), just do the n^2
+ // thing and avoid a map allocation.
+ if num < 10 {
+ for i := 0; i < num; i++ {
+ idi := f.Setting(i).ID
+ for j := i + 1; j < num; j++ {
+ idj := f.Setting(j).ID
+ if idi == idj {
+ return true
+ }
+ }
+ }
+ return false
+ }
+ seen := map[http2SettingID]bool{}
+ for i := 0; i < num; i++ {
+ id := f.Setting(i).ID
+ if seen[id] {
+ return true
+ }
+ seen[id] = true
+ }
+ return false
+}
+
+// ForeachSetting runs fn for each setting.
+// It stops and returns the first error.
+func (f *http2SettingsFrame) ForeachSetting(fn func(http2Setting) error) error {
+ f.checkValid()
+ for i := 0; i < f.NumSettings(); i++ {
+ if err := fn(f.Setting(i)); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// WriteSettings writes a SETTINGS frame with zero or more settings
+// specified and the ACK bit not set.
+//
+// It will perform exactly one Write to the underlying Writer.
+// It is the caller's responsibility to not call other Write methods concurrently.
+func (f *http2Framer) WriteSettings(settings ...http2Setting) error {
+ f.startWrite(http2FrameSettings, 0, 0)
+ for _, s := range settings {
+ f.writeUint16(uint16(s.ID))
+ f.writeUint32(s.Val)
+ }
+ return f.endWrite()
+}
+
+// WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set.
+//
+// It will perform exactly one Write to the underlying Writer.
+// It is the caller's responsibility to not call other Write methods concurrently.
+func (f *http2Framer) WriteSettingsAck() error {
+ f.startWrite(http2FrameSettings, http2FlagSettingsAck, 0)
+ return f.endWrite()
+}
+
+// A PingFrame is a mechanism for measuring a minimal round trip time
+// from the sender, as well as determining whether an idle connection
+// is still functional.
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7
+type http2PingFrame struct {
+ http2FrameHeader
+ Data [8]byte
+}
+
+func (f *http2PingFrame) IsAck() bool { return f.Flags.Has(http2FlagPingAck) }
+
+func http2parsePingFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), payload []byte) (http2Frame, error) {
+ if len(payload) != 8 {
+ countError("frame_ping_length")
+ return nil, http2ConnectionError(http2ErrCodeFrameSize)
+ }
+ if fh.StreamID != 0 {
+ countError("frame_ping_has_stream")
+ return nil, http2ConnectionError(http2ErrCodeProtocol)
+ }
+ f := &http2PingFrame{http2FrameHeader: fh}
+ copy(f.Data[:], payload)
+ return f, nil
+}
+
+func (f *http2Framer) WritePing(ack bool, data [8]byte) error {
+ var flags http2Flags
+ if ack {
+ flags = http2FlagPingAck
+ }
+ f.startWrite(http2FramePing, flags, 0)
+ f.writeBytes(data[:])
+ return f.endWrite()
+}
+
+// A GoAwayFrame informs the remote peer to stop creating streams on this connection.
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8
+type http2GoAwayFrame struct {
+ http2FrameHeader
+ LastStreamID uint32
+ ErrCode http2ErrCode
+ debugData []byte
+}
+
+// DebugData returns any debug data in the GOAWAY frame. Its contents
+// are not defined.
+// The caller must not retain the returned memory past the next
+// call to ReadFrame.
+func (f *http2GoAwayFrame) DebugData() []byte {
+ f.checkValid()
+ return f.debugData
+}
+
+func http2parseGoAwayFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (http2Frame, error) {
+ if fh.StreamID != 0 {
+ countError("frame_goaway_has_stream")
+ return nil, http2ConnectionError(http2ErrCodeProtocol)
+ }
+ if len(p) < 8 {
+ countError("frame_goaway_short")
+ return nil, http2ConnectionError(http2ErrCodeFrameSize)
+ }
+ return &http2GoAwayFrame{
+ http2FrameHeader: fh,
+ LastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1),
+ ErrCode: http2ErrCode(binary.BigEndian.Uint32(p[4:8])),
+ debugData: p[8:],
+ }, nil
+}
+
+func (f *http2Framer) WriteGoAway(maxStreamID uint32, code http2ErrCode, debugData []byte) error {
+ f.startWrite(http2FrameGoAway, 0, 0)
+ f.writeUint32(maxStreamID & (1<<31 - 1))
+ f.writeUint32(uint32(code))
+ f.writeBytes(debugData)
+ return f.endWrite()
+}
+
+// An UnknownFrame is the frame type returned when the frame type is unknown
+// or no specific frame type parser exists.
+type http2UnknownFrame struct {
+ http2FrameHeader
+ p []byte
+}
+
+// Payload returns the frame's payload (after the header). It is not
+// valid to call this method after a subsequent call to
+// Framer.ReadFrame, nor is it valid to retain the returned slice.
+// The memory is owned by the Framer and is invalidated when the next
+// frame is read.
+func (f *http2UnknownFrame) Payload() []byte {
+ f.checkValid()
+ return f.p
+}
+
+func http2parseUnknownFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (http2Frame, error) {
+ return &http2UnknownFrame{fh, p}, nil
+}
+
+// A WindowUpdateFrame is used to implement flow control.
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9
+type http2WindowUpdateFrame struct {
+ http2FrameHeader
+ Increment uint32 // never read with high bit set
+}
+
+func http2parseWindowUpdateFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (http2Frame, error) {
+ if len(p) != 4 {
+ countError("frame_windowupdate_bad_len")
+ return nil, http2ConnectionError(http2ErrCodeFrameSize)
+ }
+ inc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit
+ if inc == 0 {
+ // A receiver MUST treat the receipt of a
+ // WINDOW_UPDATE frame with an flow control window
+ // increment of 0 as a stream error (Section 5.4.2) of
+ // type PROTOCOL_ERROR; errors on the connection flow
+ // control window MUST be treated as a connection
+ // error (Section 5.4.1).
+ if fh.StreamID == 0 {
+ countError("frame_windowupdate_zero_inc_conn")
+ return nil, http2ConnectionError(http2ErrCodeProtocol)
+ }
+ countError("frame_windowupdate_zero_inc_stream")
+ return nil, http2streamError(fh.StreamID, http2ErrCodeProtocol)
+ }
+ return &http2WindowUpdateFrame{
+ http2FrameHeader: fh,
+ Increment: inc,
+ }, nil
+}
+
+// WriteWindowUpdate writes a WINDOW_UPDATE frame.
+// The increment value must be between 1 and 2,147,483,647, inclusive.
+// If the Stream ID is zero, the window update applies to the
+// connection as a whole.
+func (f *http2Framer) WriteWindowUpdate(streamID, incr uint32) error {
+ // "The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets."
+ if (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites {
+ return errors.New("illegal window increment value")
+ }
+ f.startWrite(http2FrameWindowUpdate, 0, streamID)
+ f.writeUint32(incr)
+ return f.endWrite()
+}
+
+// A HeadersFrame is used to open a stream and additionally carries a
+// header block fragment.
+type http2HeadersFrame struct {
+ http2FrameHeader
+
+ // Priority is set if FlagHeadersPriority is set in the FrameHeader.
+ Priority http2PriorityParam
+
+ headerFragBuf []byte // not owned
+}
+
+func (f *http2HeadersFrame) HeaderBlockFragment() []byte {
+ f.checkValid()
+ return f.headerFragBuf
+}
+
+func (f *http2HeadersFrame) HeadersEnded() bool {
+ return f.http2FrameHeader.Flags.Has(http2FlagHeadersEndHeaders)
+}
+
+func (f *http2HeadersFrame) StreamEnded() bool {
+ return f.http2FrameHeader.Flags.Has(http2FlagHeadersEndStream)
+}
+
+func (f *http2HeadersFrame) HasPriority() bool {
+ return f.http2FrameHeader.Flags.Has(http2FlagHeadersPriority)
+}
+
+func http2parseHeadersFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (_ http2Frame, err error) {
+ hf := &http2HeadersFrame{
+ http2FrameHeader: fh,
+ }
+ if fh.StreamID == 0 {
+ // HEADERS frames MUST be associated with a stream. If a HEADERS frame
+ // is received whose stream identifier field is 0x0, the recipient MUST
+ // respond with a connection error (Section 5.4.1) of type
+ // PROTOCOL_ERROR.
+ countError("frame_headers_zero_stream")
+ return nil, http2connError{http2ErrCodeProtocol, "HEADERS frame with stream ID 0"}
+ }
+ var padLength uint8
+ if fh.Flags.Has(http2FlagHeadersPadded) {
+ if p, padLength, err = http2readByte(p); err != nil {
+ countError("frame_headers_pad_short")
+ return
+ }
+ }
+ if fh.Flags.Has(http2FlagHeadersPriority) {
+ var v uint32
+ p, v, err = http2readUint32(p)
+ if err != nil {
+ countError("frame_headers_prio_short")
+ return nil, err
+ }
+ hf.Priority.StreamDep = v & 0x7fffffff
+ hf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set
+ p, hf.Priority.Weight, err = http2readByte(p)
+ if err != nil {
+ countError("frame_headers_prio_weight_short")
+ return nil, err
+ }
+ }
+ if len(p)-int(padLength) < 0 {
+ countError("frame_headers_pad_too_big")
+ return nil, http2streamError(fh.StreamID, http2ErrCodeProtocol)
+ }
+ hf.headerFragBuf = p[:len(p)-int(padLength)]
+ return hf, nil
+}
+
+// HeadersFrameParam are the parameters for writing a HEADERS frame.
+type http2HeadersFrameParam struct {
+ // StreamID is the required Stream ID to initiate.
+ StreamID uint32
+ // BlockFragment is part (or all) of a Header Block.
+ BlockFragment []byte
+
+ // EndStream indicates that the header block is the last that
+ // the endpoint will send for the identified stream. Setting
+ // this flag causes the stream to enter one of "half closed"
+ // states.
+ EndStream bool
+
+ // EndHeaders indicates that this frame contains an entire
+ // header block and is not followed by any
+ // CONTINUATION frames.
+ EndHeaders bool
+
+ // PadLength is the optional number of bytes of zeros to add
+ // to this frame.
+ PadLength uint8
+
+ // Priority, if non-zero, includes stream priority information
+ // in the HEADER frame.
+ Priority http2PriorityParam
+}
+
+// WriteHeaders writes a single HEADERS frame.
+//
+// This is a low-level header writing method. Encoding headers and
+// splitting them into any necessary CONTINUATION frames is handled
+// elsewhere.
+//
+// It will perform exactly one Write to the underlying Writer.
+// It is the caller's responsibility to not call other Write methods concurrently.
+func (f *http2Framer) WriteHeaders(p http2HeadersFrameParam) error {
+ if !http2validStreamID(p.StreamID) && !f.AllowIllegalWrites {
+ return http2errStreamID
+ }
+ var flags http2Flags
+ if p.PadLength != 0 {
+ flags |= http2FlagHeadersPadded
+ }
+ if p.EndStream {
+ flags |= http2FlagHeadersEndStream
+ }
+ if p.EndHeaders {
+ flags |= http2FlagHeadersEndHeaders
+ }
+ if !p.Priority.IsZero() {
+ flags |= http2FlagHeadersPriority
+ }
+ f.startWrite(http2FrameHeaders, flags, p.StreamID)
+ if p.PadLength != 0 {
+ f.writeByte(p.PadLength)
+ }
+ if !p.Priority.IsZero() {
+ v := p.Priority.StreamDep
+ if !http2validStreamIDOrZero(v) && !f.AllowIllegalWrites {
+ return http2errDepStreamID
+ }
+ if p.Priority.Exclusive {
+ v |= 1 << 31
+ }
+ f.writeUint32(v)
+ f.writeByte(p.Priority.Weight)
+ }
+ f.wbuf = append(f.wbuf, p.BlockFragment...)
+ f.wbuf = append(f.wbuf, http2padZeros[:p.PadLength]...)
+ return f.endWrite()
+}
+
+// A PriorityFrame specifies the sender-advised priority of a stream.
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3
+type http2PriorityFrame struct {
+ http2FrameHeader
+ http2PriorityParam
+}
+
+// PriorityParam are the stream prioritzation parameters.
+type http2PriorityParam struct {
+ // StreamDep is a 31-bit stream identifier for the
+ // stream that this stream depends on. Zero means no
+ // dependency.
+ StreamDep uint32
+
+ // Exclusive is whether the dependency is exclusive.
+ Exclusive bool
+
+ // Weight is the stream's zero-indexed weight. It should be
+ // set together with StreamDep, or neither should be set. Per
+ // the spec, "Add one to the value to obtain a weight between
+ // 1 and 256."
+ Weight uint8
+}
+
+func (p http2PriorityParam) IsZero() bool {
+ return p == http2PriorityParam{}
+}
+
+func http2parsePriorityFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), payload []byte) (http2Frame, error) {
+ if fh.StreamID == 0 {
+ countError("frame_priority_zero_stream")
+ return nil, http2connError{http2ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
+ }
+ if len(payload) != 5 {
+ countError("frame_priority_bad_length")
+ return nil, http2connError{http2ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
+ }
+ v := binary.BigEndian.Uint32(payload[:4])
+ streamID := v & 0x7fffffff // mask off high bit
+ return &http2PriorityFrame{
+ http2FrameHeader: fh,
+ http2PriorityParam: http2PriorityParam{
+ Weight: payload[4],
+ StreamDep: streamID,
+ Exclusive: streamID != v, // was high bit set?
+ },
+ }, nil
+}
+
+// WritePriority writes a PRIORITY frame.
+//
+// It will perform exactly one Write to the underlying Writer.
+// It is the caller's responsibility to not call other Write methods concurrently.
+func (f *http2Framer) WritePriority(streamID uint32, p http2PriorityParam) error {
+ if !http2validStreamID(streamID) && !f.AllowIllegalWrites {
+ return http2errStreamID
+ }
+ if !http2validStreamIDOrZero(p.StreamDep) {
+ return http2errDepStreamID
+ }
+ f.startWrite(http2FramePriority, 0, streamID)
+ v := p.StreamDep
+ if p.Exclusive {
+ v |= 1 << 31
+ }
+ f.writeUint32(v)
+ f.writeByte(p.Weight)
+ return f.endWrite()
+}
+
+// A RSTStreamFrame allows for abnormal termination of a stream.
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4
+type http2RSTStreamFrame struct {
+ http2FrameHeader
+ ErrCode http2ErrCode
+}
+
+func http2parseRSTStreamFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (http2Frame, error) {
+ if len(p) != 4 {
+ countError("frame_rststream_bad_len")
+ return nil, http2ConnectionError(http2ErrCodeFrameSize)
+ }
+ if fh.StreamID == 0 {
+ countError("frame_rststream_zero_stream")
+ return nil, http2ConnectionError(http2ErrCodeProtocol)
+ }
+ return &http2RSTStreamFrame{fh, http2ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil
+}
+
+// WriteRSTStream writes a RST_STREAM frame.
+//
+// It will perform exactly one Write to the underlying Writer.
+// It is the caller's responsibility to not call other Write methods concurrently.
+func (f *http2Framer) WriteRSTStream(streamID uint32, code http2ErrCode) error {
+ if !http2validStreamID(streamID) && !f.AllowIllegalWrites {
+ return http2errStreamID
+ }
+ f.startWrite(http2FrameRSTStream, 0, streamID)
+ f.writeUint32(uint32(code))
+ return f.endWrite()
+}
+
+// A ContinuationFrame is used to continue a sequence of header block fragments.
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10
+type http2ContinuationFrame struct {
+ http2FrameHeader
+ headerFragBuf []byte
+}
+
+func http2parseContinuationFrame(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (http2Frame, error) {
+ if fh.StreamID == 0 {
+ countError("frame_continuation_zero_stream")
+ return nil, http2connError{http2ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
+ }
+ return &http2ContinuationFrame{fh, p}, nil
+}
+
+func (f *http2ContinuationFrame) HeaderBlockFragment() []byte {
+ f.checkValid()
+ return f.headerFragBuf
+}
+
+func (f *http2ContinuationFrame) HeadersEnded() bool {
+ return f.http2FrameHeader.Flags.Has(http2FlagContinuationEndHeaders)
+}
+
+// WriteContinuation writes a CONTINUATION frame.
+//
+// It will perform exactly one Write to the underlying Writer.
+// It is the caller's responsibility to not call other Write methods concurrently.
+func (f *http2Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error {
+ if !http2validStreamID(streamID) && !f.AllowIllegalWrites {
+ return http2errStreamID
+ }
+ var flags http2Flags
+ if endHeaders {
+ flags |= http2FlagContinuationEndHeaders
+ }
+ f.startWrite(http2FrameContinuation, flags, streamID)
+ f.wbuf = append(f.wbuf, headerBlockFragment...)
+ return f.endWrite()
+}
+
+// A PushPromiseFrame is used to initiate a server stream.
+// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6
+type http2PushPromiseFrame struct {
+ http2FrameHeader
+ PromiseID uint32
+ headerFragBuf []byte // not owned
+}
+
+func (f *http2PushPromiseFrame) HeaderBlockFragment() []byte {
+ f.checkValid()
+ return f.headerFragBuf
+}
+
+func (f *http2PushPromiseFrame) HeadersEnded() bool {
+ return f.http2FrameHeader.Flags.Has(http2FlagPushPromiseEndHeaders)
+}
+
+func http2parsePushPromise(_ *http2frameCache, fh http2FrameHeader, countError func(string), p []byte) (_ http2Frame, err error) {
+ pp := &http2PushPromiseFrame{
+ http2FrameHeader: fh,
+ }
+ if pp.StreamID == 0 {
+ // PUSH_PROMISE frames MUST be associated with an existing,
+ // peer-initiated stream. The stream identifier of a
+ // PUSH_PROMISE frame indicates the stream it is associated
+ // with. If the stream identifier field specifies the value
+ // 0x0, a recipient MUST respond with a connection error
+ // (Section 5.4.1) of type PROTOCOL_ERROR.
+ countError("frame_pushpromise_zero_stream")
+ return nil, http2ConnectionError(http2ErrCodeProtocol)
+ }
+ // The PUSH_PROMISE frame includes optional padding.
+ // Padding fields and flags are identical to those defined for DATA frames
+ var padLength uint8
+ if fh.Flags.Has(http2FlagPushPromisePadded) {
+ if p, padLength, err = http2readByte(p); err != nil {
+ countError("frame_pushpromise_pad_short")
+ return
+ }
+ }
+
+ p, pp.PromiseID, err = http2readUint32(p)
+ if err != nil {
+ countError("frame_pushpromise_promiseid_short")
+ return
+ }
+ pp.PromiseID = pp.PromiseID & (1<<31 - 1)
+
+ if int(padLength) > len(p) {
+ // like the DATA frame, error out if padding is longer than the body.
+ countError("frame_pushpromise_pad_too_big")
+ return nil, http2ConnectionError(http2ErrCodeProtocol)
+ }
+ pp.headerFragBuf = p[:len(p)-int(padLength)]
+ return pp, nil
+}
+
+// PushPromiseParam are the parameters for writing a PUSH_PROMISE frame.
+type http2PushPromiseParam struct {
+ // StreamID is the required Stream ID to initiate.
+ StreamID uint32
+
+ // PromiseID is the required Stream ID which this
+ // Push Promises
+ PromiseID uint32
+
+ // BlockFragment is part (or all) of a Header Block.
+ BlockFragment []byte
+
+ // EndHeaders indicates that this frame contains an entire
+ // header block and is not followed by any
+ // CONTINUATION frames.
+ EndHeaders bool
+
+ // PadLength is the optional number of bytes of zeros to add
+ // to this frame.
+ PadLength uint8
+}
+
+// WritePushPromise writes a single PushPromise Frame.
+//
+// As with Header Frames, This is the low level call for writing
+// individual frames. Continuation frames are handled elsewhere.
+//
+// It will perform exactly one Write to the underlying Writer.
+// It is the caller's responsibility to not call other Write methods concurrently.
+func (f *http2Framer) WritePushPromise(p http2PushPromiseParam) error {
+ if !http2validStreamID(p.StreamID) && !f.AllowIllegalWrites {
+ return http2errStreamID
+ }
+ var flags http2Flags
+ if p.PadLength != 0 {
+ flags |= http2FlagPushPromisePadded
+ }
+ if p.EndHeaders {
+ flags |= http2FlagPushPromiseEndHeaders
+ }
+ f.startWrite(http2FramePushPromise, flags, p.StreamID)
+ if p.PadLength != 0 {
+ f.writeByte(p.PadLength)
+ }
+ if !http2validStreamID(p.PromiseID) && !f.AllowIllegalWrites {
+ return http2errStreamID
+ }
+ f.writeUint32(p.PromiseID)
+ f.wbuf = append(f.wbuf, p.BlockFragment...)
+ f.wbuf = append(f.wbuf, http2padZeros[:p.PadLength]...)
+ return f.endWrite()
+}
+
+// WriteRawFrame writes a raw frame. This can be used to write
+// extension frames unknown to this package.
+func (f *http2Framer) WriteRawFrame(t http2FrameType, flags http2Flags, streamID uint32, payload []byte) error {
+ f.startWrite(t, flags, streamID)
+ f.writeBytes(payload)
+ return f.endWrite()
+}
+
+func http2readByte(p []byte) (remain []byte, b byte, err error) {
+ if len(p) == 0 {
+ return nil, 0, io.ErrUnexpectedEOF
+ }
+ return p[1:], p[0], nil
+}
+
+func http2readUint32(p []byte) (remain []byte, v uint32, err error) {
+ if len(p) < 4 {
+ return nil, 0, io.ErrUnexpectedEOF
+ }
+ return p[4:], binary.BigEndian.Uint32(p[:4]), nil
+}
+
+type http2streamEnder interface {
+ StreamEnded() bool
+}
+
+type http2headersEnder interface {
+ HeadersEnded() bool
+}
+
+type http2headersOrContinuation interface {
+ http2headersEnder
+ HeaderBlockFragment() []byte
+}
+
+// A MetaHeadersFrame is the representation of one HEADERS frame and
+// zero or more contiguous CONTINUATION frames and the decoding of
+// their HPACK-encoded contents.
+//
+// This type of frame does not appear on the wire and is only returned
+// by the Framer when Framer.ReadMetaHeaders is set.
+type http2MetaHeadersFrame struct {
+ *http2HeadersFrame
+
+ // Fields are the fields contained in the HEADERS and
+ // CONTINUATION frames. The underlying slice is owned by the
+ // Framer and must not be retained after the next call to
+ // ReadFrame.
+ //
+ // Fields are guaranteed to be in the correct http2 order and
+ // not have unknown pseudo header fields or invalid header
+ // field names or values. Required pseudo header fields may be
+ // missing, however. Use the MetaHeadersFrame.Pseudo accessor
+ // method access pseudo headers.
+ Fields []hpack.HeaderField
+
+ // Truncated is whether the max header list size limit was hit
+ // and Fields is incomplete. The hpack decoder state is still
+ // valid, however.
+ Truncated bool
+}
+
+// PseudoValue returns the given pseudo header field's value.
+// The provided pseudo field should not contain the leading colon.
+func (mh *http2MetaHeadersFrame) PseudoValue(pseudo string) string {
+ for _, hf := range mh.Fields {
+ if !hf.IsPseudo() {
+ return ""
+ }
+ if hf.Name[1:] == pseudo {
+ return hf.Value
+ }
+ }
+ return ""
+}
+
+// RegularFields returns the regular (non-pseudo) header fields of mh.
+// The caller does not own the returned slice.
+func (mh *http2MetaHeadersFrame) RegularFields() []hpack.HeaderField {
+ for i, hf := range mh.Fields {
+ if !hf.IsPseudo() {
+ return mh.Fields[i:]
+ }
+ }
+ return nil
+}
+
+// PseudoFields returns the pseudo header fields of mh.
+// The caller does not own the returned slice.
+func (mh *http2MetaHeadersFrame) PseudoFields() []hpack.HeaderField {
+ for i, hf := range mh.Fields {
+ if !hf.IsPseudo() {
+ return mh.Fields[:i]
+ }
+ }
+ return mh.Fields
+}
+
+func (mh *http2MetaHeadersFrame) checkPseudos() error {
+ var isRequest, isResponse bool
+ pf := mh.PseudoFields()
+ for i, hf := range pf {
+ switch hf.Name {
+ case ":method", ":path", ":scheme", ":authority":
+ isRequest = true
+ case ":status":
+ isResponse = true
+ default:
+ return http2pseudoHeaderError(hf.Name)
+ }
+ // Check for duplicates.
+ // This would be a bad algorithm, but N is 4.
+ // And this doesn't allocate.
+ for _, hf2 := range pf[:i] {
+ if hf.Name == hf2.Name {
+ return http2duplicatePseudoHeaderError(hf.Name)
+ }
+ }
+ }
+ if isRequest && isResponse {
+ return http2errMixPseudoHeaderTypes
+ }
+ return nil
+}
+
+func (fr *http2Framer) maxHeaderStringLen() int {
+ v := fr.maxHeaderListSize()
+ if uint32(int(v)) == v {
+ return int(v)
+ }
+ // They had a crazy big number for MaxHeaderBytes anyway,
+ // so give them unlimited header lengths:
+ return 0
+}
+
+// readMetaFrame returns 0 or more CONTINUATION frames from fr and
+// merge them into the provided hf and returns a MetaHeadersFrame
+// with the decoded hpack values.
+func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFrame, error) {
+ if fr.AllowIllegalReads {
+ return nil, errors.New("illegal use of AllowIllegalReads with ReadMetaHeaders")
+ }
+ mh := &http2MetaHeadersFrame{
+ http2HeadersFrame: hf,
+ }
+ var remainSize = fr.maxHeaderListSize()
+ var sawRegular bool
+
+ var invalid error // pseudo header field errors
+ hdec := fr.ReadMetaHeaders
+ hdec.SetEmitEnabled(true)
+ hdec.SetMaxStringLength(fr.maxHeaderStringLen())
+ hdec.SetEmitFunc(func(hf hpack.HeaderField) {
+ if http2VerboseLogs && fr.logReads {
+ fr.debugReadLoggerf("http2: decoded hpack field %+v", hf)
+ }
+ if !httpguts.ValidHeaderFieldValue(hf.Value) {
+ // Don't include the value in the error, because it may be sensitive.
+ invalid = http2headerFieldValueError(hf.Name)
+ }
+ isPseudo := strings.HasPrefix(hf.Name, ":")
+ if isPseudo {
+ if sawRegular {
+ invalid = http2errPseudoAfterRegular
+ }
+ } else {
+ sawRegular = true
+ if !http2validWireHeaderFieldName(hf.Name) {
+ invalid = http2headerFieldNameError(hf.Name)
+ }
+ }
+
+ if invalid != nil {
+ hdec.SetEmitEnabled(false)
+ return
+ }
+
+ size := hf.Size()
+ if size > remainSize {
+ hdec.SetEmitEnabled(false)
+ mh.Truncated = true
+ return
+ }
+ remainSize -= size
+
+ mh.Fields = append(mh.Fields, hf)
+ })
+ // Lose reference to MetaHeadersFrame:
+ defer hdec.SetEmitFunc(func(hf hpack.HeaderField) {})
+
+ var hc http2headersOrContinuation = hf
+ for {
+ frag := hc.HeaderBlockFragment()
+ if _, err := hdec.Write(frag); err != nil {
+ return nil, http2ConnectionError(http2ErrCodeCompression)
+ }
+
+ if hc.HeadersEnded() {
+ break
+ }
+ if f, err := fr.ReadFrame(); err != nil {
+ return nil, err
+ } else {
+ hc = f.(*http2ContinuationFrame) // guaranteed by checkFrameOrder
+ }
+ }
+
+ mh.http2HeadersFrame.headerFragBuf = nil
+ mh.http2HeadersFrame.invalidate()
+
+ if err := hdec.Close(); err != nil {
+ return nil, http2ConnectionError(http2ErrCodeCompression)
+ }
+ if invalid != nil {
+ fr.errDetail = invalid
+ if http2VerboseLogs {
+ log.Printf("http2: invalid header: %v", invalid)
+ }
+ return nil, http2StreamError{mh.StreamID, http2ErrCodeProtocol, invalid}
+ }
+ if err := mh.checkPseudos(); err != nil {
+ fr.errDetail = err
+ if http2VerboseLogs {
+ log.Printf("http2: invalid pseudo headers: %v", err)
+ }
+ return nil, http2StreamError{mh.StreamID, http2ErrCodeProtocol, err}
+ }
+ return mh, nil
+}
+
+func http2summarizeFrame(f http2Frame) string {
+ var buf bytes.Buffer
+ f.Header().writeDebug(&buf)
+ switch f := f.(type) {
+ case *http2SettingsFrame:
+ n := 0
+ f.ForeachSetting(func(s http2Setting) error {
+ n++
+ if n == 1 {
+ buf.WriteString(", settings:")
+ }
+ fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val)
+ return nil
+ })
+ if n > 0 {
+ buf.Truncate(buf.Len() - 1) // remove trailing comma
+ }
+ case *http2DataFrame:
+ data := f.Data()
+ const max = 256
+ if len(data) > max {
+ data = data[:max]
+ }
+ fmt.Fprintf(&buf, " data=%q", data)
+ if len(f.Data()) > max {
+ fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max)
+ }
+ case *http2WindowUpdateFrame:
+ if f.StreamID == 0 {
+ buf.WriteString(" (conn)")
+ }
+ fmt.Fprintf(&buf, " incr=%v", f.Increment)
+ case *http2PingFrame:
+ fmt.Fprintf(&buf, " ping=%q", f.Data[:])
+ case *http2GoAwayFrame:
+ fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q",
+ f.LastStreamID, f.ErrCode, f.debugData)
+ case *http2RSTStreamFrame:
+ fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode)
+ }
+ return buf.String()
+}
+
+func http2traceHasWroteHeaderField(trace *httptrace.ClientTrace) bool {
+ return trace != nil && trace.WroteHeaderField != nil
+}
+
+func http2traceWroteHeaderField(trace *httptrace.ClientTrace, k, v string) {
+ if trace != nil && trace.WroteHeaderField != nil {
+ trace.WroteHeaderField(k, []string{v})
+ }
+}
+
+func http2traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error {
+ if trace != nil {
+ return trace.Got1xxResponse
+ }
+ return nil
+}
+
+// dialTLSWithContext uses tls.Dialer, added in Go 1.15, to open a TLS
+// connection.
+func (t *http2Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) {
+ dialer := &tls.Dialer{
+ Config: cfg,
+ }
+ cn, err := dialer.DialContext(ctx, network, addr)
+ if err != nil {
+ return nil, err
+ }
+ tlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed
+ return tlsCn, nil
+}
+
+func http2tlsUnderlyingConn(tc *tls.Conn) net.Conn {
+ return tc.NetConn()
+}
+
+var http2DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
+
+type http2goroutineLock uint64
+
+func http2newGoroutineLock() http2goroutineLock {
+ if !http2DebugGoroutines {
+ return 0
+ }
+ return http2goroutineLock(http2curGoroutineID())
+}
+
+func (g http2goroutineLock) check() {
+ if !http2DebugGoroutines {
+ return
+ }
+ if http2curGoroutineID() != uint64(g) {
+ panic("running on the wrong goroutine")
+ }
+}
+
+func (g http2goroutineLock) checkNotOn() {
+ if !http2DebugGoroutines {
+ return
+ }
+ if http2curGoroutineID() == uint64(g) {
+ panic("running on the wrong goroutine")
+ }
+}
+
+var http2goroutineSpace = []byte("goroutine ")
+
+func http2curGoroutineID() uint64 {
+ bp := http2littleBuf.Get().(*[]byte)
+ defer http2littleBuf.Put(bp)
+ b := *bp
+ b = b[:runtime.Stack(b, false)]
+ // Parse the 4707 out of "goroutine 4707 ["
+ b = bytes.TrimPrefix(b, http2goroutineSpace)
+ i := bytes.IndexByte(b, ' ')
+ if i < 0 {
+ panic(fmt.Sprintf("No space found in %q", b))
+ }
+ b = b[:i]
+ n, err := http2parseUintBytes(b, 10, 64)
+ if err != nil {
+ panic(fmt.Sprintf("Failed to parse goroutine ID out of %q: %v", b, err))
+ }
+ return n
+}
+
+var http2littleBuf = sync.Pool{
+ New: func() interface{} {
+ buf := make([]byte, 64)
+ return &buf
+ },
+}
+
+// parseUintBytes is like strconv.ParseUint, but using a []byte.
+func http2parseUintBytes(s []byte, base int, bitSize int) (n uint64, err error) {
+ var cutoff, maxVal uint64
+
+ if bitSize == 0 {
+ bitSize = int(strconv.IntSize)
+ }
+
+ s0 := s
+ switch {
+ case len(s) < 1:
+ err = strconv.ErrSyntax
+ goto Error
+
+ case 2 <= base && base <= 36:
+ // valid base; nothing to do
+
+ case base == 0:
+ // Look for octal, hex prefix.
+ switch {
+ case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
+ base = 16
+ s = s[2:]
+ if len(s) < 1 {
+ err = strconv.ErrSyntax
+ goto Error
+ }
+ case s[0] == '0':
+ base = 8
+ default:
+ base = 10
+ }
+
+ default:
+ err = errors.New("invalid base " + strconv.Itoa(base))
+ goto Error
+ }
+
+ n = 0
+ cutoff = http2cutoff64(base)
+ maxVal = 1<<uint(bitSize) - 1
+
+ for i := 0; i < len(s); i++ {
+ var v byte
+ d := s[i]
+ switch {
+ case '0' <= d && d <= '9':
+ v = d - '0'
+ case 'a' <= d && d <= 'z':
+ v = d - 'a' + 10
+ case 'A' <= d && d <= 'Z':
+ v = d - 'A' + 10
+ default:
+ n = 0
+ err = strconv.ErrSyntax
+ goto Error
+ }
+ if int(v) >= base {
+ n = 0
+ err = strconv.ErrSyntax
+ goto Error
+ }
+
+ if n >= cutoff {
+ // n*base overflows
+ n = 1<<64 - 1
+ err = strconv.ErrRange
+ goto Error
+ }
+ n *= uint64(base)
+
+ n1 := n + uint64(v)
+ if n1 < n || n1 > maxVal {
+ // n+v overflows
+ n = 1<<64 - 1
+ err = strconv.ErrRange
+ goto Error
+ }
+ n = n1
+ }
+
+ return n, nil
+
+Error:
+ return n, &strconv.NumError{Func: "ParseUint", Num: string(s0), Err: err}
+}
+
+// Return the first number n such that n*base >= 1<<64.
+func http2cutoff64(base int) uint64 {
+ if base < 2 {
+ return 0
+ }
+ return (1<<64-1)/uint64(base) + 1
+}
+
+var (
+ http2commonBuildOnce sync.Once
+ http2commonLowerHeader map[string]string // Go-Canonical-Case -> lower-case
+ http2commonCanonHeader map[string]string // lower-case -> Go-Canonical-Case
+)
+
+func http2buildCommonHeaderMapsOnce() {
+ http2commonBuildOnce.Do(http2buildCommonHeaderMaps)
+}
+
+func http2buildCommonHeaderMaps() {
+ common := []string{
+ "accept",
+ "accept-charset",
+ "accept-encoding",
+ "accept-language",
+ "accept-ranges",
+ "age",
+ "access-control-allow-credentials",
+ "access-control-allow-headers",
+ "access-control-allow-methods",
+ "access-control-allow-origin",
+ "access-control-expose-headers",
+ "access-control-max-age",
+ "access-control-request-headers",
+ "access-control-request-method",
+ "allow",
+ "authorization",
+ "cache-control",
+ "content-disposition",
+ "content-encoding",
+ "content-language",
+ "content-length",
+ "content-location",
+ "content-range",
+ "content-type",
+ "cookie",
+ "date",
+ "etag",
+ "expect",
+ "expires",
+ "from",
+ "host",
+ "if-match",
+ "if-modified-since",
+ "if-none-match",
+ "if-unmodified-since",
+ "last-modified",
+ "link",
+ "location",
+ "max-forwards",
+ "origin",
+ "proxy-authenticate",
+ "proxy-authorization",
+ "range",
+ "referer",
+ "refresh",
+ "retry-after",
+ "server",
+ "set-cookie",
+ "strict-transport-security",
+ "trailer",
+ "transfer-encoding",
+ "user-agent",
+ "vary",
+ "via",
+ "www-authenticate",
+ "x-forwarded-for",
+ "x-forwarded-proto",
+ }
+ http2commonLowerHeader = make(map[string]string, len(common))
+ http2commonCanonHeader = make(map[string]string, len(common))
+ for _, v := range common {
+ chk := CanonicalHeaderKey(v)
+ http2commonLowerHeader[chk] = v
+ http2commonCanonHeader[v] = chk
+ }
+}
+
+func http2lowerHeader(v string) (lower string, ascii bool) {
+ http2buildCommonHeaderMapsOnce()
+ if s, ok := http2commonLowerHeader[v]; ok {
+ return s, true
+ }
+ return http2asciiToLower(v)
+}
+
+func http2canonicalHeader(v string) string {
+ http2buildCommonHeaderMapsOnce()
+ if s, ok := http2commonCanonHeader[v]; ok {
+ return s
+ }
+ return CanonicalHeaderKey(v)
+}
+
+var (
+ http2VerboseLogs bool
+ http2logFrameWrites bool
+ http2logFrameReads bool
+ http2inTests bool
+)
+
+func init() {
+ e := os.Getenv("GODEBUG")
+ if strings.Contains(e, "http2debug=1") {
+ http2VerboseLogs = true
+ }
+ if strings.Contains(e, "http2debug=2") {
+ http2VerboseLogs = true
+ http2logFrameWrites = true
+ http2logFrameReads = true
+ }
+}
+
+const (
+ // ClientPreface is the string that must be sent by new
+ // connections from clients.
+ http2ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
+
+ // SETTINGS_MAX_FRAME_SIZE default
+ // https://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2
+ http2initialMaxFrameSize = 16384
+
+ // NextProtoTLS is the NPN/ALPN protocol negotiated during
+ // HTTP/2's TLS setup.
+ http2NextProtoTLS = "h2"
+
+ // https://httpwg.org/specs/rfc7540.html#SettingValues
+ http2initialHeaderTableSize = 4096
+
+ http2initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size
+
+ http2defaultMaxReadFrameSize = 1 << 20
+)
+
+var (
+ http2clientPreface = []byte(http2ClientPreface)
+)
+
+type http2streamState int
+
+// HTTP/2 stream states.
+//
+// See http://tools.ietf.org/html/rfc7540#section-5.1.
+//
+// For simplicity, the server code merges "reserved (local)" into
+// "half-closed (remote)". This is one less state transition to track.
+// The only downside is that we send PUSH_PROMISEs slightly less
+// liberally than allowable. More discussion here:
+// https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0599.html
+//
+// "reserved (remote)" is omitted since the client code does not
+// support server push.
+const (
+ http2stateIdle http2streamState = iota
+ http2stateOpen
+ http2stateHalfClosedLocal
+ http2stateHalfClosedRemote
+ http2stateClosed
+)
+
+var http2stateName = [...]string{
+ http2stateIdle: "Idle",
+ http2stateOpen: "Open",
+ http2stateHalfClosedLocal: "HalfClosedLocal",
+ http2stateHalfClosedRemote: "HalfClosedRemote",
+ http2stateClosed: "Closed",
+}
+
+func (st http2streamState) String() string {
+ return http2stateName[st]
+}
+
+// Setting is a setting parameter: which setting it is, and its value.
+type http2Setting struct {
+ // ID is which setting is being set.
+ // See https://httpwg.org/specs/rfc7540.html#SettingFormat
+ ID http2SettingID
+
+ // Val is the value.
+ Val uint32
+}
+
+func (s http2Setting) String() string {
+ return fmt.Sprintf("[%v = %d]", s.ID, s.Val)
+}
+
+// Valid reports whether the setting is valid.
+func (s http2Setting) Valid() error {
+ // Limits and error codes from 6.5.2 Defined SETTINGS Parameters
+ switch s.ID {
+ case http2SettingEnablePush:
+ if s.Val != 1 && s.Val != 0 {
+ return http2ConnectionError(http2ErrCodeProtocol)
+ }
+ case http2SettingInitialWindowSize:
+ if s.Val > 1<<31-1 {
+ return http2ConnectionError(http2ErrCodeFlowControl)
+ }
+ case http2SettingMaxFrameSize:
+ if s.Val < 16384 || s.Val > 1<<24-1 {
+ return http2ConnectionError(http2ErrCodeProtocol)
+ }
+ }
+ return nil
+}
+
+// A SettingID is an HTTP/2 setting as defined in
+// https://httpwg.org/specs/rfc7540.html#iana-settings
+type http2SettingID uint16
+
+const (
+ http2SettingHeaderTableSize http2SettingID = 0x1
+ http2SettingEnablePush http2SettingID = 0x2
+ http2SettingMaxConcurrentStreams http2SettingID = 0x3
+ http2SettingInitialWindowSize http2SettingID = 0x4
+ http2SettingMaxFrameSize http2SettingID = 0x5
+ http2SettingMaxHeaderListSize http2SettingID = 0x6
+)
+
+var http2settingName = map[http2SettingID]string{
+ http2SettingHeaderTableSize: "HEADER_TABLE_SIZE",
+ http2SettingEnablePush: "ENABLE_PUSH",
+ http2SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS",
+ http2SettingInitialWindowSize: "INITIAL_WINDOW_SIZE",
+ http2SettingMaxFrameSize: "MAX_FRAME_SIZE",
+ http2SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE",
+}
+
+func (s http2SettingID) String() string {
+ if v, ok := http2settingName[s]; ok {
+ return v
+ }
+ return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s))
+}
+
+// validWireHeaderFieldName reports whether v is a valid header field
+// name (key). See httpguts.ValidHeaderName for the base rules.
+//
+// Further, http2 says:
+//
+// "Just as in HTTP/1.x, header field names are strings of ASCII
+// characters that are compared in a case-insensitive
+// fashion. However, header field names MUST be converted to
+// lowercase prior to their encoding in HTTP/2. "
+func http2validWireHeaderFieldName(v string) bool {
+ if len(v) == 0 {
+ return false
+ }
+ for _, r := range v {
+ if !httpguts.IsTokenRune(r) {
+ return false
+ }
+ if 'A' <= r && r <= 'Z' {
+ return false
+ }
+ }
+ return true
+}
+
+func http2httpCodeString(code int) string {
+ switch code {
+ case 200:
+ return "200"
+ case 404:
+ return "404"
+ }
+ return strconv.Itoa(code)
+}
+
+// from pkg io
+type http2stringWriter interface {
+ WriteString(s string) (n int, err error)
+}
+
+// A gate lets two goroutines coordinate their activities.
+type http2gate chan struct{}
+
+func (g http2gate) Done() { g <- struct{}{} }
+
+func (g http2gate) Wait() { <-g }
+
+// A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).
+type http2closeWaiter chan struct{}
+
+// Init makes a closeWaiter usable.
+// It exists because so a closeWaiter value can be placed inside a
+// larger struct and have the Mutex and Cond's memory in the same
+// allocation.
+func (cw *http2closeWaiter) Init() {
+ *cw = make(chan struct{})
+}
+
+// Close marks the closeWaiter as closed and unblocks any waiters.
+func (cw http2closeWaiter) Close() {
+ close(cw)
+}
+
+// Wait waits for the closeWaiter to become closed.
+func (cw http2closeWaiter) Wait() {
+ <-cw
+}
+
+// bufferedWriter is a buffered writer that writes to w.
+// Its buffered writer is lazily allocated as needed, to minimize
+// idle memory usage with many connections.
+type http2bufferedWriter struct {
+ _ http2incomparable
+ w io.Writer // immutable
+ bw *bufio.Writer // non-nil when data is buffered
+}
+
+func http2newBufferedWriter(w io.Writer) *http2bufferedWriter {
+ return &http2bufferedWriter{w: w}
+}
+
+// bufWriterPoolBufferSize is the size of bufio.Writer's
+// buffers created using bufWriterPool.
+//
+// TODO: pick a less arbitrary value? this is a bit under
+// (3 x typical 1500 byte MTU) at least. Other than that,
+// not much thought went into it.
+const http2bufWriterPoolBufferSize = 4 << 10
+
+var http2bufWriterPool = sync.Pool{
+ New: func() interface{} {
+ return bufio.NewWriterSize(nil, http2bufWriterPoolBufferSize)
+ },
+}
+
+func (w *http2bufferedWriter) Available() int {
+ if w.bw == nil {
+ return http2bufWriterPoolBufferSize
+ }
+ return w.bw.Available()
+}
+
+func (w *http2bufferedWriter) Write(p []byte) (n int, err error) {
+ if w.bw == nil {
+ bw := http2bufWriterPool.Get().(*bufio.Writer)
+ bw.Reset(w.w)
+ w.bw = bw
+ }
+ return w.bw.Write(p)
+}
+
+func (w *http2bufferedWriter) Flush() error {
+ bw := w.bw
+ if bw == nil {
+ return nil
+ }
+ err := bw.Flush()
+ bw.Reset(nil)
+ http2bufWriterPool.Put(bw)
+ w.bw = nil
+ return err
+}
+
+func http2mustUint31(v int32) uint32 {
+ if v < 0 || v > 2147483647 {
+ panic("out of range")
+ }
+ return uint32(v)
+}
+
+// bodyAllowedForStatus reports whether a given response status code
+// permits a body. See RFC 7230, section 3.3.
+func http2bodyAllowedForStatus(status int) bool {
+ switch {
+ case status >= 100 && status <= 199:
+ return false
+ case status == 204:
+ return false
+ case status == 304:
+ return false
+ }
+ return true
+}
+
+type http2httpError struct {
+ _ http2incomparable
+ msg string
+ timeout bool
+}
+
+func (e *http2httpError) Error() string { return e.msg }
+
+func (e *http2httpError) Timeout() bool { return e.timeout }
+
+func (e *http2httpError) Temporary() bool { return true }
+
+var http2errTimeout error = &http2httpError{msg: "http2: timeout awaiting response headers", timeout: true}
+
+type http2connectionStater interface {
+ ConnectionState() tls.ConnectionState
+}
+
+var http2sorterPool = sync.Pool{New: func() interface{} { return new(http2sorter) }}
+
+type http2sorter struct {
+ v []string // owned by sorter
+}
+
+func (s *http2sorter) Len() int { return len(s.v) }
+
+func (s *http2sorter) Swap(i, j int) { s.v[i], s.v[j] = s.v[j], s.v[i] }
+
+func (s *http2sorter) Less(i, j int) bool { return s.v[i] < s.v[j] }
+
+// Keys returns the sorted keys of h.
+//
+// The returned slice is only valid until s used again or returned to
+// its pool.
+func (s *http2sorter) Keys(h Header) []string {
+ keys := s.v[:0]
+ for k := range h {
+ keys = append(keys, k)
+ }
+ s.v = keys
+ sort.Sort(s)
+ return keys
+}
+
+func (s *http2sorter) SortStrings(ss []string) {
+ // Our sorter works on s.v, which sorter owns, so
+ // stash it away while we sort the user's buffer.
+ save := s.v
+ s.v = ss
+ sort.Sort(s)
+ s.v = save
+}
+
+// validPseudoPath reports whether v is a valid :path pseudo-header
+// value. It must be either:
+//
+// - a non-empty string starting with '/'
+// - the string '*', for OPTIONS requests.
+//
+// For now this is only used a quick check for deciding when to clean
+// up Opaque URLs before sending requests from the Transport.
+// See golang.org/issue/16847
+//
+// We used to enforce that the path also didn't start with "//", but
+// Google's GFE accepts such paths and Chrome sends them, so ignore
+// that part of the spec. See golang.org/issue/19103.
+func http2validPseudoPath(v string) bool {
+ return (len(v) > 0 && v[0] == '/') || v == "*"
+}
+
+// incomparable is a zero-width, non-comparable type. Adding it to a struct
+// makes that struct also non-comparable, and generally doesn't add
+// any size (as long as it's first).
+type http2incomparable [0]func()
+
+// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like
+// io.Pipe except there are no PipeReader/PipeWriter halves, and the
+// underlying buffer is an interface. (io.Pipe is always unbuffered)
+type http2pipe struct {
+ mu sync.Mutex
+ c sync.Cond // c.L lazily initialized to &p.mu
+ b http2pipeBuffer // nil when done reading
+ unread int // bytes unread when done
+ err error // read error once empty. non-nil means closed.
+ breakErr error // immediate read error (caller doesn't see rest of b)
+ donec chan struct{} // closed on error
+ readFn func() // optional code to run in Read before error
+}
+
+type http2pipeBuffer interface {
+ Len() int
+ io.Writer
+ io.Reader
+}
+
+// setBuffer initializes the pipe buffer.
+// It has no effect if the pipe is already closed.
+func (p *http2pipe) setBuffer(b http2pipeBuffer) {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ if p.err != nil || p.breakErr != nil {
+ return
+ }
+ p.b = b
+}
+
+func (p *http2pipe) Len() int {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ if p.b == nil {
+ return p.unread
+ }
+ return p.b.Len()
+}
+
+// Read waits until data is available and copies bytes
+// from the buffer into p.
+func (p *http2pipe) Read(d []byte) (n int, err error) {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ if p.c.L == nil {
+ p.c.L = &p.mu
+ }
+ for {
+ if p.breakErr != nil {
+ return 0, p.breakErr
+ }
+ if p.b != nil && p.b.Len() > 0 {
+ return p.b.Read(d)
+ }
+ if p.err != nil {
+ if p.readFn != nil {
+ p.readFn() // e.g. copy trailers
+ p.readFn = nil // not sticky like p.err
+ }
+ p.b = nil
+ return 0, p.err
+ }
+ p.c.Wait()
+ }
+}
+
+var http2errClosedPipeWrite = errors.New("write on closed buffer")
+
+// Write copies bytes from p into the buffer and wakes a reader.
+// It is an error to write more data than the buffer can hold.
+func (p *http2pipe) Write(d []byte) (n int, err error) {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ if p.c.L == nil {
+ p.c.L = &p.mu
+ }
+ defer p.c.Signal()
+ if p.err != nil || p.breakErr != nil {
+ return 0, http2errClosedPipeWrite
+ }
+ return p.b.Write(d)
+}
+
+// CloseWithError causes the next Read (waking up a current blocked
+// Read if needed) to return the provided err after all data has been
+// read.
+//
+// The error must be non-nil.
+func (p *http2pipe) CloseWithError(err error) { p.closeWithError(&p.err, err, nil) }
+
+// BreakWithError causes the next Read (waking up a current blocked
+// Read if needed) to return the provided err immediately, without
+// waiting for unread data.
+func (p *http2pipe) BreakWithError(err error) { p.closeWithError(&p.breakErr, err, nil) }
+
+// closeWithErrorAndCode is like CloseWithError but also sets some code to run
+// in the caller's goroutine before returning the error.
+func (p *http2pipe) closeWithErrorAndCode(err error, fn func()) { p.closeWithError(&p.err, err, fn) }
+
+func (p *http2pipe) closeWithError(dst *error, err error, fn func()) {
+ if err == nil {
+ panic("err must be non-nil")
+ }
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ if p.c.L == nil {
+ p.c.L = &p.mu
+ }
+ defer p.c.Signal()
+ if *dst != nil {
+ // Already been done.
+ return
+ }
+ p.readFn = fn
+ if dst == &p.breakErr {
+ if p.b != nil {
+ p.unread += p.b.Len()
+ }
+ p.b = nil
+ }
+ *dst = err
+ p.closeDoneLocked()
+}
+
+// requires p.mu be held.
+func (p *http2pipe) closeDoneLocked() {
+ if p.donec == nil {
+ return
+ }
+ // Close if unclosed. This isn't racy since we always
+ // hold p.mu while closing.
+ select {
+ case <-p.donec:
+ default:
+ close(p.donec)
+ }
+}
+
+// Err returns the error (if any) first set by BreakWithError or CloseWithError.
+func (p *http2pipe) Err() error {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ if p.breakErr != nil {
+ return p.breakErr
+ }
+ return p.err
+}
+
+// Done returns a channel which is closed if and when this pipe is closed
+// with CloseWithError.
+func (p *http2pipe) Done() <-chan struct{} {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ if p.donec == nil {
+ p.donec = make(chan struct{})
+ if p.err != nil || p.breakErr != nil {
+ // Already hit an error.
+ p.closeDoneLocked()
+ }
+ }
+ return p.donec
+}
+
+const (
+ http2prefaceTimeout = 10 * time.Second
+ http2firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway
+ http2handlerChunkWriteSize = 4 << 10
+ http2defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to?
+ http2maxQueuedControlFrames = 10000
+)
+
+var (
+ http2errClientDisconnected = errors.New("client disconnected")
+ http2errClosedBody = errors.New("body closed by handler")
+ http2errHandlerComplete = errors.New("http2: request body closed due to handler exiting")
+ http2errStreamClosed = errors.New("http2: stream closed")
+)
+
+var http2responseWriterStatePool = sync.Pool{
+ New: func() interface{} {
+ rws := &http2responseWriterState{}
+ rws.bw = bufio.NewWriterSize(http2chunkWriter{rws}, http2handlerChunkWriteSize)
+ return rws
+ },
+}
+
+// Test hooks.
+var (
+ http2testHookOnConn func()
+ http2testHookGetServerConn func(*http2serverConn)
+ http2testHookOnPanicMu *sync.Mutex // nil except in tests
+ http2testHookOnPanic func(sc *http2serverConn, panicVal interface{}) (rePanic bool)
+)
+
+// Server is an HTTP/2 server.
+type http2Server struct {
+ // MaxHandlers limits the number of http.Handler ServeHTTP goroutines
+ // which may run at a time over all connections.
+ // Negative or zero no limit.
+ // TODO: implement
+ MaxHandlers int
+
+ // MaxConcurrentStreams optionally specifies the number of
+ // concurrent streams that each client may have open at a
+ // time. This is unrelated to the number of http.Handler goroutines
+ // which may be active globally, which is MaxHandlers.
+ // If zero, MaxConcurrentStreams defaults to at least 100, per
+ // the HTTP/2 spec's recommendations.
+ MaxConcurrentStreams uint32
+
+ // MaxDecoderHeaderTableSize optionally specifies the http2
+ // SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It
+ // informs the remote endpoint of the maximum size of the header compression
+ // table used to decode header blocks, in octets. If zero, the default value
+ // of 4096 is used.
+ MaxDecoderHeaderTableSize uint32
+
+ // MaxEncoderHeaderTableSize optionally specifies an upper limit for the
+ // header compression table used for encoding request headers. Received
+ // SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero,
+ // the default value of 4096 is used.
+ MaxEncoderHeaderTableSize uint32
+
+ // MaxReadFrameSize optionally specifies the largest frame
+ // this server is willing to read. A valid value is between
+ // 16k and 16M, inclusive. If zero or otherwise invalid, a
+ // default value is used.
+ MaxReadFrameSize uint32
+
+ // PermitProhibitedCipherSuites, if true, permits the use of
+ // cipher suites prohibited by the HTTP/2 spec.
+ PermitProhibitedCipherSuites bool
+
+ // IdleTimeout specifies how long until idle clients should be
+ // closed with a GOAWAY frame. PING frames are not considered
+ // activity for the purposes of IdleTimeout.
+ IdleTimeout time.Duration
+
+ // MaxUploadBufferPerConnection is the size of the initial flow
+ // control window for each connections. The HTTP/2 spec does not
+ // allow this to be smaller than 65535 or larger than 2^32-1.
+ // If the value is outside this range, a default value will be
+ // used instead.
+ MaxUploadBufferPerConnection int32
+
+ // MaxUploadBufferPerStream is the size of the initial flow control
+ // window for each stream. The HTTP/2 spec does not allow this to
+ // be larger than 2^32-1. If the value is zero or larger than the
+ // maximum, a default value will be used instead.
+ MaxUploadBufferPerStream int32
+
+ // NewWriteScheduler constructs a write scheduler for a connection.
+ // If nil, a default scheduler is chosen.
+ NewWriteScheduler func() http2WriteScheduler
+
+ // CountError, if non-nil, is called on HTTP/2 server errors.
+ // It's intended to increment a metric for monitoring, such
+ // as an expvar or Prometheus metric.
+ // The errType consists of only ASCII word characters.
+ CountError func(errType string)
+
+ // Internal state. This is a pointer (rather than embedded directly)
+ // so that we don't embed a Mutex in this struct, which will make the
+ // struct non-copyable, which might break some callers.
+ state *http2serverInternalState
+}
+
+func (s *http2Server) initialConnRecvWindowSize() int32 {
+ if s.MaxUploadBufferPerConnection >= http2initialWindowSize {
+ return s.MaxUploadBufferPerConnection
+ }
+ return 1 << 20
+}
+
+func (s *http2Server) initialStreamRecvWindowSize() int32 {
+ if s.MaxUploadBufferPerStream > 0 {
+ return s.MaxUploadBufferPerStream
+ }
+ return 1 << 20
+}
+
+func (s *http2Server) maxReadFrameSize() uint32 {
+ if v := s.MaxReadFrameSize; v >= http2minMaxFrameSize && v <= http2maxFrameSize {
+ return v
+ }
+ return http2defaultMaxReadFrameSize
+}
+
+func (s *http2Server) maxConcurrentStreams() uint32 {
+ if v := s.MaxConcurrentStreams; v > 0 {
+ return v
+ }
+ return http2defaultMaxStreams
+}
+
+func (s *http2Server) maxDecoderHeaderTableSize() uint32 {
+ if v := s.MaxDecoderHeaderTableSize; v > 0 {
+ return v
+ }
+ return http2initialHeaderTableSize
+}
+
+func (s *http2Server) maxEncoderHeaderTableSize() uint32 {
+ if v := s.MaxEncoderHeaderTableSize; v > 0 {
+ return v
+ }
+ return http2initialHeaderTableSize
+}
+
+// maxQueuedControlFrames is the maximum number of control frames like
+// SETTINGS, PING and RST_STREAM that will be queued for writing before
+// the connection is closed to prevent memory exhaustion attacks.
+func (s *http2Server) maxQueuedControlFrames() int {
+ // TODO: if anybody asks, add a Server field, and remember to define the
+ // behavior of negative values.
+ return http2maxQueuedControlFrames
+}
+
+type http2serverInternalState struct {
+ mu sync.Mutex
+ activeConns map[*http2serverConn]struct{}
+}
+
+func (s *http2serverInternalState) registerConn(sc *http2serverConn) {
+ if s == nil {
+ return // if the Server was used without calling ConfigureServer
+ }
+ s.mu.Lock()
+ s.activeConns[sc] = struct{}{}
+ s.mu.Unlock()
+}
+
+func (s *http2serverInternalState) unregisterConn(sc *http2serverConn) {
+ if s == nil {
+ return // if the Server was used without calling ConfigureServer
+ }
+ s.mu.Lock()
+ delete(s.activeConns, sc)
+ s.mu.Unlock()
+}
+
+func (s *http2serverInternalState) startGracefulShutdown() {
+ if s == nil {
+ return // if the Server was used without calling ConfigureServer
+ }
+ s.mu.Lock()
+ for sc := range s.activeConns {
+ sc.startGracefulShutdown()
+ }
+ s.mu.Unlock()
+}
+
+// ConfigureServer adds HTTP/2 support to a net/http Server.
+//
+// The configuration conf may be nil.
+//
+// ConfigureServer must be called before s begins serving.
+func http2ConfigureServer(s *Server, conf *http2Server) error {
+ if s == nil {
+ panic("nil *http.Server")
+ }
+ if conf == nil {
+ conf = new(http2Server)
+ }
+ conf.state = &http2serverInternalState{activeConns: make(map[*http2serverConn]struct{})}
+ if h1, h2 := s, conf; h2.IdleTimeout == 0 {
+ if h1.IdleTimeout != 0 {
+ h2.IdleTimeout = h1.IdleTimeout
+ } else {
+ h2.IdleTimeout = h1.ReadTimeout
+ }
+ }
+ s.RegisterOnShutdown(conf.state.startGracefulShutdown)
+
+ if s.TLSConfig == nil {
+ s.TLSConfig = new(tls.Config)
+ } else if s.TLSConfig.CipherSuites != nil && s.TLSConfig.MinVersion < tls.VersionTLS13 {
+ // If they already provided a TLS 1.0–1.2 CipherSuite list, return an
+ // error if it is missing ECDHE_RSA_WITH_AES_128_GCM_SHA256 or
+ // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256.
+ haveRequired := false
+ for _, cs := range s.TLSConfig.CipherSuites {
+ switch cs {
+ case tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ // Alternative MTI cipher to not discourage ECDSA-only servers.
+ // See http://golang.org/cl/30721 for further information.
+ tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+ haveRequired = true
+ }
+ }
+ if !haveRequired {
+ return fmt.Errorf("http2: TLSConfig.CipherSuites is missing an HTTP/2-required AES_128_GCM_SHA256 cipher (need at least one of TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 or TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)")
+ }
+ }
+
+ // Note: not setting MinVersion to tls.VersionTLS12,
+ // as we don't want to interfere with HTTP/1.1 traffic
+ // on the user's server. We enforce TLS 1.2 later once
+ // we accept a connection. Ideally this should be done
+ // during next-proto selection, but using TLS <1.2 with
+ // HTTP/2 is still the client's bug.
+
+ s.TLSConfig.PreferServerCipherSuites = true
+
+ if !http2strSliceContains(s.TLSConfig.NextProtos, http2NextProtoTLS) {
+ s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, http2NextProtoTLS)
+ }
+ if !http2strSliceContains(s.TLSConfig.NextProtos, "http/1.1") {
+ s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "http/1.1")
+ }
+
+ if s.TLSNextProto == nil {
+ s.TLSNextProto = map[string]func(*Server, *tls.Conn, Handler){}
+ }
+ protoHandler := func(hs *Server, c *tls.Conn, h Handler) {
+ if http2testHookOnConn != nil {
+ http2testHookOnConn()
+ }
+ // The TLSNextProto interface predates contexts, so
+ // the net/http package passes down its per-connection
+ // base context via an exported but unadvertised
+ // method on the Handler. This is for internal
+ // net/http<=>http2 use only.
+ var ctx context.Context
+ type baseContexter interface {
+ BaseContext() context.Context
+ }
+ if bc, ok := h.(baseContexter); ok {
+ ctx = bc.BaseContext()
+ }
+ conf.ServeConn(c, &http2ServeConnOpts{
+ Context: ctx,
+ Handler: h,
+ BaseConfig: hs,
+ })
+ }
+ s.TLSNextProto[http2NextProtoTLS] = protoHandler
+ return nil
+}
+
+// ServeConnOpts are options for the Server.ServeConn method.
+type http2ServeConnOpts struct {
+ // Context is the base context to use.
+ // If nil, context.Background is used.
+ Context context.Context
+
+ // BaseConfig optionally sets the base configuration
+ // for values. If nil, defaults are used.
+ BaseConfig *Server
+
+ // Handler specifies which handler to use for processing
+ // requests. If nil, BaseConfig.Handler is used. If BaseConfig
+ // or BaseConfig.Handler is nil, http.DefaultServeMux is used.
+ Handler Handler
+
+ // UpgradeRequest is an initial request received on a connection
+ // undergoing an h2c upgrade. The request body must have been
+ // completely read from the connection before calling ServeConn,
+ // and the 101 Switching Protocols response written.
+ UpgradeRequest *Request
+
+ // Settings is the decoded contents of the HTTP2-Settings header
+ // in an h2c upgrade request.
+ Settings []byte
+
+ // SawClientPreface is set if the HTTP/2 connection preface
+ // has already been read from the connection.
+ SawClientPreface bool
+}
+
+func (o *http2ServeConnOpts) context() context.Context {
+ if o != nil && o.Context != nil {
+ return o.Context
+ }
+ return context.Background()
+}
+
+func (o *http2ServeConnOpts) baseConfig() *Server {
+ if o != nil && o.BaseConfig != nil {
+ return o.BaseConfig
+ }
+ return new(Server)
+}
+
+func (o *http2ServeConnOpts) handler() Handler {
+ if o != nil {
+ if o.Handler != nil {
+ return o.Handler
+ }
+ if o.BaseConfig != nil && o.BaseConfig.Handler != nil {
+ return o.BaseConfig.Handler
+ }
+ }
+ return DefaultServeMux
+}
+
+// ServeConn serves HTTP/2 requests on the provided connection and
+// blocks until the connection is no longer readable.
+//
+// ServeConn starts speaking HTTP/2 assuming that c has not had any
+// reads or writes. It writes its initial settings frame and expects
+// to be able to read the preface and settings frame from the
+// client. If c has a ConnectionState method like a *tls.Conn, the
+// ConnectionState is used to verify the TLS ciphersuite and to set
+// the Request.TLS field in Handlers.
+//
+// ServeConn does not support h2c by itself. Any h2c support must be
+// implemented in terms of providing a suitably-behaving net.Conn.
+//
+// The opts parameter is optional. If nil, default values are used.
+func (s *http2Server) ServeConn(c net.Conn, opts *http2ServeConnOpts) {
+ baseCtx, cancel := http2serverConnBaseContext(c, opts)
+ defer cancel()
+
+ sc := &http2serverConn{
+ srv: s,
+ hs: opts.baseConfig(),
+ conn: c,
+ baseCtx: baseCtx,
+ remoteAddrStr: c.RemoteAddr().String(),
+ bw: http2newBufferedWriter(c),
+ handler: opts.handler(),
+ streams: make(map[uint32]*http2stream),
+ readFrameCh: make(chan http2readFrameResult),
+ wantWriteFrameCh: make(chan http2FrameWriteRequest, 8),
+ serveMsgCh: make(chan interface{}, 8),
+ wroteFrameCh: make(chan http2frameWriteResult, 1), // buffered; one send in writeFrameAsync
+ bodyReadCh: make(chan http2bodyReadMsg), // buffering doesn't matter either way
+ doneServing: make(chan struct{}),
+ clientMaxStreams: math.MaxUint32, // Section 6.5.2: "Initially, there is no limit to this value"
+ advMaxStreams: s.maxConcurrentStreams(),
+ initialStreamSendWindowSize: http2initialWindowSize,
+ maxFrameSize: http2initialMaxFrameSize,
+ serveG: http2newGoroutineLock(),
+ pushEnabled: true,
+ sawClientPreface: opts.SawClientPreface,
+ }
+
+ s.state.registerConn(sc)
+ defer s.state.unregisterConn(sc)
+
+ // The net/http package sets the write deadline from the
+ // http.Server.WriteTimeout during the TLS handshake, but then
+ // passes the connection off to us with the deadline already set.
+ // Write deadlines are set per stream in serverConn.newStream.
+ // Disarm the net.Conn write deadline here.
+ if sc.hs.WriteTimeout != 0 {
+ sc.conn.SetWriteDeadline(time.Time{})
+ }
+
+ if s.NewWriteScheduler != nil {
+ sc.writeSched = s.NewWriteScheduler()
+ } else {
+ sc.writeSched = http2newRoundRobinWriteScheduler()
+ }
+
+ // These start at the RFC-specified defaults. If there is a higher
+ // configured value for inflow, that will be updated when we send a
+ // WINDOW_UPDATE shortly after sending SETTINGS.
+ sc.flow.add(http2initialWindowSize)
+ sc.inflow.init(http2initialWindowSize)
+ sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf)
+ sc.hpackEncoder.SetMaxDynamicTableSizeLimit(s.maxEncoderHeaderTableSize())
+
+ fr := http2NewFramer(sc.bw, c)
+ if s.CountError != nil {
+ fr.countError = s.CountError
+ }
+ fr.ReadMetaHeaders = hpack.NewDecoder(s.maxDecoderHeaderTableSize(), nil)
+ fr.MaxHeaderListSize = sc.maxHeaderListSize()
+ fr.SetMaxReadFrameSize(s.maxReadFrameSize())
+ sc.framer = fr
+
+ if tc, ok := c.(http2connectionStater); ok {
+ sc.tlsState = new(tls.ConnectionState)
+ *sc.tlsState = tc.ConnectionState()
+ // 9.2 Use of TLS Features
+ // An implementation of HTTP/2 over TLS MUST use TLS
+ // 1.2 or higher with the restrictions on feature set
+ // and cipher suite described in this section. Due to
+ // implementation limitations, it might not be
+ // possible to fail TLS negotiation. An endpoint MUST
+ // immediately terminate an HTTP/2 connection that
+ // does not meet the TLS requirements described in
+ // this section with a connection error (Section
+ // 5.4.1) of type INADEQUATE_SECURITY.
+ if sc.tlsState.Version < tls.VersionTLS12 {
+ sc.rejectConn(http2ErrCodeInadequateSecurity, "TLS version too low")
+ return
+ }
+
+ if sc.tlsState.ServerName == "" {
+ // Client must use SNI, but we don't enforce that anymore,
+ // since it was causing problems when connecting to bare IP
+ // addresses during development.
+ //
+ // TODO: optionally enforce? Or enforce at the time we receive
+ // a new request, and verify the ServerName matches the :authority?
+ // But that precludes proxy situations, perhaps.
+ //
+ // So for now, do nothing here again.
+ }
+
+ if !s.PermitProhibitedCipherSuites && http2isBadCipher(sc.tlsState.CipherSuite) {
+ // "Endpoints MAY choose to generate a connection error
+ // (Section 5.4.1) of type INADEQUATE_SECURITY if one of
+ // the prohibited cipher suites are negotiated."
+ //
+ // We choose that. In my opinion, the spec is weak
+ // here. It also says both parties must support at least
+ // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no
+ // excuses here. If we really must, we could allow an
+ // "AllowInsecureWeakCiphers" option on the server later.
+ // Let's see how it plays out first.
+ sc.rejectConn(http2ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite))
+ return
+ }
+ }
+
+ if opts.Settings != nil {
+ fr := &http2SettingsFrame{
+ http2FrameHeader: http2FrameHeader{valid: true},
+ p: opts.Settings,
+ }
+ if err := fr.ForeachSetting(sc.processSetting); err != nil {
+ sc.rejectConn(http2ErrCodeProtocol, "invalid settings")
+ return
+ }
+ opts.Settings = nil
+ }
+
+ if hook := http2testHookGetServerConn; hook != nil {
+ hook(sc)
+ }
+
+ if opts.UpgradeRequest != nil {
+ sc.upgradeRequest(opts.UpgradeRequest)
+ opts.UpgradeRequest = nil
+ }
+
+ sc.serve()
+}
+
+func http2serverConnBaseContext(c net.Conn, opts *http2ServeConnOpts) (ctx context.Context, cancel func()) {
+ ctx, cancel = context.WithCancel(opts.context())
+ ctx = context.WithValue(ctx, LocalAddrContextKey, c.LocalAddr())
+ if hs := opts.baseConfig(); hs != nil {
+ ctx = context.WithValue(ctx, ServerContextKey, hs)
+ }
+ return
+}
+
+func (sc *http2serverConn) rejectConn(err http2ErrCode, debug string) {
+ sc.vlogf("http2: server rejecting conn: %v, %s", err, debug)
+ // ignoring errors. hanging up anyway.
+ sc.framer.WriteGoAway(0, err, []byte(debug))
+ sc.bw.Flush()
+ sc.conn.Close()
+}
+
+type http2serverConn struct {
+ // Immutable:
+ srv *http2Server
+ hs *Server
+ conn net.Conn
+ bw *http2bufferedWriter // writing to conn
+ handler Handler
+ baseCtx context.Context
+ framer *http2Framer
+ doneServing chan struct{} // closed when serverConn.serve ends
+ readFrameCh chan http2readFrameResult // written by serverConn.readFrames
+ wantWriteFrameCh chan http2FrameWriteRequest // from handlers -> serve
+ wroteFrameCh chan http2frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes
+ bodyReadCh chan http2bodyReadMsg // from handlers -> serve
+ serveMsgCh chan interface{} // misc messages & code to send to / run on the serve loop
+ flow http2outflow // conn-wide (not stream-specific) outbound flow control
+ inflow http2inflow // conn-wide inbound flow control
+ tlsState *tls.ConnectionState // shared by all handlers, like net/http
+ remoteAddrStr string
+ writeSched http2WriteScheduler
+
+ // Everything following is owned by the serve loop; use serveG.check():
+ serveG http2goroutineLock // used to verify funcs are on serve()
+ pushEnabled bool
+ sawClientPreface bool // preface has already been read, used in h2c upgrade
+ sawFirstSettings bool // got the initial SETTINGS frame after the preface
+ needToSendSettingsAck bool
+ unackedSettings int // how many SETTINGS have we sent without ACKs?
+ queuedControlFrames int // control frames in the writeSched queue
+ clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
+ advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
+ curClientStreams uint32 // number of open streams initiated by the client
+ curPushedStreams uint32 // number of open streams initiated by server push
+ curHandlers uint32 // number of running handler goroutines
+ maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests
+ maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes
+ streams map[uint32]*http2stream
+ unstartedHandlers []http2unstartedHandler
+ initialStreamSendWindowSize int32
+ maxFrameSize int32
+ peerMaxHeaderListSize uint32 // zero means unknown (default)
+ canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case
+ canonHeaderKeysSize int // canonHeader keys size in bytes
+ writingFrame bool // started writing a frame (on serve goroutine or separate)
+ writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh
+ needsFrameFlush bool // last frame write wasn't a flush
+ inGoAway bool // we've started to or sent GOAWAY
+ inFrameScheduleLoop bool // whether we're in the scheduleFrameWrite loop
+ needToSendGoAway bool // we need to schedule a GOAWAY frame write
+ goAwayCode http2ErrCode
+ shutdownTimer *time.Timer // nil until used
+ idleTimer *time.Timer // nil if unused
+
+ // Owned by the writeFrameAsync goroutine:
+ headerWriteBuf bytes.Buffer
+ hpackEncoder *hpack.Encoder
+
+ // Used by startGracefulShutdown.
+ shutdownOnce sync.Once
+}
+
+func (sc *http2serverConn) maxHeaderListSize() uint32 {
+ n := sc.hs.MaxHeaderBytes
+ if n <= 0 {
+ n = DefaultMaxHeaderBytes
+ }
+ // http2's count is in a slightly different unit and includes 32 bytes per pair.
+ // So, take the net/http.Server value and pad it up a bit, assuming 10 headers.
+ const perFieldOverhead = 32 // per http2 spec
+ const typicalHeaders = 10 // conservative
+ return uint32(n + typicalHeaders*perFieldOverhead)
+}
+
+func (sc *http2serverConn) curOpenStreams() uint32 {
+ sc.serveG.check()
+ return sc.curClientStreams + sc.curPushedStreams
+}
+
+// stream represents a stream. This is the minimal metadata needed by
+// the serve goroutine. Most of the actual stream state is owned by
+// the http.Handler's goroutine in the responseWriter. Because the
+// responseWriter's responseWriterState is recycled at the end of a
+// handler, this struct intentionally has no pointer to the
+// *responseWriter{,State} itself, as the Handler ending nils out the
+// responseWriter's state field.
+type http2stream struct {
+ // immutable:
+ sc *http2serverConn
+ id uint32
+ body *http2pipe // non-nil if expecting DATA frames
+ cw http2closeWaiter // closed wait stream transitions to closed state
+ ctx context.Context
+ cancelCtx func()
+
+ // owned by serverConn's serve loop:
+ bodyBytes int64 // body bytes seen so far
+ declBodyBytes int64 // or -1 if undeclared
+ flow http2outflow // limits writing from Handler to client
+ inflow http2inflow // what the client is allowed to POST/etc to us
+ state http2streamState
+ resetQueued bool // RST_STREAM queued for write; set by sc.resetStream
+ gotTrailerHeader bool // HEADER frame for trailers was seen
+ wroteHeaders bool // whether we wrote headers (not status 100)
+ readDeadline *time.Timer // nil if unused
+ writeDeadline *time.Timer // nil if unused
+ closeErr error // set before cw is closed
+
+ trailer Header // accumulated trailers
+ reqTrailer Header // handler's Request.Trailer
+}
+
+func (sc *http2serverConn) Framer() *http2Framer { return sc.framer }
+
+func (sc *http2serverConn) CloseConn() error { return sc.conn.Close() }
+
+func (sc *http2serverConn) Flush() error { return sc.bw.Flush() }
+
+func (sc *http2serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) {
+ return sc.hpackEncoder, &sc.headerWriteBuf
+}
+
+func (sc *http2serverConn) state(streamID uint32) (http2streamState, *http2stream) {
+ sc.serveG.check()
+ // http://tools.ietf.org/html/rfc7540#section-5.1
+ if st, ok := sc.streams[streamID]; ok {
+ return st.state, st
+ }
+ // "The first use of a new stream identifier implicitly closes all
+ // streams in the "idle" state that might have been initiated by
+ // that peer with a lower-valued stream identifier. For example, if
+ // a client sends a HEADERS frame on stream 7 without ever sending a
+ // frame on stream 5, then stream 5 transitions to the "closed"
+ // state when the first frame for stream 7 is sent or received."
+ if streamID%2 == 1 {
+ if streamID <= sc.maxClientStreamID {
+ return http2stateClosed, nil
+ }
+ } else {
+ if streamID <= sc.maxPushPromiseID {
+ return http2stateClosed, nil
+ }
+ }
+ return http2stateIdle, nil
+}
+
+// setConnState calls the net/http ConnState hook for this connection, if configured.
+// Note that the net/http package does StateNew and StateClosed for us.
+// There is currently no plan for StateHijacked or hijacking HTTP/2 connections.
+func (sc *http2serverConn) setConnState(state ConnState) {
+ if sc.hs.ConnState != nil {
+ sc.hs.ConnState(sc.conn, state)
+ }
+}
+
+func (sc *http2serverConn) vlogf(format string, args ...interface{}) {
+ if http2VerboseLogs {
+ sc.logf(format, args...)
+ }
+}
+
+func (sc *http2serverConn) logf(format string, args ...interface{}) {
+ if lg := sc.hs.ErrorLog; lg != nil {
+ lg.Printf(format, args...)
+ } else {
+ log.Printf(format, args...)
+ }
+}
+
+// errno returns v's underlying uintptr, else 0.
+//
+// TODO: remove this helper function once http2 can use build
+// tags. See comment in isClosedConnError.
+func http2errno(v error) uintptr {
+ if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr {
+ return uintptr(rv.Uint())
+ }
+ return 0
+}
+
+// isClosedConnError reports whether err is an error from use of a closed
+// network connection.
+func http2isClosedConnError(err error) bool {
+ if err == nil {
+ return false
+ }
+
+ // TODO: remove this string search and be more like the Windows
+ // case below. That might involve modifying the standard library
+ // to return better error types.
+ str := err.Error()
+ if strings.Contains(str, "use of closed network connection") {
+ return true
+ }
+
+ // TODO(bradfitz): x/tools/cmd/bundle doesn't really support
+ // build tags, so I can't make an http2_windows.go file with
+ // Windows-specific stuff. Fix that and move this, once we
+ // have a way to bundle this into std's net/http somehow.
+ if runtime.GOOS == "windows" {
+ if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
+ if se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == "wsarecv" {
+ const WSAECONNABORTED = 10053
+ const WSAECONNRESET = 10054
+ if n := http2errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED {
+ return true
+ }
+ }
+ }
+ }
+ return false
+}
+
+func (sc *http2serverConn) condlogf(err error, format string, args ...interface{}) {
+ if err == nil {
+ return
+ }
+ if err == io.EOF || err == io.ErrUnexpectedEOF || http2isClosedConnError(err) || err == http2errPrefaceTimeout {
+ // Boring, expected errors.
+ sc.vlogf(format, args...)
+ } else {
+ sc.logf(format, args...)
+ }
+}
+
+// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size
+// of the entries in the canonHeader cache.
+// This should be larger than the size of unique, uncommon header keys likely to
+// be sent by the peer, while not so high as to permit unreasonable memory usage
+// if the peer sends an unbounded number of unique header keys.
+const http2maxCachedCanonicalHeadersKeysSize = 2048
+
+func (sc *http2serverConn) canonicalHeader(v string) string {
+ sc.serveG.check()
+ http2buildCommonHeaderMapsOnce()
+ cv, ok := http2commonCanonHeader[v]
+ if ok {
+ return cv
+ }
+ cv, ok = sc.canonHeader[v]
+ if ok {
+ return cv
+ }
+ if sc.canonHeader == nil {
+ sc.canonHeader = make(map[string]string)
+ }
+ cv = CanonicalHeaderKey(v)
+ size := 100 + len(v)*2 // 100 bytes of map overhead + key + value
+ if sc.canonHeaderKeysSize+size <= http2maxCachedCanonicalHeadersKeysSize {
+ sc.canonHeader[v] = cv
+ sc.canonHeaderKeysSize += size
+ }
+ return cv
+}
+
+type http2readFrameResult struct {
+ f http2Frame // valid until readMore is called
+ err error
+
+ // readMore should be called once the consumer no longer needs or
+ // retains f. After readMore, f is invalid and more frames can be
+ // read.
+ readMore func()
+}
+
+// readFrames is the loop that reads incoming frames.
+// It takes care to only read one frame at a time, blocking until the
+// consumer is done with the frame.
+// It's run on its own goroutine.
+func (sc *http2serverConn) readFrames() {
+ gate := make(http2gate)
+ gateDone := gate.Done
+ for {
+ f, err := sc.framer.ReadFrame()
+ select {
+ case sc.readFrameCh <- http2readFrameResult{f, err, gateDone}:
+ case <-sc.doneServing:
+ return
+ }
+ select {
+ case <-gate:
+ case <-sc.doneServing:
+ return
+ }
+ if http2terminalReadFrameError(err) {
+ return
+ }
+ }
+}
+
+// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine.
+type http2frameWriteResult struct {
+ _ http2incomparable
+ wr http2FrameWriteRequest // what was written (or attempted)
+ err error // result of the writeFrame call
+}
+
+// writeFrameAsync runs in its own goroutine and writes a single frame
+// and then reports when it's done.
+// At most one goroutine can be running writeFrameAsync at a time per
+// serverConn.
+func (sc *http2serverConn) writeFrameAsync(wr http2FrameWriteRequest, wd *http2writeData) {
+ var err error
+ if wd == nil {
+ err = wr.write.writeFrame(sc)
+ } else {
+ err = sc.framer.endWrite()
+ }
+ sc.wroteFrameCh <- http2frameWriteResult{wr: wr, err: err}
+}
+
+func (sc *http2serverConn) closeAllStreamsOnConnClose() {
+ sc.serveG.check()
+ for _, st := range sc.streams {
+ sc.closeStream(st, http2errClientDisconnected)
+ }
+}
+
+func (sc *http2serverConn) stopShutdownTimer() {
+ sc.serveG.check()
+ if t := sc.shutdownTimer; t != nil {
+ t.Stop()
+ }
+}
+
+func (sc *http2serverConn) notePanic() {
+ // Note: this is for serverConn.serve panicking, not http.Handler code.
+ if http2testHookOnPanicMu != nil {
+ http2testHookOnPanicMu.Lock()
+ defer http2testHookOnPanicMu.Unlock()
+ }
+ if http2testHookOnPanic != nil {
+ if e := recover(); e != nil {
+ if http2testHookOnPanic(sc, e) {
+ panic(e)
+ }
+ }
+ }
+}
+
+func (sc *http2serverConn) serve() {
+ sc.serveG.check()
+ defer sc.notePanic()
+ defer sc.conn.Close()
+ defer sc.closeAllStreamsOnConnClose()
+ defer sc.stopShutdownTimer()
+ defer close(sc.doneServing) // unblocks handlers trying to send
+
+ if http2VerboseLogs {
+ sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs)
+ }
+
+ sc.writeFrame(http2FrameWriteRequest{
+ write: http2writeSettings{
+ {http2SettingMaxFrameSize, sc.srv.maxReadFrameSize()},
+ {http2SettingMaxConcurrentStreams, sc.advMaxStreams},
+ {http2SettingMaxHeaderListSize, sc.maxHeaderListSize()},
+ {http2SettingHeaderTableSize, sc.srv.maxDecoderHeaderTableSize()},
+ {http2SettingInitialWindowSize, uint32(sc.srv.initialStreamRecvWindowSize())},
+ },
+ })
+ sc.unackedSettings++
+
+ // Each connection starts with initialWindowSize inflow tokens.
+ // If a higher value is configured, we add more tokens.
+ if diff := sc.srv.initialConnRecvWindowSize() - http2initialWindowSize; diff > 0 {
+ sc.sendWindowUpdate(nil, int(diff))
+ }
+
+ if err := sc.readPreface(); err != nil {
+ sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err)
+ return
+ }
+ // Now that we've got the preface, get us out of the
+ // "StateNew" state. We can't go directly to idle, though.
+ // Active means we read some data and anticipate a request. We'll
+ // do another Active when we get a HEADERS frame.
+ sc.setConnState(StateActive)
+ sc.setConnState(StateIdle)
+
+ if sc.srv.IdleTimeout != 0 {
+ sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
+ defer sc.idleTimer.Stop()
+ }
+
+ go sc.readFrames() // closed by defer sc.conn.Close above
+
+ settingsTimer := time.AfterFunc(http2firstSettingsTimeout, sc.onSettingsTimer)
+ defer settingsTimer.Stop()
+
+ loopNum := 0
+ for {
+ loopNum++
+ select {
+ case wr := <-sc.wantWriteFrameCh:
+ if se, ok := wr.write.(http2StreamError); ok {
+ sc.resetStream(se)
+ break
+ }
+ sc.writeFrame(wr)
+ case res := <-sc.wroteFrameCh:
+ sc.wroteFrame(res)
+ case res := <-sc.readFrameCh:
+ // Process any written frames before reading new frames from the client since a
+ // written frame could have triggered a new stream to be started.
+ if sc.writingFrameAsync {
+ select {
+ case wroteRes := <-sc.wroteFrameCh:
+ sc.wroteFrame(wroteRes)
+ default:
+ }
+ }
+ if !sc.processFrameFromReader(res) {
+ return
+ }
+ res.readMore()
+ if settingsTimer != nil {
+ settingsTimer.Stop()
+ settingsTimer = nil
+ }
+ case m := <-sc.bodyReadCh:
+ sc.noteBodyRead(m.st, m.n)
+ case msg := <-sc.serveMsgCh:
+ switch v := msg.(type) {
+ case func(int):
+ v(loopNum) // for testing
+ case *http2serverMessage:
+ switch v {
+ case http2settingsTimerMsg:
+ sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr())
+ return
+ case http2idleTimerMsg:
+ sc.vlogf("connection is idle")
+ sc.goAway(http2ErrCodeNo)
+ case http2shutdownTimerMsg:
+ sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr())
+ return
+ case http2gracefulShutdownMsg:
+ sc.startGracefulShutdownInternal()
+ case http2handlerDoneMsg:
+ sc.handlerDone()
+ default:
+ panic("unknown timer")
+ }
+ case *http2startPushRequest:
+ sc.startPush(v)
+ case func(*http2serverConn):
+ v(sc)
+ default:
+ panic(fmt.Sprintf("unexpected type %T", v))
+ }
+ }
+
+ // If the peer is causing us to generate a lot of control frames,
+ // but not reading them from us, assume they are trying to make us
+ // run out of memory.
+ if sc.queuedControlFrames > sc.srv.maxQueuedControlFrames() {
+ sc.vlogf("http2: too many control frames in send queue, closing connection")
+ return
+ }
+
+ // Start the shutdown timer after sending a GOAWAY. When sending GOAWAY
+ // with no error code (graceful shutdown), don't start the timer until
+ // all open streams have been completed.
+ sentGoAway := sc.inGoAway && !sc.needToSendGoAway && !sc.writingFrame
+ gracefulShutdownComplete := sc.goAwayCode == http2ErrCodeNo && sc.curOpenStreams() == 0
+ if sentGoAway && sc.shutdownTimer == nil && (sc.goAwayCode != http2ErrCodeNo || gracefulShutdownComplete) {
+ sc.shutDownIn(http2goAwayTimeout)
+ }
+ }
+}
+
+func (sc *http2serverConn) awaitGracefulShutdown(sharedCh <-chan struct{}, privateCh chan struct{}) {
+ select {
+ case <-sc.doneServing:
+ case <-sharedCh:
+ close(privateCh)
+ }
+}
+
+type http2serverMessage int
+
+// Message values sent to serveMsgCh.
+var (
+ http2settingsTimerMsg = new(http2serverMessage)
+ http2idleTimerMsg = new(http2serverMessage)
+ http2shutdownTimerMsg = new(http2serverMessage)
+ http2gracefulShutdownMsg = new(http2serverMessage)
+ http2handlerDoneMsg = new(http2serverMessage)
+)
+
+func (sc *http2serverConn) onSettingsTimer() { sc.sendServeMsg(http2settingsTimerMsg) }
+
+func (sc *http2serverConn) onIdleTimer() { sc.sendServeMsg(http2idleTimerMsg) }
+
+func (sc *http2serverConn) onShutdownTimer() { sc.sendServeMsg(http2shutdownTimerMsg) }
+
+func (sc *http2serverConn) sendServeMsg(msg interface{}) {
+ sc.serveG.checkNotOn() // NOT
+ select {
+ case sc.serveMsgCh <- msg:
+ case <-sc.doneServing:
+ }
+}
+
+var http2errPrefaceTimeout = errors.New("timeout waiting for client preface")
+
+// readPreface reads the ClientPreface greeting from the peer or
+// returns errPrefaceTimeout on timeout, or an error if the greeting
+// is invalid.
+func (sc *http2serverConn) readPreface() error {
+ if sc.sawClientPreface {
+ return nil
+ }
+ errc := make(chan error, 1)
+ go func() {
+ // Read the client preface
+ buf := make([]byte, len(http2ClientPreface))
+ if _, err := io.ReadFull(sc.conn, buf); err != nil {
+ errc <- err
+ } else if !bytes.Equal(buf, http2clientPreface) {
+ errc <- fmt.Errorf("bogus greeting %q", buf)
+ } else {
+ errc <- nil
+ }
+ }()
+ timer := time.NewTimer(http2prefaceTimeout) // TODO: configurable on *Server?
+ defer timer.Stop()
+ select {
+ case <-timer.C:
+ return http2errPrefaceTimeout
+ case err := <-errc:
+ if err == nil {
+ if http2VerboseLogs {
+ sc.vlogf("http2: server: client %v said hello", sc.conn.RemoteAddr())
+ }
+ }
+ return err
+ }
+}
+
+var http2errChanPool = sync.Pool{
+ New: func() interface{} { return make(chan error, 1) },
+}
+
+var http2writeDataPool = sync.Pool{
+ New: func() interface{} { return new(http2writeData) },
+}
+
+// writeDataFromHandler writes DATA response frames from a handler on
+// the given stream.
+func (sc *http2serverConn) writeDataFromHandler(stream *http2stream, data []byte, endStream bool) error {
+ ch := http2errChanPool.Get().(chan error)
+ writeArg := http2writeDataPool.Get().(*http2writeData)
+ *writeArg = http2writeData{stream.id, data, endStream}
+ err := sc.writeFrameFromHandler(http2FrameWriteRequest{
+ write: writeArg,
+ stream: stream,
+ done: ch,
+ })
+ if err != nil {
+ return err
+ }
+ var frameWriteDone bool // the frame write is done (successfully or not)
+ select {
+ case err = <-ch:
+ frameWriteDone = true
+ case <-sc.doneServing:
+ return http2errClientDisconnected
+ case <-stream.cw:
+ // If both ch and stream.cw were ready (as might
+ // happen on the final Write after an http.Handler
+ // ends), prefer the write result. Otherwise this
+ // might just be us successfully closing the stream.
+ // The writeFrameAsync and serve goroutines guarantee
+ // that the ch send will happen before the stream.cw
+ // close.
+ select {
+ case err = <-ch:
+ frameWriteDone = true
+ default:
+ return http2errStreamClosed
+ }
+ }
+ http2errChanPool.Put(ch)
+ if frameWriteDone {
+ http2writeDataPool.Put(writeArg)
+ }
+ return err
+}
+
+// writeFrameFromHandler sends wr to sc.wantWriteFrameCh, but aborts
+// if the connection has gone away.
+//
+// This must not be run from the serve goroutine itself, else it might
+// deadlock writing to sc.wantWriteFrameCh (which is only mildly
+// buffered and is read by serve itself). If you're on the serve
+// goroutine, call writeFrame instead.
+func (sc *http2serverConn) writeFrameFromHandler(wr http2FrameWriteRequest) error {
+ sc.serveG.checkNotOn() // NOT
+ select {
+ case sc.wantWriteFrameCh <- wr:
+ return nil
+ case <-sc.doneServing:
+ // Serve loop is gone.
+ // Client has closed their connection to the server.
+ return http2errClientDisconnected
+ }
+}
+
+// writeFrame schedules a frame to write and sends it if there's nothing
+// already being written.
+//
+// There is no pushback here (the serve goroutine never blocks). It's
+// the http.Handlers that block, waiting for their previous frames to
+// make it onto the wire
+//
+// If you're not on the serve goroutine, use writeFrameFromHandler instead.
+func (sc *http2serverConn) writeFrame(wr http2FrameWriteRequest) {
+ sc.serveG.check()
+
+ // If true, wr will not be written and wr.done will not be signaled.
+ var ignoreWrite bool
+
+ // We are not allowed to write frames on closed streams. RFC 7540 Section
+ // 5.1.1 says: "An endpoint MUST NOT send frames other than PRIORITY on
+ // a closed stream." Our server never sends PRIORITY, so that exception
+ // does not apply.
+ //
+ // The serverConn might close an open stream while the stream's handler
+ // is still running. For example, the server might close a stream when it
+ // receives bad data from the client. If this happens, the handler might
+ // attempt to write a frame after the stream has been closed (since the
+ // handler hasn't yet been notified of the close). In this case, we simply
+ // ignore the frame. The handler will notice that the stream is closed when
+ // it waits for the frame to be written.
+ //
+ // As an exception to this rule, we allow sending RST_STREAM after close.
+ // This allows us to immediately reject new streams without tracking any
+ // state for those streams (except for the queued RST_STREAM frame). This
+ // may result in duplicate RST_STREAMs in some cases, but the client should
+ // ignore those.
+ if wr.StreamID() != 0 {
+ _, isReset := wr.write.(http2StreamError)
+ if state, _ := sc.state(wr.StreamID()); state == http2stateClosed && !isReset {
+ ignoreWrite = true
+ }
+ }
+
+ // Don't send a 100-continue response if we've already sent headers.
+ // See golang.org/issue/14030.
+ switch wr.write.(type) {
+ case *http2writeResHeaders:
+ wr.stream.wroteHeaders = true
+ case http2write100ContinueHeadersFrame:
+ if wr.stream.wroteHeaders {
+ // We do not need to notify wr.done because this frame is
+ // never written with wr.done != nil.
+ if wr.done != nil {
+ panic("wr.done != nil for write100ContinueHeadersFrame")
+ }
+ ignoreWrite = true
+ }
+ }
+
+ if !ignoreWrite {
+ if wr.isControl() {
+ sc.queuedControlFrames++
+ // For extra safety, detect wraparounds, which should not happen,
+ // and pull the plug.
+ if sc.queuedControlFrames < 0 {
+ sc.conn.Close()
+ }
+ }
+ sc.writeSched.Push(wr)
+ }
+ sc.scheduleFrameWrite()
+}
+
+// startFrameWrite starts a goroutine to write wr (in a separate
+// goroutine since that might block on the network), and updates the
+// serve goroutine's state about the world, updated from info in wr.
+func (sc *http2serverConn) startFrameWrite(wr http2FrameWriteRequest) {
+ sc.serveG.check()
+ if sc.writingFrame {
+ panic("internal error: can only be writing one frame at a time")
+ }
+
+ st := wr.stream
+ if st != nil {
+ switch st.state {
+ case http2stateHalfClosedLocal:
+ switch wr.write.(type) {
+ case http2StreamError, http2handlerPanicRST, http2writeWindowUpdate:
+ // RFC 7540 Section 5.1 allows sending RST_STREAM, PRIORITY, and WINDOW_UPDATE
+ // in this state. (We never send PRIORITY from the server, so that is not checked.)
+ default:
+ panic(fmt.Sprintf("internal error: attempt to send frame on a half-closed-local stream: %v", wr))
+ }
+ case http2stateClosed:
+ panic(fmt.Sprintf("internal error: attempt to send frame on a closed stream: %v", wr))
+ }
+ }
+ if wpp, ok := wr.write.(*http2writePushPromise); ok {
+ var err error
+ wpp.promisedID, err = wpp.allocatePromisedID()
+ if err != nil {
+ sc.writingFrameAsync = false
+ wr.replyToWriter(err)
+ return
+ }
+ }
+
+ sc.writingFrame = true
+ sc.needsFrameFlush = true
+ if wr.write.staysWithinBuffer(sc.bw.Available()) {
+ sc.writingFrameAsync = false
+ err := wr.write.writeFrame(sc)
+ sc.wroteFrame(http2frameWriteResult{wr: wr, err: err})
+ } else if wd, ok := wr.write.(*http2writeData); ok {
+ // Encode the frame in the serve goroutine, to ensure we don't have
+ // any lingering asynchronous references to data passed to Write.
+ // See https://go.dev/issue/58446.
+ sc.framer.startWriteDataPadded(wd.streamID, wd.endStream, wd.p, nil)
+ sc.writingFrameAsync = true
+ go sc.writeFrameAsync(wr, wd)
+ } else {
+ sc.writingFrameAsync = true
+ go sc.writeFrameAsync(wr, nil)
+ }
+}
+
+// errHandlerPanicked is the error given to any callers blocked in a read from
+// Request.Body when the main goroutine panics. Since most handlers read in the
+// main ServeHTTP goroutine, this will show up rarely.
+var http2errHandlerPanicked = errors.New("http2: handler panicked")
+
+// wroteFrame is called on the serve goroutine with the result of
+// whatever happened on writeFrameAsync.
+func (sc *http2serverConn) wroteFrame(res http2frameWriteResult) {
+ sc.serveG.check()
+ if !sc.writingFrame {
+ panic("internal error: expected to be already writing a frame")
+ }
+ sc.writingFrame = false
+ sc.writingFrameAsync = false
+
+ wr := res.wr
+
+ if http2writeEndsStream(wr.write) {
+ st := wr.stream
+ if st == nil {
+ panic("internal error: expecting non-nil stream")
+ }
+ switch st.state {
+ case http2stateOpen:
+ // Here we would go to stateHalfClosedLocal in
+ // theory, but since our handler is done and
+ // the net/http package provides no mechanism
+ // for closing a ResponseWriter while still
+ // reading data (see possible TODO at top of
+ // this file), we go into closed state here
+ // anyway, after telling the peer we're
+ // hanging up on them. We'll transition to
+ // stateClosed after the RST_STREAM frame is
+ // written.
+ st.state = http2stateHalfClosedLocal
+ // Section 8.1: a server MAY request that the client abort
+ // transmission of a request without error by sending a
+ // RST_STREAM with an error code of NO_ERROR after sending
+ // a complete response.
+ sc.resetStream(http2streamError(st.id, http2ErrCodeNo))
+ case http2stateHalfClosedRemote:
+ sc.closeStream(st, http2errHandlerComplete)
+ }
+ } else {
+ switch v := wr.write.(type) {
+ case http2StreamError:
+ // st may be unknown if the RST_STREAM was generated to reject bad input.
+ if st, ok := sc.streams[v.StreamID]; ok {
+ sc.closeStream(st, v)
+ }
+ case http2handlerPanicRST:
+ sc.closeStream(wr.stream, http2errHandlerPanicked)
+ }
+ }
+
+ // Reply (if requested) to unblock the ServeHTTP goroutine.
+ wr.replyToWriter(res.err)
+
+ sc.scheduleFrameWrite()
+}
+
+// scheduleFrameWrite tickles the frame writing scheduler.
+//
+// If a frame is already being written, nothing happens. This will be called again
+// when the frame is done being written.
+//
+// If a frame isn't being written and we need to send one, the best frame
+// to send is selected by writeSched.
+//
+// If a frame isn't being written and there's nothing else to send, we
+// flush the write buffer.
+func (sc *http2serverConn) scheduleFrameWrite() {
+ sc.serveG.check()
+ if sc.writingFrame || sc.inFrameScheduleLoop {
+ return
+ }
+ sc.inFrameScheduleLoop = true
+ for !sc.writingFrameAsync {
+ if sc.needToSendGoAway {
+ sc.needToSendGoAway = false
+ sc.startFrameWrite(http2FrameWriteRequest{
+ write: &http2writeGoAway{
+ maxStreamID: sc.maxClientStreamID,
+ code: sc.goAwayCode,
+ },
+ })
+ continue
+ }
+ if sc.needToSendSettingsAck {
+ sc.needToSendSettingsAck = false
+ sc.startFrameWrite(http2FrameWriteRequest{write: http2writeSettingsAck{}})
+ continue
+ }
+ if !sc.inGoAway || sc.goAwayCode == http2ErrCodeNo {
+ if wr, ok := sc.writeSched.Pop(); ok {
+ if wr.isControl() {
+ sc.queuedControlFrames--
+ }
+ sc.startFrameWrite(wr)
+ continue
+ }
+ }
+ if sc.needsFrameFlush {
+ sc.startFrameWrite(http2FrameWriteRequest{write: http2flushFrameWriter{}})
+ sc.needsFrameFlush = false // after startFrameWrite, since it sets this true
+ continue
+ }
+ break
+ }
+ sc.inFrameScheduleLoop = false
+}
+
+// startGracefulShutdown gracefully shuts down a connection. This
+// sends GOAWAY with ErrCodeNo to tell the client we're gracefully
+// shutting down. The connection isn't closed until all current
+// streams are done.
+//
+// startGracefulShutdown returns immediately; it does not wait until
+// the connection has shut down.
+func (sc *http2serverConn) startGracefulShutdown() {
+ sc.serveG.checkNotOn() // NOT
+ sc.shutdownOnce.Do(func() { sc.sendServeMsg(http2gracefulShutdownMsg) })
+}
+
+// After sending GOAWAY with an error code (non-graceful shutdown), the
+// connection will close after goAwayTimeout.
+//
+// If we close the connection immediately after sending GOAWAY, there may
+// be unsent data in our kernel receive buffer, which will cause the kernel
+// to send a TCP RST on close() instead of a FIN. This RST will abort the
+// connection immediately, whether or not the client had received the GOAWAY.
+//
+// Ideally we should delay for at least 1 RTT + epsilon so the client has
+// a chance to read the GOAWAY and stop sending messages. Measuring RTT
+// is hard, so we approximate with 1 second. See golang.org/issue/18701.
+//
+// This is a var so it can be shorter in tests, where all requests uses the
+// loopback interface making the expected RTT very small.
+//
+// TODO: configurable?
+var http2goAwayTimeout = 1 * time.Second
+
+func (sc *http2serverConn) startGracefulShutdownInternal() {
+ sc.goAway(http2ErrCodeNo)
+}
+
+func (sc *http2serverConn) goAway(code http2ErrCode) {
+ sc.serveG.check()
+ if sc.inGoAway {
+ if sc.goAwayCode == http2ErrCodeNo {
+ sc.goAwayCode = code
+ }
+ return
+ }
+ sc.inGoAway = true
+ sc.needToSendGoAway = true
+ sc.goAwayCode = code
+ sc.scheduleFrameWrite()
+}
+
+func (sc *http2serverConn) shutDownIn(d time.Duration) {
+ sc.serveG.check()
+ sc.shutdownTimer = time.AfterFunc(d, sc.onShutdownTimer)
+}
+
+func (sc *http2serverConn) resetStream(se http2StreamError) {
+ sc.serveG.check()
+ sc.writeFrame(http2FrameWriteRequest{write: se})
+ if st, ok := sc.streams[se.StreamID]; ok {
+ st.resetQueued = true
+ }
+}
+
+// processFrameFromReader processes the serve loop's read from readFrameCh from the
+// frame-reading goroutine.
+// processFrameFromReader returns whether the connection should be kept open.
+func (sc *http2serverConn) processFrameFromReader(res http2readFrameResult) bool {
+ sc.serveG.check()
+ err := res.err
+ if err != nil {
+ if err == http2ErrFrameTooLarge {
+ sc.goAway(http2ErrCodeFrameSize)
+ return true // goAway will close the loop
+ }
+ clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || http2isClosedConnError(err)
+ if clientGone {
+ // TODO: could we also get into this state if
+ // the peer does a half close
+ // (e.g. CloseWrite) because they're done
+ // sending frames but they're still wanting
+ // our open replies? Investigate.
+ // TODO: add CloseWrite to crypto/tls.Conn first
+ // so we have a way to test this? I suppose
+ // just for testing we could have a non-TLS mode.
+ return false
+ }
+ } else {
+ f := res.f
+ if http2VerboseLogs {
+ sc.vlogf("http2: server read frame %v", http2summarizeFrame(f))
+ }
+ err = sc.processFrame(f)
+ if err == nil {
+ return true
+ }
+ }
+
+ switch ev := err.(type) {
+ case http2StreamError:
+ sc.resetStream(ev)
+ return true
+ case http2goAwayFlowError:
+ sc.goAway(http2ErrCodeFlowControl)
+ return true
+ case http2ConnectionError:
+ sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev)
+ sc.goAway(http2ErrCode(ev))
+ return true // goAway will handle shutdown
+ default:
+ if res.err != nil {
+ sc.vlogf("http2: server closing client connection; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err)
+ } else {
+ sc.logf("http2: server closing client connection: %v", err)
+ }
+ return false
+ }
+}
+
+func (sc *http2serverConn) processFrame(f http2Frame) error {
+ sc.serveG.check()
+
+ // First frame received must be SETTINGS.
+ if !sc.sawFirstSettings {
+ if _, ok := f.(*http2SettingsFrame); !ok {
+ return sc.countError("first_settings", http2ConnectionError(http2ErrCodeProtocol))
+ }
+ sc.sawFirstSettings = true
+ }
+
+ // Discard frames for streams initiated after the identified last
+ // stream sent in a GOAWAY, or all frames after sending an error.
+ // We still need to return connection-level flow control for DATA frames.
+ // RFC 9113 Section 6.8.
+ if sc.inGoAway && (sc.goAwayCode != http2ErrCodeNo || f.Header().StreamID > sc.maxClientStreamID) {
+
+ if f, ok := f.(*http2DataFrame); ok {
+ if !sc.inflow.take(f.Length) {
+ return sc.countError("data_flow", http2streamError(f.Header().StreamID, http2ErrCodeFlowControl))
+ }
+ sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
+ }
+ return nil
+ }
+
+ switch f := f.(type) {
+ case *http2SettingsFrame:
+ return sc.processSettings(f)
+ case *http2MetaHeadersFrame:
+ return sc.processHeaders(f)
+ case *http2WindowUpdateFrame:
+ return sc.processWindowUpdate(f)
+ case *http2PingFrame:
+ return sc.processPing(f)
+ case *http2DataFrame:
+ return sc.processData(f)
+ case *http2RSTStreamFrame:
+ return sc.processResetStream(f)
+ case *http2PriorityFrame:
+ return sc.processPriority(f)
+ case *http2GoAwayFrame:
+ return sc.processGoAway(f)
+ case *http2PushPromiseFrame:
+ // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE
+ // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
+ return sc.countError("push_promise", http2ConnectionError(http2ErrCodeProtocol))
+ default:
+ sc.vlogf("http2: server ignoring frame: %v", f.Header())
+ return nil
+ }
+}
+
+func (sc *http2serverConn) processPing(f *http2PingFrame) error {
+ sc.serveG.check()
+ if f.IsAck() {
+ // 6.7 PING: " An endpoint MUST NOT respond to PING frames
+ // containing this flag."
+ return nil
+ }
+ if f.StreamID != 0 {
+ // "PING frames are not associated with any individual
+ // stream. If a PING frame is received with a stream
+ // identifier field value other than 0x0, the recipient MUST
+ // respond with a connection error (Section 5.4.1) of type
+ // PROTOCOL_ERROR."
+ return sc.countError("ping_on_stream", http2ConnectionError(http2ErrCodeProtocol))
+ }
+ sc.writeFrame(http2FrameWriteRequest{write: http2writePingAck{f}})
+ return nil
+}
+
+func (sc *http2serverConn) processWindowUpdate(f *http2WindowUpdateFrame) error {
+ sc.serveG.check()
+ switch {
+ case f.StreamID != 0: // stream-level flow control
+ state, st := sc.state(f.StreamID)
+ if state == http2stateIdle {
+ // Section 5.1: "Receiving any frame other than HEADERS
+ // or PRIORITY on a stream in this state MUST be
+ // treated as a connection error (Section 5.4.1) of
+ // type PROTOCOL_ERROR."
+ return sc.countError("stream_idle", http2ConnectionError(http2ErrCodeProtocol))
+ }
+ if st == nil {
+ // "WINDOW_UPDATE can be sent by a peer that has sent a
+ // frame bearing the END_STREAM flag. This means that a
+ // receiver could receive a WINDOW_UPDATE frame on a "half
+ // closed (remote)" or "closed" stream. A receiver MUST
+ // NOT treat this as an error, see Section 5.1."
+ return nil
+ }
+ if !st.flow.add(int32(f.Increment)) {
+ return sc.countError("bad_flow", http2streamError(f.StreamID, http2ErrCodeFlowControl))
+ }
+ default: // connection-level flow control
+ if !sc.flow.add(int32(f.Increment)) {
+ return http2goAwayFlowError{}
+ }
+ }
+ sc.scheduleFrameWrite()
+ return nil
+}
+
+func (sc *http2serverConn) processResetStream(f *http2RSTStreamFrame) error {
+ sc.serveG.check()
+
+ state, st := sc.state(f.StreamID)
+ if state == http2stateIdle {
+ // 6.4 "RST_STREAM frames MUST NOT be sent for a
+ // stream in the "idle" state. If a RST_STREAM frame
+ // identifying an idle stream is received, the
+ // recipient MUST treat this as a connection error
+ // (Section 5.4.1) of type PROTOCOL_ERROR.
+ return sc.countError("reset_idle_stream", http2ConnectionError(http2ErrCodeProtocol))
+ }
+ if st != nil {
+ st.cancelCtx()
+ sc.closeStream(st, http2streamError(f.StreamID, f.ErrCode))
+ }
+ return nil
+}
+
+func (sc *http2serverConn) closeStream(st *http2stream, err error) {
+ sc.serveG.check()
+ if st.state == http2stateIdle || st.state == http2stateClosed {
+ panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state))
+ }
+ st.state = http2stateClosed
+ if st.readDeadline != nil {
+ st.readDeadline.Stop()
+ }
+ if st.writeDeadline != nil {
+ st.writeDeadline.Stop()
+ }
+ if st.isPushed() {
+ sc.curPushedStreams--
+ } else {
+ sc.curClientStreams--
+ }
+ delete(sc.streams, st.id)
+ if len(sc.streams) == 0 {
+ sc.setConnState(StateIdle)
+ if sc.srv.IdleTimeout != 0 {
+ sc.idleTimer.Reset(sc.srv.IdleTimeout)
+ }
+ if http2h1ServerKeepAlivesDisabled(sc.hs) {
+ sc.startGracefulShutdownInternal()
+ }
+ }
+ if p := st.body; p != nil {
+ // Return any buffered unread bytes worth of conn-level flow control.
+ // See golang.org/issue/16481
+ sc.sendWindowUpdate(nil, p.Len())
+
+ p.CloseWithError(err)
+ }
+ if e, ok := err.(http2StreamError); ok {
+ if e.Cause != nil {
+ err = e.Cause
+ } else {
+ err = http2errStreamClosed
+ }
+ }
+ st.closeErr = err
+ st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc
+ sc.writeSched.CloseStream(st.id)
+}
+
+func (sc *http2serverConn) processSettings(f *http2SettingsFrame) error {
+ sc.serveG.check()
+ if f.IsAck() {
+ sc.unackedSettings--
+ if sc.unackedSettings < 0 {
+ // Why is the peer ACKing settings we never sent?
+ // The spec doesn't mention this case, but
+ // hang up on them anyway.
+ return sc.countError("ack_mystery", http2ConnectionError(http2ErrCodeProtocol))
+ }
+ return nil
+ }
+ if f.NumSettings() > 100 || f.HasDuplicates() {
+ // This isn't actually in the spec, but hang up on
+ // suspiciously large settings frames or those with
+ // duplicate entries.
+ return sc.countError("settings_big_or_dups", http2ConnectionError(http2ErrCodeProtocol))
+ }
+ if err := f.ForeachSetting(sc.processSetting); err != nil {
+ return err
+ }
+ // TODO: judging by RFC 7540, Section 6.5.3 each SETTINGS frame should be
+ // acknowledged individually, even if multiple are received before the ACK.
+ sc.needToSendSettingsAck = true
+ sc.scheduleFrameWrite()
+ return nil
+}
+
+func (sc *http2serverConn) processSetting(s http2Setting) error {
+ sc.serveG.check()
+ if err := s.Valid(); err != nil {
+ return err
+ }
+ if http2VerboseLogs {
+ sc.vlogf("http2: server processing setting %v", s)
+ }
+ switch s.ID {
+ case http2SettingHeaderTableSize:
+ sc.hpackEncoder.SetMaxDynamicTableSize(s.Val)
+ case http2SettingEnablePush:
+ sc.pushEnabled = s.Val != 0
+ case http2SettingMaxConcurrentStreams:
+ sc.clientMaxStreams = s.Val
+ case http2SettingInitialWindowSize:
+ return sc.processSettingInitialWindowSize(s.Val)
+ case http2SettingMaxFrameSize:
+ sc.maxFrameSize = int32(s.Val) // the maximum valid s.Val is < 2^31
+ case http2SettingMaxHeaderListSize:
+ sc.peerMaxHeaderListSize = s.Val
+ default:
+ // Unknown setting: "An endpoint that receives a SETTINGS
+ // frame with any unknown or unsupported identifier MUST
+ // ignore that setting."
+ if http2VerboseLogs {
+ sc.vlogf("http2: server ignoring unknown setting %v", s)
+ }
+ }
+ return nil
+}
+
+func (sc *http2serverConn) processSettingInitialWindowSize(val uint32) error {
+ sc.serveG.check()
+ // Note: val already validated to be within range by
+ // processSetting's Valid call.
+
+ // "A SETTINGS frame can alter the initial flow control window
+ // size for all current streams. When the value of
+ // SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST
+ // adjust the size of all stream flow control windows that it
+ // maintains by the difference between the new value and the
+ // old value."
+ old := sc.initialStreamSendWindowSize
+ sc.initialStreamSendWindowSize = int32(val)
+ growth := int32(val) - old // may be negative
+ for _, st := range sc.streams {
+ if !st.flow.add(growth) {
+ // 6.9.2 Initial Flow Control Window Size
+ // "An endpoint MUST treat a change to
+ // SETTINGS_INITIAL_WINDOW_SIZE that causes any flow
+ // control window to exceed the maximum size as a
+ // connection error (Section 5.4.1) of type
+ // FLOW_CONTROL_ERROR."
+ return sc.countError("setting_win_size", http2ConnectionError(http2ErrCodeFlowControl))
+ }
+ }
+ return nil
+}
+
+func (sc *http2serverConn) processData(f *http2DataFrame) error {
+ sc.serveG.check()
+ id := f.Header().StreamID
+
+ data := f.Data()
+ state, st := sc.state(id)
+ if id == 0 || state == http2stateIdle {
+ // Section 6.1: "DATA frames MUST be associated with a
+ // stream. If a DATA frame is received whose stream
+ // identifier field is 0x0, the recipient MUST respond
+ // with a connection error (Section 5.4.1) of type
+ // PROTOCOL_ERROR."
+ //
+ // Section 5.1: "Receiving any frame other than HEADERS
+ // or PRIORITY on a stream in this state MUST be
+ // treated as a connection error (Section 5.4.1) of
+ // type PROTOCOL_ERROR."
+ return sc.countError("data_on_idle", http2ConnectionError(http2ErrCodeProtocol))
+ }
+
+ // "If a DATA frame is received whose stream is not in "open"
+ // or "half closed (local)" state, the recipient MUST respond
+ // with a stream error (Section 5.4.2) of type STREAM_CLOSED."
+ if st == nil || state != http2stateOpen || st.gotTrailerHeader || st.resetQueued {
+ // This includes sending a RST_STREAM if the stream is
+ // in stateHalfClosedLocal (which currently means that
+ // the http.Handler returned, so it's done reading &
+ // done writing). Try to stop the client from sending
+ // more DATA.
+
+ // But still enforce their connection-level flow control,
+ // and return any flow control bytes since we're not going
+ // to consume them.
+ if !sc.inflow.take(f.Length) {
+ return sc.countError("data_flow", http2streamError(id, http2ErrCodeFlowControl))
+ }
+ sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
+
+ if st != nil && st.resetQueued {
+ // Already have a stream error in flight. Don't send another.
+ return nil
+ }
+ return sc.countError("closed", http2streamError(id, http2ErrCodeStreamClosed))
+ }
+ if st.body == nil {
+ panic("internal error: should have a body in this state")
+ }
+
+ // Sender sending more than they'd declared?
+ if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes {
+ if !sc.inflow.take(f.Length) {
+ return sc.countError("data_flow", http2streamError(id, http2ErrCodeFlowControl))
+ }
+ sc.sendWindowUpdate(nil, int(f.Length)) // conn-level
+
+ st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes))
+ // RFC 7540, sec 8.1.2.6: A request or response is also malformed if the
+ // value of a content-length header field does not equal the sum of the
+ // DATA frame payload lengths that form the body.
+ return sc.countError("send_too_much", http2streamError(id, http2ErrCodeProtocol))
+ }
+ if f.Length > 0 {
+ // Check whether the client has flow control quota.
+ if !http2takeInflows(&sc.inflow, &st.inflow, f.Length) {
+ return sc.countError("flow_on_data_length", http2streamError(id, http2ErrCodeFlowControl))
+ }
+
+ if len(data) > 0 {
+ st.bodyBytes += int64(len(data))
+ wrote, err := st.body.Write(data)
+ if err != nil {
+ // The handler has closed the request body.
+ // Return the connection-level flow control for the discarded data,
+ // but not the stream-level flow control.
+ sc.sendWindowUpdate(nil, int(f.Length)-wrote)
+ return nil
+ }
+ if wrote != len(data) {
+ panic("internal error: bad Writer")
+ }
+ }
+
+ // Return any padded flow control now, since we won't
+ // refund it later on body reads.
+ // Call sendWindowUpdate even if there is no padding,
+ // to return buffered flow control credit if the sent
+ // window has shrunk.
+ pad := int32(f.Length) - int32(len(data))
+ sc.sendWindowUpdate32(nil, pad)
+ sc.sendWindowUpdate32(st, pad)
+ }
+ if f.StreamEnded() {
+ st.endStream()
+ }
+ return nil
+}
+
+func (sc *http2serverConn) processGoAway(f *http2GoAwayFrame) error {
+ sc.serveG.check()
+ if f.ErrCode != http2ErrCodeNo {
+ sc.logf("http2: received GOAWAY %+v, starting graceful shutdown", f)
+ } else {
+ sc.vlogf("http2: received GOAWAY %+v, starting graceful shutdown", f)
+ }
+ sc.startGracefulShutdownInternal()
+ // http://tools.ietf.org/html/rfc7540#section-6.8
+ // We should not create any new streams, which means we should disable push.
+ sc.pushEnabled = false
+ return nil
+}
+
+// isPushed reports whether the stream is server-initiated.
+func (st *http2stream) isPushed() bool {
+ return st.id%2 == 0
+}
+
+// endStream closes a Request.Body's pipe. It is called when a DATA
+// frame says a request body is over (or after trailers).
+func (st *http2stream) endStream() {
+ sc := st.sc
+ sc.serveG.check()
+
+ if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes {
+ st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes",
+ st.declBodyBytes, st.bodyBytes))
+ } else {
+ st.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest)
+ st.body.CloseWithError(io.EOF)
+ }
+ st.state = http2stateHalfClosedRemote
+}
+
+// copyTrailersToHandlerRequest is run in the Handler's goroutine in
+// its Request.Body.Read just before it gets io.EOF.
+func (st *http2stream) copyTrailersToHandlerRequest() {
+ for k, vv := range st.trailer {
+ if _, ok := st.reqTrailer[k]; ok {
+ // Only copy it over it was pre-declared.
+ st.reqTrailer[k] = vv
+ }
+ }
+}
+
+// onReadTimeout is run on its own goroutine (from time.AfterFunc)
+// when the stream's ReadTimeout has fired.
+func (st *http2stream) onReadTimeout() {
+ // Wrap the ErrDeadlineExceeded to avoid callers depending on us
+ // returning the bare error.
+ st.body.CloseWithError(fmt.Errorf("%w", os.ErrDeadlineExceeded))
+}
+
+// onWriteTimeout is run on its own goroutine (from time.AfterFunc)
+// when the stream's WriteTimeout has fired.
+func (st *http2stream) onWriteTimeout() {
+ st.sc.writeFrameFromHandler(http2FrameWriteRequest{write: http2StreamError{
+ StreamID: st.id,
+ Code: http2ErrCodeInternal,
+ Cause: os.ErrDeadlineExceeded,
+ }})
+}
+
+func (sc *http2serverConn) processHeaders(f *http2MetaHeadersFrame) error {
+ sc.serveG.check()
+ id := f.StreamID
+ // http://tools.ietf.org/html/rfc7540#section-5.1.1
+ // Streams initiated by a client MUST use odd-numbered stream
+ // identifiers. [...] An endpoint that receives an unexpected
+ // stream identifier MUST respond with a connection error
+ // (Section 5.4.1) of type PROTOCOL_ERROR.
+ if id%2 != 1 {
+ return sc.countError("headers_even", http2ConnectionError(http2ErrCodeProtocol))
+ }
+ // A HEADERS frame can be used to create a new stream or
+ // send a trailer for an open one. If we already have a stream
+ // open, let it process its own HEADERS frame (trailers at this
+ // point, if it's valid).
+ if st := sc.streams[f.StreamID]; st != nil {
+ if st.resetQueued {
+ // We're sending RST_STREAM to close the stream, so don't bother
+ // processing this frame.
+ return nil
+ }
+ // RFC 7540, sec 5.1: If an endpoint receives additional frames, other than
+ // WINDOW_UPDATE, PRIORITY, or RST_STREAM, for a stream that is in
+ // this state, it MUST respond with a stream error (Section 5.4.2) of
+ // type STREAM_CLOSED.
+ if st.state == http2stateHalfClosedRemote {
+ return sc.countError("headers_half_closed", http2streamError(id, http2ErrCodeStreamClosed))
+ }
+ return st.processTrailerHeaders(f)
+ }
+
+ // [...] The identifier of a newly established stream MUST be
+ // numerically greater than all streams that the initiating
+ // endpoint has opened or reserved. [...] An endpoint that
+ // receives an unexpected stream identifier MUST respond with
+ // a connection error (Section 5.4.1) of type PROTOCOL_ERROR.
+ if id <= sc.maxClientStreamID {
+ return sc.countError("stream_went_down", http2ConnectionError(http2ErrCodeProtocol))
+ }
+ sc.maxClientStreamID = id
+
+ if sc.idleTimer != nil {
+ sc.idleTimer.Stop()
+ }
+
+ // http://tools.ietf.org/html/rfc7540#section-5.1.2
+ // [...] Endpoints MUST NOT exceed the limit set by their peer. An
+ // endpoint that receives a HEADERS frame that causes their
+ // advertised concurrent stream limit to be exceeded MUST treat
+ // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR
+ // or REFUSED_STREAM.
+ if sc.curClientStreams+1 > sc.advMaxStreams {
+ if sc.unackedSettings == 0 {
+ // They should know better.
+ return sc.countError("over_max_streams", http2streamError(id, http2ErrCodeProtocol))
+ }
+ // Assume it's a network race, where they just haven't
+ // received our last SETTINGS update. But actually
+ // this can't happen yet, because we don't yet provide
+ // a way for users to adjust server parameters at
+ // runtime.
+ return sc.countError("over_max_streams_race", http2streamError(id, http2ErrCodeRefusedStream))
+ }
+
+ initialState := http2stateOpen
+ if f.StreamEnded() {
+ initialState = http2stateHalfClosedRemote
+ }
+ st := sc.newStream(id, 0, initialState)
+
+ if f.HasPriority() {
+ if err := sc.checkPriority(f.StreamID, f.Priority); err != nil {
+ return err
+ }
+ sc.writeSched.AdjustStream(st.id, f.Priority)
+ }
+
+ rw, req, err := sc.newWriterAndRequest(st, f)
+ if err != nil {
+ return err
+ }
+ st.reqTrailer = req.Trailer
+ if st.reqTrailer != nil {
+ st.trailer = make(Header)
+ }
+ st.body = req.Body.(*http2requestBody).pipe // may be nil
+ st.declBodyBytes = req.ContentLength
+
+ handler := sc.handler.ServeHTTP
+ if f.Truncated {
+ // Their header list was too long. Send a 431 error.
+ handler = http2handleHeaderListTooLong
+ } else if err := http2checkValidHTTP2RequestHeaders(req.Header); err != nil {
+ handler = http2new400Handler(err)
+ }
+
+ // The net/http package sets the read deadline from the
+ // http.Server.ReadTimeout during the TLS handshake, but then
+ // passes the connection off to us with the deadline already
+ // set. Disarm it here after the request headers are read,
+ // similar to how the http1 server works. Here it's
+ // technically more like the http1 Server's ReadHeaderTimeout
+ // (in Go 1.8), though. That's a more sane option anyway.
+ if sc.hs.ReadTimeout != 0 {
+ sc.conn.SetReadDeadline(time.Time{})
+ if st.body != nil {
+ st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
+ }
+ }
+
+ return sc.scheduleHandler(id, rw, req, handler)
+}
+
+func (sc *http2serverConn) upgradeRequest(req *Request) {
+ sc.serveG.check()
+ id := uint32(1)
+ sc.maxClientStreamID = id
+ st := sc.newStream(id, 0, http2stateHalfClosedRemote)
+ st.reqTrailer = req.Trailer
+ if st.reqTrailer != nil {
+ st.trailer = make(Header)
+ }
+ rw := sc.newResponseWriter(st, req)
+
+ // Disable any read deadline set by the net/http package
+ // prior to the upgrade.
+ if sc.hs.ReadTimeout != 0 {
+ sc.conn.SetReadDeadline(time.Time{})
+ }
+
+ // This is the first request on the connection,
+ // so start the handler directly rather than going
+ // through scheduleHandler.
+ sc.curHandlers++
+ go sc.runHandler(rw, req, sc.handler.ServeHTTP)
+}
+
+func (st *http2stream) processTrailerHeaders(f *http2MetaHeadersFrame) error {
+ sc := st.sc
+ sc.serveG.check()
+ if st.gotTrailerHeader {
+ return sc.countError("dup_trailers", http2ConnectionError(http2ErrCodeProtocol))
+ }
+ st.gotTrailerHeader = true
+ if !f.StreamEnded() {
+ return sc.countError("trailers_not_ended", http2streamError(st.id, http2ErrCodeProtocol))
+ }
+
+ if len(f.PseudoFields()) > 0 {
+ return sc.countError("trailers_pseudo", http2streamError(st.id, http2ErrCodeProtocol))
+ }
+ if st.trailer != nil {
+ for _, hf := range f.RegularFields() {
+ key := sc.canonicalHeader(hf.Name)
+ if !httpguts.ValidTrailerHeader(key) {
+ // TODO: send more details to the peer somehow. But http2 has
+ // no way to send debug data at a stream level. Discuss with
+ // HTTP folk.
+ return sc.countError("trailers_bogus", http2streamError(st.id, http2ErrCodeProtocol))
+ }
+ st.trailer[key] = append(st.trailer[key], hf.Value)
+ }
+ }
+ st.endStream()
+ return nil
+}
+
+func (sc *http2serverConn) checkPriority(streamID uint32, p http2PriorityParam) error {
+ if streamID == p.StreamDep {
+ // Section 5.3.1: "A stream cannot depend on itself. An endpoint MUST treat
+ // this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR."
+ // Section 5.3.3 says that a stream can depend on one of its dependencies,
+ // so it's only self-dependencies that are forbidden.
+ return sc.countError("priority", http2streamError(streamID, http2ErrCodeProtocol))
+ }
+ return nil
+}
+
+func (sc *http2serverConn) processPriority(f *http2PriorityFrame) error {
+ if err := sc.checkPriority(f.StreamID, f.http2PriorityParam); err != nil {
+ return err
+ }
+ sc.writeSched.AdjustStream(f.StreamID, f.http2PriorityParam)
+ return nil
+}
+
+func (sc *http2serverConn) newStream(id, pusherID uint32, state http2streamState) *http2stream {
+ sc.serveG.check()
+ if id == 0 {
+ panic("internal error: cannot create stream with id 0")
+ }
+
+ ctx, cancelCtx := context.WithCancel(sc.baseCtx)
+ st := &http2stream{
+ sc: sc,
+ id: id,
+ state: state,
+ ctx: ctx,
+ cancelCtx: cancelCtx,
+ }
+ st.cw.Init()
+ st.flow.conn = &sc.flow // link to conn-level counter
+ st.flow.add(sc.initialStreamSendWindowSize)
+ st.inflow.init(sc.srv.initialStreamRecvWindowSize())
+ if sc.hs.WriteTimeout != 0 {
+ st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
+ }
+
+ sc.streams[id] = st
+ sc.writeSched.OpenStream(st.id, http2OpenStreamOptions{PusherID: pusherID})
+ if st.isPushed() {
+ sc.curPushedStreams++
+ } else {
+ sc.curClientStreams++
+ }
+ if sc.curOpenStreams() == 1 {
+ sc.setConnState(StateActive)
+ }
+
+ return st
+}
+
+func (sc *http2serverConn) newWriterAndRequest(st *http2stream, f *http2MetaHeadersFrame) (*http2responseWriter, *Request, error) {
+ sc.serveG.check()
+
+ rp := http2requestParam{
+ method: f.PseudoValue("method"),
+ scheme: f.PseudoValue("scheme"),
+ authority: f.PseudoValue("authority"),
+ path: f.PseudoValue("path"),
+ }
+
+ isConnect := rp.method == "CONNECT"
+ if isConnect {
+ if rp.path != "" || rp.scheme != "" || rp.authority == "" {
+ return nil, nil, sc.countError("bad_connect", http2streamError(f.StreamID, http2ErrCodeProtocol))
+ }
+ } else if rp.method == "" || rp.path == "" || (rp.scheme != "https" && rp.scheme != "http") {
+ // See 8.1.2.6 Malformed Requests and Responses:
+ //
+ // Malformed requests or responses that are detected
+ // MUST be treated as a stream error (Section 5.4.2)
+ // of type PROTOCOL_ERROR."
+ //
+ // 8.1.2.3 Request Pseudo-Header Fields
+ // "All HTTP/2 requests MUST include exactly one valid
+ // value for the :method, :scheme, and :path
+ // pseudo-header fields"
+ return nil, nil, sc.countError("bad_path_method", http2streamError(f.StreamID, http2ErrCodeProtocol))
+ }
+
+ rp.header = make(Header)
+ for _, hf := range f.RegularFields() {
+ rp.header.Add(sc.canonicalHeader(hf.Name), hf.Value)
+ }
+ if rp.authority == "" {
+ rp.authority = rp.header.Get("Host")
+ }
+
+ rw, req, err := sc.newWriterAndRequestNoBody(st, rp)
+ if err != nil {
+ return nil, nil, err
+ }
+ bodyOpen := !f.StreamEnded()
+ if bodyOpen {
+ if vv, ok := rp.header["Content-Length"]; ok {
+ if cl, err := strconv.ParseUint(vv[0], 10, 63); err == nil {
+ req.ContentLength = int64(cl)
+ } else {
+ req.ContentLength = 0
+ }
+ } else {
+ req.ContentLength = -1
+ }
+ req.Body.(*http2requestBody).pipe = &http2pipe{
+ b: &http2dataBuffer{expected: req.ContentLength},
+ }
+ }
+ return rw, req, nil
+}
+
+type http2requestParam struct {
+ method string
+ scheme, authority, path string
+ header Header
+}
+
+func (sc *http2serverConn) newWriterAndRequestNoBody(st *http2stream, rp http2requestParam) (*http2responseWriter, *Request, error) {
+ sc.serveG.check()
+
+ var tlsState *tls.ConnectionState // nil if not scheme https
+ if rp.scheme == "https" {
+ tlsState = sc.tlsState
+ }
+
+ needsContinue := httpguts.HeaderValuesContainsToken(rp.header["Expect"], "100-continue")
+ if needsContinue {
+ rp.header.Del("Expect")
+ }
+ // Merge Cookie headers into one "; "-delimited value.
+ if cookies := rp.header["Cookie"]; len(cookies) > 1 {
+ rp.header.Set("Cookie", strings.Join(cookies, "; "))
+ }
+
+ // Setup Trailers
+ var trailer Header
+ for _, v := range rp.header["Trailer"] {
+ for _, key := range strings.Split(v, ",") {
+ key = CanonicalHeaderKey(textproto.TrimString(key))
+ switch key {
+ case "Transfer-Encoding", "Trailer", "Content-Length":
+ // Bogus. (copy of http1 rules)
+ // Ignore.
+ default:
+ if trailer == nil {
+ trailer = make(Header)
+ }
+ trailer[key] = nil
+ }
+ }
+ }
+ delete(rp.header, "Trailer")
+
+ var url_ *url.URL
+ var requestURI string
+ if rp.method == "CONNECT" {
+ url_ = &url.URL{Host: rp.authority}
+ requestURI = rp.authority // mimic HTTP/1 server behavior
+ } else {
+ var err error
+ url_, err = url.ParseRequestURI(rp.path)
+ if err != nil {
+ return nil, nil, sc.countError("bad_path", http2streamError(st.id, http2ErrCodeProtocol))
+ }
+ requestURI = rp.path
+ }
+
+ body := &http2requestBody{
+ conn: sc,
+ stream: st,
+ needsContinue: needsContinue,
+ }
+ req := &Request{
+ Method: rp.method,
+ URL: url_,
+ RemoteAddr: sc.remoteAddrStr,
+ Header: rp.header,
+ RequestURI: requestURI,
+ Proto: "HTTP/2.0",
+ ProtoMajor: 2,
+ ProtoMinor: 0,
+ TLS: tlsState,
+ Host: rp.authority,
+ Body: body,
+ Trailer: trailer,
+ }
+ req = req.WithContext(st.ctx)
+
+ rw := sc.newResponseWriter(st, req)
+ return rw, req, nil
+}
+
+func (sc *http2serverConn) newResponseWriter(st *http2stream, req *Request) *http2responseWriter {
+ rws := http2responseWriterStatePool.Get().(*http2responseWriterState)
+ bwSave := rws.bw
+ *rws = http2responseWriterState{} // zero all the fields
+ rws.conn = sc
+ rws.bw = bwSave
+ rws.bw.Reset(http2chunkWriter{rws})
+ rws.stream = st
+ rws.req = req
+ return &http2responseWriter{rws: rws}
+}
+
+type http2unstartedHandler struct {
+ streamID uint32
+ rw *http2responseWriter
+ req *Request
+ handler func(ResponseWriter, *Request)
+}
+
+// scheduleHandler starts a handler goroutine,
+// or schedules one to start as soon as an existing handler finishes.
+func (sc *http2serverConn) scheduleHandler(streamID uint32, rw *http2responseWriter, req *Request, handler func(ResponseWriter, *Request)) error {
+ sc.serveG.check()
+ maxHandlers := sc.advMaxStreams
+ if sc.curHandlers < maxHandlers {
+ sc.curHandlers++
+ go sc.runHandler(rw, req, handler)
+ return nil
+ }
+ if len(sc.unstartedHandlers) > int(4*sc.advMaxStreams) {
+ return sc.countError("too_many_early_resets", http2ConnectionError(http2ErrCodeEnhanceYourCalm))
+ }
+ sc.unstartedHandlers = append(sc.unstartedHandlers, http2unstartedHandler{
+ streamID: streamID,
+ rw: rw,
+ req: req,
+ handler: handler,
+ })
+ return nil
+}
+
+func (sc *http2serverConn) handlerDone() {
+ sc.serveG.check()
+ sc.curHandlers--
+ i := 0
+ maxHandlers := sc.advMaxStreams
+ for ; i < len(sc.unstartedHandlers); i++ {
+ u := sc.unstartedHandlers[i]
+ if sc.streams[u.streamID] == nil {
+ // This stream was reset before its goroutine had a chance to start.
+ continue
+ }
+ if sc.curHandlers >= maxHandlers {
+ break
+ }
+ sc.curHandlers++
+ go sc.runHandler(u.rw, u.req, u.handler)
+ sc.unstartedHandlers[i] = http2unstartedHandler{} // don't retain references
+ }
+ sc.unstartedHandlers = sc.unstartedHandlers[i:]
+ if len(sc.unstartedHandlers) == 0 {
+ sc.unstartedHandlers = nil
+ }
+}
+
+// Run on its own goroutine.
+func (sc *http2serverConn) runHandler(rw *http2responseWriter, req *Request, handler func(ResponseWriter, *Request)) {
+ defer sc.sendServeMsg(http2handlerDoneMsg)
+ didPanic := true
+ defer func() {
+ rw.rws.stream.cancelCtx()
+ if req.MultipartForm != nil {
+ req.MultipartForm.RemoveAll()
+ }
+ if didPanic {
+ e := recover()
+ sc.writeFrameFromHandler(http2FrameWriteRequest{
+ write: http2handlerPanicRST{rw.rws.stream.id},
+ stream: rw.rws.stream,
+ })
+ // Same as net/http:
+ if e != nil && e != ErrAbortHandler {
+ const size = 64 << 10
+ buf := make([]byte, size)
+ buf = buf[:runtime.Stack(buf, false)]
+ sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf)
+ }
+ return
+ }
+ rw.handlerDone()
+ }()
+ handler(rw, req)
+ didPanic = false
+}
+
+func http2handleHeaderListTooLong(w ResponseWriter, r *Request) {
+ // 10.5.1 Limits on Header Block Size:
+ // .. "A server that receives a larger header block than it is
+ // willing to handle can send an HTTP 431 (Request Header Fields Too
+ // Large) status code"
+ const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+
+ w.WriteHeader(statusRequestHeaderFieldsTooLarge)
+ io.WriteString(w, "<h1>HTTP Error 431</h1><p>Request Header Field(s) Too Large</p>")
+}
+
+// called from handler goroutines.
+// h may be nil.
+func (sc *http2serverConn) writeHeaders(st *http2stream, headerData *http2writeResHeaders) error {
+ sc.serveG.checkNotOn() // NOT on
+ var errc chan error
+ if headerData.h != nil {
+ // If there's a header map (which we don't own), so we have to block on
+ // waiting for this frame to be written, so an http.Flush mid-handler
+ // writes out the correct value of keys, before a handler later potentially
+ // mutates it.
+ errc = http2errChanPool.Get().(chan error)
+ }
+ if err := sc.writeFrameFromHandler(http2FrameWriteRequest{
+ write: headerData,
+ stream: st,
+ done: errc,
+ }); err != nil {
+ return err
+ }
+ if errc != nil {
+ select {
+ case err := <-errc:
+ http2errChanPool.Put(errc)
+ return err
+ case <-sc.doneServing:
+ return http2errClientDisconnected
+ case <-st.cw:
+ return http2errStreamClosed
+ }
+ }
+ return nil
+}
+
+// called from handler goroutines.
+func (sc *http2serverConn) write100ContinueHeaders(st *http2stream) {
+ sc.writeFrameFromHandler(http2FrameWriteRequest{
+ write: http2write100ContinueHeadersFrame{st.id},
+ stream: st,
+ })
+}
+
+// A bodyReadMsg tells the server loop that the http.Handler read n
+// bytes of the DATA from the client on the given stream.
+type http2bodyReadMsg struct {
+ st *http2stream
+ n int
+}
+
+// called from handler goroutines.
+// Notes that the handler for the given stream ID read n bytes of its body
+// and schedules flow control tokens to be sent.
+func (sc *http2serverConn) noteBodyReadFromHandler(st *http2stream, n int, err error) {
+ sc.serveG.checkNotOn() // NOT on
+ if n > 0 {
+ select {
+ case sc.bodyReadCh <- http2bodyReadMsg{st, n}:
+ case <-sc.doneServing:
+ }
+ }
+}
+
+func (sc *http2serverConn) noteBodyRead(st *http2stream, n int) {
+ sc.serveG.check()
+ sc.sendWindowUpdate(nil, n) // conn-level
+ if st.state != http2stateHalfClosedRemote && st.state != http2stateClosed {
+ // Don't send this WINDOW_UPDATE if the stream is closed
+ // remotely.
+ sc.sendWindowUpdate(st, n)
+ }
+}
+
+// st may be nil for conn-level
+func (sc *http2serverConn) sendWindowUpdate32(st *http2stream, n int32) {
+ sc.sendWindowUpdate(st, int(n))
+}
+
+// st may be nil for conn-level
+func (sc *http2serverConn) sendWindowUpdate(st *http2stream, n int) {
+ sc.serveG.check()
+ var streamID uint32
+ var send int32
+ if st == nil {
+ send = sc.inflow.add(n)
+ } else {
+ streamID = st.id
+ send = st.inflow.add(n)
+ }
+ if send == 0 {
+ return
+ }
+ sc.writeFrame(http2FrameWriteRequest{
+ write: http2writeWindowUpdate{streamID: streamID, n: uint32(send)},
+ stream: st,
+ })
+}
+
+// requestBody is the Handler's Request.Body type.
+// Read and Close may be called concurrently.
+type http2requestBody struct {
+ _ http2incomparable
+ stream *http2stream
+ conn *http2serverConn
+ closeOnce sync.Once // for use by Close only
+ sawEOF bool // for use by Read only
+ pipe *http2pipe // non-nil if we have an HTTP entity message body
+ needsContinue bool // need to send a 100-continue
+}
+
+func (b *http2requestBody) Close() error {
+ b.closeOnce.Do(func() {
+ if b.pipe != nil {
+ b.pipe.BreakWithError(http2errClosedBody)
+ }
+ })
+ return nil
+}
+
+func (b *http2requestBody) Read(p []byte) (n int, err error) {
+ if b.needsContinue {
+ b.needsContinue = false
+ b.conn.write100ContinueHeaders(b.stream)
+ }
+ if b.pipe == nil || b.sawEOF {
+ return 0, io.EOF
+ }
+ n, err = b.pipe.Read(p)
+ if err == io.EOF {
+ b.sawEOF = true
+ }
+ if b.conn == nil && http2inTests {
+ return
+ }
+ b.conn.noteBodyReadFromHandler(b.stream, n, err)
+ return
+}
+
+// responseWriter is the http.ResponseWriter implementation. It's
+// intentionally small (1 pointer wide) to minimize garbage. The
+// responseWriterState pointer inside is zeroed at the end of a
+// request (in handlerDone) and calls on the responseWriter thereafter
+// simply crash (caller's mistake), but the much larger responseWriterState
+// and buffers are reused between multiple requests.
+type http2responseWriter struct {
+ rws *http2responseWriterState
+}
+
+// Optional http.ResponseWriter interfaces implemented.
+var (
+ _ CloseNotifier = (*http2responseWriter)(nil)
+ _ Flusher = (*http2responseWriter)(nil)
+ _ http2stringWriter = (*http2responseWriter)(nil)
+)
+
+type http2responseWriterState struct {
+ // immutable within a request:
+ stream *http2stream
+ req *Request
+ conn *http2serverConn
+
+ // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc
+ bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState}
+
+ // mutated by http.Handler goroutine:
+ handlerHeader Header // nil until called
+ snapHeader Header // snapshot of handlerHeader at WriteHeader time
+ trailers []string // set in writeChunk
+ status int // status code passed to WriteHeader
+ wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet.
+ sentHeader bool // have we sent the header frame?
+ handlerDone bool // handler has finished
+ dirty bool // a Write failed; don't reuse this responseWriterState
+
+ sentContentLen int64 // non-zero if handler set a Content-Length header
+ wroteBytes int64
+
+ closeNotifierMu sync.Mutex // guards closeNotifierCh
+ closeNotifierCh chan bool // nil until first used
+}
+
+type http2chunkWriter struct{ rws *http2responseWriterState }
+
+func (cw http2chunkWriter) Write(p []byte) (n int, err error) {
+ n, err = cw.rws.writeChunk(p)
+ if err == http2errStreamClosed {
+ // If writing failed because the stream has been closed,
+ // return the reason it was closed.
+ err = cw.rws.stream.closeErr
+ }
+ return n, err
+}
+
+func (rws *http2responseWriterState) hasTrailers() bool { return len(rws.trailers) > 0 }
+
+func (rws *http2responseWriterState) hasNonemptyTrailers() bool {
+ for _, trailer := range rws.trailers {
+ if _, ok := rws.handlerHeader[trailer]; ok {
+ return true
+ }
+ }
+ return false
+}
+
+// declareTrailer is called for each Trailer header when the
+// response header is written. It notes that a header will need to be
+// written in the trailers at the end of the response.
+func (rws *http2responseWriterState) declareTrailer(k string) {
+ k = CanonicalHeaderKey(k)
+ if !httpguts.ValidTrailerHeader(k) {
+ // Forbidden by RFC 7230, section 4.1.2.
+ rws.conn.logf("ignoring invalid trailer %q", k)
+ return
+ }
+ if !http2strSliceContains(rws.trailers, k) {
+ rws.trailers = append(rws.trailers, k)
+ }
+}
+
+// writeChunk writes chunks from the bufio.Writer. But because
+// bufio.Writer may bypass its chunking, sometimes p may be
+// arbitrarily large.
+//
+// writeChunk is also responsible (on the first chunk) for sending the
+// HEADER response.
+func (rws *http2responseWriterState) writeChunk(p []byte) (n int, err error) {
+ if !rws.wroteHeader {
+ rws.writeHeader(200)
+ }
+
+ if rws.handlerDone {
+ rws.promoteUndeclaredTrailers()
+ }
+
+ isHeadResp := rws.req.Method == "HEAD"
+ if !rws.sentHeader {
+ rws.sentHeader = true
+ var ctype, clen string
+ if clen = rws.snapHeader.Get("Content-Length"); clen != "" {
+ rws.snapHeader.Del("Content-Length")
+ if cl, err := strconv.ParseUint(clen, 10, 63); err == nil {
+ rws.sentContentLen = int64(cl)
+ } else {
+ clen = ""
+ }
+ }
+ _, hasContentLength := rws.snapHeader["Content-Length"]
+ if !hasContentLength && clen == "" && rws.handlerDone && http2bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) {
+ clen = strconv.Itoa(len(p))
+ }
+ _, hasContentType := rws.snapHeader["Content-Type"]
+ // If the Content-Encoding is non-blank, we shouldn't
+ // sniff the body. See Issue golang.org/issue/31753.
+ ce := rws.snapHeader.Get("Content-Encoding")
+ hasCE := len(ce) > 0
+ if !hasCE && !hasContentType && http2bodyAllowedForStatus(rws.status) && len(p) > 0 {
+ ctype = DetectContentType(p)
+ }
+ var date string
+ if _, ok := rws.snapHeader["Date"]; !ok {
+ // TODO(bradfitz): be faster here, like net/http? measure.
+ date = time.Now().UTC().Format(TimeFormat)
+ }
+
+ for _, v := range rws.snapHeader["Trailer"] {
+ http2foreachHeaderElement(v, rws.declareTrailer)
+ }
+
+ // "Connection" headers aren't allowed in HTTP/2 (RFC 7540, 8.1.2.2),
+ // but respect "Connection" == "close" to mean sending a GOAWAY and tearing
+ // down the TCP connection when idle, like we do for HTTP/1.
+ // TODO: remove more Connection-specific header fields here, in addition
+ // to "Connection".
+ if _, ok := rws.snapHeader["Connection"]; ok {
+ v := rws.snapHeader.Get("Connection")
+ delete(rws.snapHeader, "Connection")
+ if v == "close" {
+ rws.conn.startGracefulShutdown()
+ }
+ }
+
+ endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp
+ err = rws.conn.writeHeaders(rws.stream, &http2writeResHeaders{
+ streamID: rws.stream.id,
+ httpResCode: rws.status,
+ h: rws.snapHeader,
+ endStream: endStream,
+ contentType: ctype,
+ contentLength: clen,
+ date: date,
+ })
+ if err != nil {
+ rws.dirty = true
+ return 0, err
+ }
+ if endStream {
+ return 0, nil
+ }
+ }
+ if isHeadResp {
+ return len(p), nil
+ }
+ if len(p) == 0 && !rws.handlerDone {
+ return 0, nil
+ }
+
+ // only send trailers if they have actually been defined by the
+ // server handler.
+ hasNonemptyTrailers := rws.hasNonemptyTrailers()
+ endStream := rws.handlerDone && !hasNonemptyTrailers
+ if len(p) > 0 || endStream {
+ // only send a 0 byte DATA frame if we're ending the stream.
+ if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil {
+ rws.dirty = true
+ return 0, err
+ }
+ }
+
+ if rws.handlerDone && hasNonemptyTrailers {
+ err = rws.conn.writeHeaders(rws.stream, &http2writeResHeaders{
+ streamID: rws.stream.id,
+ h: rws.handlerHeader,
+ trailers: rws.trailers,
+ endStream: true,
+ })
+ if err != nil {
+ rws.dirty = true
+ }
+ return len(p), err
+ }
+ return len(p), nil
+}
+
+// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
+// that, if present, signals that the map entry is actually for
+// the response trailers, and not the response headers. The prefix
+// is stripped after the ServeHTTP call finishes and the values are
+// sent in the trailers.
+//
+// This mechanism is intended only for trailers that are not known
+// prior to the headers being written. If the set of trailers is fixed
+// or known before the header is written, the normal Go trailers mechanism
+// is preferred:
+//
+// https://golang.org/pkg/net/http/#ResponseWriter
+// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers
+const http2TrailerPrefix = "Trailer:"
+
+// promoteUndeclaredTrailers permits http.Handlers to set trailers
+// after the header has already been flushed. Because the Go
+// ResponseWriter interface has no way to set Trailers (only the
+// Header), and because we didn't want to expand the ResponseWriter
+// interface, and because nobody used trailers, and because RFC 7230
+// says you SHOULD (but not must) predeclare any trailers in the
+// header, the official ResponseWriter rules said trailers in Go must
+// be predeclared, and then we reuse the same ResponseWriter.Header()
+// map to mean both Headers and Trailers. When it's time to write the
+// Trailers, we pick out the fields of Headers that were declared as
+// trailers. That worked for a while, until we found the first major
+// user of Trailers in the wild: gRPC (using them only over http2),
+// and gRPC libraries permit setting trailers mid-stream without
+// predeclaring them. So: change of plans. We still permit the old
+// way, but we also permit this hack: if a Header() key begins with
+// "Trailer:", the suffix of that key is a Trailer. Because ':' is an
+// invalid token byte anyway, there is no ambiguity. (And it's already
+// filtered out) It's mildly hacky, but not terrible.
+//
+// This method runs after the Handler is done and promotes any Header
+// fields to be trailers.
+func (rws *http2responseWriterState) promoteUndeclaredTrailers() {
+ for k, vv := range rws.handlerHeader {
+ if !strings.HasPrefix(k, http2TrailerPrefix) {
+ continue
+ }
+ trailerKey := strings.TrimPrefix(k, http2TrailerPrefix)
+ rws.declareTrailer(trailerKey)
+ rws.handlerHeader[CanonicalHeaderKey(trailerKey)] = vv
+ }
+
+ if len(rws.trailers) > 1 {
+ sorter := http2sorterPool.Get().(*http2sorter)
+ sorter.SortStrings(rws.trailers)
+ http2sorterPool.Put(sorter)
+ }
+}
+
+func (w *http2responseWriter) SetReadDeadline(deadline time.Time) error {
+ st := w.rws.stream
+ if !deadline.IsZero() && deadline.Before(time.Now()) {
+ // If we're setting a deadline in the past, reset the stream immediately
+ // so writes after SetWriteDeadline returns will fail.
+ st.onReadTimeout()
+ return nil
+ }
+ w.rws.conn.sendServeMsg(func(sc *http2serverConn) {
+ if st.readDeadline != nil {
+ if !st.readDeadline.Stop() {
+ // Deadline already exceeded, or stream has been closed.
+ return
+ }
+ }
+ if deadline.IsZero() {
+ st.readDeadline = nil
+ } else if st.readDeadline == nil {
+ st.readDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onReadTimeout)
+ } else {
+ st.readDeadline.Reset(deadline.Sub(time.Now()))
+ }
+ })
+ return nil
+}
+
+func (w *http2responseWriter) SetWriteDeadline(deadline time.Time) error {
+ st := w.rws.stream
+ if !deadline.IsZero() && deadline.Before(time.Now()) {
+ // If we're setting a deadline in the past, reset the stream immediately
+ // so writes after SetWriteDeadline returns will fail.
+ st.onWriteTimeout()
+ return nil
+ }
+ w.rws.conn.sendServeMsg(func(sc *http2serverConn) {
+ if st.writeDeadline != nil {
+ if !st.writeDeadline.Stop() {
+ // Deadline already exceeded, or stream has been closed.
+ return
+ }
+ }
+ if deadline.IsZero() {
+ st.writeDeadline = nil
+ } else if st.writeDeadline == nil {
+ st.writeDeadline = time.AfterFunc(deadline.Sub(time.Now()), st.onWriteTimeout)
+ } else {
+ st.writeDeadline.Reset(deadline.Sub(time.Now()))
+ }
+ })
+ return nil
+}
+
+func (w *http2responseWriter) Flush() {
+ w.FlushError()
+}
+
+func (w *http2responseWriter) FlushError() error {
+ rws := w.rws
+ if rws == nil {
+ panic("Header called after Handler finished")
+ }
+ var err error
+ if rws.bw.Buffered() > 0 {
+ err = rws.bw.Flush()
+ } else {
+ // The bufio.Writer won't call chunkWriter.Write
+ // (writeChunk with zero bytes), so we have to do it
+ // ourselves to force the HTTP response header and/or
+ // final DATA frame (with END_STREAM) to be sent.
+ _, err = http2chunkWriter{rws}.Write(nil)
+ if err == nil {
+ select {
+ case <-rws.stream.cw:
+ err = rws.stream.closeErr
+ default:
+ }
+ }
+ }
+ return err
+}
+
+func (w *http2responseWriter) CloseNotify() <-chan bool {
+ rws := w.rws
+ if rws == nil {
+ panic("CloseNotify called after Handler finished")
+ }
+ rws.closeNotifierMu.Lock()
+ ch := rws.closeNotifierCh
+ if ch == nil {
+ ch = make(chan bool, 1)
+ rws.closeNotifierCh = ch
+ cw := rws.stream.cw
+ go func() {
+ cw.Wait() // wait for close
+ ch <- true
+ }()
+ }
+ rws.closeNotifierMu.Unlock()
+ return ch
+}
+
+func (w *http2responseWriter) Header() Header {
+ rws := w.rws
+ if rws == nil {
+ panic("Header called after Handler finished")
+ }
+ if rws.handlerHeader == nil {
+ rws.handlerHeader = make(Header)
+ }
+ return rws.handlerHeader
+}
+
+// checkWriteHeaderCode is a copy of net/http's checkWriteHeaderCode.
+func http2checkWriteHeaderCode(code int) {
+ // Issue 22880: require valid WriteHeader status codes.
+ // For now we only enforce that it's three digits.
+ // In the future we might block things over 599 (600 and above aren't defined
+ // at http://httpwg.org/specs/rfc7231.html#status.codes).
+ // But for now any three digits.
+ //
+ // We used to send "HTTP/1.1 000 0" on the wire in responses but there's
+ // no equivalent bogus thing we can realistically send in HTTP/2,
+ // so we'll consistently panic instead and help people find their bugs
+ // early. (We can't return an error from WriteHeader even if we wanted to.)
+ if code < 100 || code > 999 {
+ panic(fmt.Sprintf("invalid WriteHeader code %v", code))
+ }
+}
+
+func (w *http2responseWriter) WriteHeader(code int) {
+ rws := w.rws
+ if rws == nil {
+ panic("WriteHeader called after Handler finished")
+ }
+ rws.writeHeader(code)
+}
+
+func (rws *http2responseWriterState) writeHeader(code int) {
+ if rws.wroteHeader {
+ return
+ }
+
+ http2checkWriteHeaderCode(code)
+
+ // Handle informational headers
+ if code >= 100 && code <= 199 {
+ // Per RFC 8297 we must not clear the current header map
+ h := rws.handlerHeader
+
+ _, cl := h["Content-Length"]
+ _, te := h["Transfer-Encoding"]
+ if cl || te {
+ h = h.Clone()
+ h.Del("Content-Length")
+ h.Del("Transfer-Encoding")
+ }
+
+ if rws.conn.writeHeaders(rws.stream, &http2writeResHeaders{
+ streamID: rws.stream.id,
+ httpResCode: code,
+ h: h,
+ endStream: rws.handlerDone && !rws.hasTrailers(),
+ }) != nil {
+ rws.dirty = true
+ }
+
+ return
+ }
+
+ rws.wroteHeader = true
+ rws.status = code
+ if len(rws.handlerHeader) > 0 {
+ rws.snapHeader = http2cloneHeader(rws.handlerHeader)
+ }
+}
+
+func http2cloneHeader(h Header) Header {
+ h2 := make(Header, len(h))
+ for k, vv := range h {
+ vv2 := make([]string, len(vv))
+ copy(vv2, vv)
+ h2[k] = vv2
+ }
+ return h2
+}
+
+// The Life Of A Write is like this:
+//
+// * Handler calls w.Write or w.WriteString ->
+// * -> rws.bw (*bufio.Writer) ->
+// * (Handler might call Flush)
+// * -> chunkWriter{rws}
+// * -> responseWriterState.writeChunk(p []byte)
+// * -> responseWriterState.writeChunk (most of the magic; see comment there)
+func (w *http2responseWriter) Write(p []byte) (n int, err error) {
+ return w.write(len(p), p, "")
+}
+
+func (w *http2responseWriter) WriteString(s string) (n int, err error) {
+ return w.write(len(s), nil, s)
+}
+
+// either dataB or dataS is non-zero.
+func (w *http2responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) {
+ rws := w.rws
+ if rws == nil {
+ panic("Write called after Handler finished")
+ }
+ if !rws.wroteHeader {
+ w.WriteHeader(200)
+ }
+ if !http2bodyAllowedForStatus(rws.status) {
+ return 0, ErrBodyNotAllowed
+ }
+ rws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set
+ if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen {
+ // TODO: send a RST_STREAM
+ return 0, errors.New("http2: handler wrote more than declared Content-Length")
+ }
+
+ if dataB != nil {
+ return rws.bw.Write(dataB)
+ } else {
+ return rws.bw.WriteString(dataS)
+ }
+}
+
+func (w *http2responseWriter) handlerDone() {
+ rws := w.rws
+ dirty := rws.dirty
+ rws.handlerDone = true
+ w.Flush()
+ w.rws = nil
+ if !dirty {
+ // Only recycle the pool if all prior Write calls to
+ // the serverConn goroutine completed successfully. If
+ // they returned earlier due to resets from the peer
+ // there might still be write goroutines outstanding
+ // from the serverConn referencing the rws memory. See
+ // issue 20704.
+ http2responseWriterStatePool.Put(rws)
+ }
+}
+
+// Push errors.
+var (
+ http2ErrRecursivePush = errors.New("http2: recursive push not allowed")
+ http2ErrPushLimitReached = errors.New("http2: push would exceed peer's SETTINGS_MAX_CONCURRENT_STREAMS")
+)
+
+var _ Pusher = (*http2responseWriter)(nil)
+
+func (w *http2responseWriter) Push(target string, opts *PushOptions) error {
+ st := w.rws.stream
+ sc := st.sc
+ sc.serveG.checkNotOn()
+
+ // No recursive pushes: "PUSH_PROMISE frames MUST only be sent on a peer-initiated stream."
+ // http://tools.ietf.org/html/rfc7540#section-6.6
+ if st.isPushed() {
+ return http2ErrRecursivePush
+ }
+
+ if opts == nil {
+ opts = new(PushOptions)
+ }
+
+ // Default options.
+ if opts.Method == "" {
+ opts.Method = "GET"
+ }
+ if opts.Header == nil {
+ opts.Header = Header{}
+ }
+ wantScheme := "http"
+ if w.rws.req.TLS != nil {
+ wantScheme = "https"
+ }
+
+ // Validate the request.
+ u, err := url.Parse(target)
+ if err != nil {
+ return err
+ }
+ if u.Scheme == "" {
+ if !strings.HasPrefix(target, "/") {
+ return fmt.Errorf("target must be an absolute URL or an absolute path: %q", target)
+ }
+ u.Scheme = wantScheme
+ u.Host = w.rws.req.Host
+ } else {
+ if u.Scheme != wantScheme {
+ return fmt.Errorf("cannot push URL with scheme %q from request with scheme %q", u.Scheme, wantScheme)
+ }
+ if u.Host == "" {
+ return errors.New("URL must have a host")
+ }
+ }
+ for k := range opts.Header {
+ if strings.HasPrefix(k, ":") {
+ return fmt.Errorf("promised request headers cannot include pseudo header %q", k)
+ }
+ // These headers are meaningful only if the request has a body,
+ // but PUSH_PROMISE requests cannot have a body.
+ // http://tools.ietf.org/html/rfc7540#section-8.2
+ // Also disallow Host, since the promised URL must be absolute.
+ if http2asciiEqualFold(k, "content-length") ||
+ http2asciiEqualFold(k, "content-encoding") ||
+ http2asciiEqualFold(k, "trailer") ||
+ http2asciiEqualFold(k, "te") ||
+ http2asciiEqualFold(k, "expect") ||
+ http2asciiEqualFold(k, "host") {
+ return fmt.Errorf("promised request headers cannot include %q", k)
+ }
+ }
+ if err := http2checkValidHTTP2RequestHeaders(opts.Header); err != nil {
+ return err
+ }
+
+ // The RFC effectively limits promised requests to GET and HEAD:
+ // "Promised requests MUST be cacheable [GET, HEAD, or POST], and MUST be safe [GET or HEAD]"
+ // http://tools.ietf.org/html/rfc7540#section-8.2
+ if opts.Method != "GET" && opts.Method != "HEAD" {
+ return fmt.Errorf("method %q must be GET or HEAD", opts.Method)
+ }
+
+ msg := &http2startPushRequest{
+ parent: st,
+ method: opts.Method,
+ url: u,
+ header: http2cloneHeader(opts.Header),
+ done: http2errChanPool.Get().(chan error),
+ }
+
+ select {
+ case <-sc.doneServing:
+ return http2errClientDisconnected
+ case <-st.cw:
+ return http2errStreamClosed
+ case sc.serveMsgCh <- msg:
+ }
+
+ select {
+ case <-sc.doneServing:
+ return http2errClientDisconnected
+ case <-st.cw:
+ return http2errStreamClosed
+ case err := <-msg.done:
+ http2errChanPool.Put(msg.done)
+ return err
+ }
+}
+
+type http2startPushRequest struct {
+ parent *http2stream
+ method string
+ url *url.URL
+ header Header
+ done chan error
+}
+
+func (sc *http2serverConn) startPush(msg *http2startPushRequest) {
+ sc.serveG.check()
+
+ // http://tools.ietf.org/html/rfc7540#section-6.6.
+ // PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that
+ // is in either the "open" or "half-closed (remote)" state.
+ if msg.parent.state != http2stateOpen && msg.parent.state != http2stateHalfClosedRemote {
+ // responseWriter.Push checks that the stream is peer-initiated.
+ msg.done <- http2errStreamClosed
+ return
+ }
+
+ // http://tools.ietf.org/html/rfc7540#section-6.6.
+ if !sc.pushEnabled {
+ msg.done <- ErrNotSupported
+ return
+ }
+
+ // PUSH_PROMISE frames must be sent in increasing order by stream ID, so
+ // we allocate an ID for the promised stream lazily, when the PUSH_PROMISE
+ // is written. Once the ID is allocated, we start the request handler.
+ allocatePromisedID := func() (uint32, error) {
+ sc.serveG.check()
+
+ // Check this again, just in case. Technically, we might have received
+ // an updated SETTINGS by the time we got around to writing this frame.
+ if !sc.pushEnabled {
+ return 0, ErrNotSupported
+ }
+ // http://tools.ietf.org/html/rfc7540#section-6.5.2.
+ if sc.curPushedStreams+1 > sc.clientMaxStreams {
+ return 0, http2ErrPushLimitReached
+ }
+
+ // http://tools.ietf.org/html/rfc7540#section-5.1.1.
+ // Streams initiated by the server MUST use even-numbered identifiers.
+ // A server that is unable to establish a new stream identifier can send a GOAWAY
+ // frame so that the client is forced to open a new connection for new streams.
+ if sc.maxPushPromiseID+2 >= 1<<31 {
+ sc.startGracefulShutdownInternal()
+ return 0, http2ErrPushLimitReached
+ }
+ sc.maxPushPromiseID += 2
+ promisedID := sc.maxPushPromiseID
+
+ // http://tools.ietf.org/html/rfc7540#section-8.2.
+ // Strictly speaking, the new stream should start in "reserved (local)", then
+ // transition to "half closed (remote)" after sending the initial HEADERS, but
+ // we start in "half closed (remote)" for simplicity.
+ // See further comments at the definition of stateHalfClosedRemote.
+ promised := sc.newStream(promisedID, msg.parent.id, http2stateHalfClosedRemote)
+ rw, req, err := sc.newWriterAndRequestNoBody(promised, http2requestParam{
+ method: msg.method,
+ scheme: msg.url.Scheme,
+ authority: msg.url.Host,
+ path: msg.url.RequestURI(),
+ header: http2cloneHeader(msg.header), // clone since handler runs concurrently with writing the PUSH_PROMISE
+ })
+ if err != nil {
+ // Should not happen, since we've already validated msg.url.
+ panic(fmt.Sprintf("newWriterAndRequestNoBody(%+v): %v", msg.url, err))
+ }
+
+ go sc.runHandler(rw, req, sc.handler.ServeHTTP)
+ return promisedID, nil
+ }
+
+ sc.writeFrame(http2FrameWriteRequest{
+ write: &http2writePushPromise{
+ streamID: msg.parent.id,
+ method: msg.method,
+ url: msg.url,
+ h: msg.header,
+ allocatePromisedID: allocatePromisedID,
+ },
+ stream: msg.parent,
+ done: msg.done,
+ })
+}
+
+// foreachHeaderElement splits v according to the "#rule" construction
+// in RFC 7230 section 7 and calls fn for each non-empty element.
+func http2foreachHeaderElement(v string, fn func(string)) {
+ v = textproto.TrimString(v)
+ if v == "" {
+ return
+ }
+ if !strings.Contains(v, ",") {
+ fn(v)
+ return
+ }
+ for _, f := range strings.Split(v, ",") {
+ if f = textproto.TrimString(f); f != "" {
+ fn(f)
+ }
+ }
+}
+
+// From http://httpwg.org/specs/rfc7540.html#rfc.section.8.1.2.2
+var http2connHeaders = []string{
+ "Connection",
+ "Keep-Alive",
+ "Proxy-Connection",
+ "Transfer-Encoding",
+ "Upgrade",
+}
+
+// checkValidHTTP2RequestHeaders checks whether h is a valid HTTP/2 request,
+// per RFC 7540 Section 8.1.2.2.
+// The returned error is reported to users.
+func http2checkValidHTTP2RequestHeaders(h Header) error {
+ for _, k := range http2connHeaders {
+ if _, ok := h[k]; ok {
+ return fmt.Errorf("request header %q is not valid in HTTP/2", k)
+ }
+ }
+ te := h["Te"]
+ if len(te) > 0 && (len(te) > 1 || (te[0] != "trailers" && te[0] != "")) {
+ return errors.New(`request header "TE" may only be "trailers" in HTTP/2`)
+ }
+ return nil
+}
+
+func http2new400Handler(err error) HandlerFunc {
+ return func(w ResponseWriter, r *Request) {
+ Error(w, err.Error(), StatusBadRequest)
+ }
+}
+
+// h1ServerKeepAlivesDisabled reports whether hs has its keep-alives
+// disabled. See comments on h1ServerShutdownChan above for why
+// the code is written this way.
+func http2h1ServerKeepAlivesDisabled(hs *Server) bool {
+ var x interface{} = hs
+ type I interface {
+ doKeepAlives() bool
+ }
+ if hs, ok := x.(I); ok {
+ return !hs.doKeepAlives()
+ }
+ return false
+}
+
+func (sc *http2serverConn) countError(name string, err error) error {
+ if sc == nil || sc.srv == nil {
+ return err
+ }
+ f := sc.srv.CountError
+ if f == nil {
+ return err
+ }
+ var typ string
+ var code http2ErrCode
+ switch e := err.(type) {
+ case http2ConnectionError:
+ typ = "conn"
+ code = http2ErrCode(e)
+ case http2StreamError:
+ typ = "stream"
+ code = http2ErrCode(e.Code)
+ default:
+ return err
+ }
+ codeStr := http2errCodeName[code]
+ if codeStr == "" {
+ codeStr = strconv.Itoa(int(code))
+ }
+ f(fmt.Sprintf("%s_%s_%s", typ, codeStr, name))
+ return err
+}
+
+const (
+ // transportDefaultConnFlow is how many connection-level flow control
+ // tokens we give the server at start-up, past the default 64k.
+ http2transportDefaultConnFlow = 1 << 30
+
+ // transportDefaultStreamFlow is how many stream-level flow
+ // control tokens we announce to the peer, and how many bytes
+ // we buffer per stream.
+ http2transportDefaultStreamFlow = 4 << 20
+
+ http2defaultUserAgent = "Go-http-client/2.0"
+
+ // initialMaxConcurrentStreams is a connections maxConcurrentStreams until
+ // it's received servers initial SETTINGS frame, which corresponds with the
+ // spec's minimum recommended value.
+ http2initialMaxConcurrentStreams = 100
+
+ // defaultMaxConcurrentStreams is a connections default maxConcurrentStreams
+ // if the server doesn't include one in its initial SETTINGS frame.
+ http2defaultMaxConcurrentStreams = 1000
+)
+
+// Transport is an HTTP/2 Transport.
+//
+// A Transport internally caches connections to servers. It is safe
+// for concurrent use by multiple goroutines.
+type http2Transport struct {
+ // DialTLSContext specifies an optional dial function with context for
+ // creating TLS connections for requests.
+ //
+ // If DialTLSContext and DialTLS is nil, tls.Dial is used.
+ //
+ // If the returned net.Conn has a ConnectionState method like tls.Conn,
+ // it will be used to set http.Response.TLS.
+ DialTLSContext func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error)
+
+ // DialTLS specifies an optional dial function for creating
+ // TLS connections for requests.
+ //
+ // If DialTLSContext and DialTLS is nil, tls.Dial is used.
+ //
+ // Deprecated: Use DialTLSContext instead, which allows the transport
+ // to cancel dials as soon as they are no longer needed.
+ // If both are set, DialTLSContext takes priority.
+ DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error)
+
+ // TLSClientConfig specifies the TLS configuration to use with
+ // tls.Client. If nil, the default configuration is used.
+ TLSClientConfig *tls.Config
+
+ // ConnPool optionally specifies an alternate connection pool to use.
+ // If nil, the default is used.
+ ConnPool http2ClientConnPool
+
+ // DisableCompression, if true, prevents the Transport from
+ // requesting compression with an "Accept-Encoding: gzip"
+ // request header when the Request contains no existing
+ // Accept-Encoding value. If the Transport requests gzip on
+ // its own and gets a gzipped response, it's transparently
+ // decoded in the Response.Body. However, if the user
+ // explicitly requested gzip it is not automatically
+ // uncompressed.
+ DisableCompression bool
+
+ // AllowHTTP, if true, permits HTTP/2 requests using the insecure,
+ // plain-text "http" scheme. Note that this does not enable h2c support.
+ AllowHTTP bool
+
+ // MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to
+ // send in the initial settings frame. It is how many bytes
+ // of response headers are allowed. Unlike the http2 spec, zero here
+ // means to use a default limit (currently 10MB). If you actually
+ // want to advertise an unlimited value to the peer, Transport
+ // interprets the highest possible value here (0xffffffff or 1<<32-1)
+ // to mean no limit.
+ MaxHeaderListSize uint32
+
+ // MaxReadFrameSize is the http2 SETTINGS_MAX_FRAME_SIZE to send in the
+ // initial settings frame. It is the size in bytes of the largest frame
+ // payload that the sender is willing to receive. If 0, no setting is
+ // sent, and the value is provided by the peer, which should be 16384
+ // according to the spec:
+ // https://datatracker.ietf.org/doc/html/rfc7540#section-6.5.2.
+ // Values are bounded in the range 16k to 16M.
+ MaxReadFrameSize uint32
+
+ // MaxDecoderHeaderTableSize optionally specifies the http2
+ // SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It
+ // informs the remote endpoint of the maximum size of the header compression
+ // table used to decode header blocks, in octets. If zero, the default value
+ // of 4096 is used.
+ MaxDecoderHeaderTableSize uint32
+
+ // MaxEncoderHeaderTableSize optionally specifies an upper limit for the
+ // header compression table used for encoding request headers. Received
+ // SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero,
+ // the default value of 4096 is used.
+ MaxEncoderHeaderTableSize uint32
+
+ // StrictMaxConcurrentStreams controls whether the server's
+ // SETTINGS_MAX_CONCURRENT_STREAMS should be respected
+ // globally. If false, new TCP connections are created to the
+ // server as needed to keep each under the per-connection
+ // SETTINGS_MAX_CONCURRENT_STREAMS limit. If true, the
+ // server's SETTINGS_MAX_CONCURRENT_STREAMS is interpreted as
+ // a global limit and callers of RoundTrip block when needed,
+ // waiting for their turn.
+ StrictMaxConcurrentStreams bool
+
+ // ReadIdleTimeout is the timeout after which a health check using ping
+ // frame will be carried out if no frame is received on the connection.
+ // Note that a ping response will is considered a received frame, so if
+ // there is no other traffic on the connection, the health check will
+ // be performed every ReadIdleTimeout interval.
+ // If zero, no health check is performed.
+ ReadIdleTimeout time.Duration
+
+ // PingTimeout is the timeout after which the connection will be closed
+ // if a response to Ping is not received.
+ // Defaults to 15s.
+ PingTimeout time.Duration
+
+ // WriteByteTimeout is the timeout after which the connection will be
+ // closed no data can be written to it. The timeout begins when data is
+ // available to write, and is extended whenever any bytes are written.
+ WriteByteTimeout time.Duration
+
+ // CountError, if non-nil, is called on HTTP/2 transport errors.
+ // It's intended to increment a metric for monitoring, such
+ // as an expvar or Prometheus metric.
+ // The errType consists of only ASCII word characters.
+ CountError func(errType string)
+
+ // t1, if non-nil, is the standard library Transport using
+ // this transport. Its settings are used (but not its
+ // RoundTrip method, etc).
+ t1 *Transport
+
+ connPoolOnce sync.Once
+ connPoolOrDef http2ClientConnPool // non-nil version of ConnPool
+}
+
+func (t *http2Transport) maxHeaderListSize() uint32 {
+ if t.MaxHeaderListSize == 0 {
+ return 10 << 20
+ }
+ if t.MaxHeaderListSize == 0xffffffff {
+ return 0
+ }
+ return t.MaxHeaderListSize
+}
+
+func (t *http2Transport) maxFrameReadSize() uint32 {
+ if t.MaxReadFrameSize == 0 {
+ return 0 // use the default provided by the peer
+ }
+ if t.MaxReadFrameSize < http2minMaxFrameSize {
+ return http2minMaxFrameSize
+ }
+ if t.MaxReadFrameSize > http2maxFrameSize {
+ return http2maxFrameSize
+ }
+ return t.MaxReadFrameSize
+}
+
+func (t *http2Transport) disableCompression() bool {
+ return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)
+}
+
+func (t *http2Transport) pingTimeout() time.Duration {
+ if t.PingTimeout == 0 {
+ return 15 * time.Second
+ }
+ return t.PingTimeout
+
+}
+
+// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.
+// It returns an error if t1 has already been HTTP/2-enabled.
+//
+// Use ConfigureTransports instead to configure the HTTP/2 Transport.
+func http2ConfigureTransport(t1 *Transport) error {
+ _, err := http2ConfigureTransports(t1)
+ return err
+}
+
+// ConfigureTransports configures a net/http HTTP/1 Transport to use HTTP/2.
+// It returns a new HTTP/2 Transport for further configuration.
+// It returns an error if t1 has already been HTTP/2-enabled.
+func http2ConfigureTransports(t1 *Transport) (*http2Transport, error) {
+ return http2configureTransports(t1)
+}
+
+func http2configureTransports(t1 *Transport) (*http2Transport, error) {
+ connPool := new(http2clientConnPool)
+ t2 := &http2Transport{
+ ConnPool: http2noDialClientConnPool{connPool},
+ t1: t1,
+ }
+ connPool.t = t2
+ if err := http2registerHTTPSProtocol(t1, http2noDialH2RoundTripper{t2}); err != nil {
+ return nil, err
+ }
+ if t1.TLSClientConfig == nil {
+ t1.TLSClientConfig = new(tls.Config)
+ }
+ if !http2strSliceContains(t1.TLSClientConfig.NextProtos, "h2") {
+ t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...)
+ }
+ if !http2strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") {
+ t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1")
+ }
+ upgradeFn := func(authority string, c *tls.Conn) RoundTripper {
+ addr := http2authorityAddr("https", authority)
+ if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {
+ go c.Close()
+ return http2erringRoundTripper{err}
+ } else if !used {
+ // Turns out we don't need this c.
+ // For example, two goroutines made requests to the same host
+ // at the same time, both kicking off TCP dials. (since protocol
+ // was unknown)
+ go c.Close()
+ }
+ return t2
+ }
+ if m := t1.TLSNextProto; len(m) == 0 {
+ t1.TLSNextProto = map[string]func(string, *tls.Conn) RoundTripper{
+ "h2": upgradeFn,
+ }
+ } else {
+ m["h2"] = upgradeFn
+ }
+ return t2, nil
+}
+
+func (t *http2Transport) connPool() http2ClientConnPool {
+ t.connPoolOnce.Do(t.initConnPool)
+ return t.connPoolOrDef
+}
+
+func (t *http2Transport) initConnPool() {
+ if t.ConnPool != nil {
+ t.connPoolOrDef = t.ConnPool
+ } else {
+ t.connPoolOrDef = &http2clientConnPool{t: t}
+ }
+}
+
+// ClientConn is the state of a single HTTP/2 client connection to an
+// HTTP/2 server.
+type http2ClientConn struct {
+ t *http2Transport
+ tconn net.Conn // usually *tls.Conn, except specialized impls
+ tconnClosed bool
+ tlsState *tls.ConnectionState // nil only for specialized impls
+ reused uint32 // whether conn is being reused; atomic
+ singleUse bool // whether being used for a single http.Request
+ getConnCalled bool // used by clientConnPool
+
+ // readLoop goroutine fields:
+ readerDone chan struct{} // closed on error
+ readerErr error // set before readerDone is closed
+
+ idleTimeout time.Duration // or 0 for never
+ idleTimer *time.Timer
+
+ mu sync.Mutex // guards following
+ cond *sync.Cond // hold mu; broadcast on flow/closed changes
+ flow http2outflow // our conn-level flow control quota (cs.outflow is per stream)
+ inflow http2inflow // peer's conn-level flow control
+ doNotReuse bool // whether conn is marked to not be reused for any future requests
+ closing bool
+ closed bool
+ seenSettings bool // true if we've seen a settings frame, false otherwise
+ wantSettingsAck bool // we sent a SETTINGS frame and haven't heard back
+ goAway *http2GoAwayFrame // if non-nil, the GoAwayFrame we received
+ goAwayDebug string // goAway frame's debug data, retained as a string
+ streams map[uint32]*http2clientStream // client-initiated
+ streamsReserved int // incr by ReserveNewRequest; decr on RoundTrip
+ nextStreamID uint32
+ pendingRequests int // requests blocked and waiting to be sent because len(streams) == maxConcurrentStreams
+ pings map[[8]byte]chan struct{} // in flight ping data to notification channel
+ br *bufio.Reader
+ lastActive time.Time
+ lastIdle time.Time // time last idle
+ // Settings from peer: (also guarded by wmu)
+ maxFrameSize uint32
+ maxConcurrentStreams uint32
+ peerMaxHeaderListSize uint64
+ peerMaxHeaderTableSize uint32
+ initialWindowSize uint32
+
+ // reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests.
+ // Write to reqHeaderMu to lock it, read from it to unlock.
+ // Lock reqmu BEFORE mu or wmu.
+ reqHeaderMu chan struct{}
+
+ // wmu is held while writing.
+ // Acquire BEFORE mu when holding both, to avoid blocking mu on network writes.
+ // Only acquire both at the same time when changing peer settings.
+ wmu sync.Mutex
+ bw *bufio.Writer
+ fr *http2Framer
+ werr error // first write error that has occurred
+ hbuf bytes.Buffer // HPACK encoder writes into this
+ henc *hpack.Encoder
+}
+
+// clientStream is the state for a single HTTP/2 stream. One of these
+// is created for each Transport.RoundTrip call.
+type http2clientStream struct {
+ cc *http2ClientConn
+
+ // Fields of Request that we may access even after the response body is closed.
+ ctx context.Context
+ reqCancel <-chan struct{}
+
+ trace *httptrace.ClientTrace // or nil
+ ID uint32
+ bufPipe http2pipe // buffered pipe with the flow-controlled response payload
+ requestedGzip bool
+ isHead bool
+
+ abortOnce sync.Once
+ abort chan struct{} // closed to signal stream should end immediately
+ abortErr error // set if abort is closed
+
+ peerClosed chan struct{} // closed when the peer sends an END_STREAM flag
+ donec chan struct{} // closed after the stream is in the closed state
+ on100 chan struct{} // buffered; written to if a 100 is received
+
+ respHeaderRecv chan struct{} // closed when headers are received
+ res *Response // set if respHeaderRecv is closed
+
+ flow http2outflow // guarded by cc.mu
+ inflow http2inflow // guarded by cc.mu
+ bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read
+ readErr error // sticky read error; owned by transportResponseBody.Read
+
+ reqBody io.ReadCloser
+ reqBodyContentLength int64 // -1 means unknown
+ reqBodyClosed chan struct{} // guarded by cc.mu; non-nil on Close, closed when done
+
+ // owned by writeRequest:
+ sentEndStream bool // sent an END_STREAM flag to the peer
+ sentHeaders bool
+
+ // owned by clientConnReadLoop:
+ firstByte bool // got the first response byte
+ pastHeaders bool // got first MetaHeadersFrame (actual headers)
+ pastTrailers bool // got optional second MetaHeadersFrame (trailers)
+ num1xx uint8 // number of 1xx responses seen
+ readClosed bool // peer sent an END_STREAM flag
+ readAborted bool // read loop reset the stream
+
+ trailer Header // accumulated trailers
+ resTrailer *Header // client's Response.Trailer
+}
+
+var http2got1xxFuncForTests func(int, textproto.MIMEHeader) error
+
+// get1xxTraceFunc returns the value of request's httptrace.ClientTrace.Got1xxResponse func,
+// if any. It returns nil if not set or if the Go version is too old.
+func (cs *http2clientStream) get1xxTraceFunc() func(int, textproto.MIMEHeader) error {
+ if fn := http2got1xxFuncForTests; fn != nil {
+ return fn
+ }
+ return http2traceGot1xxResponseFunc(cs.trace)
+}
+
+func (cs *http2clientStream) abortStream(err error) {
+ cs.cc.mu.Lock()
+ defer cs.cc.mu.Unlock()
+ cs.abortStreamLocked(err)
+}
+
+func (cs *http2clientStream) abortStreamLocked(err error) {
+ cs.abortOnce.Do(func() {
+ cs.abortErr = err
+ close(cs.abort)
+ })
+ if cs.reqBody != nil {
+ cs.closeReqBodyLocked()
+ }
+ // TODO(dneil): Clean up tests where cs.cc.cond is nil.
+ if cs.cc.cond != nil {
+ // Wake up writeRequestBody if it is waiting on flow control.
+ cs.cc.cond.Broadcast()
+ }
+}
+
+func (cs *http2clientStream) abortRequestBodyWrite() {
+ cc := cs.cc
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+ if cs.reqBody != nil && cs.reqBodyClosed == nil {
+ cs.closeReqBodyLocked()
+ cc.cond.Broadcast()
+ }
+}
+
+func (cs *http2clientStream) closeReqBodyLocked() {
+ if cs.reqBodyClosed != nil {
+ return
+ }
+ cs.reqBodyClosed = make(chan struct{})
+ reqBodyClosed := cs.reqBodyClosed
+ go func() {
+ cs.reqBody.Close()
+ close(reqBodyClosed)
+ }()
+}
+
+type http2stickyErrWriter struct {
+ conn net.Conn
+ timeout time.Duration
+ err *error
+}
+
+func (sew http2stickyErrWriter) Write(p []byte) (n int, err error) {
+ if *sew.err != nil {
+ return 0, *sew.err
+ }
+ for {
+ if sew.timeout != 0 {
+ sew.conn.SetWriteDeadline(time.Now().Add(sew.timeout))
+ }
+ nn, err := sew.conn.Write(p[n:])
+ n += nn
+ if n < len(p) && nn > 0 && errors.Is(err, os.ErrDeadlineExceeded) {
+ // Keep extending the deadline so long as we're making progress.
+ continue
+ }
+ if sew.timeout != 0 {
+ sew.conn.SetWriteDeadline(time.Time{})
+ }
+ *sew.err = err
+ return n, err
+ }
+}
+
+// noCachedConnError is the concrete type of ErrNoCachedConn, which
+// needs to be detected by net/http regardless of whether it's its
+// bundled version (in h2_bundle.go with a rewritten type name) or
+// from a user's x/net/http2. As such, as it has a unique method name
+// (IsHTTP2NoCachedConnError) that net/http sniffs for via func
+// isNoCachedConnError.
+type http2noCachedConnError struct{}
+
+func (http2noCachedConnError) IsHTTP2NoCachedConnError() {}
+
+func (http2noCachedConnError) Error() string { return "http2: no cached connection was available" }
+
+// isNoCachedConnError reports whether err is of type noCachedConnError
+// or its equivalent renamed type in net/http2's h2_bundle.go. Both types
+// may coexist in the same running program.
+func http2isNoCachedConnError(err error) bool {
+ _, ok := err.(interface{ IsHTTP2NoCachedConnError() })
+ return ok
+}
+
+var http2ErrNoCachedConn error = http2noCachedConnError{}
+
+// RoundTripOpt are options for the Transport.RoundTripOpt method.
+type http2RoundTripOpt struct {
+ // OnlyCachedConn controls whether RoundTripOpt may
+ // create a new TCP connection. If set true and
+ // no cached connection is available, RoundTripOpt
+ // will return ErrNoCachedConn.
+ OnlyCachedConn bool
+}
+
+func (t *http2Transport) RoundTrip(req *Request) (*Response, error) {
+ return t.RoundTripOpt(req, http2RoundTripOpt{})
+}
+
+// authorityAddr returns a given authority (a host/IP, or host:port / ip:port)
+// and returns a host:port. The port 443 is added if needed.
+func http2authorityAddr(scheme string, authority string) (addr string) {
+ host, port, err := net.SplitHostPort(authority)
+ if err != nil { // authority didn't have a port
+ host = authority
+ port = ""
+ }
+ if port == "" { // authority's port was empty
+ port = "443"
+ if scheme == "http" {
+ port = "80"
+ }
+ }
+ if a, err := idna.ToASCII(host); err == nil {
+ host = a
+ }
+ // IPv6 address literal, without a port:
+ if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
+ return host + ":" + port
+ }
+ return net.JoinHostPort(host, port)
+}
+
+var http2retryBackoffHook func(time.Duration) *time.Timer
+
+func http2backoffNewTimer(d time.Duration) *time.Timer {
+ if http2retryBackoffHook != nil {
+ return http2retryBackoffHook(d)
+ }
+ return time.NewTimer(d)
+}
+
+// RoundTripOpt is like RoundTrip, but takes options.
+func (t *http2Transport) RoundTripOpt(req *Request, opt http2RoundTripOpt) (*Response, error) {
+ if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) {
+ return nil, errors.New("http2: unsupported scheme")
+ }
+
+ addr := http2authorityAddr(req.URL.Scheme, req.URL.Host)
+ for retry := 0; ; retry++ {
+ cc, err := t.connPool().GetClientConn(req, addr)
+ if err != nil {
+ t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err)
+ return nil, err
+ }
+ reused := !atomic.CompareAndSwapUint32(&cc.reused, 0, 1)
+ http2traceGotConn(req, cc, reused)
+ res, err := cc.RoundTrip(req)
+ if err != nil && retry <= 6 {
+ roundTripErr := err
+ if req, err = http2shouldRetryRequest(req, err); err == nil {
+ // After the first retry, do exponential backoff with 10% jitter.
+ if retry == 0 {
+ t.vlogf("RoundTrip retrying after failure: %v", roundTripErr)
+ continue
+ }
+ backoff := float64(uint(1) << (uint(retry) - 1))
+ backoff += backoff * (0.1 * mathrand.Float64())
+ d := time.Second * time.Duration(backoff)
+ timer := http2backoffNewTimer(d)
+ select {
+ case <-timer.C:
+ t.vlogf("RoundTrip retrying after failure: %v", roundTripErr)
+ continue
+ case <-req.Context().Done():
+ timer.Stop()
+ err = req.Context().Err()
+ }
+ }
+ }
+ if err != nil {
+ t.vlogf("RoundTrip failure: %v", err)
+ return nil, err
+ }
+ return res, nil
+ }
+}
+
+// CloseIdleConnections closes any connections which were previously
+// connected from previous requests but are now sitting idle.
+// It does not interrupt any connections currently in use.
+func (t *http2Transport) CloseIdleConnections() {
+ if cp, ok := t.connPool().(http2clientConnPoolIdleCloser); ok {
+ cp.closeIdleConnections()
+ }
+}
+
+var (
+ http2errClientConnClosed = errors.New("http2: client conn is closed")
+ http2errClientConnUnusable = errors.New("http2: client conn not usable")
+ http2errClientConnGotGoAway = errors.New("http2: Transport received Server's graceful shutdown GOAWAY")
+)
+
+// shouldRetryRequest is called by RoundTrip when a request fails to get
+// response headers. It is always called with a non-nil error.
+// It returns either a request to retry (either the same request, or a
+// modified clone), or an error if the request can't be replayed.
+func http2shouldRetryRequest(req *Request, err error) (*Request, error) {
+ if !http2canRetryError(err) {
+ return nil, err
+ }
+ // If the Body is nil (or http.NoBody), it's safe to reuse
+ // this request and its Body.
+ if req.Body == nil || req.Body == NoBody {
+ return req, nil
+ }
+
+ // If the request body can be reset back to its original
+ // state via the optional req.GetBody, do that.
+ if req.GetBody != nil {
+ body, err := req.GetBody()
+ if err != nil {
+ return nil, err
+ }
+ newReq := *req
+ newReq.Body = body
+ return &newReq, nil
+ }
+
+ // The Request.Body can't reset back to the beginning, but we
+ // don't seem to have started to read from it yet, so reuse
+ // the request directly.
+ if err == http2errClientConnUnusable {
+ return req, nil
+ }
+
+ return nil, fmt.Errorf("http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error", err)
+}
+
+func http2canRetryError(err error) bool {
+ if err == http2errClientConnUnusable || err == http2errClientConnGotGoAway {
+ return true
+ }
+ if se, ok := err.(http2StreamError); ok {
+ if se.Code == http2ErrCodeProtocol && se.Cause == http2errFromPeer {
+ // See golang/go#47635, golang/go#42777
+ return true
+ }
+ return se.Code == http2ErrCodeRefusedStream
+ }
+ return false
+}
+
+func (t *http2Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*http2ClientConn, error) {
+ host, _, err := net.SplitHostPort(addr)
+ if err != nil {
+ return nil, err
+ }
+ tconn, err := t.dialTLS(ctx, "tcp", addr, t.newTLSConfig(host))
+ if err != nil {
+ return nil, err
+ }
+ return t.newClientConn(tconn, singleUse)
+}
+
+func (t *http2Transport) newTLSConfig(host string) *tls.Config {
+ cfg := new(tls.Config)
+ if t.TLSClientConfig != nil {
+ *cfg = *t.TLSClientConfig.Clone()
+ }
+ if !http2strSliceContains(cfg.NextProtos, http2NextProtoTLS) {
+ cfg.NextProtos = append([]string{http2NextProtoTLS}, cfg.NextProtos...)
+ }
+ if cfg.ServerName == "" {
+ cfg.ServerName = host
+ }
+ return cfg
+}
+
+func (t *http2Transport) dialTLS(ctx context.Context, network, addr string, tlsCfg *tls.Config) (net.Conn, error) {
+ if t.DialTLSContext != nil {
+ return t.DialTLSContext(ctx, network, addr, tlsCfg)
+ } else if t.DialTLS != nil {
+ return t.DialTLS(network, addr, tlsCfg)
+ }
+
+ tlsCn, err := t.dialTLSWithContext(ctx, network, addr, tlsCfg)
+ if err != nil {
+ return nil, err
+ }
+ state := tlsCn.ConnectionState()
+ if p := state.NegotiatedProtocol; p != http2NextProtoTLS {
+ return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, http2NextProtoTLS)
+ }
+ if !state.NegotiatedProtocolIsMutual {
+ return nil, errors.New("http2: could not negotiate protocol mutually")
+ }
+ return tlsCn, nil
+}
+
+// disableKeepAlives reports whether connections should be closed as
+// soon as possible after handling the first request.
+func (t *http2Transport) disableKeepAlives() bool {
+ return t.t1 != nil && t.t1.DisableKeepAlives
+}
+
+func (t *http2Transport) expectContinueTimeout() time.Duration {
+ if t.t1 == nil {
+ return 0
+ }
+ return t.t1.ExpectContinueTimeout
+}
+
+func (t *http2Transport) maxDecoderHeaderTableSize() uint32 {
+ if v := t.MaxDecoderHeaderTableSize; v > 0 {
+ return v
+ }
+ return http2initialHeaderTableSize
+}
+
+func (t *http2Transport) maxEncoderHeaderTableSize() uint32 {
+ if v := t.MaxEncoderHeaderTableSize; v > 0 {
+ return v
+ }
+ return http2initialHeaderTableSize
+}
+
+func (t *http2Transport) NewClientConn(c net.Conn) (*http2ClientConn, error) {
+ return t.newClientConn(c, t.disableKeepAlives())
+}
+
+func (t *http2Transport) newClientConn(c net.Conn, singleUse bool) (*http2ClientConn, error) {
+ cc := &http2ClientConn{
+ t: t,
+ tconn: c,
+ readerDone: make(chan struct{}),
+ nextStreamID: 1,
+ maxFrameSize: 16 << 10, // spec default
+ initialWindowSize: 65535, // spec default
+ maxConcurrentStreams: http2initialMaxConcurrentStreams, // "infinite", per spec. Use a smaller value until we have received server settings.
+ peerMaxHeaderListSize: 0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead.
+ streams: make(map[uint32]*http2clientStream),
+ singleUse: singleUse,
+ wantSettingsAck: true,
+ pings: make(map[[8]byte]chan struct{}),
+ reqHeaderMu: make(chan struct{}, 1),
+ }
+ if d := t.idleConnTimeout(); d != 0 {
+ cc.idleTimeout = d
+ cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout)
+ }
+ if http2VerboseLogs {
+ t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr())
+ }
+
+ cc.cond = sync.NewCond(&cc.mu)
+ cc.flow.add(int32(http2initialWindowSize))
+
+ // TODO: adjust this writer size to account for frame size +
+ // MTU + crypto/tls record padding.
+ cc.bw = bufio.NewWriter(http2stickyErrWriter{
+ conn: c,
+ timeout: t.WriteByteTimeout,
+ err: &cc.werr,
+ })
+ cc.br = bufio.NewReader(c)
+ cc.fr = http2NewFramer(cc.bw, cc.br)
+ if t.maxFrameReadSize() != 0 {
+ cc.fr.SetMaxReadFrameSize(t.maxFrameReadSize())
+ }
+ if t.CountError != nil {
+ cc.fr.countError = t.CountError
+ }
+ maxHeaderTableSize := t.maxDecoderHeaderTableSize()
+ cc.fr.ReadMetaHeaders = hpack.NewDecoder(maxHeaderTableSize, nil)
+ cc.fr.MaxHeaderListSize = t.maxHeaderListSize()
+
+ cc.henc = hpack.NewEncoder(&cc.hbuf)
+ cc.henc.SetMaxDynamicTableSizeLimit(t.maxEncoderHeaderTableSize())
+ cc.peerMaxHeaderTableSize = http2initialHeaderTableSize
+
+ if t.AllowHTTP {
+ cc.nextStreamID = 3
+ }
+
+ if cs, ok := c.(http2connectionStater); ok {
+ state := cs.ConnectionState()
+ cc.tlsState = &state
+ }
+
+ initialSettings := []http2Setting{
+ {ID: http2SettingEnablePush, Val: 0},
+ {ID: http2SettingInitialWindowSize, Val: http2transportDefaultStreamFlow},
+ }
+ if max := t.maxFrameReadSize(); max != 0 {
+ initialSettings = append(initialSettings, http2Setting{ID: http2SettingMaxFrameSize, Val: max})
+ }
+ if max := t.maxHeaderListSize(); max != 0 {
+ initialSettings = append(initialSettings, http2Setting{ID: http2SettingMaxHeaderListSize, Val: max})
+ }
+ if maxHeaderTableSize != http2initialHeaderTableSize {
+ initialSettings = append(initialSettings, http2Setting{ID: http2SettingHeaderTableSize, Val: maxHeaderTableSize})
+ }
+
+ cc.bw.Write(http2clientPreface)
+ cc.fr.WriteSettings(initialSettings...)
+ cc.fr.WriteWindowUpdate(0, http2transportDefaultConnFlow)
+ cc.inflow.init(http2transportDefaultConnFlow + http2initialWindowSize)
+ cc.bw.Flush()
+ if cc.werr != nil {
+ cc.Close()
+ return nil, cc.werr
+ }
+
+ go cc.readLoop()
+ return cc, nil
+}
+
+func (cc *http2ClientConn) healthCheck() {
+ pingTimeout := cc.t.pingTimeout()
+ // We don't need to periodically ping in the health check, because the readLoop of ClientConn will
+ // trigger the healthCheck again if there is no frame received.
+ ctx, cancel := context.WithTimeout(context.Background(), pingTimeout)
+ defer cancel()
+ cc.vlogf("http2: Transport sending health check")
+ err := cc.Ping(ctx)
+ if err != nil {
+ cc.vlogf("http2: Transport health check failure: %v", err)
+ cc.closeForLostPing()
+ } else {
+ cc.vlogf("http2: Transport health check success")
+ }
+}
+
+// SetDoNotReuse marks cc as not reusable for future HTTP requests.
+func (cc *http2ClientConn) SetDoNotReuse() {
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+ cc.doNotReuse = true
+}
+
+func (cc *http2ClientConn) setGoAway(f *http2GoAwayFrame) {
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+
+ old := cc.goAway
+ cc.goAway = f
+
+ // Merge the previous and current GoAway error frames.
+ if cc.goAwayDebug == "" {
+ cc.goAwayDebug = string(f.DebugData())
+ }
+ if old != nil && old.ErrCode != http2ErrCodeNo {
+ cc.goAway.ErrCode = old.ErrCode
+ }
+ last := f.LastStreamID
+ for streamID, cs := range cc.streams {
+ if streamID > last {
+ cs.abortStreamLocked(http2errClientConnGotGoAway)
+ }
+ }
+}
+
+// CanTakeNewRequest reports whether the connection can take a new request,
+// meaning it has not been closed or received or sent a GOAWAY.
+//
+// If the caller is going to immediately make a new request on this
+// connection, use ReserveNewRequest instead.
+func (cc *http2ClientConn) CanTakeNewRequest() bool {
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+ return cc.canTakeNewRequestLocked()
+}
+
+// ReserveNewRequest is like CanTakeNewRequest but also reserves a
+// concurrent stream in cc. The reservation is decremented on the
+// next call to RoundTrip.
+func (cc *http2ClientConn) ReserveNewRequest() bool {
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+ if st := cc.idleStateLocked(); !st.canTakeNewRequest {
+ return false
+ }
+ cc.streamsReserved++
+ return true
+}
+
+// ClientConnState describes the state of a ClientConn.
+type http2ClientConnState struct {
+ // Closed is whether the connection is closed.
+ Closed bool
+
+ // Closing is whether the connection is in the process of
+ // closing. It may be closing due to shutdown, being a
+ // single-use connection, being marked as DoNotReuse, or
+ // having received a GOAWAY frame.
+ Closing bool
+
+ // StreamsActive is how many streams are active.
+ StreamsActive int
+
+ // StreamsReserved is how many streams have been reserved via
+ // ClientConn.ReserveNewRequest.
+ StreamsReserved int
+
+ // StreamsPending is how many requests have been sent in excess
+ // of the peer's advertised MaxConcurrentStreams setting and
+ // are waiting for other streams to complete.
+ StreamsPending int
+
+ // MaxConcurrentStreams is how many concurrent streams the
+ // peer advertised as acceptable. Zero means no SETTINGS
+ // frame has been received yet.
+ MaxConcurrentStreams uint32
+
+ // LastIdle, if non-zero, is when the connection last
+ // transitioned to idle state.
+ LastIdle time.Time
+}
+
+// State returns a snapshot of cc's state.
+func (cc *http2ClientConn) State() http2ClientConnState {
+ cc.wmu.Lock()
+ maxConcurrent := cc.maxConcurrentStreams
+ if !cc.seenSettings {
+ maxConcurrent = 0
+ }
+ cc.wmu.Unlock()
+
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+ return http2ClientConnState{
+ Closed: cc.closed,
+ Closing: cc.closing || cc.singleUse || cc.doNotReuse || cc.goAway != nil,
+ StreamsActive: len(cc.streams),
+ StreamsReserved: cc.streamsReserved,
+ StreamsPending: cc.pendingRequests,
+ LastIdle: cc.lastIdle,
+ MaxConcurrentStreams: maxConcurrent,
+ }
+}
+
+// clientConnIdleState describes the suitability of a client
+// connection to initiate a new RoundTrip request.
+type http2clientConnIdleState struct {
+ canTakeNewRequest bool
+}
+
+func (cc *http2ClientConn) idleState() http2clientConnIdleState {
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+ return cc.idleStateLocked()
+}
+
+func (cc *http2ClientConn) idleStateLocked() (st http2clientConnIdleState) {
+ if cc.singleUse && cc.nextStreamID > 1 {
+ return
+ }
+ var maxConcurrentOkay bool
+ if cc.t.StrictMaxConcurrentStreams {
+ // We'll tell the caller we can take a new request to
+ // prevent the caller from dialing a new TCP
+ // connection, but then we'll block later before
+ // writing it.
+ maxConcurrentOkay = true
+ } else {
+ maxConcurrentOkay = int64(len(cc.streams)+cc.streamsReserved+1) <= int64(cc.maxConcurrentStreams)
+ }
+
+ st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay &&
+ !cc.doNotReuse &&
+ int64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 &&
+ !cc.tooIdleLocked()
+ return
+}
+
+func (cc *http2ClientConn) canTakeNewRequestLocked() bool {
+ st := cc.idleStateLocked()
+ return st.canTakeNewRequest
+}
+
+// tooIdleLocked reports whether this connection has been been sitting idle
+// for too much wall time.
+func (cc *http2ClientConn) tooIdleLocked() bool {
+ // The Round(0) strips the monontonic clock reading so the
+ // times are compared based on their wall time. We don't want
+ // to reuse a connection that's been sitting idle during
+ // VM/laptop suspend if monotonic time was also frozen.
+ return cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && time.Since(cc.lastIdle.Round(0)) > cc.idleTimeout
+}
+
+// onIdleTimeout is called from a time.AfterFunc goroutine. It will
+// only be called when we're idle, but because we're coming from a new
+// goroutine, there could be a new request coming in at the same time,
+// so this simply calls the synchronized closeIfIdle to shut down this
+// connection. The timer could just call closeIfIdle, but this is more
+// clear.
+func (cc *http2ClientConn) onIdleTimeout() {
+ cc.closeIfIdle()
+}
+
+func (cc *http2ClientConn) closeConn() {
+ t := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn)
+ defer t.Stop()
+ cc.tconn.Close()
+}
+
+// A tls.Conn.Close can hang for a long time if the peer is unresponsive.
+// Try to shut it down more aggressively.
+func (cc *http2ClientConn) forceCloseConn() {
+ tc, ok := cc.tconn.(*tls.Conn)
+ if !ok {
+ return
+ }
+ if nc := http2tlsUnderlyingConn(tc); nc != nil {
+ nc.Close()
+ }
+}
+
+func (cc *http2ClientConn) closeIfIdle() {
+ cc.mu.Lock()
+ if len(cc.streams) > 0 || cc.streamsReserved > 0 {
+ cc.mu.Unlock()
+ return
+ }
+ cc.closed = true
+ nextID := cc.nextStreamID
+ // TODO: do clients send GOAWAY too? maybe? Just Close:
+ cc.mu.Unlock()
+
+ if http2VerboseLogs {
+ cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, nextID-2)
+ }
+ cc.closeConn()
+}
+
+func (cc *http2ClientConn) isDoNotReuseAndIdle() bool {
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+ return cc.doNotReuse && len(cc.streams) == 0
+}
+
+var http2shutdownEnterWaitStateHook = func() {}
+
+// Shutdown gracefully closes the client connection, waiting for running streams to complete.
+func (cc *http2ClientConn) Shutdown(ctx context.Context) error {
+ if err := cc.sendGoAway(); err != nil {
+ return err
+ }
+ // Wait for all in-flight streams to complete or connection to close
+ done := make(chan struct{})
+ cancelled := false // guarded by cc.mu
+ go func() {
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+ for {
+ if len(cc.streams) == 0 || cc.closed {
+ cc.closed = true
+ close(done)
+ break
+ }
+ if cancelled {
+ break
+ }
+ cc.cond.Wait()
+ }
+ }()
+ http2shutdownEnterWaitStateHook()
+ select {
+ case <-done:
+ cc.closeConn()
+ return nil
+ case <-ctx.Done():
+ cc.mu.Lock()
+ // Free the goroutine above
+ cancelled = true
+ cc.cond.Broadcast()
+ cc.mu.Unlock()
+ return ctx.Err()
+ }
+}
+
+func (cc *http2ClientConn) sendGoAway() error {
+ cc.mu.Lock()
+ closing := cc.closing
+ cc.closing = true
+ maxStreamID := cc.nextStreamID
+ cc.mu.Unlock()
+ if closing {
+ // GOAWAY sent already
+ return nil
+ }
+
+ cc.wmu.Lock()
+ defer cc.wmu.Unlock()
+ // Send a graceful shutdown frame to server
+ if err := cc.fr.WriteGoAway(maxStreamID, http2ErrCodeNo, nil); err != nil {
+ return err
+ }
+ if err := cc.bw.Flush(); err != nil {
+ return err
+ }
+ // Prevent new requests
+ return nil
+}
+
+// closes the client connection immediately. In-flight requests are interrupted.
+// err is sent to streams.
+func (cc *http2ClientConn) closeForError(err error) {
+ cc.mu.Lock()
+ cc.closed = true
+ for _, cs := range cc.streams {
+ cs.abortStreamLocked(err)
+ }
+ cc.cond.Broadcast()
+ cc.mu.Unlock()
+ cc.closeConn()
+}
+
+// Close closes the client connection immediately.
+//
+// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.
+func (cc *http2ClientConn) Close() error {
+ err := errors.New("http2: client connection force closed via ClientConn.Close")
+ cc.closeForError(err)
+ return nil
+}
+
+// closes the client connection immediately. In-flight requests are interrupted.
+func (cc *http2ClientConn) closeForLostPing() {
+ err := errors.New("http2: client connection lost")
+ if f := cc.t.CountError; f != nil {
+ f("conn_close_lost_ping")
+ }
+ cc.closeForError(err)
+}
+
+// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not
+// exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests.
+var http2errRequestCanceled = errors.New("net/http: request canceled")
+
+func http2commaSeparatedTrailers(req *Request) (string, error) {
+ keys := make([]string, 0, len(req.Trailer))
+ for k := range req.Trailer {
+ k = http2canonicalHeader(k)
+ switch k {
+ case "Transfer-Encoding", "Trailer", "Content-Length":
+ return "", fmt.Errorf("invalid Trailer key %q", k)
+ }
+ keys = append(keys, k)
+ }
+ if len(keys) > 0 {
+ sort.Strings(keys)
+ return strings.Join(keys, ","), nil
+ }
+ return "", nil
+}
+
+func (cc *http2ClientConn) responseHeaderTimeout() time.Duration {
+ if cc.t.t1 != nil {
+ return cc.t.t1.ResponseHeaderTimeout
+ }
+ // No way to do this (yet?) with just an http2.Transport. Probably
+ // no need. Request.Cancel this is the new way. We only need to support
+ // this for compatibility with the old http.Transport fields when
+ // we're doing transparent http2.
+ return 0
+}
+
+// checkConnHeaders checks whether req has any invalid connection-level headers.
+// per RFC 7540 section 8.1.2.2: Connection-Specific Header Fields.
+// Certain headers are special-cased as okay but not transmitted later.
+func http2checkConnHeaders(req *Request) error {
+ if v := req.Header.Get("Upgrade"); v != "" {
+ return fmt.Errorf("http2: invalid Upgrade request header: %q", req.Header["Upgrade"])
+ }
+ if vv := req.Header["Transfer-Encoding"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && vv[0] != "chunked") {
+ return fmt.Errorf("http2: invalid Transfer-Encoding request header: %q", vv)
+ }
+ if vv := req.Header["Connection"]; len(vv) > 0 && (len(vv) > 1 || vv[0] != "" && !http2asciiEqualFold(vv[0], "close") && !http2asciiEqualFold(vv[0], "keep-alive")) {
+ return fmt.Errorf("http2: invalid Connection request header: %q", vv)
+ }
+ return nil
+}
+
+// actualContentLength returns a sanitized version of
+// req.ContentLength, where 0 actually means zero (not unknown) and -1
+// means unknown.
+func http2actualContentLength(req *Request) int64 {
+ if req.Body == nil || req.Body == NoBody {
+ return 0
+ }
+ if req.ContentLength != 0 {
+ return req.ContentLength
+ }
+ return -1
+}
+
+func (cc *http2ClientConn) decrStreamReservations() {
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+ cc.decrStreamReservationsLocked()
+}
+
+func (cc *http2ClientConn) decrStreamReservationsLocked() {
+ if cc.streamsReserved > 0 {
+ cc.streamsReserved--
+ }
+}
+
+func (cc *http2ClientConn) RoundTrip(req *Request) (*Response, error) {
+ ctx := req.Context()
+ cs := &http2clientStream{
+ cc: cc,
+ ctx: ctx,
+ reqCancel: req.Cancel,
+ isHead: req.Method == "HEAD",
+ reqBody: req.Body,
+ reqBodyContentLength: http2actualContentLength(req),
+ trace: httptrace.ContextClientTrace(ctx),
+ peerClosed: make(chan struct{}),
+ abort: make(chan struct{}),
+ respHeaderRecv: make(chan struct{}),
+ donec: make(chan struct{}),
+ }
+ go cs.doRequest(req)
+
+ waitDone := func() error {
+ select {
+ case <-cs.donec:
+ return nil
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-cs.reqCancel:
+ return http2errRequestCanceled
+ }
+ }
+
+ handleResponseHeaders := func() (*Response, error) {
+ res := cs.res
+ if res.StatusCode > 299 {
+ // On error or status code 3xx, 4xx, 5xx, etc abort any
+ // ongoing write, assuming that the server doesn't care
+ // about our request body. If the server replied with 1xx or
+ // 2xx, however, then assume the server DOES potentially
+ // want our body (e.g. full-duplex streaming:
+ // golang.org/issue/13444). If it turns out the server
+ // doesn't, they'll RST_STREAM us soon enough. This is a
+ // heuristic to avoid adding knobs to Transport. Hopefully
+ // we can keep it.
+ cs.abortRequestBodyWrite()
+ }
+ res.Request = req
+ res.TLS = cc.tlsState
+ if res.Body == http2noBody && http2actualContentLength(req) == 0 {
+ // If there isn't a request or response body still being
+ // written, then wait for the stream to be closed before
+ // RoundTrip returns.
+ if err := waitDone(); err != nil {
+ return nil, err
+ }
+ }
+ return res, nil
+ }
+
+ cancelRequest := func(cs *http2clientStream, err error) error {
+ cs.cc.mu.Lock()
+ bodyClosed := cs.reqBodyClosed
+ cs.cc.mu.Unlock()
+ // Wait for the request body to be closed.
+ //
+ // If nothing closed the body before now, abortStreamLocked
+ // will have started a goroutine to close it.
+ //
+ // Closing the body before returning avoids a race condition
+ // with net/http checking its readTrackingBody to see if the
+ // body was read from or closed. See golang/go#60041.
+ //
+ // The body is closed in a separate goroutine without the
+ // connection mutex held, but dropping the mutex before waiting
+ // will keep us from holding it indefinitely if the body
+ // close is slow for some reason.
+ if bodyClosed != nil {
+ <-bodyClosed
+ }
+ return err
+ }
+
+ for {
+ select {
+ case <-cs.respHeaderRecv:
+ return handleResponseHeaders()
+ case <-cs.abort:
+ select {
+ case <-cs.respHeaderRecv:
+ // If both cs.respHeaderRecv and cs.abort are signaling,
+ // pick respHeaderRecv. The server probably wrote the
+ // response and immediately reset the stream.
+ // golang.org/issue/49645
+ return handleResponseHeaders()
+ default:
+ waitDone()
+ return nil, cs.abortErr
+ }
+ case <-ctx.Done():
+ err := ctx.Err()
+ cs.abortStream(err)
+ return nil, cancelRequest(cs, err)
+ case <-cs.reqCancel:
+ cs.abortStream(http2errRequestCanceled)
+ return nil, cancelRequest(cs, http2errRequestCanceled)
+ }
+ }
+}
+
+// doRequest runs for the duration of the request lifetime.
+//
+// It sends the request and performs post-request cleanup (closing Request.Body, etc.).
+func (cs *http2clientStream) doRequest(req *Request) {
+ err := cs.writeRequest(req)
+ cs.cleanupWriteRequest(err)
+}
+
+// writeRequest sends a request.
+//
+// It returns nil after the request is written, the response read,
+// and the request stream is half-closed by the peer.
+//
+// It returns non-nil if the request ends otherwise.
+// If the returned error is StreamError, the error Code may be used in resetting the stream.
+func (cs *http2clientStream) writeRequest(req *Request) (err error) {
+ cc := cs.cc
+ ctx := cs.ctx
+
+ if err := http2checkConnHeaders(req); err != nil {
+ return err
+ }
+
+ // Acquire the new-request lock by writing to reqHeaderMu.
+ // This lock guards the critical section covering allocating a new stream ID
+ // (requires mu) and creating the stream (requires wmu).
+ if cc.reqHeaderMu == nil {
+ panic("RoundTrip on uninitialized ClientConn") // for tests
+ }
+ select {
+ case cc.reqHeaderMu <- struct{}{}:
+ case <-cs.reqCancel:
+ return http2errRequestCanceled
+ case <-ctx.Done():
+ return ctx.Err()
+ }
+
+ cc.mu.Lock()
+ if cc.idleTimer != nil {
+ cc.idleTimer.Stop()
+ }
+ cc.decrStreamReservationsLocked()
+ if err := cc.awaitOpenSlotForStreamLocked(cs); err != nil {
+ cc.mu.Unlock()
+ <-cc.reqHeaderMu
+ return err
+ }
+ cc.addStreamLocked(cs) // assigns stream ID
+ if http2isConnectionCloseRequest(req) {
+ cc.doNotReuse = true
+ }
+ cc.mu.Unlock()
+
+ // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
+ if !cc.t.disableCompression() &&
+ req.Header.Get("Accept-Encoding") == "" &&
+ req.Header.Get("Range") == "" &&
+ !cs.isHead {
+ // Request gzip only, not deflate. Deflate is ambiguous and
+ // not as universally supported anyway.
+ // See: https://zlib.net/zlib_faq.html#faq39
+ //
+ // Note that we don't request this for HEAD requests,
+ // due to a bug in nginx:
+ // http://trac.nginx.org/nginx/ticket/358
+ // https://golang.org/issue/5522
+ //
+ // We don't request gzip if the request is for a range, since
+ // auto-decoding a portion of a gzipped document will just fail
+ // anyway. See https://golang.org/issue/8923
+ cs.requestedGzip = true
+ }
+
+ continueTimeout := cc.t.expectContinueTimeout()
+ if continueTimeout != 0 {
+ if !httpguts.HeaderValuesContainsToken(req.Header["Expect"], "100-continue") {
+ continueTimeout = 0
+ } else {
+ cs.on100 = make(chan struct{}, 1)
+ }
+ }
+
+ // Past this point (where we send request headers), it is possible for
+ // RoundTrip to return successfully. Since the RoundTrip contract permits
+ // the caller to "mutate or reuse" the Request after closing the Response's Body,
+ // we must take care when referencing the Request from here on.
+ err = cs.encodeAndWriteHeaders(req)
+ <-cc.reqHeaderMu
+ if err != nil {
+ return err
+ }
+
+ hasBody := cs.reqBodyContentLength != 0
+ if !hasBody {
+ cs.sentEndStream = true
+ } else {
+ if continueTimeout != 0 {
+ http2traceWait100Continue(cs.trace)
+ timer := time.NewTimer(continueTimeout)
+ select {
+ case <-timer.C:
+ err = nil
+ case <-cs.on100:
+ err = nil
+ case <-cs.abort:
+ err = cs.abortErr
+ case <-ctx.Done():
+ err = ctx.Err()
+ case <-cs.reqCancel:
+ err = http2errRequestCanceled
+ }
+ timer.Stop()
+ if err != nil {
+ http2traceWroteRequest(cs.trace, err)
+ return err
+ }
+ }
+
+ if err = cs.writeRequestBody(req); err != nil {
+ if err != http2errStopReqBodyWrite {
+ http2traceWroteRequest(cs.trace, err)
+ return err
+ }
+ } else {
+ cs.sentEndStream = true
+ }
+ }
+
+ http2traceWroteRequest(cs.trace, err)
+
+ var respHeaderTimer <-chan time.Time
+ var respHeaderRecv chan struct{}
+ if d := cc.responseHeaderTimeout(); d != 0 {
+ timer := time.NewTimer(d)
+ defer timer.Stop()
+ respHeaderTimer = timer.C
+ respHeaderRecv = cs.respHeaderRecv
+ }
+ // Wait until the peer half-closes its end of the stream,
+ // or until the request is aborted (via context, error, or otherwise),
+ // whichever comes first.
+ for {
+ select {
+ case <-cs.peerClosed:
+ return nil
+ case <-respHeaderTimer:
+ return http2errTimeout
+ case <-respHeaderRecv:
+ respHeaderRecv = nil
+ respHeaderTimer = nil // keep waiting for END_STREAM
+ case <-cs.abort:
+ return cs.abortErr
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-cs.reqCancel:
+ return http2errRequestCanceled
+ }
+ }
+}
+
+func (cs *http2clientStream) encodeAndWriteHeaders(req *Request) error {
+ cc := cs.cc
+ ctx := cs.ctx
+
+ cc.wmu.Lock()
+ defer cc.wmu.Unlock()
+
+ // If the request was canceled while waiting for cc.mu, just quit.
+ select {
+ case <-cs.abort:
+ return cs.abortErr
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-cs.reqCancel:
+ return http2errRequestCanceled
+ default:
+ }
+
+ // Encode headers.
+ //
+ // we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is
+ // sent by writeRequestBody below, along with any Trailers,
+ // again in form HEADERS{1}, CONTINUATION{0,})
+ trailers, err := http2commaSeparatedTrailers(req)
+ if err != nil {
+ return err
+ }
+ hasTrailers := trailers != ""
+ contentLen := http2actualContentLength(req)
+ hasBody := contentLen != 0
+ hdrs, err := cc.encodeHeaders(req, cs.requestedGzip, trailers, contentLen)
+ if err != nil {
+ return err
+ }
+
+ // Write the request.
+ endStream := !hasBody && !hasTrailers
+ cs.sentHeaders = true
+ err = cc.writeHeaders(cs.ID, endStream, int(cc.maxFrameSize), hdrs)
+ http2traceWroteHeaders(cs.trace)
+ return err
+}
+
+// cleanupWriteRequest performs post-request tasks.
+//
+// If err (the result of writeRequest) is non-nil and the stream is not closed,
+// cleanupWriteRequest will send a reset to the peer.
+func (cs *http2clientStream) cleanupWriteRequest(err error) {
+ cc := cs.cc
+
+ if cs.ID == 0 {
+ // We were canceled before creating the stream, so return our reservation.
+ cc.decrStreamReservations()
+ }
+
+ // TODO: write h12Compare test showing whether
+ // Request.Body is closed by the Transport,
+ // and in multiple cases: server replies <=299 and >299
+ // while still writing request body
+ cc.mu.Lock()
+ mustCloseBody := false
+ if cs.reqBody != nil && cs.reqBodyClosed == nil {
+ mustCloseBody = true
+ cs.reqBodyClosed = make(chan struct{})
+ }
+ bodyClosed := cs.reqBodyClosed
+ cc.mu.Unlock()
+ if mustCloseBody {
+ cs.reqBody.Close()
+ close(bodyClosed)
+ }
+ if bodyClosed != nil {
+ <-bodyClosed
+ }
+
+ if err != nil && cs.sentEndStream {
+ // If the connection is closed immediately after the response is read,
+ // we may be aborted before finishing up here. If the stream was closed
+ // cleanly on both sides, there is no error.
+ select {
+ case <-cs.peerClosed:
+ err = nil
+ default:
+ }
+ }
+ if err != nil {
+ cs.abortStream(err) // possibly redundant, but harmless
+ if cs.sentHeaders {
+ if se, ok := err.(http2StreamError); ok {
+ if se.Cause != http2errFromPeer {
+ cc.writeStreamReset(cs.ID, se.Code, err)
+ }
+ } else {
+ cc.writeStreamReset(cs.ID, http2ErrCodeCancel, err)
+ }
+ }
+ cs.bufPipe.CloseWithError(err) // no-op if already closed
+ } else {
+ if cs.sentHeaders && !cs.sentEndStream {
+ cc.writeStreamReset(cs.ID, http2ErrCodeNo, nil)
+ }
+ cs.bufPipe.CloseWithError(http2errRequestCanceled)
+ }
+ if cs.ID != 0 {
+ cc.forgetStreamID(cs.ID)
+ }
+
+ cc.wmu.Lock()
+ werr := cc.werr
+ cc.wmu.Unlock()
+ if werr != nil {
+ cc.Close()
+ }
+
+ close(cs.donec)
+}
+
+// awaitOpenSlotForStreamLocked waits until len(streams) < maxConcurrentStreams.
+// Must hold cc.mu.
+func (cc *http2ClientConn) awaitOpenSlotForStreamLocked(cs *http2clientStream) error {
+ for {
+ cc.lastActive = time.Now()
+ if cc.closed || !cc.canTakeNewRequestLocked() {
+ return http2errClientConnUnusable
+ }
+ cc.lastIdle = time.Time{}
+ if int64(len(cc.streams)) < int64(cc.maxConcurrentStreams) {
+ return nil
+ }
+ cc.pendingRequests++
+ cc.cond.Wait()
+ cc.pendingRequests--
+ select {
+ case <-cs.abort:
+ return cs.abortErr
+ default:
+ }
+ }
+}
+
+// requires cc.wmu be held
+func (cc *http2ClientConn) writeHeaders(streamID uint32, endStream bool, maxFrameSize int, hdrs []byte) error {
+ first := true // first frame written (HEADERS is first, then CONTINUATION)
+ for len(hdrs) > 0 && cc.werr == nil {
+ chunk := hdrs
+ if len(chunk) > maxFrameSize {
+ chunk = chunk[:maxFrameSize]
+ }
+ hdrs = hdrs[len(chunk):]
+ endHeaders := len(hdrs) == 0
+ if first {
+ cc.fr.WriteHeaders(http2HeadersFrameParam{
+ StreamID: streamID,
+ BlockFragment: chunk,
+ EndStream: endStream,
+ EndHeaders: endHeaders,
+ })
+ first = false
+ } else {
+ cc.fr.WriteContinuation(streamID, endHeaders, chunk)
+ }
+ }
+ cc.bw.Flush()
+ return cc.werr
+}
+
+// internal error values; they don't escape to callers
+var (
+ // abort request body write; don't send cancel
+ http2errStopReqBodyWrite = errors.New("http2: aborting request body write")
+
+ // abort request body write, but send stream reset of cancel.
+ http2errStopReqBodyWriteAndCancel = errors.New("http2: canceling request")
+
+ http2errReqBodyTooLong = errors.New("http2: request body larger than specified content length")
+)
+
+// frameScratchBufferLen returns the length of a buffer to use for
+// outgoing request bodies to read/write to/from.
+//
+// It returns max(1, min(peer's advertised max frame size,
+// Request.ContentLength+1, 512KB)).
+func (cs *http2clientStream) frameScratchBufferLen(maxFrameSize int) int {
+ const max = 512 << 10
+ n := int64(maxFrameSize)
+ if n > max {
+ n = max
+ }
+ if cl := cs.reqBodyContentLength; cl != -1 && cl+1 < n {
+ // Add an extra byte past the declared content-length to
+ // give the caller's Request.Body io.Reader a chance to
+ // give us more bytes than they declared, so we can catch it
+ // early.
+ n = cl + 1
+ }
+ if n < 1 {
+ return 1
+ }
+ return int(n) // doesn't truncate; max is 512K
+}
+
+var http2bufPool sync.Pool // of *[]byte
+
+func (cs *http2clientStream) writeRequestBody(req *Request) (err error) {
+ cc := cs.cc
+ body := cs.reqBody
+ sentEnd := false // whether we sent the final DATA frame w/ END_STREAM
+
+ hasTrailers := req.Trailer != nil
+ remainLen := cs.reqBodyContentLength
+ hasContentLen := remainLen != -1
+
+ cc.mu.Lock()
+ maxFrameSize := int(cc.maxFrameSize)
+ cc.mu.Unlock()
+
+ // Scratch buffer for reading into & writing from.
+ scratchLen := cs.frameScratchBufferLen(maxFrameSize)
+ var buf []byte
+ if bp, ok := http2bufPool.Get().(*[]byte); ok && len(*bp) >= scratchLen {
+ defer http2bufPool.Put(bp)
+ buf = *bp
+ } else {
+ buf = make([]byte, scratchLen)
+ defer http2bufPool.Put(&buf)
+ }
+
+ var sawEOF bool
+ for !sawEOF {
+ n, err := body.Read(buf)
+ if hasContentLen {
+ remainLen -= int64(n)
+ if remainLen == 0 && err == nil {
+ // The request body's Content-Length was predeclared and
+ // we just finished reading it all, but the underlying io.Reader
+ // returned the final chunk with a nil error (which is one of
+ // the two valid things a Reader can do at EOF). Because we'd prefer
+ // to send the END_STREAM bit early, double-check that we're actually
+ // at EOF. Subsequent reads should return (0, EOF) at this point.
+ // If either value is different, we return an error in one of two ways below.
+ var scratch [1]byte
+ var n1 int
+ n1, err = body.Read(scratch[:])
+ remainLen -= int64(n1)
+ }
+ if remainLen < 0 {
+ err = http2errReqBodyTooLong
+ return err
+ }
+ }
+ if err != nil {
+ cc.mu.Lock()
+ bodyClosed := cs.reqBodyClosed != nil
+ cc.mu.Unlock()
+ switch {
+ case bodyClosed:
+ return http2errStopReqBodyWrite
+ case err == io.EOF:
+ sawEOF = true
+ err = nil
+ default:
+ return err
+ }
+ }
+
+ remain := buf[:n]
+ for len(remain) > 0 && err == nil {
+ var allowed int32
+ allowed, err = cs.awaitFlowControl(len(remain))
+ if err != nil {
+ return err
+ }
+ cc.wmu.Lock()
+ data := remain[:allowed]
+ remain = remain[allowed:]
+ sentEnd = sawEOF && len(remain) == 0 && !hasTrailers
+ err = cc.fr.WriteData(cs.ID, sentEnd, data)
+ if err == nil {
+ // TODO(bradfitz): this flush is for latency, not bandwidth.
+ // Most requests won't need this. Make this opt-in or
+ // opt-out? Use some heuristic on the body type? Nagel-like
+ // timers? Based on 'n'? Only last chunk of this for loop,
+ // unless flow control tokens are low? For now, always.
+ // If we change this, see comment below.
+ err = cc.bw.Flush()
+ }
+ cc.wmu.Unlock()
+ }
+ if err != nil {
+ return err
+ }
+ }
+
+ if sentEnd {
+ // Already sent END_STREAM (which implies we have no
+ // trailers) and flushed, because currently all
+ // WriteData frames above get a flush. So we're done.
+ return nil
+ }
+
+ // Since the RoundTrip contract permits the caller to "mutate or reuse"
+ // a request after the Response's Body is closed, verify that this hasn't
+ // happened before accessing the trailers.
+ cc.mu.Lock()
+ trailer := req.Trailer
+ err = cs.abortErr
+ cc.mu.Unlock()
+ if err != nil {
+ return err
+ }
+
+ cc.wmu.Lock()
+ defer cc.wmu.Unlock()
+ var trls []byte
+ if len(trailer) > 0 {
+ trls, err = cc.encodeTrailers(trailer)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Two ways to send END_STREAM: either with trailers, or
+ // with an empty DATA frame.
+ if len(trls) > 0 {
+ err = cc.writeHeaders(cs.ID, true, maxFrameSize, trls)
+ } else {
+ err = cc.fr.WriteData(cs.ID, true, nil)
+ }
+ if ferr := cc.bw.Flush(); ferr != nil && err == nil {
+ err = ferr
+ }
+ return err
+}
+
+// awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow
+// control tokens from the server.
+// It returns either the non-zero number of tokens taken or an error
+// if the stream is dead.
+func (cs *http2clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) {
+ cc := cs.cc
+ ctx := cs.ctx
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+ for {
+ if cc.closed {
+ return 0, http2errClientConnClosed
+ }
+ if cs.reqBodyClosed != nil {
+ return 0, http2errStopReqBodyWrite
+ }
+ select {
+ case <-cs.abort:
+ return 0, cs.abortErr
+ case <-ctx.Done():
+ return 0, ctx.Err()
+ case <-cs.reqCancel:
+ return 0, http2errRequestCanceled
+ default:
+ }
+ if a := cs.flow.available(); a > 0 {
+ take := a
+ if int(take) > maxBytes {
+
+ take = int32(maxBytes) // can't truncate int; take is int32
+ }
+ if take > int32(cc.maxFrameSize) {
+ take = int32(cc.maxFrameSize)
+ }
+ cs.flow.take(take)
+ return take, nil
+ }
+ cc.cond.Wait()
+ }
+}
+
+var http2errNilRequestURL = errors.New("http2: Request.URI is nil")
+
+// requires cc.wmu be held.
+func (cc *http2ClientConn) encodeHeaders(req *Request, addGzipHeader bool, trailers string, contentLength int64) ([]byte, error) {
+ cc.hbuf.Reset()
+ if req.URL == nil {
+ return nil, http2errNilRequestURL
+ }
+
+ host := req.Host
+ if host == "" {
+ host = req.URL.Host
+ }
+ host, err := httpguts.PunycodeHostPort(host)
+ if err != nil {
+ return nil, err
+ }
+ if !httpguts.ValidHostHeader(host) {
+ return nil, errors.New("http2: invalid Host header")
+ }
+
+ var path string
+ if req.Method != "CONNECT" {
+ path = req.URL.RequestURI()
+ if !http2validPseudoPath(path) {
+ orig := path
+ path = strings.TrimPrefix(path, req.URL.Scheme+"://"+host)
+ if !http2validPseudoPath(path) {
+ if req.URL.Opaque != "" {
+ return nil, fmt.Errorf("invalid request :path %q from URL.Opaque = %q", orig, req.URL.Opaque)
+ } else {
+ return nil, fmt.Errorf("invalid request :path %q", orig)
+ }
+ }
+ }
+ }
+
+ // Check for any invalid headers and return an error before we
+ // potentially pollute our hpack state. (We want to be able to
+ // continue to reuse the hpack encoder for future requests)
+ for k, vv := range req.Header {
+ if !httpguts.ValidHeaderFieldName(k) {
+ return nil, fmt.Errorf("invalid HTTP header name %q", k)
+ }
+ for _, v := range vv {
+ if !httpguts.ValidHeaderFieldValue(v) {
+ // Don't include the value in the error, because it may be sensitive.
+ return nil, fmt.Errorf("invalid HTTP header value for header %q", k)
+ }
+ }
+ }
+
+ enumerateHeaders := func(f func(name, value string)) {
+ // 8.1.2.3 Request Pseudo-Header Fields
+ // The :path pseudo-header field includes the path and query parts of the
+ // target URI (the path-absolute production and optionally a '?' character
+ // followed by the query production, see Sections 3.3 and 3.4 of
+ // [RFC3986]).
+ f(":authority", host)
+ m := req.Method
+ if m == "" {
+ m = MethodGet
+ }
+ f(":method", m)
+ if req.Method != "CONNECT" {
+ f(":path", path)
+ f(":scheme", req.URL.Scheme)
+ }
+ if trailers != "" {
+ f("trailer", trailers)
+ }
+
+ var didUA bool
+ for k, vv := range req.Header {
+ if http2asciiEqualFold(k, "host") || http2asciiEqualFold(k, "content-length") {
+ // Host is :authority, already sent.
+ // Content-Length is automatic, set below.
+ continue
+ } else if http2asciiEqualFold(k, "connection") ||
+ http2asciiEqualFold(k, "proxy-connection") ||
+ http2asciiEqualFold(k, "transfer-encoding") ||
+ http2asciiEqualFold(k, "upgrade") ||
+ http2asciiEqualFold(k, "keep-alive") {
+ // Per 8.1.2.2 Connection-Specific Header
+ // Fields, don't send connection-specific
+ // fields. We have already checked if any
+ // are error-worthy so just ignore the rest.
+ continue
+ } else if http2asciiEqualFold(k, "user-agent") {
+ // Match Go's http1 behavior: at most one
+ // User-Agent. If set to nil or empty string,
+ // then omit it. Otherwise if not mentioned,
+ // include the default (below).
+ didUA = true
+ if len(vv) < 1 {
+ continue
+ }
+ vv = vv[:1]
+ if vv[0] == "" {
+ continue
+ }
+ } else if http2asciiEqualFold(k, "cookie") {
+ // Per 8.1.2.5 To allow for better compression efficiency, the
+ // Cookie header field MAY be split into separate header fields,
+ // each with one or more cookie-pairs.
+ for _, v := range vv {
+ for {
+ p := strings.IndexByte(v, ';')
+ if p < 0 {
+ break
+ }
+ f("cookie", v[:p])
+ p++
+ // strip space after semicolon if any.
+ for p+1 <= len(v) && v[p] == ' ' {
+ p++
+ }
+ v = v[p:]
+ }
+ if len(v) > 0 {
+ f("cookie", v)
+ }
+ }
+ continue
+ }
+
+ for _, v := range vv {
+ f(k, v)
+ }
+ }
+ if http2shouldSendReqContentLength(req.Method, contentLength) {
+ f("content-length", strconv.FormatInt(contentLength, 10))
+ }
+ if addGzipHeader {
+ f("accept-encoding", "gzip")
+ }
+ if !didUA {
+ f("user-agent", http2defaultUserAgent)
+ }
+ }
+
+ // Do a first pass over the headers counting bytes to ensure
+ // we don't exceed cc.peerMaxHeaderListSize. This is done as a
+ // separate pass before encoding the headers to prevent
+ // modifying the hpack state.
+ hlSize := uint64(0)
+ enumerateHeaders(func(name, value string) {
+ hf := hpack.HeaderField{Name: name, Value: value}
+ hlSize += uint64(hf.Size())
+ })
+
+ if hlSize > cc.peerMaxHeaderListSize {
+ return nil, http2errRequestHeaderListSize
+ }
+
+ trace := httptrace.ContextClientTrace(req.Context())
+ traceHeaders := http2traceHasWroteHeaderField(trace)
+
+ // Header list size is ok. Write the headers.
+ enumerateHeaders(func(name, value string) {
+ name, ascii := http2lowerHeader(name)
+ if !ascii {
+ // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
+ // field names have to be ASCII characters (just as in HTTP/1.x).
+ return
+ }
+ cc.writeHeader(name, value)
+ if traceHeaders {
+ http2traceWroteHeaderField(trace, name, value)
+ }
+ })
+
+ return cc.hbuf.Bytes(), nil
+}
+
+// shouldSendReqContentLength reports whether the http2.Transport should send
+// a "content-length" request header. This logic is basically a copy of the net/http
+// transferWriter.shouldSendContentLength.
+// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown).
+// -1 means unknown.
+func http2shouldSendReqContentLength(method string, contentLength int64) bool {
+ if contentLength > 0 {
+ return true
+ }
+ if contentLength < 0 {
+ return false
+ }
+ // For zero bodies, whether we send a content-length depends on the method.
+ // It also kinda doesn't matter for http2 either way, with END_STREAM.
+ switch method {
+ case "POST", "PUT", "PATCH":
+ return true
+ default:
+ return false
+ }
+}
+
+// requires cc.wmu be held.
+func (cc *http2ClientConn) encodeTrailers(trailer Header) ([]byte, error) {
+ cc.hbuf.Reset()
+
+ hlSize := uint64(0)
+ for k, vv := range trailer {
+ for _, v := range vv {
+ hf := hpack.HeaderField{Name: k, Value: v}
+ hlSize += uint64(hf.Size())
+ }
+ }
+ if hlSize > cc.peerMaxHeaderListSize {
+ return nil, http2errRequestHeaderListSize
+ }
+
+ for k, vv := range trailer {
+ lowKey, ascii := http2lowerHeader(k)
+ if !ascii {
+ // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
+ // field names have to be ASCII characters (just as in HTTP/1.x).
+ continue
+ }
+ // Transfer-Encoding, etc.. have already been filtered at the
+ // start of RoundTrip
+ for _, v := range vv {
+ cc.writeHeader(lowKey, v)
+ }
+ }
+ return cc.hbuf.Bytes(), nil
+}
+
+func (cc *http2ClientConn) writeHeader(name, value string) {
+ if http2VerboseLogs {
+ log.Printf("http2: Transport encoding header %q = %q", name, value)
+ }
+ cc.henc.WriteField(hpack.HeaderField{Name: name, Value: value})
+}
+
+type http2resAndError struct {
+ _ http2incomparable
+ res *Response
+ err error
+}
+
+// requires cc.mu be held.
+func (cc *http2ClientConn) addStreamLocked(cs *http2clientStream) {
+ cs.flow.add(int32(cc.initialWindowSize))
+ cs.flow.setConnFlow(&cc.flow)
+ cs.inflow.init(http2transportDefaultStreamFlow)
+ cs.ID = cc.nextStreamID
+ cc.nextStreamID += 2
+ cc.streams[cs.ID] = cs
+ if cs.ID == 0 {
+ panic("assigned stream ID 0")
+ }
+}
+
+func (cc *http2ClientConn) forgetStreamID(id uint32) {
+ cc.mu.Lock()
+ slen := len(cc.streams)
+ delete(cc.streams, id)
+ if len(cc.streams) != slen-1 {
+ panic("forgetting unknown stream id")
+ }
+ cc.lastActive = time.Now()
+ if len(cc.streams) == 0 && cc.idleTimer != nil {
+ cc.idleTimer.Reset(cc.idleTimeout)
+ cc.lastIdle = time.Now()
+ }
+ // Wake up writeRequestBody via clientStream.awaitFlowControl and
+ // wake up RoundTrip if there is a pending request.
+ cc.cond.Broadcast()
+
+ closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil
+ if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 {
+ if http2VerboseLogs {
+ cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, cc.nextStreamID-2)
+ }
+ cc.closed = true
+ defer cc.closeConn()
+ }
+
+ cc.mu.Unlock()
+}
+
+// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.
+type http2clientConnReadLoop struct {
+ _ http2incomparable
+ cc *http2ClientConn
+}
+
+// readLoop runs in its own goroutine and reads and dispatches frames.
+func (cc *http2ClientConn) readLoop() {
+ rl := &http2clientConnReadLoop{cc: cc}
+ defer rl.cleanup()
+ cc.readerErr = rl.run()
+ if ce, ok := cc.readerErr.(http2ConnectionError); ok {
+ cc.wmu.Lock()
+ cc.fr.WriteGoAway(0, http2ErrCode(ce), nil)
+ cc.wmu.Unlock()
+ }
+}
+
+// GoAwayError is returned by the Transport when the server closes the
+// TCP connection after sending a GOAWAY frame.
+type http2GoAwayError struct {
+ LastStreamID uint32
+ ErrCode http2ErrCode
+ DebugData string
+}
+
+func (e http2GoAwayError) Error() string {
+ return fmt.Sprintf("http2: server sent GOAWAY and closed the connection; LastStreamID=%v, ErrCode=%v, debug=%q",
+ e.LastStreamID, e.ErrCode, e.DebugData)
+}
+
+func http2isEOFOrNetReadError(err error) bool {
+ if err == io.EOF {
+ return true
+ }
+ ne, ok := err.(*net.OpError)
+ return ok && ne.Op == "read"
+}
+
+func (rl *http2clientConnReadLoop) cleanup() {
+ cc := rl.cc
+ cc.t.connPool().MarkDead(cc)
+ defer cc.closeConn()
+ defer close(cc.readerDone)
+
+ if cc.idleTimer != nil {
+ cc.idleTimer.Stop()
+ }
+
+ // Close any response bodies if the server closes prematurely.
+ // TODO: also do this if we've written the headers but not
+ // gotten a response yet.
+ err := cc.readerErr
+ cc.mu.Lock()
+ if cc.goAway != nil && http2isEOFOrNetReadError(err) {
+ err = http2GoAwayError{
+ LastStreamID: cc.goAway.LastStreamID,
+ ErrCode: cc.goAway.ErrCode,
+ DebugData: cc.goAwayDebug,
+ }
+ } else if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ cc.closed = true
+
+ for _, cs := range cc.streams {
+ select {
+ case <-cs.peerClosed:
+ // The server closed the stream before closing the conn,
+ // so no need to interrupt it.
+ default:
+ cs.abortStreamLocked(err)
+ }
+ }
+ cc.cond.Broadcast()
+ cc.mu.Unlock()
+}
+
+// countReadFrameError calls Transport.CountError with a string
+// representing err.
+func (cc *http2ClientConn) countReadFrameError(err error) {
+ f := cc.t.CountError
+ if f == nil || err == nil {
+ return
+ }
+ if ce, ok := err.(http2ConnectionError); ok {
+ errCode := http2ErrCode(ce)
+ f(fmt.Sprintf("read_frame_conn_error_%s", errCode.stringToken()))
+ return
+ }
+ if errors.Is(err, io.EOF) {
+ f("read_frame_eof")
+ return
+ }
+ if errors.Is(err, io.ErrUnexpectedEOF) {
+ f("read_frame_unexpected_eof")
+ return
+ }
+ if errors.Is(err, http2ErrFrameTooLarge) {
+ f("read_frame_too_large")
+ return
+ }
+ f("read_frame_other")
+}
+
+func (rl *http2clientConnReadLoop) run() error {
+ cc := rl.cc
+ gotSettings := false
+ readIdleTimeout := cc.t.ReadIdleTimeout
+ var t *time.Timer
+ if readIdleTimeout != 0 {
+ t = time.AfterFunc(readIdleTimeout, cc.healthCheck)
+ defer t.Stop()
+ }
+ for {
+ f, err := cc.fr.ReadFrame()
+ if t != nil {
+ t.Reset(readIdleTimeout)
+ }
+ if err != nil {
+ cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err)
+ }
+ if se, ok := err.(http2StreamError); ok {
+ if cs := rl.streamByID(se.StreamID); cs != nil {
+ if se.Cause == nil {
+ se.Cause = cc.fr.errDetail
+ }
+ rl.endStreamError(cs, se)
+ }
+ continue
+ } else if err != nil {
+ cc.countReadFrameError(err)
+ return err
+ }
+ if http2VerboseLogs {
+ cc.vlogf("http2: Transport received %s", http2summarizeFrame(f))
+ }
+ if !gotSettings {
+ if _, ok := f.(*http2SettingsFrame); !ok {
+ cc.logf("protocol error: received %T before a SETTINGS frame", f)
+ return http2ConnectionError(http2ErrCodeProtocol)
+ }
+ gotSettings = true
+ }
+
+ switch f := f.(type) {
+ case *http2MetaHeadersFrame:
+ err = rl.processHeaders(f)
+ case *http2DataFrame:
+ err = rl.processData(f)
+ case *http2GoAwayFrame:
+ err = rl.processGoAway(f)
+ case *http2RSTStreamFrame:
+ err = rl.processResetStream(f)
+ case *http2SettingsFrame:
+ err = rl.processSettings(f)
+ case *http2PushPromiseFrame:
+ err = rl.processPushPromise(f)
+ case *http2WindowUpdateFrame:
+ err = rl.processWindowUpdate(f)
+ case *http2PingFrame:
+ err = rl.processPing(f)
+ default:
+ cc.logf("Transport: unhandled response frame type %T", f)
+ }
+ if err != nil {
+ if http2VerboseLogs {
+ cc.vlogf("http2: Transport conn %p received error from processing frame %v: %v", cc, http2summarizeFrame(f), err)
+ }
+ return err
+ }
+ }
+}
+
+func (rl *http2clientConnReadLoop) processHeaders(f *http2MetaHeadersFrame) error {
+ cs := rl.streamByID(f.StreamID)
+ if cs == nil {
+ // We'd get here if we canceled a request while the
+ // server had its response still in flight. So if this
+ // was just something we canceled, ignore it.
+ return nil
+ }
+ if cs.readClosed {
+ rl.endStreamError(cs, http2StreamError{
+ StreamID: f.StreamID,
+ Code: http2ErrCodeProtocol,
+ Cause: errors.New("protocol error: headers after END_STREAM"),
+ })
+ return nil
+ }
+ if !cs.firstByte {
+ if cs.trace != nil {
+ // TODO(bradfitz): move first response byte earlier,
+ // when we first read the 9 byte header, not waiting
+ // until all the HEADERS+CONTINUATION frames have been
+ // merged. This works for now.
+ http2traceFirstResponseByte(cs.trace)
+ }
+ cs.firstByte = true
+ }
+ if !cs.pastHeaders {
+ cs.pastHeaders = true
+ } else {
+ return rl.processTrailers(cs, f)
+ }
+
+ res, err := rl.handleResponse(cs, f)
+ if err != nil {
+ if _, ok := err.(http2ConnectionError); ok {
+ return err
+ }
+ // Any other error type is a stream error.
+ rl.endStreamError(cs, http2StreamError{
+ StreamID: f.StreamID,
+ Code: http2ErrCodeProtocol,
+ Cause: err,
+ })
+ return nil // return nil from process* funcs to keep conn alive
+ }
+ if res == nil {
+ // (nil, nil) special case. See handleResponse docs.
+ return nil
+ }
+ cs.resTrailer = &res.Trailer
+ cs.res = res
+ close(cs.respHeaderRecv)
+ if f.StreamEnded() {
+ rl.endStream(cs)
+ }
+ return nil
+}
+
+// may return error types nil, or ConnectionError. Any other error value
+// is a StreamError of type ErrCodeProtocol. The returned error in that case
+// is the detail.
+//
+// As a special case, handleResponse may return (nil, nil) to skip the
+// frame (currently only used for 1xx responses).
+func (rl *http2clientConnReadLoop) handleResponse(cs *http2clientStream, f *http2MetaHeadersFrame) (*Response, error) {
+ if f.Truncated {
+ return nil, http2errResponseHeaderListSize
+ }
+
+ status := f.PseudoValue("status")
+ if status == "" {
+ return nil, errors.New("malformed response from server: missing status pseudo header")
+ }
+ statusCode, err := strconv.Atoi(status)
+ if err != nil {
+ return nil, errors.New("malformed response from server: malformed non-numeric status pseudo header")
+ }
+
+ regularFields := f.RegularFields()
+ strs := make([]string, len(regularFields))
+ header := make(Header, len(regularFields))
+ res := &Response{
+ Proto: "HTTP/2.0",
+ ProtoMajor: 2,
+ Header: header,
+ StatusCode: statusCode,
+ Status: status + " " + StatusText(statusCode),
+ }
+ for _, hf := range regularFields {
+ key := http2canonicalHeader(hf.Name)
+ if key == "Trailer" {
+ t := res.Trailer
+ if t == nil {
+ t = make(Header)
+ res.Trailer = t
+ }
+ http2foreachHeaderElement(hf.Value, func(v string) {
+ t[http2canonicalHeader(v)] = nil
+ })
+ } else {
+ vv := header[key]
+ if vv == nil && len(strs) > 0 {
+ // More than likely this will be a single-element key.
+ // Most headers aren't multi-valued.
+ // Set the capacity on strs[0] to 1, so any future append
+ // won't extend the slice into the other strings.
+ vv, strs = strs[:1:1], strs[1:]
+ vv[0] = hf.Value
+ header[key] = vv
+ } else {
+ header[key] = append(vv, hf.Value)
+ }
+ }
+ }
+
+ if statusCode >= 100 && statusCode <= 199 {
+ if f.StreamEnded() {
+ return nil, errors.New("1xx informational response with END_STREAM flag")
+ }
+ cs.num1xx++
+ const max1xxResponses = 5 // arbitrary bound on number of informational responses, same as net/http
+ if cs.num1xx > max1xxResponses {
+ return nil, errors.New("http2: too many 1xx informational responses")
+ }
+ if fn := cs.get1xxTraceFunc(); fn != nil {
+ if err := fn(statusCode, textproto.MIMEHeader(header)); err != nil {
+ return nil, err
+ }
+ }
+ if statusCode == 100 {
+ http2traceGot100Continue(cs.trace)
+ select {
+ case cs.on100 <- struct{}{}:
+ default:
+ }
+ }
+ cs.pastHeaders = false // do it all again
+ return nil, nil
+ }
+
+ res.ContentLength = -1
+ if clens := res.Header["Content-Length"]; len(clens) == 1 {
+ if cl, err := strconv.ParseUint(clens[0], 10, 63); err == nil {
+ res.ContentLength = int64(cl)
+ } else {
+ // TODO: care? unlike http/1, it won't mess up our framing, so it's
+ // more safe smuggling-wise to ignore.
+ }
+ } else if len(clens) > 1 {
+ // TODO: care? unlike http/1, it won't mess up our framing, so it's
+ // more safe smuggling-wise to ignore.
+ } else if f.StreamEnded() && !cs.isHead {
+ res.ContentLength = 0
+ }
+
+ if cs.isHead {
+ res.Body = http2noBody
+ return res, nil
+ }
+
+ if f.StreamEnded() {
+ if res.ContentLength > 0 {
+ res.Body = http2missingBody{}
+ } else {
+ res.Body = http2noBody
+ }
+ return res, nil
+ }
+
+ cs.bufPipe.setBuffer(&http2dataBuffer{expected: res.ContentLength})
+ cs.bytesRemain = res.ContentLength
+ res.Body = http2transportResponseBody{cs}
+
+ if cs.requestedGzip && http2asciiEqualFold(res.Header.Get("Content-Encoding"), "gzip") {
+ res.Header.Del("Content-Encoding")
+ res.Header.Del("Content-Length")
+ res.ContentLength = -1
+ res.Body = &http2gzipReader{body: res.Body}
+ res.Uncompressed = true
+ }
+ return res, nil
+}
+
+func (rl *http2clientConnReadLoop) processTrailers(cs *http2clientStream, f *http2MetaHeadersFrame) error {
+ if cs.pastTrailers {
+ // Too many HEADERS frames for this stream.
+ return http2ConnectionError(http2ErrCodeProtocol)
+ }
+ cs.pastTrailers = true
+ if !f.StreamEnded() {
+ // We expect that any headers for trailers also
+ // has END_STREAM.
+ return http2ConnectionError(http2ErrCodeProtocol)
+ }
+ if len(f.PseudoFields()) > 0 {
+ // No pseudo header fields are defined for trailers.
+ // TODO: ConnectionError might be overly harsh? Check.
+ return http2ConnectionError(http2ErrCodeProtocol)
+ }
+
+ trailer := make(Header)
+ for _, hf := range f.RegularFields() {
+ key := http2canonicalHeader(hf.Name)
+ trailer[key] = append(trailer[key], hf.Value)
+ }
+ cs.trailer = trailer
+
+ rl.endStream(cs)
+ return nil
+}
+
+// transportResponseBody is the concrete type of Transport.RoundTrip's
+// Response.Body. It is an io.ReadCloser.
+type http2transportResponseBody struct {
+ cs *http2clientStream
+}
+
+func (b http2transportResponseBody) Read(p []byte) (n int, err error) {
+ cs := b.cs
+ cc := cs.cc
+
+ if cs.readErr != nil {
+ return 0, cs.readErr
+ }
+ n, err = b.cs.bufPipe.Read(p)
+ if cs.bytesRemain != -1 {
+ if int64(n) > cs.bytesRemain {
+ n = int(cs.bytesRemain)
+ if err == nil {
+ err = errors.New("net/http: server replied with more than declared Content-Length; truncated")
+ cs.abortStream(err)
+ }
+ cs.readErr = err
+ return int(cs.bytesRemain), err
+ }
+ cs.bytesRemain -= int64(n)
+ if err == io.EOF && cs.bytesRemain > 0 {
+ err = io.ErrUnexpectedEOF
+ cs.readErr = err
+ return n, err
+ }
+ }
+ if n == 0 {
+ // No flow control tokens to send back.
+ return
+ }
+
+ cc.mu.Lock()
+ connAdd := cc.inflow.add(n)
+ var streamAdd int32
+ if err == nil { // No need to refresh if the stream is over or failed.
+ streamAdd = cs.inflow.add(n)
+ }
+ cc.mu.Unlock()
+
+ if connAdd != 0 || streamAdd != 0 {
+ cc.wmu.Lock()
+ defer cc.wmu.Unlock()
+ if connAdd != 0 {
+ cc.fr.WriteWindowUpdate(0, http2mustUint31(connAdd))
+ }
+ if streamAdd != 0 {
+ cc.fr.WriteWindowUpdate(cs.ID, http2mustUint31(streamAdd))
+ }
+ cc.bw.Flush()
+ }
+ return
+}
+
+var http2errClosedResponseBody = errors.New("http2: response body closed")
+
+func (b http2transportResponseBody) Close() error {
+ cs := b.cs
+ cc := cs.cc
+
+ cs.bufPipe.BreakWithError(http2errClosedResponseBody)
+ cs.abortStream(http2errClosedResponseBody)
+
+ unread := cs.bufPipe.Len()
+ if unread > 0 {
+ cc.mu.Lock()
+ // Return connection-level flow control.
+ connAdd := cc.inflow.add(unread)
+ cc.mu.Unlock()
+
+ // TODO(dneil): Acquiring this mutex can block indefinitely.
+ // Move flow control return to a goroutine?
+ cc.wmu.Lock()
+ // Return connection-level flow control.
+ if connAdd > 0 {
+ cc.fr.WriteWindowUpdate(0, uint32(connAdd))
+ }
+ cc.bw.Flush()
+ cc.wmu.Unlock()
+ }
+
+ select {
+ case <-cs.donec:
+ case <-cs.ctx.Done():
+ // See golang/go#49366: The net/http package can cancel the
+ // request context after the response body is fully read.
+ // Don't treat this as an error.
+ return nil
+ case <-cs.reqCancel:
+ return http2errRequestCanceled
+ }
+ return nil
+}
+
+func (rl *http2clientConnReadLoop) processData(f *http2DataFrame) error {
+ cc := rl.cc
+ cs := rl.streamByID(f.StreamID)
+ data := f.Data()
+ if cs == nil {
+ cc.mu.Lock()
+ neverSent := cc.nextStreamID
+ cc.mu.Unlock()
+ if f.StreamID >= neverSent {
+ // We never asked for this.
+ cc.logf("http2: Transport received unsolicited DATA frame; closing connection")
+ return http2ConnectionError(http2ErrCodeProtocol)
+ }
+ // We probably did ask for this, but canceled. Just ignore it.
+ // TODO: be stricter here? only silently ignore things which
+ // we canceled, but not things which were closed normally
+ // by the peer? Tough without accumulating too much state.
+
+ // But at least return their flow control:
+ if f.Length > 0 {
+ cc.mu.Lock()
+ ok := cc.inflow.take(f.Length)
+ connAdd := cc.inflow.add(int(f.Length))
+ cc.mu.Unlock()
+ if !ok {
+ return http2ConnectionError(http2ErrCodeFlowControl)
+ }
+ if connAdd > 0 {
+ cc.wmu.Lock()
+ cc.fr.WriteWindowUpdate(0, uint32(connAdd))
+ cc.bw.Flush()
+ cc.wmu.Unlock()
+ }
+ }
+ return nil
+ }
+ if cs.readClosed {
+ cc.logf("protocol error: received DATA after END_STREAM")
+ rl.endStreamError(cs, http2StreamError{
+ StreamID: f.StreamID,
+ Code: http2ErrCodeProtocol,
+ })
+ return nil
+ }
+ if !cs.firstByte {
+ cc.logf("protocol error: received DATA before a HEADERS frame")
+ rl.endStreamError(cs, http2StreamError{
+ StreamID: f.StreamID,
+ Code: http2ErrCodeProtocol,
+ })
+ return nil
+ }
+ if f.Length > 0 {
+ if cs.isHead && len(data) > 0 {
+ cc.logf("protocol error: received DATA on a HEAD request")
+ rl.endStreamError(cs, http2StreamError{
+ StreamID: f.StreamID,
+ Code: http2ErrCodeProtocol,
+ })
+ return nil
+ }
+ // Check connection-level flow control.
+ cc.mu.Lock()
+ if !http2takeInflows(&cc.inflow, &cs.inflow, f.Length) {
+ cc.mu.Unlock()
+ return http2ConnectionError(http2ErrCodeFlowControl)
+ }
+ // Return any padded flow control now, since we won't
+ // refund it later on body reads.
+ var refund int
+ if pad := int(f.Length) - len(data); pad > 0 {
+ refund += pad
+ }
+
+ didReset := false
+ var err error
+ if len(data) > 0 {
+ if _, err = cs.bufPipe.Write(data); err != nil {
+ // Return len(data) now if the stream is already closed,
+ // since data will never be read.
+ didReset = true
+ refund += len(data)
+ }
+ }
+
+ sendConn := cc.inflow.add(refund)
+ var sendStream int32
+ if !didReset {
+ sendStream = cs.inflow.add(refund)
+ }
+ cc.mu.Unlock()
+
+ if sendConn > 0 || sendStream > 0 {
+ cc.wmu.Lock()
+ if sendConn > 0 {
+ cc.fr.WriteWindowUpdate(0, uint32(sendConn))
+ }
+ if sendStream > 0 {
+ cc.fr.WriteWindowUpdate(cs.ID, uint32(sendStream))
+ }
+ cc.bw.Flush()
+ cc.wmu.Unlock()
+ }
+
+ if err != nil {
+ rl.endStreamError(cs, err)
+ return nil
+ }
+ }
+
+ if f.StreamEnded() {
+ rl.endStream(cs)
+ }
+ return nil
+}
+
+func (rl *http2clientConnReadLoop) endStream(cs *http2clientStream) {
+ // TODO: check that any declared content-length matches, like
+ // server.go's (*stream).endStream method.
+ if !cs.readClosed {
+ cs.readClosed = true
+ // Close cs.bufPipe and cs.peerClosed with cc.mu held to avoid a
+ // race condition: The caller can read io.EOF from Response.Body
+ // and close the body before we close cs.peerClosed, causing
+ // cleanupWriteRequest to send a RST_STREAM.
+ rl.cc.mu.Lock()
+ defer rl.cc.mu.Unlock()
+ cs.bufPipe.closeWithErrorAndCode(io.EOF, cs.copyTrailers)
+ close(cs.peerClosed)
+ }
+}
+
+func (rl *http2clientConnReadLoop) endStreamError(cs *http2clientStream, err error) {
+ cs.readAborted = true
+ cs.abortStream(err)
+}
+
+func (rl *http2clientConnReadLoop) streamByID(id uint32) *http2clientStream {
+ rl.cc.mu.Lock()
+ defer rl.cc.mu.Unlock()
+ cs := rl.cc.streams[id]
+ if cs != nil && !cs.readAborted {
+ return cs
+ }
+ return nil
+}
+
+func (cs *http2clientStream) copyTrailers() {
+ for k, vv := range cs.trailer {
+ t := cs.resTrailer
+ if *t == nil {
+ *t = make(Header)
+ }
+ (*t)[k] = vv
+ }
+}
+
+func (rl *http2clientConnReadLoop) processGoAway(f *http2GoAwayFrame) error {
+ cc := rl.cc
+ cc.t.connPool().MarkDead(cc)
+ if f.ErrCode != 0 {
+ // TODO: deal with GOAWAY more. particularly the error code
+ cc.vlogf("transport got GOAWAY with error code = %v", f.ErrCode)
+ if fn := cc.t.CountError; fn != nil {
+ fn("recv_goaway_" + f.ErrCode.stringToken())
+ }
+ }
+ cc.setGoAway(f)
+ return nil
+}
+
+func (rl *http2clientConnReadLoop) processSettings(f *http2SettingsFrame) error {
+ cc := rl.cc
+ // Locking both mu and wmu here allows frame encoding to read settings with only wmu held.
+ // Acquiring wmu when f.IsAck() is unnecessary, but convenient and mostly harmless.
+ cc.wmu.Lock()
+ defer cc.wmu.Unlock()
+
+ if err := rl.processSettingsNoWrite(f); err != nil {
+ return err
+ }
+ if !f.IsAck() {
+ cc.fr.WriteSettingsAck()
+ cc.bw.Flush()
+ }
+ return nil
+}
+
+func (rl *http2clientConnReadLoop) processSettingsNoWrite(f *http2SettingsFrame) error {
+ cc := rl.cc
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+
+ if f.IsAck() {
+ if cc.wantSettingsAck {
+ cc.wantSettingsAck = false
+ return nil
+ }
+ return http2ConnectionError(http2ErrCodeProtocol)
+ }
+
+ var seenMaxConcurrentStreams bool
+ err := f.ForeachSetting(func(s http2Setting) error {
+ switch s.ID {
+ case http2SettingMaxFrameSize:
+ cc.maxFrameSize = s.Val
+ case http2SettingMaxConcurrentStreams:
+ cc.maxConcurrentStreams = s.Val
+ seenMaxConcurrentStreams = true
+ case http2SettingMaxHeaderListSize:
+ cc.peerMaxHeaderListSize = uint64(s.Val)
+ case http2SettingInitialWindowSize:
+ // Values above the maximum flow-control
+ // window size of 2^31-1 MUST be treated as a
+ // connection error (Section 5.4.1) of type
+ // FLOW_CONTROL_ERROR.
+ if s.Val > math.MaxInt32 {
+ return http2ConnectionError(http2ErrCodeFlowControl)
+ }
+
+ // Adjust flow control of currently-open
+ // frames by the difference of the old initial
+ // window size and this one.
+ delta := int32(s.Val) - int32(cc.initialWindowSize)
+ for _, cs := range cc.streams {
+ cs.flow.add(delta)
+ }
+ cc.cond.Broadcast()
+
+ cc.initialWindowSize = s.Val
+ case http2SettingHeaderTableSize:
+ cc.henc.SetMaxDynamicTableSize(s.Val)
+ cc.peerMaxHeaderTableSize = s.Val
+ default:
+ cc.vlogf("Unhandled Setting: %v", s)
+ }
+ return nil
+ })
+ if err != nil {
+ return err
+ }
+
+ if !cc.seenSettings {
+ if !seenMaxConcurrentStreams {
+ // This was the servers initial SETTINGS frame and it
+ // didn't contain a MAX_CONCURRENT_STREAMS field so
+ // increase the number of concurrent streams this
+ // connection can establish to our default.
+ cc.maxConcurrentStreams = http2defaultMaxConcurrentStreams
+ }
+ cc.seenSettings = true
+ }
+
+ return nil
+}
+
+func (rl *http2clientConnReadLoop) processWindowUpdate(f *http2WindowUpdateFrame) error {
+ cc := rl.cc
+ cs := rl.streamByID(f.StreamID)
+ if f.StreamID != 0 && cs == nil {
+ return nil
+ }
+
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+
+ fl := &cc.flow
+ if cs != nil {
+ fl = &cs.flow
+ }
+ if !fl.add(int32(f.Increment)) {
+ return http2ConnectionError(http2ErrCodeFlowControl)
+ }
+ cc.cond.Broadcast()
+ return nil
+}
+
+func (rl *http2clientConnReadLoop) processResetStream(f *http2RSTStreamFrame) error {
+ cs := rl.streamByID(f.StreamID)
+ if cs == nil {
+ // TODO: return error if server tries to RST_STREAM an idle stream
+ return nil
+ }
+ serr := http2streamError(cs.ID, f.ErrCode)
+ serr.Cause = http2errFromPeer
+ if f.ErrCode == http2ErrCodeProtocol {
+ rl.cc.SetDoNotReuse()
+ }
+ if fn := cs.cc.t.CountError; fn != nil {
+ fn("recv_rststream_" + f.ErrCode.stringToken())
+ }
+ cs.abortStream(serr)
+
+ cs.bufPipe.CloseWithError(serr)
+ return nil
+}
+
+// Ping sends a PING frame to the server and waits for the ack.
+func (cc *http2ClientConn) Ping(ctx context.Context) error {
+ c := make(chan struct{})
+ // Generate a random payload
+ var p [8]byte
+ for {
+ if _, err := rand.Read(p[:]); err != nil {
+ return err
+ }
+ cc.mu.Lock()
+ // check for dup before insert
+ if _, found := cc.pings[p]; !found {
+ cc.pings[p] = c
+ cc.mu.Unlock()
+ break
+ }
+ cc.mu.Unlock()
+ }
+ errc := make(chan error, 1)
+ go func() {
+ cc.wmu.Lock()
+ defer cc.wmu.Unlock()
+ if err := cc.fr.WritePing(false, p); err != nil {
+ errc <- err
+ return
+ }
+ if err := cc.bw.Flush(); err != nil {
+ errc <- err
+ return
+ }
+ }()
+ select {
+ case <-c:
+ return nil
+ case err := <-errc:
+ return err
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-cc.readerDone:
+ // connection closed
+ return cc.readerErr
+ }
+}
+
+func (rl *http2clientConnReadLoop) processPing(f *http2PingFrame) error {
+ if f.IsAck() {
+ cc := rl.cc
+ cc.mu.Lock()
+ defer cc.mu.Unlock()
+ // If ack, notify listener if any
+ if c, ok := cc.pings[f.Data]; ok {
+ close(c)
+ delete(cc.pings, f.Data)
+ }
+ return nil
+ }
+ cc := rl.cc
+ cc.wmu.Lock()
+ defer cc.wmu.Unlock()
+ if err := cc.fr.WritePing(true, f.Data); err != nil {
+ return err
+ }
+ return cc.bw.Flush()
+}
+
+func (rl *http2clientConnReadLoop) processPushPromise(f *http2PushPromiseFrame) error {
+ // We told the peer we don't want them.
+ // Spec says:
+ // "PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH
+ // setting of the peer endpoint is set to 0. An endpoint that
+ // has set this setting and has received acknowledgement MUST
+ // treat the receipt of a PUSH_PROMISE frame as a connection
+ // error (Section 5.4.1) of type PROTOCOL_ERROR."
+ return http2ConnectionError(http2ErrCodeProtocol)
+}
+
+func (cc *http2ClientConn) writeStreamReset(streamID uint32, code http2ErrCode, err error) {
+ // TODO: map err to more interesting error codes, once the
+ // HTTP community comes up with some. But currently for
+ // RST_STREAM there's no equivalent to GOAWAY frame's debug
+ // data, and the error codes are all pretty vague ("cancel").
+ cc.wmu.Lock()
+ cc.fr.WriteRSTStream(streamID, code)
+ cc.bw.Flush()
+ cc.wmu.Unlock()
+}
+
+var (
+ http2errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit")
+ http2errRequestHeaderListSize = errors.New("http2: request header list larger than peer's advertised limit")
+)
+
+func (cc *http2ClientConn) logf(format string, args ...interface{}) {
+ cc.t.logf(format, args...)
+}
+
+func (cc *http2ClientConn) vlogf(format string, args ...interface{}) {
+ cc.t.vlogf(format, args...)
+}
+
+func (t *http2Transport) vlogf(format string, args ...interface{}) {
+ if http2VerboseLogs {
+ t.logf(format, args...)
+ }
+}
+
+func (t *http2Transport) logf(format string, args ...interface{}) {
+ log.Printf(format, args...)
+}
+
+var http2noBody io.ReadCloser = http2noBodyReader{}
+
+type http2noBodyReader struct{}
+
+func (http2noBodyReader) Close() error { return nil }
+
+func (http2noBodyReader) Read([]byte) (int, error) { return 0, io.EOF }
+
+type http2missingBody struct{}
+
+func (http2missingBody) Close() error { return nil }
+
+func (http2missingBody) Read([]byte) (int, error) { return 0, io.ErrUnexpectedEOF }
+
+func http2strSliceContains(ss []string, s string) bool {
+ for _, v := range ss {
+ if v == s {
+ return true
+ }
+ }
+ return false
+}
+
+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
+// call gzip.NewReader on the first call to Read
+type http2gzipReader struct {
+ _ http2incomparable
+ body io.ReadCloser // underlying Response.Body
+ zr *gzip.Reader // lazily-initialized gzip reader
+ zerr error // sticky error
+}
+
+func (gz *http2gzipReader) Read(p []byte) (n int, err error) {
+ if gz.zerr != nil {
+ return 0, gz.zerr
+ }
+ if gz.zr == nil {
+ gz.zr, err = gzip.NewReader(gz.body)
+ if err != nil {
+ gz.zerr = err
+ return 0, err
+ }
+ }
+ return gz.zr.Read(p)
+}
+
+func (gz *http2gzipReader) Close() error {
+ if err := gz.body.Close(); err != nil {
+ return err
+ }
+ gz.zerr = fs.ErrClosed
+ return nil
+}
+
+type http2errorReader struct{ err error }
+
+func (r http2errorReader) Read(p []byte) (int, error) { return 0, r.err }
+
+// isConnectionCloseRequest reports whether req should use its own
+// connection for a single request and then close the connection.
+func http2isConnectionCloseRequest(req *Request) bool {
+ return req.Close || httpguts.HeaderValuesContainsToken(req.Header["Connection"], "close")
+}
+
+// registerHTTPSProtocol calls Transport.RegisterProtocol but
+// converting panics into errors.
+func http2registerHTTPSProtocol(t *Transport, rt http2noDialH2RoundTripper) (err error) {
+ defer func() {
+ if e := recover(); e != nil {
+ err = fmt.Errorf("%v", e)
+ }
+ }()
+ t.RegisterProtocol("https", rt)
+ return nil
+}
+
+// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
+// if there's already has a cached connection to the host.
+// (The field is exported so it can be accessed via reflect from net/http; tested
+// by TestNoDialH2RoundTripperType)
+type http2noDialH2RoundTripper struct{ *http2Transport }
+
+func (rt http2noDialH2RoundTripper) RoundTrip(req *Request) (*Response, error) {
+ res, err := rt.http2Transport.RoundTrip(req)
+ if http2isNoCachedConnError(err) {
+ return nil, ErrSkipAltProtocol
+ }
+ return res, err
+}
+
+func (t *http2Transport) idleConnTimeout() time.Duration {
+ if t.t1 != nil {
+ return t.t1.IdleConnTimeout
+ }
+ return 0
+}
+
+func http2traceGetConn(req *Request, hostPort string) {
+ trace := httptrace.ContextClientTrace(req.Context())
+ if trace == nil || trace.GetConn == nil {
+ return
+ }
+ trace.GetConn(hostPort)
+}
+
+func http2traceGotConn(req *Request, cc *http2ClientConn, reused bool) {
+ trace := httptrace.ContextClientTrace(req.Context())
+ if trace == nil || trace.GotConn == nil {
+ return
+ }
+ ci := httptrace.GotConnInfo{Conn: cc.tconn}
+ ci.Reused = reused
+ cc.mu.Lock()
+ ci.WasIdle = len(cc.streams) == 0 && reused
+ if ci.WasIdle && !cc.lastActive.IsZero() {
+ ci.IdleTime = time.Since(cc.lastActive)
+ }
+ cc.mu.Unlock()
+
+ trace.GotConn(ci)
+}
+
+func http2traceWroteHeaders(trace *httptrace.ClientTrace) {
+ if trace != nil && trace.WroteHeaders != nil {
+ trace.WroteHeaders()
+ }
+}
+
+func http2traceGot100Continue(trace *httptrace.ClientTrace) {
+ if trace != nil && trace.Got100Continue != nil {
+ trace.Got100Continue()
+ }
+}
+
+func http2traceWait100Continue(trace *httptrace.ClientTrace) {
+ if trace != nil && trace.Wait100Continue != nil {
+ trace.Wait100Continue()
+ }
+}
+
+func http2traceWroteRequest(trace *httptrace.ClientTrace, err error) {
+ if trace != nil && trace.WroteRequest != nil {
+ trace.WroteRequest(httptrace.WroteRequestInfo{Err: err})
+ }
+}
+
+func http2traceFirstResponseByte(trace *httptrace.ClientTrace) {
+ if trace != nil && trace.GotFirstResponseByte != nil {
+ trace.GotFirstResponseByte()
+ }
+}
+
+// writeFramer is implemented by any type that is used to write frames.
+type http2writeFramer interface {
+ writeFrame(http2writeContext) error
+
+ // staysWithinBuffer reports whether this writer promises that
+ // it will only write less than or equal to size bytes, and it
+ // won't Flush the write context.
+ staysWithinBuffer(size int) bool
+}
+
+// writeContext is the interface needed by the various frame writer
+// types below. All the writeFrame methods below are scheduled via the
+// frame writing scheduler (see writeScheduler in writesched.go).
+//
+// This interface is implemented by *serverConn.
+//
+// TODO: decide whether to a) use this in the client code (which didn't
+// end up using this yet, because it has a simpler design, not
+// currently implementing priorities), or b) delete this and
+// make the server code a bit more concrete.
+type http2writeContext interface {
+ Framer() *http2Framer
+ Flush() error
+ CloseConn() error
+ // HeaderEncoder returns an HPACK encoder that writes to the
+ // returned buffer.
+ HeaderEncoder() (*hpack.Encoder, *bytes.Buffer)
+}
+
+// writeEndsStream reports whether w writes a frame that will transition
+// the stream to a half-closed local state. This returns false for RST_STREAM,
+// which closes the entire stream (not just the local half).
+func http2writeEndsStream(w http2writeFramer) bool {
+ switch v := w.(type) {
+ case *http2writeData:
+ return v.endStream
+ case *http2writeResHeaders:
+ return v.endStream
+ case nil:
+ // This can only happen if the caller reuses w after it's
+ // been intentionally nil'ed out to prevent use. Keep this
+ // here to catch future refactoring breaking it.
+ panic("writeEndsStream called on nil writeFramer")
+ }
+ return false
+}
+
+type http2flushFrameWriter struct{}
+
+func (http2flushFrameWriter) writeFrame(ctx http2writeContext) error {
+ return ctx.Flush()
+}
+
+func (http2flushFrameWriter) staysWithinBuffer(max int) bool { return false }
+
+type http2writeSettings []http2Setting
+
+func (s http2writeSettings) staysWithinBuffer(max int) bool {
+ const settingSize = 6 // uint16 + uint32
+ return http2frameHeaderLen+settingSize*len(s) <= max
+
+}
+
+func (s http2writeSettings) writeFrame(ctx http2writeContext) error {
+ return ctx.Framer().WriteSettings([]http2Setting(s)...)
+}
+
+type http2writeGoAway struct {
+ maxStreamID uint32
+ code http2ErrCode
+}
+
+func (p *http2writeGoAway) writeFrame(ctx http2writeContext) error {
+ err := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil)
+ ctx.Flush() // ignore error: we're hanging up on them anyway
+ return err
+}
+
+func (*http2writeGoAway) staysWithinBuffer(max int) bool { return false } // flushes
+
+type http2writeData struct {
+ streamID uint32
+ p []byte
+ endStream bool
+}
+
+func (w *http2writeData) String() string {
+ return fmt.Sprintf("writeData(stream=%d, p=%d, endStream=%v)", w.streamID, len(w.p), w.endStream)
+}
+
+func (w *http2writeData) writeFrame(ctx http2writeContext) error {
+ return ctx.Framer().WriteData(w.streamID, w.endStream, w.p)
+}
+
+func (w *http2writeData) staysWithinBuffer(max int) bool {
+ return http2frameHeaderLen+len(w.p) <= max
+}
+
+// handlerPanicRST is the message sent from handler goroutines when
+// the handler panics.
+type http2handlerPanicRST struct {
+ StreamID uint32
+}
+
+func (hp http2handlerPanicRST) writeFrame(ctx http2writeContext) error {
+ return ctx.Framer().WriteRSTStream(hp.StreamID, http2ErrCodeInternal)
+}
+
+func (hp http2handlerPanicRST) staysWithinBuffer(max int) bool { return http2frameHeaderLen+4 <= max }
+
+func (se http2StreamError) writeFrame(ctx http2writeContext) error {
+ return ctx.Framer().WriteRSTStream(se.StreamID, se.Code)
+}
+
+func (se http2StreamError) staysWithinBuffer(max int) bool { return http2frameHeaderLen+4 <= max }
+
+type http2writePingAck struct{ pf *http2PingFrame }
+
+func (w http2writePingAck) writeFrame(ctx http2writeContext) error {
+ return ctx.Framer().WritePing(true, w.pf.Data)
+}
+
+func (w http2writePingAck) staysWithinBuffer(max int) bool {
+ return http2frameHeaderLen+len(w.pf.Data) <= max
+}
+
+type http2writeSettingsAck struct{}
+
+func (http2writeSettingsAck) writeFrame(ctx http2writeContext) error {
+ return ctx.Framer().WriteSettingsAck()
+}
+
+func (http2writeSettingsAck) staysWithinBuffer(max int) bool { return http2frameHeaderLen <= max }
+
+// splitHeaderBlock splits headerBlock into fragments so that each fragment fits
+// in a single frame, then calls fn for each fragment. firstFrag/lastFrag are true
+// for the first/last fragment, respectively.
+func http2splitHeaderBlock(ctx http2writeContext, headerBlock []byte, fn func(ctx http2writeContext, frag []byte, firstFrag, lastFrag bool) error) error {
+ // For now we're lazy and just pick the minimum MAX_FRAME_SIZE
+ // that all peers must support (16KB). Later we could care
+ // more and send larger frames if the peer advertised it, but
+ // there's little point. Most headers are small anyway (so we
+ // generally won't have CONTINUATION frames), and extra frames
+ // only waste 9 bytes anyway.
+ const maxFrameSize = 16384
+
+ first := true
+ for len(headerBlock) > 0 {
+ frag := headerBlock
+ if len(frag) > maxFrameSize {
+ frag = frag[:maxFrameSize]
+ }
+ headerBlock = headerBlock[len(frag):]
+ if err := fn(ctx, frag, first, len(headerBlock) == 0); err != nil {
+ return err
+ }
+ first = false
+ }
+ return nil
+}
+
+// writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames
+// for HTTP response headers or trailers from a server handler.
+type http2writeResHeaders struct {
+ streamID uint32
+ httpResCode int // 0 means no ":status" line
+ h Header // may be nil
+ trailers []string // if non-nil, which keys of h to write. nil means all.
+ endStream bool
+
+ date string
+ contentType string
+ contentLength string
+}
+
+func http2encKV(enc *hpack.Encoder, k, v string) {
+ if http2VerboseLogs {
+ log.Printf("http2: server encoding header %q = %q", k, v)
+ }
+ enc.WriteField(hpack.HeaderField{Name: k, Value: v})
+}
+
+func (w *http2writeResHeaders) staysWithinBuffer(max int) bool {
+ // TODO: this is a common one. It'd be nice to return true
+ // here and get into the fast path if we could be clever and
+ // calculate the size fast enough, or at least a conservative
+ // upper bound that usually fires. (Maybe if w.h and
+ // w.trailers are nil, so we don't need to enumerate it.)
+ // Otherwise I'm afraid that just calculating the length to
+ // answer this question would be slower than the ~2µs benefit.
+ return false
+}
+
+func (w *http2writeResHeaders) writeFrame(ctx http2writeContext) error {
+ enc, buf := ctx.HeaderEncoder()
+ buf.Reset()
+
+ if w.httpResCode != 0 {
+ http2encKV(enc, ":status", http2httpCodeString(w.httpResCode))
+ }
+
+ http2encodeHeaders(enc, w.h, w.trailers)
+
+ if w.contentType != "" {
+ http2encKV(enc, "content-type", w.contentType)
+ }
+ if w.contentLength != "" {
+ http2encKV(enc, "content-length", w.contentLength)
+ }
+ if w.date != "" {
+ http2encKV(enc, "date", w.date)
+ }
+
+ headerBlock := buf.Bytes()
+ if len(headerBlock) == 0 && w.trailers == nil {
+ panic("unexpected empty hpack")
+ }
+
+ return http2splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock)
+}
+
+func (w *http2writeResHeaders) writeHeaderBlock(ctx http2writeContext, frag []byte, firstFrag, lastFrag bool) error {
+ if firstFrag {
+ return ctx.Framer().WriteHeaders(http2HeadersFrameParam{
+ StreamID: w.streamID,
+ BlockFragment: frag,
+ EndStream: w.endStream,
+ EndHeaders: lastFrag,
+ })
+ } else {
+ return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag)
+ }
+}
+
+// writePushPromise is a request to write a PUSH_PROMISE and 0+ CONTINUATION frames.
+type http2writePushPromise struct {
+ streamID uint32 // pusher stream
+ method string // for :method
+ url *url.URL // for :scheme, :authority, :path
+ h Header
+
+ // Creates an ID for a pushed stream. This runs on serveG just before
+ // the frame is written. The returned ID is copied to promisedID.
+ allocatePromisedID func() (uint32, error)
+ promisedID uint32
+}
+
+func (w *http2writePushPromise) staysWithinBuffer(max int) bool {
+ // TODO: see writeResHeaders.staysWithinBuffer
+ return false
+}
+
+func (w *http2writePushPromise) writeFrame(ctx http2writeContext) error {
+ enc, buf := ctx.HeaderEncoder()
+ buf.Reset()
+
+ http2encKV(enc, ":method", w.method)
+ http2encKV(enc, ":scheme", w.url.Scheme)
+ http2encKV(enc, ":authority", w.url.Host)
+ http2encKV(enc, ":path", w.url.RequestURI())
+ http2encodeHeaders(enc, w.h, nil)
+
+ headerBlock := buf.Bytes()
+ if len(headerBlock) == 0 {
+ panic("unexpected empty hpack")
+ }
+
+ return http2splitHeaderBlock(ctx, headerBlock, w.writeHeaderBlock)
+}
+
+func (w *http2writePushPromise) writeHeaderBlock(ctx http2writeContext, frag []byte, firstFrag, lastFrag bool) error {
+ if firstFrag {
+ return ctx.Framer().WritePushPromise(http2PushPromiseParam{
+ StreamID: w.streamID,
+ PromiseID: w.promisedID,
+ BlockFragment: frag,
+ EndHeaders: lastFrag,
+ })
+ } else {
+ return ctx.Framer().WriteContinuation(w.streamID, lastFrag, frag)
+ }
+}
+
+type http2write100ContinueHeadersFrame struct {
+ streamID uint32
+}
+
+func (w http2write100ContinueHeadersFrame) writeFrame(ctx http2writeContext) error {
+ enc, buf := ctx.HeaderEncoder()
+ buf.Reset()
+ http2encKV(enc, ":status", "100")
+ return ctx.Framer().WriteHeaders(http2HeadersFrameParam{
+ StreamID: w.streamID,
+ BlockFragment: buf.Bytes(),
+ EndStream: false,
+ EndHeaders: true,
+ })
+}
+
+func (w http2write100ContinueHeadersFrame) staysWithinBuffer(max int) bool {
+ // Sloppy but conservative:
+ return 9+2*(len(":status")+len("100")) <= max
+}
+
+type http2writeWindowUpdate struct {
+ streamID uint32 // or 0 for conn-level
+ n uint32
+}
+
+func (wu http2writeWindowUpdate) staysWithinBuffer(max int) bool { return http2frameHeaderLen+4 <= max }
+
+func (wu http2writeWindowUpdate) writeFrame(ctx http2writeContext) error {
+ return ctx.Framer().WriteWindowUpdate(wu.streamID, wu.n)
+}
+
+// encodeHeaders encodes an http.Header. If keys is not nil, then (k, h[k])
+// is encoded only if k is in keys.
+func http2encodeHeaders(enc *hpack.Encoder, h Header, keys []string) {
+ if keys == nil {
+ sorter := http2sorterPool.Get().(*http2sorter)
+ // Using defer here, since the returned keys from the
+ // sorter.Keys method is only valid until the sorter
+ // is returned:
+ defer http2sorterPool.Put(sorter)
+ keys = sorter.Keys(h)
+ }
+ for _, k := range keys {
+ vv := h[k]
+ k, ascii := http2lowerHeader(k)
+ if !ascii {
+ // Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
+ // field names have to be ASCII characters (just as in HTTP/1.x).
+ continue
+ }
+ if !http2validWireHeaderFieldName(k) {
+ // Skip it as backup paranoia. Per
+ // golang.org/issue/14048, these should
+ // already be rejected at a higher level.
+ continue
+ }
+ isTE := k == "transfer-encoding"
+ for _, v := range vv {
+ if !httpguts.ValidHeaderFieldValue(v) {
+ // TODO: return an error? golang.org/issue/14048
+ // For now just omit it.
+ continue
+ }
+ // TODO: more of "8.1.2.2 Connection-Specific Header Fields"
+ if isTE && v != "trailers" {
+ continue
+ }
+ http2encKV(enc, k, v)
+ }
+ }
+}
+
+// WriteScheduler is the interface implemented by HTTP/2 write schedulers.
+// Methods are never called concurrently.
+type http2WriteScheduler interface {
+ // OpenStream opens a new stream in the write scheduler.
+ // It is illegal to call this with streamID=0 or with a streamID that is
+ // already open -- the call may panic.
+ OpenStream(streamID uint32, options http2OpenStreamOptions)
+
+ // CloseStream closes a stream in the write scheduler. Any frames queued on
+ // this stream should be discarded. It is illegal to call this on a stream
+ // that is not open -- the call may panic.
+ CloseStream(streamID uint32)
+
+ // AdjustStream adjusts the priority of the given stream. This may be called
+ // on a stream that has not yet been opened or has been closed. Note that
+ // RFC 7540 allows PRIORITY frames to be sent on streams in any state. See:
+ // https://tools.ietf.org/html/rfc7540#section-5.1
+ AdjustStream(streamID uint32, priority http2PriorityParam)
+
+ // Push queues a frame in the scheduler. In most cases, this will not be
+ // called with wr.StreamID()!=0 unless that stream is currently open. The one
+ // exception is RST_STREAM frames, which may be sent on idle or closed streams.
+ Push(wr http2FrameWriteRequest)
+
+ // Pop dequeues the next frame to write. Returns false if no frames can
+ // be written. Frames with a given wr.StreamID() are Pop'd in the same
+ // order they are Push'd, except RST_STREAM frames. No frames should be
+ // discarded except by CloseStream.
+ Pop() (wr http2FrameWriteRequest, ok bool)
+}
+
+// OpenStreamOptions specifies extra options for WriteScheduler.OpenStream.
+type http2OpenStreamOptions struct {
+ // PusherID is zero if the stream was initiated by the client. Otherwise,
+ // PusherID names the stream that pushed the newly opened stream.
+ PusherID uint32
+}
+
+// FrameWriteRequest is a request to write a frame.
+type http2FrameWriteRequest struct {
+ // write is the interface value that does the writing, once the
+ // WriteScheduler has selected this frame to write. The write
+ // functions are all defined in write.go.
+ write http2writeFramer
+
+ // stream is the stream on which this frame will be written.
+ // nil for non-stream frames like PING and SETTINGS.
+ // nil for RST_STREAM streams, which use the StreamError.StreamID field instead.
+ stream *http2stream
+
+ // done, if non-nil, must be a buffered channel with space for
+ // 1 message and is sent the return value from write (or an
+ // earlier error) when the frame has been written.
+ done chan error
+}
+
+// StreamID returns the id of the stream this frame will be written to.
+// 0 is used for non-stream frames such as PING and SETTINGS.
+func (wr http2FrameWriteRequest) StreamID() uint32 {
+ if wr.stream == nil {
+ if se, ok := wr.write.(http2StreamError); ok {
+ // (*serverConn).resetStream doesn't set
+ // stream because it doesn't necessarily have
+ // one. So special case this type of write
+ // message.
+ return se.StreamID
+ }
+ return 0
+ }
+ return wr.stream.id
+}
+
+// isControl reports whether wr is a control frame for MaxQueuedControlFrames
+// purposes. That includes non-stream frames and RST_STREAM frames.
+func (wr http2FrameWriteRequest) isControl() bool {
+ return wr.stream == nil
+}
+
+// DataSize returns the number of flow control bytes that must be consumed
+// to write this entire frame. This is 0 for non-DATA frames.
+func (wr http2FrameWriteRequest) DataSize() int {
+ if wd, ok := wr.write.(*http2writeData); ok {
+ return len(wd.p)
+ }
+ return 0
+}
+
+// Consume consumes min(n, available) bytes from this frame, where available
+// is the number of flow control bytes available on the stream. Consume returns
+// 0, 1, or 2 frames, where the integer return value gives the number of frames
+// returned.
+//
+// If flow control prevents consuming any bytes, this returns (_, _, 0). If
+// the entire frame was consumed, this returns (wr, _, 1). Otherwise, this
+// returns (consumed, rest, 2), where 'consumed' contains the consumed bytes and
+// 'rest' contains the remaining bytes. The consumed bytes are deducted from the
+// underlying stream's flow control budget.
+func (wr http2FrameWriteRequest) Consume(n int32) (http2FrameWriteRequest, http2FrameWriteRequest, int) {
+ var empty http2FrameWriteRequest
+
+ // Non-DATA frames are always consumed whole.
+ wd, ok := wr.write.(*http2writeData)
+ if !ok || len(wd.p) == 0 {
+ return wr, empty, 1
+ }
+
+ // Might need to split after applying limits.
+ allowed := wr.stream.flow.available()
+ if n < allowed {
+ allowed = n
+ }
+ if wr.stream.sc.maxFrameSize < allowed {
+ allowed = wr.stream.sc.maxFrameSize
+ }
+ if allowed <= 0 {
+ return empty, empty, 0
+ }
+ if len(wd.p) > int(allowed) {
+ wr.stream.flow.take(allowed)
+ consumed := http2FrameWriteRequest{
+ stream: wr.stream,
+ write: &http2writeData{
+ streamID: wd.streamID,
+ p: wd.p[:allowed],
+ // Even if the original had endStream set, there
+ // are bytes remaining because len(wd.p) > allowed,
+ // so we know endStream is false.
+ endStream: false,
+ },
+ // Our caller is blocking on the final DATA frame, not
+ // this intermediate frame, so no need to wait.
+ done: nil,
+ }
+ rest := http2FrameWriteRequest{
+ stream: wr.stream,
+ write: &http2writeData{
+ streamID: wd.streamID,
+ p: wd.p[allowed:],
+ endStream: wd.endStream,
+ },
+ done: wr.done,
+ }
+ return consumed, rest, 2
+ }
+
+ // The frame is consumed whole.
+ // NB: This cast cannot overflow because allowed is <= math.MaxInt32.
+ wr.stream.flow.take(int32(len(wd.p)))
+ return wr, empty, 1
+}
+
+// String is for debugging only.
+func (wr http2FrameWriteRequest) String() string {
+ var des string
+ if s, ok := wr.write.(fmt.Stringer); ok {
+ des = s.String()
+ } else {
+ des = fmt.Sprintf("%T", wr.write)
+ }
+ return fmt.Sprintf("[FrameWriteRequest stream=%d, ch=%v, writer=%v]", wr.StreamID(), wr.done != nil, des)
+}
+
+// replyToWriter sends err to wr.done and panics if the send must block
+// This does nothing if wr.done is nil.
+func (wr *http2FrameWriteRequest) replyToWriter(err error) {
+ if wr.done == nil {
+ return
+ }
+ select {
+ case wr.done <- err:
+ default:
+ panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wr.write))
+ }
+ wr.write = nil // prevent use (assume it's tainted after wr.done send)
+}
+
+// writeQueue is used by implementations of WriteScheduler.
+type http2writeQueue struct {
+ s []http2FrameWriteRequest
+ prev, next *http2writeQueue
+}
+
+func (q *http2writeQueue) empty() bool { return len(q.s) == 0 }
+
+func (q *http2writeQueue) push(wr http2FrameWriteRequest) {
+ q.s = append(q.s, wr)
+}
+
+func (q *http2writeQueue) shift() http2FrameWriteRequest {
+ if len(q.s) == 0 {
+ panic("invalid use of queue")
+ }
+ wr := q.s[0]
+ // TODO: less copy-happy queue.
+ copy(q.s, q.s[1:])
+ q.s[len(q.s)-1] = http2FrameWriteRequest{}
+ q.s = q.s[:len(q.s)-1]
+ return wr
+}
+
+// consume consumes up to n bytes from q.s[0]. If the frame is
+// entirely consumed, it is removed from the queue. If the frame
+// is partially consumed, the frame is kept with the consumed
+// bytes removed. Returns true iff any bytes were consumed.
+func (q *http2writeQueue) consume(n int32) (http2FrameWriteRequest, bool) {
+ if len(q.s) == 0 {
+ return http2FrameWriteRequest{}, false
+ }
+ consumed, rest, numresult := q.s[0].Consume(n)
+ switch numresult {
+ case 0:
+ return http2FrameWriteRequest{}, false
+ case 1:
+ q.shift()
+ case 2:
+ q.s[0] = rest
+ }
+ return consumed, true
+}
+
+type http2writeQueuePool []*http2writeQueue
+
+// put inserts an unused writeQueue into the pool.
+
+// put inserts an unused writeQueue into the pool.
+func (p *http2writeQueuePool) put(q *http2writeQueue) {
+ for i := range q.s {
+ q.s[i] = http2FrameWriteRequest{}
+ }
+ q.s = q.s[:0]
+ *p = append(*p, q)
+}
+
+// get returns an empty writeQueue.
+func (p *http2writeQueuePool) get() *http2writeQueue {
+ ln := len(*p)
+ if ln == 0 {
+ return new(http2writeQueue)
+ }
+ x := ln - 1
+ q := (*p)[x]
+ (*p)[x] = nil
+ *p = (*p)[:x]
+ return q
+}
+
+// RFC 7540, Section 5.3.5: the default weight is 16.
+const http2priorityDefaultWeight = 15 // 16 = 15 + 1
+
+// PriorityWriteSchedulerConfig configures a priorityWriteScheduler.
+type http2PriorityWriteSchedulerConfig struct {
+ // MaxClosedNodesInTree controls the maximum number of closed streams to
+ // retain in the priority tree. Setting this to zero saves a small amount
+ // of memory at the cost of performance.
+ //
+ // See RFC 7540, Section 5.3.4:
+ // "It is possible for a stream to become closed while prioritization
+ // information ... is in transit. ... This potentially creates suboptimal
+ // prioritization, since the stream could be given a priority that is
+ // different from what is intended. To avoid these problems, an endpoint
+ // SHOULD retain stream prioritization state for a period after streams
+ // become closed. The longer state is retained, the lower the chance that
+ // streams are assigned incorrect or default priority values."
+ MaxClosedNodesInTree int
+
+ // MaxIdleNodesInTree controls the maximum number of idle streams to
+ // retain in the priority tree. Setting this to zero saves a small amount
+ // of memory at the cost of performance.
+ //
+ // See RFC 7540, Section 5.3.4:
+ // Similarly, streams that are in the "idle" state can be assigned
+ // priority or become a parent of other streams. This allows for the
+ // creation of a grouping node in the dependency tree, which enables
+ // more flexible expressions of priority. Idle streams begin with a
+ // default priority (Section 5.3.5).
+ MaxIdleNodesInTree int
+
+ // ThrottleOutOfOrderWrites enables write throttling to help ensure that
+ // data is delivered in priority order. This works around a race where
+ // stream B depends on stream A and both streams are about to call Write
+ // to queue DATA frames. If B wins the race, a naive scheduler would eagerly
+ // write as much data from B as possible, but this is suboptimal because A
+ // is a higher-priority stream. With throttling enabled, we write a small
+ // amount of data from B to minimize the amount of bandwidth that B can
+ // steal from A.
+ ThrottleOutOfOrderWrites bool
+}
+
+// NewPriorityWriteScheduler constructs a WriteScheduler that schedules
+// frames by following HTTP/2 priorities as described in RFC 7540 Section 5.3.
+// If cfg is nil, default options are used.
+func http2NewPriorityWriteScheduler(cfg *http2PriorityWriteSchedulerConfig) http2WriteScheduler {
+ if cfg == nil {
+ // For justification of these defaults, see:
+ // https://docs.google.com/document/d/1oLhNg1skaWD4_DtaoCxdSRN5erEXrH-KnLrMwEpOtFY
+ cfg = &http2PriorityWriteSchedulerConfig{
+ MaxClosedNodesInTree: 10,
+ MaxIdleNodesInTree: 10,
+ ThrottleOutOfOrderWrites: false,
+ }
+ }
+
+ ws := &http2priorityWriteScheduler{
+ nodes: make(map[uint32]*http2priorityNode),
+ maxClosedNodesInTree: cfg.MaxClosedNodesInTree,
+ maxIdleNodesInTree: cfg.MaxIdleNodesInTree,
+ enableWriteThrottle: cfg.ThrottleOutOfOrderWrites,
+ }
+ ws.nodes[0] = &ws.root
+ if cfg.ThrottleOutOfOrderWrites {
+ ws.writeThrottleLimit = 1024
+ } else {
+ ws.writeThrottleLimit = math.MaxInt32
+ }
+ return ws
+}
+
+type http2priorityNodeState int
+
+const (
+ http2priorityNodeOpen http2priorityNodeState = iota
+ http2priorityNodeClosed
+ http2priorityNodeIdle
+)
+
+// priorityNode is a node in an HTTP/2 priority tree.
+// Each node is associated with a single stream ID.
+// See RFC 7540, Section 5.3.
+type http2priorityNode struct {
+ q http2writeQueue // queue of pending frames to write
+ id uint32 // id of the stream, or 0 for the root of the tree
+ weight uint8 // the actual weight is weight+1, so the value is in [1,256]
+ state http2priorityNodeState // open | closed | idle
+ bytes int64 // number of bytes written by this node, or 0 if closed
+ subtreeBytes int64 // sum(node.bytes) of all nodes in this subtree
+
+ // These links form the priority tree.
+ parent *http2priorityNode
+ kids *http2priorityNode // start of the kids list
+ prev, next *http2priorityNode // doubly-linked list of siblings
+}
+
+func (n *http2priorityNode) setParent(parent *http2priorityNode) {
+ if n == parent {
+ panic("setParent to self")
+ }
+ if n.parent == parent {
+ return
+ }
+ // Unlink from current parent.
+ if parent := n.parent; parent != nil {
+ if n.prev == nil {
+ parent.kids = n.next
+ } else {
+ n.prev.next = n.next
+ }
+ if n.next != nil {
+ n.next.prev = n.prev
+ }
+ }
+ // Link to new parent.
+ // If parent=nil, remove n from the tree.
+ // Always insert at the head of parent.kids (this is assumed by walkReadyInOrder).
+ n.parent = parent
+ if parent == nil {
+ n.next = nil
+ n.prev = nil
+ } else {
+ n.next = parent.kids
+ n.prev = nil
+ if n.next != nil {
+ n.next.prev = n
+ }
+ parent.kids = n
+ }
+}
+
+func (n *http2priorityNode) addBytes(b int64) {
+ n.bytes += b
+ for ; n != nil; n = n.parent {
+ n.subtreeBytes += b
+ }
+}
+
+// walkReadyInOrder iterates over the tree in priority order, calling f for each node
+// with a non-empty write queue. When f returns true, this function returns true and the
+// walk halts. tmp is used as scratch space for sorting.
+//
+// f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true
+// if any ancestor p of n is still open (ignoring the root node).
+func (n *http2priorityNode) walkReadyInOrder(openParent bool, tmp *[]*http2priorityNode, f func(*http2priorityNode, bool) bool) bool {
+ if !n.q.empty() && f(n, openParent) {
+ return true
+ }
+ if n.kids == nil {
+ return false
+ }
+
+ // Don't consider the root "open" when updating openParent since
+ // we can't send data frames on the root stream (only control frames).
+ if n.id != 0 {
+ openParent = openParent || (n.state == http2priorityNodeOpen)
+ }
+
+ // Common case: only one kid or all kids have the same weight.
+ // Some clients don't use weights; other clients (like web browsers)
+ // use mostly-linear priority trees.
+ w := n.kids.weight
+ needSort := false
+ for k := n.kids.next; k != nil; k = k.next {
+ if k.weight != w {
+ needSort = true
+ break
+ }
+ }
+ if !needSort {
+ for k := n.kids; k != nil; k = k.next {
+ if k.walkReadyInOrder(openParent, tmp, f) {
+ return true
+ }
+ }
+ return false
+ }
+
+ // Uncommon case: sort the child nodes. We remove the kids from the parent,
+ // then re-insert after sorting so we can reuse tmp for future sort calls.
+ *tmp = (*tmp)[:0]
+ for n.kids != nil {
+ *tmp = append(*tmp, n.kids)
+ n.kids.setParent(nil)
+ }
+ sort.Sort(http2sortPriorityNodeSiblings(*tmp))
+ for i := len(*tmp) - 1; i >= 0; i-- {
+ (*tmp)[i].setParent(n) // setParent inserts at the head of n.kids
+ }
+ for k := n.kids; k != nil; k = k.next {
+ if k.walkReadyInOrder(openParent, tmp, f) {
+ return true
+ }
+ }
+ return false
+}
+
+type http2sortPriorityNodeSiblings []*http2priorityNode
+
+func (z http2sortPriorityNodeSiblings) Len() int { return len(z) }
+
+func (z http2sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] }
+
+func (z http2sortPriorityNodeSiblings) Less(i, k int) bool {
+ // Prefer the subtree that has sent fewer bytes relative to its weight.
+ // See sections 5.3.2 and 5.3.4.
+ wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes)
+ wk, bk := float64(z[k].weight+1), float64(z[k].subtreeBytes)
+ if bi == 0 && bk == 0 {
+ return wi >= wk
+ }
+ if bk == 0 {
+ return false
+ }
+ return bi/bk <= wi/wk
+}
+
+type http2priorityWriteScheduler struct {
+ // root is the root of the priority tree, where root.id = 0.
+ // The root queues control frames that are not associated with any stream.
+ root http2priorityNode
+
+ // nodes maps stream ids to priority tree nodes.
+ nodes map[uint32]*http2priorityNode
+
+ // maxID is the maximum stream id in nodes.
+ maxID uint32
+
+ // lists of nodes that have been closed or are idle, but are kept in
+ // the tree for improved prioritization. When the lengths exceed either
+ // maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded.
+ closedNodes, idleNodes []*http2priorityNode
+
+ // From the config.
+ maxClosedNodesInTree int
+ maxIdleNodesInTree int
+ writeThrottleLimit int32
+ enableWriteThrottle bool
+
+ // tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations.
+ tmp []*http2priorityNode
+
+ // pool of empty queues for reuse.
+ queuePool http2writeQueuePool
+}
+
+func (ws *http2priorityWriteScheduler) OpenStream(streamID uint32, options http2OpenStreamOptions) {
+ // The stream may be currently idle but cannot be opened or closed.
+ if curr := ws.nodes[streamID]; curr != nil {
+ if curr.state != http2priorityNodeIdle {
+ panic(fmt.Sprintf("stream %d already opened", streamID))
+ }
+ curr.state = http2priorityNodeOpen
+ return
+ }
+
+ // RFC 7540, Section 5.3.5:
+ // "All streams are initially assigned a non-exclusive dependency on stream 0x0.
+ // Pushed streams initially depend on their associated stream. In both cases,
+ // streams are assigned a default weight of 16."
+ parent := ws.nodes[options.PusherID]
+ if parent == nil {
+ parent = &ws.root
+ }
+ n := &http2priorityNode{
+ q: *ws.queuePool.get(),
+ id: streamID,
+ weight: http2priorityDefaultWeight,
+ state: http2priorityNodeOpen,
+ }
+ n.setParent(parent)
+ ws.nodes[streamID] = n
+ if streamID > ws.maxID {
+ ws.maxID = streamID
+ }
+}
+
+func (ws *http2priorityWriteScheduler) CloseStream(streamID uint32) {
+ if streamID == 0 {
+ panic("violation of WriteScheduler interface: cannot close stream 0")
+ }
+ if ws.nodes[streamID] == nil {
+ panic(fmt.Sprintf("violation of WriteScheduler interface: unknown stream %d", streamID))
+ }
+ if ws.nodes[streamID].state != http2priorityNodeOpen {
+ panic(fmt.Sprintf("violation of WriteScheduler interface: stream %d already closed", streamID))
+ }
+
+ n := ws.nodes[streamID]
+ n.state = http2priorityNodeClosed
+ n.addBytes(-n.bytes)
+
+ q := n.q
+ ws.queuePool.put(&q)
+ n.q.s = nil
+ if ws.maxClosedNodesInTree > 0 {
+ ws.addClosedOrIdleNode(&ws.closedNodes, ws.maxClosedNodesInTree, n)
+ } else {
+ ws.removeNode(n)
+ }
+}
+
+func (ws *http2priorityWriteScheduler) AdjustStream(streamID uint32, priority http2PriorityParam) {
+ if streamID == 0 {
+ panic("adjustPriority on root")
+ }
+
+ // If streamID does not exist, there are two cases:
+ // - A closed stream that has been removed (this will have ID <= maxID)
+ // - An idle stream that is being used for "grouping" (this will have ID > maxID)
+ n := ws.nodes[streamID]
+ if n == nil {
+ if streamID <= ws.maxID || ws.maxIdleNodesInTree == 0 {
+ return
+ }
+ ws.maxID = streamID
+ n = &http2priorityNode{
+ q: *ws.queuePool.get(),
+ id: streamID,
+ weight: http2priorityDefaultWeight,
+ state: http2priorityNodeIdle,
+ }
+ n.setParent(&ws.root)
+ ws.nodes[streamID] = n
+ ws.addClosedOrIdleNode(&ws.idleNodes, ws.maxIdleNodesInTree, n)
+ }
+
+ // Section 5.3.1: A dependency on a stream that is not currently in the tree
+ // results in that stream being given a default priority (Section 5.3.5).
+ parent := ws.nodes[priority.StreamDep]
+ if parent == nil {
+ n.setParent(&ws.root)
+ n.weight = http2priorityDefaultWeight
+ return
+ }
+
+ // Ignore if the client tries to make a node its own parent.
+ if n == parent {
+ return
+ }
+
+ // Section 5.3.3:
+ // "If a stream is made dependent on one of its own dependencies, the
+ // formerly dependent stream is first moved to be dependent on the
+ // reprioritized stream's previous parent. The moved dependency retains
+ // its weight."
+ //
+ // That is: if parent depends on n, move parent to depend on n.parent.
+ for x := parent.parent; x != nil; x = x.parent {
+ if x == n {
+ parent.setParent(n.parent)
+ break
+ }
+ }
+
+ // Section 5.3.3: The exclusive flag causes the stream to become the sole
+ // dependency of its parent stream, causing other dependencies to become
+ // dependent on the exclusive stream.
+ if priority.Exclusive {
+ k := parent.kids
+ for k != nil {
+ next := k.next
+ if k != n {
+ k.setParent(n)
+ }
+ k = next
+ }
+ }
+
+ n.setParent(parent)
+ n.weight = priority.Weight
+}
+
+func (ws *http2priorityWriteScheduler) Push(wr http2FrameWriteRequest) {
+ var n *http2priorityNode
+ if wr.isControl() {
+ n = &ws.root
+ } else {
+ id := wr.StreamID()
+ n = ws.nodes[id]
+ if n == nil {
+ // id is an idle or closed stream. wr should not be a HEADERS or
+ // DATA frame. In other case, we push wr onto the root, rather
+ // than creating a new priorityNode.
+ if wr.DataSize() > 0 {
+ panic("add DATA on non-open stream")
+ }
+ n = &ws.root
+ }
+ }
+ n.q.push(wr)
+}
+
+func (ws *http2priorityWriteScheduler) Pop() (wr http2FrameWriteRequest, ok bool) {
+ ws.root.walkReadyInOrder(false, &ws.tmp, func(n *http2priorityNode, openParent bool) bool {
+ limit := int32(math.MaxInt32)
+ if openParent {
+ limit = ws.writeThrottleLimit
+ }
+ wr, ok = n.q.consume(limit)
+ if !ok {
+ return false
+ }
+ n.addBytes(int64(wr.DataSize()))
+ // If B depends on A and B continuously has data available but A
+ // does not, gradually increase the throttling limit to allow B to
+ // steal more and more bandwidth from A.
+ if openParent {
+ ws.writeThrottleLimit += 1024
+ if ws.writeThrottleLimit < 0 {
+ ws.writeThrottleLimit = math.MaxInt32
+ }
+ } else if ws.enableWriteThrottle {
+ ws.writeThrottleLimit = 1024
+ }
+ return true
+ })
+ return wr, ok
+}
+
+func (ws *http2priorityWriteScheduler) addClosedOrIdleNode(list *[]*http2priorityNode, maxSize int, n *http2priorityNode) {
+ if maxSize == 0 {
+ return
+ }
+ if len(*list) == maxSize {
+ // Remove the oldest node, then shift left.
+ ws.removeNode((*list)[0])
+ x := (*list)[1:]
+ copy(*list, x)
+ *list = (*list)[:len(x)]
+ }
+ *list = append(*list, n)
+}
+
+func (ws *http2priorityWriteScheduler) removeNode(n *http2priorityNode) {
+ for k := n.kids; k != nil; k = k.next {
+ k.setParent(n.parent)
+ }
+ n.setParent(nil)
+ delete(ws.nodes, n.id)
+}
+
+// NewRandomWriteScheduler constructs a WriteScheduler that ignores HTTP/2
+// priorities. Control frames like SETTINGS and PING are written before DATA
+// frames, but if no control frames are queued and multiple streams have queued
+// HEADERS or DATA frames, Pop selects a ready stream arbitrarily.
+func http2NewRandomWriteScheduler() http2WriteScheduler {
+ return &http2randomWriteScheduler{sq: make(map[uint32]*http2writeQueue)}
+}
+
+type http2randomWriteScheduler struct {
+ // zero are frames not associated with a specific stream.
+ zero http2writeQueue
+
+ // sq contains the stream-specific queues, keyed by stream ID.
+ // When a stream is idle, closed, or emptied, it's deleted
+ // from the map.
+ sq map[uint32]*http2writeQueue
+
+ // pool of empty queues for reuse.
+ queuePool http2writeQueuePool
+}
+
+func (ws *http2randomWriteScheduler) OpenStream(streamID uint32, options http2OpenStreamOptions) {
+ // no-op: idle streams are not tracked
+}
+
+func (ws *http2randomWriteScheduler) CloseStream(streamID uint32) {
+ q, ok := ws.sq[streamID]
+ if !ok {
+ return
+ }
+ delete(ws.sq, streamID)
+ ws.queuePool.put(q)
+}
+
+func (ws *http2randomWriteScheduler) AdjustStream(streamID uint32, priority http2PriorityParam) {
+ // no-op: priorities are ignored
+}
+
+func (ws *http2randomWriteScheduler) Push(wr http2FrameWriteRequest) {
+ if wr.isControl() {
+ ws.zero.push(wr)
+ return
+ }
+ id := wr.StreamID()
+ q, ok := ws.sq[id]
+ if !ok {
+ q = ws.queuePool.get()
+ ws.sq[id] = q
+ }
+ q.push(wr)
+}
+
+func (ws *http2randomWriteScheduler) Pop() (http2FrameWriteRequest, bool) {
+ // Control and RST_STREAM frames first.
+ if !ws.zero.empty() {
+ return ws.zero.shift(), true
+ }
+ // Iterate over all non-idle streams until finding one that can be consumed.
+ for streamID, q := range ws.sq {
+ if wr, ok := q.consume(math.MaxInt32); ok {
+ if q.empty() {
+ delete(ws.sq, streamID)
+ ws.queuePool.put(q)
+ }
+ return wr, true
+ }
+ }
+ return http2FrameWriteRequest{}, false
+}
+
+type http2roundRobinWriteScheduler struct {
+ // control contains control frames (SETTINGS, PING, etc.).
+ control http2writeQueue
+
+ // streams maps stream ID to a queue.
+ streams map[uint32]*http2writeQueue
+
+ // stream queues are stored in a circular linked list.
+ // head is the next stream to write, or nil if there are no streams open.
+ head *http2writeQueue
+
+ // pool of empty queues for reuse.
+ queuePool http2writeQueuePool
+}
+
+// newRoundRobinWriteScheduler constructs a new write scheduler.
+// The round robin scheduler priorizes control frames
+// like SETTINGS and PING over DATA frames.
+// When there are no control frames to send, it performs a round-robin
+// selection from the ready streams.
+func http2newRoundRobinWriteScheduler() http2WriteScheduler {
+ ws := &http2roundRobinWriteScheduler{
+ streams: make(map[uint32]*http2writeQueue),
+ }
+ return ws
+}
+
+func (ws *http2roundRobinWriteScheduler) OpenStream(streamID uint32, options http2OpenStreamOptions) {
+ if ws.streams[streamID] != nil {
+ panic(fmt.Errorf("stream %d already opened", streamID))
+ }
+ q := ws.queuePool.get()
+ ws.streams[streamID] = q
+ if ws.head == nil {
+ ws.head = q
+ q.next = q
+ q.prev = q
+ } else {
+ // Queues are stored in a ring.
+ // Insert the new stream before ws.head, putting it at the end of the list.
+ q.prev = ws.head.prev
+ q.next = ws.head
+ q.prev.next = q
+ q.next.prev = q
+ }
+}
+
+func (ws *http2roundRobinWriteScheduler) CloseStream(streamID uint32) {
+ q := ws.streams[streamID]
+ if q == nil {
+ return
+ }
+ if q.next == q {
+ // This was the only open stream.
+ ws.head = nil
+ } else {
+ q.prev.next = q.next
+ q.next.prev = q.prev
+ if ws.head == q {
+ ws.head = q.next
+ }
+ }
+ delete(ws.streams, streamID)
+ ws.queuePool.put(q)
+}
+
+func (ws *http2roundRobinWriteScheduler) AdjustStream(streamID uint32, priority http2PriorityParam) {}
+
+func (ws *http2roundRobinWriteScheduler) Push(wr http2FrameWriteRequest) {
+ if wr.isControl() {
+ ws.control.push(wr)
+ return
+ }
+ q := ws.streams[wr.StreamID()]
+ if q == nil {
+ // This is a closed stream.
+ // wr should not be a HEADERS or DATA frame.
+ // We push the request onto the control queue.
+ if wr.DataSize() > 0 {
+ panic("add DATA on non-open stream")
+ }
+ ws.control.push(wr)
+ return
+ }
+ q.push(wr)
+}
+
+func (ws *http2roundRobinWriteScheduler) Pop() (http2FrameWriteRequest, bool) {
+ // Control and RST_STREAM frames first.
+ if !ws.control.empty() {
+ return ws.control.shift(), true
+ }
+ if ws.head == nil {
+ return http2FrameWriteRequest{}, false
+ }
+ q := ws.head
+ for {
+ if wr, ok := q.consume(math.MaxInt32); ok {
+ ws.head = q.next
+ return wr, true
+ }
+ q = q.next
+ if q == ws.head {
+ break
+ }
+ }
+ return http2FrameWriteRequest{}, false
+}
diff --git a/contrib/go/_std_1.20/src/net/http/h2_error.go b/contrib/go/_std_1.21/src/net/http/h2_error.go
index 0391d31e5b..0391d31e5b 100644
--- a/contrib/go/_std_1.20/src/net/http/h2_error.go
+++ b/contrib/go/_std_1.21/src/net/http/h2_error.go
diff --git a/contrib/go/_std_1.20/src/net/http/header.go b/contrib/go/_std_1.21/src/net/http/header.go
index e0b342c63c..e0b342c63c 100644
--- a/contrib/go/_std_1.20/src/net/http/header.go
+++ b/contrib/go/_std_1.21/src/net/http/header.go
diff --git a/contrib/go/_std_1.21/src/net/http/http.go b/contrib/go/_std_1.21/src/net/http/http.go
new file mode 100644
index 0000000000..9b81654fcc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/http.go
@@ -0,0 +1,165 @@
+// Copyright 2016 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.
+
+//go:generate bundle -o=h2_bundle.go -prefix=http2 -tags=!nethttpomithttp2 golang.org/x/net/http2
+
+package http
+
+import (
+ "io"
+ "strconv"
+ "strings"
+ "time"
+ "unicode/utf8"
+
+ "golang.org/x/net/http/httpguts"
+)
+
+// incomparable is a zero-width, non-comparable type. Adding it to a struct
+// makes that struct also non-comparable, and generally doesn't add
+// any size (as long as it's first).
+type incomparable [0]func()
+
+// maxInt64 is the effective "infinite" value for the Server and
+// Transport's byte-limiting readers.
+const maxInt64 = 1<<63 - 1
+
+// aLongTimeAgo is a non-zero time, far in the past, used for
+// immediate cancellation of network operations.
+var aLongTimeAgo = time.Unix(1, 0)
+
+// omitBundledHTTP2 is set by omithttp2.go when the nethttpomithttp2
+// build tag is set. That means h2_bundle.go isn't compiled in and we
+// shouldn't try to use it.
+var omitBundledHTTP2 bool
+
+// TODO(bradfitz): move common stuff here. The other files have accumulated
+// generic http stuff in random places.
+
+// contextKey is a value for use with context.WithValue. It's used as
+// a pointer so it fits in an interface{} without allocation.
+type contextKey struct {
+ name string
+}
+
+func (k *contextKey) String() string { return "net/http context value " + k.name }
+
+// Given a string of the form "host", "host:port", or "[ipv6::address]:port",
+// return true if the string includes a port.
+func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
+
+// removeEmptyPort strips the empty port in ":port" to ""
+// as mandated by RFC 3986 Section 6.2.3.
+func removeEmptyPort(host string) string {
+ if hasPort(host) {
+ return strings.TrimSuffix(host, ":")
+ }
+ return host
+}
+
+func isNotToken(r rune) bool {
+ return !httpguts.IsTokenRune(r)
+}
+
+// stringContainsCTLByte reports whether s contains any ASCII control character.
+func stringContainsCTLByte(s string) bool {
+ for i := 0; i < len(s); i++ {
+ b := s[i]
+ if b < ' ' || b == 0x7f {
+ return true
+ }
+ }
+ return false
+}
+
+func hexEscapeNonASCII(s string) string {
+ newLen := 0
+ for i := 0; i < len(s); i++ {
+ if s[i] >= utf8.RuneSelf {
+ newLen += 3
+ } else {
+ newLen++
+ }
+ }
+ if newLen == len(s) {
+ return s
+ }
+ b := make([]byte, 0, newLen)
+ var pos int
+ for i := 0; i < len(s); i++ {
+ if s[i] >= utf8.RuneSelf {
+ if pos < i {
+ b = append(b, s[pos:i]...)
+ }
+ b = append(b, '%')
+ b = strconv.AppendInt(b, int64(s[i]), 16)
+ pos = i + 1
+ }
+ }
+ if pos < len(s) {
+ b = append(b, s[pos:]...)
+ }
+ return string(b)
+}
+
+// NoBody is an io.ReadCloser with no bytes. Read always returns EOF
+// and Close always returns nil. It can be used in an outgoing client
+// request to explicitly signal that a request has zero bytes.
+// An alternative, however, is to simply set Request.Body to nil.
+var NoBody = noBody{}
+
+type noBody struct{}
+
+func (noBody) Read([]byte) (int, error) { return 0, io.EOF }
+func (noBody) Close() error { return nil }
+func (noBody) WriteTo(io.Writer) (int64, error) { return 0, nil }
+
+var (
+ // verify that an io.Copy from NoBody won't require a buffer:
+ _ io.WriterTo = NoBody
+ _ io.ReadCloser = NoBody
+)
+
+// PushOptions describes options for Pusher.Push.
+type PushOptions struct {
+ // Method specifies the HTTP method for the promised request.
+ // If set, it must be "GET" or "HEAD". Empty means "GET".
+ Method string
+
+ // Header specifies additional promised request headers. This cannot
+ // include HTTP/2 pseudo header fields like ":path" and ":scheme",
+ // which will be added automatically.
+ Header Header
+}
+
+// Pusher is the interface implemented by ResponseWriters that support
+// HTTP/2 server push. For more background, see
+// https://tools.ietf.org/html/rfc7540#section-8.2.
+type Pusher interface {
+ // Push initiates an HTTP/2 server push. This constructs a synthetic
+ // request using the given target and options, serializes that request
+ // into a PUSH_PROMISE frame, then dispatches that request using the
+ // server's request handler. If opts is nil, default options are used.
+ //
+ // The target must either be an absolute path (like "/path") or an absolute
+ // URL that contains a valid host and the same scheme as the parent request.
+ // If the target is a path, it will inherit the scheme and host of the
+ // parent request.
+ //
+ // The HTTP/2 spec disallows recursive pushes and cross-authority pushes.
+ // Push may or may not detect these invalid pushes; however, invalid
+ // pushes will be detected and canceled by conforming clients.
+ //
+ // Handlers that wish to push URL X should call Push before sending any
+ // data that may trigger a request for URL X. This avoids a race where the
+ // client issues requests for X before receiving the PUSH_PROMISE for X.
+ //
+ // Push will run in a separate goroutine making the order of arrival
+ // non-deterministic. Any required synchronization needs to be implemented
+ // by the caller.
+ //
+ // Push returns ErrNotSupported if the client has disabled push or if push
+ // is not supported on the underlying connection.
+ Push(target string, opts *PushOptions) error
+}
diff --git a/contrib/go/_std_1.20/src/net/http/httptest/httptest.go b/contrib/go/_std_1.21/src/net/http/httptest/httptest.go
index 9bedefd2bc..9bedefd2bc 100644
--- a/contrib/go/_std_1.20/src/net/http/httptest/httptest.go
+++ b/contrib/go/_std_1.21/src/net/http/httptest/httptest.go
diff --git a/contrib/go/_std_1.20/src/net/http/httptest/recorder.go b/contrib/go/_std_1.21/src/net/http/httptest/recorder.go
index 1c1d880155..1c1d880155 100644
--- a/contrib/go/_std_1.20/src/net/http/httptest/recorder.go
+++ b/contrib/go/_std_1.21/src/net/http/httptest/recorder.go
diff --git a/contrib/go/_std_1.20/src/net/http/httptest/server.go b/contrib/go/_std_1.21/src/net/http/httptest/server.go
index f254a494d1..f254a494d1 100644
--- a/contrib/go/_std_1.20/src/net/http/httptest/server.go
+++ b/contrib/go/_std_1.21/src/net/http/httptest/server.go
diff --git a/contrib/go/_std_1.21/src/net/http/httptest/ya.make b/contrib/go/_std_1.21/src/net/http/httptest/ya.make
new file mode 100644
index 0000000000..064b6af6b9
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/httptest/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ httptest.go
+ recorder.go
+ server.go
+)
+
+GO_TEST_SRCS(
+ httptest_test.go
+ recorder_test.go
+ server_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/net/http/httptrace/trace.go b/contrib/go/_std_1.21/src/net/http/httptrace/trace.go
index 6af30f78d1..6af30f78d1 100644
--- a/contrib/go/_std_1.20/src/net/http/httptrace/trace.go
+++ b/contrib/go/_std_1.21/src/net/http/httptrace/trace.go
diff --git a/contrib/go/_std_1.21/src/net/http/httptrace/ya.make b/contrib/go/_std_1.21/src/net/http/httptrace/ya.make
new file mode 100644
index 0000000000..7286a82e55
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/httptrace/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ trace.go
+)
+
+GO_TEST_SRCS(trace_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/net/http/httputil/dump.go b/contrib/go/_std_1.21/src/net/http/httputil/dump.go
index 7affe5e61a..7affe5e61a 100644
--- a/contrib/go/_std_1.20/src/net/http/httputil/dump.go
+++ b/contrib/go/_std_1.21/src/net/http/httputil/dump.go
diff --git a/contrib/go/_std_1.20/src/net/http/httputil/httputil.go b/contrib/go/_std_1.21/src/net/http/httputil/httputil.go
index 09ea74d6d1..09ea74d6d1 100644
--- a/contrib/go/_std_1.20/src/net/http/httputil/httputil.go
+++ b/contrib/go/_std_1.21/src/net/http/httputil/httputil.go
diff --git a/contrib/go/_std_1.20/src/net/http/httputil/persist.go b/contrib/go/_std_1.21/src/net/http/httputil/persist.go
index 84b116df8c..84b116df8c 100644
--- a/contrib/go/_std_1.20/src/net/http/httputil/persist.go
+++ b/contrib/go/_std_1.21/src/net/http/httputil/persist.go
diff --git a/contrib/go/_std_1.21/src/net/http/httputil/reverseproxy.go b/contrib/go/_std_1.21/src/net/http/httputil/reverseproxy.go
new file mode 100644
index 0000000000..2a76b0b8dc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/httputil/reverseproxy.go
@@ -0,0 +1,834 @@
+// Copyright 2011 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.
+
+// HTTP reverse proxy handler
+
+package httputil
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "mime"
+ "net"
+ "net/http"
+ "net/http/httptrace"
+ "net/http/internal/ascii"
+ "net/textproto"
+ "net/url"
+ "strings"
+ "sync"
+ "time"
+
+ "golang.org/x/net/http/httpguts"
+)
+
+// A ProxyRequest contains a request to be rewritten by a ReverseProxy.
+type ProxyRequest struct {
+ // In is the request received by the proxy.
+ // The Rewrite function must not modify In.
+ In *http.Request
+
+ // Out is the request which will be sent by the proxy.
+ // The Rewrite function may modify or replace this request.
+ // Hop-by-hop headers are removed from this request
+ // before Rewrite is called.
+ Out *http.Request
+}
+
+// SetURL routes the outbound request to the scheme, host, and base path
+// provided in target. If the target's path is "/base" and the incoming
+// request was for "/dir", the target request will be for "/base/dir".
+//
+// SetURL rewrites the outbound Host header to match the target's host.
+// To preserve the inbound request's Host header (the default behavior
+// of NewSingleHostReverseProxy):
+//
+// rewriteFunc := func(r *httputil.ProxyRequest) {
+// r.SetURL(url)
+// r.Out.Host = r.In.Host
+// }
+func (r *ProxyRequest) SetURL(target *url.URL) {
+ rewriteRequestURL(r.Out, target)
+ r.Out.Host = ""
+}
+
+// SetXForwarded sets the X-Forwarded-For, X-Forwarded-Host, and
+// X-Forwarded-Proto headers of the outbound request.
+//
+// - The X-Forwarded-For header is set to the client IP address.
+// - The X-Forwarded-Host header is set to the host name requested
+// by the client.
+// - The X-Forwarded-Proto header is set to "http" or "https", depending
+// on whether the inbound request was made on a TLS-enabled connection.
+//
+// If the outbound request contains an existing X-Forwarded-For header,
+// SetXForwarded appends the client IP address to it. To append to the
+// inbound request's X-Forwarded-For header (the default behavior of
+// ReverseProxy when using a Director function), copy the header
+// from the inbound request before calling SetXForwarded:
+//
+// rewriteFunc := func(r *httputil.ProxyRequest) {
+// r.Out.Header["X-Forwarded-For"] = r.In.Header["X-Forwarded-For"]
+// r.SetXForwarded()
+// }
+func (r *ProxyRequest) SetXForwarded() {
+ clientIP, _, err := net.SplitHostPort(r.In.RemoteAddr)
+ if err == nil {
+ prior := r.Out.Header["X-Forwarded-For"]
+ if len(prior) > 0 {
+ clientIP = strings.Join(prior, ", ") + ", " + clientIP
+ }
+ r.Out.Header.Set("X-Forwarded-For", clientIP)
+ } else {
+ r.Out.Header.Del("X-Forwarded-For")
+ }
+ r.Out.Header.Set("X-Forwarded-Host", r.In.Host)
+ if r.In.TLS == nil {
+ r.Out.Header.Set("X-Forwarded-Proto", "http")
+ } else {
+ r.Out.Header.Set("X-Forwarded-Proto", "https")
+ }
+}
+
+// ReverseProxy is an HTTP Handler that takes an incoming request and
+// sends it to another server, proxying the response back to the
+// client.
+//
+// 1xx responses are forwarded to the client if the underlying
+// transport supports ClientTrace.Got1xxResponse.
+type ReverseProxy struct {
+ // Rewrite must be a function which modifies
+ // the request into a new request to be sent
+ // using Transport. Its response is then copied
+ // back to the original client unmodified.
+ // Rewrite must not access the provided ProxyRequest
+ // or its contents after returning.
+ //
+ // The Forwarded, X-Forwarded, X-Forwarded-Host,
+ // and X-Forwarded-Proto headers are removed from the
+ // outbound request before Rewrite is called. See also
+ // the ProxyRequest.SetXForwarded method.
+ //
+ // Unparsable query parameters are removed from the
+ // outbound request before Rewrite is called.
+ // The Rewrite function may copy the inbound URL's
+ // RawQuery to the outbound URL to preserve the original
+ // parameter string. Note that this can lead to security
+ // issues if the proxy's interpretation of query parameters
+ // does not match that of the downstream server.
+ //
+ // At most one of Rewrite or Director may be set.
+ Rewrite func(*ProxyRequest)
+
+ // Director is a function which modifies
+ // the request into a new request to be sent
+ // using Transport. Its response is then copied
+ // back to the original client unmodified.
+ // Director must not access the provided Request
+ // after returning.
+ //
+ // By default, the X-Forwarded-For header is set to the
+ // value of the client IP address. If an X-Forwarded-For
+ // header already exists, the client IP is appended to the
+ // existing values. As a special case, if the header
+ // exists in the Request.Header map but has a nil value
+ // (such as when set by the Director func), the X-Forwarded-For
+ // header is not modified.
+ //
+ // To prevent IP spoofing, be sure to delete any pre-existing
+ // X-Forwarded-For header coming from the client or
+ // an untrusted proxy.
+ //
+ // Hop-by-hop headers are removed from the request after
+ // Director returns, which can remove headers added by
+ // Director. Use a Rewrite function instead to ensure
+ // modifications to the request are preserved.
+ //
+ // Unparsable query parameters are removed from the outbound
+ // request if Request.Form is set after Director returns.
+ //
+ // At most one of Rewrite or Director may be set.
+ Director func(*http.Request)
+
+ // The transport used to perform proxy requests.
+ // If nil, http.DefaultTransport is used.
+ Transport http.RoundTripper
+
+ // FlushInterval specifies the flush interval
+ // to flush to the client while copying the
+ // response body.
+ // If zero, no periodic flushing is done.
+ // A negative value means to flush immediately
+ // after each write to the client.
+ // The FlushInterval is ignored when ReverseProxy
+ // recognizes a response as a streaming response, or
+ // if its ContentLength is -1; for such responses, writes
+ // are flushed to the client immediately.
+ FlushInterval time.Duration
+
+ // ErrorLog specifies an optional logger for errors
+ // that occur when attempting to proxy the request.
+ // If nil, logging is done via the log package's standard logger.
+ ErrorLog *log.Logger
+
+ // BufferPool optionally specifies a buffer pool to
+ // get byte slices for use by io.CopyBuffer when
+ // copying HTTP response bodies.
+ BufferPool BufferPool
+
+ // ModifyResponse is an optional function that modifies the
+ // Response from the backend. It is called if the backend
+ // returns a response at all, with any HTTP status code.
+ // If the backend is unreachable, the optional ErrorHandler is
+ // called without any call to ModifyResponse.
+ //
+ // If ModifyResponse returns an error, ErrorHandler is called
+ // with its error value. If ErrorHandler is nil, its default
+ // implementation is used.
+ ModifyResponse func(*http.Response) error
+
+ // ErrorHandler is an optional function that handles errors
+ // reaching the backend or errors from ModifyResponse.
+ //
+ // If nil, the default is to log the provided error and return
+ // a 502 Status Bad Gateway response.
+ ErrorHandler func(http.ResponseWriter, *http.Request, error)
+}
+
+// A BufferPool is an interface for getting and returning temporary
+// byte slices for use by io.CopyBuffer.
+type BufferPool interface {
+ Get() []byte
+ Put([]byte)
+}
+
+func singleJoiningSlash(a, b string) string {
+ aslash := strings.HasSuffix(a, "/")
+ bslash := strings.HasPrefix(b, "/")
+ switch {
+ case aslash && bslash:
+ return a + b[1:]
+ case !aslash && !bslash:
+ return a + "/" + b
+ }
+ return a + b
+}
+
+func joinURLPath(a, b *url.URL) (path, rawpath string) {
+ if a.RawPath == "" && b.RawPath == "" {
+ return singleJoiningSlash(a.Path, b.Path), ""
+ }
+ // Same as singleJoiningSlash, but uses EscapedPath to determine
+ // whether a slash should be added
+ apath := a.EscapedPath()
+ bpath := b.EscapedPath()
+
+ aslash := strings.HasSuffix(apath, "/")
+ bslash := strings.HasPrefix(bpath, "/")
+
+ switch {
+ case aslash && bslash:
+ return a.Path + b.Path[1:], apath + bpath[1:]
+ case !aslash && !bslash:
+ return a.Path + "/" + b.Path, apath + "/" + bpath
+ }
+ return a.Path + b.Path, apath + bpath
+}
+
+// NewSingleHostReverseProxy returns a new ReverseProxy that routes
+// URLs to the scheme, host, and base path provided in target. If the
+// target's path is "/base" and the incoming request was for "/dir",
+// the target request will be for /base/dir.
+//
+// NewSingleHostReverseProxy does not rewrite the Host header.
+//
+// To customize the ReverseProxy behavior beyond what
+// NewSingleHostReverseProxy provides, use ReverseProxy directly
+// with a Rewrite function. The ProxyRequest SetURL method
+// may be used to route the outbound request. (Note that SetURL,
+// unlike NewSingleHostReverseProxy, rewrites the Host header
+// of the outbound request by default.)
+//
+// proxy := &ReverseProxy{
+// Rewrite: func(r *ProxyRequest) {
+// r.SetURL(target)
+// r.Out.Host = r.In.Host // if desired
+// },
+// }
+func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy {
+ director := func(req *http.Request) {
+ rewriteRequestURL(req, target)
+ }
+ return &ReverseProxy{Director: director}
+}
+
+func rewriteRequestURL(req *http.Request, target *url.URL) {
+ targetQuery := target.RawQuery
+ req.URL.Scheme = target.Scheme
+ req.URL.Host = target.Host
+ req.URL.Path, req.URL.RawPath = joinURLPath(target, req.URL)
+ if targetQuery == "" || req.URL.RawQuery == "" {
+ req.URL.RawQuery = targetQuery + req.URL.RawQuery
+ } else {
+ req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
+ }
+}
+
+func copyHeader(dst, src http.Header) {
+ for k, vv := range src {
+ for _, v := range vv {
+ dst.Add(k, v)
+ }
+ }
+}
+
+// Hop-by-hop headers. These are removed when sent to the backend.
+// As of RFC 7230, hop-by-hop headers are required to appear in the
+// Connection header field. These are the headers defined by the
+// obsoleted RFC 2616 (section 13.5.1) and are used for backward
+// compatibility.
+var hopHeaders = []string{
+ "Connection",
+ "Proxy-Connection", // non-standard but still sent by libcurl and rejected by e.g. google
+ "Keep-Alive",
+ "Proxy-Authenticate",
+ "Proxy-Authorization",
+ "Te", // canonicalized version of "TE"
+ "Trailer", // not Trailers per URL above; https://www.rfc-editor.org/errata_search.php?eid=4522
+ "Transfer-Encoding",
+ "Upgrade",
+}
+
+func (p *ReverseProxy) defaultErrorHandler(rw http.ResponseWriter, req *http.Request, err error) {
+ p.logf("http: proxy error: %v", err)
+ rw.WriteHeader(http.StatusBadGateway)
+}
+
+func (p *ReverseProxy) getErrorHandler() func(http.ResponseWriter, *http.Request, error) {
+ if p.ErrorHandler != nil {
+ return p.ErrorHandler
+ }
+ return p.defaultErrorHandler
+}
+
+// modifyResponse conditionally runs the optional ModifyResponse hook
+// and reports whether the request should proceed.
+func (p *ReverseProxy) modifyResponse(rw http.ResponseWriter, res *http.Response, req *http.Request) bool {
+ if p.ModifyResponse == nil {
+ return true
+ }
+ if err := p.ModifyResponse(res); err != nil {
+ res.Body.Close()
+ p.getErrorHandler()(rw, req, err)
+ return false
+ }
+ return true
+}
+
+func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+ transport := p.Transport
+ if transport == nil {
+ transport = http.DefaultTransport
+ }
+
+ ctx := req.Context()
+ if ctx.Done() != nil {
+ // CloseNotifier predates context.Context, and has been
+ // entirely superseded by it. If the request contains
+ // a Context that carries a cancellation signal, don't
+ // bother spinning up a goroutine to watch the CloseNotify
+ // channel (if any).
+ //
+ // If the request Context has a nil Done channel (which
+ // means it is either context.Background, or a custom
+ // Context implementation with no cancellation signal),
+ // then consult the CloseNotifier if available.
+ } else if cn, ok := rw.(http.CloseNotifier); ok {
+ var cancel context.CancelFunc
+ ctx, cancel = context.WithCancel(ctx)
+ defer cancel()
+ notifyChan := cn.CloseNotify()
+ go func() {
+ select {
+ case <-notifyChan:
+ cancel()
+ case <-ctx.Done():
+ }
+ }()
+ }
+
+ outreq := req.Clone(ctx)
+ if req.ContentLength == 0 {
+ outreq.Body = nil // Issue 16036: nil Body for http.Transport retries
+ }
+ if outreq.Body != nil {
+ // Reading from the request body after returning from a handler is not
+ // allowed, and the RoundTrip goroutine that reads the Body can outlive
+ // this handler. This can lead to a crash if the handler panics (see
+ // Issue 46866). Although calling Close doesn't guarantee there isn't
+ // any Read in flight after the handle returns, in practice it's safe to
+ // read after closing it.
+ defer outreq.Body.Close()
+ }
+ if outreq.Header == nil {
+ outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate
+ }
+
+ if (p.Director != nil) == (p.Rewrite != nil) {
+ p.getErrorHandler()(rw, req, errors.New("ReverseProxy must have exactly one of Director or Rewrite set"))
+ return
+ }
+
+ if p.Director != nil {
+ p.Director(outreq)
+ if outreq.Form != nil {
+ outreq.URL.RawQuery = cleanQueryParams(outreq.URL.RawQuery)
+ }
+ }
+ outreq.Close = false
+
+ reqUpType := upgradeType(outreq.Header)
+ if !ascii.IsPrint(reqUpType) {
+ p.getErrorHandler()(rw, req, fmt.Errorf("client tried to switch to invalid protocol %q", reqUpType))
+ return
+ }
+ removeHopByHopHeaders(outreq.Header)
+
+ // Issue 21096: tell backend applications that care about trailer support
+ // that we support trailers. (We do, but we don't go out of our way to
+ // advertise that unless the incoming client request thought it was worth
+ // mentioning.) Note that we look at req.Header, not outreq.Header, since
+ // the latter has passed through removeHopByHopHeaders.
+ if httpguts.HeaderValuesContainsToken(req.Header["Te"], "trailers") {
+ outreq.Header.Set("Te", "trailers")
+ }
+
+ // After stripping all the hop-by-hop connection headers above, add back any
+ // necessary for protocol upgrades, such as for websockets.
+ if reqUpType != "" {
+ outreq.Header.Set("Connection", "Upgrade")
+ outreq.Header.Set("Upgrade", reqUpType)
+ }
+
+ if p.Rewrite != nil {
+ // Strip client-provided forwarding headers.
+ // The Rewrite func may use SetXForwarded to set new values
+ // for these or copy the previous values from the inbound request.
+ outreq.Header.Del("Forwarded")
+ outreq.Header.Del("X-Forwarded-For")
+ outreq.Header.Del("X-Forwarded-Host")
+ outreq.Header.Del("X-Forwarded-Proto")
+
+ // Remove unparsable query parameters from the outbound request.
+ outreq.URL.RawQuery = cleanQueryParams(outreq.URL.RawQuery)
+
+ pr := &ProxyRequest{
+ In: req,
+ Out: outreq,
+ }
+ p.Rewrite(pr)
+ outreq = pr.Out
+ } else {
+ if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
+ // If we aren't the first proxy retain prior
+ // X-Forwarded-For information as a comma+space
+ // separated list and fold multiple headers into one.
+ prior, ok := outreq.Header["X-Forwarded-For"]
+ omit := ok && prior == nil // Issue 38079: nil now means don't populate the header
+ if len(prior) > 0 {
+ clientIP = strings.Join(prior, ", ") + ", " + clientIP
+ }
+ if !omit {
+ outreq.Header.Set("X-Forwarded-For", clientIP)
+ }
+ }
+ }
+
+ if _, ok := outreq.Header["User-Agent"]; !ok {
+ // If the outbound request doesn't have a User-Agent header set,
+ // don't send the default Go HTTP client User-Agent.
+ outreq.Header.Set("User-Agent", "")
+ }
+
+ trace := &httptrace.ClientTrace{
+ Got1xxResponse: func(code int, header textproto.MIMEHeader) error {
+ h := rw.Header()
+ copyHeader(h, http.Header(header))
+ rw.WriteHeader(code)
+
+ // Clear headers, it's not automatically done by ResponseWriter.WriteHeader() for 1xx responses
+ for k := range h {
+ delete(h, k)
+ }
+
+ return nil
+ },
+ }
+ outreq = outreq.WithContext(httptrace.WithClientTrace(outreq.Context(), trace))
+
+ res, err := transport.RoundTrip(outreq)
+ if err != nil {
+ p.getErrorHandler()(rw, outreq, err)
+ return
+ }
+
+ // Deal with 101 Switching Protocols responses: (WebSocket, h2c, etc)
+ if res.StatusCode == http.StatusSwitchingProtocols {
+ if !p.modifyResponse(rw, res, outreq) {
+ return
+ }
+ p.handleUpgradeResponse(rw, outreq, res)
+ return
+ }
+
+ removeHopByHopHeaders(res.Header)
+
+ if !p.modifyResponse(rw, res, outreq) {
+ return
+ }
+
+ copyHeader(rw.Header(), res.Header)
+
+ // The "Trailer" header isn't included in the Transport's response,
+ // at least for *http.Transport. Build it up from Trailer.
+ announcedTrailers := len(res.Trailer)
+ if announcedTrailers > 0 {
+ trailerKeys := make([]string, 0, len(res.Trailer))
+ for k := range res.Trailer {
+ trailerKeys = append(trailerKeys, k)
+ }
+ rw.Header().Add("Trailer", strings.Join(trailerKeys, ", "))
+ }
+
+ rw.WriteHeader(res.StatusCode)
+
+ err = p.copyResponse(rw, res.Body, p.flushInterval(res))
+ if err != nil {
+ defer res.Body.Close()
+ // Since we're streaming the response, if we run into an error all we can do
+ // is abort the request. Issue 23643: ReverseProxy should use ErrAbortHandler
+ // on read error while copying body.
+ if !shouldPanicOnCopyError(req) {
+ p.logf("suppressing panic for copyResponse error in test; copy error: %v", err)
+ return
+ }
+ panic(http.ErrAbortHandler)
+ }
+ res.Body.Close() // close now, instead of defer, to populate res.Trailer
+
+ if len(res.Trailer) > 0 {
+ // Force chunking if we saw a response trailer.
+ // This prevents net/http from calculating the length for short
+ // bodies and adding a Content-Length.
+ http.NewResponseController(rw).Flush()
+ }
+
+ if len(res.Trailer) == announcedTrailers {
+ copyHeader(rw.Header(), res.Trailer)
+ return
+ }
+
+ for k, vv := range res.Trailer {
+ k = http.TrailerPrefix + k
+ for _, v := range vv {
+ rw.Header().Add(k, v)
+ }
+ }
+}
+
+var inOurTests bool // whether we're in our own tests
+
+// shouldPanicOnCopyError reports whether the reverse proxy should
+// panic with http.ErrAbortHandler. This is the right thing to do by
+// default, but Go 1.10 and earlier did not, so existing unit tests
+// weren't expecting panics. Only panic in our own tests, or when
+// running under the HTTP server.
+func shouldPanicOnCopyError(req *http.Request) bool {
+ if inOurTests {
+ // Our tests know to handle this panic.
+ return true
+ }
+ if req.Context().Value(http.ServerContextKey) != nil {
+ // We seem to be running under an HTTP server, so
+ // it'll recover the panic.
+ return true
+ }
+ // Otherwise act like Go 1.10 and earlier to not break
+ // existing tests.
+ return false
+}
+
+// removeHopByHopHeaders removes hop-by-hop headers.
+func removeHopByHopHeaders(h http.Header) {
+ // RFC 7230, section 6.1: Remove headers listed in the "Connection" header.
+ for _, f := range h["Connection"] {
+ for _, sf := range strings.Split(f, ",") {
+ if sf = textproto.TrimString(sf); sf != "" {
+ h.Del(sf)
+ }
+ }
+ }
+ // RFC 2616, section 13.5.1: Remove a set of known hop-by-hop headers.
+ // This behavior is superseded by the RFC 7230 Connection header, but
+ // preserve it for backwards compatibility.
+ for _, f := range hopHeaders {
+ h.Del(f)
+ }
+}
+
+// flushInterval returns the p.FlushInterval value, conditionally
+// overriding its value for a specific request/response.
+func (p *ReverseProxy) flushInterval(res *http.Response) time.Duration {
+ resCT := res.Header.Get("Content-Type")
+
+ // For Server-Sent Events responses, flush immediately.
+ // The MIME type is defined in https://www.w3.org/TR/eventsource/#text-event-stream
+ if baseCT, _, _ := mime.ParseMediaType(resCT); baseCT == "text/event-stream" {
+ return -1 // negative means immediately
+ }
+
+ // We might have the case of streaming for which Content-Length might be unset.
+ if res.ContentLength == -1 {
+ return -1
+ }
+
+ return p.FlushInterval
+}
+
+func (p *ReverseProxy) copyResponse(dst http.ResponseWriter, src io.Reader, flushInterval time.Duration) error {
+ var w io.Writer = dst
+
+ if flushInterval != 0 {
+ mlw := &maxLatencyWriter{
+ dst: dst,
+ flush: http.NewResponseController(dst).Flush,
+ latency: flushInterval,
+ }
+ defer mlw.stop()
+
+ // set up initial timer so headers get flushed even if body writes are delayed
+ mlw.flushPending = true
+ mlw.t = time.AfterFunc(flushInterval, mlw.delayedFlush)
+
+ w = mlw
+ }
+
+ var buf []byte
+ if p.BufferPool != nil {
+ buf = p.BufferPool.Get()
+ defer p.BufferPool.Put(buf)
+ }
+ _, err := p.copyBuffer(w, src, buf)
+ return err
+}
+
+// copyBuffer returns any write errors or non-EOF read errors, and the amount
+// of bytes written.
+func (p *ReverseProxy) copyBuffer(dst io.Writer, src io.Reader, buf []byte) (int64, error) {
+ if len(buf) == 0 {
+ buf = make([]byte, 32*1024)
+ }
+ var written int64
+ for {
+ nr, rerr := src.Read(buf)
+ if rerr != nil && rerr != io.EOF && rerr != context.Canceled {
+ p.logf("httputil: ReverseProxy read error during body copy: %v", rerr)
+ }
+ if nr > 0 {
+ nw, werr := dst.Write(buf[:nr])
+ if nw > 0 {
+ written += int64(nw)
+ }
+ if werr != nil {
+ return written, werr
+ }
+ if nr != nw {
+ return written, io.ErrShortWrite
+ }
+ }
+ if rerr != nil {
+ if rerr == io.EOF {
+ rerr = nil
+ }
+ return written, rerr
+ }
+ }
+}
+
+func (p *ReverseProxy) logf(format string, args ...any) {
+ if p.ErrorLog != nil {
+ p.ErrorLog.Printf(format, args...)
+ } else {
+ log.Printf(format, args...)
+ }
+}
+
+type maxLatencyWriter struct {
+ dst io.Writer
+ flush func() error
+ latency time.Duration // non-zero; negative means to flush immediately
+
+ mu sync.Mutex // protects t, flushPending, and dst.Flush
+ t *time.Timer
+ flushPending bool
+}
+
+func (m *maxLatencyWriter) Write(p []byte) (n int, err error) {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+ n, err = m.dst.Write(p)
+ if m.latency < 0 {
+ m.flush()
+ return
+ }
+ if m.flushPending {
+ return
+ }
+ if m.t == nil {
+ m.t = time.AfterFunc(m.latency, m.delayedFlush)
+ } else {
+ m.t.Reset(m.latency)
+ }
+ m.flushPending = true
+ return
+}
+
+func (m *maxLatencyWriter) delayedFlush() {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+ if !m.flushPending { // if stop was called but AfterFunc already started this goroutine
+ return
+ }
+ m.flush()
+ m.flushPending = false
+}
+
+func (m *maxLatencyWriter) stop() {
+ m.mu.Lock()
+ defer m.mu.Unlock()
+ m.flushPending = false
+ if m.t != nil {
+ m.t.Stop()
+ }
+}
+
+func upgradeType(h http.Header) string {
+ if !httpguts.HeaderValuesContainsToken(h["Connection"], "Upgrade") {
+ return ""
+ }
+ return h.Get("Upgrade")
+}
+
+func (p *ReverseProxy) handleUpgradeResponse(rw http.ResponseWriter, req *http.Request, res *http.Response) {
+ reqUpType := upgradeType(req.Header)
+ resUpType := upgradeType(res.Header)
+ if !ascii.IsPrint(resUpType) { // We know reqUpType is ASCII, it's checked by the caller.
+ p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch to invalid protocol %q", resUpType))
+ }
+ if !ascii.EqualFold(reqUpType, resUpType) {
+ p.getErrorHandler()(rw, req, fmt.Errorf("backend tried to switch protocol %q when %q was requested", resUpType, reqUpType))
+ return
+ }
+
+ backConn, ok := res.Body.(io.ReadWriteCloser)
+ if !ok {
+ p.getErrorHandler()(rw, req, fmt.Errorf("internal error: 101 switching protocols response with non-writable body"))
+ return
+ }
+
+ rc := http.NewResponseController(rw)
+ conn, brw, hijackErr := rc.Hijack()
+ if errors.Is(hijackErr, http.ErrNotSupported) {
+ p.getErrorHandler()(rw, req, fmt.Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw))
+ return
+ }
+
+ backConnCloseCh := make(chan bool)
+ go func() {
+ // Ensure that the cancellation of a request closes the backend.
+ // See issue https://golang.org/issue/35559.
+ select {
+ case <-req.Context().Done():
+ case <-backConnCloseCh:
+ }
+ backConn.Close()
+ }()
+ defer close(backConnCloseCh)
+
+ if hijackErr != nil {
+ p.getErrorHandler()(rw, req, fmt.Errorf("Hijack failed on protocol switch: %v", hijackErr))
+ return
+ }
+ defer conn.Close()
+
+ copyHeader(rw.Header(), res.Header)
+
+ res.Header = rw.Header()
+ res.Body = nil // so res.Write only writes the headers; we have res.Body in backConn above
+ if err := res.Write(brw); err != nil {
+ p.getErrorHandler()(rw, req, fmt.Errorf("response write: %v", err))
+ return
+ }
+ if err := brw.Flush(); err != nil {
+ p.getErrorHandler()(rw, req, fmt.Errorf("response flush: %v", err))
+ return
+ }
+ errc := make(chan error, 1)
+ spc := switchProtocolCopier{user: conn, backend: backConn}
+ go spc.copyToBackend(errc)
+ go spc.copyFromBackend(errc)
+ <-errc
+}
+
+// switchProtocolCopier exists so goroutines proxying data back and
+// forth have nice names in stacks.
+type switchProtocolCopier struct {
+ user, backend io.ReadWriter
+}
+
+func (c switchProtocolCopier) copyFromBackend(errc chan<- error) {
+ _, err := io.Copy(c.user, c.backend)
+ errc <- err
+}
+
+func (c switchProtocolCopier) copyToBackend(errc chan<- error) {
+ _, err := io.Copy(c.backend, c.user)
+ errc <- err
+}
+
+func cleanQueryParams(s string) string {
+ reencode := func(s string) string {
+ v, _ := url.ParseQuery(s)
+ return v.Encode()
+ }
+ for i := 0; i < len(s); {
+ switch s[i] {
+ case ';':
+ return reencode(s)
+ case '%':
+ if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {
+ return reencode(s)
+ }
+ i += 3
+ default:
+ i++
+ }
+ }
+ return s
+}
+
+func ishex(c byte) bool {
+ switch {
+ case '0' <= c && c <= '9':
+ return true
+ case 'a' <= c && c <= 'f':
+ return true
+ case 'A' <= c && c <= 'F':
+ return true
+ }
+ return false
+}
diff --git a/contrib/go/_std_1.21/src/net/http/httputil/ya.make b/contrib/go/_std_1.21/src/net/http/httputil/ya.make
new file mode 100644
index 0000000000..8711125c78
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/httputil/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ dump.go
+ httputil.go
+ persist.go
+ reverseproxy.go
+)
+
+GO_TEST_SRCS(
+ dump_test.go
+ reverseproxy_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/net/http/internal/ascii/print.go b/contrib/go/_std_1.21/src/net/http/internal/ascii/print.go
index 585e5baba4..585e5baba4 100644
--- a/contrib/go/_std_1.20/src/net/http/internal/ascii/print.go
+++ b/contrib/go/_std_1.21/src/net/http/internal/ascii/print.go
diff --git a/contrib/go/_std_1.21/src/net/http/internal/ascii/ya.make b/contrib/go/_std_1.21/src/net/http/internal/ascii/ya.make
new file mode 100644
index 0000000000..406ce2021f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/internal/ascii/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ print.go
+)
+
+GO_TEST_SRCS(print_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/net/http/internal/chunked.go b/contrib/go/_std_1.21/src/net/http/internal/chunked.go
index 5a174415dc..5a174415dc 100644
--- a/contrib/go/_std_1.20/src/net/http/internal/chunked.go
+++ b/contrib/go/_std_1.21/src/net/http/internal/chunked.go
diff --git a/contrib/go/_std_1.20/src/net/http/internal/testcert/testcert.go b/contrib/go/_std_1.21/src/net/http/internal/testcert/testcert.go
index d510e791d6..d510e791d6 100644
--- a/contrib/go/_std_1.20/src/net/http/internal/testcert/testcert.go
+++ b/contrib/go/_std_1.21/src/net/http/internal/testcert/testcert.go
diff --git a/contrib/go/_std_1.20/src/net/http/internal/testcert/ya.make b/contrib/go/_std_1.21/src/net/http/internal/testcert/ya.make
index 9b32cdbe53..9b32cdbe53 100644
--- a/contrib/go/_std_1.20/src/net/http/internal/testcert/ya.make
+++ b/contrib/go/_std_1.21/src/net/http/internal/testcert/ya.make
diff --git a/contrib/go/_std_1.21/src/net/http/internal/ya.make b/contrib/go/_std_1.21/src/net/http/internal/ya.make
new file mode 100644
index 0000000000..425bf0c32f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/internal/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ chunked.go
+)
+
+GO_TEST_SRCS(chunked_test.go)
+
+END()
+
+RECURSE(
+ ascii
+ testcert
+)
diff --git a/contrib/go/_std_1.20/src/net/http/jar.go b/contrib/go/_std_1.21/src/net/http/jar.go
index 5c3de0dad2..5c3de0dad2 100644
--- a/contrib/go/_std_1.20/src/net/http/jar.go
+++ b/contrib/go/_std_1.21/src/net/http/jar.go
diff --git a/contrib/go/_std_1.20/src/net/http/method.go b/contrib/go/_std_1.21/src/net/http/method.go
index 6f46155069..6f46155069 100644
--- a/contrib/go/_std_1.20/src/net/http/method.go
+++ b/contrib/go/_std_1.21/src/net/http/method.go
diff --git a/contrib/go/_std_1.21/src/net/http/pprof/pprof.go b/contrib/go/_std_1.21/src/net/http/pprof/pprof.go
new file mode 100644
index 0000000000..bc3225daca
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/pprof/pprof.go
@@ -0,0 +1,464 @@
+// Copyright 2010 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 pprof serves via its HTTP server runtime profiling data
+// in the format expected by the pprof visualization tool.
+//
+// The package is typically only imported for the side effect of
+// registering its HTTP handlers.
+// The handled paths all begin with /debug/pprof/.
+//
+// To use pprof, link this package into your program:
+//
+// import _ "net/http/pprof"
+//
+// If your application is not already running an http server, you
+// need to start one. Add "net/http" and "log" to your imports and
+// the following code to your main function:
+//
+// go func() {
+// log.Println(http.ListenAndServe("localhost:6060", nil))
+// }()
+//
+// By default, all the profiles listed in [runtime/pprof.Profile] are
+// available (via [Handler]), in addition to the [Cmdline], [Profile], [Symbol],
+// and [Trace] profiles defined in this package.
+// If you are not using DefaultServeMux, you will have to register handlers
+// with the mux you are using.
+//
+// # Parameters
+//
+// Parameters can be passed via GET query params:
+//
+// - debug=N (all profiles): response format: N = 0: binary (default), N > 0: plaintext
+// - gc=N (heap profile): N > 0: run a garbage collection cycle before profiling
+// - seconds=N (allocs, block, goroutine, heap, mutex, threadcreate profiles): return a delta profile
+// - seconds=N (cpu (profile), trace profiles): profile for the given duration
+//
+// # Usage examples
+//
+// Use the pprof tool to look at the heap profile:
+//
+// go tool pprof http://localhost:6060/debug/pprof/heap
+//
+// Or to look at a 30-second CPU profile:
+//
+// go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30
+//
+// Or to look at the goroutine blocking profile, after calling
+// runtime.SetBlockProfileRate in your program:
+//
+// go tool pprof http://localhost:6060/debug/pprof/block
+//
+// Or to look at the holders of contended mutexes, after calling
+// runtime.SetMutexProfileFraction in your program:
+//
+// go tool pprof http://localhost:6060/debug/pprof/mutex
+//
+// The package also exports a handler that serves execution trace data
+// for the "go tool trace" command. To collect a 5-second execution trace:
+//
+// curl -o trace.out http://localhost:6060/debug/pprof/trace?seconds=5
+// go tool trace trace.out
+//
+// To view all available profiles, open http://localhost:6060/debug/pprof/
+// in your browser.
+//
+// For a study of the facility in action, visit
+// https://blog.golang.org/2011/06/profiling-go-programs.html.
+package pprof
+
+import (
+ "bufio"
+ "bytes"
+ "context"
+ "fmt"
+ "html"
+ "internal/profile"
+ "io"
+ "log"
+ "net/http"
+ "net/url"
+ "os"
+ "runtime"
+ "runtime/pprof"
+ "runtime/trace"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+)
+
+func init() {
+ http.HandleFunc("/debug/pprof/", Index)
+ http.HandleFunc("/debug/pprof/cmdline", Cmdline)
+ http.HandleFunc("/debug/pprof/profile", Profile)
+ http.HandleFunc("/debug/pprof/symbol", Symbol)
+ http.HandleFunc("/debug/pprof/trace", Trace)
+}
+
+// Cmdline responds with the running program's
+// command line, with arguments separated by NUL bytes.
+// The package initialization registers it as /debug/pprof/cmdline.
+func Cmdline(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("X-Content-Type-Options", "nosniff")
+ w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ fmt.Fprint(w, strings.Join(os.Args, "\x00"))
+}
+
+func sleep(r *http.Request, d time.Duration) {
+ select {
+ case <-time.After(d):
+ case <-r.Context().Done():
+ }
+}
+
+func durationExceedsWriteTimeout(r *http.Request, seconds float64) bool {
+ srv, ok := r.Context().Value(http.ServerContextKey).(*http.Server)
+ return ok && srv.WriteTimeout != 0 && seconds >= srv.WriteTimeout.Seconds()
+}
+
+func serveError(w http.ResponseWriter, status int, txt string) {
+ w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ w.Header().Set("X-Go-Pprof", "1")
+ w.Header().Del("Content-Disposition")
+ w.WriteHeader(status)
+ fmt.Fprintln(w, txt)
+}
+
+// Profile responds with the pprof-formatted cpu profile.
+// Profiling lasts for duration specified in seconds GET parameter, or for 30 seconds if not specified.
+// The package initialization registers it as /debug/pprof/profile.
+func Profile(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("X-Content-Type-Options", "nosniff")
+ sec, err := strconv.ParseInt(r.FormValue("seconds"), 10, 64)
+ if sec <= 0 || err != nil {
+ sec = 30
+ }
+
+ if durationExceedsWriteTimeout(r, float64(sec)) {
+ serveError(w, http.StatusBadRequest, "profile duration exceeds server's WriteTimeout")
+ return
+ }
+
+ // Set Content Type assuming StartCPUProfile will work,
+ // because if it does it starts writing.
+ w.Header().Set("Content-Type", "application/octet-stream")
+ w.Header().Set("Content-Disposition", `attachment; filename="profile"`)
+ if err := pprof.StartCPUProfile(w); err != nil {
+ // StartCPUProfile failed, so no writes yet.
+ serveError(w, http.StatusInternalServerError,
+ fmt.Sprintf("Could not enable CPU profiling: %s", err))
+ return
+ }
+ sleep(r, time.Duration(sec)*time.Second)
+ pprof.StopCPUProfile()
+}
+
+// Trace responds with the execution trace in binary form.
+// Tracing lasts for duration specified in seconds GET parameter, or for 1 second if not specified.
+// The package initialization registers it as /debug/pprof/trace.
+func Trace(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("X-Content-Type-Options", "nosniff")
+ sec, err := strconv.ParseFloat(r.FormValue("seconds"), 64)
+ if sec <= 0 || err != nil {
+ sec = 1
+ }
+
+ if durationExceedsWriteTimeout(r, sec) {
+ serveError(w, http.StatusBadRequest, "profile duration exceeds server's WriteTimeout")
+ return
+ }
+
+ // Set Content Type assuming trace.Start will work,
+ // because if it does it starts writing.
+ w.Header().Set("Content-Type", "application/octet-stream")
+ w.Header().Set("Content-Disposition", `attachment; filename="trace"`)
+ if err := trace.Start(w); err != nil {
+ // trace.Start failed, so no writes yet.
+ serveError(w, http.StatusInternalServerError,
+ fmt.Sprintf("Could not enable tracing: %s", err))
+ return
+ }
+ sleep(r, time.Duration(sec*float64(time.Second)))
+ trace.Stop()
+}
+
+// Symbol looks up the program counters listed in the request,
+// responding with a table mapping program counters to function names.
+// The package initialization registers it as /debug/pprof/symbol.
+func Symbol(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("X-Content-Type-Options", "nosniff")
+ w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+
+ // We have to read the whole POST body before
+ // writing any output. Buffer the output here.
+ var buf bytes.Buffer
+
+ // We don't know how many symbols we have, but we
+ // do have symbol information. Pprof only cares whether
+ // this number is 0 (no symbols available) or > 0.
+ fmt.Fprintf(&buf, "num_symbols: 1\n")
+
+ var b *bufio.Reader
+ if r.Method == "POST" {
+ b = bufio.NewReader(r.Body)
+ } else {
+ b = bufio.NewReader(strings.NewReader(r.URL.RawQuery))
+ }
+
+ for {
+ word, err := b.ReadSlice('+')
+ if err == nil {
+ word = word[0 : len(word)-1] // trim +
+ }
+ pc, _ := strconv.ParseUint(string(word), 0, 64)
+ if pc != 0 {
+ f := runtime.FuncForPC(uintptr(pc))
+ if f != nil {
+ fmt.Fprintf(&buf, "%#x %s\n", pc, f.Name())
+ }
+ }
+
+ // Wait until here to check for err; the last
+ // symbol will have an err because it doesn't end in +.
+ if err != nil {
+ if err != io.EOF {
+ fmt.Fprintf(&buf, "reading request: %v\n", err)
+ }
+ break
+ }
+ }
+
+ w.Write(buf.Bytes())
+}
+
+// Handler returns an HTTP handler that serves the named profile.
+// Available profiles can be found in [runtime/pprof.Profile].
+func Handler(name string) http.Handler {
+ return handler(name)
+}
+
+type handler string
+
+func (name handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ w.Header().Set("X-Content-Type-Options", "nosniff")
+ p := pprof.Lookup(string(name))
+ if p == nil {
+ serveError(w, http.StatusNotFound, "Unknown profile")
+ return
+ }
+ if sec := r.FormValue("seconds"); sec != "" {
+ name.serveDeltaProfile(w, r, p, sec)
+ return
+ }
+ gc, _ := strconv.Atoi(r.FormValue("gc"))
+ if name == "heap" && gc > 0 {
+ runtime.GC()
+ }
+ debug, _ := strconv.Atoi(r.FormValue("debug"))
+ if debug != 0 {
+ w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ } else {
+ w.Header().Set("Content-Type", "application/octet-stream")
+ w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, name))
+ }
+ p.WriteTo(w, debug)
+}
+
+func (name handler) serveDeltaProfile(w http.ResponseWriter, r *http.Request, p *pprof.Profile, secStr string) {
+ sec, err := strconv.ParseInt(secStr, 10, 64)
+ if err != nil || sec <= 0 {
+ serveError(w, http.StatusBadRequest, `invalid value for "seconds" - must be a positive integer`)
+ return
+ }
+ if !profileSupportsDelta[name] {
+ serveError(w, http.StatusBadRequest, `"seconds" parameter is not supported for this profile type`)
+ return
+ }
+ // 'name' should be a key in profileSupportsDelta.
+ if durationExceedsWriteTimeout(r, float64(sec)) {
+ serveError(w, http.StatusBadRequest, "profile duration exceeds server's WriteTimeout")
+ return
+ }
+ debug, _ := strconv.Atoi(r.FormValue("debug"))
+ if debug != 0 {
+ serveError(w, http.StatusBadRequest, "seconds and debug params are incompatible")
+ return
+ }
+ p0, err := collectProfile(p)
+ if err != nil {
+ serveError(w, http.StatusInternalServerError, "failed to collect profile")
+ return
+ }
+
+ t := time.NewTimer(time.Duration(sec) * time.Second)
+ defer t.Stop()
+
+ select {
+ case <-r.Context().Done():
+ err := r.Context().Err()
+ if err == context.DeadlineExceeded {
+ serveError(w, http.StatusRequestTimeout, err.Error())
+ } else { // TODO: what's a good status code for canceled requests? 400?
+ serveError(w, http.StatusInternalServerError, err.Error())
+ }
+ return
+ case <-t.C:
+ }
+
+ p1, err := collectProfile(p)
+ if err != nil {
+ serveError(w, http.StatusInternalServerError, "failed to collect profile")
+ return
+ }
+ ts := p1.TimeNanos
+ dur := p1.TimeNanos - p0.TimeNanos
+
+ p0.Scale(-1)
+
+ p1, err = profile.Merge([]*profile.Profile{p0, p1})
+ if err != nil {
+ serveError(w, http.StatusInternalServerError, "failed to compute delta")
+ return
+ }
+
+ p1.TimeNanos = ts // set since we don't know what profile.Merge set for TimeNanos.
+ p1.DurationNanos = dur
+
+ w.Header().Set("Content-Type", "application/octet-stream")
+ w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s-delta"`, name))
+ p1.Write(w)
+}
+
+func collectProfile(p *pprof.Profile) (*profile.Profile, error) {
+ var buf bytes.Buffer
+ if err := p.WriteTo(&buf, 0); err != nil {
+ return nil, err
+ }
+ ts := time.Now().UnixNano()
+ p0, err := profile.Parse(&buf)
+ if err != nil {
+ return nil, err
+ }
+ p0.TimeNanos = ts
+ return p0, nil
+}
+
+var profileSupportsDelta = map[handler]bool{
+ "allocs": true,
+ "block": true,
+ "goroutine": true,
+ "heap": true,
+ "mutex": true,
+ "threadcreate": true,
+}
+
+var profileDescriptions = map[string]string{
+ "allocs": "A sampling of all past memory allocations",
+ "block": "Stack traces that led to blocking on synchronization primitives",
+ "cmdline": "The command line invocation of the current program",
+ "goroutine": "Stack traces of all current goroutines. Use debug=2 as a query parameter to export in the same format as an unrecovered panic.",
+ "heap": "A sampling of memory allocations of live objects. You can specify the gc GET parameter to run GC before taking the heap sample.",
+ "mutex": "Stack traces of holders of contended mutexes",
+ "profile": "CPU profile. You can specify the duration in the seconds GET parameter. After you get the profile file, use the go tool pprof command to investigate the profile.",
+ "threadcreate": "Stack traces that led to the creation of new OS threads",
+ "trace": "A trace of execution of the current program. You can specify the duration in the seconds GET parameter. After you get the trace file, use the go tool trace command to investigate the trace.",
+}
+
+type profileEntry struct {
+ Name string
+ Href string
+ Desc string
+ Count int
+}
+
+// Index responds with the pprof-formatted profile named by the request.
+// For example, "/debug/pprof/heap" serves the "heap" profile.
+// Index responds to a request for "/debug/pprof/" with an HTML page
+// listing the available profiles.
+func Index(w http.ResponseWriter, r *http.Request) {
+ if name, found := strings.CutPrefix(r.URL.Path, "/debug/pprof/"); found {
+ if name != "" {
+ handler(name).ServeHTTP(w, r)
+ return
+ }
+ }
+
+ w.Header().Set("X-Content-Type-Options", "nosniff")
+ w.Header().Set("Content-Type", "text/html; charset=utf-8")
+
+ var profiles []profileEntry
+ for _, p := range pprof.Profiles() {
+ profiles = append(profiles, profileEntry{
+ Name: p.Name(),
+ Href: p.Name(),
+ Desc: profileDescriptions[p.Name()],
+ Count: p.Count(),
+ })
+ }
+
+ // Adding other profiles exposed from within this package
+ for _, p := range []string{"cmdline", "profile", "trace"} {
+ profiles = append(profiles, profileEntry{
+ Name: p,
+ Href: p,
+ Desc: profileDescriptions[p],
+ })
+ }
+
+ sort.Slice(profiles, func(i, j int) bool {
+ return profiles[i].Name < profiles[j].Name
+ })
+
+ if err := indexTmplExecute(w, profiles); err != nil {
+ log.Print(err)
+ }
+}
+
+func indexTmplExecute(w io.Writer, profiles []profileEntry) error {
+ var b bytes.Buffer
+ b.WriteString(`<html>
+<head>
+<title>/debug/pprof/</title>
+<style>
+.profile-name{
+ display:inline-block;
+ width:6rem;
+}
+</style>
+</head>
+<body>
+/debug/pprof/
+<br>
+<p>Set debug=1 as a query parameter to export in legacy text format</p>
+<br>
+Types of profiles available:
+<table>
+<thead><td>Count</td><td>Profile</td></thead>
+`)
+
+ for _, profile := range profiles {
+ link := &url.URL{Path: profile.Href, RawQuery: "debug=1"}
+ fmt.Fprintf(&b, "<tr><td>%d</td><td><a href='%s'>%s</a></td></tr>\n", profile.Count, link, html.EscapeString(profile.Name))
+ }
+
+ b.WriteString(`</table>
+<a href="goroutine?debug=2">full goroutine stack dump</a>
+<br>
+<p>
+Profile Descriptions:
+<ul>
+`)
+ for _, profile := range profiles {
+ fmt.Fprintf(&b, "<li><div class=profile-name>%s: </div> %s</li>\n", html.EscapeString(profile.Name), html.EscapeString(profile.Desc))
+ }
+ b.WriteString(`</ul>
+</p>
+</body>
+</html>`)
+
+ _, err := w.Write(b.Bytes())
+ return err
+}
diff --git a/contrib/go/_std_1.21/src/net/http/pprof/ya.make b/contrib/go/_std_1.21/src/net/http/pprof/ya.make
new file mode 100644
index 0000000000..1660beb63b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/pprof/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ pprof.go
+)
+
+GO_TEST_SRCS(pprof_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/net/http/request.go b/contrib/go/_std_1.21/src/net/http/request.go
new file mode 100644
index 0000000000..81f79566a5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/request.go
@@ -0,0 +1,1488 @@
+// Copyright 2009 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.
+
+// HTTP Request reading and parsing.
+
+package http
+
+import (
+ "bufio"
+ "bytes"
+ "context"
+ "crypto/tls"
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io"
+ "mime"
+ "mime/multipart"
+ "net/http/httptrace"
+ "net/http/internal/ascii"
+ "net/textproto"
+ "net/url"
+ urlpkg "net/url"
+ "strconv"
+ "strings"
+ "sync"
+
+ "golang.org/x/net/http/httpguts"
+ "golang.org/x/net/idna"
+)
+
+const (
+ defaultMaxMemory = 32 << 20 // 32 MB
+)
+
+// ErrMissingFile is returned by FormFile when the provided file field name
+// is either not present in the request or not a file field.
+var ErrMissingFile = errors.New("http: no such file")
+
+// ProtocolError represents an HTTP protocol error.
+//
+// Deprecated: Not all errors in the http package related to protocol errors
+// are of type ProtocolError.
+type ProtocolError struct {
+ ErrorString string
+}
+
+func (pe *ProtocolError) Error() string { return pe.ErrorString }
+
+// Is lets http.ErrNotSupported match errors.ErrUnsupported.
+func (pe *ProtocolError) Is(err error) bool {
+ return pe == ErrNotSupported && err == errors.ErrUnsupported
+}
+
+var (
+ // ErrNotSupported indicates that a feature is not supported.
+ //
+ // It is returned by ResponseController methods to indicate that
+ // the handler does not support the method, and by the Push method
+ // of Pusher implementations to indicate that HTTP/2 Push support
+ // is not available.
+ ErrNotSupported = &ProtocolError{"feature not supported"}
+
+ // Deprecated: ErrUnexpectedTrailer is no longer returned by
+ // anything in the net/http package. Callers should not
+ // compare errors against this variable.
+ ErrUnexpectedTrailer = &ProtocolError{"trailer header without chunked transfer encoding"}
+
+ // ErrMissingBoundary is returned by Request.MultipartReader when the
+ // request's Content-Type does not include a "boundary" parameter.
+ ErrMissingBoundary = &ProtocolError{"no multipart boundary param in Content-Type"}
+
+ // ErrNotMultipart is returned by Request.MultipartReader when the
+ // request's Content-Type is not multipart/form-data.
+ ErrNotMultipart = &ProtocolError{"request Content-Type isn't multipart/form-data"}
+
+ // Deprecated: ErrHeaderTooLong is no longer returned by
+ // anything in the net/http package. Callers should not
+ // compare errors against this variable.
+ ErrHeaderTooLong = &ProtocolError{"header too long"}
+
+ // Deprecated: ErrShortBody is no longer returned by
+ // anything in the net/http package. Callers should not
+ // compare errors against this variable.
+ ErrShortBody = &ProtocolError{"entity body too short"}
+
+ // Deprecated: ErrMissingContentLength is no longer returned by
+ // anything in the net/http package. Callers should not
+ // compare errors against this variable.
+ ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
+)
+
+func badStringError(what, val string) error { return fmt.Errorf("%s %q", what, val) }
+
+// Headers that Request.Write handles itself and should be skipped.
+var reqWriteExcludeHeader = map[string]bool{
+ "Host": true, // not in Header map anyway
+ "User-Agent": true,
+ "Content-Length": true,
+ "Transfer-Encoding": true,
+ "Trailer": true,
+}
+
+// A Request represents an HTTP request received by a server
+// or to be sent by a client.
+//
+// The field semantics differ slightly between client and server
+// usage. In addition to the notes on the fields below, see the
+// documentation for Request.Write and RoundTripper.
+type Request struct {
+ // Method specifies the HTTP method (GET, POST, PUT, etc.).
+ // For client requests, an empty string means GET.
+ //
+ // Go's HTTP client does not support sending a request with
+ // the CONNECT method. See the documentation on Transport for
+ // details.
+ Method string
+
+ // URL specifies either the URI being requested (for server
+ // requests) or the URL to access (for client requests).
+ //
+ // For server requests, the URL is parsed from the URI
+ // supplied on the Request-Line as stored in RequestURI. For
+ // most requests, fields other than Path and RawQuery will be
+ // empty. (See RFC 7230, Section 5.3)
+ //
+ // For client requests, the URL's Host specifies the server to
+ // connect to, while the Request's Host field optionally
+ // specifies the Host header value to send in the HTTP
+ // request.
+ URL *url.URL
+
+ // The protocol version for incoming server requests.
+ //
+ // For client requests, these fields are ignored. The HTTP
+ // client code always uses either HTTP/1.1 or HTTP/2.
+ // See the docs on Transport for details.
+ Proto string // "HTTP/1.0"
+ ProtoMajor int // 1
+ ProtoMinor int // 0
+
+ // Header contains the request header fields either received
+ // by the server or to be sent by the client.
+ //
+ // If a server received a request with header lines,
+ //
+ // Host: example.com
+ // accept-encoding: gzip, deflate
+ // Accept-Language: en-us
+ // fOO: Bar
+ // foo: two
+ //
+ // then
+ //
+ // Header = map[string][]string{
+ // "Accept-Encoding": {"gzip, deflate"},
+ // "Accept-Language": {"en-us"},
+ // "Foo": {"Bar", "two"},
+ // }
+ //
+ // For incoming requests, the Host header is promoted to the
+ // Request.Host field and removed from the Header map.
+ //
+ // HTTP defines that header names are case-insensitive. The
+ // request parser implements this by using CanonicalHeaderKey,
+ // making the first character and any characters following a
+ // hyphen uppercase and the rest lowercase.
+ //
+ // For client requests, certain headers such as Content-Length
+ // and Connection are automatically written when needed and
+ // values in Header may be ignored. See the documentation
+ // for the Request.Write method.
+ Header Header
+
+ // Body is the request's body.
+ //
+ // For client requests, a nil body means the request has no
+ // body, such as a GET request. The HTTP Client's Transport
+ // is responsible for calling the Close method.
+ //
+ // For server requests, the Request Body is always non-nil
+ // but will return EOF immediately when no body is present.
+ // The Server will close the request body. The ServeHTTP
+ // Handler does not need to.
+ //
+ // Body must allow Read to be called concurrently with Close.
+ // In particular, calling Close should unblock a Read waiting
+ // for input.
+ Body io.ReadCloser
+
+ // GetBody defines an optional func to return a new copy of
+ // Body. It is used for client requests when a redirect requires
+ // reading the body more than once. Use of GetBody still
+ // requires setting Body.
+ //
+ // For server requests, it is unused.
+ GetBody func() (io.ReadCloser, error)
+
+ // ContentLength records the length of the associated content.
+ // The value -1 indicates that the length is unknown.
+ // Values >= 0 indicate that the given number of bytes may
+ // be read from Body.
+ //
+ // For client requests, a value of 0 with a non-nil Body is
+ // also treated as unknown.
+ ContentLength int64
+
+ // TransferEncoding lists the transfer encodings from outermost to
+ // innermost. An empty list denotes the "identity" encoding.
+ // TransferEncoding can usually be ignored; chunked encoding is
+ // automatically added and removed as necessary when sending and
+ // receiving requests.
+ TransferEncoding []string
+
+ // Close indicates whether to close the connection after
+ // replying to this request (for servers) or after sending this
+ // request and reading its response (for clients).
+ //
+ // For server requests, the HTTP server handles this automatically
+ // and this field is not needed by Handlers.
+ //
+ // For client requests, setting this field prevents re-use of
+ // TCP connections between requests to the same hosts, as if
+ // Transport.DisableKeepAlives were set.
+ Close bool
+
+ // For server requests, Host specifies the host on which the
+ // URL is sought. For HTTP/1 (per RFC 7230, section 5.4), this
+ // is either the value of the "Host" header or the host name
+ // given in the URL itself. For HTTP/2, it is the value of the
+ // ":authority" pseudo-header field.
+ // It may be of the form "host:port". For international domain
+ // names, Host may be in Punycode or Unicode form. Use
+ // golang.org/x/net/idna to convert it to either format if
+ // needed.
+ // To prevent DNS rebinding attacks, server Handlers should
+ // validate that the Host header has a value for which the
+ // Handler considers itself authoritative. The included
+ // ServeMux supports patterns registered to particular host
+ // names and thus protects its registered Handlers.
+ //
+ // For client requests, Host optionally overrides the Host
+ // header to send. If empty, the Request.Write method uses
+ // the value of URL.Host. Host may contain an international
+ // domain name.
+ Host string
+
+ // Form contains the parsed form data, including both the URL
+ // field's query parameters and the PATCH, POST, or PUT form data.
+ // This field is only available after ParseForm is called.
+ // The HTTP client ignores Form and uses Body instead.
+ Form url.Values
+
+ // PostForm contains the parsed form data from PATCH, POST
+ // or PUT body parameters.
+ //
+ // This field is only available after ParseForm is called.
+ // The HTTP client ignores PostForm and uses Body instead.
+ PostForm url.Values
+
+ // MultipartForm is the parsed multipart form, including file uploads.
+ // This field is only available after ParseMultipartForm is called.
+ // The HTTP client ignores MultipartForm and uses Body instead.
+ MultipartForm *multipart.Form
+
+ // Trailer specifies additional headers that are sent after the request
+ // body.
+ //
+ // For server requests, the Trailer map initially contains only the
+ // trailer keys, with nil values. (The client declares which trailers it
+ // will later send.) While the handler is reading from Body, it must
+ // not reference Trailer. After reading from Body returns EOF, Trailer
+ // can be read again and will contain non-nil values, if they were sent
+ // by the client.
+ //
+ // For client requests, Trailer must be initialized to a map containing
+ // the trailer keys to later send. The values may be nil or their final
+ // values. The ContentLength must be 0 or -1, to send a chunked request.
+ // After the HTTP request is sent the map values can be updated while
+ // the request body is read. Once the body returns EOF, the caller must
+ // not mutate Trailer.
+ //
+ // Few HTTP clients, servers, or proxies support HTTP trailers.
+ Trailer Header
+
+ // RemoteAddr allows HTTP servers and other software to record
+ // the network address that sent the request, usually for
+ // logging. This field is not filled in by ReadRequest and
+ // has no defined format. The HTTP server in this package
+ // sets RemoteAddr to an "IP:port" address before invoking a
+ // handler.
+ // This field is ignored by the HTTP client.
+ RemoteAddr string
+
+ // RequestURI is the unmodified request-target of the
+ // Request-Line (RFC 7230, Section 3.1.1) as sent by the client
+ // to a server. Usually the URL field should be used instead.
+ // It is an error to set this field in an HTTP client request.
+ RequestURI string
+
+ // TLS allows HTTP servers and other software to record
+ // information about the TLS connection on which the request
+ // was received. This field is not filled in by ReadRequest.
+ // The HTTP server in this package sets the field for
+ // TLS-enabled connections before invoking a handler;
+ // otherwise it leaves the field nil.
+ // This field is ignored by the HTTP client.
+ TLS *tls.ConnectionState
+
+ // Cancel is an optional channel whose closure indicates that the client
+ // request should be regarded as canceled. Not all implementations of
+ // RoundTripper may support Cancel.
+ //
+ // For server requests, this field is not applicable.
+ //
+ // Deprecated: Set the Request's context with NewRequestWithContext
+ // instead. If a Request's Cancel field and context are both
+ // set, it is undefined whether Cancel is respected.
+ Cancel <-chan struct{}
+
+ // Response is the redirect response which caused this request
+ // to be created. This field is only populated during client
+ // redirects.
+ Response *Response
+
+ // ctx is either the client or server context. It should only
+ // be modified via copying the whole Request using Clone or WithContext.
+ // It is unexported to prevent people from using Context wrong
+ // and mutating the contexts held by callers of the same request.
+ ctx context.Context
+}
+
+// Context returns the request's context. To change the context, use
+// Clone or WithContext.
+//
+// The returned context is always non-nil; it defaults to the
+// background context.
+//
+// For outgoing client requests, the context controls cancellation.
+//
+// For incoming server requests, the context is canceled when the
+// client's connection closes, the request is canceled (with HTTP/2),
+// or when the ServeHTTP method returns.
+func (r *Request) Context() context.Context {
+ if r.ctx != nil {
+ return r.ctx
+ }
+ return context.Background()
+}
+
+// WithContext returns a shallow copy of r with its context changed
+// to ctx. The provided ctx must be non-nil.
+//
+// For outgoing client request, the context controls the entire
+// lifetime of a request and its response: obtaining a connection,
+// sending the request, and reading the response headers and body.
+//
+// To create a new request with a context, use NewRequestWithContext.
+// To make a deep copy of a request with a new context, use Request.Clone.
+func (r *Request) WithContext(ctx context.Context) *Request {
+ if ctx == nil {
+ panic("nil context")
+ }
+ r2 := new(Request)
+ *r2 = *r
+ r2.ctx = ctx
+ return r2
+}
+
+// Clone returns a deep copy of r with its context changed to ctx.
+// The provided ctx must be non-nil.
+//
+// For an outgoing client request, the context controls the entire
+// lifetime of a request and its response: obtaining a connection,
+// sending the request, and reading the response headers and body.
+func (r *Request) Clone(ctx context.Context) *Request {
+ if ctx == nil {
+ panic("nil context")
+ }
+ r2 := new(Request)
+ *r2 = *r
+ r2.ctx = ctx
+ r2.URL = cloneURL(r.URL)
+ if r.Header != nil {
+ r2.Header = r.Header.Clone()
+ }
+ if r.Trailer != nil {
+ r2.Trailer = r.Trailer.Clone()
+ }
+ if s := r.TransferEncoding; s != nil {
+ s2 := make([]string, len(s))
+ copy(s2, s)
+ r2.TransferEncoding = s2
+ }
+ r2.Form = cloneURLValues(r.Form)
+ r2.PostForm = cloneURLValues(r.PostForm)
+ r2.MultipartForm = cloneMultipartForm(r.MultipartForm)
+ return r2
+}
+
+// ProtoAtLeast reports whether the HTTP protocol used
+// in the request is at least major.minor.
+func (r *Request) ProtoAtLeast(major, minor int) bool {
+ return r.ProtoMajor > major ||
+ r.ProtoMajor == major && r.ProtoMinor >= minor
+}
+
+// UserAgent returns the client's User-Agent, if sent in the request.
+func (r *Request) UserAgent() string {
+ return r.Header.Get("User-Agent")
+}
+
+// Cookies parses and returns the HTTP cookies sent with the request.
+func (r *Request) Cookies() []*Cookie {
+ return readCookies(r.Header, "")
+}
+
+// ErrNoCookie is returned by Request's Cookie method when a cookie is not found.
+var ErrNoCookie = errors.New("http: named cookie not present")
+
+// Cookie returns the named cookie provided in the request or
+// ErrNoCookie if not found.
+// If multiple cookies match the given name, only one cookie will
+// be returned.
+func (r *Request) Cookie(name string) (*Cookie, error) {
+ if name == "" {
+ return nil, ErrNoCookie
+ }
+ for _, c := range readCookies(r.Header, name) {
+ return c, nil
+ }
+ return nil, ErrNoCookie
+}
+
+// AddCookie adds a cookie to the request. Per RFC 6265 section 5.4,
+// AddCookie does not attach more than one Cookie header field. That
+// means all cookies, if any, are written into the same line,
+// separated by semicolon.
+// AddCookie only sanitizes c's name and value, and does not sanitize
+// a Cookie header already present in the request.
+func (r *Request) AddCookie(c *Cookie) {
+ s := fmt.Sprintf("%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value))
+ if c := r.Header.Get("Cookie"); c != "" {
+ r.Header.Set("Cookie", c+"; "+s)
+ } else {
+ r.Header.Set("Cookie", s)
+ }
+}
+
+// Referer returns the referring URL, if sent in the request.
+//
+// Referer is misspelled as in the request itself, a mistake from the
+// earliest days of HTTP. This value can also be fetched from the
+// Header map as Header["Referer"]; the benefit of making it available
+// as a method is that the compiler can diagnose programs that use the
+// alternate (correct English) spelling req.Referrer() but cannot
+// diagnose programs that use Header["Referrer"].
+func (r *Request) Referer() string {
+ return r.Header.Get("Referer")
+}
+
+// multipartByReader is a sentinel value.
+// Its presence in Request.MultipartForm indicates that parsing of the request
+// body has been handed off to a MultipartReader instead of ParseMultipartForm.
+var multipartByReader = &multipart.Form{
+ Value: make(map[string][]string),
+ File: make(map[string][]*multipart.FileHeader),
+}
+
+// MultipartReader returns a MIME multipart reader if this is a
+// multipart/form-data or a multipart/mixed POST request, else returns nil and an error.
+// Use this function instead of ParseMultipartForm to
+// process the request body as a stream.
+func (r *Request) MultipartReader() (*multipart.Reader, error) {
+ if r.MultipartForm == multipartByReader {
+ return nil, errors.New("http: MultipartReader called twice")
+ }
+ if r.MultipartForm != nil {
+ return nil, errors.New("http: multipart handled by ParseMultipartForm")
+ }
+ r.MultipartForm = multipartByReader
+ return r.multipartReader(true)
+}
+
+func (r *Request) multipartReader(allowMixed bool) (*multipart.Reader, error) {
+ v := r.Header.Get("Content-Type")
+ if v == "" {
+ return nil, ErrNotMultipart
+ }
+ if r.Body == nil {
+ return nil, errors.New("missing form body")
+ }
+ d, params, err := mime.ParseMediaType(v)
+ if err != nil || !(d == "multipart/form-data" || allowMixed && d == "multipart/mixed") {
+ return nil, ErrNotMultipart
+ }
+ boundary, ok := params["boundary"]
+ if !ok {
+ return nil, ErrMissingBoundary
+ }
+ return multipart.NewReader(r.Body, boundary), nil
+}
+
+// isH2Upgrade reports whether r represents the http2 "client preface"
+// magic string.
+func (r *Request) isH2Upgrade() bool {
+ return r.Method == "PRI" && len(r.Header) == 0 && r.URL.Path == "*" && r.Proto == "HTTP/2.0"
+}
+
+// Return value if nonempty, def otherwise.
+func valueOrDefault(value, def string) string {
+ if value != "" {
+ return value
+ }
+ return def
+}
+
+// NOTE: This is not intended to reflect the actual Go version being used.
+// It was changed at the time of Go 1.1 release because the former User-Agent
+// had ended up blocked by some intrusion detection systems.
+// See https://codereview.appspot.com/7532043.
+const defaultUserAgent = "Go-http-client/1.1"
+
+// Write writes an HTTP/1.1 request, which is the header and body, in wire format.
+// This method consults the following fields of the request:
+//
+// Host
+// URL
+// Method (defaults to "GET")
+// Header
+// ContentLength
+// TransferEncoding
+// Body
+//
+// If Body is present, Content-Length is <= 0 and TransferEncoding
+// hasn't been set to "identity", Write adds "Transfer-Encoding:
+// chunked" to the header. Body is closed after it is sent.
+func (r *Request) Write(w io.Writer) error {
+ return r.write(w, false, nil, nil)
+}
+
+// WriteProxy is like Write but writes the request in the form
+// expected by an HTTP proxy. In particular, WriteProxy writes the
+// initial Request-URI line of the request with an absolute URI, per
+// section 5.3 of RFC 7230, including the scheme and host.
+// In either case, WriteProxy also writes a Host header, using
+// either r.Host or r.URL.Host.
+func (r *Request) WriteProxy(w io.Writer) error {
+ return r.write(w, true, nil, nil)
+}
+
+// errMissingHost is returned by Write when there is no Host or URL present in
+// the Request.
+var errMissingHost = errors.New("http: Request.Write on Request with no Host or URL set")
+
+// extraHeaders may be nil
+// waitForContinue may be nil
+// always closes body
+func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitForContinue func() bool) (err error) {
+ trace := httptrace.ContextClientTrace(r.Context())
+ if trace != nil && trace.WroteRequest != nil {
+ defer func() {
+ trace.WroteRequest(httptrace.WroteRequestInfo{
+ Err: err,
+ })
+ }()
+ }
+ closed := false
+ defer func() {
+ if closed {
+ return
+ }
+ if closeErr := r.closeBody(); closeErr != nil && err == nil {
+ err = closeErr
+ }
+ }()
+
+ // Find the target host. Prefer the Host: header, but if that
+ // is not given, use the host from the request URL.
+ //
+ // Clean the host, in case it arrives with unexpected stuff in it.
+ host := r.Host
+ if host == "" {
+ if r.URL == nil {
+ return errMissingHost
+ }
+ host = r.URL.Host
+ }
+ host, err = httpguts.PunycodeHostPort(host)
+ if err != nil {
+ return err
+ }
+ // Validate that the Host header is a valid header in general,
+ // but don't validate the host itself. This is sufficient to avoid
+ // header or request smuggling via the Host field.
+ // The server can (and will, if it's a net/http server) reject
+ // the request if it doesn't consider the host valid.
+ if !httpguts.ValidHostHeader(host) {
+ // Historically, we would truncate the Host header after '/' or ' '.
+ // Some users have relied on this truncation to convert a network
+ // address such as Unix domain socket path into a valid, ignored
+ // Host header (see https://go.dev/issue/61431).
+ //
+ // We don't preserve the truncation, because sending an altered
+ // header field opens a smuggling vector. Instead, zero out the
+ // Host header entirely if it isn't valid. (An empty Host is valid;
+ // see RFC 9112 Section 3.2.)
+ //
+ // Return an error if we're sending to a proxy, since the proxy
+ // probably can't do anything useful with an empty Host header.
+ if !usingProxy {
+ host = ""
+ } else {
+ return errors.New("http: invalid Host header")
+ }
+ }
+
+ // According to RFC 6874, an HTTP client, proxy, or other
+ // intermediary must remove any IPv6 zone identifier attached
+ // to an outgoing URI.
+ host = removeZone(host)
+
+ ruri := r.URL.RequestURI()
+ if usingProxy && r.URL.Scheme != "" && r.URL.Opaque == "" {
+ ruri = r.URL.Scheme + "://" + host + ruri
+ } else if r.Method == "CONNECT" && r.URL.Path == "" {
+ // CONNECT requests normally give just the host and port, not a full URL.
+ ruri = host
+ if r.URL.Opaque != "" {
+ ruri = r.URL.Opaque
+ }
+ }
+ if stringContainsCTLByte(ruri) {
+ return errors.New("net/http: can't write control character in Request.URL")
+ }
+ // TODO: validate r.Method too? At least it's less likely to
+ // come from an attacker (more likely to be a constant in
+ // code).
+
+ // Wrap the writer in a bufio Writer if it's not already buffered.
+ // Don't always call NewWriter, as that forces a bytes.Buffer
+ // and other small bufio Writers to have a minimum 4k buffer
+ // size.
+ var bw *bufio.Writer
+ if _, ok := w.(io.ByteWriter); !ok {
+ bw = bufio.NewWriter(w)
+ w = bw
+ }
+
+ _, err = fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(r.Method, "GET"), ruri)
+ if err != nil {
+ return err
+ }
+
+ // Header lines
+ _, err = fmt.Fprintf(w, "Host: %s\r\n", host)
+ if err != nil {
+ return err
+ }
+ if trace != nil && trace.WroteHeaderField != nil {
+ trace.WroteHeaderField("Host", []string{host})
+ }
+
+ // Use the defaultUserAgent unless the Header contains one, which
+ // may be blank to not send the header.
+ userAgent := defaultUserAgent
+ if r.Header.has("User-Agent") {
+ userAgent = r.Header.Get("User-Agent")
+ }
+ if userAgent != "" {
+ _, err = fmt.Fprintf(w, "User-Agent: %s\r\n", userAgent)
+ if err != nil {
+ return err
+ }
+ if trace != nil && trace.WroteHeaderField != nil {
+ trace.WroteHeaderField("User-Agent", []string{userAgent})
+ }
+ }
+
+ // Process Body,ContentLength,Close,Trailer
+ tw, err := newTransferWriter(r)
+ if err != nil {
+ return err
+ }
+ err = tw.writeHeader(w, trace)
+ if err != nil {
+ return err
+ }
+
+ err = r.Header.writeSubset(w, reqWriteExcludeHeader, trace)
+ if err != nil {
+ return err
+ }
+
+ if extraHeaders != nil {
+ err = extraHeaders.write(w, trace)
+ if err != nil {
+ return err
+ }
+ }
+
+ _, err = io.WriteString(w, "\r\n")
+ if err != nil {
+ return err
+ }
+
+ if trace != nil && trace.WroteHeaders != nil {
+ trace.WroteHeaders()
+ }
+
+ // Flush and wait for 100-continue if expected.
+ if waitForContinue != nil {
+ if bw, ok := w.(*bufio.Writer); ok {
+ err = bw.Flush()
+ if err != nil {
+ return err
+ }
+ }
+ if trace != nil && trace.Wait100Continue != nil {
+ trace.Wait100Continue()
+ }
+ if !waitForContinue() {
+ closed = true
+ r.closeBody()
+ return nil
+ }
+ }
+
+ if bw, ok := w.(*bufio.Writer); ok && tw.FlushHeaders {
+ if err := bw.Flush(); err != nil {
+ return err
+ }
+ }
+
+ // Write body and trailer
+ closed = true
+ err = tw.writeBody(w)
+ if err != nil {
+ if tw.bodyReadError == err {
+ err = requestBodyReadError{err}
+ }
+ return err
+ }
+
+ if bw != nil {
+ return bw.Flush()
+ }
+ return nil
+}
+
+// requestBodyReadError wraps an error from (*Request).write to indicate
+// that the error came from a Read call on the Request.Body.
+// This error type should not escape the net/http package to users.
+type requestBodyReadError struct{ error }
+
+func idnaASCII(v string) (string, error) {
+ // TODO: Consider removing this check after verifying performance is okay.
+ // Right now punycode verification, length checks, context checks, and the
+ // permissible character tests are all omitted. It also prevents the ToASCII
+ // call from salvaging an invalid IDN, when possible. As a result it may be
+ // possible to have two IDNs that appear identical to the user where the
+ // ASCII-only version causes an error downstream whereas the non-ASCII
+ // version does not.
+ // Note that for correct ASCII IDNs ToASCII will only do considerably more
+ // work, but it will not cause an allocation.
+ if ascii.Is(v) {
+ return v, nil
+ }
+ return idna.Lookup.ToASCII(v)
+}
+
+// removeZone removes IPv6 zone identifier from host.
+// E.g., "[fe80::1%en0]:8080" to "[fe80::1]:8080"
+func removeZone(host string) string {
+ if !strings.HasPrefix(host, "[") {
+ return host
+ }
+ i := strings.LastIndex(host, "]")
+ if i < 0 {
+ return host
+ }
+ j := strings.LastIndex(host[:i], "%")
+ if j < 0 {
+ return host
+ }
+ return host[:j] + host[i:]
+}
+
+// ParseHTTPVersion parses an HTTP version string according to RFC 7230, section 2.6.
+// "HTTP/1.0" returns (1, 0, true). Note that strings without
+// a minor version, such as "HTTP/2", are not valid.
+func ParseHTTPVersion(vers string) (major, minor int, ok bool) {
+ switch vers {
+ case "HTTP/1.1":
+ return 1, 1, true
+ case "HTTP/1.0":
+ return 1, 0, true
+ }
+ if !strings.HasPrefix(vers, "HTTP/") {
+ return 0, 0, false
+ }
+ if len(vers) != len("HTTP/X.Y") {
+ return 0, 0, false
+ }
+ if vers[6] != '.' {
+ return 0, 0, false
+ }
+ maj, err := strconv.ParseUint(vers[5:6], 10, 0)
+ if err != nil {
+ return 0, 0, false
+ }
+ min, err := strconv.ParseUint(vers[7:8], 10, 0)
+ if err != nil {
+ return 0, 0, false
+ }
+ return int(maj), int(min), true
+}
+
+func validMethod(method string) bool {
+ /*
+ Method = "OPTIONS" ; Section 9.2
+ | "GET" ; Section 9.3
+ | "HEAD" ; Section 9.4
+ | "POST" ; Section 9.5
+ | "PUT" ; Section 9.6
+ | "DELETE" ; Section 9.7
+ | "TRACE" ; Section 9.8
+ | "CONNECT" ; Section 9.9
+ | extension-method
+ extension-method = token
+ token = 1*<any CHAR except CTLs or separators>
+ */
+ return len(method) > 0 && strings.IndexFunc(method, isNotToken) == -1
+}
+
+// NewRequest wraps NewRequestWithContext using context.Background.
+func NewRequest(method, url string, body io.Reader) (*Request, error) {
+ return NewRequestWithContext(context.Background(), method, url, body)
+}
+
+// NewRequestWithContext returns a new Request given a method, URL, and
+// optional body.
+//
+// If the provided body is also an io.Closer, the returned
+// Request.Body is set to body and will be closed by the Client
+// methods Do, Post, and PostForm, and Transport.RoundTrip.
+//
+// NewRequestWithContext returns a Request suitable for use with
+// Client.Do or Transport.RoundTrip. To create a request for use with
+// testing a Server Handler, either use the NewRequest function in the
+// net/http/httptest package, use ReadRequest, or manually update the
+// Request fields. For an outgoing client request, the context
+// controls the entire lifetime of a request and its response:
+// obtaining a connection, sending the request, and reading the
+// response headers and body. See the Request type's documentation for
+// the difference between inbound and outbound request fields.
+//
+// If body is of type *bytes.Buffer, *bytes.Reader, or
+// *strings.Reader, the returned request's ContentLength is set to its
+// exact value (instead of -1), GetBody is populated (so 307 and 308
+// redirects can replay the body), and Body is set to NoBody if the
+// ContentLength is 0.
+func NewRequestWithContext(ctx context.Context, method, url string, body io.Reader) (*Request, error) {
+ if method == "" {
+ // We document that "" means "GET" for Request.Method, and people have
+ // relied on that from NewRequest, so keep that working.
+ // We still enforce validMethod for non-empty methods.
+ method = "GET"
+ }
+ if !validMethod(method) {
+ return nil, fmt.Errorf("net/http: invalid method %q", method)
+ }
+ if ctx == nil {
+ return nil, errors.New("net/http: nil Context")
+ }
+ u, err := urlpkg.Parse(url)
+ if err != nil {
+ return nil, err
+ }
+ rc, ok := body.(io.ReadCloser)
+ if !ok && body != nil {
+ rc = io.NopCloser(body)
+ }
+ // The host's colon:port should be normalized. See Issue 14836.
+ u.Host = removeEmptyPort(u.Host)
+ req := &Request{
+ ctx: ctx,
+ Method: method,
+ URL: u,
+ Proto: "HTTP/1.1",
+ ProtoMajor: 1,
+ ProtoMinor: 1,
+ Header: make(Header),
+ Body: rc,
+ Host: u.Host,
+ }
+ if body != nil {
+ switch v := body.(type) {
+ case *bytes.Buffer:
+ req.ContentLength = int64(v.Len())
+ buf := v.Bytes()
+ req.GetBody = func() (io.ReadCloser, error) {
+ r := bytes.NewReader(buf)
+ return io.NopCloser(r), nil
+ }
+ case *bytes.Reader:
+ req.ContentLength = int64(v.Len())
+ snapshot := *v
+ req.GetBody = func() (io.ReadCloser, error) {
+ r := snapshot
+ return io.NopCloser(&r), nil
+ }
+ case *strings.Reader:
+ req.ContentLength = int64(v.Len())
+ snapshot := *v
+ req.GetBody = func() (io.ReadCloser, error) {
+ r := snapshot
+ return io.NopCloser(&r), nil
+ }
+ default:
+ // This is where we'd set it to -1 (at least
+ // if body != NoBody) to mean unknown, but
+ // that broke people during the Go 1.8 testing
+ // period. People depend on it being 0 I
+ // guess. Maybe retry later. See Issue 18117.
+ }
+ // For client requests, Request.ContentLength of 0
+ // means either actually 0, or unknown. The only way
+ // to explicitly say that the ContentLength is zero is
+ // to set the Body to nil. But turns out too much code
+ // depends on NewRequest returning a non-nil Body,
+ // so we use a well-known ReadCloser variable instead
+ // and have the http package also treat that sentinel
+ // variable to mean explicitly zero.
+ if req.GetBody != nil && req.ContentLength == 0 {
+ req.Body = NoBody
+ req.GetBody = func() (io.ReadCloser, error) { return NoBody, nil }
+ }
+ }
+
+ return req, nil
+}
+
+// BasicAuth returns the username and password provided in the request's
+// Authorization header, if the request uses HTTP Basic Authentication.
+// See RFC 2617, Section 2.
+func (r *Request) BasicAuth() (username, password string, ok bool) {
+ auth := r.Header.Get("Authorization")
+ if auth == "" {
+ return "", "", false
+ }
+ return parseBasicAuth(auth)
+}
+
+// parseBasicAuth parses an HTTP Basic Authentication string.
+// "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" returns ("Aladdin", "open sesame", true).
+func parseBasicAuth(auth string) (username, password string, ok bool) {
+ const prefix = "Basic "
+ // Case insensitive prefix match. See Issue 22736.
+ if len(auth) < len(prefix) || !ascii.EqualFold(auth[:len(prefix)], prefix) {
+ return "", "", false
+ }
+ c, err := base64.StdEncoding.DecodeString(auth[len(prefix):])
+ if err != nil {
+ return "", "", false
+ }
+ cs := string(c)
+ username, password, ok = strings.Cut(cs, ":")
+ if !ok {
+ return "", "", false
+ }
+ return username, password, true
+}
+
+// SetBasicAuth sets the request's Authorization header to use HTTP
+// Basic Authentication with the provided username and password.
+//
+// With HTTP Basic Authentication the provided username and password
+// are not encrypted. It should generally only be used in an HTTPS
+// request.
+//
+// The username may not contain a colon. Some protocols may impose
+// additional requirements on pre-escaping the username and
+// password. For instance, when used with OAuth2, both arguments must
+// be URL encoded first with url.QueryEscape.
+func (r *Request) SetBasicAuth(username, password string) {
+ r.Header.Set("Authorization", "Basic "+basicAuth(username, password))
+}
+
+// parseRequestLine parses "GET /foo HTTP/1.1" into its three parts.
+func parseRequestLine(line string) (method, requestURI, proto string, ok bool) {
+ method, rest, ok1 := strings.Cut(line, " ")
+ requestURI, proto, ok2 := strings.Cut(rest, " ")
+ if !ok1 || !ok2 {
+ return "", "", "", false
+ }
+ return method, requestURI, proto, true
+}
+
+var textprotoReaderPool sync.Pool
+
+func newTextprotoReader(br *bufio.Reader) *textproto.Reader {
+ if v := textprotoReaderPool.Get(); v != nil {
+ tr := v.(*textproto.Reader)
+ tr.R = br
+ return tr
+ }
+ return textproto.NewReader(br)
+}
+
+func putTextprotoReader(r *textproto.Reader) {
+ r.R = nil
+ textprotoReaderPool.Put(r)
+}
+
+// ReadRequest reads and parses an incoming request from b.
+//
+// ReadRequest is a low-level function and should only be used for
+// specialized applications; most code should use the Server to read
+// requests and handle them via the Handler interface. ReadRequest
+// only supports HTTP/1.x requests. For HTTP/2, use golang.org/x/net/http2.
+func ReadRequest(b *bufio.Reader) (*Request, error) {
+ req, err := readRequest(b)
+ if err != nil {
+ return nil, err
+ }
+
+ delete(req.Header, "Host")
+ return req, err
+}
+
+func readRequest(b *bufio.Reader) (req *Request, err error) {
+ tp := newTextprotoReader(b)
+ defer putTextprotoReader(tp)
+
+ req = new(Request)
+
+ // First line: GET /index.html HTTP/1.0
+ var s string
+ if s, err = tp.ReadLine(); err != nil {
+ return nil, err
+ }
+ defer func() {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ }()
+
+ var ok bool
+ req.Method, req.RequestURI, req.Proto, ok = parseRequestLine(s)
+ if !ok {
+ return nil, badStringError("malformed HTTP request", s)
+ }
+ if !validMethod(req.Method) {
+ return nil, badStringError("invalid method", req.Method)
+ }
+ rawurl := req.RequestURI
+ if req.ProtoMajor, req.ProtoMinor, ok = ParseHTTPVersion(req.Proto); !ok {
+ return nil, badStringError("malformed HTTP version", req.Proto)
+ }
+
+ // CONNECT requests are used two different ways, and neither uses a full URL:
+ // The standard use is to tunnel HTTPS through an HTTP proxy.
+ // It looks like "CONNECT www.google.com:443 HTTP/1.1", and the parameter is
+ // just the authority section of a URL. This information should go in req.URL.Host.
+ //
+ // The net/rpc package also uses CONNECT, but there the parameter is a path
+ // that starts with a slash. It can be parsed with the regular URL parser,
+ // and the path will end up in req.URL.Path, where it needs to be in order for
+ // RPC to work.
+ justAuthority := req.Method == "CONNECT" && !strings.HasPrefix(rawurl, "/")
+ if justAuthority {
+ rawurl = "http://" + rawurl
+ }
+
+ if req.URL, err = url.ParseRequestURI(rawurl); err != nil {
+ return nil, err
+ }
+
+ if justAuthority {
+ // Strip the bogus "http://" back off.
+ req.URL.Scheme = ""
+ }
+
+ // Subsequent lines: Key: value.
+ mimeHeader, err := tp.ReadMIMEHeader()
+ if err != nil {
+ return nil, err
+ }
+ req.Header = Header(mimeHeader)
+ if len(req.Header["Host"]) > 1 {
+ return nil, fmt.Errorf("too many Host headers")
+ }
+
+ // RFC 7230, section 5.3: Must treat
+ // GET /index.html HTTP/1.1
+ // Host: www.google.com
+ // and
+ // GET http://www.google.com/index.html HTTP/1.1
+ // Host: doesntmatter
+ // the same. In the second case, any Host line is ignored.
+ req.Host = req.URL.Host
+ if req.Host == "" {
+ req.Host = req.Header.get("Host")
+ }
+
+ fixPragmaCacheControl(req.Header)
+
+ req.Close = shouldClose(req.ProtoMajor, req.ProtoMinor, req.Header, false)
+
+ err = readTransfer(req, b)
+ if err != nil {
+ return nil, err
+ }
+
+ if req.isH2Upgrade() {
+ // Because it's neither chunked, nor declared:
+ req.ContentLength = -1
+
+ // We want to give handlers a chance to hijack the
+ // connection, but we need to prevent the Server from
+ // dealing with the connection further if it's not
+ // hijacked. Set Close to ensure that:
+ req.Close = true
+ }
+ return req, nil
+}
+
+// MaxBytesReader is similar to io.LimitReader but is intended for
+// limiting the size of incoming request bodies. In contrast to
+// io.LimitReader, MaxBytesReader's result is a ReadCloser, returns a
+// non-nil error of type *MaxBytesError for a Read beyond the limit,
+// and closes the underlying reader when its Close method is called.
+//
+// MaxBytesReader prevents clients from accidentally or maliciously
+// sending a large request and wasting server resources. If possible,
+// it tells the ResponseWriter to close the connection after the limit
+// has been reached.
+func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser {
+ if n < 0 { // Treat negative limits as equivalent to 0.
+ n = 0
+ }
+ return &maxBytesReader{w: w, r: r, i: n, n: n}
+}
+
+// MaxBytesError is returned by MaxBytesReader when its read limit is exceeded.
+type MaxBytesError struct {
+ Limit int64
+}
+
+func (e *MaxBytesError) Error() string {
+ // Due to Hyrum's law, this text cannot be changed.
+ return "http: request body too large"
+}
+
+type maxBytesReader struct {
+ w ResponseWriter
+ r io.ReadCloser // underlying reader
+ i int64 // max bytes initially, for MaxBytesError
+ n int64 // max bytes remaining
+ err error // sticky error
+}
+
+func (l *maxBytesReader) Read(p []byte) (n int, err error) {
+ if l.err != nil {
+ return 0, l.err
+ }
+ if len(p) == 0 {
+ return 0, nil
+ }
+ // If they asked for a 32KB byte read but only 5 bytes are
+ // remaining, no need to read 32KB. 6 bytes will answer the
+ // question of the whether we hit the limit or go past it.
+ // 0 < len(p) < 2^63
+ if int64(len(p))-1 > l.n {
+ p = p[:l.n+1]
+ }
+ n, err = l.r.Read(p)
+
+ if int64(n) <= l.n {
+ l.n -= int64(n)
+ l.err = err
+ return n, err
+ }
+
+ n = int(l.n)
+ l.n = 0
+
+ // The server code and client code both use
+ // maxBytesReader. This "requestTooLarge" check is
+ // only used by the server code. To prevent binaries
+ // which only using the HTTP Client code (such as
+ // cmd/go) from also linking in the HTTP server, don't
+ // use a static type assertion to the server
+ // "*response" type. Check this interface instead:
+ type requestTooLarger interface {
+ requestTooLarge()
+ }
+ if res, ok := l.w.(requestTooLarger); ok {
+ res.requestTooLarge()
+ }
+ l.err = &MaxBytesError{l.i}
+ return n, l.err
+}
+
+func (l *maxBytesReader) Close() error {
+ return l.r.Close()
+}
+
+func copyValues(dst, src url.Values) {
+ for k, vs := range src {
+ dst[k] = append(dst[k], vs...)
+ }
+}
+
+func parsePostForm(r *Request) (vs url.Values, err error) {
+ if r.Body == nil {
+ err = errors.New("missing form body")
+ return
+ }
+ ct := r.Header.Get("Content-Type")
+ // RFC 7231, section 3.1.1.5 - empty type
+ // MAY be treated as application/octet-stream
+ if ct == "" {
+ ct = "application/octet-stream"
+ }
+ ct, _, err = mime.ParseMediaType(ct)
+ switch {
+ case ct == "application/x-www-form-urlencoded":
+ var reader io.Reader = r.Body
+ maxFormSize := int64(1<<63 - 1)
+ if _, ok := r.Body.(*maxBytesReader); !ok {
+ maxFormSize = int64(10 << 20) // 10 MB is a lot of text.
+ reader = io.LimitReader(r.Body, maxFormSize+1)
+ }
+ b, e := io.ReadAll(reader)
+ if e != nil {
+ if err == nil {
+ err = e
+ }
+ break
+ }
+ if int64(len(b)) > maxFormSize {
+ err = errors.New("http: POST too large")
+ return
+ }
+ vs, e = url.ParseQuery(string(b))
+ if err == nil {
+ err = e
+ }
+ case ct == "multipart/form-data":
+ // handled by ParseMultipartForm (which is calling us, or should be)
+ // TODO(bradfitz): there are too many possible
+ // orders to call too many functions here.
+ // Clean this up and write more tests.
+ // request_test.go contains the start of this,
+ // in TestParseMultipartFormOrder and others.
+ }
+ return
+}
+
+// ParseForm populates r.Form and r.PostForm.
+//
+// For all requests, ParseForm parses the raw query from the URL and updates
+// r.Form.
+//
+// For POST, PUT, and PATCH requests, it also reads the request body, parses it
+// as a form and puts the results into both r.PostForm and r.Form. Request body
+// parameters take precedence over URL query string values in r.Form.
+//
+// If the request Body's size has not already been limited by MaxBytesReader,
+// the size is capped at 10MB.
+//
+// For other HTTP methods, or when the Content-Type is not
+// application/x-www-form-urlencoded, the request Body is not read, and
+// r.PostForm is initialized to a non-nil, empty value.
+//
+// ParseMultipartForm calls ParseForm automatically.
+// ParseForm is idempotent.
+func (r *Request) ParseForm() error {
+ var err error
+ if r.PostForm == nil {
+ if r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" {
+ r.PostForm, err = parsePostForm(r)
+ }
+ if r.PostForm == nil {
+ r.PostForm = make(url.Values)
+ }
+ }
+ if r.Form == nil {
+ if len(r.PostForm) > 0 {
+ r.Form = make(url.Values)
+ copyValues(r.Form, r.PostForm)
+ }
+ var newValues url.Values
+ if r.URL != nil {
+ var e error
+ newValues, e = url.ParseQuery(r.URL.RawQuery)
+ if err == nil {
+ err = e
+ }
+ }
+ if newValues == nil {
+ newValues = make(url.Values)
+ }
+ if r.Form == nil {
+ r.Form = newValues
+ } else {
+ copyValues(r.Form, newValues)
+ }
+ }
+ return err
+}
+
+// ParseMultipartForm parses a request body as multipart/form-data.
+// The whole request body is parsed and up to a total of maxMemory bytes of
+// its file parts are stored in memory, with the remainder stored on
+// disk in temporary files.
+// ParseMultipartForm calls ParseForm if necessary.
+// If ParseForm returns an error, ParseMultipartForm returns it but also
+// continues parsing the request body.
+// After one call to ParseMultipartForm, subsequent calls have no effect.
+func (r *Request) ParseMultipartForm(maxMemory int64) error {
+ if r.MultipartForm == multipartByReader {
+ return errors.New("http: multipart handled by MultipartReader")
+ }
+ var parseFormErr error
+ if r.Form == nil {
+ // Let errors in ParseForm fall through, and just
+ // return it at the end.
+ parseFormErr = r.ParseForm()
+ }
+ if r.MultipartForm != nil {
+ return nil
+ }
+
+ mr, err := r.multipartReader(false)
+ if err != nil {
+ return err
+ }
+
+ f, err := mr.ReadForm(maxMemory)
+ if err != nil {
+ return err
+ }
+
+ if r.PostForm == nil {
+ r.PostForm = make(url.Values)
+ }
+ for k, v := range f.Value {
+ r.Form[k] = append(r.Form[k], v...)
+ // r.PostForm should also be populated. See Issue 9305.
+ r.PostForm[k] = append(r.PostForm[k], v...)
+ }
+
+ r.MultipartForm = f
+
+ return parseFormErr
+}
+
+// FormValue returns the first value for the named component of the query.
+// POST and PUT body parameters take precedence over URL query string values.
+// FormValue calls ParseMultipartForm and ParseForm if necessary and ignores
+// any errors returned by these functions.
+// If key is not present, FormValue returns the empty string.
+// To access multiple values of the same key, call ParseForm and
+// then inspect Request.Form directly.
+func (r *Request) FormValue(key string) string {
+ if r.Form == nil {
+ r.ParseMultipartForm(defaultMaxMemory)
+ }
+ if vs := r.Form[key]; len(vs) > 0 {
+ return vs[0]
+ }
+ return ""
+}
+
+// PostFormValue returns the first value for the named component of the POST,
+// PATCH, or PUT request body. URL query parameters are ignored.
+// PostFormValue calls ParseMultipartForm and ParseForm if necessary and ignores
+// any errors returned by these functions.
+// If key is not present, PostFormValue returns the empty string.
+func (r *Request) PostFormValue(key string) string {
+ if r.PostForm == nil {
+ r.ParseMultipartForm(defaultMaxMemory)
+ }
+ if vs := r.PostForm[key]; len(vs) > 0 {
+ return vs[0]
+ }
+ return ""
+}
+
+// FormFile returns the first file for the provided form key.
+// FormFile calls ParseMultipartForm and ParseForm if necessary.
+func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) {
+ if r.MultipartForm == multipartByReader {
+ return nil, nil, errors.New("http: multipart handled by MultipartReader")
+ }
+ if r.MultipartForm == nil {
+ err := r.ParseMultipartForm(defaultMaxMemory)
+ if err != nil {
+ return nil, nil, err
+ }
+ }
+ if r.MultipartForm != nil && r.MultipartForm.File != nil {
+ if fhs := r.MultipartForm.File[key]; len(fhs) > 0 {
+ f, err := fhs[0].Open()
+ return f, fhs[0], err
+ }
+ }
+ return nil, nil, ErrMissingFile
+}
+
+func (r *Request) expectsContinue() bool {
+ return hasToken(r.Header.get("Expect"), "100-continue")
+}
+
+func (r *Request) wantsHttp10KeepAlive() bool {
+ if r.ProtoMajor != 1 || r.ProtoMinor != 0 {
+ return false
+ }
+ return hasToken(r.Header.get("Connection"), "keep-alive")
+}
+
+func (r *Request) wantsClose() bool {
+ if r.Close {
+ return true
+ }
+ return hasToken(r.Header.get("Connection"), "close")
+}
+
+func (r *Request) closeBody() error {
+ if r.Body == nil {
+ return nil
+ }
+ return r.Body.Close()
+}
+
+func (r *Request) isReplayable() bool {
+ if r.Body == nil || r.Body == NoBody || r.GetBody != nil {
+ switch valueOrDefault(r.Method, "GET") {
+ case "GET", "HEAD", "OPTIONS", "TRACE":
+ return true
+ }
+ // The Idempotency-Key, while non-standard, is widely used to
+ // mean a POST or other request is idempotent. See
+ // https://golang.org/issue/19943#issuecomment-421092421
+ if r.Header.has("Idempotency-Key") || r.Header.has("X-Idempotency-Key") {
+ return true
+ }
+ }
+ return false
+}
+
+// outgoingLength reports the Content-Length of this outgoing (Client) request.
+// It maps 0 into -1 (unknown) when the Body is non-nil.
+func (r *Request) outgoingLength() int64 {
+ if r.Body == nil || r.Body == NoBody {
+ return 0
+ }
+ if r.ContentLength != 0 {
+ return r.ContentLength
+ }
+ return -1
+}
+
+// requestMethodUsuallyLacksBody reports whether the given request
+// method is one that typically does not involve a request body.
+// This is used by the Transport (via
+// transferWriter.shouldSendChunkedRequestBody) to determine whether
+// we try to test-read a byte from a non-nil Request.Body when
+// Request.outgoingLength() returns -1. See the comments in
+// shouldSendChunkedRequestBody.
+func requestMethodUsuallyLacksBody(method string) bool {
+ switch method {
+ case "GET", "HEAD", "DELETE", "OPTIONS", "PROPFIND", "SEARCH":
+ return true
+ }
+ return false
+}
+
+// requiresHTTP1 reports whether this request requires being sent on
+// an HTTP/1 connection.
+func (r *Request) requiresHTTP1() bool {
+ return hasToken(r.Header.Get("Connection"), "upgrade") &&
+ ascii.EqualFold(r.Header.Get("Upgrade"), "websocket")
+}
diff --git a/contrib/go/_std_1.20/src/net/http/response.go b/contrib/go/_std_1.21/src/net/http/response.go
index 755c696557..755c696557 100644
--- a/contrib/go/_std_1.20/src/net/http/response.go
+++ b/contrib/go/_std_1.21/src/net/http/response.go
diff --git a/contrib/go/_std_1.21/src/net/http/responsecontroller.go b/contrib/go/_std_1.21/src/net/http/responsecontroller.go
new file mode 100644
index 0000000000..92276ffaf2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/responsecontroller.go
@@ -0,0 +1,147 @@
+// Copyright 2022 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 http
+
+import (
+ "bufio"
+ "fmt"
+ "net"
+ "time"
+)
+
+// A ResponseController is used by an HTTP handler to control the response.
+//
+// A ResponseController may not be used after the Handler.ServeHTTP method has returned.
+type ResponseController struct {
+ rw ResponseWriter
+}
+
+// NewResponseController creates a ResponseController for a request.
+//
+// The ResponseWriter should be the original value passed to the Handler.ServeHTTP method,
+// or have an Unwrap method returning the original ResponseWriter.
+//
+// If the ResponseWriter implements any of the following methods, the ResponseController
+// will call them as appropriate:
+//
+// Flush()
+// FlushError() error // alternative Flush returning an error
+// Hijack() (net.Conn, *bufio.ReadWriter, error)
+// SetReadDeadline(deadline time.Time) error
+// SetWriteDeadline(deadline time.Time) error
+// EnableFullDuplex() error
+//
+// If the ResponseWriter does not support a method, ResponseController returns
+// an error matching ErrNotSupported.
+func NewResponseController(rw ResponseWriter) *ResponseController {
+ return &ResponseController{rw}
+}
+
+type rwUnwrapper interface {
+ Unwrap() ResponseWriter
+}
+
+// Flush flushes buffered data to the client.
+func (c *ResponseController) Flush() error {
+ rw := c.rw
+ for {
+ switch t := rw.(type) {
+ case interface{ FlushError() error }:
+ return t.FlushError()
+ case Flusher:
+ t.Flush()
+ return nil
+ case rwUnwrapper:
+ rw = t.Unwrap()
+ default:
+ return errNotSupported()
+ }
+ }
+}
+
+// Hijack lets the caller take over the connection.
+// See the Hijacker interface for details.
+func (c *ResponseController) Hijack() (net.Conn, *bufio.ReadWriter, error) {
+ rw := c.rw
+ for {
+ switch t := rw.(type) {
+ case Hijacker:
+ return t.Hijack()
+ case rwUnwrapper:
+ rw = t.Unwrap()
+ default:
+ return nil, nil, errNotSupported()
+ }
+ }
+}
+
+// SetReadDeadline sets the deadline for reading the entire request, including the body.
+// Reads from the request body after the deadline has been exceeded will return an error.
+// A zero value means no deadline.
+//
+// Setting the read deadline after it has been exceeded will not extend it.
+func (c *ResponseController) SetReadDeadline(deadline time.Time) error {
+ rw := c.rw
+ for {
+ switch t := rw.(type) {
+ case interface{ SetReadDeadline(time.Time) error }:
+ return t.SetReadDeadline(deadline)
+ case rwUnwrapper:
+ rw = t.Unwrap()
+ default:
+ return errNotSupported()
+ }
+ }
+}
+
+// SetWriteDeadline sets the deadline for writing the response.
+// Writes to the response body after the deadline has been exceeded will not block,
+// but may succeed if the data has been buffered.
+// A zero value means no deadline.
+//
+// Setting the write deadline after it has been exceeded will not extend it.
+func (c *ResponseController) SetWriteDeadline(deadline time.Time) error {
+ rw := c.rw
+ for {
+ switch t := rw.(type) {
+ case interface{ SetWriteDeadline(time.Time) error }:
+ return t.SetWriteDeadline(deadline)
+ case rwUnwrapper:
+ rw = t.Unwrap()
+ default:
+ return errNotSupported()
+ }
+ }
+}
+
+// EnableFullDuplex indicates that the request handler will interleave reads from Request.Body
+// with writes to the ResponseWriter.
+//
+// For HTTP/1 requests, the Go HTTP server by default consumes any unread portion of
+// the request body before beginning to write the response, preventing handlers from
+// concurrently reading from the request and writing the response.
+// Calling EnableFullDuplex disables this behavior and permits handlers to continue to read
+// from the request while concurrently writing the response.
+//
+// For HTTP/2 requests, the Go HTTP server always permits concurrent reads and responses.
+func (c *ResponseController) EnableFullDuplex() error {
+ rw := c.rw
+ for {
+ switch t := rw.(type) {
+ case interface{ EnableFullDuplex() error }:
+ return t.EnableFullDuplex()
+ case rwUnwrapper:
+ rw = t.Unwrap()
+ default:
+ return errNotSupported()
+ }
+ }
+}
+
+// errNotSupported returns an error that Is ErrNotSupported,
+// but is not == to it.
+func errNotSupported() error {
+ return fmt.Errorf("%w", ErrNotSupported)
+}
diff --git a/contrib/go/_std_1.21/src/net/http/roundtrip.go b/contrib/go/_std_1.21/src/net/http/roundtrip.go
new file mode 100644
index 0000000000..49ea1a71ed
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/roundtrip.go
@@ -0,0 +1,18 @@
+// Copyright 2018 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.
+
+//go:build !js
+
+package http
+
+// RoundTrip implements the RoundTripper interface.
+//
+// For higher-level HTTP client support (such as handling of cookies
+// and redirects), see Get, Post, and the Client type.
+//
+// Like the RoundTripper interface, the error types returned
+// by RoundTrip are unspecified.
+func (t *Transport) RoundTrip(req *Request) (*Response, error) {
+ return t.roundTrip(req)
+}
diff --git a/contrib/go/_std_1.21/src/net/http/server.go b/contrib/go/_std_1.21/src/net/http/server.go
new file mode 100644
index 0000000000..8f63a90299
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/server.go
@@ -0,0 +1,3645 @@
+// Copyright 2009 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.
+
+// HTTP server. See RFC 7230 through 7235.
+
+package http
+
+import (
+ "bufio"
+ "bytes"
+ "context"
+ "crypto/tls"
+ "errors"
+ "fmt"
+ "internal/godebug"
+ "io"
+ "log"
+ "math/rand"
+ "net"
+ "net/textproto"
+ "net/url"
+ urlpkg "net/url"
+ "path"
+ "runtime"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "golang.org/x/net/http/httpguts"
+)
+
+// Errors used by the HTTP server.
+var (
+ // ErrBodyNotAllowed is returned by ResponseWriter.Write calls
+ // when the HTTP method or response code does not permit a
+ // body.
+ ErrBodyNotAllowed = errors.New("http: request method or response status code does not allow body")
+
+ // ErrHijacked is returned by ResponseWriter.Write calls when
+ // the underlying connection has been hijacked using the
+ // Hijacker interface. A zero-byte write on a hijacked
+ // connection will return ErrHijacked without any other side
+ // effects.
+ ErrHijacked = errors.New("http: connection has been hijacked")
+
+ // ErrContentLength is returned by ResponseWriter.Write calls
+ // when a Handler set a Content-Length response header with a
+ // declared size and then attempted to write more bytes than
+ // declared.
+ ErrContentLength = errors.New("http: wrote more than the declared Content-Length")
+
+ // Deprecated: ErrWriteAfterFlush is no longer returned by
+ // anything in the net/http package. Callers should not
+ // compare errors against this variable.
+ ErrWriteAfterFlush = errors.New("unused")
+)
+
+// A Handler responds to an HTTP request.
+//
+// ServeHTTP should write reply headers and data to the ResponseWriter
+// and then return. Returning signals that the request is finished; it
+// is not valid to use the ResponseWriter or read from the
+// Request.Body after or concurrently with the completion of the
+// ServeHTTP call.
+//
+// Depending on the HTTP client software, HTTP protocol version, and
+// any intermediaries between the client and the Go server, it may not
+// be possible to read from the Request.Body after writing to the
+// ResponseWriter. Cautious handlers should read the Request.Body
+// first, and then reply.
+//
+// Except for reading the body, handlers should not modify the
+// provided Request.
+//
+// If ServeHTTP panics, the server (the caller of ServeHTTP) assumes
+// that the effect of the panic was isolated to the active request.
+// It recovers the panic, logs a stack trace to the server error log,
+// and either closes the network connection or sends an HTTP/2
+// RST_STREAM, depending on the HTTP protocol. To abort a handler so
+// the client sees an interrupted response but the server doesn't log
+// an error, panic with the value ErrAbortHandler.
+type Handler interface {
+ ServeHTTP(ResponseWriter, *Request)
+}
+
+// A ResponseWriter interface is used by an HTTP handler to
+// construct an HTTP response.
+//
+// A ResponseWriter may not be used after the Handler.ServeHTTP method
+// has returned.
+type ResponseWriter interface {
+ // Header returns the header map that will be sent by
+ // WriteHeader. The Header map also is the mechanism with which
+ // Handlers can set HTTP trailers.
+ //
+ // Changing the header map after a call to WriteHeader (or
+ // Write) has no effect unless the HTTP status code was of the
+ // 1xx class or the modified headers are trailers.
+ //
+ // There are two ways to set Trailers. The preferred way is to
+ // predeclare in the headers which trailers you will later
+ // send by setting the "Trailer" header to the names of the
+ // trailer keys which will come later. In this case, those
+ // keys of the Header map are treated as if they were
+ // trailers. See the example. The second way, for trailer
+ // keys not known to the Handler until after the first Write,
+ // is to prefix the Header map keys with the TrailerPrefix
+ // constant value. See TrailerPrefix.
+ //
+ // To suppress automatic response headers (such as "Date"), set
+ // their value to nil.
+ Header() Header
+
+ // Write writes the data to the connection as part of an HTTP reply.
+ //
+ // If WriteHeader has not yet been called, Write calls
+ // WriteHeader(http.StatusOK) before writing the data. If the Header
+ // does not contain a Content-Type line, Write adds a Content-Type set
+ // to the result of passing the initial 512 bytes of written data to
+ // DetectContentType. Additionally, if the total size of all written
+ // data is under a few KB and there are no Flush calls, the
+ // Content-Length header is added automatically.
+ //
+ // Depending on the HTTP protocol version and the client, calling
+ // Write or WriteHeader may prevent future reads on the
+ // Request.Body. For HTTP/1.x requests, handlers should read any
+ // needed request body data before writing the response. Once the
+ // headers have been flushed (due to either an explicit Flusher.Flush
+ // call or writing enough data to trigger a flush), the request body
+ // may be unavailable. For HTTP/2 requests, the Go HTTP server permits
+ // handlers to continue to read the request body while concurrently
+ // writing the response. However, such behavior may not be supported
+ // by all HTTP/2 clients. Handlers should read before writing if
+ // possible to maximize compatibility.
+ Write([]byte) (int, error)
+
+ // WriteHeader sends an HTTP response header with the provided
+ // status code.
+ //
+ // If WriteHeader is not called explicitly, the first call to Write
+ // will trigger an implicit WriteHeader(http.StatusOK).
+ // Thus explicit calls to WriteHeader are mainly used to
+ // send error codes or 1xx informational responses.
+ //
+ // The provided code must be a valid HTTP 1xx-5xx status code.
+ // Any number of 1xx headers may be written, followed by at most
+ // one 2xx-5xx header. 1xx headers are sent immediately, but 2xx-5xx
+ // headers may be buffered. Use the Flusher interface to send
+ // buffered data. The header map is cleared when 2xx-5xx headers are
+ // sent, but not with 1xx headers.
+ //
+ // The server will automatically send a 100 (Continue) header
+ // on the first read from the request body if the request has
+ // an "Expect: 100-continue" header.
+ WriteHeader(statusCode int)
+}
+
+// The Flusher interface is implemented by ResponseWriters that allow
+// an HTTP handler to flush buffered data to the client.
+//
+// The default HTTP/1.x and HTTP/2 ResponseWriter implementations
+// support Flusher, but ResponseWriter wrappers may not. Handlers
+// should always test for this ability at runtime.
+//
+// Note that even for ResponseWriters that support Flush,
+// if the client is connected through an HTTP proxy,
+// the buffered data may not reach the client until the response
+// completes.
+type Flusher interface {
+ // Flush sends any buffered data to the client.
+ Flush()
+}
+
+// The Hijacker interface is implemented by ResponseWriters that allow
+// an HTTP handler to take over the connection.
+//
+// The default ResponseWriter for HTTP/1.x connections supports
+// Hijacker, but HTTP/2 connections intentionally do not.
+// ResponseWriter wrappers may also not support Hijacker. Handlers
+// should always test for this ability at runtime.
+type Hijacker interface {
+ // Hijack lets the caller take over the connection.
+ // After a call to Hijack the HTTP server library
+ // will not do anything else with the connection.
+ //
+ // It becomes the caller's responsibility to manage
+ // and close the connection.
+ //
+ // The returned net.Conn may have read or write deadlines
+ // already set, depending on the configuration of the
+ // Server. It is the caller's responsibility to set
+ // or clear those deadlines as needed.
+ //
+ // The returned bufio.Reader may contain unprocessed buffered
+ // data from the client.
+ //
+ // After a call to Hijack, the original Request.Body must not
+ // be used. The original Request's Context remains valid and
+ // is not canceled until the Request's ServeHTTP method
+ // returns.
+ Hijack() (net.Conn, *bufio.ReadWriter, error)
+}
+
+// The CloseNotifier interface is implemented by ResponseWriters which
+// allow detecting when the underlying connection has gone away.
+//
+// This mechanism can be used to cancel long operations on the server
+// if the client has disconnected before the response is ready.
+//
+// Deprecated: the CloseNotifier interface predates Go's context package.
+// New code should use Request.Context instead.
+type CloseNotifier interface {
+ // CloseNotify returns a channel that receives at most a
+ // single value (true) when the client connection has gone
+ // away.
+ //
+ // CloseNotify may wait to notify until Request.Body has been
+ // fully read.
+ //
+ // After the Handler has returned, there is no guarantee
+ // that the channel receives a value.
+ //
+ // If the protocol is HTTP/1.1 and CloseNotify is called while
+ // processing an idempotent request (such a GET) while
+ // HTTP/1.1 pipelining is in use, the arrival of a subsequent
+ // pipelined request may cause a value to be sent on the
+ // returned channel. In practice HTTP/1.1 pipelining is not
+ // enabled in browsers and not seen often in the wild. If this
+ // is a problem, use HTTP/2 or only use CloseNotify on methods
+ // such as POST.
+ CloseNotify() <-chan bool
+}
+
+var (
+ // ServerContextKey is a context key. It can be used in HTTP
+ // handlers with Context.Value to access the server that
+ // started the handler. The associated value will be of
+ // type *Server.
+ ServerContextKey = &contextKey{"http-server"}
+
+ // LocalAddrContextKey is a context key. It can be used in
+ // HTTP handlers with Context.Value to access the local
+ // address the connection arrived on.
+ // The associated value will be of type net.Addr.
+ LocalAddrContextKey = &contextKey{"local-addr"}
+)
+
+// A conn represents the server side of an HTTP connection.
+type conn struct {
+ // server is the server on which the connection arrived.
+ // Immutable; never nil.
+ server *Server
+
+ // cancelCtx cancels the connection-level context.
+ cancelCtx context.CancelFunc
+
+ // rwc is the underlying network connection.
+ // This is never wrapped by other types and is the value given out
+ // to CloseNotifier callers. It is usually of type *net.TCPConn or
+ // *tls.Conn.
+ rwc net.Conn
+
+ // remoteAddr is rwc.RemoteAddr().String(). It is not populated synchronously
+ // inside the Listener's Accept goroutine, as some implementations block.
+ // It is populated immediately inside the (*conn).serve goroutine.
+ // This is the value of a Handler's (*Request).RemoteAddr.
+ remoteAddr string
+
+ // tlsState is the TLS connection state when using TLS.
+ // nil means not TLS.
+ tlsState *tls.ConnectionState
+
+ // werr is set to the first write error to rwc.
+ // It is set via checkConnErrorWriter{w}, where bufw writes.
+ werr error
+
+ // r is bufr's read source. It's a wrapper around rwc that provides
+ // io.LimitedReader-style limiting (while reading request headers)
+ // and functionality to support CloseNotifier. See *connReader docs.
+ r *connReader
+
+ // bufr reads from r.
+ bufr *bufio.Reader
+
+ // bufw writes to checkConnErrorWriter{c}, which populates werr on error.
+ bufw *bufio.Writer
+
+ // lastMethod is the method of the most recent request
+ // on this connection, if any.
+ lastMethod string
+
+ curReq atomic.Pointer[response] // (which has a Request in it)
+
+ curState atomic.Uint64 // packed (unixtime<<8|uint8(ConnState))
+
+ // mu guards hijackedv
+ mu sync.Mutex
+
+ // hijackedv is whether this connection has been hijacked
+ // by a Handler with the Hijacker interface.
+ // It is guarded by mu.
+ hijackedv bool
+}
+
+func (c *conn) hijacked() bool {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ return c.hijackedv
+}
+
+// c.mu must be held.
+func (c *conn) hijackLocked() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
+ if c.hijackedv {
+ return nil, nil, ErrHijacked
+ }
+ c.r.abortPendingRead()
+
+ c.hijackedv = true
+ rwc = c.rwc
+ rwc.SetDeadline(time.Time{})
+
+ buf = bufio.NewReadWriter(c.bufr, bufio.NewWriter(rwc))
+ if c.r.hasByte {
+ if _, err := c.bufr.Peek(c.bufr.Buffered() + 1); err != nil {
+ return nil, nil, fmt.Errorf("unexpected Peek failure reading buffered byte: %v", err)
+ }
+ }
+ c.setState(rwc, StateHijacked, runHooks)
+ return
+}
+
+// This should be >= 512 bytes for DetectContentType,
+// but otherwise it's somewhat arbitrary.
+const bufferBeforeChunkingSize = 2048
+
+// chunkWriter writes to a response's conn buffer, and is the writer
+// wrapped by the response.w buffered writer.
+//
+// chunkWriter also is responsible for finalizing the Header, including
+// conditionally setting the Content-Type and setting a Content-Length
+// in cases where the handler's final output is smaller than the buffer
+// size. It also conditionally adds chunk headers, when in chunking mode.
+//
+// See the comment above (*response).Write for the entire write flow.
+type chunkWriter struct {
+ res *response
+
+ // header is either nil or a deep clone of res.handlerHeader
+ // at the time of res.writeHeader, if res.writeHeader is
+ // called and extra buffering is being done to calculate
+ // Content-Type and/or Content-Length.
+ header Header
+
+ // wroteHeader tells whether the header's been written to "the
+ // wire" (or rather: w.conn.buf). this is unlike
+ // (*response).wroteHeader, which tells only whether it was
+ // logically written.
+ wroteHeader bool
+
+ // set by the writeHeader method:
+ chunking bool // using chunked transfer encoding for reply body
+}
+
+var (
+ crlf = []byte("\r\n")
+ colonSpace = []byte(": ")
+)
+
+func (cw *chunkWriter) Write(p []byte) (n int, err error) {
+ if !cw.wroteHeader {
+ cw.writeHeader(p)
+ }
+ if cw.res.req.Method == "HEAD" {
+ // Eat writes.
+ return len(p), nil
+ }
+ if cw.chunking {
+ _, err = fmt.Fprintf(cw.res.conn.bufw, "%x\r\n", len(p))
+ if err != nil {
+ cw.res.conn.rwc.Close()
+ return
+ }
+ }
+ n, err = cw.res.conn.bufw.Write(p)
+ if cw.chunking && err == nil {
+ _, err = cw.res.conn.bufw.Write(crlf)
+ }
+ if err != nil {
+ cw.res.conn.rwc.Close()
+ }
+ return
+}
+
+func (cw *chunkWriter) flush() error {
+ if !cw.wroteHeader {
+ cw.writeHeader(nil)
+ }
+ return cw.res.conn.bufw.Flush()
+}
+
+func (cw *chunkWriter) close() {
+ if !cw.wroteHeader {
+ cw.writeHeader(nil)
+ }
+ if cw.chunking {
+ bw := cw.res.conn.bufw // conn's bufio writer
+ // zero chunk to mark EOF
+ bw.WriteString("0\r\n")
+ if trailers := cw.res.finalTrailers(); trailers != nil {
+ trailers.Write(bw) // the writer handles noting errors
+ }
+ // final blank line after the trailers (whether
+ // present or not)
+ bw.WriteString("\r\n")
+ }
+}
+
+// A response represents the server side of an HTTP response.
+type response struct {
+ conn *conn
+ req *Request // request for this response
+ reqBody io.ReadCloser
+ cancelCtx context.CancelFunc // when ServeHTTP exits
+ wroteHeader bool // a non-1xx header has been (logically) written
+ wroteContinue bool // 100 Continue response was written
+ wants10KeepAlive bool // HTTP/1.0 w/ Connection "keep-alive"
+ wantsClose bool // HTTP request has Connection "close"
+
+ // canWriteContinue is an atomic boolean that says whether or
+ // not a 100 Continue header can be written to the
+ // connection.
+ // writeContinueMu must be held while writing the header.
+ // These two fields together synchronize the body reader (the
+ // expectContinueReader, which wants to write 100 Continue)
+ // against the main writer.
+ canWriteContinue atomic.Bool
+ writeContinueMu sync.Mutex
+
+ w *bufio.Writer // buffers output in chunks to chunkWriter
+ cw chunkWriter
+
+ // handlerHeader is the Header that Handlers get access to,
+ // which may be retained and mutated even after WriteHeader.
+ // handlerHeader is copied into cw.header at WriteHeader
+ // time, and privately mutated thereafter.
+ handlerHeader Header
+ calledHeader bool // handler accessed handlerHeader via Header
+
+ written int64 // number of bytes written in body
+ contentLength int64 // explicitly-declared Content-Length; or -1
+ status int // status code passed to WriteHeader
+
+ // close connection after this reply. set on request and
+ // updated after response from handler if there's a
+ // "Connection: keep-alive" response header and a
+ // Content-Length.
+ closeAfterReply bool
+
+ // When fullDuplex is false (the default), we consume any remaining
+ // request body before starting to write a response.
+ fullDuplex bool
+
+ // requestBodyLimitHit is set by requestTooLarge when
+ // maxBytesReader hits its max size. It is checked in
+ // WriteHeader, to make sure we don't consume the
+ // remaining request body to try to advance to the next HTTP
+ // request. Instead, when this is set, we stop reading
+ // subsequent requests on this connection and stop reading
+ // input from it.
+ requestBodyLimitHit bool
+
+ // trailers are the headers to be sent after the handler
+ // finishes writing the body. This field is initialized from
+ // the Trailer response header when the response header is
+ // written.
+ trailers []string
+
+ handlerDone atomic.Bool // set true when the handler exits
+
+ // Buffers for Date, Content-Length, and status code
+ dateBuf [len(TimeFormat)]byte
+ clenBuf [10]byte
+ statusBuf [3]byte
+
+ // closeNotifyCh is the channel returned by CloseNotify.
+ // TODO(bradfitz): this is currently (for Go 1.8) always
+ // non-nil. Make this lazily-created again as it used to be?
+ closeNotifyCh chan bool
+ didCloseNotify atomic.Bool // atomic (only false->true winner should send)
+}
+
+func (c *response) SetReadDeadline(deadline time.Time) error {
+ return c.conn.rwc.SetReadDeadline(deadline)
+}
+
+func (c *response) SetWriteDeadline(deadline time.Time) error {
+ return c.conn.rwc.SetWriteDeadline(deadline)
+}
+
+func (c *response) EnableFullDuplex() error {
+ c.fullDuplex = true
+ return nil
+}
+
+// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys
+// that, if present, signals that the map entry is actually for
+// the response trailers, and not the response headers. The prefix
+// is stripped after the ServeHTTP call finishes and the values are
+// sent in the trailers.
+//
+// This mechanism is intended only for trailers that are not known
+// prior to the headers being written. If the set of trailers is fixed
+// or known before the header is written, the normal Go trailers mechanism
+// is preferred:
+//
+// https://pkg.go.dev/net/http#ResponseWriter
+// https://pkg.go.dev/net/http#example-ResponseWriter-Trailers
+const TrailerPrefix = "Trailer:"
+
+// finalTrailers is called after the Handler exits and returns a non-nil
+// value if the Handler set any trailers.
+func (w *response) finalTrailers() Header {
+ var t Header
+ for k, vv := range w.handlerHeader {
+ if kk, found := strings.CutPrefix(k, TrailerPrefix); found {
+ if t == nil {
+ t = make(Header)
+ }
+ t[kk] = vv
+ }
+ }
+ for _, k := range w.trailers {
+ if t == nil {
+ t = make(Header)
+ }
+ for _, v := range w.handlerHeader[k] {
+ t.Add(k, v)
+ }
+ }
+ return t
+}
+
+// declareTrailer is called for each Trailer header when the
+// response header is written. It notes that a header will need to be
+// written in the trailers at the end of the response.
+func (w *response) declareTrailer(k string) {
+ k = CanonicalHeaderKey(k)
+ if !httpguts.ValidTrailerHeader(k) {
+ // Forbidden by RFC 7230, section 4.1.2
+ return
+ }
+ w.trailers = append(w.trailers, k)
+}
+
+// requestTooLarge is called by maxBytesReader when too much input has
+// been read from the client.
+func (w *response) requestTooLarge() {
+ w.closeAfterReply = true
+ w.requestBodyLimitHit = true
+ if !w.wroteHeader {
+ w.Header().Set("Connection", "close")
+ }
+}
+
+// writerOnly hides an io.Writer value's optional ReadFrom method
+// from io.Copy.
+type writerOnly struct {
+ io.Writer
+}
+
+// ReadFrom is here to optimize copying from an *os.File regular file
+// to a *net.TCPConn with sendfile, or from a supported src type such
+// as a *net.TCPConn on Linux with splice.
+func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
+ bufp := copyBufPool.Get().(*[]byte)
+ buf := *bufp
+ defer copyBufPool.Put(bufp)
+
+ // Our underlying w.conn.rwc is usually a *TCPConn (with its
+ // own ReadFrom method). If not, just fall back to the normal
+ // copy method.
+ rf, ok := w.conn.rwc.(io.ReaderFrom)
+ if !ok {
+ return io.CopyBuffer(writerOnly{w}, src, buf)
+ }
+
+ // Copy the first sniffLen bytes before switching to ReadFrom.
+ // This ensures we don't start writing the response before the
+ // source is available (see golang.org/issue/5660) and provides
+ // enough bytes to perform Content-Type sniffing when required.
+ if !w.cw.wroteHeader {
+ n0, err := io.CopyBuffer(writerOnly{w}, io.LimitReader(src, sniffLen), buf)
+ n += n0
+ if err != nil || n0 < sniffLen {
+ return n, err
+ }
+ }
+
+ w.w.Flush() // get rid of any previous writes
+ w.cw.flush() // make sure Header is written; flush data to rwc
+
+ // Now that cw has been flushed, its chunking field is guaranteed initialized.
+ if !w.cw.chunking && w.bodyAllowed() {
+ n0, err := rf.ReadFrom(src)
+ n += n0
+ w.written += n0
+ return n, err
+ }
+
+ n0, err := io.CopyBuffer(writerOnly{w}, src, buf)
+ n += n0
+ return n, err
+}
+
+// debugServerConnections controls whether all server connections are wrapped
+// with a verbose logging wrapper.
+const debugServerConnections = false
+
+// Create new connection from rwc.
+func (srv *Server) newConn(rwc net.Conn) *conn {
+ c := &conn{
+ server: srv,
+ rwc: rwc,
+ }
+ if debugServerConnections {
+ c.rwc = newLoggingConn("server", c.rwc)
+ }
+ return c
+}
+
+type readResult struct {
+ _ incomparable
+ n int
+ err error
+ b byte // byte read, if n == 1
+}
+
+// connReader is the io.Reader wrapper used by *conn. It combines a
+// selectively-activated io.LimitedReader (to bound request header
+// read sizes) with support for selectively keeping an io.Reader.Read
+// call blocked in a background goroutine to wait for activity and
+// trigger a CloseNotifier channel.
+type connReader struct {
+ conn *conn
+
+ mu sync.Mutex // guards following
+ hasByte bool
+ byteBuf [1]byte
+ cond *sync.Cond
+ inRead bool
+ aborted bool // set true before conn.rwc deadline is set to past
+ remain int64 // bytes remaining
+}
+
+func (cr *connReader) lock() {
+ cr.mu.Lock()
+ if cr.cond == nil {
+ cr.cond = sync.NewCond(&cr.mu)
+ }
+}
+
+func (cr *connReader) unlock() { cr.mu.Unlock() }
+
+func (cr *connReader) startBackgroundRead() {
+ cr.lock()
+ defer cr.unlock()
+ if cr.inRead {
+ panic("invalid concurrent Body.Read call")
+ }
+ if cr.hasByte {
+ return
+ }
+ cr.inRead = true
+ cr.conn.rwc.SetReadDeadline(time.Time{})
+ go cr.backgroundRead()
+}
+
+func (cr *connReader) backgroundRead() {
+ n, err := cr.conn.rwc.Read(cr.byteBuf[:])
+ cr.lock()
+ if n == 1 {
+ cr.hasByte = true
+ // We were past the end of the previous request's body already
+ // (since we wouldn't be in a background read otherwise), so
+ // this is a pipelined HTTP request. Prior to Go 1.11 we used to
+ // send on the CloseNotify channel and cancel the context here,
+ // but the behavior was documented as only "may", and we only
+ // did that because that's how CloseNotify accidentally behaved
+ // in very early Go releases prior to context support. Once we
+ // added context support, people used a Handler's
+ // Request.Context() and passed it along. Having that context
+ // cancel on pipelined HTTP requests caused problems.
+ // Fortunately, almost nothing uses HTTP/1.x pipelining.
+ // Unfortunately, apt-get does, or sometimes does.
+ // New Go 1.11 behavior: don't fire CloseNotify or cancel
+ // contexts on pipelined requests. Shouldn't affect people, but
+ // fixes cases like Issue 23921. This does mean that a client
+ // closing their TCP connection after sending a pipelined
+ // request won't cancel the context, but we'll catch that on any
+ // write failure (in checkConnErrorWriter.Write).
+ // If the server never writes, yes, there are still contrived
+ // server & client behaviors where this fails to ever cancel the
+ // context, but that's kinda why HTTP/1.x pipelining died
+ // anyway.
+ }
+ if ne, ok := err.(net.Error); ok && cr.aborted && ne.Timeout() {
+ // Ignore this error. It's the expected error from
+ // another goroutine calling abortPendingRead.
+ } else if err != nil {
+ cr.handleReadError(err)
+ }
+ cr.aborted = false
+ cr.inRead = false
+ cr.unlock()
+ cr.cond.Broadcast()
+}
+
+func (cr *connReader) abortPendingRead() {
+ cr.lock()
+ defer cr.unlock()
+ if !cr.inRead {
+ return
+ }
+ cr.aborted = true
+ cr.conn.rwc.SetReadDeadline(aLongTimeAgo)
+ for cr.inRead {
+ cr.cond.Wait()
+ }
+ cr.conn.rwc.SetReadDeadline(time.Time{})
+}
+
+func (cr *connReader) setReadLimit(remain int64) { cr.remain = remain }
+func (cr *connReader) setInfiniteReadLimit() { cr.remain = maxInt64 }
+func (cr *connReader) hitReadLimit() bool { return cr.remain <= 0 }
+
+// handleReadError is called whenever a Read from the client returns a
+// non-nil error.
+//
+// The provided non-nil err is almost always io.EOF or a "use of
+// closed network connection". In any case, the error is not
+// particularly interesting, except perhaps for debugging during
+// development. Any error means the connection is dead and we should
+// down its context.
+//
+// It may be called from multiple goroutines.
+func (cr *connReader) handleReadError(_ error) {
+ cr.conn.cancelCtx()
+ cr.closeNotify()
+}
+
+// may be called from multiple goroutines.
+func (cr *connReader) closeNotify() {
+ res := cr.conn.curReq.Load()
+ if res != nil && !res.didCloseNotify.Swap(true) {
+ res.closeNotifyCh <- true
+ }
+}
+
+func (cr *connReader) Read(p []byte) (n int, err error) {
+ cr.lock()
+ if cr.inRead {
+ cr.unlock()
+ if cr.conn.hijacked() {
+ panic("invalid Body.Read call. After hijacked, the original Request must not be used")
+ }
+ panic("invalid concurrent Body.Read call")
+ }
+ if cr.hitReadLimit() {
+ cr.unlock()
+ return 0, io.EOF
+ }
+ if len(p) == 0 {
+ cr.unlock()
+ return 0, nil
+ }
+ if int64(len(p)) > cr.remain {
+ p = p[:cr.remain]
+ }
+ if cr.hasByte {
+ p[0] = cr.byteBuf[0]
+ cr.hasByte = false
+ cr.unlock()
+ return 1, nil
+ }
+ cr.inRead = true
+ cr.unlock()
+ n, err = cr.conn.rwc.Read(p)
+
+ cr.lock()
+ cr.inRead = false
+ if err != nil {
+ cr.handleReadError(err)
+ }
+ cr.remain -= int64(n)
+ cr.unlock()
+
+ cr.cond.Broadcast()
+ return n, err
+}
+
+var (
+ bufioReaderPool sync.Pool
+ bufioWriter2kPool sync.Pool
+ bufioWriter4kPool sync.Pool
+)
+
+var copyBufPool = sync.Pool{
+ New: func() any {
+ b := make([]byte, 32*1024)
+ return &b
+ },
+}
+
+func bufioWriterPool(size int) *sync.Pool {
+ switch size {
+ case 2 << 10:
+ return &bufioWriter2kPool
+ case 4 << 10:
+ return &bufioWriter4kPool
+ }
+ return nil
+}
+
+func newBufioReader(r io.Reader) *bufio.Reader {
+ if v := bufioReaderPool.Get(); v != nil {
+ br := v.(*bufio.Reader)
+ br.Reset(r)
+ return br
+ }
+ // Note: if this reader size is ever changed, update
+ // TestHandlerBodyClose's assumptions.
+ return bufio.NewReader(r)
+}
+
+func putBufioReader(br *bufio.Reader) {
+ br.Reset(nil)
+ bufioReaderPool.Put(br)
+}
+
+func newBufioWriterSize(w io.Writer, size int) *bufio.Writer {
+ pool := bufioWriterPool(size)
+ if pool != nil {
+ if v := pool.Get(); v != nil {
+ bw := v.(*bufio.Writer)
+ bw.Reset(w)
+ return bw
+ }
+ }
+ return bufio.NewWriterSize(w, size)
+}
+
+func putBufioWriter(bw *bufio.Writer) {
+ bw.Reset(nil)
+ if pool := bufioWriterPool(bw.Available()); pool != nil {
+ pool.Put(bw)
+ }
+}
+
+// DefaultMaxHeaderBytes is the maximum permitted size of the headers
+// in an HTTP request.
+// This can be overridden by setting Server.MaxHeaderBytes.
+const DefaultMaxHeaderBytes = 1 << 20 // 1 MB
+
+func (srv *Server) maxHeaderBytes() int {
+ if srv.MaxHeaderBytes > 0 {
+ return srv.MaxHeaderBytes
+ }
+ return DefaultMaxHeaderBytes
+}
+
+func (srv *Server) initialReadLimitSize() int64 {
+ return int64(srv.maxHeaderBytes()) + 4096 // bufio slop
+}
+
+// tlsHandshakeTimeout returns the time limit permitted for the TLS
+// handshake, or zero for unlimited.
+//
+// It returns the minimum of any positive ReadHeaderTimeout,
+// ReadTimeout, or WriteTimeout.
+func (srv *Server) tlsHandshakeTimeout() time.Duration {
+ var ret time.Duration
+ for _, v := range [...]time.Duration{
+ srv.ReadHeaderTimeout,
+ srv.ReadTimeout,
+ srv.WriteTimeout,
+ } {
+ if v <= 0 {
+ continue
+ }
+ if ret == 0 || v < ret {
+ ret = v
+ }
+ }
+ return ret
+}
+
+// wrapper around io.ReadCloser which on first read, sends an
+// HTTP/1.1 100 Continue header
+type expectContinueReader struct {
+ resp *response
+ readCloser io.ReadCloser
+ closed atomic.Bool
+ sawEOF atomic.Bool
+}
+
+func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
+ if ecr.closed.Load() {
+ return 0, ErrBodyReadAfterClose
+ }
+ w := ecr.resp
+ if !w.wroteContinue && w.canWriteContinue.Load() && !w.conn.hijacked() {
+ w.wroteContinue = true
+ w.writeContinueMu.Lock()
+ if w.canWriteContinue.Load() {
+ w.conn.bufw.WriteString("HTTP/1.1 100 Continue\r\n\r\n")
+ w.conn.bufw.Flush()
+ w.canWriteContinue.Store(false)
+ }
+ w.writeContinueMu.Unlock()
+ }
+ n, err = ecr.readCloser.Read(p)
+ if err == io.EOF {
+ ecr.sawEOF.Store(true)
+ }
+ return
+}
+
+func (ecr *expectContinueReader) Close() error {
+ ecr.closed.Store(true)
+ return ecr.readCloser.Close()
+}
+
+// TimeFormat is the time format to use when generating times in HTTP
+// headers. It is like time.RFC1123 but hard-codes GMT as the time
+// zone. The time being formatted must be in UTC for Format to
+// generate the correct format.
+//
+// For parsing this time format, see ParseTime.
+const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
+
+// appendTime is a non-allocating version of []byte(t.UTC().Format(TimeFormat))
+func appendTime(b []byte, t time.Time) []byte {
+ const days = "SunMonTueWedThuFriSat"
+ const months = "JanFebMarAprMayJunJulAugSepOctNovDec"
+
+ t = t.UTC()
+ yy, mm, dd := t.Date()
+ hh, mn, ss := t.Clock()
+ day := days[3*t.Weekday():]
+ mon := months[3*(mm-1):]
+
+ return append(b,
+ day[0], day[1], day[2], ',', ' ',
+ byte('0'+dd/10), byte('0'+dd%10), ' ',
+ mon[0], mon[1], mon[2], ' ',
+ byte('0'+yy/1000), byte('0'+(yy/100)%10), byte('0'+(yy/10)%10), byte('0'+yy%10), ' ',
+ byte('0'+hh/10), byte('0'+hh%10), ':',
+ byte('0'+mn/10), byte('0'+mn%10), ':',
+ byte('0'+ss/10), byte('0'+ss%10), ' ',
+ 'G', 'M', 'T')
+}
+
+var errTooLarge = errors.New("http: request too large")
+
+// Read next request from connection.
+func (c *conn) readRequest(ctx context.Context) (w *response, err error) {
+ if c.hijacked() {
+ return nil, ErrHijacked
+ }
+
+ var (
+ wholeReqDeadline time.Time // or zero if none
+ hdrDeadline time.Time // or zero if none
+ )
+ t0 := time.Now()
+ if d := c.server.readHeaderTimeout(); d > 0 {
+ hdrDeadline = t0.Add(d)
+ }
+ if d := c.server.ReadTimeout; d > 0 {
+ wholeReqDeadline = t0.Add(d)
+ }
+ c.rwc.SetReadDeadline(hdrDeadline)
+ if d := c.server.WriteTimeout; d > 0 {
+ defer func() {
+ c.rwc.SetWriteDeadline(time.Now().Add(d))
+ }()
+ }
+
+ c.r.setReadLimit(c.server.initialReadLimitSize())
+ if c.lastMethod == "POST" {
+ // RFC 7230 section 3 tolerance for old buggy clients.
+ peek, _ := c.bufr.Peek(4) // ReadRequest will get err below
+ c.bufr.Discard(numLeadingCRorLF(peek))
+ }
+ req, err := readRequest(c.bufr)
+ if err != nil {
+ if c.r.hitReadLimit() {
+ return nil, errTooLarge
+ }
+ return nil, err
+ }
+
+ if !http1ServerSupportsRequest(req) {
+ return nil, statusError{StatusHTTPVersionNotSupported, "unsupported protocol version"}
+ }
+
+ c.lastMethod = req.Method
+ c.r.setInfiniteReadLimit()
+
+ hosts, haveHost := req.Header["Host"]
+ isH2Upgrade := req.isH2Upgrade()
+ if req.ProtoAtLeast(1, 1) && (!haveHost || len(hosts) == 0) && !isH2Upgrade && req.Method != "CONNECT" {
+ return nil, badRequestError("missing required Host header")
+ }
+ if len(hosts) == 1 && !httpguts.ValidHostHeader(hosts[0]) {
+ return nil, badRequestError("malformed Host header")
+ }
+ for k, vv := range req.Header {
+ if !httpguts.ValidHeaderFieldName(k) {
+ return nil, badRequestError("invalid header name")
+ }
+ for _, v := range vv {
+ if !httpguts.ValidHeaderFieldValue(v) {
+ return nil, badRequestError("invalid header value")
+ }
+ }
+ }
+ delete(req.Header, "Host")
+
+ ctx, cancelCtx := context.WithCancel(ctx)
+ req.ctx = ctx
+ req.RemoteAddr = c.remoteAddr
+ req.TLS = c.tlsState
+ if body, ok := req.Body.(*body); ok {
+ body.doEarlyClose = true
+ }
+
+ // Adjust the read deadline if necessary.
+ if !hdrDeadline.Equal(wholeReqDeadline) {
+ c.rwc.SetReadDeadline(wholeReqDeadline)
+ }
+
+ w = &response{
+ conn: c,
+ cancelCtx: cancelCtx,
+ req: req,
+ reqBody: req.Body,
+ handlerHeader: make(Header),
+ contentLength: -1,
+ closeNotifyCh: make(chan bool, 1),
+
+ // We populate these ahead of time so we're not
+ // reading from req.Header after their Handler starts
+ // and maybe mutates it (Issue 14940)
+ wants10KeepAlive: req.wantsHttp10KeepAlive(),
+ wantsClose: req.wantsClose(),
+ }
+ if isH2Upgrade {
+ w.closeAfterReply = true
+ }
+ w.cw.res = w
+ w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize)
+ return w, nil
+}
+
+// http1ServerSupportsRequest reports whether Go's HTTP/1.x server
+// supports the given request.
+func http1ServerSupportsRequest(req *Request) bool {
+ if req.ProtoMajor == 1 {
+ return true
+ }
+ // Accept "PRI * HTTP/2.0" upgrade requests, so Handlers can
+ // wire up their own HTTP/2 upgrades.
+ if req.ProtoMajor == 2 && req.ProtoMinor == 0 &&
+ req.Method == "PRI" && req.RequestURI == "*" {
+ return true
+ }
+ // Reject HTTP/0.x, and all other HTTP/2+ requests (which
+ // aren't encoded in ASCII anyway).
+ return false
+}
+
+func (w *response) Header() Header {
+ if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {
+ // Accessing the header between logically writing it
+ // and physically writing it means we need to allocate
+ // a clone to snapshot the logically written state.
+ w.cw.header = w.handlerHeader.Clone()
+ }
+ w.calledHeader = true
+ return w.handlerHeader
+}
+
+// maxPostHandlerReadBytes is the max number of Request.Body bytes not
+// consumed by a handler that the server will read from the client
+// in order to keep a connection alive. If there are more bytes than
+// this then the server to be paranoid instead sends a "Connection:
+// close" response.
+//
+// This number is approximately what a typical machine's TCP buffer
+// size is anyway. (if we have the bytes on the machine, we might as
+// well read them)
+const maxPostHandlerReadBytes = 256 << 10
+
+func checkWriteHeaderCode(code int) {
+ // Issue 22880: require valid WriteHeader status codes.
+ // For now we only enforce that it's three digits.
+ // In the future we might block things over 599 (600 and above aren't defined
+ // at https://httpwg.org/specs/rfc7231.html#status.codes).
+ // But for now any three digits.
+ //
+ // We used to send "HTTP/1.1 000 0" on the wire in responses but there's
+ // no equivalent bogus thing we can realistically send in HTTP/2,
+ // so we'll consistently panic instead and help people find their bugs
+ // early. (We can't return an error from WriteHeader even if we wanted to.)
+ if code < 100 || code > 999 {
+ panic(fmt.Sprintf("invalid WriteHeader code %v", code))
+ }
+}
+
+// relevantCaller searches the call stack for the first function outside of net/http.
+// The purpose of this function is to provide more helpful error messages.
+func relevantCaller() runtime.Frame {
+ pc := make([]uintptr, 16)
+ n := runtime.Callers(1, pc)
+ frames := runtime.CallersFrames(pc[:n])
+ var frame runtime.Frame
+ for {
+ frame, more := frames.Next()
+ if !strings.HasPrefix(frame.Function, "net/http.") {
+ return frame
+ }
+ if !more {
+ break
+ }
+ }
+ return frame
+}
+
+func (w *response) WriteHeader(code int) {
+ if w.conn.hijacked() {
+ caller := relevantCaller()
+ w.conn.server.logf("http: response.WriteHeader on hijacked connection from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
+ return
+ }
+ if w.wroteHeader {
+ caller := relevantCaller()
+ w.conn.server.logf("http: superfluous response.WriteHeader call from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
+ return
+ }
+ checkWriteHeaderCode(code)
+
+ // Handle informational headers.
+ //
+ // We shouldn't send any further headers after 101 Switching Protocols,
+ // so it takes the non-informational path.
+ if code >= 100 && code <= 199 && code != StatusSwitchingProtocols {
+ // Prevent a potential race with an automatically-sent 100 Continue triggered by Request.Body.Read()
+ if code == 100 && w.canWriteContinue.Load() {
+ w.writeContinueMu.Lock()
+ w.canWriteContinue.Store(false)
+ w.writeContinueMu.Unlock()
+ }
+
+ writeStatusLine(w.conn.bufw, w.req.ProtoAtLeast(1, 1), code, w.statusBuf[:])
+
+ // Per RFC 8297 we must not clear the current header map
+ w.handlerHeader.WriteSubset(w.conn.bufw, excludedHeadersNoBody)
+ w.conn.bufw.Write(crlf)
+ w.conn.bufw.Flush()
+
+ return
+ }
+
+ w.wroteHeader = true
+ w.status = code
+
+ if w.calledHeader && w.cw.header == nil {
+ w.cw.header = w.handlerHeader.Clone()
+ }
+
+ if cl := w.handlerHeader.get("Content-Length"); cl != "" {
+ v, err := strconv.ParseInt(cl, 10, 64)
+ if err == nil && v >= 0 {
+ w.contentLength = v
+ } else {
+ w.conn.server.logf("http: invalid Content-Length of %q", cl)
+ w.handlerHeader.Del("Content-Length")
+ }
+ }
+}
+
+// extraHeader is the set of headers sometimes added by chunkWriter.writeHeader.
+// This type is used to avoid extra allocations from cloning and/or populating
+// the response Header map and all its 1-element slices.
+type extraHeader struct {
+ contentType string
+ connection string
+ transferEncoding string
+ date []byte // written if not nil
+ contentLength []byte // written if not nil
+}
+
+// Sorted the same as extraHeader.Write's loop.
+var extraHeaderKeys = [][]byte{
+ []byte("Content-Type"),
+ []byte("Connection"),
+ []byte("Transfer-Encoding"),
+}
+
+var (
+ headerContentLength = []byte("Content-Length: ")
+ headerDate = []byte("Date: ")
+)
+
+// Write writes the headers described in h to w.
+//
+// This method has a value receiver, despite the somewhat large size
+// of h, because it prevents an allocation. The escape analysis isn't
+// smart enough to realize this function doesn't mutate h.
+func (h extraHeader) Write(w *bufio.Writer) {
+ if h.date != nil {
+ w.Write(headerDate)
+ w.Write(h.date)
+ w.Write(crlf)
+ }
+ if h.contentLength != nil {
+ w.Write(headerContentLength)
+ w.Write(h.contentLength)
+ w.Write(crlf)
+ }
+ for i, v := range []string{h.contentType, h.connection, h.transferEncoding} {
+ if v != "" {
+ w.Write(extraHeaderKeys[i])
+ w.Write(colonSpace)
+ w.WriteString(v)
+ w.Write(crlf)
+ }
+ }
+}
+
+// writeHeader finalizes the header sent to the client and writes it
+// to cw.res.conn.bufw.
+//
+// p is not written by writeHeader, but is the first chunk of the body
+// that will be written. It is sniffed for a Content-Type if none is
+// set explicitly. It's also used to set the Content-Length, if the
+// total body size was small and the handler has already finished
+// running.
+func (cw *chunkWriter) writeHeader(p []byte) {
+ if cw.wroteHeader {
+ return
+ }
+ cw.wroteHeader = true
+
+ w := cw.res
+ keepAlivesEnabled := w.conn.server.doKeepAlives()
+ isHEAD := w.req.Method == "HEAD"
+
+ // header is written out to w.conn.buf below. Depending on the
+ // state of the handler, we either own the map or not. If we
+ // don't own it, the exclude map is created lazily for
+ // WriteSubset to remove headers. The setHeader struct holds
+ // headers we need to add.
+ header := cw.header
+ owned := header != nil
+ if !owned {
+ header = w.handlerHeader
+ }
+ var excludeHeader map[string]bool
+ delHeader := func(key string) {
+ if owned {
+ header.Del(key)
+ return
+ }
+ if _, ok := header[key]; !ok {
+ return
+ }
+ if excludeHeader == nil {
+ excludeHeader = make(map[string]bool)
+ }
+ excludeHeader[key] = true
+ }
+ var setHeader extraHeader
+
+ // Don't write out the fake "Trailer:foo" keys. See TrailerPrefix.
+ trailers := false
+ for k := range cw.header {
+ if strings.HasPrefix(k, TrailerPrefix) {
+ if excludeHeader == nil {
+ excludeHeader = make(map[string]bool)
+ }
+ excludeHeader[k] = true
+ trailers = true
+ }
+ }
+ for _, v := range cw.header["Trailer"] {
+ trailers = true
+ foreachHeaderElement(v, cw.res.declareTrailer)
+ }
+
+ te := header.get("Transfer-Encoding")
+ hasTE := te != ""
+
+ // If the handler is done but never sent a Content-Length
+ // response header and this is our first (and last) write, set
+ // it, even to zero. This helps HTTP/1.0 clients keep their
+ // "keep-alive" connections alive.
+ // Exceptions: 304/204/1xx responses never get Content-Length, and if
+ // it was a HEAD request, we don't know the difference between
+ // 0 actual bytes and 0 bytes because the handler noticed it
+ // was a HEAD request and chose not to write anything. So for
+ // HEAD, the handler should either write the Content-Length or
+ // write non-zero bytes. If it's actually 0 bytes and the
+ // handler never looked at the Request.Method, we just don't
+ // send a Content-Length header.
+ // Further, we don't send an automatic Content-Length if they
+ // set a Transfer-Encoding, because they're generally incompatible.
+ if w.handlerDone.Load() && !trailers && !hasTE && bodyAllowedForStatus(w.status) && !header.has("Content-Length") && (!isHEAD || len(p) > 0) {
+ w.contentLength = int64(len(p))
+ setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)
+ }
+
+ // If this was an HTTP/1.0 request with keep-alive and we sent a
+ // Content-Length back, we can make this a keep-alive response ...
+ if w.wants10KeepAlive && keepAlivesEnabled {
+ sentLength := header.get("Content-Length") != ""
+ if sentLength && header.get("Connection") == "keep-alive" {
+ w.closeAfterReply = false
+ }
+ }
+
+ // Check for an explicit (and valid) Content-Length header.
+ hasCL := w.contentLength != -1
+
+ if w.wants10KeepAlive && (isHEAD || hasCL || !bodyAllowedForStatus(w.status)) {
+ _, connectionHeaderSet := header["Connection"]
+ if !connectionHeaderSet {
+ setHeader.connection = "keep-alive"
+ }
+ } else if !w.req.ProtoAtLeast(1, 1) || w.wantsClose {
+ w.closeAfterReply = true
+ }
+
+ if header.get("Connection") == "close" || !keepAlivesEnabled {
+ w.closeAfterReply = true
+ }
+
+ // If the client wanted a 100-continue but we never sent it to
+ // them (or, more strictly: we never finished reading their
+ // request body), don't reuse this connection because it's now
+ // in an unknown state: we might be sending this response at
+ // the same time the client is now sending its request body
+ // after a timeout. (Some HTTP clients send Expect:
+ // 100-continue but knowing that some servers don't support
+ // it, the clients set a timer and send the body later anyway)
+ // If we haven't seen EOF, we can't skip over the unread body
+ // because we don't know if the next bytes on the wire will be
+ // the body-following-the-timer or the subsequent request.
+ // See Issue 11549.
+ if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF.Load() {
+ w.closeAfterReply = true
+ }
+
+ // We do this by default because there are a number of clients that
+ // send a full request before starting to read the response, and they
+ // can deadlock if we start writing the response with unconsumed body
+ // remaining. See Issue 15527 for some history.
+ //
+ // If full duplex mode has been enabled with ResponseController.EnableFullDuplex,
+ // then leave the request body alone.
+ if w.req.ContentLength != 0 && !w.closeAfterReply && !w.fullDuplex {
+ var discard, tooBig bool
+
+ switch bdy := w.req.Body.(type) {
+ case *expectContinueReader:
+ if bdy.resp.wroteContinue {
+ discard = true
+ }
+ case *body:
+ bdy.mu.Lock()
+ switch {
+ case bdy.closed:
+ if !bdy.sawEOF {
+ // Body was closed in handler with non-EOF error.
+ w.closeAfterReply = true
+ }
+ case bdy.unreadDataSizeLocked() >= maxPostHandlerReadBytes:
+ tooBig = true
+ default:
+ discard = true
+ }
+ bdy.mu.Unlock()
+ default:
+ discard = true
+ }
+
+ if discard {
+ _, err := io.CopyN(io.Discard, w.reqBody, maxPostHandlerReadBytes+1)
+ switch err {
+ case nil:
+ // There must be even more data left over.
+ tooBig = true
+ case ErrBodyReadAfterClose:
+ // Body was already consumed and closed.
+ case io.EOF:
+ // The remaining body was just consumed, close it.
+ err = w.reqBody.Close()
+ if err != nil {
+ w.closeAfterReply = true
+ }
+ default:
+ // Some other kind of error occurred, like a read timeout, or
+ // corrupt chunked encoding. In any case, whatever remains
+ // on the wire must not be parsed as another HTTP request.
+ w.closeAfterReply = true
+ }
+ }
+
+ if tooBig {
+ w.requestTooLarge()
+ delHeader("Connection")
+ setHeader.connection = "close"
+ }
+ }
+
+ code := w.status
+ if bodyAllowedForStatus(code) {
+ // If no content type, apply sniffing algorithm to body.
+ _, haveType := header["Content-Type"]
+
+ // If the Content-Encoding was set and is non-blank,
+ // we shouldn't sniff the body. See Issue 31753.
+ ce := header.Get("Content-Encoding")
+ hasCE := len(ce) > 0
+ if !hasCE && !haveType && !hasTE && len(p) > 0 {
+ setHeader.contentType = DetectContentType(p)
+ }
+ } else {
+ for _, k := range suppressedHeaders(code) {
+ delHeader(k)
+ }
+ }
+
+ if !header.has("Date") {
+ setHeader.date = appendTime(cw.res.dateBuf[:0], time.Now())
+ }
+
+ if hasCL && hasTE && te != "identity" {
+ // TODO: return an error if WriteHeader gets a return parameter
+ // For now just ignore the Content-Length.
+ w.conn.server.logf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d",
+ te, w.contentLength)
+ delHeader("Content-Length")
+ hasCL = false
+ }
+
+ if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) || code == StatusNoContent {
+ // Response has no body.
+ delHeader("Transfer-Encoding")
+ } else if hasCL {
+ // Content-Length has been provided, so no chunking is to be done.
+ delHeader("Transfer-Encoding")
+ } else if w.req.ProtoAtLeast(1, 1) {
+ // HTTP/1.1 or greater: Transfer-Encoding has been set to identity, and no
+ // content-length has been provided. The connection must be closed after the
+ // reply is written, and no chunking is to be done. This is the setup
+ // recommended in the Server-Sent Events candidate recommendation 11,
+ // section 8.
+ if hasTE && te == "identity" {
+ cw.chunking = false
+ w.closeAfterReply = true
+ delHeader("Transfer-Encoding")
+ } else {
+ // HTTP/1.1 or greater: use chunked transfer encoding
+ // to avoid closing the connection at EOF.
+ cw.chunking = true
+ setHeader.transferEncoding = "chunked"
+ if hasTE && te == "chunked" {
+ // We will send the chunked Transfer-Encoding header later.
+ delHeader("Transfer-Encoding")
+ }
+ }
+ } else {
+ // HTTP version < 1.1: cannot do chunked transfer
+ // encoding and we don't know the Content-Length so
+ // signal EOF by closing connection.
+ w.closeAfterReply = true
+ delHeader("Transfer-Encoding") // in case already set
+ }
+
+ // Cannot use Content-Length with non-identity Transfer-Encoding.
+ if cw.chunking {
+ delHeader("Content-Length")
+ }
+ if !w.req.ProtoAtLeast(1, 0) {
+ return
+ }
+
+ // Only override the Connection header if it is not a successful
+ // protocol switch response and if KeepAlives are not enabled.
+ // See https://golang.org/issue/36381.
+ delConnectionHeader := w.closeAfterReply &&
+ (!keepAlivesEnabled || !hasToken(cw.header.get("Connection"), "close")) &&
+ !isProtocolSwitchResponse(w.status, header)
+ if delConnectionHeader {
+ delHeader("Connection")
+ if w.req.ProtoAtLeast(1, 1) {
+ setHeader.connection = "close"
+ }
+ }
+
+ writeStatusLine(w.conn.bufw, w.req.ProtoAtLeast(1, 1), code, w.statusBuf[:])
+ cw.header.WriteSubset(w.conn.bufw, excludeHeader)
+ setHeader.Write(w.conn.bufw)
+ w.conn.bufw.Write(crlf)
+}
+
+// foreachHeaderElement splits v according to the "#rule" construction
+// in RFC 7230 section 7 and calls fn for each non-empty element.
+func foreachHeaderElement(v string, fn func(string)) {
+ v = textproto.TrimString(v)
+ if v == "" {
+ return
+ }
+ if !strings.Contains(v, ",") {
+ fn(v)
+ return
+ }
+ for _, f := range strings.Split(v, ",") {
+ if f = textproto.TrimString(f); f != "" {
+ fn(f)
+ }
+ }
+}
+
+// writeStatusLine writes an HTTP/1.x Status-Line (RFC 7230 Section 3.1.2)
+// to bw. is11 is whether the HTTP request is HTTP/1.1. false means HTTP/1.0.
+// code is the response status code.
+// scratch is an optional scratch buffer. If it has at least capacity 3, it's used.
+func writeStatusLine(bw *bufio.Writer, is11 bool, code int, scratch []byte) {
+ if is11 {
+ bw.WriteString("HTTP/1.1 ")
+ } else {
+ bw.WriteString("HTTP/1.0 ")
+ }
+ if text := StatusText(code); text != "" {
+ bw.Write(strconv.AppendInt(scratch[:0], int64(code), 10))
+ bw.WriteByte(' ')
+ bw.WriteString(text)
+ bw.WriteString("\r\n")
+ } else {
+ // don't worry about performance
+ fmt.Fprintf(bw, "%03d status code %d\r\n", code, code)
+ }
+}
+
+// bodyAllowed reports whether a Write is allowed for this response type.
+// It's illegal to call this before the header has been flushed.
+func (w *response) bodyAllowed() bool {
+ if !w.wroteHeader {
+ panic("")
+ }
+ return bodyAllowedForStatus(w.status)
+}
+
+// The Life Of A Write is like this:
+//
+// Handler starts. No header has been sent. The handler can either
+// write a header, or just start writing. Writing before sending a header
+// sends an implicitly empty 200 OK header.
+//
+// If the handler didn't declare a Content-Length up front, we either
+// go into chunking mode or, if the handler finishes running before
+// the chunking buffer size, we compute a Content-Length and send that
+// in the header instead.
+//
+// Likewise, if the handler didn't set a Content-Type, we sniff that
+// from the initial chunk of output.
+//
+// The Writers are wired together like:
+//
+// 1. *response (the ResponseWriter) ->
+// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes ->
+// 3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type)
+// and which writes the chunk headers, if needed ->
+// 4. conn.bufw, a *bufio.Writer of default (4kB) bytes, writing to ->
+// 5. checkConnErrorWriter{c}, which notes any non-nil error on Write
+// and populates c.werr with it if so, but otherwise writes to ->
+// 6. the rwc, the net.Conn.
+//
+// TODO(bradfitz): short-circuit some of the buffering when the
+// initial header contains both a Content-Type and Content-Length.
+// Also short-circuit in (1) when the header's been sent and not in
+// chunking mode, writing directly to (4) instead, if (2) has no
+// buffered data. More generally, we could short-circuit from (1) to
+// (3) even in chunking mode if the write size from (1) is over some
+// threshold and nothing is in (2). The answer might be mostly making
+// bufferBeforeChunkingSize smaller and having bufio's fast-paths deal
+// with this instead.
+func (w *response) Write(data []byte) (n int, err error) {
+ return w.write(len(data), data, "")
+}
+
+func (w *response) WriteString(data string) (n int, err error) {
+ return w.write(len(data), nil, data)
+}
+
+// either dataB or dataS is non-zero.
+func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {
+ if w.conn.hijacked() {
+ if lenData > 0 {
+ caller := relevantCaller()
+ w.conn.server.logf("http: response.Write on hijacked connection from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
+ }
+ return 0, ErrHijacked
+ }
+
+ if w.canWriteContinue.Load() {
+ // Body reader wants to write 100 Continue but hasn't yet.
+ // Tell it not to. The store must be done while holding the lock
+ // because the lock makes sure that there is not an active write
+ // this very moment.
+ w.writeContinueMu.Lock()
+ w.canWriteContinue.Store(false)
+ w.writeContinueMu.Unlock()
+ }
+
+ if !w.wroteHeader {
+ w.WriteHeader(StatusOK)
+ }
+ if lenData == 0 {
+ return 0, nil
+ }
+ if !w.bodyAllowed() {
+ return 0, ErrBodyNotAllowed
+ }
+
+ w.written += int64(lenData) // ignoring errors, for errorKludge
+ if w.contentLength != -1 && w.written > w.contentLength {
+ return 0, ErrContentLength
+ }
+ if dataB != nil {
+ return w.w.Write(dataB)
+ } else {
+ return w.w.WriteString(dataS)
+ }
+}
+
+func (w *response) finishRequest() {
+ w.handlerDone.Store(true)
+
+ if !w.wroteHeader {
+ w.WriteHeader(StatusOK)
+ }
+
+ w.w.Flush()
+ putBufioWriter(w.w)
+ w.cw.close()
+ w.conn.bufw.Flush()
+
+ w.conn.r.abortPendingRead()
+
+ // Close the body (regardless of w.closeAfterReply) so we can
+ // re-use its bufio.Reader later safely.
+ w.reqBody.Close()
+
+ if w.req.MultipartForm != nil {
+ w.req.MultipartForm.RemoveAll()
+ }
+}
+
+// shouldReuseConnection reports whether the underlying TCP connection can be reused.
+// It must only be called after the handler is done executing.
+func (w *response) shouldReuseConnection() bool {
+ if w.closeAfterReply {
+ // The request or something set while executing the
+ // handler indicated we shouldn't reuse this
+ // connection.
+ return false
+ }
+
+ if w.req.Method != "HEAD" && w.contentLength != -1 && w.bodyAllowed() && w.contentLength != w.written {
+ // Did not write enough. Avoid getting out of sync.
+ return false
+ }
+
+ // There was some error writing to the underlying connection
+ // during the request, so don't re-use this conn.
+ if w.conn.werr != nil {
+ return false
+ }
+
+ if w.closedRequestBodyEarly() {
+ return false
+ }
+
+ return true
+}
+
+func (w *response) closedRequestBodyEarly() bool {
+ body, ok := w.req.Body.(*body)
+ return ok && body.didEarlyClose()
+}
+
+func (w *response) Flush() {
+ w.FlushError()
+}
+
+func (w *response) FlushError() error {
+ if !w.wroteHeader {
+ w.WriteHeader(StatusOK)
+ }
+ err := w.w.Flush()
+ e2 := w.cw.flush()
+ if err == nil {
+ err = e2
+ }
+ return err
+}
+
+func (c *conn) finalFlush() {
+ if c.bufr != nil {
+ // Steal the bufio.Reader (~4KB worth of memory) and its associated
+ // reader for a future connection.
+ putBufioReader(c.bufr)
+ c.bufr = nil
+ }
+
+ if c.bufw != nil {
+ c.bufw.Flush()
+ // Steal the bufio.Writer (~4KB worth of memory) and its associated
+ // writer for a future connection.
+ putBufioWriter(c.bufw)
+ c.bufw = nil
+ }
+}
+
+// Close the connection.
+func (c *conn) close() {
+ c.finalFlush()
+ c.rwc.Close()
+}
+
+// rstAvoidanceDelay is the amount of time we sleep after closing the
+// write side of a TCP connection before closing the entire socket.
+// By sleeping, we increase the chances that the client sees our FIN
+// and processes its final data before they process the subsequent RST
+// from closing a connection with known unread data.
+// This RST seems to occur mostly on BSD systems. (And Windows?)
+// This timeout is somewhat arbitrary (~latency around the planet).
+const rstAvoidanceDelay = 500 * time.Millisecond
+
+type closeWriter interface {
+ CloseWrite() error
+}
+
+var _ closeWriter = (*net.TCPConn)(nil)
+
+// closeWriteAndWait flushes any outstanding data and sends a FIN packet (if
+// client is connected via TCP), signaling that we're done. We then
+// pause for a bit, hoping the client processes it before any
+// subsequent RST.
+//
+// See https://golang.org/issue/3595
+func (c *conn) closeWriteAndWait() {
+ c.finalFlush()
+ if tcp, ok := c.rwc.(closeWriter); ok {
+ tcp.CloseWrite()
+ }
+ time.Sleep(rstAvoidanceDelay)
+}
+
+// validNextProto reports whether the proto is a valid ALPN protocol name.
+// Everything is valid except the empty string and built-in protocol types,
+// so that those can't be overridden with alternate implementations.
+func validNextProto(proto string) bool {
+ switch proto {
+ case "", "http/1.1", "http/1.0":
+ return false
+ }
+ return true
+}
+
+const (
+ runHooks = true
+ skipHooks = false
+)
+
+func (c *conn) setState(nc net.Conn, state ConnState, runHook bool) {
+ srv := c.server
+ switch state {
+ case StateNew:
+ srv.trackConn(c, true)
+ case StateHijacked, StateClosed:
+ srv.trackConn(c, false)
+ }
+ if state > 0xff || state < 0 {
+ panic("internal error")
+ }
+ packedState := uint64(time.Now().Unix()<<8) | uint64(state)
+ c.curState.Store(packedState)
+ if !runHook {
+ return
+ }
+ if hook := srv.ConnState; hook != nil {
+ hook(nc, state)
+ }
+}
+
+func (c *conn) getState() (state ConnState, unixSec int64) {
+ packedState := c.curState.Load()
+ return ConnState(packedState & 0xff), int64(packedState >> 8)
+}
+
+// badRequestError is a literal string (used by in the server in HTML,
+// unescaped) to tell the user why their request was bad. It should
+// be plain text without user info or other embedded errors.
+func badRequestError(e string) error { return statusError{StatusBadRequest, e} }
+
+// statusError is an error used to respond to a request with an HTTP status.
+// The text should be plain text without user info or other embedded errors.
+type statusError struct {
+ code int
+ text string
+}
+
+func (e statusError) Error() string { return StatusText(e.code) + ": " + e.text }
+
+// ErrAbortHandler is a sentinel panic value to abort a handler.
+// While any panic from ServeHTTP aborts the response to the client,
+// panicking with ErrAbortHandler also suppresses logging of a stack
+// trace to the server's error log.
+var ErrAbortHandler = errors.New("net/http: abort Handler")
+
+// isCommonNetReadError reports whether err is a common error
+// encountered during reading a request off the network when the
+// client has gone away or had its read fail somehow. This is used to
+// determine which logs are interesting enough to log about.
+func isCommonNetReadError(err error) bool {
+ if err == io.EOF {
+ return true
+ }
+ if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
+ return true
+ }
+ if oe, ok := err.(*net.OpError); ok && oe.Op == "read" {
+ return true
+ }
+ return false
+}
+
+// Serve a new connection.
+func (c *conn) serve(ctx context.Context) {
+ if ra := c.rwc.RemoteAddr(); ra != nil {
+ c.remoteAddr = ra.String()
+ }
+ ctx = context.WithValue(ctx, LocalAddrContextKey, c.rwc.LocalAddr())
+ var inFlightResponse *response
+ defer func() {
+ if err := recover(); err != nil && err != ErrAbortHandler {
+ const size = 64 << 10
+ buf := make([]byte, size)
+ buf = buf[:runtime.Stack(buf, false)]
+ c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
+ }
+ if inFlightResponse != nil {
+ inFlightResponse.cancelCtx()
+ }
+ if !c.hijacked() {
+ if inFlightResponse != nil {
+ inFlightResponse.conn.r.abortPendingRead()
+ inFlightResponse.reqBody.Close()
+ }
+ c.close()
+ c.setState(c.rwc, StateClosed, runHooks)
+ }
+ }()
+
+ if tlsConn, ok := c.rwc.(*tls.Conn); ok {
+ tlsTO := c.server.tlsHandshakeTimeout()
+ if tlsTO > 0 {
+ dl := time.Now().Add(tlsTO)
+ c.rwc.SetReadDeadline(dl)
+ c.rwc.SetWriteDeadline(dl)
+ }
+ if err := tlsConn.HandshakeContext(ctx); err != nil {
+ // If the handshake failed due to the client not speaking
+ // TLS, assume they're speaking plaintext HTTP and write a
+ // 400 response on the TLS conn's underlying net.Conn.
+ if re, ok := err.(tls.RecordHeaderError); ok && re.Conn != nil && tlsRecordHeaderLooksLikeHTTP(re.RecordHeader) {
+ io.WriteString(re.Conn, "HTTP/1.0 400 Bad Request\r\n\r\nClient sent an HTTP request to an HTTPS server.\n")
+ re.Conn.Close()
+ return
+ }
+ c.server.logf("http: TLS handshake error from %s: %v", c.rwc.RemoteAddr(), err)
+ return
+ }
+ // Restore Conn-level deadlines.
+ if tlsTO > 0 {
+ c.rwc.SetReadDeadline(time.Time{})
+ c.rwc.SetWriteDeadline(time.Time{})
+ }
+ c.tlsState = new(tls.ConnectionState)
+ *c.tlsState = tlsConn.ConnectionState()
+ if proto := c.tlsState.NegotiatedProtocol; validNextProto(proto) {
+ if fn := c.server.TLSNextProto[proto]; fn != nil {
+ h := initALPNRequest{ctx, tlsConn, serverHandler{c.server}}
+ // Mark freshly created HTTP/2 as active and prevent any server state hooks
+ // from being run on these connections. This prevents closeIdleConns from
+ // closing such connections. See issue https://golang.org/issue/39776.
+ c.setState(c.rwc, StateActive, skipHooks)
+ fn(c.server, tlsConn, h)
+ }
+ return
+ }
+ }
+
+ // HTTP/1.x from here on.
+
+ ctx, cancelCtx := context.WithCancel(ctx)
+ c.cancelCtx = cancelCtx
+ defer cancelCtx()
+
+ c.r = &connReader{conn: c}
+ c.bufr = newBufioReader(c.r)
+ c.bufw = newBufioWriterSize(checkConnErrorWriter{c}, 4<<10)
+
+ for {
+ w, err := c.readRequest(ctx)
+ if c.r.remain != c.server.initialReadLimitSize() {
+ // If we read any bytes off the wire, we're active.
+ c.setState(c.rwc, StateActive, runHooks)
+ }
+ if err != nil {
+ const errorHeaders = "\r\nContent-Type: text/plain; charset=utf-8\r\nConnection: close\r\n\r\n"
+
+ switch {
+ case err == errTooLarge:
+ // Their HTTP client may or may not be
+ // able to read this if we're
+ // responding to them and hanging up
+ // while they're still writing their
+ // request. Undefined behavior.
+ const publicErr = "431 Request Header Fields Too Large"
+ fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
+ c.closeWriteAndWait()
+ return
+
+ case isUnsupportedTEError(err):
+ // Respond as per RFC 7230 Section 3.3.1 which says,
+ // A server that receives a request message with a
+ // transfer coding it does not understand SHOULD
+ // respond with 501 (Unimplemented).
+ code := StatusNotImplemented
+
+ // We purposefully aren't echoing back the transfer-encoding's value,
+ // so as to mitigate the risk of cross side scripting by an attacker.
+ fmt.Fprintf(c.rwc, "HTTP/1.1 %d %s%sUnsupported transfer encoding", code, StatusText(code), errorHeaders)
+ return
+
+ case isCommonNetReadError(err):
+ return // don't reply
+
+ default:
+ if v, ok := err.(statusError); ok {
+ fmt.Fprintf(c.rwc, "HTTP/1.1 %d %s: %s%s%d %s: %s", v.code, StatusText(v.code), v.text, errorHeaders, v.code, StatusText(v.code), v.text)
+ return
+ }
+ publicErr := "400 Bad Request"
+ fmt.Fprintf(c.rwc, "HTTP/1.1 "+publicErr+errorHeaders+publicErr)
+ return
+ }
+ }
+
+ // Expect 100 Continue support
+ req := w.req
+ if req.expectsContinue() {
+ if req.ProtoAtLeast(1, 1) && req.ContentLength != 0 {
+ // Wrap the Body reader with one that replies on the connection
+ req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
+ w.canWriteContinue.Store(true)
+ }
+ } else if req.Header.get("Expect") != "" {
+ w.sendExpectationFailed()
+ return
+ }
+
+ c.curReq.Store(w)
+
+ if requestBodyRemains(req.Body) {
+ registerOnHitEOF(req.Body, w.conn.r.startBackgroundRead)
+ } else {
+ w.conn.r.startBackgroundRead()
+ }
+
+ // HTTP cannot have multiple simultaneous active requests.[*]
+ // Until the server replies to this request, it can't read another,
+ // so we might as well run the handler in this goroutine.
+ // [*] Not strictly true: HTTP pipelining. We could let them all process
+ // in parallel even if their responses need to be serialized.
+ // But we're not going to implement HTTP pipelining because it
+ // was never deployed in the wild and the answer is HTTP/2.
+ inFlightResponse = w
+ serverHandler{c.server}.ServeHTTP(w, w.req)
+ inFlightResponse = nil
+ w.cancelCtx()
+ if c.hijacked() {
+ return
+ }
+ w.finishRequest()
+ c.rwc.SetWriteDeadline(time.Time{})
+ if !w.shouldReuseConnection() {
+ if w.requestBodyLimitHit || w.closedRequestBodyEarly() {
+ c.closeWriteAndWait()
+ }
+ return
+ }
+ c.setState(c.rwc, StateIdle, runHooks)
+ c.curReq.Store(nil)
+
+ if !w.conn.server.doKeepAlives() {
+ // We're in shutdown mode. We might've replied
+ // to the user without "Connection: close" and
+ // they might think they can send another
+ // request, but such is life with HTTP/1.1.
+ return
+ }
+
+ if d := c.server.idleTimeout(); d != 0 {
+ c.rwc.SetReadDeadline(time.Now().Add(d))
+ } else {
+ c.rwc.SetReadDeadline(time.Time{})
+ }
+
+ // Wait for the connection to become readable again before trying to
+ // read the next request. This prevents a ReadHeaderTimeout or
+ // ReadTimeout from starting until the first bytes of the next request
+ // have been received.
+ if _, err := c.bufr.Peek(4); err != nil {
+ return
+ }
+
+ c.rwc.SetReadDeadline(time.Time{})
+ }
+}
+
+func (w *response) sendExpectationFailed() {
+ // TODO(bradfitz): let ServeHTTP handlers handle
+ // requests with non-standard expectation[s]? Seems
+ // theoretical at best, and doesn't fit into the
+ // current ServeHTTP model anyway. We'd need to
+ // make the ResponseWriter an optional
+ // "ExpectReplier" interface or something.
+ //
+ // For now we'll just obey RFC 7231 5.1.1 which says
+ // "A server that receives an Expect field-value other
+ // than 100-continue MAY respond with a 417 (Expectation
+ // Failed) status code to indicate that the unexpected
+ // expectation cannot be met."
+ w.Header().Set("Connection", "close")
+ w.WriteHeader(StatusExpectationFailed)
+ w.finishRequest()
+}
+
+// Hijack implements the Hijacker.Hijack method. Our response is both a ResponseWriter
+// and a Hijacker.
+func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
+ if w.handlerDone.Load() {
+ panic("net/http: Hijack called after ServeHTTP finished")
+ }
+ if w.wroteHeader {
+ w.cw.flush()
+ }
+
+ c := w.conn
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
+ // Release the bufioWriter that writes to the chunk writer, it is not
+ // used after a connection has been hijacked.
+ rwc, buf, err = c.hijackLocked()
+ if err == nil {
+ putBufioWriter(w.w)
+ w.w = nil
+ }
+ return rwc, buf, err
+}
+
+func (w *response) CloseNotify() <-chan bool {
+ if w.handlerDone.Load() {
+ panic("net/http: CloseNotify called after ServeHTTP finished")
+ }
+ return w.closeNotifyCh
+}
+
+func registerOnHitEOF(rc io.ReadCloser, fn func()) {
+ switch v := rc.(type) {
+ case *expectContinueReader:
+ registerOnHitEOF(v.readCloser, fn)
+ case *body:
+ v.registerOnHitEOF(fn)
+ default:
+ panic("unexpected type " + fmt.Sprintf("%T", rc))
+ }
+}
+
+// requestBodyRemains reports whether future calls to Read
+// on rc might yield more data.
+func requestBodyRemains(rc io.ReadCloser) bool {
+ if rc == NoBody {
+ return false
+ }
+ switch v := rc.(type) {
+ case *expectContinueReader:
+ return requestBodyRemains(v.readCloser)
+ case *body:
+ return v.bodyRemains()
+ default:
+ panic("unexpected type " + fmt.Sprintf("%T", rc))
+ }
+}
+
+// The HandlerFunc type is an adapter to allow the use of
+// ordinary functions as HTTP handlers. If f is a function
+// with the appropriate signature, HandlerFunc(f) is a
+// Handler that calls f.
+type HandlerFunc func(ResponseWriter, *Request)
+
+// ServeHTTP calls f(w, r).
+func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
+ f(w, r)
+}
+
+// Helper handlers
+
+// Error replies to the request with the specified error message and HTTP code.
+// It does not otherwise end the request; the caller should ensure no further
+// writes are done to w.
+// The error message should be plain text.
+func Error(w ResponseWriter, error string, code int) {
+ w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ w.Header().Set("X-Content-Type-Options", "nosniff")
+ w.WriteHeader(code)
+ fmt.Fprintln(w, error)
+}
+
+// NotFound replies to the request with an HTTP 404 not found error.
+func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) }
+
+// NotFoundHandler returns a simple request handler
+// that replies to each request with a “404 page not found” reply.
+func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
+
+// StripPrefix returns a handler that serves HTTP requests by removing the
+// given prefix from the request URL's Path (and RawPath if set) and invoking
+// the handler h. StripPrefix handles a request for a path that doesn't begin
+// with prefix by replying with an HTTP 404 not found error. The prefix must
+// match exactly: if the prefix in the request contains escaped characters
+// the reply is also an HTTP 404 not found error.
+func StripPrefix(prefix string, h Handler) Handler {
+ if prefix == "" {
+ return h
+ }
+ return HandlerFunc(func(w ResponseWriter, r *Request) {
+ p := strings.TrimPrefix(r.URL.Path, prefix)
+ rp := strings.TrimPrefix(r.URL.RawPath, prefix)
+ if len(p) < len(r.URL.Path) && (r.URL.RawPath == "" || len(rp) < len(r.URL.RawPath)) {
+ r2 := new(Request)
+ *r2 = *r
+ r2.URL = new(url.URL)
+ *r2.URL = *r.URL
+ r2.URL.Path = p
+ r2.URL.RawPath = rp
+ h.ServeHTTP(w, r2)
+ } else {
+ NotFound(w, r)
+ }
+ })
+}
+
+// Redirect replies to the request with a redirect to url,
+// which may be a path relative to the request path.
+//
+// The provided code should be in the 3xx range and is usually
+// StatusMovedPermanently, StatusFound or StatusSeeOther.
+//
+// If the Content-Type header has not been set, Redirect sets it
+// to "text/html; charset=utf-8" and writes a small HTML body.
+// Setting the Content-Type header to any value, including nil,
+// disables that behavior.
+func Redirect(w ResponseWriter, r *Request, url string, code int) {
+ if u, err := urlpkg.Parse(url); err == nil {
+ // If url was relative, make its path absolute by
+ // combining with request path.
+ // The client would probably do this for us,
+ // but doing it ourselves is more reliable.
+ // See RFC 7231, section 7.1.2
+ if u.Scheme == "" && u.Host == "" {
+ oldpath := r.URL.Path
+ if oldpath == "" { // should not happen, but avoid a crash if it does
+ oldpath = "/"
+ }
+
+ // no leading http://server
+ if url == "" || url[0] != '/' {
+ // make relative path absolute
+ olddir, _ := path.Split(oldpath)
+ url = olddir + url
+ }
+
+ var query string
+ if i := strings.Index(url, "?"); i != -1 {
+ url, query = url[:i], url[i:]
+ }
+
+ // clean up but preserve trailing slash
+ trailing := strings.HasSuffix(url, "/")
+ url = path.Clean(url)
+ if trailing && !strings.HasSuffix(url, "/") {
+ url += "/"
+ }
+ url += query
+ }
+ }
+
+ h := w.Header()
+
+ // RFC 7231 notes that a short HTML body is usually included in
+ // the response because older user agents may not understand 301/307.
+ // Do it only if the request didn't already have a Content-Type header.
+ _, hadCT := h["Content-Type"]
+
+ h.Set("Location", hexEscapeNonASCII(url))
+ if !hadCT && (r.Method == "GET" || r.Method == "HEAD") {
+ h.Set("Content-Type", "text/html; charset=utf-8")
+ }
+ w.WriteHeader(code)
+
+ // Shouldn't send the body for POST or HEAD; that leaves GET.
+ if !hadCT && r.Method == "GET" {
+ body := "<a href=\"" + htmlEscape(url) + "\">" + StatusText(code) + "</a>.\n"
+ fmt.Fprintln(w, body)
+ }
+}
+
+var htmlReplacer = strings.NewReplacer(
+ "&", "&amp;",
+ "<", "&lt;",
+ ">", "&gt;",
+ // "&#34;" is shorter than "&quot;".
+ `"`, "&#34;",
+ // "&#39;" is shorter than "&apos;" and apos was not in HTML until HTML5.
+ "'", "&#39;",
+)
+
+func htmlEscape(s string) string {
+ return htmlReplacer.Replace(s)
+}
+
+// Redirect to a fixed URL
+type redirectHandler struct {
+ url string
+ code int
+}
+
+func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
+ Redirect(w, r, rh.url, rh.code)
+}
+
+// RedirectHandler returns a request handler that redirects
+// each request it receives to the given url using the given
+// status code.
+//
+// The provided code should be in the 3xx range and is usually
+// StatusMovedPermanently, StatusFound or StatusSeeOther.
+func RedirectHandler(url string, code int) Handler {
+ return &redirectHandler{url, code}
+}
+
+// ServeMux is an HTTP request multiplexer.
+// It matches the URL of each incoming request against a list of registered
+// patterns and calls the handler for the pattern that
+// most closely matches the URL.
+//
+// Patterns name fixed, rooted paths, like "/favicon.ico",
+// or rooted subtrees, like "/images/" (note the trailing slash).
+// Longer patterns take precedence over shorter ones, so that
+// if there are handlers registered for both "/images/"
+// and "/images/thumbnails/", the latter handler will be
+// called for paths beginning with "/images/thumbnails/" and the
+// former will receive requests for any other paths in the
+// "/images/" subtree.
+//
+// Note that since a pattern ending in a slash names a rooted subtree,
+// the pattern "/" matches all paths not matched by other registered
+// patterns, not just the URL with Path == "/".
+//
+// If a subtree has been registered and a request is received naming the
+// subtree root without its trailing slash, ServeMux redirects that
+// request to the subtree root (adding the trailing slash). This behavior can
+// be overridden with a separate registration for the path without
+// the trailing slash. For example, registering "/images/" causes ServeMux
+// to redirect a request for "/images" to "/images/", unless "/images" has
+// been registered separately.
+//
+// Patterns may optionally begin with a host name, restricting matches to
+// URLs on that host only. Host-specific patterns take precedence over
+// general patterns, so that a handler might register for the two patterns
+// "/codesearch" and "codesearch.google.com/" without also taking over
+// requests for "http://www.google.com/".
+//
+// ServeMux also takes care of sanitizing the URL request path and the Host
+// header, stripping the port number and redirecting any request containing . or
+// .. elements or repeated slashes to an equivalent, cleaner URL.
+type ServeMux struct {
+ mu sync.RWMutex
+ m map[string]muxEntry
+ es []muxEntry // slice of entries sorted from longest to shortest.
+ hosts bool // whether any patterns contain hostnames
+}
+
+type muxEntry struct {
+ h Handler
+ pattern string
+}
+
+// NewServeMux allocates and returns a new ServeMux.
+func NewServeMux() *ServeMux { return new(ServeMux) }
+
+// DefaultServeMux is the default ServeMux used by Serve.
+var DefaultServeMux = &defaultServeMux
+
+var defaultServeMux ServeMux
+
+// cleanPath returns the canonical path for p, eliminating . and .. elements.
+func cleanPath(p string) string {
+ if p == "" {
+ return "/"
+ }
+ if p[0] != '/' {
+ p = "/" + p
+ }
+ np := path.Clean(p)
+ // path.Clean removes trailing slash except for root;
+ // put the trailing slash back if necessary.
+ if p[len(p)-1] == '/' && np != "/" {
+ // Fast path for common case of p being the string we want:
+ if len(p) == len(np)+1 && strings.HasPrefix(p, np) {
+ np = p
+ } else {
+ np += "/"
+ }
+ }
+ return np
+}
+
+// stripHostPort returns h without any trailing ":<port>".
+func stripHostPort(h string) string {
+ // If no port on host, return unchanged
+ if !strings.Contains(h, ":") {
+ return h
+ }
+ host, _, err := net.SplitHostPort(h)
+ if err != nil {
+ return h // on error, return unchanged
+ }
+ return host
+}
+
+// Find a handler on a handler map given a path string.
+// Most-specific (longest) pattern wins.
+func (mux *ServeMux) match(path string) (h Handler, pattern string) {
+ // Check for exact match first.
+ v, ok := mux.m[path]
+ if ok {
+ return v.h, v.pattern
+ }
+
+ // Check for longest valid match. mux.es contains all patterns
+ // that end in / sorted from longest to shortest.
+ for _, e := range mux.es {
+ if strings.HasPrefix(path, e.pattern) {
+ return e.h, e.pattern
+ }
+ }
+ return nil, ""
+}
+
+// redirectToPathSlash determines if the given path needs appending "/" to it.
+// This occurs when a handler for path + "/" was already registered, but
+// not for path itself. If the path needs appending to, it creates a new
+// URL, setting the path to u.Path + "/" and returning true to indicate so.
+func (mux *ServeMux) redirectToPathSlash(host, path string, u *url.URL) (*url.URL, bool) {
+ mux.mu.RLock()
+ shouldRedirect := mux.shouldRedirectRLocked(host, path)
+ mux.mu.RUnlock()
+ if !shouldRedirect {
+ return u, false
+ }
+ path = path + "/"
+ u = &url.URL{Path: path, RawQuery: u.RawQuery}
+ return u, true
+}
+
+// shouldRedirectRLocked reports whether the given path and host should be redirected to
+// path+"/". This should happen if a handler is registered for path+"/" but
+// not path -- see comments at ServeMux.
+func (mux *ServeMux) shouldRedirectRLocked(host, path string) bool {
+ p := []string{path, host + path}
+
+ for _, c := range p {
+ if _, exist := mux.m[c]; exist {
+ return false
+ }
+ }
+
+ n := len(path)
+ if n == 0 {
+ return false
+ }
+ for _, c := range p {
+ if _, exist := mux.m[c+"/"]; exist {
+ return path[n-1] != '/'
+ }
+ }
+
+ return false
+}
+
+// Handler returns the handler to use for the given request,
+// consulting r.Method, r.Host, and r.URL.Path. It always returns
+// a non-nil handler. If the path is not in its canonical form, the
+// handler will be an internally-generated handler that redirects
+// to the canonical path. If the host contains a port, it is ignored
+// when matching handlers.
+//
+// The path and host are used unchanged for CONNECT requests.
+//
+// Handler also returns the registered pattern that matches the
+// request or, in the case of internally-generated redirects,
+// the pattern that will match after following the redirect.
+//
+// If there is no registered handler that applies to the request,
+// Handler returns a “page not found” handler and an empty pattern.
+func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
+
+ // CONNECT requests are not canonicalized.
+ if r.Method == "CONNECT" {
+ // If r.URL.Path is /tree and its handler is not registered,
+ // the /tree -> /tree/ redirect applies to CONNECT requests
+ // but the path canonicalization does not.
+ if u, ok := mux.redirectToPathSlash(r.URL.Host, r.URL.Path, r.URL); ok {
+ return RedirectHandler(u.String(), StatusMovedPermanently), u.Path
+ }
+
+ return mux.handler(r.Host, r.URL.Path)
+ }
+
+ // All other requests have any port stripped and path cleaned
+ // before passing to mux.handler.
+ host := stripHostPort(r.Host)
+ path := cleanPath(r.URL.Path)
+
+ // If the given path is /tree and its handler is not registered,
+ // redirect for /tree/.
+ if u, ok := mux.redirectToPathSlash(host, path, r.URL); ok {
+ return RedirectHandler(u.String(), StatusMovedPermanently), u.Path
+ }
+
+ if path != r.URL.Path {
+ _, pattern = mux.handler(host, path)
+ u := &url.URL{Path: path, RawQuery: r.URL.RawQuery}
+ return RedirectHandler(u.String(), StatusMovedPermanently), pattern
+ }
+
+ return mux.handler(host, r.URL.Path)
+}
+
+// handler is the main implementation of Handler.
+// The path is known to be in canonical form, except for CONNECT methods.
+func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
+ mux.mu.RLock()
+ defer mux.mu.RUnlock()
+
+ // Host-specific pattern takes precedence over generic ones
+ if mux.hosts {
+ h, pattern = mux.match(host + path)
+ }
+ if h == nil {
+ h, pattern = mux.match(path)
+ }
+ if h == nil {
+ h, pattern = NotFoundHandler(), ""
+ }
+ return
+}
+
+// ServeHTTP dispatches the request to the handler whose
+// pattern most closely matches the request URL.
+func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
+ if r.RequestURI == "*" {
+ if r.ProtoAtLeast(1, 1) {
+ w.Header().Set("Connection", "close")
+ }
+ w.WriteHeader(StatusBadRequest)
+ return
+ }
+ h, _ := mux.Handler(r)
+ h.ServeHTTP(w, r)
+}
+
+// Handle registers the handler for the given pattern.
+// If a handler already exists for pattern, Handle panics.
+func (mux *ServeMux) Handle(pattern string, handler Handler) {
+ mux.mu.Lock()
+ defer mux.mu.Unlock()
+
+ if pattern == "" {
+ panic("http: invalid pattern")
+ }
+ if handler == nil {
+ panic("http: nil handler")
+ }
+ if _, exist := mux.m[pattern]; exist {
+ panic("http: multiple registrations for " + pattern)
+ }
+
+ if mux.m == nil {
+ mux.m = make(map[string]muxEntry)
+ }
+ e := muxEntry{h: handler, pattern: pattern}
+ mux.m[pattern] = e
+ if pattern[len(pattern)-1] == '/' {
+ mux.es = appendSorted(mux.es, e)
+ }
+
+ if pattern[0] != '/' {
+ mux.hosts = true
+ }
+}
+
+func appendSorted(es []muxEntry, e muxEntry) []muxEntry {
+ n := len(es)
+ i := sort.Search(n, func(i int) bool {
+ return len(es[i].pattern) < len(e.pattern)
+ })
+ if i == n {
+ return append(es, e)
+ }
+ // we now know that i points at where we want to insert
+ es = append(es, muxEntry{}) // try to grow the slice in place, any entry works.
+ copy(es[i+1:], es[i:]) // Move shorter entries down
+ es[i] = e
+ return es
+}
+
+// HandleFunc registers the handler function for the given pattern.
+func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
+ if handler == nil {
+ panic("http: nil handler")
+ }
+ mux.Handle(pattern, HandlerFunc(handler))
+}
+
+// Handle registers the handler for the given pattern
+// in the DefaultServeMux.
+// The documentation for ServeMux explains how patterns are matched.
+func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
+
+// HandleFunc registers the handler function for the given pattern
+// in the DefaultServeMux.
+// The documentation for ServeMux explains how patterns are matched.
+func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
+ DefaultServeMux.HandleFunc(pattern, handler)
+}
+
+// Serve accepts incoming HTTP connections on the listener l,
+// creating a new service goroutine for each. The service goroutines
+// read requests and then call handler to reply to them.
+//
+// The handler is typically nil, in which case the DefaultServeMux is used.
+//
+// HTTP/2 support is only enabled if the Listener returns *tls.Conn
+// connections and they were configured with "h2" in the TLS
+// Config.NextProtos.
+//
+// Serve always returns a non-nil error.
+func Serve(l net.Listener, handler Handler) error {
+ srv := &Server{Handler: handler}
+ return srv.Serve(l)
+}
+
+// ServeTLS accepts incoming HTTPS connections on the listener l,
+// creating a new service goroutine for each. The service goroutines
+// read requests and then call handler to reply to them.
+//
+// The handler is typically nil, in which case the DefaultServeMux is used.
+//
+// Additionally, files containing a certificate and matching private key
+// for the server must be provided. If the certificate is signed by a
+// certificate authority, the certFile should be the concatenation
+// of the server's certificate, any intermediates, and the CA's certificate.
+//
+// ServeTLS always returns a non-nil error.
+func ServeTLS(l net.Listener, handler Handler, certFile, keyFile string) error {
+ srv := &Server{Handler: handler}
+ return srv.ServeTLS(l, certFile, keyFile)
+}
+
+// A Server defines parameters for running an HTTP server.
+// The zero value for Server is a valid configuration.
+type Server struct {
+ // Addr optionally specifies the TCP address for the server to listen on,
+ // in the form "host:port". If empty, ":http" (port 80) is used.
+ // The service names are defined in RFC 6335 and assigned by IANA.
+ // See net.Dial for details of the address format.
+ Addr string
+
+ Handler Handler // handler to invoke, http.DefaultServeMux if nil
+
+ // DisableGeneralOptionsHandler, if true, passes "OPTIONS *" requests to the Handler,
+ // otherwise responds with 200 OK and Content-Length: 0.
+ DisableGeneralOptionsHandler bool
+
+ // TLSConfig optionally provides a TLS configuration for use
+ // by ServeTLS and ListenAndServeTLS. Note that this value is
+ // cloned by ServeTLS and ListenAndServeTLS, so it's not
+ // possible to modify the configuration with methods like
+ // tls.Config.SetSessionTicketKeys. To use
+ // SetSessionTicketKeys, use Server.Serve with a TLS Listener
+ // instead.
+ TLSConfig *tls.Config
+
+ // ReadTimeout is the maximum duration for reading the entire
+ // request, including the body. A zero or negative value means
+ // there will be no timeout.
+ //
+ // Because ReadTimeout does not let Handlers make per-request
+ // decisions on each request body's acceptable deadline or
+ // upload rate, most users will prefer to use
+ // ReadHeaderTimeout. It is valid to use them both.
+ ReadTimeout time.Duration
+
+ // ReadHeaderTimeout is the amount of time allowed to read
+ // request headers. The connection's read deadline is reset
+ // after reading the headers and the Handler can decide what
+ // is considered too slow for the body. If ReadHeaderTimeout
+ // is zero, the value of ReadTimeout is used. If both are
+ // zero, there is no timeout.
+ ReadHeaderTimeout time.Duration
+
+ // WriteTimeout is the maximum duration before timing out
+ // writes of the response. It is reset whenever a new
+ // request's header is read. Like ReadTimeout, it does not
+ // let Handlers make decisions on a per-request basis.
+ // A zero or negative value means there will be no timeout.
+ WriteTimeout time.Duration
+
+ // IdleTimeout is the maximum amount of time to wait for the
+ // next request when keep-alives are enabled. If IdleTimeout
+ // is zero, the value of ReadTimeout is used. If both are
+ // zero, there is no timeout.
+ IdleTimeout time.Duration
+
+ // MaxHeaderBytes controls the maximum number of bytes the
+ // server will read parsing the request header's keys and
+ // values, including the request line. It does not limit the
+ // size of the request body.
+ // If zero, DefaultMaxHeaderBytes is used.
+ MaxHeaderBytes int
+
+ // TLSNextProto optionally specifies a function to take over
+ // ownership of the provided TLS connection when an ALPN
+ // protocol upgrade has occurred. The map key is the protocol
+ // name negotiated. The Handler argument should be used to
+ // handle HTTP requests and will initialize the Request's TLS
+ // and RemoteAddr if not already set. The connection is
+ // automatically closed when the function returns.
+ // If TLSNextProto is not nil, HTTP/2 support is not enabled
+ // automatically.
+ TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
+
+ // ConnState specifies an optional callback function that is
+ // called when a client connection changes state. See the
+ // ConnState type and associated constants for details.
+ ConnState func(net.Conn, ConnState)
+
+ // ErrorLog specifies an optional logger for errors accepting
+ // connections, unexpected behavior from handlers, and
+ // underlying FileSystem errors.
+ // If nil, logging is done via the log package's standard logger.
+ ErrorLog *log.Logger
+
+ // BaseContext optionally specifies a function that returns
+ // the base context for incoming requests on this server.
+ // The provided Listener is the specific Listener that's
+ // about to start accepting requests.
+ // If BaseContext is nil, the default is context.Background().
+ // If non-nil, it must return a non-nil context.
+ BaseContext func(net.Listener) context.Context
+
+ // ConnContext optionally specifies a function that modifies
+ // the context used for a new connection c. The provided ctx
+ // is derived from the base context and has a ServerContextKey
+ // value.
+ ConnContext func(ctx context.Context, c net.Conn) context.Context
+
+ inShutdown atomic.Bool // true when server is in shutdown
+
+ disableKeepAlives atomic.Bool
+ nextProtoOnce sync.Once // guards setupHTTP2_* init
+ nextProtoErr error // result of http2.ConfigureServer if used
+
+ mu sync.Mutex
+ listeners map[*net.Listener]struct{}
+ activeConn map[*conn]struct{}
+ onShutdown []func()
+
+ listenerGroup sync.WaitGroup
+}
+
+// Close immediately closes all active net.Listeners and any
+// connections in state StateNew, StateActive, or StateIdle. For a
+// graceful shutdown, use Shutdown.
+//
+// Close does not attempt to close (and does not even know about)
+// any hijacked connections, such as WebSockets.
+//
+// Close returns any error returned from closing the Server's
+// underlying Listener(s).
+func (srv *Server) Close() error {
+ srv.inShutdown.Store(true)
+ srv.mu.Lock()
+ defer srv.mu.Unlock()
+ err := srv.closeListenersLocked()
+
+ // Unlock srv.mu while waiting for listenerGroup.
+ // The group Add and Done calls are made with srv.mu held,
+ // to avoid adding a new listener in the window between
+ // us setting inShutdown above and waiting here.
+ srv.mu.Unlock()
+ srv.listenerGroup.Wait()
+ srv.mu.Lock()
+
+ for c := range srv.activeConn {
+ c.rwc.Close()
+ delete(srv.activeConn, c)
+ }
+ return err
+}
+
+// shutdownPollIntervalMax is the max polling interval when checking
+// quiescence during Server.Shutdown. Polling starts with a small
+// interval and backs off to the max.
+// Ideally we could find a solution that doesn't involve polling,
+// but which also doesn't have a high runtime cost (and doesn't
+// involve any contentious mutexes), but that is left as an
+// exercise for the reader.
+const shutdownPollIntervalMax = 500 * time.Millisecond
+
+// Shutdown gracefully shuts down the server without interrupting any
+// active connections. Shutdown works by first closing all open
+// listeners, then closing all idle connections, and then waiting
+// indefinitely for connections to return to idle and then shut down.
+// If the provided context expires before the shutdown is complete,
+// Shutdown returns the context's error, otherwise it returns any
+// error returned from closing the Server's underlying Listener(s).
+//
+// When Shutdown is called, Serve, ListenAndServe, and
+// ListenAndServeTLS immediately return ErrServerClosed. Make sure the
+// program doesn't exit and waits instead for Shutdown to return.
+//
+// Shutdown does not attempt to close nor wait for hijacked
+// connections such as WebSockets. The caller of Shutdown should
+// separately notify such long-lived connections of shutdown and wait
+// for them to close, if desired. See RegisterOnShutdown for a way to
+// register shutdown notification functions.
+//
+// Once Shutdown has been called on a server, it may not be reused;
+// future calls to methods such as Serve will return ErrServerClosed.
+func (srv *Server) Shutdown(ctx context.Context) error {
+ srv.inShutdown.Store(true)
+
+ srv.mu.Lock()
+ lnerr := srv.closeListenersLocked()
+ for _, f := range srv.onShutdown {
+ go f()
+ }
+ srv.mu.Unlock()
+ srv.listenerGroup.Wait()
+
+ pollIntervalBase := time.Millisecond
+ nextPollInterval := func() time.Duration {
+ // Add 10% jitter.
+ interval := pollIntervalBase + time.Duration(rand.Intn(int(pollIntervalBase/10)))
+ // Double and clamp for next time.
+ pollIntervalBase *= 2
+ if pollIntervalBase > shutdownPollIntervalMax {
+ pollIntervalBase = shutdownPollIntervalMax
+ }
+ return interval
+ }
+
+ timer := time.NewTimer(nextPollInterval())
+ defer timer.Stop()
+ for {
+ if srv.closeIdleConns() {
+ return lnerr
+ }
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ case <-timer.C:
+ timer.Reset(nextPollInterval())
+ }
+ }
+}
+
+// RegisterOnShutdown registers a function to call on Shutdown.
+// This can be used to gracefully shutdown connections that have
+// undergone ALPN protocol upgrade or that have been hijacked.
+// This function should start protocol-specific graceful shutdown,
+// but should not wait for shutdown to complete.
+func (srv *Server) RegisterOnShutdown(f func()) {
+ srv.mu.Lock()
+ srv.onShutdown = append(srv.onShutdown, f)
+ srv.mu.Unlock()
+}
+
+// closeIdleConns closes all idle connections and reports whether the
+// server is quiescent.
+func (s *Server) closeIdleConns() bool {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ quiescent := true
+ for c := range s.activeConn {
+ st, unixSec := c.getState()
+ // Issue 22682: treat StateNew connections as if
+ // they're idle if we haven't read the first request's
+ // header in over 5 seconds.
+ if st == StateNew && unixSec < time.Now().Unix()-5 {
+ st = StateIdle
+ }
+ if st != StateIdle || unixSec == 0 {
+ // Assume unixSec == 0 means it's a very new
+ // connection, without state set yet.
+ quiescent = false
+ continue
+ }
+ c.rwc.Close()
+ delete(s.activeConn, c)
+ }
+ return quiescent
+}
+
+func (s *Server) closeListenersLocked() error {
+ var err error
+ for ln := range s.listeners {
+ if cerr := (*ln).Close(); cerr != nil && err == nil {
+ err = cerr
+ }
+ }
+ return err
+}
+
+// A ConnState represents the state of a client connection to a server.
+// It's used by the optional Server.ConnState hook.
+type ConnState int
+
+const (
+ // StateNew represents a new connection that is expected to
+ // send a request immediately. Connections begin at this
+ // state and then transition to either StateActive or
+ // StateClosed.
+ StateNew ConnState = iota
+
+ // StateActive represents a connection that has read 1 or more
+ // bytes of a request. The Server.ConnState hook for
+ // StateActive fires before the request has entered a handler
+ // and doesn't fire again until the request has been
+ // handled. After the request is handled, the state
+ // transitions to StateClosed, StateHijacked, or StateIdle.
+ // For HTTP/2, StateActive fires on the transition from zero
+ // to one active request, and only transitions away once all
+ // active requests are complete. That means that ConnState
+ // cannot be used to do per-request work; ConnState only notes
+ // the overall state of the connection.
+ StateActive
+
+ // StateIdle represents a connection that has finished
+ // handling a request and is in the keep-alive state, waiting
+ // for a new request. Connections transition from StateIdle
+ // to either StateActive or StateClosed.
+ StateIdle
+
+ // StateHijacked represents a hijacked connection.
+ // This is a terminal state. It does not transition to StateClosed.
+ StateHijacked
+
+ // StateClosed represents a closed connection.
+ // This is a terminal state. Hijacked connections do not
+ // transition to StateClosed.
+ StateClosed
+)
+
+var stateName = map[ConnState]string{
+ StateNew: "new",
+ StateActive: "active",
+ StateIdle: "idle",
+ StateHijacked: "hijacked",
+ StateClosed: "closed",
+}
+
+func (c ConnState) String() string {
+ return stateName[c]
+}
+
+// serverHandler delegates to either the server's Handler or
+// DefaultServeMux and also handles "OPTIONS *" requests.
+type serverHandler struct {
+ srv *Server
+}
+
+func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
+ handler := sh.srv.Handler
+ if handler == nil {
+ handler = DefaultServeMux
+ }
+ if !sh.srv.DisableGeneralOptionsHandler && req.RequestURI == "*" && req.Method == "OPTIONS" {
+ handler = globalOptionsHandler{}
+ }
+
+ handler.ServeHTTP(rw, req)
+}
+
+// AllowQuerySemicolons returns a handler that serves requests by converting any
+// unescaped semicolons in the URL query to ampersands, and invoking the handler h.
+//
+// This restores the pre-Go 1.17 behavior of splitting query parameters on both
+// semicolons and ampersands. (See golang.org/issue/25192). Note that this
+// behavior doesn't match that of many proxies, and the mismatch can lead to
+// security issues.
+//
+// AllowQuerySemicolons should be invoked before Request.ParseForm is called.
+func AllowQuerySemicolons(h Handler) Handler {
+ return HandlerFunc(func(w ResponseWriter, r *Request) {
+ if strings.Contains(r.URL.RawQuery, ";") {
+ r2 := new(Request)
+ *r2 = *r
+ r2.URL = new(url.URL)
+ *r2.URL = *r.URL
+ r2.URL.RawQuery = strings.ReplaceAll(r.URL.RawQuery, ";", "&")
+ h.ServeHTTP(w, r2)
+ } else {
+ h.ServeHTTP(w, r)
+ }
+ })
+}
+
+// ListenAndServe listens on the TCP network address srv.Addr and then
+// calls Serve to handle requests on incoming connections.
+// Accepted connections are configured to enable TCP keep-alives.
+//
+// If srv.Addr is blank, ":http" is used.
+//
+// ListenAndServe always returns a non-nil error. After Shutdown or Close,
+// the returned error is ErrServerClosed.
+func (srv *Server) ListenAndServe() error {
+ if srv.shuttingDown() {
+ return ErrServerClosed
+ }
+ addr := srv.Addr
+ if addr == "" {
+ addr = ":http"
+ }
+ ln, err := net.Listen("tcp", addr)
+ if err != nil {
+ return err
+ }
+ return srv.Serve(ln)
+}
+
+var testHookServerServe func(*Server, net.Listener) // used if non-nil
+
+// shouldConfigureHTTP2ForServe reports whether Server.Serve should configure
+// automatic HTTP/2. (which sets up the srv.TLSNextProto map)
+func (srv *Server) shouldConfigureHTTP2ForServe() bool {
+ if srv.TLSConfig == nil {
+ // Compatibility with Go 1.6:
+ // If there's no TLSConfig, it's possible that the user just
+ // didn't set it on the http.Server, but did pass it to
+ // tls.NewListener and passed that listener to Serve.
+ // So we should configure HTTP/2 (to set up srv.TLSNextProto)
+ // in case the listener returns an "h2" *tls.Conn.
+ return true
+ }
+ // The user specified a TLSConfig on their http.Server.
+ // In this, case, only configure HTTP/2 if their tls.Config
+ // explicitly mentions "h2". Otherwise http2.ConfigureServer
+ // would modify the tls.Config to add it, but they probably already
+ // passed this tls.Config to tls.NewListener. And if they did,
+ // it's too late anyway to fix it. It would only be potentially racy.
+ // See Issue 15908.
+ return strSliceContains(srv.TLSConfig.NextProtos, http2NextProtoTLS)
+}
+
+// ErrServerClosed is returned by the Server's Serve, ServeTLS, ListenAndServe,
+// and ListenAndServeTLS methods after a call to Shutdown or Close.
+var ErrServerClosed = errors.New("http: Server closed")
+
+// Serve accepts incoming connections on the Listener l, creating a
+// new service goroutine for each. The service goroutines read requests and
+// then call srv.Handler to reply to them.
+//
+// HTTP/2 support is only enabled if the Listener returns *tls.Conn
+// connections and they were configured with "h2" in the TLS
+// Config.NextProtos.
+//
+// Serve always returns a non-nil error and closes l.
+// After Shutdown or Close, the returned error is ErrServerClosed.
+func (srv *Server) Serve(l net.Listener) error {
+ if fn := testHookServerServe; fn != nil {
+ fn(srv, l) // call hook with unwrapped listener
+ }
+
+ origListener := l
+ l = &onceCloseListener{Listener: l}
+ defer l.Close()
+
+ if err := srv.setupHTTP2_Serve(); err != nil {
+ return err
+ }
+
+ if !srv.trackListener(&l, true) {
+ return ErrServerClosed
+ }
+ defer srv.trackListener(&l, false)
+
+ baseCtx := context.Background()
+ if srv.BaseContext != nil {
+ baseCtx = srv.BaseContext(origListener)
+ if baseCtx == nil {
+ panic("BaseContext returned a nil context")
+ }
+ }
+
+ var tempDelay time.Duration // how long to sleep on accept failure
+
+ ctx := context.WithValue(baseCtx, ServerContextKey, srv)
+ for {
+ rw, err := l.Accept()
+ if err != nil {
+ if srv.shuttingDown() {
+ return ErrServerClosed
+ }
+ if ne, ok := err.(net.Error); ok && ne.Temporary() {
+ if tempDelay == 0 {
+ tempDelay = 5 * time.Millisecond
+ } else {
+ tempDelay *= 2
+ }
+ if max := 1 * time.Second; tempDelay > max {
+ tempDelay = max
+ }
+ srv.logf("http: Accept error: %v; retrying in %v", err, tempDelay)
+ time.Sleep(tempDelay)
+ continue
+ }
+ return err
+ }
+ connCtx := ctx
+ if cc := srv.ConnContext; cc != nil {
+ connCtx = cc(connCtx, rw)
+ if connCtx == nil {
+ panic("ConnContext returned nil")
+ }
+ }
+ tempDelay = 0
+ c := srv.newConn(rw)
+ c.setState(c.rwc, StateNew, runHooks) // before Serve can return
+ go c.serve(connCtx)
+ }
+}
+
+// ServeTLS accepts incoming connections on the Listener l, creating a
+// new service goroutine for each. The service goroutines perform TLS
+// setup and then read requests, calling srv.Handler to reply to them.
+//
+// Files containing a certificate and matching private key for the
+// server must be provided if neither the Server's
+// TLSConfig.Certificates nor TLSConfig.GetCertificate are populated.
+// If the certificate is signed by a certificate authority, the
+// certFile should be the concatenation of the server's certificate,
+// any intermediates, and the CA's certificate.
+//
+// ServeTLS always returns a non-nil error. After Shutdown or Close, the
+// returned error is ErrServerClosed.
+func (srv *Server) ServeTLS(l net.Listener, certFile, keyFile string) error {
+ // Setup HTTP/2 before srv.Serve, to initialize srv.TLSConfig
+ // before we clone it and create the TLS Listener.
+ if err := srv.setupHTTP2_ServeTLS(); err != nil {
+ return err
+ }
+
+ config := cloneTLSConfig(srv.TLSConfig)
+ if !strSliceContains(config.NextProtos, "http/1.1") {
+ config.NextProtos = append(config.NextProtos, "http/1.1")
+ }
+
+ configHasCert := len(config.Certificates) > 0 || config.GetCertificate != nil
+ if !configHasCert || certFile != "" || keyFile != "" {
+ var err error
+ config.Certificates = make([]tls.Certificate, 1)
+ config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
+ if err != nil {
+ return err
+ }
+ }
+
+ tlsListener := tls.NewListener(l, config)
+ return srv.Serve(tlsListener)
+}
+
+// trackListener adds or removes a net.Listener to the set of tracked
+// listeners.
+//
+// We store a pointer to interface in the map set, in case the
+// net.Listener is not comparable. This is safe because we only call
+// trackListener via Serve and can track+defer untrack the same
+// pointer to local variable there. We never need to compare a
+// Listener from another caller.
+//
+// It reports whether the server is still up (not Shutdown or Closed).
+func (s *Server) trackListener(ln *net.Listener, add bool) bool {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if s.listeners == nil {
+ s.listeners = make(map[*net.Listener]struct{})
+ }
+ if add {
+ if s.shuttingDown() {
+ return false
+ }
+ s.listeners[ln] = struct{}{}
+ s.listenerGroup.Add(1)
+ } else {
+ delete(s.listeners, ln)
+ s.listenerGroup.Done()
+ }
+ return true
+}
+
+func (s *Server) trackConn(c *conn, add bool) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if s.activeConn == nil {
+ s.activeConn = make(map[*conn]struct{})
+ }
+ if add {
+ s.activeConn[c] = struct{}{}
+ } else {
+ delete(s.activeConn, c)
+ }
+}
+
+func (s *Server) idleTimeout() time.Duration {
+ if s.IdleTimeout != 0 {
+ return s.IdleTimeout
+ }
+ return s.ReadTimeout
+}
+
+func (s *Server) readHeaderTimeout() time.Duration {
+ if s.ReadHeaderTimeout != 0 {
+ return s.ReadHeaderTimeout
+ }
+ return s.ReadTimeout
+}
+
+func (s *Server) doKeepAlives() bool {
+ return !s.disableKeepAlives.Load() && !s.shuttingDown()
+}
+
+func (s *Server) shuttingDown() bool {
+ return s.inShutdown.Load()
+}
+
+// SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled.
+// By default, keep-alives are always enabled. Only very
+// resource-constrained environments or servers in the process of
+// shutting down should disable them.
+func (srv *Server) SetKeepAlivesEnabled(v bool) {
+ if v {
+ srv.disableKeepAlives.Store(false)
+ return
+ }
+ srv.disableKeepAlives.Store(true)
+
+ // Close idle HTTP/1 conns:
+ srv.closeIdleConns()
+
+ // TODO: Issue 26303: close HTTP/2 conns as soon as they become idle.
+}
+
+func (s *Server) logf(format string, args ...any) {
+ if s.ErrorLog != nil {
+ s.ErrorLog.Printf(format, args...)
+ } else {
+ log.Printf(format, args...)
+ }
+}
+
+// logf prints to the ErrorLog of the *Server associated with request r
+// via ServerContextKey. If there's no associated server, or if ErrorLog
+// is nil, logging is done via the log package's standard logger.
+func logf(r *Request, format string, args ...any) {
+ s, _ := r.Context().Value(ServerContextKey).(*Server)
+ if s != nil && s.ErrorLog != nil {
+ s.ErrorLog.Printf(format, args...)
+ } else {
+ log.Printf(format, args...)
+ }
+}
+
+// ListenAndServe listens on the TCP network address addr and then calls
+// Serve with handler to handle requests on incoming connections.
+// Accepted connections are configured to enable TCP keep-alives.
+//
+// The handler is typically nil, in which case the DefaultServeMux is used.
+//
+// ListenAndServe always returns a non-nil error.
+func ListenAndServe(addr string, handler Handler) error {
+ server := &Server{Addr: addr, Handler: handler}
+ return server.ListenAndServe()
+}
+
+// ListenAndServeTLS acts identically to ListenAndServe, except that it
+// expects HTTPS connections. Additionally, files containing a certificate and
+// matching private key for the server must be provided. If the certificate
+// is signed by a certificate authority, the certFile should be the concatenation
+// of the server's certificate, any intermediates, and the CA's certificate.
+func ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error {
+ server := &Server{Addr: addr, Handler: handler}
+ return server.ListenAndServeTLS(certFile, keyFile)
+}
+
+// ListenAndServeTLS listens on the TCP network address srv.Addr and
+// then calls ServeTLS to handle requests on incoming TLS connections.
+// Accepted connections are configured to enable TCP keep-alives.
+//
+// Filenames containing a certificate and matching private key for the
+// server must be provided if neither the Server's TLSConfig.Certificates
+// nor TLSConfig.GetCertificate are populated. If the certificate is
+// signed by a certificate authority, the certFile should be the
+// concatenation of the server's certificate, any intermediates, and
+// the CA's certificate.
+//
+// If srv.Addr is blank, ":https" is used.
+//
+// ListenAndServeTLS always returns a non-nil error. After Shutdown or
+// Close, the returned error is ErrServerClosed.
+func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
+ if srv.shuttingDown() {
+ return ErrServerClosed
+ }
+ addr := srv.Addr
+ if addr == "" {
+ addr = ":https"
+ }
+
+ ln, err := net.Listen("tcp", addr)
+ if err != nil {
+ return err
+ }
+
+ defer ln.Close()
+
+ return srv.ServeTLS(ln, certFile, keyFile)
+}
+
+// setupHTTP2_ServeTLS conditionally configures HTTP/2 on
+// srv and reports whether there was an error setting it up. If it is
+// not configured for policy reasons, nil is returned.
+func (srv *Server) setupHTTP2_ServeTLS() error {
+ srv.nextProtoOnce.Do(srv.onceSetNextProtoDefaults)
+ return srv.nextProtoErr
+}
+
+// setupHTTP2_Serve is called from (*Server).Serve and conditionally
+// configures HTTP/2 on srv using a more conservative policy than
+// setupHTTP2_ServeTLS because Serve is called after tls.Listen,
+// and may be called concurrently. See shouldConfigureHTTP2ForServe.
+//
+// The tests named TestTransportAutomaticHTTP2* and
+// TestConcurrentServerServe in server_test.go demonstrate some
+// of the supported use cases and motivations.
+func (srv *Server) setupHTTP2_Serve() error {
+ srv.nextProtoOnce.Do(srv.onceSetNextProtoDefaults_Serve)
+ return srv.nextProtoErr
+}
+
+func (srv *Server) onceSetNextProtoDefaults_Serve() {
+ if srv.shouldConfigureHTTP2ForServe() {
+ srv.onceSetNextProtoDefaults()
+ }
+}
+
+var http2server = godebug.New("http2server")
+
+// onceSetNextProtoDefaults configures HTTP/2, if the user hasn't
+// configured otherwise. (by setting srv.TLSNextProto non-nil)
+// It must only be called via srv.nextProtoOnce (use srv.setupHTTP2_*).
+func (srv *Server) onceSetNextProtoDefaults() {
+ if omitBundledHTTP2 {
+ return
+ }
+ if http2server.Value() == "0" {
+ http2server.IncNonDefault()
+ return
+ }
+ // Enable HTTP/2 by default if the user hasn't otherwise
+ // configured their TLSNextProto map.
+ if srv.TLSNextProto == nil {
+ conf := &http2Server{
+ NewWriteScheduler: func() http2WriteScheduler { return http2NewPriorityWriteScheduler(nil) },
+ }
+ srv.nextProtoErr = http2ConfigureServer(srv, conf)
+ }
+}
+
+// TimeoutHandler returns a Handler that runs h with the given time limit.
+//
+// The new Handler calls h.ServeHTTP to handle each request, but if a
+// call runs for longer than its time limit, the handler responds with
+// a 503 Service Unavailable error and the given message in its body.
+// (If msg is empty, a suitable default message will be sent.)
+// After such a timeout, writes by h to its ResponseWriter will return
+// ErrHandlerTimeout.
+//
+// TimeoutHandler supports the Pusher interface but does not support
+// the Hijacker or Flusher interfaces.
+func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
+ return &timeoutHandler{
+ handler: h,
+ body: msg,
+ dt: dt,
+ }
+}
+
+// ErrHandlerTimeout is returned on ResponseWriter Write calls
+// in handlers which have timed out.
+var ErrHandlerTimeout = errors.New("http: Handler timeout")
+
+type timeoutHandler struct {
+ handler Handler
+ body string
+ dt time.Duration
+
+ // When set, no context will be created and this context will
+ // be used instead.
+ testContext context.Context
+}
+
+func (h *timeoutHandler) errorBody() string {
+ if h.body != "" {
+ return h.body
+ }
+ return "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>"
+}
+
+func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
+ ctx := h.testContext
+ if ctx == nil {
+ var cancelCtx context.CancelFunc
+ ctx, cancelCtx = context.WithTimeout(r.Context(), h.dt)
+ defer cancelCtx()
+ }
+ r = r.WithContext(ctx)
+ done := make(chan struct{})
+ tw := &timeoutWriter{
+ w: w,
+ h: make(Header),
+ req: r,
+ }
+ panicChan := make(chan any, 1)
+ go func() {
+ defer func() {
+ if p := recover(); p != nil {
+ panicChan <- p
+ }
+ }()
+ h.handler.ServeHTTP(tw, r)
+ close(done)
+ }()
+ select {
+ case p := <-panicChan:
+ panic(p)
+ case <-done:
+ tw.mu.Lock()
+ defer tw.mu.Unlock()
+ dst := w.Header()
+ for k, vv := range tw.h {
+ dst[k] = vv
+ }
+ if !tw.wroteHeader {
+ tw.code = StatusOK
+ }
+ w.WriteHeader(tw.code)
+ w.Write(tw.wbuf.Bytes())
+ case <-ctx.Done():
+ tw.mu.Lock()
+ defer tw.mu.Unlock()
+ switch err := ctx.Err(); err {
+ case context.DeadlineExceeded:
+ w.WriteHeader(StatusServiceUnavailable)
+ io.WriteString(w, h.errorBody())
+ tw.err = ErrHandlerTimeout
+ default:
+ w.WriteHeader(StatusServiceUnavailable)
+ tw.err = err
+ }
+ }
+}
+
+type timeoutWriter struct {
+ w ResponseWriter
+ h Header
+ wbuf bytes.Buffer
+ req *Request
+
+ mu sync.Mutex
+ err error
+ wroteHeader bool
+ code int
+}
+
+var _ Pusher = (*timeoutWriter)(nil)
+
+// Push implements the Pusher interface.
+func (tw *timeoutWriter) Push(target string, opts *PushOptions) error {
+ if pusher, ok := tw.w.(Pusher); ok {
+ return pusher.Push(target, opts)
+ }
+ return ErrNotSupported
+}
+
+func (tw *timeoutWriter) Header() Header { return tw.h }
+
+func (tw *timeoutWriter) Write(p []byte) (int, error) {
+ tw.mu.Lock()
+ defer tw.mu.Unlock()
+ if tw.err != nil {
+ return 0, tw.err
+ }
+ if !tw.wroteHeader {
+ tw.writeHeaderLocked(StatusOK)
+ }
+ return tw.wbuf.Write(p)
+}
+
+func (tw *timeoutWriter) writeHeaderLocked(code int) {
+ checkWriteHeaderCode(code)
+
+ switch {
+ case tw.err != nil:
+ return
+ case tw.wroteHeader:
+ if tw.req != nil {
+ caller := relevantCaller()
+ logf(tw.req, "http: superfluous response.WriteHeader call from %s (%s:%d)", caller.Function, path.Base(caller.File), caller.Line)
+ }
+ default:
+ tw.wroteHeader = true
+ tw.code = code
+ }
+}
+
+func (tw *timeoutWriter) WriteHeader(code int) {
+ tw.mu.Lock()
+ defer tw.mu.Unlock()
+ tw.writeHeaderLocked(code)
+}
+
+// onceCloseListener wraps a net.Listener, protecting it from
+// multiple Close calls.
+type onceCloseListener struct {
+ net.Listener
+ once sync.Once
+ closeErr error
+}
+
+func (oc *onceCloseListener) Close() error {
+ oc.once.Do(oc.close)
+ return oc.closeErr
+}
+
+func (oc *onceCloseListener) close() { oc.closeErr = oc.Listener.Close() }
+
+// globalOptionsHandler responds to "OPTIONS *" requests.
+type globalOptionsHandler struct{}
+
+func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) {
+ w.Header().Set("Content-Length", "0")
+ if r.ContentLength != 0 {
+ // Read up to 4KB of OPTIONS body (as mentioned in the
+ // spec as being reserved for future use), but anything
+ // over that is considered a waste of server resources
+ // (or an attack) and we abort and close the connection,
+ // courtesy of MaxBytesReader's EOF behavior.
+ mb := MaxBytesReader(w, r.Body, 4<<10)
+ io.Copy(io.Discard, mb)
+ }
+}
+
+// initALPNRequest is an HTTP handler that initializes certain
+// uninitialized fields in its *Request. Such partially-initialized
+// Requests come from ALPN protocol handlers.
+type initALPNRequest struct {
+ ctx context.Context
+ c *tls.Conn
+ h serverHandler
+}
+
+// BaseContext is an exported but unadvertised http.Handler method
+// recognized by x/net/http2 to pass down a context; the TLSNextProto
+// API predates context support so we shoehorn through the only
+// interface we have available.
+func (h initALPNRequest) BaseContext() context.Context { return h.ctx }
+
+func (h initALPNRequest) ServeHTTP(rw ResponseWriter, req *Request) {
+ if req.TLS == nil {
+ req.TLS = &tls.ConnectionState{}
+ *req.TLS = h.c.ConnectionState()
+ }
+ if req.Body == nil {
+ req.Body = NoBody
+ }
+ if req.RemoteAddr == "" {
+ req.RemoteAddr = h.c.RemoteAddr().String()
+ }
+ h.h.ServeHTTP(rw, req)
+}
+
+// loggingConn is used for debugging.
+type loggingConn struct {
+ name string
+ net.Conn
+}
+
+var (
+ uniqNameMu sync.Mutex
+ uniqNameNext = make(map[string]int)
+)
+
+func newLoggingConn(baseName string, c net.Conn) net.Conn {
+ uniqNameMu.Lock()
+ defer uniqNameMu.Unlock()
+ uniqNameNext[baseName]++
+ return &loggingConn{
+ name: fmt.Sprintf("%s-%d", baseName, uniqNameNext[baseName]),
+ Conn: c,
+ }
+}
+
+func (c *loggingConn) Write(p []byte) (n int, err error) {
+ log.Printf("%s.Write(%d) = ....", c.name, len(p))
+ n, err = c.Conn.Write(p)
+ log.Printf("%s.Write(%d) = %d, %v", c.name, len(p), n, err)
+ return
+}
+
+func (c *loggingConn) Read(p []byte) (n int, err error) {
+ log.Printf("%s.Read(%d) = ....", c.name, len(p))
+ n, err = c.Conn.Read(p)
+ log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err)
+ return
+}
+
+func (c *loggingConn) Close() (err error) {
+ log.Printf("%s.Close() = ...", c.name)
+ err = c.Conn.Close()
+ log.Printf("%s.Close() = %v", c.name, err)
+ return
+}
+
+// checkConnErrorWriter writes to c.rwc and records any write errors to c.werr.
+// It only contains one field (and a pointer field at that), so it
+// fits in an interface value without an extra allocation.
+type checkConnErrorWriter struct {
+ c *conn
+}
+
+func (w checkConnErrorWriter) Write(p []byte) (n int, err error) {
+ n, err = w.c.rwc.Write(p)
+ if err != nil && w.c.werr == nil {
+ w.c.werr = err
+ w.c.cancelCtx()
+ }
+ return
+}
+
+func numLeadingCRorLF(v []byte) (n int) {
+ for _, b := range v {
+ if b == '\r' || b == '\n' {
+ n++
+ continue
+ }
+ break
+ }
+ return
+
+}
+
+func strSliceContains(ss []string, s string) bool {
+ for _, v := range ss {
+ if v == s {
+ return true
+ }
+ }
+ return false
+}
+
+// tlsRecordHeaderLooksLikeHTTP reports whether a TLS record header
+// looks like it might've been a misdirected plaintext HTTP request.
+func tlsRecordHeaderLooksLikeHTTP(hdr [5]byte) bool {
+ switch string(hdr[:]) {
+ case "GET /", "HEAD ", "POST ", "PUT /", "OPTIO":
+ return true
+ }
+ return false
+}
+
+// MaxBytesHandler returns a Handler that runs h with its ResponseWriter and Request.Body wrapped by a MaxBytesReader.
+func MaxBytesHandler(h Handler, n int64) Handler {
+ return HandlerFunc(func(w ResponseWriter, r *Request) {
+ r2 := *r
+ r2.Body = MaxBytesReader(w, r.Body, n)
+ h.ServeHTTP(w, &r2)
+ })
+}
diff --git a/contrib/go/_std_1.20/src/net/http/sniff.go b/contrib/go/_std_1.21/src/net/http/sniff.go
index ac18ab979d..ac18ab979d 100644
--- a/contrib/go/_std_1.20/src/net/http/sniff.go
+++ b/contrib/go/_std_1.21/src/net/http/sniff.go
diff --git a/contrib/go/_std_1.21/src/net/http/socks_bundle.go b/contrib/go/_std_1.21/src/net/http/socks_bundle.go
new file mode 100644
index 0000000000..776b03d941
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/socks_bundle.go
@@ -0,0 +1,473 @@
+// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.
+//go:generate bundle -o socks_bundle.go -prefix socks golang.org/x/net/internal/socks
+
+// Package socks provides a SOCKS version 5 client implementation.
+//
+// SOCKS protocol version 5 is defined in RFC 1928.
+// Username/Password authentication for SOCKS version 5 is defined in
+// RFC 1929.
+//
+
+package http
+
+import (
+ "context"
+ "errors"
+ "io"
+ "net"
+ "strconv"
+ "time"
+)
+
+var (
+ socksnoDeadline = time.Time{}
+ socksaLongTimeAgo = time.Unix(1, 0)
+)
+
+func (d *socksDialer) connect(ctx context.Context, c net.Conn, address string) (_ net.Addr, ctxErr error) {
+ host, port, err := sockssplitHostPort(address)
+ if err != nil {
+ return nil, err
+ }
+ if deadline, ok := ctx.Deadline(); ok && !deadline.IsZero() {
+ c.SetDeadline(deadline)
+ defer c.SetDeadline(socksnoDeadline)
+ }
+ if ctx != context.Background() {
+ errCh := make(chan error, 1)
+ done := make(chan struct{})
+ defer func() {
+ close(done)
+ if ctxErr == nil {
+ ctxErr = <-errCh
+ }
+ }()
+ go func() {
+ select {
+ case <-ctx.Done():
+ c.SetDeadline(socksaLongTimeAgo)
+ errCh <- ctx.Err()
+ case <-done:
+ errCh <- nil
+ }
+ }()
+ }
+
+ b := make([]byte, 0, 6+len(host)) // the size here is just an estimate
+ b = append(b, socksVersion5)
+ if len(d.AuthMethods) == 0 || d.Authenticate == nil {
+ b = append(b, 1, byte(socksAuthMethodNotRequired))
+ } else {
+ ams := d.AuthMethods
+ if len(ams) > 255 {
+ return nil, errors.New("too many authentication methods")
+ }
+ b = append(b, byte(len(ams)))
+ for _, am := range ams {
+ b = append(b, byte(am))
+ }
+ }
+ if _, ctxErr = c.Write(b); ctxErr != nil {
+ return
+ }
+
+ if _, ctxErr = io.ReadFull(c, b[:2]); ctxErr != nil {
+ return
+ }
+ if b[0] != socksVersion5 {
+ return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
+ }
+ am := socksAuthMethod(b[1])
+ if am == socksAuthMethodNoAcceptableMethods {
+ return nil, errors.New("no acceptable authentication methods")
+ }
+ if d.Authenticate != nil {
+ if ctxErr = d.Authenticate(ctx, c, am); ctxErr != nil {
+ return
+ }
+ }
+
+ b = b[:0]
+ b = append(b, socksVersion5, byte(d.cmd), 0)
+ if ip := net.ParseIP(host); ip != nil {
+ if ip4 := ip.To4(); ip4 != nil {
+ b = append(b, socksAddrTypeIPv4)
+ b = append(b, ip4...)
+ } else if ip6 := ip.To16(); ip6 != nil {
+ b = append(b, socksAddrTypeIPv6)
+ b = append(b, ip6...)
+ } else {
+ return nil, errors.New("unknown address type")
+ }
+ } else {
+ if len(host) > 255 {
+ return nil, errors.New("FQDN too long")
+ }
+ b = append(b, socksAddrTypeFQDN)
+ b = append(b, byte(len(host)))
+ b = append(b, host...)
+ }
+ b = append(b, byte(port>>8), byte(port))
+ if _, ctxErr = c.Write(b); ctxErr != nil {
+ return
+ }
+
+ if _, ctxErr = io.ReadFull(c, b[:4]); ctxErr != nil {
+ return
+ }
+ if b[0] != socksVersion5 {
+ return nil, errors.New("unexpected protocol version " + strconv.Itoa(int(b[0])))
+ }
+ if cmdErr := socksReply(b[1]); cmdErr != socksStatusSucceeded {
+ return nil, errors.New("unknown error " + cmdErr.String())
+ }
+ if b[2] != 0 {
+ return nil, errors.New("non-zero reserved field")
+ }
+ l := 2
+ var a socksAddr
+ switch b[3] {
+ case socksAddrTypeIPv4:
+ l += net.IPv4len
+ a.IP = make(net.IP, net.IPv4len)
+ case socksAddrTypeIPv6:
+ l += net.IPv6len
+ a.IP = make(net.IP, net.IPv6len)
+ case socksAddrTypeFQDN:
+ if _, err := io.ReadFull(c, b[:1]); err != nil {
+ return nil, err
+ }
+ l += int(b[0])
+ default:
+ return nil, errors.New("unknown address type " + strconv.Itoa(int(b[3])))
+ }
+ if cap(b) < l {
+ b = make([]byte, l)
+ } else {
+ b = b[:l]
+ }
+ if _, ctxErr = io.ReadFull(c, b); ctxErr != nil {
+ return
+ }
+ if a.IP != nil {
+ copy(a.IP, b)
+ } else {
+ a.Name = string(b[:len(b)-2])
+ }
+ a.Port = int(b[len(b)-2])<<8 | int(b[len(b)-1])
+ return &a, nil
+}
+
+func sockssplitHostPort(address string) (string, int, error) {
+ host, port, err := net.SplitHostPort(address)
+ if err != nil {
+ return "", 0, err
+ }
+ portnum, err := strconv.Atoi(port)
+ if err != nil {
+ return "", 0, err
+ }
+ if 1 > portnum || portnum > 0xffff {
+ return "", 0, errors.New("port number out of range " + port)
+ }
+ return host, portnum, nil
+}
+
+// A Command represents a SOCKS command.
+type socksCommand int
+
+func (cmd socksCommand) String() string {
+ switch cmd {
+ case socksCmdConnect:
+ return "socks connect"
+ case sockscmdBind:
+ return "socks bind"
+ default:
+ return "socks " + strconv.Itoa(int(cmd))
+ }
+}
+
+// An AuthMethod represents a SOCKS authentication method.
+type socksAuthMethod int
+
+// A Reply represents a SOCKS command reply code.
+type socksReply int
+
+func (code socksReply) String() string {
+ switch code {
+ case socksStatusSucceeded:
+ return "succeeded"
+ case 0x01:
+ return "general SOCKS server failure"
+ case 0x02:
+ return "connection not allowed by ruleset"
+ case 0x03:
+ return "network unreachable"
+ case 0x04:
+ return "host unreachable"
+ case 0x05:
+ return "connection refused"
+ case 0x06:
+ return "TTL expired"
+ case 0x07:
+ return "command not supported"
+ case 0x08:
+ return "address type not supported"
+ default:
+ return "unknown code: " + strconv.Itoa(int(code))
+ }
+}
+
+// Wire protocol constants.
+const (
+ socksVersion5 = 0x05
+
+ socksAddrTypeIPv4 = 0x01
+ socksAddrTypeFQDN = 0x03
+ socksAddrTypeIPv6 = 0x04
+
+ socksCmdConnect socksCommand = 0x01 // establishes an active-open forward proxy connection
+ sockscmdBind socksCommand = 0x02 // establishes a passive-open forward proxy connection
+
+ socksAuthMethodNotRequired socksAuthMethod = 0x00 // no authentication required
+ socksAuthMethodUsernamePassword socksAuthMethod = 0x02 // use username/password
+ socksAuthMethodNoAcceptableMethods socksAuthMethod = 0xff // no acceptable authentication methods
+
+ socksStatusSucceeded socksReply = 0x00
+)
+
+// An Addr represents a SOCKS-specific address.
+// Either Name or IP is used exclusively.
+type socksAddr struct {
+ Name string // fully-qualified domain name
+ IP net.IP
+ Port int
+}
+
+func (a *socksAddr) Network() string { return "socks" }
+
+func (a *socksAddr) String() string {
+ if a == nil {
+ return "<nil>"
+ }
+ port := strconv.Itoa(a.Port)
+ if a.IP == nil {
+ return net.JoinHostPort(a.Name, port)
+ }
+ return net.JoinHostPort(a.IP.String(), port)
+}
+
+// A Conn represents a forward proxy connection.
+type socksConn struct {
+ net.Conn
+
+ boundAddr net.Addr
+}
+
+// BoundAddr returns the address assigned by the proxy server for
+// connecting to the command target address from the proxy server.
+func (c *socksConn) BoundAddr() net.Addr {
+ if c == nil {
+ return nil
+ }
+ return c.boundAddr
+}
+
+// A Dialer holds SOCKS-specific options.
+type socksDialer struct {
+ cmd socksCommand // either CmdConnect or cmdBind
+ proxyNetwork string // network between a proxy server and a client
+ proxyAddress string // proxy server address
+
+ // ProxyDial specifies the optional dial function for
+ // establishing the transport connection.
+ ProxyDial func(context.Context, string, string) (net.Conn, error)
+
+ // AuthMethods specifies the list of request authentication
+ // methods.
+ // If empty, SOCKS client requests only AuthMethodNotRequired.
+ AuthMethods []socksAuthMethod
+
+ // Authenticate specifies the optional authentication
+ // function. It must be non-nil when AuthMethods is not empty.
+ // It must return an error when the authentication is failed.
+ Authenticate func(context.Context, io.ReadWriter, socksAuthMethod) error
+}
+
+// DialContext connects to the provided address on the provided
+// network.
+//
+// The returned error value may be a net.OpError. When the Op field of
+// net.OpError contains "socks", the Source field contains a proxy
+// server address and the Addr field contains a command target
+// address.
+//
+// See func Dial of the net package of standard library for a
+// description of the network and address parameters.
+func (d *socksDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
+ if err := d.validateTarget(network, address); err != nil {
+ proxy, dst, _ := d.pathAddrs(address)
+ return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
+ }
+ if ctx == nil {
+ proxy, dst, _ := d.pathAddrs(address)
+ return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
+ }
+ var err error
+ var c net.Conn
+ if d.ProxyDial != nil {
+ c, err = d.ProxyDial(ctx, d.proxyNetwork, d.proxyAddress)
+ } else {
+ var dd net.Dialer
+ c, err = dd.DialContext(ctx, d.proxyNetwork, d.proxyAddress)
+ }
+ if err != nil {
+ proxy, dst, _ := d.pathAddrs(address)
+ return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
+ }
+ a, err := d.connect(ctx, c, address)
+ if err != nil {
+ c.Close()
+ proxy, dst, _ := d.pathAddrs(address)
+ return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
+ }
+ return &socksConn{Conn: c, boundAddr: a}, nil
+}
+
+// DialWithConn initiates a connection from SOCKS server to the target
+// network and address using the connection c that is already
+// connected to the SOCKS server.
+//
+// It returns the connection's local address assigned by the SOCKS
+// server.
+func (d *socksDialer) DialWithConn(ctx context.Context, c net.Conn, network, address string) (net.Addr, error) {
+ if err := d.validateTarget(network, address); err != nil {
+ proxy, dst, _ := d.pathAddrs(address)
+ return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
+ }
+ if ctx == nil {
+ proxy, dst, _ := d.pathAddrs(address)
+ return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: errors.New("nil context")}
+ }
+ a, err := d.connect(ctx, c, address)
+ if err != nil {
+ proxy, dst, _ := d.pathAddrs(address)
+ return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
+ }
+ return a, nil
+}
+
+// Dial connects to the provided address on the provided network.
+//
+// Unlike DialContext, it returns a raw transport connection instead
+// of a forward proxy connection.
+//
+// Deprecated: Use DialContext or DialWithConn instead.
+func (d *socksDialer) Dial(network, address string) (net.Conn, error) {
+ if err := d.validateTarget(network, address); err != nil {
+ proxy, dst, _ := d.pathAddrs(address)
+ return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
+ }
+ var err error
+ var c net.Conn
+ if d.ProxyDial != nil {
+ c, err = d.ProxyDial(context.Background(), d.proxyNetwork, d.proxyAddress)
+ } else {
+ c, err = net.Dial(d.proxyNetwork, d.proxyAddress)
+ }
+ if err != nil {
+ proxy, dst, _ := d.pathAddrs(address)
+ return nil, &net.OpError{Op: d.cmd.String(), Net: network, Source: proxy, Addr: dst, Err: err}
+ }
+ if _, err := d.DialWithConn(context.Background(), c, network, address); err != nil {
+ c.Close()
+ return nil, err
+ }
+ return c, nil
+}
+
+func (d *socksDialer) validateTarget(network, address string) error {
+ switch network {
+ case "tcp", "tcp6", "tcp4":
+ default:
+ return errors.New("network not implemented")
+ }
+ switch d.cmd {
+ case socksCmdConnect, sockscmdBind:
+ default:
+ return errors.New("command not implemented")
+ }
+ return nil
+}
+
+func (d *socksDialer) pathAddrs(address string) (proxy, dst net.Addr, err error) {
+ for i, s := range []string{d.proxyAddress, address} {
+ host, port, err := sockssplitHostPort(s)
+ if err != nil {
+ return nil, nil, err
+ }
+ a := &socksAddr{Port: port}
+ a.IP = net.ParseIP(host)
+ if a.IP == nil {
+ a.Name = host
+ }
+ if i == 0 {
+ proxy = a
+ } else {
+ dst = a
+ }
+ }
+ return
+}
+
+// NewDialer returns a new Dialer that dials through the provided
+// proxy server's network and address.
+func socksNewDialer(network, address string) *socksDialer {
+ return &socksDialer{proxyNetwork: network, proxyAddress: address, cmd: socksCmdConnect}
+}
+
+const (
+ socksauthUsernamePasswordVersion = 0x01
+ socksauthStatusSucceeded = 0x00
+)
+
+// UsernamePassword are the credentials for the username/password
+// authentication method.
+type socksUsernamePassword struct {
+ Username string
+ Password string
+}
+
+// Authenticate authenticates a pair of username and password with the
+// proxy server.
+func (up *socksUsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter, auth socksAuthMethod) error {
+ switch auth {
+ case socksAuthMethodNotRequired:
+ return nil
+ case socksAuthMethodUsernamePassword:
+ if len(up.Username) == 0 || len(up.Username) > 255 || len(up.Password) > 255 {
+ return errors.New("invalid username/password")
+ }
+ b := []byte{socksauthUsernamePasswordVersion}
+ b = append(b, byte(len(up.Username)))
+ b = append(b, up.Username...)
+ b = append(b, byte(len(up.Password)))
+ b = append(b, up.Password...)
+ // TODO(mikio): handle IO deadlines and cancelation if
+ // necessary
+ if _, err := rw.Write(b); err != nil {
+ return err
+ }
+ if _, err := io.ReadFull(rw, b[:2]); err != nil {
+ return err
+ }
+ if b[0] != socksauthUsernamePasswordVersion {
+ return errors.New("invalid username/password version")
+ }
+ if b[1] != socksauthStatusSucceeded {
+ return errors.New("username/password authentication failed")
+ }
+ return nil
+ }
+ return errors.New("unsupported authentication method " + strconv.Itoa(int(auth)))
+}
diff --git a/contrib/go/_std_1.20/src/net/http/status.go b/contrib/go/_std_1.21/src/net/http/status.go
index cd90877ef0..cd90877ef0 100644
--- a/contrib/go/_std_1.20/src/net/http/status.go
+++ b/contrib/go/_std_1.21/src/net/http/status.go
diff --git a/contrib/go/_std_1.21/src/net/http/transfer.go b/contrib/go/_std_1.21/src/net/http/transfer.go
new file mode 100644
index 0000000000..d6f26a709c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/transfer.go
@@ -0,0 +1,1124 @@
+// Copyright 2009 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 http
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "net/http/httptrace"
+ "net/http/internal"
+ "net/http/internal/ascii"
+ "net/textproto"
+ "reflect"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ "golang.org/x/net/http/httpguts"
+)
+
+// ErrLineTooLong is returned when reading request or response bodies
+// with malformed chunked encoding.
+var ErrLineTooLong = internal.ErrLineTooLong
+
+type errorReader struct {
+ err error
+}
+
+func (r errorReader) Read(p []byte) (n int, err error) {
+ return 0, r.err
+}
+
+type byteReader struct {
+ b byte
+ done bool
+}
+
+func (br *byteReader) Read(p []byte) (n int, err error) {
+ if br.done {
+ return 0, io.EOF
+ }
+ if len(p) == 0 {
+ return 0, nil
+ }
+ br.done = true
+ p[0] = br.b
+ return 1, io.EOF
+}
+
+// transferWriter inspects the fields of a user-supplied Request or Response,
+// sanitizes them without changing the user object and provides methods for
+// writing the respective header, body and trailer in wire format.
+type transferWriter struct {
+ Method string
+ Body io.Reader
+ BodyCloser io.Closer
+ ResponseToHEAD bool
+ ContentLength int64 // -1 means unknown, 0 means exactly none
+ Close bool
+ TransferEncoding []string
+ Header Header
+ Trailer Header
+ IsResponse bool
+ bodyReadError error // any non-EOF error from reading Body
+
+ FlushHeaders bool // flush headers to network before body
+ ByteReadCh chan readResult // non-nil if probeRequestBody called
+}
+
+func newTransferWriter(r any) (t *transferWriter, err error) {
+ t = &transferWriter{}
+
+ // Extract relevant fields
+ atLeastHTTP11 := false
+ switch rr := r.(type) {
+ case *Request:
+ if rr.ContentLength != 0 && rr.Body == nil {
+ return nil, fmt.Errorf("http: Request.ContentLength=%d with nil Body", rr.ContentLength)
+ }
+ t.Method = valueOrDefault(rr.Method, "GET")
+ t.Close = rr.Close
+ t.TransferEncoding = rr.TransferEncoding
+ t.Header = rr.Header
+ t.Trailer = rr.Trailer
+ t.Body = rr.Body
+ t.BodyCloser = rr.Body
+ t.ContentLength = rr.outgoingLength()
+ if t.ContentLength < 0 && len(t.TransferEncoding) == 0 && t.shouldSendChunkedRequestBody() {
+ t.TransferEncoding = []string{"chunked"}
+ }
+ // If there's a body, conservatively flush the headers
+ // to any bufio.Writer we're writing to, just in case
+ // the server needs the headers early, before we copy
+ // the body and possibly block. We make an exception
+ // for the common standard library in-memory types,
+ // though, to avoid unnecessary TCP packets on the
+ // wire. (Issue 22088.)
+ if t.ContentLength != 0 && !isKnownInMemoryReader(t.Body) {
+ t.FlushHeaders = true
+ }
+
+ atLeastHTTP11 = true // Transport requests are always 1.1 or 2.0
+ case *Response:
+ t.IsResponse = true
+ if rr.Request != nil {
+ t.Method = rr.Request.Method
+ }
+ t.Body = rr.Body
+ t.BodyCloser = rr.Body
+ t.ContentLength = rr.ContentLength
+ t.Close = rr.Close
+ t.TransferEncoding = rr.TransferEncoding
+ t.Header = rr.Header
+ t.Trailer = rr.Trailer
+ atLeastHTTP11 = rr.ProtoAtLeast(1, 1)
+ t.ResponseToHEAD = noResponseBodyExpected(t.Method)
+ }
+
+ // Sanitize Body,ContentLength,TransferEncoding
+ if t.ResponseToHEAD {
+ t.Body = nil
+ if chunked(t.TransferEncoding) {
+ t.ContentLength = -1
+ }
+ } else {
+ if !atLeastHTTP11 || t.Body == nil {
+ t.TransferEncoding = nil
+ }
+ if chunked(t.TransferEncoding) {
+ t.ContentLength = -1
+ } else if t.Body == nil { // no chunking, no body
+ t.ContentLength = 0
+ }
+ }
+
+ // Sanitize Trailer
+ if !chunked(t.TransferEncoding) {
+ t.Trailer = nil
+ }
+
+ return t, nil
+}
+
+// shouldSendChunkedRequestBody reports whether we should try to send a
+// chunked request body to the server. In particular, the case we really
+// want to prevent is sending a GET or other typically-bodyless request to a
+// server with a chunked body when the body has zero bytes, since GETs with
+// bodies (while acceptable according to specs), even zero-byte chunked
+// bodies, are approximately never seen in the wild and confuse most
+// servers. See Issue 18257, as one example.
+//
+// The only reason we'd send such a request is if the user set the Body to a
+// non-nil value (say, io.NopCloser(bytes.NewReader(nil))) and didn't
+// set ContentLength, or NewRequest set it to -1 (unknown), so then we assume
+// there's bytes to send.
+//
+// This code tries to read a byte from the Request.Body in such cases to see
+// whether the body actually has content (super rare) or is actually just
+// a non-nil content-less ReadCloser (the more common case). In that more
+// common case, we act as if their Body were nil instead, and don't send
+// a body.
+func (t *transferWriter) shouldSendChunkedRequestBody() bool {
+ // Note that t.ContentLength is the corrected content length
+ // from rr.outgoingLength, so 0 actually means zero, not unknown.
+ if t.ContentLength >= 0 || t.Body == nil { // redundant checks; caller did them
+ return false
+ }
+ if t.Method == "CONNECT" {
+ return false
+ }
+ if requestMethodUsuallyLacksBody(t.Method) {
+ // Only probe the Request.Body for GET/HEAD/DELETE/etc
+ // requests, because it's only those types of requests
+ // that confuse servers.
+ t.probeRequestBody() // adjusts t.Body, t.ContentLength
+ return t.Body != nil
+ }
+ // For all other request types (PUT, POST, PATCH, or anything
+ // made-up we've never heard of), assume it's normal and the server
+ // can deal with a chunked request body. Maybe we'll adjust this
+ // later.
+ return true
+}
+
+// probeRequestBody reads a byte from t.Body to see whether it's empty
+// (returns io.EOF right away).
+//
+// But because we've had problems with this blocking users in the past
+// (issue 17480) when the body is a pipe (perhaps waiting on the response
+// headers before the pipe is fed data), we need to be careful and bound how
+// long we wait for it. This delay will only affect users if all the following
+// are true:
+// - the request body blocks
+// - the content length is not set (or set to -1)
+// - the method doesn't usually have a body (GET, HEAD, DELETE, ...)
+// - there is no transfer-encoding=chunked already set.
+//
+// In other words, this delay will not normally affect anybody, and there
+// are workarounds if it does.
+func (t *transferWriter) probeRequestBody() {
+ t.ByteReadCh = make(chan readResult, 1)
+ go func(body io.Reader) {
+ var buf [1]byte
+ var rres readResult
+ rres.n, rres.err = body.Read(buf[:])
+ if rres.n == 1 {
+ rres.b = buf[0]
+ }
+ t.ByteReadCh <- rres
+ close(t.ByteReadCh)
+ }(t.Body)
+ timer := time.NewTimer(200 * time.Millisecond)
+ select {
+ case rres := <-t.ByteReadCh:
+ timer.Stop()
+ if rres.n == 0 && rres.err == io.EOF {
+ // It was empty.
+ t.Body = nil
+ t.ContentLength = 0
+ } else if rres.n == 1 {
+ if rres.err != nil {
+ t.Body = io.MultiReader(&byteReader{b: rres.b}, errorReader{rres.err})
+ } else {
+ t.Body = io.MultiReader(&byteReader{b: rres.b}, t.Body)
+ }
+ } else if rres.err != nil {
+ t.Body = errorReader{rres.err}
+ }
+ case <-timer.C:
+ // Too slow. Don't wait. Read it later, and keep
+ // assuming that this is ContentLength == -1
+ // (unknown), which means we'll send a
+ // "Transfer-Encoding: chunked" header.
+ t.Body = io.MultiReader(finishAsyncByteRead{t}, t.Body)
+ // Request that Request.Write flush the headers to the
+ // network before writing the body, since our body may not
+ // become readable until it's seen the response headers.
+ t.FlushHeaders = true
+ }
+}
+
+func noResponseBodyExpected(requestMethod string) bool {
+ return requestMethod == "HEAD"
+}
+
+func (t *transferWriter) shouldSendContentLength() bool {
+ if chunked(t.TransferEncoding) {
+ return false
+ }
+ if t.ContentLength > 0 {
+ return true
+ }
+ if t.ContentLength < 0 {
+ return false
+ }
+ // Many servers expect a Content-Length for these methods
+ if t.Method == "POST" || t.Method == "PUT" || t.Method == "PATCH" {
+ return true
+ }
+ if t.ContentLength == 0 && isIdentity(t.TransferEncoding) {
+ if t.Method == "GET" || t.Method == "HEAD" {
+ return false
+ }
+ return true
+ }
+
+ return false
+}
+
+func (t *transferWriter) writeHeader(w io.Writer, trace *httptrace.ClientTrace) error {
+ if t.Close && !hasToken(t.Header.get("Connection"), "close") {
+ if _, err := io.WriteString(w, "Connection: close\r\n"); err != nil {
+ return err
+ }
+ if trace != nil && trace.WroteHeaderField != nil {
+ trace.WroteHeaderField("Connection", []string{"close"})
+ }
+ }
+
+ // Write Content-Length and/or Transfer-Encoding whose values are a
+ // function of the sanitized field triple (Body, ContentLength,
+ // TransferEncoding)
+ if t.shouldSendContentLength() {
+ if _, err := io.WriteString(w, "Content-Length: "); err != nil {
+ return err
+ }
+ if _, err := io.WriteString(w, strconv.FormatInt(t.ContentLength, 10)+"\r\n"); err != nil {
+ return err
+ }
+ if trace != nil && trace.WroteHeaderField != nil {
+ trace.WroteHeaderField("Content-Length", []string{strconv.FormatInt(t.ContentLength, 10)})
+ }
+ } else if chunked(t.TransferEncoding) {
+ if _, err := io.WriteString(w, "Transfer-Encoding: chunked\r\n"); err != nil {
+ return err
+ }
+ if trace != nil && trace.WroteHeaderField != nil {
+ trace.WroteHeaderField("Transfer-Encoding", []string{"chunked"})
+ }
+ }
+
+ // Write Trailer header
+ if t.Trailer != nil {
+ keys := make([]string, 0, len(t.Trailer))
+ for k := range t.Trailer {
+ k = CanonicalHeaderKey(k)
+ switch k {
+ case "Transfer-Encoding", "Trailer", "Content-Length":
+ return badStringError("invalid Trailer key", k)
+ }
+ keys = append(keys, k)
+ }
+ if len(keys) > 0 {
+ sort.Strings(keys)
+ // TODO: could do better allocation-wise here, but trailers are rare,
+ // so being lazy for now.
+ if _, err := io.WriteString(w, "Trailer: "+strings.Join(keys, ",")+"\r\n"); err != nil {
+ return err
+ }
+ if trace != nil && trace.WroteHeaderField != nil {
+ trace.WroteHeaderField("Trailer", keys)
+ }
+ }
+ }
+
+ return nil
+}
+
+// always closes t.BodyCloser
+func (t *transferWriter) writeBody(w io.Writer) (err error) {
+ var ncopy int64
+ closed := false
+ defer func() {
+ if closed || t.BodyCloser == nil {
+ return
+ }
+ if closeErr := t.BodyCloser.Close(); closeErr != nil && err == nil {
+ err = closeErr
+ }
+ }()
+
+ // Write body. We "unwrap" the body first if it was wrapped in a
+ // nopCloser or readTrackingBody. This is to ensure that we can take advantage of
+ // OS-level optimizations in the event that the body is an
+ // *os.File.
+ if t.Body != nil {
+ var body = t.unwrapBody()
+ if chunked(t.TransferEncoding) {
+ if bw, ok := w.(*bufio.Writer); ok && !t.IsResponse {
+ w = &internal.FlushAfterChunkWriter{Writer: bw}
+ }
+ cw := internal.NewChunkedWriter(w)
+ _, err = t.doBodyCopy(cw, body)
+ if err == nil {
+ err = cw.Close()
+ }
+ } else if t.ContentLength == -1 {
+ dst := w
+ if t.Method == "CONNECT" {
+ dst = bufioFlushWriter{dst}
+ }
+ ncopy, err = t.doBodyCopy(dst, body)
+ } else {
+ ncopy, err = t.doBodyCopy(w, io.LimitReader(body, t.ContentLength))
+ if err != nil {
+ return err
+ }
+ var nextra int64
+ nextra, err = t.doBodyCopy(io.Discard, body)
+ ncopy += nextra
+ }
+ if err != nil {
+ return err
+ }
+ }
+ if t.BodyCloser != nil {
+ closed = true
+ if err := t.BodyCloser.Close(); err != nil {
+ return err
+ }
+ }
+
+ if !t.ResponseToHEAD && t.ContentLength != -1 && t.ContentLength != ncopy {
+ return fmt.Errorf("http: ContentLength=%d with Body length %d",
+ t.ContentLength, ncopy)
+ }
+
+ if chunked(t.TransferEncoding) {
+ // Write Trailer header
+ if t.Trailer != nil {
+ if err := t.Trailer.Write(w); err != nil {
+ return err
+ }
+ }
+ // Last chunk, empty trailer
+ _, err = io.WriteString(w, "\r\n")
+ }
+ return err
+}
+
+// doBodyCopy wraps a copy operation, with any resulting error also
+// being saved in bodyReadError.
+//
+// This function is only intended for use in writeBody.
+func (t *transferWriter) doBodyCopy(dst io.Writer, src io.Reader) (n int64, err error) {
+ n, err = io.Copy(dst, src)
+ if err != nil && err != io.EOF {
+ t.bodyReadError = err
+ }
+ return
+}
+
+// unwrapBody unwraps the body's inner reader if it's a
+// nopCloser. This is to ensure that body writes sourced from local
+// files (*os.File types) are properly optimized.
+//
+// This function is only intended for use in writeBody.
+func (t *transferWriter) unwrapBody() io.Reader {
+ if r, ok := unwrapNopCloser(t.Body); ok {
+ return r
+ }
+ if r, ok := t.Body.(*readTrackingBody); ok {
+ r.didRead = true
+ return r.ReadCloser
+ }
+ return t.Body
+}
+
+type transferReader struct {
+ // Input
+ Header Header
+ StatusCode int
+ RequestMethod string
+ ProtoMajor int
+ ProtoMinor int
+ // Output
+ Body io.ReadCloser
+ ContentLength int64
+ Chunked bool
+ Close bool
+ Trailer Header
+}
+
+func (t *transferReader) protoAtLeast(m, n int) bool {
+ return t.ProtoMajor > m || (t.ProtoMajor == m && t.ProtoMinor >= n)
+}
+
+// bodyAllowedForStatus reports whether a given response status code
+// permits a body. See RFC 7230, section 3.3.
+func bodyAllowedForStatus(status int) bool {
+ switch {
+ case status >= 100 && status <= 199:
+ return false
+ case status == 204:
+ return false
+ case status == 304:
+ return false
+ }
+ return true
+}
+
+var (
+ suppressedHeaders304 = []string{"Content-Type", "Content-Length", "Transfer-Encoding"}
+ suppressedHeadersNoBody = []string{"Content-Length", "Transfer-Encoding"}
+ excludedHeadersNoBody = map[string]bool{"Content-Length": true, "Transfer-Encoding": true}
+)
+
+func suppressedHeaders(status int) []string {
+ switch {
+ case status == 304:
+ // RFC 7232 section 4.1
+ return suppressedHeaders304
+ case !bodyAllowedForStatus(status):
+ return suppressedHeadersNoBody
+ }
+ return nil
+}
+
+// msg is *Request or *Response.
+func readTransfer(msg any, r *bufio.Reader) (err error) {
+ t := &transferReader{RequestMethod: "GET"}
+
+ // Unify input
+ isResponse := false
+ switch rr := msg.(type) {
+ case *Response:
+ t.Header = rr.Header
+ t.StatusCode = rr.StatusCode
+ t.ProtoMajor = rr.ProtoMajor
+ t.ProtoMinor = rr.ProtoMinor
+ t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header, true)
+ isResponse = true
+ if rr.Request != nil {
+ t.RequestMethod = rr.Request.Method
+ }
+ case *Request:
+ t.Header = rr.Header
+ t.RequestMethod = rr.Method
+ t.ProtoMajor = rr.ProtoMajor
+ t.ProtoMinor = rr.ProtoMinor
+ // Transfer semantics for Requests are exactly like those for
+ // Responses with status code 200, responding to a GET method
+ t.StatusCode = 200
+ t.Close = rr.Close
+ default:
+ panic("unexpected type")
+ }
+
+ // Default to HTTP/1.1
+ if t.ProtoMajor == 0 && t.ProtoMinor == 0 {
+ t.ProtoMajor, t.ProtoMinor = 1, 1
+ }
+
+ // Transfer-Encoding: chunked, and overriding Content-Length.
+ if err := t.parseTransferEncoding(); err != nil {
+ return err
+ }
+
+ realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.Chunked)
+ if err != nil {
+ return err
+ }
+ if isResponse && t.RequestMethod == "HEAD" {
+ if n, err := parseContentLength(t.Header.get("Content-Length")); err != nil {
+ return err
+ } else {
+ t.ContentLength = n
+ }
+ } else {
+ t.ContentLength = realLength
+ }
+
+ // Trailer
+ t.Trailer, err = fixTrailer(t.Header, t.Chunked)
+ if err != nil {
+ return err
+ }
+
+ // If there is no Content-Length or chunked Transfer-Encoding on a *Response
+ // and the status is not 1xx, 204 or 304, then the body is unbounded.
+ // See RFC 7230, section 3.3.
+ switch msg.(type) {
+ case *Response:
+ if realLength == -1 && !t.Chunked && bodyAllowedForStatus(t.StatusCode) {
+ // Unbounded body.
+ t.Close = true
+ }
+ }
+
+ // Prepare body reader. ContentLength < 0 means chunked encoding
+ // or close connection when finished, since multipart is not supported yet
+ switch {
+ case t.Chunked:
+ if isResponse && (noResponseBodyExpected(t.RequestMethod) || !bodyAllowedForStatus(t.StatusCode)) {
+ t.Body = NoBody
+ } else {
+ t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close}
+ }
+ case realLength == 0:
+ t.Body = NoBody
+ case realLength > 0:
+ t.Body = &body{src: io.LimitReader(r, realLength), closing: t.Close}
+ default:
+ // realLength < 0, i.e. "Content-Length" not mentioned in header
+ if t.Close {
+ // Close semantics (i.e. HTTP/1.0)
+ t.Body = &body{src: r, closing: t.Close}
+ } else {
+ // Persistent connection (i.e. HTTP/1.1)
+ t.Body = NoBody
+ }
+ }
+
+ // Unify output
+ switch rr := msg.(type) {
+ case *Request:
+ rr.Body = t.Body
+ rr.ContentLength = t.ContentLength
+ if t.Chunked {
+ rr.TransferEncoding = []string{"chunked"}
+ }
+ rr.Close = t.Close
+ rr.Trailer = t.Trailer
+ case *Response:
+ rr.Body = t.Body
+ rr.ContentLength = t.ContentLength
+ if t.Chunked {
+ rr.TransferEncoding = []string{"chunked"}
+ }
+ rr.Close = t.Close
+ rr.Trailer = t.Trailer
+ }
+
+ return nil
+}
+
+// Checks whether chunked is part of the encodings stack.
+func chunked(te []string) bool { return len(te) > 0 && te[0] == "chunked" }
+
+// Checks whether the encoding is explicitly "identity".
+func isIdentity(te []string) bool { return len(te) == 1 && te[0] == "identity" }
+
+// unsupportedTEError reports unsupported transfer-encodings.
+type unsupportedTEError struct {
+ err string
+}
+
+func (uste *unsupportedTEError) Error() string {
+ return uste.err
+}
+
+// isUnsupportedTEError checks if the error is of type
+// unsupportedTEError. It is usually invoked with a non-nil err.
+func isUnsupportedTEError(err error) bool {
+ _, ok := err.(*unsupportedTEError)
+ return ok
+}
+
+// parseTransferEncoding sets t.Chunked based on the Transfer-Encoding header.
+func (t *transferReader) parseTransferEncoding() error {
+ raw, present := t.Header["Transfer-Encoding"]
+ if !present {
+ return nil
+ }
+ delete(t.Header, "Transfer-Encoding")
+
+ // Issue 12785; ignore Transfer-Encoding on HTTP/1.0 requests.
+ if !t.protoAtLeast(1, 1) {
+ return nil
+ }
+
+ // Like nginx, we only support a single Transfer-Encoding header field, and
+ // only if set to "chunked". This is one of the most security sensitive
+ // surfaces in HTTP/1.1 due to the risk of request smuggling, so we keep it
+ // strict and simple.
+ if len(raw) != 1 {
+ return &unsupportedTEError{fmt.Sprintf("too many transfer encodings: %q", raw)}
+ }
+ if !ascii.EqualFold(raw[0], "chunked") {
+ return &unsupportedTEError{fmt.Sprintf("unsupported transfer encoding: %q", raw[0])}
+ }
+
+ // RFC 7230 3.3.2 says "A sender MUST NOT send a Content-Length header field
+ // in any message that contains a Transfer-Encoding header field."
+ //
+ // but also: "If a message is received with both a Transfer-Encoding and a
+ // Content-Length header field, the Transfer-Encoding overrides the
+ // Content-Length. Such a message might indicate an attempt to perform
+ // request smuggling (Section 9.5) or response splitting (Section 9.4) and
+ // ought to be handled as an error. A sender MUST remove the received
+ // Content-Length field prior to forwarding such a message downstream."
+ //
+ // Reportedly, these appear in the wild.
+ delete(t.Header, "Content-Length")
+
+ t.Chunked = true
+ return nil
+}
+
+// Determine the expected body length, using RFC 7230 Section 3.3. This
+// function is not a method, because ultimately it should be shared by
+// ReadResponse and ReadRequest.
+func fixLength(isResponse bool, status int, requestMethod string, header Header, chunked bool) (int64, error) {
+ isRequest := !isResponse
+ contentLens := header["Content-Length"]
+
+ // Hardening against HTTP request smuggling
+ if len(contentLens) > 1 {
+ // Per RFC 7230 Section 3.3.2, prevent multiple
+ // Content-Length headers if they differ in value.
+ // If there are dups of the value, remove the dups.
+ // See Issue 16490.
+ first := textproto.TrimString(contentLens[0])
+ for _, ct := range contentLens[1:] {
+ if first != textproto.TrimString(ct) {
+ return 0, fmt.Errorf("http: message cannot contain multiple Content-Length headers; got %q", contentLens)
+ }
+ }
+
+ // deduplicate Content-Length
+ header.Del("Content-Length")
+ header.Add("Content-Length", first)
+
+ contentLens = header["Content-Length"]
+ }
+
+ // Logic based on response type or status
+ if isResponse && noResponseBodyExpected(requestMethod) {
+ return 0, nil
+ }
+ if status/100 == 1 {
+ return 0, nil
+ }
+ switch status {
+ case 204, 304:
+ return 0, nil
+ }
+
+ // Logic based on Transfer-Encoding
+ if chunked {
+ return -1, nil
+ }
+
+ // Logic based on Content-Length
+ var cl string
+ if len(contentLens) == 1 {
+ cl = textproto.TrimString(contentLens[0])
+ }
+ if cl != "" {
+ n, err := parseContentLength(cl)
+ if err != nil {
+ return -1, err
+ }
+ return n, nil
+ }
+ header.Del("Content-Length")
+
+ if isRequest {
+ // RFC 7230 neither explicitly permits nor forbids an
+ // entity-body on a GET request so we permit one if
+ // declared, but we default to 0 here (not -1 below)
+ // if there's no mention of a body.
+ // Likewise, all other request methods are assumed to have
+ // no body if neither Transfer-Encoding chunked nor a
+ // Content-Length are set.
+ return 0, nil
+ }
+
+ // Body-EOF logic based on other methods (like closing, or chunked coding)
+ return -1, nil
+}
+
+// Determine whether to hang up after sending a request and body, or
+// receiving a response and body
+// 'header' is the request headers.
+func shouldClose(major, minor int, header Header, removeCloseHeader bool) bool {
+ if major < 1 {
+ return true
+ }
+
+ conv := header["Connection"]
+ hasClose := httpguts.HeaderValuesContainsToken(conv, "close")
+ if major == 1 && minor == 0 {
+ return hasClose || !httpguts.HeaderValuesContainsToken(conv, "keep-alive")
+ }
+
+ if hasClose && removeCloseHeader {
+ header.Del("Connection")
+ }
+
+ return hasClose
+}
+
+// Parse the trailer header.
+func fixTrailer(header Header, chunked bool) (Header, error) {
+ vv, ok := header["Trailer"]
+ if !ok {
+ return nil, nil
+ }
+ if !chunked {
+ // Trailer and no chunking:
+ // this is an invalid use case for trailer header.
+ // Nevertheless, no error will be returned and we
+ // let users decide if this is a valid HTTP message.
+ // The Trailer header will be kept in Response.Header
+ // but not populate Response.Trailer.
+ // See issue #27197.
+ return nil, nil
+ }
+ header.Del("Trailer")
+
+ trailer := make(Header)
+ var err error
+ for _, v := range vv {
+ foreachHeaderElement(v, func(key string) {
+ key = CanonicalHeaderKey(key)
+ switch key {
+ case "Transfer-Encoding", "Trailer", "Content-Length":
+ if err == nil {
+ err = badStringError("bad trailer key", key)
+ return
+ }
+ }
+ trailer[key] = nil
+ })
+ }
+ if err != nil {
+ return nil, err
+ }
+ if len(trailer) == 0 {
+ return nil, nil
+ }
+ return trailer, nil
+}
+
+// body turns a Reader into a ReadCloser.
+// Close ensures that the body has been fully read
+// and then reads the trailer if necessary.
+type body struct {
+ src io.Reader
+ hdr any // non-nil (Response or Request) value means read trailer
+ r *bufio.Reader // underlying wire-format reader for the trailer
+ closing bool // is the connection to be closed after reading body?
+ doEarlyClose bool // whether Close should stop early
+
+ mu sync.Mutex // guards following, and calls to Read and Close
+ sawEOF bool
+ closed bool
+ earlyClose bool // Close called and we didn't read to the end of src
+ onHitEOF func() // if non-nil, func to call when EOF is Read
+}
+
+// ErrBodyReadAfterClose is returned when reading a Request or Response
+// Body after the body has been closed. This typically happens when the body is
+// read after an HTTP Handler calls WriteHeader or Write on its
+// ResponseWriter.
+var ErrBodyReadAfterClose = errors.New("http: invalid Read on closed Body")
+
+func (b *body) Read(p []byte) (n int, err error) {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+ if b.closed {
+ return 0, ErrBodyReadAfterClose
+ }
+ return b.readLocked(p)
+}
+
+// Must hold b.mu.
+func (b *body) readLocked(p []byte) (n int, err error) {
+ if b.sawEOF {
+ return 0, io.EOF
+ }
+ n, err = b.src.Read(p)
+
+ if err == io.EOF {
+ b.sawEOF = true
+ // Chunked case. Read the trailer.
+ if b.hdr != nil {
+ if e := b.readTrailer(); e != nil {
+ err = e
+ // Something went wrong in the trailer, we must not allow any
+ // further reads of any kind to succeed from body, nor any
+ // subsequent requests on the server connection. See
+ // golang.org/issue/12027
+ b.sawEOF = false
+ b.closed = true
+ }
+ b.hdr = nil
+ } else {
+ // If the server declared the Content-Length, our body is a LimitedReader
+ // and we need to check whether this EOF arrived early.
+ if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > 0 {
+ err = io.ErrUnexpectedEOF
+ }
+ }
+ }
+
+ // If we can return an EOF here along with the read data, do
+ // so. This is optional per the io.Reader contract, but doing
+ // so helps the HTTP transport code recycle its connection
+ // earlier (since it will see this EOF itself), even if the
+ // client doesn't do future reads or Close.
+ if err == nil && n > 0 {
+ if lr, ok := b.src.(*io.LimitedReader); ok && lr.N == 0 {
+ err = io.EOF
+ b.sawEOF = true
+ }
+ }
+
+ if b.sawEOF && b.onHitEOF != nil {
+ b.onHitEOF()
+ }
+
+ return n, err
+}
+
+var (
+ singleCRLF = []byte("\r\n")
+ doubleCRLF = []byte("\r\n\r\n")
+)
+
+func seeUpcomingDoubleCRLF(r *bufio.Reader) bool {
+ for peekSize := 4; ; peekSize++ {
+ // This loop stops when Peek returns an error,
+ // which it does when r's buffer has been filled.
+ buf, err := r.Peek(peekSize)
+ if bytes.HasSuffix(buf, doubleCRLF) {
+ return true
+ }
+ if err != nil {
+ break
+ }
+ }
+ return false
+}
+
+var errTrailerEOF = errors.New("http: unexpected EOF reading trailer")
+
+func (b *body) readTrailer() error {
+ // The common case, since nobody uses trailers.
+ buf, err := b.r.Peek(2)
+ if bytes.Equal(buf, singleCRLF) {
+ b.r.Discard(2)
+ return nil
+ }
+ if len(buf) < 2 {
+ return errTrailerEOF
+ }
+ if err != nil {
+ return err
+ }
+
+ // Make sure there's a header terminator coming up, to prevent
+ // a DoS with an unbounded size Trailer. It's not easy to
+ // slip in a LimitReader here, as textproto.NewReader requires
+ // a concrete *bufio.Reader. Also, we can't get all the way
+ // back up to our conn's LimitedReader that *might* be backing
+ // this bufio.Reader. Instead, a hack: we iteratively Peek up
+ // to the bufio.Reader's max size, looking for a double CRLF.
+ // This limits the trailer to the underlying buffer size, typically 4kB.
+ if !seeUpcomingDoubleCRLF(b.r) {
+ return errors.New("http: suspiciously long trailer after chunked body")
+ }
+
+ hdr, err := textproto.NewReader(b.r).ReadMIMEHeader()
+ if err != nil {
+ if err == io.EOF {
+ return errTrailerEOF
+ }
+ return err
+ }
+ switch rr := b.hdr.(type) {
+ case *Request:
+ mergeSetHeader(&rr.Trailer, Header(hdr))
+ case *Response:
+ mergeSetHeader(&rr.Trailer, Header(hdr))
+ }
+ return nil
+}
+
+func mergeSetHeader(dst *Header, src Header) {
+ if *dst == nil {
+ *dst = src
+ return
+ }
+ for k, vv := range src {
+ (*dst)[k] = vv
+ }
+}
+
+// unreadDataSizeLocked returns the number of bytes of unread input.
+// It returns -1 if unknown.
+// b.mu must be held.
+func (b *body) unreadDataSizeLocked() int64 {
+ if lr, ok := b.src.(*io.LimitedReader); ok {
+ return lr.N
+ }
+ return -1
+}
+
+func (b *body) Close() error {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+ if b.closed {
+ return nil
+ }
+ var err error
+ switch {
+ case b.sawEOF:
+ // Already saw EOF, so no need going to look for it.
+ case b.hdr == nil && b.closing:
+ // no trailer and closing the connection next.
+ // no point in reading to EOF.
+ case b.doEarlyClose:
+ // Read up to maxPostHandlerReadBytes bytes of the body, looking
+ // for EOF (and trailers), so we can re-use this connection.
+ if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > maxPostHandlerReadBytes {
+ // There was a declared Content-Length, and we have more bytes remaining
+ // than our maxPostHandlerReadBytes tolerance. So, give up.
+ b.earlyClose = true
+ } else {
+ var n int64
+ // Consume the body, or, which will also lead to us reading
+ // the trailer headers after the body, if present.
+ n, err = io.CopyN(io.Discard, bodyLocked{b}, maxPostHandlerReadBytes)
+ if err == io.EOF {
+ err = nil
+ }
+ if n == maxPostHandlerReadBytes {
+ b.earlyClose = true
+ }
+ }
+ default:
+ // Fully consume the body, which will also lead to us reading
+ // the trailer headers after the body, if present.
+ _, err = io.Copy(io.Discard, bodyLocked{b})
+ }
+ b.closed = true
+ return err
+}
+
+func (b *body) didEarlyClose() bool {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+ return b.earlyClose
+}
+
+// bodyRemains reports whether future Read calls might
+// yield data.
+func (b *body) bodyRemains() bool {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+ return !b.sawEOF
+}
+
+func (b *body) registerOnHitEOF(fn func()) {
+ b.mu.Lock()
+ defer b.mu.Unlock()
+ b.onHitEOF = fn
+}
+
+// bodyLocked is an io.Reader reading from a *body when its mutex is
+// already held.
+type bodyLocked struct {
+ b *body
+}
+
+func (bl bodyLocked) Read(p []byte) (n int, err error) {
+ if bl.b.closed {
+ return 0, ErrBodyReadAfterClose
+ }
+ return bl.b.readLocked(p)
+}
+
+// parseContentLength trims whitespace from s and returns -1 if no value
+// is set, or the value if it's >= 0.
+func parseContentLength(cl string) (int64, error) {
+ cl = textproto.TrimString(cl)
+ if cl == "" {
+ return -1, nil
+ }
+ n, err := strconv.ParseUint(cl, 10, 63)
+ if err != nil {
+ return 0, badStringError("bad Content-Length", cl)
+ }
+ return int64(n), nil
+
+}
+
+// finishAsyncByteRead finishes reading the 1-byte sniff
+// from the ContentLength==0, Body!=nil case.
+type finishAsyncByteRead struct {
+ tw *transferWriter
+}
+
+func (fr finishAsyncByteRead) Read(p []byte) (n int, err error) {
+ if len(p) == 0 {
+ return
+ }
+ rres := <-fr.tw.ByteReadCh
+ n, err = rres.n, rres.err
+ if n == 1 {
+ p[0] = rres.b
+ }
+ if err == nil {
+ err = io.EOF
+ }
+ return
+}
+
+var nopCloserType = reflect.TypeOf(io.NopCloser(nil))
+var nopCloserWriterToType = reflect.TypeOf(io.NopCloser(struct {
+ io.Reader
+ io.WriterTo
+}{}))
+
+// unwrapNopCloser return the underlying reader and true if r is a NopCloser
+// else it return false.
+func unwrapNopCloser(r io.Reader) (underlyingReader io.Reader, isNopCloser bool) {
+ switch reflect.TypeOf(r) {
+ case nopCloserType, nopCloserWriterToType:
+ return reflect.ValueOf(r).Field(0).Interface().(io.Reader), true
+ default:
+ return nil, false
+ }
+}
+
+// isKnownInMemoryReader reports whether r is a type known to not
+// block on Read. Its caller uses this as an optional optimization to
+// send fewer TCP packets.
+func isKnownInMemoryReader(r io.Reader) bool {
+ switch r.(type) {
+ case *bytes.Reader, *bytes.Buffer, *strings.Reader:
+ return true
+ }
+ if r, ok := unwrapNopCloser(r); ok {
+ return isKnownInMemoryReader(r)
+ }
+ if r, ok := r.(*readTrackingBody); ok {
+ return isKnownInMemoryReader(r.ReadCloser)
+ }
+ return false
+}
+
+// bufioFlushWriter is an io.Writer wrapper that flushes all writes
+// on its wrapped writer if it's a *bufio.Writer.
+type bufioFlushWriter struct{ w io.Writer }
+
+func (fw bufioFlushWriter) Write(p []byte) (n int, err error) {
+ n, err = fw.w.Write(p)
+ if bw, ok := fw.w.(*bufio.Writer); n > 0 && ok {
+ ferr := bw.Flush()
+ if ferr != nil && err == nil {
+ err = ferr
+ }
+ }
+ return
+}
diff --git a/contrib/go/_std_1.21/src/net/http/transport.go b/contrib/go/_std_1.21/src/net/http/transport.go
new file mode 100644
index 0000000000..c07352b018
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/transport.go
@@ -0,0 +1,2942 @@
+// Copyright 2011 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.
+
+// HTTP client implementation. See RFC 7230 through 7235.
+//
+// This is the low-level Transport implementation of RoundTripper.
+// The high-level interface is in client.go.
+
+package http
+
+import (
+ "bufio"
+ "compress/gzip"
+ "container/list"
+ "context"
+ "crypto/tls"
+ "errors"
+ "fmt"
+ "internal/godebug"
+ "io"
+ "log"
+ "net"
+ "net/http/httptrace"
+ "net/http/internal/ascii"
+ "net/textproto"
+ "net/url"
+ "reflect"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+
+ "golang.org/x/net/http/httpguts"
+ "golang.org/x/net/http/httpproxy"
+)
+
+// DefaultTransport is the default implementation of Transport and is
+// used by DefaultClient. It establishes network connections as needed
+// and caches them for reuse by subsequent calls. It uses HTTP proxies
+// as directed by the environment variables HTTP_PROXY, HTTPS_PROXY
+// and NO_PROXY (or the lowercase versions thereof).
+var DefaultTransport RoundTripper = &Transport{
+ Proxy: ProxyFromEnvironment,
+ DialContext: defaultTransportDialContext(&net.Dialer{
+ Timeout: 30 * time.Second,
+ KeepAlive: 30 * time.Second,
+ }),
+ ForceAttemptHTTP2: true,
+ MaxIdleConns: 100,
+ IdleConnTimeout: 90 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+}
+
+// DefaultMaxIdleConnsPerHost is the default value of Transport's
+// MaxIdleConnsPerHost.
+const DefaultMaxIdleConnsPerHost = 2
+
+// Transport is an implementation of RoundTripper that supports HTTP,
+// HTTPS, and HTTP proxies (for either HTTP or HTTPS with CONNECT).
+//
+// By default, Transport caches connections for future re-use.
+// This may leave many open connections when accessing many hosts.
+// This behavior can be managed using Transport's CloseIdleConnections method
+// and the MaxIdleConnsPerHost and DisableKeepAlives fields.
+//
+// Transports should be reused instead of created as needed.
+// Transports are safe for concurrent use by multiple goroutines.
+//
+// A Transport is a low-level primitive for making HTTP and HTTPS requests.
+// For high-level functionality, such as cookies and redirects, see Client.
+//
+// Transport uses HTTP/1.1 for HTTP URLs and either HTTP/1.1 or HTTP/2
+// for HTTPS URLs, depending on whether the server supports HTTP/2,
+// and how the Transport is configured. The DefaultTransport supports HTTP/2.
+// To explicitly enable HTTP/2 on a transport, use golang.org/x/net/http2
+// and call ConfigureTransport. See the package docs for more about HTTP/2.
+//
+// Responses with status codes in the 1xx range are either handled
+// automatically (100 expect-continue) or ignored. The one
+// exception is HTTP status code 101 (Switching Protocols), which is
+// considered a terminal status and returned by RoundTrip. To see the
+// ignored 1xx responses, use the httptrace trace package's
+// ClientTrace.Got1xxResponse.
+//
+// Transport only retries a request upon encountering a network error
+// if the connection has been already been used successfully and if the
+// request is idempotent and either has no body or has its Request.GetBody
+// defined. HTTP requests are considered idempotent if they have HTTP methods
+// GET, HEAD, OPTIONS, or TRACE; or if their Header map contains an
+// "Idempotency-Key" or "X-Idempotency-Key" entry. If the idempotency key
+// value is a zero-length slice, the request is treated as idempotent but the
+// header is not sent on the wire.
+type Transport struct {
+ idleMu sync.Mutex
+ closeIdle bool // user has requested to close all idle conns
+ idleConn map[connectMethodKey][]*persistConn // most recently used at end
+ idleConnWait map[connectMethodKey]wantConnQueue // waiting getConns
+ idleLRU connLRU
+
+ reqMu sync.Mutex
+ reqCanceler map[cancelKey]func(error)
+
+ altMu sync.Mutex // guards changing altProto only
+ altProto atomic.Value // of nil or map[string]RoundTripper, key is URI scheme
+
+ connsPerHostMu sync.Mutex
+ connsPerHost map[connectMethodKey]int
+ connsPerHostWait map[connectMethodKey]wantConnQueue // waiting getConns
+
+ // Proxy specifies a function to return a proxy for a given
+ // Request. If the function returns a non-nil error, the
+ // request is aborted with the provided error.
+ //
+ // The proxy type is determined by the URL scheme. "http",
+ // "https", and "socks5" are supported. If the scheme is empty,
+ // "http" is assumed.
+ //
+ // If Proxy is nil or returns a nil *URL, no proxy is used.
+ Proxy func(*Request) (*url.URL, error)
+
+ // OnProxyConnectResponse is called when the Transport gets an HTTP response from
+ // a proxy for a CONNECT request. It's called before the check for a 200 OK response.
+ // If it returns an error, the request fails with that error.
+ OnProxyConnectResponse func(ctx context.Context, proxyURL *url.URL, connectReq *Request, connectRes *Response) error
+
+ // DialContext specifies the dial function for creating unencrypted TCP connections.
+ // If DialContext is nil (and the deprecated Dial below is also nil),
+ // then the transport dials using package net.
+ //
+ // DialContext runs concurrently with calls to RoundTrip.
+ // A RoundTrip call that initiates a dial may end up using
+ // a connection dialed previously when the earlier connection
+ // becomes idle before the later DialContext completes.
+ DialContext func(ctx context.Context, network, addr string) (net.Conn, error)
+
+ // Dial specifies the dial function for creating unencrypted TCP connections.
+ //
+ // Dial runs concurrently with calls to RoundTrip.
+ // A RoundTrip call that initiates a dial may end up using
+ // a connection dialed previously when the earlier connection
+ // becomes idle before the later Dial completes.
+ //
+ // Deprecated: Use DialContext instead, which allows the transport
+ // to cancel dials as soon as they are no longer needed.
+ // If both are set, DialContext takes priority.
+ Dial func(network, addr string) (net.Conn, error)
+
+ // DialTLSContext specifies an optional dial function for creating
+ // TLS connections for non-proxied HTTPS requests.
+ //
+ // If DialTLSContext is nil (and the deprecated DialTLS below is also nil),
+ // DialContext and TLSClientConfig are used.
+ //
+ // If DialTLSContext is set, the Dial and DialContext hooks are not used for HTTPS
+ // requests and the TLSClientConfig and TLSHandshakeTimeout
+ // are ignored. The returned net.Conn is assumed to already be
+ // past the TLS handshake.
+ DialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)
+
+ // DialTLS specifies an optional dial function for creating
+ // TLS connections for non-proxied HTTPS requests.
+ //
+ // Deprecated: Use DialTLSContext instead, which allows the transport
+ // to cancel dials as soon as they are no longer needed.
+ // If both are set, DialTLSContext takes priority.
+ DialTLS func(network, addr string) (net.Conn, error)
+
+ // TLSClientConfig specifies the TLS configuration to use with
+ // tls.Client.
+ // If nil, the default configuration is used.
+ // If non-nil, HTTP/2 support may not be enabled by default.
+ TLSClientConfig *tls.Config
+
+ // TLSHandshakeTimeout specifies the maximum amount of time to
+ // wait for a TLS handshake. Zero means no timeout.
+ TLSHandshakeTimeout time.Duration
+
+ // DisableKeepAlives, if true, disables HTTP keep-alives and
+ // will only use the connection to the server for a single
+ // HTTP request.
+ //
+ // This is unrelated to the similarly named TCP keep-alives.
+ DisableKeepAlives bool
+
+ // DisableCompression, if true, prevents the Transport from
+ // requesting compression with an "Accept-Encoding: gzip"
+ // request header when the Request contains no existing
+ // Accept-Encoding value. If the Transport requests gzip on
+ // its own and gets a gzipped response, it's transparently
+ // decoded in the Response.Body. However, if the user
+ // explicitly requested gzip it is not automatically
+ // uncompressed.
+ DisableCompression bool
+
+ // MaxIdleConns controls the maximum number of idle (keep-alive)
+ // connections across all hosts. Zero means no limit.
+ MaxIdleConns int
+
+ // MaxIdleConnsPerHost, if non-zero, controls the maximum idle
+ // (keep-alive) connections to keep per-host. If zero,
+ // DefaultMaxIdleConnsPerHost is used.
+ MaxIdleConnsPerHost int
+
+ // MaxConnsPerHost optionally limits the total number of
+ // connections per host, including connections in the dialing,
+ // active, and idle states. On limit violation, dials will block.
+ //
+ // Zero means no limit.
+ MaxConnsPerHost int
+
+ // IdleConnTimeout is the maximum amount of time an idle
+ // (keep-alive) connection will remain idle before closing
+ // itself.
+ // Zero means no limit.
+ IdleConnTimeout time.Duration
+
+ // ResponseHeaderTimeout, if non-zero, specifies the amount of
+ // time to wait for a server's response headers after fully
+ // writing the request (including its body, if any). This
+ // time does not include the time to read the response body.
+ ResponseHeaderTimeout time.Duration
+
+ // ExpectContinueTimeout, if non-zero, specifies the amount of
+ // time to wait for a server's first response headers after fully
+ // writing the request headers if the request has an
+ // "Expect: 100-continue" header. Zero means no timeout and
+ // causes the body to be sent immediately, without
+ // waiting for the server to approve.
+ // This time does not include the time to send the request header.
+ ExpectContinueTimeout time.Duration
+
+ // TLSNextProto specifies how the Transport switches to an
+ // alternate protocol (such as HTTP/2) after a TLS ALPN
+ // protocol negotiation. If Transport dials an TLS connection
+ // with a non-empty protocol name and TLSNextProto contains a
+ // map entry for that key (such as "h2"), then the func is
+ // called with the request's authority (such as "example.com"
+ // or "example.com:1234") and the TLS connection. The function
+ // must return a RoundTripper that then handles the request.
+ // If TLSNextProto is not nil, HTTP/2 support is not enabled
+ // automatically.
+ TLSNextProto map[string]func(authority string, c *tls.Conn) RoundTripper
+
+ // ProxyConnectHeader optionally specifies headers to send to
+ // proxies during CONNECT requests.
+ // To set the header dynamically, see GetProxyConnectHeader.
+ ProxyConnectHeader Header
+
+ // GetProxyConnectHeader optionally specifies a func to return
+ // headers to send to proxyURL during a CONNECT request to the
+ // ip:port target.
+ // If it returns an error, the Transport's RoundTrip fails with
+ // that error. It can return (nil, nil) to not add headers.
+ // If GetProxyConnectHeader is non-nil, ProxyConnectHeader is
+ // ignored.
+ GetProxyConnectHeader func(ctx context.Context, proxyURL *url.URL, target string) (Header, error)
+
+ // MaxResponseHeaderBytes specifies a limit on how many
+ // response bytes are allowed in the server's response
+ // header.
+ //
+ // Zero means to use a default limit.
+ MaxResponseHeaderBytes int64
+
+ // WriteBufferSize specifies the size of the write buffer used
+ // when writing to the transport.
+ // If zero, a default (currently 4KB) is used.
+ WriteBufferSize int
+
+ // ReadBufferSize specifies the size of the read buffer used
+ // when reading from the transport.
+ // If zero, a default (currently 4KB) is used.
+ ReadBufferSize int
+
+ // nextProtoOnce guards initialization of TLSNextProto and
+ // h2transport (via onceSetNextProtoDefaults)
+ nextProtoOnce sync.Once
+ h2transport h2Transport // non-nil if http2 wired up
+ tlsNextProtoWasNil bool // whether TLSNextProto was nil when the Once fired
+
+ // ForceAttemptHTTP2 controls whether HTTP/2 is enabled when a non-zero
+ // Dial, DialTLS, or DialContext func or TLSClientConfig is provided.
+ // By default, use of any those fields conservatively disables HTTP/2.
+ // To use a custom dialer or TLS config and still attempt HTTP/2
+ // upgrades, set this to true.
+ ForceAttemptHTTP2 bool
+}
+
+// A cancelKey is the key of the reqCanceler map.
+// We wrap the *Request in this type since we want to use the original request,
+// not any transient one created by roundTrip.
+type cancelKey struct {
+ req *Request
+}
+
+func (t *Transport) writeBufferSize() int {
+ if t.WriteBufferSize > 0 {
+ return t.WriteBufferSize
+ }
+ return 4 << 10
+}
+
+func (t *Transport) readBufferSize() int {
+ if t.ReadBufferSize > 0 {
+ return t.ReadBufferSize
+ }
+ return 4 << 10
+}
+
+// Clone returns a deep copy of t's exported fields.
+func (t *Transport) Clone() *Transport {
+ t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
+ t2 := &Transport{
+ Proxy: t.Proxy,
+ OnProxyConnectResponse: t.OnProxyConnectResponse,
+ DialContext: t.DialContext,
+ Dial: t.Dial,
+ DialTLS: t.DialTLS,
+ DialTLSContext: t.DialTLSContext,
+ TLSHandshakeTimeout: t.TLSHandshakeTimeout,
+ DisableKeepAlives: t.DisableKeepAlives,
+ DisableCompression: t.DisableCompression,
+ MaxIdleConns: t.MaxIdleConns,
+ MaxIdleConnsPerHost: t.MaxIdleConnsPerHost,
+ MaxConnsPerHost: t.MaxConnsPerHost,
+ IdleConnTimeout: t.IdleConnTimeout,
+ ResponseHeaderTimeout: t.ResponseHeaderTimeout,
+ ExpectContinueTimeout: t.ExpectContinueTimeout,
+ ProxyConnectHeader: t.ProxyConnectHeader.Clone(),
+ GetProxyConnectHeader: t.GetProxyConnectHeader,
+ MaxResponseHeaderBytes: t.MaxResponseHeaderBytes,
+ ForceAttemptHTTP2: t.ForceAttemptHTTP2,
+ WriteBufferSize: t.WriteBufferSize,
+ ReadBufferSize: t.ReadBufferSize,
+ }
+ if t.TLSClientConfig != nil {
+ t2.TLSClientConfig = t.TLSClientConfig.Clone()
+ }
+ if !t.tlsNextProtoWasNil {
+ npm := map[string]func(authority string, c *tls.Conn) RoundTripper{}
+ for k, v := range t.TLSNextProto {
+ npm[k] = v
+ }
+ t2.TLSNextProto = npm
+ }
+ return t2
+}
+
+// h2Transport is the interface we expect to be able to call from
+// net/http against an *http2.Transport that's either bundled into
+// h2_bundle.go or supplied by the user via x/net/http2.
+//
+// We name it with the "h2" prefix to stay out of the "http2" prefix
+// namespace used by x/tools/cmd/bundle for h2_bundle.go.
+type h2Transport interface {
+ CloseIdleConnections()
+}
+
+func (t *Transport) hasCustomTLSDialer() bool {
+ return t.DialTLS != nil || t.DialTLSContext != nil
+}
+
+var http2client = godebug.New("http2client")
+
+// onceSetNextProtoDefaults initializes TLSNextProto.
+// It must be called via t.nextProtoOnce.Do.
+func (t *Transport) onceSetNextProtoDefaults() {
+ t.tlsNextProtoWasNil = (t.TLSNextProto == nil)
+ if http2client.Value() == "0" {
+ http2client.IncNonDefault()
+ return
+ }
+
+ // If they've already configured http2 with
+ // golang.org/x/net/http2 instead of the bundled copy, try to
+ // get at its http2.Transport value (via the "https"
+ // altproto map) so we can call CloseIdleConnections on it if
+ // requested. (Issue 22891)
+ altProto, _ := t.altProto.Load().(map[string]RoundTripper)
+ if rv := reflect.ValueOf(altProto["https"]); rv.IsValid() && rv.Type().Kind() == reflect.Struct && rv.Type().NumField() == 1 {
+ if v := rv.Field(0); v.CanInterface() {
+ if h2i, ok := v.Interface().(h2Transport); ok {
+ t.h2transport = h2i
+ return
+ }
+ }
+ }
+
+ if t.TLSNextProto != nil {
+ // This is the documented way to disable http2 on a
+ // Transport.
+ return
+ }
+ if !t.ForceAttemptHTTP2 && (t.TLSClientConfig != nil || t.Dial != nil || t.DialContext != nil || t.hasCustomTLSDialer()) {
+ // Be conservative and don't automatically enable
+ // http2 if they've specified a custom TLS config or
+ // custom dialers. Let them opt-in themselves via
+ // http2.ConfigureTransport so we don't surprise them
+ // by modifying their tls.Config. Issue 14275.
+ // However, if ForceAttemptHTTP2 is true, it overrides the above checks.
+ return
+ }
+ if omitBundledHTTP2 {
+ return
+ }
+ t2, err := http2configureTransports(t)
+ if err != nil {
+ log.Printf("Error enabling Transport HTTP/2 support: %v", err)
+ return
+ }
+ t.h2transport = t2
+
+ // Auto-configure the http2.Transport's MaxHeaderListSize from
+ // the http.Transport's MaxResponseHeaderBytes. They don't
+ // exactly mean the same thing, but they're close.
+ //
+ // TODO: also add this to x/net/http2.Configure Transport, behind
+ // a +build go1.7 build tag:
+ if limit1 := t.MaxResponseHeaderBytes; limit1 != 0 && t2.MaxHeaderListSize == 0 {
+ const h2max = 1<<32 - 1
+ if limit1 >= h2max {
+ t2.MaxHeaderListSize = h2max
+ } else {
+ t2.MaxHeaderListSize = uint32(limit1)
+ }
+ }
+}
+
+// ProxyFromEnvironment returns the URL of the proxy to use for a
+// given request, as indicated by the environment variables
+// HTTP_PROXY, HTTPS_PROXY and NO_PROXY (or the lowercase versions
+// thereof). Requests use the proxy from the environment variable
+// matching their scheme, unless excluded by NO_PROXY.
+//
+// The environment values may be either a complete URL or a
+// "host[:port]", in which case the "http" scheme is assumed.
+// The schemes "http", "https", and "socks5" are supported.
+// An error is returned if the value is a different form.
+//
+// A nil URL and nil error are returned if no proxy is defined in the
+// environment, or a proxy should not be used for the given request,
+// as defined by NO_PROXY.
+//
+// As a special case, if req.URL.Host is "localhost" (with or without
+// a port number), then a nil URL and nil error will be returned.
+func ProxyFromEnvironment(req *Request) (*url.URL, error) {
+ return envProxyFunc()(req.URL)
+}
+
+// ProxyURL returns a proxy function (for use in a Transport)
+// that always returns the same URL.
+func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error) {
+ return func(*Request) (*url.URL, error) {
+ return fixedURL, nil
+ }
+}
+
+// transportRequest is a wrapper around a *Request that adds
+// optional extra headers to write and stores any error to return
+// from roundTrip.
+type transportRequest struct {
+ *Request // original request, not to be mutated
+ extra Header // extra headers to write, or nil
+ trace *httptrace.ClientTrace // optional
+ cancelKey cancelKey
+
+ mu sync.Mutex // guards err
+ err error // first setError value for mapRoundTripError to consider
+}
+
+func (tr *transportRequest) extraHeaders() Header {
+ if tr.extra == nil {
+ tr.extra = make(Header)
+ }
+ return tr.extra
+}
+
+func (tr *transportRequest) setError(err error) {
+ tr.mu.Lock()
+ if tr.err == nil {
+ tr.err = err
+ }
+ tr.mu.Unlock()
+}
+
+// useRegisteredProtocol reports whether an alternate protocol (as registered
+// with Transport.RegisterProtocol) should be respected for this request.
+func (t *Transport) useRegisteredProtocol(req *Request) bool {
+ if req.URL.Scheme == "https" && req.requiresHTTP1() {
+ // If this request requires HTTP/1, don't use the
+ // "https" alternate protocol, which is used by the
+ // HTTP/2 code to take over requests if there's an
+ // existing cached HTTP/2 connection.
+ return false
+ }
+ return true
+}
+
+// alternateRoundTripper returns the alternate RoundTripper to use
+// for this request if the Request's URL scheme requires one,
+// or nil for the normal case of using the Transport.
+func (t *Transport) alternateRoundTripper(req *Request) RoundTripper {
+ if !t.useRegisteredProtocol(req) {
+ return nil
+ }
+ altProto, _ := t.altProto.Load().(map[string]RoundTripper)
+ return altProto[req.URL.Scheme]
+}
+
+// roundTrip implements a RoundTripper over HTTP.
+func (t *Transport) roundTrip(req *Request) (*Response, error) {
+ t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
+ ctx := req.Context()
+ trace := httptrace.ContextClientTrace(ctx)
+
+ if req.URL == nil {
+ req.closeBody()
+ return nil, errors.New("http: nil Request.URL")
+ }
+ if req.Header == nil {
+ req.closeBody()
+ return nil, errors.New("http: nil Request.Header")
+ }
+ scheme := req.URL.Scheme
+ isHTTP := scheme == "http" || scheme == "https"
+ if isHTTP {
+ for k, vv := range req.Header {
+ if !httpguts.ValidHeaderFieldName(k) {
+ req.closeBody()
+ return nil, fmt.Errorf("net/http: invalid header field name %q", k)
+ }
+ for _, v := range vv {
+ if !httpguts.ValidHeaderFieldValue(v) {
+ req.closeBody()
+ // Don't include the value in the error, because it may be sensitive.
+ return nil, fmt.Errorf("net/http: invalid header field value for %q", k)
+ }
+ }
+ }
+ }
+
+ origReq := req
+ cancelKey := cancelKey{origReq}
+ req = setupRewindBody(req)
+
+ if altRT := t.alternateRoundTripper(req); altRT != nil {
+ if resp, err := altRT.RoundTrip(req); err != ErrSkipAltProtocol {
+ return resp, err
+ }
+ var err error
+ req, err = rewindBody(req)
+ if err != nil {
+ return nil, err
+ }
+ }
+ if !isHTTP {
+ req.closeBody()
+ return nil, badStringError("unsupported protocol scheme", scheme)
+ }
+ if req.Method != "" && !validMethod(req.Method) {
+ req.closeBody()
+ return nil, fmt.Errorf("net/http: invalid method %q", req.Method)
+ }
+ if req.URL.Host == "" {
+ req.closeBody()
+ return nil, errors.New("http: no Host in request URL")
+ }
+
+ for {
+ select {
+ case <-ctx.Done():
+ req.closeBody()
+ return nil, ctx.Err()
+ default:
+ }
+
+ // treq gets modified by roundTrip, so we need to recreate for each retry.
+ treq := &transportRequest{Request: req, trace: trace, cancelKey: cancelKey}
+ cm, err := t.connectMethodForRequest(treq)
+ if err != nil {
+ req.closeBody()
+ return nil, err
+ }
+
+ // Get the cached or newly-created connection to either the
+ // host (for http or https), the http proxy, or the http proxy
+ // pre-CONNECTed to https server. In any case, we'll be ready
+ // to send it requests.
+ pconn, err := t.getConn(treq, cm)
+ if err != nil {
+ t.setReqCanceler(cancelKey, nil)
+ req.closeBody()
+ return nil, err
+ }
+
+ var resp *Response
+ if pconn.alt != nil {
+ // HTTP/2 path.
+ t.setReqCanceler(cancelKey, nil) // not cancelable with CancelRequest
+ resp, err = pconn.alt.RoundTrip(req)
+ } else {
+ resp, err = pconn.roundTrip(treq)
+ }
+ if err == nil {
+ resp.Request = origReq
+ return resp, nil
+ }
+
+ // Failed. Clean up and determine whether to retry.
+ if http2isNoCachedConnError(err) {
+ if t.removeIdleConn(pconn) {
+ t.decConnsPerHost(pconn.cacheKey)
+ }
+ } else if !pconn.shouldRetryRequest(req, err) {
+ // Issue 16465: return underlying net.Conn.Read error from peek,
+ // as we've historically done.
+ if e, ok := err.(nothingWrittenError); ok {
+ err = e.error
+ }
+ if e, ok := err.(transportReadFromServerError); ok {
+ err = e.err
+ }
+ if b, ok := req.Body.(*readTrackingBody); ok && !b.didClose {
+ // Issue 49621: Close the request body if pconn.roundTrip
+ // didn't do so already. This can happen if the pconn
+ // write loop exits without reading the write request.
+ req.closeBody()
+ }
+ return nil, err
+ }
+ testHookRoundTripRetried()
+
+ // Rewind the body if we're able to.
+ req, err = rewindBody(req)
+ if err != nil {
+ return nil, err
+ }
+ }
+}
+
+var errCannotRewind = errors.New("net/http: cannot rewind body after connection loss")
+
+type readTrackingBody struct {
+ io.ReadCloser
+ didRead bool
+ didClose bool
+}
+
+func (r *readTrackingBody) Read(data []byte) (int, error) {
+ r.didRead = true
+ return r.ReadCloser.Read(data)
+}
+
+func (r *readTrackingBody) Close() error {
+ r.didClose = true
+ return r.ReadCloser.Close()
+}
+
+// setupRewindBody returns a new request with a custom body wrapper
+// that can report whether the body needs rewinding.
+// This lets rewindBody avoid an error result when the request
+// does not have GetBody but the body hasn't been read at all yet.
+func setupRewindBody(req *Request) *Request {
+ if req.Body == nil || req.Body == NoBody {
+ return req
+ }
+ newReq := *req
+ newReq.Body = &readTrackingBody{ReadCloser: req.Body}
+ return &newReq
+}
+
+// rewindBody returns a new request with the body rewound.
+// It returns req unmodified if the body does not need rewinding.
+// rewindBody takes care of closing req.Body when appropriate
+// (in all cases except when rewindBody returns req unmodified).
+func rewindBody(req *Request) (rewound *Request, err error) {
+ if req.Body == nil || req.Body == NoBody || (!req.Body.(*readTrackingBody).didRead && !req.Body.(*readTrackingBody).didClose) {
+ return req, nil // nothing to rewind
+ }
+ if !req.Body.(*readTrackingBody).didClose {
+ req.closeBody()
+ }
+ if req.GetBody == nil {
+ return nil, errCannotRewind
+ }
+ body, err := req.GetBody()
+ if err != nil {
+ return nil, err
+ }
+ newReq := *req
+ newReq.Body = &readTrackingBody{ReadCloser: body}
+ return &newReq, nil
+}
+
+// shouldRetryRequest reports whether we should retry sending a failed
+// HTTP request on a new connection. The non-nil input error is the
+// error from roundTrip.
+func (pc *persistConn) shouldRetryRequest(req *Request, err error) bool {
+ if http2isNoCachedConnError(err) {
+ // Issue 16582: if the user started a bunch of
+ // requests at once, they can all pick the same conn
+ // and violate the server's max concurrent streams.
+ // Instead, match the HTTP/1 behavior for now and dial
+ // again to get a new TCP connection, rather than failing
+ // this request.
+ return true
+ }
+ if err == errMissingHost {
+ // User error.
+ return false
+ }
+ if !pc.isReused() {
+ // This was a fresh connection. There's no reason the server
+ // should've hung up on us.
+ //
+ // Also, if we retried now, we could loop forever
+ // creating new connections and retrying if the server
+ // is just hanging up on us because it doesn't like
+ // our request (as opposed to sending an error).
+ return false
+ }
+ if _, ok := err.(nothingWrittenError); ok {
+ // We never wrote anything, so it's safe to retry, if there's no body or we
+ // can "rewind" the body with GetBody.
+ return req.outgoingLength() == 0 || req.GetBody != nil
+ }
+ if !req.isReplayable() {
+ // Don't retry non-idempotent requests.
+ return false
+ }
+ if _, ok := err.(transportReadFromServerError); ok {
+ // We got some non-EOF net.Conn.Read failure reading
+ // the 1st response byte from the server.
+ return true
+ }
+ if err == errServerClosedIdle {
+ // The server replied with io.EOF while we were trying to
+ // read the response. Probably an unfortunately keep-alive
+ // timeout, just as the client was writing a request.
+ return true
+ }
+ return false // conservatively
+}
+
+// ErrSkipAltProtocol is a sentinel error value defined by Transport.RegisterProtocol.
+var ErrSkipAltProtocol = errors.New("net/http: skip alternate protocol")
+
+// RegisterProtocol registers a new protocol with scheme.
+// The Transport will pass requests using the given scheme to rt.
+// It is rt's responsibility to simulate HTTP request semantics.
+//
+// RegisterProtocol can be used by other packages to provide
+// implementations of protocol schemes like "ftp" or "file".
+//
+// If rt.RoundTrip returns ErrSkipAltProtocol, the Transport will
+// handle the RoundTrip itself for that one request, as if the
+// protocol were not registered.
+func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper) {
+ t.altMu.Lock()
+ defer t.altMu.Unlock()
+ oldMap, _ := t.altProto.Load().(map[string]RoundTripper)
+ if _, exists := oldMap[scheme]; exists {
+ panic("protocol " + scheme + " already registered")
+ }
+ newMap := make(map[string]RoundTripper)
+ for k, v := range oldMap {
+ newMap[k] = v
+ }
+ newMap[scheme] = rt
+ t.altProto.Store(newMap)
+}
+
+// CloseIdleConnections closes any connections which were previously
+// connected from previous requests but are now sitting idle in
+// a "keep-alive" state. It does not interrupt any connections currently
+// in use.
+func (t *Transport) CloseIdleConnections() {
+ t.nextProtoOnce.Do(t.onceSetNextProtoDefaults)
+ t.idleMu.Lock()
+ m := t.idleConn
+ t.idleConn = nil
+ t.closeIdle = true // close newly idle connections
+ t.idleLRU = connLRU{}
+ t.idleMu.Unlock()
+ for _, conns := range m {
+ for _, pconn := range conns {
+ pconn.close(errCloseIdleConns)
+ }
+ }
+ if t2 := t.h2transport; t2 != nil {
+ t2.CloseIdleConnections()
+ }
+}
+
+// CancelRequest cancels an in-flight request by closing its connection.
+// CancelRequest should only be called after RoundTrip has returned.
+//
+// Deprecated: Use Request.WithContext to create a request with a
+// cancelable context instead. CancelRequest cannot cancel HTTP/2
+// requests.
+func (t *Transport) CancelRequest(req *Request) {
+ t.cancelRequest(cancelKey{req}, errRequestCanceled)
+}
+
+// Cancel an in-flight request, recording the error value.
+// Returns whether the request was canceled.
+func (t *Transport) cancelRequest(key cancelKey, err error) bool {
+ // This function must not return until the cancel func has completed.
+ // See: https://golang.org/issue/34658
+ t.reqMu.Lock()
+ defer t.reqMu.Unlock()
+ cancel := t.reqCanceler[key]
+ delete(t.reqCanceler, key)
+ if cancel != nil {
+ cancel(err)
+ }
+
+ return cancel != nil
+}
+
+//
+// Private implementation past this point.
+//
+
+var (
+ envProxyOnce sync.Once
+ envProxyFuncValue func(*url.URL) (*url.URL, error)
+)
+
+// envProxyFunc returns a function that reads the
+// environment variable to determine the proxy address.
+func envProxyFunc() func(*url.URL) (*url.URL, error) {
+ envProxyOnce.Do(func() {
+ envProxyFuncValue = httpproxy.FromEnvironment().ProxyFunc()
+ })
+ return envProxyFuncValue
+}
+
+// resetProxyConfig is used by tests.
+func resetProxyConfig() {
+ envProxyOnce = sync.Once{}
+ envProxyFuncValue = nil
+}
+
+func (t *Transport) connectMethodForRequest(treq *transportRequest) (cm connectMethod, err error) {
+ cm.targetScheme = treq.URL.Scheme
+ cm.targetAddr = canonicalAddr(treq.URL)
+ if t.Proxy != nil {
+ cm.proxyURL, err = t.Proxy(treq.Request)
+ }
+ cm.onlyH1 = treq.requiresHTTP1()
+ return cm, err
+}
+
+// proxyAuth returns the Proxy-Authorization header to set
+// on requests, if applicable.
+func (cm *connectMethod) proxyAuth() string {
+ if cm.proxyURL == nil {
+ return ""
+ }
+ if u := cm.proxyURL.User; u != nil {
+ username := u.Username()
+ password, _ := u.Password()
+ return "Basic " + basicAuth(username, password)
+ }
+ return ""
+}
+
+// error values for debugging and testing, not seen by users.
+var (
+ errKeepAlivesDisabled = errors.New("http: putIdleConn: keep alives disabled")
+ errConnBroken = errors.New("http: putIdleConn: connection is in bad state")
+ errCloseIdle = errors.New("http: putIdleConn: CloseIdleConnections was called")
+ errTooManyIdle = errors.New("http: putIdleConn: too many idle connections")
+ errTooManyIdleHost = errors.New("http: putIdleConn: too many idle connections for host")
+ errCloseIdleConns = errors.New("http: CloseIdleConnections called")
+ errReadLoopExiting = errors.New("http: persistConn.readLoop exiting")
+ errIdleConnTimeout = errors.New("http: idle connection timeout")
+
+ // errServerClosedIdle is not seen by users for idempotent requests, but may be
+ // seen by a user if the server shuts down an idle connection and sends its FIN
+ // in flight with already-written POST body bytes from the client.
+ // See https://github.com/golang/go/issues/19943#issuecomment-355607646
+ errServerClosedIdle = errors.New("http: server closed idle connection")
+)
+
+// transportReadFromServerError is used by Transport.readLoop when the
+// 1 byte peek read fails and we're actually anticipating a response.
+// Usually this is just due to the inherent keep-alive shut down race,
+// where the server closed the connection at the same time the client
+// wrote. The underlying err field is usually io.EOF or some
+// ECONNRESET sort of thing which varies by platform. But it might be
+// the user's custom net.Conn.Read error too, so we carry it along for
+// them to return from Transport.RoundTrip.
+type transportReadFromServerError struct {
+ err error
+}
+
+func (e transportReadFromServerError) Unwrap() error { return e.err }
+
+func (e transportReadFromServerError) Error() string {
+ return fmt.Sprintf("net/http: Transport failed to read from server: %v", e.err)
+}
+
+func (t *Transport) putOrCloseIdleConn(pconn *persistConn) {
+ if err := t.tryPutIdleConn(pconn); err != nil {
+ pconn.close(err)
+ }
+}
+
+func (t *Transport) maxIdleConnsPerHost() int {
+ if v := t.MaxIdleConnsPerHost; v != 0 {
+ return v
+ }
+ return DefaultMaxIdleConnsPerHost
+}
+
+// tryPutIdleConn adds pconn to the list of idle persistent connections awaiting
+// a new request.
+// If pconn is no longer needed or not in a good state, tryPutIdleConn returns
+// an error explaining why it wasn't registered.
+// tryPutIdleConn does not close pconn. Use putOrCloseIdleConn instead for that.
+func (t *Transport) tryPutIdleConn(pconn *persistConn) error {
+ if t.DisableKeepAlives || t.MaxIdleConnsPerHost < 0 {
+ return errKeepAlivesDisabled
+ }
+ if pconn.isBroken() {
+ return errConnBroken
+ }
+ pconn.markReused()
+
+ t.idleMu.Lock()
+ defer t.idleMu.Unlock()
+
+ // HTTP/2 (pconn.alt != nil) connections do not come out of the idle list,
+ // because multiple goroutines can use them simultaneously.
+ // If this is an HTTP/2 connection being “returned,” we're done.
+ if pconn.alt != nil && t.idleLRU.m[pconn] != nil {
+ return nil
+ }
+
+ // Deliver pconn to goroutine waiting for idle connection, if any.
+ // (They may be actively dialing, but this conn is ready first.
+ // Chrome calls this socket late binding.
+ // See https://www.chromium.org/developers/design-documents/network-stack#TOC-Connection-Management.)
+ key := pconn.cacheKey
+ if q, ok := t.idleConnWait[key]; ok {
+ done := false
+ if pconn.alt == nil {
+ // HTTP/1.
+ // Loop over the waiting list until we find a w that isn't done already, and hand it pconn.
+ for q.len() > 0 {
+ w := q.popFront()
+ if w.tryDeliver(pconn, nil) {
+ done = true
+ break
+ }
+ }
+ } else {
+ // HTTP/2.
+ // Can hand the same pconn to everyone in the waiting list,
+ // and we still won't be done: we want to put it in the idle
+ // list unconditionally, for any future clients too.
+ for q.len() > 0 {
+ w := q.popFront()
+ w.tryDeliver(pconn, nil)
+ }
+ }
+ if q.len() == 0 {
+ delete(t.idleConnWait, key)
+ } else {
+ t.idleConnWait[key] = q
+ }
+ if done {
+ return nil
+ }
+ }
+
+ if t.closeIdle {
+ return errCloseIdle
+ }
+ if t.idleConn == nil {
+ t.idleConn = make(map[connectMethodKey][]*persistConn)
+ }
+ idles := t.idleConn[key]
+ if len(idles) >= t.maxIdleConnsPerHost() {
+ return errTooManyIdleHost
+ }
+ for _, exist := range idles {
+ if exist == pconn {
+ log.Fatalf("dup idle pconn %p in freelist", pconn)
+ }
+ }
+ t.idleConn[key] = append(idles, pconn)
+ t.idleLRU.add(pconn)
+ if t.MaxIdleConns != 0 && t.idleLRU.len() > t.MaxIdleConns {
+ oldest := t.idleLRU.removeOldest()
+ oldest.close(errTooManyIdle)
+ t.removeIdleConnLocked(oldest)
+ }
+
+ // Set idle timer, but only for HTTP/1 (pconn.alt == nil).
+ // The HTTP/2 implementation manages the idle timer itself
+ // (see idleConnTimeout in h2_bundle.go).
+ if t.IdleConnTimeout > 0 && pconn.alt == nil {
+ if pconn.idleTimer != nil {
+ pconn.idleTimer.Reset(t.IdleConnTimeout)
+ } else {
+ pconn.idleTimer = time.AfterFunc(t.IdleConnTimeout, pconn.closeConnIfStillIdle)
+ }
+ }
+ pconn.idleAt = time.Now()
+ return nil
+}
+
+// queueForIdleConn queues w to receive the next idle connection for w.cm.
+// As an optimization hint to the caller, queueForIdleConn reports whether
+// it successfully delivered an already-idle connection.
+func (t *Transport) queueForIdleConn(w *wantConn) (delivered bool) {
+ if t.DisableKeepAlives {
+ return false
+ }
+
+ t.idleMu.Lock()
+ defer t.idleMu.Unlock()
+
+ // Stop closing connections that become idle - we might want one.
+ // (That is, undo the effect of t.CloseIdleConnections.)
+ t.closeIdle = false
+
+ if w == nil {
+ // Happens in test hook.
+ return false
+ }
+
+ // If IdleConnTimeout is set, calculate the oldest
+ // persistConn.idleAt time we're willing to use a cached idle
+ // conn.
+ var oldTime time.Time
+ if t.IdleConnTimeout > 0 {
+ oldTime = time.Now().Add(-t.IdleConnTimeout)
+ }
+
+ // Look for most recently-used idle connection.
+ if list, ok := t.idleConn[w.key]; ok {
+ stop := false
+ delivered := false
+ for len(list) > 0 && !stop {
+ pconn := list[len(list)-1]
+
+ // See whether this connection has been idle too long, considering
+ // only the wall time (the Round(0)), in case this is a laptop or VM
+ // coming out of suspend with previously cached idle connections.
+ tooOld := !oldTime.IsZero() && pconn.idleAt.Round(0).Before(oldTime)
+ if tooOld {
+ // Async cleanup. Launch in its own goroutine (as if a
+ // time.AfterFunc called it); it acquires idleMu, which we're
+ // holding, and does a synchronous net.Conn.Close.
+ go pconn.closeConnIfStillIdle()
+ }
+ if pconn.isBroken() || tooOld {
+ // If either persistConn.readLoop has marked the connection
+ // broken, but Transport.removeIdleConn has not yet removed it
+ // from the idle list, or if this persistConn is too old (it was
+ // idle too long), then ignore it and look for another. In both
+ // cases it's already in the process of being closed.
+ list = list[:len(list)-1]
+ continue
+ }
+ delivered = w.tryDeliver(pconn, nil)
+ if delivered {
+ if pconn.alt != nil {
+ // HTTP/2: multiple clients can share pconn.
+ // Leave it in the list.
+ } else {
+ // HTTP/1: only one client can use pconn.
+ // Remove it from the list.
+ t.idleLRU.remove(pconn)
+ list = list[:len(list)-1]
+ }
+ }
+ stop = true
+ }
+ if len(list) > 0 {
+ t.idleConn[w.key] = list
+ } else {
+ delete(t.idleConn, w.key)
+ }
+ if stop {
+ return delivered
+ }
+ }
+
+ // Register to receive next connection that becomes idle.
+ if t.idleConnWait == nil {
+ t.idleConnWait = make(map[connectMethodKey]wantConnQueue)
+ }
+ q := t.idleConnWait[w.key]
+ q.cleanFront()
+ q.pushBack(w)
+ t.idleConnWait[w.key] = q
+ return false
+}
+
+// removeIdleConn marks pconn as dead.
+func (t *Transport) removeIdleConn(pconn *persistConn) bool {
+ t.idleMu.Lock()
+ defer t.idleMu.Unlock()
+ return t.removeIdleConnLocked(pconn)
+}
+
+// t.idleMu must be held.
+func (t *Transport) removeIdleConnLocked(pconn *persistConn) bool {
+ if pconn.idleTimer != nil {
+ pconn.idleTimer.Stop()
+ }
+ t.idleLRU.remove(pconn)
+ key := pconn.cacheKey
+ pconns := t.idleConn[key]
+ var removed bool
+ switch len(pconns) {
+ case 0:
+ // Nothing
+ case 1:
+ if pconns[0] == pconn {
+ delete(t.idleConn, key)
+ removed = true
+ }
+ default:
+ for i, v := range pconns {
+ if v != pconn {
+ continue
+ }
+ // Slide down, keeping most recently-used
+ // conns at the end.
+ copy(pconns[i:], pconns[i+1:])
+ t.idleConn[key] = pconns[:len(pconns)-1]
+ removed = true
+ break
+ }
+ }
+ return removed
+}
+
+func (t *Transport) setReqCanceler(key cancelKey, fn func(error)) {
+ t.reqMu.Lock()
+ defer t.reqMu.Unlock()
+ if t.reqCanceler == nil {
+ t.reqCanceler = make(map[cancelKey]func(error))
+ }
+ if fn != nil {
+ t.reqCanceler[key] = fn
+ } else {
+ delete(t.reqCanceler, key)
+ }
+}
+
+// replaceReqCanceler replaces an existing cancel function. If there is no cancel function
+// for the request, we don't set the function and return false.
+// Since CancelRequest will clear the canceler, we can use the return value to detect if
+// the request was canceled since the last setReqCancel call.
+func (t *Transport) replaceReqCanceler(key cancelKey, fn func(error)) bool {
+ t.reqMu.Lock()
+ defer t.reqMu.Unlock()
+ _, ok := t.reqCanceler[key]
+ if !ok {
+ return false
+ }
+ if fn != nil {
+ t.reqCanceler[key] = fn
+ } else {
+ delete(t.reqCanceler, key)
+ }
+ return true
+}
+
+var zeroDialer net.Dialer
+
+func (t *Transport) dial(ctx context.Context, network, addr string) (net.Conn, error) {
+ if t.DialContext != nil {
+ c, err := t.DialContext(ctx, network, addr)
+ if c == nil && err == nil {
+ err = errors.New("net/http: Transport.DialContext hook returned (nil, nil)")
+ }
+ return c, err
+ }
+ if t.Dial != nil {
+ c, err := t.Dial(network, addr)
+ if c == nil && err == nil {
+ err = errors.New("net/http: Transport.Dial hook returned (nil, nil)")
+ }
+ return c, err
+ }
+ return zeroDialer.DialContext(ctx, network, addr)
+}
+
+// A wantConn records state about a wanted connection
+// (that is, an active call to getConn).
+// The conn may be gotten by dialing or by finding an idle connection,
+// or a cancellation may make the conn no longer wanted.
+// These three options are racing against each other and use
+// wantConn to coordinate and agree about the winning outcome.
+type wantConn struct {
+ cm connectMethod
+ key connectMethodKey // cm.key()
+ ctx context.Context // context for dial
+ ready chan struct{} // closed when pc, err pair is delivered
+
+ // hooks for testing to know when dials are done
+ // beforeDial is called in the getConn goroutine when the dial is queued.
+ // afterDial is called when the dial is completed or canceled.
+ beforeDial func()
+ afterDial func()
+
+ mu sync.Mutex // protects pc, err, close(ready)
+ pc *persistConn
+ err error
+}
+
+// waiting reports whether w is still waiting for an answer (connection or error).
+func (w *wantConn) waiting() bool {
+ select {
+ case <-w.ready:
+ return false
+ default:
+ return true
+ }
+}
+
+// tryDeliver attempts to deliver pc, err to w and reports whether it succeeded.
+func (w *wantConn) tryDeliver(pc *persistConn, err error) bool {
+ w.mu.Lock()
+ defer w.mu.Unlock()
+
+ if w.pc != nil || w.err != nil {
+ return false
+ }
+
+ w.pc = pc
+ w.err = err
+ if w.pc == nil && w.err == nil {
+ panic("net/http: internal error: misuse of tryDeliver")
+ }
+ close(w.ready)
+ return true
+}
+
+// cancel marks w as no longer wanting a result (for example, due to cancellation).
+// If a connection has been delivered already, cancel returns it with t.putOrCloseIdleConn.
+func (w *wantConn) cancel(t *Transport, err error) {
+ w.mu.Lock()
+ if w.pc == nil && w.err == nil {
+ close(w.ready) // catch misbehavior in future delivery
+ }
+ pc := w.pc
+ w.pc = nil
+ w.err = err
+ w.mu.Unlock()
+
+ if pc != nil {
+ t.putOrCloseIdleConn(pc)
+ }
+}
+
+// A wantConnQueue is a queue of wantConns.
+type wantConnQueue struct {
+ // This is a queue, not a deque.
+ // It is split into two stages - head[headPos:] and tail.
+ // popFront is trivial (headPos++) on the first stage, and
+ // pushBack is trivial (append) on the second stage.
+ // If the first stage is empty, popFront can swap the
+ // first and second stages to remedy the situation.
+ //
+ // This two-stage split is analogous to the use of two lists
+ // in Okasaki's purely functional queue but without the
+ // overhead of reversing the list when swapping stages.
+ head []*wantConn
+ headPos int
+ tail []*wantConn
+}
+
+// len returns the number of items in the queue.
+func (q *wantConnQueue) len() int {
+ return len(q.head) - q.headPos + len(q.tail)
+}
+
+// pushBack adds w to the back of the queue.
+func (q *wantConnQueue) pushBack(w *wantConn) {
+ q.tail = append(q.tail, w)
+}
+
+// popFront removes and returns the wantConn at the front of the queue.
+func (q *wantConnQueue) popFront() *wantConn {
+ if q.headPos >= len(q.head) {
+ if len(q.tail) == 0 {
+ return nil
+ }
+ // Pick up tail as new head, clear tail.
+ q.head, q.headPos, q.tail = q.tail, 0, q.head[:0]
+ }
+ w := q.head[q.headPos]
+ q.head[q.headPos] = nil
+ q.headPos++
+ return w
+}
+
+// peekFront returns the wantConn at the front of the queue without removing it.
+func (q *wantConnQueue) peekFront() *wantConn {
+ if q.headPos < len(q.head) {
+ return q.head[q.headPos]
+ }
+ if len(q.tail) > 0 {
+ return q.tail[0]
+ }
+ return nil
+}
+
+// cleanFront pops any wantConns that are no longer waiting from the head of the
+// queue, reporting whether any were popped.
+func (q *wantConnQueue) cleanFront() (cleaned bool) {
+ for {
+ w := q.peekFront()
+ if w == nil || w.waiting() {
+ return cleaned
+ }
+ q.popFront()
+ cleaned = true
+ }
+}
+
+func (t *Transport) customDialTLS(ctx context.Context, network, addr string) (conn net.Conn, err error) {
+ if t.DialTLSContext != nil {
+ conn, err = t.DialTLSContext(ctx, network, addr)
+ } else {
+ conn, err = t.DialTLS(network, addr)
+ }
+ if conn == nil && err == nil {
+ err = errors.New("net/http: Transport.DialTLS or DialTLSContext returned (nil, nil)")
+ }
+ return
+}
+
+// getConn dials and creates a new persistConn to the target as
+// specified in the connectMethod. This includes doing a proxy CONNECT
+// and/or setting up TLS. If this doesn't return an error, the persistConn
+// is ready to write requests to.
+func (t *Transport) getConn(treq *transportRequest, cm connectMethod) (pc *persistConn, err error) {
+ req := treq.Request
+ trace := treq.trace
+ ctx := req.Context()
+ if trace != nil && trace.GetConn != nil {
+ trace.GetConn(cm.addr())
+ }
+
+ w := &wantConn{
+ cm: cm,
+ key: cm.key(),
+ ctx: ctx,
+ ready: make(chan struct{}, 1),
+ beforeDial: testHookPrePendingDial,
+ afterDial: testHookPostPendingDial,
+ }
+ defer func() {
+ if err != nil {
+ w.cancel(t, err)
+ }
+ }()
+
+ // Queue for idle connection.
+ if delivered := t.queueForIdleConn(w); delivered {
+ pc := w.pc
+ // Trace only for HTTP/1.
+ // HTTP/2 calls trace.GotConn itself.
+ if pc.alt == nil && trace != nil && trace.GotConn != nil {
+ trace.GotConn(pc.gotIdleConnTrace(pc.idleAt))
+ }
+ // set request canceler to some non-nil function so we
+ // can detect whether it was cleared between now and when
+ // we enter roundTrip
+ t.setReqCanceler(treq.cancelKey, func(error) {})
+ return pc, nil
+ }
+
+ cancelc := make(chan error, 1)
+ t.setReqCanceler(treq.cancelKey, func(err error) { cancelc <- err })
+
+ // Queue for permission to dial.
+ t.queueForDial(w)
+
+ // Wait for completion or cancellation.
+ select {
+ case <-w.ready:
+ // Trace success but only for HTTP/1.
+ // HTTP/2 calls trace.GotConn itself.
+ if w.pc != nil && w.pc.alt == nil && trace != nil && trace.GotConn != nil {
+ trace.GotConn(httptrace.GotConnInfo{Conn: w.pc.conn, Reused: w.pc.isReused()})
+ }
+ if w.err != nil {
+ // If the request has been canceled, that's probably
+ // what caused w.err; if so, prefer to return the
+ // cancellation error (see golang.org/issue/16049).
+ select {
+ case <-req.Cancel:
+ return nil, errRequestCanceledConn
+ case <-req.Context().Done():
+ return nil, req.Context().Err()
+ case err := <-cancelc:
+ if err == errRequestCanceled {
+ err = errRequestCanceledConn
+ }
+ return nil, err
+ default:
+ // return below
+ }
+ }
+ return w.pc, w.err
+ case <-req.Cancel:
+ return nil, errRequestCanceledConn
+ case <-req.Context().Done():
+ return nil, req.Context().Err()
+ case err := <-cancelc:
+ if err == errRequestCanceled {
+ err = errRequestCanceledConn
+ }
+ return nil, err
+ }
+}
+
+// queueForDial queues w to wait for permission to begin dialing.
+// Once w receives permission to dial, it will do so in a separate goroutine.
+func (t *Transport) queueForDial(w *wantConn) {
+ w.beforeDial()
+ if t.MaxConnsPerHost <= 0 {
+ go t.dialConnFor(w)
+ return
+ }
+
+ t.connsPerHostMu.Lock()
+ defer t.connsPerHostMu.Unlock()
+
+ if n := t.connsPerHost[w.key]; n < t.MaxConnsPerHost {
+ if t.connsPerHost == nil {
+ t.connsPerHost = make(map[connectMethodKey]int)
+ }
+ t.connsPerHost[w.key] = n + 1
+ go t.dialConnFor(w)
+ return
+ }
+
+ if t.connsPerHostWait == nil {
+ t.connsPerHostWait = make(map[connectMethodKey]wantConnQueue)
+ }
+ q := t.connsPerHostWait[w.key]
+ q.cleanFront()
+ q.pushBack(w)
+ t.connsPerHostWait[w.key] = q
+}
+
+// dialConnFor dials on behalf of w and delivers the result to w.
+// dialConnFor has received permission to dial w.cm and is counted in t.connCount[w.cm.key()].
+// If the dial is canceled or unsuccessful, dialConnFor decrements t.connCount[w.cm.key()].
+func (t *Transport) dialConnFor(w *wantConn) {
+ defer w.afterDial()
+
+ pc, err := t.dialConn(w.ctx, w.cm)
+ delivered := w.tryDeliver(pc, err)
+ if err == nil && (!delivered || pc.alt != nil) {
+ // pconn was not passed to w,
+ // or it is HTTP/2 and can be shared.
+ // Add to the idle connection pool.
+ t.putOrCloseIdleConn(pc)
+ }
+ if err != nil {
+ t.decConnsPerHost(w.key)
+ }
+}
+
+// decConnsPerHost decrements the per-host connection count for key,
+// which may in turn give a different waiting goroutine permission to dial.
+func (t *Transport) decConnsPerHost(key connectMethodKey) {
+ if t.MaxConnsPerHost <= 0 {
+ return
+ }
+
+ t.connsPerHostMu.Lock()
+ defer t.connsPerHostMu.Unlock()
+ n := t.connsPerHost[key]
+ if n == 0 {
+ // Shouldn't happen, but if it does, the counting is buggy and could
+ // easily lead to a silent deadlock, so report the problem loudly.
+ panic("net/http: internal error: connCount underflow")
+ }
+
+ // Can we hand this count to a goroutine still waiting to dial?
+ // (Some goroutines on the wait list may have timed out or
+ // gotten a connection another way. If they're all gone,
+ // we don't want to kick off any spurious dial operations.)
+ if q := t.connsPerHostWait[key]; q.len() > 0 {
+ done := false
+ for q.len() > 0 {
+ w := q.popFront()
+ if w.waiting() {
+ go t.dialConnFor(w)
+ done = true
+ break
+ }
+ }
+ if q.len() == 0 {
+ delete(t.connsPerHostWait, key)
+ } else {
+ // q is a value (like a slice), so we have to store
+ // the updated q back into the map.
+ t.connsPerHostWait[key] = q
+ }
+ if done {
+ return
+ }
+ }
+
+ // Otherwise, decrement the recorded count.
+ if n--; n == 0 {
+ delete(t.connsPerHost, key)
+ } else {
+ t.connsPerHost[key] = n
+ }
+}
+
+// Add TLS to a persistent connection, i.e. negotiate a TLS session. If pconn is already a TLS
+// tunnel, this function establishes a nested TLS session inside the encrypted channel.
+// The remote endpoint's name may be overridden by TLSClientConfig.ServerName.
+func (pconn *persistConn) addTLS(ctx context.Context, name string, trace *httptrace.ClientTrace) error {
+ // Initiate TLS and check remote host name against certificate.
+ cfg := cloneTLSConfig(pconn.t.TLSClientConfig)
+ if cfg.ServerName == "" {
+ cfg.ServerName = name
+ }
+ if pconn.cacheKey.onlyH1 {
+ cfg.NextProtos = nil
+ }
+ plainConn := pconn.conn
+ tlsConn := tls.Client(plainConn, cfg)
+ errc := make(chan error, 2)
+ var timer *time.Timer // for canceling TLS handshake
+ if d := pconn.t.TLSHandshakeTimeout; d != 0 {
+ timer = time.AfterFunc(d, func() {
+ errc <- tlsHandshakeTimeoutError{}
+ })
+ }
+ go func() {
+ if trace != nil && trace.TLSHandshakeStart != nil {
+ trace.TLSHandshakeStart()
+ }
+ err := tlsConn.HandshakeContext(ctx)
+ if timer != nil {
+ timer.Stop()
+ }
+ errc <- err
+ }()
+ if err := <-errc; err != nil {
+ plainConn.Close()
+ if trace != nil && trace.TLSHandshakeDone != nil {
+ trace.TLSHandshakeDone(tls.ConnectionState{}, err)
+ }
+ return err
+ }
+ cs := tlsConn.ConnectionState()
+ if trace != nil && trace.TLSHandshakeDone != nil {
+ trace.TLSHandshakeDone(cs, nil)
+ }
+ pconn.tlsState = &cs
+ pconn.conn = tlsConn
+ return nil
+}
+
+type erringRoundTripper interface {
+ RoundTripErr() error
+}
+
+func (t *Transport) dialConn(ctx context.Context, cm connectMethod) (pconn *persistConn, err error) {
+ pconn = &persistConn{
+ t: t,
+ cacheKey: cm.key(),
+ reqch: make(chan requestAndChan, 1),
+ writech: make(chan writeRequest, 1),
+ closech: make(chan struct{}),
+ writeErrCh: make(chan error, 1),
+ writeLoopDone: make(chan struct{}),
+ }
+ trace := httptrace.ContextClientTrace(ctx)
+ wrapErr := func(err error) error {
+ if cm.proxyURL != nil {
+ // Return a typed error, per Issue 16997
+ return &net.OpError{Op: "proxyconnect", Net: "tcp", Err: err}
+ }
+ return err
+ }
+ if cm.scheme() == "https" && t.hasCustomTLSDialer() {
+ var err error
+ pconn.conn, err = t.customDialTLS(ctx, "tcp", cm.addr())
+ if err != nil {
+ return nil, wrapErr(err)
+ }
+ if tc, ok := pconn.conn.(*tls.Conn); ok {
+ // Handshake here, in case DialTLS didn't. TLSNextProto below
+ // depends on it for knowing the connection state.
+ if trace != nil && trace.TLSHandshakeStart != nil {
+ trace.TLSHandshakeStart()
+ }
+ if err := tc.HandshakeContext(ctx); err != nil {
+ go pconn.conn.Close()
+ if trace != nil && trace.TLSHandshakeDone != nil {
+ trace.TLSHandshakeDone(tls.ConnectionState{}, err)
+ }
+ return nil, err
+ }
+ cs := tc.ConnectionState()
+ if trace != nil && trace.TLSHandshakeDone != nil {
+ trace.TLSHandshakeDone(cs, nil)
+ }
+ pconn.tlsState = &cs
+ }
+ } else {
+ conn, err := t.dial(ctx, "tcp", cm.addr())
+ if err != nil {
+ return nil, wrapErr(err)
+ }
+ pconn.conn = conn
+ if cm.scheme() == "https" {
+ var firstTLSHost string
+ if firstTLSHost, _, err = net.SplitHostPort(cm.addr()); err != nil {
+ return nil, wrapErr(err)
+ }
+ if err = pconn.addTLS(ctx, firstTLSHost, trace); err != nil {
+ return nil, wrapErr(err)
+ }
+ }
+ }
+
+ // Proxy setup.
+ switch {
+ case cm.proxyURL == nil:
+ // Do nothing. Not using a proxy.
+ case cm.proxyURL.Scheme == "socks5":
+ conn := pconn.conn
+ d := socksNewDialer("tcp", conn.RemoteAddr().String())
+ if u := cm.proxyURL.User; u != nil {
+ auth := &socksUsernamePassword{
+ Username: u.Username(),
+ }
+ auth.Password, _ = u.Password()
+ d.AuthMethods = []socksAuthMethod{
+ socksAuthMethodNotRequired,
+ socksAuthMethodUsernamePassword,
+ }
+ d.Authenticate = auth.Authenticate
+ }
+ if _, err := d.DialWithConn(ctx, conn, "tcp", cm.targetAddr); err != nil {
+ conn.Close()
+ return nil, err
+ }
+ case cm.targetScheme == "http":
+ pconn.isProxy = true
+ if pa := cm.proxyAuth(); pa != "" {
+ pconn.mutateHeaderFunc = func(h Header) {
+ h.Set("Proxy-Authorization", pa)
+ }
+ }
+ case cm.targetScheme == "https":
+ conn := pconn.conn
+ var hdr Header
+ if t.GetProxyConnectHeader != nil {
+ var err error
+ hdr, err = t.GetProxyConnectHeader(ctx, cm.proxyURL, cm.targetAddr)
+ if err != nil {
+ conn.Close()
+ return nil, err
+ }
+ } else {
+ hdr = t.ProxyConnectHeader
+ }
+ if hdr == nil {
+ hdr = make(Header)
+ }
+ if pa := cm.proxyAuth(); pa != "" {
+ hdr = hdr.Clone()
+ hdr.Set("Proxy-Authorization", pa)
+ }
+ connectReq := &Request{
+ Method: "CONNECT",
+ URL: &url.URL{Opaque: cm.targetAddr},
+ Host: cm.targetAddr,
+ Header: hdr,
+ }
+
+ // If there's no done channel (no deadline or cancellation
+ // from the caller possible), at least set some (long)
+ // timeout here. This will make sure we don't block forever
+ // and leak a goroutine if the connection stops replying
+ // after the TCP connect.
+ connectCtx := ctx
+ if ctx.Done() == nil {
+ newCtx, cancel := context.WithTimeout(ctx, 1*time.Minute)
+ defer cancel()
+ connectCtx = newCtx
+ }
+
+ didReadResponse := make(chan struct{}) // closed after CONNECT write+read is done or fails
+ var (
+ resp *Response
+ err error // write or read error
+ )
+ // Write the CONNECT request & read the response.
+ go func() {
+ defer close(didReadResponse)
+ err = connectReq.Write(conn)
+ if err != nil {
+ return
+ }
+ // Okay to use and discard buffered reader here, because
+ // TLS server will not speak until spoken to.
+ br := bufio.NewReader(conn)
+ resp, err = ReadResponse(br, connectReq)
+ }()
+ select {
+ case <-connectCtx.Done():
+ conn.Close()
+ <-didReadResponse
+ return nil, connectCtx.Err()
+ case <-didReadResponse:
+ // resp or err now set
+ }
+ if err != nil {
+ conn.Close()
+ return nil, err
+ }
+
+ if t.OnProxyConnectResponse != nil {
+ err = t.OnProxyConnectResponse(ctx, cm.proxyURL, connectReq, resp)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if resp.StatusCode != 200 {
+ _, text, ok := strings.Cut(resp.Status, " ")
+ conn.Close()
+ if !ok {
+ return nil, errors.New("unknown status code")
+ }
+ return nil, errors.New(text)
+ }
+ }
+
+ if cm.proxyURL != nil && cm.targetScheme == "https" {
+ if err := pconn.addTLS(ctx, cm.tlsHost(), trace); err != nil {
+ return nil, err
+ }
+ }
+
+ 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.(erringRoundTripper); ok {
+ // pconn.conn was closed by next (http2configureTransports.upgradeFn).
+ return nil, e.RoundTripErr()
+ }
+ return &persistConn{t: t, cacheKey: pconn.cacheKey, alt: alt}, nil
+ }
+ }
+
+ pconn.br = bufio.NewReaderSize(pconn, t.readBufferSize())
+ pconn.bw = bufio.NewWriterSize(persistConnWriter{pconn}, t.writeBufferSize())
+
+ go pconn.readLoop()
+ go pconn.writeLoop()
+ return pconn, nil
+}
+
+// persistConnWriter is the io.Writer written to by pc.bw.
+// It accumulates the number of bytes written to the underlying conn,
+// so the retry logic can determine whether any bytes made it across
+// the wire.
+// This is exactly 1 pointer field wide so it can go into an interface
+// without allocation.
+type persistConnWriter struct {
+ pc *persistConn
+}
+
+func (w persistConnWriter) Write(p []byte) (n int, err error) {
+ n, err = w.pc.conn.Write(p)
+ w.pc.nwrite += int64(n)
+ return
+}
+
+// ReadFrom exposes persistConnWriter's underlying Conn to io.Copy and if
+// the Conn implements io.ReaderFrom, it can take advantage of optimizations
+// such as sendfile.
+func (w persistConnWriter) ReadFrom(r io.Reader) (n int64, err error) {
+ n, err = io.Copy(w.pc.conn, r)
+ w.pc.nwrite += n
+ return
+}
+
+var _ io.ReaderFrom = (*persistConnWriter)(nil)
+
+// connectMethod is the map key (in its String form) for keeping persistent
+// TCP connections alive for subsequent HTTP requests.
+//
+// A connect method may be of the following types:
+//
+// connectMethod.key().String() Description
+// ------------------------------ -------------------------
+// |http|foo.com http directly to server, no proxy
+// |https|foo.com https directly to server, no proxy
+// |https,h1|foo.com https directly to server w/o HTTP/2, no proxy
+// http://proxy.com|https|foo.com http to proxy, then CONNECT to foo.com
+// http://proxy.com|http http to proxy, http to anywhere after that
+// socks5://proxy.com|http|foo.com socks5 to proxy, then http to foo.com
+// socks5://proxy.com|https|foo.com socks5 to proxy, then https to foo.com
+// https://proxy.com|https|foo.com https to proxy, then CONNECT to foo.com
+// https://proxy.com|http https to proxy, http to anywhere after that
+type connectMethod struct {
+ _ incomparable
+ proxyURL *url.URL // nil for no proxy, else full proxy URL
+ targetScheme string // "http" or "https"
+ // If proxyURL specifies an http or https proxy, and targetScheme is http (not https),
+ // then targetAddr is not included in the connect method key, because the socket can
+ // be reused for different targetAddr values.
+ targetAddr string
+ onlyH1 bool // whether to disable HTTP/2 and force HTTP/1
+}
+
+func (cm *connectMethod) key() connectMethodKey {
+ proxyStr := ""
+ targetAddr := cm.targetAddr
+ if cm.proxyURL != nil {
+ proxyStr = cm.proxyURL.String()
+ if (cm.proxyURL.Scheme == "http" || cm.proxyURL.Scheme == "https") && cm.targetScheme == "http" {
+ targetAddr = ""
+ }
+ }
+ return connectMethodKey{
+ proxy: proxyStr,
+ scheme: cm.targetScheme,
+ addr: targetAddr,
+ onlyH1: cm.onlyH1,
+ }
+}
+
+// scheme returns the first hop scheme: http, https, or socks5
+func (cm *connectMethod) scheme() string {
+ if cm.proxyURL != nil {
+ return cm.proxyURL.Scheme
+ }
+ return cm.targetScheme
+}
+
+// addr returns the first hop "host:port" to which we need to TCP connect.
+func (cm *connectMethod) addr() string {
+ if cm.proxyURL != nil {
+ return canonicalAddr(cm.proxyURL)
+ }
+ return cm.targetAddr
+}
+
+// tlsHost returns the host name to match against the peer's
+// TLS certificate.
+func (cm *connectMethod) tlsHost() string {
+ h := cm.targetAddr
+ if hasPort(h) {
+ h = h[:strings.LastIndex(h, ":")]
+ }
+ return h
+}
+
+// connectMethodKey is the map key version of connectMethod, with a
+// stringified proxy URL (or the empty string) instead of a pointer to
+// a URL.
+type connectMethodKey struct {
+ proxy, scheme, addr string
+ onlyH1 bool
+}
+
+func (k connectMethodKey) String() string {
+ // Only used by tests.
+ var h1 string
+ if k.onlyH1 {
+ h1 = ",h1"
+ }
+ return fmt.Sprintf("%s|%s%s|%s", k.proxy, k.scheme, h1, k.addr)
+}
+
+// persistConn wraps a connection, usually a persistent one
+// (but may be used for non-keep-alive requests as well)
+type persistConn struct {
+ // alt optionally specifies the TLS NextProto RoundTripper.
+ // This is used for HTTP/2 today and future protocols later.
+ // If it's non-nil, the rest of the fields are unused.
+ alt RoundTripper
+
+ t *Transport
+ cacheKey connectMethodKey
+ conn net.Conn
+ tlsState *tls.ConnectionState
+ br *bufio.Reader // from conn
+ bw *bufio.Writer // to conn
+ nwrite int64 // bytes written
+ reqch chan requestAndChan // written by roundTrip; read by readLoop
+ writech chan writeRequest // written by roundTrip; read by writeLoop
+ closech chan struct{} // closed when conn closed
+ isProxy bool
+ sawEOF bool // whether we've seen EOF from conn; owned by readLoop
+ readLimit int64 // bytes allowed to be read; owned by readLoop
+ // writeErrCh passes the request write error (usually nil)
+ // from the writeLoop goroutine to the readLoop which passes
+ // it off to the res.Body reader, which then uses it to decide
+ // whether or not a connection can be reused. Issue 7569.
+ writeErrCh chan error
+
+ writeLoopDone chan struct{} // closed when write loop ends
+
+ // Both guarded by Transport.idleMu:
+ idleAt time.Time // time it last become idle
+ idleTimer *time.Timer // holding an AfterFunc to close it
+
+ mu sync.Mutex // guards following fields
+ numExpectedResponses int
+ closed error // set non-nil when conn is closed, before closech is closed
+ canceledErr error // set non-nil if conn is canceled
+ broken bool // an error has happened on this connection; marked broken so it's not reused.
+ reused bool // whether conn has had successful request/response and is being reused.
+ // mutateHeaderFunc is an optional func to modify extra
+ // headers on each outbound request before it's written. (the
+ // original Request given to RoundTrip is not modified)
+ mutateHeaderFunc func(Header)
+}
+
+func (pc *persistConn) maxHeaderResponseSize() int64 {
+ if v := pc.t.MaxResponseHeaderBytes; v != 0 {
+ return v
+ }
+ return 10 << 20 // conservative default; same as http2
+}
+
+func (pc *persistConn) Read(p []byte) (n int, err error) {
+ if pc.readLimit <= 0 {
+ return 0, fmt.Errorf("read limit of %d bytes exhausted", pc.maxHeaderResponseSize())
+ }
+ if int64(len(p)) > pc.readLimit {
+ p = p[:pc.readLimit]
+ }
+ n, err = pc.conn.Read(p)
+ if err == io.EOF {
+ pc.sawEOF = true
+ }
+ pc.readLimit -= int64(n)
+ return
+}
+
+// isBroken reports whether this connection is in a known broken state.
+func (pc *persistConn) isBroken() bool {
+ pc.mu.Lock()
+ b := pc.closed != nil
+ pc.mu.Unlock()
+ return b
+}
+
+// canceled returns non-nil if the connection was closed due to
+// CancelRequest or due to context cancellation.
+func (pc *persistConn) canceled() error {
+ pc.mu.Lock()
+ defer pc.mu.Unlock()
+ return pc.canceledErr
+}
+
+// isReused reports whether this connection has been used before.
+func (pc *persistConn) isReused() bool {
+ pc.mu.Lock()
+ r := pc.reused
+ pc.mu.Unlock()
+ return r
+}
+
+func (pc *persistConn) gotIdleConnTrace(idleAt time.Time) (t httptrace.GotConnInfo) {
+ pc.mu.Lock()
+ defer pc.mu.Unlock()
+ t.Reused = pc.reused
+ t.Conn = pc.conn
+ t.WasIdle = true
+ if !idleAt.IsZero() {
+ t.IdleTime = time.Since(idleAt)
+ }
+ return
+}
+
+func (pc *persistConn) cancelRequest(err error) {
+ pc.mu.Lock()
+ defer pc.mu.Unlock()
+ pc.canceledErr = err
+ pc.closeLocked(errRequestCanceled)
+}
+
+// closeConnIfStillIdle closes the connection if it's still sitting idle.
+// This is what's called by the persistConn's idleTimer, and is run in its
+// own goroutine.
+func (pc *persistConn) closeConnIfStillIdle() {
+ t := pc.t
+ t.idleMu.Lock()
+ defer t.idleMu.Unlock()
+ if _, ok := t.idleLRU.m[pc]; !ok {
+ // Not idle.
+ return
+ }
+ t.removeIdleConnLocked(pc)
+ pc.close(errIdleConnTimeout)
+}
+
+// mapRoundTripError returns the appropriate error value for
+// persistConn.roundTrip.
+//
+// The provided err is the first error that (*persistConn).roundTrip
+// happened to receive from its select statement.
+//
+// The startBytesWritten value should be the value of pc.nwrite before the roundTrip
+// started writing the request.
+func (pc *persistConn) mapRoundTripError(req *transportRequest, startBytesWritten int64, err error) error {
+ if err == nil {
+ return nil
+ }
+
+ // Wait for the writeLoop goroutine to terminate to avoid data
+ // races on callers who mutate the request on failure.
+ //
+ // When resc in pc.roundTrip and hence rc.ch receives a responseAndError
+ // with a non-nil error it implies that the persistConn is either closed
+ // or closing. Waiting on pc.writeLoopDone is hence safe as all callers
+ // close closech which in turn ensures writeLoop returns.
+ <-pc.writeLoopDone
+
+ // If the request was canceled, that's better than network
+ // failures that were likely the result of tearing down the
+ // connection.
+ if cerr := pc.canceled(); cerr != nil {
+ return cerr
+ }
+
+ // See if an error was set explicitly.
+ req.mu.Lock()
+ reqErr := req.err
+ req.mu.Unlock()
+ if reqErr != nil {
+ return reqErr
+ }
+
+ if err == errServerClosedIdle {
+ // Don't decorate
+ return err
+ }
+
+ if _, ok := err.(transportReadFromServerError); ok {
+ if pc.nwrite == startBytesWritten {
+ return nothingWrittenError{err}
+ }
+ // Don't decorate
+ return err
+ }
+ if pc.isBroken() {
+ if pc.nwrite == startBytesWritten {
+ return nothingWrittenError{err}
+ }
+ return fmt.Errorf("net/http: HTTP/1.x transport connection broken: %w", err)
+ }
+ return err
+}
+
+// errCallerOwnsConn is an internal sentinel error used when we hand
+// off a writable response.Body to the caller. We use this to prevent
+// closing a net.Conn that is now owned by the caller.
+var errCallerOwnsConn = errors.New("read loop ending; caller owns writable underlying conn")
+
+func (pc *persistConn) readLoop() {
+ closeErr := errReadLoopExiting // default value, if not changed below
+ defer func() {
+ pc.close(closeErr)
+ pc.t.removeIdleConn(pc)
+ }()
+
+ tryPutIdleConn := func(trace *httptrace.ClientTrace) bool {
+ if err := pc.t.tryPutIdleConn(pc); err != nil {
+ closeErr = err
+ if trace != nil && trace.PutIdleConn != nil && err != errKeepAlivesDisabled {
+ trace.PutIdleConn(err)
+ }
+ return false
+ }
+ if trace != nil && trace.PutIdleConn != nil {
+ trace.PutIdleConn(nil)
+ }
+ return true
+ }
+
+ // eofc is used to block caller goroutines reading from Response.Body
+ // at EOF until this goroutines has (potentially) added the connection
+ // back to the idle pool.
+ eofc := make(chan struct{})
+ defer close(eofc) // unblock reader on errors
+
+ // Read this once, before loop starts. (to avoid races in tests)
+ testHookMu.Lock()
+ testHookReadLoopBeforeNextRead := testHookReadLoopBeforeNextRead
+ testHookMu.Unlock()
+
+ alive := true
+ for alive {
+ pc.readLimit = pc.maxHeaderResponseSize()
+ _, err := pc.br.Peek(1)
+
+ pc.mu.Lock()
+ if pc.numExpectedResponses == 0 {
+ pc.readLoopPeekFailLocked(err)
+ pc.mu.Unlock()
+ return
+ }
+ pc.mu.Unlock()
+
+ rc := <-pc.reqch
+ trace := httptrace.ContextClientTrace(rc.req.Context())
+
+ var resp *Response
+ if err == nil {
+ resp, err = pc.readResponse(rc, trace)
+ } else {
+ err = transportReadFromServerError{err}
+ closeErr = err
+ }
+
+ if err != nil {
+ if pc.readLimit <= 0 {
+ err = fmt.Errorf("net/http: server response headers exceeded %d bytes; aborted", pc.maxHeaderResponseSize())
+ }
+
+ select {
+ case rc.ch <- responseAndError{err: err}:
+ case <-rc.callerGone:
+ return
+ }
+ return
+ }
+ pc.readLimit = maxInt64 // effectively no limit for response bodies
+
+ pc.mu.Lock()
+ pc.numExpectedResponses--
+ pc.mu.Unlock()
+
+ bodyWritable := resp.bodyIsWritable()
+ hasBody := rc.req.Method != "HEAD" && resp.ContentLength != 0
+
+ if resp.Close || rc.req.Close || resp.StatusCode <= 199 || bodyWritable {
+ // Don't do keep-alive on error if either party requested a close
+ // or we get an unexpected informational (1xx) response.
+ // StatusCode 100 is already handled above.
+ alive = false
+ }
+
+ if !hasBody || bodyWritable {
+ 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.
+ alive = alive &&
+ !pc.sawEOF &&
+ pc.wroteRequest() &&
+ replaced && tryPutIdleConn(trace)
+
+ if bodyWritable {
+ closeErr = errCallerOwnsConn
+ }
+
+ select {
+ case rc.ch <- responseAndError{res: resp}:
+ case <-rc.callerGone:
+ return
+ }
+
+ // Now that they've read from the unbuffered channel, they're safely
+ // out of the select that also waits on this goroutine to die, so
+ // we're allowed to exit now if needed (if alive is false)
+ testHookReadLoopBeforeNextRead()
+ continue
+ }
+
+ waitForBodyRead := make(chan bool, 2)
+ body := &bodyEOFSignal{
+ body: resp.Body,
+ earlyCloseFn: func() error {
+ waitForBodyRead <- false
+ <-eofc // will be closed by deferred call at the end of the function
+ return nil
+
+ },
+ fn: func(err error) error {
+ isEOF := err == io.EOF
+ waitForBodyRead <- isEOF
+ if isEOF {
+ <-eofc // see comment above eofc declaration
+ } else if err != nil {
+ if cerr := pc.canceled(); cerr != nil {
+ return cerr
+ }
+ }
+ return err
+ },
+ }
+
+ resp.Body = body
+ if rc.addedGzip && ascii.EqualFold(resp.Header.Get("Content-Encoding"), "gzip") {
+ resp.Body = &gzipReader{body: body}
+ resp.Header.Del("Content-Encoding")
+ resp.Header.Del("Content-Length")
+ resp.ContentLength = -1
+ resp.Uncompressed = true
+ }
+
+ select {
+ case rc.ch <- responseAndError{res: resp}:
+ case <-rc.callerGone:
+ return
+ }
+
+ // Before looping back to the top of this function and peeking on
+ // the bufio.Reader, wait for the caller goroutine to finish
+ // reading the response body. (or for cancellation or death)
+ select {
+ case bodyEOF := <-waitForBodyRead:
+ replaced := pc.t.replaceReqCanceler(rc.cancelKey, nil) // before pc might return to idle pool
+ alive = alive &&
+ bodyEOF &&
+ !pc.sawEOF &&
+ pc.wroteRequest() &&
+ replaced && tryPutIdleConn(trace)
+ if bodyEOF {
+ eofc <- struct{}{}
+ }
+ case <-rc.req.Cancel:
+ alive = false
+ pc.t.CancelRequest(rc.req)
+ case <-rc.req.Context().Done():
+ alive = false
+ pc.t.cancelRequest(rc.cancelKey, rc.req.Context().Err())
+ case <-pc.closech:
+ alive = false
+ }
+
+ testHookReadLoopBeforeNextRead()
+ }
+}
+
+func (pc *persistConn) readLoopPeekFailLocked(peekErr error) {
+ if pc.closed != nil {
+ return
+ }
+ if n := pc.br.Buffered(); n > 0 {
+ buf, _ := pc.br.Peek(n)
+ if is408Message(buf) {
+ pc.closeLocked(errServerClosedIdle)
+ return
+ } else {
+ log.Printf("Unsolicited response received on idle HTTP channel starting with %q; err=%v", buf, peekErr)
+ }
+ }
+ if peekErr == io.EOF {
+ // common case.
+ pc.closeLocked(errServerClosedIdle)
+ } else {
+ pc.closeLocked(fmt.Errorf("readLoopPeekFailLocked: %w", peekErr))
+ }
+}
+
+// is408Message reports whether buf has the prefix of an
+// HTTP 408 Request Timeout response.
+// See golang.org/issue/32310.
+func is408Message(buf []byte) bool {
+ if len(buf) < len("HTTP/1.x 408") {
+ return false
+ }
+ if string(buf[:7]) != "HTTP/1." {
+ return false
+ }
+ return string(buf[8:12]) == " 408"
+}
+
+// readResponse reads an HTTP response (or two, in the case of "Expect:
+// 100-continue") from the server. It returns the final non-100 one.
+// trace is optional.
+func (pc *persistConn) readResponse(rc requestAndChan, trace *httptrace.ClientTrace) (resp *Response, err error) {
+ if trace != nil && trace.GotFirstResponseByte != nil {
+ if peek, err := pc.br.Peek(1); err == nil && len(peek) == 1 {
+ trace.GotFirstResponseByte()
+ }
+ }
+ num1xx := 0 // number of informational 1xx headers received
+ const max1xxResponses = 5 // arbitrary bound on number of informational responses
+
+ continueCh := rc.continueCh
+ for {
+ resp, err = ReadResponse(pc.br, rc.req)
+ if err != nil {
+ return
+ }
+ resCode := resp.StatusCode
+ if continueCh != nil {
+ if resCode == 100 {
+ if trace != nil && trace.Got100Continue != nil {
+ trace.Got100Continue()
+ }
+ continueCh <- struct{}{}
+ continueCh = nil
+ } else if resCode >= 200 {
+ close(continueCh)
+ continueCh = nil
+ }
+ }
+ is1xx := 100 <= resCode && resCode <= 199
+ // treat 101 as a terminal status, see issue 26161
+ is1xxNonTerminal := is1xx && resCode != StatusSwitchingProtocols
+ if is1xxNonTerminal {
+ num1xx++
+ if num1xx > max1xxResponses {
+ return nil, errors.New("net/http: too many 1xx informational responses")
+ }
+ pc.readLimit = pc.maxHeaderResponseSize() // reset the limit
+ if trace != nil && trace.Got1xxResponse != nil {
+ if err := trace.Got1xxResponse(resCode, textproto.MIMEHeader(resp.Header)); err != nil {
+ return nil, err
+ }
+ }
+ continue
+ }
+ break
+ }
+ if resp.isProtocolSwitch() {
+ resp.Body = newReadWriteCloserBody(pc.br, pc.conn)
+ }
+
+ resp.TLS = pc.tlsState
+ return
+}
+
+// waitForContinue returns the function to block until
+// any response, timeout or connection close. After any of them,
+// the function returns a bool which indicates if the body should be sent.
+func (pc *persistConn) waitForContinue(continueCh <-chan struct{}) func() bool {
+ if continueCh == nil {
+ return nil
+ }
+ return func() bool {
+ timer := time.NewTimer(pc.t.ExpectContinueTimeout)
+ defer timer.Stop()
+
+ select {
+ case _, ok := <-continueCh:
+ return ok
+ case <-timer.C:
+ return true
+ case <-pc.closech:
+ return false
+ }
+ }
+}
+
+func newReadWriteCloserBody(br *bufio.Reader, rwc io.ReadWriteCloser) io.ReadWriteCloser {
+ body := &readWriteCloserBody{ReadWriteCloser: rwc}
+ if br.Buffered() != 0 {
+ body.br = br
+ }
+ return body
+}
+
+// readWriteCloserBody is the Response.Body type used when we want to
+// give users write access to the Body through the underlying
+// connection (TCP, unless using custom dialers). This is then
+// the concrete type for a Response.Body on the 101 Switching
+// Protocols response, as used by WebSockets, h2c, etc.
+type readWriteCloserBody struct {
+ _ incomparable
+ br *bufio.Reader // used until empty
+ io.ReadWriteCloser
+}
+
+func (b *readWriteCloserBody) Read(p []byte) (n int, err error) {
+ if b.br != nil {
+ if n := b.br.Buffered(); len(p) > n {
+ p = p[:n]
+ }
+ n, err = b.br.Read(p)
+ if b.br.Buffered() == 0 {
+ b.br = nil
+ }
+ return n, err
+ }
+ return b.ReadWriteCloser.Read(p)
+}
+
+// nothingWrittenError wraps a write errors which ended up writing zero bytes.
+type nothingWrittenError struct {
+ error
+}
+
+func (nwe nothingWrittenError) Unwrap() error {
+ return nwe.error
+}
+
+func (pc *persistConn) writeLoop() {
+ defer close(pc.writeLoopDone)
+ for {
+ select {
+ case wr := <-pc.writech:
+ startBytesWritten := pc.nwrite
+ err := wr.req.Request.write(pc.bw, pc.isProxy, wr.req.extra, pc.waitForContinue(wr.continueCh))
+ if bre, ok := err.(requestBodyReadError); ok {
+ err = bre.error
+ // Errors reading from the user's
+ // Request.Body are high priority.
+ // Set it here before sending on the
+ // channels below or calling
+ // pc.close() which tears down
+ // connections and causes other
+ // errors.
+ wr.req.setError(err)
+ }
+ if err == nil {
+ err = pc.bw.Flush()
+ }
+ if err != nil {
+ if pc.nwrite == startBytesWritten {
+ err = nothingWrittenError{err}
+ }
+ }
+ pc.writeErrCh <- err // to the body reader, which might recycle us
+ wr.ch <- err // to the roundTrip function
+ if err != nil {
+ pc.close(err)
+ return
+ }
+ case <-pc.closech:
+ return
+ }
+ }
+}
+
+// maxWriteWaitBeforeConnReuse is how long the a Transport RoundTrip
+// will wait to see the Request's Body.Write result after getting a
+// response from the server. See comments in (*persistConn).wroteRequest.
+//
+// In tests, we set this to a large value to avoid flakiness from inconsistent
+// recycling of connections.
+var maxWriteWaitBeforeConnReuse = 50 * time.Millisecond
+
+// wroteRequest is a check before recycling a connection that the previous write
+// (from writeLoop above) happened and was successful.
+func (pc *persistConn) wroteRequest() bool {
+ select {
+ case err := <-pc.writeErrCh:
+ // Common case: the write happened well before the response, so
+ // avoid creating a timer.
+ return err == nil
+ default:
+ // Rare case: the request was written in writeLoop above but
+ // before it could send to pc.writeErrCh, the reader read it
+ // all, processed it, and called us here. In this case, give the
+ // write goroutine a bit of time to finish its send.
+ //
+ // Less rare case: We also get here in the legitimate case of
+ // Issue 7569, where the writer is still writing (or stalled),
+ // but the server has already replied. In this case, we don't
+ // want to wait too long, and we want to return false so this
+ // connection isn't re-used.
+ t := time.NewTimer(maxWriteWaitBeforeConnReuse)
+ defer t.Stop()
+ select {
+ case err := <-pc.writeErrCh:
+ return err == nil
+ case <-t.C:
+ return false
+ }
+ }
+}
+
+// responseAndError is how the goroutine reading from an HTTP/1 server
+// communicates with the goroutine doing the RoundTrip.
+type responseAndError struct {
+ _ incomparable
+ res *Response // else use this response (see res method)
+ err error
+}
+
+type requestAndChan struct {
+ _ incomparable
+ req *Request
+ cancelKey cancelKey
+ ch chan responseAndError // unbuffered; always send in select on callerGone
+
+ // whether the Transport (as opposed to the user client code)
+ // added the Accept-Encoding gzip header. If the Transport
+ // set it, only then do we transparently decode the gzip.
+ addedGzip bool
+
+ // Optional blocking chan for Expect: 100-continue (for send).
+ // If the request has an "Expect: 100-continue" header and
+ // the server responds 100 Continue, readLoop send a value
+ // to writeLoop via this chan.
+ continueCh chan<- struct{}
+
+ callerGone <-chan struct{} // closed when roundTrip caller has returned
+}
+
+// A writeRequest is sent by the caller's goroutine to the
+// writeLoop's goroutine to write a request while the read loop
+// concurrently waits on both the write response and the server's
+// reply.
+type writeRequest struct {
+ req *transportRequest
+ ch chan<- error
+
+ // Optional blocking chan for Expect: 100-continue (for receive).
+ // If not nil, writeLoop blocks sending request body until
+ // it receives from this chan.
+ continueCh <-chan struct{}
+}
+
+type httpError struct {
+ err string
+ timeout bool
+}
+
+func (e *httpError) Error() string { return e.err }
+func (e *httpError) Timeout() bool { return e.timeout }
+func (e *httpError) Temporary() bool { return true }
+
+var errTimeout error = &httpError{err: "net/http: timeout awaiting response headers", timeout: true}
+
+// errRequestCanceled is set to be identical to the one from h2 to facilitate
+// testing.
+var errRequestCanceled = http2errRequestCanceled
+var errRequestCanceledConn = errors.New("net/http: request canceled while waiting for connection") // TODO: unify?
+
+func nop() {}
+
+// testHooks. Always non-nil.
+var (
+ testHookEnterRoundTrip = nop
+ testHookWaitResLoop = nop
+ testHookRoundTripRetried = nop
+ testHookPrePendingDial = nop
+ testHookPostPendingDial = nop
+
+ testHookMu sync.Locker = fakeLocker{} // guards following
+ testHookReadLoopBeforeNextRead = nop
+)
+
+func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) {
+ testHookEnterRoundTrip()
+ if !pc.t.replaceReqCanceler(req.cancelKey, pc.cancelRequest) {
+ pc.t.putOrCloseIdleConn(pc)
+ return nil, errRequestCanceled
+ }
+ pc.mu.Lock()
+ pc.numExpectedResponses++
+ headerFn := pc.mutateHeaderFunc
+ pc.mu.Unlock()
+
+ if headerFn != nil {
+ headerFn(req.extraHeaders())
+ }
+
+ // Ask for a compressed version if the caller didn't set their
+ // own value for Accept-Encoding. We only attempt to
+ // uncompress the gzip stream if we were the layer that
+ // requested it.
+ requestedGzip := false
+ if !pc.t.DisableCompression &&
+ req.Header.Get("Accept-Encoding") == "" &&
+ req.Header.Get("Range") == "" &&
+ req.Method != "HEAD" {
+ // Request gzip only, not deflate. Deflate is ambiguous and
+ // not as universally supported anyway.
+ // See: https://zlib.net/zlib_faq.html#faq39
+ //
+ // Note that we don't request this for HEAD requests,
+ // due to a bug in nginx:
+ // https://trac.nginx.org/nginx/ticket/358
+ // https://golang.org/issue/5522
+ //
+ // We don't request gzip if the request is for a range, since
+ // auto-decoding a portion of a gzipped document will just fail
+ // anyway. See https://golang.org/issue/8923
+ requestedGzip = true
+ req.extraHeaders().Set("Accept-Encoding", "gzip")
+ }
+
+ var continueCh chan struct{}
+ if req.ProtoAtLeast(1, 1) && req.Body != nil && req.expectsContinue() {
+ continueCh = make(chan struct{}, 1)
+ }
+
+ if pc.t.DisableKeepAlives &&
+ !req.wantsClose() &&
+ !isProtocolSwitchHeader(req.Header) {
+ req.extraHeaders().Set("Connection", "close")
+ }
+
+ gone := make(chan struct{})
+ defer close(gone)
+
+ defer func() {
+ if err != nil {
+ pc.t.setReqCanceler(req.cancelKey, nil)
+ }
+ }()
+
+ const debugRoundTrip = false
+
+ // Write the request concurrently with waiting for a response,
+ // in case the server decides to reply before reading our full
+ // request body.
+ startBytesWritten := pc.nwrite
+ writeErrCh := make(chan error, 1)
+ pc.writech <- writeRequest{req, writeErrCh, continueCh}
+
+ resc := make(chan responseAndError)
+ pc.reqch <- requestAndChan{
+ req: req.Request,
+ cancelKey: req.cancelKey,
+ ch: resc,
+ addedGzip: requestedGzip,
+ continueCh: continueCh,
+ callerGone: gone,
+ }
+
+ var respHeaderTimer <-chan time.Time
+ cancelChan := req.Request.Cancel
+ ctxDoneChan := req.Context().Done()
+ pcClosed := pc.closech
+ canceled := false
+ for {
+ testHookWaitResLoop()
+ select {
+ case err := <-writeErrCh:
+ if debugRoundTrip {
+ req.logf("writeErrCh resv: %T/%#v", err, err)
+ }
+ if err != nil {
+ pc.close(fmt.Errorf("write error: %w", err))
+ return nil, pc.mapRoundTripError(req, startBytesWritten, err)
+ }
+ if d := pc.t.ResponseHeaderTimeout; d > 0 {
+ if debugRoundTrip {
+ req.logf("starting timer for %v", d)
+ }
+ timer := time.NewTimer(d)
+ defer timer.Stop() // prevent leaks
+ respHeaderTimer = timer.C
+ }
+ case <-pcClosed:
+ pcClosed = nil
+ if canceled || 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)
+ }
+ case <-respHeaderTimer:
+ if debugRoundTrip {
+ req.logf("timeout waiting for response headers.")
+ }
+ pc.close(errTimeout)
+ return nil, errTimeout
+ case re := <-resc:
+ if (re.res == nil) == (re.err == nil) {
+ panic(fmt.Sprintf("internal error: exactly one of res or err should be set; nil=%v", re.res == nil))
+ }
+ if debugRoundTrip {
+ req.logf("resc recv: %p, %T/%#v", re.res, re.err, re.err)
+ }
+ if re.err != nil {
+ return nil, pc.mapRoundTripError(req, startBytesWritten, re.err)
+ }
+ return re.res, nil
+ case <-cancelChan:
+ canceled = pc.t.cancelRequest(req.cancelKey, errRequestCanceled)
+ cancelChan = nil
+ case <-ctxDoneChan:
+ canceled = pc.t.cancelRequest(req.cancelKey, req.Context().Err())
+ cancelChan = nil
+ ctxDoneChan = nil
+ }
+ }
+}
+
+// tLogKey is a context WithValue key for test debugging contexts containing
+// a t.Logf func. See export_test.go's Request.WithT method.
+type tLogKey struct{}
+
+func (tr *transportRequest) logf(format string, args ...any) {
+ if logf, ok := tr.Request.Context().Value(tLogKey{}).(func(string, ...any)); ok {
+ logf(time.Now().Format(time.RFC3339Nano)+": "+format, args...)
+ }
+}
+
+// markReused marks this connection as having been successfully used for a
+// request and response.
+func (pc *persistConn) markReused() {
+ pc.mu.Lock()
+ pc.reused = true
+ pc.mu.Unlock()
+}
+
+// close closes the underlying TCP connection and closes
+// the pc.closech channel.
+//
+// The provided err is only for testing and debugging; in normal
+// circumstances it should never be seen by users.
+func (pc *persistConn) close(err error) {
+ pc.mu.Lock()
+ defer pc.mu.Unlock()
+ pc.closeLocked(err)
+}
+
+func (pc *persistConn) closeLocked(err error) {
+ if err == nil {
+ panic("nil error")
+ }
+ pc.broken = true
+ if pc.closed == nil {
+ pc.closed = err
+ pc.t.decConnsPerHost(pc.cacheKey)
+ // Close HTTP/1 (pc.alt == nil) connection.
+ // HTTP/2 closes its connection itself.
+ if pc.alt == nil {
+ if err != errCallerOwnsConn {
+ pc.conn.Close()
+ }
+ close(pc.closech)
+ }
+ }
+ pc.mutateHeaderFunc = nil
+}
+
+var portMap = map[string]string{
+ "http": "80",
+ "https": "443",
+ "socks5": "1080",
+}
+
+func idnaASCIIFromURL(url *url.URL) string {
+ addr := url.Hostname()
+ if v, err := idnaASCII(addr); err == nil {
+ addr = v
+ }
+ return addr
+}
+
+// canonicalAddr returns url.Host but always with a ":port" suffix.
+func canonicalAddr(url *url.URL) string {
+ port := url.Port()
+ if port == "" {
+ port = portMap[url.Scheme]
+ }
+ return net.JoinHostPort(idnaASCIIFromURL(url), port)
+}
+
+// bodyEOFSignal is used by the HTTP/1 transport when reading response
+// bodies to make sure we see the end of a response body before
+// proceeding and reading on the connection again.
+//
+// It wraps a ReadCloser but runs fn (if non-nil) at most
+// once, right before its final (error-producing) Read or Close call
+// returns. fn should return the new error to return from Read or Close.
+//
+// If earlyCloseFn is non-nil and Close is called before io.EOF is
+// seen, earlyCloseFn is called instead of fn, and its return value is
+// the return value from Close.
+type bodyEOFSignal struct {
+ body io.ReadCloser
+ mu sync.Mutex // guards following 4 fields
+ closed bool // whether Close has been called
+ rerr error // sticky Read error
+ fn func(error) error // err will be nil on Read io.EOF
+ earlyCloseFn func() error // optional alt Close func used if io.EOF not seen
+}
+
+var errReadOnClosedResBody = errors.New("http: read on closed response body")
+
+func (es *bodyEOFSignal) Read(p []byte) (n int, err error) {
+ es.mu.Lock()
+ closed, rerr := es.closed, es.rerr
+ es.mu.Unlock()
+ if closed {
+ return 0, errReadOnClosedResBody
+ }
+ if rerr != nil {
+ return 0, rerr
+ }
+
+ n, err = es.body.Read(p)
+ if err != nil {
+ es.mu.Lock()
+ defer es.mu.Unlock()
+ if es.rerr == nil {
+ es.rerr = err
+ }
+ err = es.condfn(err)
+ }
+ return
+}
+
+func (es *bodyEOFSignal) Close() error {
+ es.mu.Lock()
+ defer es.mu.Unlock()
+ if es.closed {
+ return nil
+ }
+ es.closed = true
+ if es.earlyCloseFn != nil && es.rerr != io.EOF {
+ return es.earlyCloseFn()
+ }
+ err := es.body.Close()
+ return es.condfn(err)
+}
+
+// caller must hold es.mu.
+func (es *bodyEOFSignal) condfn(err error) error {
+ if es.fn == nil {
+ return err
+ }
+ err = es.fn(err)
+ es.fn = nil
+ return err
+}
+
+// gzipReader wraps a response body so it can lazily
+// call gzip.NewReader on the first call to Read
+type gzipReader struct {
+ _ incomparable
+ body *bodyEOFSignal // underlying HTTP/1 response body framing
+ zr *gzip.Reader // lazily-initialized gzip reader
+ zerr error // any error from gzip.NewReader; sticky
+}
+
+func (gz *gzipReader) Read(p []byte) (n int, err error) {
+ if gz.zr == nil {
+ if gz.zerr == nil {
+ gz.zr, gz.zerr = gzip.NewReader(gz.body)
+ }
+ if gz.zerr != nil {
+ return 0, gz.zerr
+ }
+ }
+
+ gz.body.mu.Lock()
+ if gz.body.closed {
+ err = errReadOnClosedResBody
+ }
+ gz.body.mu.Unlock()
+
+ if err != nil {
+ return 0, err
+ }
+ return gz.zr.Read(p)
+}
+
+func (gz *gzipReader) Close() error {
+ return gz.body.Close()
+}
+
+type tlsHandshakeTimeoutError struct{}
+
+func (tlsHandshakeTimeoutError) Timeout() bool { return true }
+func (tlsHandshakeTimeoutError) Temporary() bool { return true }
+func (tlsHandshakeTimeoutError) Error() string { return "net/http: TLS handshake timeout" }
+
+// fakeLocker is a sync.Locker which does nothing. It's used to guard
+// test-only fields when not under test, to avoid runtime atomic
+// overhead.
+type fakeLocker struct{}
+
+func (fakeLocker) Lock() {}
+func (fakeLocker) Unlock() {}
+
+// cloneTLSConfig returns a shallow clone of cfg, or a new zero tls.Config if
+// cfg is nil. This is safe to call even if cfg is in active use by a TLS
+// client or server.
+func cloneTLSConfig(cfg *tls.Config) *tls.Config {
+ if cfg == nil {
+ return &tls.Config{}
+ }
+ return cfg.Clone()
+}
+
+type connLRU struct {
+ ll *list.List // list.Element.Value type is of *persistConn
+ m map[*persistConn]*list.Element
+}
+
+// add adds pc to the head of the linked list.
+func (cl *connLRU) add(pc *persistConn) {
+ if cl.ll == nil {
+ cl.ll = list.New()
+ cl.m = make(map[*persistConn]*list.Element)
+ }
+ ele := cl.ll.PushFront(pc)
+ if _, ok := cl.m[pc]; ok {
+ panic("persistConn was already in LRU")
+ }
+ cl.m[pc] = ele
+}
+
+func (cl *connLRU) removeOldest() *persistConn {
+ ele := cl.ll.Back()
+ pc := ele.Value.(*persistConn)
+ cl.ll.Remove(ele)
+ delete(cl.m, pc)
+ return pc
+}
+
+// remove removes pc from cl.
+func (cl *connLRU) remove(pc *persistConn) {
+ if ele, ok := cl.m[pc]; ok {
+ cl.ll.Remove(ele)
+ delete(cl.m, pc)
+ }
+}
+
+// len returns the number of items in the cache.
+func (cl *connLRU) len() int {
+ return len(cl.m)
+}
diff --git a/contrib/go/_std_1.21/src/net/http/transport_default_other.go b/contrib/go/_std_1.21/src/net/http/transport_default_other.go
new file mode 100644
index 0000000000..4f6c5c1271
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/transport_default_other.go
@@ -0,0 +1,16 @@
+// 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.
+
+//go:build !wasm
+
+package http
+
+import (
+ "context"
+ "net"
+)
+
+func defaultTransportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) {
+ return dialer.DialContext
+}
diff --git a/contrib/go/_std_1.21/src/net/http/ya.make b/contrib/go/_std_1.21/src/net/http/ya.make
new file mode 100644
index 0000000000..805ba6ba4f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/http/ya.make
@@ -0,0 +1,74 @@
+GO_LIBRARY()
+
+SRCS(
+ client.go
+ clone.go
+ cookie.go
+ doc.go
+ filetransport.go
+ fs.go
+ h2_bundle.go
+ h2_error.go
+ header.go
+ http.go
+ jar.go
+ method.go
+ request.go
+ response.go
+ responsecontroller.go
+ roundtrip.go
+ server.go
+ sniff.go
+ socks_bundle.go
+ status.go
+ transfer.go
+ transport.go
+ transport_default_other.go
+)
+
+GO_TEST_SRCS(
+ cookie_test.go
+ export_test.go
+ filetransport_test.go
+ h2_error_test.go
+ header_test.go
+ http_test.go
+ proxy_test.go
+ range_test.go
+ readrequest_test.go
+ requestwrite_test.go
+ response_test.go
+ responsewrite_test.go
+ server_test.go
+ transfer_test.go
+ transport_internal_test.go
+)
+
+GO_XTEST_SRCS(
+ alpn_test.go
+ client_test.go
+ clientserver_test.go
+ example_filesystem_test.go
+ example_handle_test.go
+ example_test.go
+ fs_test.go
+ main_test.go
+ request_test.go
+ responsecontroller_test.go
+ serve_test.go
+ sniff_test.go
+ transport_test.go
+)
+
+END()
+
+RECURSE(
+ cgi
+ cookiejar
+ fcgi
+ httptest
+ httptrace
+ httputil
+ internal
+ pprof
+)
diff --git a/contrib/go/_std_1.20/src/net/interface.go b/contrib/go/_std_1.21/src/net/interface.go
index e1c9a2e2ff..e1c9a2e2ff 100644
--- a/contrib/go/_std_1.20/src/net/interface.go
+++ b/contrib/go/_std_1.21/src/net/interface.go
diff --git a/contrib/go/_std_1.20/src/net/interface_bsd.go b/contrib/go/_std_1.21/src/net/interface_bsd.go
index 9b2b42addb..9b2b42addb 100644
--- a/contrib/go/_std_1.20/src/net/interface_bsd.go
+++ b/contrib/go/_std_1.21/src/net/interface_bsd.go
diff --git a/contrib/go/_std_1.20/src/net/interface_darwin.go b/contrib/go/_std_1.21/src/net/interface_darwin.go
index bb4fd73a98..bb4fd73a98 100644
--- a/contrib/go/_std_1.20/src/net/interface_darwin.go
+++ b/contrib/go/_std_1.21/src/net/interface_darwin.go
diff --git a/contrib/go/_std_1.20/src/net/interface_linux.go b/contrib/go/_std_1.21/src/net/interface_linux.go
index 9112ecc854..9112ecc854 100644
--- a/contrib/go/_std_1.20/src/net/interface_linux.go
+++ b/contrib/go/_std_1.21/src/net/interface_linux.go
diff --git a/contrib/go/_std_1.20/src/net/interface_windows.go b/contrib/go/_std_1.21/src/net/interface_windows.go
index 22a1312849..22a1312849 100644
--- a/contrib/go/_std_1.20/src/net/interface_windows.go
+++ b/contrib/go/_std_1.21/src/net/interface_windows.go
diff --git a/contrib/go/_std_1.20/src/net/internal/socktest/switch.go b/contrib/go/_std_1.21/src/net/internal/socktest/switch.go
index 3c37b6ff80..3c37b6ff80 100644
--- a/contrib/go/_std_1.20/src/net/internal/socktest/switch.go
+++ b/contrib/go/_std_1.21/src/net/internal/socktest/switch.go
diff --git a/contrib/go/_std_1.20/src/net/internal/socktest/switch_posix.go b/contrib/go/_std_1.21/src/net/internal/socktest/switch_posix.go
index fcad4ceae3..fcad4ceae3 100644
--- a/contrib/go/_std_1.20/src/net/internal/socktest/switch_posix.go
+++ b/contrib/go/_std_1.21/src/net/internal/socktest/switch_posix.go
diff --git a/contrib/go/_std_1.21/src/net/internal/socktest/switch_unix.go b/contrib/go/_std_1.21/src/net/internal/socktest/switch_unix.go
new file mode 100644
index 0000000000..ff92877648
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/internal/socktest/switch_unix.go
@@ -0,0 +1,29 @@
+// Copyright 2015 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package socktest
+
+// Sockets maps a socket descriptor to the status of socket.
+type Sockets map[int]Status
+
+func (sw *Switch) sockso(s int) *Status {
+ sw.smu.RLock()
+ defer sw.smu.RUnlock()
+ so, ok := sw.sotab[s]
+ if !ok {
+ return nil
+ }
+ return &so
+}
+
+// addLocked returns a new Status without locking.
+// sw.smu must be held before call.
+func (sw *Switch) addLocked(s, family, sotype, proto int) *Status {
+ sw.once.Do(sw.init)
+ so := Status{Cookie: cookie(family, sotype, proto)}
+ sw.sotab[s] = so
+ return &so
+}
diff --git a/contrib/go/_std_1.20/src/net/internal/socktest/switch_windows.go b/contrib/go/_std_1.21/src/net/internal/socktest/switch_windows.go
index 4f1d597a27..4f1d597a27 100644
--- a/contrib/go/_std_1.20/src/net/internal/socktest/switch_windows.go
+++ b/contrib/go/_std_1.21/src/net/internal/socktest/switch_windows.go
diff --git a/contrib/go/_std_1.20/src/net/internal/socktest/sys_cloexec.go b/contrib/go/_std_1.21/src/net/internal/socktest/sys_cloexec.go
index d57f44d9ee..d57f44d9ee 100644
--- a/contrib/go/_std_1.20/src/net/internal/socktest/sys_cloexec.go
+++ b/contrib/go/_std_1.21/src/net/internal/socktest/sys_cloexec.go
diff --git a/contrib/go/_std_1.21/src/net/internal/socktest/sys_unix.go b/contrib/go/_std_1.21/src/net/internal/socktest/sys_unix.go
new file mode 100644
index 0000000000..712462abf4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/internal/socktest/sys_unix.go
@@ -0,0 +1,193 @@
+// Copyright 2015 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package socktest
+
+import "syscall"
+
+// Socket wraps syscall.Socket.
+func (sw *Switch) Socket(family, sotype, proto int) (s int, err error) {
+ sw.once.Do(sw.init)
+
+ so := &Status{Cookie: cookie(family, sotype, proto)}
+ sw.fmu.RLock()
+ f := sw.fltab[FilterSocket]
+ sw.fmu.RUnlock()
+
+ af, err := f.apply(so)
+ if err != nil {
+ return -1, err
+ }
+ s, so.Err = syscall.Socket(family, sotype, proto)
+ if err = af.apply(so); err != nil {
+ if so.Err == nil {
+ syscall.Close(s)
+ }
+ return -1, err
+ }
+
+ sw.smu.Lock()
+ defer sw.smu.Unlock()
+ if so.Err != nil {
+ sw.stats.getLocked(so.Cookie).OpenFailed++
+ return -1, so.Err
+ }
+ nso := sw.addLocked(s, family, sotype, proto)
+ sw.stats.getLocked(nso.Cookie).Opened++
+ return s, nil
+}
+
+// Close wraps syscall.Close.
+func (sw *Switch) Close(s int) (err error) {
+ so := sw.sockso(s)
+ if so == nil {
+ return syscall.Close(s)
+ }
+ sw.fmu.RLock()
+ f := sw.fltab[FilterClose]
+ sw.fmu.RUnlock()
+
+ af, err := f.apply(so)
+ if err != nil {
+ return err
+ }
+ so.Err = syscall.Close(s)
+ if err = af.apply(so); err != nil {
+ return err
+ }
+
+ sw.smu.Lock()
+ defer sw.smu.Unlock()
+ if so.Err != nil {
+ sw.stats.getLocked(so.Cookie).CloseFailed++
+ return so.Err
+ }
+ delete(sw.sotab, s)
+ sw.stats.getLocked(so.Cookie).Closed++
+ return nil
+}
+
+// Connect wraps syscall.Connect.
+func (sw *Switch) Connect(s int, sa syscall.Sockaddr) (err error) {
+ so := sw.sockso(s)
+ if so == nil {
+ return syscall.Connect(s, sa)
+ }
+ sw.fmu.RLock()
+ f := sw.fltab[FilterConnect]
+ sw.fmu.RUnlock()
+
+ af, err := f.apply(so)
+ if err != nil {
+ return err
+ }
+ so.Err = syscall.Connect(s, sa)
+ if err = af.apply(so); err != nil {
+ return err
+ }
+
+ sw.smu.Lock()
+ defer sw.smu.Unlock()
+ if so.Err != nil {
+ sw.stats.getLocked(so.Cookie).ConnectFailed++
+ return so.Err
+ }
+ sw.stats.getLocked(so.Cookie).Connected++
+ return nil
+}
+
+// Listen wraps syscall.Listen.
+func (sw *Switch) Listen(s, backlog int) (err error) {
+ so := sw.sockso(s)
+ if so == nil {
+ return syscall.Listen(s, backlog)
+ }
+ sw.fmu.RLock()
+ f := sw.fltab[FilterListen]
+ sw.fmu.RUnlock()
+
+ af, err := f.apply(so)
+ if err != nil {
+ return err
+ }
+ so.Err = syscall.Listen(s, backlog)
+ if err = af.apply(so); err != nil {
+ return err
+ }
+
+ sw.smu.Lock()
+ defer sw.smu.Unlock()
+ if so.Err != nil {
+ sw.stats.getLocked(so.Cookie).ListenFailed++
+ return so.Err
+ }
+ sw.stats.getLocked(so.Cookie).Listened++
+ return nil
+}
+
+// Accept wraps syscall.Accept.
+func (sw *Switch) Accept(s int) (ns int, sa syscall.Sockaddr, err error) {
+ so := sw.sockso(s)
+ if so == nil {
+ return syscall.Accept(s)
+ }
+ sw.fmu.RLock()
+ f := sw.fltab[FilterAccept]
+ sw.fmu.RUnlock()
+
+ af, err := f.apply(so)
+ if err != nil {
+ return -1, nil, err
+ }
+ ns, sa, so.Err = syscall.Accept(s)
+ if err = af.apply(so); err != nil {
+ if so.Err == nil {
+ syscall.Close(ns)
+ }
+ return -1, nil, err
+ }
+
+ sw.smu.Lock()
+ defer sw.smu.Unlock()
+ if so.Err != nil {
+ sw.stats.getLocked(so.Cookie).AcceptFailed++
+ return -1, nil, so.Err
+ }
+ nso := sw.addLocked(ns, so.Cookie.Family(), so.Cookie.Type(), so.Cookie.Protocol())
+ sw.stats.getLocked(nso.Cookie).Accepted++
+ return ns, sa, nil
+}
+
+// GetsockoptInt wraps syscall.GetsockoptInt.
+func (sw *Switch) GetsockoptInt(s, level, opt int) (soerr int, err error) {
+ so := sw.sockso(s)
+ if so == nil {
+ return syscall.GetsockoptInt(s, level, opt)
+ }
+ sw.fmu.RLock()
+ f := sw.fltab[FilterGetsockoptInt]
+ sw.fmu.RUnlock()
+
+ af, err := f.apply(so)
+ if err != nil {
+ return -1, err
+ }
+ soerr, so.Err = syscall.GetsockoptInt(s, level, opt)
+ so.SocketErr = syscall.Errno(soerr)
+ if err = af.apply(so); err != nil {
+ return -1, err
+ }
+
+ if so.Err != nil {
+ return -1, so.Err
+ }
+ if opt == syscall.SO_ERROR && (so.SocketErr == syscall.Errno(0) || so.SocketErr == syscall.EISCONN) {
+ sw.smu.Lock()
+ sw.stats.getLocked(so.Cookie).Connected++
+ sw.smu.Unlock()
+ }
+ return soerr, nil
+}
diff --git a/contrib/go/_std_1.20/src/net/internal/socktest/sys_windows.go b/contrib/go/_std_1.21/src/net/internal/socktest/sys_windows.go
index 8c1c862f33..8c1c862f33 100644
--- a/contrib/go/_std_1.20/src/net/internal/socktest/sys_windows.go
+++ b/contrib/go/_std_1.21/src/net/internal/socktest/sys_windows.go
diff --git a/contrib/go/_std_1.21/src/net/internal/socktest/ya.make b/contrib/go/_std_1.21/src/net/internal/socktest/ya.make
new file mode 100644
index 0000000000..074fde162e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/internal/socktest/ya.make
@@ -0,0 +1,41 @@
+GO_LIBRARY()
+
+SRCS(
+ switch.go
+ switch_posix.go
+)
+
+GO_XTEST_SRCS(main_test.go)
+
+IF (OS_LINUX)
+ SRCS(
+ switch_unix.go
+ sys_cloexec.go
+ sys_unix.go
+ )
+
+ GO_XTEST_SRCS(main_unix_test.go)
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ switch_unix.go
+ sys_unix.go
+ )
+
+ GO_XTEST_SRCS(main_unix_test.go)
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ switch_windows.go
+ sys_windows.go
+ )
+
+ GO_XTEST_SRCS(main_windows_test.go)
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/net/internal/ya.make b/contrib/go/_std_1.21/src/net/internal/ya.make
index a9f0d8daec..a9f0d8daec 100644
--- a/contrib/go/_std_1.20/src/net/internal/ya.make
+++ b/contrib/go/_std_1.21/src/net/internal/ya.make
diff --git a/contrib/go/_std_1.21/src/net/ip.go b/contrib/go/_std_1.21/src/net/ip.go
new file mode 100644
index 0000000000..d51ba10eec
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/ip.go
@@ -0,0 +1,542 @@
+// Copyright 2009 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.
+
+// IP address manipulations
+//
+// IPv4 addresses are 4 bytes; IPv6 addresses are 16 bytes.
+// An IPv4 address can be converted to an IPv6 address by
+// adding a canonical prefix (10 zeros, 2 0xFFs).
+// This library accepts either size of byte slice but always
+// returns 16-byte addresses.
+
+package net
+
+import (
+ "internal/bytealg"
+ "internal/itoa"
+ "net/netip"
+)
+
+// IP address lengths (bytes).
+const (
+ IPv4len = 4
+ IPv6len = 16
+)
+
+// An IP is a single IP address, a slice of bytes.
+// Functions in this package accept either 4-byte (IPv4)
+// or 16-byte (IPv6) slices as input.
+//
+// Note that in this documentation, referring to an
+// IP address as an IPv4 address or an IPv6 address
+// is a semantic property of the address, not just the
+// length of the byte slice: a 16-byte slice can still
+// be an IPv4 address.
+type IP []byte
+
+// An IPMask is a bitmask that can be used to manipulate
+// IP addresses for IP addressing and routing.
+//
+// See type IPNet and func ParseCIDR for details.
+type IPMask []byte
+
+// An IPNet represents an IP network.
+type IPNet struct {
+ IP IP // network number
+ Mask IPMask // network mask
+}
+
+// IPv4 returns the IP address (in 16-byte form) of the
+// IPv4 address a.b.c.d.
+func IPv4(a, b, c, d byte) IP {
+ p := make(IP, IPv6len)
+ copy(p, v4InV6Prefix)
+ p[12] = a
+ p[13] = b
+ p[14] = c
+ p[15] = d
+ return p
+}
+
+var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
+
+// IPv4Mask returns the IP mask (in 4-byte form) of the
+// IPv4 mask a.b.c.d.
+func IPv4Mask(a, b, c, d byte) IPMask {
+ p := make(IPMask, IPv4len)
+ p[0] = a
+ p[1] = b
+ p[2] = c
+ p[3] = d
+ return p
+}
+
+// CIDRMask returns an IPMask consisting of 'ones' 1 bits
+// followed by 0s up to a total length of 'bits' bits.
+// For a mask of this form, CIDRMask is the inverse of IPMask.Size.
+func CIDRMask(ones, bits int) IPMask {
+ if bits != 8*IPv4len && bits != 8*IPv6len {
+ return nil
+ }
+ if ones < 0 || ones > bits {
+ return nil
+ }
+ l := bits / 8
+ m := make(IPMask, l)
+ n := uint(ones)
+ for i := 0; i < l; i++ {
+ if n >= 8 {
+ m[i] = 0xff
+ n -= 8
+ continue
+ }
+ m[i] = ^byte(0xff >> n)
+ n = 0
+ }
+ return m
+}
+
+// Well-known IPv4 addresses
+var (
+ IPv4bcast = IPv4(255, 255, 255, 255) // limited broadcast
+ IPv4allsys = IPv4(224, 0, 0, 1) // all systems
+ IPv4allrouter = IPv4(224, 0, 0, 2) // all routers
+ IPv4zero = IPv4(0, 0, 0, 0) // all zeros
+)
+
+// Well-known IPv6 addresses
+var (
+ IPv6zero = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ IPv6unspecified = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ IPv6loopback = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
+ IPv6interfacelocalallnodes = IP{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
+ IPv6linklocalallnodes = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
+ IPv6linklocalallrouters = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}
+)
+
+// IsUnspecified reports whether ip is an unspecified address, either
+// the IPv4 address "0.0.0.0" or the IPv6 address "::".
+func (ip IP) IsUnspecified() bool {
+ return ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified)
+}
+
+// IsLoopback reports whether ip is a loopback address.
+func (ip IP) IsLoopback() bool {
+ if ip4 := ip.To4(); ip4 != nil {
+ return ip4[0] == 127
+ }
+ return ip.Equal(IPv6loopback)
+}
+
+// IsPrivate reports whether ip is a private address, according to
+// RFC 1918 (IPv4 addresses) and RFC 4193 (IPv6 addresses).
+func (ip IP) IsPrivate() bool {
+ if ip4 := ip.To4(); ip4 != nil {
+ // Following RFC 1918, Section 3. Private Address Space which says:
+ // The Internet Assigned Numbers Authority (IANA) has reserved the
+ // following three blocks of the IP address space for private internets:
+ // 10.0.0.0 - 10.255.255.255 (10/8 prefix)
+ // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
+ // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
+ return ip4[0] == 10 ||
+ (ip4[0] == 172 && ip4[1]&0xf0 == 16) ||
+ (ip4[0] == 192 && ip4[1] == 168)
+ }
+ // Following RFC 4193, Section 8. IANA Considerations which says:
+ // The IANA has assigned the FC00::/7 prefix to "Unique Local Unicast".
+ return len(ip) == IPv6len && ip[0]&0xfe == 0xfc
+}
+
+// IsMulticast reports whether ip is a multicast address.
+func (ip IP) IsMulticast() bool {
+ if ip4 := ip.To4(); ip4 != nil {
+ return ip4[0]&0xf0 == 0xe0
+ }
+ return len(ip) == IPv6len && ip[0] == 0xff
+}
+
+// IsInterfaceLocalMulticast reports whether ip is
+// an interface-local multicast address.
+func (ip IP) IsInterfaceLocalMulticast() bool {
+ return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x01
+}
+
+// IsLinkLocalMulticast reports whether ip is a link-local
+// multicast address.
+func (ip IP) IsLinkLocalMulticast() bool {
+ if ip4 := ip.To4(); ip4 != nil {
+ return ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0
+ }
+ return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x02
+}
+
+// IsLinkLocalUnicast reports whether ip is a link-local
+// unicast address.
+func (ip IP) IsLinkLocalUnicast() bool {
+ if ip4 := ip.To4(); ip4 != nil {
+ return ip4[0] == 169 && ip4[1] == 254
+ }
+ return len(ip) == IPv6len && ip[0] == 0xfe && ip[1]&0xc0 == 0x80
+}
+
+// IsGlobalUnicast reports whether ip is a global unicast
+// address.
+//
+// The identification of global unicast addresses uses address type
+// identification as defined in RFC 1122, RFC 4632 and RFC 4291 with
+// the exception of IPv4 directed broadcast addresses.
+// It returns true even if ip is in IPv4 private address space or
+// local IPv6 unicast address space.
+func (ip IP) IsGlobalUnicast() bool {
+ return (len(ip) == IPv4len || len(ip) == IPv6len) &&
+ !ip.Equal(IPv4bcast) &&
+ !ip.IsUnspecified() &&
+ !ip.IsLoopback() &&
+ !ip.IsMulticast() &&
+ !ip.IsLinkLocalUnicast()
+}
+
+// Is p all zeros?
+func isZeros(p IP) bool {
+ for i := 0; i < len(p); i++ {
+ if p[i] != 0 {
+ return false
+ }
+ }
+ return true
+}
+
+// To4 converts the IPv4 address ip to a 4-byte representation.
+// If ip is not an IPv4 address, To4 returns nil.
+func (ip IP) To4() IP {
+ if len(ip) == IPv4len {
+ return ip
+ }
+ if len(ip) == IPv6len &&
+ isZeros(ip[0:10]) &&
+ ip[10] == 0xff &&
+ ip[11] == 0xff {
+ return ip[12:16]
+ }
+ return nil
+}
+
+// To16 converts the IP address ip to a 16-byte representation.
+// If ip is not an IP address (it is the wrong length), To16 returns nil.
+func (ip IP) To16() IP {
+ if len(ip) == IPv4len {
+ return IPv4(ip[0], ip[1], ip[2], ip[3])
+ }
+ if len(ip) == IPv6len {
+ return ip
+ }
+ return nil
+}
+
+// Default route masks for IPv4.
+var (
+ classAMask = IPv4Mask(0xff, 0, 0, 0)
+ classBMask = IPv4Mask(0xff, 0xff, 0, 0)
+ classCMask = IPv4Mask(0xff, 0xff, 0xff, 0)
+)
+
+// DefaultMask returns the default IP mask for the IP address ip.
+// Only IPv4 addresses have default masks; DefaultMask returns
+// nil if ip is not a valid IPv4 address.
+func (ip IP) DefaultMask() IPMask {
+ if ip = ip.To4(); ip == nil {
+ return nil
+ }
+ switch {
+ case ip[0] < 0x80:
+ return classAMask
+ case ip[0] < 0xC0:
+ return classBMask
+ default:
+ return classCMask
+ }
+}
+
+func allFF(b []byte) bool {
+ for _, c := range b {
+ if c != 0xff {
+ return false
+ }
+ }
+ return true
+}
+
+// Mask returns the result of masking the IP address ip with mask.
+func (ip IP) Mask(mask IPMask) IP {
+ if len(mask) == IPv6len && len(ip) == IPv4len && allFF(mask[:12]) {
+ mask = mask[12:]
+ }
+ if len(mask) == IPv4len && len(ip) == IPv6len && bytealg.Equal(ip[:12], v4InV6Prefix) {
+ ip = ip[12:]
+ }
+ n := len(ip)
+ if n != len(mask) {
+ return nil
+ }
+ out := make(IP, n)
+ for i := 0; i < n; i++ {
+ out[i] = ip[i] & mask[i]
+ }
+ return out
+}
+
+// String returns the string form of the IP address ip.
+// It returns one of 4 forms:
+// - "<nil>", if ip has length 0
+// - dotted decimal ("192.0.2.1"), if ip is an IPv4 or IP4-mapped IPv6 address
+// - IPv6 conforming to RFC 5952 ("2001:db8::1"), if ip is a valid IPv6 address
+// - the hexadecimal form of ip, without punctuation, if no other cases apply
+func (ip IP) String() string {
+ if len(ip) == 0 {
+ return "<nil>"
+ }
+
+ if len(ip) != IPv4len && len(ip) != IPv6len {
+ return "?" + hexString(ip)
+ }
+ // If IPv4, use dotted notation.
+ if p4 := ip.To4(); len(p4) == IPv4len {
+ return netip.AddrFrom4([4]byte(p4)).String()
+ }
+ return netip.AddrFrom16([16]byte(ip)).String()
+}
+
+func hexString(b []byte) string {
+ s := make([]byte, len(b)*2)
+ for i, tn := range b {
+ s[i*2], s[i*2+1] = hexDigit[tn>>4], hexDigit[tn&0xf]
+ }
+ return string(s)
+}
+
+// ipEmptyString is like ip.String except that it returns
+// an empty string when ip is unset.
+func ipEmptyString(ip IP) string {
+ if len(ip) == 0 {
+ return ""
+ }
+ return ip.String()
+}
+
+// MarshalText implements the encoding.TextMarshaler interface.
+// The encoding is the same as returned by String, with one exception:
+// When len(ip) is zero, it returns an empty slice.
+func (ip IP) MarshalText() ([]byte, error) {
+ if len(ip) == 0 {
+ return []byte(""), nil
+ }
+ if len(ip) != IPv4len && len(ip) != IPv6len {
+ return nil, &AddrError{Err: "invalid IP address", Addr: hexString(ip)}
+ }
+ return []byte(ip.String()), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface.
+// The IP address is expected in a form accepted by ParseIP.
+func (ip *IP) UnmarshalText(text []byte) error {
+ if len(text) == 0 {
+ *ip = nil
+ return nil
+ }
+ s := string(text)
+ x := ParseIP(s)
+ if x == nil {
+ return &ParseError{Type: "IP address", Text: s}
+ }
+ *ip = x
+ return nil
+}
+
+// Equal reports whether ip and x are the same IP address.
+// An IPv4 address and that same address in IPv6 form are
+// considered to be equal.
+func (ip IP) Equal(x IP) bool {
+ if len(ip) == len(x) {
+ return bytealg.Equal(ip, x)
+ }
+ if len(ip) == IPv4len && len(x) == IPv6len {
+ return bytealg.Equal(x[0:12], v4InV6Prefix) && bytealg.Equal(ip, x[12:])
+ }
+ if len(ip) == IPv6len && len(x) == IPv4len {
+ return bytealg.Equal(ip[0:12], v4InV6Prefix) && bytealg.Equal(ip[12:], x)
+ }
+ return false
+}
+
+func (ip IP) matchAddrFamily(x IP) bool {
+ return ip.To4() != nil && x.To4() != nil || ip.To16() != nil && ip.To4() == nil && x.To16() != nil && x.To4() == nil
+}
+
+// If mask is a sequence of 1 bits followed by 0 bits,
+// return the number of 1 bits.
+func simpleMaskLength(mask IPMask) int {
+ var n int
+ for i, v := range mask {
+ if v == 0xff {
+ n += 8
+ continue
+ }
+ // found non-ff byte
+ // count 1 bits
+ for v&0x80 != 0 {
+ n++
+ v <<= 1
+ }
+ // rest must be 0 bits
+ if v != 0 {
+ return -1
+ }
+ for i++; i < len(mask); i++ {
+ if mask[i] != 0 {
+ return -1
+ }
+ }
+ break
+ }
+ return n
+}
+
+// Size returns the number of leading ones and total bits in the mask.
+// If the mask is not in the canonical form--ones followed by zeros--then
+// Size returns 0, 0.
+func (m IPMask) Size() (ones, bits int) {
+ ones, bits = simpleMaskLength(m), len(m)*8
+ if ones == -1 {
+ return 0, 0
+ }
+ return
+}
+
+// String returns the hexadecimal form of m, with no punctuation.
+func (m IPMask) String() string {
+ if len(m) == 0 {
+ return "<nil>"
+ }
+ return hexString(m)
+}
+
+func networkNumberAndMask(n *IPNet) (ip IP, m IPMask) {
+ if ip = n.IP.To4(); ip == nil {
+ ip = n.IP
+ if len(ip) != IPv6len {
+ return nil, nil
+ }
+ }
+ m = n.Mask
+ switch len(m) {
+ case IPv4len:
+ if len(ip) != IPv4len {
+ return nil, nil
+ }
+ case IPv6len:
+ if len(ip) == IPv4len {
+ m = m[12:]
+ }
+ default:
+ return nil, nil
+ }
+ return
+}
+
+// Contains reports whether the network includes ip.
+func (n *IPNet) Contains(ip IP) bool {
+ nn, m := networkNumberAndMask(n)
+ if x := ip.To4(); x != nil {
+ ip = x
+ }
+ l := len(ip)
+ if l != len(nn) {
+ return false
+ }
+ for i := 0; i < l; i++ {
+ if nn[i]&m[i] != ip[i]&m[i] {
+ return false
+ }
+ }
+ return true
+}
+
+// Network returns the address's network name, "ip+net".
+func (n *IPNet) Network() string { return "ip+net" }
+
+// String returns the CIDR notation of n like "192.0.2.0/24"
+// or "2001:db8::/48" as defined in RFC 4632 and RFC 4291.
+// If the mask is not in the canonical form, it returns the
+// string which consists of an IP address, followed by a slash
+// character and a mask expressed as hexadecimal form with no
+// punctuation like "198.51.100.0/c000ff00".
+func (n *IPNet) String() string {
+ if n == nil {
+ return "<nil>"
+ }
+ nn, m := networkNumberAndMask(n)
+ if nn == nil || m == nil {
+ return "<nil>"
+ }
+ l := simpleMaskLength(m)
+ if l == -1 {
+ return nn.String() + "/" + m.String()
+ }
+ return nn.String() + "/" + itoa.Uitoa(uint(l))
+}
+
+// ParseIP parses s as an IP address, returning the result.
+// The string s can be in IPv4 dotted decimal ("192.0.2.1"), IPv6
+// ("2001:db8::68"), or IPv4-mapped IPv6 ("::ffff:192.0.2.1") form.
+// If s is not a valid textual representation of an IP address,
+// ParseIP returns nil.
+func ParseIP(s string) IP {
+ if addr, valid := parseIP(s); valid {
+ return IP(addr[:])
+ }
+ return nil
+}
+
+func parseIP(s string) ([16]byte, bool) {
+ ip, err := netip.ParseAddr(s)
+ if err != nil || ip.Zone() != "" {
+ return [16]byte{}, false
+ }
+ return ip.As16(), true
+}
+
+// ParseCIDR parses s as a CIDR notation IP address and prefix length,
+// like "192.0.2.0/24" or "2001:db8::/32", as defined in
+// RFC 4632 and RFC 4291.
+//
+// It returns the IP address and the network implied by the IP and
+// prefix length.
+// For example, ParseCIDR("192.0.2.1/24") returns the IP address
+// 192.0.2.1 and the network 192.0.2.0/24.
+func ParseCIDR(s string) (IP, *IPNet, error) {
+ i := bytealg.IndexByteString(s, '/')
+ if i < 0 {
+ return nil, nil, &ParseError{Type: "CIDR address", Text: s}
+ }
+ addr, mask := s[:i], s[i+1:]
+
+ ipAddr, err := netip.ParseAddr(addr)
+ if err != nil || ipAddr.Zone() != "" {
+ return nil, nil, &ParseError{Type: "CIDR address", Text: s}
+ }
+
+ n, i, ok := dtoi(mask)
+ if !ok || i != len(mask) || n < 0 || n > ipAddr.BitLen() {
+ return nil, nil, &ParseError{Type: "CIDR address", Text: s}
+ }
+ m := CIDRMask(n, ipAddr.BitLen())
+ addr16 := ipAddr.As16()
+ return IP(addr16[:]), &IPNet{IP: IP(addr16[:]).Mask(m), Mask: m}, nil
+}
+
+func copyIP(x IP) IP {
+ y := make(IP, len(x))
+ copy(y, x)
+ return y
+}
diff --git a/contrib/go/_std_1.20/src/net/iprawsock.go b/contrib/go/_std_1.21/src/net/iprawsock.go
index f18331a1fd..f18331a1fd 100644
--- a/contrib/go/_std_1.20/src/net/iprawsock.go
+++ b/contrib/go/_std_1.21/src/net/iprawsock.go
diff --git a/contrib/go/_std_1.21/src/net/iprawsock_posix.go b/contrib/go/_std_1.21/src/net/iprawsock_posix.go
new file mode 100644
index 0000000000..59967eb923
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/iprawsock_posix.go
@@ -0,0 +1,159 @@
+// Copyright 2010 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package net
+
+import (
+ "context"
+ "syscall"
+)
+
+func sockaddrToIP(sa syscall.Sockaddr) Addr {
+ switch sa := sa.(type) {
+ case *syscall.SockaddrInet4:
+ return &IPAddr{IP: sa.Addr[0:]}
+ case *syscall.SockaddrInet6:
+ return &IPAddr{IP: sa.Addr[0:], Zone: zoneCache.name(int(sa.ZoneId))}
+ }
+ return nil
+}
+
+func (a *IPAddr) family() int {
+ if a == nil || len(a.IP) <= IPv4len {
+ return syscall.AF_INET
+ }
+ if a.IP.To4() != nil {
+ return syscall.AF_INET
+ }
+ return syscall.AF_INET6
+}
+
+func (a *IPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
+ if a == nil {
+ return nil, nil
+ }
+ return ipToSockaddr(family, a.IP, 0, a.Zone)
+}
+
+func (a *IPAddr) toLocal(net string) sockaddr {
+ return &IPAddr{loopbackIP(net), a.Zone}
+}
+
+func (c *IPConn) readFrom(b []byte) (int, *IPAddr, error) {
+ // TODO(cw,rsc): consider using readv if we know the family
+ // type to avoid the header trim/copy
+ var addr *IPAddr
+ n, sa, err := c.fd.readFrom(b)
+ switch sa := sa.(type) {
+ case *syscall.SockaddrInet4:
+ addr = &IPAddr{IP: sa.Addr[0:]}
+ n = stripIPv4Header(n, b)
+ case *syscall.SockaddrInet6:
+ addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneCache.name(int(sa.ZoneId))}
+ }
+ return n, addr, err
+}
+
+func stripIPv4Header(n int, b []byte) int {
+ if len(b) < 20 {
+ return n
+ }
+ l := int(b[0]&0x0f) << 2
+ if 20 > l || l > len(b) {
+ return n
+ }
+ if b[0]>>4 != 4 {
+ return n
+ }
+ copy(b, b[l:])
+ return n - l
+}
+
+func (c *IPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error) {
+ var sa syscall.Sockaddr
+ n, oobn, flags, sa, err = c.fd.readMsg(b, oob, 0)
+ switch sa := sa.(type) {
+ case *syscall.SockaddrInet4:
+ addr = &IPAddr{IP: sa.Addr[0:]}
+ case *syscall.SockaddrInet6:
+ addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneCache.name(int(sa.ZoneId))}
+ }
+ return
+}
+
+func (c *IPConn) writeTo(b []byte, addr *IPAddr) (int, error) {
+ if c.fd.isConnected {
+ return 0, ErrWriteToConnected
+ }
+ if addr == nil {
+ return 0, errMissingAddress
+ }
+ sa, err := addr.sockaddr(c.fd.family)
+ if err != nil {
+ return 0, err
+ }
+ return c.fd.writeTo(b, sa)
+}
+
+func (c *IPConn) writeMsg(b, oob []byte, addr *IPAddr) (n, oobn int, err error) {
+ if c.fd.isConnected {
+ return 0, 0, ErrWriteToConnected
+ }
+ if addr == nil {
+ return 0, 0, errMissingAddress
+ }
+ sa, err := addr.sockaddr(c.fd.family)
+ if err != nil {
+ return 0, 0, err
+ }
+ return c.fd.writeMsg(b, oob, sa)
+}
+
+func (sd *sysDialer) dialIP(ctx context.Context, laddr, raddr *IPAddr) (*IPConn, error) {
+ network, proto, err := parseNetwork(ctx, sd.network, true)
+ if err != nil {
+ return nil, err
+ }
+ switch network {
+ case "ip", "ip4", "ip6":
+ default:
+ return nil, UnknownNetworkError(sd.network)
+ }
+ ctrlCtxFn := sd.Dialer.ControlContext
+ if ctrlCtxFn == nil && sd.Dialer.Control != nil {
+ ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+ return sd.Dialer.Control(network, address, c)
+ }
+ }
+ fd, err := internetSocket(ctx, network, laddr, raddr, syscall.SOCK_RAW, proto, "dial", ctrlCtxFn)
+ if err != nil {
+ return nil, err
+ }
+ return newIPConn(fd), nil
+}
+
+func (sl *sysListener) listenIP(ctx context.Context, laddr *IPAddr) (*IPConn, error) {
+ network, proto, err := parseNetwork(ctx, sl.network, true)
+ if err != nil {
+ return nil, err
+ }
+ switch network {
+ case "ip", "ip4", "ip6":
+ default:
+ return nil, UnknownNetworkError(sl.network)
+ }
+ var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
+ if sl.ListenConfig.Control != nil {
+ ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+ return sl.ListenConfig.Control(network, address, c)
+ }
+ }
+ fd, err := internetSocket(ctx, network, laddr, nil, syscall.SOCK_RAW, proto, "listen", ctrlCtxFn)
+ if err != nil {
+ return nil, err
+ }
+ return newIPConn(fd), nil
+}
diff --git a/contrib/go/_std_1.20/src/net/ipsock.go b/contrib/go/_std_1.21/src/net/ipsock.go
index 0f5da2577c..0f5da2577c 100644
--- a/contrib/go/_std_1.20/src/net/ipsock.go
+++ b/contrib/go/_std_1.21/src/net/ipsock.go
diff --git a/contrib/go/_std_1.21/src/net/ipsock_posix.go b/contrib/go/_std_1.21/src/net/ipsock_posix.go
new file mode 100644
index 0000000000..b0a00a6296
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/ipsock_posix.go
@@ -0,0 +1,232 @@
+// Copyright 2009 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package net
+
+import (
+ "context"
+ "internal/poll"
+ "net/netip"
+ "runtime"
+ "syscall"
+)
+
+// probe probes IPv4, IPv6 and IPv4-mapped IPv6 communication
+// capabilities which are controlled by the IPV6_V6ONLY socket option
+// and kernel configuration.
+//
+// Should we try to use the IPv4 socket interface if we're only
+// dealing with IPv4 sockets? As long as the host system understands
+// IPv4-mapped IPv6, it's okay to pass IPv4-mapped IPv6 addresses to
+// the IPv6 interface. That simplifies our code and is most
+// general. Unfortunately, we need to run on kernels built without
+// IPv6 support too. So probe the kernel to figure it out.
+func (p *ipStackCapabilities) probe() {
+ s, err := sysSocket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+ switch err {
+ case syscall.EAFNOSUPPORT, syscall.EPROTONOSUPPORT:
+ case nil:
+ poll.CloseFunc(s)
+ p.ipv4Enabled = true
+ }
+ var probes = []struct {
+ laddr TCPAddr
+ value int
+ }{
+ // IPv6 communication capability
+ {laddr: TCPAddr{IP: ParseIP("::1")}, value: 1},
+ // IPv4-mapped IPv6 address communication capability
+ {laddr: TCPAddr{IP: IPv4(127, 0, 0, 1)}, value: 0},
+ }
+ switch runtime.GOOS {
+ case "dragonfly", "openbsd":
+ // The latest DragonFly BSD and OpenBSD kernels don't
+ // support IPV6_V6ONLY=0. They always return an error
+ // and we don't need to probe the capability.
+ probes = probes[:1]
+ }
+ for i := range probes {
+ s, err := sysSocket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+ if err != nil {
+ continue
+ }
+ defer poll.CloseFunc(s)
+ syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, probes[i].value)
+ sa, err := probes[i].laddr.sockaddr(syscall.AF_INET6)
+ if err != nil {
+ continue
+ }
+ if err := syscall.Bind(s, sa); err != nil {
+ continue
+ }
+ if i == 0 {
+ p.ipv6Enabled = true
+ } else {
+ p.ipv4MappedIPv6Enabled = true
+ }
+ }
+}
+
+// favoriteAddrFamily returns the appropriate address family for the
+// given network, laddr, raddr and mode.
+//
+// If mode indicates "listen" and laddr is a wildcard, we assume that
+// the user wants to make a passive-open connection with a wildcard
+// address family, both AF_INET and AF_INET6, and a wildcard address
+// like the following:
+//
+// - A listen for a wildcard communication domain, "tcp" or
+// "udp", with a wildcard address: If the platform supports
+// both IPv6 and IPv4-mapped IPv6 communication capabilities,
+// or does not support IPv4, we use a dual stack, AF_INET6 and
+// IPV6_V6ONLY=0, wildcard address listen. The dual stack
+// wildcard address listen may fall back to an IPv6-only,
+// AF_INET6 and IPV6_V6ONLY=1, wildcard address listen.
+// Otherwise we prefer an IPv4-only, AF_INET, wildcard address
+// listen.
+//
+// - A listen for a wildcard communication domain, "tcp" or
+// "udp", with an IPv4 wildcard address: same as above.
+//
+// - A listen for a wildcard communication domain, "tcp" or
+// "udp", with an IPv6 wildcard address: same as above.
+//
+// - A listen for an IPv4 communication domain, "tcp4" or "udp4",
+// with an IPv4 wildcard address: We use an IPv4-only, AF_INET,
+// wildcard address listen.
+//
+// - A listen for an IPv6 communication domain, "tcp6" or "udp6",
+// with an IPv6 wildcard address: We use an IPv6-only, AF_INET6
+// and IPV6_V6ONLY=1, wildcard address listen.
+//
+// Otherwise guess: If the addresses are IPv4 then returns AF_INET,
+// or else returns AF_INET6. It also returns a boolean value what
+// designates IPV6_V6ONLY option.
+//
+// Note that the latest DragonFly BSD and OpenBSD kernels allow
+// neither "net.inet6.ip6.v6only=1" change nor IPPROTO_IPV6 level
+// IPV6_V6ONLY socket option setting.
+func favoriteAddrFamily(network string, laddr, raddr sockaddr, mode string) (family int, ipv6only bool) {
+ switch network[len(network)-1] {
+ case '4':
+ return syscall.AF_INET, false
+ case '6':
+ return syscall.AF_INET6, true
+ }
+
+ if mode == "listen" && (laddr == nil || laddr.isWildcard()) {
+ if supportsIPv4map() || !supportsIPv4() {
+ return syscall.AF_INET6, false
+ }
+ if laddr == nil {
+ return syscall.AF_INET, false
+ }
+ return laddr.family(), false
+ }
+
+ if (laddr == nil || laddr.family() == syscall.AF_INET) &&
+ (raddr == nil || raddr.family() == syscall.AF_INET) {
+ return syscall.AF_INET, false
+ }
+ return syscall.AF_INET6, false
+}
+
+func internetSocket(ctx context.Context, net string, laddr, raddr sockaddr, sotype, proto int, mode string, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) (fd *netFD, err error) {
+ if (runtime.GOOS == "aix" || runtime.GOOS == "windows" || runtime.GOOS == "openbsd") && mode == "dial" && raddr.isWildcard() {
+ raddr = raddr.toLocal(net)
+ }
+ family, ipv6only := favoriteAddrFamily(net, laddr, raddr, mode)
+ return socket(ctx, net, family, sotype, proto, ipv6only, laddr, raddr, ctrlCtxFn)
+}
+
+func ipToSockaddrInet4(ip IP, port int) (syscall.SockaddrInet4, error) {
+ if len(ip) == 0 {
+ ip = IPv4zero
+ }
+ ip4 := ip.To4()
+ if ip4 == nil {
+ return syscall.SockaddrInet4{}, &AddrError{Err: "non-IPv4 address", Addr: ip.String()}
+ }
+ sa := syscall.SockaddrInet4{Port: port}
+ copy(sa.Addr[:], ip4)
+ return sa, nil
+}
+
+func ipToSockaddrInet6(ip IP, port int, zone string) (syscall.SockaddrInet6, error) {
+ // In general, an IP wildcard address, which is either
+ // "0.0.0.0" or "::", means the entire IP addressing
+ // space. For some historical reason, it is used to
+ // specify "any available address" on some operations
+ // of IP node.
+ //
+ // When the IP node supports IPv4-mapped IPv6 address,
+ // we allow a listener to listen to the wildcard
+ // address of both IP addressing spaces by specifying
+ // IPv6 wildcard address.
+ if len(ip) == 0 || ip.Equal(IPv4zero) {
+ ip = IPv6zero
+ }
+ // We accept any IPv6 address including IPv4-mapped
+ // IPv6 address.
+ ip6 := ip.To16()
+ if ip6 == nil {
+ return syscall.SockaddrInet6{}, &AddrError{Err: "non-IPv6 address", Addr: ip.String()}
+ }
+ sa := syscall.SockaddrInet6{Port: port, ZoneId: uint32(zoneCache.index(zone))}
+ copy(sa.Addr[:], ip6)
+ return sa, nil
+}
+
+func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, error) {
+ switch family {
+ case syscall.AF_INET:
+ sa, err := ipToSockaddrInet4(ip, port)
+ if err != nil {
+ return nil, err
+ }
+ return &sa, nil
+ case syscall.AF_INET6:
+ sa, err := ipToSockaddrInet6(ip, port, zone)
+ if err != nil {
+ return nil, err
+ }
+ return &sa, nil
+ }
+ return nil, &AddrError{Err: "invalid address family", Addr: ip.String()}
+}
+
+func addrPortToSockaddrInet4(ap netip.AddrPort) (syscall.SockaddrInet4, error) {
+ // ipToSockaddrInet4 has special handling here for zero length slices.
+ // We do not, because netip has no concept of a generic zero IP address.
+ addr := ap.Addr()
+ if !addr.Is4() {
+ return syscall.SockaddrInet4{}, &AddrError{Err: "non-IPv4 address", Addr: addr.String()}
+ }
+ sa := syscall.SockaddrInet4{
+ Addr: addr.As4(),
+ Port: int(ap.Port()),
+ }
+ return sa, nil
+}
+
+func addrPortToSockaddrInet6(ap netip.AddrPort) (syscall.SockaddrInet6, error) {
+ // ipToSockaddrInet6 has special handling here for zero length slices.
+ // We do not, because netip has no concept of a generic zero IP address.
+ //
+ // addr is allowed to be an IPv4 address, because As16 will convert it
+ // to an IPv4-mapped IPv6 address.
+ // The error message is kept consistent with ipToSockaddrInet6.
+ addr := ap.Addr()
+ if !addr.IsValid() {
+ return syscall.SockaddrInet6{}, &AddrError{Err: "non-IPv6 address", Addr: addr.String()}
+ }
+ sa := syscall.SockaddrInet6{
+ Addr: addr.As16(),
+ Port: int(ap.Port()),
+ ZoneId: uint32(zoneCache.index(addr.Zone())),
+ }
+ return sa, nil
+}
diff --git a/contrib/go/_std_1.21/src/net/lookup.go b/contrib/go/_std_1.21/src/net/lookup.go
new file mode 100644
index 0000000000..a7133b53ac
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/lookup.go
@@ -0,0 +1,908 @@
+// Copyright 2012 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 net
+
+import (
+ "context"
+ "errors"
+ "internal/nettrace"
+ "internal/singleflight"
+ "net/netip"
+ "sync"
+
+ "golang.org/x/net/dns/dnsmessage"
+)
+
+// protocols contains minimal mappings between internet protocol
+// names and numbers for platforms that don't have a complete list of
+// protocol numbers.
+//
+// See https://www.iana.org/assignments/protocol-numbers
+//
+// On Unix, this map is augmented by readProtocols via lookupProtocol.
+var protocols = map[string]int{
+ "icmp": 1,
+ "igmp": 2,
+ "tcp": 6,
+ "udp": 17,
+ "ipv6-icmp": 58,
+}
+
+// services contains minimal mappings between services names and port
+// numbers for platforms that don't have a complete list of port numbers.
+//
+// See https://www.iana.org/assignments/service-names-port-numbers
+//
+// On Unix, this map is augmented by readServices via goLookupPort.
+var services = map[string]map[string]int{
+ "udp": {
+ "domain": 53,
+ },
+ "tcp": {
+ "ftp": 21,
+ "ftps": 990,
+ "gopher": 70, // ʕ◔ϖ◔ʔ
+ "http": 80,
+ "https": 443,
+ "imap2": 143,
+ "imap3": 220,
+ "imaps": 993,
+ "pop3": 110,
+ "pop3s": 995,
+ "smtp": 25,
+ "ssh": 22,
+ "telnet": 23,
+ },
+}
+
+// dnsWaitGroup can be used by tests to wait for all DNS goroutines to
+// complete. This avoids races on the test hooks.
+var dnsWaitGroup sync.WaitGroup
+
+const maxProtoLength = len("RSVP-E2E-IGNORE") + 10 // with room to grow
+
+func lookupProtocolMap(name string) (int, error) {
+ var lowerProtocol [maxProtoLength]byte
+ n := copy(lowerProtocol[:], name)
+ lowerASCIIBytes(lowerProtocol[:n])
+ proto, found := protocols[string(lowerProtocol[:n])]
+ if !found || n != len(name) {
+ return 0, &AddrError{Err: "unknown IP protocol specified", Addr: name}
+ }
+ return proto, nil
+}
+
+// maxPortBufSize is the longest reasonable name of a service
+// (non-numeric port).
+// Currently the longest known IANA-unregistered name is
+// "mobility-header", so we use that length, plus some slop in case
+// something longer is added in the future.
+const maxPortBufSize = len("mobility-header") + 10
+
+func lookupPortMap(network, service string) (port int, error error) {
+ switch network {
+ case "tcp4", "tcp6":
+ network = "tcp"
+ case "udp4", "udp6":
+ network = "udp"
+ }
+
+ if m, ok := services[network]; ok {
+ var lowerService [maxPortBufSize]byte
+ n := copy(lowerService[:], service)
+ lowerASCIIBytes(lowerService[:n])
+ if port, ok := m[string(lowerService[:n])]; ok && n == len(service) {
+ return port, nil
+ }
+ }
+ return 0, &AddrError{Err: "unknown port", Addr: network + "/" + service}
+}
+
+// ipVersion returns the provided network's IP version: '4', '6' or 0
+// if network does not end in a '4' or '6' byte.
+func ipVersion(network string) byte {
+ if network == "" {
+ return 0
+ }
+ n := network[len(network)-1]
+ if n != '4' && n != '6' {
+ n = 0
+ }
+ return n
+}
+
+// DefaultResolver is the resolver used by the package-level Lookup
+// functions and by Dialers without a specified Resolver.
+var DefaultResolver = &Resolver{}
+
+// A Resolver looks up names and numbers.
+//
+// A nil *Resolver is equivalent to a zero Resolver.
+type Resolver struct {
+ // PreferGo controls whether Go's built-in DNS resolver is preferred
+ // on platforms where it's available. It is equivalent to setting
+ // GODEBUG=netdns=go, but scoped to just this resolver.
+ PreferGo bool
+
+ // StrictErrors controls the behavior of temporary errors
+ // (including timeout, socket errors, and SERVFAIL) when using
+ // Go's built-in resolver. For a query composed of multiple
+ // sub-queries (such as an A+AAAA address lookup, or walking the
+ // DNS search list), this option causes such errors to abort the
+ // whole query instead of returning a partial result. This is
+ // not enabled by default because it may affect compatibility
+ // with resolvers that process AAAA queries incorrectly.
+ StrictErrors bool
+
+ // Dial optionally specifies an alternate dialer for use by
+ // Go's built-in DNS resolver to make TCP and UDP connections
+ // to DNS services. The host in the address parameter will
+ // always be a literal IP address and not a host name, and the
+ // port in the address parameter will be a literal port number
+ // and not a service name.
+ // If the Conn returned is also a PacketConn, sent and received DNS
+ // messages must adhere to RFC 1035 section 4.2.1, "UDP usage".
+ // Otherwise, DNS messages transmitted over Conn must adhere
+ // to RFC 7766 section 5, "Transport Protocol Selection".
+ // If nil, the default dialer is used.
+ Dial func(ctx context.Context, network, address string) (Conn, error)
+
+ // lookupGroup merges LookupIPAddr calls together for lookups for the same
+ // host. The lookupGroup key is the LookupIPAddr.host argument.
+ // The return values are ([]IPAddr, error).
+ lookupGroup singleflight.Group
+
+ // TODO(bradfitz): optional interface impl override hook
+ // TODO(bradfitz): Timeout time.Duration?
+}
+
+func (r *Resolver) preferGo() bool { return r != nil && r.PreferGo }
+func (r *Resolver) strictErrors() bool { return r != nil && r.StrictErrors }
+
+func (r *Resolver) getLookupGroup() *singleflight.Group {
+ if r == nil {
+ return &DefaultResolver.lookupGroup
+ }
+ return &r.lookupGroup
+}
+
+// LookupHost looks up the given host using the local resolver.
+// It returns a slice of that host's addresses.
+//
+// LookupHost uses context.Background internally; to specify the context, use
+// Resolver.LookupHost.
+func LookupHost(host string) (addrs []string, err error) {
+ return DefaultResolver.LookupHost(context.Background(), host)
+}
+
+// LookupHost looks up the given host using the local resolver.
+// It returns a slice of that host's addresses.
+func (r *Resolver) LookupHost(ctx context.Context, host string) (addrs []string, err error) {
+ // Make sure that no matter what we do later, host=="" is rejected.
+ if host == "" {
+ return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host, IsNotFound: true}
+ }
+ if _, err := netip.ParseAddr(host); err == nil {
+ return []string{host}, nil
+ }
+ return r.lookupHost(ctx, host)
+}
+
+// LookupIP looks up host using the local resolver.
+// It returns a slice of that host's IPv4 and IPv6 addresses.
+func LookupIP(host string) ([]IP, error) {
+ addrs, err := DefaultResolver.LookupIPAddr(context.Background(), host)
+ if err != nil {
+ return nil, err
+ }
+ ips := make([]IP, len(addrs))
+ for i, ia := range addrs {
+ ips[i] = ia.IP
+ }
+ return ips, nil
+}
+
+// LookupIPAddr looks up host using the local resolver.
+// It returns a slice of that host's IPv4 and IPv6 addresses.
+func (r *Resolver) LookupIPAddr(ctx context.Context, host string) ([]IPAddr, error) {
+ return r.lookupIPAddr(ctx, "ip", host)
+}
+
+// LookupIP looks up host for the given network using the local resolver.
+// It returns a slice of that host's IP addresses of the type specified by
+// network.
+// network must be one of "ip", "ip4" or "ip6".
+func (r *Resolver) LookupIP(ctx context.Context, network, host string) ([]IP, error) {
+ afnet, _, err := parseNetwork(ctx, network, false)
+ if err != nil {
+ return nil, err
+ }
+ switch afnet {
+ case "ip", "ip4", "ip6":
+ default:
+ return nil, UnknownNetworkError(network)
+ }
+
+ if host == "" {
+ return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host, IsNotFound: true}
+ }
+ addrs, err := r.internetAddrList(ctx, afnet, host)
+ if err != nil {
+ return nil, err
+ }
+
+ ips := make([]IP, 0, len(addrs))
+ for _, addr := range addrs {
+ ips = append(ips, addr.(*IPAddr).IP)
+ }
+ return ips, nil
+}
+
+// LookupNetIP looks up host using the local resolver.
+// It returns a slice of that host's IP addresses of the type specified by
+// network.
+// The network must be one of "ip", "ip4" or "ip6".
+func (r *Resolver) LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, error) {
+ // TODO(bradfitz): make this efficient, making the internal net package
+ // type throughout be netip.Addr and only converting to the net.IP slice
+ // version at the edge. But for now (2021-10-20), this is a wrapper around
+ // the old way.
+ ips, err := r.LookupIP(ctx, network, host)
+ if err != nil {
+ return nil, err
+ }
+ ret := make([]netip.Addr, 0, len(ips))
+ for _, ip := range ips {
+ if a, ok := netip.AddrFromSlice(ip); ok {
+ ret = append(ret, a)
+ }
+ }
+ return ret, nil
+}
+
+// onlyValuesCtx is a context that uses an underlying context
+// for value lookup if the underlying context hasn't yet expired.
+type onlyValuesCtx struct {
+ context.Context
+ lookupValues context.Context
+}
+
+var _ context.Context = (*onlyValuesCtx)(nil)
+
+// Value performs a lookup if the original context hasn't expired.
+func (ovc *onlyValuesCtx) Value(key any) any {
+ select {
+ case <-ovc.lookupValues.Done():
+ return nil
+ default:
+ return ovc.lookupValues.Value(key)
+ }
+}
+
+// withUnexpiredValuesPreserved returns a context.Context that only uses lookupCtx
+// for its values, otherwise it is never canceled and has no deadline.
+// If the lookup context expires, any looked up values will return nil.
+// See Issue 28600.
+func withUnexpiredValuesPreserved(lookupCtx context.Context) context.Context {
+ return &onlyValuesCtx{Context: context.Background(), lookupValues: lookupCtx}
+}
+
+// lookupIPAddr looks up host using the local resolver and particular network.
+// It returns a slice of that host's IPv4 and IPv6 addresses.
+func (r *Resolver) lookupIPAddr(ctx context.Context, network, host string) ([]IPAddr, error) {
+ // Make sure that no matter what we do later, host=="" is rejected.
+ if host == "" {
+ return nil, &DNSError{Err: errNoSuchHost.Error(), Name: host, IsNotFound: true}
+ }
+ if ip, err := netip.ParseAddr(host); err == nil {
+ return []IPAddr{{IP: IP(ip.AsSlice()).To16(), Zone: ip.Zone()}}, nil
+ }
+ trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace)
+ if trace != nil && trace.DNSStart != nil {
+ trace.DNSStart(host)
+ }
+ // The underlying resolver func is lookupIP by default but it
+ // can be overridden by tests. This is needed by net/http, so it
+ // uses a context key instead of unexported variables.
+ resolverFunc := r.lookupIP
+ if alt, _ := ctx.Value(nettrace.LookupIPAltResolverKey{}).(func(context.Context, string, string) ([]IPAddr, error)); alt != nil {
+ resolverFunc = alt
+ }
+
+ // We don't want a cancellation of ctx to affect the
+ // lookupGroup operation. Otherwise if our context gets
+ // canceled it might cause an error to be returned to a lookup
+ // using a completely different context. However we need to preserve
+ // only the values in context. See Issue 28600.
+ lookupGroupCtx, lookupGroupCancel := context.WithCancel(withUnexpiredValuesPreserved(ctx))
+
+ lookupKey := network + "\000" + host
+ dnsWaitGroup.Add(1)
+ ch := r.getLookupGroup().DoChan(lookupKey, func() (any, error) {
+ return testHookLookupIP(lookupGroupCtx, resolverFunc, network, host)
+ })
+
+ dnsWaitGroupDone := func(ch <-chan singleflight.Result, cancelFn context.CancelFunc) {
+ <-ch
+ dnsWaitGroup.Done()
+ cancelFn()
+ }
+ select {
+ case <-ctx.Done():
+ // Our context was canceled. If we are the only
+ // goroutine looking up this key, then drop the key
+ // from the lookupGroup and cancel the lookup.
+ // If there are other goroutines looking up this key,
+ // let the lookup continue uncanceled, and let later
+ // lookups with the same key share the result.
+ // See issues 8602, 20703, 22724.
+ if r.getLookupGroup().ForgetUnshared(lookupKey) {
+ lookupGroupCancel()
+ go dnsWaitGroupDone(ch, func() {})
+ } else {
+ go dnsWaitGroupDone(ch, lookupGroupCancel)
+ }
+ ctxErr := ctx.Err()
+ err := &DNSError{
+ Err: mapErr(ctxErr).Error(),
+ Name: host,
+ IsTimeout: ctxErr == context.DeadlineExceeded,
+ }
+ if trace != nil && trace.DNSDone != nil {
+ trace.DNSDone(nil, false, err)
+ }
+ return nil, err
+ case r := <-ch:
+ dnsWaitGroup.Done()
+ lookupGroupCancel()
+ err := r.Err
+ if err != nil {
+ if _, ok := err.(*DNSError); !ok {
+ isTimeout := false
+ if err == context.DeadlineExceeded {
+ isTimeout = true
+ } else if terr, ok := err.(timeout); ok {
+ isTimeout = terr.Timeout()
+ }
+ err = &DNSError{
+ Err: err.Error(),
+ Name: host,
+ IsTimeout: isTimeout,
+ }
+ }
+ }
+ if trace != nil && trace.DNSDone != nil {
+ addrs, _ := r.Val.([]IPAddr)
+ trace.DNSDone(ipAddrsEface(addrs), r.Shared, err)
+ }
+ return lookupIPReturn(r.Val, err, r.Shared)
+ }
+}
+
+// lookupIPReturn turns the return values from singleflight.Do into
+// the return values from LookupIP.
+func lookupIPReturn(addrsi any, err error, shared bool) ([]IPAddr, error) {
+ if err != nil {
+ return nil, err
+ }
+ addrs := addrsi.([]IPAddr)
+ if shared {
+ clone := make([]IPAddr, len(addrs))
+ copy(clone, addrs)
+ addrs = clone
+ }
+ return addrs, nil
+}
+
+// ipAddrsEface returns an empty interface slice of addrs.
+func ipAddrsEface(addrs []IPAddr) []any {
+ s := make([]any, len(addrs))
+ for i, v := range addrs {
+ s[i] = v
+ }
+ return s
+}
+
+// LookupPort looks up the port for the given network and service.
+//
+// LookupPort uses context.Background internally; to specify the context, use
+// Resolver.LookupPort.
+func LookupPort(network, service string) (port int, err error) {
+ return DefaultResolver.LookupPort(context.Background(), network, service)
+}
+
+// LookupPort looks up the port for the given network and service.
+func (r *Resolver) LookupPort(ctx context.Context, network, service string) (port int, err error) {
+ port, needsLookup := parsePort(service)
+ if needsLookup {
+ switch network {
+ case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
+ case "": // a hint wildcard for Go 1.0 undocumented behavior
+ network = "ip"
+ default:
+ return 0, &AddrError{Err: "unknown network", Addr: network}
+ }
+ port, err = r.lookupPort(ctx, network, service)
+ if err != nil {
+ return 0, err
+ }
+ }
+ if 0 > port || port > 65535 {
+ return 0, &AddrError{Err: "invalid port", Addr: service}
+ }
+ return port, nil
+}
+
+// LookupCNAME returns the canonical name for the given host.
+// Callers that do not care about the canonical name can call
+// LookupHost or LookupIP directly; both take care of resolving
+// the canonical name as part of the lookup.
+//
+// A canonical name is the final name after following zero
+// or more CNAME records.
+// LookupCNAME does not return an error if host does not
+// contain DNS "CNAME" records, as long as host resolves to
+// address records.
+//
+// The returned canonical name is validated to be a properly
+// formatted presentation-format domain name.
+//
+// LookupCNAME uses context.Background internally; to specify the context, use
+// Resolver.LookupCNAME.
+func LookupCNAME(host string) (cname string, err error) {
+ return DefaultResolver.LookupCNAME(context.Background(), host)
+}
+
+// LookupCNAME returns the canonical name for the given host.
+// Callers that do not care about the canonical name can call
+// LookupHost or LookupIP directly; both take care of resolving
+// the canonical name as part of the lookup.
+//
+// A canonical name is the final name after following zero
+// or more CNAME records.
+// LookupCNAME does not return an error if host does not
+// contain DNS "CNAME" records, as long as host resolves to
+// address records.
+//
+// The returned canonical name is validated to be a properly
+// formatted presentation-format domain name.
+func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error) {
+ cname, err := r.lookupCNAME(ctx, host)
+ if err != nil {
+ return "", err
+ }
+ if !isDomainName(cname) {
+ return "", &DNSError{Err: errMalformedDNSRecordsDetail, Name: host}
+ }
+ return cname, nil
+}
+
+// LookupSRV tries to resolve an SRV query of the given service,
+// protocol, and domain name. The proto is "tcp" or "udp".
+// The returned records are sorted by priority and randomized
+// by weight within a priority.
+//
+// LookupSRV constructs the DNS name to look up following RFC 2782.
+// That is, it looks up _service._proto.name. To accommodate services
+// publishing SRV records under non-standard names, if both service
+// and proto are empty strings, LookupSRV looks up name directly.
+//
+// The returned service names are validated to be properly
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the remaining results, if any.
+func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
+ return DefaultResolver.LookupSRV(context.Background(), service, proto, name)
+}
+
+// LookupSRV tries to resolve an SRV query of the given service,
+// protocol, and domain name. The proto is "tcp" or "udp".
+// The returned records are sorted by priority and randomized
+// by weight within a priority.
+//
+// LookupSRV constructs the DNS name to look up following RFC 2782.
+// That is, it looks up _service._proto.name. To accommodate services
+// publishing SRV records under non-standard names, if both service
+// and proto are empty strings, LookupSRV looks up name directly.
+//
+// The returned service names are validated to be properly
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the remaining results, if any.
+func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
+ cname, addrs, err := r.lookupSRV(ctx, service, proto, name)
+ if err != nil {
+ return "", nil, err
+ }
+ if cname != "" && !isDomainName(cname) {
+ return "", nil, &DNSError{Err: "SRV header name is invalid", Name: name}
+ }
+ filteredAddrs := make([]*SRV, 0, len(addrs))
+ for _, addr := range addrs {
+ if addr == nil {
+ continue
+ }
+ if !isDomainName(addr.Target) {
+ continue
+ }
+ filteredAddrs = append(filteredAddrs, addr)
+ }
+ if len(addrs) != len(filteredAddrs) {
+ return cname, filteredAddrs, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
+ }
+ return cname, filteredAddrs, nil
+}
+
+// LookupMX returns the DNS MX records for the given domain name sorted by preference.
+//
+// The returned mail server names are validated to be properly
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the remaining results, if any.
+//
+// LookupMX uses context.Background internally; to specify the context, use
+// Resolver.LookupMX.
+func LookupMX(name string) ([]*MX, error) {
+ return DefaultResolver.LookupMX(context.Background(), name)
+}
+
+// LookupMX returns the DNS MX records for the given domain name sorted by preference.
+//
+// The returned mail server names are validated to be properly
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the remaining results, if any.
+func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) {
+ records, err := r.lookupMX(ctx, name)
+ if err != nil {
+ return nil, err
+ }
+ filteredMX := make([]*MX, 0, len(records))
+ for _, mx := range records {
+ if mx == nil {
+ continue
+ }
+ if !isDomainName(mx.Host) {
+ continue
+ }
+ filteredMX = append(filteredMX, mx)
+ }
+ if len(records) != len(filteredMX) {
+ return filteredMX, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
+ }
+ return filteredMX, nil
+}
+
+// LookupNS returns the DNS NS records for the given domain name.
+//
+// The returned name server names are validated to be properly
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the remaining results, if any.
+//
+// LookupNS uses context.Background internally; to specify the context, use
+// Resolver.LookupNS.
+func LookupNS(name string) ([]*NS, error) {
+ return DefaultResolver.LookupNS(context.Background(), name)
+}
+
+// LookupNS returns the DNS NS records for the given domain name.
+//
+// The returned name server names are validated to be properly
+// formatted presentation-format domain names. If the response contains
+// invalid names, those records are filtered out and an error
+// will be returned alongside the remaining results, if any.
+func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*NS, error) {
+ records, err := r.lookupNS(ctx, name)
+ if err != nil {
+ return nil, err
+ }
+ filteredNS := make([]*NS, 0, len(records))
+ for _, ns := range records {
+ if ns == nil {
+ continue
+ }
+ if !isDomainName(ns.Host) {
+ continue
+ }
+ filteredNS = append(filteredNS, ns)
+ }
+ if len(records) != len(filteredNS) {
+ return filteredNS, &DNSError{Err: errMalformedDNSRecordsDetail, Name: name}
+ }
+ return filteredNS, nil
+}
+
+// LookupTXT returns the DNS TXT records for the given domain name.
+//
+// LookupTXT uses context.Background internally; to specify the context, use
+// Resolver.LookupTXT.
+func LookupTXT(name string) ([]string, error) {
+ return DefaultResolver.lookupTXT(context.Background(), name)
+}
+
+// LookupTXT returns the DNS TXT records for the given domain name.
+func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, error) {
+ return r.lookupTXT(ctx, name)
+}
+
+// LookupAddr performs a reverse lookup for the given address, returning a list
+// of names mapping to that address.
+//
+// The returned names are validated to be properly formatted presentation-format
+// domain names. If the response contains invalid names, those records are filtered
+// out and an error will be returned alongside the remaining results, if any.
+//
+// When using the host C library resolver, at most one result will be
+// returned. To bypass the host resolver, use a custom Resolver.
+//
+// LookupAddr uses context.Background internally; to specify the context, use
+// Resolver.LookupAddr.
+func LookupAddr(addr string) (names []string, err error) {
+ return DefaultResolver.LookupAddr(context.Background(), addr)
+}
+
+// LookupAddr performs a reverse lookup for the given address, returning a list
+// of names mapping to that address.
+//
+// The returned names are validated to be properly formatted presentation-format
+// domain names. If the response contains invalid names, those records are filtered
+// out and an error will be returned alongside the remaining results, if any.
+func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error) {
+ names, err := r.lookupAddr(ctx, addr)
+ if err != nil {
+ return nil, err
+ }
+ filteredNames := make([]string, 0, len(names))
+ for _, name := range names {
+ if isDomainName(name) {
+ filteredNames = append(filteredNames, name)
+ }
+ }
+ if len(names) != len(filteredNames) {
+ return filteredNames, &DNSError{Err: errMalformedDNSRecordsDetail, Name: addr}
+ }
+ return filteredNames, nil
+}
+
+// errMalformedDNSRecordsDetail is the DNSError detail which is returned when a Resolver.Lookup...
+// method receives DNS records which contain invalid DNS names. This may be returned alongside
+// results which have had the malformed records filtered out.
+var errMalformedDNSRecordsDetail = "DNS response contained records which contain invalid names"
+
+// dial makes a new connection to the provided server (which must be
+// an IP address) with the provided network type, using either r.Dial
+// (if both r and r.Dial are non-nil) or else Dialer.DialContext.
+func (r *Resolver) dial(ctx context.Context, network, server string) (Conn, error) {
+ // Calling Dial here is scary -- we have to be sure not to
+ // dial a name that will require a DNS lookup, or Dial will
+ // call back here to translate it. The DNS config parser has
+ // already checked that all the cfg.servers are IP
+ // addresses, which Dial will use without a DNS lookup.
+ var c Conn
+ var err error
+ if r != nil && r.Dial != nil {
+ c, err = r.Dial(ctx, network, server)
+ } else {
+ var d Dialer
+ c, err = d.DialContext(ctx, network, server)
+ }
+ if err != nil {
+ return nil, mapErr(err)
+ }
+ return c, nil
+}
+
+// goLookupSRV returns the SRV records for a target name, built either
+// from its component service ("sip"), protocol ("tcp"), and name
+// ("example.com."), or from name directly (if service and proto are
+// both empty).
+//
+// In either case, the returned target name ("_sip._tcp.example.com.")
+// is also returned on success.
+//
+// The records are sorted by weight.
+func (r *Resolver) goLookupSRV(ctx context.Context, service, proto, name string) (target string, srvs []*SRV, err error) {
+ if service == "" && proto == "" {
+ target = name
+ } else {
+ target = "_" + service + "._" + proto + "." + name
+ }
+ p, server, err := r.lookup(ctx, target, dnsmessage.TypeSRV, nil)
+ if err != nil {
+ return "", nil, err
+ }
+ var cname dnsmessage.Name
+ for {
+ h, err := p.AnswerHeader()
+ if err == dnsmessage.ErrSectionDone {
+ break
+ }
+ if err != nil {
+ return "", nil, &DNSError{
+ Err: "cannot unmarshal DNS message",
+ Name: name,
+ Server: server,
+ }
+ }
+ if h.Type != dnsmessage.TypeSRV {
+ if err := p.SkipAnswer(); err != nil {
+ return "", nil, &DNSError{
+ Err: "cannot unmarshal DNS message",
+ Name: name,
+ Server: server,
+ }
+ }
+ continue
+ }
+ if cname.Length == 0 && h.Name.Length != 0 {
+ cname = h.Name
+ }
+ srv, err := p.SRVResource()
+ if err != nil {
+ return "", nil, &DNSError{
+ Err: "cannot unmarshal DNS message",
+ Name: name,
+ Server: server,
+ }
+ }
+ srvs = append(srvs, &SRV{Target: srv.Target.String(), Port: srv.Port, Priority: srv.Priority, Weight: srv.Weight})
+ }
+ byPriorityWeight(srvs).sort()
+ return cname.String(), srvs, nil
+}
+
+// goLookupMX returns the MX records for name.
+func (r *Resolver) goLookupMX(ctx context.Context, name string) ([]*MX, error) {
+ p, server, err := r.lookup(ctx, name, dnsmessage.TypeMX, nil)
+ if err != nil {
+ return nil, err
+ }
+ var mxs []*MX
+ for {
+ h, err := p.AnswerHeader()
+ if err == dnsmessage.ErrSectionDone {
+ break
+ }
+ if err != nil {
+ return nil, &DNSError{
+ Err: "cannot unmarshal DNS message",
+ Name: name,
+ Server: server,
+ }
+ }
+ if h.Type != dnsmessage.TypeMX {
+ if err := p.SkipAnswer(); err != nil {
+ return nil, &DNSError{
+ Err: "cannot unmarshal DNS message",
+ Name: name,
+ Server: server,
+ }
+ }
+ continue
+ }
+ mx, err := p.MXResource()
+ if err != nil {
+ return nil, &DNSError{
+ Err: "cannot unmarshal DNS message",
+ Name: name,
+ Server: server,
+ }
+ }
+ mxs = append(mxs, &MX{Host: mx.MX.String(), Pref: mx.Pref})
+
+ }
+ byPref(mxs).sort()
+ return mxs, nil
+}
+
+// goLookupNS returns the NS records for name.
+func (r *Resolver) goLookupNS(ctx context.Context, name string) ([]*NS, error) {
+ p, server, err := r.lookup(ctx, name, dnsmessage.TypeNS, nil)
+ if err != nil {
+ return nil, err
+ }
+ var nss []*NS
+ for {
+ h, err := p.AnswerHeader()
+ if err == dnsmessage.ErrSectionDone {
+ break
+ }
+ if err != nil {
+ return nil, &DNSError{
+ Err: "cannot unmarshal DNS message",
+ Name: name,
+ Server: server,
+ }
+ }
+ if h.Type != dnsmessage.TypeNS {
+ if err := p.SkipAnswer(); err != nil {
+ return nil, &DNSError{
+ Err: "cannot unmarshal DNS message",
+ Name: name,
+ Server: server,
+ }
+ }
+ continue
+ }
+ ns, err := p.NSResource()
+ if err != nil {
+ return nil, &DNSError{
+ Err: "cannot unmarshal DNS message",
+ Name: name,
+ Server: server,
+ }
+ }
+ nss = append(nss, &NS{Host: ns.NS.String()})
+ }
+ return nss, nil
+}
+
+// goLookupTXT returns the TXT records from name.
+func (r *Resolver) goLookupTXT(ctx context.Context, name string) ([]string, error) {
+ p, server, err := r.lookup(ctx, name, dnsmessage.TypeTXT, nil)
+ if err != nil {
+ return nil, err
+ }
+ var txts []string
+ for {
+ h, err := p.AnswerHeader()
+ if err == dnsmessage.ErrSectionDone {
+ break
+ }
+ if err != nil {
+ return nil, &DNSError{
+ Err: "cannot unmarshal DNS message",
+ Name: name,
+ Server: server,
+ }
+ }
+ if h.Type != dnsmessage.TypeTXT {
+ if err := p.SkipAnswer(); err != nil {
+ return nil, &DNSError{
+ Err: "cannot unmarshal DNS message",
+ Name: name,
+ Server: server,
+ }
+ }
+ continue
+ }
+ txt, err := p.TXTResource()
+ if err != nil {
+ return nil, &DNSError{
+ Err: "cannot unmarshal DNS message",
+ Name: name,
+ Server: server,
+ }
+ }
+ // Multiple strings in one TXT record need to be
+ // concatenated without separator to be consistent
+ // with previous Go resolver.
+ n := 0
+ for _, s := range txt.TXT {
+ n += len(s)
+ }
+ txtJoin := make([]byte, 0, n)
+ for _, s := range txt.TXT {
+ txtJoin = append(txtJoin, s...)
+ }
+ if len(txts) == 0 {
+ txts = make([]string, 0, 1)
+ }
+ txts = append(txts, string(txtJoin))
+ }
+ return txts, nil
+}
+
+func parseCNAMEFromResources(resources []dnsmessage.Resource) (string, error) {
+ if len(resources) == 0 {
+ return "", errors.New("no CNAME record received")
+ }
+ c, ok := resources[0].Body.(*dnsmessage.CNAMEResource)
+ if !ok {
+ return "", errors.New("could not parse CNAME record")
+ }
+ return c.CNAME.String(), nil
+}
diff --git a/contrib/go/_std_1.21/src/net/lookup_unix.go b/contrib/go/_std_1.21/src/net/lookup_unix.go
new file mode 100644
index 0000000000..56ae11e961
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/lookup_unix.go
@@ -0,0 +1,149 @@
+// Copyright 2011 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.
+
+//go:build unix || wasip1
+
+package net
+
+import (
+ "context"
+ "internal/bytealg"
+ "sync"
+ "syscall"
+)
+
+var onceReadProtocols sync.Once
+
+// readProtocols loads contents of /etc/protocols into protocols map
+// for quick access.
+func readProtocols() {
+ file, err := open("/etc/protocols")
+ if err != nil {
+ return
+ }
+ defer file.close()
+
+ for line, ok := file.readLine(); ok; line, ok = file.readLine() {
+ // tcp 6 TCP # transmission control protocol
+ if i := bytealg.IndexByteString(line, '#'); i >= 0 {
+ line = line[0:i]
+ }
+ f := getFields(line)
+ if len(f) < 2 {
+ continue
+ }
+ if proto, _, ok := dtoi(f[1]); ok {
+ if _, ok := protocols[f[0]]; !ok {
+ protocols[f[0]] = proto
+ }
+ for _, alias := range f[2:] {
+ if _, ok := protocols[alias]; !ok {
+ protocols[alias] = proto
+ }
+ }
+ }
+ }
+}
+
+// lookupProtocol looks up IP protocol name in /etc/protocols and
+// returns correspondent protocol number.
+func lookupProtocol(_ context.Context, name string) (int, error) {
+ onceReadProtocols.Do(readProtocols)
+ return lookupProtocolMap(name)
+}
+
+func (r *Resolver) lookupHost(ctx context.Context, host string) (addrs []string, err error) {
+ order, conf := systemConf().hostLookupOrder(r, host)
+ if order == hostLookupCgo {
+ return cgoLookupHost(ctx, host)
+ }
+ return r.goLookupHostOrder(ctx, host, order, conf)
+}
+
+func (r *Resolver) lookupIP(ctx context.Context, network, host string) (addrs []IPAddr, err error) {
+ if r.preferGo() {
+ return r.goLookupIP(ctx, network, host)
+ }
+ order, conf := systemConf().hostLookupOrder(r, host)
+ if order == hostLookupCgo {
+ return cgoLookupIP(ctx, network, host)
+ }
+ ips, _, err := r.goLookupIPCNAMEOrder(ctx, network, host, order, conf)
+ return ips, err
+}
+
+func (r *Resolver) lookupPort(ctx context.Context, network, service string) (int, error) {
+ // Port lookup is not a DNS operation.
+ // Prefer the cgo resolver if possible.
+ if !systemConf().mustUseGoResolver(r) {
+ port, err := cgoLookupPort(ctx, network, service)
+ if err != nil {
+ // Issue 18213: if cgo fails, first check to see whether we
+ // have the answer baked-in to the net package.
+ if port, err := goLookupPort(network, service); err == nil {
+ return port, nil
+ }
+ }
+ return port, err
+ }
+ return goLookupPort(network, service)
+}
+
+func (r *Resolver) lookupCNAME(ctx context.Context, name string) (string, error) {
+ order, conf := systemConf().hostLookupOrder(r, name)
+ if order == hostLookupCgo {
+ if cname, err, ok := cgoLookupCNAME(ctx, name); ok {
+ return cname, err
+ }
+ }
+ return r.goLookupCNAME(ctx, name, order, conf)
+}
+
+func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
+ return r.goLookupSRV(ctx, service, proto, name)
+}
+
+func (r *Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
+ return r.goLookupMX(ctx, name)
+}
+
+func (r *Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) {
+ return r.goLookupNS(ctx, name)
+}
+
+func (r *Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) {
+ return r.goLookupTXT(ctx, name)
+}
+
+func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error) {
+ order, conf := systemConf().addrLookupOrder(r, addr)
+ if order == hostLookupCgo {
+ return cgoLookupPTR(ctx, addr)
+ }
+ return r.goLookupPTR(ctx, addr, order, conf)
+}
+
+// concurrentThreadsLimit returns the number of threads we permit to
+// run concurrently doing DNS lookups via cgo. A DNS lookup may use a
+// file descriptor so we limit this to less than the number of
+// permitted open files. On some systems, notably Darwin, if
+// getaddrinfo is unable to open a file descriptor it simply returns
+// EAI_NONAME rather than a useful error. Limiting the number of
+// concurrent getaddrinfo calls to less than the permitted number of
+// file descriptors makes that error less likely. We don't bother to
+// apply the same limit to DNS lookups run directly from Go, because
+// there we will return a meaningful "too many open files" error.
+func concurrentThreadsLimit() int {
+ var rlim syscall.Rlimit
+ if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil {
+ return 500
+ }
+ r := rlim.Cur
+ if r > 500 {
+ r = 500
+ } else if r > 30 {
+ r -= 30
+ }
+ return int(r)
+}
diff --git a/contrib/go/_std_1.21/src/net/lookup_windows.go b/contrib/go/_std_1.21/src/net/lookup_windows.go
new file mode 100644
index 0000000000..33d5ac5fb4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/lookup_windows.go
@@ -0,0 +1,455 @@
+// Copyright 2009 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 net
+
+import (
+ "context"
+ "internal/syscall/windows"
+ "os"
+ "runtime"
+ "syscall"
+ "time"
+ "unsafe"
+)
+
+// cgoAvailable set to true to indicate that the cgo resolver
+// is available on Windows. Note that on Windows the cgo resolver
+// does not actually use cgo.
+const cgoAvailable = true
+
+const (
+ _WSAHOST_NOT_FOUND = syscall.Errno(11001)
+ _WSATRY_AGAIN = syscall.Errno(11002)
+)
+
+func winError(call string, err error) error {
+ switch err {
+ case _WSAHOST_NOT_FOUND:
+ return errNoSuchHost
+ }
+ return os.NewSyscallError(call, err)
+}
+
+func getprotobyname(name string) (proto int, err error) {
+ p, err := syscall.GetProtoByName(name)
+ if err != nil {
+ return 0, winError("getprotobyname", err)
+ }
+ return int(p.Proto), nil
+}
+
+// lookupProtocol looks up IP protocol name and returns correspondent protocol number.
+func lookupProtocol(ctx context.Context, name string) (int, error) {
+ // GetProtoByName return value is stored in thread local storage.
+ // Start new os thread before the call to prevent races.
+ type result struct {
+ proto int
+ err error
+ }
+ ch := make(chan result) // unbuffered
+ go func() {
+ acquireThread()
+ defer releaseThread()
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+ proto, err := getprotobyname(name)
+ select {
+ case ch <- result{proto: proto, err: err}:
+ case <-ctx.Done():
+ }
+ }()
+ select {
+ case r := <-ch:
+ if r.err != nil {
+ if proto, err := lookupProtocolMap(name); err == nil {
+ return proto, nil
+ }
+
+ dnsError := &DNSError{Err: r.err.Error(), Name: name}
+ if r.err == errNoSuchHost {
+ dnsError.IsNotFound = true
+ }
+ r.err = dnsError
+ }
+ return r.proto, r.err
+ case <-ctx.Done():
+ return 0, mapErr(ctx.Err())
+ }
+}
+
+func (r *Resolver) lookupHost(ctx context.Context, name string) ([]string, error) {
+ ips, err := r.lookupIP(ctx, "ip", name)
+ if err != nil {
+ return nil, err
+ }
+ addrs := make([]string, 0, len(ips))
+ for _, ip := range ips {
+ addrs = append(addrs, ip.String())
+ }
+ return addrs, nil
+}
+
+// preferGoOverWindows reports whether the resolver should use the
+// pure Go implementation rather than making win32 calls to ask the
+// kernel for its answer.
+func (r *Resolver) preferGoOverWindows() bool {
+ conf := systemConf()
+ order, _ := conf.hostLookupOrder(r, "") // name is unused
+ return order != hostLookupCgo
+}
+
+func (r *Resolver) lookupIP(ctx context.Context, network, name string) ([]IPAddr, error) {
+ if r.preferGoOverWindows() {
+ return r.goLookupIP(ctx, network, name)
+ }
+ // TODO(bradfitz,brainman): use ctx more. See TODO below.
+
+ var family int32 = syscall.AF_UNSPEC
+ switch ipVersion(network) {
+ case '4':
+ family = syscall.AF_INET
+ case '6':
+ family = syscall.AF_INET6
+ }
+
+ getaddr := func() ([]IPAddr, error) {
+ acquireThread()
+ defer releaseThread()
+ hints := syscall.AddrinfoW{
+ Family: family,
+ Socktype: syscall.SOCK_STREAM,
+ Protocol: syscall.IPPROTO_IP,
+ }
+ var result *syscall.AddrinfoW
+ name16p, err := syscall.UTF16PtrFromString(name)
+ if err != nil {
+ return nil, &DNSError{Name: name, Err: err.Error()}
+ }
+
+ dnsConf := getSystemDNSConfig()
+ start := time.Now()
+
+ var e error
+ for i := 0; i < dnsConf.attempts; i++ {
+ e = syscall.GetAddrInfoW(name16p, nil, &hints, &result)
+ if e == nil || e != _WSATRY_AGAIN || time.Since(start) > dnsConf.timeout {
+ break
+ }
+ }
+ if e != nil {
+ err := winError("getaddrinfow", e)
+ dnsError := &DNSError{Err: err.Error(), Name: name}
+ if err == errNoSuchHost {
+ dnsError.IsNotFound = true
+ }
+ return nil, dnsError
+ }
+ defer syscall.FreeAddrInfoW(result)
+ addrs := make([]IPAddr, 0, 5)
+ for ; result != nil; result = result.Next {
+ addr := unsafe.Pointer(result.Addr)
+ switch result.Family {
+ case syscall.AF_INET:
+ a := (*syscall.RawSockaddrInet4)(addr).Addr
+ addrs = append(addrs, IPAddr{IP: copyIP(a[:])})
+ case syscall.AF_INET6:
+ a := (*syscall.RawSockaddrInet6)(addr).Addr
+ zone := zoneCache.name(int((*syscall.RawSockaddrInet6)(addr).Scope_id))
+ addrs = append(addrs, IPAddr{IP: copyIP(a[:]), Zone: zone})
+ default:
+ return nil, &DNSError{Err: syscall.EWINDOWS.Error(), Name: name}
+ }
+ }
+ return addrs, nil
+ }
+
+ type ret struct {
+ addrs []IPAddr
+ err error
+ }
+
+ var ch chan ret
+ if ctx.Err() == nil {
+ ch = make(chan ret, 1)
+ go func() {
+ addr, err := getaddr()
+ ch <- ret{addrs: addr, err: err}
+ }()
+ }
+
+ select {
+ case r := <-ch:
+ return r.addrs, r.err
+ case <-ctx.Done():
+ // TODO(bradfitz,brainman): cancel the ongoing
+ // GetAddrInfoW? It would require conditionally using
+ // GetAddrInfoEx with lpOverlapped, which requires
+ // Windows 8 or newer. I guess we'll need oldLookupIP,
+ // newLookupIP, and newerLookUP.
+ //
+ // For now we just let it finish and write to the
+ // buffered channel.
+ return nil, &DNSError{
+ Name: name,
+ Err: ctx.Err().Error(),
+ IsTimeout: ctx.Err() == context.DeadlineExceeded,
+ }
+ }
+}
+
+func (r *Resolver) lookupPort(ctx context.Context, network, service string) (int, error) {
+ if r.preferGoOverWindows() {
+ return lookupPortMap(network, service)
+ }
+
+ // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
+ acquireThread()
+ defer releaseThread()
+ var stype int32
+ switch network {
+ case "tcp4", "tcp6":
+ stype = syscall.SOCK_STREAM
+ case "udp4", "udp6":
+ stype = syscall.SOCK_DGRAM
+ }
+ hints := syscall.AddrinfoW{
+ Family: syscall.AF_UNSPEC,
+ Socktype: stype,
+ Protocol: syscall.IPPROTO_IP,
+ }
+ var result *syscall.AddrinfoW
+ e := syscall.GetAddrInfoW(nil, syscall.StringToUTF16Ptr(service), &hints, &result)
+ if e != nil {
+ if port, err := lookupPortMap(network, service); err == nil {
+ return port, nil
+ }
+ err := winError("getaddrinfow", e)
+ dnsError := &DNSError{Err: err.Error(), Name: network + "/" + service}
+ if err == errNoSuchHost {
+ dnsError.IsNotFound = true
+ }
+ return 0, dnsError
+ }
+ defer syscall.FreeAddrInfoW(result)
+ if result == nil {
+ return 0, &DNSError{Err: syscall.EINVAL.Error(), Name: network + "/" + service}
+ }
+ addr := unsafe.Pointer(result.Addr)
+ switch result.Family {
+ case syscall.AF_INET:
+ a := (*syscall.RawSockaddrInet4)(addr)
+ return int(syscall.Ntohs(a.Port)), nil
+ case syscall.AF_INET6:
+ a := (*syscall.RawSockaddrInet6)(addr)
+ return int(syscall.Ntohs(a.Port)), nil
+ }
+ return 0, &DNSError{Err: syscall.EINVAL.Error(), Name: network + "/" + service}
+}
+
+func (r *Resolver) lookupCNAME(ctx context.Context, name string) (string, error) {
+ if order, conf := systemConf().hostLookupOrder(r, ""); order != hostLookupCgo {
+ return r.goLookupCNAME(ctx, name, order, conf)
+ }
+
+ // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
+ acquireThread()
+ defer releaseThread()
+ var rec *syscall.DNSRecord
+ e := syscall.DnsQuery(name, syscall.DNS_TYPE_CNAME, 0, nil, &rec, nil)
+ // windows returns DNS_INFO_NO_RECORDS if there are no CNAME-s
+ if errno, ok := e.(syscall.Errno); ok && errno == syscall.DNS_INFO_NO_RECORDS {
+ // if there are no aliases, the canonical name is the input name
+ return absDomainName(name), nil
+ }
+ if e != nil {
+ return "", &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
+ }
+ defer syscall.DnsRecordListFree(rec, 1)
+
+ resolved := resolveCNAME(syscall.StringToUTF16Ptr(name), rec)
+ cname := windows.UTF16PtrToString(resolved)
+ return absDomainName(cname), nil
+}
+
+func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
+ if r.preferGoOverWindows() {
+ return r.goLookupSRV(ctx, service, proto, name)
+ }
+ // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
+ acquireThread()
+ defer releaseThread()
+ var target string
+ if service == "" && proto == "" {
+ target = name
+ } else {
+ target = "_" + service + "._" + proto + "." + name
+ }
+ var rec *syscall.DNSRecord
+ e := syscall.DnsQuery(target, syscall.DNS_TYPE_SRV, 0, nil, &rec, nil)
+ if e != nil {
+ return "", nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: target}
+ }
+ defer syscall.DnsRecordListFree(rec, 1)
+
+ srvs := make([]*SRV, 0, 10)
+ for _, p := range validRecs(rec, syscall.DNS_TYPE_SRV, target) {
+ v := (*syscall.DNSSRVData)(unsafe.Pointer(&p.Data[0]))
+ srvs = append(srvs, &SRV{absDomainName(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Target))[:])), v.Port, v.Priority, v.Weight})
+ }
+ byPriorityWeight(srvs).sort()
+ return absDomainName(target), srvs, nil
+}
+
+func (r *Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) {
+ if r.preferGoOverWindows() {
+ return r.goLookupMX(ctx, name)
+ }
+ // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
+ acquireThread()
+ defer releaseThread()
+ var rec *syscall.DNSRecord
+ e := syscall.DnsQuery(name, syscall.DNS_TYPE_MX, 0, nil, &rec, nil)
+ if e != nil {
+ return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
+ }
+ defer syscall.DnsRecordListFree(rec, 1)
+
+ mxs := make([]*MX, 0, 10)
+ for _, p := range validRecs(rec, syscall.DNS_TYPE_MX, name) {
+ v := (*syscall.DNSMXData)(unsafe.Pointer(&p.Data[0]))
+ mxs = append(mxs, &MX{absDomainName(windows.UTF16PtrToString(v.NameExchange)), v.Preference})
+ }
+ byPref(mxs).sort()
+ return mxs, nil
+}
+
+func (r *Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) {
+ if r.preferGoOverWindows() {
+ return r.goLookupNS(ctx, name)
+ }
+ // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
+ acquireThread()
+ defer releaseThread()
+ var rec *syscall.DNSRecord
+ e := syscall.DnsQuery(name, syscall.DNS_TYPE_NS, 0, nil, &rec, nil)
+ if e != nil {
+ return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
+ }
+ defer syscall.DnsRecordListFree(rec, 1)
+
+ nss := make([]*NS, 0, 10)
+ for _, p := range validRecs(rec, syscall.DNS_TYPE_NS, name) {
+ v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
+ nss = append(nss, &NS{absDomainName(syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]))})
+ }
+ return nss, nil
+}
+
+func (r *Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) {
+ if r.preferGoOverWindows() {
+ return r.goLookupTXT(ctx, name)
+ }
+ // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
+ acquireThread()
+ defer releaseThread()
+ var rec *syscall.DNSRecord
+ e := syscall.DnsQuery(name, syscall.DNS_TYPE_TEXT, 0, nil, &rec, nil)
+ if e != nil {
+ return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: name}
+ }
+ defer syscall.DnsRecordListFree(rec, 1)
+
+ txts := make([]string, 0, 10)
+ for _, p := range validRecs(rec, syscall.DNS_TYPE_TEXT, name) {
+ d := (*syscall.DNSTXTData)(unsafe.Pointer(&p.Data[0]))
+ s := ""
+ for _, v := range (*[1 << 10]*uint16)(unsafe.Pointer(&(d.StringArray[0])))[:d.StringCount:d.StringCount] {
+ s += windows.UTF16PtrToString(v)
+ }
+ txts = append(txts, s)
+ }
+ return txts, nil
+}
+
+func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error) {
+ if order, conf := systemConf().hostLookupOrder(r, ""); order != hostLookupCgo {
+ return r.goLookupPTR(ctx, addr, order, conf)
+ }
+
+ // TODO(bradfitz): finish ctx plumbing. Nothing currently depends on this.
+ acquireThread()
+ defer releaseThread()
+ arpa, err := reverseaddr(addr)
+ if err != nil {
+ return nil, err
+ }
+ var rec *syscall.DNSRecord
+ e := syscall.DnsQuery(arpa, syscall.DNS_TYPE_PTR, 0, nil, &rec, nil)
+ if e != nil {
+ return nil, &DNSError{Err: winError("dnsquery", e).Error(), Name: addr}
+ }
+ defer syscall.DnsRecordListFree(rec, 1)
+
+ ptrs := make([]string, 0, 10)
+ for _, p := range validRecs(rec, syscall.DNS_TYPE_PTR, arpa) {
+ v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
+ ptrs = append(ptrs, absDomainName(windows.UTF16PtrToString(v.Host)))
+ }
+ return ptrs, nil
+}
+
+const dnsSectionMask = 0x0003
+
+// returns only results applicable to name and resolves CNAME entries.
+func validRecs(r *syscall.DNSRecord, dnstype uint16, name string) []*syscall.DNSRecord {
+ cname := syscall.StringToUTF16Ptr(name)
+ if dnstype != syscall.DNS_TYPE_CNAME {
+ cname = resolveCNAME(cname, r)
+ }
+ rec := make([]*syscall.DNSRecord, 0, 10)
+ for p := r; p != nil; p = p.Next {
+ // in case of a local machine, DNS records are returned with DNSREC_QUESTION flag instead of DNS_ANSWER
+ if p.Dw&dnsSectionMask != syscall.DnsSectionAnswer && p.Dw&dnsSectionMask != syscall.DnsSectionQuestion {
+ continue
+ }
+ if p.Type != dnstype {
+ continue
+ }
+ if !syscall.DnsNameCompare(cname, p.Name) {
+ continue
+ }
+ rec = append(rec, p)
+ }
+ return rec
+}
+
+// returns the last CNAME in chain.
+func resolveCNAME(name *uint16, r *syscall.DNSRecord) *uint16 {
+ // limit cname resolving to 10 in case of an infinite CNAME loop
+Cname:
+ for cnameloop := 0; cnameloop < 10; cnameloop++ {
+ for p := r; p != nil; p = p.Next {
+ if p.Dw&dnsSectionMask != syscall.DnsSectionAnswer {
+ continue
+ }
+ if p.Type != syscall.DNS_TYPE_CNAME {
+ continue
+ }
+ if !syscall.DnsNameCompare(name, p.Name) {
+ continue
+ }
+ name = (*syscall.DNSPTRData)(unsafe.Pointer(&r.Data[0])).Host
+ continue Cname
+ }
+ break
+ }
+ return name
+}
+
+// concurrentThreadsLimit returns the number of threads we permit to
+// run concurrently doing DNS lookups.
+func concurrentThreadsLimit() int {
+ return 500
+}
diff --git a/contrib/go/_std_1.20/src/net/mac.go b/contrib/go/_std_1.21/src/net/mac.go
index 53d5b2dbf5..53d5b2dbf5 100644
--- a/contrib/go/_std_1.20/src/net/mac.go
+++ b/contrib/go/_std_1.21/src/net/mac.go
diff --git a/contrib/go/_std_1.21/src/net/mail/message.go b/contrib/go/_std_1.21/src/net/mail/message.go
new file mode 100644
index 0000000000..af516fc30f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/mail/message.go
@@ -0,0 +1,911 @@
+// Copyright 2011 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 mail implements parsing of mail messages.
+
+For the most part, this package follows the syntax as specified by RFC 5322 and
+extended by RFC 6532.
+Notable divergences:
+ - Obsolete address formats are not parsed, including addresses with
+ embedded route information.
+ - The full range of spacing (the CFWS syntax element) is not supported,
+ such as breaking addresses across lines.
+ - No unicode normalization is performed.
+ - The special characters ()[]:;@\, are allowed to appear unquoted in names.
+ - A leading From line is permitted, as in mbox format (RFC 4155).
+*/
+package mail
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "io"
+ "log"
+ "mime"
+ "net/textproto"
+ "strings"
+ "sync"
+ "time"
+ "unicode/utf8"
+)
+
+var debug = debugT(false)
+
+type debugT bool
+
+func (d debugT) Printf(format string, args ...any) {
+ if d {
+ log.Printf(format, args...)
+ }
+}
+
+// A Message represents a parsed mail message.
+type Message struct {
+ Header Header
+ Body io.Reader
+}
+
+// ReadMessage reads a message from r.
+// The headers are parsed, and the body of the message will be available
+// for reading from msg.Body.
+func ReadMessage(r io.Reader) (msg *Message, err error) {
+ tp := textproto.NewReader(bufio.NewReader(r))
+
+ hdr, err := readHeader(tp)
+ if err != nil && (err != io.EOF || len(hdr) == 0) {
+ return nil, err
+ }
+
+ return &Message{
+ Header: Header(hdr),
+ Body: tp.R,
+ }, nil
+}
+
+// readHeader reads the message headers from r.
+// This is like textproto.ReadMIMEHeader, but doesn't validate.
+// The fix for issue #53188 tightened up net/textproto to enforce
+// restrictions of RFC 7230.
+// This package implements RFC 5322, which does not have those restrictions.
+// This function copies the relevant code from net/textproto,
+// simplified for RFC 5322.
+func readHeader(r *textproto.Reader) (map[string][]string, error) {
+ m := make(map[string][]string)
+
+ // The first line cannot start with a leading space.
+ if buf, err := r.R.Peek(1); err == nil && (buf[0] == ' ' || buf[0] == '\t') {
+ line, err := r.ReadLine()
+ if err != nil {
+ return m, err
+ }
+ return m, errors.New("malformed initial line: " + line)
+ }
+
+ for {
+ kv, err := r.ReadContinuedLine()
+ if kv == "" {
+ return m, err
+ }
+
+ // Key ends at first colon.
+ k, v, ok := strings.Cut(kv, ":")
+ if !ok {
+ return m, errors.New("malformed header line: " + kv)
+ }
+ key := textproto.CanonicalMIMEHeaderKey(k)
+
+ // Permit empty key, because that is what we did in the past.
+ if key == "" {
+ continue
+ }
+
+ // Skip initial spaces in value.
+ value := strings.TrimLeft(v, " \t")
+
+ m[key] = append(m[key], value)
+
+ if err != nil {
+ return m, err
+ }
+ }
+}
+
+// Layouts suitable for passing to time.Parse.
+// These are tried in order.
+var (
+ dateLayoutsBuildOnce sync.Once
+ dateLayouts []string
+)
+
+func buildDateLayouts() {
+ // Generate layouts based on RFC 5322, section 3.3.
+
+ dows := [...]string{"", "Mon, "} // day-of-week
+ days := [...]string{"2", "02"} // day = 1*2DIGIT
+ years := [...]string{"2006", "06"} // year = 4*DIGIT / 2*DIGIT
+ seconds := [...]string{":05", ""} // second
+ // "-0700 (MST)" is not in RFC 5322, but is common.
+ zones := [...]string{"-0700", "MST", "UT"} // zone = (("+" / "-") 4DIGIT) / "UT" / "GMT" / ...
+
+ for _, dow := range dows {
+ for _, day := range days {
+ for _, year := range years {
+ for _, second := range seconds {
+ for _, zone := range zones {
+ s := dow + day + " Jan " + year + " 15:04" + second + " " + zone
+ dateLayouts = append(dateLayouts, s)
+ }
+ }
+ }
+ }
+ }
+}
+
+// ParseDate parses an RFC 5322 date string.
+func ParseDate(date string) (time.Time, error) {
+ dateLayoutsBuildOnce.Do(buildDateLayouts)
+ // CR and LF must match and are tolerated anywhere in the date field.
+ date = strings.ReplaceAll(date, "\r\n", "")
+ if strings.Contains(date, "\r") {
+ return time.Time{}, errors.New("mail: header has a CR without LF")
+ }
+ // Re-using some addrParser methods which support obsolete text, i.e. non-printable ASCII
+ p := addrParser{date, nil}
+ p.skipSpace()
+
+ // RFC 5322: zone = (FWS ( "+" / "-" ) 4DIGIT) / obs-zone
+ // zone length is always 5 chars unless obsolete (obs-zone)
+ if ind := strings.IndexAny(p.s, "+-"); ind != -1 && len(p.s) >= ind+5 {
+ date = p.s[:ind+5]
+ p.s = p.s[ind+5:]
+ } else {
+ ind := strings.Index(p.s, "T")
+ if ind == 0 {
+ // In this case we have the following date formats:
+ // * Thu, 20 Nov 1997 09:55:06 MDT
+ // * Thu, 20 Nov 1997 09:55:06 MDT (MDT)
+ // * Thu, 20 Nov 1997 09:55:06 MDT (This comment)
+ ind = strings.Index(p.s[1:], "T")
+ if ind != -1 {
+ ind++
+ }
+ }
+
+ if ind != -1 && len(p.s) >= ind+5 {
+ // The last letter T of the obsolete time zone is checked when no standard time zone is found.
+ // If T is misplaced, the date to parse is garbage.
+ date = p.s[:ind+1]
+ p.s = p.s[ind+1:]
+ }
+ }
+ if !p.skipCFWS() {
+ return time.Time{}, errors.New("mail: misformatted parenthetical comment")
+ }
+ for _, layout := range dateLayouts {
+ t, err := time.Parse(layout, date)
+ if err == nil {
+ return t, nil
+ }
+ }
+ return time.Time{}, errors.New("mail: header could not be parsed")
+}
+
+// A Header represents the key-value pairs in a mail message header.
+type Header map[string][]string
+
+// Get gets the first value associated with the given key.
+// It is case insensitive; CanonicalMIMEHeaderKey is used
+// to canonicalize the provided key.
+// If there are no values associated with the key, Get returns "".
+// To access multiple values of a key, or to use non-canonical keys,
+// access the map directly.
+func (h Header) Get(key string) string {
+ return textproto.MIMEHeader(h).Get(key)
+}
+
+var ErrHeaderNotPresent = errors.New("mail: header not in message")
+
+// Date parses the Date header field.
+func (h Header) Date() (time.Time, error) {
+ hdr := h.Get("Date")
+ if hdr == "" {
+ return time.Time{}, ErrHeaderNotPresent
+ }
+ return ParseDate(hdr)
+}
+
+// AddressList parses the named header field as a list of addresses.
+func (h Header) AddressList(key string) ([]*Address, error) {
+ hdr := h.Get(key)
+ if hdr == "" {
+ return nil, ErrHeaderNotPresent
+ }
+ return ParseAddressList(hdr)
+}
+
+// Address represents a single mail address.
+// An address such as "Barry Gibbs <bg@example.com>" is represented
+// as Address{Name: "Barry Gibbs", Address: "bg@example.com"}.
+type Address struct {
+ Name string // Proper name; may be empty.
+ Address string // user@domain
+}
+
+// ParseAddress parses a single RFC 5322 address, e.g. "Barry Gibbs <bg@example.com>"
+func ParseAddress(address string) (*Address, error) {
+ return (&addrParser{s: address}).parseSingleAddress()
+}
+
+// ParseAddressList parses the given string as a list of addresses.
+func ParseAddressList(list string) ([]*Address, error) {
+ return (&addrParser{s: list}).parseAddressList()
+}
+
+// An AddressParser is an RFC 5322 address parser.
+type AddressParser struct {
+ // WordDecoder optionally specifies a decoder for RFC 2047 encoded-words.
+ WordDecoder *mime.WordDecoder
+}
+
+// Parse parses a single RFC 5322 address of the
+// form "Gogh Fir <gf@example.com>" or "foo@example.com".
+func (p *AddressParser) Parse(address string) (*Address, error) {
+ return (&addrParser{s: address, dec: p.WordDecoder}).parseSingleAddress()
+}
+
+// ParseList parses the given string as a list of comma-separated addresses
+// of the form "Gogh Fir <gf@example.com>" or "foo@example.com".
+func (p *AddressParser) ParseList(list string) ([]*Address, error) {
+ return (&addrParser{s: list, dec: p.WordDecoder}).parseAddressList()
+}
+
+// String formats the address as a valid RFC 5322 address.
+// If the address's name contains non-ASCII characters
+// the name will be rendered according to RFC 2047.
+func (a *Address) String() string {
+ // Format address local@domain
+ at := strings.LastIndex(a.Address, "@")
+ var local, domain string
+ if at < 0 {
+ // This is a malformed address ("@" is required in addr-spec);
+ // treat the whole address as local-part.
+ local = a.Address
+ } else {
+ local, domain = a.Address[:at], a.Address[at+1:]
+ }
+
+ // Add quotes if needed
+ quoteLocal := false
+ for i, r := range local {
+ if isAtext(r, false, false) {
+ continue
+ }
+ if r == '.' {
+ // Dots are okay if they are surrounded by atext.
+ // We only need to check that the previous byte is
+ // not a dot, and this isn't the end of the string.
+ if i > 0 && local[i-1] != '.' && i < len(local)-1 {
+ continue
+ }
+ }
+ quoteLocal = true
+ break
+ }
+ if quoteLocal {
+ local = quoteString(local)
+
+ }
+
+ s := "<" + local + "@" + domain + ">"
+
+ if a.Name == "" {
+ return s
+ }
+
+ // If every character is printable ASCII, quoting is simple.
+ allPrintable := true
+ for _, r := range a.Name {
+ // isWSP here should actually be isFWS,
+ // but we don't support folding yet.
+ if !isVchar(r) && !isWSP(r) || isMultibyte(r) {
+ allPrintable = false
+ break
+ }
+ }
+ if allPrintable {
+ return quoteString(a.Name) + " " + s
+ }
+
+ // Text in an encoded-word in a display-name must not contain certain
+ // characters like quotes or parentheses (see RFC 2047 section 5.3).
+ // When this is the case encode the name using base64 encoding.
+ if strings.ContainsAny(a.Name, "\"#$%&'(),.:;<>@[]^`{|}~") {
+ return mime.BEncoding.Encode("utf-8", a.Name) + " " + s
+ }
+ return mime.QEncoding.Encode("utf-8", a.Name) + " " + s
+}
+
+type addrParser struct {
+ s string
+ dec *mime.WordDecoder // may be nil
+}
+
+func (p *addrParser) parseAddressList() ([]*Address, error) {
+ var list []*Address
+ for {
+ p.skipSpace()
+
+ // allow skipping empty entries (RFC5322 obs-addr-list)
+ if p.consume(',') {
+ continue
+ }
+
+ addrs, err := p.parseAddress(true)
+ if err != nil {
+ return nil, err
+ }
+ list = append(list, addrs...)
+
+ if !p.skipCFWS() {
+ return nil, errors.New("mail: misformatted parenthetical comment")
+ }
+ if p.empty() {
+ break
+ }
+ if p.peek() != ',' {
+ return nil, errors.New("mail: expected comma")
+ }
+
+ // Skip empty entries for obs-addr-list.
+ for p.consume(',') {
+ p.skipSpace()
+ }
+ if p.empty() {
+ break
+ }
+ }
+ return list, nil
+}
+
+func (p *addrParser) parseSingleAddress() (*Address, error) {
+ addrs, err := p.parseAddress(true)
+ if err != nil {
+ return nil, err
+ }
+ if !p.skipCFWS() {
+ return nil, errors.New("mail: misformatted parenthetical comment")
+ }
+ if !p.empty() {
+ return nil, fmt.Errorf("mail: expected single address, got %q", p.s)
+ }
+ if len(addrs) == 0 {
+ return nil, errors.New("mail: empty group")
+ }
+ if len(addrs) > 1 {
+ return nil, errors.New("mail: group with multiple addresses")
+ }
+ return addrs[0], nil
+}
+
+// parseAddress parses a single RFC 5322 address at the start of p.
+func (p *addrParser) parseAddress(handleGroup bool) ([]*Address, error) {
+ debug.Printf("parseAddress: %q", p.s)
+ p.skipSpace()
+ if p.empty() {
+ return nil, errors.New("mail: no address")
+ }
+
+ // address = mailbox / group
+ // mailbox = name-addr / addr-spec
+ // group = display-name ":" [group-list] ";" [CFWS]
+
+ // addr-spec has a more restricted grammar than name-addr,
+ // so try parsing it first, and fallback to name-addr.
+ // TODO(dsymonds): Is this really correct?
+ spec, err := p.consumeAddrSpec()
+ if err == nil {
+ var displayName string
+ p.skipSpace()
+ if !p.empty() && p.peek() == '(' {
+ displayName, err = p.consumeDisplayNameComment()
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return []*Address{{
+ Name: displayName,
+ Address: spec,
+ }}, err
+ }
+ debug.Printf("parseAddress: not an addr-spec: %v", err)
+ debug.Printf("parseAddress: state is now %q", p.s)
+
+ // display-name
+ var displayName string
+ if p.peek() != '<' {
+ displayName, err = p.consumePhrase()
+ if err != nil {
+ return nil, err
+ }
+ }
+ debug.Printf("parseAddress: displayName=%q", displayName)
+
+ p.skipSpace()
+ if handleGroup {
+ if p.consume(':') {
+ return p.consumeGroupList()
+ }
+ }
+ // angle-addr = "<" addr-spec ">"
+ if !p.consume('<') {
+ atext := true
+ for _, r := range displayName {
+ if !isAtext(r, true, false) {
+ atext = false
+ break
+ }
+ }
+ if atext {
+ // The input is like "foo.bar"; it's possible the input
+ // meant to be "foo.bar@domain", or "foo.bar <...>".
+ return nil, errors.New("mail: missing '@' or angle-addr")
+ }
+ // The input is like "Full Name", which couldn't possibly be a
+ // valid email address if followed by "@domain"; the input
+ // likely meant to be "Full Name <...>".
+ return nil, errors.New("mail: no angle-addr")
+ }
+ spec, err = p.consumeAddrSpec()
+ if err != nil {
+ return nil, err
+ }
+ if !p.consume('>') {
+ return nil, errors.New("mail: unclosed angle-addr")
+ }
+ debug.Printf("parseAddress: spec=%q", spec)
+
+ return []*Address{{
+ Name: displayName,
+ Address: spec,
+ }}, nil
+}
+
+func (p *addrParser) consumeGroupList() ([]*Address, error) {
+ var group []*Address
+ // handle empty group.
+ p.skipSpace()
+ if p.consume(';') {
+ p.skipCFWS()
+ return group, nil
+ }
+
+ for {
+ p.skipSpace()
+ // embedded groups not allowed.
+ addrs, err := p.parseAddress(false)
+ if err != nil {
+ return nil, err
+ }
+ group = append(group, addrs...)
+
+ if !p.skipCFWS() {
+ return nil, errors.New("mail: misformatted parenthetical comment")
+ }
+ if p.consume(';') {
+ p.skipCFWS()
+ break
+ }
+ if !p.consume(',') {
+ return nil, errors.New("mail: expected comma")
+ }
+ }
+ return group, nil
+}
+
+// consumeAddrSpec parses a single RFC 5322 addr-spec at the start of p.
+func (p *addrParser) consumeAddrSpec() (spec string, err error) {
+ debug.Printf("consumeAddrSpec: %q", p.s)
+
+ orig := *p
+ defer func() {
+ if err != nil {
+ *p = orig
+ }
+ }()
+
+ // local-part = dot-atom / quoted-string
+ var localPart string
+ p.skipSpace()
+ if p.empty() {
+ return "", errors.New("mail: no addr-spec")
+ }
+ if p.peek() == '"' {
+ // quoted-string
+ debug.Printf("consumeAddrSpec: parsing quoted-string")
+ localPart, err = p.consumeQuotedString()
+ if localPart == "" {
+ err = errors.New("mail: empty quoted string in addr-spec")
+ }
+ } else {
+ // dot-atom
+ debug.Printf("consumeAddrSpec: parsing dot-atom")
+ localPart, err = p.consumeAtom(true, false)
+ }
+ if err != nil {
+ debug.Printf("consumeAddrSpec: failed: %v", err)
+ return "", err
+ }
+
+ if !p.consume('@') {
+ return "", errors.New("mail: missing @ in addr-spec")
+ }
+
+ // domain = dot-atom / domain-literal
+ var domain string
+ p.skipSpace()
+ if p.empty() {
+ return "", errors.New("mail: no domain in addr-spec")
+ }
+ // TODO(dsymonds): Handle domain-literal
+ domain, err = p.consumeAtom(true, false)
+ if err != nil {
+ return "", err
+ }
+
+ return localPart + "@" + domain, nil
+}
+
+// consumePhrase parses the RFC 5322 phrase at the start of p.
+func (p *addrParser) consumePhrase() (phrase string, err error) {
+ debug.Printf("consumePhrase: [%s]", p.s)
+ // phrase = 1*word
+ var words []string
+ var isPrevEncoded bool
+ for {
+ // word = atom / quoted-string
+ var word string
+ p.skipSpace()
+ if p.empty() {
+ break
+ }
+ isEncoded := false
+ if p.peek() == '"' {
+ // quoted-string
+ word, err = p.consumeQuotedString()
+ } else {
+ // atom
+ // We actually parse dot-atom here to be more permissive
+ // than what RFC 5322 specifies.
+ word, err = p.consumeAtom(true, true)
+ if err == nil {
+ word, isEncoded, err = p.decodeRFC2047Word(word)
+ }
+ }
+
+ if err != nil {
+ break
+ }
+ debug.Printf("consumePhrase: consumed %q", word)
+ if isPrevEncoded && isEncoded {
+ words[len(words)-1] += word
+ } else {
+ words = append(words, word)
+ }
+ isPrevEncoded = isEncoded
+ }
+ // Ignore any error if we got at least one word.
+ if err != nil && len(words) == 0 {
+ debug.Printf("consumePhrase: hit err: %v", err)
+ return "", fmt.Errorf("mail: missing word in phrase: %v", err)
+ }
+ phrase = strings.Join(words, " ")
+ return phrase, nil
+}
+
+// consumeQuotedString parses the quoted string at the start of p.
+func (p *addrParser) consumeQuotedString() (qs string, err error) {
+ // Assume first byte is '"'.
+ i := 1
+ qsb := make([]rune, 0, 10)
+
+ escaped := false
+
+Loop:
+ for {
+ r, size := utf8.DecodeRuneInString(p.s[i:])
+
+ switch {
+ case size == 0:
+ return "", errors.New("mail: unclosed quoted-string")
+
+ case size == 1 && r == utf8.RuneError:
+ return "", fmt.Errorf("mail: invalid utf-8 in quoted-string: %q", p.s)
+
+ case escaped:
+ // quoted-pair = ("\" (VCHAR / WSP))
+
+ if !isVchar(r) && !isWSP(r) {
+ return "", fmt.Errorf("mail: bad character in quoted-string: %q", r)
+ }
+
+ qsb = append(qsb, r)
+ escaped = false
+
+ case isQtext(r) || isWSP(r):
+ // qtext (printable US-ASCII excluding " and \), or
+ // FWS (almost; we're ignoring CRLF)
+ qsb = append(qsb, r)
+
+ case r == '"':
+ break Loop
+
+ case r == '\\':
+ escaped = true
+
+ default:
+ return "", fmt.Errorf("mail: bad character in quoted-string: %q", r)
+
+ }
+
+ i += size
+ }
+ p.s = p.s[i+1:]
+ return string(qsb), nil
+}
+
+// consumeAtom parses an RFC 5322 atom at the start of p.
+// If dot is true, consumeAtom parses an RFC 5322 dot-atom instead.
+// If permissive is true, consumeAtom will not fail on:
+// - leading/trailing/double dots in the atom (see golang.org/issue/4938)
+// - special characters (RFC 5322 3.2.3) except '<', '>', ':' and '"' (see golang.org/issue/21018)
+func (p *addrParser) consumeAtom(dot bool, permissive bool) (atom string, err error) {
+ i := 0
+
+Loop:
+ for {
+ r, size := utf8.DecodeRuneInString(p.s[i:])
+ switch {
+ case size == 1 && r == utf8.RuneError:
+ return "", fmt.Errorf("mail: invalid utf-8 in address: %q", p.s)
+
+ case size == 0 || !isAtext(r, dot, permissive):
+ break Loop
+
+ default:
+ i += size
+
+ }
+ }
+
+ if i == 0 {
+ return "", errors.New("mail: invalid string")
+ }
+ atom, p.s = p.s[:i], p.s[i:]
+ if !permissive {
+ if strings.HasPrefix(atom, ".") {
+ return "", errors.New("mail: leading dot in atom")
+ }
+ if strings.Contains(atom, "..") {
+ return "", errors.New("mail: double dot in atom")
+ }
+ if strings.HasSuffix(atom, ".") {
+ return "", errors.New("mail: trailing dot in atom")
+ }
+ }
+ return atom, nil
+}
+
+func (p *addrParser) consumeDisplayNameComment() (string, error) {
+ if !p.consume('(') {
+ return "", errors.New("mail: comment does not start with (")
+ }
+ comment, ok := p.consumeComment()
+ if !ok {
+ return "", errors.New("mail: misformatted parenthetical comment")
+ }
+
+ // TODO(stapelberg): parse quoted-string within comment
+ words := strings.FieldsFunc(comment, func(r rune) bool { return r == ' ' || r == '\t' })
+ for idx, word := range words {
+ decoded, isEncoded, err := p.decodeRFC2047Word(word)
+ if err != nil {
+ return "", err
+ }
+ if isEncoded {
+ words[idx] = decoded
+ }
+ }
+
+ return strings.Join(words, " "), nil
+}
+
+func (p *addrParser) consume(c byte) bool {
+ if p.empty() || p.peek() != c {
+ return false
+ }
+ p.s = p.s[1:]
+ return true
+}
+
+// skipSpace skips the leading space and tab characters.
+func (p *addrParser) skipSpace() {
+ p.s = strings.TrimLeft(p.s, " \t")
+}
+
+func (p *addrParser) peek() byte {
+ return p.s[0]
+}
+
+func (p *addrParser) empty() bool {
+ return p.len() == 0
+}
+
+func (p *addrParser) len() int {
+ return len(p.s)
+}
+
+// skipCFWS skips CFWS as defined in RFC5322.
+func (p *addrParser) skipCFWS() bool {
+ p.skipSpace()
+
+ for {
+ if !p.consume('(') {
+ break
+ }
+
+ if _, ok := p.consumeComment(); !ok {
+ return false
+ }
+
+ p.skipSpace()
+ }
+
+ return true
+}
+
+func (p *addrParser) consumeComment() (string, bool) {
+ // '(' already consumed.
+ depth := 1
+
+ var comment string
+ for {
+ if p.empty() || depth == 0 {
+ break
+ }
+
+ if p.peek() == '\\' && p.len() > 1 {
+ p.s = p.s[1:]
+ } else if p.peek() == '(' {
+ depth++
+ } else if p.peek() == ')' {
+ depth--
+ }
+ if depth > 0 {
+ comment += p.s[:1]
+ }
+ p.s = p.s[1:]
+ }
+
+ return comment, depth == 0
+}
+
+func (p *addrParser) decodeRFC2047Word(s string) (word string, isEncoded bool, err error) {
+ dec := p.dec
+ if dec == nil {
+ dec = &rfc2047Decoder
+ }
+
+ // Substitute our own CharsetReader function so that we can tell
+ // whether an error from the Decode method was due to the
+ // CharsetReader (meaning the charset is invalid).
+ // We used to look for the charsetError type in the error result,
+ // but that behaves badly with CharsetReaders other than the
+ // one in rfc2047Decoder.
+ adec := *dec
+ charsetReaderError := false
+ adec.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {
+ if dec.CharsetReader == nil {
+ charsetReaderError = true
+ return nil, charsetError(charset)
+ }
+ r, err := dec.CharsetReader(charset, input)
+ if err != nil {
+ charsetReaderError = true
+ }
+ return r, err
+ }
+ word, err = adec.Decode(s)
+ if err == nil {
+ return word, true, nil
+ }
+
+ // If the error came from the character set reader
+ // (meaning the character set itself is invalid
+ // but the decoding worked fine until then),
+ // return the original text and the error,
+ // with isEncoded=true.
+ if charsetReaderError {
+ return s, true, err
+ }
+
+ // Ignore invalid RFC 2047 encoded-word errors.
+ return s, false, nil
+}
+
+var rfc2047Decoder = mime.WordDecoder{
+ CharsetReader: func(charset string, input io.Reader) (io.Reader, error) {
+ return nil, charsetError(charset)
+ },
+}
+
+type charsetError string
+
+func (e charsetError) Error() string {
+ return fmt.Sprintf("charset not supported: %q", string(e))
+}
+
+// isAtext reports whether r is an RFC 5322 atext character.
+// If dot is true, period is included.
+// If permissive is true, RFC 5322 3.2.3 specials is included,
+// except '<', '>', ':' and '"'.
+func isAtext(r rune, dot, permissive bool) bool {
+ switch r {
+ case '.':
+ return dot
+
+ // RFC 5322 3.2.3. specials
+ case '(', ')', '[', ']', ';', '@', '\\', ',':
+ return permissive
+
+ case '<', '>', '"', ':':
+ return false
+ }
+ return isVchar(r)
+}
+
+// isQtext reports whether r is an RFC 5322 qtext character.
+func isQtext(r rune) bool {
+ // Printable US-ASCII, excluding backslash or quote.
+ if r == '\\' || r == '"' {
+ return false
+ }
+ return isVchar(r)
+}
+
+// quoteString renders a string as an RFC 5322 quoted-string.
+func quoteString(s string) string {
+ var b strings.Builder
+ b.WriteByte('"')
+ for _, r := range s {
+ if isQtext(r) || isWSP(r) {
+ b.WriteRune(r)
+ } else if isVchar(r) {
+ b.WriteByte('\\')
+ b.WriteRune(r)
+ }
+ }
+ b.WriteByte('"')
+ return b.String()
+}
+
+// isVchar reports whether r is an RFC 5322 VCHAR character.
+func isVchar(r rune) bool {
+ // Visible (printing) characters.
+ return '!' <= r && r <= '~' || isMultibyte(r)
+}
+
+// isMultibyte reports whether r is a multi-byte UTF-8 character
+// as supported by RFC 6532.
+func isMultibyte(r rune) bool {
+ return r >= utf8.RuneSelf
+}
+
+// isWSP reports whether r is a WSP (white space).
+// WSP is a space or horizontal tab (RFC 5234 Appendix B).
+func isWSP(r rune) bool {
+ return r == ' ' || r == '\t'
+}
diff --git a/contrib/go/_std_1.21/src/net/mail/ya.make b/contrib/go/_std_1.21/src/net/mail/ya.make
new file mode 100644
index 0000000000..5b4375b9cd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/mail/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ message.go
+)
+
+GO_TEST_SRCS(message_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/net/mptcpsock_linux.go b/contrib/go/_std_1.21/src/net/mptcpsock_linux.go
new file mode 100644
index 0000000000..b2ac3ee718
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/mptcpsock_linux.go
@@ -0,0 +1,127 @@
+// Copyright 2023 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 net
+
+import (
+ "context"
+ "errors"
+ "internal/poll"
+ "internal/syscall/unix"
+ "sync"
+ "syscall"
+)
+
+var (
+ mptcpOnce sync.Once
+ mptcpAvailable bool
+ hasSOLMPTCP bool
+)
+
+// These constants aren't in the syscall package, which is frozen
+const (
+ _IPPROTO_MPTCP = 0x106
+ _SOL_MPTCP = 0x11c
+ _MPTCP_INFO = 0x1
+)
+
+func supportsMultipathTCP() bool {
+ mptcpOnce.Do(initMPTCPavailable)
+ return mptcpAvailable
+}
+
+// Check that MPTCP is supported by attempting to create an MPTCP socket and by
+// looking at the returned error if any.
+func initMPTCPavailable() {
+ s, err := sysSocket(syscall.AF_INET, syscall.SOCK_STREAM, _IPPROTO_MPTCP)
+ switch {
+ case errors.Is(err, syscall.EPROTONOSUPPORT): // Not supported: >= v5.6
+ case errors.Is(err, syscall.EINVAL): // Not supported: < v5.6
+ case err == nil: // Supported and no error
+ poll.CloseFunc(s)
+ fallthrough
+ default:
+ // another error: MPTCP was not available but it might be later
+ mptcpAvailable = true
+ }
+
+ major, minor := unix.KernelVersion()
+ // SOL_MPTCP only supported from kernel 5.16
+ hasSOLMPTCP = major > 5 || (major == 5 && minor >= 16)
+}
+
+func (sd *sysDialer) dialMPTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
+ if supportsMultipathTCP() {
+ if conn, err := sd.doDialTCPProto(ctx, laddr, raddr, _IPPROTO_MPTCP); err == nil {
+ return conn, nil
+ }
+ }
+
+ // Fallback to dialTCP if Multipath TCP isn't supported on this operating
+ // system. But also fallback in case of any error with MPTCP.
+ //
+ // Possible MPTCP specific error: ENOPROTOOPT (sysctl net.mptcp.enabled=0)
+ // But just in case MPTCP is blocked differently (SELinux, etc.), just
+ // retry with "plain" TCP.
+ return sd.dialTCP(ctx, laddr, raddr)
+}
+
+func (sl *sysListener) listenMPTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) {
+ if supportsMultipathTCP() {
+ if dial, err := sl.listenTCPProto(ctx, laddr, _IPPROTO_MPTCP); err == nil {
+ return dial, nil
+ }
+ }
+
+ // Fallback to listenTCP if Multipath TCP isn't supported on this operating
+ // system. But also fallback in case of any error with MPTCP.
+ //
+ // Possible MPTCP specific error: ENOPROTOOPT (sysctl net.mptcp.enabled=0)
+ // But just in case MPTCP is blocked differently (SELinux, etc.), just
+ // retry with "plain" TCP.
+ return sl.listenTCP(ctx, laddr)
+}
+
+// hasFallenBack reports whether the MPTCP connection has fallen back to "plain"
+// TCP.
+//
+// A connection can fallback to TCP for different reasons, e.g. the other peer
+// doesn't support it, a middle box "accidentally" drops the option, etc.
+//
+// If the MPTCP protocol has not been requested when creating the socket, this
+// method will return true: MPTCP is not being used.
+//
+// Kernel >= 5.16 returns EOPNOTSUPP/ENOPROTOOPT in case of fallback.
+// Older kernels will always return them even if MPTCP is used: not usable.
+func hasFallenBack(fd *netFD) bool {
+ _, err := fd.pfd.GetsockoptInt(_SOL_MPTCP, _MPTCP_INFO)
+
+ // 2 expected errors in case of fallback depending on the address family
+ // - AF_INET: EOPNOTSUPP
+ // - AF_INET6: ENOPROTOOPT
+ return err == syscall.EOPNOTSUPP || err == syscall.ENOPROTOOPT
+}
+
+// isUsingMPTCPProto reports whether the socket protocol is MPTCP.
+//
+// Compared to hasFallenBack method, here only the socket protocol being used is
+// checked: it can be MPTCP but it doesn't mean MPTCP is used on the wire, maybe
+// a fallback to TCP has been done.
+func isUsingMPTCPProto(fd *netFD) bool {
+ proto, _ := fd.pfd.GetsockoptInt(syscall.SOL_SOCKET, syscall.SO_PROTOCOL)
+
+ return proto == _IPPROTO_MPTCP
+}
+
+// isUsingMultipathTCP reports whether MPTCP is still being used.
+//
+// Please look at the description of hasFallenBack (kernel >=5.16) and
+// isUsingMPTCPProto methods for more details about what is being checked here.
+func isUsingMultipathTCP(fd *netFD) bool {
+ if hasSOLMPTCP {
+ return !hasFallenBack(fd)
+ }
+
+ return isUsingMPTCPProto(fd)
+}
diff --git a/contrib/go/_std_1.21/src/net/mptcpsock_stub.go b/contrib/go/_std_1.21/src/net/mptcpsock_stub.go
new file mode 100644
index 0000000000..458c1530d7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/mptcpsock_stub.go
@@ -0,0 +1,23 @@
+// Copyright 2023 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.
+
+//go:build !linux
+
+package net
+
+import (
+ "context"
+)
+
+func (sd *sysDialer) dialMPTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
+ return sd.dialTCP(ctx, laddr, raddr)
+}
+
+func (sl *sysListener) listenMPTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) {
+ return sl.listenTCP(ctx, laddr)
+}
+
+func isUsingMultipathTCP(fd *netFD) bool {
+ return false
+}
diff --git a/contrib/go/_std_1.21/src/net/net.go b/contrib/go/_std_1.21/src/net/net.go
new file mode 100644
index 0000000000..5cfc25ffca
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/net.go
@@ -0,0 +1,767 @@
+// Copyright 2009 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 net provides a portable interface for network I/O, including
+TCP/IP, UDP, domain name resolution, and Unix domain sockets.
+
+Although the package provides access to low-level networking
+primitives, most clients will need only the basic interface provided
+by the Dial, Listen, and Accept functions and the associated
+Conn and Listener interfaces. The crypto/tls package uses
+the same interfaces and similar Dial and Listen functions.
+
+The Dial function connects to a server:
+
+ conn, err := net.Dial("tcp", "golang.org:80")
+ if err != nil {
+ // handle error
+ }
+ fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
+ status, err := bufio.NewReader(conn).ReadString('\n')
+ // ...
+
+The Listen function creates servers:
+
+ ln, err := net.Listen("tcp", ":8080")
+ if err != nil {
+ // handle error
+ }
+ for {
+ conn, err := ln.Accept()
+ if err != nil {
+ // handle error
+ }
+ go handleConnection(conn)
+ }
+
+# Name Resolution
+
+The method for resolving domain names, whether indirectly with functions like Dial
+or directly with functions like LookupHost and LookupAddr, varies by operating system.
+
+On Unix systems, the resolver has two options for resolving names.
+It can use a pure Go resolver that sends DNS requests directly to the servers
+listed in /etc/resolv.conf, or it can use a cgo-based resolver that calls C
+library routines such as getaddrinfo and getnameinfo.
+
+By default the pure Go resolver is used, because a blocked DNS request consumes
+only a goroutine, while a blocked C call consumes an operating system thread.
+When cgo is available, the cgo-based resolver is used instead under a variety of
+conditions: on systems that do not let programs make direct DNS requests (OS X),
+when the LOCALDOMAIN environment variable is present (even if empty),
+when the RES_OPTIONS or HOSTALIASES environment variable is non-empty,
+when the ASR_CONFIG environment variable is non-empty (OpenBSD only),
+when /etc/resolv.conf or /etc/nsswitch.conf specify the use of features that the
+Go resolver does not implement, and when the name being looked up ends in .local
+or is an mDNS name.
+
+The resolver decision can be overridden by setting the netdns value of the
+GODEBUG environment variable (see package runtime) to go or cgo, as in:
+
+ export GODEBUG=netdns=go # force pure Go resolver
+ export GODEBUG=netdns=cgo # force native resolver (cgo, win32)
+
+The decision can also be forced while building the Go source tree
+by setting the netgo or netcgo build tag.
+
+A numeric netdns setting, as in GODEBUG=netdns=1, causes the resolver
+to print debugging information about its decisions.
+To force a particular resolver while also printing debugging information,
+join the two settings by a plus sign, as in GODEBUG=netdns=go+1.
+
+On macOS, if Go code that uses the net package is built with
+-buildmode=c-archive, linking the resulting archive into a C program
+requires passing -lresolv when linking the C code.
+
+On Plan 9, the resolver always accesses /net/cs and /net/dns.
+
+On Windows, in Go 1.18.x and earlier, the resolver always used C
+library functions, such as GetAddrInfo and DnsQuery.
+*/
+package net
+
+import (
+ "context"
+ "errors"
+ "internal/poll"
+ "io"
+ "os"
+ "sync"
+ "syscall"
+ "time"
+)
+
+// Addr represents a network end point address.
+//
+// The two methods Network and String conventionally return strings
+// that can be passed as the arguments to Dial, but the exact form
+// and meaning of the strings is up to the implementation.
+type Addr interface {
+ Network() string // name of the network (for example, "tcp", "udp")
+ String() string // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80")
+}
+
+// Conn is a generic stream-oriented network connection.
+//
+// Multiple goroutines may invoke methods on a Conn simultaneously.
+type Conn interface {
+ // Read reads data from the connection.
+ // Read can be made to time out and return an error after a fixed
+ // time limit; see SetDeadline and SetReadDeadline.
+ Read(b []byte) (n int, err error)
+
+ // Write writes data to the connection.
+ // Write can be made to time out and return an error after a fixed
+ // time limit; see SetDeadline and SetWriteDeadline.
+ Write(b []byte) (n int, err error)
+
+ // Close closes the connection.
+ // Any blocked Read or Write operations will be unblocked and return errors.
+ Close() error
+
+ // LocalAddr returns the local network address, if known.
+ LocalAddr() Addr
+
+ // RemoteAddr returns the remote network address, if known.
+ RemoteAddr() Addr
+
+ // SetDeadline sets the read and write deadlines associated
+ // with the connection. It is equivalent to calling both
+ // SetReadDeadline and SetWriteDeadline.
+ //
+ // A deadline is an absolute time after which I/O operations
+ // fail instead of blocking. The deadline applies to all future
+ // and pending I/O, not just the immediately following call to
+ // Read or Write. After a deadline has been exceeded, the
+ // connection can be refreshed by setting a deadline in the future.
+ //
+ // If the deadline is exceeded a call to Read or Write or to other
+ // I/O methods will return an error that wraps os.ErrDeadlineExceeded.
+ // This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
+ // The error's Timeout method will return true, but note that there
+ // are other possible errors for which the Timeout method will
+ // return true even if the deadline has not been exceeded.
+ //
+ // An idle timeout can be implemented by repeatedly extending
+ // the deadline after successful Read or Write calls.
+ //
+ // A zero value for t means I/O operations will not time out.
+ SetDeadline(t time.Time) error
+
+ // SetReadDeadline sets the deadline for future Read calls
+ // and any currently-blocked Read call.
+ // A zero value for t means Read will not time out.
+ SetReadDeadline(t time.Time) error
+
+ // SetWriteDeadline sets the deadline for future Write calls
+ // and any currently-blocked Write call.
+ // Even if write times out, it may return n > 0, indicating that
+ // some of the data was successfully written.
+ // A zero value for t means Write will not time out.
+ SetWriteDeadline(t time.Time) error
+}
+
+type conn struct {
+ fd *netFD
+}
+
+func (c *conn) ok() bool { return c != nil && c.fd != nil }
+
+// Implementation of the Conn interface.
+
+// Read implements the Conn Read method.
+func (c *conn) Read(b []byte) (int, error) {
+ if !c.ok() {
+ return 0, syscall.EINVAL
+ }
+ n, err := c.fd.Read(b)
+ if err != nil && err != io.EOF {
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return n, err
+}
+
+// Write implements the Conn Write method.
+func (c *conn) Write(b []byte) (int, error) {
+ if !c.ok() {
+ return 0, syscall.EINVAL
+ }
+ n, err := c.fd.Write(b)
+ if err != nil {
+ err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return n, err
+}
+
+// Close closes the connection.
+func (c *conn) Close() error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ err := c.fd.Close()
+ if err != nil {
+ err = &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return err
+}
+
+// LocalAddr returns the local network address.
+// The Addr returned is shared by all invocations of LocalAddr, so
+// do not modify it.
+func (c *conn) LocalAddr() Addr {
+ if !c.ok() {
+ return nil
+ }
+ return c.fd.laddr
+}
+
+// RemoteAddr returns the remote network address.
+// The Addr returned is shared by all invocations of RemoteAddr, so
+// do not modify it.
+func (c *conn) RemoteAddr() Addr {
+ if !c.ok() {
+ return nil
+ }
+ return c.fd.raddr
+}
+
+// SetDeadline implements the Conn SetDeadline method.
+func (c *conn) SetDeadline(t time.Time) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := c.fd.SetDeadline(t); err != nil {
+ return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
+ }
+ return nil
+}
+
+// SetReadDeadline implements the Conn SetReadDeadline method.
+func (c *conn) SetReadDeadline(t time.Time) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := c.fd.SetReadDeadline(t); err != nil {
+ return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
+ }
+ return nil
+}
+
+// SetWriteDeadline implements the Conn SetWriteDeadline method.
+func (c *conn) SetWriteDeadline(t time.Time) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := c.fd.SetWriteDeadline(t); err != nil {
+ return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
+ }
+ return nil
+}
+
+// SetReadBuffer sets the size of the operating system's
+// receive buffer associated with the connection.
+func (c *conn) SetReadBuffer(bytes int) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := setReadBuffer(c.fd, bytes); err != nil {
+ return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
+ }
+ return nil
+}
+
+// SetWriteBuffer sets the size of the operating system's
+// transmit buffer associated with the connection.
+func (c *conn) SetWriteBuffer(bytes int) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := setWriteBuffer(c.fd, bytes); err != nil {
+ return &OpError{Op: "set", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
+ }
+ return nil
+}
+
+// File returns a copy of the underlying os.File.
+// It is the caller's responsibility to close f when finished.
+// Closing c does not affect f, and closing f does not affect c.
+//
+// The returned os.File's file descriptor is different from the connection's.
+// Attempting to change properties of the original using this duplicate
+// may or may not have the desired effect.
+func (c *conn) File() (f *os.File, err error) {
+ f, err = c.fd.dup()
+ if err != nil {
+ err = &OpError{Op: "file", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return
+}
+
+// PacketConn is a generic packet-oriented network connection.
+//
+// Multiple goroutines may invoke methods on a PacketConn simultaneously.
+type PacketConn interface {
+ // ReadFrom reads a packet from the connection,
+ // copying the payload into p. It returns the number of
+ // bytes copied into p and the return address that
+ // was on the packet.
+ // It returns the number of bytes read (0 <= n <= len(p))
+ // and any error encountered. Callers should always process
+ // the n > 0 bytes returned before considering the error err.
+ // ReadFrom can be made to time out and return an error after a
+ // fixed time limit; see SetDeadline and SetReadDeadline.
+ ReadFrom(p []byte) (n int, addr Addr, err error)
+
+ // WriteTo writes a packet with payload p to addr.
+ // WriteTo can be made to time out and return an Error after a
+ // fixed time limit; see SetDeadline and SetWriteDeadline.
+ // On packet-oriented connections, write timeouts are rare.
+ WriteTo(p []byte, addr Addr) (n int, err error)
+
+ // Close closes the connection.
+ // Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
+ Close() error
+
+ // LocalAddr returns the local network address, if known.
+ LocalAddr() Addr
+
+ // SetDeadline sets the read and write deadlines associated
+ // with the connection. It is equivalent to calling both
+ // SetReadDeadline and SetWriteDeadline.
+ //
+ // A deadline is an absolute time after which I/O operations
+ // fail instead of blocking. The deadline applies to all future
+ // and pending I/O, not just the immediately following call to
+ // Read or Write. After a deadline has been exceeded, the
+ // connection can be refreshed by setting a deadline in the future.
+ //
+ // If the deadline is exceeded a call to Read or Write or to other
+ // I/O methods will return an error that wraps os.ErrDeadlineExceeded.
+ // This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
+ // The error's Timeout method will return true, but note that there
+ // are other possible errors for which the Timeout method will
+ // return true even if the deadline has not been exceeded.
+ //
+ // An idle timeout can be implemented by repeatedly extending
+ // the deadline after successful ReadFrom or WriteTo calls.
+ //
+ // A zero value for t means I/O operations will not time out.
+ SetDeadline(t time.Time) error
+
+ // SetReadDeadline sets the deadline for future ReadFrom calls
+ // and any currently-blocked ReadFrom call.
+ // A zero value for t means ReadFrom will not time out.
+ SetReadDeadline(t time.Time) error
+
+ // SetWriteDeadline sets the deadline for future WriteTo calls
+ // and any currently-blocked WriteTo call.
+ // Even if write times out, it may return n > 0, indicating that
+ // some of the data was successfully written.
+ // A zero value for t means WriteTo will not time out.
+ SetWriteDeadline(t time.Time) error
+}
+
+var listenerBacklogCache struct {
+ sync.Once
+ val int
+}
+
+// listenerBacklog is a caching wrapper around maxListenerBacklog.
+func listenerBacklog() int {
+ listenerBacklogCache.Do(func() { listenerBacklogCache.val = maxListenerBacklog() })
+ return listenerBacklogCache.val
+}
+
+// A Listener is a generic network listener for stream-oriented protocols.
+//
+// Multiple goroutines may invoke methods on a Listener simultaneously.
+type Listener interface {
+ // Accept waits for and returns the next connection to the listener.
+ Accept() (Conn, error)
+
+ // Close closes the listener.
+ // Any blocked Accept operations will be unblocked and return errors.
+ Close() error
+
+ // Addr returns the listener's network address.
+ Addr() Addr
+}
+
+// An Error represents a network error.
+type Error interface {
+ error
+ Timeout() bool // Is the error a timeout?
+
+ // Deprecated: Temporary errors are not well-defined.
+ // Most "temporary" errors are timeouts, and the few exceptions are surprising.
+ // Do not use this method.
+ Temporary() bool
+}
+
+// Various errors contained in OpError.
+var (
+ // For connection setup operations.
+ errNoSuitableAddress = errors.New("no suitable address found")
+
+ // For connection setup and write operations.
+ errMissingAddress = errors.New("missing address")
+
+ // For both read and write operations.
+ errCanceled = canceledError{}
+ ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection")
+)
+
+// canceledError lets us return the same error string we have always
+// returned, while still being Is context.Canceled.
+type canceledError struct{}
+
+func (canceledError) Error() string { return "operation was canceled" }
+
+func (canceledError) Is(err error) bool { return err == context.Canceled }
+
+// mapErr maps from the context errors to the historical internal net
+// error values.
+func mapErr(err error) error {
+ switch err {
+ case context.Canceled:
+ return errCanceled
+ case context.DeadlineExceeded:
+ return errTimeout
+ default:
+ return err
+ }
+}
+
+// OpError is the error type usually returned by functions in the net
+// package. It describes the operation, network type, and address of
+// an error.
+type OpError struct {
+ // Op is the operation which caused the error, such as
+ // "read" or "write".
+ Op string
+
+ // Net is the network type on which this error occurred,
+ // such as "tcp" or "udp6".
+ Net string
+
+ // For operations involving a remote network connection, like
+ // Dial, Read, or Write, Source is the corresponding local
+ // network address.
+ Source Addr
+
+ // Addr is the network address for which this error occurred.
+ // For local operations, like Listen or SetDeadline, Addr is
+ // the address of the local endpoint being manipulated.
+ // For operations involving a remote network connection, like
+ // Dial, Read, or Write, Addr is the remote address of that
+ // connection.
+ Addr Addr
+
+ // Err is the error that occurred during the operation.
+ // The Error method panics if the error is nil.
+ Err error
+}
+
+func (e *OpError) Unwrap() error { return e.Err }
+
+func (e *OpError) Error() string {
+ if e == nil {
+ return "<nil>"
+ }
+ s := e.Op
+ if e.Net != "" {
+ s += " " + e.Net
+ }
+ if e.Source != nil {
+ s += " " + e.Source.String()
+ }
+ if e.Addr != nil {
+ if e.Source != nil {
+ s += "->"
+ } else {
+ s += " "
+ }
+ s += e.Addr.String()
+ }
+ s += ": " + e.Err.Error()
+ return s
+}
+
+var (
+ // aLongTimeAgo is a non-zero time, far in the past, used for
+ // immediate cancellation of dials.
+ aLongTimeAgo = time.Unix(1, 0)
+
+ // noDeadline and noCancel are just zero values for
+ // readability with functions taking too many parameters.
+ noDeadline = time.Time{}
+ noCancel = (chan struct{})(nil)
+)
+
+type timeout interface {
+ Timeout() bool
+}
+
+func (e *OpError) Timeout() bool {
+ if ne, ok := e.Err.(*os.SyscallError); ok {
+ t, ok := ne.Err.(timeout)
+ return ok && t.Timeout()
+ }
+ t, ok := e.Err.(timeout)
+ return ok && t.Timeout()
+}
+
+type temporary interface {
+ Temporary() bool
+}
+
+func (e *OpError) Temporary() bool {
+ // Treat ECONNRESET and ECONNABORTED as temporary errors when
+ // they come from calling accept. See issue 6163.
+ if e.Op == "accept" && isConnError(e.Err) {
+ return true
+ }
+
+ if ne, ok := e.Err.(*os.SyscallError); ok {
+ t, ok := ne.Err.(temporary)
+ return ok && t.Temporary()
+ }
+ t, ok := e.Err.(temporary)
+ return ok && t.Temporary()
+}
+
+// A ParseError is the error type of literal network address parsers.
+type ParseError struct {
+ // Type is the type of string that was expected, such as
+ // "IP address", "CIDR address".
+ Type string
+
+ // Text is the malformed text string.
+ Text string
+}
+
+func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text }
+
+func (e *ParseError) Timeout() bool { return false }
+func (e *ParseError) Temporary() bool { return false }
+
+type AddrError struct {
+ Err string
+ Addr string
+}
+
+func (e *AddrError) Error() string {
+ if e == nil {
+ return "<nil>"
+ }
+ s := e.Err
+ if e.Addr != "" {
+ s = "address " + e.Addr + ": " + s
+ }
+ return s
+}
+
+func (e *AddrError) Timeout() bool { return false }
+func (e *AddrError) Temporary() bool { return false }
+
+type UnknownNetworkError string
+
+func (e UnknownNetworkError) Error() string { return "unknown network " + string(e) }
+func (e UnknownNetworkError) Timeout() bool { return false }
+func (e UnknownNetworkError) Temporary() bool { return false }
+
+type InvalidAddrError string
+
+func (e InvalidAddrError) Error() string { return string(e) }
+func (e InvalidAddrError) Timeout() bool { return false }
+func (e InvalidAddrError) Temporary() bool { return false }
+
+// errTimeout exists to return the historical "i/o timeout" string
+// for context.DeadlineExceeded. See mapErr.
+// It is also used when Dialer.Deadline is exceeded.
+// error.Is(errTimeout, context.DeadlineExceeded) returns true.
+//
+// TODO(iant): We could consider changing this to os.ErrDeadlineExceeded
+// in the future, if we make
+//
+// errors.Is(os.ErrDeadlineExceeded, context.DeadlineExceeded)
+//
+// return true.
+var errTimeout error = &timeoutError{}
+
+type timeoutError struct{}
+
+func (e *timeoutError) Error() string { return "i/o timeout" }
+func (e *timeoutError) Timeout() bool { return true }
+func (e *timeoutError) Temporary() bool { return true }
+
+func (e *timeoutError) Is(err error) bool {
+ return err == context.DeadlineExceeded
+}
+
+// DNSConfigError represents an error reading the machine's DNS configuration.
+// (No longer used; kept for compatibility.)
+type DNSConfigError struct {
+ Err error
+}
+
+func (e *DNSConfigError) Unwrap() error { return e.Err }
+func (e *DNSConfigError) Error() string { return "error reading DNS config: " + e.Err.Error() }
+func (e *DNSConfigError) Timeout() bool { return false }
+func (e *DNSConfigError) Temporary() bool { return false }
+
+// Various errors contained in DNSError.
+var (
+ errNoSuchHost = errors.New("no such host")
+)
+
+// DNSError represents a DNS lookup error.
+type DNSError struct {
+ Err string // description of the error
+ Name string // name looked for
+ Server string // server used
+ IsTimeout bool // if true, timed out; not all timeouts set this
+ IsTemporary bool // if true, error is temporary; not all errors set this
+ IsNotFound bool // if true, host could not be found
+}
+
+func (e *DNSError) Error() string {
+ if e == nil {
+ return "<nil>"
+ }
+ s := "lookup " + e.Name
+ if e.Server != "" {
+ s += " on " + e.Server
+ }
+ s += ": " + e.Err
+ return s
+}
+
+// Timeout reports whether the DNS lookup is known to have timed out.
+// This is not always known; a DNS lookup may fail due to a timeout
+// and return a DNSError for which Timeout returns false.
+func (e *DNSError) Timeout() bool { return e.IsTimeout }
+
+// Temporary reports whether the DNS error is known to be temporary.
+// This is not always known; a DNS lookup may fail due to a temporary
+// error and return a DNSError for which Temporary returns false.
+func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
+
+// errClosed exists just so that the docs for ErrClosed don't mention
+// the internal package poll.
+var errClosed = poll.ErrNetClosing
+
+// ErrClosed is the error returned by an I/O call on a network
+// connection that has already been closed, or that is closed by
+// another goroutine before the I/O is completed. This may be wrapped
+// in another error, and should normally be tested using
+// errors.Is(err, net.ErrClosed).
+var ErrClosed error = errClosed
+
+type writerOnly struct {
+ io.Writer
+}
+
+// Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
+// applicable.
+func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
+ // Use wrapper to hide existing r.ReadFrom from io.Copy.
+ return io.Copy(writerOnly{w}, r)
+}
+
+// Limit the number of concurrent cgo-using goroutines, because
+// each will block an entire operating system thread. The usual culprit
+// is resolving many DNS names in separate goroutines but the DNS
+// server is not responding. Then the many lookups each use a different
+// thread, and the system or the program runs out of threads.
+
+var threadLimit chan struct{}
+
+var threadOnce sync.Once
+
+func acquireThread() {
+ threadOnce.Do(func() {
+ threadLimit = make(chan struct{}, concurrentThreadsLimit())
+ })
+ threadLimit <- struct{}{}
+}
+
+func releaseThread() {
+ <-threadLimit
+}
+
+// buffersWriter is the interface implemented by Conns that support a
+// "writev"-like batch write optimization.
+// writeBuffers should fully consume and write all chunks from the
+// provided Buffers, else it should report a non-nil error.
+type buffersWriter interface {
+ writeBuffers(*Buffers) (int64, error)
+}
+
+// Buffers contains zero or more runs of bytes to write.
+//
+// On certain machines, for certain types of connections, this is
+// optimized into an OS-specific batch write operation (such as
+// "writev").
+type Buffers [][]byte
+
+var (
+ _ io.WriterTo = (*Buffers)(nil)
+ _ io.Reader = (*Buffers)(nil)
+)
+
+// WriteTo writes contents of the buffers to w.
+//
+// WriteTo implements io.WriterTo for Buffers.
+//
+// WriteTo modifies the slice v as well as v[i] for 0 <= i < len(v),
+// but does not modify v[i][j] for any i, j.
+func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) {
+ if wv, ok := w.(buffersWriter); ok {
+ return wv.writeBuffers(v)
+ }
+ for _, b := range *v {
+ nb, err := w.Write(b)
+ n += int64(nb)
+ if err != nil {
+ v.consume(n)
+ return n, err
+ }
+ }
+ v.consume(n)
+ return n, nil
+}
+
+// Read from the buffers.
+//
+// Read implements io.Reader for Buffers.
+//
+// Read modifies the slice v as well as v[i] for 0 <= i < len(v),
+// but does not modify v[i][j] for any i, j.
+func (v *Buffers) Read(p []byte) (n int, err error) {
+ for len(p) > 0 && len(*v) > 0 {
+ n0 := copy(p, (*v)[0])
+ v.consume(int64(n0))
+ p = p[n0:]
+ n += n0
+ }
+ if len(*v) == 0 {
+ err = io.EOF
+ }
+ return
+}
+
+func (v *Buffers) consume(n int64) {
+ for len(*v) > 0 {
+ ln0 := int64(len((*v)[0]))
+ if ln0 > n {
+ (*v)[0] = (*v)[0][n:]
+ return
+ }
+ n -= ln0
+ (*v)[0] = nil
+ *v = (*v)[1:]
+ }
+}
diff --git a/contrib/go/_std_1.21/src/net/netcgo_off.go b/contrib/go/_std_1.21/src/net/netcgo_off.go
new file mode 100644
index 0000000000..54677dcac6
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/netcgo_off.go
@@ -0,0 +1,9 @@
+// Copyright 2023 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.
+
+//go:build !netcgo
+
+package net
+
+const netCgoBuildTag = false
diff --git a/contrib/go/_std_1.21/src/net/netgo_off.go b/contrib/go/_std_1.21/src/net/netgo_off.go
new file mode 100644
index 0000000000..e6bc2d7d06
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/netgo_off.go
@@ -0,0 +1,9 @@
+// Copyright 2023 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.
+
+//go:build !netgo
+
+package net
+
+const netGoBuildTag = false
diff --git a/contrib/go/_std_1.20/src/net/netip/leaf_alts.go b/contrib/go/_std_1.21/src/net/netip/leaf_alts.go
index 70513abfd9..70513abfd9 100644
--- a/contrib/go/_std_1.20/src/net/netip/leaf_alts.go
+++ b/contrib/go/_std_1.21/src/net/netip/leaf_alts.go
diff --git a/contrib/go/_std_1.21/src/net/netip/netip.go b/contrib/go/_std_1.21/src/net/netip/netip.go
new file mode 100644
index 0000000000..890b94be6c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/netip/netip.go
@@ -0,0 +1,1481 @@
+// 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 netip defines an IP address type that's a small value type.
+// Building on that [Addr] type, the package also defines [AddrPort] (an
+// IP address and a port) and [Prefix] (an IP address and a bit length
+// prefix).
+//
+// Compared to the [net.IP] type, [Addr] type takes less memory, is immutable,
+// and is comparable (supports == and being a map key).
+package netip
+
+import (
+ "errors"
+ "internal/bytealg"
+ "internal/intern"
+ "internal/itoa"
+ "math"
+ "strconv"
+)
+
+// Sizes: (64-bit)
+// net.IP: 24 byte slice header + {4, 16} = 28 to 40 bytes
+// net.IPAddr: 40 byte slice header + {4, 16} = 44 to 56 bytes + zone length
+// netip.Addr: 24 bytes (zone is per-name singleton, shared across all users)
+
+// Addr represents an IPv4 or IPv6 address (with or without a scoped
+// addressing zone), similar to [net.IP] or [net.IPAddr].
+//
+// Unlike [net.IP] or [net.IPAddr], Addr is a comparable value
+// type (it supports == and can be a map key) and is immutable.
+//
+// The zero Addr is not a valid IP address.
+// Addr{} is distinct from both 0.0.0.0 and ::.
+type Addr struct {
+ // addr is the hi and lo bits of an IPv6 address. If z==z4,
+ // hi and lo contain the IPv4-mapped IPv6 address.
+ //
+ // hi and lo are constructed by interpreting a 16-byte IPv6
+ // address as a big-endian 128-bit number. The most significant
+ // bits of that number go into hi, the rest into lo.
+ //
+ // For example, 0011:2233:4455:6677:8899:aabb:ccdd:eeff is stored as:
+ // addr.hi = 0x0011223344556677
+ // addr.lo = 0x8899aabbccddeeff
+ //
+ // We store IPs like this, rather than as [16]byte, because it
+ // turns most operations on IPs into arithmetic and bit-twiddling
+ // operations on 64-bit registers, which is much faster than
+ // bytewise processing.
+ addr uint128
+
+ // z is a combination of the address family and the IPv6 zone.
+ //
+ // nil means invalid IP address (for a zero Addr).
+ // z4 means an IPv4 address.
+ // z6noz means an IPv6 address without a zone.
+ //
+ // Otherwise it's the interned zone name string.
+ z *intern.Value
+}
+
+// z0, z4, and z6noz are sentinel Addr.z values.
+// See the Addr type's field docs.
+var (
+ z0 = (*intern.Value)(nil)
+ z4 = new(intern.Value)
+ z6noz = new(intern.Value)
+)
+
+// IPv6LinkLocalAllNodes returns the IPv6 link-local all nodes multicast
+// address ff02::1.
+func IPv6LinkLocalAllNodes() Addr { return AddrFrom16([16]byte{0: 0xff, 1: 0x02, 15: 0x01}) }
+
+// IPv6LinkLocalAllRouters returns the IPv6 link-local all routers multicast
+// address ff02::2.
+func IPv6LinkLocalAllRouters() Addr { return AddrFrom16([16]byte{0: 0xff, 1: 0x02, 15: 0x02}) }
+
+// IPv6Loopback returns the IPv6 loopback address ::1.
+func IPv6Loopback() Addr { return AddrFrom16([16]byte{15: 0x01}) }
+
+// IPv6Unspecified returns the IPv6 unspecified address "::".
+func IPv6Unspecified() Addr { return Addr{z: z6noz} }
+
+// IPv4Unspecified returns the IPv4 unspecified address "0.0.0.0".
+func IPv4Unspecified() Addr { return AddrFrom4([4]byte{}) }
+
+// AddrFrom4 returns the address of the IPv4 address given by the bytes in addr.
+func AddrFrom4(addr [4]byte) Addr {
+ return Addr{
+ addr: uint128{0, 0xffff00000000 | uint64(addr[0])<<24 | uint64(addr[1])<<16 | uint64(addr[2])<<8 | uint64(addr[3])},
+ z: z4,
+ }
+}
+
+// AddrFrom16 returns the IPv6 address given by the bytes in addr.
+// An IPv4-mapped IPv6 address is left as an IPv6 address.
+// (Use Unmap to convert them if needed.)
+func AddrFrom16(addr [16]byte) Addr {
+ return Addr{
+ addr: uint128{
+ beUint64(addr[:8]),
+ beUint64(addr[8:]),
+ },
+ z: z6noz,
+ }
+}
+
+// ParseAddr parses s as an IP address, returning the result. The string
+// s can be in dotted decimal ("192.0.2.1"), IPv6 ("2001:db8::68"),
+// or IPv6 with a scoped addressing zone ("fe80::1cc0:3e8c:119f:c2e1%ens18").
+func ParseAddr(s string) (Addr, error) {
+ for i := 0; i < len(s); i++ {
+ switch s[i] {
+ case '.':
+ return parseIPv4(s)
+ case ':':
+ return parseIPv6(s)
+ case '%':
+ // Assume that this was trying to be an IPv6 address with
+ // a zone specifier, but the address is missing.
+ return Addr{}, parseAddrError{in: s, msg: "missing IPv6 address"}
+ }
+ }
+ return Addr{}, parseAddrError{in: s, msg: "unable to parse IP"}
+}
+
+// MustParseAddr calls ParseAddr(s) and panics on error.
+// It is intended for use in tests with hard-coded strings.
+func MustParseAddr(s string) Addr {
+ ip, err := ParseAddr(s)
+ if err != nil {
+ panic(err)
+ }
+ return ip
+}
+
+type parseAddrError struct {
+ in string // the string given to ParseAddr
+ msg string // an explanation of the parse failure
+ at string // optionally, the unparsed portion of in at which the error occurred.
+}
+
+func (err parseAddrError) Error() string {
+ q := strconv.Quote
+ if err.at != "" {
+ return "ParseAddr(" + q(err.in) + "): " + err.msg + " (at " + q(err.at) + ")"
+ }
+ return "ParseAddr(" + q(err.in) + "): " + err.msg
+}
+
+// parseIPv4 parses s as an IPv4 address (in form "192.168.0.1").
+func parseIPv4(s string) (ip Addr, err error) {
+ var fields [4]uint8
+ var val, pos int
+ var digLen int // number of digits in current octet
+ for i := 0; i < len(s); i++ {
+ if s[i] >= '0' && s[i] <= '9' {
+ if digLen == 1 && val == 0 {
+ return Addr{}, parseAddrError{in: s, msg: "IPv4 field has octet with leading zero"}
+ }
+ val = val*10 + int(s[i]) - '0'
+ digLen++
+ if val > 255 {
+ return Addr{}, parseAddrError{in: s, msg: "IPv4 field has value >255"}
+ }
+ } else if s[i] == '.' {
+ // .1.2.3
+ // 1.2.3.
+ // 1..2.3
+ if i == 0 || i == len(s)-1 || s[i-1] == '.' {
+ return Addr{}, parseAddrError{in: s, msg: "IPv4 field must have at least one digit", at: s[i:]}
+ }
+ // 1.2.3.4.5
+ if pos == 3 {
+ return Addr{}, parseAddrError{in: s, msg: "IPv4 address too long"}
+ }
+ fields[pos] = uint8(val)
+ pos++
+ val = 0
+ digLen = 0
+ } else {
+ return Addr{}, parseAddrError{in: s, msg: "unexpected character", at: s[i:]}
+ }
+ }
+ if pos < 3 {
+ return Addr{}, parseAddrError{in: s, msg: "IPv4 address too short"}
+ }
+ fields[3] = uint8(val)
+ return AddrFrom4(fields), nil
+}
+
+// parseIPv6 parses s as an IPv6 address (in form "2001:db8::68").
+func parseIPv6(in string) (Addr, error) {
+ s := in
+
+ // Split off the zone right from the start. Yes it's a second scan
+ // of the string, but trying to handle it inline makes a bunch of
+ // other inner loop conditionals more expensive, and it ends up
+ // being slower.
+ zone := ""
+ i := bytealg.IndexByteString(s, '%')
+ if i != -1 {
+ s, zone = s[:i], s[i+1:]
+ if zone == "" {
+ // Not allowed to have an empty zone if explicitly specified.
+ return Addr{}, parseAddrError{in: in, msg: "zone must be a non-empty string"}
+ }
+ }
+
+ var ip [16]byte
+ ellipsis := -1 // position of ellipsis in ip
+
+ // Might have leading ellipsis
+ if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
+ ellipsis = 0
+ s = s[2:]
+ // Might be only ellipsis
+ if len(s) == 0 {
+ return IPv6Unspecified().WithZone(zone), nil
+ }
+ }
+
+ // Loop, parsing hex numbers followed by colon.
+ i = 0
+ for i < 16 {
+ // Hex number. Similar to parseIPv4, inlining the hex number
+ // parsing yields a significant performance increase.
+ off := 0
+ acc := uint32(0)
+ for ; off < len(s); off++ {
+ c := s[off]
+ if c >= '0' && c <= '9' {
+ acc = (acc << 4) + uint32(c-'0')
+ } else if c >= 'a' && c <= 'f' {
+ acc = (acc << 4) + uint32(c-'a'+10)
+ } else if c >= 'A' && c <= 'F' {
+ acc = (acc << 4) + uint32(c-'A'+10)
+ } else {
+ break
+ }
+ if acc > math.MaxUint16 {
+ // Overflow, fail.
+ return Addr{}, parseAddrError{in: in, msg: "IPv6 field has value >=2^16", at: s}
+ }
+ }
+ if off == 0 {
+ // No digits found, fail.
+ return Addr{}, parseAddrError{in: in, msg: "each colon-separated field must have at least one digit", at: s}
+ }
+
+ // If followed by dot, might be in trailing IPv4.
+ if off < len(s) && s[off] == '.' {
+ if ellipsis < 0 && i != 12 {
+ // Not the right place.
+ return Addr{}, parseAddrError{in: in, msg: "embedded IPv4 address must replace the final 2 fields of the address", at: s}
+ }
+ if i+4 > 16 {
+ // Not enough room.
+ return Addr{}, parseAddrError{in: in, msg: "too many hex fields to fit an embedded IPv4 at the end of the address", at: s}
+ }
+ // TODO: could make this a bit faster by having a helper
+ // that parses to a [4]byte, and have both parseIPv4 and
+ // parseIPv6 use it.
+ ip4, err := parseIPv4(s)
+ if err != nil {
+ return Addr{}, parseAddrError{in: in, msg: err.Error(), at: s}
+ }
+ ip[i] = ip4.v4(0)
+ ip[i+1] = ip4.v4(1)
+ ip[i+2] = ip4.v4(2)
+ ip[i+3] = ip4.v4(3)
+ s = ""
+ i += 4
+ break
+ }
+
+ // Save this 16-bit chunk.
+ ip[i] = byte(acc >> 8)
+ ip[i+1] = byte(acc)
+ i += 2
+
+ // Stop at end of string.
+ s = s[off:]
+ if len(s) == 0 {
+ break
+ }
+
+ // Otherwise must be followed by colon and more.
+ if s[0] != ':' {
+ return Addr{}, parseAddrError{in: in, msg: "unexpected character, want colon", at: s}
+ } else if len(s) == 1 {
+ return Addr{}, parseAddrError{in: in, msg: "colon must be followed by more characters", at: s}
+ }
+ s = s[1:]
+
+ // Look for ellipsis.
+ if s[0] == ':' {
+ if ellipsis >= 0 { // already have one
+ return Addr{}, parseAddrError{in: in, msg: "multiple :: in address", at: s}
+ }
+ ellipsis = i
+ s = s[1:]
+ if len(s) == 0 { // can be at end
+ break
+ }
+ }
+ }
+
+ // Must have used entire string.
+ if len(s) != 0 {
+ return Addr{}, parseAddrError{in: in, msg: "trailing garbage after address", at: s}
+ }
+
+ // If didn't parse enough, expand ellipsis.
+ if i < 16 {
+ if ellipsis < 0 {
+ return Addr{}, parseAddrError{in: in, msg: "address string too short"}
+ }
+ n := 16 - i
+ for j := i - 1; j >= ellipsis; j-- {
+ ip[j+n] = ip[j]
+ }
+ for j := ellipsis + n - 1; j >= ellipsis; j-- {
+ ip[j] = 0
+ }
+ } else if ellipsis >= 0 {
+ // Ellipsis must represent at least one 0 group.
+ return Addr{}, parseAddrError{in: in, msg: "the :: must expand to at least one field of zeros"}
+ }
+ return AddrFrom16(ip).WithZone(zone), nil
+}
+
+// AddrFromSlice parses the 4- or 16-byte byte slice as an IPv4 or IPv6 address.
+// Note that a net.IP can be passed directly as the []byte argument.
+// If slice's length is not 4 or 16, AddrFromSlice returns Addr{}, false.
+func AddrFromSlice(slice []byte) (ip Addr, ok bool) {
+ switch len(slice) {
+ case 4:
+ return AddrFrom4([4]byte(slice)), true
+ case 16:
+ return AddrFrom16([16]byte(slice)), true
+ }
+ return Addr{}, false
+}
+
+// v4 returns the i'th byte of ip. If ip is not an IPv4, v4 returns
+// unspecified garbage.
+func (ip Addr) v4(i uint8) uint8 {
+ return uint8(ip.addr.lo >> ((3 - i) * 8))
+}
+
+// v6 returns the i'th byte of ip. If ip is an IPv4 address, this
+// accesses the IPv4-mapped IPv6 address form of the IP.
+func (ip Addr) v6(i uint8) uint8 {
+ return uint8(*(ip.addr.halves()[(i/8)%2]) >> ((7 - i%8) * 8))
+}
+
+// v6u16 returns the i'th 16-bit word of ip. If ip is an IPv4 address,
+// this accesses the IPv4-mapped IPv6 address form of the IP.
+func (ip Addr) v6u16(i uint8) uint16 {
+ return uint16(*(ip.addr.halves()[(i/4)%2]) >> ((3 - i%4) * 16))
+}
+
+// isZero reports whether ip is the zero value of the IP type.
+// The zero value is not a valid IP address of any type.
+//
+// Note that "0.0.0.0" and "::" are not the zero value. Use IsUnspecified to
+// check for these values instead.
+func (ip Addr) isZero() bool {
+ // Faster than comparing ip == Addr{}, but effectively equivalent,
+ // as there's no way to make an IP with a nil z from this package.
+ return ip.z == z0
+}
+
+// IsValid reports whether the Addr is an initialized address (not the zero Addr).
+//
+// Note that "0.0.0.0" and "::" are both valid values.
+func (ip Addr) IsValid() bool { return ip.z != z0 }
+
+// BitLen returns the number of bits in the IP address:
+// 128 for IPv6, 32 for IPv4, and 0 for the zero Addr.
+//
+// Note that IPv4-mapped IPv6 addresses are considered IPv6 addresses
+// and therefore have bit length 128.
+func (ip Addr) BitLen() int {
+ switch ip.z {
+ case z0:
+ return 0
+ case z4:
+ return 32
+ }
+ return 128
+}
+
+// Zone returns ip's IPv6 scoped addressing zone, if any.
+func (ip Addr) Zone() string {
+ if ip.z == nil {
+ return ""
+ }
+ zone, _ := ip.z.Get().(string)
+ return zone
+}
+
+// Compare returns an integer comparing two IPs.
+// The result will be 0 if ip == ip2, -1 if ip < ip2, and +1 if ip > ip2.
+// The definition of "less than" is the same as the Less method.
+func (ip Addr) Compare(ip2 Addr) int {
+ f1, f2 := ip.BitLen(), ip2.BitLen()
+ if f1 < f2 {
+ return -1
+ }
+ if f1 > f2 {
+ return 1
+ }
+ hi1, hi2 := ip.addr.hi, ip2.addr.hi
+ if hi1 < hi2 {
+ return -1
+ }
+ if hi1 > hi2 {
+ return 1
+ }
+ lo1, lo2 := ip.addr.lo, ip2.addr.lo
+ if lo1 < lo2 {
+ return -1
+ }
+ if lo1 > lo2 {
+ return 1
+ }
+ if ip.Is6() {
+ za, zb := ip.Zone(), ip2.Zone()
+ if za < zb {
+ return -1
+ }
+ if za > zb {
+ return 1
+ }
+ }
+ return 0
+}
+
+// Less reports whether ip sorts before ip2.
+// IP addresses sort first by length, then their address.
+// IPv6 addresses with zones sort just after the same address without a zone.
+func (ip Addr) Less(ip2 Addr) bool { return ip.Compare(ip2) == -1 }
+
+// Is4 reports whether ip is an IPv4 address.
+//
+// It returns false for IPv4-mapped IPv6 addresses. See Addr.Unmap.
+func (ip Addr) Is4() bool {
+ return ip.z == z4
+}
+
+// Is4In6 reports whether ip is an IPv4-mapped IPv6 address.
+func (ip Addr) Is4In6() bool {
+ return ip.Is6() && ip.addr.hi == 0 && ip.addr.lo>>32 == 0xffff
+}
+
+// Is6 reports whether ip is an IPv6 address, including IPv4-mapped
+// IPv6 addresses.
+func (ip Addr) Is6() bool {
+ return ip.z != z0 && ip.z != z4
+}
+
+// Unmap returns ip with any IPv4-mapped IPv6 address prefix removed.
+//
+// That is, if ip is an IPv6 address wrapping an IPv4 address, it
+// returns the wrapped IPv4 address. Otherwise it returns ip unmodified.
+func (ip Addr) Unmap() Addr {
+ if ip.Is4In6() {
+ ip.z = z4
+ }
+ return ip
+}
+
+// WithZone returns an IP that's the same as ip but with the provided
+// zone. If zone is empty, the zone is removed. If ip is an IPv4
+// address, WithZone is a no-op and returns ip unchanged.
+func (ip Addr) WithZone(zone string) Addr {
+ if !ip.Is6() {
+ return ip
+ }
+ if zone == "" {
+ ip.z = z6noz
+ return ip
+ }
+ ip.z = intern.GetByString(zone)
+ return ip
+}
+
+// withoutZone unconditionally strips the zone from ip.
+// It's similar to WithZone, but small enough to be inlinable.
+func (ip Addr) withoutZone() Addr {
+ if !ip.Is6() {
+ return ip
+ }
+ ip.z = z6noz
+ return ip
+}
+
+// hasZone reports whether ip has an IPv6 zone.
+func (ip Addr) hasZone() bool {
+ return ip.z != z0 && ip.z != z4 && ip.z != z6noz
+}
+
+// IsLinkLocalUnicast reports whether ip is a link-local unicast address.
+func (ip Addr) IsLinkLocalUnicast() bool {
+ // Dynamic Configuration of IPv4 Link-Local Addresses
+ // https://datatracker.ietf.org/doc/html/rfc3927#section-2.1
+ if ip.Is4() {
+ return ip.v4(0) == 169 && ip.v4(1) == 254
+ }
+ // IP Version 6 Addressing Architecture (2.4 Address Type Identification)
+ // https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
+ if ip.Is6() {
+ return ip.v6u16(0)&0xffc0 == 0xfe80
+ }
+ return false // zero value
+}
+
+// IsLoopback reports whether ip is a loopback address.
+func (ip Addr) IsLoopback() bool {
+ // Requirements for Internet Hosts -- Communication Layers (3.2.1.3 Addressing)
+ // https://datatracker.ietf.org/doc/html/rfc1122#section-3.2.1.3
+ if ip.Is4() {
+ return ip.v4(0) == 127
+ }
+ // IP Version 6 Addressing Architecture (2.4 Address Type Identification)
+ // https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
+ if ip.Is6() {
+ return ip.addr.hi == 0 && ip.addr.lo == 1
+ }
+ return false // zero value
+}
+
+// IsMulticast reports whether ip is a multicast address.
+func (ip Addr) IsMulticast() bool {
+ // Host Extensions for IP Multicasting (4. HOST GROUP ADDRESSES)
+ // https://datatracker.ietf.org/doc/html/rfc1112#section-4
+ if ip.Is4() {
+ return ip.v4(0)&0xf0 == 0xe0
+ }
+ // IP Version 6 Addressing Architecture (2.4 Address Type Identification)
+ // https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
+ if ip.Is6() {
+ return ip.addr.hi>>(64-8) == 0xff // ip.v6(0) == 0xff
+ }
+ return false // zero value
+}
+
+// IsInterfaceLocalMulticast reports whether ip is an IPv6 interface-local
+// multicast address.
+func (ip Addr) IsInterfaceLocalMulticast() bool {
+ // IPv6 Addressing Architecture (2.7.1. Pre-Defined Multicast Addresses)
+ // https://datatracker.ietf.org/doc/html/rfc4291#section-2.7.1
+ if ip.Is6() {
+ return ip.v6u16(0)&0xff0f == 0xff01
+ }
+ return false // zero value
+}
+
+// IsLinkLocalMulticast reports whether ip is a link-local multicast address.
+func (ip Addr) IsLinkLocalMulticast() bool {
+ // IPv4 Multicast Guidelines (4. Local Network Control Block (224.0.0/24))
+ // https://datatracker.ietf.org/doc/html/rfc5771#section-4
+ if ip.Is4() {
+ return ip.v4(0) == 224 && ip.v4(1) == 0 && ip.v4(2) == 0
+ }
+ // IPv6 Addressing Architecture (2.7.1. Pre-Defined Multicast Addresses)
+ // https://datatracker.ietf.org/doc/html/rfc4291#section-2.7.1
+ if ip.Is6() {
+ return ip.v6u16(0)&0xff0f == 0xff02
+ }
+ return false // zero value
+}
+
+// IsGlobalUnicast reports whether ip is a global unicast address.
+//
+// It returns true for IPv6 addresses which fall outside of the current
+// IANA-allocated 2000::/3 global unicast space, with the exception of the
+// link-local address space. It also returns true even if ip is in the IPv4
+// private address space or IPv6 unique local address space.
+// It returns false for the zero Addr.
+//
+// For reference, see RFC 1122, RFC 4291, and RFC 4632.
+func (ip Addr) IsGlobalUnicast() bool {
+ if ip.z == z0 {
+ // Invalid or zero-value.
+ return false
+ }
+
+ // Match package net's IsGlobalUnicast logic. Notably private IPv4 addresses
+ // and ULA IPv6 addresses are still considered "global unicast".
+ if ip.Is4() && (ip == IPv4Unspecified() || ip == AddrFrom4([4]byte{255, 255, 255, 255})) {
+ return false
+ }
+
+ return ip != IPv6Unspecified() &&
+ !ip.IsLoopback() &&
+ !ip.IsMulticast() &&
+ !ip.IsLinkLocalUnicast()
+}
+
+// IsPrivate reports whether ip is a private address, according to RFC 1918
+// (IPv4 addresses) and RFC 4193 (IPv6 addresses). That is, it reports whether
+// ip is in 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, or fc00::/7. This is the
+// same as net.IP.IsPrivate.
+func (ip Addr) IsPrivate() bool {
+ // Match the stdlib's IsPrivate logic.
+ if ip.Is4() {
+ // RFC 1918 allocates 10.0.0.0/8, 172.16.0.0/12, and 192.168.0.0/16 as
+ // private IPv4 address subnets.
+ return ip.v4(0) == 10 ||
+ (ip.v4(0) == 172 && ip.v4(1)&0xf0 == 16) ||
+ (ip.v4(0) == 192 && ip.v4(1) == 168)
+ }
+
+ if ip.Is6() {
+ // RFC 4193 allocates fc00::/7 as the unique local unicast IPv6 address
+ // subnet.
+ return ip.v6(0)&0xfe == 0xfc
+ }
+
+ return false // zero value
+}
+
+// IsUnspecified reports whether ip is an unspecified address, either the IPv4
+// address "0.0.0.0" or the IPv6 address "::".
+//
+// Note that the zero Addr is not an unspecified address.
+func (ip Addr) IsUnspecified() bool {
+ return ip == IPv4Unspecified() || ip == IPv6Unspecified()
+}
+
+// Prefix keeps only the top b bits of IP, producing a Prefix
+// of the specified length.
+// If ip is a zero Addr, Prefix always returns a zero Prefix and a nil error.
+// Otherwise, if bits is less than zero or greater than ip.BitLen(),
+// Prefix returns an error.
+func (ip Addr) Prefix(b int) (Prefix, error) {
+ if b < 0 {
+ return Prefix{}, errors.New("negative Prefix bits")
+ }
+ effectiveBits := b
+ switch ip.z {
+ case z0:
+ return Prefix{}, nil
+ case z4:
+ if b > 32 {
+ return Prefix{}, errors.New("prefix length " + itoa.Itoa(b) + " too large for IPv4")
+ }
+ effectiveBits += 96
+ default:
+ if b > 128 {
+ return Prefix{}, errors.New("prefix length " + itoa.Itoa(b) + " too large for IPv6")
+ }
+ }
+ ip.addr = ip.addr.and(mask6(effectiveBits))
+ return PrefixFrom(ip, b), nil
+}
+
+const (
+ netIPv4len = 4
+ netIPv6len = 16
+)
+
+// As16 returns the IP address in its 16-byte representation.
+// IPv4 addresses are returned as IPv4-mapped IPv6 addresses.
+// IPv6 addresses with zones are returned without their zone (use the
+// Zone method to get it).
+// The ip zero value returns all zeroes.
+func (ip Addr) As16() (a16 [16]byte) {
+ bePutUint64(a16[:8], ip.addr.hi)
+ bePutUint64(a16[8:], ip.addr.lo)
+ return a16
+}
+
+// As4 returns an IPv4 or IPv4-in-IPv6 address in its 4-byte representation.
+// If ip is the zero Addr or an IPv6 address, As4 panics.
+// Note that 0.0.0.0 is not the zero Addr.
+func (ip Addr) As4() (a4 [4]byte) {
+ if ip.z == z4 || ip.Is4In6() {
+ bePutUint32(a4[:], uint32(ip.addr.lo))
+ return a4
+ }
+ if ip.z == z0 {
+ panic("As4 called on IP zero value")
+ }
+ panic("As4 called on IPv6 address")
+}
+
+// AsSlice returns an IPv4 or IPv6 address in its respective 4-byte or 16-byte representation.
+func (ip Addr) AsSlice() []byte {
+ switch ip.z {
+ case z0:
+ return nil
+ case z4:
+ var ret [4]byte
+ bePutUint32(ret[:], uint32(ip.addr.lo))
+ return ret[:]
+ default:
+ var ret [16]byte
+ bePutUint64(ret[:8], ip.addr.hi)
+ bePutUint64(ret[8:], ip.addr.lo)
+ return ret[:]
+ }
+}
+
+// Next returns the address following ip.
+// If there is none, it returns the zero Addr.
+func (ip Addr) Next() Addr {
+ ip.addr = ip.addr.addOne()
+ if ip.Is4() {
+ if uint32(ip.addr.lo) == 0 {
+ // Overflowed.
+ return Addr{}
+ }
+ } else {
+ if ip.addr.isZero() {
+ // Overflowed
+ return Addr{}
+ }
+ }
+ return ip
+}
+
+// Prev returns the IP before ip.
+// If there is none, it returns the IP zero value.
+func (ip Addr) Prev() Addr {
+ if ip.Is4() {
+ if uint32(ip.addr.lo) == 0 {
+ return Addr{}
+ }
+ } else if ip.addr.isZero() {
+ return Addr{}
+ }
+ ip.addr = ip.addr.subOne()
+ return ip
+}
+
+// String returns the string form of the IP address ip.
+// It returns one of 5 forms:
+//
+// - "invalid IP", if ip is the zero Addr
+// - IPv4 dotted decimal ("192.0.2.1")
+// - IPv6 ("2001:db8::1")
+// - "::ffff:1.2.3.4" (if Is4In6)
+// - IPv6 with zone ("fe80:db8::1%eth0")
+//
+// Note that unlike package net's IP.String method,
+// IPv4-mapped IPv6 addresses format with a "::ffff:"
+// prefix before the dotted quad.
+func (ip Addr) String() string {
+ switch ip.z {
+ case z0:
+ return "invalid IP"
+ case z4:
+ return ip.string4()
+ default:
+ if ip.Is4In6() {
+ if z := ip.Zone(); z != "" {
+ return "::ffff:" + ip.Unmap().string4() + "%" + z
+ } else {
+ return "::ffff:" + ip.Unmap().string4()
+ }
+ }
+ return ip.string6()
+ }
+}
+
+// AppendTo appends a text encoding of ip,
+// as generated by MarshalText,
+// to b and returns the extended buffer.
+func (ip Addr) AppendTo(b []byte) []byte {
+ switch ip.z {
+ case z0:
+ return b
+ case z4:
+ return ip.appendTo4(b)
+ default:
+ if ip.Is4In6() {
+ b = append(b, "::ffff:"...)
+ b = ip.Unmap().appendTo4(b)
+ if z := ip.Zone(); z != "" {
+ b = append(b, '%')
+ b = append(b, z...)
+ }
+ return b
+ }
+ return ip.appendTo6(b)
+ }
+}
+
+// digits is a string of the hex digits from 0 to f. It's used in
+// appendDecimal and appendHex to format IP addresses.
+const digits = "0123456789abcdef"
+
+// appendDecimal appends the decimal string representation of x to b.
+func appendDecimal(b []byte, x uint8) []byte {
+ // Using this function rather than strconv.AppendUint makes IPv4
+ // string building 2x faster.
+
+ if x >= 100 {
+ b = append(b, digits[x/100])
+ }
+ if x >= 10 {
+ b = append(b, digits[x/10%10])
+ }
+ return append(b, digits[x%10])
+}
+
+// appendHex appends the hex string representation of x to b.
+func appendHex(b []byte, x uint16) []byte {
+ // Using this function rather than strconv.AppendUint makes IPv6
+ // string building 2x faster.
+
+ if x >= 0x1000 {
+ b = append(b, digits[x>>12])
+ }
+ if x >= 0x100 {
+ b = append(b, digits[x>>8&0xf])
+ }
+ if x >= 0x10 {
+ b = append(b, digits[x>>4&0xf])
+ }
+ return append(b, digits[x&0xf])
+}
+
+// appendHexPad appends the fully padded hex string representation of x to b.
+func appendHexPad(b []byte, x uint16) []byte {
+ return append(b, digits[x>>12], digits[x>>8&0xf], digits[x>>4&0xf], digits[x&0xf])
+}
+
+func (ip Addr) string4() string {
+ const max = len("255.255.255.255")
+ ret := make([]byte, 0, max)
+ ret = ip.appendTo4(ret)
+ return string(ret)
+}
+
+func (ip Addr) appendTo4(ret []byte) []byte {
+ ret = appendDecimal(ret, ip.v4(0))
+ ret = append(ret, '.')
+ ret = appendDecimal(ret, ip.v4(1))
+ ret = append(ret, '.')
+ ret = appendDecimal(ret, ip.v4(2))
+ ret = append(ret, '.')
+ ret = appendDecimal(ret, ip.v4(3))
+ return ret
+}
+
+// string6 formats ip in IPv6 textual representation. It follows the
+// guidelines in section 4 of RFC 5952
+// (https://tools.ietf.org/html/rfc5952#section-4): no unnecessary
+// zeros, use :: to elide the longest run of zeros, and don't use ::
+// to compact a single zero field.
+func (ip Addr) string6() string {
+ // Use a zone with a "plausibly long" name, so that most zone-ful
+ // IP addresses won't require additional allocation.
+ //
+ // The compiler does a cool optimization here, where ret ends up
+ // stack-allocated and so the only allocation this function does
+ // is to construct the returned string. As such, it's okay to be a
+ // bit greedy here, size-wise.
+ const max = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0")
+ ret := make([]byte, 0, max)
+ ret = ip.appendTo6(ret)
+ return string(ret)
+}
+
+func (ip Addr) appendTo6(ret []byte) []byte {
+ zeroStart, zeroEnd := uint8(255), uint8(255)
+ for i := uint8(0); i < 8; i++ {
+ j := i
+ for j < 8 && ip.v6u16(j) == 0 {
+ j++
+ }
+ if l := j - i; l >= 2 && l > zeroEnd-zeroStart {
+ zeroStart, zeroEnd = i, j
+ }
+ }
+
+ for i := uint8(0); i < 8; i++ {
+ if i == zeroStart {
+ ret = append(ret, ':', ':')
+ i = zeroEnd
+ if i >= 8 {
+ break
+ }
+ } else if i > 0 {
+ ret = append(ret, ':')
+ }
+
+ ret = appendHex(ret, ip.v6u16(i))
+ }
+
+ if ip.z != z6noz {
+ ret = append(ret, '%')
+ ret = append(ret, ip.Zone()...)
+ }
+ return ret
+}
+
+// StringExpanded is like String but IPv6 addresses are expanded with leading
+// zeroes and no "::" compression. For example, "2001:db8::1" becomes
+// "2001:0db8:0000:0000:0000:0000:0000:0001".
+func (ip Addr) StringExpanded() string {
+ switch ip.z {
+ case z0, z4:
+ return ip.String()
+ }
+
+ const size = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
+ ret := make([]byte, 0, size)
+ for i := uint8(0); i < 8; i++ {
+ if i > 0 {
+ ret = append(ret, ':')
+ }
+
+ ret = appendHexPad(ret, ip.v6u16(i))
+ }
+
+ if ip.z != z6noz {
+ // The addition of a zone will cause a second allocation, but when there
+ // is no zone the ret slice will be stack allocated.
+ ret = append(ret, '%')
+ ret = append(ret, ip.Zone()...)
+ }
+ return string(ret)
+}
+
+// MarshalText implements the encoding.TextMarshaler interface,
+// The encoding is the same as returned by String, with one exception:
+// If ip is the zero Addr, the encoding is the empty string.
+func (ip Addr) MarshalText() ([]byte, error) {
+ switch ip.z {
+ case z0:
+ return []byte(""), nil
+ case z4:
+ max := len("255.255.255.255")
+ b := make([]byte, 0, max)
+ return ip.appendTo4(b), nil
+ default:
+ max := len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0")
+ b := make([]byte, 0, max)
+ if ip.Is4In6() {
+ b = append(b, "::ffff:"...)
+ b = ip.Unmap().appendTo4(b)
+ if z := ip.Zone(); z != "" {
+ b = append(b, '%')
+ b = append(b, z...)
+ }
+ return b, nil
+ }
+ return ip.appendTo6(b), nil
+ }
+
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface.
+// The IP address is expected in a form accepted by ParseAddr.
+//
+// If text is empty, UnmarshalText sets *ip to the zero Addr and
+// returns no error.
+func (ip *Addr) UnmarshalText(text []byte) error {
+ if len(text) == 0 {
+ *ip = Addr{}
+ return nil
+ }
+ var err error
+ *ip, err = ParseAddr(string(text))
+ return err
+}
+
+func (ip Addr) marshalBinaryWithTrailingBytes(trailingBytes int) []byte {
+ var b []byte
+ switch ip.z {
+ case z0:
+ b = make([]byte, trailingBytes)
+ case z4:
+ b = make([]byte, 4+trailingBytes)
+ bePutUint32(b, uint32(ip.addr.lo))
+ default:
+ z := ip.Zone()
+ b = make([]byte, 16+len(z)+trailingBytes)
+ bePutUint64(b[:8], ip.addr.hi)
+ bePutUint64(b[8:], ip.addr.lo)
+ copy(b[16:], z)
+ }
+ return b
+}
+
+// MarshalBinary implements the encoding.BinaryMarshaler interface.
+// It returns a zero-length slice for the zero Addr,
+// the 4-byte form for an IPv4 address,
+// and the 16-byte form with zone appended for an IPv6 address.
+func (ip Addr) MarshalBinary() ([]byte, error) {
+ return ip.marshalBinaryWithTrailingBytes(0), nil
+}
+
+// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
+// It expects data in the form generated by MarshalBinary.
+func (ip *Addr) UnmarshalBinary(b []byte) error {
+ n := len(b)
+ switch {
+ case n == 0:
+ *ip = Addr{}
+ return nil
+ case n == 4:
+ *ip = AddrFrom4([4]byte(b))
+ return nil
+ case n == 16:
+ *ip = AddrFrom16([16]byte(b))
+ return nil
+ case n > 16:
+ *ip = AddrFrom16([16]byte(b[:16])).WithZone(string(b[16:]))
+ return nil
+ }
+ return errors.New("unexpected slice size")
+}
+
+// AddrPort is an IP and a port number.
+type AddrPort struct {
+ ip Addr
+ port uint16
+}
+
+// AddrPortFrom returns an AddrPort with the provided IP and port.
+// It does not allocate.
+func AddrPortFrom(ip Addr, port uint16) AddrPort { return AddrPort{ip: ip, port: port} }
+
+// Addr returns p's IP address.
+func (p AddrPort) Addr() Addr { return p.ip }
+
+// Port returns p's port.
+func (p AddrPort) Port() uint16 { return p.port }
+
+// splitAddrPort splits s into an IP address string and a port
+// string. It splits strings shaped like "foo:bar" or "[foo]:bar",
+// without further validating the substrings. v6 indicates whether the
+// ip string should parse as an IPv6 address or an IPv4 address, in
+// order for s to be a valid ip:port string.
+func splitAddrPort(s string) (ip, port string, v6 bool, err error) {
+ i := stringsLastIndexByte(s, ':')
+ if i == -1 {
+ return "", "", false, errors.New("not an ip:port")
+ }
+
+ ip, port = s[:i], s[i+1:]
+ if len(ip) == 0 {
+ return "", "", false, errors.New("no IP")
+ }
+ if len(port) == 0 {
+ return "", "", false, errors.New("no port")
+ }
+ if ip[0] == '[' {
+ if len(ip) < 2 || ip[len(ip)-1] != ']' {
+ return "", "", false, errors.New("missing ]")
+ }
+ ip = ip[1 : len(ip)-1]
+ v6 = true
+ }
+
+ return ip, port, v6, nil
+}
+
+// ParseAddrPort parses s as an AddrPort.
+//
+// It doesn't do any name resolution: both the address and the port
+// must be numeric.
+func ParseAddrPort(s string) (AddrPort, error) {
+ var ipp AddrPort
+ ip, port, v6, err := splitAddrPort(s)
+ if err != nil {
+ return ipp, err
+ }
+ port16, err := strconv.ParseUint(port, 10, 16)
+ if err != nil {
+ return ipp, errors.New("invalid port " + strconv.Quote(port) + " parsing " + strconv.Quote(s))
+ }
+ ipp.port = uint16(port16)
+ ipp.ip, err = ParseAddr(ip)
+ if err != nil {
+ return AddrPort{}, err
+ }
+ if v6 && ipp.ip.Is4() {
+ return AddrPort{}, errors.New("invalid ip:port " + strconv.Quote(s) + ", square brackets can only be used with IPv6 addresses")
+ } else if !v6 && ipp.ip.Is6() {
+ return AddrPort{}, errors.New("invalid ip:port " + strconv.Quote(s) + ", IPv6 addresses must be surrounded by square brackets")
+ }
+ return ipp, nil
+}
+
+// MustParseAddrPort calls ParseAddrPort(s) and panics on error.
+// It is intended for use in tests with hard-coded strings.
+func MustParseAddrPort(s string) AddrPort {
+ ip, err := ParseAddrPort(s)
+ if err != nil {
+ panic(err)
+ }
+ return ip
+}
+
+// IsValid reports whether p.Addr() is valid.
+// All ports are valid, including zero.
+func (p AddrPort) IsValid() bool { return p.ip.IsValid() }
+
+func (p AddrPort) String() string {
+ switch p.ip.z {
+ case z0:
+ return "invalid AddrPort"
+ case z4:
+ a := p.ip.As4()
+ buf := make([]byte, 0, 21)
+ for i := range a {
+ buf = strconv.AppendUint(buf, uint64(a[i]), 10)
+ buf = append(buf, "...:"[i])
+ }
+ buf = strconv.AppendUint(buf, uint64(p.port), 10)
+ return string(buf)
+ default:
+ // TODO: this could be more efficient allocation-wise:
+ return joinHostPort(p.ip.String(), itoa.Itoa(int(p.port)))
+ }
+}
+
+func joinHostPort(host, port string) string {
+ // We assume that host is a literal IPv6 address if host has
+ // colons.
+ if bytealg.IndexByteString(host, ':') >= 0 {
+ return "[" + host + "]:" + port
+ }
+ return host + ":" + port
+}
+
+// AppendTo appends a text encoding of p,
+// as generated by MarshalText,
+// to b and returns the extended buffer.
+func (p AddrPort) AppendTo(b []byte) []byte {
+ switch p.ip.z {
+ case z0:
+ return b
+ case z4:
+ b = p.ip.appendTo4(b)
+ default:
+ if p.ip.Is4In6() {
+ b = append(b, "[::ffff:"...)
+ b = p.ip.Unmap().appendTo4(b)
+ if z := p.ip.Zone(); z != "" {
+ b = append(b, '%')
+ b = append(b, z...)
+ }
+ } else {
+ b = append(b, '[')
+ b = p.ip.appendTo6(b)
+ }
+ b = append(b, ']')
+ }
+ b = append(b, ':')
+ b = strconv.AppendUint(b, uint64(p.port), 10)
+ return b
+}
+
+// MarshalText implements the encoding.TextMarshaler interface. The
+// encoding is the same as returned by String, with one exception: if
+// p.Addr() is the zero Addr, the encoding is the empty string.
+func (p AddrPort) MarshalText() ([]byte, error) {
+ var max int
+ switch p.ip.z {
+ case z0:
+ case z4:
+ max = len("255.255.255.255:65535")
+ default:
+ max = len("[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0]:65535")
+ }
+ b := make([]byte, 0, max)
+ b = p.AppendTo(b)
+ return b, nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler
+// interface. The AddrPort is expected in a form
+// generated by MarshalText or accepted by ParseAddrPort.
+func (p *AddrPort) UnmarshalText(text []byte) error {
+ if len(text) == 0 {
+ *p = AddrPort{}
+ return nil
+ }
+ var err error
+ *p, err = ParseAddrPort(string(text))
+ return err
+}
+
+// MarshalBinary implements the encoding.BinaryMarshaler interface.
+// It returns Addr.MarshalBinary with an additional two bytes appended
+// containing the port in little-endian.
+func (p AddrPort) MarshalBinary() ([]byte, error) {
+ b := p.Addr().marshalBinaryWithTrailingBytes(2)
+ lePutUint16(b[len(b)-2:], p.Port())
+ return b, nil
+}
+
+// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
+// It expects data in the form generated by MarshalBinary.
+func (p *AddrPort) UnmarshalBinary(b []byte) error {
+ if len(b) < 2 {
+ return errors.New("unexpected slice size")
+ }
+ var addr Addr
+ err := addr.UnmarshalBinary(b[:len(b)-2])
+ if err != nil {
+ return err
+ }
+ *p = AddrPortFrom(addr, leUint16(b[len(b)-2:]))
+ return nil
+}
+
+// Prefix is an IP address prefix (CIDR) representing an IP network.
+//
+// The first Bits() of Addr() are specified. The remaining bits match any address.
+// The range of Bits() is [0,32] for IPv4 or [0,128] for IPv6.
+type Prefix struct {
+ ip Addr
+
+ // bitsPlusOne stores the prefix bit length plus one.
+ // A Prefix is valid if and only if bitsPlusOne is non-zero.
+ bitsPlusOne uint8
+}
+
+// PrefixFrom returns a Prefix with the provided IP address and bit
+// prefix length.
+//
+// It does not allocate. Unlike Addr.Prefix, PrefixFrom does not mask
+// off the host bits of ip.
+//
+// If bits is less than zero or greater than ip.BitLen, Prefix.Bits
+// will return an invalid value -1.
+func PrefixFrom(ip Addr, bits int) Prefix {
+ var bitsPlusOne uint8
+ if !ip.isZero() && bits >= 0 && bits <= ip.BitLen() {
+ bitsPlusOne = uint8(bits) + 1
+ }
+ return Prefix{
+ ip: ip.withoutZone(),
+ bitsPlusOne: bitsPlusOne,
+ }
+}
+
+// Addr returns p's IP address.
+func (p Prefix) Addr() Addr { return p.ip }
+
+// Bits returns p's prefix length.
+//
+// It reports -1 if invalid.
+func (p Prefix) Bits() int { return int(p.bitsPlusOne) - 1 }
+
+// IsValid reports whether p.Bits() has a valid range for p.Addr().
+// If p.Addr() is the zero Addr, IsValid returns false.
+// Note that if p is the zero Prefix, then p.IsValid() == false.
+func (p Prefix) IsValid() bool { return p.bitsPlusOne > 0 }
+
+func (p Prefix) isZero() bool { return p == Prefix{} }
+
+// IsSingleIP reports whether p contains exactly one IP.
+func (p Prefix) IsSingleIP() bool { return p.IsValid() && p.Bits() == p.ip.BitLen() }
+
+// ParsePrefix parses s as an IP address prefix.
+// The string can be in the form "192.168.1.0/24" or "2001:db8::/32",
+// the CIDR notation defined in RFC 4632 and RFC 4291.
+// IPv6 zones are not permitted in prefixes, and an error will be returned if a
+// zone is present.
+//
+// Note that masked address bits are not zeroed. Use Masked for that.
+func ParsePrefix(s string) (Prefix, error) {
+ i := stringsLastIndexByte(s, '/')
+ if i < 0 {
+ return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): no '/'")
+ }
+ ip, err := ParseAddr(s[:i])
+ if err != nil {
+ return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): " + err.Error())
+ }
+ // IPv6 zones are not allowed: https://go.dev/issue/51899
+ if ip.Is6() && ip.z != z6noz {
+ return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): IPv6 zones cannot be present in a prefix")
+ }
+
+ bitsStr := s[i+1:]
+ bits, err := strconv.Atoi(bitsStr)
+ if err != nil {
+ return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): bad bits after slash: " + strconv.Quote(bitsStr))
+ }
+ maxBits := 32
+ if ip.Is6() {
+ maxBits = 128
+ }
+ if bits < 0 || bits > maxBits {
+ return Prefix{}, errors.New("netip.ParsePrefix(" + strconv.Quote(s) + "): prefix length out of range")
+ }
+ return PrefixFrom(ip, bits), nil
+}
+
+// MustParsePrefix calls ParsePrefix(s) and panics on error.
+// It is intended for use in tests with hard-coded strings.
+func MustParsePrefix(s string) Prefix {
+ ip, err := ParsePrefix(s)
+ if err != nil {
+ panic(err)
+ }
+ return ip
+}
+
+// Masked returns p in its canonical form, with all but the high
+// p.Bits() bits of p.Addr() masked off.
+//
+// If p is zero or otherwise invalid, Masked returns the zero Prefix.
+func (p Prefix) Masked() Prefix {
+ m, _ := p.ip.Prefix(p.Bits())
+ return m
+}
+
+// Contains reports whether the network p includes ip.
+//
+// An IPv4 address will not match an IPv6 prefix.
+// An IPv4-mapped IPv6 address will not match an IPv4 prefix.
+// A zero-value IP will not match any prefix.
+// If ip has an IPv6 zone, Contains returns false,
+// because Prefixes strip zones.
+func (p Prefix) Contains(ip Addr) bool {
+ if !p.IsValid() || ip.hasZone() {
+ return false
+ }
+ if f1, f2 := p.ip.BitLen(), ip.BitLen(); f1 == 0 || f2 == 0 || f1 != f2 {
+ return false
+ }
+ if ip.Is4() {
+ // xor the IP addresses together; mismatched bits are now ones.
+ // Shift away the number of bits we don't care about.
+ // Shifts in Go are more efficient if the compiler can prove
+ // that the shift amount is smaller than the width of the shifted type (64 here).
+ // We know that p.bits is in the range 0..32 because p is Valid;
+ // the compiler doesn't know that, so mask with 63 to help it.
+ // Now truncate to 32 bits, because this is IPv4.
+ // If all the bits we care about are equal, the result will be zero.
+ return uint32((ip.addr.lo^p.ip.addr.lo)>>((32-p.Bits())&63)) == 0
+ } else {
+ // xor the IP addresses together.
+ // Mask away the bits we don't care about.
+ // If all the bits we care about are equal, the result will be zero.
+ return ip.addr.xor(p.ip.addr).and(mask6(p.Bits())).isZero()
+ }
+}
+
+// Overlaps reports whether p and o contain any IP addresses in common.
+//
+// If p and o are of different address families or either have a zero
+// IP, it reports false. Like the Contains method, a prefix with an
+// IPv4-mapped IPv6 address is still treated as an IPv6 mask.
+func (p Prefix) Overlaps(o Prefix) bool {
+ if !p.IsValid() || !o.IsValid() {
+ return false
+ }
+ if p == o {
+ return true
+ }
+ if p.ip.Is4() != o.ip.Is4() {
+ return false
+ }
+ var minBits int
+ if pb, ob := p.Bits(), o.Bits(); pb < ob {
+ minBits = pb
+ } else {
+ minBits = ob
+ }
+ if minBits == 0 {
+ return true
+ }
+ // One of these Prefix calls might look redundant, but we don't require
+ // that p and o values are normalized (via Prefix.Masked) first,
+ // so the Prefix call on the one that's already minBits serves to zero
+ // out any remaining bits in IP.
+ var err error
+ if p, err = p.ip.Prefix(minBits); err != nil {
+ return false
+ }
+ if o, err = o.ip.Prefix(minBits); err != nil {
+ return false
+ }
+ return p.ip == o.ip
+}
+
+// AppendTo appends a text encoding of p,
+// as generated by MarshalText,
+// to b and returns the extended buffer.
+func (p Prefix) AppendTo(b []byte) []byte {
+ if p.isZero() {
+ return b
+ }
+ if !p.IsValid() {
+ return append(b, "invalid Prefix"...)
+ }
+
+ // p.ip is non-nil, because p is valid.
+ if p.ip.z == z4 {
+ b = p.ip.appendTo4(b)
+ } else {
+ if p.ip.Is4In6() {
+ b = append(b, "::ffff:"...)
+ b = p.ip.Unmap().appendTo4(b)
+ } else {
+ b = p.ip.appendTo6(b)
+ }
+ }
+
+ b = append(b, '/')
+ b = appendDecimal(b, uint8(p.Bits()))
+ return b
+}
+
+// MarshalText implements the encoding.TextMarshaler interface,
+// The encoding is the same as returned by String, with one exception:
+// If p is the zero value, the encoding is the empty string.
+func (p Prefix) MarshalText() ([]byte, error) {
+ var max int
+ switch p.ip.z {
+ case z0:
+ case z4:
+ max = len("255.255.255.255/32")
+ default:
+ max = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%enp5s0/128")
+ }
+ b := make([]byte, 0, max)
+ b = p.AppendTo(b)
+ return b, nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface.
+// The IP address is expected in a form accepted by ParsePrefix
+// or generated by MarshalText.
+func (p *Prefix) UnmarshalText(text []byte) error {
+ if len(text) == 0 {
+ *p = Prefix{}
+ return nil
+ }
+ var err error
+ *p, err = ParsePrefix(string(text))
+ return err
+}
+
+// MarshalBinary implements the encoding.BinaryMarshaler interface.
+// It returns Addr.MarshalBinary with an additional byte appended
+// containing the prefix bits.
+func (p Prefix) MarshalBinary() ([]byte, error) {
+ b := p.Addr().withoutZone().marshalBinaryWithTrailingBytes(1)
+ b[len(b)-1] = uint8(p.Bits())
+ return b, nil
+}
+
+// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
+// It expects data in the form generated by MarshalBinary.
+func (p *Prefix) UnmarshalBinary(b []byte) error {
+ if len(b) < 1 {
+ return errors.New("unexpected slice size")
+ }
+ var addr Addr
+ err := addr.UnmarshalBinary(b[:len(b)-1])
+ if err != nil {
+ return err
+ }
+ *p = PrefixFrom(addr, int(b[len(b)-1]))
+ return nil
+}
+
+// String returns the CIDR notation of p: "<ip>/<bits>".
+func (p Prefix) String() string {
+ if !p.IsValid() {
+ return "invalid Prefix"
+ }
+ return p.ip.String() + "/" + itoa.Itoa(p.Bits())
+}
diff --git a/contrib/go/_std_1.20/src/net/netip/uint128.go b/contrib/go/_std_1.21/src/net/netip/uint128.go
index b1605afbe7..b1605afbe7 100644
--- a/contrib/go/_std_1.20/src/net/netip/uint128.go
+++ b/contrib/go/_std_1.21/src/net/netip/uint128.go
diff --git a/contrib/go/_std_1.21/src/net/netip/ya.make b/contrib/go/_std_1.21/src/net/netip/ya.make
new file mode 100644
index 0000000000..2a78b8e5dd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/netip/ya.make
@@ -0,0 +1,25 @@
+GO_LIBRARY()
+
+SRCS(
+ leaf_alts.go
+ netip.go
+ uint128.go
+)
+
+GO_TEST_SRCS(
+ export_test.go
+ inlining_test.go
+ netip_pkg_test.go
+ uint128_test.go
+)
+
+GO_XTEST_SRCS(
+ fuzz_test.go
+ netip_test.go
+ slow_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/net/nss.go b/contrib/go/_std_1.21/src/net/nss.go
index 092b515cc7..092b515cc7 100644
--- a/contrib/go/_std_1.20/src/net/nss.go
+++ b/contrib/go/_std_1.21/src/net/nss.go
diff --git a/contrib/go/_std_1.20/src/net/parse.go b/contrib/go/_std_1.21/src/net/parse.go
index fbc50144c2..fbc50144c2 100644
--- a/contrib/go/_std_1.20/src/net/parse.go
+++ b/contrib/go/_std_1.21/src/net/parse.go
diff --git a/contrib/go/_std_1.20/src/net/pipe.go b/contrib/go/_std_1.21/src/net/pipe.go
index f1741938b0..f1741938b0 100644
--- a/contrib/go/_std_1.20/src/net/pipe.go
+++ b/contrib/go/_std_1.21/src/net/pipe.go
diff --git a/contrib/go/_std_1.20/src/net/port.go b/contrib/go/_std_1.21/src/net/port.go
index 32e7628619..32e7628619 100644
--- a/contrib/go/_std_1.20/src/net/port.go
+++ b/contrib/go/_std_1.21/src/net/port.go
diff --git a/contrib/go/_std_1.21/src/net/port_unix.go b/contrib/go/_std_1.21/src/net/port_unix.go
new file mode 100644
index 0000000000..0b2ea3ec5d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/port_unix.go
@@ -0,0 +1,57 @@
+// Copyright 2009 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+// Read system port mappings from /etc/services
+
+package net
+
+import (
+ "internal/bytealg"
+ "sync"
+)
+
+var onceReadServices sync.Once
+
+func readServices() {
+ file, err := open("/etc/services")
+ if err != nil {
+ return
+ }
+ defer file.close()
+
+ for line, ok := file.readLine(); ok; line, ok = file.readLine() {
+ // "http 80/tcp www www-http # World Wide Web HTTP"
+ if i := bytealg.IndexByteString(line, '#'); i >= 0 {
+ line = line[:i]
+ }
+ f := getFields(line)
+ if len(f) < 2 {
+ continue
+ }
+ portnet := f[1] // "80/tcp"
+ port, j, ok := dtoi(portnet)
+ if !ok || port <= 0 || j >= len(portnet) || portnet[j] != '/' {
+ continue
+ }
+ netw := portnet[j+1:] // "tcp"
+ m, ok1 := services[netw]
+ if !ok1 {
+ m = make(map[string]int)
+ services[netw] = m
+ }
+ for i := 0; i < len(f); i++ {
+ if i != 1 { // f[1] was port/net
+ m[f[i]] = port
+ }
+ }
+ }
+}
+
+// goLookupPort is the native Go implementation of LookupPort.
+func goLookupPort(network, service string) (port int, err error) {
+ onceReadServices.Do(readServices)
+ return lookupPortMap(network, service)
+}
diff --git a/contrib/go/_std_1.21/src/net/rawconn.go b/contrib/go/_std_1.21/src/net/rawconn.go
new file mode 100644
index 0000000000..974320c25f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/rawconn.go
@@ -0,0 +1,96 @@
+// Copyright 2017 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 net
+
+import (
+ "internal/poll"
+ "runtime"
+ "syscall"
+)
+
+// BUG(tmm1): On Windows, the Write method of syscall.RawConn
+// does not integrate with the runtime's network poller. It cannot
+// wait for the connection to become writeable, and does not respect
+// deadlines. If the user-provided callback returns false, the Write
+// method will fail immediately.
+
+// BUG(mikio): On JS and Plan 9, the Control, Read and Write
+// methods of syscall.RawConn are not implemented.
+
+type rawConn struct {
+ fd *netFD
+}
+
+func (c *rawConn) ok() bool { return c != nil && c.fd != nil }
+
+func (c *rawConn) Control(f func(uintptr)) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ err := c.fd.pfd.RawControl(f)
+ runtime.KeepAlive(c.fd)
+ if err != nil {
+ err = &OpError{Op: "raw-control", Net: c.fd.net, Source: nil, Addr: c.fd.laddr, Err: err}
+ }
+ return err
+}
+
+func (c *rawConn) Read(f func(uintptr) bool) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ err := c.fd.pfd.RawRead(f)
+ runtime.KeepAlive(c.fd)
+ if err != nil {
+ err = &OpError{Op: "raw-read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return err
+}
+
+func (c *rawConn) Write(f func(uintptr) bool) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ err := c.fd.pfd.RawWrite(f)
+ runtime.KeepAlive(c.fd)
+ if err != nil {
+ err = &OpError{Op: "raw-write", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return err
+}
+
+// PollFD returns the poll.FD of the underlying connection.
+//
+// Other packages in std that also import internal/poll (such as os)
+// can use a type assertion to access this extension method so that
+// they can pass the *poll.FD to functions like poll.Splice.
+//
+// PollFD is not intended for use outside the standard library.
+func (c *rawConn) PollFD() *poll.FD {
+ if !c.ok() {
+ return nil
+ }
+ return &c.fd.pfd
+}
+
+func newRawConn(fd *netFD) (*rawConn, error) {
+ return &rawConn{fd: fd}, nil
+}
+
+type rawListener struct {
+ rawConn
+}
+
+func (l *rawListener) Read(func(uintptr) bool) error {
+ return syscall.EINVAL
+}
+
+func (l *rawListener) Write(func(uintptr) bool) error {
+ return syscall.EINVAL
+}
+
+func newRawListener(fd *netFD) (*rawListener, error) {
+ return &rawListener{rawConn{fd: fd}}, nil
+}
diff --git a/contrib/go/_std_1.20/src/net/rpc/client.go b/contrib/go/_std_1.21/src/net/rpc/client.go
index 42d13519b1..42d13519b1 100644
--- a/contrib/go/_std_1.20/src/net/rpc/client.go
+++ b/contrib/go/_std_1.21/src/net/rpc/client.go
diff --git a/contrib/go/_std_1.20/src/net/rpc/debug.go b/contrib/go/_std_1.21/src/net/rpc/debug.go
index 9e499fd984..9e499fd984 100644
--- a/contrib/go/_std_1.20/src/net/rpc/debug.go
+++ b/contrib/go/_std_1.21/src/net/rpc/debug.go
diff --git a/contrib/go/_std_1.20/src/net/rpc/jsonrpc/client.go b/contrib/go/_std_1.21/src/net/rpc/jsonrpc/client.go
index c473017d26..c473017d26 100644
--- a/contrib/go/_std_1.20/src/net/rpc/jsonrpc/client.go
+++ b/contrib/go/_std_1.21/src/net/rpc/jsonrpc/client.go
diff --git a/contrib/go/_std_1.20/src/net/rpc/jsonrpc/server.go b/contrib/go/_std_1.21/src/net/rpc/jsonrpc/server.go
index 3ee4ddfef2..3ee4ddfef2 100644
--- a/contrib/go/_std_1.20/src/net/rpc/jsonrpc/server.go
+++ b/contrib/go/_std_1.21/src/net/rpc/jsonrpc/server.go
diff --git a/contrib/go/_std_1.21/src/net/rpc/jsonrpc/ya.make b/contrib/go/_std_1.21/src/net/rpc/jsonrpc/ya.make
new file mode 100644
index 0000000000..5d5e27ad80
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/rpc/jsonrpc/ya.make
@@ -0,0 +1,13 @@
+GO_LIBRARY()
+
+SRCS(
+ client.go
+ server.go
+)
+
+GO_TEST_SRCS(all_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/net/rpc/server.go b/contrib/go/_std_1.21/src/net/rpc/server.go
new file mode 100644
index 0000000000..5cea2cc507
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/rpc/server.go
@@ -0,0 +1,725 @@
+// Copyright 2009 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 rpc provides access to the exported methods of an object across a
+network or other I/O connection. A server registers an object, making it visible
+as a service with the name of the type of the object. After registration, exported
+methods of the object will be accessible remotely. A server may register multiple
+objects (services) of different types but it is an error to register multiple
+objects of the same type.
+
+Only methods that satisfy these criteria will be made available for remote access;
+other methods will be ignored:
+
+ - the method's type is exported.
+ - the method is exported.
+ - the method has two arguments, both exported (or builtin) types.
+ - the method's second argument is a pointer.
+ - the method has return type error.
+
+In effect, the method must look schematically like
+
+ func (t *T) MethodName(argType T1, replyType *T2) error
+
+where T1 and T2 can be marshaled by encoding/gob.
+These requirements apply even if a different codec is used.
+(In the future, these requirements may soften for custom codecs.)
+
+The method's first argument represents the arguments provided by the caller; the
+second argument represents the result parameters to be returned to the caller.
+The method's return value, if non-nil, is passed back as a string that the client
+sees as if created by errors.New. If an error is returned, the reply parameter
+will not be sent back to the client.
+
+The server may handle requests on a single connection by calling ServeConn. More
+typically it will create a network listener and call Accept or, for an HTTP
+listener, HandleHTTP and http.Serve.
+
+A client wishing to use the service establishes a connection and then invokes
+NewClient on the connection. The convenience function Dial (DialHTTP) performs
+both steps for a raw network connection (an HTTP connection). The resulting
+Client object has two methods, Call and Go, that specify the service and method to
+call, a pointer containing the arguments, and a pointer to receive the result
+parameters.
+
+The Call method waits for the remote call to complete while the Go method
+launches the call asynchronously and signals completion using the Call
+structure's Done channel.
+
+Unless an explicit codec is set up, package encoding/gob is used to
+transport the data.
+
+Here is a simple example. A server wishes to export an object of type Arith:
+
+ package server
+
+ import "errors"
+
+ type Args struct {
+ A, B int
+ }
+
+ type Quotient struct {
+ Quo, Rem int
+ }
+
+ type Arith int
+
+ func (t *Arith) Multiply(args *Args, reply *int) error {
+ *reply = args.A * args.B
+ return nil
+ }
+
+ func (t *Arith) Divide(args *Args, quo *Quotient) error {
+ if args.B == 0 {
+ return errors.New("divide by zero")
+ }
+ quo.Quo = args.A / args.B
+ quo.Rem = args.A % args.B
+ return nil
+ }
+
+The server calls (for HTTP service):
+
+ arith := new(Arith)
+ rpc.Register(arith)
+ rpc.HandleHTTP()
+ l, err := net.Listen("tcp", ":1234")
+ if err != nil {
+ log.Fatal("listen error:", err)
+ }
+ go http.Serve(l, nil)
+
+At this point, clients can see a service "Arith" with methods "Arith.Multiply" and
+"Arith.Divide". To invoke one, a client first dials the server:
+
+ client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
+ if err != nil {
+ log.Fatal("dialing:", err)
+ }
+
+Then it can make a remote call:
+
+ // Synchronous call
+ args := &server.Args{7,8}
+ var reply int
+ err = client.Call("Arith.Multiply", args, &reply)
+ if err != nil {
+ log.Fatal("arith error:", err)
+ }
+ fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)
+
+or
+
+ // Asynchronous call
+ quotient := new(Quotient)
+ divCall := client.Go("Arith.Divide", args, quotient, nil)
+ replyCall := <-divCall.Done // will be equal to divCall
+ // check errors, print, etc.
+
+A server implementation will often provide a simple, type-safe wrapper for the
+client.
+
+The net/rpc package is frozen and is not accepting new features.
+*/
+package rpc
+
+import (
+ "bufio"
+ "encoding/gob"
+ "errors"
+ "go/token"
+ "io"
+ "log"
+ "net"
+ "net/http"
+ "reflect"
+ "strings"
+ "sync"
+)
+
+const (
+ // Defaults used by HandleHTTP
+ DefaultRPCPath = "/_goRPC_"
+ DefaultDebugPath = "/debug/rpc"
+)
+
+// Precompute the reflect type for error. Can't use error directly
+// because Typeof takes an empty interface value. This is annoying.
+var typeOfError = reflect.TypeOf((*error)(nil)).Elem()
+
+type methodType struct {
+ sync.Mutex // protects counters
+ method reflect.Method
+ ArgType reflect.Type
+ ReplyType reflect.Type
+ numCalls uint
+}
+
+type service struct {
+ name string // name of service
+ rcvr reflect.Value // receiver of methods for the service
+ typ reflect.Type // type of the receiver
+ method map[string]*methodType // registered methods
+}
+
+// Request is a header written before every RPC call. It is used internally
+// but documented here as an aid to debugging, such as when analyzing
+// network traffic.
+type Request struct {
+ ServiceMethod string // format: "Service.Method"
+ Seq uint64 // sequence number chosen by client
+ next *Request // for free list in Server
+}
+
+// Response is a header written before every RPC return. It is used internally
+// but documented here as an aid to debugging, such as when analyzing
+// network traffic.
+type Response struct {
+ ServiceMethod string // echoes that of the Request
+ Seq uint64 // echoes that of the request
+ Error string // error, if any.
+ next *Response // for free list in Server
+}
+
+// Server represents an RPC Server.
+type Server struct {
+ serviceMap sync.Map // map[string]*service
+ reqLock sync.Mutex // protects freeReq
+ freeReq *Request
+ respLock sync.Mutex // protects freeResp
+ freeResp *Response
+}
+
+// NewServer returns a new Server.
+func NewServer() *Server {
+ return &Server{}
+}
+
+// DefaultServer is the default instance of *Server.
+var DefaultServer = NewServer()
+
+// Is this type exported or a builtin?
+func isExportedOrBuiltinType(t reflect.Type) bool {
+ for t.Kind() == reflect.Pointer {
+ t = t.Elem()
+ }
+ // PkgPath will be non-empty even for an exported type,
+ // so we need to check the type name as well.
+ return token.IsExported(t.Name()) || t.PkgPath() == ""
+}
+
+// Register publishes in the server the set of methods of the
+// receiver value that satisfy the following conditions:
+// - exported method of exported type
+// - two arguments, both of exported type
+// - the second argument is a pointer
+// - one return value, of type error
+//
+// It returns an error if the receiver is not an exported type or has
+// no suitable methods. It also logs the error using package log.
+// The client accesses each method using a string of the form "Type.Method",
+// where Type is the receiver's concrete type.
+func (server *Server) Register(rcvr any) error {
+ return server.register(rcvr, "", false)
+}
+
+// RegisterName is like Register but uses the provided name for the type
+// instead of the receiver's concrete type.
+func (server *Server) RegisterName(name string, rcvr any) error {
+ return server.register(rcvr, name, true)
+}
+
+// logRegisterError specifies whether to log problems during method registration.
+// To debug registration, recompile the package with this set to true.
+const logRegisterError = false
+
+func (server *Server) register(rcvr any, name string, useName bool) error {
+ s := new(service)
+ s.typ = reflect.TypeOf(rcvr)
+ s.rcvr = reflect.ValueOf(rcvr)
+ sname := name
+ if !useName {
+ sname = reflect.Indirect(s.rcvr).Type().Name()
+ }
+ if sname == "" {
+ s := "rpc.Register: no service name for type " + s.typ.String()
+ log.Print(s)
+ return errors.New(s)
+ }
+ if !useName && !token.IsExported(sname) {
+ s := "rpc.Register: type " + sname + " is not exported"
+ log.Print(s)
+ return errors.New(s)
+ }
+ s.name = sname
+
+ // Install the methods
+ s.method = suitableMethods(s.typ, logRegisterError)
+
+ if len(s.method) == 0 {
+ str := ""
+
+ // To help the user, see if a pointer receiver would work.
+ method := suitableMethods(reflect.PointerTo(s.typ), false)
+ if len(method) != 0 {
+ str = "rpc.Register: type " + sname + " has no exported methods of suitable type (hint: pass a pointer to value of that type)"
+ } else {
+ str = "rpc.Register: type " + sname + " has no exported methods of suitable type"
+ }
+ log.Print(str)
+ return errors.New(str)
+ }
+
+ if _, dup := server.serviceMap.LoadOrStore(sname, s); dup {
+ return errors.New("rpc: service already defined: " + sname)
+ }
+ return nil
+}
+
+// suitableMethods returns suitable Rpc methods of typ. It will log
+// errors if logErr is true.
+func suitableMethods(typ reflect.Type, logErr bool) map[string]*methodType {
+ methods := make(map[string]*methodType)
+ for m := 0; m < typ.NumMethod(); m++ {
+ method := typ.Method(m)
+ mtype := method.Type
+ mname := method.Name
+ // Method must be exported.
+ if !method.IsExported() {
+ continue
+ }
+ // Method needs three ins: receiver, *args, *reply.
+ if mtype.NumIn() != 3 {
+ if logErr {
+ log.Printf("rpc.Register: method %q has %d input parameters; needs exactly three\n", mname, mtype.NumIn())
+ }
+ continue
+ }
+ // First arg need not be a pointer.
+ argType := mtype.In(1)
+ if !isExportedOrBuiltinType(argType) {
+ if logErr {
+ log.Printf("rpc.Register: argument type of method %q is not exported: %q\n", mname, argType)
+ }
+ continue
+ }
+ // Second arg must be a pointer.
+ replyType := mtype.In(2)
+ if replyType.Kind() != reflect.Pointer {
+ if logErr {
+ log.Printf("rpc.Register: reply type of method %q is not a pointer: %q\n", mname, replyType)
+ }
+ continue
+ }
+ // Reply type must be exported.
+ if !isExportedOrBuiltinType(replyType) {
+ if logErr {
+ log.Printf("rpc.Register: reply type of method %q is not exported: %q\n", mname, replyType)
+ }
+ continue
+ }
+ // Method needs one out.
+ if mtype.NumOut() != 1 {
+ if logErr {
+ log.Printf("rpc.Register: method %q has %d output parameters; needs exactly one\n", mname, mtype.NumOut())
+ }
+ continue
+ }
+ // The return type of the method must be error.
+ if returnType := mtype.Out(0); returnType != typeOfError {
+ if logErr {
+ log.Printf("rpc.Register: return type of method %q is %q, must be error\n", mname, returnType)
+ }
+ continue
+ }
+ methods[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType}
+ }
+ return methods
+}
+
+// A value sent as a placeholder for the server's response value when the server
+// receives an invalid request. It is never decoded by the client since the Response
+// contains an error when it is used.
+var invalidRequest = struct{}{}
+
+func (server *Server) sendResponse(sending *sync.Mutex, req *Request, reply any, codec ServerCodec, errmsg string) {
+ resp := server.getResponse()
+ // Encode the response header
+ resp.ServiceMethod = req.ServiceMethod
+ if errmsg != "" {
+ resp.Error = errmsg
+ reply = invalidRequest
+ }
+ resp.Seq = req.Seq
+ sending.Lock()
+ err := codec.WriteResponse(resp, reply)
+ if debugLog && err != nil {
+ log.Println("rpc: writing response:", err)
+ }
+ sending.Unlock()
+ server.freeResponse(resp)
+}
+
+func (m *methodType) NumCalls() (n uint) {
+ m.Lock()
+ n = m.numCalls
+ m.Unlock()
+ return n
+}
+
+func (s *service) call(server *Server, sending *sync.Mutex, wg *sync.WaitGroup, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) {
+ if wg != nil {
+ defer wg.Done()
+ }
+ mtype.Lock()
+ mtype.numCalls++
+ mtype.Unlock()
+ function := mtype.method.Func
+ // Invoke the method, providing a new value for the reply.
+ returnValues := function.Call([]reflect.Value{s.rcvr, argv, replyv})
+ // The return value for the method is an error.
+ errInter := returnValues[0].Interface()
+ errmsg := ""
+ if errInter != nil {
+ errmsg = errInter.(error).Error()
+ }
+ server.sendResponse(sending, req, replyv.Interface(), codec, errmsg)
+ server.freeRequest(req)
+}
+
+type gobServerCodec struct {
+ rwc io.ReadWriteCloser
+ dec *gob.Decoder
+ enc *gob.Encoder
+ encBuf *bufio.Writer
+ closed bool
+}
+
+func (c *gobServerCodec) ReadRequestHeader(r *Request) error {
+ return c.dec.Decode(r)
+}
+
+func (c *gobServerCodec) ReadRequestBody(body any) error {
+ return c.dec.Decode(body)
+}
+
+func (c *gobServerCodec) WriteResponse(r *Response, body any) (err error) {
+ if err = c.enc.Encode(r); err != nil {
+ if c.encBuf.Flush() == nil {
+ // Gob couldn't encode the header. Should not happen, so if it does,
+ // shut down the connection to signal that the connection is broken.
+ log.Println("rpc: gob error encoding response:", err)
+ c.Close()
+ }
+ return
+ }
+ if err = c.enc.Encode(body); err != nil {
+ if c.encBuf.Flush() == nil {
+ // Was a gob problem encoding the body but the header has been written.
+ // Shut down the connection to signal that the connection is broken.
+ log.Println("rpc: gob error encoding body:", err)
+ c.Close()
+ }
+ return
+ }
+ return c.encBuf.Flush()
+}
+
+func (c *gobServerCodec) Close() error {
+ if c.closed {
+ // Only call c.rwc.Close once; otherwise the semantics are undefined.
+ return nil
+ }
+ c.closed = true
+ return c.rwc.Close()
+}
+
+// ServeConn runs the server on a single connection.
+// ServeConn blocks, serving the connection until the client hangs up.
+// The caller typically invokes ServeConn in a go statement.
+// ServeConn uses the gob wire format (see package gob) on the
+// connection. To use an alternate codec, use ServeCodec.
+// See NewClient's comment for information about concurrent access.
+func (server *Server) ServeConn(conn io.ReadWriteCloser) {
+ buf := bufio.NewWriter(conn)
+ srv := &gobServerCodec{
+ rwc: conn,
+ dec: gob.NewDecoder(conn),
+ enc: gob.NewEncoder(buf),
+ encBuf: buf,
+ }
+ server.ServeCodec(srv)
+}
+
+// ServeCodec is like ServeConn but uses the specified codec to
+// decode requests and encode responses.
+func (server *Server) ServeCodec(codec ServerCodec) {
+ sending := new(sync.Mutex)
+ wg := new(sync.WaitGroup)
+ for {
+ service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
+ if err != nil {
+ if debugLog && err != io.EOF {
+ log.Println("rpc:", err)
+ }
+ if !keepReading {
+ break
+ }
+ // send a response if we actually managed to read a header.
+ if req != nil {
+ server.sendResponse(sending, req, invalidRequest, codec, err.Error())
+ server.freeRequest(req)
+ }
+ continue
+ }
+ wg.Add(1)
+ go service.call(server, sending, wg, mtype, req, argv, replyv, codec)
+ }
+ // We've seen that there are no more requests.
+ // Wait for responses to be sent before closing codec.
+ wg.Wait()
+ codec.Close()
+}
+
+// ServeRequest is like ServeCodec but synchronously serves a single request.
+// It does not close the codec upon completion.
+func (server *Server) ServeRequest(codec ServerCodec) error {
+ sending := new(sync.Mutex)
+ service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
+ if err != nil {
+ if !keepReading {
+ return err
+ }
+ // send a response if we actually managed to read a header.
+ if req != nil {
+ server.sendResponse(sending, req, invalidRequest, codec, err.Error())
+ server.freeRequest(req)
+ }
+ return err
+ }
+ service.call(server, sending, nil, mtype, req, argv, replyv, codec)
+ return nil
+}
+
+func (server *Server) getRequest() *Request {
+ server.reqLock.Lock()
+ req := server.freeReq
+ if req == nil {
+ req = new(Request)
+ } else {
+ server.freeReq = req.next
+ *req = Request{}
+ }
+ server.reqLock.Unlock()
+ return req
+}
+
+func (server *Server) freeRequest(req *Request) {
+ server.reqLock.Lock()
+ req.next = server.freeReq
+ server.freeReq = req
+ server.reqLock.Unlock()
+}
+
+func (server *Server) getResponse() *Response {
+ server.respLock.Lock()
+ resp := server.freeResp
+ if resp == nil {
+ resp = new(Response)
+ } else {
+ server.freeResp = resp.next
+ *resp = Response{}
+ }
+ server.respLock.Unlock()
+ return resp
+}
+
+func (server *Server) freeResponse(resp *Response) {
+ server.respLock.Lock()
+ resp.next = server.freeResp
+ server.freeResp = resp
+ server.respLock.Unlock()
+}
+
+func (server *Server) readRequest(codec ServerCodec) (service *service, mtype *methodType, req *Request, argv, replyv reflect.Value, keepReading bool, err error) {
+ service, mtype, req, keepReading, err = server.readRequestHeader(codec)
+ if err != nil {
+ if !keepReading {
+ return
+ }
+ // discard body
+ codec.ReadRequestBody(nil)
+ return
+ }
+
+ // Decode the argument value.
+ argIsValue := false // if true, need to indirect before calling.
+ if mtype.ArgType.Kind() == reflect.Pointer {
+ argv = reflect.New(mtype.ArgType.Elem())
+ } else {
+ argv = reflect.New(mtype.ArgType)
+ argIsValue = true
+ }
+ // argv guaranteed to be a pointer now.
+ if err = codec.ReadRequestBody(argv.Interface()); err != nil {
+ return
+ }
+ if argIsValue {
+ argv = argv.Elem()
+ }
+
+ replyv = reflect.New(mtype.ReplyType.Elem())
+
+ switch mtype.ReplyType.Elem().Kind() {
+ case reflect.Map:
+ replyv.Elem().Set(reflect.MakeMap(mtype.ReplyType.Elem()))
+ case reflect.Slice:
+ replyv.Elem().Set(reflect.MakeSlice(mtype.ReplyType.Elem(), 0, 0))
+ }
+ return
+}
+
+func (server *Server) readRequestHeader(codec ServerCodec) (svc *service, mtype *methodType, req *Request, keepReading bool, err error) {
+ // Grab the request header.
+ req = server.getRequest()
+ err = codec.ReadRequestHeader(req)
+ if err != nil {
+ req = nil
+ if err == io.EOF || err == io.ErrUnexpectedEOF {
+ return
+ }
+ err = errors.New("rpc: server cannot decode request: " + err.Error())
+ return
+ }
+
+ // We read the header successfully. If we see an error now,
+ // we can still recover and move on to the next request.
+ keepReading = true
+
+ dot := strings.LastIndex(req.ServiceMethod, ".")
+ if dot < 0 {
+ err = errors.New("rpc: service/method request ill-formed: " + req.ServiceMethod)
+ return
+ }
+ serviceName := req.ServiceMethod[:dot]
+ methodName := req.ServiceMethod[dot+1:]
+
+ // Look up the request.
+ svci, ok := server.serviceMap.Load(serviceName)
+ if !ok {
+ err = errors.New("rpc: can't find service " + req.ServiceMethod)
+ return
+ }
+ svc = svci.(*service)
+ mtype = svc.method[methodName]
+ if mtype == nil {
+ err = errors.New("rpc: can't find method " + req.ServiceMethod)
+ }
+ return
+}
+
+// Accept accepts connections on the listener and serves requests
+// for each incoming connection. Accept blocks until the listener
+// returns a non-nil error. The caller typically invokes Accept in a
+// go statement.
+func (server *Server) Accept(lis net.Listener) {
+ for {
+ conn, err := lis.Accept()
+ if err != nil {
+ log.Print("rpc.Serve: accept:", err.Error())
+ return
+ }
+ go server.ServeConn(conn)
+ }
+}
+
+// Register publishes the receiver's methods in the DefaultServer.
+func Register(rcvr any) error { return DefaultServer.Register(rcvr) }
+
+// RegisterName is like Register but uses the provided name for the type
+// instead of the receiver's concrete type.
+func RegisterName(name string, rcvr any) error {
+ return DefaultServer.RegisterName(name, rcvr)
+}
+
+// A ServerCodec implements reading of RPC requests and writing of
+// RPC responses for the server side of an RPC session.
+// The server calls ReadRequestHeader and ReadRequestBody in pairs
+// to read requests from the connection, and it calls WriteResponse to
+// write a response back. The server calls Close when finished with the
+// connection. ReadRequestBody may be called with a nil
+// argument to force the body of the request to be read and discarded.
+// See NewClient's comment for information about concurrent access.
+type ServerCodec interface {
+ ReadRequestHeader(*Request) error
+ ReadRequestBody(any) error
+ WriteResponse(*Response, any) error
+
+ // Close can be called multiple times and must be idempotent.
+ Close() error
+}
+
+// ServeConn runs the DefaultServer on a single connection.
+// ServeConn blocks, serving the connection until the client hangs up.
+// The caller typically invokes ServeConn in a go statement.
+// ServeConn uses the gob wire format (see package gob) on the
+// connection. To use an alternate codec, use ServeCodec.
+// See NewClient's comment for information about concurrent access.
+func ServeConn(conn io.ReadWriteCloser) {
+ DefaultServer.ServeConn(conn)
+}
+
+// ServeCodec is like ServeConn but uses the specified codec to
+// decode requests and encode responses.
+func ServeCodec(codec ServerCodec) {
+ DefaultServer.ServeCodec(codec)
+}
+
+// ServeRequest is like ServeCodec but synchronously serves a single request.
+// It does not close the codec upon completion.
+func ServeRequest(codec ServerCodec) error {
+ return DefaultServer.ServeRequest(codec)
+}
+
+// Accept accepts connections on the listener and serves requests
+// to DefaultServer for each incoming connection.
+// Accept blocks; the caller typically invokes it in a go statement.
+func Accept(lis net.Listener) { DefaultServer.Accept(lis) }
+
+// Can connect to RPC service using HTTP CONNECT to rpcPath.
+var connected = "200 Connected to Go RPC"
+
+// ServeHTTP implements an http.Handler that answers RPC requests.
+func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+ if req.Method != "CONNECT" {
+ w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+ w.WriteHeader(http.StatusMethodNotAllowed)
+ io.WriteString(w, "405 must CONNECT\n")
+ return
+ }
+ conn, _, err := w.(http.Hijacker).Hijack()
+ if err != nil {
+ log.Print("rpc hijacking ", req.RemoteAddr, ": ", err.Error())
+ return
+ }
+ io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n")
+ server.ServeConn(conn)
+}
+
+// HandleHTTP registers an HTTP handler for RPC messages on rpcPath,
+// and a debugging handler on debugPath.
+// It is still necessary to invoke http.Serve(), typically in a go statement.
+func (server *Server) HandleHTTP(rpcPath, debugPath string) {
+ http.Handle(rpcPath, server)
+ http.Handle(debugPath, debugHTTP{server})
+}
+
+// HandleHTTP registers an HTTP handler for RPC messages to DefaultServer
+// on DefaultRPCPath and a debugging handler on DefaultDebugPath.
+// It is still necessary to invoke http.Serve(), typically in a go statement.
+func HandleHTTP() {
+ DefaultServer.HandleHTTP(DefaultRPCPath, DefaultDebugPath)
+}
diff --git a/contrib/go/_std_1.21/src/net/rpc/ya.make b/contrib/go/_std_1.21/src/net/rpc/ya.make
new file mode 100644
index 0000000000..f9b0002a93
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/rpc/ya.make
@@ -0,0 +1,18 @@
+GO_LIBRARY()
+
+SRCS(
+ client.go
+ debug.go
+ server.go
+)
+
+GO_TEST_SRCS(
+ client_test.go
+ server_test.go
+)
+
+END()
+
+RECURSE(
+ jsonrpc
+)
diff --git a/contrib/go/_std_1.21/src/net/sendfile_linux.go b/contrib/go/_std_1.21/src/net/sendfile_linux.go
new file mode 100644
index 0000000000..9a7d005803
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/sendfile_linux.go
@@ -0,0 +1,53 @@
+// Copyright 2011 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 net
+
+import (
+ "internal/poll"
+ "io"
+ "os"
+)
+
+// sendFile copies the contents of r to c using the sendfile
+// system call to minimize copies.
+//
+// if handled == true, sendFile returns the number (potentially zero) of bytes
+// copied and any non-EOF error.
+//
+// if handled == false, sendFile performed no work.
+func sendFile(c *netFD, r io.Reader) (written int64, err error, handled bool) {
+ var remain int64 = 1<<63 - 1 // by default, copy until EOF
+
+ lr, ok := r.(*io.LimitedReader)
+ if ok {
+ remain, r = lr.N, lr.R
+ if remain <= 0 {
+ return 0, nil, true
+ }
+ }
+ f, ok := r.(*os.File)
+ if !ok {
+ return 0, nil, false
+ }
+
+ sc, err := f.SyscallConn()
+ if err != nil {
+ return 0, nil, false
+ }
+
+ var werr error
+ err = sc.Read(func(fd uintptr) bool {
+ written, werr, handled = poll.SendFile(&c.pfd, int(fd), remain)
+ return true
+ })
+ if err == nil {
+ err = werr
+ }
+
+ if lr != nil {
+ lr.N = remain - written
+ }
+ return written, wrapSyscallError("sendfile", err), handled
+}
diff --git a/contrib/go/_std_1.20/src/net/sendfile_unix_alt.go b/contrib/go/_std_1.21/src/net/sendfile_unix_alt.go
index b86771721e..b86771721e 100644
--- a/contrib/go/_std_1.20/src/net/sendfile_unix_alt.go
+++ b/contrib/go/_std_1.21/src/net/sendfile_unix_alt.go
diff --git a/contrib/go/_std_1.20/src/net/sendfile_windows.go b/contrib/go/_std_1.21/src/net/sendfile_windows.go
index 59b1b0d5c1..59b1b0d5c1 100644
--- a/contrib/go/_std_1.20/src/net/sendfile_windows.go
+++ b/contrib/go/_std_1.21/src/net/sendfile_windows.go
diff --git a/contrib/go/_std_1.20/src/net/smtp/auth.go b/contrib/go/_std_1.21/src/net/smtp/auth.go
index 72eb16671f..72eb16671f 100644
--- a/contrib/go/_std_1.20/src/net/smtp/auth.go
+++ b/contrib/go/_std_1.21/src/net/smtp/auth.go
diff --git a/contrib/go/_std_1.20/src/net/smtp/smtp.go b/contrib/go/_std_1.21/src/net/smtp/smtp.go
index b5a025ef2a..b5a025ef2a 100644
--- a/contrib/go/_std_1.20/src/net/smtp/smtp.go
+++ b/contrib/go/_std_1.21/src/net/smtp/smtp.go
diff --git a/contrib/go/_std_1.21/src/net/smtp/ya.make b/contrib/go/_std_1.21/src/net/smtp/ya.make
new file mode 100644
index 0000000000..e7275e77d8
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/smtp/ya.make
@@ -0,0 +1,15 @@
+GO_LIBRARY()
+
+SRCS(
+ auth.go
+ smtp.go
+)
+
+GO_TEST_SRCS(smtp_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/net/sock_bsd.go b/contrib/go/_std_1.21/src/net/sock_bsd.go
index 27daf722b5..27daf722b5 100644
--- a/contrib/go/_std_1.20/src/net/sock_bsd.go
+++ b/contrib/go/_std_1.21/src/net/sock_bsd.go
diff --git a/contrib/go/_std_1.21/src/net/sock_cloexec.go b/contrib/go/_std_1.21/src/net/sock_cloexec.go
new file mode 100644
index 0000000000..9eeb89746b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/sock_cloexec.go
@@ -0,0 +1,48 @@
+// Copyright 2013 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.
+
+// This file implements sysSocket for platforms that provide a fast path for
+// setting SetNonblock and CloseOnExec.
+
+//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris
+
+package net
+
+import (
+ "internal/poll"
+ "os"
+ "syscall"
+)
+
+// Wrapper around the socket system call that marks the returned file
+// descriptor as nonblocking and close-on-exec.
+func sysSocket(family, sotype, proto int) (int, error) {
+ s, err := socketFunc(family, sotype|syscall.SOCK_NONBLOCK|syscall.SOCK_CLOEXEC, proto)
+ // TODO: We can remove the fallback on Linux and *BSD,
+ // as currently supported versions all support accept4
+ // with SOCK_CLOEXEC, but Solaris does not. See issue #59359.
+ switch err {
+ case nil:
+ return s, nil
+ default:
+ return -1, os.NewSyscallError("socket", err)
+ case syscall.EPROTONOSUPPORT, syscall.EINVAL:
+ }
+
+ // See ../syscall/exec_unix.go for description of ForkLock.
+ syscall.ForkLock.RLock()
+ s, err = socketFunc(family, sotype, proto)
+ if err == nil {
+ syscall.CloseOnExec(s)
+ }
+ syscall.ForkLock.RUnlock()
+ if err != nil {
+ return -1, os.NewSyscallError("socket", err)
+ }
+ if err = syscall.SetNonblock(s, true); err != nil {
+ poll.CloseFunc(s)
+ return -1, os.NewSyscallError("setnonblock", err)
+ }
+ return s, nil
+}
diff --git a/contrib/go/_std_1.20/src/net/sock_linux.go b/contrib/go/_std_1.21/src/net/sock_linux.go
index cffe9a236f..cffe9a236f 100644
--- a/contrib/go/_std_1.20/src/net/sock_linux.go
+++ b/contrib/go/_std_1.21/src/net/sock_linux.go
diff --git a/contrib/go/_std_1.20/src/net/sock_posix.go b/contrib/go/_std_1.21/src/net/sock_posix.go
index b3e1806ba9..b3e1806ba9 100644
--- a/contrib/go/_std_1.20/src/net/sock_posix.go
+++ b/contrib/go/_std_1.21/src/net/sock_posix.go
diff --git a/contrib/go/_std_1.20/src/net/sock_windows.go b/contrib/go/_std_1.21/src/net/sock_windows.go
index fa11c7af2e..fa11c7af2e 100644
--- a/contrib/go/_std_1.20/src/net/sock_windows.go
+++ b/contrib/go/_std_1.21/src/net/sock_windows.go
diff --git a/contrib/go/_std_1.21/src/net/sockaddr_posix.go b/contrib/go/_std_1.21/src/net/sockaddr_posix.go
new file mode 100644
index 0000000000..e44fc76f4b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/sockaddr_posix.go
@@ -0,0 +1,34 @@
+// Copyright 2018 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package net
+
+import (
+ "syscall"
+)
+
+// A sockaddr represents a TCP, UDP, IP or Unix network endpoint
+// address that can be converted into a syscall.Sockaddr.
+type sockaddr interface {
+ Addr
+
+ // family returns the platform-dependent address family
+ // identifier.
+ family() int
+
+ // isWildcard reports whether the address is a wildcard
+ // address.
+ isWildcard() bool
+
+ // sockaddr returns the address converted into a syscall
+ // sockaddr type that implements syscall.Sockaddr
+ // interface. It returns a nil interface when the address is
+ // nil.
+ sockaddr(family int) (syscall.Sockaddr, error)
+
+ // toLocal maps the zero address to a local system address (127.0.0.1 or ::1)
+ toLocal(net string) sockaddr
+}
diff --git a/contrib/go/_std_1.20/src/net/sockopt_bsd.go b/contrib/go/_std_1.21/src/net/sockopt_bsd.go
index ff99811980..ff99811980 100644
--- a/contrib/go/_std_1.20/src/net/sockopt_bsd.go
+++ b/contrib/go/_std_1.21/src/net/sockopt_bsd.go
diff --git a/contrib/go/_std_1.20/src/net/sockopt_linux.go b/contrib/go/_std_1.21/src/net/sockopt_linux.go
index 3d544299ac..3d544299ac 100644
--- a/contrib/go/_std_1.20/src/net/sockopt_linux.go
+++ b/contrib/go/_std_1.21/src/net/sockopt_linux.go
diff --git a/contrib/go/_std_1.20/src/net/sockopt_posix.go b/contrib/go/_std_1.21/src/net/sockopt_posix.go
index 32e8fcd505..32e8fcd505 100644
--- a/contrib/go/_std_1.20/src/net/sockopt_posix.go
+++ b/contrib/go/_std_1.21/src/net/sockopt_posix.go
diff --git a/contrib/go/_std_1.20/src/net/sockopt_windows.go b/contrib/go/_std_1.21/src/net/sockopt_windows.go
index 8afaf34514..8afaf34514 100644
--- a/contrib/go/_std_1.20/src/net/sockopt_windows.go
+++ b/contrib/go/_std_1.21/src/net/sockopt_windows.go
diff --git a/contrib/go/_std_1.20/src/net/sockoptip_bsdvar.go b/contrib/go/_std_1.21/src/net/sockoptip_bsdvar.go
index 3e9ba1ee78..3e9ba1ee78 100644
--- a/contrib/go/_std_1.20/src/net/sockoptip_bsdvar.go
+++ b/contrib/go/_std_1.21/src/net/sockoptip_bsdvar.go
diff --git a/contrib/go/_std_1.20/src/net/sockoptip_linux.go b/contrib/go/_std_1.21/src/net/sockoptip_linux.go
index bd7d834425..bd7d834425 100644
--- a/contrib/go/_std_1.20/src/net/sockoptip_linux.go
+++ b/contrib/go/_std_1.21/src/net/sockoptip_linux.go
diff --git a/contrib/go/_std_1.20/src/net/sockoptip_posix.go b/contrib/go/_std_1.21/src/net/sockoptip_posix.go
index 572ea455c0..572ea455c0 100644
--- a/contrib/go/_std_1.20/src/net/sockoptip_posix.go
+++ b/contrib/go/_std_1.21/src/net/sockoptip_posix.go
diff --git a/contrib/go/_std_1.20/src/net/sockoptip_windows.go b/contrib/go/_std_1.21/src/net/sockoptip_windows.go
index 62676039a3..62676039a3 100644
--- a/contrib/go/_std_1.20/src/net/sockoptip_windows.go
+++ b/contrib/go/_std_1.21/src/net/sockoptip_windows.go
diff --git a/contrib/go/_std_1.21/src/net/splice_linux.go b/contrib/go/_std_1.21/src/net/splice_linux.go
new file mode 100644
index 0000000000..ab2ab70b28
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/splice_linux.go
@@ -0,0 +1,44 @@
+// Copyright 2018 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 net
+
+import (
+ "internal/poll"
+ "io"
+)
+
+// splice transfers data from r to c using the splice system call to minimize
+// copies from and to userspace. c must be a TCP connection. Currently, splice
+// is only enabled if r is a TCP or a stream-oriented Unix connection.
+//
+// If splice returns handled == false, it has performed no work.
+func splice(c *netFD, r io.Reader) (written int64, err error, handled bool) {
+ var remain int64 = 1<<63 - 1 // by default, copy until EOF
+ lr, ok := r.(*io.LimitedReader)
+ if ok {
+ remain, r = lr.N, lr.R
+ if remain <= 0 {
+ return 0, nil, true
+ }
+ }
+
+ var s *netFD
+ if tc, ok := r.(*TCPConn); ok {
+ s = tc.fd
+ } else if uc, ok := r.(*UnixConn); ok {
+ if uc.fd.net != "unix" {
+ return 0, nil, false
+ }
+ s = uc.fd
+ } else {
+ return 0, nil, false
+ }
+
+ written, handled, sc, err := poll.Splice(&c.pfd, &s.pfd, remain)
+ if lr != nil {
+ lr.N -= written
+ }
+ return written, wrapSyscallError(sc, err), handled
+}
diff --git a/contrib/go/_std_1.20/src/net/splice_stub.go b/contrib/go/_std_1.21/src/net/splice_stub.go
index 3cdadb11c5..3cdadb11c5 100644
--- a/contrib/go/_std_1.20/src/net/splice_stub.go
+++ b/contrib/go/_std_1.21/src/net/splice_stub.go
diff --git a/contrib/go/_std_1.20/src/net/sys_cloexec.go b/contrib/go/_std_1.21/src/net/sys_cloexec.go
index 6e61d40c19..6e61d40c19 100644
--- a/contrib/go/_std_1.20/src/net/sys_cloexec.go
+++ b/contrib/go/_std_1.21/src/net/sys_cloexec.go
diff --git a/contrib/go/_std_1.21/src/net/tcpsock.go b/contrib/go/_std_1.21/src/net/tcpsock.go
new file mode 100644
index 0000000000..358e48723b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/tcpsock.go
@@ -0,0 +1,398 @@
+// Copyright 2009 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 net
+
+import (
+ "context"
+ "internal/itoa"
+ "io"
+ "net/netip"
+ "os"
+ "syscall"
+ "time"
+)
+
+// BUG(mikio): On JS and Windows, the File method of TCPConn and
+// TCPListener is not implemented.
+
+// TCPAddr represents the address of a TCP end point.
+type TCPAddr struct {
+ IP IP
+ Port int
+ Zone string // IPv6 scoped addressing zone
+}
+
+// AddrPort returns the TCPAddr a as a netip.AddrPort.
+//
+// If a.Port does not fit in a uint16, it's silently truncated.
+//
+// If a is nil, a zero value is returned.
+func (a *TCPAddr) AddrPort() netip.AddrPort {
+ if a == nil {
+ return netip.AddrPort{}
+ }
+ na, _ := netip.AddrFromSlice(a.IP)
+ na = na.WithZone(a.Zone)
+ return netip.AddrPortFrom(na, uint16(a.Port))
+}
+
+// Network returns the address's network name, "tcp".
+func (a *TCPAddr) Network() string { return "tcp" }
+
+func (a *TCPAddr) String() string {
+ if a == nil {
+ return "<nil>"
+ }
+ ip := ipEmptyString(a.IP)
+ if a.Zone != "" {
+ return JoinHostPort(ip+"%"+a.Zone, itoa.Itoa(a.Port))
+ }
+ return JoinHostPort(ip, itoa.Itoa(a.Port))
+}
+
+func (a *TCPAddr) isWildcard() bool {
+ if a == nil || a.IP == nil {
+ return true
+ }
+ return a.IP.IsUnspecified()
+}
+
+func (a *TCPAddr) opAddr() Addr {
+ if a == nil {
+ return nil
+ }
+ return a
+}
+
+// ResolveTCPAddr returns an address of TCP end point.
+//
+// The network must be a TCP network name.
+//
+// If the host in the address parameter is not a literal IP address or
+// the port is not a literal port number, ResolveTCPAddr resolves the
+// address to an address of TCP end point.
+// Otherwise, it parses the address as a pair of literal IP address
+// and port number.
+// The address parameter can use a host name, but this is not
+// recommended, because it will return at most one of the host name's
+// IP addresses.
+//
+// See func Dial for a description of the network and address
+// parameters.
+func ResolveTCPAddr(network, address string) (*TCPAddr, error) {
+ switch network {
+ case "tcp", "tcp4", "tcp6":
+ case "": // a hint wildcard for Go 1.0 undocumented behavior
+ network = "tcp"
+ default:
+ return nil, UnknownNetworkError(network)
+ }
+ addrs, err := DefaultResolver.internetAddrList(context.Background(), network, address)
+ if err != nil {
+ return nil, err
+ }
+ return addrs.forResolve(network, address).(*TCPAddr), nil
+}
+
+// TCPAddrFromAddrPort returns addr as a TCPAddr. If addr.IsValid() is false,
+// then the returned TCPAddr will contain a nil IP field, indicating an
+// address family-agnostic unspecified address.
+func TCPAddrFromAddrPort(addr netip.AddrPort) *TCPAddr {
+ return &TCPAddr{
+ IP: addr.Addr().AsSlice(),
+ Zone: addr.Addr().Zone(),
+ Port: int(addr.Port()),
+ }
+}
+
+// TCPConn is an implementation of the Conn interface for TCP network
+// connections.
+type TCPConn struct {
+ conn
+}
+
+// SyscallConn returns a raw network connection.
+// This implements the syscall.Conn interface.
+func (c *TCPConn) SyscallConn() (syscall.RawConn, error) {
+ if !c.ok() {
+ return nil, syscall.EINVAL
+ }
+ return newRawConn(c.fd)
+}
+
+// ReadFrom implements the io.ReaderFrom ReadFrom method.
+func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
+ if !c.ok() {
+ return 0, syscall.EINVAL
+ }
+ n, err := c.readFrom(r)
+ if err != nil && err != io.EOF {
+ err = &OpError{Op: "readfrom", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return n, err
+}
+
+// CloseRead shuts down the reading side of the TCP connection.
+// Most callers should just use Close.
+func (c *TCPConn) CloseRead() error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := c.fd.closeRead(); err != nil {
+ return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return nil
+}
+
+// CloseWrite shuts down the writing side of the TCP connection.
+// Most callers should just use Close.
+func (c *TCPConn) CloseWrite() error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := c.fd.closeWrite(); err != nil {
+ return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return nil
+}
+
+// SetLinger sets the behavior of Close on a connection which still
+// has data waiting to be sent or to be acknowledged.
+//
+// If sec < 0 (the default), the operating system finishes sending the
+// data in the background.
+//
+// If sec == 0, the operating system discards any unsent or
+// unacknowledged data.
+//
+// If sec > 0, the data is sent in the background as with sec < 0.
+// On some operating systems including Linux, this may cause Close to block
+// until all data has been sent or discarded.
+// On some operating systems after sec seconds have elapsed any remaining
+// unsent data may be discarded.
+func (c *TCPConn) SetLinger(sec int) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := setLinger(c.fd, sec); err != nil {
+ return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return nil
+}
+
+// SetKeepAlive sets whether the operating system should send
+// keep-alive messages on the connection.
+func (c *TCPConn) SetKeepAlive(keepalive bool) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := setKeepAlive(c.fd, keepalive); err != nil {
+ return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return nil
+}
+
+// SetKeepAlivePeriod sets period between keep-alives.
+func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := setKeepAlivePeriod(c.fd, d); err != nil {
+ return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return nil
+}
+
+// SetNoDelay controls whether the operating system should delay
+// packet transmission in hopes of sending fewer packets (Nagle's
+// algorithm). The default is true (no delay), meaning that data is
+// sent as soon as possible after a Write.
+func (c *TCPConn) SetNoDelay(noDelay bool) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := setNoDelay(c.fd, noDelay); err != nil {
+ return &OpError{Op: "set", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return nil
+}
+
+// MultipathTCP reports whether the ongoing connection is using MPTCP.
+//
+// If Multipath TCP is not supported by the host, by the other peer or
+// intentionally / accidentally filtered out by a device in between, a
+// fallback to TCP will be done. This method does its best to check if
+// MPTCP is still being used or not.
+//
+// On Linux, more conditions are verified on kernels >= v5.16, improving
+// the results.
+func (c *TCPConn) MultipathTCP() (bool, error) {
+ if !c.ok() {
+ return false, syscall.EINVAL
+ }
+ return isUsingMultipathTCP(c.fd), nil
+}
+
+func newTCPConn(fd *netFD, keepAlive time.Duration, keepAliveHook func(time.Duration)) *TCPConn {
+ setNoDelay(fd, true)
+ if keepAlive == 0 {
+ keepAlive = defaultTCPKeepAlive
+ }
+ if keepAlive > 0 {
+ setKeepAlive(fd, true)
+ setKeepAlivePeriod(fd, keepAlive)
+ if keepAliveHook != nil {
+ keepAliveHook(keepAlive)
+ }
+ }
+ return &TCPConn{conn{fd}}
+}
+
+// DialTCP acts like Dial for TCP networks.
+//
+// The network must be a TCP network name; see func Dial for details.
+//
+// If laddr is nil, a local address is automatically chosen.
+// If the IP field of raddr is nil or an unspecified IP address, the
+// local system is assumed.
+func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error) {
+ switch network {
+ case "tcp", "tcp4", "tcp6":
+ default:
+ return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
+ }
+ if raddr == nil {
+ return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
+ }
+ sd := &sysDialer{network: network, address: raddr.String()}
+ c, err := sd.dialTCP(context.Background(), laddr, raddr)
+ if err != nil {
+ return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
+ }
+ return c, nil
+}
+
+// TCPListener is a TCP network listener. Clients should typically
+// use variables of type Listener instead of assuming TCP.
+type TCPListener struct {
+ fd *netFD
+ lc ListenConfig
+}
+
+// SyscallConn returns a raw network connection.
+// This implements the syscall.Conn interface.
+//
+// The returned RawConn only supports calling Control. Read and
+// Write return an error.
+func (l *TCPListener) SyscallConn() (syscall.RawConn, error) {
+ if !l.ok() {
+ return nil, syscall.EINVAL
+ }
+ return newRawListener(l.fd)
+}
+
+// AcceptTCP accepts the next incoming call and returns the new
+// connection.
+func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
+ if !l.ok() {
+ return nil, syscall.EINVAL
+ }
+ c, err := l.accept()
+ if err != nil {
+ return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+ }
+ return c, nil
+}
+
+// Accept implements the Accept method in the Listener interface; it
+// waits for the next call and returns a generic Conn.
+func (l *TCPListener) Accept() (Conn, error) {
+ if !l.ok() {
+ return nil, syscall.EINVAL
+ }
+ c, err := l.accept()
+ if err != nil {
+ return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+ }
+ return c, nil
+}
+
+// Close stops listening on the TCP address.
+// Already Accepted connections are not closed.
+func (l *TCPListener) Close() error {
+ if !l.ok() {
+ return syscall.EINVAL
+ }
+ if err := l.close(); err != nil {
+ return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+ }
+ return nil
+}
+
+// Addr returns the listener's network address, a *TCPAddr.
+// The Addr returned is shared by all invocations of Addr, so
+// do not modify it.
+func (l *TCPListener) Addr() Addr { return l.fd.laddr }
+
+// SetDeadline sets the deadline associated with the listener.
+// A zero time value disables the deadline.
+func (l *TCPListener) SetDeadline(t time.Time) error {
+ if !l.ok() {
+ return syscall.EINVAL
+ }
+ if err := l.fd.pfd.SetDeadline(t); err != nil {
+ return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+ }
+ return nil
+}
+
+// File returns a copy of the underlying os.File.
+// It is the caller's responsibility to close f when finished.
+// Closing l does not affect f, and closing f does not affect l.
+//
+// The returned os.File's file descriptor is different from the
+// connection's. Attempting to change properties of the original
+// using this duplicate may or may not have the desired effect.
+func (l *TCPListener) File() (f *os.File, err error) {
+ if !l.ok() {
+ return nil, syscall.EINVAL
+ }
+ f, err = l.file()
+ if err != nil {
+ return nil, &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+ }
+ return
+}
+
+// ListenTCP acts like Listen for TCP networks.
+//
+// The network must be a TCP network name; see func Dial for details.
+//
+// If the IP field of laddr is nil or an unspecified IP address,
+// ListenTCP listens on all available unicast and anycast IP addresses
+// of the local system.
+// If the Port field of laddr is 0, a port number is automatically
+// chosen.
+func ListenTCP(network string, laddr *TCPAddr) (*TCPListener, error) {
+ switch network {
+ case "tcp", "tcp4", "tcp6":
+ default:
+ return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
+ }
+ if laddr == nil {
+ laddr = &TCPAddr{}
+ }
+ sl := &sysListener{network: network, address: laddr.String()}
+ ln, err := sl.listenTCP(context.Background(), laddr)
+ if err != nil {
+ return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
+ }
+ return ln, nil
+}
+
+// roundDurationUp rounds d to the next multiple of to.
+func roundDurationUp(d time.Duration, to time.Duration) time.Duration {
+ return (d + to - 1) / to
+}
diff --git a/contrib/go/_std_1.21/src/net/tcpsock_posix.go b/contrib/go/_std_1.21/src/net/tcpsock_posix.go
new file mode 100644
index 0000000000..e6f425b1cd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/tcpsock_posix.go
@@ -0,0 +1,187 @@
+// Copyright 2009 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package net
+
+import (
+ "context"
+ "io"
+ "os"
+ "syscall"
+)
+
+func sockaddrToTCP(sa syscall.Sockaddr) Addr {
+ switch sa := sa.(type) {
+ case *syscall.SockaddrInet4:
+ return &TCPAddr{IP: sa.Addr[0:], Port: sa.Port}
+ case *syscall.SockaddrInet6:
+ return &TCPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneCache.name(int(sa.ZoneId))}
+ }
+ return nil
+}
+
+func (a *TCPAddr) family() int {
+ if a == nil || len(a.IP) <= IPv4len {
+ return syscall.AF_INET
+ }
+ if a.IP.To4() != nil {
+ return syscall.AF_INET
+ }
+ return syscall.AF_INET6
+}
+
+func (a *TCPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
+ if a == nil {
+ return nil, nil
+ }
+ return ipToSockaddr(family, a.IP, a.Port, a.Zone)
+}
+
+func (a *TCPAddr) toLocal(net string) sockaddr {
+ return &TCPAddr{loopbackIP(net), a.Port, a.Zone}
+}
+
+func (c *TCPConn) readFrom(r io.Reader) (int64, error) {
+ if n, err, handled := splice(c.fd, r); handled {
+ return n, err
+ }
+ if n, err, handled := sendFile(c.fd, r); handled {
+ return n, err
+ }
+ return genericReadFrom(c, r)
+}
+
+func (sd *sysDialer) dialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
+ if h := sd.testHookDialTCP; h != nil {
+ return h(ctx, sd.network, laddr, raddr)
+ }
+ if h := testHookDialTCP; h != nil {
+ return h(ctx, sd.network, laddr, raddr)
+ }
+ return sd.doDialTCP(ctx, laddr, raddr)
+}
+
+func (sd *sysDialer) doDialTCP(ctx context.Context, laddr, raddr *TCPAddr) (*TCPConn, error) {
+ return sd.doDialTCPProto(ctx, laddr, raddr, 0)
+}
+
+func (sd *sysDialer) doDialTCPProto(ctx context.Context, laddr, raddr *TCPAddr, proto int) (*TCPConn, error) {
+ ctrlCtxFn := sd.Dialer.ControlContext
+ if ctrlCtxFn == nil && sd.Dialer.Control != nil {
+ ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+ return sd.Dialer.Control(network, address, c)
+ }
+ }
+ fd, err := internetSocket(ctx, sd.network, laddr, raddr, syscall.SOCK_STREAM, proto, "dial", ctrlCtxFn)
+
+ // TCP has a rarely used mechanism called a 'simultaneous connection' in
+ // which Dial("tcp", addr1, addr2) run on the machine at addr1 can
+ // connect to a simultaneous Dial("tcp", addr2, addr1) run on the machine
+ // at addr2, without either machine executing Listen. If laddr == nil,
+ // it means we want the kernel to pick an appropriate originating local
+ // address. Some Linux kernels cycle blindly through a fixed range of
+ // local ports, regardless of destination port. If a kernel happens to
+ // pick local port 50001 as the source for a Dial("tcp", "", "localhost:50001"),
+ // then the Dial will succeed, having simultaneously connected to itself.
+ // This can only happen when we are letting the kernel pick a port (laddr == nil)
+ // and when there is no listener for the destination address.
+ // It's hard to argue this is anything other than a kernel bug. If we
+ // see this happen, rather than expose the buggy effect to users, we
+ // close the fd and try again. If it happens twice more, we relent and
+ // use the result. See also:
+ // https://golang.org/issue/2690
+ // https://stackoverflow.com/questions/4949858/
+ //
+ // The opposite can also happen: if we ask the kernel to pick an appropriate
+ // originating local address, sometimes it picks one that is already in use.
+ // So if the error is EADDRNOTAVAIL, we have to try again too, just for
+ // a different reason.
+ //
+ // The kernel socket code is no doubt enjoying watching us squirm.
+ for i := 0; i < 2 && (laddr == nil || laddr.Port == 0) && (selfConnect(fd, err) || spuriousENOTAVAIL(err)); i++ {
+ if err == nil {
+ fd.Close()
+ }
+ fd, err = internetSocket(ctx, sd.network, laddr, raddr, syscall.SOCK_STREAM, proto, "dial", ctrlCtxFn)
+ }
+
+ if err != nil {
+ return nil, err
+ }
+ return newTCPConn(fd, sd.Dialer.KeepAlive, testHookSetKeepAlive), nil
+}
+
+func selfConnect(fd *netFD, err error) bool {
+ // If the connect failed, we clearly didn't connect to ourselves.
+ if err != nil {
+ return false
+ }
+
+ // The socket constructor can return an fd with raddr nil under certain
+ // unknown conditions. The errors in the calls there to Getpeername
+ // are discarded, but we can't catch the problem there because those
+ // calls are sometimes legally erroneous with a "socket not connected".
+ // Since this code (selfConnect) is already trying to work around
+ // a problem, we make sure if this happens we recognize trouble and
+ // ask the DialTCP routine to try again.
+ // TODO: try to understand what's really going on.
+ if fd.laddr == nil || fd.raddr == nil {
+ return true
+ }
+ l := fd.laddr.(*TCPAddr)
+ r := fd.raddr.(*TCPAddr)
+ return l.Port == r.Port && l.IP.Equal(r.IP)
+}
+
+func spuriousENOTAVAIL(err error) bool {
+ if op, ok := err.(*OpError); ok {
+ err = op.Err
+ }
+ if sys, ok := err.(*os.SyscallError); ok {
+ err = sys.Err
+ }
+ return err == syscall.EADDRNOTAVAIL
+}
+
+func (ln *TCPListener) ok() bool { return ln != nil && ln.fd != nil }
+
+func (ln *TCPListener) accept() (*TCPConn, error) {
+ fd, err := ln.fd.accept()
+ if err != nil {
+ return nil, err
+ }
+ return newTCPConn(fd, ln.lc.KeepAlive, nil), nil
+}
+
+func (ln *TCPListener) close() error {
+ return ln.fd.Close()
+}
+
+func (ln *TCPListener) file() (*os.File, error) {
+ f, err := ln.fd.dup()
+ if err != nil {
+ return nil, err
+ }
+ return f, nil
+}
+
+func (sl *sysListener) listenTCP(ctx context.Context, laddr *TCPAddr) (*TCPListener, error) {
+ return sl.listenTCPProto(ctx, laddr, 0)
+}
+
+func (sl *sysListener) listenTCPProto(ctx context.Context, laddr *TCPAddr, proto int) (*TCPListener, error) {
+ var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
+ if sl.ListenConfig.Control != nil {
+ ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+ return sl.ListenConfig.Control(network, address, c)
+ }
+ }
+ fd, err := internetSocket(ctx, sl.network, laddr, nil, syscall.SOCK_STREAM, proto, "listen", ctrlCtxFn)
+ if err != nil {
+ return nil, err
+ }
+ return &TCPListener{fd: fd, lc: sl.ListenConfig}, nil
+}
diff --git a/contrib/go/_std_1.20/src/net/tcpsockopt_darwin.go b/contrib/go/_std_1.21/src/net/tcpsockopt_darwin.go
index 53c6756e33..53c6756e33 100644
--- a/contrib/go/_std_1.20/src/net/tcpsockopt_darwin.go
+++ b/contrib/go/_std_1.21/src/net/tcpsockopt_darwin.go
diff --git a/contrib/go/_std_1.20/src/net/tcpsockopt_posix.go b/contrib/go/_std_1.21/src/net/tcpsockopt_posix.go
index d708f04875..d708f04875 100644
--- a/contrib/go/_std_1.20/src/net/tcpsockopt_posix.go
+++ b/contrib/go/_std_1.21/src/net/tcpsockopt_posix.go
diff --git a/contrib/go/_std_1.20/src/net/tcpsockopt_unix.go b/contrib/go/_std_1.21/src/net/tcpsockopt_unix.go
index bdcdc40239..bdcdc40239 100644
--- a/contrib/go/_std_1.20/src/net/tcpsockopt_unix.go
+++ b/contrib/go/_std_1.21/src/net/tcpsockopt_unix.go
diff --git a/contrib/go/_std_1.20/src/net/tcpsockopt_windows.go b/contrib/go/_std_1.21/src/net/tcpsockopt_windows.go
index 4a0b09465e..4a0b09465e 100644
--- a/contrib/go/_std_1.20/src/net/tcpsockopt_windows.go
+++ b/contrib/go/_std_1.21/src/net/tcpsockopt_windows.go
diff --git a/contrib/go/_std_1.20/src/net/textproto/header.go b/contrib/go/_std_1.21/src/net/textproto/header.go
index a58df7aebc..a58df7aebc 100644
--- a/contrib/go/_std_1.20/src/net/textproto/header.go
+++ b/contrib/go/_std_1.21/src/net/textproto/header.go
diff --git a/contrib/go/_std_1.20/src/net/textproto/pipeline.go b/contrib/go/_std_1.21/src/net/textproto/pipeline.go
index 1928a306bf..1928a306bf 100644
--- a/contrib/go/_std_1.20/src/net/textproto/pipeline.go
+++ b/contrib/go/_std_1.21/src/net/textproto/pipeline.go
diff --git a/contrib/go/_std_1.20/src/net/textproto/reader.go b/contrib/go/_std_1.21/src/net/textproto/reader.go
index fc2590b1cd..fc2590b1cd 100644
--- a/contrib/go/_std_1.20/src/net/textproto/reader.go
+++ b/contrib/go/_std_1.21/src/net/textproto/reader.go
diff --git a/contrib/go/_std_1.20/src/net/textproto/textproto.go b/contrib/go/_std_1.21/src/net/textproto/textproto.go
index 70038d5888..70038d5888 100644
--- a/contrib/go/_std_1.20/src/net/textproto/textproto.go
+++ b/contrib/go/_std_1.21/src/net/textproto/textproto.go
diff --git a/contrib/go/_std_1.20/src/net/textproto/writer.go b/contrib/go/_std_1.21/src/net/textproto/writer.go
index 2ece3f511b..2ece3f511b 100644
--- a/contrib/go/_std_1.20/src/net/textproto/writer.go
+++ b/contrib/go/_std_1.21/src/net/textproto/writer.go
diff --git a/contrib/go/_std_1.21/src/net/textproto/ya.make b/contrib/go/_std_1.21/src/net/textproto/ya.make
new file mode 100644
index 0000000000..dac7813c7d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/textproto/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ header.go
+ pipeline.go
+ reader.go
+ textproto.go
+ writer.go
+)
+
+GO_TEST_SRCS(
+ header_test.go
+ reader_test.go
+ writer_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/net/udpsock.go b/contrib/go/_std_1.21/src/net/udpsock.go
index e30624dea5..e30624dea5 100644
--- a/contrib/go/_std_1.20/src/net/udpsock.go
+++ b/contrib/go/_std_1.21/src/net/udpsock.go
diff --git a/contrib/go/_std_1.21/src/net/udpsock_posix.go b/contrib/go/_std_1.21/src/net/udpsock_posix.go
new file mode 100644
index 0000000000..f3dbcfec00
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/udpsock_posix.go
@@ -0,0 +1,287 @@
+// Copyright 2009 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package net
+
+import (
+ "context"
+ "net/netip"
+ "syscall"
+)
+
+func sockaddrToUDP(sa syscall.Sockaddr) Addr {
+ switch sa := sa.(type) {
+ case *syscall.SockaddrInet4:
+ return &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
+ case *syscall.SockaddrInet6:
+ return &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneCache.name(int(sa.ZoneId))}
+ }
+ return nil
+}
+
+func (a *UDPAddr) family() int {
+ if a == nil || len(a.IP) <= IPv4len {
+ return syscall.AF_INET
+ }
+ if a.IP.To4() != nil {
+ return syscall.AF_INET
+ }
+ return syscall.AF_INET6
+}
+
+func (a *UDPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
+ if a == nil {
+ return nil, nil
+ }
+ return ipToSockaddr(family, a.IP, a.Port, a.Zone)
+}
+
+func (a *UDPAddr) toLocal(net string) sockaddr {
+ return &UDPAddr{loopbackIP(net), a.Port, a.Zone}
+}
+
+func (c *UDPConn) readFrom(b []byte, addr *UDPAddr) (int, *UDPAddr, error) {
+ var n int
+ var err error
+ switch c.fd.family {
+ case syscall.AF_INET:
+ var from syscall.SockaddrInet4
+ n, err = c.fd.readFromInet4(b, &from)
+ if err == nil {
+ ip := from.Addr // copy from.Addr; ip escapes, so this line allocates 4 bytes
+ *addr = UDPAddr{IP: ip[:], Port: from.Port}
+ }
+ case syscall.AF_INET6:
+ var from syscall.SockaddrInet6
+ n, err = c.fd.readFromInet6(b, &from)
+ if err == nil {
+ ip := from.Addr // copy from.Addr; ip escapes, so this line allocates 16 bytes
+ *addr = UDPAddr{IP: ip[:], Port: from.Port, Zone: zoneCache.name(int(from.ZoneId))}
+ }
+ }
+ if err != nil {
+ // No sockaddr, so don't return UDPAddr.
+ addr = nil
+ }
+ return n, addr, err
+}
+
+func (c *UDPConn) readFromAddrPort(b []byte) (n int, addr netip.AddrPort, err error) {
+ var ip netip.Addr
+ var port int
+ switch c.fd.family {
+ case syscall.AF_INET:
+ var from syscall.SockaddrInet4
+ n, err = c.fd.readFromInet4(b, &from)
+ if err == nil {
+ ip = netip.AddrFrom4(from.Addr)
+ port = from.Port
+ }
+ case syscall.AF_INET6:
+ var from syscall.SockaddrInet6
+ n, err = c.fd.readFromInet6(b, &from)
+ if err == nil {
+ ip = netip.AddrFrom16(from.Addr).WithZone(zoneCache.name(int(from.ZoneId)))
+ port = from.Port
+ }
+ }
+ if err == nil {
+ addr = netip.AddrPortFrom(ip, uint16(port))
+ }
+ return n, addr, err
+}
+
+func (c *UDPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr netip.AddrPort, err error) {
+ switch c.fd.family {
+ case syscall.AF_INET:
+ var sa syscall.SockaddrInet4
+ n, oobn, flags, err = c.fd.readMsgInet4(b, oob, 0, &sa)
+ ip := netip.AddrFrom4(sa.Addr)
+ addr = netip.AddrPortFrom(ip, uint16(sa.Port))
+ case syscall.AF_INET6:
+ var sa syscall.SockaddrInet6
+ n, oobn, flags, err = c.fd.readMsgInet6(b, oob, 0, &sa)
+ ip := netip.AddrFrom16(sa.Addr).WithZone(zoneCache.name(int(sa.ZoneId)))
+ addr = netip.AddrPortFrom(ip, uint16(sa.Port))
+ }
+ return
+}
+
+func (c *UDPConn) writeTo(b []byte, addr *UDPAddr) (int, error) {
+ if c.fd.isConnected {
+ return 0, ErrWriteToConnected
+ }
+ if addr == nil {
+ return 0, errMissingAddress
+ }
+
+ switch c.fd.family {
+ case syscall.AF_INET:
+ sa, err := ipToSockaddrInet4(addr.IP, addr.Port)
+ if err != nil {
+ return 0, err
+ }
+ return c.fd.writeToInet4(b, &sa)
+ case syscall.AF_INET6:
+ sa, err := ipToSockaddrInet6(addr.IP, addr.Port, addr.Zone)
+ if err != nil {
+ return 0, err
+ }
+ return c.fd.writeToInet6(b, &sa)
+ default:
+ return 0, &AddrError{Err: "invalid address family", Addr: addr.IP.String()}
+ }
+}
+
+func (c *UDPConn) writeToAddrPort(b []byte, addr netip.AddrPort) (int, error) {
+ if c.fd.isConnected {
+ return 0, ErrWriteToConnected
+ }
+ if !addr.IsValid() {
+ return 0, errMissingAddress
+ }
+
+ switch c.fd.family {
+ case syscall.AF_INET:
+ sa, err := addrPortToSockaddrInet4(addr)
+ if err != nil {
+ return 0, err
+ }
+ return c.fd.writeToInet4(b, &sa)
+ case syscall.AF_INET6:
+ sa, err := addrPortToSockaddrInet6(addr)
+ if err != nil {
+ return 0, err
+ }
+ return c.fd.writeToInet6(b, &sa)
+ default:
+ return 0, &AddrError{Err: "invalid address family", Addr: addr.Addr().String()}
+ }
+}
+
+func (c *UDPConn) writeMsg(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
+ if c.fd.isConnected && addr != nil {
+ return 0, 0, ErrWriteToConnected
+ }
+ if !c.fd.isConnected && addr == nil {
+ return 0, 0, errMissingAddress
+ }
+ sa, err := addr.sockaddr(c.fd.family)
+ if err != nil {
+ return 0, 0, err
+ }
+ return c.fd.writeMsg(b, oob, sa)
+}
+
+func (c *UDPConn) writeMsgAddrPort(b, oob []byte, addr netip.AddrPort) (n, oobn int, err error) {
+ if c.fd.isConnected && addr.IsValid() {
+ return 0, 0, ErrWriteToConnected
+ }
+ if !c.fd.isConnected && !addr.IsValid() {
+ return 0, 0, errMissingAddress
+ }
+
+ switch c.fd.family {
+ case syscall.AF_INET:
+ sa, err := addrPortToSockaddrInet4(addr)
+ if err != nil {
+ return 0, 0, err
+ }
+ return c.fd.writeMsgInet4(b, oob, &sa)
+ case syscall.AF_INET6:
+ sa, err := addrPortToSockaddrInet6(addr)
+ if err != nil {
+ return 0, 0, err
+ }
+ return c.fd.writeMsgInet6(b, oob, &sa)
+ default:
+ return 0, 0, &AddrError{Err: "invalid address family", Addr: addr.Addr().String()}
+ }
+}
+
+func (sd *sysDialer) dialUDP(ctx context.Context, laddr, raddr *UDPAddr) (*UDPConn, error) {
+ ctrlCtxFn := sd.Dialer.ControlContext
+ if ctrlCtxFn == nil && sd.Dialer.Control != nil {
+ ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+ return sd.Dialer.Control(network, address, c)
+ }
+ }
+ fd, err := internetSocket(ctx, sd.network, laddr, raddr, syscall.SOCK_DGRAM, 0, "dial", ctrlCtxFn)
+ if err != nil {
+ return nil, err
+ }
+ return newUDPConn(fd), nil
+}
+
+func (sl *sysListener) listenUDP(ctx context.Context, laddr *UDPAddr) (*UDPConn, error) {
+ var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
+ if sl.ListenConfig.Control != nil {
+ ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+ return sl.ListenConfig.Control(network, address, c)
+ }
+ }
+ fd, err := internetSocket(ctx, sl.network, laddr, nil, syscall.SOCK_DGRAM, 0, "listen", ctrlCtxFn)
+ if err != nil {
+ return nil, err
+ }
+ return newUDPConn(fd), nil
+}
+
+func (sl *sysListener) listenMulticastUDP(ctx context.Context, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
+ var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
+ if sl.ListenConfig.Control != nil {
+ ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+ return sl.ListenConfig.Control(network, address, c)
+ }
+ }
+ fd, err := internetSocket(ctx, sl.network, gaddr, nil, syscall.SOCK_DGRAM, 0, "listen", ctrlCtxFn)
+ if err != nil {
+ return nil, err
+ }
+ c := newUDPConn(fd)
+ if ip4 := gaddr.IP.To4(); ip4 != nil {
+ if err := listenIPv4MulticastUDP(c, ifi, ip4); err != nil {
+ c.Close()
+ return nil, err
+ }
+ } else {
+ if err := listenIPv6MulticastUDP(c, ifi, gaddr.IP); err != nil {
+ c.Close()
+ return nil, err
+ }
+ }
+ return c, nil
+}
+
+func listenIPv4MulticastUDP(c *UDPConn, ifi *Interface, ip IP) error {
+ if ifi != nil {
+ if err := setIPv4MulticastInterface(c.fd, ifi); err != nil {
+ return err
+ }
+ }
+ if err := setIPv4MulticastLoopback(c.fd, false); err != nil {
+ return err
+ }
+ if err := joinIPv4Group(c.fd, ifi, ip); err != nil {
+ return err
+ }
+ return nil
+}
+
+func listenIPv6MulticastUDP(c *UDPConn, ifi *Interface, ip IP) error {
+ if ifi != nil {
+ if err := setIPv6MulticastInterface(c.fd, ifi); err != nil {
+ return err
+ }
+ }
+ if err := setIPv6MulticastLoopback(c.fd, false); err != nil {
+ return err
+ }
+ if err := joinIPv6Group(c.fd, ifi, ip); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/net/unixsock.go b/contrib/go/_std_1.21/src/net/unixsock.go
new file mode 100644
index 0000000000..14fbac0932
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/unixsock.go
@@ -0,0 +1,352 @@
+// Copyright 2009 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 net
+
+import (
+ "context"
+ "os"
+ "sync"
+ "syscall"
+ "time"
+)
+
+// BUG(mikio): On JS, WASIP1 and Plan 9, methods and functions related
+// to UnixConn and UnixListener are not implemented.
+
+// BUG(mikio): On Windows, methods and functions related to UnixConn
+// and UnixListener don't work for "unixgram" and "unixpacket".
+
+// UnixAddr represents the address of a Unix domain socket end point.
+type UnixAddr struct {
+ Name string
+ Net string
+}
+
+// Network returns the address's network name, "unix", "unixgram" or
+// "unixpacket".
+func (a *UnixAddr) Network() string {
+ return a.Net
+}
+
+func (a *UnixAddr) String() string {
+ if a == nil {
+ return "<nil>"
+ }
+ return a.Name
+}
+
+func (a *UnixAddr) isWildcard() bool {
+ return a == nil || a.Name == ""
+}
+
+func (a *UnixAddr) opAddr() Addr {
+ if a == nil {
+ return nil
+ }
+ return a
+}
+
+// ResolveUnixAddr returns an address of Unix domain socket end point.
+//
+// The network must be a Unix network name.
+//
+// See func Dial for a description of the network and address
+// parameters.
+func ResolveUnixAddr(network, address string) (*UnixAddr, error) {
+ switch network {
+ case "unix", "unixgram", "unixpacket":
+ return &UnixAddr{Name: address, Net: network}, nil
+ default:
+ return nil, UnknownNetworkError(network)
+ }
+}
+
+// UnixConn is an implementation of the Conn interface for connections
+// to Unix domain sockets.
+type UnixConn struct {
+ conn
+}
+
+// SyscallConn returns a raw network connection.
+// This implements the syscall.Conn interface.
+func (c *UnixConn) SyscallConn() (syscall.RawConn, error) {
+ if !c.ok() {
+ return nil, syscall.EINVAL
+ }
+ return newRawConn(c.fd)
+}
+
+// CloseRead shuts down the reading side of the Unix domain connection.
+// Most callers should just use Close.
+func (c *UnixConn) CloseRead() error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := c.fd.closeRead(); err != nil {
+ return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return nil
+}
+
+// CloseWrite shuts down the writing side of the Unix domain connection.
+// Most callers should just use Close.
+func (c *UnixConn) CloseWrite() error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ if err := c.fd.closeWrite(); err != nil {
+ return &OpError{Op: "close", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return nil
+}
+
+// ReadFromUnix acts like ReadFrom but returns a UnixAddr.
+func (c *UnixConn) ReadFromUnix(b []byte) (int, *UnixAddr, error) {
+ if !c.ok() {
+ return 0, nil, syscall.EINVAL
+ }
+ n, addr, err := c.readFrom(b)
+ if err != nil {
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return n, addr, err
+}
+
+// ReadFrom implements the PacketConn ReadFrom method.
+func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error) {
+ if !c.ok() {
+ return 0, nil, syscall.EINVAL
+ }
+ n, addr, err := c.readFrom(b)
+ if err != nil {
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ if addr == nil {
+ return n, nil, err
+ }
+ return n, addr, err
+}
+
+// ReadMsgUnix reads a message from c, copying the payload into b and
+// the associated out-of-band data into oob. It returns the number of
+// bytes copied into b, the number of bytes copied into oob, the flags
+// that were set on the message and the source address of the message.
+//
+// Note that if len(b) == 0 and len(oob) > 0, this function will still
+// read (and discard) 1 byte from the connection.
+func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
+ if !c.ok() {
+ return 0, 0, 0, nil, syscall.EINVAL
+ }
+ n, oobn, flags, addr, err = c.readMsg(b, oob)
+ if err != nil {
+ err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
+ }
+ return
+}
+
+// WriteToUnix acts like WriteTo but takes a UnixAddr.
+func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (int, error) {
+ if !c.ok() {
+ return 0, syscall.EINVAL
+ }
+ n, err := c.writeTo(b, addr)
+ if err != nil {
+ err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
+ }
+ return n, err
+}
+
+// WriteTo implements the PacketConn WriteTo method.
+func (c *UnixConn) WriteTo(b []byte, addr Addr) (int, error) {
+ if !c.ok() {
+ return 0, syscall.EINVAL
+ }
+ a, ok := addr.(*UnixAddr)
+ if !ok {
+ return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
+ }
+ n, err := c.writeTo(b, a)
+ if err != nil {
+ err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: a.opAddr(), Err: err}
+ }
+ return n, err
+}
+
+// WriteMsgUnix writes a message to addr via c, copying the payload
+// from b and the associated out-of-band data from oob. It returns the
+// number of payload and out-of-band bytes written.
+//
+// Note that if len(b) == 0 and len(oob) > 0, this function will still
+// write 1 byte to the connection.
+func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) {
+ if !c.ok() {
+ return 0, 0, syscall.EINVAL
+ }
+ n, oobn, err = c.writeMsg(b, oob, addr)
+ if err != nil {
+ err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
+ }
+ return
+}
+
+func newUnixConn(fd *netFD) *UnixConn { return &UnixConn{conn{fd}} }
+
+// DialUnix acts like Dial for Unix networks.
+//
+// The network must be a Unix network name; see func Dial for details.
+//
+// If laddr is non-nil, it is used as the local address for the
+// connection.
+func DialUnix(network string, laddr, raddr *UnixAddr) (*UnixConn, error) {
+ switch network {
+ case "unix", "unixgram", "unixpacket":
+ default:
+ return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
+ }
+ sd := &sysDialer{network: network, address: raddr.String()}
+ c, err := sd.dialUnix(context.Background(), laddr, raddr)
+ if err != nil {
+ return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
+ }
+ return c, nil
+}
+
+// UnixListener is a Unix domain socket listener. Clients should
+// typically use variables of type Listener instead of assuming Unix
+// domain sockets.
+type UnixListener struct {
+ fd *netFD
+ path string
+ unlink bool
+ unlinkOnce sync.Once
+}
+
+func (ln *UnixListener) ok() bool { return ln != nil && ln.fd != nil }
+
+// SyscallConn returns a raw network connection.
+// This implements the syscall.Conn interface.
+//
+// The returned RawConn only supports calling Control. Read and
+// Write return an error.
+func (l *UnixListener) SyscallConn() (syscall.RawConn, error) {
+ if !l.ok() {
+ return nil, syscall.EINVAL
+ }
+ return newRawListener(l.fd)
+}
+
+// AcceptUnix accepts the next incoming call and returns the new
+// connection.
+func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
+ if !l.ok() {
+ return nil, syscall.EINVAL
+ }
+ c, err := l.accept()
+ if err != nil {
+ return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+ }
+ return c, nil
+}
+
+// Accept implements the Accept method in the Listener interface.
+// Returned connections will be of type *UnixConn.
+func (l *UnixListener) Accept() (Conn, error) {
+ if !l.ok() {
+ return nil, syscall.EINVAL
+ }
+ c, err := l.accept()
+ if err != nil {
+ return nil, &OpError{Op: "accept", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+ }
+ return c, nil
+}
+
+// Close stops listening on the Unix address. Already accepted
+// connections are not closed.
+func (l *UnixListener) Close() error {
+ if !l.ok() {
+ return syscall.EINVAL
+ }
+ if err := l.close(); err != nil {
+ return &OpError{Op: "close", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+ }
+ return nil
+}
+
+// Addr returns the listener's network address.
+// The Addr returned is shared by all invocations of Addr, so
+// do not modify it.
+func (l *UnixListener) Addr() Addr { return l.fd.laddr }
+
+// SetDeadline sets the deadline associated with the listener.
+// A zero time value disables the deadline.
+func (l *UnixListener) SetDeadline(t time.Time) error {
+ if !l.ok() {
+ return syscall.EINVAL
+ }
+ if err := l.fd.pfd.SetDeadline(t); err != nil {
+ return &OpError{Op: "set", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+ }
+ return nil
+}
+
+// File returns a copy of the underlying os.File.
+// It is the caller's responsibility to close f when finished.
+// Closing l does not affect f, and closing f does not affect l.
+//
+// The returned os.File's file descriptor is different from the
+// connection's. Attempting to change properties of the original
+// using this duplicate may or may not have the desired effect.
+func (l *UnixListener) File() (f *os.File, err error) {
+ if !l.ok() {
+ return nil, syscall.EINVAL
+ }
+ f, err = l.file()
+ if err != nil {
+ err = &OpError{Op: "file", Net: l.fd.net, Source: nil, Addr: l.fd.laddr, Err: err}
+ }
+ return
+}
+
+// ListenUnix acts like Listen for Unix networks.
+//
+// The network must be "unix" or "unixpacket".
+func ListenUnix(network string, laddr *UnixAddr) (*UnixListener, error) {
+ switch network {
+ case "unix", "unixpacket":
+ default:
+ return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
+ }
+ if laddr == nil {
+ return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: errMissingAddress}
+ }
+ sl := &sysListener{network: network, address: laddr.String()}
+ ln, err := sl.listenUnix(context.Background(), laddr)
+ if err != nil {
+ return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
+ }
+ return ln, nil
+}
+
+// ListenUnixgram acts like ListenPacket for Unix networks.
+//
+// The network must be "unixgram".
+func ListenUnixgram(network string, laddr *UnixAddr) (*UnixConn, error) {
+ switch network {
+ case "unixgram":
+ default:
+ return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
+ }
+ if laddr == nil {
+ return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: errMissingAddress}
+ }
+ sl := &sysListener{network: network, address: laddr.String()}
+ c, err := sl.listenUnixgram(context.Background(), laddr)
+ if err != nil {
+ return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
+ }
+ return c, nil
+}
diff --git a/contrib/go/_std_1.21/src/net/unixsock_posix.go b/contrib/go/_std_1.21/src/net/unixsock_posix.go
new file mode 100644
index 0000000000..c501b499ed
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/unixsock_posix.go
@@ -0,0 +1,245 @@
+// Copyright 2009 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package net
+
+import (
+ "context"
+ "errors"
+ "os"
+ "syscall"
+)
+
+func unixSocket(ctx context.Context, net string, laddr, raddr sockaddr, mode string, ctxCtrlFn func(context.Context, string, string, syscall.RawConn) error) (*netFD, error) {
+ var sotype int
+ switch net {
+ case "unix":
+ sotype = syscall.SOCK_STREAM
+ case "unixgram":
+ sotype = syscall.SOCK_DGRAM
+ case "unixpacket":
+ sotype = syscall.SOCK_SEQPACKET
+ default:
+ return nil, UnknownNetworkError(net)
+ }
+
+ switch mode {
+ case "dial":
+ if laddr != nil && laddr.isWildcard() {
+ laddr = nil
+ }
+ if raddr != nil && raddr.isWildcard() {
+ raddr = nil
+ }
+ if raddr == nil && (sotype != syscall.SOCK_DGRAM || laddr == nil) {
+ return nil, errMissingAddress
+ }
+ case "listen":
+ default:
+ return nil, errors.New("unknown mode: " + mode)
+ }
+
+ fd, err := socket(ctx, net, syscall.AF_UNIX, sotype, 0, false, laddr, raddr, ctxCtrlFn)
+ if err != nil {
+ return nil, err
+ }
+ return fd, nil
+}
+
+func sockaddrToUnix(sa syscall.Sockaddr) Addr {
+ if s, ok := sa.(*syscall.SockaddrUnix); ok {
+ return &UnixAddr{Name: s.Name, Net: "unix"}
+ }
+ return nil
+}
+
+func sockaddrToUnixgram(sa syscall.Sockaddr) Addr {
+ if s, ok := sa.(*syscall.SockaddrUnix); ok {
+ return &UnixAddr{Name: s.Name, Net: "unixgram"}
+ }
+ return nil
+}
+
+func sockaddrToUnixpacket(sa syscall.Sockaddr) Addr {
+ if s, ok := sa.(*syscall.SockaddrUnix); ok {
+ return &UnixAddr{Name: s.Name, Net: "unixpacket"}
+ }
+ return nil
+}
+
+func sotypeToNet(sotype int) string {
+ switch sotype {
+ case syscall.SOCK_STREAM:
+ return "unix"
+ case syscall.SOCK_DGRAM:
+ return "unixgram"
+ case syscall.SOCK_SEQPACKET:
+ return "unixpacket"
+ default:
+ panic("sotypeToNet unknown socket type")
+ }
+}
+
+func (a *UnixAddr) family() int {
+ return syscall.AF_UNIX
+}
+
+func (a *UnixAddr) sockaddr(family int) (syscall.Sockaddr, error) {
+ if a == nil {
+ return nil, nil
+ }
+ return &syscall.SockaddrUnix{Name: a.Name}, nil
+}
+
+func (a *UnixAddr) toLocal(net string) sockaddr {
+ return a
+}
+
+func (c *UnixConn) readFrom(b []byte) (int, *UnixAddr, error) {
+ var addr *UnixAddr
+ n, sa, err := c.fd.readFrom(b)
+ switch sa := sa.(type) {
+ case *syscall.SockaddrUnix:
+ if sa.Name != "" {
+ addr = &UnixAddr{Name: sa.Name, Net: sotypeToNet(c.fd.sotype)}
+ }
+ }
+ return n, addr, err
+}
+
+func (c *UnixConn) readMsg(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
+ var sa syscall.Sockaddr
+ n, oobn, flags, sa, err = c.fd.readMsg(b, oob, readMsgFlags)
+ if readMsgFlags == 0 && err == nil && oobn > 0 {
+ setReadMsgCloseOnExec(oob[:oobn])
+ }
+
+ switch sa := sa.(type) {
+ case *syscall.SockaddrUnix:
+ if sa.Name != "" {
+ addr = &UnixAddr{Name: sa.Name, Net: sotypeToNet(c.fd.sotype)}
+ }
+ }
+ return
+}
+
+func (c *UnixConn) writeTo(b []byte, addr *UnixAddr) (int, error) {
+ if c.fd.isConnected {
+ return 0, ErrWriteToConnected
+ }
+ if addr == nil {
+ return 0, errMissingAddress
+ }
+ if addr.Net != sotypeToNet(c.fd.sotype) {
+ return 0, syscall.EAFNOSUPPORT
+ }
+ sa := &syscall.SockaddrUnix{Name: addr.Name}
+ return c.fd.writeTo(b, sa)
+}
+
+func (c *UnixConn) writeMsg(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) {
+ if c.fd.sotype == syscall.SOCK_DGRAM && c.fd.isConnected {
+ return 0, 0, ErrWriteToConnected
+ }
+ var sa syscall.Sockaddr
+ if addr != nil {
+ if addr.Net != sotypeToNet(c.fd.sotype) {
+ return 0, 0, syscall.EAFNOSUPPORT
+ }
+ sa = &syscall.SockaddrUnix{Name: addr.Name}
+ }
+ return c.fd.writeMsg(b, oob, sa)
+}
+
+func (sd *sysDialer) dialUnix(ctx context.Context, laddr, raddr *UnixAddr) (*UnixConn, error) {
+ ctrlCtxFn := sd.Dialer.ControlContext
+ if ctrlCtxFn == nil && sd.Dialer.Control != nil {
+ ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+ return sd.Dialer.Control(network, address, c)
+ }
+ }
+ fd, err := unixSocket(ctx, sd.network, laddr, raddr, "dial", ctrlCtxFn)
+ if err != nil {
+ return nil, err
+ }
+ return newUnixConn(fd), nil
+}
+
+func (ln *UnixListener) accept() (*UnixConn, error) {
+ fd, err := ln.fd.accept()
+ if err != nil {
+ return nil, err
+ }
+ return newUnixConn(fd), nil
+}
+
+func (ln *UnixListener) close() error {
+ // The operating system doesn't clean up
+ // the file that announcing created, so
+ // we have to clean it up ourselves.
+ // There's a race here--we can't know for
+ // sure whether someone else has come along
+ // and replaced our socket name already--
+ // but this sequence (remove then close)
+ // is at least compatible with the auto-remove
+ // sequence in ListenUnix. It's only non-Go
+ // programs that can mess us up.
+ // Even if there are racy calls to Close, we want to unlink only for the first one.
+ ln.unlinkOnce.Do(func() {
+ if ln.path[0] != '@' && ln.unlink {
+ syscall.Unlink(ln.path)
+ }
+ })
+ return ln.fd.Close()
+}
+
+func (ln *UnixListener) file() (*os.File, error) {
+ f, err := ln.fd.dup()
+ if err != nil {
+ return nil, err
+ }
+ return f, nil
+}
+
+// SetUnlinkOnClose sets whether the underlying socket file should be removed
+// from the file system when the listener is closed.
+//
+// The default behavior is to unlink the socket file only when package net created it.
+// That is, when the listener and the underlying socket file were created by a call to
+// Listen or ListenUnix, then by default closing the listener will remove the socket file.
+// but if the listener was created by a call to FileListener to use an already existing
+// socket file, then by default closing the listener will not remove the socket file.
+func (l *UnixListener) SetUnlinkOnClose(unlink bool) {
+ l.unlink = unlink
+}
+
+func (sl *sysListener) listenUnix(ctx context.Context, laddr *UnixAddr) (*UnixListener, error) {
+ var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
+ if sl.ListenConfig.Control != nil {
+ ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+ return sl.ListenConfig.Control(network, address, c)
+ }
+ }
+ fd, err := unixSocket(ctx, sl.network, laddr, nil, "listen", ctrlCtxFn)
+ if err != nil {
+ return nil, err
+ }
+ return &UnixListener{fd: fd, path: fd.laddr.String(), unlink: true}, nil
+}
+
+func (sl *sysListener) listenUnixgram(ctx context.Context, laddr *UnixAddr) (*UnixConn, error) {
+ var ctrlCtxFn func(cxt context.Context, network, address string, c syscall.RawConn) error
+ if sl.ListenConfig.Control != nil {
+ ctrlCtxFn = func(cxt context.Context, network, address string, c syscall.RawConn) error {
+ return sl.ListenConfig.Control(network, address, c)
+ }
+ }
+ fd, err := unixSocket(ctx, sl.network, laddr, nil, "listen", ctrlCtxFn)
+ if err != nil {
+ return nil, err
+ }
+ return newUnixConn(fd), nil
+}
diff --git a/contrib/go/_std_1.20/src/net/unixsock_readmsg_cloexec.go b/contrib/go/_std_1.21/src/net/unixsock_readmsg_cloexec.go
index fa4fd7d933..fa4fd7d933 100644
--- a/contrib/go/_std_1.20/src/net/unixsock_readmsg_cloexec.go
+++ b/contrib/go/_std_1.21/src/net/unixsock_readmsg_cloexec.go
diff --git a/contrib/go/_std_1.20/src/net/unixsock_readmsg_cmsg_cloexec.go b/contrib/go/_std_1.21/src/net/unixsock_readmsg_cmsg_cloexec.go
index 6b0de875ad..6b0de875ad 100644
--- a/contrib/go/_std_1.20/src/net/unixsock_readmsg_cmsg_cloexec.go
+++ b/contrib/go/_std_1.21/src/net/unixsock_readmsg_cmsg_cloexec.go
diff --git a/contrib/go/_std_1.21/src/net/unixsock_readmsg_other.go b/contrib/go/_std_1.21/src/net/unixsock_readmsg_other.go
new file mode 100644
index 0000000000..0899a6d3d3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/unixsock_readmsg_other.go
@@ -0,0 +1,11 @@
+// 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.
+
+//go:build (js && wasm) || wasip1 || windows
+
+package net
+
+const readMsgFlags = 0
+
+func setReadMsgCloseOnExec(oob []byte) {}
diff --git a/contrib/go/_std_1.21/src/net/url/url.go b/contrib/go/_std_1.21/src/net/url/url.go
new file mode 100644
index 0000000000..501b263e87
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/url/url.go
@@ -0,0 +1,1265 @@
+// Copyright 2009 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 url parses URLs and implements query escaping.
+package url
+
+// See RFC 3986. This package generally follows RFC 3986, except where
+// it deviates for compatibility reasons. When sending changes, first
+// search old issues for history on decisions. Unit tests should also
+// contain references to issue numbers with details.
+
+import (
+ "errors"
+ "fmt"
+ "path"
+ "sort"
+ "strconv"
+ "strings"
+)
+
+// Error reports an error and the operation and URL that caused it.
+type Error struct {
+ Op string
+ URL string
+ Err error
+}
+
+func (e *Error) Unwrap() error { return e.Err }
+func (e *Error) Error() string { return fmt.Sprintf("%s %q: %s", e.Op, e.URL, e.Err) }
+
+func (e *Error) Timeout() bool {
+ t, ok := e.Err.(interface {
+ Timeout() bool
+ })
+ return ok && t.Timeout()
+}
+
+func (e *Error) Temporary() bool {
+ t, ok := e.Err.(interface {
+ Temporary() bool
+ })
+ return ok && t.Temporary()
+}
+
+const upperhex = "0123456789ABCDEF"
+
+func ishex(c byte) bool {
+ switch {
+ case '0' <= c && c <= '9':
+ return true
+ case 'a' <= c && c <= 'f':
+ return true
+ case 'A' <= c && c <= 'F':
+ return true
+ }
+ return false
+}
+
+func unhex(c byte) byte {
+ switch {
+ case '0' <= c && c <= '9':
+ return c - '0'
+ case 'a' <= c && c <= 'f':
+ return c - 'a' + 10
+ case 'A' <= c && c <= 'F':
+ return c - 'A' + 10
+ }
+ return 0
+}
+
+type encoding int
+
+const (
+ encodePath encoding = 1 + iota
+ encodePathSegment
+ encodeHost
+ encodeZone
+ encodeUserPassword
+ encodeQueryComponent
+ encodeFragment
+)
+
+type EscapeError string
+
+func (e EscapeError) Error() string {
+ return "invalid URL escape " + strconv.Quote(string(e))
+}
+
+type InvalidHostError string
+
+func (e InvalidHostError) Error() string {
+ return "invalid character " + strconv.Quote(string(e)) + " in host name"
+}
+
+// Return true if the specified character should be escaped when
+// appearing in a URL string, according to RFC 3986.
+//
+// Please be informed that for now shouldEscape does not check all
+// reserved characters correctly. See golang.org/issue/5684.
+func shouldEscape(c byte, mode encoding) bool {
+ // §2.3 Unreserved characters (alphanum)
+ if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {
+ return false
+ }
+
+ if mode == encodeHost || mode == encodeZone {
+ // §3.2.2 Host allows
+ // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
+ // as part of reg-name.
+ // We add : because we include :port as part of host.
+ // We add [ ] because we include [ipv6]:port as part of host.
+ // We add < > because they're the only characters left that
+ // we could possibly allow, and Parse will reject them if we
+ // escape them (because hosts can't use %-encoding for
+ // ASCII bytes).
+ switch c {
+ case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=', ':', '[', ']', '<', '>', '"':
+ return false
+ }
+ }
+
+ switch c {
+ case '-', '_', '.', '~': // §2.3 Unreserved characters (mark)
+ return false
+
+ case '$', '&', '+', ',', '/', ':', ';', '=', '?', '@': // §2.2 Reserved characters (reserved)
+ // Different sections of the URL allow a few of
+ // the reserved characters to appear unescaped.
+ switch mode {
+ case encodePath: // §3.3
+ // The RFC allows : @ & = + $ but saves / ; , for assigning
+ // meaning to individual path segments. This package
+ // only manipulates the path as a whole, so we allow those
+ // last three as well. That leaves only ? to escape.
+ return c == '?'
+
+ case encodePathSegment: // §3.3
+ // The RFC allows : @ & = + $ but saves / ; , for assigning
+ // meaning to individual path segments.
+ return c == '/' || c == ';' || c == ',' || c == '?'
+
+ case encodeUserPassword: // §3.2.1
+ // The RFC allows ';', ':', '&', '=', '+', '$', and ',' in
+ // userinfo, so we must escape only '@', '/', and '?'.
+ // The parsing of userinfo treats ':' as special so we must escape
+ // that too.
+ return c == '@' || c == '/' || c == '?' || c == ':'
+
+ case encodeQueryComponent: // §3.4
+ // The RFC reserves (so we must escape) everything.
+ return true
+
+ case encodeFragment: // §4.1
+ // The RFC text is silent but the grammar allows
+ // everything, so escape nothing.
+ return false
+ }
+ }
+
+ if mode == encodeFragment {
+ // RFC 3986 §2.2 allows not escaping sub-delims. A subset of sub-delims are
+ // included in reserved from RFC 2396 §2.2. The remaining sub-delims do not
+ // need to be escaped. To minimize potential breakage, we apply two restrictions:
+ // (1) we always escape sub-delims outside of the fragment, and (2) we always
+ // escape single quote to avoid breaking callers that had previously assumed that
+ // single quotes would be escaped. See issue #19917.
+ switch c {
+ case '!', '(', ')', '*':
+ return false
+ }
+ }
+
+ // Everything else must be escaped.
+ return true
+}
+
+// QueryUnescape does the inverse transformation of QueryEscape,
+// converting each 3-byte encoded substring of the form "%AB" into the
+// hex-decoded byte 0xAB.
+// It returns an error if any % is not followed by two hexadecimal
+// digits.
+func QueryUnescape(s string) (string, error) {
+ return unescape(s, encodeQueryComponent)
+}
+
+// PathUnescape does the inverse transformation of PathEscape,
+// converting each 3-byte encoded substring of the form "%AB" into the
+// hex-decoded byte 0xAB. It returns an error if any % is not followed
+// by two hexadecimal digits.
+//
+// PathUnescape is identical to QueryUnescape except that it does not
+// unescape '+' to ' ' (space).
+func PathUnescape(s string) (string, error) {
+ return unescape(s, encodePathSegment)
+}
+
+// unescape unescapes a string; the mode specifies
+// which section of the URL string is being unescaped.
+func unescape(s string, mode encoding) (string, error) {
+ // Count %, check that they're well-formed.
+ n := 0
+ hasPlus := false
+ for i := 0; i < len(s); {
+ switch s[i] {
+ case '%':
+ n++
+ if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {
+ s = s[i:]
+ if len(s) > 3 {
+ s = s[:3]
+ }
+ return "", EscapeError(s)
+ }
+ // Per https://tools.ietf.org/html/rfc3986#page-21
+ // in the host component %-encoding can only be used
+ // for non-ASCII bytes.
+ // But https://tools.ietf.org/html/rfc6874#section-2
+ // introduces %25 being allowed to escape a percent sign
+ // in IPv6 scoped-address literals. Yay.
+ if mode == encodeHost && unhex(s[i+1]) < 8 && s[i:i+3] != "%25" {
+ return "", EscapeError(s[i : i+3])
+ }
+ if mode == encodeZone {
+ // RFC 6874 says basically "anything goes" for zone identifiers
+ // and that even non-ASCII can be redundantly escaped,
+ // but it seems prudent to restrict %-escaped bytes here to those
+ // that are valid host name bytes in their unescaped form.
+ // That is, you can use escaping in the zone identifier but not
+ // to introduce bytes you couldn't just write directly.
+ // But Windows puts spaces here! Yay.
+ v := unhex(s[i+1])<<4 | unhex(s[i+2])
+ if s[i:i+3] != "%25" && v != ' ' && shouldEscape(v, encodeHost) {
+ return "", EscapeError(s[i : i+3])
+ }
+ }
+ i += 3
+ case '+':
+ hasPlus = mode == encodeQueryComponent
+ i++
+ default:
+ if (mode == encodeHost || mode == encodeZone) && s[i] < 0x80 && shouldEscape(s[i], mode) {
+ return "", InvalidHostError(s[i : i+1])
+ }
+ i++
+ }
+ }
+
+ if n == 0 && !hasPlus {
+ return s, nil
+ }
+
+ var t strings.Builder
+ t.Grow(len(s) - 2*n)
+ for i := 0; i < len(s); i++ {
+ switch s[i] {
+ case '%':
+ t.WriteByte(unhex(s[i+1])<<4 | unhex(s[i+2]))
+ i += 2
+ case '+':
+ if mode == encodeQueryComponent {
+ t.WriteByte(' ')
+ } else {
+ t.WriteByte('+')
+ }
+ default:
+ t.WriteByte(s[i])
+ }
+ }
+ return t.String(), nil
+}
+
+// QueryEscape escapes the string so it can be safely placed
+// inside a URL query.
+func QueryEscape(s string) string {
+ return escape(s, encodeQueryComponent)
+}
+
+// PathEscape escapes the string so it can be safely placed inside a URL path segment,
+// replacing special characters (including /) with %XX sequences as needed.
+func PathEscape(s string) string {
+ return escape(s, encodePathSegment)
+}
+
+func escape(s string, mode encoding) string {
+ spaceCount, hexCount := 0, 0
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ if shouldEscape(c, mode) {
+ if c == ' ' && mode == encodeQueryComponent {
+ spaceCount++
+ } else {
+ hexCount++
+ }
+ }
+ }
+
+ if spaceCount == 0 && hexCount == 0 {
+ return s
+ }
+
+ var buf [64]byte
+ var t []byte
+
+ required := len(s) + 2*hexCount
+ if required <= len(buf) {
+ t = buf[:required]
+ } else {
+ t = make([]byte, required)
+ }
+
+ if hexCount == 0 {
+ copy(t, s)
+ for i := 0; i < len(s); i++ {
+ if s[i] == ' ' {
+ t[i] = '+'
+ }
+ }
+ return string(t)
+ }
+
+ j := 0
+ for i := 0; i < len(s); i++ {
+ switch c := s[i]; {
+ case c == ' ' && mode == encodeQueryComponent:
+ t[j] = '+'
+ j++
+ case shouldEscape(c, mode):
+ t[j] = '%'
+ t[j+1] = upperhex[c>>4]
+ t[j+2] = upperhex[c&15]
+ j += 3
+ default:
+ t[j] = s[i]
+ j++
+ }
+ }
+ return string(t)
+}
+
+// A URL represents a parsed URL (technically, a URI reference).
+//
+// The general form represented is:
+//
+// [scheme:][//[userinfo@]host][/]path[?query][#fragment]
+//
+// URLs that do not start with a slash after the scheme are interpreted as:
+//
+// scheme:opaque[?query][#fragment]
+//
+// Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.
+// A consequence is that it is impossible to tell which slashes in the Path were
+// slashes in the raw URL and which were %2f. This distinction is rarely important,
+// but when it is, the code should use the EscapedPath method, which preserves
+// the original encoding of Path.
+//
+// The RawPath field is an optional field which is only set when the default
+// encoding of Path is different from the escaped path. See the EscapedPath method
+// for more details.
+//
+// URL's String method uses the EscapedPath method to obtain the path.
+type URL struct {
+ Scheme string
+ Opaque string // encoded opaque data
+ User *Userinfo // username and password information
+ Host string // host or host:port
+ Path string // path (relative paths may omit leading slash)
+ RawPath string // encoded path hint (see EscapedPath method)
+ OmitHost bool // do not emit empty host (authority)
+ ForceQuery bool // append a query ('?') even if RawQuery is empty
+ RawQuery string // encoded query values, without '?'
+ Fragment string // fragment for references, without '#'
+ RawFragment string // encoded fragment hint (see EscapedFragment method)
+}
+
+// User returns a Userinfo containing the provided username
+// and no password set.
+func User(username string) *Userinfo {
+ return &Userinfo{username, "", false}
+}
+
+// UserPassword returns a Userinfo containing the provided username
+// and password.
+//
+// This functionality should only be used with legacy web sites.
+// RFC 2396 warns that interpreting Userinfo this way
+// “is NOT RECOMMENDED, because the passing of authentication
+// information in clear text (such as URI) has proven to be a
+// security risk in almost every case where it has been used.”
+func UserPassword(username, password string) *Userinfo {
+ return &Userinfo{username, password, true}
+}
+
+// The Userinfo type is an immutable encapsulation of username and
+// password details for a URL. An existing Userinfo value is guaranteed
+// to have a username set (potentially empty, as allowed by RFC 2396),
+// and optionally a password.
+type Userinfo struct {
+ username string
+ password string
+ passwordSet bool
+}
+
+// Username returns the username.
+func (u *Userinfo) Username() string {
+ if u == nil {
+ return ""
+ }
+ return u.username
+}
+
+// Password returns the password in case it is set, and whether it is set.
+func (u *Userinfo) Password() (string, bool) {
+ if u == nil {
+ return "", false
+ }
+ return u.password, u.passwordSet
+}
+
+// String returns the encoded userinfo information in the standard form
+// of "username[:password]".
+func (u *Userinfo) String() string {
+ if u == nil {
+ return ""
+ }
+ s := escape(u.username, encodeUserPassword)
+ if u.passwordSet {
+ s += ":" + escape(u.password, encodeUserPassword)
+ }
+ return s
+}
+
+// Maybe rawURL is of the form scheme:path.
+// (Scheme must be [a-zA-Z][a-zA-Z0-9+.-]*)
+// If so, return scheme, path; else return "", rawURL.
+func getScheme(rawURL string) (scheme, path string, err error) {
+ for i := 0; i < len(rawURL); i++ {
+ c := rawURL[i]
+ switch {
+ case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
+ // do nothing
+ case '0' <= c && c <= '9' || c == '+' || c == '-' || c == '.':
+ if i == 0 {
+ return "", rawURL, nil
+ }
+ case c == ':':
+ if i == 0 {
+ return "", "", errors.New("missing protocol scheme")
+ }
+ return rawURL[:i], rawURL[i+1:], nil
+ default:
+ // we have encountered an invalid character,
+ // so there is no valid scheme
+ return "", rawURL, nil
+ }
+ }
+ return "", rawURL, nil
+}
+
+// Parse parses a raw url into a URL structure.
+//
+// The url may be relative (a path, without a host) or absolute
+// (starting with a scheme). Trying to parse a hostname and path
+// without a scheme is invalid but may not necessarily return an
+// error, due to parsing ambiguities.
+func Parse(rawURL string) (*URL, error) {
+ // Cut off #frag
+ u, frag, _ := strings.Cut(rawURL, "#")
+ url, err := parse(u, false)
+ if err != nil {
+ return nil, &Error{"parse", u, err}
+ }
+ if frag == "" {
+ return url, nil
+ }
+ if err = url.setFragment(frag); err != nil {
+ return nil, &Error{"parse", rawURL, err}
+ }
+ return url, nil
+}
+
+// ParseRequestURI parses a raw url into a URL structure. It assumes that
+// url was received in an HTTP request, so the url is interpreted
+// only as an absolute URI or an absolute path.
+// The string url is assumed not to have a #fragment suffix.
+// (Web browsers strip #fragment before sending the URL to a web server.)
+func ParseRequestURI(rawURL string) (*URL, error) {
+ url, err := parse(rawURL, true)
+ if err != nil {
+ return nil, &Error{"parse", rawURL, err}
+ }
+ return url, nil
+}
+
+// parse parses a URL from a string in one of two contexts. If
+// viaRequest is true, the URL is assumed to have arrived via an HTTP request,
+// in which case only absolute URLs or path-absolute relative URLs are allowed.
+// If viaRequest is false, all forms of relative URLs are allowed.
+func parse(rawURL string, viaRequest bool) (*URL, error) {
+ var rest string
+ var err error
+
+ if stringContainsCTLByte(rawURL) {
+ return nil, errors.New("net/url: invalid control character in URL")
+ }
+
+ if rawURL == "" && viaRequest {
+ return nil, errors.New("empty url")
+ }
+ url := new(URL)
+
+ if rawURL == "*" {
+ url.Path = "*"
+ return url, nil
+ }
+
+ // Split off possible leading "http:", "mailto:", etc.
+ // Cannot contain escaped characters.
+ if url.Scheme, rest, err = getScheme(rawURL); err != nil {
+ return nil, err
+ }
+ url.Scheme = strings.ToLower(url.Scheme)
+
+ if strings.HasSuffix(rest, "?") && strings.Count(rest, "?") == 1 {
+ url.ForceQuery = true
+ rest = rest[:len(rest)-1]
+ } else {
+ rest, url.RawQuery, _ = strings.Cut(rest, "?")
+ }
+
+ if !strings.HasPrefix(rest, "/") {
+ if url.Scheme != "" {
+ // We consider rootless paths per RFC 3986 as opaque.
+ url.Opaque = rest
+ return url, nil
+ }
+ if viaRequest {
+ return nil, errors.New("invalid URI for request")
+ }
+
+ // Avoid confusion with malformed schemes, like cache_object:foo/bar.
+ // See golang.org/issue/16822.
+ //
+ // RFC 3986, §3.3:
+ // In addition, a URI reference (Section 4.1) may be a relative-path reference,
+ // in which case the first path segment cannot contain a colon (":") character.
+ if segment, _, _ := strings.Cut(rest, "/"); strings.Contains(segment, ":") {
+ // First path segment has colon. Not allowed in relative URL.
+ return nil, errors.New("first path segment in URL cannot contain colon")
+ }
+ }
+
+ if (url.Scheme != "" || !viaRequest && !strings.HasPrefix(rest, "///")) && strings.HasPrefix(rest, "//") {
+ var authority string
+ authority, rest = rest[2:], ""
+ if i := strings.Index(authority, "/"); i >= 0 {
+ authority, rest = authority[:i], authority[i:]
+ }
+ url.User, url.Host, err = parseAuthority(authority)
+ if err != nil {
+ return nil, err
+ }
+ } else if url.Scheme != "" && strings.HasPrefix(rest, "/") {
+ // OmitHost is set to true when rawURL has an empty host (authority).
+ // See golang.org/issue/46059.
+ url.OmitHost = true
+ }
+
+ // Set Path and, optionally, RawPath.
+ // RawPath is a hint of the encoding of Path. We don't want to set it if
+ // the default escaping of Path is equivalent, to help make sure that people
+ // don't rely on it in general.
+ if err := url.setPath(rest); err != nil {
+ return nil, err
+ }
+ return url, nil
+}
+
+func parseAuthority(authority string) (user *Userinfo, host string, err error) {
+ i := strings.LastIndex(authority, "@")
+ if i < 0 {
+ host, err = parseHost(authority)
+ } else {
+ host, err = parseHost(authority[i+1:])
+ }
+ if err != nil {
+ return nil, "", err
+ }
+ if i < 0 {
+ return nil, host, nil
+ }
+ userinfo := authority[:i]
+ if !validUserinfo(userinfo) {
+ return nil, "", errors.New("net/url: invalid userinfo")
+ }
+ if !strings.Contains(userinfo, ":") {
+ if userinfo, err = unescape(userinfo, encodeUserPassword); err != nil {
+ return nil, "", err
+ }
+ user = User(userinfo)
+ } else {
+ username, password, _ := strings.Cut(userinfo, ":")
+ if username, err = unescape(username, encodeUserPassword); err != nil {
+ return nil, "", err
+ }
+ if password, err = unescape(password, encodeUserPassword); err != nil {
+ return nil, "", err
+ }
+ user = UserPassword(username, password)
+ }
+ return user, host, nil
+}
+
+// parseHost parses host as an authority without user
+// information. That is, as host[:port].
+func parseHost(host string) (string, error) {
+ if strings.HasPrefix(host, "[") {
+ // Parse an IP-Literal in RFC 3986 and RFC 6874.
+ // E.g., "[fe80::1]", "[fe80::1%25en0]", "[fe80::1]:80".
+ i := strings.LastIndex(host, "]")
+ if i < 0 {
+ return "", errors.New("missing ']' in host")
+ }
+ colonPort := host[i+1:]
+ if !validOptionalPort(colonPort) {
+ return "", fmt.Errorf("invalid port %q after host", colonPort)
+ }
+
+ // RFC 6874 defines that %25 (%-encoded percent) introduces
+ // the zone identifier, and the zone identifier can use basically
+ // any %-encoding it likes. That's different from the host, which
+ // can only %-encode non-ASCII bytes.
+ // We do impose some restrictions on the zone, to avoid stupidity
+ // like newlines.
+ zone := strings.Index(host[:i], "%25")
+ if zone >= 0 {
+ host1, err := unescape(host[:zone], encodeHost)
+ if err != nil {
+ return "", err
+ }
+ host2, err := unescape(host[zone:i], encodeZone)
+ if err != nil {
+ return "", err
+ }
+ host3, err := unescape(host[i:], encodeHost)
+ if err != nil {
+ return "", err
+ }
+ return host1 + host2 + host3, nil
+ }
+ } else if i := strings.LastIndex(host, ":"); i != -1 {
+ colonPort := host[i:]
+ if !validOptionalPort(colonPort) {
+ return "", fmt.Errorf("invalid port %q after host", colonPort)
+ }
+ }
+
+ var err error
+ if host, err = unescape(host, encodeHost); err != nil {
+ return "", err
+ }
+ return host, nil
+}
+
+// setPath sets the Path and RawPath fields of the URL based on the provided
+// escaped path p. It maintains the invariant that RawPath is only specified
+// when it differs from the default encoding of the path.
+// For example:
+// - setPath("/foo/bar") will set Path="/foo/bar" and RawPath=""
+// - setPath("/foo%2fbar") will set Path="/foo/bar" and RawPath="/foo%2fbar"
+// setPath will return an error only if the provided path contains an invalid
+// escaping.
+func (u *URL) setPath(p string) error {
+ path, err := unescape(p, encodePath)
+ if err != nil {
+ return err
+ }
+ u.Path = path
+ if escp := escape(path, encodePath); p == escp {
+ // Default encoding is fine.
+ u.RawPath = ""
+ } else {
+ u.RawPath = p
+ }
+ return nil
+}
+
+// EscapedPath returns the escaped form of u.Path.
+// In general there are multiple possible escaped forms of any path.
+// EscapedPath returns u.RawPath when it is a valid escaping of u.Path.
+// Otherwise EscapedPath ignores u.RawPath and computes an escaped
+// form on its own.
+// The String and RequestURI methods use EscapedPath to construct
+// their results.
+// In general, code should call EscapedPath instead of
+// reading u.RawPath directly.
+func (u *URL) EscapedPath() string {
+ if u.RawPath != "" && validEncoded(u.RawPath, encodePath) {
+ p, err := unescape(u.RawPath, encodePath)
+ if err == nil && p == u.Path {
+ return u.RawPath
+ }
+ }
+ if u.Path == "*" {
+ return "*" // don't escape (Issue 11202)
+ }
+ return escape(u.Path, encodePath)
+}
+
+// validEncoded reports whether s is a valid encoded path or fragment,
+// according to mode.
+// It must not contain any bytes that require escaping during encoding.
+func validEncoded(s string, mode encoding) bool {
+ for i := 0; i < len(s); i++ {
+ // RFC 3986, Appendix A.
+ // pchar = unreserved / pct-encoded / sub-delims / ":" / "@".
+ // shouldEscape is not quite compliant with the RFC,
+ // so we check the sub-delims ourselves and let
+ // shouldEscape handle the others.
+ switch s[i] {
+ case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=', ':', '@':
+ // ok
+ case '[', ']':
+ // ok - not specified in RFC 3986 but left alone by modern browsers
+ case '%':
+ // ok - percent encoded, will decode
+ default:
+ if shouldEscape(s[i], mode) {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+// setFragment is like setPath but for Fragment/RawFragment.
+func (u *URL) setFragment(f string) error {
+ frag, err := unescape(f, encodeFragment)
+ if err != nil {
+ return err
+ }
+ u.Fragment = frag
+ if escf := escape(frag, encodeFragment); f == escf {
+ // Default encoding is fine.
+ u.RawFragment = ""
+ } else {
+ u.RawFragment = f
+ }
+ return nil
+}
+
+// EscapedFragment returns the escaped form of u.Fragment.
+// In general there are multiple possible escaped forms of any fragment.
+// EscapedFragment returns u.RawFragment when it is a valid escaping of u.Fragment.
+// Otherwise EscapedFragment ignores u.RawFragment and computes an escaped
+// form on its own.
+// The String method uses EscapedFragment to construct its result.
+// In general, code should call EscapedFragment instead of
+// reading u.RawFragment directly.
+func (u *URL) EscapedFragment() string {
+ if u.RawFragment != "" && validEncoded(u.RawFragment, encodeFragment) {
+ f, err := unescape(u.RawFragment, encodeFragment)
+ if err == nil && f == u.Fragment {
+ return u.RawFragment
+ }
+ }
+ return escape(u.Fragment, encodeFragment)
+}
+
+// validOptionalPort reports whether port is either an empty string
+// or matches /^:\d*$/
+func validOptionalPort(port string) bool {
+ if port == "" {
+ return true
+ }
+ if port[0] != ':' {
+ return false
+ }
+ for _, b := range port[1:] {
+ if b < '0' || b > '9' {
+ return false
+ }
+ }
+ return true
+}
+
+// String reassembles the URL into a valid URL string.
+// The general form of the result is one of:
+//
+// scheme:opaque?query#fragment
+// scheme://userinfo@host/path?query#fragment
+//
+// If u.Opaque is non-empty, String uses the first form;
+// otherwise it uses the second form.
+// Any non-ASCII characters in host are escaped.
+// To obtain the path, String uses u.EscapedPath().
+//
+// In the second form, the following rules apply:
+// - if u.Scheme is empty, scheme: is omitted.
+// - if u.User is nil, userinfo@ is omitted.
+// - if u.Host is empty, host/ is omitted.
+// - if u.Scheme and u.Host are empty and u.User is nil,
+// the entire scheme://userinfo@host/ is omitted.
+// - if u.Host is non-empty and u.Path begins with a /,
+// the form host/path does not add its own /.
+// - if u.RawQuery is empty, ?query is omitted.
+// - if u.Fragment is empty, #fragment is omitted.
+func (u *URL) String() string {
+ var buf strings.Builder
+ if u.Scheme != "" {
+ buf.WriteString(u.Scheme)
+ buf.WriteByte(':')
+ }
+ if u.Opaque != "" {
+ buf.WriteString(u.Opaque)
+ } else {
+ if u.Scheme != "" || u.Host != "" || u.User != nil {
+ if u.OmitHost && u.Host == "" && u.User == nil {
+ // omit empty host
+ } else {
+ if u.Host != "" || u.Path != "" || u.User != nil {
+ buf.WriteString("//")
+ }
+ if ui := u.User; ui != nil {
+ buf.WriteString(ui.String())
+ buf.WriteByte('@')
+ }
+ if h := u.Host; h != "" {
+ buf.WriteString(escape(h, encodeHost))
+ }
+ }
+ }
+ path := u.EscapedPath()
+ if path != "" && path[0] != '/' && u.Host != "" {
+ buf.WriteByte('/')
+ }
+ if buf.Len() == 0 {
+ // RFC 3986 §4.2
+ // A path segment that contains a colon character (e.g., "this:that")
+ // cannot be used as the first segment of a relative-path reference, as
+ // it would be mistaken for a scheme name. Such a segment must be
+ // preceded by a dot-segment (e.g., "./this:that") to make a relative-
+ // path reference.
+ if segment, _, _ := strings.Cut(path, "/"); strings.Contains(segment, ":") {
+ buf.WriteString("./")
+ }
+ }
+ buf.WriteString(path)
+ }
+ if u.ForceQuery || u.RawQuery != "" {
+ buf.WriteByte('?')
+ buf.WriteString(u.RawQuery)
+ }
+ if u.Fragment != "" {
+ buf.WriteByte('#')
+ buf.WriteString(u.EscapedFragment())
+ }
+ return buf.String()
+}
+
+// Redacted is like String but replaces any password with "xxxxx".
+// Only the password in u.User is redacted.
+func (u *URL) Redacted() string {
+ if u == nil {
+ return ""
+ }
+
+ ru := *u
+ if _, has := ru.User.Password(); has {
+ ru.User = UserPassword(ru.User.Username(), "xxxxx")
+ }
+ return ru.String()
+}
+
+// Values maps a string key to a list of values.
+// It is typically used for query parameters and form values.
+// Unlike in the http.Header map, the keys in a Values map
+// are case-sensitive.
+type Values map[string][]string
+
+// Get gets the first value associated with the given key.
+// If there are no values associated with the key, Get returns
+// the empty string. To access multiple values, use the map
+// directly.
+func (v Values) Get(key string) string {
+ vs := v[key]
+ if len(vs) == 0 {
+ return ""
+ }
+ return vs[0]
+}
+
+// Set sets the key to value. It replaces any existing
+// values.
+func (v Values) Set(key, value string) {
+ v[key] = []string{value}
+}
+
+// Add adds the value to key. It appends to any existing
+// values associated with key.
+func (v Values) Add(key, value string) {
+ v[key] = append(v[key], value)
+}
+
+// Del deletes the values associated with key.
+func (v Values) Del(key string) {
+ delete(v, key)
+}
+
+// Has checks whether a given key is set.
+func (v Values) Has(key string) bool {
+ _, ok := v[key]
+ return ok
+}
+
+// ParseQuery parses the URL-encoded query string and returns
+// a map listing the values specified for each key.
+// ParseQuery always returns a non-nil map containing all the
+// valid query parameters found; err describes the first decoding error
+// encountered, if any.
+//
+// Query is expected to be a list of key=value settings separated by ampersands.
+// A setting without an equals sign is interpreted as a key set to an empty
+// value.
+// Settings containing a non-URL-encoded semicolon are considered invalid.
+func ParseQuery(query string) (Values, error) {
+ m := make(Values)
+ err := parseQuery(m, query)
+ return m, err
+}
+
+func parseQuery(m Values, query string) (err error) {
+ for query != "" {
+ var key string
+ key, query, _ = strings.Cut(query, "&")
+ if strings.Contains(key, ";") {
+ err = fmt.Errorf("invalid semicolon separator in query")
+ continue
+ }
+ if key == "" {
+ continue
+ }
+ key, value, _ := strings.Cut(key, "=")
+ key, err1 := QueryUnescape(key)
+ if err1 != nil {
+ if err == nil {
+ err = err1
+ }
+ continue
+ }
+ value, err1 = QueryUnescape(value)
+ if err1 != nil {
+ if err == nil {
+ err = err1
+ }
+ continue
+ }
+ m[key] = append(m[key], value)
+ }
+ return err
+}
+
+// Encode encodes the values into “URL encoded” form
+// ("bar=baz&foo=quux") sorted by key.
+func (v Values) Encode() string {
+ if v == nil {
+ return ""
+ }
+ var buf strings.Builder
+ keys := make([]string, 0, len(v))
+ for k := range v {
+ keys = append(keys, k)
+ }
+ sort.Strings(keys)
+ for _, k := range keys {
+ vs := v[k]
+ keyEscaped := QueryEscape(k)
+ for _, v := range vs {
+ if buf.Len() > 0 {
+ buf.WriteByte('&')
+ }
+ buf.WriteString(keyEscaped)
+ buf.WriteByte('=')
+ buf.WriteString(QueryEscape(v))
+ }
+ }
+ return buf.String()
+}
+
+// resolvePath applies special path segments from refs and applies
+// them to base, per RFC 3986.
+func resolvePath(base, ref string) string {
+ var full string
+ if ref == "" {
+ full = base
+ } else if ref[0] != '/' {
+ i := strings.LastIndex(base, "/")
+ full = base[:i+1] + ref
+ } else {
+ full = ref
+ }
+ if full == "" {
+ return ""
+ }
+
+ var (
+ elem string
+ dst strings.Builder
+ )
+ first := true
+ remaining := full
+ // We want to return a leading '/', so write it now.
+ dst.WriteByte('/')
+ found := true
+ for found {
+ elem, remaining, found = strings.Cut(remaining, "/")
+ if elem == "." {
+ first = false
+ // drop
+ continue
+ }
+
+ if elem == ".." {
+ // Ignore the leading '/' we already wrote.
+ str := dst.String()[1:]
+ index := strings.LastIndexByte(str, '/')
+
+ dst.Reset()
+ dst.WriteByte('/')
+ if index == -1 {
+ first = true
+ } else {
+ dst.WriteString(str[:index])
+ }
+ } else {
+ if !first {
+ dst.WriteByte('/')
+ }
+ dst.WriteString(elem)
+ first = false
+ }
+ }
+
+ if elem == "." || elem == ".." {
+ dst.WriteByte('/')
+ }
+
+ // We wrote an initial '/', but we don't want two.
+ r := dst.String()
+ if len(r) > 1 && r[1] == '/' {
+ r = r[1:]
+ }
+ return r
+}
+
+// IsAbs reports whether the URL is absolute.
+// Absolute means that it has a non-empty scheme.
+func (u *URL) IsAbs() bool {
+ return u.Scheme != ""
+}
+
+// Parse parses a URL in the context of the receiver. The provided URL
+// may be relative or absolute. Parse returns nil, err on parse
+// failure, otherwise its return value is the same as ResolveReference.
+func (u *URL) Parse(ref string) (*URL, error) {
+ refURL, err := Parse(ref)
+ if err != nil {
+ return nil, err
+ }
+ return u.ResolveReference(refURL), nil
+}
+
+// ResolveReference resolves a URI reference to an absolute URI from
+// an absolute base URI u, per RFC 3986 Section 5.2. The URI reference
+// may be relative or absolute. ResolveReference always returns a new
+// URL instance, even if the returned URL is identical to either the
+// base or reference. If ref is an absolute URL, then ResolveReference
+// ignores base and returns a copy of ref.
+func (u *URL) ResolveReference(ref *URL) *URL {
+ url := *ref
+ if ref.Scheme == "" {
+ url.Scheme = u.Scheme
+ }
+ if ref.Scheme != "" || ref.Host != "" || ref.User != nil {
+ // The "absoluteURI" or "net_path" cases.
+ // We can ignore the error from setPath since we know we provided a
+ // validly-escaped path.
+ url.setPath(resolvePath(ref.EscapedPath(), ""))
+ return &url
+ }
+ if ref.Opaque != "" {
+ url.User = nil
+ url.Host = ""
+ url.Path = ""
+ return &url
+ }
+ if ref.Path == "" && !ref.ForceQuery && ref.RawQuery == "" {
+ url.RawQuery = u.RawQuery
+ if ref.Fragment == "" {
+ url.Fragment = u.Fragment
+ url.RawFragment = u.RawFragment
+ }
+ }
+ // The "abs_path" or "rel_path" cases.
+ url.Host = u.Host
+ url.User = u.User
+ url.setPath(resolvePath(u.EscapedPath(), ref.EscapedPath()))
+ return &url
+}
+
+// Query parses RawQuery and returns the corresponding values.
+// It silently discards malformed value pairs.
+// To check errors use ParseQuery.
+func (u *URL) Query() Values {
+ v, _ := ParseQuery(u.RawQuery)
+ return v
+}
+
+// RequestURI returns the encoded path?query or opaque?query
+// string that would be used in an HTTP request for u.
+func (u *URL) RequestURI() string {
+ result := u.Opaque
+ if result == "" {
+ result = u.EscapedPath()
+ if result == "" {
+ result = "/"
+ }
+ } else {
+ if strings.HasPrefix(result, "//") {
+ result = u.Scheme + ":" + result
+ }
+ }
+ if u.ForceQuery || u.RawQuery != "" {
+ result += "?" + u.RawQuery
+ }
+ return result
+}
+
+// Hostname returns u.Host, stripping any valid port number if present.
+//
+// If the result is enclosed in square brackets, as literal IPv6 addresses are,
+// the square brackets are removed from the result.
+func (u *URL) Hostname() string {
+ host, _ := splitHostPort(u.Host)
+ return host
+}
+
+// Port returns the port part of u.Host, without the leading colon.
+//
+// If u.Host doesn't contain a valid numeric port, Port returns an empty string.
+func (u *URL) Port() string {
+ _, port := splitHostPort(u.Host)
+ return port
+}
+
+// splitHostPort separates host and port. If the port is not valid, it returns
+// the entire input as host, and it doesn't check the validity of the host.
+// Unlike net.SplitHostPort, but per RFC 3986, it requires ports to be numeric.
+func splitHostPort(hostPort string) (host, port string) {
+ host = hostPort
+
+ colon := strings.LastIndexByte(host, ':')
+ if colon != -1 && validOptionalPort(host[colon:]) {
+ host, port = host[:colon], host[colon+1:]
+ }
+
+ if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
+ host = host[1 : len(host)-1]
+ }
+
+ return
+}
+
+// Marshaling interface implementations.
+// Would like to implement MarshalText/UnmarshalText but that will change the JSON representation of URLs.
+
+func (u *URL) MarshalBinary() (text []byte, err error) {
+ return []byte(u.String()), nil
+}
+
+func (u *URL) UnmarshalBinary(text []byte) error {
+ u1, err := Parse(string(text))
+ if err != nil {
+ return err
+ }
+ *u = *u1
+ return nil
+}
+
+// JoinPath returns a new URL with the provided path elements joined to
+// any existing path and the resulting path cleaned of any ./ or ../ elements.
+// Any sequences of multiple / characters will be reduced to a single /.
+func (u *URL) JoinPath(elem ...string) *URL {
+ elem = append([]string{u.EscapedPath()}, elem...)
+ var p string
+ if !strings.HasPrefix(elem[0], "/") {
+ // Return a relative path if u is relative,
+ // but ensure that it contains no ../ elements.
+ elem[0] = "/" + elem[0]
+ p = path.Join(elem...)[1:]
+ } else {
+ p = path.Join(elem...)
+ }
+ // path.Join will remove any trailing slashes.
+ // Preserve at least one.
+ if strings.HasSuffix(elem[len(elem)-1], "/") && !strings.HasSuffix(p, "/") {
+ p += "/"
+ }
+ url := *u
+ url.setPath(p)
+ return &url
+}
+
+// validUserinfo reports whether s is a valid userinfo string per RFC 3986
+// Section 3.2.1:
+//
+// userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
+// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
+// sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
+// / "*" / "+" / "," / ";" / "="
+//
+// It doesn't validate pct-encoded. The caller does that via func unescape.
+func validUserinfo(s string) bool {
+ for _, r := range s {
+ if 'A' <= r && r <= 'Z' {
+ continue
+ }
+ if 'a' <= r && r <= 'z' {
+ continue
+ }
+ if '0' <= r && r <= '9' {
+ continue
+ }
+ switch r {
+ case '-', '.', '_', ':', '~', '!', '$', '&', '\'',
+ '(', ')', '*', '+', ',', ';', '=', '%', '@':
+ continue
+ default:
+ return false
+ }
+ }
+ return true
+}
+
+// stringContainsCTLByte reports whether s contains any ASCII control character.
+func stringContainsCTLByte(s string) bool {
+ for i := 0; i < len(s); i++ {
+ b := s[i]
+ if b < ' ' || b == 0x7f {
+ return true
+ }
+ }
+ return false
+}
+
+// JoinPath returns a URL string with the provided path elements joined to
+// the existing path of base and the resulting path cleaned of any ./ or ../ elements.
+func JoinPath(base string, elem ...string) (result string, err error) {
+ url, err := Parse(base)
+ if err != nil {
+ return
+ }
+ result = url.JoinPath(elem...).String()
+ return
+}
diff --git a/contrib/go/_std_1.21/src/net/url/ya.make b/contrib/go/_std_1.21/src/net/url/ya.make
new file mode 100644
index 0000000000..d7c5027033
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/url/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ url.go
+)
+
+GO_TEST_SRCS(url_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/net/writev_unix.go b/contrib/go/_std_1.21/src/net/writev_unix.go
index 3b0325bf64..3b0325bf64 100644
--- a/contrib/go/_std_1.20/src/net/writev_unix.go
+++ b/contrib/go/_std_1.21/src/net/writev_unix.go
diff --git a/contrib/go/_std_1.21/src/net/ya.make b/contrib/go/_std_1.21/src/net/ya.make
new file mode 100644
index 0000000000..bee559f144
--- /dev/null
+++ b/contrib/go/_std_1.21/src/net/ya.make
@@ -0,0 +1,254 @@
+GO_LIBRARY()
+
+NO_COMPILER_WARNINGS()
+
+IF (CGO_ENABLED)
+ IF (OS_LINUX)
+ CGO_LDFLAGS(-lresolv)
+ ENDIF()
+ENDIF()
+
+SRCS(
+ addrselect.go
+ conf.go
+ dial.go
+ dnsclient.go
+ dnsclient_unix.go
+ dnsconfig.go
+ error_posix.go
+ fd_posix.go
+ file.go
+ hook.go
+ hosts.go
+ interface.go
+ ip.go
+ iprawsock.go
+ iprawsock_posix.go
+ ipsock.go
+ ipsock_posix.go
+ lookup.go
+ mac.go
+ net.go
+ netcgo_off.go
+ netgo_off.go
+ nss.go
+ parse.go
+ pipe.go
+ port.go
+ rawconn.go
+ sock_posix.go
+ sockaddr_posix.go
+ sockopt_posix.go
+ sockoptip_posix.go
+ tcpsock.go
+ tcpsock_posix.go
+ tcpsockopt_posix.go
+ udpsock.go
+ udpsock_posix.go
+ unixsock.go
+ unixsock_posix.go
+)
+
+GO_TEST_SRCS(
+ conn_test.go
+ dial_test.go
+ dnsclient_test.go
+ dnsname_test.go
+ error_posix_test.go
+ error_test.go
+ external_test.go
+ file_test.go
+ hosts_test.go
+ interface_test.go
+ ip_test.go
+ iprawsock_test.go
+ ipsock_test.go
+ listen_test.go
+ lookup_test.go
+ mac_test.go
+ main_conf_test.go
+ main_posix_test.go
+ main_test.go
+ mockserver_test.go
+ net_test.go
+ packetconn_test.go
+ parse_test.go
+ platform_test.go
+ port_test.go
+ protoconn_test.go
+ rawconn_test.go
+ resolverdialfunc_test.go
+ sendfile_test.go
+ server_test.go
+ tcpsock_test.go
+ timeout_test.go
+ udpsock_test.go
+ writev_test.go
+)
+
+GO_XTEST_SRCS(
+ example_test.go
+ pipe_test.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ dnsconfig_unix.go
+ error_unix.go
+ fd_unix.go
+ file_unix.go
+ hook_unix.go
+ interface_linux.go
+ lookup_unix.go
+ mptcpsock_linux.go
+ port_unix.go
+ sendfile_linux.go
+ sock_cloexec.go
+ sock_linux.go
+ sockopt_linux.go
+ sockoptip_linux.go
+ splice_linux.go
+ tcpsockopt_unix.go
+ unixsock_readmsg_cmsg_cloexec.go
+ writev_unix.go
+ )
+
+ GO_TEST_SRCS(
+ addrselect_test.go
+ cgo_unix_test.go
+ conf_test.go
+ dial_unix_test.go
+ dnsclient_unix_test.go
+ dnsconfig_unix_test.go
+ error_unix_test.go
+ file_unix_test.go
+ interface_linux_test.go
+ interface_unix_test.go
+ main_cloexec_test.go
+ main_unix_test.go
+ mptcpsock_linux_test.go
+ nss_test.go
+ rawconn_unix_test.go
+ sendfile_linux_test.go
+ sock_linux_test.go
+ splice_test.go
+ tcpsock_unix_test.go
+ unixsock_linux_test.go
+ unixsock_readmsg_test.go
+ unixsock_test.go
+ write_unix_test.go
+ )
+ENDIF()
+
+IF (OS_LINUX AND CGO_ENABLED)
+ SRCS(
+ cgo_unix.go
+ )
+
+ CGO_SRCS(
+ cgo_linux.go
+ cgo_resnew.go
+ cgo_socknew.go
+ cgo_unix_cgo.go
+ cgo_unix_cgo_res.go
+ )
+ELSE()
+ IF(OS_LINUX)
+ SRCS(
+ cgo_stub.go
+ )
+ ENDIF()
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ cgo_darwin.go
+ cgo_unix.go
+ cgo_unix_syscall.go
+ dnsconfig_unix.go
+ error_unix.go
+ fd_unix.go
+ file_unix.go
+ hook_unix.go
+ interface_bsd.go
+ interface_darwin.go
+ lookup_unix.go
+ mptcpsock_stub.go
+ port_unix.go
+ sendfile_unix_alt.go
+ sock_bsd.go
+ sockopt_bsd.go
+ sockoptip_bsdvar.go
+ splice_stub.go
+ sys_cloexec.go
+ tcpsockopt_darwin.go
+ unixsock_readmsg_cloexec.go
+ writev_unix.go
+ )
+
+ GO_TEST_SRCS(
+ addrselect_test.go
+ cgo_unix_test.go
+ conf_test.go
+ dial_unix_test.go
+ dnsclient_unix_test.go
+ dnsconfig_unix_test.go
+ error_unix_test.go
+ file_unix_test.go
+ interface_bsd_test.go
+ interface_unix_test.go
+ main_unix_test.go
+ nss_test.go
+ rawconn_unix_test.go
+ tcpsock_unix_test.go
+ unixsock_readmsg_test.go
+ unixsock_test.go
+ write_unix_test.go
+ )
+ENDIF()
+
+IF (OS_DARWIN AND CGO_ENABLED)
+ CGO_SRCS(cgo_unix_cgo_darwin.go)
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ dnsconfig_windows.go
+ error_windows.go
+ fd_windows.go
+ file_windows.go
+ hook_windows.go
+ interface_windows.go
+ lookup_windows.go
+ mptcpsock_stub.go
+ sendfile_windows.go
+ sock_windows.go
+ sockopt_windows.go
+ sockoptip_windows.go
+ splice_stub.go
+ tcpsockopt_windows.go
+ unixsock_readmsg_other.go
+ )
+
+ GO_TEST_SRCS(
+ error_windows_test.go
+ lookup_windows_test.go
+ main_windows_test.go
+ net_windows_test.go
+ rawconn_windows_test.go
+ unixsock_windows_test.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+ http
+ internal
+ mail
+ netip
+ rpc
+ smtp
+ textproto
+ url
+)
diff --git a/contrib/go/_std_1.20/src/os/dir.go b/contrib/go/_std_1.21/src/os/dir.go
index 5306bcb3ba..5306bcb3ba 100644
--- a/contrib/go/_std_1.20/src/os/dir.go
+++ b/contrib/go/_std_1.21/src/os/dir.go
diff --git a/contrib/go/_std_1.21/src/os/dir_darwin.go b/contrib/go/_std_1.21/src/os/dir_darwin.go
new file mode 100644
index 0000000000..e6d5bda24b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/dir_darwin.go
@@ -0,0 +1,140 @@
+// Copyright 2009 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 os
+
+import (
+ "io"
+ "runtime"
+ "syscall"
+ "unsafe"
+)
+
+// Auxiliary information if the File describes a directory
+type dirInfo struct {
+ dir uintptr // Pointer to DIR structure from dirent.h
+}
+
+func (d *dirInfo) close() {
+ if d.dir == 0 {
+ return
+ }
+ closedir(d.dir)
+ d.dir = 0
+}
+
+func (f *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEntry, infos []FileInfo, err error) {
+ if f.dirinfo == nil {
+ dir, call, errno := f.pfd.OpenDir()
+ if errno != nil {
+ return nil, nil, nil, &PathError{Op: call, Path: f.name, Err: errno}
+ }
+ f.dirinfo = &dirInfo{
+ dir: dir,
+ }
+ }
+ d := f.dirinfo
+
+ size := n
+ if size <= 0 {
+ size = 100
+ n = -1
+ }
+
+ var dirent syscall.Dirent
+ var entptr *syscall.Dirent
+ for len(names)+len(dirents)+len(infos) < size || n == -1 {
+ if errno := readdir_r(d.dir, &dirent, &entptr); errno != 0 {
+ if errno == syscall.EINTR {
+ continue
+ }
+ return names, dirents, infos, &PathError{Op: "readdir", Path: f.name, Err: errno}
+ }
+ if entptr == nil { // EOF
+ break
+ }
+ // Darwin may return a zero inode when a directory entry has been
+ // deleted but not yet removed from the directory. The man page for
+ // getdirentries(2) states that programs are responsible for skipping
+ // those entries:
+ //
+ // Users of getdirentries() should skip entries with d_fileno = 0,
+ // as such entries represent files which have been deleted but not
+ // yet removed from the directory entry.
+ //
+ if dirent.Ino == 0 {
+ continue
+ }
+ name := (*[len(syscall.Dirent{}.Name)]byte)(unsafe.Pointer(&dirent.Name))[:]
+ for i, c := range name {
+ if c == 0 {
+ name = name[:i]
+ break
+ }
+ }
+ // Check for useless names before allocating a string.
+ if string(name) == "." || string(name) == ".." {
+ continue
+ }
+ if mode == readdirName {
+ names = append(names, string(name))
+ } else if mode == readdirDirEntry {
+ de, err := newUnixDirent(f.name, string(name), dtToType(dirent.Type))
+ if IsNotExist(err) {
+ // File disappeared between readdir and stat.
+ // Treat as if it didn't exist.
+ continue
+ }
+ if err != nil {
+ return nil, dirents, nil, err
+ }
+ dirents = append(dirents, de)
+ } else {
+ info, err := lstat(f.name + "/" + string(name))
+ if IsNotExist(err) {
+ // File disappeared between readdir + stat.
+ // Treat as if it didn't exist.
+ continue
+ }
+ if err != nil {
+ return nil, nil, infos, err
+ }
+ infos = append(infos, info)
+ }
+ runtime.KeepAlive(f)
+ }
+
+ if n > 0 && len(names)+len(dirents)+len(infos) == 0 {
+ return nil, nil, nil, io.EOF
+ }
+ return names, dirents, infos, nil
+}
+
+func dtToType(typ uint8) FileMode {
+ switch typ {
+ case syscall.DT_BLK:
+ return ModeDevice
+ case syscall.DT_CHR:
+ return ModeDevice | ModeCharDevice
+ case syscall.DT_DIR:
+ return ModeDir
+ case syscall.DT_FIFO:
+ return ModeNamedPipe
+ case syscall.DT_LNK:
+ return ModeSymlink
+ case syscall.DT_REG:
+ return 0
+ case syscall.DT_SOCK:
+ return ModeSocket
+ }
+ return ^FileMode(0)
+}
+
+// Implemented in syscall/syscall_darwin.go.
+
+//go:linkname closedir syscall.closedir
+func closedir(dir uintptr) (err error)
+
+//go:linkname readdir_r syscall.readdir_r
+func readdir_r(dir uintptr, entry *syscall.Dirent, result **syscall.Dirent) (res syscall.Errno)
diff --git a/contrib/go/_std_1.21/src/os/dir_unix.go b/contrib/go/_std_1.21/src/os/dir_unix.go
new file mode 100644
index 0000000000..266a78acaf
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/dir_unix.go
@@ -0,0 +1,198 @@
+// Copyright 2009 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.
+
+//go:build aix || dragonfly || freebsd || (js && wasm) || wasip1 || linux || netbsd || openbsd || solaris
+
+package os
+
+import (
+ "io"
+ "runtime"
+ "sync"
+ "syscall"
+ "unsafe"
+)
+
+// Auxiliary information if the File describes a directory
+type dirInfo struct {
+ buf *[]byte // buffer for directory I/O
+ nbuf int // length of buf; return value from Getdirentries
+ bufp int // location of next record in buf.
+}
+
+const (
+ // More than 5760 to work around https://golang.org/issue/24015.
+ blockSize = 8192
+)
+
+var dirBufPool = sync.Pool{
+ New: func() any {
+ // The buffer must be at least a block long.
+ buf := make([]byte, blockSize)
+ return &buf
+ },
+}
+
+func (d *dirInfo) close() {
+ if d.buf != nil {
+ dirBufPool.Put(d.buf)
+ d.buf = nil
+ }
+}
+
+func (f *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEntry, infos []FileInfo, err error) {
+ // If this file has no dirinfo, create one.
+ if f.dirinfo == nil {
+ f.dirinfo = new(dirInfo)
+ f.dirinfo.buf = dirBufPool.Get().(*[]byte)
+ }
+ d := f.dirinfo
+
+ // Change the meaning of n for the implementation below.
+ //
+ // The n above was for the public interface of "if n <= 0,
+ // Readdir returns all the FileInfo from the directory in a
+ // single slice".
+ //
+ // But below, we use only negative to mean looping until the
+ // end and positive to mean bounded, with positive
+ // terminating at 0.
+ if n == 0 {
+ n = -1
+ }
+
+ for n != 0 {
+ // Refill the buffer if necessary
+ if d.bufp >= d.nbuf {
+ d.bufp = 0
+ var errno error
+ d.nbuf, errno = f.pfd.ReadDirent(*d.buf)
+ runtime.KeepAlive(f)
+ if errno != nil {
+ return names, dirents, infos, &PathError{Op: "readdirent", Path: f.name, Err: errno}
+ }
+ if d.nbuf <= 0 {
+ break // EOF
+ }
+ }
+
+ // Drain the buffer
+ buf := (*d.buf)[d.bufp:d.nbuf]
+ reclen, ok := direntReclen(buf)
+ if !ok || reclen > uint64(len(buf)) {
+ break
+ }
+ rec := buf[:reclen]
+ d.bufp += int(reclen)
+ ino, ok := direntIno(rec)
+ if !ok {
+ break
+ }
+ // When building to wasip1, the host runtime might be running on Windows
+ // or might expose a remote file system which does not have the concept
+ // of inodes. Therefore, we cannot make the assumption that it is safe
+ // to skip entries with zero inodes.
+ if ino == 0 && runtime.GOOS != "wasip1" {
+ continue
+ }
+ const namoff = uint64(unsafe.Offsetof(syscall.Dirent{}.Name))
+ namlen, ok := direntNamlen(rec)
+ if !ok || namoff+namlen > uint64(len(rec)) {
+ break
+ }
+ name := rec[namoff : namoff+namlen]
+ for i, c := range name {
+ if c == 0 {
+ name = name[:i]
+ break
+ }
+ }
+ // Check for useless names before allocating a string.
+ if string(name) == "." || string(name) == ".." {
+ continue
+ }
+ if n > 0 { // see 'n == 0' comment above
+ n--
+ }
+ if mode == readdirName {
+ names = append(names, string(name))
+ } else if mode == readdirDirEntry {
+ de, err := newUnixDirent(f.name, string(name), direntType(rec))
+ if IsNotExist(err) {
+ // File disappeared between readdir and stat.
+ // Treat as if it didn't exist.
+ continue
+ }
+ if err != nil {
+ return nil, dirents, nil, err
+ }
+ dirents = append(dirents, de)
+ } else {
+ info, err := lstat(f.name + "/" + string(name))
+ if IsNotExist(err) {
+ // File disappeared between readdir + stat.
+ // Treat as if it didn't exist.
+ continue
+ }
+ if err != nil {
+ return nil, nil, infos, err
+ }
+ infos = append(infos, info)
+ }
+ }
+
+ if n > 0 && len(names)+len(dirents)+len(infos) == 0 {
+ return nil, nil, nil, io.EOF
+ }
+ return names, dirents, infos, nil
+}
+
+// readInt returns the size-bytes unsigned integer in native byte order at offset off.
+func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
+ if len(b) < int(off+size) {
+ return 0, false
+ }
+ if isBigEndian {
+ return readIntBE(b[off:], size), true
+ }
+ return readIntLE(b[off:], size), true
+}
+
+func readIntBE(b []byte, size uintptr) uint64 {
+ switch size {
+ case 1:
+ return uint64(b[0])
+ case 2:
+ _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[1]) | uint64(b[0])<<8
+ case 4:
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24
+ case 8:
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+ default:
+ panic("syscall: readInt with unsupported size")
+ }
+}
+
+func readIntLE(b []byte, size uintptr) uint64 {
+ switch size {
+ case 1:
+ return uint64(b[0])
+ case 2:
+ _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8
+ case 4:
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
+ case 8:
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
+ uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+ default:
+ panic("syscall: readInt with unsupported size")
+ }
+}
diff --git a/contrib/go/_std_1.21/src/os/dir_windows.go b/contrib/go/_std_1.21/src/os/dir_windows.go
new file mode 100644
index 0000000000..9dc2cd7689
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/dir_windows.go
@@ -0,0 +1,80 @@
+// Copyright 2009 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 os
+
+import (
+ "io"
+ "io/fs"
+ "runtime"
+ "syscall"
+)
+
+func (file *File) readdir(n int, mode readdirMode) (names []string, dirents []DirEntry, infos []FileInfo, err error) {
+ // If this file has no dirinfo, create one.
+ needdata := true
+ if file.dirinfo == nil {
+ needdata = false
+ file.dirinfo, err = openDir(file.name)
+ if err != nil {
+ err = &PathError{Op: "readdir", Path: file.name, Err: err}
+ return
+ }
+ }
+ wantAll := n <= 0
+ if wantAll {
+ n = -1
+ }
+ d := &file.dirinfo.data
+ for n != 0 && !file.dirinfo.isempty {
+ if needdata {
+ e := syscall.FindNextFile(file.dirinfo.h, d)
+ runtime.KeepAlive(file)
+ if e != nil {
+ if e == syscall.ERROR_NO_MORE_FILES {
+ break
+ } else {
+ err = &PathError{Op: "FindNextFile", Path: file.name, Err: e}
+ return
+ }
+ }
+ }
+ needdata = true
+ name := syscall.UTF16ToString(d.FileName[0:])
+ if name == "." || name == ".." { // Useless names
+ continue
+ }
+ if mode == readdirName {
+ names = append(names, name)
+ } else {
+ f := newFileStatFromWin32finddata(d)
+ f.name = name
+ f.path = file.dirinfo.path
+ f.appendNameToPath = true
+ if mode == readdirDirEntry {
+ dirents = append(dirents, dirEntry{f})
+ } else {
+ infos = append(infos, f)
+ }
+ }
+ n--
+ }
+ if !wantAll && len(names)+len(dirents)+len(infos) == 0 {
+ return nil, nil, nil, io.EOF
+ }
+ return names, dirents, infos, nil
+}
+
+type dirEntry struct {
+ fs *fileStat
+}
+
+func (de dirEntry) Name() string { return de.fs.Name() }
+func (de dirEntry) IsDir() bool { return de.fs.IsDir() }
+func (de dirEntry) Type() FileMode { return de.fs.Mode().Type() }
+func (de dirEntry) Info() (FileInfo, error) { return de.fs, nil }
+
+func (de dirEntry) String() string {
+ return fs.FormatDirEntry(de)
+}
diff --git a/contrib/go/_std_1.20/src/os/dirent_linux.go b/contrib/go/_std_1.21/src/os/dirent_linux.go
index 74a3431121..74a3431121 100644
--- a/contrib/go/_std_1.20/src/os/dirent_linux.go
+++ b/contrib/go/_std_1.21/src/os/dirent_linux.go
diff --git a/contrib/go/_std_1.20/src/os/endian_little.go b/contrib/go/_std_1.21/src/os/endian_little.go
index a7cf1cdda8..a7cf1cdda8 100644
--- a/contrib/go/_std_1.20/src/os/endian_little.go
+++ b/contrib/go/_std_1.21/src/os/endian_little.go
diff --git a/contrib/go/_std_1.20/src/os/env.go b/contrib/go/_std_1.21/src/os/env.go
index 63ad5ab4bd..63ad5ab4bd 100644
--- a/contrib/go/_std_1.20/src/os/env.go
+++ b/contrib/go/_std_1.21/src/os/env.go
diff --git a/contrib/go/_std_1.21/src/os/error.go b/contrib/go/_std_1.21/src/os/error.go
new file mode 100644
index 0000000000..62ede9ded3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/error.go
@@ -0,0 +1,141 @@
+// Copyright 2009 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 os
+
+import (
+ "internal/poll"
+ "io/fs"
+)
+
+// Portable analogs of some common system call errors.
+//
+// Errors returned from this package may be tested against these errors
+// with errors.Is.
+var (
+ // ErrInvalid indicates an invalid argument.
+ // Methods on File will return this error when the receiver is nil.
+ ErrInvalid = fs.ErrInvalid // "invalid argument"
+
+ ErrPermission = fs.ErrPermission // "permission denied"
+ ErrExist = fs.ErrExist // "file already exists"
+ ErrNotExist = fs.ErrNotExist // "file does not exist"
+ ErrClosed = fs.ErrClosed // "file already closed"
+
+ ErrNoDeadline = errNoDeadline() // "file type does not support deadline"
+ ErrDeadlineExceeded = errDeadlineExceeded() // "i/o timeout"
+)
+
+func errNoDeadline() error { return poll.ErrNoDeadline }
+
+// errDeadlineExceeded returns the value for os.ErrDeadlineExceeded.
+// This error comes from the internal/poll package, which is also
+// used by package net. Doing it this way ensures that the net
+// package will return os.ErrDeadlineExceeded for an exceeded deadline,
+// as documented by net.Conn.SetDeadline, without requiring any extra
+// work in the net package and without requiring the internal/poll
+// package to import os (which it can't, because that would be circular).
+func errDeadlineExceeded() error { return poll.ErrDeadlineExceeded }
+
+type timeout interface {
+ Timeout() bool
+}
+
+// PathError records an error and the operation and file path that caused it.
+type PathError = fs.PathError
+
+// SyscallError records an error from a specific system call.
+type SyscallError struct {
+ Syscall string
+ Err error
+}
+
+func (e *SyscallError) Error() string { return e.Syscall + ": " + e.Err.Error() }
+
+func (e *SyscallError) Unwrap() error { return e.Err }
+
+// Timeout reports whether this error represents a timeout.
+func (e *SyscallError) Timeout() bool {
+ t, ok := e.Err.(timeout)
+ return ok && t.Timeout()
+}
+
+// NewSyscallError returns, as an error, a new SyscallError
+// with the given system call name and error details.
+// As a convenience, if err is nil, NewSyscallError returns nil.
+func NewSyscallError(syscall string, err error) error {
+ if err == nil {
+ return nil
+ }
+ return &SyscallError{syscall, err}
+}
+
+// IsExist returns a boolean indicating whether the error is known to report
+// that a file or directory already exists. It is satisfied by ErrExist as
+// well as some syscall errors.
+//
+// This function predates errors.Is. It only supports errors returned by
+// the os package. New code should use errors.Is(err, fs.ErrExist).
+func IsExist(err error) bool {
+ return underlyingErrorIs(err, ErrExist)
+}
+
+// IsNotExist returns a boolean indicating whether the error is known to
+// report that a file or directory does not exist. It is satisfied by
+// ErrNotExist as well as some syscall errors.
+//
+// This function predates errors.Is. It only supports errors returned by
+// the os package. New code should use errors.Is(err, fs.ErrNotExist).
+func IsNotExist(err error) bool {
+ return underlyingErrorIs(err, ErrNotExist)
+}
+
+// IsPermission returns a boolean indicating whether the error is known to
+// report that permission is denied. It is satisfied by ErrPermission as well
+// as some syscall errors.
+//
+// This function predates errors.Is. It only supports errors returned by
+// the os package. New code should use errors.Is(err, fs.ErrPermission).
+func IsPermission(err error) bool {
+ return underlyingErrorIs(err, ErrPermission)
+}
+
+// IsTimeout returns a boolean indicating whether the error is known
+// to report that a timeout occurred.
+//
+// This function predates errors.Is, and the notion of whether an
+// error indicates a timeout can be ambiguous. For example, the Unix
+// error EWOULDBLOCK sometimes indicates a timeout and sometimes does not.
+// New code should use errors.Is with a value appropriate to the call
+// returning the error, such as os.ErrDeadlineExceeded.
+func IsTimeout(err error) bool {
+ terr, ok := underlyingError(err).(timeout)
+ return ok && terr.Timeout()
+}
+
+func underlyingErrorIs(err, target error) bool {
+ // Note that this function is not errors.Is:
+ // underlyingError only unwraps the specific error-wrapping types
+ // that it historically did, not all errors implementing Unwrap().
+ err = underlyingError(err)
+ if err == target {
+ return true
+ }
+ // To preserve prior behavior, only examine syscall errors.
+ e, ok := err.(syscallErrorType)
+ return ok && e.Is(target)
+}
+
+// underlyingError returns the underlying error for known os error types.
+func underlyingError(err error) error {
+ switch err := err.(type) {
+ case *PathError:
+ return err.Err
+ case *LinkError:
+ return err.Err
+ case *SyscallError:
+ return err.Err
+ }
+ return err
+}
diff --git a/contrib/go/_std_1.20/src/os/error_errno.go b/contrib/go/_std_1.21/src/os/error_errno.go
index c8140461a4..c8140461a4 100644
--- a/contrib/go/_std_1.20/src/os/error_errno.go
+++ b/contrib/go/_std_1.21/src/os/error_errno.go
diff --git a/contrib/go/_std_1.21/src/os/error_posix.go b/contrib/go/_std_1.21/src/os/error_posix.go
new file mode 100644
index 0000000000..b159c036c1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/error_posix.go
@@ -0,0 +1,18 @@
+// Copyright 2017 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package os
+
+import "syscall"
+
+// wrapSyscallError takes an error and a syscall name. If the error is
+// a syscall.Errno, it wraps it in an os.SyscallError using the syscall name.
+func wrapSyscallError(name string, err error) error {
+ if _, ok := err.(syscall.Errno); ok {
+ err = NewSyscallError(name, err)
+ }
+ return err
+}
diff --git a/contrib/go/_std_1.21/src/os/exec.go b/contrib/go/_std_1.21/src/os/exec.go
new file mode 100644
index 0000000000..ed5a75c4d1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/exec.go
@@ -0,0 +1,180 @@
+// Copyright 2009 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 os
+
+import (
+ "errors"
+ "internal/testlog"
+ "runtime"
+ "sync"
+ "sync/atomic"
+ "syscall"
+ "time"
+)
+
+// ErrProcessDone indicates a Process has finished.
+var ErrProcessDone = errors.New("os: process already finished")
+
+// Process stores the information about a process created by StartProcess.
+type Process struct {
+ Pid int
+ handle uintptr // handle is accessed atomically on Windows
+ isdone atomic.Bool // process has been successfully waited on
+ sigMu sync.RWMutex // avoid race between wait and signal
+}
+
+func newProcess(pid int, handle uintptr) *Process {
+ p := &Process{Pid: pid, handle: handle}
+ runtime.SetFinalizer(p, (*Process).Release)
+ return p
+}
+
+func (p *Process) setDone() {
+ p.isdone.Store(true)
+}
+
+func (p *Process) done() bool {
+ return p.isdone.Load()
+}
+
+// ProcAttr holds the attributes that will be applied to a new process
+// started by StartProcess.
+type ProcAttr struct {
+ // If Dir is non-empty, the child changes into the directory before
+ // creating the process.
+ Dir string
+ // If Env is non-nil, it gives the environment variables for the
+ // new process in the form returned by Environ.
+ // If it is nil, the result of Environ will be used.
+ Env []string
+ // Files specifies the open files inherited by the new process. The
+ // first three entries correspond to standard input, standard output, and
+ // standard error. An implementation may support additional entries,
+ // depending on the underlying operating system. A nil entry corresponds
+ // to that file being closed when the process starts.
+ // On Unix systems, StartProcess will change these File values
+ // to blocking mode, which means that SetDeadline will stop working
+ // and calling Close will not interrupt a Read or Write.
+ Files []*File
+
+ // Operating system-specific process creation attributes.
+ // Note that setting this field means that your program
+ // may not execute properly or even compile on some
+ // operating systems.
+ Sys *syscall.SysProcAttr
+}
+
+// A Signal represents an operating system signal.
+// The usual underlying implementation is operating system-dependent:
+// on Unix it is syscall.Signal.
+type Signal interface {
+ String() string
+ Signal() // to distinguish from other Stringers
+}
+
+// Getpid returns the process id of the caller.
+func Getpid() int { return syscall.Getpid() }
+
+// Getppid returns the process id of the caller's parent.
+func Getppid() int { return syscall.Getppid() }
+
+// FindProcess looks for a running process by its pid.
+//
+// The Process it returns can be used to obtain information
+// about the underlying operating system process.
+//
+// On Unix systems, FindProcess always succeeds and returns a Process
+// for the given pid, regardless of whether the process exists. To test whether
+// the process actually exists, see whether p.Signal(syscall.Signal(0)) reports
+// an error.
+func FindProcess(pid int) (*Process, error) {
+ return findProcess(pid)
+}
+
+// StartProcess starts a new process with the program, arguments and attributes
+// specified by name, argv and attr. The argv slice will become os.Args in the
+// new process, so it normally starts with the program name.
+//
+// If the calling goroutine has locked the operating system thread
+// with runtime.LockOSThread and modified any inheritable OS-level
+// thread state (for example, Linux or Plan 9 name spaces), the new
+// process will inherit the caller's thread state.
+//
+// StartProcess is a low-level interface. The os/exec package provides
+// higher-level interfaces.
+//
+// If there is an error, it will be of type *PathError.
+func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error) {
+ testlog.Open(name)
+ return startProcess(name, argv, attr)
+}
+
+// Release releases any resources associated with the Process p,
+// rendering it unusable in the future.
+// Release only needs to be called if Wait is not.
+func (p *Process) Release() error {
+ return p.release()
+}
+
+// Kill causes the Process to exit immediately. Kill does not wait until
+// the Process has actually exited. This only kills the Process itself,
+// not any other processes it may have started.
+func (p *Process) Kill() error {
+ return p.kill()
+}
+
+// Wait waits for the Process to exit, and then returns a
+// ProcessState describing its status and an error, if any.
+// Wait releases any resources associated with the Process.
+// On most operating systems, the Process must be a child
+// of the current process or an error will be returned.
+func (p *Process) Wait() (*ProcessState, error) {
+ return p.wait()
+}
+
+// Signal sends a signal to the Process.
+// Sending Interrupt on Windows is not implemented.
+func (p *Process) Signal(sig Signal) error {
+ return p.signal(sig)
+}
+
+// UserTime returns the user CPU time of the exited process and its children.
+func (p *ProcessState) UserTime() time.Duration {
+ return p.userTime()
+}
+
+// SystemTime returns the system CPU time of the exited process and its children.
+func (p *ProcessState) SystemTime() time.Duration {
+ return p.systemTime()
+}
+
+// Exited reports whether the program has exited.
+// On Unix systems this reports true if the program exited due to calling exit,
+// but false if the program terminated due to a signal.
+func (p *ProcessState) Exited() bool {
+ return p.exited()
+}
+
+// Success reports whether the program exited successfully,
+// such as with exit status 0 on Unix.
+func (p *ProcessState) Success() bool {
+ return p.success()
+}
+
+// Sys returns system-dependent exit information about
+// the process. Convert it to the appropriate underlying
+// type, such as syscall.WaitStatus on Unix, to access its contents.
+func (p *ProcessState) Sys() any {
+ return p.sys()
+}
+
+// SysUsage returns system-dependent resource usage information about
+// the exited process. Convert it to the appropriate underlying
+// type, such as *syscall.Rusage on Unix, to access its contents.
+// (On Unix, *syscall.Rusage matches struct rusage as defined in the
+// getrusage(2) manual page.)
+func (p *ProcessState) SysUsage() any {
+ return p.sysUsage()
+}
diff --git a/contrib/go/_std_1.21/src/os/exec/exec.go b/contrib/go/_std_1.21/src/os/exec/exec.go
new file mode 100644
index 0000000000..138be29ecf
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/exec/exec.go
@@ -0,0 +1,1303 @@
+// Copyright 2009 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 exec runs external commands. It wraps os.StartProcess to make it
+// easier to remap stdin and stdout, connect I/O with pipes, and do other
+// adjustments.
+//
+// Unlike the "system" library call from C and other languages, the
+// os/exec package intentionally does not invoke the system shell and
+// does not expand any glob patterns or handle other expansions,
+// pipelines, or redirections typically done by shells. The package
+// behaves more like C's "exec" family of functions. To expand glob
+// patterns, either call the shell directly, taking care to escape any
+// dangerous input, or use the path/filepath package's Glob function.
+// To expand environment variables, use package os's ExpandEnv.
+//
+// Note that the examples in this package assume a Unix system.
+// They may not run on Windows, and they do not run in the Go Playground
+// used by golang.org and godoc.org.
+//
+// # Executables in the current directory
+//
+// The functions Command and LookPath look for a program
+// in the directories listed in the current path, following the
+// conventions of the host operating system.
+// Operating systems have for decades included the current
+// directory in this search, sometimes implicitly and sometimes
+// configured explicitly that way by default.
+// Modern practice is that including the current directory
+// is usually unexpected and often leads to security problems.
+//
+// To avoid those security problems, as of Go 1.19, this package will not resolve a program
+// using an implicit or explicit path entry relative to the current directory.
+// That is, if you run exec.LookPath("go"), it will not successfully return
+// ./go on Unix nor .\go.exe on Windows, no matter how the path is configured.
+// Instead, if the usual path algorithms would result in that answer,
+// these functions return an error err satisfying errors.Is(err, ErrDot).
+//
+// For example, consider these two program snippets:
+//
+// path, err := exec.LookPath("prog")
+// if err != nil {
+// log.Fatal(err)
+// }
+// use(path)
+//
+// and
+//
+// cmd := exec.Command("prog")
+// if err := cmd.Run(); err != nil {
+// log.Fatal(err)
+// }
+//
+// These will not find and run ./prog or .\prog.exe,
+// no matter how the current path is configured.
+//
+// Code that always wants to run a program from the current directory
+// can be rewritten to say "./prog" instead of "prog".
+//
+// Code that insists on including results from relative path entries
+// can instead override the error using an errors.Is check:
+//
+// path, err := exec.LookPath("prog")
+// if errors.Is(err, exec.ErrDot) {
+// err = nil
+// }
+// if err != nil {
+// log.Fatal(err)
+// }
+// use(path)
+//
+// and
+//
+// cmd := exec.Command("prog")
+// if errors.Is(cmd.Err, exec.ErrDot) {
+// cmd.Err = nil
+// }
+// if err := cmd.Run(); err != nil {
+// log.Fatal(err)
+// }
+//
+// Setting the environment variable GODEBUG=execerrdot=0
+// disables generation of ErrDot entirely, temporarily restoring the pre-Go 1.19
+// behavior for programs that are unable to apply more targeted fixes.
+// A future version of Go may remove support for this variable.
+//
+// Before adding such overrides, make sure you understand the
+// security implications of doing so.
+// See https://go.dev/blog/path-security for more information.
+package exec
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "internal/godebug"
+ "internal/syscall/execenv"
+ "io"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "strings"
+ "syscall"
+ "time"
+)
+
+// Error is returned by LookPath when it fails to classify a file as an
+// executable.
+type Error struct {
+ // Name is the file name for which the error occurred.
+ Name string
+ // Err is the underlying error.
+ Err error
+}
+
+func (e *Error) Error() string {
+ return "exec: " + strconv.Quote(e.Name) + ": " + e.Err.Error()
+}
+
+func (e *Error) Unwrap() error { return e.Err }
+
+// ErrWaitDelay is returned by (*Cmd).Wait if the process exits with a
+// successful status code but its output pipes are not closed before the
+// command's WaitDelay expires.
+var ErrWaitDelay = errors.New("exec: WaitDelay expired before I/O complete")
+
+// wrappedError wraps an error without relying on fmt.Errorf.
+type wrappedError struct {
+ prefix string
+ err error
+}
+
+func (w wrappedError) Error() string {
+ return w.prefix + ": " + w.err.Error()
+}
+
+func (w wrappedError) Unwrap() error {
+ return w.err
+}
+
+// Cmd represents an external command being prepared or run.
+//
+// A Cmd cannot be reused after calling its Run, Output or CombinedOutput
+// methods.
+type Cmd struct {
+ // Path is the path of the command to run.
+ //
+ // This is the only field that must be set to a non-zero
+ // value. If Path is relative, it is evaluated relative
+ // to Dir.
+ Path string
+
+ // Args holds command line arguments, including the command as Args[0].
+ // If the Args field is empty or nil, Run uses {Path}.
+ //
+ // In typical use, both Path and Args are set by calling Command.
+ Args []string
+
+ // Env specifies the environment of the process.
+ // Each entry is of the form "key=value".
+ // If Env is nil, the new process uses the current process's
+ // environment.
+ // If Env contains duplicate environment keys, only the last
+ // value in the slice for each duplicate key is used.
+ // As a special case on Windows, SYSTEMROOT is always added if
+ // missing and not explicitly set to the empty string.
+ Env []string
+
+ // Dir specifies the working directory of the command.
+ // If Dir is the empty string, Run runs the command in the
+ // calling process's current directory.
+ Dir string
+
+ // Stdin specifies the process's standard input.
+ //
+ // If Stdin is nil, the process reads from the null device (os.DevNull).
+ //
+ // If Stdin is an *os.File, the process's standard input is connected
+ // directly to that file.
+ //
+ // Otherwise, during the execution of the command a separate
+ // goroutine reads from Stdin and delivers that data to the command
+ // over a pipe. In this case, Wait does not complete until the goroutine
+ // stops copying, either because it has reached the end of Stdin
+ // (EOF or a read error), or because writing to the pipe returned an error,
+ // or because a nonzero WaitDelay was set and expired.
+ Stdin io.Reader
+
+ // Stdout and Stderr specify the process's standard output and error.
+ //
+ // If either is nil, Run connects the corresponding file descriptor
+ // to the null device (os.DevNull).
+ //
+ // If either is an *os.File, the corresponding output from the process
+ // is connected directly to that file.
+ //
+ // Otherwise, during the execution of the command a separate goroutine
+ // reads from the process over a pipe and delivers that data to the
+ // corresponding Writer. In this case, Wait does not complete until the
+ // goroutine reaches EOF or encounters an error or a nonzero WaitDelay
+ // expires.
+ //
+ // If Stdout and Stderr are the same writer, and have a type that can
+ // be compared with ==, at most one goroutine at a time will call Write.
+ Stdout io.Writer
+ Stderr io.Writer
+
+ // ExtraFiles specifies additional open files to be inherited by the
+ // new process. It does not include standard input, standard output, or
+ // standard error. If non-nil, entry i becomes file descriptor 3+i.
+ //
+ // ExtraFiles is not supported on Windows.
+ ExtraFiles []*os.File
+
+ // SysProcAttr holds optional, operating system-specific attributes.
+ // Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
+ SysProcAttr *syscall.SysProcAttr
+
+ // Process is the underlying process, once started.
+ Process *os.Process
+
+ // ProcessState contains information about an exited process.
+ // If the process was started successfully, Wait or Run will
+ // populate its ProcessState when the command completes.
+ ProcessState *os.ProcessState
+
+ // ctx is the context passed to CommandContext, if any.
+ ctx context.Context
+
+ Err error // LookPath error, if any.
+
+ // If Cancel is non-nil, the command must have been created with
+ // CommandContext and Cancel will be called when the command's
+ // Context is done. By default, CommandContext sets Cancel to
+ // call the Kill method on the command's Process.
+ //
+ // Typically a custom Cancel will send a signal to the command's
+ // Process, but it may instead take other actions to initiate cancellation,
+ // such as closing a stdin or stdout pipe or sending a shutdown request on a
+ // network socket.
+ //
+ // If the command exits with a success status after Cancel is
+ // called, and Cancel does not return an error equivalent to
+ // os.ErrProcessDone, then Wait and similar methods will return a non-nil
+ // error: either an error wrapping the one returned by Cancel,
+ // or the error from the Context.
+ // (If the command exits with a non-success status, or Cancel
+ // returns an error that wraps os.ErrProcessDone, Wait and similar methods
+ // continue to return the command's usual exit status.)
+ //
+ // If Cancel is set to nil, nothing will happen immediately when the command's
+ // Context is done, but a nonzero WaitDelay will still take effect. That may
+ // be useful, for example, to work around deadlocks in commands that do not
+ // support shutdown signals but are expected to always finish quickly.
+ //
+ // Cancel will not be called if Start returns a non-nil error.
+ Cancel func() error
+
+ // If WaitDelay is non-zero, it bounds the time spent waiting on two sources
+ // of unexpected delay in Wait: a child process that fails to exit after the
+ // associated Context is canceled, and a child process that exits but leaves
+ // its I/O pipes unclosed.
+ //
+ // The WaitDelay timer starts when either the associated Context is done or a
+ // call to Wait observes that the child process has exited, whichever occurs
+ // first. When the delay has elapsed, the command shuts down the child process
+ // and/or its I/O pipes.
+ //
+ // If the child process has failed to exit — perhaps because it ignored or
+ // failed to receive a shutdown signal from a Cancel function, or because no
+ // Cancel function was set — then it will be terminated using os.Process.Kill.
+ //
+ // Then, if the I/O pipes communicating with the child process are still open,
+ // those pipes are closed in order to unblock any goroutines currently blocked
+ // on Read or Write calls.
+ //
+ // If pipes are closed due to WaitDelay, no Cancel call has occurred,
+ // and the command has otherwise exited with a successful status, Wait and
+ // similar methods will return ErrWaitDelay instead of nil.
+ //
+ // If WaitDelay is zero (the default), I/O pipes will be read until EOF,
+ // which might not occur until orphaned subprocesses of the command have
+ // also closed their descriptors for the pipes.
+ WaitDelay time.Duration
+
+ // childIOFiles holds closers for any of the child process's
+ // stdin, stdout, and/or stderr files that were opened by the Cmd itself
+ // (not supplied by the caller). These should be closed as soon as they
+ // are inherited by the child process.
+ childIOFiles []io.Closer
+
+ // parentIOPipes holds closers for the parent's end of any pipes
+ // connected to the child's stdin, stdout, and/or stderr streams
+ // that were opened by the Cmd itself (not supplied by the caller).
+ // These should be closed after Wait sees the command and copying
+ // goroutines exit, or after WaitDelay has expired.
+ parentIOPipes []io.Closer
+
+ // goroutine holds a set of closures to execute to copy data
+ // to and/or from the command's I/O pipes.
+ goroutine []func() error
+
+ // If goroutineErr is non-nil, it receives the first error from a copying
+ // goroutine once all such goroutines have completed.
+ // goroutineErr is set to nil once its error has been received.
+ goroutineErr <-chan error
+
+ // If ctxResult is non-nil, it receives the result of watchCtx exactly once.
+ ctxResult <-chan ctxResult
+
+ // The stack saved when the Command was created, if GODEBUG contains
+ // execwait=2. Used for debugging leaks.
+ createdByStack []byte
+
+ // For a security release long ago, we created x/sys/execabs,
+ // which manipulated the unexported lookPathErr error field
+ // in this struct. For Go 1.19 we exported the field as Err error,
+ // above, but we have to keep lookPathErr around for use by
+ // old programs building against new toolchains.
+ // The String and Start methods look for an error in lookPathErr
+ // in preference to Err, to preserve the errors that execabs sets.
+ //
+ // In general we don't guarantee misuse of reflect like this,
+ // but the misuse of reflect was by us, the best of various bad
+ // options to fix the security problem, and people depend on
+ // those old copies of execabs continuing to work.
+ // The result is that we have to leave this variable around for the
+ // rest of time, a compatibility scar.
+ //
+ // See https://go.dev/blog/path-security
+ // and https://go.dev/issue/43724 for more context.
+ lookPathErr error
+}
+
+// A ctxResult reports the result of watching the Context associated with a
+// running command (and sending corresponding signals if needed).
+type ctxResult struct {
+ err error
+
+ // If timer is non-nil, it expires after WaitDelay has elapsed after
+ // the Context is done.
+ //
+ // (If timer is nil, that means that the Context was not done before the
+ // command completed, or no WaitDelay was set, or the WaitDelay already
+ // expired and its effect was already applied.)
+ timer *time.Timer
+}
+
+var execwait = godebug.New("#execwait")
+var execerrdot = godebug.New("execerrdot")
+
+// Command returns the Cmd struct to execute the named program with
+// the given arguments.
+//
+// It sets only the Path and Args in the returned structure.
+//
+// If name contains no path separators, Command uses LookPath to
+// resolve name to a complete path if possible. Otherwise it uses name
+// directly as Path.
+//
+// The returned Cmd's Args field is constructed from the command name
+// followed by the elements of arg, so arg should not include the
+// command name itself. For example, Command("echo", "hello").
+// Args[0] is always name, not the possibly resolved Path.
+//
+// On Windows, processes receive the whole command line as a single string
+// and do their own parsing. Command combines and quotes Args into a command
+// line string with an algorithm compatible with applications using
+// CommandLineToArgvW (which is the most common way). Notable exceptions are
+// msiexec.exe and cmd.exe (and thus, all batch files), which have a different
+// unquoting algorithm. In these or other similar cases, you can do the
+// quoting yourself and provide the full command line in SysProcAttr.CmdLine,
+// leaving Args empty.
+func Command(name string, arg ...string) *Cmd {
+ cmd := &Cmd{
+ Path: name,
+ Args: append([]string{name}, arg...),
+ }
+
+ if v := execwait.Value(); v != "" {
+ if v == "2" {
+ // Obtain the caller stack. (This is equivalent to runtime/debug.Stack,
+ // copied to avoid importing the whole package.)
+ stack := make([]byte, 1024)
+ for {
+ n := runtime.Stack(stack, false)
+ if n < len(stack) {
+ stack = stack[:n]
+ break
+ }
+ stack = make([]byte, 2*len(stack))
+ }
+
+ if i := bytes.Index(stack, []byte("\nos/exec.Command(")); i >= 0 {
+ stack = stack[i+1:]
+ }
+ cmd.createdByStack = stack
+ }
+
+ runtime.SetFinalizer(cmd, func(c *Cmd) {
+ if c.Process != nil && c.ProcessState == nil {
+ debugHint := ""
+ if c.createdByStack == nil {
+ debugHint = " (set GODEBUG=execwait=2 to capture stacks for debugging)"
+ } else {
+ os.Stderr.WriteString("GODEBUG=execwait=2 detected a leaked exec.Cmd created by:\n")
+ os.Stderr.Write(c.createdByStack)
+ os.Stderr.WriteString("\n")
+ debugHint = ""
+ }
+ panic("exec: Cmd started a Process but leaked without a call to Wait" + debugHint)
+ }
+ })
+ }
+
+ if filepath.Base(name) == name {
+ lp, err := LookPath(name)
+ if lp != "" {
+ // Update cmd.Path even if err is non-nil.
+ // If err is ErrDot (especially on Windows), lp may include a resolved
+ // extension (like .exe or .bat) that should be preserved.
+ cmd.Path = lp
+ }
+ if err != nil {
+ cmd.Err = err
+ }
+ }
+ return cmd
+}
+
+// CommandContext is like Command but includes a context.
+//
+// The provided context is used to interrupt the process
+// (by calling cmd.Cancel or os.Process.Kill)
+// if the context becomes done before the command completes on its own.
+//
+// CommandContext sets the command's Cancel function to invoke the Kill method
+// on its Process, and leaves its WaitDelay unset. The caller may change the
+// cancellation behavior by modifying those fields before starting the command.
+func CommandContext(ctx context.Context, name string, arg ...string) *Cmd {
+ if ctx == nil {
+ panic("nil Context")
+ }
+ cmd := Command(name, arg...)
+ cmd.ctx = ctx
+ cmd.Cancel = func() error {
+ return cmd.Process.Kill()
+ }
+ return cmd
+}
+
+// String returns a human-readable description of c.
+// It is intended only for debugging.
+// In particular, it is not suitable for use as input to a shell.
+// The output of String may vary across Go releases.
+func (c *Cmd) String() string {
+ if c.Err != nil || c.lookPathErr != nil {
+ // failed to resolve path; report the original requested path (plus args)
+ return strings.Join(c.Args, " ")
+ }
+ // report the exact executable path (plus args)
+ b := new(strings.Builder)
+ b.WriteString(c.Path)
+ for _, a := range c.Args[1:] {
+ b.WriteByte(' ')
+ b.WriteString(a)
+ }
+ return b.String()
+}
+
+// interfaceEqual protects against panics from doing equality tests on
+// two interfaces with non-comparable underlying types.
+func interfaceEqual(a, b any) bool {
+ defer func() {
+ recover()
+ }()
+ return a == b
+}
+
+func (c *Cmd) argv() []string {
+ if len(c.Args) > 0 {
+ return c.Args
+ }
+ return []string{c.Path}
+}
+
+func (c *Cmd) childStdin() (*os.File, error) {
+ if c.Stdin == nil {
+ f, err := os.Open(os.DevNull)
+ if err != nil {
+ return nil, err
+ }
+ c.childIOFiles = append(c.childIOFiles, f)
+ return f, nil
+ }
+
+ if f, ok := c.Stdin.(*os.File); ok {
+ return f, nil
+ }
+
+ pr, pw, err := os.Pipe()
+ if err != nil {
+ return nil, err
+ }
+
+ c.childIOFiles = append(c.childIOFiles, pr)
+ c.parentIOPipes = append(c.parentIOPipes, pw)
+ c.goroutine = append(c.goroutine, func() error {
+ _, err := io.Copy(pw, c.Stdin)
+ if skipStdinCopyError(err) {
+ err = nil
+ }
+ if err1 := pw.Close(); err == nil {
+ err = err1
+ }
+ return err
+ })
+ return pr, nil
+}
+
+func (c *Cmd) childStdout() (*os.File, error) {
+ return c.writerDescriptor(c.Stdout)
+}
+
+func (c *Cmd) childStderr(childStdout *os.File) (*os.File, error) {
+ if c.Stderr != nil && interfaceEqual(c.Stderr, c.Stdout) {
+ return childStdout, nil
+ }
+ return c.writerDescriptor(c.Stderr)
+}
+
+// writerDescriptor returns an os.File to which the child process
+// can write to send data to w.
+//
+// If w is nil, writerDescriptor returns a File that writes to os.DevNull.
+func (c *Cmd) writerDescriptor(w io.Writer) (*os.File, error) {
+ if w == nil {
+ f, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0)
+ if err != nil {
+ return nil, err
+ }
+ c.childIOFiles = append(c.childIOFiles, f)
+ return f, nil
+ }
+
+ if f, ok := w.(*os.File); ok {
+ return f, nil
+ }
+
+ pr, pw, err := os.Pipe()
+ if err != nil {
+ return nil, err
+ }
+
+ c.childIOFiles = append(c.childIOFiles, pw)
+ c.parentIOPipes = append(c.parentIOPipes, pr)
+ c.goroutine = append(c.goroutine, func() error {
+ _, err := io.Copy(w, pr)
+ pr.Close() // in case io.Copy stopped due to write error
+ return err
+ })
+ return pw, nil
+}
+
+func closeDescriptors(closers []io.Closer) {
+ for _, fd := range closers {
+ fd.Close()
+ }
+}
+
+// Run starts the specified command and waits for it to complete.
+//
+// The returned error is nil if the command runs, has no problems
+// copying stdin, stdout, and stderr, and exits with a zero exit
+// status.
+//
+// If the command starts but does not complete successfully, the error is of
+// type *ExitError. Other error types may be returned for other situations.
+//
+// If the calling goroutine has locked the operating system thread
+// with runtime.LockOSThread and modified any inheritable OS-level
+// thread state (for example, Linux or Plan 9 name spaces), the new
+// process will inherit the caller's thread state.
+func (c *Cmd) Run() error {
+ if err := c.Start(); err != nil {
+ return err
+ }
+ return c.Wait()
+}
+
+// lookExtensions finds windows executable by its dir and path.
+// It uses LookPath to try appropriate extensions.
+// lookExtensions does not search PATH, instead it converts `prog` into `.\prog`.
+func lookExtensions(path, dir string) (string, error) {
+ if filepath.Base(path) == path {
+ path = "." + string(filepath.Separator) + path
+ }
+ if dir == "" {
+ return LookPath(path)
+ }
+ if filepath.VolumeName(path) != "" {
+ return LookPath(path)
+ }
+ if len(path) > 1 && os.IsPathSeparator(path[0]) {
+ return LookPath(path)
+ }
+ dirandpath := filepath.Join(dir, path)
+ // We assume that LookPath will only add file extension.
+ lp, err := LookPath(dirandpath)
+ if err != nil {
+ return "", err
+ }
+ ext := strings.TrimPrefix(lp, dirandpath)
+ return path + ext, nil
+}
+
+// Start starts the specified command but does not wait for it to complete.
+//
+// If Start returns successfully, the c.Process field will be set.
+//
+// After a successful call to Start the Wait method must be called in
+// order to release associated system resources.
+func (c *Cmd) Start() error {
+ // Check for doubled Start calls before we defer failure cleanup. If the prior
+ // call to Start succeeded, we don't want to spuriously close its pipes.
+ if c.Process != nil {
+ return errors.New("exec: already started")
+ }
+
+ started := false
+ defer func() {
+ closeDescriptors(c.childIOFiles)
+ c.childIOFiles = nil
+
+ if !started {
+ closeDescriptors(c.parentIOPipes)
+ c.parentIOPipes = nil
+ }
+ }()
+
+ if c.Path == "" && c.Err == nil && c.lookPathErr == nil {
+ c.Err = errors.New("exec: no command")
+ }
+ if c.Err != nil || c.lookPathErr != nil {
+ if c.lookPathErr != nil {
+ return c.lookPathErr
+ }
+ return c.Err
+ }
+ if runtime.GOOS == "windows" {
+ lp, err := lookExtensions(c.Path, c.Dir)
+ if err != nil {
+ return err
+ }
+ c.Path = lp
+ }
+ if c.Cancel != nil && c.ctx == nil {
+ return errors.New("exec: command with a non-nil Cancel was not created with CommandContext")
+ }
+ if c.ctx != nil {
+ select {
+ case <-c.ctx.Done():
+ return c.ctx.Err()
+ default:
+ }
+ }
+
+ childFiles := make([]*os.File, 0, 3+len(c.ExtraFiles))
+ stdin, err := c.childStdin()
+ if err != nil {
+ return err
+ }
+ childFiles = append(childFiles, stdin)
+ stdout, err := c.childStdout()
+ if err != nil {
+ return err
+ }
+ childFiles = append(childFiles, stdout)
+ stderr, err := c.childStderr(stdout)
+ if err != nil {
+ return err
+ }
+ childFiles = append(childFiles, stderr)
+ childFiles = append(childFiles, c.ExtraFiles...)
+
+ env, err := c.environ()
+ if err != nil {
+ return err
+ }
+
+ c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
+ Dir: c.Dir,
+ Files: childFiles,
+ Env: env,
+ Sys: c.SysProcAttr,
+ })
+ if err != nil {
+ return err
+ }
+ started = true
+
+ // Don't allocate the goroutineErr channel unless there are goroutines to start.
+ if len(c.goroutine) > 0 {
+ goroutineErr := make(chan error, 1)
+ c.goroutineErr = goroutineErr
+
+ type goroutineStatus struct {
+ running int
+ firstErr error
+ }
+ statusc := make(chan goroutineStatus, 1)
+ statusc <- goroutineStatus{running: len(c.goroutine)}
+ for _, fn := range c.goroutine {
+ go func(fn func() error) {
+ err := fn()
+
+ status := <-statusc
+ if status.firstErr == nil {
+ status.firstErr = err
+ }
+ status.running--
+ if status.running == 0 {
+ goroutineErr <- status.firstErr
+ } else {
+ statusc <- status
+ }
+ }(fn)
+ }
+ c.goroutine = nil // Allow the goroutines' closures to be GC'd when they complete.
+ }
+
+ // If we have anything to do when the command's Context expires,
+ // start a goroutine to watch for cancellation.
+ //
+ // (Even if the command was created by CommandContext, a helper library may
+ // have explicitly set its Cancel field back to nil, indicating that it should
+ // be allowed to continue running after cancellation after all.)
+ if (c.Cancel != nil || c.WaitDelay != 0) && c.ctx != nil && c.ctx.Done() != nil {
+ resultc := make(chan ctxResult)
+ c.ctxResult = resultc
+ go c.watchCtx(resultc)
+ }
+
+ return nil
+}
+
+// watchCtx watches c.ctx until it is able to send a result to resultc.
+//
+// If c.ctx is done before a result can be sent, watchCtx calls c.Cancel,
+// and/or kills cmd.Process it after c.WaitDelay has elapsed.
+//
+// watchCtx manipulates c.goroutineErr, so its result must be received before
+// c.awaitGoroutines is called.
+func (c *Cmd) watchCtx(resultc chan<- ctxResult) {
+ select {
+ case resultc <- ctxResult{}:
+ return
+ case <-c.ctx.Done():
+ }
+
+ var err error
+ if c.Cancel != nil {
+ if interruptErr := c.Cancel(); interruptErr == nil {
+ // We appear to have successfully interrupted the command, so any
+ // program behavior from this point may be due to ctx even if the
+ // command exits with code 0.
+ err = c.ctx.Err()
+ } else if errors.Is(interruptErr, os.ErrProcessDone) {
+ // The process already finished: we just didn't notice it yet.
+ // (Perhaps c.Wait hadn't been called, or perhaps it happened to race with
+ // c.ctx being cancelled.) Don't inject a needless error.
+ } else {
+ err = wrappedError{
+ prefix: "exec: canceling Cmd",
+ err: interruptErr,
+ }
+ }
+ }
+ if c.WaitDelay == 0 {
+ resultc <- ctxResult{err: err}
+ return
+ }
+
+ timer := time.NewTimer(c.WaitDelay)
+ select {
+ case resultc <- ctxResult{err: err, timer: timer}:
+ // c.Process.Wait returned and we've handed the timer off to c.Wait.
+ // It will take care of goroutine shutdown from here.
+ return
+ case <-timer.C:
+ }
+
+ killed := false
+ if killErr := c.Process.Kill(); killErr == nil {
+ // We appear to have killed the process. c.Process.Wait should return a
+ // non-nil error to c.Wait unless the Kill signal races with a successful
+ // exit, and if that does happen we shouldn't report a spurious error,
+ // so don't set err to anything here.
+ killed = true
+ } else if !errors.Is(killErr, os.ErrProcessDone) {
+ err = wrappedError{
+ prefix: "exec: killing Cmd",
+ err: killErr,
+ }
+ }
+
+ if c.goroutineErr != nil {
+ select {
+ case goroutineErr := <-c.goroutineErr:
+ // Forward goroutineErr only if we don't have reason to believe it was
+ // caused by a call to Cancel or Kill above.
+ if err == nil && !killed {
+ err = goroutineErr
+ }
+ default:
+ // Close the child process's I/O pipes, in case it abandoned some
+ // subprocess that inherited them and is still holding them open
+ // (see https://go.dev/issue/23019).
+ //
+ // We close the goroutine pipes only after we have sent any signals we're
+ // going to send to the process (via Signal or Kill above): if we send
+ // SIGKILL to the process, we would prefer for it to die of SIGKILL, not
+ // SIGPIPE. (However, this may still cause any orphaned subprocesses to
+ // terminate with SIGPIPE.)
+ closeDescriptors(c.parentIOPipes)
+ // Wait for the copying goroutines to finish, but report ErrWaitDelay for
+ // the error: any other error here could result from closing the pipes.
+ _ = <-c.goroutineErr
+ if err == nil {
+ err = ErrWaitDelay
+ }
+ }
+
+ // Since we have already received the only result from c.goroutineErr,
+ // set it to nil to prevent awaitGoroutines from blocking on it.
+ c.goroutineErr = nil
+ }
+
+ resultc <- ctxResult{err: err}
+}
+
+// An ExitError reports an unsuccessful exit by a command.
+type ExitError struct {
+ *os.ProcessState
+
+ // Stderr holds a subset of the standard error output from the
+ // Cmd.Output method if standard error was not otherwise being
+ // collected.
+ //
+ // If the error output is long, Stderr may contain only a prefix
+ // and suffix of the output, with the middle replaced with
+ // text about the number of omitted bytes.
+ //
+ // Stderr is provided for debugging, for inclusion in error messages.
+ // Users with other needs should redirect Cmd.Stderr as needed.
+ Stderr []byte
+}
+
+func (e *ExitError) Error() string {
+ return e.ProcessState.String()
+}
+
+// Wait waits for the command to exit and waits for any copying to
+// stdin or copying from stdout or stderr to complete.
+//
+// The command must have been started by Start.
+//
+// The returned error is nil if the command runs, has no problems
+// copying stdin, stdout, and stderr, and exits with a zero exit
+// status.
+//
+// If the command fails to run or doesn't complete successfully, the
+// error is of type *ExitError. Other error types may be
+// returned for I/O problems.
+//
+// If any of c.Stdin, c.Stdout or c.Stderr are not an *os.File, Wait also waits
+// for the respective I/O loop copying to or from the process to complete.
+//
+// Wait releases any resources associated with the Cmd.
+func (c *Cmd) Wait() error {
+ if c.Process == nil {
+ return errors.New("exec: not started")
+ }
+ if c.ProcessState != nil {
+ return errors.New("exec: Wait was already called")
+ }
+
+ state, err := c.Process.Wait()
+ if err == nil && !state.Success() {
+ err = &ExitError{ProcessState: state}
+ }
+ c.ProcessState = state
+
+ var timer *time.Timer
+ if c.ctxResult != nil {
+ watch := <-c.ctxResult
+ timer = watch.timer
+ // If c.Process.Wait returned an error, prefer that.
+ // Otherwise, report any error from the watchCtx goroutine,
+ // such as a Context cancellation or a WaitDelay overrun.
+ if err == nil && watch.err != nil {
+ err = watch.err
+ }
+ }
+
+ if goroutineErr := c.awaitGoroutines(timer); err == nil {
+ // Report an error from the copying goroutines only if the program otherwise
+ // exited normally on its own. Otherwise, the copying error may be due to the
+ // abnormal termination.
+ err = goroutineErr
+ }
+ closeDescriptors(c.parentIOPipes)
+ c.parentIOPipes = nil
+
+ return err
+}
+
+// awaitGoroutines waits for the results of the goroutines copying data to or
+// from the command's I/O pipes.
+//
+// If c.WaitDelay elapses before the goroutines complete, awaitGoroutines
+// forcibly closes their pipes and returns ErrWaitDelay.
+//
+// If timer is non-nil, it must send to timer.C at the end of c.WaitDelay.
+func (c *Cmd) awaitGoroutines(timer *time.Timer) error {
+ defer func() {
+ if timer != nil {
+ timer.Stop()
+ }
+ c.goroutineErr = nil
+ }()
+
+ if c.goroutineErr == nil {
+ return nil // No running goroutines to await.
+ }
+
+ if timer == nil {
+ if c.WaitDelay == 0 {
+ return <-c.goroutineErr
+ }
+
+ select {
+ case err := <-c.goroutineErr:
+ // Avoid the overhead of starting a timer.
+ return err
+ default:
+ }
+
+ // No existing timer was started: either there is no Context associated with
+ // the command, or c.Process.Wait completed before the Context was done.
+ timer = time.NewTimer(c.WaitDelay)
+ }
+
+ select {
+ case <-timer.C:
+ closeDescriptors(c.parentIOPipes)
+ // Wait for the copying goroutines to finish, but ignore any error
+ // (since it was probably caused by closing the pipes).
+ _ = <-c.goroutineErr
+ return ErrWaitDelay
+
+ case err := <-c.goroutineErr:
+ return err
+ }
+}
+
+// Output runs the command and returns its standard output.
+// Any returned error will usually be of type *ExitError.
+// If c.Stderr was nil, Output populates ExitError.Stderr.
+func (c *Cmd) Output() ([]byte, error) {
+ if c.Stdout != nil {
+ return nil, errors.New("exec: Stdout already set")
+ }
+ var stdout bytes.Buffer
+ c.Stdout = &stdout
+
+ captureErr := c.Stderr == nil
+ if captureErr {
+ c.Stderr = &prefixSuffixSaver{N: 32 << 10}
+ }
+
+ err := c.Run()
+ if err != nil && captureErr {
+ if ee, ok := err.(*ExitError); ok {
+ ee.Stderr = c.Stderr.(*prefixSuffixSaver).Bytes()
+ }
+ }
+ return stdout.Bytes(), err
+}
+
+// CombinedOutput runs the command and returns its combined standard
+// output and standard error.
+func (c *Cmd) CombinedOutput() ([]byte, error) {
+ if c.Stdout != nil {
+ return nil, errors.New("exec: Stdout already set")
+ }
+ if c.Stderr != nil {
+ return nil, errors.New("exec: Stderr already set")
+ }
+ var b bytes.Buffer
+ c.Stdout = &b
+ c.Stderr = &b
+ err := c.Run()
+ return b.Bytes(), err
+}
+
+// StdinPipe returns a pipe that will be connected to the command's
+// standard input when the command starts.
+// The pipe will be closed automatically after Wait sees the command exit.
+// A caller need only call Close to force the pipe to close sooner.
+// For example, if the command being run will not exit until standard input
+// is closed, the caller must close the pipe.
+func (c *Cmd) StdinPipe() (io.WriteCloser, error) {
+ if c.Stdin != nil {
+ return nil, errors.New("exec: Stdin already set")
+ }
+ if c.Process != nil {
+ return nil, errors.New("exec: StdinPipe after process started")
+ }
+ pr, pw, err := os.Pipe()
+ if err != nil {
+ return nil, err
+ }
+ c.Stdin = pr
+ c.childIOFiles = append(c.childIOFiles, pr)
+ c.parentIOPipes = append(c.parentIOPipes, pw)
+ return pw, nil
+}
+
+// StdoutPipe returns a pipe that will be connected to the command's
+// standard output when the command starts.
+//
+// Wait will close the pipe after seeing the command exit, so most callers
+// need not close the pipe themselves. It is thus incorrect to call Wait
+// before all reads from the pipe have completed.
+// For the same reason, it is incorrect to call Run when using StdoutPipe.
+// See the example for idiomatic usage.
+func (c *Cmd) StdoutPipe() (io.ReadCloser, error) {
+ if c.Stdout != nil {
+ return nil, errors.New("exec: Stdout already set")
+ }
+ if c.Process != nil {
+ return nil, errors.New("exec: StdoutPipe after process started")
+ }
+ pr, pw, err := os.Pipe()
+ if err != nil {
+ return nil, err
+ }
+ c.Stdout = pw
+ c.childIOFiles = append(c.childIOFiles, pw)
+ c.parentIOPipes = append(c.parentIOPipes, pr)
+ return pr, nil
+}
+
+// StderrPipe returns a pipe that will be connected to the command's
+// standard error when the command starts.
+//
+// Wait will close the pipe after seeing the command exit, so most callers
+// need not close the pipe themselves. It is thus incorrect to call Wait
+// before all reads from the pipe have completed.
+// For the same reason, it is incorrect to use Run when using StderrPipe.
+// See the StdoutPipe example for idiomatic usage.
+func (c *Cmd) StderrPipe() (io.ReadCloser, error) {
+ if c.Stderr != nil {
+ return nil, errors.New("exec: Stderr already set")
+ }
+ if c.Process != nil {
+ return nil, errors.New("exec: StderrPipe after process started")
+ }
+ pr, pw, err := os.Pipe()
+ if err != nil {
+ return nil, err
+ }
+ c.Stderr = pw
+ c.childIOFiles = append(c.childIOFiles, pw)
+ c.parentIOPipes = append(c.parentIOPipes, pr)
+ return pr, nil
+}
+
+// prefixSuffixSaver is an io.Writer which retains the first N bytes
+// and the last N bytes written to it. The Bytes() methods reconstructs
+// it with a pretty error message.
+type prefixSuffixSaver struct {
+ N int // max size of prefix or suffix
+ prefix []byte
+ suffix []byte // ring buffer once len(suffix) == N
+ suffixOff int // offset to write into suffix
+ skipped int64
+
+ // TODO(bradfitz): we could keep one large []byte and use part of it for
+ // the prefix, reserve space for the '... Omitting N bytes ...' message,
+ // then the ring buffer suffix, and just rearrange the ring buffer
+ // suffix when Bytes() is called, but it doesn't seem worth it for
+ // now just for error messages. It's only ~64KB anyway.
+}
+
+func (w *prefixSuffixSaver) Write(p []byte) (n int, err error) {
+ lenp := len(p)
+ p = w.fill(&w.prefix, p)
+
+ // Only keep the last w.N bytes of suffix data.
+ if overage := len(p) - w.N; overage > 0 {
+ p = p[overage:]
+ w.skipped += int64(overage)
+ }
+ p = w.fill(&w.suffix, p)
+
+ // w.suffix is full now if p is non-empty. Overwrite it in a circle.
+ for len(p) > 0 { // 0, 1, or 2 iterations.
+ n := copy(w.suffix[w.suffixOff:], p)
+ p = p[n:]
+ w.skipped += int64(n)
+ w.suffixOff += n
+ if w.suffixOff == w.N {
+ w.suffixOff = 0
+ }
+ }
+ return lenp, nil
+}
+
+// fill appends up to len(p) bytes of p to *dst, such that *dst does not
+// grow larger than w.N. It returns the un-appended suffix of p.
+func (w *prefixSuffixSaver) fill(dst *[]byte, p []byte) (pRemain []byte) {
+ if remain := w.N - len(*dst); remain > 0 {
+ add := minInt(len(p), remain)
+ *dst = append(*dst, p[:add]...)
+ p = p[add:]
+ }
+ return p
+}
+
+func (w *prefixSuffixSaver) Bytes() []byte {
+ if w.suffix == nil {
+ return w.prefix
+ }
+ if w.skipped == 0 {
+ return append(w.prefix, w.suffix...)
+ }
+ var buf bytes.Buffer
+ buf.Grow(len(w.prefix) + len(w.suffix) + 50)
+ buf.Write(w.prefix)
+ buf.WriteString("\n... omitting ")
+ buf.WriteString(strconv.FormatInt(w.skipped, 10))
+ buf.WriteString(" bytes ...\n")
+ buf.Write(w.suffix[w.suffixOff:])
+ buf.Write(w.suffix[:w.suffixOff])
+ return buf.Bytes()
+}
+
+func minInt(a, b int) int {
+ if a < b {
+ return a
+ }
+ return b
+}
+
+// environ returns a best-effort copy of the environment in which the command
+// would be run as it is currently configured. If an error occurs in computing
+// the environment, it is returned alongside the best-effort copy.
+func (c *Cmd) environ() ([]string, error) {
+ var err error
+
+ env := c.Env
+ if env == nil {
+ env, err = execenv.Default(c.SysProcAttr)
+ if err != nil {
+ env = os.Environ()
+ // Note that the non-nil err is preserved despite env being overridden.
+ }
+
+ if c.Dir != "" {
+ switch runtime.GOOS {
+ case "windows", "plan9":
+ // Windows and Plan 9 do not use the PWD variable, so we don't need to
+ // keep it accurate.
+ default:
+ // On POSIX platforms, PWD represents “an absolute pathname of the
+ // current working directory.” Since we are changing the working
+ // directory for the command, we should also update PWD to reflect that.
+ //
+ // Unfortunately, we didn't always do that, so (as proposed in
+ // https://go.dev/issue/50599) to avoid unintended collateral damage we
+ // only implicitly update PWD when Env is nil. That way, we're much
+ // less likely to override an intentional change to the variable.
+ if pwd, absErr := filepath.Abs(c.Dir); absErr == nil {
+ env = append(env, "PWD="+pwd)
+ } else if err == nil {
+ err = absErr
+ }
+ }
+ }
+ }
+
+ env, dedupErr := dedupEnv(env)
+ if err == nil {
+ err = dedupErr
+ }
+ return addCriticalEnv(env), err
+}
+
+// Environ returns a copy of the environment in which the command would be run
+// as it is currently configured.
+func (c *Cmd) Environ() []string {
+ // Intentionally ignore errors: environ returns a best-effort environment no matter what.
+ env, _ := c.environ()
+ return env
+}
+
+// dedupEnv returns a copy of env with any duplicates removed, in favor of
+// later values.
+// Items not of the normal environment "key=value" form are preserved unchanged.
+// Except on Plan 9, items containing NUL characters are removed, and
+// an error is returned along with the remaining values.
+func dedupEnv(env []string) ([]string, error) {
+ return dedupEnvCase(runtime.GOOS == "windows", runtime.GOOS == "plan9", env)
+}
+
+// dedupEnvCase is dedupEnv with a case option for testing.
+// If caseInsensitive is true, the case of keys is ignored.
+// If nulOK is false, items containing NUL characters are allowed.
+func dedupEnvCase(caseInsensitive, nulOK bool, env []string) ([]string, error) {
+ // Construct the output in reverse order, to preserve the
+ // last occurrence of each key.
+ var err error
+ out := make([]string, 0, len(env))
+ saw := make(map[string]bool, len(env))
+ for n := len(env); n > 0; n-- {
+ kv := env[n-1]
+
+ // Reject NUL in environment variables to prevent security issues (#56284);
+ // except on Plan 9, which uses NUL as os.PathListSeparator (#56544).
+ if !nulOK && strings.IndexByte(kv, 0) != -1 {
+ err = errors.New("exec: environment variable contains NUL")
+ continue
+ }
+
+ i := strings.Index(kv, "=")
+ if i == 0 {
+ // We observe in practice keys with a single leading "=" on Windows.
+ // TODO(#49886): Should we consume only the first leading "=" as part
+ // of the key, or parse through arbitrarily many of them until a non-"="?
+ i = strings.Index(kv[1:], "=") + 1
+ }
+ if i < 0 {
+ if kv != "" {
+ // The entry is not of the form "key=value" (as it is required to be).
+ // Leave it as-is for now.
+ // TODO(#52436): should we strip or reject these bogus entries?
+ out = append(out, kv)
+ }
+ continue
+ }
+ k := kv[:i]
+ if caseInsensitive {
+ k = strings.ToLower(k)
+ }
+ if saw[k] {
+ continue
+ }
+
+ saw[k] = true
+ out = append(out, kv)
+ }
+
+ // Now reverse the slice to restore the original order.
+ for i := 0; i < len(out)/2; i++ {
+ j := len(out) - i - 1
+ out[i], out[j] = out[j], out[i]
+ }
+
+ return out, err
+}
+
+// addCriticalEnv adds any critical environment variables that are required
+// (or at least almost always required) on the operating system.
+// Currently this is only used for Windows.
+func addCriticalEnv(env []string) []string {
+ if runtime.GOOS != "windows" {
+ return env
+ }
+ for _, kv := range env {
+ k, _, ok := strings.Cut(kv, "=")
+ if !ok {
+ continue
+ }
+ if strings.EqualFold(k, "SYSTEMROOT") {
+ // We already have it.
+ return env
+ }
+ }
+ return append(env, "SYSTEMROOT="+os.Getenv("SYSTEMROOT"))
+}
+
+// ErrDot indicates that a path lookup resolved to an executable
+// in the current directory due to ‘.’ being in the path, either
+// implicitly or explicitly. See the package documentation for details.
+//
+// Note that functions in this package do not return ErrDot directly.
+// Code should use errors.Is(err, ErrDot), not err == ErrDot,
+// to test whether a returned error err is due to this condition.
+var ErrDot = errors.New("cannot run executable found relative to current directory")
diff --git a/contrib/go/_std_1.20/src/os/exec/exec_unix.go b/contrib/go/_std_1.21/src/os/exec/exec_unix.go
index 3ed672a744..3ed672a744 100644
--- a/contrib/go/_std_1.20/src/os/exec/exec_unix.go
+++ b/contrib/go/_std_1.21/src/os/exec/exec_unix.go
diff --git a/contrib/go/_std_1.20/src/os/exec/exec_windows.go b/contrib/go/_std_1.21/src/os/exec/exec_windows.go
index e7a2ee6c9d..e7a2ee6c9d 100644
--- a/contrib/go/_std_1.20/src/os/exec/exec_windows.go
+++ b/contrib/go/_std_1.21/src/os/exec/exec_windows.go
diff --git a/contrib/go/_std_1.21/src/os/exec/internal/fdtest/exists_unix.go b/contrib/go/_std_1.21/src/os/exec/internal/fdtest/exists_unix.go
new file mode 100644
index 0000000000..472a802d7b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/exec/internal/fdtest/exists_unix.go
@@ -0,0 +1,19 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix || wasm
+
+// Package fdtest provides test helpers for working with file descriptors across exec.
+package fdtest
+
+import (
+ "syscall"
+)
+
+// Exists returns true if fd is a valid file descriptor.
+func Exists(fd uintptr) bool {
+ var s syscall.Stat_t
+ err := syscall.Fstat(int(fd), &s)
+ return err != syscall.EBADF
+}
diff --git a/contrib/go/_std_1.20/src/os/exec/internal/fdtest/exists_windows.go b/contrib/go/_std_1.21/src/os/exec/internal/fdtest/exists_windows.go
index 72b8ccfd23..72b8ccfd23 100644
--- a/contrib/go/_std_1.20/src/os/exec/internal/fdtest/exists_windows.go
+++ b/contrib/go/_std_1.21/src/os/exec/internal/fdtest/exists_windows.go
diff --git a/contrib/go/_std_1.21/src/os/exec/internal/fdtest/ya.make b/contrib/go/_std_1.21/src/os/exec/internal/fdtest/ya.make
new file mode 100644
index 0000000000..a3efa83c55
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/exec/internal/fdtest/ya.make
@@ -0,0 +1,26 @@
+GO_LIBRARY()
+
+GO_TEST_SRCS(exists_test.go)
+
+IF (OS_LINUX)
+ SRCS(
+ exists_unix.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ exists_unix.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ exists_windows.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/os/exec/internal/ya.make b/contrib/go/_std_1.21/src/os/exec/internal/ya.make
index 66dbcf8245..66dbcf8245 100644
--- a/contrib/go/_std_1.20/src/os/exec/internal/ya.make
+++ b/contrib/go/_std_1.21/src/os/exec/internal/ya.make
diff --git a/contrib/go/_std_1.21/src/os/exec/lp_unix.go b/contrib/go/_std_1.21/src/os/exec/lp_unix.go
new file mode 100644
index 0000000000..fd2c6efbef
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/exec/lp_unix.go
@@ -0,0 +1,82 @@
+// Copyright 2010 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.
+
+//go:build unix
+
+package exec
+
+import (
+ "errors"
+ "internal/syscall/unix"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "strings"
+ "syscall"
+)
+
+// ErrNotFound is the error resulting if a path search failed to find an executable file.
+var ErrNotFound = errors.New("executable file not found in $PATH")
+
+func findExecutable(file string) error {
+ d, err := os.Stat(file)
+ if err != nil {
+ return err
+ }
+ m := d.Mode()
+ if m.IsDir() {
+ return syscall.EISDIR
+ }
+ err = unix.Eaccess(file, unix.X_OK)
+ // ENOSYS means Eaccess is not available or not implemented.
+ // EPERM can be returned by Linux containers employing seccomp.
+ // In both cases, fall back to checking the permission bits.
+ if err == nil || (err != syscall.ENOSYS && err != syscall.EPERM) {
+ return err
+ }
+ if m&0111 != 0 {
+ return nil
+ }
+ return fs.ErrPermission
+}
+
+// LookPath searches for an executable named file in the
+// directories named by the PATH environment variable.
+// If file contains a slash, it is tried directly and the PATH is not consulted.
+// Otherwise, on success, the result is an absolute path.
+//
+// In older versions of Go, LookPath could return a path relative to the current directory.
+// As of Go 1.19, LookPath will instead return that path along with an error satisfying
+// errors.Is(err, ErrDot). See the package documentation for more details.
+func LookPath(file string) (string, error) {
+ // NOTE(rsc): I wish we could use the Plan 9 behavior here
+ // (only bypass the path if file begins with / or ./ or ../)
+ // but that would not match all the Unix shells.
+
+ if strings.Contains(file, "/") {
+ err := findExecutable(file)
+ if err == nil {
+ return file, nil
+ }
+ return "", &Error{file, err}
+ }
+ path := os.Getenv("PATH")
+ for _, dir := range filepath.SplitList(path) {
+ if dir == "" {
+ // Unix shell semantics: path element "" means "."
+ dir = "."
+ }
+ path := filepath.Join(dir, file)
+ if err := findExecutable(path); err == nil {
+ if !filepath.IsAbs(path) {
+ if execerrdot.Value() != "0" {
+ return path, &Error{file, ErrDot}
+ }
+ execerrdot.IncNonDefault()
+ }
+ return path, nil
+ }
+ }
+ return "", &Error{file, ErrNotFound}
+}
diff --git a/contrib/go/_std_1.21/src/os/exec/lp_windows.go b/contrib/go/_std_1.21/src/os/exec/lp_windows.go
new file mode 100644
index 0000000000..066d38dfdb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/exec/lp_windows.go
@@ -0,0 +1,145 @@
+// Copyright 2010 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 exec
+
+import (
+ "errors"
+ "io/fs"
+ "os"
+ "path/filepath"
+ "strings"
+ "syscall"
+)
+
+// ErrNotFound is the error resulting if a path search failed to find an executable file.
+var ErrNotFound = errors.New("executable file not found in %PATH%")
+
+func chkStat(file string) error {
+ d, err := os.Stat(file)
+ if err != nil {
+ return err
+ }
+ if d.IsDir() {
+ return fs.ErrPermission
+ }
+ return nil
+}
+
+func hasExt(file string) bool {
+ i := strings.LastIndex(file, ".")
+ if i < 0 {
+ return false
+ }
+ return strings.LastIndexAny(file, `:\/`) < i
+}
+
+func findExecutable(file string, exts []string) (string, error) {
+ if len(exts) == 0 {
+ return file, chkStat(file)
+ }
+ if hasExt(file) {
+ if chkStat(file) == nil {
+ return file, nil
+ }
+ }
+ for _, e := range exts {
+ if f := file + e; chkStat(f) == nil {
+ return f, nil
+ }
+ }
+ return "", fs.ErrNotExist
+}
+
+// LookPath searches for an executable named file in the
+// directories named by the PATH environment variable.
+// LookPath also uses PATHEXT environment variable to match
+// a suitable candidate.
+// If file contains a slash, it is tried directly and the PATH is not consulted.
+// Otherwise, on success, the result is an absolute path.
+//
+// In older versions of Go, LookPath could return a path relative to the current directory.
+// As of Go 1.19, LookPath will instead return that path along with an error satisfying
+// errors.Is(err, ErrDot). See the package documentation for more details.
+func LookPath(file string) (string, error) {
+ var exts []string
+ x := os.Getenv(`PATHEXT`)
+ if x != "" {
+ for _, e := range strings.Split(strings.ToLower(x), `;`) {
+ if e == "" {
+ continue
+ }
+ if e[0] != '.' {
+ e = "." + e
+ }
+ exts = append(exts, e)
+ }
+ } else {
+ exts = []string{".com", ".exe", ".bat", ".cmd"}
+ }
+
+ if strings.ContainsAny(file, `:\/`) {
+ f, err := findExecutable(file, exts)
+ if err == nil {
+ return f, nil
+ }
+ return "", &Error{file, err}
+ }
+
+ // On Windows, creating the NoDefaultCurrentDirectoryInExePath
+ // environment variable (with any value or no value!) signals that
+ // path lookups should skip the current directory.
+ // In theory we are supposed to call NeedCurrentDirectoryForExePathW
+ // "as the registry location of this environment variable can change"
+ // but that seems exceedingly unlikely: it would break all users who
+ // have configured their environment this way!
+ // https://docs.microsoft.com/en-us/windows/win32/api/processenv/nf-processenv-needcurrentdirectoryforexepathw
+ // See also go.dev/issue/43947.
+ var (
+ dotf string
+ dotErr error
+ )
+ if _, found := syscall.Getenv("NoDefaultCurrentDirectoryInExePath"); !found {
+ if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
+ if execerrdot.Value() == "0" {
+ execerrdot.IncNonDefault()
+ return f, nil
+ }
+ dotf, dotErr = f, &Error{file, ErrDot}
+ }
+ }
+
+ path := os.Getenv("path")
+ for _, dir := range filepath.SplitList(path) {
+ if f, err := findExecutable(filepath.Join(dir, file), exts); err == nil {
+ if dotErr != nil {
+ // https://go.dev/issue/53536: if we resolved a relative path implicitly,
+ // and it is the same executable that would be resolved from the explicit %PATH%,
+ // prefer the explicit name for the executable (and, likely, no error) instead
+ // of the equivalent implicit name with ErrDot.
+ //
+ // Otherwise, return the ErrDot for the implicit path as soon as we find
+ // out that the explicit one doesn't match.
+ dotfi, dotfiErr := os.Lstat(dotf)
+ fi, fiErr := os.Lstat(f)
+ if dotfiErr != nil || fiErr != nil || !os.SameFile(dotfi, fi) {
+ return dotf, dotErr
+ }
+ }
+
+ if !filepath.IsAbs(f) {
+ if execerrdot.Value() != "0" {
+ return f, &Error{file, ErrDot}
+ }
+ execerrdot.IncNonDefault()
+ }
+ return f, nil
+ }
+ }
+
+ if dotErr != nil {
+ return dotf, dotErr
+ }
+ return "", &Error{file, ErrNotFound}
+}
diff --git a/contrib/go/_std_1.21/src/os/exec/ya.make b/contrib/go/_std_1.21/src/os/exec/ya.make
new file mode 100644
index 0000000000..686a009ede
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/exec/ya.make
@@ -0,0 +1,66 @@
+GO_LIBRARY()
+
+SRCS(
+ exec.go
+)
+
+GO_TEST_SRCS(
+ bench_test.go
+ env_test.go
+ internal_test.go
+ lp_test.go
+)
+
+GO_XTEST_SRCS(
+ dot_test.go
+ example_test.go
+ exec_test.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ exec_unix.go
+ lp_unix.go
+ )
+
+ GO_TEST_SRCS(lp_unix_test.go)
+
+ GO_XTEST_SRCS(
+ exec_linux_test.go
+ exec_posix_test.go
+ exec_unix_test.go
+ lp_linux_test.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ exec_unix.go
+ lp_unix.go
+ )
+
+ GO_TEST_SRCS(lp_unix_test.go)
+
+ GO_XTEST_SRCS(
+ exec_posix_test.go
+ exec_unix_test.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ exec_windows.go
+ lp_windows.go
+ )
+
+ GO_XTEST_SRCS(
+ exec_windows_test.go
+ lp_windows_test.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+ internal
+)
diff --git a/contrib/go/_std_1.21/src/os/exec_posix.go b/contrib/go/_std_1.21/src/os/exec_posix.go
new file mode 100644
index 0000000000..a512d5199a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/exec_posix.go
@@ -0,0 +1,136 @@
+// Copyright 2009 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package os
+
+import (
+ "internal/itoa"
+ "internal/syscall/execenv"
+ "runtime"
+ "syscall"
+)
+
+// The only signal values guaranteed to be present in the os package on all
+// systems are os.Interrupt (send the process an interrupt) and os.Kill (force
+// the process to exit). On Windows, sending os.Interrupt to a process with
+// os.Process.Signal is not implemented; it will return an error instead of
+// sending a signal.
+var (
+ Interrupt Signal = syscall.SIGINT
+ Kill Signal = syscall.SIGKILL
+)
+
+func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
+ // If there is no SysProcAttr (ie. no Chroot or changed
+ // UID/GID), double-check existence of the directory we want
+ // to chdir into. We can make the error clearer this way.
+ if attr != nil && attr.Sys == nil && attr.Dir != "" {
+ if _, err := Stat(attr.Dir); err != nil {
+ pe := err.(*PathError)
+ pe.Op = "chdir"
+ return nil, pe
+ }
+ }
+
+ sysattr := &syscall.ProcAttr{
+ Dir: attr.Dir,
+ Env: attr.Env,
+ Sys: attr.Sys,
+ }
+ if sysattr.Env == nil {
+ sysattr.Env, err = execenv.Default(sysattr.Sys)
+ if err != nil {
+ return nil, err
+ }
+ }
+ sysattr.Files = make([]uintptr, 0, len(attr.Files))
+ for _, f := range attr.Files {
+ sysattr.Files = append(sysattr.Files, f.Fd())
+ }
+
+ pid, h, e := syscall.StartProcess(name, argv, sysattr)
+
+ // Make sure we don't run the finalizers of attr.Files.
+ runtime.KeepAlive(attr)
+
+ if e != nil {
+ return nil, &PathError{Op: "fork/exec", Path: name, Err: e}
+ }
+
+ return newProcess(pid, h), nil
+}
+
+func (p *Process) kill() error {
+ return p.Signal(Kill)
+}
+
+// ProcessState stores information about a process, as reported by Wait.
+type ProcessState struct {
+ pid int // The process's id.
+ status syscall.WaitStatus // System-dependent status info.
+ rusage *syscall.Rusage
+}
+
+// Pid returns the process id of the exited process.
+func (p *ProcessState) Pid() int {
+ return p.pid
+}
+
+func (p *ProcessState) exited() bool {
+ return p.status.Exited()
+}
+
+func (p *ProcessState) success() bool {
+ return p.status.ExitStatus() == 0
+}
+
+func (p *ProcessState) sys() any {
+ return p.status
+}
+
+func (p *ProcessState) sysUsage() any {
+ return p.rusage
+}
+
+func (p *ProcessState) String() string {
+ if p == nil {
+ return "<nil>"
+ }
+ status := p.Sys().(syscall.WaitStatus)
+ res := ""
+ switch {
+ case status.Exited():
+ code := status.ExitStatus()
+ if runtime.GOOS == "windows" && uint(code) >= 1<<16 { // windows uses large hex numbers
+ res = "exit status " + uitox(uint(code))
+ } else { // unix systems use small decimal integers
+ res = "exit status " + itoa.Itoa(code) // unix
+ }
+ case status.Signaled():
+ res = "signal: " + status.Signal().String()
+ case status.Stopped():
+ res = "stop signal: " + status.StopSignal().String()
+ if status.StopSignal() == syscall.SIGTRAP && status.TrapCause() != 0 {
+ res += " (trap " + itoa.Itoa(status.TrapCause()) + ")"
+ }
+ case status.Continued():
+ res = "continued"
+ }
+ if status.CoreDump() {
+ res += " (core dumped)"
+ }
+ return res
+}
+
+// ExitCode returns the exit code of the exited process, or -1
+// if the process hasn't exited or was terminated by a signal.
+func (p *ProcessState) ExitCode() int {
+ // return -1 if the process hasn't started.
+ if p == nil {
+ return -1
+ }
+ return p.status.ExitStatus()
+}
diff --git a/contrib/go/_std_1.21/src/os/exec_unix.go b/contrib/go/_std_1.21/src/os/exec_unix.go
new file mode 100644
index 0000000000..f9063b4db4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/exec_unix.go
@@ -0,0 +1,106 @@
+// Copyright 2009 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package os
+
+import (
+ "errors"
+ "runtime"
+ "syscall"
+ "time"
+)
+
+func (p *Process) wait() (ps *ProcessState, err error) {
+ if p.Pid == -1 {
+ return nil, syscall.EINVAL
+ }
+
+ // If we can block until Wait4 will succeed immediately, do so.
+ ready, err := p.blockUntilWaitable()
+ if err != nil {
+ return nil, err
+ }
+ if ready {
+ // Mark the process done now, before the call to Wait4,
+ // so that Process.signal will not send a signal.
+ p.setDone()
+ // Acquire a write lock on sigMu to wait for any
+ // active call to the signal method to complete.
+ p.sigMu.Lock()
+ p.sigMu.Unlock()
+ }
+
+ var (
+ status syscall.WaitStatus
+ rusage syscall.Rusage
+ pid1 int
+ e error
+ )
+ for {
+ pid1, e = syscall.Wait4(p.Pid, &status, 0, &rusage)
+ if e != syscall.EINTR {
+ break
+ }
+ }
+ if e != nil {
+ return nil, NewSyscallError("wait", e)
+ }
+ if pid1 != 0 {
+ p.setDone()
+ }
+ ps = &ProcessState{
+ pid: pid1,
+ status: status,
+ rusage: &rusage,
+ }
+ return ps, nil
+}
+
+func (p *Process) signal(sig Signal) error {
+ if p.Pid == -1 {
+ return errors.New("os: process already released")
+ }
+ if p.Pid == 0 {
+ return errors.New("os: process not initialized")
+ }
+ p.sigMu.RLock()
+ defer p.sigMu.RUnlock()
+ if p.done() {
+ return ErrProcessDone
+ }
+ s, ok := sig.(syscall.Signal)
+ if !ok {
+ return errors.New("os: unsupported signal type")
+ }
+ if e := syscall.Kill(p.Pid, s); e != nil {
+ if e == syscall.ESRCH {
+ return ErrProcessDone
+ }
+ return e
+ }
+ return nil
+}
+
+func (p *Process) release() error {
+ // NOOP for unix.
+ p.Pid = -1
+ // no need for a finalizer anymore
+ runtime.SetFinalizer(p, nil)
+ return nil
+}
+
+func findProcess(pid int) (p *Process, err error) {
+ // NOOP for unix.
+ return newProcess(pid, 0), nil
+}
+
+func (p *ProcessState) userTime() time.Duration {
+ return time.Duration(p.rusage.Utime.Nano()) * time.Nanosecond
+}
+
+func (p *ProcessState) systemTime() time.Duration {
+ return time.Duration(p.rusage.Stime.Nano()) * time.Nanosecond
+}
diff --git a/contrib/go/_std_1.20/src/os/exec_windows.go b/contrib/go/_std_1.21/src/os/exec_windows.go
index 239bed198f..239bed198f 100644
--- a/contrib/go/_std_1.20/src/os/exec_windows.go
+++ b/contrib/go/_std_1.21/src/os/exec_windows.go
diff --git a/contrib/go/_std_1.20/src/os/executable.go b/contrib/go/_std_1.21/src/os/executable.go
index cc3134af1c..cc3134af1c 100644
--- a/contrib/go/_std_1.20/src/os/executable.go
+++ b/contrib/go/_std_1.21/src/os/executable.go
diff --git a/contrib/go/_std_1.20/src/os/executable_darwin.go b/contrib/go/_std_1.21/src/os/executable_darwin.go
index dae9f4ee18..dae9f4ee18 100644
--- a/contrib/go/_std_1.20/src/os/executable_darwin.go
+++ b/contrib/go/_std_1.21/src/os/executable_darwin.go
diff --git a/contrib/go/_std_1.21/src/os/executable_procfs.go b/contrib/go/_std_1.21/src/os/executable_procfs.go
new file mode 100644
index 0000000000..94e674e364
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/executable_procfs.go
@@ -0,0 +1,37 @@
+// Copyright 2016 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.
+
+//go:build linux || netbsd
+
+package os
+
+import (
+ "errors"
+ "runtime"
+)
+
+func executable() (string, error) {
+ var procfn string
+ switch runtime.GOOS {
+ default:
+ return "", errors.New("Executable not implemented for " + runtime.GOOS)
+ case "linux", "android":
+ procfn = "/proc/self/exe"
+ case "netbsd":
+ procfn = "/proc/curproc/exe"
+ }
+ path, err := Readlink(procfn)
+
+ // When the executable has been deleted then Readlink returns a
+ // path appended with " (deleted)".
+ return stringsTrimSuffix(path, " (deleted)"), err
+}
+
+// stringsTrimSuffix is the same as strings.TrimSuffix.
+func stringsTrimSuffix(s, suffix string) string {
+ if len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix {
+ return s[:len(s)-len(suffix)]
+ }
+ return s
+}
diff --git a/contrib/go/_std_1.20/src/os/executable_windows.go b/contrib/go/_std_1.21/src/os/executable_windows.go
index fc5cf86005..fc5cf86005 100644
--- a/contrib/go/_std_1.20/src/os/executable_windows.go
+++ b/contrib/go/_std_1.21/src/os/executable_windows.go
diff --git a/contrib/go/_std_1.21/src/os/file.go b/contrib/go/_std_1.21/src/os/file.go
new file mode 100644
index 0000000000..7fd2f5d202
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/file.go
@@ -0,0 +1,770 @@
+// Copyright 2009 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 os provides a platform-independent interface to operating system
+// functionality. The design is Unix-like, although the error handling is
+// Go-like; failing calls return values of type error rather than error numbers.
+// Often, more information is available within the error. For example,
+// if a call that takes a file name fails, such as Open or Stat, the error
+// will include the failing file name when printed and will be of type
+// *PathError, which may be unpacked for more information.
+//
+// The os interface is intended to be uniform across all operating systems.
+// Features not generally available appear in the system-specific package syscall.
+//
+// Here is a simple example, opening a file and reading some of it.
+//
+// file, err := os.Open("file.go") // For read access.
+// if err != nil {
+// log.Fatal(err)
+// }
+//
+// If the open fails, the error string will be self-explanatory, like
+//
+// open file.go: no such file or directory
+//
+// The file's data can then be read into a slice of bytes. Read and
+// Write take their byte counts from the length of the argument slice.
+//
+// data := make([]byte, 100)
+// count, err := file.Read(data)
+// if err != nil {
+// log.Fatal(err)
+// }
+// fmt.Printf("read %d bytes: %q\n", count, data[:count])
+//
+// Note: The maximum number of concurrent operations on a File may be limited by
+// the OS or the system. The number should be high, but exceeding it may degrade
+// performance or cause other issues.
+package os
+
+import (
+ "errors"
+ "internal/poll"
+ "internal/safefilepath"
+ "internal/testlog"
+ "io"
+ "io/fs"
+ "runtime"
+ "syscall"
+ "time"
+ "unsafe"
+)
+
+// Name returns the name of the file as presented to Open.
+func (f *File) Name() string { return f.name }
+
+// Stdin, Stdout, and Stderr are open Files pointing to the standard input,
+// standard output, and standard error file descriptors.
+//
+// Note that the Go runtime writes to standard error for panics and crashes;
+// closing Stderr may cause those messages to go elsewhere, perhaps
+// to a file opened later.
+var (
+ Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
+ Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
+ Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
+)
+
+// Flags to OpenFile wrapping those of the underlying system. Not all
+// flags may be implemented on a given system.
+const (
+ // Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
+ O_RDONLY int = syscall.O_RDONLY // open the file read-only.
+ O_WRONLY int = syscall.O_WRONLY // open the file write-only.
+ O_RDWR int = syscall.O_RDWR // open the file read-write.
+ // The remaining values may be or'ed in to control behavior.
+ O_APPEND int = syscall.O_APPEND // append data to the file when writing.
+ O_CREATE int = syscall.O_CREAT // create a new file if none exists.
+ O_EXCL int = syscall.O_EXCL // used with O_CREATE, file must not exist.
+ O_SYNC int = syscall.O_SYNC // open for synchronous I/O.
+ O_TRUNC int = syscall.O_TRUNC // truncate regular writable file when opened.
+)
+
+// Seek whence values.
+//
+// Deprecated: Use io.SeekStart, io.SeekCurrent, and io.SeekEnd.
+const (
+ SEEK_SET int = 0 // seek relative to the origin of the file
+ SEEK_CUR int = 1 // seek relative to the current offset
+ SEEK_END int = 2 // seek relative to the end
+)
+
+// LinkError records an error during a link or symlink or rename
+// system call and the paths that caused it.
+type LinkError struct {
+ Op string
+ Old string
+ New string
+ Err error
+}
+
+func (e *LinkError) Error() string {
+ return e.Op + " " + e.Old + " " + e.New + ": " + e.Err.Error()
+}
+
+func (e *LinkError) Unwrap() error {
+ return e.Err
+}
+
+// Read reads up to len(b) bytes from the File and stores them in b.
+// It returns the number of bytes read and any error encountered.
+// At end of file, Read returns 0, io.EOF.
+func (f *File) Read(b []byte) (n int, err error) {
+ if err := f.checkValid("read"); err != nil {
+ return 0, err
+ }
+ n, e := f.read(b)
+ return n, f.wrapErr("read", e)
+}
+
+// ReadAt reads len(b) bytes from the File starting at byte offset off.
+// It returns the number of bytes read and the error, if any.
+// ReadAt always returns a non-nil error when n < len(b).
+// At end of file, that error is io.EOF.
+func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
+ if err := f.checkValid("read"); err != nil {
+ return 0, err
+ }
+
+ if off < 0 {
+ return 0, &PathError{Op: "readat", Path: f.name, Err: errors.New("negative offset")}
+ }
+
+ for len(b) > 0 {
+ m, e := f.pread(b, off)
+ if e != nil {
+ err = f.wrapErr("read", e)
+ break
+ }
+ n += m
+ b = b[m:]
+ off += int64(m)
+ }
+ return
+}
+
+// ReadFrom implements io.ReaderFrom.
+func (f *File) ReadFrom(r io.Reader) (n int64, err error) {
+ if err := f.checkValid("write"); err != nil {
+ return 0, err
+ }
+ n, handled, e := f.readFrom(r)
+ if !handled {
+ return genericReadFrom(f, r) // without wrapping
+ }
+ return n, f.wrapErr("write", e)
+}
+
+func genericReadFrom(f *File, r io.Reader) (int64, error) {
+ return io.Copy(fileWithoutReadFrom{f}, r)
+}
+
+// fileWithoutReadFrom implements all the methods of *File other
+// than ReadFrom. This is used to permit ReadFrom to call io.Copy
+// without leading to a recursive call to ReadFrom.
+type fileWithoutReadFrom struct {
+ *File
+}
+
+// This ReadFrom method hides the *File ReadFrom method.
+func (fileWithoutReadFrom) ReadFrom(fileWithoutReadFrom) {
+ panic("unreachable")
+}
+
+// Write writes len(b) bytes from b to the File.
+// It returns the number of bytes written and an error, if any.
+// Write returns a non-nil error when n != len(b).
+func (f *File) Write(b []byte) (n int, err error) {
+ if err := f.checkValid("write"); err != nil {
+ return 0, err
+ }
+ n, e := f.write(b)
+ if n < 0 {
+ n = 0
+ }
+ if n != len(b) {
+ err = io.ErrShortWrite
+ }
+
+ epipecheck(f, e)
+
+ if e != nil {
+ err = f.wrapErr("write", e)
+ }
+
+ return n, err
+}
+
+var errWriteAtInAppendMode = errors.New("os: invalid use of WriteAt on file opened with O_APPEND")
+
+// WriteAt writes len(b) bytes to the File starting at byte offset off.
+// It returns the number of bytes written and an error, if any.
+// WriteAt returns a non-nil error when n != len(b).
+//
+// If file was opened with the O_APPEND flag, WriteAt returns an error.
+func (f *File) WriteAt(b []byte, off int64) (n int, err error) {
+ if err := f.checkValid("write"); err != nil {
+ return 0, err
+ }
+ if f.appendMode {
+ return 0, errWriteAtInAppendMode
+ }
+
+ if off < 0 {
+ return 0, &PathError{Op: "writeat", Path: f.name, Err: errors.New("negative offset")}
+ }
+
+ for len(b) > 0 {
+ m, e := f.pwrite(b, off)
+ if e != nil {
+ err = f.wrapErr("write", e)
+ break
+ }
+ n += m
+ b = b[m:]
+ off += int64(m)
+ }
+ return
+}
+
+// Seek sets the offset for the next Read or Write on file to offset, interpreted
+// according to whence: 0 means relative to the origin of the file, 1 means
+// relative to the current offset, and 2 means relative to the end.
+// It returns the new offset and an error, if any.
+// The behavior of Seek on a file opened with O_APPEND is not specified.
+func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
+ if err := f.checkValid("seek"); err != nil {
+ return 0, err
+ }
+ r, e := f.seek(offset, whence)
+ if e == nil && f.dirinfo != nil && r != 0 {
+ e = syscall.EISDIR
+ }
+ if e != nil {
+ return 0, f.wrapErr("seek", e)
+ }
+ return r, nil
+}
+
+// WriteString is like Write, but writes the contents of string s rather than
+// a slice of bytes.
+func (f *File) WriteString(s string) (n int, err error) {
+ b := unsafe.Slice(unsafe.StringData(s), len(s))
+ return f.Write(b)
+}
+
+// Mkdir creates a new directory with the specified name and permission
+// bits (before umask).
+// If there is an error, it will be of type *PathError.
+func Mkdir(name string, perm FileMode) error {
+ longName := fixLongPath(name)
+ e := ignoringEINTR(func() error {
+ return syscall.Mkdir(longName, syscallMode(perm))
+ })
+
+ if e != nil {
+ return &PathError{Op: "mkdir", Path: name, Err: e}
+ }
+
+ // mkdir(2) itself won't handle the sticky bit on *BSD and Solaris
+ if !supportsCreateWithStickyBit && perm&ModeSticky != 0 {
+ e = setStickyBit(name)
+
+ if e != nil {
+ Remove(name)
+ return e
+ }
+ }
+
+ return nil
+}
+
+// setStickyBit adds ModeSticky to the permission bits of path, non atomic.
+func setStickyBit(name string) error {
+ fi, err := Stat(name)
+ if err != nil {
+ return err
+ }
+ return Chmod(name, fi.Mode()|ModeSticky)
+}
+
+// Chdir changes the current working directory to the named directory.
+// If there is an error, it will be of type *PathError.
+func Chdir(dir string) error {
+ if e := syscall.Chdir(dir); e != nil {
+ testlog.Open(dir) // observe likely non-existent directory
+ return &PathError{Op: "chdir", Path: dir, Err: e}
+ }
+ if log := testlog.Logger(); log != nil {
+ wd, err := Getwd()
+ if err == nil {
+ log.Chdir(wd)
+ }
+ }
+ return nil
+}
+
+// Open opens the named file for reading. If successful, methods on
+// the returned file can be used for reading; the associated file
+// descriptor has mode O_RDONLY.
+// If there is an error, it will be of type *PathError.
+func Open(name string) (*File, error) {
+ return OpenFile(name, O_RDONLY, 0)
+}
+
+// Create creates or truncates the named file. If the file already exists,
+// it is truncated. If the file does not exist, it is created with mode 0666
+// (before umask). If successful, methods on the returned File can
+// be used for I/O; the associated file descriptor has mode O_RDWR.
+// If there is an error, it will be of type *PathError.
+func Create(name string) (*File, error) {
+ return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
+}
+
+// OpenFile is the generalized open call; most users will use Open
+// or Create instead. It opens the named file with specified flag
+// (O_RDONLY etc.). If the file does not exist, and the O_CREATE flag
+// is passed, it is created with mode perm (before umask). If successful,
+// methods on the returned File can be used for I/O.
+// If there is an error, it will be of type *PathError.
+func OpenFile(name string, flag int, perm FileMode) (*File, error) {
+ testlog.Open(name)
+ f, err := openFileNolog(name, flag, perm)
+ if err != nil {
+ return nil, err
+ }
+ f.appendMode = flag&O_APPEND != 0
+
+ return f, nil
+}
+
+// lstat is overridden in tests.
+var lstat = Lstat
+
+// Rename renames (moves) oldpath to newpath.
+// If newpath already exists and is not a directory, Rename replaces it.
+// OS-specific restrictions may apply when oldpath and newpath are in different directories.
+// Even within the same directory, on non-Unix platforms Rename is not an atomic operation.
+// If there is an error, it will be of type *LinkError.
+func Rename(oldpath, newpath string) error {
+ return rename(oldpath, newpath)
+}
+
+// Many functions in package syscall return a count of -1 instead of 0.
+// Using fixCount(call()) instead of call() corrects the count.
+func fixCount(n int, err error) (int, error) {
+ if n < 0 {
+ n = 0
+ }
+ return n, err
+}
+
+// checkWrapErr is the test hook to enable checking unexpected wrapped errors of poll.ErrFileClosing.
+// It is set to true in the export_test.go for tests (including fuzz tests).
+var checkWrapErr = false
+
+// wrapErr wraps an error that occurred during an operation on an open file.
+// It passes io.EOF through unchanged, otherwise converts
+// poll.ErrFileClosing to ErrClosed and wraps the error in a PathError.
+func (f *File) wrapErr(op string, err error) error {
+ if err == nil || err == io.EOF {
+ return err
+ }
+ if err == poll.ErrFileClosing {
+ err = ErrClosed
+ } else if checkWrapErr && errors.Is(err, poll.ErrFileClosing) {
+ panic("unexpected error wrapping poll.ErrFileClosing: " + err.Error())
+ }
+ return &PathError{Op: op, Path: f.name, Err: err}
+}
+
+// TempDir returns the default directory to use for temporary files.
+//
+// On Unix systems, it returns $TMPDIR if non-empty, else /tmp.
+// On Windows, it uses GetTempPath, returning the first non-empty
+// value from %TMP%, %TEMP%, %USERPROFILE%, or the Windows directory.
+// On Plan 9, it returns /tmp.
+//
+// The directory is neither guaranteed to exist nor have accessible
+// permissions.
+func TempDir() string {
+ return tempDir()
+}
+
+// UserCacheDir returns the default root directory to use for user-specific
+// cached data. Users should create their own application-specific subdirectory
+// within this one and use that.
+//
+// On Unix systems, it returns $XDG_CACHE_HOME as specified by
+// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if
+// non-empty, else $HOME/.cache.
+// On Darwin, it returns $HOME/Library/Caches.
+// On Windows, it returns %LocalAppData%.
+// On Plan 9, it returns $home/lib/cache.
+//
+// If the location cannot be determined (for example, $HOME is not defined),
+// then it will return an error.
+func UserCacheDir() (string, error) {
+ var dir string
+
+ switch runtime.GOOS {
+ case "windows":
+ dir = Getenv("LocalAppData")
+ if dir == "" {
+ return "", errors.New("%LocalAppData% is not defined")
+ }
+
+ case "darwin", "ios":
+ dir = Getenv("HOME")
+ if dir == "" {
+ return "", errors.New("$HOME is not defined")
+ }
+ dir += "/Library/Caches"
+
+ case "plan9":
+ dir = Getenv("home")
+ if dir == "" {
+ return "", errors.New("$home is not defined")
+ }
+ dir += "/lib/cache"
+
+ default: // Unix
+ dir = Getenv("XDG_CACHE_HOME")
+ if dir == "" {
+ dir = Getenv("HOME")
+ if dir == "" {
+ return "", errors.New("neither $XDG_CACHE_HOME nor $HOME are defined")
+ }
+ dir += "/.cache"
+ }
+ }
+
+ return dir, nil
+}
+
+// UserConfigDir returns the default root directory to use for user-specific
+// configuration data. Users should create their own application-specific
+// subdirectory within this one and use that.
+//
+// On Unix systems, it returns $XDG_CONFIG_HOME as specified by
+// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html if
+// non-empty, else $HOME/.config.
+// On Darwin, it returns $HOME/Library/Application Support.
+// On Windows, it returns %AppData%.
+// On Plan 9, it returns $home/lib.
+//
+// If the location cannot be determined (for example, $HOME is not defined),
+// then it will return an error.
+func UserConfigDir() (string, error) {
+ var dir string
+
+ switch runtime.GOOS {
+ case "windows":
+ dir = Getenv("AppData")
+ if dir == "" {
+ return "", errors.New("%AppData% is not defined")
+ }
+
+ case "darwin", "ios":
+ dir = Getenv("HOME")
+ if dir == "" {
+ return "", errors.New("$HOME is not defined")
+ }
+ dir += "/Library/Application Support"
+
+ case "plan9":
+ dir = Getenv("home")
+ if dir == "" {
+ return "", errors.New("$home is not defined")
+ }
+ dir += "/lib"
+
+ default: // Unix
+ dir = Getenv("XDG_CONFIG_HOME")
+ if dir == "" {
+ dir = Getenv("HOME")
+ if dir == "" {
+ return "", errors.New("neither $XDG_CONFIG_HOME nor $HOME are defined")
+ }
+ dir += "/.config"
+ }
+ }
+
+ return dir, nil
+}
+
+// UserHomeDir returns the current user's home directory.
+//
+// On Unix, including macOS, it returns the $HOME environment variable.
+// On Windows, it returns %USERPROFILE%.
+// On Plan 9, it returns the $home environment variable.
+//
+// If the expected variable is not set in the environment, UserHomeDir
+// returns either a platform-specific default value or a non-nil error.
+func UserHomeDir() (string, error) {
+ env, enverr := "HOME", "$HOME"
+ switch runtime.GOOS {
+ case "windows":
+ env, enverr = "USERPROFILE", "%userprofile%"
+ case "plan9":
+ env, enverr = "home", "$home"
+ }
+ if v := Getenv(env); v != "" {
+ return v, nil
+ }
+ // On some geese the home directory is not always defined.
+ switch runtime.GOOS {
+ case "android":
+ return "/sdcard", nil
+ case "ios":
+ return "/", nil
+ }
+ return "", errors.New(enverr + " is not defined")
+}
+
+// Chmod changes the mode of the named file to mode.
+// If the file is a symbolic link, it changes the mode of the link's target.
+// If there is an error, it will be of type *PathError.
+//
+// A different subset of the mode bits are used, depending on the
+// operating system.
+//
+// On Unix, the mode's permission bits, ModeSetuid, ModeSetgid, and
+// ModeSticky are used.
+//
+// On Windows, only the 0200 bit (owner writable) of mode is used; it
+// controls whether the file's read-only attribute is set or cleared.
+// The other bits are currently unused. For compatibility with Go 1.12
+// and earlier, use a non-zero mode. Use mode 0400 for a read-only
+// file and 0600 for a readable+writable file.
+//
+// On Plan 9, the mode's permission bits, ModeAppend, ModeExclusive,
+// and ModeTemporary are used.
+func Chmod(name string, mode FileMode) error { return chmod(name, mode) }
+
+// Chmod changes the mode of the file to mode.
+// If there is an error, it will be of type *PathError.
+func (f *File) Chmod(mode FileMode) error { return f.chmod(mode) }
+
+// SetDeadline sets the read and write deadlines for a File.
+// It is equivalent to calling both SetReadDeadline and SetWriteDeadline.
+//
+// Only some kinds of files support setting a deadline. Calls to SetDeadline
+// for files that do not support deadlines will return ErrNoDeadline.
+// On most systems ordinary files do not support deadlines, but pipes do.
+//
+// A deadline is an absolute time after which I/O operations fail with an
+// error instead of blocking. The deadline applies to all future and pending
+// I/O, not just the immediately following call to Read or Write.
+// After a deadline has been exceeded, the connection can be refreshed
+// by setting a deadline in the future.
+//
+// If the deadline is exceeded a call to Read or Write or to other I/O
+// methods will return an error that wraps ErrDeadlineExceeded.
+// This can be tested using errors.Is(err, os.ErrDeadlineExceeded).
+// That error implements the Timeout method, and calling the Timeout
+// method will return true, but there are other possible errors for which
+// the Timeout will return true even if the deadline has not been exceeded.
+//
+// An idle timeout can be implemented by repeatedly extending
+// the deadline after successful Read or Write calls.
+//
+// A zero value for t means I/O operations will not time out.
+func (f *File) SetDeadline(t time.Time) error {
+ return f.setDeadline(t)
+}
+
+// SetReadDeadline sets the deadline for future Read calls and any
+// currently-blocked Read call.
+// A zero value for t means Read will not time out.
+// Not all files support setting deadlines; see SetDeadline.
+func (f *File) SetReadDeadline(t time.Time) error {
+ return f.setReadDeadline(t)
+}
+
+// SetWriteDeadline sets the deadline for any future Write calls and any
+// currently-blocked Write call.
+// Even if Write times out, it may return n > 0, indicating that
+// some of the data was successfully written.
+// A zero value for t means Write will not time out.
+// Not all files support setting deadlines; see SetDeadline.
+func (f *File) SetWriteDeadline(t time.Time) error {
+ return f.setWriteDeadline(t)
+}
+
+// SyscallConn returns a raw file.
+// This implements the syscall.Conn interface.
+func (f *File) SyscallConn() (syscall.RawConn, error) {
+ if err := f.checkValid("SyscallConn"); err != nil {
+ return nil, err
+ }
+ return newRawConn(f)
+}
+
+// DirFS returns a file system (an fs.FS) for the tree of files rooted at the directory dir.
+//
+// Note that DirFS("/prefix") only guarantees that the Open calls it makes to the
+// operating system will begin with "/prefix": DirFS("/prefix").Open("file") is the
+// same as os.Open("/prefix/file"). So if /prefix/file is a symbolic link pointing outside
+// the /prefix tree, then using DirFS does not stop the access any more than using
+// os.Open does. Additionally, the root of the fs.FS returned for a relative path,
+// DirFS("prefix"), will be affected by later calls to Chdir. DirFS is therefore not
+// a general substitute for a chroot-style security mechanism when the directory tree
+// contains arbitrary content.
+//
+// The directory dir must not be "".
+//
+// The result implements [io/fs.StatFS], [io/fs.ReadFileFS] and
+// [io/fs.ReadDirFS].
+func DirFS(dir string) fs.FS {
+ return dirFS(dir)
+}
+
+// containsAny reports whether any bytes in chars are within s.
+func containsAny(s, chars string) bool {
+ for i := 0; i < len(s); i++ {
+ for j := 0; j < len(chars); j++ {
+ if s[i] == chars[j] {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+type dirFS string
+
+func (dir dirFS) Open(name string) (fs.File, error) {
+ fullname, err := dir.join(name)
+ if err != nil {
+ return nil, &PathError{Op: "stat", Path: name, Err: err}
+ }
+ f, err := Open(fullname)
+ if err != nil {
+ // DirFS takes a string appropriate for GOOS,
+ // while the name argument here is always slash separated.
+ // dir.join will have mixed the two; undo that for
+ // error reporting.
+ err.(*PathError).Path = name
+ return nil, err
+ }
+ return f, nil
+}
+
+// The ReadFile method calls the [ReadFile] function for the file
+// with the given name in the directory. The function provides
+// robust handling for small files and special file systems.
+// Through this method, dirFS implements [io/fs.ReadFileFS].
+func (dir dirFS) ReadFile(name string) ([]byte, error) {
+ fullname, err := dir.join(name)
+ if err != nil {
+ return nil, &PathError{Op: "readfile", Path: name, Err: err}
+ }
+ return ReadFile(fullname)
+}
+
+// ReadDir reads the named directory, returning all its directory entries sorted
+// by filename. Through this method, dirFS implements [io/fs.ReadDirFS].
+func (dir dirFS) ReadDir(name string) ([]DirEntry, error) {
+ fullname, err := dir.join(name)
+ if err != nil {
+ return nil, &PathError{Op: "readdir", Path: name, Err: err}
+ }
+ return ReadDir(fullname)
+}
+
+func (dir dirFS) Stat(name string) (fs.FileInfo, error) {
+ fullname, err := dir.join(name)
+ if err != nil {
+ return nil, &PathError{Op: "stat", Path: name, Err: err}
+ }
+ f, err := Stat(fullname)
+ if err != nil {
+ // See comment in dirFS.Open.
+ err.(*PathError).Path = name
+ return nil, err
+ }
+ return f, nil
+}
+
+// join returns the path for name in dir.
+func (dir dirFS) join(name string) (string, error) {
+ if dir == "" {
+ return "", errors.New("os: DirFS with empty root")
+ }
+ if !fs.ValidPath(name) {
+ return "", ErrInvalid
+ }
+ name, err := safefilepath.FromFS(name)
+ if err != nil {
+ return "", ErrInvalid
+ }
+ if IsPathSeparator(dir[len(dir)-1]) {
+ return string(dir) + name, nil
+ }
+ return string(dir) + string(PathSeparator) + name, nil
+}
+
+// ReadFile reads the named file and returns the contents.
+// A successful call returns err == nil, not err == EOF.
+// Because ReadFile reads the whole file, it does not treat an EOF from Read
+// as an error to be reported.
+func ReadFile(name string) ([]byte, error) {
+ f, err := Open(name)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ var size int
+ if info, err := f.Stat(); err == nil {
+ size64 := info.Size()
+ if int64(int(size64)) == size64 {
+ size = int(size64)
+ }
+ }
+ size++ // one byte for final read at EOF
+
+ // If a file claims a small size, read at least 512 bytes.
+ // In particular, files in Linux's /proc claim size 0 but
+ // then do not work right if read in small pieces,
+ // so an initial read of 1 byte would not work correctly.
+ if size < 512 {
+ size = 512
+ }
+
+ data := make([]byte, 0, size)
+ for {
+ if len(data) >= cap(data) {
+ d := append(data[:cap(data)], 0)
+ data = d[:len(data)]
+ }
+ n, err := f.Read(data[len(data):cap(data)])
+ data = data[:len(data)+n]
+ if err != nil {
+ if err == io.EOF {
+ err = nil
+ }
+ return data, err
+ }
+ }
+}
+
+// WriteFile writes data to the named file, creating it if necessary.
+// If the file does not exist, WriteFile creates it with permissions perm (before umask);
+// otherwise WriteFile truncates it before writing, without changing permissions.
+// Since WriteFile requires multiple system calls to complete, a failure mid-operation
+// can leave the file in a partially written state.
+func WriteFile(name string, data []byte, perm FileMode) error {
+ f, err := OpenFile(name, O_WRONLY|O_CREATE|O_TRUNC, perm)
+ if err != nil {
+ return err
+ }
+ _, err = f.Write(data)
+ if err1 := f.Close(); err1 != nil && err == nil {
+ err = err1
+ }
+ return err
+}
diff --git a/contrib/go/_std_1.21/src/os/file_open_unix.go b/contrib/go/_std_1.21/src/os/file_open_unix.go
new file mode 100644
index 0000000000..a3336eac81
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/file_open_unix.go
@@ -0,0 +1,17 @@
+// Copyright 2023 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.
+
+//go:build unix || (js && wasm)
+
+package os
+
+import (
+ "internal/poll"
+ "syscall"
+)
+
+func open(path string, flag int, perm uint32) (int, poll.SysFile, error) {
+ fd, err := syscall.Open(path, flag, perm)
+ return fd, poll.SysFile{}, err
+}
diff --git a/contrib/go/_std_1.21/src/os/file_posix.go b/contrib/go/_std_1.21/src/os/file_posix.go
new file mode 100644
index 0000000000..5692657753
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/file_posix.go
@@ -0,0 +1,256 @@
+// Copyright 2009 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package os
+
+import (
+ "runtime"
+ "syscall"
+ "time"
+)
+
+// Close closes the File, rendering it unusable for I/O.
+// On files that support SetDeadline, any pending I/O operations will
+// be canceled and return immediately with an ErrClosed error.
+// Close will return an error if it has already been called.
+func (f *File) Close() error {
+ if f == nil {
+ return ErrInvalid
+ }
+ return f.file.close()
+}
+
+// read reads up to len(b) bytes from the File.
+// It returns the number of bytes read and an error, if any.
+func (f *File) read(b []byte) (n int, err error) {
+ n, err = f.pfd.Read(b)
+ runtime.KeepAlive(f)
+ return n, err
+}
+
+// pread reads len(b) bytes from the File starting at byte offset off.
+// It returns the number of bytes read and the error, if any.
+// EOF is signaled by a zero count with err set to nil.
+func (f *File) pread(b []byte, off int64) (n int, err error) {
+ n, err = f.pfd.Pread(b, off)
+ runtime.KeepAlive(f)
+ return n, err
+}
+
+// write writes len(b) bytes to the File.
+// It returns the number of bytes written and an error, if any.
+func (f *File) write(b []byte) (n int, err error) {
+ n, err = f.pfd.Write(b)
+ runtime.KeepAlive(f)
+ return n, err
+}
+
+// pwrite writes len(b) bytes to the File starting at byte offset off.
+// It returns the number of bytes written and an error, if any.
+func (f *File) pwrite(b []byte, off int64) (n int, err error) {
+ n, err = f.pfd.Pwrite(b, off)
+ runtime.KeepAlive(f)
+ return n, err
+}
+
+// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
+func syscallMode(i FileMode) (o uint32) {
+ o |= uint32(i.Perm())
+ if i&ModeSetuid != 0 {
+ o |= syscall.S_ISUID
+ }
+ if i&ModeSetgid != 0 {
+ o |= syscall.S_ISGID
+ }
+ if i&ModeSticky != 0 {
+ o |= syscall.S_ISVTX
+ }
+ // No mapping for Go's ModeTemporary (plan9 only).
+ return
+}
+
+// See docs in file.go:Chmod.
+func chmod(name string, mode FileMode) error {
+ longName := fixLongPath(name)
+ e := ignoringEINTR(func() error {
+ return syscall.Chmod(longName, syscallMode(mode))
+ })
+ if e != nil {
+ return &PathError{Op: "chmod", Path: name, Err: e}
+ }
+ return nil
+}
+
+// See docs in file.go:(*File).Chmod.
+func (f *File) chmod(mode FileMode) error {
+ if err := f.checkValid("chmod"); err != nil {
+ return err
+ }
+ if e := f.pfd.Fchmod(syscallMode(mode)); e != nil {
+ return f.wrapErr("chmod", e)
+ }
+ return nil
+}
+
+// Chown changes the numeric uid and gid of the named file.
+// If the file is a symbolic link, it changes the uid and gid of the link's target.
+// A uid or gid of -1 means to not change that value.
+// If there is an error, it will be of type *PathError.
+//
+// On Windows or Plan 9, Chown always returns the syscall.EWINDOWS or
+// EPLAN9 error, wrapped in *PathError.
+func Chown(name string, uid, gid int) error {
+ e := ignoringEINTR(func() error {
+ return syscall.Chown(name, uid, gid)
+ })
+ if e != nil {
+ return &PathError{Op: "chown", Path: name, Err: e}
+ }
+ return nil
+}
+
+// Lchown changes the numeric uid and gid of the named file.
+// If the file is a symbolic link, it changes the uid and gid of the link itself.
+// If there is an error, it will be of type *PathError.
+//
+// On Windows, it always returns the syscall.EWINDOWS error, wrapped
+// in *PathError.
+func Lchown(name string, uid, gid int) error {
+ e := ignoringEINTR(func() error {
+ return syscall.Lchown(name, uid, gid)
+ })
+ if e != nil {
+ return &PathError{Op: "lchown", Path: name, Err: e}
+ }
+ return nil
+}
+
+// Chown changes the numeric uid and gid of the named file.
+// If there is an error, it will be of type *PathError.
+//
+// On Windows, it always returns the syscall.EWINDOWS error, wrapped
+// in *PathError.
+func (f *File) Chown(uid, gid int) error {
+ if err := f.checkValid("chown"); err != nil {
+ return err
+ }
+ if e := f.pfd.Fchown(uid, gid); e != nil {
+ return f.wrapErr("chown", e)
+ }
+ return nil
+}
+
+// Truncate changes the size of the file.
+// It does not change the I/O offset.
+// If there is an error, it will be of type *PathError.
+func (f *File) Truncate(size int64) error {
+ if err := f.checkValid("truncate"); err != nil {
+ return err
+ }
+ if e := f.pfd.Ftruncate(size); e != nil {
+ return f.wrapErr("truncate", e)
+ }
+ return nil
+}
+
+// Sync commits the current contents of the file to stable storage.
+// Typically, this means flushing the file system's in-memory copy
+// of recently written data to disk.
+func (f *File) Sync() error {
+ if err := f.checkValid("sync"); err != nil {
+ return err
+ }
+ if e := f.pfd.Fsync(); e != nil {
+ return f.wrapErr("sync", e)
+ }
+ return nil
+}
+
+// Chtimes changes the access and modification times of the named
+// file, similar to the Unix utime() or utimes() functions.
+// A zero time.Time value will leave the corresponding file time unchanged.
+//
+// The underlying filesystem may truncate or round the values to a
+// less precise time unit.
+// If there is an error, it will be of type *PathError.
+func Chtimes(name string, atime time.Time, mtime time.Time) error {
+ var utimes [2]syscall.Timespec
+ set := func(i int, t time.Time) {
+ if t.IsZero() {
+ utimes[i] = syscall.Timespec{Sec: _UTIME_OMIT, Nsec: _UTIME_OMIT}
+ } else {
+ utimes[i] = syscall.NsecToTimespec(t.UnixNano())
+ }
+ }
+ set(0, atime)
+ set(1, mtime)
+ if e := syscall.UtimesNano(fixLongPath(name), utimes[0:]); e != nil {
+ return &PathError{Op: "chtimes", Path: name, Err: e}
+ }
+ return nil
+}
+
+// Chdir changes the current working directory to the file,
+// which must be a directory.
+// If there is an error, it will be of type *PathError.
+func (f *File) Chdir() error {
+ if err := f.checkValid("chdir"); err != nil {
+ return err
+ }
+ if e := f.pfd.Fchdir(); e != nil {
+ return f.wrapErr("chdir", e)
+ }
+ return nil
+}
+
+// setDeadline sets the read and write deadline.
+func (f *File) setDeadline(t time.Time) error {
+ if err := f.checkValid("SetDeadline"); err != nil {
+ return err
+ }
+ return f.pfd.SetDeadline(t)
+}
+
+// setReadDeadline sets the read deadline.
+func (f *File) setReadDeadline(t time.Time) error {
+ if err := f.checkValid("SetReadDeadline"); err != nil {
+ return err
+ }
+ return f.pfd.SetReadDeadline(t)
+}
+
+// setWriteDeadline sets the write deadline.
+func (f *File) setWriteDeadline(t time.Time) error {
+ if err := f.checkValid("SetWriteDeadline"); err != nil {
+ return err
+ }
+ return f.pfd.SetWriteDeadline(t)
+}
+
+// checkValid checks whether f is valid for use.
+// If not, it returns an appropriate error, perhaps incorporating the operation name op.
+func (f *File) checkValid(op string) error {
+ if f == nil {
+ return ErrInvalid
+ }
+ return nil
+}
+
+// ignoringEINTR makes a function call and repeats it if it returns an
+// EINTR error. This appears to be required even though we install all
+// signal handlers with SA_RESTART: see #22838, #38033, #38836, #40846.
+// Also #20400 and #36644 are issues in which a signal handler is
+// installed without setting SA_RESTART. None of these are the common case,
+// but there are enough of them that it seems that we can't avoid
+// an EINTR loop.
+func ignoringEINTR(fn func() error) error {
+ for {
+ err := fn()
+ if err != syscall.EINTR {
+ return err
+ }
+ }
+}
diff --git a/contrib/go/_std_1.21/src/os/file_unix.go b/contrib/go/_std_1.21/src/os/file_unix.go
new file mode 100644
index 0000000000..fc711c1edd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/file_unix.go
@@ -0,0 +1,498 @@
+// Copyright 2009 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package os
+
+import (
+ "internal/poll"
+ "internal/syscall/unix"
+ "io/fs"
+ "runtime"
+ "syscall"
+ _ "unsafe" // for go:linkname
+
+)
+
+const _UTIME_OMIT = unix.UTIME_OMIT
+
+// fixLongPath is a noop on non-Windows platforms.
+func fixLongPath(path string) string {
+ return path
+}
+
+func rename(oldname, newname string) error {
+ fi, err := Lstat(newname)
+ if err == nil && fi.IsDir() {
+ // There are two independent errors this function can return:
+ // one for a bad oldname, and one for a bad newname.
+ // At this point we've determined the newname is bad.
+ // But just in case oldname is also bad, prioritize returning
+ // the oldname error because that's what we did historically.
+ // However, if the old name and new name are not the same, yet
+ // they refer to the same file, it implies a case-only
+ // rename on a case-insensitive filesystem, which is ok.
+ if ofi, err := Lstat(oldname); err != nil {
+ if pe, ok := err.(*PathError); ok {
+ err = pe.Err
+ }
+ return &LinkError{"rename", oldname, newname, err}
+ } else if newname == oldname || !SameFile(fi, ofi) {
+ return &LinkError{"rename", oldname, newname, syscall.EEXIST}
+ }
+ }
+ err = ignoringEINTR(func() error {
+ return syscall.Rename(oldname, newname)
+ })
+ if err != nil {
+ return &LinkError{"rename", oldname, newname, err}
+ }
+ return nil
+}
+
+// file is the real representation of *File.
+// The extra level of indirection ensures that no clients of os
+// can overwrite this data, which could cause the finalizer
+// to close the wrong file descriptor.
+type file struct {
+ pfd poll.FD
+ name string
+ dirinfo *dirInfo // nil unless directory being read
+ nonblock bool // whether we set nonblocking mode
+ stdoutOrErr bool // whether this is stdout or stderr
+ appendMode bool // whether file is opened for appending
+}
+
+// Fd returns the integer Unix file descriptor referencing the open file.
+// If f is closed, the file descriptor becomes invalid.
+// If f is garbage collected, a finalizer may close the file descriptor,
+// making it invalid; see runtime.SetFinalizer for more information on when
+// a finalizer might be run. On Unix systems this will cause the SetDeadline
+// methods to stop working.
+// Because file descriptors can be reused, the returned file descriptor may
+// only be closed through the Close method of f, or by its finalizer during
+// garbage collection. Otherwise, during garbage collection the finalizer
+// may close an unrelated file descriptor with the same (reused) number.
+//
+// As an alternative, see the f.SyscallConn method.
+func (f *File) Fd() uintptr {
+ if f == nil {
+ return ^(uintptr(0))
+ }
+
+ // If we put the file descriptor into nonblocking mode,
+ // then set it to blocking mode before we return it,
+ // because historically we have always returned a descriptor
+ // opened in blocking mode. The File will continue to work,
+ // but any blocking operation will tie up a thread.
+ if f.nonblock {
+ f.pfd.SetBlocking()
+ }
+
+ return uintptr(f.pfd.Sysfd)
+}
+
+// NewFile returns a new File with the given file descriptor and
+// name. The returned value will be nil if fd is not a valid file
+// descriptor. On Unix systems, if the file descriptor is in
+// non-blocking mode, NewFile will attempt to return a pollable File
+// (one for which the SetDeadline methods work).
+//
+// After passing it to NewFile, fd may become invalid under the same
+// conditions described in the comments of the Fd method, and the same
+// constraints apply.
+func NewFile(fd uintptr, name string) *File {
+ fdi := int(fd)
+ if fdi < 0 {
+ return nil
+ }
+
+ kind := kindNewFile
+ appendMode := false
+ if flags, err := unix.Fcntl(fdi, syscall.F_GETFL, 0); err == nil {
+ if unix.HasNonblockFlag(flags) {
+ kind = kindNonBlock
+ }
+ appendMode = flags&syscall.O_APPEND != 0
+ }
+ f := newFile(fdi, name, kind)
+ f.appendMode = appendMode
+ return f
+}
+
+// net_newUnixFile is a hidden entry point called by net.conn.File.
+// This is used so that a nonblocking network connection will become
+// blocking if code calls the Fd method. We don't want that for direct
+// calls to NewFile: passing a nonblocking descriptor to NewFile should
+// remain nonblocking if you get it back using Fd. But for net.conn.File
+// the call to NewFile is hidden from the user. Historically in that case
+// the Fd method has returned a blocking descriptor, and we want to
+// retain that behavior because existing code expects it and depends on it.
+//
+//go:linkname net_newUnixFile net.newUnixFile
+func net_newUnixFile(fd int, name string) *File {
+ if fd < 0 {
+ panic("invalid FD")
+ }
+
+ f := newFile(fd, name, kindNonBlock)
+ f.nonblock = true // tell Fd to return blocking descriptor
+ return f
+}
+
+// newFileKind describes the kind of file to newFile.
+type newFileKind int
+
+const (
+ // kindNewFile means that the descriptor was passed to us via NewFile.
+ kindNewFile newFileKind = iota
+ // kindOpenFile means that the descriptor was opened using
+ // Open, Create, or OpenFile (without O_NONBLOCK).
+ kindOpenFile
+ // kindPipe means that the descriptor was opened using Pipe.
+ kindPipe
+ // kindNonBlock means that the descriptor is already in
+ // non-blocking mode.
+ kindNonBlock
+ // kindNoPoll means that we should not put the descriptor into
+ // non-blocking mode, because we know it is not a pipe or FIFO.
+ // Used by openFdAt for directories.
+ kindNoPoll
+)
+
+// newFile is like NewFile, but if called from OpenFile or Pipe
+// (as passed in the kind parameter) it tries to add the file to
+// the runtime poller.
+func newFile(fd int, name string, kind newFileKind) *File {
+ f := &File{&file{
+ pfd: poll.FD{
+ Sysfd: fd,
+ IsStream: true,
+ ZeroReadIsEOF: true,
+ },
+ name: name,
+ stdoutOrErr: fd == 1 || fd == 2,
+ }}
+
+ pollable := kind == kindOpenFile || kind == kindPipe || kind == kindNonBlock
+
+ // If the caller passed a non-blocking filedes (kindNonBlock),
+ // we assume they know what they are doing so we allow it to be
+ // used with kqueue.
+ if kind == kindOpenFile {
+ switch runtime.GOOS {
+ case "darwin", "ios", "dragonfly", "freebsd", "netbsd", "openbsd":
+ var st syscall.Stat_t
+ err := ignoringEINTR(func() error {
+ return syscall.Fstat(fd, &st)
+ })
+ typ := st.Mode & syscall.S_IFMT
+ // Don't try to use kqueue with regular files on *BSDs.
+ // On FreeBSD a regular file is always
+ // reported as ready for writing.
+ // On Dragonfly, NetBSD and OpenBSD the fd is signaled
+ // only once as ready (both read and write).
+ // Issue 19093.
+ // Also don't add directories to the netpoller.
+ if err == nil && (typ == syscall.S_IFREG || typ == syscall.S_IFDIR) {
+ pollable = false
+ }
+
+ // In addition to the behavior described above for regular files,
+ // on Darwin, kqueue does not work properly with fifos:
+ // closing the last writer does not cause a kqueue event
+ // for any readers. See issue #24164.
+ if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && typ == syscall.S_IFIFO {
+ pollable = false
+ }
+ }
+ }
+
+ clearNonBlock := false
+ if pollable {
+ if kind == kindNonBlock {
+ // The descriptor is already in non-blocking mode.
+ // We only set f.nonblock if we put the file into
+ // non-blocking mode.
+ } else if err := syscall.SetNonblock(fd, true); err == nil {
+ f.nonblock = true
+ clearNonBlock = true
+ } else {
+ pollable = false
+ }
+ }
+
+ // An error here indicates a failure to register
+ // with the netpoll system. That can happen for
+ // a file descriptor that is not supported by
+ // epoll/kqueue; for example, disk files on
+ // Linux systems. We assume that any real error
+ // will show up in later I/O.
+ // We do restore the blocking behavior if it was set by us.
+ if pollErr := f.pfd.Init("file", pollable); pollErr != nil && clearNonBlock {
+ if err := syscall.SetNonblock(fd, false); err == nil {
+ f.nonblock = false
+ }
+ }
+
+ runtime.SetFinalizer(f.file, (*file).close)
+ return f
+}
+
+func sigpipe() // implemented in package runtime
+
+// epipecheck raises SIGPIPE if we get an EPIPE error on standard
+// output or standard error. See the SIGPIPE docs in os/signal, and
+// issue 11845.
+func epipecheck(file *File, e error) {
+ if e == syscall.EPIPE && file.stdoutOrErr {
+ sigpipe()
+ }
+}
+
+// DevNull is the name of the operating system's “null device.”
+// On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
+const DevNull = "/dev/null"
+
+// openFileNolog is the Unix implementation of OpenFile.
+// Changes here should be reflected in openFdAt, if relevant.
+func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
+ setSticky := false
+ if !supportsCreateWithStickyBit && flag&O_CREATE != 0 && perm&ModeSticky != 0 {
+ if _, err := Stat(name); IsNotExist(err) {
+ setSticky = true
+ }
+ }
+
+ var r int
+ var s poll.SysFile
+ for {
+ var e error
+ r, s, e = open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
+ if e == nil {
+ break
+ }
+
+ // We have to check EINTR here, per issues 11180 and 39237.
+ if e == syscall.EINTR {
+ continue
+ }
+
+ return nil, &PathError{Op: "open", Path: name, Err: e}
+ }
+
+ // open(2) itself won't handle the sticky bit on *BSD and Solaris
+ if setSticky {
+ setStickyBit(name)
+ }
+
+ // There's a race here with fork/exec, which we are
+ // content to live with. See ../syscall/exec_unix.go.
+ if !supportsCloseOnExec {
+ syscall.CloseOnExec(r)
+ }
+
+ kind := kindOpenFile
+ if unix.HasNonblockFlag(flag) {
+ kind = kindNonBlock
+ }
+
+ f := newFile(r, name, kind)
+ f.pfd.SysFile = s
+ return f, nil
+}
+
+func (file *file) close() error {
+ if file == nil {
+ return syscall.EINVAL
+ }
+ if file.dirinfo != nil {
+ file.dirinfo.close()
+ file.dirinfo = nil
+ }
+ var err error
+ if e := file.pfd.Close(); e != nil {
+ if e == poll.ErrFileClosing {
+ e = ErrClosed
+ }
+ err = &PathError{Op: "close", Path: file.name, Err: e}
+ }
+
+ // no need for a finalizer anymore
+ runtime.SetFinalizer(file, nil)
+ return err
+}
+
+// seek sets the offset for the next Read or Write on file to offset, interpreted
+// according to whence: 0 means relative to the origin of the file, 1 means
+// relative to the current offset, and 2 means relative to the end.
+// It returns the new offset and an error, if any.
+func (f *File) seek(offset int64, whence int) (ret int64, err error) {
+ if f.dirinfo != nil {
+ // Free cached dirinfo, so we allocate a new one if we
+ // access this file as a directory again. See #35767 and #37161.
+ f.dirinfo.close()
+ f.dirinfo = nil
+ }
+ ret, err = f.pfd.Seek(offset, whence)
+ runtime.KeepAlive(f)
+ return ret, err
+}
+
+// Truncate changes the size of the named file.
+// If the file is a symbolic link, it changes the size of the link's target.
+// If there is an error, it will be of type *PathError.
+func Truncate(name string, size int64) error {
+ e := ignoringEINTR(func() error {
+ return syscall.Truncate(name, size)
+ })
+ if e != nil {
+ return &PathError{Op: "truncate", Path: name, Err: e}
+ }
+ return nil
+}
+
+// Remove removes the named file or (empty) directory.
+// If there is an error, it will be of type *PathError.
+func Remove(name string) error {
+ // System call interface forces us to know
+ // whether name is a file or directory.
+ // Try both: it is cheaper on average than
+ // doing a Stat plus the right one.
+ e := ignoringEINTR(func() error {
+ return syscall.Unlink(name)
+ })
+ if e == nil {
+ return nil
+ }
+ e1 := ignoringEINTR(func() error {
+ return syscall.Rmdir(name)
+ })
+ if e1 == nil {
+ return nil
+ }
+
+ // Both failed: figure out which error to return.
+ // OS X and Linux differ on whether unlink(dir)
+ // returns EISDIR, so can't use that. However,
+ // both agree that rmdir(file) returns ENOTDIR,
+ // so we can use that to decide which error is real.
+ // Rmdir might also return ENOTDIR if given a bad
+ // file path, like /etc/passwd/foo, but in that case,
+ // both errors will be ENOTDIR, so it's okay to
+ // use the error from unlink.
+ if e1 != syscall.ENOTDIR {
+ e = e1
+ }
+ return &PathError{Op: "remove", Path: name, Err: e}
+}
+
+func tempDir() string {
+ dir := Getenv("TMPDIR")
+ if dir == "" {
+ if runtime.GOOS == "android" {
+ dir = "/data/local/tmp"
+ } else {
+ dir = "/tmp"
+ }
+ }
+ return dir
+}
+
+// Link creates newname as a hard link to the oldname file.
+// If there is an error, it will be of type *LinkError.
+func Link(oldname, newname string) error {
+ e := ignoringEINTR(func() error {
+ return syscall.Link(oldname, newname)
+ })
+ if e != nil {
+ return &LinkError{"link", oldname, newname, e}
+ }
+ return nil
+}
+
+// Symlink creates newname as a symbolic link to oldname.
+// On Windows, a symlink to a non-existent oldname creates a file symlink;
+// if oldname is later created as a directory the symlink will not work.
+// If there is an error, it will be of type *LinkError.
+func Symlink(oldname, newname string) error {
+ e := ignoringEINTR(func() error {
+ return syscall.Symlink(oldname, newname)
+ })
+ if e != nil {
+ return &LinkError{"symlink", oldname, newname, e}
+ }
+ return nil
+}
+
+// Readlink returns the destination of the named symbolic link.
+// If there is an error, it will be of type *PathError.
+func Readlink(name string) (string, error) {
+ for len := 128; ; len *= 2 {
+ b := make([]byte, len)
+ var (
+ n int
+ e error
+ )
+ for {
+ n, e = fixCount(syscall.Readlink(name, b))
+ if e != syscall.EINTR {
+ break
+ }
+ }
+ // buffer too small
+ if (runtime.GOOS == "aix" || runtime.GOOS == "wasip1") && e == syscall.ERANGE {
+ continue
+ }
+ if e != nil {
+ return "", &PathError{Op: "readlink", Path: name, Err: e}
+ }
+ if n < len {
+ return string(b[0:n]), nil
+ }
+ }
+}
+
+type unixDirent struct {
+ parent string
+ name string
+ typ FileMode
+ info FileInfo
+}
+
+func (d *unixDirent) Name() string { return d.name }
+func (d *unixDirent) IsDir() bool { return d.typ.IsDir() }
+func (d *unixDirent) Type() FileMode { return d.typ }
+
+func (d *unixDirent) Info() (FileInfo, error) {
+ if d.info != nil {
+ return d.info, nil
+ }
+ return lstat(d.parent + "/" + d.name)
+}
+
+func (d *unixDirent) String() string {
+ return fs.FormatDirEntry(d)
+}
+
+func newUnixDirent(parent, name string, typ FileMode) (DirEntry, error) {
+ ude := &unixDirent{
+ parent: parent,
+ name: name,
+ typ: typ,
+ }
+ if typ != ^FileMode(0) && !testingForceReadDirLstat {
+ return ude, nil
+ }
+
+ info, err := lstat(parent + "/" + name)
+ if err != nil {
+ return nil, err
+ }
+
+ ude.typ = info.Mode().Type()
+ ude.info = info
+ return ude, nil
+}
diff --git a/contrib/go/_std_1.21/src/os/file_windows.go b/contrib/go/_std_1.21/src/os/file_windows.go
new file mode 100644
index 0000000000..8d77a63d37
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/file_windows.go
@@ -0,0 +1,524 @@
+// Copyright 2009 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 os
+
+import (
+ "errors"
+ "internal/poll"
+ "internal/syscall/windows"
+ "runtime"
+ "sync"
+ "syscall"
+ "unsafe"
+)
+
+// This matches the value in syscall/syscall_windows.go.
+const _UTIME_OMIT = -1
+
+// file is the real representation of *File.
+// The extra level of indirection ensures that no clients of os
+// can overwrite this data, which could cause the finalizer
+// to close the wrong file descriptor.
+type file struct {
+ pfd poll.FD
+ name string
+ dirinfo *dirInfo // nil unless directory being read
+ appendMode bool // whether file is opened for appending
+}
+
+// Fd returns the Windows handle referencing the open file.
+// If f is closed, the file descriptor becomes invalid.
+// If f is garbage collected, a finalizer may close the file descriptor,
+// making it invalid; see runtime.SetFinalizer for more information on when
+// a finalizer might be run. On Unix systems this will cause the SetDeadline
+// methods to stop working.
+func (file *File) Fd() uintptr {
+ if file == nil {
+ return uintptr(syscall.InvalidHandle)
+ }
+ return uintptr(file.pfd.Sysfd)
+}
+
+// newFile returns a new File with the given file handle and name.
+// Unlike NewFile, it does not check that h is syscall.InvalidHandle.
+func newFile(h syscall.Handle, name string, kind string) *File {
+ if kind == "file" {
+ var m uint32
+ if syscall.GetConsoleMode(h, &m) == nil {
+ kind = "console"
+ }
+ if t, err := syscall.GetFileType(h); err == nil && t == syscall.FILE_TYPE_PIPE {
+ kind = "pipe"
+ }
+ }
+
+ f := &File{&file{
+ pfd: poll.FD{
+ Sysfd: h,
+ IsStream: true,
+ ZeroReadIsEOF: true,
+ },
+ name: name,
+ }}
+ runtime.SetFinalizer(f.file, (*file).close)
+
+ // Ignore initialization errors.
+ // Assume any problems will show up in later I/O.
+ f.pfd.Init(kind, false)
+
+ return f
+}
+
+// newConsoleFile creates new File that will be used as console.
+func newConsoleFile(h syscall.Handle, name string) *File {
+ return newFile(h, name, "console")
+}
+
+// NewFile returns a new File with the given file descriptor and
+// name. The returned value will be nil if fd is not a valid file
+// descriptor.
+func NewFile(fd uintptr, name string) *File {
+ h := syscall.Handle(fd)
+ if h == syscall.InvalidHandle {
+ return nil
+ }
+ return newFile(h, name, "file")
+}
+
+// Auxiliary information if the File describes a directory
+type dirInfo struct {
+ h syscall.Handle // search handle created with FindFirstFile
+ data syscall.Win32finddata
+ path string
+ isempty bool // set if FindFirstFile returns ERROR_FILE_NOT_FOUND
+}
+
+func (d *dirInfo) close() error {
+ return syscall.FindClose(d.h)
+}
+
+func epipecheck(file *File, e error) {
+}
+
+// DevNull is the name of the operating system's “null device.”
+// On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
+const DevNull = "NUL"
+
+func openDir(name string) (d *dirInfo, e error) {
+ var mask string
+
+ path := fixLongPath(name)
+
+ if len(path) == 2 && path[1] == ':' { // it is a drive letter, like C:
+ mask = path + `*`
+ } else if len(path) > 0 {
+ lc := path[len(path)-1]
+ if lc == '/' || lc == '\\' {
+ mask = path + `*`
+ } else {
+ mask = path + `\*`
+ }
+ } else {
+ mask = `\*`
+ }
+ maskp, e := syscall.UTF16PtrFromString(mask)
+ if e != nil {
+ return nil, e
+ }
+ d = new(dirInfo)
+ d.h, e = syscall.FindFirstFile(maskp, &d.data)
+ if e != nil {
+ // FindFirstFile returns ERROR_FILE_NOT_FOUND when
+ // no matching files can be found. Then, if directory
+ // exists, we should proceed.
+ // If FindFirstFile failed because name does not point
+ // to a directory, we should return ENOTDIR.
+ var fa syscall.Win32FileAttributeData
+ pathp, e1 := syscall.UTF16PtrFromString(path)
+ if e1 != nil {
+ return nil, e
+ }
+ e1 = syscall.GetFileAttributesEx(pathp, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
+ if e1 != nil {
+ return nil, e
+ }
+ if fa.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY == 0 {
+ return nil, syscall.ENOTDIR
+ }
+ if e != syscall.ERROR_FILE_NOT_FOUND {
+ return nil, e
+ }
+ d.isempty = true
+ }
+ d.path = path
+ if !isAbs(d.path) {
+ d.path, e = syscall.FullPath(d.path)
+ if e != nil {
+ d.close()
+ return nil, e
+ }
+ }
+ return d, nil
+}
+
+// openFileNolog is the Windows implementation of OpenFile.
+func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
+ if name == "" {
+ return nil, &PathError{Op: "open", Path: name, Err: syscall.ENOENT}
+ }
+ path := fixLongPath(name)
+ r, e := syscall.Open(path, flag|syscall.O_CLOEXEC, syscallMode(perm))
+ if e != nil {
+ // We should return EISDIR when we are trying to open a directory with write access.
+ if e == syscall.ERROR_ACCESS_DENIED && (flag&O_WRONLY != 0 || flag&O_RDWR != 0) {
+ pathp, e1 := syscall.UTF16PtrFromString(path)
+ if e1 == nil {
+ var fa syscall.Win32FileAttributeData
+ e1 = syscall.GetFileAttributesEx(pathp, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
+ if e1 == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
+ e = syscall.EISDIR
+ }
+ }
+ }
+ return nil, &PathError{Op: "open", Path: name, Err: e}
+ }
+ f, e := newFile(r, name, "file"), nil
+ if e != nil {
+ return nil, &PathError{Op: "open", Path: name, Err: e}
+ }
+ return f, nil
+}
+
+func (file *file) close() error {
+ if file == nil {
+ return syscall.EINVAL
+ }
+ if file.dirinfo != nil {
+ file.dirinfo.close()
+ file.dirinfo = nil
+ }
+ var err error
+ if e := file.pfd.Close(); e != nil {
+ if e == poll.ErrFileClosing {
+ e = ErrClosed
+ }
+ err = &PathError{Op: "close", Path: file.name, Err: e}
+ }
+
+ // no need for a finalizer anymore
+ runtime.SetFinalizer(file, nil)
+ return err
+}
+
+// seek sets the offset for the next Read or Write on file to offset, interpreted
+// according to whence: 0 means relative to the origin of the file, 1 means
+// relative to the current offset, and 2 means relative to the end.
+// It returns the new offset and an error, if any.
+func (f *File) seek(offset int64, whence int) (ret int64, err error) {
+ if f.dirinfo != nil {
+ // Free cached dirinfo, so we allocate a new one if we
+ // access this file as a directory again. See #35767 and #37161.
+ f.dirinfo.close()
+ f.dirinfo = nil
+ }
+ ret, err = f.pfd.Seek(offset, whence)
+ runtime.KeepAlive(f)
+ return ret, err
+}
+
+// Truncate changes the size of the named file.
+// If the file is a symbolic link, it changes the size of the link's target.
+func Truncate(name string, size int64) error {
+ f, e := OpenFile(name, O_WRONLY, 0666)
+ if e != nil {
+ return e
+ }
+ defer f.Close()
+ e1 := f.Truncate(size)
+ if e1 != nil {
+ return e1
+ }
+ return nil
+}
+
+// Remove removes the named file or directory.
+// If there is an error, it will be of type *PathError.
+func Remove(name string) error {
+ p, e := syscall.UTF16PtrFromString(fixLongPath(name))
+ if e != nil {
+ return &PathError{Op: "remove", Path: name, Err: e}
+ }
+
+ // Go file interface forces us to know whether
+ // name is a file or directory. Try both.
+ e = syscall.DeleteFile(p)
+ if e == nil {
+ return nil
+ }
+ e1 := syscall.RemoveDirectory(p)
+ if e1 == nil {
+ return nil
+ }
+
+ // Both failed: figure out which error to return.
+ if e1 != e {
+ a, e2 := syscall.GetFileAttributes(p)
+ if e2 != nil {
+ e = e2
+ } else {
+ if a&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
+ e = e1
+ } else if a&syscall.FILE_ATTRIBUTE_READONLY != 0 {
+ if e1 = syscall.SetFileAttributes(p, a&^syscall.FILE_ATTRIBUTE_READONLY); e1 == nil {
+ if e = syscall.DeleteFile(p); e == nil {
+ return nil
+ }
+ }
+ }
+ }
+ }
+ return &PathError{Op: "remove", Path: name, Err: e}
+}
+
+func rename(oldname, newname string) error {
+ e := windows.Rename(fixLongPath(oldname), fixLongPath(newname))
+ if e != nil {
+ return &LinkError{"rename", oldname, newname, e}
+ }
+ return nil
+}
+
+// Pipe returns a connected pair of Files; reads from r return bytes written to w.
+// It returns the files and an error, if any. The Windows handles underlying
+// the returned files are marked as inheritable by child processes.
+func Pipe() (r *File, w *File, err error) {
+ var p [2]syscall.Handle
+ e := syscall.Pipe(p[:])
+ if e != nil {
+ return nil, nil, NewSyscallError("pipe", e)
+ }
+ return newFile(p[0], "|0", "pipe"), newFile(p[1], "|1", "pipe"), nil
+}
+
+var (
+ useGetTempPath2Once sync.Once
+ useGetTempPath2 bool
+)
+
+func tempDir() string {
+ useGetTempPath2Once.Do(func() {
+ useGetTempPath2 = (windows.ErrorLoadingGetTempPath2() == nil)
+ })
+ getTempPath := syscall.GetTempPath
+ if useGetTempPath2 {
+ getTempPath = windows.GetTempPath2
+ }
+ n := uint32(syscall.MAX_PATH)
+ for {
+ b := make([]uint16, n)
+ n, _ = getTempPath(uint32(len(b)), &b[0])
+ if n > uint32(len(b)) {
+ continue
+ }
+ if n == 3 && b[1] == ':' && b[2] == '\\' {
+ // Do nothing for path, like C:\.
+ } else if n > 0 && b[n-1] == '\\' {
+ // Otherwise remove terminating \.
+ n--
+ }
+ return syscall.UTF16ToString(b[:n])
+ }
+}
+
+// Link creates newname as a hard link to the oldname file.
+// If there is an error, it will be of type *LinkError.
+func Link(oldname, newname string) error {
+ n, err := syscall.UTF16PtrFromString(fixLongPath(newname))
+ if err != nil {
+ return &LinkError{"link", oldname, newname, err}
+ }
+ o, err := syscall.UTF16PtrFromString(fixLongPath(oldname))
+ if err != nil {
+ return &LinkError{"link", oldname, newname, err}
+ }
+ err = syscall.CreateHardLink(n, o, 0)
+ if err != nil {
+ return &LinkError{"link", oldname, newname, err}
+ }
+ return nil
+}
+
+// Symlink creates newname as a symbolic link to oldname.
+// On Windows, a symlink to a non-existent oldname creates a file symlink;
+// if oldname is later created as a directory the symlink will not work.
+// If there is an error, it will be of type *LinkError.
+func Symlink(oldname, newname string) error {
+ // '/' does not work in link's content
+ oldname = fromSlash(oldname)
+
+ // need the exact location of the oldname when it's relative to determine if it's a directory
+ destpath := oldname
+ if v := volumeName(oldname); v == "" {
+ if len(oldname) > 0 && IsPathSeparator(oldname[0]) {
+ // oldname is relative to the volume containing newname.
+ if v = volumeName(newname); v != "" {
+ // Prepend the volume explicitly, because it may be different from the
+ // volume of the current working directory.
+ destpath = v + oldname
+ }
+ } else {
+ // oldname is relative to newname.
+ destpath = dirname(newname) + `\` + oldname
+ }
+ }
+
+ fi, err := Stat(destpath)
+ isdir := err == nil && fi.IsDir()
+
+ n, err := syscall.UTF16PtrFromString(fixLongPath(newname))
+ if err != nil {
+ return &LinkError{"symlink", oldname, newname, err}
+ }
+ o, err := syscall.UTF16PtrFromString(fixLongPath(oldname))
+ if err != nil {
+ return &LinkError{"symlink", oldname, newname, err}
+ }
+
+ var flags uint32 = windows.SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
+ if isdir {
+ flags |= syscall.SYMBOLIC_LINK_FLAG_DIRECTORY
+ }
+ err = syscall.CreateSymbolicLink(n, o, flags)
+ if err != nil {
+ // the unprivileged create flag is unsupported
+ // below Windows 10 (1703, v10.0.14972). retry without it.
+ flags &^= windows.SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
+ err = syscall.CreateSymbolicLink(n, o, flags)
+ if err != nil {
+ return &LinkError{"symlink", oldname, newname, err}
+ }
+ }
+ return nil
+}
+
+// openSymlink calls CreateFile Windows API with FILE_FLAG_OPEN_REPARSE_POINT
+// parameter, so that Windows does not follow symlink, if path is a symlink.
+// openSymlink returns opened file handle.
+func openSymlink(path string) (syscall.Handle, error) {
+ p, err := syscall.UTF16PtrFromString(path)
+ if err != nil {
+ return 0, err
+ }
+ attrs := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS)
+ // Use FILE_FLAG_OPEN_REPARSE_POINT, otherwise CreateFile will follow symlink.
+ // See https://docs.microsoft.com/en-us/windows/desktop/FileIO/symbolic-link-effects-on-file-systems-functions#createfile-and-createfiletransacted
+ attrs |= syscall.FILE_FLAG_OPEN_REPARSE_POINT
+ h, err := syscall.CreateFile(p, 0, 0, nil, syscall.OPEN_EXISTING, attrs, 0)
+ if err != nil {
+ return 0, err
+ }
+ return h, nil
+}
+
+// normaliseLinkPath converts absolute paths returned by
+// DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, ...)
+// into paths acceptable by all Windows APIs.
+// For example, it converts
+//
+// \??\C:\foo\bar into C:\foo\bar
+// \??\UNC\foo\bar into \\foo\bar
+// \??\Volume{abc}\ into C:\
+func normaliseLinkPath(path string) (string, error) {
+ if len(path) < 4 || path[:4] != `\??\` {
+ // unexpected path, return it as is
+ return path, nil
+ }
+ // we have path that start with \??\
+ s := path[4:]
+ switch {
+ case len(s) >= 2 && s[1] == ':': // \??\C:\foo\bar
+ return s, nil
+ case len(s) >= 4 && s[:4] == `UNC\`: // \??\UNC\foo\bar
+ return `\\` + s[4:], nil
+ }
+
+ // handle paths, like \??\Volume{abc}\...
+
+ err := windows.LoadGetFinalPathNameByHandle()
+ if err != nil {
+ // we must be using old version of Windows
+ return "", err
+ }
+
+ h, err := openSymlink(path)
+ if err != nil {
+ return "", err
+ }
+ defer syscall.CloseHandle(h)
+
+ buf := make([]uint16, 100)
+ for {
+ n, err := windows.GetFinalPathNameByHandle(h, &buf[0], uint32(len(buf)), windows.VOLUME_NAME_DOS)
+ if err != nil {
+ return "", err
+ }
+ if n < uint32(len(buf)) {
+ break
+ }
+ buf = make([]uint16, n)
+ }
+ s = syscall.UTF16ToString(buf)
+ if len(s) > 4 && s[:4] == `\\?\` {
+ s = s[4:]
+ if len(s) > 3 && s[:3] == `UNC` {
+ // return path like \\server\share\...
+ return `\` + s[3:], nil
+ }
+ return s, nil
+ }
+ return "", errors.New("GetFinalPathNameByHandle returned unexpected path: " + s)
+}
+
+func readlink(path string) (string, error) {
+ h, err := openSymlink(path)
+ if err != nil {
+ return "", err
+ }
+ defer syscall.CloseHandle(h)
+
+ rdbbuf := make([]byte, syscall.MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
+ var bytesReturned uint32
+ err = syscall.DeviceIoControl(h, syscall.FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
+ if err != nil {
+ return "", err
+ }
+
+ rdb := (*windows.REPARSE_DATA_BUFFER)(unsafe.Pointer(&rdbbuf[0]))
+ switch rdb.ReparseTag {
+ case syscall.IO_REPARSE_TAG_SYMLINK:
+ rb := (*windows.SymbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.DUMMYUNIONNAME))
+ s := rb.Path()
+ if rb.Flags&windows.SYMLINK_FLAG_RELATIVE != 0 {
+ return s, nil
+ }
+ return normaliseLinkPath(s)
+ case windows.IO_REPARSE_TAG_MOUNT_POINT:
+ return normaliseLinkPath((*windows.MountPointReparseBuffer)(unsafe.Pointer(&rdb.DUMMYUNIONNAME)).Path())
+ default:
+ // the path is not a symlink or junction but another type of reparse
+ // point
+ return "", syscall.ENOENT
+ }
+}
+
+// Readlink returns the destination of the named symbolic link.
+// If there is an error, it will be of type *PathError.
+func Readlink(name string) (string, error) {
+ s, err := readlink(fixLongPath(name))
+ if err != nil {
+ return "", &PathError{Op: "readlink", Path: name, Err: err}
+ }
+ return s, nil
+}
diff --git a/contrib/go/_std_1.20/src/os/getwd.go b/contrib/go/_std_1.21/src/os/getwd.go
index 90604cf2f4..90604cf2f4 100644
--- a/contrib/go/_std_1.20/src/os/getwd.go
+++ b/contrib/go/_std_1.21/src/os/getwd.go
diff --git a/contrib/go/_std_1.20/src/os/path.go b/contrib/go/_std_1.21/src/os/path.go
index df87887b9b..df87887b9b 100644
--- a/contrib/go/_std_1.20/src/os/path.go
+++ b/contrib/go/_std_1.21/src/os/path.go
diff --git a/contrib/go/_std_1.21/src/os/path_unix.go b/contrib/go/_std_1.21/src/os/path_unix.go
new file mode 100644
index 0000000000..c975cdb11e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/path_unix.go
@@ -0,0 +1,75 @@
+// Copyright 2011 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package os
+
+const (
+ PathSeparator = '/' // OS-specific path separator
+ PathListSeparator = ':' // OS-specific path list separator
+)
+
+// IsPathSeparator reports whether c is a directory separator character.
+func IsPathSeparator(c uint8) bool {
+ return PathSeparator == c
+}
+
+// basename removes trailing slashes and the leading directory name from path name.
+func basename(name string) string {
+ i := len(name) - 1
+ // Remove trailing slashes
+ for ; i > 0 && name[i] == '/'; i-- {
+ name = name[:i]
+ }
+ // Remove leading directory name
+ for i--; i >= 0; i-- {
+ if name[i] == '/' {
+ name = name[i+1:]
+ break
+ }
+ }
+
+ return name
+}
+
+// splitPath returns the base name and parent directory.
+func splitPath(path string) (string, string) {
+ // if no better parent is found, the path is relative from "here"
+ dirname := "."
+
+ // Remove all but one leading slash.
+ for len(path) > 1 && path[0] == '/' && path[1] == '/' {
+ path = path[1:]
+ }
+
+ i := len(path) - 1
+
+ // Remove trailing slashes.
+ for ; i > 0 && path[i] == '/'; i-- {
+ path = path[:i]
+ }
+
+ // if no slashes in path, base is path
+ basename := path
+
+ // Remove leading directory path
+ for i--; i >= 0; i-- {
+ if path[i] == '/' {
+ if i == 0 {
+ dirname = path[:1]
+ } else {
+ dirname = path[:i]
+ }
+ basename = path[i+1:]
+ break
+ }
+ }
+
+ return dirname, basename
+}
+
+func fixRootDirectory(p string) string {
+ return p
+}
diff --git a/contrib/go/_std_1.20/src/os/path_windows.go b/contrib/go/_std_1.21/src/os/path_windows.go
index 3356908a36..3356908a36 100644
--- a/contrib/go/_std_1.20/src/os/path_windows.go
+++ b/contrib/go/_std_1.21/src/os/path_windows.go
diff --git a/contrib/go/_std_1.21/src/os/pipe2_unix.go b/contrib/go/_std_1.21/src/os/pipe2_unix.go
new file mode 100644
index 0000000000..2d293fdb4d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/pipe2_unix.go
@@ -0,0 +1,22 @@
+// Copyright 2017 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.
+
+//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris
+
+package os
+
+import "syscall"
+
+// Pipe returns a connected pair of Files; reads from r return bytes written to w.
+// It returns the files and an error, if any.
+func Pipe() (r *File, w *File, err error) {
+ var p [2]int
+
+ e := syscall.Pipe2(p[0:], syscall.O_CLOEXEC)
+ if e != nil {
+ return nil, nil, NewSyscallError("pipe2", e)
+ }
+
+ return newFile(p[0], "|0", kindPipe), newFile(p[1], "|1", kindPipe), nil
+}
diff --git a/contrib/go/_std_1.21/src/os/pipe_unix.go b/contrib/go/_std_1.21/src/os/pipe_unix.go
new file mode 100644
index 0000000000..2eb11a04cb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/pipe_unix.go
@@ -0,0 +1,28 @@
+// Copyright 2009 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.
+
+//go:build aix || darwin
+
+package os
+
+import "syscall"
+
+// Pipe returns a connected pair of Files; reads from r return bytes written to w.
+// It returns the files and an error, if any.
+func Pipe() (r *File, w *File, err error) {
+ var p [2]int
+
+ // See ../syscall/exec.go for description of lock.
+ syscall.ForkLock.RLock()
+ e := syscall.Pipe(p[0:])
+ if e != nil {
+ syscall.ForkLock.RUnlock()
+ return nil, nil, NewSyscallError("pipe", e)
+ }
+ syscall.CloseOnExec(p[0])
+ syscall.CloseOnExec(p[1])
+ syscall.ForkLock.RUnlock()
+
+ return newFile(p[0], "|0", kindPipe), newFile(p[1], "|1", kindPipe), nil
+}
diff --git a/contrib/go/_std_1.20/src/os/proc.go b/contrib/go/_std_1.21/src/os/proc.go
index 3aae5680ee..3aae5680ee 100644
--- a/contrib/go/_std_1.20/src/os/proc.go
+++ b/contrib/go/_std_1.21/src/os/proc.go
diff --git a/contrib/go/_std_1.20/src/os/rawconn.go b/contrib/go/_std_1.21/src/os/rawconn.go
index 14a495d9c0..14a495d9c0 100644
--- a/contrib/go/_std_1.20/src/os/rawconn.go
+++ b/contrib/go/_std_1.21/src/os/rawconn.go
diff --git a/contrib/go/_std_1.21/src/os/readfrom_linux.go b/contrib/go/_std_1.21/src/os/readfrom_linux.go
new file mode 100644
index 0000000000..7e8024028e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/readfrom_linux.go
@@ -0,0 +1,124 @@
+// 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 os
+
+import (
+ "internal/poll"
+ "io"
+ "syscall"
+)
+
+var (
+ pollCopyFileRange = poll.CopyFileRange
+ pollSplice = poll.Splice
+)
+
+func (f *File) readFrom(r io.Reader) (written int64, handled bool, err error) {
+ // Neither copy_file_range(2) nor splice(2) supports destinations opened with
+ // O_APPEND, so don't bother to try zero-copy with these system calls.
+ //
+ // Visit https://man7.org/linux/man-pages/man2/copy_file_range.2.html#ERRORS and
+ // https://man7.org/linux/man-pages/man2/splice.2.html#ERRORS for details.
+ if f.appendMode {
+ return 0, false, nil
+ }
+
+ written, handled, err = f.copyFileRange(r)
+ if handled {
+ return
+ }
+ return f.spliceToFile(r)
+}
+
+func (f *File) spliceToFile(r io.Reader) (written int64, handled bool, err error) {
+ var (
+ remain int64
+ lr *io.LimitedReader
+ )
+ if lr, r, remain = tryLimitedReader(r); remain <= 0 {
+ return 0, true, nil
+ }
+
+ pfd := getPollFD(r)
+ // TODO(panjf2000): run some tests to see if we should unlock the non-streams for splice.
+ // Streams benefit the most from the splice(2), non-streams are not even supported in old kernels
+ // where splice(2) will just return EINVAL; newer kernels support non-streams like UDP, but I really
+ // doubt that splice(2) could help non-streams, cuz they usually send small frames respectively
+ // and one splice call would result in one frame.
+ // splice(2) is suitable for large data but the generation of fragments defeats its edge here.
+ // Therefore, don't bother to try splice if the r is not a streaming descriptor.
+ if pfd == nil || !pfd.IsStream {
+ return
+ }
+
+ var syscallName string
+ written, handled, syscallName, err = pollSplice(&f.pfd, pfd, remain)
+
+ if lr != nil {
+ lr.N = remain - written
+ }
+
+ return written, handled, wrapSyscallError(syscallName, err)
+}
+
+// getPollFD tries to get the poll.FD from the given io.Reader by expecting
+// the underlying type of r to be the implementation of syscall.Conn that contains
+// a *net.rawConn.
+func getPollFD(r io.Reader) *poll.FD {
+ sc, ok := r.(syscall.Conn)
+ if !ok {
+ return nil
+ }
+ rc, err := sc.SyscallConn()
+ if err != nil {
+ return nil
+ }
+ ipfd, ok := rc.(interface{ PollFD() *poll.FD })
+ if !ok {
+ return nil
+ }
+ return ipfd.PollFD()
+}
+
+func (f *File) copyFileRange(r io.Reader) (written int64, handled bool, err error) {
+ var (
+ remain int64
+ lr *io.LimitedReader
+ )
+ if lr, r, remain = tryLimitedReader(r); remain <= 0 {
+ return 0, true, nil
+ }
+
+ src, ok := r.(*File)
+ if !ok {
+ return 0, false, nil
+ }
+ if src.checkValid("ReadFrom") != nil {
+ // Avoid returning the error as we report handled as false,
+ // leave further error handling as the responsibility of the caller.
+ return 0, false, nil
+ }
+
+ written, handled, err = pollCopyFileRange(&f.pfd, &src.pfd, remain)
+ if lr != nil {
+ lr.N -= written
+ }
+ return written, handled, wrapSyscallError("copy_file_range", err)
+}
+
+// tryLimitedReader tries to assert the io.Reader to io.LimitedReader, it returns the io.LimitedReader,
+// the underlying io.Reader and the remaining amount of bytes if the assertion succeeds,
+// otherwise it just returns the original io.Reader and the theoretical unlimited remaining amount of bytes.
+func tryLimitedReader(r io.Reader) (*io.LimitedReader, io.Reader, int64) {
+ var remain int64 = 1<<63 - 1 // by default, copy until EOF
+
+ lr, ok := r.(*io.LimitedReader)
+ if !ok {
+ return nil, r, remain
+ }
+
+ remain = lr.N
+ return lr, lr.R, remain
+}
diff --git a/contrib/go/_std_1.20/src/os/readfrom_stub.go b/contrib/go/_std_1.21/src/os/readfrom_stub.go
index 8b7d5fb8f9..8b7d5fb8f9 100644
--- a/contrib/go/_std_1.20/src/os/readfrom_stub.go
+++ b/contrib/go/_std_1.21/src/os/readfrom_stub.go
diff --git a/contrib/go/_std_1.21/src/os/removeall_at.go b/contrib/go/_std_1.21/src/os/removeall_at.go
new file mode 100644
index 0000000000..8ea5df4117
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/removeall_at.go
@@ -0,0 +1,199 @@
+// Copyright 2018 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.
+
+//go:build unix
+
+package os
+
+import (
+ "internal/syscall/unix"
+ "io"
+ "syscall"
+)
+
+func removeAll(path string) error {
+ if path == "" {
+ // fail silently to retain compatibility with previous behavior
+ // of RemoveAll. See issue 28830.
+ return nil
+ }
+
+ // The rmdir system call does not permit removing ".",
+ // so we don't permit it either.
+ if endsWithDot(path) {
+ return &PathError{Op: "RemoveAll", Path: path, Err: syscall.EINVAL}
+ }
+
+ // Simple case: if Remove works, we're done.
+ err := Remove(path)
+ if err == nil || IsNotExist(err) {
+ return nil
+ }
+
+ // RemoveAll recurses by deleting the path base from
+ // its parent directory
+ parentDir, base := splitPath(path)
+
+ parent, err := Open(parentDir)
+ if IsNotExist(err) {
+ // If parent does not exist, base cannot exist. Fail silently
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+ defer parent.Close()
+
+ if err := removeAllFrom(parent, base); err != nil {
+ if pathErr, ok := err.(*PathError); ok {
+ pathErr.Path = parentDir + string(PathSeparator) + pathErr.Path
+ err = pathErr
+ }
+ return err
+ }
+ return nil
+}
+
+func removeAllFrom(parent *File, base string) error {
+ parentFd := int(parent.Fd())
+ // Simple case: if Unlink (aka remove) works, we're done.
+ err := ignoringEINTR(func() error {
+ return unix.Unlinkat(parentFd, base, 0)
+ })
+ if err == nil || IsNotExist(err) {
+ return nil
+ }
+
+ // EISDIR means that we have a directory, and we need to
+ // remove its contents.
+ // EPERM or EACCES means that we don't have write permission on
+ // the parent directory, but this entry might still be a directory
+ // whose contents need to be removed.
+ // Otherwise just return the error.
+ if err != syscall.EISDIR && err != syscall.EPERM && err != syscall.EACCES {
+ return &PathError{Op: "unlinkat", Path: base, Err: err}
+ }
+
+ // Is this a directory we need to recurse into?
+ var statInfo syscall.Stat_t
+ statErr := ignoringEINTR(func() error {
+ return unix.Fstatat(parentFd, base, &statInfo, unix.AT_SYMLINK_NOFOLLOW)
+ })
+ if statErr != nil {
+ if IsNotExist(statErr) {
+ return nil
+ }
+ return &PathError{Op: "fstatat", Path: base, Err: statErr}
+ }
+ if statInfo.Mode&syscall.S_IFMT != syscall.S_IFDIR {
+ // Not a directory; return the error from the unix.Unlinkat.
+ return &PathError{Op: "unlinkat", Path: base, Err: err}
+ }
+
+ // Remove the directory's entries.
+ var recurseErr error
+ for {
+ const reqSize = 1024
+ var respSize int
+
+ // Open the directory to recurse into
+ file, err := openFdAt(parentFd, base)
+ if err != nil {
+ if IsNotExist(err) {
+ return nil
+ }
+ recurseErr = &PathError{Op: "openfdat", Path: base, Err: err}
+ break
+ }
+
+ for {
+ numErr := 0
+
+ names, readErr := file.Readdirnames(reqSize)
+ // Errors other than EOF should stop us from continuing.
+ if readErr != nil && readErr != io.EOF {
+ file.Close()
+ if IsNotExist(readErr) {
+ return nil
+ }
+ return &PathError{Op: "readdirnames", Path: base, Err: readErr}
+ }
+
+ respSize = len(names)
+ for _, name := range names {
+ err := removeAllFrom(file, name)
+ if err != nil {
+ if pathErr, ok := err.(*PathError); ok {
+ pathErr.Path = base + string(PathSeparator) + pathErr.Path
+ }
+ numErr++
+ if recurseErr == nil {
+ recurseErr = err
+ }
+ }
+ }
+
+ // If we can delete any entry, break to start new iteration.
+ // Otherwise, we discard current names, get next entries and try deleting them.
+ if numErr != reqSize {
+ break
+ }
+ }
+
+ // Removing files from the directory may have caused
+ // the OS to reshuffle it. Simply calling Readdirnames
+ // again may skip some entries. The only reliable way
+ // to avoid this is to close and re-open the
+ // directory. See issue 20841.
+ file.Close()
+
+ // Finish when the end of the directory is reached
+ if respSize < reqSize {
+ break
+ }
+ }
+
+ // Remove the directory itself.
+ unlinkError := ignoringEINTR(func() error {
+ return unix.Unlinkat(parentFd, base, unix.AT_REMOVEDIR)
+ })
+ if unlinkError == nil || IsNotExist(unlinkError) {
+ return nil
+ }
+
+ if recurseErr != nil {
+ return recurseErr
+ }
+ return &PathError{Op: "unlinkat", Path: base, Err: unlinkError}
+}
+
+// openFdAt opens path relative to the directory in fd.
+// Other than that this should act like openFileNolog.
+// This acts like openFileNolog rather than OpenFile because
+// we are going to (try to) remove the file.
+// The contents of this file are not relevant for test caching.
+func openFdAt(dirfd int, name string) (*File, error) {
+ var r int
+ for {
+ var e error
+ r, e = unix.Openat(dirfd, name, O_RDONLY|syscall.O_CLOEXEC, 0)
+ if e == nil {
+ break
+ }
+
+ // See comment in openFileNolog.
+ if e == syscall.EINTR {
+ continue
+ }
+
+ return nil, e
+ }
+
+ if !supportsCloseOnExec {
+ syscall.CloseOnExec(r)
+ }
+
+ // We use kindNoPoll because we know that this is a directory.
+ return newFile(r, name, kindNoPoll), nil
+}
diff --git a/contrib/go/_std_1.20/src/os/removeall_noat.go b/contrib/go/_std_1.21/src/os/removeall_noat.go
index 2b8a7727f4..2b8a7727f4 100644
--- a/contrib/go/_std_1.20/src/os/removeall_noat.go
+++ b/contrib/go/_std_1.21/src/os/removeall_noat.go
diff --git a/contrib/go/_std_1.20/src/os/rlimit.go b/contrib/go/_std_1.21/src/os/rlimit.go
index e0d0ef9b62..e0d0ef9b62 100644
--- a/contrib/go/_std_1.20/src/os/rlimit.go
+++ b/contrib/go/_std_1.21/src/os/rlimit.go
diff --git a/contrib/go/_std_1.20/src/os/rlimit_darwin.go b/contrib/go/_std_1.21/src/os/rlimit_darwin.go
index b28982a83a..b28982a83a 100644
--- a/contrib/go/_std_1.20/src/os/rlimit_darwin.go
+++ b/contrib/go/_std_1.21/src/os/rlimit_darwin.go
diff --git a/contrib/go/_std_1.20/src/os/rlimit_stub.go b/contrib/go/_std_1.21/src/os/rlimit_stub.go
index cbe28400c5..cbe28400c5 100644
--- a/contrib/go/_std_1.20/src/os/rlimit_stub.go
+++ b/contrib/go/_std_1.21/src/os/rlimit_stub.go
diff --git a/contrib/go/_std_1.21/src/os/signal/doc.go b/contrib/go/_std_1.21/src/os/signal/doc.go
new file mode 100644
index 0000000000..a2a7525ef0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/signal/doc.go
@@ -0,0 +1,232 @@
+// Copyright 2015 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 signal implements access to incoming signals.
+
+Signals are primarily used on Unix-like systems. For the use of this
+package on Windows and Plan 9, see below.
+
+# Types of signals
+
+The signals SIGKILL and SIGSTOP may not be caught by a program, and
+therefore cannot be affected by this package.
+
+Synchronous signals are signals triggered by errors in program
+execution: SIGBUS, SIGFPE, and SIGSEGV. These are only considered
+synchronous when caused by program execution, not when sent using
+[os.Process.Kill] or the kill program or some similar mechanism. In
+general, except as discussed below, Go programs will convert a
+synchronous signal into a run-time panic.
+
+The remaining signals are asynchronous signals. They are not
+triggered by program errors, but are instead sent from the kernel or
+from some other program.
+
+Of the asynchronous signals, the SIGHUP signal is sent when a program
+loses its controlling terminal. The SIGINT signal is sent when the
+user at the controlling terminal presses the interrupt character,
+which by default is ^C (Control-C). The SIGQUIT signal is sent when
+the user at the controlling terminal presses the quit character, which
+by default is ^\ (Control-Backslash). In general you can cause a
+program to simply exit by pressing ^C, and you can cause it to exit
+with a stack dump by pressing ^\.
+
+# Default behavior of signals in Go programs
+
+By default, a synchronous signal is converted into a run-time panic. A
+SIGHUP, SIGINT, or SIGTERM signal causes the program to exit. A
+SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT, or SIGSYS signal
+causes the program to exit with a stack dump. A SIGTSTP, SIGTTIN, or
+SIGTTOU signal gets the system default behavior (these signals are
+used by the shell for job control). The SIGPROF signal is handled
+directly by the Go runtime to implement runtime.CPUProfile. Other
+signals will be caught but no action will be taken.
+
+If the Go program is started with either SIGHUP or SIGINT ignored
+(signal handler set to SIG_IGN), they will remain ignored.
+
+If the Go program is started with a non-empty signal mask, that will
+generally be honored. However, some signals are explicitly unblocked:
+the synchronous signals, SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF,
+and, on Linux, signals 32 (SIGCANCEL) and 33 (SIGSETXID)
+(SIGCANCEL and SIGSETXID are used internally by glibc). Subprocesses
+started by [os.Exec], or by [os/exec], will inherit the
+modified signal mask.
+
+# Changing the behavior of signals in Go programs
+
+The functions in this package allow a program to change the way Go
+programs handle signals.
+
+Notify disables the default behavior for a given set of asynchronous
+signals and instead delivers them over one or more registered
+channels. Specifically, it applies to the signals SIGHUP, SIGINT,
+SIGQUIT, SIGABRT, and SIGTERM. It also applies to the job control
+signals SIGTSTP, SIGTTIN, and SIGTTOU, in which case the system
+default behavior does not occur. It also applies to some signals that
+otherwise cause no action: SIGUSR1, SIGUSR2, SIGPIPE, SIGALRM,
+SIGCHLD, SIGCONT, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGWINCH,
+SIGIO, SIGPWR, SIGSYS, SIGINFO, SIGTHR, SIGWAITING, SIGLWP, SIGFREEZE,
+SIGTHAW, SIGLOST, SIGXRES, SIGJVM1, SIGJVM2, and any real time signals
+used on the system. Note that not all of these signals are available
+on all systems.
+
+If the program was started with SIGHUP or SIGINT ignored, and Notify
+is called for either signal, a signal handler will be installed for
+that signal and it will no longer be ignored. If, later, Reset or
+Ignore is called for that signal, or Stop is called on all channels
+passed to Notify for that signal, the signal will once again be
+ignored. Reset will restore the system default behavior for the
+signal, while Ignore will cause the system to ignore the signal
+entirely.
+
+If the program is started with a non-empty signal mask, some signals
+will be explicitly unblocked as described above. If Notify is called
+for a blocked signal, it will be unblocked. If, later, Reset is
+called for that signal, or Stop is called on all channels passed to
+Notify for that signal, the signal will once again be blocked.
+
+# SIGPIPE
+
+When a Go program writes to a broken pipe, the kernel will raise a
+SIGPIPE signal.
+
+If the program has not called Notify to receive SIGPIPE signals, then
+the behavior depends on the file descriptor number. A write to a
+broken pipe on file descriptors 1 or 2 (standard output or standard
+error) will cause the program to exit with a SIGPIPE signal. A write
+to a broken pipe on some other file descriptor will take no action on
+the SIGPIPE signal, and the write will fail with an EPIPE error.
+
+If the program has called Notify to receive SIGPIPE signals, the file
+descriptor number does not matter. The SIGPIPE signal will be
+delivered to the Notify channel, and the write will fail with an EPIPE
+error.
+
+This means that, by default, command line programs will behave like
+typical Unix command line programs, while other programs will not
+crash with SIGPIPE when writing to a closed network connection.
+
+# Go programs that use cgo or SWIG
+
+In a Go program that includes non-Go code, typically C/C++ code
+accessed using cgo or SWIG, Go's startup code normally runs first. It
+configures the signal handlers as expected by the Go runtime, before
+the non-Go startup code runs. If the non-Go startup code wishes to
+install its own signal handlers, it must take certain steps to keep Go
+working well. This section documents those steps and the overall
+effect changes to signal handler settings by the non-Go code can have
+on Go programs. In rare cases, the non-Go code may run before the Go
+code, in which case the next section also applies.
+
+If the non-Go code called by the Go program does not change any signal
+handlers or masks, then the behavior is the same as for a pure Go
+program.
+
+If the non-Go code installs any signal handlers, it must use the
+SA_ONSTACK flag with sigaction. Failing to do so is likely to cause
+the program to crash if the signal is received. Go programs routinely
+run with a limited stack, and therefore set up an alternate signal
+stack.
+
+If the non-Go code installs a signal handler for any of the
+synchronous signals (SIGBUS, SIGFPE, SIGSEGV), then it should record
+the existing Go signal handler. If those signals occur while
+executing Go code, it should invoke the Go signal handler (whether the
+signal occurs while executing Go code can be determined by looking at
+the PC passed to the signal handler). Otherwise some Go run-time
+panics will not occur as expected.
+
+If the non-Go code installs a signal handler for any of the
+asynchronous signals, it may invoke the Go signal handler or not as it
+chooses. Naturally, if it does not invoke the Go signal handler, the
+Go behavior described above will not occur. This can be an issue with
+the SIGPROF signal in particular.
+
+The non-Go code should not change the signal mask on any threads
+created by the Go runtime. If the non-Go code starts new threads of
+its own, it may set the signal mask as it pleases.
+
+If the non-Go code starts a new thread, changes the signal mask, and
+then invokes a Go function in that thread, the Go runtime will
+automatically unblock certain signals: the synchronous signals,
+SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF, SIGCANCEL, and
+SIGSETXID. When the Go function returns, the non-Go signal mask will
+be restored.
+
+If the Go signal handler is invoked on a non-Go thread not running Go
+code, the handler generally forwards the signal to the non-Go code, as
+follows. If the signal is SIGPROF, the Go handler does
+nothing. Otherwise, the Go handler removes itself, unblocks the
+signal, and raises it again, to invoke any non-Go handler or default
+system handler. If the program does not exit, the Go handler then
+reinstalls itself and continues execution of the program.
+
+If a SIGPIPE signal is received, the Go program will invoke the
+special handling described above if the SIGPIPE is received on a Go
+thread. If the SIGPIPE is received on a non-Go thread the signal will
+be forwarded to the non-Go handler, if any; if there is none the
+default system handler will cause the program to terminate.
+
+# Non-Go programs that call Go code
+
+When Go code is built with options like -buildmode=c-shared, it will
+be run as part of an existing non-Go program. The non-Go code may
+have already installed signal handlers when the Go code starts (that
+may also happen in unusual cases when using cgo or SWIG; in that case,
+the discussion here applies). For -buildmode=c-archive the Go runtime
+will initialize signals at global constructor time. For
+-buildmode=c-shared the Go runtime will initialize signals when the
+shared library is loaded.
+
+If the Go runtime sees an existing signal handler for the SIGCANCEL or
+SIGSETXID signals (which are used only on Linux), it will turn on
+the SA_ONSTACK flag and otherwise keep the signal handler.
+
+For the synchronous signals and SIGPIPE, the Go runtime will install a
+signal handler. It will save any existing signal handler. If a
+synchronous signal arrives while executing non-Go code, the Go runtime
+will invoke the existing signal handler instead of the Go signal
+handler.
+
+Go code built with -buildmode=c-archive or -buildmode=c-shared will
+not install any other signal handlers by default. If there is an
+existing signal handler, the Go runtime will turn on the SA_ONSTACK
+flag and otherwise keep the signal handler. If Notify is called for an
+asynchronous signal, a Go signal handler will be installed for that
+signal. If, later, Reset is called for that signal, the original
+handling for that signal will be reinstalled, restoring the non-Go
+signal handler if any.
+
+Go code built without -buildmode=c-archive or -buildmode=c-shared will
+install a signal handler for the asynchronous signals listed above,
+and save any existing signal handler. If a signal is delivered to a
+non-Go thread, it will act as described above, except that if there is
+an existing non-Go signal handler, that handler will be installed
+before raising the signal.
+
+# Windows
+
+On Windows a ^C (Control-C) or ^BREAK (Control-Break) normally cause
+the program to exit. If Notify is called for [os.Interrupt], ^C or ^BREAK
+will cause [os.Interrupt] to be sent on the channel, and the program will
+not exit. If Reset is called, or Stop is called on all channels passed
+to Notify, then the default behavior will be restored.
+
+Additionally, if Notify is called, and Windows sends CTRL_CLOSE_EVENT,
+CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT to the process, Notify will
+return syscall.SIGTERM. Unlike Control-C and Control-Break, Notify does
+not change process behavior when either CTRL_CLOSE_EVENT,
+CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT is received - the process will
+still get terminated unless it exits. But receiving syscall.SIGTERM will
+give the process an opportunity to clean up before termination.
+
+# Plan 9
+
+On Plan 9, signals have type syscall.Note, which is a string. Calling
+Notify with a syscall.Note will cause that value to be sent on the
+channel when that string is posted as a note.
+*/
+package signal
diff --git a/contrib/go/_std_1.20/src/os/signal/sig.s b/contrib/go/_std_1.21/src/os/signal/sig.s
index 12833a8934..12833a8934 100644
--- a/contrib/go/_std_1.20/src/os/signal/sig.s
+++ b/contrib/go/_std_1.21/src/os/signal/sig.s
diff --git a/contrib/go/_std_1.20/src/os/signal/signal.go b/contrib/go/_std_1.21/src/os/signal/signal.go
index 4250a7e0de..4250a7e0de 100644
--- a/contrib/go/_std_1.20/src/os/signal/signal.go
+++ b/contrib/go/_std_1.21/src/os/signal/signal.go
diff --git a/contrib/go/_std_1.21/src/os/signal/signal_unix.go b/contrib/go/_std_1.21/src/os/signal/signal_unix.go
new file mode 100644
index 0000000000..21dfa41691
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/signal/signal_unix.go
@@ -0,0 +1,62 @@
+// Copyright 2012 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package signal
+
+import (
+ "os"
+ "syscall"
+)
+
+// Defined by the runtime package.
+func signal_disable(uint32)
+func signal_enable(uint32)
+func signal_ignore(uint32)
+func signal_ignored(uint32) bool
+func signal_recv() uint32
+
+func loop() {
+ for {
+ process(syscall.Signal(signal_recv()))
+ }
+}
+
+func init() {
+ watchSignalLoop = loop
+}
+
+const (
+ numSig = 65 // max across all systems
+)
+
+func signum(sig os.Signal) int {
+ switch sig := sig.(type) {
+ case syscall.Signal:
+ i := int(sig)
+ if i < 0 || i >= numSig {
+ return -1
+ }
+ return i
+ default:
+ return -1
+ }
+}
+
+func enableSignal(sig int) {
+ signal_enable(uint32(sig))
+}
+
+func disableSignal(sig int) {
+ signal_disable(uint32(sig))
+}
+
+func ignoreSignal(sig int) {
+ signal_ignore(uint32(sig))
+}
+
+func signalIgnored(sig int) bool {
+ return signal_ignored(uint32(sig))
+}
diff --git a/contrib/go/_std_1.21/src/os/signal/ya.make b/contrib/go/_std_1.21/src/os/signal/ya.make
new file mode 100644
index 0000000000..00f85fc581
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/signal/ya.make
@@ -0,0 +1,40 @@
+GO_LIBRARY()
+
+SRCS(
+ doc.go
+ sig.s
+ signal.go
+ signal_unix.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+IF (OS_LINUX)
+ GO_TEST_SRCS(
+ signal_linux_test.go
+ signal_test.go
+ )
+
+ GO_XTEST_SRCS(
+ example_unix_test.go
+ signal_cgo_test.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ GO_TEST_SRCS(signal_test.go)
+
+ GO_XTEST_SRCS(
+ example_unix_test.go
+ signal_cgo_test.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS)
+ GO_TEST_SRCS(signal_windows_test.go)
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/os/stat.go b/contrib/go/_std_1.21/src/os/stat.go
index af66838e3e..af66838e3e 100644
--- a/contrib/go/_std_1.20/src/os/stat.go
+++ b/contrib/go/_std_1.21/src/os/stat.go
diff --git a/contrib/go/_std_1.20/src/os/stat_darwin.go b/contrib/go/_std_1.21/src/os/stat_darwin.go
index b92ffd4a0a..b92ffd4a0a 100644
--- a/contrib/go/_std_1.20/src/os/stat_darwin.go
+++ b/contrib/go/_std_1.21/src/os/stat_darwin.go
diff --git a/contrib/go/_std_1.20/src/os/stat_linux.go b/contrib/go/_std_1.21/src/os/stat_linux.go
index 316c26c7ca..316c26c7ca 100644
--- a/contrib/go/_std_1.20/src/os/stat_linux.go
+++ b/contrib/go/_std_1.21/src/os/stat_linux.go
diff --git a/contrib/go/_std_1.21/src/os/stat_unix.go b/contrib/go/_std_1.21/src/os/stat_unix.go
new file mode 100644
index 0000000000..431df33fae
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/stat_unix.go
@@ -0,0 +1,52 @@
+// Copyright 2016 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package os
+
+import (
+ "syscall"
+)
+
+// Stat returns the FileInfo structure describing file.
+// If there is an error, it will be of type *PathError.
+func (f *File) Stat() (FileInfo, error) {
+ if f == nil {
+ return nil, ErrInvalid
+ }
+ var fs fileStat
+ err := f.pfd.Fstat(&fs.sys)
+ if err != nil {
+ return nil, &PathError{Op: "stat", Path: f.name, Err: err}
+ }
+ fillFileStatFromSys(&fs, f.name)
+ return &fs, nil
+}
+
+// statNolog stats a file with no test logging.
+func statNolog(name string) (FileInfo, error) {
+ var fs fileStat
+ err := ignoringEINTR(func() error {
+ return syscall.Stat(name, &fs.sys)
+ })
+ if err != nil {
+ return nil, &PathError{Op: "stat", Path: name, Err: err}
+ }
+ fillFileStatFromSys(&fs, name)
+ return &fs, nil
+}
+
+// lstatNolog lstats a file with no test logging.
+func lstatNolog(name string) (FileInfo, error) {
+ var fs fileStat
+ err := ignoringEINTR(func() error {
+ return syscall.Lstat(name, &fs.sys)
+ })
+ if err != nil {
+ return nil, &PathError{Op: "lstat", Path: name, Err: err}
+ }
+ fillFileStatFromSys(&fs, name)
+ return &fs, nil
+}
diff --git a/contrib/go/_std_1.21/src/os/stat_windows.go b/contrib/go/_std_1.21/src/os/stat_windows.go
new file mode 100644
index 0000000000..033c3b9353
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/stat_windows.go
@@ -0,0 +1,136 @@
+// Copyright 2009 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 os
+
+import (
+ "internal/syscall/windows"
+ "syscall"
+ "unsafe"
+)
+
+// Stat returns the FileInfo structure describing file.
+// If there is an error, it will be of type *PathError.
+func (file *File) Stat() (FileInfo, error) {
+ if file == nil {
+ return nil, ErrInvalid
+ }
+ return statHandle(file.name, file.pfd.Sysfd)
+}
+
+// stat implements both Stat and Lstat of a file.
+func stat(funcname, name string, followSymlinks bool) (FileInfo, error) {
+ if len(name) == 0 {
+ return nil, &PathError{Op: funcname, Path: name, Err: syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
+ }
+ namep, err := syscall.UTF16PtrFromString(fixLongPath(name))
+ if err != nil {
+ return nil, &PathError{Op: funcname, Path: name, Err: err}
+ }
+
+ // Try GetFileAttributesEx first, because it is faster than CreateFile.
+ // See https://golang.org/issues/19922#issuecomment-300031421 for details.
+ var fa syscall.Win32FileAttributeData
+ err = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
+
+ // GetFileAttributesEx fails with ERROR_SHARING_VIOLATION error for
+ // files like c:\pagefile.sys. Use FindFirstFile for such files.
+ if err == windows.ERROR_SHARING_VIOLATION {
+ var fd syscall.Win32finddata
+ sh, err := syscall.FindFirstFile(namep, &fd)
+ if err != nil {
+ return nil, &PathError{Op: "FindFirstFile", Path: name, Err: err}
+ }
+ syscall.FindClose(sh)
+ if fd.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
+ // Not a symlink or mount point. FindFirstFile is good enough.
+ fs := newFileStatFromWin32finddata(&fd)
+ if err := fs.saveInfoFromPath(name); err != nil {
+ return nil, err
+ }
+ return fs, nil
+ }
+ }
+
+ if err == nil && fa.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT == 0 {
+ // The file is definitely not a symlink, because it isn't any kind of reparse point.
+ // The information we got from GetFileAttributesEx is good enough for now.
+ fs := &fileStat{
+ FileAttributes: fa.FileAttributes,
+ CreationTime: fa.CreationTime,
+ LastAccessTime: fa.LastAccessTime,
+ LastWriteTime: fa.LastWriteTime,
+ FileSizeHigh: fa.FileSizeHigh,
+ FileSizeLow: fa.FileSizeLow,
+ }
+ if err := fs.saveInfoFromPath(name); err != nil {
+ return nil, err
+ }
+ return fs, nil
+ }
+
+ // Use CreateFile to determine whether the file is a symlink and, if so,
+ // save information about the link target.
+ // Set FILE_FLAG_BACKUP_SEMANTICS so that CreateFile will create the handle
+ // even if name refers to a directory.
+ h, err := syscall.CreateFile(namep, 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OPEN_REPARSE_POINT, 0)
+ if err != nil {
+ // Since CreateFile failed, we can't determine whether name refers to a
+ // symlink, or some other kind of reparse point. Since we can't return a
+ // FileInfo with a known-accurate Mode, we must return an error.
+ return nil, &PathError{Op: "CreateFile", Path: name, Err: err}
+ }
+
+ fi, err := statHandle(name, h)
+ syscall.CloseHandle(h)
+ if err == nil && followSymlinks && fi.(*fileStat).isSymlink() {
+ // To obtain information about the link target, we reopen the file without
+ // FILE_FLAG_OPEN_REPARSE_POINT and examine the resulting handle.
+ // (See https://devblogs.microsoft.com/oldnewthing/20100212-00/?p=14963.)
+ h, err = syscall.CreateFile(namep, 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
+ if err != nil {
+ // name refers to a symlink, but we couldn't resolve the symlink target.
+ return nil, &PathError{Op: "CreateFile", Path: name, Err: err}
+ }
+ defer syscall.CloseHandle(h)
+ return statHandle(name, h)
+ }
+ return fi, err
+}
+
+func statHandle(name string, h syscall.Handle) (FileInfo, error) {
+ ft, err := syscall.GetFileType(h)
+ if err != nil {
+ return nil, &PathError{Op: "GetFileType", Path: name, Err: err}
+ }
+ switch ft {
+ case syscall.FILE_TYPE_PIPE, syscall.FILE_TYPE_CHAR:
+ return &fileStat{name: basename(name), filetype: ft}, nil
+ }
+ fs, err := newFileStatFromGetFileInformationByHandle(name, h)
+ if err != nil {
+ return nil, err
+ }
+ fs.filetype = ft
+ return fs, err
+}
+
+// statNolog implements Stat for Windows.
+func statNolog(name string) (FileInfo, error) {
+ return stat("Stat", name, true)
+}
+
+// lstatNolog implements Lstat for Windows.
+func lstatNolog(name string) (FileInfo, error) {
+ followSymlinks := false
+ if name != "" && IsPathSeparator(name[len(name)-1]) {
+ // We try to implement POSIX semantics for Lstat path resolution
+ // (per https://pubs.opengroup.org/onlinepubs/9699919799.2013edition/basedefs/V1_chap04.html#tag_04_12):
+ // symlinks before the last separator in the path must be resolved. Since
+ // the last separator in this case follows the last path element, we should
+ // follow symlinks in the last path element.
+ followSymlinks = true
+ }
+ return stat("Lstat", name, followSymlinks)
+}
diff --git a/contrib/go/_std_1.21/src/os/sticky_bsd.go b/contrib/go/_std_1.21/src/os/sticky_bsd.go
new file mode 100644
index 0000000000..a6d9339505
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/sticky_bsd.go
@@ -0,0 +1,11 @@
+// Copyright 2014 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.
+
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || netbsd || openbsd || solaris || wasip1
+
+package os
+
+// According to sticky(8), neither open(2) nor mkdir(2) will create
+// a file with the sticky bit set.
+const supportsCreateWithStickyBit = false
diff --git a/contrib/go/_std_1.21/src/os/sticky_notbsd.go b/contrib/go/_std_1.21/src/os/sticky_notbsd.go
new file mode 100644
index 0000000000..1d289b0fe3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/sticky_notbsd.go
@@ -0,0 +1,9 @@
+// Copyright 2014 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.
+
+//go:build !aix && !darwin && !dragonfly && !freebsd && !js && !netbsd && !openbsd && !solaris && !wasip1
+
+package os
+
+const supportsCreateWithStickyBit = true
diff --git a/contrib/go/_std_1.20/src/os/str.go b/contrib/go/_std_1.21/src/os/str.go
index 242c945caf..242c945caf 100644
--- a/contrib/go/_std_1.20/src/os/str.go
+++ b/contrib/go/_std_1.21/src/os/str.go
diff --git a/contrib/go/_std_1.20/src/os/sys.go b/contrib/go/_std_1.21/src/os/sys.go
index 28b0f6bab0..28b0f6bab0 100644
--- a/contrib/go/_std_1.20/src/os/sys.go
+++ b/contrib/go/_std_1.21/src/os/sys.go
diff --git a/contrib/go/_std_1.21/src/os/sys_bsd.go b/contrib/go/_std_1.21/src/os/sys_bsd.go
new file mode 100644
index 0000000000..63120fb9b4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/sys_bsd.go
@@ -0,0 +1,17 @@
+// Copyright 2009 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.
+
+//go:build darwin || dragonfly || freebsd || (js && wasm) || netbsd || openbsd || wasip1
+
+package os
+
+import "syscall"
+
+func hostname() (name string, err error) {
+ name, err = syscall.Sysctl("kern.hostname")
+ if err != nil {
+ return "", NewSyscallError("sysctl kern.hostname", err)
+ }
+ return name, nil
+}
diff --git a/contrib/go/_std_1.20/src/os/sys_linux.go b/contrib/go/_std_1.21/src/os/sys_linux.go
index 36a8a24455..36a8a24455 100644
--- a/contrib/go/_std_1.20/src/os/sys_linux.go
+++ b/contrib/go/_std_1.21/src/os/sys_linux.go
diff --git a/contrib/go/_std_1.20/src/os/sys_unix.go b/contrib/go/_std_1.21/src/os/sys_unix.go
index 79005c2cbd..79005c2cbd 100644
--- a/contrib/go/_std_1.20/src/os/sys_unix.go
+++ b/contrib/go/_std_1.21/src/os/sys_unix.go
diff --git a/contrib/go/_std_1.20/src/os/sys_windows.go b/contrib/go/_std_1.21/src/os/sys_windows.go
index 72ad90b924..72ad90b924 100644
--- a/contrib/go/_std_1.20/src/os/sys_windows.go
+++ b/contrib/go/_std_1.21/src/os/sys_windows.go
diff --git a/contrib/go/_std_1.21/src/os/tempfile.go b/contrib/go/_std_1.21/src/os/tempfile.go
new file mode 100644
index 0000000000..99f65c625a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/tempfile.go
@@ -0,0 +1,128 @@
+// Copyright 2010 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 os
+
+import (
+ "errors"
+ "internal/itoa"
+)
+
+// fastrand provided by runtime.
+// We generate random temporary file names so that there's a good
+// chance the file doesn't exist yet - keeps the number of tries in
+// TempFile to a minimum.
+func fastrand() uint32
+
+func nextRandom() string {
+ return itoa.Uitoa(uint(fastrand()))
+}
+
+// CreateTemp creates a new temporary file in the directory dir,
+// opens the file for reading and writing, and returns the resulting file.
+// The filename is generated by taking pattern and adding a random string to the end.
+// If pattern includes a "*", the random string replaces the last "*".
+// If dir is the empty string, CreateTemp uses the default directory for temporary files, as returned by TempDir.
+// Multiple programs or goroutines calling CreateTemp simultaneously will not choose the same file.
+// The caller can use the file's Name method to find the pathname of the file.
+// It is the caller's responsibility to remove the file when it is no longer needed.
+func CreateTemp(dir, pattern string) (*File, error) {
+ if dir == "" {
+ dir = TempDir()
+ }
+
+ prefix, suffix, err := prefixAndSuffix(pattern)
+ if err != nil {
+ return nil, &PathError{Op: "createtemp", Path: pattern, Err: err}
+ }
+ prefix = joinPath(dir, prefix)
+
+ try := 0
+ for {
+ name := prefix + nextRandom() + suffix
+ f, err := OpenFile(name, O_RDWR|O_CREATE|O_EXCL, 0600)
+ if IsExist(err) {
+ if try++; try < 10000 {
+ continue
+ }
+ return nil, &PathError{Op: "createtemp", Path: prefix + "*" + suffix, Err: ErrExist}
+ }
+ return f, err
+ }
+}
+
+var errPatternHasSeparator = errors.New("pattern contains path separator")
+
+// prefixAndSuffix splits pattern by the last wildcard "*", if applicable,
+// returning prefix as the part before "*" and suffix as the part after "*".
+func prefixAndSuffix(pattern string) (prefix, suffix string, err error) {
+ for i := 0; i < len(pattern); i++ {
+ if IsPathSeparator(pattern[i]) {
+ return "", "", errPatternHasSeparator
+ }
+ }
+ if pos := lastIndex(pattern, '*'); pos != -1 {
+ prefix, suffix = pattern[:pos], pattern[pos+1:]
+ } else {
+ prefix = pattern
+ }
+ return prefix, suffix, nil
+}
+
+// MkdirTemp creates a new temporary directory in the directory dir
+// and returns the pathname of the new directory.
+// The new directory's name is generated by adding a random string to the end of pattern.
+// If pattern includes a "*", the random string replaces the last "*" instead.
+// If dir is the empty string, MkdirTemp uses the default directory for temporary files, as returned by TempDir.
+// Multiple programs or goroutines calling MkdirTemp simultaneously will not choose the same directory.
+// It is the caller's responsibility to remove the directory when it is no longer needed.
+func MkdirTemp(dir, pattern string) (string, error) {
+ if dir == "" {
+ dir = TempDir()
+ }
+
+ prefix, suffix, err := prefixAndSuffix(pattern)
+ if err != nil {
+ return "", &PathError{Op: "mkdirtemp", Path: pattern, Err: err}
+ }
+ prefix = joinPath(dir, prefix)
+
+ try := 0
+ for {
+ name := prefix + nextRandom() + suffix
+ err := Mkdir(name, 0700)
+ if err == nil {
+ return name, nil
+ }
+ if IsExist(err) {
+ if try++; try < 10000 {
+ continue
+ }
+ return "", &PathError{Op: "mkdirtemp", Path: dir + string(PathSeparator) + prefix + "*" + suffix, Err: ErrExist}
+ }
+ if IsNotExist(err) {
+ if _, err := Stat(dir); IsNotExist(err) {
+ return "", err
+ }
+ }
+ return "", err
+ }
+}
+
+func joinPath(dir, name string) string {
+ if len(dir) > 0 && IsPathSeparator(dir[len(dir)-1]) {
+ return dir + name
+ }
+ return dir + string(PathSeparator) + name
+}
+
+// lastIndex from the strings package.
+func lastIndex(s string, sep byte) int {
+ for i := len(s) - 1; i >= 0; i-- {
+ if s[i] == sep {
+ return i
+ }
+ }
+ return -1
+}
diff --git a/contrib/go/_std_1.20/src/os/types.go b/contrib/go/_std_1.21/src/os/types.go
index d8edd98b68..d8edd98b68 100644
--- a/contrib/go/_std_1.20/src/os/types.go
+++ b/contrib/go/_std_1.21/src/os/types.go
diff --git a/contrib/go/_std_1.20/src/os/types_unix.go b/contrib/go/_std_1.21/src/os/types_unix.go
index 1b90a5a141..1b90a5a141 100644
--- a/contrib/go/_std_1.20/src/os/types_unix.go
+++ b/contrib/go/_std_1.21/src/os/types_unix.go
diff --git a/contrib/go/_std_1.21/src/os/types_windows.go b/contrib/go/_std_1.21/src/os/types_windows.go
new file mode 100644
index 0000000000..9a3d508783
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/types_windows.go
@@ -0,0 +1,246 @@
+// Copyright 2009 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 os
+
+import (
+ "internal/syscall/windows"
+ "sync"
+ "syscall"
+ "time"
+ "unsafe"
+)
+
+// A fileStat is the implementation of FileInfo returned by Stat and Lstat.
+type fileStat struct {
+ name string
+
+ // from ByHandleFileInformation, Win32FileAttributeData and Win32finddata
+ FileAttributes uint32
+ CreationTime syscall.Filetime
+ LastAccessTime syscall.Filetime
+ LastWriteTime syscall.Filetime
+ FileSizeHigh uint32
+ FileSizeLow uint32
+
+ // from Win32finddata
+ ReparseTag uint32
+
+ // what syscall.GetFileType returns
+ filetype uint32
+
+ // used to implement SameFile
+ sync.Mutex
+ path string
+ vol uint32
+ idxhi uint32
+ idxlo uint32
+ appendNameToPath bool
+}
+
+// newFileStatFromGetFileInformationByHandle calls GetFileInformationByHandle
+// to gather all required information about the file handle h.
+func newFileStatFromGetFileInformationByHandle(path string, h syscall.Handle) (fs *fileStat, err error) {
+ var d syscall.ByHandleFileInformation
+ err = syscall.GetFileInformationByHandle(h, &d)
+ if err != nil {
+ return nil, &PathError{Op: "GetFileInformationByHandle", Path: path, Err: err}
+ }
+
+ var ti windows.FILE_ATTRIBUTE_TAG_INFO
+ err = windows.GetFileInformationByHandleEx(h, windows.FileAttributeTagInfo, (*byte)(unsafe.Pointer(&ti)), uint32(unsafe.Sizeof(ti)))
+ if err != nil {
+ if errno, ok := err.(syscall.Errno); ok && errno == windows.ERROR_INVALID_PARAMETER {
+ // It appears calling GetFileInformationByHandleEx with
+ // FILE_ATTRIBUTE_TAG_INFO fails on FAT file system with
+ // ERROR_INVALID_PARAMETER. Clear ti.ReparseTag in that
+ // instance to indicate no symlinks are possible.
+ ti.ReparseTag = 0
+ } else {
+ return nil, &PathError{Op: "GetFileInformationByHandleEx", Path: path, Err: err}
+ }
+ }
+
+ return &fileStat{
+ name: basename(path),
+ FileAttributes: d.FileAttributes,
+ CreationTime: d.CreationTime,
+ LastAccessTime: d.LastAccessTime,
+ LastWriteTime: d.LastWriteTime,
+ FileSizeHigh: d.FileSizeHigh,
+ FileSizeLow: d.FileSizeLow,
+ vol: d.VolumeSerialNumber,
+ idxhi: d.FileIndexHigh,
+ idxlo: d.FileIndexLow,
+ ReparseTag: ti.ReparseTag,
+ // fileStat.path is used by os.SameFile to decide if it needs
+ // to fetch vol, idxhi and idxlo. But these are already set,
+ // so set fileStat.path to "" to prevent os.SameFile doing it again.
+ }, nil
+}
+
+// newFileStatFromWin32finddata copies all required information
+// from syscall.Win32finddata d into the newly created fileStat.
+func newFileStatFromWin32finddata(d *syscall.Win32finddata) *fileStat {
+ fs := &fileStat{
+ FileAttributes: d.FileAttributes,
+ CreationTime: d.CreationTime,
+ LastAccessTime: d.LastAccessTime,
+ LastWriteTime: d.LastWriteTime,
+ FileSizeHigh: d.FileSizeHigh,
+ FileSizeLow: d.FileSizeLow,
+ }
+ if d.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
+ // Per https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-win32_find_dataw:
+ // “If the dwFileAttributes member includes the FILE_ATTRIBUTE_REPARSE_POINT
+ // attribute, this member specifies the reparse point tag. Otherwise, this
+ // value is undefined and should not be used.”
+ fs.ReparseTag = d.Reserved0
+ }
+ return fs
+}
+
+func (fs *fileStat) isSymlink() bool {
+ // As of https://go.dev/cl/86556, we treat MOUNT_POINT reparse points as
+ // symlinks because otherwise certain directory junction tests in the
+ // path/filepath package would fail.
+ //
+ // However,
+ // https://learn.microsoft.com/en-us/windows/win32/fileio/hard-links-and-junctions
+ // seems to suggest that directory junctions should be treated like hard
+ // links, not symlinks.
+ //
+ // TODO(bcmills): Get more input from Microsoft on what the behavior ought to
+ // be for MOUNT_POINT reparse points.
+
+ return fs.ReparseTag == syscall.IO_REPARSE_TAG_SYMLINK ||
+ fs.ReparseTag == windows.IO_REPARSE_TAG_MOUNT_POINT
+}
+
+func (fs *fileStat) Size() int64 {
+ return int64(fs.FileSizeHigh)<<32 + int64(fs.FileSizeLow)
+}
+
+func (fs *fileStat) Mode() (m FileMode) {
+ if fs.FileAttributes&syscall.FILE_ATTRIBUTE_READONLY != 0 {
+ m |= 0444
+ } else {
+ m |= 0666
+ }
+ if fs.isSymlink() {
+ return m | ModeSymlink
+ }
+ if fs.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
+ m |= ModeDir | 0111
+ }
+ switch fs.filetype {
+ case syscall.FILE_TYPE_PIPE:
+ m |= ModeNamedPipe
+ case syscall.FILE_TYPE_CHAR:
+ m |= ModeDevice | ModeCharDevice
+ }
+ if fs.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 && m&ModeType == 0 {
+ m |= ModeIrregular
+ }
+ return m
+}
+
+func (fs *fileStat) ModTime() time.Time {
+ return time.Unix(0, fs.LastWriteTime.Nanoseconds())
+}
+
+// Sys returns syscall.Win32FileAttributeData for file fs.
+func (fs *fileStat) Sys() any {
+ return &syscall.Win32FileAttributeData{
+ FileAttributes: fs.FileAttributes,
+ CreationTime: fs.CreationTime,
+ LastAccessTime: fs.LastAccessTime,
+ LastWriteTime: fs.LastWriteTime,
+ FileSizeHigh: fs.FileSizeHigh,
+ FileSizeLow: fs.FileSizeLow,
+ }
+}
+
+func (fs *fileStat) loadFileId() error {
+ fs.Lock()
+ defer fs.Unlock()
+ if fs.path == "" {
+ // already done
+ return nil
+ }
+ var path string
+ if fs.appendNameToPath {
+ path = fs.path + `\` + fs.name
+ } else {
+ path = fs.path
+ }
+ pathp, err := syscall.UTF16PtrFromString(path)
+ if err != nil {
+ return err
+ }
+
+ // Per https://learn.microsoft.com/en-us/windows/win32/fileio/reparse-points-and-file-operations,
+ // “Applications that use the CreateFile function should specify the
+ // FILE_FLAG_OPEN_REPARSE_POINT flag when opening the file if it is a reparse
+ // point.”
+ //
+ // And per https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew,
+ // “If the file is not a reparse point, then this flag is ignored.”
+ //
+ // So we set FILE_FLAG_OPEN_REPARSE_POINT unconditionally, since we want
+ // information about the reparse point itself.
+ //
+ // If the file is a symlink, the symlink target should have already been
+ // resolved when the fileStat was created, so we don't need to worry about
+ // resolving symlink reparse points again here.
+ attrs := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS | syscall.FILE_FLAG_OPEN_REPARSE_POINT)
+
+ h, err := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, attrs, 0)
+ if err != nil {
+ return err
+ }
+ defer syscall.CloseHandle(h)
+ var i syscall.ByHandleFileInformation
+ err = syscall.GetFileInformationByHandle(h, &i)
+ if err != nil {
+ return err
+ }
+ fs.path = ""
+ fs.vol = i.VolumeSerialNumber
+ fs.idxhi = i.FileIndexHigh
+ fs.idxlo = i.FileIndexLow
+ return nil
+}
+
+// saveInfoFromPath saves full path of the file to be used by os.SameFile later,
+// and set name from path.
+func (fs *fileStat) saveInfoFromPath(path string) error {
+ fs.path = path
+ if !isAbs(fs.path) {
+ var err error
+ fs.path, err = syscall.FullPath(fs.path)
+ if err != nil {
+ return &PathError{Op: "FullPath", Path: path, Err: err}
+ }
+ }
+ fs.name = basename(path)
+ return nil
+}
+
+func sameFile(fs1, fs2 *fileStat) bool {
+ e := fs1.loadFileId()
+ if e != nil {
+ return false
+ }
+ e = fs2.loadFileId()
+ if e != nil {
+ return false
+ }
+ return fs1.vol == fs2.vol && fs1.idxhi == fs2.idxhi && fs1.idxlo == fs2.idxlo
+}
+
+// For testing.
+func atime(fi FileInfo) time.Time {
+ return time.Unix(0, fi.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
+}
diff --git a/contrib/go/_std_1.20/src/os/user/cgo_listgroups_unix.go b/contrib/go/_std_1.21/src/os/user/cgo_listgroups_unix.go
index 59636954b2..59636954b2 100644
--- a/contrib/go/_std_1.20/src/os/user/cgo_listgroups_unix.go
+++ b/contrib/go/_std_1.21/src/os/user/cgo_listgroups_unix.go
diff --git a/contrib/go/_std_1.20/src/os/user/cgo_lookup_cgo.go b/contrib/go/_std_1.21/src/os/user/cgo_lookup_cgo.go
index 4f78dcad23..4f78dcad23 100644
--- a/contrib/go/_std_1.20/src/os/user/cgo_lookup_cgo.go
+++ b/contrib/go/_std_1.21/src/os/user/cgo_lookup_cgo.go
diff --git a/contrib/go/_std_1.20/src/os/user/cgo_lookup_syscall.go b/contrib/go/_std_1.21/src/os/user/cgo_lookup_syscall.go
index 321df652be..321df652be 100644
--- a/contrib/go/_std_1.20/src/os/user/cgo_lookup_syscall.go
+++ b/contrib/go/_std_1.21/src/os/user/cgo_lookup_syscall.go
diff --git a/contrib/go/_std_1.20/src/os/user/cgo_lookup_unix.go b/contrib/go/_std_1.21/src/os/user/cgo_lookup_unix.go
index 3735971eb4..3735971eb4 100644
--- a/contrib/go/_std_1.20/src/os/user/cgo_lookup_unix.go
+++ b/contrib/go/_std_1.21/src/os/user/cgo_lookup_unix.go
diff --git a/contrib/go/_std_1.20/src/os/user/getgrouplist_syscall.go b/contrib/go/_std_1.21/src/os/user/getgrouplist_syscall.go
index 41b64fca93..41b64fca93 100644
--- a/contrib/go/_std_1.20/src/os/user/getgrouplist_syscall.go
+++ b/contrib/go/_std_1.21/src/os/user/getgrouplist_syscall.go
diff --git a/contrib/go/_std_1.20/src/os/user/getgrouplist_unix.go b/contrib/go/_std_1.21/src/os/user/getgrouplist_unix.go
index fb482d35ba..fb482d35ba 100644
--- a/contrib/go/_std_1.20/src/os/user/getgrouplist_unix.go
+++ b/contrib/go/_std_1.21/src/os/user/getgrouplist_unix.go
diff --git a/contrib/go/_std_1.20/src/os/user/lookup.go b/contrib/go/_std_1.21/src/os/user/lookup.go
index ed33d0c7cd..ed33d0c7cd 100644
--- a/contrib/go/_std_1.20/src/os/user/lookup.go
+++ b/contrib/go/_std_1.21/src/os/user/lookup.go
diff --git a/contrib/go/_std_1.20/src/os/user/lookup_windows.go b/contrib/go/_std_1.21/src/os/user/lookup_windows.go
index e64b8ae028..e64b8ae028 100644
--- a/contrib/go/_std_1.20/src/os/user/lookup_windows.go
+++ b/contrib/go/_std_1.21/src/os/user/lookup_windows.go
diff --git a/contrib/go/_std_1.20/src/os/user/user.go b/contrib/go/_std_1.21/src/os/user/user.go
index 0307d2ad6a..0307d2ad6a 100644
--- a/contrib/go/_std_1.20/src/os/user/user.go
+++ b/contrib/go/_std_1.21/src/os/user/user.go
diff --git a/contrib/go/_std_1.20/src/os/user/ya.make b/contrib/go/_std_1.21/src/os/user/ya.make
index 0005f463d8..0005f463d8 100644
--- a/contrib/go/_std_1.20/src/os/user/ya.make
+++ b/contrib/go/_std_1.21/src/os/user/ya.make
diff --git a/contrib/go/_std_1.21/src/os/wait_unimp.go b/contrib/go/_std_1.21/src/os/wait_unimp.go
new file mode 100644
index 0000000000..810e35da63
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/wait_unimp.go
@@ -0,0 +1,21 @@
+// Copyright 2016 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.
+
+// aix, darwin, js/wasm, openbsd, solaris and wasip1/wasm don't implement
+// waitid/wait6.
+
+//go:build aix || darwin || (js && wasm) || openbsd || solaris || wasip1
+
+package os
+
+// blockUntilWaitable attempts to block until a call to p.Wait will
+// succeed immediately, and reports whether it has done so.
+// It does not actually call p.Wait.
+// This version is used on systems that do not implement waitid,
+// or where we have not implemented it yet. Note that this is racy:
+// a call to Process.Signal can in an extremely unlikely case send a
+// signal to the wrong process, see issue #13987.
+func (p *Process) blockUntilWaitable() (bool, error) {
+ return false, nil
+}
diff --git a/contrib/go/_std_1.20/src/os/wait_waitid.go b/contrib/go/_std_1.21/src/os/wait_waitid.go
index c0503b209c..c0503b209c 100644
--- a/contrib/go/_std_1.20/src/os/wait_waitid.go
+++ b/contrib/go/_std_1.21/src/os/wait_waitid.go
diff --git a/contrib/go/_std_1.21/src/os/ya.make b/contrib/go/_std_1.21/src/os/ya.make
new file mode 100644
index 0000000000..1a759dfd18
--- /dev/null
+++ b/contrib/go/_std_1.21/src/os/ya.make
@@ -0,0 +1,147 @@
+GO_LIBRARY()
+
+SRCS(
+ dir.go
+ endian_little.go
+ env.go
+ error.go
+ error_errno.go
+ error_posix.go
+ exec.go
+ exec_posix.go
+ executable.go
+ file.go
+ file_posix.go
+ getwd.go
+ path.go
+ proc.go
+ rawconn.go
+ stat.go
+ str.go
+ sys.go
+ tempfile.go
+ types.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ env_test.go
+ error_test.go
+ example_test.go
+ executable_test.go
+ os_test.go
+ path_test.go
+ pipe_test.go
+ rawconn_test.go
+ read_test.go
+ removeall_test.go
+ rlimit_test.go
+ stat_test.go
+ tempfile_test.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ dir_unix.go
+ dirent_linux.go
+ exec_unix.go
+ executable_procfs.go
+ file_open_unix.go
+ file_unix.go
+ path_unix.go
+ pipe2_unix.go
+ readfrom_linux.go
+ removeall_at.go
+ rlimit.go
+ rlimit_stub.go
+ stat_linux.go
+ stat_unix.go
+ sticky_notbsd.go
+ sys_linux.go
+ sys_unix.go
+ types_unix.go
+ wait_waitid.go
+ )
+
+ GO_TEST_SRCS(
+ export_linux_test.go
+ export_unix_test.go
+ )
+
+ GO_XTEST_SRCS(
+ env_unix_test.go
+ error_unix_test.go
+ exec_unix_test.go
+ fifo_test.go
+ os_unix_test.go
+ readfrom_linux_test.go
+ timeout_test.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ dir_darwin.go
+ exec_unix.go
+ executable_darwin.go
+ file_open_unix.go
+ file_unix.go
+ path_unix.go
+ pipe_unix.go
+ readfrom_stub.go
+ removeall_at.go
+ rlimit.go
+ rlimit_darwin.go
+ stat_darwin.go
+ stat_unix.go
+ sticky_bsd.go
+ sys_bsd.go
+ sys_unix.go
+ types_unix.go
+ wait_unimp.go
+ )
+
+ GO_TEST_SRCS(export_unix_test.go)
+
+ GO_XTEST_SRCS(
+ env_unix_test.go
+ error_unix_test.go
+ exec_unix_test.go
+ fifo_test.go
+ os_unix_test.go
+ timeout_test.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ dir_windows.go
+ exec_windows.go
+ executable_windows.go
+ file_windows.go
+ path_windows.go
+ readfrom_stub.go
+ removeall_noat.go
+ stat_windows.go
+ sticky_notbsd.go
+ sys_windows.go
+ types_windows.go
+ )
+
+ GO_TEST_SRCS(export_windows_test.go)
+
+ GO_XTEST_SRCS(
+ error_windows_test.go
+ os_windows_test.go
+ path_windows_test.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+ exec
+ signal
+ user
+)
diff --git a/contrib/go/_std_1.20/src/path/filepath/match.go b/contrib/go/_std_1.21/src/path/filepath/match.go
index b5cc4b8cf3..b5cc4b8cf3 100644
--- a/contrib/go/_std_1.20/src/path/filepath/match.go
+++ b/contrib/go/_std_1.21/src/path/filepath/match.go
diff --git a/contrib/go/_std_1.21/src/path/filepath/path.go b/contrib/go/_std_1.21/src/path/filepath/path.go
new file mode 100644
index 0000000000..ca1d8b3116
--- /dev/null
+++ b/contrib/go/_std_1.21/src/path/filepath/path.go
@@ -0,0 +1,682 @@
+// Copyright 2009 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 filepath implements utility routines for manipulating filename paths
+// in a way compatible with the target operating system-defined file paths.
+//
+// The filepath package uses either forward slashes or backslashes,
+// depending on the operating system. To process paths such as URLs
+// that always use forward slashes regardless of the operating
+// system, see the [path] package.
+package filepath
+
+import (
+ "errors"
+ "io/fs"
+ "os"
+ "runtime"
+ "sort"
+ "strings"
+)
+
+// A lazybuf is a lazily constructed path buffer.
+// It supports append, reading previously appended bytes,
+// and retrieving the final string. It does not allocate a buffer
+// to hold the output until that output diverges from s.
+type lazybuf struct {
+ path string
+ buf []byte
+ w int
+ volAndPath string
+ volLen int
+}
+
+func (b *lazybuf) index(i int) byte {
+ if b.buf != nil {
+ return b.buf[i]
+ }
+ return b.path[i]
+}
+
+func (b *lazybuf) append(c byte) {
+ if b.buf == nil {
+ if b.w < len(b.path) && b.path[b.w] == c {
+ b.w++
+ return
+ }
+ b.buf = make([]byte, len(b.path))
+ copy(b.buf, b.path[:b.w])
+ }
+ b.buf[b.w] = c
+ b.w++
+}
+
+func (b *lazybuf) prepend(prefix ...byte) {
+ b.buf = append(prefix, b.buf...)
+ b.w += len(prefix)
+}
+
+func (b *lazybuf) string() string {
+ if b.buf == nil {
+ return b.volAndPath[:b.volLen+b.w]
+ }
+ return b.volAndPath[:b.volLen] + string(b.buf[:b.w])
+}
+
+const (
+ Separator = os.PathSeparator
+ ListSeparator = os.PathListSeparator
+)
+
+// Clean returns the shortest path name equivalent to path
+// by purely lexical processing. It applies the following rules
+// iteratively until no further processing can be done:
+//
+// 1. Replace multiple Separator elements with a single one.
+// 2. Eliminate each . path name element (the current directory).
+// 3. Eliminate each inner .. path name element (the parent directory)
+// along with the non-.. element that precedes it.
+// 4. Eliminate .. elements that begin a rooted path:
+// that is, replace "/.." by "/" at the beginning of a path,
+// assuming Separator is '/'.
+//
+// The returned path ends in a slash only if it represents a root directory,
+// such as "/" on Unix or `C:\` on Windows.
+//
+// Finally, any occurrences of slash are replaced by Separator.
+//
+// If the result of this process is an empty string, Clean
+// returns the string ".".
+//
+// On Windows, Clean does not modify the volume name other than to replace
+// occurrences of "/" with `\`.
+// For example, Clean("//host/share/../x") returns `\\host\share\x`.
+//
+// See also Rob Pike, “Lexical File Names in Plan 9 or
+// Getting Dot-Dot Right,”
+// https://9p.io/sys/doc/lexnames.html
+func Clean(path string) string {
+ originalPath := path
+ volLen := volumeNameLen(path)
+ path = path[volLen:]
+ if path == "" {
+ if volLen > 1 && os.IsPathSeparator(originalPath[0]) && os.IsPathSeparator(originalPath[1]) {
+ // should be UNC
+ return FromSlash(originalPath)
+ }
+ return originalPath + "."
+ }
+ rooted := os.IsPathSeparator(path[0])
+
+ // Invariants:
+ // reading from path; r is index of next byte to process.
+ // writing to buf; w is index of next byte to write.
+ // dotdot is index in buf where .. must stop, either because
+ // it is the leading slash or it is a leading ../../.. prefix.
+ n := len(path)
+ out := lazybuf{path: path, volAndPath: originalPath, volLen: volLen}
+ r, dotdot := 0, 0
+ if rooted {
+ out.append(Separator)
+ r, dotdot = 1, 1
+ }
+
+ for r < n {
+ switch {
+ case os.IsPathSeparator(path[r]):
+ // empty path element
+ r++
+ case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])):
+ // . element
+ r++
+ case path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])):
+ // .. element: remove to last separator
+ r += 2
+ switch {
+ case out.w > dotdot:
+ // can backtrack
+ out.w--
+ for out.w > dotdot && !os.IsPathSeparator(out.index(out.w)) {
+ out.w--
+ }
+ case !rooted:
+ // cannot backtrack, but not rooted, so append .. element.
+ if out.w > 0 {
+ out.append(Separator)
+ }
+ out.append('.')
+ out.append('.')
+ dotdot = out.w
+ }
+ default:
+ // real path element.
+ // add slash if needed
+ if rooted && out.w != 1 || !rooted && out.w != 0 {
+ out.append(Separator)
+ }
+ // copy element
+ for ; r < n && !os.IsPathSeparator(path[r]); r++ {
+ out.append(path[r])
+ }
+ }
+ }
+
+ // Turn empty string into "."
+ if out.w == 0 {
+ out.append('.')
+ }
+
+ if runtime.GOOS == "windows" && out.volLen == 0 && out.buf != nil {
+ // If a ':' appears in the path element at the start of a Windows path,
+ // insert a .\ at the beginning to avoid converting relative paths
+ // like a/../c: into c:.
+ for _, c := range out.buf {
+ if os.IsPathSeparator(c) {
+ break
+ }
+ if c == ':' {
+ out.prepend('.', Separator)
+ break
+ }
+ }
+ }
+
+ return FromSlash(out.string())
+}
+
+// IsLocal reports whether path, using lexical analysis only, has all of these properties:
+//
+// - is within the subtree rooted at the directory in which path is evaluated
+// - is not an absolute path
+// - is not empty
+// - on Windows, is not a reserved name such as "NUL"
+//
+// If IsLocal(path) returns true, then
+// Join(base, path) will always produce a path contained within base and
+// Clean(path) will always produce an unrooted path with no ".." path elements.
+//
+// IsLocal is a purely lexical operation.
+// In particular, it does not account for the effect of any symbolic links
+// that may exist in the filesystem.
+func IsLocal(path string) bool {
+ return isLocal(path)
+}
+
+func unixIsLocal(path string) bool {
+ if IsAbs(path) || path == "" {
+ return false
+ }
+ hasDots := false
+ for p := path; p != ""; {
+ var part string
+ part, p, _ = strings.Cut(p, "/")
+ if part == "." || part == ".." {
+ hasDots = true
+ break
+ }
+ }
+ if hasDots {
+ path = Clean(path)
+ }
+ if path == ".." || strings.HasPrefix(path, "../") {
+ return false
+ }
+ return true
+}
+
+// ToSlash returns the result of replacing each separator character
+// in path with a slash ('/') character. Multiple separators are
+// replaced by multiple slashes.
+func ToSlash(path string) string {
+ if Separator == '/' {
+ return path
+ }
+ return strings.ReplaceAll(path, string(Separator), "/")
+}
+
+// FromSlash returns the result of replacing each slash ('/') character
+// in path with a separator character. Multiple slashes are replaced
+// by multiple separators.
+func FromSlash(path string) string {
+ if Separator == '/' {
+ return path
+ }
+ return strings.ReplaceAll(path, "/", string(Separator))
+}
+
+// SplitList splits a list of paths joined by the OS-specific ListSeparator,
+// usually found in PATH or GOPATH environment variables.
+// Unlike strings.Split, SplitList returns an empty slice when passed an empty
+// string.
+func SplitList(path string) []string {
+ return splitList(path)
+}
+
+// Split splits path immediately following the final Separator,
+// separating it into a directory and file name component.
+// If there is no Separator in path, Split returns an empty dir
+// and file set to path.
+// The returned values have the property that path = dir+file.
+func Split(path string) (dir, file string) {
+ vol := VolumeName(path)
+ i := len(path) - 1
+ for i >= len(vol) && !os.IsPathSeparator(path[i]) {
+ i--
+ }
+ return path[:i+1], path[i+1:]
+}
+
+// Join joins any number of path elements into a single path,
+// separating them with an OS specific Separator. Empty elements
+// are ignored. The result is Cleaned. However, if the argument
+// list is empty or all its elements are empty, Join returns
+// an empty string.
+// On Windows, the result will only be a UNC path if the first
+// non-empty element is a UNC path.
+func Join(elem ...string) string {
+ return join(elem)
+}
+
+// Ext returns the file name extension used by path.
+// The extension is the suffix beginning at the final dot
+// in the final element of path; it is empty if there is
+// no dot.
+func Ext(path string) string {
+ for i := len(path) - 1; i >= 0 && !os.IsPathSeparator(path[i]); i-- {
+ if path[i] == '.' {
+ return path[i:]
+ }
+ }
+ return ""
+}
+
+// EvalSymlinks returns the path name after the evaluation of any symbolic
+// links.
+// If path is relative the result will be relative to the current directory,
+// unless one of the components is an absolute symbolic link.
+// EvalSymlinks calls Clean on the result.
+func EvalSymlinks(path string) (string, error) {
+ return evalSymlinks(path)
+}
+
+// Abs returns an absolute representation of path.
+// If the path is not absolute it will be joined with the current
+// working directory to turn it into an absolute path. The absolute
+// path name for a given file is not guaranteed to be unique.
+// Abs calls Clean on the result.
+func Abs(path string) (string, error) {
+ return abs(path)
+}
+
+func unixAbs(path string) (string, error) {
+ if IsAbs(path) {
+ return Clean(path), nil
+ }
+ wd, err := os.Getwd()
+ if err != nil {
+ return "", err
+ }
+ return Join(wd, path), nil
+}
+
+// Rel returns a relative path that is lexically equivalent to targpath when
+// joined to basepath with an intervening separator. That is,
+// Join(basepath, Rel(basepath, targpath)) is equivalent to targpath itself.
+// On success, the returned path will always be relative to basepath,
+// even if basepath and targpath share no elements.
+// An error is returned if targpath can't be made relative to basepath or if
+// knowing the current working directory would be necessary to compute it.
+// Rel calls Clean on the result.
+func Rel(basepath, targpath string) (string, error) {
+ baseVol := VolumeName(basepath)
+ targVol := VolumeName(targpath)
+ base := Clean(basepath)
+ targ := Clean(targpath)
+ if sameWord(targ, base) {
+ return ".", nil
+ }
+ base = base[len(baseVol):]
+ targ = targ[len(targVol):]
+ if base == "." {
+ base = ""
+ } else if base == "" && volumeNameLen(baseVol) > 2 /* isUNC */ {
+ // Treat any targetpath matching `\\host\share` basepath as absolute path.
+ base = string(Separator)
+ }
+
+ // Can't use IsAbs - `\a` and `a` are both relative in Windows.
+ baseSlashed := len(base) > 0 && base[0] == Separator
+ targSlashed := len(targ) > 0 && targ[0] == Separator
+ if baseSlashed != targSlashed || !sameWord(baseVol, targVol) {
+ return "", errors.New("Rel: can't make " + targpath + " relative to " + basepath)
+ }
+ // Position base[b0:bi] and targ[t0:ti] at the first differing elements.
+ bl := len(base)
+ tl := len(targ)
+ var b0, bi, t0, ti int
+ for {
+ for bi < bl && base[bi] != Separator {
+ bi++
+ }
+ for ti < tl && targ[ti] != Separator {
+ ti++
+ }
+ if !sameWord(targ[t0:ti], base[b0:bi]) {
+ break
+ }
+ if bi < bl {
+ bi++
+ }
+ if ti < tl {
+ ti++
+ }
+ b0 = bi
+ t0 = ti
+ }
+ if base[b0:bi] == ".." {
+ return "", errors.New("Rel: can't make " + targpath + " relative to " + basepath)
+ }
+ if b0 != bl {
+ // Base elements left. Must go up before going down.
+ seps := strings.Count(base[b0:bl], string(Separator))
+ size := 2 + seps*3
+ if tl != t0 {
+ size += 1 + tl - t0
+ }
+ buf := make([]byte, size)
+ n := copy(buf, "..")
+ for i := 0; i < seps; i++ {
+ buf[n] = Separator
+ copy(buf[n+1:], "..")
+ n += 3
+ }
+ if t0 != tl {
+ buf[n] = Separator
+ copy(buf[n+1:], targ[t0:])
+ }
+ return string(buf), nil
+ }
+ return targ[t0:], nil
+}
+
+// SkipDir is used as a return value from WalkFuncs to indicate that
+// the directory named in the call is to be skipped. It is not returned
+// as an error by any function.
+var SkipDir error = fs.SkipDir
+
+// SkipAll is used as a return value from WalkFuncs to indicate that
+// all remaining files and directories are to be skipped. It is not returned
+// as an error by any function.
+var SkipAll error = fs.SkipAll
+
+// WalkFunc is the type of the function called by Walk to visit each
+// file or directory.
+//
+// The path argument contains the argument to Walk as a prefix.
+// That is, if Walk is called with root argument "dir" and finds a file
+// named "a" in that directory, the walk function will be called with
+// argument "dir/a".
+//
+// The directory and file are joined with Join, which may clean the
+// directory name: if Walk is called with the root argument "x/../dir"
+// and finds a file named "a" in that directory, the walk function will
+// be called with argument "dir/a", not "x/../dir/a".
+//
+// The info argument is the fs.FileInfo for the named path.
+//
+// The error result returned by the function controls how Walk continues.
+// If the function returns the special value SkipDir, Walk skips the
+// current directory (path if info.IsDir() is true, otherwise path's
+// parent directory). If the function returns the special value SkipAll,
+// Walk skips all remaining files and directories. Otherwise, if the function
+// returns a non-nil error, Walk stops entirely and returns that error.
+//
+// The err argument reports an error related to path, signaling that Walk
+// will not walk into that directory. The function can decide how to
+// handle that error; as described earlier, returning the error will
+// cause Walk to stop walking the entire tree.
+//
+// Walk calls the function with a non-nil err argument in two cases.
+//
+// First, if an os.Lstat on the root directory or any directory or file
+// in the tree fails, Walk calls the function with path set to that
+// directory or file's path, info set to nil, and err set to the error
+// from os.Lstat.
+//
+// Second, if a directory's Readdirnames method fails, Walk calls the
+// function with path set to the directory's path, info, set to an
+// fs.FileInfo describing the directory, and err set to the error from
+// Readdirnames.
+type WalkFunc func(path string, info fs.FileInfo, err error) error
+
+var lstat = os.Lstat // for testing
+
+// walkDir recursively descends path, calling walkDirFn.
+func walkDir(path string, d fs.DirEntry, walkDirFn fs.WalkDirFunc) error {
+ if err := walkDirFn(path, d, nil); err != nil || !d.IsDir() {
+ if err == SkipDir && d.IsDir() {
+ // Successfully skipped directory.
+ err = nil
+ }
+ return err
+ }
+
+ dirs, err := readDir(path)
+ if err != nil {
+ // Second call, to report ReadDir error.
+ err = walkDirFn(path, d, err)
+ if err != nil {
+ if err == SkipDir && d.IsDir() {
+ err = nil
+ }
+ return err
+ }
+ }
+
+ for _, d1 := range dirs {
+ path1 := Join(path, d1.Name())
+ if err := walkDir(path1, d1, walkDirFn); err != nil {
+ if err == SkipDir {
+ break
+ }
+ return err
+ }
+ }
+ return nil
+}
+
+// walk recursively descends path, calling walkFn.
+func walk(path string, info fs.FileInfo, walkFn WalkFunc) error {
+ if !info.IsDir() {
+ return walkFn(path, info, nil)
+ }
+
+ names, err := readDirNames(path)
+ err1 := walkFn(path, info, err)
+ // If err != nil, walk can't walk into this directory.
+ // err1 != nil means walkFn want walk to skip this directory or stop walking.
+ // Therefore, if one of err and err1 isn't nil, walk will return.
+ if err != nil || err1 != nil {
+ // The caller's behavior is controlled by the return value, which is decided
+ // by walkFn. walkFn may ignore err and return nil.
+ // If walkFn returns SkipDir or SkipAll, it will be handled by the caller.
+ // So walk should return whatever walkFn returns.
+ return err1
+ }
+
+ for _, name := range names {
+ filename := Join(path, name)
+ fileInfo, err := lstat(filename)
+ if err != nil {
+ if err := walkFn(filename, fileInfo, err); err != nil && err != SkipDir {
+ return err
+ }
+ } else {
+ err = walk(filename, fileInfo, walkFn)
+ if err != nil {
+ if !fileInfo.IsDir() || err != SkipDir {
+ return err
+ }
+ }
+ }
+ }
+ return nil
+}
+
+// WalkDir walks the file tree rooted at root, calling fn for each file or
+// directory in the tree, including root.
+//
+// All errors that arise visiting files and directories are filtered by fn:
+// see the fs.WalkDirFunc documentation for details.
+//
+// The files are walked in lexical order, which makes the output deterministic
+// but requires WalkDir to read an entire directory into memory before proceeding
+// to walk that directory.
+//
+// WalkDir does not follow symbolic links.
+//
+// WalkDir calls fn with paths that use the separator character appropriate
+// for the operating system. This is unlike [io/fs.WalkDir], which always
+// uses slash separated paths.
+func WalkDir(root string, fn fs.WalkDirFunc) error {
+ info, err := os.Lstat(root)
+ if err != nil {
+ err = fn(root, nil, err)
+ } else {
+ err = walkDir(root, &statDirEntry{info}, fn)
+ }
+ if err == SkipDir || err == SkipAll {
+ return nil
+ }
+ return err
+}
+
+type statDirEntry struct {
+ info fs.FileInfo
+}
+
+func (d *statDirEntry) Name() string { return d.info.Name() }
+func (d *statDirEntry) IsDir() bool { return d.info.IsDir() }
+func (d *statDirEntry) Type() fs.FileMode { return d.info.Mode().Type() }
+func (d *statDirEntry) Info() (fs.FileInfo, error) { return d.info, nil }
+
+func (d *statDirEntry) String() string {
+ return fs.FormatDirEntry(d)
+}
+
+// Walk walks the file tree rooted at root, calling fn for each file or
+// directory in the tree, including root.
+//
+// All errors that arise visiting files and directories are filtered by fn:
+// see the WalkFunc documentation for details.
+//
+// The files are walked in lexical order, which makes the output deterministic
+// but requires Walk to read an entire directory into memory before proceeding
+// to walk that directory.
+//
+// Walk does not follow symbolic links.
+//
+// Walk is less efficient than WalkDir, introduced in Go 1.16,
+// which avoids calling os.Lstat on every visited file or directory.
+func Walk(root string, fn WalkFunc) error {
+ info, err := os.Lstat(root)
+ if err != nil {
+ err = fn(root, nil, err)
+ } else {
+ err = walk(root, info, fn)
+ }
+ if err == SkipDir || err == SkipAll {
+ return nil
+ }
+ return err
+}
+
+// readDir reads the directory named by dirname and returns
+// a sorted list of directory entries.
+func readDir(dirname string) ([]fs.DirEntry, error) {
+ f, err := os.Open(dirname)
+ if err != nil {
+ return nil, err
+ }
+ dirs, err := f.ReadDir(-1)
+ f.Close()
+ if err != nil {
+ return nil, err
+ }
+ sort.Slice(dirs, func(i, j int) bool { return dirs[i].Name() < dirs[j].Name() })
+ return dirs, nil
+}
+
+// readDirNames reads the directory named by dirname and returns
+// a sorted list of directory entry names.
+func readDirNames(dirname string) ([]string, error) {
+ f, err := os.Open(dirname)
+ if err != nil {
+ return nil, err
+ }
+ names, err := f.Readdirnames(-1)
+ f.Close()
+ if err != nil {
+ return nil, err
+ }
+ sort.Strings(names)
+ return names, nil
+}
+
+// Base returns the last element of path.
+// Trailing path separators are removed before extracting the last element.
+// If the path is empty, Base returns ".".
+// If the path consists entirely of separators, Base returns a single separator.
+func Base(path string) string {
+ if path == "" {
+ return "."
+ }
+ // Strip trailing slashes.
+ for len(path) > 0 && os.IsPathSeparator(path[len(path)-1]) {
+ path = path[0 : len(path)-1]
+ }
+ // Throw away volume name
+ path = path[len(VolumeName(path)):]
+ // Find the last element
+ i := len(path) - 1
+ for i >= 0 && !os.IsPathSeparator(path[i]) {
+ i--
+ }
+ if i >= 0 {
+ path = path[i+1:]
+ }
+ // If empty now, it had only slashes.
+ if path == "" {
+ return string(Separator)
+ }
+ return path
+}
+
+// Dir returns all but the last element of path, typically the path's directory.
+// After dropping the final element, Dir calls Clean on the path and trailing
+// slashes are removed.
+// If the path is empty, Dir returns ".".
+// If the path consists entirely of separators, Dir returns a single separator.
+// The returned path does not end in a separator unless it is the root directory.
+func Dir(path string) string {
+ vol := VolumeName(path)
+ i := len(path) - 1
+ for i >= len(vol) && !os.IsPathSeparator(path[i]) {
+ i--
+ }
+ dir := Clean(path[len(vol) : i+1])
+ if dir == "." && len(vol) > 2 {
+ // must be UNC
+ return vol
+ }
+ return vol + dir
+}
+
+// VolumeName returns leading volume name.
+// Given "C:\foo\bar" it returns "C:" on Windows.
+// Given "\\host\share\foo" it returns "\\host\share".
+// On other platforms it returns "".
+func VolumeName(path string) string {
+ return FromSlash(path[:volumeNameLen(path)])
+}
diff --git a/contrib/go/_std_1.21/src/path/filepath/path_unix.go b/contrib/go/_std_1.21/src/path/filepath/path_unix.go
new file mode 100644
index 0000000000..57e6217434
--- /dev/null
+++ b/contrib/go/_std_1.21/src/path/filepath/path_unix.go
@@ -0,0 +1,57 @@
+// Copyright 2010 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package filepath
+
+import "strings"
+
+func isLocal(path string) bool {
+ return unixIsLocal(path)
+}
+
+// IsAbs reports whether the path is absolute.
+func IsAbs(path string) bool {
+ return strings.HasPrefix(path, "/")
+}
+
+// volumeNameLen returns length of the leading volume name on Windows.
+// It returns 0 elsewhere.
+func volumeNameLen(path string) int {
+ return 0
+}
+
+// HasPrefix exists for historical compatibility and should not be used.
+//
+// Deprecated: HasPrefix does not respect path boundaries and
+// does not ignore case when required.
+func HasPrefix(p, prefix string) bool {
+ return strings.HasPrefix(p, prefix)
+}
+
+func splitList(path string) []string {
+ if path == "" {
+ return []string{}
+ }
+ return strings.Split(path, string(ListSeparator))
+}
+
+func abs(path string) (string, error) {
+ return unixAbs(path)
+}
+
+func join(elem []string) string {
+ // If there's a bug here, fix the logic in ./path_plan9.go too.
+ for i, e := range elem {
+ if e != "" {
+ return Clean(strings.Join(elem[i:], string(Separator)))
+ }
+ }
+ return ""
+}
+
+func sameWord(a, b string) bool {
+ return a == b
+}
diff --git a/contrib/go/_std_1.20/src/path/filepath/path_windows.go b/contrib/go/_std_1.21/src/path/filepath/path_windows.go
index 4dca9e0f55..4dca9e0f55 100644
--- a/contrib/go/_std_1.20/src/path/filepath/path_windows.go
+++ b/contrib/go/_std_1.21/src/path/filepath/path_windows.go
diff --git a/contrib/go/_std_1.21/src/path/filepath/symlink.go b/contrib/go/_std_1.21/src/path/filepath/symlink.go
new file mode 100644
index 0000000000..f9435e0d5b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/path/filepath/symlink.go
@@ -0,0 +1,149 @@
+// Copyright 2012 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 filepath
+
+import (
+ "errors"
+ "io/fs"
+ "os"
+ "runtime"
+ "syscall"
+)
+
+func walkSymlinks(path string) (string, error) {
+ volLen := volumeNameLen(path)
+ pathSeparator := string(os.PathSeparator)
+
+ if volLen < len(path) && os.IsPathSeparator(path[volLen]) {
+ volLen++
+ }
+ vol := path[:volLen]
+ dest := vol
+ linksWalked := 0
+ for start, end := volLen, volLen; start < len(path); start = end {
+ for start < len(path) && os.IsPathSeparator(path[start]) {
+ start++
+ }
+ end = start
+ for end < len(path) && !os.IsPathSeparator(path[end]) {
+ end++
+ }
+
+ // On Windows, "." can be a symlink.
+ // We look it up, and use the value if it is absolute.
+ // If not, we just return ".".
+ isWindowsDot := runtime.GOOS == "windows" && path[volumeNameLen(path):] == "."
+
+ // The next path component is in path[start:end].
+ if end == start {
+ // No more path components.
+ break
+ } else if path[start:end] == "." && !isWindowsDot {
+ // Ignore path component ".".
+ continue
+ } else if path[start:end] == ".." {
+ // Back up to previous component if possible.
+ // Note that volLen includes any leading slash.
+
+ // Set r to the index of the last slash in dest,
+ // after the volume.
+ var r int
+ for r = len(dest) - 1; r >= volLen; r-- {
+ if os.IsPathSeparator(dest[r]) {
+ break
+ }
+ }
+ if r < volLen || dest[r+1:] == ".." {
+ // Either path has no slashes
+ // (it's empty or just "C:")
+ // or it ends in a ".." we had to keep.
+ // Either way, keep this "..".
+ if len(dest) > volLen {
+ dest += pathSeparator
+ }
+ dest += ".."
+ } else {
+ // Discard everything since the last slash.
+ dest = dest[:r]
+ }
+ continue
+ }
+
+ // Ordinary path component. Add it to result.
+
+ if len(dest) > volumeNameLen(dest) && !os.IsPathSeparator(dest[len(dest)-1]) {
+ dest += pathSeparator
+ }
+
+ dest += path[start:end]
+
+ // Resolve symlink.
+
+ fi, err := os.Lstat(dest)
+ if err != nil {
+ return "", err
+ }
+
+ if fi.Mode()&fs.ModeSymlink == 0 {
+ if !fi.Mode().IsDir() && end < len(path) {
+ return "", syscall.ENOTDIR
+ }
+ continue
+ }
+
+ // Found symlink.
+
+ linksWalked++
+ if linksWalked > 255 {
+ return "", errors.New("EvalSymlinks: too many links")
+ }
+
+ link, err := os.Readlink(dest)
+ if err != nil {
+ return "", err
+ }
+
+ if isWindowsDot && !IsAbs(link) {
+ // On Windows, if "." is a relative symlink,
+ // just return ".".
+ break
+ }
+
+ path = link + path[end:]
+
+ v := volumeNameLen(link)
+ if v > 0 {
+ // Symlink to drive name is an absolute path.
+ if v < len(link) && os.IsPathSeparator(link[v]) {
+ v++
+ }
+ vol = link[:v]
+ dest = vol
+ end = len(vol)
+ } else if len(link) > 0 && os.IsPathSeparator(link[0]) {
+ // Symlink to absolute path.
+ dest = link[:1]
+ end = 1
+ vol = link[:1]
+ volLen = 1
+ } else {
+ // Symlink to relative path; replace last
+ // path component in dest.
+ var r int
+ for r = len(dest) - 1; r >= volLen; r-- {
+ if os.IsPathSeparator(dest[r]) {
+ break
+ }
+ }
+ if r < volLen {
+ dest = vol
+ } else {
+ dest = dest[:r]
+ }
+ end = 0
+ }
+ }
+ return Clean(dest), nil
+}
diff --git a/contrib/go/_std_1.20/src/path/filepath/symlink_unix.go b/contrib/go/_std_1.21/src/path/filepath/symlink_unix.go
index 4cac063be0..4cac063be0 100644
--- a/contrib/go/_std_1.20/src/path/filepath/symlink_unix.go
+++ b/contrib/go/_std_1.21/src/path/filepath/symlink_unix.go
diff --git a/contrib/go/_std_1.21/src/path/filepath/symlink_windows.go b/contrib/go/_std_1.21/src/path/filepath/symlink_windows.go
new file mode 100644
index 0000000000..8047ff83c1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/path/filepath/symlink_windows.go
@@ -0,0 +1,118 @@
+// Copyright 2012 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 filepath
+
+import (
+ "strings"
+ "syscall"
+)
+
+// normVolumeName is like VolumeName, but makes drive letter upper case.
+// result of EvalSymlinks must be unique, so we have
+// EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`).
+func normVolumeName(path string) string {
+ volume := VolumeName(path)
+
+ if len(volume) > 2 { // isUNC
+ return volume
+ }
+
+ return strings.ToUpper(volume)
+}
+
+// normBase returns the last element of path with correct case.
+func normBase(path string) (string, error) {
+ p, err := syscall.UTF16PtrFromString(path)
+ if err != nil {
+ return "", err
+ }
+
+ var data syscall.Win32finddata
+
+ h, err := syscall.FindFirstFile(p, &data)
+ if err != nil {
+ return "", err
+ }
+ syscall.FindClose(h)
+
+ return syscall.UTF16ToString(data.FileName[:]), nil
+}
+
+// baseIsDotDot reports whether the last element of path is "..".
+// The given path should be 'Clean'-ed in advance.
+func baseIsDotDot(path string) bool {
+ i := strings.LastIndexByte(path, Separator)
+ return path[i+1:] == ".."
+}
+
+// toNorm returns the normalized path that is guaranteed to be unique.
+// It should accept the following formats:
+// - UNC paths (e.g \\server\share\foo\bar)
+// - absolute paths (e.g C:\foo\bar)
+// - relative paths begin with drive letter (e.g C:foo\bar, C:..\foo\bar, C:.., C:.)
+// - relative paths begin with '\' (e.g \foo\bar)
+// - relative paths begin without '\' (e.g foo\bar, ..\foo\bar, .., .)
+//
+// The returned normalized path will be in the same form (of 5 listed above) as the input path.
+// If two paths A and B are indicating the same file with the same format, toNorm(A) should be equal to toNorm(B).
+// The normBase parameter should be equal to the normBase func, except for in tests. See docs on the normBase func.
+func toNorm(path string, normBase func(string) (string, error)) (string, error) {
+ if path == "" {
+ return path, nil
+ }
+
+ volume := normVolumeName(path)
+ path = path[len(volume):]
+
+ // skip special cases
+ if path == "" || path == "." || path == `\` {
+ return volume + path, nil
+ }
+
+ var normPath string
+
+ for {
+ if baseIsDotDot(path) {
+ normPath = path + `\` + normPath
+
+ break
+ }
+
+ name, err := normBase(volume + path)
+ if err != nil {
+ return "", err
+ }
+
+ normPath = name + `\` + normPath
+
+ i := strings.LastIndexByte(path, Separator)
+ if i == -1 {
+ break
+ }
+ if i == 0 { // `\Go` or `C:\Go`
+ normPath = `\` + normPath
+
+ break
+ }
+
+ path = path[:i]
+ }
+
+ normPath = normPath[:len(normPath)-1] // remove trailing '\'
+
+ return volume + normPath, nil
+}
+
+func evalSymlinks(path string) (string, error) {
+ newpath, err := walkSymlinks(path)
+ if err != nil {
+ return "", err
+ }
+ newpath, err = toNorm(newpath, normBase)
+ if err != nil {
+ return "", err
+ }
+ return newpath, nil
+}
diff --git a/contrib/go/_std_1.21/src/path/filepath/ya.make b/contrib/go/_std_1.21/src/path/filepath/ya.make
new file mode 100644
index 0000000000..ac067ec110
--- /dev/null
+++ b/contrib/go/_std_1.21/src/path/filepath/ya.make
@@ -0,0 +1,55 @@
+GO_LIBRARY()
+
+SRCS(
+ match.go
+ path.go
+ symlink.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ example_test.go
+ match_test.go
+ path_test.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ path_unix.go
+ symlink_unix.go
+ )
+
+ GO_XTEST_SRCS(
+ example_unix_test.go
+ example_unix_walk_test.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ path_unix.go
+ symlink_unix.go
+ )
+
+ GO_XTEST_SRCS(
+ example_unix_test.go
+ example_unix_walk_test.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ path_windows.go
+ symlink_windows.go
+ )
+
+ GO_TEST_SRCS(export_windows_test.go)
+
+ GO_XTEST_SRCS(path_windows_test.go)
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/path/match.go b/contrib/go/_std_1.21/src/path/match.go
index 673bbc7ff6..673bbc7ff6 100644
--- a/contrib/go/_std_1.20/src/path/match.go
+++ b/contrib/go/_std_1.21/src/path/match.go
diff --git a/contrib/go/_std_1.20/src/path/path.go b/contrib/go/_std_1.21/src/path/path.go
index 547b9debce..547b9debce 100644
--- a/contrib/go/_std_1.20/src/path/path.go
+++ b/contrib/go/_std_1.21/src/path/path.go
diff --git a/contrib/go/_std_1.21/src/path/ya.make b/contrib/go/_std_1.21/src/path/ya.make
new file mode 100644
index 0000000000..8cb503647a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/path/ya.make
@@ -0,0 +1,18 @@
+GO_LIBRARY()
+
+SRCS(
+ match.go
+ path.go
+)
+
+GO_XTEST_SRCS(
+ example_test.go
+ match_test.go
+ path_test.go
+)
+
+END()
+
+RECURSE(
+ filepath
+)
diff --git a/contrib/go/_std_1.21/src/reflect/abi.go b/contrib/go/_std_1.21/src/reflect/abi.go
new file mode 100644
index 0000000000..2b5f405380
--- /dev/null
+++ b/contrib/go/_std_1.21/src/reflect/abi.go
@@ -0,0 +1,510 @@
+// 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 reflect
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "unsafe"
+)
+
+// These variables are used by the register assignment
+// algorithm in this file.
+//
+// They should be modified with care (no other reflect code
+// may be executing) and are generally only modified
+// when testing this package.
+//
+// They should never be set higher than their internal/abi
+// constant counterparts, because the system relies on a
+// structure that is at least large enough to hold the
+// registers the system supports.
+//
+// Currently they're set to zero because using the actual
+// constants will break every part of the toolchain that
+// uses reflect to call functions (e.g. go test, or anything
+// that uses text/template). The values that are currently
+// commented out there should be the actual values once
+// we're ready to use the register ABI everywhere.
+var (
+ intArgRegs = abi.IntArgRegs
+ floatArgRegs = abi.FloatArgRegs
+ floatRegSize = uintptr(abi.EffectiveFloatRegSize)
+)
+
+// abiStep represents an ABI "instruction." Each instruction
+// describes one part of how to translate between a Go value
+// in memory and a call frame.
+type abiStep struct {
+ kind abiStepKind
+
+ // offset and size together describe a part of a Go value
+ // in memory.
+ offset uintptr
+ size uintptr // size in bytes of the part
+
+ // These fields describe the ABI side of the translation.
+ stkOff uintptr // stack offset, used if kind == abiStepStack
+ ireg int // integer register index, used if kind == abiStepIntReg or kind == abiStepPointer
+ freg int // FP register index, used if kind == abiStepFloatReg
+}
+
+// abiStepKind is the "op-code" for an abiStep instruction.
+type abiStepKind int
+
+const (
+ abiStepBad abiStepKind = iota
+ abiStepStack // copy to/from stack
+ abiStepIntReg // copy to/from integer register
+ abiStepPointer // copy pointer to/from integer register
+ abiStepFloatReg // copy to/from FP register
+)
+
+// abiSeq represents a sequence of ABI instructions for copying
+// from a series of reflect.Values to a call frame (for call arguments)
+// or vice-versa (for call results).
+//
+// An abiSeq should be populated by calling its addArg method.
+type abiSeq struct {
+ // steps is the set of instructions.
+ //
+ // The instructions are grouped together by whole arguments,
+ // with the starting index for the instructions
+ // of the i'th Go value available in valueStart.
+ //
+ // For instance, if this abiSeq represents 3 arguments
+ // passed to a function, then the 2nd argument's steps
+ // begin at steps[valueStart[1]].
+ //
+ // Because reflect accepts Go arguments in distinct
+ // Values and each Value is stored separately, each abiStep
+ // that begins a new argument will have its offset
+ // field == 0.
+ steps []abiStep
+ valueStart []int
+
+ stackBytes uintptr // stack space used
+ iregs, fregs int // registers used
+}
+
+func (a *abiSeq) dump() {
+ for i, p := range a.steps {
+ println("part", i, p.kind, p.offset, p.size, p.stkOff, p.ireg, p.freg)
+ }
+ print("values ")
+ for _, i := range a.valueStart {
+ print(i, " ")
+ }
+ println()
+ println("stack", a.stackBytes)
+ println("iregs", a.iregs)
+ println("fregs", a.fregs)
+}
+
+// stepsForValue returns the ABI instructions for translating
+// the i'th Go argument or return value represented by this
+// abiSeq to the Go ABI.
+func (a *abiSeq) stepsForValue(i int) []abiStep {
+ s := a.valueStart[i]
+ var e int
+ if i == len(a.valueStart)-1 {
+ e = len(a.steps)
+ } else {
+ e = a.valueStart[i+1]
+ }
+ return a.steps[s:e]
+}
+
+// addArg extends the abiSeq with a new Go value of type t.
+//
+// If the value was stack-assigned, returns the single
+// abiStep describing that translation, and nil otherwise.
+func (a *abiSeq) addArg(t *abi.Type) *abiStep {
+ // We'll always be adding a new value, so do that first.
+ pStart := len(a.steps)
+ a.valueStart = append(a.valueStart, pStart)
+ if t.Size() == 0 {
+ // If the size of the argument type is zero, then
+ // in order to degrade gracefully into ABI0, we need
+ // to stack-assign this type. The reason is that
+ // although zero-sized types take up no space on the
+ // stack, they do cause the next argument to be aligned.
+ // So just do that here, but don't bother actually
+ // generating a new ABI step for it (there's nothing to
+ // actually copy).
+ //
+ // We cannot handle this in the recursive case of
+ // regAssign because zero-sized *fields* of a
+ // non-zero-sized struct do not cause it to be
+ // stack-assigned. So we need a special case here
+ // at the top.
+ a.stackBytes = align(a.stackBytes, uintptr(t.Align()))
+ return nil
+ }
+ // Hold a copy of "a" so that we can roll back if
+ // register assignment fails.
+ aOld := *a
+ if !a.regAssign(t, 0) {
+ // Register assignment failed. Roll back any changes
+ // and stack-assign.
+ *a = aOld
+ a.stackAssign(t.Size(), uintptr(t.Align()))
+ return &a.steps[len(a.steps)-1]
+ }
+ return nil
+}
+
+// addRcvr extends the abiSeq with a new method call
+// receiver according to the interface calling convention.
+//
+// If the receiver was stack-assigned, returns the single
+// abiStep describing that translation, and nil otherwise.
+// Returns true if the receiver is a pointer.
+func (a *abiSeq) addRcvr(rcvr *abi.Type) (*abiStep, bool) {
+ // The receiver is always one word.
+ a.valueStart = append(a.valueStart, len(a.steps))
+ var ok, ptr bool
+ if ifaceIndir(rcvr) || rcvr.Pointers() {
+ ok = a.assignIntN(0, goarch.PtrSize, 1, 0b1)
+ ptr = true
+ } else {
+ // TODO(mknyszek): Is this case even possible?
+ // The interface data work never contains a non-pointer
+ // value. This case was copied over from older code
+ // in the reflect package which only conditionally added
+ // a pointer bit to the reflect.(Value).Call stack frame's
+ // GC bitmap.
+ ok = a.assignIntN(0, goarch.PtrSize, 1, 0b0)
+ ptr = false
+ }
+ if !ok {
+ a.stackAssign(goarch.PtrSize, goarch.PtrSize)
+ return &a.steps[len(a.steps)-1], ptr
+ }
+ return nil, ptr
+}
+
+// regAssign attempts to reserve argument registers for a value of
+// type t, stored at some offset.
+//
+// It returns whether or not the assignment succeeded, but
+// leaves any changes it made to a.steps behind, so the caller
+// must undo that work by adjusting a.steps if it fails.
+//
+// This method along with the assign* methods represent the
+// complete register-assignment algorithm for the Go ABI.
+func (a *abiSeq) regAssign(t *abi.Type, offset uintptr) bool {
+ switch Kind(t.Kind()) {
+ case UnsafePointer, Pointer, Chan, Map, Func:
+ return a.assignIntN(offset, t.Size(), 1, 0b1)
+ case Bool, Int, Uint, Int8, Uint8, Int16, Uint16, Int32, Uint32, Uintptr:
+ return a.assignIntN(offset, t.Size(), 1, 0b0)
+ case Int64, Uint64:
+ switch goarch.PtrSize {
+ case 4:
+ return a.assignIntN(offset, 4, 2, 0b0)
+ case 8:
+ return a.assignIntN(offset, 8, 1, 0b0)
+ }
+ case Float32, Float64:
+ return a.assignFloatN(offset, t.Size(), 1)
+ case Complex64:
+ return a.assignFloatN(offset, 4, 2)
+ case Complex128:
+ return a.assignFloatN(offset, 8, 2)
+ case String:
+ return a.assignIntN(offset, goarch.PtrSize, 2, 0b01)
+ case Interface:
+ return a.assignIntN(offset, goarch.PtrSize, 2, 0b10)
+ case Slice:
+ return a.assignIntN(offset, goarch.PtrSize, 3, 0b001)
+ case Array:
+ tt := (*arrayType)(unsafe.Pointer(t))
+ switch tt.Len {
+ case 0:
+ // There's nothing to assign, so don't modify
+ // a.steps but succeed so the caller doesn't
+ // try to stack-assign this value.
+ return true
+ case 1:
+ return a.regAssign(tt.Elem, offset)
+ default:
+ return false
+ }
+ case Struct:
+ st := (*structType)(unsafe.Pointer(t))
+ for i := range st.Fields {
+ f := &st.Fields[i]
+ if !a.regAssign(f.Typ, offset+f.Offset) {
+ return false
+ }
+ }
+ return true
+ default:
+ print("t.Kind == ", t.Kind(), "\n")
+ panic("unknown type kind")
+ }
+ panic("unhandled register assignment path")
+}
+
+// assignIntN assigns n values to registers, each "size" bytes large,
+// from the data at [offset, offset+n*size) in memory. Each value at
+// [offset+i*size, offset+(i+1)*size) for i < n is assigned to the
+// next n integer registers.
+//
+// Bit i in ptrMap indicates whether the i'th value is a pointer.
+// n must be <= 8.
+//
+// Returns whether assignment succeeded.
+func (a *abiSeq) assignIntN(offset, size uintptr, n int, ptrMap uint8) bool {
+ if n > 8 || n < 0 {
+ panic("invalid n")
+ }
+ if ptrMap != 0 && size != goarch.PtrSize {
+ panic("non-empty pointer map passed for non-pointer-size values")
+ }
+ if a.iregs+n > intArgRegs {
+ return false
+ }
+ for i := 0; i < n; i++ {
+ kind := abiStepIntReg
+ if ptrMap&(uint8(1)<<i) != 0 {
+ kind = abiStepPointer
+ }
+ a.steps = append(a.steps, abiStep{
+ kind: kind,
+ offset: offset + uintptr(i)*size,
+ size: size,
+ ireg: a.iregs,
+ })
+ a.iregs++
+ }
+ return true
+}
+
+// assignFloatN assigns n values to registers, each "size" bytes large,
+// from the data at [offset, offset+n*size) in memory. Each value at
+// [offset+i*size, offset+(i+1)*size) for i < n is assigned to the
+// next n floating-point registers.
+//
+// Returns whether assignment succeeded.
+func (a *abiSeq) assignFloatN(offset, size uintptr, n int) bool {
+ if n < 0 {
+ panic("invalid n")
+ }
+ if a.fregs+n > floatArgRegs || floatRegSize < size {
+ return false
+ }
+ for i := 0; i < n; i++ {
+ a.steps = append(a.steps, abiStep{
+ kind: abiStepFloatReg,
+ offset: offset + uintptr(i)*size,
+ size: size,
+ freg: a.fregs,
+ })
+ a.fregs++
+ }
+ return true
+}
+
+// stackAssign reserves space for one value that is "size" bytes
+// large with alignment "alignment" to the stack.
+//
+// Should not be called directly; use addArg instead.
+func (a *abiSeq) stackAssign(size, alignment uintptr) {
+ a.stackBytes = align(a.stackBytes, alignment)
+ a.steps = append(a.steps, abiStep{
+ kind: abiStepStack,
+ offset: 0, // Only used for whole arguments, so the memory offset is 0.
+ size: size,
+ stkOff: a.stackBytes,
+ })
+ a.stackBytes += size
+}
+
+// abiDesc describes the ABI for a function or method.
+type abiDesc struct {
+ // call and ret represent the translation steps for
+ // the call and return paths of a Go function.
+ call, ret abiSeq
+
+ // These fields describe the stack space allocated
+ // for the call. stackCallArgsSize is the amount of space
+ // reserved for arguments but not return values. retOffset
+ // is the offset at which return values begin, and
+ // spill is the size in bytes of additional space reserved
+ // to spill argument registers into in case of preemption in
+ // reflectcall's stack frame.
+ stackCallArgsSize, retOffset, spill uintptr
+
+ // stackPtrs is a bitmap that indicates whether
+ // each word in the ABI stack space (stack-assigned
+ // args + return values) is a pointer. Used
+ // as the heap pointer bitmap for stack space
+ // passed to reflectcall.
+ stackPtrs *bitVector
+
+ // inRegPtrs is a bitmap whose i'th bit indicates
+ // whether the i'th integer argument register contains
+ // a pointer. Used by makeFuncStub and methodValueCall
+ // to make result pointers visible to the GC.
+ //
+ // outRegPtrs is the same, but for result values.
+ // Used by reflectcall to make result pointers visible
+ // to the GC.
+ inRegPtrs, outRegPtrs abi.IntArgRegBitmap
+}
+
+func (a *abiDesc) dump() {
+ println("ABI")
+ println("call")
+ a.call.dump()
+ println("ret")
+ a.ret.dump()
+ println("stackCallArgsSize", a.stackCallArgsSize)
+ println("retOffset", a.retOffset)
+ println("spill", a.spill)
+ print("inRegPtrs:")
+ dumpPtrBitMap(a.inRegPtrs)
+ println()
+ print("outRegPtrs:")
+ dumpPtrBitMap(a.outRegPtrs)
+ println()
+}
+
+func dumpPtrBitMap(b abi.IntArgRegBitmap) {
+ for i := 0; i < intArgRegs; i++ {
+ x := 0
+ if b.Get(i) {
+ x = 1
+ }
+ print(" ", x)
+ }
+}
+
+func newAbiDesc(t *funcType, rcvr *abi.Type) abiDesc {
+ // We need to add space for this argument to
+ // the frame so that it can spill args into it.
+ //
+ // The size of this space is just the sum of the sizes
+ // of each register-allocated type.
+ //
+ // TODO(mknyszek): Remove this when we no longer have
+ // caller reserved spill space.
+ spill := uintptr(0)
+
+ // Compute gc program & stack bitmap for stack arguments
+ stackPtrs := new(bitVector)
+
+ // Compute the stack frame pointer bitmap and register
+ // pointer bitmap for arguments.
+ inRegPtrs := abi.IntArgRegBitmap{}
+
+ // Compute abiSeq for input parameters.
+ var in abiSeq
+ if rcvr != nil {
+ stkStep, isPtr := in.addRcvr(rcvr)
+ if stkStep != nil {
+ if isPtr {
+ stackPtrs.append(1)
+ } else {
+ stackPtrs.append(0)
+ }
+ } else {
+ spill += goarch.PtrSize
+ }
+ }
+ for i, arg := range t.InSlice() {
+ stkStep := in.addArg(arg)
+ if stkStep != nil {
+ addTypeBits(stackPtrs, stkStep.stkOff, arg)
+ } else {
+ spill = align(spill, uintptr(arg.Align()))
+ spill += arg.Size()
+ for _, st := range in.stepsForValue(i) {
+ if st.kind == abiStepPointer {
+ inRegPtrs.Set(st.ireg)
+ }
+ }
+ }
+ }
+ spill = align(spill, goarch.PtrSize)
+
+ // From the input parameters alone, we now know
+ // the stackCallArgsSize and retOffset.
+ stackCallArgsSize := in.stackBytes
+ retOffset := align(in.stackBytes, goarch.PtrSize)
+
+ // Compute the stack frame pointer bitmap and register
+ // pointer bitmap for return values.
+ outRegPtrs := abi.IntArgRegBitmap{}
+
+ // Compute abiSeq for output parameters.
+ var out abiSeq
+ // Stack-assigned return values do not share
+ // space with arguments like they do with registers,
+ // so we need to inject a stack offset here.
+ // Fake it by artificially extending stackBytes by
+ // the return offset.
+ out.stackBytes = retOffset
+ for i, res := range t.OutSlice() {
+ stkStep := out.addArg(res)
+ if stkStep != nil {
+ addTypeBits(stackPtrs, stkStep.stkOff, res)
+ } else {
+ for _, st := range out.stepsForValue(i) {
+ if st.kind == abiStepPointer {
+ outRegPtrs.Set(st.ireg)
+ }
+ }
+ }
+ }
+ // Undo the faking from earlier so that stackBytes
+ // is accurate.
+ out.stackBytes -= retOffset
+ return abiDesc{in, out, stackCallArgsSize, retOffset, spill, stackPtrs, inRegPtrs, outRegPtrs}
+}
+
+// intFromReg loads an argSize sized integer from reg and places it at to.
+//
+// argSize must be non-zero, fit in a register, and a power-of-two.
+func intFromReg(r *abi.RegArgs, reg int, argSize uintptr, to unsafe.Pointer) {
+ memmove(to, r.IntRegArgAddr(reg, argSize), argSize)
+}
+
+// intToReg loads an argSize sized integer and stores it into reg.
+//
+// argSize must be non-zero, fit in a register, and a power-of-two.
+func intToReg(r *abi.RegArgs, reg int, argSize uintptr, from unsafe.Pointer) {
+ memmove(r.IntRegArgAddr(reg, argSize), from, argSize)
+}
+
+// floatFromReg loads a float value from its register representation in r.
+//
+// argSize must be 4 or 8.
+func floatFromReg(r *abi.RegArgs, reg int, argSize uintptr, to unsafe.Pointer) {
+ switch argSize {
+ case 4:
+ *(*float32)(to) = archFloat32FromReg(r.Floats[reg])
+ case 8:
+ *(*float64)(to) = *(*float64)(unsafe.Pointer(&r.Floats[reg]))
+ default:
+ panic("bad argSize")
+ }
+}
+
+// floatToReg stores a float value in its register representation in r.
+//
+// argSize must be either 4 or 8.
+func floatToReg(r *abi.RegArgs, reg int, argSize uintptr, from unsafe.Pointer) {
+ switch argSize {
+ case 4:
+ r.Floats[reg] = archFloat32ToReg(*(*float32)(from))
+ case 8:
+ r.Floats[reg] = *(*uint64)(from)
+ default:
+ panic("bad argSize")
+ }
+}
diff --git a/contrib/go/_std_1.20/src/reflect/asm_amd64.s b/contrib/go/_std_1.21/src/reflect/asm_amd64.s
index d21d498063..d21d498063 100644
--- a/contrib/go/_std_1.20/src/reflect/asm_amd64.s
+++ b/contrib/go/_std_1.21/src/reflect/asm_amd64.s
diff --git a/contrib/go/_std_1.20/src/reflect/asm_arm64.s b/contrib/go/_std_1.21/src/reflect/asm_arm64.s
index 5e91e62aa1..5e91e62aa1 100644
--- a/contrib/go/_std_1.20/src/reflect/asm_arm64.s
+++ b/contrib/go/_std_1.21/src/reflect/asm_arm64.s
diff --git a/contrib/go/_std_1.21/src/reflect/deepequal.go b/contrib/go/_std_1.21/src/reflect/deepequal.go
new file mode 100644
index 0000000000..579781e703
--- /dev/null
+++ b/contrib/go/_std_1.21/src/reflect/deepequal.go
@@ -0,0 +1,238 @@
+// Copyright 2009 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.
+
+// Deep equality test via reflection
+
+package reflect
+
+import (
+ "internal/bytealg"
+ "unsafe"
+)
+
+// During deepValueEqual, must keep track of checks that are
+// in progress. The comparison algorithm assumes that all
+// checks in progress are true when it reencounters them.
+// Visited comparisons are stored in a map indexed by visit.
+type visit struct {
+ a1 unsafe.Pointer
+ a2 unsafe.Pointer
+ typ Type
+}
+
+// Tests for deep equality using reflected types. The map argument tracks
+// comparisons that have already been seen, which allows short circuiting on
+// recursive types.
+func deepValueEqual(v1, v2 Value, visited map[visit]bool) bool {
+ if !v1.IsValid() || !v2.IsValid() {
+ return v1.IsValid() == v2.IsValid()
+ }
+ if v1.Type() != v2.Type() {
+ return false
+ }
+
+ // We want to avoid putting more in the visited map than we need to.
+ // For any possible reference cycle that might be encountered,
+ // hard(v1, v2) needs to return true for at least one of the types in the cycle,
+ // and it's safe and valid to get Value's internal pointer.
+ hard := func(v1, v2 Value) bool {
+ switch v1.Kind() {
+ case Pointer:
+ if v1.typ().PtrBytes == 0 {
+ // not-in-heap pointers can't be cyclic.
+ // At least, all of our current uses of runtime/internal/sys.NotInHeap
+ // have that property. The runtime ones aren't cyclic (and we don't use
+ // DeepEqual on them anyway), and the cgo-generated ones are
+ // all empty structs.
+ return false
+ }
+ fallthrough
+ case Map, Slice, Interface:
+ // Nil pointers cannot be cyclic. Avoid putting them in the visited map.
+ return !v1.IsNil() && !v2.IsNil()
+ }
+ return false
+ }
+
+ if hard(v1, v2) {
+ // For a Pointer or Map value, we need to check flagIndir,
+ // which we do by calling the pointer method.
+ // For Slice or Interface, flagIndir is always set,
+ // and using v.ptr suffices.
+ ptrval := func(v Value) unsafe.Pointer {
+ switch v.Kind() {
+ case Pointer, Map:
+ return v.pointer()
+ default:
+ return v.ptr
+ }
+ }
+ addr1 := ptrval(v1)
+ addr2 := ptrval(v2)
+ if uintptr(addr1) > uintptr(addr2) {
+ // Canonicalize order to reduce number of entries in visited.
+ // Assumes non-moving garbage collector.
+ addr1, addr2 = addr2, addr1
+ }
+
+ // Short circuit if references are already seen.
+ typ := v1.Type()
+ v := visit{addr1, addr2, typ}
+ if visited[v] {
+ return true
+ }
+
+ // Remember for later.
+ visited[v] = true
+ }
+
+ switch v1.Kind() {
+ case Array:
+ for i := 0; i < v1.Len(); i++ {
+ if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
+ return false
+ }
+ }
+ return true
+ case Slice:
+ if v1.IsNil() != v2.IsNil() {
+ return false
+ }
+ if v1.Len() != v2.Len() {
+ return false
+ }
+ if v1.UnsafePointer() == v2.UnsafePointer() {
+ return true
+ }
+ // Special case for []byte, which is common.
+ if v1.Type().Elem().Kind() == Uint8 {
+ return bytealg.Equal(v1.Bytes(), v2.Bytes())
+ }
+ for i := 0; i < v1.Len(); i++ {
+ if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
+ return false
+ }
+ }
+ return true
+ case Interface:
+ if v1.IsNil() || v2.IsNil() {
+ return v1.IsNil() == v2.IsNil()
+ }
+ return deepValueEqual(v1.Elem(), v2.Elem(), visited)
+ case Pointer:
+ if v1.UnsafePointer() == v2.UnsafePointer() {
+ return true
+ }
+ return deepValueEqual(v1.Elem(), v2.Elem(), visited)
+ case Struct:
+ for i, n := 0, v1.NumField(); i < n; i++ {
+ if !deepValueEqual(v1.Field(i), v2.Field(i), visited) {
+ return false
+ }
+ }
+ return true
+ case Map:
+ if v1.IsNil() != v2.IsNil() {
+ return false
+ }
+ if v1.Len() != v2.Len() {
+ return false
+ }
+ if v1.UnsafePointer() == v2.UnsafePointer() {
+ return true
+ }
+ for _, k := range v1.MapKeys() {
+ val1 := v1.MapIndex(k)
+ val2 := v2.MapIndex(k)
+ if !val1.IsValid() || !val2.IsValid() || !deepValueEqual(val1, val2, visited) {
+ return false
+ }
+ }
+ return true
+ case Func:
+ if v1.IsNil() && v2.IsNil() {
+ return true
+ }
+ // Can't do better than this:
+ return false
+ case Int, Int8, Int16, Int32, Int64:
+ return v1.Int() == v2.Int()
+ case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+ return v1.Uint() == v2.Uint()
+ case String:
+ return v1.String() == v2.String()
+ case Bool:
+ return v1.Bool() == v2.Bool()
+ case Float32, Float64:
+ return v1.Float() == v2.Float()
+ case Complex64, Complex128:
+ return v1.Complex() == v2.Complex()
+ default:
+ // Normal equality suffices
+ return valueInterface(v1, false) == valueInterface(v2, false)
+ }
+}
+
+// DeepEqual reports whether x and y are “deeply equal,” defined as follows.
+// Two values of identical type are deeply equal if one of the following cases applies.
+// Values of distinct types are never deeply equal.
+//
+// Array values are deeply equal when their corresponding elements are deeply equal.
+//
+// Struct values are deeply equal if their corresponding fields,
+// both exported and unexported, are deeply equal.
+//
+// Func values are deeply equal if both are nil; otherwise they are not deeply equal.
+//
+// Interface values are deeply equal if they hold deeply equal concrete values.
+//
+// Map values are deeply equal when all of the following are true:
+// they are both nil or both non-nil, they have the same length,
+// and either they are the same map object or their corresponding keys
+// (matched using Go equality) map to deeply equal values.
+//
+// Pointer values are deeply equal if they are equal using Go's == operator
+// or if they point to deeply equal values.
+//
+// Slice values are deeply equal when all of the following are true:
+// they are both nil or both non-nil, they have the same length,
+// and either they point to the same initial entry of the same underlying array
+// (that is, &x[0] == &y[0]) or their corresponding elements (up to length) are deeply equal.
+// Note that a non-nil empty slice and a nil slice (for example, []byte{} and []byte(nil))
+// are not deeply equal.
+//
+// Other values - numbers, bools, strings, and channels - are deeply equal
+// if they are equal using Go's == operator.
+//
+// In general DeepEqual is a recursive relaxation of Go's == operator.
+// However, this idea is impossible to implement without some inconsistency.
+// Specifically, it is possible for a value to be unequal to itself,
+// either because it is of func type (uncomparable in general)
+// or because it is a floating-point NaN value (not equal to itself in floating-point comparison),
+// or because it is an array, struct, or interface containing
+// such a value.
+// On the other hand, pointer values are always equal to themselves,
+// even if they point at or contain such problematic values,
+// because they compare equal using Go's == operator, and that
+// is a sufficient condition to be deeply equal, regardless of content.
+// DeepEqual has been defined so that the same short-cut applies
+// to slices and maps: if x and y are the same slice or the same map,
+// they are deeply equal regardless of content.
+//
+// As DeepEqual traverses the data values it may find a cycle. The
+// second and subsequent times that DeepEqual compares two pointer
+// values that have been compared before, it treats the values as
+// equal rather than examining the values to which they point.
+// This ensures that DeepEqual terminates.
+func DeepEqual(x, y any) bool {
+ if x == nil || y == nil {
+ return x == y
+ }
+ v1 := ValueOf(x)
+ v2 := ValueOf(y)
+ if v1.Type() != v2.Type() {
+ return false
+ }
+ return deepValueEqual(v1, v2, make(map[visit]bool))
+}
diff --git a/contrib/go/_std_1.20/src/reflect/float32reg_generic.go b/contrib/go/_std_1.21/src/reflect/float32reg_generic.go
index 23ad4bf285..23ad4bf285 100644
--- a/contrib/go/_std_1.20/src/reflect/float32reg_generic.go
+++ b/contrib/go/_std_1.21/src/reflect/float32reg_generic.go
diff --git a/contrib/go/_std_1.20/src/reflect/internal/example1/example.go b/contrib/go/_std_1.21/src/reflect/internal/example1/example.go
index 181dd993af..181dd993af 100644
--- a/contrib/go/_std_1.20/src/reflect/internal/example1/example.go
+++ b/contrib/go/_std_1.21/src/reflect/internal/example1/example.go
diff --git a/contrib/go/_std_1.20/src/reflect/internal/example1/ya.make b/contrib/go/_std_1.21/src/reflect/internal/example1/ya.make
index f4f9cc54f2..f4f9cc54f2 100644
--- a/contrib/go/_std_1.20/src/reflect/internal/example1/ya.make
+++ b/contrib/go/_std_1.21/src/reflect/internal/example1/ya.make
diff --git a/contrib/go/_std_1.20/src/reflect/internal/example2/example.go b/contrib/go/_std_1.21/src/reflect/internal/example2/example.go
index 8a55826a1c..8a55826a1c 100644
--- a/contrib/go/_std_1.20/src/reflect/internal/example2/example.go
+++ b/contrib/go/_std_1.21/src/reflect/internal/example2/example.go
diff --git a/contrib/go/_std_1.20/src/reflect/internal/example2/ya.make b/contrib/go/_std_1.21/src/reflect/internal/example2/ya.make
index f4f9cc54f2..f4f9cc54f2 100644
--- a/contrib/go/_std_1.20/src/reflect/internal/example2/ya.make
+++ b/contrib/go/_std_1.21/src/reflect/internal/example2/ya.make
diff --git a/contrib/go/_std_1.20/src/reflect/internal/ya.make b/contrib/go/_std_1.21/src/reflect/internal/ya.make
index 988b105424..988b105424 100644
--- a/contrib/go/_std_1.20/src/reflect/internal/ya.make
+++ b/contrib/go/_std_1.21/src/reflect/internal/ya.make
diff --git a/contrib/go/_std_1.21/src/reflect/makefunc.go b/contrib/go/_std_1.21/src/reflect/makefunc.go
new file mode 100644
index 0000000000..2ed7f38905
--- /dev/null
+++ b/contrib/go/_std_1.21/src/reflect/makefunc.go
@@ -0,0 +1,176 @@
+// Copyright 2012 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.
+
+// MakeFunc implementation.
+
+package reflect
+
+import (
+ "internal/abi"
+ "unsafe"
+)
+
+// makeFuncImpl is the closure value implementing the function
+// returned by MakeFunc.
+// The first three words of this type must be kept in sync with
+// methodValue and runtime.reflectMethodValue.
+// Any changes should be reflected in all three.
+type makeFuncImpl struct {
+ makeFuncCtxt
+ ftyp *funcType
+ fn func([]Value) []Value
+}
+
+// MakeFunc returns a new function of the given Type
+// that wraps the function fn. When called, that new function
+// does the following:
+//
+// - converts its arguments to a slice of Values.
+// - runs results := fn(args).
+// - returns the results as a slice of Values, one per formal result.
+//
+// The implementation fn can assume that the argument Value slice
+// has the number and type of arguments given by typ.
+// If typ describes a variadic function, the final Value is itself
+// a slice representing the variadic arguments, as in the
+// body of a variadic function. The result Value slice returned by fn
+// must have the number and type of results given by typ.
+//
+// The Value.Call method allows the caller to invoke a typed function
+// in terms of Values; in contrast, MakeFunc allows the caller to implement
+// a typed function in terms of Values.
+//
+// The Examples section of the documentation includes an illustration
+// of how to use MakeFunc to build a swap function for different types.
+func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value {
+ if typ.Kind() != Func {
+ panic("reflect: call of MakeFunc with non-Func type")
+ }
+
+ t := typ.common()
+ ftyp := (*funcType)(unsafe.Pointer(t))
+
+ code := abi.FuncPCABI0(makeFuncStub)
+
+ // makeFuncImpl contains a stack map for use by the runtime
+ _, _, abid := funcLayout(ftyp, nil)
+
+ impl := &makeFuncImpl{
+ makeFuncCtxt: makeFuncCtxt{
+ fn: code,
+ stack: abid.stackPtrs,
+ argLen: abid.stackCallArgsSize,
+ regPtrs: abid.inRegPtrs,
+ },
+ ftyp: ftyp,
+ fn: fn,
+ }
+
+ return Value{t, unsafe.Pointer(impl), flag(Func)}
+}
+
+// makeFuncStub is an assembly function that is the code half of
+// the function returned from MakeFunc. It expects a *callReflectFunc
+// as its context register, and its job is to invoke callReflect(ctxt, frame)
+// where ctxt is the context register and frame is a pointer to the first
+// word in the passed-in argument frame.
+func makeFuncStub()
+
+// The first 3 words of this type must be kept in sync with
+// makeFuncImpl and runtime.reflectMethodValue.
+// Any changes should be reflected in all three.
+type methodValue struct {
+ makeFuncCtxt
+ method int
+ rcvr Value
+}
+
+// makeMethodValue converts v from the rcvr+method index representation
+// of a method value to an actual method func value, which is
+// basically the receiver value with a special bit set, into a true
+// func value - a value holding an actual func. The output is
+// semantically equivalent to the input as far as the user of package
+// reflect can tell, but the true func representation can be handled
+// by code like Convert and Interface and Assign.
+func makeMethodValue(op string, v Value) Value {
+ if v.flag&flagMethod == 0 {
+ panic("reflect: internal error: invalid use of makeMethodValue")
+ }
+
+ // Ignoring the flagMethod bit, v describes the receiver, not the method type.
+ fl := v.flag & (flagRO | flagAddr | flagIndir)
+ fl |= flag(v.typ().Kind())
+ rcvr := Value{v.typ(), v.ptr, fl}
+
+ // v.Type returns the actual type of the method value.
+ ftyp := (*funcType)(unsafe.Pointer(v.Type().(*rtype)))
+
+ code := methodValueCallCodePtr()
+
+ // methodValue contains a stack map for use by the runtime
+ _, _, abid := funcLayout(ftyp, nil)
+ fv := &methodValue{
+ makeFuncCtxt: makeFuncCtxt{
+ fn: code,
+ stack: abid.stackPtrs,
+ argLen: abid.stackCallArgsSize,
+ regPtrs: abid.inRegPtrs,
+ },
+ method: int(v.flag) >> flagMethodShift,
+ rcvr: rcvr,
+ }
+
+ // Cause panic if method is not appropriate.
+ // The panic would still happen during the call if we omit this,
+ // but we want Interface() and other operations to fail early.
+ methodReceiver(op, fv.rcvr, fv.method)
+
+ return Value{ftyp.Common(), unsafe.Pointer(fv), v.flag&flagRO | flag(Func)}
+}
+
+func methodValueCallCodePtr() uintptr {
+ return abi.FuncPCABI0(methodValueCall)
+}
+
+// methodValueCall is an assembly function that is the code half of
+// the function returned from makeMethodValue. It expects a *methodValue
+// as its context register, and its job is to invoke callMethod(ctxt, frame)
+// where ctxt is the context register and frame is a pointer to the first
+// word in the passed-in argument frame.
+func methodValueCall()
+
+// This structure must be kept in sync with runtime.reflectMethodValue.
+// Any changes should be reflected in all both.
+type makeFuncCtxt struct {
+ fn uintptr
+ stack *bitVector // ptrmap for both stack args and results
+ argLen uintptr // just args
+ regPtrs abi.IntArgRegBitmap
+}
+
+// moveMakeFuncArgPtrs uses ctxt.regPtrs to copy integer pointer arguments
+// in args.Ints to args.Ptrs where the GC can see them.
+//
+// This is similar to what reflectcallmove does in the runtime, except
+// that happens on the return path, whereas this happens on the call path.
+//
+// nosplit because pointers are being held in uintptr slots in args, so
+// having our stack scanned now could lead to accidentally freeing
+// memory.
+//
+//go:nosplit
+func moveMakeFuncArgPtrs(ctxt *makeFuncCtxt, args *abi.RegArgs) {
+ for i, arg := range args.Ints {
+ // Avoid write barriers! Because our write barrier enqueues what
+ // was there before, we might enqueue garbage.
+ if ctxt.regPtrs.Get(i) {
+ *(*uintptr)(unsafe.Pointer(&args.Ptrs[i])) = arg
+ } else {
+ // We *must* zero this space ourselves because it's defined in
+ // assembly code and the GC will scan these pointers. Otherwise,
+ // there will be garbage here.
+ *(*uintptr)(unsafe.Pointer(&args.Ptrs[i])) = 0
+ }
+ }
+}
diff --git a/contrib/go/_std_1.21/src/reflect/swapper.go b/contrib/go/_std_1.21/src/reflect/swapper.go
new file mode 100644
index 0000000000..1e8f4ed163
--- /dev/null
+++ b/contrib/go/_std_1.21/src/reflect/swapper.go
@@ -0,0 +1,79 @@
+// Copyright 2016 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 reflect
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "internal/unsafeheader"
+ "unsafe"
+)
+
+// Swapper returns a function that swaps the elements in the provided
+// slice.
+//
+// Swapper panics if the provided interface is not a slice.
+func Swapper(slice any) func(i, j int) {
+ v := ValueOf(slice)
+ if v.Kind() != Slice {
+ panic(&ValueError{Method: "Swapper", Kind: v.Kind()})
+ }
+ // Fast path for slices of size 0 and 1. Nothing to swap.
+ switch v.Len() {
+ case 0:
+ return func(i, j int) { panic("reflect: slice index out of range") }
+ case 1:
+ return func(i, j int) {
+ if i != 0 || j != 0 {
+ panic("reflect: slice index out of range")
+ }
+ }
+ }
+
+ typ := v.Type().Elem().common()
+ size := typ.Size()
+ hasPtr := typ.PtrBytes != 0
+
+ // Some common & small cases, without using memmove:
+ if hasPtr {
+ if size == goarch.PtrSize {
+ ps := *(*[]unsafe.Pointer)(v.ptr)
+ return func(i, j int) { ps[i], ps[j] = ps[j], ps[i] }
+ }
+ if typ.Kind() == abi.String {
+ ss := *(*[]string)(v.ptr)
+ return func(i, j int) { ss[i], ss[j] = ss[j], ss[i] }
+ }
+ } else {
+ switch size {
+ case 8:
+ is := *(*[]int64)(v.ptr)
+ return func(i, j int) { is[i], is[j] = is[j], is[i] }
+ case 4:
+ is := *(*[]int32)(v.ptr)
+ return func(i, j int) { is[i], is[j] = is[j], is[i] }
+ case 2:
+ is := *(*[]int16)(v.ptr)
+ return func(i, j int) { is[i], is[j] = is[j], is[i] }
+ case 1:
+ is := *(*[]int8)(v.ptr)
+ return func(i, j int) { is[i], is[j] = is[j], is[i] }
+ }
+ }
+
+ s := (*unsafeheader.Slice)(v.ptr)
+ tmp := unsafe_New(typ) // swap scratch space
+
+ return func(i, j int) {
+ if uint(i) >= uint(s.Len) || uint(j) >= uint(s.Len) {
+ panic("reflect: slice index out of range")
+ }
+ val1 := arrayAt(s.Data, i, size, "i < s.Len")
+ val2 := arrayAt(s.Data, j, size, "j < s.Len")
+ typedmemmove(typ, tmp, val1)
+ typedmemmove(typ, val1, val2)
+ typedmemmove(typ, val2, tmp)
+ }
+}
diff --git a/contrib/go/_std_1.21/src/reflect/type.go b/contrib/go/_std_1.21/src/reflect/type.go
new file mode 100644
index 0000000000..9fd242e732
--- /dev/null
+++ b/contrib/go/_std_1.21/src/reflect/type.go
@@ -0,0 +1,2911 @@
+// Copyright 2009 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 reflect implements run-time reflection, allowing a program to
+// manipulate objects with arbitrary types. The typical use is to take a value
+// with static type interface{} and extract its dynamic type information by
+// calling TypeOf, which returns a Type.
+//
+// A call to ValueOf returns a Value representing the run-time data.
+// Zero takes a Type and returns a Value representing a zero value
+// for that type.
+//
+// See "The Laws of Reflection" for an introduction to reflection in Go:
+// https://golang.org/doc/articles/laws_of_reflection.html
+package reflect
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "strconv"
+ "sync"
+ "unicode"
+ "unicode/utf8"
+ "unsafe"
+)
+
+// Type is the representation of a Go type.
+//
+// Not all methods apply to all kinds of types. Restrictions,
+// if any, are noted in the documentation for each method.
+// Use the Kind method to find out the kind of type before
+// calling kind-specific methods. Calling a method
+// inappropriate to the kind of type causes a run-time panic.
+//
+// Type values are comparable, such as with the == operator,
+// so they can be used as map keys.
+// Two Type values are equal if they represent identical types.
+type Type interface {
+ // Methods applicable to all types.
+
+ // Align returns the alignment in bytes of a value of
+ // this type when allocated in memory.
+ Align() int
+
+ // FieldAlign returns the alignment in bytes of a value of
+ // this type when used as a field in a struct.
+ FieldAlign() int
+
+ // Method returns the i'th method in the type's method set.
+ // It panics if i is not in the range [0, NumMethod()).
+ //
+ // For a non-interface type T or *T, the returned Method's Type and Func
+ // fields describe a function whose first argument is the receiver,
+ // and only exported methods are accessible.
+ //
+ // For an interface type, the returned Method's Type field gives the
+ // method signature, without a receiver, and the Func field is nil.
+ //
+ // Methods are sorted in lexicographic order.
+ Method(int) Method
+
+ // MethodByName returns the method with that name in the type's
+ // method set and a boolean indicating if the method was found.
+ //
+ // For a non-interface type T or *T, the returned Method's Type and Func
+ // fields describe a function whose first argument is the receiver.
+ //
+ // For an interface type, the returned Method's Type field gives the
+ // method signature, without a receiver, and the Func field is nil.
+ MethodByName(string) (Method, bool)
+
+ // NumMethod returns the number of methods accessible using Method.
+ //
+ // For a non-interface type, it returns the number of exported methods.
+ //
+ // For an interface type, it returns the number of exported and unexported methods.
+ NumMethod() int
+
+ // Name returns the type's name within its package for a defined type.
+ // For other (non-defined) types it returns the empty string.
+ Name() string
+
+ // PkgPath returns a defined type's package path, that is, the import path
+ // that uniquely identifies the package, such as "encoding/base64".
+ // If the type was predeclared (string, error) or not defined (*T, struct{},
+ // []int, or A where A is an alias for a non-defined type), the package path
+ // will be the empty string.
+ PkgPath() string
+
+ // Size returns the number of bytes needed to store
+ // a value of the given type; it is analogous to unsafe.Sizeof.
+ Size() uintptr
+
+ // String returns a string representation of the type.
+ // The string representation may use shortened package names
+ // (e.g., base64 instead of "encoding/base64") and is not
+ // guaranteed to be unique among types. To test for type identity,
+ // compare the Types directly.
+ String() string
+
+ // Kind returns the specific kind of this type.
+ Kind() Kind
+
+ // Implements reports whether the type implements the interface type u.
+ Implements(u Type) bool
+
+ // AssignableTo reports whether a value of the type is assignable to type u.
+ AssignableTo(u Type) bool
+
+ // ConvertibleTo reports whether a value of the type is convertible to type u.
+ // Even if ConvertibleTo returns true, the conversion may still panic.
+ // For example, a slice of type []T is convertible to *[N]T,
+ // but the conversion will panic if its length is less than N.
+ ConvertibleTo(u Type) bool
+
+ // Comparable reports whether values of this type are comparable.
+ // Even if Comparable returns true, the comparison may still panic.
+ // For example, values of interface type are comparable,
+ // but the comparison will panic if their dynamic type is not comparable.
+ Comparable() bool
+
+ // Methods applicable only to some types, depending on Kind.
+ // The methods allowed for each kind are:
+ //
+ // Int*, Uint*, Float*, Complex*: Bits
+ // Array: Elem, Len
+ // Chan: ChanDir, Elem
+ // Func: In, NumIn, Out, NumOut, IsVariadic.
+ // Map: Key, Elem
+ // Pointer: Elem
+ // Slice: Elem
+ // Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField
+
+ // Bits returns the size of the type in bits.
+ // It panics if the type's Kind is not one of the
+ // sized or unsized Int, Uint, Float, or Complex kinds.
+ Bits() int
+
+ // ChanDir returns a channel type's direction.
+ // It panics if the type's Kind is not Chan.
+ ChanDir() ChanDir
+
+ // IsVariadic reports whether a function type's final input parameter
+ // is a "..." parameter. If so, t.In(t.NumIn() - 1) returns the parameter's
+ // implicit actual type []T.
+ //
+ // For concreteness, if t represents func(x int, y ... float64), then
+ //
+ // t.NumIn() == 2
+ // t.In(0) is the reflect.Type for "int"
+ // t.In(1) is the reflect.Type for "[]float64"
+ // t.IsVariadic() == true
+ //
+ // IsVariadic panics if the type's Kind is not Func.
+ IsVariadic() bool
+
+ // Elem returns a type's element type.
+ // It panics if the type's Kind is not Array, Chan, Map, Pointer, or Slice.
+ Elem() Type
+
+ // Field returns a struct type's i'th field.
+ // It panics if the type's Kind is not Struct.
+ // It panics if i is not in the range [0, NumField()).
+ Field(i int) StructField
+
+ // FieldByIndex returns the nested field corresponding
+ // to the index sequence. It is equivalent to calling Field
+ // successively for each index i.
+ // It panics if the type's Kind is not Struct.
+ FieldByIndex(index []int) StructField
+
+ // FieldByName returns the struct field with the given name
+ // and a boolean indicating if the field was found.
+ FieldByName(name string) (StructField, bool)
+
+ // FieldByNameFunc returns the struct field with a name
+ // that satisfies the match function and a boolean indicating if
+ // the field was found.
+ //
+ // FieldByNameFunc considers the fields in the struct itself
+ // and then the fields in any embedded structs, in breadth first order,
+ // stopping at the shallowest nesting depth containing one or more
+ // fields satisfying the match function. If multiple fields at that depth
+ // satisfy the match function, they cancel each other
+ // and FieldByNameFunc returns no match.
+ // This behavior mirrors Go's handling of name lookup in
+ // structs containing embedded fields.
+ FieldByNameFunc(match func(string) bool) (StructField, bool)
+
+ // In returns the type of a function type's i'th input parameter.
+ // It panics if the type's Kind is not Func.
+ // It panics if i is not in the range [0, NumIn()).
+ In(i int) Type
+
+ // Key returns a map type's key type.
+ // It panics if the type's Kind is not Map.
+ Key() Type
+
+ // Len returns an array type's length.
+ // It panics if the type's Kind is not Array.
+ Len() int
+
+ // NumField returns a struct type's field count.
+ // It panics if the type's Kind is not Struct.
+ NumField() int
+
+ // NumIn returns a function type's input parameter count.
+ // It panics if the type's Kind is not Func.
+ NumIn() int
+
+ // NumOut returns a function type's output parameter count.
+ // It panics if the type's Kind is not Func.
+ NumOut() int
+
+ // Out returns the type of a function type's i'th output parameter.
+ // It panics if the type's Kind is not Func.
+ // It panics if i is not in the range [0, NumOut()).
+ Out(i int) Type
+
+ common() *abi.Type
+ uncommon() *uncommonType
+}
+
+// BUG(rsc): FieldByName and related functions consider struct field names to be equal
+// if the names are equal, even if they are unexported names originating
+// in different packages. The practical effect of this is that the result of
+// t.FieldByName("x") is not well defined if the struct type t contains
+// multiple fields named x (embedded from different packages).
+// FieldByName may return one of the fields named x or may report that there are none.
+// See https://golang.org/issue/4876 for more details.
+
+/*
+ * These data structures are known to the compiler (../cmd/compile/internal/reflectdata/reflect.go).
+ * A few are known to ../runtime/type.go to convey to debuggers.
+ * They are also known to ../runtime/type.go.
+ */
+
+// A Kind represents the specific kind of type that a Type represents.
+// The zero Kind is not a valid kind.
+type Kind uint
+
+const (
+ Invalid Kind = iota
+ Bool
+ Int
+ Int8
+ Int16
+ Int32
+ Int64
+ Uint
+ Uint8
+ Uint16
+ Uint32
+ Uint64
+ Uintptr
+ Float32
+ Float64
+ Complex64
+ Complex128
+ Array
+ Chan
+ Func
+ Interface
+ Map
+ Pointer
+ Slice
+ String
+ Struct
+ UnsafePointer
+)
+
+// Ptr is the old name for the Pointer kind.
+const Ptr = Pointer
+
+// uncommonType is present only for defined types or types with methods
+// (if T is a defined type, the uncommonTypes for T and *T have methods).
+// Using a pointer to this struct reduces the overall size required
+// to describe a non-defined type with no methods.
+type uncommonType = abi.UncommonType
+
+// Embed this type to get common/uncommon
+type common struct {
+ abi.Type
+}
+
+// rtype is the common implementation of most values.
+// It is embedded in other struct types.
+type rtype struct {
+ t abi.Type
+}
+
+func (t *rtype) common() *abi.Type {
+ return &t.t
+}
+
+func (t *rtype) uncommon() *abi.UncommonType {
+ return t.t.Uncommon()
+}
+
+type aNameOff = abi.NameOff
+type aTypeOff = abi.TypeOff
+type aTextOff = abi.TextOff
+
+// ChanDir represents a channel type's direction.
+type ChanDir int
+
+const (
+ RecvDir ChanDir = 1 << iota // <-chan
+ SendDir // chan<-
+ BothDir = RecvDir | SendDir // chan
+)
+
+// arrayType represents a fixed array type.
+type arrayType = abi.ArrayType
+
+// chanType represents a channel type.
+type chanType = abi.ChanType
+
+// funcType represents a function type.
+//
+// A *rtype for each in and out parameter is stored in an array that
+// directly follows the funcType (and possibly its uncommonType). So
+// a function type with one method, one input, and one output is:
+//
+// struct {
+// funcType
+// uncommonType
+// [2]*rtype // [0] is in, [1] is out
+// }
+type funcType = abi.FuncType
+
+// interfaceType represents an interface type.
+type interfaceType struct {
+ abi.InterfaceType // can embed directly because not a public type.
+}
+
+func (t *interfaceType) nameOff(off aNameOff) abi.Name {
+ return toRType(&t.Type).nameOff(off)
+}
+
+func nameOffFor(t *abi.Type, off aNameOff) abi.Name {
+ return toRType(t).nameOff(off)
+}
+
+func typeOffFor(t *abi.Type, off aTypeOff) *abi.Type {
+ return toRType(t).typeOff(off)
+}
+
+func (t *interfaceType) typeOff(off aTypeOff) *abi.Type {
+ return toRType(&t.Type).typeOff(off)
+}
+
+func (t *interfaceType) common() *abi.Type {
+ return &t.Type
+}
+
+func (t *interfaceType) uncommon() *abi.UncommonType {
+ return t.Uncommon()
+}
+
+// mapType represents a map type.
+type mapType struct {
+ abi.MapType
+}
+
+// ptrType represents a pointer type.
+type ptrType struct {
+ abi.PtrType
+}
+
+// sliceType represents a slice type.
+type sliceType struct {
+ abi.SliceType
+}
+
+// Struct field
+type structField = abi.StructField
+
+// structType represents a struct type.
+type structType struct {
+ abi.StructType
+}
+
+func pkgPath(n abi.Name) string {
+ if n.Bytes == nil || *n.DataChecked(0, "name flag field")&(1<<2) == 0 {
+ return ""
+ }
+ i, l := n.ReadVarint(1)
+ off := 1 + i + l
+ if n.HasTag() {
+ i2, l2 := n.ReadVarint(off)
+ off += i2 + l2
+ }
+ var nameOff int32
+ // Note that this field may not be aligned in memory,
+ // so we cannot use a direct int32 assignment here.
+ copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.DataChecked(off, "name offset field")))[:])
+ pkgPathName := abi.Name{Bytes: (*byte)(resolveTypeOff(unsafe.Pointer(n.Bytes), nameOff))}
+ return pkgPathName.Name()
+}
+
+func newName(n, tag string, exported, embedded bool) abi.Name {
+ return abi.NewName(n, tag, exported, embedded)
+}
+
+/*
+ * The compiler knows the exact layout of all the data structures above.
+ * The compiler does not know about the data structures and methods below.
+ */
+
+// Method represents a single method.
+type Method struct {
+ // Name is the method name.
+ Name string
+
+ // PkgPath is the package path that qualifies a lower case (unexported)
+ // method name. It is empty for upper case (exported) method names.
+ // The combination of PkgPath and Name uniquely identifies a method
+ // in a method set.
+ // See https://golang.org/ref/spec#Uniqueness_of_identifiers
+ PkgPath string
+
+ Type Type // method type
+ Func Value // func with receiver as first argument
+ Index int // index for Type.Method
+}
+
+// IsExported reports whether the method is exported.
+func (m Method) IsExported() bool {
+ return m.PkgPath == ""
+}
+
+const (
+ kindDirectIface = 1 << 5
+ kindGCProg = 1 << 6 // Type.gc points to GC program
+ kindMask = (1 << 5) - 1
+)
+
+// String returns the name of k.
+func (k Kind) String() string {
+ if uint(k) < uint(len(kindNames)) {
+ return kindNames[uint(k)]
+ }
+ return "kind" + strconv.Itoa(int(k))
+}
+
+var kindNames = []string{
+ Invalid: "invalid",
+ Bool: "bool",
+ Int: "int",
+ Int8: "int8",
+ Int16: "int16",
+ Int32: "int32",
+ Int64: "int64",
+ Uint: "uint",
+ Uint8: "uint8",
+ Uint16: "uint16",
+ Uint32: "uint32",
+ Uint64: "uint64",
+ Uintptr: "uintptr",
+ Float32: "float32",
+ Float64: "float64",
+ Complex64: "complex64",
+ Complex128: "complex128",
+ Array: "array",
+ Chan: "chan",
+ Func: "func",
+ Interface: "interface",
+ Map: "map",
+ Pointer: "ptr",
+ Slice: "slice",
+ String: "string",
+ Struct: "struct",
+ UnsafePointer: "unsafe.Pointer",
+}
+
+// resolveNameOff resolves a name offset from a base pointer.
+// The (*rtype).nameOff method is a convenience wrapper for this function.
+// Implemented in the runtime package.
+//
+//go:noescape
+func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer
+
+// resolveTypeOff resolves an *rtype offset from a base type.
+// The (*rtype).typeOff method is a convenience wrapper for this function.
+// Implemented in the runtime package.
+//
+//go:noescape
+func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
+
+// resolveTextOff resolves a function pointer offset from a base type.
+// The (*rtype).textOff method is a convenience wrapper for this function.
+// Implemented in the runtime package.
+//
+//go:noescape
+func resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer
+
+// addReflectOff adds a pointer to the reflection lookup map in the runtime.
+// It returns a new ID that can be used as a typeOff or textOff, and will
+// be resolved correctly. Implemented in the runtime package.
+//
+//go:noescape
+func addReflectOff(ptr unsafe.Pointer) int32
+
+// resolveReflectName adds a name to the reflection lookup map in the runtime.
+// It returns a new nameOff that can be used to refer to the pointer.
+func resolveReflectName(n abi.Name) aNameOff {
+ return aNameOff(addReflectOff(unsafe.Pointer(n.Bytes)))
+}
+
+// resolveReflectType adds a *rtype to the reflection lookup map in the runtime.
+// It returns a new typeOff that can be used to refer to the pointer.
+func resolveReflectType(t *abi.Type) aTypeOff {
+ return aTypeOff(addReflectOff(unsafe.Pointer(t)))
+}
+
+// resolveReflectText adds a function pointer to the reflection lookup map in
+// the runtime. It returns a new textOff that can be used to refer to the
+// pointer.
+func resolveReflectText(ptr unsafe.Pointer) aTextOff {
+ return aTextOff(addReflectOff(ptr))
+}
+
+func (t *rtype) nameOff(off aNameOff) abi.Name {
+ return abi.Name{Bytes: (*byte)(resolveNameOff(unsafe.Pointer(t), int32(off)))}
+}
+
+func (t *rtype) typeOff(off aTypeOff) *abi.Type {
+ return (*abi.Type)(resolveTypeOff(unsafe.Pointer(t), int32(off)))
+}
+
+func (t *rtype) textOff(off aTextOff) unsafe.Pointer {
+ return resolveTextOff(unsafe.Pointer(t), int32(off))
+}
+
+func textOffFor(t *abi.Type, off aTextOff) unsafe.Pointer {
+ return toRType(t).textOff(off)
+}
+
+func (t *rtype) String() string {
+ s := t.nameOff(t.t.Str).Name()
+ if t.t.TFlag&abi.TFlagExtraStar != 0 {
+ return s[1:]
+ }
+ return s
+}
+
+func (t *rtype) Size() uintptr { return t.t.Size() }
+
+func (t *rtype) Bits() int {
+ if t == nil {
+ panic("reflect: Bits of nil Type")
+ }
+ k := t.Kind()
+ if k < Int || k > Complex128 {
+ panic("reflect: Bits of non-arithmetic Type " + t.String())
+ }
+ return int(t.t.Size_) * 8
+}
+
+func (t *rtype) Align() int { return t.t.Align() }
+
+func (t *rtype) FieldAlign() int { return t.t.FieldAlign() }
+
+func (t *rtype) Kind() Kind { return Kind(t.t.Kind()) }
+
+func (t *rtype) exportedMethods() []abi.Method {
+ ut := t.uncommon()
+ if ut == nil {
+ return nil
+ }
+ return ut.ExportedMethods()
+}
+
+func (t *rtype) NumMethod() int {
+ if t.Kind() == Interface {
+ tt := (*interfaceType)(unsafe.Pointer(t))
+ return tt.NumMethod()
+ }
+ return len(t.exportedMethods())
+}
+
+func (t *rtype) Method(i int) (m Method) {
+ if t.Kind() == Interface {
+ tt := (*interfaceType)(unsafe.Pointer(t))
+ return tt.Method(i)
+ }
+ methods := t.exportedMethods()
+ if i < 0 || i >= len(methods) {
+ panic("reflect: Method index out of range")
+ }
+ p := methods[i]
+ pname := t.nameOff(p.Name)
+ m.Name = pname.Name()
+ fl := flag(Func)
+ mtyp := t.typeOff(p.Mtyp)
+ ft := (*funcType)(unsafe.Pointer(mtyp))
+ in := make([]Type, 0, 1+ft.NumIn())
+ in = append(in, t)
+ for _, arg := range ft.InSlice() {
+ in = append(in, toRType(arg))
+ }
+ out := make([]Type, 0, ft.NumOut())
+ for _, ret := range ft.OutSlice() {
+ out = append(out, toRType(ret))
+ }
+ mt := FuncOf(in, out, ft.IsVariadic())
+ m.Type = mt
+ tfn := t.textOff(p.Tfn)
+ fn := unsafe.Pointer(&tfn)
+ m.Func = Value{&mt.(*rtype).t, fn, fl}
+
+ m.Index = i
+ return m
+}
+
+func (t *rtype) MethodByName(name string) (m Method, ok bool) {
+ if t.Kind() == Interface {
+ tt := (*interfaceType)(unsafe.Pointer(t))
+ return tt.MethodByName(name)
+ }
+ ut := t.uncommon()
+ if ut == nil {
+ return Method{}, false
+ }
+
+ methods := ut.ExportedMethods()
+
+ // We are looking for the first index i where the string becomes >= s.
+ // This is a copy of sort.Search, with f(h) replaced by (t.nameOff(methods[h].name).name() >= name).
+ i, j := 0, len(methods)
+ for i < j {
+ h := int(uint(i+j) >> 1) // avoid overflow when computing h
+ // i ≤ h < j
+ if !(t.nameOff(methods[h].Name).Name() >= name) {
+ i = h + 1 // preserves f(i-1) == false
+ } else {
+ j = h // preserves f(j) == true
+ }
+ }
+ // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i.
+ if i < len(methods) && name == t.nameOff(methods[i].Name).Name() {
+ return t.Method(i), true
+ }
+
+ return Method{}, false
+}
+
+func (t *rtype) PkgPath() string {
+ if t.t.TFlag&abi.TFlagNamed == 0 {
+ return ""
+ }
+ ut := t.uncommon()
+ if ut == nil {
+ return ""
+ }
+ return t.nameOff(ut.PkgPath).Name()
+}
+
+func pkgPathFor(t *abi.Type) string {
+ return toRType(t).PkgPath()
+}
+
+func (t *rtype) Name() string {
+ if !t.t.HasName() {
+ return ""
+ }
+ s := t.String()
+ i := len(s) - 1
+ sqBrackets := 0
+ for i >= 0 && (s[i] != '.' || sqBrackets != 0) {
+ switch s[i] {
+ case ']':
+ sqBrackets++
+ case '[':
+ sqBrackets--
+ }
+ i--
+ }
+ return s[i+1:]
+}
+
+func nameFor(t *abi.Type) string {
+ return toRType(t).Name()
+}
+
+func (t *rtype) ChanDir() ChanDir {
+ if t.Kind() != Chan {
+ panic("reflect: ChanDir of non-chan type " + t.String())
+ }
+ tt := (*abi.ChanType)(unsafe.Pointer(t))
+ return ChanDir(tt.Dir)
+}
+
+func toRType(t *abi.Type) *rtype {
+ return (*rtype)(unsafe.Pointer(t))
+}
+
+func elem(t *abi.Type) *abi.Type {
+ et := t.Elem()
+ if et != nil {
+ return et
+ }
+ panic("reflect: Elem of invalid type " + stringFor(t))
+}
+
+func (t *rtype) Elem() Type {
+ return toType(elem(t.common()))
+}
+
+func (t *rtype) Field(i int) StructField {
+ if t.Kind() != Struct {
+ panic("reflect: Field of non-struct type " + t.String())
+ }
+ tt := (*structType)(unsafe.Pointer(t))
+ return tt.Field(i)
+}
+
+func (t *rtype) FieldByIndex(index []int) StructField {
+ if t.Kind() != Struct {
+ panic("reflect: FieldByIndex of non-struct type " + t.String())
+ }
+ tt := (*structType)(unsafe.Pointer(t))
+ return tt.FieldByIndex(index)
+}
+
+func (t *rtype) FieldByName(name string) (StructField, bool) {
+ if t.Kind() != Struct {
+ panic("reflect: FieldByName of non-struct type " + t.String())
+ }
+ tt := (*structType)(unsafe.Pointer(t))
+ return tt.FieldByName(name)
+}
+
+func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) {
+ if t.Kind() != Struct {
+ panic("reflect: FieldByNameFunc of non-struct type " + t.String())
+ }
+ tt := (*structType)(unsafe.Pointer(t))
+ return tt.FieldByNameFunc(match)
+}
+
+func (t *rtype) Key() Type {
+ if t.Kind() != Map {
+ panic("reflect: Key of non-map type " + t.String())
+ }
+ tt := (*mapType)(unsafe.Pointer(t))
+ return toType(tt.Key)
+}
+
+func (t *rtype) Len() int {
+ if t.Kind() != Array {
+ panic("reflect: Len of non-array type " + t.String())
+ }
+ tt := (*arrayType)(unsafe.Pointer(t))
+ return int(tt.Len)
+}
+
+func (t *rtype) NumField() int {
+ if t.Kind() != Struct {
+ panic("reflect: NumField of non-struct type " + t.String())
+ }
+ tt := (*structType)(unsafe.Pointer(t))
+ return len(tt.Fields)
+}
+
+func (t *rtype) In(i int) Type {
+ if t.Kind() != Func {
+ panic("reflect: In of non-func type " + t.String())
+ }
+ tt := (*abi.FuncType)(unsafe.Pointer(t))
+ return toType(tt.InSlice()[i])
+}
+
+func (t *rtype) NumIn() int {
+ if t.Kind() != Func {
+ panic("reflect: NumIn of non-func type " + t.String())
+ }
+ tt := (*abi.FuncType)(unsafe.Pointer(t))
+ return tt.NumIn()
+}
+
+func (t *rtype) NumOut() int {
+ if t.Kind() != Func {
+ panic("reflect: NumOut of non-func type " + t.String())
+ }
+ tt := (*abi.FuncType)(unsafe.Pointer(t))
+ return tt.NumOut()
+}
+
+func (t *rtype) Out(i int) Type {
+ if t.Kind() != Func {
+ panic("reflect: Out of non-func type " + t.String())
+ }
+ tt := (*abi.FuncType)(unsafe.Pointer(t))
+ return toType(tt.OutSlice()[i])
+}
+
+func (t *rtype) IsVariadic() bool {
+ if t.Kind() != Func {
+ panic("reflect: IsVariadic of non-func type " + t.String())
+ }
+ tt := (*abi.FuncType)(unsafe.Pointer(t))
+ return tt.IsVariadic()
+}
+
+// add returns p+x.
+//
+// The whySafe string is ignored, so that the function still inlines
+// as efficiently as p+x, but all call sites should use the string to
+// record why the addition is safe, which is to say why the addition
+// does not cause x to advance to the very end of p's allocation
+// and therefore point incorrectly at the next block in memory.
+func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer {
+ return unsafe.Pointer(uintptr(p) + x)
+}
+
+func (d ChanDir) String() string {
+ switch d {
+ case SendDir:
+ return "chan<-"
+ case RecvDir:
+ return "<-chan"
+ case BothDir:
+ return "chan"
+ }
+ return "ChanDir" + strconv.Itoa(int(d))
+}
+
+// Method returns the i'th method in the type's method set.
+func (t *interfaceType) Method(i int) (m Method) {
+ if i < 0 || i >= len(t.Methods) {
+ return
+ }
+ p := &t.Methods[i]
+ pname := t.nameOff(p.Name)
+ m.Name = pname.Name()
+ if !pname.IsExported() {
+ m.PkgPath = pkgPath(pname)
+ if m.PkgPath == "" {
+ m.PkgPath = t.PkgPath.Name()
+ }
+ }
+ m.Type = toType(t.typeOff(p.Typ))
+ m.Index = i
+ return
+}
+
+// NumMethod returns the number of interface methods in the type's method set.
+func (t *interfaceType) NumMethod() int { return len(t.Methods) }
+
+// MethodByName method with the given name in the type's method set.
+func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
+ if t == nil {
+ return
+ }
+ var p *abi.Imethod
+ for i := range t.Methods {
+ p = &t.Methods[i]
+ if t.nameOff(p.Name).Name() == name {
+ return t.Method(i), true
+ }
+ }
+ return
+}
+
+// A StructField describes a single field in a struct.
+type StructField struct {
+ // Name is the field name.
+ Name string
+
+ // PkgPath is the package path that qualifies a lower case (unexported)
+ // field name. It is empty for upper case (exported) field names.
+ // See https://golang.org/ref/spec#Uniqueness_of_identifiers
+ PkgPath string
+
+ Type Type // field type
+ Tag StructTag // field tag string
+ Offset uintptr // offset within struct, in bytes
+ Index []int // index sequence for Type.FieldByIndex
+ Anonymous bool // is an embedded field
+}
+
+// IsExported reports whether the field is exported.
+func (f StructField) IsExported() bool {
+ return f.PkgPath == ""
+}
+
+// A StructTag is the tag string in a struct field.
+//
+// By convention, tag strings are a concatenation of
+// optionally space-separated key:"value" pairs.
+// Each key is a non-empty string consisting of non-control
+// characters other than space (U+0020 ' '), quote (U+0022 '"'),
+// and colon (U+003A ':'). Each value is quoted using U+0022 '"'
+// characters and Go string literal syntax.
+type StructTag string
+
+// Get returns the value associated with key in the tag string.
+// If there is no such key in the tag, Get returns the empty string.
+// If the tag does not have the conventional format, the value
+// returned by Get is unspecified. To determine whether a tag is
+// explicitly set to the empty string, use Lookup.
+func (tag StructTag) Get(key string) string {
+ v, _ := tag.Lookup(key)
+ return v
+}
+
+// Lookup returns the value associated with key in the tag string.
+// If the key is present in the tag the value (which may be empty)
+// is returned. Otherwise the returned value will be the empty string.
+// The ok return value reports whether the value was explicitly set in
+// the tag string. If the tag does not have the conventional format,
+// the value returned by Lookup is unspecified.
+func (tag StructTag) Lookup(key string) (value string, ok bool) {
+ // When modifying this code, also update the validateStructTag code
+ // in cmd/vet/structtag.go.
+
+ for tag != "" {
+ // Skip leading space.
+ i := 0
+ for i < len(tag) && tag[i] == ' ' {
+ i++
+ }
+ tag = tag[i:]
+ if tag == "" {
+ break
+ }
+
+ // Scan to colon. A space, a quote or a control character is a syntax error.
+ // Strictly speaking, control chars include the range [0x7f, 0x9f], not just
+ // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
+ // as it is simpler to inspect the tag's bytes than the tag's runes.
+ i = 0
+ for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
+ i++
+ }
+ if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
+ break
+ }
+ name := string(tag[:i])
+ tag = tag[i+1:]
+
+ // Scan quoted string to find value.
+ i = 1
+ for i < len(tag) && tag[i] != '"' {
+ if tag[i] == '\\' {
+ i++
+ }
+ i++
+ }
+ if i >= len(tag) {
+ break
+ }
+ qvalue := string(tag[:i+1])
+ tag = tag[i+1:]
+
+ if key == name {
+ value, err := strconv.Unquote(qvalue)
+ if err != nil {
+ break
+ }
+ return value, true
+ }
+ }
+ return "", false
+}
+
+// Field returns the i'th struct field.
+func (t *structType) Field(i int) (f StructField) {
+ if i < 0 || i >= len(t.Fields) {
+ panic("reflect: Field index out of bounds")
+ }
+ p := &t.Fields[i]
+ f.Type = toType(p.Typ)
+ f.Name = p.Name.Name()
+ f.Anonymous = p.Embedded()
+ if !p.Name.IsExported() {
+ f.PkgPath = t.PkgPath.Name()
+ }
+ if tag := p.Name.Tag(); tag != "" {
+ f.Tag = StructTag(tag)
+ }
+ f.Offset = p.Offset
+
+ // NOTE(rsc): This is the only allocation in the interface
+ // presented by a reflect.Type. It would be nice to avoid,
+ // at least in the common cases, but we need to make sure
+ // that misbehaving clients of reflect cannot affect other
+ // uses of reflect. One possibility is CL 5371098, but we
+ // postponed that ugliness until there is a demonstrated
+ // need for the performance. This is issue 2320.
+ f.Index = []int{i}
+ return
+}
+
+// TODO(gri): Should there be an error/bool indicator if the index
+// is wrong for FieldByIndex?
+
+// FieldByIndex returns the nested field corresponding to index.
+func (t *structType) FieldByIndex(index []int) (f StructField) {
+ f.Type = toType(&t.Type)
+ for i, x := range index {
+ if i > 0 {
+ ft := f.Type
+ if ft.Kind() == Pointer && ft.Elem().Kind() == Struct {
+ ft = ft.Elem()
+ }
+ f.Type = ft
+ }
+ f = f.Type.Field(x)
+ }
+ return
+}
+
+// A fieldScan represents an item on the fieldByNameFunc scan work list.
+type fieldScan struct {
+ typ *structType
+ index []int
+}
+
+// FieldByNameFunc returns the struct field with a name that satisfies the
+// match function and a boolean to indicate if the field was found.
+func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) {
+ // This uses the same condition that the Go language does: there must be a unique instance
+ // of the match at a given depth level. If there are multiple instances of a match at the
+ // same depth, they annihilate each other and inhibit any possible match at a lower level.
+ // The algorithm is breadth first search, one depth level at a time.
+
+ // The current and next slices are work queues:
+ // current lists the fields to visit on this depth level,
+ // and next lists the fields on the next lower level.
+ current := []fieldScan{}
+ next := []fieldScan{{typ: t}}
+
+ // nextCount records the number of times an embedded type has been
+ // encountered and considered for queueing in the 'next' slice.
+ // We only queue the first one, but we increment the count on each.
+ // If a struct type T can be reached more than once at a given depth level,
+ // then it annihilates itself and need not be considered at all when we
+ // process that next depth level.
+ var nextCount map[*structType]int
+
+ // visited records the structs that have been considered already.
+ // Embedded pointer fields can create cycles in the graph of
+ // reachable embedded types; visited avoids following those cycles.
+ // It also avoids duplicated effort: if we didn't find the field in an
+ // embedded type T at level 2, we won't find it in one at level 4 either.
+ visited := map[*structType]bool{}
+
+ for len(next) > 0 {
+ current, next = next, current[:0]
+ count := nextCount
+ nextCount = nil
+
+ // Process all the fields at this depth, now listed in 'current'.
+ // The loop queues embedded fields found in 'next', for processing during the next
+ // iteration. The multiplicity of the 'current' field counts is recorded
+ // in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'.
+ for _, scan := range current {
+ t := scan.typ
+ if visited[t] {
+ // We've looked through this type before, at a higher level.
+ // That higher level would shadow the lower level we're now at,
+ // so this one can't be useful to us. Ignore it.
+ continue
+ }
+ visited[t] = true
+ for i := range t.Fields {
+ f := &t.Fields[i]
+ // Find name and (for embedded field) type for field f.
+ fname := f.Name.Name()
+ var ntyp *abi.Type
+ if f.Embedded() {
+ // Embedded field of type T or *T.
+ ntyp = f.Typ
+ if ntyp.Kind() == abi.Pointer {
+ ntyp = ntyp.Elem()
+ }
+ }
+
+ // Does it match?
+ if match(fname) {
+ // Potential match
+ if count[t] > 1 || ok {
+ // Name appeared multiple times at this level: annihilate.
+ return StructField{}, false
+ }
+ result = t.Field(i)
+ result.Index = nil
+ result.Index = append(result.Index, scan.index...)
+ result.Index = append(result.Index, i)
+ ok = true
+ continue
+ }
+
+ // Queue embedded struct fields for processing with next level,
+ // but only if we haven't seen a match yet at this level and only
+ // if the embedded types haven't already been queued.
+ if ok || ntyp == nil || ntyp.Kind() != abi.Struct {
+ continue
+ }
+ styp := (*structType)(unsafe.Pointer(ntyp))
+ if nextCount[styp] > 0 {
+ nextCount[styp] = 2 // exact multiple doesn't matter
+ continue
+ }
+ if nextCount == nil {
+ nextCount = map[*structType]int{}
+ }
+ nextCount[styp] = 1
+ if count[t] > 1 {
+ nextCount[styp] = 2 // exact multiple doesn't matter
+ }
+ var index []int
+ index = append(index, scan.index...)
+ index = append(index, i)
+ next = append(next, fieldScan{styp, index})
+ }
+ }
+ if ok {
+ break
+ }
+ }
+ return
+}
+
+// FieldByName returns the struct field with the given name
+// and a boolean to indicate if the field was found.
+func (t *structType) FieldByName(name string) (f StructField, present bool) {
+ // Quick check for top-level name, or struct without embedded fields.
+ hasEmbeds := false
+ if name != "" {
+ for i := range t.Fields {
+ tf := &t.Fields[i]
+ if tf.Name.Name() == name {
+ return t.Field(i), true
+ }
+ if tf.Embedded() {
+ hasEmbeds = true
+ }
+ }
+ }
+ if !hasEmbeds {
+ return
+ }
+ return t.FieldByNameFunc(func(s string) bool { return s == name })
+}
+
+// TypeOf returns the reflection Type that represents the dynamic type of i.
+// If i is a nil interface value, TypeOf returns nil.
+func TypeOf(i any) Type {
+ eface := *(*emptyInterface)(unsafe.Pointer(&i))
+ // Noescape so this doesn't make i to escape. See the comment
+ // at Value.typ for why this is safe.
+ return toType((*abi.Type)(noescape(unsafe.Pointer(eface.typ))))
+}
+
+// rtypeOf directly extracts the *rtype of the provided value.
+func rtypeOf(i any) *abi.Type {
+ eface := *(*emptyInterface)(unsafe.Pointer(&i))
+ return eface.typ
+}
+
+// ptrMap is the cache for PointerTo.
+var ptrMap sync.Map // map[*rtype]*ptrType
+
+// PtrTo returns the pointer type with element t.
+// For example, if t represents type Foo, PtrTo(t) represents *Foo.
+//
+// PtrTo is the old spelling of PointerTo.
+// The two functions behave identically.
+func PtrTo(t Type) Type { return PointerTo(t) }
+
+// PointerTo returns the pointer type with element t.
+// For example, if t represents type Foo, PointerTo(t) represents *Foo.
+func PointerTo(t Type) Type {
+ return toRType(t.(*rtype).ptrTo())
+}
+
+func (t *rtype) ptrTo() *abi.Type {
+ at := &t.t
+ if at.PtrToThis != 0 {
+ return t.typeOff(at.PtrToThis)
+ }
+
+ // Check the cache.
+ if pi, ok := ptrMap.Load(t); ok {
+ return &pi.(*ptrType).Type
+ }
+
+ // Look in known types.
+ s := "*" + t.String()
+ for _, tt := range typesByString(s) {
+ p := (*ptrType)(unsafe.Pointer(tt))
+ if p.Elem != &t.t {
+ continue
+ }
+ pi, _ := ptrMap.LoadOrStore(t, p)
+ return &pi.(*ptrType).Type
+ }
+
+ // Create a new ptrType starting with the description
+ // of an *unsafe.Pointer.
+ var iptr any = (*unsafe.Pointer)(nil)
+ prototype := *(**ptrType)(unsafe.Pointer(&iptr))
+ pp := *prototype
+
+ pp.Str = resolveReflectName(newName(s, "", false, false))
+ pp.PtrToThis = 0
+
+ // For the type structures linked into the binary, the
+ // compiler provides a good hash of the string.
+ // Create a good hash for the new string by using
+ // the FNV-1 hash's mixing function to combine the
+ // old hash and the new "*".
+ pp.Hash = fnv1(t.t.Hash, '*')
+
+ pp.Elem = at
+
+ pi, _ := ptrMap.LoadOrStore(t, &pp)
+ return &pi.(*ptrType).Type
+}
+
+func ptrTo(t *abi.Type) *abi.Type {
+ return toRType(t).ptrTo()
+}
+
+// fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function.
+func fnv1(x uint32, list ...byte) uint32 {
+ for _, b := range list {
+ x = x*16777619 ^ uint32(b)
+ }
+ return x
+}
+
+func (t *rtype) Implements(u Type) bool {
+ if u == nil {
+ panic("reflect: nil type passed to Type.Implements")
+ }
+ if u.Kind() != Interface {
+ panic("reflect: non-interface type passed to Type.Implements")
+ }
+ return implements(u.common(), t.common())
+}
+
+func (t *rtype) AssignableTo(u Type) bool {
+ if u == nil {
+ panic("reflect: nil type passed to Type.AssignableTo")
+ }
+ uu := u.common()
+ return directlyAssignable(uu, t.common()) || implements(uu, t.common())
+}
+
+func (t *rtype) ConvertibleTo(u Type) bool {
+ if u == nil {
+ panic("reflect: nil type passed to Type.ConvertibleTo")
+ }
+ return convertOp(u.common(), t.common()) != nil
+}
+
+func (t *rtype) Comparable() bool {
+ return t.t.Equal != nil
+}
+
+// implements reports whether the type V implements the interface type T.
+func implements(T, V *abi.Type) bool {
+ if T.Kind() != abi.Interface {
+ return false
+ }
+ t := (*interfaceType)(unsafe.Pointer(T))
+ if len(t.Methods) == 0 {
+ return true
+ }
+
+ // The same algorithm applies in both cases, but the
+ // method tables for an interface type and a concrete type
+ // are different, so the code is duplicated.
+ // In both cases the algorithm is a linear scan over the two
+ // lists - T's methods and V's methods - simultaneously.
+ // Since method tables are stored in a unique sorted order
+ // (alphabetical, with no duplicate method names), the scan
+ // through V's methods must hit a match for each of T's
+ // methods along the way, or else V does not implement T.
+ // This lets us run the scan in overall linear time instead of
+ // the quadratic time a naive search would require.
+ // See also ../runtime/iface.go.
+ if V.Kind() == abi.Interface {
+ v := (*interfaceType)(unsafe.Pointer(V))
+ i := 0
+ for j := 0; j < len(v.Methods); j++ {
+ tm := &t.Methods[i]
+ tmName := t.nameOff(tm.Name)
+ vm := &v.Methods[j]
+ vmName := nameOffFor(V, vm.Name)
+ if vmName.Name() == tmName.Name() && typeOffFor(V, vm.Typ) == t.typeOff(tm.Typ) {
+ if !tmName.IsExported() {
+ tmPkgPath := pkgPath(tmName)
+ if tmPkgPath == "" {
+ tmPkgPath = t.PkgPath.Name()
+ }
+ vmPkgPath := pkgPath(vmName)
+ if vmPkgPath == "" {
+ vmPkgPath = v.PkgPath.Name()
+ }
+ if tmPkgPath != vmPkgPath {
+ continue
+ }
+ }
+ if i++; i >= len(t.Methods) {
+ return true
+ }
+ }
+ }
+ return false
+ }
+
+ v := V.Uncommon()
+ if v == nil {
+ return false
+ }
+ i := 0
+ vmethods := v.Methods()
+ for j := 0; j < int(v.Mcount); j++ {
+ tm := &t.Methods[i]
+ tmName := t.nameOff(tm.Name)
+ vm := vmethods[j]
+ vmName := nameOffFor(V, vm.Name)
+ if vmName.Name() == tmName.Name() && typeOffFor(V, vm.Mtyp) == t.typeOff(tm.Typ) {
+ if !tmName.IsExported() {
+ tmPkgPath := pkgPath(tmName)
+ if tmPkgPath == "" {
+ tmPkgPath = t.PkgPath.Name()
+ }
+ vmPkgPath := pkgPath(vmName)
+ if vmPkgPath == "" {
+ vmPkgPath = nameOffFor(V, v.PkgPath).Name()
+ }
+ if tmPkgPath != vmPkgPath {
+ continue
+ }
+ }
+ if i++; i >= len(t.Methods) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// specialChannelAssignability reports whether a value x of channel type V
+// can be directly assigned (using memmove) to another channel type T.
+// https://golang.org/doc/go_spec.html#Assignability
+// T and V must be both of Chan kind.
+func specialChannelAssignability(T, V *abi.Type) bool {
+ // Special case:
+ // x is a bidirectional channel value, T is a channel type,
+ // x's type V and T have identical element types,
+ // and at least one of V or T is not a defined type.
+ return V.ChanDir() == abi.BothDir && (nameFor(T) == "" || nameFor(V) == "") && haveIdenticalType(T.Elem(), V.Elem(), true)
+}
+
+// directlyAssignable reports whether a value x of type V can be directly
+// assigned (using memmove) to a value of type T.
+// https://golang.org/doc/go_spec.html#Assignability
+// Ignoring the interface rules (implemented elsewhere)
+// and the ideal constant rules (no ideal constants at run time).
+func directlyAssignable(T, V *abi.Type) bool {
+ // x's type V is identical to T?
+ if T == V {
+ return true
+ }
+
+ // Otherwise at least one of T and V must not be defined
+ // and they must have the same kind.
+ if T.HasName() && V.HasName() || T.Kind() != V.Kind() {
+ return false
+ }
+
+ if T.Kind() == abi.Chan && specialChannelAssignability(T, V) {
+ return true
+ }
+
+ // x's type T and V must have identical underlying types.
+ return haveIdenticalUnderlyingType(T, V, true)
+}
+
+func haveIdenticalType(T, V *abi.Type, cmpTags bool) bool {
+ if cmpTags {
+ return T == V
+ }
+
+ if nameFor(T) != nameFor(V) || T.Kind() != V.Kind() || pkgPathFor(T) != pkgPathFor(V) {
+ return false
+ }
+
+ return haveIdenticalUnderlyingType(T, V, false)
+}
+
+func haveIdenticalUnderlyingType(T, V *abi.Type, cmpTags bool) bool {
+ if T == V {
+ return true
+ }
+
+ kind := Kind(T.Kind())
+ if kind != Kind(V.Kind()) {
+ return false
+ }
+
+ // Non-composite types of equal kind have same underlying type
+ // (the predefined instance of the type).
+ if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
+ return true
+ }
+
+ // Composite types.
+ switch kind {
+ case Array:
+ return T.Len() == V.Len() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
+
+ case Chan:
+ return V.ChanDir() == T.ChanDir() && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
+
+ case Func:
+ t := (*funcType)(unsafe.Pointer(T))
+ v := (*funcType)(unsafe.Pointer(V))
+ if t.OutCount != v.OutCount || t.InCount != v.InCount {
+ return false
+ }
+ for i := 0; i < t.NumIn(); i++ {
+ if !haveIdenticalType(t.In(i), v.In(i), cmpTags) {
+ return false
+ }
+ }
+ for i := 0; i < t.NumOut(); i++ {
+ if !haveIdenticalType(t.Out(i), v.Out(i), cmpTags) {
+ return false
+ }
+ }
+ return true
+
+ case Interface:
+ t := (*interfaceType)(unsafe.Pointer(T))
+ v := (*interfaceType)(unsafe.Pointer(V))
+ if len(t.Methods) == 0 && len(v.Methods) == 0 {
+ return true
+ }
+ // Might have the same methods but still
+ // need a run time conversion.
+ return false
+
+ case Map:
+ return haveIdenticalType(T.Key(), V.Key(), cmpTags) && haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
+
+ case Pointer, Slice:
+ return haveIdenticalType(T.Elem(), V.Elem(), cmpTags)
+
+ case Struct:
+ t := (*structType)(unsafe.Pointer(T))
+ v := (*structType)(unsafe.Pointer(V))
+ if len(t.Fields) != len(v.Fields) {
+ return false
+ }
+ if t.PkgPath.Name() != v.PkgPath.Name() {
+ return false
+ }
+ for i := range t.Fields {
+ tf := &t.Fields[i]
+ vf := &v.Fields[i]
+ if tf.Name.Name() != vf.Name.Name() {
+ return false
+ }
+ if !haveIdenticalType(tf.Typ, vf.Typ, cmpTags) {
+ return false
+ }
+ if cmpTags && tf.Name.Tag() != vf.Name.Tag() {
+ return false
+ }
+ if tf.Offset != vf.Offset {
+ return false
+ }
+ if tf.Embedded() != vf.Embedded() {
+ return false
+ }
+ }
+ return true
+ }
+
+ return false
+}
+
+// typelinks is implemented in package runtime.
+// It returns a slice of the sections in each module,
+// and a slice of *rtype offsets in each module.
+//
+// The types in each module are sorted by string. That is, the first
+// two linked types of the first module are:
+//
+// d0 := sections[0]
+// t1 := (*rtype)(add(d0, offset[0][0]))
+// t2 := (*rtype)(add(d0, offset[0][1]))
+//
+// and
+//
+// t1.String() < t2.String()
+//
+// Note that strings are not unique identifiers for types:
+// there can be more than one with a given string.
+// Only types we might want to look up are included:
+// pointers, channels, maps, slices, and arrays.
+func typelinks() (sections []unsafe.Pointer, offset [][]int32)
+
+func rtypeOff(section unsafe.Pointer, off int32) *abi.Type {
+ return (*abi.Type)(add(section, uintptr(off), "sizeof(rtype) > 0"))
+}
+
+// typesByString returns the subslice of typelinks() whose elements have
+// the given string representation.
+// It may be empty (no known types with that string) or may have
+// multiple elements (multiple types with that string).
+func typesByString(s string) []*abi.Type {
+ sections, offset := typelinks()
+ var ret []*abi.Type
+
+ for offsI, offs := range offset {
+ section := sections[offsI]
+
+ // We are looking for the first index i where the string becomes >= s.
+ // This is a copy of sort.Search, with f(h) replaced by (*typ[h].String() >= s).
+ i, j := 0, len(offs)
+ for i < j {
+ h := i + (j-i)>>1 // avoid overflow when computing h
+ // i ≤ h < j
+ if !(stringFor(rtypeOff(section, offs[h])) >= s) {
+ i = h + 1 // preserves f(i-1) == false
+ } else {
+ j = h // preserves f(j) == true
+ }
+ }
+ // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i.
+
+ // Having found the first, linear scan forward to find the last.
+ // We could do a second binary search, but the caller is going
+ // to do a linear scan anyway.
+ for j := i; j < len(offs); j++ {
+ typ := rtypeOff(section, offs[j])
+ if stringFor(typ) != s {
+ break
+ }
+ ret = append(ret, typ)
+ }
+ }
+ return ret
+}
+
+// The lookupCache caches ArrayOf, ChanOf, MapOf and SliceOf lookups.
+var lookupCache sync.Map // map[cacheKey]*rtype
+
+// A cacheKey is the key for use in the lookupCache.
+// Four values describe any of the types we are looking for:
+// type kind, one or two subtypes, and an extra integer.
+type cacheKey struct {
+ kind Kind
+ t1 *abi.Type
+ t2 *abi.Type
+ extra uintptr
+}
+
+// The funcLookupCache caches FuncOf lookups.
+// FuncOf does not share the common lookupCache since cacheKey is not
+// sufficient to represent functions unambiguously.
+var funcLookupCache struct {
+ sync.Mutex // Guards stores (but not loads) on m.
+
+ // m is a map[uint32][]*rtype keyed by the hash calculated in FuncOf.
+ // Elements of m are append-only and thus safe for concurrent reading.
+ m sync.Map
+}
+
+// ChanOf returns the channel type with the given direction and element type.
+// For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int.
+//
+// The gc runtime imposes a limit of 64 kB on channel element types.
+// If t's size is equal to or exceeds this limit, ChanOf panics.
+func ChanOf(dir ChanDir, t Type) Type {
+ typ := t.common()
+
+ // Look in cache.
+ ckey := cacheKey{Chan, typ, nil, uintptr(dir)}
+ if ch, ok := lookupCache.Load(ckey); ok {
+ return ch.(*rtype)
+ }
+
+ // This restriction is imposed by the gc compiler and the runtime.
+ if typ.Size_ >= 1<<16 {
+ panic("reflect.ChanOf: element size too large")
+ }
+
+ // Look in known types.
+ var s string
+ switch dir {
+ default:
+ panic("reflect.ChanOf: invalid dir")
+ case SendDir:
+ s = "chan<- " + stringFor(typ)
+ case RecvDir:
+ s = "<-chan " + stringFor(typ)
+ case BothDir:
+ typeStr := stringFor(typ)
+ if typeStr[0] == '<' {
+ // typ is recv chan, need parentheses as "<-" associates with leftmost
+ // chan possible, see:
+ // * https://golang.org/ref/spec#Channel_types
+ // * https://github.com/golang/go/issues/39897
+ s = "chan (" + typeStr + ")"
+ } else {
+ s = "chan " + typeStr
+ }
+ }
+ for _, tt := range typesByString(s) {
+ ch := (*chanType)(unsafe.Pointer(tt))
+ if ch.Elem == typ && ch.Dir == abi.ChanDir(dir) {
+ ti, _ := lookupCache.LoadOrStore(ckey, toRType(tt))
+ return ti.(Type)
+ }
+ }
+
+ // Make a channel type.
+ var ichan any = (chan unsafe.Pointer)(nil)
+ prototype := *(**chanType)(unsafe.Pointer(&ichan))
+ ch := *prototype
+ ch.TFlag = abi.TFlagRegularMemory
+ ch.Dir = abi.ChanDir(dir)
+ ch.Str = resolveReflectName(newName(s, "", false, false))
+ ch.Hash = fnv1(typ.Hash, 'c', byte(dir))
+ ch.Elem = typ
+
+ ti, _ := lookupCache.LoadOrStore(ckey, toRType(&ch.Type))
+ return ti.(Type)
+}
+
+// MapOf returns the map type with the given key and element types.
+// For example, if k represents int and e represents string,
+// MapOf(k, e) represents map[int]string.
+//
+// If the key type is not a valid map key type (that is, if it does
+// not implement Go's == operator), MapOf panics.
+func MapOf(key, elem Type) Type {
+ ktyp := key.common()
+ etyp := elem.common()
+
+ if ktyp.Equal == nil {
+ panic("reflect.MapOf: invalid key type " + stringFor(ktyp))
+ }
+
+ // Look in cache.
+ ckey := cacheKey{Map, ktyp, etyp, 0}
+ if mt, ok := lookupCache.Load(ckey); ok {
+ return mt.(Type)
+ }
+
+ // Look in known types.
+ s := "map[" + stringFor(ktyp) + "]" + stringFor(etyp)
+ for _, tt := range typesByString(s) {
+ mt := (*mapType)(unsafe.Pointer(tt))
+ if mt.Key == ktyp && mt.Elem == etyp {
+ ti, _ := lookupCache.LoadOrStore(ckey, toRType(tt))
+ return ti.(Type)
+ }
+ }
+
+ // Make a map type.
+ // Note: flag values must match those used in the TMAP case
+ // in ../cmd/compile/internal/reflectdata/reflect.go:writeType.
+ var imap any = (map[unsafe.Pointer]unsafe.Pointer)(nil)
+ mt := **(**mapType)(unsafe.Pointer(&imap))
+ mt.Str = resolveReflectName(newName(s, "", false, false))
+ mt.TFlag = 0
+ mt.Hash = fnv1(etyp.Hash, 'm', byte(ktyp.Hash>>24), byte(ktyp.Hash>>16), byte(ktyp.Hash>>8), byte(ktyp.Hash))
+ mt.Key = ktyp
+ mt.Elem = etyp
+ mt.Bucket = bucketOf(ktyp, etyp)
+ mt.Hasher = func(p unsafe.Pointer, seed uintptr) uintptr {
+ return typehash(ktyp, p, seed)
+ }
+ mt.Flags = 0
+ if ktyp.Size_ > maxKeySize {
+ mt.KeySize = uint8(goarch.PtrSize)
+ mt.Flags |= 1 // indirect key
+ } else {
+ mt.KeySize = uint8(ktyp.Size_)
+ }
+ if etyp.Size_ > maxValSize {
+ mt.ValueSize = uint8(goarch.PtrSize)
+ mt.Flags |= 2 // indirect value
+ } else {
+ mt.MapType.ValueSize = uint8(etyp.Size_)
+ }
+ mt.MapType.BucketSize = uint16(mt.Bucket.Size_)
+ if isReflexive(ktyp) {
+ mt.Flags |= 4
+ }
+ if needKeyUpdate(ktyp) {
+ mt.Flags |= 8
+ }
+ if hashMightPanic(ktyp) {
+ mt.Flags |= 16
+ }
+ mt.PtrToThis = 0
+
+ ti, _ := lookupCache.LoadOrStore(ckey, toRType(&mt.Type))
+ return ti.(Type)
+}
+
+var funcTypes []Type
+var funcTypesMutex sync.Mutex
+
+func initFuncTypes(n int) Type {
+ funcTypesMutex.Lock()
+ defer funcTypesMutex.Unlock()
+ if n >= len(funcTypes) {
+ newFuncTypes := make([]Type, n+1)
+ copy(newFuncTypes, funcTypes)
+ funcTypes = newFuncTypes
+ }
+ if funcTypes[n] != nil {
+ return funcTypes[n]
+ }
+
+ funcTypes[n] = StructOf([]StructField{
+ {
+ Name: "FuncType",
+ Type: TypeOf(funcType{}),
+ },
+ {
+ Name: "Args",
+ Type: ArrayOf(n, TypeOf(&rtype{})),
+ },
+ })
+ return funcTypes[n]
+}
+
+// FuncOf returns the function type with the given argument and result types.
+// For example if k represents int and e represents string,
+// FuncOf([]Type{k}, []Type{e}, false) represents func(int) string.
+//
+// The variadic argument controls whether the function is variadic. FuncOf
+// panics if the in[len(in)-1] does not represent a slice and variadic is
+// true.
+func FuncOf(in, out []Type, variadic bool) Type {
+ if variadic && (len(in) == 0 || in[len(in)-1].Kind() != Slice) {
+ panic("reflect.FuncOf: last arg of variadic func must be slice")
+ }
+
+ // Make a func type.
+ var ifunc any = (func())(nil)
+ prototype := *(**funcType)(unsafe.Pointer(&ifunc))
+ n := len(in) + len(out)
+
+ if n > 128 {
+ panic("reflect.FuncOf: too many arguments")
+ }
+
+ o := New(initFuncTypes(n)).Elem()
+ ft := (*funcType)(unsafe.Pointer(o.Field(0).Addr().Pointer()))
+ args := unsafe.Slice((**rtype)(unsafe.Pointer(o.Field(1).Addr().Pointer())), n)[0:0:n]
+ *ft = *prototype
+
+ // Build a hash and minimally populate ft.
+ var hash uint32
+ for _, in := range in {
+ t := in.(*rtype)
+ args = append(args, t)
+ hash = fnv1(hash, byte(t.t.Hash>>24), byte(t.t.Hash>>16), byte(t.t.Hash>>8), byte(t.t.Hash))
+ }
+ if variadic {
+ hash = fnv1(hash, 'v')
+ }
+ hash = fnv1(hash, '.')
+ for _, out := range out {
+ t := out.(*rtype)
+ args = append(args, t)
+ hash = fnv1(hash, byte(t.t.Hash>>24), byte(t.t.Hash>>16), byte(t.t.Hash>>8), byte(t.t.Hash))
+ }
+
+ ft.TFlag = 0
+ ft.Hash = hash
+ ft.InCount = uint16(len(in))
+ ft.OutCount = uint16(len(out))
+ if variadic {
+ ft.OutCount |= 1 << 15
+ }
+
+ // Look in cache.
+ if ts, ok := funcLookupCache.m.Load(hash); ok {
+ for _, t := range ts.([]*abi.Type) {
+ if haveIdenticalUnderlyingType(&ft.Type, t, true) {
+ return toRType(t)
+ }
+ }
+ }
+
+ // Not in cache, lock and retry.
+ funcLookupCache.Lock()
+ defer funcLookupCache.Unlock()
+ if ts, ok := funcLookupCache.m.Load(hash); ok {
+ for _, t := range ts.([]*abi.Type) {
+ if haveIdenticalUnderlyingType(&ft.Type, t, true) {
+ return toRType(t)
+ }
+ }
+ }
+
+ addToCache := func(tt *abi.Type) Type {
+ var rts []*abi.Type
+ if rti, ok := funcLookupCache.m.Load(hash); ok {
+ rts = rti.([]*abi.Type)
+ }
+ funcLookupCache.m.Store(hash, append(rts, tt))
+ return toType(tt)
+ }
+
+ // Look in known types for the same string representation.
+ str := funcStr(ft)
+ for _, tt := range typesByString(str) {
+ if haveIdenticalUnderlyingType(&ft.Type, tt, true) {
+ return addToCache(tt)
+ }
+ }
+
+ // Populate the remaining fields of ft and store in cache.
+ ft.Str = resolveReflectName(newName(str, "", false, false))
+ ft.PtrToThis = 0
+ return addToCache(&ft.Type)
+}
+func stringFor(t *abi.Type) string {
+ return toRType(t).String()
+}
+
+// funcStr builds a string representation of a funcType.
+func funcStr(ft *funcType) string {
+ repr := make([]byte, 0, 64)
+ repr = append(repr, "func("...)
+ for i, t := range ft.InSlice() {
+ if i > 0 {
+ repr = append(repr, ", "...)
+ }
+ if ft.IsVariadic() && i == int(ft.InCount)-1 {
+ repr = append(repr, "..."...)
+ repr = append(repr, stringFor((*sliceType)(unsafe.Pointer(t)).Elem)...)
+ } else {
+ repr = append(repr, stringFor(t)...)
+ }
+ }
+ repr = append(repr, ')')
+ out := ft.OutSlice()
+ if len(out) == 1 {
+ repr = append(repr, ' ')
+ } else if len(out) > 1 {
+ repr = append(repr, " ("...)
+ }
+ for i, t := range out {
+ if i > 0 {
+ repr = append(repr, ", "...)
+ }
+ repr = append(repr, stringFor(t)...)
+ }
+ if len(out) > 1 {
+ repr = append(repr, ')')
+ }
+ return string(repr)
+}
+
+// isReflexive reports whether the == operation on the type is reflexive.
+// That is, x == x for all values x of type t.
+func isReflexive(t *abi.Type) bool {
+ switch Kind(t.Kind()) {
+ case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Pointer, String, UnsafePointer:
+ return true
+ case Float32, Float64, Complex64, Complex128, Interface:
+ return false
+ case Array:
+ tt := (*arrayType)(unsafe.Pointer(t))
+ return isReflexive(tt.Elem)
+ case Struct:
+ tt := (*structType)(unsafe.Pointer(t))
+ for _, f := range tt.Fields {
+ if !isReflexive(f.Typ) {
+ return false
+ }
+ }
+ return true
+ default:
+ // Func, Map, Slice, Invalid
+ panic("isReflexive called on non-key type " + stringFor(t))
+ }
+}
+
+// needKeyUpdate reports whether map overwrites require the key to be copied.
+func needKeyUpdate(t *abi.Type) bool {
+ switch Kind(t.Kind()) {
+ case Bool, Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr, Chan, Pointer, UnsafePointer:
+ return false
+ case Float32, Float64, Complex64, Complex128, Interface, String:
+ // Float keys can be updated from +0 to -0.
+ // String keys can be updated to use a smaller backing store.
+ // Interfaces might have floats of strings in them.
+ return true
+ case Array:
+ tt := (*arrayType)(unsafe.Pointer(t))
+ return needKeyUpdate(tt.Elem)
+ case Struct:
+ tt := (*structType)(unsafe.Pointer(t))
+ for _, f := range tt.Fields {
+ if needKeyUpdate(f.Typ) {
+ return true
+ }
+ }
+ return false
+ default:
+ // Func, Map, Slice, Invalid
+ panic("needKeyUpdate called on non-key type " + stringFor(t))
+ }
+}
+
+// hashMightPanic reports whether the hash of a map key of type t might panic.
+func hashMightPanic(t *abi.Type) bool {
+ switch Kind(t.Kind()) {
+ case Interface:
+ return true
+ case Array:
+ tt := (*arrayType)(unsafe.Pointer(t))
+ return hashMightPanic(tt.Elem)
+ case Struct:
+ tt := (*structType)(unsafe.Pointer(t))
+ for _, f := range tt.Fields {
+ if hashMightPanic(f.Typ) {
+ return true
+ }
+ }
+ return false
+ default:
+ return false
+ }
+}
+
+// Make sure these routines stay in sync with ../runtime/map.go!
+// These types exist only for GC, so we only fill out GC relevant info.
+// Currently, that's just size and the GC program. We also fill in string
+// for possible debugging use.
+const (
+ bucketSize uintptr = abi.MapBucketCount
+ maxKeySize uintptr = abi.MapMaxKeyBytes
+ maxValSize uintptr = abi.MapMaxElemBytes
+)
+
+func bucketOf(ktyp, etyp *abi.Type) *abi.Type {
+ if ktyp.Size_ > maxKeySize {
+ ktyp = ptrTo(ktyp)
+ }
+ if etyp.Size_ > maxValSize {
+ etyp = ptrTo(etyp)
+ }
+
+ // Prepare GC data if any.
+ // A bucket is at most bucketSize*(1+maxKeySize+maxValSize)+ptrSize bytes,
+ // or 2064 bytes, or 258 pointer-size words, or 33 bytes of pointer bitmap.
+ // Note that since the key and value are known to be <= 128 bytes,
+ // they're guaranteed to have bitmaps instead of GC programs.
+ var gcdata *byte
+ var ptrdata uintptr
+
+ size := bucketSize*(1+ktyp.Size_+etyp.Size_) + goarch.PtrSize
+ if size&uintptr(ktyp.Align_-1) != 0 || size&uintptr(etyp.Align_-1) != 0 {
+ panic("reflect: bad size computation in MapOf")
+ }
+
+ if ktyp.PtrBytes != 0 || etyp.PtrBytes != 0 {
+ nptr := (bucketSize*(1+ktyp.Size_+etyp.Size_) + goarch.PtrSize) / goarch.PtrSize
+ n := (nptr + 7) / 8
+
+ // Runtime needs pointer masks to be a multiple of uintptr in size.
+ n = (n + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1)
+ mask := make([]byte, n)
+ base := bucketSize / goarch.PtrSize
+
+ if ktyp.PtrBytes != 0 {
+ emitGCMask(mask, base, ktyp, bucketSize)
+ }
+ base += bucketSize * ktyp.Size_ / goarch.PtrSize
+
+ if etyp.PtrBytes != 0 {
+ emitGCMask(mask, base, etyp, bucketSize)
+ }
+ base += bucketSize * etyp.Size_ / goarch.PtrSize
+
+ word := base
+ mask[word/8] |= 1 << (word % 8)
+ gcdata = &mask[0]
+ ptrdata = (word + 1) * goarch.PtrSize
+
+ // overflow word must be last
+ if ptrdata != size {
+ panic("reflect: bad layout computation in MapOf")
+ }
+ }
+
+ b := &abi.Type{
+ Align_: goarch.PtrSize,
+ Size_: size,
+ Kind_: uint8(Struct),
+ PtrBytes: ptrdata,
+ GCData: gcdata,
+ }
+ s := "bucket(" + stringFor(ktyp) + "," + stringFor(etyp) + ")"
+ b.Str = resolveReflectName(newName(s, "", false, false))
+ return b
+}
+
+func (t *rtype) gcSlice(begin, end uintptr) []byte {
+ return (*[1 << 30]byte)(unsafe.Pointer(t.t.GCData))[begin:end:end]
+}
+
+// emitGCMask writes the GC mask for [n]typ into out, starting at bit
+// offset base.
+func emitGCMask(out []byte, base uintptr, typ *abi.Type, n uintptr) {
+ if typ.Kind_&kindGCProg != 0 {
+ panic("reflect: unexpected GC program")
+ }
+ ptrs := typ.PtrBytes / goarch.PtrSize
+ words := typ.Size_ / goarch.PtrSize
+ mask := typ.GcSlice(0, (ptrs+7)/8)
+ for j := uintptr(0); j < ptrs; j++ {
+ if (mask[j/8]>>(j%8))&1 != 0 {
+ for i := uintptr(0); i < n; i++ {
+ k := base + i*words + j
+ out[k/8] |= 1 << (k % 8)
+ }
+ }
+ }
+}
+
+// appendGCProg appends the GC program for the first ptrdata bytes of
+// typ to dst and returns the extended slice.
+func appendGCProg(dst []byte, typ *abi.Type) []byte {
+ if typ.Kind_&kindGCProg != 0 {
+ // Element has GC program; emit one element.
+ n := uintptr(*(*uint32)(unsafe.Pointer(typ.GCData)))
+ prog := typ.GcSlice(4, 4+n-1)
+ return append(dst, prog...)
+ }
+
+ // Element is small with pointer mask; use as literal bits.
+ ptrs := typ.PtrBytes / goarch.PtrSize
+ mask := typ.GcSlice(0, (ptrs+7)/8)
+
+ // Emit 120-bit chunks of full bytes (max is 127 but we avoid using partial bytes).
+ for ; ptrs > 120; ptrs -= 120 {
+ dst = append(dst, 120)
+ dst = append(dst, mask[:15]...)
+ mask = mask[15:]
+ }
+
+ dst = append(dst, byte(ptrs))
+ dst = append(dst, mask...)
+ return dst
+}
+
+// SliceOf returns the slice type with element type t.
+// For example, if t represents int, SliceOf(t) represents []int.
+func SliceOf(t Type) Type {
+ typ := t.common()
+
+ // Look in cache.
+ ckey := cacheKey{Slice, typ, nil, 0}
+ if slice, ok := lookupCache.Load(ckey); ok {
+ return slice.(Type)
+ }
+
+ // Look in known types.
+ s := "[]" + stringFor(typ)
+ for _, tt := range typesByString(s) {
+ slice := (*sliceType)(unsafe.Pointer(tt))
+ if slice.Elem == typ {
+ ti, _ := lookupCache.LoadOrStore(ckey, toRType(tt))
+ return ti.(Type)
+ }
+ }
+
+ // Make a slice type.
+ var islice any = ([]unsafe.Pointer)(nil)
+ prototype := *(**sliceType)(unsafe.Pointer(&islice))
+ slice := *prototype
+ slice.TFlag = 0
+ slice.Str = resolveReflectName(newName(s, "", false, false))
+ slice.Hash = fnv1(typ.Hash, '[')
+ slice.Elem = typ
+ slice.PtrToThis = 0
+
+ ti, _ := lookupCache.LoadOrStore(ckey, toRType(&slice.Type))
+ return ti.(Type)
+}
+
+// The structLookupCache caches StructOf lookups.
+// StructOf does not share the common lookupCache since we need to pin
+// the memory associated with *structTypeFixedN.
+var structLookupCache struct {
+ sync.Mutex // Guards stores (but not loads) on m.
+
+ // m is a map[uint32][]Type keyed by the hash calculated in StructOf.
+ // Elements in m are append-only and thus safe for concurrent reading.
+ m sync.Map
+}
+
+type structTypeUncommon struct {
+ structType
+ u uncommonType
+}
+
+// isLetter reports whether a given 'rune' is classified as a Letter.
+func isLetter(ch rune) bool {
+ return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch)
+}
+
+// isValidFieldName checks if a string is a valid (struct) field name or not.
+//
+// According to the language spec, a field name should be an identifier.
+//
+// identifier = letter { letter | unicode_digit } .
+// letter = unicode_letter | "_" .
+func isValidFieldName(fieldName string) bool {
+ for i, c := range fieldName {
+ if i == 0 && !isLetter(c) {
+ return false
+ }
+
+ if !(isLetter(c) || unicode.IsDigit(c)) {
+ return false
+ }
+ }
+
+ return len(fieldName) > 0
+}
+
+// StructOf returns the struct type containing fields.
+// The Offset and Index fields are ignored and computed as they would be
+// by the compiler.
+//
+// StructOf currently does not generate wrapper methods for embedded
+// fields and panics if passed unexported StructFields.
+// These limitations may be lifted in a future version.
+func StructOf(fields []StructField) Type {
+ var (
+ hash = fnv1(0, []byte("struct {")...)
+ size uintptr
+ typalign uint8
+ comparable = true
+ methods []abi.Method
+
+ fs = make([]structField, len(fields))
+ repr = make([]byte, 0, 64)
+ fset = map[string]struct{}{} // fields' names
+
+ hasGCProg = false // records whether a struct-field type has a GCProg
+ )
+
+ lastzero := uintptr(0)
+ repr = append(repr, "struct {"...)
+ pkgpath := ""
+ for i, field := range fields {
+ if field.Name == "" {
+ panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no name")
+ }
+ if !isValidFieldName(field.Name) {
+ panic("reflect.StructOf: field " + strconv.Itoa(i) + " has invalid name")
+ }
+ if field.Type == nil {
+ panic("reflect.StructOf: field " + strconv.Itoa(i) + " has no type")
+ }
+ f, fpkgpath := runtimeStructField(field)
+ ft := f.Typ
+ if ft.Kind_&kindGCProg != 0 {
+ hasGCProg = true
+ }
+ if fpkgpath != "" {
+ if pkgpath == "" {
+ pkgpath = fpkgpath
+ } else if pkgpath != fpkgpath {
+ panic("reflect.Struct: fields with different PkgPath " + pkgpath + " and " + fpkgpath)
+ }
+ }
+
+ // Update string and hash
+ name := f.Name.Name()
+ hash = fnv1(hash, []byte(name)...)
+ repr = append(repr, (" " + name)...)
+ if f.Embedded() {
+ // Embedded field
+ if f.Typ.Kind() == abi.Pointer {
+ // Embedded ** and *interface{} are illegal
+ elem := ft.Elem()
+ if k := elem.Kind(); k == abi.Pointer || k == abi.Interface {
+ panic("reflect.StructOf: illegal embedded field type " + stringFor(ft))
+ }
+ }
+
+ switch Kind(f.Typ.Kind()) {
+ case Interface:
+ ift := (*interfaceType)(unsafe.Pointer(ft))
+ for im, m := range ift.Methods {
+ if pkgPath(ift.nameOff(m.Name)) != "" {
+ // TODO(sbinet). Issue 15924.
+ panic("reflect: embedded interface with unexported method(s) not implemented")
+ }
+
+ var (
+ mtyp = ift.typeOff(m.Typ)
+ ifield = i
+ imethod = im
+ ifn Value
+ tfn Value
+ )
+
+ if ft.Kind_&kindDirectIface != 0 {
+ tfn = MakeFunc(toRType(mtyp), func(in []Value) []Value {
+ var args []Value
+ var recv = in[0]
+ if len(in) > 1 {
+ args = in[1:]
+ }
+ return recv.Field(ifield).Method(imethod).Call(args)
+ })
+ ifn = MakeFunc(toRType(mtyp), func(in []Value) []Value {
+ var args []Value
+ var recv = in[0]
+ if len(in) > 1 {
+ args = in[1:]
+ }
+ return recv.Field(ifield).Method(imethod).Call(args)
+ })
+ } else {
+ tfn = MakeFunc(toRType(mtyp), func(in []Value) []Value {
+ var args []Value
+ var recv = in[0]
+ if len(in) > 1 {
+ args = in[1:]
+ }
+ return recv.Field(ifield).Method(imethod).Call(args)
+ })
+ ifn = MakeFunc(toRType(mtyp), func(in []Value) []Value {
+ var args []Value
+ var recv = Indirect(in[0])
+ if len(in) > 1 {
+ args = in[1:]
+ }
+ return recv.Field(ifield).Method(imethod).Call(args)
+ })
+ }
+
+ methods = append(methods, abi.Method{
+ Name: resolveReflectName(ift.nameOff(m.Name)),
+ Mtyp: resolveReflectType(mtyp),
+ Ifn: resolveReflectText(unsafe.Pointer(&ifn)),
+ Tfn: resolveReflectText(unsafe.Pointer(&tfn)),
+ })
+ }
+ case Pointer:
+ ptr := (*ptrType)(unsafe.Pointer(ft))
+ if unt := ptr.Uncommon(); unt != nil {
+ if i > 0 && unt.Mcount > 0 {
+ // Issue 15924.
+ panic("reflect: embedded type with methods not implemented if type is not first field")
+ }
+ if len(fields) > 1 {
+ panic("reflect: embedded type with methods not implemented if there is more than one field")
+ }
+ for _, m := range unt.Methods() {
+ mname := nameOffFor(ft, m.Name)
+ if pkgPath(mname) != "" {
+ // TODO(sbinet).
+ // Issue 15924.
+ panic("reflect: embedded interface with unexported method(s) not implemented")
+ }
+ methods = append(methods, abi.Method{
+ Name: resolveReflectName(mname),
+ Mtyp: resolveReflectType(typeOffFor(ft, m.Mtyp)),
+ Ifn: resolveReflectText(textOffFor(ft, m.Ifn)),
+ Tfn: resolveReflectText(textOffFor(ft, m.Tfn)),
+ })
+ }
+ }
+ if unt := ptr.Elem.Uncommon(); unt != nil {
+ for _, m := range unt.Methods() {
+ mname := nameOffFor(ft, m.Name)
+ if pkgPath(mname) != "" {
+ // TODO(sbinet)
+ // Issue 15924.
+ panic("reflect: embedded interface with unexported method(s) not implemented")
+ }
+ methods = append(methods, abi.Method{
+ Name: resolveReflectName(mname),
+ Mtyp: resolveReflectType(typeOffFor(ptr.Elem, m.Mtyp)),
+ Ifn: resolveReflectText(textOffFor(ptr.Elem, m.Ifn)),
+ Tfn: resolveReflectText(textOffFor(ptr.Elem, m.Tfn)),
+ })
+ }
+ }
+ default:
+ if unt := ft.Uncommon(); unt != nil {
+ if i > 0 && unt.Mcount > 0 {
+ // Issue 15924.
+ panic("reflect: embedded type with methods not implemented if type is not first field")
+ }
+ if len(fields) > 1 && ft.Kind_&kindDirectIface != 0 {
+ panic("reflect: embedded type with methods not implemented for non-pointer type")
+ }
+ for _, m := range unt.Methods() {
+ mname := nameOffFor(ft, m.Name)
+ if pkgPath(mname) != "" {
+ // TODO(sbinet)
+ // Issue 15924.
+ panic("reflect: embedded interface with unexported method(s) not implemented")
+ }
+ methods = append(methods, abi.Method{
+ Name: resolveReflectName(mname),
+ Mtyp: resolveReflectType(typeOffFor(ft, m.Mtyp)),
+ Ifn: resolveReflectText(textOffFor(ft, m.Ifn)),
+ Tfn: resolveReflectText(textOffFor(ft, m.Tfn)),
+ })
+
+ }
+ }
+ }
+ }
+ if _, dup := fset[name]; dup && name != "_" {
+ panic("reflect.StructOf: duplicate field " + name)
+ }
+ fset[name] = struct{}{}
+
+ hash = fnv1(hash, byte(ft.Hash>>24), byte(ft.Hash>>16), byte(ft.Hash>>8), byte(ft.Hash))
+
+ repr = append(repr, (" " + stringFor(ft))...)
+ if f.Name.HasTag() {
+ hash = fnv1(hash, []byte(f.Name.Tag())...)
+ repr = append(repr, (" " + strconv.Quote(f.Name.Tag()))...)
+ }
+ if i < len(fields)-1 {
+ repr = append(repr, ';')
+ }
+
+ comparable = comparable && (ft.Equal != nil)
+
+ offset := align(size, uintptr(ft.Align_))
+ if offset < size {
+ panic("reflect.StructOf: struct size would exceed virtual address space")
+ }
+ if ft.Align_ > typalign {
+ typalign = ft.Align_
+ }
+ size = offset + ft.Size_
+ if size < offset {
+ panic("reflect.StructOf: struct size would exceed virtual address space")
+ }
+ f.Offset = offset
+
+ if ft.Size_ == 0 {
+ lastzero = size
+ }
+
+ fs[i] = f
+ }
+
+ if size > 0 && lastzero == size {
+ // This is a non-zero sized struct that ends in a
+ // zero-sized field. We add an extra byte of padding,
+ // to ensure that taking the address of the final
+ // zero-sized field can't manufacture a pointer to the
+ // next object in the heap. See issue 9401.
+ size++
+ if size == 0 {
+ panic("reflect.StructOf: struct size would exceed virtual address space")
+ }
+ }
+
+ var typ *structType
+ var ut *uncommonType
+
+ if len(methods) == 0 {
+ t := new(structTypeUncommon)
+ typ = &t.structType
+ ut = &t.u
+ } else {
+ // A *rtype representing a struct is followed directly in memory by an
+ // array of method objects representing the methods attached to the
+ // struct. To get the same layout for a run time generated type, we
+ // need an array directly following the uncommonType memory.
+ // A similar strategy is used for funcTypeFixed4, ...funcTypeFixedN.
+ tt := New(StructOf([]StructField{
+ {Name: "S", Type: TypeOf(structType{})},
+ {Name: "U", Type: TypeOf(uncommonType{})},
+ {Name: "M", Type: ArrayOf(len(methods), TypeOf(methods[0]))},
+ }))
+
+ typ = (*structType)(tt.Elem().Field(0).Addr().UnsafePointer())
+ ut = (*uncommonType)(tt.Elem().Field(1).Addr().UnsafePointer())
+
+ copy(tt.Elem().Field(2).Slice(0, len(methods)).Interface().([]abi.Method), methods)
+ }
+ // TODO(sbinet): Once we allow embedding multiple types,
+ // methods will need to be sorted like the compiler does.
+ // TODO(sbinet): Once we allow non-exported methods, we will
+ // need to compute xcount as the number of exported methods.
+ ut.Mcount = uint16(len(methods))
+ ut.Xcount = ut.Mcount
+ ut.Moff = uint32(unsafe.Sizeof(uncommonType{}))
+
+ if len(fs) > 0 {
+ repr = append(repr, ' ')
+ }
+ repr = append(repr, '}')
+ hash = fnv1(hash, '}')
+ str := string(repr)
+
+ // Round the size up to be a multiple of the alignment.
+ s := align(size, uintptr(typalign))
+ if s < size {
+ panic("reflect.StructOf: struct size would exceed virtual address space")
+ }
+ size = s
+
+ // Make the struct type.
+ var istruct any = struct{}{}
+ prototype := *(**structType)(unsafe.Pointer(&istruct))
+ *typ = *prototype
+ typ.Fields = fs
+ if pkgpath != "" {
+ typ.PkgPath = newName(pkgpath, "", false, false)
+ }
+
+ // Look in cache.
+ if ts, ok := structLookupCache.m.Load(hash); ok {
+ for _, st := range ts.([]Type) {
+ t := st.common()
+ if haveIdenticalUnderlyingType(&typ.Type, t, true) {
+ return toType(t)
+ }
+ }
+ }
+
+ // Not in cache, lock and retry.
+ structLookupCache.Lock()
+ defer structLookupCache.Unlock()
+ if ts, ok := structLookupCache.m.Load(hash); ok {
+ for _, st := range ts.([]Type) {
+ t := st.common()
+ if haveIdenticalUnderlyingType(&typ.Type, t, true) {
+ return toType(t)
+ }
+ }
+ }
+
+ addToCache := func(t Type) Type {
+ var ts []Type
+ if ti, ok := structLookupCache.m.Load(hash); ok {
+ ts = ti.([]Type)
+ }
+ structLookupCache.m.Store(hash, append(ts, t))
+ return t
+ }
+
+ // Look in known types.
+ for _, t := range typesByString(str) {
+ if haveIdenticalUnderlyingType(&typ.Type, t, true) {
+ // even if 't' wasn't a structType with methods, we should be ok
+ // as the 'u uncommonType' field won't be accessed except when
+ // tflag&abi.TFlagUncommon is set.
+ return addToCache(toType(t))
+ }
+ }
+
+ typ.Str = resolveReflectName(newName(str, "", false, false))
+ typ.TFlag = 0 // TODO: set tflagRegularMemory
+ typ.Hash = hash
+ typ.Size_ = size
+ typ.PtrBytes = typeptrdata(&typ.Type)
+ typ.Align_ = typalign
+ typ.FieldAlign_ = typalign
+ typ.PtrToThis = 0
+ if len(methods) > 0 {
+ typ.TFlag |= abi.TFlagUncommon
+ }
+
+ if hasGCProg {
+ lastPtrField := 0
+ for i, ft := range fs {
+ if ft.Typ.Pointers() {
+ lastPtrField = i
+ }
+ }
+ prog := []byte{0, 0, 0, 0} // will be length of prog
+ var off uintptr
+ for i, ft := range fs {
+ if i > lastPtrField {
+ // gcprog should not include anything for any field after
+ // the last field that contains pointer data
+ break
+ }
+ if !ft.Typ.Pointers() {
+ // Ignore pointerless fields.
+ continue
+ }
+ // Pad to start of this field with zeros.
+ if ft.Offset > off {
+ n := (ft.Offset - off) / goarch.PtrSize
+ prog = append(prog, 0x01, 0x00) // emit a 0 bit
+ if n > 1 {
+ prog = append(prog, 0x81) // repeat previous bit
+ prog = appendVarint(prog, n-1) // n-1 times
+ }
+ off = ft.Offset
+ }
+
+ prog = appendGCProg(prog, ft.Typ)
+ off += ft.Typ.PtrBytes
+ }
+ prog = append(prog, 0)
+ *(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4)
+ typ.Kind_ |= kindGCProg
+ typ.GCData = &prog[0]
+ } else {
+ typ.Kind_ &^= kindGCProg
+ bv := new(bitVector)
+ addTypeBits(bv, 0, &typ.Type)
+ if len(bv.data) > 0 {
+ typ.GCData = &bv.data[0]
+ }
+ }
+ typ.Equal = nil
+ if comparable {
+ typ.Equal = func(p, q unsafe.Pointer) bool {
+ for _, ft := range typ.Fields {
+ pi := add(p, ft.Offset, "&x.field safe")
+ qi := add(q, ft.Offset, "&x.field safe")
+ if !ft.Typ.Equal(pi, qi) {
+ return false
+ }
+ }
+ return true
+ }
+ }
+
+ switch {
+ case len(fs) == 1 && !ifaceIndir(fs[0].Typ):
+ // structs of 1 direct iface type can be direct
+ typ.Kind_ |= kindDirectIface
+ default:
+ typ.Kind_ &^= kindDirectIface
+ }
+
+ return addToCache(toType(&typ.Type))
+}
+
+// runtimeStructField takes a StructField value passed to StructOf and
+// returns both the corresponding internal representation, of type
+// structField, and the pkgpath value to use for this field.
+func runtimeStructField(field StructField) (structField, string) {
+ if field.Anonymous && field.PkgPath != "" {
+ panic("reflect.StructOf: field \"" + field.Name + "\" is anonymous but has PkgPath set")
+ }
+
+ if field.IsExported() {
+ // Best-effort check for misuse.
+ // Since this field will be treated as exported, not much harm done if Unicode lowercase slips through.
+ c := field.Name[0]
+ if 'a' <= c && c <= 'z' || c == '_' {
+ panic("reflect.StructOf: field \"" + field.Name + "\" is unexported but missing PkgPath")
+ }
+ }
+
+ resolveReflectType(field.Type.common()) // install in runtime
+ f := structField{
+ Name: newName(field.Name, string(field.Tag), field.IsExported(), field.Anonymous),
+ Typ: field.Type.common(),
+ Offset: 0,
+ }
+ return f, field.PkgPath
+}
+
+// typeptrdata returns the length in bytes of the prefix of t
+// containing pointer data. Anything after this offset is scalar data.
+// keep in sync with ../cmd/compile/internal/reflectdata/reflect.go
+func typeptrdata(t *abi.Type) uintptr {
+ switch t.Kind() {
+ case abi.Struct:
+ st := (*structType)(unsafe.Pointer(t))
+ // find the last field that has pointers.
+ field := -1
+ for i := range st.Fields {
+ ft := st.Fields[i].Typ
+ if ft.Pointers() {
+ field = i
+ }
+ }
+ if field == -1 {
+ return 0
+ }
+ f := st.Fields[field]
+ return f.Offset + f.Typ.PtrBytes
+
+ default:
+ panic("reflect.typeptrdata: unexpected type, " + stringFor(t))
+ }
+}
+
+// See cmd/compile/internal/reflectdata/reflect.go for derivation of constant.
+const maxPtrmaskBytes = 2048
+
+// ArrayOf returns the array type with the given length and element type.
+// For example, if t represents int, ArrayOf(5, t) represents [5]int.
+//
+// If the resulting type would be larger than the available address space,
+// ArrayOf panics.
+func ArrayOf(length int, elem Type) Type {
+ if length < 0 {
+ panic("reflect: negative length passed to ArrayOf")
+ }
+
+ typ := elem.common()
+
+ // Look in cache.
+ ckey := cacheKey{Array, typ, nil, uintptr(length)}
+ if array, ok := lookupCache.Load(ckey); ok {
+ return array.(Type)
+ }
+
+ // Look in known types.
+ s := "[" + strconv.Itoa(length) + "]" + stringFor(typ)
+ for _, tt := range typesByString(s) {
+ array := (*arrayType)(unsafe.Pointer(tt))
+ if array.Elem == typ {
+ ti, _ := lookupCache.LoadOrStore(ckey, toRType(tt))
+ return ti.(Type)
+ }
+ }
+
+ // Make an array type.
+ var iarray any = [1]unsafe.Pointer{}
+ prototype := *(**arrayType)(unsafe.Pointer(&iarray))
+ array := *prototype
+ array.TFlag = typ.TFlag & abi.TFlagRegularMemory
+ array.Str = resolveReflectName(newName(s, "", false, false))
+ array.Hash = fnv1(typ.Hash, '[')
+ for n := uint32(length); n > 0; n >>= 8 {
+ array.Hash = fnv1(array.Hash, byte(n))
+ }
+ array.Hash = fnv1(array.Hash, ']')
+ array.Elem = typ
+ array.PtrToThis = 0
+ if typ.Size_ > 0 {
+ max := ^uintptr(0) / typ.Size_
+ if uintptr(length) > max {
+ panic("reflect.ArrayOf: array size would exceed virtual address space")
+ }
+ }
+ array.Size_ = typ.Size_ * uintptr(length)
+ if length > 0 && typ.PtrBytes != 0 {
+ array.PtrBytes = typ.Size_*uintptr(length-1) + typ.PtrBytes
+ }
+ array.Align_ = typ.Align_
+ array.FieldAlign_ = typ.FieldAlign_
+ array.Len = uintptr(length)
+ array.Slice = &(SliceOf(elem).(*rtype).t)
+
+ switch {
+ case typ.PtrBytes == 0 || array.Size_ == 0:
+ // No pointers.
+ array.GCData = nil
+ array.PtrBytes = 0
+
+ case length == 1:
+ // In memory, 1-element array looks just like the element.
+ array.Kind_ |= typ.Kind_ & kindGCProg
+ array.GCData = typ.GCData
+ array.PtrBytes = typ.PtrBytes
+
+ case typ.Kind_&kindGCProg == 0 && array.Size_ <= maxPtrmaskBytes*8*goarch.PtrSize:
+ // Element is small with pointer mask; array is still small.
+ // Create direct pointer mask by turning each 1 bit in elem
+ // into length 1 bits in larger mask.
+ n := (array.PtrBytes/goarch.PtrSize + 7) / 8
+ // Runtime needs pointer masks to be a multiple of uintptr in size.
+ n = (n + goarch.PtrSize - 1) &^ (goarch.PtrSize - 1)
+ mask := make([]byte, n)
+ emitGCMask(mask, 0, typ, array.Len)
+ array.GCData = &mask[0]
+
+ default:
+ // Create program that emits one element
+ // and then repeats to make the array.
+ prog := []byte{0, 0, 0, 0} // will be length of prog
+ prog = appendGCProg(prog, typ)
+ // Pad from ptrdata to size.
+ elemPtrs := typ.PtrBytes / goarch.PtrSize
+ elemWords := typ.Size_ / goarch.PtrSize
+ if elemPtrs < elemWords {
+ // Emit literal 0 bit, then repeat as needed.
+ prog = append(prog, 0x01, 0x00)
+ if elemPtrs+1 < elemWords {
+ prog = append(prog, 0x81)
+ prog = appendVarint(prog, elemWords-elemPtrs-1)
+ }
+ }
+ // Repeat length-1 times.
+ if elemWords < 0x80 {
+ prog = append(prog, byte(elemWords|0x80))
+ } else {
+ prog = append(prog, 0x80)
+ prog = appendVarint(prog, elemWords)
+ }
+ prog = appendVarint(prog, uintptr(length)-1)
+ prog = append(prog, 0)
+ *(*uint32)(unsafe.Pointer(&prog[0])) = uint32(len(prog) - 4)
+ array.Kind_ |= kindGCProg
+ array.GCData = &prog[0]
+ array.PtrBytes = array.Size_ // overestimate but ok; must match program
+ }
+
+ etyp := typ
+ esize := etyp.Size()
+
+ array.Equal = nil
+ if eequal := etyp.Equal; eequal != nil {
+ array.Equal = func(p, q unsafe.Pointer) bool {
+ for i := 0; i < length; i++ {
+ pi := arrayAt(p, i, esize, "i < length")
+ qi := arrayAt(q, i, esize, "i < length")
+ if !eequal(pi, qi) {
+ return false
+ }
+
+ }
+ return true
+ }
+ }
+
+ switch {
+ case length == 1 && !ifaceIndir(typ):
+ // array of 1 direct iface type can be direct
+ array.Kind_ |= kindDirectIface
+ default:
+ array.Kind_ &^= kindDirectIface
+ }
+
+ ti, _ := lookupCache.LoadOrStore(ckey, toRType(&array.Type))
+ return ti.(Type)
+}
+
+func appendVarint(x []byte, v uintptr) []byte {
+ for ; v >= 0x80; v >>= 7 {
+ x = append(x, byte(v|0x80))
+ }
+ x = append(x, byte(v))
+ return x
+}
+
+// toType converts from a *rtype to a Type that can be returned
+// to the client of package reflect. In gc, the only concern is that
+// a nil *rtype must be replaced by a nil Type, but in gccgo this
+// function takes care of ensuring that multiple *rtype for the same
+// type are coalesced into a single Type.
+func toType(t *abi.Type) Type {
+ if t == nil {
+ return nil
+ }
+ return toRType(t)
+}
+
+type layoutKey struct {
+ ftyp *funcType // function signature
+ rcvr *abi.Type // receiver type, or nil if none
+}
+
+type layoutType struct {
+ t *abi.Type
+ framePool *sync.Pool
+ abid abiDesc
+}
+
+var layoutCache sync.Map // map[layoutKey]layoutType
+
+// funcLayout computes a struct type representing the layout of the
+// stack-assigned function arguments and return values for the function
+// type t.
+// If rcvr != nil, rcvr specifies the type of the receiver.
+// The returned type exists only for GC, so we only fill out GC relevant info.
+// Currently, that's just size and the GC program. We also fill in
+// the name for possible debugging use.
+func funcLayout(t *funcType, rcvr *abi.Type) (frametype *abi.Type, framePool *sync.Pool, abid abiDesc) {
+ if t.Kind() != abi.Func {
+ panic("reflect: funcLayout of non-func type " + stringFor(&t.Type))
+ }
+ if rcvr != nil && rcvr.Kind() == abi.Interface {
+ panic("reflect: funcLayout with interface receiver " + stringFor(rcvr))
+ }
+ k := layoutKey{t, rcvr}
+ if lti, ok := layoutCache.Load(k); ok {
+ lt := lti.(layoutType)
+ return lt.t, lt.framePool, lt.abid
+ }
+
+ // Compute the ABI layout.
+ abid = newAbiDesc(t, rcvr)
+
+ // build dummy rtype holding gc program
+ x := &abi.Type{
+ Align_: goarch.PtrSize,
+ // Don't add spill space here; it's only necessary in
+ // reflectcall's frame, not in the allocated frame.
+ // TODO(mknyszek): Remove this comment when register
+ // spill space in the frame is no longer required.
+ Size_: align(abid.retOffset+abid.ret.stackBytes, goarch.PtrSize),
+ PtrBytes: uintptr(abid.stackPtrs.n) * goarch.PtrSize,
+ }
+ if abid.stackPtrs.n > 0 {
+ x.GCData = &abid.stackPtrs.data[0]
+ }
+
+ var s string
+ if rcvr != nil {
+ s = "methodargs(" + stringFor(rcvr) + ")(" + stringFor(&t.Type) + ")"
+ } else {
+ s = "funcargs(" + stringFor(&t.Type) + ")"
+ }
+ x.Str = resolveReflectName(newName(s, "", false, false))
+
+ // cache result for future callers
+ framePool = &sync.Pool{New: func() any {
+ return unsafe_New(x)
+ }}
+ lti, _ := layoutCache.LoadOrStore(k, layoutType{
+ t: x,
+ framePool: framePool,
+ abid: abid,
+ })
+ lt := lti.(layoutType)
+ return lt.t, lt.framePool, lt.abid
+}
+
+// ifaceIndir reports whether t is stored indirectly in an interface value.
+func ifaceIndir(t *abi.Type) bool {
+ return t.Kind_&kindDirectIface == 0
+}
+
+// Note: this type must agree with runtime.bitvector.
+type bitVector struct {
+ n uint32 // number of bits
+ data []byte
+}
+
+// append a bit to the bitmap.
+func (bv *bitVector) append(bit uint8) {
+ if bv.n%(8*goarch.PtrSize) == 0 {
+ // Runtime needs pointer masks to be a multiple of uintptr in size.
+ // Since reflect passes bv.data directly to the runtime as a pointer mask,
+ // we append a full uintptr of zeros at a time.
+ for i := 0; i < goarch.PtrSize; i++ {
+ bv.data = append(bv.data, 0)
+ }
+ }
+ bv.data[bv.n/8] |= bit << (bv.n % 8)
+ bv.n++
+}
+
+func addTypeBits(bv *bitVector, offset uintptr, t *abi.Type) {
+ if t.PtrBytes == 0 {
+ return
+ }
+
+ switch Kind(t.Kind_ & kindMask) {
+ case Chan, Func, Map, Pointer, Slice, String, UnsafePointer:
+ // 1 pointer at start of representation
+ for bv.n < uint32(offset/uintptr(goarch.PtrSize)) {
+ bv.append(0)
+ }
+ bv.append(1)
+
+ case Interface:
+ // 2 pointers
+ for bv.n < uint32(offset/uintptr(goarch.PtrSize)) {
+ bv.append(0)
+ }
+ bv.append(1)
+ bv.append(1)
+
+ case Array:
+ // repeat inner type
+ tt := (*arrayType)(unsafe.Pointer(t))
+ for i := 0; i < int(tt.Len); i++ {
+ addTypeBits(bv, offset+uintptr(i)*tt.Elem.Size_, tt.Elem)
+ }
+
+ case Struct:
+ // apply fields
+ tt := (*structType)(unsafe.Pointer(t))
+ for i := range tt.Fields {
+ f := &tt.Fields[i]
+ addTypeBits(bv, offset+f.Offset, f.Typ)
+ }
+ }
+}
diff --git a/contrib/go/_std_1.21/src/reflect/value.go b/contrib/go/_std_1.21/src/reflect/value.go
new file mode 100644
index 0000000000..616da6a5c7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/reflect/value.go
@@ -0,0 +1,3962 @@
+// Copyright 2009 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 reflect
+
+import (
+ "errors"
+ "internal/abi"
+ "internal/goarch"
+ "internal/itoa"
+ "internal/unsafeheader"
+ "math"
+ "runtime"
+ "unsafe"
+)
+
+// Value is the reflection interface to a Go value.
+//
+// Not all methods apply to all kinds of values. Restrictions,
+// if any, are noted in the documentation for each method.
+// Use the Kind method to find out the kind of value before
+// calling kind-specific methods. Calling a method
+// inappropriate to the kind of type causes a run time panic.
+//
+// The zero Value represents no value.
+// Its IsValid method returns false, its Kind method returns Invalid,
+// its String method returns "<invalid Value>", and all other methods panic.
+// Most functions and methods never return an invalid value.
+// If one does, its documentation states the conditions explicitly.
+//
+// A Value can be used concurrently by multiple goroutines provided that
+// the underlying Go value can be used concurrently for the equivalent
+// direct operations.
+//
+// To compare two Values, compare the results of the Interface method.
+// Using == on two Values does not compare the underlying values
+// they represent.
+type Value struct {
+ // typ_ holds the type of the value represented by a Value.
+ // Access using the typ method to avoid escape of v.
+ typ_ *abi.Type
+
+ // Pointer-valued data or, if flagIndir is set, pointer to data.
+ // Valid when either flagIndir is set or typ.pointers() is true.
+ ptr unsafe.Pointer
+
+ // flag holds metadata about the value.
+ //
+ // The lowest five bits give the Kind of the value, mirroring typ.Kind().
+ //
+ // The next set of bits are flag bits:
+ // - flagStickyRO: obtained via unexported not embedded field, so read-only
+ // - flagEmbedRO: obtained via unexported embedded field, so read-only
+ // - flagIndir: val holds a pointer to the data
+ // - flagAddr: v.CanAddr is true (implies flagIndir and ptr is non-nil)
+ // - flagMethod: v is a method value.
+ // If ifaceIndir(typ), code can assume that flagIndir is set.
+ //
+ // The remaining 22+ bits give a method number for method values.
+ // If flag.kind() != Func, code can assume that flagMethod is unset.
+ flag
+
+ // A method value represents a curried method invocation
+ // like r.Read for some receiver r. The typ+val+flag bits describe
+ // the receiver r, but the flag's Kind bits say Func (methods are
+ // functions), and the top bits of the flag give the method number
+ // in r's type's method table.
+}
+
+type flag uintptr
+
+const (
+ flagKindWidth = 5 // there are 27 kinds
+ flagKindMask flag = 1<<flagKindWidth - 1
+ flagStickyRO flag = 1 << 5
+ flagEmbedRO flag = 1 << 6
+ flagIndir flag = 1 << 7
+ flagAddr flag = 1 << 8
+ flagMethod flag = 1 << 9
+ flagMethodShift = 10
+ flagRO flag = flagStickyRO | flagEmbedRO
+)
+
+func (f flag) kind() Kind {
+ return Kind(f & flagKindMask)
+}
+
+func (f flag) ro() flag {
+ if f&flagRO != 0 {
+ return flagStickyRO
+ }
+ return 0
+}
+
+func (v Value) typ() *abi.Type {
+ // Types are either static (for compiler-created types) or
+ // heap-allocated but always reachable (for reflection-created
+ // types, held in the central map). So there is no need to
+ // escape types. noescape here help avoid unnecessary escape
+ // of v.
+ return (*abi.Type)(noescape(unsafe.Pointer(v.typ_)))
+}
+
+// pointer returns the underlying pointer represented by v.
+// v.Kind() must be Pointer, Map, Chan, Func, or UnsafePointer
+// if v.Kind() == Pointer, the base type must not be not-in-heap.
+func (v Value) pointer() unsafe.Pointer {
+ if v.typ().Size() != goarch.PtrSize || !v.typ().Pointers() {
+ panic("can't call pointer on a non-pointer Value")
+ }
+ if v.flag&flagIndir != 0 {
+ return *(*unsafe.Pointer)(v.ptr)
+ }
+ return v.ptr
+}
+
+// packEface converts v to the empty interface.
+func packEface(v Value) any {
+ t := v.typ()
+ var i any
+ e := (*emptyInterface)(unsafe.Pointer(&i))
+ // First, fill in the data portion of the interface.
+ switch {
+ case t.IfaceIndir():
+ if v.flag&flagIndir == 0 {
+ panic("bad indir")
+ }
+ // Value is indirect, and so is the interface we're making.
+ ptr := v.ptr
+ if v.flag&flagAddr != 0 {
+ // TODO: pass safe boolean from valueInterface so
+ // we don't need to copy if safe==true?
+ c := unsafe_New(t)
+ typedmemmove(t, c, ptr)
+ ptr = c
+ }
+ e.word = ptr
+ case v.flag&flagIndir != 0:
+ // Value is indirect, but interface is direct. We need
+ // to load the data at v.ptr into the interface data word.
+ e.word = *(*unsafe.Pointer)(v.ptr)
+ default:
+ // Value is direct, and so is the interface.
+ e.word = v.ptr
+ }
+ // Now, fill in the type portion. We're very careful here not
+ // to have any operation between the e.word and e.typ assignments
+ // that would let the garbage collector observe the partially-built
+ // interface value.
+ e.typ = t
+ return i
+}
+
+// unpackEface converts the empty interface i to a Value.
+func unpackEface(i any) Value {
+ e := (*emptyInterface)(unsafe.Pointer(&i))
+ // NOTE: don't read e.word until we know whether it is really a pointer or not.
+ t := e.typ
+ if t == nil {
+ return Value{}
+ }
+ f := flag(t.Kind())
+ if t.IfaceIndir() {
+ f |= flagIndir
+ }
+ return Value{t, e.word, f}
+}
+
+// A ValueError occurs when a Value method is invoked on
+// a Value that does not support it. Such cases are documented
+// in the description of each method.
+type ValueError struct {
+ Method string
+ Kind Kind
+}
+
+func (e *ValueError) Error() string {
+ if e.Kind == 0 {
+ return "reflect: call of " + e.Method + " on zero Value"
+ }
+ return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
+}
+
+// valueMethodName returns the name of the exported calling method on Value.
+func valueMethodName() string {
+ var pc [5]uintptr
+ n := runtime.Callers(1, pc[:])
+ frames := runtime.CallersFrames(pc[:n])
+ var frame runtime.Frame
+ for more := true; more; {
+ const prefix = "reflect.Value."
+ frame, more = frames.Next()
+ name := frame.Function
+ if len(name) > len(prefix) && name[:len(prefix)] == prefix {
+ methodName := name[len(prefix):]
+ if len(methodName) > 0 && 'A' <= methodName[0] && methodName[0] <= 'Z' {
+ return name
+ }
+ }
+ }
+ return "unknown method"
+}
+
+// emptyInterface is the header for an interface{} value.
+type emptyInterface struct {
+ typ *abi.Type
+ word unsafe.Pointer
+}
+
+// nonEmptyInterface is the header for an interface value with methods.
+type nonEmptyInterface struct {
+ // see ../runtime/iface.go:/Itab
+ itab *struct {
+ ityp *abi.Type // static interface type
+ typ *abi.Type // dynamic concrete type
+ hash uint32 // copy of typ.hash
+ _ [4]byte
+ fun [100000]unsafe.Pointer // method table
+ }
+ word unsafe.Pointer
+}
+
+// mustBe panics if f's kind is not expected.
+// Making this a method on flag instead of on Value
+// (and embedding flag in Value) means that we can write
+// the very clear v.mustBe(Bool) and have it compile into
+// v.flag.mustBe(Bool), which will only bother to copy the
+// single important word for the receiver.
+func (f flag) mustBe(expected Kind) {
+ // TODO(mvdan): use f.kind() again once mid-stack inlining gets better
+ if Kind(f&flagKindMask) != expected {
+ panic(&ValueError{valueMethodName(), f.kind()})
+ }
+}
+
+// mustBeExported panics if f records that the value was obtained using
+// an unexported field.
+func (f flag) mustBeExported() {
+ if f == 0 || f&flagRO != 0 {
+ f.mustBeExportedSlow()
+ }
+}
+
+func (f flag) mustBeExportedSlow() {
+ if f == 0 {
+ panic(&ValueError{valueMethodName(), Invalid})
+ }
+ if f&flagRO != 0 {
+ panic("reflect: " + valueMethodName() + " using value obtained using unexported field")
+ }
+}
+
+// mustBeAssignable panics if f records that the value is not assignable,
+// which is to say that either it was obtained using an unexported field
+// or it is not addressable.
+func (f flag) mustBeAssignable() {
+ if f&flagRO != 0 || f&flagAddr == 0 {
+ f.mustBeAssignableSlow()
+ }
+}
+
+func (f flag) mustBeAssignableSlow() {
+ if f == 0 {
+ panic(&ValueError{valueMethodName(), Invalid})
+ }
+ // Assignable if addressable and not read-only.
+ if f&flagRO != 0 {
+ panic("reflect: " + valueMethodName() + " using value obtained using unexported field")
+ }
+ if f&flagAddr == 0 {
+ panic("reflect: " + valueMethodName() + " using unaddressable value")
+ }
+}
+
+// Addr returns a pointer value representing the address of v.
+// It panics if CanAddr() returns false.
+// Addr is typically used to obtain a pointer to a struct field
+// or slice element in order to call a method that requires a
+// pointer receiver.
+func (v Value) Addr() Value {
+ if v.flag&flagAddr == 0 {
+ panic("reflect.Value.Addr of unaddressable value")
+ }
+ // Preserve flagRO instead of using v.flag.ro() so that
+ // v.Addr().Elem() is equivalent to v (#32772)
+ fl := v.flag & flagRO
+ return Value{ptrTo(v.typ()), v.ptr, fl | flag(Pointer)}
+}
+
+// Bool returns v's underlying value.
+// It panics if v's kind is not Bool.
+func (v Value) Bool() bool {
+ // panicNotBool is split out to keep Bool inlineable.
+ if v.kind() != Bool {
+ v.panicNotBool()
+ }
+ return *(*bool)(v.ptr)
+}
+
+func (v Value) panicNotBool() {
+ v.mustBe(Bool)
+}
+
+var bytesType = rtypeOf(([]byte)(nil))
+
+// Bytes returns v's underlying value.
+// It panics if v's underlying value is not a slice of bytes or
+// an addressable array of bytes.
+func (v Value) Bytes() []byte {
+ // bytesSlow is split out to keep Bytes inlineable for unnamed []byte.
+ if v.typ_ == bytesType { // ok to use v.typ_ directly as comparison doesn't cause escape
+ return *(*[]byte)(v.ptr)
+ }
+ return v.bytesSlow()
+}
+
+func (v Value) bytesSlow() []byte {
+ switch v.kind() {
+ case Slice:
+ if v.typ().Elem().Kind() != abi.Uint8 {
+ panic("reflect.Value.Bytes of non-byte slice")
+ }
+ // Slice is always bigger than a word; assume flagIndir.
+ return *(*[]byte)(v.ptr)
+ case Array:
+ if v.typ().Elem().Kind() != abi.Uint8 {
+ panic("reflect.Value.Bytes of non-byte array")
+ }
+ if !v.CanAddr() {
+ panic("reflect.Value.Bytes of unaddressable byte array")
+ }
+ p := (*byte)(v.ptr)
+ n := int((*arrayType)(unsafe.Pointer(v.typ())).Len)
+ return unsafe.Slice(p, n)
+ }
+ panic(&ValueError{"reflect.Value.Bytes", v.kind()})
+}
+
+// runes returns v's underlying value.
+// It panics if v's underlying value is not a slice of runes (int32s).
+func (v Value) runes() []rune {
+ v.mustBe(Slice)
+ if v.typ().Elem().Kind() != abi.Int32 {
+ panic("reflect.Value.Bytes of non-rune slice")
+ }
+ // Slice is always bigger than a word; assume flagIndir.
+ return *(*[]rune)(v.ptr)
+}
+
+// CanAddr reports whether the value's address can be obtained with Addr.
+// Such values are called addressable. A value is addressable if it is
+// an element of a slice, an element of an addressable array,
+// a field of an addressable struct, or the result of dereferencing a pointer.
+// If CanAddr returns false, calling Addr will panic.
+func (v Value) CanAddr() bool {
+ return v.flag&flagAddr != 0
+}
+
+// CanSet reports whether the value of v can be changed.
+// A Value can be changed only if it is addressable and was not
+// obtained by the use of unexported struct fields.
+// If CanSet returns false, calling Set or any type-specific
+// setter (e.g., SetBool, SetInt) will panic.
+func (v Value) CanSet() bool {
+ return v.flag&(flagAddr|flagRO) == flagAddr
+}
+
+// Call calls the function v with the input arguments in.
+// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]).
+// Call panics if v's Kind is not Func.
+// It returns the output results as Values.
+// As in Go, each input argument must be assignable to the
+// type of the function's corresponding input parameter.
+// If v is a variadic function, Call creates the variadic slice parameter
+// itself, copying in the corresponding values.
+func (v Value) Call(in []Value) []Value {
+ v.mustBe(Func)
+ v.mustBeExported()
+ return v.call("Call", in)
+}
+
+// CallSlice calls the variadic function v with the input arguments in,
+// assigning the slice in[len(in)-1] to v's final variadic argument.
+// For example, if len(in) == 3, v.CallSlice(in) represents the Go call v(in[0], in[1], in[2]...).
+// CallSlice panics if v's Kind is not Func or if v is not variadic.
+// It returns the output results as Values.
+// As in Go, each input argument must be assignable to the
+// type of the function's corresponding input parameter.
+func (v Value) CallSlice(in []Value) []Value {
+ v.mustBe(Func)
+ v.mustBeExported()
+ return v.call("CallSlice", in)
+}
+
+var callGC bool // for testing; see TestCallMethodJump and TestCallArgLive
+
+const debugReflectCall = false
+
+func (v Value) call(op string, in []Value) []Value {
+ // Get function pointer, type.
+ t := (*funcType)(unsafe.Pointer(v.typ()))
+ var (
+ fn unsafe.Pointer
+ rcvr Value
+ rcvrtype *abi.Type
+ )
+ if v.flag&flagMethod != 0 {
+ rcvr = v
+ rcvrtype, t, fn = methodReceiver(op, v, int(v.flag)>>flagMethodShift)
+ } else if v.flag&flagIndir != 0 {
+ fn = *(*unsafe.Pointer)(v.ptr)
+ } else {
+ fn = v.ptr
+ }
+
+ if fn == nil {
+ panic("reflect.Value.Call: call of nil function")
+ }
+
+ isSlice := op == "CallSlice"
+ n := t.NumIn()
+ isVariadic := t.IsVariadic()
+ if isSlice {
+ if !isVariadic {
+ panic("reflect: CallSlice of non-variadic function")
+ }
+ if len(in) < n {
+ panic("reflect: CallSlice with too few input arguments")
+ }
+ if len(in) > n {
+ panic("reflect: CallSlice with too many input arguments")
+ }
+ } else {
+ if isVariadic {
+ n--
+ }
+ if len(in) < n {
+ panic("reflect: Call with too few input arguments")
+ }
+ if !isVariadic && len(in) > n {
+ panic("reflect: Call with too many input arguments")
+ }
+ }
+ for _, x := range in {
+ if x.Kind() == Invalid {
+ panic("reflect: " + op + " using zero Value argument")
+ }
+ }
+ for i := 0; i < n; i++ {
+ if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(toRType(targ)) {
+ panic("reflect: " + op + " using " + xt.String() + " as type " + stringFor(targ))
+ }
+ }
+ if !isSlice && isVariadic {
+ // prepare slice for remaining values
+ m := len(in) - n
+ slice := MakeSlice(toRType(t.In(n)), m, m)
+ elem := toRType(t.In(n)).Elem() // FIXME cast to slice type and Elem()
+ for i := 0; i < m; i++ {
+ x := in[n+i]
+ if xt := x.Type(); !xt.AssignableTo(elem) {
+ panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + op)
+ }
+ slice.Index(i).Set(x)
+ }
+ origIn := in
+ in = make([]Value, n+1)
+ copy(in[:n], origIn)
+ in[n] = slice
+ }
+
+ nin := len(in)
+ if nin != t.NumIn() {
+ panic("reflect.Value.Call: wrong argument count")
+ }
+ nout := t.NumOut()
+
+ // Register argument space.
+ var regArgs abi.RegArgs
+
+ // Compute frame type.
+ frametype, framePool, abid := funcLayout(t, rcvrtype)
+
+ // Allocate a chunk of memory for frame if needed.
+ var stackArgs unsafe.Pointer
+ if frametype.Size() != 0 {
+ if nout == 0 {
+ stackArgs = framePool.Get().(unsafe.Pointer)
+ } else {
+ // Can't use pool if the function has return values.
+ // We will leak pointer to args in ret, so its lifetime is not scoped.
+ stackArgs = unsafe_New(frametype)
+ }
+ }
+ frameSize := frametype.Size()
+
+ if debugReflectCall {
+ println("reflect.call", stringFor(&t.Type))
+ abid.dump()
+ }
+
+ // Copy inputs into args.
+
+ // Handle receiver.
+ inStart := 0
+ if rcvrtype != nil {
+ // Guaranteed to only be one word in size,
+ // so it will only take up exactly 1 abiStep (either
+ // in a register or on the stack).
+ switch st := abid.call.steps[0]; st.kind {
+ case abiStepStack:
+ storeRcvr(rcvr, stackArgs)
+ case abiStepPointer:
+ storeRcvr(rcvr, unsafe.Pointer(&regArgs.Ptrs[st.ireg]))
+ fallthrough
+ case abiStepIntReg:
+ storeRcvr(rcvr, unsafe.Pointer(&regArgs.Ints[st.ireg]))
+ case abiStepFloatReg:
+ storeRcvr(rcvr, unsafe.Pointer(&regArgs.Floats[st.freg]))
+ default:
+ panic("unknown ABI parameter kind")
+ }
+ inStart = 1
+ }
+
+ // Handle arguments.
+ for i, v := range in {
+ v.mustBeExported()
+ targ := toRType(t.In(i))
+ // TODO(mknyszek): Figure out if it's possible to get some
+ // scratch space for this assignment check. Previously, it
+ // was possible to use space in the argument frame.
+ v = v.assignTo("reflect.Value.Call", &targ.t, nil)
+ stepsLoop:
+ for _, st := range abid.call.stepsForValue(i + inStart) {
+ switch st.kind {
+ case abiStepStack:
+ // Copy values to the "stack."
+ addr := add(stackArgs, st.stkOff, "precomputed stack arg offset")
+ if v.flag&flagIndir != 0 {
+ typedmemmove(&targ.t, addr, v.ptr)
+ } else {
+ *(*unsafe.Pointer)(addr) = v.ptr
+ }
+ // There's only one step for a stack-allocated value.
+ break stepsLoop
+ case abiStepIntReg, abiStepPointer:
+ // Copy values to "integer registers."
+ if v.flag&flagIndir != 0 {
+ offset := add(v.ptr, st.offset, "precomputed value offset")
+ if st.kind == abiStepPointer {
+ // Duplicate this pointer in the pointer area of the
+ // register space. Otherwise, there's the potential for
+ // this to be the last reference to v.ptr.
+ regArgs.Ptrs[st.ireg] = *(*unsafe.Pointer)(offset)
+ }
+ intToReg(&regArgs, st.ireg, st.size, offset)
+ } else {
+ if st.kind == abiStepPointer {
+ // See the comment in abiStepPointer case above.
+ regArgs.Ptrs[st.ireg] = v.ptr
+ }
+ regArgs.Ints[st.ireg] = uintptr(v.ptr)
+ }
+ case abiStepFloatReg:
+ // Copy values to "float registers."
+ if v.flag&flagIndir == 0 {
+ panic("attempted to copy pointer to FP register")
+ }
+ offset := add(v.ptr, st.offset, "precomputed value offset")
+ floatToReg(&regArgs, st.freg, st.size, offset)
+ default:
+ panic("unknown ABI part kind")
+ }
+ }
+ }
+ // TODO(mknyszek): Remove this when we no longer have
+ // caller reserved spill space.
+ frameSize = align(frameSize, goarch.PtrSize)
+ frameSize += abid.spill
+
+ // Mark pointers in registers for the return path.
+ regArgs.ReturnIsPtr = abid.outRegPtrs
+
+ if debugReflectCall {
+ regArgs.Dump()
+ }
+
+ // For testing; see TestCallArgLive.
+ if callGC {
+ runtime.GC()
+ }
+
+ // Call.
+ call(frametype, fn, stackArgs, uint32(frametype.Size()), uint32(abid.retOffset), uint32(frameSize), &regArgs)
+
+ // For testing; see TestCallMethodJump.
+ if callGC {
+ runtime.GC()
+ }
+
+ var ret []Value
+ if nout == 0 {
+ if stackArgs != nil {
+ typedmemclr(frametype, stackArgs)
+ framePool.Put(stackArgs)
+ }
+ } else {
+ if stackArgs != nil {
+ // Zero the now unused input area of args,
+ // because the Values returned by this function contain pointers to the args object,
+ // and will thus keep the args object alive indefinitely.
+ typedmemclrpartial(frametype, stackArgs, 0, abid.retOffset)
+ }
+
+ // Wrap Values around return values in args.
+ ret = make([]Value, nout)
+ for i := 0; i < nout; i++ {
+ tv := t.Out(i)
+ if tv.Size() == 0 {
+ // For zero-sized return value, args+off may point to the next object.
+ // In this case, return the zero value instead.
+ ret[i] = Zero(toRType(tv))
+ continue
+ }
+ steps := abid.ret.stepsForValue(i)
+ if st := steps[0]; st.kind == abiStepStack {
+ // This value is on the stack. If part of a value is stack
+ // allocated, the entire value is according to the ABI. So
+ // just make an indirection into the allocated frame.
+ fl := flagIndir | flag(tv.Kind())
+ ret[i] = Value{tv, add(stackArgs, st.stkOff, "tv.Size() != 0"), fl}
+ // Note: this does introduce false sharing between results -
+ // if any result is live, they are all live.
+ // (And the space for the args is live as well, but as we've
+ // cleared that space it isn't as big a deal.)
+ continue
+ }
+
+ // Handle pointers passed in registers.
+ if !ifaceIndir(tv) {
+ // Pointer-valued data gets put directly
+ // into v.ptr.
+ if steps[0].kind != abiStepPointer {
+ print("kind=", steps[0].kind, ", type=", stringFor(tv), "\n")
+ panic("mismatch between ABI description and types")
+ }
+ ret[i] = Value{tv, regArgs.Ptrs[steps[0].ireg], flag(tv.Kind())}
+ continue
+ }
+
+ // All that's left is values passed in registers that we need to
+ // create space for and copy values back into.
+ //
+ // TODO(mknyszek): We make a new allocation for each register-allocated
+ // value, but previously we could always point into the heap-allocated
+ // stack frame. This is a regression that could be fixed by adding
+ // additional space to the allocated stack frame and storing the
+ // register-allocated return values into the allocated stack frame and
+ // referring there in the resulting Value.
+ s := unsafe_New(tv)
+ for _, st := range steps {
+ switch st.kind {
+ case abiStepIntReg:
+ offset := add(s, st.offset, "precomputed value offset")
+ intFromReg(&regArgs, st.ireg, st.size, offset)
+ case abiStepPointer:
+ s := add(s, st.offset, "precomputed value offset")
+ *((*unsafe.Pointer)(s)) = regArgs.Ptrs[st.ireg]
+ case abiStepFloatReg:
+ offset := add(s, st.offset, "precomputed value offset")
+ floatFromReg(&regArgs, st.freg, st.size, offset)
+ case abiStepStack:
+ panic("register-based return value has stack component")
+ default:
+ panic("unknown ABI part kind")
+ }
+ }
+ ret[i] = Value{tv, s, flagIndir | flag(tv.Kind())}
+ }
+ }
+
+ return ret
+}
+
+// callReflect is the call implementation used by a function
+// returned by MakeFunc. In many ways it is the opposite of the
+// method Value.call above. The method above converts a call using Values
+// into a call of a function with a concrete argument frame, while
+// callReflect converts a call of a function with a concrete argument
+// frame into a call using Values.
+// It is in this file so that it can be next to the call method above.
+// The remainder of the MakeFunc implementation is in makefunc.go.
+//
+// NOTE: This function must be marked as a "wrapper" in the generated code,
+// so that the linker can make it work correctly for panic and recover.
+// The gc compilers know to do that for the name "reflect.callReflect".
+//
+// ctxt is the "closure" generated by MakeFunc.
+// frame is a pointer to the arguments to that closure on the stack.
+// retValid points to a boolean which should be set when the results
+// section of frame is set.
+//
+// regs contains the argument values passed in registers and will contain
+// the values returned from ctxt.fn in registers.
+func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer, retValid *bool, regs *abi.RegArgs) {
+ if callGC {
+ // Call GC upon entry during testing.
+ // Getting our stack scanned here is the biggest hazard, because
+ // our caller (makeFuncStub) could have failed to place the last
+ // pointer to a value in regs' pointer space, in which case it
+ // won't be visible to the GC.
+ runtime.GC()
+ }
+ ftyp := ctxt.ftyp
+ f := ctxt.fn
+
+ _, _, abid := funcLayout(ftyp, nil)
+
+ // Copy arguments into Values.
+ ptr := frame
+ in := make([]Value, 0, int(ftyp.InCount))
+ for i, typ := range ftyp.InSlice() {
+ if typ.Size() == 0 {
+ in = append(in, Zero(toRType(typ)))
+ continue
+ }
+ v := Value{typ, nil, flag(typ.Kind())}
+ steps := abid.call.stepsForValue(i)
+ if st := steps[0]; st.kind == abiStepStack {
+ if ifaceIndir(typ) {
+ // value cannot be inlined in interface data.
+ // Must make a copy, because f might keep a reference to it,
+ // and we cannot let f keep a reference to the stack frame
+ // after this function returns, not even a read-only reference.
+ v.ptr = unsafe_New(typ)
+ if typ.Size() > 0 {
+ typedmemmove(typ, v.ptr, add(ptr, st.stkOff, "typ.size > 0"))
+ }
+ v.flag |= flagIndir
+ } else {
+ v.ptr = *(*unsafe.Pointer)(add(ptr, st.stkOff, "1-ptr"))
+ }
+ } else {
+ if ifaceIndir(typ) {
+ // All that's left is values passed in registers that we need to
+ // create space for the values.
+ v.flag |= flagIndir
+ v.ptr = unsafe_New(typ)
+ for _, st := range steps {
+ switch st.kind {
+ case abiStepIntReg:
+ offset := add(v.ptr, st.offset, "precomputed value offset")
+ intFromReg(regs, st.ireg, st.size, offset)
+ case abiStepPointer:
+ s := add(v.ptr, st.offset, "precomputed value offset")
+ *((*unsafe.Pointer)(s)) = regs.Ptrs[st.ireg]
+ case abiStepFloatReg:
+ offset := add(v.ptr, st.offset, "precomputed value offset")
+ floatFromReg(regs, st.freg, st.size, offset)
+ case abiStepStack:
+ panic("register-based return value has stack component")
+ default:
+ panic("unknown ABI part kind")
+ }
+ }
+ } else {
+ // Pointer-valued data gets put directly
+ // into v.ptr.
+ if steps[0].kind != abiStepPointer {
+ print("kind=", steps[0].kind, ", type=", stringFor(typ), "\n")
+ panic("mismatch between ABI description and types")
+ }
+ v.ptr = regs.Ptrs[steps[0].ireg]
+ }
+ }
+ in = append(in, v)
+ }
+
+ // Call underlying function.
+ out := f(in)
+ numOut := ftyp.NumOut()
+ if len(out) != numOut {
+ panic("reflect: wrong return count from function created by MakeFunc")
+ }
+
+ // Copy results back into argument frame and register space.
+ if numOut > 0 {
+ for i, typ := range ftyp.OutSlice() {
+ v := out[i]
+ if v.typ() == nil {
+ panic("reflect: function created by MakeFunc using " + funcName(f) +
+ " returned zero Value")
+ }
+ if v.flag&flagRO != 0 {
+ panic("reflect: function created by MakeFunc using " + funcName(f) +
+ " returned value obtained from unexported field")
+ }
+ if typ.Size() == 0 {
+ continue
+ }
+
+ // Convert v to type typ if v is assignable to a variable
+ // of type t in the language spec.
+ // See issue 28761.
+ //
+ //
+ // TODO(mknyszek): In the switch to the register ABI we lost
+ // the scratch space here for the register cases (and
+ // temporarily for all the cases).
+ //
+ // If/when this happens, take note of the following:
+ //
+ // We must clear the destination before calling assignTo,
+ // in case assignTo writes (with memory barriers) to the
+ // target location used as scratch space. See issue 39541.
+ v = v.assignTo("reflect.MakeFunc", typ, nil)
+ stepsLoop:
+ for _, st := range abid.ret.stepsForValue(i) {
+ switch st.kind {
+ case abiStepStack:
+ // Copy values to the "stack."
+ addr := add(ptr, st.stkOff, "precomputed stack arg offset")
+ // Do not use write barriers. The stack space used
+ // for this call is not adequately zeroed, and we
+ // are careful to keep the arguments alive until we
+ // return to makeFuncStub's caller.
+ if v.flag&flagIndir != 0 {
+ memmove(addr, v.ptr, st.size)
+ } else {
+ // This case must be a pointer type.
+ *(*uintptr)(addr) = uintptr(v.ptr)
+ }
+ // There's only one step for a stack-allocated value.
+ break stepsLoop
+ case abiStepIntReg, abiStepPointer:
+ // Copy values to "integer registers."
+ if v.flag&flagIndir != 0 {
+ offset := add(v.ptr, st.offset, "precomputed value offset")
+ intToReg(regs, st.ireg, st.size, offset)
+ } else {
+ // Only populate the Ints space on the return path.
+ // This is safe because out is kept alive until the
+ // end of this function, and the return path through
+ // makeFuncStub has no preemption, so these pointers
+ // are always visible to the GC.
+ regs.Ints[st.ireg] = uintptr(v.ptr)
+ }
+ case abiStepFloatReg:
+ // Copy values to "float registers."
+ if v.flag&flagIndir == 0 {
+ panic("attempted to copy pointer to FP register")
+ }
+ offset := add(v.ptr, st.offset, "precomputed value offset")
+ floatToReg(regs, st.freg, st.size, offset)
+ default:
+ panic("unknown ABI part kind")
+ }
+ }
+ }
+ }
+
+ // Announce that the return values are valid.
+ // After this point the runtime can depend on the return values being valid.
+ *retValid = true
+
+ // We have to make sure that the out slice lives at least until
+ // the runtime knows the return values are valid. Otherwise, the
+ // return values might not be scanned by anyone during a GC.
+ // (out would be dead, and the return slots not yet alive.)
+ runtime.KeepAlive(out)
+
+ // runtime.getArgInfo expects to be able to find ctxt on the
+ // stack when it finds our caller, makeFuncStub. Make sure it
+ // doesn't get garbage collected.
+ runtime.KeepAlive(ctxt)
+}
+
+// methodReceiver returns information about the receiver
+// described by v. The Value v may or may not have the
+// flagMethod bit set, so the kind cached in v.flag should
+// not be used.
+// The return value rcvrtype gives the method's actual receiver type.
+// The return value t gives the method type signature (without the receiver).
+// The return value fn is a pointer to the method code.
+func methodReceiver(op string, v Value, methodIndex int) (rcvrtype *abi.Type, t *funcType, fn unsafe.Pointer) {
+ i := methodIndex
+ if v.typ().Kind() == abi.Interface {
+ tt := (*interfaceType)(unsafe.Pointer(v.typ()))
+ if uint(i) >= uint(len(tt.Methods)) {
+ panic("reflect: internal error: invalid method index")
+ }
+ m := &tt.Methods[i]
+ if !tt.nameOff(m.Name).IsExported() {
+ panic("reflect: " + op + " of unexported method")
+ }
+ iface := (*nonEmptyInterface)(v.ptr)
+ if iface.itab == nil {
+ panic("reflect: " + op + " of method on nil interface value")
+ }
+ rcvrtype = iface.itab.typ
+ fn = unsafe.Pointer(&iface.itab.fun[i])
+ t = (*funcType)(unsafe.Pointer(tt.typeOff(m.Typ)))
+ } else {
+ rcvrtype = v.typ()
+ ms := v.typ().ExportedMethods()
+ if uint(i) >= uint(len(ms)) {
+ panic("reflect: internal error: invalid method index")
+ }
+ m := ms[i]
+ if !nameOffFor(v.typ(), m.Name).IsExported() {
+ panic("reflect: " + op + " of unexported method")
+ }
+ ifn := textOffFor(v.typ(), m.Ifn)
+ fn = unsafe.Pointer(&ifn)
+ t = (*funcType)(unsafe.Pointer(typeOffFor(v.typ(), m.Mtyp)))
+ }
+ return
+}
+
+// v is a method receiver. Store at p the word which is used to
+// encode that receiver at the start of the argument list.
+// Reflect uses the "interface" calling convention for
+// methods, which always uses one word to record the receiver.
+func storeRcvr(v Value, p unsafe.Pointer) {
+ t := v.typ()
+ if t.Kind() == abi.Interface {
+ // the interface data word becomes the receiver word
+ iface := (*nonEmptyInterface)(v.ptr)
+ *(*unsafe.Pointer)(p) = iface.word
+ } else if v.flag&flagIndir != 0 && !ifaceIndir(t) {
+ *(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
+ } else {
+ *(*unsafe.Pointer)(p) = v.ptr
+ }
+}
+
+// align returns the result of rounding x up to a multiple of n.
+// n must be a power of two.
+func align(x, n uintptr) uintptr {
+ return (x + n - 1) &^ (n - 1)
+}
+
+// callMethod is the call implementation used by a function returned
+// by makeMethodValue (used by v.Method(i).Interface()).
+// It is a streamlined version of the usual reflect call: the caller has
+// already laid out the argument frame for us, so we don't have
+// to deal with individual Values for each argument.
+// It is in this file so that it can be next to the two similar functions above.
+// The remainder of the makeMethodValue implementation is in makefunc.go.
+//
+// NOTE: This function must be marked as a "wrapper" in the generated code,
+// so that the linker can make it work correctly for panic and recover.
+// The gc compilers know to do that for the name "reflect.callMethod".
+//
+// ctxt is the "closure" generated by makeVethodValue.
+// frame is a pointer to the arguments to that closure on the stack.
+// retValid points to a boolean which should be set when the results
+// section of frame is set.
+//
+// regs contains the argument values passed in registers and will contain
+// the values returned from ctxt.fn in registers.
+func callMethod(ctxt *methodValue, frame unsafe.Pointer, retValid *bool, regs *abi.RegArgs) {
+ rcvr := ctxt.rcvr
+ rcvrType, valueFuncType, methodFn := methodReceiver("call", rcvr, ctxt.method)
+
+ // There are two ABIs at play here.
+ //
+ // methodValueCall was invoked with the ABI assuming there was no
+ // receiver ("value ABI") and that's what frame and regs are holding.
+ //
+ // Meanwhile, we need to actually call the method with a receiver, which
+ // has its own ABI ("method ABI"). Everything that follows is a translation
+ // between the two.
+ _, _, valueABI := funcLayout(valueFuncType, nil)
+ valueFrame, valueRegs := frame, regs
+ methodFrameType, methodFramePool, methodABI := funcLayout(valueFuncType, rcvrType)
+
+ // Make a new frame that is one word bigger so we can store the receiver.
+ // This space is used for both arguments and return values.
+ methodFrame := methodFramePool.Get().(unsafe.Pointer)
+ var methodRegs abi.RegArgs
+
+ // Deal with the receiver. It's guaranteed to only be one word in size.
+ switch st := methodABI.call.steps[0]; st.kind {
+ case abiStepStack:
+ // Only copy the receiver to the stack if the ABI says so.
+ // Otherwise, it'll be in a register already.
+ storeRcvr(rcvr, methodFrame)
+ case abiStepPointer:
+ // Put the receiver in a register.
+ storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ptrs[st.ireg]))
+ fallthrough
+ case abiStepIntReg:
+ storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Ints[st.ireg]))
+ case abiStepFloatReg:
+ storeRcvr(rcvr, unsafe.Pointer(&methodRegs.Floats[st.freg]))
+ default:
+ panic("unknown ABI parameter kind")
+ }
+
+ // Translate the rest of the arguments.
+ for i, t := range valueFuncType.InSlice() {
+ valueSteps := valueABI.call.stepsForValue(i)
+ methodSteps := methodABI.call.stepsForValue(i + 1)
+
+ // Zero-sized types are trivial: nothing to do.
+ if len(valueSteps) == 0 {
+ if len(methodSteps) != 0 {
+ panic("method ABI and value ABI do not align")
+ }
+ continue
+ }
+
+ // There are four cases to handle in translating each
+ // argument:
+ // 1. Stack -> stack translation.
+ // 2. Stack -> registers translation.
+ // 3. Registers -> stack translation.
+ // 4. Registers -> registers translation.
+
+ // If the value ABI passes the value on the stack,
+ // then the method ABI does too, because it has strictly
+ // fewer arguments. Simply copy between the two.
+ if vStep := valueSteps[0]; vStep.kind == abiStepStack {
+ mStep := methodSteps[0]
+ // Handle stack -> stack translation.
+ if mStep.kind == abiStepStack {
+ if vStep.size != mStep.size {
+ panic("method ABI and value ABI do not align")
+ }
+ typedmemmove(t,
+ add(methodFrame, mStep.stkOff, "precomputed stack offset"),
+ add(valueFrame, vStep.stkOff, "precomputed stack offset"))
+ continue
+ }
+ // Handle stack -> register translation.
+ for _, mStep := range methodSteps {
+ from := add(valueFrame, vStep.stkOff+mStep.offset, "precomputed stack offset")
+ switch mStep.kind {
+ case abiStepPointer:
+ // Do the pointer copy directly so we get a write barrier.
+ methodRegs.Ptrs[mStep.ireg] = *(*unsafe.Pointer)(from)
+ fallthrough // We need to make sure this ends up in Ints, too.
+ case abiStepIntReg:
+ intToReg(&methodRegs, mStep.ireg, mStep.size, from)
+ case abiStepFloatReg:
+ floatToReg(&methodRegs, mStep.freg, mStep.size, from)
+ default:
+ panic("unexpected method step")
+ }
+ }
+ continue
+ }
+ // Handle register -> stack translation.
+ if mStep := methodSteps[0]; mStep.kind == abiStepStack {
+ for _, vStep := range valueSteps {
+ to := add(methodFrame, mStep.stkOff+vStep.offset, "precomputed stack offset")
+ switch vStep.kind {
+ case abiStepPointer:
+ // Do the pointer copy directly so we get a write barrier.
+ *(*unsafe.Pointer)(to) = valueRegs.Ptrs[vStep.ireg]
+ case abiStepIntReg:
+ intFromReg(valueRegs, vStep.ireg, vStep.size, to)
+ case abiStepFloatReg:
+ floatFromReg(valueRegs, vStep.freg, vStep.size, to)
+ default:
+ panic("unexpected value step")
+ }
+ }
+ continue
+ }
+ // Handle register -> register translation.
+ if len(valueSteps) != len(methodSteps) {
+ // Because it's the same type for the value, and it's assigned
+ // to registers both times, it should always take up the same
+ // number of registers for each ABI.
+ panic("method ABI and value ABI don't align")
+ }
+ for i, vStep := range valueSteps {
+ mStep := methodSteps[i]
+ if mStep.kind != vStep.kind {
+ panic("method ABI and value ABI don't align")
+ }
+ switch vStep.kind {
+ case abiStepPointer:
+ // Copy this too, so we get a write barrier.
+ methodRegs.Ptrs[mStep.ireg] = valueRegs.Ptrs[vStep.ireg]
+ fallthrough
+ case abiStepIntReg:
+ methodRegs.Ints[mStep.ireg] = valueRegs.Ints[vStep.ireg]
+ case abiStepFloatReg:
+ methodRegs.Floats[mStep.freg] = valueRegs.Floats[vStep.freg]
+ default:
+ panic("unexpected value step")
+ }
+ }
+ }
+
+ methodFrameSize := methodFrameType.Size()
+ // TODO(mknyszek): Remove this when we no longer have
+ // caller reserved spill space.
+ methodFrameSize = align(methodFrameSize, goarch.PtrSize)
+ methodFrameSize += methodABI.spill
+
+ // Mark pointers in registers for the return path.
+ methodRegs.ReturnIsPtr = methodABI.outRegPtrs
+
+ // Call.
+ // Call copies the arguments from scratch to the stack, calls fn,
+ // and then copies the results back into scratch.
+ call(methodFrameType, methodFn, methodFrame, uint32(methodFrameType.Size()), uint32(methodABI.retOffset), uint32(methodFrameSize), &methodRegs)
+
+ // Copy return values.
+ //
+ // This is somewhat simpler because both ABIs have an identical
+ // return value ABI (the types are identical). As a result, register
+ // results can simply be copied over. Stack-allocated values are laid
+ // out the same, but are at different offsets from the start of the frame
+ // Ignore any changes to args.
+ // Avoid constructing out-of-bounds pointers if there are no return values.
+ // because the arguments may be laid out differently.
+ if valueRegs != nil {
+ *valueRegs = methodRegs
+ }
+ if retSize := methodFrameType.Size() - methodABI.retOffset; retSize > 0 {
+ valueRet := add(valueFrame, valueABI.retOffset, "valueFrame's size > retOffset")
+ methodRet := add(methodFrame, methodABI.retOffset, "methodFrame's size > retOffset")
+ // This copies to the stack. Write barriers are not needed.
+ memmove(valueRet, methodRet, retSize)
+ }
+
+ // Tell the runtime it can now depend on the return values
+ // being properly initialized.
+ *retValid = true
+
+ // Clear the scratch space and put it back in the pool.
+ // This must happen after the statement above, so that the return
+ // values will always be scanned by someone.
+ typedmemclr(methodFrameType, methodFrame)
+ methodFramePool.Put(methodFrame)
+
+ // See the comment in callReflect.
+ runtime.KeepAlive(ctxt)
+
+ // Keep valueRegs alive because it may hold live pointer results.
+ // The caller (methodValueCall) has it as a stack object, which is only
+ // scanned when there is a reference to it.
+ runtime.KeepAlive(valueRegs)
+}
+
+// funcName returns the name of f, for use in error messages.
+func funcName(f func([]Value) []Value) string {
+ pc := *(*uintptr)(unsafe.Pointer(&f))
+ rf := runtime.FuncForPC(pc)
+ if rf != nil {
+ return rf.Name()
+ }
+ return "closure"
+}
+
+// Cap returns v's capacity.
+// It panics if v's Kind is not Array, Chan, Slice or pointer to Array.
+func (v Value) Cap() int {
+ // capNonSlice is split out to keep Cap inlineable for slice kinds.
+ if v.kind() == Slice {
+ return (*unsafeheader.Slice)(v.ptr).Cap
+ }
+ return v.capNonSlice()
+}
+
+func (v Value) capNonSlice() int {
+ k := v.kind()
+ switch k {
+ case Array:
+ return v.typ().Len()
+ case Chan:
+ return chancap(v.pointer())
+ case Ptr:
+ if v.typ().Elem().Kind() == abi.Array {
+ return v.typ().Elem().Len()
+ }
+ panic("reflect: call of reflect.Value.Cap on ptr to non-array Value")
+ }
+ panic(&ValueError{"reflect.Value.Cap", v.kind()})
+}
+
+// Close closes the channel v.
+// It panics if v's Kind is not Chan.
+func (v Value) Close() {
+ v.mustBe(Chan)
+ v.mustBeExported()
+ chanclose(v.pointer())
+}
+
+// CanComplex reports whether Complex can be used without panicking.
+func (v Value) CanComplex() bool {
+ switch v.kind() {
+ case Complex64, Complex128:
+ return true
+ default:
+ return false
+ }
+}
+
+// Complex returns v's underlying value, as a complex128.
+// It panics if v's Kind is not Complex64 or Complex128
+func (v Value) Complex() complex128 {
+ k := v.kind()
+ switch k {
+ case Complex64:
+ return complex128(*(*complex64)(v.ptr))
+ case Complex128:
+ return *(*complex128)(v.ptr)
+ }
+ panic(&ValueError{"reflect.Value.Complex", v.kind()})
+}
+
+// Elem returns the value that the interface v contains
+// or that the pointer v points to.
+// It panics if v's Kind is not Interface or Pointer.
+// It returns the zero Value if v is nil.
+func (v Value) Elem() Value {
+ k := v.kind()
+ switch k {
+ case Interface:
+ var eface any
+ if v.typ().NumMethod() == 0 {
+ eface = *(*any)(v.ptr)
+ } else {
+ eface = (any)(*(*interface {
+ M()
+ })(v.ptr))
+ }
+ x := unpackEface(eface)
+ if x.flag != 0 {
+ x.flag |= v.flag.ro()
+ }
+ return x
+ case Pointer:
+ ptr := v.ptr
+ if v.flag&flagIndir != 0 {
+ if ifaceIndir(v.typ()) {
+ // This is a pointer to a not-in-heap object. ptr points to a uintptr
+ // in the heap. That uintptr is the address of a not-in-heap object.
+ // In general, pointers to not-in-heap objects can be total junk.
+ // But Elem() is asking to dereference it, so the user has asserted
+ // that at least it is a valid pointer (not just an integer stored in
+ // a pointer slot). So let's check, to make sure that it isn't a pointer
+ // that the runtime will crash on if it sees it during GC or write barriers.
+ // Since it is a not-in-heap pointer, all pointers to the heap are
+ // forbidden! That makes the test pretty easy.
+ // See issue 48399.
+ if !verifyNotInHeapPtr(*(*uintptr)(ptr)) {
+ panic("reflect: reflect.Value.Elem on an invalid notinheap pointer")
+ }
+ }
+ ptr = *(*unsafe.Pointer)(ptr)
+ }
+ // The returned value's address is v's value.
+ if ptr == nil {
+ return Value{}
+ }
+ tt := (*ptrType)(unsafe.Pointer(v.typ()))
+ typ := tt.Elem
+ fl := v.flag&flagRO | flagIndir | flagAddr
+ fl |= flag(typ.Kind())
+ return Value{typ, ptr, fl}
+ }
+ panic(&ValueError{"reflect.Value.Elem", v.kind()})
+}
+
+// Field returns the i'th field of the struct v.
+// It panics if v's Kind is not Struct or i is out of range.
+func (v Value) Field(i int) Value {
+ if v.kind() != Struct {
+ panic(&ValueError{"reflect.Value.Field", v.kind()})
+ }
+ tt := (*structType)(unsafe.Pointer(v.typ()))
+ if uint(i) >= uint(len(tt.Fields)) {
+ panic("reflect: Field index out of range")
+ }
+ field := &tt.Fields[i]
+ typ := field.Typ
+
+ // Inherit permission bits from v, but clear flagEmbedRO.
+ fl := v.flag&(flagStickyRO|flagIndir|flagAddr) | flag(typ.Kind())
+ // Using an unexported field forces flagRO.
+ if !field.Name.IsExported() {
+ if field.Embedded() {
+ fl |= flagEmbedRO
+ } else {
+ fl |= flagStickyRO
+ }
+ }
+ // Either flagIndir is set and v.ptr points at struct,
+ // or flagIndir is not set and v.ptr is the actual struct data.
+ // In the former case, we want v.ptr + offset.
+ // In the latter case, we must have field.offset = 0,
+ // so v.ptr + field.offset is still the correct address.
+ ptr := add(v.ptr, field.Offset, "same as non-reflect &v.field")
+ return Value{typ, ptr, fl}
+}
+
+// FieldByIndex returns the nested field corresponding to index.
+// It panics if evaluation requires stepping through a nil
+// pointer or a field that is not a struct.
+func (v Value) FieldByIndex(index []int) Value {
+ if len(index) == 1 {
+ return v.Field(index[0])
+ }
+ v.mustBe(Struct)
+ for i, x := range index {
+ if i > 0 {
+ if v.Kind() == Pointer && v.typ().Elem().Kind() == abi.Struct {
+ if v.IsNil() {
+ panic("reflect: indirection through nil pointer to embedded struct")
+ }
+ v = v.Elem()
+ }
+ }
+ v = v.Field(x)
+ }
+ return v
+}
+
+// FieldByIndexErr returns the nested field corresponding to index.
+// It returns an error if evaluation requires stepping through a nil
+// pointer, but panics if it must step through a field that
+// is not a struct.
+func (v Value) FieldByIndexErr(index []int) (Value, error) {
+ if len(index) == 1 {
+ return v.Field(index[0]), nil
+ }
+ v.mustBe(Struct)
+ for i, x := range index {
+ if i > 0 {
+ if v.Kind() == Ptr && v.typ().Elem().Kind() == abi.Struct {
+ if v.IsNil() {
+ return Value{}, errors.New("reflect: indirection through nil pointer to embedded struct field " + nameFor(v.typ().Elem()))
+ }
+ v = v.Elem()
+ }
+ }
+ v = v.Field(x)
+ }
+ return v, nil
+}
+
+// FieldByName returns the struct field with the given name.
+// It returns the zero Value if no field was found.
+// It panics if v's Kind is not struct.
+func (v Value) FieldByName(name string) Value {
+ v.mustBe(Struct)
+ if f, ok := toRType(v.typ()).FieldByName(name); ok {
+ return v.FieldByIndex(f.Index)
+ }
+ return Value{}
+}
+
+// FieldByNameFunc returns the struct field with a name
+// that satisfies the match function.
+// It panics if v's Kind is not struct.
+// It returns the zero Value if no field was found.
+func (v Value) FieldByNameFunc(match func(string) bool) Value {
+ if f, ok := toRType(v.typ()).FieldByNameFunc(match); ok {
+ return v.FieldByIndex(f.Index)
+ }
+ return Value{}
+}
+
+// CanFloat reports whether Float can be used without panicking.
+func (v Value) CanFloat() bool {
+ switch v.kind() {
+ case Float32, Float64:
+ return true
+ default:
+ return false
+ }
+}
+
+// Float returns v's underlying value, as a float64.
+// It panics if v's Kind is not Float32 or Float64
+func (v Value) Float() float64 {
+ k := v.kind()
+ switch k {
+ case Float32:
+ return float64(*(*float32)(v.ptr))
+ case Float64:
+ return *(*float64)(v.ptr)
+ }
+ panic(&ValueError{"reflect.Value.Float", v.kind()})
+}
+
+var uint8Type = rtypeOf(uint8(0))
+
+// Index returns v's i'th element.
+// It panics if v's Kind is not Array, Slice, or String or i is out of range.
+func (v Value) Index(i int) Value {
+ switch v.kind() {
+ case Array:
+ tt := (*arrayType)(unsafe.Pointer(v.typ()))
+ if uint(i) >= uint(tt.Len) {
+ panic("reflect: array index out of range")
+ }
+ typ := tt.Elem
+ offset := uintptr(i) * typ.Size()
+
+ // Either flagIndir is set and v.ptr points at array,
+ // or flagIndir is not set and v.ptr is the actual array data.
+ // In the former case, we want v.ptr + offset.
+ // In the latter case, we must be doing Index(0), so offset = 0,
+ // so v.ptr + offset is still the correct address.
+ val := add(v.ptr, offset, "same as &v[i], i < tt.len")
+ fl := v.flag&(flagIndir|flagAddr) | v.flag.ro() | flag(typ.Kind()) // bits same as overall array
+ return Value{typ, val, fl}
+
+ case Slice:
+ // Element flag same as Elem of Pointer.
+ // Addressable, indirect, possibly read-only.
+ s := (*unsafeheader.Slice)(v.ptr)
+ if uint(i) >= uint(s.Len) {
+ panic("reflect: slice index out of range")
+ }
+ tt := (*sliceType)(unsafe.Pointer(v.typ()))
+ typ := tt.Elem
+ val := arrayAt(s.Data, i, typ.Size(), "i < s.Len")
+ fl := flagAddr | flagIndir | v.flag.ro() | flag(typ.Kind())
+ return Value{typ, val, fl}
+
+ case String:
+ s := (*unsafeheader.String)(v.ptr)
+ if uint(i) >= uint(s.Len) {
+ panic("reflect: string index out of range")
+ }
+ p := arrayAt(s.Data, i, 1, "i < s.Len")
+ fl := v.flag.ro() | flag(Uint8) | flagIndir
+ return Value{uint8Type, p, fl}
+ }
+ panic(&ValueError{"reflect.Value.Index", v.kind()})
+}
+
+// CanInt reports whether Int can be used without panicking.
+func (v Value) CanInt() bool {
+ switch v.kind() {
+ case Int, Int8, Int16, Int32, Int64:
+ return true
+ default:
+ return false
+ }
+}
+
+// Int returns v's underlying value, as an int64.
+// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.
+func (v Value) Int() int64 {
+ k := v.kind()
+ p := v.ptr
+ switch k {
+ case Int:
+ return int64(*(*int)(p))
+ case Int8:
+ return int64(*(*int8)(p))
+ case Int16:
+ return int64(*(*int16)(p))
+ case Int32:
+ return int64(*(*int32)(p))
+ case Int64:
+ return *(*int64)(p)
+ }
+ panic(&ValueError{"reflect.Value.Int", v.kind()})
+}
+
+// CanInterface reports whether Interface can be used without panicking.
+func (v Value) CanInterface() bool {
+ if v.flag == 0 {
+ panic(&ValueError{"reflect.Value.CanInterface", Invalid})
+ }
+ return v.flag&flagRO == 0
+}
+
+// Interface returns v's current value as an interface{}.
+// It is equivalent to:
+//
+// var i interface{} = (v's underlying value)
+//
+// It panics if the Value was obtained by accessing
+// unexported struct fields.
+func (v Value) Interface() (i any) {
+ return valueInterface(v, true)
+}
+
+func valueInterface(v Value, safe bool) any {
+ if v.flag == 0 {
+ panic(&ValueError{"reflect.Value.Interface", Invalid})
+ }
+ if safe && v.flag&flagRO != 0 {
+ // Do not allow access to unexported values via Interface,
+ // because they might be pointers that should not be
+ // writable or methods or function that should not be callable.
+ panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
+ }
+ if v.flag&flagMethod != 0 {
+ v = makeMethodValue("Interface", v)
+ }
+
+ if v.kind() == Interface {
+ // Special case: return the element inside the interface.
+ // Empty interface has one layout, all interfaces with
+ // methods have a second layout.
+ if v.NumMethod() == 0 {
+ return *(*any)(v.ptr)
+ }
+ return *(*interface {
+ M()
+ })(v.ptr)
+ }
+
+ // TODO: pass safe to packEface so we don't need to copy if safe==true?
+ return packEface(v)
+}
+
+// InterfaceData returns a pair of unspecified uintptr values.
+// It panics if v's Kind is not Interface.
+//
+// In earlier versions of Go, this function returned the interface's
+// value as a uintptr pair. As of Go 1.4, the implementation of
+// interface values precludes any defined use of InterfaceData.
+//
+// Deprecated: The memory representation of interface values is not
+// compatible with InterfaceData.
+func (v Value) InterfaceData() [2]uintptr {
+ v.mustBe(Interface)
+ // The compiler loses track as it converts to uintptr. Force escape.
+ escapes(v.ptr)
+ // We treat this as a read operation, so we allow
+ // it even for unexported data, because the caller
+ // has to import "unsafe" to turn it into something
+ // that can be abused.
+ // Interface value is always bigger than a word; assume flagIndir.
+ return *(*[2]uintptr)(v.ptr)
+}
+
+// IsNil reports whether its argument v is nil. The argument must be
+// a chan, func, interface, map, pointer, or slice value; if it is
+// not, IsNil panics. Note that IsNil is not always equivalent to a
+// regular comparison with nil in Go. For example, if v was created
+// by calling ValueOf with an uninitialized interface variable i,
+// i==nil will be true but v.IsNil will panic as v will be the zero
+// Value.
+func (v Value) IsNil() bool {
+ k := v.kind()
+ switch k {
+ case Chan, Func, Map, Pointer, UnsafePointer:
+ if v.flag&flagMethod != 0 {
+ return false
+ }
+ ptr := v.ptr
+ if v.flag&flagIndir != 0 {
+ ptr = *(*unsafe.Pointer)(ptr)
+ }
+ return ptr == nil
+ case Interface, Slice:
+ // Both interface and slice are nil if first word is 0.
+ // Both are always bigger than a word; assume flagIndir.
+ return *(*unsafe.Pointer)(v.ptr) == nil
+ }
+ panic(&ValueError{"reflect.Value.IsNil", v.kind()})
+}
+
+// IsValid reports whether v represents a value.
+// It returns false if v is the zero Value.
+// If IsValid returns false, all other methods except String panic.
+// Most functions and methods never return an invalid Value.
+// If one does, its documentation states the conditions explicitly.
+func (v Value) IsValid() bool {
+ return v.flag != 0
+}
+
+// IsZero reports whether v is the zero value for its type.
+// It panics if the argument is invalid.
+func (v Value) IsZero() bool {
+ switch v.kind() {
+ case Bool:
+ return !v.Bool()
+ case Int, Int8, Int16, Int32, Int64:
+ return v.Int() == 0
+ case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+ return v.Uint() == 0
+ case Float32, Float64:
+ return math.Float64bits(v.Float()) == 0
+ case Complex64, Complex128:
+ c := v.Complex()
+ return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
+ case Array:
+ // If the type is comparable, then compare directly with zero.
+ if v.typ().Equal != nil && v.typ().Size() <= maxZero {
+ if v.flag&flagIndir == 0 {
+ return v.ptr == nil
+ }
+ // v.ptr doesn't escape, as Equal functions are compiler generated
+ // and never escape. The escape analysis doesn't know, as it is a
+ // function pointer call.
+ return v.typ().Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0]))
+ }
+
+ n := v.Len()
+ for i := 0; i < n; i++ {
+ if !v.Index(i).IsZero() {
+ return false
+ }
+ }
+ return true
+ case Chan, Func, Interface, Map, Pointer, Slice, UnsafePointer:
+ return v.IsNil()
+ case String:
+ return v.Len() == 0
+ case Struct:
+ // If the type is comparable, then compare directly with zero.
+ if v.typ().Equal != nil && v.typ().Size() <= maxZero {
+ if v.flag&flagIndir == 0 {
+ return v.ptr == nil
+ }
+ // See noescape justification above.
+ return v.typ().Equal(noescape(v.ptr), unsafe.Pointer(&zeroVal[0]))
+ }
+
+ n := v.NumField()
+ for i := 0; i < n; i++ {
+ if !v.Field(i).IsZero() {
+ return false
+ }
+ }
+ return true
+ default:
+ // This should never happen, but will act as a safeguard for later,
+ // as a default value doesn't makes sense here.
+ panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
+ }
+}
+
+// SetZero sets v to be the zero value of v's type.
+// It panics if CanSet returns false.
+func (v Value) SetZero() {
+ v.mustBeAssignable()
+ switch v.kind() {
+ case Bool:
+ *(*bool)(v.ptr) = false
+ case Int:
+ *(*int)(v.ptr) = 0
+ case Int8:
+ *(*int8)(v.ptr) = 0
+ case Int16:
+ *(*int16)(v.ptr) = 0
+ case Int32:
+ *(*int32)(v.ptr) = 0
+ case Int64:
+ *(*int64)(v.ptr) = 0
+ case Uint:
+ *(*uint)(v.ptr) = 0
+ case Uint8:
+ *(*uint8)(v.ptr) = 0
+ case Uint16:
+ *(*uint16)(v.ptr) = 0
+ case Uint32:
+ *(*uint32)(v.ptr) = 0
+ case Uint64:
+ *(*uint64)(v.ptr) = 0
+ case Uintptr:
+ *(*uintptr)(v.ptr) = 0
+ case Float32:
+ *(*float32)(v.ptr) = 0
+ case Float64:
+ *(*float64)(v.ptr) = 0
+ case Complex64:
+ *(*complex64)(v.ptr) = 0
+ case Complex128:
+ *(*complex128)(v.ptr) = 0
+ case String:
+ *(*string)(v.ptr) = ""
+ case Slice:
+ *(*unsafeheader.Slice)(v.ptr) = unsafeheader.Slice{}
+ case Interface:
+ *(*[2]unsafe.Pointer)(v.ptr) = [2]unsafe.Pointer{}
+ case Chan, Func, Map, Pointer, UnsafePointer:
+ *(*unsafe.Pointer)(v.ptr) = nil
+ case Array, Struct:
+ typedmemclr(v.typ(), v.ptr)
+ default:
+ // This should never happen, but will act as a safeguard for later,
+ // as a default value doesn't makes sense here.
+ panic(&ValueError{"reflect.Value.SetZero", v.Kind()})
+ }
+}
+
+// Kind returns v's Kind.
+// If v is the zero Value (IsValid returns false), Kind returns Invalid.
+func (v Value) Kind() Kind {
+ return v.kind()
+}
+
+// Len returns v's length.
+// It panics if v's Kind is not Array, Chan, Map, Slice, String, or pointer to Array.
+func (v Value) Len() int {
+ // lenNonSlice is split out to keep Len inlineable for slice kinds.
+ if v.kind() == Slice {
+ return (*unsafeheader.Slice)(v.ptr).Len
+ }
+ return v.lenNonSlice()
+}
+
+func (v Value) lenNonSlice() int {
+ switch k := v.kind(); k {
+ case Array:
+ tt := (*arrayType)(unsafe.Pointer(v.typ()))
+ return int(tt.Len)
+ case Chan:
+ return chanlen(v.pointer())
+ case Map:
+ return maplen(v.pointer())
+ case String:
+ // String is bigger than a word; assume flagIndir.
+ return (*unsafeheader.String)(v.ptr).Len
+ case Ptr:
+ if v.typ().Elem().Kind() == abi.Array {
+ return v.typ().Elem().Len()
+ }
+ panic("reflect: call of reflect.Value.Len on ptr to non-array Value")
+ }
+ panic(&ValueError{"reflect.Value.Len", v.kind()})
+}
+
+var stringType = rtypeOf("")
+
+// MapIndex returns the value associated with key in the map v.
+// It panics if v's Kind is not Map.
+// It returns the zero Value if key is not found in the map or if v represents a nil map.
+// As in Go, the key's value must be assignable to the map's key type.
+func (v Value) MapIndex(key Value) Value {
+ v.mustBe(Map)
+ tt := (*mapType)(unsafe.Pointer(v.typ()))
+
+ // Do not require key to be exported, so that DeepEqual
+ // and other programs can use all the keys returned by
+ // MapKeys as arguments to MapIndex. If either the map
+ // or the key is unexported, though, the result will be
+ // considered unexported. This is consistent with the
+ // behavior for structs, which allow read but not write
+ // of unexported fields.
+
+ var e unsafe.Pointer
+ if (tt.Key == stringType || key.kind() == String) && tt.Key == key.typ() && tt.Elem.Size() <= maxValSize {
+ k := *(*string)(key.ptr)
+ e = mapaccess_faststr(v.typ(), v.pointer(), k)
+ } else {
+ key = key.assignTo("reflect.Value.MapIndex", tt.Key, nil)
+ var k unsafe.Pointer
+ if key.flag&flagIndir != 0 {
+ k = key.ptr
+ } else {
+ k = unsafe.Pointer(&key.ptr)
+ }
+ e = mapaccess(v.typ(), v.pointer(), k)
+ }
+ if e == nil {
+ return Value{}
+ }
+ typ := tt.Elem
+ fl := (v.flag | key.flag).ro()
+ fl |= flag(typ.Kind())
+ return copyVal(typ, fl, e)
+}
+
+// MapKeys returns a slice containing all the keys present in the map,
+// in unspecified order.
+// It panics if v's Kind is not Map.
+// It returns an empty slice if v represents a nil map.
+func (v Value) MapKeys() []Value {
+ v.mustBe(Map)
+ tt := (*mapType)(unsafe.Pointer(v.typ()))
+ keyType := tt.Key
+
+ fl := v.flag.ro() | flag(keyType.Kind())
+
+ m := v.pointer()
+ mlen := int(0)
+ if m != nil {
+ mlen = maplen(m)
+ }
+ var it hiter
+ mapiterinit(v.typ(), m, &it)
+ a := make([]Value, mlen)
+ var i int
+ for i = 0; i < len(a); i++ {
+ key := mapiterkey(&it)
+ if key == nil {
+ // Someone deleted an entry from the map since we
+ // called maplen above. It's a data race, but nothing
+ // we can do about it.
+ break
+ }
+ a[i] = copyVal(keyType, fl, key)
+ mapiternext(&it)
+ }
+ return a[:i]
+}
+
+// hiter's structure matches runtime.hiter's structure.
+// Having a clone here allows us to embed a map iterator
+// inside type MapIter so that MapIters can be re-used
+// without doing any allocations.
+type hiter struct {
+ key unsafe.Pointer
+ elem unsafe.Pointer
+ t unsafe.Pointer
+ h unsafe.Pointer
+ buckets unsafe.Pointer
+ bptr unsafe.Pointer
+ overflow *[]unsafe.Pointer
+ oldoverflow *[]unsafe.Pointer
+ startBucket uintptr
+ offset uint8
+ wrapped bool
+ B uint8
+ i uint8
+ bucket uintptr
+ checkBucket uintptr
+}
+
+func (h *hiter) initialized() bool {
+ return h.t != nil
+}
+
+// A MapIter is an iterator for ranging over a map.
+// See Value.MapRange.
+type MapIter struct {
+ m Value
+ hiter hiter
+}
+
+// Key returns the key of iter's current map entry.
+func (iter *MapIter) Key() Value {
+ if !iter.hiter.initialized() {
+ panic("MapIter.Key called before Next")
+ }
+ iterkey := mapiterkey(&iter.hiter)
+ if iterkey == nil {
+ panic("MapIter.Key called on exhausted iterator")
+ }
+
+ t := (*mapType)(unsafe.Pointer(iter.m.typ()))
+ ktype := t.Key
+ return copyVal(ktype, iter.m.flag.ro()|flag(ktype.Kind()), iterkey)
+}
+
+// SetIterKey assigns to v the key of iter's current map entry.
+// It is equivalent to v.Set(iter.Key()), but it avoids allocating a new Value.
+// As in Go, the key must be assignable to v's type and
+// must not be derived from an unexported field.
+func (v Value) SetIterKey(iter *MapIter) {
+ if !iter.hiter.initialized() {
+ panic("reflect: Value.SetIterKey called before Next")
+ }
+ iterkey := mapiterkey(&iter.hiter)
+ if iterkey == nil {
+ panic("reflect: Value.SetIterKey called on exhausted iterator")
+ }
+
+ v.mustBeAssignable()
+ var target unsafe.Pointer
+ if v.kind() == Interface {
+ target = v.ptr
+ }
+
+ t := (*mapType)(unsafe.Pointer(iter.m.typ()))
+ ktype := t.Key
+
+ iter.m.mustBeExported() // do not let unexported m leak
+ key := Value{ktype, iterkey, iter.m.flag | flag(ktype.Kind()) | flagIndir}
+ key = key.assignTo("reflect.MapIter.SetKey", v.typ(), target)
+ typedmemmove(v.typ(), v.ptr, key.ptr)
+}
+
+// Value returns the value of iter's current map entry.
+func (iter *MapIter) Value() Value {
+ if !iter.hiter.initialized() {
+ panic("MapIter.Value called before Next")
+ }
+ iterelem := mapiterelem(&iter.hiter)
+ if iterelem == nil {
+ panic("MapIter.Value called on exhausted iterator")
+ }
+
+ t := (*mapType)(unsafe.Pointer(iter.m.typ()))
+ vtype := t.Elem
+ return copyVal(vtype, iter.m.flag.ro()|flag(vtype.Kind()), iterelem)
+}
+
+// SetIterValue assigns to v the value of iter's current map entry.
+// It is equivalent to v.Set(iter.Value()), but it avoids allocating a new Value.
+// As in Go, the value must be assignable to v's type and
+// must not be derived from an unexported field.
+func (v Value) SetIterValue(iter *MapIter) {
+ if !iter.hiter.initialized() {
+ panic("reflect: Value.SetIterValue called before Next")
+ }
+ iterelem := mapiterelem(&iter.hiter)
+ if iterelem == nil {
+ panic("reflect: Value.SetIterValue called on exhausted iterator")
+ }
+
+ v.mustBeAssignable()
+ var target unsafe.Pointer
+ if v.kind() == Interface {
+ target = v.ptr
+ }
+
+ t := (*mapType)(unsafe.Pointer(iter.m.typ()))
+ vtype := t.Elem
+
+ iter.m.mustBeExported() // do not let unexported m leak
+ elem := Value{vtype, iterelem, iter.m.flag | flag(vtype.Kind()) | flagIndir}
+ elem = elem.assignTo("reflect.MapIter.SetValue", v.typ(), target)
+ typedmemmove(v.typ(), v.ptr, elem.ptr)
+}
+
+// Next advances the map iterator and reports whether there is another
+// entry. It returns false when iter is exhausted; subsequent
+// calls to Key, Value, or Next will panic.
+func (iter *MapIter) Next() bool {
+ if !iter.m.IsValid() {
+ panic("MapIter.Next called on an iterator that does not have an associated map Value")
+ }
+ if !iter.hiter.initialized() {
+ mapiterinit(iter.m.typ(), iter.m.pointer(), &iter.hiter)
+ } else {
+ if mapiterkey(&iter.hiter) == nil {
+ panic("MapIter.Next called on exhausted iterator")
+ }
+ mapiternext(&iter.hiter)
+ }
+ return mapiterkey(&iter.hiter) != nil
+}
+
+// Reset modifies iter to iterate over v.
+// It panics if v's Kind is not Map and v is not the zero Value.
+// Reset(Value{}) causes iter to not to refer to any map,
+// which may allow the previously iterated-over map to be garbage collected.
+func (iter *MapIter) Reset(v Value) {
+ if v.IsValid() {
+ v.mustBe(Map)
+ }
+ iter.m = v
+ iter.hiter = hiter{}
+}
+
+// MapRange returns a range iterator for a map.
+// It panics if v's Kind is not Map.
+//
+// Call Next to advance the iterator, and Key/Value to access each entry.
+// Next returns false when the iterator is exhausted.
+// MapRange follows the same iteration semantics as a range statement.
+//
+// Example:
+//
+// iter := reflect.ValueOf(m).MapRange()
+// for iter.Next() {
+// k := iter.Key()
+// v := iter.Value()
+// ...
+// }
+func (v Value) MapRange() *MapIter {
+ // This is inlinable to take advantage of "function outlining".
+ // The allocation of MapIter can be stack allocated if the caller
+ // does not allow it to escape.
+ // See https://blog.filippo.io/efficient-go-apis-with-the-inliner/
+ if v.kind() != Map {
+ v.panicNotMap()
+ }
+ return &MapIter{m: v}
+}
+
+// Force slow panicking path not inlined, so it won't add to the
+// inlining budget of the caller.
+// TODO: undo when the inliner is no longer bottom-up only.
+//
+//go:noinline
+func (f flag) panicNotMap() {
+ f.mustBe(Map)
+}
+
+// copyVal returns a Value containing the map key or value at ptr,
+// allocating a new variable as needed.
+func copyVal(typ *abi.Type, fl flag, ptr unsafe.Pointer) Value {
+ if typ.IfaceIndir() {
+ // Copy result so future changes to the map
+ // won't change the underlying value.
+ c := unsafe_New(typ)
+ typedmemmove(typ, c, ptr)
+ return Value{typ, c, fl | flagIndir}
+ }
+ return Value{typ, *(*unsafe.Pointer)(ptr), fl}
+}
+
+// Method returns a function value corresponding to v's i'th method.
+// The arguments to a Call on the returned function should not include
+// a receiver; the returned function will always use v as the receiver.
+// Method panics if i is out of range or if v is a nil interface value.
+func (v Value) Method(i int) Value {
+ if v.typ() == nil {
+ panic(&ValueError{"reflect.Value.Method", Invalid})
+ }
+ if v.flag&flagMethod != 0 || uint(i) >= uint(toRType(v.typ()).NumMethod()) {
+ panic("reflect: Method index out of range")
+ }
+ if v.typ().Kind() == abi.Interface && v.IsNil() {
+ panic("reflect: Method on nil interface value")
+ }
+ fl := v.flag.ro() | (v.flag & flagIndir)
+ fl |= flag(Func)
+ fl |= flag(i)<<flagMethodShift | flagMethod
+ return Value{v.typ(), v.ptr, fl}
+}
+
+// NumMethod returns the number of methods in the value's method set.
+//
+// For a non-interface type, it returns the number of exported methods.
+//
+// For an interface type, it returns the number of exported and unexported methods.
+func (v Value) NumMethod() int {
+ if v.typ() == nil {
+ panic(&ValueError{"reflect.Value.NumMethod", Invalid})
+ }
+ if v.flag&flagMethod != 0 {
+ return 0
+ }
+ return toRType(v.typ()).NumMethod()
+}
+
+// MethodByName returns a function value corresponding to the method
+// of v with the given name.
+// The arguments to a Call on the returned function should not include
+// a receiver; the returned function will always use v as the receiver.
+// It returns the zero Value if no method was found.
+func (v Value) MethodByName(name string) Value {
+ if v.typ() == nil {
+ panic(&ValueError{"reflect.Value.MethodByName", Invalid})
+ }
+ if v.flag&flagMethod != 0 {
+ return Value{}
+ }
+ m, ok := toRType(v.typ()).MethodByName(name)
+ if !ok {
+ return Value{}
+ }
+ return v.Method(m.Index)
+}
+
+// NumField returns the number of fields in the struct v.
+// It panics if v's Kind is not Struct.
+func (v Value) NumField() int {
+ v.mustBe(Struct)
+ tt := (*structType)(unsafe.Pointer(v.typ()))
+ return len(tt.Fields)
+}
+
+// OverflowComplex reports whether the complex128 x cannot be represented by v's type.
+// It panics if v's Kind is not Complex64 or Complex128.
+func (v Value) OverflowComplex(x complex128) bool {
+ k := v.kind()
+ switch k {
+ case Complex64:
+ return overflowFloat32(real(x)) || overflowFloat32(imag(x))
+ case Complex128:
+ return false
+ }
+ panic(&ValueError{"reflect.Value.OverflowComplex", v.kind()})
+}
+
+// OverflowFloat reports whether the float64 x cannot be represented by v's type.
+// It panics if v's Kind is not Float32 or Float64.
+func (v Value) OverflowFloat(x float64) bool {
+ k := v.kind()
+ switch k {
+ case Float32:
+ return overflowFloat32(x)
+ case Float64:
+ return false
+ }
+ panic(&ValueError{"reflect.Value.OverflowFloat", v.kind()})
+}
+
+func overflowFloat32(x float64) bool {
+ if x < 0 {
+ x = -x
+ }
+ return math.MaxFloat32 < x && x <= math.MaxFloat64
+}
+
+// OverflowInt reports whether the int64 x cannot be represented by v's type.
+// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.
+func (v Value) OverflowInt(x int64) bool {
+ k := v.kind()
+ switch k {
+ case Int, Int8, Int16, Int32, Int64:
+ bitSize := v.typ().Size() * 8
+ trunc := (x << (64 - bitSize)) >> (64 - bitSize)
+ return x != trunc
+ }
+ panic(&ValueError{"reflect.Value.OverflowInt", v.kind()})
+}
+
+// OverflowUint reports whether the uint64 x cannot be represented by v's type.
+// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
+func (v Value) OverflowUint(x uint64) bool {
+ k := v.kind()
+ switch k {
+ case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
+ bitSize := v.typ_.Size() * 8 // ok to use v.typ_ directly as Size doesn't escape
+ trunc := (x << (64 - bitSize)) >> (64 - bitSize)
+ return x != trunc
+ }
+ panic(&ValueError{"reflect.Value.OverflowUint", v.kind()})
+}
+
+//go:nocheckptr
+// This prevents inlining Value.Pointer when -d=checkptr is enabled,
+// which ensures cmd/compile can recognize unsafe.Pointer(v.Pointer())
+// and make an exception.
+
+// Pointer returns v's value as a uintptr.
+// It panics if v's Kind is not Chan, Func, Map, Pointer, Slice, or UnsafePointer.
+//
+// If v's Kind is Func, the returned pointer is an underlying
+// code pointer, but not necessarily enough to identify a
+// single function uniquely. The only guarantee is that the
+// result is zero if and only if v is a nil func Value.
+//
+// If v's Kind is Slice, the returned pointer is to the first
+// element of the slice. If the slice is nil the returned value
+// is 0. If the slice is empty but non-nil the return value is non-zero.
+//
+// It's preferred to use uintptr(Value.UnsafePointer()) to get the equivalent result.
+func (v Value) Pointer() uintptr {
+ // The compiler loses track as it converts to uintptr. Force escape.
+ escapes(v.ptr)
+
+ k := v.kind()
+ switch k {
+ case Pointer:
+ if v.typ().PtrBytes == 0 {
+ val := *(*uintptr)(v.ptr)
+ // Since it is a not-in-heap pointer, all pointers to the heap are
+ // forbidden! See comment in Value.Elem and issue #48399.
+ if !verifyNotInHeapPtr(val) {
+ panic("reflect: reflect.Value.Pointer on an invalid notinheap pointer")
+ }
+ return val
+ }
+ fallthrough
+ case Chan, Map, UnsafePointer:
+ return uintptr(v.pointer())
+ case Func:
+ if v.flag&flagMethod != 0 {
+ // As the doc comment says, the returned pointer is an
+ // underlying code pointer but not necessarily enough to
+ // identify a single function uniquely. All method expressions
+ // created via reflect have the same underlying code pointer,
+ // so their Pointers are equal. The function used here must
+ // match the one used in makeMethodValue.
+ return methodValueCallCodePtr()
+ }
+ p := v.pointer()
+ // Non-nil func value points at data block.
+ // First word of data block is actual code.
+ if p != nil {
+ p = *(*unsafe.Pointer)(p)
+ }
+ return uintptr(p)
+
+ case Slice:
+ return uintptr((*unsafeheader.Slice)(v.ptr).Data)
+ }
+ panic(&ValueError{"reflect.Value.Pointer", v.kind()})
+}
+
+// Recv receives and returns a value from the channel v.
+// It panics if v's Kind is not Chan.
+// The receive blocks until a value is ready.
+// The boolean value ok is true if the value x corresponds to a send
+// on the channel, false if it is a zero value received because the channel is closed.
+func (v Value) Recv() (x Value, ok bool) {
+ v.mustBe(Chan)
+ v.mustBeExported()
+ return v.recv(false)
+}
+
+// internal recv, possibly non-blocking (nb).
+// v is known to be a channel.
+func (v Value) recv(nb bool) (val Value, ok bool) {
+ tt := (*chanType)(unsafe.Pointer(v.typ()))
+ if ChanDir(tt.Dir)&RecvDir == 0 {
+ panic("reflect: recv on send-only channel")
+ }
+ t := tt.Elem
+ val = Value{t, nil, flag(t.Kind())}
+ var p unsafe.Pointer
+ if ifaceIndir(t) {
+ p = unsafe_New(t)
+ val.ptr = p
+ val.flag |= flagIndir
+ } else {
+ p = unsafe.Pointer(&val.ptr)
+ }
+ selected, ok := chanrecv(v.pointer(), nb, p)
+ if !selected {
+ val = Value{}
+ }
+ return
+}
+
+// Send sends x on the channel v.
+// It panics if v's kind is not Chan or if x's type is not the same type as v's element type.
+// As in Go, x's value must be assignable to the channel's element type.
+func (v Value) Send(x Value) {
+ v.mustBe(Chan)
+ v.mustBeExported()
+ v.send(x, false)
+}
+
+// internal send, possibly non-blocking.
+// v is known to be a channel.
+func (v Value) send(x Value, nb bool) (selected bool) {
+ tt := (*chanType)(unsafe.Pointer(v.typ()))
+ if ChanDir(tt.Dir)&SendDir == 0 {
+ panic("reflect: send on recv-only channel")
+ }
+ x.mustBeExported()
+ x = x.assignTo("reflect.Value.Send", tt.Elem, nil)
+ var p unsafe.Pointer
+ if x.flag&flagIndir != 0 {
+ p = x.ptr
+ } else {
+ p = unsafe.Pointer(&x.ptr)
+ }
+ return chansend(v.pointer(), p, nb)
+}
+
+// Set assigns x to the value v.
+// It panics if CanSet returns false.
+// As in Go, x's value must be assignable to v's type and
+// must not be derived from an unexported field.
+func (v Value) Set(x Value) {
+ v.mustBeAssignable()
+ x.mustBeExported() // do not let unexported x leak
+ var target unsafe.Pointer
+ if v.kind() == Interface {
+ target = v.ptr
+ }
+ x = x.assignTo("reflect.Set", v.typ(), target)
+ if x.flag&flagIndir != 0 {
+ if x.ptr == unsafe.Pointer(&zeroVal[0]) {
+ typedmemclr(v.typ(), v.ptr)
+ } else {
+ typedmemmove(v.typ(), v.ptr, x.ptr)
+ }
+ } else {
+ *(*unsafe.Pointer)(v.ptr) = x.ptr
+ }
+}
+
+// SetBool sets v's underlying value.
+// It panics if v's Kind is not Bool or if CanSet() is false.
+func (v Value) SetBool(x bool) {
+ v.mustBeAssignable()
+ v.mustBe(Bool)
+ *(*bool)(v.ptr) = x
+}
+
+// SetBytes sets v's underlying value.
+// It panics if v's underlying value is not a slice of bytes.
+func (v Value) SetBytes(x []byte) {
+ v.mustBeAssignable()
+ v.mustBe(Slice)
+ if toRType(v.typ()).Elem().Kind() != Uint8 { // TODO add Elem method, fix mustBe(Slice) to return slice.
+ panic("reflect.Value.SetBytes of non-byte slice")
+ }
+ *(*[]byte)(v.ptr) = x
+}
+
+// setRunes sets v's underlying value.
+// It panics if v's underlying value is not a slice of runes (int32s).
+func (v Value) setRunes(x []rune) {
+ v.mustBeAssignable()
+ v.mustBe(Slice)
+ if v.typ().Elem().Kind() != abi.Int32 {
+ panic("reflect.Value.setRunes of non-rune slice")
+ }
+ *(*[]rune)(v.ptr) = x
+}
+
+// SetComplex sets v's underlying value to x.
+// It panics if v's Kind is not Complex64 or Complex128, or if CanSet() is false.
+func (v Value) SetComplex(x complex128) {
+ v.mustBeAssignable()
+ switch k := v.kind(); k {
+ default:
+ panic(&ValueError{"reflect.Value.SetComplex", v.kind()})
+ case Complex64:
+ *(*complex64)(v.ptr) = complex64(x)
+ case Complex128:
+ *(*complex128)(v.ptr) = x
+ }
+}
+
+// SetFloat sets v's underlying value to x.
+// It panics if v's Kind is not Float32 or Float64, or if CanSet() is false.
+func (v Value) SetFloat(x float64) {
+ v.mustBeAssignable()
+ switch k := v.kind(); k {
+ default:
+ panic(&ValueError{"reflect.Value.SetFloat", v.kind()})
+ case Float32:
+ *(*float32)(v.ptr) = float32(x)
+ case Float64:
+ *(*float64)(v.ptr) = x
+ }
+}
+
+// SetInt sets v's underlying value to x.
+// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64, or if CanSet() is false.
+func (v Value) SetInt(x int64) {
+ v.mustBeAssignable()
+ switch k := v.kind(); k {
+ default:
+ panic(&ValueError{"reflect.Value.SetInt", v.kind()})
+ case Int:
+ *(*int)(v.ptr) = int(x)
+ case Int8:
+ *(*int8)(v.ptr) = int8(x)
+ case Int16:
+ *(*int16)(v.ptr) = int16(x)
+ case Int32:
+ *(*int32)(v.ptr) = int32(x)
+ case Int64:
+ *(*int64)(v.ptr) = x
+ }
+}
+
+// SetLen sets v's length to n.
+// It panics if v's Kind is not Slice or if n is negative or
+// greater than the capacity of the slice.
+func (v Value) SetLen(n int) {
+ v.mustBeAssignable()
+ v.mustBe(Slice)
+ s := (*unsafeheader.Slice)(v.ptr)
+ if uint(n) > uint(s.Cap) {
+ panic("reflect: slice length out of range in SetLen")
+ }
+ s.Len = n
+}
+
+// SetCap sets v's capacity to n.
+// It panics if v's Kind is not Slice or if n is smaller than the length or
+// greater than the capacity of the slice.
+func (v Value) SetCap(n int) {
+ v.mustBeAssignable()
+ v.mustBe(Slice)
+ s := (*unsafeheader.Slice)(v.ptr)
+ if n < s.Len || n > s.Cap {
+ panic("reflect: slice capacity out of range in SetCap")
+ }
+ s.Cap = n
+}
+
+// SetMapIndex sets the element associated with key in the map v to elem.
+// It panics if v's Kind is not Map.
+// If elem is the zero Value, SetMapIndex deletes the key from the map.
+// Otherwise if v holds a nil map, SetMapIndex will panic.
+// As in Go, key's elem must be assignable to the map's key type,
+// and elem's value must be assignable to the map's elem type.
+func (v Value) SetMapIndex(key, elem Value) {
+ v.mustBe(Map)
+ v.mustBeExported()
+ key.mustBeExported()
+ tt := (*mapType)(unsafe.Pointer(v.typ()))
+
+ if (tt.Key == stringType || key.kind() == String) && tt.Key == key.typ() && tt.Elem.Size() <= maxValSize {
+ k := *(*string)(key.ptr)
+ if elem.typ() == nil {
+ mapdelete_faststr(v.typ(), v.pointer(), k)
+ return
+ }
+ elem.mustBeExported()
+ elem = elem.assignTo("reflect.Value.SetMapIndex", tt.Elem, nil)
+ var e unsafe.Pointer
+ if elem.flag&flagIndir != 0 {
+ e = elem.ptr
+ } else {
+ e = unsafe.Pointer(&elem.ptr)
+ }
+ mapassign_faststr(v.typ(), v.pointer(), k, e)
+ return
+ }
+
+ key = key.assignTo("reflect.Value.SetMapIndex", tt.Key, nil)
+ var k unsafe.Pointer
+ if key.flag&flagIndir != 0 {
+ k = key.ptr
+ } else {
+ k = unsafe.Pointer(&key.ptr)
+ }
+ if elem.typ() == nil {
+ mapdelete(v.typ(), v.pointer(), k)
+ return
+ }
+ elem.mustBeExported()
+ elem = elem.assignTo("reflect.Value.SetMapIndex", tt.Elem, nil)
+ var e unsafe.Pointer
+ if elem.flag&flagIndir != 0 {
+ e = elem.ptr
+ } else {
+ e = unsafe.Pointer(&elem.ptr)
+ }
+ mapassign(v.typ(), v.pointer(), k, e)
+}
+
+// SetUint sets v's underlying value to x.
+// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64, or if CanSet() is false.
+func (v Value) SetUint(x uint64) {
+ v.mustBeAssignable()
+ switch k := v.kind(); k {
+ default:
+ panic(&ValueError{"reflect.Value.SetUint", v.kind()})
+ case Uint:
+ *(*uint)(v.ptr) = uint(x)
+ case Uint8:
+ *(*uint8)(v.ptr) = uint8(x)
+ case Uint16:
+ *(*uint16)(v.ptr) = uint16(x)
+ case Uint32:
+ *(*uint32)(v.ptr) = uint32(x)
+ case Uint64:
+ *(*uint64)(v.ptr) = x
+ case Uintptr:
+ *(*uintptr)(v.ptr) = uintptr(x)
+ }
+}
+
+// SetPointer sets the [unsafe.Pointer] value v to x.
+// It panics if v's Kind is not UnsafePointer.
+func (v Value) SetPointer(x unsafe.Pointer) {
+ v.mustBeAssignable()
+ v.mustBe(UnsafePointer)
+ *(*unsafe.Pointer)(v.ptr) = x
+}
+
+// SetString sets v's underlying value to x.
+// It panics if v's Kind is not String or if CanSet() is false.
+func (v Value) SetString(x string) {
+ v.mustBeAssignable()
+ v.mustBe(String)
+ *(*string)(v.ptr) = x
+}
+
+// Slice returns v[i:j].
+// It panics if v's Kind is not Array, Slice or String, or if v is an unaddressable array,
+// or if the indexes are out of bounds.
+func (v Value) Slice(i, j int) Value {
+ var (
+ cap int
+ typ *sliceType
+ base unsafe.Pointer
+ )
+ switch kind := v.kind(); kind {
+ default:
+ panic(&ValueError{"reflect.Value.Slice", v.kind()})
+
+ case Array:
+ if v.flag&flagAddr == 0 {
+ panic("reflect.Value.Slice: slice of unaddressable array")
+ }
+ tt := (*arrayType)(unsafe.Pointer(v.typ()))
+ cap = int(tt.Len)
+ typ = (*sliceType)(unsafe.Pointer(tt.Slice))
+ base = v.ptr
+
+ case Slice:
+ typ = (*sliceType)(unsafe.Pointer(v.typ()))
+ s := (*unsafeheader.Slice)(v.ptr)
+ base = s.Data
+ cap = s.Cap
+
+ case String:
+ s := (*unsafeheader.String)(v.ptr)
+ if i < 0 || j < i || j > s.Len {
+ panic("reflect.Value.Slice: string slice index out of bounds")
+ }
+ var t unsafeheader.String
+ if i < s.Len {
+ t = unsafeheader.String{Data: arrayAt(s.Data, i, 1, "i < s.Len"), Len: j - i}
+ }
+ return Value{v.typ(), unsafe.Pointer(&t), v.flag}
+ }
+
+ if i < 0 || j < i || j > cap {
+ panic("reflect.Value.Slice: slice index out of bounds")
+ }
+
+ // Declare slice so that gc can see the base pointer in it.
+ var x []unsafe.Pointer
+
+ // Reinterpret as *unsafeheader.Slice to edit.
+ s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
+ s.Len = j - i
+ s.Cap = cap - i
+ if cap-i > 0 {
+ s.Data = arrayAt(base, i, typ.Elem.Size(), "i < cap")
+ } else {
+ // do not advance pointer, to avoid pointing beyond end of slice
+ s.Data = base
+ }
+
+ fl := v.flag.ro() | flagIndir | flag(Slice)
+ return Value{typ.Common(), unsafe.Pointer(&x), fl}
+}
+
+// Slice3 is the 3-index form of the slice operation: it returns v[i:j:k].
+// It panics if v's Kind is not Array or Slice, or if v is an unaddressable array,
+// or if the indexes are out of bounds.
+func (v Value) Slice3(i, j, k int) Value {
+ var (
+ cap int
+ typ *sliceType
+ base unsafe.Pointer
+ )
+ switch kind := v.kind(); kind {
+ default:
+ panic(&ValueError{"reflect.Value.Slice3", v.kind()})
+
+ case Array:
+ if v.flag&flagAddr == 0 {
+ panic("reflect.Value.Slice3: slice of unaddressable array")
+ }
+ tt := (*arrayType)(unsafe.Pointer(v.typ()))
+ cap = int(tt.Len)
+ typ = (*sliceType)(unsafe.Pointer(tt.Slice))
+ base = v.ptr
+
+ case Slice:
+ typ = (*sliceType)(unsafe.Pointer(v.typ()))
+ s := (*unsafeheader.Slice)(v.ptr)
+ base = s.Data
+ cap = s.Cap
+ }
+
+ if i < 0 || j < i || k < j || k > cap {
+ panic("reflect.Value.Slice3: slice index out of bounds")
+ }
+
+ // Declare slice so that the garbage collector
+ // can see the base pointer in it.
+ var x []unsafe.Pointer
+
+ // Reinterpret as *unsafeheader.Slice to edit.
+ s := (*unsafeheader.Slice)(unsafe.Pointer(&x))
+ s.Len = j - i
+ s.Cap = k - i
+ if k-i > 0 {
+ s.Data = arrayAt(base, i, typ.Elem.Size(), "i < k <= cap")
+ } else {
+ // do not advance pointer, to avoid pointing beyond end of slice
+ s.Data = base
+ }
+
+ fl := v.flag.ro() | flagIndir | flag(Slice)
+ return Value{typ.Common(), unsafe.Pointer(&x), fl}
+}
+
+// String returns the string v's underlying value, as a string.
+// String is a special case because of Go's String method convention.
+// Unlike the other getters, it does not panic if v's Kind is not String.
+// Instead, it returns a string of the form "<T value>" where T is v's type.
+// The fmt package treats Values specially. It does not call their String
+// method implicitly but instead prints the concrete values they hold.
+func (v Value) String() string {
+ // stringNonString is split out to keep String inlineable for string kinds.
+ if v.kind() == String {
+ return *(*string)(v.ptr)
+ }
+ return v.stringNonString()
+}
+
+func (v Value) stringNonString() string {
+ if v.kind() == Invalid {
+ return "<invalid Value>"
+ }
+ // If you call String on a reflect.Value of other type, it's better to
+ // print something than to panic. Useful in debugging.
+ return "<" + v.Type().String() + " Value>"
+}
+
+// TryRecv attempts to receive a value from the channel v but will not block.
+// It panics if v's Kind is not Chan.
+// If the receive delivers a value, x is the transferred value and ok is true.
+// If the receive cannot finish without blocking, x is the zero Value and ok is false.
+// If the channel is closed, x is the zero value for the channel's element type and ok is false.
+func (v Value) TryRecv() (x Value, ok bool) {
+ v.mustBe(Chan)
+ v.mustBeExported()
+ return v.recv(true)
+}
+
+// TrySend attempts to send x on the channel v but will not block.
+// It panics if v's Kind is not Chan.
+// It reports whether the value was sent.
+// As in Go, x's value must be assignable to the channel's element type.
+func (v Value) TrySend(x Value) bool {
+ v.mustBe(Chan)
+ v.mustBeExported()
+ return v.send(x, true)
+}
+
+// Type returns v's type.
+func (v Value) Type() Type {
+ if v.flag != 0 && v.flag&flagMethod == 0 {
+ return (*rtype)(noescape(unsafe.Pointer(v.typ_))) // inline of toRType(v.typ()), for own inlining in inline test
+ }
+ return v.typeSlow()
+}
+
+func (v Value) typeSlow() Type {
+ if v.flag == 0 {
+ panic(&ValueError{"reflect.Value.Type", Invalid})
+ }
+
+ typ := v.typ()
+ if v.flag&flagMethod == 0 {
+ return toRType(v.typ())
+ }
+
+ // Method value.
+ // v.typ describes the receiver, not the method type.
+ i := int(v.flag) >> flagMethodShift
+ if v.typ().Kind() == abi.Interface {
+ // Method on interface.
+ tt := (*interfaceType)(unsafe.Pointer(typ))
+ if uint(i) >= uint(len(tt.Methods)) {
+ panic("reflect: internal error: invalid method index")
+ }
+ m := &tt.Methods[i]
+ return toRType(typeOffFor(typ, m.Typ))
+ }
+ // Method on concrete type.
+ ms := typ.ExportedMethods()
+ if uint(i) >= uint(len(ms)) {
+ panic("reflect: internal error: invalid method index")
+ }
+ m := ms[i]
+ return toRType(typeOffFor(typ, m.Mtyp))
+}
+
+// CanUint reports whether Uint can be used without panicking.
+func (v Value) CanUint() bool {
+ switch v.kind() {
+ case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+ return true
+ default:
+ return false
+ }
+}
+
+// Uint returns v's underlying value, as a uint64.
+// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
+func (v Value) Uint() uint64 {
+ k := v.kind()
+ p := v.ptr
+ switch k {
+ case Uint:
+ return uint64(*(*uint)(p))
+ case Uint8:
+ return uint64(*(*uint8)(p))
+ case Uint16:
+ return uint64(*(*uint16)(p))
+ case Uint32:
+ return uint64(*(*uint32)(p))
+ case Uint64:
+ return *(*uint64)(p)
+ case Uintptr:
+ return uint64(*(*uintptr)(p))
+ }
+ panic(&ValueError{"reflect.Value.Uint", v.kind()})
+}
+
+//go:nocheckptr
+// This prevents inlining Value.UnsafeAddr when -d=checkptr is enabled,
+// which ensures cmd/compile can recognize unsafe.Pointer(v.UnsafeAddr())
+// and make an exception.
+
+// UnsafeAddr returns a pointer to v's data, as a uintptr.
+// It panics if v is not addressable.
+//
+// It's preferred to use uintptr(Value.Addr().UnsafePointer()) to get the equivalent result.
+func (v Value) UnsafeAddr() uintptr {
+ if v.typ() == nil {
+ panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
+ }
+ if v.flag&flagAddr == 0 {
+ panic("reflect.Value.UnsafeAddr of unaddressable value")
+ }
+ // The compiler loses track as it converts to uintptr. Force escape.
+ escapes(v.ptr)
+ return uintptr(v.ptr)
+}
+
+// UnsafePointer returns v's value as a [unsafe.Pointer].
+// It panics if v's Kind is not Chan, Func, Map, Pointer, Slice, or UnsafePointer.
+//
+// If v's Kind is Func, the returned pointer is an underlying
+// code pointer, but not necessarily enough to identify a
+// single function uniquely. The only guarantee is that the
+// result is zero if and only if v is a nil func Value.
+//
+// If v's Kind is Slice, the returned pointer is to the first
+// element of the slice. If the slice is nil the returned value
+// is nil. If the slice is empty but non-nil the return value is non-nil.
+func (v Value) UnsafePointer() unsafe.Pointer {
+ k := v.kind()
+ switch k {
+ case Pointer:
+ if v.typ().PtrBytes == 0 {
+ // Since it is a not-in-heap pointer, all pointers to the heap are
+ // forbidden! See comment in Value.Elem and issue #48399.
+ if !verifyNotInHeapPtr(*(*uintptr)(v.ptr)) {
+ panic("reflect: reflect.Value.UnsafePointer on an invalid notinheap pointer")
+ }
+ return *(*unsafe.Pointer)(v.ptr)
+ }
+ fallthrough
+ case Chan, Map, UnsafePointer:
+ return v.pointer()
+ case Func:
+ if v.flag&flagMethod != 0 {
+ // As the doc comment says, the returned pointer is an
+ // underlying code pointer but not necessarily enough to
+ // identify a single function uniquely. All method expressions
+ // created via reflect have the same underlying code pointer,
+ // so their Pointers are equal. The function used here must
+ // match the one used in makeMethodValue.
+ code := methodValueCallCodePtr()
+ return *(*unsafe.Pointer)(unsafe.Pointer(&code))
+ }
+ p := v.pointer()
+ // Non-nil func value points at data block.
+ // First word of data block is actual code.
+ if p != nil {
+ p = *(*unsafe.Pointer)(p)
+ }
+ return p
+
+ case Slice:
+ return (*unsafeheader.Slice)(v.ptr).Data
+ }
+ panic(&ValueError{"reflect.Value.UnsafePointer", v.kind()})
+}
+
+// StringHeader is the runtime representation of a string.
+// It cannot be used safely or portably and its representation may
+// change in a later release.
+// Moreover, the Data field is not sufficient to guarantee the data
+// it references will not be garbage collected, so programs must keep
+// a separate, correctly typed pointer to the underlying data.
+//
+// Deprecated: Use unsafe.String or unsafe.StringData instead.
+type StringHeader struct {
+ Data uintptr
+ Len int
+}
+
+// SliceHeader is the runtime representation of a slice.
+// It cannot be used safely or portably and its representation may
+// change in a later release.
+// Moreover, the Data field is not sufficient to guarantee the data
+// it references will not be garbage collected, so programs must keep
+// a separate, correctly typed pointer to the underlying data.
+//
+// Deprecated: Use unsafe.Slice or unsafe.SliceData instead.
+type SliceHeader struct {
+ Data uintptr
+ Len int
+ Cap int
+}
+
+func typesMustMatch(what string, t1, t2 Type) {
+ if t1 != t2 {
+ panic(what + ": " + t1.String() + " != " + t2.String())
+ }
+}
+
+// arrayAt returns the i-th element of p,
+// an array whose elements are eltSize bytes wide.
+// The array pointed at by p must have at least i+1 elements:
+// it is invalid (but impossible to check here) to pass i >= len,
+// because then the result will point outside the array.
+// whySafe must explain why i < len. (Passing "i < len" is fine;
+// the benefit is to surface this assumption at the call site.)
+func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer {
+ return add(p, uintptr(i)*eltSize, "i < len")
+}
+
+// Grow increases the slice's capacity, if necessary, to guarantee space for
+// another n elements. After Grow(n), at least n elements can be appended
+// to the slice without another allocation.
+//
+// It panics if v's Kind is not a Slice or if n is negative or too large to
+// allocate the memory.
+func (v Value) Grow(n int) {
+ v.mustBeAssignable()
+ v.mustBe(Slice)
+ v.grow(n)
+}
+
+// grow is identical to Grow but does not check for assignability.
+func (v Value) grow(n int) {
+ p := (*unsafeheader.Slice)(v.ptr)
+ switch {
+ case n < 0:
+ panic("reflect.Value.Grow: negative len")
+ case p.Len+n < 0:
+ panic("reflect.Value.Grow: slice overflow")
+ case p.Len+n > p.Cap:
+ t := v.typ().Elem()
+ *p = growslice(t, *p, n)
+ }
+}
+
+// extendSlice extends a slice by n elements.
+//
+// Unlike Value.grow, which modifies the slice in place and
+// does not change the length of the slice in place,
+// extendSlice returns a new slice value with the length
+// incremented by the number of specified elements.
+func (v Value) extendSlice(n int) Value {
+ v.mustBeExported()
+ v.mustBe(Slice)
+
+ // Shallow copy the slice header to avoid mutating the source slice.
+ sh := *(*unsafeheader.Slice)(v.ptr)
+ s := &sh
+ v.ptr = unsafe.Pointer(s)
+ v.flag = flagIndir | flag(Slice) // equivalent flag to MakeSlice
+
+ v.grow(n) // fine to treat as assignable since we allocate a new slice header
+ s.Len += n
+ return v
+}
+
+// Clear clears the contents of a map or zeros the contents of a slice.
+//
+// It panics if v's Kind is not Map or Slice.
+func (v Value) Clear() {
+ switch v.Kind() {
+ case Slice:
+ sh := *(*unsafeheader.Slice)(v.ptr)
+ st := (*sliceType)(unsafe.Pointer(v.typ()))
+ typedarrayclear(st.Elem, sh.Data, sh.Len)
+ case Map:
+ mapclear(v.typ(), v.pointer())
+ default:
+ panic(&ValueError{"reflect.Value.Clear", v.Kind()})
+ }
+}
+
+// Append appends the values x to a slice s and returns the resulting slice.
+// As in Go, each x's value must be assignable to the slice's element type.
+func Append(s Value, x ...Value) Value {
+ s.mustBe(Slice)
+ n := s.Len()
+ s = s.extendSlice(len(x))
+ for i, v := range x {
+ s.Index(n + i).Set(v)
+ }
+ return s
+}
+
+// AppendSlice appends a slice t to a slice s and returns the resulting slice.
+// The slices s and t must have the same element type.
+func AppendSlice(s, t Value) Value {
+ s.mustBe(Slice)
+ t.mustBe(Slice)
+ typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
+ ns := s.Len()
+ nt := t.Len()
+ s = s.extendSlice(nt)
+ Copy(s.Slice(ns, ns+nt), t)
+ return s
+}
+
+// Copy copies the contents of src into dst until either
+// dst has been filled or src has been exhausted.
+// It returns the number of elements copied.
+// Dst and src each must have kind Slice or Array, and
+// dst and src must have the same element type.
+//
+// As a special case, src can have kind String if the element type of dst is kind Uint8.
+func Copy(dst, src Value) int {
+ dk := dst.kind()
+ if dk != Array && dk != Slice {
+ panic(&ValueError{"reflect.Copy", dk})
+ }
+ if dk == Array {
+ dst.mustBeAssignable()
+ }
+ dst.mustBeExported()
+
+ sk := src.kind()
+ var stringCopy bool
+ if sk != Array && sk != Slice {
+ stringCopy = sk == String && dst.typ().Elem().Kind() == abi.Uint8
+ if !stringCopy {
+ panic(&ValueError{"reflect.Copy", sk})
+ }
+ }
+ src.mustBeExported()
+
+ de := dst.typ().Elem()
+ if !stringCopy {
+ se := src.typ().Elem()
+ typesMustMatch("reflect.Copy", toType(de), toType(se))
+ }
+
+ var ds, ss unsafeheader.Slice
+ if dk == Array {
+ ds.Data = dst.ptr
+ ds.Len = dst.Len()
+ ds.Cap = ds.Len
+ } else {
+ ds = *(*unsafeheader.Slice)(dst.ptr)
+ }
+ if sk == Array {
+ ss.Data = src.ptr
+ ss.Len = src.Len()
+ ss.Cap = ss.Len
+ } else if sk == Slice {
+ ss = *(*unsafeheader.Slice)(src.ptr)
+ } else {
+ sh := *(*unsafeheader.String)(src.ptr)
+ ss.Data = sh.Data
+ ss.Len = sh.Len
+ ss.Cap = sh.Len
+ }
+
+ return typedslicecopy(de.Common(), ds, ss)
+}
+
+// A runtimeSelect is a single case passed to rselect.
+// This must match ../runtime/select.go:/runtimeSelect
+type runtimeSelect struct {
+ dir SelectDir // SelectSend, SelectRecv or SelectDefault
+ typ *rtype // channel type
+ ch unsafe.Pointer // channel
+ val unsafe.Pointer // ptr to data (SendDir) or ptr to receive buffer (RecvDir)
+}
+
+// rselect runs a select. It returns the index of the chosen case.
+// If the case was a receive, val is filled in with the received value.
+// The conventional OK bool indicates whether the receive corresponds
+// to a sent value.
+//
+// rselect generally doesn't escape the runtimeSelect slice, except
+// that for the send case the value to send needs to escape. We don't
+// have a way to represent that in the function signature. So we handle
+// that with a forced escape in function Select.
+//
+//go:noescape
+func rselect([]runtimeSelect) (chosen int, recvOK bool)
+
+// A SelectDir describes the communication direction of a select case.
+type SelectDir int
+
+// NOTE: These values must match ../runtime/select.go:/selectDir.
+
+const (
+ _ SelectDir = iota
+ SelectSend // case Chan <- Send
+ SelectRecv // case <-Chan:
+ SelectDefault // default
+)
+
+// A SelectCase describes a single case in a select operation.
+// The kind of case depends on Dir, the communication direction.
+//
+// If Dir is SelectDefault, the case represents a default case.
+// Chan and Send must be zero Values.
+//
+// If Dir is SelectSend, the case represents a send operation.
+// Normally Chan's underlying value must be a channel, and Send's underlying value must be
+// assignable to the channel's element type. As a special case, if Chan is a zero Value,
+// then the case is ignored, and the field Send will also be ignored and may be either zero
+// or non-zero.
+//
+// If Dir is SelectRecv, the case represents a receive operation.
+// Normally Chan's underlying value must be a channel and Send must be a zero Value.
+// If Chan is a zero Value, then the case is ignored, but Send must still be a zero Value.
+// When a receive operation is selected, the received Value is returned by Select.
+type SelectCase struct {
+ Dir SelectDir // direction of case
+ Chan Value // channel to use (for send or receive)
+ Send Value // value to send (for send)
+}
+
+// Select executes a select operation described by the list of cases.
+// Like the Go select statement, it blocks until at least one of the cases
+// can proceed, makes a uniform pseudo-random choice,
+// and then executes that case. It returns the index of the chosen case
+// and, if that case was a receive operation, the value received and a
+// boolean indicating whether the value corresponds to a send on the channel
+// (as opposed to a zero value received because the channel is closed).
+// Select supports a maximum of 65536 cases.
+func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
+ if len(cases) > 65536 {
+ panic("reflect.Select: too many cases (max 65536)")
+ }
+ // NOTE: Do not trust that caller is not modifying cases data underfoot.
+ // The range is safe because the caller cannot modify our copy of the len
+ // and each iteration makes its own copy of the value c.
+ var runcases []runtimeSelect
+ if len(cases) > 4 {
+ // Slice is heap allocated due to runtime dependent capacity.
+ runcases = make([]runtimeSelect, len(cases))
+ } else {
+ // Slice can be stack allocated due to constant capacity.
+ runcases = make([]runtimeSelect, len(cases), 4)
+ }
+
+ haveDefault := false
+ for i, c := range cases {
+ rc := &runcases[i]
+ rc.dir = c.Dir
+ switch c.Dir {
+ default:
+ panic("reflect.Select: invalid Dir")
+
+ case SelectDefault: // default
+ if haveDefault {
+ panic("reflect.Select: multiple default cases")
+ }
+ haveDefault = true
+ if c.Chan.IsValid() {
+ panic("reflect.Select: default case has Chan value")
+ }
+ if c.Send.IsValid() {
+ panic("reflect.Select: default case has Send value")
+ }
+
+ case SelectSend:
+ ch := c.Chan
+ if !ch.IsValid() {
+ break
+ }
+ ch.mustBe(Chan)
+ ch.mustBeExported()
+ tt := (*chanType)(unsafe.Pointer(ch.typ()))
+ if ChanDir(tt.Dir)&SendDir == 0 {
+ panic("reflect.Select: SendDir case using recv-only channel")
+ }
+ rc.ch = ch.pointer()
+ rc.typ = toRType(&tt.Type)
+ v := c.Send
+ if !v.IsValid() {
+ panic("reflect.Select: SendDir case missing Send value")
+ }
+ v.mustBeExported()
+ v = v.assignTo("reflect.Select", tt.Elem, nil)
+ if v.flag&flagIndir != 0 {
+ rc.val = v.ptr
+ } else {
+ rc.val = unsafe.Pointer(&v.ptr)
+ }
+ // The value to send needs to escape. See the comment at rselect for
+ // why we need forced escape.
+ escapes(rc.val)
+
+ case SelectRecv:
+ if c.Send.IsValid() {
+ panic("reflect.Select: RecvDir case has Send value")
+ }
+ ch := c.Chan
+ if !ch.IsValid() {
+ break
+ }
+ ch.mustBe(Chan)
+ ch.mustBeExported()
+ tt := (*chanType)(unsafe.Pointer(ch.typ()))
+ if ChanDir(tt.Dir)&RecvDir == 0 {
+ panic("reflect.Select: RecvDir case using send-only channel")
+ }
+ rc.ch = ch.pointer()
+ rc.typ = toRType(&tt.Type)
+ rc.val = unsafe_New(tt.Elem)
+ }
+ }
+
+ chosen, recvOK = rselect(runcases)
+ if runcases[chosen].dir == SelectRecv {
+ tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
+ t := tt.Elem
+ p := runcases[chosen].val
+ fl := flag(t.Kind())
+ if t.IfaceIndir() {
+ recv = Value{t, p, fl | flagIndir}
+ } else {
+ recv = Value{t, *(*unsafe.Pointer)(p), fl}
+ }
+ }
+ return chosen, recv, recvOK
+}
+
+/*
+ * constructors
+ */
+
+// implemented in package runtime
+
+//go:noescape
+func unsafe_New(*abi.Type) unsafe.Pointer
+
+//go:noescape
+func unsafe_NewArray(*abi.Type, int) unsafe.Pointer
+
+// MakeSlice creates a new zero-initialized slice value
+// for the specified slice type, length, and capacity.
+func MakeSlice(typ Type, len, cap int) Value {
+ if typ.Kind() != Slice {
+ panic("reflect.MakeSlice of non-slice type")
+ }
+ if len < 0 {
+ panic("reflect.MakeSlice: negative len")
+ }
+ if cap < 0 {
+ panic("reflect.MakeSlice: negative cap")
+ }
+ if len > cap {
+ panic("reflect.MakeSlice: len > cap")
+ }
+
+ s := unsafeheader.Slice{Data: unsafe_NewArray(&(typ.Elem().(*rtype).t), cap), Len: len, Cap: cap}
+ return Value{&typ.(*rtype).t, unsafe.Pointer(&s), flagIndir | flag(Slice)}
+}
+
+// MakeChan creates a new channel with the specified type and buffer size.
+func MakeChan(typ Type, buffer int) Value {
+ if typ.Kind() != Chan {
+ panic("reflect.MakeChan of non-chan type")
+ }
+ if buffer < 0 {
+ panic("reflect.MakeChan: negative buffer size")
+ }
+ if typ.ChanDir() != BothDir {
+ panic("reflect.MakeChan: unidirectional channel type")
+ }
+ t := typ.common()
+ ch := makechan(t, buffer)
+ return Value{t, ch, flag(Chan)}
+}
+
+// MakeMap creates a new map with the specified type.
+func MakeMap(typ Type) Value {
+ return MakeMapWithSize(typ, 0)
+}
+
+// MakeMapWithSize creates a new map with the specified type
+// and initial space for approximately n elements.
+func MakeMapWithSize(typ Type, n int) Value {
+ if typ.Kind() != Map {
+ panic("reflect.MakeMapWithSize of non-map type")
+ }
+ t := typ.common()
+ m := makemap(t, n)
+ return Value{t, m, flag(Map)}
+}
+
+// Indirect returns the value that v points to.
+// If v is a nil pointer, Indirect returns a zero Value.
+// If v is not a pointer, Indirect returns v.
+func Indirect(v Value) Value {
+ if v.Kind() != Pointer {
+ return v
+ }
+ return v.Elem()
+}
+
+// Before Go 1.21, ValueOf always escapes and a Value's content
+// is always heap allocated.
+// Set go121noForceValueEscape to true to avoid the forced escape,
+// allowing Value content to be on the stack.
+// Set go121noForceValueEscape to false for the legacy behavior
+// (for debugging).
+const go121noForceValueEscape = true
+
+// ValueOf returns a new Value initialized to the concrete value
+// stored in the interface i. ValueOf(nil) returns the zero Value.
+func ValueOf(i any) Value {
+ if i == nil {
+ return Value{}
+ }
+
+ if !go121noForceValueEscape {
+ escapes(i)
+ }
+
+ return unpackEface(i)
+}
+
+// Zero returns a Value representing the zero value for the specified type.
+// The result is different from the zero value of the Value struct,
+// which represents no value at all.
+// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
+// The returned value is neither addressable nor settable.
+func Zero(typ Type) Value {
+ if typ == nil {
+ panic("reflect: Zero(nil)")
+ }
+ t := &typ.(*rtype).t
+ fl := flag(t.Kind())
+ if t.IfaceIndir() {
+ var p unsafe.Pointer
+ if t.Size() <= maxZero {
+ p = unsafe.Pointer(&zeroVal[0])
+ } else {
+ p = unsafe_New(t)
+ }
+ return Value{t, p, fl | flagIndir}
+ }
+ return Value{t, nil, fl}
+}
+
+// must match declarations in runtime/map.go.
+const maxZero = 1024
+
+//go:linkname zeroVal runtime.zeroVal
+var zeroVal [maxZero]byte
+
+// New returns a Value representing a pointer to a new zero value
+// for the specified type. That is, the returned Value's Type is PointerTo(typ).
+func New(typ Type) Value {
+ if typ == nil {
+ panic("reflect: New(nil)")
+ }
+ t := &typ.(*rtype).t
+ pt := ptrTo(t)
+ if ifaceIndir(pt) {
+ // This is a pointer to a not-in-heap type.
+ panic("reflect: New of type that may not be allocated in heap (possibly undefined cgo C type)")
+ }
+ ptr := unsafe_New(t)
+ fl := flag(Pointer)
+ return Value{pt, ptr, fl}
+}
+
+// NewAt returns a Value representing a pointer to a value of the
+// specified type, using p as that pointer.
+func NewAt(typ Type, p unsafe.Pointer) Value {
+ fl := flag(Pointer)
+ t := typ.(*rtype)
+ return Value{t.ptrTo(), p, fl}
+}
+
+// assignTo returns a value v that can be assigned directly to dst.
+// It panics if v is not assignable to dst.
+// For a conversion to an interface type, target, if not nil,
+// is a suggested scratch space to use.
+// target must be initialized memory (or nil).
+func (v Value) assignTo(context string, dst *abi.Type, target unsafe.Pointer) Value {
+ if v.flag&flagMethod != 0 {
+ v = makeMethodValue(context, v)
+ }
+
+ switch {
+ case directlyAssignable(dst, v.typ()):
+ // Overwrite type so that they match.
+ // Same memory layout, so no harm done.
+ fl := v.flag&(flagAddr|flagIndir) | v.flag.ro()
+ fl |= flag(dst.Kind())
+ return Value{dst, v.ptr, fl}
+
+ case implements(dst, v.typ()):
+ if v.Kind() == Interface && v.IsNil() {
+ // A nil ReadWriter passed to nil Reader is OK,
+ // but using ifaceE2I below will panic.
+ // Avoid the panic by returning a nil dst (e.g., Reader) explicitly.
+ return Value{dst, nil, flag(Interface)}
+ }
+ x := valueInterface(v, false)
+ if target == nil {
+ target = unsafe_New(dst)
+ }
+ if dst.NumMethod() == 0 {
+ *(*any)(target) = x
+ } else {
+ ifaceE2I(dst, x, target)
+ }
+ return Value{dst, target, flagIndir | flag(Interface)}
+ }
+
+ // Failed.
+ panic(context + ": value of type " + stringFor(v.typ()) + " is not assignable to type " + stringFor(dst))
+}
+
+// Convert returns the value v converted to type t.
+// If the usual Go conversion rules do not allow conversion
+// of the value v to type t, or if converting v to type t panics, Convert panics.
+func (v Value) Convert(t Type) Value {
+ if v.flag&flagMethod != 0 {
+ v = makeMethodValue("Convert", v)
+ }
+ op := convertOp(t.common(), v.typ())
+ if op == nil {
+ panic("reflect.Value.Convert: value of type " + stringFor(v.typ()) + " cannot be converted to type " + t.String())
+ }
+ return op(v, t)
+}
+
+// CanConvert reports whether the value v can be converted to type t.
+// If v.CanConvert(t) returns true then v.Convert(t) will not panic.
+func (v Value) CanConvert(t Type) bool {
+ vt := v.Type()
+ if !vt.ConvertibleTo(t) {
+ return false
+ }
+ // Converting from slice to array or to pointer-to-array can panic
+ // depending on the value.
+ switch {
+ case vt.Kind() == Slice && t.Kind() == Array:
+ if t.Len() > v.Len() {
+ return false
+ }
+ case vt.Kind() == Slice && t.Kind() == Pointer && t.Elem().Kind() == Array:
+ n := t.Elem().Len()
+ if n > v.Len() {
+ return false
+ }
+ }
+ return true
+}
+
+// Comparable reports whether the value v is comparable.
+// If the type of v is an interface, this checks the dynamic type.
+// If this reports true then v.Interface() == x will not panic for any x,
+// nor will v.Equal(u) for any Value u.
+func (v Value) Comparable() bool {
+ k := v.Kind()
+ switch k {
+ case Invalid:
+ return false
+
+ case Array:
+ switch v.Type().Elem().Kind() {
+ case Interface, Array, Struct:
+ for i := 0; i < v.Type().Len(); i++ {
+ if !v.Index(i).Comparable() {
+ return false
+ }
+ }
+ return true
+ }
+ return v.Type().Comparable()
+
+ case Interface:
+ return v.Elem().Comparable()
+
+ case Struct:
+ for i := 0; i < v.NumField(); i++ {
+ if !v.Field(i).Comparable() {
+ return false
+ }
+ }
+ return true
+
+ default:
+ return v.Type().Comparable()
+ }
+}
+
+// Equal reports true if v is equal to u.
+// For two invalid values, Equal will report true.
+// For an interface value, Equal will compare the value within the interface.
+// Otherwise, If the values have different types, Equal will report false.
+// Otherwise, for arrays and structs Equal will compare each element in order,
+// and report false if it finds non-equal elements.
+// During all comparisons, if values of the same type are compared,
+// and the type is not comparable, Equal will panic.
+func (v Value) Equal(u Value) bool {
+ if v.Kind() == Interface {
+ v = v.Elem()
+ }
+ if u.Kind() == Interface {
+ u = u.Elem()
+ }
+
+ if !v.IsValid() || !u.IsValid() {
+ return v.IsValid() == u.IsValid()
+ }
+
+ if v.Kind() != u.Kind() || v.Type() != u.Type() {
+ return false
+ }
+
+ // Handle each Kind directly rather than calling valueInterface
+ // to avoid allocating.
+ switch v.Kind() {
+ default:
+ panic("reflect.Value.Equal: invalid Kind")
+ case Bool:
+ return v.Bool() == u.Bool()
+ case Int, Int8, Int16, Int32, Int64:
+ return v.Int() == u.Int()
+ case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+ return v.Uint() == u.Uint()
+ case Float32, Float64:
+ return v.Float() == u.Float()
+ case Complex64, Complex128:
+ return v.Complex() == u.Complex()
+ case String:
+ return v.String() == u.String()
+ case Chan, Pointer, UnsafePointer:
+ return v.Pointer() == u.Pointer()
+ case Array:
+ // u and v have the same type so they have the same length
+ vl := v.Len()
+ if vl == 0 {
+ // panic on [0]func()
+ if !v.Type().Elem().Comparable() {
+ break
+ }
+ return true
+ }
+ for i := 0; i < vl; i++ {
+ if !v.Index(i).Equal(u.Index(i)) {
+ return false
+ }
+ }
+ return true
+ case Struct:
+ // u and v have the same type so they have the same fields
+ nf := v.NumField()
+ for i := 0; i < nf; i++ {
+ if !v.Field(i).Equal(u.Field(i)) {
+ return false
+ }
+ }
+ return true
+ case Func, Map, Slice:
+ break
+ }
+ panic("reflect.Value.Equal: values of type " + v.Type().String() + " are not comparable")
+}
+
+// convertOp returns the function to convert a value of type src
+// to a value of type dst. If the conversion is illegal, convertOp returns nil.
+func convertOp(dst, src *abi.Type) func(Value, Type) Value {
+ switch Kind(src.Kind()) {
+ case Int, Int8, Int16, Int32, Int64:
+ switch Kind(dst.Kind()) {
+ case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+ return cvtInt
+ case Float32, Float64:
+ return cvtIntFloat
+ case String:
+ return cvtIntString
+ }
+
+ case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+ switch Kind(dst.Kind()) {
+ case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+ return cvtUint
+ case Float32, Float64:
+ return cvtUintFloat
+ case String:
+ return cvtUintString
+ }
+
+ case Float32, Float64:
+ switch Kind(dst.Kind()) {
+ case Int, Int8, Int16, Int32, Int64:
+ return cvtFloatInt
+ case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+ return cvtFloatUint
+ case Float32, Float64:
+ return cvtFloat
+ }
+
+ case Complex64, Complex128:
+ switch Kind(dst.Kind()) {
+ case Complex64, Complex128:
+ return cvtComplex
+ }
+
+ case String:
+ if dst.Kind() == abi.Slice && pkgPathFor(dst.Elem()) == "" {
+ switch Kind(dst.Elem().Kind()) {
+ case Uint8:
+ return cvtStringBytes
+ case Int32:
+ return cvtStringRunes
+ }
+ }
+
+ case Slice:
+ if dst.Kind() == abi.String && pkgPathFor(src.Elem()) == "" {
+ switch Kind(src.Elem().Kind()) {
+ case Uint8:
+ return cvtBytesString
+ case Int32:
+ return cvtRunesString
+ }
+ }
+ // "x is a slice, T is a pointer-to-array type,
+ // and the slice and array types have identical element types."
+ if dst.Kind() == abi.Pointer && dst.Elem().Kind() == abi.Array && src.Elem() == dst.Elem().Elem() {
+ return cvtSliceArrayPtr
+ }
+ // "x is a slice, T is an array type,
+ // and the slice and array types have identical element types."
+ if dst.Kind() == abi.Array && src.Elem() == dst.Elem() {
+ return cvtSliceArray
+ }
+
+ case Chan:
+ if dst.Kind() == abi.Chan && specialChannelAssignability(dst, src) {
+ return cvtDirect
+ }
+ }
+
+ // dst and src have same underlying type.
+ if haveIdenticalUnderlyingType(dst, src, false) {
+ return cvtDirect
+ }
+
+ // dst and src are non-defined pointer types with same underlying base type.
+ if dst.Kind() == abi.Pointer && nameFor(dst) == "" &&
+ src.Kind() == abi.Pointer && nameFor(src) == "" &&
+ haveIdenticalUnderlyingType(elem(dst), elem(src), false) {
+ return cvtDirect
+ }
+
+ if implements(dst, src) {
+ if src.Kind() == abi.Interface {
+ return cvtI2I
+ }
+ return cvtT2I
+ }
+
+ return nil
+}
+
+// makeInt returns a Value of type t equal to bits (possibly truncated),
+// where t is a signed or unsigned int type.
+func makeInt(f flag, bits uint64, t Type) Value {
+ typ := t.common()
+ ptr := unsafe_New(typ)
+ switch typ.Size() {
+ case 1:
+ *(*uint8)(ptr) = uint8(bits)
+ case 2:
+ *(*uint16)(ptr) = uint16(bits)
+ case 4:
+ *(*uint32)(ptr) = uint32(bits)
+ case 8:
+ *(*uint64)(ptr) = bits
+ }
+ return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
+}
+
+// makeFloat returns a Value of type t equal to v (possibly truncated to float32),
+// where t is a float32 or float64 type.
+func makeFloat(f flag, v float64, t Type) Value {
+ typ := t.common()
+ ptr := unsafe_New(typ)
+ switch typ.Size() {
+ case 4:
+ *(*float32)(ptr) = float32(v)
+ case 8:
+ *(*float64)(ptr) = v
+ }
+ return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
+}
+
+// makeFloat32 returns a Value of type t equal to v, where t is a float32 type.
+func makeFloat32(f flag, v float32, t Type) Value {
+ typ := t.common()
+ ptr := unsafe_New(typ)
+ *(*float32)(ptr) = v
+ return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
+}
+
+// makeComplex returns a Value of type t equal to v (possibly truncated to complex64),
+// where t is a complex64 or complex128 type.
+func makeComplex(f flag, v complex128, t Type) Value {
+ typ := t.common()
+ ptr := unsafe_New(typ)
+ switch typ.Size() {
+ case 8:
+ *(*complex64)(ptr) = complex64(v)
+ case 16:
+ *(*complex128)(ptr) = v
+ }
+ return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
+}
+
+func makeString(f flag, v string, t Type) Value {
+ ret := New(t).Elem()
+ ret.SetString(v)
+ ret.flag = ret.flag&^flagAddr | f
+ return ret
+}
+
+func makeBytes(f flag, v []byte, t Type) Value {
+ ret := New(t).Elem()
+ ret.SetBytes(v)
+ ret.flag = ret.flag&^flagAddr | f
+ return ret
+}
+
+func makeRunes(f flag, v []rune, t Type) Value {
+ ret := New(t).Elem()
+ ret.setRunes(v)
+ ret.flag = ret.flag&^flagAddr | f
+ return ret
+}
+
+// These conversion functions are returned by convertOp
+// for classes of conversions. For example, the first function, cvtInt,
+// takes any value v of signed int type and returns the value converted
+// to type t, where t is any signed or unsigned int type.
+
+// convertOp: intXX -> [u]intXX
+func cvtInt(v Value, t Type) Value {
+ return makeInt(v.flag.ro(), uint64(v.Int()), t)
+}
+
+// convertOp: uintXX -> [u]intXX
+func cvtUint(v Value, t Type) Value {
+ return makeInt(v.flag.ro(), v.Uint(), t)
+}
+
+// convertOp: floatXX -> intXX
+func cvtFloatInt(v Value, t Type) Value {
+ return makeInt(v.flag.ro(), uint64(int64(v.Float())), t)
+}
+
+// convertOp: floatXX -> uintXX
+func cvtFloatUint(v Value, t Type) Value {
+ return makeInt(v.flag.ro(), uint64(v.Float()), t)
+}
+
+// convertOp: intXX -> floatXX
+func cvtIntFloat(v Value, t Type) Value {
+ return makeFloat(v.flag.ro(), float64(v.Int()), t)
+}
+
+// convertOp: uintXX -> floatXX
+func cvtUintFloat(v Value, t Type) Value {
+ return makeFloat(v.flag.ro(), float64(v.Uint()), t)
+}
+
+// convertOp: floatXX -> floatXX
+func cvtFloat(v Value, t Type) Value {
+ if v.Type().Kind() == Float32 && t.Kind() == Float32 {
+ // Don't do any conversion if both types have underlying type float32.
+ // This avoids converting to float64 and back, which will
+ // convert a signaling NaN to a quiet NaN. See issue 36400.
+ return makeFloat32(v.flag.ro(), *(*float32)(v.ptr), t)
+ }
+ return makeFloat(v.flag.ro(), v.Float(), t)
+}
+
+// convertOp: complexXX -> complexXX
+func cvtComplex(v Value, t Type) Value {
+ return makeComplex(v.flag.ro(), v.Complex(), t)
+}
+
+// convertOp: intXX -> string
+func cvtIntString(v Value, t Type) Value {
+ s := "\uFFFD"
+ if x := v.Int(); int64(rune(x)) == x {
+ s = string(rune(x))
+ }
+ return makeString(v.flag.ro(), s, t)
+}
+
+// convertOp: uintXX -> string
+func cvtUintString(v Value, t Type) Value {
+ s := "\uFFFD"
+ if x := v.Uint(); uint64(rune(x)) == x {
+ s = string(rune(x))
+ }
+ return makeString(v.flag.ro(), s, t)
+}
+
+// convertOp: []byte -> string
+func cvtBytesString(v Value, t Type) Value {
+ return makeString(v.flag.ro(), string(v.Bytes()), t)
+}
+
+// convertOp: string -> []byte
+func cvtStringBytes(v Value, t Type) Value {
+ return makeBytes(v.flag.ro(), []byte(v.String()), t)
+}
+
+// convertOp: []rune -> string
+func cvtRunesString(v Value, t Type) Value {
+ return makeString(v.flag.ro(), string(v.runes()), t)
+}
+
+// convertOp: string -> []rune
+func cvtStringRunes(v Value, t Type) Value {
+ return makeRunes(v.flag.ro(), []rune(v.String()), t)
+}
+
+// convertOp: []T -> *[N]T
+func cvtSliceArrayPtr(v Value, t Type) Value {
+ n := t.Elem().Len()
+ if n > v.Len() {
+ panic("reflect: cannot convert slice with length " + itoa.Itoa(v.Len()) + " to pointer to array with length " + itoa.Itoa(n))
+ }
+ h := (*unsafeheader.Slice)(v.ptr)
+ return Value{t.common(), h.Data, v.flag&^(flagIndir|flagAddr|flagKindMask) | flag(Pointer)}
+}
+
+// convertOp: []T -> [N]T
+func cvtSliceArray(v Value, t Type) Value {
+ n := t.Len()
+ if n > v.Len() {
+ panic("reflect: cannot convert slice with length " + itoa.Itoa(v.Len()) + " to array with length " + itoa.Itoa(n))
+ }
+ h := (*unsafeheader.Slice)(v.ptr)
+ typ := t.common()
+ ptr := h.Data
+ c := unsafe_New(typ)
+ typedmemmove(typ, c, ptr)
+ ptr = c
+
+ return Value{typ, ptr, v.flag&^(flagAddr|flagKindMask) | flag(Array)}
+}
+
+// convertOp: direct copy
+func cvtDirect(v Value, typ Type) Value {
+ f := v.flag
+ t := typ.common()
+ ptr := v.ptr
+ if f&flagAddr != 0 {
+ // indirect, mutable word - make a copy
+ c := unsafe_New(t)
+ typedmemmove(t, c, ptr)
+ ptr = c
+ f &^= flagAddr
+ }
+ return Value{t, ptr, v.flag.ro() | f} // v.flag.ro()|f == f?
+}
+
+// convertOp: concrete -> interface
+func cvtT2I(v Value, typ Type) Value {
+ target := unsafe_New(typ.common())
+ x := valueInterface(v, false)
+ if typ.NumMethod() == 0 {
+ *(*any)(target) = x
+ } else {
+ ifaceE2I(typ.common(), x, target)
+ }
+ return Value{typ.common(), target, v.flag.ro() | flagIndir | flag(Interface)}
+}
+
+// convertOp: interface -> interface
+func cvtI2I(v Value, typ Type) Value {
+ if v.IsNil() {
+ ret := Zero(typ)
+ ret.flag |= v.flag.ro()
+ return ret
+ }
+ return cvtT2I(v.Elem(), typ)
+}
+
+// implemented in ../runtime
+//
+//go:noescape
+func chancap(ch unsafe.Pointer) int
+
+//go:noescape
+func chanclose(ch unsafe.Pointer)
+
+//go:noescape
+func chanlen(ch unsafe.Pointer) int
+
+// Note: some of the noescape annotations below are technically a lie,
+// but safe in the context of this package. Functions like chansend0
+// and mapassign0 don't escape the referent, but may escape anything
+// the referent points to (they do shallow copies of the referent).
+// We add a 0 to their names and wrap them in functions with the
+// proper escape behavior.
+
+//go:noescape
+func chanrecv(ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
+
+//go:noescape
+func chansend0(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
+
+func chansend(ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool {
+ contentEscapes(val)
+ return chansend0(ch, val, nb)
+}
+
+func makechan(typ *abi.Type, size int) (ch unsafe.Pointer)
+func makemap(t *abi.Type, cap int) (m unsafe.Pointer)
+
+//go:noescape
+func mapaccess(t *abi.Type, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
+
+//go:noescape
+func mapaccess_faststr(t *abi.Type, m unsafe.Pointer, key string) (val unsafe.Pointer)
+
+//go:noescape
+func mapassign0(t *abi.Type, m unsafe.Pointer, key, val unsafe.Pointer)
+
+func mapassign(t *abi.Type, m unsafe.Pointer, key, val unsafe.Pointer) {
+ contentEscapes(key)
+ contentEscapes(val)
+ mapassign0(t, m, key, val)
+}
+
+//go:noescape
+func mapassign_faststr0(t *abi.Type, m unsafe.Pointer, key string, val unsafe.Pointer)
+
+func mapassign_faststr(t *abi.Type, m unsafe.Pointer, key string, val unsafe.Pointer) {
+ contentEscapes((*unsafeheader.String)(unsafe.Pointer(&key)).Data)
+ contentEscapes(val)
+ mapassign_faststr0(t, m, key, val)
+}
+
+//go:noescape
+func mapdelete(t *abi.Type, m unsafe.Pointer, key unsafe.Pointer)
+
+//go:noescape
+func mapdelete_faststr(t *abi.Type, m unsafe.Pointer, key string)
+
+//go:noescape
+func mapiterinit(t *abi.Type, m unsafe.Pointer, it *hiter)
+
+//go:noescape
+func mapiterkey(it *hiter) (key unsafe.Pointer)
+
+//go:noescape
+func mapiterelem(it *hiter) (elem unsafe.Pointer)
+
+//go:noescape
+func mapiternext(it *hiter)
+
+//go:noescape
+func maplen(m unsafe.Pointer) int
+
+func mapclear(t *abi.Type, m unsafe.Pointer)
+
+// call calls fn with "stackArgsSize" bytes of stack arguments laid out
+// at stackArgs and register arguments laid out in regArgs. frameSize is
+// the total amount of stack space that will be reserved by call, so this
+// should include enough space to spill register arguments to the stack in
+// case of preemption.
+//
+// After fn returns, call copies stackArgsSize-stackRetOffset result bytes
+// back into stackArgs+stackRetOffset before returning, for any return
+// values passed on the stack. Register-based return values will be found
+// in the same regArgs structure.
+//
+// regArgs must also be prepared with an appropriate ReturnIsPtr bitmap
+// indicating which registers will contain pointer-valued return values. The
+// purpose of this bitmap is to keep pointers visible to the GC between
+// returning from reflectcall and actually using them.
+//
+// If copying result bytes back from the stack, the caller must pass the
+// argument frame type as stackArgsType, so that call can execute appropriate
+// write barriers during the copy.
+//
+// Arguments passed through to call do not escape. The type is used only in a
+// very limited callee of call, the stackArgs are copied, and regArgs is only
+// used in the call frame.
+//
+//go:noescape
+//go:linkname call runtime.reflectcall
+func call(stackArgsType *abi.Type, f, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+
+func ifaceE2I(t *abi.Type, src any, dst unsafe.Pointer)
+
+// memmove copies size bytes to dst from src. No write barriers are used.
+//
+//go:noescape
+func memmove(dst, src unsafe.Pointer, size uintptr)
+
+// typedmemmove copies a value of type t to dst from src.
+//
+//go:noescape
+func typedmemmove(t *abi.Type, dst, src unsafe.Pointer)
+
+// typedmemclr zeros the value at ptr of type t.
+//
+//go:noescape
+func typedmemclr(t *abi.Type, ptr unsafe.Pointer)
+
+// typedmemclrpartial is like typedmemclr but assumes that
+// dst points off bytes into the value and only clears size bytes.
+//
+//go:noescape
+func typedmemclrpartial(t *abi.Type, ptr unsafe.Pointer, off, size uintptr)
+
+// typedslicecopy copies a slice of elemType values from src to dst,
+// returning the number of elements copied.
+//
+//go:noescape
+func typedslicecopy(t *abi.Type, dst, src unsafeheader.Slice) int
+
+// typedarrayclear zeroes the value at ptr of an array of elemType,
+// only clears len elem.
+//
+//go:noescape
+func typedarrayclear(elemType *abi.Type, ptr unsafe.Pointer, len int)
+
+//go:noescape
+func typehash(t *abi.Type, p unsafe.Pointer, h uintptr) uintptr
+
+func verifyNotInHeapPtr(p uintptr) bool
+
+//go:noescape
+func growslice(t *abi.Type, old unsafeheader.Slice, num int) unsafeheader.Slice
+
+// Dummy annotation marking that the value x escapes,
+// for use in cases where the reflect code is so clever that
+// the compiler cannot follow.
+func escapes(x any) {
+ if dummy.b {
+ dummy.x = x
+ }
+}
+
+var dummy struct {
+ b bool
+ x any
+}
+
+// Dummy annotation marking that the content of value x
+// escapes (i.e. modeling roughly heap=*x),
+// for use in cases where the reflect code is so clever that
+// the compiler cannot follow.
+func contentEscapes(x unsafe.Pointer) {
+ if dummy.b {
+ escapes(*(*any)(x)) // the dereference may not always be safe, but never executed
+ }
+}
+
+//go:nosplit
+func noescape(p unsafe.Pointer) unsafe.Pointer {
+ x := uintptr(p)
+ return unsafe.Pointer(x ^ 0)
+}
diff --git a/contrib/go/_std_1.20/src/reflect/visiblefields.go b/contrib/go/_std_1.21/src/reflect/visiblefields.go
index 9375faa110..9375faa110 100644
--- a/contrib/go/_std_1.20/src/reflect/visiblefields.go
+++ b/contrib/go/_std_1.21/src/reflect/visiblefields.go
diff --git a/contrib/go/_std_1.21/src/reflect/ya.make b/contrib/go/_std_1.21/src/reflect/ya.make
new file mode 100644
index 0000000000..e513e677d0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/reflect/ya.make
@@ -0,0 +1,43 @@
+GO_LIBRARY()
+
+SRCS(
+ abi.go
+ deepequal.go
+ float32reg_generic.go
+ makefunc.go
+ swapper.go
+ type.go
+ value.go
+ visiblefields.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ abi_test.go
+ all_test.go
+ benchmark_test.go
+ example_test.go
+ nih_test.go
+ set_test.go
+ tostring_test.go
+ visiblefields_test.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ asm_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ asm_arm64.s
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+ internal
+)
diff --git a/contrib/go/_std_1.20/src/regexp/backtrack.go b/contrib/go/_std_1.21/src/regexp/backtrack.go
index 0739f5ff58..0739f5ff58 100644
--- a/contrib/go/_std_1.20/src/regexp/backtrack.go
+++ b/contrib/go/_std_1.21/src/regexp/backtrack.go
diff --git a/contrib/go/_std_1.20/src/regexp/exec.go b/contrib/go/_std_1.21/src/regexp/exec.go
index 3fc4b684fe..3fc4b684fe 100644
--- a/contrib/go/_std_1.20/src/regexp/exec.go
+++ b/contrib/go/_std_1.21/src/regexp/exec.go
diff --git a/contrib/go/_std_1.20/src/regexp/onepass.go b/contrib/go/_std_1.21/src/regexp/onepass.go
index b3066e88ee..b3066e88ee 100644
--- a/contrib/go/_std_1.20/src/regexp/onepass.go
+++ b/contrib/go/_std_1.21/src/regexp/onepass.go
diff --git a/contrib/go/_std_1.21/src/regexp/regexp.go b/contrib/go/_std_1.21/src/regexp/regexp.go
new file mode 100644
index 0000000000..1c9b2fd4de
--- /dev/null
+++ b/contrib/go/_std_1.21/src/regexp/regexp.go
@@ -0,0 +1,1306 @@
+// Copyright 2009 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 regexp implements regular expression search.
+//
+// The syntax of the regular expressions accepted is the same
+// general syntax used by Perl, Python, and other languages.
+// More precisely, it is the syntax accepted by RE2 and described at
+// https://golang.org/s/re2syntax, except for \C.
+// For an overview of the syntax, run
+//
+// go doc regexp/syntax
+//
+// The regexp implementation provided by this package is
+// guaranteed to run in time linear in the size of the input.
+// (This is a property not guaranteed by most open source
+// implementations of regular expressions.) For more information
+// about this property, see
+//
+// https://swtch.com/~rsc/regexp/regexp1.html
+//
+// or any book about automata theory.
+//
+// All characters are UTF-8-encoded code points.
+// Following utf8.DecodeRune, each byte of an invalid UTF-8 sequence
+// is treated as if it encoded utf8.RuneError (U+FFFD).
+//
+// There are 16 methods of Regexp that match a regular expression and identify
+// the matched text. Their names are matched by this regular expression:
+//
+// Find(All)?(String)?(Submatch)?(Index)?
+//
+// If 'All' is present, the routine matches successive non-overlapping
+// matches of the entire expression. Empty matches abutting a preceding
+// match are ignored. The return value is a slice containing the successive
+// return values of the corresponding non-'All' routine. These routines take
+// an extra integer argument, n. If n >= 0, the function returns at most n
+// matches/submatches; otherwise, it returns all of them.
+//
+// If 'String' is present, the argument is a string; otherwise it is a slice
+// of bytes; return values are adjusted as appropriate.
+//
+// If 'Submatch' is present, the return value is a slice identifying the
+// successive submatches of the expression. Submatches are matches of
+// parenthesized subexpressions (also known as capturing groups) within the
+// regular expression, numbered from left to right in order of opening
+// parenthesis. Submatch 0 is the match of the entire expression, submatch 1 is
+// the match of the first parenthesized subexpression, and so on.
+//
+// If 'Index' is present, matches and submatches are identified by byte index
+// pairs within the input string: result[2*n:2*n+2] identifies the indexes of
+// the nth submatch. The pair for n==0 identifies the match of the entire
+// expression. If 'Index' is not present, the match is identified by the text
+// of the match/submatch. If an index is negative or text is nil, it means that
+// subexpression did not match any string in the input. For 'String' versions
+// an empty string means either no match or an empty match.
+//
+// There is also a subset of the methods that can be applied to text read
+// from a RuneReader:
+//
+// MatchReader, FindReaderIndex, FindReaderSubmatchIndex
+//
+// This set may grow. Note that regular expression matches may need to
+// examine text beyond the text returned by a match, so the methods that
+// match text from a RuneReader may read arbitrarily far into the input
+// before returning.
+//
+// (There are a few other methods that do not match this pattern.)
+package regexp
+
+import (
+ "bytes"
+ "io"
+ "regexp/syntax"
+ "strconv"
+ "strings"
+ "sync"
+ "unicode"
+ "unicode/utf8"
+)
+
+// Regexp is the representation of a compiled regular expression.
+// A Regexp is safe for concurrent use by multiple goroutines,
+// except for configuration methods, such as Longest.
+type Regexp struct {
+ expr string // as passed to Compile
+ prog *syntax.Prog // compiled program
+ onepass *onePassProg // onepass program or nil
+ numSubexp int
+ maxBitStateLen int
+ subexpNames []string
+ prefix string // required prefix in unanchored matches
+ prefixBytes []byte // prefix, as a []byte
+ prefixRune rune // first rune in prefix
+ prefixEnd uint32 // pc for last rune in prefix
+ mpool int // pool for machines
+ matchcap int // size of recorded match lengths
+ prefixComplete bool // prefix is the entire regexp
+ cond syntax.EmptyOp // empty-width conditions required at start of match
+ minInputLen int // minimum length of the input in bytes
+
+ // This field can be modified by the Longest method,
+ // but it is otherwise read-only.
+ longest bool // whether regexp prefers leftmost-longest match
+}
+
+// String returns the source text used to compile the regular expression.
+func (re *Regexp) String() string {
+ return re.expr
+}
+
+// Copy returns a new Regexp object copied from re.
+// Calling Longest on one copy does not affect another.
+//
+// Deprecated: In earlier releases, when using a Regexp in multiple goroutines,
+// giving each goroutine its own copy helped to avoid lock contention.
+// As of Go 1.12, using Copy is no longer necessary to avoid lock contention.
+// Copy may still be appropriate if the reason for its use is to make
+// two copies with different Longest settings.
+func (re *Regexp) Copy() *Regexp {
+ re2 := *re
+ return &re2
+}
+
+// Compile parses a regular expression and returns, if successful,
+// a Regexp object that can be used to match against text.
+//
+// When matching against text, the regexp returns a match that
+// begins as early as possible in the input (leftmost), and among those
+// it chooses the one that a backtracking search would have found first.
+// This so-called leftmost-first matching is the same semantics
+// that Perl, Python, and other implementations use, although this
+// package implements it without the expense of backtracking.
+// For POSIX leftmost-longest matching, see CompilePOSIX.
+func Compile(expr string) (*Regexp, error) {
+ return compile(expr, syntax.Perl, false)
+}
+
+// CompilePOSIX is like Compile but restricts the regular expression
+// to POSIX ERE (egrep) syntax and changes the match semantics to
+// leftmost-longest.
+//
+// That is, when matching against text, the regexp returns a match that
+// begins as early as possible in the input (leftmost), and among those
+// it chooses a match that is as long as possible.
+// This so-called leftmost-longest matching is the same semantics
+// that early regular expression implementations used and that POSIX
+// specifies.
+//
+// However, there can be multiple leftmost-longest matches, with different
+// submatch choices, and here this package diverges from POSIX.
+// Among the possible leftmost-longest matches, this package chooses
+// the one that a backtracking search would have found first, while POSIX
+// specifies that the match be chosen to maximize the length of the first
+// subexpression, then the second, and so on from left to right.
+// The POSIX rule is computationally prohibitive and not even well-defined.
+// See https://swtch.com/~rsc/regexp/regexp2.html#posix for details.
+func CompilePOSIX(expr string) (*Regexp, error) {
+ return compile(expr, syntax.POSIX, true)
+}
+
+// Longest makes future searches prefer the leftmost-longest match.
+// That is, when matching against text, the regexp returns a match that
+// begins as early as possible in the input (leftmost), and among those
+// it chooses a match that is as long as possible.
+// This method modifies the Regexp and may not be called concurrently
+// with any other methods.
+func (re *Regexp) Longest() {
+ re.longest = true
+}
+
+func compile(expr string, mode syntax.Flags, longest bool) (*Regexp, error) {
+ re, err := syntax.Parse(expr, mode)
+ if err != nil {
+ return nil, err
+ }
+ maxCap := re.MaxCap()
+ capNames := re.CapNames()
+
+ re = re.Simplify()
+ prog, err := syntax.Compile(re)
+ if err != nil {
+ return nil, err
+ }
+ matchcap := prog.NumCap
+ if matchcap < 2 {
+ matchcap = 2
+ }
+ regexp := &Regexp{
+ expr: expr,
+ prog: prog,
+ onepass: compileOnePass(prog),
+ numSubexp: maxCap,
+ subexpNames: capNames,
+ cond: prog.StartCond(),
+ longest: longest,
+ matchcap: matchcap,
+ minInputLen: minInputLen(re),
+ }
+ if regexp.onepass == nil {
+ regexp.prefix, regexp.prefixComplete = prog.Prefix()
+ regexp.maxBitStateLen = maxBitStateLen(prog)
+ } else {
+ regexp.prefix, regexp.prefixComplete, regexp.prefixEnd = onePassPrefix(prog)
+ }
+ if regexp.prefix != "" {
+ // TODO(rsc): Remove this allocation by adding
+ // IndexString to package bytes.
+ regexp.prefixBytes = []byte(regexp.prefix)
+ regexp.prefixRune, _ = utf8.DecodeRuneInString(regexp.prefix)
+ }
+
+ n := len(prog.Inst)
+ i := 0
+ for matchSize[i] != 0 && matchSize[i] < n {
+ i++
+ }
+ regexp.mpool = i
+
+ return regexp, nil
+}
+
+// Pools of *machine for use during (*Regexp).doExecute,
+// split up by the size of the execution queues.
+// matchPool[i] machines have queue size matchSize[i].
+// On a 64-bit system each queue entry is 16 bytes,
+// so matchPool[0] has 16*2*128 = 4kB queues, etc.
+// The final matchPool is a catch-all for very large queues.
+var (
+ matchSize = [...]int{128, 512, 2048, 16384, 0}
+ matchPool [len(matchSize)]sync.Pool
+)
+
+// get returns a machine to use for matching re.
+// It uses the re's machine cache if possible, to avoid
+// unnecessary allocation.
+func (re *Regexp) get() *machine {
+ m, ok := matchPool[re.mpool].Get().(*machine)
+ if !ok {
+ m = new(machine)
+ }
+ m.re = re
+ m.p = re.prog
+ if cap(m.matchcap) < re.matchcap {
+ m.matchcap = make([]int, re.matchcap)
+ for _, t := range m.pool {
+ t.cap = make([]int, re.matchcap)
+ }
+ }
+
+ // Allocate queues if needed.
+ // Or reallocate, for "large" match pool.
+ n := matchSize[re.mpool]
+ if n == 0 { // large pool
+ n = len(re.prog.Inst)
+ }
+ if len(m.q0.sparse) < n {
+ m.q0 = queue{make([]uint32, n), make([]entry, 0, n)}
+ m.q1 = queue{make([]uint32, n), make([]entry, 0, n)}
+ }
+ return m
+}
+
+// put returns a machine to the correct machine pool.
+func (re *Regexp) put(m *machine) {
+ m.re = nil
+ m.p = nil
+ m.inputs.clear()
+ matchPool[re.mpool].Put(m)
+}
+
+// minInputLen walks the regexp to find the minimum length of any matchable input.
+func minInputLen(re *syntax.Regexp) int {
+ switch re.Op {
+ default:
+ return 0
+ case syntax.OpAnyChar, syntax.OpAnyCharNotNL, syntax.OpCharClass:
+ return 1
+ case syntax.OpLiteral:
+ l := 0
+ for _, r := range re.Rune {
+ if r == utf8.RuneError {
+ l++
+ } else {
+ l += utf8.RuneLen(r)
+ }
+ }
+ return l
+ case syntax.OpCapture, syntax.OpPlus:
+ return minInputLen(re.Sub[0])
+ case syntax.OpRepeat:
+ return re.Min * minInputLen(re.Sub[0])
+ case syntax.OpConcat:
+ l := 0
+ for _, sub := range re.Sub {
+ l += minInputLen(sub)
+ }
+ return l
+ case syntax.OpAlternate:
+ l := minInputLen(re.Sub[0])
+ var lnext int
+ for _, sub := range re.Sub[1:] {
+ lnext = minInputLen(sub)
+ if lnext < l {
+ l = lnext
+ }
+ }
+ return l
+ }
+}
+
+// MustCompile is like Compile but panics if the expression cannot be parsed.
+// It simplifies safe initialization of global variables holding compiled regular
+// expressions.
+func MustCompile(str string) *Regexp {
+ regexp, err := Compile(str)
+ if err != nil {
+ panic(`regexp: Compile(` + quote(str) + `): ` + err.Error())
+ }
+ return regexp
+}
+
+// MustCompilePOSIX is like CompilePOSIX but panics if the expression cannot be parsed.
+// It simplifies safe initialization of global variables holding compiled regular
+// expressions.
+func MustCompilePOSIX(str string) *Regexp {
+ regexp, err := CompilePOSIX(str)
+ if err != nil {
+ panic(`regexp: CompilePOSIX(` + quote(str) + `): ` + err.Error())
+ }
+ return regexp
+}
+
+func quote(s string) string {
+ if strconv.CanBackquote(s) {
+ return "`" + s + "`"
+ }
+ return strconv.Quote(s)
+}
+
+// NumSubexp returns the number of parenthesized subexpressions in this Regexp.
+func (re *Regexp) NumSubexp() int {
+ return re.numSubexp
+}
+
+// SubexpNames returns the names of the parenthesized subexpressions
+// in this Regexp. The name for the first sub-expression is names[1],
+// so that if m is a match slice, the name for m[i] is SubexpNames()[i].
+// Since the Regexp as a whole cannot be named, names[0] is always
+// the empty string. The slice should not be modified.
+func (re *Regexp) SubexpNames() []string {
+ return re.subexpNames
+}
+
+// SubexpIndex returns the index of the first subexpression with the given name,
+// or -1 if there is no subexpression with that name.
+//
+// Note that multiple subexpressions can be written using the same name, as in
+// (?P<bob>a+)(?P<bob>b+), which declares two subexpressions named "bob".
+// In this case, SubexpIndex returns the index of the leftmost such subexpression
+// in the regular expression.
+func (re *Regexp) SubexpIndex(name string) int {
+ if name != "" {
+ for i, s := range re.subexpNames {
+ if name == s {
+ return i
+ }
+ }
+ }
+ return -1
+}
+
+const endOfText rune = -1
+
+// input abstracts different representations of the input text. It provides
+// one-character lookahead.
+type input interface {
+ step(pos int) (r rune, width int) // advance one rune
+ canCheckPrefix() bool // can we look ahead without losing info?
+ hasPrefix(re *Regexp) bool
+ index(re *Regexp, pos int) int
+ context(pos int) lazyFlag
+}
+
+// inputString scans a string.
+type inputString struct {
+ str string
+}
+
+func (i *inputString) step(pos int) (rune, int) {
+ if pos < len(i.str) {
+ c := i.str[pos]
+ if c < utf8.RuneSelf {
+ return rune(c), 1
+ }
+ return utf8.DecodeRuneInString(i.str[pos:])
+ }
+ return endOfText, 0
+}
+
+func (i *inputString) canCheckPrefix() bool {
+ return true
+}
+
+func (i *inputString) hasPrefix(re *Regexp) bool {
+ return strings.HasPrefix(i.str, re.prefix)
+}
+
+func (i *inputString) index(re *Regexp, pos int) int {
+ return strings.Index(i.str[pos:], re.prefix)
+}
+
+func (i *inputString) context(pos int) lazyFlag {
+ r1, r2 := endOfText, endOfText
+ // 0 < pos && pos <= len(i.str)
+ if uint(pos-1) < uint(len(i.str)) {
+ r1 = rune(i.str[pos-1])
+ if r1 >= utf8.RuneSelf {
+ r1, _ = utf8.DecodeLastRuneInString(i.str[:pos])
+ }
+ }
+ // 0 <= pos && pos < len(i.str)
+ if uint(pos) < uint(len(i.str)) {
+ r2 = rune(i.str[pos])
+ if r2 >= utf8.RuneSelf {
+ r2, _ = utf8.DecodeRuneInString(i.str[pos:])
+ }
+ }
+ return newLazyFlag(r1, r2)
+}
+
+// inputBytes scans a byte slice.
+type inputBytes struct {
+ str []byte
+}
+
+func (i *inputBytes) step(pos int) (rune, int) {
+ if pos < len(i.str) {
+ c := i.str[pos]
+ if c < utf8.RuneSelf {
+ return rune(c), 1
+ }
+ return utf8.DecodeRune(i.str[pos:])
+ }
+ return endOfText, 0
+}
+
+func (i *inputBytes) canCheckPrefix() bool {
+ return true
+}
+
+func (i *inputBytes) hasPrefix(re *Regexp) bool {
+ return bytes.HasPrefix(i.str, re.prefixBytes)
+}
+
+func (i *inputBytes) index(re *Regexp, pos int) int {
+ return bytes.Index(i.str[pos:], re.prefixBytes)
+}
+
+func (i *inputBytes) context(pos int) lazyFlag {
+ r1, r2 := endOfText, endOfText
+ // 0 < pos && pos <= len(i.str)
+ if uint(pos-1) < uint(len(i.str)) {
+ r1 = rune(i.str[pos-1])
+ if r1 >= utf8.RuneSelf {
+ r1, _ = utf8.DecodeLastRune(i.str[:pos])
+ }
+ }
+ // 0 <= pos && pos < len(i.str)
+ if uint(pos) < uint(len(i.str)) {
+ r2 = rune(i.str[pos])
+ if r2 >= utf8.RuneSelf {
+ r2, _ = utf8.DecodeRune(i.str[pos:])
+ }
+ }
+ return newLazyFlag(r1, r2)
+}
+
+// inputReader scans a RuneReader.
+type inputReader struct {
+ r io.RuneReader
+ atEOT bool
+ pos int
+}
+
+func (i *inputReader) step(pos int) (rune, int) {
+ if !i.atEOT && pos != i.pos {
+ return endOfText, 0
+
+ }
+ r, w, err := i.r.ReadRune()
+ if err != nil {
+ i.atEOT = true
+ return endOfText, 0
+ }
+ i.pos += w
+ return r, w
+}
+
+func (i *inputReader) canCheckPrefix() bool {
+ return false
+}
+
+func (i *inputReader) hasPrefix(re *Regexp) bool {
+ return false
+}
+
+func (i *inputReader) index(re *Regexp, pos int) int {
+ return -1
+}
+
+func (i *inputReader) context(pos int) lazyFlag {
+ return 0 // not used
+}
+
+// LiteralPrefix returns a literal string that must begin any match
+// of the regular expression re. It returns the boolean true if the
+// literal string comprises the entire regular expression.
+func (re *Regexp) LiteralPrefix() (prefix string, complete bool) {
+ return re.prefix, re.prefixComplete
+}
+
+// MatchReader reports whether the text returned by the RuneReader
+// contains any match of the regular expression re.
+func (re *Regexp) MatchReader(r io.RuneReader) bool {
+ return re.doMatch(r, nil, "")
+}
+
+// MatchString reports whether the string s
+// contains any match of the regular expression re.
+func (re *Regexp) MatchString(s string) bool {
+ return re.doMatch(nil, nil, s)
+}
+
+// Match reports whether the byte slice b
+// contains any match of the regular expression re.
+func (re *Regexp) Match(b []byte) bool {
+ return re.doMatch(nil, b, "")
+}
+
+// MatchReader reports whether the text returned by the RuneReader
+// contains any match of the regular expression pattern.
+// More complicated queries need to use Compile and the full Regexp interface.
+func MatchReader(pattern string, r io.RuneReader) (matched bool, err error) {
+ re, err := Compile(pattern)
+ if err != nil {
+ return false, err
+ }
+ return re.MatchReader(r), nil
+}
+
+// MatchString reports whether the string s
+// contains any match of the regular expression pattern.
+// More complicated queries need to use Compile and the full Regexp interface.
+func MatchString(pattern string, s string) (matched bool, err error) {
+ re, err := Compile(pattern)
+ if err != nil {
+ return false, err
+ }
+ return re.MatchString(s), nil
+}
+
+// Match reports whether the byte slice b
+// contains any match of the regular expression pattern.
+// More complicated queries need to use Compile and the full Regexp interface.
+func Match(pattern string, b []byte) (matched bool, err error) {
+ re, err := Compile(pattern)
+ if err != nil {
+ return false, err
+ }
+ return re.Match(b), nil
+}
+
+// ReplaceAllString returns a copy of src, replacing matches of the Regexp
+// with the replacement string repl. Inside repl, $ signs are interpreted as
+// in Expand, so for instance $1 represents the text of the first submatch.
+func (re *Regexp) ReplaceAllString(src, repl string) string {
+ n := 2
+ if strings.Contains(repl, "$") {
+ n = 2 * (re.numSubexp + 1)
+ }
+ b := re.replaceAll(nil, src, n, func(dst []byte, match []int) []byte {
+ return re.expand(dst, repl, nil, src, match)
+ })
+ return string(b)
+}
+
+// ReplaceAllLiteralString returns a copy of src, replacing matches of the Regexp
+// with the replacement string repl. The replacement repl is substituted directly,
+// without using Expand.
+func (re *Regexp) ReplaceAllLiteralString(src, repl string) string {
+ return string(re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte {
+ return append(dst, repl...)
+ }))
+}
+
+// ReplaceAllStringFunc returns a copy of src in which all matches of the
+// Regexp have been replaced by the return value of function repl applied
+// to the matched substring. The replacement returned by repl is substituted
+// directly, without using Expand.
+func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string {
+ b := re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte {
+ return append(dst, repl(src[match[0]:match[1]])...)
+ })
+ return string(b)
+}
+
+func (re *Regexp) replaceAll(bsrc []byte, src string, nmatch int, repl func(dst []byte, m []int) []byte) []byte {
+ lastMatchEnd := 0 // end position of the most recent match
+ searchPos := 0 // position where we next look for a match
+ var buf []byte
+ var endPos int
+ if bsrc != nil {
+ endPos = len(bsrc)
+ } else {
+ endPos = len(src)
+ }
+ if nmatch > re.prog.NumCap {
+ nmatch = re.prog.NumCap
+ }
+
+ var dstCap [2]int
+ for searchPos <= endPos {
+ a := re.doExecute(nil, bsrc, src, searchPos, nmatch, dstCap[:0])
+ if len(a) == 0 {
+ break // no more matches
+ }
+
+ // Copy the unmatched characters before this match.
+ if bsrc != nil {
+ buf = append(buf, bsrc[lastMatchEnd:a[0]]...)
+ } else {
+ buf = append(buf, src[lastMatchEnd:a[0]]...)
+ }
+
+ // Now insert a copy of the replacement string, but not for a
+ // match of the empty string immediately after another match.
+ // (Otherwise, we get double replacement for patterns that
+ // match both empty and nonempty strings.)
+ if a[1] > lastMatchEnd || a[0] == 0 {
+ buf = repl(buf, a)
+ }
+ lastMatchEnd = a[1]
+
+ // Advance past this match; always advance at least one character.
+ var width int
+ if bsrc != nil {
+ _, width = utf8.DecodeRune(bsrc[searchPos:])
+ } else {
+ _, width = utf8.DecodeRuneInString(src[searchPos:])
+ }
+ if searchPos+width > a[1] {
+ searchPos += width
+ } else if searchPos+1 > a[1] {
+ // This clause is only needed at the end of the input
+ // string. In that case, DecodeRuneInString returns width=0.
+ searchPos++
+ } else {
+ searchPos = a[1]
+ }
+ }
+
+ // Copy the unmatched characters after the last match.
+ if bsrc != nil {
+ buf = append(buf, bsrc[lastMatchEnd:]...)
+ } else {
+ buf = append(buf, src[lastMatchEnd:]...)
+ }
+
+ return buf
+}
+
+// ReplaceAll returns a copy of src, replacing matches of the Regexp
+// with the replacement text repl. Inside repl, $ signs are interpreted as
+// in Expand, so for instance $1 represents the text of the first submatch.
+func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
+ n := 2
+ if bytes.IndexByte(repl, '$') >= 0 {
+ n = 2 * (re.numSubexp + 1)
+ }
+ srepl := ""
+ b := re.replaceAll(src, "", n, func(dst []byte, match []int) []byte {
+ if len(srepl) != len(repl) {
+ srepl = string(repl)
+ }
+ return re.expand(dst, srepl, src, "", match)
+ })
+ return b
+}
+
+// ReplaceAllLiteral returns a copy of src, replacing matches of the Regexp
+// with the replacement bytes repl. The replacement repl is substituted directly,
+// without using Expand.
+func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte {
+ return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte {
+ return append(dst, repl...)
+ })
+}
+
+// ReplaceAllFunc returns a copy of src in which all matches of the
+// Regexp have been replaced by the return value of function repl applied
+// to the matched byte slice. The replacement returned by repl is substituted
+// directly, without using Expand.
+func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte {
+ return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte {
+ return append(dst, repl(src[match[0]:match[1]])...)
+ })
+}
+
+// Bitmap used by func special to check whether a character needs to be escaped.
+var specialBytes [16]byte
+
+// special reports whether byte b needs to be escaped by QuoteMeta.
+func special(b byte) bool {
+ return b < utf8.RuneSelf && specialBytes[b%16]&(1<<(b/16)) != 0
+}
+
+func init() {
+ for _, b := range []byte(`\.+*?()|[]{}^$`) {
+ specialBytes[b%16] |= 1 << (b / 16)
+ }
+}
+
+// QuoteMeta returns a string that escapes all regular expression metacharacters
+// inside the argument text; the returned string is a regular expression matching
+// the literal text.
+func QuoteMeta(s string) string {
+ // A byte loop is correct because all metacharacters are ASCII.
+ var i int
+ for i = 0; i < len(s); i++ {
+ if special(s[i]) {
+ break
+ }
+ }
+ // No meta characters found, so return original string.
+ if i >= len(s) {
+ return s
+ }
+
+ b := make([]byte, 2*len(s)-i)
+ copy(b, s[:i])
+ j := i
+ for ; i < len(s); i++ {
+ if special(s[i]) {
+ b[j] = '\\'
+ j++
+ }
+ b[j] = s[i]
+ j++
+ }
+ return string(b[:j])
+}
+
+// The number of capture values in the program may correspond
+// to fewer capturing expressions than are in the regexp.
+// For example, "(a){0}" turns into an empty program, so the
+// maximum capture in the program is 0 but we need to return
+// an expression for \1. Pad appends -1s to the slice a as needed.
+func (re *Regexp) pad(a []int) []int {
+ if a == nil {
+ // No match.
+ return nil
+ }
+ n := (1 + re.numSubexp) * 2
+ for len(a) < n {
+ a = append(a, -1)
+ }
+ return a
+}
+
+// allMatches calls deliver at most n times
+// with the location of successive matches in the input text.
+// The input text is b if non-nil, otherwise s.
+func (re *Regexp) allMatches(s string, b []byte, n int, deliver func([]int)) {
+ var end int
+ if b == nil {
+ end = len(s)
+ } else {
+ end = len(b)
+ }
+
+ for pos, i, prevMatchEnd := 0, 0, -1; i < n && pos <= end; {
+ matches := re.doExecute(nil, b, s, pos, re.prog.NumCap, nil)
+ if len(matches) == 0 {
+ break
+ }
+
+ accept := true
+ if matches[1] == pos {
+ // We've found an empty match.
+ if matches[0] == prevMatchEnd {
+ // We don't allow an empty match right
+ // after a previous match, so ignore it.
+ accept = false
+ }
+ var width int
+ if b == nil {
+ is := inputString{str: s}
+ _, width = is.step(pos)
+ } else {
+ ib := inputBytes{str: b}
+ _, width = ib.step(pos)
+ }
+ if width > 0 {
+ pos += width
+ } else {
+ pos = end + 1
+ }
+ } else {
+ pos = matches[1]
+ }
+ prevMatchEnd = matches[1]
+
+ if accept {
+ deliver(re.pad(matches))
+ i++
+ }
+ }
+}
+
+// Find returns a slice holding the text of the leftmost match in b of the regular expression.
+// A return value of nil indicates no match.
+func (re *Regexp) Find(b []byte) []byte {
+ var dstCap [2]int
+ a := re.doExecute(nil, b, "", 0, 2, dstCap[:0])
+ if a == nil {
+ return nil
+ }
+ return b[a[0]:a[1]:a[1]]
+}
+
+// FindIndex returns a two-element slice of integers defining the location of
+// the leftmost match in b of the regular expression. The match itself is at
+// b[loc[0]:loc[1]].
+// A return value of nil indicates no match.
+func (re *Regexp) FindIndex(b []byte) (loc []int) {
+ a := re.doExecute(nil, b, "", 0, 2, nil)
+ if a == nil {
+ return nil
+ }
+ return a[0:2]
+}
+
+// FindString returns a string holding the text of the leftmost match in s of the regular
+// expression. If there is no match, the return value is an empty string,
+// but it will also be empty if the regular expression successfully matches
+// an empty string. Use FindStringIndex or FindStringSubmatch if it is
+// necessary to distinguish these cases.
+func (re *Regexp) FindString(s string) string {
+ var dstCap [2]int
+ a := re.doExecute(nil, nil, s, 0, 2, dstCap[:0])
+ if a == nil {
+ return ""
+ }
+ return s[a[0]:a[1]]
+}
+
+// FindStringIndex returns a two-element slice of integers defining the
+// location of the leftmost match in s of the regular expression. The match
+// itself is at s[loc[0]:loc[1]].
+// A return value of nil indicates no match.
+func (re *Regexp) FindStringIndex(s string) (loc []int) {
+ a := re.doExecute(nil, nil, s, 0, 2, nil)
+ if a == nil {
+ return nil
+ }
+ return a[0:2]
+}
+
+// FindReaderIndex returns a two-element slice of integers defining the
+// location of the leftmost match of the regular expression in text read from
+// the RuneReader. The match text was found in the input stream at
+// byte offset loc[0] through loc[1]-1.
+// A return value of nil indicates no match.
+func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int) {
+ a := re.doExecute(r, nil, "", 0, 2, nil)
+ if a == nil {
+ return nil
+ }
+ return a[0:2]
+}
+
+// FindSubmatch returns a slice of slices holding the text of the leftmost
+// match of the regular expression in b and the matches, if any, of its
+// subexpressions, as defined by the 'Submatch' descriptions in the package
+// comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindSubmatch(b []byte) [][]byte {
+ var dstCap [4]int
+ a := re.doExecute(nil, b, "", 0, re.prog.NumCap, dstCap[:0])
+ if a == nil {
+ return nil
+ }
+ ret := make([][]byte, 1+re.numSubexp)
+ for i := range ret {
+ if 2*i < len(a) && a[2*i] >= 0 {
+ ret[i] = b[a[2*i]:a[2*i+1]:a[2*i+1]]
+ }
+ }
+ return ret
+}
+
+// Expand appends template to dst and returns the result; during the
+// append, Expand replaces variables in the template with corresponding
+// matches drawn from src. The match slice should have been returned by
+// FindSubmatchIndex.
+//
+// In the template, a variable is denoted by a substring of the form
+// $name or ${name}, where name is a non-empty sequence of letters,
+// digits, and underscores. A purely numeric name like $1 refers to
+// the submatch with the corresponding index; other names refer to
+// capturing parentheses named with the (?P<name>...) syntax. A
+// reference to an out of range or unmatched index or a name that is not
+// present in the regular expression is replaced with an empty slice.
+//
+// In the $name form, name is taken to be as long as possible: $1x is
+// equivalent to ${1x}, not ${1}x, and, $10 is equivalent to ${10}, not ${1}0.
+//
+// To insert a literal $ in the output, use $$ in the template.
+func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte {
+ return re.expand(dst, string(template), src, "", match)
+}
+
+// ExpandString is like Expand but the template and source are strings.
+// It appends to and returns a byte slice in order to give the calling
+// code control over allocation.
+func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte {
+ return re.expand(dst, template, nil, src, match)
+}
+
+func (re *Regexp) expand(dst []byte, template string, bsrc []byte, src string, match []int) []byte {
+ for len(template) > 0 {
+ before, after, ok := strings.Cut(template, "$")
+ if !ok {
+ break
+ }
+ dst = append(dst, before...)
+ template = after
+ if template != "" && template[0] == '$' {
+ // Treat $$ as $.
+ dst = append(dst, '$')
+ template = template[1:]
+ continue
+ }
+ name, num, rest, ok := extract(template)
+ if !ok {
+ // Malformed; treat $ as raw text.
+ dst = append(dst, '$')
+ continue
+ }
+ template = rest
+ if num >= 0 {
+ if 2*num+1 < len(match) && match[2*num] >= 0 {
+ if bsrc != nil {
+ dst = append(dst, bsrc[match[2*num]:match[2*num+1]]...)
+ } else {
+ dst = append(dst, src[match[2*num]:match[2*num+1]]...)
+ }
+ }
+ } else {
+ for i, namei := range re.subexpNames {
+ if name == namei && 2*i+1 < len(match) && match[2*i] >= 0 {
+ if bsrc != nil {
+ dst = append(dst, bsrc[match[2*i]:match[2*i+1]]...)
+ } else {
+ dst = append(dst, src[match[2*i]:match[2*i+1]]...)
+ }
+ break
+ }
+ }
+ }
+ }
+ dst = append(dst, template...)
+ return dst
+}
+
+// extract returns the name from a leading "name" or "{name}" in str.
+// (The $ has already been removed by the caller.)
+// If it is a number, extract returns num set to that number; otherwise num = -1.
+func extract(str string) (name string, num int, rest string, ok bool) {
+ if str == "" {
+ return
+ }
+ brace := false
+ if str[0] == '{' {
+ brace = true
+ str = str[1:]
+ }
+ i := 0
+ for i < len(str) {
+ rune, size := utf8.DecodeRuneInString(str[i:])
+ if !unicode.IsLetter(rune) && !unicode.IsDigit(rune) && rune != '_' {
+ break
+ }
+ i += size
+ }
+ if i == 0 {
+ // empty name is not okay
+ return
+ }
+ name = str[:i]
+ if brace {
+ if i >= len(str) || str[i] != '}' {
+ // missing closing brace
+ return
+ }
+ i++
+ }
+
+ // Parse number.
+ num = 0
+ for i := 0; i < len(name); i++ {
+ if name[i] < '0' || '9' < name[i] || num >= 1e8 {
+ num = -1
+ break
+ }
+ num = num*10 + int(name[i]) - '0'
+ }
+ // Disallow leading zeros.
+ if name[0] == '0' && len(name) > 1 {
+ num = -1
+ }
+
+ rest = str[i:]
+ ok = true
+ return
+}
+
+// FindSubmatchIndex returns a slice holding the index pairs identifying the
+// leftmost match of the regular expression in b and the matches, if any, of
+// its subexpressions, as defined by the 'Submatch' and 'Index' descriptions
+// in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindSubmatchIndex(b []byte) []int {
+ return re.pad(re.doExecute(nil, b, "", 0, re.prog.NumCap, nil))
+}
+
+// FindStringSubmatch returns a slice of strings holding the text of the
+// leftmost match of the regular expression in s and the matches, if any, of
+// its subexpressions, as defined by the 'Submatch' description in the
+// package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindStringSubmatch(s string) []string {
+ var dstCap [4]int
+ a := re.doExecute(nil, nil, s, 0, re.prog.NumCap, dstCap[:0])
+ if a == nil {
+ return nil
+ }
+ ret := make([]string, 1+re.numSubexp)
+ for i := range ret {
+ if 2*i < len(a) && a[2*i] >= 0 {
+ ret[i] = s[a[2*i]:a[2*i+1]]
+ }
+ }
+ return ret
+}
+
+// FindStringSubmatchIndex returns a slice holding the index pairs
+// identifying the leftmost match of the regular expression in s and the
+// matches, if any, of its subexpressions, as defined by the 'Submatch' and
+// 'Index' descriptions in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindStringSubmatchIndex(s string) []int {
+ return re.pad(re.doExecute(nil, nil, s, 0, re.prog.NumCap, nil))
+}
+
+// FindReaderSubmatchIndex returns a slice holding the index pairs
+// identifying the leftmost match of the regular expression of text read by
+// the RuneReader, and the matches, if any, of its subexpressions, as defined
+// by the 'Submatch' and 'Index' descriptions in the package comment. A
+// return value of nil indicates no match.
+func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int {
+ return re.pad(re.doExecute(r, nil, "", 0, re.prog.NumCap, nil))
+}
+
+const startSize = 10 // The size at which to start a slice in the 'All' routines.
+
+// FindAll is the 'All' version of Find; it returns a slice of all successive
+// matches of the expression, as defined by the 'All' description in the
+// package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAll(b []byte, n int) [][]byte {
+ if n < 0 {
+ n = len(b) + 1
+ }
+ var result [][]byte
+ re.allMatches("", b, n, func(match []int) {
+ if result == nil {
+ result = make([][]byte, 0, startSize)
+ }
+ result = append(result, b[match[0]:match[1]:match[1]])
+ })
+ return result
+}
+
+// FindAllIndex is the 'All' version of FindIndex; it returns a slice of all
+// successive matches of the expression, as defined by the 'All' description
+// in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllIndex(b []byte, n int) [][]int {
+ if n < 0 {
+ n = len(b) + 1
+ }
+ var result [][]int
+ re.allMatches("", b, n, func(match []int) {
+ if result == nil {
+ result = make([][]int, 0, startSize)
+ }
+ result = append(result, match[0:2])
+ })
+ return result
+}
+
+// FindAllString is the 'All' version of FindString; it returns a slice of all
+// successive matches of the expression, as defined by the 'All' description
+// in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllString(s string, n int) []string {
+ if n < 0 {
+ n = len(s) + 1
+ }
+ var result []string
+ re.allMatches(s, nil, n, func(match []int) {
+ if result == nil {
+ result = make([]string, 0, startSize)
+ }
+ result = append(result, s[match[0]:match[1]])
+ })
+ return result
+}
+
+// FindAllStringIndex is the 'All' version of FindStringIndex; it returns a
+// slice of all successive matches of the expression, as defined by the 'All'
+// description in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllStringIndex(s string, n int) [][]int {
+ if n < 0 {
+ n = len(s) + 1
+ }
+ var result [][]int
+ re.allMatches(s, nil, n, func(match []int) {
+ if result == nil {
+ result = make([][]int, 0, startSize)
+ }
+ result = append(result, match[0:2])
+ })
+ return result
+}
+
+// FindAllSubmatch is the 'All' version of FindSubmatch; it returns a slice
+// of all successive matches of the expression, as defined by the 'All'
+// description in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte {
+ if n < 0 {
+ n = len(b) + 1
+ }
+ var result [][][]byte
+ re.allMatches("", b, n, func(match []int) {
+ if result == nil {
+ result = make([][][]byte, 0, startSize)
+ }
+ slice := make([][]byte, len(match)/2)
+ for j := range slice {
+ if match[2*j] >= 0 {
+ slice[j] = b[match[2*j]:match[2*j+1]:match[2*j+1]]
+ }
+ }
+ result = append(result, slice)
+ })
+ return result
+}
+
+// FindAllSubmatchIndex is the 'All' version of FindSubmatchIndex; it returns
+// a slice of all successive matches of the expression, as defined by the
+// 'All' description in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int {
+ if n < 0 {
+ n = len(b) + 1
+ }
+ var result [][]int
+ re.allMatches("", b, n, func(match []int) {
+ if result == nil {
+ result = make([][]int, 0, startSize)
+ }
+ result = append(result, match)
+ })
+ return result
+}
+
+// FindAllStringSubmatch is the 'All' version of FindStringSubmatch; it
+// returns a slice of all successive matches of the expression, as defined by
+// the 'All' description in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string {
+ if n < 0 {
+ n = len(s) + 1
+ }
+ var result [][]string
+ re.allMatches(s, nil, n, func(match []int) {
+ if result == nil {
+ result = make([][]string, 0, startSize)
+ }
+ slice := make([]string, len(match)/2)
+ for j := range slice {
+ if match[2*j] >= 0 {
+ slice[j] = s[match[2*j]:match[2*j+1]]
+ }
+ }
+ result = append(result, slice)
+ })
+ return result
+}
+
+// FindAllStringSubmatchIndex is the 'All' version of
+// FindStringSubmatchIndex; it returns a slice of all successive matches of
+// the expression, as defined by the 'All' description in the package
+// comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int {
+ if n < 0 {
+ n = len(s) + 1
+ }
+ var result [][]int
+ re.allMatches(s, nil, n, func(match []int) {
+ if result == nil {
+ result = make([][]int, 0, startSize)
+ }
+ result = append(result, match)
+ })
+ return result
+}
+
+// Split slices s into substrings separated by the expression and returns a slice of
+// the substrings between those expression matches.
+//
+// The slice returned by this method consists of all the substrings of s
+// not contained in the slice returned by FindAllString. When called on an expression
+// that contains no metacharacters, it is equivalent to strings.SplitN.
+//
+// Example:
+//
+// s := regexp.MustCompile("a*").Split("abaabaccadaaae", 5)
+// // s: ["", "b", "b", "c", "cadaaae"]
+//
+// The count determines the number of substrings to return:
+//
+// n > 0: at most n substrings; the last substring will be the unsplit remainder.
+// n == 0: the result is nil (zero substrings)
+// n < 0: all substrings
+func (re *Regexp) Split(s string, n int) []string {
+
+ if n == 0 {
+ return nil
+ }
+
+ if len(re.expr) > 0 && len(s) == 0 {
+ return []string{""}
+ }
+
+ matches := re.FindAllStringIndex(s, n)
+ strings := make([]string, 0, len(matches))
+
+ beg := 0
+ end := 0
+ for _, match := range matches {
+ if n > 0 && len(strings) >= n-1 {
+ break
+ }
+
+ end = match[0]
+ if match[1] != 0 {
+ strings = append(strings, s[beg:end])
+ }
+ beg = match[1]
+ }
+
+ if end != len(s) {
+ strings = append(strings, s[beg:])
+ }
+
+ return strings
+}
+
+// MarshalText implements [encoding.TextMarshaler]. The output
+// matches that of calling the [Regexp.String] method.
+//
+// Note that the output is lossy in some cases: This method does not indicate
+// POSIX regular expressions (i.e. those compiled by calling [CompilePOSIX]), or
+// those for which the [Regexp.Longest] method has been called.
+func (re *Regexp) MarshalText() ([]byte, error) {
+ return []byte(re.String()), nil
+}
+
+// UnmarshalText implements [encoding.TextUnmarshaler] by calling
+// [Compile] on the encoded value.
+func (re *Regexp) UnmarshalText(text []byte) error {
+ newRE, err := Compile(string(text))
+ if err != nil {
+ return err
+ }
+ *re = *newRE
+ return nil
+}
diff --git a/contrib/go/_std_1.20/src/regexp/syntax/compile.go b/contrib/go/_std_1.21/src/regexp/syntax/compile.go
index c9f9fa024b..c9f9fa024b 100644
--- a/contrib/go/_std_1.20/src/regexp/syntax/compile.go
+++ b/contrib/go/_std_1.21/src/regexp/syntax/compile.go
diff --git a/contrib/go/_std_1.20/src/regexp/syntax/doc.go b/contrib/go/_std_1.21/src/regexp/syntax/doc.go
index f6a4b43f7a..f6a4b43f7a 100644
--- a/contrib/go/_std_1.20/src/regexp/syntax/doc.go
+++ b/contrib/go/_std_1.21/src/regexp/syntax/doc.go
diff --git a/contrib/go/_std_1.21/src/regexp/syntax/op_string.go b/contrib/go/_std_1.21/src/regexp/syntax/op_string.go
new file mode 100644
index 0000000000..1368f5b7ea
--- /dev/null
+++ b/contrib/go/_std_1.21/src/regexp/syntax/op_string.go
@@ -0,0 +1,52 @@
+// Code generated by "stringer -type Op -trimprefix Op"; DO NOT EDIT.
+
+package syntax
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[OpNoMatch-1]
+ _ = x[OpEmptyMatch-2]
+ _ = x[OpLiteral-3]
+ _ = x[OpCharClass-4]
+ _ = x[OpAnyCharNotNL-5]
+ _ = x[OpAnyChar-6]
+ _ = x[OpBeginLine-7]
+ _ = x[OpEndLine-8]
+ _ = x[OpBeginText-9]
+ _ = x[OpEndText-10]
+ _ = x[OpWordBoundary-11]
+ _ = x[OpNoWordBoundary-12]
+ _ = x[OpCapture-13]
+ _ = x[OpStar-14]
+ _ = x[OpPlus-15]
+ _ = x[OpQuest-16]
+ _ = x[OpRepeat-17]
+ _ = x[OpConcat-18]
+ _ = x[OpAlternate-19]
+ _ = x[opPseudo-128]
+}
+
+const (
+ _Op_name_0 = "NoMatchEmptyMatchLiteralCharClassAnyCharNotNLAnyCharBeginLineEndLineBeginTextEndTextWordBoundaryNoWordBoundaryCaptureStarPlusQuestRepeatConcatAlternate"
+ _Op_name_1 = "opPseudo"
+)
+
+var (
+ _Op_index_0 = [...]uint8{0, 7, 17, 24, 33, 45, 52, 61, 68, 77, 84, 96, 110, 117, 121, 125, 130, 136, 142, 151}
+)
+
+func (i Op) String() string {
+ switch {
+ case 1 <= i && i <= 19:
+ i -= 1
+ return _Op_name_0[_Op_index_0[i]:_Op_index_0[i+1]]
+ case i == 128:
+ return _Op_name_1
+ default:
+ return "Op(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+}
diff --git a/contrib/go/_std_1.20/src/regexp/syntax/parse.go b/contrib/go/_std_1.21/src/regexp/syntax/parse.go
index accee9ab08..accee9ab08 100644
--- a/contrib/go/_std_1.20/src/regexp/syntax/parse.go
+++ b/contrib/go/_std_1.21/src/regexp/syntax/parse.go
diff --git a/contrib/go/_std_1.20/src/regexp/syntax/perl_groups.go b/contrib/go/_std_1.21/src/regexp/syntax/perl_groups.go
index effe4e6862..effe4e6862 100644
--- a/contrib/go/_std_1.20/src/regexp/syntax/perl_groups.go
+++ b/contrib/go/_std_1.21/src/regexp/syntax/perl_groups.go
diff --git a/contrib/go/_std_1.21/src/regexp/syntax/prog.go b/contrib/go/_std_1.21/src/regexp/syntax/prog.go
new file mode 100644
index 0000000000..66995e2052
--- /dev/null
+++ b/contrib/go/_std_1.21/src/regexp/syntax/prog.go
@@ -0,0 +1,349 @@
+// Copyright 2011 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 syntax
+
+import (
+ "strconv"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+)
+
+// Compiled program.
+// May not belong in this package, but convenient for now.
+
+// A Prog is a compiled regular expression program.
+type Prog struct {
+ Inst []Inst
+ Start int // index of start instruction
+ NumCap int // number of InstCapture insts in re
+}
+
+// An InstOp is an instruction opcode.
+type InstOp uint8
+
+const (
+ InstAlt InstOp = iota
+ InstAltMatch
+ InstCapture
+ InstEmptyWidth
+ InstMatch
+ InstFail
+ InstNop
+ InstRune
+ InstRune1
+ InstRuneAny
+ InstRuneAnyNotNL
+)
+
+var instOpNames = []string{
+ "InstAlt",
+ "InstAltMatch",
+ "InstCapture",
+ "InstEmptyWidth",
+ "InstMatch",
+ "InstFail",
+ "InstNop",
+ "InstRune",
+ "InstRune1",
+ "InstRuneAny",
+ "InstRuneAnyNotNL",
+}
+
+func (i InstOp) String() string {
+ if uint(i) >= uint(len(instOpNames)) {
+ return ""
+ }
+ return instOpNames[i]
+}
+
+// An EmptyOp specifies a kind or mixture of zero-width assertions.
+type EmptyOp uint8
+
+const (
+ EmptyBeginLine EmptyOp = 1 << iota
+ EmptyEndLine
+ EmptyBeginText
+ EmptyEndText
+ EmptyWordBoundary
+ EmptyNoWordBoundary
+)
+
+// EmptyOpContext returns the zero-width assertions
+// satisfied at the position between the runes r1 and r2.
+// Passing r1 == -1 indicates that the position is
+// at the beginning of the text.
+// Passing r2 == -1 indicates that the position is
+// at the end of the text.
+func EmptyOpContext(r1, r2 rune) EmptyOp {
+ var op EmptyOp = EmptyNoWordBoundary
+ var boundary byte
+ switch {
+ case IsWordChar(r1):
+ boundary = 1
+ case r1 == '\n':
+ op |= EmptyBeginLine
+ case r1 < 0:
+ op |= EmptyBeginText | EmptyBeginLine
+ }
+ switch {
+ case IsWordChar(r2):
+ boundary ^= 1
+ case r2 == '\n':
+ op |= EmptyEndLine
+ case r2 < 0:
+ op |= EmptyEndText | EmptyEndLine
+ }
+ if boundary != 0 { // IsWordChar(r1) != IsWordChar(r2)
+ op ^= (EmptyWordBoundary | EmptyNoWordBoundary)
+ }
+ return op
+}
+
+// IsWordChar reports whether r is considered a “word character”
+// during the evaluation of the \b and \B zero-width assertions.
+// These assertions are ASCII-only: the word characters are [A-Za-z0-9_].
+func IsWordChar(r rune) bool {
+ // Test for lowercase letters first, as these occur more
+ // frequently than uppercase letters in common cases.
+ return 'a' <= r && r <= 'z' || 'A' <= r && r <= 'Z' || '0' <= r && r <= '9' || r == '_'
+}
+
+// An Inst is a single instruction in a regular expression program.
+type Inst struct {
+ Op InstOp
+ Out uint32 // all but InstMatch, InstFail
+ Arg uint32 // InstAlt, InstAltMatch, InstCapture, InstEmptyWidth
+ Rune []rune
+}
+
+func (p *Prog) String() string {
+ var b strings.Builder
+ dumpProg(&b, p)
+ return b.String()
+}
+
+// skipNop follows any no-op or capturing instructions.
+func (p *Prog) skipNop(pc uint32) *Inst {
+ i := &p.Inst[pc]
+ for i.Op == InstNop || i.Op == InstCapture {
+ i = &p.Inst[i.Out]
+ }
+ return i
+}
+
+// op returns i.Op but merges all the Rune special cases into InstRune
+func (i *Inst) op() InstOp {
+ op := i.Op
+ switch op {
+ case InstRune1, InstRuneAny, InstRuneAnyNotNL:
+ op = InstRune
+ }
+ return op
+}
+
+// Prefix returns a literal string that all matches for the
+// regexp must start with. Complete is true if the prefix
+// is the entire match.
+func (p *Prog) Prefix() (prefix string, complete bool) {
+ i := p.skipNop(uint32(p.Start))
+
+ // Avoid allocation of buffer if prefix is empty.
+ if i.op() != InstRune || len(i.Rune) != 1 {
+ return "", i.Op == InstMatch
+ }
+
+ // Have prefix; gather characters.
+ var buf strings.Builder
+ for i.op() == InstRune && len(i.Rune) == 1 && Flags(i.Arg)&FoldCase == 0 && i.Rune[0] != utf8.RuneError {
+ buf.WriteRune(i.Rune[0])
+ i = p.skipNop(i.Out)
+ }
+ return buf.String(), i.Op == InstMatch
+}
+
+// StartCond returns the leading empty-width conditions that must
+// be true in any match. It returns ^EmptyOp(0) if no matches are possible.
+func (p *Prog) StartCond() EmptyOp {
+ var flag EmptyOp
+ pc := uint32(p.Start)
+ i := &p.Inst[pc]
+Loop:
+ for {
+ switch i.Op {
+ case InstEmptyWidth:
+ flag |= EmptyOp(i.Arg)
+ case InstFail:
+ return ^EmptyOp(0)
+ case InstCapture, InstNop:
+ // skip
+ default:
+ break Loop
+ }
+ pc = i.Out
+ i = &p.Inst[pc]
+ }
+ return flag
+}
+
+const noMatch = -1
+
+// MatchRune reports whether the instruction matches (and consumes) r.
+// It should only be called when i.Op == InstRune.
+func (i *Inst) MatchRune(r rune) bool {
+ return i.MatchRunePos(r) != noMatch
+}
+
+// MatchRunePos checks whether the instruction matches (and consumes) r.
+// If so, MatchRunePos returns the index of the matching rune pair
+// (or, when len(i.Rune) == 1, rune singleton).
+// If not, MatchRunePos returns -1.
+// MatchRunePos should only be called when i.Op == InstRune.
+func (i *Inst) MatchRunePos(r rune) int {
+ rune := i.Rune
+
+ switch len(rune) {
+ case 0:
+ return noMatch
+
+ case 1:
+ // Special case: single-rune slice is from literal string, not char class.
+ r0 := rune[0]
+ if r == r0 {
+ return 0
+ }
+ if Flags(i.Arg)&FoldCase != 0 {
+ for r1 := unicode.SimpleFold(r0); r1 != r0; r1 = unicode.SimpleFold(r1) {
+ if r == r1 {
+ return 0
+ }
+ }
+ }
+ return noMatch
+
+ case 2:
+ if r >= rune[0] && r <= rune[1] {
+ return 0
+ }
+ return noMatch
+
+ case 4, 6, 8:
+ // Linear search for a few pairs.
+ // Should handle ASCII well.
+ for j := 0; j < len(rune); j += 2 {
+ if r < rune[j] {
+ return noMatch
+ }
+ if r <= rune[j+1] {
+ return j / 2
+ }
+ }
+ return noMatch
+ }
+
+ // Otherwise binary search.
+ lo := 0
+ hi := len(rune) / 2
+ for lo < hi {
+ m := lo + (hi-lo)/2
+ if c := rune[2*m]; c <= r {
+ if r <= rune[2*m+1] {
+ return m
+ }
+ lo = m + 1
+ } else {
+ hi = m
+ }
+ }
+ return noMatch
+}
+
+// MatchEmptyWidth reports whether the instruction matches
+// an empty string between the runes before and after.
+// It should only be called when i.Op == InstEmptyWidth.
+func (i *Inst) MatchEmptyWidth(before rune, after rune) bool {
+ switch EmptyOp(i.Arg) {
+ case EmptyBeginLine:
+ return before == '\n' || before == -1
+ case EmptyEndLine:
+ return after == '\n' || after == -1
+ case EmptyBeginText:
+ return before == -1
+ case EmptyEndText:
+ return after == -1
+ case EmptyWordBoundary:
+ return IsWordChar(before) != IsWordChar(after)
+ case EmptyNoWordBoundary:
+ return IsWordChar(before) == IsWordChar(after)
+ }
+ panic("unknown empty width arg")
+}
+
+func (i *Inst) String() string {
+ var b strings.Builder
+ dumpInst(&b, i)
+ return b.String()
+}
+
+func bw(b *strings.Builder, args ...string) {
+ for _, s := range args {
+ b.WriteString(s)
+ }
+}
+
+func dumpProg(b *strings.Builder, p *Prog) {
+ for j := range p.Inst {
+ i := &p.Inst[j]
+ pc := strconv.Itoa(j)
+ if len(pc) < 3 {
+ b.WriteString(" "[len(pc):])
+ }
+ if j == p.Start {
+ pc += "*"
+ }
+ bw(b, pc, "\t")
+ dumpInst(b, i)
+ bw(b, "\n")
+ }
+}
+
+func u32(i uint32) string {
+ return strconv.FormatUint(uint64(i), 10)
+}
+
+func dumpInst(b *strings.Builder, i *Inst) {
+ switch i.Op {
+ case InstAlt:
+ bw(b, "alt -> ", u32(i.Out), ", ", u32(i.Arg))
+ case InstAltMatch:
+ bw(b, "altmatch -> ", u32(i.Out), ", ", u32(i.Arg))
+ case InstCapture:
+ bw(b, "cap ", u32(i.Arg), " -> ", u32(i.Out))
+ case InstEmptyWidth:
+ bw(b, "empty ", u32(i.Arg), " -> ", u32(i.Out))
+ case InstMatch:
+ bw(b, "match")
+ case InstFail:
+ bw(b, "fail")
+ case InstNop:
+ bw(b, "nop -> ", u32(i.Out))
+ case InstRune:
+ if i.Rune == nil {
+ // shouldn't happen
+ bw(b, "rune <nil>")
+ }
+ bw(b, "rune ", strconv.QuoteToASCII(string(i.Rune)))
+ if Flags(i.Arg)&FoldCase != 0 {
+ bw(b, "/i")
+ }
+ bw(b, " -> ", u32(i.Out))
+ case InstRune1:
+ bw(b, "rune1 ", strconv.QuoteToASCII(string(i.Rune)), " -> ", u32(i.Out))
+ case InstRuneAny:
+ bw(b, "any -> ", u32(i.Out))
+ case InstRuneAnyNotNL:
+ bw(b, "anynotnl -> ", u32(i.Out))
+ }
+}
diff --git a/contrib/go/_std_1.20/src/regexp/syntax/regexp.go b/contrib/go/_std_1.21/src/regexp/syntax/regexp.go
index 3a4d2d201c..3a4d2d201c 100644
--- a/contrib/go/_std_1.20/src/regexp/syntax/regexp.go
+++ b/contrib/go/_std_1.21/src/regexp/syntax/regexp.go
diff --git a/contrib/go/_std_1.20/src/regexp/syntax/simplify.go b/contrib/go/_std_1.21/src/regexp/syntax/simplify.go
index e439325139..e439325139 100644
--- a/contrib/go/_std_1.20/src/regexp/syntax/simplify.go
+++ b/contrib/go/_std_1.21/src/regexp/syntax/simplify.go
diff --git a/contrib/go/_std_1.21/src/regexp/syntax/ya.make b/contrib/go/_std_1.21/src/regexp/syntax/ya.make
new file mode 100644
index 0000000000..d33cb6e8ce
--- /dev/null
+++ b/contrib/go/_std_1.21/src/regexp/syntax/ya.make
@@ -0,0 +1,23 @@
+GO_LIBRARY()
+
+SRCS(
+ compile.go
+ doc.go
+ op_string.go
+ parse.go
+ perl_groups.go
+ prog.go
+ regexp.go
+ simplify.go
+)
+
+GO_TEST_SRCS(
+ parse_test.go
+ prog_test.go
+ simplify_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/regexp/ya.make b/contrib/go/_std_1.21/src/regexp/ya.make
new file mode 100644
index 0000000000..907550a3e1
--- /dev/null
+++ b/contrib/go/_std_1.21/src/regexp/ya.make
@@ -0,0 +1,24 @@
+GO_LIBRARY()
+
+SRCS(
+ backtrack.go
+ exec.go
+ onepass.go
+ regexp.go
+)
+
+GO_TEST_SRCS(
+ all_test.go
+ exec2_test.go
+ exec_test.go
+ find_test.go
+ onepass_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+ syntax
+)
diff --git a/contrib/go/_std_1.21/src/runtime/alg.go b/contrib/go/_std_1.21/src/runtime/alg.go
new file mode 100644
index 0000000000..a1f683f68a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/alg.go
@@ -0,0 +1,354 @@
+// Copyright 2014 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 runtime
+
+import (
+ "internal/abi"
+ "internal/cpu"
+ "internal/goarch"
+ "unsafe"
+)
+
+const (
+ c0 = uintptr((8-goarch.PtrSize)/4*2860486313 + (goarch.PtrSize-4)/4*33054211828000289)
+ c1 = uintptr((8-goarch.PtrSize)/4*3267000013 + (goarch.PtrSize-4)/4*23344194077549503)
+)
+
+func memhash0(p unsafe.Pointer, h uintptr) uintptr {
+ return h
+}
+
+func memhash8(p unsafe.Pointer, h uintptr) uintptr {
+ return memhash(p, h, 1)
+}
+
+func memhash16(p unsafe.Pointer, h uintptr) uintptr {
+ return memhash(p, h, 2)
+}
+
+func memhash128(p unsafe.Pointer, h uintptr) uintptr {
+ return memhash(p, h, 16)
+}
+
+//go:nosplit
+func memhash_varlen(p unsafe.Pointer, h uintptr) uintptr {
+ ptr := getclosureptr()
+ size := *(*uintptr)(unsafe.Pointer(ptr + unsafe.Sizeof(h)))
+ return memhash(p, h, size)
+}
+
+// runtime variable to check if the processor we're running on
+// actually supports the instructions used by the AES-based
+// hash implementation.
+var useAeshash bool
+
+// in asm_*.s
+func memhash(p unsafe.Pointer, h, s uintptr) uintptr
+func memhash32(p unsafe.Pointer, h uintptr) uintptr
+func memhash64(p unsafe.Pointer, h uintptr) uintptr
+func strhash(p unsafe.Pointer, h uintptr) uintptr
+
+func strhashFallback(a unsafe.Pointer, h uintptr) uintptr {
+ x := (*stringStruct)(a)
+ return memhashFallback(x.str, h, uintptr(x.len))
+}
+
+// NOTE: Because NaN != NaN, a map can contain any
+// number of (mostly useless) entries keyed with NaNs.
+// To avoid long hash chains, we assign a random number
+// as the hash value for a NaN.
+
+func f32hash(p unsafe.Pointer, h uintptr) uintptr {
+ f := *(*float32)(p)
+ switch {
+ case f == 0:
+ return c1 * (c0 ^ h) // +0, -0
+ case f != f:
+ return c1 * (c0 ^ h ^ uintptr(fastrand())) // any kind of NaN
+ default:
+ return memhash(p, h, 4)
+ }
+}
+
+func f64hash(p unsafe.Pointer, h uintptr) uintptr {
+ f := *(*float64)(p)
+ switch {
+ case f == 0:
+ return c1 * (c0 ^ h) // +0, -0
+ case f != f:
+ return c1 * (c0 ^ h ^ uintptr(fastrand())) // any kind of NaN
+ default:
+ return memhash(p, h, 8)
+ }
+}
+
+func c64hash(p unsafe.Pointer, h uintptr) uintptr {
+ x := (*[2]float32)(p)
+ return f32hash(unsafe.Pointer(&x[1]), f32hash(unsafe.Pointer(&x[0]), h))
+}
+
+func c128hash(p unsafe.Pointer, h uintptr) uintptr {
+ x := (*[2]float64)(p)
+ return f64hash(unsafe.Pointer(&x[1]), f64hash(unsafe.Pointer(&x[0]), h))
+}
+
+func interhash(p unsafe.Pointer, h uintptr) uintptr {
+ a := (*iface)(p)
+ tab := a.tab
+ if tab == nil {
+ return h
+ }
+ t := tab._type
+ if t.Equal == nil {
+ // Check hashability here. We could do this check inside
+ // typehash, but we want to report the topmost type in
+ // the error text (e.g. in a struct with a field of slice type
+ // we want to report the struct, not the slice).
+ panic(errorString("hash of unhashable type " + toRType(t).string()))
+ }
+ if isDirectIface(t) {
+ return c1 * typehash(t, unsafe.Pointer(&a.data), h^c0)
+ } else {
+ return c1 * typehash(t, a.data, h^c0)
+ }
+}
+
+func nilinterhash(p unsafe.Pointer, h uintptr) uintptr {
+ a := (*eface)(p)
+ t := a._type
+ if t == nil {
+ return h
+ }
+ if t.Equal == nil {
+ // See comment in interhash above.
+ panic(errorString("hash of unhashable type " + toRType(t).string()))
+ }
+ if isDirectIface(t) {
+ return c1 * typehash(t, unsafe.Pointer(&a.data), h^c0)
+ } else {
+ return c1 * typehash(t, a.data, h^c0)
+ }
+}
+
+// typehash computes the hash of the object of type t at address p.
+// h is the seed.
+// This function is seldom used. Most maps use for hashing either
+// fixed functions (e.g. f32hash) or compiler-generated functions
+// (e.g. for a type like struct { x, y string }). This implementation
+// is slower but more general and is used for hashing interface types
+// (called from interhash or nilinterhash, above) or for hashing in
+// maps generated by reflect.MapOf (reflect_typehash, below).
+// Note: this function must match the compiler generated
+// functions exactly. See issue 37716.
+func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
+ if t.TFlag&abi.TFlagRegularMemory != 0 {
+ // Handle ptr sizes specially, see issue 37086.
+ switch t.Size_ {
+ case 4:
+ return memhash32(p, h)
+ case 8:
+ return memhash64(p, h)
+ default:
+ return memhash(p, h, t.Size_)
+ }
+ }
+ switch t.Kind_ & kindMask {
+ case kindFloat32:
+ return f32hash(p, h)
+ case kindFloat64:
+ return f64hash(p, h)
+ case kindComplex64:
+ return c64hash(p, h)
+ case kindComplex128:
+ return c128hash(p, h)
+ case kindString:
+ return strhash(p, h)
+ case kindInterface:
+ i := (*interfacetype)(unsafe.Pointer(t))
+ if len(i.Methods) == 0 {
+ return nilinterhash(p, h)
+ }
+ return interhash(p, h)
+ case kindArray:
+ a := (*arraytype)(unsafe.Pointer(t))
+ for i := uintptr(0); i < a.Len; i++ {
+ h = typehash(a.Elem, add(p, i*a.Elem.Size_), h)
+ }
+ return h
+ case kindStruct:
+ s := (*structtype)(unsafe.Pointer(t))
+ for _, f := range s.Fields {
+ if f.Name.IsBlank() {
+ continue
+ }
+ h = typehash(f.Typ, add(p, f.Offset), h)
+ }
+ return h
+ default:
+ // Should never happen, as typehash should only be called
+ // with comparable types.
+ panic(errorString("hash of unhashable type " + toRType(t).string()))
+ }
+}
+
+//go:linkname reflect_typehash reflect.typehash
+func reflect_typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
+ return typehash(t, p, h)
+}
+
+func memequal0(p, q unsafe.Pointer) bool {
+ return true
+}
+func memequal8(p, q unsafe.Pointer) bool {
+ return *(*int8)(p) == *(*int8)(q)
+}
+func memequal16(p, q unsafe.Pointer) bool {
+ return *(*int16)(p) == *(*int16)(q)
+}
+func memequal32(p, q unsafe.Pointer) bool {
+ return *(*int32)(p) == *(*int32)(q)
+}
+func memequal64(p, q unsafe.Pointer) bool {
+ return *(*int64)(p) == *(*int64)(q)
+}
+func memequal128(p, q unsafe.Pointer) bool {
+ return *(*[2]int64)(p) == *(*[2]int64)(q)
+}
+func f32equal(p, q unsafe.Pointer) bool {
+ return *(*float32)(p) == *(*float32)(q)
+}
+func f64equal(p, q unsafe.Pointer) bool {
+ return *(*float64)(p) == *(*float64)(q)
+}
+func c64equal(p, q unsafe.Pointer) bool {
+ return *(*complex64)(p) == *(*complex64)(q)
+}
+func c128equal(p, q unsafe.Pointer) bool {
+ return *(*complex128)(p) == *(*complex128)(q)
+}
+func strequal(p, q unsafe.Pointer) bool {
+ return *(*string)(p) == *(*string)(q)
+}
+func interequal(p, q unsafe.Pointer) bool {
+ x := *(*iface)(p)
+ y := *(*iface)(q)
+ return x.tab == y.tab && ifaceeq(x.tab, x.data, y.data)
+}
+func nilinterequal(p, q unsafe.Pointer) bool {
+ x := *(*eface)(p)
+ y := *(*eface)(q)
+ return x._type == y._type && efaceeq(x._type, x.data, y.data)
+}
+func efaceeq(t *_type, x, y unsafe.Pointer) bool {
+ if t == nil {
+ return true
+ }
+ eq := t.Equal
+ if eq == nil {
+ panic(errorString("comparing uncomparable type " + toRType(t).string()))
+ }
+ if isDirectIface(t) {
+ // Direct interface types are ptr, chan, map, func, and single-element structs/arrays thereof.
+ // Maps and funcs are not comparable, so they can't reach here.
+ // Ptrs, chans, and single-element items can be compared directly using ==.
+ return x == y
+ }
+ return eq(x, y)
+}
+func ifaceeq(tab *itab, x, y unsafe.Pointer) bool {
+ if tab == nil {
+ return true
+ }
+ t := tab._type
+ eq := t.Equal
+ if eq == nil {
+ panic(errorString("comparing uncomparable type " + toRType(t).string()))
+ }
+ if isDirectIface(t) {
+ // See comment in efaceeq.
+ return x == y
+ }
+ return eq(x, y)
+}
+
+// Testing adapters for hash quality tests (see hash_test.go)
+func stringHash(s string, seed uintptr) uintptr {
+ return strhash(noescape(unsafe.Pointer(&s)), seed)
+}
+
+func bytesHash(b []byte, seed uintptr) uintptr {
+ s := (*slice)(unsafe.Pointer(&b))
+ return memhash(s.array, seed, uintptr(s.len))
+}
+
+func int32Hash(i uint32, seed uintptr) uintptr {
+ return memhash32(noescape(unsafe.Pointer(&i)), seed)
+}
+
+func int64Hash(i uint64, seed uintptr) uintptr {
+ return memhash64(noescape(unsafe.Pointer(&i)), seed)
+}
+
+func efaceHash(i any, seed uintptr) uintptr {
+ return nilinterhash(noescape(unsafe.Pointer(&i)), seed)
+}
+
+func ifaceHash(i interface {
+ F()
+}, seed uintptr) uintptr {
+ return interhash(noescape(unsafe.Pointer(&i)), seed)
+}
+
+const hashRandomBytes = goarch.PtrSize / 4 * 64
+
+// used in asm_{386,amd64,arm64}.s to seed the hash function
+var aeskeysched [hashRandomBytes]byte
+
+// used in hash{32,64}.go to seed the hash function
+var hashkey [4]uintptr
+
+func alginit() {
+ // Install AES hash algorithms if the instructions needed are present.
+ if (GOARCH == "386" || GOARCH == "amd64") &&
+ cpu.X86.HasAES && // AESENC
+ cpu.X86.HasSSSE3 && // PSHUFB
+ cpu.X86.HasSSE41 { // PINSR{D,Q}
+ initAlgAES()
+ return
+ }
+ if GOARCH == "arm64" && cpu.ARM64.HasAES {
+ initAlgAES()
+ return
+ }
+ getRandomData((*[len(hashkey) * goarch.PtrSize]byte)(unsafe.Pointer(&hashkey))[:])
+ hashkey[0] |= 1 // make sure these numbers are odd
+ hashkey[1] |= 1
+ hashkey[2] |= 1
+ hashkey[3] |= 1
+}
+
+func initAlgAES() {
+ useAeshash = true
+ // Initialize with random data so hash collisions will be hard to engineer.
+ getRandomData(aeskeysched[:])
+}
+
+// Note: These routines perform the read with a native endianness.
+func readUnaligned32(p unsafe.Pointer) uint32 {
+ q := (*[4]byte)(p)
+ if goarch.BigEndian {
+ return uint32(q[3]) | uint32(q[2])<<8 | uint32(q[1])<<16 | uint32(q[0])<<24
+ }
+ return uint32(q[0]) | uint32(q[1])<<8 | uint32(q[2])<<16 | uint32(q[3])<<24
+}
+
+func readUnaligned64(p unsafe.Pointer) uint64 {
+ q := (*[8]byte)(p)
+ if goarch.BigEndian {
+ return uint64(q[7]) | uint64(q[6])<<8 | uint64(q[5])<<16 | uint64(q[4])<<24 |
+ uint64(q[3])<<32 | uint64(q[2])<<40 | uint64(q[1])<<48 | uint64(q[0])<<56
+ }
+ return uint64(q[0]) | uint64(q[1])<<8 | uint64(q[2])<<16 | uint64(q[3])<<24 | uint64(q[4])<<32 | uint64(q[5])<<40 | uint64(q[6])<<48 | uint64(q[7])<<56
+}
diff --git a/contrib/go/_std_1.21/src/runtime/arena.go b/contrib/go/_std_1.21/src/runtime/arena.go
new file mode 100644
index 0000000000..f9806c545e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/arena.go
@@ -0,0 +1,1003 @@
+// Copyright 2022 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.
+
+// Implementation of (safe) user arenas.
+//
+// This file contains the implementation of user arenas wherein Go values can
+// be manually allocated and freed in bulk. The act of manually freeing memory,
+// potentially before a GC cycle, means that a garbage collection cycle can be
+// delayed, improving efficiency by reducing GC cycle frequency. There are other
+// potential efficiency benefits, such as improved locality and access to a more
+// efficient allocation strategy.
+//
+// What makes the arenas here safe is that once they are freed, accessing the
+// arena's memory will cause an explicit program fault, and the arena's address
+// space will not be reused until no more pointers into it are found. There's one
+// exception to this: if an arena allocated memory that isn't exhausted, it's placed
+// back into a pool for reuse. This means that a crash is not always guaranteed.
+//
+// While this may seem unsafe, it still prevents memory corruption, and is in fact
+// necessary in order to make new(T) a valid implementation of arenas. Such a property
+// is desirable to allow for a trivial implementation. (It also avoids complexities
+// that arise from synchronization with the GC when trying to set the arena chunks to
+// fault while the GC is active.)
+//
+// The implementation works in layers. At the bottom, arenas are managed in chunks.
+// Each chunk must be a multiple of the heap arena size, or the heap arena size must
+// be divisible by the arena chunks. The address space for each chunk, and each
+// corresponding heapArena for that address space, are eternally reserved for use as
+// arena chunks. That is, they can never be used for the general heap. Each chunk
+// is also represented by a single mspan, and is modeled as a single large heap
+// allocation. It must be, because each chunk contains ordinary Go values that may
+// point into the heap, so it must be scanned just like any other object. Any
+// pointer into a chunk will therefore always cause the whole chunk to be scanned
+// while its corresponding arena is still live.
+//
+// Chunks may be allocated either from new memory mapped by the OS on our behalf,
+// or by reusing old freed chunks. When chunks are freed, their underlying memory
+// is returned to the OS, set to fault on access, and may not be reused until the
+// program doesn't point into the chunk anymore (the code refers to this state as
+// "quarantined"), a property checked by the GC.
+//
+// The sweeper handles moving chunks out of this quarantine state to be ready for
+// reuse. When the chunk is placed into the quarantine state, its corresponding
+// span is marked as noscan so that the GC doesn't try to scan memory that would
+// cause a fault.
+//
+// At the next layer are the user arenas themselves. They consist of a single
+// active chunk which new Go values are bump-allocated into and a list of chunks
+// that were exhausted when allocating into the arena. Once the arena is freed,
+// it frees all full chunks it references, and places the active one onto a reuse
+// list for a future arena to use. Each arena keeps its list of referenced chunks
+// explicitly live until it is freed. Each user arena also maps to an object which
+// has a finalizer attached that ensures the arena's chunks are all freed even if
+// the arena itself is never explicitly freed.
+//
+// Pointer-ful memory is bump-allocated from low addresses to high addresses in each
+// chunk, while pointer-free memory is bump-allocated from high address to low
+// addresses. The reason for this is to take advantage of a GC optimization wherein
+// the GC will stop scanning an object when there are no more pointers in it, which
+// also allows us to elide clearing the heap bitmap for pointer-free Go values
+// allocated into arenas.
+//
+// Note that arenas are not safe to use concurrently.
+//
+// In summary, there are 2 resources: arenas, and arena chunks. They exist in the
+// following lifecycle:
+//
+// (1) A new arena is created via newArena.
+// (2) Chunks are allocated to hold memory allocated into the arena with new or slice.
+// (a) Chunks are first allocated from the reuse list of partially-used chunks.
+// (b) If there are no such chunks, then chunks on the ready list are taken.
+// (c) Failing all the above, memory for a new chunk is mapped.
+// (3) The arena is freed, or all references to it are dropped, triggering its finalizer.
+// (a) If the GC is not active, exhausted chunks are set to fault and placed on a
+// quarantine list.
+// (b) If the GC is active, exhausted chunks are placed on a fault list and will
+// go through step (a) at a later point in time.
+// (c) Any remaining partially-used chunk is placed on a reuse list.
+// (4) Once no more pointers are found into quarantined arena chunks, the sweeper
+// takes these chunks out of quarantine and places them on the ready list.
+
+package runtime
+
+import (
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "runtime/internal/math"
+ "unsafe"
+)
+
+// Functions starting with arena_ are meant to be exported to downstream users
+// of arenas. They should wrap these functions in a higher-lever API.
+//
+// The underlying arena and its resources are managed through an opaque unsafe.Pointer.
+
+// arena_newArena is a wrapper around newUserArena.
+//
+//go:linkname arena_newArena arena.runtime_arena_newArena
+func arena_newArena() unsafe.Pointer {
+ return unsafe.Pointer(newUserArena())
+}
+
+// arena_arena_New is a wrapper around (*userArena).new, except that typ
+// is an any (must be a *_type, still) and typ must be a type descriptor
+// for a pointer to the type to actually be allocated, i.e. pass a *T
+// to allocate a T. This is necessary because this function returns a *T.
+//
+//go:linkname arena_arena_New arena.runtime_arena_arena_New
+func arena_arena_New(arena unsafe.Pointer, typ any) any {
+ t := (*_type)(efaceOf(&typ).data)
+ if t.Kind_&kindMask != kindPtr {
+ throw("arena_New: non-pointer type")
+ }
+ te := (*ptrtype)(unsafe.Pointer(t)).Elem
+ x := ((*userArena)(arena)).new(te)
+ var result any
+ e := efaceOf(&result)
+ e._type = t
+ e.data = x
+ return result
+}
+
+// arena_arena_Slice is a wrapper around (*userArena).slice.
+//
+//go:linkname arena_arena_Slice arena.runtime_arena_arena_Slice
+func arena_arena_Slice(arena unsafe.Pointer, slice any, cap int) {
+ ((*userArena)(arena)).slice(slice, cap)
+}
+
+// arena_arena_Free is a wrapper around (*userArena).free.
+//
+//go:linkname arena_arena_Free arena.runtime_arena_arena_Free
+func arena_arena_Free(arena unsafe.Pointer) {
+ ((*userArena)(arena)).free()
+}
+
+// arena_heapify takes a value that lives in an arena and makes a copy
+// of it on the heap. Values that don't live in an arena are returned unmodified.
+//
+//go:linkname arena_heapify arena.runtime_arena_heapify
+func arena_heapify(s any) any {
+ var v unsafe.Pointer
+ e := efaceOf(&s)
+ t := e._type
+ switch t.Kind_ & kindMask {
+ case kindString:
+ v = stringStructOf((*string)(e.data)).str
+ case kindSlice:
+ v = (*slice)(e.data).array
+ case kindPtr:
+ v = e.data
+ default:
+ panic("arena: Clone only supports pointers, slices, and strings")
+ }
+ span := spanOf(uintptr(v))
+ if span == nil || !span.isUserArenaChunk {
+ // Not stored in a user arena chunk.
+ return s
+ }
+ // Heap-allocate storage for a copy.
+ var x any
+ switch t.Kind_ & kindMask {
+ case kindString:
+ s1 := s.(string)
+ s2, b := rawstring(len(s1))
+ copy(b, s1)
+ x = s2
+ case kindSlice:
+ len := (*slice)(e.data).len
+ et := (*slicetype)(unsafe.Pointer(t)).Elem
+ sl := new(slice)
+ *sl = slice{makeslicecopy(et, len, len, (*slice)(e.data).array), len, len}
+ xe := efaceOf(&x)
+ xe._type = t
+ xe.data = unsafe.Pointer(sl)
+ case kindPtr:
+ et := (*ptrtype)(unsafe.Pointer(t)).Elem
+ e2 := newobject(et)
+ typedmemmove(et, e2, e.data)
+ xe := efaceOf(&x)
+ xe._type = t
+ xe.data = e2
+ }
+ return x
+}
+
+const (
+ // userArenaChunkBytes is the size of a user arena chunk.
+ userArenaChunkBytesMax = 8 << 20
+ userArenaChunkBytes = uintptr(int64(userArenaChunkBytesMax-heapArenaBytes)&(int64(userArenaChunkBytesMax-heapArenaBytes)>>63) + heapArenaBytes) // min(userArenaChunkBytesMax, heapArenaBytes)
+
+ // userArenaChunkPages is the number of pages a user arena chunk uses.
+ userArenaChunkPages = userArenaChunkBytes / pageSize
+
+ // userArenaChunkMaxAllocBytes is the maximum size of an object that can
+ // be allocated from an arena. This number is chosen to cap worst-case
+ // fragmentation of user arenas to 25%. Larger allocations are redirected
+ // to the heap.
+ userArenaChunkMaxAllocBytes = userArenaChunkBytes / 4
+)
+
+func init() {
+ if userArenaChunkPages*pageSize != userArenaChunkBytes {
+ throw("user arena chunk size is not a multiple of the page size")
+ }
+ if userArenaChunkBytes%physPageSize != 0 {
+ throw("user arena chunk size is not a multiple of the physical page size")
+ }
+ if userArenaChunkBytes < heapArenaBytes {
+ if heapArenaBytes%userArenaChunkBytes != 0 {
+ throw("user arena chunk size is smaller than a heap arena, but doesn't divide it")
+ }
+ } else {
+ if userArenaChunkBytes%heapArenaBytes != 0 {
+ throw("user arena chunks size is larger than a heap arena, but not a multiple")
+ }
+ }
+ lockInit(&userArenaState.lock, lockRankUserArenaState)
+}
+
+type userArena struct {
+ // full is a list of full chunks that have not enough free memory left, and
+ // that we'll free once this user arena is freed.
+ //
+ // Can't use mSpanList here because it's not-in-heap.
+ fullList *mspan
+
+ // active is the user arena chunk we're currently allocating into.
+ active *mspan
+
+ // refs is a set of references to the arena chunks so that they're kept alive.
+ //
+ // The last reference in the list always refers to active, while the rest of
+ // them correspond to fullList. Specifically, the head of fullList is the
+ // second-to-last one, fullList.next is the third-to-last, and so on.
+ //
+ // In other words, every time a new chunk becomes active, its appended to this
+ // list.
+ refs []unsafe.Pointer
+
+ // defunct is true if free has been called on this arena.
+ //
+ // This is just a best-effort way to discover a concurrent allocation
+ // and free. Also used to detect a double-free.
+ defunct atomic.Bool
+}
+
+// newUserArena creates a new userArena ready to be used.
+func newUserArena() *userArena {
+ a := new(userArena)
+ SetFinalizer(a, func(a *userArena) {
+ // If arena handle is dropped without being freed, then call
+ // free on the arena, so the arena chunks are never reclaimed
+ // by the garbage collector.
+ a.free()
+ })
+ a.refill()
+ return a
+}
+
+// new allocates a new object of the provided type into the arena, and returns
+// its pointer.
+//
+// This operation is not safe to call concurrently with other operations on the
+// same arena.
+func (a *userArena) new(typ *_type) unsafe.Pointer {
+ return a.alloc(typ, -1)
+}
+
+// slice allocates a new slice backing store. slice must be a pointer to a slice
+// (i.e. *[]T), because userArenaSlice will update the slice directly.
+//
+// cap determines the capacity of the slice backing store and must be non-negative.
+//
+// This operation is not safe to call concurrently with other operations on the
+// same arena.
+func (a *userArena) slice(sl any, cap int) {
+ if cap < 0 {
+ panic("userArena.slice: negative cap")
+ }
+ i := efaceOf(&sl)
+ typ := i._type
+ if typ.Kind_&kindMask != kindPtr {
+ panic("slice result of non-ptr type")
+ }
+ typ = (*ptrtype)(unsafe.Pointer(typ)).Elem
+ if typ.Kind_&kindMask != kindSlice {
+ panic("slice of non-ptr-to-slice type")
+ }
+ typ = (*slicetype)(unsafe.Pointer(typ)).Elem
+ // t is now the element type of the slice we want to allocate.
+
+ *((*slice)(i.data)) = slice{a.alloc(typ, cap), cap, cap}
+}
+
+// free returns the userArena's chunks back to mheap and marks it as defunct.
+//
+// Must be called at most once for any given arena.
+//
+// This operation is not safe to call concurrently with other operations on the
+// same arena.
+func (a *userArena) free() {
+ // Check for a double-free.
+ if a.defunct.Load() {
+ panic("arena double free")
+ }
+
+ // Mark ourselves as defunct.
+ a.defunct.Store(true)
+ SetFinalizer(a, nil)
+
+ // Free all the full arenas.
+ //
+ // The refs on this list are in reverse order from the second-to-last.
+ s := a.fullList
+ i := len(a.refs) - 2
+ for s != nil {
+ a.fullList = s.next
+ s.next = nil
+ freeUserArenaChunk(s, a.refs[i])
+ s = a.fullList
+ i--
+ }
+ if a.fullList != nil || i >= 0 {
+ // There's still something left on the full list, or we
+ // failed to actually iterate over the entire refs list.
+ throw("full list doesn't match refs list in length")
+ }
+
+ // Put the active chunk onto the reuse list.
+ //
+ // Note that active's reference is always the last reference in refs.
+ s = a.active
+ if s != nil {
+ if raceenabled || msanenabled || asanenabled {
+ // Don't reuse arenas with sanitizers enabled. We want to catch
+ // any use-after-free errors aggressively.
+ freeUserArenaChunk(s, a.refs[len(a.refs)-1])
+ } else {
+ lock(&userArenaState.lock)
+ userArenaState.reuse = append(userArenaState.reuse, liveUserArenaChunk{s, a.refs[len(a.refs)-1]})
+ unlock(&userArenaState.lock)
+ }
+ }
+ // nil out a.active so that a race with freeing will more likely cause a crash.
+ a.active = nil
+ a.refs = nil
+}
+
+// alloc reserves space in the current chunk or calls refill and reserves space
+// in a new chunk. If cap is negative, the type will be taken literally, otherwise
+// it will be considered as an element type for a slice backing store with capacity
+// cap.
+func (a *userArena) alloc(typ *_type, cap int) unsafe.Pointer {
+ s := a.active
+ var x unsafe.Pointer
+ for {
+ x = s.userArenaNextFree(typ, cap)
+ if x != nil {
+ break
+ }
+ s = a.refill()
+ }
+ return x
+}
+
+// refill inserts the current arena chunk onto the full list and obtains a new
+// one, either from the partial list or allocating a new one, both from mheap.
+func (a *userArena) refill() *mspan {
+ // If there's an active chunk, assume it's full.
+ s := a.active
+ if s != nil {
+ if s.userArenaChunkFree.size() > userArenaChunkMaxAllocBytes {
+ // It's difficult to tell when we're actually out of memory
+ // in a chunk because the allocation that failed may still leave
+ // some free space available. However, that amount of free space
+ // should never exceed the maximum allocation size.
+ throw("wasted too much memory in an arena chunk")
+ }
+ s.next = a.fullList
+ a.fullList = s
+ a.active = nil
+ s = nil
+ }
+ var x unsafe.Pointer
+
+ // Check the partially-used list.
+ lock(&userArenaState.lock)
+ if len(userArenaState.reuse) > 0 {
+ // Pick off the last arena chunk from the list.
+ n := len(userArenaState.reuse) - 1
+ x = userArenaState.reuse[n].x
+ s = userArenaState.reuse[n].mspan
+ userArenaState.reuse[n].x = nil
+ userArenaState.reuse[n].mspan = nil
+ userArenaState.reuse = userArenaState.reuse[:n]
+ }
+ unlock(&userArenaState.lock)
+ if s == nil {
+ // Allocate a new one.
+ x, s = newUserArenaChunk()
+ if s == nil {
+ throw("out of memory")
+ }
+ }
+ a.refs = append(a.refs, x)
+ a.active = s
+ return s
+}
+
+type liveUserArenaChunk struct {
+ *mspan // Must represent a user arena chunk.
+
+ // Reference to mspan.base() to keep the chunk alive.
+ x unsafe.Pointer
+}
+
+var userArenaState struct {
+ lock mutex
+
+ // reuse contains a list of partially-used and already-live
+ // user arena chunks that can be quickly reused for another
+ // arena.
+ //
+ // Protected by lock.
+ reuse []liveUserArenaChunk
+
+ // fault contains full user arena chunks that need to be faulted.
+ //
+ // Protected by lock.
+ fault []liveUserArenaChunk
+}
+
+// userArenaNextFree reserves space in the user arena for an item of the specified
+// type. If cap is not -1, this is for an array of cap elements of type t.
+func (s *mspan) userArenaNextFree(typ *_type, cap int) unsafe.Pointer {
+ size := typ.Size_
+ if cap > 0 {
+ if size > ^uintptr(0)/uintptr(cap) {
+ // Overflow.
+ throw("out of memory")
+ }
+ size *= uintptr(cap)
+ }
+ if size == 0 || cap == 0 {
+ return unsafe.Pointer(&zerobase)
+ }
+ if size > userArenaChunkMaxAllocBytes {
+ // Redirect allocations that don't fit into a chunk well directly
+ // from the heap.
+ if cap >= 0 {
+ return newarray(typ, cap)
+ }
+ return newobject(typ)
+ }
+
+ // Prevent preemption as we set up the space for a new object.
+ //
+ // Act like we're allocating.
+ mp := acquirem()
+ if mp.mallocing != 0 {
+ throw("malloc deadlock")
+ }
+ if mp.gsignal == getg() {
+ throw("malloc during signal")
+ }
+ mp.mallocing = 1
+
+ var ptr unsafe.Pointer
+ if typ.PtrBytes == 0 {
+ // Allocate pointer-less objects from the tail end of the chunk.
+ v, ok := s.userArenaChunkFree.takeFromBack(size, typ.Align_)
+ if ok {
+ ptr = unsafe.Pointer(v)
+ }
+ } else {
+ v, ok := s.userArenaChunkFree.takeFromFront(size, typ.Align_)
+ if ok {
+ ptr = unsafe.Pointer(v)
+ }
+ }
+ if ptr == nil {
+ // Failed to allocate.
+ mp.mallocing = 0
+ releasem(mp)
+ return nil
+ }
+ if s.needzero != 0 {
+ throw("arena chunk needs zeroing, but should already be zeroed")
+ }
+ // Set up heap bitmap and do extra accounting.
+ if typ.PtrBytes != 0 {
+ if cap >= 0 {
+ userArenaHeapBitsSetSliceType(typ, cap, ptr, s.base())
+ } else {
+ userArenaHeapBitsSetType(typ, ptr, s.base())
+ }
+ c := getMCache(mp)
+ if c == nil {
+ throw("mallocgc called without a P or outside bootstrapping")
+ }
+ if cap > 0 {
+ c.scanAlloc += size - (typ.Size_ - typ.PtrBytes)
+ } else {
+ c.scanAlloc += typ.PtrBytes
+ }
+ }
+
+ // Ensure that the stores above that initialize x to
+ // type-safe memory and set the heap bits occur before
+ // the caller can make ptr observable to the garbage
+ // collector. Otherwise, on weakly ordered machines,
+ // the garbage collector could follow a pointer to x,
+ // but see uninitialized memory or stale heap bits.
+ publicationBarrier()
+
+ mp.mallocing = 0
+ releasem(mp)
+
+ return ptr
+}
+
+// userArenaHeapBitsSetType is the equivalent of heapBitsSetType but for
+// non-slice-backing-store Go values allocated in a user arena chunk. It
+// sets up the heap bitmap for the value with type typ allocated at address ptr.
+// base is the base address of the arena chunk.
+func userArenaHeapBitsSetType(typ *_type, ptr unsafe.Pointer, base uintptr) {
+ h := writeHeapBitsForAddr(uintptr(ptr))
+
+ // Our last allocation might have ended right at a noMorePtrs mark,
+ // which we would not have erased. We need to erase that mark here,
+ // because we're going to start adding new heap bitmap bits.
+ // We only need to clear one mark, because below we make sure to
+ // pad out the bits with zeroes and only write one noMorePtrs bit
+ // for each new object.
+ // (This is only necessary at noMorePtrs boundaries, as noMorePtrs
+ // marks within an object allocated with newAt will be erased by
+ // the normal writeHeapBitsForAddr mechanism.)
+ //
+ // Note that we skip this if this is the first allocation in the
+ // arena because there's definitely no previous noMorePtrs mark
+ // (in fact, we *must* do this, because we're going to try to back
+ // up a pointer to fix this up).
+ if uintptr(ptr)%(8*goarch.PtrSize*goarch.PtrSize) == 0 && uintptr(ptr) != base {
+ // Back up one pointer and rewrite that pointer. That will
+ // cause the writeHeapBits implementation to clear the
+ // noMorePtrs bit we need to clear.
+ r := heapBitsForAddr(uintptr(ptr)-goarch.PtrSize, goarch.PtrSize)
+ _, p := r.next()
+ b := uintptr(0)
+ if p == uintptr(ptr)-goarch.PtrSize {
+ b = 1
+ }
+ h = writeHeapBitsForAddr(uintptr(ptr) - goarch.PtrSize)
+ h = h.write(b, 1)
+ }
+
+ p := typ.GCData // start of 1-bit pointer mask (or GC program)
+ var gcProgBits uintptr
+ if typ.Kind_&kindGCProg != 0 {
+ // Expand gc program, using the object itself for storage.
+ gcProgBits = runGCProg(addb(p, 4), (*byte)(ptr))
+ p = (*byte)(ptr)
+ }
+ nb := typ.PtrBytes / goarch.PtrSize
+
+ for i := uintptr(0); i < nb; i += ptrBits {
+ k := nb - i
+ if k > ptrBits {
+ k = ptrBits
+ }
+ h = h.write(readUintptr(addb(p, i/8)), k)
+ }
+ // Note: we call pad here to ensure we emit explicit 0 bits
+ // for the pointerless tail of the object. This ensures that
+ // there's only a single noMorePtrs mark for the next object
+ // to clear. We don't need to do this to clear stale noMorePtrs
+ // markers from previous uses because arena chunk pointer bitmaps
+ // are always fully cleared when reused.
+ h = h.pad(typ.Size_ - typ.PtrBytes)
+ h.flush(uintptr(ptr), typ.Size_)
+
+ if typ.Kind_&kindGCProg != 0 {
+ // Zero out temporary ptrmask buffer inside object.
+ memclrNoHeapPointers(ptr, (gcProgBits+7)/8)
+ }
+
+ // Double-check that the bitmap was written out correctly.
+ //
+ // Derived from heapBitsSetType.
+ const doubleCheck = false
+ if doubleCheck {
+ size := typ.Size_
+ x := uintptr(ptr)
+ h := heapBitsForAddr(x, size)
+ for i := uintptr(0); i < size; i += goarch.PtrSize {
+ // Compute the pointer bit we want at offset i.
+ want := false
+ off := i % typ.Size_
+ if off < typ.PtrBytes {
+ j := off / goarch.PtrSize
+ want = *addb(typ.GCData, j/8)>>(j%8)&1 != 0
+ }
+ if want {
+ var addr uintptr
+ h, addr = h.next()
+ if addr != x+i {
+ throw("userArenaHeapBitsSetType: pointer entry not correct")
+ }
+ }
+ }
+ if _, addr := h.next(); addr != 0 {
+ throw("userArenaHeapBitsSetType: extra pointer")
+ }
+ }
+}
+
+// userArenaHeapBitsSetSliceType is the equivalent of heapBitsSetType but for
+// Go slice backing store values allocated in a user arena chunk. It sets up the
+// heap bitmap for n consecutive values with type typ allocated at address ptr.
+func userArenaHeapBitsSetSliceType(typ *_type, n int, ptr unsafe.Pointer, base uintptr) {
+ mem, overflow := math.MulUintptr(typ.Size_, uintptr(n))
+ if overflow || n < 0 || mem > maxAlloc {
+ panic(plainError("runtime: allocation size out of range"))
+ }
+ for i := 0; i < n; i++ {
+ userArenaHeapBitsSetType(typ, add(ptr, uintptr(i)*typ.Size_), base)
+ }
+}
+
+// newUserArenaChunk allocates a user arena chunk, which maps to a single
+// heap arena and single span. Returns a pointer to the base of the chunk
+// (this is really important: we need to keep the chunk alive) and the span.
+func newUserArenaChunk() (unsafe.Pointer, *mspan) {
+ if gcphase == _GCmarktermination {
+ throw("newUserArenaChunk called with gcphase == _GCmarktermination")
+ }
+
+ // Deduct assist credit. Because user arena chunks are modeled as one
+ // giant heap object which counts toward heapLive, we're obligated to
+ // assist the GC proportionally (and it's worth noting that the arena
+ // does represent additional work for the GC, but we also have no idea
+ // what that looks like until we actually allocate things into the
+ // arena).
+ deductAssistCredit(userArenaChunkBytes)
+
+ // Set mp.mallocing to keep from being preempted by GC.
+ mp := acquirem()
+ if mp.mallocing != 0 {
+ throw("malloc deadlock")
+ }
+ if mp.gsignal == getg() {
+ throw("malloc during signal")
+ }
+ mp.mallocing = 1
+
+ // Allocate a new user arena.
+ var span *mspan
+ systemstack(func() {
+ span = mheap_.allocUserArenaChunk()
+ })
+ if span == nil {
+ throw("out of memory")
+ }
+ x := unsafe.Pointer(span.base())
+
+ // Allocate black during GC.
+ // All slots hold nil so no scanning is needed.
+ // This may be racing with GC so do it atomically if there can be
+ // a race marking the bit.
+ if gcphase != _GCoff {
+ gcmarknewobject(span, span.base(), span.elemsize)
+ }
+
+ if raceenabled {
+ // TODO(mknyszek): Track individual objects.
+ racemalloc(unsafe.Pointer(span.base()), span.elemsize)
+ }
+
+ if msanenabled {
+ // TODO(mknyszek): Track individual objects.
+ msanmalloc(unsafe.Pointer(span.base()), span.elemsize)
+ }
+
+ if asanenabled {
+ // TODO(mknyszek): Track individual objects.
+ rzSize := computeRZlog(span.elemsize)
+ span.elemsize -= rzSize
+ span.limit -= rzSize
+ span.userArenaChunkFree = makeAddrRange(span.base(), span.limit)
+ asanpoison(unsafe.Pointer(span.limit), span.npages*pageSize-span.elemsize)
+ asanunpoison(unsafe.Pointer(span.base()), span.elemsize)
+ }
+
+ if rate := MemProfileRate; rate > 0 {
+ c := getMCache(mp)
+ if c == nil {
+ throw("newUserArenaChunk called without a P or outside bootstrapping")
+ }
+ // Note cache c only valid while m acquired; see #47302
+ if rate != 1 && userArenaChunkBytes < c.nextSample {
+ c.nextSample -= userArenaChunkBytes
+ } else {
+ profilealloc(mp, unsafe.Pointer(span.base()), userArenaChunkBytes)
+ }
+ }
+ mp.mallocing = 0
+ releasem(mp)
+
+ // Again, because this chunk counts toward heapLive, potentially trigger a GC.
+ if t := (gcTrigger{kind: gcTriggerHeap}); t.test() {
+ gcStart(t)
+ }
+
+ if debug.malloc {
+ if debug.allocfreetrace != 0 {
+ tracealloc(unsafe.Pointer(span.base()), userArenaChunkBytes, nil)
+ }
+
+ if inittrace.active && inittrace.id == getg().goid {
+ // Init functions are executed sequentially in a single goroutine.
+ inittrace.bytes += uint64(userArenaChunkBytes)
+ }
+ }
+
+ // Double-check it's aligned to the physical page size. Based on the current
+ // implementation this is trivially true, but it need not be in the future.
+ // However, if it's not aligned to the physical page size then we can't properly
+ // set it to fault later.
+ if uintptr(x)%physPageSize != 0 {
+ throw("user arena chunk is not aligned to the physical page size")
+ }
+
+ return x, span
+}
+
+// isUnusedUserArenaChunk indicates that the arena chunk has been set to fault
+// and doesn't contain any scannable memory anymore. However, it might still be
+// mSpanInUse as it sits on the quarantine list, since it needs to be swept.
+//
+// This is not safe to execute unless the caller has ownership of the mspan or
+// the world is stopped (preemption is prevented while the relevant state changes).
+//
+// This is really only meant to be used by accounting tests in the runtime to
+// distinguish when a span shouldn't be counted (since mSpanInUse might not be
+// enough).
+func (s *mspan) isUnusedUserArenaChunk() bool {
+ return s.isUserArenaChunk && s.spanclass == makeSpanClass(0, true)
+}
+
+// setUserArenaChunkToFault sets the address space for the user arena chunk to fault
+// and releases any underlying memory resources.
+//
+// Must be in a non-preemptible state to ensure the consistency of statistics
+// exported to MemStats.
+func (s *mspan) setUserArenaChunkToFault() {
+ if !s.isUserArenaChunk {
+ throw("invalid span in heapArena for user arena")
+ }
+ if s.npages*pageSize != userArenaChunkBytes {
+ throw("span on userArena.faultList has invalid size")
+ }
+
+ // Update the span class to be noscan. What we want to happen is that
+ // any pointer into the span keeps it from getting recycled, so we want
+ // the mark bit to get set, but we're about to set the address space to fault,
+ // so we have to prevent the GC from scanning this memory.
+ //
+ // It's OK to set it here because (1) a GC isn't in progress, so the scanning code
+ // won't make a bad decision, (2) we're currently non-preemptible and in the runtime,
+ // so a GC is blocked from starting. We might race with sweeping, which could
+ // put it on the "wrong" sweep list, but really don't care because the chunk is
+ // treated as a large object span and there's no meaningful difference between scan
+ // and noscan large objects in the sweeper. The STW at the start of the GC acts as a
+ // barrier for this update.
+ s.spanclass = makeSpanClass(0, true)
+
+ // Actually set the arena chunk to fault, so we'll get dangling pointer errors.
+ // sysFault currently uses a method on each OS that forces it to evacuate all
+ // memory backing the chunk.
+ sysFault(unsafe.Pointer(s.base()), s.npages*pageSize)
+
+ // Everything on the list is counted as in-use, however sysFault transitions to
+ // Reserved, not Prepared, so we skip updating heapFree or heapReleased and just
+ // remove the memory from the total altogether; it's just address space now.
+ gcController.heapInUse.add(-int64(s.npages * pageSize))
+
+ // Count this as a free of an object right now as opposed to when
+ // the span gets off the quarantine list. The main reason is so that the
+ // amount of bytes allocated doesn't exceed how much is counted as
+ // "mapped ready," which could cause a deadlock in the pacer.
+ gcController.totalFree.Add(int64(s.npages * pageSize))
+
+ // Update consistent stats to match.
+ //
+ // We're non-preemptible, so it's safe to update consistent stats (our P
+ // won't change out from under us).
+ stats := memstats.heapStats.acquire()
+ atomic.Xaddint64(&stats.committed, -int64(s.npages*pageSize))
+ atomic.Xaddint64(&stats.inHeap, -int64(s.npages*pageSize))
+ atomic.Xadd64(&stats.largeFreeCount, 1)
+ atomic.Xadd64(&stats.largeFree, int64(s.npages*pageSize))
+ memstats.heapStats.release()
+
+ // This counts as a free, so update heapLive.
+ gcController.update(-int64(s.npages*pageSize), 0)
+
+ // Mark it as free for the race detector.
+ if raceenabled {
+ racefree(unsafe.Pointer(s.base()), s.elemsize)
+ }
+
+ systemstack(func() {
+ // Add the user arena to the quarantine list.
+ lock(&mheap_.lock)
+ mheap_.userArena.quarantineList.insert(s)
+ unlock(&mheap_.lock)
+ })
+}
+
+// inUserArenaChunk returns true if p points to a user arena chunk.
+func inUserArenaChunk(p uintptr) bool {
+ s := spanOf(p)
+ if s == nil {
+ return false
+ }
+ return s.isUserArenaChunk
+}
+
+// freeUserArenaChunk releases the user arena represented by s back to the runtime.
+//
+// x must be a live pointer within s.
+//
+// The runtime will set the user arena to fault once it's safe (the GC is no longer running)
+// and then once the user arena is no longer referenced by the application, will allow it to
+// be reused.
+func freeUserArenaChunk(s *mspan, x unsafe.Pointer) {
+ if !s.isUserArenaChunk {
+ throw("span is not for a user arena")
+ }
+ if s.npages*pageSize != userArenaChunkBytes {
+ throw("invalid user arena span size")
+ }
+
+ // Mark the region as free to various santizers immediately instead
+ // of handling them at sweep time.
+ if raceenabled {
+ racefree(unsafe.Pointer(s.base()), s.elemsize)
+ }
+ if msanenabled {
+ msanfree(unsafe.Pointer(s.base()), s.elemsize)
+ }
+ if asanenabled {
+ asanpoison(unsafe.Pointer(s.base()), s.elemsize)
+ }
+
+ // Make ourselves non-preemptible as we manipulate state and statistics.
+ //
+ // Also required by setUserArenaChunksToFault.
+ mp := acquirem()
+
+ // We can only set user arenas to fault if we're in the _GCoff phase.
+ if gcphase == _GCoff {
+ lock(&userArenaState.lock)
+ faultList := userArenaState.fault
+ userArenaState.fault = nil
+ unlock(&userArenaState.lock)
+
+ s.setUserArenaChunkToFault()
+ for _, lc := range faultList {
+ lc.mspan.setUserArenaChunkToFault()
+ }
+
+ // Until the chunks are set to fault, keep them alive via the fault list.
+ KeepAlive(x)
+ KeepAlive(faultList)
+ } else {
+ // Put the user arena on the fault list.
+ lock(&userArenaState.lock)
+ userArenaState.fault = append(userArenaState.fault, liveUserArenaChunk{s, x})
+ unlock(&userArenaState.lock)
+ }
+ releasem(mp)
+}
+
+// allocUserArenaChunk attempts to reuse a free user arena chunk represented
+// as a span.
+//
+// Must be in a non-preemptible state to ensure the consistency of statistics
+// exported to MemStats.
+//
+// Acquires the heap lock. Must run on the system stack for that reason.
+//
+//go:systemstack
+func (h *mheap) allocUserArenaChunk() *mspan {
+ var s *mspan
+ var base uintptr
+
+ // First check the free list.
+ lock(&h.lock)
+ if !h.userArena.readyList.isEmpty() {
+ s = h.userArena.readyList.first
+ h.userArena.readyList.remove(s)
+ base = s.base()
+ } else {
+ // Free list was empty, so allocate a new arena.
+ hintList := &h.userArena.arenaHints
+ if raceenabled {
+ // In race mode just use the regular heap hints. We might fragment
+ // the address space, but the race detector requires that the heap
+ // is mapped contiguously.
+ hintList = &h.arenaHints
+ }
+ v, size := h.sysAlloc(userArenaChunkBytes, hintList, false)
+ if size%userArenaChunkBytes != 0 {
+ throw("sysAlloc size is not divisible by userArenaChunkBytes")
+ }
+ if size > userArenaChunkBytes {
+ // We got more than we asked for. This can happen if
+ // heapArenaSize > userArenaChunkSize, or if sysAlloc just returns
+ // some extra as a result of trying to find an aligned region.
+ //
+ // Divide it up and put it on the ready list.
+ for i := uintptr(userArenaChunkBytes); i < size; i += userArenaChunkBytes {
+ s := h.allocMSpanLocked()
+ s.init(uintptr(v)+i, userArenaChunkPages)
+ h.userArena.readyList.insertBack(s)
+ }
+ size = userArenaChunkBytes
+ }
+ base = uintptr(v)
+ if base == 0 {
+ // Out of memory.
+ unlock(&h.lock)
+ return nil
+ }
+ s = h.allocMSpanLocked()
+ }
+ unlock(&h.lock)
+
+ // sysAlloc returns Reserved address space, and any span we're
+ // reusing is set to fault (so, also Reserved), so transition
+ // it to Prepared and then Ready.
+ //
+ // Unlike (*mheap).grow, just map in everything that we
+ // asked for. We're likely going to use it all.
+ sysMap(unsafe.Pointer(base), userArenaChunkBytes, &gcController.heapReleased)
+ sysUsed(unsafe.Pointer(base), userArenaChunkBytes, userArenaChunkBytes)
+
+ // Model the user arena as a heap span for a large object.
+ spc := makeSpanClass(0, false)
+ h.initSpan(s, spanAllocHeap, spc, base, userArenaChunkPages)
+ s.isUserArenaChunk = true
+
+ // Account for this new arena chunk memory.
+ gcController.heapInUse.add(int64(userArenaChunkBytes))
+ gcController.heapReleased.add(-int64(userArenaChunkBytes))
+
+ stats := memstats.heapStats.acquire()
+ atomic.Xaddint64(&stats.inHeap, int64(userArenaChunkBytes))
+ atomic.Xaddint64(&stats.committed, int64(userArenaChunkBytes))
+
+ // Model the arena as a single large malloc.
+ atomic.Xadd64(&stats.largeAlloc, int64(userArenaChunkBytes))
+ atomic.Xadd64(&stats.largeAllocCount, 1)
+ memstats.heapStats.release()
+
+ // Count the alloc in inconsistent, internal stats.
+ gcController.totalAlloc.Add(int64(userArenaChunkBytes))
+
+ // Update heapLive.
+ gcController.update(int64(userArenaChunkBytes), 0)
+
+ // Put the large span in the mcentral swept list so that it's
+ // visible to the background sweeper.
+ h.central[spc].mcentral.fullSwept(h.sweepgen).push(s)
+ s.limit = s.base() + userArenaChunkBytes
+ s.freeindex = 1
+ s.allocCount = 1
+
+ // This must clear the entire heap bitmap so that it's safe
+ // to allocate noscan data without writing anything out.
+ s.initHeapBits(true)
+
+ // Clear the span preemptively. It's an arena chunk, so let's assume
+ // everything is going to be used.
+ //
+ // This also seems to make a massive difference as to whether or
+ // not Linux decides to back this memory with transparent huge
+ // pages. There's latency involved in this zeroing, but the hugepage
+ // gains are almost always worth it. Note: it's important that we
+ // clear even if it's freshly mapped and we know there's no point
+ // to zeroing as *that* is the critical signal to use huge pages.
+ memclrNoHeapPointers(unsafe.Pointer(s.base()), s.elemsize)
+ s.needzero = 0
+
+ s.freeIndexForScan = 1
+
+ // Set up the range for allocation.
+ s.userArenaChunkFree = makeAddrRange(base, s.limit)
+ return s
+}
diff --git a/contrib/go/_std_1.20/src/runtime/asan0.go b/contrib/go/_std_1.21/src/runtime/asan0.go
index 0948786200..0948786200 100644
--- a/contrib/go/_std_1.20/src/runtime/asan0.go
+++ b/contrib/go/_std_1.21/src/runtime/asan0.go
diff --git a/contrib/go/_std_1.21/src/runtime/asm.s b/contrib/go/_std_1.21/src/runtime/asm.s
new file mode 100644
index 0000000000..f7bc5d432e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/asm.s
@@ -0,0 +1,14 @@
+// Copyright 2014 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.
+
+#include "textflag.h"
+
+#ifndef GOARCH_amd64
+TEXT ·sigpanic0(SB),NOSPLIT,$0-0
+ JMP ·sigpanic<ABIInternal>(SB)
+#endif
+
+// See map.go comment on the need for this routine.
+TEXT ·mapinitnoop<ABIInternal>(SB),NOSPLIT,$0-0
+ RET
diff --git a/contrib/go/_std_1.20/src/runtime/asm_amd64.h b/contrib/go/_std_1.21/src/runtime/asm_amd64.h
index f7a8896db6..f7a8896db6 100644
--- a/contrib/go/_std_1.20/src/runtime/asm_amd64.h
+++ b/contrib/go/_std_1.21/src/runtime/asm_amd64.h
diff --git a/contrib/go/_std_1.21/src/runtime/asm_amd64.s b/contrib/go/_std_1.21/src/runtime/asm_amd64.s
new file mode 100644
index 0000000000..edf0909a77
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/asm_amd64.s
@@ -0,0 +1,2093 @@
+// Copyright 2009 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.
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "funcdata.h"
+#include "textflag.h"
+#include "cgo/abi_amd64.h"
+
+// _rt0_amd64 is common startup code for most amd64 systems when using
+// internal linking. This is the entry point for the program from the
+// kernel for an ordinary -buildmode=exe program. The stack holds the
+// number of arguments and the C-style argv.
+TEXT _rt0_amd64(SB),NOSPLIT,$-8
+ MOVQ 0(SP), DI // argc
+ LEAQ 8(SP), SI // argv
+ JMP runtime·rt0_go(SB)
+
+// main is common startup code for most amd64 systems when using
+// external linking. The C startup code will call the symbol "main"
+// passing argc and argv in the usual C ABI registers DI and SI.
+TEXT main(SB),NOSPLIT,$-8
+ JMP runtime·rt0_go(SB)
+
+// _rt0_amd64_lib is common startup code for most amd64 systems when
+// using -buildmode=c-archive or -buildmode=c-shared. The linker will
+// arrange to invoke this function as a global constructor (for
+// c-archive) or when the shared library is loaded (for c-shared).
+// We expect argc and argv to be passed in the usual C ABI registers
+// DI and SI.
+TEXT _rt0_amd64_lib(SB),NOSPLIT|NOFRAME,$0
+ // Transition from C ABI to Go ABI.
+ PUSH_REGS_HOST_TO_ABI0()
+
+ MOVQ DI, _rt0_amd64_lib_argc<>(SB)
+ MOVQ SI, _rt0_amd64_lib_argv<>(SB)
+
+ // Synchronous initialization.
+ CALL runtime·libpreinit(SB)
+
+ // Create a new thread to finish Go runtime initialization.
+ MOVQ _cgo_sys_thread_create(SB), AX
+ TESTQ AX, AX
+ JZ nocgo
+
+ // We're calling back to C.
+ // Align stack per ELF ABI requirements.
+ MOVQ SP, BX // Callee-save in C ABI
+ ANDQ $~15, SP
+ MOVQ $_rt0_amd64_lib_go(SB), DI
+ MOVQ $0, SI
+ CALL AX
+ MOVQ BX, SP
+ JMP restore
+
+nocgo:
+ ADJSP $16
+ MOVQ $0x800000, 0(SP) // stacksize
+ MOVQ $_rt0_amd64_lib_go(SB), AX
+ MOVQ AX, 8(SP) // fn
+ CALL runtime·newosproc0(SB)
+ ADJSP $-16
+
+restore:
+ POP_REGS_HOST_TO_ABI0()
+ RET
+
+// _rt0_amd64_lib_go initializes the Go runtime.
+// This is started in a separate thread by _rt0_amd64_lib.
+TEXT _rt0_amd64_lib_go(SB),NOSPLIT,$0
+ MOVQ _rt0_amd64_lib_argc<>(SB), DI
+ MOVQ _rt0_amd64_lib_argv<>(SB), SI
+ JMP runtime·rt0_go(SB)
+
+DATA _rt0_amd64_lib_argc<>(SB)/8, $0
+GLOBL _rt0_amd64_lib_argc<>(SB),NOPTR, $8
+DATA _rt0_amd64_lib_argv<>(SB)/8, $0
+GLOBL _rt0_amd64_lib_argv<>(SB),NOPTR, $8
+
+#ifdef GOAMD64_v2
+DATA bad_cpu_msg<>+0x00(SB)/84, $"This program can only be run on AMD64 processors with v2 microarchitecture support.\n"
+#endif
+
+#ifdef GOAMD64_v3
+DATA bad_cpu_msg<>+0x00(SB)/84, $"This program can only be run on AMD64 processors with v3 microarchitecture support.\n"
+#endif
+
+#ifdef GOAMD64_v4
+DATA bad_cpu_msg<>+0x00(SB)/84, $"This program can only be run on AMD64 processors with v4 microarchitecture support.\n"
+#endif
+
+GLOBL bad_cpu_msg<>(SB), RODATA, $84
+
+// Define a list of AMD64 microarchitecture level features
+// https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels
+
+ // SSE3 SSSE3 CMPXCHNG16 SSE4.1 SSE4.2 POPCNT
+#define V2_FEATURES_CX (1 << 0 | 1 << 9 | 1 << 13 | 1 << 19 | 1 << 20 | 1 << 23)
+ // LAHF/SAHF
+#define V2_EXT_FEATURES_CX (1 << 0)
+ // FMA MOVBE OSXSAVE AVX F16C
+#define V3_FEATURES_CX (V2_FEATURES_CX | 1 << 12 | 1 << 22 | 1 << 27 | 1 << 28 | 1 << 29)
+ // ABM (FOR LZNCT)
+#define V3_EXT_FEATURES_CX (V2_EXT_FEATURES_CX | 1 << 5)
+ // BMI1 AVX2 BMI2
+#define V3_EXT_FEATURES_BX (1 << 3 | 1 << 5 | 1 << 8)
+ // XMM YMM
+#define V3_OS_SUPPORT_AX (1 << 1 | 1 << 2)
+
+#define V4_FEATURES_CX V3_FEATURES_CX
+
+#define V4_EXT_FEATURES_CX V3_EXT_FEATURES_CX
+ // AVX512F AVX512DQ AVX512CD AVX512BW AVX512VL
+#define V4_EXT_FEATURES_BX (V3_EXT_FEATURES_BX | 1 << 16 | 1 << 17 | 1 << 28 | 1 << 30 | 1 << 31)
+ // OPMASK ZMM
+#define V4_OS_SUPPORT_AX (V3_OS_SUPPORT_AX | 1 << 5 | (1 << 6 | 1 << 7))
+
+#ifdef GOAMD64_v2
+#define NEED_MAX_CPUID 0x80000001
+#define NEED_FEATURES_CX V2_FEATURES_CX
+#define NEED_EXT_FEATURES_CX V2_EXT_FEATURES_CX
+#endif
+
+#ifdef GOAMD64_v3
+#define NEED_MAX_CPUID 0x80000001
+#define NEED_FEATURES_CX V3_FEATURES_CX
+#define NEED_EXT_FEATURES_CX V3_EXT_FEATURES_CX
+#define NEED_EXT_FEATURES_BX V3_EXT_FEATURES_BX
+#define NEED_OS_SUPPORT_AX V3_OS_SUPPORT_AX
+#endif
+
+#ifdef GOAMD64_v4
+#define NEED_MAX_CPUID 0x80000001
+#define NEED_FEATURES_CX V4_FEATURES_CX
+#define NEED_EXT_FEATURES_CX V4_EXT_FEATURES_CX
+#define NEED_EXT_FEATURES_BX V4_EXT_FEATURES_BX
+
+// Darwin requires a different approach to check AVX512 support, see CL 285572.
+#ifdef GOOS_darwin
+#define NEED_OS_SUPPORT_AX V3_OS_SUPPORT_AX
+// These values are from:
+// https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/osfmk/i386/cpu_capabilities.h
+#define commpage64_base_address 0x00007fffffe00000
+#define commpage64_cpu_capabilities64 (commpage64_base_address+0x010)
+#define commpage64_version (commpage64_base_address+0x01E)
+#define hasAVX512F 0x0000004000000000
+#define hasAVX512CD 0x0000008000000000
+#define hasAVX512DQ 0x0000010000000000
+#define hasAVX512BW 0x0000020000000000
+#define hasAVX512VL 0x0000100000000000
+#define NEED_DARWIN_SUPPORT (hasAVX512F | hasAVX512DQ | hasAVX512CD | hasAVX512BW | hasAVX512VL)
+#else
+#define NEED_OS_SUPPORT_AX V4_OS_SUPPORT_AX
+#endif
+
+#endif
+
+TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0
+ // copy arguments forward on an even stack
+ MOVQ DI, AX // argc
+ MOVQ SI, BX // argv
+ SUBQ $(5*8), SP // 3args 2auto
+ ANDQ $~15, SP
+ MOVQ AX, 24(SP)
+ MOVQ BX, 32(SP)
+
+ // create istack out of the given (operating system) stack.
+ // _cgo_init may update stackguard.
+ MOVQ $runtime·g0(SB), DI
+ LEAQ (-64*1024)(SP), BX
+ MOVQ BX, g_stackguard0(DI)
+ MOVQ BX, g_stackguard1(DI)
+ MOVQ BX, (g_stack+stack_lo)(DI)
+ MOVQ SP, (g_stack+stack_hi)(DI)
+
+ // find out information about the processor we're on
+ MOVL $0, AX
+ CPUID
+ CMPL AX, $0
+ JE nocpuinfo
+
+ CMPL BX, $0x756E6547 // "Genu"
+ JNE notintel
+ CMPL DX, $0x49656E69 // "ineI"
+ JNE notintel
+ CMPL CX, $0x6C65746E // "ntel"
+ JNE notintel
+ MOVB $1, runtime·isIntel(SB)
+
+notintel:
+ // Load EAX=1 cpuid flags
+ MOVL $1, AX
+ CPUID
+ MOVL AX, runtime·processorVersionInfo(SB)
+
+nocpuinfo:
+ // if there is an _cgo_init, call it.
+ MOVQ _cgo_init(SB), AX
+ TESTQ AX, AX
+ JZ needtls
+ // arg 1: g0, already in DI
+ MOVQ $setg_gcc<>(SB), SI // arg 2: setg_gcc
+ MOVQ $0, DX // arg 3, 4: not used when using platform's TLS
+ MOVQ $0, CX
+#ifdef GOOS_android
+ MOVQ $runtime·tls_g(SB), DX // arg 3: &tls_g
+ // arg 4: TLS base, stored in slot 0 (Android's TLS_SLOT_SELF).
+ // Compensate for tls_g (+16).
+ MOVQ -16(TLS), CX
+#endif
+#ifdef GOOS_windows
+ MOVQ $runtime·tls_g(SB), DX // arg 3: &tls_g
+ // Adjust for the Win64 calling convention.
+ MOVQ CX, R9 // arg 4
+ MOVQ DX, R8 // arg 3
+ MOVQ SI, DX // arg 2
+ MOVQ DI, CX // arg 1
+#endif
+ CALL AX
+
+ // update stackguard after _cgo_init
+ MOVQ $runtime·g0(SB), CX
+ MOVQ (g_stack+stack_lo)(CX), AX
+ ADDQ $const_stackGuard, AX
+ MOVQ AX, g_stackguard0(CX)
+ MOVQ AX, g_stackguard1(CX)
+
+#ifndef GOOS_windows
+ JMP ok
+#endif
+needtls:
+#ifdef GOOS_plan9
+ // skip TLS setup on Plan 9
+ JMP ok
+#endif
+#ifdef GOOS_solaris
+ // skip TLS setup on Solaris
+ JMP ok
+#endif
+#ifdef GOOS_illumos
+ // skip TLS setup on illumos
+ JMP ok
+#endif
+#ifdef GOOS_darwin
+ // skip TLS setup on Darwin
+ JMP ok
+#endif
+#ifdef GOOS_openbsd
+ // skip TLS setup on OpenBSD
+ JMP ok
+#endif
+
+#ifdef GOOS_windows
+ CALL runtime·wintls(SB)
+#endif
+
+ LEAQ runtime·m0+m_tls(SB), DI
+ CALL runtime·settls(SB)
+
+ // store through it, to make sure it works
+ get_tls(BX)
+ MOVQ $0x123, g(BX)
+ MOVQ runtime·m0+m_tls(SB), AX
+ CMPQ AX, $0x123
+ JEQ 2(PC)
+ CALL runtime·abort(SB)
+ok:
+ // set the per-goroutine and per-mach "registers"
+ get_tls(BX)
+ LEAQ runtime·g0(SB), CX
+ MOVQ CX, g(BX)
+ LEAQ runtime·m0(SB), AX
+
+ // save m->g0 = g0
+ MOVQ CX, m_g0(AX)
+ // save m0 to g0->m
+ MOVQ AX, g_m(CX)
+
+ CLD // convention is D is always left cleared
+
+ // Check GOAMD64 requirements
+ // We need to do this after setting up TLS, so that
+ // we can report an error if there is a failure. See issue 49586.
+#ifdef NEED_FEATURES_CX
+ MOVL $0, AX
+ CPUID
+ CMPL AX, $0
+ JE bad_cpu
+ MOVL $1, AX
+ CPUID
+ ANDL $NEED_FEATURES_CX, CX
+ CMPL CX, $NEED_FEATURES_CX
+ JNE bad_cpu
+#endif
+
+#ifdef NEED_MAX_CPUID
+ MOVL $0x80000000, AX
+ CPUID
+ CMPL AX, $NEED_MAX_CPUID
+ JL bad_cpu
+#endif
+
+#ifdef NEED_EXT_FEATURES_BX
+ MOVL $7, AX
+ MOVL $0, CX
+ CPUID
+ ANDL $NEED_EXT_FEATURES_BX, BX
+ CMPL BX, $NEED_EXT_FEATURES_BX
+ JNE bad_cpu
+#endif
+
+#ifdef NEED_EXT_FEATURES_CX
+ MOVL $0x80000001, AX
+ CPUID
+ ANDL $NEED_EXT_FEATURES_CX, CX
+ CMPL CX, $NEED_EXT_FEATURES_CX
+ JNE bad_cpu
+#endif
+
+#ifdef NEED_OS_SUPPORT_AX
+ XORL CX, CX
+ XGETBV
+ ANDL $NEED_OS_SUPPORT_AX, AX
+ CMPL AX, $NEED_OS_SUPPORT_AX
+ JNE bad_cpu
+#endif
+
+#ifdef NEED_DARWIN_SUPPORT
+ MOVQ $commpage64_version, BX
+ CMPW (BX), $13 // cpu_capabilities64 undefined in versions < 13
+ JL bad_cpu
+ MOVQ $commpage64_cpu_capabilities64, BX
+ MOVQ (BX), BX
+ MOVQ $NEED_DARWIN_SUPPORT, CX
+ ANDQ CX, BX
+ CMPQ BX, CX
+ JNE bad_cpu
+#endif
+
+ CALL runtime·check(SB)
+
+ MOVL 24(SP), AX // copy argc
+ MOVL AX, 0(SP)
+ MOVQ 32(SP), AX // copy argv
+ MOVQ AX, 8(SP)
+ CALL runtime·args(SB)
+ CALL runtime·osinit(SB)
+ CALL runtime·schedinit(SB)
+
+ // create a new goroutine to start program
+ MOVQ $runtime·mainPC(SB), AX // entry
+ PUSHQ AX
+ CALL runtime·newproc(SB)
+ POPQ AX
+
+ // start this M
+ CALL runtime·mstart(SB)
+
+ CALL runtime·abort(SB) // mstart should never return
+ RET
+
+bad_cpu: // show that the program requires a certain microarchitecture level.
+ MOVQ $2, 0(SP)
+ MOVQ $bad_cpu_msg<>(SB), AX
+ MOVQ AX, 8(SP)
+ MOVQ $84, 16(SP)
+ CALL runtime·write(SB)
+ MOVQ $1, 0(SP)
+ CALL runtime·exit(SB)
+ CALL runtime·abort(SB)
+ RET
+
+ // Prevent dead-code elimination of debugCallV2, which is
+ // intended to be called by debuggers.
+ MOVQ $runtime·debugCallV2<ABIInternal>(SB), AX
+ RET
+
+// mainPC is a function value for runtime.main, to be passed to newproc.
+// The reference to runtime.main is made via ABIInternal, since the
+// actual function (not the ABI0 wrapper) is needed by newproc.
+DATA runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
+GLOBL runtime·mainPC(SB),RODATA,$8
+
+TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
+ BYTE $0xcc
+ RET
+
+TEXT runtime·asminit(SB),NOSPLIT,$0-0
+ // No per-thread init.
+ RET
+
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME|NOFRAME,$0
+ CALL runtime·mstart0(SB)
+ RET // not reached
+
+/*
+ * go-routine
+ */
+
+// func gogo(buf *gobuf)
+// restore state from Gobuf; longjmp
+TEXT runtime·gogo(SB), NOSPLIT, $0-8
+ MOVQ buf+0(FP), BX // gobuf
+ MOVQ gobuf_g(BX), DX
+ MOVQ 0(DX), CX // make sure g != nil
+ JMP gogo<>(SB)
+
+TEXT gogo<>(SB), NOSPLIT, $0
+ get_tls(CX)
+ MOVQ DX, g(CX)
+ MOVQ DX, R14 // set the g register
+ MOVQ gobuf_sp(BX), SP // restore SP
+ MOVQ gobuf_ret(BX), AX
+ MOVQ gobuf_ctxt(BX), DX
+ MOVQ gobuf_bp(BX), BP
+ MOVQ $0, gobuf_sp(BX) // clear to help garbage collector
+ MOVQ $0, gobuf_ret(BX)
+ MOVQ $0, gobuf_ctxt(BX)
+ MOVQ $0, gobuf_bp(BX)
+ MOVQ gobuf_pc(BX), BX
+ JMP BX
+
+// func mcall(fn func(*g))
+// Switch to m->g0's stack, call fn(g).
+// Fn must never return. It should gogo(&g->sched)
+// to keep running g.
+TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT, $0-8
+ MOVQ AX, DX // DX = fn
+
+ // Save state in g->sched. The caller's SP and PC are restored by gogo to
+ // resume execution in the caller's frame (implicit return). The caller's BP
+ // is also restored to support frame pointer unwinding.
+ MOVQ SP, BX // hide (SP) reads from vet
+ MOVQ 8(BX), BX // caller's PC
+ MOVQ BX, (g_sched+gobuf_pc)(R14)
+ LEAQ fn+0(FP), BX // caller's SP
+ MOVQ BX, (g_sched+gobuf_sp)(R14)
+ // Get the caller's frame pointer by dereferencing BP. Storing BP as it is
+ // can cause a frame pointer cycle, see CL 476235.
+ MOVQ (BP), BX // caller's BP
+ MOVQ BX, (g_sched+gobuf_bp)(R14)
+
+ // switch to m->g0 & its stack, call fn
+ MOVQ g_m(R14), BX
+ MOVQ m_g0(BX), SI // SI = g.m.g0
+ CMPQ SI, R14 // if g == m->g0 call badmcall
+ JNE goodm
+ JMP runtime·badmcall(SB)
+goodm:
+ MOVQ R14, AX // AX (and arg 0) = g
+ MOVQ SI, R14 // g = g.m.g0
+ get_tls(CX) // Set G in TLS
+ MOVQ R14, g(CX)
+ MOVQ (g_sched+gobuf_sp)(R14), SP // sp = g0.sched.sp
+ PUSHQ AX // open up space for fn's arg spill slot
+ MOVQ 0(DX), R12
+ CALL R12 // fn(g)
+ POPQ AX
+ JMP runtime·badmcall2(SB)
+ RET
+
+// systemstack_switch is a dummy routine that systemstack leaves at the bottom
+// of the G stack. We need to distinguish the routine that
+// lives at the bottom of the G stack from the one that lives
+// at the top of the system stack because the one at the top of
+// the system stack terminates the stack walk (see topofstack()).
+// The frame layout needs to match systemstack
+// so that it can pretend to be systemstack_switch.
+TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
+ UNDEF
+ // Make sure this function is not leaf,
+ // so the frame is saved.
+ CALL runtime·abort(SB)
+ RET
+
+// func systemstack(fn func())
+TEXT runtime·systemstack(SB), NOSPLIT, $0-8
+ MOVQ fn+0(FP), DI // DI = fn
+ get_tls(CX)
+ MOVQ g(CX), AX // AX = g
+ MOVQ g_m(AX), BX // BX = m
+
+ CMPQ AX, m_gsignal(BX)
+ JEQ noswitch
+
+ MOVQ m_g0(BX), DX // DX = g0
+ CMPQ AX, DX
+ JEQ noswitch
+
+ CMPQ AX, m_curg(BX)
+ JNE bad
+
+ // Switch stacks.
+ // The original frame pointer is stored in BP,
+ // which is useful for stack unwinding.
+ // Save our state in g->sched. Pretend to
+ // be systemstack_switch if the G stack is scanned.
+ CALL gosave_systemstack_switch<>(SB)
+
+ // switch to g0
+ MOVQ DX, g(CX)
+ MOVQ DX, R14 // set the g register
+ MOVQ (g_sched+gobuf_sp)(DX), SP
+
+ // call target function
+ MOVQ DI, DX
+ MOVQ 0(DI), DI
+ CALL DI
+
+ // switch back to g
+ get_tls(CX)
+ MOVQ g(CX), AX
+ MOVQ g_m(AX), BX
+ MOVQ m_curg(BX), AX
+ MOVQ AX, g(CX)
+ MOVQ (g_sched+gobuf_sp)(AX), SP
+ MOVQ (g_sched+gobuf_bp)(AX), BP
+ MOVQ $0, (g_sched+gobuf_sp)(AX)
+ MOVQ $0, (g_sched+gobuf_bp)(AX)
+ RET
+
+noswitch:
+ // already on m stack; tail call the function
+ // Using a tail call here cleans up tracebacks since we won't stop
+ // at an intermediate systemstack.
+ MOVQ DI, DX
+ MOVQ 0(DI), DI
+ // The function epilogue is not called on a tail call.
+ // Pop BP from the stack to simulate it.
+ POPQ BP
+ JMP DI
+
+bad:
+ // Bad: g is not gsignal, not g0, not curg. What is it?
+ MOVQ $runtime·badsystemstack(SB), AX
+ CALL AX
+ INT $3
+
+
+/*
+ * support for morestack
+ */
+
+// Called during function prolog when more stack is needed.
+//
+// The traceback routines see morestack on a g0 as being
+// the top of a stack (for example, morestack calling newstack
+// calling the scheduler calling newm calling gc), so we must
+// record an argument size. For that purpose, it has no arguments.
+TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
+ // Cannot grow scheduler stack (m->g0).
+ get_tls(CX)
+ MOVQ g(CX), BX
+ MOVQ g_m(BX), BX
+ MOVQ m_g0(BX), SI
+ CMPQ g(CX), SI
+ JNE 3(PC)
+ CALL runtime·badmorestackg0(SB)
+ CALL runtime·abort(SB)
+
+ // Cannot grow signal stack (m->gsignal).
+ MOVQ m_gsignal(BX), SI
+ CMPQ g(CX), SI
+ JNE 3(PC)
+ CALL runtime·badmorestackgsignal(SB)
+ CALL runtime·abort(SB)
+
+ // Called from f.
+ // Set m->morebuf to f's caller.
+ NOP SP // tell vet SP changed - stop checking offsets
+ MOVQ 8(SP), AX // f's caller's PC
+ MOVQ AX, (m_morebuf+gobuf_pc)(BX)
+ LEAQ 16(SP), AX // f's caller's SP
+ MOVQ AX, (m_morebuf+gobuf_sp)(BX)
+ get_tls(CX)
+ MOVQ g(CX), SI
+ MOVQ SI, (m_morebuf+gobuf_g)(BX)
+
+ // Set g->sched to context in f.
+ MOVQ 0(SP), AX // f's PC
+ MOVQ AX, (g_sched+gobuf_pc)(SI)
+ LEAQ 8(SP), AX // f's SP
+ MOVQ AX, (g_sched+gobuf_sp)(SI)
+ MOVQ BP, (g_sched+gobuf_bp)(SI)
+ MOVQ DX, (g_sched+gobuf_ctxt)(SI)
+
+ // Call newstack on m->g0's stack.
+ MOVQ m_g0(BX), BX
+ MOVQ BX, g(CX)
+ MOVQ (g_sched+gobuf_sp)(BX), SP
+ MOVQ (g_sched+gobuf_bp)(BX), BP
+ CALL runtime·newstack(SB)
+ CALL runtime·abort(SB) // crash if newstack returns
+ RET
+
+// morestack but not preserving ctxt.
+TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0
+ MOVL $0, DX
+ JMP runtime·morestack(SB)
+
+// spillArgs stores return values from registers to a *internal/abi.RegArgs in R12.
+TEXT ·spillArgs(SB),NOSPLIT,$0-0
+ MOVQ AX, 0(R12)
+ MOVQ BX, 8(R12)
+ MOVQ CX, 16(R12)
+ MOVQ DI, 24(R12)
+ MOVQ SI, 32(R12)
+ MOVQ R8, 40(R12)
+ MOVQ R9, 48(R12)
+ MOVQ R10, 56(R12)
+ MOVQ R11, 64(R12)
+ MOVQ X0, 72(R12)
+ MOVQ X1, 80(R12)
+ MOVQ X2, 88(R12)
+ MOVQ X3, 96(R12)
+ MOVQ X4, 104(R12)
+ MOVQ X5, 112(R12)
+ MOVQ X6, 120(R12)
+ MOVQ X7, 128(R12)
+ MOVQ X8, 136(R12)
+ MOVQ X9, 144(R12)
+ MOVQ X10, 152(R12)
+ MOVQ X11, 160(R12)
+ MOVQ X12, 168(R12)
+ MOVQ X13, 176(R12)
+ MOVQ X14, 184(R12)
+ RET
+
+// unspillArgs loads args into registers from a *internal/abi.RegArgs in R12.
+TEXT ·unspillArgs(SB),NOSPLIT,$0-0
+ MOVQ 0(R12), AX
+ MOVQ 8(R12), BX
+ MOVQ 16(R12), CX
+ MOVQ 24(R12), DI
+ MOVQ 32(R12), SI
+ MOVQ 40(R12), R8
+ MOVQ 48(R12), R9
+ MOVQ 56(R12), R10
+ MOVQ 64(R12), R11
+ MOVQ 72(R12), X0
+ MOVQ 80(R12), X1
+ MOVQ 88(R12), X2
+ MOVQ 96(R12), X3
+ MOVQ 104(R12), X4
+ MOVQ 112(R12), X5
+ MOVQ 120(R12), X6
+ MOVQ 128(R12), X7
+ MOVQ 136(R12), X8
+ MOVQ 144(R12), X9
+ MOVQ 152(R12), X10
+ MOVQ 160(R12), X11
+ MOVQ 168(R12), X12
+ MOVQ 176(R12), X13
+ MOVQ 184(R12), X14
+ RET
+
+// reflectcall: call a function with the given argument list
+// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
+// we don't have variable-sized frames, so we use a small number
+// of constant-sized-frame functions to encode a few bits of size in the pc.
+// Caution: ugly multiline assembly macros in your future!
+
+#define DISPATCH(NAME,MAXSIZE) \
+ CMPQ CX, $MAXSIZE; \
+ JA 3(PC); \
+ MOVQ $NAME(SB), AX; \
+ JMP AX
+// Note: can't just "JMP NAME(SB)" - bad inlining results.
+
+TEXT ·reflectcall(SB), NOSPLIT, $0-48
+ MOVLQZX frameSize+32(FP), CX
+ DISPATCH(runtime·call16, 16)
+ DISPATCH(runtime·call32, 32)
+ DISPATCH(runtime·call64, 64)
+ DISPATCH(runtime·call128, 128)
+ DISPATCH(runtime·call256, 256)
+ DISPATCH(runtime·call512, 512)
+ DISPATCH(runtime·call1024, 1024)
+ DISPATCH(runtime·call2048, 2048)
+ DISPATCH(runtime·call4096, 4096)
+ DISPATCH(runtime·call8192, 8192)
+ DISPATCH(runtime·call16384, 16384)
+ DISPATCH(runtime·call32768, 32768)
+ DISPATCH(runtime·call65536, 65536)
+ DISPATCH(runtime·call131072, 131072)
+ DISPATCH(runtime·call262144, 262144)
+ DISPATCH(runtime·call524288, 524288)
+ DISPATCH(runtime·call1048576, 1048576)
+ DISPATCH(runtime·call2097152, 2097152)
+ DISPATCH(runtime·call4194304, 4194304)
+ DISPATCH(runtime·call8388608, 8388608)
+ DISPATCH(runtime·call16777216, 16777216)
+ DISPATCH(runtime·call33554432, 33554432)
+ DISPATCH(runtime·call67108864, 67108864)
+ DISPATCH(runtime·call134217728, 134217728)
+ DISPATCH(runtime·call268435456, 268435456)
+ DISPATCH(runtime·call536870912, 536870912)
+ DISPATCH(runtime·call1073741824, 1073741824)
+ MOVQ $runtime·badreflectcall(SB), AX
+ JMP AX
+
+#define CALLFN(NAME,MAXSIZE) \
+TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \
+ NO_LOCAL_POINTERS; \
+ /* copy arguments to stack */ \
+ MOVQ stackArgs+16(FP), SI; \
+ MOVLQZX stackArgsSize+24(FP), CX; \
+ MOVQ SP, DI; \
+ REP;MOVSB; \
+ /* set up argument registers */ \
+ MOVQ regArgs+40(FP), R12; \
+ CALL ·unspillArgs(SB); \
+ /* call function */ \
+ MOVQ f+8(FP), DX; \
+ PCDATA $PCDATA_StackMapIndex, $0; \
+ MOVQ (DX), R12; \
+ CALL R12; \
+ /* copy register return values back */ \
+ MOVQ regArgs+40(FP), R12; \
+ CALL ·spillArgs(SB); \
+ MOVLQZX stackArgsSize+24(FP), CX; \
+ MOVLQZX stackRetOffset+28(FP), BX; \
+ MOVQ stackArgs+16(FP), DI; \
+ MOVQ stackArgsType+0(FP), DX; \
+ MOVQ SP, SI; \
+ ADDQ BX, DI; \
+ ADDQ BX, SI; \
+ SUBQ BX, CX; \
+ CALL callRet<>(SB); \
+ RET
+
+// callRet copies return values back at the end of call*. This is a
+// separate function so it can allocate stack space for the arguments
+// to reflectcallmove. It does not follow the Go ABI; it expects its
+// arguments in registers.
+TEXT callRet<>(SB), NOSPLIT, $40-0
+ NO_LOCAL_POINTERS
+ MOVQ DX, 0(SP)
+ MOVQ DI, 8(SP)
+ MOVQ SI, 16(SP)
+ MOVQ CX, 24(SP)
+ MOVQ R12, 32(SP)
+ CALL runtime·reflectcallmove(SB)
+ RET
+
+CALLFN(·call16, 16)
+CALLFN(·call32, 32)
+CALLFN(·call64, 64)
+CALLFN(·call128, 128)
+CALLFN(·call256, 256)
+CALLFN(·call512, 512)
+CALLFN(·call1024, 1024)
+CALLFN(·call2048, 2048)
+CALLFN(·call4096, 4096)
+CALLFN(·call8192, 8192)
+CALLFN(·call16384, 16384)
+CALLFN(·call32768, 32768)
+CALLFN(·call65536, 65536)
+CALLFN(·call131072, 131072)
+CALLFN(·call262144, 262144)
+CALLFN(·call524288, 524288)
+CALLFN(·call1048576, 1048576)
+CALLFN(·call2097152, 2097152)
+CALLFN(·call4194304, 4194304)
+CALLFN(·call8388608, 8388608)
+CALLFN(·call16777216, 16777216)
+CALLFN(·call33554432, 33554432)
+CALLFN(·call67108864, 67108864)
+CALLFN(·call134217728, 134217728)
+CALLFN(·call268435456, 268435456)
+CALLFN(·call536870912, 536870912)
+CALLFN(·call1073741824, 1073741824)
+
+TEXT runtime·procyield(SB),NOSPLIT,$0-0
+ MOVL cycles+0(FP), AX
+again:
+ PAUSE
+ SUBL $1, AX
+ JNZ again
+ RET
+
+
+TEXT ·publicationBarrier<ABIInternal>(SB),NOSPLIT,$0-0
+ // Stores are already ordered on x86, so this is just a
+ // compile barrier.
+ RET
+
+// Save state of caller into g->sched,
+// but using fake PC from systemstack_switch.
+// Must only be called from functions with frame pointer
+// and without locals ($0) or else unwinding from
+// systemstack_switch is incorrect.
+// Smashes R9.
+TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
+ // Take systemstack_switch PC and add 8 bytes to skip
+ // the prologue. The final location does not matter
+ // as long as we are between the prologue and the epilogue.
+ MOVQ $runtime·systemstack_switch+8(SB), R9
+ MOVQ R9, (g_sched+gobuf_pc)(R14)
+ LEAQ 8(SP), R9
+ MOVQ R9, (g_sched+gobuf_sp)(R14)
+ MOVQ $0, (g_sched+gobuf_ret)(R14)
+ MOVQ BP, (g_sched+gobuf_bp)(R14)
+ // Assert ctxt is zero. See func save.
+ MOVQ (g_sched+gobuf_ctxt)(R14), R9
+ TESTQ R9, R9
+ JZ 2(PC)
+ CALL runtime·abort(SB)
+ RET
+
+// func asmcgocall_no_g(fn, arg unsafe.Pointer)
+// Call fn(arg) aligned appropriately for the gcc ABI.
+// Called on a system stack, and there may be no g yet (during needm).
+TEXT ·asmcgocall_no_g(SB),NOSPLIT,$32-16
+ MOVQ fn+0(FP), AX
+ MOVQ arg+8(FP), BX
+ MOVQ SP, DX
+ ANDQ $~15, SP // alignment
+ MOVQ DX, 8(SP)
+ MOVQ BX, DI // DI = first argument in AMD64 ABI
+ MOVQ BX, CX // CX = first argument in Win64
+ CALL AX
+ MOVQ 8(SP), DX
+ MOVQ DX, SP
+ RET
+
+// func asmcgocall(fn, arg unsafe.Pointer) int32
+// Call fn(arg) on the scheduler stack,
+// aligned appropriately for the gcc ABI.
+// See cgocall.go for more details.
+TEXT ·asmcgocall(SB),NOSPLIT,$0-20
+ MOVQ fn+0(FP), AX
+ MOVQ arg+8(FP), BX
+
+ MOVQ SP, DX
+
+ // Figure out if we need to switch to m->g0 stack.
+ // We get called to create new OS threads too, and those
+ // come in on the m->g0 stack already. Or we might already
+ // be on the m->gsignal stack.
+ get_tls(CX)
+ MOVQ g(CX), DI
+ CMPQ DI, $0
+ JEQ nosave
+ MOVQ g_m(DI), R8
+ MOVQ m_gsignal(R8), SI
+ CMPQ DI, SI
+ JEQ nosave
+ MOVQ m_g0(R8), SI
+ CMPQ DI, SI
+ JEQ nosave
+
+ // Switch to system stack.
+ // The original frame pointer is stored in BP,
+ // which is useful for stack unwinding.
+ CALL gosave_systemstack_switch<>(SB)
+ MOVQ SI, g(CX)
+ MOVQ (g_sched+gobuf_sp)(SI), SP
+
+ // Now on a scheduling stack (a pthread-created stack).
+ // Make sure we have enough room for 4 stack-backed fast-call
+ // registers as per windows amd64 calling convention.
+ SUBQ $64, SP
+ ANDQ $~15, SP // alignment for gcc ABI
+ MOVQ DI, 48(SP) // save g
+ MOVQ (g_stack+stack_hi)(DI), DI
+ SUBQ DX, DI
+ MOVQ DI, 40(SP) // save depth in stack (can't just save SP, as stack might be copied during a callback)
+ MOVQ BX, DI // DI = first argument in AMD64 ABI
+ MOVQ BX, CX // CX = first argument in Win64
+ CALL AX
+
+ // Restore registers, g, stack pointer.
+ get_tls(CX)
+ MOVQ 48(SP), DI
+ MOVQ (g_stack+stack_hi)(DI), SI
+ SUBQ 40(SP), SI
+ MOVQ DI, g(CX)
+ MOVQ SI, SP
+
+ MOVL AX, ret+16(FP)
+ RET
+
+nosave:
+ // Running on a system stack, perhaps even without a g.
+ // Having no g can happen during thread creation or thread teardown
+ // (see needm/dropm on Solaris, for example).
+ // This code is like the above sequence but without saving/restoring g
+ // and without worrying about the stack moving out from under us
+ // (because we're on a system stack, not a goroutine stack).
+ // The above code could be used directly if already on a system stack,
+ // but then the only path through this code would be a rare case on Solaris.
+ // Using this code for all "already on system stack" calls exercises it more,
+ // which should help keep it correct.
+ SUBQ $64, SP
+ ANDQ $~15, SP
+ MOVQ $0, 48(SP) // where above code stores g, in case someone looks during debugging
+ MOVQ DX, 40(SP) // save original stack pointer
+ MOVQ BX, DI // DI = first argument in AMD64 ABI
+ MOVQ BX, CX // CX = first argument in Win64
+ CALL AX
+ MOVQ 40(SP), SI // restore original stack pointer
+ MOVQ SI, SP
+ MOVL AX, ret+16(FP)
+ RET
+
+#ifdef GOOS_windows
+// Dummy TLS that's used on Windows so that we don't crash trying
+// to restore the G register in needm. needm and its callees are
+// very careful never to actually use the G, the TLS just can't be
+// unset since we're in Go code.
+GLOBL zeroTLS<>(SB),RODATA,$const_tlsSize
+#endif
+
+// func cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
+// See cgocall.go for more details.
+TEXT ·cgocallback(SB),NOSPLIT,$24-24
+ NO_LOCAL_POINTERS
+
+ // Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
+ // It is used to dropm while thread is exiting.
+ MOVQ fn+0(FP), AX
+ CMPQ AX, $0
+ JNE loadg
+ // Restore the g from frame.
+ get_tls(CX)
+ MOVQ frame+8(FP), BX
+ MOVQ BX, g(CX)
+ JMP dropm
+
+loadg:
+ // If g is nil, Go did not create the current thread,
+ // or if this thread never called into Go on pthread platforms.
+ // Call needm to obtain one m for temporary use.
+ // In this case, we're running on the thread stack, so there's
+ // lots of space, but the linker doesn't know. Hide the call from
+ // the linker analysis by using an indirect call through AX.
+ get_tls(CX)
+#ifdef GOOS_windows
+ MOVL $0, BX
+ CMPQ CX, $0
+ JEQ 2(PC)
+#endif
+ MOVQ g(CX), BX
+ CMPQ BX, $0
+ JEQ needm
+ MOVQ g_m(BX), BX
+ MOVQ BX, savedm-8(SP) // saved copy of oldm
+ JMP havem
+needm:
+#ifdef GOOS_windows
+ // Set up a dummy TLS value. needm is careful not to use it,
+ // but it needs to be there to prevent autogenerated code from
+ // crashing when it loads from it.
+ // We don't need to clear it or anything later because needm
+ // will set up TLS properly.
+ MOVQ $zeroTLS<>(SB), DI
+ CALL runtime·settls(SB)
+#endif
+ // On some platforms (Windows) we cannot call needm through
+ // an ABI wrapper because there's no TLS set up, and the ABI
+ // wrapper will try to restore the G register (R14) from TLS.
+ // Clear X15 because Go expects it and we're not calling
+ // through a wrapper, but otherwise avoid setting the G
+ // register in the wrapper and call needm directly. It
+ // takes no arguments and doesn't return any values so
+ // there's no need to handle that. Clear R14 so that there's
+ // a bad value in there, in case needm tries to use it.
+ XORPS X15, X15
+ XORQ R14, R14
+ MOVQ $runtime·needAndBindM<ABIInternal>(SB), AX
+ CALL AX
+ MOVQ $0, savedm-8(SP)
+ get_tls(CX)
+ MOVQ g(CX), BX
+ MOVQ g_m(BX), BX
+
+ // Set m->sched.sp = SP, so that if a panic happens
+ // during the function we are about to execute, it will
+ // have a valid SP to run on the g0 stack.
+ // The next few lines (after the havem label)
+ // will save this SP onto the stack and then write
+ // the same SP back to m->sched.sp. That seems redundant,
+ // but if an unrecovered panic happens, unwindm will
+ // restore the g->sched.sp from the stack location
+ // and then systemstack will try to use it. If we don't set it here,
+ // that restored SP will be uninitialized (typically 0) and
+ // will not be usable.
+ MOVQ m_g0(BX), SI
+ MOVQ SP, (g_sched+gobuf_sp)(SI)
+
+havem:
+ // Now there's a valid m, and we're running on its m->g0.
+ // Save current m->g0->sched.sp on stack and then set it to SP.
+ // Save current sp in m->g0->sched.sp in preparation for
+ // switch back to m->curg stack.
+ // NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
+ MOVQ m_g0(BX), SI
+ MOVQ (g_sched+gobuf_sp)(SI), AX
+ MOVQ AX, 0(SP)
+ MOVQ SP, (g_sched+gobuf_sp)(SI)
+
+ // Switch to m->curg stack and call runtime.cgocallbackg.
+ // Because we are taking over the execution of m->curg
+ // but *not* resuming what had been running, we need to
+ // save that information (m->curg->sched) so we can restore it.
+ // We can restore m->curg->sched.sp easily, because calling
+ // runtime.cgocallbackg leaves SP unchanged upon return.
+ // To save m->curg->sched.pc, we push it onto the curg stack and
+ // open a frame the same size as cgocallback's g0 frame.
+ // Once we switch to the curg stack, the pushed PC will appear
+ // to be the return PC of cgocallback, so that the traceback
+ // will seamlessly trace back into the earlier calls.
+ MOVQ m_curg(BX), SI
+ MOVQ SI, g(CX)
+ MOVQ (g_sched+gobuf_sp)(SI), DI // prepare stack as DI
+ MOVQ (g_sched+gobuf_pc)(SI), BX
+ MOVQ BX, -8(DI) // "push" return PC on the g stack
+ // Gather our arguments into registers.
+ MOVQ fn+0(FP), BX
+ MOVQ frame+8(FP), CX
+ MOVQ ctxt+16(FP), DX
+ // Compute the size of the frame, including return PC and, if
+ // GOEXPERIMENT=framepointer, the saved base pointer
+ LEAQ fn+0(FP), AX
+ SUBQ SP, AX // AX is our actual frame size
+ SUBQ AX, DI // Allocate the same frame size on the g stack
+ MOVQ DI, SP
+
+ MOVQ BX, 0(SP)
+ MOVQ CX, 8(SP)
+ MOVQ DX, 16(SP)
+ MOVQ $runtime·cgocallbackg(SB), AX
+ CALL AX // indirect call to bypass nosplit check. We're on a different stack now.
+
+ // Compute the size of the frame again. FP and SP have
+ // completely different values here than they did above,
+ // but only their difference matters.
+ LEAQ fn+0(FP), AX
+ SUBQ SP, AX
+
+ // Restore g->sched (== m->curg->sched) from saved values.
+ get_tls(CX)
+ MOVQ g(CX), SI
+ MOVQ SP, DI
+ ADDQ AX, DI
+ MOVQ -8(DI), BX
+ MOVQ BX, (g_sched+gobuf_pc)(SI)
+ MOVQ DI, (g_sched+gobuf_sp)(SI)
+
+ // Switch back to m->g0's stack and restore m->g0->sched.sp.
+ // (Unlike m->curg, the g0 goroutine never uses sched.pc,
+ // so we do not have to restore it.)
+ MOVQ g(CX), BX
+ MOVQ g_m(BX), BX
+ MOVQ m_g0(BX), SI
+ MOVQ SI, g(CX)
+ MOVQ (g_sched+gobuf_sp)(SI), SP
+ MOVQ 0(SP), AX
+ MOVQ AX, (g_sched+gobuf_sp)(SI)
+
+ // If the m on entry was nil, we called needm above to borrow an m,
+ // 1. for the duration of the call on non-pthread platforms,
+ // 2. or the duration of the C thread alive on pthread platforms.
+ // If the m on entry wasn't nil,
+ // 1. the thread might be a Go thread,
+ // 2. or it wasn't the first call from a C thread on pthread platforms,
+ // since then we skip dropm to reuse the m in the first call.
+ MOVQ savedm-8(SP), BX
+ CMPQ BX, $0
+ JNE done
+
+ // Skip dropm to reuse it in the next call, when a pthread key has been created.
+ MOVQ _cgo_pthread_key_created(SB), AX
+ // It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
+ CMPQ AX, $0
+ JEQ dropm
+ CMPQ (AX), $0
+ JNE done
+
+dropm:
+ MOVQ $runtime·dropm(SB), AX
+ CALL AX
+#ifdef GOOS_windows
+ // We need to clear the TLS pointer in case the next
+ // thread that comes into Go tries to reuse that space
+ // but uses the same M.
+ XORQ DI, DI
+ CALL runtime·settls(SB)
+#endif
+done:
+
+ // Done!
+ RET
+
+// func setg(gg *g)
+// set g. for use by needm.
+TEXT runtime·setg(SB), NOSPLIT, $0-8
+ MOVQ gg+0(FP), BX
+ get_tls(CX)
+ MOVQ BX, g(CX)
+ RET
+
+// void setg_gcc(G*); set g called from gcc.
+TEXT setg_gcc<>(SB),NOSPLIT,$0
+ get_tls(AX)
+ MOVQ DI, g(AX)
+ MOVQ DI, R14 // set the g register
+ RET
+
+TEXT runtime·abort(SB),NOSPLIT,$0-0
+ INT $3
+loop:
+ JMP loop
+
+// check that SP is in range [g->stack.lo, g->stack.hi)
+TEXT runtime·stackcheck(SB), NOSPLIT|NOFRAME, $0-0
+ get_tls(CX)
+ MOVQ g(CX), AX
+ CMPQ (g_stack+stack_hi)(AX), SP
+ JHI 2(PC)
+ CALL runtime·abort(SB)
+ CMPQ SP, (g_stack+stack_lo)(AX)
+ JHI 2(PC)
+ CALL runtime·abort(SB)
+ RET
+
+// func cputicks() int64
+TEXT runtime·cputicks(SB),NOSPLIT,$0-0
+ CMPB internal∕cpu·X86+const_offsetX86HasRDTSCP(SB), $1
+ JNE fences
+ // Instruction stream serializing RDTSCP is supported.
+ // RDTSCP is supported by Intel Nehalem (2008) and
+ // AMD K8 Rev. F (2006) and newer.
+ RDTSCP
+done:
+ SHLQ $32, DX
+ ADDQ DX, AX
+ MOVQ AX, ret+0(FP)
+ RET
+fences:
+ // MFENCE is instruction stream serializing and flushes the
+ // store buffers on AMD. The serialization semantics of LFENCE on AMD
+ // are dependent on MSR C001_1029 and CPU generation.
+ // LFENCE on Intel does wait for all previous instructions to have executed.
+ // Intel recommends MFENCE;LFENCE in its manuals before RDTSC to have all
+ // previous instructions executed and all previous loads and stores to globally visible.
+ // Using MFENCE;LFENCE here aligns the serializing properties without
+ // runtime detection of CPU manufacturer.
+ MFENCE
+ LFENCE
+ RDTSC
+ JMP done
+
+// func memhash(p unsafe.Pointer, h, s uintptr) uintptr
+// hash function using AES hardware instructions
+TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT,$0-32
+ // AX = ptr to data
+ // BX = seed
+ // CX = size
+ CMPB runtime·useAeshash(SB), $0
+ JEQ noaes
+ JMP aeshashbody<>(SB)
+noaes:
+ JMP runtime·memhashFallback<ABIInternal>(SB)
+
+// func strhash(p unsafe.Pointer, h uintptr) uintptr
+TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT,$0-24
+ // AX = ptr to string struct
+ // BX = seed
+ CMPB runtime·useAeshash(SB), $0
+ JEQ noaes
+ MOVQ 8(AX), CX // length of string
+ MOVQ (AX), AX // string data
+ JMP aeshashbody<>(SB)
+noaes:
+ JMP runtime·strhashFallback<ABIInternal>(SB)
+
+// AX: data
+// BX: hash seed
+// CX: length
+// At return: AX = return value
+TEXT aeshashbody<>(SB),NOSPLIT,$0-0
+ // Fill an SSE register with our seeds.
+ MOVQ BX, X0 // 64 bits of per-table hash seed
+ PINSRW $4, CX, X0 // 16 bits of length
+ PSHUFHW $0, X0, X0 // repeat length 4 times total
+ MOVO X0, X1 // save unscrambled seed
+ PXOR runtime·aeskeysched(SB), X0 // xor in per-process seed
+ AESENC X0, X0 // scramble seed
+
+ CMPQ CX, $16
+ JB aes0to15
+ JE aes16
+ CMPQ CX, $32
+ JBE aes17to32
+ CMPQ CX, $64
+ JBE aes33to64
+ CMPQ CX, $128
+ JBE aes65to128
+ JMP aes129plus
+
+aes0to15:
+ TESTQ CX, CX
+ JE aes0
+
+ ADDQ $16, AX
+ TESTW $0xff0, AX
+ JE endofpage
+
+ // 16 bytes loaded at this address won't cross
+ // a page boundary, so we can load it directly.
+ MOVOU -16(AX), X1
+ ADDQ CX, CX
+ MOVQ $masks<>(SB), AX
+ PAND (AX)(CX*8), X1
+final1:
+ PXOR X0, X1 // xor data with seed
+ AESENC X1, X1 // scramble combo 3 times
+ AESENC X1, X1
+ AESENC X1, X1
+ MOVQ X1, AX // return X1
+ RET
+
+endofpage:
+ // address ends in 1111xxxx. Might be up against
+ // a page boundary, so load ending at last byte.
+ // Then shift bytes down using pshufb.
+ MOVOU -32(AX)(CX*1), X1
+ ADDQ CX, CX
+ MOVQ $shifts<>(SB), AX
+ PSHUFB (AX)(CX*8), X1
+ JMP final1
+
+aes0:
+ // Return scrambled input seed
+ AESENC X0, X0
+ MOVQ X0, AX // return X0
+ RET
+
+aes16:
+ MOVOU (AX), X1
+ JMP final1
+
+aes17to32:
+ // make second starting seed
+ PXOR runtime·aeskeysched+16(SB), X1
+ AESENC X1, X1
+
+ // load data to be hashed
+ MOVOU (AX), X2
+ MOVOU -16(AX)(CX*1), X3
+
+ // xor with seed
+ PXOR X0, X2
+ PXOR X1, X3
+
+ // scramble 3 times
+ AESENC X2, X2
+ AESENC X3, X3
+ AESENC X2, X2
+ AESENC X3, X3
+ AESENC X2, X2
+ AESENC X3, X3
+
+ // combine results
+ PXOR X3, X2
+ MOVQ X2, AX // return X2
+ RET
+
+aes33to64:
+ // make 3 more starting seeds
+ MOVO X1, X2
+ MOVO X1, X3
+ PXOR runtime·aeskeysched+16(SB), X1
+ PXOR runtime·aeskeysched+32(SB), X2
+ PXOR runtime·aeskeysched+48(SB), X3
+ AESENC X1, X1
+ AESENC X2, X2
+ AESENC X3, X3
+
+ MOVOU (AX), X4
+ MOVOU 16(AX), X5
+ MOVOU -32(AX)(CX*1), X6
+ MOVOU -16(AX)(CX*1), X7
+
+ PXOR X0, X4
+ PXOR X1, X5
+ PXOR X2, X6
+ PXOR X3, X7
+
+ AESENC X4, X4
+ AESENC X5, X5
+ AESENC X6, X6
+ AESENC X7, X7
+
+ AESENC X4, X4
+ AESENC X5, X5
+ AESENC X6, X6
+ AESENC X7, X7
+
+ AESENC X4, X4
+ AESENC X5, X5
+ AESENC X6, X6
+ AESENC X7, X7
+
+ PXOR X6, X4
+ PXOR X7, X5
+ PXOR X5, X4
+ MOVQ X4, AX // return X4
+ RET
+
+aes65to128:
+ // make 7 more starting seeds
+ MOVO X1, X2
+ MOVO X1, X3
+ MOVO X1, X4
+ MOVO X1, X5
+ MOVO X1, X6
+ MOVO X1, X7
+ PXOR runtime·aeskeysched+16(SB), X1
+ PXOR runtime·aeskeysched+32(SB), X2
+ PXOR runtime·aeskeysched+48(SB), X3
+ PXOR runtime·aeskeysched+64(SB), X4
+ PXOR runtime·aeskeysched+80(SB), X5
+ PXOR runtime·aeskeysched+96(SB), X6
+ PXOR runtime·aeskeysched+112(SB), X7
+ AESENC X1, X1
+ AESENC X2, X2
+ AESENC X3, X3
+ AESENC X4, X4
+ AESENC X5, X5
+ AESENC X6, X6
+ AESENC X7, X7
+
+ // load data
+ MOVOU (AX), X8
+ MOVOU 16(AX), X9
+ MOVOU 32(AX), X10
+ MOVOU 48(AX), X11
+ MOVOU -64(AX)(CX*1), X12
+ MOVOU -48(AX)(CX*1), X13
+ MOVOU -32(AX)(CX*1), X14
+ MOVOU -16(AX)(CX*1), X15
+
+ // xor with seed
+ PXOR X0, X8
+ PXOR X1, X9
+ PXOR X2, X10
+ PXOR X3, X11
+ PXOR X4, X12
+ PXOR X5, X13
+ PXOR X6, X14
+ PXOR X7, X15
+
+ // scramble 3 times
+ AESENC X8, X8
+ AESENC X9, X9
+ AESENC X10, X10
+ AESENC X11, X11
+ AESENC X12, X12
+ AESENC X13, X13
+ AESENC X14, X14
+ AESENC X15, X15
+
+ AESENC X8, X8
+ AESENC X9, X9
+ AESENC X10, X10
+ AESENC X11, X11
+ AESENC X12, X12
+ AESENC X13, X13
+ AESENC X14, X14
+ AESENC X15, X15
+
+ AESENC X8, X8
+ AESENC X9, X9
+ AESENC X10, X10
+ AESENC X11, X11
+ AESENC X12, X12
+ AESENC X13, X13
+ AESENC X14, X14
+ AESENC X15, X15
+
+ // combine results
+ PXOR X12, X8
+ PXOR X13, X9
+ PXOR X14, X10
+ PXOR X15, X11
+ PXOR X10, X8
+ PXOR X11, X9
+ PXOR X9, X8
+ // X15 must be zero on return
+ PXOR X15, X15
+ MOVQ X8, AX // return X8
+ RET
+
+aes129plus:
+ // make 7 more starting seeds
+ MOVO X1, X2
+ MOVO X1, X3
+ MOVO X1, X4
+ MOVO X1, X5
+ MOVO X1, X6
+ MOVO X1, X7
+ PXOR runtime·aeskeysched+16(SB), X1
+ PXOR runtime·aeskeysched+32(SB), X2
+ PXOR runtime·aeskeysched+48(SB), X3
+ PXOR runtime·aeskeysched+64(SB), X4
+ PXOR runtime·aeskeysched+80(SB), X5
+ PXOR runtime·aeskeysched+96(SB), X6
+ PXOR runtime·aeskeysched+112(SB), X7
+ AESENC X1, X1
+ AESENC X2, X2
+ AESENC X3, X3
+ AESENC X4, X4
+ AESENC X5, X5
+ AESENC X6, X6
+ AESENC X7, X7
+
+ // start with last (possibly overlapping) block
+ MOVOU -128(AX)(CX*1), X8
+ MOVOU -112(AX)(CX*1), X9
+ MOVOU -96(AX)(CX*1), X10
+ MOVOU -80(AX)(CX*1), X11
+ MOVOU -64(AX)(CX*1), X12
+ MOVOU -48(AX)(CX*1), X13
+ MOVOU -32(AX)(CX*1), X14
+ MOVOU -16(AX)(CX*1), X15
+
+ // xor in seed
+ PXOR X0, X8
+ PXOR X1, X9
+ PXOR X2, X10
+ PXOR X3, X11
+ PXOR X4, X12
+ PXOR X5, X13
+ PXOR X6, X14
+ PXOR X7, X15
+
+ // compute number of remaining 128-byte blocks
+ DECQ CX
+ SHRQ $7, CX
+
+aesloop:
+ // scramble state
+ AESENC X8, X8
+ AESENC X9, X9
+ AESENC X10, X10
+ AESENC X11, X11
+ AESENC X12, X12
+ AESENC X13, X13
+ AESENC X14, X14
+ AESENC X15, X15
+
+ // scramble state, xor in a block
+ MOVOU (AX), X0
+ MOVOU 16(AX), X1
+ MOVOU 32(AX), X2
+ MOVOU 48(AX), X3
+ AESENC X0, X8
+ AESENC X1, X9
+ AESENC X2, X10
+ AESENC X3, X11
+ MOVOU 64(AX), X4
+ MOVOU 80(AX), X5
+ MOVOU 96(AX), X6
+ MOVOU 112(AX), X7
+ AESENC X4, X12
+ AESENC X5, X13
+ AESENC X6, X14
+ AESENC X7, X15
+
+ ADDQ $128, AX
+ DECQ CX
+ JNE aesloop
+
+ // 3 more scrambles to finish
+ AESENC X8, X8
+ AESENC X9, X9
+ AESENC X10, X10
+ AESENC X11, X11
+ AESENC X12, X12
+ AESENC X13, X13
+ AESENC X14, X14
+ AESENC X15, X15
+ AESENC X8, X8
+ AESENC X9, X9
+ AESENC X10, X10
+ AESENC X11, X11
+ AESENC X12, X12
+ AESENC X13, X13
+ AESENC X14, X14
+ AESENC X15, X15
+ AESENC X8, X8
+ AESENC X9, X9
+ AESENC X10, X10
+ AESENC X11, X11
+ AESENC X12, X12
+ AESENC X13, X13
+ AESENC X14, X14
+ AESENC X15, X15
+
+ PXOR X12, X8
+ PXOR X13, X9
+ PXOR X14, X10
+ PXOR X15, X11
+ PXOR X10, X8
+ PXOR X11, X9
+ PXOR X9, X8
+ // X15 must be zero on return
+ PXOR X15, X15
+ MOVQ X8, AX // return X8
+ RET
+
+// func memhash32(p unsafe.Pointer, h uintptr) uintptr
+// ABIInternal for performance.
+TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT,$0-24
+ // AX = ptr to data
+ // BX = seed
+ CMPB runtime·useAeshash(SB), $0
+ JEQ noaes
+ MOVQ BX, X0 // X0 = seed
+ PINSRD $2, (AX), X0 // data
+ AESENC runtime·aeskeysched+0(SB), X0
+ AESENC runtime·aeskeysched+16(SB), X0
+ AESENC runtime·aeskeysched+32(SB), X0
+ MOVQ X0, AX // return X0
+ RET
+noaes:
+ JMP runtime·memhash32Fallback<ABIInternal>(SB)
+
+// func memhash64(p unsafe.Pointer, h uintptr) uintptr
+// ABIInternal for performance.
+TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT,$0-24
+ // AX = ptr to data
+ // BX = seed
+ CMPB runtime·useAeshash(SB), $0
+ JEQ noaes
+ MOVQ BX, X0 // X0 = seed
+ PINSRQ $1, (AX), X0 // data
+ AESENC runtime·aeskeysched+0(SB), X0
+ AESENC runtime·aeskeysched+16(SB), X0
+ AESENC runtime·aeskeysched+32(SB), X0
+ MOVQ X0, AX // return X0
+ RET
+noaes:
+ JMP runtime·memhash64Fallback<ABIInternal>(SB)
+
+// simple mask to get rid of data in the high part of the register.
+DATA masks<>+0x00(SB)/8, $0x0000000000000000
+DATA masks<>+0x08(SB)/8, $0x0000000000000000
+DATA masks<>+0x10(SB)/8, $0x00000000000000ff
+DATA masks<>+0x18(SB)/8, $0x0000000000000000
+DATA masks<>+0x20(SB)/8, $0x000000000000ffff
+DATA masks<>+0x28(SB)/8, $0x0000000000000000
+DATA masks<>+0x30(SB)/8, $0x0000000000ffffff
+DATA masks<>+0x38(SB)/8, $0x0000000000000000
+DATA masks<>+0x40(SB)/8, $0x00000000ffffffff
+DATA masks<>+0x48(SB)/8, $0x0000000000000000
+DATA masks<>+0x50(SB)/8, $0x000000ffffffffff
+DATA masks<>+0x58(SB)/8, $0x0000000000000000
+DATA masks<>+0x60(SB)/8, $0x0000ffffffffffff
+DATA masks<>+0x68(SB)/8, $0x0000000000000000
+DATA masks<>+0x70(SB)/8, $0x00ffffffffffffff
+DATA masks<>+0x78(SB)/8, $0x0000000000000000
+DATA masks<>+0x80(SB)/8, $0xffffffffffffffff
+DATA masks<>+0x88(SB)/8, $0x0000000000000000
+DATA masks<>+0x90(SB)/8, $0xffffffffffffffff
+DATA masks<>+0x98(SB)/8, $0x00000000000000ff
+DATA masks<>+0xa0(SB)/8, $0xffffffffffffffff
+DATA masks<>+0xa8(SB)/8, $0x000000000000ffff
+DATA masks<>+0xb0(SB)/8, $0xffffffffffffffff
+DATA masks<>+0xb8(SB)/8, $0x0000000000ffffff
+DATA masks<>+0xc0(SB)/8, $0xffffffffffffffff
+DATA masks<>+0xc8(SB)/8, $0x00000000ffffffff
+DATA masks<>+0xd0(SB)/8, $0xffffffffffffffff
+DATA masks<>+0xd8(SB)/8, $0x000000ffffffffff
+DATA masks<>+0xe0(SB)/8, $0xffffffffffffffff
+DATA masks<>+0xe8(SB)/8, $0x0000ffffffffffff
+DATA masks<>+0xf0(SB)/8, $0xffffffffffffffff
+DATA masks<>+0xf8(SB)/8, $0x00ffffffffffffff
+GLOBL masks<>(SB),RODATA,$256
+
+// func checkASM() bool
+TEXT ·checkASM(SB),NOSPLIT,$0-1
+ // check that masks<>(SB) and shifts<>(SB) are aligned to 16-byte
+ MOVQ $masks<>(SB), AX
+ MOVQ $shifts<>(SB), BX
+ ORQ BX, AX
+ TESTQ $15, AX
+ SETEQ ret+0(FP)
+ RET
+
+// these are arguments to pshufb. They move data down from
+// the high bytes of the register to the low bytes of the register.
+// index is how many bytes to move.
+DATA shifts<>+0x00(SB)/8, $0x0000000000000000
+DATA shifts<>+0x08(SB)/8, $0x0000000000000000
+DATA shifts<>+0x10(SB)/8, $0xffffffffffffff0f
+DATA shifts<>+0x18(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x20(SB)/8, $0xffffffffffff0f0e
+DATA shifts<>+0x28(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x30(SB)/8, $0xffffffffff0f0e0d
+DATA shifts<>+0x38(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x40(SB)/8, $0xffffffff0f0e0d0c
+DATA shifts<>+0x48(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x50(SB)/8, $0xffffff0f0e0d0c0b
+DATA shifts<>+0x58(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x60(SB)/8, $0xffff0f0e0d0c0b0a
+DATA shifts<>+0x68(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x70(SB)/8, $0xff0f0e0d0c0b0a09
+DATA shifts<>+0x78(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x80(SB)/8, $0x0f0e0d0c0b0a0908
+DATA shifts<>+0x88(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x90(SB)/8, $0x0e0d0c0b0a090807
+DATA shifts<>+0x98(SB)/8, $0xffffffffffffff0f
+DATA shifts<>+0xa0(SB)/8, $0x0d0c0b0a09080706
+DATA shifts<>+0xa8(SB)/8, $0xffffffffffff0f0e
+DATA shifts<>+0xb0(SB)/8, $0x0c0b0a0908070605
+DATA shifts<>+0xb8(SB)/8, $0xffffffffff0f0e0d
+DATA shifts<>+0xc0(SB)/8, $0x0b0a090807060504
+DATA shifts<>+0xc8(SB)/8, $0xffffffff0f0e0d0c
+DATA shifts<>+0xd0(SB)/8, $0x0a09080706050403
+DATA shifts<>+0xd8(SB)/8, $0xffffff0f0e0d0c0b
+DATA shifts<>+0xe0(SB)/8, $0x0908070605040302
+DATA shifts<>+0xe8(SB)/8, $0xffff0f0e0d0c0b0a
+DATA shifts<>+0xf0(SB)/8, $0x0807060504030201
+DATA shifts<>+0xf8(SB)/8, $0xff0f0e0d0c0b0a09
+GLOBL shifts<>(SB),RODATA,$256
+
+TEXT runtime·return0(SB), NOSPLIT, $0
+ MOVL $0, AX
+ RET
+
+
+// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
+// Must obey the gcc calling convention.
+TEXT _cgo_topofstack(SB),NOSPLIT,$0
+ get_tls(CX)
+ MOVQ g(CX), AX
+ MOVQ g_m(AX), AX
+ MOVQ m_curg(AX), AX
+ MOVQ (g_stack+stack_hi)(AX), AX
+ RET
+
+// The top-most function running on a goroutine
+// returns to goexit+PCQuantum.
+TEXT runtime·goexit(SB),NOSPLIT|TOPFRAME|NOFRAME,$0-0
+ BYTE $0x90 // NOP
+ CALL runtime·goexit1(SB) // does not return
+ // traceback from goexit1 must hit code range of goexit
+ BYTE $0x90 // NOP
+
+// This is called from .init_array and follows the platform, not Go, ABI.
+TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
+ PUSHQ R15 // The access to global variables below implicitly uses R15, which is callee-save
+ MOVQ runtime·lastmoduledatap(SB), AX
+ MOVQ DI, moduledata_next(AX)
+ MOVQ DI, runtime·lastmoduledatap(SB)
+ POPQ R15
+ RET
+
+// Initialize special registers then jump to sigpanic.
+// This function is injected from the signal handler for panicking
+// signals. It is quite painful to set X15 in the signal context,
+// so we do it here.
+TEXT ·sigpanic0(SB),NOSPLIT,$0-0
+ get_tls(R14)
+ MOVQ g(R14), R14
+#ifndef GOOS_plan9
+ XORPS X15, X15
+#endif
+ JMP ·sigpanic<ABIInternal>(SB)
+
+// gcWriteBarrier informs the GC about heap pointer writes.
+//
+// gcWriteBarrier returns space in a write barrier buffer which
+// should be filled in by the caller.
+// gcWriteBarrier does NOT follow the Go ABI. It accepts the
+// number of bytes of buffer needed in R11, and returns a pointer
+// to the buffer space in R11.
+// It clobbers FLAGS. It does not clobber any general-purpose registers,
+// but may clobber others (e.g., SSE registers).
+// Typical use would be, when doing *(CX+88) = AX
+// CMPL $0, runtime.writeBarrier(SB)
+// JEQ dowrite
+// CALL runtime.gcBatchBarrier2(SB)
+// MOVQ AX, (R11)
+// MOVQ 88(CX), DX
+// MOVQ DX, 8(R11)
+// dowrite:
+// MOVQ AX, 88(CX)
+TEXT gcWriteBarrier<>(SB),NOSPLIT,$112
+ // Save the registers clobbered by the fast path. This is slightly
+ // faster than having the caller spill these.
+ MOVQ R12, 96(SP)
+ MOVQ R13, 104(SP)
+retry:
+ // TODO: Consider passing g.m.p in as an argument so they can be shared
+ // across a sequence of write barriers.
+ MOVQ g_m(R14), R13
+ MOVQ m_p(R13), R13
+ // Get current buffer write position.
+ MOVQ (p_wbBuf+wbBuf_next)(R13), R12 // original next position
+ ADDQ R11, R12 // new next position
+ // Is the buffer full?
+ CMPQ R12, (p_wbBuf+wbBuf_end)(R13)
+ JA flush
+ // Commit to the larger buffer.
+ MOVQ R12, (p_wbBuf+wbBuf_next)(R13)
+ // Make return value (the original next position)
+ SUBQ R11, R12
+ MOVQ R12, R11
+ // Restore registers.
+ MOVQ 96(SP), R12
+ MOVQ 104(SP), R13
+ RET
+
+flush:
+ // Save all general purpose registers since these could be
+ // clobbered by wbBufFlush and were not saved by the caller.
+ // It is possible for wbBufFlush to clobber other registers
+ // (e.g., SSE registers), but the compiler takes care of saving
+ // those in the caller if necessary. This strikes a balance
+ // with registers that are likely to be used.
+ //
+ // We don't have type information for these, but all code under
+ // here is NOSPLIT, so nothing will observe these.
+ //
+ // TODO: We could strike a different balance; e.g., saving X0
+ // and not saving GP registers that are less likely to be used.
+ MOVQ DI, 0(SP)
+ MOVQ AX, 8(SP)
+ MOVQ BX, 16(SP)
+ MOVQ CX, 24(SP)
+ MOVQ DX, 32(SP)
+ // DI already saved
+ MOVQ SI, 40(SP)
+ MOVQ BP, 48(SP)
+ MOVQ R8, 56(SP)
+ MOVQ R9, 64(SP)
+ MOVQ R10, 72(SP)
+ MOVQ R11, 80(SP)
+ // R12 already saved
+ // R13 already saved
+ // R14 is g
+ MOVQ R15, 88(SP)
+
+ CALL runtime·wbBufFlush(SB)
+
+ MOVQ 0(SP), DI
+ MOVQ 8(SP), AX
+ MOVQ 16(SP), BX
+ MOVQ 24(SP), CX
+ MOVQ 32(SP), DX
+ MOVQ 40(SP), SI
+ MOVQ 48(SP), BP
+ MOVQ 56(SP), R8
+ MOVQ 64(SP), R9
+ MOVQ 72(SP), R10
+ MOVQ 80(SP), R11
+ MOVQ 88(SP), R15
+ JMP retry
+
+TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+ MOVL $8, R11
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+ MOVL $16, R11
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+ MOVL $24, R11
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+ MOVL $32, R11
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+ MOVL $40, R11
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+ MOVL $48, R11
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+ MOVL $56, R11
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+ MOVL $64, R11
+ JMP gcWriteBarrier<>(SB)
+
+DATA debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
+GLOBL debugCallFrameTooLarge<>(SB), RODATA, $20 // Size duplicated below
+
+// debugCallV2 is the entry point for debugger-injected function
+// calls on running goroutines. It informs the runtime that a
+// debug call has been injected and creates a call frame for the
+// debugger to fill in.
+//
+// To inject a function call, a debugger should:
+// 1. Check that the goroutine is in state _Grunning and that
+// there are at least 256 bytes free on the stack.
+// 2. Push the current PC on the stack (updating SP).
+// 3. Write the desired argument frame size at SP-16 (using the SP
+// after step 2).
+// 4. Save all machine registers (including flags and XMM registers)
+// so they can be restored later by the debugger.
+// 5. Set the PC to debugCallV2 and resume execution.
+//
+// If the goroutine is in state _Grunnable, then it's not generally
+// safe to inject a call because it may return out via other runtime
+// operations. Instead, the debugger should unwind the stack to find
+// the return to non-runtime code, add a temporary breakpoint there,
+// and inject the call once that breakpoint is hit.
+//
+// If the goroutine is in any other state, it's not safe to inject a call.
+//
+// This function communicates back to the debugger by setting R12 and
+// invoking INT3 to raise a breakpoint signal. See the comments in the
+// implementation for the protocol the debugger is expected to
+// follow. InjectDebugCall in the runtime tests demonstrates this protocol.
+//
+// The debugger must ensure that any pointers passed to the function
+// obey escape analysis requirements. Specifically, it must not pass
+// a stack pointer to an escaping argument. debugCallV2 cannot check
+// this invariant.
+//
+// This is ABIInternal because Go code injects its PC directly into new
+// goroutine stacks.
+TEXT runtime·debugCallV2<ABIInternal>(SB),NOSPLIT,$152-0
+ // Save all registers that may contain pointers so they can be
+ // conservatively scanned.
+ //
+ // We can't do anything that might clobber any of these
+ // registers before this.
+ MOVQ R15, r15-(14*8+8)(SP)
+ MOVQ R14, r14-(13*8+8)(SP)
+ MOVQ R13, r13-(12*8+8)(SP)
+ MOVQ R12, r12-(11*8+8)(SP)
+ MOVQ R11, r11-(10*8+8)(SP)
+ MOVQ R10, r10-(9*8+8)(SP)
+ MOVQ R9, r9-(8*8+8)(SP)
+ MOVQ R8, r8-(7*8+8)(SP)
+ MOVQ DI, di-(6*8+8)(SP)
+ MOVQ SI, si-(5*8+8)(SP)
+ MOVQ BP, bp-(4*8+8)(SP)
+ MOVQ BX, bx-(3*8+8)(SP)
+ MOVQ DX, dx-(2*8+8)(SP)
+ // Save the frame size before we clobber it. Either of the last
+ // saves could clobber this depending on whether there's a saved BP.
+ MOVQ frameSize-24(FP), DX // aka -16(RSP) before prologue
+ MOVQ CX, cx-(1*8+8)(SP)
+ MOVQ AX, ax-(0*8+8)(SP)
+
+ // Save the argument frame size.
+ MOVQ DX, frameSize-128(SP)
+
+ // Perform a safe-point check.
+ MOVQ retpc-8(FP), AX // Caller's PC
+ MOVQ AX, 0(SP)
+ CALL runtime·debugCallCheck(SB)
+ MOVQ 8(SP), AX
+ TESTQ AX, AX
+ JZ good
+ // The safety check failed. Put the reason string at the top
+ // of the stack.
+ MOVQ AX, 0(SP)
+ MOVQ 16(SP), AX
+ MOVQ AX, 8(SP)
+ // Set R12 to 8 and invoke INT3. The debugger should get the
+ // reason a call can't be injected from the top of the stack
+ // and resume execution.
+ MOVQ $8, R12
+ BYTE $0xcc
+ JMP restore
+
+good:
+ // Registers are saved and it's safe to make a call.
+ // Open up a call frame, moving the stack if necessary.
+ //
+ // Once the frame is allocated, this will set R12 to 0 and
+ // invoke INT3. The debugger should write the argument
+ // frame for the call at SP, set up argument registers, push
+ // the trapping PC on the stack, set the PC to the function to
+ // call, set RDX to point to the closure (if a closure call),
+ // and resume execution.
+ //
+ // If the function returns, this will set R12 to 1 and invoke
+ // INT3. The debugger can then inspect any return value saved
+ // on the stack at SP and in registers and resume execution again.
+ //
+ // If the function panics, this will set R12 to 2 and invoke INT3.
+ // The interface{} value of the panic will be at SP. The debugger
+ // can inspect the panic value and resume execution again.
+#define DEBUG_CALL_DISPATCH(NAME,MAXSIZE) \
+ CMPQ AX, $MAXSIZE; \
+ JA 5(PC); \
+ MOVQ $NAME(SB), AX; \
+ MOVQ AX, 0(SP); \
+ CALL runtime·debugCallWrap(SB); \
+ JMP restore
+
+ MOVQ frameSize-128(SP), AX
+ DEBUG_CALL_DISPATCH(debugCall32<>, 32)
+ DEBUG_CALL_DISPATCH(debugCall64<>, 64)
+ DEBUG_CALL_DISPATCH(debugCall128<>, 128)
+ DEBUG_CALL_DISPATCH(debugCall256<>, 256)
+ DEBUG_CALL_DISPATCH(debugCall512<>, 512)
+ DEBUG_CALL_DISPATCH(debugCall1024<>, 1024)
+ DEBUG_CALL_DISPATCH(debugCall2048<>, 2048)
+ DEBUG_CALL_DISPATCH(debugCall4096<>, 4096)
+ DEBUG_CALL_DISPATCH(debugCall8192<>, 8192)
+ DEBUG_CALL_DISPATCH(debugCall16384<>, 16384)
+ DEBUG_CALL_DISPATCH(debugCall32768<>, 32768)
+ DEBUG_CALL_DISPATCH(debugCall65536<>, 65536)
+ // The frame size is too large. Report the error.
+ MOVQ $debugCallFrameTooLarge<>(SB), AX
+ MOVQ AX, 0(SP)
+ MOVQ $20, 8(SP) // length of debugCallFrameTooLarge string
+ MOVQ $8, R12
+ BYTE $0xcc
+ JMP restore
+
+restore:
+ // Calls and failures resume here.
+ //
+ // Set R12 to 16 and invoke INT3. The debugger should restore
+ // all registers except RIP and RSP and resume execution.
+ MOVQ $16, R12
+ BYTE $0xcc
+ // We must not modify flags after this point.
+
+ // Restore pointer-containing registers, which may have been
+ // modified from the debugger's copy by stack copying.
+ MOVQ ax-(0*8+8)(SP), AX
+ MOVQ cx-(1*8+8)(SP), CX
+ MOVQ dx-(2*8+8)(SP), DX
+ MOVQ bx-(3*8+8)(SP), BX
+ MOVQ bp-(4*8+8)(SP), BP
+ MOVQ si-(5*8+8)(SP), SI
+ MOVQ di-(6*8+8)(SP), DI
+ MOVQ r8-(7*8+8)(SP), R8
+ MOVQ r9-(8*8+8)(SP), R9
+ MOVQ r10-(9*8+8)(SP), R10
+ MOVQ r11-(10*8+8)(SP), R11
+ MOVQ r12-(11*8+8)(SP), R12
+ MOVQ r13-(12*8+8)(SP), R13
+ MOVQ r14-(13*8+8)(SP), R14
+ MOVQ r15-(14*8+8)(SP), R15
+
+ RET
+
+// runtime.debugCallCheck assumes that functions defined with the
+// DEBUG_CALL_FN macro are safe points to inject calls.
+#define DEBUG_CALL_FN(NAME,MAXSIZE) \
+TEXT NAME(SB),WRAPPER,$MAXSIZE-0; \
+ NO_LOCAL_POINTERS; \
+ MOVQ $0, R12; \
+ BYTE $0xcc; \
+ MOVQ $1, R12; \
+ BYTE $0xcc; \
+ RET
+DEBUG_CALL_FN(debugCall32<>, 32)
+DEBUG_CALL_FN(debugCall64<>, 64)
+DEBUG_CALL_FN(debugCall128<>, 128)
+DEBUG_CALL_FN(debugCall256<>, 256)
+DEBUG_CALL_FN(debugCall512<>, 512)
+DEBUG_CALL_FN(debugCall1024<>, 1024)
+DEBUG_CALL_FN(debugCall2048<>, 2048)
+DEBUG_CALL_FN(debugCall4096<>, 4096)
+DEBUG_CALL_FN(debugCall8192<>, 8192)
+DEBUG_CALL_FN(debugCall16384<>, 16384)
+DEBUG_CALL_FN(debugCall32768<>, 32768)
+DEBUG_CALL_FN(debugCall65536<>, 65536)
+
+// func debugCallPanicked(val interface{})
+TEXT runtime·debugCallPanicked(SB),NOSPLIT,$16-16
+ // Copy the panic value to the top of stack.
+ MOVQ val_type+0(FP), AX
+ MOVQ AX, 0(SP)
+ MOVQ val_data+8(FP), AX
+ MOVQ AX, 8(SP)
+ MOVQ $2, R12
+ BYTE $0xcc
+ RET
+
+// Note: these functions use a special calling convention to save generated code space.
+// Arguments are passed in registers, but the space for those arguments are allocated
+// in the caller's stack frame. These stubs write the args into that stack space and
+// then tail call to the corresponding runtime handler.
+// The tail call makes these stubs disappear in backtraces.
+// Defined as ABIInternal since they do not use the stack-based Go ABI.
+TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ CX, BX
+ JMP runtime·goPanicIndex<ABIInternal>(SB)
+TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ CX, BX
+ JMP runtime·goPanicIndexU<ABIInternal>(SB)
+TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ CX, AX
+ MOVQ DX, BX
+ JMP runtime·goPanicSliceAlen<ABIInternal>(SB)
+TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ CX, AX
+ MOVQ DX, BX
+ JMP runtime·goPanicSliceAlenU<ABIInternal>(SB)
+TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ CX, AX
+ MOVQ DX, BX
+ JMP runtime·goPanicSliceAcap<ABIInternal>(SB)
+TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ CX, AX
+ MOVQ DX, BX
+ JMP runtime·goPanicSliceAcapU<ABIInternal>(SB)
+TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ CX, BX
+ JMP runtime·goPanicSliceB<ABIInternal>(SB)
+TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ CX, BX
+ JMP runtime·goPanicSliceBU<ABIInternal>(SB)
+TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ DX, AX
+ JMP runtime·goPanicSlice3Alen<ABIInternal>(SB)
+TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ DX, AX
+ JMP runtime·goPanicSlice3AlenU<ABIInternal>(SB)
+TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ DX, AX
+ JMP runtime·goPanicSlice3Acap<ABIInternal>(SB)
+TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ DX, AX
+ JMP runtime·goPanicSlice3AcapU<ABIInternal>(SB)
+TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ CX, AX
+ MOVQ DX, BX
+ JMP runtime·goPanicSlice3B<ABIInternal>(SB)
+TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ CX, AX
+ MOVQ DX, BX
+ JMP runtime·goPanicSlice3BU<ABIInternal>(SB)
+TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ CX, BX
+ JMP runtime·goPanicSlice3C<ABIInternal>(SB)
+TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ CX, BX
+ JMP runtime·goPanicSlice3CU<ABIInternal>(SB)
+TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVQ DX, AX
+ JMP runtime·goPanicSliceConvert<ABIInternal>(SB)
+
+#ifdef GOOS_android
+// Use the free TLS_SLOT_APP slot #2 on Android Q.
+// Earlier androids are set up in gcc_android.c.
+DATA runtime·tls_g+0(SB)/8, $16
+GLOBL runtime·tls_g+0(SB), NOPTR, $8
+#endif
+#ifdef GOOS_windows
+GLOBL runtime·tls_g+0(SB), NOPTR, $8
+#endif
+
+// The compiler and assembler's -spectre=ret mode rewrites
+// all indirect CALL AX / JMP AX instructions to be
+// CALL retpolineAX / JMP retpolineAX.
+// See https://support.google.com/faqs/answer/7625886.
+#define RETPOLINE(reg) \
+ /* CALL setup */ BYTE $0xE8; BYTE $(2+2); BYTE $0; BYTE $0; BYTE $0; \
+ /* nospec: */ \
+ /* PAUSE */ BYTE $0xF3; BYTE $0x90; \
+ /* JMP nospec */ BYTE $0xEB; BYTE $-(2+2); \
+ /* setup: */ \
+ /* MOVQ AX, 0(SP) */ BYTE $0x48|((reg&8)>>1); BYTE $0x89; \
+ BYTE $0x04|((reg&7)<<3); BYTE $0x24; \
+ /* RET */ BYTE $0xC3
+
+TEXT runtime·retpolineAX(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(0)
+TEXT runtime·retpolineCX(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(1)
+TEXT runtime·retpolineDX(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(2)
+TEXT runtime·retpolineBX(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(3)
+/* SP is 4, can't happen / magic encodings */
+TEXT runtime·retpolineBP(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(5)
+TEXT runtime·retpolineSI(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(6)
+TEXT runtime·retpolineDI(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(7)
+TEXT runtime·retpolineR8(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(8)
+TEXT runtime·retpolineR9(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(9)
+TEXT runtime·retpolineR10(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(10)
+TEXT runtime·retpolineR11(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(11)
+TEXT runtime·retpolineR12(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(12)
+TEXT runtime·retpolineR13(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(13)
+TEXT runtime·retpolineR14(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(14)
+TEXT runtime·retpolineR15(SB),NOSPLIT|NOFRAME,$0; RETPOLINE(15)
+
+TEXT ·getfp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+ MOVQ BP, AX
+ RET
diff --git a/contrib/go/_std_1.21/src/runtime/asm_arm64.s b/contrib/go/_std_1.21/src/runtime/asm_arm64.s
new file mode 100644
index 0000000000..7866e35e4f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/asm_arm64.s
@@ -0,0 +1,1573 @@
+// Copyright 2015 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.
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "tls_arm64.h"
+#include "funcdata.h"
+#include "textflag.h"
+
+TEXT runtime·rt0_go(SB),NOSPLIT|TOPFRAME,$0
+ // SP = stack; R0 = argc; R1 = argv
+
+ SUB $32, RSP
+ MOVW R0, 8(RSP) // argc
+ MOVD R1, 16(RSP) // argv
+
+#ifdef TLS_darwin
+ // Initialize TLS.
+ MOVD ZR, g // clear g, make sure it's not junk.
+ SUB $32, RSP
+ MRS_TPIDR_R0
+ AND $~7, R0
+ MOVD R0, 16(RSP) // arg2: TLS base
+ MOVD $runtime·tls_g(SB), R2
+ MOVD R2, 8(RSP) // arg1: &tlsg
+ BL ·tlsinit(SB)
+ ADD $32, RSP
+#endif
+
+ // create istack out of the given (operating system) stack.
+ // _cgo_init may update stackguard.
+ MOVD $runtime·g0(SB), g
+ MOVD RSP, R7
+ MOVD $(-64*1024)(R7), R0
+ MOVD R0, g_stackguard0(g)
+ MOVD R0, g_stackguard1(g)
+ MOVD R0, (g_stack+stack_lo)(g)
+ MOVD R7, (g_stack+stack_hi)(g)
+
+ // if there is a _cgo_init, call it using the gcc ABI.
+ MOVD _cgo_init(SB), R12
+ CBZ R12, nocgo
+
+#ifdef GOOS_android
+ MRS_TPIDR_R0 // load TLS base pointer
+ MOVD R0, R3 // arg 3: TLS base pointer
+ MOVD $runtime·tls_g(SB), R2 // arg 2: &tls_g
+#else
+ MOVD $0, R2 // arg 2: not used when using platform's TLS
+#endif
+ MOVD $setg_gcc<>(SB), R1 // arg 1: setg
+ MOVD g, R0 // arg 0: G
+ SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
+ BL (R12)
+ ADD $16, RSP
+
+nocgo:
+ BL runtime·save_g(SB)
+ // update stackguard after _cgo_init
+ MOVD (g_stack+stack_lo)(g), R0
+ ADD $const_stackGuard, R0
+ MOVD R0, g_stackguard0(g)
+ MOVD R0, g_stackguard1(g)
+
+ // set the per-goroutine and per-mach "registers"
+ MOVD $runtime·m0(SB), R0
+
+ // save m->g0 = g0
+ MOVD g, m_g0(R0)
+ // save m0 to g0->m
+ MOVD R0, g_m(g)
+
+ BL runtime·check(SB)
+
+#ifdef GOOS_windows
+ BL runtime·wintls(SB)
+#endif
+
+ MOVW 8(RSP), R0 // copy argc
+ MOVW R0, -8(RSP)
+ MOVD 16(RSP), R0 // copy argv
+ MOVD R0, 0(RSP)
+ BL runtime·args(SB)
+ BL runtime·osinit(SB)
+ BL runtime·schedinit(SB)
+
+ // create a new goroutine to start program
+ MOVD $runtime·mainPC(SB), R0 // entry
+ SUB $16, RSP
+ MOVD R0, 8(RSP) // arg
+ MOVD $0, 0(RSP) // dummy LR
+ BL runtime·newproc(SB)
+ ADD $16, RSP
+
+ // start this M
+ BL runtime·mstart(SB)
+
+ // Prevent dead-code elimination of debugCallV2, which is
+ // intended to be called by debuggers.
+ MOVD $runtime·debugCallV2<ABIInternal>(SB), R0
+
+ MOVD $0, R0
+ MOVD R0, (R0) // boom
+ UNDEF
+
+DATA runtime·mainPC+0(SB)/8,$runtime·main<ABIInternal>(SB)
+GLOBL runtime·mainPC(SB),RODATA,$8
+
+// Windows ARM64 needs an immediate 0xf000 argument.
+// See go.dev/issues/53837.
+#define BREAK \
+#ifdef GOOS_windows \
+ BRK $0xf000 \
+#else \
+ BRK \
+#endif \
+
+
+TEXT runtime·breakpoint(SB),NOSPLIT|NOFRAME,$0-0
+ BREAK
+ RET
+
+TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
+ RET
+
+TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0
+ BL runtime·mstart0(SB)
+ RET // not reached
+
+/*
+ * go-routine
+ */
+
+// void gogo(Gobuf*)
+// restore state from Gobuf; longjmp
+TEXT runtime·gogo(SB), NOSPLIT|NOFRAME, $0-8
+ MOVD buf+0(FP), R5
+ MOVD gobuf_g(R5), R6
+ MOVD 0(R6), R4 // make sure g != nil
+ B gogo<>(SB)
+
+TEXT gogo<>(SB), NOSPLIT|NOFRAME, $0
+ MOVD R6, g
+ BL runtime·save_g(SB)
+
+ MOVD gobuf_sp(R5), R0
+ MOVD R0, RSP
+ MOVD gobuf_bp(R5), R29
+ MOVD gobuf_lr(R5), LR
+ MOVD gobuf_ret(R5), R0
+ MOVD gobuf_ctxt(R5), R26
+ MOVD $0, gobuf_sp(R5)
+ MOVD $0, gobuf_bp(R5)
+ MOVD $0, gobuf_ret(R5)
+ MOVD $0, gobuf_lr(R5)
+ MOVD $0, gobuf_ctxt(R5)
+ CMP ZR, ZR // set condition codes for == test, needed by stack split
+ MOVD gobuf_pc(R5), R6
+ B (R6)
+
+// void mcall(fn func(*g))
+// Switch to m->g0's stack, call fn(g).
+// Fn must never return. It should gogo(&g->sched)
+// to keep running g.
+TEXT runtime·mcall<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-8
+ MOVD R0, R26 // context
+
+ // Save caller state in g->sched
+ MOVD RSP, R0
+ MOVD R0, (g_sched+gobuf_sp)(g)
+ MOVD R29, (g_sched+gobuf_bp)(g)
+ MOVD LR, (g_sched+gobuf_pc)(g)
+ MOVD $0, (g_sched+gobuf_lr)(g)
+
+ // Switch to m->g0 & its stack, call fn.
+ MOVD g, R3
+ MOVD g_m(g), R8
+ MOVD m_g0(R8), g
+ BL runtime·save_g(SB)
+ CMP g, R3
+ BNE 2(PC)
+ B runtime·badmcall(SB)
+
+ MOVD (g_sched+gobuf_sp)(g), R0
+ MOVD R0, RSP // sp = m->g0->sched.sp
+ MOVD (g_sched+gobuf_bp)(g), R29
+ MOVD R3, R0 // arg = g
+ MOVD $0, -16(RSP) // dummy LR
+ SUB $16, RSP
+ MOVD 0(R26), R4 // code pointer
+ BL (R4)
+ B runtime·badmcall2(SB)
+
+// systemstack_switch is a dummy routine that systemstack leaves at the bottom
+// of the G stack. We need to distinguish the routine that
+// lives at the bottom of the G stack from the one that lives
+// at the top of the system stack because the one at the top of
+// the system stack terminates the stack walk (see topofstack()).
+TEXT runtime·systemstack_switch(SB), NOSPLIT, $0-0
+ UNDEF
+ BL (LR) // make sure this function is not leaf
+ RET
+
+// func systemstack(fn func())
+TEXT runtime·systemstack(SB), NOSPLIT, $0-8
+ MOVD fn+0(FP), R3 // R3 = fn
+ MOVD R3, R26 // context
+ MOVD g_m(g), R4 // R4 = m
+
+ MOVD m_gsignal(R4), R5 // R5 = gsignal
+ CMP g, R5
+ BEQ noswitch
+
+ MOVD m_g0(R4), R5 // R5 = g0
+ CMP g, R5
+ BEQ noswitch
+
+ MOVD m_curg(R4), R6
+ CMP g, R6
+ BEQ switch
+
+ // Bad: g is not gsignal, not g0, not curg. What is it?
+ // Hide call from linker nosplit analysis.
+ MOVD $runtime·badsystemstack(SB), R3
+ BL (R3)
+ B runtime·abort(SB)
+
+switch:
+ // save our state in g->sched. Pretend to
+ // be systemstack_switch if the G stack is scanned.
+ BL gosave_systemstack_switch<>(SB)
+
+ // switch to g0
+ MOVD R5, g
+ BL runtime·save_g(SB)
+ MOVD (g_sched+gobuf_sp)(g), R3
+ MOVD R3, RSP
+ MOVD (g_sched+gobuf_bp)(g), R29
+
+ // call target function
+ MOVD 0(R26), R3 // code pointer
+ BL (R3)
+
+ // switch back to g
+ MOVD g_m(g), R3
+ MOVD m_curg(R3), g
+ BL runtime·save_g(SB)
+ MOVD (g_sched+gobuf_sp)(g), R0
+ MOVD R0, RSP
+ MOVD (g_sched+gobuf_bp)(g), R29
+ MOVD $0, (g_sched+gobuf_sp)(g)
+ MOVD $0, (g_sched+gobuf_bp)(g)
+ RET
+
+noswitch:
+ // already on m stack, just call directly
+ // Using a tail call here cleans up tracebacks since we won't stop
+ // at an intermediate systemstack.
+ MOVD 0(R26), R3 // code pointer
+ MOVD.P 16(RSP), R30 // restore LR
+ SUB $8, RSP, R29 // restore FP
+ B (R3)
+
+/*
+ * support for morestack
+ */
+
+// Called during function prolog when more stack is needed.
+// Caller has already loaded:
+// R3 prolog's LR (R30)
+//
+// The traceback routines see morestack on a g0 as being
+// the top of a stack (for example, morestack calling newstack
+// calling the scheduler calling newm calling gc), so we must
+// record an argument size. For that purpose, it has no arguments.
+TEXT runtime·morestack(SB),NOSPLIT|NOFRAME,$0-0
+ // Cannot grow scheduler stack (m->g0).
+ MOVD g_m(g), R8
+ MOVD m_g0(R8), R4
+ CMP g, R4
+ BNE 3(PC)
+ BL runtime·badmorestackg0(SB)
+ B runtime·abort(SB)
+
+ // Cannot grow signal stack (m->gsignal).
+ MOVD m_gsignal(R8), R4
+ CMP g, R4
+ BNE 3(PC)
+ BL runtime·badmorestackgsignal(SB)
+ B runtime·abort(SB)
+
+ // Called from f.
+ // Set g->sched to context in f
+ MOVD RSP, R0
+ MOVD R0, (g_sched+gobuf_sp)(g)
+ MOVD R29, (g_sched+gobuf_bp)(g)
+ MOVD LR, (g_sched+gobuf_pc)(g)
+ MOVD R3, (g_sched+gobuf_lr)(g)
+ MOVD R26, (g_sched+gobuf_ctxt)(g)
+
+ // Called from f.
+ // Set m->morebuf to f's callers.
+ MOVD R3, (m_morebuf+gobuf_pc)(R8) // f's caller's PC
+ MOVD RSP, R0
+ MOVD R0, (m_morebuf+gobuf_sp)(R8) // f's caller's RSP
+ MOVD g, (m_morebuf+gobuf_g)(R8)
+
+ // Call newstack on m->g0's stack.
+ MOVD m_g0(R8), g
+ BL runtime·save_g(SB)
+ MOVD (g_sched+gobuf_sp)(g), R0
+ MOVD R0, RSP
+ MOVD (g_sched+gobuf_bp)(g), R29
+ MOVD.W $0, -16(RSP) // create a call frame on g0 (saved LR; keep 16-aligned)
+ BL runtime·newstack(SB)
+
+ // Not reached, but make sure the return PC from the call to newstack
+ // is still in this function, and not the beginning of the next.
+ UNDEF
+
+TEXT runtime·morestack_noctxt(SB),NOSPLIT|NOFRAME,$0-0
+ // Force SPWRITE. This function doesn't actually write SP,
+ // but it is called with a special calling convention where
+ // the caller doesn't save LR on stack but passes it as a
+ // register (R3), and the unwinder currently doesn't understand.
+ // Make it SPWRITE to stop unwinding. (See issue 54332)
+ MOVD RSP, RSP
+
+ MOVW $0, R26
+ B runtime·morestack(SB)
+
+// spillArgs stores return values from registers to a *internal/abi.RegArgs in R20.
+TEXT ·spillArgs(SB),NOSPLIT,$0-0
+ STP (R0, R1), (0*8)(R20)
+ STP (R2, R3), (2*8)(R20)
+ STP (R4, R5), (4*8)(R20)
+ STP (R6, R7), (6*8)(R20)
+ STP (R8, R9), (8*8)(R20)
+ STP (R10, R11), (10*8)(R20)
+ STP (R12, R13), (12*8)(R20)
+ STP (R14, R15), (14*8)(R20)
+ FSTPD (F0, F1), (16*8)(R20)
+ FSTPD (F2, F3), (18*8)(R20)
+ FSTPD (F4, F5), (20*8)(R20)
+ FSTPD (F6, F7), (22*8)(R20)
+ FSTPD (F8, F9), (24*8)(R20)
+ FSTPD (F10, F11), (26*8)(R20)
+ FSTPD (F12, F13), (28*8)(R20)
+ FSTPD (F14, F15), (30*8)(R20)
+ RET
+
+// unspillArgs loads args into registers from a *internal/abi.RegArgs in R20.
+TEXT ·unspillArgs(SB),NOSPLIT,$0-0
+ LDP (0*8)(R20), (R0, R1)
+ LDP (2*8)(R20), (R2, R3)
+ LDP (4*8)(R20), (R4, R5)
+ LDP (6*8)(R20), (R6, R7)
+ LDP (8*8)(R20), (R8, R9)
+ LDP (10*8)(R20), (R10, R11)
+ LDP (12*8)(R20), (R12, R13)
+ LDP (14*8)(R20), (R14, R15)
+ FLDPD (16*8)(R20), (F0, F1)
+ FLDPD (18*8)(R20), (F2, F3)
+ FLDPD (20*8)(R20), (F4, F5)
+ FLDPD (22*8)(R20), (F6, F7)
+ FLDPD (24*8)(R20), (F8, F9)
+ FLDPD (26*8)(R20), (F10, F11)
+ FLDPD (28*8)(R20), (F12, F13)
+ FLDPD (30*8)(R20), (F14, F15)
+ RET
+
+// reflectcall: call a function with the given argument list
+// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
+// we don't have variable-sized frames, so we use a small number
+// of constant-sized-frame functions to encode a few bits of size in the pc.
+// Caution: ugly multiline assembly macros in your future!
+
+#define DISPATCH(NAME,MAXSIZE) \
+ MOVD $MAXSIZE, R27; \
+ CMP R27, R16; \
+ BGT 3(PC); \
+ MOVD $NAME(SB), R27; \
+ B (R27)
+// Note: can't just "B NAME(SB)" - bad inlining results.
+
+TEXT ·reflectcall(SB), NOSPLIT|NOFRAME, $0-48
+ MOVWU frameSize+32(FP), R16
+ DISPATCH(runtime·call16, 16)
+ DISPATCH(runtime·call32, 32)
+ DISPATCH(runtime·call64, 64)
+ DISPATCH(runtime·call128, 128)
+ DISPATCH(runtime·call256, 256)
+ DISPATCH(runtime·call512, 512)
+ DISPATCH(runtime·call1024, 1024)
+ DISPATCH(runtime·call2048, 2048)
+ DISPATCH(runtime·call4096, 4096)
+ DISPATCH(runtime·call8192, 8192)
+ DISPATCH(runtime·call16384, 16384)
+ DISPATCH(runtime·call32768, 32768)
+ DISPATCH(runtime·call65536, 65536)
+ DISPATCH(runtime·call131072, 131072)
+ DISPATCH(runtime·call262144, 262144)
+ DISPATCH(runtime·call524288, 524288)
+ DISPATCH(runtime·call1048576, 1048576)
+ DISPATCH(runtime·call2097152, 2097152)
+ DISPATCH(runtime·call4194304, 4194304)
+ DISPATCH(runtime·call8388608, 8388608)
+ DISPATCH(runtime·call16777216, 16777216)
+ DISPATCH(runtime·call33554432, 33554432)
+ DISPATCH(runtime·call67108864, 67108864)
+ DISPATCH(runtime·call134217728, 134217728)
+ DISPATCH(runtime·call268435456, 268435456)
+ DISPATCH(runtime·call536870912, 536870912)
+ DISPATCH(runtime·call1073741824, 1073741824)
+ MOVD $runtime·badreflectcall(SB), R0
+ B (R0)
+
+#define CALLFN(NAME,MAXSIZE) \
+TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \
+ NO_LOCAL_POINTERS; \
+ /* copy arguments to stack */ \
+ MOVD stackArgs+16(FP), R3; \
+ MOVWU stackArgsSize+24(FP), R4; \
+ ADD $8, RSP, R5; \
+ BIC $0xf, R4, R6; \
+ CBZ R6, 6(PC); \
+ /* if R6=(argsize&~15) != 0 */ \
+ ADD R6, R5, R6; \
+ /* copy 16 bytes a time */ \
+ LDP.P 16(R3), (R7, R8); \
+ STP.P (R7, R8), 16(R5); \
+ CMP R5, R6; \
+ BNE -3(PC); \
+ AND $0xf, R4, R6; \
+ CBZ R6, 6(PC); \
+ /* if R6=(argsize&15) != 0 */ \
+ ADD R6, R5, R6; \
+ /* copy 1 byte a time for the rest */ \
+ MOVBU.P 1(R3), R7; \
+ MOVBU.P R7, 1(R5); \
+ CMP R5, R6; \
+ BNE -3(PC); \
+ /* set up argument registers */ \
+ MOVD regArgs+40(FP), R20; \
+ CALL ·unspillArgs(SB); \
+ /* call function */ \
+ MOVD f+8(FP), R26; \
+ MOVD (R26), R20; \
+ PCDATA $PCDATA_StackMapIndex, $0; \
+ BL (R20); \
+ /* copy return values back */ \
+ MOVD regArgs+40(FP), R20; \
+ CALL ·spillArgs(SB); \
+ MOVD stackArgsType+0(FP), R7; \
+ MOVD stackArgs+16(FP), R3; \
+ MOVWU stackArgsSize+24(FP), R4; \
+ MOVWU stackRetOffset+28(FP), R6; \
+ ADD $8, RSP, R5; \
+ ADD R6, R5; \
+ ADD R6, R3; \
+ SUB R6, R4; \
+ BL callRet<>(SB); \
+ RET
+
+// callRet copies return values back at the end of call*. This is a
+// separate function so it can allocate stack space for the arguments
+// to reflectcallmove. It does not follow the Go ABI; it expects its
+// arguments in registers.
+TEXT callRet<>(SB), NOSPLIT, $48-0
+ NO_LOCAL_POINTERS
+ STP (R7, R3), 8(RSP)
+ STP (R5, R4), 24(RSP)
+ MOVD R20, 40(RSP)
+ BL runtime·reflectcallmove(SB)
+ RET
+
+CALLFN(·call16, 16)
+CALLFN(·call32, 32)
+CALLFN(·call64, 64)
+CALLFN(·call128, 128)
+CALLFN(·call256, 256)
+CALLFN(·call512, 512)
+CALLFN(·call1024, 1024)
+CALLFN(·call2048, 2048)
+CALLFN(·call4096, 4096)
+CALLFN(·call8192, 8192)
+CALLFN(·call16384, 16384)
+CALLFN(·call32768, 32768)
+CALLFN(·call65536, 65536)
+CALLFN(·call131072, 131072)
+CALLFN(·call262144, 262144)
+CALLFN(·call524288, 524288)
+CALLFN(·call1048576, 1048576)
+CALLFN(·call2097152, 2097152)
+CALLFN(·call4194304, 4194304)
+CALLFN(·call8388608, 8388608)
+CALLFN(·call16777216, 16777216)
+CALLFN(·call33554432, 33554432)
+CALLFN(·call67108864, 67108864)
+CALLFN(·call134217728, 134217728)
+CALLFN(·call268435456, 268435456)
+CALLFN(·call536870912, 536870912)
+CALLFN(·call1073741824, 1073741824)
+
+// func memhash32(p unsafe.Pointer, h uintptr) uintptr
+TEXT runtime·memhash32<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
+ MOVB runtime·useAeshash(SB), R10
+ CBZ R10, noaes
+ MOVD $runtime·aeskeysched+0(SB), R3
+
+ VEOR V0.B16, V0.B16, V0.B16
+ VLD1 (R3), [V2.B16]
+ VLD1 (R0), V0.S[1]
+ VMOV R1, V0.S[0]
+
+ AESE V2.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V2.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V2.B16, V0.B16
+
+ VMOV V0.D[0], R0
+ RET
+noaes:
+ B runtime·memhash32Fallback<ABIInternal>(SB)
+
+// func memhash64(p unsafe.Pointer, h uintptr) uintptr
+TEXT runtime·memhash64<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
+ MOVB runtime·useAeshash(SB), R10
+ CBZ R10, noaes
+ MOVD $runtime·aeskeysched+0(SB), R3
+
+ VEOR V0.B16, V0.B16, V0.B16
+ VLD1 (R3), [V2.B16]
+ VLD1 (R0), V0.D[1]
+ VMOV R1, V0.D[0]
+
+ AESE V2.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V2.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V2.B16, V0.B16
+
+ VMOV V0.D[0], R0
+ RET
+noaes:
+ B runtime·memhash64Fallback<ABIInternal>(SB)
+
+// func memhash(p unsafe.Pointer, h, size uintptr) uintptr
+TEXT runtime·memhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-32
+ MOVB runtime·useAeshash(SB), R10
+ CBZ R10, noaes
+ B aeshashbody<>(SB)
+noaes:
+ B runtime·memhashFallback<ABIInternal>(SB)
+
+// func strhash(p unsafe.Pointer, h uintptr) uintptr
+TEXT runtime·strhash<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-24
+ MOVB runtime·useAeshash(SB), R10
+ CBZ R10, noaes
+ LDP (R0), (R0, R2) // string data / length
+ B aeshashbody<>(SB)
+noaes:
+ B runtime·strhashFallback<ABIInternal>(SB)
+
+// R0: data
+// R1: seed data
+// R2: length
+// At return, R0 = return value
+TEXT aeshashbody<>(SB),NOSPLIT|NOFRAME,$0
+ VEOR V30.B16, V30.B16, V30.B16
+ VMOV R1, V30.D[0]
+ VMOV R2, V30.D[1] // load length into seed
+
+ MOVD $runtime·aeskeysched+0(SB), R4
+ VLD1.P 16(R4), [V0.B16]
+ AESE V30.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ CMP $16, R2
+ BLO aes0to15
+ BEQ aes16
+ CMP $32, R2
+ BLS aes17to32
+ CMP $64, R2
+ BLS aes33to64
+ CMP $128, R2
+ BLS aes65to128
+ B aes129plus
+
+aes0to15:
+ CBZ R2, aes0
+ VEOR V2.B16, V2.B16, V2.B16
+ TBZ $3, R2, less_than_8
+ VLD1.P 8(R0), V2.D[0]
+
+less_than_8:
+ TBZ $2, R2, less_than_4
+ VLD1.P 4(R0), V2.S[2]
+
+less_than_4:
+ TBZ $1, R2, less_than_2
+ VLD1.P 2(R0), V2.H[6]
+
+less_than_2:
+ TBZ $0, R2, done
+ VLD1 (R0), V2.B[14]
+done:
+ AESE V0.B16, V2.B16
+ AESMC V2.B16, V2.B16
+ AESE V0.B16, V2.B16
+ AESMC V2.B16, V2.B16
+ AESE V0.B16, V2.B16
+ AESMC V2.B16, V2.B16
+
+ VMOV V2.D[0], R0
+ RET
+
+aes0:
+ VMOV V0.D[0], R0
+ RET
+
+aes16:
+ VLD1 (R0), [V2.B16]
+ B done
+
+aes17to32:
+ // make second seed
+ VLD1 (R4), [V1.B16]
+ AESE V30.B16, V1.B16
+ AESMC V1.B16, V1.B16
+ SUB $16, R2, R10
+ VLD1.P (R0)(R10), [V2.B16]
+ VLD1 (R0), [V3.B16]
+
+ AESE V0.B16, V2.B16
+ AESMC V2.B16, V2.B16
+ AESE V1.B16, V3.B16
+ AESMC V3.B16, V3.B16
+
+ AESE V0.B16, V2.B16
+ AESMC V2.B16, V2.B16
+ AESE V1.B16, V3.B16
+ AESMC V3.B16, V3.B16
+
+ AESE V0.B16, V2.B16
+ AESE V1.B16, V3.B16
+
+ VEOR V3.B16, V2.B16, V2.B16
+
+ VMOV V2.D[0], R0
+ RET
+
+aes33to64:
+ VLD1 (R4), [V1.B16, V2.B16, V3.B16]
+ AESE V30.B16, V1.B16
+ AESMC V1.B16, V1.B16
+ AESE V30.B16, V2.B16
+ AESMC V2.B16, V2.B16
+ AESE V30.B16, V3.B16
+ AESMC V3.B16, V3.B16
+ SUB $32, R2, R10
+
+ VLD1.P (R0)(R10), [V4.B16, V5.B16]
+ VLD1 (R0), [V6.B16, V7.B16]
+
+ AESE V0.B16, V4.B16
+ AESMC V4.B16, V4.B16
+ AESE V1.B16, V5.B16
+ AESMC V5.B16, V5.B16
+ AESE V2.B16, V6.B16
+ AESMC V6.B16, V6.B16
+ AESE V3.B16, V7.B16
+ AESMC V7.B16, V7.B16
+
+ AESE V0.B16, V4.B16
+ AESMC V4.B16, V4.B16
+ AESE V1.B16, V5.B16
+ AESMC V5.B16, V5.B16
+ AESE V2.B16, V6.B16
+ AESMC V6.B16, V6.B16
+ AESE V3.B16, V7.B16
+ AESMC V7.B16, V7.B16
+
+ AESE V0.B16, V4.B16
+ AESE V1.B16, V5.B16
+ AESE V2.B16, V6.B16
+ AESE V3.B16, V7.B16
+
+ VEOR V6.B16, V4.B16, V4.B16
+ VEOR V7.B16, V5.B16, V5.B16
+ VEOR V5.B16, V4.B16, V4.B16
+
+ VMOV V4.D[0], R0
+ RET
+
+aes65to128:
+ VLD1.P 64(R4), [V1.B16, V2.B16, V3.B16, V4.B16]
+ VLD1 (R4), [V5.B16, V6.B16, V7.B16]
+ AESE V30.B16, V1.B16
+ AESMC V1.B16, V1.B16
+ AESE V30.B16, V2.B16
+ AESMC V2.B16, V2.B16
+ AESE V30.B16, V3.B16
+ AESMC V3.B16, V3.B16
+ AESE V30.B16, V4.B16
+ AESMC V4.B16, V4.B16
+ AESE V30.B16, V5.B16
+ AESMC V5.B16, V5.B16
+ AESE V30.B16, V6.B16
+ AESMC V6.B16, V6.B16
+ AESE V30.B16, V7.B16
+ AESMC V7.B16, V7.B16
+
+ SUB $64, R2, R10
+ VLD1.P (R0)(R10), [V8.B16, V9.B16, V10.B16, V11.B16]
+ VLD1 (R0), [V12.B16, V13.B16, V14.B16, V15.B16]
+ AESE V0.B16, V8.B16
+ AESMC V8.B16, V8.B16
+ AESE V1.B16, V9.B16
+ AESMC V9.B16, V9.B16
+ AESE V2.B16, V10.B16
+ AESMC V10.B16, V10.B16
+ AESE V3.B16, V11.B16
+ AESMC V11.B16, V11.B16
+ AESE V4.B16, V12.B16
+ AESMC V12.B16, V12.B16
+ AESE V5.B16, V13.B16
+ AESMC V13.B16, V13.B16
+ AESE V6.B16, V14.B16
+ AESMC V14.B16, V14.B16
+ AESE V7.B16, V15.B16
+ AESMC V15.B16, V15.B16
+
+ AESE V0.B16, V8.B16
+ AESMC V8.B16, V8.B16
+ AESE V1.B16, V9.B16
+ AESMC V9.B16, V9.B16
+ AESE V2.B16, V10.B16
+ AESMC V10.B16, V10.B16
+ AESE V3.B16, V11.B16
+ AESMC V11.B16, V11.B16
+ AESE V4.B16, V12.B16
+ AESMC V12.B16, V12.B16
+ AESE V5.B16, V13.B16
+ AESMC V13.B16, V13.B16
+ AESE V6.B16, V14.B16
+ AESMC V14.B16, V14.B16
+ AESE V7.B16, V15.B16
+ AESMC V15.B16, V15.B16
+
+ AESE V0.B16, V8.B16
+ AESE V1.B16, V9.B16
+ AESE V2.B16, V10.B16
+ AESE V3.B16, V11.B16
+ AESE V4.B16, V12.B16
+ AESE V5.B16, V13.B16
+ AESE V6.B16, V14.B16
+ AESE V7.B16, V15.B16
+
+ VEOR V12.B16, V8.B16, V8.B16
+ VEOR V13.B16, V9.B16, V9.B16
+ VEOR V14.B16, V10.B16, V10.B16
+ VEOR V15.B16, V11.B16, V11.B16
+ VEOR V10.B16, V8.B16, V8.B16
+ VEOR V11.B16, V9.B16, V9.B16
+ VEOR V9.B16, V8.B16, V8.B16
+
+ VMOV V8.D[0], R0
+ RET
+
+aes129plus:
+ PRFM (R0), PLDL1KEEP
+ VLD1.P 64(R4), [V1.B16, V2.B16, V3.B16, V4.B16]
+ VLD1 (R4), [V5.B16, V6.B16, V7.B16]
+ AESE V30.B16, V1.B16
+ AESMC V1.B16, V1.B16
+ AESE V30.B16, V2.B16
+ AESMC V2.B16, V2.B16
+ AESE V30.B16, V3.B16
+ AESMC V3.B16, V3.B16
+ AESE V30.B16, V4.B16
+ AESMC V4.B16, V4.B16
+ AESE V30.B16, V5.B16
+ AESMC V5.B16, V5.B16
+ AESE V30.B16, V6.B16
+ AESMC V6.B16, V6.B16
+ AESE V30.B16, V7.B16
+ AESMC V7.B16, V7.B16
+ ADD R0, R2, R10
+ SUB $128, R10, R10
+ VLD1.P 64(R10), [V8.B16, V9.B16, V10.B16, V11.B16]
+ VLD1 (R10), [V12.B16, V13.B16, V14.B16, V15.B16]
+ SUB $1, R2, R2
+ LSR $7, R2, R2
+
+aesloop:
+ AESE V8.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V9.B16, V1.B16
+ AESMC V1.B16, V1.B16
+ AESE V10.B16, V2.B16
+ AESMC V2.B16, V2.B16
+ AESE V11.B16, V3.B16
+ AESMC V3.B16, V3.B16
+ AESE V12.B16, V4.B16
+ AESMC V4.B16, V4.B16
+ AESE V13.B16, V5.B16
+ AESMC V5.B16, V5.B16
+ AESE V14.B16, V6.B16
+ AESMC V6.B16, V6.B16
+ AESE V15.B16, V7.B16
+ AESMC V7.B16, V7.B16
+
+ VLD1.P 64(R0), [V8.B16, V9.B16, V10.B16, V11.B16]
+ AESE V8.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V9.B16, V1.B16
+ AESMC V1.B16, V1.B16
+ AESE V10.B16, V2.B16
+ AESMC V2.B16, V2.B16
+ AESE V11.B16, V3.B16
+ AESMC V3.B16, V3.B16
+
+ VLD1.P 64(R0), [V12.B16, V13.B16, V14.B16, V15.B16]
+ AESE V12.B16, V4.B16
+ AESMC V4.B16, V4.B16
+ AESE V13.B16, V5.B16
+ AESMC V5.B16, V5.B16
+ AESE V14.B16, V6.B16
+ AESMC V6.B16, V6.B16
+ AESE V15.B16, V7.B16
+ AESMC V7.B16, V7.B16
+ SUB $1, R2, R2
+ CBNZ R2, aesloop
+
+ AESE V8.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V9.B16, V1.B16
+ AESMC V1.B16, V1.B16
+ AESE V10.B16, V2.B16
+ AESMC V2.B16, V2.B16
+ AESE V11.B16, V3.B16
+ AESMC V3.B16, V3.B16
+ AESE V12.B16, V4.B16
+ AESMC V4.B16, V4.B16
+ AESE V13.B16, V5.B16
+ AESMC V5.B16, V5.B16
+ AESE V14.B16, V6.B16
+ AESMC V6.B16, V6.B16
+ AESE V15.B16, V7.B16
+ AESMC V7.B16, V7.B16
+
+ AESE V8.B16, V0.B16
+ AESMC V0.B16, V0.B16
+ AESE V9.B16, V1.B16
+ AESMC V1.B16, V1.B16
+ AESE V10.B16, V2.B16
+ AESMC V2.B16, V2.B16
+ AESE V11.B16, V3.B16
+ AESMC V3.B16, V3.B16
+ AESE V12.B16, V4.B16
+ AESMC V4.B16, V4.B16
+ AESE V13.B16, V5.B16
+ AESMC V5.B16, V5.B16
+ AESE V14.B16, V6.B16
+ AESMC V6.B16, V6.B16
+ AESE V15.B16, V7.B16
+ AESMC V7.B16, V7.B16
+
+ AESE V8.B16, V0.B16
+ AESE V9.B16, V1.B16
+ AESE V10.B16, V2.B16
+ AESE V11.B16, V3.B16
+ AESE V12.B16, V4.B16
+ AESE V13.B16, V5.B16
+ AESE V14.B16, V6.B16
+ AESE V15.B16, V7.B16
+
+ VEOR V0.B16, V1.B16, V0.B16
+ VEOR V2.B16, V3.B16, V2.B16
+ VEOR V4.B16, V5.B16, V4.B16
+ VEOR V6.B16, V7.B16, V6.B16
+ VEOR V0.B16, V2.B16, V0.B16
+ VEOR V4.B16, V6.B16, V4.B16
+ VEOR V4.B16, V0.B16, V0.B16
+
+ VMOV V0.D[0], R0
+ RET
+
+TEXT runtime·procyield(SB),NOSPLIT,$0-0
+ MOVWU cycles+0(FP), R0
+again:
+ YIELD
+ SUBW $1, R0
+ CBNZ R0, again
+ RET
+
+// Save state of caller into g->sched,
+// but using fake PC from systemstack_switch.
+// Must only be called from functions with no locals ($0)
+// or else unwinding from systemstack_switch is incorrect.
+// Smashes R0.
+TEXT gosave_systemstack_switch<>(SB),NOSPLIT|NOFRAME,$0
+ MOVD $runtime·systemstack_switch(SB), R0
+ ADD $8, R0 // get past prologue
+ MOVD R0, (g_sched+gobuf_pc)(g)
+ MOVD RSP, R0
+ MOVD R0, (g_sched+gobuf_sp)(g)
+ MOVD R29, (g_sched+gobuf_bp)(g)
+ MOVD $0, (g_sched+gobuf_lr)(g)
+ MOVD $0, (g_sched+gobuf_ret)(g)
+ // Assert ctxt is zero. See func save.
+ MOVD (g_sched+gobuf_ctxt)(g), R0
+ CBZ R0, 2(PC)
+ CALL runtime·abort(SB)
+ RET
+
+// func asmcgocall_no_g(fn, arg unsafe.Pointer)
+// Call fn(arg) aligned appropriately for the gcc ABI.
+// Called on a system stack, and there may be no g yet (during needm).
+TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-16
+ MOVD fn+0(FP), R1
+ MOVD arg+8(FP), R0
+ SUB $16, RSP // skip over saved frame pointer below RSP
+ BL (R1)
+ ADD $16, RSP // skip over saved frame pointer below RSP
+ RET
+
+// func asmcgocall(fn, arg unsafe.Pointer) int32
+// Call fn(arg) on the scheduler stack,
+// aligned appropriately for the gcc ABI.
+// See cgocall.go for more details.
+TEXT ·asmcgocall(SB),NOSPLIT,$0-20
+ MOVD fn+0(FP), R1
+ MOVD arg+8(FP), R0
+
+ MOVD RSP, R2 // save original stack pointer
+ CBZ g, nosave
+ MOVD g, R4
+
+ // Figure out if we need to switch to m->g0 stack.
+ // We get called to create new OS threads too, and those
+ // come in on the m->g0 stack already. Or we might already
+ // be on the m->gsignal stack.
+ MOVD g_m(g), R8
+ MOVD m_gsignal(R8), R3
+ CMP R3, g
+ BEQ nosave
+ MOVD m_g0(R8), R3
+ CMP R3, g
+ BEQ nosave
+
+ // Switch to system stack.
+ MOVD R0, R9 // gosave_systemstack_switch<> and save_g might clobber R0
+ BL gosave_systemstack_switch<>(SB)
+ MOVD R3, g
+ BL runtime·save_g(SB)
+ MOVD (g_sched+gobuf_sp)(g), R0
+ MOVD R0, RSP
+ MOVD (g_sched+gobuf_bp)(g), R29
+ MOVD R9, R0
+
+ // Now on a scheduling stack (a pthread-created stack).
+ // Save room for two of our pointers /*, plus 32 bytes of callee
+ // save area that lives on the caller stack. */
+ MOVD RSP, R13
+ SUB $16, R13
+ MOVD R13, RSP
+ MOVD R4, 0(RSP) // save old g on stack
+ MOVD (g_stack+stack_hi)(R4), R4
+ SUB R2, R4
+ MOVD R4, 8(RSP) // save depth in old g stack (can't just save SP, as stack might be copied during a callback)
+ BL (R1)
+ MOVD R0, R9
+
+ // Restore g, stack pointer. R0 is errno, so don't touch it
+ MOVD 0(RSP), g
+ BL runtime·save_g(SB)
+ MOVD (g_stack+stack_hi)(g), R5
+ MOVD 8(RSP), R6
+ SUB R6, R5
+ MOVD R9, R0
+ MOVD R5, RSP
+
+ MOVW R0, ret+16(FP)
+ RET
+
+nosave:
+ // Running on a system stack, perhaps even without a g.
+ // Having no g can happen during thread creation or thread teardown
+ // (see needm/dropm on Solaris, for example).
+ // This code is like the above sequence but without saving/restoring g
+ // and without worrying about the stack moving out from under us
+ // (because we're on a system stack, not a goroutine stack).
+ // The above code could be used directly if already on a system stack,
+ // but then the only path through this code would be a rare case on Solaris.
+ // Using this code for all "already on system stack" calls exercises it more,
+ // which should help keep it correct.
+ MOVD RSP, R13
+ SUB $16, R13
+ MOVD R13, RSP
+ MOVD $0, R4
+ MOVD R4, 0(RSP) // Where above code stores g, in case someone looks during debugging.
+ MOVD R2, 8(RSP) // Save original stack pointer.
+ BL (R1)
+ // Restore stack pointer.
+ MOVD 8(RSP), R2
+ MOVD R2, RSP
+ MOVD R0, ret+16(FP)
+ RET
+
+// cgocallback(fn, frame unsafe.Pointer, ctxt uintptr)
+// See cgocall.go for more details.
+TEXT ·cgocallback(SB),NOSPLIT,$24-24
+ NO_LOCAL_POINTERS
+
+ // Skip cgocallbackg, just dropm when fn is nil, and frame is the saved g.
+ // It is used to dropm while thread is exiting.
+ MOVD fn+0(FP), R1
+ CBNZ R1, loadg
+ // Restore the g from frame.
+ MOVD frame+8(FP), g
+ B dropm
+
+loadg:
+ // Load g from thread-local storage.
+ BL runtime·load_g(SB)
+
+ // If g is nil, Go did not create the current thread,
+ // or if this thread never called into Go on pthread platforms.
+ // Call needm to obtain one for temporary use.
+ // In this case, we're running on the thread stack, so there's
+ // lots of space, but the linker doesn't know. Hide the call from
+ // the linker analysis by using an indirect call.
+ CBZ g, needm
+
+ MOVD g_m(g), R8
+ MOVD R8, savedm-8(SP)
+ B havem
+
+needm:
+ MOVD g, savedm-8(SP) // g is zero, so is m.
+ MOVD $runtime·needAndBindM(SB), R0
+ BL (R0)
+
+ // Set m->g0->sched.sp = SP, so that if a panic happens
+ // during the function we are about to execute, it will
+ // have a valid SP to run on the g0 stack.
+ // The next few lines (after the havem label)
+ // will save this SP onto the stack and then write
+ // the same SP back to m->sched.sp. That seems redundant,
+ // but if an unrecovered panic happens, unwindm will
+ // restore the g->sched.sp from the stack location
+ // and then systemstack will try to use it. If we don't set it here,
+ // that restored SP will be uninitialized (typically 0) and
+ // will not be usable.
+ MOVD g_m(g), R8
+ MOVD m_g0(R8), R3
+ MOVD RSP, R0
+ MOVD R0, (g_sched+gobuf_sp)(R3)
+ MOVD R29, (g_sched+gobuf_bp)(R3)
+
+havem:
+ // Now there's a valid m, and we're running on its m->g0.
+ // Save current m->g0->sched.sp on stack and then set it to SP.
+ // Save current sp in m->g0->sched.sp in preparation for
+ // switch back to m->curg stack.
+ // NOTE: unwindm knows that the saved g->sched.sp is at 16(RSP) aka savedsp-16(SP).
+ // Beware that the frame size is actually 32+16.
+ MOVD m_g0(R8), R3
+ MOVD (g_sched+gobuf_sp)(R3), R4
+ MOVD R4, savedsp-16(SP)
+ MOVD RSP, R0
+ MOVD R0, (g_sched+gobuf_sp)(R3)
+
+ // Switch to m->curg stack and call runtime.cgocallbackg.
+ // Because we are taking over the execution of m->curg
+ // but *not* resuming what had been running, we need to
+ // save that information (m->curg->sched) so we can restore it.
+ // We can restore m->curg->sched.sp easily, because calling
+ // runtime.cgocallbackg leaves SP unchanged upon return.
+ // To save m->curg->sched.pc, we push it onto the curg stack and
+ // open a frame the same size as cgocallback's g0 frame.
+ // Once we switch to the curg stack, the pushed PC will appear
+ // to be the return PC of cgocallback, so that the traceback
+ // will seamlessly trace back into the earlier calls.
+ MOVD m_curg(R8), g
+ BL runtime·save_g(SB)
+ MOVD (g_sched+gobuf_sp)(g), R4 // prepare stack as R4
+ MOVD (g_sched+gobuf_pc)(g), R5
+ MOVD R5, -48(R4)
+ MOVD (g_sched+gobuf_bp)(g), R5
+ MOVD R5, -56(R4)
+ // Gather our arguments into registers.
+ MOVD fn+0(FP), R1
+ MOVD frame+8(FP), R2
+ MOVD ctxt+16(FP), R3
+ MOVD $-48(R4), R0 // maintain 16-byte SP alignment
+ MOVD R0, RSP // switch stack
+ MOVD R1, 8(RSP)
+ MOVD R2, 16(RSP)
+ MOVD R3, 24(RSP)
+ MOVD $runtime·cgocallbackg(SB), R0
+ CALL (R0) // indirect call to bypass nosplit check. We're on a different stack now.
+
+ // Restore g->sched (== m->curg->sched) from saved values.
+ MOVD 0(RSP), R5
+ MOVD R5, (g_sched+gobuf_pc)(g)
+ MOVD RSP, R4
+ ADD $48, R4, R4
+ MOVD R4, (g_sched+gobuf_sp)(g)
+
+ // Switch back to m->g0's stack and restore m->g0->sched.sp.
+ // (Unlike m->curg, the g0 goroutine never uses sched.pc,
+ // so we do not have to restore it.)
+ MOVD g_m(g), R8
+ MOVD m_g0(R8), g
+ BL runtime·save_g(SB)
+ MOVD (g_sched+gobuf_sp)(g), R0
+ MOVD R0, RSP
+ MOVD savedsp-16(SP), R4
+ MOVD R4, (g_sched+gobuf_sp)(g)
+
+ // If the m on entry was nil, we called needm above to borrow an m,
+ // 1. for the duration of the call on non-pthread platforms,
+ // 2. or the duration of the C thread alive on pthread platforms.
+ // If the m on entry wasn't nil,
+ // 1. the thread might be a Go thread,
+ // 2. or it wasn't the first call from a C thread on pthread platforms,
+ // since then we skip dropm to reuse the m in the first call.
+ MOVD savedm-8(SP), R6
+ CBNZ R6, droppedm
+
+ // Skip dropm to reuse it in the next call, when a pthread key has been created.
+ MOVD _cgo_pthread_key_created(SB), R6
+ // It means cgo is disabled when _cgo_pthread_key_created is a nil pointer, need dropm.
+ CBZ R6, dropm
+ MOVD (R6), R6
+ CBNZ R6, droppedm
+
+dropm:
+ MOVD $runtime·dropm(SB), R0
+ BL (R0)
+droppedm:
+
+ // Done!
+ RET
+
+// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
+// Must obey the gcc calling convention.
+TEXT _cgo_topofstack(SB),NOSPLIT,$24
+ // g (R28) and REGTMP (R27) might be clobbered by load_g. They
+ // are callee-save in the gcc calling convention, so save them.
+ MOVD R27, savedR27-8(SP)
+ MOVD g, saveG-16(SP)
+
+ BL runtime·load_g(SB)
+ MOVD g_m(g), R0
+ MOVD m_curg(R0), R0
+ MOVD (g_stack+stack_hi)(R0), R0
+
+ MOVD saveG-16(SP), g
+ MOVD savedR28-8(SP), R27
+ RET
+
+// void setg(G*); set g. for use by needm.
+TEXT runtime·setg(SB), NOSPLIT, $0-8
+ MOVD gg+0(FP), g
+ // This only happens if iscgo, so jump straight to save_g
+ BL runtime·save_g(SB)
+ RET
+
+// void setg_gcc(G*); set g called from gcc
+TEXT setg_gcc<>(SB),NOSPLIT,$8
+ MOVD R0, g
+ MOVD R27, savedR27-8(SP)
+ BL runtime·save_g(SB)
+ MOVD savedR27-8(SP), R27
+ RET
+
+TEXT runtime·emptyfunc(SB),0,$0-0
+ RET
+
+TEXT runtime·abort(SB),NOSPLIT|NOFRAME,$0-0
+ MOVD ZR, R0
+ MOVD (R0), R0
+ UNDEF
+
+TEXT runtime·return0(SB), NOSPLIT, $0
+ MOVW $0, R0
+ RET
+
+// The top-most function running on a goroutine
+// returns to goexit+PCQuantum.
+TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
+ MOVD R0, R0 // NOP
+ BL runtime·goexit1(SB) // does not return
+
+// This is called from .init_array and follows the platform, not Go, ABI.
+TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
+ SUB $0x10, RSP
+ MOVD R27, 8(RSP) // The access to global variables below implicitly uses R27, which is callee-save
+ MOVD runtime·lastmoduledatap(SB), R1
+ MOVD R0, moduledata_next(R1)
+ MOVD R0, runtime·lastmoduledatap(SB)
+ MOVD 8(RSP), R27
+ ADD $0x10, RSP
+ RET
+
+TEXT ·checkASM(SB),NOSPLIT,$0-1
+ MOVW $1, R3
+ MOVB R3, ret+0(FP)
+ RET
+
+// gcWriteBarrier informs the GC about heap pointer writes.
+//
+// gcWriteBarrier does NOT follow the Go ABI. It accepts the
+// number of bytes of buffer needed in R25, and returns a pointer
+// to the buffer space in R25.
+// It clobbers condition codes.
+// It does not clobber any general-purpose registers except R27,
+// but may clobber others (e.g., floating point registers)
+// The act of CALLing gcWriteBarrier will clobber R30 (LR).
+TEXT gcWriteBarrier<>(SB),NOSPLIT,$200
+ // Save the registers clobbered by the fast path.
+ STP (R0, R1), 184(RSP)
+retry:
+ MOVD g_m(g), R0
+ MOVD m_p(R0), R0
+ MOVD (p_wbBuf+wbBuf_next)(R0), R1
+ MOVD (p_wbBuf+wbBuf_end)(R0), R27
+ // Increment wbBuf.next position.
+ ADD R25, R1
+ // Is the buffer full?
+ CMP R27, R1
+ BHI flush
+ // Commit to the larger buffer.
+ MOVD R1, (p_wbBuf+wbBuf_next)(R0)
+ // Make return value (the original next position)
+ SUB R25, R1, R25
+ // Restore registers.
+ LDP 184(RSP), (R0, R1)
+ RET
+
+flush:
+ // Save all general purpose registers since these could be
+ // clobbered by wbBufFlush and were not saved by the caller.
+ // R0 and R1 already saved
+ STP (R2, R3), 1*8(RSP)
+ STP (R4, R5), 3*8(RSP)
+ STP (R6, R7), 5*8(RSP)
+ STP (R8, R9), 7*8(RSP)
+ STP (R10, R11), 9*8(RSP)
+ STP (R12, R13), 11*8(RSP)
+ STP (R14, R15), 13*8(RSP)
+ // R16, R17 may be clobbered by linker trampoline
+ // R18 is unused.
+ STP (R19, R20), 15*8(RSP)
+ STP (R21, R22), 17*8(RSP)
+ STP (R23, R24), 19*8(RSP)
+ STP (R25, R26), 21*8(RSP)
+ // R27 is temp register.
+ // R28 is g.
+ // R29 is frame pointer (unused).
+ // R30 is LR, which was saved by the prologue.
+ // R31 is SP.
+
+ CALL runtime·wbBufFlush(SB)
+ LDP 1*8(RSP), (R2, R3)
+ LDP 3*8(RSP), (R4, R5)
+ LDP 5*8(RSP), (R6, R7)
+ LDP 7*8(RSP), (R8, R9)
+ LDP 9*8(RSP), (R10, R11)
+ LDP 11*8(RSP), (R12, R13)
+ LDP 13*8(RSP), (R14, R15)
+ LDP 15*8(RSP), (R19, R20)
+ LDP 17*8(RSP), (R21, R22)
+ LDP 19*8(RSP), (R23, R24)
+ LDP 21*8(RSP), (R25, R26)
+ JMP retry
+
+TEXT runtime·gcWriteBarrier1<ABIInternal>(SB),NOSPLIT,$0
+ MOVD $8, R25
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier2<ABIInternal>(SB),NOSPLIT,$0
+ MOVD $16, R25
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier3<ABIInternal>(SB),NOSPLIT,$0
+ MOVD $24, R25
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier4<ABIInternal>(SB),NOSPLIT,$0
+ MOVD $32, R25
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier5<ABIInternal>(SB),NOSPLIT,$0
+ MOVD $40, R25
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier6<ABIInternal>(SB),NOSPLIT,$0
+ MOVD $48, R25
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier7<ABIInternal>(SB),NOSPLIT,$0
+ MOVD $56, R25
+ JMP gcWriteBarrier<>(SB)
+TEXT runtime·gcWriteBarrier8<ABIInternal>(SB),NOSPLIT,$0
+ MOVD $64, R25
+ JMP gcWriteBarrier<>(SB)
+
+DATA debugCallFrameTooLarge<>+0x00(SB)/20, $"call frame too large"
+GLOBL debugCallFrameTooLarge<>(SB), RODATA, $20 // Size duplicated below
+
+// debugCallV2 is the entry point for debugger-injected function
+// calls on running goroutines. It informs the runtime that a
+// debug call has been injected and creates a call frame for the
+// debugger to fill in.
+//
+// To inject a function call, a debugger should:
+// 1. Check that the goroutine is in state _Grunning and that
+// there are at least 288 bytes free on the stack.
+// 2. Set SP as SP-16.
+// 3. Store the current LR in (SP) (using the SP after step 2).
+// 4. Store the current PC in the LR register.
+// 5. Write the desired argument frame size at SP-16
+// 6. Save all machine registers (including flags and fpsimd registers)
+// so they can be restored later by the debugger.
+// 7. Set the PC to debugCallV2 and resume execution.
+//
+// If the goroutine is in state _Grunnable, then it's not generally
+// safe to inject a call because it may return out via other runtime
+// operations. Instead, the debugger should unwind the stack to find
+// the return to non-runtime code, add a temporary breakpoint there,
+// and inject the call once that breakpoint is hit.
+//
+// If the goroutine is in any other state, it's not safe to inject a call.
+//
+// This function communicates back to the debugger by setting R20 and
+// invoking BRK to raise a breakpoint signal. Note that the signal PC of
+// the signal triggered by the BRK instruction is the PC where the signal
+// is trapped, not the next PC, so to resume execution, the debugger needs
+// to set the signal PC to PC+4. See the comments in the implementation for
+// the protocol the debugger is expected to follow. InjectDebugCall in the
+// runtime tests demonstrates this protocol.
+//
+// The debugger must ensure that any pointers passed to the function
+// obey escape analysis requirements. Specifically, it must not pass
+// a stack pointer to an escaping argument. debugCallV2 cannot check
+// this invariant.
+//
+// This is ABIInternal because Go code injects its PC directly into new
+// goroutine stacks.
+TEXT runtime·debugCallV2<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-0
+ STP (R29, R30), -280(RSP)
+ SUB $272, RSP, RSP
+ SUB $8, RSP, R29
+ // Save all registers that may contain pointers so they can be
+ // conservatively scanned.
+ //
+ // We can't do anything that might clobber any of these
+ // registers before this.
+ STP (R27, g), (30*8)(RSP)
+ STP (R25, R26), (28*8)(RSP)
+ STP (R23, R24), (26*8)(RSP)
+ STP (R21, R22), (24*8)(RSP)
+ STP (R19, R20), (22*8)(RSP)
+ STP (R16, R17), (20*8)(RSP)
+ STP (R14, R15), (18*8)(RSP)
+ STP (R12, R13), (16*8)(RSP)
+ STP (R10, R11), (14*8)(RSP)
+ STP (R8, R9), (12*8)(RSP)
+ STP (R6, R7), (10*8)(RSP)
+ STP (R4, R5), (8*8)(RSP)
+ STP (R2, R3), (6*8)(RSP)
+ STP (R0, R1), (4*8)(RSP)
+
+ // Perform a safe-point check.
+ MOVD R30, 8(RSP) // Caller's PC
+ CALL runtime·debugCallCheck(SB)
+ MOVD 16(RSP), R0
+ CBZ R0, good
+
+ // The safety check failed. Put the reason string at the top
+ // of the stack.
+ MOVD R0, 8(RSP)
+ MOVD 24(RSP), R0
+ MOVD R0, 16(RSP)
+
+ // Set R20 to 8 and invoke BRK. The debugger should get the
+ // reason a call can't be injected from SP+8 and resume execution.
+ MOVD $8, R20
+ BREAK
+ JMP restore
+
+good:
+ // Registers are saved and it's safe to make a call.
+ // Open up a call frame, moving the stack if necessary.
+ //
+ // Once the frame is allocated, this will set R20 to 0 and
+ // invoke BRK. The debugger should write the argument
+ // frame for the call at SP+8, set up argument registers,
+ // set the LR as the signal PC + 4, set the PC to the function
+ // to call, set R26 to point to the closure (if a closure call),
+ // and resume execution.
+ //
+ // If the function returns, this will set R20 to 1 and invoke
+ // BRK. The debugger can then inspect any return value saved
+ // on the stack at SP+8 and in registers. To resume execution,
+ // the debugger should restore the LR from (SP).
+ //
+ // If the function panics, this will set R20 to 2 and invoke BRK.
+ // The interface{} value of the panic will be at SP+8. The debugger
+ // can inspect the panic value and resume execution again.
+#define DEBUG_CALL_DISPATCH(NAME,MAXSIZE) \
+ CMP $MAXSIZE, R0; \
+ BGT 5(PC); \
+ MOVD $NAME(SB), R0; \
+ MOVD R0, 8(RSP); \
+ CALL runtime·debugCallWrap(SB); \
+ JMP restore
+
+ MOVD 256(RSP), R0 // the argument frame size
+ DEBUG_CALL_DISPATCH(debugCall32<>, 32)
+ DEBUG_CALL_DISPATCH(debugCall64<>, 64)
+ DEBUG_CALL_DISPATCH(debugCall128<>, 128)
+ DEBUG_CALL_DISPATCH(debugCall256<>, 256)
+ DEBUG_CALL_DISPATCH(debugCall512<>, 512)
+ DEBUG_CALL_DISPATCH(debugCall1024<>, 1024)
+ DEBUG_CALL_DISPATCH(debugCall2048<>, 2048)
+ DEBUG_CALL_DISPATCH(debugCall4096<>, 4096)
+ DEBUG_CALL_DISPATCH(debugCall8192<>, 8192)
+ DEBUG_CALL_DISPATCH(debugCall16384<>, 16384)
+ DEBUG_CALL_DISPATCH(debugCall32768<>, 32768)
+ DEBUG_CALL_DISPATCH(debugCall65536<>, 65536)
+ // The frame size is too large. Report the error.
+ MOVD $debugCallFrameTooLarge<>(SB), R0
+ MOVD R0, 8(RSP)
+ MOVD $20, R0
+ MOVD R0, 16(RSP) // length of debugCallFrameTooLarge string
+ MOVD $8, R20
+ BREAK
+ JMP restore
+
+restore:
+ // Calls and failures resume here.
+ //
+ // Set R20 to 16 and invoke BRK. The debugger should restore
+ // all registers except for PC and RSP and resume execution.
+ MOVD $16, R20
+ BREAK
+ // We must not modify flags after this point.
+
+ // Restore pointer-containing registers, which may have been
+ // modified from the debugger's copy by stack copying.
+ LDP (30*8)(RSP), (R27, g)
+ LDP (28*8)(RSP), (R25, R26)
+ LDP (26*8)(RSP), (R23, R24)
+ LDP (24*8)(RSP), (R21, R22)
+ LDP (22*8)(RSP), (R19, R20)
+ LDP (20*8)(RSP), (R16, R17)
+ LDP (18*8)(RSP), (R14, R15)
+ LDP (16*8)(RSP), (R12, R13)
+ LDP (14*8)(RSP), (R10, R11)
+ LDP (12*8)(RSP), (R8, R9)
+ LDP (10*8)(RSP), (R6, R7)
+ LDP (8*8)(RSP), (R4, R5)
+ LDP (6*8)(RSP), (R2, R3)
+ LDP (4*8)(RSP), (R0, R1)
+
+ LDP -8(RSP), (R29, R27)
+ ADD $288, RSP, RSP // Add 16 more bytes, see saveSigContext
+ MOVD -16(RSP), R30 // restore old lr
+ JMP (R27)
+
+// runtime.debugCallCheck assumes that functions defined with the
+// DEBUG_CALL_FN macro are safe points to inject calls.
+#define DEBUG_CALL_FN(NAME,MAXSIZE) \
+TEXT NAME(SB),WRAPPER,$MAXSIZE-0; \
+ NO_LOCAL_POINTERS; \
+ MOVD $0, R20; \
+ BREAK; \
+ MOVD $1, R20; \
+ BREAK; \
+ RET
+DEBUG_CALL_FN(debugCall32<>, 32)
+DEBUG_CALL_FN(debugCall64<>, 64)
+DEBUG_CALL_FN(debugCall128<>, 128)
+DEBUG_CALL_FN(debugCall256<>, 256)
+DEBUG_CALL_FN(debugCall512<>, 512)
+DEBUG_CALL_FN(debugCall1024<>, 1024)
+DEBUG_CALL_FN(debugCall2048<>, 2048)
+DEBUG_CALL_FN(debugCall4096<>, 4096)
+DEBUG_CALL_FN(debugCall8192<>, 8192)
+DEBUG_CALL_FN(debugCall16384<>, 16384)
+DEBUG_CALL_FN(debugCall32768<>, 32768)
+DEBUG_CALL_FN(debugCall65536<>, 65536)
+
+// func debugCallPanicked(val interface{})
+TEXT runtime·debugCallPanicked(SB),NOSPLIT,$16-16
+ // Copy the panic value to the top of stack at SP+8.
+ MOVD val_type+0(FP), R0
+ MOVD R0, 8(RSP)
+ MOVD val_data+8(FP), R0
+ MOVD R0, 16(RSP)
+ MOVD $2, R20
+ BREAK
+ RET
+
+// Note: these functions use a special calling convention to save generated code space.
+// Arguments are passed in registers, but the space for those arguments are allocated
+// in the caller's stack frame. These stubs write the args into that stack space and
+// then tail call to the corresponding runtime handler.
+// The tail call makes these stubs disappear in backtraces.
+//
+// Defined as ABIInternal since the compiler generates ABIInternal
+// calls to it directly and it does not use the stack-based Go ABI.
+TEXT runtime·panicIndex<ABIInternal>(SB),NOSPLIT,$0-16
+ JMP runtime·goPanicIndex<ABIInternal>(SB)
+TEXT runtime·panicIndexU<ABIInternal>(SB),NOSPLIT,$0-16
+ JMP runtime·goPanicIndexU<ABIInternal>(SB)
+TEXT runtime·panicSliceAlen<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVD R1, R0
+ MOVD R2, R1
+ JMP runtime·goPanicSliceAlen<ABIInternal>(SB)
+TEXT runtime·panicSliceAlenU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVD R1, R0
+ MOVD R2, R1
+ JMP runtime·goPanicSliceAlenU<ABIInternal>(SB)
+TEXT runtime·panicSliceAcap<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVD R1, R0
+ MOVD R2, R1
+ JMP runtime·goPanicSliceAcap<ABIInternal>(SB)
+TEXT runtime·panicSliceAcapU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVD R1, R0
+ MOVD R2, R1
+ JMP runtime·goPanicSliceAcapU<ABIInternal>(SB)
+TEXT runtime·panicSliceB<ABIInternal>(SB),NOSPLIT,$0-16
+ JMP runtime·goPanicSliceB<ABIInternal>(SB)
+TEXT runtime·panicSliceBU<ABIInternal>(SB),NOSPLIT,$0-16
+ JMP runtime·goPanicSliceBU<ABIInternal>(SB)
+TEXT runtime·panicSlice3Alen<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVD R2, R0
+ MOVD R3, R1
+ JMP runtime·goPanicSlice3Alen<ABIInternal>(SB)
+TEXT runtime·panicSlice3AlenU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVD R2, R0
+ MOVD R3, R1
+ JMP runtime·goPanicSlice3AlenU<ABIInternal>(SB)
+TEXT runtime·panicSlice3Acap<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVD R2, R0
+ MOVD R3, R1
+ JMP runtime·goPanicSlice3Acap<ABIInternal>(SB)
+TEXT runtime·panicSlice3AcapU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVD R2, R0
+ MOVD R3, R1
+ JMP runtime·goPanicSlice3AcapU<ABIInternal>(SB)
+TEXT runtime·panicSlice3B<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVD R1, R0
+ MOVD R2, R1
+ JMP runtime·goPanicSlice3B<ABIInternal>(SB)
+TEXT runtime·panicSlice3BU<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVD R1, R0
+ MOVD R2, R1
+ JMP runtime·goPanicSlice3BU<ABIInternal>(SB)
+TEXT runtime·panicSlice3C<ABIInternal>(SB),NOSPLIT,$0-16
+ JMP runtime·goPanicSlice3C<ABIInternal>(SB)
+TEXT runtime·panicSlice3CU<ABIInternal>(SB),NOSPLIT,$0-16
+ JMP runtime·goPanicSlice3CU<ABIInternal>(SB)
+TEXT runtime·panicSliceConvert<ABIInternal>(SB),NOSPLIT,$0-16
+ MOVD R2, R0
+ MOVD R3, R1
+ JMP runtime·goPanicSliceConvert<ABIInternal>(SB)
+
+TEXT ·getfp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
+ MOVD R29, R0
+ RET
diff --git a/contrib/go/_std_1.20/src/runtime/atomic_arm64.s b/contrib/go/_std_1.21/src/runtime/atomic_arm64.s
index 21b4d8ccd5..21b4d8ccd5 100644
--- a/contrib/go/_std_1.20/src/runtime/atomic_arm64.s
+++ b/contrib/go/_std_1.21/src/runtime/atomic_arm64.s
diff --git a/contrib/go/_std_1.21/src/runtime/atomic_pointer.go b/contrib/go/_std_1.21/src/runtime/atomic_pointer.go
new file mode 100644
index 0000000000..b61bf0b8b2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/atomic_pointer.go
@@ -0,0 +1,114 @@
+// Copyright 2009 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 runtime
+
+import (
+ "internal/goexperiment"
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// These functions cannot have go:noescape annotations,
+// because while ptr does not escape, new does.
+// If new is marked as not escaping, the compiler will make incorrect
+// escape analysis decisions about the pointer value being stored.
+
+// atomicwb performs a write barrier before an atomic pointer write.
+// The caller should guard the call with "if writeBarrier.enabled".
+//
+//go:nosplit
+func atomicwb(ptr *unsafe.Pointer, new unsafe.Pointer) {
+ slot := (*uintptr)(unsafe.Pointer(ptr))
+ buf := getg().m.p.ptr().wbBuf.get2()
+ buf[0] = *slot
+ buf[1] = uintptr(new)
+}
+
+// atomicstorep performs *ptr = new atomically and invokes a write barrier.
+//
+//go:nosplit
+func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) {
+ if writeBarrier.enabled {
+ atomicwb((*unsafe.Pointer)(ptr), new)
+ }
+ if goexperiment.CgoCheck2 {
+ cgoCheckPtrWrite((*unsafe.Pointer)(ptr), new)
+ }
+ atomic.StorepNoWB(noescape(ptr), new)
+}
+
+// atomic_storePointer is the implementation of runtime/internal/UnsafePointer.Store
+// (like StoreNoWB but with the write barrier).
+//
+//go:nosplit
+//go:linkname atomic_storePointer runtime/internal/atomic.storePointer
+func atomic_storePointer(ptr *unsafe.Pointer, new unsafe.Pointer) {
+ atomicstorep(unsafe.Pointer(ptr), new)
+}
+
+// atomic_casPointer is the implementation of runtime/internal/UnsafePointer.CompareAndSwap
+// (like CompareAndSwapNoWB but with the write barrier).
+//
+//go:nosplit
+//go:linkname atomic_casPointer runtime/internal/atomic.casPointer
+func atomic_casPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
+ if writeBarrier.enabled {
+ atomicwb(ptr, new)
+ }
+ if goexperiment.CgoCheck2 {
+ cgoCheckPtrWrite(ptr, new)
+ }
+ return atomic.Casp1(ptr, old, new)
+}
+
+// Like above, but implement in terms of sync/atomic's uintptr operations.
+// We cannot just call the runtime routines, because the race detector expects
+// to be able to intercept the sync/atomic forms but not the runtime forms.
+
+//go:linkname sync_atomic_StoreUintptr sync/atomic.StoreUintptr
+func sync_atomic_StoreUintptr(ptr *uintptr, new uintptr)
+
+//go:linkname sync_atomic_StorePointer sync/atomic.StorePointer
+//go:nosplit
+func sync_atomic_StorePointer(ptr *unsafe.Pointer, new unsafe.Pointer) {
+ if writeBarrier.enabled {
+ atomicwb(ptr, new)
+ }
+ if goexperiment.CgoCheck2 {
+ cgoCheckPtrWrite(ptr, new)
+ }
+ sync_atomic_StoreUintptr((*uintptr)(unsafe.Pointer(ptr)), uintptr(new))
+}
+
+//go:linkname sync_atomic_SwapUintptr sync/atomic.SwapUintptr
+func sync_atomic_SwapUintptr(ptr *uintptr, new uintptr) uintptr
+
+//go:linkname sync_atomic_SwapPointer sync/atomic.SwapPointer
+//go:nosplit
+func sync_atomic_SwapPointer(ptr *unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer {
+ if writeBarrier.enabled {
+ atomicwb(ptr, new)
+ }
+ if goexperiment.CgoCheck2 {
+ cgoCheckPtrWrite(ptr, new)
+ }
+ old := unsafe.Pointer(sync_atomic_SwapUintptr((*uintptr)(noescape(unsafe.Pointer(ptr))), uintptr(new)))
+ return old
+}
+
+//go:linkname sync_atomic_CompareAndSwapUintptr sync/atomic.CompareAndSwapUintptr
+func sync_atomic_CompareAndSwapUintptr(ptr *uintptr, old, new uintptr) bool
+
+//go:linkname sync_atomic_CompareAndSwapPointer sync/atomic.CompareAndSwapPointer
+//go:nosplit
+func sync_atomic_CompareAndSwapPointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool {
+ if writeBarrier.enabled {
+ atomicwb(ptr, new)
+ }
+ if goexperiment.CgoCheck2 {
+ cgoCheckPtrWrite(ptr, new)
+ }
+ return sync_atomic_CompareAndSwapUintptr((*uintptr)(noescape(unsafe.Pointer(ptr))), uintptr(old), uintptr(new))
+}
diff --git a/contrib/go/_std_1.20/src/runtime/auxv_none.go b/contrib/go/_std_1.21/src/runtime/auxv_none.go
index 5d473cab5c..5d473cab5c 100644
--- a/contrib/go/_std_1.20/src/runtime/auxv_none.go
+++ b/contrib/go/_std_1.21/src/runtime/auxv_none.go
diff --git a/contrib/go/_std_1.21/src/runtime/cgo.go b/contrib/go/_std_1.21/src/runtime/cgo.go
new file mode 100644
index 0000000000..395303552c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo.go
@@ -0,0 +1,63 @@
+// Copyright 2014 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 runtime
+
+import "unsafe"
+
+//go:cgo_export_static main
+
+// Filled in by runtime/cgo when linked into binary.
+
+//go:linkname _cgo_init _cgo_init
+//go:linkname _cgo_thread_start _cgo_thread_start
+//go:linkname _cgo_sys_thread_create _cgo_sys_thread_create
+//go:linkname _cgo_notify_runtime_init_done _cgo_notify_runtime_init_done
+//go:linkname _cgo_callers _cgo_callers
+//go:linkname _cgo_set_context_function _cgo_set_context_function
+//go:linkname _cgo_yield _cgo_yield
+//go:linkname _cgo_pthread_key_created _cgo_pthread_key_created
+//go:linkname _cgo_bindm _cgo_bindm
+//go:linkname _cgo_getstackbound _cgo_getstackbound
+
+var (
+ _cgo_init unsafe.Pointer
+ _cgo_thread_start unsafe.Pointer
+ _cgo_sys_thread_create unsafe.Pointer
+ _cgo_notify_runtime_init_done unsafe.Pointer
+ _cgo_callers unsafe.Pointer
+ _cgo_set_context_function unsafe.Pointer
+ _cgo_yield unsafe.Pointer
+ _cgo_pthread_key_created unsafe.Pointer
+ _cgo_bindm unsafe.Pointer
+ _cgo_getstackbound unsafe.Pointer
+)
+
+// iscgo is set to true by the runtime/cgo package
+var iscgo bool
+
+// set_crosscall2 is set by the runtime/cgo package
+var set_crosscall2 func()
+
+// cgoHasExtraM is set on startup when an extra M is created for cgo.
+// The extra M must be created before any C/C++ code calls cgocallback.
+var cgoHasExtraM bool
+
+// cgoUse is called by cgo-generated code (using go:linkname to get at
+// an unexported name). The calls serve two purposes:
+// 1) they are opaque to escape analysis, so the argument is considered to
+// escape to the heap.
+// 2) they keep the argument alive until the call site; the call is emitted after
+// the end of the (presumed) use of the argument by C.
+// cgoUse should not actually be called (see cgoAlwaysFalse).
+func cgoUse(any) { throw("cgoUse should not be called") }
+
+// cgoAlwaysFalse is a boolean value that is always false.
+// The cgo-generated code says if cgoAlwaysFalse { cgoUse(p) }.
+// The compiler cannot see that cgoAlwaysFalse is always false,
+// so it emits the test and keeps the call, giving the desired
+// escape analysis result. The test is cheaper than the call.
+var cgoAlwaysFalse bool
+
+var cgo_yield = &_cgo_yield
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/abi_amd64.h b/contrib/go/_std_1.21/src/runtime/cgo/abi_amd64.h
index 9949435fe9..9949435fe9 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/abi_amd64.h
+++ b/contrib/go/_std_1.21/src/runtime/cgo/abi_amd64.h
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/abi_arm64.h b/contrib/go/_std_1.21/src/runtime/cgo/abi_arm64.h
index e2b5e6d0be..e2b5e6d0be 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/abi_arm64.h
+++ b/contrib/go/_std_1.21/src/runtime/cgo/abi_arm64.h
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s b/contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s
new file mode 100644
index 0000000000..f254622f23
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/asm_amd64.s
@@ -0,0 +1,42 @@
+// Copyright 2009 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.
+
+#include "textflag.h"
+#include "abi_amd64.h"
+
+// Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
+// It's such a pointer chain: _crosscall2_ptr -> x_crosscall2_ptr -> crosscall2
+TEXT ·set_crosscall2(SB),NOSPLIT,$0-0
+ MOVQ _crosscall2_ptr(SB), AX
+ MOVQ $crosscall2(SB), BX
+ MOVQ BX, (AX)
+ RET
+
+// Called by C code generated by cmd/cgo.
+// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
+// Saves C callee-saved registers and calls cgocallback with three arguments.
+// fn is the PC of a func(a unsafe.Pointer) function.
+// This signature is known to SWIG, so we can't change it.
+TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0-0
+ PUSH_REGS_HOST_TO_ABI0()
+
+ // Make room for arguments to cgocallback.
+ ADJSP $0x18
+#ifndef GOOS_windows
+ MOVQ DI, 0x0(SP) /* fn */
+ MOVQ SI, 0x8(SP) /* arg */
+ // Skip n in DX.
+ MOVQ CX, 0x10(SP) /* ctxt */
+#else
+ MOVQ CX, 0x0(SP) /* fn */
+ MOVQ DX, 0x8(SP) /* arg */
+ // Skip n in R8.
+ MOVQ R9, 0x10(SP) /* ctxt */
+#endif
+
+ CALL runtime·cgocallback(SB)
+
+ ADJSP $-0x18
+ POP_REGS_HOST_TO_ABI0()
+ RET
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s b/contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s
new file mode 100644
index 0000000000..ce8909b492
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/asm_arm64.s
@@ -0,0 +1,45 @@
+// Copyright 2015 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.
+
+#include "textflag.h"
+#include "abi_arm64.h"
+
+// Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
+// It's such a pointer chain: _crosscall2_ptr -> x_crosscall2_ptr -> crosscall2
+TEXT ·set_crosscall2(SB),NOSPLIT,$0-0
+ MOVD _crosscall2_ptr(SB), R1
+ MOVD $crosscall2(SB), R2
+ MOVD R2, (R1)
+ RET
+
+// Called by C code generated by cmd/cgo.
+// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
+// Saves C callee-saved registers and calls cgocallback with three arguments.
+// fn is the PC of a func(a unsafe.Pointer) function.
+TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
+ /*
+ * We still need to save all callee save register as before, and then
+ * push 3 args for fn (R0, R1, R3), skipping R2.
+ * Also note that at procedure entry in gc world, 8(RSP) will be the
+ * first arg.
+ */
+ SUB $(8*24), RSP
+ STP (R0, R1), (8*1)(RSP)
+ MOVD R3, (8*3)(RSP)
+
+ SAVE_R19_TO_R28(8*4)
+ SAVE_F8_TO_F15(8*14)
+ STP (R29, R30), (8*22)(RSP)
+
+
+ // Initialize Go ABI environment
+ BL runtime·load_g(SB)
+ BL runtime·cgocallback(SB)
+
+ RESTORE_R19_TO_R28(8*4)
+ RESTORE_F8_TO_F15(8*14)
+ LDP (8*22)(RSP), (R29, R30)
+
+ ADD $(8*24), RSP
+ RET
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/callbacks.go b/contrib/go/_std_1.21/src/runtime/cgo/callbacks.go
new file mode 100644
index 0000000000..3c246a88b6
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/callbacks.go
@@ -0,0 +1,152 @@
+// Copyright 2011 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 cgo
+
+import "unsafe"
+
+// These utility functions are available to be called from code
+// compiled with gcc via crosscall2.
+
+// The declaration of crosscall2 is:
+// void crosscall2(void (*fn)(void *), void *, int);
+//
+// We need to export the symbol crosscall2 in order to support
+// callbacks from shared libraries. This applies regardless of
+// linking mode.
+//
+// Compatibility note: SWIG uses crosscall2 in exactly one situation:
+// to call _cgo_panic using the pattern shown below. We need to keep
+// that pattern working. In particular, crosscall2 actually takes four
+// arguments, but it works to call it with three arguments when
+// calling _cgo_panic.
+//
+//go:cgo_export_static crosscall2
+//go:cgo_export_dynamic crosscall2
+
+// Panic. The argument is converted into a Go string.
+
+// Call like this in code compiled with gcc:
+// struct { const char *p; } a;
+// a.p = /* string to pass to panic */;
+// crosscall2(_cgo_panic, &a, sizeof a);
+// /* The function call will not return. */
+
+// TODO: We should export a regular C function to panic, change SWIG
+// to use that instead of the above pattern, and then we can drop
+// backwards-compatibility from crosscall2 and stop exporting it.
+
+//go:linkname _runtime_cgo_panic_internal runtime._cgo_panic_internal
+func _runtime_cgo_panic_internal(p *byte)
+
+//go:linkname _cgo_panic _cgo_panic
+//go:cgo_export_static _cgo_panic
+//go:cgo_export_dynamic _cgo_panic
+func _cgo_panic(a *struct{ cstr *byte }) {
+ _runtime_cgo_panic_internal(a.cstr)
+}
+
+//go:cgo_import_static x_cgo_init
+//go:linkname x_cgo_init x_cgo_init
+//go:linkname _cgo_init _cgo_init
+var x_cgo_init byte
+var _cgo_init = &x_cgo_init
+
+//go:cgo_import_static x_cgo_thread_start
+//go:linkname x_cgo_thread_start x_cgo_thread_start
+//go:linkname _cgo_thread_start _cgo_thread_start
+var x_cgo_thread_start byte
+var _cgo_thread_start = &x_cgo_thread_start
+
+// Creates a new system thread without updating any Go state.
+//
+// This method is invoked during shared library loading to create a new OS
+// thread to perform the runtime initialization. This method is similar to
+// _cgo_sys_thread_start except that it doesn't update any Go state.
+
+//go:cgo_import_static x_cgo_sys_thread_create
+//go:linkname x_cgo_sys_thread_create x_cgo_sys_thread_create
+//go:linkname _cgo_sys_thread_create _cgo_sys_thread_create
+var x_cgo_sys_thread_create byte
+var _cgo_sys_thread_create = &x_cgo_sys_thread_create
+
+// Indicates whether a dummy thread key has been created or not.
+//
+// When calling go exported function from C, we register a destructor
+// callback, for a dummy thread key, by using pthread_key_create.
+
+//go:cgo_import_static x_cgo_pthread_key_created
+//go:linkname x_cgo_pthread_key_created x_cgo_pthread_key_created
+//go:linkname _cgo_pthread_key_created _cgo_pthread_key_created
+var x_cgo_pthread_key_created byte
+var _cgo_pthread_key_created = &x_cgo_pthread_key_created
+
+// Export crosscall2 to a c function pointer variable.
+// Used to dropm in pthread key destructor, while C thread is exiting.
+
+//go:cgo_import_static x_crosscall2_ptr
+//go:linkname x_crosscall2_ptr x_crosscall2_ptr
+//go:linkname _crosscall2_ptr _crosscall2_ptr
+var x_crosscall2_ptr byte
+var _crosscall2_ptr = &x_crosscall2_ptr
+
+// Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
+// It's for the runtime package to call at init time.
+func set_crosscall2()
+
+//go:linkname _set_crosscall2 runtime.set_crosscall2
+var _set_crosscall2 = set_crosscall2
+
+// Store the g into the thread-specific value.
+// So that pthread_key_destructor will dropm when the thread is exiting.
+
+//go:cgo_import_static x_cgo_bindm
+//go:linkname x_cgo_bindm x_cgo_bindm
+//go:linkname _cgo_bindm _cgo_bindm
+var x_cgo_bindm byte
+var _cgo_bindm = &x_cgo_bindm
+
+// Notifies that the runtime has been initialized.
+//
+// We currently block at every CGO entry point (via _cgo_wait_runtime_init_done)
+// to ensure that the runtime has been initialized before the CGO call is
+// executed. This is necessary for shared libraries where we kickoff runtime
+// initialization in a separate thread and return without waiting for this
+// thread to complete the init.
+
+//go:cgo_import_static x_cgo_notify_runtime_init_done
+//go:linkname x_cgo_notify_runtime_init_done x_cgo_notify_runtime_init_done
+//go:linkname _cgo_notify_runtime_init_done _cgo_notify_runtime_init_done
+var x_cgo_notify_runtime_init_done byte
+var _cgo_notify_runtime_init_done = &x_cgo_notify_runtime_init_done
+
+// Sets the traceback context function. See runtime.SetCgoTraceback.
+
+//go:cgo_import_static x_cgo_set_context_function
+//go:linkname x_cgo_set_context_function x_cgo_set_context_function
+//go:linkname _cgo_set_context_function _cgo_set_context_function
+var x_cgo_set_context_function byte
+var _cgo_set_context_function = &x_cgo_set_context_function
+
+// Calls a libc function to execute background work injected via libc
+// interceptors, such as processing pending signals under the thread
+// sanitizer.
+//
+// Left as a nil pointer if no libc interceptors are expected.
+
+//go:cgo_import_static _cgo_yield
+//go:linkname _cgo_yield _cgo_yield
+var _cgo_yield unsafe.Pointer
+
+//go:cgo_export_static _cgo_topofstack
+//go:cgo_export_dynamic _cgo_topofstack
+
+// x_cgo_getstackbound gets the thread's C stack size and
+// set the G's stack bound based on the stack size.
+
+//go:cgo_import_static x_cgo_getstackbound
+//go:linkname x_cgo_getstackbound x_cgo_getstackbound
+//go:linkname _cgo_getstackbound _cgo_getstackbound
+var x_cgo_getstackbound byte
+var _cgo_getstackbound = &x_cgo_getstackbound
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/callbacks_traceback.go b/contrib/go/_std_1.21/src/runtime/cgo/callbacks_traceback.go
index c8f25118c6..c8f25118c6 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/callbacks_traceback.go
+++ b/contrib/go/_std_1.21/src/runtime/cgo/callbacks_traceback.go
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/cgo.go b/contrib/go/_std_1.21/src/runtime/cgo/cgo.go
new file mode 100644
index 0000000000..1e3a502918
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/cgo.go
@@ -0,0 +1,40 @@
+// Copyright 2010 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 cgo contains runtime support for code generated
+by the cgo tool. See the documentation for the cgo command
+for details on using cgo.
+*/
+package cgo
+
+/*
+
+#cgo darwin,!arm64 LDFLAGS: -lpthread
+#cgo darwin,arm64 LDFLAGS: -framework CoreFoundation
+#cgo dragonfly LDFLAGS: -lpthread
+#cgo freebsd LDFLAGS: -lpthread
+#cgo android LDFLAGS: -llog
+#cgo !android,linux LDFLAGS: -lpthread
+#cgo netbsd LDFLAGS: -lpthread
+#cgo openbsd LDFLAGS: -lpthread
+#cgo aix LDFLAGS: -Wl,-berok
+#cgo solaris LDFLAGS: -lxnet
+#cgo solaris LDFLAGS: -lsocket
+
+// Use -fno-stack-protector to avoid problems locating the
+// proper support functions. See issues #52919, #54313, #58385.
+#cgo CFLAGS: -Wall -Werror -fno-stack-protector
+
+#cgo solaris CPPFLAGS: -D_POSIX_PTHREAD_SEMANTICS
+
+*/
+import "C"
+
+import "runtime/internal/sys"
+
+// Incomplete is used specifically for the semantics of incomplete C types.
+type Incomplete struct {
+ _ sys.NotInHeap
+}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_amd64.S b/contrib/go/_std_1.21/src/runtime/cgo/gcc_amd64.S
index 5a1629e28c..5a1629e28c 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_amd64.S
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_amd64.S
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_arm64.S b/contrib/go/_std_1.21/src/runtime/cgo/gcc_arm64.S
index 865f67c38f..865f67c38f 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_arm64.S
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_arm64.S
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/gcc_context.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_context.c
new file mode 100644
index 0000000000..ad58692821
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_context.c
@@ -0,0 +1,20 @@
+// Copyright 2016 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.
+
+//go:build unix || windows
+
+#include "libcgo.h"
+
+// Releases the cgo traceback context.
+void _cgo_release_context(uintptr_t ctxt) {
+ void (*pfn)(struct context_arg*);
+
+ pfn = _cgo_get_context_function();
+ if (ctxt != 0 && pfn != nil) {
+ struct context_arg arg;
+
+ arg.Context = ctxt;
+ (*pfn)(&arg);
+ }
+}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_darwin_amd64.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_darwin_amd64.c
index 955b81da0b..955b81da0b 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_darwin_amd64.c
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_darwin_amd64.c
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/gcc_fatalf.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_fatalf.c
new file mode 100644
index 0000000000..9493dbb4b0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_fatalf.c
@@ -0,0 +1,23 @@
+// Copyright 2014 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.
+
+//go:build aix || (!android && linux) || freebsd
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "libcgo.h"
+
+void
+fatalf(const char* format, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "runtime/cgo: ");
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+ abort();
+}
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/gcc_libinit.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_libinit.c
new file mode 100644
index 0000000000..9676593211
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_libinit.c
@@ -0,0 +1,147 @@
+// Copyright 2015 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.
+
+//go:build unix
+
+#include <pthread.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> // strerror
+#include <time.h>
+#include "libcgo.h"
+#include "libcgo_unix.h"
+
+static pthread_cond_t runtime_init_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t runtime_init_mu = PTHREAD_MUTEX_INITIALIZER;
+static int runtime_init_done;
+
+// pthread_g is a pthread specific key, for storing the g that binded to the C thread.
+// The registered pthread_key_destructor will dropm, when the pthread-specified value g is not NULL,
+// while a C thread is exiting.
+static pthread_key_t pthread_g;
+static void pthread_key_destructor(void* g);
+uintptr_t x_cgo_pthread_key_created;
+void (*x_crosscall2_ptr)(void (*fn)(void *), void *, int, size_t);
+
+// The context function, used when tracing back C calls into Go.
+static void (*cgo_context_function)(struct context_arg*);
+
+void
+x_cgo_sys_thread_create(void* (*func)(void*), void* arg) {
+ pthread_t p;
+ int err = _cgo_try_pthread_create(&p, NULL, func, arg);
+ if (err != 0) {
+ fprintf(stderr, "pthread_create failed: %s", strerror(err));
+ abort();
+ }
+}
+
+uintptr_t
+_cgo_wait_runtime_init_done(void) {
+ void (*pfn)(struct context_arg*);
+
+ pthread_mutex_lock(&runtime_init_mu);
+ while (runtime_init_done == 0) {
+ pthread_cond_wait(&runtime_init_cond, &runtime_init_mu);
+ }
+
+ // The key and x_cgo_pthread_key_created are for the whole program,
+ // whereas the specific and destructor is per thread.
+ if (x_cgo_pthread_key_created == 0 && pthread_key_create(&pthread_g, pthread_key_destructor) == 0) {
+ x_cgo_pthread_key_created = 1;
+ }
+
+ // TODO(iant): For the case of a new C thread calling into Go, such
+ // as when using -buildmode=c-archive, we know that Go runtime
+ // initialization is complete but we do not know that all Go init
+ // functions have been run. We should not fetch cgo_context_function
+ // until they have been, because that is where a call to
+ // SetCgoTraceback is likely to occur. We are going to wait for Go
+ // initialization to be complete anyhow, later, by waiting for
+ // main_init_done to be closed in cgocallbackg1. We should wait here
+ // instead. See also issue #15943.
+ pfn = cgo_context_function;
+
+ pthread_mutex_unlock(&runtime_init_mu);
+ if (pfn != nil) {
+ struct context_arg arg;
+
+ arg.Context = 0;
+ (*pfn)(&arg);
+ return arg.Context;
+ }
+ return 0;
+}
+
+// Store the g into a thread-specific value associated with the pthread key pthread_g.
+// And pthread_key_destructor will dropm when the thread is exiting.
+void x_cgo_bindm(void* g) {
+ // We assume this will always succeed, otherwise, there might be extra M leaking,
+ // when a C thread exits after a cgo call.
+ // We only invoke this function once per thread in runtime.needAndBindM,
+ // and the next calls just reuse the bound m.
+ pthread_setspecific(pthread_g, g);
+}
+
+void
+x_cgo_notify_runtime_init_done(void* dummy __attribute__ ((unused))) {
+ pthread_mutex_lock(&runtime_init_mu);
+ runtime_init_done = 1;
+ pthread_cond_broadcast(&runtime_init_cond);
+ pthread_mutex_unlock(&runtime_init_mu);
+}
+
+// Sets the context function to call to record the traceback context
+// when calling a Go function from C code. Called from runtime.SetCgoTraceback.
+void x_cgo_set_context_function(void (*context)(struct context_arg*)) {
+ pthread_mutex_lock(&runtime_init_mu);
+ cgo_context_function = context;
+ pthread_mutex_unlock(&runtime_init_mu);
+}
+
+// Gets the context function.
+void (*(_cgo_get_context_function(void)))(struct context_arg*) {
+ void (*ret)(struct context_arg*);
+
+ pthread_mutex_lock(&runtime_init_mu);
+ ret = cgo_context_function;
+ pthread_mutex_unlock(&runtime_init_mu);
+ return ret;
+}
+
+// _cgo_try_pthread_create retries pthread_create if it fails with
+// EAGAIN.
+int
+_cgo_try_pthread_create(pthread_t* thread, const pthread_attr_t* attr, void* (*pfn)(void*), void* arg) {
+ int tries;
+ int err;
+ struct timespec ts;
+
+ for (tries = 0; tries < 20; tries++) {
+ err = pthread_create(thread, attr, pfn, arg);
+ if (err == 0) {
+ pthread_detach(*thread);
+ return 0;
+ }
+ if (err != EAGAIN) {
+ return err;
+ }
+ ts.tv_sec = 0;
+ ts.tv_nsec = (tries + 1) * 1000 * 1000; // Milliseconds.
+ nanosleep(&ts, nil);
+ }
+ return EAGAIN;
+}
+
+static void
+pthread_key_destructor(void* g) {
+ if (x_crosscall2_ptr != NULL) {
+ // fn == NULL means dropm.
+ // We restore g by using the stored g, before dropm in runtime.cgocallback,
+ // since the g stored in the TLS by Go might be cleared in some platforms,
+ // before this destructor invoked.
+ x_crosscall2_ptr(NULL, g, 0, 0);
+ }
+}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_linux_amd64.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_linux_amd64.c
index fb164c1a1d..fb164c1a1d 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_linux_amd64.c
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_linux_amd64.c
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_linux_arm64.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_linux_arm64.c
index dac45e418b..dac45e418b 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_linux_arm64.c
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_linux_arm64.c
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/gcc_mmap.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_mmap.c
new file mode 100644
index 0000000000..1fbd5e82a4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_mmap.c
@@ -0,0 +1,39 @@
+// Copyright 2015 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.
+
+//go:build (linux && (amd64 || arm64 || ppc64le)) || (freebsd && amd64)
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#include "libcgo.h"
+
+uintptr_t
+x_cgo_mmap(void *addr, uintptr_t length, int32_t prot, int32_t flags, int32_t fd, uint32_t offset) {
+ void *p;
+
+ _cgo_tsan_acquire();
+ p = mmap(addr, length, prot, flags, fd, offset);
+ _cgo_tsan_release();
+ if (p == MAP_FAILED) {
+ /* This is what the Go code expects on failure. */
+ return (uintptr_t)errno;
+ }
+ return (uintptr_t)p;
+}
+
+void
+x_cgo_munmap(void *addr, uintptr_t length) {
+ int r;
+
+ _cgo_tsan_acquire();
+ r = munmap(addr, length);
+ _cgo_tsan_release();
+ if (r < 0) {
+ /* The Go runtime is not prepared for munmap to fail. */
+ abort();
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/gcc_setenv.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_setenv.c
new file mode 100644
index 0000000000..47caa4b00a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_setenv.c
@@ -0,0 +1,27 @@
+// Copyright 2011 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.
+
+//go:build unix
+
+#include "libcgo.h"
+
+#include <stdlib.h>
+
+/* Stub for calling setenv */
+void
+x_cgo_setenv(char **arg)
+{
+ _cgo_tsan_acquire();
+ setenv(arg[0], arg[1], 1);
+ _cgo_tsan_release();
+}
+
+/* Stub for calling unsetenv */
+void
+x_cgo_unsetenv(char **arg)
+{
+ _cgo_tsan_acquire();
+ unsetenv(arg[0]);
+ _cgo_tsan_release();
+}
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/gcc_sigaction.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_sigaction.c
new file mode 100644
index 0000000000..374909bf97
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_sigaction.c
@@ -0,0 +1,82 @@
+// Copyright 2016 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.
+
+//go:build linux && (amd64 || arm64 || ppc64le)
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <signal.h>
+
+#include "libcgo.h"
+
+// go_sigaction_t is a C version of the sigactiont struct from
+// defs_linux_amd64.go. This definition — and its conversion to and from struct
+// sigaction — are specific to linux/amd64.
+typedef struct {
+ uintptr_t handler;
+ uint64_t flags;
+ uintptr_t restorer;
+ uint64_t mask;
+} go_sigaction_t;
+
+// SA_RESTORER is part of the kernel interface.
+// This is Linux i386/amd64 specific.
+#ifndef SA_RESTORER
+#define SA_RESTORER 0x4000000
+#endif
+
+int32_t
+x_cgo_sigaction(intptr_t signum, const go_sigaction_t *goact, go_sigaction_t *oldgoact) {
+ int32_t ret;
+ struct sigaction act;
+ struct sigaction oldact;
+ size_t i;
+
+ _cgo_tsan_acquire();
+
+ memset(&act, 0, sizeof act);
+ memset(&oldact, 0, sizeof oldact);
+
+ if (goact) {
+ if (goact->flags & SA_SIGINFO) {
+ act.sa_sigaction = (void(*)(int, siginfo_t*, void*))(goact->handler);
+ } else {
+ act.sa_handler = (void(*)(int))(goact->handler);
+ }
+ sigemptyset(&act.sa_mask);
+ for (i = 0; i < 8 * sizeof(goact->mask); i++) {
+ if (goact->mask & ((uint64_t)(1)<<i)) {
+ sigaddset(&act.sa_mask, (int)(i+1));
+ }
+ }
+ act.sa_flags = (int)(goact->flags & ~(uint64_t)SA_RESTORER);
+ }
+
+ ret = sigaction((int)signum, goact ? &act : NULL, oldgoact ? &oldact : NULL);
+ if (ret == -1) {
+ // runtime.rt_sigaction expects _cgo_sigaction to return errno on error.
+ _cgo_tsan_release();
+ return errno;
+ }
+
+ if (oldgoact) {
+ if (oldact.sa_flags & SA_SIGINFO) {
+ oldgoact->handler = (uintptr_t)(oldact.sa_sigaction);
+ } else {
+ oldgoact->handler = (uintptr_t)(oldact.sa_handler);
+ }
+ oldgoact->mask = 0;
+ for (i = 0; i < 8 * sizeof(oldgoact->mask); i++) {
+ if (sigismember(&oldact.sa_mask, (int)(i+1)) == 1) {
+ oldgoact->mask |= (uint64_t)(1)<<i;
+ }
+ }
+ oldgoact->flags = (uint64_t)oldact.sa_flags;
+ }
+
+ _cgo_tsan_release();
+ return ret;
+}
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/gcc_stack_darwin.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_stack_darwin.c
new file mode 100644
index 0000000000..0a9038eb3b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_stack_darwin.c
@@ -0,0 +1,20 @@
+// Copyright 2023 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.
+
+#include <pthread.h>
+#include "libcgo.h"
+
+void
+x_cgo_getstackbound(uintptr bounds[2])
+{
+ void* addr;
+ size_t size;
+ pthread_t p;
+
+ p = pthread_self();
+ addr = pthread_get_stackaddr_np(p); // high address (!)
+ size = pthread_get_stacksize_np(p);
+ bounds[0] = (uintptr)addr - size;
+ bounds[1] = (uintptr)addr;
+}
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/gcc_stack_unix.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_stack_unix.c
new file mode 100644
index 0000000000..f3fead9c9e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_stack_unix.c
@@ -0,0 +1,40 @@
+// Copyright 2023 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.
+
+//go:build unix && !darwin
+
+#ifndef _GNU_SOURCE // pthread_getattr_np
+#define _GNU_SOURCE
+#endif
+
+#include <pthread.h>
+#include "libcgo.h"
+
+void
+x_cgo_getstackbound(uintptr bounds[2])
+{
+ pthread_attr_t attr;
+ void *addr;
+ size_t size;
+
+#if defined(__GLIBC__) || (defined(__sun) && !defined(__illumos__))
+ // pthread_getattr_np is a GNU extension supported in glibc.
+ // Solaris is not glibc but does support pthread_getattr_np
+ // (and the fallback doesn't work...). Illumos does not.
+ pthread_getattr_np(pthread_self(), &attr); // GNU extension
+ pthread_attr_getstack(&attr, &addr, &size); // low address
+#elif defined(__illumos__)
+ pthread_attr_init(&attr);
+ pthread_attr_get_np(pthread_self(), &attr);
+ pthread_attr_getstack(&attr, &addr, &size); // low address
+#else
+ pthread_attr_init(&attr);
+ pthread_attr_getstacksize(&attr, &size);
+ addr = __builtin_frame_address(0) + 4096 - size;
+#endif
+ pthread_attr_destroy(&attr);
+
+ bounds[0] = (uintptr)addr;
+ bounds[1] = (uintptr)addr + size;
+}
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/gcc_traceback.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_traceback.c
new file mode 100644
index 0000000000..c6643a1e53
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_traceback.c
@@ -0,0 +1,46 @@
+// Copyright 2016 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.
+
+//go:build darwin || linux
+
+#include <stdint.h>
+#include "libcgo.h"
+
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+#if __has_feature(memory_sanitizer)
+#include <sanitizer/msan_interface.h>
+#endif
+
+// Call the user's traceback function and then call sigtramp.
+// The runtime signal handler will jump to this code.
+// We do it this way so that the user's traceback function will be called
+// by a C function with proper unwind info.
+void
+x_cgo_callers(uintptr_t sig, void *info, void *context, void (*cgoTraceback)(struct cgoTracebackArg*), uintptr_t* cgoCallers, void (*sigtramp)(uintptr_t, void*, void*)) {
+ struct cgoTracebackArg arg;
+
+ arg.Context = 0;
+ arg.SigContext = (uintptr_t)(context);
+ arg.Buf = cgoCallers;
+ arg.Max = 32; // must match len(runtime.cgoCallers)
+
+#if __has_feature(memory_sanitizer)
+ // This function is called directly from the signal handler.
+ // The arguments are passed in registers, so whether msan
+ // considers cgoCallers to be initialized depends on whether
+ // it considers the appropriate register to be initialized.
+ // That can cause false reports in rare cases.
+ // Explicitly unpoison the memory to avoid that.
+ // See issue #47543 for more details.
+ __msan_unpoison(&arg, sizeof arg);
+#endif
+
+ _cgo_tsan_acquire();
+ (*cgoTraceback)(&arg);
+ _cgo_tsan_release();
+ sigtramp(sig, info, context);
+}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/gcc_util.c b/contrib/go/_std_1.21/src/runtime/cgo/gcc_util.c
index 3fcb48cc8d..3fcb48cc8d 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/gcc_util.c
+++ b/contrib/go/_std_1.21/src/runtime/cgo/gcc_util.c
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/handle.go b/contrib/go/_std_1.21/src/runtime/cgo/handle.go
new file mode 100644
index 0000000000..061dfb0e2e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/handle.go
@@ -0,0 +1,144 @@
+// 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 cgo
+
+import (
+ "sync"
+ "sync/atomic"
+)
+
+// Handle provides a way to pass values that contain Go pointers
+// (pointers to memory allocated by Go) between Go and C without
+// breaking the cgo pointer passing rules. A Handle is an integer
+// value that can represent any Go value. A Handle can be passed
+// through C and back to Go, and Go code can use the Handle to
+// retrieve the original Go value.
+//
+// The underlying type of Handle is guaranteed to fit in an integer type
+// that is large enough to hold the bit pattern of any pointer. The zero
+// value of a Handle is not valid, and thus is safe to use as a sentinel
+// in C APIs.
+//
+// For instance, on the Go side:
+//
+// package main
+//
+// /*
+// #include <stdint.h> // for uintptr_t
+//
+// extern void MyGoPrint(uintptr_t handle);
+// void myprint(uintptr_t handle);
+// */
+// import "C"
+// import "runtime/cgo"
+//
+// //export MyGoPrint
+// func MyGoPrint(handle C.uintptr_t) {
+// h := cgo.Handle(handle)
+// val := h.Value().(string)
+// println(val)
+// h.Delete()
+// }
+//
+// func main() {
+// val := "hello Go"
+// C.myprint(C.uintptr_t(cgo.NewHandle(val)))
+// // Output: hello Go
+// }
+//
+// and on the C side:
+//
+// #include <stdint.h> // for uintptr_t
+//
+// // A Go function
+// extern void MyGoPrint(uintptr_t handle);
+//
+// // A C function
+// void myprint(uintptr_t handle) {
+// MyGoPrint(handle);
+// }
+//
+// Some C functions accept a void* argument that points to an arbitrary
+// data value supplied by the caller. It is not safe to coerce a cgo.Handle
+// (an integer) to a Go unsafe.Pointer, but instead we can pass the address
+// of the cgo.Handle to the void* parameter, as in this variant of the
+// previous example:
+//
+// package main
+//
+// /*
+// extern void MyGoPrint(void *context);
+// static inline void myprint(void *context) {
+// MyGoPrint(context);
+// }
+// */
+// import "C"
+// import (
+// "runtime/cgo"
+// "unsafe"
+// )
+//
+// //export MyGoPrint
+// func MyGoPrint(context unsafe.Pointer) {
+// h := *(*cgo.Handle)(context)
+// val := h.Value().(string)
+// println(val)
+// h.Delete()
+// }
+//
+// func main() {
+// val := "hello Go"
+// h := cgo.NewHandle(val)
+// C.myprint(unsafe.Pointer(&h))
+// // Output: hello Go
+// }
+type Handle uintptr
+
+// NewHandle returns a handle for a given value.
+//
+// The handle is valid until the program calls Delete on it. The handle
+// uses resources, and this package assumes that C code may hold on to
+// the handle, so a program must explicitly call Delete when the handle
+// is no longer needed.
+//
+// The intended use is to pass the returned handle to C code, which
+// passes it back to Go, which calls Value.
+func NewHandle(v any) Handle {
+ h := handleIdx.Add(1)
+ if h == 0 {
+ panic("runtime/cgo: ran out of handle space")
+ }
+
+ handles.Store(h, v)
+ return Handle(h)
+}
+
+// Value returns the associated Go value for a valid handle.
+//
+// The method panics if the handle is invalid.
+func (h Handle) Value() any {
+ v, ok := handles.Load(uintptr(h))
+ if !ok {
+ panic("runtime/cgo: misuse of an invalid Handle")
+ }
+ return v
+}
+
+// Delete invalidates a handle. This method should only be called once
+// the program no longer needs to pass the handle to C and the C code
+// no longer has a copy of the handle value.
+//
+// The method panics if the handle is invalid.
+func (h Handle) Delete() {
+ _, ok := handles.LoadAndDelete(uintptr(h))
+ if !ok {
+ panic("runtime/cgo: misuse of an invalid Handle")
+ }
+}
+
+var (
+ handles = sync.Map{} // map[Handle]interface{}
+ handleIdx atomic.Uintptr
+)
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/iscgo.go b/contrib/go/_std_1.21/src/runtime/cgo/iscgo.go
index 91159fe3dc..91159fe3dc 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/iscgo.go
+++ b/contrib/go/_std_1.21/src/runtime/cgo/iscgo.go
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/libcgo.h b/contrib/go/_std_1.21/src/runtime/cgo/libcgo.h
new file mode 100644
index 0000000000..04755f0f20
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/libcgo.h
@@ -0,0 +1,156 @@
+// Copyright 2009 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.
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#undef nil
+#define nil ((void*)0)
+#define nelem(x) (sizeof(x)/sizeof((x)[0]))
+
+typedef uint32_t uint32;
+typedef uint64_t uint64;
+typedef uintptr_t uintptr;
+
+/*
+ * The beginning of the per-goroutine structure,
+ * as defined in ../pkg/runtime/runtime.h.
+ * Just enough to edit these two fields.
+ */
+typedef struct G G;
+struct G
+{
+ uintptr stacklo;
+ uintptr stackhi;
+};
+
+/*
+ * Arguments to the _cgo_thread_start call.
+ * Also known to ../pkg/runtime/runtime.h.
+ */
+typedef struct ThreadStart ThreadStart;
+struct ThreadStart
+{
+ G *g;
+ uintptr *tls;
+ void (*fn)(void);
+};
+
+/*
+ * Called by 5c/6c/8c world.
+ * Makes a local copy of the ThreadStart and
+ * calls _cgo_sys_thread_start(ts).
+ */
+extern void (*_cgo_thread_start)(ThreadStart *ts);
+
+/*
+ * Creates a new operating system thread without updating any Go state
+ * (OS dependent).
+ */
+extern void (*_cgo_sys_thread_create)(void* (*func)(void*), void* arg);
+
+/*
+ * Indicates whether a dummy pthread per-thread variable is allocated.
+ */
+extern uintptr_t *_cgo_pthread_key_created;
+
+/*
+ * Creates the new operating system thread (OS, arch dependent).
+ */
+void _cgo_sys_thread_start(ThreadStart *ts);
+
+/*
+ * Waits for the Go runtime to be initialized (OS dependent).
+ * If runtime.SetCgoTraceback is used to set a context function,
+ * calls the context function and returns the context value.
+ */
+uintptr_t _cgo_wait_runtime_init_done(void);
+
+/*
+ * Call fn in the 6c world.
+ */
+void crosscall_amd64(void (*fn)(void), void (*setg_gcc)(void*), void *g);
+
+/*
+ * Call fn in the 8c world.
+ */
+void crosscall_386(void (*fn)(void));
+
+/*
+ * Prints error then calls abort. For linux and android.
+ */
+void fatalf(const char* format, ...);
+
+/*
+ * Registers the current mach thread port for EXC_BAD_ACCESS processing.
+ */
+void darwin_arm_init_thread_exception_port(void);
+
+/*
+ * Starts a mach message server processing EXC_BAD_ACCESS.
+ */
+void darwin_arm_init_mach_exception_handler(void);
+
+/*
+ * The cgo context function. See runtime.SetCgoTraceback.
+ */
+struct context_arg {
+ uintptr_t Context;
+};
+extern void (*(_cgo_get_context_function(void)))(struct context_arg*);
+
+/*
+ * The argument for the cgo traceback callback. See runtime.SetCgoTraceback.
+ */
+struct cgoTracebackArg {
+ uintptr_t Context;
+ uintptr_t SigContext;
+ uintptr_t* Buf;
+ uintptr_t Max;
+};
+
+/*
+ * TSAN support. This is only useful when building with
+ * CGO_CFLAGS="-fsanitize=thread" CGO_LDFLAGS="-fsanitize=thread" go install
+ */
+#undef CGO_TSAN
+#if defined(__has_feature)
+# if __has_feature(thread_sanitizer)
+# define CGO_TSAN
+# endif
+#elif defined(__SANITIZE_THREAD__)
+# define CGO_TSAN
+#endif
+
+#ifdef CGO_TSAN
+
+// These must match the definitions in yesTsanProlog in cmd/cgo/out.go.
+// In general we should call _cgo_tsan_acquire when we enter C code,
+// and call _cgo_tsan_release when we return to Go code.
+// This is only necessary when calling code that might be instrumented
+// by TSAN, which mostly means system library calls that TSAN intercepts.
+// See the comment in cmd/cgo/out.go for more details.
+
+long long _cgo_sync __attribute__ ((common));
+
+extern void __tsan_acquire(void*);
+extern void __tsan_release(void*);
+
+__attribute__ ((unused))
+static void _cgo_tsan_acquire() {
+ __tsan_acquire(&_cgo_sync);
+}
+
+__attribute__ ((unused))
+static void _cgo_tsan_release() {
+ __tsan_release(&_cgo_sync);
+}
+
+#else // !defined(CGO_TSAN)
+
+#define _cgo_tsan_acquire()
+#define _cgo_tsan_release()
+
+#endif // !defined(CGO_TSAN)
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/libcgo_unix.h b/contrib/go/_std_1.21/src/runtime/cgo/libcgo_unix.h
index a56a366f23..a56a366f23 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/libcgo_unix.h
+++ b/contrib/go/_std_1.21/src/runtime/cgo/libcgo_unix.h
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/linux.go b/contrib/go/_std_1.21/src/runtime/cgo/linux.go
index 1d6fe03917..1d6fe03917 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/linux.go
+++ b/contrib/go/_std_1.21/src/runtime/cgo/linux.go
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/linux_syscall.c b/contrib/go/_std_1.21/src/runtime/cgo/linux_syscall.c
new file mode 100644
index 0000000000..0ea2da719a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/linux_syscall.c
@@ -0,0 +1,85 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux
+
+#ifndef _GNU_SOURCE // setres[ug]id() API.
+#define _GNU_SOURCE
+#endif
+
+#include <grp.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include "libcgo.h"
+
+/*
+ * Assumed POSIX compliant libc system call wrappers. For linux, the
+ * glibc/nptl/setxid mechanism ensures that POSIX semantics are
+ * honored for all pthreads (by default), and this in turn with cgo
+ * ensures that all Go threads launched with cgo are kept in sync for
+ * these function calls.
+ */
+
+// argset_t matches runtime/cgocall.go:argset.
+typedef struct {
+ uintptr_t* args;
+ uintptr_t retval;
+} argset_t;
+
+// libc backed posix-compliant syscalls.
+
+#define SET_RETVAL(fn) \
+ uintptr_t ret = (uintptr_t) fn ; \
+ if (ret == (uintptr_t) -1) { \
+ x->retval = (uintptr_t) errno; \
+ } else \
+ x->retval = ret
+
+void
+_cgo_libc_setegid(argset_t* x) {
+ SET_RETVAL(setegid((gid_t) x->args[0]));
+}
+
+void
+_cgo_libc_seteuid(argset_t* x) {
+ SET_RETVAL(seteuid((uid_t) x->args[0]));
+}
+
+void
+_cgo_libc_setgid(argset_t* x) {
+ SET_RETVAL(setgid((gid_t) x->args[0]));
+}
+
+void
+_cgo_libc_setgroups(argset_t* x) {
+ SET_RETVAL(setgroups((size_t) x->args[0], (const gid_t *) x->args[1]));
+}
+
+void
+_cgo_libc_setregid(argset_t* x) {
+ SET_RETVAL(setregid((gid_t) x->args[0], (gid_t) x->args[1]));
+}
+
+void
+_cgo_libc_setresgid(argset_t* x) {
+ SET_RETVAL(setresgid((gid_t) x->args[0], (gid_t) x->args[1],
+ (gid_t) x->args[2]));
+}
+
+void
+_cgo_libc_setresuid(argset_t* x) {
+ SET_RETVAL(setresuid((uid_t) x->args[0], (uid_t) x->args[1],
+ (uid_t) x->args[2]));
+}
+
+void
+_cgo_libc_setreuid(argset_t* x) {
+ SET_RETVAL(setreuid((uid_t) x->args[0], (uid_t) x->args[1]));
+}
+
+void
+_cgo_libc_setuid(argset_t* x) {
+ SET_RETVAL(setuid((uid_t) x->args[0]));
+}
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/mmap.go b/contrib/go/_std_1.21/src/runtime/cgo/mmap.go
index 2f7e83bcb7..2f7e83bcb7 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/mmap.go
+++ b/contrib/go/_std_1.21/src/runtime/cgo/mmap.go
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/setenv.go b/contrib/go/_std_1.21/src/runtime/cgo/setenv.go
index 12f0a0014f..12f0a0014f 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/setenv.go
+++ b/contrib/go/_std_1.21/src/runtime/cgo/setenv.go
diff --git a/contrib/go/_std_1.20/src/runtime/cgo/sigaction.go b/contrib/go/_std_1.21/src/runtime/cgo/sigaction.go
index dc714f7ef4..dc714f7ef4 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo/sigaction.go
+++ b/contrib/go/_std_1.21/src/runtime/cgo/sigaction.go
diff --git a/contrib/go/_std_1.21/src/runtime/cgo/ya.make b/contrib/go/_std_1.21/src/runtime/cgo/ya.make
new file mode 100644
index 0000000000..a2b9e0a94c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgo/ya.make
@@ -0,0 +1,128 @@
+IF (CGO_ENABLED)
+ GO_LIBRARY()
+
+ PEERDIR(
+ library/cpp/sanitizer/include
+ )
+
+ NO_COMPILER_WARNINGS()
+
+ SRCS(
+ abi_loong64.h
+ abi_ppc64x.h
+ callbacks.go
+ CGO_EXPORT gcc_context.c
+ CGO_EXPORT gcc_util.c
+ handle.go
+ iscgo.go
+ libcgo.h
+ libcgo_unix.h
+ )
+ CGO_SRCS(
+ cgo.go
+ )
+
+ IF (ARCH_ARM64)
+ SRCS(
+ abi_arm64.h
+ asm_arm64.s
+ gcc_arm64.S
+ )
+ ENDIF()
+
+ IF (ARCH_X86_64)
+ SRCS(
+ abi_amd64.h
+ asm_amd64.s
+ gcc_amd64.S
+ )
+ ENDIF()
+
+ IF (OS_DARWIN)
+ SRCS(
+ callbacks_traceback.go
+ CGO_EXPORT gcc_libinit.c
+ CGO_EXPORT gcc_setenv.c
+ CGO_EXPORT gcc_stack_darwin.c
+ CGO_EXPORT gcc_traceback.c
+ setenv.go
+ )
+
+ IF (ARCH_ARM64)
+ CGO_LDFLAGS(
+ -framework
+ CoreFoundation
+ )
+
+ SRCS(
+ CGO_EXPORT gcc_darwin_arm64.c
+ )
+ ENDIF()
+
+ IF (ARCH_X86_64)
+ CGO_LDFLAGS(
+ -lpthread
+ )
+
+ SRCS(
+ CGO_EXPORT gcc_darwin_amd64.c
+ )
+ ENDIF()
+ ENDIF()
+
+ IF (OS_LINUX)
+ CGO_LDFLAGS(
+ -lpthread
+ )
+
+ SRCS(
+ callbacks_traceback.go
+ CGO_EXPORT gcc_fatalf.c
+ CGO_EXPORT gcc_libinit.c
+ CGO_EXPORT gcc_mmap.c
+ CGO_EXPORT gcc_setenv.c
+ CGO_EXPORT gcc_sigaction.c
+ CGO_EXPORT gcc_stack_unix.c
+ CGO_EXPORT gcc_traceback.c
+ linux.go
+ CGO_EXPORT linux_syscall.c
+ mmap.go
+ setenv.go
+ sigaction.go
+ )
+
+ IF (ARCH_ARM64)
+ SRCS(
+ CGO_EXPORT gcc_linux_arm64.c
+ )
+ ENDIF()
+
+ IF (ARCH_X86_64)
+ SRCS(
+ CGO_EXPORT gcc_linux_amd64.c
+ )
+ ENDIF()
+ ENDIF()
+
+ IF (OS_WINDOWS)
+ SRCS(
+ CGO_EXPORT gcc_libinit_windows.c
+ CGO_EXPORT gcc_stack_windows.c
+ libcgo_windows.h
+ )
+
+ IF (ARCH_ARM64)
+ SRCS(
+ CGO_EXPORT gcc_windows_arm64.c
+ )
+ ENDIF()
+
+ IF (ARCH_X86_64)
+ SRCS(
+ CGO_EXPORT gcc_windows_amd64.c
+ )
+ ENDIF()
+ ENDIF()
+
+ END()
+ENDIF()
diff --git a/contrib/go/_std_1.20/src/runtime/cgo_mmap.go b/contrib/go/_std_1.21/src/runtime/cgo_mmap.go
index 30660f7784..30660f7784 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo_mmap.go
+++ b/contrib/go/_std_1.21/src/runtime/cgo_mmap.go
diff --git a/contrib/go/_std_1.20/src/runtime/cgo_sigaction.go b/contrib/go/_std_1.21/src/runtime/cgo_sigaction.go
index 9500c52205..9500c52205 100644
--- a/contrib/go/_std_1.20/src/runtime/cgo_sigaction.go
+++ b/contrib/go/_std_1.21/src/runtime/cgo_sigaction.go
diff --git a/contrib/go/_std_1.21/src/runtime/cgocall.go b/contrib/go/_std_1.21/src/runtime/cgocall.go
new file mode 100644
index 0000000000..1da7249abc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgocall.go
@@ -0,0 +1,657 @@
+// Copyright 2009 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.
+
+// Cgo call and callback support.
+//
+// To call into the C function f from Go, the cgo-generated code calls
+// runtime.cgocall(_cgo_Cfunc_f, frame), where _cgo_Cfunc_f is a
+// gcc-compiled function written by cgo.
+//
+// runtime.cgocall (below) calls entersyscall so as not to block
+// other goroutines or the garbage collector, and then calls
+// runtime.asmcgocall(_cgo_Cfunc_f, frame).
+//
+// runtime.asmcgocall (in asm_$GOARCH.s) switches to the m->g0 stack
+// (assumed to be an operating system-allocated stack, so safe to run
+// gcc-compiled code on) and calls _cgo_Cfunc_f(frame).
+//
+// _cgo_Cfunc_f invokes the actual C function f with arguments
+// taken from the frame structure, records the results in the frame,
+// and returns to runtime.asmcgocall.
+//
+// After it regains control, runtime.asmcgocall switches back to the
+// original g (m->curg)'s stack and returns to runtime.cgocall.
+//
+// After it regains control, runtime.cgocall calls exitsyscall, which blocks
+// until this m can run Go code without violating the $GOMAXPROCS limit,
+// and then unlocks g from m.
+//
+// The above description skipped over the possibility of the gcc-compiled
+// function f calling back into Go. If that happens, we continue down
+// the rabbit hole during the execution of f.
+//
+// To make it possible for gcc-compiled C code to call a Go function p.GoF,
+// cgo writes a gcc-compiled function named GoF (not p.GoF, since gcc doesn't
+// know about packages). The gcc-compiled C function f calls GoF.
+//
+// GoF initializes "frame", a structure containing all of its
+// arguments and slots for p.GoF's results. It calls
+// crosscall2(_cgoexp_GoF, frame, framesize, ctxt) using the gcc ABI.
+//
+// crosscall2 (in cgo/asm_$GOARCH.s) is a four-argument adapter from
+// the gcc function call ABI to the gc function call ABI. At this
+// point we're in the Go runtime, but we're still running on m.g0's
+// stack and outside the $GOMAXPROCS limit. crosscall2 calls
+// runtime.cgocallback(_cgoexp_GoF, frame, ctxt) using the gc ABI.
+// (crosscall2's framesize argument is no longer used, but there's one
+// case where SWIG calls crosscall2 directly and expects to pass this
+// argument. See _cgo_panic.)
+//
+// runtime.cgocallback (in asm_$GOARCH.s) switches from m.g0's stack
+// to the original g (m.curg)'s stack, on which it calls
+// runtime.cgocallbackg(_cgoexp_GoF, frame, ctxt). As part of the
+// stack switch, runtime.cgocallback saves the current SP as
+// m.g0.sched.sp, so that any use of m.g0's stack during the execution
+// of the callback will be done below the existing stack frames.
+// Before overwriting m.g0.sched.sp, it pushes the old value on the
+// m.g0 stack, so that it can be restored later.
+//
+// runtime.cgocallbackg (below) is now running on a real goroutine
+// stack (not an m.g0 stack). First it calls runtime.exitsyscall, which will
+// block until the $GOMAXPROCS limit allows running this goroutine.
+// Once exitsyscall has returned, it is safe to do things like call the memory
+// allocator or invoke the Go callback function. runtime.cgocallbackg
+// first defers a function to unwind m.g0.sched.sp, so that if p.GoF
+// panics, m.g0.sched.sp will be restored to its old value: the m.g0 stack
+// and the m.curg stack will be unwound in lock step.
+// Then it calls _cgoexp_GoF(frame).
+//
+// _cgoexp_GoF, which was generated by cmd/cgo, unpacks the arguments
+// from frame, calls p.GoF, writes the results back to frame, and
+// returns. Now we start unwinding this whole process.
+//
+// runtime.cgocallbackg pops but does not execute the deferred
+// function to unwind m.g0.sched.sp, calls runtime.entersyscall, and
+// returns to runtime.cgocallback.
+//
+// After it regains control, runtime.cgocallback switches back to
+// m.g0's stack (the pointer is still in m.g0.sched.sp), restores the old
+// m.g0.sched.sp value from the stack, and returns to crosscall2.
+//
+// crosscall2 restores the callee-save registers for gcc and returns
+// to GoF, which unpacks any result values and returns to f.
+
+package runtime
+
+import (
+ "internal/goarch"
+ "internal/goexperiment"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// Addresses collected in a cgo backtrace when crashing.
+// Length must match arg.Max in x_cgo_callers in runtime/cgo/gcc_traceback.c.
+type cgoCallers [32]uintptr
+
+// argset matches runtime/cgo/linux_syscall.c:argset_t
+type argset struct {
+ args unsafe.Pointer
+ retval uintptr
+}
+
+// wrapper for syscall package to call cgocall for libc (cgo) calls.
+//
+//go:linkname syscall_cgocaller syscall.cgocaller
+//go:nosplit
+//go:uintptrescapes
+func syscall_cgocaller(fn unsafe.Pointer, args ...uintptr) uintptr {
+ as := argset{args: unsafe.Pointer(&args[0])}
+ cgocall(fn, unsafe.Pointer(&as))
+ return as.retval
+}
+
+var ncgocall uint64 // number of cgo calls in total for dead m
+
+// Call from Go to C.
+//
+// This must be nosplit because it's used for syscalls on some
+// platforms. Syscalls may have untyped arguments on the stack, so
+// it's not safe to grow or scan the stack.
+//
+//go:nosplit
+func cgocall(fn, arg unsafe.Pointer) int32 {
+ if !iscgo && GOOS != "solaris" && GOOS != "illumos" && GOOS != "windows" {
+ throw("cgocall unavailable")
+ }
+
+ if fn == nil {
+ throw("cgocall nil")
+ }
+
+ if raceenabled {
+ racereleasemerge(unsafe.Pointer(&racecgosync))
+ }
+
+ mp := getg().m
+ mp.ncgocall++
+
+ // Reset traceback.
+ mp.cgoCallers[0] = 0
+
+ // Announce we are entering a system call
+ // so that the scheduler knows to create another
+ // M to run goroutines while we are in the
+ // foreign code.
+ //
+ // The call to asmcgocall is guaranteed not to
+ // grow the stack and does not allocate memory,
+ // so it is safe to call while "in a system call", outside
+ // the $GOMAXPROCS accounting.
+ //
+ // fn may call back into Go code, in which case we'll exit the
+ // "system call", run the Go code (which may grow the stack),
+ // and then re-enter the "system call" reusing the PC and SP
+ // saved by entersyscall here.
+ entersyscall()
+
+ // Tell asynchronous preemption that we're entering external
+ // code. We do this after entersyscall because this may block
+ // and cause an async preemption to fail, but at this point a
+ // sync preemption will succeed (though this is not a matter
+ // of correctness).
+ osPreemptExtEnter(mp)
+
+ mp.incgo = true
+ // We use ncgo as a check during execution tracing for whether there is
+ // any C on the call stack, which there will be after this point. If
+ // there isn't, we can use frame pointer unwinding to collect call
+ // stacks efficiently. This will be the case for the first Go-to-C call
+ // on a stack, so it's prefereable to update it here, after we emit a
+ // trace event in entersyscall above.
+ mp.ncgo++
+
+ errno := asmcgocall(fn, arg)
+
+ // Update accounting before exitsyscall because exitsyscall may
+ // reschedule us on to a different M.
+ mp.incgo = false
+ mp.ncgo--
+
+ osPreemptExtExit(mp)
+
+ exitsyscall()
+
+ // Note that raceacquire must be called only after exitsyscall has
+ // wired this M to a P.
+ if raceenabled {
+ raceacquire(unsafe.Pointer(&racecgosync))
+ }
+
+ // From the garbage collector's perspective, time can move
+ // backwards in the sequence above. If there's a callback into
+ // Go code, GC will see this function at the call to
+ // asmcgocall. When the Go call later returns to C, the
+ // syscall PC/SP is rolled back and the GC sees this function
+ // back at the call to entersyscall. Normally, fn and arg
+ // would be live at entersyscall and dead at asmcgocall, so if
+ // time moved backwards, GC would see these arguments as dead
+ // and then live. Prevent these undead arguments from crashing
+ // GC by forcing them to stay live across this time warp.
+ KeepAlive(fn)
+ KeepAlive(arg)
+ KeepAlive(mp)
+
+ return errno
+}
+
+// Call from C back to Go. fn must point to an ABIInternal Go entry-point.
+//
+//go:nosplit
+func cgocallbackg(fn, frame unsafe.Pointer, ctxt uintptr) {
+ gp := getg()
+ if gp != gp.m.curg {
+ println("runtime: bad g in cgocallback")
+ exit(2)
+ }
+
+ // The call from C is on gp.m's g0 stack, so we must ensure
+ // that we stay on that M. We have to do this before calling
+ // exitsyscall, since it would otherwise be free to move us to
+ // a different M. The call to unlockOSThread is in unwindm.
+ lockOSThread()
+
+ checkm := gp.m
+
+ // Save current syscall parameters, so m.syscall can be
+ // used again if callback decide to make syscall.
+ syscall := gp.m.syscall
+
+ // entersyscall saves the caller's SP to allow the GC to trace the Go
+ // stack. However, since we're returning to an earlier stack frame and
+ // need to pair with the entersyscall() call made by cgocall, we must
+ // save syscall* and let reentersyscall restore them.
+ savedsp := unsafe.Pointer(gp.syscallsp)
+ savedpc := gp.syscallpc
+ exitsyscall() // coming out of cgo call
+ gp.m.incgo = false
+ if gp.m.isextra {
+ gp.m.isExtraInC = false
+ }
+
+ osPreemptExtExit(gp.m)
+
+ cgocallbackg1(fn, frame, ctxt) // will call unlockOSThread
+
+ // At this point unlockOSThread has been called.
+ // The following code must not change to a different m.
+ // This is enforced by checking incgo in the schedule function.
+
+ gp.m.incgo = true
+ if gp.m.isextra {
+ gp.m.isExtraInC = true
+ }
+
+ if gp.m != checkm {
+ throw("m changed unexpectedly in cgocallbackg")
+ }
+
+ osPreemptExtEnter(gp.m)
+
+ // going back to cgo call
+ reentersyscall(savedpc, uintptr(savedsp))
+
+ gp.m.syscall = syscall
+}
+
+func cgocallbackg1(fn, frame unsafe.Pointer, ctxt uintptr) {
+ gp := getg()
+
+ // When we return, undo the call to lockOSThread in cgocallbackg.
+ // We must still stay on the same m.
+ defer unlockOSThread()
+
+ if gp.m.needextram || extraMWaiters.Load() > 0 {
+ gp.m.needextram = false
+ systemstack(newextram)
+ }
+
+ if ctxt != 0 {
+ s := append(gp.cgoCtxt, ctxt)
+
+ // Now we need to set gp.cgoCtxt = s, but we could get
+ // a SIGPROF signal while manipulating the slice, and
+ // the SIGPROF handler could pick up gp.cgoCtxt while
+ // tracing up the stack. We need to ensure that the
+ // handler always sees a valid slice, so set the
+ // values in an order such that it always does.
+ p := (*slice)(unsafe.Pointer(&gp.cgoCtxt))
+ atomicstorep(unsafe.Pointer(&p.array), unsafe.Pointer(&s[0]))
+ p.cap = cap(s)
+ p.len = len(s)
+
+ defer func(gp *g) {
+ // Decrease the length of the slice by one, safely.
+ p := (*slice)(unsafe.Pointer(&gp.cgoCtxt))
+ p.len--
+ }(gp)
+ }
+
+ if gp.m.ncgo == 0 {
+ // The C call to Go came from a thread not currently running
+ // any Go. In the case of -buildmode=c-archive or c-shared,
+ // this call may be coming in before package initialization
+ // is complete. Wait until it is.
+ <-main_init_done
+ }
+
+ // Check whether the profiler needs to be turned on or off; this route to
+ // run Go code does not use runtime.execute, so bypasses the check there.
+ hz := sched.profilehz
+ if gp.m.profilehz != hz {
+ setThreadCPUProfiler(hz)
+ }
+
+ // Add entry to defer stack in case of panic.
+ restore := true
+ defer unwindm(&restore)
+
+ if raceenabled {
+ raceacquire(unsafe.Pointer(&racecgosync))
+ }
+
+ // Invoke callback. This function is generated by cmd/cgo and
+ // will unpack the argument frame and call the Go function.
+ var cb func(frame unsafe.Pointer)
+ cbFV := funcval{uintptr(fn)}
+ *(*unsafe.Pointer)(unsafe.Pointer(&cb)) = noescape(unsafe.Pointer(&cbFV))
+ cb(frame)
+
+ if raceenabled {
+ racereleasemerge(unsafe.Pointer(&racecgosync))
+ }
+
+ // Do not unwind m->g0->sched.sp.
+ // Our caller, cgocallback, will do that.
+ restore = false
+}
+
+func unwindm(restore *bool) {
+ if *restore {
+ // Restore sp saved by cgocallback during
+ // unwind of g's stack (see comment at top of file).
+ mp := acquirem()
+ sched := &mp.g0.sched
+ sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + alignUp(sys.MinFrameSize, sys.StackAlign)))
+
+ // Do the accounting that cgocall will not have a chance to do
+ // during an unwind.
+ //
+ // In the case where a Go call originates from C, ncgo is 0
+ // and there is no matching cgocall to end.
+ if mp.ncgo > 0 {
+ mp.incgo = false
+ mp.ncgo--
+ osPreemptExtExit(mp)
+ }
+
+ releasem(mp)
+ }
+}
+
+// called from assembly.
+func badcgocallback() {
+ throw("misaligned stack in cgocallback")
+}
+
+// called from (incomplete) assembly.
+func cgounimpl() {
+ throw("cgo not implemented")
+}
+
+var racecgosync uint64 // represents possible synchronization in C code
+
+// Pointer checking for cgo code.
+
+// We want to detect all cases where a program that does not use
+// unsafe makes a cgo call passing a Go pointer to memory that
+// contains an unpinned Go pointer. Here a Go pointer is defined as a
+// pointer to memory allocated by the Go runtime. Programs that use
+// unsafe can evade this restriction easily, so we don't try to catch
+// them. The cgo program will rewrite all possibly bad pointer
+// arguments to call cgoCheckPointer, where we can catch cases of a Go
+// pointer pointing to an unpinned Go pointer.
+
+// Complicating matters, taking the address of a slice or array
+// element permits the C program to access all elements of the slice
+// or array. In that case we will see a pointer to a single element,
+// but we need to check the entire data structure.
+
+// The cgoCheckPointer call takes additional arguments indicating that
+// it was called on an address expression. An additional argument of
+// true means that it only needs to check a single element. An
+// additional argument of a slice or array means that it needs to
+// check the entire slice/array, but nothing else. Otherwise, the
+// pointer could be anything, and we check the entire heap object,
+// which is conservative but safe.
+
+// When and if we implement a moving garbage collector,
+// cgoCheckPointer will pin the pointer for the duration of the cgo
+// call. (This is necessary but not sufficient; the cgo program will
+// also have to change to pin Go pointers that cannot point to Go
+// pointers.)
+
+// cgoCheckPointer checks if the argument contains a Go pointer that
+// points to an unpinned Go pointer, and panics if it does.
+func cgoCheckPointer(ptr any, arg any) {
+ if !goexperiment.CgoCheck2 && debug.cgocheck == 0 {
+ return
+ }
+
+ ep := efaceOf(&ptr)
+ t := ep._type
+
+ top := true
+ if arg != nil && (t.Kind_&kindMask == kindPtr || t.Kind_&kindMask == kindUnsafePointer) {
+ p := ep.data
+ if t.Kind_&kindDirectIface == 0 {
+ p = *(*unsafe.Pointer)(p)
+ }
+ if p == nil || !cgoIsGoPointer(p) {
+ return
+ }
+ aep := efaceOf(&arg)
+ switch aep._type.Kind_ & kindMask {
+ case kindBool:
+ if t.Kind_&kindMask == kindUnsafePointer {
+ // We don't know the type of the element.
+ break
+ }
+ pt := (*ptrtype)(unsafe.Pointer(t))
+ cgoCheckArg(pt.Elem, p, true, false, cgoCheckPointerFail)
+ return
+ case kindSlice:
+ // Check the slice rather than the pointer.
+ ep = aep
+ t = ep._type
+ case kindArray:
+ // Check the array rather than the pointer.
+ // Pass top as false since we have a pointer
+ // to the array.
+ ep = aep
+ t = ep._type
+ top = false
+ default:
+ throw("can't happen")
+ }
+ }
+
+ cgoCheckArg(t, ep.data, t.Kind_&kindDirectIface == 0, top, cgoCheckPointerFail)
+}
+
+const cgoCheckPointerFail = "cgo argument has Go pointer to unpinned Go pointer"
+const cgoResultFail = "cgo result has Go pointer"
+
+// cgoCheckArg is the real work of cgoCheckPointer. The argument p
+// is either a pointer to the value (of type t), or the value itself,
+// depending on indir. The top parameter is whether we are at the top
+// level, where Go pointers are allowed. Go pointers to pinned objects are
+// always allowed.
+func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
+ if t.PtrBytes == 0 || p == nil {
+ // If the type has no pointers there is nothing to do.
+ return
+ }
+
+ switch t.Kind_ & kindMask {
+ default:
+ throw("can't happen")
+ case kindArray:
+ at := (*arraytype)(unsafe.Pointer(t))
+ if !indir {
+ if at.Len != 1 {
+ throw("can't happen")
+ }
+ cgoCheckArg(at.Elem, p, at.Elem.Kind_&kindDirectIface == 0, top, msg)
+ return
+ }
+ for i := uintptr(0); i < at.Len; i++ {
+ cgoCheckArg(at.Elem, p, true, top, msg)
+ p = add(p, at.Elem.Size_)
+ }
+ case kindChan, kindMap:
+ // These types contain internal pointers that will
+ // always be allocated in the Go heap. It's never OK
+ // to pass them to C.
+ panic(errorString(msg))
+ case kindFunc:
+ if indir {
+ p = *(*unsafe.Pointer)(p)
+ }
+ if !cgoIsGoPointer(p) {
+ return
+ }
+ panic(errorString(msg))
+ case kindInterface:
+ it := *(**_type)(p)
+ if it == nil {
+ return
+ }
+ // A type known at compile time is OK since it's
+ // constant. A type not known at compile time will be
+ // in the heap and will not be OK.
+ if inheap(uintptr(unsafe.Pointer(it))) {
+ panic(errorString(msg))
+ }
+ p = *(*unsafe.Pointer)(add(p, goarch.PtrSize))
+ if !cgoIsGoPointer(p) {
+ return
+ }
+ if !top && !isPinned(p) {
+ panic(errorString(msg))
+ }
+ cgoCheckArg(it, p, it.Kind_&kindDirectIface == 0, false, msg)
+ case kindSlice:
+ st := (*slicetype)(unsafe.Pointer(t))
+ s := (*slice)(p)
+ p = s.array
+ if p == nil || !cgoIsGoPointer(p) {
+ return
+ }
+ if !top && !isPinned(p) {
+ panic(errorString(msg))
+ }
+ if st.Elem.PtrBytes == 0 {
+ return
+ }
+ for i := 0; i < s.cap; i++ {
+ cgoCheckArg(st.Elem, p, true, false, msg)
+ p = add(p, st.Elem.Size_)
+ }
+ case kindString:
+ ss := (*stringStruct)(p)
+ if !cgoIsGoPointer(ss.str) {
+ return
+ }
+ if !top && !isPinned(ss.str) {
+ panic(errorString(msg))
+ }
+ case kindStruct:
+ st := (*structtype)(unsafe.Pointer(t))
+ if !indir {
+ if len(st.Fields) != 1 {
+ throw("can't happen")
+ }
+ cgoCheckArg(st.Fields[0].Typ, p, st.Fields[0].Typ.Kind_&kindDirectIface == 0, top, msg)
+ return
+ }
+ for _, f := range st.Fields {
+ if f.Typ.PtrBytes == 0 {
+ continue
+ }
+ cgoCheckArg(f.Typ, add(p, f.Offset), true, top, msg)
+ }
+ case kindPtr, kindUnsafePointer:
+ if indir {
+ p = *(*unsafe.Pointer)(p)
+ if p == nil {
+ return
+ }
+ }
+
+ if !cgoIsGoPointer(p) {
+ return
+ }
+ if !top && !isPinned(p) {
+ panic(errorString(msg))
+ }
+
+ cgoCheckUnknownPointer(p, msg)
+ }
+}
+
+// cgoCheckUnknownPointer is called for an arbitrary pointer into Go
+// memory. It checks whether that Go memory contains any other
+// pointer into unpinned Go memory. If it does, we panic.
+// The return values are unused but useful to see in panic tracebacks.
+func cgoCheckUnknownPointer(p unsafe.Pointer, msg string) (base, i uintptr) {
+ if inheap(uintptr(p)) {
+ b, span, _ := findObject(uintptr(p), 0, 0)
+ base = b
+ if base == 0 {
+ return
+ }
+ n := span.elemsize
+ hbits := heapBitsForAddr(base, n)
+ for {
+ var addr uintptr
+ if hbits, addr = hbits.next(); addr == 0 {
+ break
+ }
+ pp := *(*unsafe.Pointer)(unsafe.Pointer(addr))
+ if cgoIsGoPointer(pp) && !isPinned(pp) {
+ panic(errorString(msg))
+ }
+ }
+
+ return
+ }
+
+ for _, datap := range activeModules() {
+ if cgoInRange(p, datap.data, datap.edata) || cgoInRange(p, datap.bss, datap.ebss) {
+ // We have no way to know the size of the object.
+ // We have to assume that it might contain a pointer.
+ panic(errorString(msg))
+ }
+ // In the text or noptr sections, we know that the
+ // pointer does not point to a Go pointer.
+ }
+
+ return
+}
+
+// cgoIsGoPointer reports whether the pointer is a Go pointer--a
+// pointer to Go memory. We only care about Go memory that might
+// contain pointers.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func cgoIsGoPointer(p unsafe.Pointer) bool {
+ if p == nil {
+ return false
+ }
+
+ if inHeapOrStack(uintptr(p)) {
+ return true
+ }
+
+ for _, datap := range activeModules() {
+ if cgoInRange(p, datap.data, datap.edata) || cgoInRange(p, datap.bss, datap.ebss) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// cgoInRange reports whether p is between start and end.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func cgoInRange(p unsafe.Pointer, start, end uintptr) bool {
+ return start <= uintptr(p) && uintptr(p) < end
+}
+
+// cgoCheckResult is called to check the result parameter of an
+// exported Go function. It panics if the result is or contains a Go
+// pointer.
+func cgoCheckResult(val any) {
+ if !goexperiment.CgoCheck2 && debug.cgocheck == 0 {
+ return
+ }
+
+ ep := efaceOf(&val)
+ t := ep._type
+ cgoCheckArg(t, ep.data, t.Kind_&kindDirectIface == 0, false, cgoResultFail)
+}
diff --git a/contrib/go/_std_1.20/src/runtime/cgocallback.go b/contrib/go/_std_1.21/src/runtime/cgocallback.go
index 59953f1cee..59953f1cee 100644
--- a/contrib/go/_std_1.20/src/runtime/cgocallback.go
+++ b/contrib/go/_std_1.21/src/runtime/cgocallback.go
diff --git a/contrib/go/_std_1.21/src/runtime/cgocheck.go b/contrib/go/_std_1.21/src/runtime/cgocheck.go
new file mode 100644
index 0000000000..ec5734a5c7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cgocheck.go
@@ -0,0 +1,292 @@
+// Copyright 2015 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.
+
+// Code to check that pointer writes follow the cgo rules.
+// These functions are invoked when GOEXPERIMENT=cgocheck2 is enabled.
+
+package runtime
+
+import (
+ "internal/goarch"
+ "unsafe"
+)
+
+const cgoWriteBarrierFail = "unpinned Go pointer stored into non-Go memory"
+
+// cgoCheckPtrWrite is called whenever a pointer is stored into memory.
+// It throws if the program is storing an unpinned Go pointer into non-Go
+// memory.
+//
+// This is called from generated code when GOEXPERIMENT=cgocheck2 is enabled.
+//
+//go:nosplit
+//go:nowritebarrier
+func cgoCheckPtrWrite(dst *unsafe.Pointer, src unsafe.Pointer) {
+ if !mainStarted {
+ // Something early in startup hates this function.
+ // Don't start doing any actual checking until the
+ // runtime has set itself up.
+ return
+ }
+ if !cgoIsGoPointer(src) {
+ return
+ }
+ if cgoIsGoPointer(unsafe.Pointer(dst)) {
+ return
+ }
+
+ // If we are running on the system stack then dst might be an
+ // address on the stack, which is OK.
+ gp := getg()
+ if gp == gp.m.g0 || gp == gp.m.gsignal {
+ return
+ }
+
+ // Allocating memory can write to various mfixalloc structs
+ // that look like they are non-Go memory.
+ if gp.m.mallocing != 0 {
+ return
+ }
+
+ // If the object is pinned, it's safe to store it in C memory. The GC
+ // ensures it will not be moved or freed.
+ if isPinned(src) {
+ return
+ }
+
+ // It's OK if writing to memory allocated by persistentalloc.
+ // Do this check last because it is more expensive and rarely true.
+ // If it is false the expense doesn't matter since we are crashing.
+ if inPersistentAlloc(uintptr(unsafe.Pointer(dst))) {
+ return
+ }
+
+ systemstack(func() {
+ println("write of unpinned Go pointer", hex(uintptr(src)), "to non-Go memory", hex(uintptr(unsafe.Pointer(dst))))
+ throw(cgoWriteBarrierFail)
+ })
+}
+
+// cgoCheckMemmove is called when moving a block of memory.
+// It throws if the program is copying a block that contains an unpinned Go
+// pointer into non-Go memory.
+//
+// This is called from generated code when GOEXPERIMENT=cgocheck2 is enabled.
+//
+//go:nosplit
+//go:nowritebarrier
+func cgoCheckMemmove(typ *_type, dst, src unsafe.Pointer) {
+ cgoCheckMemmove2(typ, dst, src, 0, typ.Size_)
+}
+
+// cgoCheckMemmove2 is called when moving a block of memory.
+// dst and src point off bytes into the value to copy.
+// size is the number of bytes to copy.
+// It throws if the program is copying a block that contains an unpinned Go
+// pointer into non-Go memory.
+//
+//go:nosplit
+//go:nowritebarrier
+func cgoCheckMemmove2(typ *_type, dst, src unsafe.Pointer, off, size uintptr) {
+ if typ.PtrBytes == 0 {
+ return
+ }
+ if !cgoIsGoPointer(src) {
+ return
+ }
+ if cgoIsGoPointer(dst) {
+ return
+ }
+ cgoCheckTypedBlock(typ, src, off, size)
+}
+
+// cgoCheckSliceCopy is called when copying n elements of a slice.
+// src and dst are pointers to the first element of the slice.
+// typ is the element type of the slice.
+// It throws if the program is copying slice elements that contain unpinned Go
+// pointers into non-Go memory.
+//
+//go:nosplit
+//go:nowritebarrier
+func cgoCheckSliceCopy(typ *_type, dst, src unsafe.Pointer, n int) {
+ if typ.PtrBytes == 0 {
+ return
+ }
+ if !cgoIsGoPointer(src) {
+ return
+ }
+ if cgoIsGoPointer(dst) {
+ return
+ }
+ p := src
+ for i := 0; i < n; i++ {
+ cgoCheckTypedBlock(typ, p, 0, typ.Size_)
+ p = add(p, typ.Size_)
+ }
+}
+
+// cgoCheckTypedBlock checks the block of memory at src, for up to size bytes,
+// and throws if it finds an unpinned Go pointer. The type of the memory is typ,
+// and src is off bytes into that type.
+//
+//go:nosplit
+//go:nowritebarrier
+func cgoCheckTypedBlock(typ *_type, src unsafe.Pointer, off, size uintptr) {
+ // Anything past typ.PtrBytes is not a pointer.
+ if typ.PtrBytes <= off {
+ return
+ }
+ if ptrdataSize := typ.PtrBytes - off; size > ptrdataSize {
+ size = ptrdataSize
+ }
+
+ if typ.Kind_&kindGCProg == 0 {
+ cgoCheckBits(src, typ.GCData, off, size)
+ return
+ }
+
+ // The type has a GC program. Try to find GC bits somewhere else.
+ for _, datap := range activeModules() {
+ if cgoInRange(src, datap.data, datap.edata) {
+ doff := uintptr(src) - datap.data
+ cgoCheckBits(add(src, -doff), datap.gcdatamask.bytedata, off+doff, size)
+ return
+ }
+ if cgoInRange(src, datap.bss, datap.ebss) {
+ boff := uintptr(src) - datap.bss
+ cgoCheckBits(add(src, -boff), datap.gcbssmask.bytedata, off+boff, size)
+ return
+ }
+ }
+
+ s := spanOfUnchecked(uintptr(src))
+ if s.state.get() == mSpanManual {
+ // There are no heap bits for value stored on the stack.
+ // For a channel receive src might be on the stack of some
+ // other goroutine, so we can't unwind the stack even if
+ // we wanted to.
+ // We can't expand the GC program without extra storage
+ // space we can't easily get.
+ // Fortunately we have the type information.
+ systemstack(func() {
+ cgoCheckUsingType(typ, src, off, size)
+ })
+ return
+ }
+
+ // src must be in the regular heap.
+
+ hbits := heapBitsForAddr(uintptr(src), size)
+ for {
+ var addr uintptr
+ if hbits, addr = hbits.next(); addr == 0 {
+ break
+ }
+ v := *(*unsafe.Pointer)(unsafe.Pointer(addr))
+ if cgoIsGoPointer(v) && !isPinned(v) {
+ throw(cgoWriteBarrierFail)
+ }
+ }
+}
+
+// cgoCheckBits checks the block of memory at src, for up to size
+// bytes, and throws if it finds an unpinned Go pointer. The gcbits mark each
+// pointer value. The src pointer is off bytes into the gcbits.
+//
+//go:nosplit
+//go:nowritebarrier
+func cgoCheckBits(src unsafe.Pointer, gcbits *byte, off, size uintptr) {
+ skipMask := off / goarch.PtrSize / 8
+ skipBytes := skipMask * goarch.PtrSize * 8
+ ptrmask := addb(gcbits, skipMask)
+ src = add(src, skipBytes)
+ off -= skipBytes
+ size += off
+ var bits uint32
+ for i := uintptr(0); i < size; i += goarch.PtrSize {
+ if i&(goarch.PtrSize*8-1) == 0 {
+ bits = uint32(*ptrmask)
+ ptrmask = addb(ptrmask, 1)
+ } else {
+ bits >>= 1
+ }
+ if off > 0 {
+ off -= goarch.PtrSize
+ } else {
+ if bits&1 != 0 {
+ v := *(*unsafe.Pointer)(add(src, i))
+ if cgoIsGoPointer(v) && !isPinned(v) {
+ throw(cgoWriteBarrierFail)
+ }
+ }
+ }
+ }
+}
+
+// cgoCheckUsingType is like cgoCheckTypedBlock, but is a last ditch
+// fall back to look for pointers in src using the type information.
+// We only use this when looking at a value on the stack when the type
+// uses a GC program, because otherwise it's more efficient to use the
+// GC bits. This is called on the system stack.
+//
+//go:nowritebarrier
+//go:systemstack
+func cgoCheckUsingType(typ *_type, src unsafe.Pointer, off, size uintptr) {
+ if typ.PtrBytes == 0 {
+ return
+ }
+
+ // Anything past typ.PtrBytes is not a pointer.
+ if typ.PtrBytes <= off {
+ return
+ }
+ if ptrdataSize := typ.PtrBytes - off; size > ptrdataSize {
+ size = ptrdataSize
+ }
+
+ if typ.Kind_&kindGCProg == 0 {
+ cgoCheckBits(src, typ.GCData, off, size)
+ return
+ }
+ switch typ.Kind_ & kindMask {
+ default:
+ throw("can't happen")
+ case kindArray:
+ at := (*arraytype)(unsafe.Pointer(typ))
+ for i := uintptr(0); i < at.Len; i++ {
+ if off < at.Elem.Size_ {
+ cgoCheckUsingType(at.Elem, src, off, size)
+ }
+ src = add(src, at.Elem.Size_)
+ skipped := off
+ if skipped > at.Elem.Size_ {
+ skipped = at.Elem.Size_
+ }
+ checked := at.Elem.Size_ - skipped
+ off -= skipped
+ if size <= checked {
+ return
+ }
+ size -= checked
+ }
+ case kindStruct:
+ st := (*structtype)(unsafe.Pointer(typ))
+ for _, f := range st.Fields {
+ if off < f.Typ.Size_ {
+ cgoCheckUsingType(f.Typ, src, off, size)
+ }
+ src = add(src, f.Typ.Size_)
+ skipped := off
+ if skipped > f.Typ.Size_ {
+ skipped = f.Typ.Size_
+ }
+ checked := f.Typ.Size_ - skipped
+ off -= skipped
+ if size <= checked {
+ return
+ }
+ size -= checked
+ }
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/chan.go b/contrib/go/_std_1.21/src/runtime/chan.go
new file mode 100644
index 0000000000..ff9e2a9155
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/chan.go
@@ -0,0 +1,851 @@
+// Copyright 2014 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 runtime
+
+// This file contains the implementation of Go channels.
+
+// Invariants:
+// At least one of c.sendq and c.recvq is empty,
+// except for the case of an unbuffered channel with a single goroutine
+// blocked on it for both sending and receiving using a select statement,
+// in which case the length of c.sendq and c.recvq is limited only by the
+// size of the select statement.
+//
+// For buffered channels, also:
+// c.qcount > 0 implies that c.recvq is empty.
+// c.qcount < c.dataqsiz implies that c.sendq is empty.
+
+import (
+ "internal/abi"
+ "runtime/internal/atomic"
+ "runtime/internal/math"
+ "unsafe"
+)
+
+const (
+ maxAlign = 8
+ hchanSize = unsafe.Sizeof(hchan{}) + uintptr(-int(unsafe.Sizeof(hchan{}))&(maxAlign-1))
+ debugChan = false
+)
+
+type hchan struct {
+ qcount uint // total data in the queue
+ dataqsiz uint // size of the circular queue
+ buf unsafe.Pointer // points to an array of dataqsiz elements
+ elemsize uint16
+ closed uint32
+ elemtype *_type // element type
+ sendx uint // send index
+ recvx uint // receive index
+ recvq waitq // list of recv waiters
+ sendq waitq // list of send waiters
+
+ // lock protects all fields in hchan, as well as several
+ // fields in sudogs blocked on this channel.
+ //
+ // Do not change another G's status while holding this lock
+ // (in particular, do not ready a G), as this can deadlock
+ // with stack shrinking.
+ lock mutex
+}
+
+type waitq struct {
+ first *sudog
+ last *sudog
+}
+
+//go:linkname reflect_makechan reflect.makechan
+func reflect_makechan(t *chantype, size int) *hchan {
+ return makechan(t, size)
+}
+
+func makechan64(t *chantype, size int64) *hchan {
+ if int64(int(size)) != size {
+ panic(plainError("makechan: size out of range"))
+ }
+
+ return makechan(t, int(size))
+}
+
+func makechan(t *chantype, size int) *hchan {
+ elem := t.Elem
+
+ // compiler checks this but be safe.
+ if elem.Size_ >= 1<<16 {
+ throw("makechan: invalid channel element type")
+ }
+ if hchanSize%maxAlign != 0 || elem.Align_ > maxAlign {
+ throw("makechan: bad alignment")
+ }
+
+ mem, overflow := math.MulUintptr(elem.Size_, uintptr(size))
+ if overflow || mem > maxAlloc-hchanSize || size < 0 {
+ panic(plainError("makechan: size out of range"))
+ }
+
+ // Hchan does not contain pointers interesting for GC when elements stored in buf do not contain pointers.
+ // buf points into the same allocation, elemtype is persistent.
+ // SudoG's are referenced from their owning thread so they can't be collected.
+ // TODO(dvyukov,rlh): Rethink when collector can move allocated objects.
+ var c *hchan
+ switch {
+ case mem == 0:
+ // Queue or element size is zero.
+ c = (*hchan)(mallocgc(hchanSize, nil, true))
+ // Race detector uses this location for synchronization.
+ c.buf = c.raceaddr()
+ case elem.PtrBytes == 0:
+ // Elements do not contain pointers.
+ // Allocate hchan and buf in one call.
+ c = (*hchan)(mallocgc(hchanSize+mem, nil, true))
+ c.buf = add(unsafe.Pointer(c), hchanSize)
+ default:
+ // Elements contain pointers.
+ c = new(hchan)
+ c.buf = mallocgc(mem, elem, true)
+ }
+
+ c.elemsize = uint16(elem.Size_)
+ c.elemtype = elem
+ c.dataqsiz = uint(size)
+ lockInit(&c.lock, lockRankHchan)
+
+ if debugChan {
+ print("makechan: chan=", c, "; elemsize=", elem.Size_, "; dataqsiz=", size, "\n")
+ }
+ return c
+}
+
+// chanbuf(c, i) is pointer to the i'th slot in the buffer.
+func chanbuf(c *hchan, i uint) unsafe.Pointer {
+ return add(c.buf, uintptr(i)*uintptr(c.elemsize))
+}
+
+// full reports whether a send on c would block (that is, the channel is full).
+// It uses a single word-sized read of mutable state, so although
+// the answer is instantaneously true, the correct answer may have changed
+// by the time the calling function receives the return value.
+func full(c *hchan) bool {
+ // c.dataqsiz is immutable (never written after the channel is created)
+ // so it is safe to read at any time during channel operation.
+ if c.dataqsiz == 0 {
+ // Assumes that a pointer read is relaxed-atomic.
+ return c.recvq.first == nil
+ }
+ // Assumes that a uint read is relaxed-atomic.
+ return c.qcount == c.dataqsiz
+}
+
+// entry point for c <- x from compiled code.
+//
+//go:nosplit
+func chansend1(c *hchan, elem unsafe.Pointer) {
+ chansend(c, elem, true, getcallerpc())
+}
+
+/*
+ * generic single channel send/recv
+ * If block is not nil,
+ * then the protocol will not
+ * sleep but return if it could
+ * not complete.
+ *
+ * sleep can wake up with g.param == nil
+ * when a channel involved in the sleep has
+ * been closed. it is easiest to loop and re-run
+ * the operation; we'll see that it's now closed.
+ */
+func chansend(c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool {
+ if c == nil {
+ if !block {
+ return false
+ }
+ gopark(nil, nil, waitReasonChanSendNilChan, traceBlockForever, 2)
+ throw("unreachable")
+ }
+
+ if debugChan {
+ print("chansend: chan=", c, "\n")
+ }
+
+ if raceenabled {
+ racereadpc(c.raceaddr(), callerpc, abi.FuncPCABIInternal(chansend))
+ }
+
+ // Fast path: check for failed non-blocking operation without acquiring the lock.
+ //
+ // After observing that the channel is not closed, we observe that the channel is
+ // not ready for sending. Each of these observations is a single word-sized read
+ // (first c.closed and second full()).
+ // Because a closed channel cannot transition from 'ready for sending' to
+ // 'not ready for sending', even if the channel is closed between the two observations,
+ // they imply a moment between the two when the channel was both not yet closed
+ // and not ready for sending. We behave as if we observed the channel at that moment,
+ // and report that the send cannot proceed.
+ //
+ // It is okay if the reads are reordered here: if we observe that the channel is not
+ // ready for sending and then observe that it is not closed, that implies that the
+ // channel wasn't closed during the first observation. However, nothing here
+ // guarantees forward progress. We rely on the side effects of lock release in
+ // chanrecv() and closechan() to update this thread's view of c.closed and full().
+ if !block && c.closed == 0 && full(c) {
+ return false
+ }
+
+ var t0 int64
+ if blockprofilerate > 0 {
+ t0 = cputicks()
+ }
+
+ lock(&c.lock)
+
+ if c.closed != 0 {
+ unlock(&c.lock)
+ panic(plainError("send on closed channel"))
+ }
+
+ if sg := c.recvq.dequeue(); sg != nil {
+ // Found a waiting receiver. We pass the value we want to send
+ // directly to the receiver, bypassing the channel buffer (if any).
+ send(c, sg, ep, func() { unlock(&c.lock) }, 3)
+ return true
+ }
+
+ if c.qcount < c.dataqsiz {
+ // Space is available in the channel buffer. Enqueue the element to send.
+ qp := chanbuf(c, c.sendx)
+ if raceenabled {
+ racenotify(c, c.sendx, nil)
+ }
+ typedmemmove(c.elemtype, qp, ep)
+ c.sendx++
+ if c.sendx == c.dataqsiz {
+ c.sendx = 0
+ }
+ c.qcount++
+ unlock(&c.lock)
+ return true
+ }
+
+ if !block {
+ unlock(&c.lock)
+ return false
+ }
+
+ // Block on the channel. Some receiver will complete our operation for us.
+ gp := getg()
+ mysg := acquireSudog()
+ mysg.releasetime = 0
+ if t0 != 0 {
+ mysg.releasetime = -1
+ }
+ // No stack splits between assigning elem and enqueuing mysg
+ // on gp.waiting where copystack can find it.
+ mysg.elem = ep
+ mysg.waitlink = nil
+ mysg.g = gp
+ mysg.isSelect = false
+ mysg.c = c
+ gp.waiting = mysg
+ gp.param = nil
+ c.sendq.enqueue(mysg)
+ // Signal to anyone trying to shrink our stack that we're about
+ // to park on a channel. The window between when this G's status
+ // changes and when we set gp.activeStackChans is not safe for
+ // stack shrinking.
+ gp.parkingOnChan.Store(true)
+ gopark(chanparkcommit, unsafe.Pointer(&c.lock), waitReasonChanSend, traceBlockChanSend, 2)
+ // Ensure the value being sent is kept alive until the
+ // receiver copies it out. The sudog has a pointer to the
+ // stack object, but sudogs aren't considered as roots of the
+ // stack tracer.
+ KeepAlive(ep)
+
+ // someone woke us up.
+ if mysg != gp.waiting {
+ throw("G waiting list is corrupted")
+ }
+ gp.waiting = nil
+ gp.activeStackChans = false
+ closed := !mysg.success
+ gp.param = nil
+ if mysg.releasetime > 0 {
+ blockevent(mysg.releasetime-t0, 2)
+ }
+ mysg.c = nil
+ releaseSudog(mysg)
+ if closed {
+ if c.closed == 0 {
+ throw("chansend: spurious wakeup")
+ }
+ panic(plainError("send on closed channel"))
+ }
+ return true
+}
+
+// send processes a send operation on an empty channel c.
+// The value ep sent by the sender is copied to the receiver sg.
+// The receiver is then woken up to go on its merry way.
+// Channel c must be empty and locked. send unlocks c with unlockf.
+// sg must already be dequeued from c.
+// ep must be non-nil and point to the heap or the caller's stack.
+func send(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) {
+ if raceenabled {
+ if c.dataqsiz == 0 {
+ racesync(c, sg)
+ } else {
+ // Pretend we go through the buffer, even though
+ // we copy directly. Note that we need to increment
+ // the head/tail locations only when raceenabled.
+ racenotify(c, c.recvx, nil)
+ racenotify(c, c.recvx, sg)
+ c.recvx++
+ if c.recvx == c.dataqsiz {
+ c.recvx = 0
+ }
+ c.sendx = c.recvx // c.sendx = (c.sendx+1) % c.dataqsiz
+ }
+ }
+ if sg.elem != nil {
+ sendDirect(c.elemtype, sg, ep)
+ sg.elem = nil
+ }
+ gp := sg.g
+ unlockf()
+ gp.param = unsafe.Pointer(sg)
+ sg.success = true
+ if sg.releasetime != 0 {
+ sg.releasetime = cputicks()
+ }
+ goready(gp, skip+1)
+}
+
+// Sends and receives on unbuffered or empty-buffered channels are the
+// only operations where one running goroutine writes to the stack of
+// another running goroutine. The GC assumes that stack writes only
+// happen when the goroutine is running and are only done by that
+// goroutine. Using a write barrier is sufficient to make up for
+// violating that assumption, but the write barrier has to work.
+// typedmemmove will call bulkBarrierPreWrite, but the target bytes
+// are not in the heap, so that will not help. We arrange to call
+// memmove and typeBitsBulkBarrier instead.
+
+func sendDirect(t *_type, sg *sudog, src unsafe.Pointer) {
+ // src is on our stack, dst is a slot on another stack.
+
+ // Once we read sg.elem out of sg, it will no longer
+ // be updated if the destination's stack gets copied (shrunk).
+ // So make sure that no preemption points can happen between read & use.
+ dst := sg.elem
+ typeBitsBulkBarrier(t, uintptr(dst), uintptr(src), t.Size_)
+ // No need for cgo write barrier checks because dst is always
+ // Go memory.
+ memmove(dst, src, t.Size_)
+}
+
+func recvDirect(t *_type, sg *sudog, dst unsafe.Pointer) {
+ // dst is on our stack or the heap, src is on another stack.
+ // The channel is locked, so src will not move during this
+ // operation.
+ src := sg.elem
+ typeBitsBulkBarrier(t, uintptr(dst), uintptr(src), t.Size_)
+ memmove(dst, src, t.Size_)
+}
+
+func closechan(c *hchan) {
+ if c == nil {
+ panic(plainError("close of nil channel"))
+ }
+
+ lock(&c.lock)
+ if c.closed != 0 {
+ unlock(&c.lock)
+ panic(plainError("close of closed channel"))
+ }
+
+ if raceenabled {
+ callerpc := getcallerpc()
+ racewritepc(c.raceaddr(), callerpc, abi.FuncPCABIInternal(closechan))
+ racerelease(c.raceaddr())
+ }
+
+ c.closed = 1
+
+ var glist gList
+
+ // release all readers
+ for {
+ sg := c.recvq.dequeue()
+ if sg == nil {
+ break
+ }
+ if sg.elem != nil {
+ typedmemclr(c.elemtype, sg.elem)
+ sg.elem = nil
+ }
+ if sg.releasetime != 0 {
+ sg.releasetime = cputicks()
+ }
+ gp := sg.g
+ gp.param = unsafe.Pointer(sg)
+ sg.success = false
+ if raceenabled {
+ raceacquireg(gp, c.raceaddr())
+ }
+ glist.push(gp)
+ }
+
+ // release all writers (they will panic)
+ for {
+ sg := c.sendq.dequeue()
+ if sg == nil {
+ break
+ }
+ sg.elem = nil
+ if sg.releasetime != 0 {
+ sg.releasetime = cputicks()
+ }
+ gp := sg.g
+ gp.param = unsafe.Pointer(sg)
+ sg.success = false
+ if raceenabled {
+ raceacquireg(gp, c.raceaddr())
+ }
+ glist.push(gp)
+ }
+ unlock(&c.lock)
+
+ // Ready all Gs now that we've dropped the channel lock.
+ for !glist.empty() {
+ gp := glist.pop()
+ gp.schedlink = 0
+ goready(gp, 3)
+ }
+}
+
+// empty reports whether a read from c would block (that is, the channel is
+// empty). It uses a single atomic read of mutable state.
+func empty(c *hchan) bool {
+ // c.dataqsiz is immutable.
+ if c.dataqsiz == 0 {
+ return atomic.Loadp(unsafe.Pointer(&c.sendq.first)) == nil
+ }
+ return atomic.Loaduint(&c.qcount) == 0
+}
+
+// entry points for <- c from compiled code.
+//
+//go:nosplit
+func chanrecv1(c *hchan, elem unsafe.Pointer) {
+ chanrecv(c, elem, true)
+}
+
+//go:nosplit
+func chanrecv2(c *hchan, elem unsafe.Pointer) (received bool) {
+ _, received = chanrecv(c, elem, true)
+ return
+}
+
+// chanrecv receives on channel c and writes the received data to ep.
+// ep may be nil, in which case received data is ignored.
+// If block == false and no elements are available, returns (false, false).
+// Otherwise, if c is closed, zeros *ep and returns (true, false).
+// Otherwise, fills in *ep with an element and returns (true, true).
+// A non-nil ep must point to the heap or the caller's stack.
+func chanrecv(c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) {
+ // raceenabled: don't need to check ep, as it is always on the stack
+ // or is new memory allocated by reflect.
+
+ if debugChan {
+ print("chanrecv: chan=", c, "\n")
+ }
+
+ if c == nil {
+ if !block {
+ return
+ }
+ gopark(nil, nil, waitReasonChanReceiveNilChan, traceBlockForever, 2)
+ throw("unreachable")
+ }
+
+ // Fast path: check for failed non-blocking operation without acquiring the lock.
+ if !block && empty(c) {
+ // After observing that the channel is not ready for receiving, we observe whether the
+ // channel is closed.
+ //
+ // Reordering of these checks could lead to incorrect behavior when racing with a close.
+ // For example, if the channel was open and not empty, was closed, and then drained,
+ // reordered reads could incorrectly indicate "open and empty". To prevent reordering,
+ // we use atomic loads for both checks, and rely on emptying and closing to happen in
+ // separate critical sections under the same lock. This assumption fails when closing
+ // an unbuffered channel with a blocked send, but that is an error condition anyway.
+ if atomic.Load(&c.closed) == 0 {
+ // Because a channel cannot be reopened, the later observation of the channel
+ // being not closed implies that it was also not closed at the moment of the
+ // first observation. We behave as if we observed the channel at that moment
+ // and report that the receive cannot proceed.
+ return
+ }
+ // The channel is irreversibly closed. Re-check whether the channel has any pending data
+ // to receive, which could have arrived between the empty and closed checks above.
+ // Sequential consistency is also required here, when racing with such a send.
+ if empty(c) {
+ // The channel is irreversibly closed and empty.
+ if raceenabled {
+ raceacquire(c.raceaddr())
+ }
+ if ep != nil {
+ typedmemclr(c.elemtype, ep)
+ }
+ return true, false
+ }
+ }
+
+ var t0 int64
+ if blockprofilerate > 0 {
+ t0 = cputicks()
+ }
+
+ lock(&c.lock)
+
+ if c.closed != 0 {
+ if c.qcount == 0 {
+ if raceenabled {
+ raceacquire(c.raceaddr())
+ }
+ unlock(&c.lock)
+ if ep != nil {
+ typedmemclr(c.elemtype, ep)
+ }
+ return true, false
+ }
+ // The channel has been closed, but the channel's buffer have data.
+ } else {
+ // Just found waiting sender with not closed.
+ if sg := c.sendq.dequeue(); sg != nil {
+ // Found a waiting sender. If buffer is size 0, receive value
+ // directly from sender. Otherwise, receive from head of queue
+ // and add sender's value to the tail of the queue (both map to
+ // the same buffer slot because the queue is full).
+ recv(c, sg, ep, func() { unlock(&c.lock) }, 3)
+ return true, true
+ }
+ }
+
+ if c.qcount > 0 {
+ // Receive directly from queue
+ qp := chanbuf(c, c.recvx)
+ if raceenabled {
+ racenotify(c, c.recvx, nil)
+ }
+ if ep != nil {
+ typedmemmove(c.elemtype, ep, qp)
+ }
+ typedmemclr(c.elemtype, qp)
+ c.recvx++
+ if c.recvx == c.dataqsiz {
+ c.recvx = 0
+ }
+ c.qcount--
+ unlock(&c.lock)
+ return true, true
+ }
+
+ if !block {
+ unlock(&c.lock)
+ return false, false
+ }
+
+ // no sender available: block on this channel.
+ gp := getg()
+ mysg := acquireSudog()
+ mysg.releasetime = 0
+ if t0 != 0 {
+ mysg.releasetime = -1
+ }
+ // No stack splits between assigning elem and enqueuing mysg
+ // on gp.waiting where copystack can find it.
+ mysg.elem = ep
+ mysg.waitlink = nil
+ gp.waiting = mysg
+ mysg.g = gp
+ mysg.isSelect = false
+ mysg.c = c
+ gp.param = nil
+ c.recvq.enqueue(mysg)
+ // Signal to anyone trying to shrink our stack that we're about
+ // to park on a channel. The window between when this G's status
+ // changes and when we set gp.activeStackChans is not safe for
+ // stack shrinking.
+ gp.parkingOnChan.Store(true)
+ gopark(chanparkcommit, unsafe.Pointer(&c.lock), waitReasonChanReceive, traceBlockChanRecv, 2)
+
+ // someone woke us up
+ if mysg != gp.waiting {
+ throw("G waiting list is corrupted")
+ }
+ gp.waiting = nil
+ gp.activeStackChans = false
+ if mysg.releasetime > 0 {
+ blockevent(mysg.releasetime-t0, 2)
+ }
+ success := mysg.success
+ gp.param = nil
+ mysg.c = nil
+ releaseSudog(mysg)
+ return true, success
+}
+
+// recv processes a receive operation on a full channel c.
+// There are 2 parts:
+// 1. The value sent by the sender sg is put into the channel
+// and the sender is woken up to go on its merry way.
+// 2. The value received by the receiver (the current G) is
+// written to ep.
+//
+// For synchronous channels, both values are the same.
+// For asynchronous channels, the receiver gets its data from
+// the channel buffer and the sender's data is put in the
+// channel buffer.
+// Channel c must be full and locked. recv unlocks c with unlockf.
+// sg must already be dequeued from c.
+// A non-nil ep must point to the heap or the caller's stack.
+func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func(), skip int) {
+ if c.dataqsiz == 0 {
+ if raceenabled {
+ racesync(c, sg)
+ }
+ if ep != nil {
+ // copy data from sender
+ recvDirect(c.elemtype, sg, ep)
+ }
+ } else {
+ // Queue is full. Take the item at the
+ // head of the queue. Make the sender enqueue
+ // its item at the tail of the queue. Since the
+ // queue is full, those are both the same slot.
+ qp := chanbuf(c, c.recvx)
+ if raceenabled {
+ racenotify(c, c.recvx, nil)
+ racenotify(c, c.recvx, sg)
+ }
+ // copy data from queue to receiver
+ if ep != nil {
+ typedmemmove(c.elemtype, ep, qp)
+ }
+ // copy data from sender to queue
+ typedmemmove(c.elemtype, qp, sg.elem)
+ c.recvx++
+ if c.recvx == c.dataqsiz {
+ c.recvx = 0
+ }
+ c.sendx = c.recvx // c.sendx = (c.sendx+1) % c.dataqsiz
+ }
+ sg.elem = nil
+ gp := sg.g
+ unlockf()
+ gp.param = unsafe.Pointer(sg)
+ sg.success = true
+ if sg.releasetime != 0 {
+ sg.releasetime = cputicks()
+ }
+ goready(gp, skip+1)
+}
+
+func chanparkcommit(gp *g, chanLock unsafe.Pointer) bool {
+ // There are unlocked sudogs that point into gp's stack. Stack
+ // copying must lock the channels of those sudogs.
+ // Set activeStackChans here instead of before we try parking
+ // because we could self-deadlock in stack growth on the
+ // channel lock.
+ gp.activeStackChans = true
+ // Mark that it's safe for stack shrinking to occur now,
+ // because any thread acquiring this G's stack for shrinking
+ // is guaranteed to observe activeStackChans after this store.
+ gp.parkingOnChan.Store(false)
+ // Make sure we unlock after setting activeStackChans and
+ // unsetting parkingOnChan. The moment we unlock chanLock
+ // we risk gp getting readied by a channel operation and
+ // so gp could continue running before everything before
+ // the unlock is visible (even to gp itself).
+ unlock((*mutex)(chanLock))
+ return true
+}
+
+// compiler implements
+//
+// select {
+// case c <- v:
+// ... foo
+// default:
+// ... bar
+// }
+//
+// as
+//
+// if selectnbsend(c, v) {
+// ... foo
+// } else {
+// ... bar
+// }
+func selectnbsend(c *hchan, elem unsafe.Pointer) (selected bool) {
+ return chansend(c, elem, false, getcallerpc())
+}
+
+// compiler implements
+//
+// select {
+// case v, ok = <-c:
+// ... foo
+// default:
+// ... bar
+// }
+//
+// as
+//
+// if selected, ok = selectnbrecv(&v, c); selected {
+// ... foo
+// } else {
+// ... bar
+// }
+func selectnbrecv(elem unsafe.Pointer, c *hchan) (selected, received bool) {
+ return chanrecv(c, elem, false)
+}
+
+//go:linkname reflect_chansend reflect.chansend0
+func reflect_chansend(c *hchan, elem unsafe.Pointer, nb bool) (selected bool) {
+ return chansend(c, elem, !nb, getcallerpc())
+}
+
+//go:linkname reflect_chanrecv reflect.chanrecv
+func reflect_chanrecv(c *hchan, nb bool, elem unsafe.Pointer) (selected bool, received bool) {
+ return chanrecv(c, elem, !nb)
+}
+
+//go:linkname reflect_chanlen reflect.chanlen
+func reflect_chanlen(c *hchan) int {
+ if c == nil {
+ return 0
+ }
+ return int(c.qcount)
+}
+
+//go:linkname reflectlite_chanlen internal/reflectlite.chanlen
+func reflectlite_chanlen(c *hchan) int {
+ if c == nil {
+ return 0
+ }
+ return int(c.qcount)
+}
+
+//go:linkname reflect_chancap reflect.chancap
+func reflect_chancap(c *hchan) int {
+ if c == nil {
+ return 0
+ }
+ return int(c.dataqsiz)
+}
+
+//go:linkname reflect_chanclose reflect.chanclose
+func reflect_chanclose(c *hchan) {
+ closechan(c)
+}
+
+func (q *waitq) enqueue(sgp *sudog) {
+ sgp.next = nil
+ x := q.last
+ if x == nil {
+ sgp.prev = nil
+ q.first = sgp
+ q.last = sgp
+ return
+ }
+ sgp.prev = x
+ x.next = sgp
+ q.last = sgp
+}
+
+func (q *waitq) dequeue() *sudog {
+ for {
+ sgp := q.first
+ if sgp == nil {
+ return nil
+ }
+ y := sgp.next
+ if y == nil {
+ q.first = nil
+ q.last = nil
+ } else {
+ y.prev = nil
+ q.first = y
+ sgp.next = nil // mark as removed (see dequeueSudoG)
+ }
+
+ // if a goroutine was put on this queue because of a
+ // select, there is a small window between the goroutine
+ // being woken up by a different case and it grabbing the
+ // channel locks. Once it has the lock
+ // it removes itself from the queue, so we won't see it after that.
+ // We use a flag in the G struct to tell us when someone
+ // else has won the race to signal this goroutine but the goroutine
+ // hasn't removed itself from the queue yet.
+ if sgp.isSelect && !sgp.g.selectDone.CompareAndSwap(0, 1) {
+ continue
+ }
+
+ return sgp
+ }
+}
+
+func (c *hchan) raceaddr() unsafe.Pointer {
+ // Treat read-like and write-like operations on the channel to
+ // happen at this address. Avoid using the address of qcount
+ // or dataqsiz, because the len() and cap() builtins read
+ // those addresses, and we don't want them racing with
+ // operations like close().
+ return unsafe.Pointer(&c.buf)
+}
+
+func racesync(c *hchan, sg *sudog) {
+ racerelease(chanbuf(c, 0))
+ raceacquireg(sg.g, chanbuf(c, 0))
+ racereleaseg(sg.g, chanbuf(c, 0))
+ raceacquire(chanbuf(c, 0))
+}
+
+// Notify the race detector of a send or receive involving buffer entry idx
+// and a channel c or its communicating partner sg.
+// This function handles the special case of c.elemsize==0.
+func racenotify(c *hchan, idx uint, sg *sudog) {
+ // We could have passed the unsafe.Pointer corresponding to entry idx
+ // instead of idx itself. However, in a future version of this function,
+ // we can use idx to better handle the case of elemsize==0.
+ // A future improvement to the detector is to call TSan with c and idx:
+ // this way, Go will continue to not allocating buffer entries for channels
+ // of elemsize==0, yet the race detector can be made to handle multiple
+ // sync objects underneath the hood (one sync object per idx)
+ qp := chanbuf(c, idx)
+ // When elemsize==0, we don't allocate a full buffer for the channel.
+ // Instead of individual buffer entries, the race detector uses the
+ // c.buf as the only buffer entry. This simplification prevents us from
+ // following the memory model's happens-before rules (rules that are
+ // implemented in racereleaseacquire). Instead, we accumulate happens-before
+ // information in the synchronization object associated with c.buf.
+ if c.elemsize == 0 {
+ if sg == nil {
+ raceacquire(qp)
+ racerelease(qp)
+ } else {
+ raceacquireg(sg.g, qp)
+ racereleaseg(sg.g, qp)
+ }
+ } else {
+ if sg == nil {
+ racereleaseacquire(qp)
+ } else {
+ racereleaseacquireg(sg.g, qp)
+ }
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/checkptr.go b/contrib/go/_std_1.21/src/runtime/checkptr.go
new file mode 100644
index 0000000000..3c49645a44
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/checkptr.go
@@ -0,0 +1,109 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+func checkptrAlignment(p unsafe.Pointer, elem *_type, n uintptr) {
+ // nil pointer is always suitably aligned (#47430).
+ if p == nil {
+ return
+ }
+
+ // Check that (*[n]elem)(p) is appropriately aligned.
+ // Note that we allow unaligned pointers if the types they point to contain
+ // no pointers themselves. See issue 37298.
+ // TODO(mdempsky): What about fieldAlign?
+ if elem.PtrBytes != 0 && uintptr(p)&(uintptr(elem.Align_)-1) != 0 {
+ throw("checkptr: misaligned pointer conversion")
+ }
+
+ // Check that (*[n]elem)(p) doesn't straddle multiple heap objects.
+ // TODO(mdempsky): Fix #46938 so we don't need to worry about overflow here.
+ if checkptrStraddles(p, n*elem.Size_) {
+ throw("checkptr: converted pointer straddles multiple allocations")
+ }
+}
+
+// checkptrStraddles reports whether the first size-bytes of memory
+// addressed by ptr is known to straddle more than one Go allocation.
+func checkptrStraddles(ptr unsafe.Pointer, size uintptr) bool {
+ if size <= 1 {
+ return false
+ }
+
+ // Check that add(ptr, size-1) won't overflow. This avoids the risk
+ // of producing an illegal pointer value (assuming ptr is legal).
+ if uintptr(ptr) >= -(size - 1) {
+ return true
+ }
+ end := add(ptr, size-1)
+
+ // TODO(mdempsky): Detect when [ptr, end] contains Go allocations,
+ // but neither ptr nor end point into one themselves.
+
+ return checkptrBase(ptr) != checkptrBase(end)
+}
+
+func checkptrArithmetic(p unsafe.Pointer, originals []unsafe.Pointer) {
+ if 0 < uintptr(p) && uintptr(p) < minLegalPointer {
+ throw("checkptr: pointer arithmetic computed bad pointer value")
+ }
+
+ // Check that if the computed pointer p points into a heap
+ // object, then one of the original pointers must have pointed
+ // into the same object.
+ base := checkptrBase(p)
+ if base == 0 {
+ return
+ }
+
+ for _, original := range originals {
+ if base == checkptrBase(original) {
+ return
+ }
+ }
+
+ throw("checkptr: pointer arithmetic result points to invalid allocation")
+}
+
+// checkptrBase returns the base address for the allocation containing
+// the address p.
+//
+// Importantly, if p1 and p2 point into the same variable, then
+// checkptrBase(p1) == checkptrBase(p2). However, the converse/inverse
+// is not necessarily true as allocations can have trailing padding,
+// and multiple variables may be packed into a single allocation.
+func checkptrBase(p unsafe.Pointer) uintptr {
+ // stack
+ if gp := getg(); gp.stack.lo <= uintptr(p) && uintptr(p) < gp.stack.hi {
+ // TODO(mdempsky): Walk the stack to identify the
+ // specific stack frame or even stack object that p
+ // points into.
+ //
+ // In the mean time, use "1" as a pseudo-address to
+ // represent the stack. This is an invalid address on
+ // all platforms, so it's guaranteed to be distinct
+ // from any of the addresses we might return below.
+ return 1
+ }
+
+ // heap (must check after stack because of #35068)
+ if base, _, _ := findObject(uintptr(p), 0, 0); base != 0 {
+ return base
+ }
+
+ // data or bss
+ for _, datap := range activeModules() {
+ if datap.data <= uintptr(p) && uintptr(p) < datap.edata {
+ return datap.data
+ }
+ if datap.bss <= uintptr(p) && uintptr(p) < datap.ebss {
+ return datap.bss
+ }
+ }
+
+ return 0
+}
diff --git a/contrib/go/_std_1.20/src/runtime/compiler.go b/contrib/go/_std_1.21/src/runtime/compiler.go
index f430a27719..f430a27719 100644
--- a/contrib/go/_std_1.20/src/runtime/compiler.go
+++ b/contrib/go/_std_1.21/src/runtime/compiler.go
diff --git a/contrib/go/_std_1.20/src/runtime/complex.go b/contrib/go/_std_1.21/src/runtime/complex.go
index 07c596fc0b..07c596fc0b 100644
--- a/contrib/go/_std_1.20/src/runtime/complex.go
+++ b/contrib/go/_std_1.21/src/runtime/complex.go
diff --git a/contrib/go/_std_1.21/src/runtime/coverage/apis.go b/contrib/go/_std_1.21/src/runtime/coverage/apis.go
new file mode 100644
index 0000000000..05da345ede
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/coverage/apis.go
@@ -0,0 +1,184 @@
+// Copyright 2022 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 coverage
+
+import (
+ "fmt"
+ "internal/coverage"
+ "io"
+ "reflect"
+ "sync/atomic"
+ "unsafe"
+)
+
+// WriteMetaDir writes a coverage meta-data file for the currently
+// running program to the directory specified in 'dir'. An error will
+// be returned if the operation can't be completed successfully (for
+// example, if the currently running program was not built with
+// "-cover", or if the directory does not exist).
+func WriteMetaDir(dir string) error {
+ if !finalHashComputed {
+ return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
+ }
+ return emitMetaDataToDirectory(dir, getCovMetaList())
+}
+
+// WriteMeta writes the meta-data content (the payload that would
+// normally be emitted to a meta-data file) for the currently running
+// program to the writer 'w'. An error will be returned if the
+// operation can't be completed successfully (for example, if the
+// currently running program was not built with "-cover", or if a
+// write fails).
+func WriteMeta(w io.Writer) error {
+ if w == nil {
+ return fmt.Errorf("error: nil writer in WriteMeta")
+ }
+ if !finalHashComputed {
+ return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
+ }
+ ml := getCovMetaList()
+ return writeMetaData(w, ml, cmode, cgran, finalHash)
+}
+
+// WriteCountersDir writes a coverage counter-data file for the
+// currently running program to the directory specified in 'dir'. An
+// error will be returned if the operation can't be completed
+// successfully (for example, if the currently running program was not
+// built with "-cover", or if the directory does not exist). The
+// counter data written will be a snapshot taken at the point of the
+// call.
+func WriteCountersDir(dir string) error {
+ if cmode != coverage.CtrModeAtomic {
+ return fmt.Errorf("WriteCountersDir invoked for program built with -covermode=%s (please use -covermode=atomic)", cmode.String())
+ }
+ return emitCounterDataToDirectory(dir)
+}
+
+// WriteCounters writes coverage counter-data content for the
+// currently running program to the writer 'w'. An error will be
+// returned if the operation can't be completed successfully (for
+// example, if the currently running program was not built with
+// "-cover", or if a write fails). The counter data written will be a
+// snapshot taken at the point of the invocation.
+func WriteCounters(w io.Writer) error {
+ if w == nil {
+ return fmt.Errorf("error: nil writer in WriteCounters")
+ }
+ if cmode != coverage.CtrModeAtomic {
+ return fmt.Errorf("WriteCounters invoked for program built with -covermode=%s (please use -covermode=atomic)", cmode.String())
+ }
+ // Ask the runtime for the list of coverage counter symbols.
+ cl := getCovCounterList()
+ if len(cl) == 0 {
+ return fmt.Errorf("program not built with -cover")
+ }
+ if !finalHashComputed {
+ return fmt.Errorf("meta-data not written yet, unable to write counter data")
+ }
+
+ pm := getCovPkgMap()
+ s := &emitState{
+ counterlist: cl,
+ pkgmap: pm,
+ }
+ return s.emitCounterDataToWriter(w)
+}
+
+// ClearCounters clears/resets all coverage counter variables in the
+// currently running program. It returns an error if the program in
+// question was not built with the "-cover" flag. Clearing of coverage
+// counters is also not supported for programs not using atomic
+// counter mode (see more detailed comments below for the rationale
+// here).
+func ClearCounters() error {
+ cl := getCovCounterList()
+ if len(cl) == 0 {
+ return fmt.Errorf("program not built with -cover")
+ }
+ if cmode != coverage.CtrModeAtomic {
+ return fmt.Errorf("ClearCounters invoked for program built with -covermode=%s (please use -covermode=atomic)", cmode.String())
+ }
+
+ // Implementation note: this function would be faster and simpler
+ // if we could just zero out the entire counter array, but for the
+ // moment we go through and zero out just the slots in the array
+ // corresponding to the counter values. We do this to avoid the
+ // following bad scenario: suppose that a user builds their Go
+ // program with "-cover", and that program has a function (call it
+ // main.XYZ) that invokes ClearCounters:
+ //
+ // func XYZ() {
+ // ... do some stuff ...
+ // coverage.ClearCounters()
+ // if someCondition { <<--- HERE
+ // ...
+ // }
+ // }
+ //
+ // At the point where ClearCounters executes, main.XYZ has not yet
+ // finished running, thus as soon as the call returns the line
+ // marked "HERE" above will trigger the writing of a non-zero
+ // value into main.XYZ's counter slab. However since we've just
+ // finished clearing the entire counter segment, we will have lost
+ // the values in the prolog portion of main.XYZ's counter slab
+ // (nctrs, pkgid, funcid). This means that later on at the end of
+ // program execution as we walk through the entire counter array
+ // for the program looking for executed functions, we'll zoom past
+ // main.XYZ's prolog (which was zero'd) and hit the non-zero
+ // counter value corresponding to the "HERE" block, which will
+ // then be interpreted as the start of another live function.
+ // Things will go downhill from there.
+ //
+ // This same scenario is also a potential risk if the program is
+ // running on an architecture that permits reordering of
+ // writes/stores, since the inconsistency described above could
+ // arise here. Example scenario:
+ //
+ // func ABC() {
+ // ... // prolog
+ // if alwaysTrue() {
+ // XYZ() // counter update here
+ // }
+ // }
+ //
+ // In the instrumented version of ABC, the prolog of the function
+ // will contain a series of stores to the initial portion of the
+ // counter array to write number-of-counters, pkgid, funcid. Later
+ // in the function there is also a store to increment a counter
+ // for the block containing the call to XYZ(). If the CPU is
+ // allowed to reorder stores and decides to issue the XYZ store
+ // before the prolog stores, this could be observable as an
+ // inconsistency similar to the one above. Hence the requirement
+ // for atomic counter mode: according to package atomic docs,
+ // "...operations that happen in a specific order on one thread,
+ // will always be observed to happen in exactly that order by
+ // another thread". Thus we can be sure that there will be no
+ // inconsistency when reading the counter array from the thread
+ // running ClearCounters.
+
+ var sd []atomic.Uint32
+
+ bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&sd))
+ for _, c := range cl {
+ bufHdr.Data = uintptr(unsafe.Pointer(c.Counters))
+ bufHdr.Len = int(c.Len)
+ bufHdr.Cap = int(c.Len)
+ for i := 0; i < len(sd); i++ {
+ // Skip ahead until the next non-zero value.
+ sdi := sd[i].Load()
+ if sdi == 0 {
+ continue
+ }
+ // We found a function that was executed; clear its counters.
+ nCtrs := sdi
+ for j := 0; j < int(nCtrs); j++ {
+ sd[i+coverage.FirstCtrOffset+j].Store(0)
+ }
+ // Move to next function.
+ i += coverage.FirstCtrOffset + int(nCtrs) - 1
+ }
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.20/src/runtime/coverage/dummy.s b/contrib/go/_std_1.21/src/runtime/coverage/dummy.s
index 75928593a0..75928593a0 100644
--- a/contrib/go/_std_1.20/src/runtime/coverage/dummy.s
+++ b/contrib/go/_std_1.21/src/runtime/coverage/dummy.s
diff --git a/contrib/go/_std_1.21/src/runtime/coverage/emit.go b/contrib/go/_std_1.21/src/runtime/coverage/emit.go
new file mode 100644
index 0000000000..bb0c6fb6a2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/coverage/emit.go
@@ -0,0 +1,622 @@
+// Copyright 2022 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 coverage
+
+import (
+ "crypto/md5"
+ "fmt"
+ "internal/coverage"
+ "internal/coverage/encodecounter"
+ "internal/coverage/encodemeta"
+ "internal/coverage/rtcov"
+ "io"
+ "os"
+ "path/filepath"
+ "reflect"
+ "runtime"
+ "strconv"
+ "sync/atomic"
+ "time"
+ "unsafe"
+)
+
+// This file contains functions that support the writing of data files
+// emitted at the end of code coverage testing runs, from instrumented
+// executables.
+
+// getCovMetaList returns a list of meta-data blobs registered
+// for the currently executing instrumented program. It is defined in the
+// runtime.
+func getCovMetaList() []rtcov.CovMetaBlob
+
+// getCovCounterList returns a list of counter-data blobs registered
+// for the currently executing instrumented program. It is defined in the
+// runtime.
+func getCovCounterList() []rtcov.CovCounterBlob
+
+// getCovPkgMap returns a map storing the remapped package IDs for
+// hard-coded runtime packages (see internal/coverage/pkgid.go for
+// more on why hard-coded package IDs are needed). This function
+// is defined in the runtime.
+func getCovPkgMap() map[int]int
+
+// emitState holds useful state information during the emit process.
+//
+// When an instrumented program finishes execution and starts the
+// process of writing out coverage data, it's possible that an
+// existing meta-data file already exists in the output directory. In
+// this case openOutputFiles() below will leave the 'mf' field below
+// as nil. If a new meta-data file is needed, field 'mfname' will be
+// the final desired path of the meta file, 'mftmp' will be a
+// temporary file, and 'mf' will be an open os.File pointer for
+// 'mftmp'. The meta-data file payload will be written to 'mf', the
+// temp file will be then closed and renamed (from 'mftmp' to
+// 'mfname'), so as to insure that the meta-data file is created
+// atomically; we want this so that things work smoothly in cases
+// where there are several instances of a given instrumented program
+// all terminating at the same time and trying to create meta-data
+// files simultaneously.
+//
+// For counter data files there is less chance of a collision, hence
+// the openOutputFiles() stores the counter data file in 'cfname' and
+// then places the *io.File into 'cf'.
+type emitState struct {
+ mfname string // path of final meta-data output file
+ mftmp string // path to meta-data temp file (if needed)
+ mf *os.File // open os.File for meta-data temp file
+ cfname string // path of final counter data file
+ cftmp string // path to counter data temp file
+ cf *os.File // open os.File for counter data file
+ outdir string // output directory
+
+ // List of meta-data symbols obtained from the runtime
+ metalist []rtcov.CovMetaBlob
+
+ // List of counter-data symbols obtained from the runtime
+ counterlist []rtcov.CovCounterBlob
+
+ // Table to use for remapping hard-coded pkg ids.
+ pkgmap map[int]int
+
+ // emit debug trace output
+ debug bool
+}
+
+var (
+ // finalHash is computed at init time from the list of meta-data
+ // symbols registered during init. It is used both for writing the
+ // meta-data file and counter-data files.
+ finalHash [16]byte
+ // Set to true when we've computed finalHash + finalMetaLen.
+ finalHashComputed bool
+ // Total meta-data length.
+ finalMetaLen uint64
+ // Records whether we've already attempted to write meta-data.
+ metaDataEmitAttempted bool
+ // Counter mode for this instrumented program run.
+ cmode coverage.CounterMode
+ // Counter granularity for this instrumented program run.
+ cgran coverage.CounterGranularity
+ // Cached value of GOCOVERDIR environment variable.
+ goCoverDir string
+ // Copy of os.Args made at init time, converted into map format.
+ capturedOsArgs map[string]string
+ // Flag used in tests to signal that coverage data already written.
+ covProfileAlreadyEmitted bool
+)
+
+// fileType is used to select between counter-data files and
+// meta-data files.
+type fileType int
+
+const (
+ noFile = 1 << iota
+ metaDataFile
+ counterDataFile
+)
+
+// emitMetaData emits the meta-data output file for this coverage run.
+// This entry point is intended to be invoked by the compiler from
+// an instrumented program's main package init func.
+func emitMetaData() {
+ if covProfileAlreadyEmitted {
+ return
+ }
+ ml, err := prepareForMetaEmit()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error: coverage meta-data prep failed: %v\n", err)
+ if os.Getenv("GOCOVERDEBUG") != "" {
+ panic("meta-data write failure")
+ }
+ }
+ if len(ml) == 0 {
+ fmt.Fprintf(os.Stderr, "program not built with -cover\n")
+ return
+ }
+
+ goCoverDir = os.Getenv("GOCOVERDIR")
+ if goCoverDir == "" {
+ fmt.Fprintf(os.Stderr, "warning: GOCOVERDIR not set, no coverage data emitted\n")
+ return
+ }
+
+ if err := emitMetaDataToDirectory(goCoverDir, ml); err != nil {
+ fmt.Fprintf(os.Stderr, "error: coverage meta-data emit failed: %v\n", err)
+ if os.Getenv("GOCOVERDEBUG") != "" {
+ panic("meta-data write failure")
+ }
+ }
+}
+
+func modeClash(m coverage.CounterMode) bool {
+ if m == coverage.CtrModeRegOnly || m == coverage.CtrModeTestMain {
+ return false
+ }
+ if cmode == coverage.CtrModeInvalid {
+ cmode = m
+ return false
+ }
+ return cmode != m
+}
+
+func granClash(g coverage.CounterGranularity) bool {
+ if cgran == coverage.CtrGranularityInvalid {
+ cgran = g
+ return false
+ }
+ return cgran != g
+}
+
+// prepareForMetaEmit performs preparatory steps needed prior to
+// emitting a meta-data file, notably computing a final hash of
+// all meta-data blobs and capturing os args.
+func prepareForMetaEmit() ([]rtcov.CovMetaBlob, error) {
+ // Ask the runtime for the list of coverage meta-data symbols.
+ ml := getCovMetaList()
+
+ // In the normal case (go build -o prog.exe ... ; ./prog.exe)
+ // len(ml) will always be non-zero, but we check here since at
+ // some point this function will be reachable via user-callable
+ // APIs (for example, to write out coverage data from a server
+ // program that doesn't ever call os.Exit).
+ if len(ml) == 0 {
+ return nil, nil
+ }
+
+ s := &emitState{
+ metalist: ml,
+ debug: os.Getenv("GOCOVERDEBUG") != "",
+ }
+
+ // Capture os.Args() now so as to avoid issues if args
+ // are rewritten during program execution.
+ capturedOsArgs = captureOsArgs()
+
+ if s.debug {
+ fmt.Fprintf(os.Stderr, "=+= GOCOVERDIR is %s\n", os.Getenv("GOCOVERDIR"))
+ fmt.Fprintf(os.Stderr, "=+= contents of covmetalist:\n")
+ for k, b := range ml {
+ fmt.Fprintf(os.Stderr, "=+= slot: %d path: %s ", k, b.PkgPath)
+ if b.PkgID != -1 {
+ fmt.Fprintf(os.Stderr, " hcid: %d", b.PkgID)
+ }
+ fmt.Fprintf(os.Stderr, "\n")
+ }
+ pm := getCovPkgMap()
+ fmt.Fprintf(os.Stderr, "=+= remap table:\n")
+ for from, to := range pm {
+ fmt.Fprintf(os.Stderr, "=+= from %d to %d\n",
+ uint32(from), uint32(to))
+ }
+ }
+
+ h := md5.New()
+ tlen := uint64(unsafe.Sizeof(coverage.MetaFileHeader{}))
+ for _, entry := range ml {
+ if _, err := h.Write(entry.Hash[:]); err != nil {
+ return nil, err
+ }
+ tlen += uint64(entry.Len)
+ ecm := coverage.CounterMode(entry.CounterMode)
+ if modeClash(ecm) {
+ return nil, fmt.Errorf("coverage counter mode clash: package %s uses mode=%d, but package %s uses mode=%s\n", ml[0].PkgPath, cmode, entry.PkgPath, ecm)
+ }
+ ecg := coverage.CounterGranularity(entry.CounterGranularity)
+ if granClash(ecg) {
+ return nil, fmt.Errorf("coverage counter granularity clash: package %s uses gran=%d, but package %s uses gran=%s\n", ml[0].PkgPath, cgran, entry.PkgPath, ecg)
+ }
+ }
+
+ // Hash mode and granularity as well.
+ h.Write([]byte(cmode.String()))
+ h.Write([]byte(cgran.String()))
+
+ // Compute final digest.
+ fh := h.Sum(nil)
+ copy(finalHash[:], fh)
+ finalHashComputed = true
+ finalMetaLen = tlen
+
+ return ml, nil
+}
+
+// emitMetaDataToDirectory emits the meta-data output file to the specified
+// directory, returning an error if something went wrong.
+func emitMetaDataToDirectory(outdir string, ml []rtcov.CovMetaBlob) error {
+ ml, err := prepareForMetaEmit()
+ if err != nil {
+ return err
+ }
+ if len(ml) == 0 {
+ return nil
+ }
+
+ metaDataEmitAttempted = true
+
+ s := &emitState{
+ metalist: ml,
+ debug: os.Getenv("GOCOVERDEBUG") != "",
+ outdir: outdir,
+ }
+
+ // Open output files.
+ if err := s.openOutputFiles(finalHash, finalMetaLen, metaDataFile); err != nil {
+ return err
+ }
+
+ // Emit meta-data file only if needed (may already be present).
+ if s.needMetaDataFile() {
+ if err := s.emitMetaDataFile(finalHash, finalMetaLen); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// emitCounterData emits the counter data output file for this coverage run.
+// This entry point is intended to be invoked by the runtime when an
+// instrumented program is terminating or calling os.Exit().
+func emitCounterData() {
+ if goCoverDir == "" || !finalHashComputed || covProfileAlreadyEmitted {
+ return
+ }
+ if err := emitCounterDataToDirectory(goCoverDir); err != nil {
+ fmt.Fprintf(os.Stderr, "error: coverage counter data emit failed: %v\n", err)
+ if os.Getenv("GOCOVERDEBUG") != "" {
+ panic("counter-data write failure")
+ }
+ }
+}
+
+// emitCounterDataToDirectory emits the counter-data output file for this coverage run.
+func emitCounterDataToDirectory(outdir string) error {
+ // Ask the runtime for the list of coverage counter symbols.
+ cl := getCovCounterList()
+ if len(cl) == 0 {
+ // no work to do here.
+ return nil
+ }
+
+ if !finalHashComputed {
+ return fmt.Errorf("error: meta-data not available (binary not built with -cover?)")
+ }
+
+ // Ask the runtime for the list of coverage counter symbols.
+ pm := getCovPkgMap()
+ s := &emitState{
+ counterlist: cl,
+ pkgmap: pm,
+ outdir: outdir,
+ debug: os.Getenv("GOCOVERDEBUG") != "",
+ }
+
+ // Open output file.
+ if err := s.openOutputFiles(finalHash, finalMetaLen, counterDataFile); err != nil {
+ return err
+ }
+ if s.cf == nil {
+ return fmt.Errorf("counter data output file open failed (no additional info")
+ }
+
+ // Emit counter data file.
+ if err := s.emitCounterDataFile(finalHash, s.cf); err != nil {
+ return err
+ }
+ if err := s.cf.Close(); err != nil {
+ return fmt.Errorf("closing counter data file: %v", err)
+ }
+
+ // Counter file has now been closed. Rename the temp to the
+ // final desired path.
+ if err := os.Rename(s.cftmp, s.cfname); err != nil {
+ return fmt.Errorf("writing %s: rename from %s failed: %v\n", s.cfname, s.cftmp, err)
+ }
+
+ return nil
+}
+
+// emitCounterDataToWriter emits counter data for this coverage run to an io.Writer.
+func (s *emitState) emitCounterDataToWriter(w io.Writer) error {
+ if err := s.emitCounterDataFile(finalHash, w); err != nil {
+ return err
+ }
+ return nil
+}
+
+// openMetaFile determines whether we need to emit a meta-data output
+// file, or whether we can reuse the existing file in the coverage out
+// dir. It updates mfname/mftmp/mf fields in 's', returning an error
+// if something went wrong. See the comment on the emitState type
+// definition above for more on how file opening is managed.
+func (s *emitState) openMetaFile(metaHash [16]byte, metaLen uint64) error {
+
+ // Open meta-outfile for reading to see if it exists.
+ fn := fmt.Sprintf("%s.%x", coverage.MetaFilePref, metaHash)
+ s.mfname = filepath.Join(s.outdir, fn)
+ fi, err := os.Stat(s.mfname)
+ if err != nil || fi.Size() != int64(metaLen) {
+ // We need a new meta-file.
+ tname := "tmp." + fn + strconv.FormatInt(time.Now().UnixNano(), 10)
+ s.mftmp = filepath.Join(s.outdir, tname)
+ s.mf, err = os.Create(s.mftmp)
+ if err != nil {
+ return fmt.Errorf("creating meta-data file %s: %v", s.mftmp, err)
+ }
+ }
+ return nil
+}
+
+// openCounterFile opens an output file for the counter data portion
+// of a test coverage run. If updates the 'cfname' and 'cf' fields in
+// 's', returning an error if something went wrong.
+func (s *emitState) openCounterFile(metaHash [16]byte) error {
+ processID := os.Getpid()
+ fn := fmt.Sprintf(coverage.CounterFileTempl, coverage.CounterFilePref, metaHash, processID, time.Now().UnixNano())
+ s.cfname = filepath.Join(s.outdir, fn)
+ s.cftmp = filepath.Join(s.outdir, "tmp."+fn)
+ var err error
+ s.cf, err = os.Create(s.cftmp)
+ if err != nil {
+ return fmt.Errorf("creating counter data file %s: %v", s.cftmp, err)
+ }
+ return nil
+}
+
+// openOutputFiles opens output files in preparation for emitting
+// coverage data. In the case of the meta-data file, openOutputFiles
+// may determine that we can reuse an existing meta-data file in the
+// outdir, in which case it will leave the 'mf' field in the state
+// struct as nil. If a new meta-file is needed, the field 'mfname'
+// will be the final desired path of the meta file, 'mftmp' will be a
+// temporary file, and 'mf' will be an open os.File pointer for
+// 'mftmp'. The idea is that the client/caller will write content into
+// 'mf', close it, and then rename 'mftmp' to 'mfname'. This function
+// also opens the counter data output file, setting 'cf' and 'cfname'
+// in the state struct.
+func (s *emitState) openOutputFiles(metaHash [16]byte, metaLen uint64, which fileType) error {
+ fi, err := os.Stat(s.outdir)
+ if err != nil {
+ return fmt.Errorf("output directory %q inaccessible (err: %v); no coverage data written", s.outdir, err)
+ }
+ if !fi.IsDir() {
+ return fmt.Errorf("output directory %q not a directory; no coverage data written", s.outdir)
+ }
+
+ if (which & metaDataFile) != 0 {
+ if err := s.openMetaFile(metaHash, metaLen); err != nil {
+ return err
+ }
+ }
+ if (which & counterDataFile) != 0 {
+ if err := s.openCounterFile(metaHash); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// emitMetaDataFile emits coverage meta-data to a previously opened
+// temporary file (s.mftmp), then renames the generated file to the
+// final path (s.mfname).
+func (s *emitState) emitMetaDataFile(finalHash [16]byte, tlen uint64) error {
+ if err := writeMetaData(s.mf, s.metalist, cmode, cgran, finalHash); err != nil {
+ return fmt.Errorf("writing %s: %v\n", s.mftmp, err)
+ }
+ if err := s.mf.Close(); err != nil {
+ return fmt.Errorf("closing meta data temp file: %v", err)
+ }
+
+ // Temp file has now been flushed and closed. Rename the temp to the
+ // final desired path.
+ if err := os.Rename(s.mftmp, s.mfname); err != nil {
+ return fmt.Errorf("writing %s: rename from %s failed: %v\n", s.mfname, s.mftmp, err)
+ }
+
+ return nil
+}
+
+// needMetaDataFile returns TRUE if we need to emit a meta-data file
+// for this program run. It should be used only after
+// openOutputFiles() has been invoked.
+func (s *emitState) needMetaDataFile() bool {
+ return s.mf != nil
+}
+
+func writeMetaData(w io.Writer, metalist []rtcov.CovMetaBlob, cmode coverage.CounterMode, gran coverage.CounterGranularity, finalHash [16]byte) error {
+ mfw := encodemeta.NewCoverageMetaFileWriter("<io.Writer>", w)
+
+ // Note: "sd" is re-initialized on each iteration of the loop
+ // below, and would normally be declared inside the loop, but
+ // placed here escape analysis since we capture it in bufHdr.
+ var sd []byte
+ bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&sd))
+
+ var blobs [][]byte
+ for _, e := range metalist {
+ bufHdr.Data = uintptr(unsafe.Pointer(e.P))
+ bufHdr.Len = int(e.Len)
+ bufHdr.Cap = int(e.Len)
+ blobs = append(blobs, sd)
+ }
+ return mfw.Write(finalHash, blobs, cmode, gran)
+}
+
+func (s *emitState) VisitFuncs(f encodecounter.CounterVisitorFn) error {
+ var sd []atomic.Uint32
+ var tcounters []uint32
+ bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&sd))
+
+ rdCounters := func(actrs []atomic.Uint32, ctrs []uint32) []uint32 {
+ ctrs = ctrs[:0]
+ for i := range actrs {
+ ctrs = append(ctrs, actrs[i].Load())
+ }
+ return ctrs
+ }
+
+ dpkg := uint32(0)
+ for _, c := range s.counterlist {
+ bufHdr.Data = uintptr(unsafe.Pointer(c.Counters))
+ bufHdr.Len = int(c.Len)
+ bufHdr.Cap = int(c.Len)
+ for i := 0; i < len(sd); i++ {
+ // Skip ahead until the next non-zero value.
+ sdi := sd[i].Load()
+ if sdi == 0 {
+ continue
+ }
+
+ // We found a function that was executed.
+ nCtrs := sd[i+coverage.NumCtrsOffset].Load()
+ pkgId := sd[i+coverage.PkgIdOffset].Load()
+ funcId := sd[i+coverage.FuncIdOffset].Load()
+ cst := i + coverage.FirstCtrOffset
+ counters := sd[cst : cst+int(nCtrs)]
+
+ // Check to make sure that we have at least one live
+ // counter. See the implementation note in ClearCoverageCounters
+ // for a description of why this is needed.
+ isLive := false
+ for i := 0; i < len(counters); i++ {
+ if counters[i].Load() != 0 {
+ isLive = true
+ break
+ }
+ }
+ if !isLive {
+ // Skip this function.
+ i += coverage.FirstCtrOffset + int(nCtrs) - 1
+ continue
+ }
+
+ if s.debug {
+ if pkgId != dpkg {
+ dpkg = pkgId
+ fmt.Fprintf(os.Stderr, "\n=+= %d: pk=%d visit live fcn",
+ i, pkgId)
+ }
+ fmt.Fprintf(os.Stderr, " {i=%d F%d NC%d}", i, funcId, nCtrs)
+ }
+
+ // Vet and/or fix up package ID. A package ID of zero
+ // indicates that there is some new package X that is a
+ // runtime dependency, and this package has code that
+ // executes before its corresponding init package runs.
+ // This is a fatal error that we should only see during
+ // Go development (e.g. tip).
+ ipk := int32(pkgId)
+ if ipk == 0 {
+ fmt.Fprintf(os.Stderr, "\n")
+ reportErrorInHardcodedList(int32(i), ipk, funcId, nCtrs)
+ } else if ipk < 0 {
+ if newId, ok := s.pkgmap[int(ipk)]; ok {
+ pkgId = uint32(newId)
+ } else {
+ fmt.Fprintf(os.Stderr, "\n")
+ reportErrorInHardcodedList(int32(i), ipk, funcId, nCtrs)
+ }
+ } else {
+ // The package ID value stored in the counter array
+ // has 1 added to it (so as to preclude the
+ // possibility of a zero value ; see
+ // runtime.addCovMeta), so subtract off 1 here to form
+ // the real package ID.
+ pkgId--
+ }
+
+ tcounters = rdCounters(counters, tcounters)
+ if err := f(pkgId, funcId, tcounters); err != nil {
+ return err
+ }
+
+ // Skip over this function.
+ i += coverage.FirstCtrOffset + int(nCtrs) - 1
+ }
+ if s.debug {
+ fmt.Fprintf(os.Stderr, "\n")
+ }
+ }
+ return nil
+}
+
+// captureOsArgs converts os.Args() into the format we use to store
+// this info in the counter data file (counter data file "args"
+// section is a generic key-value collection). See the 'args' section
+// in internal/coverage/defs.go for more info. The args map
+// is also used to capture GOOS + GOARCH values as well.
+func captureOsArgs() map[string]string {
+ m := make(map[string]string)
+ m["argc"] = strconv.Itoa(len(os.Args))
+ for k, a := range os.Args {
+ m[fmt.Sprintf("argv%d", k)] = a
+ }
+ m["GOOS"] = runtime.GOOS
+ m["GOARCH"] = runtime.GOARCH
+ return m
+}
+
+// emitCounterDataFile emits the counter data portion of a
+// coverage output file (to the file 's.cf').
+func (s *emitState) emitCounterDataFile(finalHash [16]byte, w io.Writer) error {
+ cfw := encodecounter.NewCoverageDataWriter(w, coverage.CtrULeb128)
+ if err := cfw.Write(finalHash, capturedOsArgs, s); err != nil {
+ return err
+ }
+ return nil
+}
+
+// markProfileEmitted signals the runtime/coverage machinery that
+// coverate data output files have already been written out, and there
+// is no need to take any additional action at exit time. This
+// function is called (via linknamed reference) from the
+// coverage-related boilerplate code in _testmain.go emitted for go
+// unit tests.
+func markProfileEmitted(val bool) {
+ covProfileAlreadyEmitted = val
+}
+
+func reportErrorInHardcodedList(slot, pkgID int32, fnID, nCtrs uint32) {
+ metaList := getCovMetaList()
+ pkgMap := getCovPkgMap()
+
+ println("internal error in coverage meta-data tracking:")
+ println("encountered bad pkgID:", pkgID, " at slot:", slot,
+ " fnID:", fnID, " numCtrs:", nCtrs)
+ println("list of hard-coded runtime package IDs needs revising.")
+ println("[see the comment on the 'rtPkgs' var in ")
+ println(" <goroot>/src/internal/coverage/pkid.go]")
+ println("registered list:")
+ for k, b := range metaList {
+ print("slot: ", k, " path='", b.PkgPath, "' ")
+ if b.PkgID != -1 {
+ print(" hard-coded id: ", b.PkgID)
+ }
+ println("")
+ }
+ println("remap table:")
+ for from, to := range pkgMap {
+ println("from ", from, " to ", to)
+ }
+}
diff --git a/contrib/go/_std_1.20/src/runtime/coverage/hooks.go b/contrib/go/_std_1.21/src/runtime/coverage/hooks.go
index a9fbf9d7dd..a9fbf9d7dd 100644
--- a/contrib/go/_std_1.20/src/runtime/coverage/hooks.go
+++ b/contrib/go/_std_1.21/src/runtime/coverage/hooks.go
diff --git a/contrib/go/_std_1.21/src/runtime/coverage/testsupport.go b/contrib/go/_std_1.21/src/runtime/coverage/testsupport.go
new file mode 100644
index 0000000000..f169580618
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/coverage/testsupport.go
@@ -0,0 +1,323 @@
+// Copyright 2022 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 coverage
+
+import (
+ "encoding/json"
+ "fmt"
+ "internal/coverage"
+ "internal/coverage/calloc"
+ "internal/coverage/cformat"
+ "internal/coverage/cmerge"
+ "internal/coverage/decodecounter"
+ "internal/coverage/decodemeta"
+ "internal/coverage/pods"
+ "io"
+ "os"
+ "path/filepath"
+ "runtime/internal/atomic"
+ "strings"
+ "unsafe"
+)
+
+// processCoverTestDir is called (via a linknamed reference) from
+// testmain code when "go test -cover" is in effect. It is not
+// intended to be used other than internally by the Go command's
+// generated code.
+func processCoverTestDir(dir string, cfile string, cm string, cpkg string) error {
+ return processCoverTestDirInternal(dir, cfile, cm, cpkg, os.Stdout)
+}
+
+// processCoverTestDirInternal is an io.Writer version of processCoverTestDir,
+// exposed for unit testing.
+func processCoverTestDirInternal(dir string, cfile string, cm string, cpkg string, w io.Writer) error {
+ cmode := coverage.ParseCounterMode(cm)
+ if cmode == coverage.CtrModeInvalid {
+ return fmt.Errorf("invalid counter mode %q", cm)
+ }
+
+ // Emit meta-data and counter data.
+ ml := getCovMetaList()
+ if len(ml) == 0 {
+ // This corresponds to the case where we have a package that
+ // contains test code but no functions (which is fine). In this
+ // case there is no need to emit anything.
+ } else {
+ if err := emitMetaDataToDirectory(dir, ml); err != nil {
+ return err
+ }
+ if err := emitCounterDataToDirectory(dir); err != nil {
+ return err
+ }
+ }
+
+ // Collect pods from test run. For the majority of cases we would
+ // expect to see a single pod here, but allow for multiple pods in
+ // case the test harness is doing extra work to collect data files
+ // from builds that it kicks off as part of the testing.
+ podlist, err := pods.CollectPods([]string{dir}, false)
+ if err != nil {
+ return fmt.Errorf("reading from %s: %v", dir, err)
+ }
+
+ // Open text output file if appropriate.
+ var tf *os.File
+ var tfClosed bool
+ if cfile != "" {
+ var err error
+ tf, err = os.Create(cfile)
+ if err != nil {
+ return fmt.Errorf("internal error: opening coverage data output file %q: %v", cfile, err)
+ }
+ defer func() {
+ if !tfClosed {
+ tfClosed = true
+ tf.Close()
+ }
+ }()
+ }
+
+ // Read/process the pods.
+ ts := &tstate{
+ cm: &cmerge.Merger{},
+ cf: cformat.NewFormatter(cmode),
+ cmode: cmode,
+ }
+ // Generate the expected hash string based on the final meta-data
+ // hash for this test, then look only for pods that refer to that
+ // hash (just in case there are multiple instrumented executables
+ // in play). See issue #57924 for more on this.
+ hashstring := fmt.Sprintf("%x", finalHash)
+ importpaths := make(map[string]struct{})
+ for _, p := range podlist {
+ if !strings.Contains(p.MetaFile, hashstring) {
+ continue
+ }
+ if err := ts.processPod(p, importpaths); err != nil {
+ return err
+ }
+ }
+
+ metafilespath := filepath.Join(dir, coverage.MetaFilesFileName)
+ if _, err := os.Stat(metafilespath); err == nil {
+ if err := ts.readAuxMetaFiles(metafilespath, importpaths); err != nil {
+ return err
+ }
+ }
+
+ // Emit percent.
+ if err := ts.cf.EmitPercent(w, cpkg, true, true); err != nil {
+ return err
+ }
+
+ // Emit text output.
+ if tf != nil {
+ if err := ts.cf.EmitTextual(tf); err != nil {
+ return err
+ }
+ tfClosed = true
+ if err := tf.Close(); err != nil {
+ return fmt.Errorf("closing %s: %v", cfile, err)
+ }
+ }
+
+ return nil
+}
+
+type tstate struct {
+ calloc.BatchCounterAlloc
+ cm *cmerge.Merger
+ cf *cformat.Formatter
+ cmode coverage.CounterMode
+}
+
+// processPod reads coverage counter data for a specific pod.
+func (ts *tstate) processPod(p pods.Pod, importpaths map[string]struct{}) error {
+ // Open meta-data file
+ f, err := os.Open(p.MetaFile)
+ if err != nil {
+ return fmt.Errorf("unable to open meta-data file %s: %v", p.MetaFile, err)
+ }
+ defer func() {
+ f.Close()
+ }()
+ var mfr *decodemeta.CoverageMetaFileReader
+ mfr, err = decodemeta.NewCoverageMetaFileReader(f, nil)
+ if err != nil {
+ return fmt.Errorf("error reading meta-data file %s: %v", p.MetaFile, err)
+ }
+ newmode := mfr.CounterMode()
+ if newmode != ts.cmode {
+ return fmt.Errorf("internal error: counter mode clash: %q from test harness, %q from data file %s", ts.cmode.String(), newmode.String(), p.MetaFile)
+ }
+ newgran := mfr.CounterGranularity()
+ if err := ts.cm.SetModeAndGranularity(p.MetaFile, cmode, newgran); err != nil {
+ return err
+ }
+
+ // A map to store counter data, indexed by pkgid/fnid tuple.
+ pmm := make(map[pkfunc][]uint32)
+
+ // Helper to read a single counter data file.
+ readcdf := func(cdf string) error {
+ cf, err := os.Open(cdf)
+ if err != nil {
+ return fmt.Errorf("opening counter data file %s: %s", cdf, err)
+ }
+ defer cf.Close()
+ var cdr *decodecounter.CounterDataReader
+ cdr, err = decodecounter.NewCounterDataReader(cdf, cf)
+ if err != nil {
+ return fmt.Errorf("reading counter data file %s: %s", cdf, err)
+ }
+ var data decodecounter.FuncPayload
+ for {
+ ok, err := cdr.NextFunc(&data)
+ if err != nil {
+ return fmt.Errorf("reading counter data file %s: %v", cdf, err)
+ }
+ if !ok {
+ break
+ }
+
+ // NB: sanity check on pkg and func IDs?
+ key := pkfunc{pk: data.PkgIdx, fcn: data.FuncIdx}
+ if prev, found := pmm[key]; found {
+ // Note: no overflow reporting here.
+ if err, _ := ts.cm.MergeCounters(data.Counters, prev); err != nil {
+ return fmt.Errorf("processing counter data file %s: %v", cdf, err)
+ }
+ }
+ c := ts.AllocateCounters(len(data.Counters))
+ copy(c, data.Counters)
+ pmm[key] = c
+ }
+ return nil
+ }
+
+ // Read counter data files.
+ for _, cdf := range p.CounterDataFiles {
+ if err := readcdf(cdf); err != nil {
+ return err
+ }
+ }
+
+ // Visit meta-data file.
+ np := uint32(mfr.NumPackages())
+ payload := []byte{}
+ for pkIdx := uint32(0); pkIdx < np; pkIdx++ {
+ var pd *decodemeta.CoverageMetaDataDecoder
+ pd, payload, err = mfr.GetPackageDecoder(pkIdx, payload)
+ if err != nil {
+ return fmt.Errorf("reading pkg %d from meta-file %s: %s", pkIdx, p.MetaFile, err)
+ }
+ ts.cf.SetPackage(pd.PackagePath())
+ importpaths[pd.PackagePath()] = struct{}{}
+ var fd coverage.FuncDesc
+ nf := pd.NumFuncs()
+ for fnIdx := uint32(0); fnIdx < nf; fnIdx++ {
+ if err := pd.ReadFunc(fnIdx, &fd); err != nil {
+ return fmt.Errorf("reading meta-data file %s: %v",
+ p.MetaFile, err)
+ }
+ key := pkfunc{pk: pkIdx, fcn: fnIdx}
+ counters, haveCounters := pmm[key]
+ for i := 0; i < len(fd.Units); i++ {
+ u := fd.Units[i]
+ // Skip units with non-zero parent (no way to represent
+ // these in the existing format).
+ if u.Parent != 0 {
+ continue
+ }
+ count := uint32(0)
+ if haveCounters {
+ count = counters[i]
+ }
+ ts.cf.AddUnit(fd.Srcfile, fd.Funcname, fd.Lit, u, count)
+ }
+ }
+ }
+ return nil
+}
+
+type pkfunc struct {
+ pk, fcn uint32
+}
+
+func (ts *tstate) readAuxMetaFiles(metafiles string, importpaths map[string]struct{}) error {
+ // Unmarshall the information on available aux metafiles into
+ // a MetaFileCollection struct.
+ var mfc coverage.MetaFileCollection
+ data, err := os.ReadFile(metafiles)
+ if err != nil {
+ return fmt.Errorf("error reading auxmetafiles file %q: %v", metafiles, err)
+ }
+ if err := json.Unmarshal(data, &mfc); err != nil {
+ return fmt.Errorf("error reading auxmetafiles file %q: %v", metafiles, err)
+ }
+
+ // Walk through each available aux meta-file. If we've already
+ // seen the package path in question during the walk of the
+ // "regular" meta-data file, then we can skip the package,
+ // otherwise construct a dummy pod with the single meta-data file
+ // (no counters) and invoke processPod on it.
+ for i := range mfc.ImportPaths {
+ p := mfc.ImportPaths[i]
+ if _, ok := importpaths[p]; ok {
+ continue
+ }
+ var pod pods.Pod
+ pod.MetaFile = mfc.MetaFileFragments[i]
+ if err := ts.processPod(pod, importpaths); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// snapshot returns a snapshot of coverage percentage at a moment of
+// time within a running test, so as to support the testing.Coverage()
+// function. This version doesn't examine coverage meta-data, so the
+// result it returns will be less accurate (more "slop") due to the
+// fact that we don't look at the meta data to see how many statements
+// are associated with each counter.
+func snapshot() float64 {
+ cl := getCovCounterList()
+ if len(cl) == 0 {
+ // no work to do here.
+ return 0.0
+ }
+
+ tot := uint64(0)
+ totExec := uint64(0)
+ for _, c := range cl {
+ sd := unsafe.Slice((*atomic.Uint32)(unsafe.Pointer(c.Counters)), c.Len)
+ tot += uint64(len(sd))
+ for i := 0; i < len(sd); i++ {
+ // Skip ahead until the next non-zero value.
+ if sd[i].Load() == 0 {
+ continue
+ }
+ // We found a function that was executed.
+ nCtrs := sd[i+coverage.NumCtrsOffset].Load()
+ cst := i + coverage.FirstCtrOffset
+
+ if cst+int(nCtrs) > len(sd) {
+ break
+ }
+ counters := sd[cst : cst+int(nCtrs)]
+ for i := range counters {
+ if counters[i].Load() != 0 {
+ totExec++
+ }
+ }
+ i += coverage.FirstCtrOffset + int(nCtrs) - 1
+ }
+ }
+ if tot == 0 {
+ return 0.0
+ }
+ return float64(totExec) / float64(tot)
+}
diff --git a/contrib/go/_std_1.21/src/runtime/coverage/ya.make b/contrib/go/_std_1.21/src/runtime/coverage/ya.make
new file mode 100644
index 0000000000..f6bf4c6c71
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/coverage/ya.make
@@ -0,0 +1,19 @@
+GO_LIBRARY()
+
+SRCS(
+ apis.go
+ dummy.s
+ emit.go
+ hooks.go
+ testsupport.go
+)
+
+GO_TEST_SRCS(
+ emitdata_test.go
+ ts_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/runtime/covercounter.go b/contrib/go/_std_1.21/src/runtime/covercounter.go
index 72842bdd94..72842bdd94 100644
--- a/contrib/go/_std_1.20/src/runtime/covercounter.go
+++ b/contrib/go/_std_1.21/src/runtime/covercounter.go
diff --git a/contrib/go/_std_1.20/src/runtime/covermeta.go b/contrib/go/_std_1.21/src/runtime/covermeta.go
index 54ef42ae1f..54ef42ae1f 100644
--- a/contrib/go/_std_1.20/src/runtime/covermeta.go
+++ b/contrib/go/_std_1.21/src/runtime/covermeta.go
diff --git a/contrib/go/_std_1.20/src/runtime/cpuflags.go b/contrib/go/_std_1.21/src/runtime/cpuflags.go
index bbe93c5bea..bbe93c5bea 100644
--- a/contrib/go/_std_1.20/src/runtime/cpuflags.go
+++ b/contrib/go/_std_1.21/src/runtime/cpuflags.go
diff --git a/contrib/go/_std_1.20/src/runtime/cpuflags_amd64.go b/contrib/go/_std_1.21/src/runtime/cpuflags_amd64.go
index 8cca4bca8f..8cca4bca8f 100644
--- a/contrib/go/_std_1.20/src/runtime/cpuflags_amd64.go
+++ b/contrib/go/_std_1.21/src/runtime/cpuflags_amd64.go
diff --git a/contrib/go/_std_1.21/src/runtime/cpuflags_arm64.go b/contrib/go/_std_1.21/src/runtime/cpuflags_arm64.go
new file mode 100644
index 0000000000..2ed1811456
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cpuflags_arm64.go
@@ -0,0 +1,17 @@
+// 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 runtime
+
+import (
+ "internal/cpu"
+)
+
+var arm64UseAlignedLoads bool
+
+func init() {
+ if cpu.ARM64.IsNeoverse {
+ arm64UseAlignedLoads = true
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/cpuprof.go b/contrib/go/_std_1.21/src/runtime/cpuprof.go
new file mode 100644
index 0000000000..0d7eeacb39
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cpuprof.go
@@ -0,0 +1,241 @@
+// Copyright 2011 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.
+
+// CPU profiling.
+//
+// The signal handler for the profiling clock tick adds a new stack trace
+// to a log of recent traces. The log is read by a user goroutine that
+// turns it into formatted profile data. If the reader does not keep up
+// with the log, those writes will be recorded as a count of lost records.
+// The actual profile buffer is in profbuf.go.
+
+package runtime
+
+import (
+ "internal/abi"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+const (
+ maxCPUProfStack = 64
+
+ // profBufWordCount is the size of the CPU profile buffer's storage for the
+ // header and stack of each sample, measured in 64-bit words. Every sample
+ // has a required header of two words. With a small additional header (a
+ // word or two) and stacks at the profiler's maximum length of 64 frames,
+ // that capacity can support 1900 samples or 19 thread-seconds at a 100 Hz
+ // sample rate, at a cost of 1 MiB.
+ profBufWordCount = 1 << 17
+ // profBufTagCount is the size of the CPU profile buffer's storage for the
+ // goroutine tags associated with each sample. A capacity of 1<<14 means
+ // room for 16k samples, or 160 thread-seconds at a 100 Hz sample rate.
+ profBufTagCount = 1 << 14
+)
+
+type cpuProfile struct {
+ lock mutex
+ on bool // profiling is on
+ log *profBuf // profile events written here
+
+ // extra holds extra stacks accumulated in addNonGo
+ // corresponding to profiling signals arriving on
+ // non-Go-created threads. Those stacks are written
+ // to log the next time a normal Go thread gets the
+ // signal handler.
+ // Assuming the stacks are 2 words each (we don't get
+ // a full traceback from those threads), plus one word
+ // size for framing, 100 Hz profiling would generate
+ // 300 words per second.
+ // Hopefully a normal Go thread will get the profiling
+ // signal at least once every few seconds.
+ extra [1000]uintptr
+ numExtra int
+ lostExtra uint64 // count of frames lost because extra is full
+ lostAtomic uint64 // count of frames lost because of being in atomic64 on mips/arm; updated racily
+}
+
+var cpuprof cpuProfile
+
+// SetCPUProfileRate sets the CPU profiling rate to hz samples per second.
+// If hz <= 0, SetCPUProfileRate turns off profiling.
+// If the profiler is on, the rate cannot be changed without first turning it off.
+//
+// Most clients should use the runtime/pprof package or
+// the testing package's -test.cpuprofile flag instead of calling
+// SetCPUProfileRate directly.
+func SetCPUProfileRate(hz int) {
+ // Clamp hz to something reasonable.
+ if hz < 0 {
+ hz = 0
+ }
+ if hz > 1000000 {
+ hz = 1000000
+ }
+
+ lock(&cpuprof.lock)
+ if hz > 0 {
+ if cpuprof.on || cpuprof.log != nil {
+ print("runtime: cannot set cpu profile rate until previous profile has finished.\n")
+ unlock(&cpuprof.lock)
+ return
+ }
+
+ cpuprof.on = true
+ cpuprof.log = newProfBuf(1, profBufWordCount, profBufTagCount)
+ hdr := [1]uint64{uint64(hz)}
+ cpuprof.log.write(nil, nanotime(), hdr[:], nil)
+ setcpuprofilerate(int32(hz))
+ } else if cpuprof.on {
+ setcpuprofilerate(0)
+ cpuprof.on = false
+ cpuprof.addExtra()
+ cpuprof.log.close()
+ }
+ unlock(&cpuprof.lock)
+}
+
+// add adds the stack trace to the profile.
+// It is called from signal handlers and other limited environments
+// and cannot allocate memory or acquire locks that might be
+// held at the time of the signal, nor can it use substantial amounts
+// of stack.
+//
+//go:nowritebarrierrec
+func (p *cpuProfile) add(tagPtr *unsafe.Pointer, stk []uintptr) {
+ // Simple cas-lock to coordinate with setcpuprofilerate.
+ for !prof.signalLock.CompareAndSwap(0, 1) {
+ // TODO: Is it safe to osyield here? https://go.dev/issue/52672
+ osyield()
+ }
+
+ if prof.hz.Load() != 0 { // implies cpuprof.log != nil
+ if p.numExtra > 0 || p.lostExtra > 0 || p.lostAtomic > 0 {
+ p.addExtra()
+ }
+ hdr := [1]uint64{1}
+ // Note: write "knows" that the argument is &gp.labels,
+ // because otherwise its write barrier behavior may not
+ // be correct. See the long comment there before
+ // changing the argument here.
+ cpuprof.log.write(tagPtr, nanotime(), hdr[:], stk)
+ }
+
+ prof.signalLock.Store(0)
+}
+
+// addNonGo adds the non-Go stack trace to the profile.
+// It is called from a non-Go thread, so we cannot use much stack at all,
+// nor do anything that needs a g or an m.
+// In particular, we can't call cpuprof.log.write.
+// Instead, we copy the stack into cpuprof.extra,
+// which will be drained the next time a Go thread
+// gets the signal handling event.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func (p *cpuProfile) addNonGo(stk []uintptr) {
+ // Simple cas-lock to coordinate with SetCPUProfileRate.
+ // (Other calls to add or addNonGo should be blocked out
+ // by the fact that only one SIGPROF can be handled by the
+ // process at a time. If not, this lock will serialize those too.
+ // The use of timer_create(2) on Linux to request process-targeted
+ // signals may have changed this.)
+ for !prof.signalLock.CompareAndSwap(0, 1) {
+ // TODO: Is it safe to osyield here? https://go.dev/issue/52672
+ osyield()
+ }
+
+ if cpuprof.numExtra+1+len(stk) < len(cpuprof.extra) {
+ i := cpuprof.numExtra
+ cpuprof.extra[i] = uintptr(1 + len(stk))
+ copy(cpuprof.extra[i+1:], stk)
+ cpuprof.numExtra += 1 + len(stk)
+ } else {
+ cpuprof.lostExtra++
+ }
+
+ prof.signalLock.Store(0)
+}
+
+// addExtra adds the "extra" profiling events,
+// queued by addNonGo, to the profile log.
+// addExtra is called either from a signal handler on a Go thread
+// or from an ordinary goroutine; either way it can use stack
+// and has a g. The world may be stopped, though.
+func (p *cpuProfile) addExtra() {
+ // Copy accumulated non-Go profile events.
+ hdr := [1]uint64{1}
+ for i := 0; i < p.numExtra; {
+ p.log.write(nil, 0, hdr[:], p.extra[i+1:i+int(p.extra[i])])
+ i += int(p.extra[i])
+ }
+ p.numExtra = 0
+
+ // Report any lost events.
+ if p.lostExtra > 0 {
+ hdr := [1]uint64{p.lostExtra}
+ lostStk := [2]uintptr{
+ abi.FuncPCABIInternal(_LostExternalCode) + sys.PCQuantum,
+ abi.FuncPCABIInternal(_ExternalCode) + sys.PCQuantum,
+ }
+ p.log.write(nil, 0, hdr[:], lostStk[:])
+ p.lostExtra = 0
+ }
+
+ if p.lostAtomic > 0 {
+ hdr := [1]uint64{p.lostAtomic}
+ lostStk := [2]uintptr{
+ abi.FuncPCABIInternal(_LostSIGPROFDuringAtomic64) + sys.PCQuantum,
+ abi.FuncPCABIInternal(_System) + sys.PCQuantum,
+ }
+ p.log.write(nil, 0, hdr[:], lostStk[:])
+ p.lostAtomic = 0
+ }
+
+}
+
+// CPUProfile panics.
+// It formerly provided raw access to chunks of
+// a pprof-format profile generated by the runtime.
+// The details of generating that format have changed,
+// so this functionality has been removed.
+//
+// Deprecated: Use the runtime/pprof package,
+// or the handlers in the net/http/pprof package,
+// or the testing package's -test.cpuprofile flag instead.
+func CPUProfile() []byte {
+ panic("CPUProfile no longer available")
+}
+
+//go:linkname runtime_pprof_runtime_cyclesPerSecond runtime/pprof.runtime_cyclesPerSecond
+func runtime_pprof_runtime_cyclesPerSecond() int64 {
+ return tickspersecond()
+}
+
+// readProfile, provided to runtime/pprof, returns the next chunk of
+// binary CPU profiling stack trace data, blocking until data is available.
+// If profiling is turned off and all the profile data accumulated while it was
+// on has been returned, readProfile returns eof=true.
+// The caller must save the returned data and tags before calling readProfile again.
+// The returned data contains a whole number of records, and tags contains
+// exactly one entry per record.
+//
+//go:linkname runtime_pprof_readProfile runtime/pprof.readProfile
+func runtime_pprof_readProfile() ([]uint64, []unsafe.Pointer, bool) {
+ lock(&cpuprof.lock)
+ log := cpuprof.log
+ unlock(&cpuprof.lock)
+ readMode := profBufBlocking
+ if GOOS == "darwin" || GOOS == "ios" {
+ readMode = profBufNonBlocking // For #61768; on Darwin notes are not async-signal-safe. See sigNoteSetup in os_darwin.go.
+ }
+ data, tags, eof := log.read(readMode)
+ if len(data) == 0 && eof {
+ lock(&cpuprof.lock)
+ cpuprof.log = nil
+ unlock(&cpuprof.lock)
+ }
+ return data, tags, eof
+}
diff --git a/contrib/go/_std_1.21/src/runtime/cputicks.go b/contrib/go/_std_1.21/src/runtime/cputicks.go
new file mode 100644
index 0000000000..2cf3240333
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/cputicks.go
@@ -0,0 +1,11 @@
+// Copyright 2014 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.
+
+//go:build !arm && !arm64 && !mips64 && !mips64le && !mips && !mipsle && !wasm
+
+package runtime
+
+// careful: cputicks is not guaranteed to be monotonic! In particular, we have
+// noticed drift between cpus on certain os/arch combinations. See issue 8976.
+func cputicks() int64
diff --git a/contrib/go/_std_1.20/src/runtime/create_file_nounix.go b/contrib/go/_std_1.21/src/runtime/create_file_nounix.go
index 60f75175a2..60f75175a2 100644
--- a/contrib/go/_std_1.20/src/runtime/create_file_nounix.go
+++ b/contrib/go/_std_1.21/src/runtime/create_file_nounix.go
diff --git a/contrib/go/_std_1.20/src/runtime/create_file_unix.go b/contrib/go/_std_1.21/src/runtime/create_file_unix.go
index 7280810ed2..7280810ed2 100644
--- a/contrib/go/_std_1.20/src/runtime/create_file_unix.go
+++ b/contrib/go/_std_1.21/src/runtime/create_file_unix.go
diff --git a/contrib/go/_std_1.21/src/runtime/debug.go b/contrib/go/_std_1.21/src/runtime/debug.go
new file mode 100644
index 0000000000..9a92b45ff3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/debug.go
@@ -0,0 +1,115 @@
+// Copyright 2009 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 runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// GOMAXPROCS sets the maximum number of CPUs that can be executing
+// simultaneously and returns the previous setting. It defaults to
+// the value of runtime.NumCPU. If n < 1, it does not change the current setting.
+// This call will go away when the scheduler improves.
+func GOMAXPROCS(n int) int {
+ if GOARCH == "wasm" && n > 1 {
+ n = 1 // WebAssembly has no threads yet, so only one CPU is possible.
+ }
+
+ lock(&sched.lock)
+ ret := int(gomaxprocs)
+ unlock(&sched.lock)
+ if n <= 0 || n == ret {
+ return ret
+ }
+
+ stopTheWorldGC(stwGOMAXPROCS)
+
+ // newprocs will be processed by startTheWorld
+ newprocs = int32(n)
+
+ startTheWorldGC()
+ return ret
+}
+
+// NumCPU returns the number of logical CPUs usable by the current process.
+//
+// The set of available CPUs is checked by querying the operating system
+// at process startup. Changes to operating system CPU allocation after
+// process startup are not reflected.
+func NumCPU() int {
+ return int(ncpu)
+}
+
+// NumCgoCall returns the number of cgo calls made by the current process.
+func NumCgoCall() int64 {
+ var n = int64(atomic.Load64(&ncgocall))
+ for mp := (*m)(atomic.Loadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink {
+ n += int64(mp.ncgocall)
+ }
+ return n
+}
+
+// NumGoroutine returns the number of goroutines that currently exist.
+func NumGoroutine() int {
+ return int(gcount())
+}
+
+//go:linkname debug_modinfo runtime/debug.modinfo
+func debug_modinfo() string {
+ return modinfo
+}
+
+// mayMoreStackPreempt is a maymorestack hook that forces a preemption
+// at every possible cooperative preemption point.
+//
+// This is valuable to apply to the runtime, which can be sensitive to
+// preemption points. To apply this to all preemption points in the
+// runtime and runtime-like code, use the following in bash or zsh:
+//
+// X=(-{gc,asm}flags={runtime/...,reflect,sync}=-d=maymorestack=runtime.mayMoreStackPreempt) GOFLAGS=${X[@]}
+//
+// This must be deeply nosplit because it is called from a function
+// prologue before the stack is set up and because the compiler will
+// call it from any splittable prologue (leading to infinite
+// recursion).
+//
+// Ideally it should also use very little stack because the linker
+// doesn't currently account for this in nosplit stack depth checking.
+//
+// Ensure mayMoreStackPreempt can be called for all ABIs.
+//
+//go:nosplit
+//go:linkname mayMoreStackPreempt
+func mayMoreStackPreempt() {
+ // Don't do anything on the g0 or gsignal stack.
+ gp := getg()
+ if gp == gp.m.g0 || gp == gp.m.gsignal {
+ return
+ }
+ // Force a preemption, unless the stack is already poisoned.
+ if gp.stackguard0 < stackPoisonMin {
+ gp.stackguard0 = stackPreempt
+ }
+}
+
+// mayMoreStackMove is a maymorestack hook that forces stack movement
+// at every possible point.
+//
+// See mayMoreStackPreempt.
+//
+//go:nosplit
+//go:linkname mayMoreStackMove
+func mayMoreStackMove() {
+ // Don't do anything on the g0 or gsignal stack.
+ gp := getg()
+ if gp == gp.m.g0 || gp == gp.m.gsignal {
+ return
+ }
+ // Force stack movement, unless the stack is already poisoned.
+ if gp.stackguard0 < stackPoisonMin {
+ gp.stackguard0 = stackForceMove
+ }
+}
diff --git a/contrib/go/_std_1.20/src/runtime/debug/debug.s b/contrib/go/_std_1.21/src/runtime/debug/debug.s
index 6aae33a871..6aae33a871 100644
--- a/contrib/go/_std_1.20/src/runtime/debug/debug.s
+++ b/contrib/go/_std_1.21/src/runtime/debug/debug.s
diff --git a/contrib/go/_std_1.20/src/runtime/debug/garbage.go b/contrib/go/_std_1.21/src/runtime/debug/garbage.go
index 0f53928fe8..0f53928fe8 100644
--- a/contrib/go/_std_1.20/src/runtime/debug/garbage.go
+++ b/contrib/go/_std_1.21/src/runtime/debug/garbage.go
diff --git a/contrib/go/_std_1.21/src/runtime/debug/mod.go b/contrib/go/_std_1.21/src/runtime/debug/mod.go
new file mode 100644
index 0000000000..7f85174c06
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/debug/mod.go
@@ -0,0 +1,287 @@
+// Copyright 2018 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 debug
+
+import (
+ "fmt"
+ "runtime"
+ "strconv"
+ "strings"
+)
+
+// exported from runtime.
+func modinfo() string
+
+// ReadBuildInfo returns the build information embedded
+// in the running binary. The information is available only
+// in binaries built with module support.
+func ReadBuildInfo() (info *BuildInfo, ok bool) {
+ data := modinfo()
+ if len(data) < 32 {
+ return nil, false
+ }
+ data = data[16 : len(data)-16]
+ bi, err := ParseBuildInfo(data)
+ if err != nil {
+ return nil, false
+ }
+
+ // The go version is stored separately from other build info, mostly for
+ // historical reasons. It is not part of the modinfo() string, and
+ // ParseBuildInfo does not recognize it. We inject it here to hide this
+ // awkwardness from the user.
+ bi.GoVersion = runtime.Version()
+
+ return bi, true
+}
+
+// BuildInfo represents the build information read from a Go binary.
+type BuildInfo struct {
+ // GoVersion is the version of the Go toolchain that built the binary
+ // (for example, "go1.19.2").
+ GoVersion string
+
+ // Path is the package path of the main package for the binary
+ // (for example, "golang.org/x/tools/cmd/stringer").
+ Path string
+
+ // Main describes the module that contains the main package for the binary.
+ Main Module
+
+ // Deps describes all the dependency modules, both direct and indirect,
+ // that contributed packages to the build of this binary.
+ Deps []*Module
+
+ // Settings describes the build settings used to build the binary.
+ Settings []BuildSetting
+}
+
+// A Module describes a single module included in a build.
+type Module struct {
+ Path string // module path
+ Version string // module version
+ Sum string // checksum
+ Replace *Module // replaced by this module
+}
+
+// A BuildSetting is a key-value pair describing one setting that influenced a build.
+//
+// Defined keys include:
+//
+// - -buildmode: the buildmode flag used (typically "exe")
+// - -compiler: the compiler toolchain flag used (typically "gc")
+// - CGO_ENABLED: the effective CGO_ENABLED environment variable
+// - CGO_CFLAGS: the effective CGO_CFLAGS environment variable
+// - CGO_CPPFLAGS: the effective CGO_CPPFLAGS environment variable
+// - CGO_CXXFLAGS: the effective CGO_CPPFLAGS environment variable
+// - CGO_LDFLAGS: the effective CGO_CPPFLAGS environment variable
+// - GOARCH: the architecture target
+// - GOAMD64/GOARM/GO386/etc: the architecture feature level for GOARCH
+// - GOOS: the operating system target
+// - vcs: the version control system for the source tree where the build ran
+// - vcs.revision: the revision identifier for the current commit or checkout
+// - vcs.time: the modification time associated with vcs.revision, in RFC3339 format
+// - vcs.modified: true or false indicating whether the source tree had local modifications
+type BuildSetting struct {
+ // Key and Value describe the build setting.
+ // Key must not contain an equals sign, space, tab, or newline.
+ // Value must not contain newlines ('\n').
+ Key, Value string
+}
+
+// quoteKey reports whether key is required to be quoted.
+func quoteKey(key string) bool {
+ return len(key) == 0 || strings.ContainsAny(key, "= \t\r\n\"`")
+}
+
+// quoteValue reports whether value is required to be quoted.
+func quoteValue(value string) bool {
+ return strings.ContainsAny(value, " \t\r\n\"`")
+}
+
+func (bi *BuildInfo) String() string {
+ buf := new(strings.Builder)
+ if bi.GoVersion != "" {
+ fmt.Fprintf(buf, "go\t%s\n", bi.GoVersion)
+ }
+ if bi.Path != "" {
+ fmt.Fprintf(buf, "path\t%s\n", bi.Path)
+ }
+ var formatMod func(string, Module)
+ formatMod = func(word string, m Module) {
+ buf.WriteString(word)
+ buf.WriteByte('\t')
+ buf.WriteString(m.Path)
+ buf.WriteByte('\t')
+ buf.WriteString(m.Version)
+ if m.Replace == nil {
+ buf.WriteByte('\t')
+ buf.WriteString(m.Sum)
+ } else {
+ buf.WriteByte('\n')
+ formatMod("=>", *m.Replace)
+ }
+ buf.WriteByte('\n')
+ }
+ if bi.Main != (Module{}) {
+ formatMod("mod", bi.Main)
+ }
+ for _, dep := range bi.Deps {
+ formatMod("dep", *dep)
+ }
+ for _, s := range bi.Settings {
+ key := s.Key
+ if quoteKey(key) {
+ key = strconv.Quote(key)
+ }
+ value := s.Value
+ if quoteValue(value) {
+ value = strconv.Quote(value)
+ }
+ fmt.Fprintf(buf, "build\t%s=%s\n", key, value)
+ }
+
+ return buf.String()
+}
+
+func ParseBuildInfo(data string) (bi *BuildInfo, err error) {
+ lineNum := 1
+ defer func() {
+ if err != nil {
+ err = fmt.Errorf("could not parse Go build info: line %d: %w", lineNum, err)
+ }
+ }()
+
+ var (
+ pathLine = "path\t"
+ modLine = "mod\t"
+ depLine = "dep\t"
+ repLine = "=>\t"
+ buildLine = "build\t"
+ newline = "\n"
+ tab = "\t"
+ )
+
+ readModuleLine := func(elem []string) (Module, error) {
+ if len(elem) != 2 && len(elem) != 3 {
+ return Module{}, fmt.Errorf("expected 2 or 3 columns; got %d", len(elem))
+ }
+ version := elem[1]
+ sum := ""
+ if len(elem) == 3 {
+ sum = elem[2]
+ }
+ return Module{
+ Path: elem[0],
+ Version: version,
+ Sum: sum,
+ }, nil
+ }
+
+ bi = new(BuildInfo)
+ var (
+ last *Module
+ line string
+ ok bool
+ )
+ // Reverse of BuildInfo.String(), except for go version.
+ for len(data) > 0 {
+ line, data, ok = strings.Cut(data, newline)
+ if !ok {
+ break
+ }
+ switch {
+ case strings.HasPrefix(line, pathLine):
+ elem := line[len(pathLine):]
+ bi.Path = string(elem)
+ case strings.HasPrefix(line, modLine):
+ elem := strings.Split(line[len(modLine):], tab)
+ last = &bi.Main
+ *last, err = readModuleLine(elem)
+ if err != nil {
+ return nil, err
+ }
+ case strings.HasPrefix(line, depLine):
+ elem := strings.Split(line[len(depLine):], tab)
+ last = new(Module)
+ bi.Deps = append(bi.Deps, last)
+ *last, err = readModuleLine(elem)
+ if err != nil {
+ return nil, err
+ }
+ case strings.HasPrefix(line, repLine):
+ elem := strings.Split(line[len(repLine):], tab)
+ if len(elem) != 3 {
+ return nil, fmt.Errorf("expected 3 columns for replacement; got %d", len(elem))
+ }
+ if last == nil {
+ return nil, fmt.Errorf("replacement with no module on previous line")
+ }
+ last.Replace = &Module{
+ Path: string(elem[0]),
+ Version: string(elem[1]),
+ Sum: string(elem[2]),
+ }
+ last = nil
+ case strings.HasPrefix(line, buildLine):
+ kv := line[len(buildLine):]
+ if len(kv) < 1 {
+ return nil, fmt.Errorf("build line missing '='")
+ }
+
+ var key, rawValue string
+ switch kv[0] {
+ case '=':
+ return nil, fmt.Errorf("build line with missing key")
+
+ case '`', '"':
+ rawKey, err := strconv.QuotedPrefix(kv)
+ if err != nil {
+ return nil, fmt.Errorf("invalid quoted key in build line")
+ }
+ if len(kv) == len(rawKey) {
+ return nil, fmt.Errorf("build line missing '=' after quoted key")
+ }
+ if c := kv[len(rawKey)]; c != '=' {
+ return nil, fmt.Errorf("unexpected character after quoted key: %q", c)
+ }
+ key, _ = strconv.Unquote(rawKey)
+ rawValue = kv[len(rawKey)+1:]
+
+ default:
+ var ok bool
+ key, rawValue, ok = strings.Cut(kv, "=")
+ if !ok {
+ return nil, fmt.Errorf("build line missing '=' after key")
+ }
+ if quoteKey(key) {
+ return nil, fmt.Errorf("unquoted key %q must be quoted", key)
+ }
+ }
+
+ var value string
+ if len(rawValue) > 0 {
+ switch rawValue[0] {
+ case '`', '"':
+ var err error
+ value, err = strconv.Unquote(rawValue)
+ if err != nil {
+ return nil, fmt.Errorf("invalid quoted value in build line")
+ }
+
+ default:
+ value = rawValue
+ if quoteValue(value) {
+ return nil, fmt.Errorf("unquoted value %q must be quoted", value)
+ }
+ }
+ }
+
+ bi.Settings = append(bi.Settings, BuildSetting{Key: key, Value: value})
+ }
+ lineNum++
+ }
+ return bi, nil
+}
diff --git a/contrib/go/_std_1.20/src/runtime/debug/stack.go b/contrib/go/_std_1.21/src/runtime/debug/stack.go
index 5d810af540..5d810af540 100644
--- a/contrib/go/_std_1.20/src/runtime/debug/stack.go
+++ b/contrib/go/_std_1.21/src/runtime/debug/stack.go
diff --git a/contrib/go/_std_1.20/src/runtime/debug/stubs.go b/contrib/go/_std_1.21/src/runtime/debug/stubs.go
index 913d4b9b09..913d4b9b09 100644
--- a/contrib/go/_std_1.20/src/runtime/debug/stubs.go
+++ b/contrib/go/_std_1.21/src/runtime/debug/stubs.go
diff --git a/contrib/go/_std_1.21/src/runtime/debug/ya.make b/contrib/go/_std_1.21/src/runtime/debug/ya.make
new file mode 100644
index 0000000000..4181f5b962
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/debug/ya.make
@@ -0,0 +1,29 @@
+GO_LIBRARY()
+
+SRCS(
+ debug.s
+ garbage.go
+ mod.go
+ stack.go
+ stubs.go
+)
+
+GO_XTEST_SRCS(
+ garbage_test.go
+ heapdump_test.go
+ mod_test.go
+ stack_test.go
+)
+
+IF (OS_LINUX)
+ GO_XTEST_SRCS(panic_test.go)
+ENDIF()
+
+IF (OS_DARWIN)
+ GO_XTEST_SRCS(panic_test.go)
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/runtime/debugcall.go b/contrib/go/_std_1.21/src/runtime/debugcall.go
new file mode 100644
index 0000000000..e793545036
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/debugcall.go
@@ -0,0 +1,257 @@
+// Copyright 2018 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.
+
+//go:build amd64 || arm64
+
+package runtime
+
+import (
+ "internal/abi"
+ "unsafe"
+)
+
+const (
+ debugCallSystemStack = "executing on Go runtime stack"
+ debugCallUnknownFunc = "call from unknown function"
+ debugCallRuntime = "call from within the Go runtime"
+ debugCallUnsafePoint = "call not at safe point"
+)
+
+func debugCallV2()
+func debugCallPanicked(val any)
+
+// debugCallCheck checks whether it is safe to inject a debugger
+// function call with return PC pc. If not, it returns a string
+// explaining why.
+//
+//go:nosplit
+func debugCallCheck(pc uintptr) string {
+ // No user calls from the system stack.
+ if getg() != getg().m.curg {
+ return debugCallSystemStack
+ }
+ if sp := getcallersp(); !(getg().stack.lo < sp && sp <= getg().stack.hi) {
+ // Fast syscalls (nanotime) and racecall switch to the
+ // g0 stack without switching g. We can't safely make
+ // a call in this state. (We can't even safely
+ // systemstack.)
+ return debugCallSystemStack
+ }
+
+ // Switch to the system stack to avoid overflowing the user
+ // stack.
+ var ret string
+ systemstack(func() {
+ f := findfunc(pc)
+ if !f.valid() {
+ ret = debugCallUnknownFunc
+ return
+ }
+
+ name := funcname(f)
+
+ switch name {
+ case "debugCall32",
+ "debugCall64",
+ "debugCall128",
+ "debugCall256",
+ "debugCall512",
+ "debugCall1024",
+ "debugCall2048",
+ "debugCall4096",
+ "debugCall8192",
+ "debugCall16384",
+ "debugCall32768",
+ "debugCall65536":
+ // These functions are allowed so that the debugger can initiate multiple function calls.
+ // See: https://golang.org/cl/161137/
+ return
+ }
+
+ // Disallow calls from the runtime. We could
+ // potentially make this condition tighter (e.g., not
+ // when locks are held), but there are enough tightly
+ // coded sequences (e.g., defer handling) that it's
+ // better to play it safe.
+ if pfx := "runtime."; len(name) > len(pfx) && name[:len(pfx)] == pfx {
+ ret = debugCallRuntime
+ return
+ }
+
+ // Check that this isn't an unsafe-point.
+ if pc != f.entry() {
+ pc--
+ }
+ up := pcdatavalue(f, abi.PCDATA_UnsafePoint, pc, nil)
+ if up != abi.UnsafePointSafe {
+ // Not at a safe point.
+ ret = debugCallUnsafePoint
+ }
+ })
+ return ret
+}
+
+// debugCallWrap starts a new goroutine to run a debug call and blocks
+// the calling goroutine. On the goroutine, it prepares to recover
+// panics from the debug call, and then calls the call dispatching
+// function at PC dispatch.
+//
+// This must be deeply nosplit because there are untyped values on the
+// stack from debugCallV2.
+//
+//go:nosplit
+func debugCallWrap(dispatch uintptr) {
+ var lockedExt uint32
+ callerpc := getcallerpc()
+ gp := getg()
+
+ // Lock ourselves to the OS thread.
+ //
+ // Debuggers rely on us running on the same thread until we get to
+ // dispatch the function they asked as to.
+ //
+ // We're going to transfer this to the new G we just created.
+ lockOSThread()
+
+ // Create a new goroutine to execute the call on. Run this on
+ // the system stack to avoid growing our stack.
+ systemstack(func() {
+ // TODO(mknyszek): It would be nice to wrap these arguments in an allocated
+ // closure and start the goroutine with that closure, but the compiler disallows
+ // implicit closure allocation in the runtime.
+ fn := debugCallWrap1
+ newg := newproc1(*(**funcval)(unsafe.Pointer(&fn)), gp, callerpc)
+ args := &debugCallWrapArgs{
+ dispatch: dispatch,
+ callingG: gp,
+ }
+ newg.param = unsafe.Pointer(args)
+
+ // Transfer locked-ness to the new goroutine.
+ // Save lock state to restore later.
+ mp := gp.m
+ if mp != gp.lockedm.ptr() {
+ throw("inconsistent lockedm")
+ }
+ // Save the external lock count and clear it so
+ // that it can't be unlocked from the debug call.
+ // Note: we already locked internally to the thread,
+ // so if we were locked before we're still locked now.
+ lockedExt = mp.lockedExt
+ mp.lockedExt = 0
+
+ mp.lockedg.set(newg)
+ newg.lockedm.set(mp)
+ gp.lockedm = 0
+
+ // Mark the calling goroutine as being at an async
+ // safe-point, since it has a few conservative frames
+ // at the bottom of the stack. This also prevents
+ // stack shrinks.
+ gp.asyncSafePoint = true
+
+ // Stash newg away so we can execute it below (mcall's
+ // closure can't capture anything).
+ gp.schedlink.set(newg)
+ })
+
+ // Switch to the new goroutine.
+ mcall(func(gp *g) {
+ // Get newg.
+ newg := gp.schedlink.ptr()
+ gp.schedlink = 0
+
+ // Park the calling goroutine.
+ if traceEnabled() {
+ traceGoPark(traceBlockDebugCall, 1)
+ }
+ casGToWaiting(gp, _Grunning, waitReasonDebugCall)
+ dropg()
+
+ // Directly execute the new goroutine. The debug
+ // protocol will continue on the new goroutine, so
+ // it's important we not just let the scheduler do
+ // this or it may resume a different goroutine.
+ execute(newg, true)
+ })
+
+ // We'll resume here when the call returns.
+
+ // Restore locked state.
+ mp := gp.m
+ mp.lockedExt = lockedExt
+ mp.lockedg.set(gp)
+ gp.lockedm.set(mp)
+
+ // Undo the lockOSThread we did earlier.
+ unlockOSThread()
+
+ gp.asyncSafePoint = false
+}
+
+type debugCallWrapArgs struct {
+ dispatch uintptr
+ callingG *g
+}
+
+// debugCallWrap1 is the continuation of debugCallWrap on the callee
+// goroutine.
+func debugCallWrap1() {
+ gp := getg()
+ args := (*debugCallWrapArgs)(gp.param)
+ dispatch, callingG := args.dispatch, args.callingG
+ gp.param = nil
+
+ // Dispatch call and trap panics.
+ debugCallWrap2(dispatch)
+
+ // Resume the caller goroutine.
+ getg().schedlink.set(callingG)
+ mcall(func(gp *g) {
+ callingG := gp.schedlink.ptr()
+ gp.schedlink = 0
+
+ // Unlock this goroutine from the M if necessary. The
+ // calling G will relock.
+ if gp.lockedm != 0 {
+ gp.lockedm = 0
+ gp.m.lockedg = 0
+ }
+
+ // Switch back to the calling goroutine. At some point
+ // the scheduler will schedule us again and we'll
+ // finish exiting.
+ if traceEnabled() {
+ traceGoSched()
+ }
+ casgstatus(gp, _Grunning, _Grunnable)
+ dropg()
+ lock(&sched.lock)
+ globrunqput(gp)
+ unlock(&sched.lock)
+
+ if traceEnabled() {
+ traceGoUnpark(callingG, 0)
+ }
+ casgstatus(callingG, _Gwaiting, _Grunnable)
+ execute(callingG, true)
+ })
+}
+
+func debugCallWrap2(dispatch uintptr) {
+ // Call the dispatch function and trap panics.
+ var dispatchF func()
+ dispatchFV := funcval{dispatch}
+ *(*unsafe.Pointer)(unsafe.Pointer(&dispatchF)) = noescape(unsafe.Pointer(&dispatchFV))
+
+ var ok bool
+ defer func() {
+ if !ok {
+ err := recover()
+ debugCallPanicked(err)
+ }
+ }()
+ dispatchF()
+ ok = true
+}
diff --git a/contrib/go/_std_1.21/src/runtime/debuglog.go b/contrib/go/_std_1.21/src/runtime/debuglog.go
new file mode 100644
index 0000000000..873f1b45bd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/debuglog.go
@@ -0,0 +1,831 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file provides an internal debug logging facility. The debug
+// log is a lightweight, in-memory, per-M ring buffer. By default, the
+// runtime prints the debug log on panic.
+//
+// To print something to the debug log, call dlog to obtain a dlogger
+// and use the methods on that to add values. The values will be
+// space-separated in the output (much like println).
+//
+// This facility can be enabled by passing -tags debuglog when
+// building. Without this tag, dlog calls compile to nothing.
+
+package runtime
+
+import (
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// debugLogBytes is the size of each per-M ring buffer. This is
+// allocated off-heap to avoid blowing up the M and hence the GC'd
+// heap size.
+const debugLogBytes = 16 << 10
+
+// debugLogStringLimit is the maximum number of bytes in a string.
+// Above this, the string will be truncated with "..(n more bytes).."
+const debugLogStringLimit = debugLogBytes / 8
+
+// dlog returns a debug logger. The caller can use methods on the
+// returned logger to add values, which will be space-separated in the
+// final output, much like println. The caller must call end() to
+// finish the message.
+//
+// dlog can be used from highly-constrained corners of the runtime: it
+// is safe to use in the signal handler, from within the write
+// barrier, from within the stack implementation, and in places that
+// must be recursively nosplit.
+//
+// This will be compiled away if built without the debuglog build tag.
+// However, argument construction may not be. If any of the arguments
+// are not literals or trivial expressions, consider protecting the
+// call with "if dlogEnabled".
+//
+//go:nosplit
+//go:nowritebarrierrec
+func dlog() *dlogger {
+ if !dlogEnabled {
+ return nil
+ }
+
+ // Get the time.
+ tick, nano := uint64(cputicks()), uint64(nanotime())
+
+ // Try to get a cached logger.
+ l := getCachedDlogger()
+
+ // If we couldn't get a cached logger, try to get one from the
+ // global pool.
+ if l == nil {
+ allp := (*uintptr)(unsafe.Pointer(&allDloggers))
+ all := (*dlogger)(unsafe.Pointer(atomic.Loaduintptr(allp)))
+ for l1 := all; l1 != nil; l1 = l1.allLink {
+ if l1.owned.Load() == 0 && l1.owned.CompareAndSwap(0, 1) {
+ l = l1
+ break
+ }
+ }
+ }
+
+ // If that failed, allocate a new logger.
+ if l == nil {
+ // Use sysAllocOS instead of sysAlloc because we want to interfere
+ // with the runtime as little as possible, and sysAlloc updates accounting.
+ l = (*dlogger)(sysAllocOS(unsafe.Sizeof(dlogger{})))
+ if l == nil {
+ throw("failed to allocate debug log")
+ }
+ l.w.r.data = &l.w.data
+ l.owned.Store(1)
+
+ // Prepend to allDloggers list.
+ headp := (*uintptr)(unsafe.Pointer(&allDloggers))
+ for {
+ head := atomic.Loaduintptr(headp)
+ l.allLink = (*dlogger)(unsafe.Pointer(head))
+ if atomic.Casuintptr(headp, head, uintptr(unsafe.Pointer(l))) {
+ break
+ }
+ }
+ }
+
+ // If the time delta is getting too high, write a new sync
+ // packet. We set the limit so we don't write more than 6
+ // bytes of delta in the record header.
+ const deltaLimit = 1<<(3*7) - 1 // ~2ms between sync packets
+ if tick-l.w.tick > deltaLimit || nano-l.w.nano > deltaLimit {
+ l.w.writeSync(tick, nano)
+ }
+
+ // Reserve space for framing header.
+ l.w.ensure(debugLogHeaderSize)
+ l.w.write += debugLogHeaderSize
+
+ // Write record header.
+ l.w.uvarint(tick - l.w.tick)
+ l.w.uvarint(nano - l.w.nano)
+ gp := getg()
+ if gp != nil && gp.m != nil && gp.m.p != 0 {
+ l.w.varint(int64(gp.m.p.ptr().id))
+ } else {
+ l.w.varint(-1)
+ }
+
+ return l
+}
+
+// A dlogger writes to the debug log.
+//
+// To obtain a dlogger, call dlog(). When done with the dlogger, call
+// end().
+type dlogger struct {
+ _ sys.NotInHeap
+ w debugLogWriter
+
+ // allLink is the next dlogger in the allDloggers list.
+ allLink *dlogger
+
+ // owned indicates that this dlogger is owned by an M. This is
+ // accessed atomically.
+ owned atomic.Uint32
+}
+
+// allDloggers is a list of all dloggers, linked through
+// dlogger.allLink. This is accessed atomically. This is prepend only,
+// so it doesn't need to protect against ABA races.
+var allDloggers *dlogger
+
+//go:nosplit
+func (l *dlogger) end() {
+ if !dlogEnabled {
+ return
+ }
+
+ // Fill in framing header.
+ size := l.w.write - l.w.r.end
+ if !l.w.writeFrameAt(l.w.r.end, size) {
+ throw("record too large")
+ }
+
+ // Commit the record.
+ l.w.r.end = l.w.write
+
+ // Attempt to return this logger to the cache.
+ if putCachedDlogger(l) {
+ return
+ }
+
+ // Return the logger to the global pool.
+ l.owned.Store(0)
+}
+
+const (
+ debugLogUnknown = 1 + iota
+ debugLogBoolTrue
+ debugLogBoolFalse
+ debugLogInt
+ debugLogUint
+ debugLogHex
+ debugLogPtr
+ debugLogString
+ debugLogConstString
+ debugLogStringOverflow
+
+ debugLogPC
+ debugLogTraceback
+)
+
+//go:nosplit
+func (l *dlogger) b(x bool) *dlogger {
+ if !dlogEnabled {
+ return l
+ }
+ if x {
+ l.w.byte(debugLogBoolTrue)
+ } else {
+ l.w.byte(debugLogBoolFalse)
+ }
+ return l
+}
+
+//go:nosplit
+func (l *dlogger) i(x int) *dlogger {
+ return l.i64(int64(x))
+}
+
+//go:nosplit
+func (l *dlogger) i8(x int8) *dlogger {
+ return l.i64(int64(x))
+}
+
+//go:nosplit
+func (l *dlogger) i16(x int16) *dlogger {
+ return l.i64(int64(x))
+}
+
+//go:nosplit
+func (l *dlogger) i32(x int32) *dlogger {
+ return l.i64(int64(x))
+}
+
+//go:nosplit
+func (l *dlogger) i64(x int64) *dlogger {
+ if !dlogEnabled {
+ return l
+ }
+ l.w.byte(debugLogInt)
+ l.w.varint(x)
+ return l
+}
+
+//go:nosplit
+func (l *dlogger) u(x uint) *dlogger {
+ return l.u64(uint64(x))
+}
+
+//go:nosplit
+func (l *dlogger) uptr(x uintptr) *dlogger {
+ return l.u64(uint64(x))
+}
+
+//go:nosplit
+func (l *dlogger) u8(x uint8) *dlogger {
+ return l.u64(uint64(x))
+}
+
+//go:nosplit
+func (l *dlogger) u16(x uint16) *dlogger {
+ return l.u64(uint64(x))
+}
+
+//go:nosplit
+func (l *dlogger) u32(x uint32) *dlogger {
+ return l.u64(uint64(x))
+}
+
+//go:nosplit
+func (l *dlogger) u64(x uint64) *dlogger {
+ if !dlogEnabled {
+ return l
+ }
+ l.w.byte(debugLogUint)
+ l.w.uvarint(x)
+ return l
+}
+
+//go:nosplit
+func (l *dlogger) hex(x uint64) *dlogger {
+ if !dlogEnabled {
+ return l
+ }
+ l.w.byte(debugLogHex)
+ l.w.uvarint(x)
+ return l
+}
+
+//go:nosplit
+func (l *dlogger) p(x any) *dlogger {
+ if !dlogEnabled {
+ return l
+ }
+ l.w.byte(debugLogPtr)
+ if x == nil {
+ l.w.uvarint(0)
+ } else {
+ v := efaceOf(&x)
+ switch v._type.Kind_ & kindMask {
+ case kindChan, kindFunc, kindMap, kindPtr, kindUnsafePointer:
+ l.w.uvarint(uint64(uintptr(v.data)))
+ default:
+ throw("not a pointer type")
+ }
+ }
+ return l
+}
+
+//go:nosplit
+func (l *dlogger) s(x string) *dlogger {
+ if !dlogEnabled {
+ return l
+ }
+
+ strData := unsafe.StringData(x)
+ datap := &firstmoduledata
+ if len(x) > 4 && datap.etext <= uintptr(unsafe.Pointer(strData)) && uintptr(unsafe.Pointer(strData)) < datap.end {
+ // String constants are in the rodata section, which
+ // isn't recorded in moduledata. But it has to be
+ // somewhere between etext and end.
+ l.w.byte(debugLogConstString)
+ l.w.uvarint(uint64(len(x)))
+ l.w.uvarint(uint64(uintptr(unsafe.Pointer(strData)) - datap.etext))
+ } else {
+ l.w.byte(debugLogString)
+ // We can't use unsafe.Slice as it may panic, which isn't safe
+ // in this (potentially) nowritebarrier context.
+ var b []byte
+ bb := (*slice)(unsafe.Pointer(&b))
+ bb.array = unsafe.Pointer(strData)
+ bb.len, bb.cap = len(x), len(x)
+ if len(b) > debugLogStringLimit {
+ b = b[:debugLogStringLimit]
+ }
+ l.w.uvarint(uint64(len(b)))
+ l.w.bytes(b)
+ if len(b) != len(x) {
+ l.w.byte(debugLogStringOverflow)
+ l.w.uvarint(uint64(len(x) - len(b)))
+ }
+ }
+ return l
+}
+
+//go:nosplit
+func (l *dlogger) pc(x uintptr) *dlogger {
+ if !dlogEnabled {
+ return l
+ }
+ l.w.byte(debugLogPC)
+ l.w.uvarint(uint64(x))
+ return l
+}
+
+//go:nosplit
+func (l *dlogger) traceback(x []uintptr) *dlogger {
+ if !dlogEnabled {
+ return l
+ }
+ l.w.byte(debugLogTraceback)
+ l.w.uvarint(uint64(len(x)))
+ for _, pc := range x {
+ l.w.uvarint(uint64(pc))
+ }
+ return l
+}
+
+// A debugLogWriter is a ring buffer of binary debug log records.
+//
+// A log record consists of a 2-byte framing header and a sequence of
+// fields. The framing header gives the size of the record as a little
+// endian 16-bit value. Each field starts with a byte indicating its
+// type, followed by type-specific data. If the size in the framing
+// header is 0, it's a sync record consisting of two little endian
+// 64-bit values giving a new time base.
+//
+// Because this is a ring buffer, new records will eventually
+// overwrite old records. Hence, it maintains a reader that consumes
+// the log as it gets overwritten. That reader state is where an
+// actual log reader would start.
+type debugLogWriter struct {
+ _ sys.NotInHeap
+ write uint64
+ data debugLogBuf
+
+ // tick and nano are the time bases from the most recently
+ // written sync record.
+ tick, nano uint64
+
+ // r is a reader that consumes records as they get overwritten
+ // by the writer. It also acts as the initial reader state
+ // when printing the log.
+ r debugLogReader
+
+ // buf is a scratch buffer for encoding. This is here to
+ // reduce stack usage.
+ buf [10]byte
+}
+
+type debugLogBuf struct {
+ _ sys.NotInHeap
+ b [debugLogBytes]byte
+}
+
+const (
+ // debugLogHeaderSize is the number of bytes in the framing
+ // header of every dlog record.
+ debugLogHeaderSize = 2
+
+ // debugLogSyncSize is the number of bytes in a sync record.
+ debugLogSyncSize = debugLogHeaderSize + 2*8
+)
+
+//go:nosplit
+func (l *debugLogWriter) ensure(n uint64) {
+ for l.write+n >= l.r.begin+uint64(len(l.data.b)) {
+ // Consume record at begin.
+ if l.r.skip() == ^uint64(0) {
+ // Wrapped around within a record.
+ //
+ // TODO(austin): It would be better to just
+ // eat the whole buffer at this point, but we
+ // have to communicate that to the reader
+ // somehow.
+ throw("record wrapped around")
+ }
+ }
+}
+
+//go:nosplit
+func (l *debugLogWriter) writeFrameAt(pos, size uint64) bool {
+ l.data.b[pos%uint64(len(l.data.b))] = uint8(size)
+ l.data.b[(pos+1)%uint64(len(l.data.b))] = uint8(size >> 8)
+ return size <= 0xFFFF
+}
+
+//go:nosplit
+func (l *debugLogWriter) writeSync(tick, nano uint64) {
+ l.tick, l.nano = tick, nano
+ l.ensure(debugLogHeaderSize)
+ l.writeFrameAt(l.write, 0)
+ l.write += debugLogHeaderSize
+ l.writeUint64LE(tick)
+ l.writeUint64LE(nano)
+ l.r.end = l.write
+}
+
+//go:nosplit
+func (l *debugLogWriter) writeUint64LE(x uint64) {
+ var b [8]byte
+ b[0] = byte(x)
+ b[1] = byte(x >> 8)
+ b[2] = byte(x >> 16)
+ b[3] = byte(x >> 24)
+ b[4] = byte(x >> 32)
+ b[5] = byte(x >> 40)
+ b[6] = byte(x >> 48)
+ b[7] = byte(x >> 56)
+ l.bytes(b[:])
+}
+
+//go:nosplit
+func (l *debugLogWriter) byte(x byte) {
+ l.ensure(1)
+ pos := l.write
+ l.write++
+ l.data.b[pos%uint64(len(l.data.b))] = x
+}
+
+//go:nosplit
+func (l *debugLogWriter) bytes(x []byte) {
+ l.ensure(uint64(len(x)))
+ pos := l.write
+ l.write += uint64(len(x))
+ for len(x) > 0 {
+ n := copy(l.data.b[pos%uint64(len(l.data.b)):], x)
+ pos += uint64(n)
+ x = x[n:]
+ }
+}
+
+//go:nosplit
+func (l *debugLogWriter) varint(x int64) {
+ var u uint64
+ if x < 0 {
+ u = (^uint64(x) << 1) | 1 // complement i, bit 0 is 1
+ } else {
+ u = (uint64(x) << 1) // do not complement i, bit 0 is 0
+ }
+ l.uvarint(u)
+}
+
+//go:nosplit
+func (l *debugLogWriter) uvarint(u uint64) {
+ i := 0
+ for u >= 0x80 {
+ l.buf[i] = byte(u) | 0x80
+ u >>= 7
+ i++
+ }
+ l.buf[i] = byte(u)
+ i++
+ l.bytes(l.buf[:i])
+}
+
+type debugLogReader struct {
+ data *debugLogBuf
+
+ // begin and end are the positions in the log of the beginning
+ // and end of the log data, modulo len(data).
+ begin, end uint64
+
+ // tick and nano are the current time base at begin.
+ tick, nano uint64
+}
+
+//go:nosplit
+func (r *debugLogReader) skip() uint64 {
+ // Read size at pos.
+ if r.begin+debugLogHeaderSize > r.end {
+ return ^uint64(0)
+ }
+ size := uint64(r.readUint16LEAt(r.begin))
+ if size == 0 {
+ // Sync packet.
+ r.tick = r.readUint64LEAt(r.begin + debugLogHeaderSize)
+ r.nano = r.readUint64LEAt(r.begin + debugLogHeaderSize + 8)
+ size = debugLogSyncSize
+ }
+ if r.begin+size > r.end {
+ return ^uint64(0)
+ }
+ r.begin += size
+ return size
+}
+
+//go:nosplit
+func (r *debugLogReader) readUint16LEAt(pos uint64) uint16 {
+ return uint16(r.data.b[pos%uint64(len(r.data.b))]) |
+ uint16(r.data.b[(pos+1)%uint64(len(r.data.b))])<<8
+}
+
+//go:nosplit
+func (r *debugLogReader) readUint64LEAt(pos uint64) uint64 {
+ var b [8]byte
+ for i := range b {
+ b[i] = r.data.b[pos%uint64(len(r.data.b))]
+ pos++
+ }
+ return uint64(b[0]) | uint64(b[1])<<8 |
+ uint64(b[2])<<16 | uint64(b[3])<<24 |
+ uint64(b[4])<<32 | uint64(b[5])<<40 |
+ uint64(b[6])<<48 | uint64(b[7])<<56
+}
+
+func (r *debugLogReader) peek() (tick uint64) {
+ // Consume any sync records.
+ size := uint64(0)
+ for size == 0 {
+ if r.begin+debugLogHeaderSize > r.end {
+ return ^uint64(0)
+ }
+ size = uint64(r.readUint16LEAt(r.begin))
+ if size != 0 {
+ break
+ }
+ if r.begin+debugLogSyncSize > r.end {
+ return ^uint64(0)
+ }
+ // Sync packet.
+ r.tick = r.readUint64LEAt(r.begin + debugLogHeaderSize)
+ r.nano = r.readUint64LEAt(r.begin + debugLogHeaderSize + 8)
+ r.begin += debugLogSyncSize
+ }
+
+ // Peek tick delta.
+ if r.begin+size > r.end {
+ return ^uint64(0)
+ }
+ pos := r.begin + debugLogHeaderSize
+ var u uint64
+ for i := uint(0); ; i += 7 {
+ b := r.data.b[pos%uint64(len(r.data.b))]
+ pos++
+ u |= uint64(b&^0x80) << i
+ if b&0x80 == 0 {
+ break
+ }
+ }
+ if pos > r.begin+size {
+ return ^uint64(0)
+ }
+ return r.tick + u
+}
+
+func (r *debugLogReader) header() (end, tick, nano uint64, p int) {
+ // Read size. We've already skipped sync packets and checked
+ // bounds in peek.
+ size := uint64(r.readUint16LEAt(r.begin))
+ end = r.begin + size
+ r.begin += debugLogHeaderSize
+
+ // Read tick, nano, and p.
+ tick = r.uvarint() + r.tick
+ nano = r.uvarint() + r.nano
+ p = int(r.varint())
+
+ return
+}
+
+func (r *debugLogReader) uvarint() uint64 {
+ var u uint64
+ for i := uint(0); ; i += 7 {
+ b := r.data.b[r.begin%uint64(len(r.data.b))]
+ r.begin++
+ u |= uint64(b&^0x80) << i
+ if b&0x80 == 0 {
+ break
+ }
+ }
+ return u
+}
+
+func (r *debugLogReader) varint() int64 {
+ u := r.uvarint()
+ var v int64
+ if u&1 == 0 {
+ v = int64(u >> 1)
+ } else {
+ v = ^int64(u >> 1)
+ }
+ return v
+}
+
+func (r *debugLogReader) printVal() bool {
+ typ := r.data.b[r.begin%uint64(len(r.data.b))]
+ r.begin++
+
+ switch typ {
+ default:
+ print("<unknown field type ", hex(typ), " pos ", r.begin-1, " end ", r.end, ">\n")
+ return false
+
+ case debugLogUnknown:
+ print("<unknown kind>")
+
+ case debugLogBoolTrue:
+ print(true)
+
+ case debugLogBoolFalse:
+ print(false)
+
+ case debugLogInt:
+ print(r.varint())
+
+ case debugLogUint:
+ print(r.uvarint())
+
+ case debugLogHex, debugLogPtr:
+ print(hex(r.uvarint()))
+
+ case debugLogString:
+ sl := r.uvarint()
+ if r.begin+sl > r.end {
+ r.begin = r.end
+ print("<string length corrupted>")
+ break
+ }
+ for sl > 0 {
+ b := r.data.b[r.begin%uint64(len(r.data.b)):]
+ if uint64(len(b)) > sl {
+ b = b[:sl]
+ }
+ r.begin += uint64(len(b))
+ sl -= uint64(len(b))
+ gwrite(b)
+ }
+
+ case debugLogConstString:
+ len, ptr := int(r.uvarint()), uintptr(r.uvarint())
+ ptr += firstmoduledata.etext
+ // We can't use unsafe.String as it may panic, which isn't safe
+ // in this (potentially) nowritebarrier context.
+ str := stringStruct{
+ str: unsafe.Pointer(ptr),
+ len: len,
+ }
+ s := *(*string)(unsafe.Pointer(&str))
+ print(s)
+
+ case debugLogStringOverflow:
+ print("..(", r.uvarint(), " more bytes)..")
+
+ case debugLogPC:
+ printDebugLogPC(uintptr(r.uvarint()), false)
+
+ case debugLogTraceback:
+ n := int(r.uvarint())
+ for i := 0; i < n; i++ {
+ print("\n\t")
+ // gentraceback PCs are always return PCs.
+ // Convert them to call PCs.
+ //
+ // TODO(austin): Expand inlined frames.
+ printDebugLogPC(uintptr(r.uvarint()), true)
+ }
+ }
+
+ return true
+}
+
+// printDebugLog prints the debug log.
+func printDebugLog() {
+ if !dlogEnabled {
+ return
+ }
+
+ // This function should not panic or throw since it is used in
+ // the fatal panic path and this may deadlock.
+
+ printlock()
+
+ // Get the list of all debug logs.
+ allp := (*uintptr)(unsafe.Pointer(&allDloggers))
+ all := (*dlogger)(unsafe.Pointer(atomic.Loaduintptr(allp)))
+
+ // Count the logs.
+ n := 0
+ for l := all; l != nil; l = l.allLink {
+ n++
+ }
+ if n == 0 {
+ printunlock()
+ return
+ }
+
+ // Prepare read state for all logs.
+ type readState struct {
+ debugLogReader
+ first bool
+ lost uint64
+ nextTick uint64
+ }
+ // Use sysAllocOS instead of sysAlloc because we want to interfere
+ // with the runtime as little as possible, and sysAlloc updates accounting.
+ state1 := sysAllocOS(unsafe.Sizeof(readState{}) * uintptr(n))
+ if state1 == nil {
+ println("failed to allocate read state for", n, "logs")
+ printunlock()
+ return
+ }
+ state := (*[1 << 20]readState)(state1)[:n]
+ {
+ l := all
+ for i := range state {
+ s := &state[i]
+ s.debugLogReader = l.w.r
+ s.first = true
+ s.lost = l.w.r.begin
+ s.nextTick = s.peek()
+ l = l.allLink
+ }
+ }
+
+ // Print records.
+ for {
+ // Find the next record.
+ var best struct {
+ tick uint64
+ i int
+ }
+ best.tick = ^uint64(0)
+ for i := range state {
+ if state[i].nextTick < best.tick {
+ best.tick = state[i].nextTick
+ best.i = i
+ }
+ }
+ if best.tick == ^uint64(0) {
+ break
+ }
+
+ // Print record.
+ s := &state[best.i]
+ if s.first {
+ print(">> begin log ", best.i)
+ if s.lost != 0 {
+ print("; lost first ", s.lost>>10, "KB")
+ }
+ print(" <<\n")
+ s.first = false
+ }
+
+ end, _, nano, p := s.header()
+ oldEnd := s.end
+ s.end = end
+
+ print("[")
+ var tmpbuf [21]byte
+ pnano := int64(nano) - runtimeInitTime
+ if pnano < 0 {
+ // Logged before runtimeInitTime was set.
+ pnano = 0
+ }
+ pnanoBytes := itoaDiv(tmpbuf[:], uint64(pnano), 9)
+ print(slicebytetostringtmp((*byte)(noescape(unsafe.Pointer(&pnanoBytes[0]))), len(pnanoBytes)))
+ print(" P ", p, "] ")
+
+ for i := 0; s.begin < s.end; i++ {
+ if i > 0 {
+ print(" ")
+ }
+ if !s.printVal() {
+ // Abort this P log.
+ print("<aborting P log>")
+ end = oldEnd
+ break
+ }
+ }
+ println()
+
+ // Move on to the next record.
+ s.begin = end
+ s.end = oldEnd
+ s.nextTick = s.peek()
+ }
+
+ printunlock()
+}
+
+// printDebugLogPC prints a single symbolized PC. If returnPC is true,
+// pc is a return PC that must first be converted to a call PC.
+func printDebugLogPC(pc uintptr, returnPC bool) {
+ fn := findfunc(pc)
+ if returnPC && (!fn.valid() || pc > fn.entry()) {
+ // TODO(austin): Don't back up if the previous frame
+ // was a sigpanic.
+ pc--
+ }
+
+ print(hex(pc))
+ if !fn.valid() {
+ print(" [unknown PC]")
+ } else {
+ name := funcname(fn)
+ file, line := funcline(fn, pc)
+ print(" [", name, "+", hex(pc-fn.entry()),
+ " ", file, ":", line, "]")
+ }
+}
diff --git a/contrib/go/_std_1.20/src/runtime/debuglog_off.go b/contrib/go/_std_1.21/src/runtime/debuglog_off.go
index fa3be39c70..fa3be39c70 100644
--- a/contrib/go/_std_1.20/src/runtime/debuglog_off.go
+++ b/contrib/go/_std_1.21/src/runtime/debuglog_off.go
diff --git a/contrib/go/_std_1.21/src/runtime/defs_darwin_amd64.go b/contrib/go/_std_1.21/src/runtime/defs_darwin_amd64.go
new file mode 100644
index 0000000000..fc7de3330a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/defs_darwin_amd64.go
@@ -0,0 +1,373 @@
+// created by cgo -cdefs and then converted to Go
+// cgo -cdefs defs_darwin.go
+
+package runtime
+
+import "unsafe"
+
+const (
+ _EINTR = 0x4
+ _EFAULT = 0xe
+ _EAGAIN = 0x23
+ _ETIMEDOUT = 0x3c
+
+ _PROT_NONE = 0x0
+ _PROT_READ = 0x1
+ _PROT_WRITE = 0x2
+ _PROT_EXEC = 0x4
+
+ _MAP_ANON = 0x1000
+ _MAP_PRIVATE = 0x2
+ _MAP_FIXED = 0x10
+
+ _MADV_DONTNEED = 0x4
+ _MADV_FREE = 0x5
+ _MADV_FREE_REUSABLE = 0x7
+ _MADV_FREE_REUSE = 0x8
+
+ _SA_SIGINFO = 0x40
+ _SA_RESTART = 0x2
+ _SA_ONSTACK = 0x1
+ _SA_USERTRAMP = 0x100
+ _SA_64REGSET = 0x200
+
+ _SIGHUP = 0x1
+ _SIGINT = 0x2
+ _SIGQUIT = 0x3
+ _SIGILL = 0x4
+ _SIGTRAP = 0x5
+ _SIGABRT = 0x6
+ _SIGEMT = 0x7
+ _SIGFPE = 0x8
+ _SIGKILL = 0x9
+ _SIGBUS = 0xa
+ _SIGSEGV = 0xb
+ _SIGSYS = 0xc
+ _SIGPIPE = 0xd
+ _SIGALRM = 0xe
+ _SIGTERM = 0xf
+ _SIGURG = 0x10
+ _SIGSTOP = 0x11
+ _SIGTSTP = 0x12
+ _SIGCONT = 0x13
+ _SIGCHLD = 0x14
+ _SIGTTIN = 0x15
+ _SIGTTOU = 0x16
+ _SIGIO = 0x17
+ _SIGXCPU = 0x18
+ _SIGXFSZ = 0x19
+ _SIGVTALRM = 0x1a
+ _SIGPROF = 0x1b
+ _SIGWINCH = 0x1c
+ _SIGINFO = 0x1d
+ _SIGUSR1 = 0x1e
+ _SIGUSR2 = 0x1f
+
+ _FPE_INTDIV = 0x7
+ _FPE_INTOVF = 0x8
+ _FPE_FLTDIV = 0x1
+ _FPE_FLTOVF = 0x2
+ _FPE_FLTUND = 0x3
+ _FPE_FLTRES = 0x4
+ _FPE_FLTINV = 0x5
+ _FPE_FLTSUB = 0x6
+
+ _BUS_ADRALN = 0x1
+ _BUS_ADRERR = 0x2
+ _BUS_OBJERR = 0x3
+
+ _SEGV_MAPERR = 0x1
+ _SEGV_ACCERR = 0x2
+
+ _ITIMER_REAL = 0x0
+ _ITIMER_VIRTUAL = 0x1
+ _ITIMER_PROF = 0x2
+
+ _EV_ADD = 0x1
+ _EV_DELETE = 0x2
+ _EV_CLEAR = 0x20
+ _EV_RECEIPT = 0x40
+ _EV_ERROR = 0x4000
+ _EV_EOF = 0x8000
+ _EVFILT_READ = -0x1
+ _EVFILT_WRITE = -0x2
+
+ _PTHREAD_CREATE_DETACHED = 0x2
+
+ _F_GETFL = 0x3
+ _F_SETFL = 0x4
+
+ _O_WRONLY = 0x1
+ _O_NONBLOCK = 0x4
+ _O_CREAT = 0x200
+ _O_TRUNC = 0x400
+)
+
+type stackt struct {
+ ss_sp *byte
+ ss_size uintptr
+ ss_flags int32
+ pad_cgo_0 [4]byte
+}
+
+type sigactiont struct {
+ __sigaction_u [8]byte
+ sa_tramp unsafe.Pointer
+ sa_mask uint32
+ sa_flags int32
+}
+
+type usigactiont struct {
+ __sigaction_u [8]byte
+ sa_mask uint32
+ sa_flags int32
+}
+
+type siginfo struct {
+ si_signo int32
+ si_errno int32
+ si_code int32
+ si_pid int32
+ si_uid uint32
+ si_status int32
+ si_addr uint64
+ si_value [8]byte
+ si_band int64
+ __pad [7]uint64
+}
+
+type timeval struct {
+ tv_sec int64
+ tv_usec int32
+ pad_cgo_0 [4]byte
+}
+
+func (tv *timeval) set_usec(x int32) {
+ tv.tv_usec = x
+}
+
+type itimerval struct {
+ it_interval timeval
+ it_value timeval
+}
+
+type timespec struct {
+ tv_sec int64
+ tv_nsec int64
+}
+
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+ ts.tv_sec = ns / 1e9
+ ts.tv_nsec = ns % 1e9
+}
+
+type fpcontrol struct {
+ pad_cgo_0 [2]byte
+}
+
+type fpstatus struct {
+ pad_cgo_0 [2]byte
+}
+
+type regmmst struct {
+ mmst_reg [10]int8
+ mmst_rsrv [6]int8
+}
+
+type regxmm struct {
+ xmm_reg [16]int8
+}
+
+type regs64 struct {
+ rax uint64
+ rbx uint64
+ rcx uint64
+ rdx uint64
+ rdi uint64
+ rsi uint64
+ rbp uint64
+ rsp uint64
+ r8 uint64
+ r9 uint64
+ r10 uint64
+ r11 uint64
+ r12 uint64
+ r13 uint64
+ r14 uint64
+ r15 uint64
+ rip uint64
+ rflags uint64
+ cs uint64
+ fs uint64
+ gs uint64
+}
+
+type floatstate64 struct {
+ fpu_reserved [2]int32
+ fpu_fcw fpcontrol
+ fpu_fsw fpstatus
+ fpu_ftw uint8
+ fpu_rsrv1 uint8
+ fpu_fop uint16
+ fpu_ip uint32
+ fpu_cs uint16
+ fpu_rsrv2 uint16
+ fpu_dp uint32
+ fpu_ds uint16
+ fpu_rsrv3 uint16
+ fpu_mxcsr uint32
+ fpu_mxcsrmask uint32
+ fpu_stmm0 regmmst
+ fpu_stmm1 regmmst
+ fpu_stmm2 regmmst
+ fpu_stmm3 regmmst
+ fpu_stmm4 regmmst
+ fpu_stmm5 regmmst
+ fpu_stmm6 regmmst
+ fpu_stmm7 regmmst
+ fpu_xmm0 regxmm
+ fpu_xmm1 regxmm
+ fpu_xmm2 regxmm
+ fpu_xmm3 regxmm
+ fpu_xmm4 regxmm
+ fpu_xmm5 regxmm
+ fpu_xmm6 regxmm
+ fpu_xmm7 regxmm
+ fpu_xmm8 regxmm
+ fpu_xmm9 regxmm
+ fpu_xmm10 regxmm
+ fpu_xmm11 regxmm
+ fpu_xmm12 regxmm
+ fpu_xmm13 regxmm
+ fpu_xmm14 regxmm
+ fpu_xmm15 regxmm
+ fpu_rsrv4 [96]int8
+ fpu_reserved1 int32
+}
+
+type exceptionstate64 struct {
+ trapno uint16
+ cpu uint16
+ err uint32
+ faultvaddr uint64
+}
+
+type mcontext64 struct {
+ es exceptionstate64
+ ss regs64
+ fs floatstate64
+ pad_cgo_0 [4]byte
+}
+
+type regs32 struct {
+ eax uint32
+ ebx uint32
+ ecx uint32
+ edx uint32
+ edi uint32
+ esi uint32
+ ebp uint32
+ esp uint32
+ ss uint32
+ eflags uint32
+ eip uint32
+ cs uint32
+ ds uint32
+ es uint32
+ fs uint32
+ gs uint32
+}
+
+type floatstate32 struct {
+ fpu_reserved [2]int32
+ fpu_fcw fpcontrol
+ fpu_fsw fpstatus
+ fpu_ftw uint8
+ fpu_rsrv1 uint8
+ fpu_fop uint16
+ fpu_ip uint32
+ fpu_cs uint16
+ fpu_rsrv2 uint16
+ fpu_dp uint32
+ fpu_ds uint16
+ fpu_rsrv3 uint16
+ fpu_mxcsr uint32
+ fpu_mxcsrmask uint32
+ fpu_stmm0 regmmst
+ fpu_stmm1 regmmst
+ fpu_stmm2 regmmst
+ fpu_stmm3 regmmst
+ fpu_stmm4 regmmst
+ fpu_stmm5 regmmst
+ fpu_stmm6 regmmst
+ fpu_stmm7 regmmst
+ fpu_xmm0 regxmm
+ fpu_xmm1 regxmm
+ fpu_xmm2 regxmm
+ fpu_xmm3 regxmm
+ fpu_xmm4 regxmm
+ fpu_xmm5 regxmm
+ fpu_xmm6 regxmm
+ fpu_xmm7 regxmm
+ fpu_rsrv4 [224]int8
+ fpu_reserved1 int32
+}
+
+type exceptionstate32 struct {
+ trapno uint16
+ cpu uint16
+ err uint32
+ faultvaddr uint32
+}
+
+type mcontext32 struct {
+ es exceptionstate32
+ ss regs32
+ fs floatstate32
+}
+
+type ucontext struct {
+ uc_onstack int32
+ uc_sigmask uint32
+ uc_stack stackt
+ uc_link *ucontext
+ uc_mcsize uint64
+ uc_mcontext *mcontext64
+}
+
+type keventt struct {
+ ident uint64
+ filter int16
+ flags uint16
+ fflags uint32
+ data int64
+ udata *byte
+}
+
+type pthread uintptr
+type pthreadattr struct {
+ X__sig int64
+ X__opaque [56]int8
+}
+type pthreadmutex struct {
+ X__sig int64
+ X__opaque [56]int8
+}
+type pthreadmutexattr struct {
+ X__sig int64
+ X__opaque [8]int8
+}
+type pthreadcond struct {
+ X__sig int64
+ X__opaque [40]int8
+}
+type pthreadcondattr struct {
+ X__sig int64
+ X__opaque [8]int8
+}
+
+type machTimebaseInfo struct {
+ numer uint32
+ denom uint32
+}
diff --git a/contrib/go/_std_1.21/src/runtime/defs_linux_amd64.go b/contrib/go/_std_1.21/src/runtime/defs_linux_amd64.go
new file mode 100644
index 0000000000..dce7799b6a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/defs_linux_amd64.go
@@ -0,0 +1,289 @@
+// created by cgo -cdefs and then converted to Go
+// cgo -cdefs defs_linux.go defs1_linux.go
+
+package runtime
+
+import "unsafe"
+
+const (
+ _EINTR = 0x4
+ _EAGAIN = 0xb
+ _ENOMEM = 0xc
+
+ _PROT_NONE = 0x0
+ _PROT_READ = 0x1
+ _PROT_WRITE = 0x2
+ _PROT_EXEC = 0x4
+
+ _MAP_ANON = 0x20
+ _MAP_PRIVATE = 0x2
+ _MAP_FIXED = 0x10
+
+ _MADV_DONTNEED = 0x4
+ _MADV_FREE = 0x8
+ _MADV_HUGEPAGE = 0xe
+ _MADV_NOHUGEPAGE = 0xf
+ _MADV_COLLAPSE = 0x19
+
+ _SA_RESTART = 0x10000000
+ _SA_ONSTACK = 0x8000000
+ _SA_RESTORER = 0x4000000
+ _SA_SIGINFO = 0x4
+
+ _SI_KERNEL = 0x80
+ _SI_TIMER = -0x2
+
+ _SIGHUP = 0x1
+ _SIGINT = 0x2
+ _SIGQUIT = 0x3
+ _SIGILL = 0x4
+ _SIGTRAP = 0x5
+ _SIGABRT = 0x6
+ _SIGBUS = 0x7
+ _SIGFPE = 0x8
+ _SIGKILL = 0x9
+ _SIGUSR1 = 0xa
+ _SIGSEGV = 0xb
+ _SIGUSR2 = 0xc
+ _SIGPIPE = 0xd
+ _SIGALRM = 0xe
+ _SIGSTKFLT = 0x10
+ _SIGCHLD = 0x11
+ _SIGCONT = 0x12
+ _SIGSTOP = 0x13
+ _SIGTSTP = 0x14
+ _SIGTTIN = 0x15
+ _SIGTTOU = 0x16
+ _SIGURG = 0x17
+ _SIGXCPU = 0x18
+ _SIGXFSZ = 0x19
+ _SIGVTALRM = 0x1a
+ _SIGPROF = 0x1b
+ _SIGWINCH = 0x1c
+ _SIGIO = 0x1d
+ _SIGPWR = 0x1e
+ _SIGSYS = 0x1f
+
+ _SIGRTMIN = 0x20
+
+ _FPE_INTDIV = 0x1
+ _FPE_INTOVF = 0x2
+ _FPE_FLTDIV = 0x3
+ _FPE_FLTOVF = 0x4
+ _FPE_FLTUND = 0x5
+ _FPE_FLTRES = 0x6
+ _FPE_FLTINV = 0x7
+ _FPE_FLTSUB = 0x8
+
+ _BUS_ADRALN = 0x1
+ _BUS_ADRERR = 0x2
+ _BUS_OBJERR = 0x3
+
+ _SEGV_MAPERR = 0x1
+ _SEGV_ACCERR = 0x2
+
+ _ITIMER_REAL = 0x0
+ _ITIMER_VIRTUAL = 0x1
+ _ITIMER_PROF = 0x2
+
+ _CLOCK_THREAD_CPUTIME_ID = 0x3
+
+ _SIGEV_THREAD_ID = 0x4
+
+ _AF_UNIX = 0x1
+ _SOCK_DGRAM = 0x2
+)
+
+type timespec struct {
+ tv_sec int64
+ tv_nsec int64
+}
+
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+ ts.tv_sec = ns / 1e9
+ ts.tv_nsec = ns % 1e9
+}
+
+type timeval struct {
+ tv_sec int64
+ tv_usec int64
+}
+
+func (tv *timeval) set_usec(x int32) {
+ tv.tv_usec = int64(x)
+}
+
+type sigactiont struct {
+ sa_handler uintptr
+ sa_flags uint64
+ sa_restorer uintptr
+ sa_mask uint64
+}
+
+type siginfoFields struct {
+ si_signo int32
+ si_errno int32
+ si_code int32
+ // below here is a union; si_addr is the only field we use
+ si_addr uint64
+}
+
+type siginfo struct {
+ siginfoFields
+
+ // Pad struct to the max size in the kernel.
+ _ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
+}
+
+type itimerspec struct {
+ it_interval timespec
+ it_value timespec
+}
+
+type itimerval struct {
+ it_interval timeval
+ it_value timeval
+}
+
+type sigeventFields struct {
+ value uintptr
+ signo int32
+ notify int32
+ // below here is a union; sigev_notify_thread_id is the only field we use
+ sigev_notify_thread_id int32
+}
+
+type sigevent struct {
+ sigeventFields
+
+ // Pad struct to the max size in the kernel.
+ _ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
+}
+
+// created by cgo -cdefs and then converted to Go
+// cgo -cdefs defs_linux.go defs1_linux.go
+
+const (
+ _O_RDONLY = 0x0
+ _O_WRONLY = 0x1
+ _O_CREAT = 0x40
+ _O_TRUNC = 0x200
+ _O_NONBLOCK = 0x800
+ _O_CLOEXEC = 0x80000
+)
+
+type usigset struct {
+ __val [16]uint64
+}
+
+type fpxreg struct {
+ significand [4]uint16
+ exponent uint16
+ padding [3]uint16
+}
+
+type xmmreg struct {
+ element [4]uint32
+}
+
+type fpstate struct {
+ cwd uint16
+ swd uint16
+ ftw uint16
+ fop uint16
+ rip uint64
+ rdp uint64
+ mxcsr uint32
+ mxcr_mask uint32
+ _st [8]fpxreg
+ _xmm [16]xmmreg
+ padding [24]uint32
+}
+
+type fpxreg1 struct {
+ significand [4]uint16
+ exponent uint16
+ padding [3]uint16
+}
+
+type xmmreg1 struct {
+ element [4]uint32
+}
+
+type fpstate1 struct {
+ cwd uint16
+ swd uint16
+ ftw uint16
+ fop uint16
+ rip uint64
+ rdp uint64
+ mxcsr uint32
+ mxcr_mask uint32
+ _st [8]fpxreg1
+ _xmm [16]xmmreg1
+ padding [24]uint32
+}
+
+type fpreg1 struct {
+ significand [4]uint16
+ exponent uint16
+}
+
+type stackt struct {
+ ss_sp *byte
+ ss_flags int32
+ pad_cgo_0 [4]byte
+ ss_size uintptr
+}
+
+type mcontext struct {
+ gregs [23]uint64
+ fpregs *fpstate
+ __reserved1 [8]uint64
+}
+
+type ucontext struct {
+ uc_flags uint64
+ uc_link *ucontext
+ uc_stack stackt
+ uc_mcontext mcontext
+ uc_sigmask usigset
+ __fpregs_mem fpstate
+}
+
+type sigcontext struct {
+ r8 uint64
+ r9 uint64
+ r10 uint64
+ r11 uint64
+ r12 uint64
+ r13 uint64
+ r14 uint64
+ r15 uint64
+ rdi uint64
+ rsi uint64
+ rbp uint64
+ rbx uint64
+ rdx uint64
+ rax uint64
+ rcx uint64
+ rsp uint64
+ rip uint64
+ eflags uint64
+ cs uint16
+ gs uint16
+ fs uint16
+ __pad0 uint16
+ err uint64
+ trapno uint64
+ oldmask uint64
+ cr2 uint64
+ fpstate *fpstate1
+ __reserved1 [8]uint64
+}
+
+type sockaddr_un struct {
+ family uint16
+ path [108]byte
+}
diff --git a/contrib/go/_std_1.21/src/runtime/defs_linux_arm64.go b/contrib/go/_std_1.21/src/runtime/defs_linux_arm64.go
new file mode 100644
index 0000000000..606cd70494
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/defs_linux_arm64.go
@@ -0,0 +1,211 @@
+// Created by cgo -cdefs and converted (by hand) to Go
+// ../cmd/cgo/cgo -cdefs defs_linux.go defs1_linux.go defs2_linux.go
+
+package runtime
+
+import "unsafe"
+
+const (
+ _EINTR = 0x4
+ _EAGAIN = 0xb
+ _ENOMEM = 0xc
+
+ _PROT_NONE = 0x0
+ _PROT_READ = 0x1
+ _PROT_WRITE = 0x2
+ _PROT_EXEC = 0x4
+
+ _MAP_ANON = 0x20
+ _MAP_PRIVATE = 0x2
+ _MAP_FIXED = 0x10
+
+ _MADV_DONTNEED = 0x4
+ _MADV_FREE = 0x8
+ _MADV_HUGEPAGE = 0xe
+ _MADV_NOHUGEPAGE = 0xf
+ _MADV_COLLAPSE = 0x19
+
+ _SA_RESTART = 0x10000000
+ _SA_ONSTACK = 0x8000000
+ _SA_RESTORER = 0x0 // Only used on intel
+ _SA_SIGINFO = 0x4
+
+ _SI_KERNEL = 0x80
+ _SI_TIMER = -0x2
+
+ _SIGHUP = 0x1
+ _SIGINT = 0x2
+ _SIGQUIT = 0x3
+ _SIGILL = 0x4
+ _SIGTRAP = 0x5
+ _SIGABRT = 0x6
+ _SIGBUS = 0x7
+ _SIGFPE = 0x8
+ _SIGKILL = 0x9
+ _SIGUSR1 = 0xa
+ _SIGSEGV = 0xb
+ _SIGUSR2 = 0xc
+ _SIGPIPE = 0xd
+ _SIGALRM = 0xe
+ _SIGSTKFLT = 0x10
+ _SIGCHLD = 0x11
+ _SIGCONT = 0x12
+ _SIGSTOP = 0x13
+ _SIGTSTP = 0x14
+ _SIGTTIN = 0x15
+ _SIGTTOU = 0x16
+ _SIGURG = 0x17
+ _SIGXCPU = 0x18
+ _SIGXFSZ = 0x19
+ _SIGVTALRM = 0x1a
+ _SIGPROF = 0x1b
+ _SIGWINCH = 0x1c
+ _SIGIO = 0x1d
+ _SIGPWR = 0x1e
+ _SIGSYS = 0x1f
+
+ _SIGRTMIN = 0x20
+
+ _FPE_INTDIV = 0x1
+ _FPE_INTOVF = 0x2
+ _FPE_FLTDIV = 0x3
+ _FPE_FLTOVF = 0x4
+ _FPE_FLTUND = 0x5
+ _FPE_FLTRES = 0x6
+ _FPE_FLTINV = 0x7
+ _FPE_FLTSUB = 0x8
+
+ _BUS_ADRALN = 0x1
+ _BUS_ADRERR = 0x2
+ _BUS_OBJERR = 0x3
+
+ _SEGV_MAPERR = 0x1
+ _SEGV_ACCERR = 0x2
+
+ _ITIMER_REAL = 0x0
+ _ITIMER_VIRTUAL = 0x1
+ _ITIMER_PROF = 0x2
+
+ _CLOCK_THREAD_CPUTIME_ID = 0x3
+
+ _SIGEV_THREAD_ID = 0x4
+
+ _AF_UNIX = 0x1
+ _SOCK_DGRAM = 0x2
+)
+
+type timespec struct {
+ tv_sec int64
+ tv_nsec int64
+}
+
+//go:nosplit
+func (ts *timespec) setNsec(ns int64) {
+ ts.tv_sec = ns / 1e9
+ ts.tv_nsec = ns % 1e9
+}
+
+type timeval struct {
+ tv_sec int64
+ tv_usec int64
+}
+
+func (tv *timeval) set_usec(x int32) {
+ tv.tv_usec = int64(x)
+}
+
+type sigactiont struct {
+ sa_handler uintptr
+ sa_flags uint64
+ sa_restorer uintptr
+ sa_mask uint64
+}
+
+type siginfoFields struct {
+ si_signo int32
+ si_errno int32
+ si_code int32
+ // below here is a union; si_addr is the only field we use
+ si_addr uint64
+}
+
+type siginfo struct {
+ siginfoFields
+
+ // Pad struct to the max size in the kernel.
+ _ [_si_max_size - unsafe.Sizeof(siginfoFields{})]byte
+}
+
+type itimerspec struct {
+ it_interval timespec
+ it_value timespec
+}
+
+type itimerval struct {
+ it_interval timeval
+ it_value timeval
+}
+
+type sigeventFields struct {
+ value uintptr
+ signo int32
+ notify int32
+ // below here is a union; sigev_notify_thread_id is the only field we use
+ sigev_notify_thread_id int32
+}
+
+type sigevent struct {
+ sigeventFields
+
+ // Pad struct to the max size in the kernel.
+ _ [_sigev_max_size - unsafe.Sizeof(sigeventFields{})]byte
+}
+
+// Created by cgo -cdefs and then converted to Go by hand
+// ../cmd/cgo/cgo -cdefs defs_linux.go defs1_linux.go defs2_linux.go
+
+const (
+ _O_RDONLY = 0x0
+ _O_WRONLY = 0x1
+ _O_CREAT = 0x40
+ _O_TRUNC = 0x200
+ _O_NONBLOCK = 0x800
+ _O_CLOEXEC = 0x80000
+)
+
+type usigset struct {
+ __val [16]uint64
+}
+
+type stackt struct {
+ ss_sp *byte
+ ss_flags int32
+ pad_cgo_0 [4]byte
+ ss_size uintptr
+}
+
+type sigcontext struct {
+ fault_address uint64
+ /* AArch64 registers */
+ regs [31]uint64
+ sp uint64
+ pc uint64
+ pstate uint64
+ _pad [8]byte // __attribute__((__aligned__(16)))
+ __reserved [4096]byte
+}
+
+type sockaddr_un struct {
+ family uint16
+ path [108]byte
+}
+
+type ucontext struct {
+ uc_flags uint64
+ uc_link *ucontext
+ uc_stack stackt
+ uc_sigmask uint64
+ _pad [(1024 - 64) / 8]byte
+ _pad2 [8]byte // sigcontext must be aligned to 16-byte
+ uc_mcontext sigcontext
+}
diff --git a/contrib/go/_std_1.21/src/runtime/defs_windows.go b/contrib/go/_std_1.21/src/runtime/defs_windows.go
new file mode 100644
index 0000000000..56698fa56c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/defs_windows.go
@@ -0,0 +1,90 @@
+// Copyright 2009 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.
+
+// Windows architecture-independent definitions.
+
+package runtime
+
+const (
+ _PROT_NONE = 0
+ _PROT_READ = 1
+ _PROT_WRITE = 2
+ _PROT_EXEC = 4
+
+ _MAP_ANON = 1
+ _MAP_PRIVATE = 2
+
+ _DUPLICATE_SAME_ACCESS = 0x2
+ _THREAD_PRIORITY_HIGHEST = 0x2
+
+ _SIGINT = 0x2
+ _SIGTERM = 0xF
+ _CTRL_C_EVENT = 0x0
+ _CTRL_BREAK_EVENT = 0x1
+ _CTRL_CLOSE_EVENT = 0x2
+ _CTRL_LOGOFF_EVENT = 0x5
+ _CTRL_SHUTDOWN_EVENT = 0x6
+
+ _EXCEPTION_ACCESS_VIOLATION = 0xc0000005
+ _EXCEPTION_IN_PAGE_ERROR = 0xc0000006
+ _EXCEPTION_BREAKPOINT = 0x80000003
+ _EXCEPTION_ILLEGAL_INSTRUCTION = 0xc000001d
+ _EXCEPTION_FLT_DENORMAL_OPERAND = 0xc000008d
+ _EXCEPTION_FLT_DIVIDE_BY_ZERO = 0xc000008e
+ _EXCEPTION_FLT_INEXACT_RESULT = 0xc000008f
+ _EXCEPTION_FLT_OVERFLOW = 0xc0000091
+ _EXCEPTION_FLT_UNDERFLOW = 0xc0000093
+ _EXCEPTION_INT_DIVIDE_BY_ZERO = 0xc0000094
+ _EXCEPTION_INT_OVERFLOW = 0xc0000095
+
+ _INFINITE = 0xffffffff
+ _WAIT_TIMEOUT = 0x102
+
+ _EXCEPTION_CONTINUE_EXECUTION = -0x1
+ _EXCEPTION_CONTINUE_SEARCH = 0x0
+)
+
+type systeminfo struct {
+ anon0 [4]byte
+ dwpagesize uint32
+ lpminimumapplicationaddress *byte
+ lpmaximumapplicationaddress *byte
+ dwactiveprocessormask uintptr
+ dwnumberofprocessors uint32
+ dwprocessortype uint32
+ dwallocationgranularity uint32
+ wprocessorlevel uint16
+ wprocessorrevision uint16
+}
+
+type exceptionpointers struct {
+ record *exceptionrecord
+ context *context
+}
+
+type exceptionrecord struct {
+ exceptioncode uint32
+ exceptionflags uint32
+ exceptionrecord *exceptionrecord
+ exceptionaddress uintptr
+ numberparameters uint32
+ exceptioninformation [15]uintptr
+}
+
+type overlapped struct {
+ internal uintptr
+ internalhigh uintptr
+ anon0 [8]byte
+ hevent *byte
+}
+
+type memoryBasicInformation struct {
+ baseAddress uintptr
+ allocationBase uintptr
+ allocationProtect uint32
+ regionSize uintptr
+ state uint32
+ protect uint32
+ type_ uint32
+}
diff --git a/contrib/go/_std_1.21/src/runtime/defs_windows_amd64.go b/contrib/go/_std_1.21/src/runtime/defs_windows_amd64.go
new file mode 100644
index 0000000000..20c9c4d932
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/defs_windows_amd64.go
@@ -0,0 +1,100 @@
+// Copyright 2009 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 runtime
+
+const _CONTEXT_CONTROL = 0x100001
+
+type m128a struct {
+ low uint64
+ high int64
+}
+
+type context struct {
+ p1home uint64
+ p2home uint64
+ p3home uint64
+ p4home uint64
+ p5home uint64
+ p6home uint64
+ contextflags uint32
+ mxcsr uint32
+ segcs uint16
+ segds uint16
+ seges uint16
+ segfs uint16
+ seggs uint16
+ segss uint16
+ eflags uint32
+ dr0 uint64
+ dr1 uint64
+ dr2 uint64
+ dr3 uint64
+ dr6 uint64
+ dr7 uint64
+ rax uint64
+ rcx uint64
+ rdx uint64
+ rbx uint64
+ rsp uint64
+ rbp uint64
+ rsi uint64
+ rdi uint64
+ r8 uint64
+ r9 uint64
+ r10 uint64
+ r11 uint64
+ r12 uint64
+ r13 uint64
+ r14 uint64
+ r15 uint64
+ rip uint64
+ anon0 [512]byte
+ vectorregister [26]m128a
+ vectorcontrol uint64
+ debugcontrol uint64
+ lastbranchtorip uint64
+ lastbranchfromrip uint64
+ lastexceptiontorip uint64
+ lastexceptionfromrip uint64
+}
+
+func (c *context) ip() uintptr { return uintptr(c.rip) }
+func (c *context) sp() uintptr { return uintptr(c.rsp) }
+
+// AMD64 does not have link register, so this returns 0.
+func (c *context) lr() uintptr { return 0 }
+func (c *context) set_lr(x uintptr) {}
+
+func (c *context) set_ip(x uintptr) { c.rip = uint64(x) }
+func (c *context) set_sp(x uintptr) { c.rsp = uint64(x) }
+func (c *context) set_fp(x uintptr) { c.rbp = uint64(x) }
+
+func prepareContextForSigResume(c *context) {
+ c.r8 = c.rsp
+ c.r9 = c.rip
+}
+
+func dumpregs(r *context) {
+ print("rax ", hex(r.rax), "\n")
+ print("rbx ", hex(r.rbx), "\n")
+ print("rcx ", hex(r.rcx), "\n")
+ print("rdi ", hex(r.rdi), "\n")
+ print("rsi ", hex(r.rsi), "\n")
+ print("rbp ", hex(r.rbp), "\n")
+ print("rsp ", hex(r.rsp), "\n")
+ print("r8 ", hex(r.r8), "\n")
+ print("r9 ", hex(r.r9), "\n")
+ print("r10 ", hex(r.r10), "\n")
+ print("r11 ", hex(r.r11), "\n")
+ print("r12 ", hex(r.r12), "\n")
+ print("r13 ", hex(r.r13), "\n")
+ print("r14 ", hex(r.r14), "\n")
+ print("r15 ", hex(r.r15), "\n")
+ print("rip ", hex(r.rip), "\n")
+ print("rflags ", hex(r.eflags), "\n")
+ print("cs ", hex(r.segcs), "\n")
+ print("fs ", hex(r.segfs), "\n")
+ print("gs ", hex(r.seggs), "\n")
+}
diff --git a/contrib/go/_std_1.21/src/runtime/duff_amd64.s b/contrib/go/_std_1.21/src/runtime/duff_amd64.s
new file mode 100644
index 0000000000..69e9980a30
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/duff_amd64.s
@@ -0,0 +1,427 @@
+// Code generated by mkduff.go; DO NOT EDIT.
+// Run go generate from src/runtime to update.
+// See mkduff.go for comments.
+
+#include "textflag.h"
+
+TEXT runtime·duffzero<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-0
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ MOVUPS X15,(DI)
+ MOVUPS X15,16(DI)
+ MOVUPS X15,32(DI)
+ MOVUPS X15,48(DI)
+ LEAQ 64(DI),DI
+
+ RET
+
+TEXT runtime·duffcopy<ABIInternal>(SB), NOSPLIT|NOFRAME, $0-0
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ MOVUPS (SI), X0
+ ADDQ $16, SI
+ MOVUPS X0, (DI)
+ ADDQ $16, DI
+
+ RET
diff --git a/contrib/go/_std_1.20/src/runtime/duff_arm64.s b/contrib/go/_std_1.21/src/runtime/duff_arm64.s
index 33c4905078..33c4905078 100644
--- a/contrib/go/_std_1.20/src/runtime/duff_arm64.s
+++ b/contrib/go/_std_1.21/src/runtime/duff_arm64.s
diff --git a/contrib/go/_std_1.20/src/runtime/env_posix.go b/contrib/go/_std_1.21/src/runtime/env_posix.go
index 0eb4f0d7a3..0eb4f0d7a3 100644
--- a/contrib/go/_std_1.20/src/runtime/env_posix.go
+++ b/contrib/go/_std_1.21/src/runtime/env_posix.go
diff --git a/contrib/go/_std_1.21/src/runtime/error.go b/contrib/go/_std_1.21/src/runtime/error.go
new file mode 100644
index 0000000000..3590ccd965
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/error.go
@@ -0,0 +1,330 @@
+// Copyright 2010 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 runtime
+
+import "internal/bytealg"
+
+// The Error interface identifies a run time error.
+type Error interface {
+ error
+
+ // RuntimeError is a no-op function but
+ // serves to distinguish types that are run time
+ // errors from ordinary errors: a type is a
+ // run time error if it has a RuntimeError method.
+ RuntimeError()
+}
+
+// A TypeAssertionError explains a failed type assertion.
+type TypeAssertionError struct {
+ _interface *_type
+ concrete *_type
+ asserted *_type
+ missingMethod string // one method needed by Interface, missing from Concrete
+}
+
+func (*TypeAssertionError) RuntimeError() {}
+
+func (e *TypeAssertionError) Error() string {
+ inter := "interface"
+ if e._interface != nil {
+ inter = toRType(e._interface).string()
+ }
+ as := toRType(e.asserted).string()
+ if e.concrete == nil {
+ return "interface conversion: " + inter + " is nil, not " + as
+ }
+ cs := toRType(e.concrete).string()
+ if e.missingMethod == "" {
+ msg := "interface conversion: " + inter + " is " + cs + ", not " + as
+ if cs == as {
+ // provide slightly clearer error message
+ if toRType(e.concrete).pkgpath() != toRType(e.asserted).pkgpath() {
+ msg += " (types from different packages)"
+ } else {
+ msg += " (types from different scopes)"
+ }
+ }
+ return msg
+ }
+ return "interface conversion: " + cs + " is not " + as +
+ ": missing method " + e.missingMethod
+}
+
+// itoa converts val to a decimal representation. The result is
+// written somewhere within buf and the location of the result is returned.
+// buf must be at least 20 bytes.
+//
+//go:nosplit
+func itoa(buf []byte, val uint64) []byte {
+ i := len(buf) - 1
+ for val >= 10 {
+ buf[i] = byte(val%10 + '0')
+ i--
+ val /= 10
+ }
+ buf[i] = byte(val + '0')
+ return buf[i:]
+}
+
+// An errorString represents a runtime error described by a single string.
+type errorString string
+
+func (e errorString) RuntimeError() {}
+
+func (e errorString) Error() string {
+ return "runtime error: " + string(e)
+}
+
+type errorAddressString struct {
+ msg string // error message
+ addr uintptr // memory address where the error occurred
+}
+
+func (e errorAddressString) RuntimeError() {}
+
+func (e errorAddressString) Error() string {
+ return "runtime error: " + e.msg
+}
+
+// Addr returns the memory address where a fault occurred.
+// The address provided is best-effort.
+// The veracity of the result may depend on the platform.
+// Errors providing this method will only be returned as
+// a result of using runtime/debug.SetPanicOnFault.
+func (e errorAddressString) Addr() uintptr {
+ return e.addr
+}
+
+// plainError represents a runtime error described a string without
+// the prefix "runtime error: " after invoking errorString.Error().
+// See Issue #14965.
+type plainError string
+
+func (e plainError) RuntimeError() {}
+
+func (e plainError) Error() string {
+ return string(e)
+}
+
+// A boundsError represents an indexing or slicing operation gone wrong.
+type boundsError struct {
+ x int64
+ y int
+ // Values in an index or slice expression can be signed or unsigned.
+ // That means we'd need 65 bits to encode all possible indexes, from -2^63 to 2^64-1.
+ // Instead, we keep track of whether x should be interpreted as signed or unsigned.
+ // y is known to be nonnegative and to fit in an int.
+ signed bool
+ code boundsErrorCode
+}
+
+type boundsErrorCode uint8
+
+const (
+ boundsIndex boundsErrorCode = iota // s[x], 0 <= x < len(s) failed
+
+ boundsSliceAlen // s[?:x], 0 <= x <= len(s) failed
+ boundsSliceAcap // s[?:x], 0 <= x <= cap(s) failed
+ boundsSliceB // s[x:y], 0 <= x <= y failed (but boundsSliceA didn't happen)
+
+ boundsSlice3Alen // s[?:?:x], 0 <= x <= len(s) failed
+ boundsSlice3Acap // s[?:?:x], 0 <= x <= cap(s) failed
+ boundsSlice3B // s[?:x:y], 0 <= x <= y failed (but boundsSlice3A didn't happen)
+ boundsSlice3C // s[x:y:?], 0 <= x <= y failed (but boundsSlice3A/B didn't happen)
+
+ boundsConvert // (*[x]T)(s), 0 <= x <= len(s) failed
+ // Note: in the above, len(s) and cap(s) are stored in y
+)
+
+// boundsErrorFmts provide error text for various out-of-bounds panics.
+// Note: if you change these strings, you should adjust the size of the buffer
+// in boundsError.Error below as well.
+var boundsErrorFmts = [...]string{
+ boundsIndex: "index out of range [%x] with length %y",
+ boundsSliceAlen: "slice bounds out of range [:%x] with length %y",
+ boundsSliceAcap: "slice bounds out of range [:%x] with capacity %y",
+ boundsSliceB: "slice bounds out of range [%x:%y]",
+ boundsSlice3Alen: "slice bounds out of range [::%x] with length %y",
+ boundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",
+ boundsSlice3B: "slice bounds out of range [:%x:%y]",
+ boundsSlice3C: "slice bounds out of range [%x:%y:]",
+ boundsConvert: "cannot convert slice with length %y to array or pointer to array with length %x",
+}
+
+// boundsNegErrorFmts are overriding formats if x is negative. In this case there's no need to report y.
+var boundsNegErrorFmts = [...]string{
+ boundsIndex: "index out of range [%x]",
+ boundsSliceAlen: "slice bounds out of range [:%x]",
+ boundsSliceAcap: "slice bounds out of range [:%x]",
+ boundsSliceB: "slice bounds out of range [%x:]",
+ boundsSlice3Alen: "slice bounds out of range [::%x]",
+ boundsSlice3Acap: "slice bounds out of range [::%x]",
+ boundsSlice3B: "slice bounds out of range [:%x:]",
+ boundsSlice3C: "slice bounds out of range [%x::]",
+}
+
+func (e boundsError) RuntimeError() {}
+
+func appendIntStr(b []byte, v int64, signed bool) []byte {
+ if signed && v < 0 {
+ b = append(b, '-')
+ v = -v
+ }
+ var buf [20]byte
+ b = append(b, itoa(buf[:], uint64(v))...)
+ return b
+}
+
+func (e boundsError) Error() string {
+ fmt := boundsErrorFmts[e.code]
+ if e.signed && e.x < 0 {
+ fmt = boundsNegErrorFmts[e.code]
+ }
+ // max message length is 99: "runtime error: slice bounds out of range [::%x] with capacity %y"
+ // x can be at most 20 characters. y can be at most 19.
+ b := make([]byte, 0, 100)
+ b = append(b, "runtime error: "...)
+ for i := 0; i < len(fmt); i++ {
+ c := fmt[i]
+ if c != '%' {
+ b = append(b, c)
+ continue
+ }
+ i++
+ switch fmt[i] {
+ case 'x':
+ b = appendIntStr(b, e.x, e.signed)
+ case 'y':
+ b = appendIntStr(b, int64(e.y), true)
+ }
+ }
+ return string(b)
+}
+
+type stringer interface {
+ String() string
+}
+
+// printany prints an argument passed to panic.
+// If panic is called with a value that has a String or Error method,
+// it has already been converted into a string by preprintpanics.
+func printany(i any) {
+ switch v := i.(type) {
+ case nil:
+ print("nil")
+ case bool:
+ print(v)
+ case int:
+ print(v)
+ case int8:
+ print(v)
+ case int16:
+ print(v)
+ case int32:
+ print(v)
+ case int64:
+ print(v)
+ case uint:
+ print(v)
+ case uint8:
+ print(v)
+ case uint16:
+ print(v)
+ case uint32:
+ print(v)
+ case uint64:
+ print(v)
+ case uintptr:
+ print(v)
+ case float32:
+ print(v)
+ case float64:
+ print(v)
+ case complex64:
+ print(v)
+ case complex128:
+ print(v)
+ case string:
+ print(v)
+ default:
+ printanycustomtype(i)
+ }
+}
+
+func printanycustomtype(i any) {
+ eface := efaceOf(&i)
+ typestring := toRType(eface._type).string()
+
+ switch eface._type.Kind_ {
+ case kindString:
+ print(typestring, `("`, *(*string)(eface.data), `")`)
+ case kindBool:
+ print(typestring, "(", *(*bool)(eface.data), ")")
+ case kindInt:
+ print(typestring, "(", *(*int)(eface.data), ")")
+ case kindInt8:
+ print(typestring, "(", *(*int8)(eface.data), ")")
+ case kindInt16:
+ print(typestring, "(", *(*int16)(eface.data), ")")
+ case kindInt32:
+ print(typestring, "(", *(*int32)(eface.data), ")")
+ case kindInt64:
+ print(typestring, "(", *(*int64)(eface.data), ")")
+ case kindUint:
+ print(typestring, "(", *(*uint)(eface.data), ")")
+ case kindUint8:
+ print(typestring, "(", *(*uint8)(eface.data), ")")
+ case kindUint16:
+ print(typestring, "(", *(*uint16)(eface.data), ")")
+ case kindUint32:
+ print(typestring, "(", *(*uint32)(eface.data), ")")
+ case kindUint64:
+ print(typestring, "(", *(*uint64)(eface.data), ")")
+ case kindUintptr:
+ print(typestring, "(", *(*uintptr)(eface.data), ")")
+ case kindFloat32:
+ print(typestring, "(", *(*float32)(eface.data), ")")
+ case kindFloat64:
+ print(typestring, "(", *(*float64)(eface.data), ")")
+ case kindComplex64:
+ print(typestring, *(*complex64)(eface.data))
+ case kindComplex128:
+ print(typestring, *(*complex128)(eface.data))
+ default:
+ print("(", typestring, ") ", eface.data)
+ }
+}
+
+// panicwrap generates a panic for a call to a wrapped value method
+// with a nil pointer receiver.
+//
+// It is called from the generated wrapper code.
+func panicwrap() {
+ pc := getcallerpc()
+ name := funcNameForPrint(funcname(findfunc(pc)))
+ // name is something like "main.(*T).F".
+ // We want to extract pkg ("main"), typ ("T"), and meth ("F").
+ // Do it by finding the parens.
+ i := bytealg.IndexByteString(name, '(')
+ if i < 0 {
+ throw("panicwrap: no ( in " + name)
+ }
+ pkg := name[:i-1]
+ if i+2 >= len(name) || name[i-1:i+2] != ".(*" {
+ throw("panicwrap: unexpected string after package name: " + name)
+ }
+ name = name[i+2:]
+ i = bytealg.IndexByteString(name, ')')
+ if i < 0 {
+ throw("panicwrap: no ) in " + name)
+ }
+ if i+2 >= len(name) || name[i:i+2] != ")." {
+ throw("panicwrap: unexpected string after type name: " + name)
+ }
+ typ := name[:i]
+ meth := name[i+2:]
+ panic(plainError("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer"))
+}
diff --git a/contrib/go/_std_1.21/src/runtime/exithook.go b/contrib/go/_std_1.21/src/runtime/exithook.go
new file mode 100644
index 0000000000..65b426b383
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/exithook.go
@@ -0,0 +1,69 @@
+// Copyright 2022 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 runtime
+
+// addExitHook registers the specified function 'f' to be run at
+// program termination (e.g. when someone invokes os.Exit(), or when
+// main.main returns). Hooks are run in reverse order of registration:
+// first hook added is the last one run.
+//
+// CAREFUL: the expectation is that addExitHook should only be called
+// from a safe context (e.g. not an error/panic path or signal
+// handler, preemption enabled, allocation allowed, write barriers
+// allowed, etc), and that the exit function 'f' will be invoked under
+// similar circumstances. That is the say, we are expecting that 'f'
+// uses normal / high-level Go code as opposed to one of the more
+// restricted dialects used for the trickier parts of the runtime.
+func addExitHook(f func(), runOnNonZeroExit bool) {
+ exitHooks.hooks = append(exitHooks.hooks, exitHook{f: f, runOnNonZeroExit: runOnNonZeroExit})
+}
+
+// exitHook stores a function to be run on program exit, registered
+// by the utility runtime.addExitHook.
+type exitHook struct {
+ f func() // func to run
+ runOnNonZeroExit bool // whether to run on non-zero exit code
+}
+
+// exitHooks stores state related to hook functions registered to
+// run when program execution terminates.
+var exitHooks struct {
+ hooks []exitHook
+ runningExitHooks bool
+}
+
+// runExitHooks runs any registered exit hook functions (funcs
+// previously registered using runtime.addExitHook). Here 'exitCode'
+// is the status code being passed to os.Exit, or zero if the program
+// is terminating normally without calling os.Exit.
+func runExitHooks(exitCode int) {
+ if exitHooks.runningExitHooks {
+ throw("internal error: exit hook invoked exit")
+ }
+ exitHooks.runningExitHooks = true
+
+ runExitHook := func(f func()) (caughtPanic bool) {
+ defer func() {
+ if x := recover(); x != nil {
+ caughtPanic = true
+ }
+ }()
+ f()
+ return
+ }
+
+ finishPageTrace()
+ for i := range exitHooks.hooks {
+ h := exitHooks.hooks[len(exitHooks.hooks)-i-1]
+ if exitCode != 0 && !h.runOnNonZeroExit {
+ continue
+ }
+ if caughtPanic := runExitHook(h.f); caughtPanic {
+ throw("internal error: exit hook invoked panic")
+ }
+ }
+ exitHooks.hooks = nil
+ exitHooks.runningExitHooks = false
+}
diff --git a/contrib/go/_std_1.21/src/runtime/extern.go b/contrib/go/_std_1.21/src/runtime/extern.go
new file mode 100644
index 0000000000..26dcf0bd52
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/extern.go
@@ -0,0 +1,341 @@
+// Copyright 2009 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 runtime contains operations that interact with Go's runtime system,
+such as functions to control goroutines. It also includes the low-level type information
+used by the reflect package; see reflect's documentation for the programmable
+interface to the run-time type system.
+
+# Environment Variables
+
+The following environment variables ($name or %name%, depending on the host
+operating system) control the run-time behavior of Go programs. The meanings
+and use may change from release to release.
+
+The GOGC variable sets the initial garbage collection target percentage.
+A collection is triggered when the ratio of freshly allocated data to live data
+remaining after the previous collection reaches this percentage. The default
+is GOGC=100. Setting GOGC=off disables the garbage collector entirely.
+[runtime/debug.SetGCPercent] allows changing this percentage at run time.
+
+The GOMEMLIMIT variable sets a soft memory limit for the runtime. This memory limit
+includes the Go heap and all other memory managed by the runtime, and excludes
+external memory sources such as mappings of the binary itself, memory managed in
+other languages, and memory held by the operating system on behalf of the Go
+program. GOMEMLIMIT is a numeric value in bytes with an optional unit suffix.
+The supported suffixes include B, KiB, MiB, GiB, and TiB. These suffixes
+represent quantities of bytes as defined by the IEC 80000-13 standard. That is,
+they are based on powers of two: KiB means 2^10 bytes, MiB means 2^20 bytes,
+and so on. The default setting is math.MaxInt64, which effectively disables the
+memory limit. [runtime/debug.SetMemoryLimit] allows changing this limit at run
+time.
+
+The GODEBUG variable controls debugging variables within the runtime.
+It is a comma-separated list of name=val pairs setting these named variables:
+
+ allocfreetrace: setting allocfreetrace=1 causes every allocation to be
+ profiled and a stack trace printed on each object's allocation and free.
+
+ clobberfree: setting clobberfree=1 causes the garbage collector to
+ clobber the memory content of an object with bad content when it frees
+ the object.
+
+ cpu.*: cpu.all=off disables the use of all optional instruction set extensions.
+ cpu.extension=off disables use of instructions from the specified instruction set extension.
+ extension is the lower case name for the instruction set extension such as sse41 or avx
+ as listed in internal/cpu package. As an example cpu.avx=off disables runtime detection
+ and thereby use of AVX instructions.
+
+ cgocheck: setting cgocheck=0 disables all checks for packages
+ using cgo to incorrectly pass Go pointers to non-Go code.
+ Setting cgocheck=1 (the default) enables relatively cheap
+ checks that may miss some errors. A more complete, but slow,
+ cgocheck mode can be enabled using GOEXPERIMENT (which
+ requires a rebuild), see https://pkg.go.dev/internal/goexperiment for details.
+
+ dontfreezetheworld: by default, the start of a fatal panic or throw
+ "freezes the world", preempting all threads to stop all running
+ goroutines, which makes it possible to traceback all goroutines, and
+ keeps their state close to the point of panic. Setting
+ dontfreezetheworld=1 disables this preemption, allowing goroutines to
+ continue executing during panic processing. Note that goroutines that
+ naturally enter the scheduler will still stop. This can be useful when
+ debugging the runtime scheduler, as freezetheworld perturbs scheduler
+ state and thus may hide problems.
+
+ efence: setting efence=1 causes the allocator to run in a mode
+ where each object is allocated on a unique page and addresses are
+ never recycled.
+
+ gccheckmark: setting gccheckmark=1 enables verification of the
+ garbage collector's concurrent mark phase by performing a
+ second mark pass while the world is stopped. If the second
+ pass finds a reachable object that was not found by concurrent
+ mark, the garbage collector will panic.
+
+ gcpacertrace: setting gcpacertrace=1 causes the garbage collector to
+ print information about the internal state of the concurrent pacer.
+
+ gcshrinkstackoff: setting gcshrinkstackoff=1 disables moving goroutines
+ onto smaller stacks. In this mode, a goroutine's stack can only grow.
+
+ gcstoptheworld: setting gcstoptheworld=1 disables concurrent garbage collection,
+ making every garbage collection a stop-the-world event. Setting gcstoptheworld=2
+ also disables concurrent sweeping after the garbage collection finishes.
+
+ gctrace: setting gctrace=1 causes the garbage collector to emit a single line to standard
+ error at each collection, summarizing the amount of memory collected and the
+ length of the pause. The format of this line is subject to change. Included in
+ the explanation below is also the relevant runtime/metrics metric for each field.
+ Currently, it is:
+ gc # @#s #%: #+#+# ms clock, #+#/#/#+# ms cpu, #->#-># MB, # MB goal, # MB stacks, #MB globals, # P
+ where the fields are as follows:
+ gc # the GC number, incremented at each GC
+ @#s time in seconds since program start
+ #% percentage of time spent in GC since program start
+ #+...+# wall-clock/CPU times for the phases of the GC
+ #->#-># MB heap size at GC start, at GC end, and live heap, or /gc/scan/heap:bytes
+ # MB goal goal heap size, or /gc/heap/goal:bytes
+ # MB stacks estimated scannable stack size, or /gc/scan/stack:bytes
+ # MB globals scannable global size, or /gc/scan/globals:bytes
+ # P number of processors used, or /sched/gomaxprocs:threads
+ The phases are stop-the-world (STW) sweep termination, concurrent
+ mark and scan, and STW mark termination. The CPU times
+ for mark/scan are broken down in to assist time (GC performed in
+ line with allocation), background GC time, and idle GC time.
+ If the line ends with "(forced)", this GC was forced by a
+ runtime.GC() call.
+
+ harddecommit: setting harddecommit=1 causes memory that is returned to the OS to
+ also have protections removed on it. This is the only mode of operation on Windows,
+ but is helpful in debugging scavenger-related issues on other platforms. Currently,
+ only supported on Linux.
+
+ inittrace: setting inittrace=1 causes the runtime to emit a single line to standard
+ error for each package with init work, summarizing the execution time and memory
+ allocation. No information is printed for inits executed as part of plugin loading
+ and for packages without both user defined and compiler generated init work.
+ The format of this line is subject to change. Currently, it is:
+ init # @#ms, # ms clock, # bytes, # allocs
+ where the fields are as follows:
+ init # the package name
+ @# ms time in milliseconds when the init started since program start
+ # clock wall-clock time for package initialization work
+ # bytes memory allocated on the heap
+ # allocs number of heap allocations
+
+ madvdontneed: setting madvdontneed=0 will use MADV_FREE
+ instead of MADV_DONTNEED on Linux when returning memory to the
+ kernel. This is more efficient, but means RSS numbers will
+ drop only when the OS is under memory pressure. On the BSDs and
+ Illumos/Solaris, setting madvdontneed=1 will use MADV_DONTNEED instead
+ of MADV_FREE. This is less efficient, but causes RSS numbers to drop
+ more quickly.
+
+ memprofilerate: setting memprofilerate=X will update the value of runtime.MemProfileRate.
+ When set to 0 memory profiling is disabled. Refer to the description of
+ MemProfileRate for the default value.
+
+ pagetrace: setting pagetrace=/path/to/file will write out a trace of page events
+ that can be viewed, analyzed, and visualized using the x/debug/cmd/pagetrace tool.
+ Build your program with GOEXPERIMENT=pagetrace to enable this functionality. Do not
+ enable this functionality if your program is a setuid binary as it introduces a security
+ risk in that scenario. Currently not supported on Windows, plan9 or js/wasm. Setting this
+ option for some applications can produce large traces, so use with care.
+
+ invalidptr: invalidptr=1 (the default) causes the garbage collector and stack
+ copier to crash the program if an invalid pointer value (for example, 1)
+ is found in a pointer-typed location. Setting invalidptr=0 disables this check.
+ This should only be used as a temporary workaround to diagnose buggy code.
+ The real fix is to not store integers in pointer-typed locations.
+
+ sbrk: setting sbrk=1 replaces the memory allocator and garbage collector
+ with a trivial allocator that obtains memory from the operating system and
+ never reclaims any memory.
+
+ scavtrace: setting scavtrace=1 causes the runtime to emit a single line to standard
+ error, roughly once per GC cycle, summarizing the amount of work done by the
+ scavenger as well as the total amount of memory returned to the operating system
+ and an estimate of physical memory utilization. The format of this line is subject
+ to change, but currently it is:
+ scav # KiB work (bg), # KiB work (eager), # KiB total, #% util
+ where the fields are as follows:
+ # KiB work (bg) the amount of memory returned to the OS in the background since
+ the last line
+ # KiB work (eager) the amount of memory returned to the OS eagerly since the last line
+ # KiB now the amount of address space currently returned to the OS
+ #% util the fraction of all unscavenged heap memory which is in-use
+ If the line ends with "(forced)", then scavenging was forced by a
+ debug.FreeOSMemory() call.
+
+ scheddetail: setting schedtrace=X and scheddetail=1 causes the scheduler to emit
+ detailed multiline info every X milliseconds, describing state of the scheduler,
+ processors, threads and goroutines.
+
+ schedtrace: setting schedtrace=X causes the scheduler to emit a single line to standard
+ error every X milliseconds, summarizing the scheduler state.
+
+ tracebackancestors: setting tracebackancestors=N extends tracebacks with the stacks at
+ which goroutines were created, where N limits the number of ancestor goroutines to
+ report. This also extends the information returned by runtime.Stack. Ancestor's goroutine
+ IDs will refer to the ID of the goroutine at the time of creation; it's possible for this
+ ID to be reused for another goroutine. Setting N to 0 will report no ancestry information.
+
+ tracefpunwindoff: setting tracefpunwindoff=1 forces the execution tracer to
+ use the runtime's default stack unwinder instead of frame pointer unwinding.
+ This increases tracer overhead, but could be helpful as a workaround or for
+ debugging unexpected regressions caused by frame pointer unwinding.
+
+ asyncpreemptoff: asyncpreemptoff=1 disables signal-based
+ asynchronous goroutine preemption. This makes some loops
+ non-preemptible for long periods, which may delay GC and
+ goroutine scheduling. This is useful for debugging GC issues
+ because it also disables the conservative stack scanning used
+ for asynchronously preempted goroutines.
+
+The net and net/http packages also refer to debugging variables in GODEBUG.
+See the documentation for those packages for details.
+
+The GOMAXPROCS variable limits the number of operating system threads that
+can execute user-level Go code simultaneously. There is no limit to the number of threads
+that can be blocked in system calls on behalf of Go code; those do not count against
+the GOMAXPROCS limit. This package's GOMAXPROCS function queries and changes
+the limit.
+
+The GORACE variable configures the race detector, for programs built using -race.
+See https://golang.org/doc/articles/race_detector.html for details.
+
+The GOTRACEBACK variable controls the amount of output generated when a Go
+program fails due to an unrecovered panic or an unexpected runtime condition.
+By default, a failure prints a stack trace for the current goroutine,
+eliding functions internal to the run-time system, and then exits with exit code 2.
+The failure prints stack traces for all goroutines if there is no current goroutine
+or the failure is internal to the run-time.
+GOTRACEBACK=none omits the goroutine stack traces entirely.
+GOTRACEBACK=single (the default) behaves as described above.
+GOTRACEBACK=all adds stack traces for all user-created goroutines.
+GOTRACEBACK=system is like “all” but adds stack frames for run-time functions
+and shows goroutines created internally by the run-time.
+GOTRACEBACK=crash is like “system” but crashes in an operating system-specific
+manner instead of exiting. For example, on Unix systems, the crash raises
+SIGABRT to trigger a core dump.
+GOTRACEBACK=wer is like “crash” but doesn't disable Windows Error Reporting (WER).
+For historical reasons, the GOTRACEBACK settings 0, 1, and 2 are synonyms for
+none, all, and system, respectively.
+The runtime/debug package's SetTraceback function allows increasing the
+amount of output at run time, but it cannot reduce the amount below that
+specified by the environment variable.
+See https://golang.org/pkg/runtime/debug/#SetTraceback.
+
+The GOARCH, GOOS, GOPATH, and GOROOT environment variables complete
+the set of Go environment variables. They influence the building of Go programs
+(see https://golang.org/cmd/go and https://golang.org/pkg/go/build).
+GOARCH, GOOS, and GOROOT are recorded at compile time and made available by
+constants or functions in this package, but they do not influence the execution
+of the run-time system.
+
+# Security
+
+On Unix platforms, Go's runtime system behaves slightly differently when a
+binary is setuid/setgid or executed with setuid/setgid-like properties, in order
+to prevent dangerous behaviors. On Linux this is determined by checking for the
+AT_SECURE flag in the auxiliary vector, on the BSDs and Solaris/Illumos it is
+determined by checking the issetugid syscall, and on AIX it is determined by
+checking if the uid/gid match the effective uid/gid.
+
+When the runtime determines the binary is setuid/setgid-like, it does three main
+things:
+ - The standard input/output file descriptors (0, 1, 2) are checked to be open.
+ If any of them are closed, they are opened pointing at /dev/null.
+ - The value of the GOTRACEBACK environment variable is set to 'none'.
+ - When a signal is received that terminates the program, or the program
+ encounters an unrecoverable panic that would otherwise override the value
+ of GOTRACEBACK, the goroutine stack, registers, and other memory related
+ information are omitted.
+*/
+package runtime
+
+import (
+ "internal/goarch"
+ "internal/goos"
+)
+
+// Caller reports file and line number information about function invocations on
+// the calling goroutine's stack. The argument skip is the number of stack frames
+// to ascend, with 0 identifying the caller of Caller. (For historical reasons the
+// meaning of skip differs between Caller and Callers.) The return values report the
+// program counter, file name, and line number within the file of the corresponding
+// call. The boolean ok is false if it was not possible to recover the information.
+func Caller(skip int) (pc uintptr, file string, line int, ok bool) {
+ rpc := make([]uintptr, 1)
+ n := callers(skip+1, rpc[:])
+ if n < 1 {
+ return
+ }
+ frame, _ := CallersFrames(rpc).Next()
+ return frame.PC, frame.File, frame.Line, frame.PC != 0
+}
+
+// Callers fills the slice pc with the return program counters of function invocations
+// on the calling goroutine's stack. The argument skip is the number of stack frames
+// to skip before recording in pc, with 0 identifying the frame for Callers itself and
+// 1 identifying the caller of Callers.
+// It returns the number of entries written to pc.
+//
+// To translate these PCs into symbolic information such as function
+// names and line numbers, use CallersFrames. CallersFrames accounts
+// for inlined functions and adjusts the return program counters into
+// call program counters. Iterating over the returned slice of PCs
+// directly is discouraged, as is using FuncForPC on any of the
+// returned PCs, since these cannot account for inlining or return
+// program counter adjustment.
+func Callers(skip int, pc []uintptr) int {
+ // runtime.callers uses pc.array==nil as a signal
+ // to print a stack trace. Pick off 0-length pc here
+ // so that we don't let a nil pc slice get to it.
+ if len(pc) == 0 {
+ return 0
+ }
+ return callers(skip, pc)
+}
+
+var defaultGOROOT string // set by cmd/link
+
+// GOROOT returns the root of the Go tree. It uses the
+// GOROOT environment variable, if set at process start,
+// or else the root used during the Go build.
+func GOROOT() string {
+ s := gogetenv("GOROOT")
+ if s != "" {
+ return s
+ }
+ return defaultGOROOT
+}
+
+// buildVersion is the Go tree's version string at build time.
+//
+// If any GOEXPERIMENTs are set to non-default values, it will include
+// "X:<GOEXPERIMENT>".
+//
+// This is set by the linker.
+//
+// This is accessed by "go version <binary>".
+var buildVersion string
+
+// Version returns the Go tree's version string.
+// It is either the commit hash and date at the time of the build or,
+// when possible, a release tag like "go1.3".
+func Version() string {
+ return buildVersion
+}
+
+// GOOS is the running program's operating system target:
+// one of darwin, freebsd, linux, and so on.
+// To view possible combinations of GOOS and GOARCH, run "go tool dist list".
+const GOOS string = goos.GOOS
+
+// GOARCH is the running program's architecture target:
+// one of 386, amd64, arm, s390x, and so on.
+const GOARCH string = goarch.GOARCH
diff --git a/contrib/go/_std_1.20/src/runtime/fastlog2.go b/contrib/go/_std_1.21/src/runtime/fastlog2.go
index 1f251bfaab..1f251bfaab 100644
--- a/contrib/go/_std_1.20/src/runtime/fastlog2.go
+++ b/contrib/go/_std_1.21/src/runtime/fastlog2.go
diff --git a/contrib/go/_std_1.20/src/runtime/fastlog2table.go b/contrib/go/_std_1.21/src/runtime/fastlog2table.go
index 6ba4a7d3f2..6ba4a7d3f2 100644
--- a/contrib/go/_std_1.20/src/runtime/fastlog2table.go
+++ b/contrib/go/_std_1.21/src/runtime/fastlog2table.go
diff --git a/contrib/go/_std_1.20/src/runtime/float.go b/contrib/go/_std_1.21/src/runtime/float.go
index 9f281c4045..9f281c4045 100644
--- a/contrib/go/_std_1.20/src/runtime/float.go
+++ b/contrib/go/_std_1.21/src/runtime/float.go
diff --git a/contrib/go/_std_1.21/src/runtime/funcdata.h b/contrib/go/_std_1.21/src/runtime/funcdata.h
new file mode 100644
index 0000000000..edc0316fb0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/funcdata.h
@@ -0,0 +1,56 @@
+// Copyright 2013 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.
+
+// This file defines the IDs for PCDATA and FUNCDATA instructions
+// in Go binaries. It is included by assembly sources, so it must
+// be written using #defines.
+//
+// These must agree with internal/abi/symtab.go.
+
+#define PCDATA_UnsafePoint 0
+#define PCDATA_StackMapIndex 1
+#define PCDATA_InlTreeIndex 2
+#define PCDATA_ArgLiveIndex 3
+
+#define FUNCDATA_ArgsPointerMaps 0 /* garbage collector blocks */
+#define FUNCDATA_LocalsPointerMaps 1
+#define FUNCDATA_StackObjects 2
+#define FUNCDATA_InlTree 3
+#define FUNCDATA_OpenCodedDeferInfo 4 /* info for func with open-coded defers */
+#define FUNCDATA_ArgInfo 5
+#define FUNCDATA_ArgLiveInfo 6
+#define FUNCDATA_WrapInfo 7
+
+// Pseudo-assembly statements.
+
+// GO_ARGS, GO_RESULTS_INITIALIZED, and NO_LOCAL_POINTERS are macros
+// that communicate to the runtime information about the location and liveness
+// of pointers in an assembly function's arguments, results, and stack frame.
+// This communication is only required in assembly functions that make calls
+// to other functions that might be preempted or grow the stack.
+// NOSPLIT functions that make no calls do not need to use these macros.
+
+// GO_ARGS indicates that the Go prototype for this assembly function
+// defines the pointer map for the function's arguments.
+// GO_ARGS should be the first instruction in a function that uses it.
+// It can be omitted if there are no arguments at all.
+// GO_ARGS is inserted implicitly by the linker for any function whose
+// name starts with a middle-dot and that also has a Go prototype; it
+// is therefore usually not necessary to write explicitly.
+#define GO_ARGS FUNCDATA $FUNCDATA_ArgsPointerMaps, go_args_stackmap(SB)
+
+// GO_RESULTS_INITIALIZED indicates that the assembly function
+// has initialized the stack space for its results and that those results
+// should be considered live for the remainder of the function.
+#define GO_RESULTS_INITIALIZED PCDATA $PCDATA_StackMapIndex, $1
+
+// NO_LOCAL_POINTERS indicates that the assembly function stores
+// no pointers to heap objects in its local stack variables.
+#define NO_LOCAL_POINTERS FUNCDATA $FUNCDATA_LocalsPointerMaps, no_pointers_stackmap(SB)
+
+// ArgsSizeUnknown is set in Func.argsize to mark all functions
+// whose argument size is unknown (C vararg functions, and
+// assembly code without an explicit specification).
+// This value is generated by the compiler, assembler, or linker.
+#define ArgsSizeUnknown 0x80000000
diff --git a/contrib/go/_std_1.20/src/runtime/go_tls.h b/contrib/go/_std_1.21/src/runtime/go_tls.h
index a47e798d9d..a47e798d9d 100644
--- a/contrib/go/_std_1.20/src/runtime/go_tls.h
+++ b/contrib/go/_std_1.21/src/runtime/go_tls.h
diff --git a/contrib/go/_std_1.20/src/runtime/hash64.go b/contrib/go/_std_1.21/src/runtime/hash64.go
index 2864a4b963..2864a4b963 100644
--- a/contrib/go/_std_1.20/src/runtime/hash64.go
+++ b/contrib/go/_std_1.21/src/runtime/hash64.go
diff --git a/contrib/go/_std_1.21/src/runtime/heapdump.go b/contrib/go/_std_1.21/src/runtime/heapdump.go
new file mode 100644
index 0000000000..8ddec8b2d5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/heapdump.go
@@ -0,0 +1,752 @@
+// Copyright 2014 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.
+
+// Implementation of runtime/debug.WriteHeapDump. Writes all
+// objects in the heap plus additional info (roots, threads,
+// finalizers, etc.) to a file.
+
+// The format of the dumped file is described at
+// https://golang.org/s/go15heapdump.
+
+package runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "unsafe"
+)
+
+//go:linkname runtime_debug_WriteHeapDump runtime/debug.WriteHeapDump
+func runtime_debug_WriteHeapDump(fd uintptr) {
+ stopTheWorld(stwWriteHeapDump)
+
+ // Keep m on this G's stack instead of the system stack.
+ // Both readmemstats_m and writeheapdump_m have pretty large
+ // peak stack depths and we risk blowing the system stack.
+ // This is safe because the world is stopped, so we don't
+ // need to worry about anyone shrinking and therefore moving
+ // our stack.
+ var m MemStats
+ systemstack(func() {
+ // Call readmemstats_m here instead of deeper in
+ // writeheapdump_m because we might blow the system stack
+ // otherwise.
+ readmemstats_m(&m)
+ writeheapdump_m(fd, &m)
+ })
+
+ startTheWorld()
+}
+
+const (
+ fieldKindEol = 0
+ fieldKindPtr = 1
+ fieldKindIface = 2
+ fieldKindEface = 3
+ tagEOF = 0
+ tagObject = 1
+ tagOtherRoot = 2
+ tagType = 3
+ tagGoroutine = 4
+ tagStackFrame = 5
+ tagParams = 6
+ tagFinalizer = 7
+ tagItab = 8
+ tagOSThread = 9
+ tagMemStats = 10
+ tagQueuedFinalizer = 11
+ tagData = 12
+ tagBSS = 13
+ tagDefer = 14
+ tagPanic = 15
+ tagMemProf = 16
+ tagAllocSample = 17
+)
+
+var dumpfd uintptr // fd to write the dump to.
+var tmpbuf []byte
+
+// buffer of pending write data
+const (
+ bufSize = 4096
+)
+
+var buf [bufSize]byte
+var nbuf uintptr
+
+func dwrite(data unsafe.Pointer, len uintptr) {
+ if len == 0 {
+ return
+ }
+ if nbuf+len <= bufSize {
+ copy(buf[nbuf:], (*[bufSize]byte)(data)[:len])
+ nbuf += len
+ return
+ }
+
+ write(dumpfd, unsafe.Pointer(&buf), int32(nbuf))
+ if len >= bufSize {
+ write(dumpfd, data, int32(len))
+ nbuf = 0
+ } else {
+ copy(buf[:], (*[bufSize]byte)(data)[:len])
+ nbuf = len
+ }
+}
+
+func dwritebyte(b byte) {
+ dwrite(unsafe.Pointer(&b), 1)
+}
+
+func flush() {
+ write(dumpfd, unsafe.Pointer(&buf), int32(nbuf))
+ nbuf = 0
+}
+
+// Cache of types that have been serialized already.
+// We use a type's hash field to pick a bucket.
+// Inside a bucket, we keep a list of types that
+// have been serialized so far, most recently used first.
+// Note: when a bucket overflows we may end up
+// serializing a type more than once. That's ok.
+const (
+ typeCacheBuckets = 256
+ typeCacheAssoc = 4
+)
+
+type typeCacheBucket struct {
+ t [typeCacheAssoc]*_type
+}
+
+var typecache [typeCacheBuckets]typeCacheBucket
+
+// dump a uint64 in a varint format parseable by encoding/binary.
+func dumpint(v uint64) {
+ var buf [10]byte
+ var n int
+ for v >= 0x80 {
+ buf[n] = byte(v | 0x80)
+ n++
+ v >>= 7
+ }
+ buf[n] = byte(v)
+ n++
+ dwrite(unsafe.Pointer(&buf), uintptr(n))
+}
+
+func dumpbool(b bool) {
+ if b {
+ dumpint(1)
+ } else {
+ dumpint(0)
+ }
+}
+
+// dump varint uint64 length followed by memory contents.
+func dumpmemrange(data unsafe.Pointer, len uintptr) {
+ dumpint(uint64(len))
+ dwrite(data, len)
+}
+
+func dumpslice(b []byte) {
+ dumpint(uint64(len(b)))
+ if len(b) > 0 {
+ dwrite(unsafe.Pointer(&b[0]), uintptr(len(b)))
+ }
+}
+
+func dumpstr(s string) {
+ dumpmemrange(unsafe.Pointer(unsafe.StringData(s)), uintptr(len(s)))
+}
+
+// dump information for a type.
+func dumptype(t *_type) {
+ if t == nil {
+ return
+ }
+
+ // If we've definitely serialized the type before,
+ // no need to do it again.
+ b := &typecache[t.Hash&(typeCacheBuckets-1)]
+ if t == b.t[0] {
+ return
+ }
+ for i := 1; i < typeCacheAssoc; i++ {
+ if t == b.t[i] {
+ // Move-to-front
+ for j := i; j > 0; j-- {
+ b.t[j] = b.t[j-1]
+ }
+ b.t[0] = t
+ return
+ }
+ }
+
+ // Might not have been dumped yet. Dump it and
+ // remember we did so.
+ for j := typeCacheAssoc - 1; j > 0; j-- {
+ b.t[j] = b.t[j-1]
+ }
+ b.t[0] = t
+
+ // dump the type
+ dumpint(tagType)
+ dumpint(uint64(uintptr(unsafe.Pointer(t))))
+ dumpint(uint64(t.Size_))
+ rt := toRType(t)
+ if x := t.Uncommon(); x == nil || rt.nameOff(x.PkgPath).Name() == "" {
+ dumpstr(rt.string())
+ } else {
+ pkgpath := rt.nameOff(x.PkgPath).Name()
+ name := rt.name()
+ dumpint(uint64(uintptr(len(pkgpath)) + 1 + uintptr(len(name))))
+ dwrite(unsafe.Pointer(unsafe.StringData(pkgpath)), uintptr(len(pkgpath)))
+ dwritebyte('.')
+ dwrite(unsafe.Pointer(unsafe.StringData(name)), uintptr(len(name)))
+ }
+ dumpbool(t.Kind_&kindDirectIface == 0 || t.PtrBytes != 0)
+}
+
+// dump an object.
+func dumpobj(obj unsafe.Pointer, size uintptr, bv bitvector) {
+ dumpint(tagObject)
+ dumpint(uint64(uintptr(obj)))
+ dumpmemrange(obj, size)
+ dumpfields(bv)
+}
+
+func dumpotherroot(description string, to unsafe.Pointer) {
+ dumpint(tagOtherRoot)
+ dumpstr(description)
+ dumpint(uint64(uintptr(to)))
+}
+
+func dumpfinalizer(obj unsafe.Pointer, fn *funcval, fint *_type, ot *ptrtype) {
+ dumpint(tagFinalizer)
+ dumpint(uint64(uintptr(obj)))
+ dumpint(uint64(uintptr(unsafe.Pointer(fn))))
+ dumpint(uint64(uintptr(unsafe.Pointer(fn.fn))))
+ dumpint(uint64(uintptr(unsafe.Pointer(fint))))
+ dumpint(uint64(uintptr(unsafe.Pointer(ot))))
+}
+
+type childInfo struct {
+ // Information passed up from the callee frame about
+ // the layout of the outargs region.
+ argoff uintptr // where the arguments start in the frame
+ arglen uintptr // size of args region
+ args bitvector // if args.n >= 0, pointer map of args region
+ sp *uint8 // callee sp
+ depth uintptr // depth in call stack (0 == most recent)
+}
+
+// dump kinds & offsets of interesting fields in bv.
+func dumpbv(cbv *bitvector, offset uintptr) {
+ for i := uintptr(0); i < uintptr(cbv.n); i++ {
+ if cbv.ptrbit(i) == 1 {
+ dumpint(fieldKindPtr)
+ dumpint(uint64(offset + i*goarch.PtrSize))
+ }
+ }
+}
+
+func dumpframe(s *stkframe, child *childInfo) {
+ f := s.fn
+
+ // Figure out what we can about our stack map
+ pc := s.pc
+ pcdata := int32(-1) // Use the entry map at function entry
+ if pc != f.entry() {
+ pc--
+ pcdata = pcdatavalue(f, abi.PCDATA_StackMapIndex, pc, nil)
+ }
+ if pcdata == -1 {
+ // We do not have a valid pcdata value but there might be a
+ // stackmap for this function. It is likely that we are looking
+ // at the function prologue, assume so and hope for the best.
+ pcdata = 0
+ }
+ stkmap := (*stackmap)(funcdata(f, abi.FUNCDATA_LocalsPointerMaps))
+
+ var bv bitvector
+ if stkmap != nil && stkmap.n > 0 {
+ bv = stackmapdata(stkmap, pcdata)
+ } else {
+ bv.n = -1
+ }
+
+ // Dump main body of stack frame.
+ dumpint(tagStackFrame)
+ dumpint(uint64(s.sp)) // lowest address in frame
+ dumpint(uint64(child.depth)) // # of frames deep on the stack
+ dumpint(uint64(uintptr(unsafe.Pointer(child.sp)))) // sp of child, or 0 if bottom of stack
+ dumpmemrange(unsafe.Pointer(s.sp), s.fp-s.sp) // frame contents
+ dumpint(uint64(f.entry()))
+ dumpint(uint64(s.pc))
+ dumpint(uint64(s.continpc))
+ name := funcname(f)
+ if name == "" {
+ name = "unknown function"
+ }
+ dumpstr(name)
+
+ // Dump fields in the outargs section
+ if child.args.n >= 0 {
+ dumpbv(&child.args, child.argoff)
+ } else {
+ // conservative - everything might be a pointer
+ for off := child.argoff; off < child.argoff+child.arglen; off += goarch.PtrSize {
+ dumpint(fieldKindPtr)
+ dumpint(uint64(off))
+ }
+ }
+
+ // Dump fields in the local vars section
+ if stkmap == nil {
+ // No locals information, dump everything.
+ for off := child.arglen; off < s.varp-s.sp; off += goarch.PtrSize {
+ dumpint(fieldKindPtr)
+ dumpint(uint64(off))
+ }
+ } else if stkmap.n < 0 {
+ // Locals size information, dump just the locals.
+ size := uintptr(-stkmap.n)
+ for off := s.varp - size - s.sp; off < s.varp-s.sp; off += goarch.PtrSize {
+ dumpint(fieldKindPtr)
+ dumpint(uint64(off))
+ }
+ } else if stkmap.n > 0 {
+ // Locals bitmap information, scan just the pointers in
+ // locals.
+ dumpbv(&bv, s.varp-uintptr(bv.n)*goarch.PtrSize-s.sp)
+ }
+ dumpint(fieldKindEol)
+
+ // Record arg info for parent.
+ child.argoff = s.argp - s.fp
+ child.arglen = s.argBytes()
+ child.sp = (*uint8)(unsafe.Pointer(s.sp))
+ child.depth++
+ stkmap = (*stackmap)(funcdata(f, abi.FUNCDATA_ArgsPointerMaps))
+ if stkmap != nil {
+ child.args = stackmapdata(stkmap, pcdata)
+ } else {
+ child.args.n = -1
+ }
+ return
+}
+
+func dumpgoroutine(gp *g) {
+ var sp, pc, lr uintptr
+ if gp.syscallsp != 0 {
+ sp = gp.syscallsp
+ pc = gp.syscallpc
+ lr = 0
+ } else {
+ sp = gp.sched.sp
+ pc = gp.sched.pc
+ lr = gp.sched.lr
+ }
+
+ dumpint(tagGoroutine)
+ dumpint(uint64(uintptr(unsafe.Pointer(gp))))
+ dumpint(uint64(sp))
+ dumpint(gp.goid)
+ dumpint(uint64(gp.gopc))
+ dumpint(uint64(readgstatus(gp)))
+ dumpbool(isSystemGoroutine(gp, false))
+ dumpbool(false) // isbackground
+ dumpint(uint64(gp.waitsince))
+ dumpstr(gp.waitreason.String())
+ dumpint(uint64(uintptr(gp.sched.ctxt)))
+ dumpint(uint64(uintptr(unsafe.Pointer(gp.m))))
+ dumpint(uint64(uintptr(unsafe.Pointer(gp._defer))))
+ dumpint(uint64(uintptr(unsafe.Pointer(gp._panic))))
+
+ // dump stack
+ var child childInfo
+ child.args.n = -1
+ child.arglen = 0
+ child.sp = nil
+ child.depth = 0
+ var u unwinder
+ for u.initAt(pc, sp, lr, gp, 0); u.valid(); u.next() {
+ dumpframe(&u.frame, &child)
+ }
+
+ // dump defer & panic records
+ for d := gp._defer; d != nil; d = d.link {
+ dumpint(tagDefer)
+ dumpint(uint64(uintptr(unsafe.Pointer(d))))
+ dumpint(uint64(uintptr(unsafe.Pointer(gp))))
+ dumpint(uint64(d.sp))
+ dumpint(uint64(d.pc))
+ fn := *(**funcval)(unsafe.Pointer(&d.fn))
+ dumpint(uint64(uintptr(unsafe.Pointer(fn))))
+ if d.fn == nil {
+ // d.fn can be nil for open-coded defers
+ dumpint(uint64(0))
+ } else {
+ dumpint(uint64(uintptr(unsafe.Pointer(fn.fn))))
+ }
+ dumpint(uint64(uintptr(unsafe.Pointer(d.link))))
+ }
+ for p := gp._panic; p != nil; p = p.link {
+ dumpint(tagPanic)
+ dumpint(uint64(uintptr(unsafe.Pointer(p))))
+ dumpint(uint64(uintptr(unsafe.Pointer(gp))))
+ eface := efaceOf(&p.arg)
+ dumpint(uint64(uintptr(unsafe.Pointer(eface._type))))
+ dumpint(uint64(uintptr(unsafe.Pointer(eface.data))))
+ dumpint(0) // was p->defer, no longer recorded
+ dumpint(uint64(uintptr(unsafe.Pointer(p.link))))
+ }
+}
+
+func dumpgs() {
+ assertWorldStopped()
+
+ // goroutines & stacks
+ forEachG(func(gp *g) {
+ status := readgstatus(gp) // The world is stopped so gp will not be in a scan state.
+ switch status {
+ default:
+ print("runtime: unexpected G.status ", hex(status), "\n")
+ throw("dumpgs in STW - bad status")
+ case _Gdead:
+ // ok
+ case _Grunnable,
+ _Gsyscall,
+ _Gwaiting:
+ dumpgoroutine(gp)
+ }
+ })
+}
+
+func finq_callback(fn *funcval, obj unsafe.Pointer, nret uintptr, fint *_type, ot *ptrtype) {
+ dumpint(tagQueuedFinalizer)
+ dumpint(uint64(uintptr(obj)))
+ dumpint(uint64(uintptr(unsafe.Pointer(fn))))
+ dumpint(uint64(uintptr(unsafe.Pointer(fn.fn))))
+ dumpint(uint64(uintptr(unsafe.Pointer(fint))))
+ dumpint(uint64(uintptr(unsafe.Pointer(ot))))
+}
+
+func dumproots() {
+ // To protect mheap_.allspans.
+ assertWorldStopped()
+
+ // TODO(mwhudson): dump datamask etc from all objects
+ // data segment
+ dumpint(tagData)
+ dumpint(uint64(firstmoduledata.data))
+ dumpmemrange(unsafe.Pointer(firstmoduledata.data), firstmoduledata.edata-firstmoduledata.data)
+ dumpfields(firstmoduledata.gcdatamask)
+
+ // bss segment
+ dumpint(tagBSS)
+ dumpint(uint64(firstmoduledata.bss))
+ dumpmemrange(unsafe.Pointer(firstmoduledata.bss), firstmoduledata.ebss-firstmoduledata.bss)
+ dumpfields(firstmoduledata.gcbssmask)
+
+ // mspan.types
+ for _, s := range mheap_.allspans {
+ if s.state.get() == mSpanInUse {
+ // Finalizers
+ for sp := s.specials; sp != nil; sp = sp.next {
+ if sp.kind != _KindSpecialFinalizer {
+ continue
+ }
+ spf := (*specialfinalizer)(unsafe.Pointer(sp))
+ p := unsafe.Pointer(s.base() + uintptr(spf.special.offset))
+ dumpfinalizer(p, spf.fn, spf.fint, spf.ot)
+ }
+ }
+ }
+
+ // Finalizer queue
+ iterate_finq(finq_callback)
+}
+
+// Bit vector of free marks.
+// Needs to be as big as the largest number of objects per span.
+var freemark [_PageSize / 8]bool
+
+func dumpobjs() {
+ // To protect mheap_.allspans.
+ assertWorldStopped()
+
+ for _, s := range mheap_.allspans {
+ if s.state.get() != mSpanInUse {
+ continue
+ }
+ p := s.base()
+ size := s.elemsize
+ n := (s.npages << _PageShift) / size
+ if n > uintptr(len(freemark)) {
+ throw("freemark array doesn't have enough entries")
+ }
+
+ for freeIndex := uintptr(0); freeIndex < s.nelems; freeIndex++ {
+ if s.isFree(freeIndex) {
+ freemark[freeIndex] = true
+ }
+ }
+
+ for j := uintptr(0); j < n; j, p = j+1, p+size {
+ if freemark[j] {
+ freemark[j] = false
+ continue
+ }
+ dumpobj(unsafe.Pointer(p), size, makeheapobjbv(p, size))
+ }
+ }
+}
+
+func dumpparams() {
+ dumpint(tagParams)
+ x := uintptr(1)
+ if *(*byte)(unsafe.Pointer(&x)) == 1 {
+ dumpbool(false) // little-endian ptrs
+ } else {
+ dumpbool(true) // big-endian ptrs
+ }
+ dumpint(goarch.PtrSize)
+ var arenaStart, arenaEnd uintptr
+ for i1 := range mheap_.arenas {
+ if mheap_.arenas[i1] == nil {
+ continue
+ }
+ for i, ha := range mheap_.arenas[i1] {
+ if ha == nil {
+ continue
+ }
+ base := arenaBase(arenaIdx(i1)<<arenaL1Shift | arenaIdx(i))
+ if arenaStart == 0 || base < arenaStart {
+ arenaStart = base
+ }
+ if base+heapArenaBytes > arenaEnd {
+ arenaEnd = base + heapArenaBytes
+ }
+ }
+ }
+ dumpint(uint64(arenaStart))
+ dumpint(uint64(arenaEnd))
+ dumpstr(goarch.GOARCH)
+ dumpstr(buildVersion)
+ dumpint(uint64(ncpu))
+}
+
+func itab_callback(tab *itab) {
+ t := tab._type
+ dumptype(t)
+ dumpint(tagItab)
+ dumpint(uint64(uintptr(unsafe.Pointer(tab))))
+ dumpint(uint64(uintptr(unsafe.Pointer(t))))
+}
+
+func dumpitabs() {
+ iterate_itabs(itab_callback)
+}
+
+func dumpms() {
+ for mp := allm; mp != nil; mp = mp.alllink {
+ dumpint(tagOSThread)
+ dumpint(uint64(uintptr(unsafe.Pointer(mp))))
+ dumpint(uint64(mp.id))
+ dumpint(mp.procid)
+ }
+}
+
+//go:systemstack
+func dumpmemstats(m *MemStats) {
+ assertWorldStopped()
+
+ // These ints should be identical to the exported
+ // MemStats structure and should be ordered the same
+ // way too.
+ dumpint(tagMemStats)
+ dumpint(m.Alloc)
+ dumpint(m.TotalAlloc)
+ dumpint(m.Sys)
+ dumpint(m.Lookups)
+ dumpint(m.Mallocs)
+ dumpint(m.Frees)
+ dumpint(m.HeapAlloc)
+ dumpint(m.HeapSys)
+ dumpint(m.HeapIdle)
+ dumpint(m.HeapInuse)
+ dumpint(m.HeapReleased)
+ dumpint(m.HeapObjects)
+ dumpint(m.StackInuse)
+ dumpint(m.StackSys)
+ dumpint(m.MSpanInuse)
+ dumpint(m.MSpanSys)
+ dumpint(m.MCacheInuse)
+ dumpint(m.MCacheSys)
+ dumpint(m.BuckHashSys)
+ dumpint(m.GCSys)
+ dumpint(m.OtherSys)
+ dumpint(m.NextGC)
+ dumpint(m.LastGC)
+ dumpint(m.PauseTotalNs)
+ for i := 0; i < 256; i++ {
+ dumpint(m.PauseNs[i])
+ }
+ dumpint(uint64(m.NumGC))
+}
+
+func dumpmemprof_callback(b *bucket, nstk uintptr, pstk *uintptr, size, allocs, frees uintptr) {
+ stk := (*[100000]uintptr)(unsafe.Pointer(pstk))
+ dumpint(tagMemProf)
+ dumpint(uint64(uintptr(unsafe.Pointer(b))))
+ dumpint(uint64(size))
+ dumpint(uint64(nstk))
+ for i := uintptr(0); i < nstk; i++ {
+ pc := stk[i]
+ f := findfunc(pc)
+ if !f.valid() {
+ var buf [64]byte
+ n := len(buf)
+ n--
+ buf[n] = ')'
+ if pc == 0 {
+ n--
+ buf[n] = '0'
+ } else {
+ for pc > 0 {
+ n--
+ buf[n] = "0123456789abcdef"[pc&15]
+ pc >>= 4
+ }
+ }
+ n--
+ buf[n] = 'x'
+ n--
+ buf[n] = '0'
+ n--
+ buf[n] = '('
+ dumpslice(buf[n:])
+ dumpstr("?")
+ dumpint(0)
+ } else {
+ dumpstr(funcname(f))
+ if i > 0 && pc > f.entry() {
+ pc--
+ }
+ file, line := funcline(f, pc)
+ dumpstr(file)
+ dumpint(uint64(line))
+ }
+ }
+ dumpint(uint64(allocs))
+ dumpint(uint64(frees))
+}
+
+func dumpmemprof() {
+ // To protect mheap_.allspans.
+ assertWorldStopped()
+
+ iterate_memprof(dumpmemprof_callback)
+ for _, s := range mheap_.allspans {
+ if s.state.get() != mSpanInUse {
+ continue
+ }
+ for sp := s.specials; sp != nil; sp = sp.next {
+ if sp.kind != _KindSpecialProfile {
+ continue
+ }
+ spp := (*specialprofile)(unsafe.Pointer(sp))
+ p := s.base() + uintptr(spp.special.offset)
+ dumpint(tagAllocSample)
+ dumpint(uint64(p))
+ dumpint(uint64(uintptr(unsafe.Pointer(spp.b))))
+ }
+ }
+}
+
+var dumphdr = []byte("go1.7 heap dump\n")
+
+func mdump(m *MemStats) {
+ assertWorldStopped()
+
+ // make sure we're done sweeping
+ for _, s := range mheap_.allspans {
+ if s.state.get() == mSpanInUse {
+ s.ensureSwept()
+ }
+ }
+ memclrNoHeapPointers(unsafe.Pointer(&typecache), unsafe.Sizeof(typecache))
+ dwrite(unsafe.Pointer(&dumphdr[0]), uintptr(len(dumphdr)))
+ dumpparams()
+ dumpitabs()
+ dumpobjs()
+ dumpgs()
+ dumpms()
+ dumproots()
+ dumpmemstats(m)
+ dumpmemprof()
+ dumpint(tagEOF)
+ flush()
+}
+
+func writeheapdump_m(fd uintptr, m *MemStats) {
+ assertWorldStopped()
+
+ gp := getg()
+ casGToWaiting(gp.m.curg, _Grunning, waitReasonDumpingHeap)
+
+ // Set dump file.
+ dumpfd = fd
+
+ // Call dump routine.
+ mdump(m)
+
+ // Reset dump file.
+ dumpfd = 0
+ if tmpbuf != nil {
+ sysFree(unsafe.Pointer(&tmpbuf[0]), uintptr(len(tmpbuf)), &memstats.other_sys)
+ tmpbuf = nil
+ }
+
+ casgstatus(gp.m.curg, _Gwaiting, _Grunning)
+}
+
+// dumpint() the kind & offset of each field in an object.
+func dumpfields(bv bitvector) {
+ dumpbv(&bv, 0)
+ dumpint(fieldKindEol)
+}
+
+func makeheapobjbv(p uintptr, size uintptr) bitvector {
+ // Extend the temp buffer if necessary.
+ nptr := size / goarch.PtrSize
+ if uintptr(len(tmpbuf)) < nptr/8+1 {
+ if tmpbuf != nil {
+ sysFree(unsafe.Pointer(&tmpbuf[0]), uintptr(len(tmpbuf)), &memstats.other_sys)
+ }
+ n := nptr/8 + 1
+ p := sysAlloc(n, &memstats.other_sys)
+ if p == nil {
+ throw("heapdump: out of memory")
+ }
+ tmpbuf = (*[1 << 30]byte)(p)[:n]
+ }
+ // Convert heap bitmap to pointer bitmap.
+ for i := uintptr(0); i < nptr/8+1; i++ {
+ tmpbuf[i] = 0
+ }
+
+ hbits := heapBitsForAddr(p, size)
+ for {
+ var addr uintptr
+ hbits, addr = hbits.next()
+ if addr == 0 {
+ break
+ }
+ i := (addr - p) / goarch.PtrSize
+ tmpbuf[i/8] |= 1 << (i % 8)
+ }
+ return bitvector{int32(nptr), &tmpbuf[0]}
+}
diff --git a/contrib/go/_std_1.20/src/runtime/histogram.go b/contrib/go/_std_1.21/src/runtime/histogram.go
index 43dfe61901..43dfe61901 100644
--- a/contrib/go/_std_1.20/src/runtime/histogram.go
+++ b/contrib/go/_std_1.21/src/runtime/histogram.go
diff --git a/contrib/go/_std_1.21/src/runtime/iface.go b/contrib/go/_std_1.21/src/runtime/iface.go
new file mode 100644
index 0000000000..87f7c20f5d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/iface.go
@@ -0,0 +1,534 @@
+// Copyright 2014 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+const itabInitSize = 512
+
+var (
+ itabLock mutex // lock for accessing itab table
+ itabTable = &itabTableInit // pointer to current table
+ itabTableInit = itabTableType{size: itabInitSize} // starter table
+)
+
+// Note: change the formula in the mallocgc call in itabAdd if you change these fields.
+type itabTableType struct {
+ size uintptr // length of entries array. Always a power of 2.
+ count uintptr // current number of filled entries.
+ entries [itabInitSize]*itab // really [size] large
+}
+
+func itabHashFunc(inter *interfacetype, typ *_type) uintptr {
+ // compiler has provided some good hash codes for us.
+ return uintptr(inter.Type.Hash ^ typ.Hash)
+}
+
+func getitab(inter *interfacetype, typ *_type, canfail bool) *itab {
+ if len(inter.Methods) == 0 {
+ throw("internal error - misuse of itab")
+ }
+
+ // easy case
+ if typ.TFlag&abi.TFlagUncommon == 0 {
+ if canfail {
+ return nil
+ }
+ name := toRType(&inter.Type).nameOff(inter.Methods[0].Name)
+ panic(&TypeAssertionError{nil, typ, &inter.Type, name.Name()})
+ }
+
+ var m *itab
+
+ // First, look in the existing table to see if we can find the itab we need.
+ // This is by far the most common case, so do it without locks.
+ // Use atomic to ensure we see any previous writes done by the thread
+ // that updates the itabTable field (with atomic.Storep in itabAdd).
+ t := (*itabTableType)(atomic.Loadp(unsafe.Pointer(&itabTable)))
+ if m = t.find(inter, typ); m != nil {
+ goto finish
+ }
+
+ // Not found. Grab the lock and try again.
+ lock(&itabLock)
+ if m = itabTable.find(inter, typ); m != nil {
+ unlock(&itabLock)
+ goto finish
+ }
+
+ // Entry doesn't exist yet. Make a new entry & add it.
+ m = (*itab)(persistentalloc(unsafe.Sizeof(itab{})+uintptr(len(inter.Methods)-1)*goarch.PtrSize, 0, &memstats.other_sys))
+ m.inter = inter
+ m._type = typ
+ // The hash is used in type switches. However, compiler statically generates itab's
+ // for all interface/type pairs used in switches (which are added to itabTable
+ // in itabsinit). The dynamically-generated itab's never participate in type switches,
+ // and thus the hash is irrelevant.
+ // Note: m.hash is _not_ the hash used for the runtime itabTable hash table.
+ m.hash = 0
+ m.init()
+ itabAdd(m)
+ unlock(&itabLock)
+finish:
+ if m.fun[0] != 0 {
+ return m
+ }
+ if canfail {
+ return nil
+ }
+ // this can only happen if the conversion
+ // was already done once using the , ok form
+ // and we have a cached negative result.
+ // The cached result doesn't record which
+ // interface function was missing, so initialize
+ // the itab again to get the missing function name.
+ panic(&TypeAssertionError{concrete: typ, asserted: &inter.Type, missingMethod: m.init()})
+}
+
+// find finds the given interface/type pair in t.
+// Returns nil if the given interface/type pair isn't present.
+func (t *itabTableType) find(inter *interfacetype, typ *_type) *itab {
+ // Implemented using quadratic probing.
+ // Probe sequence is h(i) = h0 + i*(i+1)/2 mod 2^k.
+ // We're guaranteed to hit all table entries using this probe sequence.
+ mask := t.size - 1
+ h := itabHashFunc(inter, typ) & mask
+ for i := uintptr(1); ; i++ {
+ p := (**itab)(add(unsafe.Pointer(&t.entries), h*goarch.PtrSize))
+ // Use atomic read here so if we see m != nil, we also see
+ // the initializations of the fields of m.
+ // m := *p
+ m := (*itab)(atomic.Loadp(unsafe.Pointer(p)))
+ if m == nil {
+ return nil
+ }
+ if m.inter == inter && m._type == typ {
+ return m
+ }
+ h += i
+ h &= mask
+ }
+}
+
+// itabAdd adds the given itab to the itab hash table.
+// itabLock must be held.
+func itabAdd(m *itab) {
+ // Bugs can lead to calling this while mallocing is set,
+ // typically because this is called while panicking.
+ // Crash reliably, rather than only when we need to grow
+ // the hash table.
+ if getg().m.mallocing != 0 {
+ throw("malloc deadlock")
+ }
+
+ t := itabTable
+ if t.count >= 3*(t.size/4) { // 75% load factor
+ // Grow hash table.
+ // t2 = new(itabTableType) + some additional entries
+ // We lie and tell malloc we want pointer-free memory because
+ // all the pointed-to values are not in the heap.
+ t2 := (*itabTableType)(mallocgc((2+2*t.size)*goarch.PtrSize, nil, true))
+ t2.size = t.size * 2
+
+ // Copy over entries.
+ // Note: while copying, other threads may look for an itab and
+ // fail to find it. That's ok, they will then try to get the itab lock
+ // and as a consequence wait until this copying is complete.
+ iterate_itabs(t2.add)
+ if t2.count != t.count {
+ throw("mismatched count during itab table copy")
+ }
+ // Publish new hash table. Use an atomic write: see comment in getitab.
+ atomicstorep(unsafe.Pointer(&itabTable), unsafe.Pointer(t2))
+ // Adopt the new table as our own.
+ t = itabTable
+ // Note: the old table can be GC'ed here.
+ }
+ t.add(m)
+}
+
+// add adds the given itab to itab table t.
+// itabLock must be held.
+func (t *itabTableType) add(m *itab) {
+ // See comment in find about the probe sequence.
+ // Insert new itab in the first empty spot in the probe sequence.
+ mask := t.size - 1
+ h := itabHashFunc(m.inter, m._type) & mask
+ for i := uintptr(1); ; i++ {
+ p := (**itab)(add(unsafe.Pointer(&t.entries), h*goarch.PtrSize))
+ m2 := *p
+ if m2 == m {
+ // A given itab may be used in more than one module
+ // and thanks to the way global symbol resolution works, the
+ // pointed-to itab may already have been inserted into the
+ // global 'hash'.
+ return
+ }
+ if m2 == nil {
+ // Use atomic write here so if a reader sees m, it also
+ // sees the correctly initialized fields of m.
+ // NoWB is ok because m is not in heap memory.
+ // *p = m
+ atomic.StorepNoWB(unsafe.Pointer(p), unsafe.Pointer(m))
+ t.count++
+ return
+ }
+ h += i
+ h &= mask
+ }
+}
+
+// init fills in the m.fun array with all the code pointers for
+// the m.inter/m._type pair. If the type does not implement the interface,
+// it sets m.fun[0] to 0 and returns the name of an interface function that is missing.
+// It is ok to call this multiple times on the same m, even concurrently.
+func (m *itab) init() string {
+ inter := m.inter
+ typ := m._type
+ x := typ.Uncommon()
+
+ // both inter and typ have method sorted by name,
+ // and interface names are unique,
+ // so can iterate over both in lock step;
+ // the loop is O(ni+nt) not O(ni*nt).
+ ni := len(inter.Methods)
+ nt := int(x.Mcount)
+ xmhdr := (*[1 << 16]abi.Method)(add(unsafe.Pointer(x), uintptr(x.Moff)))[:nt:nt]
+ j := 0
+ methods := (*[1 << 16]unsafe.Pointer)(unsafe.Pointer(&m.fun[0]))[:ni:ni]
+ var fun0 unsafe.Pointer
+imethods:
+ for k := 0; k < ni; k++ {
+ i := &inter.Methods[k]
+ itype := toRType(&inter.Type).typeOff(i.Typ)
+ name := toRType(&inter.Type).nameOff(i.Name)
+ iname := name.Name()
+ ipkg := pkgPath(name)
+ if ipkg == "" {
+ ipkg = inter.PkgPath.Name()
+ }
+ for ; j < nt; j++ {
+ t := &xmhdr[j]
+ rtyp := toRType(typ)
+ tname := rtyp.nameOff(t.Name)
+ if rtyp.typeOff(t.Mtyp) == itype && tname.Name() == iname {
+ pkgPath := pkgPath(tname)
+ if pkgPath == "" {
+ pkgPath = rtyp.nameOff(x.PkgPath).Name()
+ }
+ if tname.IsExported() || pkgPath == ipkg {
+ if m != nil {
+ ifn := rtyp.textOff(t.Ifn)
+ if k == 0 {
+ fun0 = ifn // we'll set m.fun[0] at the end
+ } else {
+ methods[k] = ifn
+ }
+ }
+ continue imethods
+ }
+ }
+ }
+ // didn't find method
+ m.fun[0] = 0
+ return iname
+ }
+ m.fun[0] = uintptr(fun0)
+ return ""
+}
+
+func itabsinit() {
+ lockInit(&itabLock, lockRankItab)
+ lock(&itabLock)
+ for _, md := range activeModules() {
+ for _, i := range md.itablinks {
+ itabAdd(i)
+ }
+ }
+ unlock(&itabLock)
+}
+
+// panicdottypeE is called when doing an e.(T) conversion and the conversion fails.
+// have = the dynamic type we have.
+// want = the static type we're trying to convert to.
+// iface = the static type we're converting from.
+func panicdottypeE(have, want, iface *_type) {
+ panic(&TypeAssertionError{iface, have, want, ""})
+}
+
+// panicdottypeI is called when doing an i.(T) conversion and the conversion fails.
+// Same args as panicdottypeE, but "have" is the dynamic itab we have.
+func panicdottypeI(have *itab, want, iface *_type) {
+ var t *_type
+ if have != nil {
+ t = have._type
+ }
+ panicdottypeE(t, want, iface)
+}
+
+// panicnildottype is called when doing an i.(T) conversion and the interface i is nil.
+// want = the static type we're trying to convert to.
+func panicnildottype(want *_type) {
+ panic(&TypeAssertionError{nil, nil, want, ""})
+ // TODO: Add the static type we're converting from as well.
+ // It might generate a better error message.
+ // Just to match other nil conversion errors, we don't for now.
+}
+
+// The specialized convTx routines need a type descriptor to use when calling mallocgc.
+// We don't need the type to be exact, just to have the correct size, alignment, and pointer-ness.
+// However, when debugging, it'd be nice to have some indication in mallocgc where the types came from,
+// so we use named types here.
+// We then construct interface values of these types,
+// and then extract the type word to use as needed.
+type (
+ uint16InterfacePtr uint16
+ uint32InterfacePtr uint32
+ uint64InterfacePtr uint64
+ stringInterfacePtr string
+ sliceInterfacePtr []byte
+)
+
+var (
+ uint16Eface any = uint16InterfacePtr(0)
+ uint32Eface any = uint32InterfacePtr(0)
+ uint64Eface any = uint64InterfacePtr(0)
+ stringEface any = stringInterfacePtr("")
+ sliceEface any = sliceInterfacePtr(nil)
+
+ uint16Type *_type = efaceOf(&uint16Eface)._type
+ uint32Type *_type = efaceOf(&uint32Eface)._type
+ uint64Type *_type = efaceOf(&uint64Eface)._type
+ stringType *_type = efaceOf(&stringEface)._type
+ sliceType *_type = efaceOf(&sliceEface)._type
+)
+
+// The conv and assert functions below do very similar things.
+// The convXXX functions are guaranteed by the compiler to succeed.
+// The assertXXX functions may fail (either panicking or returning false,
+// depending on whether they are 1-result or 2-result).
+// The convXXX functions succeed on a nil input, whereas the assertXXX
+// functions fail on a nil input.
+
+// convT converts a value of type t, which is pointed to by v, to a pointer that can
+// be used as the second word of an interface value.
+func convT(t *_type, v unsafe.Pointer) unsafe.Pointer {
+ if raceenabled {
+ raceReadObjectPC(t, v, getcallerpc(), abi.FuncPCABIInternal(convT))
+ }
+ if msanenabled {
+ msanread(v, t.Size_)
+ }
+ if asanenabled {
+ asanread(v, t.Size_)
+ }
+ x := mallocgc(t.Size_, t, true)
+ typedmemmove(t, x, v)
+ return x
+}
+func convTnoptr(t *_type, v unsafe.Pointer) unsafe.Pointer {
+ // TODO: maybe take size instead of type?
+ if raceenabled {
+ raceReadObjectPC(t, v, getcallerpc(), abi.FuncPCABIInternal(convTnoptr))
+ }
+ if msanenabled {
+ msanread(v, t.Size_)
+ }
+ if asanenabled {
+ asanread(v, t.Size_)
+ }
+
+ x := mallocgc(t.Size_, t, false)
+ memmove(x, v, t.Size_)
+ return x
+}
+
+func convT16(val uint16) (x unsafe.Pointer) {
+ if val < uint16(len(staticuint64s)) {
+ x = unsafe.Pointer(&staticuint64s[val])
+ if goarch.BigEndian {
+ x = add(x, 6)
+ }
+ } else {
+ x = mallocgc(2, uint16Type, false)
+ *(*uint16)(x) = val
+ }
+ return
+}
+
+func convT32(val uint32) (x unsafe.Pointer) {
+ if val < uint32(len(staticuint64s)) {
+ x = unsafe.Pointer(&staticuint64s[val])
+ if goarch.BigEndian {
+ x = add(x, 4)
+ }
+ } else {
+ x = mallocgc(4, uint32Type, false)
+ *(*uint32)(x) = val
+ }
+ return
+}
+
+func convT64(val uint64) (x unsafe.Pointer) {
+ if val < uint64(len(staticuint64s)) {
+ x = unsafe.Pointer(&staticuint64s[val])
+ } else {
+ x = mallocgc(8, uint64Type, false)
+ *(*uint64)(x) = val
+ }
+ return
+}
+
+func convTstring(val string) (x unsafe.Pointer) {
+ if val == "" {
+ x = unsafe.Pointer(&zeroVal[0])
+ } else {
+ x = mallocgc(unsafe.Sizeof(val), stringType, true)
+ *(*string)(x) = val
+ }
+ return
+}
+
+func convTslice(val []byte) (x unsafe.Pointer) {
+ // Note: this must work for any element type, not just byte.
+ if (*slice)(unsafe.Pointer(&val)).array == nil {
+ x = unsafe.Pointer(&zeroVal[0])
+ } else {
+ x = mallocgc(unsafe.Sizeof(val), sliceType, true)
+ *(*[]byte)(x) = val
+ }
+ return
+}
+
+// convI2I returns the new itab to be used for the destination value
+// when converting a value with itab src to the dst interface.
+func convI2I(dst *interfacetype, src *itab) *itab {
+ if src == nil {
+ return nil
+ }
+ if src.inter == dst {
+ return src
+ }
+ return getitab(dst, src._type, false)
+}
+
+func assertI2I(inter *interfacetype, tab *itab) *itab {
+ if tab == nil {
+ // explicit conversions require non-nil interface value.
+ panic(&TypeAssertionError{nil, nil, &inter.Type, ""})
+ }
+ if tab.inter == inter {
+ return tab
+ }
+ return getitab(inter, tab._type, false)
+}
+
+func assertI2I2(inter *interfacetype, i iface) (r iface) {
+ tab := i.tab
+ if tab == nil {
+ return
+ }
+ if tab.inter != inter {
+ tab = getitab(inter, tab._type, true)
+ if tab == nil {
+ return
+ }
+ }
+ r.tab = tab
+ r.data = i.data
+ return
+}
+
+func assertE2I(inter *interfacetype, t *_type) *itab {
+ if t == nil {
+ // explicit conversions require non-nil interface value.
+ panic(&TypeAssertionError{nil, nil, &inter.Type, ""})
+ }
+ return getitab(inter, t, false)
+}
+
+func assertE2I2(inter *interfacetype, e eface) (r iface) {
+ t := e._type
+ if t == nil {
+ return
+ }
+ tab := getitab(inter, t, true)
+ if tab == nil {
+ return
+ }
+ r.tab = tab
+ r.data = e.data
+ return
+}
+
+//go:linkname reflect_ifaceE2I reflect.ifaceE2I
+func reflect_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
+ *dst = iface{assertE2I(inter, e._type), e.data}
+}
+
+//go:linkname reflectlite_ifaceE2I internal/reflectlite.ifaceE2I
+func reflectlite_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
+ *dst = iface{assertE2I(inter, e._type), e.data}
+}
+
+func iterate_itabs(fn func(*itab)) {
+ // Note: only runs during stop the world or with itabLock held,
+ // so no other locks/atomics needed.
+ t := itabTable
+ for i := uintptr(0); i < t.size; i++ {
+ m := *(**itab)(add(unsafe.Pointer(&t.entries), i*goarch.PtrSize))
+ if m != nil {
+ fn(m)
+ }
+ }
+}
+
+// staticuint64s is used to avoid allocating in convTx for small integer values.
+var staticuint64s = [...]uint64{
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+}
+
+// The linker redirects a reference of a method that it determined
+// unreachable to a reference to this function, so it will throw if
+// ever called.
+func unreachableMethod() {
+ throw("unreachable method called. linker bug?")
+}
diff --git a/contrib/go/_std_1.20/src/runtime/internal/atomic/atomic_amd64.go b/contrib/go/_std_1.21/src/runtime/internal/atomic/atomic_amd64.go
index 52a83620c8..52a83620c8 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/atomic/atomic_amd64.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/atomic/atomic_amd64.go
diff --git a/contrib/go/_std_1.20/src/runtime/internal/atomic/atomic_amd64.s b/contrib/go/_std_1.21/src/runtime/internal/atomic/atomic_amd64.s
index d21514b36b..d21514b36b 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/atomic/atomic_amd64.s
+++ b/contrib/go/_std_1.21/src/runtime/internal/atomic/atomic_amd64.s
diff --git a/contrib/go/_std_1.20/src/runtime/internal/atomic/atomic_arm64.go b/contrib/go/_std_1.21/src/runtime/internal/atomic/atomic_arm64.go
index 459fb9978d..459fb9978d 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/atomic/atomic_arm64.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/atomic/atomic_arm64.go
diff --git a/contrib/go/_std_1.20/src/runtime/internal/atomic/atomic_arm64.s b/contrib/go/_std_1.21/src/runtime/internal/atomic/atomic_arm64.s
index 5f77d92deb..5f77d92deb 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/atomic/atomic_arm64.s
+++ b/contrib/go/_std_1.21/src/runtime/internal/atomic/atomic_arm64.s
diff --git a/contrib/go/_std_1.20/src/runtime/internal/atomic/doc.go b/contrib/go/_std_1.21/src/runtime/internal/atomic/doc.go
index 08e6b6ce0b..08e6b6ce0b 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/atomic/doc.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/atomic/doc.go
diff --git a/contrib/go/_std_1.20/src/runtime/internal/atomic/stubs.go b/contrib/go/_std_1.21/src/runtime/internal/atomic/stubs.go
index 7df8d9c863..7df8d9c863 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/atomic/stubs.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/atomic/stubs.go
diff --git a/contrib/go/_std_1.20/src/runtime/internal/atomic/types.go b/contrib/go/_std_1.21/src/runtime/internal/atomic/types.go
index 287742fee5..287742fee5 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/atomic/types.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/atomic/types.go
diff --git a/contrib/go/_std_1.20/src/runtime/internal/atomic/types_64bit.go b/contrib/go/_std_1.21/src/runtime/internal/atomic/types_64bit.go
index 006e83ba87..006e83ba87 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/atomic/types_64bit.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/atomic/types_64bit.go
diff --git a/contrib/go/_std_1.20/src/runtime/internal/atomic/unaligned.go b/contrib/go/_std_1.21/src/runtime/internal/atomic/unaligned.go
index a859de4144..a859de4144 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/atomic/unaligned.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/atomic/unaligned.go
diff --git a/contrib/go/_std_1.21/src/runtime/internal/atomic/ya.make b/contrib/go/_std_1.21/src/runtime/internal/atomic/ya.make
new file mode 100644
index 0000000000..7c2eb1c793
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/internal/atomic/ya.make
@@ -0,0 +1,33 @@
+GO_LIBRARY()
+
+SRCS(
+ doc.go
+ stubs.go
+ types.go
+ types_64bit.go
+ unaligned.go
+)
+
+GO_XTEST_SRCS(
+ atomic_test.go
+ bench_test.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ atomic_amd64.go
+ atomic_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ atomic_arm64.go
+ atomic_arm64.s
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/runtime/internal/math/math.go b/contrib/go/_std_1.21/src/runtime/internal/math/math.go
index c3fac366be..c3fac366be 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/math/math.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/math/math.go
diff --git a/contrib/go/_std_1.21/src/runtime/internal/math/ya.make b/contrib/go/_std_1.21/src/runtime/internal/math/ya.make
new file mode 100644
index 0000000000..14e2391073
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/internal/math/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ math.go
+)
+
+GO_XTEST_SRCS(math_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/runtime/internal/startlinetest/func_amd64.go b/contrib/go/_std_1.21/src/runtime/internal/startlinetest/func_amd64.go
index ab7063d615..ab7063d615 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/startlinetest/func_amd64.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/startlinetest/func_amd64.go
diff --git a/contrib/go/_std_1.20/src/runtime/internal/startlinetest/func_amd64.s b/contrib/go/_std_1.21/src/runtime/internal/startlinetest/func_amd64.s
index 96982bedab..96982bedab 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/startlinetest/func_amd64.s
+++ b/contrib/go/_std_1.21/src/runtime/internal/startlinetest/func_amd64.s
diff --git a/contrib/go/_std_1.20/src/runtime/internal/startlinetest/ya.make b/contrib/go/_std_1.21/src/runtime/internal/startlinetest/ya.make
index d14f8588cc..d14f8588cc 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/startlinetest/ya.make
+++ b/contrib/go/_std_1.21/src/runtime/internal/startlinetest/ya.make
diff --git a/contrib/go/_std_1.20/src/runtime/internal/sys/consts.go b/contrib/go/_std_1.21/src/runtime/internal/sys/consts.go
index 98c0f09ef1..98c0f09ef1 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/sys/consts.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/sys/consts.go
diff --git a/contrib/go/_std_1.20/src/runtime/internal/sys/consts_norace.go b/contrib/go/_std_1.21/src/runtime/internal/sys/consts_norace.go
index a9613b8843..a9613b8843 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/sys/consts_norace.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/sys/consts_norace.go
diff --git a/contrib/go/_std_1.21/src/runtime/internal/sys/intrinsics.go b/contrib/go/_std_1.21/src/runtime/internal/sys/intrinsics.go
new file mode 100644
index 0000000000..e6a3758447
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/internal/sys/intrinsics.go
@@ -0,0 +1,208 @@
+// Copyright 2016 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 sys
+
+// Copied from math/bits to avoid dependence.
+
+var deBruijn32tab = [32]byte{
+ 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
+ 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9,
+}
+
+const deBruijn32 = 0x077CB531
+
+var deBruijn64tab = [64]byte{
+ 0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
+ 62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
+ 63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
+ 54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
+}
+
+const deBruijn64 = 0x03f79d71b4ca8b09
+
+const ntz8tab = "" +
+ "\x08\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x06\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x07\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x06\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x05\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00" +
+ "\x04\x00\x01\x00\x02\x00\x01\x00\x03\x00\x01\x00\x02\x00\x01\x00"
+
+// TrailingZeros32 returns the number of trailing zero bits in x; the result is 32 for x == 0.
+func TrailingZeros32(x uint32) int {
+ if x == 0 {
+ return 32
+ }
+ // see comment in TrailingZeros64
+ return int(deBruijn32tab[(x&-x)*deBruijn32>>(32-5)])
+}
+
+// TrailingZeros64 returns the number of trailing zero bits in x; the result is 64 for x == 0.
+func TrailingZeros64(x uint64) int {
+ if x == 0 {
+ return 64
+ }
+ // If popcount is fast, replace code below with return popcount(^x & (x - 1)).
+ //
+ // x & -x leaves only the right-most bit set in the word. Let k be the
+ // index of that bit. Since only a single bit is set, the value is two
+ // to the power of k. Multiplying by a power of two is equivalent to
+ // left shifting, in this case by k bits. The de Bruijn (64 bit) constant
+ // is such that all six bit, consecutive substrings are distinct.
+ // Therefore, if we have a left shifted version of this constant we can
+ // find by how many bits it was shifted by looking at which six bit
+ // substring ended up at the top of the word.
+ // (Knuth, volume 4, section 7.3.1)
+ return int(deBruijn64tab[(x&-x)*deBruijn64>>(64-6)])
+}
+
+// TrailingZeros8 returns the number of trailing zero bits in x; the result is 8 for x == 0.
+func TrailingZeros8(x uint8) int {
+ return int(ntz8tab[x])
+}
+
+const len8tab = "" +
+ "\x00\x01\x02\x02\x03\x03\x03\x03\x04\x04\x04\x04\x04\x04\x04\x04" +
+ "\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05\x05" +
+ "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06" +
+ "\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06\x06" +
+ "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
+ "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
+ "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
+ "\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07\x07" +
+ "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+ "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+ "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+ "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+ "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+ "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+ "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08" +
+ "\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08\x08"
+
+// Len64 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
+//
+// nosplit because this is used in src/runtime/histogram.go, which make run in sensitive contexts.
+//
+//go:nosplit
+func Len64(x uint64) (n int) {
+ if x >= 1<<32 {
+ x >>= 32
+ n = 32
+ }
+ if x >= 1<<16 {
+ x >>= 16
+ n += 16
+ }
+ if x >= 1<<8 {
+ x >>= 8
+ n += 8
+ }
+ return n + int(len8tab[x])
+}
+
+// --- OnesCount ---
+
+const m0 = 0x5555555555555555 // 01010101 ...
+const m1 = 0x3333333333333333 // 00110011 ...
+const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ...
+
+// OnesCount64 returns the number of one bits ("population count") in x.
+func OnesCount64(x uint64) int {
+ // Implementation: Parallel summing of adjacent bits.
+ // See "Hacker's Delight", Chap. 5: Counting Bits.
+ // The following pattern shows the general approach:
+ //
+ // x = x>>1&(m0&m) + x&(m0&m)
+ // x = x>>2&(m1&m) + x&(m1&m)
+ // x = x>>4&(m2&m) + x&(m2&m)
+ // x = x>>8&(m3&m) + x&(m3&m)
+ // x = x>>16&(m4&m) + x&(m4&m)
+ // x = x>>32&(m5&m) + x&(m5&m)
+ // return int(x)
+ //
+ // Masking (& operations) can be left away when there's no
+ // danger that a field's sum will carry over into the next
+ // field: Since the result cannot be > 64, 8 bits is enough
+ // and we can ignore the masks for the shifts by 8 and up.
+ // Per "Hacker's Delight", the first line can be simplified
+ // more, but it saves at best one instruction, so we leave
+ // it alone for clarity.
+ const m = 1<<64 - 1
+ x = x>>1&(m0&m) + x&(m0&m)
+ x = x>>2&(m1&m) + x&(m1&m)
+ x = (x>>4 + x) & (m2 & m)
+ x += x >> 8
+ x += x >> 16
+ x += x >> 32
+ return int(x) & (1<<7 - 1)
+}
+
+// LeadingZeros64 returns the number of leading zero bits in x; the result is 64 for x == 0.
+func LeadingZeros64(x uint64) int { return 64 - Len64(x) }
+
+// LeadingZeros8 returns the number of leading zero bits in x; the result is 8 for x == 0.
+func LeadingZeros8(x uint8) int { return 8 - Len8(x) }
+
+// Len8 returns the minimum number of bits required to represent x; the result is 0 for x == 0.
+func Len8(x uint8) int {
+ return int(len8tab[x])
+}
+
+// Bswap64 returns its input with byte order reversed
+// 0x0102030405060708 -> 0x0807060504030201
+func Bswap64(x uint64) uint64 {
+ c8 := uint64(0x00ff00ff00ff00ff)
+ a := x >> 8 & c8
+ b := (x & c8) << 8
+ x = a | b
+ c16 := uint64(0x0000ffff0000ffff)
+ a = x >> 16 & c16
+ b = (x & c16) << 16
+ x = a | b
+ c32 := uint64(0x00000000ffffffff)
+ a = x >> 32 & c32
+ b = (x & c32) << 32
+ x = a | b
+ return x
+}
+
+// Bswap32 returns its input with byte order reversed
+// 0x01020304 -> 0x04030201
+func Bswap32(x uint32) uint32 {
+ c8 := uint32(0x00ff00ff)
+ a := x >> 8 & c8
+ b := (x & c8) << 8
+ x = a | b
+ c16 := uint32(0x0000ffff)
+ a = x >> 16 & c16
+ b = (x & c16) << 16
+ x = a | b
+ return x
+}
+
+// Prefetch prefetches data from memory addr to cache
+//
+// AMD64: Produce PREFETCHT0 instruction
+//
+// ARM64: Produce PRFM instruction with PLDL1KEEP option
+func Prefetch(addr uintptr) {}
+
+// PrefetchStreamed prefetches data from memory addr, with a hint that this data is being streamed.
+// That is, it is likely to be accessed very soon, but only once. If possible, this will avoid polluting the cache.
+//
+// AMD64: Produce PREFETCHNTA instruction
+//
+// ARM64: Produce PRFM instruction with PLDL1STRM option
+func PrefetchStreamed(addr uintptr) {}
diff --git a/contrib/go/_std_1.20/src/runtime/internal/sys/nih.go b/contrib/go/_std_1.21/src/runtime/internal/sys/nih.go
index 17eab67345..17eab67345 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/sys/nih.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/sys/nih.go
diff --git a/contrib/go/_std_1.20/src/runtime/internal/sys/sys.go b/contrib/go/_std_1.21/src/runtime/internal/sys/sys.go
index 694101d36f..694101d36f 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/sys/sys.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/sys/sys.go
diff --git a/contrib/go/_std_1.21/src/runtime/internal/sys/ya.make b/contrib/go/_std_1.21/src/runtime/internal/sys/ya.make
new file mode 100644
index 0000000000..0855cdb84c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/internal/sys/ya.make
@@ -0,0 +1,17 @@
+GO_LIBRARY()
+
+SRCS(
+ consts.go
+ consts_norace.go
+ intrinsics.go
+ nih.go
+ sys.go
+ zversion.go
+)
+
+GO_XTEST_SRCS(intrinsics_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/runtime/internal/sys/zversion.go b/contrib/go/_std_1.21/src/runtime/internal/sys/zversion.go
index 184c2639f9..184c2639f9 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/sys/zversion.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/sys/zversion.go
diff --git a/contrib/go/_std_1.20/src/runtime/internal/syscall/asm_linux_amd64.s b/contrib/go/_std_1.21/src/runtime/internal/syscall/asm_linux_amd64.s
index 3740ef1beb..3740ef1beb 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/syscall/asm_linux_amd64.s
+++ b/contrib/go/_std_1.21/src/runtime/internal/syscall/asm_linux_amd64.s
diff --git a/contrib/go/_std_1.20/src/runtime/internal/syscall/asm_linux_arm64.s b/contrib/go/_std_1.21/src/runtime/internal/syscall/asm_linux_arm64.s
index 83e862ff72..83e862ff72 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/syscall/asm_linux_arm64.s
+++ b/contrib/go/_std_1.21/src/runtime/internal/syscall/asm_linux_arm64.s
diff --git a/contrib/go/_std_1.20/src/runtime/internal/syscall/defs_linux_amd64.go b/contrib/go/_std_1.21/src/runtime/internal/syscall/defs_linux_amd64.go
index 886eb5bda2..886eb5bda2 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/syscall/defs_linux_amd64.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/syscall/defs_linux_amd64.go
diff --git a/contrib/go/_std_1.20/src/runtime/internal/syscall/defs_linux_arm64.go b/contrib/go/_std_1.21/src/runtime/internal/syscall/defs_linux_arm64.go
index 48e11b0c51..48e11b0c51 100644
--- a/contrib/go/_std_1.20/src/runtime/internal/syscall/defs_linux_arm64.go
+++ b/contrib/go/_std_1.21/src/runtime/internal/syscall/defs_linux_arm64.go
diff --git a/contrib/go/_std_1.21/src/runtime/internal/syscall/syscall_linux.go b/contrib/go/_std_1.21/src/runtime/internal/syscall/syscall_linux.go
new file mode 100644
index 0000000000..7209634edb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/internal/syscall/syscall_linux.go
@@ -0,0 +1,62 @@
+// Copyright 2022 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 syscall provides the syscall primitives required for the runtime.
+package syscall
+
+import (
+ "unsafe"
+)
+
+// TODO(https://go.dev/issue/51087): This package is incomplete and currently
+// only contains very minimal support for Linux.
+
+// Syscall6 calls system call number 'num' with arguments a1-6.
+func Syscall6(num, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr)
+
+// syscall_RawSyscall6 is a push linkname to export Syscall6 as
+// syscall.RawSyscall6.
+//
+// //go:uintptrkeepalive because the uintptr argument may be converted pointers
+// that need to be kept alive in the caller (this is implied for Syscall6 since
+// it has no body).
+//
+// //go:nosplit because stack copying does not account for uintptrkeepalive, so
+// the stack must not grow. Stack copying cannot blindly assume that all
+// uintptr arguments are pointers, because some values may look like pointers,
+// but not really be pointers, and adjusting their value would break the call.
+//
+// This is a separate wrapper because we can't export one function as two
+// names. The assembly implementations name themselves Syscall6 would not be
+// affected by a linkname.
+//
+//go:uintptrkeepalive
+//go:nosplit
+//go:linkname syscall_RawSyscall6 syscall.RawSyscall6
+func syscall_RawSyscall6(num, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr) {
+ return Syscall6(num, a1, a2, a3, a4, a5, a6)
+}
+
+func EpollCreate1(flags int32) (fd int32, errno uintptr) {
+ r1, _, e := Syscall6(SYS_EPOLL_CREATE1, uintptr(flags), 0, 0, 0, 0, 0)
+ return int32(r1), e
+}
+
+var _zero uintptr
+
+func EpollWait(epfd int32, events []EpollEvent, maxev, waitms int32) (n int32, errno uintptr) {
+ var ev unsafe.Pointer
+ if len(events) > 0 {
+ ev = unsafe.Pointer(&events[0])
+ } else {
+ ev = unsafe.Pointer(&_zero)
+ }
+ r1, _, e := Syscall6(SYS_EPOLL_PWAIT, uintptr(epfd), uintptr(ev), uintptr(maxev), uintptr(waitms), 0, 0)
+ return int32(r1), e
+}
+
+func EpollCtl(epfd, op, fd int32, event *EpollEvent) (errno uintptr) {
+ _, _, e := Syscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
+ return e
+}
diff --git a/contrib/go/_std_1.21/src/runtime/internal/syscall/ya.make b/contrib/go/_std_1.21/src/runtime/internal/syscall/ya.make
new file mode 100644
index 0000000000..2174a67498
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/internal/syscall/ya.make
@@ -0,0 +1,33 @@
+GO_LIBRARY()
+
+BUILD_ONLY_IF(
+ WARNING
+ OS_LINUX
+)
+
+IF (OS_LINUX)
+ SRCS(
+ syscall_linux.go
+ )
+
+ GO_XTEST_SRCS(syscall_linux_test.go)
+ENDIF()
+
+IF (OS_LINUX AND ARCH_X86_64)
+ SRCS(
+ asm_linux_amd64.s
+ defs_linux_amd64.go
+ )
+ENDIF()
+
+IF (OS_LINUX AND ARCH_ARM64)
+ SRCS(
+ asm_linux_arm64.s
+ defs_linux_arm64.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/runtime/internal/ya.make b/contrib/go/_std_1.21/src/runtime/internal/ya.make
new file mode 100644
index 0000000000..c95610ed15
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/internal/ya.make
@@ -0,0 +1,18 @@
+RECURSE(
+ atomic
+ math
+ sys
+ # wasitest # wasm not supported
+)
+
+IF (ARCH_X86_64)
+ RECURSE(
+ startlinetest
+ )
+ENDIF()
+
+IF (OS_LINUX)
+ RECURSE(
+ syscall
+ )
+ENDIF()
diff --git a/contrib/go/_std_1.21/src/runtime/lfstack.go b/contrib/go/_std_1.21/src/runtime/lfstack.go
new file mode 100644
index 0000000000..a91ae64e53
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/lfstack.go
@@ -0,0 +1,77 @@
+// Copyright 2012 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.
+
+// Lock-free stack.
+
+package runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// lfstack is the head of a lock-free stack.
+//
+// The zero value of lfstack is an empty list.
+//
+// This stack is intrusive. Nodes must embed lfnode as the first field.
+//
+// The stack does not keep GC-visible pointers to nodes, so the caller
+// must ensure the nodes are allocated outside the Go heap.
+type lfstack uint64
+
+func (head *lfstack) push(node *lfnode) {
+ node.pushcnt++
+ new := lfstackPack(node, node.pushcnt)
+ if node1 := lfstackUnpack(new); node1 != node {
+ print("runtime: lfstack.push invalid packing: node=", node, " cnt=", hex(node.pushcnt), " packed=", hex(new), " -> node=", node1, "\n")
+ throw("lfstack.push")
+ }
+ for {
+ old := atomic.Load64((*uint64)(head))
+ node.next = old
+ if atomic.Cas64((*uint64)(head), old, new) {
+ break
+ }
+ }
+}
+
+func (head *lfstack) pop() unsafe.Pointer {
+ for {
+ old := atomic.Load64((*uint64)(head))
+ if old == 0 {
+ return nil
+ }
+ node := lfstackUnpack(old)
+ next := atomic.Load64(&node.next)
+ if atomic.Cas64((*uint64)(head), old, next) {
+ return unsafe.Pointer(node)
+ }
+ }
+}
+
+func (head *lfstack) empty() bool {
+ return atomic.Load64((*uint64)(head)) == 0
+}
+
+// lfnodeValidate panics if node is not a valid address for use with
+// lfstack.push. This only needs to be called when node is allocated.
+func lfnodeValidate(node *lfnode) {
+ if base, _, _ := findObject(uintptr(unsafe.Pointer(node)), 0, 0); base != 0 {
+ throw("lfstack node allocated from the heap")
+ }
+ if lfstackUnpack(lfstackPack(node, ^uintptr(0))) != node {
+ printlock()
+ println("runtime: bad lfnode address", hex(uintptr(unsafe.Pointer(node))))
+ throw("bad lfnode address")
+ }
+}
+
+func lfstackPack(node *lfnode, cnt uintptr) uint64 {
+ return uint64(taggedPointerPack(unsafe.Pointer(node), cnt))
+}
+
+func lfstackUnpack(val uint64) *lfnode {
+ return (*lfnode)(taggedPointer(val).pointer())
+}
diff --git a/contrib/go/_std_1.20/src/runtime/lock_futex.go b/contrib/go/_std_1.21/src/runtime/lock_futex.go
index cc7d465ef1..cc7d465ef1 100644
--- a/contrib/go/_std_1.20/src/runtime/lock_futex.go
+++ b/contrib/go/_std_1.21/src/runtime/lock_futex.go
diff --git a/contrib/go/_std_1.20/src/runtime/lock_sema.go b/contrib/go/_std_1.21/src/runtime/lock_sema.go
index e15bbf79ae..e15bbf79ae 100644
--- a/contrib/go/_std_1.20/src/runtime/lock_sema.go
+++ b/contrib/go/_std_1.21/src/runtime/lock_sema.go
diff --git a/contrib/go/_std_1.21/src/runtime/lockrank.go b/contrib/go/_std_1.21/src/runtime/lockrank.go
new file mode 100644
index 0000000000..4d661e93dc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/lockrank.go
@@ -0,0 +1,187 @@
+// Code generated by mklockrank.go; DO NOT EDIT.
+
+package runtime
+
+type lockRank int
+
+// Constants representing the ranks of all non-leaf runtime locks, in rank order.
+// Locks with lower rank must be taken before locks with higher rank,
+// in addition to satisfying the partial order in lockPartialOrder.
+// A few ranks allow self-cycles, which are specified in lockPartialOrder.
+const (
+ lockRankUnknown lockRank = iota
+
+ lockRankSysmon
+ lockRankScavenge
+ lockRankForcegc
+ lockRankDefer
+ lockRankSweepWaiters
+ lockRankAssistQueue
+ lockRankSweep
+ lockRankPollDesc
+ lockRankCpuprof
+ lockRankSched
+ lockRankAllg
+ lockRankAllp
+ lockRankTimers
+ lockRankNetpollInit
+ lockRankHchan
+ lockRankNotifyList
+ lockRankSudog
+ lockRankRwmutexW
+ lockRankRwmutexR
+ lockRankRoot
+ lockRankItab
+ lockRankReflectOffs
+ lockRankUserArenaState
+ // TRACEGLOBAL
+ lockRankTraceBuf
+ lockRankTraceStrings
+ // MALLOC
+ lockRankFin
+ lockRankSpanSetSpine
+ lockRankMspanSpecial
+ // MPROF
+ lockRankGcBitsArenas
+ lockRankProfInsert
+ lockRankProfBlock
+ lockRankProfMemActive
+ lockRankProfMemFuture
+ // STACKGROW
+ lockRankGscan
+ lockRankStackpool
+ lockRankStackLarge
+ lockRankHchanLeaf
+ // WB
+ lockRankWbufSpans
+ lockRankMheap
+ lockRankMheapSpecial
+ lockRankGlobalAlloc
+ // TRACE
+ lockRankTrace
+ lockRankTraceStackTab
+ lockRankPanic
+ lockRankDeadlock
+ lockRankRaceFini
+)
+
+// lockRankLeafRank is the rank of lock that does not have a declared rank,
+// and hence is a leaf lock.
+const lockRankLeafRank lockRank = 1000
+
+// lockNames gives the names associated with each of the above ranks.
+var lockNames = []string{
+ lockRankSysmon: "sysmon",
+ lockRankScavenge: "scavenge",
+ lockRankForcegc: "forcegc",
+ lockRankDefer: "defer",
+ lockRankSweepWaiters: "sweepWaiters",
+ lockRankAssistQueue: "assistQueue",
+ lockRankSweep: "sweep",
+ lockRankPollDesc: "pollDesc",
+ lockRankCpuprof: "cpuprof",
+ lockRankSched: "sched",
+ lockRankAllg: "allg",
+ lockRankAllp: "allp",
+ lockRankTimers: "timers",
+ lockRankNetpollInit: "netpollInit",
+ lockRankHchan: "hchan",
+ lockRankNotifyList: "notifyList",
+ lockRankSudog: "sudog",
+ lockRankRwmutexW: "rwmutexW",
+ lockRankRwmutexR: "rwmutexR",
+ lockRankRoot: "root",
+ lockRankItab: "itab",
+ lockRankReflectOffs: "reflectOffs",
+ lockRankUserArenaState: "userArenaState",
+ lockRankTraceBuf: "traceBuf",
+ lockRankTraceStrings: "traceStrings",
+ lockRankFin: "fin",
+ lockRankSpanSetSpine: "spanSetSpine",
+ lockRankMspanSpecial: "mspanSpecial",
+ lockRankGcBitsArenas: "gcBitsArenas",
+ lockRankProfInsert: "profInsert",
+ lockRankProfBlock: "profBlock",
+ lockRankProfMemActive: "profMemActive",
+ lockRankProfMemFuture: "profMemFuture",
+ lockRankGscan: "gscan",
+ lockRankStackpool: "stackpool",
+ lockRankStackLarge: "stackLarge",
+ lockRankHchanLeaf: "hchanLeaf",
+ lockRankWbufSpans: "wbufSpans",
+ lockRankMheap: "mheap",
+ lockRankMheapSpecial: "mheapSpecial",
+ lockRankGlobalAlloc: "globalAlloc",
+ lockRankTrace: "trace",
+ lockRankTraceStackTab: "traceStackTab",
+ lockRankPanic: "panic",
+ lockRankDeadlock: "deadlock",
+ lockRankRaceFini: "raceFini",
+}
+
+func (rank lockRank) String() string {
+ if rank == 0 {
+ return "UNKNOWN"
+ }
+ if rank == lockRankLeafRank {
+ return "LEAF"
+ }
+ if rank < 0 || int(rank) >= len(lockNames) {
+ return "BAD RANK"
+ }
+ return lockNames[rank]
+}
+
+// lockPartialOrder is the transitive closure of the lock rank graph.
+// An entry for rank X lists all of the ranks that can already be held
+// when rank X is acquired.
+//
+// Lock ranks that allow self-cycles list themselves.
+var lockPartialOrder [][]lockRank = [][]lockRank{
+ lockRankSysmon: {},
+ lockRankScavenge: {lockRankSysmon},
+ lockRankForcegc: {lockRankSysmon},
+ lockRankDefer: {},
+ lockRankSweepWaiters: {},
+ lockRankAssistQueue: {},
+ lockRankSweep: {},
+ lockRankPollDesc: {},
+ lockRankCpuprof: {},
+ lockRankSched: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof},
+ lockRankAllg: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched},
+ lockRankAllp: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched},
+ lockRankTimers: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllp, lockRankTimers},
+ lockRankNetpollInit: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllp, lockRankTimers},
+ lockRankHchan: {lockRankSysmon, lockRankScavenge, lockRankSweep, lockRankHchan},
+ lockRankNotifyList: {},
+ lockRankSudog: {lockRankSysmon, lockRankScavenge, lockRankSweep, lockRankHchan, lockRankNotifyList},
+ lockRankRwmutexW: {},
+ lockRankRwmutexR: {lockRankSysmon, lockRankRwmutexW},
+ lockRankRoot: {},
+ lockRankItab: {},
+ lockRankReflectOffs: {lockRankItab},
+ lockRankUserArenaState: {},
+ lockRankTraceBuf: {lockRankSysmon, lockRankScavenge},
+ lockRankTraceStrings: {lockRankSysmon, lockRankScavenge, lockRankTraceBuf},
+ lockRankFin: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+ lockRankSpanSetSpine: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+ lockRankMspanSpecial: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+ lockRankGcBitsArenas: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankMspanSpecial},
+ lockRankProfInsert: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+ lockRankProfBlock: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+ lockRankProfMemActive: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings},
+ lockRankProfMemFuture: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankHchan, lockRankNotifyList, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankProfMemActive},
+ lockRankGscan: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankSpanSetSpine, lockRankMspanSpecial, lockRankGcBitsArenas, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture},
+ lockRankStackpool: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankSpanSetSpine, lockRankMspanSpecial, lockRankGcBitsArenas, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan},
+ lockRankStackLarge: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankSpanSetSpine, lockRankMspanSpecial, lockRankGcBitsArenas, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan},
+ lockRankHchanLeaf: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankSpanSetSpine, lockRankMspanSpecial, lockRankGcBitsArenas, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankHchanLeaf},
+ lockRankWbufSpans: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankSpanSetSpine, lockRankMspanSpecial, lockRankGcBitsArenas, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan},
+ lockRankMheap: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankSpanSetSpine, lockRankMspanSpecial, lockRankGcBitsArenas, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans},
+ lockRankMheapSpecial: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankSpanSetSpine, lockRankMspanSpecial, lockRankGcBitsArenas, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap},
+ lockRankGlobalAlloc: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankSpanSetSpine, lockRankMspanSpecial, lockRankGcBitsArenas, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap, lockRankMheapSpecial},
+ lockRankTrace: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankSpanSetSpine, lockRankMspanSpecial, lockRankGcBitsArenas, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap},
+ lockRankTraceStackTab: {lockRankSysmon, lockRankScavenge, lockRankForcegc, lockRankDefer, lockRankSweepWaiters, lockRankAssistQueue, lockRankSweep, lockRankPollDesc, lockRankCpuprof, lockRankSched, lockRankAllg, lockRankAllp, lockRankTimers, lockRankNetpollInit, lockRankHchan, lockRankNotifyList, lockRankSudog, lockRankRwmutexW, lockRankRwmutexR, lockRankRoot, lockRankItab, lockRankReflectOffs, lockRankUserArenaState, lockRankTraceBuf, lockRankTraceStrings, lockRankFin, lockRankSpanSetSpine, lockRankMspanSpecial, lockRankGcBitsArenas, lockRankProfInsert, lockRankProfBlock, lockRankProfMemActive, lockRankProfMemFuture, lockRankGscan, lockRankStackpool, lockRankStackLarge, lockRankWbufSpans, lockRankMheap, lockRankTrace},
+ lockRankPanic: {},
+ lockRankDeadlock: {lockRankPanic, lockRankDeadlock},
+ lockRankRaceFini: {lockRankPanic},
+}
diff --git a/contrib/go/_std_1.21/src/runtime/lockrank_off.go b/contrib/go/_std_1.21/src/runtime/lockrank_off.go
new file mode 100644
index 0000000000..c86726f3dd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/lockrank_off.go
@@ -0,0 +1,68 @@
+// 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.
+
+//go:build !goexperiment.staticlockranking
+
+package runtime
+
+const staticLockRanking = false
+
+// // lockRankStruct is embedded in mutex, but is empty when staticklockranking is
+// disabled (the default)
+type lockRankStruct struct {
+}
+
+func lockInit(l *mutex, rank lockRank) {
+}
+
+func getLockRank(l *mutex) lockRank {
+ return 0
+}
+
+func lockWithRank(l *mutex, rank lockRank) {
+ lock2(l)
+}
+
+// This function may be called in nosplit context and thus must be nosplit.
+//
+//go:nosplit
+func acquireLockRank(rank lockRank) {
+}
+
+func unlockWithRank(l *mutex) {
+ unlock2(l)
+}
+
+// This function may be called in nosplit context and thus must be nosplit.
+//
+//go:nosplit
+func releaseLockRank(rank lockRank) {
+}
+
+func lockWithRankMayAcquire(l *mutex, rank lockRank) {
+}
+
+//go:nosplit
+func assertLockHeld(l *mutex) {
+}
+
+//go:nosplit
+func assertRankHeld(r lockRank) {
+}
+
+//go:nosplit
+func worldStopped() {
+}
+
+//go:nosplit
+func worldStarted() {
+}
+
+//go:nosplit
+func assertWorldStopped() {
+}
+
+//go:nosplit
+func assertWorldStoppedOrLockHeld(l *mutex) {
+}
diff --git a/contrib/go/_std_1.21/src/runtime/malloc.go b/contrib/go/_std_1.21/src/runtime/malloc.go
new file mode 100644
index 0000000000..44479cc2be
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/malloc.go
@@ -0,0 +1,1632 @@
+// Copyright 2014 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.
+
+// Memory allocator.
+//
+// This was originally based on tcmalloc, but has diverged quite a bit.
+// http://goog-perftools.sourceforge.net/doc/tcmalloc.html
+
+// The main allocator works in runs of pages.
+// Small allocation sizes (up to and including 32 kB) are
+// rounded to one of about 70 size classes, each of which
+// has its own free set of objects of exactly that size.
+// Any free page of memory can be split into a set of objects
+// of one size class, which are then managed using a free bitmap.
+//
+// The allocator's data structures are:
+//
+// fixalloc: a free-list allocator for fixed-size off-heap objects,
+// used to manage storage used by the allocator.
+// mheap: the malloc heap, managed at page (8192-byte) granularity.
+// mspan: a run of in-use pages managed by the mheap.
+// mcentral: collects all spans of a given size class.
+// mcache: a per-P cache of mspans with free space.
+// mstats: allocation statistics.
+//
+// Allocating a small object proceeds up a hierarchy of caches:
+//
+// 1. Round the size up to one of the small size classes
+// and look in the corresponding mspan in this P's mcache.
+// Scan the mspan's free bitmap to find a free slot.
+// If there is a free slot, allocate it.
+// This can all be done without acquiring a lock.
+//
+// 2. If the mspan has no free slots, obtain a new mspan
+// from the mcentral's list of mspans of the required size
+// class that have free space.
+// Obtaining a whole span amortizes the cost of locking
+// the mcentral.
+//
+// 3. If the mcentral's mspan list is empty, obtain a run
+// of pages from the mheap to use for the mspan.
+//
+// 4. If the mheap is empty or has no page runs large enough,
+// allocate a new group of pages (at least 1MB) from the
+// operating system. Allocating a large run of pages
+// amortizes the cost of talking to the operating system.
+//
+// Sweeping an mspan and freeing objects on it proceeds up a similar
+// hierarchy:
+//
+// 1. If the mspan is being swept in response to allocation, it
+// is returned to the mcache to satisfy the allocation.
+//
+// 2. Otherwise, if the mspan still has allocated objects in it,
+// it is placed on the mcentral free list for the mspan's size
+// class.
+//
+// 3. Otherwise, if all objects in the mspan are free, the mspan's
+// pages are returned to the mheap and the mspan is now dead.
+//
+// Allocating and freeing a large object uses the mheap
+// directly, bypassing the mcache and mcentral.
+//
+// If mspan.needzero is false, then free object slots in the mspan are
+// already zeroed. Otherwise if needzero is true, objects are zeroed as
+// they are allocated. There are various benefits to delaying zeroing
+// this way:
+//
+// 1. Stack frame allocation can avoid zeroing altogether.
+//
+// 2. It exhibits better temporal locality, since the program is
+// probably about to write to the memory.
+//
+// 3. We don't zero pages that never get reused.
+
+// Virtual memory layout
+//
+// The heap consists of a set of arenas, which are 64MB on 64-bit and
+// 4MB on 32-bit (heapArenaBytes). Each arena's start address is also
+// aligned to the arena size.
+//
+// Each arena has an associated heapArena object that stores the
+// metadata for that arena: the heap bitmap for all words in the arena
+// and the span map for all pages in the arena. heapArena objects are
+// themselves allocated off-heap.
+//
+// Since arenas are aligned, the address space can be viewed as a
+// series of arena frames. The arena map (mheap_.arenas) maps from
+// arena frame number to *heapArena, or nil for parts of the address
+// space not backed by the Go heap. The arena map is structured as a
+// two-level array consisting of a "L1" arena map and many "L2" arena
+// maps; however, since arenas are large, on many architectures, the
+// arena map consists of a single, large L2 map.
+//
+// The arena map covers the entire possible address space, allowing
+// the Go heap to use any part of the address space. The allocator
+// attempts to keep arenas contiguous so that large spans (and hence
+// large objects) can cross arenas.
+
+package runtime
+
+import (
+ "internal/goarch"
+ "internal/goos"
+ "runtime/internal/atomic"
+ "runtime/internal/math"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+const (
+ maxTinySize = _TinySize
+ tinySizeClass = _TinySizeClass
+ maxSmallSize = _MaxSmallSize
+
+ pageShift = _PageShift
+ pageSize = _PageSize
+
+ concurrentSweep = _ConcurrentSweep
+
+ _PageSize = 1 << _PageShift
+ _PageMask = _PageSize - 1
+
+ // _64bit = 1 on 64-bit systems, 0 on 32-bit systems
+ _64bit = 1 << (^uintptr(0) >> 63) / 2
+
+ // Tiny allocator parameters, see "Tiny allocator" comment in malloc.go.
+ _TinySize = 16
+ _TinySizeClass = int8(2)
+
+ _FixAllocChunk = 16 << 10 // Chunk size for FixAlloc
+
+ // Per-P, per order stack segment cache size.
+ _StackCacheSize = 32 * 1024
+
+ // Number of orders that get caching. Order 0 is FixedStack
+ // and each successive order is twice as large.
+ // We want to cache 2KB, 4KB, 8KB, and 16KB stacks. Larger stacks
+ // will be allocated directly.
+ // Since FixedStack is different on different systems, we
+ // must vary NumStackOrders to keep the same maximum cached size.
+ // OS | FixedStack | NumStackOrders
+ // -----------------+------------+---------------
+ // linux/darwin/bsd | 2KB | 4
+ // windows/32 | 4KB | 3
+ // windows/64 | 8KB | 2
+ // plan9 | 4KB | 3
+ _NumStackOrders = 4 - goarch.PtrSize/4*goos.IsWindows - 1*goos.IsPlan9
+
+ // heapAddrBits is the number of bits in a heap address. On
+ // amd64, addresses are sign-extended beyond heapAddrBits. On
+ // other arches, they are zero-extended.
+ //
+ // On most 64-bit platforms, we limit this to 48 bits based on a
+ // combination of hardware and OS limitations.
+ //
+ // amd64 hardware limits addresses to 48 bits, sign-extended
+ // to 64 bits. Addresses where the top 16 bits are not either
+ // all 0 or all 1 are "non-canonical" and invalid. Because of
+ // these "negative" addresses, we offset addresses by 1<<47
+ // (arenaBaseOffset) on amd64 before computing indexes into
+ // the heap arenas index. In 2017, amd64 hardware added
+ // support for 57 bit addresses; however, currently only Linux
+ // supports this extension and the kernel will never choose an
+ // address above 1<<47 unless mmap is called with a hint
+ // address above 1<<47 (which we never do).
+ //
+ // arm64 hardware (as of ARMv8) limits user addresses to 48
+ // bits, in the range [0, 1<<48).
+ //
+ // ppc64, mips64, and s390x support arbitrary 64 bit addresses
+ // in hardware. On Linux, Go leans on stricter OS limits. Based
+ // on Linux's processor.h, the user address space is limited as
+ // follows on 64-bit architectures:
+ //
+ // Architecture Name Maximum Value (exclusive)
+ // ---------------------------------------------------------------------
+ // amd64 TASK_SIZE_MAX 0x007ffffffff000 (47 bit addresses)
+ // arm64 TASK_SIZE_64 0x01000000000000 (48 bit addresses)
+ // ppc64{,le} TASK_SIZE_USER64 0x00400000000000 (46 bit addresses)
+ // mips64{,le} TASK_SIZE64 0x00010000000000 (40 bit addresses)
+ // s390x TASK_SIZE 1<<64 (64 bit addresses)
+ //
+ // These limits may increase over time, but are currently at
+ // most 48 bits except on s390x. On all architectures, Linux
+ // starts placing mmap'd regions at addresses that are
+ // significantly below 48 bits, so even if it's possible to
+ // exceed Go's 48 bit limit, it's extremely unlikely in
+ // practice.
+ //
+ // On 32-bit platforms, we accept the full 32-bit address
+ // space because doing so is cheap.
+ // mips32 only has access to the low 2GB of virtual memory, so
+ // we further limit it to 31 bits.
+ //
+ // On ios/arm64, although 64-bit pointers are presumably
+ // available, pointers are truncated to 33 bits in iOS <14.
+ // Furthermore, only the top 4 GiB of the address space are
+ // actually available to the application. In iOS >=14, more
+ // of the address space is available, and the OS can now
+ // provide addresses outside of those 33 bits. Pick 40 bits
+ // as a reasonable balance between address space usage by the
+ // page allocator, and flexibility for what mmap'd regions
+ // we'll accept for the heap. We can't just move to the full
+ // 48 bits because this uses too much address space for older
+ // iOS versions.
+ // TODO(mknyszek): Once iOS <14 is deprecated, promote ios/arm64
+ // to a 48-bit address space like every other arm64 platform.
+ //
+ // WebAssembly currently has a limit of 4GB linear memory.
+ heapAddrBits = (_64bit*(1-goarch.IsWasm)*(1-goos.IsIos*goarch.IsArm64))*48 + (1-_64bit+goarch.IsWasm)*(32-(goarch.IsMips+goarch.IsMipsle)) + 40*goos.IsIos*goarch.IsArm64
+
+ // maxAlloc is the maximum size of an allocation. On 64-bit,
+ // it's theoretically possible to allocate 1<<heapAddrBits bytes. On
+ // 32-bit, however, this is one less than 1<<32 because the
+ // number of bytes in the address space doesn't actually fit
+ // in a uintptr.
+ maxAlloc = (1 << heapAddrBits) - (1-_64bit)*1
+
+ // The number of bits in a heap address, the size of heap
+ // arenas, and the L1 and L2 arena map sizes are related by
+ //
+ // (1 << addr bits) = arena size * L1 entries * L2 entries
+ //
+ // Currently, we balance these as follows:
+ //
+ // Platform Addr bits Arena size L1 entries L2 entries
+ // -------------- --------- ---------- ---------- -----------
+ // */64-bit 48 64MB 1 4M (32MB)
+ // windows/64-bit 48 4MB 64 1M (8MB)
+ // ios/arm64 33 4MB 1 2048 (8KB)
+ // */32-bit 32 4MB 1 1024 (4KB)
+ // */mips(le) 31 4MB 1 512 (2KB)
+
+ // heapArenaBytes is the size of a heap arena. The heap
+ // consists of mappings of size heapArenaBytes, aligned to
+ // heapArenaBytes. The initial heap mapping is one arena.
+ //
+ // This is currently 64MB on 64-bit non-Windows and 4MB on
+ // 32-bit and on Windows. We use smaller arenas on Windows
+ // because all committed memory is charged to the process,
+ // even if it's not touched. Hence, for processes with small
+ // heaps, the mapped arena space needs to be commensurate.
+ // This is particularly important with the race detector,
+ // since it significantly amplifies the cost of committed
+ // memory.
+ heapArenaBytes = 1 << logHeapArenaBytes
+
+ heapArenaWords = heapArenaBytes / goarch.PtrSize
+
+ // logHeapArenaBytes is log_2 of heapArenaBytes. For clarity,
+ // prefer using heapArenaBytes where possible (we need the
+ // constant to compute some other constants).
+ logHeapArenaBytes = (6+20)*(_64bit*(1-goos.IsWindows)*(1-goarch.IsWasm)*(1-goos.IsIos*goarch.IsArm64)) + (2+20)*(_64bit*goos.IsWindows) + (2+20)*(1-_64bit) + (2+20)*goarch.IsWasm + (2+20)*goos.IsIos*goarch.IsArm64
+
+ // heapArenaBitmapWords is the size of each heap arena's bitmap in uintptrs.
+ heapArenaBitmapWords = heapArenaWords / (8 * goarch.PtrSize)
+
+ pagesPerArena = heapArenaBytes / pageSize
+
+ // arenaL1Bits is the number of bits of the arena number
+ // covered by the first level arena map.
+ //
+ // This number should be small, since the first level arena
+ // map requires PtrSize*(1<<arenaL1Bits) of space in the
+ // binary's BSS. It can be zero, in which case the first level
+ // index is effectively unused. There is a performance benefit
+ // to this, since the generated code can be more efficient,
+ // but comes at the cost of having a large L2 mapping.
+ //
+ // We use the L1 map on 64-bit Windows because the arena size
+ // is small, but the address space is still 48 bits, and
+ // there's a high cost to having a large L2.
+ arenaL1Bits = 6 * (_64bit * goos.IsWindows)
+
+ // arenaL2Bits is the number of bits of the arena number
+ // covered by the second level arena index.
+ //
+ // The size of each arena map allocation is proportional to
+ // 1<<arenaL2Bits, so it's important that this not be too
+ // large. 48 bits leads to 32MB arena index allocations, which
+ // is about the practical threshold.
+ arenaL2Bits = heapAddrBits - logHeapArenaBytes - arenaL1Bits
+
+ // arenaL1Shift is the number of bits to shift an arena frame
+ // number by to compute an index into the first level arena map.
+ arenaL1Shift = arenaL2Bits
+
+ // arenaBits is the total bits in a combined arena map index.
+ // This is split between the index into the L1 arena map and
+ // the L2 arena map.
+ arenaBits = arenaL1Bits + arenaL2Bits
+
+ // arenaBaseOffset is the pointer value that corresponds to
+ // index 0 in the heap arena map.
+ //
+ // On amd64, the address space is 48 bits, sign extended to 64
+ // bits. This offset lets us handle "negative" addresses (or
+ // high addresses if viewed as unsigned).
+ //
+ // On aix/ppc64, this offset allows to keep the heapAddrBits to
+ // 48. Otherwise, it would be 60 in order to handle mmap addresses
+ // (in range 0x0a00000000000000 - 0x0afffffffffffff). But in this
+ // case, the memory reserved in (s *pageAlloc).init for chunks
+ // is causing important slowdowns.
+ //
+ // On other platforms, the user address space is contiguous
+ // and starts at 0, so no offset is necessary.
+ arenaBaseOffset = 0xffff800000000000*goarch.IsAmd64 + 0x0a00000000000000*goos.IsAix
+ // A typed version of this constant that will make it into DWARF (for viewcore).
+ arenaBaseOffsetUintptr = uintptr(arenaBaseOffset)
+
+ // Max number of threads to run garbage collection.
+ // 2, 3, and 4 are all plausible maximums depending
+ // on the hardware details of the machine. The garbage
+ // collector scales well to 32 cpus.
+ _MaxGcproc = 32
+
+ // minLegalPointer is the smallest possible legal pointer.
+ // This is the smallest possible architectural page size,
+ // since we assume that the first page is never mapped.
+ //
+ // This should agree with minZeroPage in the compiler.
+ minLegalPointer uintptr = 4096
+
+ // minHeapForMetadataHugePages sets a threshold on when certain kinds of
+ // heap metadata, currently the arenas map L2 entries and page alloc bitmap
+ // mappings, are allowed to be backed by huge pages. If the heap goal ever
+ // exceeds this threshold, then huge pages are enabled.
+ //
+ // These numbers are chosen with the assumption that huge pages are on the
+ // order of a few MiB in size.
+ //
+ // The kind of metadata this applies to has a very low overhead when compared
+ // to address space used, but their constant overheads for small heaps would
+ // be very high if they were to be backed by huge pages (e.g. a few MiB makes
+ // a huge difference for an 8 MiB heap, but barely any difference for a 1 GiB
+ // heap). The benefit of huge pages is also not worth it for small heaps,
+ // because only a very, very small part of the metadata is used for small heaps.
+ //
+ // N.B. If the heap goal exceeds the threshold then shrinks to a very small size
+ // again, then huge pages will still be enabled for this mapping. The reason is that
+ // there's no point unless we're also returning the physical memory for these
+ // metadata mappings back to the OS. That would be quite complex to do in general
+ // as the heap is likely fragmented after a reduction in heap size.
+ minHeapForMetadataHugePages = 1 << 30
+)
+
+// physPageSize is the size in bytes of the OS's physical pages.
+// Mapping and unmapping operations must be done at multiples of
+// physPageSize.
+//
+// This must be set by the OS init code (typically in osinit) before
+// mallocinit.
+var physPageSize uintptr
+
+// physHugePageSize is the size in bytes of the OS's default physical huge
+// page size whose allocation is opaque to the application. It is assumed
+// and verified to be a power of two.
+//
+// If set, this must be set by the OS init code (typically in osinit) before
+// mallocinit. However, setting it at all is optional, and leaving the default
+// value is always safe (though potentially less efficient).
+//
+// Since physHugePageSize is always assumed to be a power of two,
+// physHugePageShift is defined as physHugePageSize == 1 << physHugePageShift.
+// The purpose of physHugePageShift is to avoid doing divisions in
+// performance critical functions.
+var (
+ physHugePageSize uintptr
+ physHugePageShift uint
+)
+
+func mallocinit() {
+ if class_to_size[_TinySizeClass] != _TinySize {
+ throw("bad TinySizeClass")
+ }
+
+ if heapArenaBitmapWords&(heapArenaBitmapWords-1) != 0 {
+ // heapBits expects modular arithmetic on bitmap
+ // addresses to work.
+ throw("heapArenaBitmapWords not a power of 2")
+ }
+
+ // Check physPageSize.
+ if physPageSize == 0 {
+ // The OS init code failed to fetch the physical page size.
+ throw("failed to get system page size")
+ }
+ if physPageSize > maxPhysPageSize {
+ print("system page size (", physPageSize, ") is larger than maximum page size (", maxPhysPageSize, ")\n")
+ throw("bad system page size")
+ }
+ if physPageSize < minPhysPageSize {
+ print("system page size (", physPageSize, ") is smaller than minimum page size (", minPhysPageSize, ")\n")
+ throw("bad system page size")
+ }
+ if physPageSize&(physPageSize-1) != 0 {
+ print("system page size (", physPageSize, ") must be a power of 2\n")
+ throw("bad system page size")
+ }
+ if physHugePageSize&(physHugePageSize-1) != 0 {
+ print("system huge page size (", physHugePageSize, ") must be a power of 2\n")
+ throw("bad system huge page size")
+ }
+ if physHugePageSize > maxPhysHugePageSize {
+ // physHugePageSize is greater than the maximum supported huge page size.
+ // Don't throw here, like in the other cases, since a system configured
+ // in this way isn't wrong, we just don't have the code to support them.
+ // Instead, silently set the huge page size to zero.
+ physHugePageSize = 0
+ }
+ if physHugePageSize != 0 {
+ // Since physHugePageSize is a power of 2, it suffices to increase
+ // physHugePageShift until 1<<physHugePageShift == physHugePageSize.
+ for 1<<physHugePageShift != physHugePageSize {
+ physHugePageShift++
+ }
+ }
+ if pagesPerArena%pagesPerSpanRoot != 0 {
+ print("pagesPerArena (", pagesPerArena, ") is not divisible by pagesPerSpanRoot (", pagesPerSpanRoot, ")\n")
+ throw("bad pagesPerSpanRoot")
+ }
+ if pagesPerArena%pagesPerReclaimerChunk != 0 {
+ print("pagesPerArena (", pagesPerArena, ") is not divisible by pagesPerReclaimerChunk (", pagesPerReclaimerChunk, ")\n")
+ throw("bad pagesPerReclaimerChunk")
+ }
+
+ if minTagBits > taggedPointerBits {
+ throw("taggedPointerbits too small")
+ }
+
+ // Initialize the heap.
+ mheap_.init()
+ mcache0 = allocmcache()
+ lockInit(&gcBitsArenas.lock, lockRankGcBitsArenas)
+ lockInit(&profInsertLock, lockRankProfInsert)
+ lockInit(&profBlockLock, lockRankProfBlock)
+ lockInit(&profMemActiveLock, lockRankProfMemActive)
+ for i := range profMemFutureLock {
+ lockInit(&profMemFutureLock[i], lockRankProfMemFuture)
+ }
+ lockInit(&globalAlloc.mutex, lockRankGlobalAlloc)
+
+ // Create initial arena growth hints.
+ if goarch.PtrSize == 8 {
+ // On a 64-bit machine, we pick the following hints
+ // because:
+ //
+ // 1. Starting from the middle of the address space
+ // makes it easier to grow out a contiguous range
+ // without running in to some other mapping.
+ //
+ // 2. This makes Go heap addresses more easily
+ // recognizable when debugging.
+ //
+ // 3. Stack scanning in gccgo is still conservative,
+ // so it's important that addresses be distinguishable
+ // from other data.
+ //
+ // Starting at 0x00c0 means that the valid memory addresses
+ // will begin 0x00c0, 0x00c1, ...
+ // In little-endian, that's c0 00, c1 00, ... None of those are valid
+ // UTF-8 sequences, and they are otherwise as far away from
+ // ff (likely a common byte) as possible. If that fails, we try other 0xXXc0
+ // addresses. An earlier attempt to use 0x11f8 caused out of memory errors
+ // on OS X during thread allocations. 0x00c0 causes conflicts with
+ // AddressSanitizer which reserves all memory up to 0x0100.
+ // These choices reduce the odds of a conservative garbage collector
+ // not collecting memory because some non-pointer block of memory
+ // had a bit pattern that matched a memory address.
+ //
+ // However, on arm64, we ignore all this advice above and slam the
+ // allocation at 0x40 << 32 because when using 4k pages with 3-level
+ // translation buffers, the user address space is limited to 39 bits
+ // On ios/arm64, the address space is even smaller.
+ //
+ // On AIX, mmaps starts at 0x0A00000000000000 for 64-bit.
+ // processes.
+ //
+ // Space mapped for user arenas comes immediately after the range
+ // originally reserved for the regular heap when race mode is not
+ // enabled because user arena chunks can never be used for regular heap
+ // allocations and we want to avoid fragmenting the address space.
+ //
+ // In race mode we have no choice but to just use the same hints because
+ // the race detector requires that the heap be mapped contiguously.
+ for i := 0x7f; i >= 0; i-- {
+ var p uintptr
+ switch {
+ case raceenabled:
+ // The TSAN runtime requires the heap
+ // to be in the range [0x00c000000000,
+ // 0x00e000000000).
+ p = uintptr(i)<<32 | uintptrMask&(0x00c0<<32)
+ if p >= uintptrMask&0x00e000000000 {
+ continue
+ }
+ case GOARCH == "arm64" && GOOS == "ios":
+ p = uintptr(i)<<40 | uintptrMask&(0x0013<<28)
+ case GOARCH == "arm64":
+ p = uintptr(i)<<40 | uintptrMask&(0x0040<<32)
+ case GOOS == "aix":
+ if i == 0 {
+ // We don't use addresses directly after 0x0A00000000000000
+ // to avoid collisions with others mmaps done by non-go programs.
+ continue
+ }
+ p = uintptr(i)<<40 | uintptrMask&(0xa0<<52)
+ default:
+ p = uintptr(i)<<40 | uintptrMask&(0x00c0<<32)
+ }
+ // Switch to generating hints for user arenas if we've gone
+ // through about half the hints. In race mode, take only about
+ // a quarter; we don't have very much space to work with.
+ hintList := &mheap_.arenaHints
+ if (!raceenabled && i > 0x3f) || (raceenabled && i > 0x5f) {
+ hintList = &mheap_.userArena.arenaHints
+ }
+ hint := (*arenaHint)(mheap_.arenaHintAlloc.alloc())
+ hint.addr = p
+ hint.next, *hintList = *hintList, hint
+ }
+ } else {
+ // On a 32-bit machine, we're much more concerned
+ // about keeping the usable heap contiguous.
+ // Hence:
+ //
+ // 1. We reserve space for all heapArenas up front so
+ // they don't get interleaved with the heap. They're
+ // ~258MB, so this isn't too bad. (We could reserve a
+ // smaller amount of space up front if this is a
+ // problem.)
+ //
+ // 2. We hint the heap to start right above the end of
+ // the binary so we have the best chance of keeping it
+ // contiguous.
+ //
+ // 3. We try to stake out a reasonably large initial
+ // heap reservation.
+
+ const arenaMetaSize = (1 << arenaBits) * unsafe.Sizeof(heapArena{})
+ meta := uintptr(sysReserve(nil, arenaMetaSize))
+ if meta != 0 {
+ mheap_.heapArenaAlloc.init(meta, arenaMetaSize, true)
+ }
+
+ // We want to start the arena low, but if we're linked
+ // against C code, it's possible global constructors
+ // have called malloc and adjusted the process' brk.
+ // Query the brk so we can avoid trying to map the
+ // region over it (which will cause the kernel to put
+ // the region somewhere else, likely at a high
+ // address).
+ procBrk := sbrk0()
+
+ // If we ask for the end of the data segment but the
+ // operating system requires a little more space
+ // before we can start allocating, it will give out a
+ // slightly higher pointer. Except QEMU, which is
+ // buggy, as usual: it won't adjust the pointer
+ // upward. So adjust it upward a little bit ourselves:
+ // 1/4 MB to get away from the running binary image.
+ p := firstmoduledata.end
+ if p < procBrk {
+ p = procBrk
+ }
+ if mheap_.heapArenaAlloc.next <= p && p < mheap_.heapArenaAlloc.end {
+ p = mheap_.heapArenaAlloc.end
+ }
+ p = alignUp(p+(256<<10), heapArenaBytes)
+ // Because we're worried about fragmentation on
+ // 32-bit, we try to make a large initial reservation.
+ arenaSizes := []uintptr{
+ 512 << 20,
+ 256 << 20,
+ 128 << 20,
+ }
+ for _, arenaSize := range arenaSizes {
+ a, size := sysReserveAligned(unsafe.Pointer(p), arenaSize, heapArenaBytes)
+ if a != nil {
+ mheap_.arena.init(uintptr(a), size, false)
+ p = mheap_.arena.end // For hint below
+ break
+ }
+ }
+ hint := (*arenaHint)(mheap_.arenaHintAlloc.alloc())
+ hint.addr = p
+ hint.next, mheap_.arenaHints = mheap_.arenaHints, hint
+
+ // Place the hint for user arenas just after the large reservation.
+ //
+ // While this potentially competes with the hint above, in practice we probably
+ // aren't going to be getting this far anyway on 32-bit platforms.
+ userArenaHint := (*arenaHint)(mheap_.arenaHintAlloc.alloc())
+ userArenaHint.addr = p
+ userArenaHint.next, mheap_.userArena.arenaHints = mheap_.userArena.arenaHints, userArenaHint
+ }
+ // Initialize the memory limit here because the allocator is going to look at it
+ // but we haven't called gcinit yet and we're definitely going to allocate memory before then.
+ gcController.memoryLimit.Store(maxInt64)
+}
+
+// sysAlloc allocates heap arena space for at least n bytes. The
+// returned pointer is always heapArenaBytes-aligned and backed by
+// h.arenas metadata. The returned size is always a multiple of
+// heapArenaBytes. sysAlloc returns nil on failure.
+// There is no corresponding free function.
+//
+// hintList is a list of hint addresses for where to allocate new
+// heap arenas. It must be non-nil.
+//
+// register indicates whether the heap arena should be registered
+// in allArenas.
+//
+// sysAlloc returns a memory region in the Reserved state. This region must
+// be transitioned to Prepared and then Ready before use.
+//
+// h must be locked.
+func (h *mheap) sysAlloc(n uintptr, hintList **arenaHint, register bool) (v unsafe.Pointer, size uintptr) {
+ assertLockHeld(&h.lock)
+
+ n = alignUp(n, heapArenaBytes)
+
+ if hintList == &h.arenaHints {
+ // First, try the arena pre-reservation.
+ // Newly-used mappings are considered released.
+ //
+ // Only do this if we're using the regular heap arena hints.
+ // This behavior is only for the heap.
+ v = h.arena.alloc(n, heapArenaBytes, &gcController.heapReleased)
+ if v != nil {
+ size = n
+ goto mapped
+ }
+ }
+
+ // Try to grow the heap at a hint address.
+ for *hintList != nil {
+ hint := *hintList
+ p := hint.addr
+ if hint.down {
+ p -= n
+ }
+ if p+n < p {
+ // We can't use this, so don't ask.
+ v = nil
+ } else if arenaIndex(p+n-1) >= 1<<arenaBits {
+ // Outside addressable heap. Can't use.
+ v = nil
+ } else {
+ v = sysReserve(unsafe.Pointer(p), n)
+ }
+ if p == uintptr(v) {
+ // Success. Update the hint.
+ if !hint.down {
+ p += n
+ }
+ hint.addr = p
+ size = n
+ break
+ }
+ // Failed. Discard this hint and try the next.
+ //
+ // TODO: This would be cleaner if sysReserve could be
+ // told to only return the requested address. In
+ // particular, this is already how Windows behaves, so
+ // it would simplify things there.
+ if v != nil {
+ sysFreeOS(v, n)
+ }
+ *hintList = hint.next
+ h.arenaHintAlloc.free(unsafe.Pointer(hint))
+ }
+
+ if size == 0 {
+ if raceenabled {
+ // The race detector assumes the heap lives in
+ // [0x00c000000000, 0x00e000000000), but we
+ // just ran out of hints in this region. Give
+ // a nice failure.
+ throw("too many address space collisions for -race mode")
+ }
+
+ // All of the hints failed, so we'll take any
+ // (sufficiently aligned) address the kernel will give
+ // us.
+ v, size = sysReserveAligned(nil, n, heapArenaBytes)
+ if v == nil {
+ return nil, 0
+ }
+
+ // Create new hints for extending this region.
+ hint := (*arenaHint)(h.arenaHintAlloc.alloc())
+ hint.addr, hint.down = uintptr(v), true
+ hint.next, mheap_.arenaHints = mheap_.arenaHints, hint
+ hint = (*arenaHint)(h.arenaHintAlloc.alloc())
+ hint.addr = uintptr(v) + size
+ hint.next, mheap_.arenaHints = mheap_.arenaHints, hint
+ }
+
+ // Check for bad pointers or pointers we can't use.
+ {
+ var bad string
+ p := uintptr(v)
+ if p+size < p {
+ bad = "region exceeds uintptr range"
+ } else if arenaIndex(p) >= 1<<arenaBits {
+ bad = "base outside usable address space"
+ } else if arenaIndex(p+size-1) >= 1<<arenaBits {
+ bad = "end outside usable address space"
+ }
+ if bad != "" {
+ // This should be impossible on most architectures,
+ // but it would be really confusing to debug.
+ print("runtime: memory allocated by OS [", hex(p), ", ", hex(p+size), ") not in usable address space: ", bad, "\n")
+ throw("memory reservation exceeds address space limit")
+ }
+ }
+
+ if uintptr(v)&(heapArenaBytes-1) != 0 {
+ throw("misrounded allocation in sysAlloc")
+ }
+
+mapped:
+ // Create arena metadata.
+ for ri := arenaIndex(uintptr(v)); ri <= arenaIndex(uintptr(v)+size-1); ri++ {
+ l2 := h.arenas[ri.l1()]
+ if l2 == nil {
+ // Allocate an L2 arena map.
+ //
+ // Use sysAllocOS instead of sysAlloc or persistentalloc because there's no
+ // statistic we can comfortably account for this space in. With this structure,
+ // we rely on demand paging to avoid large overheads, but tracking which memory
+ // is paged in is too expensive. Trying to account for the whole region means
+ // that it will appear like an enormous memory overhead in statistics, even though
+ // it is not.
+ l2 = (*[1 << arenaL2Bits]*heapArena)(sysAllocOS(unsafe.Sizeof(*l2)))
+ if l2 == nil {
+ throw("out of memory allocating heap arena map")
+ }
+ if h.arenasHugePages {
+ sysHugePage(unsafe.Pointer(l2), unsafe.Sizeof(*l2))
+ } else {
+ sysNoHugePage(unsafe.Pointer(l2), unsafe.Sizeof(*l2))
+ }
+ atomic.StorepNoWB(unsafe.Pointer(&h.arenas[ri.l1()]), unsafe.Pointer(l2))
+ }
+
+ if l2[ri.l2()] != nil {
+ throw("arena already initialized")
+ }
+ var r *heapArena
+ r = (*heapArena)(h.heapArenaAlloc.alloc(unsafe.Sizeof(*r), goarch.PtrSize, &memstats.gcMiscSys))
+ if r == nil {
+ r = (*heapArena)(persistentalloc(unsafe.Sizeof(*r), goarch.PtrSize, &memstats.gcMiscSys))
+ if r == nil {
+ throw("out of memory allocating heap arena metadata")
+ }
+ }
+
+ // Register the arena in allArenas if requested.
+ if register {
+ if len(h.allArenas) == cap(h.allArenas) {
+ size := 2 * uintptr(cap(h.allArenas)) * goarch.PtrSize
+ if size == 0 {
+ size = physPageSize
+ }
+ newArray := (*notInHeap)(persistentalloc(size, goarch.PtrSize, &memstats.gcMiscSys))
+ if newArray == nil {
+ throw("out of memory allocating allArenas")
+ }
+ oldSlice := h.allArenas
+ *(*notInHeapSlice)(unsafe.Pointer(&h.allArenas)) = notInHeapSlice{newArray, len(h.allArenas), int(size / goarch.PtrSize)}
+ copy(h.allArenas, oldSlice)
+ // Do not free the old backing array because
+ // there may be concurrent readers. Since we
+ // double the array each time, this can lead
+ // to at most 2x waste.
+ }
+ h.allArenas = h.allArenas[:len(h.allArenas)+1]
+ h.allArenas[len(h.allArenas)-1] = ri
+ }
+
+ // Store atomically just in case an object from the
+ // new heap arena becomes visible before the heap lock
+ // is released (which shouldn't happen, but there's
+ // little downside to this).
+ atomic.StorepNoWB(unsafe.Pointer(&l2[ri.l2()]), unsafe.Pointer(r))
+ }
+
+ // Tell the race detector about the new heap memory.
+ if raceenabled {
+ racemapshadow(v, size)
+ }
+
+ return
+}
+
+// sysReserveAligned is like sysReserve, but the returned pointer is
+// aligned to align bytes. It may reserve either n or n+align bytes,
+// so it returns the size that was reserved.
+func sysReserveAligned(v unsafe.Pointer, size, align uintptr) (unsafe.Pointer, uintptr) {
+ // Since the alignment is rather large in uses of this
+ // function, we're not likely to get it by chance, so we ask
+ // for a larger region and remove the parts we don't need.
+ retries := 0
+retry:
+ p := uintptr(sysReserve(v, size+align))
+ switch {
+ case p == 0:
+ return nil, 0
+ case p&(align-1) == 0:
+ return unsafe.Pointer(p), size + align
+ case GOOS == "windows":
+ // On Windows we can't release pieces of a
+ // reservation, so we release the whole thing and
+ // re-reserve the aligned sub-region. This may race,
+ // so we may have to try again.
+ sysFreeOS(unsafe.Pointer(p), size+align)
+ p = alignUp(p, align)
+ p2 := sysReserve(unsafe.Pointer(p), size)
+ if p != uintptr(p2) {
+ // Must have raced. Try again.
+ sysFreeOS(p2, size)
+ if retries++; retries == 100 {
+ throw("failed to allocate aligned heap memory; too many retries")
+ }
+ goto retry
+ }
+ // Success.
+ return p2, size
+ default:
+ // Trim off the unaligned parts.
+ pAligned := alignUp(p, align)
+ sysFreeOS(unsafe.Pointer(p), pAligned-p)
+ end := pAligned + size
+ endLen := (p + size + align) - end
+ if endLen > 0 {
+ sysFreeOS(unsafe.Pointer(end), endLen)
+ }
+ return unsafe.Pointer(pAligned), size
+ }
+}
+
+// enableMetadataHugePages enables huge pages for various sources of heap metadata.
+//
+// A note on latency: for sufficiently small heaps (<10s of GiB) this function will take constant
+// time, but may take time proportional to the size of the mapped heap beyond that.
+//
+// This function is idempotent.
+//
+// The heap lock must not be held over this operation, since it will briefly acquire
+// the heap lock.
+func (h *mheap) enableMetadataHugePages() {
+ // Enable huge pages for page structure.
+ h.pages.enableChunkHugePages()
+
+ // Grab the lock and set arenasHugePages if it's not.
+ //
+ // Once arenasHugePages is set, all new L2 entries will be eligible for
+ // huge pages. We'll set all the old entries after we release the lock.
+ lock(&h.lock)
+ if h.arenasHugePages {
+ unlock(&h.lock)
+ return
+ }
+ h.arenasHugePages = true
+ unlock(&h.lock)
+
+ // N.B. The arenas L1 map is quite small on all platforms, so it's fine to
+ // just iterate over the whole thing.
+ for i := range h.arenas {
+ l2 := (*[1 << arenaL2Bits]*heapArena)(atomic.Loadp(unsafe.Pointer(&h.arenas[i])))
+ if l2 == nil {
+ continue
+ }
+ sysHugePage(unsafe.Pointer(l2), unsafe.Sizeof(*l2))
+ }
+}
+
+// base address for all 0-byte allocations
+var zerobase uintptr
+
+// nextFreeFast returns the next free object if one is quickly available.
+// Otherwise it returns 0.
+func nextFreeFast(s *mspan) gclinkptr {
+ theBit := sys.TrailingZeros64(s.allocCache) // Is there a free object in the allocCache?
+ if theBit < 64 {
+ result := s.freeindex + uintptr(theBit)
+ if result < s.nelems {
+ freeidx := result + 1
+ if freeidx%64 == 0 && freeidx != s.nelems {
+ return 0
+ }
+ s.allocCache >>= uint(theBit + 1)
+ s.freeindex = freeidx
+ s.allocCount++
+ return gclinkptr(result*s.elemsize + s.base())
+ }
+ }
+ return 0
+}
+
+// nextFree returns the next free object from the cached span if one is available.
+// Otherwise it refills the cache with a span with an available object and
+// returns that object along with a flag indicating that this was a heavy
+// weight allocation. If it is a heavy weight allocation the caller must
+// determine whether a new GC cycle needs to be started or if the GC is active
+// whether this goroutine needs to assist the GC.
+//
+// Must run in a non-preemptible context since otherwise the owner of
+// c could change.
+func (c *mcache) nextFree(spc spanClass) (v gclinkptr, s *mspan, shouldhelpgc bool) {
+ s = c.alloc[spc]
+ shouldhelpgc = false
+ freeIndex := s.nextFreeIndex()
+ if freeIndex == s.nelems {
+ // The span is full.
+ if uintptr(s.allocCount) != s.nelems {
+ println("runtime: s.allocCount=", s.allocCount, "s.nelems=", s.nelems)
+ throw("s.allocCount != s.nelems && freeIndex == s.nelems")
+ }
+ c.refill(spc)
+ shouldhelpgc = true
+ s = c.alloc[spc]
+
+ freeIndex = s.nextFreeIndex()
+ }
+
+ if freeIndex >= s.nelems {
+ throw("freeIndex is not valid")
+ }
+
+ v = gclinkptr(freeIndex*s.elemsize + s.base())
+ s.allocCount++
+ if uintptr(s.allocCount) > s.nelems {
+ println("s.allocCount=", s.allocCount, "s.nelems=", s.nelems)
+ throw("s.allocCount > s.nelems")
+ }
+ return
+}
+
+// Allocate an object of size bytes.
+// Small objects are allocated from the per-P cache's free lists.
+// Large objects (> 32 kB) are allocated straight from the heap.
+func mallocgc(size uintptr, typ *_type, needzero bool) unsafe.Pointer {
+ if gcphase == _GCmarktermination {
+ throw("mallocgc called with gcphase == _GCmarktermination")
+ }
+
+ if size == 0 {
+ return unsafe.Pointer(&zerobase)
+ }
+
+ // It's possible for any malloc to trigger sweeping, which may in
+ // turn queue finalizers. Record this dynamic lock edge.
+ lockRankMayQueueFinalizer()
+
+ userSize := size
+ if asanenabled {
+ // Refer to ASAN runtime library, the malloc() function allocates extra memory,
+ // the redzone, around the user requested memory region. And the redzones are marked
+ // as unaddressable. We perform the same operations in Go to detect the overflows or
+ // underflows.
+ size += computeRZlog(size)
+ }
+
+ if debug.malloc {
+ if debug.sbrk != 0 {
+ align := uintptr(16)
+ if typ != nil {
+ // TODO(austin): This should be just
+ // align = uintptr(typ.align)
+ // but that's only 4 on 32-bit platforms,
+ // even if there's a uint64 field in typ (see #599).
+ // This causes 64-bit atomic accesses to panic.
+ // Hence, we use stricter alignment that matches
+ // the normal allocator better.
+ if size&7 == 0 {
+ align = 8
+ } else if size&3 == 0 {
+ align = 4
+ } else if size&1 == 0 {
+ align = 2
+ } else {
+ align = 1
+ }
+ }
+ return persistentalloc(size, align, &memstats.other_sys)
+ }
+
+ if inittrace.active && inittrace.id == getg().goid {
+ // Init functions are executed sequentially in a single goroutine.
+ inittrace.allocs += 1
+ }
+ }
+
+ // assistG is the G to charge for this allocation, or nil if
+ // GC is not currently active.
+ assistG := deductAssistCredit(size)
+
+ // Set mp.mallocing to keep from being preempted by GC.
+ mp := acquirem()
+ if mp.mallocing != 0 {
+ throw("malloc deadlock")
+ }
+ if mp.gsignal == getg() {
+ throw("malloc during signal")
+ }
+ mp.mallocing = 1
+
+ shouldhelpgc := false
+ dataSize := userSize
+ c := getMCache(mp)
+ if c == nil {
+ throw("mallocgc called without a P or outside bootstrapping")
+ }
+ var span *mspan
+ var x unsafe.Pointer
+ noscan := typ == nil || typ.PtrBytes == 0
+ // In some cases block zeroing can profitably (for latency reduction purposes)
+ // be delayed till preemption is possible; delayedZeroing tracks that state.
+ delayedZeroing := false
+ if size <= maxSmallSize {
+ if noscan && size < maxTinySize {
+ // Tiny allocator.
+ //
+ // Tiny allocator combines several tiny allocation requests
+ // into a single memory block. The resulting memory block
+ // is freed when all subobjects are unreachable. The subobjects
+ // must be noscan (don't have pointers), this ensures that
+ // the amount of potentially wasted memory is bounded.
+ //
+ // Size of the memory block used for combining (maxTinySize) is tunable.
+ // Current setting is 16 bytes, which relates to 2x worst case memory
+ // wastage (when all but one subobjects are unreachable).
+ // 8 bytes would result in no wastage at all, but provides less
+ // opportunities for combining.
+ // 32 bytes provides more opportunities for combining,
+ // but can lead to 4x worst case wastage.
+ // The best case winning is 8x regardless of block size.
+ //
+ // Objects obtained from tiny allocator must not be freed explicitly.
+ // So when an object will be freed explicitly, we ensure that
+ // its size >= maxTinySize.
+ //
+ // SetFinalizer has a special case for objects potentially coming
+ // from tiny allocator, it such case it allows to set finalizers
+ // for an inner byte of a memory block.
+ //
+ // The main targets of tiny allocator are small strings and
+ // standalone escaping variables. On a json benchmark
+ // the allocator reduces number of allocations by ~12% and
+ // reduces heap size by ~20%.
+ off := c.tinyoffset
+ // Align tiny pointer for required (conservative) alignment.
+ if size&7 == 0 {
+ off = alignUp(off, 8)
+ } else if goarch.PtrSize == 4 && size == 12 {
+ // Conservatively align 12-byte objects to 8 bytes on 32-bit
+ // systems so that objects whose first field is a 64-bit
+ // value is aligned to 8 bytes and does not cause a fault on
+ // atomic access. See issue 37262.
+ // TODO(mknyszek): Remove this workaround if/when issue 36606
+ // is resolved.
+ off = alignUp(off, 8)
+ } else if size&3 == 0 {
+ off = alignUp(off, 4)
+ } else if size&1 == 0 {
+ off = alignUp(off, 2)
+ }
+ if off+size <= maxTinySize && c.tiny != 0 {
+ // The object fits into existing tiny block.
+ x = unsafe.Pointer(c.tiny + off)
+ c.tinyoffset = off + size
+ c.tinyAllocs++
+ mp.mallocing = 0
+ releasem(mp)
+ return x
+ }
+ // Allocate a new maxTinySize block.
+ span = c.alloc[tinySpanClass]
+ v := nextFreeFast(span)
+ if v == 0 {
+ v, span, shouldhelpgc = c.nextFree(tinySpanClass)
+ }
+ x = unsafe.Pointer(v)
+ (*[2]uint64)(x)[0] = 0
+ (*[2]uint64)(x)[1] = 0
+ // See if we need to replace the existing tiny block with the new one
+ // based on amount of remaining free space.
+ if !raceenabled && (size < c.tinyoffset || c.tiny == 0) {
+ // Note: disabled when race detector is on, see comment near end of this function.
+ c.tiny = uintptr(x)
+ c.tinyoffset = size
+ }
+ size = maxTinySize
+ } else {
+ var sizeclass uint8
+ if size <= smallSizeMax-8 {
+ sizeclass = size_to_class8[divRoundUp(size, smallSizeDiv)]
+ } else {
+ sizeclass = size_to_class128[divRoundUp(size-smallSizeMax, largeSizeDiv)]
+ }
+ size = uintptr(class_to_size[sizeclass])
+ spc := makeSpanClass(sizeclass, noscan)
+ span = c.alloc[spc]
+ v := nextFreeFast(span)
+ if v == 0 {
+ v, span, shouldhelpgc = c.nextFree(spc)
+ }
+ x = unsafe.Pointer(v)
+ if needzero && span.needzero != 0 {
+ memclrNoHeapPointers(x, size)
+ }
+ }
+ } else {
+ shouldhelpgc = true
+ // For large allocations, keep track of zeroed state so that
+ // bulk zeroing can be happen later in a preemptible context.
+ span = c.allocLarge(size, noscan)
+ span.freeindex = 1
+ span.allocCount = 1
+ size = span.elemsize
+ x = unsafe.Pointer(span.base())
+ if needzero && span.needzero != 0 {
+ if noscan {
+ delayedZeroing = true
+ } else {
+ memclrNoHeapPointers(x, size)
+ // We've in theory cleared almost the whole span here,
+ // and could take the extra step of actually clearing
+ // the whole thing. However, don't. Any GC bits for the
+ // uncleared parts will be zero, and it's just going to
+ // be needzero = 1 once freed anyway.
+ }
+ }
+ }
+
+ if !noscan {
+ var scanSize uintptr
+ heapBitsSetType(uintptr(x), size, dataSize, typ)
+ if dataSize > typ.Size_ {
+ // Array allocation. If there are any
+ // pointers, GC has to scan to the last
+ // element.
+ if typ.PtrBytes != 0 {
+ scanSize = dataSize - typ.Size_ + typ.PtrBytes
+ }
+ } else {
+ scanSize = typ.PtrBytes
+ }
+ c.scanAlloc += scanSize
+ }
+
+ // Ensure that the stores above that initialize x to
+ // type-safe memory and set the heap bits occur before
+ // the caller can make x observable to the garbage
+ // collector. Otherwise, on weakly ordered machines,
+ // the garbage collector could follow a pointer to x,
+ // but see uninitialized memory or stale heap bits.
+ publicationBarrier()
+ // As x and the heap bits are initialized, update
+ // freeIndexForScan now so x is seen by the GC
+ // (including conservative scan) as an allocated object.
+ // While this pointer can't escape into user code as a
+ // _live_ pointer until we return, conservative scanning
+ // may find a dead pointer that happens to point into this
+ // object. Delaying this update until now ensures that
+ // conservative scanning considers this pointer dead until
+ // this point.
+ span.freeIndexForScan = span.freeindex
+
+ // Allocate black during GC.
+ // All slots hold nil so no scanning is needed.
+ // This may be racing with GC so do it atomically if there can be
+ // a race marking the bit.
+ if gcphase != _GCoff {
+ gcmarknewobject(span, uintptr(x), size)
+ }
+
+ if raceenabled {
+ racemalloc(x, size)
+ }
+
+ if msanenabled {
+ msanmalloc(x, size)
+ }
+
+ if asanenabled {
+ // We should only read/write the memory with the size asked by the user.
+ // The rest of the allocated memory should be poisoned, so that we can report
+ // errors when accessing poisoned memory.
+ // The allocated memory is larger than required userSize, it will also include
+ // redzone and some other padding bytes.
+ rzBeg := unsafe.Add(x, userSize)
+ asanpoison(rzBeg, size-userSize)
+ asanunpoison(x, userSize)
+ }
+
+ if rate := MemProfileRate; rate > 0 {
+ // Note cache c only valid while m acquired; see #47302
+ if rate != 1 && size < c.nextSample {
+ c.nextSample -= size
+ } else {
+ profilealloc(mp, x, size)
+ }
+ }
+ mp.mallocing = 0
+ releasem(mp)
+
+ // Pointerfree data can be zeroed late in a context where preemption can occur.
+ // x will keep the memory alive.
+ if delayedZeroing {
+ if !noscan {
+ throw("delayed zeroing on data that may contain pointers")
+ }
+ memclrNoHeapPointersChunked(size, x) // This is a possible preemption point: see #47302
+ }
+
+ if debug.malloc {
+ if debug.allocfreetrace != 0 {
+ tracealloc(x, size, typ)
+ }
+
+ if inittrace.active && inittrace.id == getg().goid {
+ // Init functions are executed sequentially in a single goroutine.
+ inittrace.bytes += uint64(size)
+ }
+ }
+
+ if assistG != nil {
+ // Account for internal fragmentation in the assist
+ // debt now that we know it.
+ assistG.gcAssistBytes -= int64(size - dataSize)
+ }
+
+ if shouldhelpgc {
+ if t := (gcTrigger{kind: gcTriggerHeap}); t.test() {
+ gcStart(t)
+ }
+ }
+
+ if raceenabled && noscan && dataSize < maxTinySize {
+ // Pad tinysize allocations so they are aligned with the end
+ // of the tinyalloc region. This ensures that any arithmetic
+ // that goes off the top end of the object will be detectable
+ // by checkptr (issue 38872).
+ // Note that we disable tinyalloc when raceenabled for this to work.
+ // TODO: This padding is only performed when the race detector
+ // is enabled. It would be nice to enable it if any package
+ // was compiled with checkptr, but there's no easy way to
+ // detect that (especially at compile time).
+ // TODO: enable this padding for all allocations, not just
+ // tinyalloc ones. It's tricky because of pointer maps.
+ // Maybe just all noscan objects?
+ x = add(x, size-dataSize)
+ }
+
+ return x
+}
+
+// deductAssistCredit reduces the current G's assist credit
+// by size bytes, and assists the GC if necessary.
+//
+// Caller must be preemptible.
+//
+// Returns the G for which the assist credit was accounted.
+func deductAssistCredit(size uintptr) *g {
+ var assistG *g
+ if gcBlackenEnabled != 0 {
+ // Charge the current user G for this allocation.
+ assistG = getg()
+ if assistG.m.curg != nil {
+ assistG = assistG.m.curg
+ }
+ // Charge the allocation against the G. We'll account
+ // for internal fragmentation at the end of mallocgc.
+ assistG.gcAssistBytes -= int64(size)
+
+ if assistG.gcAssistBytes < 0 {
+ // This G is in debt. Assist the GC to correct
+ // this before allocating. This must happen
+ // before disabling preemption.
+ gcAssistAlloc(assistG)
+ }
+ }
+ return assistG
+}
+
+// memclrNoHeapPointersChunked repeatedly calls memclrNoHeapPointers
+// on chunks of the buffer to be zeroed, with opportunities for preemption
+// along the way. memclrNoHeapPointers contains no safepoints and also
+// cannot be preemptively scheduled, so this provides a still-efficient
+// block copy that can also be preempted on a reasonable granularity.
+//
+// Use this with care; if the data being cleared is tagged to contain
+// pointers, this allows the GC to run before it is all cleared.
+func memclrNoHeapPointersChunked(size uintptr, x unsafe.Pointer) {
+ v := uintptr(x)
+ // got this from benchmarking. 128k is too small, 512k is too large.
+ const chunkBytes = 256 * 1024
+ vsize := v + size
+ for voff := v; voff < vsize; voff = voff + chunkBytes {
+ if getg().preempt {
+ // may hold locks, e.g., profiling
+ goschedguarded()
+ }
+ // clear min(avail, lump) bytes
+ n := vsize - voff
+ if n > chunkBytes {
+ n = chunkBytes
+ }
+ memclrNoHeapPointers(unsafe.Pointer(voff), n)
+ }
+}
+
+// implementation of new builtin
+// compiler (both frontend and SSA backend) knows the signature
+// of this function.
+func newobject(typ *_type) unsafe.Pointer {
+ return mallocgc(typ.Size_, typ, true)
+}
+
+//go:linkname reflect_unsafe_New reflect.unsafe_New
+func reflect_unsafe_New(typ *_type) unsafe.Pointer {
+ return mallocgc(typ.Size_, typ, true)
+}
+
+//go:linkname reflectlite_unsafe_New internal/reflectlite.unsafe_New
+func reflectlite_unsafe_New(typ *_type) unsafe.Pointer {
+ return mallocgc(typ.Size_, typ, true)
+}
+
+// newarray allocates an array of n elements of type typ.
+func newarray(typ *_type, n int) unsafe.Pointer {
+ if n == 1 {
+ return mallocgc(typ.Size_, typ, true)
+ }
+ mem, overflow := math.MulUintptr(typ.Size_, uintptr(n))
+ if overflow || mem > maxAlloc || n < 0 {
+ panic(plainError("runtime: allocation size out of range"))
+ }
+ return mallocgc(mem, typ, true)
+}
+
+//go:linkname reflect_unsafe_NewArray reflect.unsafe_NewArray
+func reflect_unsafe_NewArray(typ *_type, n int) unsafe.Pointer {
+ return newarray(typ, n)
+}
+
+func profilealloc(mp *m, x unsafe.Pointer, size uintptr) {
+ c := getMCache(mp)
+ if c == nil {
+ throw("profilealloc called without a P or outside bootstrapping")
+ }
+ c.nextSample = nextSample()
+ mProf_Malloc(x, size)
+}
+
+// nextSample returns the next sampling point for heap profiling. The goal is
+// to sample allocations on average every MemProfileRate bytes, but with a
+// completely random distribution over the allocation timeline; this
+// corresponds to a Poisson process with parameter MemProfileRate. In Poisson
+// processes, the distance between two samples follows the exponential
+// distribution (exp(MemProfileRate)), so the best return value is a random
+// number taken from an exponential distribution whose mean is MemProfileRate.
+func nextSample() uintptr {
+ if MemProfileRate == 1 {
+ // Callers assign our return value to
+ // mcache.next_sample, but next_sample is not used
+ // when the rate is 1. So avoid the math below and
+ // just return something.
+ return 0
+ }
+ if GOOS == "plan9" {
+ // Plan 9 doesn't support floating point in note handler.
+ if gp := getg(); gp == gp.m.gsignal {
+ return nextSampleNoFP()
+ }
+ }
+
+ return uintptr(fastexprand(MemProfileRate))
+}
+
+// fastexprand returns a random number from an exponential distribution with
+// the specified mean.
+func fastexprand(mean int) int32 {
+ // Avoid overflow. Maximum possible step is
+ // -ln(1/(1<<randomBitCount)) * mean, approximately 20 * mean.
+ switch {
+ case mean > 0x7000000:
+ mean = 0x7000000
+ case mean == 0:
+ return 0
+ }
+
+ // Take a random sample of the exponential distribution exp(-mean*x).
+ // The probability distribution function is mean*exp(-mean*x), so the CDF is
+ // p = 1 - exp(-mean*x), so
+ // q = 1 - p == exp(-mean*x)
+ // log_e(q) = -mean*x
+ // -log_e(q)/mean = x
+ // x = -log_e(q) * mean
+ // x = log_2(q) * (-log_e(2)) * mean ; Using log_2 for efficiency
+ const randomBitCount = 26
+ q := fastrandn(1<<randomBitCount) + 1
+ qlog := fastlog2(float64(q)) - randomBitCount
+ if qlog > 0 {
+ qlog = 0
+ }
+ const minusLog2 = -0.6931471805599453 // -ln(2)
+ return int32(qlog*(minusLog2*float64(mean))) + 1
+}
+
+// nextSampleNoFP is similar to nextSample, but uses older,
+// simpler code to avoid floating point.
+func nextSampleNoFP() uintptr {
+ // Set first allocation sample size.
+ rate := MemProfileRate
+ if rate > 0x3fffffff { // make 2*rate not overflow
+ rate = 0x3fffffff
+ }
+ if rate != 0 {
+ return uintptr(fastrandn(uint32(2 * rate)))
+ }
+ return 0
+}
+
+type persistentAlloc struct {
+ base *notInHeap
+ off uintptr
+}
+
+var globalAlloc struct {
+ mutex
+ persistentAlloc
+}
+
+// persistentChunkSize is the number of bytes we allocate when we grow
+// a persistentAlloc.
+const persistentChunkSize = 256 << 10
+
+// persistentChunks is a list of all the persistent chunks we have
+// allocated. The list is maintained through the first word in the
+// persistent chunk. This is updated atomically.
+var persistentChunks *notInHeap
+
+// Wrapper around sysAlloc that can allocate small chunks.
+// There is no associated free operation.
+// Intended for things like function/type/debug-related persistent data.
+// If align is 0, uses default align (currently 8).
+// The returned memory will be zeroed.
+// sysStat must be non-nil.
+//
+// Consider marking persistentalloc'd types not in heap by embedding
+// runtime/internal/sys.NotInHeap.
+func persistentalloc(size, align uintptr, sysStat *sysMemStat) unsafe.Pointer {
+ var p *notInHeap
+ systemstack(func() {
+ p = persistentalloc1(size, align, sysStat)
+ })
+ return unsafe.Pointer(p)
+}
+
+// Must run on system stack because stack growth can (re)invoke it.
+// See issue 9174.
+//
+//go:systemstack
+func persistentalloc1(size, align uintptr, sysStat *sysMemStat) *notInHeap {
+ const (
+ maxBlock = 64 << 10 // VM reservation granularity is 64K on windows
+ )
+
+ if size == 0 {
+ throw("persistentalloc: size == 0")
+ }
+ if align != 0 {
+ if align&(align-1) != 0 {
+ throw("persistentalloc: align is not a power of 2")
+ }
+ if align > _PageSize {
+ throw("persistentalloc: align is too large")
+ }
+ } else {
+ align = 8
+ }
+
+ if size >= maxBlock {
+ return (*notInHeap)(sysAlloc(size, sysStat))
+ }
+
+ mp := acquirem()
+ var persistent *persistentAlloc
+ if mp != nil && mp.p != 0 {
+ persistent = &mp.p.ptr().palloc
+ } else {
+ lock(&globalAlloc.mutex)
+ persistent = &globalAlloc.persistentAlloc
+ }
+ persistent.off = alignUp(persistent.off, align)
+ if persistent.off+size > persistentChunkSize || persistent.base == nil {
+ persistent.base = (*notInHeap)(sysAlloc(persistentChunkSize, &memstats.other_sys))
+ if persistent.base == nil {
+ if persistent == &globalAlloc.persistentAlloc {
+ unlock(&globalAlloc.mutex)
+ }
+ throw("runtime: cannot allocate memory")
+ }
+
+ // Add the new chunk to the persistentChunks list.
+ for {
+ chunks := uintptr(unsafe.Pointer(persistentChunks))
+ *(*uintptr)(unsafe.Pointer(persistent.base)) = chunks
+ if atomic.Casuintptr((*uintptr)(unsafe.Pointer(&persistentChunks)), chunks, uintptr(unsafe.Pointer(persistent.base))) {
+ break
+ }
+ }
+ persistent.off = alignUp(goarch.PtrSize, align)
+ }
+ p := persistent.base.add(persistent.off)
+ persistent.off += size
+ releasem(mp)
+ if persistent == &globalAlloc.persistentAlloc {
+ unlock(&globalAlloc.mutex)
+ }
+
+ if sysStat != &memstats.other_sys {
+ sysStat.add(int64(size))
+ memstats.other_sys.add(-int64(size))
+ }
+ return p
+}
+
+// inPersistentAlloc reports whether p points to memory allocated by
+// persistentalloc. This must be nosplit because it is called by the
+// cgo checker code, which is called by the write barrier code.
+//
+//go:nosplit
+func inPersistentAlloc(p uintptr) bool {
+ chunk := atomic.Loaduintptr((*uintptr)(unsafe.Pointer(&persistentChunks)))
+ for chunk != 0 {
+ if p >= chunk && p < chunk+persistentChunkSize {
+ return true
+ }
+ chunk = *(*uintptr)(unsafe.Pointer(chunk))
+ }
+ return false
+}
+
+// linearAlloc is a simple linear allocator that pre-reserves a region
+// of memory and then optionally maps that region into the Ready state
+// as needed.
+//
+// The caller is responsible for locking.
+type linearAlloc struct {
+ next uintptr // next free byte
+ mapped uintptr // one byte past end of mapped space
+ end uintptr // end of reserved space
+
+ mapMemory bool // transition memory from Reserved to Ready if true
+}
+
+func (l *linearAlloc) init(base, size uintptr, mapMemory bool) {
+ if base+size < base {
+ // Chop off the last byte. The runtime isn't prepared
+ // to deal with situations where the bounds could overflow.
+ // Leave that memory reserved, though, so we don't map it
+ // later.
+ size -= 1
+ }
+ l.next, l.mapped = base, base
+ l.end = base + size
+ l.mapMemory = mapMemory
+}
+
+func (l *linearAlloc) alloc(size, align uintptr, sysStat *sysMemStat) unsafe.Pointer {
+ p := alignUp(l.next, align)
+ if p+size > l.end {
+ return nil
+ }
+ l.next = p + size
+ if pEnd := alignUp(l.next-1, physPageSize); pEnd > l.mapped {
+ if l.mapMemory {
+ // Transition from Reserved to Prepared to Ready.
+ n := pEnd - l.mapped
+ sysMap(unsafe.Pointer(l.mapped), n, sysStat)
+ sysUsed(unsafe.Pointer(l.mapped), n, n)
+ }
+ l.mapped = pEnd
+ }
+ return unsafe.Pointer(p)
+}
+
+// notInHeap is off-heap memory allocated by a lower-level allocator
+// like sysAlloc or persistentAlloc.
+//
+// In general, it's better to use real types which embed
+// runtime/internal/sys.NotInHeap, but this serves as a generic type
+// for situations where that isn't possible (like in the allocators).
+//
+// TODO: Use this as the return type of sysAlloc, persistentAlloc, etc?
+type notInHeap struct{ _ sys.NotInHeap }
+
+func (p *notInHeap) add(bytes uintptr) *notInHeap {
+ return (*notInHeap)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + bytes))
+}
+
+// computeRZlog computes the size of the redzone.
+// Refer to the implementation of the compiler-rt.
+func computeRZlog(userSize uintptr) uintptr {
+ switch {
+ case userSize <= (64 - 16):
+ return 16 << 0
+ case userSize <= (128 - 32):
+ return 16 << 1
+ case userSize <= (512 - 64):
+ return 16 << 2
+ case userSize <= (4096 - 128):
+ return 16 << 3
+ case userSize <= (1<<14)-256:
+ return 16 << 4
+ case userSize <= (1<<15)-512:
+ return 16 << 5
+ case userSize <= (1<<16)-1024:
+ return 16 << 6
+ default:
+ return 16 << 7
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/map.go b/contrib/go/_std_1.21/src/runtime/map.go
new file mode 100644
index 0000000000..6b85681447
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/map.go
@@ -0,0 +1,1724 @@
+// Copyright 2014 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 runtime
+
+// This file contains the implementation of Go's map type.
+//
+// A map is just a hash table. The data is arranged
+// into an array of buckets. Each bucket contains up to
+// 8 key/elem pairs. The low-order bits of the hash are
+// used to select a bucket. Each bucket contains a few
+// high-order bits of each hash to distinguish the entries
+// within a single bucket.
+//
+// If more than 8 keys hash to a bucket, we chain on
+// extra buckets.
+//
+// When the hashtable grows, we allocate a new array
+// of buckets twice as big. Buckets are incrementally
+// copied from the old bucket array to the new bucket array.
+//
+// Map iterators walk through the array of buckets and
+// return the keys in walk order (bucket #, then overflow
+// chain order, then bucket index). To maintain iteration
+// semantics, we never move keys within their bucket (if
+// we did, keys might be returned 0 or 2 times). When
+// growing the table, iterators remain iterating through the
+// old table and must check the new table if the bucket
+// they are iterating through has been moved ("evacuated")
+// to the new table.
+
+// Picking loadFactor: too large and we have lots of overflow
+// buckets, too small and we waste a lot of space. I wrote
+// a simple program to check some stats for different loads:
+// (64-bit, 8 byte keys and elems)
+// loadFactor %overflow bytes/entry hitprobe missprobe
+// 4.00 2.13 20.77 3.00 4.00
+// 4.50 4.05 17.30 3.25 4.50
+// 5.00 6.85 14.77 3.50 5.00
+// 5.50 10.55 12.94 3.75 5.50
+// 6.00 15.27 11.67 4.00 6.00
+// 6.50 20.90 10.79 4.25 6.50
+// 7.00 27.14 10.15 4.50 7.00
+// 7.50 34.03 9.73 4.75 7.50
+// 8.00 41.10 9.40 5.00 8.00
+//
+// %overflow = percentage of buckets which have an overflow bucket
+// bytes/entry = overhead bytes used per key/elem pair
+// hitprobe = # of entries to check when looking up a present key
+// missprobe = # of entries to check when looking up an absent key
+//
+// Keep in mind this data is for maximally loaded tables, i.e. just
+// before the table grows. Typical tables will be somewhat less loaded.
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "runtime/internal/math"
+ "unsafe"
+)
+
+const (
+ // Maximum number of key/elem pairs a bucket can hold.
+ bucketCntBits = abi.MapBucketCountBits
+ bucketCnt = abi.MapBucketCount
+
+ // Maximum average load of a bucket that triggers growth is bucketCnt*13/16 (about 80% full)
+ // Because of minimum alignment rules, bucketCnt is known to be at least 8.
+ // Represent as loadFactorNum/loadFactorDen, to allow integer math.
+ loadFactorDen = 2
+ loadFactorNum = (bucketCnt * 13 / 16) * loadFactorDen
+
+ // Maximum key or elem size to keep inline (instead of mallocing per element).
+ // Must fit in a uint8.
+ // Fast versions cannot handle big elems - the cutoff size for
+ // fast versions in cmd/compile/internal/gc/walk.go must be at most this elem.
+ maxKeySize = abi.MapMaxKeyBytes
+ maxElemSize = abi.MapMaxElemBytes
+
+ // data offset should be the size of the bmap struct, but needs to be
+ // aligned correctly. For amd64p32 this means 64-bit alignment
+ // even though pointers are 32 bit.
+ dataOffset = unsafe.Offsetof(struct {
+ b bmap
+ v int64
+ }{}.v)
+
+ // Possible tophash values. We reserve a few possibilities for special marks.
+ // Each bucket (including its overflow buckets, if any) will have either all or none of its
+ // entries in the evacuated* states (except during the evacuate() method, which only happens
+ // during map writes and thus no one else can observe the map during that time).
+ emptyRest = 0 // this cell is empty, and there are no more non-empty cells at higher indexes or overflows.
+ emptyOne = 1 // this cell is empty
+ evacuatedX = 2 // key/elem is valid. Entry has been evacuated to first half of larger table.
+ evacuatedY = 3 // same as above, but evacuated to second half of larger table.
+ evacuatedEmpty = 4 // cell is empty, bucket is evacuated.
+ minTopHash = 5 // minimum tophash for a normal filled cell.
+
+ // flags
+ iterator = 1 // there may be an iterator using buckets
+ oldIterator = 2 // there may be an iterator using oldbuckets
+ hashWriting = 4 // a goroutine is writing to the map
+ sameSizeGrow = 8 // the current map growth is to a new map of the same size
+
+ // sentinel bucket ID for iterator checks
+ noCheck = 1<<(8*goarch.PtrSize) - 1
+)
+
+// isEmpty reports whether the given tophash array entry represents an empty bucket entry.
+func isEmpty(x uint8) bool {
+ return x <= emptyOne
+}
+
+// A header for a Go map.
+type hmap struct {
+ // Note: the format of the hmap is also encoded in cmd/compile/internal/reflectdata/reflect.go.
+ // Make sure this stays in sync with the compiler's definition.
+ count int // # live cells == size of map. Must be first (used by len() builtin)
+ flags uint8
+ B uint8 // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
+ noverflow uint16 // approximate number of overflow buckets; see incrnoverflow for details
+ hash0 uint32 // hash seed
+
+ buckets unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
+ oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
+ nevacuate uintptr // progress counter for evacuation (buckets less than this have been evacuated)
+
+ extra *mapextra // optional fields
+}
+
+// mapextra holds fields that are not present on all maps.
+type mapextra struct {
+ // If both key and elem do not contain pointers and are inline, then we mark bucket
+ // type as containing no pointers. This avoids scanning such maps.
+ // However, bmap.overflow is a pointer. In order to keep overflow buckets
+ // alive, we store pointers to all overflow buckets in hmap.extra.overflow and hmap.extra.oldoverflow.
+ // overflow and oldoverflow are only used if key and elem do not contain pointers.
+ // overflow contains overflow buckets for hmap.buckets.
+ // oldoverflow contains overflow buckets for hmap.oldbuckets.
+ // The indirection allows to store a pointer to the slice in hiter.
+ overflow *[]*bmap
+ oldoverflow *[]*bmap
+
+ // nextOverflow holds a pointer to a free overflow bucket.
+ nextOverflow *bmap
+}
+
+// A bucket for a Go map.
+type bmap struct {
+ // tophash generally contains the top byte of the hash value
+ // for each key in this bucket. If tophash[0] < minTopHash,
+ // tophash[0] is a bucket evacuation state instead.
+ tophash [bucketCnt]uint8
+ // Followed by bucketCnt keys and then bucketCnt elems.
+ // NOTE: packing all the keys together and then all the elems together makes the
+ // code a bit more complicated than alternating key/elem/key/elem/... but it allows
+ // us to eliminate padding which would be needed for, e.g., map[int64]int8.
+ // Followed by an overflow pointer.
+}
+
+// A hash iteration structure.
+// If you modify hiter, also change cmd/compile/internal/reflectdata/reflect.go
+// and reflect/value.go to match the layout of this structure.
+type hiter struct {
+ key unsafe.Pointer // Must be in first position. Write nil to indicate iteration end (see cmd/compile/internal/walk/range.go).
+ elem unsafe.Pointer // Must be in second position (see cmd/compile/internal/walk/range.go).
+ t *maptype
+ h *hmap
+ buckets unsafe.Pointer // bucket ptr at hash_iter initialization time
+ bptr *bmap // current bucket
+ overflow *[]*bmap // keeps overflow buckets of hmap.buckets alive
+ oldoverflow *[]*bmap // keeps overflow buckets of hmap.oldbuckets alive
+ startBucket uintptr // bucket iteration started at
+ offset uint8 // intra-bucket offset to start from during iteration (should be big enough to hold bucketCnt-1)
+ wrapped bool // already wrapped around from end of bucket array to beginning
+ B uint8
+ i uint8
+ bucket uintptr
+ checkBucket uintptr
+}
+
+// bucketShift returns 1<<b, optimized for code generation.
+func bucketShift(b uint8) uintptr {
+ // Masking the shift amount allows overflow checks to be elided.
+ return uintptr(1) << (b & (goarch.PtrSize*8 - 1))
+}
+
+// bucketMask returns 1<<b - 1, optimized for code generation.
+func bucketMask(b uint8) uintptr {
+ return bucketShift(b) - 1
+}
+
+// tophash calculates the tophash value for hash.
+func tophash(hash uintptr) uint8 {
+ top := uint8(hash >> (goarch.PtrSize*8 - 8))
+ if top < minTopHash {
+ top += minTopHash
+ }
+ return top
+}
+
+func evacuated(b *bmap) bool {
+ h := b.tophash[0]
+ return h > emptyOne && h < minTopHash
+}
+
+func (b *bmap) overflow(t *maptype) *bmap {
+ return *(**bmap)(add(unsafe.Pointer(b), uintptr(t.BucketSize)-goarch.PtrSize))
+}
+
+func (b *bmap) setoverflow(t *maptype, ovf *bmap) {
+ *(**bmap)(add(unsafe.Pointer(b), uintptr(t.BucketSize)-goarch.PtrSize)) = ovf
+}
+
+func (b *bmap) keys() unsafe.Pointer {
+ return add(unsafe.Pointer(b), dataOffset)
+}
+
+// incrnoverflow increments h.noverflow.
+// noverflow counts the number of overflow buckets.
+// This is used to trigger same-size map growth.
+// See also tooManyOverflowBuckets.
+// To keep hmap small, noverflow is a uint16.
+// When there are few buckets, noverflow is an exact count.
+// When there are many buckets, noverflow is an approximate count.
+func (h *hmap) incrnoverflow() {
+ // We trigger same-size map growth if there are
+ // as many overflow buckets as buckets.
+ // We need to be able to count to 1<<h.B.
+ if h.B < 16 {
+ h.noverflow++
+ return
+ }
+ // Increment with probability 1/(1<<(h.B-15)).
+ // When we reach 1<<15 - 1, we will have approximately
+ // as many overflow buckets as buckets.
+ mask := uint32(1)<<(h.B-15) - 1
+ // Example: if h.B == 18, then mask == 7,
+ // and fastrand & 7 == 0 with probability 1/8.
+ if fastrand()&mask == 0 {
+ h.noverflow++
+ }
+}
+
+func (h *hmap) newoverflow(t *maptype, b *bmap) *bmap {
+ var ovf *bmap
+ if h.extra != nil && h.extra.nextOverflow != nil {
+ // We have preallocated overflow buckets available.
+ // See makeBucketArray for more details.
+ ovf = h.extra.nextOverflow
+ if ovf.overflow(t) == nil {
+ // We're not at the end of the preallocated overflow buckets. Bump the pointer.
+ h.extra.nextOverflow = (*bmap)(add(unsafe.Pointer(ovf), uintptr(t.BucketSize)))
+ } else {
+ // This is the last preallocated overflow bucket.
+ // Reset the overflow pointer on this bucket,
+ // which was set to a non-nil sentinel value.
+ ovf.setoverflow(t, nil)
+ h.extra.nextOverflow = nil
+ }
+ } else {
+ ovf = (*bmap)(newobject(t.Bucket))
+ }
+ h.incrnoverflow()
+ if t.Bucket.PtrBytes == 0 {
+ h.createOverflow()
+ *h.extra.overflow = append(*h.extra.overflow, ovf)
+ }
+ b.setoverflow(t, ovf)
+ return ovf
+}
+
+func (h *hmap) createOverflow() {
+ if h.extra == nil {
+ h.extra = new(mapextra)
+ }
+ if h.extra.overflow == nil {
+ h.extra.overflow = new([]*bmap)
+ }
+}
+
+func makemap64(t *maptype, hint int64, h *hmap) *hmap {
+ if int64(int(hint)) != hint {
+ hint = 0
+ }
+ return makemap(t, int(hint), h)
+}
+
+// makemap_small implements Go map creation for make(map[k]v) and
+// make(map[k]v, hint) when hint is known to be at most bucketCnt
+// at compile time and the map needs to be allocated on the heap.
+func makemap_small() *hmap {
+ h := new(hmap)
+ h.hash0 = fastrand()
+ return h
+}
+
+// makemap implements Go map creation for make(map[k]v, hint).
+// If the compiler has determined that the map or the first bucket
+// can be created on the stack, h and/or bucket may be non-nil.
+// If h != nil, the map can be created directly in h.
+// If h.buckets != nil, bucket pointed to can be used as the first bucket.
+func makemap(t *maptype, hint int, h *hmap) *hmap {
+ mem, overflow := math.MulUintptr(uintptr(hint), t.Bucket.Size_)
+ if overflow || mem > maxAlloc {
+ hint = 0
+ }
+
+ // initialize Hmap
+ if h == nil {
+ h = new(hmap)
+ }
+ h.hash0 = fastrand()
+
+ // Find the size parameter B which will hold the requested # of elements.
+ // For hint < 0 overLoadFactor returns false since hint < bucketCnt.
+ B := uint8(0)
+ for overLoadFactor(hint, B) {
+ B++
+ }
+ h.B = B
+
+ // allocate initial hash table
+ // if B == 0, the buckets field is allocated lazily later (in mapassign)
+ // If hint is large zeroing this memory could take a while.
+ if h.B != 0 {
+ var nextOverflow *bmap
+ h.buckets, nextOverflow = makeBucketArray(t, h.B, nil)
+ if nextOverflow != nil {
+ h.extra = new(mapextra)
+ h.extra.nextOverflow = nextOverflow
+ }
+ }
+
+ return h
+}
+
+// makeBucketArray initializes a backing array for map buckets.
+// 1<<b is the minimum number of buckets to allocate.
+// dirtyalloc should either be nil or a bucket array previously
+// allocated by makeBucketArray with the same t and b parameters.
+// If dirtyalloc is nil a new backing array will be alloced and
+// otherwise dirtyalloc will be cleared and reused as backing array.
+func makeBucketArray(t *maptype, b uint8, dirtyalloc unsafe.Pointer) (buckets unsafe.Pointer, nextOverflow *bmap) {
+ base := bucketShift(b)
+ nbuckets := base
+ // For small b, overflow buckets are unlikely.
+ // Avoid the overhead of the calculation.
+ if b >= 4 {
+ // Add on the estimated number of overflow buckets
+ // required to insert the median number of elements
+ // used with this value of b.
+ nbuckets += bucketShift(b - 4)
+ sz := t.Bucket.Size_ * nbuckets
+ up := roundupsize(sz)
+ if up != sz {
+ nbuckets = up / t.Bucket.Size_
+ }
+ }
+
+ if dirtyalloc == nil {
+ buckets = newarray(t.Bucket, int(nbuckets))
+ } else {
+ // dirtyalloc was previously generated by
+ // the above newarray(t.Bucket, int(nbuckets))
+ // but may not be empty.
+ buckets = dirtyalloc
+ size := t.Bucket.Size_ * nbuckets
+ if t.Bucket.PtrBytes != 0 {
+ memclrHasPointers(buckets, size)
+ } else {
+ memclrNoHeapPointers(buckets, size)
+ }
+ }
+
+ if base != nbuckets {
+ // We preallocated some overflow buckets.
+ // To keep the overhead of tracking these overflow buckets to a minimum,
+ // we use the convention that if a preallocated overflow bucket's overflow
+ // pointer is nil, then there are more available by bumping the pointer.
+ // We need a safe non-nil pointer for the last overflow bucket; just use buckets.
+ nextOverflow = (*bmap)(add(buckets, base*uintptr(t.BucketSize)))
+ last := (*bmap)(add(buckets, (nbuckets-1)*uintptr(t.BucketSize)))
+ last.setoverflow(t, (*bmap)(buckets))
+ }
+ return buckets, nextOverflow
+}
+
+// mapaccess1 returns a pointer to h[key]. Never returns nil, instead
+// it will return a reference to the zero object for the elem type if
+// the key is not in the map.
+// NOTE: The returned pointer may keep the whole map live, so don't
+// hold onto it for very long.
+func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ pc := abi.FuncPCABIInternal(mapaccess1)
+ racereadpc(unsafe.Pointer(h), callerpc, pc)
+ raceReadObjectPC(t.Key, key, callerpc, pc)
+ }
+ if msanenabled && h != nil {
+ msanread(key, t.Key.Size_)
+ }
+ if asanenabled && h != nil {
+ asanread(key, t.Key.Size_)
+ }
+ if h == nil || h.count == 0 {
+ if t.HashMightPanic() {
+ t.Hasher(key, 0) // see issue 23734
+ }
+ return unsafe.Pointer(&zeroVal[0])
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map read and map write")
+ }
+ hash := t.Hasher(key, uintptr(h.hash0))
+ m := bucketMask(h.B)
+ b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.BucketSize)))
+ if c := h.oldbuckets; c != nil {
+ if !h.sameSizeGrow() {
+ // There used to be half as many buckets; mask down one more power of two.
+ m >>= 1
+ }
+ oldb := (*bmap)(add(c, (hash&m)*uintptr(t.BucketSize)))
+ if !evacuated(oldb) {
+ b = oldb
+ }
+ }
+ top := tophash(hash)
+bucketloop:
+ for ; b != nil; b = b.overflow(t) {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ if b.tophash[i] != top {
+ if b.tophash[i] == emptyRest {
+ break bucketloop
+ }
+ continue
+ }
+ k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.KeySize))
+ if t.IndirectKey() {
+ k = *((*unsafe.Pointer)(k))
+ }
+ if t.Key.Equal(key, k) {
+ e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.KeySize)+i*uintptr(t.ValueSize))
+ if t.IndirectElem() {
+ e = *((*unsafe.Pointer)(e))
+ }
+ return e
+ }
+ }
+ }
+ return unsafe.Pointer(&zeroVal[0])
+}
+
+func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ pc := abi.FuncPCABIInternal(mapaccess2)
+ racereadpc(unsafe.Pointer(h), callerpc, pc)
+ raceReadObjectPC(t.Key, key, callerpc, pc)
+ }
+ if msanenabled && h != nil {
+ msanread(key, t.Key.Size_)
+ }
+ if asanenabled && h != nil {
+ asanread(key, t.Key.Size_)
+ }
+ if h == nil || h.count == 0 {
+ if t.HashMightPanic() {
+ t.Hasher(key, 0) // see issue 23734
+ }
+ return unsafe.Pointer(&zeroVal[0]), false
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map read and map write")
+ }
+ hash := t.Hasher(key, uintptr(h.hash0))
+ m := bucketMask(h.B)
+ b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.BucketSize)))
+ if c := h.oldbuckets; c != nil {
+ if !h.sameSizeGrow() {
+ // There used to be half as many buckets; mask down one more power of two.
+ m >>= 1
+ }
+ oldb := (*bmap)(add(c, (hash&m)*uintptr(t.BucketSize)))
+ if !evacuated(oldb) {
+ b = oldb
+ }
+ }
+ top := tophash(hash)
+bucketloop:
+ for ; b != nil; b = b.overflow(t) {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ if b.tophash[i] != top {
+ if b.tophash[i] == emptyRest {
+ break bucketloop
+ }
+ continue
+ }
+ k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.KeySize))
+ if t.IndirectKey() {
+ k = *((*unsafe.Pointer)(k))
+ }
+ if t.Key.Equal(key, k) {
+ e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.KeySize)+i*uintptr(t.ValueSize))
+ if t.IndirectElem() {
+ e = *((*unsafe.Pointer)(e))
+ }
+ return e, true
+ }
+ }
+ }
+ return unsafe.Pointer(&zeroVal[0]), false
+}
+
+// returns both key and elem. Used by map iterator.
+func mapaccessK(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, unsafe.Pointer) {
+ if h == nil || h.count == 0 {
+ return nil, nil
+ }
+ hash := t.Hasher(key, uintptr(h.hash0))
+ m := bucketMask(h.B)
+ b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.BucketSize)))
+ if c := h.oldbuckets; c != nil {
+ if !h.sameSizeGrow() {
+ // There used to be half as many buckets; mask down one more power of two.
+ m >>= 1
+ }
+ oldb := (*bmap)(add(c, (hash&m)*uintptr(t.BucketSize)))
+ if !evacuated(oldb) {
+ b = oldb
+ }
+ }
+ top := tophash(hash)
+bucketloop:
+ for ; b != nil; b = b.overflow(t) {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ if b.tophash[i] != top {
+ if b.tophash[i] == emptyRest {
+ break bucketloop
+ }
+ continue
+ }
+ k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.KeySize))
+ if t.IndirectKey() {
+ k = *((*unsafe.Pointer)(k))
+ }
+ if t.Key.Equal(key, k) {
+ e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.KeySize)+i*uintptr(t.ValueSize))
+ if t.IndirectElem() {
+ e = *((*unsafe.Pointer)(e))
+ }
+ return k, e
+ }
+ }
+ }
+ return nil, nil
+}
+
+func mapaccess1_fat(t *maptype, h *hmap, key, zero unsafe.Pointer) unsafe.Pointer {
+ e := mapaccess1(t, h, key)
+ if e == unsafe.Pointer(&zeroVal[0]) {
+ return zero
+ }
+ return e
+}
+
+func mapaccess2_fat(t *maptype, h *hmap, key, zero unsafe.Pointer) (unsafe.Pointer, bool) {
+ e := mapaccess1(t, h, key)
+ if e == unsafe.Pointer(&zeroVal[0]) {
+ return zero, false
+ }
+ return e, true
+}
+
+// Like mapaccess, but allocates a slot for the key if it is not present in the map.
+func mapassign(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
+ if h == nil {
+ panic(plainError("assignment to entry in nil map"))
+ }
+ if raceenabled {
+ callerpc := getcallerpc()
+ pc := abi.FuncPCABIInternal(mapassign)
+ racewritepc(unsafe.Pointer(h), callerpc, pc)
+ raceReadObjectPC(t.Key, key, callerpc, pc)
+ }
+ if msanenabled {
+ msanread(key, t.Key.Size_)
+ }
+ if asanenabled {
+ asanread(key, t.Key.Size_)
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map writes")
+ }
+ hash := t.Hasher(key, uintptr(h.hash0))
+
+ // Set hashWriting after calling t.hasher, since t.hasher may panic,
+ // in which case we have not actually done a write.
+ h.flags ^= hashWriting
+
+ if h.buckets == nil {
+ h.buckets = newobject(t.Bucket) // newarray(t.Bucket, 1)
+ }
+
+again:
+ bucket := hash & bucketMask(h.B)
+ if h.growing() {
+ growWork(t, h, bucket)
+ }
+ b := (*bmap)(add(h.buckets, bucket*uintptr(t.BucketSize)))
+ top := tophash(hash)
+
+ var inserti *uint8
+ var insertk unsafe.Pointer
+ var elem unsafe.Pointer
+bucketloop:
+ for {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ if b.tophash[i] != top {
+ if isEmpty(b.tophash[i]) && inserti == nil {
+ inserti = &b.tophash[i]
+ insertk = add(unsafe.Pointer(b), dataOffset+i*uintptr(t.KeySize))
+ elem = add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.KeySize)+i*uintptr(t.ValueSize))
+ }
+ if b.tophash[i] == emptyRest {
+ break bucketloop
+ }
+ continue
+ }
+ k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.KeySize))
+ if t.IndirectKey() {
+ k = *((*unsafe.Pointer)(k))
+ }
+ if !t.Key.Equal(key, k) {
+ continue
+ }
+ // already have a mapping for key. Update it.
+ if t.NeedKeyUpdate() {
+ typedmemmove(t.Key, k, key)
+ }
+ elem = add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.KeySize)+i*uintptr(t.ValueSize))
+ goto done
+ }
+ ovf := b.overflow(t)
+ if ovf == nil {
+ break
+ }
+ b = ovf
+ }
+
+ // Did not find mapping for key. Allocate new cell & add entry.
+
+ // If we hit the max load factor or we have too many overflow buckets,
+ // and we're not already in the middle of growing, start growing.
+ if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+ hashGrow(t, h)
+ goto again // Growing the table invalidates everything, so try again
+ }
+
+ if inserti == nil {
+ // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
+ newb := h.newoverflow(t, b)
+ inserti = &newb.tophash[0]
+ insertk = add(unsafe.Pointer(newb), dataOffset)
+ elem = add(insertk, bucketCnt*uintptr(t.KeySize))
+ }
+
+ // store new key/elem at insert position
+ if t.IndirectKey() {
+ kmem := newobject(t.Key)
+ *(*unsafe.Pointer)(insertk) = kmem
+ insertk = kmem
+ }
+ if t.IndirectElem() {
+ vmem := newobject(t.Elem)
+ *(*unsafe.Pointer)(elem) = vmem
+ }
+ typedmemmove(t.Key, insertk, key)
+ *inserti = top
+ h.count++
+
+done:
+ if h.flags&hashWriting == 0 {
+ fatal("concurrent map writes")
+ }
+ h.flags &^= hashWriting
+ if t.IndirectElem() {
+ elem = *((*unsafe.Pointer)(elem))
+ }
+ return elem
+}
+
+func mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ pc := abi.FuncPCABIInternal(mapdelete)
+ racewritepc(unsafe.Pointer(h), callerpc, pc)
+ raceReadObjectPC(t.Key, key, callerpc, pc)
+ }
+ if msanenabled && h != nil {
+ msanread(key, t.Key.Size_)
+ }
+ if asanenabled && h != nil {
+ asanread(key, t.Key.Size_)
+ }
+ if h == nil || h.count == 0 {
+ if t.HashMightPanic() {
+ t.Hasher(key, 0) // see issue 23734
+ }
+ return
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map writes")
+ }
+
+ hash := t.Hasher(key, uintptr(h.hash0))
+
+ // Set hashWriting after calling t.hasher, since t.hasher may panic,
+ // in which case we have not actually done a write (delete).
+ h.flags ^= hashWriting
+
+ bucket := hash & bucketMask(h.B)
+ if h.growing() {
+ growWork(t, h, bucket)
+ }
+ b := (*bmap)(add(h.buckets, bucket*uintptr(t.BucketSize)))
+ bOrig := b
+ top := tophash(hash)
+search:
+ for ; b != nil; b = b.overflow(t) {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ if b.tophash[i] != top {
+ if b.tophash[i] == emptyRest {
+ break search
+ }
+ continue
+ }
+ k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.KeySize))
+ k2 := k
+ if t.IndirectKey() {
+ k2 = *((*unsafe.Pointer)(k2))
+ }
+ if !t.Key.Equal(key, k2) {
+ continue
+ }
+ // Only clear key if there are pointers in it.
+ if t.IndirectKey() {
+ *(*unsafe.Pointer)(k) = nil
+ } else if t.Key.PtrBytes != 0 {
+ memclrHasPointers(k, t.Key.Size_)
+ }
+ e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.KeySize)+i*uintptr(t.ValueSize))
+ if t.IndirectElem() {
+ *(*unsafe.Pointer)(e) = nil
+ } else if t.Elem.PtrBytes != 0 {
+ memclrHasPointers(e, t.Elem.Size_)
+ } else {
+ memclrNoHeapPointers(e, t.Elem.Size_)
+ }
+ b.tophash[i] = emptyOne
+ // If the bucket now ends in a bunch of emptyOne states,
+ // change those to emptyRest states.
+ // It would be nice to make this a separate function, but
+ // for loops are not currently inlineable.
+ if i == bucketCnt-1 {
+ if b.overflow(t) != nil && b.overflow(t).tophash[0] != emptyRest {
+ goto notLast
+ }
+ } else {
+ if b.tophash[i+1] != emptyRest {
+ goto notLast
+ }
+ }
+ for {
+ b.tophash[i] = emptyRest
+ if i == 0 {
+ if b == bOrig {
+ break // beginning of initial bucket, we're done.
+ }
+ // Find previous bucket, continue at its last entry.
+ c := b
+ for b = bOrig; b.overflow(t) != c; b = b.overflow(t) {
+ }
+ i = bucketCnt - 1
+ } else {
+ i--
+ }
+ if b.tophash[i] != emptyOne {
+ break
+ }
+ }
+ notLast:
+ h.count--
+ // Reset the hash seed to make it more difficult for attackers to
+ // repeatedly trigger hash collisions. See issue 25237.
+ if h.count == 0 {
+ h.hash0 = fastrand()
+ }
+ break search
+ }
+ }
+
+ if h.flags&hashWriting == 0 {
+ fatal("concurrent map writes")
+ }
+ h.flags &^= hashWriting
+}
+
+// mapiterinit initializes the hiter struct used for ranging over maps.
+// The hiter struct pointed to by 'it' is allocated on the stack
+// by the compilers order pass or on the heap by reflect_mapiterinit.
+// Both need to have zeroed hiter since the struct contains pointers.
+func mapiterinit(t *maptype, h *hmap, it *hiter) {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapiterinit))
+ }
+
+ it.t = t
+ if h == nil || h.count == 0 {
+ return
+ }
+
+ if unsafe.Sizeof(hiter{})/goarch.PtrSize != 12 {
+ throw("hash_iter size incorrect") // see cmd/compile/internal/reflectdata/reflect.go
+ }
+ it.h = h
+
+ // grab snapshot of bucket state
+ it.B = h.B
+ it.buckets = h.buckets
+ if t.Bucket.PtrBytes == 0 {
+ // Allocate the current slice and remember pointers to both current and old.
+ // This preserves all relevant overflow buckets alive even if
+ // the table grows and/or overflow buckets are added to the table
+ // while we are iterating.
+ h.createOverflow()
+ it.overflow = h.extra.overflow
+ it.oldoverflow = h.extra.oldoverflow
+ }
+
+ // decide where to start
+ var r uintptr
+ if h.B > 31-bucketCntBits {
+ r = uintptr(fastrand64())
+ } else {
+ r = uintptr(fastrand())
+ }
+ it.startBucket = r & bucketMask(h.B)
+ it.offset = uint8(r >> h.B & (bucketCnt - 1))
+
+ // iterator state
+ it.bucket = it.startBucket
+
+ // Remember we have an iterator.
+ // Can run concurrently with another mapiterinit().
+ if old := h.flags; old&(iterator|oldIterator) != iterator|oldIterator {
+ atomic.Or8(&h.flags, iterator|oldIterator)
+ }
+
+ mapiternext(it)
+}
+
+func mapiternext(it *hiter) {
+ h := it.h
+ if raceenabled {
+ callerpc := getcallerpc()
+ racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapiternext))
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map iteration and map write")
+ }
+ t := it.t
+ bucket := it.bucket
+ b := it.bptr
+ i := it.i
+ checkBucket := it.checkBucket
+
+next:
+ if b == nil {
+ if bucket == it.startBucket && it.wrapped {
+ // end of iteration
+ it.key = nil
+ it.elem = nil
+ return
+ }
+ if h.growing() && it.B == h.B {
+ // Iterator was started in the middle of a grow, and the grow isn't done yet.
+ // If the bucket we're looking at hasn't been filled in yet (i.e. the old
+ // bucket hasn't been evacuated) then we need to iterate through the old
+ // bucket and only return the ones that will be migrated to this bucket.
+ oldbucket := bucket & it.h.oldbucketmask()
+ b = (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.BucketSize)))
+ if !evacuated(b) {
+ checkBucket = bucket
+ } else {
+ b = (*bmap)(add(it.buckets, bucket*uintptr(t.BucketSize)))
+ checkBucket = noCheck
+ }
+ } else {
+ b = (*bmap)(add(it.buckets, bucket*uintptr(t.BucketSize)))
+ checkBucket = noCheck
+ }
+ bucket++
+ if bucket == bucketShift(it.B) {
+ bucket = 0
+ it.wrapped = true
+ }
+ i = 0
+ }
+ for ; i < bucketCnt; i++ {
+ offi := (i + it.offset) & (bucketCnt - 1)
+ if isEmpty(b.tophash[offi]) || b.tophash[offi] == evacuatedEmpty {
+ // TODO: emptyRest is hard to use here, as we start iterating
+ // in the middle of a bucket. It's feasible, just tricky.
+ continue
+ }
+ k := add(unsafe.Pointer(b), dataOffset+uintptr(offi)*uintptr(t.KeySize))
+ if t.IndirectKey() {
+ k = *((*unsafe.Pointer)(k))
+ }
+ e := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.KeySize)+uintptr(offi)*uintptr(t.ValueSize))
+ if checkBucket != noCheck && !h.sameSizeGrow() {
+ // Special case: iterator was started during a grow to a larger size
+ // and the grow is not done yet. We're working on a bucket whose
+ // oldbucket has not been evacuated yet. Or at least, it wasn't
+ // evacuated when we started the bucket. So we're iterating
+ // through the oldbucket, skipping any keys that will go
+ // to the other new bucket (each oldbucket expands to two
+ // buckets during a grow).
+ if t.ReflexiveKey() || t.Key.Equal(k, k) {
+ // If the item in the oldbucket is not destined for
+ // the current new bucket in the iteration, skip it.
+ hash := t.Hasher(k, uintptr(h.hash0))
+ if hash&bucketMask(it.B) != checkBucket {
+ continue
+ }
+ } else {
+ // Hash isn't repeatable if k != k (NaNs). We need a
+ // repeatable and randomish choice of which direction
+ // to send NaNs during evacuation. We'll use the low
+ // bit of tophash to decide which way NaNs go.
+ // NOTE: this case is why we need two evacuate tophash
+ // values, evacuatedX and evacuatedY, that differ in
+ // their low bit.
+ if checkBucket>>(it.B-1) != uintptr(b.tophash[offi]&1) {
+ continue
+ }
+ }
+ }
+ if (b.tophash[offi] != evacuatedX && b.tophash[offi] != evacuatedY) ||
+ !(t.ReflexiveKey() || t.Key.Equal(k, k)) {
+ // This is the golden data, we can return it.
+ // OR
+ // key!=key, so the entry can't be deleted or updated, so we can just return it.
+ // That's lucky for us because when key!=key we can't look it up successfully.
+ it.key = k
+ if t.IndirectElem() {
+ e = *((*unsafe.Pointer)(e))
+ }
+ it.elem = e
+ } else {
+ // The hash table has grown since the iterator was started.
+ // The golden data for this key is now somewhere else.
+ // Check the current hash table for the data.
+ // This code handles the case where the key
+ // has been deleted, updated, or deleted and reinserted.
+ // NOTE: we need to regrab the key as it has potentially been
+ // updated to an equal() but not identical key (e.g. +0.0 vs -0.0).
+ rk, re := mapaccessK(t, h, k)
+ if rk == nil {
+ continue // key has been deleted
+ }
+ it.key = rk
+ it.elem = re
+ }
+ it.bucket = bucket
+ if it.bptr != b { // avoid unnecessary write barrier; see issue 14921
+ it.bptr = b
+ }
+ it.i = i + 1
+ it.checkBucket = checkBucket
+ return
+ }
+ b = b.overflow(t)
+ i = 0
+ goto next
+}
+
+// mapclear deletes all keys from a map.
+func mapclear(t *maptype, h *hmap) {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ pc := abi.FuncPCABIInternal(mapclear)
+ racewritepc(unsafe.Pointer(h), callerpc, pc)
+ }
+
+ if h == nil || h.count == 0 {
+ return
+ }
+
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map writes")
+ }
+
+ h.flags ^= hashWriting
+
+ // Mark buckets empty, so existing iterators can be terminated, see issue #59411.
+ markBucketsEmpty := func(bucket unsafe.Pointer, mask uintptr) {
+ for i := uintptr(0); i <= mask; i++ {
+ b := (*bmap)(add(bucket, i*uintptr(t.BucketSize)))
+ for ; b != nil; b = b.overflow(t) {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ b.tophash[i] = emptyRest
+ }
+ }
+ }
+ }
+ markBucketsEmpty(h.buckets, bucketMask(h.B))
+ if oldBuckets := h.oldbuckets; oldBuckets != nil {
+ markBucketsEmpty(oldBuckets, h.oldbucketmask())
+ }
+
+ h.flags &^= sameSizeGrow
+ h.oldbuckets = nil
+ h.nevacuate = 0
+ h.noverflow = 0
+ h.count = 0
+
+ // Reset the hash seed to make it more difficult for attackers to
+ // repeatedly trigger hash collisions. See issue 25237.
+ h.hash0 = fastrand()
+
+ // Keep the mapextra allocation but clear any extra information.
+ if h.extra != nil {
+ *h.extra = mapextra{}
+ }
+
+ // makeBucketArray clears the memory pointed to by h.buckets
+ // and recovers any overflow buckets by generating them
+ // as if h.buckets was newly alloced.
+ _, nextOverflow := makeBucketArray(t, h.B, h.buckets)
+ if nextOverflow != nil {
+ // If overflow buckets are created then h.extra
+ // will have been allocated during initial bucket creation.
+ h.extra.nextOverflow = nextOverflow
+ }
+
+ if h.flags&hashWriting == 0 {
+ fatal("concurrent map writes")
+ }
+ h.flags &^= hashWriting
+}
+
+func hashGrow(t *maptype, h *hmap) {
+ // If we've hit the load factor, get bigger.
+ // Otherwise, there are too many overflow buckets,
+ // so keep the same number of buckets and "grow" laterally.
+ bigger := uint8(1)
+ if !overLoadFactor(h.count+1, h.B) {
+ bigger = 0
+ h.flags |= sameSizeGrow
+ }
+ oldbuckets := h.buckets
+ newbuckets, nextOverflow := makeBucketArray(t, h.B+bigger, nil)
+
+ flags := h.flags &^ (iterator | oldIterator)
+ if h.flags&iterator != 0 {
+ flags |= oldIterator
+ }
+ // commit the grow (atomic wrt gc)
+ h.B += bigger
+ h.flags = flags
+ h.oldbuckets = oldbuckets
+ h.buckets = newbuckets
+ h.nevacuate = 0
+ h.noverflow = 0
+
+ if h.extra != nil && h.extra.overflow != nil {
+ // Promote current overflow buckets to the old generation.
+ if h.extra.oldoverflow != nil {
+ throw("oldoverflow is not nil")
+ }
+ h.extra.oldoverflow = h.extra.overflow
+ h.extra.overflow = nil
+ }
+ if nextOverflow != nil {
+ if h.extra == nil {
+ h.extra = new(mapextra)
+ }
+ h.extra.nextOverflow = nextOverflow
+ }
+
+ // the actual copying of the hash table data is done incrementally
+ // by growWork() and evacuate().
+}
+
+// overLoadFactor reports whether count items placed in 1<<B buckets is over loadFactor.
+func overLoadFactor(count int, B uint8) bool {
+ return count > bucketCnt && uintptr(count) > loadFactorNum*(bucketShift(B)/loadFactorDen)
+}
+
+// tooManyOverflowBuckets reports whether noverflow buckets is too many for a map with 1<<B buckets.
+// Note that most of these overflow buckets must be in sparse use;
+// if use was dense, then we'd have already triggered regular map growth.
+func tooManyOverflowBuckets(noverflow uint16, B uint8) bool {
+ // If the threshold is too low, we do extraneous work.
+ // If the threshold is too high, maps that grow and shrink can hold on to lots of unused memory.
+ // "too many" means (approximately) as many overflow buckets as regular buckets.
+ // See incrnoverflow for more details.
+ if B > 15 {
+ B = 15
+ }
+ // The compiler doesn't see here that B < 16; mask B to generate shorter shift code.
+ return noverflow >= uint16(1)<<(B&15)
+}
+
+// growing reports whether h is growing. The growth may be to the same size or bigger.
+func (h *hmap) growing() bool {
+ return h.oldbuckets != nil
+}
+
+// sameSizeGrow reports whether the current growth is to a map of the same size.
+func (h *hmap) sameSizeGrow() bool {
+ return h.flags&sameSizeGrow != 0
+}
+
+// noldbuckets calculates the number of buckets prior to the current map growth.
+func (h *hmap) noldbuckets() uintptr {
+ oldB := h.B
+ if !h.sameSizeGrow() {
+ oldB--
+ }
+ return bucketShift(oldB)
+}
+
+// oldbucketmask provides a mask that can be applied to calculate n % noldbuckets().
+func (h *hmap) oldbucketmask() uintptr {
+ return h.noldbuckets() - 1
+}
+
+func growWork(t *maptype, h *hmap, bucket uintptr) {
+ // make sure we evacuate the oldbucket corresponding
+ // to the bucket we're about to use
+ evacuate(t, h, bucket&h.oldbucketmask())
+
+ // evacuate one more oldbucket to make progress on growing
+ if h.growing() {
+ evacuate(t, h, h.nevacuate)
+ }
+}
+
+func bucketEvacuated(t *maptype, h *hmap, bucket uintptr) bool {
+ b := (*bmap)(add(h.oldbuckets, bucket*uintptr(t.BucketSize)))
+ return evacuated(b)
+}
+
+// evacDst is an evacuation destination.
+type evacDst struct {
+ b *bmap // current destination bucket
+ i int // key/elem index into b
+ k unsafe.Pointer // pointer to current key storage
+ e unsafe.Pointer // pointer to current elem storage
+}
+
+func evacuate(t *maptype, h *hmap, oldbucket uintptr) {
+ b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.BucketSize)))
+ newbit := h.noldbuckets()
+ if !evacuated(b) {
+ // TODO: reuse overflow buckets instead of using new ones, if there
+ // is no iterator using the old buckets. (If !oldIterator.)
+
+ // xy contains the x and y (low and high) evacuation destinations.
+ var xy [2]evacDst
+ x := &xy[0]
+ x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.BucketSize)))
+ x.k = add(unsafe.Pointer(x.b), dataOffset)
+ x.e = add(x.k, bucketCnt*uintptr(t.KeySize))
+
+ if !h.sameSizeGrow() {
+ // Only calculate y pointers if we're growing bigger.
+ // Otherwise GC can see bad pointers.
+ y := &xy[1]
+ y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.BucketSize)))
+ y.k = add(unsafe.Pointer(y.b), dataOffset)
+ y.e = add(y.k, bucketCnt*uintptr(t.KeySize))
+ }
+
+ for ; b != nil; b = b.overflow(t) {
+ k := add(unsafe.Pointer(b), dataOffset)
+ e := add(k, bucketCnt*uintptr(t.KeySize))
+ for i := 0; i < bucketCnt; i, k, e = i+1, add(k, uintptr(t.KeySize)), add(e, uintptr(t.ValueSize)) {
+ top := b.tophash[i]
+ if isEmpty(top) {
+ b.tophash[i] = evacuatedEmpty
+ continue
+ }
+ if top < minTopHash {
+ throw("bad map state")
+ }
+ k2 := k
+ if t.IndirectKey() {
+ k2 = *((*unsafe.Pointer)(k2))
+ }
+ var useY uint8
+ if !h.sameSizeGrow() {
+ // Compute hash to make our evacuation decision (whether we need
+ // to send this key/elem to bucket x or bucket y).
+ hash := t.Hasher(k2, uintptr(h.hash0))
+ if h.flags&iterator != 0 && !t.ReflexiveKey() && !t.Key.Equal(k2, k2) {
+ // If key != key (NaNs), then the hash could be (and probably
+ // will be) entirely different from the old hash. Moreover,
+ // it isn't reproducible. Reproducibility is required in the
+ // presence of iterators, as our evacuation decision must
+ // match whatever decision the iterator made.
+ // Fortunately, we have the freedom to send these keys either
+ // way. Also, tophash is meaningless for these kinds of keys.
+ // We let the low bit of tophash drive the evacuation decision.
+ // We recompute a new random tophash for the next level so
+ // these keys will get evenly distributed across all buckets
+ // after multiple grows.
+ useY = top & 1
+ top = tophash(hash)
+ } else {
+ if hash&newbit != 0 {
+ useY = 1
+ }
+ }
+ }
+
+ if evacuatedX+1 != evacuatedY || evacuatedX^1 != evacuatedY {
+ throw("bad evacuatedN")
+ }
+
+ b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY
+ dst := &xy[useY] // evacuation destination
+
+ if dst.i == bucketCnt {
+ dst.b = h.newoverflow(t, dst.b)
+ dst.i = 0
+ dst.k = add(unsafe.Pointer(dst.b), dataOffset)
+ dst.e = add(dst.k, bucketCnt*uintptr(t.KeySize))
+ }
+ dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
+ if t.IndirectKey() {
+ *(*unsafe.Pointer)(dst.k) = k2 // copy pointer
+ } else {
+ typedmemmove(t.Key, dst.k, k) // copy elem
+ }
+ if t.IndirectElem() {
+ *(*unsafe.Pointer)(dst.e) = *(*unsafe.Pointer)(e)
+ } else {
+ typedmemmove(t.Elem, dst.e, e)
+ }
+ dst.i++
+ // These updates might push these pointers past the end of the
+ // key or elem arrays. That's ok, as we have the overflow pointer
+ // at the end of the bucket to protect against pointing past the
+ // end of the bucket.
+ dst.k = add(dst.k, uintptr(t.KeySize))
+ dst.e = add(dst.e, uintptr(t.ValueSize))
+ }
+ }
+ // Unlink the overflow buckets & clear key/elem to help GC.
+ if h.flags&oldIterator == 0 && t.Bucket.PtrBytes != 0 {
+ b := add(h.oldbuckets, oldbucket*uintptr(t.BucketSize))
+ // Preserve b.tophash because the evacuation
+ // state is maintained there.
+ ptr := add(b, dataOffset)
+ n := uintptr(t.BucketSize) - dataOffset
+ memclrHasPointers(ptr, n)
+ }
+ }
+
+ if oldbucket == h.nevacuate {
+ advanceEvacuationMark(h, t, newbit)
+ }
+}
+
+func advanceEvacuationMark(h *hmap, t *maptype, newbit uintptr) {
+ h.nevacuate++
+ // Experiments suggest that 1024 is overkill by at least an order of magnitude.
+ // Put it in there as a safeguard anyway, to ensure O(1) behavior.
+ stop := h.nevacuate + 1024
+ if stop > newbit {
+ stop = newbit
+ }
+ for h.nevacuate != stop && bucketEvacuated(t, h, h.nevacuate) {
+ h.nevacuate++
+ }
+ if h.nevacuate == newbit { // newbit == # of oldbuckets
+ // Growing is all done. Free old main bucket array.
+ h.oldbuckets = nil
+ // Can discard old overflow buckets as well.
+ // If they are still referenced by an iterator,
+ // then the iterator holds a pointers to the slice.
+ if h.extra != nil {
+ h.extra.oldoverflow = nil
+ }
+ h.flags &^= sameSizeGrow
+ }
+}
+
+// Reflect stubs. Called from ../reflect/asm_*.s
+
+//go:linkname reflect_makemap reflect.makemap
+func reflect_makemap(t *maptype, cap int) *hmap {
+ // Check invariants and reflects math.
+ if t.Key.Equal == nil {
+ throw("runtime.reflect_makemap: unsupported map key type")
+ }
+ if t.Key.Size_ > maxKeySize && (!t.IndirectKey() || t.KeySize != uint8(goarch.PtrSize)) ||
+ t.Key.Size_ <= maxKeySize && (t.IndirectKey() || t.KeySize != uint8(t.Key.Size_)) {
+ throw("key size wrong")
+ }
+ if t.Elem.Size_ > maxElemSize && (!t.IndirectElem() || t.ValueSize != uint8(goarch.PtrSize)) ||
+ t.Elem.Size_ <= maxElemSize && (t.IndirectElem() || t.ValueSize != uint8(t.Elem.Size_)) {
+ throw("elem size wrong")
+ }
+ if t.Key.Align_ > bucketCnt {
+ throw("key align too big")
+ }
+ if t.Elem.Align_ > bucketCnt {
+ throw("elem align too big")
+ }
+ if t.Key.Size_%uintptr(t.Key.Align_) != 0 {
+ throw("key size not a multiple of key align")
+ }
+ if t.Elem.Size_%uintptr(t.Elem.Align_) != 0 {
+ throw("elem size not a multiple of elem align")
+ }
+ if bucketCnt < 8 {
+ throw("bucketsize too small for proper alignment")
+ }
+ if dataOffset%uintptr(t.Key.Align_) != 0 {
+ throw("need padding in bucket (key)")
+ }
+ if dataOffset%uintptr(t.Elem.Align_) != 0 {
+ throw("need padding in bucket (elem)")
+ }
+
+ return makemap(t, cap, nil)
+}
+
+//go:linkname reflect_mapaccess reflect.mapaccess
+func reflect_mapaccess(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
+ elem, ok := mapaccess2(t, h, key)
+ if !ok {
+ // reflect wants nil for a missing element
+ elem = nil
+ }
+ return elem
+}
+
+//go:linkname reflect_mapaccess_faststr reflect.mapaccess_faststr
+func reflect_mapaccess_faststr(t *maptype, h *hmap, key string) unsafe.Pointer {
+ elem, ok := mapaccess2_faststr(t, h, key)
+ if !ok {
+ // reflect wants nil for a missing element
+ elem = nil
+ }
+ return elem
+}
+
+//go:linkname reflect_mapassign reflect.mapassign0
+func reflect_mapassign(t *maptype, h *hmap, key unsafe.Pointer, elem unsafe.Pointer) {
+ p := mapassign(t, h, key)
+ typedmemmove(t.Elem, p, elem)
+}
+
+//go:linkname reflect_mapassign_faststr reflect.mapassign_faststr0
+func reflect_mapassign_faststr(t *maptype, h *hmap, key string, elem unsafe.Pointer) {
+ p := mapassign_faststr(t, h, key)
+ typedmemmove(t.Elem, p, elem)
+}
+
+//go:linkname reflect_mapdelete reflect.mapdelete
+func reflect_mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
+ mapdelete(t, h, key)
+}
+
+//go:linkname reflect_mapdelete_faststr reflect.mapdelete_faststr
+func reflect_mapdelete_faststr(t *maptype, h *hmap, key string) {
+ mapdelete_faststr(t, h, key)
+}
+
+//go:linkname reflect_mapiterinit reflect.mapiterinit
+func reflect_mapiterinit(t *maptype, h *hmap, it *hiter) {
+ mapiterinit(t, h, it)
+}
+
+//go:linkname reflect_mapiternext reflect.mapiternext
+func reflect_mapiternext(it *hiter) {
+ mapiternext(it)
+}
+
+//go:linkname reflect_mapiterkey reflect.mapiterkey
+func reflect_mapiterkey(it *hiter) unsafe.Pointer {
+ return it.key
+}
+
+//go:linkname reflect_mapiterelem reflect.mapiterelem
+func reflect_mapiterelem(it *hiter) unsafe.Pointer {
+ return it.elem
+}
+
+//go:linkname reflect_maplen reflect.maplen
+func reflect_maplen(h *hmap) int {
+ if h == nil {
+ return 0
+ }
+ if raceenabled {
+ callerpc := getcallerpc()
+ racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(reflect_maplen))
+ }
+ return h.count
+}
+
+//go:linkname reflect_mapclear reflect.mapclear
+func reflect_mapclear(t *maptype, h *hmap) {
+ mapclear(t, h)
+}
+
+//go:linkname reflectlite_maplen internal/reflectlite.maplen
+func reflectlite_maplen(h *hmap) int {
+ if h == nil {
+ return 0
+ }
+ if raceenabled {
+ callerpc := getcallerpc()
+ racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(reflect_maplen))
+ }
+ return h.count
+}
+
+const maxZero = 1024 // must match value in reflect/value.go:maxZero cmd/compile/internal/gc/walk.go:zeroValSize
+var zeroVal [maxZero]byte
+
+// mapinitnoop is a no-op function known the Go linker; if a given global
+// map (of the right size) is determined to be dead, the linker will
+// rewrite the relocation (from the package init func) from the outlined
+// map init function to this symbol. Defined in assembly so as to avoid
+// complications with instrumentation (coverage, etc).
+func mapinitnoop()
+
+// mapclone for implementing maps.Clone
+//
+//go:linkname mapclone maps.clone
+func mapclone(m any) any {
+ e := efaceOf(&m)
+ e.data = unsafe.Pointer(mapclone2((*maptype)(unsafe.Pointer(e._type)), (*hmap)(e.data)))
+ return m
+}
+
+// moveToBmap moves a bucket from src to dst. It returns the destination bucket or new destination bucket if it overflows
+// and the pos that the next key/value will be written, if pos == bucketCnt means needs to written in overflow bucket.
+func moveToBmap(t *maptype, h *hmap, dst *bmap, pos int, src *bmap) (*bmap, int) {
+ for i := 0; i < bucketCnt; i++ {
+ if isEmpty(src.tophash[i]) {
+ continue
+ }
+
+ for ; pos < bucketCnt; pos++ {
+ if isEmpty(dst.tophash[pos]) {
+ break
+ }
+ }
+
+ if pos == bucketCnt {
+ dst = h.newoverflow(t, dst)
+ pos = 0
+ }
+
+ srcK := add(unsafe.Pointer(src), dataOffset+uintptr(i)*uintptr(t.KeySize))
+ srcEle := add(unsafe.Pointer(src), dataOffset+bucketCnt*uintptr(t.KeySize)+uintptr(i)*uintptr(t.ValueSize))
+ dstK := add(unsafe.Pointer(dst), dataOffset+uintptr(pos)*uintptr(t.KeySize))
+ dstEle := add(unsafe.Pointer(dst), dataOffset+bucketCnt*uintptr(t.KeySize)+uintptr(pos)*uintptr(t.ValueSize))
+
+ dst.tophash[pos] = src.tophash[i]
+ if t.IndirectKey() {
+ *(*unsafe.Pointer)(dstK) = *(*unsafe.Pointer)(srcK)
+ } else {
+ typedmemmove(t.Key, dstK, srcK)
+ }
+ if t.IndirectElem() {
+ *(*unsafe.Pointer)(dstEle) = *(*unsafe.Pointer)(srcEle)
+ } else {
+ typedmemmove(t.Elem, dstEle, srcEle)
+ }
+ pos++
+ h.count++
+ }
+ return dst, pos
+}
+
+func mapclone2(t *maptype, src *hmap) *hmap {
+ dst := makemap(t, src.count, nil)
+ dst.hash0 = src.hash0
+ dst.nevacuate = 0
+ //flags do not need to be copied here, just like a new map has no flags.
+
+ if src.count == 0 {
+ return dst
+ }
+
+ if src.flags&hashWriting != 0 {
+ fatal("concurrent map clone and map write")
+ }
+
+ if src.B == 0 {
+ dst.buckets = newobject(t.Bucket)
+ dst.count = src.count
+ typedmemmove(t.Bucket, dst.buckets, src.buckets)
+ return dst
+ }
+
+ //src.B != 0
+ if dst.B == 0 {
+ dst.buckets = newobject(t.Bucket)
+ }
+ dstArraySize := int(bucketShift(dst.B))
+ srcArraySize := int(bucketShift(src.B))
+ for i := 0; i < dstArraySize; i++ {
+ dstBmap := (*bmap)(add(dst.buckets, uintptr(i*int(t.BucketSize))))
+ pos := 0
+ for j := 0; j < srcArraySize; j += dstArraySize {
+ srcBmap := (*bmap)(add(src.buckets, uintptr((i+j)*int(t.BucketSize))))
+ for srcBmap != nil {
+ dstBmap, pos = moveToBmap(t, dst, dstBmap, pos, srcBmap)
+ srcBmap = srcBmap.overflow(t)
+ }
+ }
+ }
+
+ if src.oldbuckets == nil {
+ return dst
+ }
+
+ oldB := src.B
+ srcOldbuckets := src.oldbuckets
+ if !src.sameSizeGrow() {
+ oldB--
+ }
+ oldSrcArraySize := int(bucketShift(oldB))
+
+ for i := 0; i < oldSrcArraySize; i++ {
+ srcBmap := (*bmap)(add(srcOldbuckets, uintptr(i*int(t.BucketSize))))
+ if evacuated(srcBmap) {
+ continue
+ }
+
+ if oldB >= dst.B { // main bucket bits in dst is less than oldB bits in src
+ dstBmap := (*bmap)(add(dst.buckets, (uintptr(i)&bucketMask(dst.B))*uintptr(t.BucketSize)))
+ for dstBmap.overflow(t) != nil {
+ dstBmap = dstBmap.overflow(t)
+ }
+ pos := 0
+ for srcBmap != nil {
+ dstBmap, pos = moveToBmap(t, dst, dstBmap, pos, srcBmap)
+ srcBmap = srcBmap.overflow(t)
+ }
+ continue
+ }
+
+ for srcBmap != nil {
+ // move from oldBlucket to new bucket
+ for i := uintptr(0); i < bucketCnt; i++ {
+ if isEmpty(srcBmap.tophash[i]) {
+ continue
+ }
+
+ if src.flags&hashWriting != 0 {
+ fatal("concurrent map clone and map write")
+ }
+
+ srcK := add(unsafe.Pointer(srcBmap), dataOffset+i*uintptr(t.KeySize))
+ if t.IndirectKey() {
+ srcK = *((*unsafe.Pointer)(srcK))
+ }
+
+ srcEle := add(unsafe.Pointer(srcBmap), dataOffset+bucketCnt*uintptr(t.KeySize)+i*uintptr(t.ValueSize))
+ if t.IndirectElem() {
+ srcEle = *((*unsafe.Pointer)(srcEle))
+ }
+ dstEle := mapassign(t, dst, srcK)
+ typedmemmove(t.Elem, dstEle, srcEle)
+ }
+ srcBmap = srcBmap.overflow(t)
+ }
+ }
+ return dst
+}
+
+// keys for implementing maps.keys
+//
+//go:linkname keys maps.keys
+func keys(m any, p unsafe.Pointer) {
+ e := efaceOf(&m)
+ t := (*maptype)(unsafe.Pointer(e._type))
+ h := (*hmap)(e.data)
+
+ if h == nil || h.count == 0 {
+ return
+ }
+ s := (*slice)(p)
+ r := int(fastrand())
+ offset := uint8(r >> h.B & (bucketCnt - 1))
+ if h.B == 0 {
+ copyKeys(t, h, (*bmap)(h.buckets), s, offset)
+ return
+ }
+ arraySize := int(bucketShift(h.B))
+ buckets := h.buckets
+ for i := 0; i < arraySize; i++ {
+ bucket := (i + r) & (arraySize - 1)
+ b := (*bmap)(add(buckets, uintptr(bucket)*uintptr(t.BucketSize)))
+ copyKeys(t, h, b, s, offset)
+ }
+
+ if h.growing() {
+ oldArraySize := int(h.noldbuckets())
+ for i := 0; i < oldArraySize; i++ {
+ bucket := (i + r) & (oldArraySize - 1)
+ b := (*bmap)(add(h.oldbuckets, uintptr(bucket)*uintptr(t.BucketSize)))
+ if evacuated(b) {
+ continue
+ }
+ copyKeys(t, h, b, s, offset)
+ }
+ }
+ return
+}
+
+func copyKeys(t *maptype, h *hmap, b *bmap, s *slice, offset uint8) {
+ for b != nil {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ offi := (i + uintptr(offset)) & (bucketCnt - 1)
+ if isEmpty(b.tophash[offi]) {
+ continue
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map read and map write")
+ }
+ k := add(unsafe.Pointer(b), dataOffset+offi*uintptr(t.KeySize))
+ if t.IndirectKey() {
+ k = *((*unsafe.Pointer)(k))
+ }
+ if s.len >= s.cap {
+ fatal("concurrent map read and map write")
+ }
+ typedmemmove(t.Key, add(s.array, uintptr(s.len)*uintptr(t.KeySize)), k)
+ s.len++
+ }
+ b = b.overflow(t)
+ }
+}
+
+// values for implementing maps.values
+//
+//go:linkname values maps.values
+func values(m any, p unsafe.Pointer) {
+ e := efaceOf(&m)
+ t := (*maptype)(unsafe.Pointer(e._type))
+ h := (*hmap)(e.data)
+ if h == nil || h.count == 0 {
+ return
+ }
+ s := (*slice)(p)
+ r := int(fastrand())
+ offset := uint8(r >> h.B & (bucketCnt - 1))
+ if h.B == 0 {
+ copyValues(t, h, (*bmap)(h.buckets), s, offset)
+ return
+ }
+ arraySize := int(bucketShift(h.B))
+ buckets := h.buckets
+ for i := 0; i < arraySize; i++ {
+ bucket := (i + r) & (arraySize - 1)
+ b := (*bmap)(add(buckets, uintptr(bucket)*uintptr(t.BucketSize)))
+ copyValues(t, h, b, s, offset)
+ }
+
+ if h.growing() {
+ oldArraySize := int(h.noldbuckets())
+ for i := 0; i < oldArraySize; i++ {
+ bucket := (i + r) & (oldArraySize - 1)
+ b := (*bmap)(add(h.oldbuckets, uintptr(bucket)*uintptr(t.BucketSize)))
+ if evacuated(b) {
+ continue
+ }
+ copyValues(t, h, b, s, offset)
+ }
+ }
+ return
+}
+
+func copyValues(t *maptype, h *hmap, b *bmap, s *slice, offset uint8) {
+ for b != nil {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ offi := (i + uintptr(offset)) & (bucketCnt - 1)
+ if isEmpty(b.tophash[offi]) {
+ continue
+ }
+
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map read and map write")
+ }
+
+ ele := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.KeySize)+offi*uintptr(t.ValueSize))
+ if t.IndirectElem() {
+ ele = *((*unsafe.Pointer)(ele))
+ }
+ if s.len >= s.cap {
+ fatal("concurrent map read and map write")
+ }
+ typedmemmove(t.Elem, add(s.array, uintptr(s.len)*uintptr(t.ValueSize)), ele)
+ s.len++
+ }
+ b = b.overflow(t)
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/map_fast32.go b/contrib/go/_std_1.21/src/runtime/map_fast32.go
new file mode 100644
index 0000000000..d10dca3e91
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/map_fast32.go
@@ -0,0 +1,462 @@
+// Copyright 2018 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "unsafe"
+)
+
+func mapaccess1_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess1_fast32))
+ }
+ if h == nil || h.count == 0 {
+ return unsafe.Pointer(&zeroVal[0])
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map read and map write")
+ }
+ var b *bmap
+ if h.B == 0 {
+ // One-bucket table. No need to hash.
+ b = (*bmap)(h.buckets)
+ } else {
+ hash := t.Hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
+ m := bucketMask(h.B)
+ b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.BucketSize)))
+ if c := h.oldbuckets; c != nil {
+ if !h.sameSizeGrow() {
+ // There used to be half as many buckets; mask down one more power of two.
+ m >>= 1
+ }
+ oldb := (*bmap)(add(c, (hash&m)*uintptr(t.BucketSize)))
+ if !evacuated(oldb) {
+ b = oldb
+ }
+ }
+ }
+ for ; b != nil; b = b.overflow(t) {
+ for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 4) {
+ if *(*uint32)(k) == key && !isEmpty(b.tophash[i]) {
+ return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.ValueSize))
+ }
+ }
+ }
+ return unsafe.Pointer(&zeroVal[0])
+}
+
+func mapaccess2_fast32(t *maptype, h *hmap, key uint32) (unsafe.Pointer, bool) {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess2_fast32))
+ }
+ if h == nil || h.count == 0 {
+ return unsafe.Pointer(&zeroVal[0]), false
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map read and map write")
+ }
+ var b *bmap
+ if h.B == 0 {
+ // One-bucket table. No need to hash.
+ b = (*bmap)(h.buckets)
+ } else {
+ hash := t.Hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
+ m := bucketMask(h.B)
+ b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.BucketSize)))
+ if c := h.oldbuckets; c != nil {
+ if !h.sameSizeGrow() {
+ // There used to be half as many buckets; mask down one more power of two.
+ m >>= 1
+ }
+ oldb := (*bmap)(add(c, (hash&m)*uintptr(t.BucketSize)))
+ if !evacuated(oldb) {
+ b = oldb
+ }
+ }
+ }
+ for ; b != nil; b = b.overflow(t) {
+ for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 4) {
+ if *(*uint32)(k) == key && !isEmpty(b.tophash[i]) {
+ return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.ValueSize)), true
+ }
+ }
+ }
+ return unsafe.Pointer(&zeroVal[0]), false
+}
+
+func mapassign_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer {
+ if h == nil {
+ panic(plainError("assignment to entry in nil map"))
+ }
+ if raceenabled {
+ callerpc := getcallerpc()
+ racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapassign_fast32))
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map writes")
+ }
+ hash := t.Hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
+
+ // Set hashWriting after calling t.hasher for consistency with mapassign.
+ h.flags ^= hashWriting
+
+ if h.buckets == nil {
+ h.buckets = newobject(t.Bucket) // newarray(t.bucket, 1)
+ }
+
+again:
+ bucket := hash & bucketMask(h.B)
+ if h.growing() {
+ growWork_fast32(t, h, bucket)
+ }
+ b := (*bmap)(add(h.buckets, bucket*uintptr(t.BucketSize)))
+
+ var insertb *bmap
+ var inserti uintptr
+ var insertk unsafe.Pointer
+
+bucketloop:
+ for {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ if isEmpty(b.tophash[i]) {
+ if insertb == nil {
+ inserti = i
+ insertb = b
+ }
+ if b.tophash[i] == emptyRest {
+ break bucketloop
+ }
+ continue
+ }
+ k := *((*uint32)(add(unsafe.Pointer(b), dataOffset+i*4)))
+ if k != key {
+ continue
+ }
+ inserti = i
+ insertb = b
+ goto done
+ }
+ ovf := b.overflow(t)
+ if ovf == nil {
+ break
+ }
+ b = ovf
+ }
+
+ // Did not find mapping for key. Allocate new cell & add entry.
+
+ // If we hit the max load factor or we have too many overflow buckets,
+ // and we're not already in the middle of growing, start growing.
+ if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+ hashGrow(t, h)
+ goto again // Growing the table invalidates everything, so try again
+ }
+
+ if insertb == nil {
+ // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
+ insertb = h.newoverflow(t, b)
+ inserti = 0 // not necessary, but avoids needlessly spilling inserti
+ }
+ insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks
+
+ insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*4)
+ // store new key at insert position
+ *(*uint32)(insertk) = key
+
+ h.count++
+
+done:
+ elem := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*4+inserti*uintptr(t.ValueSize))
+ if h.flags&hashWriting == 0 {
+ fatal("concurrent map writes")
+ }
+ h.flags &^= hashWriting
+ return elem
+}
+
+func mapassign_fast32ptr(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
+ if h == nil {
+ panic(plainError("assignment to entry in nil map"))
+ }
+ if raceenabled {
+ callerpc := getcallerpc()
+ racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapassign_fast32))
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map writes")
+ }
+ hash := t.Hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
+
+ // Set hashWriting after calling t.hasher for consistency with mapassign.
+ h.flags ^= hashWriting
+
+ if h.buckets == nil {
+ h.buckets = newobject(t.Bucket) // newarray(t.bucket, 1)
+ }
+
+again:
+ bucket := hash & bucketMask(h.B)
+ if h.growing() {
+ growWork_fast32(t, h, bucket)
+ }
+ b := (*bmap)(add(h.buckets, bucket*uintptr(t.BucketSize)))
+
+ var insertb *bmap
+ var inserti uintptr
+ var insertk unsafe.Pointer
+
+bucketloop:
+ for {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ if isEmpty(b.tophash[i]) {
+ if insertb == nil {
+ inserti = i
+ insertb = b
+ }
+ if b.tophash[i] == emptyRest {
+ break bucketloop
+ }
+ continue
+ }
+ k := *((*unsafe.Pointer)(add(unsafe.Pointer(b), dataOffset+i*4)))
+ if k != key {
+ continue
+ }
+ inserti = i
+ insertb = b
+ goto done
+ }
+ ovf := b.overflow(t)
+ if ovf == nil {
+ break
+ }
+ b = ovf
+ }
+
+ // Did not find mapping for key. Allocate new cell & add entry.
+
+ // If we hit the max load factor or we have too many overflow buckets,
+ // and we're not already in the middle of growing, start growing.
+ if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+ hashGrow(t, h)
+ goto again // Growing the table invalidates everything, so try again
+ }
+
+ if insertb == nil {
+ // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
+ insertb = h.newoverflow(t, b)
+ inserti = 0 // not necessary, but avoids needlessly spilling inserti
+ }
+ insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks
+
+ insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*4)
+ // store new key at insert position
+ *(*unsafe.Pointer)(insertk) = key
+
+ h.count++
+
+done:
+ elem := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*4+inserti*uintptr(t.ValueSize))
+ if h.flags&hashWriting == 0 {
+ fatal("concurrent map writes")
+ }
+ h.flags &^= hashWriting
+ return elem
+}
+
+func mapdelete_fast32(t *maptype, h *hmap, key uint32) {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapdelete_fast32))
+ }
+ if h == nil || h.count == 0 {
+ return
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map writes")
+ }
+
+ hash := t.Hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
+
+ // Set hashWriting after calling t.hasher for consistency with mapdelete
+ h.flags ^= hashWriting
+
+ bucket := hash & bucketMask(h.B)
+ if h.growing() {
+ growWork_fast32(t, h, bucket)
+ }
+ b := (*bmap)(add(h.buckets, bucket*uintptr(t.BucketSize)))
+ bOrig := b
+search:
+ for ; b != nil; b = b.overflow(t) {
+ for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 4) {
+ if key != *(*uint32)(k) || isEmpty(b.tophash[i]) {
+ continue
+ }
+ // Only clear key if there are pointers in it.
+ // This can only happen if pointers are 32 bit
+ // wide as 64 bit pointers do not fit into a 32 bit key.
+ if goarch.PtrSize == 4 && t.Key.PtrBytes != 0 {
+ // The key must be a pointer as we checked pointers are
+ // 32 bits wide and the key is 32 bits wide also.
+ *(*unsafe.Pointer)(k) = nil
+ }
+ e := add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.ValueSize))
+ if t.Elem.PtrBytes != 0 {
+ memclrHasPointers(e, t.Elem.Size_)
+ } else {
+ memclrNoHeapPointers(e, t.Elem.Size_)
+ }
+ b.tophash[i] = emptyOne
+ // If the bucket now ends in a bunch of emptyOne states,
+ // change those to emptyRest states.
+ if i == bucketCnt-1 {
+ if b.overflow(t) != nil && b.overflow(t).tophash[0] != emptyRest {
+ goto notLast
+ }
+ } else {
+ if b.tophash[i+1] != emptyRest {
+ goto notLast
+ }
+ }
+ for {
+ b.tophash[i] = emptyRest
+ if i == 0 {
+ if b == bOrig {
+ break // beginning of initial bucket, we're done.
+ }
+ // Find previous bucket, continue at its last entry.
+ c := b
+ for b = bOrig; b.overflow(t) != c; b = b.overflow(t) {
+ }
+ i = bucketCnt - 1
+ } else {
+ i--
+ }
+ if b.tophash[i] != emptyOne {
+ break
+ }
+ }
+ notLast:
+ h.count--
+ // Reset the hash seed to make it more difficult for attackers to
+ // repeatedly trigger hash collisions. See issue 25237.
+ if h.count == 0 {
+ h.hash0 = fastrand()
+ }
+ break search
+ }
+ }
+
+ if h.flags&hashWriting == 0 {
+ fatal("concurrent map writes")
+ }
+ h.flags &^= hashWriting
+}
+
+func growWork_fast32(t *maptype, h *hmap, bucket uintptr) {
+ // make sure we evacuate the oldbucket corresponding
+ // to the bucket we're about to use
+ evacuate_fast32(t, h, bucket&h.oldbucketmask())
+
+ // evacuate one more oldbucket to make progress on growing
+ if h.growing() {
+ evacuate_fast32(t, h, h.nevacuate)
+ }
+}
+
+func evacuate_fast32(t *maptype, h *hmap, oldbucket uintptr) {
+ b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.BucketSize)))
+ newbit := h.noldbuckets()
+ if !evacuated(b) {
+ // TODO: reuse overflow buckets instead of using new ones, if there
+ // is no iterator using the old buckets. (If !oldIterator.)
+
+ // xy contains the x and y (low and high) evacuation destinations.
+ var xy [2]evacDst
+ x := &xy[0]
+ x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.BucketSize)))
+ x.k = add(unsafe.Pointer(x.b), dataOffset)
+ x.e = add(x.k, bucketCnt*4)
+
+ if !h.sameSizeGrow() {
+ // Only calculate y pointers if we're growing bigger.
+ // Otherwise GC can see bad pointers.
+ y := &xy[1]
+ y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.BucketSize)))
+ y.k = add(unsafe.Pointer(y.b), dataOffset)
+ y.e = add(y.k, bucketCnt*4)
+ }
+
+ for ; b != nil; b = b.overflow(t) {
+ k := add(unsafe.Pointer(b), dataOffset)
+ e := add(k, bucketCnt*4)
+ for i := 0; i < bucketCnt; i, k, e = i+1, add(k, 4), add(e, uintptr(t.ValueSize)) {
+ top := b.tophash[i]
+ if isEmpty(top) {
+ b.tophash[i] = evacuatedEmpty
+ continue
+ }
+ if top < minTopHash {
+ throw("bad map state")
+ }
+ var useY uint8
+ if !h.sameSizeGrow() {
+ // Compute hash to make our evacuation decision (whether we need
+ // to send this key/elem to bucket x or bucket y).
+ hash := t.Hasher(k, uintptr(h.hash0))
+ if hash&newbit != 0 {
+ useY = 1
+ }
+ }
+
+ b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY, enforced in makemap
+ dst := &xy[useY] // evacuation destination
+
+ if dst.i == bucketCnt {
+ dst.b = h.newoverflow(t, dst.b)
+ dst.i = 0
+ dst.k = add(unsafe.Pointer(dst.b), dataOffset)
+ dst.e = add(dst.k, bucketCnt*4)
+ }
+ dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
+
+ // Copy key.
+ if goarch.PtrSize == 4 && t.Key.PtrBytes != 0 && writeBarrier.enabled {
+ // Write with a write barrier.
+ *(*unsafe.Pointer)(dst.k) = *(*unsafe.Pointer)(k)
+ } else {
+ *(*uint32)(dst.k) = *(*uint32)(k)
+ }
+
+ typedmemmove(t.Elem, dst.e, e)
+ dst.i++
+ // These updates might push these pointers past the end of the
+ // key or elem arrays. That's ok, as we have the overflow pointer
+ // at the end of the bucket to protect against pointing past the
+ // end of the bucket.
+ dst.k = add(dst.k, 4)
+ dst.e = add(dst.e, uintptr(t.ValueSize))
+ }
+ }
+ // Unlink the overflow buckets & clear key/elem to help GC.
+ if h.flags&oldIterator == 0 && t.Bucket.PtrBytes != 0 {
+ b := add(h.oldbuckets, oldbucket*uintptr(t.BucketSize))
+ // Preserve b.tophash because the evacuation
+ // state is maintained there.
+ ptr := add(b, dataOffset)
+ n := uintptr(t.BucketSize) - dataOffset
+ memclrHasPointers(ptr, n)
+ }
+ }
+
+ if oldbucket == h.nevacuate {
+ advanceEvacuationMark(h, t, newbit)
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/map_fast64.go b/contrib/go/_std_1.21/src/runtime/map_fast64.go
new file mode 100644
index 0000000000..d771e0b747
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/map_fast64.go
@@ -0,0 +1,470 @@
+// Copyright 2018 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "unsafe"
+)
+
+func mapaccess1_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess1_fast64))
+ }
+ if h == nil || h.count == 0 {
+ return unsafe.Pointer(&zeroVal[0])
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map read and map write")
+ }
+ var b *bmap
+ if h.B == 0 {
+ // One-bucket table. No need to hash.
+ b = (*bmap)(h.buckets)
+ } else {
+ hash := t.Hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
+ m := bucketMask(h.B)
+ b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.BucketSize)))
+ if c := h.oldbuckets; c != nil {
+ if !h.sameSizeGrow() {
+ // There used to be half as many buckets; mask down one more power of two.
+ m >>= 1
+ }
+ oldb := (*bmap)(add(c, (hash&m)*uintptr(t.BucketSize)))
+ if !evacuated(oldb) {
+ b = oldb
+ }
+ }
+ }
+ for ; b != nil; b = b.overflow(t) {
+ for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 8) {
+ if *(*uint64)(k) == key && !isEmpty(b.tophash[i]) {
+ return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.ValueSize))
+ }
+ }
+ }
+ return unsafe.Pointer(&zeroVal[0])
+}
+
+func mapaccess2_fast64(t *maptype, h *hmap, key uint64) (unsafe.Pointer, bool) {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess2_fast64))
+ }
+ if h == nil || h.count == 0 {
+ return unsafe.Pointer(&zeroVal[0]), false
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map read and map write")
+ }
+ var b *bmap
+ if h.B == 0 {
+ // One-bucket table. No need to hash.
+ b = (*bmap)(h.buckets)
+ } else {
+ hash := t.Hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
+ m := bucketMask(h.B)
+ b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.BucketSize)))
+ if c := h.oldbuckets; c != nil {
+ if !h.sameSizeGrow() {
+ // There used to be half as many buckets; mask down one more power of two.
+ m >>= 1
+ }
+ oldb := (*bmap)(add(c, (hash&m)*uintptr(t.BucketSize)))
+ if !evacuated(oldb) {
+ b = oldb
+ }
+ }
+ }
+ for ; b != nil; b = b.overflow(t) {
+ for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 8) {
+ if *(*uint64)(k) == key && !isEmpty(b.tophash[i]) {
+ return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.ValueSize)), true
+ }
+ }
+ }
+ return unsafe.Pointer(&zeroVal[0]), false
+}
+
+func mapassign_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer {
+ if h == nil {
+ panic(plainError("assignment to entry in nil map"))
+ }
+ if raceenabled {
+ callerpc := getcallerpc()
+ racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapassign_fast64))
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map writes")
+ }
+ hash := t.Hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
+
+ // Set hashWriting after calling t.hasher for consistency with mapassign.
+ h.flags ^= hashWriting
+
+ if h.buckets == nil {
+ h.buckets = newobject(t.Bucket) // newarray(t.bucket, 1)
+ }
+
+again:
+ bucket := hash & bucketMask(h.B)
+ if h.growing() {
+ growWork_fast64(t, h, bucket)
+ }
+ b := (*bmap)(add(h.buckets, bucket*uintptr(t.BucketSize)))
+
+ var insertb *bmap
+ var inserti uintptr
+ var insertk unsafe.Pointer
+
+bucketloop:
+ for {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ if isEmpty(b.tophash[i]) {
+ if insertb == nil {
+ insertb = b
+ inserti = i
+ }
+ if b.tophash[i] == emptyRest {
+ break bucketloop
+ }
+ continue
+ }
+ k := *((*uint64)(add(unsafe.Pointer(b), dataOffset+i*8)))
+ if k != key {
+ continue
+ }
+ insertb = b
+ inserti = i
+ goto done
+ }
+ ovf := b.overflow(t)
+ if ovf == nil {
+ break
+ }
+ b = ovf
+ }
+
+ // Did not find mapping for key. Allocate new cell & add entry.
+
+ // If we hit the max load factor or we have too many overflow buckets,
+ // and we're not already in the middle of growing, start growing.
+ if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+ hashGrow(t, h)
+ goto again // Growing the table invalidates everything, so try again
+ }
+
+ if insertb == nil {
+ // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
+ insertb = h.newoverflow(t, b)
+ inserti = 0 // not necessary, but avoids needlessly spilling inserti
+ }
+ insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks
+
+ insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*8)
+ // store new key at insert position
+ *(*uint64)(insertk) = key
+
+ h.count++
+
+done:
+ elem := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*8+inserti*uintptr(t.ValueSize))
+ if h.flags&hashWriting == 0 {
+ fatal("concurrent map writes")
+ }
+ h.flags &^= hashWriting
+ return elem
+}
+
+func mapassign_fast64ptr(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
+ if h == nil {
+ panic(plainError("assignment to entry in nil map"))
+ }
+ if raceenabled {
+ callerpc := getcallerpc()
+ racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapassign_fast64))
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map writes")
+ }
+ hash := t.Hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
+
+ // Set hashWriting after calling t.hasher for consistency with mapassign.
+ h.flags ^= hashWriting
+
+ if h.buckets == nil {
+ h.buckets = newobject(t.Bucket) // newarray(t.bucket, 1)
+ }
+
+again:
+ bucket := hash & bucketMask(h.B)
+ if h.growing() {
+ growWork_fast64(t, h, bucket)
+ }
+ b := (*bmap)(add(h.buckets, bucket*uintptr(t.BucketSize)))
+
+ var insertb *bmap
+ var inserti uintptr
+ var insertk unsafe.Pointer
+
+bucketloop:
+ for {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ if isEmpty(b.tophash[i]) {
+ if insertb == nil {
+ insertb = b
+ inserti = i
+ }
+ if b.tophash[i] == emptyRest {
+ break bucketloop
+ }
+ continue
+ }
+ k := *((*unsafe.Pointer)(add(unsafe.Pointer(b), dataOffset+i*8)))
+ if k != key {
+ continue
+ }
+ insertb = b
+ inserti = i
+ goto done
+ }
+ ovf := b.overflow(t)
+ if ovf == nil {
+ break
+ }
+ b = ovf
+ }
+
+ // Did not find mapping for key. Allocate new cell & add entry.
+
+ // If we hit the max load factor or we have too many overflow buckets,
+ // and we're not already in the middle of growing, start growing.
+ if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+ hashGrow(t, h)
+ goto again // Growing the table invalidates everything, so try again
+ }
+
+ if insertb == nil {
+ // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
+ insertb = h.newoverflow(t, b)
+ inserti = 0 // not necessary, but avoids needlessly spilling inserti
+ }
+ insertb.tophash[inserti&(bucketCnt-1)] = tophash(hash) // mask inserti to avoid bounds checks
+
+ insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*8)
+ // store new key at insert position
+ *(*unsafe.Pointer)(insertk) = key
+
+ h.count++
+
+done:
+ elem := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*8+inserti*uintptr(t.ValueSize))
+ if h.flags&hashWriting == 0 {
+ fatal("concurrent map writes")
+ }
+ h.flags &^= hashWriting
+ return elem
+}
+
+func mapdelete_fast64(t *maptype, h *hmap, key uint64) {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapdelete_fast64))
+ }
+ if h == nil || h.count == 0 {
+ return
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map writes")
+ }
+
+ hash := t.Hasher(noescape(unsafe.Pointer(&key)), uintptr(h.hash0))
+
+ // Set hashWriting after calling t.hasher for consistency with mapdelete
+ h.flags ^= hashWriting
+
+ bucket := hash & bucketMask(h.B)
+ if h.growing() {
+ growWork_fast64(t, h, bucket)
+ }
+ b := (*bmap)(add(h.buckets, bucket*uintptr(t.BucketSize)))
+ bOrig := b
+search:
+ for ; b != nil; b = b.overflow(t) {
+ for i, k := uintptr(0), b.keys(); i < bucketCnt; i, k = i+1, add(k, 8) {
+ if key != *(*uint64)(k) || isEmpty(b.tophash[i]) {
+ continue
+ }
+ // Only clear key if there are pointers in it.
+ if t.Key.PtrBytes != 0 {
+ if goarch.PtrSize == 8 {
+ *(*unsafe.Pointer)(k) = nil
+ } else {
+ // There are three ways to squeeze at one or more 32 bit pointers into 64 bits.
+ // Just call memclrHasPointers instead of trying to handle all cases here.
+ memclrHasPointers(k, 8)
+ }
+ }
+ e := add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.ValueSize))
+ if t.Elem.PtrBytes != 0 {
+ memclrHasPointers(e, t.Elem.Size_)
+ } else {
+ memclrNoHeapPointers(e, t.Elem.Size_)
+ }
+ b.tophash[i] = emptyOne
+ // If the bucket now ends in a bunch of emptyOne states,
+ // change those to emptyRest states.
+ if i == bucketCnt-1 {
+ if b.overflow(t) != nil && b.overflow(t).tophash[0] != emptyRest {
+ goto notLast
+ }
+ } else {
+ if b.tophash[i+1] != emptyRest {
+ goto notLast
+ }
+ }
+ for {
+ b.tophash[i] = emptyRest
+ if i == 0 {
+ if b == bOrig {
+ break // beginning of initial bucket, we're done.
+ }
+ // Find previous bucket, continue at its last entry.
+ c := b
+ for b = bOrig; b.overflow(t) != c; b = b.overflow(t) {
+ }
+ i = bucketCnt - 1
+ } else {
+ i--
+ }
+ if b.tophash[i] != emptyOne {
+ break
+ }
+ }
+ notLast:
+ h.count--
+ // Reset the hash seed to make it more difficult for attackers to
+ // repeatedly trigger hash collisions. See issue 25237.
+ if h.count == 0 {
+ h.hash0 = fastrand()
+ }
+ break search
+ }
+ }
+
+ if h.flags&hashWriting == 0 {
+ fatal("concurrent map writes")
+ }
+ h.flags &^= hashWriting
+}
+
+func growWork_fast64(t *maptype, h *hmap, bucket uintptr) {
+ // make sure we evacuate the oldbucket corresponding
+ // to the bucket we're about to use
+ evacuate_fast64(t, h, bucket&h.oldbucketmask())
+
+ // evacuate one more oldbucket to make progress on growing
+ if h.growing() {
+ evacuate_fast64(t, h, h.nevacuate)
+ }
+}
+
+func evacuate_fast64(t *maptype, h *hmap, oldbucket uintptr) {
+ b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.BucketSize)))
+ newbit := h.noldbuckets()
+ if !evacuated(b) {
+ // TODO: reuse overflow buckets instead of using new ones, if there
+ // is no iterator using the old buckets. (If !oldIterator.)
+
+ // xy contains the x and y (low and high) evacuation destinations.
+ var xy [2]evacDst
+ x := &xy[0]
+ x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.BucketSize)))
+ x.k = add(unsafe.Pointer(x.b), dataOffset)
+ x.e = add(x.k, bucketCnt*8)
+
+ if !h.sameSizeGrow() {
+ // Only calculate y pointers if we're growing bigger.
+ // Otherwise GC can see bad pointers.
+ y := &xy[1]
+ y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.BucketSize)))
+ y.k = add(unsafe.Pointer(y.b), dataOffset)
+ y.e = add(y.k, bucketCnt*8)
+ }
+
+ for ; b != nil; b = b.overflow(t) {
+ k := add(unsafe.Pointer(b), dataOffset)
+ e := add(k, bucketCnt*8)
+ for i := 0; i < bucketCnt; i, k, e = i+1, add(k, 8), add(e, uintptr(t.ValueSize)) {
+ top := b.tophash[i]
+ if isEmpty(top) {
+ b.tophash[i] = evacuatedEmpty
+ continue
+ }
+ if top < minTopHash {
+ throw("bad map state")
+ }
+ var useY uint8
+ if !h.sameSizeGrow() {
+ // Compute hash to make our evacuation decision (whether we need
+ // to send this key/elem to bucket x or bucket y).
+ hash := t.Hasher(k, uintptr(h.hash0))
+ if hash&newbit != 0 {
+ useY = 1
+ }
+ }
+
+ b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY, enforced in makemap
+ dst := &xy[useY] // evacuation destination
+
+ if dst.i == bucketCnt {
+ dst.b = h.newoverflow(t, dst.b)
+ dst.i = 0
+ dst.k = add(unsafe.Pointer(dst.b), dataOffset)
+ dst.e = add(dst.k, bucketCnt*8)
+ }
+ dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
+
+ // Copy key.
+ if t.Key.PtrBytes != 0 && writeBarrier.enabled {
+ if goarch.PtrSize == 8 {
+ // Write with a write barrier.
+ *(*unsafe.Pointer)(dst.k) = *(*unsafe.Pointer)(k)
+ } else {
+ // There are three ways to squeeze at least one 32 bit pointer into 64 bits.
+ // Give up and call typedmemmove.
+ typedmemmove(t.Key, dst.k, k)
+ }
+ } else {
+ *(*uint64)(dst.k) = *(*uint64)(k)
+ }
+
+ typedmemmove(t.Elem, dst.e, e)
+ dst.i++
+ // These updates might push these pointers past the end of the
+ // key or elem arrays. That's ok, as we have the overflow pointer
+ // at the end of the bucket to protect against pointing past the
+ // end of the bucket.
+ dst.k = add(dst.k, 8)
+ dst.e = add(dst.e, uintptr(t.ValueSize))
+ }
+ }
+ // Unlink the overflow buckets & clear key/elem to help GC.
+ if h.flags&oldIterator == 0 && t.Bucket.PtrBytes != 0 {
+ b := add(h.oldbuckets, oldbucket*uintptr(t.BucketSize))
+ // Preserve b.tophash because the evacuation
+ // state is maintained there.
+ ptr := add(b, dataOffset)
+ n := uintptr(t.BucketSize) - dataOffset
+ memclrHasPointers(ptr, n)
+ }
+ }
+
+ if oldbucket == h.nevacuate {
+ advanceEvacuationMark(h, t, newbit)
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/map_faststr.go b/contrib/go/_std_1.21/src/runtime/map_faststr.go
new file mode 100644
index 0000000000..ef71da859a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/map_faststr.go
@@ -0,0 +1,485 @@
+// Copyright 2018 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "unsafe"
+)
+
+func mapaccess1_faststr(t *maptype, h *hmap, ky string) unsafe.Pointer {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess1_faststr))
+ }
+ if h == nil || h.count == 0 {
+ return unsafe.Pointer(&zeroVal[0])
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map read and map write")
+ }
+ key := stringStructOf(&ky)
+ if h.B == 0 {
+ // One-bucket table.
+ b := (*bmap)(h.buckets)
+ if key.len < 32 {
+ // short key, doing lots of comparisons is ok
+ for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
+ k := (*stringStruct)(kptr)
+ if k.len != key.len || isEmpty(b.tophash[i]) {
+ if b.tophash[i] == emptyRest {
+ break
+ }
+ continue
+ }
+ if k.str == key.str || memequal(k.str, key.str, uintptr(key.len)) {
+ return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.ValueSize))
+ }
+ }
+ return unsafe.Pointer(&zeroVal[0])
+ }
+ // long key, try not to do more comparisons than necessary
+ keymaybe := uintptr(bucketCnt)
+ for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
+ k := (*stringStruct)(kptr)
+ if k.len != key.len || isEmpty(b.tophash[i]) {
+ if b.tophash[i] == emptyRest {
+ break
+ }
+ continue
+ }
+ if k.str == key.str {
+ return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.ValueSize))
+ }
+ // check first 4 bytes
+ if *((*[4]byte)(key.str)) != *((*[4]byte)(k.str)) {
+ continue
+ }
+ // check last 4 bytes
+ if *((*[4]byte)(add(key.str, uintptr(key.len)-4))) != *((*[4]byte)(add(k.str, uintptr(key.len)-4))) {
+ continue
+ }
+ if keymaybe != bucketCnt {
+ // Two keys are potential matches. Use hash to distinguish them.
+ goto dohash
+ }
+ keymaybe = i
+ }
+ if keymaybe != bucketCnt {
+ k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+keymaybe*2*goarch.PtrSize))
+ if memequal(k.str, key.str, uintptr(key.len)) {
+ return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+keymaybe*uintptr(t.ValueSize))
+ }
+ }
+ return unsafe.Pointer(&zeroVal[0])
+ }
+dohash:
+ hash := t.Hasher(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0))
+ m := bucketMask(h.B)
+ b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.BucketSize)))
+ if c := h.oldbuckets; c != nil {
+ if !h.sameSizeGrow() {
+ // There used to be half as many buckets; mask down one more power of two.
+ m >>= 1
+ }
+ oldb := (*bmap)(add(c, (hash&m)*uintptr(t.BucketSize)))
+ if !evacuated(oldb) {
+ b = oldb
+ }
+ }
+ top := tophash(hash)
+ for ; b != nil; b = b.overflow(t) {
+ for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
+ k := (*stringStruct)(kptr)
+ if k.len != key.len || b.tophash[i] != top {
+ continue
+ }
+ if k.str == key.str || memequal(k.str, key.str, uintptr(key.len)) {
+ return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.ValueSize))
+ }
+ }
+ }
+ return unsafe.Pointer(&zeroVal[0])
+}
+
+func mapaccess2_faststr(t *maptype, h *hmap, ky string) (unsafe.Pointer, bool) {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ racereadpc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapaccess2_faststr))
+ }
+ if h == nil || h.count == 0 {
+ return unsafe.Pointer(&zeroVal[0]), false
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map read and map write")
+ }
+ key := stringStructOf(&ky)
+ if h.B == 0 {
+ // One-bucket table.
+ b := (*bmap)(h.buckets)
+ if key.len < 32 {
+ // short key, doing lots of comparisons is ok
+ for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
+ k := (*stringStruct)(kptr)
+ if k.len != key.len || isEmpty(b.tophash[i]) {
+ if b.tophash[i] == emptyRest {
+ break
+ }
+ continue
+ }
+ if k.str == key.str || memequal(k.str, key.str, uintptr(key.len)) {
+ return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.ValueSize)), true
+ }
+ }
+ return unsafe.Pointer(&zeroVal[0]), false
+ }
+ // long key, try not to do more comparisons than necessary
+ keymaybe := uintptr(bucketCnt)
+ for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
+ k := (*stringStruct)(kptr)
+ if k.len != key.len || isEmpty(b.tophash[i]) {
+ if b.tophash[i] == emptyRest {
+ break
+ }
+ continue
+ }
+ if k.str == key.str {
+ return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.ValueSize)), true
+ }
+ // check first 4 bytes
+ if *((*[4]byte)(key.str)) != *((*[4]byte)(k.str)) {
+ continue
+ }
+ // check last 4 bytes
+ if *((*[4]byte)(add(key.str, uintptr(key.len)-4))) != *((*[4]byte)(add(k.str, uintptr(key.len)-4))) {
+ continue
+ }
+ if keymaybe != bucketCnt {
+ // Two keys are potential matches. Use hash to distinguish them.
+ goto dohash
+ }
+ keymaybe = i
+ }
+ if keymaybe != bucketCnt {
+ k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+keymaybe*2*goarch.PtrSize))
+ if memequal(k.str, key.str, uintptr(key.len)) {
+ return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+keymaybe*uintptr(t.ValueSize)), true
+ }
+ }
+ return unsafe.Pointer(&zeroVal[0]), false
+ }
+dohash:
+ hash := t.Hasher(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0))
+ m := bucketMask(h.B)
+ b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.BucketSize)))
+ if c := h.oldbuckets; c != nil {
+ if !h.sameSizeGrow() {
+ // There used to be half as many buckets; mask down one more power of two.
+ m >>= 1
+ }
+ oldb := (*bmap)(add(c, (hash&m)*uintptr(t.BucketSize)))
+ if !evacuated(oldb) {
+ b = oldb
+ }
+ }
+ top := tophash(hash)
+ for ; b != nil; b = b.overflow(t) {
+ for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
+ k := (*stringStruct)(kptr)
+ if k.len != key.len || b.tophash[i] != top {
+ continue
+ }
+ if k.str == key.str || memequal(k.str, key.str, uintptr(key.len)) {
+ return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.ValueSize)), true
+ }
+ }
+ }
+ return unsafe.Pointer(&zeroVal[0]), false
+}
+
+func mapassign_faststr(t *maptype, h *hmap, s string) unsafe.Pointer {
+ if h == nil {
+ panic(plainError("assignment to entry in nil map"))
+ }
+ if raceenabled {
+ callerpc := getcallerpc()
+ racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapassign_faststr))
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map writes")
+ }
+ key := stringStructOf(&s)
+ hash := t.Hasher(noescape(unsafe.Pointer(&s)), uintptr(h.hash0))
+
+ // Set hashWriting after calling t.hasher for consistency with mapassign.
+ h.flags ^= hashWriting
+
+ if h.buckets == nil {
+ h.buckets = newobject(t.Bucket) // newarray(t.bucket, 1)
+ }
+
+again:
+ bucket := hash & bucketMask(h.B)
+ if h.growing() {
+ growWork_faststr(t, h, bucket)
+ }
+ b := (*bmap)(add(h.buckets, bucket*uintptr(t.BucketSize)))
+ top := tophash(hash)
+
+ var insertb *bmap
+ var inserti uintptr
+ var insertk unsafe.Pointer
+
+bucketloop:
+ for {
+ for i := uintptr(0); i < bucketCnt; i++ {
+ if b.tophash[i] != top {
+ if isEmpty(b.tophash[i]) && insertb == nil {
+ insertb = b
+ inserti = i
+ }
+ if b.tophash[i] == emptyRest {
+ break bucketloop
+ }
+ continue
+ }
+ k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*goarch.PtrSize))
+ if k.len != key.len {
+ continue
+ }
+ if k.str != key.str && !memequal(k.str, key.str, uintptr(key.len)) {
+ continue
+ }
+ // already have a mapping for key. Update it.
+ inserti = i
+ insertb = b
+ // Overwrite existing key, so it can be garbage collected.
+ // The size is already guaranteed to be set correctly.
+ k.str = key.str
+ goto done
+ }
+ ovf := b.overflow(t)
+ if ovf == nil {
+ break
+ }
+ b = ovf
+ }
+
+ // Did not find mapping for key. Allocate new cell & add entry.
+
+ // If we hit the max load factor or we have too many overflow buckets,
+ // and we're not already in the middle of growing, start growing.
+ if !h.growing() && (overLoadFactor(h.count+1, h.B) || tooManyOverflowBuckets(h.noverflow, h.B)) {
+ hashGrow(t, h)
+ goto again // Growing the table invalidates everything, so try again
+ }
+
+ if insertb == nil {
+ // The current bucket and all the overflow buckets connected to it are full, allocate a new one.
+ insertb = h.newoverflow(t, b)
+ inserti = 0 // not necessary, but avoids needlessly spilling inserti
+ }
+ insertb.tophash[inserti&(bucketCnt-1)] = top // mask inserti to avoid bounds checks
+
+ insertk = add(unsafe.Pointer(insertb), dataOffset+inserti*2*goarch.PtrSize)
+ // store new key at insert position
+ *((*stringStruct)(insertk)) = *key
+ h.count++
+
+done:
+ elem := add(unsafe.Pointer(insertb), dataOffset+bucketCnt*2*goarch.PtrSize+inserti*uintptr(t.ValueSize))
+ if h.flags&hashWriting == 0 {
+ fatal("concurrent map writes")
+ }
+ h.flags &^= hashWriting
+ return elem
+}
+
+func mapdelete_faststr(t *maptype, h *hmap, ky string) {
+ if raceenabled && h != nil {
+ callerpc := getcallerpc()
+ racewritepc(unsafe.Pointer(h), callerpc, abi.FuncPCABIInternal(mapdelete_faststr))
+ }
+ if h == nil || h.count == 0 {
+ return
+ }
+ if h.flags&hashWriting != 0 {
+ fatal("concurrent map writes")
+ }
+
+ key := stringStructOf(&ky)
+ hash := t.Hasher(noescape(unsafe.Pointer(&ky)), uintptr(h.hash0))
+
+ // Set hashWriting after calling t.hasher for consistency with mapdelete
+ h.flags ^= hashWriting
+
+ bucket := hash & bucketMask(h.B)
+ if h.growing() {
+ growWork_faststr(t, h, bucket)
+ }
+ b := (*bmap)(add(h.buckets, bucket*uintptr(t.BucketSize)))
+ bOrig := b
+ top := tophash(hash)
+search:
+ for ; b != nil; b = b.overflow(t) {
+ for i, kptr := uintptr(0), b.keys(); i < bucketCnt; i, kptr = i+1, add(kptr, 2*goarch.PtrSize) {
+ k := (*stringStruct)(kptr)
+ if k.len != key.len || b.tophash[i] != top {
+ continue
+ }
+ if k.str != key.str && !memequal(k.str, key.str, uintptr(key.len)) {
+ continue
+ }
+ // Clear key's pointer.
+ k.str = nil
+ e := add(unsafe.Pointer(b), dataOffset+bucketCnt*2*goarch.PtrSize+i*uintptr(t.ValueSize))
+ if t.Elem.PtrBytes != 0 {
+ memclrHasPointers(e, t.Elem.Size_)
+ } else {
+ memclrNoHeapPointers(e, t.Elem.Size_)
+ }
+ b.tophash[i] = emptyOne
+ // If the bucket now ends in a bunch of emptyOne states,
+ // change those to emptyRest states.
+ if i == bucketCnt-1 {
+ if b.overflow(t) != nil && b.overflow(t).tophash[0] != emptyRest {
+ goto notLast
+ }
+ } else {
+ if b.tophash[i+1] != emptyRest {
+ goto notLast
+ }
+ }
+ for {
+ b.tophash[i] = emptyRest
+ if i == 0 {
+ if b == bOrig {
+ break // beginning of initial bucket, we're done.
+ }
+ // Find previous bucket, continue at its last entry.
+ c := b
+ for b = bOrig; b.overflow(t) != c; b = b.overflow(t) {
+ }
+ i = bucketCnt - 1
+ } else {
+ i--
+ }
+ if b.tophash[i] != emptyOne {
+ break
+ }
+ }
+ notLast:
+ h.count--
+ // Reset the hash seed to make it more difficult for attackers to
+ // repeatedly trigger hash collisions. See issue 25237.
+ if h.count == 0 {
+ h.hash0 = fastrand()
+ }
+ break search
+ }
+ }
+
+ if h.flags&hashWriting == 0 {
+ fatal("concurrent map writes")
+ }
+ h.flags &^= hashWriting
+}
+
+func growWork_faststr(t *maptype, h *hmap, bucket uintptr) {
+ // make sure we evacuate the oldbucket corresponding
+ // to the bucket we're about to use
+ evacuate_faststr(t, h, bucket&h.oldbucketmask())
+
+ // evacuate one more oldbucket to make progress on growing
+ if h.growing() {
+ evacuate_faststr(t, h, h.nevacuate)
+ }
+}
+
+func evacuate_faststr(t *maptype, h *hmap, oldbucket uintptr) {
+ b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.BucketSize)))
+ newbit := h.noldbuckets()
+ if !evacuated(b) {
+ // TODO: reuse overflow buckets instead of using new ones, if there
+ // is no iterator using the old buckets. (If !oldIterator.)
+
+ // xy contains the x and y (low and high) evacuation destinations.
+ var xy [2]evacDst
+ x := &xy[0]
+ x.b = (*bmap)(add(h.buckets, oldbucket*uintptr(t.BucketSize)))
+ x.k = add(unsafe.Pointer(x.b), dataOffset)
+ x.e = add(x.k, bucketCnt*2*goarch.PtrSize)
+
+ if !h.sameSizeGrow() {
+ // Only calculate y pointers if we're growing bigger.
+ // Otherwise GC can see bad pointers.
+ y := &xy[1]
+ y.b = (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.BucketSize)))
+ y.k = add(unsafe.Pointer(y.b), dataOffset)
+ y.e = add(y.k, bucketCnt*2*goarch.PtrSize)
+ }
+
+ for ; b != nil; b = b.overflow(t) {
+ k := add(unsafe.Pointer(b), dataOffset)
+ e := add(k, bucketCnt*2*goarch.PtrSize)
+ for i := 0; i < bucketCnt; i, k, e = i+1, add(k, 2*goarch.PtrSize), add(e, uintptr(t.ValueSize)) {
+ top := b.tophash[i]
+ if isEmpty(top) {
+ b.tophash[i] = evacuatedEmpty
+ continue
+ }
+ if top < minTopHash {
+ throw("bad map state")
+ }
+ var useY uint8
+ if !h.sameSizeGrow() {
+ // Compute hash to make our evacuation decision (whether we need
+ // to send this key/elem to bucket x or bucket y).
+ hash := t.Hasher(k, uintptr(h.hash0))
+ if hash&newbit != 0 {
+ useY = 1
+ }
+ }
+
+ b.tophash[i] = evacuatedX + useY // evacuatedX + 1 == evacuatedY, enforced in makemap
+ dst := &xy[useY] // evacuation destination
+
+ if dst.i == bucketCnt {
+ dst.b = h.newoverflow(t, dst.b)
+ dst.i = 0
+ dst.k = add(unsafe.Pointer(dst.b), dataOffset)
+ dst.e = add(dst.k, bucketCnt*2*goarch.PtrSize)
+ }
+ dst.b.tophash[dst.i&(bucketCnt-1)] = top // mask dst.i as an optimization, to avoid a bounds check
+
+ // Copy key.
+ *(*string)(dst.k) = *(*string)(k)
+
+ typedmemmove(t.Elem, dst.e, e)
+ dst.i++
+ // These updates might push these pointers past the end of the
+ // key or elem arrays. That's ok, as we have the overflow pointer
+ // at the end of the bucket to protect against pointing past the
+ // end of the bucket.
+ dst.k = add(dst.k, 2*goarch.PtrSize)
+ dst.e = add(dst.e, uintptr(t.ValueSize))
+ }
+ }
+ // Unlink the overflow buckets & clear key/elem to help GC.
+ if h.flags&oldIterator == 0 && t.Bucket.PtrBytes != 0 {
+ b := add(h.oldbuckets, oldbucket*uintptr(t.BucketSize))
+ // Preserve b.tophash because the evacuation
+ // state is maintained there.
+ ptr := add(b, dataOffset)
+ n := uintptr(t.BucketSize) - dataOffset
+ memclrHasPointers(ptr, n)
+ }
+ }
+
+ if oldbucket == h.nevacuate {
+ advanceEvacuationMark(h, t, newbit)
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mbarrier.go b/contrib/go/_std_1.21/src/runtime/mbarrier.go
new file mode 100644
index 0000000000..159a298155
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mbarrier.go
@@ -0,0 +1,347 @@
+// Copyright 2015 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.
+
+// Garbage collector: write barriers.
+//
+// For the concurrent garbage collector, the Go compiler implements
+// updates to pointer-valued fields that may be in heap objects by
+// emitting calls to write barriers. The main write barrier for
+// individual pointer writes is gcWriteBarrier and is implemented in
+// assembly. This file contains write barrier entry points for bulk
+// operations. See also mwbbuf.go.
+
+package runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "internal/goexperiment"
+ "unsafe"
+)
+
+// Go uses a hybrid barrier that combines a Yuasa-style deletion
+// barrier—which shades the object whose reference is being
+// overwritten—with Dijkstra insertion barrier—which shades the object
+// whose reference is being written. The insertion part of the barrier
+// is necessary while the calling goroutine's stack is grey. In
+// pseudocode, the barrier is:
+//
+// writePointer(slot, ptr):
+// shade(*slot)
+// if current stack is grey:
+// shade(ptr)
+// *slot = ptr
+//
+// slot is the destination in Go code.
+// ptr is the value that goes into the slot in Go code.
+//
+// Shade indicates that it has seen a white pointer by adding the referent
+// to wbuf as well as marking it.
+//
+// The two shades and the condition work together to prevent a mutator
+// from hiding an object from the garbage collector:
+//
+// 1. shade(*slot) prevents a mutator from hiding an object by moving
+// the sole pointer to it from the heap to its stack. If it attempts
+// to unlink an object from the heap, this will shade it.
+//
+// 2. shade(ptr) prevents a mutator from hiding an object by moving
+// the sole pointer to it from its stack into a black object in the
+// heap. If it attempts to install the pointer into a black object,
+// this will shade it.
+//
+// 3. Once a goroutine's stack is black, the shade(ptr) becomes
+// unnecessary. shade(ptr) prevents hiding an object by moving it from
+// the stack to the heap, but this requires first having a pointer
+// hidden on the stack. Immediately after a stack is scanned, it only
+// points to shaded objects, so it's not hiding anything, and the
+// shade(*slot) prevents it from hiding any other pointers on its
+// stack.
+//
+// For a detailed description of this barrier and proof of
+// correctness, see https://github.com/golang/proposal/blob/master/design/17503-eliminate-rescan.md
+//
+//
+//
+// Dealing with memory ordering:
+//
+// Both the Yuasa and Dijkstra barriers can be made conditional on the
+// color of the object containing the slot. We chose not to make these
+// conditional because the cost of ensuring that the object holding
+// the slot doesn't concurrently change color without the mutator
+// noticing seems prohibitive.
+//
+// Consider the following example where the mutator writes into
+// a slot and then loads the slot's mark bit while the GC thread
+// writes to the slot's mark bit and then as part of scanning reads
+// the slot.
+//
+// Initially both [slot] and [slotmark] are 0 (nil)
+// Mutator thread GC thread
+// st [slot], ptr st [slotmark], 1
+//
+// ld r1, [slotmark] ld r2, [slot]
+//
+// Without an expensive memory barrier between the st and the ld, the final
+// result on most HW (including 386/amd64) can be r1==r2==0. This is a classic
+// example of what can happen when loads are allowed to be reordered with older
+// stores (avoiding such reorderings lies at the heart of the classic
+// Peterson/Dekker algorithms for mutual exclusion). Rather than require memory
+// barriers, which will slow down both the mutator and the GC, we always grey
+// the ptr object regardless of the slot's color.
+//
+// Another place where we intentionally omit memory barriers is when
+// accessing mheap_.arena_used to check if a pointer points into the
+// heap. On relaxed memory machines, it's possible for a mutator to
+// extend the size of the heap by updating arena_used, allocate an
+// object from this new region, and publish a pointer to that object,
+// but for tracing running on another processor to observe the pointer
+// but use the old value of arena_used. In this case, tracing will not
+// mark the object, even though it's reachable. However, the mutator
+// is guaranteed to execute a write barrier when it publishes the
+// pointer, so it will take care of marking the object. A general
+// consequence of this is that the garbage collector may cache the
+// value of mheap_.arena_used. (See issue #9984.)
+//
+//
+// Stack writes:
+//
+// The compiler omits write barriers for writes to the current frame,
+// but if a stack pointer has been passed down the call stack, the
+// compiler will generate a write barrier for writes through that
+// pointer (because it doesn't know it's not a heap pointer).
+//
+//
+// Global writes:
+//
+// The Go garbage collector requires write barriers when heap pointers
+// are stored in globals. Many garbage collectors ignore writes to
+// globals and instead pick up global -> heap pointers during
+// termination. This increases pause time, so we instead rely on write
+// barriers for writes to globals so that we don't have to rescan
+// global during mark termination.
+//
+//
+// Publication ordering:
+//
+// The write barrier is *pre-publication*, meaning that the write
+// barrier happens prior to the *slot = ptr write that may make ptr
+// reachable by some goroutine that currently cannot reach it.
+//
+//
+// Signal handler pointer writes:
+//
+// In general, the signal handler cannot safely invoke the write
+// barrier because it may run without a P or even during the write
+// barrier.
+//
+// There is exactly one exception: profbuf.go omits a barrier during
+// signal handler profile logging. That's safe only because of the
+// deletion barrier. See profbuf.go for a detailed argument. If we
+// remove the deletion barrier, we'll have to work out a new way to
+// handle the profile logging.
+
+// typedmemmove copies a value of type typ to dst from src.
+// Must be nosplit, see #16026.
+//
+// TODO: Perfect for go:nosplitrec since we can't have a safe point
+// anywhere in the bulk barrier or memmove.
+//
+//go:nosplit
+func typedmemmove(typ *abi.Type, dst, src unsafe.Pointer) {
+ if dst == src {
+ return
+ }
+ if writeBarrier.needed && typ.PtrBytes != 0 {
+ bulkBarrierPreWrite(uintptr(dst), uintptr(src), typ.PtrBytes)
+ }
+ // There's a race here: if some other goroutine can write to
+ // src, it may change some pointer in src after we've
+ // performed the write barrier but before we perform the
+ // memory copy. This safe because the write performed by that
+ // other goroutine must also be accompanied by a write
+ // barrier, so at worst we've unnecessarily greyed the old
+ // pointer that was in src.
+ memmove(dst, src, typ.Size_)
+ if goexperiment.CgoCheck2 {
+ cgoCheckMemmove2(typ, dst, src, 0, typ.Size_)
+ }
+}
+
+// wbZero performs the write barrier operations necessary before
+// zeroing a region of memory at address dst of type typ.
+// Does not actually do the zeroing.
+//
+//go:nowritebarrierrec
+//go:nosplit
+func wbZero(typ *_type, dst unsafe.Pointer) {
+ bulkBarrierPreWrite(uintptr(dst), 0, typ.PtrBytes)
+}
+
+// wbMove performs the write barrier operations necessary before
+// copying a region of memory from src to dst of type typ.
+// Does not actually do the copying.
+//
+//go:nowritebarrierrec
+//go:nosplit
+func wbMove(typ *_type, dst, src unsafe.Pointer) {
+ bulkBarrierPreWrite(uintptr(dst), uintptr(src), typ.PtrBytes)
+}
+
+//go:linkname reflect_typedmemmove reflect.typedmemmove
+func reflect_typedmemmove(typ *_type, dst, src unsafe.Pointer) {
+ if raceenabled {
+ raceWriteObjectPC(typ, dst, getcallerpc(), abi.FuncPCABIInternal(reflect_typedmemmove))
+ raceReadObjectPC(typ, src, getcallerpc(), abi.FuncPCABIInternal(reflect_typedmemmove))
+ }
+ if msanenabled {
+ msanwrite(dst, typ.Size_)
+ msanread(src, typ.Size_)
+ }
+ if asanenabled {
+ asanwrite(dst, typ.Size_)
+ asanread(src, typ.Size_)
+ }
+ typedmemmove(typ, dst, src)
+}
+
+//go:linkname reflectlite_typedmemmove internal/reflectlite.typedmemmove
+func reflectlite_typedmemmove(typ *_type, dst, src unsafe.Pointer) {
+ reflect_typedmemmove(typ, dst, src)
+}
+
+// reflectcallmove is invoked by reflectcall to copy the return values
+// out of the stack and into the heap, invoking the necessary write
+// barriers. dst, src, and size describe the return value area to
+// copy. typ describes the entire frame (not just the return values).
+// typ may be nil, which indicates write barriers are not needed.
+//
+// It must be nosplit and must only call nosplit functions because the
+// stack map of reflectcall is wrong.
+//
+//go:nosplit
+func reflectcallmove(typ *_type, dst, src unsafe.Pointer, size uintptr, regs *abi.RegArgs) {
+ if writeBarrier.needed && typ != nil && typ.PtrBytes != 0 && size >= goarch.PtrSize {
+ bulkBarrierPreWrite(uintptr(dst), uintptr(src), size)
+ }
+ memmove(dst, src, size)
+
+ // Move pointers returned in registers to a place where the GC can see them.
+ for i := range regs.Ints {
+ if regs.ReturnIsPtr.Get(i) {
+ regs.Ptrs[i] = unsafe.Pointer(regs.Ints[i])
+ }
+ }
+}
+
+//go:nosplit
+func typedslicecopy(typ *_type, dstPtr unsafe.Pointer, dstLen int, srcPtr unsafe.Pointer, srcLen int) int {
+ n := dstLen
+ if n > srcLen {
+ n = srcLen
+ }
+ if n == 0 {
+ return 0
+ }
+
+ // The compiler emits calls to typedslicecopy before
+ // instrumentation runs, so unlike the other copying and
+ // assignment operations, it's not instrumented in the calling
+ // code and needs its own instrumentation.
+ if raceenabled {
+ callerpc := getcallerpc()
+ pc := abi.FuncPCABIInternal(slicecopy)
+ racewriterangepc(dstPtr, uintptr(n)*typ.Size_, callerpc, pc)
+ racereadrangepc(srcPtr, uintptr(n)*typ.Size_, callerpc, pc)
+ }
+ if msanenabled {
+ msanwrite(dstPtr, uintptr(n)*typ.Size_)
+ msanread(srcPtr, uintptr(n)*typ.Size_)
+ }
+ if asanenabled {
+ asanwrite(dstPtr, uintptr(n)*typ.Size_)
+ asanread(srcPtr, uintptr(n)*typ.Size_)
+ }
+
+ if goexperiment.CgoCheck2 {
+ cgoCheckSliceCopy(typ, dstPtr, srcPtr, n)
+ }
+
+ if dstPtr == srcPtr {
+ return n
+ }
+
+ // Note: No point in checking typ.PtrBytes here:
+ // compiler only emits calls to typedslicecopy for types with pointers,
+ // and growslice and reflect_typedslicecopy check for pointers
+ // before calling typedslicecopy.
+ size := uintptr(n) * typ.Size_
+ if writeBarrier.needed {
+ pwsize := size - typ.Size_ + typ.PtrBytes
+ bulkBarrierPreWrite(uintptr(dstPtr), uintptr(srcPtr), pwsize)
+ }
+ // See typedmemmove for a discussion of the race between the
+ // barrier and memmove.
+ memmove(dstPtr, srcPtr, size)
+ return n
+}
+
+//go:linkname reflect_typedslicecopy reflect.typedslicecopy
+func reflect_typedslicecopy(elemType *_type, dst, src slice) int {
+ if elemType.PtrBytes == 0 {
+ return slicecopy(dst.array, dst.len, src.array, src.len, elemType.Size_)
+ }
+ return typedslicecopy(elemType, dst.array, dst.len, src.array, src.len)
+}
+
+// typedmemclr clears the typed memory at ptr with type typ. The
+// memory at ptr must already be initialized (and hence in type-safe
+// state). If the memory is being initialized for the first time, see
+// memclrNoHeapPointers.
+//
+// If the caller knows that typ has pointers, it can alternatively
+// call memclrHasPointers.
+//
+// TODO: A "go:nosplitrec" annotation would be perfect for this.
+//
+//go:nosplit
+func typedmemclr(typ *_type, ptr unsafe.Pointer) {
+ if writeBarrier.needed && typ.PtrBytes != 0 {
+ bulkBarrierPreWrite(uintptr(ptr), 0, typ.PtrBytes)
+ }
+ memclrNoHeapPointers(ptr, typ.Size_)
+}
+
+//go:linkname reflect_typedmemclr reflect.typedmemclr
+func reflect_typedmemclr(typ *_type, ptr unsafe.Pointer) {
+ typedmemclr(typ, ptr)
+}
+
+//go:linkname reflect_typedmemclrpartial reflect.typedmemclrpartial
+func reflect_typedmemclrpartial(typ *_type, ptr unsafe.Pointer, off, size uintptr) {
+ if writeBarrier.needed && typ.PtrBytes != 0 {
+ bulkBarrierPreWrite(uintptr(ptr), 0, size)
+ }
+ memclrNoHeapPointers(ptr, size)
+}
+
+//go:linkname reflect_typedarrayclear reflect.typedarrayclear
+func reflect_typedarrayclear(typ *_type, ptr unsafe.Pointer, len int) {
+ size := typ.Size_ * uintptr(len)
+ if writeBarrier.needed && typ.PtrBytes != 0 {
+ bulkBarrierPreWrite(uintptr(ptr), 0, size)
+ }
+ memclrNoHeapPointers(ptr, size)
+}
+
+// memclrHasPointers clears n bytes of typed memory starting at ptr.
+// The caller must ensure that the type of the object at ptr has
+// pointers, usually by checking typ.PtrBytes. However, ptr
+// does not have to point to the start of the allocation.
+//
+//go:nosplit
+func memclrHasPointers(ptr unsafe.Pointer, n uintptr) {
+ bulkBarrierPreWrite(uintptr(ptr), 0, n)
+ memclrNoHeapPointers(ptr, n)
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mbitmap.go b/contrib/go/_std_1.21/src/runtime/mbitmap.go
new file mode 100644
index 0000000000..a242872884
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mbitmap.go
@@ -0,0 +1,1501 @@
+// Copyright 2009 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.
+
+// Garbage collector: type and heap bitmaps.
+//
+// Stack, data, and bss bitmaps
+//
+// Stack frames and global variables in the data and bss sections are
+// described by bitmaps with 1 bit per pointer-sized word. A "1" bit
+// means the word is a live pointer to be visited by the GC (referred to
+// as "pointer"). A "0" bit means the word should be ignored by GC
+// (referred to as "scalar", though it could be a dead pointer value).
+//
+// Heap bitmap
+//
+// The heap bitmap comprises 1 bit for each pointer-sized word in the heap,
+// recording whether a pointer is stored in that word or not. This bitmap
+// is stored in the heapArena metadata backing each heap arena.
+// That is, if ha is the heapArena for the arena starting at "start",
+// then ha.bitmap[0] holds the 64 bits for the 64 words "start"
+// through start+63*ptrSize, ha.bitmap[1] holds the entries for
+// start+64*ptrSize through start+127*ptrSize, and so on.
+// Bits correspond to words in little-endian order. ha.bitmap[0]&1 represents
+// the word at "start", ha.bitmap[0]>>1&1 represents the word at start+8, etc.
+// (For 32-bit platforms, s/64/32/.)
+//
+// We also keep a noMorePtrs bitmap which allows us to stop scanning
+// the heap bitmap early in certain situations. If ha.noMorePtrs[i]>>j&1
+// is 1, then the object containing the last word described by ha.bitmap[8*i+j]
+// has no more pointers beyond those described by ha.bitmap[8*i+j].
+// If ha.noMorePtrs[i]>>j&1 is set, the entries in ha.bitmap[8*i+j+1] and
+// beyond must all be zero until the start of the next object.
+//
+// The bitmap for noscan spans is set to all zero at span allocation time.
+//
+// The bitmap for unallocated objects in scannable spans is not maintained
+// (can be junk).
+
+package runtime
+
+import (
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// addb returns the byte pointer p+n.
+//
+//go:nowritebarrier
+//go:nosplit
+func addb(p *byte, n uintptr) *byte {
+ // Note: wrote out full expression instead of calling add(p, n)
+ // to reduce the number of temporaries generated by the
+ // compiler for this trivial expression during inlining.
+ return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + n))
+}
+
+// subtractb returns the byte pointer p-n.
+//
+//go:nowritebarrier
+//go:nosplit
+func subtractb(p *byte, n uintptr) *byte {
+ // Note: wrote out full expression instead of calling add(p, -n)
+ // to reduce the number of temporaries generated by the
+ // compiler for this trivial expression during inlining.
+ return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) - n))
+}
+
+// add1 returns the byte pointer p+1.
+//
+//go:nowritebarrier
+//go:nosplit
+func add1(p *byte) *byte {
+ // Note: wrote out full expression instead of calling addb(p, 1)
+ // to reduce the number of temporaries generated by the
+ // compiler for this trivial expression during inlining.
+ return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + 1))
+}
+
+// subtract1 returns the byte pointer p-1.
+//
+// nosplit because it is used during write barriers and must not be preempted.
+//
+//go:nowritebarrier
+//go:nosplit
+func subtract1(p *byte) *byte {
+ // Note: wrote out full expression instead of calling subtractb(p, 1)
+ // to reduce the number of temporaries generated by the
+ // compiler for this trivial expression during inlining.
+ return (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) - 1))
+}
+
+// markBits provides access to the mark bit for an object in the heap.
+// bytep points to the byte holding the mark bit.
+// mask is a byte with a single bit set that can be &ed with *bytep
+// to see if the bit has been set.
+// *m.byte&m.mask != 0 indicates the mark bit is set.
+// index can be used along with span information to generate
+// the address of the object in the heap.
+// We maintain one set of mark bits for allocation and one for
+// marking purposes.
+type markBits struct {
+ bytep *uint8
+ mask uint8
+ index uintptr
+}
+
+//go:nosplit
+func (s *mspan) allocBitsForIndex(allocBitIndex uintptr) markBits {
+ bytep, mask := s.allocBits.bitp(allocBitIndex)
+ return markBits{bytep, mask, allocBitIndex}
+}
+
+// refillAllocCache takes 8 bytes s.allocBits starting at whichByte
+// and negates them so that ctz (count trailing zeros) instructions
+// can be used. It then places these 8 bytes into the cached 64 bit
+// s.allocCache.
+func (s *mspan) refillAllocCache(whichByte uintptr) {
+ bytes := (*[8]uint8)(unsafe.Pointer(s.allocBits.bytep(whichByte)))
+ aCache := uint64(0)
+ aCache |= uint64(bytes[0])
+ aCache |= uint64(bytes[1]) << (1 * 8)
+ aCache |= uint64(bytes[2]) << (2 * 8)
+ aCache |= uint64(bytes[3]) << (3 * 8)
+ aCache |= uint64(bytes[4]) << (4 * 8)
+ aCache |= uint64(bytes[5]) << (5 * 8)
+ aCache |= uint64(bytes[6]) << (6 * 8)
+ aCache |= uint64(bytes[7]) << (7 * 8)
+ s.allocCache = ^aCache
+}
+
+// nextFreeIndex returns the index of the next free object in s at
+// or after s.freeindex.
+// There are hardware instructions that can be used to make this
+// faster if profiling warrants it.
+func (s *mspan) nextFreeIndex() uintptr {
+ sfreeindex := s.freeindex
+ snelems := s.nelems
+ if sfreeindex == snelems {
+ return sfreeindex
+ }
+ if sfreeindex > snelems {
+ throw("s.freeindex > s.nelems")
+ }
+
+ aCache := s.allocCache
+
+ bitIndex := sys.TrailingZeros64(aCache)
+ for bitIndex == 64 {
+ // Move index to start of next cached bits.
+ sfreeindex = (sfreeindex + 64) &^ (64 - 1)
+ if sfreeindex >= snelems {
+ s.freeindex = snelems
+ return snelems
+ }
+ whichByte := sfreeindex / 8
+ // Refill s.allocCache with the next 64 alloc bits.
+ s.refillAllocCache(whichByte)
+ aCache = s.allocCache
+ bitIndex = sys.TrailingZeros64(aCache)
+ // nothing available in cached bits
+ // grab the next 8 bytes and try again.
+ }
+ result := sfreeindex + uintptr(bitIndex)
+ if result >= snelems {
+ s.freeindex = snelems
+ return snelems
+ }
+
+ s.allocCache >>= uint(bitIndex + 1)
+ sfreeindex = result + 1
+
+ if sfreeindex%64 == 0 && sfreeindex != snelems {
+ // We just incremented s.freeindex so it isn't 0.
+ // As each 1 in s.allocCache was encountered and used for allocation
+ // it was shifted away. At this point s.allocCache contains all 0s.
+ // Refill s.allocCache so that it corresponds
+ // to the bits at s.allocBits starting at s.freeindex.
+ whichByte := sfreeindex / 8
+ s.refillAllocCache(whichByte)
+ }
+ s.freeindex = sfreeindex
+ return result
+}
+
+// isFree reports whether the index'th object in s is unallocated.
+//
+// The caller must ensure s.state is mSpanInUse, and there must have
+// been no preemption points since ensuring this (which could allow a
+// GC transition, which would allow the state to change).
+func (s *mspan) isFree(index uintptr) bool {
+ if index < s.freeIndexForScan {
+ return false
+ }
+ bytep, mask := s.allocBits.bitp(index)
+ return *bytep&mask == 0
+}
+
+// divideByElemSize returns n/s.elemsize.
+// n must be within [0, s.npages*_PageSize),
+// or may be exactly s.npages*_PageSize
+// if s.elemsize is from sizeclasses.go.
+//
+// nosplit, because it is called by objIndex, which is nosplit
+//
+//go:nosplit
+func (s *mspan) divideByElemSize(n uintptr) uintptr {
+ const doubleCheck = false
+
+ // See explanation in mksizeclasses.go's computeDivMagic.
+ q := uintptr((uint64(n) * uint64(s.divMul)) >> 32)
+
+ if doubleCheck && q != n/s.elemsize {
+ println(n, "/", s.elemsize, "should be", n/s.elemsize, "but got", q)
+ throw("bad magic division")
+ }
+ return q
+}
+
+// nosplit, because it is called by other nosplit code like findObject
+//
+//go:nosplit
+func (s *mspan) objIndex(p uintptr) uintptr {
+ return s.divideByElemSize(p - s.base())
+}
+
+func markBitsForAddr(p uintptr) markBits {
+ s := spanOf(p)
+ objIndex := s.objIndex(p)
+ return s.markBitsForIndex(objIndex)
+}
+
+func (s *mspan) markBitsForIndex(objIndex uintptr) markBits {
+ bytep, mask := s.gcmarkBits.bitp(objIndex)
+ return markBits{bytep, mask, objIndex}
+}
+
+func (s *mspan) markBitsForBase() markBits {
+ return markBits{&s.gcmarkBits.x, uint8(1), 0}
+}
+
+// isMarked reports whether mark bit m is set.
+func (m markBits) isMarked() bool {
+ return *m.bytep&m.mask != 0
+}
+
+// setMarked sets the marked bit in the markbits, atomically.
+func (m markBits) setMarked() {
+ // Might be racing with other updates, so use atomic update always.
+ // We used to be clever here and use a non-atomic update in certain
+ // cases, but it's not worth the risk.
+ atomic.Or8(m.bytep, m.mask)
+}
+
+// setMarkedNonAtomic sets the marked bit in the markbits, non-atomically.
+func (m markBits) setMarkedNonAtomic() {
+ *m.bytep |= m.mask
+}
+
+// clearMarked clears the marked bit in the markbits, atomically.
+func (m markBits) clearMarked() {
+ // Might be racing with other updates, so use atomic update always.
+ // We used to be clever here and use a non-atomic update in certain
+ // cases, but it's not worth the risk.
+ atomic.And8(m.bytep, ^m.mask)
+}
+
+// markBitsForSpan returns the markBits for the span base address base.
+func markBitsForSpan(base uintptr) (mbits markBits) {
+ mbits = markBitsForAddr(base)
+ if mbits.mask != 1 {
+ throw("markBitsForSpan: unaligned start")
+ }
+ return mbits
+}
+
+// advance advances the markBits to the next object in the span.
+func (m *markBits) advance() {
+ if m.mask == 1<<7 {
+ m.bytep = (*uint8)(unsafe.Pointer(uintptr(unsafe.Pointer(m.bytep)) + 1))
+ m.mask = 1
+ } else {
+ m.mask = m.mask << 1
+ }
+ m.index++
+}
+
+// clobberdeadPtr is a special value that is used by the compiler to
+// clobber dead stack slots, when -clobberdead flag is set.
+const clobberdeadPtr = uintptr(0xdeaddead | 0xdeaddead<<((^uintptr(0)>>63)*32))
+
+// badPointer throws bad pointer in heap panic.
+func badPointer(s *mspan, p, refBase, refOff uintptr) {
+ // Typically this indicates an incorrect use
+ // of unsafe or cgo to store a bad pointer in
+ // the Go heap. It may also indicate a runtime
+ // bug.
+ //
+ // TODO(austin): We could be more aggressive
+ // and detect pointers to unallocated objects
+ // in allocated spans.
+ printlock()
+ print("runtime: pointer ", hex(p))
+ if s != nil {
+ state := s.state.get()
+ if state != mSpanInUse {
+ print(" to unallocated span")
+ } else {
+ print(" to unused region of span")
+ }
+ print(" span.base()=", hex(s.base()), " span.limit=", hex(s.limit), " span.state=", state)
+ }
+ print("\n")
+ if refBase != 0 {
+ print("runtime: found in object at *(", hex(refBase), "+", hex(refOff), ")\n")
+ gcDumpObject("object", refBase, refOff)
+ }
+ getg().m.traceback = 2
+ throw("found bad pointer in Go heap (incorrect use of unsafe or cgo?)")
+}
+
+// findObject returns the base address for the heap object containing
+// the address p, the object's span, and the index of the object in s.
+// If p does not point into a heap object, it returns base == 0.
+//
+// If p points is an invalid heap pointer and debug.invalidptr != 0,
+// findObject panics.
+//
+// refBase and refOff optionally give the base address of the object
+// in which the pointer p was found and the byte offset at which it
+// was found. These are used for error reporting.
+//
+// It is nosplit so it is safe for p to be a pointer to the current goroutine's stack.
+// Since p is a uintptr, it would not be adjusted if the stack were to move.
+//
+//go:nosplit
+func findObject(p, refBase, refOff uintptr) (base uintptr, s *mspan, objIndex uintptr) {
+ s = spanOf(p)
+ // If s is nil, the virtual address has never been part of the heap.
+ // This pointer may be to some mmap'd region, so we allow it.
+ if s == nil {
+ if (GOARCH == "amd64" || GOARCH == "arm64") && p == clobberdeadPtr && debug.invalidptr != 0 {
+ // Crash if clobberdeadPtr is seen. Only on AMD64 and ARM64 for now,
+ // as they are the only platform where compiler's clobberdead mode is
+ // implemented. On these platforms clobberdeadPtr cannot be a valid address.
+ badPointer(s, p, refBase, refOff)
+ }
+ return
+ }
+ // If p is a bad pointer, it may not be in s's bounds.
+ //
+ // Check s.state to synchronize with span initialization
+ // before checking other fields. See also spanOfHeap.
+ if state := s.state.get(); state != mSpanInUse || p < s.base() || p >= s.limit {
+ // Pointers into stacks are also ok, the runtime manages these explicitly.
+ if state == mSpanManual {
+ return
+ }
+ // The following ensures that we are rigorous about what data
+ // structures hold valid pointers.
+ if debug.invalidptr != 0 {
+ badPointer(s, p, refBase, refOff)
+ }
+ return
+ }
+
+ objIndex = s.objIndex(p)
+ base = s.base() + objIndex*s.elemsize
+ return
+}
+
+// reflect_verifyNotInHeapPtr reports whether converting the not-in-heap pointer into a unsafe.Pointer is ok.
+//
+//go:linkname reflect_verifyNotInHeapPtr reflect.verifyNotInHeapPtr
+func reflect_verifyNotInHeapPtr(p uintptr) bool {
+ // Conversion to a pointer is ok as long as findObject above does not call badPointer.
+ // Since we're already promised that p doesn't point into the heap, just disallow heap
+ // pointers and the special clobbered pointer.
+ return spanOf(p) == nil && p != clobberdeadPtr
+}
+
+const ptrBits = 8 * goarch.PtrSize
+
+// heapBits provides access to the bitmap bits for a single heap word.
+// The methods on heapBits take value receivers so that the compiler
+// can more easily inline calls to those methods and registerize the
+// struct fields independently.
+type heapBits struct {
+ // heapBits will report on pointers in the range [addr,addr+size).
+ // The low bit of mask contains the pointerness of the word at addr
+ // (assuming valid>0).
+ addr, size uintptr
+
+ // The next few pointer bits representing words starting at addr.
+ // Those bits already returned by next() are zeroed.
+ mask uintptr
+ // Number of bits in mask that are valid. mask is always less than 1<<valid.
+ valid uintptr
+}
+
+// heapBitsForAddr returns the heapBits for the address addr.
+// The caller must ensure [addr,addr+size) is in an allocated span.
+// In particular, be careful not to point past the end of an object.
+//
+// nosplit because it is used during write barriers and must not be preempted.
+//
+//go:nosplit
+func heapBitsForAddr(addr, size uintptr) heapBits {
+ // Find arena
+ ai := arenaIndex(addr)
+ ha := mheap_.arenas[ai.l1()][ai.l2()]
+
+ // Word index in arena.
+ word := addr / goarch.PtrSize % heapArenaWords
+
+ // Word index and bit offset in bitmap array.
+ idx := word / ptrBits
+ off := word % ptrBits
+
+ // Grab relevant bits of bitmap.
+ mask := ha.bitmap[idx] >> off
+ valid := ptrBits - off
+
+ // Process depending on where the object ends.
+ nptr := size / goarch.PtrSize
+ if nptr < valid {
+ // Bits for this object end before the end of this bitmap word.
+ // Squash bits for the following objects.
+ mask &= 1<<(nptr&(ptrBits-1)) - 1
+ valid = nptr
+ } else if nptr == valid {
+ // Bits for this object end at exactly the end of this bitmap word.
+ // All good.
+ } else {
+ // Bits for this object extend into the next bitmap word. See if there
+ // may be any pointers recorded there.
+ if uintptr(ha.noMorePtrs[idx/8])>>(idx%8)&1 != 0 {
+ // No more pointers in this object after this bitmap word.
+ // Update size so we know not to look there.
+ size = valid * goarch.PtrSize
+ }
+ }
+
+ return heapBits{addr: addr, size: size, mask: mask, valid: valid}
+}
+
+// Returns the (absolute) address of the next known pointer and
+// a heapBits iterator representing any remaining pointers.
+// If there are no more pointers, returns address 0.
+// Note that next does not modify h. The caller must record the result.
+//
+// nosplit because it is used during write barriers and must not be preempted.
+//
+//go:nosplit
+func (h heapBits) next() (heapBits, uintptr) {
+ for {
+ if h.mask != 0 {
+ var i int
+ if goarch.PtrSize == 8 {
+ i = sys.TrailingZeros64(uint64(h.mask))
+ } else {
+ i = sys.TrailingZeros32(uint32(h.mask))
+ }
+ h.mask ^= uintptr(1) << (i & (ptrBits - 1))
+ return h, h.addr + uintptr(i)*goarch.PtrSize
+ }
+
+ // Skip words that we've already processed.
+ h.addr += h.valid * goarch.PtrSize
+ h.size -= h.valid * goarch.PtrSize
+ if h.size == 0 {
+ return h, 0 // no more pointers
+ }
+
+ // Grab more bits and try again.
+ h = heapBitsForAddr(h.addr, h.size)
+ }
+}
+
+// nextFast is like next, but can return 0 even when there are more pointers
+// to be found. Callers should call next if nextFast returns 0 as its second
+// return value.
+//
+// if addr, h = h.nextFast(); addr == 0 {
+// if addr, h = h.next(); addr == 0 {
+// ... no more pointers ...
+// }
+// }
+// ... process pointer at addr ...
+//
+// nextFast is designed to be inlineable.
+//
+//go:nosplit
+func (h heapBits) nextFast() (heapBits, uintptr) {
+ // TESTQ/JEQ
+ if h.mask == 0 {
+ return h, 0
+ }
+ // BSFQ
+ var i int
+ if goarch.PtrSize == 8 {
+ i = sys.TrailingZeros64(uint64(h.mask))
+ } else {
+ i = sys.TrailingZeros32(uint32(h.mask))
+ }
+ // BTCQ
+ h.mask ^= uintptr(1) << (i & (ptrBits - 1))
+ // LEAQ (XX)(XX*8)
+ return h, h.addr + uintptr(i)*goarch.PtrSize
+}
+
+// bulkBarrierPreWrite executes a write barrier
+// for every pointer slot in the memory range [src, src+size),
+// using pointer/scalar information from [dst, dst+size).
+// This executes the write barriers necessary before a memmove.
+// src, dst, and size must be pointer-aligned.
+// The range [dst, dst+size) must lie within a single object.
+// It does not perform the actual writes.
+//
+// As a special case, src == 0 indicates that this is being used for a
+// memclr. bulkBarrierPreWrite will pass 0 for the src of each write
+// barrier.
+//
+// Callers should call bulkBarrierPreWrite immediately before
+// calling memmove(dst, src, size). This function is marked nosplit
+// to avoid being preempted; the GC must not stop the goroutine
+// between the memmove and the execution of the barriers.
+// The caller is also responsible for cgo pointer checks if this
+// may be writing Go pointers into non-Go memory.
+//
+// The pointer bitmap is not maintained for allocations containing
+// no pointers at all; any caller of bulkBarrierPreWrite must first
+// make sure the underlying allocation contains pointers, usually
+// by checking typ.PtrBytes.
+//
+// Callers must perform cgo checks if goexperiment.CgoCheck2.
+//
+//go:nosplit
+func bulkBarrierPreWrite(dst, src, size uintptr) {
+ if (dst|src|size)&(goarch.PtrSize-1) != 0 {
+ throw("bulkBarrierPreWrite: unaligned arguments")
+ }
+ if !writeBarrier.needed {
+ return
+ }
+ if s := spanOf(dst); s == nil {
+ // If dst is a global, use the data or BSS bitmaps to
+ // execute write barriers.
+ for _, datap := range activeModules() {
+ if datap.data <= dst && dst < datap.edata {
+ bulkBarrierBitmap(dst, src, size, dst-datap.data, datap.gcdatamask.bytedata)
+ return
+ }
+ }
+ for _, datap := range activeModules() {
+ if datap.bss <= dst && dst < datap.ebss {
+ bulkBarrierBitmap(dst, src, size, dst-datap.bss, datap.gcbssmask.bytedata)
+ return
+ }
+ }
+ return
+ } else if s.state.get() != mSpanInUse || dst < s.base() || s.limit <= dst {
+ // dst was heap memory at some point, but isn't now.
+ // It can't be a global. It must be either our stack,
+ // or in the case of direct channel sends, it could be
+ // another stack. Either way, no need for barriers.
+ // This will also catch if dst is in a freed span,
+ // though that should never have.
+ return
+ }
+
+ buf := &getg().m.p.ptr().wbBuf
+ h := heapBitsForAddr(dst, size)
+ if src == 0 {
+ for {
+ var addr uintptr
+ if h, addr = h.next(); addr == 0 {
+ break
+ }
+ dstx := (*uintptr)(unsafe.Pointer(addr))
+ p := buf.get1()
+ p[0] = *dstx
+ }
+ } else {
+ for {
+ var addr uintptr
+ if h, addr = h.next(); addr == 0 {
+ break
+ }
+ dstx := (*uintptr)(unsafe.Pointer(addr))
+ srcx := (*uintptr)(unsafe.Pointer(src + (addr - dst)))
+ p := buf.get2()
+ p[0] = *dstx
+ p[1] = *srcx
+ }
+ }
+}
+
+// bulkBarrierPreWriteSrcOnly is like bulkBarrierPreWrite but
+// does not execute write barriers for [dst, dst+size).
+//
+// In addition to the requirements of bulkBarrierPreWrite
+// callers need to ensure [dst, dst+size) is zeroed.
+//
+// This is used for special cases where e.g. dst was just
+// created and zeroed with malloc.
+//
+//go:nosplit
+func bulkBarrierPreWriteSrcOnly(dst, src, size uintptr) {
+ if (dst|src|size)&(goarch.PtrSize-1) != 0 {
+ throw("bulkBarrierPreWrite: unaligned arguments")
+ }
+ if !writeBarrier.needed {
+ return
+ }
+ buf := &getg().m.p.ptr().wbBuf
+ h := heapBitsForAddr(dst, size)
+ for {
+ var addr uintptr
+ if h, addr = h.next(); addr == 0 {
+ break
+ }
+ srcx := (*uintptr)(unsafe.Pointer(addr - dst + src))
+ p := buf.get1()
+ p[0] = *srcx
+ }
+}
+
+// bulkBarrierBitmap executes write barriers for copying from [src,
+// src+size) to [dst, dst+size) using a 1-bit pointer bitmap. src is
+// assumed to start maskOffset bytes into the data covered by the
+// bitmap in bits (which may not be a multiple of 8).
+//
+// This is used by bulkBarrierPreWrite for writes to data and BSS.
+//
+//go:nosplit
+func bulkBarrierBitmap(dst, src, size, maskOffset uintptr, bits *uint8) {
+ word := maskOffset / goarch.PtrSize
+ bits = addb(bits, word/8)
+ mask := uint8(1) << (word % 8)
+
+ buf := &getg().m.p.ptr().wbBuf
+ for i := uintptr(0); i < size; i += goarch.PtrSize {
+ if mask == 0 {
+ bits = addb(bits, 1)
+ if *bits == 0 {
+ // Skip 8 words.
+ i += 7 * goarch.PtrSize
+ continue
+ }
+ mask = 1
+ }
+ if *bits&mask != 0 {
+ dstx := (*uintptr)(unsafe.Pointer(dst + i))
+ if src == 0 {
+ p := buf.get1()
+ p[0] = *dstx
+ } else {
+ srcx := (*uintptr)(unsafe.Pointer(src + i))
+ p := buf.get2()
+ p[0] = *dstx
+ p[1] = *srcx
+ }
+ }
+ mask <<= 1
+ }
+}
+
+// typeBitsBulkBarrier executes a write barrier for every
+// pointer that would be copied from [src, src+size) to [dst,
+// dst+size) by a memmove using the type bitmap to locate those
+// pointer slots.
+//
+// The type typ must correspond exactly to [src, src+size) and [dst, dst+size).
+// dst, src, and size must be pointer-aligned.
+// The type typ must have a plain bitmap, not a GC program.
+// The only use of this function is in channel sends, and the
+// 64 kB channel element limit takes care of this for us.
+//
+// Must not be preempted because it typically runs right before memmove,
+// and the GC must observe them as an atomic action.
+//
+// Callers must perform cgo checks if goexperiment.CgoCheck2.
+//
+//go:nosplit
+func typeBitsBulkBarrier(typ *_type, dst, src, size uintptr) {
+ if typ == nil {
+ throw("runtime: typeBitsBulkBarrier without type")
+ }
+ if typ.Size_ != size {
+ println("runtime: typeBitsBulkBarrier with type ", toRType(typ).string(), " of size ", typ.Size_, " but memory size", size)
+ throw("runtime: invalid typeBitsBulkBarrier")
+ }
+ if typ.Kind_&kindGCProg != 0 {
+ println("runtime: typeBitsBulkBarrier with type ", toRType(typ).string(), " with GC prog")
+ throw("runtime: invalid typeBitsBulkBarrier")
+ }
+ if !writeBarrier.needed {
+ return
+ }
+ ptrmask := typ.GCData
+ buf := &getg().m.p.ptr().wbBuf
+ var bits uint32
+ for i := uintptr(0); i < typ.PtrBytes; i += goarch.PtrSize {
+ if i&(goarch.PtrSize*8-1) == 0 {
+ bits = uint32(*ptrmask)
+ ptrmask = addb(ptrmask, 1)
+ } else {
+ bits = bits >> 1
+ }
+ if bits&1 != 0 {
+ dstx := (*uintptr)(unsafe.Pointer(dst + i))
+ srcx := (*uintptr)(unsafe.Pointer(src + i))
+ p := buf.get2()
+ p[0] = *dstx
+ p[1] = *srcx
+ }
+ }
+}
+
+// initHeapBits initializes the heap bitmap for a span.
+// If this is a span of single pointer allocations, it initializes all
+// words to pointer. If force is true, clears all bits.
+func (s *mspan) initHeapBits(forceClear bool) {
+ if forceClear || s.spanclass.noscan() {
+ // Set all the pointer bits to zero. We do this once
+ // when the span is allocated so we don't have to do it
+ // for each object allocation.
+ base := s.base()
+ size := s.npages * pageSize
+ h := writeHeapBitsForAddr(base)
+ h.flush(base, size)
+ return
+ }
+ isPtrs := goarch.PtrSize == 8 && s.elemsize == goarch.PtrSize
+ if !isPtrs {
+ return // nothing to do
+ }
+ h := writeHeapBitsForAddr(s.base())
+ size := s.npages * pageSize
+ nptrs := size / goarch.PtrSize
+ for i := uintptr(0); i < nptrs; i += ptrBits {
+ h = h.write(^uintptr(0), ptrBits)
+ }
+ h.flush(s.base(), size)
+}
+
+// countAlloc returns the number of objects allocated in span s by
+// scanning the allocation bitmap.
+func (s *mspan) countAlloc() int {
+ count := 0
+ bytes := divRoundUp(s.nelems, 8)
+ // Iterate over each 8-byte chunk and count allocations
+ // with an intrinsic. Note that newMarkBits guarantees that
+ // gcmarkBits will be 8-byte aligned, so we don't have to
+ // worry about edge cases, irrelevant bits will simply be zero.
+ for i := uintptr(0); i < bytes; i += 8 {
+ // Extract 64 bits from the byte pointer and get a OnesCount.
+ // Note that the unsafe cast here doesn't preserve endianness,
+ // but that's OK. We only care about how many bits are 1, not
+ // about the order we discover them in.
+ mrkBits := *(*uint64)(unsafe.Pointer(s.gcmarkBits.bytep(i)))
+ count += sys.OnesCount64(mrkBits)
+ }
+ return count
+}
+
+type writeHeapBits struct {
+ addr uintptr // address that the low bit of mask represents the pointer state of.
+ mask uintptr // some pointer bits starting at the address addr.
+ valid uintptr // number of bits in buf that are valid (including low)
+ low uintptr // number of low-order bits to not overwrite
+}
+
+func writeHeapBitsForAddr(addr uintptr) (h writeHeapBits) {
+ // We start writing bits maybe in the middle of a heap bitmap word.
+ // Remember how many bits into the word we started, so we can be sure
+ // not to overwrite the previous bits.
+ h.low = addr / goarch.PtrSize % ptrBits
+
+ // round down to heap word that starts the bitmap word.
+ h.addr = addr - h.low*goarch.PtrSize
+
+ // We don't have any bits yet.
+ h.mask = 0
+ h.valid = h.low
+
+ return
+}
+
+// write appends the pointerness of the next valid pointer slots
+// using the low valid bits of bits. 1=pointer, 0=scalar.
+func (h writeHeapBits) write(bits, valid uintptr) writeHeapBits {
+ if h.valid+valid <= ptrBits {
+ // Fast path - just accumulate the bits.
+ h.mask |= bits << h.valid
+ h.valid += valid
+ return h
+ }
+ // Too many bits to fit in this word. Write the current word
+ // out and move on to the next word.
+
+ data := h.mask | bits<<h.valid // mask for this word
+ h.mask = bits >> (ptrBits - h.valid) // leftover for next word
+ h.valid += valid - ptrBits // have h.valid+valid bits, writing ptrBits of them
+
+ // Flush mask to the memory bitmap.
+ // TODO: figure out how to cache arena lookup.
+ ai := arenaIndex(h.addr)
+ ha := mheap_.arenas[ai.l1()][ai.l2()]
+ idx := h.addr / (ptrBits * goarch.PtrSize) % heapArenaBitmapWords
+ m := uintptr(1)<<h.low - 1
+ ha.bitmap[idx] = ha.bitmap[idx]&m | data
+ // Note: no synchronization required for this write because
+ // the allocator has exclusive access to the page, and the bitmap
+ // entries are all for a single page. Also, visibility of these
+ // writes is guaranteed by the publication barrier in mallocgc.
+
+ // Clear noMorePtrs bit, since we're going to be writing bits
+ // into the following word.
+ ha.noMorePtrs[idx/8] &^= uint8(1) << (idx % 8)
+ // Note: same as above
+
+ // Move to next word of bitmap.
+ h.addr += ptrBits * goarch.PtrSize
+ h.low = 0
+ return h
+}
+
+// Add padding of size bytes.
+func (h writeHeapBits) pad(size uintptr) writeHeapBits {
+ if size == 0 {
+ return h
+ }
+ words := size / goarch.PtrSize
+ for words > ptrBits {
+ h = h.write(0, ptrBits)
+ words -= ptrBits
+ }
+ return h.write(0, words)
+}
+
+// Flush the bits that have been written, and add zeros as needed
+// to cover the full object [addr, addr+size).
+func (h writeHeapBits) flush(addr, size uintptr) {
+ // zeros counts the number of bits needed to represent the object minus the
+ // number of bits we've already written. This is the number of 0 bits
+ // that need to be added.
+ zeros := (addr+size-h.addr)/goarch.PtrSize - h.valid
+
+ // Add zero bits up to the bitmap word boundary
+ if zeros > 0 {
+ z := ptrBits - h.valid
+ if z > zeros {
+ z = zeros
+ }
+ h.valid += z
+ zeros -= z
+ }
+
+ // Find word in bitmap that we're going to write.
+ ai := arenaIndex(h.addr)
+ ha := mheap_.arenas[ai.l1()][ai.l2()]
+ idx := h.addr / (ptrBits * goarch.PtrSize) % heapArenaBitmapWords
+
+ // Write remaining bits.
+ if h.valid != h.low {
+ m := uintptr(1)<<h.low - 1 // don't clear existing bits below "low"
+ m |= ^(uintptr(1)<<h.valid - 1) // don't clear existing bits above "valid"
+ ha.bitmap[idx] = ha.bitmap[idx]&m | h.mask
+ }
+ if zeros == 0 {
+ return
+ }
+
+ // Record in the noMorePtrs map that there won't be any more 1 bits,
+ // so readers can stop early.
+ ha.noMorePtrs[idx/8] |= uint8(1) << (idx % 8)
+
+ // Advance to next bitmap word.
+ h.addr += ptrBits * goarch.PtrSize
+
+ // Continue on writing zeros for the rest of the object.
+ // For standard use of the ptr bits this is not required, as
+ // the bits are read from the beginning of the object. Some uses,
+ // like noscan spans, oblets, bulk write barriers, and cgocheck, might
+ // start mid-object, so these writes are still required.
+ for {
+ // Write zero bits.
+ ai := arenaIndex(h.addr)
+ ha := mheap_.arenas[ai.l1()][ai.l2()]
+ idx := h.addr / (ptrBits * goarch.PtrSize) % heapArenaBitmapWords
+ if zeros < ptrBits {
+ ha.bitmap[idx] &^= uintptr(1)<<zeros - 1
+ break
+ } else if zeros == ptrBits {
+ ha.bitmap[idx] = 0
+ break
+ } else {
+ ha.bitmap[idx] = 0
+ zeros -= ptrBits
+ }
+ ha.noMorePtrs[idx/8] |= uint8(1) << (idx % 8)
+ h.addr += ptrBits * goarch.PtrSize
+ }
+}
+
+// Read the bytes starting at the aligned pointer p into a uintptr.
+// Read is little-endian.
+func readUintptr(p *byte) uintptr {
+ x := *(*uintptr)(unsafe.Pointer(p))
+ if goarch.BigEndian {
+ if goarch.PtrSize == 8 {
+ return uintptr(sys.Bswap64(uint64(x)))
+ }
+ return uintptr(sys.Bswap32(uint32(x)))
+ }
+ return x
+}
+
+// heapBitsSetType records that the new allocation [x, x+size)
+// holds in [x, x+dataSize) one or more values of type typ.
+// (The number of values is given by dataSize / typ.Size.)
+// If dataSize < size, the fragment [x+dataSize, x+size) is
+// recorded as non-pointer data.
+// It is known that the type has pointers somewhere;
+// malloc does not call heapBitsSetType when there are no pointers,
+// because all free objects are marked as noscan during
+// heapBitsSweepSpan.
+//
+// There can only be one allocation from a given span active at a time,
+// and the bitmap for a span always falls on word boundaries,
+// so there are no write-write races for access to the heap bitmap.
+// Hence, heapBitsSetType can access the bitmap without atomics.
+//
+// There can be read-write races between heapBitsSetType and things
+// that read the heap bitmap like scanobject. However, since
+// heapBitsSetType is only used for objects that have not yet been
+// made reachable, readers will ignore bits being modified by this
+// function. This does mean this function cannot transiently modify
+// bits that belong to neighboring objects. Also, on weakly-ordered
+// machines, callers must execute a store/store (publication) barrier
+// between calling this function and making the object reachable.
+func heapBitsSetType(x, size, dataSize uintptr, typ *_type) {
+ const doubleCheck = false // slow but helpful; enable to test modifications to this code
+
+ if doubleCheck && dataSize%typ.Size_ != 0 {
+ throw("heapBitsSetType: dataSize not a multiple of typ.Size")
+ }
+
+ if goarch.PtrSize == 8 && size == goarch.PtrSize {
+ // It's one word and it has pointers, it must be a pointer.
+ // Since all allocated one-word objects are pointers
+ // (non-pointers are aggregated into tinySize allocations),
+ // (*mspan).initHeapBits sets the pointer bits for us.
+ // Nothing to do here.
+ if doubleCheck {
+ h, addr := heapBitsForAddr(x, size).next()
+ if addr != x {
+ throw("heapBitsSetType: pointer bit missing")
+ }
+ _, addr = h.next()
+ if addr != 0 {
+ throw("heapBitsSetType: second pointer bit found")
+ }
+ }
+ return
+ }
+
+ h := writeHeapBitsForAddr(x)
+
+ // Handle GC program.
+ if typ.Kind_&kindGCProg != 0 {
+ // Expand the gc program into the storage we're going to use for the actual object.
+ obj := (*uint8)(unsafe.Pointer(x))
+ n := runGCProg(addb(typ.GCData, 4), obj)
+ // Use the expanded program to set the heap bits.
+ for i := uintptr(0); true; i += typ.Size_ {
+ // Copy expanded program to heap bitmap.
+ p := obj
+ j := n
+ for j > 8 {
+ h = h.write(uintptr(*p), 8)
+ p = add1(p)
+ j -= 8
+ }
+ h = h.write(uintptr(*p), j)
+
+ if i+typ.Size_ == dataSize {
+ break // no padding after last element
+ }
+
+ // Pad with zeros to the start of the next element.
+ h = h.pad(typ.Size_ - n*goarch.PtrSize)
+ }
+
+ h.flush(x, size)
+
+ // Erase the expanded GC program.
+ memclrNoHeapPointers(unsafe.Pointer(obj), (n+7)/8)
+ return
+ }
+
+ // Note about sizes:
+ //
+ // typ.Size is the number of words in the object,
+ // and typ.PtrBytes is the number of words in the prefix
+ // of the object that contains pointers. That is, the final
+ // typ.Size - typ.PtrBytes words contain no pointers.
+ // This allows optimization of a common pattern where
+ // an object has a small header followed by a large scalar
+ // buffer. If we know the pointers are over, we don't have
+ // to scan the buffer's heap bitmap at all.
+ // The 1-bit ptrmasks are sized to contain only bits for
+ // the typ.PtrBytes prefix, zero padded out to a full byte
+ // of bitmap. If there is more room in the allocated object,
+ // that space is pointerless. The noMorePtrs bitmap will prevent
+ // scanning large pointerless tails of an object.
+ //
+ // Replicated copies are not as nice: if there is an array of
+ // objects with scalar tails, all but the last tail does have to
+ // be initialized, because there is no way to say "skip forward".
+
+ ptrs := typ.PtrBytes / goarch.PtrSize
+ if typ.Size_ == dataSize { // Single element
+ if ptrs <= ptrBits { // Single small element
+ m := readUintptr(typ.GCData)
+ h = h.write(m, ptrs)
+ } else { // Single large element
+ p := typ.GCData
+ for {
+ h = h.write(readUintptr(p), ptrBits)
+ p = addb(p, ptrBits/8)
+ ptrs -= ptrBits
+ if ptrs <= ptrBits {
+ break
+ }
+ }
+ m := readUintptr(p)
+ h = h.write(m, ptrs)
+ }
+ } else { // Repeated element
+ words := typ.Size_ / goarch.PtrSize // total words, including scalar tail
+ if words <= ptrBits { // Repeated small element
+ n := dataSize / typ.Size_
+ m := readUintptr(typ.GCData)
+ // Make larger unit to repeat
+ for words <= ptrBits/2 {
+ if n&1 != 0 {
+ h = h.write(m, words)
+ }
+ n /= 2
+ m |= m << words
+ ptrs += words
+ words *= 2
+ if n == 1 {
+ break
+ }
+ }
+ for n > 1 {
+ h = h.write(m, words)
+ n--
+ }
+ h = h.write(m, ptrs)
+ } else { // Repeated large element
+ for i := uintptr(0); true; i += typ.Size_ {
+ p := typ.GCData
+ j := ptrs
+ for j > ptrBits {
+ h = h.write(readUintptr(p), ptrBits)
+ p = addb(p, ptrBits/8)
+ j -= ptrBits
+ }
+ m := readUintptr(p)
+ h = h.write(m, j)
+ if i+typ.Size_ == dataSize {
+ break // don't need the trailing nonptr bits on the last element.
+ }
+ // Pad with zeros to the start of the next element.
+ h = h.pad(typ.Size_ - typ.PtrBytes)
+ }
+ }
+ }
+ h.flush(x, size)
+
+ if doubleCheck {
+ h := heapBitsForAddr(x, size)
+ for i := uintptr(0); i < size; i += goarch.PtrSize {
+ // Compute the pointer bit we want at offset i.
+ want := false
+ if i < dataSize {
+ off := i % typ.Size_
+ if off < typ.PtrBytes {
+ j := off / goarch.PtrSize
+ want = *addb(typ.GCData, j/8)>>(j%8)&1 != 0
+ }
+ }
+ if want {
+ var addr uintptr
+ h, addr = h.next()
+ if addr != x+i {
+ throw("heapBitsSetType: pointer entry not correct")
+ }
+ }
+ }
+ if _, addr := h.next(); addr != 0 {
+ throw("heapBitsSetType: extra pointer")
+ }
+ }
+}
+
+var debugPtrmask struct {
+ lock mutex
+ data *byte
+}
+
+// progToPointerMask returns the 1-bit pointer mask output by the GC program prog.
+// size the size of the region described by prog, in bytes.
+// The resulting bitvector will have no more than size/goarch.PtrSize bits.
+func progToPointerMask(prog *byte, size uintptr) bitvector {
+ n := (size/goarch.PtrSize + 7) / 8
+ x := (*[1 << 30]byte)(persistentalloc(n+1, 1, &memstats.buckhash_sys))[:n+1]
+ x[len(x)-1] = 0xa1 // overflow check sentinel
+ n = runGCProg(prog, &x[0])
+ if x[len(x)-1] != 0xa1 {
+ throw("progToPointerMask: overflow")
+ }
+ return bitvector{int32(n), &x[0]}
+}
+
+// Packed GC pointer bitmaps, aka GC programs.
+//
+// For large types containing arrays, the type information has a
+// natural repetition that can be encoded to save space in the
+// binary and in the memory representation of the type information.
+//
+// The encoding is a simple Lempel-Ziv style bytecode machine
+// with the following instructions:
+//
+// 00000000: stop
+// 0nnnnnnn: emit n bits copied from the next (n+7)/8 bytes
+// 10000000 n c: repeat the previous n bits c times; n, c are varints
+// 1nnnnnnn c: repeat the previous n bits c times; c is a varint
+
+// runGCProg returns the number of 1-bit entries written to memory.
+func runGCProg(prog, dst *byte) uintptr {
+ dstStart := dst
+
+ // Bits waiting to be written to memory.
+ var bits uintptr
+ var nbits uintptr
+
+ p := prog
+Run:
+ for {
+ // Flush accumulated full bytes.
+ // The rest of the loop assumes that nbits <= 7.
+ for ; nbits >= 8; nbits -= 8 {
+ *dst = uint8(bits)
+ dst = add1(dst)
+ bits >>= 8
+ }
+
+ // Process one instruction.
+ inst := uintptr(*p)
+ p = add1(p)
+ n := inst & 0x7F
+ if inst&0x80 == 0 {
+ // Literal bits; n == 0 means end of program.
+ if n == 0 {
+ // Program is over.
+ break Run
+ }
+ nbyte := n / 8
+ for i := uintptr(0); i < nbyte; i++ {
+ bits |= uintptr(*p) << nbits
+ p = add1(p)
+ *dst = uint8(bits)
+ dst = add1(dst)
+ bits >>= 8
+ }
+ if n %= 8; n > 0 {
+ bits |= uintptr(*p) << nbits
+ p = add1(p)
+ nbits += n
+ }
+ continue Run
+ }
+
+ // Repeat. If n == 0, it is encoded in a varint in the next bytes.
+ if n == 0 {
+ for off := uint(0); ; off += 7 {
+ x := uintptr(*p)
+ p = add1(p)
+ n |= (x & 0x7F) << off
+ if x&0x80 == 0 {
+ break
+ }
+ }
+ }
+
+ // Count is encoded in a varint in the next bytes.
+ c := uintptr(0)
+ for off := uint(0); ; off += 7 {
+ x := uintptr(*p)
+ p = add1(p)
+ c |= (x & 0x7F) << off
+ if x&0x80 == 0 {
+ break
+ }
+ }
+ c *= n // now total number of bits to copy
+
+ // If the number of bits being repeated is small, load them
+ // into a register and use that register for the entire loop
+ // instead of repeatedly reading from memory.
+ // Handling fewer than 8 bits here makes the general loop simpler.
+ // The cutoff is goarch.PtrSize*8 - 7 to guarantee that when we add
+ // the pattern to a bit buffer holding at most 7 bits (a partial byte)
+ // it will not overflow.
+ src := dst
+ const maxBits = goarch.PtrSize*8 - 7
+ if n <= maxBits {
+ // Start with bits in output buffer.
+ pattern := bits
+ npattern := nbits
+
+ // If we need more bits, fetch them from memory.
+ src = subtract1(src)
+ for npattern < n {
+ pattern <<= 8
+ pattern |= uintptr(*src)
+ src = subtract1(src)
+ npattern += 8
+ }
+
+ // We started with the whole bit output buffer,
+ // and then we loaded bits from whole bytes.
+ // Either way, we might now have too many instead of too few.
+ // Discard the extra.
+ if npattern > n {
+ pattern >>= npattern - n
+ npattern = n
+ }
+
+ // Replicate pattern to at most maxBits.
+ if npattern == 1 {
+ // One bit being repeated.
+ // If the bit is 1, make the pattern all 1s.
+ // If the bit is 0, the pattern is already all 0s,
+ // but we can claim that the number of bits
+ // in the word is equal to the number we need (c),
+ // because right shift of bits will zero fill.
+ if pattern == 1 {
+ pattern = 1<<maxBits - 1
+ npattern = maxBits
+ } else {
+ npattern = c
+ }
+ } else {
+ b := pattern
+ nb := npattern
+ if nb+nb <= maxBits {
+ // Double pattern until the whole uintptr is filled.
+ for nb <= goarch.PtrSize*8 {
+ b |= b << nb
+ nb += nb
+ }
+ // Trim away incomplete copy of original pattern in high bits.
+ // TODO(rsc): Replace with table lookup or loop on systems without divide?
+ nb = maxBits / npattern * npattern
+ b &= 1<<nb - 1
+ pattern = b
+ npattern = nb
+ }
+ }
+
+ // Add pattern to bit buffer and flush bit buffer, c/npattern times.
+ // Since pattern contains >8 bits, there will be full bytes to flush
+ // on each iteration.
+ for ; c >= npattern; c -= npattern {
+ bits |= pattern << nbits
+ nbits += npattern
+ for nbits >= 8 {
+ *dst = uint8(bits)
+ dst = add1(dst)
+ bits >>= 8
+ nbits -= 8
+ }
+ }
+
+ // Add final fragment to bit buffer.
+ if c > 0 {
+ pattern &= 1<<c - 1
+ bits |= pattern << nbits
+ nbits += c
+ }
+ continue Run
+ }
+
+ // Repeat; n too large to fit in a register.
+ // Since nbits <= 7, we know the first few bytes of repeated data
+ // are already written to memory.
+ off := n - nbits // n > nbits because n > maxBits and nbits <= 7
+ // Leading src fragment.
+ src = subtractb(src, (off+7)/8)
+ if frag := off & 7; frag != 0 {
+ bits |= uintptr(*src) >> (8 - frag) << nbits
+ src = add1(src)
+ nbits += frag
+ c -= frag
+ }
+ // Main loop: load one byte, write another.
+ // The bits are rotating through the bit buffer.
+ for i := c / 8; i > 0; i-- {
+ bits |= uintptr(*src) << nbits
+ src = add1(src)
+ *dst = uint8(bits)
+ dst = add1(dst)
+ bits >>= 8
+ }
+ // Final src fragment.
+ if c %= 8; c > 0 {
+ bits |= (uintptr(*src) & (1<<c - 1)) << nbits
+ nbits += c
+ }
+ }
+
+ // Write any final bits out, using full-byte writes, even for the final byte.
+ totalBits := (uintptr(unsafe.Pointer(dst))-uintptr(unsafe.Pointer(dstStart)))*8 + nbits
+ nbits += -nbits & 7
+ for ; nbits > 0; nbits -= 8 {
+ *dst = uint8(bits)
+ dst = add1(dst)
+ bits >>= 8
+ }
+ return totalBits
+}
+
+// materializeGCProg allocates space for the (1-bit) pointer bitmask
+// for an object of size ptrdata. Then it fills that space with the
+// pointer bitmask specified by the program prog.
+// The bitmask starts at s.startAddr.
+// The result must be deallocated with dematerializeGCProg.
+func materializeGCProg(ptrdata uintptr, prog *byte) *mspan {
+ // Each word of ptrdata needs one bit in the bitmap.
+ bitmapBytes := divRoundUp(ptrdata, 8*goarch.PtrSize)
+ // Compute the number of pages needed for bitmapBytes.
+ pages := divRoundUp(bitmapBytes, pageSize)
+ s := mheap_.allocManual(pages, spanAllocPtrScalarBits)
+ runGCProg(addb(prog, 4), (*byte)(unsafe.Pointer(s.startAddr)))
+ return s
+}
+func dematerializeGCProg(s *mspan) {
+ mheap_.freeManual(s, spanAllocPtrScalarBits)
+}
+
+func dumpGCProg(p *byte) {
+ nptr := 0
+ for {
+ x := *p
+ p = add1(p)
+ if x == 0 {
+ print("\t", nptr, " end\n")
+ break
+ }
+ if x&0x80 == 0 {
+ print("\t", nptr, " lit ", x, ":")
+ n := int(x+7) / 8
+ for i := 0; i < n; i++ {
+ print(" ", hex(*p))
+ p = add1(p)
+ }
+ print("\n")
+ nptr += int(x)
+ } else {
+ nbit := int(x &^ 0x80)
+ if nbit == 0 {
+ for nb := uint(0); ; nb += 7 {
+ x := *p
+ p = add1(p)
+ nbit |= int(x&0x7f) << nb
+ if x&0x80 == 0 {
+ break
+ }
+ }
+ }
+ count := 0
+ for nb := uint(0); ; nb += 7 {
+ x := *p
+ p = add1(p)
+ count |= int(x&0x7f) << nb
+ if x&0x80 == 0 {
+ break
+ }
+ }
+ print("\t", nptr, " repeat ", nbit, " × ", count, "\n")
+ nptr += nbit * count
+ }
+ }
+}
+
+// Testing.
+
+// reflect_gcbits returns the GC type info for x, for testing.
+// The result is the bitmap entries (0 or 1), one entry per byte.
+//
+//go:linkname reflect_gcbits reflect.gcbits
+func reflect_gcbits(x any) []byte {
+ return getgcmask(x)
+}
+
+// Returns GC type info for the pointer stored in ep for testing.
+// If ep points to the stack, only static live information will be returned
+// (i.e. not for objects which are only dynamically live stack objects).
+func getgcmask(ep any) (mask []byte) {
+ e := *efaceOf(&ep)
+ p := e.data
+ t := e._type
+ // data or bss
+ for _, datap := range activeModules() {
+ // data
+ if datap.data <= uintptr(p) && uintptr(p) < datap.edata {
+ bitmap := datap.gcdatamask.bytedata
+ n := (*ptrtype)(unsafe.Pointer(t)).Elem.Size_
+ mask = make([]byte, n/goarch.PtrSize)
+ for i := uintptr(0); i < n; i += goarch.PtrSize {
+ off := (uintptr(p) + i - datap.data) / goarch.PtrSize
+ mask[i/goarch.PtrSize] = (*addb(bitmap, off/8) >> (off % 8)) & 1
+ }
+ return
+ }
+
+ // bss
+ if datap.bss <= uintptr(p) && uintptr(p) < datap.ebss {
+ bitmap := datap.gcbssmask.bytedata
+ n := (*ptrtype)(unsafe.Pointer(t)).Elem.Size_
+ mask = make([]byte, n/goarch.PtrSize)
+ for i := uintptr(0); i < n; i += goarch.PtrSize {
+ off := (uintptr(p) + i - datap.bss) / goarch.PtrSize
+ mask[i/goarch.PtrSize] = (*addb(bitmap, off/8) >> (off % 8)) & 1
+ }
+ return
+ }
+ }
+
+ // heap
+ if base, s, _ := findObject(uintptr(p), 0, 0); base != 0 {
+ if s.spanclass.noscan() {
+ return nil
+ }
+ n := s.elemsize
+ hbits := heapBitsForAddr(base, n)
+ mask = make([]byte, n/goarch.PtrSize)
+ for {
+ var addr uintptr
+ if hbits, addr = hbits.next(); addr == 0 {
+ break
+ }
+ mask[(addr-base)/goarch.PtrSize] = 1
+ }
+ // Callers expect this mask to end at the last pointer.
+ for len(mask) > 0 && mask[len(mask)-1] == 0 {
+ mask = mask[:len(mask)-1]
+ }
+ return
+ }
+
+ // stack
+ if gp := getg(); gp.m.curg.stack.lo <= uintptr(p) && uintptr(p) < gp.m.curg.stack.hi {
+ found := false
+ var u unwinder
+ for u.initAt(gp.m.curg.sched.pc, gp.m.curg.sched.sp, 0, gp.m.curg, 0); u.valid(); u.next() {
+ if u.frame.sp <= uintptr(p) && uintptr(p) < u.frame.varp {
+ found = true
+ break
+ }
+ }
+ if found {
+ locals, _, _ := u.frame.getStackMap(nil, false)
+ if locals.n == 0 {
+ return
+ }
+ size := uintptr(locals.n) * goarch.PtrSize
+ n := (*ptrtype)(unsafe.Pointer(t)).Elem.Size_
+ mask = make([]byte, n/goarch.PtrSize)
+ for i := uintptr(0); i < n; i += goarch.PtrSize {
+ off := (uintptr(p) + i - u.frame.varp + size) / goarch.PtrSize
+ mask[i/goarch.PtrSize] = locals.ptrbit(off)
+ }
+ }
+ return
+ }
+
+ // otherwise, not something the GC knows about.
+ // possibly read-only data, like malloc(0).
+ // must not have pointers
+ return
+}
diff --git a/contrib/go/_std_1.20/src/runtime/mcache.go b/contrib/go/_std_1.21/src/runtime/mcache.go
index acfd99b31e..acfd99b31e 100644
--- a/contrib/go/_std_1.20/src/runtime/mcache.go
+++ b/contrib/go/_std_1.21/src/runtime/mcache.go
diff --git a/contrib/go/_std_1.21/src/runtime/mcentral.go b/contrib/go/_std_1.21/src/runtime/mcentral.go
new file mode 100644
index 0000000000..78611994f3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mcentral.go
@@ -0,0 +1,257 @@
+// Copyright 2009 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.
+
+// Central free lists.
+//
+// See malloc.go for an overview.
+//
+// The mcentral doesn't actually contain the list of free objects; the mspan does.
+// Each mcentral is two lists of mspans: those with free objects (c->nonempty)
+// and those that are completely allocated (c->empty).
+
+package runtime
+
+import (
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+)
+
+// Central list of free objects of a given size.
+type mcentral struct {
+ _ sys.NotInHeap
+ spanclass spanClass
+
+ // partial and full contain two mspan sets: one of swept in-use
+ // spans, and one of unswept in-use spans. These two trade
+ // roles on each GC cycle. The unswept set is drained either by
+ // allocation or by the background sweeper in every GC cycle,
+ // so only two roles are necessary.
+ //
+ // sweepgen is increased by 2 on each GC cycle, so the swept
+ // spans are in partial[sweepgen/2%2] and the unswept spans are in
+ // partial[1-sweepgen/2%2]. Sweeping pops spans from the
+ // unswept set and pushes spans that are still in-use on the
+ // swept set. Likewise, allocating an in-use span pushes it
+ // on the swept set.
+ //
+ // Some parts of the sweeper can sweep arbitrary spans, and hence
+ // can't remove them from the unswept set, but will add the span
+ // to the appropriate swept list. As a result, the parts of the
+ // sweeper and mcentral that do consume from the unswept list may
+ // encounter swept spans, and these should be ignored.
+ partial [2]spanSet // list of spans with a free object
+ full [2]spanSet // list of spans with no free objects
+}
+
+// Initialize a single central free list.
+func (c *mcentral) init(spc spanClass) {
+ c.spanclass = spc
+ lockInit(&c.partial[0].spineLock, lockRankSpanSetSpine)
+ lockInit(&c.partial[1].spineLock, lockRankSpanSetSpine)
+ lockInit(&c.full[0].spineLock, lockRankSpanSetSpine)
+ lockInit(&c.full[1].spineLock, lockRankSpanSetSpine)
+}
+
+// partialUnswept returns the spanSet which holds partially-filled
+// unswept spans for this sweepgen.
+func (c *mcentral) partialUnswept(sweepgen uint32) *spanSet {
+ return &c.partial[1-sweepgen/2%2]
+}
+
+// partialSwept returns the spanSet which holds partially-filled
+// swept spans for this sweepgen.
+func (c *mcentral) partialSwept(sweepgen uint32) *spanSet {
+ return &c.partial[sweepgen/2%2]
+}
+
+// fullUnswept returns the spanSet which holds unswept spans without any
+// free slots for this sweepgen.
+func (c *mcentral) fullUnswept(sweepgen uint32) *spanSet {
+ return &c.full[1-sweepgen/2%2]
+}
+
+// fullSwept returns the spanSet which holds swept spans without any
+// free slots for this sweepgen.
+func (c *mcentral) fullSwept(sweepgen uint32) *spanSet {
+ return &c.full[sweepgen/2%2]
+}
+
+// Allocate a span to use in an mcache.
+func (c *mcentral) cacheSpan() *mspan {
+ // Deduct credit for this span allocation and sweep if necessary.
+ spanBytes := uintptr(class_to_allocnpages[c.spanclass.sizeclass()]) * _PageSize
+ deductSweepCredit(spanBytes, 0)
+
+ traceDone := false
+ if traceEnabled() {
+ traceGCSweepStart()
+ }
+
+ // If we sweep spanBudget spans without finding any free
+ // space, just allocate a fresh span. This limits the amount
+ // of time we can spend trying to find free space and
+ // amortizes the cost of small object sweeping over the
+ // benefit of having a full free span to allocate from. By
+ // setting this to 100, we limit the space overhead to 1%.
+ //
+ // TODO(austin,mknyszek): This still has bad worst-case
+ // throughput. For example, this could find just one free slot
+ // on the 100th swept span. That limits allocation latency, but
+ // still has very poor throughput. We could instead keep a
+ // running free-to-used budget and switch to fresh span
+ // allocation if the budget runs low.
+ spanBudget := 100
+
+ var s *mspan
+ var sl sweepLocker
+
+ // Try partial swept spans first.
+ sg := mheap_.sweepgen
+ if s = c.partialSwept(sg).pop(); s != nil {
+ goto havespan
+ }
+
+ sl = sweep.active.begin()
+ if sl.valid {
+ // Now try partial unswept spans.
+ for ; spanBudget >= 0; spanBudget-- {
+ s = c.partialUnswept(sg).pop()
+ if s == nil {
+ break
+ }
+ if s, ok := sl.tryAcquire(s); ok {
+ // We got ownership of the span, so let's sweep it and use it.
+ s.sweep(true)
+ sweep.active.end(sl)
+ goto havespan
+ }
+ // We failed to get ownership of the span, which means it's being or
+ // has been swept by an asynchronous sweeper that just couldn't remove it
+ // from the unswept list. That sweeper took ownership of the span and
+ // responsibility for either freeing it to the heap or putting it on the
+ // right swept list. Either way, we should just ignore it (and it's unsafe
+ // for us to do anything else).
+ }
+ // Now try full unswept spans, sweeping them and putting them into the
+ // right list if we fail to get a span.
+ for ; spanBudget >= 0; spanBudget-- {
+ s = c.fullUnswept(sg).pop()
+ if s == nil {
+ break
+ }
+ if s, ok := sl.tryAcquire(s); ok {
+ // We got ownership of the span, so let's sweep it.
+ s.sweep(true)
+ // Check if there's any free space.
+ freeIndex := s.nextFreeIndex()
+ if freeIndex != s.nelems {
+ s.freeindex = freeIndex
+ sweep.active.end(sl)
+ goto havespan
+ }
+ // Add it to the swept list, because sweeping didn't give us any free space.
+ c.fullSwept(sg).push(s.mspan)
+ }
+ // See comment for partial unswept spans.
+ }
+ sweep.active.end(sl)
+ }
+ if traceEnabled() {
+ traceGCSweepDone()
+ traceDone = true
+ }
+
+ // We failed to get a span from the mcentral so get one from mheap.
+ s = c.grow()
+ if s == nil {
+ return nil
+ }
+
+ // At this point s is a span that should have free slots.
+havespan:
+ if traceEnabled() && !traceDone {
+ traceGCSweepDone()
+ }
+ n := int(s.nelems) - int(s.allocCount)
+ if n == 0 || s.freeindex == s.nelems || uintptr(s.allocCount) == s.nelems {
+ throw("span has no free objects")
+ }
+ freeByteBase := s.freeindex &^ (64 - 1)
+ whichByte := freeByteBase / 8
+ // Init alloc bits cache.
+ s.refillAllocCache(whichByte)
+
+ // Adjust the allocCache so that s.freeindex corresponds to the low bit in
+ // s.allocCache.
+ s.allocCache >>= s.freeindex % 64
+
+ return s
+}
+
+// Return span from an mcache.
+//
+// s must have a span class corresponding to this
+// mcentral and it must not be empty.
+func (c *mcentral) uncacheSpan(s *mspan) {
+ if s.allocCount == 0 {
+ throw("uncaching span but s.allocCount == 0")
+ }
+
+ sg := mheap_.sweepgen
+ stale := s.sweepgen == sg+1
+
+ // Fix up sweepgen.
+ if stale {
+ // Span was cached before sweep began. It's our
+ // responsibility to sweep it.
+ //
+ // Set sweepgen to indicate it's not cached but needs
+ // sweeping and can't be allocated from. sweep will
+ // set s.sweepgen to indicate s is swept.
+ atomic.Store(&s.sweepgen, sg-1)
+ } else {
+ // Indicate that s is no longer cached.
+ atomic.Store(&s.sweepgen, sg)
+ }
+
+ // Put the span in the appropriate place.
+ if stale {
+ // It's stale, so just sweep it. Sweeping will put it on
+ // the right list.
+ //
+ // We don't use a sweepLocker here. Stale cached spans
+ // aren't in the global sweep lists, so mark termination
+ // itself holds up sweep completion until all mcaches
+ // have been swept.
+ ss := sweepLocked{s}
+ ss.sweep(false)
+ } else {
+ if int(s.nelems)-int(s.allocCount) > 0 {
+ // Put it back on the partial swept list.
+ c.partialSwept(sg).push(s)
+ } else {
+ // There's no free space and it's not stale, so put it on the
+ // full swept list.
+ c.fullSwept(sg).push(s)
+ }
+ }
+}
+
+// grow allocates a new empty span from the heap and initializes it for c's size class.
+func (c *mcentral) grow() *mspan {
+ npages := uintptr(class_to_allocnpages[c.spanclass.sizeclass()])
+ size := uintptr(class_to_size[c.spanclass.sizeclass()])
+
+ s := mheap_.alloc(npages, c.spanclass)
+ if s == nil {
+ return nil
+ }
+
+ // Use division by multiplication and shifts to quickly compute:
+ // n := (npages << _PageShift) / size
+ n := s.divideByElemSize(npages << _PageShift)
+ s.limit = s.base() + size*n
+ s.initHeapBits(false)
+ return s
+}
diff --git a/contrib/go/_std_1.20/src/runtime/mcheckmark.go b/contrib/go/_std_1.21/src/runtime/mcheckmark.go
index 73c1a10d23..73c1a10d23 100644
--- a/contrib/go/_std_1.20/src/runtime/mcheckmark.go
+++ b/contrib/go/_std_1.21/src/runtime/mcheckmark.go
diff --git a/contrib/go/_std_1.21/src/runtime/mem.go b/contrib/go/_std_1.21/src/runtime/mem.go
new file mode 100644
index 0000000000..22688d51d5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mem.go
@@ -0,0 +1,156 @@
+// Copyright 2022 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 runtime
+
+import "unsafe"
+
+// OS memory management abstraction layer
+//
+// Regions of the address space managed by the runtime may be in one of four
+// states at any given time:
+// 1) None - Unreserved and unmapped, the default state of any region.
+// 2) Reserved - Owned by the runtime, but accessing it would cause a fault.
+// Does not count against the process' memory footprint.
+// 3) Prepared - Reserved, intended not to be backed by physical memory (though
+// an OS may implement this lazily). Can transition efficiently to
+// Ready. Accessing memory in such a region is undefined (may
+// fault, may give back unexpected zeroes, etc.).
+// 4) Ready - may be accessed safely.
+//
+// This set of states is more than is strictly necessary to support all the
+// currently supported platforms. One could get by with just None, Reserved, and
+// Ready. However, the Prepared state gives us flexibility for performance
+// purposes. For example, on POSIX-y operating systems, Reserved is usually a
+// private anonymous mmap'd region with PROT_NONE set, and to transition
+// to Ready would require setting PROT_READ|PROT_WRITE. However the
+// underspecification of Prepared lets us use just MADV_FREE to transition from
+// Ready to Prepared. Thus with the Prepared state we can set the permission
+// bits just once early on, we can efficiently tell the OS that it's free to
+// take pages away from us when we don't strictly need them.
+//
+// This file defines a cross-OS interface for a common set of helpers
+// that transition memory regions between these states. The helpers call into
+// OS-specific implementations that handle errors, while the interface boundary
+// implements cross-OS functionality, like updating runtime accounting.
+
+// sysAlloc transitions an OS-chosen region of memory from None to Ready.
+// More specifically, it obtains a large chunk of zeroed memory from the
+// operating system, typically on the order of a hundred kilobytes
+// or a megabyte. This memory is always immediately available for use.
+//
+// sysStat must be non-nil.
+//
+// Don't split the stack as this function may be invoked without a valid G,
+// which prevents us from allocating more stack.
+//
+//go:nosplit
+func sysAlloc(n uintptr, sysStat *sysMemStat) unsafe.Pointer {
+ sysStat.add(int64(n))
+ gcController.mappedReady.Add(int64(n))
+ return sysAllocOS(n)
+}
+
+// sysUnused transitions a memory region from Ready to Prepared. It notifies the
+// operating system that the physical pages backing this memory region are no
+// longer needed and can be reused for other purposes. The contents of a
+// sysUnused memory region are considered forfeit and the region must not be
+// accessed again until sysUsed is called.
+func sysUnused(v unsafe.Pointer, n uintptr) {
+ gcController.mappedReady.Add(-int64(n))
+ sysUnusedOS(v, n)
+}
+
+// sysUsed transitions a memory region from Prepared to Ready. It notifies the
+// operating system that the memory region is needed and ensures that the region
+// may be safely accessed. This is typically a no-op on systems that don't have
+// an explicit commit step and hard over-commit limits, but is critical on
+// Windows, for example.
+//
+// This operation is idempotent for memory already in the Prepared state, so
+// it is safe to refer, with v and n, to a range of memory that includes both
+// Prepared and Ready memory. However, the caller must provide the exact amount
+// of Prepared memory for accounting purposes.
+func sysUsed(v unsafe.Pointer, n, prepared uintptr) {
+ gcController.mappedReady.Add(int64(prepared))
+ sysUsedOS(v, n)
+}
+
+// sysHugePage does not transition memory regions, but instead provides a
+// hint to the OS that it would be more efficient to back this memory region
+// with pages of a larger size transparently.
+func sysHugePage(v unsafe.Pointer, n uintptr) {
+ sysHugePageOS(v, n)
+}
+
+// sysNoHugePage does not transition memory regions, but instead provides a
+// hint to the OS that it would be less efficient to back this memory region
+// with pages of a larger size transparently.
+func sysNoHugePage(v unsafe.Pointer, n uintptr) {
+ sysNoHugePageOS(v, n)
+}
+
+// sysHugePageCollapse attempts to immediately back the provided memory region
+// with huge pages. It is best-effort and may fail silently.
+func sysHugePageCollapse(v unsafe.Pointer, n uintptr) {
+ sysHugePageCollapseOS(v, n)
+}
+
+// sysFree transitions a memory region from any state to None. Therefore, it
+// returns memory unconditionally. It is used if an out-of-memory error has been
+// detected midway through an allocation or to carve out an aligned section of
+// the address space. It is okay if sysFree is a no-op only if sysReserve always
+// returns a memory region aligned to the heap allocator's alignment
+// restrictions.
+//
+// sysStat must be non-nil.
+//
+// Don't split the stack as this function may be invoked without a valid G,
+// which prevents us from allocating more stack.
+//
+//go:nosplit
+func sysFree(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {
+ sysStat.add(-int64(n))
+ gcController.mappedReady.Add(-int64(n))
+ sysFreeOS(v, n)
+}
+
+// sysFault transitions a memory region from Ready to Reserved. It
+// marks a region such that it will always fault if accessed. Used only for
+// debugging the runtime.
+//
+// TODO(mknyszek): Currently it's true that all uses of sysFault transition
+// memory from Ready to Reserved, but this may not be true in the future
+// since on every platform the operation is much more general than that.
+// If a transition from Prepared is ever introduced, create a new function
+// that elides the Ready state accounting.
+func sysFault(v unsafe.Pointer, n uintptr) {
+ gcController.mappedReady.Add(-int64(n))
+ sysFaultOS(v, n)
+}
+
+// sysReserve transitions a memory region from None to Reserved. It reserves
+// address space in such a way that it would cause a fatal fault upon access
+// (either via permissions or not committing the memory). Such a reservation is
+// thus never backed by physical memory.
+//
+// If the pointer passed to it is non-nil, the caller wants the
+// reservation there, but sysReserve can still choose another
+// location if that one is unavailable.
+//
+// NOTE: sysReserve returns OS-aligned memory, but the heap allocator
+// may use larger alignment, so the caller must be careful to realign the
+// memory obtained by sysReserve.
+func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer {
+ return sysReserveOS(v, n)
+}
+
+// sysMap transitions a memory region from Reserved to Prepared. It ensures the
+// memory region can be efficiently transitioned to Ready.
+//
+// sysStat must be non-nil.
+func sysMap(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {
+ sysStat.add(int64(n))
+ sysMapOS(v, n)
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mem_darwin.go b/contrib/go/_std_1.21/src/runtime/mem_darwin.go
new file mode 100644
index 0000000000..ae8487127c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mem_darwin.go
@@ -0,0 +1,76 @@
+// Copyright 2018 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 runtime
+
+import (
+ "unsafe"
+)
+
+// Don't split the stack as this function may be invoked without a valid G,
+// which prevents us from allocating more stack.
+//
+//go:nosplit
+func sysAllocOS(n uintptr) unsafe.Pointer {
+ v, err := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+ if err != 0 {
+ return nil
+ }
+ return v
+}
+
+func sysUnusedOS(v unsafe.Pointer, n uintptr) {
+ // MADV_FREE_REUSABLE is like MADV_FREE except it also propagates
+ // accounting information about the process to task_info.
+ madvise(v, n, _MADV_FREE_REUSABLE)
+}
+
+func sysUsedOS(v unsafe.Pointer, n uintptr) {
+ // MADV_FREE_REUSE is necessary to keep the kernel's accounting
+ // accurate. If called on any memory region that hasn't been
+ // MADV_FREE_REUSABLE'd, it's a no-op.
+ madvise(v, n, _MADV_FREE_REUSE)
+}
+
+func sysHugePageOS(v unsafe.Pointer, n uintptr) {
+}
+
+func sysNoHugePageOS(v unsafe.Pointer, n uintptr) {
+}
+
+func sysHugePageCollapseOS(v unsafe.Pointer, n uintptr) {
+}
+
+// Don't split the stack as this function may be invoked without a valid G,
+// which prevents us from allocating more stack.
+//
+//go:nosplit
+func sysFreeOS(v unsafe.Pointer, n uintptr) {
+ munmap(v, n)
+}
+
+func sysFaultOS(v unsafe.Pointer, n uintptr) {
+ mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE|_MAP_FIXED, -1, 0)
+}
+
+func sysReserveOS(v unsafe.Pointer, n uintptr) unsafe.Pointer {
+ p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+ if err != 0 {
+ return nil
+ }
+ return p
+}
+
+const _ENOMEM = 12
+
+func sysMapOS(v unsafe.Pointer, n uintptr) {
+ p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
+ if err == _ENOMEM {
+ throw("runtime: out of memory")
+ }
+ if p != v || err != 0 {
+ print("runtime: mmap(", v, ", ", n, ") returned ", p, ", ", err, "\n")
+ throw("runtime: cannot map pages in arena address space")
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mem_linux.go b/contrib/go/_std_1.21/src/runtime/mem_linux.go
new file mode 100644
index 0000000000..c9823d3011
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mem_linux.go
@@ -0,0 +1,173 @@
+// Copyright 2010 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 runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+const (
+ _EACCES = 13
+ _EINVAL = 22
+)
+
+// Don't split the stack as this method may be invoked without a valid G, which
+// prevents us from allocating more stack.
+//
+//go:nosplit
+func sysAllocOS(n uintptr) unsafe.Pointer {
+ p, err := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+ if err != 0 {
+ if err == _EACCES {
+ print("runtime: mmap: access denied\n")
+ exit(2)
+ }
+ if err == _EAGAIN {
+ print("runtime: mmap: too much locked memory (check 'ulimit -l').\n")
+ exit(2)
+ }
+ return nil
+ }
+ return p
+}
+
+var adviseUnused = uint32(_MADV_FREE)
+
+const madviseUnsupported = 0
+
+func sysUnusedOS(v unsafe.Pointer, n uintptr) {
+ if uintptr(v)&(physPageSize-1) != 0 || n&(physPageSize-1) != 0 {
+ // madvise will round this to any physical page
+ // *covered* by this range, so an unaligned madvise
+ // will release more memory than intended.
+ throw("unaligned sysUnused")
+ }
+
+ advise := atomic.Load(&adviseUnused)
+ if debug.madvdontneed != 0 && advise != madviseUnsupported {
+ advise = _MADV_DONTNEED
+ }
+ switch advise {
+ case _MADV_FREE:
+ if madvise(v, n, _MADV_FREE) == 0 {
+ break
+ }
+ atomic.Store(&adviseUnused, _MADV_DONTNEED)
+ fallthrough
+ case _MADV_DONTNEED:
+ // MADV_FREE was added in Linux 4.5. Fall back on MADV_DONTNEED if it's
+ // not supported.
+ if madvise(v, n, _MADV_DONTNEED) == 0 {
+ break
+ }
+ atomic.Store(&adviseUnused, madviseUnsupported)
+ fallthrough
+ case madviseUnsupported:
+ // Since Linux 3.18, support for madvise is optional.
+ // Fall back on mmap if it's not supported.
+ // _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE will unmap all the
+ // pages in the old mapping, and remap the memory region.
+ mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
+ }
+
+ if debug.harddecommit > 0 {
+ p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
+ if p != v || err != 0 {
+ throw("runtime: cannot disable permissions in address space")
+ }
+ }
+}
+
+func sysUsedOS(v unsafe.Pointer, n uintptr) {
+ if debug.harddecommit > 0 {
+ p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
+ if err == _ENOMEM {
+ throw("runtime: out of memory")
+ }
+ if p != v || err != 0 {
+ throw("runtime: cannot remap pages in address space")
+ }
+ return
+ }
+}
+
+func sysHugePageOS(v unsafe.Pointer, n uintptr) {
+ if physHugePageSize != 0 {
+ // Round v up to a huge page boundary.
+ beg := alignUp(uintptr(v), physHugePageSize)
+ // Round v+n down to a huge page boundary.
+ end := alignDown(uintptr(v)+n, physHugePageSize)
+
+ if beg < end {
+ madvise(unsafe.Pointer(beg), end-beg, _MADV_HUGEPAGE)
+ }
+ }
+}
+
+func sysNoHugePageOS(v unsafe.Pointer, n uintptr) {
+ if uintptr(v)&(physPageSize-1) != 0 {
+ // The Linux implementation requires that the address
+ // addr be page-aligned, and allows length to be zero.
+ throw("unaligned sysNoHugePageOS")
+ }
+ madvise(v, n, _MADV_NOHUGEPAGE)
+}
+
+func sysHugePageCollapseOS(v unsafe.Pointer, n uintptr) {
+ if uintptr(v)&(physPageSize-1) != 0 {
+ // The Linux implementation requires that the address
+ // addr be page-aligned, and allows length to be zero.
+ throw("unaligned sysHugePageCollapseOS")
+ }
+ if physHugePageSize == 0 {
+ return
+ }
+ // N.B. If you find yourself debugging this code, note that
+ // this call can fail with EAGAIN because it's best-effort.
+ // Also, when it returns an error, it's only for the last
+ // huge page in the region requested.
+ //
+ // It can also sometimes return EINVAL if the corresponding
+ // region hasn't been backed by physical memory. This is
+ // difficult to guarantee in general, and it also means
+ // there's no way to distinguish whether this syscall is
+ // actually available. Oops.
+ //
+ // Anyway, that's why this call just doesn't bother checking
+ // any errors.
+ madvise(v, n, _MADV_COLLAPSE)
+}
+
+// Don't split the stack as this function may be invoked without a valid G,
+// which prevents us from allocating more stack.
+//
+//go:nosplit
+func sysFreeOS(v unsafe.Pointer, n uintptr) {
+ munmap(v, n)
+}
+
+func sysFaultOS(v unsafe.Pointer, n uintptr) {
+ mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE|_MAP_FIXED, -1, 0)
+}
+
+func sysReserveOS(v unsafe.Pointer, n uintptr) unsafe.Pointer {
+ p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+ if err != 0 {
+ return nil
+ }
+ return p
+}
+
+func sysMapOS(v unsafe.Pointer, n uintptr) {
+ p, err := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
+ if err == _ENOMEM {
+ throw("runtime: out of memory")
+ }
+ if p != v || err != 0 {
+ print("runtime: mmap(", v, ", ", n, ") returned ", p, ", ", err, "\n")
+ throw("runtime: cannot map pages in arena address space")
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mem_windows.go b/contrib/go/_std_1.21/src/runtime/mem_windows.go
new file mode 100644
index 0000000000..477d898870
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mem_windows.go
@@ -0,0 +1,134 @@
+// Copyright 2010 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 runtime
+
+import (
+ "unsafe"
+)
+
+const (
+ _MEM_COMMIT = 0x1000
+ _MEM_RESERVE = 0x2000
+ _MEM_DECOMMIT = 0x4000
+ _MEM_RELEASE = 0x8000
+
+ _PAGE_READWRITE = 0x0004
+ _PAGE_NOACCESS = 0x0001
+
+ _ERROR_NOT_ENOUGH_MEMORY = 8
+ _ERROR_COMMITMENT_LIMIT = 1455
+)
+
+// Don't split the stack as this function may be invoked without a valid G,
+// which prevents us from allocating more stack.
+//
+//go:nosplit
+func sysAllocOS(n uintptr) unsafe.Pointer {
+ return unsafe.Pointer(stdcall4(_VirtualAlloc, 0, n, _MEM_COMMIT|_MEM_RESERVE, _PAGE_READWRITE))
+}
+
+func sysUnusedOS(v unsafe.Pointer, n uintptr) {
+ r := stdcall3(_VirtualFree, uintptr(v), n, _MEM_DECOMMIT)
+ if r != 0 {
+ return
+ }
+
+ // Decommit failed. Usual reason is that we've merged memory from two different
+ // VirtualAlloc calls, and Windows will only let each VirtualFree handle pages from
+ // a single VirtualAlloc. It is okay to specify a subset of the pages from a single alloc,
+ // just not pages from multiple allocs. This is a rare case, arising only when we're
+ // trying to give memory back to the operating system, which happens on a time
+ // scale of minutes. It doesn't have to be terribly fast. Instead of extra bookkeeping
+ // on all our VirtualAlloc calls, try freeing successively smaller pieces until
+ // we manage to free something, and then repeat. This ends up being O(n log n)
+ // in the worst case, but that's fast enough.
+ for n > 0 {
+ small := n
+ for small >= 4096 && stdcall3(_VirtualFree, uintptr(v), small, _MEM_DECOMMIT) == 0 {
+ small /= 2
+ small &^= 4096 - 1
+ }
+ if small < 4096 {
+ print("runtime: VirtualFree of ", small, " bytes failed with errno=", getlasterror(), "\n")
+ throw("runtime: failed to decommit pages")
+ }
+ v = add(v, small)
+ n -= small
+ }
+}
+
+func sysUsedOS(v unsafe.Pointer, n uintptr) {
+ p := stdcall4(_VirtualAlloc, uintptr(v), n, _MEM_COMMIT, _PAGE_READWRITE)
+ if p == uintptr(v) {
+ return
+ }
+
+ // Commit failed. See SysUnused.
+ // Hold on to n here so we can give back a better error message
+ // for certain cases.
+ k := n
+ for k > 0 {
+ small := k
+ for small >= 4096 && stdcall4(_VirtualAlloc, uintptr(v), small, _MEM_COMMIT, _PAGE_READWRITE) == 0 {
+ small /= 2
+ small &^= 4096 - 1
+ }
+ if small < 4096 {
+ errno := getlasterror()
+ switch errno {
+ case _ERROR_NOT_ENOUGH_MEMORY, _ERROR_COMMITMENT_LIMIT:
+ print("runtime: VirtualAlloc of ", n, " bytes failed with errno=", errno, "\n")
+ throw("out of memory")
+ default:
+ print("runtime: VirtualAlloc of ", small, " bytes failed with errno=", errno, "\n")
+ throw("runtime: failed to commit pages")
+ }
+ }
+ v = add(v, small)
+ k -= small
+ }
+}
+
+func sysHugePageOS(v unsafe.Pointer, n uintptr) {
+}
+
+func sysNoHugePageOS(v unsafe.Pointer, n uintptr) {
+}
+
+func sysHugePageCollapseOS(v unsafe.Pointer, n uintptr) {
+}
+
+// Don't split the stack as this function may be invoked without a valid G,
+// which prevents us from allocating more stack.
+//
+//go:nosplit
+func sysFreeOS(v unsafe.Pointer, n uintptr) {
+ r := stdcall3(_VirtualFree, uintptr(v), 0, _MEM_RELEASE)
+ if r == 0 {
+ print("runtime: VirtualFree of ", n, " bytes failed with errno=", getlasterror(), "\n")
+ throw("runtime: failed to release pages")
+ }
+}
+
+func sysFaultOS(v unsafe.Pointer, n uintptr) {
+ // SysUnused makes the memory inaccessible and prevents its reuse
+ sysUnusedOS(v, n)
+}
+
+func sysReserveOS(v unsafe.Pointer, n uintptr) unsafe.Pointer {
+ // v is just a hint.
+ // First try at v.
+ // This will fail if any of [v, v+n) is already reserved.
+ v = unsafe.Pointer(stdcall4(_VirtualAlloc, uintptr(v), n, _MEM_RESERVE, _PAGE_READWRITE))
+ if v != nil {
+ return v
+ }
+
+ // Next let the kernel choose the address.
+ return unsafe.Pointer(stdcall4(_VirtualAlloc, 0, n, _MEM_RESERVE, _PAGE_READWRITE))
+}
+
+func sysMapOS(v unsafe.Pointer, n uintptr) {
+}
diff --git a/contrib/go/_std_1.20/src/runtime/memclr_amd64.s b/contrib/go/_std_1.21/src/runtime/memclr_amd64.s
index 19bfa6f20d..19bfa6f20d 100644
--- a/contrib/go/_std_1.20/src/runtime/memclr_amd64.s
+++ b/contrib/go/_std_1.21/src/runtime/memclr_amd64.s
diff --git a/contrib/go/_std_1.20/src/runtime/memclr_arm64.s b/contrib/go/_std_1.21/src/runtime/memclr_arm64.s
index 1c35dfe0cf..1c35dfe0cf 100644
--- a/contrib/go/_std_1.20/src/runtime/memclr_arm64.s
+++ b/contrib/go/_std_1.21/src/runtime/memclr_arm64.s
diff --git a/contrib/go/_std_1.20/src/runtime/memmove_amd64.s b/contrib/go/_std_1.21/src/runtime/memmove_amd64.s
index 018bb0b19d..018bb0b19d 100644
--- a/contrib/go/_std_1.20/src/runtime/memmove_amd64.s
+++ b/contrib/go/_std_1.21/src/runtime/memmove_amd64.s
diff --git a/contrib/go/_std_1.20/src/runtime/memmove_arm64.s b/contrib/go/_std_1.21/src/runtime/memmove_arm64.s
index 8ec3ed86b9..8ec3ed86b9 100644
--- a/contrib/go/_std_1.20/src/runtime/memmove_arm64.s
+++ b/contrib/go/_std_1.21/src/runtime/memmove_arm64.s
diff --git a/contrib/go/_std_1.21/src/runtime/metrics.go b/contrib/go/_std_1.21/src/runtime/metrics.go
new file mode 100644
index 0000000000..3d0f174133
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/metrics.go
@@ -0,0 +1,855 @@
+// 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 runtime
+
+// Metrics implementation exported to runtime/metrics.
+
+import (
+ "internal/godebugs"
+ "unsafe"
+)
+
+var (
+ // metrics is a map of runtime/metrics keys to data used by the runtime
+ // to sample each metric's value. metricsInit indicates it has been
+ // initialized.
+ //
+ // These fields are protected by metricsSema which should be
+ // locked/unlocked with metricsLock() / metricsUnlock().
+ metricsSema uint32 = 1
+ metricsInit bool
+ metrics map[string]metricData
+
+ sizeClassBuckets []float64
+ timeHistBuckets []float64
+)
+
+type metricData struct {
+ // deps is the set of runtime statistics that this metric
+ // depends on. Before compute is called, the statAggregate
+ // which will be passed must ensure() these dependencies.
+ deps statDepSet
+
+ // compute is a function that populates a metricValue
+ // given a populated statAggregate structure.
+ compute func(in *statAggregate, out *metricValue)
+}
+
+func metricsLock() {
+ // Acquire the metricsSema but with handoff. Operations are typically
+ // expensive enough that queueing up goroutines and handing off between
+ // them will be noticeably better-behaved.
+ semacquire1(&metricsSema, true, 0, 0, waitReasonSemacquire)
+ if raceenabled {
+ raceacquire(unsafe.Pointer(&metricsSema))
+ }
+}
+
+func metricsUnlock() {
+ if raceenabled {
+ racerelease(unsafe.Pointer(&metricsSema))
+ }
+ semrelease(&metricsSema)
+}
+
+// initMetrics initializes the metrics map if it hasn't been yet.
+//
+// metricsSema must be held.
+func initMetrics() {
+ if metricsInit {
+ return
+ }
+
+ sizeClassBuckets = make([]float64, _NumSizeClasses, _NumSizeClasses+1)
+ // Skip size class 0 which is a stand-in for large objects, but large
+ // objects are tracked separately (and they actually get placed in
+ // the last bucket, not the first).
+ sizeClassBuckets[0] = 1 // The smallest allocation is 1 byte in size.
+ for i := 1; i < _NumSizeClasses; i++ {
+ // Size classes have an inclusive upper-bound
+ // and exclusive lower bound (e.g. 48-byte size class is
+ // (32, 48]) whereas we want and inclusive lower-bound
+ // and exclusive upper-bound (e.g. 48-byte size class is
+ // [33, 49)). We can achieve this by shifting all bucket
+ // boundaries up by 1.
+ //
+ // Also, a float64 can precisely represent integers with
+ // value up to 2^53 and size classes are relatively small
+ // (nowhere near 2^48 even) so this will give us exact
+ // boundaries.
+ sizeClassBuckets[i] = float64(class_to_size[i] + 1)
+ }
+ sizeClassBuckets = append(sizeClassBuckets, float64Inf())
+
+ timeHistBuckets = timeHistogramMetricsBuckets()
+ metrics = map[string]metricData{
+ "/cgo/go-to-c-calls:calls": {
+ compute: func(_ *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(NumCgoCall())
+ },
+ },
+ "/cpu/classes/gc/mark/assist:cpu-seconds": {
+ deps: makeStatDepSet(cpuStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindFloat64
+ out.scalar = float64bits(nsToSec(in.cpuStats.gcAssistTime))
+ },
+ },
+ "/cpu/classes/gc/mark/dedicated:cpu-seconds": {
+ deps: makeStatDepSet(cpuStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindFloat64
+ out.scalar = float64bits(nsToSec(in.cpuStats.gcDedicatedTime))
+ },
+ },
+ "/cpu/classes/gc/mark/idle:cpu-seconds": {
+ deps: makeStatDepSet(cpuStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindFloat64
+ out.scalar = float64bits(nsToSec(in.cpuStats.gcIdleTime))
+ },
+ },
+ "/cpu/classes/gc/pause:cpu-seconds": {
+ deps: makeStatDepSet(cpuStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindFloat64
+ out.scalar = float64bits(nsToSec(in.cpuStats.gcPauseTime))
+ },
+ },
+ "/cpu/classes/gc/total:cpu-seconds": {
+ deps: makeStatDepSet(cpuStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindFloat64
+ out.scalar = float64bits(nsToSec(in.cpuStats.gcTotalTime))
+ },
+ },
+ "/cpu/classes/idle:cpu-seconds": {
+ deps: makeStatDepSet(cpuStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindFloat64
+ out.scalar = float64bits(nsToSec(in.cpuStats.idleTime))
+ },
+ },
+ "/cpu/classes/scavenge/assist:cpu-seconds": {
+ deps: makeStatDepSet(cpuStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindFloat64
+ out.scalar = float64bits(nsToSec(in.cpuStats.scavengeAssistTime))
+ },
+ },
+ "/cpu/classes/scavenge/background:cpu-seconds": {
+ deps: makeStatDepSet(cpuStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindFloat64
+ out.scalar = float64bits(nsToSec(in.cpuStats.scavengeBgTime))
+ },
+ },
+ "/cpu/classes/scavenge/total:cpu-seconds": {
+ deps: makeStatDepSet(cpuStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindFloat64
+ out.scalar = float64bits(nsToSec(in.cpuStats.scavengeTotalTime))
+ },
+ },
+ "/cpu/classes/total:cpu-seconds": {
+ deps: makeStatDepSet(cpuStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindFloat64
+ out.scalar = float64bits(nsToSec(in.cpuStats.totalTime))
+ },
+ },
+ "/cpu/classes/user:cpu-seconds": {
+ deps: makeStatDepSet(cpuStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindFloat64
+ out.scalar = float64bits(nsToSec(in.cpuStats.userTime))
+ },
+ },
+ "/gc/cycles/automatic:gc-cycles": {
+ deps: makeStatDepSet(sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.sysStats.gcCyclesDone - in.sysStats.gcCyclesForced
+ },
+ },
+ "/gc/cycles/forced:gc-cycles": {
+ deps: makeStatDepSet(sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.sysStats.gcCyclesForced
+ },
+ },
+ "/gc/cycles/total:gc-cycles": {
+ deps: makeStatDepSet(sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.sysStats.gcCyclesDone
+ },
+ },
+ "/gc/scan/globals:bytes": {
+ deps: makeStatDepSet(gcStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.gcStats.globalsScan
+ },
+ },
+ "/gc/scan/heap:bytes": {
+ deps: makeStatDepSet(gcStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.gcStats.heapScan
+ },
+ },
+ "/gc/scan/stack:bytes": {
+ deps: makeStatDepSet(gcStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.gcStats.stackScan
+ },
+ },
+ "/gc/scan/total:bytes": {
+ deps: makeStatDepSet(gcStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.gcStats.totalScan
+ },
+ },
+ "/gc/heap/allocs-by-size:bytes": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ hist := out.float64HistOrInit(sizeClassBuckets)
+ hist.counts[len(hist.counts)-1] = uint64(in.heapStats.largeAllocCount)
+ // Cut off the first index which is ostensibly for size class 0,
+ // but large objects are tracked separately so it's actually unused.
+ for i, count := range in.heapStats.smallAllocCount[1:] {
+ hist.counts[i] = uint64(count)
+ }
+ },
+ },
+ "/gc/heap/allocs:bytes": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.heapStats.totalAllocated
+ },
+ },
+ "/gc/heap/allocs:objects": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.heapStats.totalAllocs
+ },
+ },
+ "/gc/heap/frees-by-size:bytes": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ hist := out.float64HistOrInit(sizeClassBuckets)
+ hist.counts[len(hist.counts)-1] = uint64(in.heapStats.largeFreeCount)
+ // Cut off the first index which is ostensibly for size class 0,
+ // but large objects are tracked separately so it's actually unused.
+ for i, count := range in.heapStats.smallFreeCount[1:] {
+ hist.counts[i] = uint64(count)
+ }
+ },
+ },
+ "/gc/heap/frees:bytes": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.heapStats.totalFreed
+ },
+ },
+ "/gc/heap/frees:objects": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.heapStats.totalFrees
+ },
+ },
+ "/gc/heap/goal:bytes": {
+ deps: makeStatDepSet(sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.sysStats.heapGoal
+ },
+ },
+ "/gc/gomemlimit:bytes": {
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(gcController.memoryLimit.Load())
+ },
+ },
+ "/gc/gogc:percent": {
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(gcController.gcPercent.Load())
+ },
+ },
+ "/gc/heap/live:bytes": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = gcController.heapMarked
+ },
+ },
+ "/gc/heap/objects:objects": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.heapStats.numObjects
+ },
+ },
+ "/gc/heap/tiny/allocs:objects": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(in.heapStats.tinyAllocCount)
+ },
+ },
+ "/gc/limiter/last-enabled:gc-cycle": {
+ compute: func(_ *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(gcCPULimiter.lastEnabledCycle.Load())
+ },
+ },
+ "/gc/pauses:seconds": {
+ compute: func(_ *statAggregate, out *metricValue) {
+ hist := out.float64HistOrInit(timeHistBuckets)
+ // The bottom-most bucket, containing negative values, is tracked
+ // as a separately as underflow, so fill that in manually and then
+ // iterate over the rest.
+ hist.counts[0] = memstats.gcPauseDist.underflow.Load()
+ for i := range memstats.gcPauseDist.counts {
+ hist.counts[i+1] = memstats.gcPauseDist.counts[i].Load()
+ }
+ hist.counts[len(hist.counts)-1] = memstats.gcPauseDist.overflow.Load()
+ },
+ },
+ "/gc/stack/starting-size:bytes": {
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(startingStackSize)
+ },
+ },
+ "/memory/classes/heap/free:bytes": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(in.heapStats.committed - in.heapStats.inHeap -
+ in.heapStats.inStacks - in.heapStats.inWorkBufs -
+ in.heapStats.inPtrScalarBits)
+ },
+ },
+ "/memory/classes/heap/objects:bytes": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.heapStats.inObjects
+ },
+ },
+ "/memory/classes/heap/released:bytes": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(in.heapStats.released)
+ },
+ },
+ "/memory/classes/heap/stacks:bytes": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(in.heapStats.inStacks)
+ },
+ },
+ "/memory/classes/heap/unused:bytes": {
+ deps: makeStatDepSet(heapStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(in.heapStats.inHeap) - in.heapStats.inObjects
+ },
+ },
+ "/memory/classes/metadata/mcache/free:bytes": {
+ deps: makeStatDepSet(sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.sysStats.mCacheSys - in.sysStats.mCacheInUse
+ },
+ },
+ "/memory/classes/metadata/mcache/inuse:bytes": {
+ deps: makeStatDepSet(sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.sysStats.mCacheInUse
+ },
+ },
+ "/memory/classes/metadata/mspan/free:bytes": {
+ deps: makeStatDepSet(sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.sysStats.mSpanSys - in.sysStats.mSpanInUse
+ },
+ },
+ "/memory/classes/metadata/mspan/inuse:bytes": {
+ deps: makeStatDepSet(sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.sysStats.mSpanInUse
+ },
+ },
+ "/memory/classes/metadata/other:bytes": {
+ deps: makeStatDepSet(heapStatsDep, sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(in.heapStats.inWorkBufs+in.heapStats.inPtrScalarBits) + in.sysStats.gcMiscSys
+ },
+ },
+ "/memory/classes/os-stacks:bytes": {
+ deps: makeStatDepSet(sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.sysStats.stacksSys
+ },
+ },
+ "/memory/classes/other:bytes": {
+ deps: makeStatDepSet(sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.sysStats.otherSys
+ },
+ },
+ "/memory/classes/profiling/buckets:bytes": {
+ deps: makeStatDepSet(sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = in.sysStats.buckHashSys
+ },
+ },
+ "/memory/classes/total:bytes": {
+ deps: makeStatDepSet(heapStatsDep, sysStatsDep),
+ compute: func(in *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(in.heapStats.committed+in.heapStats.released) +
+ in.sysStats.stacksSys + in.sysStats.mSpanSys +
+ in.sysStats.mCacheSys + in.sysStats.buckHashSys +
+ in.sysStats.gcMiscSys + in.sysStats.otherSys
+ },
+ },
+ "/sched/gomaxprocs:threads": {
+ compute: func(_ *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(gomaxprocs)
+ },
+ },
+ "/sched/goroutines:goroutines": {
+ compute: func(_ *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = uint64(gcount())
+ },
+ },
+ "/sched/latencies:seconds": {
+ compute: func(_ *statAggregate, out *metricValue) {
+ hist := out.float64HistOrInit(timeHistBuckets)
+ hist.counts[0] = sched.timeToRun.underflow.Load()
+ for i := range sched.timeToRun.counts {
+ hist.counts[i+1] = sched.timeToRun.counts[i].Load()
+ }
+ hist.counts[len(hist.counts)-1] = sched.timeToRun.overflow.Load()
+ },
+ },
+ "/sync/mutex/wait/total:seconds": {
+ compute: func(_ *statAggregate, out *metricValue) {
+ out.kind = metricKindFloat64
+ out.scalar = float64bits(nsToSec(sched.totalMutexWaitTime.Load()))
+ },
+ },
+ }
+
+ for _, info := range godebugs.All {
+ if !info.Opaque {
+ metrics["/godebug/non-default-behavior/"+info.Name+":events"] = metricData{compute: compute0}
+ }
+ }
+
+ metricsInit = true
+}
+
+func compute0(_ *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = 0
+}
+
+type metricReader func() uint64
+
+func (f metricReader) compute(_ *statAggregate, out *metricValue) {
+ out.kind = metricKindUint64
+ out.scalar = f()
+}
+
+//go:linkname godebug_registerMetric internal/godebug.registerMetric
+func godebug_registerMetric(name string, read func() uint64) {
+ metricsLock()
+ initMetrics()
+ d, ok := metrics[name]
+ if !ok {
+ throw("runtime: unexpected metric registration for " + name)
+ }
+ d.compute = metricReader(read).compute
+ metrics[name] = d
+ metricsUnlock()
+}
+
+// statDep is a dependency on a group of statistics
+// that a metric might have.
+type statDep uint
+
+const (
+ heapStatsDep statDep = iota // corresponds to heapStatsAggregate
+ sysStatsDep // corresponds to sysStatsAggregate
+ cpuStatsDep // corresponds to cpuStatsAggregate
+ gcStatsDep // corresponds to gcStatsAggregate
+ numStatsDeps
+)
+
+// statDepSet represents a set of statDeps.
+//
+// Under the hood, it's a bitmap.
+type statDepSet [1]uint64
+
+// makeStatDepSet creates a new statDepSet from a list of statDeps.
+func makeStatDepSet(deps ...statDep) statDepSet {
+ var s statDepSet
+ for _, d := range deps {
+ s[d/64] |= 1 << (d % 64)
+ }
+ return s
+}
+
+// difference returns set difference of s from b as a new set.
+func (s statDepSet) difference(b statDepSet) statDepSet {
+ var c statDepSet
+ for i := range s {
+ c[i] = s[i] &^ b[i]
+ }
+ return c
+}
+
+// union returns the union of the two sets as a new set.
+func (s statDepSet) union(b statDepSet) statDepSet {
+ var c statDepSet
+ for i := range s {
+ c[i] = s[i] | b[i]
+ }
+ return c
+}
+
+// empty returns true if there are no dependencies in the set.
+func (s *statDepSet) empty() bool {
+ for _, c := range s {
+ if c != 0 {
+ return false
+ }
+ }
+ return true
+}
+
+// has returns true if the set contains a given statDep.
+func (s *statDepSet) has(d statDep) bool {
+ return s[d/64]&(1<<(d%64)) != 0
+}
+
+// heapStatsAggregate represents memory stats obtained from the
+// runtime. This set of stats is grouped together because they
+// depend on each other in some way to make sense of the runtime's
+// current heap memory use. They're also sharded across Ps, so it
+// makes sense to grab them all at once.
+type heapStatsAggregate struct {
+ heapStatsDelta
+
+ // Derived from values in heapStatsDelta.
+
+ // inObjects is the bytes of memory occupied by objects,
+ inObjects uint64
+
+ // numObjects is the number of live objects in the heap.
+ numObjects uint64
+
+ // totalAllocated is the total bytes of heap objects allocated
+ // over the lifetime of the program.
+ totalAllocated uint64
+
+ // totalFreed is the total bytes of heap objects freed
+ // over the lifetime of the program.
+ totalFreed uint64
+
+ // totalAllocs is the number of heap objects allocated over
+ // the lifetime of the program.
+ totalAllocs uint64
+
+ // totalFrees is the number of heap objects freed over
+ // the lifetime of the program.
+ totalFrees uint64
+}
+
+// compute populates the heapStatsAggregate with values from the runtime.
+func (a *heapStatsAggregate) compute() {
+ memstats.heapStats.read(&a.heapStatsDelta)
+
+ // Calculate derived stats.
+ a.totalAllocs = a.largeAllocCount
+ a.totalFrees = a.largeFreeCount
+ a.totalAllocated = a.largeAlloc
+ a.totalFreed = a.largeFree
+ for i := range a.smallAllocCount {
+ na := a.smallAllocCount[i]
+ nf := a.smallFreeCount[i]
+ a.totalAllocs += na
+ a.totalFrees += nf
+ a.totalAllocated += na * uint64(class_to_size[i])
+ a.totalFreed += nf * uint64(class_to_size[i])
+ }
+ a.inObjects = a.totalAllocated - a.totalFreed
+ a.numObjects = a.totalAllocs - a.totalFrees
+}
+
+// sysStatsAggregate represents system memory stats obtained
+// from the runtime. This set of stats is grouped together because
+// they're all relatively cheap to acquire and generally independent
+// of one another and other runtime memory stats. The fact that they
+// may be acquired at different times, especially with respect to
+// heapStatsAggregate, means there could be some skew, but because of
+// these stats are independent, there's no real consistency issue here.
+type sysStatsAggregate struct {
+ stacksSys uint64
+ mSpanSys uint64
+ mSpanInUse uint64
+ mCacheSys uint64
+ mCacheInUse uint64
+ buckHashSys uint64
+ gcMiscSys uint64
+ otherSys uint64
+ heapGoal uint64
+ gcCyclesDone uint64
+ gcCyclesForced uint64
+}
+
+// compute populates the sysStatsAggregate with values from the runtime.
+func (a *sysStatsAggregate) compute() {
+ a.stacksSys = memstats.stacks_sys.load()
+ a.buckHashSys = memstats.buckhash_sys.load()
+ a.gcMiscSys = memstats.gcMiscSys.load()
+ a.otherSys = memstats.other_sys.load()
+ a.heapGoal = gcController.heapGoal()
+ a.gcCyclesDone = uint64(memstats.numgc)
+ a.gcCyclesForced = uint64(memstats.numforcedgc)
+
+ systemstack(func() {
+ lock(&mheap_.lock)
+ a.mSpanSys = memstats.mspan_sys.load()
+ a.mSpanInUse = uint64(mheap_.spanalloc.inuse)
+ a.mCacheSys = memstats.mcache_sys.load()
+ a.mCacheInUse = uint64(mheap_.cachealloc.inuse)
+ unlock(&mheap_.lock)
+ })
+}
+
+// cpuStatsAggregate represents CPU stats obtained from the runtime
+// acquired together to avoid skew and inconsistencies.
+type cpuStatsAggregate struct {
+ cpuStats
+}
+
+// compute populates the cpuStatsAggregate with values from the runtime.
+func (a *cpuStatsAggregate) compute() {
+ a.cpuStats = work.cpuStats
+ // TODO(mknyszek): Update the CPU stats again so that we're not
+ // just relying on the STW snapshot. The issue here is that currently
+ // this will cause non-monotonicity in the "user" CPU time metric.
+ //
+ // a.cpuStats.accumulate(nanotime(), gcphase == _GCmark)
+}
+
+// gcStatsAggregate represents various GC stats obtained from the runtime
+// acquired together to avoid skew and inconsistencies.
+type gcStatsAggregate struct {
+ heapScan uint64
+ stackScan uint64
+ globalsScan uint64
+ totalScan uint64
+}
+
+// compute populates the gcStatsAggregate with values from the runtime.
+func (a *gcStatsAggregate) compute() {
+ a.heapScan = gcController.heapScan.Load()
+ a.stackScan = uint64(gcController.lastStackScan.Load())
+ a.globalsScan = gcController.globalsScan.Load()
+ a.totalScan = a.heapScan + a.stackScan + a.globalsScan
+}
+
+// nsToSec takes a duration in nanoseconds and converts it to seconds as
+// a float64.
+func nsToSec(ns int64) float64 {
+ return float64(ns) / 1e9
+}
+
+// statAggregate is the main driver of the metrics implementation.
+//
+// It contains multiple aggregates of runtime statistics, as well
+// as a set of these aggregates that it has populated. The aggregates
+// are populated lazily by its ensure method.
+type statAggregate struct {
+ ensured statDepSet
+ heapStats heapStatsAggregate
+ sysStats sysStatsAggregate
+ cpuStats cpuStatsAggregate
+ gcStats gcStatsAggregate
+}
+
+// ensure populates statistics aggregates determined by deps if they
+// haven't yet been populated.
+func (a *statAggregate) ensure(deps *statDepSet) {
+ missing := deps.difference(a.ensured)
+ if missing.empty() {
+ return
+ }
+ for i := statDep(0); i < numStatsDeps; i++ {
+ if !missing.has(i) {
+ continue
+ }
+ switch i {
+ case heapStatsDep:
+ a.heapStats.compute()
+ case sysStatsDep:
+ a.sysStats.compute()
+ case cpuStatsDep:
+ a.cpuStats.compute()
+ case gcStatsDep:
+ a.gcStats.compute()
+ }
+ }
+ a.ensured = a.ensured.union(missing)
+}
+
+// metricKind is a runtime copy of runtime/metrics.ValueKind and
+// must be kept structurally identical to that type.
+type metricKind int
+
+const (
+ // These values must be kept identical to their corresponding Kind* values
+ // in the runtime/metrics package.
+ metricKindBad metricKind = iota
+ metricKindUint64
+ metricKindFloat64
+ metricKindFloat64Histogram
+)
+
+// metricSample is a runtime copy of runtime/metrics.Sample and
+// must be kept structurally identical to that type.
+type metricSample struct {
+ name string
+ value metricValue
+}
+
+// metricValue is a runtime copy of runtime/metrics.Sample and
+// must be kept structurally identical to that type.
+type metricValue struct {
+ kind metricKind
+ scalar uint64 // contains scalar values for scalar Kinds.
+ pointer unsafe.Pointer // contains non-scalar values.
+}
+
+// float64HistOrInit tries to pull out an existing float64Histogram
+// from the value, but if none exists, then it allocates one with
+// the given buckets.
+func (v *metricValue) float64HistOrInit(buckets []float64) *metricFloat64Histogram {
+ var hist *metricFloat64Histogram
+ if v.kind == metricKindFloat64Histogram && v.pointer != nil {
+ hist = (*metricFloat64Histogram)(v.pointer)
+ } else {
+ v.kind = metricKindFloat64Histogram
+ hist = new(metricFloat64Histogram)
+ v.pointer = unsafe.Pointer(hist)
+ }
+ hist.buckets = buckets
+ if len(hist.counts) != len(hist.buckets)-1 {
+ hist.counts = make([]uint64, len(buckets)-1)
+ }
+ return hist
+}
+
+// metricFloat64Histogram is a runtime copy of runtime/metrics.Float64Histogram
+// and must be kept structurally identical to that type.
+type metricFloat64Histogram struct {
+ counts []uint64
+ buckets []float64
+}
+
+// agg is used by readMetrics, and is protected by metricsSema.
+//
+// Managed as a global variable because its pointer will be
+// an argument to a dynamically-defined function, and we'd
+// like to avoid it escaping to the heap.
+var agg statAggregate
+
+type metricName struct {
+ name string
+ kind metricKind
+}
+
+// readMetricNames is the implementation of runtime/metrics.readMetricNames,
+// used by the runtime/metrics test and otherwise unreferenced.
+//
+//go:linkname readMetricNames runtime/metrics_test.runtime_readMetricNames
+func readMetricNames() []string {
+ metricsLock()
+ initMetrics()
+ n := len(metrics)
+ metricsUnlock()
+
+ list := make([]string, 0, n)
+
+ metricsLock()
+ for name := range metrics {
+ list = append(list, name)
+ }
+ metricsUnlock()
+
+ return list
+}
+
+// readMetrics is the implementation of runtime/metrics.Read.
+//
+//go:linkname readMetrics runtime/metrics.runtime_readMetrics
+func readMetrics(samplesp unsafe.Pointer, len int, cap int) {
+ // Construct a slice from the args.
+ sl := slice{samplesp, len, cap}
+ samples := *(*[]metricSample)(unsafe.Pointer(&sl))
+
+ metricsLock()
+
+ // Ensure the map is initialized.
+ initMetrics()
+
+ // Clear agg defensively.
+ agg = statAggregate{}
+
+ // Sample.
+ for i := range samples {
+ sample := &samples[i]
+ data, ok := metrics[sample.name]
+ if !ok {
+ sample.value.kind = metricKindBad
+ continue
+ }
+ // Ensure we have all the stats we need.
+ // agg is populated lazily.
+ agg.ensure(&data.deps)
+
+ // Compute the value based on the stats we have.
+ data.compute(&agg, &sample.value)
+ }
+
+ metricsUnlock()
+}
diff --git a/contrib/go/_std_1.21/src/runtime/metrics/description.go b/contrib/go/_std_1.21/src/runtime/metrics/description.go
new file mode 100644
index 0000000000..745691b24f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/metrics/description.go
@@ -0,0 +1,453 @@
+// 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 metrics
+
+import "internal/godebugs"
+
+// Description describes a runtime metric.
+type Description struct {
+ // Name is the full name of the metric which includes the unit.
+ //
+ // The format of the metric may be described by the following regular expression.
+ //
+ // ^(?P<name>/[^:]+):(?P<unit>[^:*/]+(?:[*/][^:*/]+)*)$
+ //
+ // The format splits the name into two components, separated by a colon: a path which always
+ // starts with a /, and a machine-parseable unit. The name may contain any valid Unicode
+ // codepoint in between / characters, but by convention will try to stick to lowercase
+ // characters and hyphens. An example of such a path might be "/memory/heap/free".
+ //
+ // The unit is by convention a series of lowercase English unit names (singular or plural)
+ // without prefixes delimited by '*' or '/'. The unit names may contain any valid Unicode
+ // codepoint that is not a delimiter.
+ // Examples of units might be "seconds", "bytes", "bytes/second", "cpu-seconds",
+ // "byte*cpu-seconds", and "bytes/second/second".
+ //
+ // For histograms, multiple units may apply. For instance, the units of the buckets and
+ // the count. By convention, for histograms, the units of the count are always "samples"
+ // with the type of sample evident by the metric's name, while the unit in the name
+ // specifies the buckets' unit.
+ //
+ // A complete name might look like "/memory/heap/free:bytes".
+ Name string
+
+ // Description is an English language sentence describing the metric.
+ Description string
+
+ // Kind is the kind of value for this metric.
+ //
+ // The purpose of this field is to allow users to filter out metrics whose values are
+ // types which their application may not understand.
+ Kind ValueKind
+
+ // Cumulative is whether or not the metric is cumulative. If a cumulative metric is just
+ // a single number, then it increases monotonically. If the metric is a distribution,
+ // then each bucket count increases monotonically.
+ //
+ // This flag thus indicates whether or not it's useful to compute a rate from this value.
+ Cumulative bool
+}
+
+// The English language descriptions below must be kept in sync with the
+// descriptions of each metric in doc.go by running 'go generate'.
+var allDesc = []Description{
+ {
+ Name: "/cgo/go-to-c-calls:calls",
+ Description: "Count of calls made from Go to C by the current process.",
+ Kind: KindUint64,
+ Cumulative: true,
+ },
+ {
+ Name: "/cpu/classes/gc/mark/assist:cpu-seconds",
+ Description: "Estimated total CPU time goroutines spent performing GC tasks " +
+ "to assist the GC and prevent it from falling behind the application. " +
+ "This metric is an overestimate, and not directly comparable to " +
+ "system CPU time measurements. Compare only with other /cpu/classes " +
+ "metrics.",
+ Kind: KindFloat64,
+ Cumulative: true,
+ },
+ {
+ Name: "/cpu/classes/gc/mark/dedicated:cpu-seconds",
+ Description: "Estimated total CPU time spent performing GC tasks on " +
+ "processors (as defined by GOMAXPROCS) dedicated to those tasks. " +
+ "This metric is an overestimate, and not directly comparable to " +
+ "system CPU time measurements. Compare only with other /cpu/classes " +
+ "metrics.",
+ Kind: KindFloat64,
+ Cumulative: true,
+ },
+ {
+ Name: "/cpu/classes/gc/mark/idle:cpu-seconds",
+ Description: "Estimated total CPU time spent performing GC tasks on " +
+ "spare CPU resources that the Go scheduler could not otherwise find " +
+ "a use for. This should be subtracted from the total GC CPU time to " +
+ "obtain a measure of compulsory GC CPU time. " +
+ "This metric is an overestimate, and not directly comparable to " +
+ "system CPU time measurements. Compare only with other /cpu/classes " +
+ "metrics.",
+ Kind: KindFloat64,
+ Cumulative: true,
+ },
+ {
+ Name: "/cpu/classes/gc/pause:cpu-seconds",
+ Description: "Estimated total CPU time spent with the application paused by " +
+ "the GC. Even if only one thread is running during the pause, this is " +
+ "computed as GOMAXPROCS times the pause latency because nothing else " +
+ "can be executing. This is the exact sum of samples in /gc/pause:seconds " +
+ "if each sample is multiplied by GOMAXPROCS at the time it is taken. " +
+ "This metric is an overestimate, and not directly comparable to " +
+ "system CPU time measurements. Compare only with other /cpu/classes " +
+ "metrics.",
+ Kind: KindFloat64,
+ Cumulative: true,
+ },
+ {
+ Name: "/cpu/classes/gc/total:cpu-seconds",
+ Description: "Estimated total CPU time spent performing GC tasks. " +
+ "This metric is an overestimate, and not directly comparable to " +
+ "system CPU time measurements. Compare only with other /cpu/classes " +
+ "metrics. Sum of all metrics in /cpu/classes/gc.",
+ Kind: KindFloat64,
+ Cumulative: true,
+ },
+ {
+ Name: "/cpu/classes/idle:cpu-seconds",
+ Description: "Estimated total available CPU time not spent executing any Go or Go runtime code. " +
+ "In other words, the part of /cpu/classes/total:cpu-seconds that was unused. " +
+ "This metric is an overestimate, and not directly comparable to " +
+ "system CPU time measurements. Compare only with other /cpu/classes " +
+ "metrics.",
+ Kind: KindFloat64,
+ Cumulative: true,
+ },
+ {
+ Name: "/cpu/classes/scavenge/assist:cpu-seconds",
+ Description: "Estimated total CPU time spent returning unused memory to the " +
+ "underlying platform in response eagerly in response to memory pressure. " +
+ "This metric is an overestimate, and not directly comparable to " +
+ "system CPU time measurements. Compare only with other /cpu/classes " +
+ "metrics.",
+ Kind: KindFloat64,
+ Cumulative: true,
+ },
+ {
+ Name: "/cpu/classes/scavenge/background:cpu-seconds",
+ Description: "Estimated total CPU time spent performing background tasks " +
+ "to return unused memory to the underlying platform. " +
+ "This metric is an overestimate, and not directly comparable to " +
+ "system CPU time measurements. Compare only with other /cpu/classes " +
+ "metrics.",
+ Kind: KindFloat64,
+ Cumulative: true,
+ },
+ {
+ Name: "/cpu/classes/scavenge/total:cpu-seconds",
+ Description: "Estimated total CPU time spent performing tasks that return " +
+ "unused memory to the underlying platform. " +
+ "This metric is an overestimate, and not directly comparable to " +
+ "system CPU time measurements. Compare only with other /cpu/classes " +
+ "metrics. Sum of all metrics in /cpu/classes/scavenge.",
+ Kind: KindFloat64,
+ Cumulative: true,
+ },
+ {
+ Name: "/cpu/classes/total:cpu-seconds",
+ Description: "Estimated total available CPU time for user Go code " +
+ "or the Go runtime, as defined by GOMAXPROCS. In other words, GOMAXPROCS " +
+ "integrated over the wall-clock duration this process has been executing for. " +
+ "This metric is an overestimate, and not directly comparable to " +
+ "system CPU time measurements. Compare only with other /cpu/classes " +
+ "metrics. Sum of all metrics in /cpu/classes.",
+ Kind: KindFloat64,
+ Cumulative: true,
+ },
+ {
+ Name: "/cpu/classes/user:cpu-seconds",
+ Description: "Estimated total CPU time spent running user Go code. This may " +
+ "also include some small amount of time spent in the Go runtime. " +
+ "This metric is an overestimate, and not directly comparable to " +
+ "system CPU time measurements. Compare only with other /cpu/classes " +
+ "metrics.",
+ Kind: KindFloat64,
+ Cumulative: true,
+ },
+ {
+ Name: "/gc/cycles/automatic:gc-cycles",
+ Description: "Count of completed GC cycles generated by the Go runtime.",
+ Kind: KindUint64,
+ Cumulative: true,
+ },
+ {
+ Name: "/gc/cycles/forced:gc-cycles",
+ Description: "Count of completed GC cycles forced by the application.",
+ Kind: KindUint64,
+ Cumulative: true,
+ },
+ {
+ Name: "/gc/cycles/total:gc-cycles",
+ Description: "Count of all completed GC cycles.",
+ Kind: KindUint64,
+ Cumulative: true,
+ },
+ {
+ Name: "/gc/gogc:percent",
+ Description: "Heap size target percentage configured by the user, otherwise 100. This " +
+ "value is set by the GOGC environment variable, and the runtime/debug.SetGCPercent " +
+ "function.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/gc/gomemlimit:bytes",
+ Description: "Go runtime memory limit configured by the user, otherwise " +
+ "math.MaxInt64. This value is set by the GOMEMLIMIT environment variable, and " +
+ "the runtime/debug.SetMemoryLimit function.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/gc/heap/allocs-by-size:bytes",
+ Description: "Distribution of heap allocations by approximate size. " +
+ "Bucket counts increase monotonically. " +
+ "Note that this does not include tiny objects as defined by " +
+ "/gc/heap/tiny/allocs:objects, only tiny blocks.",
+ Kind: KindFloat64Histogram,
+ Cumulative: true,
+ },
+ {
+ Name: "/gc/heap/allocs:bytes",
+ Description: "Cumulative sum of memory allocated to the heap by the application.",
+ Kind: KindUint64,
+ Cumulative: true,
+ },
+ {
+ Name: "/gc/heap/allocs:objects",
+ Description: "Cumulative count of heap allocations triggered by the application. " +
+ "Note that this does not include tiny objects as defined by " +
+ "/gc/heap/tiny/allocs:objects, only tiny blocks.",
+ Kind: KindUint64,
+ Cumulative: true,
+ },
+ {
+ Name: "/gc/heap/frees-by-size:bytes",
+ Description: "Distribution of freed heap allocations by approximate size. " +
+ "Bucket counts increase monotonically. " +
+ "Note that this does not include tiny objects as defined by " +
+ "/gc/heap/tiny/allocs:objects, only tiny blocks.",
+ Kind: KindFloat64Histogram,
+ Cumulative: true,
+ },
+ {
+ Name: "/gc/heap/frees:bytes",
+ Description: "Cumulative sum of heap memory freed by the garbage collector.",
+ Kind: KindUint64,
+ Cumulative: true,
+ },
+ {
+ Name: "/gc/heap/frees:objects",
+ Description: "Cumulative count of heap allocations whose storage was freed " +
+ "by the garbage collector. " +
+ "Note that this does not include tiny objects as defined by " +
+ "/gc/heap/tiny/allocs:objects, only tiny blocks.",
+ Kind: KindUint64,
+ Cumulative: true,
+ },
+ {
+ Name: "/gc/heap/goal:bytes",
+ Description: "Heap size target for the end of the GC cycle.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/gc/heap/live:bytes",
+ Description: "Heap memory occupied by live objects that were marked by the previous GC.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/gc/heap/objects:objects",
+ Description: "Number of objects, live or unswept, occupying heap memory.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/gc/heap/tiny/allocs:objects",
+ Description: "Count of small allocations that are packed together into blocks. " +
+ "These allocations are counted separately from other allocations " +
+ "because each individual allocation is not tracked by the runtime, " +
+ "only their block. Each block is already accounted for in " +
+ "allocs-by-size and frees-by-size.",
+ Kind: KindUint64,
+ Cumulative: true,
+ },
+ {
+ Name: "/gc/limiter/last-enabled:gc-cycle",
+ Description: "GC cycle the last time the GC CPU limiter was enabled. " +
+ "This metric is useful for diagnosing the root cause of an out-of-memory " +
+ "error, because the limiter trades memory for CPU time when the GC's CPU " +
+ "time gets too high. This is most likely to occur with use of SetMemoryLimit. " +
+ "The first GC cycle is cycle 1, so a value of 0 indicates that it was never enabled.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/gc/pauses:seconds",
+ Description: "Distribution of individual GC-related stop-the-world pause latencies. Bucket counts increase monotonically.",
+ Kind: KindFloat64Histogram,
+ Cumulative: true,
+ },
+ {
+ Name: "/gc/scan/globals:bytes",
+ Description: "The total amount of global variable space that is scannable.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/gc/scan/heap:bytes",
+ Description: "The total amount of heap space that is scannable.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/gc/scan/stack:bytes",
+ Description: "The number of bytes of stack that were scanned last GC cycle.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/gc/scan/total:bytes",
+ Description: "The total amount space that is scannable. Sum of all metrics in /gc/scan.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/gc/stack/starting-size:bytes",
+ Description: "The stack size of new goroutines.",
+ Kind: KindUint64,
+ Cumulative: false,
+ },
+ {
+ Name: "/memory/classes/heap/free:bytes",
+ Description: "Memory that is completely free and eligible to be returned to the underlying system, " +
+ "but has not been. This metric is the runtime's estimate of free address space that is backed by " +
+ "physical memory.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/heap/objects:bytes",
+ Description: "Memory occupied by live objects and dead objects that have not yet been marked free by the garbage collector.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/heap/released:bytes",
+ Description: "Memory that is completely free and has been returned to the underlying system. This " +
+ "metric is the runtime's estimate of free address space that is still mapped into the process, " +
+ "but is not backed by physical memory.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/heap/stacks:bytes",
+ Description: "Memory allocated from the heap that is reserved for stack space, whether or not it is currently in-use. " +
+ "Currently, this represents all stack memory for goroutines. It also includes all OS thread stacks in non-cgo programs. " +
+ "Note that stacks may be allocated differently in the future, and this may change.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/heap/unused:bytes",
+ Description: "Memory that is reserved for heap objects but is not currently used to hold heap objects.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/metadata/mcache/free:bytes",
+ Description: "Memory that is reserved for runtime mcache structures, but not in-use.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/metadata/mcache/inuse:bytes",
+ Description: "Memory that is occupied by runtime mcache structures that are currently being used.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/metadata/mspan/free:bytes",
+ Description: "Memory that is reserved for runtime mspan structures, but not in-use.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/metadata/mspan/inuse:bytes",
+ Description: "Memory that is occupied by runtime mspan structures that are currently being used.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/metadata/other:bytes",
+ Description: "Memory that is reserved for or used to hold runtime metadata.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/os-stacks:bytes",
+ Description: "Stack memory allocated by the underlying operating system. " +
+ "In non-cgo programs this metric is currently zero. This may change in the future." +
+ "In cgo programs this metric includes OS thread stacks allocated directly from the OS. " +
+ "Currently, this only accounts for one stack in c-shared and c-archive build modes, " +
+ "and other sources of stacks from the OS are not measured. This too may change in the future.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/other:bytes",
+ Description: "Memory used by execution trace buffers, structures for debugging the runtime, finalizer and profiler specials, and more.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/profiling/buckets:bytes",
+ Description: "Memory that is used by the stack trace hash map used for profiling.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/memory/classes/total:bytes",
+ Description: "All memory mapped by the Go runtime into the current process as read-write. Note that this does not include memory mapped by code called via cgo or via the syscall package. Sum of all metrics in /memory/classes.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/sched/gomaxprocs:threads",
+ Description: "The current runtime.GOMAXPROCS setting, or the number of operating system threads that can execute user-level Go code simultaneously.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/sched/goroutines:goroutines",
+ Description: "Count of live goroutines.",
+ Kind: KindUint64,
+ },
+ {
+ Name: "/sched/latencies:seconds",
+ Description: "Distribution of the time goroutines have spent in the scheduler in a runnable state before actually running. Bucket counts increase monotonically.",
+ Kind: KindFloat64Histogram,
+ Cumulative: true,
+ },
+ {
+ Name: "/sync/mutex/wait/total:seconds",
+ Description: "Approximate cumulative time goroutines have spent blocked on a sync.Mutex or sync.RWMutex. This metric is useful for identifying global changes in lock contention. Collect a mutex or block profile using the runtime/pprof package for more detailed contention data.",
+ Kind: KindFloat64,
+ Cumulative: true,
+ },
+}
+
+func init() {
+ // Insert all the non-default-reporting GODEBUGs into the table,
+ // preserving the overall sort order.
+ i := 0
+ for i < len(allDesc) && allDesc[i].Name < "/godebug/" {
+ i++
+ }
+ more := make([]Description, i, len(allDesc)+len(godebugs.All))
+ copy(more, allDesc)
+ for _, info := range godebugs.All {
+ if !info.Opaque {
+ more = append(more, Description{
+ Name: "/godebug/non-default-behavior/" + info.Name + ":events",
+ Description: "The number of non-default behaviors executed by the " +
+ info.Package + " package " + "due to a non-default " +
+ "GODEBUG=" + info.Name + "=... setting.",
+ Kind: KindUint64,
+ Cumulative: true,
+ })
+ }
+ }
+ allDesc = append(more, allDesc[i:]...)
+}
+
+// All returns a slice of containing metric descriptions for all supported metrics.
+func All() []Description {
+ return allDesc
+}
diff --git a/contrib/go/_std_1.21/src/runtime/metrics/doc.go b/contrib/go/_std_1.21/src/runtime/metrics/doc.go
new file mode 100644
index 0000000000..55d1f65f42
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/metrics/doc.go
@@ -0,0 +1,400 @@
+// 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.
+
+// Note: run 'go generate' (which will run 'go test -generate') to update the "Supported metrics" list.
+//go:generate go test -run=Docs -generate
+
+/*
+Package metrics provides a stable interface to access implementation-defined
+metrics exported by the Go runtime. This package is similar to existing functions
+like [runtime.ReadMemStats] and [debug.ReadGCStats], but significantly more general.
+
+The set of metrics defined by this package may evolve as the runtime itself
+evolves, and also enables variation across Go implementations, whose relevant
+metric sets may not intersect.
+
+# Interface
+
+Metrics are designated by a string key, rather than, for example, a field name in
+a struct. The full list of supported metrics is always available in the slice of
+Descriptions returned by All. Each Description also includes useful information
+about the metric.
+
+Thus, users of this API are encouraged to sample supported metrics defined by the
+slice returned by All to remain compatible across Go versions. Of course, situations
+arise where reading specific metrics is critical. For these cases, users are
+encouraged to use build tags, and although metrics may be deprecated and removed,
+users should consider this to be an exceptional and rare event, coinciding with a
+very large change in a particular Go implementation.
+
+Each metric key also has a "kind" that describes the format of the metric's value.
+In the interest of not breaking users of this package, the "kind" for a given metric
+is guaranteed not to change. If it must change, then a new metric will be introduced
+with a new key and a new "kind."
+
+# Metric key format
+
+As mentioned earlier, metric keys are strings. Their format is simple and well-defined,
+designed to be both human and machine readable. It is split into two components,
+separated by a colon: a rooted path and a unit. The choice to include the unit in
+the key is motivated by compatibility: if a metric's unit changes, its semantics likely
+did also, and a new key should be introduced.
+
+For more details on the precise definition of the metric key's path and unit formats, see
+the documentation of the Name field of the Description struct.
+
+# A note about floats
+
+This package supports metrics whose values have a floating-point representation. In
+order to improve ease-of-use, this package promises to never produce the following
+classes of floating-point values: NaN, infinity.
+
+# Supported metrics
+
+Below is the full list of supported metrics, ordered lexicographically.
+
+ /cgo/go-to-c-calls:calls
+ Count of calls made from Go to C by the current process.
+
+ /cpu/classes/gc/mark/assist:cpu-seconds
+ Estimated total CPU time goroutines spent performing GC
+ tasks to assist the GC and prevent it from falling behind the
+ application. This metric is an overestimate, and not directly
+ comparable to system CPU time measurements. Compare only with
+ other /cpu/classes metrics.
+
+ /cpu/classes/gc/mark/dedicated:cpu-seconds
+ Estimated total CPU time spent performing GC tasks on processors
+ (as defined by GOMAXPROCS) dedicated to those tasks. This metric
+ is an overestimate, and not directly comparable to system CPU
+ time measurements. Compare only with other /cpu/classes metrics.
+
+ /cpu/classes/gc/mark/idle:cpu-seconds
+ Estimated total CPU time spent performing GC tasks on spare CPU
+ resources that the Go scheduler could not otherwise find a use
+ for. This should be subtracted from the total GC CPU time to
+ obtain a measure of compulsory GC CPU time. This metric is an
+ overestimate, and not directly comparable to system CPU time
+ measurements. Compare only with other /cpu/classes metrics.
+
+ /cpu/classes/gc/pause:cpu-seconds
+ Estimated total CPU time spent with the application paused by
+ the GC. Even if only one thread is running during the pause,
+ this is computed as GOMAXPROCS times the pause latency because
+ nothing else can be executing. This is the exact sum of samples
+ in /gc/pause:seconds if each sample is multiplied by GOMAXPROCS
+ at the time it is taken. This metric is an overestimate,
+ and not directly comparable to system CPU time measurements.
+ Compare only with other /cpu/classes metrics.
+
+ /cpu/classes/gc/total:cpu-seconds
+ Estimated total CPU time spent performing GC tasks. This metric
+ is an overestimate, and not directly comparable to system CPU
+ time measurements. Compare only with other /cpu/classes metrics.
+ Sum of all metrics in /cpu/classes/gc.
+
+ /cpu/classes/idle:cpu-seconds
+ Estimated total available CPU time not spent executing
+ any Go or Go runtime code. In other words, the part of
+ /cpu/classes/total:cpu-seconds that was unused. This metric is
+ an overestimate, and not directly comparable to system CPU time
+ measurements. Compare only with other /cpu/classes metrics.
+
+ /cpu/classes/scavenge/assist:cpu-seconds
+ Estimated total CPU time spent returning unused memory to the
+ underlying platform in response eagerly in response to memory
+ pressure. This metric is an overestimate, and not directly
+ comparable to system CPU time measurements. Compare only with
+ other /cpu/classes metrics.
+
+ /cpu/classes/scavenge/background:cpu-seconds
+ Estimated total CPU time spent performing background tasks to
+ return unused memory to the underlying platform. This metric is
+ an overestimate, and not directly comparable to system CPU time
+ measurements. Compare only with other /cpu/classes metrics.
+
+ /cpu/classes/scavenge/total:cpu-seconds
+ Estimated total CPU time spent performing tasks that return
+ unused memory to the underlying platform. This metric is an
+ overestimate, and not directly comparable to system CPU time
+ measurements. Compare only with other /cpu/classes metrics.
+ Sum of all metrics in /cpu/classes/scavenge.
+
+ /cpu/classes/total:cpu-seconds
+ Estimated total available CPU time for user Go code or the Go
+ runtime, as defined by GOMAXPROCS. In other words, GOMAXPROCS
+ integrated over the wall-clock duration this process has been
+ executing for. This metric is an overestimate, and not directly
+ comparable to system CPU time measurements. Compare only with
+ other /cpu/classes metrics. Sum of all metrics in /cpu/classes.
+
+ /cpu/classes/user:cpu-seconds
+ Estimated total CPU time spent running user Go code. This may
+ also include some small amount of time spent in the Go runtime.
+ This metric is an overestimate, and not directly comparable
+ to system CPU time measurements. Compare only with other
+ /cpu/classes metrics.
+
+ /gc/cycles/automatic:gc-cycles
+ Count of completed GC cycles generated by the Go runtime.
+
+ /gc/cycles/forced:gc-cycles
+ Count of completed GC cycles forced by the application.
+
+ /gc/cycles/total:gc-cycles
+ Count of all completed GC cycles.
+
+ /gc/gogc:percent
+ Heap size target percentage configured by the user, otherwise
+ 100. This value is set by the GOGC environment variable, and the
+ runtime/debug.SetGCPercent function.
+
+ /gc/gomemlimit:bytes
+ Go runtime memory limit configured by the user, otherwise
+ math.MaxInt64. This value is set by the GOMEMLIMIT environment
+ variable, and the runtime/debug.SetMemoryLimit function.
+
+ /gc/heap/allocs-by-size:bytes
+ Distribution of heap allocations by approximate size.
+ Bucket counts increase monotonically. Note that this does not
+ include tiny objects as defined by /gc/heap/tiny/allocs:objects,
+ only tiny blocks.
+
+ /gc/heap/allocs:bytes
+ Cumulative sum of memory allocated to the heap by the
+ application.
+
+ /gc/heap/allocs:objects
+ Cumulative count of heap allocations triggered by the
+ application. Note that this does not include tiny objects as
+ defined by /gc/heap/tiny/allocs:objects, only tiny blocks.
+
+ /gc/heap/frees-by-size:bytes
+ Distribution of freed heap allocations by approximate size.
+ Bucket counts increase monotonically. Note that this does not
+ include tiny objects as defined by /gc/heap/tiny/allocs:objects,
+ only tiny blocks.
+
+ /gc/heap/frees:bytes
+ Cumulative sum of heap memory freed by the garbage collector.
+
+ /gc/heap/frees:objects
+ Cumulative count of heap allocations whose storage was freed
+ by the garbage collector. Note that this does not include tiny
+ objects as defined by /gc/heap/tiny/allocs:objects, only tiny
+ blocks.
+
+ /gc/heap/goal:bytes
+ Heap size target for the end of the GC cycle.
+
+ /gc/heap/live:bytes
+ Heap memory occupied by live objects that were marked by the
+ previous GC.
+
+ /gc/heap/objects:objects
+ Number of objects, live or unswept, occupying heap memory.
+
+ /gc/heap/tiny/allocs:objects
+ Count of small allocations that are packed together into blocks.
+ These allocations are counted separately from other allocations
+ because each individual allocation is not tracked by the
+ runtime, only their block. Each block is already accounted for
+ in allocs-by-size and frees-by-size.
+
+ /gc/limiter/last-enabled:gc-cycle
+ GC cycle the last time the GC CPU limiter was enabled.
+ This metric is useful for diagnosing the root cause of an
+ out-of-memory error, because the limiter trades memory for CPU
+ time when the GC's CPU time gets too high. This is most likely
+ to occur with use of SetMemoryLimit. The first GC cycle is cycle
+ 1, so a value of 0 indicates that it was never enabled.
+
+ /gc/pauses:seconds
+ Distribution of individual GC-related stop-the-world pause
+ latencies. Bucket counts increase monotonically.
+
+ /gc/scan/globals:bytes
+ The total amount of global variable space that is scannable.
+
+ /gc/scan/heap:bytes
+ The total amount of heap space that is scannable.
+
+ /gc/scan/stack:bytes
+ The number of bytes of stack that were scanned last GC cycle.
+
+ /gc/scan/total:bytes
+ The total amount space that is scannable. Sum of all metrics in
+ /gc/scan.
+
+ /gc/stack/starting-size:bytes
+ The stack size of new goroutines.
+
+ /godebug/non-default-behavior/execerrdot:events
+ The number of non-default behaviors executed by the os/exec
+ package due to a non-default GODEBUG=execerrdot=... setting.
+
+ /godebug/non-default-behavior/gocachehash:events
+ The number of non-default behaviors executed by the cmd/go
+ package due to a non-default GODEBUG=gocachehash=... setting.
+
+ /godebug/non-default-behavior/gocachetest:events
+ The number of non-default behaviors executed by the cmd/go
+ package due to a non-default GODEBUG=gocachetest=... setting.
+
+ /godebug/non-default-behavior/gocacheverify:events
+ The number of non-default behaviors executed by the cmd/go
+ package due to a non-default GODEBUG=gocacheverify=... setting.
+
+ /godebug/non-default-behavior/http2client:events
+ The number of non-default behaviors executed by the net/http
+ package due to a non-default GODEBUG=http2client=... setting.
+
+ /godebug/non-default-behavior/http2server:events
+ The number of non-default behaviors executed by the net/http
+ package due to a non-default GODEBUG=http2server=... setting.
+
+ /godebug/non-default-behavior/installgoroot:events
+ The number of non-default behaviors executed by the go/build
+ package due to a non-default GODEBUG=installgoroot=... setting.
+
+ /godebug/non-default-behavior/jstmpllitinterp:events
+ The number of non-default behaviors executed by
+ the html/template package due to a non-default
+ GODEBUG=jstmpllitinterp=... setting.
+
+ /godebug/non-default-behavior/multipartmaxheaders:events
+ The number of non-default behaviors executed by
+ the mime/multipart package due to a non-default
+ GODEBUG=multipartmaxheaders=... setting.
+
+ /godebug/non-default-behavior/multipartmaxparts:events
+ The number of non-default behaviors executed by
+ the mime/multipart package due to a non-default
+ GODEBUG=multipartmaxparts=... setting.
+
+ /godebug/non-default-behavior/multipathtcp:events
+ The number of non-default behaviors executed by the net package
+ due to a non-default GODEBUG=multipathtcp=... setting.
+
+ /godebug/non-default-behavior/panicnil:events
+ The number of non-default behaviors executed by the runtime
+ package due to a non-default GODEBUG=panicnil=... setting.
+
+ /godebug/non-default-behavior/randautoseed:events
+ The number of non-default behaviors executed by the math/rand
+ package due to a non-default GODEBUG=randautoseed=... setting.
+
+ /godebug/non-default-behavior/tarinsecurepath:events
+ The number of non-default behaviors executed by the archive/tar
+ package due to a non-default GODEBUG=tarinsecurepath=...
+ setting.
+
+ /godebug/non-default-behavior/tlsmaxrsasize:events
+ The number of non-default behaviors executed by the crypto/tls
+ package due to a non-default GODEBUG=tlsmaxrsasize=... setting.
+
+ /godebug/non-default-behavior/x509sha1:events
+ The number of non-default behaviors executed by the crypto/x509
+ package due to a non-default GODEBUG=x509sha1=... setting.
+
+ /godebug/non-default-behavior/x509usefallbackroots:events
+ The number of non-default behaviors executed by the crypto/x509
+ package due to a non-default GODEBUG=x509usefallbackroots=...
+ setting.
+
+ /godebug/non-default-behavior/zipinsecurepath:events
+ The number of non-default behaviors executed by the archive/zip
+ package due to a non-default GODEBUG=zipinsecurepath=...
+ setting.
+
+ /memory/classes/heap/free:bytes
+ Memory that is completely free and eligible to be returned to
+ the underlying system, but has not been. This metric is the
+ runtime's estimate of free address space that is backed by
+ physical memory.
+
+ /memory/classes/heap/objects:bytes
+ Memory occupied by live objects and dead objects that have not
+ yet been marked free by the garbage collector.
+
+ /memory/classes/heap/released:bytes
+ Memory that is completely free and has been returned to the
+ underlying system. This metric is the runtime's estimate of free
+ address space that is still mapped into the process, but is not
+ backed by physical memory.
+
+ /memory/classes/heap/stacks:bytes
+ Memory allocated from the heap that is reserved for stack space,
+ whether or not it is currently in-use. Currently, this
+ represents all stack memory for goroutines. It also includes all
+ OS thread stacks in non-cgo programs. Note that stacks may be
+ allocated differently in the future, and this may change.
+
+ /memory/classes/heap/unused:bytes
+ Memory that is reserved for heap objects but is not currently
+ used to hold heap objects.
+
+ /memory/classes/metadata/mcache/free:bytes
+ Memory that is reserved for runtime mcache structures, but not
+ in-use.
+
+ /memory/classes/metadata/mcache/inuse:bytes
+ Memory that is occupied by runtime mcache structures that are
+ currently being used.
+
+ /memory/classes/metadata/mspan/free:bytes
+ Memory that is reserved for runtime mspan structures, but not
+ in-use.
+
+ /memory/classes/metadata/mspan/inuse:bytes
+ Memory that is occupied by runtime mspan structures that are
+ currently being used.
+
+ /memory/classes/metadata/other:bytes
+ Memory that is reserved for or used to hold runtime metadata.
+
+ /memory/classes/os-stacks:bytes
+ Stack memory allocated by the underlying operating system.
+ In non-cgo programs this metric is currently zero. This may
+ change in the future.In cgo programs this metric includes
+ OS thread stacks allocated directly from the OS. Currently,
+ this only accounts for one stack in c-shared and c-archive build
+ modes, and other sources of stacks from the OS are not measured.
+ This too may change in the future.
+
+ /memory/classes/other:bytes
+ Memory used by execution trace buffers, structures for debugging
+ the runtime, finalizer and profiler specials, and more.
+
+ /memory/classes/profiling/buckets:bytes
+ Memory that is used by the stack trace hash map used for
+ profiling.
+
+ /memory/classes/total:bytes
+ All memory mapped by the Go runtime into the current process
+ as read-write. Note that this does not include memory mapped
+ by code called via cgo or via the syscall package. Sum of all
+ metrics in /memory/classes.
+
+ /sched/gomaxprocs:threads
+ The current runtime.GOMAXPROCS setting, or the number of
+ operating system threads that can execute user-level Go code
+ simultaneously.
+
+ /sched/goroutines:goroutines
+ Count of live goroutines.
+
+ /sched/latencies:seconds
+ Distribution of the time goroutines have spent in the scheduler
+ in a runnable state before actually running. Bucket counts
+ increase monotonically.
+
+ /sync/mutex/wait/total:seconds
+ Approximate cumulative time goroutines have spent blocked
+ on a sync.Mutex or sync.RWMutex. This metric is useful for
+ identifying global changes in lock contention. Collect a mutex
+ or block profile using the runtime/pprof package for more
+ detailed contention data.
+*/
+package metrics
diff --git a/contrib/go/_std_1.20/src/runtime/metrics/histogram.go b/contrib/go/_std_1.21/src/runtime/metrics/histogram.go
index 956422bf84..956422bf84 100644
--- a/contrib/go/_std_1.20/src/runtime/metrics/histogram.go
+++ b/contrib/go/_std_1.21/src/runtime/metrics/histogram.go
diff --git a/contrib/go/_std_1.20/src/runtime/metrics/sample.go b/contrib/go/_std_1.21/src/runtime/metrics/sample.go
index 4cf8cdf799..4cf8cdf799 100644
--- a/contrib/go/_std_1.20/src/runtime/metrics/sample.go
+++ b/contrib/go/_std_1.21/src/runtime/metrics/sample.go
diff --git a/contrib/go/_std_1.20/src/runtime/metrics/value.go b/contrib/go/_std_1.21/src/runtime/metrics/value.go
index ed9a33d87c..ed9a33d87c 100644
--- a/contrib/go/_std_1.20/src/runtime/metrics/value.go
+++ b/contrib/go/_std_1.21/src/runtime/metrics/value.go
diff --git a/contrib/go/_std_1.21/src/runtime/metrics/ya.make b/contrib/go/_std_1.21/src/runtime/metrics/ya.make
new file mode 100644
index 0000000000..51aa4e989d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/metrics/ya.make
@@ -0,0 +1,19 @@
+GO_LIBRARY()
+
+SRCS(
+ description.go
+ doc.go
+ histogram.go
+ sample.go
+ value.go
+)
+
+GO_XTEST_SRCS(
+ description_test.go
+ example_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/runtime/mfinal.go b/contrib/go/_std_1.21/src/runtime/mfinal.go
new file mode 100644
index 0000000000..650db18105
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mfinal.go
@@ -0,0 +1,525 @@
+// Copyright 2009 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.
+
+// Garbage collector: finalizers and block profiling.
+
+package runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// finblock is an array of finalizers to be executed. finblocks are
+// arranged in a linked list for the finalizer queue.
+//
+// finblock is allocated from non-GC'd memory, so any heap pointers
+// must be specially handled. GC currently assumes that the finalizer
+// queue does not grow during marking (but it can shrink).
+type finblock struct {
+ _ sys.NotInHeap
+ alllink *finblock
+ next *finblock
+ cnt uint32
+ _ int32
+ fin [(_FinBlockSize - 2*goarch.PtrSize - 2*4) / unsafe.Sizeof(finalizer{})]finalizer
+}
+
+var fingStatus atomic.Uint32
+
+// finalizer goroutine status.
+const (
+ fingUninitialized uint32 = iota
+ fingCreated uint32 = 1 << (iota - 1)
+ fingRunningFinalizer
+ fingWait
+ fingWake
+)
+
+var finlock mutex // protects the following variables
+var fing *g // goroutine that runs finalizers
+var finq *finblock // list of finalizers that are to be executed
+var finc *finblock // cache of free blocks
+var finptrmask [_FinBlockSize / goarch.PtrSize / 8]byte
+
+var allfin *finblock // list of all blocks
+
+// NOTE: Layout known to queuefinalizer.
+type finalizer struct {
+ fn *funcval // function to call (may be a heap pointer)
+ arg unsafe.Pointer // ptr to object (may be a heap pointer)
+ nret uintptr // bytes of return values from fn
+ fint *_type // type of first argument of fn
+ ot *ptrtype // type of ptr to object (may be a heap pointer)
+}
+
+var finalizer1 = [...]byte{
+ // Each Finalizer is 5 words, ptr ptr INT ptr ptr (INT = uintptr here)
+ // Each byte describes 8 words.
+ // Need 8 Finalizers described by 5 bytes before pattern repeats:
+ // ptr ptr INT ptr ptr
+ // ptr ptr INT ptr ptr
+ // ptr ptr INT ptr ptr
+ // ptr ptr INT ptr ptr
+ // ptr ptr INT ptr ptr
+ // ptr ptr INT ptr ptr
+ // ptr ptr INT ptr ptr
+ // ptr ptr INT ptr ptr
+ // aka
+ //
+ // ptr ptr INT ptr ptr ptr ptr INT
+ // ptr ptr ptr ptr INT ptr ptr ptr
+ // ptr INT ptr ptr ptr ptr INT ptr
+ // ptr ptr ptr INT ptr ptr ptr ptr
+ // INT ptr ptr ptr ptr INT ptr ptr
+ //
+ // Assumptions about Finalizer layout checked below.
+ 1<<0 | 1<<1 | 0<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6 | 0<<7,
+ 1<<0 | 1<<1 | 1<<2 | 1<<3 | 0<<4 | 1<<5 | 1<<6 | 1<<7,
+ 1<<0 | 0<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 0<<6 | 1<<7,
+ 1<<0 | 1<<1 | 1<<2 | 0<<3 | 1<<4 | 1<<5 | 1<<6 | 1<<7,
+ 0<<0 | 1<<1 | 1<<2 | 1<<3 | 1<<4 | 0<<5 | 1<<6 | 1<<7,
+}
+
+// lockRankMayQueueFinalizer records the lock ranking effects of a
+// function that may call queuefinalizer.
+func lockRankMayQueueFinalizer() {
+ lockWithRankMayAcquire(&finlock, getLockRank(&finlock))
+}
+
+func queuefinalizer(p unsafe.Pointer, fn *funcval, nret uintptr, fint *_type, ot *ptrtype) {
+ if gcphase != _GCoff {
+ // Currently we assume that the finalizer queue won't
+ // grow during marking so we don't have to rescan it
+ // during mark termination. If we ever need to lift
+ // this assumption, we can do it by adding the
+ // necessary barriers to queuefinalizer (which it may
+ // have automatically).
+ throw("queuefinalizer during GC")
+ }
+
+ lock(&finlock)
+ if finq == nil || finq.cnt == uint32(len(finq.fin)) {
+ if finc == nil {
+ finc = (*finblock)(persistentalloc(_FinBlockSize, 0, &memstats.gcMiscSys))
+ finc.alllink = allfin
+ allfin = finc
+ if finptrmask[0] == 0 {
+ // Build pointer mask for Finalizer array in block.
+ // Check assumptions made in finalizer1 array above.
+ if (unsafe.Sizeof(finalizer{}) != 5*goarch.PtrSize ||
+ unsafe.Offsetof(finalizer{}.fn) != 0 ||
+ unsafe.Offsetof(finalizer{}.arg) != goarch.PtrSize ||
+ unsafe.Offsetof(finalizer{}.nret) != 2*goarch.PtrSize ||
+ unsafe.Offsetof(finalizer{}.fint) != 3*goarch.PtrSize ||
+ unsafe.Offsetof(finalizer{}.ot) != 4*goarch.PtrSize) {
+ throw("finalizer out of sync")
+ }
+ for i := range finptrmask {
+ finptrmask[i] = finalizer1[i%len(finalizer1)]
+ }
+ }
+ }
+ block := finc
+ finc = block.next
+ block.next = finq
+ finq = block
+ }
+ f := &finq.fin[finq.cnt]
+ atomic.Xadd(&finq.cnt, +1) // Sync with markroots
+ f.fn = fn
+ f.nret = nret
+ f.fint = fint
+ f.ot = ot
+ f.arg = p
+ unlock(&finlock)
+ fingStatus.Or(fingWake)
+}
+
+//go:nowritebarrier
+func iterate_finq(callback func(*funcval, unsafe.Pointer, uintptr, *_type, *ptrtype)) {
+ for fb := allfin; fb != nil; fb = fb.alllink {
+ for i := uint32(0); i < fb.cnt; i++ {
+ f := &fb.fin[i]
+ callback(f.fn, f.arg, f.nret, f.fint, f.ot)
+ }
+ }
+}
+
+func wakefing() *g {
+ if ok := fingStatus.CompareAndSwap(fingCreated|fingWait|fingWake, fingCreated); ok {
+ return fing
+ }
+ return nil
+}
+
+func createfing() {
+ // start the finalizer goroutine exactly once
+ if fingStatus.Load() == fingUninitialized && fingStatus.CompareAndSwap(fingUninitialized, fingCreated) {
+ go runfinq()
+ }
+}
+
+func finalizercommit(gp *g, lock unsafe.Pointer) bool {
+ unlock((*mutex)(lock))
+ // fingStatus should be modified after fing is put into a waiting state
+ // to avoid waking fing in running state, even if it is about to be parked.
+ fingStatus.Or(fingWait)
+ return true
+}
+
+// This is the goroutine that runs all of the finalizers.
+func runfinq() {
+ var (
+ frame unsafe.Pointer
+ framecap uintptr
+ argRegs int
+ )
+
+ gp := getg()
+ lock(&finlock)
+ fing = gp
+ unlock(&finlock)
+
+ for {
+ lock(&finlock)
+ fb := finq
+ finq = nil
+ if fb == nil {
+ gopark(finalizercommit, unsafe.Pointer(&finlock), waitReasonFinalizerWait, traceBlockSystemGoroutine, 1)
+ continue
+ }
+ argRegs = intArgRegs
+ unlock(&finlock)
+ if raceenabled {
+ racefingo()
+ }
+ for fb != nil {
+ for i := fb.cnt; i > 0; i-- {
+ f := &fb.fin[i-1]
+
+ var regs abi.RegArgs
+ // The args may be passed in registers or on stack. Even for
+ // the register case, we still need the spill slots.
+ // TODO: revisit if we remove spill slots.
+ //
+ // Unfortunately because we can have an arbitrary
+ // amount of returns and it would be complex to try and
+ // figure out how many of those can get passed in registers,
+ // just conservatively assume none of them do.
+ framesz := unsafe.Sizeof((any)(nil)) + f.nret
+ if framecap < framesz {
+ // The frame does not contain pointers interesting for GC,
+ // all not yet finalized objects are stored in finq.
+ // If we do not mark it as FlagNoScan,
+ // the last finalized object is not collected.
+ frame = mallocgc(framesz, nil, true)
+ framecap = framesz
+ }
+
+ if f.fint == nil {
+ throw("missing type in runfinq")
+ }
+ r := frame
+ if argRegs > 0 {
+ r = unsafe.Pointer(&regs.Ints)
+ } else {
+ // frame is effectively uninitialized
+ // memory. That means we have to clear
+ // it before writing to it to avoid
+ // confusing the write barrier.
+ *(*[2]uintptr)(frame) = [2]uintptr{}
+ }
+ switch f.fint.Kind_ & kindMask {
+ case kindPtr:
+ // direct use of pointer
+ *(*unsafe.Pointer)(r) = f.arg
+ case kindInterface:
+ ityp := (*interfacetype)(unsafe.Pointer(f.fint))
+ // set up with empty interface
+ (*eface)(r)._type = &f.ot.Type
+ (*eface)(r).data = f.arg
+ if len(ityp.Methods) != 0 {
+ // convert to interface with methods
+ // this conversion is guaranteed to succeed - we checked in SetFinalizer
+ (*iface)(r).tab = assertE2I(ityp, (*eface)(r)._type)
+ }
+ default:
+ throw("bad kind in runfinq")
+ }
+ fingStatus.Or(fingRunningFinalizer)
+ reflectcall(nil, unsafe.Pointer(f.fn), frame, uint32(framesz), uint32(framesz), uint32(framesz), &regs)
+ fingStatus.And(^fingRunningFinalizer)
+
+ // Drop finalizer queue heap references
+ // before hiding them from markroot.
+ // This also ensures these will be
+ // clear if we reuse the finalizer.
+ f.fn = nil
+ f.arg = nil
+ f.ot = nil
+ atomic.Store(&fb.cnt, i-1)
+ }
+ next := fb.next
+ lock(&finlock)
+ fb.next = finc
+ finc = fb
+ unlock(&finlock)
+ fb = next
+ }
+ }
+}
+
+func isGoPointerWithoutSpan(p unsafe.Pointer) bool {
+ // 0-length objects are okay.
+ if p == unsafe.Pointer(&zerobase) {
+ return true
+ }
+
+ // Global initializers might be linker-allocated.
+ // var Foo = &Object{}
+ // func main() {
+ // runtime.SetFinalizer(Foo, nil)
+ // }
+ // The relevant segments are: noptrdata, data, bss, noptrbss.
+ // We cannot assume they are in any order or even contiguous,
+ // due to external linking.
+ for datap := &firstmoduledata; datap != nil; datap = datap.next {
+ if datap.noptrdata <= uintptr(p) && uintptr(p) < datap.enoptrdata ||
+ datap.data <= uintptr(p) && uintptr(p) < datap.edata ||
+ datap.bss <= uintptr(p) && uintptr(p) < datap.ebss ||
+ datap.noptrbss <= uintptr(p) && uintptr(p) < datap.enoptrbss {
+ return true
+ }
+ }
+ return false
+}
+
+// SetFinalizer sets the finalizer associated with obj to the provided
+// finalizer function. When the garbage collector finds an unreachable block
+// with an associated finalizer, it clears the association and runs
+// finalizer(obj) in a separate goroutine. This makes obj reachable again,
+// but now without an associated finalizer. Assuming that SetFinalizer
+// is not called again, the next time the garbage collector sees
+// that obj is unreachable, it will free obj.
+//
+// SetFinalizer(obj, nil) clears any finalizer associated with obj.
+//
+// The argument obj must be a pointer to an object allocated by calling
+// new, by taking the address of a composite literal, or by taking the
+// address of a local variable.
+// The argument finalizer must be a function that takes a single argument
+// to which obj's type can be assigned, and can have arbitrary ignored return
+// values. If either of these is not true, SetFinalizer may abort the
+// program.
+//
+// Finalizers are run in dependency order: if A points at B, both have
+// finalizers, and they are otherwise unreachable, only the finalizer
+// for A runs; once A is freed, the finalizer for B can run.
+// If a cyclic structure includes a block with a finalizer, that
+// cycle is not guaranteed to be garbage collected and the finalizer
+// is not guaranteed to run, because there is no ordering that
+// respects the dependencies.
+//
+// The finalizer is scheduled to run at some arbitrary time after the
+// program can no longer reach the object to which obj points.
+// There is no guarantee that finalizers will run before a program exits,
+// so typically they are useful only for releasing non-memory resources
+// associated with an object during a long-running program.
+// For example, an os.File object could use a finalizer to close the
+// associated operating system file descriptor when a program discards
+// an os.File without calling Close, but it would be a mistake
+// to depend on a finalizer to flush an in-memory I/O buffer such as a
+// bufio.Writer, because the buffer would not be flushed at program exit.
+//
+// It is not guaranteed that a finalizer will run if the size of *obj is
+// zero bytes, because it may share same address with other zero-size
+// objects in memory. See https://go.dev/ref/spec#Size_and_alignment_guarantees.
+//
+// It is not guaranteed that a finalizer will run for objects allocated
+// in initializers for package-level variables. Such objects may be
+// linker-allocated, not heap-allocated.
+//
+// Note that because finalizers may execute arbitrarily far into the future
+// after an object is no longer referenced, the runtime is allowed to perform
+// a space-saving optimization that batches objects together in a single
+// allocation slot. The finalizer for an unreferenced object in such an
+// allocation may never run if it always exists in the same batch as a
+// referenced object. Typically, this batching only happens for tiny
+// (on the order of 16 bytes or less) and pointer-free objects.
+//
+// A finalizer may run as soon as an object becomes unreachable.
+// In order to use finalizers correctly, the program must ensure that
+// the object is reachable until it is no longer required.
+// Objects stored in global variables, or that can be found by tracing
+// pointers from a global variable, are reachable. For other objects,
+// pass the object to a call of the KeepAlive function to mark the
+// last point in the function where the object must be reachable.
+//
+// For example, if p points to a struct, such as os.File, that contains
+// a file descriptor d, and p has a finalizer that closes that file
+// descriptor, and if the last use of p in a function is a call to
+// syscall.Write(p.d, buf, size), then p may be unreachable as soon as
+// the program enters syscall.Write. The finalizer may run at that moment,
+// closing p.d, causing syscall.Write to fail because it is writing to
+// a closed file descriptor (or, worse, to an entirely different
+// file descriptor opened by a different goroutine). To avoid this problem,
+// call KeepAlive(p) after the call to syscall.Write.
+//
+// A single goroutine runs all finalizers for a program, sequentially.
+// If a finalizer must run for a long time, it should do so by starting
+// a new goroutine.
+//
+// In the terminology of the Go memory model, a call
+// SetFinalizer(x, f) “synchronizes before” the finalization call f(x).
+// However, there is no guarantee that KeepAlive(x) or any other use of x
+// “synchronizes before” f(x), so in general a finalizer should use a mutex
+// or other synchronization mechanism if it needs to access mutable state in x.
+// For example, consider a finalizer that inspects a mutable field in x
+// that is modified from time to time in the main program before x
+// becomes unreachable and the finalizer is invoked.
+// The modifications in the main program and the inspection in the finalizer
+// need to use appropriate synchronization, such as mutexes or atomic updates,
+// to avoid read-write races.
+func SetFinalizer(obj any, finalizer any) {
+ if debug.sbrk != 0 {
+ // debug.sbrk never frees memory, so no finalizers run
+ // (and we don't have the data structures to record them).
+ return
+ }
+ e := efaceOf(&obj)
+ etyp := e._type
+ if etyp == nil {
+ throw("runtime.SetFinalizer: first argument is nil")
+ }
+ if etyp.Kind_&kindMask != kindPtr {
+ throw("runtime.SetFinalizer: first argument is " + toRType(etyp).string() + ", not pointer")
+ }
+ ot := (*ptrtype)(unsafe.Pointer(etyp))
+ if ot.Elem == nil {
+ throw("nil elem type!")
+ }
+
+ if inUserArenaChunk(uintptr(e.data)) {
+ // Arena-allocated objects are not eligible for finalizers.
+ throw("runtime.SetFinalizer: first argument was allocated into an arena")
+ }
+
+ // find the containing object
+ base, _, _ := findObject(uintptr(e.data), 0, 0)
+
+ if base == 0 {
+ if isGoPointerWithoutSpan(e.data) {
+ return
+ }
+ throw("runtime.SetFinalizer: pointer not in allocated block")
+ }
+
+ if uintptr(e.data) != base {
+ // As an implementation detail we allow to set finalizers for an inner byte
+ // of an object if it could come from tiny alloc (see mallocgc for details).
+ if ot.Elem == nil || ot.Elem.PtrBytes != 0 || ot.Elem.Size_ >= maxTinySize {
+ throw("runtime.SetFinalizer: pointer not at beginning of allocated block")
+ }
+ }
+
+ f := efaceOf(&finalizer)
+ ftyp := f._type
+ if ftyp == nil {
+ // switch to system stack and remove finalizer
+ systemstack(func() {
+ removefinalizer(e.data)
+ })
+ return
+ }
+
+ if ftyp.Kind_&kindMask != kindFunc {
+ throw("runtime.SetFinalizer: second argument is " + toRType(ftyp).string() + ", not a function")
+ }
+ ft := (*functype)(unsafe.Pointer(ftyp))
+ if ft.IsVariadic() {
+ throw("runtime.SetFinalizer: cannot pass " + toRType(etyp).string() + " to finalizer " + toRType(ftyp).string() + " because dotdotdot")
+ }
+ if ft.InCount != 1 {
+ throw("runtime.SetFinalizer: cannot pass " + toRType(etyp).string() + " to finalizer " + toRType(ftyp).string())
+ }
+ fint := ft.InSlice()[0]
+ switch {
+ case fint == etyp:
+ // ok - same type
+ goto okarg
+ case fint.Kind_&kindMask == kindPtr:
+ if (fint.Uncommon() == nil || etyp.Uncommon() == nil) && (*ptrtype)(unsafe.Pointer(fint)).Elem == ot.Elem {
+ // ok - not same type, but both pointers,
+ // one or the other is unnamed, and same element type, so assignable.
+ goto okarg
+ }
+ case fint.Kind_&kindMask == kindInterface:
+ ityp := (*interfacetype)(unsafe.Pointer(fint))
+ if len(ityp.Methods) == 0 {
+ // ok - satisfies empty interface
+ goto okarg
+ }
+ if iface := assertE2I2(ityp, *efaceOf(&obj)); iface.tab != nil {
+ goto okarg
+ }
+ }
+ throw("runtime.SetFinalizer: cannot pass " + toRType(etyp).string() + " to finalizer " + toRType(ftyp).string())
+okarg:
+ // compute size needed for return parameters
+ nret := uintptr(0)
+ for _, t := range ft.OutSlice() {
+ nret = alignUp(nret, uintptr(t.Align_)) + uintptr(t.Size_)
+ }
+ nret = alignUp(nret, goarch.PtrSize)
+
+ // make sure we have a finalizer goroutine
+ createfing()
+
+ systemstack(func() {
+ if !addfinalizer(e.data, (*funcval)(f.data), nret, fint, ot) {
+ throw("runtime.SetFinalizer: finalizer already set")
+ }
+ })
+}
+
+// Mark KeepAlive as noinline so that it is easily detectable as an intrinsic.
+//
+//go:noinline
+
+// KeepAlive marks its argument as currently reachable.
+// This ensures that the object is not freed, and its finalizer is not run,
+// before the point in the program where KeepAlive is called.
+//
+// A very simplified example showing where KeepAlive is required:
+//
+// type File struct { d int }
+// d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0)
+// // ... do something if err != nil ...
+// p := &File{d}
+// runtime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) })
+// var buf [10]byte
+// n, err := syscall.Read(p.d, buf[:])
+// // Ensure p is not finalized until Read returns.
+// runtime.KeepAlive(p)
+// // No more uses of p after this point.
+//
+// Without the KeepAlive call, the finalizer could run at the start of
+// syscall.Read, closing the file descriptor before syscall.Read makes
+// the actual system call.
+//
+// Note: KeepAlive should only be used to prevent finalizers from
+// running prematurely. In particular, when used with unsafe.Pointer,
+// the rules for valid uses of unsafe.Pointer still apply.
+func KeepAlive(x any) {
+ // Introduce a use of x that the compiler can't eliminate.
+ // This makes sure x is alive on entry. We need x to be alive
+ // on entry for "defer runtime.KeepAlive(x)"; see issue 21402.
+ if cgoAlwaysFalse {
+ println(x)
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mfixalloc.go b/contrib/go/_std_1.21/src/runtime/mfixalloc.go
new file mode 100644
index 0000000000..1a249e5981
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mfixalloc.go
@@ -0,0 +1,111 @@
+// Copyright 2009 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.
+
+// Fixed-size object allocator. Returned memory is not zeroed.
+//
+// See malloc.go for overview.
+
+package runtime
+
+import (
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// fixalloc is a simple free-list allocator for fixed size objects.
+// Malloc uses a FixAlloc wrapped around sysAlloc to manage its
+// mcache and mspan objects.
+//
+// Memory returned by fixalloc.alloc is zeroed by default, but the
+// caller may take responsibility for zeroing allocations by setting
+// the zero flag to false. This is only safe if the memory never
+// contains heap pointers.
+//
+// The caller is responsible for locking around FixAlloc calls.
+// Callers can keep state in the object but the first word is
+// smashed by freeing and reallocating.
+//
+// Consider marking fixalloc'd types not in heap by embedding
+// runtime/internal/sys.NotInHeap.
+type fixalloc struct {
+ size uintptr
+ first func(arg, p unsafe.Pointer) // called first time p is returned
+ arg unsafe.Pointer
+ list *mlink
+ chunk uintptr // use uintptr instead of unsafe.Pointer to avoid write barriers
+ nchunk uint32 // bytes remaining in current chunk
+ nalloc uint32 // size of new chunks in bytes
+ inuse uintptr // in-use bytes now
+ stat *sysMemStat
+ zero bool // zero allocations
+}
+
+// A generic linked list of blocks. (Typically the block is bigger than sizeof(MLink).)
+// Since assignments to mlink.next will result in a write barrier being performed
+// this cannot be used by some of the internal GC structures. For example when
+// the sweeper is placing an unmarked object on the free list it does not want the
+// write barrier to be called since that could result in the object being reachable.
+type mlink struct {
+ _ sys.NotInHeap
+ next *mlink
+}
+
+// Initialize f to allocate objects of the given size,
+// using the allocator to obtain chunks of memory.
+func (f *fixalloc) init(size uintptr, first func(arg, p unsafe.Pointer), arg unsafe.Pointer, stat *sysMemStat) {
+ if size > _FixAllocChunk {
+ throw("runtime: fixalloc size too large")
+ }
+ if min := unsafe.Sizeof(mlink{}); size < min {
+ size = min
+ }
+
+ f.size = size
+ f.first = first
+ f.arg = arg
+ f.list = nil
+ f.chunk = 0
+ f.nchunk = 0
+ f.nalloc = uint32(_FixAllocChunk / size * size) // Round _FixAllocChunk down to an exact multiple of size to eliminate tail waste
+ f.inuse = 0
+ f.stat = stat
+ f.zero = true
+}
+
+func (f *fixalloc) alloc() unsafe.Pointer {
+ if f.size == 0 {
+ print("runtime: use of FixAlloc_Alloc before FixAlloc_Init\n")
+ throw("runtime: internal error")
+ }
+
+ if f.list != nil {
+ v := unsafe.Pointer(f.list)
+ f.list = f.list.next
+ f.inuse += f.size
+ if f.zero {
+ memclrNoHeapPointers(v, f.size)
+ }
+ return v
+ }
+ if uintptr(f.nchunk) < f.size {
+ f.chunk = uintptr(persistentalloc(uintptr(f.nalloc), 0, f.stat))
+ f.nchunk = f.nalloc
+ }
+
+ v := unsafe.Pointer(f.chunk)
+ if f.first != nil {
+ f.first(f.arg, v)
+ }
+ f.chunk = f.chunk + f.size
+ f.nchunk -= uint32(f.size)
+ f.inuse += f.size
+ return v
+}
+
+func (f *fixalloc) free(p unsafe.Pointer) {
+ f.inuse -= f.size
+ v := (*mlink)(p)
+ v.next = f.list
+ f.list = v
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mgc.go b/contrib/go/_std_1.21/src/runtime/mgc.go
new file mode 100644
index 0000000000..de5ae0ae00
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mgc.go
@@ -0,0 +1,1816 @@
+// Copyright 2009 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.
+
+// Garbage collector (GC).
+//
+// The GC runs concurrently with mutator threads, is type accurate (aka precise), allows multiple
+// GC thread to run in parallel. It is a concurrent mark and sweep that uses a write barrier. It is
+// non-generational and non-compacting. Allocation is done using size segregated per P allocation
+// areas to minimize fragmentation while eliminating locks in the common case.
+//
+// The algorithm decomposes into several steps.
+// This is a high level description of the algorithm being used. For an overview of GC a good
+// place to start is Richard Jones' gchandbook.org.
+//
+// The algorithm's intellectual heritage includes Dijkstra's on-the-fly algorithm, see
+// Edsger W. Dijkstra, Leslie Lamport, A. J. Martin, C. S. Scholten, and E. F. M. Steffens. 1978.
+// On-the-fly garbage collection: an exercise in cooperation. Commun. ACM 21, 11 (November 1978),
+// 966-975.
+// For journal quality proofs that these steps are complete, correct, and terminate see
+// Hudson, R., and Moss, J.E.B. Copying Garbage Collection without stopping the world.
+// Concurrency and Computation: Practice and Experience 15(3-5), 2003.
+//
+// 1. GC performs sweep termination.
+//
+// a. Stop the world. This causes all Ps to reach a GC safe-point.
+//
+// b. Sweep any unswept spans. There will only be unswept spans if
+// this GC cycle was forced before the expected time.
+//
+// 2. GC performs the mark phase.
+//
+// a. Prepare for the mark phase by setting gcphase to _GCmark
+// (from _GCoff), enabling the write barrier, enabling mutator
+// assists, and enqueueing root mark jobs. No objects may be
+// scanned until all Ps have enabled the write barrier, which is
+// accomplished using STW.
+//
+// b. Start the world. From this point, GC work is done by mark
+// workers started by the scheduler and by assists performed as
+// part of allocation. The write barrier shades both the
+// overwritten pointer and the new pointer value for any pointer
+// writes (see mbarrier.go for details). Newly allocated objects
+// are immediately marked black.
+//
+// c. GC performs root marking jobs. This includes scanning all
+// stacks, shading all globals, and shading any heap pointers in
+// off-heap runtime data structures. Scanning a stack stops a
+// goroutine, shades any pointers found on its stack, and then
+// resumes the goroutine.
+//
+// d. GC drains the work queue of grey objects, scanning each grey
+// object to black and shading all pointers found in the object
+// (which in turn may add those pointers to the work queue).
+//
+// e. Because GC work is spread across local caches, GC uses a
+// distributed termination algorithm to detect when there are no
+// more root marking jobs or grey objects (see gcMarkDone). At this
+// point, GC transitions to mark termination.
+//
+// 3. GC performs mark termination.
+//
+// a. Stop the world.
+//
+// b. Set gcphase to _GCmarktermination, and disable workers and
+// assists.
+//
+// c. Perform housekeeping like flushing mcaches.
+//
+// 4. GC performs the sweep phase.
+//
+// a. Prepare for the sweep phase by setting gcphase to _GCoff,
+// setting up sweep state and disabling the write barrier.
+//
+// b. Start the world. From this point on, newly allocated objects
+// are white, and allocating sweeps spans before use if necessary.
+//
+// c. GC does concurrent sweeping in the background and in response
+// to allocation. See description below.
+//
+// 5. When sufficient allocation has taken place, replay the sequence
+// starting with 1 above. See discussion of GC rate below.
+
+// Concurrent sweep.
+//
+// The sweep phase proceeds concurrently with normal program execution.
+// The heap is swept span-by-span both lazily (when a goroutine needs another span)
+// and concurrently in a background goroutine (this helps programs that are not CPU bound).
+// At the end of STW mark termination all spans are marked as "needs sweeping".
+//
+// The background sweeper goroutine simply sweeps spans one-by-one.
+//
+// To avoid requesting more OS memory while there are unswept spans, when a
+// goroutine needs another span, it first attempts to reclaim that much memory
+// by sweeping. When a goroutine needs to allocate a new small-object span, it
+// sweeps small-object spans for the same object size until it frees at least
+// one object. When a goroutine needs to allocate large-object span from heap,
+// it sweeps spans until it frees at least that many pages into heap. There is
+// one case where this may not suffice: if a goroutine sweeps and frees two
+// nonadjacent one-page spans to the heap, it will allocate a new two-page
+// span, but there can still be other one-page unswept spans which could be
+// combined into a two-page span.
+//
+// It's critical to ensure that no operations proceed on unswept spans (that would corrupt
+// mark bits in GC bitmap). During GC all mcaches are flushed into the central cache,
+// so they are empty. When a goroutine grabs a new span into mcache, it sweeps it.
+// When a goroutine explicitly frees an object or sets a finalizer, it ensures that
+// the span is swept (either by sweeping it, or by waiting for the concurrent sweep to finish).
+// The finalizer goroutine is kicked off only when all spans are swept.
+// When the next GC starts, it sweeps all not-yet-swept spans (if any).
+
+// GC rate.
+// Next GC is after we've allocated an extra amount of memory proportional to
+// the amount already in use. The proportion is controlled by GOGC environment variable
+// (100 by default). If GOGC=100 and we're using 4M, we'll GC again when we get to 8M
+// (this mark is computed by the gcController.heapGoal method). This keeps the GC cost in
+// linear proportion to the allocation cost. Adjusting GOGC just changes the linear constant
+// (and also the amount of extra memory used).
+
+// Oblets
+//
+// In order to prevent long pauses while scanning large objects and to
+// improve parallelism, the garbage collector breaks up scan jobs for
+// objects larger than maxObletBytes into "oblets" of at most
+// maxObletBytes. When scanning encounters the beginning of a large
+// object, it scans only the first oblet and enqueues the remaining
+// oblets as new scan jobs.
+
+package runtime
+
+import (
+ "internal/cpu"
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+const (
+ _DebugGC = 0
+ _ConcurrentSweep = true
+ _FinBlockSize = 4 * 1024
+
+ // debugScanConservative enables debug logging for stack
+ // frames that are scanned conservatively.
+ debugScanConservative = false
+
+ // sweepMinHeapDistance is a lower bound on the heap distance
+ // (in bytes) reserved for concurrent sweeping between GC
+ // cycles.
+ sweepMinHeapDistance = 1024 * 1024
+)
+
+// heapObjectsCanMove always returns false in the current garbage collector.
+// It exists for go4.org/unsafe/assume-no-moving-gc, which is an
+// unfortunate idea that had an even more unfortunate implementation.
+// Every time a new Go release happened, the package stopped building,
+// and the authors had to add a new file with a new //go:build line, and
+// then the entire ecosystem of packages with that as a dependency had to
+// explicitly update to the new version. Many packages depend on
+// assume-no-moving-gc transitively, through paths like
+// inet.af/netaddr -> go4.org/intern -> assume-no-moving-gc.
+// This was causing a significant amount of friction around each new
+// release, so we added this bool for the package to //go:linkname
+// instead. The bool is still unfortunate, but it's not as bad as
+// breaking the ecosystem on every new release.
+//
+// If the Go garbage collector ever does move heap objects, we can set
+// this to true to break all the programs using assume-no-moving-gc.
+//
+//go:linkname heapObjectsCanMove
+func heapObjectsCanMove() bool {
+ return false
+}
+
+func gcinit() {
+ if unsafe.Sizeof(workbuf{}) != _WorkbufSize {
+ throw("size of Workbuf is suboptimal")
+ }
+ // No sweep on the first cycle.
+ sweep.active.state.Store(sweepDrainedMask)
+
+ // Initialize GC pacer state.
+ // Use the environment variable GOGC for the initial gcPercent value.
+ // Use the environment variable GOMEMLIMIT for the initial memoryLimit value.
+ gcController.init(readGOGC(), readGOMEMLIMIT())
+
+ work.startSema = 1
+ work.markDoneSema = 1
+ lockInit(&work.sweepWaiters.lock, lockRankSweepWaiters)
+ lockInit(&work.assistQueue.lock, lockRankAssistQueue)
+ lockInit(&work.wbufSpans.lock, lockRankWbufSpans)
+}
+
+// gcenable is called after the bulk of the runtime initialization,
+// just before we're about to start letting user code run.
+// It kicks off the background sweeper goroutine, the background
+// scavenger goroutine, and enables GC.
+func gcenable() {
+ // Kick off sweeping and scavenging.
+ c := make(chan int, 2)
+ go bgsweep(c)
+ go bgscavenge(c)
+ <-c
+ <-c
+ memstats.enablegc = true // now that runtime is initialized, GC is okay
+}
+
+// Garbage collector phase.
+// Indicates to write barrier and synchronization task to perform.
+var gcphase uint32
+
+// The compiler knows about this variable.
+// If you change it, you must change builtin/runtime.go, too.
+// If you change the first four bytes, you must also change the write
+// barrier insertion code.
+var writeBarrier struct {
+ enabled bool // compiler emits a check of this before calling write barrier
+ pad [3]byte // compiler uses 32-bit load for "enabled" field
+ needed bool // identical to enabled, for now (TODO: dedup)
+ alignme uint64 // guarantee alignment so that compiler can use a 32 or 64-bit load
+}
+
+// gcBlackenEnabled is 1 if mutator assists and background mark
+// workers are allowed to blacken objects. This must only be set when
+// gcphase == _GCmark.
+var gcBlackenEnabled uint32
+
+const (
+ _GCoff = iota // GC not running; sweeping in background, write barrier disabled
+ _GCmark // GC marking roots and workbufs: allocate black, write barrier ENABLED
+ _GCmarktermination // GC mark termination: allocate black, P's help GC, write barrier ENABLED
+)
+
+//go:nosplit
+func setGCPhase(x uint32) {
+ atomic.Store(&gcphase, x)
+ writeBarrier.needed = gcphase == _GCmark || gcphase == _GCmarktermination
+ writeBarrier.enabled = writeBarrier.needed
+}
+
+// gcMarkWorkerMode represents the mode that a concurrent mark worker
+// should operate in.
+//
+// Concurrent marking happens through four different mechanisms. One
+// is mutator assists, which happen in response to allocations and are
+// not scheduled. The other three are variations in the per-P mark
+// workers and are distinguished by gcMarkWorkerMode.
+type gcMarkWorkerMode int
+
+const (
+ // gcMarkWorkerNotWorker indicates that the next scheduled G is not
+ // starting work and the mode should be ignored.
+ gcMarkWorkerNotWorker gcMarkWorkerMode = iota
+
+ // gcMarkWorkerDedicatedMode indicates that the P of a mark
+ // worker is dedicated to running that mark worker. The mark
+ // worker should run without preemption.
+ gcMarkWorkerDedicatedMode
+
+ // gcMarkWorkerFractionalMode indicates that a P is currently
+ // running the "fractional" mark worker. The fractional worker
+ // is necessary when GOMAXPROCS*gcBackgroundUtilization is not
+ // an integer and using only dedicated workers would result in
+ // utilization too far from the target of gcBackgroundUtilization.
+ // The fractional worker should run until it is preempted and
+ // will be scheduled to pick up the fractional part of
+ // GOMAXPROCS*gcBackgroundUtilization.
+ gcMarkWorkerFractionalMode
+
+ // gcMarkWorkerIdleMode indicates that a P is running the mark
+ // worker because it has nothing else to do. The idle worker
+ // should run until it is preempted and account its time
+ // against gcController.idleMarkTime.
+ gcMarkWorkerIdleMode
+)
+
+// gcMarkWorkerModeStrings are the strings labels of gcMarkWorkerModes
+// to use in execution traces.
+var gcMarkWorkerModeStrings = [...]string{
+ "Not worker",
+ "GC (dedicated)",
+ "GC (fractional)",
+ "GC (idle)",
+}
+
+// pollFractionalWorkerExit reports whether a fractional mark worker
+// should self-preempt. It assumes it is called from the fractional
+// worker.
+func pollFractionalWorkerExit() bool {
+ // This should be kept in sync with the fractional worker
+ // scheduler logic in findRunnableGCWorker.
+ now := nanotime()
+ delta := now - gcController.markStartTime
+ if delta <= 0 {
+ return true
+ }
+ p := getg().m.p.ptr()
+ selfTime := p.gcFractionalMarkTime + (now - p.gcMarkWorkerStartTime)
+ // Add some slack to the utilization goal so that the
+ // fractional worker isn't behind again the instant it exits.
+ return float64(selfTime)/float64(delta) > 1.2*gcController.fractionalUtilizationGoal
+}
+
+var work workType
+
+type workType struct {
+ full lfstack // lock-free list of full blocks workbuf
+ _ cpu.CacheLinePad // prevents false-sharing between full and empty
+ empty lfstack // lock-free list of empty blocks workbuf
+ _ cpu.CacheLinePad // prevents false-sharing between empty and nproc/nwait
+
+ wbufSpans struct {
+ lock mutex
+ // free is a list of spans dedicated to workbufs, but
+ // that don't currently contain any workbufs.
+ free mSpanList
+ // busy is a list of all spans containing workbufs on
+ // one of the workbuf lists.
+ busy mSpanList
+ }
+
+ // Restore 64-bit alignment on 32-bit.
+ _ uint32
+
+ // bytesMarked is the number of bytes marked this cycle. This
+ // includes bytes blackened in scanned objects, noscan objects
+ // that go straight to black, and permagrey objects scanned by
+ // markroot during the concurrent scan phase. This is updated
+ // atomically during the cycle. Updates may be batched
+ // arbitrarily, since the value is only read at the end of the
+ // cycle.
+ //
+ // Because of benign races during marking, this number may not
+ // be the exact number of marked bytes, but it should be very
+ // close.
+ //
+ // Put this field here because it needs 64-bit atomic access
+ // (and thus 8-byte alignment even on 32-bit architectures).
+ bytesMarked uint64
+
+ markrootNext uint32 // next markroot job
+ markrootJobs uint32 // number of markroot jobs
+
+ nproc uint32
+ tstart int64
+ nwait uint32
+
+ // Number of roots of various root types. Set by gcMarkRootPrepare.
+ //
+ // nStackRoots == len(stackRoots), but we have nStackRoots for
+ // consistency.
+ nDataRoots, nBSSRoots, nSpanRoots, nStackRoots int
+
+ // Base indexes of each root type. Set by gcMarkRootPrepare.
+ baseData, baseBSS, baseSpans, baseStacks, baseEnd uint32
+
+ // stackRoots is a snapshot of all of the Gs that existed
+ // before the beginning of concurrent marking. The backing
+ // store of this must not be modified because it might be
+ // shared with allgs.
+ stackRoots []*g
+
+ // Each type of GC state transition is protected by a lock.
+ // Since multiple threads can simultaneously detect the state
+ // transition condition, any thread that detects a transition
+ // condition must acquire the appropriate transition lock,
+ // re-check the transition condition and return if it no
+ // longer holds or perform the transition if it does.
+ // Likewise, any transition must invalidate the transition
+ // condition before releasing the lock. This ensures that each
+ // transition is performed by exactly one thread and threads
+ // that need the transition to happen block until it has
+ // happened.
+ //
+ // startSema protects the transition from "off" to mark or
+ // mark termination.
+ startSema uint32
+ // markDoneSema protects transitions from mark to mark termination.
+ markDoneSema uint32
+
+ bgMarkReady note // signal background mark worker has started
+ bgMarkDone uint32 // cas to 1 when at a background mark completion point
+ // Background mark completion signaling
+
+ // mode is the concurrency mode of the current GC cycle.
+ mode gcMode
+
+ // userForced indicates the current GC cycle was forced by an
+ // explicit user call.
+ userForced bool
+
+ // initialHeapLive is the value of gcController.heapLive at the
+ // beginning of this GC cycle.
+ initialHeapLive uint64
+
+ // assistQueue is a queue of assists that are blocked because
+ // there was neither enough credit to steal or enough work to
+ // do.
+ assistQueue struct {
+ lock mutex
+ q gQueue
+ }
+
+ // sweepWaiters is a list of blocked goroutines to wake when
+ // we transition from mark termination to sweep.
+ sweepWaiters struct {
+ lock mutex
+ list gList
+ }
+
+ // cycles is the number of completed GC cycles, where a GC
+ // cycle is sweep termination, mark, mark termination, and
+ // sweep. This differs from memstats.numgc, which is
+ // incremented at mark termination.
+ cycles atomic.Uint32
+
+ // Timing/utilization stats for this cycle.
+ stwprocs, maxprocs int32
+ tSweepTerm, tMark, tMarkTerm, tEnd int64 // nanotime() of phase start
+
+ pauseNS int64 // total STW time this cycle
+ pauseStart int64 // nanotime() of last STW
+
+ // debug.gctrace heap sizes for this cycle.
+ heap0, heap1, heap2 uint64
+
+ // Cumulative estimated CPU usage.
+ cpuStats
+}
+
+// GC runs a garbage collection and blocks the caller until the
+// garbage collection is complete. It may also block the entire
+// program.
+func GC() {
+ // We consider a cycle to be: sweep termination, mark, mark
+ // termination, and sweep. This function shouldn't return
+ // until a full cycle has been completed, from beginning to
+ // end. Hence, we always want to finish up the current cycle
+ // and start a new one. That means:
+ //
+ // 1. In sweep termination, mark, or mark termination of cycle
+ // N, wait until mark termination N completes and transitions
+ // to sweep N.
+ //
+ // 2. In sweep N, help with sweep N.
+ //
+ // At this point we can begin a full cycle N+1.
+ //
+ // 3. Trigger cycle N+1 by starting sweep termination N+1.
+ //
+ // 4. Wait for mark termination N+1 to complete.
+ //
+ // 5. Help with sweep N+1 until it's done.
+ //
+ // This all has to be written to deal with the fact that the
+ // GC may move ahead on its own. For example, when we block
+ // until mark termination N, we may wake up in cycle N+2.
+
+ // Wait until the current sweep termination, mark, and mark
+ // termination complete.
+ n := work.cycles.Load()
+ gcWaitOnMark(n)
+
+ // We're now in sweep N or later. Trigger GC cycle N+1, which
+ // will first finish sweep N if necessary and then enter sweep
+ // termination N+1.
+ gcStart(gcTrigger{kind: gcTriggerCycle, n: n + 1})
+
+ // Wait for mark termination N+1 to complete.
+ gcWaitOnMark(n + 1)
+
+ // Finish sweep N+1 before returning. We do this both to
+ // complete the cycle and because runtime.GC() is often used
+ // as part of tests and benchmarks to get the system into a
+ // relatively stable and isolated state.
+ for work.cycles.Load() == n+1 && sweepone() != ^uintptr(0) {
+ sweep.nbgsweep++
+ Gosched()
+ }
+
+ // Callers may assume that the heap profile reflects the
+ // just-completed cycle when this returns (historically this
+ // happened because this was a STW GC), but right now the
+ // profile still reflects mark termination N, not N+1.
+ //
+ // As soon as all of the sweep frees from cycle N+1 are done,
+ // we can go ahead and publish the heap profile.
+ //
+ // First, wait for sweeping to finish. (We know there are no
+ // more spans on the sweep queue, but we may be concurrently
+ // sweeping spans, so we have to wait.)
+ for work.cycles.Load() == n+1 && !isSweepDone() {
+ Gosched()
+ }
+
+ // Now we're really done with sweeping, so we can publish the
+ // stable heap profile. Only do this if we haven't already hit
+ // another mark termination.
+ mp := acquirem()
+ cycle := work.cycles.Load()
+ if cycle == n+1 || (gcphase == _GCmark && cycle == n+2) {
+ mProf_PostSweep()
+ }
+ releasem(mp)
+}
+
+// gcWaitOnMark blocks until GC finishes the Nth mark phase. If GC has
+// already completed this mark phase, it returns immediately.
+func gcWaitOnMark(n uint32) {
+ for {
+ // Disable phase transitions.
+ lock(&work.sweepWaiters.lock)
+ nMarks := work.cycles.Load()
+ if gcphase != _GCmark {
+ // We've already completed this cycle's mark.
+ nMarks++
+ }
+ if nMarks > n {
+ // We're done.
+ unlock(&work.sweepWaiters.lock)
+ return
+ }
+
+ // Wait until sweep termination, mark, and mark
+ // termination of cycle N complete.
+ work.sweepWaiters.list.push(getg())
+ goparkunlock(&work.sweepWaiters.lock, waitReasonWaitForGCCycle, traceBlockUntilGCEnds, 1)
+ }
+}
+
+// gcMode indicates how concurrent a GC cycle should be.
+type gcMode int
+
+const (
+ gcBackgroundMode gcMode = iota // concurrent GC and sweep
+ gcForceMode // stop-the-world GC now, concurrent sweep
+ gcForceBlockMode // stop-the-world GC now and STW sweep (forced by user)
+)
+
+// A gcTrigger is a predicate for starting a GC cycle. Specifically,
+// it is an exit condition for the _GCoff phase.
+type gcTrigger struct {
+ kind gcTriggerKind
+ now int64 // gcTriggerTime: current time
+ n uint32 // gcTriggerCycle: cycle number to start
+}
+
+type gcTriggerKind int
+
+const (
+ // gcTriggerHeap indicates that a cycle should be started when
+ // the heap size reaches the trigger heap size computed by the
+ // controller.
+ gcTriggerHeap gcTriggerKind = iota
+
+ // gcTriggerTime indicates that a cycle should be started when
+ // it's been more than forcegcperiod nanoseconds since the
+ // previous GC cycle.
+ gcTriggerTime
+
+ // gcTriggerCycle indicates that a cycle should be started if
+ // we have not yet started cycle number gcTrigger.n (relative
+ // to work.cycles).
+ gcTriggerCycle
+)
+
+// test reports whether the trigger condition is satisfied, meaning
+// that the exit condition for the _GCoff phase has been met. The exit
+// condition should be tested when allocating.
+func (t gcTrigger) test() bool {
+ if !memstats.enablegc || panicking.Load() != 0 || gcphase != _GCoff {
+ return false
+ }
+ switch t.kind {
+ case gcTriggerHeap:
+ // Non-atomic access to gcController.heapLive for performance. If
+ // we are going to trigger on this, this thread just
+ // atomically wrote gcController.heapLive anyway and we'll see our
+ // own write.
+ trigger, _ := gcController.trigger()
+ return gcController.heapLive.Load() >= trigger
+ case gcTriggerTime:
+ if gcController.gcPercent.Load() < 0 {
+ return false
+ }
+ lastgc := int64(atomic.Load64(&memstats.last_gc_nanotime))
+ return lastgc != 0 && t.now-lastgc > forcegcperiod
+ case gcTriggerCycle:
+ // t.n > work.cycles, but accounting for wraparound.
+ return int32(t.n-work.cycles.Load()) > 0
+ }
+ return true
+}
+
+// gcStart starts the GC. It transitions from _GCoff to _GCmark (if
+// debug.gcstoptheworld == 0) or performs all of GC (if
+// debug.gcstoptheworld != 0).
+//
+// This may return without performing this transition in some cases,
+// such as when called on a system stack or with locks held.
+func gcStart(trigger gcTrigger) {
+ // Since this is called from malloc and malloc is called in
+ // the guts of a number of libraries that might be holding
+ // locks, don't attempt to start GC in non-preemptible or
+ // potentially unstable situations.
+ mp := acquirem()
+ if gp := getg(); gp == mp.g0 || mp.locks > 1 || mp.preemptoff != "" {
+ releasem(mp)
+ return
+ }
+ releasem(mp)
+ mp = nil
+
+ // Pick up the remaining unswept/not being swept spans concurrently
+ //
+ // This shouldn't happen if we're being invoked in background
+ // mode since proportional sweep should have just finished
+ // sweeping everything, but rounding errors, etc, may leave a
+ // few spans unswept. In forced mode, this is necessary since
+ // GC can be forced at any point in the sweeping cycle.
+ //
+ // We check the transition condition continuously here in case
+ // this G gets delayed in to the next GC cycle.
+ for trigger.test() && sweepone() != ^uintptr(0) {
+ sweep.nbgsweep++
+ }
+
+ // Perform GC initialization and the sweep termination
+ // transition.
+ semacquire(&work.startSema)
+ // Re-check transition condition under transition lock.
+ if !trigger.test() {
+ semrelease(&work.startSema)
+ return
+ }
+
+ // In gcstoptheworld debug mode, upgrade the mode accordingly.
+ // We do this after re-checking the transition condition so
+ // that multiple goroutines that detect the heap trigger don't
+ // start multiple STW GCs.
+ mode := gcBackgroundMode
+ if debug.gcstoptheworld == 1 {
+ mode = gcForceMode
+ } else if debug.gcstoptheworld == 2 {
+ mode = gcForceBlockMode
+ }
+
+ // Ok, we're doing it! Stop everybody else
+ semacquire(&gcsema)
+ semacquire(&worldsema)
+
+ // For stats, check if this GC was forced by the user.
+ // Update it under gcsema to avoid gctrace getting wrong values.
+ work.userForced = trigger.kind == gcTriggerCycle
+
+ if traceEnabled() {
+ traceGCStart()
+ }
+
+ // Check that all Ps have finished deferred mcache flushes.
+ for _, p := range allp {
+ if fg := p.mcache.flushGen.Load(); fg != mheap_.sweepgen {
+ println("runtime: p", p.id, "flushGen", fg, "!= sweepgen", mheap_.sweepgen)
+ throw("p mcache not flushed")
+ }
+ }
+
+ gcBgMarkStartWorkers()
+
+ systemstack(gcResetMarkState)
+
+ work.stwprocs, work.maxprocs = gomaxprocs, gomaxprocs
+ if work.stwprocs > ncpu {
+ // This is used to compute CPU time of the STW phases,
+ // so it can't be more than ncpu, even if GOMAXPROCS is.
+ work.stwprocs = ncpu
+ }
+ work.heap0 = gcController.heapLive.Load()
+ work.pauseNS = 0
+ work.mode = mode
+
+ now := nanotime()
+ work.tSweepTerm = now
+ work.pauseStart = now
+ systemstack(func() { stopTheWorldWithSema(stwGCSweepTerm) })
+ // Finish sweep before we start concurrent scan.
+ systemstack(func() {
+ finishsweep_m()
+ })
+
+ // clearpools before we start the GC. If we wait they memory will not be
+ // reclaimed until the next GC cycle.
+ clearpools()
+
+ work.cycles.Add(1)
+
+ // Assists and workers can start the moment we start
+ // the world.
+ gcController.startCycle(now, int(gomaxprocs), trigger)
+
+ // Notify the CPU limiter that assists may begin.
+ gcCPULimiter.startGCTransition(true, now)
+
+ // In STW mode, disable scheduling of user Gs. This may also
+ // disable scheduling of this goroutine, so it may block as
+ // soon as we start the world again.
+ if mode != gcBackgroundMode {
+ schedEnableUser(false)
+ }
+
+ // Enter concurrent mark phase and enable
+ // write barriers.
+ //
+ // Because the world is stopped, all Ps will
+ // observe that write barriers are enabled by
+ // the time we start the world and begin
+ // scanning.
+ //
+ // Write barriers must be enabled before assists are
+ // enabled because they must be enabled before
+ // any non-leaf heap objects are marked. Since
+ // allocations are blocked until assists can
+ // happen, we want enable assists as early as
+ // possible.
+ setGCPhase(_GCmark)
+
+ gcBgMarkPrepare() // Must happen before assist enable.
+ gcMarkRootPrepare()
+
+ // Mark all active tinyalloc blocks. Since we're
+ // allocating from these, they need to be black like
+ // other allocations. The alternative is to blacken
+ // the tiny block on every allocation from it, which
+ // would slow down the tiny allocator.
+ gcMarkTinyAllocs()
+
+ // At this point all Ps have enabled the write
+ // barrier, thus maintaining the no white to
+ // black invariant. Enable mutator assists to
+ // put back-pressure on fast allocating
+ // mutators.
+ atomic.Store(&gcBlackenEnabled, 1)
+
+ // In STW mode, we could block the instant systemstack
+ // returns, so make sure we're not preemptible.
+ mp = acquirem()
+
+ // Concurrent mark.
+ systemstack(func() {
+ now = startTheWorldWithSema()
+ work.pauseNS += now - work.pauseStart
+ work.tMark = now
+ memstats.gcPauseDist.record(now - work.pauseStart)
+
+ sweepTermCpu := int64(work.stwprocs) * (work.tMark - work.tSweepTerm)
+ work.cpuStats.gcPauseTime += sweepTermCpu
+ work.cpuStats.gcTotalTime += sweepTermCpu
+
+ // Release the CPU limiter.
+ gcCPULimiter.finishGCTransition(now)
+ })
+
+ // Release the world sema before Gosched() in STW mode
+ // because we will need to reacquire it later but before
+ // this goroutine becomes runnable again, and we could
+ // self-deadlock otherwise.
+ semrelease(&worldsema)
+ releasem(mp)
+
+ // Make sure we block instead of returning to user code
+ // in STW mode.
+ if mode != gcBackgroundMode {
+ Gosched()
+ }
+
+ semrelease(&work.startSema)
+}
+
+// gcMarkDoneFlushed counts the number of P's with flushed work.
+//
+// Ideally this would be a captured local in gcMarkDone, but forEachP
+// escapes its callback closure, so it can't capture anything.
+//
+// This is protected by markDoneSema.
+var gcMarkDoneFlushed uint32
+
+// gcMarkDone transitions the GC from mark to mark termination if all
+// reachable objects have been marked (that is, there are no grey
+// objects and can be no more in the future). Otherwise, it flushes
+// all local work to the global queues where it can be discovered by
+// other workers.
+//
+// This should be called when all local mark work has been drained and
+// there are no remaining workers. Specifically, when
+//
+// work.nwait == work.nproc && !gcMarkWorkAvailable(p)
+//
+// The calling context must be preemptible.
+//
+// Flushing local work is important because idle Ps may have local
+// work queued. This is the only way to make that work visible and
+// drive GC to completion.
+//
+// It is explicitly okay to have write barriers in this function. If
+// it does transition to mark termination, then all reachable objects
+// have been marked, so the write barrier cannot shade any more
+// objects.
+func gcMarkDone() {
+ // Ensure only one thread is running the ragged barrier at a
+ // time.
+ semacquire(&work.markDoneSema)
+
+top:
+ // Re-check transition condition under transition lock.
+ //
+ // It's critical that this checks the global work queues are
+ // empty before performing the ragged barrier. Otherwise,
+ // there could be global work that a P could take after the P
+ // has passed the ragged barrier.
+ if !(gcphase == _GCmark && work.nwait == work.nproc && !gcMarkWorkAvailable(nil)) {
+ semrelease(&work.markDoneSema)
+ return
+ }
+
+ // forEachP needs worldsema to execute, and we'll need it to
+ // stop the world later, so acquire worldsema now.
+ semacquire(&worldsema)
+
+ // Flush all local buffers and collect flushedWork flags.
+ gcMarkDoneFlushed = 0
+ systemstack(func() {
+ gp := getg().m.curg
+ // Mark the user stack as preemptible so that it may be scanned.
+ // Otherwise, our attempt to force all P's to a safepoint could
+ // result in a deadlock as we attempt to preempt a worker that's
+ // trying to preempt us (e.g. for a stack scan).
+ casGToWaiting(gp, _Grunning, waitReasonGCMarkTermination)
+ forEachP(func(pp *p) {
+ // Flush the write barrier buffer, since this may add
+ // work to the gcWork.
+ wbBufFlush1(pp)
+
+ // Flush the gcWork, since this may create global work
+ // and set the flushedWork flag.
+ //
+ // TODO(austin): Break up these workbufs to
+ // better distribute work.
+ pp.gcw.dispose()
+ // Collect the flushedWork flag.
+ if pp.gcw.flushedWork {
+ atomic.Xadd(&gcMarkDoneFlushed, 1)
+ pp.gcw.flushedWork = false
+ }
+ })
+ casgstatus(gp, _Gwaiting, _Grunning)
+ })
+
+ if gcMarkDoneFlushed != 0 {
+ // More grey objects were discovered since the
+ // previous termination check, so there may be more
+ // work to do. Keep going. It's possible the
+ // transition condition became true again during the
+ // ragged barrier, so re-check it.
+ semrelease(&worldsema)
+ goto top
+ }
+
+ // There was no global work, no local work, and no Ps
+ // communicated work since we took markDoneSema. Therefore
+ // there are no grey objects and no more objects can be
+ // shaded. Transition to mark termination.
+ now := nanotime()
+ work.tMarkTerm = now
+ work.pauseStart = now
+ getg().m.preemptoff = "gcing"
+ systemstack(func() { stopTheWorldWithSema(stwGCMarkTerm) })
+ // The gcphase is _GCmark, it will transition to _GCmarktermination
+ // below. The important thing is that the wb remains active until
+ // all marking is complete. This includes writes made by the GC.
+
+ // There is sometimes work left over when we enter mark termination due
+ // to write barriers performed after the completion barrier above.
+ // Detect this and resume concurrent mark. This is obviously
+ // unfortunate.
+ //
+ // See issue #27993 for details.
+ //
+ // Switch to the system stack to call wbBufFlush1, though in this case
+ // it doesn't matter because we're non-preemptible anyway.
+ restart := false
+ systemstack(func() {
+ for _, p := range allp {
+ wbBufFlush1(p)
+ if !p.gcw.empty() {
+ restart = true
+ break
+ }
+ }
+ })
+ if restart {
+ getg().m.preemptoff = ""
+ systemstack(func() {
+ now := startTheWorldWithSema()
+ work.pauseNS += now - work.pauseStart
+ memstats.gcPauseDist.record(now - work.pauseStart)
+ })
+ semrelease(&worldsema)
+ goto top
+ }
+
+ gcComputeStartingStackSize()
+
+ // Disable assists and background workers. We must do
+ // this before waking blocked assists.
+ atomic.Store(&gcBlackenEnabled, 0)
+
+ // Notify the CPU limiter that GC assists will now cease.
+ gcCPULimiter.startGCTransition(false, now)
+
+ // Wake all blocked assists. These will run when we
+ // start the world again.
+ gcWakeAllAssists()
+
+ // Likewise, release the transition lock. Blocked
+ // workers and assists will run when we start the
+ // world again.
+ semrelease(&work.markDoneSema)
+
+ // In STW mode, re-enable user goroutines. These will be
+ // queued to run after we start the world.
+ schedEnableUser(true)
+
+ // endCycle depends on all gcWork cache stats being flushed.
+ // The termination algorithm above ensured that up to
+ // allocations since the ragged barrier.
+ gcController.endCycle(now, int(gomaxprocs), work.userForced)
+
+ // Perform mark termination. This will restart the world.
+ gcMarkTermination()
+}
+
+// World must be stopped and mark assists and background workers must be
+// disabled.
+func gcMarkTermination() {
+ // Start marktermination (write barrier remains enabled for now).
+ setGCPhase(_GCmarktermination)
+
+ work.heap1 = gcController.heapLive.Load()
+ startTime := nanotime()
+
+ mp := acquirem()
+ mp.preemptoff = "gcing"
+ mp.traceback = 2
+ curgp := mp.curg
+ casGToWaiting(curgp, _Grunning, waitReasonGarbageCollection)
+
+ // Run gc on the g0 stack. We do this so that the g stack
+ // we're currently running on will no longer change. Cuts
+ // the root set down a bit (g0 stacks are not scanned, and
+ // we don't need to scan gc's internal state). We also
+ // need to switch to g0 so we can shrink the stack.
+ systemstack(func() {
+ gcMark(startTime)
+ // Must return immediately.
+ // The outer function's stack may have moved
+ // during gcMark (it shrinks stacks, including the
+ // outer function's stack), so we must not refer
+ // to any of its variables. Return back to the
+ // non-system stack to pick up the new addresses
+ // before continuing.
+ })
+
+ systemstack(func() {
+ work.heap2 = work.bytesMarked
+ if debug.gccheckmark > 0 {
+ // Run a full non-parallel, stop-the-world
+ // mark using checkmark bits, to check that we
+ // didn't forget to mark anything during the
+ // concurrent mark process.
+ startCheckmarks()
+ gcResetMarkState()
+ gcw := &getg().m.p.ptr().gcw
+ gcDrain(gcw, 0)
+ wbBufFlush1(getg().m.p.ptr())
+ gcw.dispose()
+ endCheckmarks()
+ }
+
+ // marking is complete so we can turn the write barrier off
+ setGCPhase(_GCoff)
+ gcSweep(work.mode)
+ })
+
+ mp.traceback = 0
+ casgstatus(curgp, _Gwaiting, _Grunning)
+
+ if traceEnabled() {
+ traceGCDone()
+ }
+
+ // all done
+ mp.preemptoff = ""
+
+ if gcphase != _GCoff {
+ throw("gc done but gcphase != _GCoff")
+ }
+
+ // Record heapInUse for scavenger.
+ memstats.lastHeapInUse = gcController.heapInUse.load()
+
+ // Update GC trigger and pacing, as well as downstream consumers
+ // of this pacing information, for the next cycle.
+ systemstack(gcControllerCommit)
+
+ // Update timing memstats
+ now := nanotime()
+ sec, nsec, _ := time_now()
+ unixNow := sec*1e9 + int64(nsec)
+ work.pauseNS += now - work.pauseStart
+ work.tEnd = now
+ memstats.gcPauseDist.record(now - work.pauseStart)
+ atomic.Store64(&memstats.last_gc_unix, uint64(unixNow)) // must be Unix time to make sense to user
+ atomic.Store64(&memstats.last_gc_nanotime, uint64(now)) // monotonic time for us
+ memstats.pause_ns[memstats.numgc%uint32(len(memstats.pause_ns))] = uint64(work.pauseNS)
+ memstats.pause_end[memstats.numgc%uint32(len(memstats.pause_end))] = uint64(unixNow)
+ memstats.pause_total_ns += uint64(work.pauseNS)
+
+ markTermCpu := int64(work.stwprocs) * (work.tEnd - work.tMarkTerm)
+ work.cpuStats.gcPauseTime += markTermCpu
+ work.cpuStats.gcTotalTime += markTermCpu
+
+ // Accumulate CPU stats.
+ //
+ // Pass gcMarkPhase=true so we can get all the latest GC CPU stats in there too.
+ work.cpuStats.accumulate(now, true)
+
+ // Compute overall GC CPU utilization.
+ // Omit idle marking time from the overall utilization here since it's "free".
+ memstats.gc_cpu_fraction = float64(work.cpuStats.gcTotalTime-work.cpuStats.gcIdleTime) / float64(work.cpuStats.totalTime)
+
+ // Reset assist time and background time stats.
+ //
+ // Do this now, instead of at the start of the next GC cycle, because
+ // these two may keep accumulating even if the GC is not active.
+ scavenge.assistTime.Store(0)
+ scavenge.backgroundTime.Store(0)
+
+ // Reset idle time stat.
+ sched.idleTime.Store(0)
+
+ // Reset sweep state.
+ sweep.nbgsweep = 0
+ sweep.npausesweep = 0
+
+ if work.userForced {
+ memstats.numforcedgc++
+ }
+
+ // Bump GC cycle count and wake goroutines waiting on sweep.
+ lock(&work.sweepWaiters.lock)
+ memstats.numgc++
+ injectglist(&work.sweepWaiters.list)
+ unlock(&work.sweepWaiters.lock)
+
+ // Increment the scavenge generation now.
+ //
+ // This moment represents peak heap in use because we're
+ // about to start sweeping.
+ mheap_.pages.scav.index.nextGen()
+
+ // Release the CPU limiter.
+ gcCPULimiter.finishGCTransition(now)
+
+ // Finish the current heap profiling cycle and start a new
+ // heap profiling cycle. We do this before starting the world
+ // so events don't leak into the wrong cycle.
+ mProf_NextCycle()
+
+ // There may be stale spans in mcaches that need to be swept.
+ // Those aren't tracked in any sweep lists, so we need to
+ // count them against sweep completion until we ensure all
+ // those spans have been forced out.
+ sl := sweep.active.begin()
+ if !sl.valid {
+ throw("failed to set sweep barrier")
+ }
+
+ systemstack(func() { startTheWorldWithSema() })
+
+ // Flush the heap profile so we can start a new cycle next GC.
+ // This is relatively expensive, so we don't do it with the
+ // world stopped.
+ mProf_Flush()
+
+ // Prepare workbufs for freeing by the sweeper. We do this
+ // asynchronously because it can take non-trivial time.
+ prepareFreeWorkbufs()
+
+ // Free stack spans. This must be done between GC cycles.
+ systemstack(freeStackSpans)
+
+ // Ensure all mcaches are flushed. Each P will flush its own
+ // mcache before allocating, but idle Ps may not. Since this
+ // is necessary to sweep all spans, we need to ensure all
+ // mcaches are flushed before we start the next GC cycle.
+ //
+ // While we're here, flush the page cache for idle Ps to avoid
+ // having pages get stuck on them. These pages are hidden from
+ // the scavenger, so in small idle heaps a significant amount
+ // of additional memory might be held onto.
+ //
+ // Also, flush the pinner cache, to avoid leaking that memory
+ // indefinitely.
+ systemstack(func() {
+ forEachP(func(pp *p) {
+ pp.mcache.prepareForSweep()
+ if pp.status == _Pidle {
+ systemstack(func() {
+ lock(&mheap_.lock)
+ pp.pcache.flush(&mheap_.pages)
+ unlock(&mheap_.lock)
+ })
+ }
+ pp.pinnerCache = nil
+ })
+ })
+ // Now that we've swept stale spans in mcaches, they don't
+ // count against unswept spans.
+ sweep.active.end(sl)
+
+ // Print gctrace before dropping worldsema. As soon as we drop
+ // worldsema another cycle could start and smash the stats
+ // we're trying to print.
+ if debug.gctrace > 0 {
+ util := int(memstats.gc_cpu_fraction * 100)
+
+ var sbuf [24]byte
+ printlock()
+ print("gc ", memstats.numgc,
+ " @", string(itoaDiv(sbuf[:], uint64(work.tSweepTerm-runtimeInitTime)/1e6, 3)), "s ",
+ util, "%: ")
+ prev := work.tSweepTerm
+ for i, ns := range []int64{work.tMark, work.tMarkTerm, work.tEnd} {
+ if i != 0 {
+ print("+")
+ }
+ print(string(fmtNSAsMS(sbuf[:], uint64(ns-prev))))
+ prev = ns
+ }
+ print(" ms clock, ")
+ for i, ns := range []int64{
+ int64(work.stwprocs) * (work.tMark - work.tSweepTerm),
+ gcController.assistTime.Load(),
+ gcController.dedicatedMarkTime.Load() + gcController.fractionalMarkTime.Load(),
+ gcController.idleMarkTime.Load(),
+ markTermCpu,
+ } {
+ if i == 2 || i == 3 {
+ // Separate mark time components with /.
+ print("/")
+ } else if i != 0 {
+ print("+")
+ }
+ print(string(fmtNSAsMS(sbuf[:], uint64(ns))))
+ }
+ print(" ms cpu, ",
+ work.heap0>>20, "->", work.heap1>>20, "->", work.heap2>>20, " MB, ",
+ gcController.lastHeapGoal>>20, " MB goal, ",
+ gcController.lastStackScan.Load()>>20, " MB stacks, ",
+ gcController.globalsScan.Load()>>20, " MB globals, ",
+ work.maxprocs, " P")
+ if work.userForced {
+ print(" (forced)")
+ }
+ print("\n")
+ printunlock()
+ }
+
+ // Set any arena chunks that were deferred to fault.
+ lock(&userArenaState.lock)
+ faultList := userArenaState.fault
+ userArenaState.fault = nil
+ unlock(&userArenaState.lock)
+ for _, lc := range faultList {
+ lc.mspan.setUserArenaChunkToFault()
+ }
+
+ // Enable huge pages on some metadata if we cross a heap threshold.
+ if gcController.heapGoal() > minHeapForMetadataHugePages {
+ mheap_.enableMetadataHugePages()
+ }
+
+ semrelease(&worldsema)
+ semrelease(&gcsema)
+ // Careful: another GC cycle may start now.
+
+ releasem(mp)
+ mp = nil
+
+ // now that gc is done, kick off finalizer thread if needed
+ if !concurrentSweep {
+ // give the queued finalizers, if any, a chance to run
+ Gosched()
+ }
+}
+
+// gcBgMarkStartWorkers prepares background mark worker goroutines. These
+// goroutines will not run until the mark phase, but they must be started while
+// the work is not stopped and from a regular G stack. The caller must hold
+// worldsema.
+func gcBgMarkStartWorkers() {
+ // Background marking is performed by per-P G's. Ensure that each P has
+ // a background GC G.
+ //
+ // Worker Gs don't exit if gomaxprocs is reduced. If it is raised
+ // again, we can reuse the old workers; no need to create new workers.
+ for gcBgMarkWorkerCount < gomaxprocs {
+ go gcBgMarkWorker()
+
+ notetsleepg(&work.bgMarkReady, -1)
+ noteclear(&work.bgMarkReady)
+ // The worker is now guaranteed to be added to the pool before
+ // its P's next findRunnableGCWorker.
+
+ gcBgMarkWorkerCount++
+ }
+}
+
+// gcBgMarkPrepare sets up state for background marking.
+// Mutator assists must not yet be enabled.
+func gcBgMarkPrepare() {
+ // Background marking will stop when the work queues are empty
+ // and there are no more workers (note that, since this is
+ // concurrent, this may be a transient state, but mark
+ // termination will clean it up). Between background workers
+ // and assists, we don't really know how many workers there
+ // will be, so we pretend to have an arbitrarily large number
+ // of workers, almost all of which are "waiting". While a
+ // worker is working it decrements nwait. If nproc == nwait,
+ // there are no workers.
+ work.nproc = ^uint32(0)
+ work.nwait = ^uint32(0)
+}
+
+// gcBgMarkWorkerNode is an entry in the gcBgMarkWorkerPool. It points to a single
+// gcBgMarkWorker goroutine.
+type gcBgMarkWorkerNode struct {
+ // Unused workers are managed in a lock-free stack. This field must be first.
+ node lfnode
+
+ // The g of this worker.
+ gp guintptr
+
+ // Release this m on park. This is used to communicate with the unlock
+ // function, which cannot access the G's stack. It is unused outside of
+ // gcBgMarkWorker().
+ m muintptr
+}
+
+func gcBgMarkWorker() {
+ gp := getg()
+
+ // We pass node to a gopark unlock function, so it can't be on
+ // the stack (see gopark). Prevent deadlock from recursively
+ // starting GC by disabling preemption.
+ gp.m.preemptoff = "GC worker init"
+ node := new(gcBgMarkWorkerNode)
+ gp.m.preemptoff = ""
+
+ node.gp.set(gp)
+
+ node.m.set(acquirem())
+ notewakeup(&work.bgMarkReady)
+ // After this point, the background mark worker is generally scheduled
+ // cooperatively by gcController.findRunnableGCWorker. While performing
+ // work on the P, preemption is disabled because we are working on
+ // P-local work buffers. When the preempt flag is set, this puts itself
+ // into _Gwaiting to be woken up by gcController.findRunnableGCWorker
+ // at the appropriate time.
+ //
+ // When preemption is enabled (e.g., while in gcMarkDone), this worker
+ // may be preempted and schedule as a _Grunnable G from a runq. That is
+ // fine; it will eventually gopark again for further scheduling via
+ // findRunnableGCWorker.
+ //
+ // Since we disable preemption before notifying bgMarkReady, we
+ // guarantee that this G will be in the worker pool for the next
+ // findRunnableGCWorker. This isn't strictly necessary, but it reduces
+ // latency between _GCmark starting and the workers starting.
+
+ for {
+ // Go to sleep until woken by
+ // gcController.findRunnableGCWorker.
+ gopark(func(g *g, nodep unsafe.Pointer) bool {
+ node := (*gcBgMarkWorkerNode)(nodep)
+
+ if mp := node.m.ptr(); mp != nil {
+ // The worker G is no longer running; release
+ // the M.
+ //
+ // N.B. it is _safe_ to release the M as soon
+ // as we are no longer performing P-local mark
+ // work.
+ //
+ // However, since we cooperatively stop work
+ // when gp.preempt is set, if we releasem in
+ // the loop then the following call to gopark
+ // would immediately preempt the G. This is
+ // also safe, but inefficient: the G must
+ // schedule again only to enter gopark and park
+ // again. Thus, we defer the release until
+ // after parking the G.
+ releasem(mp)
+ }
+
+ // Release this G to the pool.
+ gcBgMarkWorkerPool.push(&node.node)
+ // Note that at this point, the G may immediately be
+ // rescheduled and may be running.
+ return true
+ }, unsafe.Pointer(node), waitReasonGCWorkerIdle, traceBlockSystemGoroutine, 0)
+
+ // Preemption must not occur here, or another G might see
+ // p.gcMarkWorkerMode.
+
+ // Disable preemption so we can use the gcw. If the
+ // scheduler wants to preempt us, we'll stop draining,
+ // dispose the gcw, and then preempt.
+ node.m.set(acquirem())
+ pp := gp.m.p.ptr() // P can't change with preemption disabled.
+
+ if gcBlackenEnabled == 0 {
+ println("worker mode", pp.gcMarkWorkerMode)
+ throw("gcBgMarkWorker: blackening not enabled")
+ }
+
+ if pp.gcMarkWorkerMode == gcMarkWorkerNotWorker {
+ throw("gcBgMarkWorker: mode not set")
+ }
+
+ startTime := nanotime()
+ pp.gcMarkWorkerStartTime = startTime
+ var trackLimiterEvent bool
+ if pp.gcMarkWorkerMode == gcMarkWorkerIdleMode {
+ trackLimiterEvent = pp.limiterEvent.start(limiterEventIdleMarkWork, startTime)
+ }
+
+ decnwait := atomic.Xadd(&work.nwait, -1)
+ if decnwait == work.nproc {
+ println("runtime: work.nwait=", decnwait, "work.nproc=", work.nproc)
+ throw("work.nwait was > work.nproc")
+ }
+
+ systemstack(func() {
+ // Mark our goroutine preemptible so its stack
+ // can be scanned. This lets two mark workers
+ // scan each other (otherwise, they would
+ // deadlock). We must not modify anything on
+ // the G stack. However, stack shrinking is
+ // disabled for mark workers, so it is safe to
+ // read from the G stack.
+ casGToWaiting(gp, _Grunning, waitReasonGCWorkerActive)
+ switch pp.gcMarkWorkerMode {
+ default:
+ throw("gcBgMarkWorker: unexpected gcMarkWorkerMode")
+ case gcMarkWorkerDedicatedMode:
+ gcDrain(&pp.gcw, gcDrainUntilPreempt|gcDrainFlushBgCredit)
+ if gp.preempt {
+ // We were preempted. This is
+ // a useful signal to kick
+ // everything out of the run
+ // queue so it can run
+ // somewhere else.
+ if drainQ, n := runqdrain(pp); n > 0 {
+ lock(&sched.lock)
+ globrunqputbatch(&drainQ, int32(n))
+ unlock(&sched.lock)
+ }
+ }
+ // Go back to draining, this time
+ // without preemption.
+ gcDrain(&pp.gcw, gcDrainFlushBgCredit)
+ case gcMarkWorkerFractionalMode:
+ gcDrain(&pp.gcw, gcDrainFractional|gcDrainUntilPreempt|gcDrainFlushBgCredit)
+ case gcMarkWorkerIdleMode:
+ gcDrain(&pp.gcw, gcDrainIdle|gcDrainUntilPreempt|gcDrainFlushBgCredit)
+ }
+ casgstatus(gp, _Gwaiting, _Grunning)
+ })
+
+ // Account for time and mark us as stopped.
+ now := nanotime()
+ duration := now - startTime
+ gcController.markWorkerStop(pp.gcMarkWorkerMode, duration)
+ if trackLimiterEvent {
+ pp.limiterEvent.stop(limiterEventIdleMarkWork, now)
+ }
+ if pp.gcMarkWorkerMode == gcMarkWorkerFractionalMode {
+ atomic.Xaddint64(&pp.gcFractionalMarkTime, duration)
+ }
+
+ // Was this the last worker and did we run out
+ // of work?
+ incnwait := atomic.Xadd(&work.nwait, +1)
+ if incnwait > work.nproc {
+ println("runtime: p.gcMarkWorkerMode=", pp.gcMarkWorkerMode,
+ "work.nwait=", incnwait, "work.nproc=", work.nproc)
+ throw("work.nwait > work.nproc")
+ }
+
+ // We'll releasem after this point and thus this P may run
+ // something else. We must clear the worker mode to avoid
+ // attributing the mode to a different (non-worker) G in
+ // traceGoStart.
+ pp.gcMarkWorkerMode = gcMarkWorkerNotWorker
+
+ // If this worker reached a background mark completion
+ // point, signal the main GC goroutine.
+ if incnwait == work.nproc && !gcMarkWorkAvailable(nil) {
+ // We don't need the P-local buffers here, allow
+ // preemption because we may schedule like a regular
+ // goroutine in gcMarkDone (block on locks, etc).
+ releasem(node.m.ptr())
+ node.m.set(nil)
+
+ gcMarkDone()
+ }
+ }
+}
+
+// gcMarkWorkAvailable reports whether executing a mark worker
+// on p is potentially useful. p may be nil, in which case it only
+// checks the global sources of work.
+func gcMarkWorkAvailable(p *p) bool {
+ if p != nil && !p.gcw.empty() {
+ return true
+ }
+ if !work.full.empty() {
+ return true // global work available
+ }
+ if work.markrootNext < work.markrootJobs {
+ return true // root scan work available
+ }
+ return false
+}
+
+// gcMark runs the mark (or, for concurrent GC, mark termination)
+// All gcWork caches must be empty.
+// STW is in effect at this point.
+func gcMark(startTime int64) {
+ if debug.allocfreetrace > 0 {
+ tracegc()
+ }
+
+ if gcphase != _GCmarktermination {
+ throw("in gcMark expecting to see gcphase as _GCmarktermination")
+ }
+ work.tstart = startTime
+
+ // Check that there's no marking work remaining.
+ if work.full != 0 || work.markrootNext < work.markrootJobs {
+ print("runtime: full=", hex(work.full), " next=", work.markrootNext, " jobs=", work.markrootJobs, " nDataRoots=", work.nDataRoots, " nBSSRoots=", work.nBSSRoots, " nSpanRoots=", work.nSpanRoots, " nStackRoots=", work.nStackRoots, "\n")
+ panic("non-empty mark queue after concurrent mark")
+ }
+
+ if debug.gccheckmark > 0 {
+ // This is expensive when there's a large number of
+ // Gs, so only do it if checkmark is also enabled.
+ gcMarkRootCheck()
+ }
+
+ // Drop allg snapshot. allgs may have grown, in which case
+ // this is the only reference to the old backing store and
+ // there's no need to keep it around.
+ work.stackRoots = nil
+
+ // Clear out buffers and double-check that all gcWork caches
+ // are empty. This should be ensured by gcMarkDone before we
+ // enter mark termination.
+ //
+ // TODO: We could clear out buffers just before mark if this
+ // has a non-negligible impact on STW time.
+ for _, p := range allp {
+ // The write barrier may have buffered pointers since
+ // the gcMarkDone barrier. However, since the barrier
+ // ensured all reachable objects were marked, all of
+ // these must be pointers to black objects. Hence we
+ // can just discard the write barrier buffer.
+ if debug.gccheckmark > 0 {
+ // For debugging, flush the buffer and make
+ // sure it really was all marked.
+ wbBufFlush1(p)
+ } else {
+ p.wbBuf.reset()
+ }
+
+ gcw := &p.gcw
+ if !gcw.empty() {
+ printlock()
+ print("runtime: P ", p.id, " flushedWork ", gcw.flushedWork)
+ if gcw.wbuf1 == nil {
+ print(" wbuf1=<nil>")
+ } else {
+ print(" wbuf1.n=", gcw.wbuf1.nobj)
+ }
+ if gcw.wbuf2 == nil {
+ print(" wbuf2=<nil>")
+ } else {
+ print(" wbuf2.n=", gcw.wbuf2.nobj)
+ }
+ print("\n")
+ throw("P has cached GC work at end of mark termination")
+ }
+ // There may still be cached empty buffers, which we
+ // need to flush since we're going to free them. Also,
+ // there may be non-zero stats because we allocated
+ // black after the gcMarkDone barrier.
+ gcw.dispose()
+ }
+
+ // Flush scanAlloc from each mcache since we're about to modify
+ // heapScan directly. If we were to flush this later, then scanAlloc
+ // might have incorrect information.
+ //
+ // Note that it's not important to retain this information; we know
+ // exactly what heapScan is at this point via scanWork.
+ for _, p := range allp {
+ c := p.mcache
+ if c == nil {
+ continue
+ }
+ c.scanAlloc = 0
+ }
+
+ // Reset controller state.
+ gcController.resetLive(work.bytesMarked)
+}
+
+// gcSweep must be called on the system stack because it acquires the heap
+// lock. See mheap for details.
+//
+// The world must be stopped.
+//
+//go:systemstack
+func gcSweep(mode gcMode) {
+ assertWorldStopped()
+
+ if gcphase != _GCoff {
+ throw("gcSweep being done but phase is not GCoff")
+ }
+
+ lock(&mheap_.lock)
+ mheap_.sweepgen += 2
+ sweep.active.reset()
+ mheap_.pagesSwept.Store(0)
+ mheap_.sweepArenas = mheap_.allArenas
+ mheap_.reclaimIndex.Store(0)
+ mheap_.reclaimCredit.Store(0)
+ unlock(&mheap_.lock)
+
+ sweep.centralIndex.clear()
+
+ if !_ConcurrentSweep || mode == gcForceBlockMode {
+ // Special case synchronous sweep.
+ // Record that no proportional sweeping has to happen.
+ lock(&mheap_.lock)
+ mheap_.sweepPagesPerByte = 0
+ unlock(&mheap_.lock)
+ // Sweep all spans eagerly.
+ for sweepone() != ^uintptr(0) {
+ sweep.npausesweep++
+ }
+ // Free workbufs eagerly.
+ prepareFreeWorkbufs()
+ for freeSomeWbufs(false) {
+ }
+ // All "free" events for this mark/sweep cycle have
+ // now happened, so we can make this profile cycle
+ // available immediately.
+ mProf_NextCycle()
+ mProf_Flush()
+ return
+ }
+
+ // Background sweep.
+ lock(&sweep.lock)
+ if sweep.parked {
+ sweep.parked = false
+ ready(sweep.g, 0, true)
+ }
+ unlock(&sweep.lock)
+}
+
+// gcResetMarkState resets global state prior to marking (concurrent
+// or STW) and resets the stack scan state of all Gs.
+//
+// This is safe to do without the world stopped because any Gs created
+// during or after this will start out in the reset state.
+//
+// gcResetMarkState must be called on the system stack because it acquires
+// the heap lock. See mheap for details.
+//
+//go:systemstack
+func gcResetMarkState() {
+ // This may be called during a concurrent phase, so lock to make sure
+ // allgs doesn't change.
+ forEachG(func(gp *g) {
+ gp.gcscandone = false // set to true in gcphasework
+ gp.gcAssistBytes = 0
+ })
+
+ // Clear page marks. This is just 1MB per 64GB of heap, so the
+ // time here is pretty trivial.
+ lock(&mheap_.lock)
+ arenas := mheap_.allArenas
+ unlock(&mheap_.lock)
+ for _, ai := range arenas {
+ ha := mheap_.arenas[ai.l1()][ai.l2()]
+ for i := range ha.pageMarks {
+ ha.pageMarks[i] = 0
+ }
+ }
+
+ work.bytesMarked = 0
+ work.initialHeapLive = gcController.heapLive.Load()
+}
+
+// Hooks for other packages
+
+var poolcleanup func()
+var boringCaches []unsafe.Pointer // for crypto/internal/boring
+
+//go:linkname sync_runtime_registerPoolCleanup sync.runtime_registerPoolCleanup
+func sync_runtime_registerPoolCleanup(f func()) {
+ poolcleanup = f
+}
+
+//go:linkname boring_registerCache crypto/internal/boring/bcache.registerCache
+func boring_registerCache(p unsafe.Pointer) {
+ boringCaches = append(boringCaches, p)
+}
+
+func clearpools() {
+ // clear sync.Pools
+ if poolcleanup != nil {
+ poolcleanup()
+ }
+
+ // clear boringcrypto caches
+ for _, p := range boringCaches {
+ atomicstorep(p, nil)
+ }
+
+ // Clear central sudog cache.
+ // Leave per-P caches alone, they have strictly bounded size.
+ // Disconnect cached list before dropping it on the floor,
+ // so that a dangling ref to one entry does not pin all of them.
+ lock(&sched.sudoglock)
+ var sg, sgnext *sudog
+ for sg = sched.sudogcache; sg != nil; sg = sgnext {
+ sgnext = sg.next
+ sg.next = nil
+ }
+ sched.sudogcache = nil
+ unlock(&sched.sudoglock)
+
+ // Clear central defer pool.
+ // Leave per-P pools alone, they have strictly bounded size.
+ lock(&sched.deferlock)
+ // disconnect cached list before dropping it on the floor,
+ // so that a dangling ref to one entry does not pin all of them.
+ var d, dlink *_defer
+ for d = sched.deferpool; d != nil; d = dlink {
+ dlink = d.link
+ d.link = nil
+ }
+ sched.deferpool = nil
+ unlock(&sched.deferlock)
+}
+
+// Timing
+
+// itoaDiv formats val/(10**dec) into buf.
+func itoaDiv(buf []byte, val uint64, dec int) []byte {
+ i := len(buf) - 1
+ idec := i - dec
+ for val >= 10 || i >= idec {
+ buf[i] = byte(val%10 + '0')
+ i--
+ if i == idec {
+ buf[i] = '.'
+ i--
+ }
+ val /= 10
+ }
+ buf[i] = byte(val + '0')
+ return buf[i:]
+}
+
+// fmtNSAsMS nicely formats ns nanoseconds as milliseconds.
+func fmtNSAsMS(buf []byte, ns uint64) []byte {
+ if ns >= 10e6 {
+ // Format as whole milliseconds.
+ return itoaDiv(buf, ns/1e6, 0)
+ }
+ // Format two digits of precision, with at most three decimal places.
+ x := ns / 1e3
+ if x == 0 {
+ buf[0] = '0'
+ return buf[:1]
+ }
+ dec := 3
+ for x >= 100 {
+ x /= 10
+ dec--
+ }
+ return itoaDiv(buf, x, dec)
+}
+
+// Helpers for testing GC.
+
+// gcTestMoveStackOnNextCall causes the stack to be moved on a call
+// immediately following the call to this. It may not work correctly
+// if any other work appears after this call (such as returning).
+// Typically the following call should be marked go:noinline so it
+// performs a stack check.
+//
+// In rare cases this may not cause the stack to move, specifically if
+// there's a preemption between this call and the next.
+func gcTestMoveStackOnNextCall() {
+ gp := getg()
+ gp.stackguard0 = stackForceMove
+}
+
+// gcTestIsReachable performs a GC and returns a bit set where bit i
+// is set if ptrs[i] is reachable.
+func gcTestIsReachable(ptrs ...unsafe.Pointer) (mask uint64) {
+ // This takes the pointers as unsafe.Pointers in order to keep
+ // them live long enough for us to attach specials. After
+ // that, we drop our references to them.
+
+ if len(ptrs) > 64 {
+ panic("too many pointers for uint64 mask")
+ }
+
+ // Block GC while we attach specials and drop our references
+ // to ptrs. Otherwise, if a GC is in progress, it could mark
+ // them reachable via this function before we have a chance to
+ // drop them.
+ semacquire(&gcsema)
+
+ // Create reachability specials for ptrs.
+ specials := make([]*specialReachable, len(ptrs))
+ for i, p := range ptrs {
+ lock(&mheap_.speciallock)
+ s := (*specialReachable)(mheap_.specialReachableAlloc.alloc())
+ unlock(&mheap_.speciallock)
+ s.special.kind = _KindSpecialReachable
+ if !addspecial(p, &s.special) {
+ throw("already have a reachable special (duplicate pointer?)")
+ }
+ specials[i] = s
+ // Make sure we don't retain ptrs.
+ ptrs[i] = nil
+ }
+
+ semrelease(&gcsema)
+
+ // Force a full GC and sweep.
+ GC()
+
+ // Process specials.
+ for i, s := range specials {
+ if !s.done {
+ printlock()
+ println("runtime: object", i, "was not swept")
+ throw("IsReachable failed")
+ }
+ if s.reachable {
+ mask |= 1 << i
+ }
+ lock(&mheap_.speciallock)
+ mheap_.specialReachableAlloc.free(unsafe.Pointer(s))
+ unlock(&mheap_.speciallock)
+ }
+
+ return mask
+}
+
+// gcTestPointerClass returns the category of what p points to, one of:
+// "heap", "stack", "data", "bss", "other". This is useful for checking
+// that a test is doing what it's intended to do.
+//
+// This is nosplit simply to avoid extra pointer shuffling that may
+// complicate a test.
+//
+//go:nosplit
+func gcTestPointerClass(p unsafe.Pointer) string {
+ p2 := uintptr(noescape(p))
+ gp := getg()
+ if gp.stack.lo <= p2 && p2 < gp.stack.hi {
+ return "stack"
+ }
+ if base, _, _ := findObject(p2, 0, 0); base != 0 {
+ return "heap"
+ }
+ for _, datap := range activeModules() {
+ if datap.data <= p2 && p2 < datap.edata || datap.noptrdata <= p2 && p2 < datap.enoptrdata {
+ return "data"
+ }
+ if datap.bss <= p2 && p2 < datap.ebss || datap.noptrbss <= p2 && p2 <= datap.enoptrbss {
+ return "bss"
+ }
+ }
+ KeepAlive(p)
+ return "other"
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mgclimit.go b/contrib/go/_std_1.21/src/runtime/mgclimit.go
new file mode 100644
index 0000000000..ef3cc081ce
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mgclimit.go
@@ -0,0 +1,484 @@
+// Copyright 2022 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 runtime
+
+import "runtime/internal/atomic"
+
+// gcCPULimiter is a mechanism to limit GC CPU utilization in situations
+// where it might become excessive and inhibit application progress (e.g.
+// a death spiral).
+//
+// The core of the limiter is a leaky bucket mechanism that fills with GC
+// CPU time and drains with mutator time. Because the bucket fills and
+// drains with time directly (i.e. without any weighting), this effectively
+// sets a very conservative limit of 50%. This limit could be enforced directly,
+// however, but the purpose of the bucket is to accommodate spikes in GC CPU
+// utilization without hurting throughput.
+//
+// Note that the bucket in the leaky bucket mechanism can never go negative,
+// so the GC never gets credit for a lot of CPU time spent without the GC
+// running. This is intentional, as an application that stays idle for, say,
+// an entire day, could build up enough credit to fail to prevent a death
+// spiral the following day. The bucket's capacity is the GC's only leeway.
+//
+// The capacity thus also sets the window the limiter considers. For example,
+// if the capacity of the bucket is 1 cpu-second, then the limiter will not
+// kick in until at least 1 full cpu-second in the last 2 cpu-second window
+// is spent on GC CPU time.
+var gcCPULimiter gcCPULimiterState
+
+type gcCPULimiterState struct {
+ lock atomic.Uint32
+
+ enabled atomic.Bool
+ bucket struct {
+ // Invariants:
+ // - fill >= 0
+ // - capacity >= 0
+ // - fill <= capacity
+ fill, capacity uint64
+ }
+ // overflow is the cumulative amount of GC CPU time that we tried to fill the
+ // bucket with but exceeded its capacity.
+ overflow uint64
+
+ // gcEnabled is an internal copy of gcBlackenEnabled that determines
+ // whether the limiter tracks total assist time.
+ //
+ // gcBlackenEnabled isn't used directly so as to keep this structure
+ // unit-testable.
+ gcEnabled bool
+
+ // transitioning is true when the GC is in a STW and transitioning between
+ // the mark and sweep phases.
+ transitioning bool
+
+ // assistTimePool is the accumulated assist time since the last update.
+ assistTimePool atomic.Int64
+
+ // idleMarkTimePool is the accumulated idle mark time since the last update.
+ idleMarkTimePool atomic.Int64
+
+ // idleTimePool is the accumulated time Ps spent on the idle list since the last update.
+ idleTimePool atomic.Int64
+
+ // lastUpdate is the nanotime timestamp of the last time update was called.
+ //
+ // Updated under lock, but may be read concurrently.
+ lastUpdate atomic.Int64
+
+ // lastEnabledCycle is the GC cycle that last had the limiter enabled.
+ lastEnabledCycle atomic.Uint32
+
+ // nprocs is an internal copy of gomaxprocs, used to determine total available
+ // CPU time.
+ //
+ // gomaxprocs isn't used directly so as to keep this structure unit-testable.
+ nprocs int32
+
+ // test indicates whether this instance of the struct was made for testing purposes.
+ test bool
+}
+
+// limiting returns true if the CPU limiter is currently enabled, meaning the Go GC
+// should take action to limit CPU utilization.
+//
+// It is safe to call concurrently with other operations.
+func (l *gcCPULimiterState) limiting() bool {
+ return l.enabled.Load()
+}
+
+// startGCTransition notifies the limiter of a GC transition.
+//
+// This call takes ownership of the limiter and disables all other means of
+// updating the limiter. Release ownership by calling finishGCTransition.
+//
+// It is safe to call concurrently with other operations.
+func (l *gcCPULimiterState) startGCTransition(enableGC bool, now int64) {
+ if !l.tryLock() {
+ // This must happen during a STW, so we can't fail to acquire the lock.
+ // If we did, something went wrong. Throw.
+ throw("failed to acquire lock to start a GC transition")
+ }
+ if l.gcEnabled == enableGC {
+ throw("transitioning GC to the same state as before?")
+ }
+ // Flush whatever was left between the last update and now.
+ l.updateLocked(now)
+ l.gcEnabled = enableGC
+ l.transitioning = true
+ // N.B. finishGCTransition releases the lock.
+ //
+ // We don't release here to increase the chance that if there's a failure
+ // to finish the transition, that we throw on failing to acquire the lock.
+}
+
+// finishGCTransition notifies the limiter that the GC transition is complete
+// and releases ownership of it. It also accumulates STW time in the bucket.
+// now must be the timestamp from the end of the STW pause.
+func (l *gcCPULimiterState) finishGCTransition(now int64) {
+ if !l.transitioning {
+ throw("finishGCTransition called without starting one?")
+ }
+ // Count the full nprocs set of CPU time because the world is stopped
+ // between startGCTransition and finishGCTransition. Even though the GC
+ // isn't running on all CPUs, it is preventing user code from doing so,
+ // so it might as well be.
+ if lastUpdate := l.lastUpdate.Load(); now >= lastUpdate {
+ l.accumulate(0, (now-lastUpdate)*int64(l.nprocs))
+ }
+ l.lastUpdate.Store(now)
+ l.transitioning = false
+ l.unlock()
+}
+
+// gcCPULimiterUpdatePeriod dictates the maximum amount of wall-clock time
+// we can go before updating the limiter.
+const gcCPULimiterUpdatePeriod = 10e6 // 10ms
+
+// needUpdate returns true if the limiter's maximum update period has been
+// exceeded, and so would benefit from an update.
+func (l *gcCPULimiterState) needUpdate(now int64) bool {
+ return now-l.lastUpdate.Load() > gcCPULimiterUpdatePeriod
+}
+
+// addAssistTime notifies the limiter of additional assist time. It will be
+// included in the next update.
+func (l *gcCPULimiterState) addAssistTime(t int64) {
+ l.assistTimePool.Add(t)
+}
+
+// addIdleTime notifies the limiter of additional time a P spent on the idle list. It will be
+// subtracted from the total CPU time in the next update.
+func (l *gcCPULimiterState) addIdleTime(t int64) {
+ l.idleTimePool.Add(t)
+}
+
+// update updates the bucket given runtime-specific information. now is the
+// current monotonic time in nanoseconds.
+//
+// This is safe to call concurrently with other operations, except *GCTransition.
+func (l *gcCPULimiterState) update(now int64) {
+ if !l.tryLock() {
+ // We failed to acquire the lock, which means something else is currently
+ // updating. Just drop our update, the next one to update will include
+ // our total assist time.
+ return
+ }
+ if l.transitioning {
+ throw("update during transition")
+ }
+ l.updateLocked(now)
+ l.unlock()
+}
+
+// updateLocked is the implementation of update. l.lock must be held.
+func (l *gcCPULimiterState) updateLocked(now int64) {
+ lastUpdate := l.lastUpdate.Load()
+ if now < lastUpdate {
+ // Defensively avoid overflow. This isn't even the latest update anyway.
+ return
+ }
+ windowTotalTime := (now - lastUpdate) * int64(l.nprocs)
+ l.lastUpdate.Store(now)
+
+ // Drain the pool of assist time.
+ assistTime := l.assistTimePool.Load()
+ if assistTime != 0 {
+ l.assistTimePool.Add(-assistTime)
+ }
+
+ // Drain the pool of idle time.
+ idleTime := l.idleTimePool.Load()
+ if idleTime != 0 {
+ l.idleTimePool.Add(-idleTime)
+ }
+
+ if !l.test {
+ // Consume time from in-flight events. Make sure we're not preemptible so allp can't change.
+ //
+ // The reason we do this instead of just waiting for those events to finish and push updates
+ // is to ensure that all the time we're accounting for happened sometime between lastUpdate
+ // and now. This dramatically simplifies reasoning about the limiter because we're not at
+ // risk of extra time being accounted for in this window than actually happened in this window,
+ // leading to all sorts of weird transient behavior.
+ mp := acquirem()
+ for _, pp := range allp {
+ typ, duration := pp.limiterEvent.consume(now)
+ switch typ {
+ case limiterEventIdleMarkWork:
+ fallthrough
+ case limiterEventIdle:
+ idleTime += duration
+ sched.idleTime.Add(duration)
+ case limiterEventMarkAssist:
+ fallthrough
+ case limiterEventScavengeAssist:
+ assistTime += duration
+ case limiterEventNone:
+ break
+ default:
+ throw("invalid limiter event type found")
+ }
+ }
+ releasem(mp)
+ }
+
+ // Compute total GC time.
+ windowGCTime := assistTime
+ if l.gcEnabled {
+ windowGCTime += int64(float64(windowTotalTime) * gcBackgroundUtilization)
+ }
+
+ // Subtract out all idle time from the total time. Do this after computing
+ // GC time, because the background utilization is dependent on the *real*
+ // total time, not the total time after idle time is subtracted.
+ //
+ // Idle time is counted as any time that a P is on the P idle list plus idle mark
+ // time. Idle mark workers soak up time that the application spends idle.
+ //
+ // On a heavily undersubscribed system, any additional idle time can skew GC CPU
+ // utilization, because the GC might be executing continuously and thrashing,
+ // yet the CPU utilization with respect to GOMAXPROCS will be quite low, so
+ // the limiter fails to turn on. By subtracting idle time, we're removing time that
+ // we know the application was idle giving a more accurate picture of whether
+ // the GC is thrashing.
+ //
+ // Note that this can cause the limiter to turn on even if it's not needed. For
+ // instance, on a system with 32 Ps but only 1 running goroutine, each GC will have
+ // 8 dedicated GC workers. Assuming the GC cycle is half mark phase and half sweep
+ // phase, then the GC CPU utilization over that cycle, with idle time removed, will
+ // be 8/(8+2) = 80%. Even though the limiter turns on, though, assist should be
+ // unnecessary, as the GC has way more CPU time to outpace the 1 goroutine that's
+ // running.
+ windowTotalTime -= idleTime
+
+ l.accumulate(windowTotalTime-windowGCTime, windowGCTime)
+}
+
+// accumulate adds time to the bucket and signals whether the limiter is enabled.
+//
+// This is an internal function that deals just with the bucket. Prefer update.
+// l.lock must be held.
+func (l *gcCPULimiterState) accumulate(mutatorTime, gcTime int64) {
+ headroom := l.bucket.capacity - l.bucket.fill
+ enabled := headroom == 0
+
+ // Let's be careful about three things here:
+ // 1. The addition and subtraction, for the invariants.
+ // 2. Overflow.
+ // 3. Excessive mutation of l.enabled, which is accessed
+ // by all assists, potentially more than once.
+ change := gcTime - mutatorTime
+
+ // Handle limiting case.
+ if change > 0 && headroom <= uint64(change) {
+ l.overflow += uint64(change) - headroom
+ l.bucket.fill = l.bucket.capacity
+ if !enabled {
+ l.enabled.Store(true)
+ l.lastEnabledCycle.Store(memstats.numgc + 1)
+ }
+ return
+ }
+
+ // Handle non-limiting cases.
+ if change < 0 && l.bucket.fill <= uint64(-change) {
+ // Bucket emptied.
+ l.bucket.fill = 0
+ } else {
+ // All other cases.
+ l.bucket.fill -= uint64(-change)
+ }
+ if change != 0 && enabled {
+ l.enabled.Store(false)
+ }
+}
+
+// tryLock attempts to lock l. Returns true on success.
+func (l *gcCPULimiterState) tryLock() bool {
+ return l.lock.CompareAndSwap(0, 1)
+}
+
+// unlock releases the lock on l. Must be called if tryLock returns true.
+func (l *gcCPULimiterState) unlock() {
+ old := l.lock.Swap(0)
+ if old != 1 {
+ throw("double unlock")
+ }
+}
+
+// capacityPerProc is the limiter's bucket capacity for each P in GOMAXPROCS.
+const capacityPerProc = 1e9 // 1 second in nanoseconds
+
+// resetCapacity updates the capacity based on GOMAXPROCS. Must not be called
+// while the GC is enabled.
+//
+// It is safe to call concurrently with other operations.
+func (l *gcCPULimiterState) resetCapacity(now int64, nprocs int32) {
+ if !l.tryLock() {
+ // This must happen during a STW, so we can't fail to acquire the lock.
+ // If we did, something went wrong. Throw.
+ throw("failed to acquire lock to reset capacity")
+ }
+ // Flush the rest of the time for this period.
+ l.updateLocked(now)
+ l.nprocs = nprocs
+
+ l.bucket.capacity = uint64(nprocs) * capacityPerProc
+ if l.bucket.fill > l.bucket.capacity {
+ l.bucket.fill = l.bucket.capacity
+ l.enabled.Store(true)
+ l.lastEnabledCycle.Store(memstats.numgc + 1)
+ } else if l.bucket.fill < l.bucket.capacity {
+ l.enabled.Store(false)
+ }
+ l.unlock()
+}
+
+// limiterEventType indicates the type of an event occurring on some P.
+//
+// These events represent the full set of events that the GC CPU limiter tracks
+// to execute its function.
+//
+// This type may use no more than limiterEventBits bits of information.
+type limiterEventType uint8
+
+const (
+ limiterEventNone limiterEventType = iota // None of the following events.
+ limiterEventIdleMarkWork // Refers to an idle mark worker (see gcMarkWorkerMode).
+ limiterEventMarkAssist // Refers to mark assist (see gcAssistAlloc).
+ limiterEventScavengeAssist // Refers to a scavenge assist (see allocSpan).
+ limiterEventIdle // Refers to time a P spent on the idle list.
+
+ limiterEventBits = 3
+)
+
+// limiterEventTypeMask is a mask for the bits in p.limiterEventStart that represent
+// the event type. The rest of the bits of that field represent a timestamp.
+const (
+ limiterEventTypeMask = uint64((1<<limiterEventBits)-1) << (64 - limiterEventBits)
+ limiterEventStampNone = limiterEventStamp(0)
+)
+
+// limiterEventStamp is a nanotime timestamp packed with a limiterEventType.
+type limiterEventStamp uint64
+
+// makeLimiterEventStamp creates a new stamp from the event type and the current timestamp.
+func makeLimiterEventStamp(typ limiterEventType, now int64) limiterEventStamp {
+ return limiterEventStamp(uint64(typ)<<(64-limiterEventBits) | (uint64(now) &^ limiterEventTypeMask))
+}
+
+// duration computes the difference between now and the start time stored in the stamp.
+//
+// Returns 0 if the difference is negative, which may happen if now is stale or if the
+// before and after timestamps cross a 2^(64-limiterEventBits) boundary.
+func (s limiterEventStamp) duration(now int64) int64 {
+ // The top limiterEventBits bits of the timestamp are derived from the current time
+ // when computing a duration.
+ start := int64((uint64(now) & limiterEventTypeMask) | (uint64(s) &^ limiterEventTypeMask))
+ if now < start {
+ return 0
+ }
+ return now - start
+}
+
+// type extracts the event type from the stamp.
+func (s limiterEventStamp) typ() limiterEventType {
+ return limiterEventType(s >> (64 - limiterEventBits))
+}
+
+// limiterEvent represents tracking state for an event tracked by the GC CPU limiter.
+type limiterEvent struct {
+ stamp atomic.Uint64 // Stores a limiterEventStamp.
+}
+
+// start begins tracking a new limiter event of the current type. If an event
+// is already in flight, then a new event cannot begin because the current time is
+// already being attributed to that event. In this case, this function returns false.
+// Otherwise, it returns true.
+//
+// The caller must be non-preemptible until at least stop is called or this function
+// returns false. Because this is trying to measure "on-CPU" time of some event, getting
+// scheduled away during it can mean that whatever we're measuring isn't a reflection
+// of "on-CPU" time. The OS could deschedule us at any time, but we want to maintain as
+// close of an approximation as we can.
+func (e *limiterEvent) start(typ limiterEventType, now int64) bool {
+ if limiterEventStamp(e.stamp.Load()).typ() != limiterEventNone {
+ return false
+ }
+ e.stamp.Store(uint64(makeLimiterEventStamp(typ, now)))
+ return true
+}
+
+// consume acquires the partial event CPU time from any in-flight event.
+// It achieves this by storing the current time as the new event time.
+//
+// Returns the type of the in-flight event, as well as how long it's currently been
+// executing for. Returns limiterEventNone if no event is active.
+func (e *limiterEvent) consume(now int64) (typ limiterEventType, duration int64) {
+ // Read the limiter event timestamp and update it to now.
+ for {
+ old := limiterEventStamp(e.stamp.Load())
+ typ = old.typ()
+ if typ == limiterEventNone {
+ // There's no in-flight event, so just push that up.
+ return
+ }
+ duration = old.duration(now)
+ if duration == 0 {
+ // We might have a stale now value, or this crossed the
+ // 2^(64-limiterEventBits) boundary in the clock readings.
+ // Just ignore it.
+ return limiterEventNone, 0
+ }
+ new := makeLimiterEventStamp(typ, now)
+ if e.stamp.CompareAndSwap(uint64(old), uint64(new)) {
+ break
+ }
+ }
+ return
+}
+
+// stop stops the active limiter event. Throws if the
+//
+// The caller must be non-preemptible across the event. See start as to why.
+func (e *limiterEvent) stop(typ limiterEventType, now int64) {
+ var stamp limiterEventStamp
+ for {
+ stamp = limiterEventStamp(e.stamp.Load())
+ if stamp.typ() != typ {
+ print("runtime: want=", typ, " got=", stamp.typ(), "\n")
+ throw("limiterEvent.stop: found wrong event in p's limiter event slot")
+ }
+ if e.stamp.CompareAndSwap(uint64(stamp), uint64(limiterEventStampNone)) {
+ break
+ }
+ }
+ duration := stamp.duration(now)
+ if duration == 0 {
+ // It's possible that we're missing time because we crossed a
+ // 2^(64-limiterEventBits) boundary between the start and end.
+ // In this case, we're dropping that information. This is OK because
+ // at worst it'll cause a transient hiccup that will quickly resolve
+ // itself as all new timestamps begin on the other side of the boundary.
+ // Such a hiccup should be incredibly rare.
+ return
+ }
+ // Account for the event.
+ switch typ {
+ case limiterEventIdleMarkWork:
+ gcCPULimiter.addIdleTime(duration)
+ case limiterEventIdle:
+ gcCPULimiter.addIdleTime(duration)
+ sched.idleTime.Add(duration)
+ case limiterEventMarkAssist:
+ fallthrough
+ case limiterEventScavengeAssist:
+ gcCPULimiter.addAssistTime(duration)
+ default:
+ throw("limiterEvent.stop: invalid limiter event type found")
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mgcmark.go b/contrib/go/_std_1.21/src/runtime/mgcmark.go
new file mode 100644
index 0000000000..2ed411ae61
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mgcmark.go
@@ -0,0 +1,1598 @@
+// Copyright 2009 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.
+
+// Garbage collector: marking and scanning
+
+package runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+const (
+ fixedRootFinalizers = iota
+ fixedRootFreeGStacks
+ fixedRootCount
+
+ // rootBlockBytes is the number of bytes to scan per data or
+ // BSS root.
+ rootBlockBytes = 256 << 10
+
+ // maxObletBytes is the maximum bytes of an object to scan at
+ // once. Larger objects will be split up into "oblets" of at
+ // most this size. Since we can scan 1–2 MB/ms, 128 KB bounds
+ // scan preemption at ~100 µs.
+ //
+ // This must be > _MaxSmallSize so that the object base is the
+ // span base.
+ maxObletBytes = 128 << 10
+
+ // drainCheckThreshold specifies how many units of work to do
+ // between self-preemption checks in gcDrain. Assuming a scan
+ // rate of 1 MB/ms, this is ~100 µs. Lower values have higher
+ // overhead in the scan loop (the scheduler check may perform
+ // a syscall, so its overhead is nontrivial). Higher values
+ // make the system less responsive to incoming work.
+ drainCheckThreshold = 100000
+
+ // pagesPerSpanRoot indicates how many pages to scan from a span root
+ // at a time. Used by special root marking.
+ //
+ // Higher values improve throughput by increasing locality, but
+ // increase the minimum latency of a marking operation.
+ //
+ // Must be a multiple of the pageInUse bitmap element size and
+ // must also evenly divide pagesPerArena.
+ pagesPerSpanRoot = 512
+)
+
+// gcMarkRootPrepare queues root scanning jobs (stacks, globals, and
+// some miscellany) and initializes scanning-related state.
+//
+// The world must be stopped.
+func gcMarkRootPrepare() {
+ assertWorldStopped()
+
+ // Compute how many data and BSS root blocks there are.
+ nBlocks := func(bytes uintptr) int {
+ return int(divRoundUp(bytes, rootBlockBytes))
+ }
+
+ work.nDataRoots = 0
+ work.nBSSRoots = 0
+
+ // Scan globals.
+ for _, datap := range activeModules() {
+ nDataRoots := nBlocks(datap.edata - datap.data)
+ if nDataRoots > work.nDataRoots {
+ work.nDataRoots = nDataRoots
+ }
+ }
+
+ for _, datap := range activeModules() {
+ nBSSRoots := nBlocks(datap.ebss - datap.bss)
+ if nBSSRoots > work.nBSSRoots {
+ work.nBSSRoots = nBSSRoots
+ }
+ }
+
+ // Scan span roots for finalizer specials.
+ //
+ // We depend on addfinalizer to mark objects that get
+ // finalizers after root marking.
+ //
+ // We're going to scan the whole heap (that was available at the time the
+ // mark phase started, i.e. markArenas) for in-use spans which have specials.
+ //
+ // Break up the work into arenas, and further into chunks.
+ //
+ // Snapshot allArenas as markArenas. This snapshot is safe because allArenas
+ // is append-only.
+ mheap_.markArenas = mheap_.allArenas[:len(mheap_.allArenas):len(mheap_.allArenas)]
+ work.nSpanRoots = len(mheap_.markArenas) * (pagesPerArena / pagesPerSpanRoot)
+
+ // Scan stacks.
+ //
+ // Gs may be created after this point, but it's okay that we
+ // ignore them because they begin life without any roots, so
+ // there's nothing to scan, and any roots they create during
+ // the concurrent phase will be caught by the write barrier.
+ work.stackRoots = allGsSnapshot()
+ work.nStackRoots = len(work.stackRoots)
+
+ work.markrootNext = 0
+ work.markrootJobs = uint32(fixedRootCount + work.nDataRoots + work.nBSSRoots + work.nSpanRoots + work.nStackRoots)
+
+ // Calculate base indexes of each root type
+ work.baseData = uint32(fixedRootCount)
+ work.baseBSS = work.baseData + uint32(work.nDataRoots)
+ work.baseSpans = work.baseBSS + uint32(work.nBSSRoots)
+ work.baseStacks = work.baseSpans + uint32(work.nSpanRoots)
+ work.baseEnd = work.baseStacks + uint32(work.nStackRoots)
+}
+
+// gcMarkRootCheck checks that all roots have been scanned. It is
+// purely for debugging.
+func gcMarkRootCheck() {
+ if work.markrootNext < work.markrootJobs {
+ print(work.markrootNext, " of ", work.markrootJobs, " markroot jobs done\n")
+ throw("left over markroot jobs")
+ }
+
+ // Check that stacks have been scanned.
+ //
+ // We only check the first nStackRoots Gs that we should have scanned.
+ // Since we don't care about newer Gs (see comment in
+ // gcMarkRootPrepare), no locking is required.
+ i := 0
+ forEachGRace(func(gp *g) {
+ if i >= work.nStackRoots {
+ return
+ }
+
+ if !gp.gcscandone {
+ println("gp", gp, "goid", gp.goid,
+ "status", readgstatus(gp),
+ "gcscandone", gp.gcscandone)
+ throw("scan missed a g")
+ }
+
+ i++
+ })
+}
+
+// ptrmask for an allocation containing a single pointer.
+var oneptrmask = [...]uint8{1}
+
+// markroot scans the i'th root.
+//
+// Preemption must be disabled (because this uses a gcWork).
+//
+// Returns the amount of GC work credit produced by the operation.
+// If flushBgCredit is true, then that credit is also flushed
+// to the background credit pool.
+//
+// nowritebarrier is only advisory here.
+//
+//go:nowritebarrier
+func markroot(gcw *gcWork, i uint32, flushBgCredit bool) int64 {
+ // Note: if you add a case here, please also update heapdump.go:dumproots.
+ var workDone int64
+ var workCounter *atomic.Int64
+ switch {
+ case work.baseData <= i && i < work.baseBSS:
+ workCounter = &gcController.globalsScanWork
+ for _, datap := range activeModules() {
+ workDone += markrootBlock(datap.data, datap.edata-datap.data, datap.gcdatamask.bytedata, gcw, int(i-work.baseData))
+ }
+
+ case work.baseBSS <= i && i < work.baseSpans:
+ workCounter = &gcController.globalsScanWork
+ for _, datap := range activeModules() {
+ workDone += markrootBlock(datap.bss, datap.ebss-datap.bss, datap.gcbssmask.bytedata, gcw, int(i-work.baseBSS))
+ }
+
+ case i == fixedRootFinalizers:
+ for fb := allfin; fb != nil; fb = fb.alllink {
+ cnt := uintptr(atomic.Load(&fb.cnt))
+ scanblock(uintptr(unsafe.Pointer(&fb.fin[0])), cnt*unsafe.Sizeof(fb.fin[0]), &finptrmask[0], gcw, nil)
+ }
+
+ case i == fixedRootFreeGStacks:
+ // Switch to the system stack so we can call
+ // stackfree.
+ systemstack(markrootFreeGStacks)
+
+ case work.baseSpans <= i && i < work.baseStacks:
+ // mark mspan.specials
+ markrootSpans(gcw, int(i-work.baseSpans))
+
+ default:
+ // the rest is scanning goroutine stacks
+ workCounter = &gcController.stackScanWork
+ if i < work.baseStacks || work.baseEnd <= i {
+ printlock()
+ print("runtime: markroot index ", i, " not in stack roots range [", work.baseStacks, ", ", work.baseEnd, ")\n")
+ throw("markroot: bad index")
+ }
+ gp := work.stackRoots[i-work.baseStacks]
+
+ // remember when we've first observed the G blocked
+ // needed only to output in traceback
+ status := readgstatus(gp) // We are not in a scan state
+ if (status == _Gwaiting || status == _Gsyscall) && gp.waitsince == 0 {
+ gp.waitsince = work.tstart
+ }
+
+ // scanstack must be done on the system stack in case
+ // we're trying to scan our own stack.
+ systemstack(func() {
+ // If this is a self-scan, put the user G in
+ // _Gwaiting to prevent self-deadlock. It may
+ // already be in _Gwaiting if this is a mark
+ // worker or we're in mark termination.
+ userG := getg().m.curg
+ selfScan := gp == userG && readgstatus(userG) == _Grunning
+ if selfScan {
+ casGToWaiting(userG, _Grunning, waitReasonGarbageCollectionScan)
+ }
+
+ // TODO: suspendG blocks (and spins) until gp
+ // stops, which may take a while for
+ // running goroutines. Consider doing this in
+ // two phases where the first is non-blocking:
+ // we scan the stacks we can and ask running
+ // goroutines to scan themselves; and the
+ // second blocks.
+ stopped := suspendG(gp)
+ if stopped.dead {
+ gp.gcscandone = true
+ return
+ }
+ if gp.gcscandone {
+ throw("g already scanned")
+ }
+ workDone += scanstack(gp, gcw)
+ gp.gcscandone = true
+ resumeG(stopped)
+
+ if selfScan {
+ casgstatus(userG, _Gwaiting, _Grunning)
+ }
+ })
+ }
+ if workCounter != nil && workDone != 0 {
+ workCounter.Add(workDone)
+ if flushBgCredit {
+ gcFlushBgCredit(workDone)
+ }
+ }
+ return workDone
+}
+
+// markrootBlock scans the shard'th shard of the block of memory [b0,
+// b0+n0), with the given pointer mask.
+//
+// Returns the amount of work done.
+//
+//go:nowritebarrier
+func markrootBlock(b0, n0 uintptr, ptrmask0 *uint8, gcw *gcWork, shard int) int64 {
+ if rootBlockBytes%(8*goarch.PtrSize) != 0 {
+ // This is necessary to pick byte offsets in ptrmask0.
+ throw("rootBlockBytes must be a multiple of 8*ptrSize")
+ }
+
+ // Note that if b0 is toward the end of the address space,
+ // then b0 + rootBlockBytes might wrap around.
+ // These tests are written to avoid any possible overflow.
+ off := uintptr(shard) * rootBlockBytes
+ if off >= n0 {
+ return 0
+ }
+ b := b0 + off
+ ptrmask := (*uint8)(add(unsafe.Pointer(ptrmask0), uintptr(shard)*(rootBlockBytes/(8*goarch.PtrSize))))
+ n := uintptr(rootBlockBytes)
+ if off+n > n0 {
+ n = n0 - off
+ }
+
+ // Scan this shard.
+ scanblock(b, n, ptrmask, gcw, nil)
+ return int64(n)
+}
+
+// markrootFreeGStacks frees stacks of dead Gs.
+//
+// This does not free stacks of dead Gs cached on Ps, but having a few
+// cached stacks around isn't a problem.
+func markrootFreeGStacks() {
+ // Take list of dead Gs with stacks.
+ lock(&sched.gFree.lock)
+ list := sched.gFree.stack
+ sched.gFree.stack = gList{}
+ unlock(&sched.gFree.lock)
+ if list.empty() {
+ return
+ }
+
+ // Free stacks.
+ q := gQueue{list.head, list.head}
+ for gp := list.head.ptr(); gp != nil; gp = gp.schedlink.ptr() {
+ stackfree(gp.stack)
+ gp.stack.lo = 0
+ gp.stack.hi = 0
+ // Manipulate the queue directly since the Gs are
+ // already all linked the right way.
+ q.tail.set(gp)
+ }
+
+ // Put Gs back on the free list.
+ lock(&sched.gFree.lock)
+ sched.gFree.noStack.pushAll(q)
+ unlock(&sched.gFree.lock)
+}
+
+// markrootSpans marks roots for one shard of markArenas.
+//
+//go:nowritebarrier
+func markrootSpans(gcw *gcWork, shard int) {
+ // Objects with finalizers have two GC-related invariants:
+ //
+ // 1) Everything reachable from the object must be marked.
+ // This ensures that when we pass the object to its finalizer,
+ // everything the finalizer can reach will be retained.
+ //
+ // 2) Finalizer specials (which are not in the garbage
+ // collected heap) are roots. In practice, this means the fn
+ // field must be scanned.
+ sg := mheap_.sweepgen
+
+ // Find the arena and page index into that arena for this shard.
+ ai := mheap_.markArenas[shard/(pagesPerArena/pagesPerSpanRoot)]
+ ha := mheap_.arenas[ai.l1()][ai.l2()]
+ arenaPage := uint(uintptr(shard) * pagesPerSpanRoot % pagesPerArena)
+
+ // Construct slice of bitmap which we'll iterate over.
+ specialsbits := ha.pageSpecials[arenaPage/8:]
+ specialsbits = specialsbits[:pagesPerSpanRoot/8]
+ for i := range specialsbits {
+ // Find set bits, which correspond to spans with specials.
+ specials := atomic.Load8(&specialsbits[i])
+ if specials == 0 {
+ continue
+ }
+ for j := uint(0); j < 8; j++ {
+ if specials&(1<<j) == 0 {
+ continue
+ }
+ // Find the span for this bit.
+ //
+ // This value is guaranteed to be non-nil because having
+ // specials implies that the span is in-use, and since we're
+ // currently marking we can be sure that we don't have to worry
+ // about the span being freed and re-used.
+ s := ha.spans[arenaPage+uint(i)*8+j]
+
+ // The state must be mSpanInUse if the specials bit is set, so
+ // sanity check that.
+ if state := s.state.get(); state != mSpanInUse {
+ print("s.state = ", state, "\n")
+ throw("non in-use span found with specials bit set")
+ }
+ // Check that this span was swept (it may be cached or uncached).
+ if !useCheckmark && !(s.sweepgen == sg || s.sweepgen == sg+3) {
+ // sweepgen was updated (+2) during non-checkmark GC pass
+ print("sweep ", s.sweepgen, " ", sg, "\n")
+ throw("gc: unswept span")
+ }
+
+ // Lock the specials to prevent a special from being
+ // removed from the list while we're traversing it.
+ lock(&s.speciallock)
+ for sp := s.specials; sp != nil; sp = sp.next {
+ if sp.kind != _KindSpecialFinalizer {
+ continue
+ }
+ // don't mark finalized object, but scan it so we
+ // retain everything it points to.
+ spf := (*specialfinalizer)(unsafe.Pointer(sp))
+ // A finalizer can be set for an inner byte of an object, find object beginning.
+ p := s.base() + uintptr(spf.special.offset)/s.elemsize*s.elemsize
+
+ // Mark everything that can be reached from
+ // the object (but *not* the object itself or
+ // we'll never collect it).
+ if !s.spanclass.noscan() {
+ scanobject(p, gcw)
+ }
+
+ // The special itself is a root.
+ scanblock(uintptr(unsafe.Pointer(&spf.fn)), goarch.PtrSize, &oneptrmask[0], gcw, nil)
+ }
+ unlock(&s.speciallock)
+ }
+ }
+}
+
+// gcAssistAlloc performs GC work to make gp's assist debt positive.
+// gp must be the calling user goroutine.
+//
+// This must be called with preemption enabled.
+func gcAssistAlloc(gp *g) {
+ // Don't assist in non-preemptible contexts. These are
+ // generally fragile and won't allow the assist to block.
+ if getg() == gp.m.g0 {
+ return
+ }
+ if mp := getg().m; mp.locks > 0 || mp.preemptoff != "" {
+ return
+ }
+
+ traced := false
+retry:
+ if gcCPULimiter.limiting() {
+ // If the CPU limiter is enabled, intentionally don't
+ // assist to reduce the amount of CPU time spent in the GC.
+ if traced {
+ traceGCMarkAssistDone()
+ }
+ return
+ }
+ // Compute the amount of scan work we need to do to make the
+ // balance positive. When the required amount of work is low,
+ // we over-assist to build up credit for future allocations
+ // and amortize the cost of assisting.
+ assistWorkPerByte := gcController.assistWorkPerByte.Load()
+ assistBytesPerWork := gcController.assistBytesPerWork.Load()
+ debtBytes := -gp.gcAssistBytes
+ scanWork := int64(assistWorkPerByte * float64(debtBytes))
+ if scanWork < gcOverAssistWork {
+ scanWork = gcOverAssistWork
+ debtBytes = int64(assistBytesPerWork * float64(scanWork))
+ }
+
+ // Steal as much credit as we can from the background GC's
+ // scan credit. This is racy and may drop the background
+ // credit below 0 if two mutators steal at the same time. This
+ // will just cause steals to fail until credit is accumulated
+ // again, so in the long run it doesn't really matter, but we
+ // do have to handle the negative credit case.
+ bgScanCredit := gcController.bgScanCredit.Load()
+ stolen := int64(0)
+ if bgScanCredit > 0 {
+ if bgScanCredit < scanWork {
+ stolen = bgScanCredit
+ gp.gcAssistBytes += 1 + int64(assistBytesPerWork*float64(stolen))
+ } else {
+ stolen = scanWork
+ gp.gcAssistBytes += debtBytes
+ }
+ gcController.bgScanCredit.Add(-stolen)
+
+ scanWork -= stolen
+
+ if scanWork == 0 {
+ // We were able to steal all of the credit we
+ // needed.
+ if traced {
+ traceGCMarkAssistDone()
+ }
+ return
+ }
+ }
+
+ if traceEnabled() && !traced {
+ traced = true
+ traceGCMarkAssistStart()
+ }
+
+ // Perform assist work
+ systemstack(func() {
+ gcAssistAlloc1(gp, scanWork)
+ // The user stack may have moved, so this can't touch
+ // anything on it until it returns from systemstack.
+ })
+
+ completed := gp.param != nil
+ gp.param = nil
+ if completed {
+ gcMarkDone()
+ }
+
+ if gp.gcAssistBytes < 0 {
+ // We were unable steal enough credit or perform
+ // enough work to pay off the assist debt. We need to
+ // do one of these before letting the mutator allocate
+ // more to prevent over-allocation.
+ //
+ // If this is because we were preempted, reschedule
+ // and try some more.
+ if gp.preempt {
+ Gosched()
+ goto retry
+ }
+
+ // Add this G to an assist queue and park. When the GC
+ // has more background credit, it will satisfy queued
+ // assists before flushing to the global credit pool.
+ //
+ // Note that this does *not* get woken up when more
+ // work is added to the work list. The theory is that
+ // there wasn't enough work to do anyway, so we might
+ // as well let background marking take care of the
+ // work that is available.
+ if !gcParkAssist() {
+ goto retry
+ }
+
+ // At this point either background GC has satisfied
+ // this G's assist debt, or the GC cycle is over.
+ }
+ if traced {
+ traceGCMarkAssistDone()
+ }
+}
+
+// gcAssistAlloc1 is the part of gcAssistAlloc that runs on the system
+// stack. This is a separate function to make it easier to see that
+// we're not capturing anything from the user stack, since the user
+// stack may move while we're in this function.
+//
+// gcAssistAlloc1 indicates whether this assist completed the mark
+// phase by setting gp.param to non-nil. This can't be communicated on
+// the stack since it may move.
+//
+//go:systemstack
+func gcAssistAlloc1(gp *g, scanWork int64) {
+ // Clear the flag indicating that this assist completed the
+ // mark phase.
+ gp.param = nil
+
+ if atomic.Load(&gcBlackenEnabled) == 0 {
+ // The gcBlackenEnabled check in malloc races with the
+ // store that clears it but an atomic check in every malloc
+ // would be a performance hit.
+ // Instead we recheck it here on the non-preemptable system
+ // stack to determine if we should perform an assist.
+
+ // GC is done, so ignore any remaining debt.
+ gp.gcAssistBytes = 0
+ return
+ }
+ // Track time spent in this assist. Since we're on the
+ // system stack, this is non-preemptible, so we can
+ // just measure start and end time.
+ //
+ // Limiter event tracking might be disabled if we end up here
+ // while on a mark worker.
+ startTime := nanotime()
+ trackLimiterEvent := gp.m.p.ptr().limiterEvent.start(limiterEventMarkAssist, startTime)
+
+ decnwait := atomic.Xadd(&work.nwait, -1)
+ if decnwait == work.nproc {
+ println("runtime: work.nwait =", decnwait, "work.nproc=", work.nproc)
+ throw("nwait > work.nprocs")
+ }
+
+ // gcDrainN requires the caller to be preemptible.
+ casGToWaiting(gp, _Grunning, waitReasonGCAssistMarking)
+
+ // drain own cached work first in the hopes that it
+ // will be more cache friendly.
+ gcw := &getg().m.p.ptr().gcw
+ workDone := gcDrainN(gcw, scanWork)
+
+ casgstatus(gp, _Gwaiting, _Grunning)
+
+ // Record that we did this much scan work.
+ //
+ // Back out the number of bytes of assist credit that
+ // this scan work counts for. The "1+" is a poor man's
+ // round-up, to ensure this adds credit even if
+ // assistBytesPerWork is very low.
+ assistBytesPerWork := gcController.assistBytesPerWork.Load()
+ gp.gcAssistBytes += 1 + int64(assistBytesPerWork*float64(workDone))
+
+ // If this is the last worker and we ran out of work,
+ // signal a completion point.
+ incnwait := atomic.Xadd(&work.nwait, +1)
+ if incnwait > work.nproc {
+ println("runtime: work.nwait=", incnwait,
+ "work.nproc=", work.nproc)
+ throw("work.nwait > work.nproc")
+ }
+
+ if incnwait == work.nproc && !gcMarkWorkAvailable(nil) {
+ // This has reached a background completion point. Set
+ // gp.param to a non-nil value to indicate this. It
+ // doesn't matter what we set it to (it just has to be
+ // a valid pointer).
+ gp.param = unsafe.Pointer(gp)
+ }
+ now := nanotime()
+ duration := now - startTime
+ pp := gp.m.p.ptr()
+ pp.gcAssistTime += duration
+ if trackLimiterEvent {
+ pp.limiterEvent.stop(limiterEventMarkAssist, now)
+ }
+ if pp.gcAssistTime > gcAssistTimeSlack {
+ gcController.assistTime.Add(pp.gcAssistTime)
+ gcCPULimiter.update(now)
+ pp.gcAssistTime = 0
+ }
+}
+
+// gcWakeAllAssists wakes all currently blocked assists. This is used
+// at the end of a GC cycle. gcBlackenEnabled must be false to prevent
+// new assists from going to sleep after this point.
+func gcWakeAllAssists() {
+ lock(&work.assistQueue.lock)
+ list := work.assistQueue.q.popList()
+ injectglist(&list)
+ unlock(&work.assistQueue.lock)
+}
+
+// gcParkAssist puts the current goroutine on the assist queue and parks.
+//
+// gcParkAssist reports whether the assist is now satisfied. If it
+// returns false, the caller must retry the assist.
+func gcParkAssist() bool {
+ lock(&work.assistQueue.lock)
+ // If the GC cycle finished while we were getting the lock,
+ // exit the assist. The cycle can't finish while we hold the
+ // lock.
+ if atomic.Load(&gcBlackenEnabled) == 0 {
+ unlock(&work.assistQueue.lock)
+ return true
+ }
+
+ gp := getg()
+ oldList := work.assistQueue.q
+ work.assistQueue.q.pushBack(gp)
+
+ // Recheck for background credit now that this G is in
+ // the queue, but can still back out. This avoids a
+ // race in case background marking has flushed more
+ // credit since we checked above.
+ if gcController.bgScanCredit.Load() > 0 {
+ work.assistQueue.q = oldList
+ if oldList.tail != 0 {
+ oldList.tail.ptr().schedlink.set(nil)
+ }
+ unlock(&work.assistQueue.lock)
+ return false
+ }
+ // Park.
+ goparkunlock(&work.assistQueue.lock, waitReasonGCAssistWait, traceBlockGCMarkAssist, 2)
+ return true
+}
+
+// gcFlushBgCredit flushes scanWork units of background scan work
+// credit. This first satisfies blocked assists on the
+// work.assistQueue and then flushes any remaining credit to
+// gcController.bgScanCredit.
+//
+// Write barriers are disallowed because this is used by gcDrain after
+// it has ensured that all work is drained and this must preserve that
+// condition.
+//
+//go:nowritebarrierrec
+func gcFlushBgCredit(scanWork int64) {
+ if work.assistQueue.q.empty() {
+ // Fast path; there are no blocked assists. There's a
+ // small window here where an assist may add itself to
+ // the blocked queue and park. If that happens, we'll
+ // just get it on the next flush.
+ gcController.bgScanCredit.Add(scanWork)
+ return
+ }
+
+ assistBytesPerWork := gcController.assistBytesPerWork.Load()
+ scanBytes := int64(float64(scanWork) * assistBytesPerWork)
+
+ lock(&work.assistQueue.lock)
+ for !work.assistQueue.q.empty() && scanBytes > 0 {
+ gp := work.assistQueue.q.pop()
+ // Note that gp.gcAssistBytes is negative because gp
+ // is in debt. Think carefully about the signs below.
+ if scanBytes+gp.gcAssistBytes >= 0 {
+ // Satisfy this entire assist debt.
+ scanBytes += gp.gcAssistBytes
+ gp.gcAssistBytes = 0
+ // It's important that we *not* put gp in
+ // runnext. Otherwise, it's possible for user
+ // code to exploit the GC worker's high
+ // scheduler priority to get itself always run
+ // before other goroutines and always in the
+ // fresh quantum started by GC.
+ ready(gp, 0, false)
+ } else {
+ // Partially satisfy this assist.
+ gp.gcAssistBytes += scanBytes
+ scanBytes = 0
+ // As a heuristic, we move this assist to the
+ // back of the queue so that large assists
+ // can't clog up the assist queue and
+ // substantially delay small assists.
+ work.assistQueue.q.pushBack(gp)
+ break
+ }
+ }
+
+ if scanBytes > 0 {
+ // Convert from scan bytes back to work.
+ assistWorkPerByte := gcController.assistWorkPerByte.Load()
+ scanWork = int64(float64(scanBytes) * assistWorkPerByte)
+ gcController.bgScanCredit.Add(scanWork)
+ }
+ unlock(&work.assistQueue.lock)
+}
+
+// scanstack scans gp's stack, greying all pointers found on the stack.
+//
+// Returns the amount of scan work performed, but doesn't update
+// gcController.stackScanWork or flush any credit. Any background credit produced
+// by this function should be flushed by its caller. scanstack itself can't
+// safely flush because it may result in trying to wake up a goroutine that
+// was just scanned, resulting in a self-deadlock.
+//
+// scanstack will also shrink the stack if it is safe to do so. If it
+// is not, it schedules a stack shrink for the next synchronous safe
+// point.
+//
+// scanstack is marked go:systemstack because it must not be preempted
+// while using a workbuf.
+//
+//go:nowritebarrier
+//go:systemstack
+func scanstack(gp *g, gcw *gcWork) int64 {
+ if readgstatus(gp)&_Gscan == 0 {
+ print("runtime:scanstack: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", hex(readgstatus(gp)), "\n")
+ throw("scanstack - bad status")
+ }
+
+ switch readgstatus(gp) &^ _Gscan {
+ default:
+ print("runtime: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n")
+ throw("mark - bad status")
+ case _Gdead:
+ return 0
+ case _Grunning:
+ print("runtime: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n")
+ throw("scanstack: goroutine not stopped")
+ case _Grunnable, _Gsyscall, _Gwaiting:
+ // ok
+ }
+
+ if gp == getg() {
+ throw("can't scan our own stack")
+ }
+
+ // scannedSize is the amount of work we'll be reporting.
+ //
+ // It is less than the allocated size (which is hi-lo).
+ var sp uintptr
+ if gp.syscallsp != 0 {
+ sp = gp.syscallsp // If in a system call this is the stack pointer (gp.sched.sp can be 0 in this case on Windows).
+ } else {
+ sp = gp.sched.sp
+ }
+ scannedSize := gp.stack.hi - sp
+
+ // Keep statistics for initial stack size calculation.
+ // Note that this accumulates the scanned size, not the allocated size.
+ p := getg().m.p.ptr()
+ p.scannedStackSize += uint64(scannedSize)
+ p.scannedStacks++
+
+ if isShrinkStackSafe(gp) {
+ // Shrink the stack if not much of it is being used.
+ shrinkstack(gp)
+ } else {
+ // Otherwise, shrink the stack at the next sync safe point.
+ gp.preemptShrink = true
+ }
+
+ var state stackScanState
+ state.stack = gp.stack
+
+ if stackTraceDebug {
+ println("stack trace goroutine", gp.goid)
+ }
+
+ if debugScanConservative && gp.asyncSafePoint {
+ print("scanning async preempted goroutine ", gp.goid, " stack [", hex(gp.stack.lo), ",", hex(gp.stack.hi), ")\n")
+ }
+
+ // Scan the saved context register. This is effectively a live
+ // register that gets moved back and forth between the
+ // register and sched.ctxt without a write barrier.
+ if gp.sched.ctxt != nil {
+ scanblock(uintptr(unsafe.Pointer(&gp.sched.ctxt)), goarch.PtrSize, &oneptrmask[0], gcw, &state)
+ }
+
+ // Scan the stack. Accumulate a list of stack objects.
+ var u unwinder
+ for u.init(gp, 0); u.valid(); u.next() {
+ scanframeworker(&u.frame, &state, gcw)
+ }
+
+ // Find additional pointers that point into the stack from the heap.
+ // Currently this includes defers and panics. See also function copystack.
+
+ // Find and trace other pointers in defer records.
+ for d := gp._defer; d != nil; d = d.link {
+ if d.fn != nil {
+ // Scan the func value, which could be a stack allocated closure.
+ // See issue 30453.
+ scanblock(uintptr(unsafe.Pointer(&d.fn)), goarch.PtrSize, &oneptrmask[0], gcw, &state)
+ }
+ if d.link != nil {
+ // The link field of a stack-allocated defer record might point
+ // to a heap-allocated defer record. Keep that heap record live.
+ scanblock(uintptr(unsafe.Pointer(&d.link)), goarch.PtrSize, &oneptrmask[0], gcw, &state)
+ }
+ // Retain defers records themselves.
+ // Defer records might not be reachable from the G through regular heap
+ // tracing because the defer linked list might weave between the stack and the heap.
+ if d.heap {
+ scanblock(uintptr(unsafe.Pointer(&d)), goarch.PtrSize, &oneptrmask[0], gcw, &state)
+ }
+ }
+ if gp._panic != nil {
+ // Panics are always stack allocated.
+ state.putPtr(uintptr(unsafe.Pointer(gp._panic)), false)
+ }
+
+ // Find and scan all reachable stack objects.
+ //
+ // The state's pointer queue prioritizes precise pointers over
+ // conservative pointers so that we'll prefer scanning stack
+ // objects precisely.
+ state.buildIndex()
+ for {
+ p, conservative := state.getPtr()
+ if p == 0 {
+ break
+ }
+ obj := state.findObject(p)
+ if obj == nil {
+ continue
+ }
+ r := obj.r
+ if r == nil {
+ // We've already scanned this object.
+ continue
+ }
+ obj.setRecord(nil) // Don't scan it again.
+ if stackTraceDebug {
+ printlock()
+ print(" live stkobj at", hex(state.stack.lo+uintptr(obj.off)), "of size", obj.size)
+ if conservative {
+ print(" (conservative)")
+ }
+ println()
+ printunlock()
+ }
+ gcdata := r.gcdata()
+ var s *mspan
+ if r.useGCProg() {
+ // This path is pretty unlikely, an object large enough
+ // to have a GC program allocated on the stack.
+ // We need some space to unpack the program into a straight
+ // bitmask, which we allocate/free here.
+ // TODO: it would be nice if there were a way to run a GC
+ // program without having to store all its bits. We'd have
+ // to change from a Lempel-Ziv style program to something else.
+ // Or we can forbid putting objects on stacks if they require
+ // a gc program (see issue 27447).
+ s = materializeGCProg(r.ptrdata(), gcdata)
+ gcdata = (*byte)(unsafe.Pointer(s.startAddr))
+ }
+
+ b := state.stack.lo + uintptr(obj.off)
+ if conservative {
+ scanConservative(b, r.ptrdata(), gcdata, gcw, &state)
+ } else {
+ scanblock(b, r.ptrdata(), gcdata, gcw, &state)
+ }
+
+ if s != nil {
+ dematerializeGCProg(s)
+ }
+ }
+
+ // Deallocate object buffers.
+ // (Pointer buffers were all deallocated in the loop above.)
+ for state.head != nil {
+ x := state.head
+ state.head = x.next
+ if stackTraceDebug {
+ for i := 0; i < x.nobj; i++ {
+ obj := &x.obj[i]
+ if obj.r == nil { // reachable
+ continue
+ }
+ println(" dead stkobj at", hex(gp.stack.lo+uintptr(obj.off)), "of size", obj.r.size)
+ // Note: not necessarily really dead - only reachable-from-ptr dead.
+ }
+ }
+ x.nobj = 0
+ putempty((*workbuf)(unsafe.Pointer(x)))
+ }
+ if state.buf != nil || state.cbuf != nil || state.freeBuf != nil {
+ throw("remaining pointer buffers")
+ }
+ return int64(scannedSize)
+}
+
+// Scan a stack frame: local variables and function arguments/results.
+//
+//go:nowritebarrier
+func scanframeworker(frame *stkframe, state *stackScanState, gcw *gcWork) {
+ if _DebugGC > 1 && frame.continpc != 0 {
+ print("scanframe ", funcname(frame.fn), "\n")
+ }
+
+ isAsyncPreempt := frame.fn.valid() && frame.fn.funcID == abi.FuncID_asyncPreempt
+ isDebugCall := frame.fn.valid() && frame.fn.funcID == abi.FuncID_debugCallV2
+ if state.conservative || isAsyncPreempt || isDebugCall {
+ if debugScanConservative {
+ println("conservatively scanning function", funcname(frame.fn), "at PC", hex(frame.continpc))
+ }
+
+ // Conservatively scan the frame. Unlike the precise
+ // case, this includes the outgoing argument space
+ // since we may have stopped while this function was
+ // setting up a call.
+ //
+ // TODO: We could narrow this down if the compiler
+ // produced a single map per function of stack slots
+ // and registers that ever contain a pointer.
+ if frame.varp != 0 {
+ size := frame.varp - frame.sp
+ if size > 0 {
+ scanConservative(frame.sp, size, nil, gcw, state)
+ }
+ }
+
+ // Scan arguments to this frame.
+ if n := frame.argBytes(); n != 0 {
+ // TODO: We could pass the entry argument map
+ // to narrow this down further.
+ scanConservative(frame.argp, n, nil, gcw, state)
+ }
+
+ if isAsyncPreempt || isDebugCall {
+ // This function's frame contained the
+ // registers for the asynchronously stopped
+ // parent frame. Scan the parent
+ // conservatively.
+ state.conservative = true
+ } else {
+ // We only wanted to scan those two frames
+ // conservatively. Clear the flag for future
+ // frames.
+ state.conservative = false
+ }
+ return
+ }
+
+ locals, args, objs := frame.getStackMap(&state.cache, false)
+
+ // Scan local variables if stack frame has been allocated.
+ if locals.n > 0 {
+ size := uintptr(locals.n) * goarch.PtrSize
+ scanblock(frame.varp-size, size, locals.bytedata, gcw, state)
+ }
+
+ // Scan arguments.
+ if args.n > 0 {
+ scanblock(frame.argp, uintptr(args.n)*goarch.PtrSize, args.bytedata, gcw, state)
+ }
+
+ // Add all stack objects to the stack object list.
+ if frame.varp != 0 {
+ // varp is 0 for defers, where there are no locals.
+ // In that case, there can't be a pointer to its args, either.
+ // (And all args would be scanned above anyway.)
+ for i := range objs {
+ obj := &objs[i]
+ off := obj.off
+ base := frame.varp // locals base pointer
+ if off >= 0 {
+ base = frame.argp // arguments and return values base pointer
+ }
+ ptr := base + uintptr(off)
+ if ptr < frame.sp {
+ // object hasn't been allocated in the frame yet.
+ continue
+ }
+ if stackTraceDebug {
+ println("stkobj at", hex(ptr), "of size", obj.size)
+ }
+ state.addObject(ptr, obj)
+ }
+ }
+}
+
+type gcDrainFlags int
+
+const (
+ gcDrainUntilPreempt gcDrainFlags = 1 << iota
+ gcDrainFlushBgCredit
+ gcDrainIdle
+ gcDrainFractional
+)
+
+// gcDrain scans roots and objects in work buffers, blackening grey
+// objects until it is unable to get more work. It may return before
+// GC is done; it's the caller's responsibility to balance work from
+// other Ps.
+//
+// If flags&gcDrainUntilPreempt != 0, gcDrain returns when g.preempt
+// is set.
+//
+// If flags&gcDrainIdle != 0, gcDrain returns when there is other work
+// to do.
+//
+// If flags&gcDrainFractional != 0, gcDrain self-preempts when
+// pollFractionalWorkerExit() returns true. This implies
+// gcDrainNoBlock.
+//
+// If flags&gcDrainFlushBgCredit != 0, gcDrain flushes scan work
+// credit to gcController.bgScanCredit every gcCreditSlack units of
+// scan work.
+//
+// gcDrain will always return if there is a pending STW.
+//
+//go:nowritebarrier
+func gcDrain(gcw *gcWork, flags gcDrainFlags) {
+ if !writeBarrier.needed {
+ throw("gcDrain phase incorrect")
+ }
+
+ gp := getg().m.curg
+ preemptible := flags&gcDrainUntilPreempt != 0
+ flushBgCredit := flags&gcDrainFlushBgCredit != 0
+ idle := flags&gcDrainIdle != 0
+
+ initScanWork := gcw.heapScanWork
+
+ // checkWork is the scan work before performing the next
+ // self-preempt check.
+ checkWork := int64(1<<63 - 1)
+ var check func() bool
+ if flags&(gcDrainIdle|gcDrainFractional) != 0 {
+ checkWork = initScanWork + drainCheckThreshold
+ if idle {
+ check = pollWork
+ } else if flags&gcDrainFractional != 0 {
+ check = pollFractionalWorkerExit
+ }
+ }
+
+ // Drain root marking jobs.
+ if work.markrootNext < work.markrootJobs {
+ // Stop if we're preemptible or if someone wants to STW.
+ for !(gp.preempt && (preemptible || sched.gcwaiting.Load())) {
+ job := atomic.Xadd(&work.markrootNext, +1) - 1
+ if job >= work.markrootJobs {
+ break
+ }
+ markroot(gcw, job, flushBgCredit)
+ if check != nil && check() {
+ goto done
+ }
+ }
+ }
+
+ // Drain heap marking jobs.
+ // Stop if we're preemptible or if someone wants to STW.
+ for !(gp.preempt && (preemptible || sched.gcwaiting.Load())) {
+ // Try to keep work available on the global queue. We used to
+ // check if there were waiting workers, but it's better to
+ // just keep work available than to make workers wait. In the
+ // worst case, we'll do O(log(_WorkbufSize)) unnecessary
+ // balances.
+ if work.full == 0 {
+ gcw.balance()
+ }
+
+ b := gcw.tryGetFast()
+ if b == 0 {
+ b = gcw.tryGet()
+ if b == 0 {
+ // Flush the write barrier
+ // buffer; this may create
+ // more work.
+ wbBufFlush()
+ b = gcw.tryGet()
+ }
+ }
+ if b == 0 {
+ // Unable to get work.
+ break
+ }
+ scanobject(b, gcw)
+
+ // Flush background scan work credit to the global
+ // account if we've accumulated enough locally so
+ // mutator assists can draw on it.
+ if gcw.heapScanWork >= gcCreditSlack {
+ gcController.heapScanWork.Add(gcw.heapScanWork)
+ if flushBgCredit {
+ gcFlushBgCredit(gcw.heapScanWork - initScanWork)
+ initScanWork = 0
+ }
+ checkWork -= gcw.heapScanWork
+ gcw.heapScanWork = 0
+
+ if checkWork <= 0 {
+ checkWork += drainCheckThreshold
+ if check != nil && check() {
+ break
+ }
+ }
+ }
+ }
+
+done:
+ // Flush remaining scan work credit.
+ if gcw.heapScanWork > 0 {
+ gcController.heapScanWork.Add(gcw.heapScanWork)
+ if flushBgCredit {
+ gcFlushBgCredit(gcw.heapScanWork - initScanWork)
+ }
+ gcw.heapScanWork = 0
+ }
+}
+
+// gcDrainN blackens grey objects until it has performed roughly
+// scanWork units of scan work or the G is preempted. This is
+// best-effort, so it may perform less work if it fails to get a work
+// buffer. Otherwise, it will perform at least n units of work, but
+// may perform more because scanning is always done in whole object
+// increments. It returns the amount of scan work performed.
+//
+// The caller goroutine must be in a preemptible state (e.g.,
+// _Gwaiting) to prevent deadlocks during stack scanning. As a
+// consequence, this must be called on the system stack.
+//
+//go:nowritebarrier
+//go:systemstack
+func gcDrainN(gcw *gcWork, scanWork int64) int64 {
+ if !writeBarrier.needed {
+ throw("gcDrainN phase incorrect")
+ }
+
+ // There may already be scan work on the gcw, which we don't
+ // want to claim was done by this call.
+ workFlushed := -gcw.heapScanWork
+
+ // In addition to backing out because of a preemption, back out
+ // if the GC CPU limiter is enabled.
+ gp := getg().m.curg
+ for !gp.preempt && !gcCPULimiter.limiting() && workFlushed+gcw.heapScanWork < scanWork {
+ // See gcDrain comment.
+ if work.full == 0 {
+ gcw.balance()
+ }
+
+ b := gcw.tryGetFast()
+ if b == 0 {
+ b = gcw.tryGet()
+ if b == 0 {
+ // Flush the write barrier buffer;
+ // this may create more work.
+ wbBufFlush()
+ b = gcw.tryGet()
+ }
+ }
+
+ if b == 0 {
+ // Try to do a root job.
+ if work.markrootNext < work.markrootJobs {
+ job := atomic.Xadd(&work.markrootNext, +1) - 1
+ if job < work.markrootJobs {
+ workFlushed += markroot(gcw, job, false)
+ continue
+ }
+ }
+ // No heap or root jobs.
+ break
+ }
+
+ scanobject(b, gcw)
+
+ // Flush background scan work credit.
+ if gcw.heapScanWork >= gcCreditSlack {
+ gcController.heapScanWork.Add(gcw.heapScanWork)
+ workFlushed += gcw.heapScanWork
+ gcw.heapScanWork = 0
+ }
+ }
+
+ // Unlike gcDrain, there's no need to flush remaining work
+ // here because this never flushes to bgScanCredit and
+ // gcw.dispose will flush any remaining work to scanWork.
+
+ return workFlushed + gcw.heapScanWork
+}
+
+// scanblock scans b as scanobject would, but using an explicit
+// pointer bitmap instead of the heap bitmap.
+//
+// This is used to scan non-heap roots, so it does not update
+// gcw.bytesMarked or gcw.heapScanWork.
+//
+// If stk != nil, possible stack pointers are also reported to stk.putPtr.
+//
+//go:nowritebarrier
+func scanblock(b0, n0 uintptr, ptrmask *uint8, gcw *gcWork, stk *stackScanState) {
+ // Use local copies of original parameters, so that a stack trace
+ // due to one of the throws below shows the original block
+ // base and extent.
+ b := b0
+ n := n0
+
+ for i := uintptr(0); i < n; {
+ // Find bits for the next word.
+ bits := uint32(*addb(ptrmask, i/(goarch.PtrSize*8)))
+ if bits == 0 {
+ i += goarch.PtrSize * 8
+ continue
+ }
+ for j := 0; j < 8 && i < n; j++ {
+ if bits&1 != 0 {
+ // Same work as in scanobject; see comments there.
+ p := *(*uintptr)(unsafe.Pointer(b + i))
+ if p != 0 {
+ if obj, span, objIndex := findObject(p, b, i); obj != 0 {
+ greyobject(obj, b, i, span, gcw, objIndex)
+ } else if stk != nil && p >= stk.stack.lo && p < stk.stack.hi {
+ stk.putPtr(p, false)
+ }
+ }
+ }
+ bits >>= 1
+ i += goarch.PtrSize
+ }
+ }
+}
+
+// scanobject scans the object starting at b, adding pointers to gcw.
+// b must point to the beginning of a heap object or an oblet.
+// scanobject consults the GC bitmap for the pointer mask and the
+// spans for the size of the object.
+//
+//go:nowritebarrier
+func scanobject(b uintptr, gcw *gcWork) {
+ // Prefetch object before we scan it.
+ //
+ // This will overlap fetching the beginning of the object with initial
+ // setup before we start scanning the object.
+ sys.Prefetch(b)
+
+ // Find the bits for b and the size of the object at b.
+ //
+ // b is either the beginning of an object, in which case this
+ // is the size of the object to scan, or it points to an
+ // oblet, in which case we compute the size to scan below.
+ s := spanOfUnchecked(b)
+ n := s.elemsize
+ if n == 0 {
+ throw("scanobject n == 0")
+ }
+ if s.spanclass.noscan() {
+ // Correctness-wise this is ok, but it's inefficient
+ // if noscan objects reach here.
+ throw("scanobject of a noscan object")
+ }
+
+ if n > maxObletBytes {
+ // Large object. Break into oblets for better
+ // parallelism and lower latency.
+ if b == s.base() {
+ // Enqueue the other oblets to scan later.
+ // Some oblets may be in b's scalar tail, but
+ // these will be marked as "no more pointers",
+ // so we'll drop out immediately when we go to
+ // scan those.
+ for oblet := b + maxObletBytes; oblet < s.base()+s.elemsize; oblet += maxObletBytes {
+ if !gcw.putFast(oblet) {
+ gcw.put(oblet)
+ }
+ }
+ }
+
+ // Compute the size of the oblet. Since this object
+ // must be a large object, s.base() is the beginning
+ // of the object.
+ n = s.base() + s.elemsize - b
+ if n > maxObletBytes {
+ n = maxObletBytes
+ }
+ }
+
+ hbits := heapBitsForAddr(b, n)
+ var scanSize uintptr
+ for {
+ var addr uintptr
+ if hbits, addr = hbits.nextFast(); addr == 0 {
+ if hbits, addr = hbits.next(); addr == 0 {
+ break
+ }
+ }
+
+ // Keep track of farthest pointer we found, so we can
+ // update heapScanWork. TODO: is there a better metric,
+ // now that we can skip scalar portions pretty efficiently?
+ scanSize = addr - b + goarch.PtrSize
+
+ // Work here is duplicated in scanblock and above.
+ // If you make changes here, make changes there too.
+ obj := *(*uintptr)(unsafe.Pointer(addr))
+
+ // At this point we have extracted the next potential pointer.
+ // Quickly filter out nil and pointers back to the current object.
+ if obj != 0 && obj-b >= n {
+ // Test if obj points into the Go heap and, if so,
+ // mark the object.
+ //
+ // Note that it's possible for findObject to
+ // fail if obj points to a just-allocated heap
+ // object because of a race with growing the
+ // heap. In this case, we know the object was
+ // just allocated and hence will be marked by
+ // allocation itself.
+ if obj, span, objIndex := findObject(obj, b, addr-b); obj != 0 {
+ greyobject(obj, b, addr-b, span, gcw, objIndex)
+ }
+ }
+ }
+ gcw.bytesMarked += uint64(n)
+ gcw.heapScanWork += int64(scanSize)
+}
+
+// scanConservative scans block [b, b+n) conservatively, treating any
+// pointer-like value in the block as a pointer.
+//
+// If ptrmask != nil, only words that are marked in ptrmask are
+// considered as potential pointers.
+//
+// If state != nil, it's assumed that [b, b+n) is a block in the stack
+// and may contain pointers to stack objects.
+func scanConservative(b, n uintptr, ptrmask *uint8, gcw *gcWork, state *stackScanState) {
+ if debugScanConservative {
+ printlock()
+ print("conservatively scanning [", hex(b), ",", hex(b+n), ")\n")
+ hexdumpWords(b, b+n, func(p uintptr) byte {
+ if ptrmask != nil {
+ word := (p - b) / goarch.PtrSize
+ bits := *addb(ptrmask, word/8)
+ if (bits>>(word%8))&1 == 0 {
+ return '$'
+ }
+ }
+
+ val := *(*uintptr)(unsafe.Pointer(p))
+ if state != nil && state.stack.lo <= val && val < state.stack.hi {
+ return '@'
+ }
+
+ span := spanOfHeap(val)
+ if span == nil {
+ return ' '
+ }
+ idx := span.objIndex(val)
+ if span.isFree(idx) {
+ return ' '
+ }
+ return '*'
+ })
+ printunlock()
+ }
+
+ for i := uintptr(0); i < n; i += goarch.PtrSize {
+ if ptrmask != nil {
+ word := i / goarch.PtrSize
+ bits := *addb(ptrmask, word/8)
+ if bits == 0 {
+ // Skip 8 words (the loop increment will do the 8th)
+ //
+ // This must be the first time we've
+ // seen this word of ptrmask, so i
+ // must be 8-word-aligned, but check
+ // our reasoning just in case.
+ if i%(goarch.PtrSize*8) != 0 {
+ throw("misaligned mask")
+ }
+ i += goarch.PtrSize*8 - goarch.PtrSize
+ continue
+ }
+ if (bits>>(word%8))&1 == 0 {
+ continue
+ }
+ }
+
+ val := *(*uintptr)(unsafe.Pointer(b + i))
+
+ // Check if val points into the stack.
+ if state != nil && state.stack.lo <= val && val < state.stack.hi {
+ // val may point to a stack object. This
+ // object may be dead from last cycle and
+ // hence may contain pointers to unallocated
+ // objects, but unlike heap objects we can't
+ // tell if it's already dead. Hence, if all
+ // pointers to this object are from
+ // conservative scanning, we have to scan it
+ // defensively, too.
+ state.putPtr(val, true)
+ continue
+ }
+
+ // Check if val points to a heap span.
+ span := spanOfHeap(val)
+ if span == nil {
+ continue
+ }
+
+ // Check if val points to an allocated object.
+ idx := span.objIndex(val)
+ if span.isFree(idx) {
+ continue
+ }
+
+ // val points to an allocated object. Mark it.
+ obj := span.base() + idx*span.elemsize
+ greyobject(obj, b, i, span, gcw, idx)
+ }
+}
+
+// Shade the object if it isn't already.
+// The object is not nil and known to be in the heap.
+// Preemption must be disabled.
+//
+//go:nowritebarrier
+func shade(b uintptr) {
+ if obj, span, objIndex := findObject(b, 0, 0); obj != 0 {
+ gcw := &getg().m.p.ptr().gcw
+ greyobject(obj, 0, 0, span, gcw, objIndex)
+ }
+}
+
+// obj is the start of an object with mark mbits.
+// If it isn't already marked, mark it and enqueue into gcw.
+// base and off are for debugging only and could be removed.
+//
+// See also wbBufFlush1, which partially duplicates this logic.
+//
+//go:nowritebarrierrec
+func greyobject(obj, base, off uintptr, span *mspan, gcw *gcWork, objIndex uintptr) {
+ // obj should be start of allocation, and so must be at least pointer-aligned.
+ if obj&(goarch.PtrSize-1) != 0 {
+ throw("greyobject: obj not pointer-aligned")
+ }
+ mbits := span.markBitsForIndex(objIndex)
+
+ if useCheckmark {
+ if setCheckmark(obj, base, off, mbits) {
+ // Already marked.
+ return
+ }
+ } else {
+ if debug.gccheckmark > 0 && span.isFree(objIndex) {
+ print("runtime: marking free object ", hex(obj), " found at *(", hex(base), "+", hex(off), ")\n")
+ gcDumpObject("base", base, off)
+ gcDumpObject("obj", obj, ^uintptr(0))
+ getg().m.traceback = 2
+ throw("marking free object")
+ }
+
+ // If marked we have nothing to do.
+ if mbits.isMarked() {
+ return
+ }
+ mbits.setMarked()
+
+ // Mark span.
+ arena, pageIdx, pageMask := pageIndexOf(span.base())
+ if arena.pageMarks[pageIdx]&pageMask == 0 {
+ atomic.Or8(&arena.pageMarks[pageIdx], pageMask)
+ }
+
+ // If this is a noscan object, fast-track it to black
+ // instead of greying it.
+ if span.spanclass.noscan() {
+ gcw.bytesMarked += uint64(span.elemsize)
+ return
+ }
+ }
+
+ // We're adding obj to P's local workbuf, so it's likely
+ // this object will be processed soon by the same P.
+ // Even if the workbuf gets flushed, there will likely still be
+ // some benefit on platforms with inclusive shared caches.
+ sys.Prefetch(obj)
+ // Queue the obj for scanning.
+ if !gcw.putFast(obj) {
+ gcw.put(obj)
+ }
+}
+
+// gcDumpObject dumps the contents of obj for debugging and marks the
+// field at byte offset off in obj.
+func gcDumpObject(label string, obj, off uintptr) {
+ s := spanOf(obj)
+ print(label, "=", hex(obj))
+ if s == nil {
+ print(" s=nil\n")
+ return
+ }
+ print(" s.base()=", hex(s.base()), " s.limit=", hex(s.limit), " s.spanclass=", s.spanclass, " s.elemsize=", s.elemsize, " s.state=")
+ if state := s.state.get(); 0 <= state && int(state) < len(mSpanStateNames) {
+ print(mSpanStateNames[state], "\n")
+ } else {
+ print("unknown(", state, ")\n")
+ }
+
+ skipped := false
+ size := s.elemsize
+ if s.state.get() == mSpanManual && size == 0 {
+ // We're printing something from a stack frame. We
+ // don't know how big it is, so just show up to an
+ // including off.
+ size = off + goarch.PtrSize
+ }
+ for i := uintptr(0); i < size; i += goarch.PtrSize {
+ // For big objects, just print the beginning (because
+ // that usually hints at the object's type) and the
+ // fields around off.
+ if !(i < 128*goarch.PtrSize || off-16*goarch.PtrSize < i && i < off+16*goarch.PtrSize) {
+ skipped = true
+ continue
+ }
+ if skipped {
+ print(" ...\n")
+ skipped = false
+ }
+ print(" *(", label, "+", i, ") = ", hex(*(*uintptr)(unsafe.Pointer(obj + i))))
+ if i == off {
+ print(" <==")
+ }
+ print("\n")
+ }
+ if skipped {
+ print(" ...\n")
+ }
+}
+
+// gcmarknewobject marks a newly allocated object black. obj must
+// not contain any non-nil pointers.
+//
+// This is nosplit so it can manipulate a gcWork without preemption.
+//
+//go:nowritebarrier
+//go:nosplit
+func gcmarknewobject(span *mspan, obj, size uintptr) {
+ if useCheckmark { // The world should be stopped so this should not happen.
+ throw("gcmarknewobject called while doing checkmark")
+ }
+
+ // Mark object.
+ objIndex := span.objIndex(obj)
+ span.markBitsForIndex(objIndex).setMarked()
+
+ // Mark span.
+ arena, pageIdx, pageMask := pageIndexOf(span.base())
+ if arena.pageMarks[pageIdx]&pageMask == 0 {
+ atomic.Or8(&arena.pageMarks[pageIdx], pageMask)
+ }
+
+ gcw := &getg().m.p.ptr().gcw
+ gcw.bytesMarked += uint64(size)
+}
+
+// gcMarkTinyAllocs greys all active tiny alloc blocks.
+//
+// The world must be stopped.
+func gcMarkTinyAllocs() {
+ assertWorldStopped()
+
+ for _, p := range allp {
+ c := p.mcache
+ if c == nil || c.tiny == 0 {
+ continue
+ }
+ _, span, objIndex := findObject(c.tiny, 0, 0)
+ gcw := &p.gcw
+ greyobject(c.tiny, 0, 0, span, gcw, objIndex)
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mgcpacer.go b/contrib/go/_std_1.21/src/runtime/mgcpacer.go
new file mode 100644
index 0000000000..cd56dc427c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mgcpacer.go
@@ -0,0 +1,1445 @@
+// 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 runtime
+
+import (
+ "internal/cpu"
+ "internal/goexperiment"
+ "runtime/internal/atomic"
+ _ "unsafe" // for go:linkname
+
+)
+
+const (
+ // gcGoalUtilization is the goal CPU utilization for
+ // marking as a fraction of GOMAXPROCS.
+ //
+ // Increasing the goal utilization will shorten GC cycles as the GC
+ // has more resources behind it, lessening costs from the write barrier,
+ // but comes at the cost of increasing mutator latency.
+ gcGoalUtilization = gcBackgroundUtilization
+
+ // gcBackgroundUtilization is the fixed CPU utilization for background
+ // marking. It must be <= gcGoalUtilization. The difference between
+ // gcGoalUtilization and gcBackgroundUtilization will be made up by
+ // mark assists. The scheduler will aim to use within 50% of this
+ // goal.
+ //
+ // As a general rule, there's little reason to set gcBackgroundUtilization
+ // < gcGoalUtilization. One reason might be in mostly idle applications,
+ // where goroutines are unlikely to assist at all, so the actual
+ // utilization will be lower than the goal. But this is moot point
+ // because the idle mark workers already soak up idle CPU resources.
+ // These two values are still kept separate however because they are
+ // distinct conceptually, and in previous iterations of the pacer the
+ // distinction was more important.
+ gcBackgroundUtilization = 0.25
+
+ // gcCreditSlack is the amount of scan work credit that can
+ // accumulate locally before updating gcController.heapScanWork and,
+ // optionally, gcController.bgScanCredit. Lower values give a more
+ // accurate assist ratio and make it more likely that assists will
+ // successfully steal background credit. Higher values reduce memory
+ // contention.
+ gcCreditSlack = 2000
+
+ // gcAssistTimeSlack is the nanoseconds of mutator assist time that
+ // can accumulate on a P before updating gcController.assistTime.
+ gcAssistTimeSlack = 5000
+
+ // gcOverAssistWork determines how many extra units of scan work a GC
+ // assist does when an assist happens. This amortizes the cost of an
+ // assist by pre-paying for this many bytes of future allocations.
+ gcOverAssistWork = 64 << 10
+
+ // defaultHeapMinimum is the value of heapMinimum for GOGC==100.
+ defaultHeapMinimum = (goexperiment.HeapMinimum512KiBInt)*(512<<10) +
+ (1-goexperiment.HeapMinimum512KiBInt)*(4<<20)
+
+ // maxStackScanSlack is the bytes of stack space allocated or freed
+ // that can accumulate on a P before updating gcController.stackSize.
+ maxStackScanSlack = 8 << 10
+
+ // memoryLimitMinHeapGoalHeadroom is the minimum amount of headroom the
+ // pacer gives to the heap goal when operating in the memory-limited regime.
+ // That is, it'll reduce the heap goal by this many extra bytes off of the
+ // base calculation, at minimum.
+ memoryLimitMinHeapGoalHeadroom = 1 << 20
+
+ // memoryLimitHeapGoalHeadroomPercent is how headroom the memory-limit-based
+ // heap goal should have as a percent of the maximum possible heap goal allowed
+ // to maintain the memory limit.
+ memoryLimitHeapGoalHeadroomPercent = 3
+)
+
+// gcController implements the GC pacing controller that determines
+// when to trigger concurrent garbage collection and how much marking
+// work to do in mutator assists and background marking.
+//
+// It calculates the ratio between the allocation rate (in terms of CPU
+// time) and the GC scan throughput to determine the heap size at which to
+// trigger a GC cycle such that no GC assists are required to finish on time.
+// This algorithm thus optimizes GC CPU utilization to the dedicated background
+// mark utilization of 25% of GOMAXPROCS by minimizing GC assists.
+// GOMAXPROCS. The high-level design of this algorithm is documented
+// at https://github.com/golang/proposal/blob/master/design/44167-gc-pacer-redesign.md.
+// See https://golang.org/s/go15gcpacing for additional historical context.
+var gcController gcControllerState
+
+type gcControllerState struct {
+ // Initialized from GOGC. GOGC=off means no GC.
+ gcPercent atomic.Int32
+
+ // memoryLimit is the soft memory limit in bytes.
+ //
+ // Initialized from GOMEMLIMIT. GOMEMLIMIT=off is equivalent to MaxInt64
+ // which means no soft memory limit in practice.
+ //
+ // This is an int64 instead of a uint64 to more easily maintain parity with
+ // the SetMemoryLimit API, which sets a maximum at MaxInt64. This value
+ // should never be negative.
+ memoryLimit atomic.Int64
+
+ // heapMinimum is the minimum heap size at which to trigger GC.
+ // For small heaps, this overrides the usual GOGC*live set rule.
+ //
+ // When there is a very small live set but a lot of allocation, simply
+ // collecting when the heap reaches GOGC*live results in many GC
+ // cycles and high total per-GC overhead. This minimum amortizes this
+ // per-GC overhead while keeping the heap reasonably small.
+ //
+ // During initialization this is set to 4MB*GOGC/100. In the case of
+ // GOGC==0, this will set heapMinimum to 0, resulting in constant
+ // collection even when the heap size is small, which is useful for
+ // debugging.
+ heapMinimum uint64
+
+ // runway is the amount of runway in heap bytes allocated by the
+ // application that we want to give the GC once it starts.
+ //
+ // This is computed from consMark during mark termination.
+ runway atomic.Uint64
+
+ // consMark is the estimated per-CPU consMark ratio for the application.
+ //
+ // It represents the ratio between the application's allocation
+ // rate, as bytes allocated per CPU-time, and the GC's scan rate,
+ // as bytes scanned per CPU-time.
+ // The units of this ratio are (B / cpu-ns) / (B / cpu-ns).
+ //
+ // At a high level, this value is computed as the bytes of memory
+ // allocated (cons) per unit of scan work completed (mark) in a GC
+ // cycle, divided by the CPU time spent on each activity.
+ //
+ // Updated at the end of each GC cycle, in endCycle.
+ consMark float64
+
+ // lastConsMark is the computed cons/mark value for the previous 4 GC
+ // cycles. Note that this is *not* the last value of consMark, but the
+ // measured cons/mark value in endCycle.
+ lastConsMark [4]float64
+
+ // gcPercentHeapGoal is the goal heapLive for when next GC ends derived
+ // from gcPercent.
+ //
+ // Set to ^uint64(0) if gcPercent is disabled.
+ gcPercentHeapGoal atomic.Uint64
+
+ // sweepDistMinTrigger is the minimum trigger to ensure a minimum
+ // sweep distance.
+ //
+ // This bound is also special because it applies to both the trigger
+ // *and* the goal (all other trigger bounds must be based *on* the goal).
+ //
+ // It is computed ahead of time, at commit time. The theory is that,
+ // absent a sudden change to a parameter like gcPercent, the trigger
+ // will be chosen to always give the sweeper enough headroom. However,
+ // such a change might dramatically and suddenly move up the trigger,
+ // in which case we need to ensure the sweeper still has enough headroom.
+ sweepDistMinTrigger atomic.Uint64
+
+ // triggered is the point at which the current GC cycle actually triggered.
+ // Only valid during the mark phase of a GC cycle, otherwise set to ^uint64(0).
+ //
+ // Updated while the world is stopped.
+ triggered uint64
+
+ // lastHeapGoal is the value of heapGoal at the moment the last GC
+ // ended. Note that this is distinct from the last value heapGoal had,
+ // because it could change if e.g. gcPercent changes.
+ //
+ // Read and written with the world stopped or with mheap_.lock held.
+ lastHeapGoal uint64
+
+ // heapLive is the number of bytes considered live by the GC.
+ // That is: retained by the most recent GC plus allocated
+ // since then. heapLive ≤ memstats.totalAlloc-memstats.totalFree, since
+ // heapAlloc includes unmarked objects that have not yet been swept (and
+ // hence goes up as we allocate and down as we sweep) while heapLive
+ // excludes these objects (and hence only goes up between GCs).
+ //
+ // To reduce contention, this is updated only when obtaining a span
+ // from an mcentral and at this point it counts all of the unallocated
+ // slots in that span (which will be allocated before that mcache
+ // obtains another span from that mcentral). Hence, it slightly
+ // overestimates the "true" live heap size. It's better to overestimate
+ // than to underestimate because 1) this triggers the GC earlier than
+ // necessary rather than potentially too late and 2) this leads to a
+ // conservative GC rate rather than a GC rate that is potentially too
+ // low.
+ //
+ // Whenever this is updated, call traceHeapAlloc() and
+ // this gcControllerState's revise() method.
+ heapLive atomic.Uint64
+
+ // heapScan is the number of bytes of "scannable" heap. This is the
+ // live heap (as counted by heapLive), but omitting no-scan objects and
+ // no-scan tails of objects.
+ //
+ // This value is fixed at the start of a GC cycle. It represents the
+ // maximum scannable heap.
+ heapScan atomic.Uint64
+
+ // lastHeapScan is the number of bytes of heap that were scanned
+ // last GC cycle. It is the same as heapMarked, but only
+ // includes the "scannable" parts of objects.
+ //
+ // Updated when the world is stopped.
+ lastHeapScan uint64
+
+ // lastStackScan is the number of bytes of stack that were scanned
+ // last GC cycle.
+ lastStackScan atomic.Uint64
+
+ // maxStackScan is the amount of allocated goroutine stack space in
+ // use by goroutines.
+ //
+ // This number tracks allocated goroutine stack space rather than used
+ // goroutine stack space (i.e. what is actually scanned) because used
+ // goroutine stack space is much harder to measure cheaply. By using
+ // allocated space, we make an overestimate; this is OK, it's better
+ // to conservatively overcount than undercount.
+ maxStackScan atomic.Uint64
+
+ // globalsScan is the total amount of global variable space
+ // that is scannable.
+ globalsScan atomic.Uint64
+
+ // heapMarked is the number of bytes marked by the previous
+ // GC. After mark termination, heapLive == heapMarked, but
+ // unlike heapLive, heapMarked does not change until the
+ // next mark termination.
+ heapMarked uint64
+
+ // heapScanWork is the total heap scan work performed this cycle.
+ // stackScanWork is the total stack scan work performed this cycle.
+ // globalsScanWork is the total globals scan work performed this cycle.
+ //
+ // These are updated atomically during the cycle. Updates occur in
+ // bounded batches, since they are both written and read
+ // throughout the cycle. At the end of the cycle, heapScanWork is how
+ // much of the retained heap is scannable.
+ //
+ // Currently these are measured in bytes. For most uses, this is an
+ // opaque unit of work, but for estimation the definition is important.
+ //
+ // Note that stackScanWork includes only stack space scanned, not all
+ // of the allocated stack.
+ heapScanWork atomic.Int64
+ stackScanWork atomic.Int64
+ globalsScanWork atomic.Int64
+
+ // bgScanCredit is the scan work credit accumulated by the concurrent
+ // background scan. This credit is accumulated by the background scan
+ // and stolen by mutator assists. Updates occur in bounded batches,
+ // since it is both written and read throughout the cycle.
+ bgScanCredit atomic.Int64
+
+ // assistTime is the nanoseconds spent in mutator assists
+ // during this cycle. This is updated atomically, and must also
+ // be updated atomically even during a STW, because it is read
+ // by sysmon. Updates occur in bounded batches, since it is both
+ // written and read throughout the cycle.
+ assistTime atomic.Int64
+
+ // dedicatedMarkTime is the nanoseconds spent in dedicated mark workers
+ // during this cycle. This is updated at the end of the concurrent mark
+ // phase.
+ dedicatedMarkTime atomic.Int64
+
+ // fractionalMarkTime is the nanoseconds spent in the fractional mark
+ // worker during this cycle. This is updated throughout the cycle and
+ // will be up-to-date if the fractional mark worker is not currently
+ // running.
+ fractionalMarkTime atomic.Int64
+
+ // idleMarkTime is the nanoseconds spent in idle marking during this
+ // cycle. This is updated throughout the cycle.
+ idleMarkTime atomic.Int64
+
+ // markStartTime is the absolute start time in nanoseconds
+ // that assists and background mark workers started.
+ markStartTime int64
+
+ // dedicatedMarkWorkersNeeded is the number of dedicated mark workers
+ // that need to be started. This is computed at the beginning of each
+ // cycle and decremented as dedicated mark workers get started.
+ dedicatedMarkWorkersNeeded atomic.Int64
+
+ // idleMarkWorkers is two packed int32 values in a single uint64.
+ // These two values are always updated simultaneously.
+ //
+ // The bottom int32 is the current number of idle mark workers executing.
+ //
+ // The top int32 is the maximum number of idle mark workers allowed to
+ // execute concurrently. Normally, this number is just gomaxprocs. However,
+ // during periodic GC cycles it is set to 0 because the system is idle
+ // anyway; there's no need to go full blast on all of GOMAXPROCS.
+ //
+ // The maximum number of idle mark workers is used to prevent new workers
+ // from starting, but it is not a hard maximum. It is possible (but
+ // exceedingly rare) for the current number of idle mark workers to
+ // transiently exceed the maximum. This could happen if the maximum changes
+ // just after a GC ends, and an M with no P.
+ //
+ // Note that if we have no dedicated mark workers, we set this value to
+ // 1 in this case we only have fractional GC workers which aren't scheduled
+ // strictly enough to ensure GC progress. As a result, idle-priority mark
+ // workers are vital to GC progress in these situations.
+ //
+ // For example, consider a situation in which goroutines block on the GC
+ // (such as via runtime.GOMAXPROCS) and only fractional mark workers are
+ // scheduled (e.g. GOMAXPROCS=1). Without idle-priority mark workers, the
+ // last running M might skip scheduling a fractional mark worker if its
+ // utilization goal is met, such that once it goes to sleep (because there's
+ // nothing to do), there will be nothing else to spin up a new M for the
+ // fractional worker in the future, stalling GC progress and causing a
+ // deadlock. However, idle-priority workers will *always* run when there is
+ // nothing left to do, ensuring the GC makes progress.
+ //
+ // See github.com/golang/go/issues/44163 for more details.
+ idleMarkWorkers atomic.Uint64
+
+ // assistWorkPerByte is the ratio of scan work to allocated
+ // bytes that should be performed by mutator assists. This is
+ // computed at the beginning of each cycle and updated every
+ // time heapScan is updated.
+ assistWorkPerByte atomic.Float64
+
+ // assistBytesPerWork is 1/assistWorkPerByte.
+ //
+ // Note that because this is read and written independently
+ // from assistWorkPerByte users may notice a skew between
+ // the two values, and such a state should be safe.
+ assistBytesPerWork atomic.Float64
+
+ // fractionalUtilizationGoal is the fraction of wall clock
+ // time that should be spent in the fractional mark worker on
+ // each P that isn't running a dedicated worker.
+ //
+ // For example, if the utilization goal is 25% and there are
+ // no dedicated workers, this will be 0.25. If the goal is
+ // 25%, there is one dedicated worker, and GOMAXPROCS is 5,
+ // this will be 0.05 to make up the missing 5%.
+ //
+ // If this is zero, no fractional workers are needed.
+ fractionalUtilizationGoal float64
+
+ // These memory stats are effectively duplicates of fields from
+ // memstats.heapStats but are updated atomically or with the world
+ // stopped and don't provide the same consistency guarantees.
+ //
+ // Because the runtime is responsible for managing a memory limit, it's
+ // useful to couple these stats more tightly to the gcController, which
+ // is intimately connected to how that memory limit is maintained.
+ heapInUse sysMemStat // bytes in mSpanInUse spans
+ heapReleased sysMemStat // bytes released to the OS
+ heapFree sysMemStat // bytes not in any span, but not released to the OS
+ totalAlloc atomic.Uint64 // total bytes allocated
+ totalFree atomic.Uint64 // total bytes freed
+ mappedReady atomic.Uint64 // total virtual memory in the Ready state (see mem.go).
+
+ // test indicates that this is a test-only copy of gcControllerState.
+ test bool
+
+ _ cpu.CacheLinePad
+}
+
+func (c *gcControllerState) init(gcPercent int32, memoryLimit int64) {
+ c.heapMinimum = defaultHeapMinimum
+ c.triggered = ^uint64(0)
+ c.setGCPercent(gcPercent)
+ c.setMemoryLimit(memoryLimit)
+ c.commit(true) // No sweep phase in the first GC cycle.
+ // N.B. Don't bother calling traceHeapGoal. Tracing is never enabled at
+ // initialization time.
+ // N.B. No need to call revise; there's no GC enabled during
+ // initialization.
+}
+
+// startCycle resets the GC controller's state and computes estimates
+// for a new GC cycle. The caller must hold worldsema and the world
+// must be stopped.
+func (c *gcControllerState) startCycle(markStartTime int64, procs int, trigger gcTrigger) {
+ c.heapScanWork.Store(0)
+ c.stackScanWork.Store(0)
+ c.globalsScanWork.Store(0)
+ c.bgScanCredit.Store(0)
+ c.assistTime.Store(0)
+ c.dedicatedMarkTime.Store(0)
+ c.fractionalMarkTime.Store(0)
+ c.idleMarkTime.Store(0)
+ c.markStartTime = markStartTime
+ c.triggered = c.heapLive.Load()
+
+ // Compute the background mark utilization goal. In general,
+ // this may not come out exactly. We round the number of
+ // dedicated workers so that the utilization is closest to
+ // 25%. For small GOMAXPROCS, this would introduce too much
+ // error, so we add fractional workers in that case.
+ totalUtilizationGoal := float64(procs) * gcBackgroundUtilization
+ dedicatedMarkWorkersNeeded := int64(totalUtilizationGoal + 0.5)
+ utilError := float64(dedicatedMarkWorkersNeeded)/totalUtilizationGoal - 1
+ const maxUtilError = 0.3
+ if utilError < -maxUtilError || utilError > maxUtilError {
+ // Rounding put us more than 30% off our goal. With
+ // gcBackgroundUtilization of 25%, this happens for
+ // GOMAXPROCS<=3 or GOMAXPROCS=6. Enable fractional
+ // workers to compensate.
+ if float64(dedicatedMarkWorkersNeeded) > totalUtilizationGoal {
+ // Too many dedicated workers.
+ dedicatedMarkWorkersNeeded--
+ }
+ c.fractionalUtilizationGoal = (totalUtilizationGoal - float64(dedicatedMarkWorkersNeeded)) / float64(procs)
+ } else {
+ c.fractionalUtilizationGoal = 0
+ }
+
+ // In STW mode, we just want dedicated workers.
+ if debug.gcstoptheworld > 0 {
+ dedicatedMarkWorkersNeeded = int64(procs)
+ c.fractionalUtilizationGoal = 0
+ }
+
+ // Clear per-P state
+ for _, p := range allp {
+ p.gcAssistTime = 0
+ p.gcFractionalMarkTime = 0
+ }
+
+ if trigger.kind == gcTriggerTime {
+ // During a periodic GC cycle, reduce the number of idle mark workers
+ // required. However, we need at least one dedicated mark worker or
+ // idle GC worker to ensure GC progress in some scenarios (see comment
+ // on maxIdleMarkWorkers).
+ if dedicatedMarkWorkersNeeded > 0 {
+ c.setMaxIdleMarkWorkers(0)
+ } else {
+ // TODO(mknyszek): The fundamental reason why we need this is because
+ // we can't count on the fractional mark worker to get scheduled.
+ // Fix that by ensuring it gets scheduled according to its quota even
+ // if the rest of the application is idle.
+ c.setMaxIdleMarkWorkers(1)
+ }
+ } else {
+ // N.B. gomaxprocs and dedicatedMarkWorkersNeeded are guaranteed not to
+ // change during a GC cycle.
+ c.setMaxIdleMarkWorkers(int32(procs) - int32(dedicatedMarkWorkersNeeded))
+ }
+
+ // Compute initial values for controls that are updated
+ // throughout the cycle.
+ c.dedicatedMarkWorkersNeeded.Store(dedicatedMarkWorkersNeeded)
+ c.revise()
+
+ if debug.gcpacertrace > 0 {
+ heapGoal := c.heapGoal()
+ assistRatio := c.assistWorkPerByte.Load()
+ print("pacer: assist ratio=", assistRatio,
+ " (scan ", gcController.heapScan.Load()>>20, " MB in ",
+ work.initialHeapLive>>20, "->",
+ heapGoal>>20, " MB)",
+ " workers=", dedicatedMarkWorkersNeeded,
+ "+", c.fractionalUtilizationGoal, "\n")
+ }
+}
+
+// revise updates the assist ratio during the GC cycle to account for
+// improved estimates. This should be called whenever gcController.heapScan,
+// gcController.heapLive, or if any inputs to gcController.heapGoal are
+// updated. It is safe to call concurrently, but it may race with other
+// calls to revise.
+//
+// The result of this race is that the two assist ratio values may not line
+// up or may be stale. In practice this is OK because the assist ratio
+// moves slowly throughout a GC cycle, and the assist ratio is a best-effort
+// heuristic anyway. Furthermore, no part of the heuristic depends on
+// the two assist ratio values being exact reciprocals of one another, since
+// the two values are used to convert values from different sources.
+//
+// The worst case result of this raciness is that we may miss a larger shift
+// in the ratio (say, if we decide to pace more aggressively against the
+// hard heap goal) but even this "hard goal" is best-effort (see #40460).
+// The dedicated GC should ensure we don't exceed the hard goal by too much
+// in the rare case we do exceed it.
+//
+// It should only be called when gcBlackenEnabled != 0 (because this
+// is when assists are enabled and the necessary statistics are
+// available).
+func (c *gcControllerState) revise() {
+ gcPercent := c.gcPercent.Load()
+ if gcPercent < 0 {
+ // If GC is disabled but we're running a forced GC,
+ // act like GOGC is huge for the below calculations.
+ gcPercent = 100000
+ }
+ live := c.heapLive.Load()
+ scan := c.heapScan.Load()
+ work := c.heapScanWork.Load() + c.stackScanWork.Load() + c.globalsScanWork.Load()
+
+ // Assume we're under the soft goal. Pace GC to complete at
+ // heapGoal assuming the heap is in steady-state.
+ heapGoal := int64(c.heapGoal())
+
+ // The expected scan work is computed as the amount of bytes scanned last
+ // GC cycle (both heap and stack), plus our estimate of globals work for this cycle.
+ scanWorkExpected := int64(c.lastHeapScan + c.lastStackScan.Load() + c.globalsScan.Load())
+
+ // maxScanWork is a worst-case estimate of the amount of scan work that
+ // needs to be performed in this GC cycle. Specifically, it represents
+ // the case where *all* scannable memory turns out to be live, and
+ // *all* allocated stack space is scannable.
+ maxStackScan := c.maxStackScan.Load()
+ maxScanWork := int64(scan + maxStackScan + c.globalsScan.Load())
+ if work > scanWorkExpected {
+ // We've already done more scan work than expected. Because our expectation
+ // is based on a steady-state scannable heap size, we assume this means our
+ // heap is growing. Compute a new heap goal that takes our existing runway
+ // computed for scanWorkExpected and extrapolates it to maxScanWork, the worst-case
+ // scan work. This keeps our assist ratio stable if the heap continues to grow.
+ //
+ // The effect of this mechanism is that assists stay flat in the face of heap
+ // growths. It's OK to use more memory this cycle to scan all the live heap,
+ // because the next GC cycle is inevitably going to use *at least* that much
+ // memory anyway.
+ extHeapGoal := int64(float64(heapGoal-int64(c.triggered))/float64(scanWorkExpected)*float64(maxScanWork)) + int64(c.triggered)
+ scanWorkExpected = maxScanWork
+
+ // hardGoal is a hard limit on the amount that we're willing to push back the
+ // heap goal, and that's twice the heap goal (i.e. if GOGC=100 and the heap and/or
+ // stacks and/or globals grow to twice their size, this limits the current GC cycle's
+ // growth to 4x the original live heap's size).
+ //
+ // This maintains the invariant that we use no more memory than the next GC cycle
+ // will anyway.
+ hardGoal := int64((1.0 + float64(gcPercent)/100.0) * float64(heapGoal))
+ if extHeapGoal > hardGoal {
+ extHeapGoal = hardGoal
+ }
+ heapGoal = extHeapGoal
+ }
+ if int64(live) > heapGoal {
+ // We're already past our heap goal, even the extrapolated one.
+ // Leave ourselves some extra runway, so in the worst case we
+ // finish by that point.
+ const maxOvershoot = 1.1
+ heapGoal = int64(float64(heapGoal) * maxOvershoot)
+
+ // Compute the upper bound on the scan work remaining.
+ scanWorkExpected = maxScanWork
+ }
+
+ // Compute the remaining scan work estimate.
+ //
+ // Note that we currently count allocations during GC as both
+ // scannable heap (heapScan) and scan work completed
+ // (scanWork), so allocation will change this difference
+ // slowly in the soft regime and not at all in the hard
+ // regime.
+ scanWorkRemaining := scanWorkExpected - work
+ if scanWorkRemaining < 1000 {
+ // We set a somewhat arbitrary lower bound on
+ // remaining scan work since if we aim a little high,
+ // we can miss by a little.
+ //
+ // We *do* need to enforce that this is at least 1,
+ // since marking is racy and double-scanning objects
+ // may legitimately make the remaining scan work
+ // negative, even in the hard goal regime.
+ scanWorkRemaining = 1000
+ }
+
+ // Compute the heap distance remaining.
+ heapRemaining := heapGoal - int64(live)
+ if heapRemaining <= 0 {
+ // This shouldn't happen, but if it does, avoid
+ // dividing by zero or setting the assist negative.
+ heapRemaining = 1
+ }
+
+ // Compute the mutator assist ratio so by the time the mutator
+ // allocates the remaining heap bytes up to heapGoal, it will
+ // have done (or stolen) the remaining amount of scan work.
+ // Note that the assist ratio values are updated atomically
+ // but not together. This means there may be some degree of
+ // skew between the two values. This is generally OK as the
+ // values shift relatively slowly over the course of a GC
+ // cycle.
+ assistWorkPerByte := float64(scanWorkRemaining) / float64(heapRemaining)
+ assistBytesPerWork := float64(heapRemaining) / float64(scanWorkRemaining)
+ c.assistWorkPerByte.Store(assistWorkPerByte)
+ c.assistBytesPerWork.Store(assistBytesPerWork)
+}
+
+// endCycle computes the consMark estimate for the next cycle.
+// userForced indicates whether the current GC cycle was forced
+// by the application.
+func (c *gcControllerState) endCycle(now int64, procs int, userForced bool) {
+ // Record last heap goal for the scavenger.
+ // We'll be updating the heap goal soon.
+ gcController.lastHeapGoal = c.heapGoal()
+
+ // Compute the duration of time for which assists were turned on.
+ assistDuration := now - c.markStartTime
+
+ // Assume background mark hit its utilization goal.
+ utilization := gcBackgroundUtilization
+ // Add assist utilization; avoid divide by zero.
+ if assistDuration > 0 {
+ utilization += float64(c.assistTime.Load()) / float64(assistDuration*int64(procs))
+ }
+
+ if c.heapLive.Load() <= c.triggered {
+ // Shouldn't happen, but let's be very safe about this in case the
+ // GC is somehow extremely short.
+ //
+ // In this case though, the only reasonable value for c.heapLive-c.triggered
+ // would be 0, which isn't really all that useful, i.e. the GC was so short
+ // that it didn't matter.
+ //
+ // Ignore this case and don't update anything.
+ return
+ }
+ idleUtilization := 0.0
+ if assistDuration > 0 {
+ idleUtilization = float64(c.idleMarkTime.Load()) / float64(assistDuration*int64(procs))
+ }
+ // Determine the cons/mark ratio.
+ //
+ // The units we want for the numerator and denominator are both B / cpu-ns.
+ // We get this by taking the bytes allocated or scanned, and divide by the amount of
+ // CPU time it took for those operations. For allocations, that CPU time is
+ //
+ // assistDuration * procs * (1 - utilization)
+ //
+ // Where utilization includes just background GC workers and assists. It does *not*
+ // include idle GC work time, because in theory the mutator is free to take that at
+ // any point.
+ //
+ // For scanning, that CPU time is
+ //
+ // assistDuration * procs * (utilization + idleUtilization)
+ //
+ // In this case, we *include* idle utilization, because that is additional CPU time that
+ // the GC had available to it.
+ //
+ // In effect, idle GC time is sort of double-counted here, but it's very weird compared
+ // to other kinds of GC work, because of how fluid it is. Namely, because the mutator is
+ // *always* free to take it.
+ //
+ // So this calculation is really:
+ // (heapLive-trigger) / (assistDuration * procs * (1-utilization)) /
+ // (scanWork) / (assistDuration * procs * (utilization+idleUtilization))
+ //
+ // Note that because we only care about the ratio, assistDuration and procs cancel out.
+ scanWork := c.heapScanWork.Load() + c.stackScanWork.Load() + c.globalsScanWork.Load()
+ currentConsMark := (float64(c.heapLive.Load()-c.triggered) * (utilization + idleUtilization)) /
+ (float64(scanWork) * (1 - utilization))
+
+ // Update our cons/mark estimate. This is the maximum of the value we just computed and the last
+ // 4 cons/mark values we measured. The reason we take the maximum here is to bias a noisy
+ // cons/mark measurement toward fewer assists at the expense of additional GC cycles (starting
+ // earlier).
+ oldConsMark := c.consMark
+ c.consMark = currentConsMark
+ for i := range c.lastConsMark {
+ if c.lastConsMark[i] > c.consMark {
+ c.consMark = c.lastConsMark[i]
+ }
+ }
+ copy(c.lastConsMark[:], c.lastConsMark[1:])
+ c.lastConsMark[len(c.lastConsMark)-1] = currentConsMark
+
+ if debug.gcpacertrace > 0 {
+ printlock()
+ goal := gcGoalUtilization * 100
+ print("pacer: ", int(utilization*100), "% CPU (", int(goal), " exp.) for ")
+ print(c.heapScanWork.Load(), "+", c.stackScanWork.Load(), "+", c.globalsScanWork.Load(), " B work (", c.lastHeapScan+c.lastStackScan.Load()+c.globalsScan.Load(), " B exp.) ")
+ live := c.heapLive.Load()
+ print("in ", c.triggered, " B -> ", live, " B (∆goal ", int64(live)-int64(c.lastHeapGoal), ", cons/mark ", oldConsMark, ")")
+ println()
+ printunlock()
+ }
+}
+
+// enlistWorker encourages another dedicated mark worker to start on
+// another P if there are spare worker slots. It is used by putfull
+// when more work is made available.
+//
+//go:nowritebarrier
+func (c *gcControllerState) enlistWorker() {
+ // If there are idle Ps, wake one so it will run an idle worker.
+ // NOTE: This is suspected of causing deadlocks. See golang.org/issue/19112.
+ //
+ // if sched.npidle.Load() != 0 && sched.nmspinning.Load() == 0 {
+ // wakep()
+ // return
+ // }
+
+ // There are no idle Ps. If we need more dedicated workers,
+ // try to preempt a running P so it will switch to a worker.
+ if c.dedicatedMarkWorkersNeeded.Load() <= 0 {
+ return
+ }
+ // Pick a random other P to preempt.
+ if gomaxprocs <= 1 {
+ return
+ }
+ gp := getg()
+ if gp == nil || gp.m == nil || gp.m.p == 0 {
+ return
+ }
+ myID := gp.m.p.ptr().id
+ for tries := 0; tries < 5; tries++ {
+ id := int32(fastrandn(uint32(gomaxprocs - 1)))
+ if id >= myID {
+ id++
+ }
+ p := allp[id]
+ if p.status != _Prunning {
+ continue
+ }
+ if preemptone(p) {
+ return
+ }
+ }
+}
+
+// findRunnableGCWorker returns a background mark worker for pp if it
+// should be run. This must only be called when gcBlackenEnabled != 0.
+func (c *gcControllerState) findRunnableGCWorker(pp *p, now int64) (*g, int64) {
+ if gcBlackenEnabled == 0 {
+ throw("gcControllerState.findRunnable: blackening not enabled")
+ }
+
+ // Since we have the current time, check if the GC CPU limiter
+ // hasn't had an update in a while. This check is necessary in
+ // case the limiter is on but hasn't been checked in a while and
+ // so may have left sufficient headroom to turn off again.
+ if now == 0 {
+ now = nanotime()
+ }
+ if gcCPULimiter.needUpdate(now) {
+ gcCPULimiter.update(now)
+ }
+
+ if !gcMarkWorkAvailable(pp) {
+ // No work to be done right now. This can happen at
+ // the end of the mark phase when there are still
+ // assists tapering off. Don't bother running a worker
+ // now because it'll just return immediately.
+ return nil, now
+ }
+
+ // Grab a worker before we commit to running below.
+ node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
+ if node == nil {
+ // There is at least one worker per P, so normally there are
+ // enough workers to run on all Ps, if necessary. However, once
+ // a worker enters gcMarkDone it may park without rejoining the
+ // pool, thus freeing a P with no corresponding worker.
+ // gcMarkDone never depends on another worker doing work, so it
+ // is safe to simply do nothing here.
+ //
+ // If gcMarkDone bails out without completing the mark phase,
+ // it will always do so with queued global work. Thus, that P
+ // will be immediately eligible to re-run the worker G it was
+ // just using, ensuring work can complete.
+ return nil, now
+ }
+
+ decIfPositive := func(val *atomic.Int64) bool {
+ for {
+ v := val.Load()
+ if v <= 0 {
+ return false
+ }
+
+ if val.CompareAndSwap(v, v-1) {
+ return true
+ }
+ }
+ }
+
+ if decIfPositive(&c.dedicatedMarkWorkersNeeded) {
+ // This P is now dedicated to marking until the end of
+ // the concurrent mark phase.
+ pp.gcMarkWorkerMode = gcMarkWorkerDedicatedMode
+ } else if c.fractionalUtilizationGoal == 0 {
+ // No need for fractional workers.
+ gcBgMarkWorkerPool.push(&node.node)
+ return nil, now
+ } else {
+ // Is this P behind on the fractional utilization
+ // goal?
+ //
+ // This should be kept in sync with pollFractionalWorkerExit.
+ delta := now - c.markStartTime
+ if delta > 0 && float64(pp.gcFractionalMarkTime)/float64(delta) > c.fractionalUtilizationGoal {
+ // Nope. No need to run a fractional worker.
+ gcBgMarkWorkerPool.push(&node.node)
+ return nil, now
+ }
+ // Run a fractional worker.
+ pp.gcMarkWorkerMode = gcMarkWorkerFractionalMode
+ }
+
+ // Run the background mark worker.
+ gp := node.gp.ptr()
+ casgstatus(gp, _Gwaiting, _Grunnable)
+ if traceEnabled() {
+ traceGoUnpark(gp, 0)
+ }
+ return gp, now
+}
+
+// resetLive sets up the controller state for the next mark phase after the end
+// of the previous one. Must be called after endCycle and before commit, before
+// the world is started.
+//
+// The world must be stopped.
+func (c *gcControllerState) resetLive(bytesMarked uint64) {
+ c.heapMarked = bytesMarked
+ c.heapLive.Store(bytesMarked)
+ c.heapScan.Store(uint64(c.heapScanWork.Load()))
+ c.lastHeapScan = uint64(c.heapScanWork.Load())
+ c.lastStackScan.Store(uint64(c.stackScanWork.Load()))
+ c.triggered = ^uint64(0) // Reset triggered.
+
+ // heapLive was updated, so emit a trace event.
+ if traceEnabled() {
+ traceHeapAlloc(bytesMarked)
+ }
+}
+
+// markWorkerStop must be called whenever a mark worker stops executing.
+//
+// It updates mark work accounting in the controller by a duration of
+// work in nanoseconds and other bookkeeping.
+//
+// Safe to execute at any time.
+func (c *gcControllerState) markWorkerStop(mode gcMarkWorkerMode, duration int64) {
+ switch mode {
+ case gcMarkWorkerDedicatedMode:
+ c.dedicatedMarkTime.Add(duration)
+ c.dedicatedMarkWorkersNeeded.Add(1)
+ case gcMarkWorkerFractionalMode:
+ c.fractionalMarkTime.Add(duration)
+ case gcMarkWorkerIdleMode:
+ c.idleMarkTime.Add(duration)
+ c.removeIdleMarkWorker()
+ default:
+ throw("markWorkerStop: unknown mark worker mode")
+ }
+}
+
+func (c *gcControllerState) update(dHeapLive, dHeapScan int64) {
+ if dHeapLive != 0 {
+ live := gcController.heapLive.Add(dHeapLive)
+ if traceEnabled() {
+ // gcController.heapLive changed.
+ traceHeapAlloc(live)
+ }
+ }
+ if gcBlackenEnabled == 0 {
+ // Update heapScan when we're not in a current GC. It is fixed
+ // at the beginning of a cycle.
+ if dHeapScan != 0 {
+ gcController.heapScan.Add(dHeapScan)
+ }
+ } else {
+ // gcController.heapLive changed.
+ c.revise()
+ }
+}
+
+func (c *gcControllerState) addScannableStack(pp *p, amount int64) {
+ if pp == nil {
+ c.maxStackScan.Add(amount)
+ return
+ }
+ pp.maxStackScanDelta += amount
+ if pp.maxStackScanDelta >= maxStackScanSlack || pp.maxStackScanDelta <= -maxStackScanSlack {
+ c.maxStackScan.Add(pp.maxStackScanDelta)
+ pp.maxStackScanDelta = 0
+ }
+}
+
+func (c *gcControllerState) addGlobals(amount int64) {
+ c.globalsScan.Add(amount)
+}
+
+// heapGoal returns the current heap goal.
+func (c *gcControllerState) heapGoal() uint64 {
+ goal, _ := c.heapGoalInternal()
+ return goal
+}
+
+// heapGoalInternal is the implementation of heapGoal which returns additional
+// information that is necessary for computing the trigger.
+//
+// The returned minTrigger is always <= goal.
+func (c *gcControllerState) heapGoalInternal() (goal, minTrigger uint64) {
+ // Start with the goal calculated for gcPercent.
+ goal = c.gcPercentHeapGoal.Load()
+
+ // Check if the memory-limit-based goal is smaller, and if so, pick that.
+ if newGoal := c.memoryLimitHeapGoal(); newGoal < goal {
+ goal = newGoal
+ } else {
+ // We're not limited by the memory limit goal, so perform a series of
+ // adjustments that might move the goal forward in a variety of circumstances.
+
+ sweepDistTrigger := c.sweepDistMinTrigger.Load()
+ if sweepDistTrigger > goal {
+ // Set the goal to maintain a minimum sweep distance since
+ // the last call to commit. Note that we never want to do this
+ // if we're in the memory limit regime, because it could push
+ // the goal up.
+ goal = sweepDistTrigger
+ }
+ // Since we ignore the sweep distance trigger in the memory
+ // limit regime, we need to ensure we don't propagate it to
+ // the trigger, because it could cause a violation of the
+ // invariant that the trigger < goal.
+ minTrigger = sweepDistTrigger
+
+ // Ensure that the heap goal is at least a little larger than
+ // the point at which we triggered. This may not be the case if GC
+ // start is delayed or if the allocation that pushed gcController.heapLive
+ // over trigger is large or if the trigger is really close to
+ // GOGC. Assist is proportional to this distance, so enforce a
+ // minimum distance, even if it means going over the GOGC goal
+ // by a tiny bit.
+ //
+ // Ignore this if we're in the memory limit regime: we'd prefer to
+ // have the GC respond hard about how close we are to the goal than to
+ // push the goal back in such a manner that it could cause us to exceed
+ // the memory limit.
+ const minRunway = 64 << 10
+ if c.triggered != ^uint64(0) && goal < c.triggered+minRunway {
+ goal = c.triggered + minRunway
+ }
+ }
+ return
+}
+
+// memoryLimitHeapGoal returns a heap goal derived from memoryLimit.
+func (c *gcControllerState) memoryLimitHeapGoal() uint64 {
+ // Start by pulling out some values we'll need. Be careful about overflow.
+ var heapFree, heapAlloc, mappedReady uint64
+ for {
+ heapFree = c.heapFree.load() // Free and unscavenged memory.
+ heapAlloc = c.totalAlloc.Load() - c.totalFree.Load() // Heap object bytes in use.
+ mappedReady = c.mappedReady.Load() // Total unreleased mapped memory.
+ if heapFree+heapAlloc <= mappedReady {
+ break
+ }
+ // It is impossible for total unreleased mapped memory to exceed heap memory, but
+ // because these stats are updated independently, we may observe a partial update
+ // including only some values. Thus, we appear to break the invariant. However,
+ // this condition is necessarily transient, so just try again. In the case of a
+ // persistent accounting error, we'll deadlock here.
+ }
+
+ // Below we compute a goal from memoryLimit. There are a few things to be aware of.
+ // Firstly, the memoryLimit does not easily compare to the heap goal: the former
+ // is total mapped memory by the runtime that hasn't been released, while the latter is
+ // only heap object memory. Intuitively, the way we convert from one to the other is to
+ // subtract everything from memoryLimit that both contributes to the memory limit (so,
+ // ignore scavenged memory) and doesn't contain heap objects. This isn't quite what
+ // lines up with reality, but it's a good starting point.
+ //
+ // In practice this computation looks like the following:
+ //
+ // goal := memoryLimit - ((mappedReady - heapFree - heapAlloc) + max(mappedReady - memoryLimit, 0))
+ // ^1 ^2
+ // goal -= goal / 100 * memoryLimitHeapGoalHeadroomPercent
+ // ^3
+ //
+ // Let's break this down.
+ //
+ // The first term (marker 1) is everything that contributes to the memory limit and isn't
+ // or couldn't become heap objects. It represents, broadly speaking, non-heap overheads.
+ // One oddity you may have noticed is that we also subtract out heapFree, i.e. unscavenged
+ // memory that may contain heap objects in the future.
+ //
+ // Let's take a step back. In an ideal world, this term would look something like just
+ // the heap goal. That is, we "reserve" enough space for the heap to grow to the heap
+ // goal, and subtract out everything else. This is of course impossible; the definition
+ // is circular! However, this impossible definition contains a key insight: the amount
+ // we're *going* to use matters just as much as whatever we're currently using.
+ //
+ // Consider if the heap shrinks to 1/10th its size, leaving behind lots of free and
+ // unscavenged memory. mappedReady - heapAlloc will be quite large, because of that free
+ // and unscavenged memory, pushing the goal down significantly.
+ //
+ // heapFree is also safe to exclude from the memory limit because in the steady-state, it's
+ // just a pool of memory for future heap allocations, and making new allocations from heapFree
+ // memory doesn't increase overall memory use. In transient states, the scavenger and the
+ // allocator actively manage the pool of heapFree memory to maintain the memory limit.
+ //
+ // The second term (marker 2) is the amount of memory we've exceeded the limit by, and is
+ // intended to help recover from such a situation. By pushing the heap goal down, we also
+ // push the trigger down, triggering and finishing a GC sooner in order to make room for
+ // other memory sources. Note that since we're effectively reducing the heap goal by X bytes,
+ // we're actually giving more than X bytes of headroom back, because the heap goal is in
+ // terms of heap objects, but it takes more than X bytes (e.g. due to fragmentation) to store
+ // X bytes worth of objects.
+ //
+ // The final adjustment (marker 3) reduces the maximum possible memory limit heap goal by
+ // memoryLimitHeapGoalPercent. As the name implies, this is to provide additional headroom in
+ // the face of pacing inaccuracies, and also to leave a buffer of unscavenged memory so the
+ // allocator isn't constantly scavenging. The reduction amount also has a fixed minimum
+ // (memoryLimitMinHeapGoalHeadroom, not pictured) because the aforementioned pacing inaccuracies
+ // disproportionately affect small heaps: as heaps get smaller, the pacer's inputs get fuzzier.
+ // Shorter GC cycles and less GC work means noisy external factors like the OS scheduler have a
+ // greater impact.
+
+ memoryLimit := uint64(c.memoryLimit.Load())
+
+ // Compute term 1.
+ nonHeapMemory := mappedReady - heapFree - heapAlloc
+
+ // Compute term 2.
+ var overage uint64
+ if mappedReady > memoryLimit {
+ overage = mappedReady - memoryLimit
+ }
+
+ if nonHeapMemory+overage >= memoryLimit {
+ // We're at a point where non-heap memory exceeds the memory limit on its own.
+ // There's honestly not much we can do here but just trigger GCs continuously
+ // and let the CPU limiter reign that in. Something has to give at this point.
+ // Set it to heapMarked, the lowest possible goal.
+ return c.heapMarked
+ }
+
+ // Compute the goal.
+ goal := memoryLimit - (nonHeapMemory + overage)
+
+ // Apply some headroom to the goal to account for pacing inaccuracies and to reduce
+ // the impact of scavenging at allocation time in response to a high allocation rate
+ // when GOGC=off. See issue #57069. Also, be careful about small limits.
+ headroom := goal / 100 * memoryLimitHeapGoalHeadroomPercent
+ if headroom < memoryLimitMinHeapGoalHeadroom {
+ // Set a fixed minimum to deal with the particularly large effect pacing inaccuracies
+ // have for smaller heaps.
+ headroom = memoryLimitMinHeapGoalHeadroom
+ }
+ if goal < headroom || goal-headroom < headroom {
+ goal = headroom
+ } else {
+ goal = goal - headroom
+ }
+ // Don't let us go below the live heap. A heap goal below the live heap doesn't make sense.
+ if goal < c.heapMarked {
+ goal = c.heapMarked
+ }
+ return goal
+}
+
+const (
+ // These constants determine the bounds on the GC trigger as a fraction
+ // of heap bytes allocated between the start of a GC (heapLive == heapMarked)
+ // and the end of a GC (heapLive == heapGoal).
+ //
+ // The constants are obscured in this way for efficiency. The denominator
+ // of the fraction is always a power-of-two for a quick division, so that
+ // the numerator is a single constant integer multiplication.
+ triggerRatioDen = 64
+
+ // The minimum trigger constant was chosen empirically: given a sufficiently
+ // fast/scalable allocator with 48 Ps that could drive the trigger ratio
+ // to <0.05, this constant causes applications to retain the same peak
+ // RSS compared to not having this allocator.
+ minTriggerRatioNum = 45 // ~0.7
+
+ // The maximum trigger constant is chosen somewhat arbitrarily, but the
+ // current constant has served us well over the years.
+ maxTriggerRatioNum = 61 // ~0.95
+)
+
+// trigger returns the current point at which a GC should trigger along with
+// the heap goal.
+//
+// The returned value may be compared against heapLive to determine whether
+// the GC should trigger. Thus, the GC trigger condition should be (but may
+// not be, in the case of small movements for efficiency) checked whenever
+// the heap goal may change.
+func (c *gcControllerState) trigger() (uint64, uint64) {
+ goal, minTrigger := c.heapGoalInternal()
+
+ // Invariant: the trigger must always be less than the heap goal.
+ //
+ // Note that the memory limit sets a hard maximum on our heap goal,
+ // but the live heap may grow beyond it.
+
+ if c.heapMarked >= goal {
+ // The goal should never be smaller than heapMarked, but let's be
+ // defensive about it. The only reasonable trigger here is one that
+ // causes a continuous GC cycle at heapMarked, but respect the goal
+ // if it came out as smaller than that.
+ return goal, goal
+ }
+
+ // Below this point, c.heapMarked < goal.
+
+ // heapMarked is our absolute minimum, and it's possible the trigger
+ // bound we get from heapGoalinternal is less than that.
+ if minTrigger < c.heapMarked {
+ minTrigger = c.heapMarked
+ }
+
+ // If we let the trigger go too low, then if the application
+ // is allocating very rapidly we might end up in a situation
+ // where we're allocating black during a nearly always-on GC.
+ // The result of this is a growing heap and ultimately an
+ // increase in RSS. By capping us at a point >0, we're essentially
+ // saying that we're OK using more CPU during the GC to prevent
+ // this growth in RSS.
+ triggerLowerBound := uint64(((goal-c.heapMarked)/triggerRatioDen)*minTriggerRatioNum) + c.heapMarked
+ if minTrigger < triggerLowerBound {
+ minTrigger = triggerLowerBound
+ }
+
+ // For small heaps, set the max trigger point at maxTriggerRatio of the way
+ // from the live heap to the heap goal. This ensures we always have *some*
+ // headroom when the GC actually starts. For larger heaps, set the max trigger
+ // point at the goal, minus the minimum heap size.
+ //
+ // This choice follows from the fact that the minimum heap size is chosen
+ // to reflect the costs of a GC with no work to do. With a large heap but
+ // very little scan work to perform, this gives us exactly as much runway
+ // as we would need, in the worst case.
+ maxTrigger := uint64(((goal-c.heapMarked)/triggerRatioDen)*maxTriggerRatioNum) + c.heapMarked
+ if goal > defaultHeapMinimum && goal-defaultHeapMinimum > maxTrigger {
+ maxTrigger = goal - defaultHeapMinimum
+ }
+ if maxTrigger < minTrigger {
+ maxTrigger = minTrigger
+ }
+
+ // Compute the trigger from our bounds and the runway stored by commit.
+ var trigger uint64
+ runway := c.runway.Load()
+ if runway > goal {
+ trigger = minTrigger
+ } else {
+ trigger = goal - runway
+ }
+ if trigger < minTrigger {
+ trigger = minTrigger
+ }
+ if trigger > maxTrigger {
+ trigger = maxTrigger
+ }
+ if trigger > goal {
+ print("trigger=", trigger, " heapGoal=", goal, "\n")
+ print("minTrigger=", minTrigger, " maxTrigger=", maxTrigger, "\n")
+ throw("produced a trigger greater than the heap goal")
+ }
+ return trigger, goal
+}
+
+// commit recomputes all pacing parameters needed to derive the
+// trigger and the heap goal. Namely, the gcPercent-based heap goal,
+// and the amount of runway we want to give the GC this cycle.
+//
+// This can be called any time. If GC is the in the middle of a
+// concurrent phase, it will adjust the pacing of that phase.
+//
+// isSweepDone should be the result of calling isSweepDone(),
+// unless we're testing or we know we're executing during a GC cycle.
+//
+// This depends on gcPercent, gcController.heapMarked, and
+// gcController.heapLive. These must be up to date.
+//
+// Callers must call gcControllerState.revise after calling this
+// function if the GC is enabled.
+//
+// mheap_.lock must be held or the world must be stopped.
+func (c *gcControllerState) commit(isSweepDone bool) {
+ if !c.test {
+ assertWorldStoppedOrLockHeld(&mheap_.lock)
+ }
+
+ if isSweepDone {
+ // The sweep is done, so there aren't any restrictions on the trigger
+ // we need to think about.
+ c.sweepDistMinTrigger.Store(0)
+ } else {
+ // Concurrent sweep happens in the heap growth
+ // from gcController.heapLive to trigger. Make sure we
+ // give the sweeper some runway if it doesn't have enough.
+ c.sweepDistMinTrigger.Store(c.heapLive.Load() + sweepMinHeapDistance)
+ }
+
+ // Compute the next GC goal, which is when the allocated heap
+ // has grown by GOGC/100 over where it started the last cycle,
+ // plus additional runway for non-heap sources of GC work.
+ gcPercentHeapGoal := ^uint64(0)
+ if gcPercent := c.gcPercent.Load(); gcPercent >= 0 {
+ gcPercentHeapGoal = c.heapMarked + (c.heapMarked+c.lastStackScan.Load()+c.globalsScan.Load())*uint64(gcPercent)/100
+ }
+ // Apply the minimum heap size here. It's defined in terms of gcPercent
+ // and is only updated by functions that call commit.
+ if gcPercentHeapGoal < c.heapMinimum {
+ gcPercentHeapGoal = c.heapMinimum
+ }
+ c.gcPercentHeapGoal.Store(gcPercentHeapGoal)
+
+ // Compute the amount of runway we want the GC to have by using our
+ // estimate of the cons/mark ratio.
+ //
+ // The idea is to take our expected scan work, and multiply it by
+ // the cons/mark ratio to determine how long it'll take to complete
+ // that scan work in terms of bytes allocated. This gives us our GC's
+ // runway.
+ //
+ // However, the cons/mark ratio is a ratio of rates per CPU-second, but
+ // here we care about the relative rates for some division of CPU
+ // resources among the mutator and the GC.
+ //
+ // To summarize, we have B / cpu-ns, and we want B / ns. We get that
+ // by multiplying by our desired division of CPU resources. We choose
+ // to express CPU resources as GOMAPROCS*fraction. Note that because
+ // we're working with a ratio here, we can omit the number of CPU cores,
+ // because they'll appear in the numerator and denominator and cancel out.
+ // As a result, this is basically just "weighing" the cons/mark ratio by
+ // our desired division of resources.
+ //
+ // Furthermore, by setting the runway so that CPU resources are divided
+ // this way, assuming that the cons/mark ratio is correct, we make that
+ // division a reality.
+ c.runway.Store(uint64((c.consMark * (1 - gcGoalUtilization) / (gcGoalUtilization)) * float64(c.lastHeapScan+c.lastStackScan.Load()+c.globalsScan.Load())))
+}
+
+// setGCPercent updates gcPercent. commit must be called after.
+// Returns the old value of gcPercent.
+//
+// The world must be stopped, or mheap_.lock must be held.
+func (c *gcControllerState) setGCPercent(in int32) int32 {
+ if !c.test {
+ assertWorldStoppedOrLockHeld(&mheap_.lock)
+ }
+
+ out := c.gcPercent.Load()
+ if in < 0 {
+ in = -1
+ }
+ c.heapMinimum = defaultHeapMinimum * uint64(in) / 100
+ c.gcPercent.Store(in)
+
+ return out
+}
+
+//go:linkname setGCPercent runtime/debug.setGCPercent
+func setGCPercent(in int32) (out int32) {
+ // Run on the system stack since we grab the heap lock.
+ systemstack(func() {
+ lock(&mheap_.lock)
+ out = gcController.setGCPercent(in)
+ gcControllerCommit()
+ unlock(&mheap_.lock)
+ })
+
+ // If we just disabled GC, wait for any concurrent GC mark to
+ // finish so we always return with no GC running.
+ if in < 0 {
+ gcWaitOnMark(work.cycles.Load())
+ }
+
+ return out
+}
+
+func readGOGC() int32 {
+ p := gogetenv("GOGC")
+ if p == "off" {
+ return -1
+ }
+ if n, ok := atoi32(p); ok {
+ return n
+ }
+ return 100
+}
+
+// setMemoryLimit updates memoryLimit. commit must be called after
+// Returns the old value of memoryLimit.
+//
+// The world must be stopped, or mheap_.lock must be held.
+func (c *gcControllerState) setMemoryLimit(in int64) int64 {
+ if !c.test {
+ assertWorldStoppedOrLockHeld(&mheap_.lock)
+ }
+
+ out := c.memoryLimit.Load()
+ if in >= 0 {
+ c.memoryLimit.Store(in)
+ }
+
+ return out
+}
+
+//go:linkname setMemoryLimit runtime/debug.setMemoryLimit
+func setMemoryLimit(in int64) (out int64) {
+ // Run on the system stack since we grab the heap lock.
+ systemstack(func() {
+ lock(&mheap_.lock)
+ out = gcController.setMemoryLimit(in)
+ if in < 0 || out == in {
+ // If we're just checking the value or not changing
+ // it, there's no point in doing the rest.
+ unlock(&mheap_.lock)
+ return
+ }
+ gcControllerCommit()
+ unlock(&mheap_.lock)
+ })
+ return out
+}
+
+func readGOMEMLIMIT() int64 {
+ p := gogetenv("GOMEMLIMIT")
+ if p == "" || p == "off" {
+ return maxInt64
+ }
+ n, ok := parseByteCount(p)
+ if !ok {
+ print("GOMEMLIMIT=", p, "\n")
+ throw("malformed GOMEMLIMIT; see `go doc runtime/debug.SetMemoryLimit`")
+ }
+ return n
+}
+
+// addIdleMarkWorker attempts to add a new idle mark worker.
+//
+// If this returns true, the caller must become an idle mark worker unless
+// there's no background mark worker goroutines in the pool. This case is
+// harmless because there are already background mark workers running.
+// If this returns false, the caller must NOT become an idle mark worker.
+//
+// nosplit because it may be called without a P.
+//
+//go:nosplit
+func (c *gcControllerState) addIdleMarkWorker() bool {
+ for {
+ old := c.idleMarkWorkers.Load()
+ n, max := int32(old&uint64(^uint32(0))), int32(old>>32)
+ if n >= max {
+ // See the comment on idleMarkWorkers for why
+ // n > max is tolerated.
+ return false
+ }
+ if n < 0 {
+ print("n=", n, " max=", max, "\n")
+ throw("negative idle mark workers")
+ }
+ new := uint64(uint32(n+1)) | (uint64(max) << 32)
+ if c.idleMarkWorkers.CompareAndSwap(old, new) {
+ return true
+ }
+ }
+}
+
+// needIdleMarkWorker is a hint as to whether another idle mark worker is needed.
+//
+// The caller must still call addIdleMarkWorker to become one. This is mainly
+// useful for a quick check before an expensive operation.
+//
+// nosplit because it may be called without a P.
+//
+//go:nosplit
+func (c *gcControllerState) needIdleMarkWorker() bool {
+ p := c.idleMarkWorkers.Load()
+ n, max := int32(p&uint64(^uint32(0))), int32(p>>32)
+ return n < max
+}
+
+// removeIdleMarkWorker must be called when an new idle mark worker stops executing.
+func (c *gcControllerState) removeIdleMarkWorker() {
+ for {
+ old := c.idleMarkWorkers.Load()
+ n, max := int32(old&uint64(^uint32(0))), int32(old>>32)
+ if n-1 < 0 {
+ print("n=", n, " max=", max, "\n")
+ throw("negative idle mark workers")
+ }
+ new := uint64(uint32(n-1)) | (uint64(max) << 32)
+ if c.idleMarkWorkers.CompareAndSwap(old, new) {
+ return
+ }
+ }
+}
+
+// setMaxIdleMarkWorkers sets the maximum number of idle mark workers allowed.
+//
+// This method is optimistic in that it does not wait for the number of
+// idle mark workers to reduce to max before returning; it assumes the workers
+// will deschedule themselves.
+func (c *gcControllerState) setMaxIdleMarkWorkers(max int32) {
+ for {
+ old := c.idleMarkWorkers.Load()
+ n := int32(old & uint64(^uint32(0)))
+ if n < 0 {
+ print("n=", n, " max=", max, "\n")
+ throw("negative idle mark workers")
+ }
+ new := uint64(uint32(n)) | (uint64(max) << 32)
+ if c.idleMarkWorkers.CompareAndSwap(old, new) {
+ return
+ }
+ }
+}
+
+// gcControllerCommit is gcController.commit, but passes arguments from live
+// (non-test) data. It also updates any consumers of the GC pacing, such as
+// sweep pacing and the background scavenger.
+//
+// Calls gcController.commit.
+//
+// The heap lock must be held, so this must be executed on the system stack.
+//
+//go:systemstack
+func gcControllerCommit() {
+ assertWorldStoppedOrLockHeld(&mheap_.lock)
+
+ gcController.commit(isSweepDone())
+
+ // Update mark pacing.
+ if gcphase != _GCoff {
+ gcController.revise()
+ }
+
+ // TODO(mknyszek): This isn't really accurate any longer because the heap
+ // goal is computed dynamically. Still useful to snapshot, but not as useful.
+ if traceEnabled() {
+ traceHeapGoal()
+ }
+
+ trigger, heapGoal := gcController.trigger()
+ gcPaceSweeper(trigger)
+ gcPaceScavenger(gcController.memoryLimit.Load(), heapGoal, gcController.lastHeapGoal)
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mgcscavenge.go b/contrib/go/_std_1.21/src/runtime/mgcscavenge.go
new file mode 100644
index 0000000000..4c6d6be4f0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mgcscavenge.go
@@ -0,0 +1,1473 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Scavenging free pages.
+//
+// This file implements scavenging (the release of physical pages backing mapped
+// memory) of free and unused pages in the heap as a way to deal with page-level
+// fragmentation and reduce the RSS of Go applications.
+//
+// Scavenging in Go happens on two fronts: there's the background
+// (asynchronous) scavenger and the allocation-time (synchronous) scavenger.
+//
+// The former happens on a goroutine much like the background sweeper which is
+// soft-capped at using scavengePercent of the mutator's time, based on
+// order-of-magnitude estimates of the costs of scavenging. The latter happens
+// when allocating pages from the heap.
+//
+// The scavenger's primary goal is to bring the estimated heap RSS of the
+// application down to a goal.
+//
+// Before we consider what this looks like, we need to split the world into two
+// halves. One in which a memory limit is not set, and one in which it is.
+//
+// For the former, the goal is defined as:
+// (retainExtraPercent+100) / 100 * (heapGoal / lastHeapGoal) * lastHeapInUse
+//
+// Essentially, we wish to have the application's RSS track the heap goal, but
+// the heap goal is defined in terms of bytes of objects, rather than pages like
+// RSS. As a result, we need to take into account for fragmentation internal to
+// spans. heapGoal / lastHeapGoal defines the ratio between the current heap goal
+// and the last heap goal, which tells us by how much the heap is growing and
+// shrinking. We estimate what the heap will grow to in terms of pages by taking
+// this ratio and multiplying it by heapInUse at the end of the last GC, which
+// allows us to account for this additional fragmentation. Note that this
+// procedure makes the assumption that the degree of fragmentation won't change
+// dramatically over the next GC cycle. Overestimating the amount of
+// fragmentation simply results in higher memory use, which will be accounted
+// for by the next pacing up date. Underestimating the fragmentation however
+// could lead to performance degradation. Handling this case is not within the
+// scope of the scavenger. Situations where the amount of fragmentation balloons
+// over the course of a single GC cycle should be considered pathologies,
+// flagged as bugs, and fixed appropriately.
+//
+// An additional factor of retainExtraPercent is added as a buffer to help ensure
+// that there's more unscavenged memory to allocate out of, since each allocation
+// out of scavenged memory incurs a potentially expensive page fault.
+//
+// If a memory limit is set, then we wish to pick a scavenge goal that maintains
+// that memory limit. For that, we look at total memory that has been committed
+// (memstats.mappedReady) and try to bring that down below the limit. In this case,
+// we want to give buffer space in the *opposite* direction. When the application
+// is close to the limit, we want to make sure we push harder to keep it under, so
+// if we target below the memory limit, we ensure that the background scavenger is
+// giving the situation the urgency it deserves.
+//
+// In this case, the goal is defined as:
+// (100-reduceExtraPercent) / 100 * memoryLimit
+//
+// We compute both of these goals, and check whether either of them have been met.
+// The background scavenger continues operating as long as either one of the goals
+// has not been met.
+//
+// The goals are updated after each GC.
+//
+// Synchronous scavenging happens for one of two reasons: if an allocation would
+// exceed the memory limit or whenever the heap grows in size, for some
+// definition of heap-growth. The intuition behind this second reason is that the
+// application had to grow the heap because existing fragments were not sufficiently
+// large to satisfy a page-level memory allocation, so we scavenge those fragments
+// eagerly to offset the growth in RSS that results.
+//
+// Lastly, not all pages are available for scavenging at all times and in all cases.
+// The background scavenger and heap-growth scavenger only release memory in chunks
+// that have not been densely-allocated for at least 1 full GC cycle. The reason
+// behind this is likelihood of reuse: the Go heap is allocated in a first-fit order
+// and by the end of the GC mark phase, the heap tends to be densely packed. Releasing
+// memory in these densely packed chunks while they're being packed is counter-productive,
+// and worse, it breaks up huge pages on systems that support them. The scavenger (invoked
+// during memory allocation) further ensures that chunks it identifies as "dense" are
+// immediately eligible for being backed by huge pages. Note that for the most part these
+// density heuristics are best-effort heuristics. It's totally possible (but unlikely)
+// that a chunk that just became dense is scavenged in the case of a race between memory
+// allocation and scavenging.
+//
+// When synchronously scavenging for the memory limit or for debug.FreeOSMemory, these
+// "dense" packing heuristics are ignored (in other words, scavenging is "forced") because
+// in these scenarios returning memory to the OS is more important than keeping CPU
+// overheads low.
+
+package runtime
+
+import (
+ "internal/goos"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+const (
+ // The background scavenger is paced according to these parameters.
+ //
+ // scavengePercent represents the portion of mutator time we're willing
+ // to spend on scavenging in percent.
+ scavengePercent = 1 // 1%
+
+ // retainExtraPercent represents the amount of memory over the heap goal
+ // that the scavenger should keep as a buffer space for the allocator.
+ // This constant is used when we do not have a memory limit set.
+ //
+ // The purpose of maintaining this overhead is to have a greater pool of
+ // unscavenged memory available for allocation (since using scavenged memory
+ // incurs an additional cost), to account for heap fragmentation and
+ // the ever-changing layout of the heap.
+ retainExtraPercent = 10
+
+ // reduceExtraPercent represents the amount of memory under the limit
+ // that the scavenger should target. For example, 5 means we target 95%
+ // of the limit.
+ //
+ // The purpose of shooting lower than the limit is to ensure that, once
+ // close to the limit, the scavenger is working hard to maintain it. If
+ // we have a memory limit set but are far away from it, there's no harm
+ // in leaving up to 100-retainExtraPercent live, and it's more efficient
+ // anyway, for the same reasons that retainExtraPercent exists.
+ reduceExtraPercent = 5
+
+ // maxPagesPerPhysPage is the maximum number of supported runtime pages per
+ // physical page, based on maxPhysPageSize.
+ maxPagesPerPhysPage = maxPhysPageSize / pageSize
+
+ // scavengeCostRatio is the approximate ratio between the costs of using previously
+ // scavenged memory and scavenging memory.
+ //
+ // For most systems the cost of scavenging greatly outweighs the costs
+ // associated with using scavenged memory, making this constant 0. On other systems
+ // (especially ones where "sysUsed" is not just a no-op) this cost is non-trivial.
+ //
+ // This ratio is used as part of multiplicative factor to help the scavenger account
+ // for the additional costs of using scavenged memory in its pacing.
+ scavengeCostRatio = 0.7 * (goos.IsDarwin + goos.IsIos)
+
+ // scavChunkHiOcFrac indicates the fraction of pages that need to be allocated
+ // in the chunk in a single GC cycle for it to be considered high density.
+ scavChunkHiOccFrac = 0.96875
+ scavChunkHiOccPages = uint16(scavChunkHiOccFrac * pallocChunkPages)
+)
+
+// heapRetained returns an estimate of the current heap RSS.
+func heapRetained() uint64 {
+ return gcController.heapInUse.load() + gcController.heapFree.load()
+}
+
+// gcPaceScavenger updates the scavenger's pacing, particularly
+// its rate and RSS goal. For this, it requires the current heapGoal,
+// and the heapGoal for the previous GC cycle.
+//
+// The RSS goal is based on the current heap goal with a small overhead
+// to accommodate non-determinism in the allocator.
+//
+// The pacing is based on scavengePageRate, which applies to both regular and
+// huge pages. See that constant for more information.
+//
+// Must be called whenever GC pacing is updated.
+//
+// mheap_.lock must be held or the world must be stopped.
+func gcPaceScavenger(memoryLimit int64, heapGoal, lastHeapGoal uint64) {
+ assertWorldStoppedOrLockHeld(&mheap_.lock)
+
+ // As described at the top of this file, there are two scavenge goals here: one
+ // for gcPercent and one for memoryLimit. Let's handle the latter first because
+ // it's simpler.
+
+ // We want to target retaining (100-reduceExtraPercent)% of the heap.
+ memoryLimitGoal := uint64(float64(memoryLimit) * (100.0 - reduceExtraPercent))
+
+ // mappedReady is comparable to memoryLimit, and represents how much total memory
+ // the Go runtime has committed now (estimated).
+ mappedReady := gcController.mappedReady.Load()
+
+ // If we're below the goal already indicate that we don't need the background
+ // scavenger for the memory limit. This may seems worrisome at first, but note
+ // that the allocator will assist the background scavenger in the face of a memory
+ // limit, so we'll be safe even if we stop the scavenger when we shouldn't have.
+ if mappedReady <= memoryLimitGoal {
+ scavenge.memoryLimitGoal.Store(^uint64(0))
+ } else {
+ scavenge.memoryLimitGoal.Store(memoryLimitGoal)
+ }
+
+ // Now handle the gcPercent goal.
+
+ // If we're called before the first GC completed, disable scavenging.
+ // We never scavenge before the 2nd GC cycle anyway (we don't have enough
+ // information about the heap yet) so this is fine, and avoids a fault
+ // or garbage data later.
+ if lastHeapGoal == 0 {
+ scavenge.gcPercentGoal.Store(^uint64(0))
+ return
+ }
+ // Compute our scavenging goal.
+ goalRatio := float64(heapGoal) / float64(lastHeapGoal)
+ gcPercentGoal := uint64(float64(memstats.lastHeapInUse) * goalRatio)
+ // Add retainExtraPercent overhead to retainedGoal. This calculation
+ // looks strange but the purpose is to arrive at an integer division
+ // (e.g. if retainExtraPercent = 12.5, then we get a divisor of 8)
+ // that also avoids the overflow from a multiplication.
+ gcPercentGoal += gcPercentGoal / (1.0 / (retainExtraPercent / 100.0))
+ // Align it to a physical page boundary to make the following calculations
+ // a bit more exact.
+ gcPercentGoal = (gcPercentGoal + uint64(physPageSize) - 1) &^ (uint64(physPageSize) - 1)
+
+ // Represents where we are now in the heap's contribution to RSS in bytes.
+ //
+ // Guaranteed to always be a multiple of physPageSize on systems where
+ // physPageSize <= pageSize since we map new heap memory at a size larger than
+ // any physPageSize and released memory in multiples of the physPageSize.
+ //
+ // However, certain functions recategorize heap memory as other stats (e.g.
+ // stacks) and this happens in multiples of pageSize, so on systems
+ // where physPageSize > pageSize the calculations below will not be exact.
+ // Generally this is OK since we'll be off by at most one regular
+ // physical page.
+ heapRetainedNow := heapRetained()
+
+ // If we're already below our goal, or within one page of our goal, then indicate
+ // that we don't need the background scavenger for maintaining a memory overhead
+ // proportional to the heap goal.
+ if heapRetainedNow <= gcPercentGoal || heapRetainedNow-gcPercentGoal < uint64(physPageSize) {
+ scavenge.gcPercentGoal.Store(^uint64(0))
+ } else {
+ scavenge.gcPercentGoal.Store(gcPercentGoal)
+ }
+}
+
+var scavenge struct {
+ // gcPercentGoal is the amount of retained heap memory (measured by
+ // heapRetained) that the runtime will try to maintain by returning
+ // memory to the OS. This goal is derived from gcController.gcPercent
+ // by choosing to retain enough memory to allocate heap memory up to
+ // the heap goal.
+ gcPercentGoal atomic.Uint64
+
+ // memoryLimitGoal is the amount of memory retained by the runtime (
+ // measured by gcController.mappedReady) that the runtime will try to
+ // maintain by returning memory to the OS. This goal is derived from
+ // gcController.memoryLimit by choosing to target the memory limit or
+ // some lower target to keep the scavenger working.
+ memoryLimitGoal atomic.Uint64
+
+ // assistTime is the time spent by the allocator scavenging in the last GC cycle.
+ //
+ // This is reset once a GC cycle ends.
+ assistTime atomic.Int64
+
+ // backgroundTime is the time spent by the background scavenger in the last GC cycle.
+ //
+ // This is reset once a GC cycle ends.
+ backgroundTime atomic.Int64
+}
+
+const (
+ // It doesn't really matter what value we start at, but we can't be zero, because
+ // that'll cause divide-by-zero issues. Pick something conservative which we'll
+ // also use as a fallback.
+ startingScavSleepRatio = 0.001
+
+ // Spend at least 1 ms scavenging, otherwise the corresponding
+ // sleep time to maintain our desired utilization is too low to
+ // be reliable.
+ minScavWorkTime = 1e6
+)
+
+// Sleep/wait state of the background scavenger.
+var scavenger scavengerState
+
+type scavengerState struct {
+ // lock protects all fields below.
+ lock mutex
+
+ // g is the goroutine the scavenger is bound to.
+ g *g
+
+ // parked is whether or not the scavenger is parked.
+ parked bool
+
+ // timer is the timer used for the scavenger to sleep.
+ timer *timer
+
+ // sysmonWake signals to sysmon that it should wake the scavenger.
+ sysmonWake atomic.Uint32
+
+ // targetCPUFraction is the target CPU overhead for the scavenger.
+ targetCPUFraction float64
+
+ // sleepRatio is the ratio of time spent doing scavenging work to
+ // time spent sleeping. This is used to decide how long the scavenger
+ // should sleep for in between batches of work. It is set by
+ // critSleepController in order to maintain a CPU overhead of
+ // targetCPUFraction.
+ //
+ // Lower means more sleep, higher means more aggressive scavenging.
+ sleepRatio float64
+
+ // sleepController controls sleepRatio.
+ //
+ // See sleepRatio for more details.
+ sleepController piController
+
+ // cooldown is the time left in nanoseconds during which we avoid
+ // using the controller and we hold sleepRatio at a conservative
+ // value. Used if the controller's assumptions fail to hold.
+ controllerCooldown int64
+
+ // printControllerReset instructs printScavTrace to signal that
+ // the controller was reset.
+ printControllerReset bool
+
+ // sleepStub is a stub used for testing to avoid actually having
+ // the scavenger sleep.
+ //
+ // Unlike the other stubs, this is not populated if left nil
+ // Instead, it is called when non-nil because any valid implementation
+ // of this function basically requires closing over this scavenger
+ // state, and allocating a closure is not allowed in the runtime as
+ // a matter of policy.
+ sleepStub func(n int64) int64
+
+ // scavenge is a function that scavenges n bytes of memory.
+ // Returns how many bytes of memory it actually scavenged, as
+ // well as the time it took in nanoseconds. Usually mheap.pages.scavenge
+ // with nanotime called around it, but stubbed out for testing.
+ // Like mheap.pages.scavenge, if it scavenges less than n bytes of
+ // memory, the caller may assume the heap is exhausted of scavengable
+ // memory for now.
+ //
+ // If this is nil, it is populated with the real thing in init.
+ scavenge func(n uintptr) (uintptr, int64)
+
+ // shouldStop is a callback called in the work loop and provides a
+ // point that can force the scavenger to stop early, for example because
+ // the scavenge policy dictates too much has been scavenged already.
+ //
+ // If this is nil, it is populated with the real thing in init.
+ shouldStop func() bool
+
+ // gomaxprocs returns the current value of gomaxprocs. Stub for testing.
+ //
+ // If this is nil, it is populated with the real thing in init.
+ gomaxprocs func() int32
+}
+
+// init initializes a scavenger state and wires to the current G.
+//
+// Must be called from a regular goroutine that can allocate.
+func (s *scavengerState) init() {
+ if s.g != nil {
+ throw("scavenger state is already wired")
+ }
+ lockInit(&s.lock, lockRankScavenge)
+ s.g = getg()
+
+ s.timer = new(timer)
+ s.timer.arg = s
+ s.timer.f = func(s any, _ uintptr) {
+ s.(*scavengerState).wake()
+ }
+
+ // input: fraction of CPU time actually used.
+ // setpoint: ideal CPU fraction.
+ // output: ratio of time worked to time slept (determines sleep time).
+ //
+ // The output of this controller is somewhat indirect to what we actually
+ // want to achieve: how much time to sleep for. The reason for this definition
+ // is to ensure that the controller's outputs have a direct relationship with
+ // its inputs (as opposed to an inverse relationship), making it somewhat
+ // easier to reason about for tuning purposes.
+ s.sleepController = piController{
+ // Tuned loosely via Ziegler-Nichols process.
+ kp: 0.3375,
+ ti: 3.2e6,
+ tt: 1e9, // 1 second reset time.
+
+ // These ranges seem wide, but we want to give the controller plenty of
+ // room to hunt for the optimal value.
+ min: 0.001, // 1:1000
+ max: 1000.0, // 1000:1
+ }
+ s.sleepRatio = startingScavSleepRatio
+
+ // Install real functions if stubs aren't present.
+ if s.scavenge == nil {
+ s.scavenge = func(n uintptr) (uintptr, int64) {
+ start := nanotime()
+ r := mheap_.pages.scavenge(n, nil, false)
+ end := nanotime()
+ if start >= end {
+ return r, 0
+ }
+ scavenge.backgroundTime.Add(end - start)
+ return r, end - start
+ }
+ }
+ if s.shouldStop == nil {
+ s.shouldStop = func() bool {
+ // If background scavenging is disabled or if there's no work to do just stop.
+ return heapRetained() <= scavenge.gcPercentGoal.Load() &&
+ gcController.mappedReady.Load() <= scavenge.memoryLimitGoal.Load()
+ }
+ }
+ if s.gomaxprocs == nil {
+ s.gomaxprocs = func() int32 {
+ return gomaxprocs
+ }
+ }
+}
+
+// park parks the scavenger goroutine.
+func (s *scavengerState) park() {
+ lock(&s.lock)
+ if getg() != s.g {
+ throw("tried to park scavenger from another goroutine")
+ }
+ s.parked = true
+ goparkunlock(&s.lock, waitReasonGCScavengeWait, traceBlockSystemGoroutine, 2)
+}
+
+// ready signals to sysmon that the scavenger should be awoken.
+func (s *scavengerState) ready() {
+ s.sysmonWake.Store(1)
+}
+
+// wake immediately unparks the scavenger if necessary.
+//
+// Safe to run without a P.
+func (s *scavengerState) wake() {
+ lock(&s.lock)
+ if s.parked {
+ // Unset sysmonWake, since the scavenger is now being awoken.
+ s.sysmonWake.Store(0)
+
+ // s.parked is unset to prevent a double wake-up.
+ s.parked = false
+
+ // Ready the goroutine by injecting it. We use injectglist instead
+ // of ready or goready in order to allow us to run this function
+ // without a P. injectglist also avoids placing the goroutine in
+ // the current P's runnext slot, which is desirable to prevent
+ // the scavenger from interfering with user goroutine scheduling
+ // too much.
+ var list gList
+ list.push(s.g)
+ injectglist(&list)
+ }
+ unlock(&s.lock)
+}
+
+// sleep puts the scavenger to sleep based on the amount of time that it worked
+// in nanoseconds.
+//
+// Note that this function should only be called by the scavenger.
+//
+// The scavenger may be woken up earlier by a pacing change, and it may not go
+// to sleep at all if there's a pending pacing change.
+func (s *scavengerState) sleep(worked float64) {
+ lock(&s.lock)
+ if getg() != s.g {
+ throw("tried to sleep scavenger from another goroutine")
+ }
+
+ if worked < minScavWorkTime {
+ // This means there wasn't enough work to actually fill up minScavWorkTime.
+ // That's fine; we shouldn't try to do anything with this information
+ // because it's going result in a short enough sleep request that things
+ // will get messy. Just assume we did at least this much work.
+ // All this means is that we'll sleep longer than we otherwise would have.
+ worked = minScavWorkTime
+ }
+
+ // Multiply the critical time by 1 + the ratio of the costs of using
+ // scavenged memory vs. scavenging memory. This forces us to pay down
+ // the cost of reusing this memory eagerly by sleeping for a longer period
+ // of time and scavenging less frequently. More concretely, we avoid situations
+ // where we end up scavenging so often that we hurt allocation performance
+ // because of the additional overheads of using scavenged memory.
+ worked *= 1 + scavengeCostRatio
+
+ // sleepTime is the amount of time we're going to sleep, based on the amount
+ // of time we worked, and the sleepRatio.
+ sleepTime := int64(worked / s.sleepRatio)
+
+ var slept int64
+ if s.sleepStub == nil {
+ // Set the timer.
+ //
+ // This must happen here instead of inside gopark
+ // because we can't close over any variables without
+ // failing escape analysis.
+ start := nanotime()
+ resetTimer(s.timer, start+sleepTime)
+
+ // Mark ourselves as asleep and go to sleep.
+ s.parked = true
+ goparkunlock(&s.lock, waitReasonSleep, traceBlockSleep, 2)
+
+ // How long we actually slept for.
+ slept = nanotime() - start
+
+ lock(&s.lock)
+ // Stop the timer here because s.wake is unable to do it for us.
+ // We don't really care if we succeed in stopping the timer. One
+ // reason we might fail is that we've already woken up, but the timer
+ // might be in the process of firing on some other P; essentially we're
+ // racing with it. That's totally OK. Double wake-ups are perfectly safe.
+ stopTimer(s.timer)
+ unlock(&s.lock)
+ } else {
+ unlock(&s.lock)
+ slept = s.sleepStub(sleepTime)
+ }
+
+ // Stop here if we're cooling down from the controller.
+ if s.controllerCooldown > 0 {
+ // worked and slept aren't exact measures of time, but it's OK to be a bit
+ // sloppy here. We're just hoping we're avoiding some transient bad behavior.
+ t := slept + int64(worked)
+ if t > s.controllerCooldown {
+ s.controllerCooldown = 0
+ } else {
+ s.controllerCooldown -= t
+ }
+ return
+ }
+
+ // idealFraction is the ideal % of overall application CPU time that we
+ // spend scavenging.
+ idealFraction := float64(scavengePercent) / 100.0
+
+ // Calculate the CPU time spent.
+ //
+ // This may be slightly inaccurate with respect to GOMAXPROCS, but we're
+ // recomputing this often enough relative to GOMAXPROCS changes in general
+ // (it only changes when the world is stopped, and not during a GC) that
+ // that small inaccuracy is in the noise.
+ cpuFraction := worked / ((float64(slept) + worked) * float64(s.gomaxprocs()))
+
+ // Update the critSleepRatio, adjusting until we reach our ideal fraction.
+ var ok bool
+ s.sleepRatio, ok = s.sleepController.next(cpuFraction, idealFraction, float64(slept)+worked)
+ if !ok {
+ // The core assumption of the controller, that we can get a proportional
+ // response, broke down. This may be transient, so temporarily switch to
+ // sleeping a fixed, conservative amount.
+ s.sleepRatio = startingScavSleepRatio
+ s.controllerCooldown = 5e9 // 5 seconds.
+
+ // Signal the scav trace printer to output this.
+ s.controllerFailed()
+ }
+}
+
+// controllerFailed indicates that the scavenger's scheduling
+// controller failed.
+func (s *scavengerState) controllerFailed() {
+ lock(&s.lock)
+ s.printControllerReset = true
+ unlock(&s.lock)
+}
+
+// run is the body of the main scavenging loop.
+//
+// Returns the number of bytes released and the estimated time spent
+// releasing those bytes.
+//
+// Must be run on the scavenger goroutine.
+func (s *scavengerState) run() (released uintptr, worked float64) {
+ lock(&s.lock)
+ if getg() != s.g {
+ throw("tried to run scavenger from another goroutine")
+ }
+ unlock(&s.lock)
+
+ for worked < minScavWorkTime {
+ // If something from outside tells us to stop early, stop.
+ if s.shouldStop() {
+ break
+ }
+
+ // scavengeQuantum is the amount of memory we try to scavenge
+ // in one go. A smaller value means the scavenger is more responsive
+ // to the scheduler in case of e.g. preemption. A larger value means
+ // that the overheads of scavenging are better amortized, so better
+ // scavenging throughput.
+ //
+ // The current value is chosen assuming a cost of ~10µs/physical page
+ // (this is somewhat pessimistic), which implies a worst-case latency of
+ // about 160µs for 4 KiB physical pages. The current value is biased
+ // toward latency over throughput.
+ const scavengeQuantum = 64 << 10
+
+ // Accumulate the amount of time spent scavenging.
+ r, duration := s.scavenge(scavengeQuantum)
+
+ // On some platforms we may see end >= start if the time it takes to scavenge
+ // memory is less than the minimum granularity of its clock (e.g. Windows) or
+ // due to clock bugs.
+ //
+ // In this case, just assume scavenging takes 10 µs per regular physical page
+ // (determined empirically), and conservatively ignore the impact of huge pages
+ // on timing.
+ const approxWorkedNSPerPhysicalPage = 10e3
+ if duration == 0 {
+ worked += approxWorkedNSPerPhysicalPage * float64(r/physPageSize)
+ } else {
+ // TODO(mknyszek): If duration is small compared to worked, it could be
+ // rounded down to zero. Probably not a problem in practice because the
+ // values are all within a few orders of magnitude of each other but maybe
+ // worth worrying about.
+ worked += float64(duration)
+ }
+ released += r
+
+ // scavenge does not return until it either finds the requisite amount of
+ // memory to scavenge, or exhausts the heap. If we haven't found enough
+ // to scavenge, then the heap must be exhausted.
+ if r < scavengeQuantum {
+ break
+ }
+ // When using fake time just do one loop.
+ if faketime != 0 {
+ break
+ }
+ }
+ if released > 0 && released < physPageSize {
+ // If this happens, it means that we may have attempted to release part
+ // of a physical page, but the likely effect of that is that it released
+ // the whole physical page, some of which may have still been in-use.
+ // This could lead to memory corruption. Throw.
+ throw("released less than one physical page of memory")
+ }
+ return
+}
+
+// Background scavenger.
+//
+// The background scavenger maintains the RSS of the application below
+// the line described by the proportional scavenging statistics in
+// the mheap struct.
+func bgscavenge(c chan int) {
+ scavenger.init()
+
+ c <- 1
+ scavenger.park()
+
+ for {
+ released, workTime := scavenger.run()
+ if released == 0 {
+ scavenger.park()
+ continue
+ }
+ mheap_.pages.scav.releasedBg.Add(released)
+ scavenger.sleep(workTime)
+ }
+}
+
+// scavenge scavenges nbytes worth of free pages, starting with the
+// highest address first. Successive calls continue from where it left
+// off until the heap is exhausted. force makes all memory available to
+// scavenge, ignoring huge page heuristics.
+//
+// Returns the amount of memory scavenged in bytes.
+//
+// scavenge always tries to scavenge nbytes worth of memory, and will
+// only fail to do so if the heap is exhausted for now.
+func (p *pageAlloc) scavenge(nbytes uintptr, shouldStop func() bool, force bool) uintptr {
+ released := uintptr(0)
+ for released < nbytes {
+ ci, pageIdx := p.scav.index.find(force)
+ if ci == 0 {
+ break
+ }
+ systemstack(func() {
+ released += p.scavengeOne(ci, pageIdx, nbytes-released)
+ })
+ if shouldStop != nil && shouldStop() {
+ break
+ }
+ }
+ return released
+}
+
+// printScavTrace prints a scavenge trace line to standard error.
+//
+// released should be the amount of memory released since the last time this
+// was called, and forced indicates whether the scavenge was forced by the
+// application.
+//
+// scavenger.lock must be held.
+func printScavTrace(releasedBg, releasedEager uintptr, forced bool) {
+ assertLockHeld(&scavenger.lock)
+
+ printlock()
+ print("scav ",
+ releasedBg>>10, " KiB work (bg), ",
+ releasedEager>>10, " KiB work (eager), ",
+ gcController.heapReleased.load()>>10, " KiB now, ",
+ (gcController.heapInUse.load()*100)/heapRetained(), "% util",
+ )
+ if forced {
+ print(" (forced)")
+ } else if scavenger.printControllerReset {
+ print(" [controller reset]")
+ scavenger.printControllerReset = false
+ }
+ println()
+ printunlock()
+}
+
+// scavengeOne walks over the chunk at chunk index ci and searches for
+// a contiguous run of pages to scavenge. It will try to scavenge
+// at most max bytes at once, but may scavenge more to avoid
+// breaking huge pages. Once it scavenges some memory it returns
+// how much it scavenged in bytes.
+//
+// searchIdx is the page index to start searching from in ci.
+//
+// Returns the number of bytes scavenged.
+//
+// Must run on the systemstack because it acquires p.mheapLock.
+//
+//go:systemstack
+func (p *pageAlloc) scavengeOne(ci chunkIdx, searchIdx uint, max uintptr) uintptr {
+ // Calculate the maximum number of pages to scavenge.
+ //
+ // This should be alignUp(max, pageSize) / pageSize but max can and will
+ // be ^uintptr(0), so we need to be very careful not to overflow here.
+ // Rather than use alignUp, calculate the number of pages rounded down
+ // first, then add back one if necessary.
+ maxPages := max / pageSize
+ if max%pageSize != 0 {
+ maxPages++
+ }
+
+ // Calculate the minimum number of pages we can scavenge.
+ //
+ // Because we can only scavenge whole physical pages, we must
+ // ensure that we scavenge at least minPages each time, aligned
+ // to minPages*pageSize.
+ minPages := physPageSize / pageSize
+ if minPages < 1 {
+ minPages = 1
+ }
+
+ lock(p.mheapLock)
+ if p.summary[len(p.summary)-1][ci].max() >= uint(minPages) {
+ // We only bother looking for a candidate if there at least
+ // minPages free pages at all.
+ base, npages := p.chunkOf(ci).findScavengeCandidate(searchIdx, minPages, maxPages)
+
+ // If we found something, scavenge it and return!
+ if npages != 0 {
+ // Compute the full address for the start of the range.
+ addr := chunkBase(ci) + uintptr(base)*pageSize
+
+ // Mark the range we're about to scavenge as allocated, because
+ // we don't want any allocating goroutines to grab it while
+ // the scavenging is in progress. Be careful here -- just do the
+ // bare minimum to avoid stepping on our own scavenging stats.
+ p.chunkOf(ci).allocRange(base, npages)
+ p.update(addr, uintptr(npages), true, true)
+
+ // Grab whether the chunk is hugepage backed and if it is,
+ // clear it. We're about to break up this huge page.
+ p.scav.index.setNoHugePage(ci)
+
+ // With that done, it's safe to unlock.
+ unlock(p.mheapLock)
+
+ if !p.test {
+ pageTraceScav(getg().m.p.ptr(), 0, addr, uintptr(npages))
+
+ // Only perform sys* operations if we're not in a test.
+ // It's dangerous to do so otherwise.
+ sysUnused(unsafe.Pointer(addr), uintptr(npages)*pageSize)
+
+ // Update global accounting only when not in test, otherwise
+ // the runtime's accounting will be wrong.
+ nbytes := int64(npages * pageSize)
+ gcController.heapReleased.add(nbytes)
+ gcController.heapFree.add(-nbytes)
+
+ stats := memstats.heapStats.acquire()
+ atomic.Xaddint64(&stats.committed, -nbytes)
+ atomic.Xaddint64(&stats.released, nbytes)
+ memstats.heapStats.release()
+ }
+
+ // Relock the heap, because now we need to make these pages
+ // available allocation. Free them back to the page allocator.
+ lock(p.mheapLock)
+ if b := (offAddr{addr}); b.lessThan(p.searchAddr) {
+ p.searchAddr = b
+ }
+ p.chunkOf(ci).free(base, npages)
+ p.update(addr, uintptr(npages), true, false)
+
+ // Mark the range as scavenged.
+ p.chunkOf(ci).scavenged.setRange(base, npages)
+ unlock(p.mheapLock)
+
+ return uintptr(npages) * pageSize
+ }
+ }
+ // Mark this chunk as having no free pages.
+ p.scav.index.setEmpty(ci)
+ unlock(p.mheapLock)
+
+ return 0
+}
+
+// fillAligned returns x but with all zeroes in m-aligned
+// groups of m bits set to 1 if any bit in the group is non-zero.
+//
+// For example, fillAligned(0x0100a3, 8) == 0xff00ff.
+//
+// Note that if m == 1, this is a no-op.
+//
+// m must be a power of 2 <= maxPagesPerPhysPage.
+func fillAligned(x uint64, m uint) uint64 {
+ apply := func(x uint64, c uint64) uint64 {
+ // The technique used it here is derived from
+ // https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
+ // and extended for more than just bytes (like nibbles
+ // and uint16s) by using an appropriate constant.
+ //
+ // To summarize the technique, quoting from that page:
+ // "[It] works by first zeroing the high bits of the [8]
+ // bytes in the word. Subsequently, it adds a number that
+ // will result in an overflow to the high bit of a byte if
+ // any of the low bits were initially set. Next the high
+ // bits of the original word are ORed with these values;
+ // thus, the high bit of a byte is set iff any bit in the
+ // byte was set. Finally, we determine if any of these high
+ // bits are zero by ORing with ones everywhere except the
+ // high bits and inverting the result."
+ return ^((((x & c) + c) | x) | c)
+ }
+ // Transform x to contain a 1 bit at the top of each m-aligned
+ // group of m zero bits.
+ switch m {
+ case 1:
+ return x
+ case 2:
+ x = apply(x, 0x5555555555555555)
+ case 4:
+ x = apply(x, 0x7777777777777777)
+ case 8:
+ x = apply(x, 0x7f7f7f7f7f7f7f7f)
+ case 16:
+ x = apply(x, 0x7fff7fff7fff7fff)
+ case 32:
+ x = apply(x, 0x7fffffff7fffffff)
+ case 64: // == maxPagesPerPhysPage
+ x = apply(x, 0x7fffffffffffffff)
+ default:
+ throw("bad m value")
+ }
+ // Now, the top bit of each m-aligned group in x is set
+ // that group was all zero in the original x.
+
+ // From each group of m bits subtract 1.
+ // Because we know only the top bits of each
+ // m-aligned group are set, we know this will
+ // set each group to have all the bits set except
+ // the top bit, so just OR with the original
+ // result to set all the bits.
+ return ^((x - (x >> (m - 1))) | x)
+}
+
+// findScavengeCandidate returns a start index and a size for this pallocData
+// segment which represents a contiguous region of free and unscavenged memory.
+//
+// searchIdx indicates the page index within this chunk to start the search, but
+// note that findScavengeCandidate searches backwards through the pallocData. As
+// a result, it will return the highest scavenge candidate in address order.
+//
+// min indicates a hard minimum size and alignment for runs of pages. That is,
+// findScavengeCandidate will not return a region smaller than min pages in size,
+// or that is min pages or greater in size but not aligned to min. min must be
+// a non-zero power of 2 <= maxPagesPerPhysPage.
+//
+// max is a hint for how big of a region is desired. If max >= pallocChunkPages, then
+// findScavengeCandidate effectively returns entire free and unscavenged regions.
+// If max < pallocChunkPages, it may truncate the returned region such that size is
+// max. However, findScavengeCandidate may still return a larger region if, for
+// example, it chooses to preserve huge pages, or if max is not aligned to min (it
+// will round up). That is, even if max is small, the returned size is not guaranteed
+// to be equal to max. max is allowed to be less than min, in which case it is as if
+// max == min.
+func (m *pallocData) findScavengeCandidate(searchIdx uint, min, max uintptr) (uint, uint) {
+ if min&(min-1) != 0 || min == 0 {
+ print("runtime: min = ", min, "\n")
+ throw("min must be a non-zero power of 2")
+ } else if min > maxPagesPerPhysPage {
+ print("runtime: min = ", min, "\n")
+ throw("min too large")
+ }
+ // max may not be min-aligned, so we might accidentally truncate to
+ // a max value which causes us to return a non-min-aligned value.
+ // To prevent this, align max up to a multiple of min (which is always
+ // a power of 2). This also prevents max from ever being less than
+ // min, unless it's zero, so handle that explicitly.
+ if max == 0 {
+ max = min
+ } else {
+ max = alignUp(max, min)
+ }
+
+ i := int(searchIdx / 64)
+ // Start by quickly skipping over blocks of non-free or scavenged pages.
+ for ; i >= 0; i-- {
+ // 1s are scavenged OR non-free => 0s are unscavenged AND free
+ x := fillAligned(m.scavenged[i]|m.pallocBits[i], uint(min))
+ if x != ^uint64(0) {
+ break
+ }
+ }
+ if i < 0 {
+ // Failed to find any free/unscavenged pages.
+ return 0, 0
+ }
+ // We have something in the 64-bit chunk at i, but it could
+ // extend further. Loop until we find the extent of it.
+
+ // 1s are scavenged OR non-free => 0s are unscavenged AND free
+ x := fillAligned(m.scavenged[i]|m.pallocBits[i], uint(min))
+ z1 := uint(sys.LeadingZeros64(^x))
+ run, end := uint(0), uint(i)*64+(64-z1)
+ if x<<z1 != 0 {
+ // After shifting out z1 bits, we still have 1s,
+ // so the run ends inside this word.
+ run = uint(sys.LeadingZeros64(x << z1))
+ } else {
+ // After shifting out z1 bits, we have no more 1s.
+ // This means the run extends to the bottom of the
+ // word so it may extend into further words.
+ run = 64 - z1
+ for j := i - 1; j >= 0; j-- {
+ x := fillAligned(m.scavenged[j]|m.pallocBits[j], uint(min))
+ run += uint(sys.LeadingZeros64(x))
+ if x != 0 {
+ // The run stopped in this word.
+ break
+ }
+ }
+ }
+
+ // Split the run we found if it's larger than max but hold on to
+ // our original length, since we may need it later.
+ size := run
+ if size > uint(max) {
+ size = uint(max)
+ }
+ start := end - size
+
+ // Each huge page is guaranteed to fit in a single palloc chunk.
+ //
+ // TODO(mknyszek): Support larger huge page sizes.
+ // TODO(mknyszek): Consider taking pages-per-huge-page as a parameter
+ // so we can write tests for this.
+ if physHugePageSize > pageSize && physHugePageSize > physPageSize {
+ // We have huge pages, so let's ensure we don't break one by scavenging
+ // over a huge page boundary. If the range [start, start+size) overlaps with
+ // a free-and-unscavenged huge page, we want to grow the region we scavenge
+ // to include that huge page.
+
+ // Compute the huge page boundary above our candidate.
+ pagesPerHugePage := uintptr(physHugePageSize / pageSize)
+ hugePageAbove := uint(alignUp(uintptr(start), pagesPerHugePage))
+
+ // If that boundary is within our current candidate, then we may be breaking
+ // a huge page.
+ if hugePageAbove <= end {
+ // Compute the huge page boundary below our candidate.
+ hugePageBelow := uint(alignDown(uintptr(start), pagesPerHugePage))
+
+ if hugePageBelow >= end-run {
+ // We're in danger of breaking apart a huge page since start+size crosses
+ // a huge page boundary and rounding down start to the nearest huge
+ // page boundary is included in the full run we found. Include the entire
+ // huge page in the bound by rounding down to the huge page size.
+ size = size + (start - hugePageBelow)
+ start = hugePageBelow
+ }
+ }
+ }
+ return start, size
+}
+
+// scavengeIndex is a structure for efficiently managing which pageAlloc chunks have
+// memory available to scavenge.
+type scavengeIndex struct {
+ // chunks is a scavChunkData-per-chunk structure that indicates the presence of pages
+ // available for scavenging. Updates to the index are serialized by the pageAlloc lock.
+ //
+ // It tracks chunk occupancy and a generation counter per chunk. If a chunk's occupancy
+ // never exceeds pallocChunkDensePages over the course of a single GC cycle, the chunk
+ // becomes eligible for scavenging on the next cycle. If a chunk ever hits this density
+ // threshold it immediately becomes unavailable for scavenging in the current cycle as
+ // well as the next.
+ //
+ // [min, max) represents the range of chunks that is safe to access (i.e. will not cause
+ // a fault). As an optimization minHeapIdx represents the true minimum chunk that has been
+ // mapped, since min is likely rounded down to include the system page containing minHeapIdx.
+ //
+ // For a chunk size of 4 MiB this structure will only use 2 MiB for a 1 TiB contiguous heap.
+ chunks []atomicScavChunkData
+ min, max atomic.Uintptr
+ minHeapIdx atomic.Uintptr
+
+ // searchAddr* is the maximum address (in the offset address space, so we have a linear
+ // view of the address space; see mranges.go:offAddr) containing memory available to
+ // scavenge. It is a hint to the find operation to avoid O(n^2) behavior in repeated lookups.
+ //
+ // searchAddr* is always inclusive and should be the base address of the highest runtime
+ // page available for scavenging.
+ //
+ // searchAddrForce is managed by find and free.
+ // searchAddrBg is managed by find and nextGen.
+ //
+ // Normally, find monotonically decreases searchAddr* as it finds no more free pages to
+ // scavenge. However, mark, when marking a new chunk at an index greater than the current
+ // searchAddr, sets searchAddr to the *negative* index into chunks of that page. The trick here
+ // is that concurrent calls to find will fail to monotonically decrease searchAddr*, and so they
+ // won't barge over new memory becoming available to scavenge. Furthermore, this ensures
+ // that some future caller of find *must* observe the new high index. That caller
+ // (or any other racing with it), then makes searchAddr positive before continuing, bringing
+ // us back to our monotonically decreasing steady-state.
+ //
+ // A pageAlloc lock serializes updates between min, max, and searchAddr, so abs(searchAddr)
+ // is always guaranteed to be >= min and < max (converted to heap addresses).
+ //
+ // searchAddrBg is increased only on each new generation and is mainly used by the
+ // background scavenger and heap-growth scavenging. searchAddrForce is increased continuously
+ // as memory gets freed and is mainly used by eager memory reclaim such as debug.FreeOSMemory
+ // and scavenging to maintain the memory limit.
+ searchAddrBg atomicOffAddr
+ searchAddrForce atomicOffAddr
+
+ // freeHWM is the highest address (in offset address space) that was freed
+ // this generation.
+ freeHWM offAddr
+
+ // Generation counter. Updated by nextGen at the end of each mark phase.
+ gen uint32
+
+ // test indicates whether or not we're in a test.
+ test bool
+}
+
+// init initializes the scavengeIndex.
+//
+// Returns the amount added to sysStat.
+func (s *scavengeIndex) init(test bool, sysStat *sysMemStat) uintptr {
+ s.searchAddrBg.Clear()
+ s.searchAddrForce.Clear()
+ s.freeHWM = minOffAddr
+ s.test = test
+ return s.sysInit(test, sysStat)
+}
+
+// sysGrow updates the index's backing store in response to a heap growth.
+//
+// Returns the amount of memory added to sysStat.
+func (s *scavengeIndex) grow(base, limit uintptr, sysStat *sysMemStat) uintptr {
+ // Update minHeapIdx. Note that even if there's no mapping work to do,
+ // we may still have a new, lower minimum heap address.
+ minHeapIdx := s.minHeapIdx.Load()
+ if baseIdx := uintptr(chunkIndex(base)); minHeapIdx == 0 || baseIdx < minHeapIdx {
+ s.minHeapIdx.Store(baseIdx)
+ }
+ return s.sysGrow(base, limit, sysStat)
+}
+
+// find returns the highest chunk index that may contain pages available to scavenge.
+// It also returns an offset to start searching in the highest chunk.
+func (s *scavengeIndex) find(force bool) (chunkIdx, uint) {
+ cursor := &s.searchAddrBg
+ if force {
+ cursor = &s.searchAddrForce
+ }
+ searchAddr, marked := cursor.Load()
+ if searchAddr == minOffAddr.addr() {
+ // We got a cleared search addr.
+ return 0, 0
+ }
+
+ // Starting from searchAddr's chunk, iterate until we find a chunk with pages to scavenge.
+ gen := s.gen
+ min := chunkIdx(s.minHeapIdx.Load())
+ start := chunkIndex(uintptr(searchAddr))
+ // N.B. We'll never map the 0'th chunk, so minHeapIdx ensures this loop overflow.
+ for i := start; i >= min; i-- {
+ // Skip over chunks.
+ if !s.chunks[i].load().shouldScavenge(gen, force) {
+ continue
+ }
+ // We're still scavenging this chunk.
+ if i == start {
+ return i, chunkPageIndex(uintptr(searchAddr))
+ }
+ // Try to reduce searchAddr to newSearchAddr.
+ newSearchAddr := chunkBase(i) + pallocChunkBytes - pageSize
+ if marked {
+ // Attempt to be the first one to decrease the searchAddr
+ // after an increase. If we fail, that means there was another
+ // increase, or somebody else got to it before us. Either way,
+ // it doesn't matter. We may lose some performance having an
+ // incorrect search address, but it's far more important that
+ // we don't miss updates.
+ cursor.StoreUnmark(searchAddr, newSearchAddr)
+ } else {
+ // Decrease searchAddr.
+ cursor.StoreMin(newSearchAddr)
+ }
+ return i, pallocChunkPages - 1
+ }
+ // Clear searchAddr, because we've exhausted the heap.
+ cursor.Clear()
+ return 0, 0
+}
+
+// alloc updates metadata for chunk at index ci with the fact that
+// an allocation of npages occurred. It also eagerly attempts to collapse
+// the chunk's memory into hugepage if the chunk has become sufficiently
+// dense and we're not allocating the whole chunk at once (which suggests
+// the allocation is part of a bigger one and it's probably not worth
+// eagerly collapsing).
+//
+// alloc may only run concurrently with find.
+func (s *scavengeIndex) alloc(ci chunkIdx, npages uint) {
+ sc := s.chunks[ci].load()
+ sc.alloc(npages, s.gen)
+ if !sc.isHugePage() && sc.inUse > scavChunkHiOccPages {
+ // Mark that we're considering this chunk as backed by huge pages.
+ sc.setHugePage()
+
+ // Collapse dense chunks into huge pages and mark that
+ // we did that, but only if we're not allocating to
+ // use the entire chunk. If we're allocating an entire chunk,
+ // this is likely part of a much bigger allocation. For
+ // instance, if the caller is allocating a 1 GiB slice of bytes, we
+ // don't want to go and manually collapse all those pages; we want
+ // them to be demand-paged. If the caller is actually going to use
+ // all that memory, it'll naturally get backed by huge pages later.
+ //
+ // This also avoids having sysHugePageCollapse fail. On Linux,
+ // the call requires that some part of the huge page being collapsed
+ // is already paged in.
+ if !s.test && npages < pallocChunkPages {
+ sysHugePageCollapse(unsafe.Pointer(chunkBase(ci)), pallocChunkBytes)
+ }
+ }
+ s.chunks[ci].store(sc)
+}
+
+// free updates metadata for chunk at index ci with the fact that
+// a free of npages occurred.
+//
+// free may only run concurrently with find.
+func (s *scavengeIndex) free(ci chunkIdx, page, npages uint) {
+ sc := s.chunks[ci].load()
+ sc.free(npages, s.gen)
+ s.chunks[ci].store(sc)
+
+ // Update scavenge search addresses.
+ addr := chunkBase(ci) + uintptr(page+npages-1)*pageSize
+ if s.freeHWM.lessThan(offAddr{addr}) {
+ s.freeHWM = offAddr{addr}
+ }
+ // N.B. Because free is serialized, it's not necessary to do a
+ // full CAS here. free only ever increases searchAddr, while
+ // find only ever decreases it. Since we only ever race with
+ // decreases, even if the value we loaded is stale, the actual
+ // value will never be larger.
+ searchAddr, _ := s.searchAddrForce.Load()
+ if (offAddr{searchAddr}).lessThan(offAddr{addr}) {
+ s.searchAddrForce.StoreMarked(addr)
+ }
+}
+
+// nextGen moves the scavenger forward one generation. Must be called
+// once per GC cycle, but may be called more often to force more memory
+// to be released.
+//
+// nextGen may only run concurrently with find.
+func (s *scavengeIndex) nextGen() {
+ s.gen++
+ searchAddr, _ := s.searchAddrBg.Load()
+ if (offAddr{searchAddr}).lessThan(s.freeHWM) {
+ s.searchAddrBg.StoreMarked(s.freeHWM.addr())
+ }
+ s.freeHWM = minOffAddr
+}
+
+// setEmpty marks that the scavenger has finished looking at ci
+// for now to prevent the scavenger from getting stuck looking
+// at the same chunk.
+//
+// setEmpty may only run concurrently with find.
+func (s *scavengeIndex) setEmpty(ci chunkIdx) {
+ val := s.chunks[ci].load()
+ val.setEmpty()
+ s.chunks[ci].store(val)
+}
+
+// setNoHugePage updates the backed-by-hugepages status of a particular chunk.
+// Returns true if the set was successful (not already backed by huge pages).
+//
+// setNoHugePage may only run concurrently with find.
+func (s *scavengeIndex) setNoHugePage(ci chunkIdx) {
+ val := s.chunks[ci].load()
+ if !val.isHugePage() {
+ return
+ }
+ val.setNoHugePage()
+ s.chunks[ci].store(val)
+}
+
+// atomicScavChunkData is an atomic wrapper around a scavChunkData
+// that stores it in its packed form.
+type atomicScavChunkData struct {
+ value atomic.Uint64
+}
+
+// load loads and unpacks a scavChunkData.
+func (sc *atomicScavChunkData) load() scavChunkData {
+ return unpackScavChunkData(sc.value.Load())
+}
+
+// store packs and writes a new scavChunkData. store must be serialized
+// with other calls to store.
+func (sc *atomicScavChunkData) store(ssc scavChunkData) {
+ sc.value.Store(ssc.pack())
+}
+
+// scavChunkData tracks information about a palloc chunk for
+// scavenging. It packs well into 64 bits.
+//
+// The zero value always represents a valid newly-grown chunk.
+type scavChunkData struct {
+ // inUse indicates how many pages in this chunk are currently
+ // allocated.
+ //
+ // Only the first 10 bits are used.
+ inUse uint16
+
+ // lastInUse indicates how many pages in this chunk were allocated
+ // when we transitioned from gen-1 to gen.
+ //
+ // Only the first 10 bits are used.
+ lastInUse uint16
+
+ // gen is the generation counter from a scavengeIndex from the
+ // last time this scavChunkData was updated.
+ gen uint32
+
+ // scavChunkFlags represents additional flags
+ //
+ // Note: only 6 bits are available.
+ scavChunkFlags
+}
+
+// unpackScavChunkData unpacks a scavChunkData from a uint64.
+func unpackScavChunkData(sc uint64) scavChunkData {
+ return scavChunkData{
+ inUse: uint16(sc),
+ lastInUse: uint16(sc>>16) & scavChunkInUseMask,
+ gen: uint32(sc >> 32),
+ scavChunkFlags: scavChunkFlags(uint8(sc>>(16+logScavChunkInUseMax)) & scavChunkFlagsMask),
+ }
+}
+
+// pack returns sc packed into a uint64.
+func (sc scavChunkData) pack() uint64 {
+ return uint64(sc.inUse) |
+ (uint64(sc.lastInUse) << 16) |
+ (uint64(sc.scavChunkFlags) << (16 + logScavChunkInUseMax)) |
+ (uint64(sc.gen) << 32)
+}
+
+const (
+ // scavChunkHasFree indicates whether the chunk has anything left to
+ // scavenge. This is the opposite of "empty," used elsewhere in this
+ // file. The reason we say "HasFree" here is so the zero value is
+ // correct for a newly-grown chunk. (New memory is scavenged.)
+ scavChunkHasFree scavChunkFlags = 1 << iota
+ // scavChunkNoHugePage indicates whether this chunk has had any huge
+ // pages broken by the scavenger.
+ //.
+ // The negative here is unfortunate, but necessary to make it so that
+ // the zero value of scavChunkData accurately represents the state of
+ // a newly-grown chunk. (New memory is marked as backed by huge pages.)
+ scavChunkNoHugePage
+
+ // scavChunkMaxFlags is the maximum number of flags we can have, given how
+ // a scavChunkData is packed into 8 bytes.
+ scavChunkMaxFlags = 6
+ scavChunkFlagsMask = (1 << scavChunkMaxFlags) - 1
+
+ // logScavChunkInUseMax is the number of bits needed to represent the number
+ // of pages allocated in a single chunk. This is 1 more than log2 of the
+ // number of pages in the chunk because we need to represent a fully-allocated
+ // chunk.
+ logScavChunkInUseMax = logPallocChunkPages + 1
+ scavChunkInUseMask = (1 << logScavChunkInUseMax) - 1
+)
+
+// scavChunkFlags is a set of bit-flags for the scavenger for each palloc chunk.
+type scavChunkFlags uint8
+
+// isEmpty returns true if the hasFree flag is unset.
+func (sc *scavChunkFlags) isEmpty() bool {
+ return (*sc)&scavChunkHasFree == 0
+}
+
+// setEmpty clears the hasFree flag.
+func (sc *scavChunkFlags) setEmpty() {
+ *sc &^= scavChunkHasFree
+}
+
+// setNonEmpty sets the hasFree flag.
+func (sc *scavChunkFlags) setNonEmpty() {
+ *sc |= scavChunkHasFree
+}
+
+// isHugePage returns false if the noHugePage flag is set.
+func (sc *scavChunkFlags) isHugePage() bool {
+ return (*sc)&scavChunkNoHugePage == 0
+}
+
+// setHugePage clears the noHugePage flag.
+func (sc *scavChunkFlags) setHugePage() {
+ *sc &^= scavChunkNoHugePage
+}
+
+// setNoHugePage sets the noHugePage flag.
+func (sc *scavChunkFlags) setNoHugePage() {
+ *sc |= scavChunkNoHugePage
+}
+
+// shouldScavenge returns true if the corresponding chunk should be interrogated
+// by the scavenger.
+func (sc scavChunkData) shouldScavenge(currGen uint32, force bool) bool {
+ if sc.isEmpty() {
+ // Nothing to scavenge.
+ return false
+ }
+ if force {
+ // We're forcing the memory to be scavenged.
+ return true
+ }
+ if sc.gen == currGen {
+ // In the current generation, if either the current or last generation
+ // is dense, then skip scavenging. Inverting that, we should scavenge
+ // if both the current and last generation were not dense.
+ return sc.inUse < scavChunkHiOccPages && sc.lastInUse < scavChunkHiOccPages
+ }
+ // If we're one or more generations ahead, we know inUse represents the current
+ // state of the chunk, since otherwise it would've been updated already.
+ return sc.inUse < scavChunkHiOccPages
+}
+
+// alloc updates sc given that npages were allocated in the corresponding chunk.
+func (sc *scavChunkData) alloc(npages uint, newGen uint32) {
+ if uint(sc.inUse)+npages > pallocChunkPages {
+ print("runtime: inUse=", sc.inUse, " npages=", npages, "\n")
+ throw("too many pages allocated in chunk?")
+ }
+ if sc.gen != newGen {
+ sc.lastInUse = sc.inUse
+ sc.gen = newGen
+ }
+ sc.inUse += uint16(npages)
+ if sc.inUse == pallocChunkPages {
+ // There's nothing for the scavenger to take from here.
+ sc.setEmpty()
+ }
+}
+
+// free updates sc given that npages was freed in the corresponding chunk.
+func (sc *scavChunkData) free(npages uint, newGen uint32) {
+ if uint(sc.inUse) < npages {
+ print("runtime: inUse=", sc.inUse, " npages=", npages, "\n")
+ throw("allocated pages below zero?")
+ }
+ if sc.gen != newGen {
+ sc.lastInUse = sc.inUse
+ sc.gen = newGen
+ }
+ sc.inUse -= uint16(npages)
+ // The scavenger can no longer be done with this chunk now that
+ // new memory has been freed into it.
+ sc.setNonEmpty()
+}
+
+type piController struct {
+ kp float64 // Proportional constant.
+ ti float64 // Integral time constant.
+ tt float64 // Reset time.
+
+ min, max float64 // Output boundaries.
+
+ // PI controller state.
+
+ errIntegral float64 // Integral of the error from t=0 to now.
+
+ // Error flags.
+ errOverflow bool // Set if errIntegral ever overflowed.
+ inputOverflow bool // Set if an operation with the input overflowed.
+}
+
+// next provides a new sample to the controller.
+//
+// input is the sample, setpoint is the desired point, and period is how much
+// time (in whatever unit makes the most sense) has passed since the last sample.
+//
+// Returns a new value for the variable it's controlling, and whether the operation
+// completed successfully. One reason this might fail is if error has been growing
+// in an unbounded manner, to the point of overflow.
+//
+// In the specific case of an error overflow occurs, the errOverflow field will be
+// set and the rest of the controller's internal state will be fully reset.
+func (c *piController) next(input, setpoint, period float64) (float64, bool) {
+ // Compute the raw output value.
+ prop := c.kp * (setpoint - input)
+ rawOutput := prop + c.errIntegral
+
+ // Clamp rawOutput into output.
+ output := rawOutput
+ if isInf(output) || isNaN(output) {
+ // The input had a large enough magnitude that either it was already
+ // overflowed, or some operation with it overflowed.
+ // Set a flag and reset. That's the safest thing to do.
+ c.reset()
+ c.inputOverflow = true
+ return c.min, false
+ }
+ if output < c.min {
+ output = c.min
+ } else if output > c.max {
+ output = c.max
+ }
+
+ // Update the controller's state.
+ if c.ti != 0 && c.tt != 0 {
+ c.errIntegral += (c.kp*period/c.ti)*(setpoint-input) + (period/c.tt)*(output-rawOutput)
+ if isInf(c.errIntegral) || isNaN(c.errIntegral) {
+ // So much error has accumulated that we managed to overflow.
+ // The assumptions around the controller have likely broken down.
+ // Set a flag and reset. That's the safest thing to do.
+ c.reset()
+ c.errOverflow = true
+ return c.min, false
+ }
+ }
+ return output, true
+}
+
+// reset resets the controller state, except for controller error flags.
+func (c *piController) reset() {
+ c.errIntegral = 0
+}
diff --git a/contrib/go/_std_1.20/src/runtime/mgcstack.go b/contrib/go/_std_1.21/src/runtime/mgcstack.go
index 6b552203ee..6b552203ee 100644
--- a/contrib/go/_std_1.20/src/runtime/mgcstack.go
+++ b/contrib/go/_std_1.21/src/runtime/mgcstack.go
diff --git a/contrib/go/_std_1.21/src/runtime/mgcsweep.go b/contrib/go/_std_1.21/src/runtime/mgcsweep.go
new file mode 100644
index 0000000000..68f1aae600
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mgcsweep.go
@@ -0,0 +1,982 @@
+// Copyright 2009 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.
+
+// Garbage collector: sweeping
+
+// The sweeper consists of two different algorithms:
+//
+// * The object reclaimer finds and frees unmarked slots in spans. It
+// can free a whole span if none of the objects are marked, but that
+// isn't its goal. This can be driven either synchronously by
+// mcentral.cacheSpan for mcentral spans, or asynchronously by
+// sweepone, which looks at all the mcentral lists.
+//
+// * The span reclaimer looks for spans that contain no marked objects
+// and frees whole spans. This is a separate algorithm because
+// freeing whole spans is the hardest task for the object reclaimer,
+// but is critical when allocating new spans. The entry point for
+// this is mheap_.reclaim and it's driven by a sequential scan of
+// the page marks bitmap in the heap arenas.
+//
+// Both algorithms ultimately call mspan.sweep, which sweeps a single
+// heap span.
+
+package runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+var sweep sweepdata
+
+// State of background sweep.
+type sweepdata struct {
+ lock mutex
+ g *g
+ parked bool
+
+ nbgsweep uint32
+ npausesweep uint32
+
+ // active tracks outstanding sweepers and the sweep
+ // termination condition.
+ active activeSweep
+
+ // centralIndex is the current unswept span class.
+ // It represents an index into the mcentral span
+ // sets. Accessed and updated via its load and
+ // update methods. Not protected by a lock.
+ //
+ // Reset at mark termination.
+ // Used by mheap.nextSpanForSweep.
+ centralIndex sweepClass
+}
+
+// sweepClass is a spanClass and one bit to represent whether we're currently
+// sweeping partial or full spans.
+type sweepClass uint32
+
+const (
+ numSweepClasses = numSpanClasses * 2
+ sweepClassDone sweepClass = sweepClass(^uint32(0))
+)
+
+func (s *sweepClass) load() sweepClass {
+ return sweepClass(atomic.Load((*uint32)(s)))
+}
+
+func (s *sweepClass) update(sNew sweepClass) {
+ // Only update *s if its current value is less than sNew,
+ // since *s increases monotonically.
+ sOld := s.load()
+ for sOld < sNew && !atomic.Cas((*uint32)(s), uint32(sOld), uint32(sNew)) {
+ sOld = s.load()
+ }
+ // TODO(mknyszek): This isn't the only place we have
+ // an atomic monotonically increasing counter. It would
+ // be nice to have an "atomic max" which is just implemented
+ // as the above on most architectures. Some architectures
+ // like RISC-V however have native support for an atomic max.
+}
+
+func (s *sweepClass) clear() {
+ atomic.Store((*uint32)(s), 0)
+}
+
+// split returns the underlying span class as well as
+// whether we're interested in the full or partial
+// unswept lists for that class, indicated as a boolean
+// (true means "full").
+func (s sweepClass) split() (spc spanClass, full bool) {
+ return spanClass(s >> 1), s&1 == 0
+}
+
+// nextSpanForSweep finds and pops the next span for sweeping from the
+// central sweep buffers. It returns ownership of the span to the caller.
+// Returns nil if no such span exists.
+func (h *mheap) nextSpanForSweep() *mspan {
+ sg := h.sweepgen
+ for sc := sweep.centralIndex.load(); sc < numSweepClasses; sc++ {
+ spc, full := sc.split()
+ c := &h.central[spc].mcentral
+ var s *mspan
+ if full {
+ s = c.fullUnswept(sg).pop()
+ } else {
+ s = c.partialUnswept(sg).pop()
+ }
+ if s != nil {
+ // Write down that we found something so future sweepers
+ // can start from here.
+ sweep.centralIndex.update(sc)
+ return s
+ }
+ }
+ // Write down that we found nothing.
+ sweep.centralIndex.update(sweepClassDone)
+ return nil
+}
+
+const sweepDrainedMask = 1 << 31
+
+// activeSweep is a type that captures whether sweeping
+// is done, and whether there are any outstanding sweepers.
+//
+// Every potential sweeper must call begin() before they look
+// for work, and end() after they've finished sweeping.
+type activeSweep struct {
+ // state is divided into two parts.
+ //
+ // The top bit (masked by sweepDrainedMask) is a boolean
+ // value indicating whether all the sweep work has been
+ // drained from the queue.
+ //
+ // The rest of the bits are a counter, indicating the
+ // number of outstanding concurrent sweepers.
+ state atomic.Uint32
+}
+
+// begin registers a new sweeper. Returns a sweepLocker
+// for acquiring spans for sweeping. Any outstanding sweeper blocks
+// sweep termination.
+//
+// If the sweepLocker is invalid, the caller can be sure that all
+// outstanding sweep work has been drained, so there is nothing left
+// to sweep. Note that there may be sweepers currently running, so
+// this does not indicate that all sweeping has completed.
+//
+// Even if the sweepLocker is invalid, its sweepGen is always valid.
+func (a *activeSweep) begin() sweepLocker {
+ for {
+ state := a.state.Load()
+ if state&sweepDrainedMask != 0 {
+ return sweepLocker{mheap_.sweepgen, false}
+ }
+ if a.state.CompareAndSwap(state, state+1) {
+ return sweepLocker{mheap_.sweepgen, true}
+ }
+ }
+}
+
+// end deregisters a sweeper. Must be called once for each time
+// begin is called if the sweepLocker is valid.
+func (a *activeSweep) end(sl sweepLocker) {
+ if sl.sweepGen != mheap_.sweepgen {
+ throw("sweeper left outstanding across sweep generations")
+ }
+ for {
+ state := a.state.Load()
+ if (state&^sweepDrainedMask)-1 >= sweepDrainedMask {
+ throw("mismatched begin/end of activeSweep")
+ }
+ if a.state.CompareAndSwap(state, state-1) {
+ if state != sweepDrainedMask {
+ return
+ }
+ if debug.gcpacertrace > 0 {
+ live := gcController.heapLive.Load()
+ print("pacer: sweep done at heap size ", live>>20, "MB; allocated ", (live-mheap_.sweepHeapLiveBasis)>>20, "MB during sweep; swept ", mheap_.pagesSwept.Load(), " pages at ", mheap_.sweepPagesPerByte, " pages/byte\n")
+ }
+ return
+ }
+ }
+}
+
+// markDrained marks the active sweep cycle as having drained
+// all remaining work. This is safe to be called concurrently
+// with all other methods of activeSweep, though may race.
+//
+// Returns true if this call was the one that actually performed
+// the mark.
+func (a *activeSweep) markDrained() bool {
+ for {
+ state := a.state.Load()
+ if state&sweepDrainedMask != 0 {
+ return false
+ }
+ if a.state.CompareAndSwap(state, state|sweepDrainedMask) {
+ return true
+ }
+ }
+}
+
+// sweepers returns the current number of active sweepers.
+func (a *activeSweep) sweepers() uint32 {
+ return a.state.Load() &^ sweepDrainedMask
+}
+
+// isDone returns true if all sweep work has been drained and no more
+// outstanding sweepers exist. That is, when the sweep phase is
+// completely done.
+func (a *activeSweep) isDone() bool {
+ return a.state.Load() == sweepDrainedMask
+}
+
+// reset sets up the activeSweep for the next sweep cycle.
+//
+// The world must be stopped.
+func (a *activeSweep) reset() {
+ assertWorldStopped()
+ a.state.Store(0)
+}
+
+// finishsweep_m ensures that all spans are swept.
+//
+// The world must be stopped. This ensures there are no sweeps in
+// progress.
+//
+//go:nowritebarrier
+func finishsweep_m() {
+ assertWorldStopped()
+
+ // Sweeping must be complete before marking commences, so
+ // sweep any unswept spans. If this is a concurrent GC, there
+ // shouldn't be any spans left to sweep, so this should finish
+ // instantly. If GC was forced before the concurrent sweep
+ // finished, there may be spans to sweep.
+ for sweepone() != ^uintptr(0) {
+ sweep.npausesweep++
+ }
+
+ // Make sure there aren't any outstanding sweepers left.
+ // At this point, with the world stopped, it means one of two
+ // things. Either we were able to preempt a sweeper, or that
+ // a sweeper didn't call sweep.active.end when it should have.
+ // Both cases indicate a bug, so throw.
+ if sweep.active.sweepers() != 0 {
+ throw("active sweepers found at start of mark phase")
+ }
+
+ // Reset all the unswept buffers, which should be empty.
+ // Do this in sweep termination as opposed to mark termination
+ // so that we can catch unswept spans and reclaim blocks as
+ // soon as possible.
+ sg := mheap_.sweepgen
+ for i := range mheap_.central {
+ c := &mheap_.central[i].mcentral
+ c.partialUnswept(sg).reset()
+ c.fullUnswept(sg).reset()
+ }
+
+ // Sweeping is done, so there won't be any new memory to
+ // scavenge for a bit.
+ //
+ // If the scavenger isn't already awake, wake it up. There's
+ // definitely work for it to do at this point.
+ scavenger.wake()
+
+ nextMarkBitArenaEpoch()
+}
+
+func bgsweep(c chan int) {
+ sweep.g = getg()
+
+ lockInit(&sweep.lock, lockRankSweep)
+ lock(&sweep.lock)
+ sweep.parked = true
+ c <- 1
+ goparkunlock(&sweep.lock, waitReasonGCSweepWait, traceBlockGCSweep, 1)
+
+ for {
+ // bgsweep attempts to be a "low priority" goroutine by intentionally
+ // yielding time. It's OK if it doesn't run, because goroutines allocating
+ // memory will sweep and ensure that all spans are swept before the next
+ // GC cycle. We really only want to run when we're idle.
+ //
+ // However, calling Gosched after each span swept produces a tremendous
+ // amount of tracing events, sometimes up to 50% of events in a trace. It's
+ // also inefficient to call into the scheduler so much because sweeping a
+ // single span is in general a very fast operation, taking as little as 30 ns
+ // on modern hardware. (See #54767.)
+ //
+ // As a result, bgsweep sweeps in batches, and only calls into the scheduler
+ // at the end of every batch. Furthermore, it only yields its time if there
+ // isn't spare idle time available on other cores. If there's available idle
+ // time, helping to sweep can reduce allocation latencies by getting ahead of
+ // the proportional sweeper and having spans ready to go for allocation.
+ const sweepBatchSize = 10
+ nSwept := 0
+ for sweepone() != ^uintptr(0) {
+ sweep.nbgsweep++
+ nSwept++
+ if nSwept%sweepBatchSize == 0 {
+ goschedIfBusy()
+ }
+ }
+ for freeSomeWbufs(true) {
+ // N.B. freeSomeWbufs is already batched internally.
+ goschedIfBusy()
+ }
+ lock(&sweep.lock)
+ if !isSweepDone() {
+ // This can happen if a GC runs between
+ // gosweepone returning ^0 above
+ // and the lock being acquired.
+ unlock(&sweep.lock)
+ continue
+ }
+ sweep.parked = true
+ goparkunlock(&sweep.lock, waitReasonGCSweepWait, traceBlockGCSweep, 1)
+ }
+}
+
+// sweepLocker acquires sweep ownership of spans.
+type sweepLocker struct {
+ // sweepGen is the sweep generation of the heap.
+ sweepGen uint32
+ valid bool
+}
+
+// sweepLocked represents sweep ownership of a span.
+type sweepLocked struct {
+ *mspan
+}
+
+// tryAcquire attempts to acquire sweep ownership of span s. If it
+// successfully acquires ownership, it blocks sweep completion.
+func (l *sweepLocker) tryAcquire(s *mspan) (sweepLocked, bool) {
+ if !l.valid {
+ throw("use of invalid sweepLocker")
+ }
+ // Check before attempting to CAS.
+ if atomic.Load(&s.sweepgen) != l.sweepGen-2 {
+ return sweepLocked{}, false
+ }
+ // Attempt to acquire sweep ownership of s.
+ if !atomic.Cas(&s.sweepgen, l.sweepGen-2, l.sweepGen-1) {
+ return sweepLocked{}, false
+ }
+ return sweepLocked{s}, true
+}
+
+// sweepone sweeps some unswept heap span and returns the number of pages returned
+// to the heap, or ^uintptr(0) if there was nothing to sweep.
+func sweepone() uintptr {
+ gp := getg()
+
+ // Increment locks to ensure that the goroutine is not preempted
+ // in the middle of sweep thus leaving the span in an inconsistent state for next GC
+ gp.m.locks++
+
+ // TODO(austin): sweepone is almost always called in a loop;
+ // lift the sweepLocker into its callers.
+ sl := sweep.active.begin()
+ if !sl.valid {
+ gp.m.locks--
+ return ^uintptr(0)
+ }
+
+ // Find a span to sweep.
+ npages := ^uintptr(0)
+ var noMoreWork bool
+ for {
+ s := mheap_.nextSpanForSweep()
+ if s == nil {
+ noMoreWork = sweep.active.markDrained()
+ break
+ }
+ if state := s.state.get(); state != mSpanInUse {
+ // This can happen if direct sweeping already
+ // swept this span, but in that case the sweep
+ // generation should always be up-to-date.
+ if !(s.sweepgen == sl.sweepGen || s.sweepgen == sl.sweepGen+3) {
+ print("runtime: bad span s.state=", state, " s.sweepgen=", s.sweepgen, " sweepgen=", sl.sweepGen, "\n")
+ throw("non in-use span in unswept list")
+ }
+ continue
+ }
+ if s, ok := sl.tryAcquire(s); ok {
+ // Sweep the span we found.
+ npages = s.npages
+ if s.sweep(false) {
+ // Whole span was freed. Count it toward the
+ // page reclaimer credit since these pages can
+ // now be used for span allocation.
+ mheap_.reclaimCredit.Add(npages)
+ } else {
+ // Span is still in-use, so this returned no
+ // pages to the heap and the span needs to
+ // move to the swept in-use list.
+ npages = 0
+ }
+ break
+ }
+ }
+ sweep.active.end(sl)
+
+ if noMoreWork {
+ // The sweep list is empty. There may still be
+ // concurrent sweeps running, but we're at least very
+ // close to done sweeping.
+
+ // Move the scavenge gen forward (signaling
+ // that there's new work to do) and wake the scavenger.
+ //
+ // The scavenger is signaled by the last sweeper because once
+ // sweeping is done, we will definitely have useful work for
+ // the scavenger to do, since the scavenger only runs over the
+ // heap once per GC cycle. This update is not done during sweep
+ // termination because in some cases there may be a long delay
+ // between sweep done and sweep termination (e.g. not enough
+ // allocations to trigger a GC) which would be nice to fill in
+ // with scavenging work.
+ if debug.scavtrace > 0 {
+ systemstack(func() {
+ lock(&mheap_.lock)
+
+ // Get released stats.
+ releasedBg := mheap_.pages.scav.releasedBg.Load()
+ releasedEager := mheap_.pages.scav.releasedEager.Load()
+
+ // Print the line.
+ printScavTrace(releasedBg, releasedEager, false)
+
+ // Update the stats.
+ mheap_.pages.scav.releasedBg.Add(-releasedBg)
+ mheap_.pages.scav.releasedEager.Add(-releasedEager)
+ unlock(&mheap_.lock)
+ })
+ }
+ scavenger.ready()
+ }
+
+ gp.m.locks--
+ return npages
+}
+
+// isSweepDone reports whether all spans are swept.
+//
+// Note that this condition may transition from false to true at any
+// time as the sweeper runs. It may transition from true to false if a
+// GC runs; to prevent that the caller must be non-preemptible or must
+// somehow block GC progress.
+func isSweepDone() bool {
+ return sweep.active.isDone()
+}
+
+// Returns only when span s has been swept.
+//
+//go:nowritebarrier
+func (s *mspan) ensureSwept() {
+ // Caller must disable preemption.
+ // Otherwise when this function returns the span can become unswept again
+ // (if GC is triggered on another goroutine).
+ gp := getg()
+ if gp.m.locks == 0 && gp.m.mallocing == 0 && gp != gp.m.g0 {
+ throw("mspan.ensureSwept: m is not locked")
+ }
+
+ // If this operation fails, then that means that there are
+ // no more spans to be swept. In this case, either s has already
+ // been swept, or is about to be acquired for sweeping and swept.
+ sl := sweep.active.begin()
+ if sl.valid {
+ // The caller must be sure that the span is a mSpanInUse span.
+ if s, ok := sl.tryAcquire(s); ok {
+ s.sweep(false)
+ sweep.active.end(sl)
+ return
+ }
+ sweep.active.end(sl)
+ }
+
+ // Unfortunately we can't sweep the span ourselves. Somebody else
+ // got to it first. We don't have efficient means to wait, but that's
+ // OK, it will be swept fairly soon.
+ for {
+ spangen := atomic.Load(&s.sweepgen)
+ if spangen == sl.sweepGen || spangen == sl.sweepGen+3 {
+ break
+ }
+ osyield()
+ }
+}
+
+// sweep frees or collects finalizers for blocks not marked in the mark phase.
+// It clears the mark bits in preparation for the next GC round.
+// Returns true if the span was returned to heap.
+// If preserve=true, don't return it to heap nor relink in mcentral lists;
+// caller takes care of it.
+func (sl *sweepLocked) sweep(preserve bool) bool {
+ // It's critical that we enter this function with preemption disabled,
+ // GC must not start while we are in the middle of this function.
+ gp := getg()
+ if gp.m.locks == 0 && gp.m.mallocing == 0 && gp != gp.m.g0 {
+ throw("mspan.sweep: m is not locked")
+ }
+
+ s := sl.mspan
+ if !preserve {
+ // We'll release ownership of this span. Nil it out to
+ // prevent the caller from accidentally using it.
+ sl.mspan = nil
+ }
+
+ sweepgen := mheap_.sweepgen
+ if state := s.state.get(); state != mSpanInUse || s.sweepgen != sweepgen-1 {
+ print("mspan.sweep: state=", state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n")
+ throw("mspan.sweep: bad span state")
+ }
+
+ if traceEnabled() {
+ traceGCSweepSpan(s.npages * _PageSize)
+ }
+
+ mheap_.pagesSwept.Add(int64(s.npages))
+
+ spc := s.spanclass
+ size := s.elemsize
+
+ // The allocBits indicate which unmarked objects don't need to be
+ // processed since they were free at the end of the last GC cycle
+ // and were not allocated since then.
+ // If the allocBits index is >= s.freeindex and the bit
+ // is not marked then the object remains unallocated
+ // since the last GC.
+ // This situation is analogous to being on a freelist.
+
+ // Unlink & free special records for any objects we're about to free.
+ // Two complications here:
+ // 1. An object can have both finalizer and profile special records.
+ // In such case we need to queue finalizer for execution,
+ // mark the object as live and preserve the profile special.
+ // 2. A tiny object can have several finalizers setup for different offsets.
+ // If such object is not marked, we need to queue all finalizers at once.
+ // Both 1 and 2 are possible at the same time.
+ hadSpecials := s.specials != nil
+ siter := newSpecialsIter(s)
+ for siter.valid() {
+ // A finalizer can be set for an inner byte of an object, find object beginning.
+ objIndex := uintptr(siter.s.offset) / size
+ p := s.base() + objIndex*size
+ mbits := s.markBitsForIndex(objIndex)
+ if !mbits.isMarked() {
+ // This object is not marked and has at least one special record.
+ // Pass 1: see if it has at least one finalizer.
+ hasFin := false
+ endOffset := p - s.base() + size
+ for tmp := siter.s; tmp != nil && uintptr(tmp.offset) < endOffset; tmp = tmp.next {
+ if tmp.kind == _KindSpecialFinalizer {
+ // Stop freeing of object if it has a finalizer.
+ mbits.setMarkedNonAtomic()
+ hasFin = true
+ break
+ }
+ }
+ // Pass 2: queue all finalizers _or_ handle profile record.
+ for siter.valid() && uintptr(siter.s.offset) < endOffset {
+ // Find the exact byte for which the special was setup
+ // (as opposed to object beginning).
+ special := siter.s
+ p := s.base() + uintptr(special.offset)
+ if special.kind == _KindSpecialFinalizer || !hasFin {
+ siter.unlinkAndNext()
+ freeSpecial(special, unsafe.Pointer(p), size)
+ } else {
+ // The object has finalizers, so we're keeping it alive.
+ // All other specials only apply when an object is freed,
+ // so just keep the special record.
+ siter.next()
+ }
+ }
+ } else {
+ // object is still live
+ if siter.s.kind == _KindSpecialReachable {
+ special := siter.unlinkAndNext()
+ (*specialReachable)(unsafe.Pointer(special)).reachable = true
+ freeSpecial(special, unsafe.Pointer(p), size)
+ } else {
+ // keep special record
+ siter.next()
+ }
+ }
+ }
+ if hadSpecials && s.specials == nil {
+ spanHasNoSpecials(s)
+ }
+
+ if debug.allocfreetrace != 0 || debug.clobberfree != 0 || raceenabled || msanenabled || asanenabled {
+ // Find all newly freed objects. This doesn't have to
+ // efficient; allocfreetrace has massive overhead.
+ mbits := s.markBitsForBase()
+ abits := s.allocBitsForIndex(0)
+ for i := uintptr(0); i < s.nelems; i++ {
+ if !mbits.isMarked() && (abits.index < s.freeindex || abits.isMarked()) {
+ x := s.base() + i*s.elemsize
+ if debug.allocfreetrace != 0 {
+ tracefree(unsafe.Pointer(x), size)
+ }
+ if debug.clobberfree != 0 {
+ clobberfree(unsafe.Pointer(x), size)
+ }
+ // User arenas are handled on explicit free.
+ if raceenabled && !s.isUserArenaChunk {
+ racefree(unsafe.Pointer(x), size)
+ }
+ if msanenabled && !s.isUserArenaChunk {
+ msanfree(unsafe.Pointer(x), size)
+ }
+ if asanenabled && !s.isUserArenaChunk {
+ asanpoison(unsafe.Pointer(x), size)
+ }
+ }
+ mbits.advance()
+ abits.advance()
+ }
+ }
+
+ // Check for zombie objects.
+ if s.freeindex < s.nelems {
+ // Everything < freeindex is allocated and hence
+ // cannot be zombies.
+ //
+ // Check the first bitmap byte, where we have to be
+ // careful with freeindex.
+ obj := s.freeindex
+ if (*s.gcmarkBits.bytep(obj / 8)&^*s.allocBits.bytep(obj / 8))>>(obj%8) != 0 {
+ s.reportZombies()
+ }
+ // Check remaining bytes.
+ for i := obj/8 + 1; i < divRoundUp(s.nelems, 8); i++ {
+ if *s.gcmarkBits.bytep(i)&^*s.allocBits.bytep(i) != 0 {
+ s.reportZombies()
+ }
+ }
+ }
+
+ // Count the number of free objects in this span.
+ nalloc := uint16(s.countAlloc())
+ nfreed := s.allocCount - nalloc
+ if nalloc > s.allocCount {
+ // The zombie check above should have caught this in
+ // more detail.
+ print("runtime: nelems=", s.nelems, " nalloc=", nalloc, " previous allocCount=", s.allocCount, " nfreed=", nfreed, "\n")
+ throw("sweep increased allocation count")
+ }
+
+ s.allocCount = nalloc
+ s.freeindex = 0 // reset allocation index to start of span.
+ s.freeIndexForScan = 0
+ if traceEnabled() {
+ getg().m.p.ptr().trace.reclaimed += uintptr(nfreed) * s.elemsize
+ }
+
+ // gcmarkBits becomes the allocBits.
+ // get a fresh cleared gcmarkBits in preparation for next GC
+ s.allocBits = s.gcmarkBits
+ s.gcmarkBits = newMarkBits(s.nelems)
+
+ // refresh pinnerBits if they exists
+ if s.pinnerBits != nil {
+ s.refreshPinnerBits()
+ }
+
+ // Initialize alloc bits cache.
+ s.refillAllocCache(0)
+
+ // The span must be in our exclusive ownership until we update sweepgen,
+ // check for potential races.
+ if state := s.state.get(); state != mSpanInUse || s.sweepgen != sweepgen-1 {
+ print("mspan.sweep: state=", state, " sweepgen=", s.sweepgen, " mheap.sweepgen=", sweepgen, "\n")
+ throw("mspan.sweep: bad span state after sweep")
+ }
+ if s.sweepgen == sweepgen+1 || s.sweepgen == sweepgen+3 {
+ throw("swept cached span")
+ }
+
+ // We need to set s.sweepgen = h.sweepgen only when all blocks are swept,
+ // because of the potential for a concurrent free/SetFinalizer.
+ //
+ // But we need to set it before we make the span available for allocation
+ // (return it to heap or mcentral), because allocation code assumes that a
+ // span is already swept if available for allocation.
+ //
+ // Serialization point.
+ // At this point the mark bits are cleared and allocation ready
+ // to go so release the span.
+ atomic.Store(&s.sweepgen, sweepgen)
+
+ if s.isUserArenaChunk {
+ if preserve {
+ // This is a case that should never be handled by a sweeper that
+ // preserves the span for reuse.
+ throw("sweep: tried to preserve a user arena span")
+ }
+ if nalloc > 0 {
+ // There still exist pointers into the span or the span hasn't been
+ // freed yet. It's not ready to be reused. Put it back on the
+ // full swept list for the next cycle.
+ mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s)
+ return false
+ }
+
+ // It's only at this point that the sweeper doesn't actually need to look
+ // at this arena anymore, so subtract from pagesInUse now.
+ mheap_.pagesInUse.Add(-s.npages)
+ s.state.set(mSpanDead)
+
+ // The arena is ready to be recycled. Remove it from the quarantine list
+ // and place it on the ready list. Don't add it back to any sweep lists.
+ systemstack(func() {
+ // It's the arena code's responsibility to get the chunk on the quarantine
+ // list by the time all references to the chunk are gone.
+ if s.list != &mheap_.userArena.quarantineList {
+ throw("user arena span is on the wrong list")
+ }
+ lock(&mheap_.lock)
+ mheap_.userArena.quarantineList.remove(s)
+ mheap_.userArena.readyList.insert(s)
+ unlock(&mheap_.lock)
+ })
+ return false
+ }
+
+ if spc.sizeclass() != 0 {
+ // Handle spans for small objects.
+ if nfreed > 0 {
+ // Only mark the span as needing zeroing if we've freed any
+ // objects, because a fresh span that had been allocated into,
+ // wasn't totally filled, but then swept, still has all of its
+ // free slots zeroed.
+ s.needzero = 1
+ stats := memstats.heapStats.acquire()
+ atomic.Xadd64(&stats.smallFreeCount[spc.sizeclass()], int64(nfreed))
+ memstats.heapStats.release()
+
+ // Count the frees in the inconsistent, internal stats.
+ gcController.totalFree.Add(int64(nfreed) * int64(s.elemsize))
+ }
+ if !preserve {
+ // The caller may not have removed this span from whatever
+ // unswept set its on but taken ownership of the span for
+ // sweeping by updating sweepgen. If this span still is in
+ // an unswept set, then the mcentral will pop it off the
+ // set, check its sweepgen, and ignore it.
+ if nalloc == 0 {
+ // Free totally free span directly back to the heap.
+ mheap_.freeSpan(s)
+ return true
+ }
+ // Return span back to the right mcentral list.
+ if uintptr(nalloc) == s.nelems {
+ mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s)
+ } else {
+ mheap_.central[spc].mcentral.partialSwept(sweepgen).push(s)
+ }
+ }
+ } else if !preserve {
+ // Handle spans for large objects.
+ if nfreed != 0 {
+ // Free large object span to heap.
+
+ // NOTE(rsc,dvyukov): The original implementation of efence
+ // in CL 22060046 used sysFree instead of sysFault, so that
+ // the operating system would eventually give the memory
+ // back to us again, so that an efence program could run
+ // longer without running out of memory. Unfortunately,
+ // calling sysFree here without any kind of adjustment of the
+ // heap data structures means that when the memory does
+ // come back to us, we have the wrong metadata for it, either in
+ // the mspan structures or in the garbage collection bitmap.
+ // Using sysFault here means that the program will run out of
+ // memory fairly quickly in efence mode, but at least it won't
+ // have mysterious crashes due to confused memory reuse.
+ // It should be possible to switch back to sysFree if we also
+ // implement and then call some kind of mheap.deleteSpan.
+ if debug.efence > 0 {
+ s.limit = 0 // prevent mlookup from finding this span
+ sysFault(unsafe.Pointer(s.base()), size)
+ } else {
+ mheap_.freeSpan(s)
+ }
+
+ // Count the free in the consistent, external stats.
+ stats := memstats.heapStats.acquire()
+ atomic.Xadd64(&stats.largeFreeCount, 1)
+ atomic.Xadd64(&stats.largeFree, int64(size))
+ memstats.heapStats.release()
+
+ // Count the free in the inconsistent, internal stats.
+ gcController.totalFree.Add(int64(size))
+
+ return true
+ }
+
+ // Add a large span directly onto the full+swept list.
+ mheap_.central[spc].mcentral.fullSwept(sweepgen).push(s)
+ }
+ return false
+}
+
+// reportZombies reports any marked but free objects in s and throws.
+//
+// This generally means one of the following:
+//
+// 1. User code converted a pointer to a uintptr and then back
+// unsafely, and a GC ran while the uintptr was the only reference to
+// an object.
+//
+// 2. User code (or a compiler bug) constructed a bad pointer that
+// points to a free slot, often a past-the-end pointer.
+//
+// 3. The GC two cycles ago missed a pointer and freed a live object,
+// but it was still live in the last cycle, so this GC cycle found a
+// pointer to that object and marked it.
+func (s *mspan) reportZombies() {
+ printlock()
+ print("runtime: marked free object in span ", s, ", elemsize=", s.elemsize, " freeindex=", s.freeindex, " (bad use of unsafe.Pointer? try -d=checkptr)\n")
+ mbits := s.markBitsForBase()
+ abits := s.allocBitsForIndex(0)
+ for i := uintptr(0); i < s.nelems; i++ {
+ addr := s.base() + i*s.elemsize
+ print(hex(addr))
+ alloc := i < s.freeindex || abits.isMarked()
+ if alloc {
+ print(" alloc")
+ } else {
+ print(" free ")
+ }
+ if mbits.isMarked() {
+ print(" marked ")
+ } else {
+ print(" unmarked")
+ }
+ zombie := mbits.isMarked() && !alloc
+ if zombie {
+ print(" zombie")
+ }
+ print("\n")
+ if zombie {
+ length := s.elemsize
+ if length > 1024 {
+ length = 1024
+ }
+ hexdumpWords(addr, addr+length, nil)
+ }
+ mbits.advance()
+ abits.advance()
+ }
+ throw("found pointer to free object")
+}
+
+// deductSweepCredit deducts sweep credit for allocating a span of
+// size spanBytes. This must be performed *before* the span is
+// allocated to ensure the system has enough credit. If necessary, it
+// performs sweeping to prevent going in to debt. If the caller will
+// also sweep pages (e.g., for a large allocation), it can pass a
+// non-zero callerSweepPages to leave that many pages unswept.
+//
+// deductSweepCredit makes a worst-case assumption that all spanBytes
+// bytes of the ultimately allocated span will be available for object
+// allocation.
+//
+// deductSweepCredit is the core of the "proportional sweep" system.
+// It uses statistics gathered by the garbage collector to perform
+// enough sweeping so that all pages are swept during the concurrent
+// sweep phase between GC cycles.
+//
+// mheap_ must NOT be locked.
+func deductSweepCredit(spanBytes uintptr, callerSweepPages uintptr) {
+ if mheap_.sweepPagesPerByte == 0 {
+ // Proportional sweep is done or disabled.
+ return
+ }
+
+ if traceEnabled() {
+ traceGCSweepStart()
+ }
+
+ // Fix debt if necessary.
+retry:
+ sweptBasis := mheap_.pagesSweptBasis.Load()
+ live := gcController.heapLive.Load()
+ liveBasis := mheap_.sweepHeapLiveBasis
+ newHeapLive := spanBytes
+ if liveBasis < live {
+ // Only do this subtraction when we don't overflow. Otherwise, pagesTarget
+ // might be computed as something really huge, causing us to get stuck
+ // sweeping here until the next mark phase.
+ //
+ // Overflow can happen here if gcPaceSweeper is called concurrently with
+ // sweeping (i.e. not during a STW, like it usually is) because this code
+ // is intentionally racy. A concurrent call to gcPaceSweeper can happen
+ // if a GC tuning parameter is modified and we read an older value of
+ // heapLive than what was used to set the basis.
+ //
+ // This state should be transient, so it's fine to just let newHeapLive
+ // be a relatively small number. We'll probably just skip this attempt to
+ // sweep.
+ //
+ // See issue #57523.
+ newHeapLive += uintptr(live - liveBasis)
+ }
+ pagesTarget := int64(mheap_.sweepPagesPerByte*float64(newHeapLive)) - int64(callerSweepPages)
+ for pagesTarget > int64(mheap_.pagesSwept.Load()-sweptBasis) {
+ if sweepone() == ^uintptr(0) {
+ mheap_.sweepPagesPerByte = 0
+ break
+ }
+ if mheap_.pagesSweptBasis.Load() != sweptBasis {
+ // Sweep pacing changed. Recompute debt.
+ goto retry
+ }
+ }
+
+ if traceEnabled() {
+ traceGCSweepDone()
+ }
+}
+
+// clobberfree sets the memory content at x to bad content, for debugging
+// purposes.
+func clobberfree(x unsafe.Pointer, size uintptr) {
+ // size (span.elemsize) is always a multiple of 4.
+ for i := uintptr(0); i < size; i += 4 {
+ *(*uint32)(add(x, i)) = 0xdeadbeef
+ }
+}
+
+// gcPaceSweeper updates the sweeper's pacing parameters.
+//
+// Must be called whenever the GC's pacing is updated.
+//
+// The world must be stopped, or mheap_.lock must be held.
+func gcPaceSweeper(trigger uint64) {
+ assertWorldStoppedOrLockHeld(&mheap_.lock)
+
+ // Update sweep pacing.
+ if isSweepDone() {
+ mheap_.sweepPagesPerByte = 0
+ } else {
+ // Concurrent sweep needs to sweep all of the in-use
+ // pages by the time the allocated heap reaches the GC
+ // trigger. Compute the ratio of in-use pages to sweep
+ // per byte allocated, accounting for the fact that
+ // some might already be swept.
+ heapLiveBasis := gcController.heapLive.Load()
+ heapDistance := int64(trigger) - int64(heapLiveBasis)
+ // Add a little margin so rounding errors and
+ // concurrent sweep are less likely to leave pages
+ // unswept when GC starts.
+ heapDistance -= 1024 * 1024
+ if heapDistance < _PageSize {
+ // Avoid setting the sweep ratio extremely high
+ heapDistance = _PageSize
+ }
+ pagesSwept := mheap_.pagesSwept.Load()
+ pagesInUse := mheap_.pagesInUse.Load()
+ sweepDistancePages := int64(pagesInUse) - int64(pagesSwept)
+ if sweepDistancePages <= 0 {
+ mheap_.sweepPagesPerByte = 0
+ } else {
+ mheap_.sweepPagesPerByte = float64(sweepDistancePages) / float64(heapDistance)
+ mheap_.sweepHeapLiveBasis = heapLiveBasis
+ // Write pagesSweptBasis last, since this
+ // signals concurrent sweeps to recompute
+ // their debt.
+ mheap_.pagesSweptBasis.Store(pagesSwept)
+ }
+ }
+}
diff --git a/contrib/go/_std_1.20/src/runtime/mgcwork.go b/contrib/go/_std_1.21/src/runtime/mgcwork.go
index 7ab89754d4..7ab89754d4 100644
--- a/contrib/go/_std_1.20/src/runtime/mgcwork.go
+++ b/contrib/go/_std_1.21/src/runtime/mgcwork.go
diff --git a/contrib/go/_std_1.21/src/runtime/mheap.go b/contrib/go/_std_1.21/src/runtime/mheap.go
new file mode 100644
index 0000000000..f836d91c6a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mheap.go
@@ -0,0 +1,2260 @@
+// Copyright 2009 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.
+
+// Page heap.
+//
+// See malloc.go for overview.
+
+package runtime
+
+import (
+ "internal/cpu"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+const (
+ // minPhysPageSize is a lower-bound on the physical page size. The
+ // true physical page size may be larger than this. In contrast,
+ // sys.PhysPageSize is an upper-bound on the physical page size.
+ minPhysPageSize = 4096
+
+ // maxPhysPageSize is the maximum page size the runtime supports.
+ maxPhysPageSize = 512 << 10
+
+ // maxPhysHugePageSize sets an upper-bound on the maximum huge page size
+ // that the runtime supports.
+ maxPhysHugePageSize = pallocChunkBytes
+
+ // pagesPerReclaimerChunk indicates how many pages to scan from the
+ // pageInUse bitmap at a time. Used by the page reclaimer.
+ //
+ // Higher values reduce contention on scanning indexes (such as
+ // h.reclaimIndex), but increase the minimum latency of the
+ // operation.
+ //
+ // The time required to scan this many pages can vary a lot depending
+ // on how many spans are actually freed. Experimentally, it can
+ // scan for pages at ~300 GB/ms on a 2.6GHz Core i7, but can only
+ // free spans at ~32 MB/ms. Using 512 pages bounds this at
+ // roughly 100µs.
+ //
+ // Must be a multiple of the pageInUse bitmap element size and
+ // must also evenly divide pagesPerArena.
+ pagesPerReclaimerChunk = 512
+
+ // physPageAlignedStacks indicates whether stack allocations must be
+ // physical page aligned. This is a requirement for MAP_STACK on
+ // OpenBSD.
+ physPageAlignedStacks = GOOS == "openbsd"
+)
+
+// Main malloc heap.
+// The heap itself is the "free" and "scav" treaps,
+// but all the other global data is here too.
+//
+// mheap must not be heap-allocated because it contains mSpanLists,
+// which must not be heap-allocated.
+type mheap struct {
+ _ sys.NotInHeap
+
+ // lock must only be acquired on the system stack, otherwise a g
+ // could self-deadlock if its stack grows with the lock held.
+ lock mutex
+
+ pages pageAlloc // page allocation data structure
+
+ sweepgen uint32 // sweep generation, see comment in mspan; written during STW
+
+ // allspans is a slice of all mspans ever created. Each mspan
+ // appears exactly once.
+ //
+ // The memory for allspans is manually managed and can be
+ // reallocated and move as the heap grows.
+ //
+ // In general, allspans is protected by mheap_.lock, which
+ // prevents concurrent access as well as freeing the backing
+ // store. Accesses during STW might not hold the lock, but
+ // must ensure that allocation cannot happen around the
+ // access (since that may free the backing store).
+ allspans []*mspan // all spans out there
+
+ // Proportional sweep
+ //
+ // These parameters represent a linear function from gcController.heapLive
+ // to page sweep count. The proportional sweep system works to
+ // stay in the black by keeping the current page sweep count
+ // above this line at the current gcController.heapLive.
+ //
+ // The line has slope sweepPagesPerByte and passes through a
+ // basis point at (sweepHeapLiveBasis, pagesSweptBasis). At
+ // any given time, the system is at (gcController.heapLive,
+ // pagesSwept) in this space.
+ //
+ // It is important that the line pass through a point we
+ // control rather than simply starting at a 0,0 origin
+ // because that lets us adjust sweep pacing at any time while
+ // accounting for current progress. If we could only adjust
+ // the slope, it would create a discontinuity in debt if any
+ // progress has already been made.
+ pagesInUse atomic.Uintptr // pages of spans in stats mSpanInUse
+ pagesSwept atomic.Uint64 // pages swept this cycle
+ pagesSweptBasis atomic.Uint64 // pagesSwept to use as the origin of the sweep ratio
+ sweepHeapLiveBasis uint64 // value of gcController.heapLive to use as the origin of sweep ratio; written with lock, read without
+ sweepPagesPerByte float64 // proportional sweep ratio; written with lock, read without
+
+ // Page reclaimer state
+
+ // reclaimIndex is the page index in allArenas of next page to
+ // reclaim. Specifically, it refers to page (i %
+ // pagesPerArena) of arena allArenas[i / pagesPerArena].
+ //
+ // If this is >= 1<<63, the page reclaimer is done scanning
+ // the page marks.
+ reclaimIndex atomic.Uint64
+
+ // reclaimCredit is spare credit for extra pages swept. Since
+ // the page reclaimer works in large chunks, it may reclaim
+ // more than requested. Any spare pages released go to this
+ // credit pool.
+ reclaimCredit atomic.Uintptr
+
+ // arenas is the heap arena map. It points to the metadata for
+ // the heap for every arena frame of the entire usable virtual
+ // address space.
+ //
+ // Use arenaIndex to compute indexes into this array.
+ //
+ // For regions of the address space that are not backed by the
+ // Go heap, the arena map contains nil.
+ //
+ // Modifications are protected by mheap_.lock. Reads can be
+ // performed without locking; however, a given entry can
+ // transition from nil to non-nil at any time when the lock
+ // isn't held. (Entries never transitions back to nil.)
+ //
+ // In general, this is a two-level mapping consisting of an L1
+ // map and possibly many L2 maps. This saves space when there
+ // are a huge number of arena frames. However, on many
+ // platforms (even 64-bit), arenaL1Bits is 0, making this
+ // effectively a single-level map. In this case, arenas[0]
+ // will never be nil.
+ arenas [1 << arenaL1Bits]*[1 << arenaL2Bits]*heapArena
+
+ // arenasHugePages indicates whether arenas' L2 entries are eligible
+ // to be backed by huge pages.
+ arenasHugePages bool
+
+ // heapArenaAlloc is pre-reserved space for allocating heapArena
+ // objects. This is only used on 32-bit, where we pre-reserve
+ // this space to avoid interleaving it with the heap itself.
+ heapArenaAlloc linearAlloc
+
+ // arenaHints is a list of addresses at which to attempt to
+ // add more heap arenas. This is initially populated with a
+ // set of general hint addresses, and grown with the bounds of
+ // actual heap arena ranges.
+ arenaHints *arenaHint
+
+ // arena is a pre-reserved space for allocating heap arenas
+ // (the actual arenas). This is only used on 32-bit.
+ arena linearAlloc
+
+ // allArenas is the arenaIndex of every mapped arena. This can
+ // be used to iterate through the address space.
+ //
+ // Access is protected by mheap_.lock. However, since this is
+ // append-only and old backing arrays are never freed, it is
+ // safe to acquire mheap_.lock, copy the slice header, and
+ // then release mheap_.lock.
+ allArenas []arenaIdx
+
+ // sweepArenas is a snapshot of allArenas taken at the
+ // beginning of the sweep cycle. This can be read safely by
+ // simply blocking GC (by disabling preemption).
+ sweepArenas []arenaIdx
+
+ // markArenas is a snapshot of allArenas taken at the beginning
+ // of the mark cycle. Because allArenas is append-only, neither
+ // this slice nor its contents will change during the mark, so
+ // it can be read safely.
+ markArenas []arenaIdx
+
+ // curArena is the arena that the heap is currently growing
+ // into. This should always be physPageSize-aligned.
+ curArena struct {
+ base, end uintptr
+ }
+
+ // central free lists for small size classes.
+ // the padding makes sure that the mcentrals are
+ // spaced CacheLinePadSize bytes apart, so that each mcentral.lock
+ // gets its own cache line.
+ // central is indexed by spanClass.
+ central [numSpanClasses]struct {
+ mcentral mcentral
+ pad [(cpu.CacheLinePadSize - unsafe.Sizeof(mcentral{})%cpu.CacheLinePadSize) % cpu.CacheLinePadSize]byte
+ }
+
+ spanalloc fixalloc // allocator for span*
+ cachealloc fixalloc // allocator for mcache*
+ specialfinalizeralloc fixalloc // allocator for specialfinalizer*
+ specialprofilealloc fixalloc // allocator for specialprofile*
+ specialReachableAlloc fixalloc // allocator for specialReachable
+ specialPinCounterAlloc fixalloc // allocator for specialPinCounter
+ speciallock mutex // lock for special record allocators.
+ arenaHintAlloc fixalloc // allocator for arenaHints
+
+ // User arena state.
+ //
+ // Protected by mheap_.lock.
+ userArena struct {
+ // arenaHints is a list of addresses at which to attempt to
+ // add more heap arenas for user arena chunks. This is initially
+ // populated with a set of general hint addresses, and grown with
+ // the bounds of actual heap arena ranges.
+ arenaHints *arenaHint
+
+ // quarantineList is a list of user arena spans that have been set to fault, but
+ // are waiting for all pointers into them to go away. Sweeping handles
+ // identifying when this is true, and moves the span to the ready list.
+ quarantineList mSpanList
+
+ // readyList is a list of empty user arena spans that are ready for reuse.
+ readyList mSpanList
+ }
+
+ unused *specialfinalizer // never set, just here to force the specialfinalizer type into DWARF
+}
+
+var mheap_ mheap
+
+// A heapArena stores metadata for a heap arena. heapArenas are stored
+// outside of the Go heap and accessed via the mheap_.arenas index.
+type heapArena struct {
+ _ sys.NotInHeap
+
+ // bitmap stores the pointer/scalar bitmap for the words in
+ // this arena. See mbitmap.go for a description.
+ // This array uses 1 bit per word of heap, or 1.6% of the heap size (for 64-bit).
+ bitmap [heapArenaBitmapWords]uintptr
+
+ // If the ith bit of noMorePtrs is true, then there are no more
+ // pointers for the object containing the word described by the
+ // high bit of bitmap[i].
+ // In that case, bitmap[i+1], ... must be zero until the start
+ // of the next object.
+ // We never operate on these entries using bit-parallel techniques,
+ // so it is ok if they are small. Also, they can't be bigger than
+ // uint16 because at that size a single noMorePtrs entry
+ // represents 8K of memory, the minimum size of a span. Any larger
+ // and we'd have to worry about concurrent updates.
+ // This array uses 1 bit per word of bitmap, or .024% of the heap size (for 64-bit).
+ noMorePtrs [heapArenaBitmapWords / 8]uint8
+
+ // spans maps from virtual address page ID within this arena to *mspan.
+ // For allocated spans, their pages map to the span itself.
+ // For free spans, only the lowest and highest pages map to the span itself.
+ // Internal pages map to an arbitrary span.
+ // For pages that have never been allocated, spans entries are nil.
+ //
+ // Modifications are protected by mheap.lock. Reads can be
+ // performed without locking, but ONLY from indexes that are
+ // known to contain in-use or stack spans. This means there
+ // must not be a safe-point between establishing that an
+ // address is live and looking it up in the spans array.
+ spans [pagesPerArena]*mspan
+
+ // pageInUse is a bitmap that indicates which spans are in
+ // state mSpanInUse. This bitmap is indexed by page number,
+ // but only the bit corresponding to the first page in each
+ // span is used.
+ //
+ // Reads and writes are atomic.
+ pageInUse [pagesPerArena / 8]uint8
+
+ // pageMarks is a bitmap that indicates which spans have any
+ // marked objects on them. Like pageInUse, only the bit
+ // corresponding to the first page in each span is used.
+ //
+ // Writes are done atomically during marking. Reads are
+ // non-atomic and lock-free since they only occur during
+ // sweeping (and hence never race with writes).
+ //
+ // This is used to quickly find whole spans that can be freed.
+ //
+ // TODO(austin): It would be nice if this was uint64 for
+ // faster scanning, but we don't have 64-bit atomic bit
+ // operations.
+ pageMarks [pagesPerArena / 8]uint8
+
+ // pageSpecials is a bitmap that indicates which spans have
+ // specials (finalizers or other). Like pageInUse, only the bit
+ // corresponding to the first page in each span is used.
+ //
+ // Writes are done atomically whenever a special is added to
+ // a span and whenever the last special is removed from a span.
+ // Reads are done atomically to find spans containing specials
+ // during marking.
+ pageSpecials [pagesPerArena / 8]uint8
+
+ // checkmarks stores the debug.gccheckmark state. It is only
+ // used if debug.gccheckmark > 0.
+ checkmarks *checkmarksMap
+
+ // zeroedBase marks the first byte of the first page in this
+ // arena which hasn't been used yet and is therefore already
+ // zero. zeroedBase is relative to the arena base.
+ // Increases monotonically until it hits heapArenaBytes.
+ //
+ // This field is sufficient to determine if an allocation
+ // needs to be zeroed because the page allocator follows an
+ // address-ordered first-fit policy.
+ //
+ // Read atomically and written with an atomic CAS.
+ zeroedBase uintptr
+}
+
+// arenaHint is a hint for where to grow the heap arenas. See
+// mheap_.arenaHints.
+type arenaHint struct {
+ _ sys.NotInHeap
+ addr uintptr
+ down bool
+ next *arenaHint
+}
+
+// An mspan is a run of pages.
+//
+// When a mspan is in the heap free treap, state == mSpanFree
+// and heapmap(s->start) == span, heapmap(s->start+s->npages-1) == span.
+// If the mspan is in the heap scav treap, then in addition to the
+// above scavenged == true. scavenged == false in all other cases.
+//
+// When a mspan is allocated, state == mSpanInUse or mSpanManual
+// and heapmap(i) == span for all s->start <= i < s->start+s->npages.
+
+// Every mspan is in one doubly-linked list, either in the mheap's
+// busy list or one of the mcentral's span lists.
+
+// An mspan representing actual memory has state mSpanInUse,
+// mSpanManual, or mSpanFree. Transitions between these states are
+// constrained as follows:
+//
+// - A span may transition from free to in-use or manual during any GC
+// phase.
+//
+// - During sweeping (gcphase == _GCoff), a span may transition from
+// in-use to free (as a result of sweeping) or manual to free (as a
+// result of stacks being freed).
+//
+// - During GC (gcphase != _GCoff), a span *must not* transition from
+// manual or in-use to free. Because concurrent GC may read a pointer
+// and then look up its span, the span state must be monotonic.
+//
+// Setting mspan.state to mSpanInUse or mSpanManual must be done
+// atomically and only after all other span fields are valid.
+// Likewise, if inspecting a span is contingent on it being
+// mSpanInUse, the state should be loaded atomically and checked
+// before depending on other fields. This allows the garbage collector
+// to safely deal with potentially invalid pointers, since resolving
+// such pointers may race with a span being allocated.
+type mSpanState uint8
+
+const (
+ mSpanDead mSpanState = iota
+ mSpanInUse // allocated for garbage collected heap
+ mSpanManual // allocated for manual management (e.g., stack allocator)
+)
+
+// mSpanStateNames are the names of the span states, indexed by
+// mSpanState.
+var mSpanStateNames = []string{
+ "mSpanDead",
+ "mSpanInUse",
+ "mSpanManual",
+}
+
+// mSpanStateBox holds an atomic.Uint8 to provide atomic operations on
+// an mSpanState. This is a separate type to disallow accidental comparison
+// or assignment with mSpanState.
+type mSpanStateBox struct {
+ s atomic.Uint8
+}
+
+// It is nosplit to match get, below.
+
+//go:nosplit
+func (b *mSpanStateBox) set(s mSpanState) {
+ b.s.Store(uint8(s))
+}
+
+// It is nosplit because it's called indirectly by typedmemclr,
+// which must not be preempted.
+
+//go:nosplit
+func (b *mSpanStateBox) get() mSpanState {
+ return mSpanState(b.s.Load())
+}
+
+// mSpanList heads a linked list of spans.
+type mSpanList struct {
+ _ sys.NotInHeap
+ first *mspan // first span in list, or nil if none
+ last *mspan // last span in list, or nil if none
+}
+
+type mspan struct {
+ _ sys.NotInHeap
+ next *mspan // next span in list, or nil if none
+ prev *mspan // previous span in list, or nil if none
+ list *mSpanList // For debugging. TODO: Remove.
+
+ startAddr uintptr // address of first byte of span aka s.base()
+ npages uintptr // number of pages in span
+
+ manualFreeList gclinkptr // list of free objects in mSpanManual spans
+
+ // freeindex is the slot index between 0 and nelems at which to begin scanning
+ // for the next free object in this span.
+ // Each allocation scans allocBits starting at freeindex until it encounters a 0
+ // indicating a free object. freeindex is then adjusted so that subsequent scans begin
+ // just past the newly discovered free object.
+ //
+ // If freeindex == nelem, this span has no free objects.
+ //
+ // allocBits is a bitmap of objects in this span.
+ // If n >= freeindex and allocBits[n/8] & (1<<(n%8)) is 0
+ // then object n is free;
+ // otherwise, object n is allocated. Bits starting at nelem are
+ // undefined and should never be referenced.
+ //
+ // Object n starts at address n*elemsize + (start << pageShift).
+ freeindex uintptr
+ // TODO: Look up nelems from sizeclass and remove this field if it
+ // helps performance.
+ nelems uintptr // number of object in the span.
+
+ // Cache of the allocBits at freeindex. allocCache is shifted
+ // such that the lowest bit corresponds to the bit freeindex.
+ // allocCache holds the complement of allocBits, thus allowing
+ // ctz (count trailing zero) to use it directly.
+ // allocCache may contain bits beyond s.nelems; the caller must ignore
+ // these.
+ allocCache uint64
+
+ // allocBits and gcmarkBits hold pointers to a span's mark and
+ // allocation bits. The pointers are 8 byte aligned.
+ // There are three arenas where this data is held.
+ // free: Dirty arenas that are no longer accessed
+ // and can be reused.
+ // next: Holds information to be used in the next GC cycle.
+ // current: Information being used during this GC cycle.
+ // previous: Information being used during the last GC cycle.
+ // A new GC cycle starts with the call to finishsweep_m.
+ // finishsweep_m moves the previous arena to the free arena,
+ // the current arena to the previous arena, and
+ // the next arena to the current arena.
+ // The next arena is populated as the spans request
+ // memory to hold gcmarkBits for the next GC cycle as well
+ // as allocBits for newly allocated spans.
+ //
+ // The pointer arithmetic is done "by hand" instead of using
+ // arrays to avoid bounds checks along critical performance
+ // paths.
+ // The sweep will free the old allocBits and set allocBits to the
+ // gcmarkBits. The gcmarkBits are replaced with a fresh zeroed
+ // out memory.
+ allocBits *gcBits
+ gcmarkBits *gcBits
+ pinnerBits *gcBits // bitmap for pinned objects; accessed atomically
+
+ // sweep generation:
+ // if sweepgen == h->sweepgen - 2, the span needs sweeping
+ // if sweepgen == h->sweepgen - 1, the span is currently being swept
+ // if sweepgen == h->sweepgen, the span is swept and ready to use
+ // if sweepgen == h->sweepgen + 1, the span was cached before sweep began and is still cached, and needs sweeping
+ // if sweepgen == h->sweepgen + 3, the span was swept and then cached and is still cached
+ // h->sweepgen is incremented by 2 after every GC
+
+ sweepgen uint32
+ divMul uint32 // for divide by elemsize
+ allocCount uint16 // number of allocated objects
+ spanclass spanClass // size class and noscan (uint8)
+ state mSpanStateBox // mSpanInUse etc; accessed atomically (get/set methods)
+ needzero uint8 // needs to be zeroed before allocation
+ isUserArenaChunk bool // whether or not this span represents a user arena
+ allocCountBeforeCache uint16 // a copy of allocCount that is stored just before this span is cached
+ elemsize uintptr // computed from sizeclass or from npages
+ limit uintptr // end of data in span
+ speciallock mutex // guards specials list and changes to pinnerBits
+ specials *special // linked list of special records sorted by offset.
+ userArenaChunkFree addrRange // interval for managing chunk allocation
+
+ // freeIndexForScan is like freeindex, except that freeindex is
+ // used by the allocator whereas freeIndexForScan is used by the
+ // GC scanner. They are two fields so that the GC sees the object
+ // is allocated only when the object and the heap bits are
+ // initialized (see also the assignment of freeIndexForScan in
+ // mallocgc, and issue 54596).
+ freeIndexForScan uintptr
+}
+
+func (s *mspan) base() uintptr {
+ return s.startAddr
+}
+
+func (s *mspan) layout() (size, n, total uintptr) {
+ total = s.npages << _PageShift
+ size = s.elemsize
+ if size > 0 {
+ n = total / size
+ }
+ return
+}
+
+// recordspan adds a newly allocated span to h.allspans.
+//
+// This only happens the first time a span is allocated from
+// mheap.spanalloc (it is not called when a span is reused).
+//
+// Write barriers are disallowed here because it can be called from
+// gcWork when allocating new workbufs. However, because it's an
+// indirect call from the fixalloc initializer, the compiler can't see
+// this.
+//
+// The heap lock must be held.
+//
+//go:nowritebarrierrec
+func recordspan(vh unsafe.Pointer, p unsafe.Pointer) {
+ h := (*mheap)(vh)
+ s := (*mspan)(p)
+
+ assertLockHeld(&h.lock)
+
+ if len(h.allspans) >= cap(h.allspans) {
+ n := 64 * 1024 / goarch.PtrSize
+ if n < cap(h.allspans)*3/2 {
+ n = cap(h.allspans) * 3 / 2
+ }
+ var new []*mspan
+ sp := (*slice)(unsafe.Pointer(&new))
+ sp.array = sysAlloc(uintptr(n)*goarch.PtrSize, &memstats.other_sys)
+ if sp.array == nil {
+ throw("runtime: cannot allocate memory")
+ }
+ sp.len = len(h.allspans)
+ sp.cap = n
+ if len(h.allspans) > 0 {
+ copy(new, h.allspans)
+ }
+ oldAllspans := h.allspans
+ *(*notInHeapSlice)(unsafe.Pointer(&h.allspans)) = *(*notInHeapSlice)(unsafe.Pointer(&new))
+ if len(oldAllspans) != 0 {
+ sysFree(unsafe.Pointer(&oldAllspans[0]), uintptr(cap(oldAllspans))*unsafe.Sizeof(oldAllspans[0]), &memstats.other_sys)
+ }
+ }
+ h.allspans = h.allspans[:len(h.allspans)+1]
+ h.allspans[len(h.allspans)-1] = s
+}
+
+// A spanClass represents the size class and noscan-ness of a span.
+//
+// Each size class has a noscan spanClass and a scan spanClass. The
+// noscan spanClass contains only noscan objects, which do not contain
+// pointers and thus do not need to be scanned by the garbage
+// collector.
+type spanClass uint8
+
+const (
+ numSpanClasses = _NumSizeClasses << 1
+ tinySpanClass = spanClass(tinySizeClass<<1 | 1)
+)
+
+func makeSpanClass(sizeclass uint8, noscan bool) spanClass {
+ return spanClass(sizeclass<<1) | spanClass(bool2int(noscan))
+}
+
+func (sc spanClass) sizeclass() int8 {
+ return int8(sc >> 1)
+}
+
+func (sc spanClass) noscan() bool {
+ return sc&1 != 0
+}
+
+// arenaIndex returns the index into mheap_.arenas of the arena
+// containing metadata for p. This index combines of an index into the
+// L1 map and an index into the L2 map and should be used as
+// mheap_.arenas[ai.l1()][ai.l2()].
+//
+// If p is outside the range of valid heap addresses, either l1() or
+// l2() will be out of bounds.
+//
+// It is nosplit because it's called by spanOf and several other
+// nosplit functions.
+//
+//go:nosplit
+func arenaIndex(p uintptr) arenaIdx {
+ return arenaIdx((p - arenaBaseOffset) / heapArenaBytes)
+}
+
+// arenaBase returns the low address of the region covered by heap
+// arena i.
+func arenaBase(i arenaIdx) uintptr {
+ return uintptr(i)*heapArenaBytes + arenaBaseOffset
+}
+
+type arenaIdx uint
+
+// l1 returns the "l1" portion of an arenaIdx.
+//
+// Marked nosplit because it's called by spanOf and other nosplit
+// functions.
+//
+//go:nosplit
+func (i arenaIdx) l1() uint {
+ if arenaL1Bits == 0 {
+ // Let the compiler optimize this away if there's no
+ // L1 map.
+ return 0
+ } else {
+ return uint(i) >> arenaL1Shift
+ }
+}
+
+// l2 returns the "l2" portion of an arenaIdx.
+//
+// Marked nosplit because it's called by spanOf and other nosplit funcs.
+// functions.
+//
+//go:nosplit
+func (i arenaIdx) l2() uint {
+ if arenaL1Bits == 0 {
+ return uint(i)
+ } else {
+ return uint(i) & (1<<arenaL2Bits - 1)
+ }
+}
+
+// inheap reports whether b is a pointer into a (potentially dead) heap object.
+// It returns false for pointers into mSpanManual spans.
+// Non-preemptible because it is used by write barriers.
+//
+//go:nowritebarrier
+//go:nosplit
+func inheap(b uintptr) bool {
+ return spanOfHeap(b) != nil
+}
+
+// inHeapOrStack is a variant of inheap that returns true for pointers
+// into any allocated heap span.
+//
+//go:nowritebarrier
+//go:nosplit
+func inHeapOrStack(b uintptr) bool {
+ s := spanOf(b)
+ if s == nil || b < s.base() {
+ return false
+ }
+ switch s.state.get() {
+ case mSpanInUse, mSpanManual:
+ return b < s.limit
+ default:
+ return false
+ }
+}
+
+// spanOf returns the span of p. If p does not point into the heap
+// arena or no span has ever contained p, spanOf returns nil.
+//
+// If p does not point to allocated memory, this may return a non-nil
+// span that does *not* contain p. If this is a possibility, the
+// caller should either call spanOfHeap or check the span bounds
+// explicitly.
+//
+// Must be nosplit because it has callers that are nosplit.
+//
+//go:nosplit
+func spanOf(p uintptr) *mspan {
+ // This function looks big, but we use a lot of constant
+ // folding around arenaL1Bits to get it under the inlining
+ // budget. Also, many of the checks here are safety checks
+ // that Go needs to do anyway, so the generated code is quite
+ // short.
+ ri := arenaIndex(p)
+ if arenaL1Bits == 0 {
+ // If there's no L1, then ri.l1() can't be out of bounds but ri.l2() can.
+ if ri.l2() >= uint(len(mheap_.arenas[0])) {
+ return nil
+ }
+ } else {
+ // If there's an L1, then ri.l1() can be out of bounds but ri.l2() can't.
+ if ri.l1() >= uint(len(mheap_.arenas)) {
+ return nil
+ }
+ }
+ l2 := mheap_.arenas[ri.l1()]
+ if arenaL1Bits != 0 && l2 == nil { // Should never happen if there's no L1.
+ return nil
+ }
+ ha := l2[ri.l2()]
+ if ha == nil {
+ return nil
+ }
+ return ha.spans[(p/pageSize)%pagesPerArena]
+}
+
+// spanOfUnchecked is equivalent to spanOf, but the caller must ensure
+// that p points into an allocated heap arena.
+//
+// Must be nosplit because it has callers that are nosplit.
+//
+//go:nosplit
+func spanOfUnchecked(p uintptr) *mspan {
+ ai := arenaIndex(p)
+ return mheap_.arenas[ai.l1()][ai.l2()].spans[(p/pageSize)%pagesPerArena]
+}
+
+// spanOfHeap is like spanOf, but returns nil if p does not point to a
+// heap object.
+//
+// Must be nosplit because it has callers that are nosplit.
+//
+//go:nosplit
+func spanOfHeap(p uintptr) *mspan {
+ s := spanOf(p)
+ // s is nil if it's never been allocated. Otherwise, we check
+ // its state first because we don't trust this pointer, so we
+ // have to synchronize with span initialization. Then, it's
+ // still possible we picked up a stale span pointer, so we
+ // have to check the span's bounds.
+ if s == nil || s.state.get() != mSpanInUse || p < s.base() || p >= s.limit {
+ return nil
+ }
+ return s
+}
+
+// pageIndexOf returns the arena, page index, and page mask for pointer p.
+// The caller must ensure p is in the heap.
+func pageIndexOf(p uintptr) (arena *heapArena, pageIdx uintptr, pageMask uint8) {
+ ai := arenaIndex(p)
+ arena = mheap_.arenas[ai.l1()][ai.l2()]
+ pageIdx = ((p / pageSize) / 8) % uintptr(len(arena.pageInUse))
+ pageMask = byte(1 << ((p / pageSize) % 8))
+ return
+}
+
+// Initialize the heap.
+func (h *mheap) init() {
+ lockInit(&h.lock, lockRankMheap)
+ lockInit(&h.speciallock, lockRankMheapSpecial)
+
+ h.spanalloc.init(unsafe.Sizeof(mspan{}), recordspan, unsafe.Pointer(h), &memstats.mspan_sys)
+ h.cachealloc.init(unsafe.Sizeof(mcache{}), nil, nil, &memstats.mcache_sys)
+ h.specialfinalizeralloc.init(unsafe.Sizeof(specialfinalizer{}), nil, nil, &memstats.other_sys)
+ h.specialprofilealloc.init(unsafe.Sizeof(specialprofile{}), nil, nil, &memstats.other_sys)
+ h.specialReachableAlloc.init(unsafe.Sizeof(specialReachable{}), nil, nil, &memstats.other_sys)
+ h.specialPinCounterAlloc.init(unsafe.Sizeof(specialPinCounter{}), nil, nil, &memstats.other_sys)
+ h.arenaHintAlloc.init(unsafe.Sizeof(arenaHint{}), nil, nil, &memstats.other_sys)
+
+ // Don't zero mspan allocations. Background sweeping can
+ // inspect a span concurrently with allocating it, so it's
+ // important that the span's sweepgen survive across freeing
+ // and re-allocating a span to prevent background sweeping
+ // from improperly cas'ing it from 0.
+ //
+ // This is safe because mspan contains no heap pointers.
+ h.spanalloc.zero = false
+
+ // h->mapcache needs no init
+
+ for i := range h.central {
+ h.central[i].mcentral.init(spanClass(i))
+ }
+
+ h.pages.init(&h.lock, &memstats.gcMiscSys, false)
+}
+
+// reclaim sweeps and reclaims at least npage pages into the heap.
+// It is called before allocating npage pages to keep growth in check.
+//
+// reclaim implements the page-reclaimer half of the sweeper.
+//
+// h.lock must NOT be held.
+func (h *mheap) reclaim(npage uintptr) {
+ // TODO(austin): Half of the time spent freeing spans is in
+ // locking/unlocking the heap (even with low contention). We
+ // could make the slow path here several times faster by
+ // batching heap frees.
+
+ // Bail early if there's no more reclaim work.
+ if h.reclaimIndex.Load() >= 1<<63 {
+ return
+ }
+
+ // Disable preemption so the GC can't start while we're
+ // sweeping, so we can read h.sweepArenas, and so
+ // traceGCSweepStart/Done pair on the P.
+ mp := acquirem()
+
+ if traceEnabled() {
+ traceGCSweepStart()
+ }
+
+ arenas := h.sweepArenas
+ locked := false
+ for npage > 0 {
+ // Pull from accumulated credit first.
+ if credit := h.reclaimCredit.Load(); credit > 0 {
+ take := credit
+ if take > npage {
+ // Take only what we need.
+ take = npage
+ }
+ if h.reclaimCredit.CompareAndSwap(credit, credit-take) {
+ npage -= take
+ }
+ continue
+ }
+
+ // Claim a chunk of work.
+ idx := uintptr(h.reclaimIndex.Add(pagesPerReclaimerChunk) - pagesPerReclaimerChunk)
+ if idx/pagesPerArena >= uintptr(len(arenas)) {
+ // Page reclaiming is done.
+ h.reclaimIndex.Store(1 << 63)
+ break
+ }
+
+ if !locked {
+ // Lock the heap for reclaimChunk.
+ lock(&h.lock)
+ locked = true
+ }
+
+ // Scan this chunk.
+ nfound := h.reclaimChunk(arenas, idx, pagesPerReclaimerChunk)
+ if nfound <= npage {
+ npage -= nfound
+ } else {
+ // Put spare pages toward global credit.
+ h.reclaimCredit.Add(nfound - npage)
+ npage = 0
+ }
+ }
+ if locked {
+ unlock(&h.lock)
+ }
+
+ if traceEnabled() {
+ traceGCSweepDone()
+ }
+ releasem(mp)
+}
+
+// reclaimChunk sweeps unmarked spans that start at page indexes [pageIdx, pageIdx+n).
+// It returns the number of pages returned to the heap.
+//
+// h.lock must be held and the caller must be non-preemptible. Note: h.lock may be
+// temporarily unlocked and re-locked in order to do sweeping or if tracing is
+// enabled.
+func (h *mheap) reclaimChunk(arenas []arenaIdx, pageIdx, n uintptr) uintptr {
+ // The heap lock must be held because this accesses the
+ // heapArena.spans arrays using potentially non-live pointers.
+ // In particular, if a span were freed and merged concurrently
+ // with this probing heapArena.spans, it would be possible to
+ // observe arbitrary, stale span pointers.
+ assertLockHeld(&h.lock)
+
+ n0 := n
+ var nFreed uintptr
+ sl := sweep.active.begin()
+ if !sl.valid {
+ return 0
+ }
+ for n > 0 {
+ ai := arenas[pageIdx/pagesPerArena]
+ ha := h.arenas[ai.l1()][ai.l2()]
+
+ // Get a chunk of the bitmap to work on.
+ arenaPage := uint(pageIdx % pagesPerArena)
+ inUse := ha.pageInUse[arenaPage/8:]
+ marked := ha.pageMarks[arenaPage/8:]
+ if uintptr(len(inUse)) > n/8 {
+ inUse = inUse[:n/8]
+ marked = marked[:n/8]
+ }
+
+ // Scan this bitmap chunk for spans that are in-use
+ // but have no marked objects on them.
+ for i := range inUse {
+ inUseUnmarked := atomic.Load8(&inUse[i]) &^ marked[i]
+ if inUseUnmarked == 0 {
+ continue
+ }
+
+ for j := uint(0); j < 8; j++ {
+ if inUseUnmarked&(1<<j) != 0 {
+ s := ha.spans[arenaPage+uint(i)*8+j]
+ if s, ok := sl.tryAcquire(s); ok {
+ npages := s.npages
+ unlock(&h.lock)
+ if s.sweep(false) {
+ nFreed += npages
+ }
+ lock(&h.lock)
+ // Reload inUse. It's possible nearby
+ // spans were freed when we dropped the
+ // lock and we don't want to get stale
+ // pointers from the spans array.
+ inUseUnmarked = atomic.Load8(&inUse[i]) &^ marked[i]
+ }
+ }
+ }
+ }
+
+ // Advance.
+ pageIdx += uintptr(len(inUse) * 8)
+ n -= uintptr(len(inUse) * 8)
+ }
+ sweep.active.end(sl)
+ if traceEnabled() {
+ unlock(&h.lock)
+ // Account for pages scanned but not reclaimed.
+ traceGCSweepSpan((n0 - nFreed) * pageSize)
+ lock(&h.lock)
+ }
+
+ assertLockHeld(&h.lock) // Must be locked on return.
+ return nFreed
+}
+
+// spanAllocType represents the type of allocation to make, or
+// the type of allocation to be freed.
+type spanAllocType uint8
+
+const (
+ spanAllocHeap spanAllocType = iota // heap span
+ spanAllocStack // stack span
+ spanAllocPtrScalarBits // unrolled GC prog bitmap span
+ spanAllocWorkBuf // work buf span
+)
+
+// manual returns true if the span allocation is manually managed.
+func (s spanAllocType) manual() bool {
+ return s != spanAllocHeap
+}
+
+// alloc allocates a new span of npage pages from the GC'd heap.
+//
+// spanclass indicates the span's size class and scannability.
+//
+// Returns a span that has been fully initialized. span.needzero indicates
+// whether the span has been zeroed. Note that it may not be.
+func (h *mheap) alloc(npages uintptr, spanclass spanClass) *mspan {
+ // Don't do any operations that lock the heap on the G stack.
+ // It might trigger stack growth, and the stack growth code needs
+ // to be able to allocate heap.
+ var s *mspan
+ systemstack(func() {
+ // To prevent excessive heap growth, before allocating n pages
+ // we need to sweep and reclaim at least n pages.
+ if !isSweepDone() {
+ h.reclaim(npages)
+ }
+ s = h.allocSpan(npages, spanAllocHeap, spanclass)
+ })
+ return s
+}
+
+// allocManual allocates a manually-managed span of npage pages.
+// allocManual returns nil if allocation fails.
+//
+// allocManual adds the bytes used to *stat, which should be a
+// memstats in-use field. Unlike allocations in the GC'd heap, the
+// allocation does *not* count toward heapInUse.
+//
+// The memory backing the returned span may not be zeroed if
+// span.needzero is set.
+//
+// allocManual must be called on the system stack because it may
+// acquire the heap lock via allocSpan. See mheap for details.
+//
+// If new code is written to call allocManual, do NOT use an
+// existing spanAllocType value and instead declare a new one.
+//
+//go:systemstack
+func (h *mheap) allocManual(npages uintptr, typ spanAllocType) *mspan {
+ if !typ.manual() {
+ throw("manual span allocation called with non-manually-managed type")
+ }
+ return h.allocSpan(npages, typ, 0)
+}
+
+// setSpans modifies the span map so [spanOf(base), spanOf(base+npage*pageSize))
+// is s.
+func (h *mheap) setSpans(base, npage uintptr, s *mspan) {
+ p := base / pageSize
+ ai := arenaIndex(base)
+ ha := h.arenas[ai.l1()][ai.l2()]
+ for n := uintptr(0); n < npage; n++ {
+ i := (p + n) % pagesPerArena
+ if i == 0 {
+ ai = arenaIndex(base + n*pageSize)
+ ha = h.arenas[ai.l1()][ai.l2()]
+ }
+ ha.spans[i] = s
+ }
+}
+
+// allocNeedsZero checks if the region of address space [base, base+npage*pageSize),
+// assumed to be allocated, needs to be zeroed, updating heap arena metadata for
+// future allocations.
+//
+// This must be called each time pages are allocated from the heap, even if the page
+// allocator can otherwise prove the memory it's allocating is already zero because
+// they're fresh from the operating system. It updates heapArena metadata that is
+// critical for future page allocations.
+//
+// There are no locking constraints on this method.
+func (h *mheap) allocNeedsZero(base, npage uintptr) (needZero bool) {
+ for npage > 0 {
+ ai := arenaIndex(base)
+ ha := h.arenas[ai.l1()][ai.l2()]
+
+ zeroedBase := atomic.Loaduintptr(&ha.zeroedBase)
+ arenaBase := base % heapArenaBytes
+ if arenaBase < zeroedBase {
+ // We extended into the non-zeroed part of the
+ // arena, so this region needs to be zeroed before use.
+ //
+ // zeroedBase is monotonically increasing, so if we see this now then
+ // we can be sure we need to zero this memory region.
+ //
+ // We still need to update zeroedBase for this arena, and
+ // potentially more arenas.
+ needZero = true
+ }
+ // We may observe arenaBase > zeroedBase if we're racing with one or more
+ // allocations which are acquiring memory directly before us in the address
+ // space. But, because we know no one else is acquiring *this* memory, it's
+ // still safe to not zero.
+
+ // Compute how far into the arena we extend into, capped
+ // at heapArenaBytes.
+ arenaLimit := arenaBase + npage*pageSize
+ if arenaLimit > heapArenaBytes {
+ arenaLimit = heapArenaBytes
+ }
+ // Increase ha.zeroedBase so it's >= arenaLimit.
+ // We may be racing with other updates.
+ for arenaLimit > zeroedBase {
+ if atomic.Casuintptr(&ha.zeroedBase, zeroedBase, arenaLimit) {
+ break
+ }
+ zeroedBase = atomic.Loaduintptr(&ha.zeroedBase)
+ // Double check basic conditions of zeroedBase.
+ if zeroedBase <= arenaLimit && zeroedBase > arenaBase {
+ // The zeroedBase moved into the space we were trying to
+ // claim. That's very bad, and indicates someone allocated
+ // the same region we did.
+ throw("potentially overlapping in-use allocations detected")
+ }
+ }
+
+ // Move base forward and subtract from npage to move into
+ // the next arena, or finish.
+ base += arenaLimit - arenaBase
+ npage -= (arenaLimit - arenaBase) / pageSize
+ }
+ return
+}
+
+// tryAllocMSpan attempts to allocate an mspan object from
+// the P-local cache, but may fail.
+//
+// h.lock need not be held.
+//
+// This caller must ensure that its P won't change underneath
+// it during this function. Currently to ensure that we enforce
+// that the function is run on the system stack, because that's
+// the only place it is used now. In the future, this requirement
+// may be relaxed if its use is necessary elsewhere.
+//
+//go:systemstack
+func (h *mheap) tryAllocMSpan() *mspan {
+ pp := getg().m.p.ptr()
+ // If we don't have a p or the cache is empty, we can't do
+ // anything here.
+ if pp == nil || pp.mspancache.len == 0 {
+ return nil
+ }
+ // Pull off the last entry in the cache.
+ s := pp.mspancache.buf[pp.mspancache.len-1]
+ pp.mspancache.len--
+ return s
+}
+
+// allocMSpanLocked allocates an mspan object.
+//
+// h.lock must be held.
+//
+// allocMSpanLocked must be called on the system stack because
+// its caller holds the heap lock. See mheap for details.
+// Running on the system stack also ensures that we won't
+// switch Ps during this function. See tryAllocMSpan for details.
+//
+//go:systemstack
+func (h *mheap) allocMSpanLocked() *mspan {
+ assertLockHeld(&h.lock)
+
+ pp := getg().m.p.ptr()
+ if pp == nil {
+ // We don't have a p so just do the normal thing.
+ return (*mspan)(h.spanalloc.alloc())
+ }
+ // Refill the cache if necessary.
+ if pp.mspancache.len == 0 {
+ const refillCount = len(pp.mspancache.buf) / 2
+ for i := 0; i < refillCount; i++ {
+ pp.mspancache.buf[i] = (*mspan)(h.spanalloc.alloc())
+ }
+ pp.mspancache.len = refillCount
+ }
+ // Pull off the last entry in the cache.
+ s := pp.mspancache.buf[pp.mspancache.len-1]
+ pp.mspancache.len--
+ return s
+}
+
+// freeMSpanLocked free an mspan object.
+//
+// h.lock must be held.
+//
+// freeMSpanLocked must be called on the system stack because
+// its caller holds the heap lock. See mheap for details.
+// Running on the system stack also ensures that we won't
+// switch Ps during this function. See tryAllocMSpan for details.
+//
+//go:systemstack
+func (h *mheap) freeMSpanLocked(s *mspan) {
+ assertLockHeld(&h.lock)
+
+ pp := getg().m.p.ptr()
+ // First try to free the mspan directly to the cache.
+ if pp != nil && pp.mspancache.len < len(pp.mspancache.buf) {
+ pp.mspancache.buf[pp.mspancache.len] = s
+ pp.mspancache.len++
+ return
+ }
+ // Failing that (or if we don't have a p), just free it to
+ // the heap.
+ h.spanalloc.free(unsafe.Pointer(s))
+}
+
+// allocSpan allocates an mspan which owns npages worth of memory.
+//
+// If typ.manual() == false, allocSpan allocates a heap span of class spanclass
+// and updates heap accounting. If manual == true, allocSpan allocates a
+// manually-managed span (spanclass is ignored), and the caller is
+// responsible for any accounting related to its use of the span. Either
+// way, allocSpan will atomically add the bytes in the newly allocated
+// span to *sysStat.
+//
+// The returned span is fully initialized.
+//
+// h.lock must not be held.
+//
+// allocSpan must be called on the system stack both because it acquires
+// the heap lock and because it must block GC transitions.
+//
+//go:systemstack
+func (h *mheap) allocSpan(npages uintptr, typ spanAllocType, spanclass spanClass) (s *mspan) {
+ // Function-global state.
+ gp := getg()
+ base, scav := uintptr(0), uintptr(0)
+ growth := uintptr(0)
+
+ // On some platforms we need to provide physical page aligned stack
+ // allocations. Where the page size is less than the physical page
+ // size, we already manage to do this by default.
+ needPhysPageAlign := physPageAlignedStacks && typ == spanAllocStack && pageSize < physPageSize
+
+ // If the allocation is small enough, try the page cache!
+ // The page cache does not support aligned allocations, so we cannot use
+ // it if we need to provide a physical page aligned stack allocation.
+ pp := gp.m.p.ptr()
+ if !needPhysPageAlign && pp != nil && npages < pageCachePages/4 {
+ c := &pp.pcache
+
+ // If the cache is empty, refill it.
+ if c.empty() {
+ lock(&h.lock)
+ *c = h.pages.allocToCache()
+ unlock(&h.lock)
+ }
+
+ // Try to allocate from the cache.
+ base, scav = c.alloc(npages)
+ if base != 0 {
+ s = h.tryAllocMSpan()
+ if s != nil {
+ goto HaveSpan
+ }
+ // We have a base but no mspan, so we need
+ // to lock the heap.
+ }
+ }
+
+ // For one reason or another, we couldn't get the
+ // whole job done without the heap lock.
+ lock(&h.lock)
+
+ if needPhysPageAlign {
+ // Overallocate by a physical page to allow for later alignment.
+ extraPages := physPageSize / pageSize
+
+ // Find a big enough region first, but then only allocate the
+ // aligned portion. We can't just allocate and then free the
+ // edges because we need to account for scavenged memory, and
+ // that's difficult with alloc.
+ //
+ // Note that we skip updates to searchAddr here. It's OK if
+ // it's stale and higher than normal; it'll operate correctly,
+ // just come with a performance cost.
+ base, _ = h.pages.find(npages + extraPages)
+ if base == 0 {
+ var ok bool
+ growth, ok = h.grow(npages + extraPages)
+ if !ok {
+ unlock(&h.lock)
+ return nil
+ }
+ base, _ = h.pages.find(npages + extraPages)
+ if base == 0 {
+ throw("grew heap, but no adequate free space found")
+ }
+ }
+ base = alignUp(base, physPageSize)
+ scav = h.pages.allocRange(base, npages)
+ }
+
+ if base == 0 {
+ // Try to acquire a base address.
+ base, scav = h.pages.alloc(npages)
+ if base == 0 {
+ var ok bool
+ growth, ok = h.grow(npages)
+ if !ok {
+ unlock(&h.lock)
+ return nil
+ }
+ base, scav = h.pages.alloc(npages)
+ if base == 0 {
+ throw("grew heap, but no adequate free space found")
+ }
+ }
+ }
+ if s == nil {
+ // We failed to get an mspan earlier, so grab
+ // one now that we have the heap lock.
+ s = h.allocMSpanLocked()
+ }
+ unlock(&h.lock)
+
+HaveSpan:
+ // Decide if we need to scavenge in response to what we just allocated.
+ // Specifically, we track the maximum amount of memory to scavenge of all
+ // the alternatives below, assuming that the maximum satisfies *all*
+ // conditions we check (e.g. if we need to scavenge X to satisfy the
+ // memory limit and Y to satisfy heap-growth scavenging, and Y > X, then
+ // it's fine to pick Y, because the memory limit is still satisfied).
+ //
+ // It's fine to do this after allocating because we expect any scavenged
+ // pages not to get touched until we return. Simultaneously, it's important
+ // to do this before calling sysUsed because that may commit address space.
+ bytesToScavenge := uintptr(0)
+ forceScavenge := false
+ if limit := gcController.memoryLimit.Load(); !gcCPULimiter.limiting() {
+ // Assist with scavenging to maintain the memory limit by the amount
+ // that we expect to page in.
+ inuse := gcController.mappedReady.Load()
+ // Be careful about overflow, especially with uintptrs. Even on 32-bit platforms
+ // someone can set a really big memory limit that isn't maxInt64.
+ if uint64(scav)+inuse > uint64(limit) {
+ bytesToScavenge = uintptr(uint64(scav) + inuse - uint64(limit))
+ forceScavenge = true
+ }
+ }
+ if goal := scavenge.gcPercentGoal.Load(); goal != ^uint64(0) && growth > 0 {
+ // We just caused a heap growth, so scavenge down what will soon be used.
+ // By scavenging inline we deal with the failure to allocate out of
+ // memory fragments by scavenging the memory fragments that are least
+ // likely to be re-used.
+ //
+ // Only bother with this because we're not using a memory limit. We don't
+ // care about heap growths as long as we're under the memory limit, and the
+ // previous check for scaving already handles that.
+ if retained := heapRetained(); retained+uint64(growth) > goal {
+ // The scavenging algorithm requires the heap lock to be dropped so it
+ // can acquire it only sparingly. This is a potentially expensive operation
+ // so it frees up other goroutines to allocate in the meanwhile. In fact,
+ // they can make use of the growth we just created.
+ todo := growth
+ if overage := uintptr(retained + uint64(growth) - goal); todo > overage {
+ todo = overage
+ }
+ if todo > bytesToScavenge {
+ bytesToScavenge = todo
+ }
+ }
+ }
+ // There are a few very limited circumstances where we won't have a P here.
+ // It's OK to simply skip scavenging in these cases. Something else will notice
+ // and pick up the tab.
+ var now int64
+ if pp != nil && bytesToScavenge > 0 {
+ // Measure how long we spent scavenging and add that measurement to the assist
+ // time so we can track it for the GC CPU limiter.
+ //
+ // Limiter event tracking might be disabled if we end up here
+ // while on a mark worker.
+ start := nanotime()
+ track := pp.limiterEvent.start(limiterEventScavengeAssist, start)
+
+ // Scavenge, but back out if the limiter turns on.
+ released := h.pages.scavenge(bytesToScavenge, func() bool {
+ return gcCPULimiter.limiting()
+ }, forceScavenge)
+
+ mheap_.pages.scav.releasedEager.Add(released)
+
+ // Finish up accounting.
+ now = nanotime()
+ if track {
+ pp.limiterEvent.stop(limiterEventScavengeAssist, now)
+ }
+ scavenge.assistTime.Add(now - start)
+ }
+
+ // Initialize the span.
+ h.initSpan(s, typ, spanclass, base, npages)
+
+ // Commit and account for any scavenged memory that the span now owns.
+ nbytes := npages * pageSize
+ if scav != 0 {
+ // sysUsed all the pages that are actually available
+ // in the span since some of them might be scavenged.
+ sysUsed(unsafe.Pointer(base), nbytes, scav)
+ gcController.heapReleased.add(-int64(scav))
+ }
+ // Update stats.
+ gcController.heapFree.add(-int64(nbytes - scav))
+ if typ == spanAllocHeap {
+ gcController.heapInUse.add(int64(nbytes))
+ }
+ // Update consistent stats.
+ stats := memstats.heapStats.acquire()
+ atomic.Xaddint64(&stats.committed, int64(scav))
+ atomic.Xaddint64(&stats.released, -int64(scav))
+ switch typ {
+ case spanAllocHeap:
+ atomic.Xaddint64(&stats.inHeap, int64(nbytes))
+ case spanAllocStack:
+ atomic.Xaddint64(&stats.inStacks, int64(nbytes))
+ case spanAllocPtrScalarBits:
+ atomic.Xaddint64(&stats.inPtrScalarBits, int64(nbytes))
+ case spanAllocWorkBuf:
+ atomic.Xaddint64(&stats.inWorkBufs, int64(nbytes))
+ }
+ memstats.heapStats.release()
+
+ pageTraceAlloc(pp, now, base, npages)
+ return s
+}
+
+// initSpan initializes a blank span s which will represent the range
+// [base, base+npages*pageSize). typ is the type of span being allocated.
+func (h *mheap) initSpan(s *mspan, typ spanAllocType, spanclass spanClass, base, npages uintptr) {
+ // At this point, both s != nil and base != 0, and the heap
+ // lock is no longer held. Initialize the span.
+ s.init(base, npages)
+ if h.allocNeedsZero(base, npages) {
+ s.needzero = 1
+ }
+ nbytes := npages * pageSize
+ if typ.manual() {
+ s.manualFreeList = 0
+ s.nelems = 0
+ s.limit = s.base() + s.npages*pageSize
+ s.state.set(mSpanManual)
+ } else {
+ // We must set span properties before the span is published anywhere
+ // since we're not holding the heap lock.
+ s.spanclass = spanclass
+ if sizeclass := spanclass.sizeclass(); sizeclass == 0 {
+ s.elemsize = nbytes
+ s.nelems = 1
+ s.divMul = 0
+ } else {
+ s.elemsize = uintptr(class_to_size[sizeclass])
+ s.nelems = nbytes / s.elemsize
+ s.divMul = class_to_divmagic[sizeclass]
+ }
+
+ // Initialize mark and allocation structures.
+ s.freeindex = 0
+ s.freeIndexForScan = 0
+ s.allocCache = ^uint64(0) // all 1s indicating all free.
+ s.gcmarkBits = newMarkBits(s.nelems)
+ s.allocBits = newAllocBits(s.nelems)
+
+ // It's safe to access h.sweepgen without the heap lock because it's
+ // only ever updated with the world stopped and we run on the
+ // systemstack which blocks a STW transition.
+ atomic.Store(&s.sweepgen, h.sweepgen)
+
+ // Now that the span is filled in, set its state. This
+ // is a publication barrier for the other fields in
+ // the span. While valid pointers into this span
+ // should never be visible until the span is returned,
+ // if the garbage collector finds an invalid pointer,
+ // access to the span may race with initialization of
+ // the span. We resolve this race by atomically
+ // setting the state after the span is fully
+ // initialized, and atomically checking the state in
+ // any situation where a pointer is suspect.
+ s.state.set(mSpanInUse)
+ }
+
+ // Publish the span in various locations.
+
+ // This is safe to call without the lock held because the slots
+ // related to this span will only ever be read or modified by
+ // this thread until pointers into the span are published (and
+ // we execute a publication barrier at the end of this function
+ // before that happens) or pageInUse is updated.
+ h.setSpans(s.base(), npages, s)
+
+ if !typ.manual() {
+ // Mark in-use span in arena page bitmap.
+ //
+ // This publishes the span to the page sweeper, so
+ // it's imperative that the span be completely initialized
+ // prior to this line.
+ arena, pageIdx, pageMask := pageIndexOf(s.base())
+ atomic.Or8(&arena.pageInUse[pageIdx], pageMask)
+
+ // Update related page sweeper stats.
+ h.pagesInUse.Add(npages)
+ }
+
+ // Make sure the newly allocated span will be observed
+ // by the GC before pointers into the span are published.
+ publicationBarrier()
+}
+
+// Try to add at least npage pages of memory to the heap,
+// returning how much the heap grew by and whether it worked.
+//
+// h.lock must be held.
+func (h *mheap) grow(npage uintptr) (uintptr, bool) {
+ assertLockHeld(&h.lock)
+
+ // We must grow the heap in whole palloc chunks.
+ // We call sysMap below but note that because we
+ // round up to pallocChunkPages which is on the order
+ // of MiB (generally >= to the huge page size) we
+ // won't be calling it too much.
+ ask := alignUp(npage, pallocChunkPages) * pageSize
+
+ totalGrowth := uintptr(0)
+ // This may overflow because ask could be very large
+ // and is otherwise unrelated to h.curArena.base.
+ end := h.curArena.base + ask
+ nBase := alignUp(end, physPageSize)
+ if nBase > h.curArena.end || /* overflow */ end < h.curArena.base {
+ // Not enough room in the current arena. Allocate more
+ // arena space. This may not be contiguous with the
+ // current arena, so we have to request the full ask.
+ av, asize := h.sysAlloc(ask, &h.arenaHints, true)
+ if av == nil {
+ inUse := gcController.heapFree.load() + gcController.heapReleased.load() + gcController.heapInUse.load()
+ print("runtime: out of memory: cannot allocate ", ask, "-byte block (", inUse, " in use)\n")
+ return 0, false
+ }
+
+ if uintptr(av) == h.curArena.end {
+ // The new space is contiguous with the old
+ // space, so just extend the current space.
+ h.curArena.end = uintptr(av) + asize
+ } else {
+ // The new space is discontiguous. Track what
+ // remains of the current space and switch to
+ // the new space. This should be rare.
+ if size := h.curArena.end - h.curArena.base; size != 0 {
+ // Transition this space from Reserved to Prepared and mark it
+ // as released since we'll be able to start using it after updating
+ // the page allocator and releasing the lock at any time.
+ sysMap(unsafe.Pointer(h.curArena.base), size, &gcController.heapReleased)
+ // Update stats.
+ stats := memstats.heapStats.acquire()
+ atomic.Xaddint64(&stats.released, int64(size))
+ memstats.heapStats.release()
+ // Update the page allocator's structures to make this
+ // space ready for allocation.
+ h.pages.grow(h.curArena.base, size)
+ totalGrowth += size
+ }
+ // Switch to the new space.
+ h.curArena.base = uintptr(av)
+ h.curArena.end = uintptr(av) + asize
+ }
+
+ // Recalculate nBase.
+ // We know this won't overflow, because sysAlloc returned
+ // a valid region starting at h.curArena.base which is at
+ // least ask bytes in size.
+ nBase = alignUp(h.curArena.base+ask, physPageSize)
+ }
+
+ // Grow into the current arena.
+ v := h.curArena.base
+ h.curArena.base = nBase
+
+ // Transition the space we're going to use from Reserved to Prepared.
+ //
+ // The allocation is always aligned to the heap arena
+ // size which is always > physPageSize, so its safe to
+ // just add directly to heapReleased.
+ sysMap(unsafe.Pointer(v), nBase-v, &gcController.heapReleased)
+
+ // The memory just allocated counts as both released
+ // and idle, even though it's not yet backed by spans.
+ stats := memstats.heapStats.acquire()
+ atomic.Xaddint64(&stats.released, int64(nBase-v))
+ memstats.heapStats.release()
+
+ // Update the page allocator's structures to make this
+ // space ready for allocation.
+ h.pages.grow(v, nBase-v)
+ totalGrowth += nBase - v
+ return totalGrowth, true
+}
+
+// Free the span back into the heap.
+func (h *mheap) freeSpan(s *mspan) {
+ systemstack(func() {
+ pageTraceFree(getg().m.p.ptr(), 0, s.base(), s.npages)
+
+ lock(&h.lock)
+ if msanenabled {
+ // Tell msan that this entire span is no longer in use.
+ base := unsafe.Pointer(s.base())
+ bytes := s.npages << _PageShift
+ msanfree(base, bytes)
+ }
+ if asanenabled {
+ // Tell asan that this entire span is no longer in use.
+ base := unsafe.Pointer(s.base())
+ bytes := s.npages << _PageShift
+ asanpoison(base, bytes)
+ }
+ h.freeSpanLocked(s, spanAllocHeap)
+ unlock(&h.lock)
+ })
+}
+
+// freeManual frees a manually-managed span returned by allocManual.
+// typ must be the same as the spanAllocType passed to the allocManual that
+// allocated s.
+//
+// This must only be called when gcphase == _GCoff. See mSpanState for
+// an explanation.
+//
+// freeManual must be called on the system stack because it acquires
+// the heap lock. See mheap for details.
+//
+//go:systemstack
+func (h *mheap) freeManual(s *mspan, typ spanAllocType) {
+ pageTraceFree(getg().m.p.ptr(), 0, s.base(), s.npages)
+
+ s.needzero = 1
+ lock(&h.lock)
+ h.freeSpanLocked(s, typ)
+ unlock(&h.lock)
+}
+
+func (h *mheap) freeSpanLocked(s *mspan, typ spanAllocType) {
+ assertLockHeld(&h.lock)
+
+ switch s.state.get() {
+ case mSpanManual:
+ if s.allocCount != 0 {
+ throw("mheap.freeSpanLocked - invalid stack free")
+ }
+ case mSpanInUse:
+ if s.isUserArenaChunk {
+ throw("mheap.freeSpanLocked - invalid free of user arena chunk")
+ }
+ if s.allocCount != 0 || s.sweepgen != h.sweepgen {
+ print("mheap.freeSpanLocked - span ", s, " ptr ", hex(s.base()), " allocCount ", s.allocCount, " sweepgen ", s.sweepgen, "/", h.sweepgen, "\n")
+ throw("mheap.freeSpanLocked - invalid free")
+ }
+ h.pagesInUse.Add(-s.npages)
+
+ // Clear in-use bit in arena page bitmap.
+ arena, pageIdx, pageMask := pageIndexOf(s.base())
+ atomic.And8(&arena.pageInUse[pageIdx], ^pageMask)
+ default:
+ throw("mheap.freeSpanLocked - invalid span state")
+ }
+
+ // Update stats.
+ //
+ // Mirrors the code in allocSpan.
+ nbytes := s.npages * pageSize
+ gcController.heapFree.add(int64(nbytes))
+ if typ == spanAllocHeap {
+ gcController.heapInUse.add(-int64(nbytes))
+ }
+ // Update consistent stats.
+ stats := memstats.heapStats.acquire()
+ switch typ {
+ case spanAllocHeap:
+ atomic.Xaddint64(&stats.inHeap, -int64(nbytes))
+ case spanAllocStack:
+ atomic.Xaddint64(&stats.inStacks, -int64(nbytes))
+ case spanAllocPtrScalarBits:
+ atomic.Xaddint64(&stats.inPtrScalarBits, -int64(nbytes))
+ case spanAllocWorkBuf:
+ atomic.Xaddint64(&stats.inWorkBufs, -int64(nbytes))
+ }
+ memstats.heapStats.release()
+
+ // Mark the space as free.
+ h.pages.free(s.base(), s.npages)
+
+ // Free the span structure. We no longer have a use for it.
+ s.state.set(mSpanDead)
+ h.freeMSpanLocked(s)
+}
+
+// scavengeAll acquires the heap lock (blocking any additional
+// manipulation of the page allocator) and iterates over the whole
+// heap, scavenging every free page available.
+//
+// Must run on the system stack because it acquires the heap lock.
+//
+//go:systemstack
+func (h *mheap) scavengeAll() {
+ // Disallow malloc or panic while holding the heap lock. We do
+ // this here because this is a non-mallocgc entry-point to
+ // the mheap API.
+ gp := getg()
+ gp.m.mallocing++
+
+ // Force scavenge everything.
+ released := h.pages.scavenge(^uintptr(0), nil, true)
+
+ gp.m.mallocing--
+
+ if debug.scavtrace > 0 {
+ printScavTrace(0, released, true)
+ }
+}
+
+//go:linkname runtime_debug_freeOSMemory runtime/debug.freeOSMemory
+func runtime_debug_freeOSMemory() {
+ GC()
+ systemstack(func() { mheap_.scavengeAll() })
+}
+
+// Initialize a new span with the given start and npages.
+func (span *mspan) init(base uintptr, npages uintptr) {
+ // span is *not* zeroed.
+ span.next = nil
+ span.prev = nil
+ span.list = nil
+ span.startAddr = base
+ span.npages = npages
+ span.allocCount = 0
+ span.spanclass = 0
+ span.elemsize = 0
+ span.speciallock.key = 0
+ span.specials = nil
+ span.needzero = 0
+ span.freeindex = 0
+ span.freeIndexForScan = 0
+ span.allocBits = nil
+ span.gcmarkBits = nil
+ span.pinnerBits = nil
+ span.state.set(mSpanDead)
+ lockInit(&span.speciallock, lockRankMspanSpecial)
+}
+
+func (span *mspan) inList() bool {
+ return span.list != nil
+}
+
+// Initialize an empty doubly-linked list.
+func (list *mSpanList) init() {
+ list.first = nil
+ list.last = nil
+}
+
+func (list *mSpanList) remove(span *mspan) {
+ if span.list != list {
+ print("runtime: failed mSpanList.remove span.npages=", span.npages,
+ " span=", span, " prev=", span.prev, " span.list=", span.list, " list=", list, "\n")
+ throw("mSpanList.remove")
+ }
+ if list.first == span {
+ list.first = span.next
+ } else {
+ span.prev.next = span.next
+ }
+ if list.last == span {
+ list.last = span.prev
+ } else {
+ span.next.prev = span.prev
+ }
+ span.next = nil
+ span.prev = nil
+ span.list = nil
+}
+
+func (list *mSpanList) isEmpty() bool {
+ return list.first == nil
+}
+
+func (list *mSpanList) insert(span *mspan) {
+ if span.next != nil || span.prev != nil || span.list != nil {
+ println("runtime: failed mSpanList.insert", span, span.next, span.prev, span.list)
+ throw("mSpanList.insert")
+ }
+ span.next = list.first
+ if list.first != nil {
+ // The list contains at least one span; link it in.
+ // The last span in the list doesn't change.
+ list.first.prev = span
+ } else {
+ // The list contains no spans, so this is also the last span.
+ list.last = span
+ }
+ list.first = span
+ span.list = list
+}
+
+func (list *mSpanList) insertBack(span *mspan) {
+ if span.next != nil || span.prev != nil || span.list != nil {
+ println("runtime: failed mSpanList.insertBack", span, span.next, span.prev, span.list)
+ throw("mSpanList.insertBack")
+ }
+ span.prev = list.last
+ if list.last != nil {
+ // The list contains at least one span.
+ list.last.next = span
+ } else {
+ // The list contains no spans, so this is also the first span.
+ list.first = span
+ }
+ list.last = span
+ span.list = list
+}
+
+// takeAll removes all spans from other and inserts them at the front
+// of list.
+func (list *mSpanList) takeAll(other *mSpanList) {
+ if other.isEmpty() {
+ return
+ }
+
+ // Reparent everything in other to list.
+ for s := other.first; s != nil; s = s.next {
+ s.list = list
+ }
+
+ // Concatenate the lists.
+ if list.isEmpty() {
+ *list = *other
+ } else {
+ // Neither list is empty. Put other before list.
+ other.last.next = list.first
+ list.first.prev = other.last
+ list.first = other.first
+ }
+
+ other.first, other.last = nil, nil
+}
+
+const (
+ _KindSpecialFinalizer = 1
+ _KindSpecialProfile = 2
+ // _KindSpecialReachable is a special used for tracking
+ // reachability during testing.
+ _KindSpecialReachable = 3
+ // _KindSpecialPinCounter is a special used for objects that are pinned
+ // multiple times
+ _KindSpecialPinCounter = 4
+ // Note: The finalizer special must be first because if we're freeing
+ // an object, a finalizer special will cause the freeing operation
+ // to abort, and we want to keep the other special records around
+ // if that happens.
+)
+
+type special struct {
+ _ sys.NotInHeap
+ next *special // linked list in span
+ offset uint16 // span offset of object
+ kind byte // kind of special
+}
+
+// spanHasSpecials marks a span as having specials in the arena bitmap.
+func spanHasSpecials(s *mspan) {
+ arenaPage := (s.base() / pageSize) % pagesPerArena
+ ai := arenaIndex(s.base())
+ ha := mheap_.arenas[ai.l1()][ai.l2()]
+ atomic.Or8(&ha.pageSpecials[arenaPage/8], uint8(1)<<(arenaPage%8))
+}
+
+// spanHasNoSpecials marks a span as having no specials in the arena bitmap.
+func spanHasNoSpecials(s *mspan) {
+ arenaPage := (s.base() / pageSize) % pagesPerArena
+ ai := arenaIndex(s.base())
+ ha := mheap_.arenas[ai.l1()][ai.l2()]
+ atomic.And8(&ha.pageSpecials[arenaPage/8], ^(uint8(1) << (arenaPage % 8)))
+}
+
+// Adds the special record s to the list of special records for
+// the object p. All fields of s should be filled in except for
+// offset & next, which this routine will fill in.
+// Returns true if the special was successfully added, false otherwise.
+// (The add will fail only if a record with the same p and s->kind
+// already exists.)
+func addspecial(p unsafe.Pointer, s *special) bool {
+ span := spanOfHeap(uintptr(p))
+ if span == nil {
+ throw("addspecial on invalid pointer")
+ }
+
+ // Ensure that the span is swept.
+ // Sweeping accesses the specials list w/o locks, so we have
+ // to synchronize with it. And it's just much safer.
+ mp := acquirem()
+ span.ensureSwept()
+
+ offset := uintptr(p) - span.base()
+ kind := s.kind
+
+ lock(&span.speciallock)
+
+ // Find splice point, check for existing record.
+ iter, exists := span.specialFindSplicePoint(offset, kind)
+ if !exists {
+ // Splice in record, fill in offset.
+ s.offset = uint16(offset)
+ s.next = *iter
+ *iter = s
+ spanHasSpecials(span)
+ }
+
+ unlock(&span.speciallock)
+ releasem(mp)
+ return !exists // already exists
+}
+
+// Removes the Special record of the given kind for the object p.
+// Returns the record if the record existed, nil otherwise.
+// The caller must FixAlloc_Free the result.
+func removespecial(p unsafe.Pointer, kind uint8) *special {
+ span := spanOfHeap(uintptr(p))
+ if span == nil {
+ throw("removespecial on invalid pointer")
+ }
+
+ // Ensure that the span is swept.
+ // Sweeping accesses the specials list w/o locks, so we have
+ // to synchronize with it. And it's just much safer.
+ mp := acquirem()
+ span.ensureSwept()
+
+ offset := uintptr(p) - span.base()
+
+ var result *special
+ lock(&span.speciallock)
+
+ iter, exists := span.specialFindSplicePoint(offset, kind)
+ if exists {
+ s := *iter
+ *iter = s.next
+ result = s
+ }
+ if span.specials == nil {
+ spanHasNoSpecials(span)
+ }
+ unlock(&span.speciallock)
+ releasem(mp)
+ return result
+}
+
+// Find a splice point in the sorted list and check for an already existing
+// record. Returns a pointer to the next-reference in the list predecessor.
+// Returns true, if the referenced item is an exact match.
+func (span *mspan) specialFindSplicePoint(offset uintptr, kind byte) (**special, bool) {
+ // Find splice point, check for existing record.
+ iter := &span.specials
+ found := false
+ for {
+ s := *iter
+ if s == nil {
+ break
+ }
+ if offset == uintptr(s.offset) && kind == s.kind {
+ found = true
+ break
+ }
+ if offset < uintptr(s.offset) || (offset == uintptr(s.offset) && kind < s.kind) {
+ break
+ }
+ iter = &s.next
+ }
+ return iter, found
+}
+
+// The described object has a finalizer set for it.
+//
+// specialfinalizer is allocated from non-GC'd memory, so any heap
+// pointers must be specially handled.
+type specialfinalizer struct {
+ _ sys.NotInHeap
+ special special
+ fn *funcval // May be a heap pointer.
+ nret uintptr
+ fint *_type // May be a heap pointer, but always live.
+ ot *ptrtype // May be a heap pointer, but always live.
+}
+
+// Adds a finalizer to the object p. Returns true if it succeeded.
+func addfinalizer(p unsafe.Pointer, f *funcval, nret uintptr, fint *_type, ot *ptrtype) bool {
+ lock(&mheap_.speciallock)
+ s := (*specialfinalizer)(mheap_.specialfinalizeralloc.alloc())
+ unlock(&mheap_.speciallock)
+ s.special.kind = _KindSpecialFinalizer
+ s.fn = f
+ s.nret = nret
+ s.fint = fint
+ s.ot = ot
+ if addspecial(p, &s.special) {
+ // This is responsible for maintaining the same
+ // GC-related invariants as markrootSpans in any
+ // situation where it's possible that markrootSpans
+ // has already run but mark termination hasn't yet.
+ if gcphase != _GCoff {
+ base, span, _ := findObject(uintptr(p), 0, 0)
+ mp := acquirem()
+ gcw := &mp.p.ptr().gcw
+ // Mark everything reachable from the object
+ // so it's retained for the finalizer.
+ if !span.spanclass.noscan() {
+ scanobject(base, gcw)
+ }
+ // Mark the finalizer itself, since the
+ // special isn't part of the GC'd heap.
+ scanblock(uintptr(unsafe.Pointer(&s.fn)), goarch.PtrSize, &oneptrmask[0], gcw, nil)
+ releasem(mp)
+ }
+ return true
+ }
+
+ // There was an old finalizer
+ lock(&mheap_.speciallock)
+ mheap_.specialfinalizeralloc.free(unsafe.Pointer(s))
+ unlock(&mheap_.speciallock)
+ return false
+}
+
+// Removes the finalizer (if any) from the object p.
+func removefinalizer(p unsafe.Pointer) {
+ s := (*specialfinalizer)(unsafe.Pointer(removespecial(p, _KindSpecialFinalizer)))
+ if s == nil {
+ return // there wasn't a finalizer to remove
+ }
+ lock(&mheap_.speciallock)
+ mheap_.specialfinalizeralloc.free(unsafe.Pointer(s))
+ unlock(&mheap_.speciallock)
+}
+
+// The described object is being heap profiled.
+type specialprofile struct {
+ _ sys.NotInHeap
+ special special
+ b *bucket
+}
+
+// Set the heap profile bucket associated with addr to b.
+func setprofilebucket(p unsafe.Pointer, b *bucket) {
+ lock(&mheap_.speciallock)
+ s := (*specialprofile)(mheap_.specialprofilealloc.alloc())
+ unlock(&mheap_.speciallock)
+ s.special.kind = _KindSpecialProfile
+ s.b = b
+ if !addspecial(p, &s.special) {
+ throw("setprofilebucket: profile already set")
+ }
+}
+
+// specialReachable tracks whether an object is reachable on the next
+// GC cycle. This is used by testing.
+type specialReachable struct {
+ special special
+ done bool
+ reachable bool
+}
+
+// specialPinCounter tracks whether an object is pinned multiple times.
+type specialPinCounter struct {
+ special special
+ counter uintptr
+}
+
+// specialsIter helps iterate over specials lists.
+type specialsIter struct {
+ pprev **special
+ s *special
+}
+
+func newSpecialsIter(span *mspan) specialsIter {
+ return specialsIter{&span.specials, span.specials}
+}
+
+func (i *specialsIter) valid() bool {
+ return i.s != nil
+}
+
+func (i *specialsIter) next() {
+ i.pprev = &i.s.next
+ i.s = *i.pprev
+}
+
+// unlinkAndNext removes the current special from the list and moves
+// the iterator to the next special. It returns the unlinked special.
+func (i *specialsIter) unlinkAndNext() *special {
+ cur := i.s
+ i.s = cur.next
+ *i.pprev = i.s
+ return cur
+}
+
+// freeSpecial performs any cleanup on special s and deallocates it.
+// s must already be unlinked from the specials list.
+func freeSpecial(s *special, p unsafe.Pointer, size uintptr) {
+ switch s.kind {
+ case _KindSpecialFinalizer:
+ sf := (*specialfinalizer)(unsafe.Pointer(s))
+ queuefinalizer(p, sf.fn, sf.nret, sf.fint, sf.ot)
+ lock(&mheap_.speciallock)
+ mheap_.specialfinalizeralloc.free(unsafe.Pointer(sf))
+ unlock(&mheap_.speciallock)
+ case _KindSpecialProfile:
+ sp := (*specialprofile)(unsafe.Pointer(s))
+ mProf_Free(sp.b, size)
+ lock(&mheap_.speciallock)
+ mheap_.specialprofilealloc.free(unsafe.Pointer(sp))
+ unlock(&mheap_.speciallock)
+ case _KindSpecialReachable:
+ sp := (*specialReachable)(unsafe.Pointer(s))
+ sp.done = true
+ // The creator frees these.
+ case _KindSpecialPinCounter:
+ lock(&mheap_.speciallock)
+ mheap_.specialPinCounterAlloc.free(unsafe.Pointer(s))
+ unlock(&mheap_.speciallock)
+ default:
+ throw("bad special kind")
+ panic("not reached")
+ }
+}
+
+// gcBits is an alloc/mark bitmap. This is always used as gcBits.x.
+type gcBits struct {
+ _ sys.NotInHeap
+ x uint8
+}
+
+// bytep returns a pointer to the n'th byte of b.
+func (b *gcBits) bytep(n uintptr) *uint8 {
+ return addb(&b.x, n)
+}
+
+// bitp returns a pointer to the byte containing bit n and a mask for
+// selecting that bit from *bytep.
+func (b *gcBits) bitp(n uintptr) (bytep *uint8, mask uint8) {
+ return b.bytep(n / 8), 1 << (n % 8)
+}
+
+const gcBitsChunkBytes = uintptr(64 << 10)
+const gcBitsHeaderBytes = unsafe.Sizeof(gcBitsHeader{})
+
+type gcBitsHeader struct {
+ free uintptr // free is the index into bits of the next free byte.
+ next uintptr // *gcBits triggers recursive type bug. (issue 14620)
+}
+
+type gcBitsArena struct {
+ _ sys.NotInHeap
+ // gcBitsHeader // side step recursive type bug (issue 14620) by including fields by hand.
+ free uintptr // free is the index into bits of the next free byte; read/write atomically
+ next *gcBitsArena
+ bits [gcBitsChunkBytes - gcBitsHeaderBytes]gcBits
+}
+
+var gcBitsArenas struct {
+ lock mutex
+ free *gcBitsArena
+ next *gcBitsArena // Read atomically. Write atomically under lock.
+ current *gcBitsArena
+ previous *gcBitsArena
+}
+
+// tryAlloc allocates from b or returns nil if b does not have enough room.
+// This is safe to call concurrently.
+func (b *gcBitsArena) tryAlloc(bytes uintptr) *gcBits {
+ if b == nil || atomic.Loaduintptr(&b.free)+bytes > uintptr(len(b.bits)) {
+ return nil
+ }
+ // Try to allocate from this block.
+ end := atomic.Xadduintptr(&b.free, bytes)
+ if end > uintptr(len(b.bits)) {
+ return nil
+ }
+ // There was enough room.
+ start := end - bytes
+ return &b.bits[start]
+}
+
+// newMarkBits returns a pointer to 8 byte aligned bytes
+// to be used for a span's mark bits.
+func newMarkBits(nelems uintptr) *gcBits {
+ blocksNeeded := uintptr((nelems + 63) / 64)
+ bytesNeeded := blocksNeeded * 8
+
+ // Try directly allocating from the current head arena.
+ head := (*gcBitsArena)(atomic.Loadp(unsafe.Pointer(&gcBitsArenas.next)))
+ if p := head.tryAlloc(bytesNeeded); p != nil {
+ return p
+ }
+
+ // There's not enough room in the head arena. We may need to
+ // allocate a new arena.
+ lock(&gcBitsArenas.lock)
+ // Try the head arena again, since it may have changed. Now
+ // that we hold the lock, the list head can't change, but its
+ // free position still can.
+ if p := gcBitsArenas.next.tryAlloc(bytesNeeded); p != nil {
+ unlock(&gcBitsArenas.lock)
+ return p
+ }
+
+ // Allocate a new arena. This may temporarily drop the lock.
+ fresh := newArenaMayUnlock()
+ // If newArenaMayUnlock dropped the lock, another thread may
+ // have put a fresh arena on the "next" list. Try allocating
+ // from next again.
+ if p := gcBitsArenas.next.tryAlloc(bytesNeeded); p != nil {
+ // Put fresh back on the free list.
+ // TODO: Mark it "already zeroed"
+ fresh.next = gcBitsArenas.free
+ gcBitsArenas.free = fresh
+ unlock(&gcBitsArenas.lock)
+ return p
+ }
+
+ // Allocate from the fresh arena. We haven't linked it in yet, so
+ // this cannot race and is guaranteed to succeed.
+ p := fresh.tryAlloc(bytesNeeded)
+ if p == nil {
+ throw("markBits overflow")
+ }
+
+ // Add the fresh arena to the "next" list.
+ fresh.next = gcBitsArenas.next
+ atomic.StorepNoWB(unsafe.Pointer(&gcBitsArenas.next), unsafe.Pointer(fresh))
+
+ unlock(&gcBitsArenas.lock)
+ return p
+}
+
+// newAllocBits returns a pointer to 8 byte aligned bytes
+// to be used for this span's alloc bits.
+// newAllocBits is used to provide newly initialized spans
+// allocation bits. For spans not being initialized the
+// mark bits are repurposed as allocation bits when
+// the span is swept.
+func newAllocBits(nelems uintptr) *gcBits {
+ return newMarkBits(nelems)
+}
+
+// nextMarkBitArenaEpoch establishes a new epoch for the arenas
+// holding the mark bits. The arenas are named relative to the
+// current GC cycle which is demarcated by the call to finishweep_m.
+//
+// All current spans have been swept.
+// During that sweep each span allocated room for its gcmarkBits in
+// gcBitsArenas.next block. gcBitsArenas.next becomes the gcBitsArenas.current
+// where the GC will mark objects and after each span is swept these bits
+// will be used to allocate objects.
+// gcBitsArenas.current becomes gcBitsArenas.previous where the span's
+// gcAllocBits live until all the spans have been swept during this GC cycle.
+// The span's sweep extinguishes all the references to gcBitsArenas.previous
+// by pointing gcAllocBits into the gcBitsArenas.current.
+// The gcBitsArenas.previous is released to the gcBitsArenas.free list.
+func nextMarkBitArenaEpoch() {
+ lock(&gcBitsArenas.lock)
+ if gcBitsArenas.previous != nil {
+ if gcBitsArenas.free == nil {
+ gcBitsArenas.free = gcBitsArenas.previous
+ } else {
+ // Find end of previous arenas.
+ last := gcBitsArenas.previous
+ for last = gcBitsArenas.previous; last.next != nil; last = last.next {
+ }
+ last.next = gcBitsArenas.free
+ gcBitsArenas.free = gcBitsArenas.previous
+ }
+ }
+ gcBitsArenas.previous = gcBitsArenas.current
+ gcBitsArenas.current = gcBitsArenas.next
+ atomic.StorepNoWB(unsafe.Pointer(&gcBitsArenas.next), nil) // newMarkBits calls newArena when needed
+ unlock(&gcBitsArenas.lock)
+}
+
+// newArenaMayUnlock allocates and zeroes a gcBits arena.
+// The caller must hold gcBitsArena.lock. This may temporarily release it.
+func newArenaMayUnlock() *gcBitsArena {
+ var result *gcBitsArena
+ if gcBitsArenas.free == nil {
+ unlock(&gcBitsArenas.lock)
+ result = (*gcBitsArena)(sysAlloc(gcBitsChunkBytes, &memstats.gcMiscSys))
+ if result == nil {
+ throw("runtime: cannot allocate memory")
+ }
+ lock(&gcBitsArenas.lock)
+ } else {
+ result = gcBitsArenas.free
+ gcBitsArenas.free = gcBitsArenas.free.next
+ memclrNoHeapPointers(unsafe.Pointer(result), gcBitsChunkBytes)
+ }
+ result.next = nil
+ // If result.bits is not 8 byte aligned adjust index so
+ // that &result.bits[result.free] is 8 byte aligned.
+ if uintptr(unsafe.Offsetof(gcBitsArena{}.bits))&7 == 0 {
+ result.free = 0
+ } else {
+ result.free = 8 - (uintptr(unsafe.Pointer(&result.bits[0])) & 7)
+ }
+ return result
+}
diff --git a/contrib/go/_std_1.21/src/runtime/minmax.go b/contrib/go/_std_1.21/src/runtime/minmax.go
new file mode 100644
index 0000000000..e5efc65c1d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/minmax.go
@@ -0,0 +1,72 @@
+// Copyright 2023 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 runtime
+
+import "unsafe"
+
+func strmin(x, y string) string {
+ if y < x {
+ return y
+ }
+ return x
+}
+
+func strmax(x, y string) string {
+ if y > x {
+ return y
+ }
+ return x
+}
+
+func fmin32(x, y float32) float32 { return fmin(x, y) }
+func fmin64(x, y float64) float64 { return fmin(x, y) }
+func fmax32(x, y float32) float32 { return fmax(x, y) }
+func fmax64(x, y float64) float64 { return fmax(x, y) }
+
+type floaty interface{ ~float32 | ~float64 }
+
+func fmin[F floaty](x, y F) F {
+ if y != y || y < x {
+ return y
+ }
+ if x != x || x < y || x != 0 {
+ return x
+ }
+ // x and y are both ±0
+ // if either is -0, return -0; else return +0
+ return forbits(x, y)
+}
+
+func fmax[F floaty](x, y F) F {
+ if y != y || y > x {
+ return y
+ }
+ if x != x || x > y || x != 0 {
+ return x
+ }
+ // x and y are both ±0
+ // if both are -0, return -0; else return +0
+ return fandbits(x, y)
+}
+
+func forbits[F floaty](x, y F) F {
+ switch unsafe.Sizeof(x) {
+ case 4:
+ *(*uint32)(unsafe.Pointer(&x)) |= *(*uint32)(unsafe.Pointer(&y))
+ case 8:
+ *(*uint64)(unsafe.Pointer(&x)) |= *(*uint64)(unsafe.Pointer(&y))
+ }
+ return x
+}
+
+func fandbits[F floaty](x, y F) F {
+ switch unsafe.Sizeof(x) {
+ case 4:
+ *(*uint32)(unsafe.Pointer(&x)) &= *(*uint32)(unsafe.Pointer(&y))
+ case 8:
+ *(*uint64)(unsafe.Pointer(&x)) &= *(*uint64)(unsafe.Pointer(&y))
+ }
+ return x
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mpagealloc.go b/contrib/go/_std_1.21/src/runtime/mpagealloc.go
new file mode 100644
index 0000000000..3e789ab85c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mpagealloc.go
@@ -0,0 +1,1077 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Page allocator.
+//
+// The page allocator manages mapped pages (defined by pageSize, NOT
+// physPageSize) for allocation and re-use. It is embedded into mheap.
+//
+// Pages are managed using a bitmap that is sharded into chunks.
+// In the bitmap, 1 means in-use, and 0 means free. The bitmap spans the
+// process's address space. Chunks are managed in a sparse-array-style structure
+// similar to mheap.arenas, since the bitmap may be large on some systems.
+//
+// The bitmap is efficiently searched by using a radix tree in combination
+// with fast bit-wise intrinsics. Allocation is performed using an address-ordered
+// first-fit approach.
+//
+// Each entry in the radix tree is a summary that describes three properties of
+// a particular region of the address space: the number of contiguous free pages
+// at the start and end of the region it represents, and the maximum number of
+// contiguous free pages found anywhere in that region.
+//
+// Each level of the radix tree is stored as one contiguous array, which represents
+// a different granularity of subdivision of the processes' address space. Thus, this
+// radix tree is actually implicit in these large arrays, as opposed to having explicit
+// dynamically-allocated pointer-based node structures. Naturally, these arrays may be
+// quite large for system with large address spaces, so in these cases they are mapped
+// into memory as needed. The leaf summaries of the tree correspond to a bitmap chunk.
+//
+// The root level (referred to as L0 and index 0 in pageAlloc.summary) has each
+// summary represent the largest section of address space (16 GiB on 64-bit systems),
+// with each subsequent level representing successively smaller subsections until we
+// reach the finest granularity at the leaves, a chunk.
+//
+// More specifically, each summary in each level (except for leaf summaries)
+// represents some number of entries in the following level. For example, each
+// summary in the root level may represent a 16 GiB region of address space,
+// and in the next level there could be 8 corresponding entries which represent 2
+// GiB subsections of that 16 GiB region, each of which could correspond to 8
+// entries in the next level which each represent 256 MiB regions, and so on.
+//
+// Thus, this design only scales to heaps so large, but can always be extended to
+// larger heaps by simply adding levels to the radix tree, which mostly costs
+// additional virtual address space. The choice of managing large arrays also means
+// that a large amount of virtual address space may be reserved by the runtime.
+
+package runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+const (
+ // The size of a bitmap chunk, i.e. the amount of bits (that is, pages) to consider
+ // in the bitmap at once.
+ pallocChunkPages = 1 << logPallocChunkPages
+ pallocChunkBytes = pallocChunkPages * pageSize
+ logPallocChunkPages = 9
+ logPallocChunkBytes = logPallocChunkPages + pageShift
+
+ // The number of radix bits for each level.
+ //
+ // The value of 3 is chosen such that the block of summaries we need to scan at
+ // each level fits in 64 bytes (2^3 summaries * 8 bytes per summary), which is
+ // close to the L1 cache line width on many systems. Also, a value of 3 fits 4 tree
+ // levels perfectly into the 21-bit pallocBits summary field at the root level.
+ //
+ // The following equation explains how each of the constants relate:
+ // summaryL0Bits + (summaryLevels-1)*summaryLevelBits + logPallocChunkBytes = heapAddrBits
+ //
+ // summaryLevels is an architecture-dependent value defined in mpagealloc_*.go.
+ summaryLevelBits = 3
+ summaryL0Bits = heapAddrBits - logPallocChunkBytes - (summaryLevels-1)*summaryLevelBits
+
+ // pallocChunksL2Bits is the number of bits of the chunk index number
+ // covered by the second level of the chunks map.
+ //
+ // See (*pageAlloc).chunks for more details. Update the documentation
+ // there should this change.
+ pallocChunksL2Bits = heapAddrBits - logPallocChunkBytes - pallocChunksL1Bits
+ pallocChunksL1Shift = pallocChunksL2Bits
+)
+
+// maxSearchAddr returns the maximum searchAddr value, which indicates
+// that the heap has no free space.
+//
+// This function exists just to make it clear that this is the maximum address
+// for the page allocator's search space. See maxOffAddr for details.
+//
+// It's a function (rather than a variable) because it needs to be
+// usable before package runtime's dynamic initialization is complete.
+// See #51913 for details.
+func maxSearchAddr() offAddr { return maxOffAddr }
+
+// Global chunk index.
+//
+// Represents an index into the leaf level of the radix tree.
+// Similar to arenaIndex, except instead of arenas, it divides the address
+// space into chunks.
+type chunkIdx uint
+
+// chunkIndex returns the global index of the palloc chunk containing the
+// pointer p.
+func chunkIndex(p uintptr) chunkIdx {
+ return chunkIdx((p - arenaBaseOffset) / pallocChunkBytes)
+}
+
+// chunkBase returns the base address of the palloc chunk at index ci.
+func chunkBase(ci chunkIdx) uintptr {
+ return uintptr(ci)*pallocChunkBytes + arenaBaseOffset
+}
+
+// chunkPageIndex computes the index of the page that contains p,
+// relative to the chunk which contains p.
+func chunkPageIndex(p uintptr) uint {
+ return uint(p % pallocChunkBytes / pageSize)
+}
+
+// l1 returns the index into the first level of (*pageAlloc).chunks.
+func (i chunkIdx) l1() uint {
+ if pallocChunksL1Bits == 0 {
+ // Let the compiler optimize this away if there's no
+ // L1 map.
+ return 0
+ } else {
+ return uint(i) >> pallocChunksL1Shift
+ }
+}
+
+// l2 returns the index into the second level of (*pageAlloc).chunks.
+func (i chunkIdx) l2() uint {
+ if pallocChunksL1Bits == 0 {
+ return uint(i)
+ } else {
+ return uint(i) & (1<<pallocChunksL2Bits - 1)
+ }
+}
+
+// offAddrToLevelIndex converts an address in the offset address space
+// to the index into summary[level] containing addr.
+func offAddrToLevelIndex(level int, addr offAddr) int {
+ return int((addr.a - arenaBaseOffset) >> levelShift[level])
+}
+
+// levelIndexToOffAddr converts an index into summary[level] into
+// the corresponding address in the offset address space.
+func levelIndexToOffAddr(level, idx int) offAddr {
+ return offAddr{(uintptr(idx) << levelShift[level]) + arenaBaseOffset}
+}
+
+// addrsToSummaryRange converts base and limit pointers into a range
+// of entries for the given summary level.
+//
+// The returned range is inclusive on the lower bound and exclusive on
+// the upper bound.
+func addrsToSummaryRange(level int, base, limit uintptr) (lo int, hi int) {
+ // This is slightly more nuanced than just a shift for the exclusive
+ // upper-bound. Note that the exclusive upper bound may be within a
+ // summary at this level, meaning if we just do the obvious computation
+ // hi will end up being an inclusive upper bound. Unfortunately, just
+ // adding 1 to that is too broad since we might be on the very edge
+ // of a summary's max page count boundary for this level
+ // (1 << levelLogPages[level]). So, make limit an inclusive upper bound
+ // then shift, then add 1, so we get an exclusive upper bound at the end.
+ lo = int((base - arenaBaseOffset) >> levelShift[level])
+ hi = int(((limit-1)-arenaBaseOffset)>>levelShift[level]) + 1
+ return
+}
+
+// blockAlignSummaryRange aligns indices into the given level to that
+// level's block width (1 << levelBits[level]). It assumes lo is inclusive
+// and hi is exclusive, and so aligns them down and up respectively.
+func blockAlignSummaryRange(level int, lo, hi int) (int, int) {
+ e := uintptr(1) << levelBits[level]
+ return int(alignDown(uintptr(lo), e)), int(alignUp(uintptr(hi), e))
+}
+
+type pageAlloc struct {
+ // Radix tree of summaries.
+ //
+ // Each slice's cap represents the whole memory reservation.
+ // Each slice's len reflects the allocator's maximum known
+ // mapped heap address for that level.
+ //
+ // The backing store of each summary level is reserved in init
+ // and may or may not be committed in grow (small address spaces
+ // may commit all the memory in init).
+ //
+ // The purpose of keeping len <= cap is to enforce bounds checks
+ // on the top end of the slice so that instead of an unknown
+ // runtime segmentation fault, we get a much friendlier out-of-bounds
+ // error.
+ //
+ // To iterate over a summary level, use inUse to determine which ranges
+ // are currently available. Otherwise one might try to access
+ // memory which is only Reserved which may result in a hard fault.
+ //
+ // We may still get segmentation faults < len since some of that
+ // memory may not be committed yet.
+ summary [summaryLevels][]pallocSum
+
+ // chunks is a slice of bitmap chunks.
+ //
+ // The total size of chunks is quite large on most 64-bit platforms
+ // (O(GiB) or more) if flattened, so rather than making one large mapping
+ // (which has problems on some platforms, even when PROT_NONE) we use a
+ // two-level sparse array approach similar to the arena index in mheap.
+ //
+ // To find the chunk containing a memory address `a`, do:
+ // chunkOf(chunkIndex(a))
+ //
+ // Below is a table describing the configuration for chunks for various
+ // heapAddrBits supported by the runtime.
+ //
+ // heapAddrBits | L1 Bits | L2 Bits | L2 Entry Size
+ // ------------------------------------------------
+ // 32 | 0 | 10 | 128 KiB
+ // 33 (iOS) | 0 | 11 | 256 KiB
+ // 48 | 13 | 13 | 1 MiB
+ //
+ // There's no reason to use the L1 part of chunks on 32-bit, the
+ // address space is small so the L2 is small. For platforms with a
+ // 48-bit address space, we pick the L1 such that the L2 is 1 MiB
+ // in size, which is a good balance between low granularity without
+ // making the impact on BSS too high (note the L1 is stored directly
+ // in pageAlloc).
+ //
+ // To iterate over the bitmap, use inUse to determine which ranges
+ // are currently available. Otherwise one might iterate over unused
+ // ranges.
+ //
+ // Protected by mheapLock.
+ //
+ // TODO(mknyszek): Consider changing the definition of the bitmap
+ // such that 1 means free and 0 means in-use so that summaries and
+ // the bitmaps align better on zero-values.
+ chunks [1 << pallocChunksL1Bits]*[1 << pallocChunksL2Bits]pallocData
+
+ // The address to start an allocation search with. It must never
+ // point to any memory that is not contained in inUse, i.e.
+ // inUse.contains(searchAddr.addr()) must always be true. The one
+ // exception to this rule is that it may take on the value of
+ // maxOffAddr to indicate that the heap is exhausted.
+ //
+ // We guarantee that all valid heap addresses below this value
+ // are allocated and not worth searching.
+ searchAddr offAddr
+
+ // start and end represent the chunk indices
+ // which pageAlloc knows about. It assumes
+ // chunks in the range [start, end) are
+ // currently ready to use.
+ start, end chunkIdx
+
+ // inUse is a slice of ranges of address space which are
+ // known by the page allocator to be currently in-use (passed
+ // to grow).
+ //
+ // We care much more about having a contiguous heap in these cases
+ // and take additional measures to ensure that, so in nearly all
+ // cases this should have just 1 element.
+ //
+ // All access is protected by the mheapLock.
+ inUse addrRanges
+
+ // scav stores the scavenger state.
+ scav struct {
+ // index is an efficient index of chunks that have pages available to
+ // scavenge.
+ index scavengeIndex
+
+ // releasedBg is the amount of memory released in the background this
+ // scavenge cycle.
+ releasedBg atomic.Uintptr
+
+ // releasedEager is the amount of memory released eagerly this scavenge
+ // cycle.
+ releasedEager atomic.Uintptr
+ }
+
+ // mheap_.lock. This level of indirection makes it possible
+ // to test pageAlloc independently of the runtime allocator.
+ mheapLock *mutex
+
+ // sysStat is the runtime memstat to update when new system
+ // memory is committed by the pageAlloc for allocation metadata.
+ sysStat *sysMemStat
+
+ // summaryMappedReady is the number of bytes mapped in the Ready state
+ // in the summary structure. Used only for testing currently.
+ //
+ // Protected by mheapLock.
+ summaryMappedReady uintptr
+
+ // chunkHugePages indicates whether page bitmap chunks should be backed
+ // by huge pages.
+ chunkHugePages bool
+
+ // Whether or not this struct is being used in tests.
+ test bool
+}
+
+func (p *pageAlloc) init(mheapLock *mutex, sysStat *sysMemStat, test bool) {
+ if levelLogPages[0] > logMaxPackedValue {
+ // We can't represent 1<<levelLogPages[0] pages, the maximum number
+ // of pages we need to represent at the root level, in a summary, which
+ // is a big problem. Throw.
+ print("runtime: root level max pages = ", 1<<levelLogPages[0], "\n")
+ print("runtime: summary max pages = ", maxPackedValue, "\n")
+ throw("root level max pages doesn't fit in summary")
+ }
+ p.sysStat = sysStat
+
+ // Initialize p.inUse.
+ p.inUse.init(sysStat)
+
+ // System-dependent initialization.
+ p.sysInit(test)
+
+ // Start with the searchAddr in a state indicating there's no free memory.
+ p.searchAddr = maxSearchAddr()
+
+ // Set the mheapLock.
+ p.mheapLock = mheapLock
+
+ // Initialize the scavenge index.
+ p.summaryMappedReady += p.scav.index.init(test, sysStat)
+
+ // Set if we're in a test.
+ p.test = test
+}
+
+// tryChunkOf returns the bitmap data for the given chunk.
+//
+// Returns nil if the chunk data has not been mapped.
+func (p *pageAlloc) tryChunkOf(ci chunkIdx) *pallocData {
+ l2 := p.chunks[ci.l1()]
+ if l2 == nil {
+ return nil
+ }
+ return &l2[ci.l2()]
+}
+
+// chunkOf returns the chunk at the given chunk index.
+//
+// The chunk index must be valid or this method may throw.
+func (p *pageAlloc) chunkOf(ci chunkIdx) *pallocData {
+ return &p.chunks[ci.l1()][ci.l2()]
+}
+
+// grow sets up the metadata for the address range [base, base+size).
+// It may allocate metadata, in which case *p.sysStat will be updated.
+//
+// p.mheapLock must be held.
+func (p *pageAlloc) grow(base, size uintptr) {
+ assertLockHeld(p.mheapLock)
+
+ // Round up to chunks, since we can't deal with increments smaller
+ // than chunks. Also, sysGrow expects aligned values.
+ limit := alignUp(base+size, pallocChunkBytes)
+ base = alignDown(base, pallocChunkBytes)
+
+ // Grow the summary levels in a system-dependent manner.
+ // We just update a bunch of additional metadata here.
+ p.sysGrow(base, limit)
+
+ // Grow the scavenge index.
+ p.summaryMappedReady += p.scav.index.grow(base, limit, p.sysStat)
+
+ // Update p.start and p.end.
+ // If no growth happened yet, start == 0. This is generally
+ // safe since the zero page is unmapped.
+ firstGrowth := p.start == 0
+ start, end := chunkIndex(base), chunkIndex(limit)
+ if firstGrowth || start < p.start {
+ p.start = start
+ }
+ if end > p.end {
+ p.end = end
+ }
+ // Note that [base, limit) will never overlap with any existing
+ // range inUse because grow only ever adds never-used memory
+ // regions to the page allocator.
+ p.inUse.add(makeAddrRange(base, limit))
+
+ // A grow operation is a lot like a free operation, so if our
+ // chunk ends up below p.searchAddr, update p.searchAddr to the
+ // new address, just like in free.
+ if b := (offAddr{base}); b.lessThan(p.searchAddr) {
+ p.searchAddr = b
+ }
+
+ // Add entries into chunks, which is sparse, if needed. Then,
+ // initialize the bitmap.
+ //
+ // Newly-grown memory is always considered scavenged.
+ // Set all the bits in the scavenged bitmaps high.
+ for c := chunkIndex(base); c < chunkIndex(limit); c++ {
+ if p.chunks[c.l1()] == nil {
+ // Create the necessary l2 entry.
+ const l2Size = unsafe.Sizeof(*p.chunks[0])
+ r := sysAlloc(l2Size, p.sysStat)
+ if r == nil {
+ throw("pageAlloc: out of memory")
+ }
+ if !p.test {
+ // Make the chunk mapping eligible or ineligible
+ // for huge pages, depending on what our current
+ // state is.
+ if p.chunkHugePages {
+ sysHugePage(r, l2Size)
+ } else {
+ sysNoHugePage(r, l2Size)
+ }
+ }
+ // Store the new chunk block but avoid a write barrier.
+ // grow is used in call chains that disallow write barriers.
+ *(*uintptr)(unsafe.Pointer(&p.chunks[c.l1()])) = uintptr(r)
+ }
+ p.chunkOf(c).scavenged.setRange(0, pallocChunkPages)
+ }
+
+ // Update summaries accordingly. The grow acts like a free, so
+ // we need to ensure this newly-free memory is visible in the
+ // summaries.
+ p.update(base, size/pageSize, true, false)
+}
+
+// enableChunkHugePages enables huge pages for the chunk bitmap mappings (disabled by default).
+//
+// This function is idempotent.
+//
+// A note on latency: for sufficiently small heaps (<10s of GiB) this function will take constant
+// time, but may take time proportional to the size of the mapped heap beyond that.
+//
+// The heap lock must not be held over this operation, since it will briefly acquire
+// the heap lock.
+func (p *pageAlloc) enableChunkHugePages() {
+ // Grab the heap lock to turn on huge pages for new chunks and clone the current
+ // heap address space ranges.
+ //
+ // After the lock is released, we can be sure that bitmaps for any new chunks may
+ // be backed with huge pages, and we have the address space for the rest of the
+ // chunks. At the end of this function, all chunk metadata should be backed by huge
+ // pages.
+ lock(&mheap_.lock)
+ if p.chunkHugePages {
+ unlock(&mheap_.lock)
+ return
+ }
+ p.chunkHugePages = true
+ var inUse addrRanges
+ inUse.sysStat = p.sysStat
+ p.inUse.cloneInto(&inUse)
+ unlock(&mheap_.lock)
+
+ // This might seem like a lot of work, but all these loops are for generality.
+ //
+ // For a 1 GiB contiguous heap, a 48-bit address space, 13 L1 bits, a palloc chunk size
+ // of 4 MiB, and adherence to the default set of heap address hints, this will result in
+ // exactly 1 call to sysHugePage.
+ for _, r := range p.inUse.ranges {
+ for i := chunkIndex(r.base.addr()).l1(); i < chunkIndex(r.limit.addr()-1).l1(); i++ {
+ // N.B. We can assume that p.chunks[i] is non-nil and in a mapped part of p.chunks
+ // because it's derived from inUse, which never shrinks.
+ sysHugePage(unsafe.Pointer(p.chunks[i]), unsafe.Sizeof(*p.chunks[0]))
+ }
+ }
+}
+
+// update updates heap metadata. It must be called each time the bitmap
+// is updated.
+//
+// If contig is true, update does some optimizations assuming that there was
+// a contiguous allocation or free between addr and addr+npages. alloc indicates
+// whether the operation performed was an allocation or a free.
+//
+// p.mheapLock must be held.
+func (p *pageAlloc) update(base, npages uintptr, contig, alloc bool) {
+ assertLockHeld(p.mheapLock)
+
+ // base, limit, start, and end are inclusive.
+ limit := base + npages*pageSize - 1
+ sc, ec := chunkIndex(base), chunkIndex(limit)
+
+ // Handle updating the lowest level first.
+ if sc == ec {
+ // Fast path: the allocation doesn't span more than one chunk,
+ // so update this one and if the summary didn't change, return.
+ x := p.summary[len(p.summary)-1][sc]
+ y := p.chunkOf(sc).summarize()
+ if x == y {
+ return
+ }
+ p.summary[len(p.summary)-1][sc] = y
+ } else if contig {
+ // Slow contiguous path: the allocation spans more than one chunk
+ // and at least one summary is guaranteed to change.
+ summary := p.summary[len(p.summary)-1]
+
+ // Update the summary for chunk sc.
+ summary[sc] = p.chunkOf(sc).summarize()
+
+ // Update the summaries for chunks in between, which are
+ // either totally allocated or freed.
+ whole := p.summary[len(p.summary)-1][sc+1 : ec]
+ if alloc {
+ // Should optimize into a memclr.
+ for i := range whole {
+ whole[i] = 0
+ }
+ } else {
+ for i := range whole {
+ whole[i] = freeChunkSum
+ }
+ }
+
+ // Update the summary for chunk ec.
+ summary[ec] = p.chunkOf(ec).summarize()
+ } else {
+ // Slow general path: the allocation spans more than one chunk
+ // and at least one summary is guaranteed to change.
+ //
+ // We can't assume a contiguous allocation happened, so walk over
+ // every chunk in the range and manually recompute the summary.
+ summary := p.summary[len(p.summary)-1]
+ for c := sc; c <= ec; c++ {
+ summary[c] = p.chunkOf(c).summarize()
+ }
+ }
+
+ // Walk up the radix tree and update the summaries appropriately.
+ changed := true
+ for l := len(p.summary) - 2; l >= 0 && changed; l-- {
+ // Update summaries at level l from summaries at level l+1.
+ changed = false
+
+ // "Constants" for the previous level which we
+ // need to compute the summary from that level.
+ logEntriesPerBlock := levelBits[l+1]
+ logMaxPages := levelLogPages[l+1]
+
+ // lo and hi describe all the parts of the level we need to look at.
+ lo, hi := addrsToSummaryRange(l, base, limit+1)
+
+ // Iterate over each block, updating the corresponding summary in the less-granular level.
+ for i := lo; i < hi; i++ {
+ children := p.summary[l+1][i<<logEntriesPerBlock : (i+1)<<logEntriesPerBlock]
+ sum := mergeSummaries(children, logMaxPages)
+ old := p.summary[l][i]
+ if old != sum {
+ changed = true
+ p.summary[l][i] = sum
+ }
+ }
+ }
+}
+
+// allocRange marks the range of memory [base, base+npages*pageSize) as
+// allocated. It also updates the summaries to reflect the newly-updated
+// bitmap.
+//
+// Returns the amount of scavenged memory in bytes present in the
+// allocated range.
+//
+// p.mheapLock must be held.
+func (p *pageAlloc) allocRange(base, npages uintptr) uintptr {
+ assertLockHeld(p.mheapLock)
+
+ limit := base + npages*pageSize - 1
+ sc, ec := chunkIndex(base), chunkIndex(limit)
+ si, ei := chunkPageIndex(base), chunkPageIndex(limit)
+
+ scav := uint(0)
+ if sc == ec {
+ // The range doesn't cross any chunk boundaries.
+ chunk := p.chunkOf(sc)
+ scav += chunk.scavenged.popcntRange(si, ei+1-si)
+ chunk.allocRange(si, ei+1-si)
+ p.scav.index.alloc(sc, ei+1-si)
+ } else {
+ // The range crosses at least one chunk boundary.
+ chunk := p.chunkOf(sc)
+ scav += chunk.scavenged.popcntRange(si, pallocChunkPages-si)
+ chunk.allocRange(si, pallocChunkPages-si)
+ p.scav.index.alloc(sc, pallocChunkPages-si)
+ for c := sc + 1; c < ec; c++ {
+ chunk := p.chunkOf(c)
+ scav += chunk.scavenged.popcntRange(0, pallocChunkPages)
+ chunk.allocAll()
+ p.scav.index.alloc(c, pallocChunkPages)
+ }
+ chunk = p.chunkOf(ec)
+ scav += chunk.scavenged.popcntRange(0, ei+1)
+ chunk.allocRange(0, ei+1)
+ p.scav.index.alloc(ec, ei+1)
+ }
+ p.update(base, npages, true, true)
+ return uintptr(scav) * pageSize
+}
+
+// findMappedAddr returns the smallest mapped offAddr that is
+// >= addr. That is, if addr refers to mapped memory, then it is
+// returned. If addr is higher than any mapped region, then
+// it returns maxOffAddr.
+//
+// p.mheapLock must be held.
+func (p *pageAlloc) findMappedAddr(addr offAddr) offAddr {
+ assertLockHeld(p.mheapLock)
+
+ // If we're not in a test, validate first by checking mheap_.arenas.
+ // This is a fast path which is only safe to use outside of testing.
+ ai := arenaIndex(addr.addr())
+ if p.test || mheap_.arenas[ai.l1()] == nil || mheap_.arenas[ai.l1()][ai.l2()] == nil {
+ vAddr, ok := p.inUse.findAddrGreaterEqual(addr.addr())
+ if ok {
+ return offAddr{vAddr}
+ } else {
+ // The candidate search address is greater than any
+ // known address, which means we definitely have no
+ // free memory left.
+ return maxOffAddr
+ }
+ }
+ return addr
+}
+
+// find searches for the first (address-ordered) contiguous free region of
+// npages in size and returns a base address for that region.
+//
+// It uses p.searchAddr to prune its search and assumes that no palloc chunks
+// below chunkIndex(p.searchAddr) contain any free memory at all.
+//
+// find also computes and returns a candidate p.searchAddr, which may or
+// may not prune more of the address space than p.searchAddr already does.
+// This candidate is always a valid p.searchAddr.
+//
+// find represents the slow path and the full radix tree search.
+//
+// Returns a base address of 0 on failure, in which case the candidate
+// searchAddr returned is invalid and must be ignored.
+//
+// p.mheapLock must be held.
+func (p *pageAlloc) find(npages uintptr) (uintptr, offAddr) {
+ assertLockHeld(p.mheapLock)
+
+ // Search algorithm.
+ //
+ // This algorithm walks each level l of the radix tree from the root level
+ // to the leaf level. It iterates over at most 1 << levelBits[l] of entries
+ // in a given level in the radix tree, and uses the summary information to
+ // find either:
+ // 1) That a given subtree contains a large enough contiguous region, at
+ // which point it continues iterating on the next level, or
+ // 2) That there are enough contiguous boundary-crossing bits to satisfy
+ // the allocation, at which point it knows exactly where to start
+ // allocating from.
+ //
+ // i tracks the index into the current level l's structure for the
+ // contiguous 1 << levelBits[l] entries we're actually interested in.
+ //
+ // NOTE: Technically this search could allocate a region which crosses
+ // the arenaBaseOffset boundary, which when arenaBaseOffset != 0, is
+ // a discontinuity. However, the only way this could happen is if the
+ // page at the zero address is mapped, and this is impossible on
+ // every system we support where arenaBaseOffset != 0. So, the
+ // discontinuity is already encoded in the fact that the OS will never
+ // map the zero page for us, and this function doesn't try to handle
+ // this case in any way.
+
+ // i is the beginning of the block of entries we're searching at the
+ // current level.
+ i := 0
+
+ // firstFree is the region of address space that we are certain to
+ // find the first free page in the heap. base and bound are the inclusive
+ // bounds of this window, and both are addresses in the linearized, contiguous
+ // view of the address space (with arenaBaseOffset pre-added). At each level,
+ // this window is narrowed as we find the memory region containing the
+ // first free page of memory. To begin with, the range reflects the
+ // full process address space.
+ //
+ // firstFree is updated by calling foundFree each time free space in the
+ // heap is discovered.
+ //
+ // At the end of the search, base.addr() is the best new
+ // searchAddr we could deduce in this search.
+ firstFree := struct {
+ base, bound offAddr
+ }{
+ base: minOffAddr,
+ bound: maxOffAddr,
+ }
+ // foundFree takes the given address range [addr, addr+size) and
+ // updates firstFree if it is a narrower range. The input range must
+ // either be fully contained within firstFree or not overlap with it
+ // at all.
+ //
+ // This way, we'll record the first summary we find with any free
+ // pages on the root level and narrow that down if we descend into
+ // that summary. But as soon as we need to iterate beyond that summary
+ // in a level to find a large enough range, we'll stop narrowing.
+ foundFree := func(addr offAddr, size uintptr) {
+ if firstFree.base.lessEqual(addr) && addr.add(size-1).lessEqual(firstFree.bound) {
+ // This range fits within the current firstFree window, so narrow
+ // down the firstFree window to the base and bound of this range.
+ firstFree.base = addr
+ firstFree.bound = addr.add(size - 1)
+ } else if !(addr.add(size-1).lessThan(firstFree.base) || firstFree.bound.lessThan(addr)) {
+ // This range only partially overlaps with the firstFree range,
+ // so throw.
+ print("runtime: addr = ", hex(addr.addr()), ", size = ", size, "\n")
+ print("runtime: base = ", hex(firstFree.base.addr()), ", bound = ", hex(firstFree.bound.addr()), "\n")
+ throw("range partially overlaps")
+ }
+ }
+
+ // lastSum is the summary which we saw on the previous level that made us
+ // move on to the next level. Used to print additional information in the
+ // case of a catastrophic failure.
+ // lastSumIdx is that summary's index in the previous level.
+ lastSum := packPallocSum(0, 0, 0)
+ lastSumIdx := -1
+
+nextLevel:
+ for l := 0; l < len(p.summary); l++ {
+ // For the root level, entriesPerBlock is the whole level.
+ entriesPerBlock := 1 << levelBits[l]
+ logMaxPages := levelLogPages[l]
+
+ // We've moved into a new level, so let's update i to our new
+ // starting index. This is a no-op for level 0.
+ i <<= levelBits[l]
+
+ // Slice out the block of entries we care about.
+ entries := p.summary[l][i : i+entriesPerBlock]
+
+ // Determine j0, the first index we should start iterating from.
+ // The searchAddr may help us eliminate iterations if we followed the
+ // searchAddr on the previous level or we're on the root level, in which
+ // case the searchAddr should be the same as i after levelShift.
+ j0 := 0
+ if searchIdx := offAddrToLevelIndex(l, p.searchAddr); searchIdx&^(entriesPerBlock-1) == i {
+ j0 = searchIdx & (entriesPerBlock - 1)
+ }
+
+ // Run over the level entries looking for
+ // a contiguous run of at least npages either
+ // within an entry or across entries.
+ //
+ // base contains the page index (relative to
+ // the first entry's first page) of the currently
+ // considered run of consecutive pages.
+ //
+ // size contains the size of the currently considered
+ // run of consecutive pages.
+ var base, size uint
+ for j := j0; j < len(entries); j++ {
+ sum := entries[j]
+ if sum == 0 {
+ // A full entry means we broke any streak and
+ // that we should skip it altogether.
+ size = 0
+ continue
+ }
+
+ // We've encountered a non-zero summary which means
+ // free memory, so update firstFree.
+ foundFree(levelIndexToOffAddr(l, i+j), (uintptr(1)<<logMaxPages)*pageSize)
+
+ s := sum.start()
+ if size+s >= uint(npages) {
+ // If size == 0 we don't have a run yet,
+ // which means base isn't valid. So, set
+ // base to the first page in this block.
+ if size == 0 {
+ base = uint(j) << logMaxPages
+ }
+ // We hit npages; we're done!
+ size += s
+ break
+ }
+ if sum.max() >= uint(npages) {
+ // The entry itself contains npages contiguous
+ // free pages, so continue on the next level
+ // to find that run.
+ i += j
+ lastSumIdx = i
+ lastSum = sum
+ continue nextLevel
+ }
+ if size == 0 || s < 1<<logMaxPages {
+ // We either don't have a current run started, or this entry
+ // isn't totally free (meaning we can't continue the current
+ // one), so try to begin a new run by setting size and base
+ // based on sum.end.
+ size = sum.end()
+ base = uint(j+1)<<logMaxPages - size
+ continue
+ }
+ // The entry is completely free, so continue the run.
+ size += 1 << logMaxPages
+ }
+ if size >= uint(npages) {
+ // We found a sufficiently large run of free pages straddling
+ // some boundary, so compute the address and return it.
+ addr := levelIndexToOffAddr(l, i).add(uintptr(base) * pageSize).addr()
+ return addr, p.findMappedAddr(firstFree.base)
+ }
+ if l == 0 {
+ // We're at level zero, so that means we've exhausted our search.
+ return 0, maxSearchAddr()
+ }
+
+ // We're not at level zero, and we exhausted the level we were looking in.
+ // This means that either our calculations were wrong or the level above
+ // lied to us. In either case, dump some useful state and throw.
+ print("runtime: summary[", l-1, "][", lastSumIdx, "] = ", lastSum.start(), ", ", lastSum.max(), ", ", lastSum.end(), "\n")
+ print("runtime: level = ", l, ", npages = ", npages, ", j0 = ", j0, "\n")
+ print("runtime: p.searchAddr = ", hex(p.searchAddr.addr()), ", i = ", i, "\n")
+ print("runtime: levelShift[level] = ", levelShift[l], ", levelBits[level] = ", levelBits[l], "\n")
+ for j := 0; j < len(entries); j++ {
+ sum := entries[j]
+ print("runtime: summary[", l, "][", i+j, "] = (", sum.start(), ", ", sum.max(), ", ", sum.end(), ")\n")
+ }
+ throw("bad summary data")
+ }
+
+ // Since we've gotten to this point, that means we haven't found a
+ // sufficiently-sized free region straddling some boundary (chunk or larger).
+ // This means the last summary we inspected must have had a large enough "max"
+ // value, so look inside the chunk to find a suitable run.
+ //
+ // After iterating over all levels, i must contain a chunk index which
+ // is what the final level represents.
+ ci := chunkIdx(i)
+ j, searchIdx := p.chunkOf(ci).find(npages, 0)
+ if j == ^uint(0) {
+ // We couldn't find any space in this chunk despite the summaries telling
+ // us it should be there. There's likely a bug, so dump some state and throw.
+ sum := p.summary[len(p.summary)-1][i]
+ print("runtime: summary[", len(p.summary)-1, "][", i, "] = (", sum.start(), ", ", sum.max(), ", ", sum.end(), ")\n")
+ print("runtime: npages = ", npages, "\n")
+ throw("bad summary data")
+ }
+
+ // Compute the address at which the free space starts.
+ addr := chunkBase(ci) + uintptr(j)*pageSize
+
+ // Since we actually searched the chunk, we may have
+ // found an even narrower free window.
+ searchAddr := chunkBase(ci) + uintptr(searchIdx)*pageSize
+ foundFree(offAddr{searchAddr}, chunkBase(ci+1)-searchAddr)
+ return addr, p.findMappedAddr(firstFree.base)
+}
+
+// alloc allocates npages worth of memory from the page heap, returning the base
+// address for the allocation and the amount of scavenged memory in bytes
+// contained in the region [base address, base address + npages*pageSize).
+//
+// Returns a 0 base address on failure, in which case other returned values
+// should be ignored.
+//
+// p.mheapLock must be held.
+//
+// Must run on the system stack because p.mheapLock must be held.
+//
+//go:systemstack
+func (p *pageAlloc) alloc(npages uintptr) (addr uintptr, scav uintptr) {
+ assertLockHeld(p.mheapLock)
+
+ // If the searchAddr refers to a region which has a higher address than
+ // any known chunk, then we know we're out of memory.
+ if chunkIndex(p.searchAddr.addr()) >= p.end {
+ return 0, 0
+ }
+
+ // If npages has a chance of fitting in the chunk where the searchAddr is,
+ // search it directly.
+ searchAddr := minOffAddr
+ if pallocChunkPages-chunkPageIndex(p.searchAddr.addr()) >= uint(npages) {
+ // npages is guaranteed to be no greater than pallocChunkPages here.
+ i := chunkIndex(p.searchAddr.addr())
+ if max := p.summary[len(p.summary)-1][i].max(); max >= uint(npages) {
+ j, searchIdx := p.chunkOf(i).find(npages, chunkPageIndex(p.searchAddr.addr()))
+ if j == ^uint(0) {
+ print("runtime: max = ", max, ", npages = ", npages, "\n")
+ print("runtime: searchIdx = ", chunkPageIndex(p.searchAddr.addr()), ", p.searchAddr = ", hex(p.searchAddr.addr()), "\n")
+ throw("bad summary data")
+ }
+ addr = chunkBase(i) + uintptr(j)*pageSize
+ searchAddr = offAddr{chunkBase(i) + uintptr(searchIdx)*pageSize}
+ goto Found
+ }
+ }
+ // We failed to use a searchAddr for one reason or another, so try
+ // the slow path.
+ addr, searchAddr = p.find(npages)
+ if addr == 0 {
+ if npages == 1 {
+ // We failed to find a single free page, the smallest unit
+ // of allocation. This means we know the heap is completely
+ // exhausted. Otherwise, the heap still might have free
+ // space in it, just not enough contiguous space to
+ // accommodate npages.
+ p.searchAddr = maxSearchAddr()
+ }
+ return 0, 0
+ }
+Found:
+ // Go ahead and actually mark the bits now that we have an address.
+ scav = p.allocRange(addr, npages)
+
+ // If we found a higher searchAddr, we know that all the
+ // heap memory before that searchAddr in an offset address space is
+ // allocated, so bump p.searchAddr up to the new one.
+ if p.searchAddr.lessThan(searchAddr) {
+ p.searchAddr = searchAddr
+ }
+ return addr, scav
+}
+
+// free returns npages worth of memory starting at base back to the page heap.
+//
+// p.mheapLock must be held.
+//
+// Must run on the system stack because p.mheapLock must be held.
+//
+//go:systemstack
+func (p *pageAlloc) free(base, npages uintptr) {
+ assertLockHeld(p.mheapLock)
+
+ // If we're freeing pages below the p.searchAddr, update searchAddr.
+ if b := (offAddr{base}); b.lessThan(p.searchAddr) {
+ p.searchAddr = b
+ }
+ limit := base + npages*pageSize - 1
+ if npages == 1 {
+ // Fast path: we're clearing a single bit, and we know exactly
+ // where it is, so mark it directly.
+ i := chunkIndex(base)
+ pi := chunkPageIndex(base)
+ p.chunkOf(i).free1(pi)
+ p.scav.index.free(i, pi, 1)
+ } else {
+ // Slow path: we're clearing more bits so we may need to iterate.
+ sc, ec := chunkIndex(base), chunkIndex(limit)
+ si, ei := chunkPageIndex(base), chunkPageIndex(limit)
+
+ if sc == ec {
+ // The range doesn't cross any chunk boundaries.
+ p.chunkOf(sc).free(si, ei+1-si)
+ p.scav.index.free(sc, si, ei+1-si)
+ } else {
+ // The range crosses at least one chunk boundary.
+ p.chunkOf(sc).free(si, pallocChunkPages-si)
+ p.scav.index.free(sc, si, pallocChunkPages-si)
+ for c := sc + 1; c < ec; c++ {
+ p.chunkOf(c).freeAll()
+ p.scav.index.free(c, 0, pallocChunkPages)
+ }
+ p.chunkOf(ec).free(0, ei+1)
+ p.scav.index.free(ec, 0, ei+1)
+ }
+ }
+ p.update(base, npages, true, false)
+}
+
+const (
+ pallocSumBytes = unsafe.Sizeof(pallocSum(0))
+
+ // maxPackedValue is the maximum value that any of the three fields in
+ // the pallocSum may take on.
+ maxPackedValue = 1 << logMaxPackedValue
+ logMaxPackedValue = logPallocChunkPages + (summaryLevels-1)*summaryLevelBits
+
+ freeChunkSum = pallocSum(uint64(pallocChunkPages) |
+ uint64(pallocChunkPages<<logMaxPackedValue) |
+ uint64(pallocChunkPages<<(2*logMaxPackedValue)))
+)
+
+// pallocSum is a packed summary type which packs three numbers: start, max,
+// and end into a single 8-byte value. Each of these values are a summary of
+// a bitmap and are thus counts, each of which may have a maximum value of
+// 2^21 - 1, or all three may be equal to 2^21. The latter case is represented
+// by just setting the 64th bit.
+type pallocSum uint64
+
+// packPallocSum takes a start, max, and end value and produces a pallocSum.
+func packPallocSum(start, max, end uint) pallocSum {
+ if max == maxPackedValue {
+ return pallocSum(uint64(1 << 63))
+ }
+ return pallocSum((uint64(start) & (maxPackedValue - 1)) |
+ ((uint64(max) & (maxPackedValue - 1)) << logMaxPackedValue) |
+ ((uint64(end) & (maxPackedValue - 1)) << (2 * logMaxPackedValue)))
+}
+
+// start extracts the start value from a packed sum.
+func (p pallocSum) start() uint {
+ if uint64(p)&uint64(1<<63) != 0 {
+ return maxPackedValue
+ }
+ return uint(uint64(p) & (maxPackedValue - 1))
+}
+
+// max extracts the max value from a packed sum.
+func (p pallocSum) max() uint {
+ if uint64(p)&uint64(1<<63) != 0 {
+ return maxPackedValue
+ }
+ return uint((uint64(p) >> logMaxPackedValue) & (maxPackedValue - 1))
+}
+
+// end extracts the end value from a packed sum.
+func (p pallocSum) end() uint {
+ if uint64(p)&uint64(1<<63) != 0 {
+ return maxPackedValue
+ }
+ return uint((uint64(p) >> (2 * logMaxPackedValue)) & (maxPackedValue - 1))
+}
+
+// unpack unpacks all three values from the summary.
+func (p pallocSum) unpack() (uint, uint, uint) {
+ if uint64(p)&uint64(1<<63) != 0 {
+ return maxPackedValue, maxPackedValue, maxPackedValue
+ }
+ return uint(uint64(p) & (maxPackedValue - 1)),
+ uint((uint64(p) >> logMaxPackedValue) & (maxPackedValue - 1)),
+ uint((uint64(p) >> (2 * logMaxPackedValue)) & (maxPackedValue - 1))
+}
+
+// mergeSummaries merges consecutive summaries which may each represent at
+// most 1 << logMaxPagesPerSum pages each together into one.
+func mergeSummaries(sums []pallocSum, logMaxPagesPerSum uint) pallocSum {
+ // Merge the summaries in sums into one.
+ //
+ // We do this by keeping a running summary representing the merged
+ // summaries of sums[:i] in start, max, and end.
+ start, max, end := sums[0].unpack()
+ for i := 1; i < len(sums); i++ {
+ // Merge in sums[i].
+ si, mi, ei := sums[i].unpack()
+
+ // Merge in sums[i].start only if the running summary is
+ // completely free, otherwise this summary's start
+ // plays no role in the combined sum.
+ if start == uint(i)<<logMaxPagesPerSum {
+ start += si
+ }
+
+ // Recompute the max value of the running sum by looking
+ // across the boundary between the running sum and sums[i]
+ // and at the max sums[i], taking the greatest of those two
+ // and the max of the running sum.
+ if end+si > max {
+ max = end + si
+ }
+ if mi > max {
+ max = mi
+ }
+
+ // Merge in end by checking if this new summary is totally
+ // free. If it is, then we want to extend the running sum's
+ // end by the new summary. If not, then we have some alloc'd
+ // pages in there and we just want to take the end value in
+ // sums[i].
+ if ei == 1<<logMaxPagesPerSum {
+ end += 1 << logMaxPagesPerSum
+ } else {
+ end = ei
+ }
+ }
+ return packPallocSum(start, max, end)
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mpagealloc_64bit.go b/contrib/go/_std_1.21/src/runtime/mpagealloc_64bit.go
new file mode 100644
index 0000000000..1418831a50
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mpagealloc_64bit.go
@@ -0,0 +1,258 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x
+
+package runtime
+
+import (
+ "unsafe"
+)
+
+const (
+ // The number of levels in the radix tree.
+ summaryLevels = 5
+
+ // Constants for testing.
+ pageAlloc32Bit = 0
+ pageAlloc64Bit = 1
+
+ // Number of bits needed to represent all indices into the L1 of the
+ // chunks map.
+ //
+ // See (*pageAlloc).chunks for more details. Update the documentation
+ // there should this number change.
+ pallocChunksL1Bits = 13
+)
+
+// levelBits is the number of bits in the radix for a given level in the super summary
+// structure.
+//
+// The sum of all the entries of levelBits should equal heapAddrBits.
+var levelBits = [summaryLevels]uint{
+ summaryL0Bits,
+ summaryLevelBits,
+ summaryLevelBits,
+ summaryLevelBits,
+ summaryLevelBits,
+}
+
+// levelShift is the number of bits to shift to acquire the radix for a given level
+// in the super summary structure.
+//
+// With levelShift, one can compute the index of the summary at level l related to a
+// pointer p by doing:
+//
+// p >> levelShift[l]
+var levelShift = [summaryLevels]uint{
+ heapAddrBits - summaryL0Bits,
+ heapAddrBits - summaryL0Bits - 1*summaryLevelBits,
+ heapAddrBits - summaryL0Bits - 2*summaryLevelBits,
+ heapAddrBits - summaryL0Bits - 3*summaryLevelBits,
+ heapAddrBits - summaryL0Bits - 4*summaryLevelBits,
+}
+
+// levelLogPages is log2 the maximum number of runtime pages in the address space
+// a summary in the given level represents.
+//
+// The leaf level always represents exactly log2 of 1 chunk's worth of pages.
+var levelLogPages = [summaryLevels]uint{
+ logPallocChunkPages + 4*summaryLevelBits,
+ logPallocChunkPages + 3*summaryLevelBits,
+ logPallocChunkPages + 2*summaryLevelBits,
+ logPallocChunkPages + 1*summaryLevelBits,
+ logPallocChunkPages,
+}
+
+// sysInit performs architecture-dependent initialization of fields
+// in pageAlloc. pageAlloc should be uninitialized except for sysStat
+// if any runtime statistic should be updated.
+func (p *pageAlloc) sysInit(test bool) {
+ // Reserve memory for each level. This will get mapped in
+ // as R/W by setArenas.
+ for l, shift := range levelShift {
+ entries := 1 << (heapAddrBits - shift)
+
+ // Reserve b bytes of memory anywhere in the address space.
+ b := alignUp(uintptr(entries)*pallocSumBytes, physPageSize)
+ r := sysReserve(nil, b)
+ if r == nil {
+ throw("failed to reserve page summary memory")
+ }
+
+ // Put this reservation into a slice.
+ sl := notInHeapSlice{(*notInHeap)(r), 0, entries}
+ p.summary[l] = *(*[]pallocSum)(unsafe.Pointer(&sl))
+ }
+}
+
+// sysGrow performs architecture-dependent operations on heap
+// growth for the page allocator, such as mapping in new memory
+// for summaries. It also updates the length of the slices in
+// p.summary.
+//
+// base is the base of the newly-added heap memory and limit is
+// the first address past the end of the newly-added heap memory.
+// Both must be aligned to pallocChunkBytes.
+//
+// The caller must update p.start and p.end after calling sysGrow.
+func (p *pageAlloc) sysGrow(base, limit uintptr) {
+ if base%pallocChunkBytes != 0 || limit%pallocChunkBytes != 0 {
+ print("runtime: base = ", hex(base), ", limit = ", hex(limit), "\n")
+ throw("sysGrow bounds not aligned to pallocChunkBytes")
+ }
+
+ // addrRangeToSummaryRange converts a range of addresses into a range
+ // of summary indices which must be mapped to support those addresses
+ // in the summary range.
+ addrRangeToSummaryRange := func(level int, r addrRange) (int, int) {
+ sumIdxBase, sumIdxLimit := addrsToSummaryRange(level, r.base.addr(), r.limit.addr())
+ return blockAlignSummaryRange(level, sumIdxBase, sumIdxLimit)
+ }
+
+ // summaryRangeToSumAddrRange converts a range of indices in any
+ // level of p.summary into page-aligned addresses which cover that
+ // range of indices.
+ summaryRangeToSumAddrRange := func(level, sumIdxBase, sumIdxLimit int) addrRange {
+ baseOffset := alignDown(uintptr(sumIdxBase)*pallocSumBytes, physPageSize)
+ limitOffset := alignUp(uintptr(sumIdxLimit)*pallocSumBytes, physPageSize)
+ base := unsafe.Pointer(&p.summary[level][0])
+ return addrRange{
+ offAddr{uintptr(add(base, baseOffset))},
+ offAddr{uintptr(add(base, limitOffset))},
+ }
+ }
+
+ // addrRangeToSumAddrRange is a convenience function that converts
+ // an address range r to the address range of the given summary level
+ // that stores the summaries for r.
+ addrRangeToSumAddrRange := func(level int, r addrRange) addrRange {
+ sumIdxBase, sumIdxLimit := addrRangeToSummaryRange(level, r)
+ return summaryRangeToSumAddrRange(level, sumIdxBase, sumIdxLimit)
+ }
+
+ // Find the first inUse index which is strictly greater than base.
+ //
+ // Because this function will never be asked remap the same memory
+ // twice, this index is effectively the index at which we would insert
+ // this new growth, and base will never overlap/be contained within
+ // any existing range.
+ //
+ // This will be used to look at what memory in the summary array is already
+ // mapped before and after this new range.
+ inUseIndex := p.inUse.findSucc(base)
+
+ // Walk up the radix tree and map summaries in as needed.
+ for l := range p.summary {
+ // Figure out what part of the summary array this new address space needs.
+ needIdxBase, needIdxLimit := addrRangeToSummaryRange(l, makeAddrRange(base, limit))
+
+ // Update the summary slices with a new upper-bound. This ensures
+ // we get tight bounds checks on at least the top bound.
+ //
+ // We must do this regardless of whether we map new memory.
+ if needIdxLimit > len(p.summary[l]) {
+ p.summary[l] = p.summary[l][:needIdxLimit]
+ }
+
+ // Compute the needed address range in the summary array for level l.
+ need := summaryRangeToSumAddrRange(l, needIdxBase, needIdxLimit)
+
+ // Prune need down to what needs to be newly mapped. Some parts of it may
+ // already be mapped by what inUse describes due to page alignment requirements
+ // for mapping. Because this function will never be asked to remap the same
+ // memory twice, it should never be possible to prune in such a way that causes
+ // need to be split.
+ if inUseIndex > 0 {
+ need = need.subtract(addrRangeToSumAddrRange(l, p.inUse.ranges[inUseIndex-1]))
+ }
+ if inUseIndex < len(p.inUse.ranges) {
+ need = need.subtract(addrRangeToSumAddrRange(l, p.inUse.ranges[inUseIndex]))
+ }
+ // It's possible that after our pruning above, there's nothing new to map.
+ if need.size() == 0 {
+ continue
+ }
+
+ // Map and commit need.
+ sysMap(unsafe.Pointer(need.base.addr()), need.size(), p.sysStat)
+ sysUsed(unsafe.Pointer(need.base.addr()), need.size(), need.size())
+ p.summaryMappedReady += need.size()
+ }
+
+ // Update the scavenge index.
+ p.summaryMappedReady += p.scav.index.sysGrow(base, limit, p.sysStat)
+}
+
+// sysGrow increases the index's backing store in response to a heap growth.
+//
+// Returns the amount of memory added to sysStat.
+func (s *scavengeIndex) sysGrow(base, limit uintptr, sysStat *sysMemStat) uintptr {
+ if base%pallocChunkBytes != 0 || limit%pallocChunkBytes != 0 {
+ print("runtime: base = ", hex(base), ", limit = ", hex(limit), "\n")
+ throw("sysGrow bounds not aligned to pallocChunkBytes")
+ }
+ scSize := unsafe.Sizeof(atomicScavChunkData{})
+ // Map and commit the pieces of chunks that we need.
+ //
+ // We always map the full range of the minimum heap address to the
+ // maximum heap address. We don't do this for the summary structure
+ // because it's quite large and a discontiguous heap could cause a
+ // lot of memory to be used. In this situation, the worst case overhead
+ // is in the single-digit MiB if we map the whole thing.
+ //
+ // The base address of the backing store is always page-aligned,
+ // because it comes from the OS, so it's sufficient to align the
+ // index.
+ haveMin := s.min.Load()
+ haveMax := s.max.Load()
+ needMin := alignDown(uintptr(chunkIndex(base)), physPageSize/scSize)
+ needMax := alignUp(uintptr(chunkIndex(limit)), physPageSize/scSize)
+ // Extend the range down to what we have, if there's no overlap.
+ if needMax < haveMin {
+ needMax = haveMin
+ }
+ if haveMax != 0 && needMin > haveMax {
+ needMin = haveMax
+ }
+ have := makeAddrRange(
+ // Avoid a panic from indexing one past the last element.
+ uintptr(unsafe.Pointer(&s.chunks[0]))+haveMin*scSize,
+ uintptr(unsafe.Pointer(&s.chunks[0]))+haveMax*scSize,
+ )
+ need := makeAddrRange(
+ // Avoid a panic from indexing one past the last element.
+ uintptr(unsafe.Pointer(&s.chunks[0]))+needMin*scSize,
+ uintptr(unsafe.Pointer(&s.chunks[0]))+needMax*scSize,
+ )
+ // Subtract any overlap from rounding. We can't re-map memory because
+ // it'll be zeroed.
+ need = need.subtract(have)
+
+ // If we've got something to map, map it, and update the slice bounds.
+ if need.size() != 0 {
+ sysMap(unsafe.Pointer(need.base.addr()), need.size(), sysStat)
+ sysUsed(unsafe.Pointer(need.base.addr()), need.size(), need.size())
+ // Update the indices only after the new memory is valid.
+ if haveMin == 0 || needMin < haveMin {
+ s.min.Store(needMin)
+ }
+ if haveMax == 0 || needMax > haveMax {
+ s.max.Store(needMax)
+ }
+ }
+ return need.size()
+}
+
+// sysInit initializes the scavengeIndex' chunks array.
+//
+// Returns the amount of memory added to sysStat.
+func (s *scavengeIndex) sysInit(test bool, sysStat *sysMemStat) uintptr {
+ n := uintptr(1<<heapAddrBits) / pallocChunkBytes
+ nbytes := n * unsafe.Sizeof(atomicScavChunkData{})
+ r := sysReserve(nil, nbytes)
+ sl := notInHeapSlice{(*notInHeap)(r), int(n), int(n)}
+ s.chunks = *(*[]atomicScavChunkData)(unsafe.Pointer(&sl))
+ return 0 // All memory above is mapped Reserved.
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mpagecache.go b/contrib/go/_std_1.21/src/runtime/mpagecache.go
new file mode 100644
index 0000000000..245b0cbfef
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mpagecache.go
@@ -0,0 +1,183 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import (
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+const pageCachePages = 8 * unsafe.Sizeof(pageCache{}.cache)
+
+// pageCache represents a per-p cache of pages the allocator can
+// allocate from without a lock. More specifically, it represents
+// a pageCachePages*pageSize chunk of memory with 0 or more free
+// pages in it.
+type pageCache struct {
+ base uintptr // base address of the chunk
+ cache uint64 // 64-bit bitmap representing free pages (1 means free)
+ scav uint64 // 64-bit bitmap representing scavenged pages (1 means scavenged)
+}
+
+// empty reports whether the page cache has no free pages.
+func (c *pageCache) empty() bool {
+ return c.cache == 0
+}
+
+// alloc allocates npages from the page cache and is the main entry
+// point for allocation.
+//
+// Returns a base address and the amount of scavenged memory in the
+// allocated region in bytes.
+//
+// Returns a base address of zero on failure, in which case the
+// amount of scavenged memory should be ignored.
+func (c *pageCache) alloc(npages uintptr) (uintptr, uintptr) {
+ if c.cache == 0 {
+ return 0, 0
+ }
+ if npages == 1 {
+ i := uintptr(sys.TrailingZeros64(c.cache))
+ scav := (c.scav >> i) & 1
+ c.cache &^= 1 << i // set bit to mark in-use
+ c.scav &^= 1 << i // clear bit to mark unscavenged
+ return c.base + i*pageSize, uintptr(scav) * pageSize
+ }
+ return c.allocN(npages)
+}
+
+// allocN is a helper which attempts to allocate npages worth of pages
+// from the cache. It represents the general case for allocating from
+// the page cache.
+//
+// Returns a base address and the amount of scavenged memory in the
+// allocated region in bytes.
+func (c *pageCache) allocN(npages uintptr) (uintptr, uintptr) {
+ i := findBitRange64(c.cache, uint(npages))
+ if i >= 64 {
+ return 0, 0
+ }
+ mask := ((uint64(1) << npages) - 1) << i
+ scav := sys.OnesCount64(c.scav & mask)
+ c.cache &^= mask // mark in-use bits
+ c.scav &^= mask // clear scavenged bits
+ return c.base + uintptr(i*pageSize), uintptr(scav) * pageSize
+}
+
+// flush empties out unallocated free pages in the given cache
+// into s. Then, it clears the cache, such that empty returns
+// true.
+//
+// p.mheapLock must be held.
+//
+// Must run on the system stack because p.mheapLock must be held.
+//
+//go:systemstack
+func (c *pageCache) flush(p *pageAlloc) {
+ assertLockHeld(p.mheapLock)
+
+ if c.empty() {
+ return
+ }
+ ci := chunkIndex(c.base)
+ pi := chunkPageIndex(c.base)
+
+ // This method is called very infrequently, so just do the
+ // slower, safer thing by iterating over each bit individually.
+ for i := uint(0); i < 64; i++ {
+ if c.cache&(1<<i) != 0 {
+ p.chunkOf(ci).free1(pi + i)
+
+ // Update density statistics.
+ p.scav.index.free(ci, pi+i, 1)
+ }
+ if c.scav&(1<<i) != 0 {
+ p.chunkOf(ci).scavenged.setRange(pi+i, 1)
+ }
+ }
+
+ // Since this is a lot like a free, we need to make sure
+ // we update the searchAddr just like free does.
+ if b := (offAddr{c.base}); b.lessThan(p.searchAddr) {
+ p.searchAddr = b
+ }
+ p.update(c.base, pageCachePages, false, false)
+ *c = pageCache{}
+}
+
+// allocToCache acquires a pageCachePages-aligned chunk of free pages which
+// may not be contiguous, and returns a pageCache structure which owns the
+// chunk.
+//
+// p.mheapLock must be held.
+//
+// Must run on the system stack because p.mheapLock must be held.
+//
+//go:systemstack
+func (p *pageAlloc) allocToCache() pageCache {
+ assertLockHeld(p.mheapLock)
+
+ // If the searchAddr refers to a region which has a higher address than
+ // any known chunk, then we know we're out of memory.
+ if chunkIndex(p.searchAddr.addr()) >= p.end {
+ return pageCache{}
+ }
+ c := pageCache{}
+ ci := chunkIndex(p.searchAddr.addr()) // chunk index
+ var chunk *pallocData
+ if p.summary[len(p.summary)-1][ci] != 0 {
+ // Fast path: there's free pages at or near the searchAddr address.
+ chunk = p.chunkOf(ci)
+ j, _ := chunk.find(1, chunkPageIndex(p.searchAddr.addr()))
+ if j == ^uint(0) {
+ throw("bad summary data")
+ }
+ c = pageCache{
+ base: chunkBase(ci) + alignDown(uintptr(j), 64)*pageSize,
+ cache: ^chunk.pages64(j),
+ scav: chunk.scavenged.block64(j),
+ }
+ } else {
+ // Slow path: the searchAddr address had nothing there, so go find
+ // the first free page the slow way.
+ addr, _ := p.find(1)
+ if addr == 0 {
+ // We failed to find adequate free space, so mark the searchAddr as OoM
+ // and return an empty pageCache.
+ p.searchAddr = maxSearchAddr()
+ return pageCache{}
+ }
+ ci = chunkIndex(addr)
+ chunk = p.chunkOf(ci)
+ c = pageCache{
+ base: alignDown(addr, 64*pageSize),
+ cache: ^chunk.pages64(chunkPageIndex(addr)),
+ scav: chunk.scavenged.block64(chunkPageIndex(addr)),
+ }
+ }
+
+ // Set the page bits as allocated and clear the scavenged bits, but
+ // be careful to only set and clear the relevant bits.
+ cpi := chunkPageIndex(c.base)
+ chunk.allocPages64(cpi, c.cache)
+ chunk.scavenged.clearBlock64(cpi, c.cache&c.scav /* free and scavenged */)
+
+ // Update as an allocation, but note that it's not contiguous.
+ p.update(c.base, pageCachePages, false, true)
+
+ // Update density statistics.
+ p.scav.index.alloc(ci, uint(sys.OnesCount64(c.cache)))
+
+ // Set the search address to the last page represented by the cache.
+ // Since all of the pages in this block are going to the cache, and we
+ // searched for the first free page, we can confidently start at the
+ // next page.
+ //
+ // However, p.searchAddr is not allowed to point into unmapped heap memory
+ // unless it is maxSearchAddr, so make it the last page as opposed to
+ // the page after.
+ p.searchAddr = offAddr{c.base + pageSize*(pageCachePages-1)}
+ return c
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mpallocbits.go b/contrib/go/_std_1.21/src/runtime/mpallocbits.go
new file mode 100644
index 0000000000..2f35ce007c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mpallocbits.go
@@ -0,0 +1,446 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import (
+ "runtime/internal/sys"
+)
+
+// pageBits is a bitmap representing one bit per page in a palloc chunk.
+type pageBits [pallocChunkPages / 64]uint64
+
+// get returns the value of the i'th bit in the bitmap.
+func (b *pageBits) get(i uint) uint {
+ return uint((b[i/64] >> (i % 64)) & 1)
+}
+
+// block64 returns the 64-bit aligned block of bits containing the i'th bit.
+func (b *pageBits) block64(i uint) uint64 {
+ return b[i/64]
+}
+
+// set sets bit i of pageBits.
+func (b *pageBits) set(i uint) {
+ b[i/64] |= 1 << (i % 64)
+}
+
+// setRange sets bits in the range [i, i+n).
+func (b *pageBits) setRange(i, n uint) {
+ _ = b[i/64]
+ if n == 1 {
+ // Fast path for the n == 1 case.
+ b.set(i)
+ return
+ }
+ // Set bits [i, j].
+ j := i + n - 1
+ if i/64 == j/64 {
+ b[i/64] |= ((uint64(1) << n) - 1) << (i % 64)
+ return
+ }
+ _ = b[j/64]
+ // Set leading bits.
+ b[i/64] |= ^uint64(0) << (i % 64)
+ for k := i/64 + 1; k < j/64; k++ {
+ b[k] = ^uint64(0)
+ }
+ // Set trailing bits.
+ b[j/64] |= (uint64(1) << (j%64 + 1)) - 1
+}
+
+// setAll sets all the bits of b.
+func (b *pageBits) setAll() {
+ for i := range b {
+ b[i] = ^uint64(0)
+ }
+}
+
+// setBlock64 sets the 64-bit aligned block of bits containing the i'th bit that
+// are set in v.
+func (b *pageBits) setBlock64(i uint, v uint64) {
+ b[i/64] |= v
+}
+
+// clear clears bit i of pageBits.
+func (b *pageBits) clear(i uint) {
+ b[i/64] &^= 1 << (i % 64)
+}
+
+// clearRange clears bits in the range [i, i+n).
+func (b *pageBits) clearRange(i, n uint) {
+ _ = b[i/64]
+ if n == 1 {
+ // Fast path for the n == 1 case.
+ b.clear(i)
+ return
+ }
+ // Clear bits [i, j].
+ j := i + n - 1
+ if i/64 == j/64 {
+ b[i/64] &^= ((uint64(1) << n) - 1) << (i % 64)
+ return
+ }
+ _ = b[j/64]
+ // Clear leading bits.
+ b[i/64] &^= ^uint64(0) << (i % 64)
+ for k := i/64 + 1; k < j/64; k++ {
+ b[k] = 0
+ }
+ // Clear trailing bits.
+ b[j/64] &^= (uint64(1) << (j%64 + 1)) - 1
+}
+
+// clearAll frees all the bits of b.
+func (b *pageBits) clearAll() {
+ for i := range b {
+ b[i] = 0
+ }
+}
+
+// clearBlock64 clears the 64-bit aligned block of bits containing the i'th bit that
+// are set in v.
+func (b *pageBits) clearBlock64(i uint, v uint64) {
+ b[i/64] &^= v
+}
+
+// popcntRange counts the number of set bits in the
+// range [i, i+n).
+func (b *pageBits) popcntRange(i, n uint) (s uint) {
+ if n == 1 {
+ return uint((b[i/64] >> (i % 64)) & 1)
+ }
+ _ = b[i/64]
+ j := i + n - 1
+ if i/64 == j/64 {
+ return uint(sys.OnesCount64((b[i/64] >> (i % 64)) & ((1 << n) - 1)))
+ }
+ _ = b[j/64]
+ s += uint(sys.OnesCount64(b[i/64] >> (i % 64)))
+ for k := i/64 + 1; k < j/64; k++ {
+ s += uint(sys.OnesCount64(b[k]))
+ }
+ s += uint(sys.OnesCount64(b[j/64] & ((1 << (j%64 + 1)) - 1)))
+ return
+}
+
+// pallocBits is a bitmap that tracks page allocations for at most one
+// palloc chunk.
+//
+// The precise representation is an implementation detail, but for the
+// sake of documentation, 0s are free pages and 1s are allocated pages.
+type pallocBits pageBits
+
+// summarize returns a packed summary of the bitmap in pallocBits.
+func (b *pallocBits) summarize() pallocSum {
+ var start, max, cur uint
+ const notSetYet = ^uint(0) // sentinel for start value
+ start = notSetYet
+ for i := 0; i < len(b); i++ {
+ x := b[i]
+ if x == 0 {
+ cur += 64
+ continue
+ }
+ t := uint(sys.TrailingZeros64(x))
+ l := uint(sys.LeadingZeros64(x))
+
+ // Finish any region spanning the uint64s
+ cur += t
+ if start == notSetYet {
+ start = cur
+ }
+ if cur > max {
+ max = cur
+ }
+ // Final region that might span to next uint64
+ cur = l
+ }
+ if start == notSetYet {
+ // Made it all the way through without finding a single 1 bit.
+ const n = uint(64 * len(b))
+ return packPallocSum(n, n, n)
+ }
+ if cur > max {
+ max = cur
+ }
+ if max >= 64-2 {
+ // There is no way an internal run of zeros could beat max.
+ return packPallocSum(start, max, cur)
+ }
+ // Now look inside each uint64 for runs of zeros.
+ // All uint64s must be nonzero, or we would have aborted above.
+outer:
+ for i := 0; i < len(b); i++ {
+ x := b[i]
+
+ // Look inside this uint64. We have a pattern like
+ // 000000 1xxxxx1 000000
+ // We need to look inside the 1xxxxx1 for any contiguous
+ // region of zeros.
+
+ // We already know the trailing zeros are no larger than max. Remove them.
+ x >>= sys.TrailingZeros64(x) & 63
+ if x&(x+1) == 0 { // no more zeros (except at the top).
+ continue
+ }
+
+ // Strategy: shrink all runs of zeros by max. If any runs of zero
+ // remain, then we've identified a larger maximum zero run.
+ p := max // number of zeros we still need to shrink by.
+ k := uint(1) // current minimum length of runs of ones in x.
+ for {
+ // Shrink all runs of zeros by p places (except the top zeros).
+ for p > 0 {
+ if p <= k {
+ // Shift p ones down into the top of each run of zeros.
+ x |= x >> (p & 63)
+ if x&(x+1) == 0 { // no more zeros (except at the top).
+ continue outer
+ }
+ break
+ }
+ // Shift k ones down into the top of each run of zeros.
+ x |= x >> (k & 63)
+ if x&(x+1) == 0 { // no more zeros (except at the top).
+ continue outer
+ }
+ p -= k
+ // We've just doubled the minimum length of 1-runs.
+ // This allows us to shift farther in the next iteration.
+ k *= 2
+ }
+
+ // The length of the lowest-order zero run is an increment to our maximum.
+ j := uint(sys.TrailingZeros64(^x)) // count contiguous trailing ones
+ x >>= j & 63 // remove trailing ones
+ j = uint(sys.TrailingZeros64(x)) // count contiguous trailing zeros
+ x >>= j & 63 // remove zeros
+ max += j // we have a new maximum!
+ if x&(x+1) == 0 { // no more zeros (except at the top).
+ continue outer
+ }
+ p = j // remove j more zeros from each zero run.
+ }
+ }
+ return packPallocSum(start, max, cur)
+}
+
+// find searches for npages contiguous free pages in pallocBits and returns
+// the index where that run starts, as well as the index of the first free page
+// it found in the search. searchIdx represents the first known free page and
+// where to begin the next search from.
+//
+// If find fails to find any free space, it returns an index of ^uint(0) and
+// the new searchIdx should be ignored.
+//
+// Note that if npages == 1, the two returned values will always be identical.
+func (b *pallocBits) find(npages uintptr, searchIdx uint) (uint, uint) {
+ if npages == 1 {
+ addr := b.find1(searchIdx)
+ return addr, addr
+ } else if npages <= 64 {
+ return b.findSmallN(npages, searchIdx)
+ }
+ return b.findLargeN(npages, searchIdx)
+}
+
+// find1 is a helper for find which searches for a single free page
+// in the pallocBits and returns the index.
+//
+// See find for an explanation of the searchIdx parameter.
+func (b *pallocBits) find1(searchIdx uint) uint {
+ _ = b[0] // lift nil check out of loop
+ for i := searchIdx / 64; i < uint(len(b)); i++ {
+ x := b[i]
+ if ^x == 0 {
+ continue
+ }
+ return i*64 + uint(sys.TrailingZeros64(^x))
+ }
+ return ^uint(0)
+}
+
+// findSmallN is a helper for find which searches for npages contiguous free pages
+// in this pallocBits and returns the index where that run of contiguous pages
+// starts as well as the index of the first free page it finds in its search.
+//
+// See find for an explanation of the searchIdx parameter.
+//
+// Returns a ^uint(0) index on failure and the new searchIdx should be ignored.
+//
+// findSmallN assumes npages <= 64, where any such contiguous run of pages
+// crosses at most one aligned 64-bit boundary in the bits.
+func (b *pallocBits) findSmallN(npages uintptr, searchIdx uint) (uint, uint) {
+ end, newSearchIdx := uint(0), ^uint(0)
+ for i := searchIdx / 64; i < uint(len(b)); i++ {
+ bi := b[i]
+ if ^bi == 0 {
+ end = 0
+ continue
+ }
+ // First see if we can pack our allocation in the trailing
+ // zeros plus the end of the last 64 bits.
+ if newSearchIdx == ^uint(0) {
+ // The new searchIdx is going to be at these 64 bits after any
+ // 1s we file, so count trailing 1s.
+ newSearchIdx = i*64 + uint(sys.TrailingZeros64(^bi))
+ }
+ start := uint(sys.TrailingZeros64(bi))
+ if end+start >= uint(npages) {
+ return i*64 - end, newSearchIdx
+ }
+ // Next, check the interior of the 64-bit chunk.
+ j := findBitRange64(^bi, uint(npages))
+ if j < 64 {
+ return i*64 + j, newSearchIdx
+ }
+ end = uint(sys.LeadingZeros64(bi))
+ }
+ return ^uint(0), newSearchIdx
+}
+
+// findLargeN is a helper for find which searches for npages contiguous free pages
+// in this pallocBits and returns the index where that run starts, as well as the
+// index of the first free page it found it its search.
+//
+// See alloc for an explanation of the searchIdx parameter.
+//
+// Returns a ^uint(0) index on failure and the new searchIdx should be ignored.
+//
+// findLargeN assumes npages > 64, where any such run of free pages
+// crosses at least one aligned 64-bit boundary in the bits.
+func (b *pallocBits) findLargeN(npages uintptr, searchIdx uint) (uint, uint) {
+ start, size, newSearchIdx := ^uint(0), uint(0), ^uint(0)
+ for i := searchIdx / 64; i < uint(len(b)); i++ {
+ x := b[i]
+ if x == ^uint64(0) {
+ size = 0
+ continue
+ }
+ if newSearchIdx == ^uint(0) {
+ // The new searchIdx is going to be at these 64 bits after any
+ // 1s we file, so count trailing 1s.
+ newSearchIdx = i*64 + uint(sys.TrailingZeros64(^x))
+ }
+ if size == 0 {
+ size = uint(sys.LeadingZeros64(x))
+ start = i*64 + 64 - size
+ continue
+ }
+ s := uint(sys.TrailingZeros64(x))
+ if s+size >= uint(npages) {
+ size += s
+ return start, newSearchIdx
+ }
+ if s < 64 {
+ size = uint(sys.LeadingZeros64(x))
+ start = i*64 + 64 - size
+ continue
+ }
+ size += 64
+ }
+ if size < uint(npages) {
+ return ^uint(0), newSearchIdx
+ }
+ return start, newSearchIdx
+}
+
+// allocRange allocates the range [i, i+n).
+func (b *pallocBits) allocRange(i, n uint) {
+ (*pageBits)(b).setRange(i, n)
+}
+
+// allocAll allocates all the bits of b.
+func (b *pallocBits) allocAll() {
+ (*pageBits)(b).setAll()
+}
+
+// free1 frees a single page in the pallocBits at i.
+func (b *pallocBits) free1(i uint) {
+ (*pageBits)(b).clear(i)
+}
+
+// free frees the range [i, i+n) of pages in the pallocBits.
+func (b *pallocBits) free(i, n uint) {
+ (*pageBits)(b).clearRange(i, n)
+}
+
+// freeAll frees all the bits of b.
+func (b *pallocBits) freeAll() {
+ (*pageBits)(b).clearAll()
+}
+
+// pages64 returns a 64-bit bitmap representing a block of 64 pages aligned
+// to 64 pages. The returned block of pages is the one containing the i'th
+// page in this pallocBits. Each bit represents whether the page is in-use.
+func (b *pallocBits) pages64(i uint) uint64 {
+ return (*pageBits)(b).block64(i)
+}
+
+// allocPages64 allocates a 64-bit block of 64 pages aligned to 64 pages according
+// to the bits set in alloc. The block set is the one containing the i'th page.
+func (b *pallocBits) allocPages64(i uint, alloc uint64) {
+ (*pageBits)(b).setBlock64(i, alloc)
+}
+
+// findBitRange64 returns the bit index of the first set of
+// n consecutive 1 bits. If no consecutive set of 1 bits of
+// size n may be found in c, then it returns an integer >= 64.
+// n must be > 0.
+func findBitRange64(c uint64, n uint) uint {
+ // This implementation is based on shrinking the length of
+ // runs of contiguous 1 bits. We remove the top n-1 1 bits
+ // from each run of 1s, then look for the first remaining 1 bit.
+ p := n - 1 // number of 1s we want to remove.
+ k := uint(1) // current minimum width of runs of 0 in c.
+ for p > 0 {
+ if p <= k {
+ // Shift p 0s down into the top of each run of 1s.
+ c &= c >> (p & 63)
+ break
+ }
+ // Shift k 0s down into the top of each run of 1s.
+ c &= c >> (k & 63)
+ if c == 0 {
+ return 64
+ }
+ p -= k
+ // We've just doubled the minimum length of 0-runs.
+ // This allows us to shift farther in the next iteration.
+ k *= 2
+ }
+ // Find first remaining 1.
+ // Since we shrunk from the top down, the first 1 is in
+ // its correct original position.
+ return uint(sys.TrailingZeros64(c))
+}
+
+// pallocData encapsulates pallocBits and a bitmap for
+// whether or not a given page is scavenged in a single
+// structure. It's effectively a pallocBits with
+// additional functionality.
+//
+// Update the comment on (*pageAlloc).chunks should this
+// structure change.
+type pallocData struct {
+ pallocBits
+ scavenged pageBits
+}
+
+// allocRange sets bits [i, i+n) in the bitmap to 1 and
+// updates the scavenged bits appropriately.
+func (m *pallocData) allocRange(i, n uint) {
+ // Clear the scavenged bits when we alloc the range.
+ m.pallocBits.allocRange(i, n)
+ m.scavenged.clearRange(i, n)
+}
+
+// allocAll sets every bit in the bitmap to 1 and updates
+// the scavenged bits appropriately.
+func (m *pallocData) allocAll() {
+ // Clear the scavenged bits when we alloc the range.
+ m.pallocBits.allocAll()
+ m.scavenged.clearAll()
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mprof.go b/contrib/go/_std_1.21/src/runtime/mprof.go
new file mode 100644
index 0000000000..308ebaebe6
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mprof.go
@@ -0,0 +1,1278 @@
+// Copyright 2009 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.
+
+// Malloc profiling.
+// Patterned after tcmalloc's algorithms; shorter code.
+
+package runtime
+
+import (
+ "internal/abi"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// NOTE(rsc): Everything here could use cas if contention became an issue.
+var (
+ // profInsertLock protects changes to the start of all *bucket linked lists
+ profInsertLock mutex
+ // profBlockLock protects the contents of every blockRecord struct
+ profBlockLock mutex
+ // profMemActiveLock protects the active field of every memRecord struct
+ profMemActiveLock mutex
+ // profMemFutureLock is a set of locks that protect the respective elements
+ // of the future array of every memRecord struct
+ profMemFutureLock [len(memRecord{}.future)]mutex
+)
+
+// All memory allocations are local and do not escape outside of the profiler.
+// The profiler is forbidden from referring to garbage-collected memory.
+
+const (
+ // profile types
+ memProfile bucketType = 1 + iota
+ blockProfile
+ mutexProfile
+
+ // size of bucket hash table
+ buckHashSize = 179999
+
+ // max depth of stack to record in bucket
+ maxStack = 32
+)
+
+type bucketType int
+
+// A bucket holds per-call-stack profiling information.
+// The representation is a bit sleazy, inherited from C.
+// This struct defines the bucket header. It is followed in
+// memory by the stack words and then the actual record
+// data, either a memRecord or a blockRecord.
+//
+// Per-call-stack profiling information.
+// Lookup by hashing call stack into a linked-list hash table.
+//
+// None of the fields in this bucket header are modified after
+// creation, including its next and allnext links.
+//
+// No heap pointers.
+type bucket struct {
+ _ sys.NotInHeap
+ next *bucket
+ allnext *bucket
+ typ bucketType // memBucket or blockBucket (includes mutexProfile)
+ hash uintptr
+ size uintptr
+ nstk uintptr
+}
+
+// A memRecord is the bucket data for a bucket of type memProfile,
+// part of the memory profile.
+type memRecord struct {
+ // The following complex 3-stage scheme of stats accumulation
+ // is required to obtain a consistent picture of mallocs and frees
+ // for some point in time.
+ // The problem is that mallocs come in real time, while frees
+ // come only after a GC during concurrent sweeping. So if we would
+ // naively count them, we would get a skew toward mallocs.
+ //
+ // Hence, we delay information to get consistent snapshots as
+ // of mark termination. Allocations count toward the next mark
+ // termination's snapshot, while sweep frees count toward the
+ // previous mark termination's snapshot:
+ //
+ // MT MT MT MT
+ // .·| .·| .·| .·|
+ // .·˙ | .·˙ | .·˙ | .·˙ |
+ // .·˙ | .·˙ | .·˙ | .·˙ |
+ // .·˙ |.·˙ |.·˙ |.·˙ |
+ //
+ // alloc → ▲ ← free
+ // ┠┅┅┅┅┅┅┅┅┅┅┅P
+ // C+2 → C+1 → C
+ //
+ // alloc → ▲ ← free
+ // ┠┅┅┅┅┅┅┅┅┅┅┅P
+ // C+2 → C+1 → C
+ //
+ // Since we can't publish a consistent snapshot until all of
+ // the sweep frees are accounted for, we wait until the next
+ // mark termination ("MT" above) to publish the previous mark
+ // termination's snapshot ("P" above). To do this, allocation
+ // and free events are accounted to *future* heap profile
+ // cycles ("C+n" above) and we only publish a cycle once all
+ // of the events from that cycle must be done. Specifically:
+ //
+ // Mallocs are accounted to cycle C+2.
+ // Explicit frees are accounted to cycle C+2.
+ // GC frees (done during sweeping) are accounted to cycle C+1.
+ //
+ // After mark termination, we increment the global heap
+ // profile cycle counter and accumulate the stats from cycle C
+ // into the active profile.
+
+ // active is the currently published profile. A profiling
+ // cycle can be accumulated into active once its complete.
+ active memRecordCycle
+
+ // future records the profile events we're counting for cycles
+ // that have not yet been published. This is ring buffer
+ // indexed by the global heap profile cycle C and stores
+ // cycles C, C+1, and C+2. Unlike active, these counts are
+ // only for a single cycle; they are not cumulative across
+ // cycles.
+ //
+ // We store cycle C here because there's a window between when
+ // C becomes the active cycle and when we've flushed it to
+ // active.
+ future [3]memRecordCycle
+}
+
+// memRecordCycle
+type memRecordCycle struct {
+ allocs, frees uintptr
+ alloc_bytes, free_bytes uintptr
+}
+
+// add accumulates b into a. It does not zero b.
+func (a *memRecordCycle) add(b *memRecordCycle) {
+ a.allocs += b.allocs
+ a.frees += b.frees
+ a.alloc_bytes += b.alloc_bytes
+ a.free_bytes += b.free_bytes
+}
+
+// A blockRecord is the bucket data for a bucket of type blockProfile,
+// which is used in blocking and mutex profiles.
+type blockRecord struct {
+ count float64
+ cycles int64
+}
+
+var (
+ mbuckets atomic.UnsafePointer // *bucket, memory profile buckets
+ bbuckets atomic.UnsafePointer // *bucket, blocking profile buckets
+ xbuckets atomic.UnsafePointer // *bucket, mutex profile buckets
+ buckhash atomic.UnsafePointer // *buckhashArray
+
+ mProfCycle mProfCycleHolder
+)
+
+type buckhashArray [buckHashSize]atomic.UnsafePointer // *bucket
+
+const mProfCycleWrap = uint32(len(memRecord{}.future)) * (2 << 24)
+
+// mProfCycleHolder holds the global heap profile cycle number (wrapped at
+// mProfCycleWrap, stored starting at bit 1), and a flag (stored at bit 0) to
+// indicate whether future[cycle] in all buckets has been queued to flush into
+// the active profile.
+type mProfCycleHolder struct {
+ value atomic.Uint32
+}
+
+// read returns the current cycle count.
+func (c *mProfCycleHolder) read() (cycle uint32) {
+ v := c.value.Load()
+ cycle = v >> 1
+ return cycle
+}
+
+// setFlushed sets the flushed flag. It returns the current cycle count and the
+// previous value of the flushed flag.
+func (c *mProfCycleHolder) setFlushed() (cycle uint32, alreadyFlushed bool) {
+ for {
+ prev := c.value.Load()
+ cycle = prev >> 1
+ alreadyFlushed = (prev & 0x1) != 0
+ next := prev | 0x1
+ if c.value.CompareAndSwap(prev, next) {
+ return cycle, alreadyFlushed
+ }
+ }
+}
+
+// increment increases the cycle count by one, wrapping the value at
+// mProfCycleWrap. It clears the flushed flag.
+func (c *mProfCycleHolder) increment() {
+ // We explicitly wrap mProfCycle rather than depending on
+ // uint wraparound because the memRecord.future ring does not
+ // itself wrap at a power of two.
+ for {
+ prev := c.value.Load()
+ cycle := prev >> 1
+ cycle = (cycle + 1) % mProfCycleWrap
+ next := cycle << 1
+ if c.value.CompareAndSwap(prev, next) {
+ break
+ }
+ }
+}
+
+// newBucket allocates a bucket with the given type and number of stack entries.
+func newBucket(typ bucketType, nstk int) *bucket {
+ size := unsafe.Sizeof(bucket{}) + uintptr(nstk)*unsafe.Sizeof(uintptr(0))
+ switch typ {
+ default:
+ throw("invalid profile bucket type")
+ case memProfile:
+ size += unsafe.Sizeof(memRecord{})
+ case blockProfile, mutexProfile:
+ size += unsafe.Sizeof(blockRecord{})
+ }
+
+ b := (*bucket)(persistentalloc(size, 0, &memstats.buckhash_sys))
+ b.typ = typ
+ b.nstk = uintptr(nstk)
+ return b
+}
+
+// stk returns the slice in b holding the stack.
+func (b *bucket) stk() []uintptr {
+ stk := (*[maxStack]uintptr)(add(unsafe.Pointer(b), unsafe.Sizeof(*b)))
+ return stk[:b.nstk:b.nstk]
+}
+
+// mp returns the memRecord associated with the memProfile bucket b.
+func (b *bucket) mp() *memRecord {
+ if b.typ != memProfile {
+ throw("bad use of bucket.mp")
+ }
+ data := add(unsafe.Pointer(b), unsafe.Sizeof(*b)+b.nstk*unsafe.Sizeof(uintptr(0)))
+ return (*memRecord)(data)
+}
+
+// bp returns the blockRecord associated with the blockProfile bucket b.
+func (b *bucket) bp() *blockRecord {
+ if b.typ != blockProfile && b.typ != mutexProfile {
+ throw("bad use of bucket.bp")
+ }
+ data := add(unsafe.Pointer(b), unsafe.Sizeof(*b)+b.nstk*unsafe.Sizeof(uintptr(0)))
+ return (*blockRecord)(data)
+}
+
+// Return the bucket for stk[0:nstk], allocating new bucket if needed.
+func stkbucket(typ bucketType, size uintptr, stk []uintptr, alloc bool) *bucket {
+ bh := (*buckhashArray)(buckhash.Load())
+ if bh == nil {
+ lock(&profInsertLock)
+ // check again under the lock
+ bh = (*buckhashArray)(buckhash.Load())
+ if bh == nil {
+ bh = (*buckhashArray)(sysAlloc(unsafe.Sizeof(buckhashArray{}), &memstats.buckhash_sys))
+ if bh == nil {
+ throw("runtime: cannot allocate memory")
+ }
+ buckhash.StoreNoWB(unsafe.Pointer(bh))
+ }
+ unlock(&profInsertLock)
+ }
+
+ // Hash stack.
+ var h uintptr
+ for _, pc := range stk {
+ h += pc
+ h += h << 10
+ h ^= h >> 6
+ }
+ // hash in size
+ h += size
+ h += h << 10
+ h ^= h >> 6
+ // finalize
+ h += h << 3
+ h ^= h >> 11
+
+ i := int(h % buckHashSize)
+ // first check optimistically, without the lock
+ for b := (*bucket)(bh[i].Load()); b != nil; b = b.next {
+ if b.typ == typ && b.hash == h && b.size == size && eqslice(b.stk(), stk) {
+ return b
+ }
+ }
+
+ if !alloc {
+ return nil
+ }
+
+ lock(&profInsertLock)
+ // check again under the insertion lock
+ for b := (*bucket)(bh[i].Load()); b != nil; b = b.next {
+ if b.typ == typ && b.hash == h && b.size == size && eqslice(b.stk(), stk) {
+ unlock(&profInsertLock)
+ return b
+ }
+ }
+
+ // Create new bucket.
+ b := newBucket(typ, len(stk))
+ copy(b.stk(), stk)
+ b.hash = h
+ b.size = size
+
+ var allnext *atomic.UnsafePointer
+ if typ == memProfile {
+ allnext = &mbuckets
+ } else if typ == mutexProfile {
+ allnext = &xbuckets
+ } else {
+ allnext = &bbuckets
+ }
+
+ b.next = (*bucket)(bh[i].Load())
+ b.allnext = (*bucket)(allnext.Load())
+
+ bh[i].StoreNoWB(unsafe.Pointer(b))
+ allnext.StoreNoWB(unsafe.Pointer(b))
+
+ unlock(&profInsertLock)
+ return b
+}
+
+func eqslice(x, y []uintptr) bool {
+ if len(x) != len(y) {
+ return false
+ }
+ for i, xi := range x {
+ if xi != y[i] {
+ return false
+ }
+ }
+ return true
+}
+
+// mProf_NextCycle publishes the next heap profile cycle and creates a
+// fresh heap profile cycle. This operation is fast and can be done
+// during STW. The caller must call mProf_Flush before calling
+// mProf_NextCycle again.
+//
+// This is called by mark termination during STW so allocations and
+// frees after the world is started again count towards a new heap
+// profiling cycle.
+func mProf_NextCycle() {
+ mProfCycle.increment()
+}
+
+// mProf_Flush flushes the events from the current heap profiling
+// cycle into the active profile. After this it is safe to start a new
+// heap profiling cycle with mProf_NextCycle.
+//
+// This is called by GC after mark termination starts the world. In
+// contrast with mProf_NextCycle, this is somewhat expensive, but safe
+// to do concurrently.
+func mProf_Flush() {
+ cycle, alreadyFlushed := mProfCycle.setFlushed()
+ if alreadyFlushed {
+ return
+ }
+
+ index := cycle % uint32(len(memRecord{}.future))
+ lock(&profMemActiveLock)
+ lock(&profMemFutureLock[index])
+ mProf_FlushLocked(index)
+ unlock(&profMemFutureLock[index])
+ unlock(&profMemActiveLock)
+}
+
+// mProf_FlushLocked flushes the events from the heap profiling cycle at index
+// into the active profile. The caller must hold the lock for the active profile
+// (profMemActiveLock) and for the profiling cycle at index
+// (profMemFutureLock[index]).
+func mProf_FlushLocked(index uint32) {
+ assertLockHeld(&profMemActiveLock)
+ assertLockHeld(&profMemFutureLock[index])
+ head := (*bucket)(mbuckets.Load())
+ for b := head; b != nil; b = b.allnext {
+ mp := b.mp()
+
+ // Flush cycle C into the published profile and clear
+ // it for reuse.
+ mpc := &mp.future[index]
+ mp.active.add(mpc)
+ *mpc = memRecordCycle{}
+ }
+}
+
+// mProf_PostSweep records that all sweep frees for this GC cycle have
+// completed. This has the effect of publishing the heap profile
+// snapshot as of the last mark termination without advancing the heap
+// profile cycle.
+func mProf_PostSweep() {
+ // Flush cycle C+1 to the active profile so everything as of
+ // the last mark termination becomes visible. *Don't* advance
+ // the cycle, since we're still accumulating allocs in cycle
+ // C+2, which have to become C+1 in the next mark termination
+ // and so on.
+ cycle := mProfCycle.read() + 1
+
+ index := cycle % uint32(len(memRecord{}.future))
+ lock(&profMemActiveLock)
+ lock(&profMemFutureLock[index])
+ mProf_FlushLocked(index)
+ unlock(&profMemFutureLock[index])
+ unlock(&profMemActiveLock)
+}
+
+// Called by malloc to record a profiled block.
+func mProf_Malloc(p unsafe.Pointer, size uintptr) {
+ var stk [maxStack]uintptr
+ nstk := callers(4, stk[:])
+
+ index := (mProfCycle.read() + 2) % uint32(len(memRecord{}.future))
+
+ b := stkbucket(memProfile, size, stk[:nstk], true)
+ mp := b.mp()
+ mpc := &mp.future[index]
+
+ lock(&profMemFutureLock[index])
+ mpc.allocs++
+ mpc.alloc_bytes += size
+ unlock(&profMemFutureLock[index])
+
+ // Setprofilebucket locks a bunch of other mutexes, so we call it outside of
+ // the profiler locks. This reduces potential contention and chances of
+ // deadlocks. Since the object must be alive during the call to
+ // mProf_Malloc, it's fine to do this non-atomically.
+ systemstack(func() {
+ setprofilebucket(p, b)
+ })
+}
+
+// Called when freeing a profiled block.
+func mProf_Free(b *bucket, size uintptr) {
+ index := (mProfCycle.read() + 1) % uint32(len(memRecord{}.future))
+
+ mp := b.mp()
+ mpc := &mp.future[index]
+
+ lock(&profMemFutureLock[index])
+ mpc.frees++
+ mpc.free_bytes += size
+ unlock(&profMemFutureLock[index])
+}
+
+var blockprofilerate uint64 // in CPU ticks
+
+// SetBlockProfileRate controls the fraction of goroutine blocking events
+// that are reported in the blocking profile. The profiler aims to sample
+// an average of one blocking event per rate nanoseconds spent blocked.
+//
+// To include every blocking event in the profile, pass rate = 1.
+// To turn off profiling entirely, pass rate <= 0.
+func SetBlockProfileRate(rate int) {
+ var r int64
+ if rate <= 0 {
+ r = 0 // disable profiling
+ } else if rate == 1 {
+ r = 1 // profile everything
+ } else {
+ // convert ns to cycles, use float64 to prevent overflow during multiplication
+ r = int64(float64(rate) * float64(tickspersecond()) / (1000 * 1000 * 1000))
+ if r == 0 {
+ r = 1
+ }
+ }
+
+ atomic.Store64(&blockprofilerate, uint64(r))
+}
+
+func blockevent(cycles int64, skip int) {
+ if cycles <= 0 {
+ cycles = 1
+ }
+
+ rate := int64(atomic.Load64(&blockprofilerate))
+ if blocksampled(cycles, rate) {
+ saveblockevent(cycles, rate, skip+1, blockProfile)
+ }
+}
+
+// blocksampled returns true for all events where cycles >= rate. Shorter
+// events have a cycles/rate random chance of returning true.
+func blocksampled(cycles, rate int64) bool {
+ if rate <= 0 || (rate > cycles && int64(fastrand())%rate > cycles) {
+ return false
+ }
+ return true
+}
+
+func saveblockevent(cycles, rate int64, skip int, which bucketType) {
+ gp := getg()
+ var nstk int
+ var stk [maxStack]uintptr
+ if gp.m.curg == nil || gp.m.curg == gp {
+ nstk = callers(skip, stk[:])
+ } else {
+ nstk = gcallers(gp.m.curg, skip, stk[:])
+ }
+ b := stkbucket(which, 0, stk[:nstk], true)
+ bp := b.bp()
+
+ lock(&profBlockLock)
+ // We want to up-scale the count and cycles according to the
+ // probability that the event was sampled. For block profile events,
+ // the sample probability is 1 if cycles >= rate, and cycles / rate
+ // otherwise. For mutex profile events, the sample probability is 1 / rate.
+ // We scale the events by 1 / (probability the event was sampled).
+ if which == blockProfile && cycles < rate {
+ // Remove sampling bias, see discussion on http://golang.org/cl/299991.
+ bp.count += float64(rate) / float64(cycles)
+ bp.cycles += rate
+ } else if which == mutexProfile {
+ bp.count += float64(rate)
+ bp.cycles += rate * cycles
+ } else {
+ bp.count++
+ bp.cycles += cycles
+ }
+ unlock(&profBlockLock)
+}
+
+var mutexprofilerate uint64 // fraction sampled
+
+// SetMutexProfileFraction controls the fraction of mutex contention events
+// that are reported in the mutex profile. On average 1/rate events are
+// reported. The previous rate is returned.
+//
+// To turn off profiling entirely, pass rate 0.
+// To just read the current rate, pass rate < 0.
+// (For n>1 the details of sampling may change.)
+func SetMutexProfileFraction(rate int) int {
+ if rate < 0 {
+ return int(mutexprofilerate)
+ }
+ old := mutexprofilerate
+ atomic.Store64(&mutexprofilerate, uint64(rate))
+ return int(old)
+}
+
+//go:linkname mutexevent sync.event
+func mutexevent(cycles int64, skip int) {
+ if cycles < 0 {
+ cycles = 0
+ }
+ rate := int64(atomic.Load64(&mutexprofilerate))
+ // TODO(pjw): measure impact of always calling fastrand vs using something
+ // like malloc.go:nextSample()
+ if rate > 0 && int64(fastrand())%rate == 0 {
+ saveblockevent(cycles, rate, skip+1, mutexProfile)
+ }
+}
+
+// Go interface to profile data.
+
+// A StackRecord describes a single execution stack.
+type StackRecord struct {
+ Stack0 [32]uintptr // stack trace for this record; ends at first 0 entry
+}
+
+// Stack returns the stack trace associated with the record,
+// a prefix of r.Stack0.
+func (r *StackRecord) Stack() []uintptr {
+ for i, v := range r.Stack0 {
+ if v == 0 {
+ return r.Stack0[0:i]
+ }
+ }
+ return r.Stack0[0:]
+}
+
+// MemProfileRate controls the fraction of memory allocations
+// that are recorded and reported in the memory profile.
+// The profiler aims to sample an average of
+// one allocation per MemProfileRate bytes allocated.
+//
+// To include every allocated block in the profile, set MemProfileRate to 1.
+// To turn off profiling entirely, set MemProfileRate to 0.
+//
+// The tools that process the memory profiles assume that the
+// profile rate is constant across the lifetime of the program
+// and equal to the current value. Programs that change the
+// memory profiling rate should do so just once, as early as
+// possible in the execution of the program (for example,
+// at the beginning of main).
+var MemProfileRate int = 512 * 1024
+
+// disableMemoryProfiling is set by the linker if runtime.MemProfile
+// is not used and the link type guarantees nobody else could use it
+// elsewhere.
+var disableMemoryProfiling bool
+
+// A MemProfileRecord describes the live objects allocated
+// by a particular call sequence (stack trace).
+type MemProfileRecord struct {
+ AllocBytes, FreeBytes int64 // number of bytes allocated, freed
+ AllocObjects, FreeObjects int64 // number of objects allocated, freed
+ Stack0 [32]uintptr // stack trace for this record; ends at first 0 entry
+}
+
+// InUseBytes returns the number of bytes in use (AllocBytes - FreeBytes).
+func (r *MemProfileRecord) InUseBytes() int64 { return r.AllocBytes - r.FreeBytes }
+
+// InUseObjects returns the number of objects in use (AllocObjects - FreeObjects).
+func (r *MemProfileRecord) InUseObjects() int64 {
+ return r.AllocObjects - r.FreeObjects
+}
+
+// Stack returns the stack trace associated with the record,
+// a prefix of r.Stack0.
+func (r *MemProfileRecord) Stack() []uintptr {
+ for i, v := range r.Stack0 {
+ if v == 0 {
+ return r.Stack0[0:i]
+ }
+ }
+ return r.Stack0[0:]
+}
+
+// MemProfile returns a profile of memory allocated and freed per allocation
+// site.
+//
+// MemProfile returns n, the number of records in the current memory profile.
+// If len(p) >= n, MemProfile copies the profile into p and returns n, true.
+// If len(p) < n, MemProfile does not change p and returns n, false.
+//
+// If inuseZero is true, the profile includes allocation records
+// where r.AllocBytes > 0 but r.AllocBytes == r.FreeBytes.
+// These are sites where memory was allocated, but it has all
+// been released back to the runtime.
+//
+// The returned profile may be up to two garbage collection cycles old.
+// This is to avoid skewing the profile toward allocations; because
+// allocations happen in real time but frees are delayed until the garbage
+// collector performs sweeping, the profile only accounts for allocations
+// that have had a chance to be freed by the garbage collector.
+//
+// Most clients should use the runtime/pprof package or
+// the testing package's -test.memprofile flag instead
+// of calling MemProfile directly.
+func MemProfile(p []MemProfileRecord, inuseZero bool) (n int, ok bool) {
+ cycle := mProfCycle.read()
+ // If we're between mProf_NextCycle and mProf_Flush, take care
+ // of flushing to the active profile so we only have to look
+ // at the active profile below.
+ index := cycle % uint32(len(memRecord{}.future))
+ lock(&profMemActiveLock)
+ lock(&profMemFutureLock[index])
+ mProf_FlushLocked(index)
+ unlock(&profMemFutureLock[index])
+ clear := true
+ head := (*bucket)(mbuckets.Load())
+ for b := head; b != nil; b = b.allnext {
+ mp := b.mp()
+ if inuseZero || mp.active.alloc_bytes != mp.active.free_bytes {
+ n++
+ }
+ if mp.active.allocs != 0 || mp.active.frees != 0 {
+ clear = false
+ }
+ }
+ if clear {
+ // Absolutely no data, suggesting that a garbage collection
+ // has not yet happened. In order to allow profiling when
+ // garbage collection is disabled from the beginning of execution,
+ // accumulate all of the cycles, and recount buckets.
+ n = 0
+ for b := head; b != nil; b = b.allnext {
+ mp := b.mp()
+ for c := range mp.future {
+ lock(&profMemFutureLock[c])
+ mp.active.add(&mp.future[c])
+ mp.future[c] = memRecordCycle{}
+ unlock(&profMemFutureLock[c])
+ }
+ if inuseZero || mp.active.alloc_bytes != mp.active.free_bytes {
+ n++
+ }
+ }
+ }
+ if n <= len(p) {
+ ok = true
+ idx := 0
+ for b := head; b != nil; b = b.allnext {
+ mp := b.mp()
+ if inuseZero || mp.active.alloc_bytes != mp.active.free_bytes {
+ record(&p[idx], b)
+ idx++
+ }
+ }
+ }
+ unlock(&profMemActiveLock)
+ return
+}
+
+// Write b's data to r.
+func record(r *MemProfileRecord, b *bucket) {
+ mp := b.mp()
+ r.AllocBytes = int64(mp.active.alloc_bytes)
+ r.FreeBytes = int64(mp.active.free_bytes)
+ r.AllocObjects = int64(mp.active.allocs)
+ r.FreeObjects = int64(mp.active.frees)
+ if raceenabled {
+ racewriterangepc(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0), getcallerpc(), abi.FuncPCABIInternal(MemProfile))
+ }
+ if msanenabled {
+ msanwrite(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0))
+ }
+ if asanenabled {
+ asanwrite(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0))
+ }
+ copy(r.Stack0[:], b.stk())
+ for i := int(b.nstk); i < len(r.Stack0); i++ {
+ r.Stack0[i] = 0
+ }
+}
+
+func iterate_memprof(fn func(*bucket, uintptr, *uintptr, uintptr, uintptr, uintptr)) {
+ lock(&profMemActiveLock)
+ head := (*bucket)(mbuckets.Load())
+ for b := head; b != nil; b = b.allnext {
+ mp := b.mp()
+ fn(b, b.nstk, &b.stk()[0], b.size, mp.active.allocs, mp.active.frees)
+ }
+ unlock(&profMemActiveLock)
+}
+
+// BlockProfileRecord describes blocking events originated
+// at a particular call sequence (stack trace).
+type BlockProfileRecord struct {
+ Count int64
+ Cycles int64
+ StackRecord
+}
+
+// BlockProfile returns n, the number of records in the current blocking profile.
+// If len(p) >= n, BlockProfile copies the profile into p and returns n, true.
+// If len(p) < n, BlockProfile does not change p and returns n, false.
+//
+// Most clients should use the runtime/pprof package or
+// the testing package's -test.blockprofile flag instead
+// of calling BlockProfile directly.
+func BlockProfile(p []BlockProfileRecord) (n int, ok bool) {
+ lock(&profBlockLock)
+ head := (*bucket)(bbuckets.Load())
+ for b := head; b != nil; b = b.allnext {
+ n++
+ }
+ if n <= len(p) {
+ ok = true
+ for b := head; b != nil; b = b.allnext {
+ bp := b.bp()
+ r := &p[0]
+ r.Count = int64(bp.count)
+ // Prevent callers from having to worry about division by zero errors.
+ // See discussion on http://golang.org/cl/299991.
+ if r.Count == 0 {
+ r.Count = 1
+ }
+ r.Cycles = bp.cycles
+ if raceenabled {
+ racewriterangepc(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0), getcallerpc(), abi.FuncPCABIInternal(BlockProfile))
+ }
+ if msanenabled {
+ msanwrite(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0))
+ }
+ if asanenabled {
+ asanwrite(unsafe.Pointer(&r.Stack0[0]), unsafe.Sizeof(r.Stack0))
+ }
+ i := copy(r.Stack0[:], b.stk())
+ for ; i < len(r.Stack0); i++ {
+ r.Stack0[i] = 0
+ }
+ p = p[1:]
+ }
+ }
+ unlock(&profBlockLock)
+ return
+}
+
+// MutexProfile returns n, the number of records in the current mutex profile.
+// If len(p) >= n, MutexProfile copies the profile into p and returns n, true.
+// Otherwise, MutexProfile does not change p, and returns n, false.
+//
+// Most clients should use the runtime/pprof package
+// instead of calling MutexProfile directly.
+func MutexProfile(p []BlockProfileRecord) (n int, ok bool) {
+ lock(&profBlockLock)
+ head := (*bucket)(xbuckets.Load())
+ for b := head; b != nil; b = b.allnext {
+ n++
+ }
+ if n <= len(p) {
+ ok = true
+ for b := head; b != nil; b = b.allnext {
+ bp := b.bp()
+ r := &p[0]
+ r.Count = int64(bp.count)
+ r.Cycles = bp.cycles
+ i := copy(r.Stack0[:], b.stk())
+ for ; i < len(r.Stack0); i++ {
+ r.Stack0[i] = 0
+ }
+ p = p[1:]
+ }
+ }
+ unlock(&profBlockLock)
+ return
+}
+
+// ThreadCreateProfile returns n, the number of records in the thread creation profile.
+// If len(p) >= n, ThreadCreateProfile copies the profile into p and returns n, true.
+// If len(p) < n, ThreadCreateProfile does not change p and returns n, false.
+//
+// Most clients should use the runtime/pprof package instead
+// of calling ThreadCreateProfile directly.
+func ThreadCreateProfile(p []StackRecord) (n int, ok bool) {
+ first := (*m)(atomic.Loadp(unsafe.Pointer(&allm)))
+ for mp := first; mp != nil; mp = mp.alllink {
+ n++
+ }
+ if n <= len(p) {
+ ok = true
+ i := 0
+ for mp := first; mp != nil; mp = mp.alllink {
+ p[i].Stack0 = mp.createstack
+ i++
+ }
+ }
+ return
+}
+
+//go:linkname runtime_goroutineProfileWithLabels runtime/pprof.runtime_goroutineProfileWithLabels
+func runtime_goroutineProfileWithLabels(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
+ return goroutineProfileWithLabels(p, labels)
+}
+
+// labels may be nil. If labels is non-nil, it must have the same length as p.
+func goroutineProfileWithLabels(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
+ if labels != nil && len(labels) != len(p) {
+ labels = nil
+ }
+
+ return goroutineProfileWithLabelsConcurrent(p, labels)
+}
+
+var goroutineProfile = struct {
+ sema uint32
+ active bool
+ offset atomic.Int64
+ records []StackRecord
+ labels []unsafe.Pointer
+}{
+ sema: 1,
+}
+
+// goroutineProfileState indicates the status of a goroutine's stack for the
+// current in-progress goroutine profile. Goroutines' stacks are initially
+// "Absent" from the profile, and end up "Satisfied" by the time the profile is
+// complete. While a goroutine's stack is being captured, its
+// goroutineProfileState will be "InProgress" and it will not be able to run
+// until the capture completes and the state moves to "Satisfied".
+//
+// Some goroutines (the finalizer goroutine, which at various times can be
+// either a "system" or a "user" goroutine, and the goroutine that is
+// coordinating the profile, any goroutines created during the profile) move
+// directly to the "Satisfied" state.
+type goroutineProfileState uint32
+
+const (
+ goroutineProfileAbsent goroutineProfileState = iota
+ goroutineProfileInProgress
+ goroutineProfileSatisfied
+)
+
+type goroutineProfileStateHolder atomic.Uint32
+
+func (p *goroutineProfileStateHolder) Load() goroutineProfileState {
+ return goroutineProfileState((*atomic.Uint32)(p).Load())
+}
+
+func (p *goroutineProfileStateHolder) Store(value goroutineProfileState) {
+ (*atomic.Uint32)(p).Store(uint32(value))
+}
+
+func (p *goroutineProfileStateHolder) CompareAndSwap(old, new goroutineProfileState) bool {
+ return (*atomic.Uint32)(p).CompareAndSwap(uint32(old), uint32(new))
+}
+
+func goroutineProfileWithLabelsConcurrent(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
+ semacquire(&goroutineProfile.sema)
+
+ ourg := getg()
+
+ stopTheWorld(stwGoroutineProfile)
+ // Using gcount while the world is stopped should give us a consistent view
+ // of the number of live goroutines, minus the number of goroutines that are
+ // alive and permanently marked as "system". But to make this count agree
+ // with what we'd get from isSystemGoroutine, we need special handling for
+ // goroutines that can vary between user and system to ensure that the count
+ // doesn't change during the collection. So, check the finalizer goroutine
+ // in particular.
+ n = int(gcount())
+ if fingStatus.Load()&fingRunningFinalizer != 0 {
+ n++
+ }
+
+ if n > len(p) {
+ // There's not enough space in p to store the whole profile, so (per the
+ // contract of runtime.GoroutineProfile) we're not allowed to write to p
+ // at all and must return n, false.
+ startTheWorld()
+ semrelease(&goroutineProfile.sema)
+ return n, false
+ }
+
+ // Save current goroutine.
+ sp := getcallersp()
+ pc := getcallerpc()
+ systemstack(func() {
+ saveg(pc, sp, ourg, &p[0])
+ })
+ ourg.goroutineProfiled.Store(goroutineProfileSatisfied)
+ goroutineProfile.offset.Store(1)
+
+ // Prepare for all other goroutines to enter the profile. Aside from ourg,
+ // every goroutine struct in the allgs list has its goroutineProfiled field
+ // cleared. Any goroutine created from this point on (while
+ // goroutineProfile.active is set) will start with its goroutineProfiled
+ // field set to goroutineProfileSatisfied.
+ goroutineProfile.active = true
+ goroutineProfile.records = p
+ goroutineProfile.labels = labels
+ // The finalizer goroutine needs special handling because it can vary over
+ // time between being a user goroutine (eligible for this profile) and a
+ // system goroutine (to be excluded). Pick one before restarting the world.
+ if fing != nil {
+ fing.goroutineProfiled.Store(goroutineProfileSatisfied)
+ if readgstatus(fing) != _Gdead && !isSystemGoroutine(fing, false) {
+ doRecordGoroutineProfile(fing)
+ }
+ }
+ startTheWorld()
+
+ // Visit each goroutine that existed as of the startTheWorld call above.
+ //
+ // New goroutines may not be in this list, but we didn't want to know about
+ // them anyway. If they do appear in this list (via reusing a dead goroutine
+ // struct, or racing to launch between the world restarting and us getting
+ // the list), they will already have their goroutineProfiled field set to
+ // goroutineProfileSatisfied before their state transitions out of _Gdead.
+ //
+ // Any goroutine that the scheduler tries to execute concurrently with this
+ // call will start by adding itself to the profile (before the act of
+ // executing can cause any changes in its stack).
+ forEachGRace(func(gp1 *g) {
+ tryRecordGoroutineProfile(gp1, Gosched)
+ })
+
+ stopTheWorld(stwGoroutineProfileCleanup)
+ endOffset := goroutineProfile.offset.Swap(0)
+ goroutineProfile.active = false
+ goroutineProfile.records = nil
+ goroutineProfile.labels = nil
+ startTheWorld()
+
+ // Restore the invariant that every goroutine struct in allgs has its
+ // goroutineProfiled field cleared.
+ forEachGRace(func(gp1 *g) {
+ gp1.goroutineProfiled.Store(goroutineProfileAbsent)
+ })
+
+ if raceenabled {
+ raceacquire(unsafe.Pointer(&labelSync))
+ }
+
+ if n != int(endOffset) {
+ // It's a big surprise that the number of goroutines changed while we
+ // were collecting the profile. But probably better to return a
+ // truncated profile than to crash the whole process.
+ //
+ // For instance, needm moves a goroutine out of the _Gdead state and so
+ // might be able to change the goroutine count without interacting with
+ // the scheduler. For code like that, the race windows are small and the
+ // combination of features is uncommon, so it's hard to be (and remain)
+ // sure we've caught them all.
+ }
+
+ semrelease(&goroutineProfile.sema)
+ return n, true
+}
+
+// tryRecordGoroutineProfileWB asserts that write barriers are allowed and calls
+// tryRecordGoroutineProfile.
+//
+//go:yeswritebarrierrec
+func tryRecordGoroutineProfileWB(gp1 *g) {
+ if getg().m.p.ptr() == nil {
+ throw("no P available, write barriers are forbidden")
+ }
+ tryRecordGoroutineProfile(gp1, osyield)
+}
+
+// tryRecordGoroutineProfile ensures that gp1 has the appropriate representation
+// in the current goroutine profile: either that it should not be profiled, or
+// that a snapshot of its call stack and labels are now in the profile.
+func tryRecordGoroutineProfile(gp1 *g, yield func()) {
+ if readgstatus(gp1) == _Gdead {
+ // Dead goroutines should not appear in the profile. Goroutines that
+ // start while profile collection is active will get goroutineProfiled
+ // set to goroutineProfileSatisfied before transitioning out of _Gdead,
+ // so here we check _Gdead first.
+ return
+ }
+ if isSystemGoroutine(gp1, true) {
+ // System goroutines should not appear in the profile. (The finalizer
+ // goroutine is marked as "already profiled".)
+ return
+ }
+
+ for {
+ prev := gp1.goroutineProfiled.Load()
+ if prev == goroutineProfileSatisfied {
+ // This goroutine is already in the profile (or is new since the
+ // start of collection, so shouldn't appear in the profile).
+ break
+ }
+ if prev == goroutineProfileInProgress {
+ // Something else is adding gp1 to the goroutine profile right now.
+ // Give that a moment to finish.
+ yield()
+ continue
+ }
+
+ // While we have gp1.goroutineProfiled set to
+ // goroutineProfileInProgress, gp1 may appear _Grunnable but will not
+ // actually be able to run. Disable preemption for ourselves, to make
+ // sure we finish profiling gp1 right away instead of leaving it stuck
+ // in this limbo.
+ mp := acquirem()
+ if gp1.goroutineProfiled.CompareAndSwap(goroutineProfileAbsent, goroutineProfileInProgress) {
+ doRecordGoroutineProfile(gp1)
+ gp1.goroutineProfiled.Store(goroutineProfileSatisfied)
+ }
+ releasem(mp)
+ }
+}
+
+// doRecordGoroutineProfile writes gp1's call stack and labels to an in-progress
+// goroutine profile. Preemption is disabled.
+//
+// This may be called via tryRecordGoroutineProfile in two ways: by the
+// goroutine that is coordinating the goroutine profile (running on its own
+// stack), or from the scheduler in preparation to execute gp1 (running on the
+// system stack).
+func doRecordGoroutineProfile(gp1 *g) {
+ if readgstatus(gp1) == _Grunning {
+ print("doRecordGoroutineProfile gp1=", gp1.goid, "\n")
+ throw("cannot read stack of running goroutine")
+ }
+
+ offset := int(goroutineProfile.offset.Add(1)) - 1
+
+ if offset >= len(goroutineProfile.records) {
+ // Should be impossible, but better to return a truncated profile than
+ // to crash the entire process at this point. Instead, deal with it in
+ // goroutineProfileWithLabelsConcurrent where we have more context.
+ return
+ }
+
+ // saveg calls gentraceback, which may call cgo traceback functions. When
+ // called from the scheduler, this is on the system stack already so
+ // traceback.go:cgoContextPCs will avoid calling back into the scheduler.
+ //
+ // When called from the goroutine coordinating the profile, we still have
+ // set gp1.goroutineProfiled to goroutineProfileInProgress and so are still
+ // preventing it from being truly _Grunnable. So we'll use the system stack
+ // to avoid schedule delays.
+ systemstack(func() { saveg(^uintptr(0), ^uintptr(0), gp1, &goroutineProfile.records[offset]) })
+
+ if goroutineProfile.labels != nil {
+ goroutineProfile.labels[offset] = gp1.labels
+ }
+}
+
+func goroutineProfileWithLabelsSync(p []StackRecord, labels []unsafe.Pointer) (n int, ok bool) {
+ gp := getg()
+
+ isOK := func(gp1 *g) bool {
+ // Checking isSystemGoroutine here makes GoroutineProfile
+ // consistent with both NumGoroutine and Stack.
+ return gp1 != gp && readgstatus(gp1) != _Gdead && !isSystemGoroutine(gp1, false)
+ }
+
+ stopTheWorld(stwGoroutineProfile)
+
+ // World is stopped, no locking required.
+ n = 1
+ forEachGRace(func(gp1 *g) {
+ if isOK(gp1) {
+ n++
+ }
+ })
+
+ if n <= len(p) {
+ ok = true
+ r, lbl := p, labels
+
+ // Save current goroutine.
+ sp := getcallersp()
+ pc := getcallerpc()
+ systemstack(func() {
+ saveg(pc, sp, gp, &r[0])
+ })
+ r = r[1:]
+
+ // If we have a place to put our goroutine labelmap, insert it there.
+ if labels != nil {
+ lbl[0] = gp.labels
+ lbl = lbl[1:]
+ }
+
+ // Save other goroutines.
+ forEachGRace(func(gp1 *g) {
+ if !isOK(gp1) {
+ return
+ }
+
+ if len(r) == 0 {
+ // Should be impossible, but better to return a
+ // truncated profile than to crash the entire process.
+ return
+ }
+ // saveg calls gentraceback, which may call cgo traceback functions.
+ // The world is stopped, so it cannot use cgocall (which will be
+ // blocked at exitsyscall). Do it on the system stack so it won't
+ // call into the schedular (see traceback.go:cgoContextPCs).
+ systemstack(func() { saveg(^uintptr(0), ^uintptr(0), gp1, &r[0]) })
+ if labels != nil {
+ lbl[0] = gp1.labels
+ lbl = lbl[1:]
+ }
+ r = r[1:]
+ })
+ }
+
+ if raceenabled {
+ raceacquire(unsafe.Pointer(&labelSync))
+ }
+
+ startTheWorld()
+ return n, ok
+}
+
+// GoroutineProfile returns n, the number of records in the active goroutine stack profile.
+// If len(p) >= n, GoroutineProfile copies the profile into p and returns n, true.
+// If len(p) < n, GoroutineProfile does not change p and returns n, false.
+//
+// Most clients should use the runtime/pprof package instead
+// of calling GoroutineProfile directly.
+func GoroutineProfile(p []StackRecord) (n int, ok bool) {
+
+ return goroutineProfileWithLabels(p, nil)
+}
+
+func saveg(pc, sp uintptr, gp *g, r *StackRecord) {
+ var u unwinder
+ u.initAt(pc, sp, 0, gp, unwindSilentErrors)
+ n := tracebackPCs(&u, 0, r.Stack0[:])
+ if n < len(r.Stack0) {
+ r.Stack0[n] = 0
+ }
+}
+
+// Stack formats a stack trace of the calling goroutine into buf
+// and returns the number of bytes written to buf.
+// If all is true, Stack formats stack traces of all other goroutines
+// into buf after the trace for the current goroutine.
+func Stack(buf []byte, all bool) int {
+ if all {
+ stopTheWorld(stwAllGoroutinesStack)
+ }
+
+ n := 0
+ if len(buf) > 0 {
+ gp := getg()
+ sp := getcallersp()
+ pc := getcallerpc()
+ systemstack(func() {
+ g0 := getg()
+ // Force traceback=1 to override GOTRACEBACK setting,
+ // so that Stack's results are consistent.
+ // GOTRACEBACK is only about crash dumps.
+ g0.m.traceback = 1
+ g0.writebuf = buf[0:0:len(buf)]
+ goroutineheader(gp)
+ traceback(pc, sp, 0, gp)
+ if all {
+ tracebackothers(gp)
+ }
+ g0.m.traceback = 0
+ n = len(g0.writebuf)
+ g0.writebuf = nil
+ })
+ }
+
+ if all {
+ startTheWorld()
+ }
+ return n
+}
+
+// Tracing of alloc/free/gc.
+
+var tracelock mutex
+
+func tracealloc(p unsafe.Pointer, size uintptr, typ *_type) {
+ lock(&tracelock)
+ gp := getg()
+ gp.m.traceback = 2
+ if typ == nil {
+ print("tracealloc(", p, ", ", hex(size), ")\n")
+ } else {
+ print("tracealloc(", p, ", ", hex(size), ", ", toRType(typ).string(), ")\n")
+ }
+ if gp.m.curg == nil || gp == gp.m.curg {
+ goroutineheader(gp)
+ pc := getcallerpc()
+ sp := getcallersp()
+ systemstack(func() {
+ traceback(pc, sp, 0, gp)
+ })
+ } else {
+ goroutineheader(gp.m.curg)
+ traceback(^uintptr(0), ^uintptr(0), 0, gp.m.curg)
+ }
+ print("\n")
+ gp.m.traceback = 0
+ unlock(&tracelock)
+}
+
+func tracefree(p unsafe.Pointer, size uintptr) {
+ lock(&tracelock)
+ gp := getg()
+ gp.m.traceback = 2
+ print("tracefree(", p, ", ", hex(size), ")\n")
+ goroutineheader(gp)
+ pc := getcallerpc()
+ sp := getcallersp()
+ systemstack(func() {
+ traceback(pc, sp, 0, gp)
+ })
+ print("\n")
+ gp.m.traceback = 0
+ unlock(&tracelock)
+}
+
+func tracegc() {
+ lock(&tracelock)
+ gp := getg()
+ gp.m.traceback = 2
+ print("tracegc()\n")
+ // running on m->g0 stack; show all non-g0 goroutines
+ tracebackothers(gp)
+ print("end tracegc\n")
+ print("\n")
+ gp.m.traceback = 0
+ unlock(&tracelock)
+}
diff --git a/contrib/go/_std_1.20/src/runtime/mranges.go b/contrib/go/_std_1.21/src/runtime/mranges.go
index 4388d26088..4388d26088 100644
--- a/contrib/go/_std_1.20/src/runtime/mranges.go
+++ b/contrib/go/_std_1.21/src/runtime/mranges.go
diff --git a/contrib/go/_std_1.20/src/runtime/msan0.go b/contrib/go/_std_1.21/src/runtime/msan0.go
index 2f5fd2d982..2f5fd2d982 100644
--- a/contrib/go/_std_1.20/src/runtime/msan0.go
+++ b/contrib/go/_std_1.21/src/runtime/msan0.go
diff --git a/contrib/go/_std_1.20/src/runtime/msize.go b/contrib/go/_std_1.21/src/runtime/msize.go
index c56aa5a7b2..c56aa5a7b2 100644
--- a/contrib/go/_std_1.20/src/runtime/msize.go
+++ b/contrib/go/_std_1.21/src/runtime/msize.go
diff --git a/contrib/go/_std_1.21/src/runtime/mspanset.go b/contrib/go/_std_1.21/src/runtime/mspanset.go
new file mode 100644
index 0000000000..5520d6ce75
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mspanset.go
@@ -0,0 +1,404 @@
+// 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 runtime
+
+import (
+ "internal/cpu"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// A spanSet is a set of *mspans.
+//
+// spanSet is safe for concurrent push and pop operations.
+type spanSet struct {
+ // A spanSet is a two-level data structure consisting of a
+ // growable spine that points to fixed-sized blocks. The spine
+ // can be accessed without locks, but adding a block or
+ // growing it requires taking the spine lock.
+ //
+ // Because each mspan covers at least 8K of heap and takes at
+ // most 8 bytes in the spanSet, the growth of the spine is
+ // quite limited.
+ //
+ // The spine and all blocks are allocated off-heap, which
+ // allows this to be used in the memory manager and avoids the
+ // need for write barriers on all of these. spanSetBlocks are
+ // managed in a pool, though never freed back to the operating
+ // system. We never release spine memory because there could be
+ // concurrent lock-free access and we're likely to reuse it
+ // anyway. (In principle, we could do this during STW.)
+
+ spineLock mutex
+ spine atomicSpanSetSpinePointer // *[N]atomic.Pointer[spanSetBlock]
+ spineLen atomic.Uintptr // Spine array length
+ spineCap uintptr // Spine array cap, accessed under spineLock
+
+ // index is the head and tail of the spanSet in a single field.
+ // The head and the tail both represent an index into the logical
+ // concatenation of all blocks, with the head always behind or
+ // equal to the tail (indicating an empty set). This field is
+ // always accessed atomically.
+ //
+ // The head and the tail are only 32 bits wide, which means we
+ // can only support up to 2^32 pushes before a reset. If every
+ // span in the heap were stored in this set, and each span were
+ // the minimum size (1 runtime page, 8 KiB), then roughly the
+ // smallest heap which would be unrepresentable is 32 TiB in size.
+ index atomicHeadTailIndex
+}
+
+const (
+ spanSetBlockEntries = 512 // 4KB on 64-bit
+ spanSetInitSpineCap = 256 // Enough for 1GB heap on 64-bit
+)
+
+type spanSetBlock struct {
+ // Free spanSetBlocks are managed via a lock-free stack.
+ lfnode
+
+ // popped is the number of pop operations that have occurred on
+ // this block. This number is used to help determine when a block
+ // may be safely recycled.
+ popped atomic.Uint32
+
+ // spans is the set of spans in this block.
+ spans [spanSetBlockEntries]atomicMSpanPointer
+}
+
+// push adds span s to buffer b. push is safe to call concurrently
+// with other push and pop operations.
+func (b *spanSet) push(s *mspan) {
+ // Obtain our slot.
+ cursor := uintptr(b.index.incTail().tail() - 1)
+ top, bottom := cursor/spanSetBlockEntries, cursor%spanSetBlockEntries
+
+ // Do we need to add a block?
+ spineLen := b.spineLen.Load()
+ var block *spanSetBlock
+retry:
+ if top < spineLen {
+ block = b.spine.Load().lookup(top).Load()
+ } else {
+ // Add a new block to the spine, potentially growing
+ // the spine.
+ lock(&b.spineLock)
+ // spineLen cannot change until we release the lock,
+ // but may have changed while we were waiting.
+ spineLen = b.spineLen.Load()
+ if top < spineLen {
+ unlock(&b.spineLock)
+ goto retry
+ }
+
+ spine := b.spine.Load()
+ if spineLen == b.spineCap {
+ // Grow the spine.
+ newCap := b.spineCap * 2
+ if newCap == 0 {
+ newCap = spanSetInitSpineCap
+ }
+ newSpine := persistentalloc(newCap*goarch.PtrSize, cpu.CacheLineSize, &memstats.gcMiscSys)
+ if b.spineCap != 0 {
+ // Blocks are allocated off-heap, so
+ // no write barriers.
+ memmove(newSpine, spine.p, b.spineCap*goarch.PtrSize)
+ }
+ spine = spanSetSpinePointer{newSpine}
+
+ // Spine is allocated off-heap, so no write barrier.
+ b.spine.StoreNoWB(spine)
+ b.spineCap = newCap
+ // We can't immediately free the old spine
+ // since a concurrent push with a lower index
+ // could still be reading from it. We let it
+ // leak because even a 1TB heap would waste
+ // less than 2MB of memory on old spines. If
+ // this is a problem, we could free old spines
+ // during STW.
+ }
+
+ // Allocate a new block from the pool.
+ block = spanSetBlockPool.alloc()
+
+ // Add it to the spine.
+ // Blocks are allocated off-heap, so no write barrier.
+ spine.lookup(top).StoreNoWB(block)
+ b.spineLen.Store(spineLen + 1)
+ unlock(&b.spineLock)
+ }
+
+ // We have a block. Insert the span atomically, since there may be
+ // concurrent readers via the block API.
+ block.spans[bottom].StoreNoWB(s)
+}
+
+// pop removes and returns a span from buffer b, or nil if b is empty.
+// pop is safe to call concurrently with other pop and push operations.
+func (b *spanSet) pop() *mspan {
+ var head, tail uint32
+claimLoop:
+ for {
+ headtail := b.index.load()
+ head, tail = headtail.split()
+ if head >= tail {
+ // The buf is empty, as far as we can tell.
+ return nil
+ }
+ // Check if the head position we want to claim is actually
+ // backed by a block.
+ spineLen := b.spineLen.Load()
+ if spineLen <= uintptr(head)/spanSetBlockEntries {
+ // We're racing with a spine growth and the allocation of
+ // a new block (and maybe a new spine!), and trying to grab
+ // the span at the index which is currently being pushed.
+ // Instead of spinning, let's just notify the caller that
+ // there's nothing currently here. Spinning on this is
+ // almost definitely not worth it.
+ return nil
+ }
+ // Try to claim the current head by CASing in an updated head.
+ // This may fail transiently due to a push which modifies the
+ // tail, so keep trying while the head isn't changing.
+ want := head
+ for want == head {
+ if b.index.cas(headtail, makeHeadTailIndex(want+1, tail)) {
+ break claimLoop
+ }
+ headtail = b.index.load()
+ head, tail = headtail.split()
+ }
+ // We failed to claim the spot we were after and the head changed,
+ // meaning a popper got ahead of us. Try again from the top because
+ // the buf may not be empty.
+ }
+ top, bottom := head/spanSetBlockEntries, head%spanSetBlockEntries
+
+ // We may be reading a stale spine pointer, but because the length
+ // grows monotonically and we've already verified it, we'll definitely
+ // be reading from a valid block.
+ blockp := b.spine.Load().lookup(uintptr(top))
+
+ // Given that the spine length is correct, we know we will never
+ // see a nil block here, since the length is always updated after
+ // the block is set.
+ block := blockp.Load()
+ s := block.spans[bottom].Load()
+ for s == nil {
+ // We raced with the span actually being set, but given that we
+ // know a block for this span exists, the race window here is
+ // extremely small. Try again.
+ s = block.spans[bottom].Load()
+ }
+ // Clear the pointer. This isn't strictly necessary, but defensively
+ // avoids accidentally re-using blocks which could lead to memory
+ // corruption. This way, we'll get a nil pointer access instead.
+ block.spans[bottom].StoreNoWB(nil)
+
+ // Increase the popped count. If we are the last possible popper
+ // in the block (note that bottom need not equal spanSetBlockEntries-1
+ // due to races) then it's our responsibility to free the block.
+ //
+ // If we increment popped to spanSetBlockEntries, we can be sure that
+ // we're the last popper for this block, and it's thus safe to free it.
+ // Every other popper must have crossed this barrier (and thus finished
+ // popping its corresponding mspan) by the time we get here. Because
+ // we're the last popper, we also don't have to worry about concurrent
+ // pushers (there can't be any). Note that we may not be the popper
+ // which claimed the last slot in the block, we're just the last one
+ // to finish popping.
+ if block.popped.Add(1) == spanSetBlockEntries {
+ // Clear the block's pointer.
+ blockp.StoreNoWB(nil)
+
+ // Return the block to the block pool.
+ spanSetBlockPool.free(block)
+ }
+ return s
+}
+
+// reset resets a spanSet which is empty. It will also clean up
+// any left over blocks.
+//
+// Throws if the buf is not empty.
+//
+// reset may not be called concurrently with any other operations
+// on the span set.
+func (b *spanSet) reset() {
+ head, tail := b.index.load().split()
+ if head < tail {
+ print("head = ", head, ", tail = ", tail, "\n")
+ throw("attempt to clear non-empty span set")
+ }
+ top := head / spanSetBlockEntries
+ if uintptr(top) < b.spineLen.Load() {
+ // If the head catches up to the tail and the set is empty,
+ // we may not clean up the block containing the head and tail
+ // since it may be pushed into again. In order to avoid leaking
+ // memory since we're going to reset the head and tail, clean
+ // up such a block now, if it exists.
+ blockp := b.spine.Load().lookup(uintptr(top))
+ block := blockp.Load()
+ if block != nil {
+ // Check the popped value.
+ if block.popped.Load() == 0 {
+ // popped should never be zero because that means we have
+ // pushed at least one value but not yet popped if this
+ // block pointer is not nil.
+ throw("span set block with unpopped elements found in reset")
+ }
+ if block.popped.Load() == spanSetBlockEntries {
+ // popped should also never be equal to spanSetBlockEntries
+ // because the last popper should have made the block pointer
+ // in this slot nil.
+ throw("fully empty unfreed span set block found in reset")
+ }
+
+ // Clear the pointer to the block.
+ blockp.StoreNoWB(nil)
+
+ // Return the block to the block pool.
+ spanSetBlockPool.free(block)
+ }
+ }
+ b.index.reset()
+ b.spineLen.Store(0)
+}
+
+// atomicSpanSetSpinePointer is an atomically-accessed spanSetSpinePointer.
+//
+// It has the same semantics as atomic.UnsafePointer.
+type atomicSpanSetSpinePointer struct {
+ a atomic.UnsafePointer
+}
+
+// Loads the spanSetSpinePointer and returns it.
+//
+// It has the same semantics as atomic.UnsafePointer.
+func (s *atomicSpanSetSpinePointer) Load() spanSetSpinePointer {
+ return spanSetSpinePointer{s.a.Load()}
+}
+
+// Stores the spanSetSpinePointer.
+//
+// It has the same semantics as atomic.UnsafePointer.
+func (s *atomicSpanSetSpinePointer) StoreNoWB(p spanSetSpinePointer) {
+ s.a.StoreNoWB(p.p)
+}
+
+// spanSetSpinePointer represents a pointer to a contiguous block of atomic.Pointer[spanSetBlock].
+type spanSetSpinePointer struct {
+ p unsafe.Pointer
+}
+
+// lookup returns &s[idx].
+func (s spanSetSpinePointer) lookup(idx uintptr) *atomic.Pointer[spanSetBlock] {
+ return (*atomic.Pointer[spanSetBlock])(add(unsafe.Pointer(s.p), goarch.PtrSize*idx))
+}
+
+// spanSetBlockPool is a global pool of spanSetBlocks.
+var spanSetBlockPool spanSetBlockAlloc
+
+// spanSetBlockAlloc represents a concurrent pool of spanSetBlocks.
+type spanSetBlockAlloc struct {
+ stack lfstack
+}
+
+// alloc tries to grab a spanSetBlock out of the pool, and if it fails
+// persistentallocs a new one and returns it.
+func (p *spanSetBlockAlloc) alloc() *spanSetBlock {
+ if s := (*spanSetBlock)(p.stack.pop()); s != nil {
+ return s
+ }
+ return (*spanSetBlock)(persistentalloc(unsafe.Sizeof(spanSetBlock{}), cpu.CacheLineSize, &memstats.gcMiscSys))
+}
+
+// free returns a spanSetBlock back to the pool.
+func (p *spanSetBlockAlloc) free(block *spanSetBlock) {
+ block.popped.Store(0)
+ p.stack.push(&block.lfnode)
+}
+
+// headTailIndex represents a combined 32-bit head and 32-bit tail
+// of a queue into a single 64-bit value.
+type headTailIndex uint64
+
+// makeHeadTailIndex creates a headTailIndex value from a separate
+// head and tail.
+func makeHeadTailIndex(head, tail uint32) headTailIndex {
+ return headTailIndex(uint64(head)<<32 | uint64(tail))
+}
+
+// head returns the head of a headTailIndex value.
+func (h headTailIndex) head() uint32 {
+ return uint32(h >> 32)
+}
+
+// tail returns the tail of a headTailIndex value.
+func (h headTailIndex) tail() uint32 {
+ return uint32(h)
+}
+
+// split splits the headTailIndex value into its parts.
+func (h headTailIndex) split() (head uint32, tail uint32) {
+ return h.head(), h.tail()
+}
+
+// atomicHeadTailIndex is an atomically-accessed headTailIndex.
+type atomicHeadTailIndex struct {
+ u atomic.Uint64
+}
+
+// load atomically reads a headTailIndex value.
+func (h *atomicHeadTailIndex) load() headTailIndex {
+ return headTailIndex(h.u.Load())
+}
+
+// cas atomically compares-and-swaps a headTailIndex value.
+func (h *atomicHeadTailIndex) cas(old, new headTailIndex) bool {
+ return h.u.CompareAndSwap(uint64(old), uint64(new))
+}
+
+// incHead atomically increments the head of a headTailIndex.
+func (h *atomicHeadTailIndex) incHead() headTailIndex {
+ return headTailIndex(h.u.Add(1 << 32))
+}
+
+// decHead atomically decrements the head of a headTailIndex.
+func (h *atomicHeadTailIndex) decHead() headTailIndex {
+ return headTailIndex(h.u.Add(-(1 << 32)))
+}
+
+// incTail atomically increments the tail of a headTailIndex.
+func (h *atomicHeadTailIndex) incTail() headTailIndex {
+ ht := headTailIndex(h.u.Add(1))
+ // Check for overflow.
+ if ht.tail() == 0 {
+ print("runtime: head = ", ht.head(), ", tail = ", ht.tail(), "\n")
+ throw("headTailIndex overflow")
+ }
+ return ht
+}
+
+// reset clears the headTailIndex to (0, 0).
+func (h *atomicHeadTailIndex) reset() {
+ h.u.Store(0)
+}
+
+// atomicMSpanPointer is an atomic.Pointer[mspan]. Can't use generics because it's NotInHeap.
+type atomicMSpanPointer struct {
+ p atomic.UnsafePointer
+}
+
+// Load returns the *mspan.
+func (p *atomicMSpanPointer) Load() *mspan {
+ return (*mspan)(p.p.Load())
+}
+
+// Store stores an *mspan.
+func (p *atomicMSpanPointer) StoreNoWB(s *mspan) {
+ p.p.StoreNoWB(unsafe.Pointer(s))
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mstats.go b/contrib/go/_std_1.21/src/runtime/mstats.go
new file mode 100644
index 0000000000..9cdc565137
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mstats.go
@@ -0,0 +1,969 @@
+// Copyright 2009 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.
+
+// Memory statistics
+
+package runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+type mstats struct {
+ // Statistics about malloc heap.
+ heapStats consistentHeapStats
+
+ // Statistics about stacks.
+ stacks_sys sysMemStat // only counts newosproc0 stack in mstats; differs from MemStats.StackSys
+
+ // Statistics about allocation of low-level fixed-size structures.
+ mspan_sys sysMemStat
+ mcache_sys sysMemStat
+ buckhash_sys sysMemStat // profiling bucket hash table
+
+ // Statistics about GC overhead.
+ gcMiscSys sysMemStat // updated atomically or during STW
+
+ // Miscellaneous statistics.
+ other_sys sysMemStat // updated atomically or during STW
+
+ // Statistics about the garbage collector.
+
+ // Protected by mheap or stopping the world during GC.
+ last_gc_unix uint64 // last gc (in unix time)
+ pause_total_ns uint64
+ pause_ns [256]uint64 // circular buffer of recent gc pause lengths
+ pause_end [256]uint64 // circular buffer of recent gc end times (nanoseconds since 1970)
+ numgc uint32
+ numforcedgc uint32 // number of user-forced GCs
+ gc_cpu_fraction float64 // fraction of CPU time used by GC
+
+ last_gc_nanotime uint64 // last gc (monotonic time)
+ lastHeapInUse uint64 // heapInUse at mark termination of the previous GC
+
+ enablegc bool
+
+ // gcPauseDist represents the distribution of all GC-related
+ // application pauses in the runtime.
+ //
+ // Each individual pause is counted separately, unlike pause_ns.
+ gcPauseDist timeHistogram
+}
+
+var memstats mstats
+
+// A MemStats records statistics about the memory allocator.
+type MemStats struct {
+ // General statistics.
+
+ // Alloc is bytes of allocated heap objects.
+ //
+ // This is the same as HeapAlloc (see below).
+ Alloc uint64
+
+ // TotalAlloc is cumulative bytes allocated for heap objects.
+ //
+ // TotalAlloc increases as heap objects are allocated, but
+ // unlike Alloc and HeapAlloc, it does not decrease when
+ // objects are freed.
+ TotalAlloc uint64
+
+ // Sys is the total bytes of memory obtained from the OS.
+ //
+ // Sys is the sum of the XSys fields below. Sys measures the
+ // virtual address space reserved by the Go runtime for the
+ // heap, stacks, and other internal data structures. It's
+ // likely that not all of the virtual address space is backed
+ // by physical memory at any given moment, though in general
+ // it all was at some point.
+ Sys uint64
+
+ // Lookups is the number of pointer lookups performed by the
+ // runtime.
+ //
+ // This is primarily useful for debugging runtime internals.
+ Lookups uint64
+
+ // Mallocs is the cumulative count of heap objects allocated.
+ // The number of live objects is Mallocs - Frees.
+ Mallocs uint64
+
+ // Frees is the cumulative count of heap objects freed.
+ Frees uint64
+
+ // Heap memory statistics.
+ //
+ // Interpreting the heap statistics requires some knowledge of
+ // how Go organizes memory. Go divides the virtual address
+ // space of the heap into "spans", which are contiguous
+ // regions of memory 8K or larger. A span may be in one of
+ // three states:
+ //
+ // An "idle" span contains no objects or other data. The
+ // physical memory backing an idle span can be released back
+ // to the OS (but the virtual address space never is), or it
+ // can be converted into an "in use" or "stack" span.
+ //
+ // An "in use" span contains at least one heap object and may
+ // have free space available to allocate more heap objects.
+ //
+ // A "stack" span is used for goroutine stacks. Stack spans
+ // are not considered part of the heap. A span can change
+ // between heap and stack memory; it is never used for both
+ // simultaneously.
+
+ // HeapAlloc is bytes of allocated heap objects.
+ //
+ // "Allocated" heap objects include all reachable objects, as
+ // well as unreachable objects that the garbage collector has
+ // not yet freed. Specifically, HeapAlloc increases as heap
+ // objects are allocated and decreases as the heap is swept
+ // and unreachable objects are freed. Sweeping occurs
+ // incrementally between GC cycles, so these two processes
+ // occur simultaneously, and as a result HeapAlloc tends to
+ // change smoothly (in contrast with the sawtooth that is
+ // typical of stop-the-world garbage collectors).
+ HeapAlloc uint64
+
+ // HeapSys is bytes of heap memory obtained from the OS.
+ //
+ // HeapSys measures the amount of virtual address space
+ // reserved for the heap. This includes virtual address space
+ // that has been reserved but not yet used, which consumes no
+ // physical memory, but tends to be small, as well as virtual
+ // address space for which the physical memory has been
+ // returned to the OS after it became unused (see HeapReleased
+ // for a measure of the latter).
+ //
+ // HeapSys estimates the largest size the heap has had.
+ HeapSys uint64
+
+ // HeapIdle is bytes in idle (unused) spans.
+ //
+ // Idle spans have no objects in them. These spans could be
+ // (and may already have been) returned to the OS, or they can
+ // be reused for heap allocations, or they can be reused as
+ // stack memory.
+ //
+ // HeapIdle minus HeapReleased estimates the amount of memory
+ // that could be returned to the OS, but is being retained by
+ // the runtime so it can grow the heap without requesting more
+ // memory from the OS. If this difference is significantly
+ // larger than the heap size, it indicates there was a recent
+ // transient spike in live heap size.
+ HeapIdle uint64
+
+ // HeapInuse is bytes in in-use spans.
+ //
+ // In-use spans have at least one object in them. These spans
+ // can only be used for other objects of roughly the same
+ // size.
+ //
+ // HeapInuse minus HeapAlloc estimates the amount of memory
+ // that has been dedicated to particular size classes, but is
+ // not currently being used. This is an upper bound on
+ // fragmentation, but in general this memory can be reused
+ // efficiently.
+ HeapInuse uint64
+
+ // HeapReleased is bytes of physical memory returned to the OS.
+ //
+ // This counts heap memory from idle spans that was returned
+ // to the OS and has not yet been reacquired for the heap.
+ HeapReleased uint64
+
+ // HeapObjects is the number of allocated heap objects.
+ //
+ // Like HeapAlloc, this increases as objects are allocated and
+ // decreases as the heap is swept and unreachable objects are
+ // freed.
+ HeapObjects uint64
+
+ // Stack memory statistics.
+ //
+ // Stacks are not considered part of the heap, but the runtime
+ // can reuse a span of heap memory for stack memory, and
+ // vice-versa.
+
+ // StackInuse is bytes in stack spans.
+ //
+ // In-use stack spans have at least one stack in them. These
+ // spans can only be used for other stacks of the same size.
+ //
+ // There is no StackIdle because unused stack spans are
+ // returned to the heap (and hence counted toward HeapIdle).
+ StackInuse uint64
+
+ // StackSys is bytes of stack memory obtained from the OS.
+ //
+ // StackSys is StackInuse, plus any memory obtained directly
+ // from the OS for OS thread stacks.
+ //
+ // In non-cgo programs this metric is currently equal to StackInuse
+ // (but this should not be relied upon, and the value may change in
+ // the future).
+ //
+ // In cgo programs this metric includes OS thread stacks allocated
+ // directly from the OS. Currently, this only accounts for one stack in
+ // c-shared and c-archive build modes and other sources of stacks from
+ // the OS (notably, any allocated by C code) are not currently measured.
+ // Note this too may change in the future.
+ StackSys uint64
+
+ // Off-heap memory statistics.
+ //
+ // The following statistics measure runtime-internal
+ // structures that are not allocated from heap memory (usually
+ // because they are part of implementing the heap). Unlike
+ // heap or stack memory, any memory allocated to these
+ // structures is dedicated to these structures.
+ //
+ // These are primarily useful for debugging runtime memory
+ // overheads.
+
+ // MSpanInuse is bytes of allocated mspan structures.
+ MSpanInuse uint64
+
+ // MSpanSys is bytes of memory obtained from the OS for mspan
+ // structures.
+ MSpanSys uint64
+
+ // MCacheInuse is bytes of allocated mcache structures.
+ MCacheInuse uint64
+
+ // MCacheSys is bytes of memory obtained from the OS for
+ // mcache structures.
+ MCacheSys uint64
+
+ // BuckHashSys is bytes of memory in profiling bucket hash tables.
+ BuckHashSys uint64
+
+ // GCSys is bytes of memory in garbage collection metadata.
+ GCSys uint64
+
+ // OtherSys is bytes of memory in miscellaneous off-heap
+ // runtime allocations.
+ OtherSys uint64
+
+ // Garbage collector statistics.
+
+ // NextGC is the target heap size of the next GC cycle.
+ //
+ // The garbage collector's goal is to keep HeapAlloc ≤ NextGC.
+ // At the end of each GC cycle, the target for the next cycle
+ // is computed based on the amount of reachable data and the
+ // value of GOGC.
+ NextGC uint64
+
+ // LastGC is the time the last garbage collection finished, as
+ // nanoseconds since 1970 (the UNIX epoch).
+ LastGC uint64
+
+ // PauseTotalNs is the cumulative nanoseconds in GC
+ // stop-the-world pauses since the program started.
+ //
+ // During a stop-the-world pause, all goroutines are paused
+ // and only the garbage collector can run.
+ PauseTotalNs uint64
+
+ // PauseNs is a circular buffer of recent GC stop-the-world
+ // pause times in nanoseconds.
+ //
+ // The most recent pause is at PauseNs[(NumGC+255)%256]. In
+ // general, PauseNs[N%256] records the time paused in the most
+ // recent N%256th GC cycle. There may be multiple pauses per
+ // GC cycle; this is the sum of all pauses during a cycle.
+ PauseNs [256]uint64
+
+ // PauseEnd is a circular buffer of recent GC pause end times,
+ // as nanoseconds since 1970 (the UNIX epoch).
+ //
+ // This buffer is filled the same way as PauseNs. There may be
+ // multiple pauses per GC cycle; this records the end of the
+ // last pause in a cycle.
+ PauseEnd [256]uint64
+
+ // NumGC is the number of completed GC cycles.
+ NumGC uint32
+
+ // NumForcedGC is the number of GC cycles that were forced by
+ // the application calling the GC function.
+ NumForcedGC uint32
+
+ // GCCPUFraction is the fraction of this program's available
+ // CPU time used by the GC since the program started.
+ //
+ // GCCPUFraction is expressed as a number between 0 and 1,
+ // where 0 means GC has consumed none of this program's CPU. A
+ // program's available CPU time is defined as the integral of
+ // GOMAXPROCS since the program started. That is, if
+ // GOMAXPROCS is 2 and a program has been running for 10
+ // seconds, its "available CPU" is 20 seconds. GCCPUFraction
+ // does not include CPU time used for write barrier activity.
+ //
+ // This is the same as the fraction of CPU reported by
+ // GODEBUG=gctrace=1.
+ GCCPUFraction float64
+
+ // EnableGC indicates that GC is enabled. It is always true,
+ // even if GOGC=off.
+ EnableGC bool
+
+ // DebugGC is currently unused.
+ DebugGC bool
+
+ // BySize reports per-size class allocation statistics.
+ //
+ // BySize[N] gives statistics for allocations of size S where
+ // BySize[N-1].Size < S ≤ BySize[N].Size.
+ //
+ // This does not report allocations larger than BySize[60].Size.
+ BySize [61]struct {
+ // Size is the maximum byte size of an object in this
+ // size class.
+ Size uint32
+
+ // Mallocs is the cumulative count of heap objects
+ // allocated in this size class. The cumulative bytes
+ // of allocation is Size*Mallocs. The number of live
+ // objects in this size class is Mallocs - Frees.
+ Mallocs uint64
+
+ // Frees is the cumulative count of heap objects freed
+ // in this size class.
+ Frees uint64
+ }
+}
+
+func init() {
+ if offset := unsafe.Offsetof(memstats.heapStats); offset%8 != 0 {
+ println(offset)
+ throw("memstats.heapStats not aligned to 8 bytes")
+ }
+ // Ensure the size of heapStatsDelta causes adjacent fields/slots (e.g.
+ // [3]heapStatsDelta) to be 8-byte aligned.
+ if size := unsafe.Sizeof(heapStatsDelta{}); size%8 != 0 {
+ println(size)
+ throw("heapStatsDelta not a multiple of 8 bytes in size")
+ }
+}
+
+// ReadMemStats populates m with memory allocator statistics.
+//
+// The returned memory allocator statistics are up to date as of the
+// call to ReadMemStats. This is in contrast with a heap profile,
+// which is a snapshot as of the most recently completed garbage
+// collection cycle.
+func ReadMemStats(m *MemStats) {
+ _ = m.Alloc // nil check test before we switch stacks, see issue 61158
+ stopTheWorld(stwReadMemStats)
+
+ systemstack(func() {
+ readmemstats_m(m)
+ })
+
+ startTheWorld()
+}
+
+// readmemstats_m populates stats for internal runtime values.
+//
+// The world must be stopped.
+func readmemstats_m(stats *MemStats) {
+ assertWorldStopped()
+
+ // Flush mcaches to mcentral before doing anything else.
+ //
+ // Flushing to the mcentral may in general cause stats to
+ // change as mcentral data structures are manipulated.
+ systemstack(flushallmcaches)
+
+ // Calculate memory allocator stats.
+ // During program execution we only count number of frees and amount of freed memory.
+ // Current number of alive objects in the heap and amount of alive heap memory
+ // are calculated by scanning all spans.
+ // Total number of mallocs is calculated as number of frees plus number of alive objects.
+ // Similarly, total amount of allocated memory is calculated as amount of freed memory
+ // plus amount of alive heap memory.
+
+ // Collect consistent stats, which are the source-of-truth in some cases.
+ var consStats heapStatsDelta
+ memstats.heapStats.unsafeRead(&consStats)
+
+ // Collect large allocation stats.
+ totalAlloc := consStats.largeAlloc
+ nMalloc := consStats.largeAllocCount
+ totalFree := consStats.largeFree
+ nFree := consStats.largeFreeCount
+
+ // Collect per-sizeclass stats.
+ var bySize [_NumSizeClasses]struct {
+ Size uint32
+ Mallocs uint64
+ Frees uint64
+ }
+ for i := range bySize {
+ bySize[i].Size = uint32(class_to_size[i])
+
+ // Malloc stats.
+ a := consStats.smallAllocCount[i]
+ totalAlloc += a * uint64(class_to_size[i])
+ nMalloc += a
+ bySize[i].Mallocs = a
+
+ // Free stats.
+ f := consStats.smallFreeCount[i]
+ totalFree += f * uint64(class_to_size[i])
+ nFree += f
+ bySize[i].Frees = f
+ }
+
+ // Account for tiny allocations.
+ // For historical reasons, MemStats includes tiny allocations
+ // in both the total free and total alloc count. This double-counts
+ // memory in some sense because their tiny allocation block is also
+ // counted. Tracking the lifetime of individual tiny allocations is
+ // currently not done because it would be too expensive.
+ nFree += consStats.tinyAllocCount
+ nMalloc += consStats.tinyAllocCount
+
+ // Calculate derived stats.
+
+ stackInUse := uint64(consStats.inStacks)
+ gcWorkBufInUse := uint64(consStats.inWorkBufs)
+ gcProgPtrScalarBitsInUse := uint64(consStats.inPtrScalarBits)
+
+ totalMapped := gcController.heapInUse.load() + gcController.heapFree.load() + gcController.heapReleased.load() +
+ memstats.stacks_sys.load() + memstats.mspan_sys.load() + memstats.mcache_sys.load() +
+ memstats.buckhash_sys.load() + memstats.gcMiscSys.load() + memstats.other_sys.load() +
+ stackInUse + gcWorkBufInUse + gcProgPtrScalarBitsInUse
+
+ heapGoal := gcController.heapGoal()
+
+ // The world is stopped, so the consistent stats (after aggregation)
+ // should be identical to some combination of memstats. In particular:
+ //
+ // * memstats.heapInUse == inHeap
+ // * memstats.heapReleased == released
+ // * memstats.heapInUse + memstats.heapFree == committed - inStacks - inWorkBufs - inPtrScalarBits
+ // * memstats.totalAlloc == totalAlloc
+ // * memstats.totalFree == totalFree
+ //
+ // Check if that's actually true.
+ //
+ // TODO(mknyszek): Maybe don't throw here. It would be bad if a
+ // bug in otherwise benign accounting caused the whole application
+ // to crash.
+ if gcController.heapInUse.load() != uint64(consStats.inHeap) {
+ print("runtime: heapInUse=", gcController.heapInUse.load(), "\n")
+ print("runtime: consistent value=", consStats.inHeap, "\n")
+ throw("heapInUse and consistent stats are not equal")
+ }
+ if gcController.heapReleased.load() != uint64(consStats.released) {
+ print("runtime: heapReleased=", gcController.heapReleased.load(), "\n")
+ print("runtime: consistent value=", consStats.released, "\n")
+ throw("heapReleased and consistent stats are not equal")
+ }
+ heapRetained := gcController.heapInUse.load() + gcController.heapFree.load()
+ consRetained := uint64(consStats.committed - consStats.inStacks - consStats.inWorkBufs - consStats.inPtrScalarBits)
+ if heapRetained != consRetained {
+ print("runtime: global value=", heapRetained, "\n")
+ print("runtime: consistent value=", consRetained, "\n")
+ throw("measures of the retained heap are not equal")
+ }
+ if gcController.totalAlloc.Load() != totalAlloc {
+ print("runtime: totalAlloc=", gcController.totalAlloc.Load(), "\n")
+ print("runtime: consistent value=", totalAlloc, "\n")
+ throw("totalAlloc and consistent stats are not equal")
+ }
+ if gcController.totalFree.Load() != totalFree {
+ print("runtime: totalFree=", gcController.totalFree.Load(), "\n")
+ print("runtime: consistent value=", totalFree, "\n")
+ throw("totalFree and consistent stats are not equal")
+ }
+ // Also check that mappedReady lines up with totalMapped - released.
+ // This isn't really the same type of "make sure consistent stats line up" situation,
+ // but this is an opportune time to check.
+ if gcController.mappedReady.Load() != totalMapped-uint64(consStats.released) {
+ print("runtime: mappedReady=", gcController.mappedReady.Load(), "\n")
+ print("runtime: totalMapped=", totalMapped, "\n")
+ print("runtime: released=", uint64(consStats.released), "\n")
+ print("runtime: totalMapped-released=", totalMapped-uint64(consStats.released), "\n")
+ throw("mappedReady and other memstats are not equal")
+ }
+
+ // We've calculated all the values we need. Now, populate stats.
+
+ stats.Alloc = totalAlloc - totalFree
+ stats.TotalAlloc = totalAlloc
+ stats.Sys = totalMapped
+ stats.Mallocs = nMalloc
+ stats.Frees = nFree
+ stats.HeapAlloc = totalAlloc - totalFree
+ stats.HeapSys = gcController.heapInUse.load() + gcController.heapFree.load() + gcController.heapReleased.load()
+ // By definition, HeapIdle is memory that was mapped
+ // for the heap but is not currently used to hold heap
+ // objects. It also specifically is memory that can be
+ // used for other purposes, like stacks, but this memory
+ // is subtracted out of HeapSys before it makes that
+ // transition. Put another way:
+ //
+ // HeapSys = bytes allocated from the OS for the heap - bytes ultimately used for non-heap purposes
+ // HeapIdle = bytes allocated from the OS for the heap - bytes ultimately used for any purpose
+ //
+ // or
+ //
+ // HeapSys = sys - stacks_inuse - gcWorkBufInUse - gcProgPtrScalarBitsInUse
+ // HeapIdle = sys - stacks_inuse - gcWorkBufInUse - gcProgPtrScalarBitsInUse - heapInUse
+ //
+ // => HeapIdle = HeapSys - heapInUse = heapFree + heapReleased
+ stats.HeapIdle = gcController.heapFree.load() + gcController.heapReleased.load()
+ stats.HeapInuse = gcController.heapInUse.load()
+ stats.HeapReleased = gcController.heapReleased.load()
+ stats.HeapObjects = nMalloc - nFree
+ stats.StackInuse = stackInUse
+ // memstats.stacks_sys is only memory mapped directly for OS stacks.
+ // Add in heap-allocated stack memory for user consumption.
+ stats.StackSys = stackInUse + memstats.stacks_sys.load()
+ stats.MSpanInuse = uint64(mheap_.spanalloc.inuse)
+ stats.MSpanSys = memstats.mspan_sys.load()
+ stats.MCacheInuse = uint64(mheap_.cachealloc.inuse)
+ stats.MCacheSys = memstats.mcache_sys.load()
+ stats.BuckHashSys = memstats.buckhash_sys.load()
+ // MemStats defines GCSys as an aggregate of all memory related
+ // to the memory management system, but we track this memory
+ // at a more granular level in the runtime.
+ stats.GCSys = memstats.gcMiscSys.load() + gcWorkBufInUse + gcProgPtrScalarBitsInUse
+ stats.OtherSys = memstats.other_sys.load()
+ stats.NextGC = heapGoal
+ stats.LastGC = memstats.last_gc_unix
+ stats.PauseTotalNs = memstats.pause_total_ns
+ stats.PauseNs = memstats.pause_ns
+ stats.PauseEnd = memstats.pause_end
+ stats.NumGC = memstats.numgc
+ stats.NumForcedGC = memstats.numforcedgc
+ stats.GCCPUFraction = memstats.gc_cpu_fraction
+ stats.EnableGC = true
+
+ // stats.BySize and bySize might not match in length.
+ // That's OK, stats.BySize cannot change due to backwards
+ // compatibility issues. copy will copy the minimum amount
+ // of values between the two of them.
+ copy(stats.BySize[:], bySize[:])
+}
+
+//go:linkname readGCStats runtime/debug.readGCStats
+func readGCStats(pauses *[]uint64) {
+ systemstack(func() {
+ readGCStats_m(pauses)
+ })
+}
+
+// readGCStats_m must be called on the system stack because it acquires the heap
+// lock. See mheap for details.
+//
+//go:systemstack
+func readGCStats_m(pauses *[]uint64) {
+ p := *pauses
+ // Calling code in runtime/debug should make the slice large enough.
+ if cap(p) < len(memstats.pause_ns)+3 {
+ throw("short slice passed to readGCStats")
+ }
+
+ // Pass back: pauses, pause ends, last gc (absolute time), number of gc, total pause ns.
+ lock(&mheap_.lock)
+
+ n := memstats.numgc
+ if n > uint32(len(memstats.pause_ns)) {
+ n = uint32(len(memstats.pause_ns))
+ }
+
+ // The pause buffer is circular. The most recent pause is at
+ // pause_ns[(numgc-1)%len(pause_ns)], and then backward
+ // from there to go back farther in time. We deliver the times
+ // most recent first (in p[0]).
+ p = p[:cap(p)]
+ for i := uint32(0); i < n; i++ {
+ j := (memstats.numgc - 1 - i) % uint32(len(memstats.pause_ns))
+ p[i] = memstats.pause_ns[j]
+ p[n+i] = memstats.pause_end[j]
+ }
+
+ p[n+n] = memstats.last_gc_unix
+ p[n+n+1] = uint64(memstats.numgc)
+ p[n+n+2] = memstats.pause_total_ns
+ unlock(&mheap_.lock)
+ *pauses = p[:n+n+3]
+}
+
+// flushmcache flushes the mcache of allp[i].
+//
+// The world must be stopped.
+//
+//go:nowritebarrier
+func flushmcache(i int) {
+ assertWorldStopped()
+
+ p := allp[i]
+ c := p.mcache
+ if c == nil {
+ return
+ }
+ c.releaseAll()
+ stackcache_clear(c)
+}
+
+// flushallmcaches flushes the mcaches of all Ps.
+//
+// The world must be stopped.
+//
+//go:nowritebarrier
+func flushallmcaches() {
+ assertWorldStopped()
+
+ for i := 0; i < int(gomaxprocs); i++ {
+ flushmcache(i)
+ }
+}
+
+// sysMemStat represents a global system statistic that is managed atomically.
+//
+// This type must structurally be a uint64 so that mstats aligns with MemStats.
+type sysMemStat uint64
+
+// load atomically reads the value of the stat.
+//
+// Must be nosplit as it is called in runtime initialization, e.g. newosproc0.
+//
+//go:nosplit
+func (s *sysMemStat) load() uint64 {
+ return atomic.Load64((*uint64)(s))
+}
+
+// add atomically adds the sysMemStat by n.
+//
+// Must be nosplit as it is called in runtime initialization, e.g. newosproc0.
+//
+//go:nosplit
+func (s *sysMemStat) add(n int64) {
+ val := atomic.Xadd64((*uint64)(s), n)
+ if (n > 0 && int64(val) < n) || (n < 0 && int64(val)+n < n) {
+ print("runtime: val=", val, " n=", n, "\n")
+ throw("sysMemStat overflow")
+ }
+}
+
+// heapStatsDelta contains deltas of various runtime memory statistics
+// that need to be updated together in order for them to be kept
+// consistent with one another.
+type heapStatsDelta struct {
+ // Memory stats.
+ committed int64 // byte delta of memory committed
+ released int64 // byte delta of released memory generated
+ inHeap int64 // byte delta of memory placed in the heap
+ inStacks int64 // byte delta of memory reserved for stacks
+ inWorkBufs int64 // byte delta of memory reserved for work bufs
+ inPtrScalarBits int64 // byte delta of memory reserved for unrolled GC prog bits
+
+ // Allocator stats.
+ //
+ // These are all uint64 because they're cumulative, and could quickly wrap
+ // around otherwise.
+ tinyAllocCount uint64 // number of tiny allocations
+ largeAlloc uint64 // bytes allocated for large objects
+ largeAllocCount uint64 // number of large object allocations
+ smallAllocCount [_NumSizeClasses]uint64 // number of allocs for small objects
+ largeFree uint64 // bytes freed for large objects (>maxSmallSize)
+ largeFreeCount uint64 // number of frees for large objects (>maxSmallSize)
+ smallFreeCount [_NumSizeClasses]uint64 // number of frees for small objects (<=maxSmallSize)
+
+ // NOTE: This struct must be a multiple of 8 bytes in size because it
+ // is stored in an array. If it's not, atomic accesses to the above
+ // fields may be unaligned and fail on 32-bit platforms.
+}
+
+// merge adds in the deltas from b into a.
+func (a *heapStatsDelta) merge(b *heapStatsDelta) {
+ a.committed += b.committed
+ a.released += b.released
+ a.inHeap += b.inHeap
+ a.inStacks += b.inStacks
+ a.inWorkBufs += b.inWorkBufs
+ a.inPtrScalarBits += b.inPtrScalarBits
+
+ a.tinyAllocCount += b.tinyAllocCount
+ a.largeAlloc += b.largeAlloc
+ a.largeAllocCount += b.largeAllocCount
+ for i := range b.smallAllocCount {
+ a.smallAllocCount[i] += b.smallAllocCount[i]
+ }
+ a.largeFree += b.largeFree
+ a.largeFreeCount += b.largeFreeCount
+ for i := range b.smallFreeCount {
+ a.smallFreeCount[i] += b.smallFreeCount[i]
+ }
+}
+
+// consistentHeapStats represents a set of various memory statistics
+// whose updates must be viewed completely to get a consistent
+// state of the world.
+//
+// To write updates to memory stats use the acquire and release
+// methods. To obtain a consistent global snapshot of these statistics,
+// use read.
+type consistentHeapStats struct {
+ // stats is a ring buffer of heapStatsDelta values.
+ // Writers always atomically update the delta at index gen.
+ //
+ // Readers operate by rotating gen (0 -> 1 -> 2 -> 0 -> ...)
+ // and synchronizing with writers by observing each P's
+ // statsSeq field. If the reader observes a P not writing,
+ // it can be sure that it will pick up the new gen value the
+ // next time it writes.
+ //
+ // The reader then takes responsibility by clearing space
+ // in the ring buffer for the next reader to rotate gen to
+ // that space (i.e. it merges in values from index (gen-2) mod 3
+ // to index (gen-1) mod 3, then clears the former).
+ //
+ // Note that this means only one reader can be reading at a time.
+ // There is no way for readers to synchronize.
+ //
+ // This process is why we need a ring buffer of size 3 instead
+ // of 2: one is for the writers, one contains the most recent
+ // data, and the last one is clear so writers can begin writing
+ // to it the moment gen is updated.
+ stats [3]heapStatsDelta
+
+ // gen represents the current index into which writers
+ // are writing, and can take on the value of 0, 1, or 2.
+ gen atomic.Uint32
+
+ // noPLock is intended to provide mutual exclusion for updating
+ // stats when no P is available. It does not block other writers
+ // with a P, only other writers without a P and the reader. Because
+ // stats are usually updated when a P is available, contention on
+ // this lock should be minimal.
+ noPLock mutex
+}
+
+// acquire returns a heapStatsDelta to be updated. In effect,
+// it acquires the shard for writing. release must be called
+// as soon as the relevant deltas are updated.
+//
+// The returned heapStatsDelta must be updated atomically.
+//
+// The caller's P must not change between acquire and
+// release. This also means that the caller should not
+// acquire a P or release its P in between. A P also must
+// not acquire a given consistentHeapStats if it hasn't
+// yet released it.
+//
+// nosplit because a stack growth in this function could
+// lead to a stack allocation that could reenter the
+// function.
+//
+//go:nosplit
+func (m *consistentHeapStats) acquire() *heapStatsDelta {
+ if pp := getg().m.p.ptr(); pp != nil {
+ seq := pp.statsSeq.Add(1)
+ if seq%2 == 0 {
+ // Should have been incremented to odd.
+ print("runtime: seq=", seq, "\n")
+ throw("bad sequence number")
+ }
+ } else {
+ lock(&m.noPLock)
+ }
+ gen := m.gen.Load() % 3
+ return &m.stats[gen]
+}
+
+// release indicates that the writer is done modifying
+// the delta. The value returned by the corresponding
+// acquire must no longer be accessed or modified after
+// release is called.
+//
+// The caller's P must not change between acquire and
+// release. This also means that the caller should not
+// acquire a P or release its P in between.
+//
+// nosplit because a stack growth in this function could
+// lead to a stack allocation that causes another acquire
+// before this operation has completed.
+//
+//go:nosplit
+func (m *consistentHeapStats) release() {
+ if pp := getg().m.p.ptr(); pp != nil {
+ seq := pp.statsSeq.Add(1)
+ if seq%2 != 0 {
+ // Should have been incremented to even.
+ print("runtime: seq=", seq, "\n")
+ throw("bad sequence number")
+ }
+ } else {
+ unlock(&m.noPLock)
+ }
+}
+
+// unsafeRead aggregates the delta for this shard into out.
+//
+// Unsafe because it does so without any synchronization. The
+// world must be stopped.
+func (m *consistentHeapStats) unsafeRead(out *heapStatsDelta) {
+ assertWorldStopped()
+
+ for i := range m.stats {
+ out.merge(&m.stats[i])
+ }
+}
+
+// unsafeClear clears the shard.
+//
+// Unsafe because the world must be stopped and values should
+// be donated elsewhere before clearing.
+func (m *consistentHeapStats) unsafeClear() {
+ assertWorldStopped()
+
+ for i := range m.stats {
+ m.stats[i] = heapStatsDelta{}
+ }
+}
+
+// read takes a globally consistent snapshot of m
+// and puts the aggregated value in out. Even though out is a
+// heapStatsDelta, the resulting values should be complete and
+// valid statistic values.
+//
+// Not safe to call concurrently. The world must be stopped
+// or metricsSema must be held.
+func (m *consistentHeapStats) read(out *heapStatsDelta) {
+ // Getting preempted after this point is not safe because
+ // we read allp. We need to make sure a STW can't happen
+ // so it doesn't change out from under us.
+ mp := acquirem()
+
+ // Get the current generation. We can be confident that this
+ // will not change since read is serialized and is the only
+ // one that modifies currGen.
+ currGen := m.gen.Load()
+ prevGen := currGen - 1
+ if currGen == 0 {
+ prevGen = 2
+ }
+
+ // Prevent writers without a P from writing while we update gen.
+ lock(&m.noPLock)
+
+ // Rotate gen, effectively taking a snapshot of the state of
+ // these statistics at the point of the exchange by moving
+ // writers to the next set of deltas.
+ //
+ // This exchange is safe to do because we won't race
+ // with anyone else trying to update this value.
+ m.gen.Swap((currGen + 1) % 3)
+
+ // Allow P-less writers to continue. They'll be writing to the
+ // next generation now.
+ unlock(&m.noPLock)
+
+ for _, p := range allp {
+ // Spin until there are no more writers.
+ for p.statsSeq.Load()%2 != 0 {
+ }
+ }
+
+ // At this point we've observed that each sequence
+ // number is even, so any future writers will observe
+ // the new gen value. That means it's safe to read from
+ // the other deltas in the stats buffer.
+
+ // Perform our responsibilities and free up
+ // stats[prevGen] for the next time we want to take
+ // a snapshot.
+ m.stats[currGen].merge(&m.stats[prevGen])
+ m.stats[prevGen] = heapStatsDelta{}
+
+ // Finally, copy out the complete delta.
+ *out = m.stats[currGen]
+
+ releasem(mp)
+}
+
+type cpuStats struct {
+ // All fields are CPU time in nanoseconds computed by comparing
+ // calls of nanotime. This means they're all overestimates, because
+ // they don't accurately compute on-CPU time (so some of the time
+ // could be spent scheduled away by the OS).
+
+ gcAssistTime int64 // GC assists
+ gcDedicatedTime int64 // GC dedicated mark workers + pauses
+ gcIdleTime int64 // GC idle mark workers
+ gcPauseTime int64 // GC pauses (all GOMAXPROCS, even if just 1 is running)
+ gcTotalTime int64
+
+ scavengeAssistTime int64 // background scavenger
+ scavengeBgTime int64 // scavenge assists
+ scavengeTotalTime int64
+
+ idleTime int64 // Time Ps spent in _Pidle.
+ userTime int64 // Time Ps spent in _Prunning or _Psyscall that's not any of the above.
+
+ totalTime int64 // GOMAXPROCS * (monotonic wall clock time elapsed)
+}
+
+// accumulate takes a cpuStats and adds in the current state of all GC CPU
+// counters.
+//
+// gcMarkPhase indicates that we're in the mark phase and that certain counter
+// values should be used.
+func (s *cpuStats) accumulate(now int64, gcMarkPhase bool) {
+ // N.B. Mark termination and sweep termination pauses are
+ // accumulated in work.cpuStats at the end of their respective pauses.
+ var (
+ markAssistCpu int64
+ markDedicatedCpu int64
+ markFractionalCpu int64
+ markIdleCpu int64
+ )
+ if gcMarkPhase {
+ // N.B. These stats may have stale values if the GC is not
+ // currently in the mark phase.
+ markAssistCpu = gcController.assistTime.Load()
+ markDedicatedCpu = gcController.dedicatedMarkTime.Load()
+ markFractionalCpu = gcController.fractionalMarkTime.Load()
+ markIdleCpu = gcController.idleMarkTime.Load()
+ }
+
+ // The rest of the stats below are either derived from the above or
+ // are reset on each mark termination.
+
+ scavAssistCpu := scavenge.assistTime.Load()
+ scavBgCpu := scavenge.backgroundTime.Load()
+
+ // Update cumulative GC CPU stats.
+ s.gcAssistTime += markAssistCpu
+ s.gcDedicatedTime += markDedicatedCpu + markFractionalCpu
+ s.gcIdleTime += markIdleCpu
+ s.gcTotalTime += markAssistCpu + markDedicatedCpu + markFractionalCpu + markIdleCpu
+
+ // Update cumulative scavenge CPU stats.
+ s.scavengeAssistTime += scavAssistCpu
+ s.scavengeBgTime += scavBgCpu
+ s.scavengeTotalTime += scavAssistCpu + scavBgCpu
+
+ // Update total CPU.
+ s.totalTime = sched.totaltime + (now-sched.procresizetime)*int64(gomaxprocs)
+ s.idleTime += sched.idleTime.Load()
+
+ // Compute userTime. We compute this indirectly as everything that's not the above.
+ //
+ // Since time spent in _Pgcstop is covered by gcPauseTime, and time spent in _Pidle
+ // is covered by idleTime, what we're left with is time spent in _Prunning and _Psyscall,
+ // the latter of which is fine because the P will either go idle or get used for something
+ // else via sysmon. Meanwhile if we subtract GC time from whatever's left, we get non-GC
+ // _Prunning time. Note that this still leaves time spent in sweeping and in the scheduler,
+ // but that's fine. The overwhelming majority of this time will be actual user time.
+ s.userTime = s.totalTime - (s.gcTotalTime + s.scavengeTotalTime + s.idleTime)
+}
diff --git a/contrib/go/_std_1.21/src/runtime/mwbbuf.go b/contrib/go/_std_1.21/src/runtime/mwbbuf.go
new file mode 100644
index 0000000000..7419bd291d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/mwbbuf.go
@@ -0,0 +1,270 @@
+// Copyright 2017 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.
+
+// This implements the write barrier buffer. The write barrier itself
+// is gcWriteBarrier and is implemented in assembly.
+//
+// See mbarrier.go for algorithmic details on the write barrier. This
+// file deals only with the buffer.
+//
+// The write barrier has a fast path and a slow path. The fast path
+// simply enqueues to a per-P write barrier buffer. It's written in
+// assembly and doesn't clobber any general purpose registers, so it
+// doesn't have the usual overheads of a Go call.
+//
+// When the buffer fills up, the write barrier invokes the slow path
+// (wbBufFlush) to flush the buffer to the GC work queues. In this
+// path, since the compiler didn't spill registers, we spill *all*
+// registers and disallow any GC safe points that could observe the
+// stack frame (since we don't know the types of the spilled
+// registers).
+
+package runtime
+
+import (
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// testSmallBuf forces a small write barrier buffer to stress write
+// barrier flushing.
+const testSmallBuf = false
+
+// wbBuf is a per-P buffer of pointers queued by the write barrier.
+// This buffer is flushed to the GC workbufs when it fills up and on
+// various GC transitions.
+//
+// This is closely related to a "sequential store buffer" (SSB),
+// except that SSBs are usually used for maintaining remembered sets,
+// while this is used for marking.
+type wbBuf struct {
+ // next points to the next slot in buf. It must not be a
+ // pointer type because it can point past the end of buf and
+ // must be updated without write barriers.
+ //
+ // This is a pointer rather than an index to optimize the
+ // write barrier assembly.
+ next uintptr
+
+ // end points to just past the end of buf. It must not be a
+ // pointer type because it points past the end of buf and must
+ // be updated without write barriers.
+ end uintptr
+
+ // buf stores a series of pointers to execute write barriers on.
+ buf [wbBufEntries]uintptr
+}
+
+const (
+ // wbBufEntries is the maximum number of pointers that can be
+ // stored in the write barrier buffer.
+ //
+ // This trades latency for throughput amortization. Higher
+ // values amortize flushing overhead more, but increase the
+ // latency of flushing. Higher values also increase the cache
+ // footprint of the buffer.
+ //
+ // TODO: What is the latency cost of this? Tune this value.
+ wbBufEntries = 512
+
+ // Maximum number of entries that we need to ask from the
+ // buffer in a single call.
+ wbMaxEntriesPerCall = 8
+)
+
+// reset empties b by resetting its next and end pointers.
+func (b *wbBuf) reset() {
+ start := uintptr(unsafe.Pointer(&b.buf[0]))
+ b.next = start
+ if testSmallBuf {
+ // For testing, make the buffer smaller but more than
+ // 1 write barrier's worth, so it tests both the
+ // immediate flush and delayed flush cases.
+ b.end = uintptr(unsafe.Pointer(&b.buf[wbMaxEntriesPerCall+1]))
+ } else {
+ b.end = start + uintptr(len(b.buf))*unsafe.Sizeof(b.buf[0])
+ }
+
+ if (b.end-b.next)%unsafe.Sizeof(b.buf[0]) != 0 {
+ throw("bad write barrier buffer bounds")
+ }
+}
+
+// discard resets b's next pointer, but not its end pointer.
+//
+// This must be nosplit because it's called by wbBufFlush.
+//
+//go:nosplit
+func (b *wbBuf) discard() {
+ b.next = uintptr(unsafe.Pointer(&b.buf[0]))
+}
+
+// empty reports whether b contains no pointers.
+func (b *wbBuf) empty() bool {
+ return b.next == uintptr(unsafe.Pointer(&b.buf[0]))
+}
+
+// getX returns space in the write barrier buffer to store X pointers.
+// getX will flush the buffer if necessary. Callers should use this as:
+//
+// buf := &getg().m.p.ptr().wbBuf
+// p := buf.get2()
+// p[0], p[1] = old, new
+// ... actual memory write ...
+//
+// The caller must ensure there are no preemption points during the
+// above sequence. There must be no preemption points while buf is in
+// use because it is a per-P resource. There must be no preemption
+// points between the buffer put and the write to memory because this
+// could allow a GC phase change, which could result in missed write
+// barriers.
+//
+// getX must be nowritebarrierrec to because write barriers here would
+// corrupt the write barrier buffer. It (and everything it calls, if
+// it called anything) has to be nosplit to avoid scheduling on to a
+// different P and a different buffer.
+//
+//go:nowritebarrierrec
+//go:nosplit
+func (b *wbBuf) get1() *[1]uintptr {
+ if b.next+goarch.PtrSize > b.end {
+ wbBufFlush()
+ }
+ p := (*[1]uintptr)(unsafe.Pointer(b.next))
+ b.next += goarch.PtrSize
+ return p
+}
+
+//go:nowritebarrierrec
+//go:nosplit
+func (b *wbBuf) get2() *[2]uintptr {
+ if b.next+2*goarch.PtrSize > b.end {
+ wbBufFlush()
+ }
+ p := (*[2]uintptr)(unsafe.Pointer(b.next))
+ b.next += 2 * goarch.PtrSize
+ return p
+}
+
+// wbBufFlush flushes the current P's write barrier buffer to the GC
+// workbufs.
+//
+// This must not have write barriers because it is part of the write
+// barrier implementation.
+//
+// This and everything it calls must be nosplit because 1) the stack
+// contains untyped slots from gcWriteBarrier and 2) there must not be
+// a GC safe point between the write barrier test in the caller and
+// flushing the buffer.
+//
+// TODO: A "go:nosplitrec" annotation would be perfect for this.
+//
+//go:nowritebarrierrec
+//go:nosplit
+func wbBufFlush() {
+ // Note: Every possible return from this function must reset
+ // the buffer's next pointer to prevent buffer overflow.
+
+ if getg().m.dying > 0 {
+ // We're going down. Not much point in write barriers
+ // and this way we can allow write barriers in the
+ // panic path.
+ getg().m.p.ptr().wbBuf.discard()
+ return
+ }
+
+ // Switch to the system stack so we don't have to worry about
+ // safe points.
+ systemstack(func() {
+ wbBufFlush1(getg().m.p.ptr())
+ })
+}
+
+// wbBufFlush1 flushes p's write barrier buffer to the GC work queue.
+//
+// This must not have write barriers because it is part of the write
+// barrier implementation, so this may lead to infinite loops or
+// buffer corruption.
+//
+// This must be non-preemptible because it uses the P's workbuf.
+//
+//go:nowritebarrierrec
+//go:systemstack
+func wbBufFlush1(pp *p) {
+ // Get the buffered pointers.
+ start := uintptr(unsafe.Pointer(&pp.wbBuf.buf[0]))
+ n := (pp.wbBuf.next - start) / unsafe.Sizeof(pp.wbBuf.buf[0])
+ ptrs := pp.wbBuf.buf[:n]
+
+ // Poison the buffer to make extra sure nothing is enqueued
+ // while we're processing the buffer.
+ pp.wbBuf.next = 0
+
+ if useCheckmark {
+ // Slow path for checkmark mode.
+ for _, ptr := range ptrs {
+ shade(ptr)
+ }
+ pp.wbBuf.reset()
+ return
+ }
+
+ // Mark all of the pointers in the buffer and record only the
+ // pointers we greyed. We use the buffer itself to temporarily
+ // record greyed pointers.
+ //
+ // TODO: Should scanobject/scanblock just stuff pointers into
+ // the wbBuf? Then this would become the sole greying path.
+ //
+ // TODO: We could avoid shading any of the "new" pointers in
+ // the buffer if the stack has been shaded, or even avoid
+ // putting them in the buffer at all (which would double its
+ // capacity). This is slightly complicated with the buffer; we
+ // could track whether any un-shaded goroutine has used the
+ // buffer, or just track globally whether there are any
+ // un-shaded stacks and flush after each stack scan.
+ gcw := &pp.gcw
+ pos := 0
+ for _, ptr := range ptrs {
+ if ptr < minLegalPointer {
+ // nil pointers are very common, especially
+ // for the "old" values. Filter out these and
+ // other "obvious" non-heap pointers ASAP.
+ //
+ // TODO: Should we filter out nils in the fast
+ // path to reduce the rate of flushes?
+ continue
+ }
+ obj, span, objIndex := findObject(ptr, 0, 0)
+ if obj == 0 {
+ continue
+ }
+ // TODO: Consider making two passes where the first
+ // just prefetches the mark bits.
+ mbits := span.markBitsForIndex(objIndex)
+ if mbits.isMarked() {
+ continue
+ }
+ mbits.setMarked()
+
+ // Mark span.
+ arena, pageIdx, pageMask := pageIndexOf(span.base())
+ if arena.pageMarks[pageIdx]&pageMask == 0 {
+ atomic.Or8(&arena.pageMarks[pageIdx], pageMask)
+ }
+
+ if span.spanclass.noscan() {
+ gcw.bytesMarked += uint64(span.elemsize)
+ continue
+ }
+ ptrs[pos] = obj
+ pos++
+ }
+
+ // Enqueue the greyed objects.
+ gcw.putBatch(ptrs[:pos])
+
+ pp.wbBuf.reset()
+}
diff --git a/contrib/go/_std_1.20/src/runtime/nbpipe_pipe.go b/contrib/go/_std_1.21/src/runtime/nbpipe_pipe.go
index 408e1ec410..408e1ec410 100644
--- a/contrib/go/_std_1.20/src/runtime/nbpipe_pipe.go
+++ b/contrib/go/_std_1.21/src/runtime/nbpipe_pipe.go
diff --git a/contrib/go/_std_1.20/src/runtime/nbpipe_pipe2.go b/contrib/go/_std_1.21/src/runtime/nbpipe_pipe2.go
index 22d60b4a63..22d60b4a63 100644
--- a/contrib/go/_std_1.20/src/runtime/nbpipe_pipe2.go
+++ b/contrib/go/_std_1.21/src/runtime/nbpipe_pipe2.go
diff --git a/contrib/go/_std_1.21/src/runtime/netpoll.go b/contrib/go/_std_1.21/src/runtime/netpoll.go
new file mode 100644
index 0000000000..9b54e8e21f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/netpoll.go
@@ -0,0 +1,694 @@
+// Copyright 2013 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.
+
+//go:build unix || (js && wasm) || wasip1 || windows
+
+package runtime
+
+import (
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// Integrated network poller (platform-independent part).
+// A particular implementation (epoll/kqueue/port/AIX/Windows)
+// must define the following functions:
+//
+// func netpollinit()
+// Initialize the poller. Only called once.
+//
+// func netpollopen(fd uintptr, pd *pollDesc) int32
+// Arm edge-triggered notifications for fd. The pd argument is to pass
+// back to netpollready when fd is ready. Return an errno value.
+//
+// func netpollclose(fd uintptr) int32
+// Disable notifications for fd. Return an errno value.
+//
+// func netpoll(delta int64) gList
+// Poll the network. If delta < 0, block indefinitely. If delta == 0,
+// poll without blocking. If delta > 0, block for up to delta nanoseconds.
+// Return a list of goroutines built by calling netpollready.
+//
+// func netpollBreak()
+// Wake up the network poller, assumed to be blocked in netpoll.
+//
+// func netpollIsPollDescriptor(fd uintptr) bool
+// Reports whether fd is a file descriptor used by the poller.
+
+// Error codes returned by runtime_pollReset and runtime_pollWait.
+// These must match the values in internal/poll/fd_poll_runtime.go.
+const (
+ pollNoError = 0 // no error
+ pollErrClosing = 1 // descriptor is closed
+ pollErrTimeout = 2 // I/O timeout
+ pollErrNotPollable = 3 // general error polling descriptor
+)
+
+// pollDesc contains 2 binary semaphores, rg and wg, to park reader and writer
+// goroutines respectively. The semaphore can be in the following states:
+//
+// pdReady - io readiness notification is pending;
+// a goroutine consumes the notification by changing the state to pdNil.
+// pdWait - a goroutine prepares to park on the semaphore, but not yet parked;
+// the goroutine commits to park by changing the state to G pointer,
+// or, alternatively, concurrent io notification changes the state to pdReady,
+// or, alternatively, concurrent timeout/close changes the state to pdNil.
+// G pointer - the goroutine is blocked on the semaphore;
+// io notification or timeout/close changes the state to pdReady or pdNil respectively
+// and unparks the goroutine.
+// pdNil - none of the above.
+const (
+ pdNil uintptr = 0
+ pdReady uintptr = 1
+ pdWait uintptr = 2
+)
+
+const pollBlockSize = 4 * 1024
+
+// Network poller descriptor.
+//
+// No heap pointers.
+type pollDesc struct {
+ _ sys.NotInHeap
+ link *pollDesc // in pollcache, protected by pollcache.lock
+ fd uintptr // constant for pollDesc usage lifetime
+ fdseq atomic.Uintptr // protects against stale pollDesc
+
+ // atomicInfo holds bits from closing, rd, and wd,
+ // which are only ever written while holding the lock,
+ // summarized for use by netpollcheckerr,
+ // which cannot acquire the lock.
+ // After writing these fields under lock in a way that
+ // might change the summary, code must call publishInfo
+ // before releasing the lock.
+ // Code that changes fields and then calls netpollunblock
+ // (while still holding the lock) must call publishInfo
+ // before calling netpollunblock, because publishInfo is what
+ // stops netpollblock from blocking anew
+ // (by changing the result of netpollcheckerr).
+ // atomicInfo also holds the eventErr bit,
+ // recording whether a poll event on the fd got an error;
+ // atomicInfo is the only source of truth for that bit.
+ atomicInfo atomic.Uint32 // atomic pollInfo
+
+ // rg, wg are accessed atomically and hold g pointers.
+ // (Using atomic.Uintptr here is similar to using guintptr elsewhere.)
+ rg atomic.Uintptr // pdReady, pdWait, G waiting for read or pdNil
+ wg atomic.Uintptr // pdReady, pdWait, G waiting for write or pdNil
+
+ lock mutex // protects the following fields
+ closing bool
+ user uint32 // user settable cookie
+ rseq uintptr // protects from stale read timers
+ rt timer // read deadline timer (set if rt.f != nil)
+ rd int64 // read deadline (a nanotime in the future, -1 when expired)
+ wseq uintptr // protects from stale write timers
+ wt timer // write deadline timer
+ wd int64 // write deadline (a nanotime in the future, -1 when expired)
+ self *pollDesc // storage for indirect interface. See (*pollDesc).makeArg.
+}
+
+// pollInfo is the bits needed by netpollcheckerr, stored atomically,
+// mostly duplicating state that is manipulated under lock in pollDesc.
+// The one exception is the pollEventErr bit, which is maintained only
+// in the pollInfo.
+type pollInfo uint32
+
+const (
+ pollClosing = 1 << iota
+ pollEventErr
+ pollExpiredReadDeadline
+ pollExpiredWriteDeadline
+ pollFDSeq // 20 bit field, low 20 bits of fdseq field
+)
+
+const (
+ pollFDSeqBits = 20 // number of bits in pollFDSeq
+ pollFDSeqMask = 1<<pollFDSeqBits - 1 // mask for pollFDSeq
+)
+
+func (i pollInfo) closing() bool { return i&pollClosing != 0 }
+func (i pollInfo) eventErr() bool { return i&pollEventErr != 0 }
+func (i pollInfo) expiredReadDeadline() bool { return i&pollExpiredReadDeadline != 0 }
+func (i pollInfo) expiredWriteDeadline() bool { return i&pollExpiredWriteDeadline != 0 }
+
+// info returns the pollInfo corresponding to pd.
+func (pd *pollDesc) info() pollInfo {
+ return pollInfo(pd.atomicInfo.Load())
+}
+
+// publishInfo updates pd.atomicInfo (returned by pd.info)
+// using the other values in pd.
+// It must be called while holding pd.lock,
+// and it must be called after changing anything
+// that might affect the info bits.
+// In practice this means after changing closing
+// or changing rd or wd from < 0 to >= 0.
+func (pd *pollDesc) publishInfo() {
+ var info uint32
+ if pd.closing {
+ info |= pollClosing
+ }
+ if pd.rd < 0 {
+ info |= pollExpiredReadDeadline
+ }
+ if pd.wd < 0 {
+ info |= pollExpiredWriteDeadline
+ }
+ info |= uint32(pd.fdseq.Load()&pollFDSeqMask) << pollFDSeq
+
+ // Set all of x except the pollEventErr bit.
+ x := pd.atomicInfo.Load()
+ for !pd.atomicInfo.CompareAndSwap(x, (x&pollEventErr)|info) {
+ x = pd.atomicInfo.Load()
+ }
+}
+
+// setEventErr sets the result of pd.info().eventErr() to b.
+// We only change the error bit if seq == 0 or if seq matches pollFDSeq
+// (issue #59545).
+func (pd *pollDesc) setEventErr(b bool, seq uintptr) {
+ mSeq := uint32(seq & pollFDSeqMask)
+ x := pd.atomicInfo.Load()
+ xSeq := (x >> pollFDSeq) & pollFDSeqMask
+ if seq != 0 && xSeq != mSeq {
+ return
+ }
+ for (x&pollEventErr != 0) != b && !pd.atomicInfo.CompareAndSwap(x, x^pollEventErr) {
+ x = pd.atomicInfo.Load()
+ xSeq := (x >> pollFDSeq) & pollFDSeqMask
+ if seq != 0 && xSeq != mSeq {
+ return
+ }
+ }
+}
+
+type pollCache struct {
+ lock mutex
+ first *pollDesc
+ // PollDesc objects must be type-stable,
+ // because we can get ready notification from epoll/kqueue
+ // after the descriptor is closed/reused.
+ // Stale notifications are detected using seq variable,
+ // seq is incremented when deadlines are changed or descriptor is reused.
+}
+
+var (
+ netpollInitLock mutex
+ netpollInited atomic.Uint32
+
+ pollcache pollCache
+ netpollWaiters atomic.Uint32
+)
+
+//go:linkname poll_runtime_pollServerInit internal/poll.runtime_pollServerInit
+func poll_runtime_pollServerInit() {
+ netpollGenericInit()
+}
+
+func netpollGenericInit() {
+ if netpollInited.Load() == 0 {
+ lockInit(&netpollInitLock, lockRankNetpollInit)
+ lock(&netpollInitLock)
+ if netpollInited.Load() == 0 {
+ netpollinit()
+ netpollInited.Store(1)
+ }
+ unlock(&netpollInitLock)
+ }
+}
+
+func netpollinited() bool {
+ return netpollInited.Load() != 0
+}
+
+//go:linkname poll_runtime_isPollServerDescriptor internal/poll.runtime_isPollServerDescriptor
+
+// poll_runtime_isPollServerDescriptor reports whether fd is a
+// descriptor being used by netpoll.
+func poll_runtime_isPollServerDescriptor(fd uintptr) bool {
+ return netpollIsPollDescriptor(fd)
+}
+
+//go:linkname poll_runtime_pollOpen internal/poll.runtime_pollOpen
+func poll_runtime_pollOpen(fd uintptr) (*pollDesc, int) {
+ pd := pollcache.alloc()
+ lock(&pd.lock)
+ wg := pd.wg.Load()
+ if wg != pdNil && wg != pdReady {
+ throw("runtime: blocked write on free polldesc")
+ }
+ rg := pd.rg.Load()
+ if rg != pdNil && rg != pdReady {
+ throw("runtime: blocked read on free polldesc")
+ }
+ pd.fd = fd
+ if pd.fdseq.Load() == 0 {
+ // The value 0 is special in setEventErr, so don't use it.
+ pd.fdseq.Store(1)
+ }
+ pd.closing = false
+ pd.setEventErr(false, 0)
+ pd.rseq++
+ pd.rg.Store(pdNil)
+ pd.rd = 0
+ pd.wseq++
+ pd.wg.Store(pdNil)
+ pd.wd = 0
+ pd.self = pd
+ pd.publishInfo()
+ unlock(&pd.lock)
+
+ errno := netpollopen(fd, pd)
+ if errno != 0 {
+ pollcache.free(pd)
+ return nil, int(errno)
+ }
+ return pd, 0
+}
+
+//go:linkname poll_runtime_pollClose internal/poll.runtime_pollClose
+func poll_runtime_pollClose(pd *pollDesc) {
+ if !pd.closing {
+ throw("runtime: close polldesc w/o unblock")
+ }
+ wg := pd.wg.Load()
+ if wg != pdNil && wg != pdReady {
+ throw("runtime: blocked write on closing polldesc")
+ }
+ rg := pd.rg.Load()
+ if rg != pdNil && rg != pdReady {
+ throw("runtime: blocked read on closing polldesc")
+ }
+ netpollclose(pd.fd)
+ pollcache.free(pd)
+}
+
+func (c *pollCache) free(pd *pollDesc) {
+ // pd can't be shared here, but lock anyhow because
+ // that's what publishInfo documents.
+ lock(&pd.lock)
+
+ // Increment the fdseq field, so that any currently
+ // running netpoll calls will not mark pd as ready.
+ fdseq := pd.fdseq.Load()
+ fdseq = (fdseq + 1) & (1<<taggedPointerBits - 1)
+ pd.fdseq.Store(fdseq)
+
+ pd.publishInfo()
+
+ unlock(&pd.lock)
+
+ lock(&c.lock)
+ pd.link = c.first
+ c.first = pd
+ unlock(&c.lock)
+}
+
+// poll_runtime_pollReset, which is internal/poll.runtime_pollReset,
+// prepares a descriptor for polling in mode, which is 'r' or 'w'.
+// This returns an error code; the codes are defined above.
+//
+//go:linkname poll_runtime_pollReset internal/poll.runtime_pollReset
+func poll_runtime_pollReset(pd *pollDesc, mode int) int {
+ errcode := netpollcheckerr(pd, int32(mode))
+ if errcode != pollNoError {
+ return errcode
+ }
+ if mode == 'r' {
+ pd.rg.Store(pdNil)
+ } else if mode == 'w' {
+ pd.wg.Store(pdNil)
+ }
+ return pollNoError
+}
+
+// poll_runtime_pollWait, which is internal/poll.runtime_pollWait,
+// waits for a descriptor to be ready for reading or writing,
+// according to mode, which is 'r' or 'w'.
+// This returns an error code; the codes are defined above.
+//
+//go:linkname poll_runtime_pollWait internal/poll.runtime_pollWait
+func poll_runtime_pollWait(pd *pollDesc, mode int) int {
+ errcode := netpollcheckerr(pd, int32(mode))
+ if errcode != pollNoError {
+ return errcode
+ }
+ // As for now only Solaris, illumos, AIX and wasip1 use level-triggered IO.
+ if GOOS == "solaris" || GOOS == "illumos" || GOOS == "aix" || GOOS == "wasip1" {
+ netpollarm(pd, mode)
+ }
+ for !netpollblock(pd, int32(mode), false) {
+ errcode = netpollcheckerr(pd, int32(mode))
+ if errcode != pollNoError {
+ return errcode
+ }
+ // Can happen if timeout has fired and unblocked us,
+ // but before we had a chance to run, timeout has been reset.
+ // Pretend it has not happened and retry.
+ }
+ return pollNoError
+}
+
+//go:linkname poll_runtime_pollWaitCanceled internal/poll.runtime_pollWaitCanceled
+func poll_runtime_pollWaitCanceled(pd *pollDesc, mode int) {
+ // This function is used only on windows after a failed attempt to cancel
+ // a pending async IO operation. Wait for ioready, ignore closing or timeouts.
+ for !netpollblock(pd, int32(mode), true) {
+ }
+}
+
+//go:linkname poll_runtime_pollSetDeadline internal/poll.runtime_pollSetDeadline
+func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) {
+ lock(&pd.lock)
+ if pd.closing {
+ unlock(&pd.lock)
+ return
+ }
+ rd0, wd0 := pd.rd, pd.wd
+ combo0 := rd0 > 0 && rd0 == wd0
+ if d > 0 {
+ d += nanotime()
+ if d <= 0 {
+ // If the user has a deadline in the future, but the delay calculation
+ // overflows, then set the deadline to the maximum possible value.
+ d = 1<<63 - 1
+ }
+ }
+ if mode == 'r' || mode == 'r'+'w' {
+ pd.rd = d
+ }
+ if mode == 'w' || mode == 'r'+'w' {
+ pd.wd = d
+ }
+ pd.publishInfo()
+ combo := pd.rd > 0 && pd.rd == pd.wd
+ rtf := netpollReadDeadline
+ if combo {
+ rtf = netpollDeadline
+ }
+ if pd.rt.f == nil {
+ if pd.rd > 0 {
+ pd.rt.f = rtf
+ // Copy current seq into the timer arg.
+ // Timer func will check the seq against current descriptor seq,
+ // if they differ the descriptor was reused or timers were reset.
+ pd.rt.arg = pd.makeArg()
+ pd.rt.seq = pd.rseq
+ resettimer(&pd.rt, pd.rd)
+ }
+ } else if pd.rd != rd0 || combo != combo0 {
+ pd.rseq++ // invalidate current timers
+ if pd.rd > 0 {
+ modtimer(&pd.rt, pd.rd, 0, rtf, pd.makeArg(), pd.rseq)
+ } else {
+ deltimer(&pd.rt)
+ pd.rt.f = nil
+ }
+ }
+ if pd.wt.f == nil {
+ if pd.wd > 0 && !combo {
+ pd.wt.f = netpollWriteDeadline
+ pd.wt.arg = pd.makeArg()
+ pd.wt.seq = pd.wseq
+ resettimer(&pd.wt, pd.wd)
+ }
+ } else if pd.wd != wd0 || combo != combo0 {
+ pd.wseq++ // invalidate current timers
+ if pd.wd > 0 && !combo {
+ modtimer(&pd.wt, pd.wd, 0, netpollWriteDeadline, pd.makeArg(), pd.wseq)
+ } else {
+ deltimer(&pd.wt)
+ pd.wt.f = nil
+ }
+ }
+ // If we set the new deadline in the past, unblock currently pending IO if any.
+ // Note that pd.publishInfo has already been called, above, immediately after modifying rd and wd.
+ var rg, wg *g
+ if pd.rd < 0 {
+ rg = netpollunblock(pd, 'r', false)
+ }
+ if pd.wd < 0 {
+ wg = netpollunblock(pd, 'w', false)
+ }
+ unlock(&pd.lock)
+ if rg != nil {
+ netpollgoready(rg, 3)
+ }
+ if wg != nil {
+ netpollgoready(wg, 3)
+ }
+}
+
+//go:linkname poll_runtime_pollUnblock internal/poll.runtime_pollUnblock
+func poll_runtime_pollUnblock(pd *pollDesc) {
+ lock(&pd.lock)
+ if pd.closing {
+ throw("runtime: unblock on closing polldesc")
+ }
+ pd.closing = true
+ pd.rseq++
+ pd.wseq++
+ var rg, wg *g
+ pd.publishInfo()
+ rg = netpollunblock(pd, 'r', false)
+ wg = netpollunblock(pd, 'w', false)
+ if pd.rt.f != nil {
+ deltimer(&pd.rt)
+ pd.rt.f = nil
+ }
+ if pd.wt.f != nil {
+ deltimer(&pd.wt)
+ pd.wt.f = nil
+ }
+ unlock(&pd.lock)
+ if rg != nil {
+ netpollgoready(rg, 3)
+ }
+ if wg != nil {
+ netpollgoready(wg, 3)
+ }
+}
+
+// netpollready is called by the platform-specific netpoll function.
+// It declares that the fd associated with pd is ready for I/O.
+// The toRun argument is used to build a list of goroutines to return
+// from netpoll. The mode argument is 'r', 'w', or 'r'+'w' to indicate
+// whether the fd is ready for reading or writing or both.
+//
+// This may run while the world is stopped, so write barriers are not allowed.
+//
+//go:nowritebarrier
+func netpollready(toRun *gList, pd *pollDesc, mode int32) {
+ var rg, wg *g
+ if mode == 'r' || mode == 'r'+'w' {
+ rg = netpollunblock(pd, 'r', true)
+ }
+ if mode == 'w' || mode == 'r'+'w' {
+ wg = netpollunblock(pd, 'w', true)
+ }
+ if rg != nil {
+ toRun.push(rg)
+ }
+ if wg != nil {
+ toRun.push(wg)
+ }
+}
+
+func netpollcheckerr(pd *pollDesc, mode int32) int {
+ info := pd.info()
+ if info.closing() {
+ return pollErrClosing
+ }
+ if (mode == 'r' && info.expiredReadDeadline()) || (mode == 'w' && info.expiredWriteDeadline()) {
+ return pollErrTimeout
+ }
+ // Report an event scanning error only on a read event.
+ // An error on a write event will be captured in a subsequent
+ // write call that is able to report a more specific error.
+ if mode == 'r' && info.eventErr() {
+ return pollErrNotPollable
+ }
+ return pollNoError
+}
+
+func netpollblockcommit(gp *g, gpp unsafe.Pointer) bool {
+ r := atomic.Casuintptr((*uintptr)(gpp), pdWait, uintptr(unsafe.Pointer(gp)))
+ if r {
+ // Bump the count of goroutines waiting for the poller.
+ // The scheduler uses this to decide whether to block
+ // waiting for the poller if there is nothing else to do.
+ netpollWaiters.Add(1)
+ }
+ return r
+}
+
+func netpollgoready(gp *g, traceskip int) {
+ netpollWaiters.Add(-1)
+ goready(gp, traceskip+1)
+}
+
+// returns true if IO is ready, or false if timed out or closed
+// waitio - wait only for completed IO, ignore errors
+// Concurrent calls to netpollblock in the same mode are forbidden, as pollDesc
+// can hold only a single waiting goroutine for each mode.
+func netpollblock(pd *pollDesc, mode int32, waitio bool) bool {
+ gpp := &pd.rg
+ if mode == 'w' {
+ gpp = &pd.wg
+ }
+
+ // set the gpp semaphore to pdWait
+ for {
+ // Consume notification if already ready.
+ if gpp.CompareAndSwap(pdReady, pdNil) {
+ return true
+ }
+ if gpp.CompareAndSwap(pdNil, pdWait) {
+ break
+ }
+
+ // Double check that this isn't corrupt; otherwise we'd loop
+ // forever.
+ if v := gpp.Load(); v != pdReady && v != pdNil {
+ throw("runtime: double wait")
+ }
+ }
+
+ // need to recheck error states after setting gpp to pdWait
+ // this is necessary because runtime_pollUnblock/runtime_pollSetDeadline/deadlineimpl
+ // do the opposite: store to closing/rd/wd, publishInfo, load of rg/wg
+ if waitio || netpollcheckerr(pd, mode) == pollNoError {
+ gopark(netpollblockcommit, unsafe.Pointer(gpp), waitReasonIOWait, traceBlockNet, 5)
+ }
+ // be careful to not lose concurrent pdReady notification
+ old := gpp.Swap(pdNil)
+ if old > pdWait {
+ throw("runtime: corrupted polldesc")
+ }
+ return old == pdReady
+}
+
+func netpollunblock(pd *pollDesc, mode int32, ioready bool) *g {
+ gpp := &pd.rg
+ if mode == 'w' {
+ gpp = &pd.wg
+ }
+
+ for {
+ old := gpp.Load()
+ if old == pdReady {
+ return nil
+ }
+ if old == pdNil && !ioready {
+ // Only set pdReady for ioready. runtime_pollWait
+ // will check for timeout/cancel before waiting.
+ return nil
+ }
+ var new uintptr
+ if ioready {
+ new = pdReady
+ }
+ if gpp.CompareAndSwap(old, new) {
+ if old == pdWait {
+ old = pdNil
+ }
+ return (*g)(unsafe.Pointer(old))
+ }
+ }
+}
+
+func netpolldeadlineimpl(pd *pollDesc, seq uintptr, read, write bool) {
+ lock(&pd.lock)
+ // Seq arg is seq when the timer was set.
+ // If it's stale, ignore the timer event.
+ currentSeq := pd.rseq
+ if !read {
+ currentSeq = pd.wseq
+ }
+ if seq != currentSeq {
+ // The descriptor was reused or timers were reset.
+ unlock(&pd.lock)
+ return
+ }
+ var rg *g
+ if read {
+ if pd.rd <= 0 || pd.rt.f == nil {
+ throw("runtime: inconsistent read deadline")
+ }
+ pd.rd = -1
+ pd.publishInfo()
+ rg = netpollunblock(pd, 'r', false)
+ }
+ var wg *g
+ if write {
+ if pd.wd <= 0 || pd.wt.f == nil && !read {
+ throw("runtime: inconsistent write deadline")
+ }
+ pd.wd = -1
+ pd.publishInfo()
+ wg = netpollunblock(pd, 'w', false)
+ }
+ unlock(&pd.lock)
+ if rg != nil {
+ netpollgoready(rg, 0)
+ }
+ if wg != nil {
+ netpollgoready(wg, 0)
+ }
+}
+
+func netpollDeadline(arg any, seq uintptr) {
+ netpolldeadlineimpl(arg.(*pollDesc), seq, true, true)
+}
+
+func netpollReadDeadline(arg any, seq uintptr) {
+ netpolldeadlineimpl(arg.(*pollDesc), seq, true, false)
+}
+
+func netpollWriteDeadline(arg any, seq uintptr) {
+ netpolldeadlineimpl(arg.(*pollDesc), seq, false, true)
+}
+
+func (c *pollCache) alloc() *pollDesc {
+ lock(&c.lock)
+ if c.first == nil {
+ const pdSize = unsafe.Sizeof(pollDesc{})
+ n := pollBlockSize / pdSize
+ if n == 0 {
+ n = 1
+ }
+ // Must be in non-GC memory because can be referenced
+ // only from epoll/kqueue internals.
+ mem := persistentalloc(n*pdSize, 0, &memstats.other_sys)
+ for i := uintptr(0); i < n; i++ {
+ pd := (*pollDesc)(add(mem, i*pdSize))
+ pd.link = c.first
+ c.first = pd
+ }
+ }
+ pd := c.first
+ c.first = pd.link
+ lockInit(&pd.lock, lockRankPollDesc)
+ unlock(&c.lock)
+ return pd
+}
+
+// makeArg converts pd to an interface{}.
+// makeArg does not do any allocation. Normally, such
+// a conversion requires an allocation because pointers to
+// types which embed runtime/internal/sys.NotInHeap (which pollDesc is)
+// must be stored in interfaces indirectly. See issue 42076.
+func (pd *pollDesc) makeArg() (i any) {
+ x := (*eface)(unsafe.Pointer(&i))
+ x._type = pdType
+ x.data = unsafe.Pointer(&pd.self)
+ return
+}
+
+var (
+ pdEface any = (*pollDesc)(nil)
+ pdType *_type = efaceOf(&pdEface)._type
+)
diff --git a/contrib/go/_std_1.21/src/runtime/netpoll_epoll.go b/contrib/go/_std_1.21/src/runtime/netpoll_epoll.go
new file mode 100644
index 0000000000..e29b64dc9c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/netpoll_epoll.go
@@ -0,0 +1,172 @@
+// Copyright 2013 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.
+
+//go:build linux
+
+package runtime
+
+import (
+ "runtime/internal/atomic"
+ "runtime/internal/syscall"
+ "unsafe"
+)
+
+var (
+ epfd int32 = -1 // epoll descriptor
+
+ netpollBreakRd, netpollBreakWr uintptr // for netpollBreak
+
+ netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
+)
+
+func netpollinit() {
+ var errno uintptr
+ epfd, errno = syscall.EpollCreate1(syscall.EPOLL_CLOEXEC)
+ if errno != 0 {
+ println("runtime: epollcreate failed with", errno)
+ throw("runtime: netpollinit failed")
+ }
+ r, w, errpipe := nonblockingPipe()
+ if errpipe != 0 {
+ println("runtime: pipe failed with", -errpipe)
+ throw("runtime: pipe failed")
+ }
+ ev := syscall.EpollEvent{
+ Events: syscall.EPOLLIN,
+ }
+ *(**uintptr)(unsafe.Pointer(&ev.Data)) = &netpollBreakRd
+ errno = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, r, &ev)
+ if errno != 0 {
+ println("runtime: epollctl failed with", errno)
+ throw("runtime: epollctl failed")
+ }
+ netpollBreakRd = uintptr(r)
+ netpollBreakWr = uintptr(w)
+}
+
+func netpollIsPollDescriptor(fd uintptr) bool {
+ return fd == uintptr(epfd) || fd == netpollBreakRd || fd == netpollBreakWr
+}
+
+func netpollopen(fd uintptr, pd *pollDesc) uintptr {
+ var ev syscall.EpollEvent
+ ev.Events = syscall.EPOLLIN | syscall.EPOLLOUT | syscall.EPOLLRDHUP | syscall.EPOLLET
+ tp := taggedPointerPack(unsafe.Pointer(pd), pd.fdseq.Load())
+ *(*taggedPointer)(unsafe.Pointer(&ev.Data)) = tp
+ return syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, int32(fd), &ev)
+}
+
+func netpollclose(fd uintptr) uintptr {
+ var ev syscall.EpollEvent
+ return syscall.EpollCtl(epfd, syscall.EPOLL_CTL_DEL, int32(fd), &ev)
+}
+
+func netpollarm(pd *pollDesc, mode int) {
+ throw("runtime: unused")
+}
+
+// netpollBreak interrupts an epollwait.
+func netpollBreak() {
+ // Failing to cas indicates there is an in-flight wakeup, so we're done here.
+ if !netpollWakeSig.CompareAndSwap(0, 1) {
+ return
+ }
+
+ for {
+ var b byte
+ n := write(netpollBreakWr, unsafe.Pointer(&b), 1)
+ if n == 1 {
+ break
+ }
+ if n == -_EINTR {
+ continue
+ }
+ if n == -_EAGAIN {
+ return
+ }
+ println("runtime: netpollBreak write failed with", -n)
+ throw("runtime: netpollBreak write failed")
+ }
+}
+
+// netpoll checks for ready network connections.
+// Returns list of goroutines that become runnable.
+// delay < 0: blocks indefinitely
+// delay == 0: does not block, just polls
+// delay > 0: block for up to that many nanoseconds
+func netpoll(delay int64) gList {
+ if epfd == -1 {
+ return gList{}
+ }
+ var waitms int32
+ if delay < 0 {
+ waitms = -1
+ } else if delay == 0 {
+ waitms = 0
+ } else if delay < 1e6 {
+ waitms = 1
+ } else if delay < 1e15 {
+ waitms = int32(delay / 1e6)
+ } else {
+ // An arbitrary cap on how long to wait for a timer.
+ // 1e9 ms == ~11.5 days.
+ waitms = 1e9
+ }
+ var events [128]syscall.EpollEvent
+retry:
+ n, errno := syscall.EpollWait(epfd, events[:], int32(len(events)), waitms)
+ if errno != 0 {
+ if errno != _EINTR {
+ println("runtime: epollwait on fd", epfd, "failed with", errno)
+ throw("runtime: netpoll failed")
+ }
+ // If a timed sleep was interrupted, just return to
+ // recalculate how long we should sleep now.
+ if waitms > 0 {
+ return gList{}
+ }
+ goto retry
+ }
+ var toRun gList
+ for i := int32(0); i < n; i++ {
+ ev := events[i]
+ if ev.Events == 0 {
+ continue
+ }
+
+ if *(**uintptr)(unsafe.Pointer(&ev.Data)) == &netpollBreakRd {
+ if ev.Events != syscall.EPOLLIN {
+ println("runtime: netpoll: break fd ready for", ev.Events)
+ throw("runtime: netpoll: break fd ready for something unexpected")
+ }
+ if delay != 0 {
+ // netpollBreak could be picked up by a
+ // nonblocking poll. Only read the byte
+ // if blocking.
+ var tmp [16]byte
+ read(int32(netpollBreakRd), noescape(unsafe.Pointer(&tmp[0])), int32(len(tmp)))
+ netpollWakeSig.Store(0)
+ }
+ continue
+ }
+
+ var mode int32
+ if ev.Events&(syscall.EPOLLIN|syscall.EPOLLRDHUP|syscall.EPOLLHUP|syscall.EPOLLERR) != 0 {
+ mode += 'r'
+ }
+ if ev.Events&(syscall.EPOLLOUT|syscall.EPOLLHUP|syscall.EPOLLERR) != 0 {
+ mode += 'w'
+ }
+ if mode != 0 {
+ tp := *(*taggedPointer)(unsafe.Pointer(&ev.Data))
+ pd := (*pollDesc)(tp.pointer())
+ tag := tp.tag()
+ if pd.fdseq.Load() == tag {
+ pd.setEventErr(ev.Events == syscall.EPOLLERR, tag)
+ netpollready(&toRun, pd, mode)
+ }
+ }
+ }
+ return toRun
+}
diff --git a/contrib/go/_std_1.21/src/runtime/netpoll_kqueue.go b/contrib/go/_std_1.21/src/runtime/netpoll_kqueue.go
new file mode 100644
index 0000000000..3af45e6892
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/netpoll_kqueue.go
@@ -0,0 +1,215 @@
+// Copyright 2013 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.
+
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
+
+package runtime
+
+// Integrated network poller (kqueue-based implementation).
+
+import (
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+var (
+ kq int32 = -1
+
+ netpollBreakRd, netpollBreakWr uintptr // for netpollBreak
+
+ netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
+)
+
+func netpollinit() {
+ kq = kqueue()
+ if kq < 0 {
+ println("runtime: kqueue failed with", -kq)
+ throw("runtime: netpollinit failed")
+ }
+ closeonexec(kq)
+ r, w, errno := nonblockingPipe()
+ if errno != 0 {
+ println("runtime: pipe failed with", -errno)
+ throw("runtime: pipe failed")
+ }
+ ev := keventt{
+ filter: _EVFILT_READ,
+ flags: _EV_ADD,
+ }
+ *(*uintptr)(unsafe.Pointer(&ev.ident)) = uintptr(r)
+ n := kevent(kq, &ev, 1, nil, 0, nil)
+ if n < 0 {
+ println("runtime: kevent failed with", -n)
+ throw("runtime: kevent failed")
+ }
+ netpollBreakRd = uintptr(r)
+ netpollBreakWr = uintptr(w)
+}
+
+func netpollIsPollDescriptor(fd uintptr) bool {
+ return fd == uintptr(kq) || fd == netpollBreakRd || fd == netpollBreakWr
+}
+
+func netpollopen(fd uintptr, pd *pollDesc) int32 {
+ // Arm both EVFILT_READ and EVFILT_WRITE in edge-triggered mode (EV_CLEAR)
+ // for the whole fd lifetime. The notifications are automatically unregistered
+ // when fd is closed.
+ var ev [2]keventt
+ *(*uintptr)(unsafe.Pointer(&ev[0].ident)) = fd
+ ev[0].filter = _EVFILT_READ
+ ev[0].flags = _EV_ADD | _EV_CLEAR
+ ev[0].fflags = 0
+ ev[0].data = 0
+
+ if goarch.PtrSize == 4 {
+ // We only have a pointer-sized field to store into,
+ // so on a 32-bit system we get no sequence protection.
+ // TODO(iant): If we notice any problems we could at least
+ // steal the low-order 2 bits for a tiny sequence number.
+ ev[0].udata = (*byte)(unsafe.Pointer(pd))
+ } else {
+ tp := taggedPointerPack(unsafe.Pointer(pd), pd.fdseq.Load())
+ ev[0].udata = (*byte)(unsafe.Pointer(uintptr(tp)))
+ }
+ ev[1] = ev[0]
+ ev[1].filter = _EVFILT_WRITE
+ n := kevent(kq, &ev[0], 2, nil, 0, nil)
+ if n < 0 {
+ return -n
+ }
+ return 0
+}
+
+func netpollclose(fd uintptr) int32 {
+ // Don't need to unregister because calling close()
+ // on fd will remove any kevents that reference the descriptor.
+ return 0
+}
+
+func netpollarm(pd *pollDesc, mode int) {
+ throw("runtime: unused")
+}
+
+// netpollBreak interrupts a kevent.
+func netpollBreak() {
+ // Failing to cas indicates there is an in-flight wakeup, so we're done here.
+ if !netpollWakeSig.CompareAndSwap(0, 1) {
+ return
+ }
+
+ for {
+ var b byte
+ n := write(netpollBreakWr, unsafe.Pointer(&b), 1)
+ if n == 1 || n == -_EAGAIN {
+ break
+ }
+ if n == -_EINTR {
+ continue
+ }
+ println("runtime: netpollBreak write failed with", -n)
+ throw("runtime: netpollBreak write failed")
+ }
+}
+
+// netpoll checks for ready network connections.
+// Returns list of goroutines that become runnable.
+// delay < 0: blocks indefinitely
+// delay == 0: does not block, just polls
+// delay > 0: block for up to that many nanoseconds
+func netpoll(delay int64) gList {
+ if kq == -1 {
+ return gList{}
+ }
+ var tp *timespec
+ var ts timespec
+ if delay < 0 {
+ tp = nil
+ } else if delay == 0 {
+ tp = &ts
+ } else {
+ ts.setNsec(delay)
+ if ts.tv_sec > 1e6 {
+ // Darwin returns EINVAL if the sleep time is too long.
+ ts.tv_sec = 1e6
+ }
+ tp = &ts
+ }
+ var events [64]keventt
+retry:
+ n := kevent(kq, nil, 0, &events[0], int32(len(events)), tp)
+ if n < 0 {
+ if n != -_EINTR {
+ println("runtime: kevent on fd", kq, "failed with", -n)
+ throw("runtime: netpoll failed")
+ }
+ // If a timed sleep was interrupted, just return to
+ // recalculate how long we should sleep now.
+ if delay > 0 {
+ return gList{}
+ }
+ goto retry
+ }
+ var toRun gList
+ for i := 0; i < int(n); i++ {
+ ev := &events[i]
+
+ if uintptr(ev.ident) == netpollBreakRd {
+ if ev.filter != _EVFILT_READ {
+ println("runtime: netpoll: break fd ready for", ev.filter)
+ throw("runtime: netpoll: break fd ready for something unexpected")
+ }
+ if delay != 0 {
+ // netpollBreak could be picked up by a
+ // nonblocking poll. Only read the byte
+ // if blocking.
+ var tmp [16]byte
+ read(int32(netpollBreakRd), noescape(unsafe.Pointer(&tmp[0])), int32(len(tmp)))
+ netpollWakeSig.Store(0)
+ }
+ continue
+ }
+
+ var mode int32
+ switch ev.filter {
+ case _EVFILT_READ:
+ mode += 'r'
+
+ // On some systems when the read end of a pipe
+ // is closed the write end will not get a
+ // _EVFILT_WRITE event, but will get a
+ // _EVFILT_READ event with EV_EOF set.
+ // Note that setting 'w' here just means that we
+ // will wake up a goroutine waiting to write;
+ // that goroutine will try the write again,
+ // and the appropriate thing will happen based
+ // on what that write returns (success, EPIPE, EAGAIN).
+ if ev.flags&_EV_EOF != 0 {
+ mode += 'w'
+ }
+ case _EVFILT_WRITE:
+ mode += 'w'
+ }
+ if mode != 0 {
+ var pd *pollDesc
+ var tag uintptr
+ if goarch.PtrSize == 4 {
+ // No sequence protection on 32-bit systems.
+ // See netpollopen for details.
+ pd = (*pollDesc)(unsafe.Pointer(ev.udata))
+ tag = 0
+ } else {
+ tp := taggedPointer(uintptr(unsafe.Pointer(ev.udata)))
+ pd = (*pollDesc)(tp.pointer())
+ tag = tp.tag()
+ if pd.fdseq.Load() != tag {
+ continue
+ }
+ }
+ pd.setEventErr(ev.flags == _EV_ERROR, tag)
+ netpollready(&toRun, pd, mode)
+ }
+ }
+ return toRun
+}
diff --git a/contrib/go/_std_1.21/src/runtime/netpoll_windows.go b/contrib/go/_std_1.21/src/runtime/netpoll_windows.go
new file mode 100644
index 0000000000..bb77d8d045
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/netpoll_windows.go
@@ -0,0 +1,160 @@
+// Copyright 2013 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 runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+const _DWORD_MAX = 0xffffffff
+
+const _INVALID_HANDLE_VALUE = ^uintptr(0)
+
+// net_op must be the same as beginning of internal/poll.operation.
+// Keep these in sync.
+type net_op struct {
+ // used by windows
+ o overlapped
+ // used by netpoll
+ pd *pollDesc
+ mode int32
+ errno int32
+ qty uint32
+}
+
+type overlappedEntry struct {
+ key *pollDesc
+ op *net_op // In reality it's *overlapped, but we cast it to *net_op anyway.
+ internal uintptr
+ qty uint32
+}
+
+var (
+ iocphandle uintptr = _INVALID_HANDLE_VALUE // completion port io handle
+
+ netpollWakeSig atomic.Uint32 // used to avoid duplicate calls of netpollBreak
+)
+
+func netpollinit() {
+ iocphandle = stdcall4(_CreateIoCompletionPort, _INVALID_HANDLE_VALUE, 0, 0, _DWORD_MAX)
+ if iocphandle == 0 {
+ println("runtime: CreateIoCompletionPort failed (errno=", getlasterror(), ")")
+ throw("runtime: netpollinit failed")
+ }
+}
+
+func netpollIsPollDescriptor(fd uintptr) bool {
+ return fd == iocphandle
+}
+
+func netpollopen(fd uintptr, pd *pollDesc) int32 {
+ // TODO(iant): Consider using taggedPointer on 64-bit systems.
+ if stdcall4(_CreateIoCompletionPort, fd, iocphandle, uintptr(unsafe.Pointer(pd)), 0) == 0 {
+ return int32(getlasterror())
+ }
+ return 0
+}
+
+func netpollclose(fd uintptr) int32 {
+ // nothing to do
+ return 0
+}
+
+func netpollarm(pd *pollDesc, mode int) {
+ throw("runtime: unused")
+}
+
+func netpollBreak() {
+ // Failing to cas indicates there is an in-flight wakeup, so we're done here.
+ if !netpollWakeSig.CompareAndSwap(0, 1) {
+ return
+ }
+
+ if stdcall4(_PostQueuedCompletionStatus, iocphandle, 0, 0, 0) == 0 {
+ println("runtime: netpoll: PostQueuedCompletionStatus failed (errno=", getlasterror(), ")")
+ throw("runtime: netpoll: PostQueuedCompletionStatus failed")
+ }
+}
+
+// netpoll checks for ready network connections.
+// Returns list of goroutines that become runnable.
+// delay < 0: blocks indefinitely
+// delay == 0: does not block, just polls
+// delay > 0: block for up to that many nanoseconds
+func netpoll(delay int64) gList {
+ var entries [64]overlappedEntry
+ var wait, qty, flags, n, i uint32
+ var errno int32
+ var op *net_op
+ var toRun gList
+
+ mp := getg().m
+
+ if iocphandle == _INVALID_HANDLE_VALUE {
+ return gList{}
+ }
+ if delay < 0 {
+ wait = _INFINITE
+ } else if delay == 0 {
+ wait = 0
+ } else if delay < 1e6 {
+ wait = 1
+ } else if delay < 1e15 {
+ wait = uint32(delay / 1e6)
+ } else {
+ // An arbitrary cap on how long to wait for a timer.
+ // 1e9 ms == ~11.5 days.
+ wait = 1e9
+ }
+
+ n = uint32(len(entries) / int(gomaxprocs))
+ if n < 8 {
+ n = 8
+ }
+ if delay != 0 {
+ mp.blocked = true
+ }
+ if stdcall6(_GetQueuedCompletionStatusEx, iocphandle, uintptr(unsafe.Pointer(&entries[0])), uintptr(n), uintptr(unsafe.Pointer(&n)), uintptr(wait), 0) == 0 {
+ mp.blocked = false
+ errno = int32(getlasterror())
+ if errno == _WAIT_TIMEOUT {
+ return gList{}
+ }
+ println("runtime: GetQueuedCompletionStatusEx failed (errno=", errno, ")")
+ throw("runtime: netpoll failed")
+ }
+ mp.blocked = false
+ for i = 0; i < n; i++ {
+ op = entries[i].op
+ if op != nil && op.pd == entries[i].key {
+ errno = 0
+ qty = 0
+ if stdcall5(_WSAGetOverlappedResult, op.pd.fd, uintptr(unsafe.Pointer(op)), uintptr(unsafe.Pointer(&qty)), 0, uintptr(unsafe.Pointer(&flags))) == 0 {
+ errno = int32(getlasterror())
+ }
+ handlecompletion(&toRun, op, errno, qty)
+ } else {
+ netpollWakeSig.Store(0)
+ if delay == 0 {
+ // Forward the notification to the
+ // blocked poller.
+ netpollBreak()
+ }
+ }
+ }
+ return toRun
+}
+
+func handlecompletion(toRun *gList, op *net_op, errno int32, qty uint32) {
+ mode := op.mode
+ if mode != 'r' && mode != 'w' {
+ println("runtime: GetQueuedCompletionStatusEx returned invalid mode=", mode)
+ throw("runtime: netpoll failed")
+ }
+ op.errno = errno
+ op.qty = qty
+ netpollready(toRun, op.pd, mode)
+}
diff --git a/contrib/go/_std_1.21/src/runtime/nonwindows_stub.go b/contrib/go/_std_1.21/src/runtime/nonwindows_stub.go
new file mode 100644
index 0000000000..033f026c42
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/nonwindows_stub.go
@@ -0,0 +1,21 @@
+// Copyright 2017 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.
+
+//go:build !windows
+
+package runtime
+
+// osRelaxMinNS is the number of nanoseconds of idleness to tolerate
+// without performing an osRelax. Since osRelax may reduce the
+// precision of timers, this should be enough larger than the relaxed
+// timer precision to keep the timer error acceptable.
+const osRelaxMinNS = 0
+
+// osRelax is called by the scheduler when transitioning to and from
+// all Ps being idle.
+func osRelax(relax bool) {}
+
+// enableWER is called by setTraceback("wer").
+// Windows Error Reporting (WER) is only supported on Windows.
+func enableWER() {}
diff --git a/contrib/go/_std_1.21/src/runtime/os_darwin.go b/contrib/go/_std_1.21/src/runtime/os_darwin.go
new file mode 100644
index 0000000000..105de47a1f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/os_darwin.go
@@ -0,0 +1,476 @@
+// Copyright 2009 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 runtime
+
+import (
+ "internal/abi"
+ "unsafe"
+)
+
+type mOS struct {
+ initialized bool
+ mutex pthreadmutex
+ cond pthreadcond
+ count int
+}
+
+func unimplemented(name string) {
+ println(name, "not implemented")
+ *(*int)(unsafe.Pointer(uintptr(1231))) = 1231
+}
+
+//go:nosplit
+func semacreate(mp *m) {
+ if mp.initialized {
+ return
+ }
+ mp.initialized = true
+ if err := pthread_mutex_init(&mp.mutex, nil); err != 0 {
+ throw("pthread_mutex_init")
+ }
+ if err := pthread_cond_init(&mp.cond, nil); err != 0 {
+ throw("pthread_cond_init")
+ }
+}
+
+//go:nosplit
+func semasleep(ns int64) int32 {
+ var start int64
+ if ns >= 0 {
+ start = nanotime()
+ }
+ mp := getg().m
+ pthread_mutex_lock(&mp.mutex)
+ for {
+ if mp.count > 0 {
+ mp.count--
+ pthread_mutex_unlock(&mp.mutex)
+ return 0
+ }
+ if ns >= 0 {
+ spent := nanotime() - start
+ if spent >= ns {
+ pthread_mutex_unlock(&mp.mutex)
+ return -1
+ }
+ var t timespec
+ t.setNsec(ns - spent)
+ err := pthread_cond_timedwait_relative_np(&mp.cond, &mp.mutex, &t)
+ if err == _ETIMEDOUT {
+ pthread_mutex_unlock(&mp.mutex)
+ return -1
+ }
+ } else {
+ pthread_cond_wait(&mp.cond, &mp.mutex)
+ }
+ }
+}
+
+//go:nosplit
+func semawakeup(mp *m) {
+ pthread_mutex_lock(&mp.mutex)
+ mp.count++
+ if mp.count > 0 {
+ pthread_cond_signal(&mp.cond)
+ }
+ pthread_mutex_unlock(&mp.mutex)
+}
+
+// The read and write file descriptors used by the sigNote functions.
+var sigNoteRead, sigNoteWrite int32
+
+// sigNoteSetup initializes a single, there-can-only-be-one, async-signal-safe note.
+//
+// The current implementation of notes on Darwin is not async-signal-safe,
+// because the functions pthread_mutex_lock, pthread_cond_signal, and
+// pthread_mutex_unlock, called by semawakeup, are not async-signal-safe.
+// There is only one case where we need to wake up a note from a signal
+// handler: the sigsend function. The signal handler code does not require
+// all the features of notes: it does not need to do a timed wait.
+// This is a separate implementation of notes, based on a pipe, that does
+// not support timed waits but is async-signal-safe.
+func sigNoteSetup(*note) {
+ if sigNoteRead != 0 || sigNoteWrite != 0 {
+ // Generalizing this would require avoiding the pipe-fork-closeonexec race, which entangles syscall.
+ throw("duplicate sigNoteSetup")
+ }
+ var errno int32
+ sigNoteRead, sigNoteWrite, errno = pipe()
+ if errno != 0 {
+ throw("pipe failed")
+ }
+ closeonexec(sigNoteRead)
+ closeonexec(sigNoteWrite)
+
+ // Make the write end of the pipe non-blocking, so that if the pipe
+ // buffer is somehow full we will not block in the signal handler.
+ // Leave the read end of the pipe blocking so that we will block
+ // in sigNoteSleep.
+ setNonblock(sigNoteWrite)
+}
+
+// sigNoteWakeup wakes up a thread sleeping on a note created by sigNoteSetup.
+func sigNoteWakeup(*note) {
+ var b byte
+ write(uintptr(sigNoteWrite), unsafe.Pointer(&b), 1)
+}
+
+// sigNoteSleep waits for a note created by sigNoteSetup to be woken.
+func sigNoteSleep(*note) {
+ for {
+ var b byte
+ entersyscallblock()
+ n := read(sigNoteRead, unsafe.Pointer(&b), 1)
+ exitsyscall()
+ if n != -_EINTR {
+ return
+ }
+ }
+}
+
+// BSD interface for threading.
+func osinit() {
+ // pthread_create delayed until end of goenvs so that we
+ // can look at the environment first.
+
+ ncpu = getncpu()
+ physPageSize = getPageSize()
+
+ osinit_hack()
+}
+
+func sysctlbynameInt32(name []byte) (int32, int32) {
+ out := int32(0)
+ nout := unsafe.Sizeof(out)
+ ret := sysctlbyname(&name[0], (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+ return ret, out
+}
+
+//go:linkname internal_cpu_getsysctlbyname internal/cpu.getsysctlbyname
+func internal_cpu_getsysctlbyname(name []byte) (int32, int32) {
+ return sysctlbynameInt32(name)
+}
+
+const (
+ _CTL_HW = 6
+ _HW_NCPU = 3
+ _HW_PAGESIZE = 7
+)
+
+func getncpu() int32 {
+ // Use sysctl to fetch hw.ncpu.
+ mib := [2]uint32{_CTL_HW, _HW_NCPU}
+ out := uint32(0)
+ nout := unsafe.Sizeof(out)
+ ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+ if ret >= 0 && int32(out) > 0 {
+ return int32(out)
+ }
+ return 1
+}
+
+func getPageSize() uintptr {
+ // Use sysctl to fetch hw.pagesize.
+ mib := [2]uint32{_CTL_HW, _HW_PAGESIZE}
+ out := uint32(0)
+ nout := unsafe.Sizeof(out)
+ ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+ if ret >= 0 && int32(out) > 0 {
+ return uintptr(out)
+ }
+ return 0
+}
+
+var urandom_dev = []byte("/dev/urandom\x00")
+
+//go:nosplit
+func getRandomData(r []byte) {
+ fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
+ n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
+ closefd(fd)
+ extendRandom(r, int(n))
+}
+
+func goenvs() {
+ goenvs_unix()
+}
+
+// May run with m.p==nil, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func newosproc(mp *m) {
+ stk := unsafe.Pointer(mp.g0.stack.hi)
+ if false {
+ print("newosproc stk=", stk, " m=", mp, " g=", mp.g0, " id=", mp.id, " ostk=", &mp, "\n")
+ }
+
+ // Initialize an attribute object.
+ var attr pthreadattr
+ var err int32
+ err = pthread_attr_init(&attr)
+ if err != 0 {
+ writeErrStr(failthreadcreate)
+ exit(1)
+ }
+
+ // Find out OS stack size for our own stack guard.
+ var stacksize uintptr
+ if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
+ writeErrStr(failthreadcreate)
+ exit(1)
+ }
+ mp.g0.stack.hi = stacksize // for mstart
+
+ // Tell the pthread library we won't join with this thread.
+ if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
+ writeErrStr(failthreadcreate)
+ exit(1)
+ }
+
+ // Finally, create the thread. It starts at mstart_stub, which does some low-level
+ // setup and then calls mstart.
+ var oset sigset
+ sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
+ err = retryOnEAGAIN(func() int32 {
+ return pthread_create(&attr, abi.FuncPCABI0(mstart_stub), unsafe.Pointer(mp))
+ })
+ sigprocmask(_SIG_SETMASK, &oset, nil)
+ if err != 0 {
+ writeErrStr(failthreadcreate)
+ exit(1)
+ }
+}
+
+// glue code to call mstart from pthread_create.
+func mstart_stub()
+
+// newosproc0 is a version of newosproc that can be called before the runtime
+// is initialized.
+//
+// This function is not safe to use after initialization as it does not pass an M as fnarg.
+//
+//go:nosplit
+func newosproc0(stacksize uintptr, fn uintptr) {
+ // Initialize an attribute object.
+ var attr pthreadattr
+ var err int32
+ err = pthread_attr_init(&attr)
+ if err != 0 {
+ writeErrStr(failthreadcreate)
+ exit(1)
+ }
+
+ // The caller passes in a suggested stack size,
+ // from when we allocated the stack and thread ourselves,
+ // without libpthread. Now that we're using libpthread,
+ // we use the OS default stack size instead of the suggestion.
+ // Find out that stack size for our own stack guard.
+ if pthread_attr_getstacksize(&attr, &stacksize) != 0 {
+ writeErrStr(failthreadcreate)
+ exit(1)
+ }
+ g0.stack.hi = stacksize // for mstart
+ memstats.stacks_sys.add(int64(stacksize))
+
+ // Tell the pthread library we won't join with this thread.
+ if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
+ writeErrStr(failthreadcreate)
+ exit(1)
+ }
+
+ // Finally, create the thread. It starts at mstart_stub, which does some low-level
+ // setup and then calls mstart.
+ var oset sigset
+ sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
+ err = pthread_create(&attr, fn, nil)
+ sigprocmask(_SIG_SETMASK, &oset, nil)
+ if err != 0 {
+ writeErrStr(failthreadcreate)
+ exit(1)
+ }
+}
+
+// Called to do synchronous initialization of Go code built with
+// -buildmode=c-archive or -buildmode=c-shared.
+// None of the Go runtime is initialized.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func libpreinit() {
+ initsig(true)
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+func mpreinit(mp *m) {
+ mp.gsignal = malg(32 * 1024) // OS X wants >= 8K
+ mp.gsignal.m = mp
+ if GOOS == "darwin" && GOARCH == "arm64" {
+ // mlock the signal stack to work around a kernel bug where it may
+ // SIGILL when the signal stack is not faulted in while a signal
+ // arrives. See issue 42774.
+ mlock(unsafe.Pointer(mp.gsignal.stack.hi-physPageSize), physPageSize)
+ }
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, cannot allocate memory.
+func minit() {
+ // iOS does not support alternate signal stack.
+ // The signal handler handles it directly.
+ if !(GOOS == "ios" && GOARCH == "arm64") {
+ minitSignalStack()
+ }
+ minitSignalMask()
+ getg().m.procid = uint64(pthread_self())
+}
+
+// Called from dropm to undo the effect of an minit.
+//
+//go:nosplit
+func unminit() {
+ // iOS does not support alternate signal stack.
+ // See minit.
+ if !(GOOS == "ios" && GOARCH == "arm64") {
+ unminitSignals()
+ }
+}
+
+// Called from exitm, but not from drop, to undo the effect of thread-owned
+// resources in minit, semacreate, or elsewhere. Do not take locks after calling this.
+func mdestroy(mp *m) {
+}
+
+//go:nosplit
+func osyield_no_g() {
+ usleep_no_g(1)
+}
+
+//go:nosplit
+func osyield() {
+ usleep(1)
+}
+
+const (
+ _NSIG = 32
+ _SI_USER = 0 /* empirically true, but not what headers say */
+ _SIG_BLOCK = 1
+ _SIG_UNBLOCK = 2
+ _SIG_SETMASK = 3
+ _SS_DISABLE = 4
+)
+
+//extern SigTabTT runtime·sigtab[];
+
+type sigset uint32
+
+var sigset_all = ^sigset(0)
+
+//go:nosplit
+//go:nowritebarrierrec
+func setsig(i uint32, fn uintptr) {
+ var sa usigactiont
+ sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
+ sa.sa_mask = ^uint32(0)
+ if fn == abi.FuncPCABIInternal(sighandler) { // abi.FuncPCABIInternal(sighandler) matches the callers in signal_unix.go
+ if iscgo {
+ fn = abi.FuncPCABI0(cgoSigtramp)
+ } else {
+ fn = abi.FuncPCABI0(sigtramp)
+ }
+ }
+ *(*uintptr)(unsafe.Pointer(&sa.__sigaction_u)) = fn
+ sigaction(i, &sa, nil)
+}
+
+// sigtramp is the callback from libc when a signal is received.
+// It is called with the C calling convention.
+func sigtramp()
+func cgoSigtramp()
+
+//go:nosplit
+//go:nowritebarrierrec
+func setsigstack(i uint32) {
+ var osa usigactiont
+ sigaction(i, nil, &osa)
+ handler := *(*uintptr)(unsafe.Pointer(&osa.__sigaction_u))
+ if osa.sa_flags&_SA_ONSTACK != 0 {
+ return
+ }
+ var sa usigactiont
+ *(*uintptr)(unsafe.Pointer(&sa.__sigaction_u)) = handler
+ sa.sa_mask = osa.sa_mask
+ sa.sa_flags = osa.sa_flags | _SA_ONSTACK
+ sigaction(i, &sa, nil)
+}
+
+//go:nosplit
+//go:nowritebarrierrec
+func getsig(i uint32) uintptr {
+ var sa usigactiont
+ sigaction(i, nil, &sa)
+ return *(*uintptr)(unsafe.Pointer(&sa.__sigaction_u))
+}
+
+// setSignalstackSP sets the ss_sp field of a stackt.
+//
+//go:nosplit
+func setSignalstackSP(s *stackt, sp uintptr) {
+ *(*uintptr)(unsafe.Pointer(&s.ss_sp)) = sp
+}
+
+//go:nosplit
+//go:nowritebarrierrec
+func sigaddset(mask *sigset, i int) {
+ *mask |= 1 << (uint32(i) - 1)
+}
+
+func sigdelset(mask *sigset, i int) {
+ *mask &^= 1 << (uint32(i) - 1)
+}
+
+func setProcessCPUProfiler(hz int32) {
+ setProcessCPUProfilerTimer(hz)
+}
+
+func setThreadCPUProfiler(hz int32) {
+ setThreadCPUProfilerHz(hz)
+}
+
+//go:nosplit
+func validSIGPROF(mp *m, c *sigctxt) bool {
+ return true
+}
+
+//go:linkname executablePath os.executablePath
+var executablePath string
+
+func sysargs(argc int32, argv **byte) {
+ // skip over argv, envv and the first string will be the path
+ n := argc + 1
+ for argv_index(argv, n) != nil {
+ n++
+ }
+ executablePath = gostringnocopy(argv_index(argv, n+1))
+
+ // strip "executable_path=" prefix if available, it's added after OS X 10.11.
+ const prefix = "executable_path="
+ if len(executablePath) > len(prefix) && executablePath[:len(prefix)] == prefix {
+ executablePath = executablePath[len(prefix):]
+ }
+}
+
+func signalM(mp *m, sig int) {
+ pthread_kill(pthread(mp.procid), uint32(sig))
+}
+
+// sigPerThreadSyscall is only used on linux, so we assign a bogus signal
+// number.
+const sigPerThreadSyscall = 1 << 31
+
+//go:nosplit
+func runPerThreadSyscall() {
+ throw("runPerThreadSyscall only valid on linux")
+}
diff --git a/contrib/go/_std_1.21/src/runtime/os_linux.go b/contrib/go/_std_1.21/src/runtime/os_linux.go
new file mode 100644
index 0000000000..0b0561039f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/os_linux.go
@@ -0,0 +1,918 @@
+// Copyright 2009 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "runtime/internal/syscall"
+ "unsafe"
+)
+
+// sigPerThreadSyscall is the same signal (SIGSETXID) used by glibc for
+// per-thread syscalls on Linux. We use it for the same purpose in non-cgo
+// binaries.
+const sigPerThreadSyscall = _SIGRTMIN + 1
+
+type mOS struct {
+ // profileTimer holds the ID of the POSIX interval timer for profiling CPU
+ // usage on this thread.
+ //
+ // It is valid when the profileTimerValid field is true. A thread
+ // creates and manages its own timer, and these fields are read and written
+ // only by this thread. But because some of the reads on profileTimerValid
+ // are in signal handling code, this field should be atomic type.
+ profileTimer int32
+ profileTimerValid atomic.Bool
+
+ // needPerThreadSyscall indicates that a per-thread syscall is required
+ // for doAllThreadsSyscall.
+ needPerThreadSyscall atomic.Uint8
+}
+
+//go:noescape
+func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer, val3 uint32) int32
+
+// Linux futex.
+//
+// futexsleep(uint32 *addr, uint32 val)
+// futexwakeup(uint32 *addr)
+//
+// Futexsleep atomically checks if *addr == val and if so, sleeps on addr.
+// Futexwakeup wakes up threads sleeping on addr.
+// Futexsleep is allowed to wake up spuriously.
+
+const (
+ _FUTEX_PRIVATE_FLAG = 128
+ _FUTEX_WAIT_PRIVATE = 0 | _FUTEX_PRIVATE_FLAG
+ _FUTEX_WAKE_PRIVATE = 1 | _FUTEX_PRIVATE_FLAG
+)
+
+// Atomically,
+//
+// if(*addr == val) sleep
+//
+// Might be woken up spuriously; that's allowed.
+// Don't sleep longer than ns; ns < 0 means forever.
+//
+//go:nosplit
+func futexsleep(addr *uint32, val uint32, ns int64) {
+ // Some Linux kernels have a bug where futex of
+ // FUTEX_WAIT returns an internal error code
+ // as an errno. Libpthread ignores the return value
+ // here, and so can we: as it says a few lines up,
+ // spurious wakeups are allowed.
+ if ns < 0 {
+ futex(unsafe.Pointer(addr), _FUTEX_WAIT_PRIVATE, val, nil, nil, 0)
+ return
+ }
+
+ var ts timespec
+ ts.setNsec(ns)
+ futex(unsafe.Pointer(addr), _FUTEX_WAIT_PRIVATE, val, unsafe.Pointer(&ts), nil, 0)
+}
+
+// If any procs are sleeping on addr, wake up at most cnt.
+//
+//go:nosplit
+func futexwakeup(addr *uint32, cnt uint32) {
+ ret := futex(unsafe.Pointer(addr), _FUTEX_WAKE_PRIVATE, cnt, nil, nil, 0)
+ if ret >= 0 {
+ return
+ }
+
+ // I don't know that futex wakeup can return
+ // EAGAIN or EINTR, but if it does, it would be
+ // safe to loop and call futex again.
+ systemstack(func() {
+ print("futexwakeup addr=", addr, " returned ", ret, "\n")
+ })
+
+ *(*int32)(unsafe.Pointer(uintptr(0x1006))) = 0x1006
+}
+
+func getproccount() int32 {
+ // This buffer is huge (8 kB) but we are on the system stack
+ // and there should be plenty of space (64 kB).
+ // Also this is a leaf, so we're not holding up the memory for long.
+ // See golang.org/issue/11823.
+ // The suggested behavior here is to keep trying with ever-larger
+ // buffers, but we don't have a dynamic memory allocator at the
+ // moment, so that's a bit tricky and seems like overkill.
+ const maxCPUs = 64 * 1024
+ var buf [maxCPUs / 8]byte
+ r := sched_getaffinity(0, unsafe.Sizeof(buf), &buf[0])
+ if r < 0 {
+ return 1
+ }
+ n := int32(0)
+ for _, v := range buf[:r] {
+ for v != 0 {
+ n += int32(v & 1)
+ v >>= 1
+ }
+ }
+ if n == 0 {
+ n = 1
+ }
+ return n
+}
+
+// Clone, the Linux rfork.
+const (
+ _CLONE_VM = 0x100
+ _CLONE_FS = 0x200
+ _CLONE_FILES = 0x400
+ _CLONE_SIGHAND = 0x800
+ _CLONE_PTRACE = 0x2000
+ _CLONE_VFORK = 0x4000
+ _CLONE_PARENT = 0x8000
+ _CLONE_THREAD = 0x10000
+ _CLONE_NEWNS = 0x20000
+ _CLONE_SYSVSEM = 0x40000
+ _CLONE_SETTLS = 0x80000
+ _CLONE_PARENT_SETTID = 0x100000
+ _CLONE_CHILD_CLEARTID = 0x200000
+ _CLONE_UNTRACED = 0x800000
+ _CLONE_CHILD_SETTID = 0x1000000
+ _CLONE_STOPPED = 0x2000000
+ _CLONE_NEWUTS = 0x4000000
+ _CLONE_NEWIPC = 0x8000000
+
+ // As of QEMU 2.8.0 (5ea2fc84d), user emulation requires all six of these
+ // flags to be set when creating a thread; attempts to share the other
+ // five but leave SYSVSEM unshared will fail with -EINVAL.
+ //
+ // In non-QEMU environments CLONE_SYSVSEM is inconsequential as we do not
+ // use System V semaphores.
+
+ cloneFlags = _CLONE_VM | /* share memory */
+ _CLONE_FS | /* share cwd, etc */
+ _CLONE_FILES | /* share fd table */
+ _CLONE_SIGHAND | /* share sig handler table */
+ _CLONE_SYSVSEM | /* share SysV semaphore undo lists (see issue #20763) */
+ _CLONE_THREAD /* revisit - okay for now */
+)
+
+//go:noescape
+func clone(flags int32, stk, mp, gp, fn unsafe.Pointer) int32
+
+// May run with m.p==nil, so write barriers are not allowed.
+//
+//go:nowritebarrier
+func newosproc(mp *m) {
+ stk := unsafe.Pointer(mp.g0.stack.hi)
+ /*
+ * note: strace gets confused if we use CLONE_PTRACE here.
+ */
+ if false {
+ print("newosproc stk=", stk, " m=", mp, " g=", mp.g0, " clone=", abi.FuncPCABI0(clone), " id=", mp.id, " ostk=", &mp, "\n")
+ }
+
+ // Disable signals during clone, so that the new thread starts
+ // with signals disabled. It will enable them in minit.
+ var oset sigset
+ sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
+ ret := retryOnEAGAIN(func() int32 {
+ r := clone(cloneFlags, stk, unsafe.Pointer(mp), unsafe.Pointer(mp.g0), unsafe.Pointer(abi.FuncPCABI0(mstart)))
+ // clone returns positive TID, negative errno.
+ // We don't care about the TID.
+ if r >= 0 {
+ return 0
+ }
+ return -r
+ })
+ sigprocmask(_SIG_SETMASK, &oset, nil)
+
+ if ret != 0 {
+ print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
+ if ret == _EAGAIN {
+ println("runtime: may need to increase max user processes (ulimit -u)")
+ }
+ throw("newosproc")
+ }
+}
+
+// Version of newosproc that doesn't require a valid G.
+//
+//go:nosplit
+func newosproc0(stacksize uintptr, fn unsafe.Pointer) {
+ stack := sysAlloc(stacksize, &memstats.stacks_sys)
+ if stack == nil {
+ writeErrStr(failallocatestack)
+ exit(1)
+ }
+ ret := clone(cloneFlags, unsafe.Pointer(uintptr(stack)+stacksize), nil, nil, fn)
+ if ret < 0 {
+ writeErrStr(failthreadcreate)
+ exit(1)
+ }
+}
+
+const (
+ _AT_NULL = 0 // End of vector
+ _AT_PAGESZ = 6 // System physical page size
+ _AT_HWCAP = 16 // hardware capability bit vector
+ _AT_SECURE = 23 // secure mode boolean
+ _AT_RANDOM = 25 // introduced in 2.6.29
+ _AT_HWCAP2 = 26 // hardware capability bit vector 2
+)
+
+var procAuxv = []byte("/proc/self/auxv\x00")
+
+var addrspace_vec [1]byte
+
+func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
+
+var auxvreadbuf [128]uintptr
+
+func sysargs(argc int32, argv **byte) {
+ n := argc + 1
+
+ // skip over argv, envp to get to auxv
+ for argv_index(argv, n) != nil {
+ n++
+ }
+
+ // skip NULL separator
+ n++
+
+ // now argv+n is auxv
+ auxvp := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*goarch.PtrSize))
+
+ if pairs := sysauxv(auxvp[:]); pairs != 0 {
+ auxv = auxvp[: pairs*2 : pairs*2]
+ return
+ }
+ // In some situations we don't get a loader-provided
+ // auxv, such as when loaded as a library on Android.
+ // Fall back to /proc/self/auxv.
+ fd := open(&procAuxv[0], 0 /* O_RDONLY */, 0)
+ if fd < 0 {
+ // On Android, /proc/self/auxv might be unreadable (issue 9229), so we fallback to
+ // try using mincore to detect the physical page size.
+ // mincore should return EINVAL when address is not a multiple of system page size.
+ const size = 256 << 10 // size of memory region to allocate
+ p, err := mmap(nil, size, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
+ if err != 0 {
+ return
+ }
+ var n uintptr
+ for n = 4 << 10; n < size; n <<= 1 {
+ err := mincore(unsafe.Pointer(uintptr(p)+n), 1, &addrspace_vec[0])
+ if err == 0 {
+ physPageSize = n
+ break
+ }
+ }
+ if physPageSize == 0 {
+ physPageSize = size
+ }
+ munmap(p, size)
+ return
+ }
+
+ n = read(fd, noescape(unsafe.Pointer(&auxvreadbuf[0])), int32(unsafe.Sizeof(auxvreadbuf)))
+ closefd(fd)
+ if n < 0 {
+ return
+ }
+ // Make sure buf is terminated, even if we didn't read
+ // the whole file.
+ auxvreadbuf[len(auxvreadbuf)-2] = _AT_NULL
+ pairs := sysauxv(auxvreadbuf[:])
+ auxv = auxvreadbuf[: pairs*2 : pairs*2]
+}
+
+// startupRandomData holds random bytes initialized at startup. These come from
+// the ELF AT_RANDOM auxiliary vector.
+var startupRandomData []byte
+
+// secureMode holds the value of AT_SECURE passed in the auxiliary vector.
+var secureMode bool
+
+func sysauxv(auxv []uintptr) (pairs int) {
+ var i int
+ for ; auxv[i] != _AT_NULL; i += 2 {
+ tag, val := auxv[i], auxv[i+1]
+ switch tag {
+ case _AT_RANDOM:
+ // The kernel provides a pointer to 16-bytes
+ // worth of random data.
+ startupRandomData = (*[16]byte)(unsafe.Pointer(val))[:]
+
+ case _AT_PAGESZ:
+ physPageSize = val
+
+ case _AT_SECURE:
+ secureMode = val == 1
+ }
+
+ archauxv(tag, val)
+ vdsoauxv(tag, val)
+ }
+ return i / 2
+}
+
+var sysTHPSizePath = []byte("/sys/kernel/mm/transparent_hugepage/hpage_pmd_size\x00")
+
+func getHugePageSize() uintptr {
+ var numbuf [20]byte
+ fd := open(&sysTHPSizePath[0], 0 /* O_RDONLY */, 0)
+ if fd < 0 {
+ return 0
+ }
+ ptr := noescape(unsafe.Pointer(&numbuf[0]))
+ n := read(fd, ptr, int32(len(numbuf)))
+ closefd(fd)
+ if n <= 0 {
+ return 0
+ }
+ n-- // remove trailing newline
+ v, ok := atoi(slicebytetostringtmp((*byte)(ptr), int(n)))
+ if !ok || v < 0 {
+ v = 0
+ }
+ if v&(v-1) != 0 {
+ // v is not a power of 2
+ return 0
+ }
+ return uintptr(v)
+}
+
+func osinit() {
+ ncpu = getproccount()
+ physHugePageSize = getHugePageSize()
+ if iscgo {
+ // #42494 glibc and musl reserve some signals for
+ // internal use and require they not be blocked by
+ // the rest of a normal C runtime. When the go runtime
+ // blocks...unblocks signals, temporarily, the blocked
+ // interval of time is generally very short. As such,
+ // these expectations of *libc code are mostly met by
+ // the combined go+cgo system of threads. However,
+ // when go causes a thread to exit, via a return from
+ // mstart(), the combined runtime can deadlock if
+ // these signals are blocked. Thus, don't block these
+ // signals when exiting threads.
+ // - glibc: SIGCANCEL (32), SIGSETXID (33)
+ // - musl: SIGTIMER (32), SIGCANCEL (33), SIGSYNCCALL (34)
+ sigdelset(&sigsetAllExiting, 32)
+ sigdelset(&sigsetAllExiting, 33)
+ sigdelset(&sigsetAllExiting, 34)
+ }
+ osArchInit()
+}
+
+var urandom_dev = []byte("/dev/urandom\x00")
+
+func getRandomData(r []byte) {
+ if startupRandomData != nil {
+ n := copy(r, startupRandomData)
+ extendRandom(r, n)
+ return
+ }
+ fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
+ n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
+ closefd(fd)
+ extendRandom(r, int(n))
+}
+
+func goenvs() {
+ goenvs_unix()
+}
+
+// Called to do synchronous initialization of Go code built with
+// -buildmode=c-archive or -buildmode=c-shared.
+// None of the Go runtime is initialized.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func libpreinit() {
+ initsig(true)
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+func mpreinit(mp *m) {
+ mp.gsignal = malg(32 * 1024) // Linux wants >= 2K
+ mp.gsignal.m = mp
+}
+
+func gettid() uint32
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, cannot allocate memory.
+func minit() {
+ minitSignals()
+
+ // Cgo-created threads and the bootstrap m are missing a
+ // procid. We need this for asynchronous preemption and it's
+ // useful in debuggers.
+ getg().m.procid = uint64(gettid())
+}
+
+// Called from dropm to undo the effect of an minit.
+//
+//go:nosplit
+func unminit() {
+ unminitSignals()
+}
+
+// Called from exitm, but not from drop, to undo the effect of thread-owned
+// resources in minit, semacreate, or elsewhere. Do not take locks after calling this.
+func mdestroy(mp *m) {
+}
+
+//#ifdef GOARCH_386
+//#define sa_handler k_sa_handler
+//#endif
+
+func sigreturn__sigaction()
+func sigtramp() // Called via C ABI
+func cgoSigtramp()
+
+//go:noescape
+func sigaltstack(new, old *stackt)
+
+//go:noescape
+func setitimer(mode int32, new, old *itimerval)
+
+//go:noescape
+func timer_create(clockid int32, sevp *sigevent, timerid *int32) int32
+
+//go:noescape
+func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32
+
+//go:noescape
+func timer_delete(timerid int32) int32
+
+//go:noescape
+func rtsigprocmask(how int32, new, old *sigset, size int32)
+
+//go:nosplit
+//go:nowritebarrierrec
+func sigprocmask(how int32, new, old *sigset) {
+ rtsigprocmask(how, new, old, int32(unsafe.Sizeof(*new)))
+}
+
+func raise(sig uint32)
+func raiseproc(sig uint32)
+
+//go:noescape
+func sched_getaffinity(pid, len uintptr, buf *byte) int32
+func osyield()
+
+//go:nosplit
+func osyield_no_g() {
+ osyield()
+}
+
+func pipe2(flags int32) (r, w int32, errno int32)
+
+//go:nosplit
+func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
+ r, _, err := syscall.Syscall6(syscall.SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
+ return int32(r), int32(err)
+}
+
+const (
+ _si_max_size = 128
+ _sigev_max_size = 64
+)
+
+//go:nosplit
+//go:nowritebarrierrec
+func setsig(i uint32, fn uintptr) {
+ var sa sigactiont
+ sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTORER | _SA_RESTART
+ sigfillset(&sa.sa_mask)
+ // Although Linux manpage says "sa_restorer element is obsolete and
+ // should not be used". x86_64 kernel requires it. Only use it on
+ // x86.
+ if GOARCH == "386" || GOARCH == "amd64" {
+ sa.sa_restorer = abi.FuncPCABI0(sigreturn__sigaction)
+ }
+ if fn == abi.FuncPCABIInternal(sighandler) { // abi.FuncPCABIInternal(sighandler) matches the callers in signal_unix.go
+ if iscgo {
+ fn = abi.FuncPCABI0(cgoSigtramp)
+ } else {
+ fn = abi.FuncPCABI0(sigtramp)
+ }
+ }
+ sa.sa_handler = fn
+ sigaction(i, &sa, nil)
+}
+
+//go:nosplit
+//go:nowritebarrierrec
+func setsigstack(i uint32) {
+ var sa sigactiont
+ sigaction(i, nil, &sa)
+ if sa.sa_flags&_SA_ONSTACK != 0 {
+ return
+ }
+ sa.sa_flags |= _SA_ONSTACK
+ sigaction(i, &sa, nil)
+}
+
+//go:nosplit
+//go:nowritebarrierrec
+func getsig(i uint32) uintptr {
+ var sa sigactiont
+ sigaction(i, nil, &sa)
+ return sa.sa_handler
+}
+
+// setSignalstackSP sets the ss_sp field of a stackt.
+//
+//go:nosplit
+func setSignalstackSP(s *stackt, sp uintptr) {
+ *(*uintptr)(unsafe.Pointer(&s.ss_sp)) = sp
+}
+
+//go:nosplit
+func (c *sigctxt) fixsigcode(sig uint32) {
+}
+
+// sysSigaction calls the rt_sigaction system call.
+//
+//go:nosplit
+func sysSigaction(sig uint32, new, old *sigactiont) {
+ if rt_sigaction(uintptr(sig), new, old, unsafe.Sizeof(sigactiont{}.sa_mask)) != 0 {
+ // Workaround for bugs in QEMU user mode emulation.
+ //
+ // QEMU turns calls to the sigaction system call into
+ // calls to the C library sigaction call; the C
+ // library call rejects attempts to call sigaction for
+ // SIGCANCEL (32) or SIGSETXID (33).
+ //
+ // QEMU rejects calling sigaction on SIGRTMAX (64).
+ //
+ // Just ignore the error in these case. There isn't
+ // anything we can do about it anyhow.
+ if sig != 32 && sig != 33 && sig != 64 {
+ // Use system stack to avoid split stack overflow on ppc64/ppc64le.
+ systemstack(func() {
+ throw("sigaction failed")
+ })
+ }
+ }
+}
+
+// rt_sigaction is implemented in assembly.
+//
+//go:noescape
+func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32
+
+func getpid() int
+func tgkill(tgid, tid, sig int)
+
+// signalM sends a signal to mp.
+func signalM(mp *m, sig int) {
+ tgkill(getpid(), int(mp.procid), sig)
+}
+
+// validSIGPROF compares this signal delivery's code against the signal sources
+// that the profiler uses, returning whether the delivery should be processed.
+// To be processed, a signal delivery from a known profiling mechanism should
+// correspond to the best profiling mechanism available to this thread. Signals
+// from other sources are always considered valid.
+//
+//go:nosplit
+func validSIGPROF(mp *m, c *sigctxt) bool {
+ code := int32(c.sigcode())
+ setitimer := code == _SI_KERNEL
+ timer_create := code == _SI_TIMER
+
+ if !(setitimer || timer_create) {
+ // The signal doesn't correspond to a profiling mechanism that the
+ // runtime enables itself. There's no reason to process it, but there's
+ // no reason to ignore it either.
+ return true
+ }
+
+ if mp == nil {
+ // Since we don't have an M, we can't check if there's an active
+ // per-thread timer for this thread. We don't know how long this thread
+ // has been around, and if it happened to interact with the Go scheduler
+ // at a time when profiling was active (causing it to have a per-thread
+ // timer). But it may have never interacted with the Go scheduler, or
+ // never while profiling was active. To avoid double-counting, process
+ // only signals from setitimer.
+ //
+ // When a custom cgo traceback function has been registered (on
+ // platforms that support runtime.SetCgoTraceback), SIGPROF signals
+ // delivered to a thread that cannot find a matching M do this check in
+ // the assembly implementations of runtime.cgoSigtramp.
+ return setitimer
+ }
+
+ // Having an M means the thread interacts with the Go scheduler, and we can
+ // check whether there's an active per-thread timer for this thread.
+ if mp.profileTimerValid.Load() {
+ // If this M has its own per-thread CPU profiling interval timer, we
+ // should track the SIGPROF signals that come from that timer (for
+ // accurate reporting of its CPU usage; see issue 35057) and ignore any
+ // that it gets from the process-wide setitimer (to not over-count its
+ // CPU consumption).
+ return timer_create
+ }
+
+ // No active per-thread timer means the only valid profiler is setitimer.
+ return setitimer
+}
+
+func setProcessCPUProfiler(hz int32) {
+ setProcessCPUProfilerTimer(hz)
+}
+
+func setThreadCPUProfiler(hz int32) {
+ mp := getg().m
+ mp.profilehz = hz
+
+ // destroy any active timer
+ if mp.profileTimerValid.Load() {
+ timerid := mp.profileTimer
+ mp.profileTimerValid.Store(false)
+ mp.profileTimer = 0
+
+ ret := timer_delete(timerid)
+ if ret != 0 {
+ print("runtime: failed to disable profiling timer; timer_delete(", timerid, ") errno=", -ret, "\n")
+ throw("timer_delete")
+ }
+ }
+
+ if hz == 0 {
+ // If the goal was to disable profiling for this thread, then the job's done.
+ return
+ }
+
+ // The period of the timer should be 1/Hz. For every "1/Hz" of additional
+ // work, the user should expect one additional sample in the profile.
+ //
+ // But to scale down to very small amounts of application work, to observe
+ // even CPU usage of "one tenth" of the requested period, set the initial
+ // timing delay in a different way: So that "one tenth" of a period of CPU
+ // spend shows up as a 10% chance of one sample (for an expected value of
+ // 0.1 samples), and so that "two and six tenths" periods of CPU spend show
+ // up as a 60% chance of 3 samples and a 40% chance of 2 samples (for an
+ // expected value of 2.6). Set the initial delay to a value in the unifom
+ // random distribution between 0 and the desired period. And because "0"
+ // means "disable timer", add 1 so the half-open interval [0,period) turns
+ // into (0,period].
+ //
+ // Otherwise, this would show up as a bias away from short-lived threads and
+ // from threads that are only occasionally active: for example, when the
+ // garbage collector runs on a mostly-idle system, the additional threads it
+ // activates may do a couple milliseconds of GC-related work and nothing
+ // else in the few seconds that the profiler observes.
+ spec := new(itimerspec)
+ spec.it_value.setNsec(1 + int64(fastrandn(uint32(1e9/hz))))
+ spec.it_interval.setNsec(1e9 / int64(hz))
+
+ var timerid int32
+ var sevp sigevent
+ sevp.notify = _SIGEV_THREAD_ID
+ sevp.signo = _SIGPROF
+ sevp.sigev_notify_thread_id = int32(mp.procid)
+ ret := timer_create(_CLOCK_THREAD_CPUTIME_ID, &sevp, &timerid)
+ if ret != 0 {
+ // If we cannot create a timer for this M, leave profileTimerValid false
+ // to fall back to the process-wide setitimer profiler.
+ return
+ }
+
+ ret = timer_settime(timerid, 0, spec, nil)
+ if ret != 0 {
+ print("runtime: failed to configure profiling timer; timer_settime(", timerid,
+ ", 0, {interval: {",
+ spec.it_interval.tv_sec, "s + ", spec.it_interval.tv_nsec, "ns} value: {",
+ spec.it_value.tv_sec, "s + ", spec.it_value.tv_nsec, "ns}}, nil) errno=", -ret, "\n")
+ throw("timer_settime")
+ }
+
+ mp.profileTimer = timerid
+ mp.profileTimerValid.Store(true)
+}
+
+// perThreadSyscallArgs contains the system call number, arguments, and
+// expected return values for a system call to be executed on all threads.
+type perThreadSyscallArgs struct {
+ trap uintptr
+ a1 uintptr
+ a2 uintptr
+ a3 uintptr
+ a4 uintptr
+ a5 uintptr
+ a6 uintptr
+ r1 uintptr
+ r2 uintptr
+}
+
+// perThreadSyscall is the system call to execute for the ongoing
+// doAllThreadsSyscall.
+//
+// perThreadSyscall may only be written while mp.needPerThreadSyscall == 0 on
+// all Ms.
+var perThreadSyscall perThreadSyscallArgs
+
+// syscall_runtime_doAllThreadsSyscall and executes a specified system call on
+// all Ms.
+//
+// The system call is expected to succeed and return the same value on every
+// thread. If any threads do not match, the runtime throws.
+//
+//go:linkname syscall_runtime_doAllThreadsSyscall syscall.runtime_doAllThreadsSyscall
+//go:uintptrescapes
+func syscall_runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
+ if iscgo {
+ // In cgo, we are not aware of threads created in C, so this approach will not work.
+ panic("doAllThreadsSyscall not supported with cgo enabled")
+ }
+
+ // STW to guarantee that user goroutines see an atomic change to thread
+ // state. Without STW, goroutines could migrate Ms while change is in
+ // progress and e.g., see state old -> new -> old -> new.
+ //
+ // N.B. Internally, this function does not depend on STW to
+ // successfully change every thread. It is only needed for user
+ // expectations, per above.
+ stopTheWorld(stwAllThreadsSyscall)
+
+ // This function depends on several properties:
+ //
+ // 1. All OS threads that already exist are associated with an M in
+ // allm. i.e., we won't miss any pre-existing threads.
+ // 2. All Ms listed in allm will eventually have an OS thread exist.
+ // i.e., they will set procid and be able to receive signals.
+ // 3. OS threads created after we read allm will clone from a thread
+ // that has executed the system call. i.e., they inherit the
+ // modified state.
+ //
+ // We achieve these through different mechanisms:
+ //
+ // 1. Addition of new Ms to allm in allocm happens before clone of its
+ // OS thread later in newm.
+ // 2. newm does acquirem to avoid being preempted, ensuring that new Ms
+ // created in allocm will eventually reach OS thread clone later in
+ // newm.
+ // 3. We take allocmLock for write here to prevent allocation of new Ms
+ // while this function runs. Per (1), this prevents clone of OS
+ // threads that are not yet in allm.
+ allocmLock.lock()
+
+ // Disable preemption, preventing us from changing Ms, as we handle
+ // this M specially.
+ //
+ // N.B. STW and lock() above do this as well, this is added for extra
+ // clarity.
+ acquirem()
+
+ // N.B. allocmLock also prevents concurrent execution of this function,
+ // serializing use of perThreadSyscall, mp.needPerThreadSyscall, and
+ // ensuring all threads execute system calls from multiple calls in the
+ // same order.
+
+ r1, r2, errno := syscall.Syscall6(trap, a1, a2, a3, a4, a5, a6)
+ if GOARCH == "ppc64" || GOARCH == "ppc64le" {
+ // TODO(https://go.dev/issue/51192 ): ppc64 doesn't use r2.
+ r2 = 0
+ }
+ if errno != 0 {
+ releasem(getg().m)
+ allocmLock.unlock()
+ startTheWorld()
+ return r1, r2, errno
+ }
+
+ perThreadSyscall = perThreadSyscallArgs{
+ trap: trap,
+ a1: a1,
+ a2: a2,
+ a3: a3,
+ a4: a4,
+ a5: a5,
+ a6: a6,
+ r1: r1,
+ r2: r2,
+ }
+
+ // Wait for all threads to start.
+ //
+ // As described above, some Ms have been added to allm prior to
+ // allocmLock, but not yet completed OS clone and set procid.
+ //
+ // At minimum we must wait for a thread to set procid before we can
+ // send it a signal.
+ //
+ // We take this one step further and wait for all threads to start
+ // before sending any signals. This prevents system calls from getting
+ // applied twice: once in the parent and once in the child, like so:
+ //
+ // A B C
+ // add C to allm
+ // doAllThreadsSyscall
+ // allocmLock.lock()
+ // signal B
+ // <receive signal>
+ // execute syscall
+ // <signal return>
+ // clone C
+ // <thread start>
+ // set procid
+ // signal C
+ // <receive signal>
+ // execute syscall
+ // <signal return>
+ //
+ // In this case, thread C inherited the syscall-modified state from
+ // thread B and did not need to execute the syscall, but did anyway
+ // because doAllThreadsSyscall could not be sure whether it was
+ // required.
+ //
+ // Some system calls may not be idempotent, so we ensure each thread
+ // executes the system call exactly once.
+ for mp := allm; mp != nil; mp = mp.alllink {
+ for atomic.Load64(&mp.procid) == 0 {
+ // Thread is starting.
+ osyield()
+ }
+ }
+
+ // Signal every other thread, where they will execute perThreadSyscall
+ // from the signal handler.
+ gp := getg()
+ tid := gp.m.procid
+ for mp := allm; mp != nil; mp = mp.alllink {
+ if atomic.Load64(&mp.procid) == tid {
+ // Our thread already performed the syscall.
+ continue
+ }
+ mp.needPerThreadSyscall.Store(1)
+ signalM(mp, sigPerThreadSyscall)
+ }
+
+ // Wait for all threads to complete.
+ for mp := allm; mp != nil; mp = mp.alllink {
+ if mp.procid == tid {
+ continue
+ }
+ for mp.needPerThreadSyscall.Load() != 0 {
+ osyield()
+ }
+ }
+
+ perThreadSyscall = perThreadSyscallArgs{}
+
+ releasem(getg().m)
+ allocmLock.unlock()
+ startTheWorld()
+
+ return r1, r2, errno
+}
+
+// runPerThreadSyscall runs perThreadSyscall for this M if required.
+//
+// This function throws if the system call returns with anything other than the
+// expected values.
+//
+//go:nosplit
+func runPerThreadSyscall() {
+ gp := getg()
+ if gp.m.needPerThreadSyscall.Load() == 0 {
+ return
+ }
+
+ args := perThreadSyscall
+ r1, r2, errno := syscall.Syscall6(args.trap, args.a1, args.a2, args.a3, args.a4, args.a5, args.a6)
+ if GOARCH == "ppc64" || GOARCH == "ppc64le" {
+ // TODO(https://go.dev/issue/51192 ): ppc64 doesn't use r2.
+ r2 = 0
+ }
+ if errno != 0 || r1 != args.r1 || r2 != args.r2 {
+ print("trap:", args.trap, ", a123456=[", args.a1, ",", args.a2, ",", args.a3, ",", args.a4, ",", args.a5, ",", args.a6, "]\n")
+ print("results: got {r1=", r1, ",r2=", r2, ",errno=", errno, "}, want {r1=", args.r1, ",r2=", args.r2, ",errno=0}\n")
+ fatal("AllThreadsSyscall6 results differ between threads; runtime corrupted")
+ }
+
+ gp.m.needPerThreadSyscall.Store(0)
+}
+
+const (
+ _SI_USER = 0
+ _SI_TKILL = -6
+)
+
+// sigFromUser reports whether the signal was sent because of a call
+// to kill or tgkill.
+//
+//go:nosplit
+func (c *sigctxt) sigFromUser() bool {
+ code := int32(c.sigcode())
+ return code == _SI_USER || code == _SI_TKILL
+}
diff --git a/contrib/go/_std_1.20/src/runtime/os_linux_arm64.go b/contrib/go/_std_1.21/src/runtime/os_linux_arm64.go
index 2daa56fce7..2daa56fce7 100644
--- a/contrib/go/_std_1.20/src/runtime/os_linux_arm64.go
+++ b/contrib/go/_std_1.21/src/runtime/os_linux_arm64.go
diff --git a/contrib/go/_std_1.20/src/runtime/os_linux_generic.go b/contrib/go/_std_1.21/src/runtime/os_linux_generic.go
index 15fafc14ea..15fafc14ea 100644
--- a/contrib/go/_std_1.20/src/runtime/os_linux_generic.go
+++ b/contrib/go/_std_1.21/src/runtime/os_linux_generic.go
diff --git a/contrib/go/_std_1.20/src/runtime/os_linux_noauxv.go b/contrib/go/_std_1.21/src/runtime/os_linux_noauxv.go
index ff377277aa..ff377277aa 100644
--- a/contrib/go/_std_1.20/src/runtime/os_linux_noauxv.go
+++ b/contrib/go/_std_1.21/src/runtime/os_linux_noauxv.go
diff --git a/contrib/go/_std_1.20/src/runtime/os_linux_x86.go b/contrib/go/_std_1.21/src/runtime/os_linux_x86.go
index c88f61fa2e..c88f61fa2e 100644
--- a/contrib/go/_std_1.20/src/runtime/os_linux_x86.go
+++ b/contrib/go/_std_1.21/src/runtime/os_linux_x86.go
diff --git a/contrib/go/_std_1.20/src/runtime/os_nonopenbsd.go b/contrib/go/_std_1.21/src/runtime/os_nonopenbsd.go
index a5775961e8..a5775961e8 100644
--- a/contrib/go/_std_1.20/src/runtime/os_nonopenbsd.go
+++ b/contrib/go/_std_1.21/src/runtime/os_nonopenbsd.go
diff --git a/contrib/go/_std_1.21/src/runtime/os_unix.go b/contrib/go/_std_1.21/src/runtime/os_unix.go
new file mode 100644
index 0000000000..fdbeba70cc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/os_unix.go
@@ -0,0 +1,19 @@
+// Copyright 2023 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.
+
+//go:build unix
+
+package runtime
+
+const (
+ // These values are the same on all known Unix systems.
+ // If we find a discrepancy some day, we can split them out.
+ _F_SETFD = 2
+ _FD_CLOEXEC = 1
+)
+
+//go:nosplit
+func closeonexec(fd int32) {
+ fcntl(fd, _F_SETFD, _FD_CLOEXEC)
+}
diff --git a/contrib/go/_std_1.20/src/runtime/os_unix_nonlinux.go b/contrib/go/_std_1.21/src/runtime/os_unix_nonlinux.go
index b98753b8fe..b98753b8fe 100644
--- a/contrib/go/_std_1.20/src/runtime/os_unix_nonlinux.go
+++ b/contrib/go/_std_1.21/src/runtime/os_unix_nonlinux.go
diff --git a/contrib/go/_std_1.21/src/runtime/os_windows.go b/contrib/go/_std_1.21/src/runtime/os_windows.go
new file mode 100644
index 0000000000..f5c2429a05
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/os_windows.go
@@ -0,0 +1,1445 @@
+// Copyright 2009 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// TODO(brainman): should not need those
+const (
+ _NSIG = 65
+)
+
+//go:cgo_import_dynamic runtime._AddVectoredExceptionHandler AddVectoredExceptionHandler%2 "kernel32.dll"
+//go:cgo_import_dynamic runtime._CloseHandle CloseHandle%1 "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateEventA CreateEventA%4 "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateFileA CreateFileA%7 "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateIoCompletionPort CreateIoCompletionPort%4 "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateThread CreateThread%6 "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateWaitableTimerA CreateWaitableTimerA%3 "kernel32.dll"
+//go:cgo_import_dynamic runtime._CreateWaitableTimerExW CreateWaitableTimerExW%4 "kernel32.dll"
+//go:cgo_import_dynamic runtime._DuplicateHandle DuplicateHandle%7 "kernel32.dll"
+//go:cgo_import_dynamic runtime._ExitProcess ExitProcess%1 "kernel32.dll"
+//go:cgo_import_dynamic runtime._FreeEnvironmentStringsW FreeEnvironmentStringsW%1 "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetConsoleMode GetConsoleMode%2 "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetCurrentThreadId GetCurrentThreadId%0 "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetEnvironmentStringsW GetEnvironmentStringsW%0 "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetErrorMode GetErrorMode%0 "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetProcAddress GetProcAddress%2 "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetProcessAffinityMask GetProcessAffinityMask%3 "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetQueuedCompletionStatusEx GetQueuedCompletionStatusEx%6 "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetStdHandle GetStdHandle%1 "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetSystemDirectoryA GetSystemDirectoryA%2 "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll"
+//go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll"
+//go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll"
+//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll"
+//go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll"
+//go:cgo_import_dynamic runtime._RaiseFailFastException RaiseFailFastException%3 "kernel32.dll"
+//go:cgo_import_dynamic runtime._ResumeThread ResumeThread%1 "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetConsoleCtrlHandler SetConsoleCtrlHandler%2 "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetErrorMode SetErrorMode%1 "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetEvent SetEvent%1 "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetProcessPriorityBoost SetProcessPriorityBoost%2 "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetThreadPriority SetThreadPriority%2 "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetUnhandledExceptionFilter SetUnhandledExceptionFilter%1 "kernel32.dll"
+//go:cgo_import_dynamic runtime._SetWaitableTimer SetWaitableTimer%6 "kernel32.dll"
+//go:cgo_import_dynamic runtime._SuspendThread SuspendThread%1 "kernel32.dll"
+//go:cgo_import_dynamic runtime._SwitchToThread SwitchToThread%0 "kernel32.dll"
+//go:cgo_import_dynamic runtime._TlsAlloc TlsAlloc%0 "kernel32.dll"
+//go:cgo_import_dynamic runtime._VirtualAlloc VirtualAlloc%4 "kernel32.dll"
+//go:cgo_import_dynamic runtime._VirtualFree VirtualFree%3 "kernel32.dll"
+//go:cgo_import_dynamic runtime._VirtualQuery VirtualQuery%3 "kernel32.dll"
+//go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject%2 "kernel32.dll"
+//go:cgo_import_dynamic runtime._WaitForMultipleObjects WaitForMultipleObjects%4 "kernel32.dll"
+//go:cgo_import_dynamic runtime._WerGetFlags WerGetFlags%2 "kernel32.dll"
+//go:cgo_import_dynamic runtime._WerSetFlags WerSetFlags%1 "kernel32.dll"
+//go:cgo_import_dynamic runtime._WriteConsoleW WriteConsoleW%5 "kernel32.dll"
+//go:cgo_import_dynamic runtime._WriteFile WriteFile%5 "kernel32.dll"
+
+type stdFunction unsafe.Pointer
+
+var (
+ // Following syscalls are available on every Windows PC.
+ // All these variables are set by the Windows executable
+ // loader before the Go program starts.
+ _AddVectoredExceptionHandler,
+ _CloseHandle,
+ _CreateEventA,
+ _CreateFileA,
+ _CreateIoCompletionPort,
+ _CreateThread,
+ _CreateWaitableTimerA,
+ _CreateWaitableTimerExW,
+ _DuplicateHandle,
+ _ExitProcess,
+ _FreeEnvironmentStringsW,
+ _GetConsoleMode,
+ _GetCurrentThreadId,
+ _GetEnvironmentStringsW,
+ _GetErrorMode,
+ _GetProcAddress,
+ _GetProcessAffinityMask,
+ _GetQueuedCompletionStatusEx,
+ _GetStdHandle,
+ _GetSystemDirectoryA,
+ _GetSystemInfo,
+ _GetSystemTimeAsFileTime,
+ _GetThreadContext,
+ _SetThreadContext,
+ _LoadLibraryExW,
+ _LoadLibraryW,
+ _PostQueuedCompletionStatus,
+ _QueryPerformanceCounter,
+ _QueryPerformanceFrequency,
+ _RaiseFailFastException,
+ _ResumeThread,
+ _SetConsoleCtrlHandler,
+ _SetErrorMode,
+ _SetEvent,
+ _SetProcessPriorityBoost,
+ _SetThreadPriority,
+ _SetUnhandledExceptionFilter,
+ _SetWaitableTimer,
+ _SuspendThread,
+ _SwitchToThread,
+ _TlsAlloc,
+ _VirtualAlloc,
+ _VirtualFree,
+ _VirtualQuery,
+ _WaitForSingleObject,
+ _WaitForMultipleObjects,
+ _WerGetFlags,
+ _WerSetFlags,
+ _WriteConsoleW,
+ _WriteFile,
+ _ stdFunction
+
+ // Following syscalls are only available on some Windows PCs.
+ // We will load syscalls, if available, before using them.
+ _AddVectoredContinueHandler,
+ _ stdFunction
+
+ // Use RtlGenRandom to generate cryptographically random data.
+ // This approach has been recommended by Microsoft (see issue
+ // 15589 for details).
+ // The RtlGenRandom is not listed in advapi32.dll, instead
+ // RtlGenRandom function can be found by searching for SystemFunction036.
+ // Also some versions of Mingw cannot link to SystemFunction036
+ // when building executable as Cgo. So load SystemFunction036
+ // manually during runtime startup.
+ _RtlGenRandom stdFunction
+
+ // Load ntdll.dll manually during startup, otherwise Mingw
+ // links wrong printf function to cgo executable (see issue
+ // 12030 for details).
+ _NtWaitForSingleObject stdFunction
+ _RtlGetCurrentPeb stdFunction
+ _RtlGetNtVersionNumbers stdFunction
+
+ // These are from non-kernel32.dll, so we prefer to LoadLibraryEx them.
+ _timeBeginPeriod,
+ _timeEndPeriod,
+ _WSAGetOverlappedResult,
+ _ stdFunction
+)
+
+var (
+ advapi32dll = [...]uint16{'a', 'd', 'v', 'a', 'p', 'i', '3', '2', '.', 'd', 'l', 'l', 0}
+ kernel32dll = [...]uint16{'k', 'e', 'r', 'n', 'e', 'l', '3', '2', '.', 'd', 'l', 'l', 0}
+ ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0}
+ powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0}
+ winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0}
+ ws2_32dll = [...]uint16{'w', 's', '2', '_', '3', '2', '.', 'd', 'l', 'l', 0}
+)
+
+// Function to be called by windows CreateThread
+// to start new os thread.
+func tstart_stdcall(newm *m)
+
+// Init-time helper
+func wintls()
+
+type mOS struct {
+ threadLock mutex // protects "thread" and prevents closing
+ thread uintptr // thread handle
+
+ waitsema uintptr // semaphore for parking on locks
+ resumesema uintptr // semaphore to indicate suspend/resume
+
+ highResTimer uintptr // high resolution timer handle used in usleep
+
+ // preemptExtLock synchronizes preemptM with entry/exit from
+ // external C code.
+ //
+ // This protects against races between preemptM calling
+ // SuspendThread and external code on this thread calling
+ // ExitProcess. If these happen concurrently, it's possible to
+ // exit the suspending thread and suspend the exiting thread,
+ // leading to deadlock.
+ //
+ // 0 indicates this M is not being preempted or in external
+ // code. Entering external code CASes this from 0 to 1. If
+ // this fails, a preemption is in progress, so the thread must
+ // wait for the preemption. preemptM also CASes this from 0 to
+ // 1. If this fails, the preemption fails (as it would if the
+ // PC weren't in Go code). The value is reset to 0 when
+ // returning from external code or after a preemption is
+ // complete.
+ //
+ // TODO(austin): We may not need this if preemption were more
+ // tightly synchronized on the G/P status and preemption
+ // blocked transition into _Gsyscall/_Psyscall.
+ preemptExtLock uint32
+}
+
+// Stubs so tests can link correctly. These should never be called.
+func open(name *byte, mode, perm int32) int32 {
+ throw("unimplemented")
+ return -1
+}
+func closefd(fd int32) int32 {
+ throw("unimplemented")
+ return -1
+}
+func read(fd int32, p unsafe.Pointer, n int32) int32 {
+ throw("unimplemented")
+ return -1
+}
+
+type sigset struct{}
+
+// Call a Windows function with stdcall conventions,
+// and switch to os stack during the call.
+func asmstdcall(fn unsafe.Pointer)
+
+var asmstdcallAddr unsafe.Pointer
+
+func windowsFindfunc(lib uintptr, name []byte) stdFunction {
+ if name[len(name)-1] != 0 {
+ throw("usage")
+ }
+ f := stdcall2(_GetProcAddress, lib, uintptr(unsafe.Pointer(&name[0])))
+ return stdFunction(unsafe.Pointer(f))
+}
+
+const _MAX_PATH = 260 // https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
+var sysDirectory [_MAX_PATH + 1]byte
+var sysDirectoryLen uintptr
+
+func initSysDirectory() {
+ l := stdcall2(_GetSystemDirectoryA, uintptr(unsafe.Pointer(&sysDirectory[0])), uintptr(len(sysDirectory)-1))
+ if l == 0 || l > uintptr(len(sysDirectory)-1) {
+ throw("Unable to determine system directory")
+ }
+ sysDirectory[l] = '\\'
+ sysDirectoryLen = l + 1
+}
+
+func windowsLoadSystemLib(name []uint16) uintptr {
+ return stdcall3(_LoadLibraryExW, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32)
+}
+
+const haveCputicksAsm = GOARCH == "386" || GOARCH == "amd64"
+
+func loadOptionalSyscalls() {
+ k32 := windowsLoadSystemLib(kernel32dll[:])
+ if k32 == 0 {
+ throw("kernel32.dll not found")
+ }
+ _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000"))
+
+ a32 := windowsLoadSystemLib(advapi32dll[:])
+ if a32 == 0 {
+ throw("advapi32.dll not found")
+ }
+ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000"))
+
+ n32 := windowsLoadSystemLib(ntdlldll[:])
+ if n32 == 0 {
+ throw("ntdll.dll not found")
+ }
+ _NtWaitForSingleObject = windowsFindfunc(n32, []byte("NtWaitForSingleObject\000"))
+ _RtlGetCurrentPeb = windowsFindfunc(n32, []byte("RtlGetCurrentPeb\000"))
+ _RtlGetNtVersionNumbers = windowsFindfunc(n32, []byte("RtlGetNtVersionNumbers\000"))
+
+ if !haveCputicksAsm {
+ _QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
+ if _QueryPerformanceCounter == nil {
+ throw("could not find QPC syscalls")
+ }
+ }
+
+ m32 := windowsLoadSystemLib(winmmdll[:])
+ if m32 == 0 {
+ throw("winmm.dll not found")
+ }
+ _timeBeginPeriod = windowsFindfunc(m32, []byte("timeBeginPeriod\000"))
+ _timeEndPeriod = windowsFindfunc(m32, []byte("timeEndPeriod\000"))
+ if _timeBeginPeriod == nil || _timeEndPeriod == nil {
+ throw("timeBegin/EndPeriod not found")
+ }
+
+ ws232 := windowsLoadSystemLib(ws2_32dll[:])
+ if ws232 == 0 {
+ throw("ws2_32.dll not found")
+ }
+ _WSAGetOverlappedResult = windowsFindfunc(ws232, []byte("WSAGetOverlappedResult\000"))
+ if _WSAGetOverlappedResult == nil {
+ throw("WSAGetOverlappedResult not found")
+ }
+
+ if windowsFindfunc(n32, []byte("wine_get_version\000")) != nil {
+ // running on Wine
+ initWine(k32)
+ }
+}
+
+func monitorSuspendResume() {
+ const (
+ _DEVICE_NOTIFY_CALLBACK = 2
+ )
+ type _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS struct {
+ callback uintptr
+ context uintptr
+ }
+
+ powrprof := windowsLoadSystemLib(powrprofdll[:])
+ if powrprof == 0 {
+ return // Running on Windows 7, where we don't need it anyway.
+ }
+ powerRegisterSuspendResumeNotification := windowsFindfunc(powrprof, []byte("PowerRegisterSuspendResumeNotification\000"))
+ if powerRegisterSuspendResumeNotification == nil {
+ return // Running on Windows 7, where we don't need it anyway.
+ }
+ var fn any = func(context uintptr, changeType uint32, setting uintptr) uintptr {
+ for mp := (*m)(atomic.Loadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink {
+ if mp.resumesema != 0 {
+ stdcall1(_SetEvent, mp.resumesema)
+ }
+ }
+ return 0
+ }
+ params := _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS{
+ callback: compileCallback(*efaceOf(&fn), true),
+ }
+ handle := uintptr(0)
+ stdcall3(powerRegisterSuspendResumeNotification, _DEVICE_NOTIFY_CALLBACK,
+ uintptr(unsafe.Pointer(&params)), uintptr(unsafe.Pointer(&handle)))
+}
+
+//go:nosplit
+func getLoadLibrary() uintptr {
+ return uintptr(unsafe.Pointer(_LoadLibraryW))
+}
+
+//go:nosplit
+func getLoadLibraryEx() uintptr {
+ return uintptr(unsafe.Pointer(_LoadLibraryExW))
+}
+
+//go:nosplit
+func getGetProcAddress() uintptr {
+ return uintptr(unsafe.Pointer(_GetProcAddress))
+}
+
+func getproccount() int32 {
+ var mask, sysmask uintptr
+ ret := stdcall3(_GetProcessAffinityMask, currentProcess, uintptr(unsafe.Pointer(&mask)), uintptr(unsafe.Pointer(&sysmask)))
+ if ret != 0 {
+ n := 0
+ maskbits := int(unsafe.Sizeof(mask) * 8)
+ for i := 0; i < maskbits; i++ {
+ if mask&(1<<uint(i)) != 0 {
+ n++
+ }
+ }
+ if n != 0 {
+ return int32(n)
+ }
+ }
+ // use GetSystemInfo if GetProcessAffinityMask fails
+ var info systeminfo
+ stdcall1(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
+ return int32(info.dwnumberofprocessors)
+}
+
+func getPageSize() uintptr {
+ var info systeminfo
+ stdcall1(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
+ return uintptr(info.dwpagesize)
+}
+
+const (
+ currentProcess = ^uintptr(0) // -1 = current process
+ currentThread = ^uintptr(1) // -2 = current thread
+)
+
+// in sys_windows_386.s and sys_windows_amd64.s:
+func getlasterror() uint32
+
+var timeBeginPeriodRetValue uint32
+
+// osRelaxMinNS indicates that sysmon shouldn't osRelax if the next
+// timer is less than 60 ms from now. Since osRelaxing may reduce
+// timer resolution to 15.6 ms, this keeps timer error under roughly 1
+// part in 4.
+const osRelaxMinNS = 60 * 1e6
+
+// osRelax is called by the scheduler when transitioning to and from
+// all Ps being idle.
+//
+// Some versions of Windows have high resolution timer. For those
+// versions osRelax is noop.
+// For Windows versions without high resolution timer, osRelax
+// adjusts the system-wide timer resolution. Go needs a
+// high resolution timer while running and there's little extra cost
+// if we're already using the CPU, but if all Ps are idle there's no
+// need to consume extra power to drive the high-res timer.
+func osRelax(relax bool) uint32 {
+ if haveHighResTimer {
+ // If the high resolution timer is available, the runtime uses the timer
+ // to sleep for short durations. This means there's no need to adjust
+ // the global clock frequency.
+ return 0
+ }
+
+ if relax {
+ return uint32(stdcall1(_timeEndPeriod, 1))
+ } else {
+ return uint32(stdcall1(_timeBeginPeriod, 1))
+ }
+}
+
+// haveHighResTimer indicates that the CreateWaitableTimerEx
+// CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag is available.
+var haveHighResTimer = false
+
+// createHighResTimer calls CreateWaitableTimerEx with
+// CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag to create high
+// resolution timer. createHighResTimer returns new timer
+// handle or 0, if CreateWaitableTimerEx failed.
+func createHighResTimer() uintptr {
+ const (
+ // As per @jstarks, see
+ // https://github.com/golang/go/issues/8687#issuecomment-656259353
+ _CREATE_WAITABLE_TIMER_HIGH_RESOLUTION = 0x00000002
+
+ _SYNCHRONIZE = 0x00100000
+ _TIMER_QUERY_STATE = 0x0001
+ _TIMER_MODIFY_STATE = 0x0002
+ )
+ return stdcall4(_CreateWaitableTimerExW, 0, 0,
+ _CREATE_WAITABLE_TIMER_HIGH_RESOLUTION,
+ _SYNCHRONIZE|_TIMER_QUERY_STATE|_TIMER_MODIFY_STATE)
+}
+
+func initHighResTimer() {
+ h := createHighResTimer()
+ if h != 0 {
+ haveHighResTimer = true
+ stdcall1(_CloseHandle, h)
+ }
+}
+
+//go:linkname canUseLongPaths os.canUseLongPaths
+var canUseLongPaths bool
+
+// We want this to be large enough to hold the contents of sysDirectory, *plus*
+// a slash and another component that itself is greater than MAX_PATH.
+var longFileName [(_MAX_PATH+1)*2 + 1]byte
+
+// initLongPathSupport initializes the canUseLongPaths variable, which is
+// linked into os.canUseLongPaths for determining whether or not long paths
+// need to be fixed up. In the best case, this function is running on newer
+// Windows 10 builds, which have a bit field member of the PEB called
+// "IsLongPathAwareProcess." When this is set, we don't need to go through the
+// error-prone fixup function in order to access long paths. So this init
+// function first checks the Windows build number, sets the flag, and then
+// tests to see if it's actually working. If everything checks out, then
+// canUseLongPaths is set to true, and later when called, os.fixLongPath
+// returns early without doing work.
+func initLongPathSupport() {
+ const (
+ IsLongPathAwareProcess = 0x80
+ PebBitFieldOffset = 3
+ OPEN_EXISTING = 3
+ ERROR_PATH_NOT_FOUND = 3
+ )
+
+ // Check that we're ≥ 10.0.15063.
+ var maj, min, build uint32
+ stdcall3(_RtlGetNtVersionNumbers, uintptr(unsafe.Pointer(&maj)), uintptr(unsafe.Pointer(&min)), uintptr(unsafe.Pointer(&build)))
+ if maj < 10 || (maj == 10 && min == 0 && build&0xffff < 15063) {
+ return
+ }
+
+ // Set the IsLongPathAwareProcess flag of the PEB's bit field.
+ bitField := (*byte)(unsafe.Pointer(stdcall0(_RtlGetCurrentPeb) + PebBitFieldOffset))
+ originalBitField := *bitField
+ *bitField |= IsLongPathAwareProcess
+
+ // Check that this actually has an effect, by constructing a large file
+ // path and seeing whether we get ERROR_PATH_NOT_FOUND, rather than
+ // some other error, which would indicate the path is too long, and
+ // hence long path support is not successful. This whole section is NOT
+ // strictly necessary, but is a nice validity check for the near to
+ // medium term, when this functionality is still relatively new in
+ // Windows.
+ getRandomData(longFileName[len(longFileName)-33 : len(longFileName)-1])
+ start := copy(longFileName[:], sysDirectory[:sysDirectoryLen])
+ const dig = "0123456789abcdef"
+ for i := 0; i < 32; i++ {
+ longFileName[start+i*2] = dig[longFileName[len(longFileName)-33+i]>>4]
+ longFileName[start+i*2+1] = dig[longFileName[len(longFileName)-33+i]&0xf]
+ }
+ start += 64
+ for i := start; i < len(longFileName)-1; i++ {
+ longFileName[i] = 'A'
+ }
+ stdcall7(_CreateFileA, uintptr(unsafe.Pointer(&longFileName[0])), 0, 0, 0, OPEN_EXISTING, 0, 0)
+ // The ERROR_PATH_NOT_FOUND error value is distinct from
+ // ERROR_FILE_NOT_FOUND or ERROR_INVALID_NAME, the latter of which we
+ // expect here due to the final component being too long.
+ if getlasterror() == ERROR_PATH_NOT_FOUND {
+ *bitField = originalBitField
+ println("runtime: warning: IsLongPathAwareProcess failed to enable long paths; proceeding in fixup mode")
+ return
+ }
+
+ canUseLongPaths = true
+}
+
+func osinit() {
+ asmstdcallAddr = unsafe.Pointer(abi.FuncPCABI0(asmstdcall))
+
+ loadOptionalSyscalls()
+
+ preventErrorDialogs()
+
+ initExceptionHandler()
+
+ initHighResTimer()
+ timeBeginPeriodRetValue = osRelax(false)
+
+ initSysDirectory()
+ initLongPathSupport()
+
+ ncpu = getproccount()
+
+ physPageSize = getPageSize()
+
+ // Windows dynamic priority boosting assumes that a process has different types
+ // of dedicated threads -- GUI, IO, computational, etc. Go processes use
+ // equivalent threads that all do a mix of GUI, IO, computations, etc.
+ // In such context dynamic priority boosting does nothing but harm, so we turn it off.
+ stdcall2(_SetProcessPriorityBoost, currentProcess, 1)
+}
+
+// useQPCTime controls whether time.now and nanotime use QueryPerformanceCounter.
+// This is only set to 1 when running under Wine.
+var useQPCTime uint8
+
+var qpcStartCounter int64
+var qpcMultiplier int64
+
+//go:nosplit
+func nanotimeQPC() int64 {
+ var counter int64 = 0
+ stdcall1(_QueryPerformanceCounter, uintptr(unsafe.Pointer(&counter)))
+
+ // returns number of nanoseconds
+ return (counter - qpcStartCounter) * qpcMultiplier
+}
+
+//go:nosplit
+func nowQPC() (sec int64, nsec int32, mono int64) {
+ var ft int64
+ stdcall1(_GetSystemTimeAsFileTime, uintptr(unsafe.Pointer(&ft)))
+
+ t := (ft - 116444736000000000) * 100
+
+ sec = t / 1000000000
+ nsec = int32(t - sec*1000000000)
+
+ mono = nanotimeQPC()
+ return
+}
+
+func initWine(k32 uintptr) {
+ _GetSystemTimeAsFileTime = windowsFindfunc(k32, []byte("GetSystemTimeAsFileTime\000"))
+ if _GetSystemTimeAsFileTime == nil {
+ throw("could not find GetSystemTimeAsFileTime() syscall")
+ }
+
+ _QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
+ _QueryPerformanceFrequency = windowsFindfunc(k32, []byte("QueryPerformanceFrequency\000"))
+ if _QueryPerformanceCounter == nil || _QueryPerformanceFrequency == nil {
+ throw("could not find QPC syscalls")
+ }
+
+ // We can not simply fallback to GetSystemTimeAsFileTime() syscall, since its time is not monotonic,
+ // instead we use QueryPerformanceCounter family of syscalls to implement monotonic timer
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
+
+ var tmp int64
+ stdcall1(_QueryPerformanceFrequency, uintptr(unsafe.Pointer(&tmp)))
+ if tmp == 0 {
+ throw("QueryPerformanceFrequency syscall returned zero, running on unsupported hardware")
+ }
+
+ // This should not overflow, it is a number of ticks of the performance counter per second,
+ // its resolution is at most 10 per usecond (on Wine, even smaller on real hardware), so it will be at most 10 millions here,
+ // panic if overflows.
+ if tmp > (1<<31 - 1) {
+ throw("QueryPerformanceFrequency overflow 32 bit divider, check nosplit discussion to proceed")
+ }
+ qpcFrequency := int32(tmp)
+ stdcall1(_QueryPerformanceCounter, uintptr(unsafe.Pointer(&qpcStartCounter)))
+
+ // Since we are supposed to run this time calls only on Wine, it does not lose precision,
+ // since Wine's timer is kind of emulated at 10 Mhz, so it will be a nice round multiplier of 100
+ // but for general purpose system (like 3.3 Mhz timer on i7) it will not be very precise.
+ // We have to do it this way (or similar), since multiplying QPC counter by 100 millions overflows
+ // int64 and resulted time will always be invalid.
+ qpcMultiplier = int64(timediv(1000000000, qpcFrequency, nil))
+
+ useQPCTime = 1
+}
+
+//go:nosplit
+func getRandomData(r []byte) {
+ n := 0
+ if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 {
+ n = len(r)
+ }
+ extendRandom(r, n)
+}
+
+func goenvs() {
+ // strings is a pointer to environment variable pairs in the form:
+ // "envA=valA\x00envB=valB\x00\x00" (in UTF-16)
+ // Two consecutive zero bytes end the list.
+ strings := unsafe.Pointer(stdcall0(_GetEnvironmentStringsW))
+ p := (*[1 << 24]uint16)(strings)[:]
+
+ n := 0
+ for from, i := 0, 0; true; i++ {
+ if p[i] == 0 {
+ // empty string marks the end
+ if i == from {
+ break
+ }
+ from = i + 1
+ n++
+ }
+ }
+ envs = make([]string, n)
+
+ for i := range envs {
+ envs[i] = gostringw(&p[0])
+ for p[0] != 0 {
+ p = p[1:]
+ }
+ p = p[1:] // skip nil byte
+ }
+
+ stdcall1(_FreeEnvironmentStringsW, uintptr(strings))
+
+ // We call these all the way here, late in init, so that malloc works
+ // for the callback functions these generate.
+ var fn any = ctrlHandler
+ ctrlHandlerPC := compileCallback(*efaceOf(&fn), true)
+ stdcall2(_SetConsoleCtrlHandler, ctrlHandlerPC, 1)
+
+ monitorSuspendResume()
+}
+
+// exiting is set to non-zero when the process is exiting.
+var exiting uint32
+
+//go:nosplit
+func exit(code int32) {
+ // Disallow thread suspension for preemption. Otherwise,
+ // ExitProcess and SuspendThread can race: SuspendThread
+ // queues a suspension request for this thread, ExitProcess
+ // kills the suspending thread, and then this thread suspends.
+ lock(&suspendLock)
+ atomic.Store(&exiting, 1)
+ stdcall1(_ExitProcess, uintptr(code))
+}
+
+// write1 must be nosplit because it's used as a last resort in
+// functions like badmorestackg0. In such cases, we'll always take the
+// ASCII path.
+//
+//go:nosplit
+func write1(fd uintptr, buf unsafe.Pointer, n int32) int32 {
+ const (
+ _STD_OUTPUT_HANDLE = ^uintptr(10) // -11
+ _STD_ERROR_HANDLE = ^uintptr(11) // -12
+ )
+ var handle uintptr
+ switch fd {
+ case 1:
+ handle = stdcall1(_GetStdHandle, _STD_OUTPUT_HANDLE)
+ case 2:
+ handle = stdcall1(_GetStdHandle, _STD_ERROR_HANDLE)
+ default:
+ // assume fd is real windows handle.
+ handle = fd
+ }
+ isASCII := true
+ b := (*[1 << 30]byte)(buf)[:n]
+ for _, x := range b {
+ if x >= 0x80 {
+ isASCII = false
+ break
+ }
+ }
+
+ if !isASCII {
+ var m uint32
+ isConsole := stdcall2(_GetConsoleMode, handle, uintptr(unsafe.Pointer(&m))) != 0
+ // If this is a console output, various non-unicode code pages can be in use.
+ // Use the dedicated WriteConsole call to ensure unicode is printed correctly.
+ if isConsole {
+ return int32(writeConsole(handle, buf, n))
+ }
+ }
+ var written uint32
+ stdcall5(_WriteFile, handle, uintptr(buf), uintptr(n), uintptr(unsafe.Pointer(&written)), 0)
+ return int32(written)
+}
+
+var (
+ utf16ConsoleBack [1000]uint16
+ utf16ConsoleBackLock mutex
+)
+
+// writeConsole writes bufLen bytes from buf to the console File.
+// It returns the number of bytes written.
+func writeConsole(handle uintptr, buf unsafe.Pointer, bufLen int32) int {
+ const surr2 = (surrogateMin + surrogateMax + 1) / 2
+
+ // Do not use defer for unlock. May cause issues when printing a panic.
+ lock(&utf16ConsoleBackLock)
+
+ b := (*[1 << 30]byte)(buf)[:bufLen]
+ s := *(*string)(unsafe.Pointer(&b))
+
+ utf16tmp := utf16ConsoleBack[:]
+
+ total := len(s)
+ w := 0
+ for _, r := range s {
+ if w >= len(utf16tmp)-2 {
+ writeConsoleUTF16(handle, utf16tmp[:w])
+ w = 0
+ }
+ if r < 0x10000 {
+ utf16tmp[w] = uint16(r)
+ w++
+ } else {
+ r -= 0x10000
+ utf16tmp[w] = surrogateMin + uint16(r>>10)&0x3ff
+ utf16tmp[w+1] = surr2 + uint16(r)&0x3ff
+ w += 2
+ }
+ }
+ writeConsoleUTF16(handle, utf16tmp[:w])
+ unlock(&utf16ConsoleBackLock)
+ return total
+}
+
+// writeConsoleUTF16 is the dedicated windows calls that correctly prints
+// to the console regardless of the current code page. Input is utf-16 code points.
+// The handle must be a console handle.
+func writeConsoleUTF16(handle uintptr, b []uint16) {
+ l := uint32(len(b))
+ if l == 0 {
+ return
+ }
+ var written uint32
+ stdcall5(_WriteConsoleW,
+ handle,
+ uintptr(unsafe.Pointer(&b[0])),
+ uintptr(l),
+ uintptr(unsafe.Pointer(&written)),
+ 0,
+ )
+ return
+}
+
+//go:nosplit
+func semasleep(ns int64) int32 {
+ const (
+ _WAIT_ABANDONED = 0x00000080
+ _WAIT_OBJECT_0 = 0x00000000
+ _WAIT_TIMEOUT = 0x00000102
+ _WAIT_FAILED = 0xFFFFFFFF
+ )
+
+ var result uintptr
+ if ns < 0 {
+ result = stdcall2(_WaitForSingleObject, getg().m.waitsema, uintptr(_INFINITE))
+ } else {
+ start := nanotime()
+ elapsed := int64(0)
+ for {
+ ms := int64(timediv(ns-elapsed, 1000000, nil))
+ if ms == 0 {
+ ms = 1
+ }
+ result = stdcall4(_WaitForMultipleObjects, 2,
+ uintptr(unsafe.Pointer(&[2]uintptr{getg().m.waitsema, getg().m.resumesema})),
+ 0, uintptr(ms))
+ if result != _WAIT_OBJECT_0+1 {
+ // Not a suspend/resume event
+ break
+ }
+ elapsed = nanotime() - start
+ if elapsed >= ns {
+ return -1
+ }
+ }
+ }
+ switch result {
+ case _WAIT_OBJECT_0: // Signaled
+ return 0
+
+ case _WAIT_TIMEOUT:
+ return -1
+
+ case _WAIT_ABANDONED:
+ systemstack(func() {
+ throw("runtime.semasleep wait_abandoned")
+ })
+
+ case _WAIT_FAILED:
+ systemstack(func() {
+ print("runtime: waitforsingleobject wait_failed; errno=", getlasterror(), "\n")
+ throw("runtime.semasleep wait_failed")
+ })
+
+ default:
+ systemstack(func() {
+ print("runtime: waitforsingleobject unexpected; result=", result, "\n")
+ throw("runtime.semasleep unexpected")
+ })
+ }
+
+ return -1 // unreachable
+}
+
+//go:nosplit
+func semawakeup(mp *m) {
+ if stdcall1(_SetEvent, mp.waitsema) == 0 {
+ systemstack(func() {
+ print("runtime: setevent failed; errno=", getlasterror(), "\n")
+ throw("runtime.semawakeup")
+ })
+ }
+}
+
+//go:nosplit
+func semacreate(mp *m) {
+ if mp.waitsema != 0 {
+ return
+ }
+ mp.waitsema = stdcall4(_CreateEventA, 0, 0, 0, 0)
+ if mp.waitsema == 0 {
+ systemstack(func() {
+ print("runtime: createevent failed; errno=", getlasterror(), "\n")
+ throw("runtime.semacreate")
+ })
+ }
+ mp.resumesema = stdcall4(_CreateEventA, 0, 0, 0, 0)
+ if mp.resumesema == 0 {
+ systemstack(func() {
+ print("runtime: createevent failed; errno=", getlasterror(), "\n")
+ throw("runtime.semacreate")
+ })
+ stdcall1(_CloseHandle, mp.waitsema)
+ mp.waitsema = 0
+ }
+}
+
+// May run with m.p==nil, so write barriers are not allowed. This
+// function is called by newosproc0, so it is also required to
+// operate without stack guards.
+//
+//go:nowritebarrierrec
+//go:nosplit
+func newosproc(mp *m) {
+ // We pass 0 for the stack size to use the default for this binary.
+ thandle := stdcall6(_CreateThread, 0, 0,
+ abi.FuncPCABI0(tstart_stdcall), uintptr(unsafe.Pointer(mp)),
+ 0, 0)
+
+ if thandle == 0 {
+ if atomic.Load(&exiting) != 0 {
+ // CreateThread may fail if called
+ // concurrently with ExitProcess. If this
+ // happens, just freeze this thread and let
+ // the process exit. See issue #18253.
+ lock(&deadlock)
+ lock(&deadlock)
+ }
+ print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", getlasterror(), ")\n")
+ throw("runtime.newosproc")
+ }
+
+ // Close thandle to avoid leaking the thread object if it exits.
+ stdcall1(_CloseHandle, thandle)
+}
+
+// Used by the C library build mode. On Linux this function would allocate a
+// stack, but that's not necessary for Windows. No stack guards are present
+// and the GC has not been initialized, so write barriers will fail.
+//
+//go:nowritebarrierrec
+//go:nosplit
+func newosproc0(mp *m, stk unsafe.Pointer) {
+ // TODO: this is completely broken. The args passed to newosproc0 (in asm_amd64.s)
+ // are stacksize and function, not *m and stack.
+ // Check os_linux.go for an implementation that might actually work.
+ throw("bad newosproc0")
+}
+
+func exitThread(wait *atomic.Uint32) {
+ // We should never reach exitThread on Windows because we let
+ // the OS clean up threads.
+ throw("exitThread")
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+func mpreinit(mp *m) {
+}
+
+//go:nosplit
+func sigsave(p *sigset) {
+}
+
+//go:nosplit
+func msigrestore(sigmask sigset) {
+}
+
+//go:nosplit
+//go:nowritebarrierrec
+func clearSignalHandlers() {
+}
+
+//go:nosplit
+func sigblock(exiting bool) {
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, cannot allocate memory.
+func minit() {
+ var thandle uintptr
+ if stdcall7(_DuplicateHandle, currentProcess, currentThread, currentProcess, uintptr(unsafe.Pointer(&thandle)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
+ print("runtime.minit: duplicatehandle failed; errno=", getlasterror(), "\n")
+ throw("runtime.minit: duplicatehandle failed")
+ }
+
+ mp := getg().m
+ lock(&mp.threadLock)
+ mp.thread = thandle
+ mp.procid = uint64(stdcall0(_GetCurrentThreadId))
+
+ // Configure usleep timer, if possible.
+ if mp.highResTimer == 0 && haveHighResTimer {
+ mp.highResTimer = createHighResTimer()
+ if mp.highResTimer == 0 {
+ print("runtime: CreateWaitableTimerEx failed; errno=", getlasterror(), "\n")
+ throw("CreateWaitableTimerEx when creating timer failed")
+ }
+ }
+ unlock(&mp.threadLock)
+
+ // Query the true stack base from the OS. Currently we're
+ // running on a small assumed stack.
+ var mbi memoryBasicInformation
+ res := stdcall3(_VirtualQuery, uintptr(unsafe.Pointer(&mbi)), uintptr(unsafe.Pointer(&mbi)), unsafe.Sizeof(mbi))
+ if res == 0 {
+ print("runtime: VirtualQuery failed; errno=", getlasterror(), "\n")
+ throw("VirtualQuery for stack base failed")
+ }
+ // The system leaves an 8K PAGE_GUARD region at the bottom of
+ // the stack (in theory VirtualQuery isn't supposed to include
+ // that, but it does). Add an additional 8K of slop for
+ // calling C functions that don't have stack checks and for
+ // lastcontinuehandler. We shouldn't be anywhere near this
+ // bound anyway.
+ base := mbi.allocationBase + 16<<10
+ // Sanity check the stack bounds.
+ g0 := getg()
+ if base > g0.stack.hi || g0.stack.hi-base > 64<<20 {
+ print("runtime: g0 stack [", hex(base), ",", hex(g0.stack.hi), ")\n")
+ throw("bad g0 stack")
+ }
+ g0.stack.lo = base
+ g0.stackguard0 = g0.stack.lo + stackGuard
+ g0.stackguard1 = g0.stackguard0
+ // Sanity check the SP.
+ stackcheck()
+}
+
+// Called from dropm to undo the effect of an minit.
+//
+//go:nosplit
+func unminit() {
+ mp := getg().m
+ lock(&mp.threadLock)
+ if mp.thread != 0 {
+ stdcall1(_CloseHandle, mp.thread)
+ mp.thread = 0
+ }
+ unlock(&mp.threadLock)
+}
+
+// Called from exitm, but not from drop, to undo the effect of thread-owned
+// resources in minit, semacreate, or elsewhere. Do not take locks after calling this.
+//
+//go:nosplit
+func mdestroy(mp *m) {
+ if mp.highResTimer != 0 {
+ stdcall1(_CloseHandle, mp.highResTimer)
+ mp.highResTimer = 0
+ }
+ if mp.waitsema != 0 {
+ stdcall1(_CloseHandle, mp.waitsema)
+ mp.waitsema = 0
+ }
+ if mp.resumesema != 0 {
+ stdcall1(_CloseHandle, mp.resumesema)
+ mp.resumesema = 0
+ }
+}
+
+// Calling stdcall on os stack.
+// May run during STW, so write barriers are not allowed.
+//
+//go:nowritebarrier
+//go:nosplit
+func stdcall(fn stdFunction) uintptr {
+ gp := getg()
+ mp := gp.m
+ mp.libcall.fn = uintptr(unsafe.Pointer(fn))
+ resetLibcall := false
+ if mp.profilehz != 0 && mp.libcallsp == 0 {
+ // leave pc/sp for cpu profiler
+ mp.libcallg.set(gp)
+ mp.libcallpc = getcallerpc()
+ // sp must be the last, because once async cpu profiler finds
+ // all three values to be non-zero, it will use them
+ mp.libcallsp = getcallersp()
+ resetLibcall = true // See comment in sys_darwin.go:libcCall
+ }
+ asmcgocall(asmstdcallAddr, unsafe.Pointer(&mp.libcall))
+ if resetLibcall {
+ mp.libcallsp = 0
+ }
+ return mp.libcall.r1
+}
+
+//go:nosplit
+func stdcall0(fn stdFunction) uintptr {
+ mp := getg().m
+ mp.libcall.n = 0
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&fn))) // it's unused but must be non-nil, otherwise crashes
+ return stdcall(fn)
+}
+
+//go:nosplit
+//go:cgo_unsafe_args
+func stdcall1(fn stdFunction, a0 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 1
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+//go:nosplit
+//go:cgo_unsafe_args
+func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 2
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+//go:nosplit
+//go:cgo_unsafe_args
+func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 3
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+//go:nosplit
+//go:cgo_unsafe_args
+func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 4
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+//go:nosplit
+//go:cgo_unsafe_args
+func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 5
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+//go:nosplit
+//go:cgo_unsafe_args
+func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 6
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+//go:nosplit
+//go:cgo_unsafe_args
+func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
+ mp := getg().m
+ mp.libcall.n = 7
+ mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
+ return stdcall(fn)
+}
+
+// These must run on the system stack only.
+func usleep2(dt int32)
+func switchtothread()
+
+//go:nosplit
+func osyield_no_g() {
+ switchtothread()
+}
+
+//go:nosplit
+func osyield() {
+ systemstack(switchtothread)
+}
+
+//go:nosplit
+func usleep_no_g(us uint32) {
+ dt := -10 * int32(us) // relative sleep (negative), 100ns units
+ usleep2(dt)
+}
+
+//go:nosplit
+func usleep(us uint32) {
+ systemstack(func() {
+ dt := -10 * int64(us) // relative sleep (negative), 100ns units
+ // If the high-res timer is available and its handle has been allocated for this m, use it.
+ // Otherwise fall back to the low-res one, which doesn't need a handle.
+ if haveHighResTimer && getg().m.highResTimer != 0 {
+ h := getg().m.highResTimer
+ stdcall6(_SetWaitableTimer, h, uintptr(unsafe.Pointer(&dt)), 0, 0, 0, 0)
+ stdcall3(_NtWaitForSingleObject, h, 0, 0)
+ } else {
+ usleep2(int32(dt))
+ }
+ })
+}
+
+func ctrlHandler(_type uint32) uintptr {
+ var s uint32
+
+ switch _type {
+ case _CTRL_C_EVENT, _CTRL_BREAK_EVENT:
+ s = _SIGINT
+ case _CTRL_CLOSE_EVENT, _CTRL_LOGOFF_EVENT, _CTRL_SHUTDOWN_EVENT:
+ s = _SIGTERM
+ default:
+ return 0
+ }
+
+ if sigsend(s) {
+ if s == _SIGTERM {
+ // Windows terminates the process after this handler returns.
+ // Block indefinitely to give signal handlers a chance to clean up,
+ // but make sure to be properly parked first, so the rest of the
+ // program can continue executing.
+ block()
+ }
+ return 1
+ }
+ return 0
+}
+
+// called from zcallback_windows_*.s to sys_windows_*.s
+func callbackasm1()
+
+var profiletimer uintptr
+
+func profilem(mp *m, thread uintptr) {
+ // Align Context to 16 bytes.
+ var c *context
+ var cbuf [unsafe.Sizeof(*c) + 15]byte
+ c = (*context)(unsafe.Pointer((uintptr(unsafe.Pointer(&cbuf[15]))) &^ 15))
+
+ c.contextflags = _CONTEXT_CONTROL
+ stdcall2(_GetThreadContext, thread, uintptr(unsafe.Pointer(c)))
+
+ gp := gFromSP(mp, c.sp())
+
+ sigprof(c.ip(), c.sp(), c.lr(), gp, mp)
+}
+
+func gFromSP(mp *m, sp uintptr) *g {
+ if gp := mp.g0; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
+ return gp
+ }
+ if gp := mp.gsignal; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
+ return gp
+ }
+ if gp := mp.curg; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
+ return gp
+ }
+ return nil
+}
+
+func profileLoop() {
+ stdcall2(_SetThreadPriority, currentThread, _THREAD_PRIORITY_HIGHEST)
+
+ for {
+ stdcall2(_WaitForSingleObject, profiletimer, _INFINITE)
+ first := (*m)(atomic.Loadp(unsafe.Pointer(&allm)))
+ for mp := first; mp != nil; mp = mp.alllink {
+ if mp == getg().m {
+ // Don't profile ourselves.
+ continue
+ }
+
+ lock(&mp.threadLock)
+ // Do not profile threads blocked on Notes,
+ // this includes idle worker threads,
+ // idle timer thread, idle heap scavenger, etc.
+ if mp.thread == 0 || mp.profilehz == 0 || mp.blocked {
+ unlock(&mp.threadLock)
+ continue
+ }
+ // Acquire our own handle to the thread.
+ var thread uintptr
+ if stdcall7(_DuplicateHandle, currentProcess, mp.thread, currentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
+ print("runtime: duplicatehandle failed; errno=", getlasterror(), "\n")
+ throw("duplicatehandle failed")
+ }
+ unlock(&mp.threadLock)
+
+ // mp may exit between the DuplicateHandle
+ // above and the SuspendThread. The handle
+ // will remain valid, but SuspendThread may
+ // fail.
+ if int32(stdcall1(_SuspendThread, thread)) == -1 {
+ // The thread no longer exists.
+ stdcall1(_CloseHandle, thread)
+ continue
+ }
+ if mp.profilehz != 0 && !mp.blocked {
+ // Pass the thread handle in case mp
+ // was in the process of shutting down.
+ profilem(mp, thread)
+ }
+ stdcall1(_ResumeThread, thread)
+ stdcall1(_CloseHandle, thread)
+ }
+ }
+}
+
+func setProcessCPUProfiler(hz int32) {
+ if profiletimer == 0 {
+ timer := stdcall3(_CreateWaitableTimerA, 0, 0, 0)
+ atomic.Storeuintptr(&profiletimer, timer)
+ newm(profileLoop, nil, -1)
+ }
+}
+
+func setThreadCPUProfiler(hz int32) {
+ ms := int32(0)
+ due := ^int64(^uint64(1 << 63))
+ if hz > 0 {
+ ms = 1000 / hz
+ if ms == 0 {
+ ms = 1
+ }
+ due = int64(ms) * -10000
+ }
+ stdcall6(_SetWaitableTimer, profiletimer, uintptr(unsafe.Pointer(&due)), uintptr(ms), 0, 0, 0)
+ atomic.Store((*uint32)(unsafe.Pointer(&getg().m.profilehz)), uint32(hz))
+}
+
+const preemptMSupported = true
+
+// suspendLock protects simultaneous SuspendThread operations from
+// suspending each other.
+var suspendLock mutex
+
+func preemptM(mp *m) {
+ if mp == getg().m {
+ throw("self-preempt")
+ }
+
+ // Synchronize with external code that may try to ExitProcess.
+ if !atomic.Cas(&mp.preemptExtLock, 0, 1) {
+ // External code is running. Fail the preemption
+ // attempt.
+ mp.preemptGen.Add(1)
+ return
+ }
+
+ // Acquire our own handle to mp's thread.
+ lock(&mp.threadLock)
+ if mp.thread == 0 {
+ // The M hasn't been minit'd yet (or was just unminit'd).
+ unlock(&mp.threadLock)
+ atomic.Store(&mp.preemptExtLock, 0)
+ mp.preemptGen.Add(1)
+ return
+ }
+ var thread uintptr
+ if stdcall7(_DuplicateHandle, currentProcess, mp.thread, currentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
+ print("runtime.preemptM: duplicatehandle failed; errno=", getlasterror(), "\n")
+ throw("runtime.preemptM: duplicatehandle failed")
+ }
+ unlock(&mp.threadLock)
+
+ // Prepare thread context buffer. This must be aligned to 16 bytes.
+ var c *context
+ var cbuf [unsafe.Sizeof(*c) + 15]byte
+ c = (*context)(unsafe.Pointer((uintptr(unsafe.Pointer(&cbuf[15]))) &^ 15))
+ c.contextflags = _CONTEXT_CONTROL
+
+ // Serialize thread suspension. SuspendThread is asynchronous,
+ // so it's otherwise possible for two threads to suspend each
+ // other and deadlock. We must hold this lock until after
+ // GetThreadContext, since that blocks until the thread is
+ // actually suspended.
+ lock(&suspendLock)
+
+ // Suspend the thread.
+ if int32(stdcall1(_SuspendThread, thread)) == -1 {
+ unlock(&suspendLock)
+ stdcall1(_CloseHandle, thread)
+ atomic.Store(&mp.preemptExtLock, 0)
+ // The thread no longer exists. This shouldn't be
+ // possible, but just acknowledge the request.
+ mp.preemptGen.Add(1)
+ return
+ }
+
+ // We have to be very careful between this point and once
+ // we've shown mp is at an async safe-point. This is like a
+ // signal handler in the sense that mp could have been doing
+ // anything when we stopped it, including holding arbitrary
+ // locks.
+
+ // We have to get the thread context before inspecting the M
+ // because SuspendThread only requests a suspend.
+ // GetThreadContext actually blocks until it's suspended.
+ stdcall2(_GetThreadContext, thread, uintptr(unsafe.Pointer(c)))
+
+ unlock(&suspendLock)
+
+ // Does it want a preemption and is it safe to preempt?
+ gp := gFromSP(mp, c.sp())
+ if gp != nil && wantAsyncPreempt(gp) {
+ if ok, newpc := isAsyncSafePoint(gp, c.ip(), c.sp(), c.lr()); ok {
+ // Inject call to asyncPreempt
+ targetPC := abi.FuncPCABI0(asyncPreempt)
+ switch GOARCH {
+ default:
+ throw("unsupported architecture")
+ case "386", "amd64":
+ // Make it look like the thread called targetPC.
+ sp := c.sp()
+ sp -= goarch.PtrSize
+ *(*uintptr)(unsafe.Pointer(sp)) = newpc
+ c.set_sp(sp)
+ c.set_ip(targetPC)
+
+ case "arm":
+ // Push LR. The injected call is responsible
+ // for restoring LR. gentraceback is aware of
+ // this extra slot. See sigctxt.pushCall in
+ // signal_arm.go, which is similar except we
+ // subtract 1 from IP here.
+ sp := c.sp()
+ sp -= goarch.PtrSize
+ c.set_sp(sp)
+ *(*uint32)(unsafe.Pointer(sp)) = uint32(c.lr())
+ c.set_lr(newpc - 1)
+ c.set_ip(targetPC)
+
+ case "arm64":
+ // Push LR. The injected call is responsible
+ // for restoring LR. gentraceback is aware of
+ // this extra slot. See sigctxt.pushCall in
+ // signal_arm64.go.
+ sp := c.sp() - 16 // SP needs 16-byte alignment
+ c.set_sp(sp)
+ *(*uint64)(unsafe.Pointer(sp)) = uint64(c.lr())
+ c.set_lr(newpc)
+ c.set_ip(targetPC)
+ }
+ stdcall2(_SetThreadContext, thread, uintptr(unsafe.Pointer(c)))
+ }
+ }
+
+ atomic.Store(&mp.preemptExtLock, 0)
+
+ // Acknowledge the preemption.
+ mp.preemptGen.Add(1)
+
+ stdcall1(_ResumeThread, thread)
+ stdcall1(_CloseHandle, thread)
+}
+
+// osPreemptExtEnter is called before entering external code that may
+// call ExitProcess.
+//
+// This must be nosplit because it may be called from a syscall with
+// untyped stack slots, so the stack must not be grown or scanned.
+//
+//go:nosplit
+func osPreemptExtEnter(mp *m) {
+ for !atomic.Cas(&mp.preemptExtLock, 0, 1) {
+ // An asynchronous preemption is in progress. It's not
+ // safe to enter external code because it may call
+ // ExitProcess and deadlock with SuspendThread.
+ // Ideally we would do the preemption ourselves, but
+ // can't since there may be untyped syscall arguments
+ // on the stack. Instead, just wait and encourage the
+ // SuspendThread APC to run. The preemption should be
+ // done shortly.
+ osyield()
+ }
+ // Asynchronous preemption is now blocked.
+}
+
+// osPreemptExtExit is called after returning from external code that
+// may call ExitProcess.
+//
+// See osPreemptExtEnter for why this is nosplit.
+//
+//go:nosplit
+func osPreemptExtExit(mp *m) {
+ atomic.Store(&mp.preemptExtLock, 0)
+}
diff --git a/contrib/go/_std_1.20/src/runtime/pagetrace_off.go b/contrib/go/_std_1.21/src/runtime/pagetrace_off.go
index 10b44d40ce..10b44d40ce 100644
--- a/contrib/go/_std_1.20/src/runtime/pagetrace_off.go
+++ b/contrib/go/_std_1.21/src/runtime/pagetrace_off.go
diff --git a/contrib/go/_std_1.21/src/runtime/panic.go b/contrib/go/_std_1.21/src/runtime/panic.go
new file mode 100644
index 0000000000..39c27a4478
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/panic.go
@@ -0,0 +1,1419 @@
+// Copyright 2014 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// throwType indicates the current type of ongoing throw, which affects the
+// amount of detail printed to stderr. Higher values include more detail.
+type throwType uint32
+
+const (
+ // throwTypeNone means that we are not throwing.
+ throwTypeNone throwType = iota
+
+ // throwTypeUser is a throw due to a problem with the application.
+ //
+ // These throws do not include runtime frames, system goroutines, or
+ // frame metadata.
+ throwTypeUser
+
+ // throwTypeRuntime is a throw due to a problem with Go itself.
+ //
+ // These throws include as much information as possible to aid in
+ // debugging the runtime, including runtime frames, system goroutines,
+ // and frame metadata.
+ throwTypeRuntime
+)
+
+// We have two different ways of doing defers. The older way involves creating a
+// defer record at the time that a defer statement is executing and adding it to a
+// defer chain. This chain is inspected by the deferreturn call at all function
+// exits in order to run the appropriate defer calls. A cheaper way (which we call
+// open-coded defers) is used for functions in which no defer statements occur in
+// loops. In that case, we simply store the defer function/arg information into
+// specific stack slots at the point of each defer statement, as well as setting a
+// bit in a bitmask. At each function exit, we add inline code to directly make
+// the appropriate defer calls based on the bitmask and fn/arg information stored
+// on the stack. During panic/Goexit processing, the appropriate defer calls are
+// made using extra funcdata info that indicates the exact stack slots that
+// contain the bitmask and defer fn/args.
+
+// Check to make sure we can really generate a panic. If the panic
+// was generated from the runtime, or from inside malloc, then convert
+// to a throw of msg.
+// pc should be the program counter of the compiler-generated code that
+// triggered this panic.
+func panicCheck1(pc uintptr, msg string) {
+ if goarch.IsWasm == 0 && hasPrefix(funcname(findfunc(pc)), "runtime.") {
+ // Note: wasm can't tail call, so we can't get the original caller's pc.
+ throw(msg)
+ }
+ // TODO: is this redundant? How could we be in malloc
+ // but not in the runtime? runtime/internal/*, maybe?
+ gp := getg()
+ if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
+ throw(msg)
+ }
+}
+
+// Same as above, but calling from the runtime is allowed.
+//
+// Using this function is necessary for any panic that may be
+// generated by runtime.sigpanic, since those are always called by the
+// runtime.
+func panicCheck2(err string) {
+ // panic allocates, so to avoid recursive malloc, turn panics
+ // during malloc into throws.
+ gp := getg()
+ if gp != nil && gp.m != nil && gp.m.mallocing != 0 {
+ throw(err)
+ }
+}
+
+// Many of the following panic entry-points turn into throws when they
+// happen in various runtime contexts. These should never happen in
+// the runtime, and if they do, they indicate a serious issue and
+// should not be caught by user code.
+//
+// The panic{Index,Slice,divide,shift} functions are called by
+// code generated by the compiler for out of bounds index expressions,
+// out of bounds slice expressions, division by zero, and shift by negative.
+// The panicdivide (again), panicoverflow, panicfloat, and panicmem
+// functions are called by the signal handler when a signal occurs
+// indicating the respective problem.
+//
+// Since panic{Index,Slice,shift} are never called directly, and
+// since the runtime package should never have an out of bounds slice
+// or array reference or negative shift, if we see those functions called from the
+// runtime package we turn the panic into a throw. That will dump the
+// entire runtime stack for easier debugging.
+//
+// The entry points called by the signal handler will be called from
+// runtime.sigpanic, so we can't disallow calls from the runtime to
+// these (they always look like they're called from the runtime).
+// Hence, for these, we just check for clearly bad runtime conditions.
+//
+// The panic{Index,Slice} functions are implemented in assembly and tail call
+// to the goPanic{Index,Slice} functions below. This is done so we can use
+// a space-minimal register calling convention.
+
+// failures in the comparisons for s[x], 0 <= x < y (y == len(s))
+//
+//go:yeswritebarrierrec
+func goPanicIndex(x int, y int) {
+ panicCheck1(getcallerpc(), "index out of range")
+ panic(boundsError{x: int64(x), signed: true, y: y, code: boundsIndex})
+}
+
+//go:yeswritebarrierrec
+func goPanicIndexU(x uint, y int) {
+ panicCheck1(getcallerpc(), "index out of range")
+ panic(boundsError{x: int64(x), signed: false, y: y, code: boundsIndex})
+}
+
+// failures in the comparisons for s[:x], 0 <= x <= y (y == len(s) or cap(s))
+//
+//go:yeswritebarrierrec
+func goPanicSliceAlen(x int, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceAlen})
+}
+
+//go:yeswritebarrierrec
+func goPanicSliceAlenU(x uint, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceAlen})
+}
+
+//go:yeswritebarrierrec
+func goPanicSliceAcap(x int, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceAcap})
+}
+
+//go:yeswritebarrierrec
+func goPanicSliceAcapU(x uint, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceAcap})
+}
+
+// failures in the comparisons for s[x:y], 0 <= x <= y
+//
+//go:yeswritebarrierrec
+func goPanicSliceB(x int, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceB})
+}
+
+//go:yeswritebarrierrec
+func goPanicSliceBU(x uint, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceB})
+}
+
+// failures in the comparisons for s[::x], 0 <= x <= y (y == len(s) or cap(s))
+func goPanicSlice3Alen(x int, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3Alen})
+}
+func goPanicSlice3AlenU(x uint, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3Alen})
+}
+func goPanicSlice3Acap(x int, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3Acap})
+}
+func goPanicSlice3AcapU(x uint, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3Acap})
+}
+
+// failures in the comparisons for s[:x:y], 0 <= x <= y
+func goPanicSlice3B(x int, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3B})
+}
+func goPanicSlice3BU(x uint, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3B})
+}
+
+// failures in the comparisons for s[x:y:], 0 <= x <= y
+func goPanicSlice3C(x int, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3C})
+}
+func goPanicSlice3CU(x uint, y int) {
+ panicCheck1(getcallerpc(), "slice bounds out of range")
+ panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3C})
+}
+
+// failures in the conversion ([x]T)(s) or (*[x]T)(s), 0 <= x <= y, y == len(s)
+func goPanicSliceConvert(x int, y int) {
+ panicCheck1(getcallerpc(), "slice length too short to convert to array or pointer to array")
+ panic(boundsError{x: int64(x), signed: true, y: y, code: boundsConvert})
+}
+
+// Implemented in assembly, as they take arguments in registers.
+// Declared here to mark them as ABIInternal.
+func panicIndex(x int, y int)
+func panicIndexU(x uint, y int)
+func panicSliceAlen(x int, y int)
+func panicSliceAlenU(x uint, y int)
+func panicSliceAcap(x int, y int)
+func panicSliceAcapU(x uint, y int)
+func panicSliceB(x int, y int)
+func panicSliceBU(x uint, y int)
+func panicSlice3Alen(x int, y int)
+func panicSlice3AlenU(x uint, y int)
+func panicSlice3Acap(x int, y int)
+func panicSlice3AcapU(x uint, y int)
+func panicSlice3B(x int, y int)
+func panicSlice3BU(x uint, y int)
+func panicSlice3C(x int, y int)
+func panicSlice3CU(x uint, y int)
+func panicSliceConvert(x int, y int)
+
+var shiftError = error(errorString("negative shift amount"))
+
+//go:yeswritebarrierrec
+func panicshift() {
+ panicCheck1(getcallerpc(), "negative shift amount")
+ panic(shiftError)
+}
+
+var divideError = error(errorString("integer divide by zero"))
+
+//go:yeswritebarrierrec
+func panicdivide() {
+ panicCheck2("integer divide by zero")
+ panic(divideError)
+}
+
+var overflowError = error(errorString("integer overflow"))
+
+func panicoverflow() {
+ panicCheck2("integer overflow")
+ panic(overflowError)
+}
+
+var floatError = error(errorString("floating point error"))
+
+func panicfloat() {
+ panicCheck2("floating point error")
+ panic(floatError)
+}
+
+var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
+
+func panicmem() {
+ panicCheck2("invalid memory address or nil pointer dereference")
+ panic(memoryError)
+}
+
+func panicmemAddr(addr uintptr) {
+ panicCheck2("invalid memory address or nil pointer dereference")
+ panic(errorAddressString{msg: "invalid memory address or nil pointer dereference", addr: addr})
+}
+
+// Create a new deferred function fn, which has no arguments and results.
+// The compiler turns a defer statement into a call to this.
+func deferproc(fn func()) {
+ gp := getg()
+ if gp.m.curg != gp {
+ // go code on the system stack can't defer
+ throw("defer on system stack")
+ }
+
+ d := newdefer()
+ if d._panic != nil {
+ throw("deferproc: d.panic != nil after newdefer")
+ }
+ d.link = gp._defer
+ gp._defer = d
+ d.fn = fn
+ d.pc = getcallerpc()
+ // We must not be preempted between calling getcallersp and
+ // storing it to d.sp because getcallersp's result is a
+ // uintptr stack pointer.
+ d.sp = getcallersp()
+
+ // deferproc returns 0 normally.
+ // a deferred func that stops a panic
+ // makes the deferproc return 1.
+ // the code the compiler generates always
+ // checks the return value and jumps to the
+ // end of the function if deferproc returns != 0.
+ return0()
+ // No code can go here - the C return register has
+ // been set and must not be clobbered.
+}
+
+// deferprocStack queues a new deferred function with a defer record on the stack.
+// The defer record must have its fn field initialized.
+// All other fields can contain junk.
+// Nosplit because of the uninitialized pointer fields on the stack.
+//
+//go:nosplit
+func deferprocStack(d *_defer) {
+ gp := getg()
+ if gp.m.curg != gp {
+ // go code on the system stack can't defer
+ throw("defer on system stack")
+ }
+ // fn is already set.
+ // The other fields are junk on entry to deferprocStack and
+ // are initialized here.
+ d.started = false
+ d.heap = false
+ d.openDefer = false
+ d.sp = getcallersp()
+ d.pc = getcallerpc()
+ d.framepc = 0
+ d.varp = 0
+ // The lines below implement:
+ // d.panic = nil
+ // d.fd = nil
+ // d.link = gp._defer
+ // gp._defer = d
+ // But without write barriers. The first three are writes to
+ // the stack so they don't need a write barrier, and furthermore
+ // are to uninitialized memory, so they must not use a write barrier.
+ // The fourth write does not require a write barrier because we
+ // explicitly mark all the defer structures, so we don't need to
+ // keep track of pointers to them with a write barrier.
+ *(*uintptr)(unsafe.Pointer(&d._panic)) = 0
+ *(*uintptr)(unsafe.Pointer(&d.fd)) = 0
+ *(*uintptr)(unsafe.Pointer(&d.link)) = uintptr(unsafe.Pointer(gp._defer))
+ *(*uintptr)(unsafe.Pointer(&gp._defer)) = uintptr(unsafe.Pointer(d))
+
+ return0()
+ // No code can go here - the C return register has
+ // been set and must not be clobbered.
+}
+
+// Each P holds a pool for defers.
+
+// Allocate a Defer, usually using per-P pool.
+// Each defer must be released with freedefer. The defer is not
+// added to any defer chain yet.
+func newdefer() *_defer {
+ var d *_defer
+ mp := acquirem()
+ pp := mp.p.ptr()
+ if len(pp.deferpool) == 0 && sched.deferpool != nil {
+ lock(&sched.deferlock)
+ for len(pp.deferpool) < cap(pp.deferpool)/2 && sched.deferpool != nil {
+ d := sched.deferpool
+ sched.deferpool = d.link
+ d.link = nil
+ pp.deferpool = append(pp.deferpool, d)
+ }
+ unlock(&sched.deferlock)
+ }
+ if n := len(pp.deferpool); n > 0 {
+ d = pp.deferpool[n-1]
+ pp.deferpool[n-1] = nil
+ pp.deferpool = pp.deferpool[:n-1]
+ }
+ releasem(mp)
+ mp, pp = nil, nil
+
+ if d == nil {
+ // Allocate new defer.
+ d = new(_defer)
+ }
+ d.heap = true
+ return d
+}
+
+// Free the given defer.
+// The defer cannot be used after this call.
+//
+// This is nosplit because the incoming defer is in a perilous state.
+// It's not on any defer list, so stack copying won't adjust stack
+// pointers in it (namely, d.link). Hence, if we were to copy the
+// stack, d could then contain a stale pointer.
+//
+//go:nosplit
+func freedefer(d *_defer) {
+ d.link = nil
+ // After this point we can copy the stack.
+
+ if d._panic != nil {
+ freedeferpanic()
+ }
+ if d.fn != nil {
+ freedeferfn()
+ }
+ if !d.heap {
+ return
+ }
+
+ mp := acquirem()
+ pp := mp.p.ptr()
+ if len(pp.deferpool) == cap(pp.deferpool) {
+ // Transfer half of local cache to the central cache.
+ var first, last *_defer
+ for len(pp.deferpool) > cap(pp.deferpool)/2 {
+ n := len(pp.deferpool)
+ d := pp.deferpool[n-1]
+ pp.deferpool[n-1] = nil
+ pp.deferpool = pp.deferpool[:n-1]
+ if first == nil {
+ first = d
+ } else {
+ last.link = d
+ }
+ last = d
+ }
+ lock(&sched.deferlock)
+ last.link = sched.deferpool
+ sched.deferpool = first
+ unlock(&sched.deferlock)
+ }
+
+ *d = _defer{}
+
+ pp.deferpool = append(pp.deferpool, d)
+
+ releasem(mp)
+ mp, pp = nil, nil
+}
+
+// Separate function so that it can split stack.
+// Windows otherwise runs out of stack space.
+func freedeferpanic() {
+ // _panic must be cleared before d is unlinked from gp.
+ throw("freedefer with d._panic != nil")
+}
+
+func freedeferfn() {
+ // fn must be cleared before d is unlinked from gp.
+ throw("freedefer with d.fn != nil")
+}
+
+// deferreturn runs deferred functions for the caller's frame.
+// The compiler inserts a call to this at the end of any
+// function which calls defer.
+func deferreturn() {
+ gp := getg()
+ for {
+ d := gp._defer
+ if d == nil {
+ return
+ }
+ sp := getcallersp()
+ if d.sp != sp {
+ return
+ }
+ if d.openDefer {
+ done := runOpenDeferFrame(d)
+ if !done {
+ throw("unfinished open-coded defers in deferreturn")
+ }
+ gp._defer = d.link
+ freedefer(d)
+ // If this frame uses open defers, then this
+ // must be the only defer record for the
+ // frame, so we can just return.
+ return
+ }
+
+ fn := d.fn
+ d.fn = nil
+ gp._defer = d.link
+ freedefer(d)
+ fn()
+ }
+}
+
+// Goexit terminates the goroutine that calls it. No other goroutine is affected.
+// Goexit runs all deferred calls before terminating the goroutine. Because Goexit
+// is not a panic, any recover calls in those deferred functions will return nil.
+//
+// Calling Goexit from the main goroutine terminates that goroutine
+// without func main returning. Since func main has not returned,
+// the program continues execution of other goroutines.
+// If all other goroutines exit, the program crashes.
+func Goexit() {
+ // Run all deferred functions for the current goroutine.
+ // This code is similar to gopanic, see that implementation
+ // for detailed comments.
+ gp := getg()
+
+ // Create a panic object for Goexit, so we can recognize when it might be
+ // bypassed by a recover().
+ var p _panic
+ p.goexit = true
+ p.link = gp._panic
+ gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
+
+ addOneOpenDeferFrame(gp, getcallerpc(), unsafe.Pointer(getcallersp()))
+ for {
+ d := gp._defer
+ if d == nil {
+ break
+ }
+ if d.started {
+ if d._panic != nil {
+ d._panic.aborted = true
+ d._panic = nil
+ }
+ if !d.openDefer {
+ d.fn = nil
+ gp._defer = d.link
+ freedefer(d)
+ continue
+ }
+ }
+ d.started = true
+ d._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
+ if d.openDefer {
+ done := runOpenDeferFrame(d)
+ if !done {
+ // We should always run all defers in the frame,
+ // since there is no panic associated with this
+ // defer that can be recovered.
+ throw("unfinished open-coded defers in Goexit")
+ }
+ if p.aborted {
+ // Since our current defer caused a panic and may
+ // have been already freed, just restart scanning
+ // for open-coded defers from this frame again.
+ addOneOpenDeferFrame(gp, getcallerpc(), unsafe.Pointer(getcallersp()))
+ } else {
+ addOneOpenDeferFrame(gp, 0, nil)
+ }
+ } else {
+ // Save the pc/sp in deferCallSave(), so we can "recover" back to this
+ // loop if necessary.
+ deferCallSave(&p, d.fn)
+ }
+ if p.aborted {
+ // We had a recursive panic in the defer d we started, and
+ // then did a recover in a defer that was further down the
+ // defer chain than d. In the case of an outstanding Goexit,
+ // we force the recover to return back to this loop. d will
+ // have already been freed if completed, so just continue
+ // immediately to the next defer on the chain.
+ p.aborted = false
+ continue
+ }
+ if gp._defer != d {
+ throw("bad defer entry in Goexit")
+ }
+ d._panic = nil
+ d.fn = nil
+ gp._defer = d.link
+ freedefer(d)
+ // Note: we ignore recovers here because Goexit isn't a panic
+ }
+ goexit1()
+}
+
+// Call all Error and String methods before freezing the world.
+// Used when crashing with panicking.
+func preprintpanics(p *_panic) {
+ defer func() {
+ text := "panic while printing panic value"
+ switch r := recover().(type) {
+ case nil:
+ // nothing to do
+ case string:
+ throw(text + ": " + r)
+ default:
+ throw(text + ": type " + toRType(efaceOf(&r)._type).string())
+ }
+ }()
+ for p != nil {
+ switch v := p.arg.(type) {
+ case error:
+ p.arg = v.Error()
+ case stringer:
+ p.arg = v.String()
+ }
+ p = p.link
+ }
+}
+
+// Print all currently active panics. Used when crashing.
+// Should only be called after preprintpanics.
+func printpanics(p *_panic) {
+ if p.link != nil {
+ printpanics(p.link)
+ if !p.link.goexit {
+ print("\t")
+ }
+ }
+ if p.goexit {
+ return
+ }
+ print("panic: ")
+ printany(p.arg)
+ if p.recovered {
+ print(" [recovered]")
+ }
+ print("\n")
+}
+
+// addOneOpenDeferFrame scans the stack (in gentraceback order, from inner frames to
+// outer frames) for the first frame (if any) with open-coded defers. If it finds
+// one, it adds a single entry to the defer chain for that frame. The entry added
+// represents all the defers in the associated open defer frame, and is sorted in
+// order with respect to any non-open-coded defers.
+//
+// addOneOpenDeferFrame stops (possibly without adding a new entry) if it encounters
+// an in-progress open defer entry. An in-progress open defer entry means there has
+// been a new panic because of a defer in the associated frame. addOneOpenDeferFrame
+// does not add an open defer entry past a started entry, because that started entry
+// still needs to finished, and addOneOpenDeferFrame will be called when that started
+// entry is completed. The defer removal loop in gopanic() similarly stops at an
+// in-progress defer entry. Together, addOneOpenDeferFrame and the defer removal loop
+// ensure the invariant that there is no open defer entry further up the stack than
+// an in-progress defer, and also that the defer removal loop is guaranteed to remove
+// all not-in-progress open defer entries from the defer chain.
+//
+// If sp is non-nil, addOneOpenDeferFrame starts the stack scan from the frame
+// specified by sp. If sp is nil, it uses the sp from the current defer record (which
+// has just been finished). Hence, it continues the stack scan from the frame of the
+// defer that just finished. It skips any frame that already has a (not-in-progress)
+// open-coded _defer record in the defer chain.
+//
+// Note: All entries of the defer chain (including this new open-coded entry) have
+// their pointers (including sp) adjusted properly if the stack moves while
+// running deferred functions. Also, it is safe to pass in the sp arg (which is
+// the direct result of calling getcallersp()), because all pointer variables
+// (including arguments) are adjusted as needed during stack copies.
+func addOneOpenDeferFrame(gp *g, pc uintptr, sp unsafe.Pointer) {
+ var prevDefer *_defer
+ if sp == nil {
+ prevDefer = gp._defer
+ pc = prevDefer.framepc
+ sp = unsafe.Pointer(prevDefer.sp)
+ }
+ systemstack(func() {
+ var u unwinder
+ frames:
+ for u.initAt(pc, uintptr(sp), 0, gp, 0); u.valid(); u.next() {
+ frame := &u.frame
+ if prevDefer != nil && prevDefer.sp == frame.sp {
+ // Skip the frame for the previous defer that
+ // we just finished (and was used to set
+ // where we restarted the stack scan)
+ continue
+ }
+ f := frame.fn
+ fd := funcdata(f, abi.FUNCDATA_OpenCodedDeferInfo)
+ if fd == nil {
+ continue
+ }
+ // Insert the open defer record in the
+ // chain, in order sorted by sp.
+ d := gp._defer
+ var prev *_defer
+ for d != nil {
+ dsp := d.sp
+ if frame.sp < dsp {
+ break
+ }
+ if frame.sp == dsp {
+ if !d.openDefer {
+ throw("duplicated defer entry")
+ }
+ // Don't add any record past an
+ // in-progress defer entry. We don't
+ // need it, and more importantly, we
+ // want to keep the invariant that
+ // there is no open defer entry
+ // passed an in-progress entry (see
+ // header comment).
+ if d.started {
+ break frames
+ }
+ continue frames
+ }
+ prev = d
+ d = d.link
+ }
+ if frame.fn.deferreturn == 0 {
+ throw("missing deferreturn")
+ }
+
+ d1 := newdefer()
+ d1.openDefer = true
+ d1._panic = nil
+ // These are the pc/sp to set after we've
+ // run a defer in this frame that did a
+ // recover. We return to a special
+ // deferreturn that runs any remaining
+ // defers and then returns from the
+ // function.
+ d1.pc = frame.fn.entry() + uintptr(frame.fn.deferreturn)
+ d1.varp = frame.varp
+ d1.fd = fd
+ // Save the SP/PC associated with current frame,
+ // so we can continue stack trace later if needed.
+ d1.framepc = frame.pc
+ d1.sp = frame.sp
+ d1.link = d
+ if prev == nil {
+ gp._defer = d1
+ } else {
+ prev.link = d1
+ }
+ // Stop stack scanning after adding one open defer record
+ break
+ }
+ })
+}
+
+// readvarintUnsafe reads the uint32 in varint format starting at fd, and returns the
+// uint32 and a pointer to the byte following the varint.
+//
+// There is a similar function runtime.readvarint, which takes a slice of bytes,
+// rather than an unsafe pointer. These functions are duplicated, because one of
+// the two use cases for the functions would get slower if the functions were
+// combined.
+func readvarintUnsafe(fd unsafe.Pointer) (uint32, unsafe.Pointer) {
+ var r uint32
+ var shift int
+ for {
+ b := *(*uint8)((unsafe.Pointer(fd)))
+ fd = add(fd, unsafe.Sizeof(b))
+ if b < 128 {
+ return r + uint32(b)<<shift, fd
+ }
+ r += ((uint32(b) &^ 128) << shift)
+ shift += 7
+ if shift > 28 {
+ panic("Bad varint")
+ }
+ }
+}
+
+// runOpenDeferFrame runs the active open-coded defers in the frame specified by
+// d. It normally processes all active defers in the frame, but stops immediately
+// if a defer does a successful recover. It returns true if there are no
+// remaining defers to run in the frame.
+func runOpenDeferFrame(d *_defer) bool {
+ done := true
+ fd := d.fd
+
+ deferBitsOffset, fd := readvarintUnsafe(fd)
+ nDefers, fd := readvarintUnsafe(fd)
+ deferBits := *(*uint8)(unsafe.Pointer(d.varp - uintptr(deferBitsOffset)))
+
+ for i := int(nDefers) - 1; i >= 0; i-- {
+ // read the funcdata info for this defer
+ var closureOffset uint32
+ closureOffset, fd = readvarintUnsafe(fd)
+ if deferBits&(1<<i) == 0 {
+ continue
+ }
+ closure := *(*func())(unsafe.Pointer(d.varp - uintptr(closureOffset)))
+ d.fn = closure
+ deferBits = deferBits &^ (1 << i)
+ *(*uint8)(unsafe.Pointer(d.varp - uintptr(deferBitsOffset))) = deferBits
+ p := d._panic
+ // Call the defer. Note that this can change d.varp if
+ // the stack moves.
+ deferCallSave(p, d.fn)
+ if p != nil && p.aborted {
+ break
+ }
+ d.fn = nil
+ if d._panic != nil && d._panic.recovered {
+ done = deferBits == 0
+ break
+ }
+ }
+
+ return done
+}
+
+// deferCallSave calls fn() after saving the caller's pc and sp in the
+// panic record. This allows the runtime to return to the Goexit defer
+// processing loop, in the unusual case where the Goexit may be
+// bypassed by a successful recover.
+//
+// This is marked as a wrapper by the compiler so it doesn't appear in
+// tracebacks.
+func deferCallSave(p *_panic, fn func()) {
+ if p != nil {
+ p.argp = unsafe.Pointer(getargp())
+ p.pc = getcallerpc()
+ p.sp = unsafe.Pointer(getcallersp())
+ }
+ fn()
+ if p != nil {
+ p.pc = 0
+ p.sp = unsafe.Pointer(nil)
+ }
+}
+
+// A PanicNilError happens when code calls panic(nil).
+//
+// Before Go 1.21, programs that called panic(nil) observed recover returning nil.
+// Starting in Go 1.21, programs that call panic(nil) observe recover returning a *PanicNilError.
+// Programs can change back to the old behavior by setting GODEBUG=panicnil=1.
+type PanicNilError struct {
+ // This field makes PanicNilError structurally different from
+ // any other struct in this package, and the _ makes it different
+ // from any struct in other packages too.
+ // This avoids any accidental conversions being possible
+ // between this struct and some other struct sharing the same fields,
+ // like happened in go.dev/issue/56603.
+ _ [0]*PanicNilError
+}
+
+func (*PanicNilError) Error() string { return "panic called with nil argument" }
+func (*PanicNilError) RuntimeError() {}
+
+var panicnil = &godebugInc{name: "panicnil"}
+
+// The implementation of the predeclared function panic.
+func gopanic(e any) {
+ if e == nil {
+ if debug.panicnil.Load() != 1 {
+ e = new(PanicNilError)
+ } else {
+ panicnil.IncNonDefault()
+ }
+ }
+
+ gp := getg()
+ if gp.m.curg != gp {
+ print("panic: ")
+ printany(e)
+ print("\n")
+ throw("panic on system stack")
+ }
+
+ if gp.m.mallocing != 0 {
+ print("panic: ")
+ printany(e)
+ print("\n")
+ throw("panic during malloc")
+ }
+ if gp.m.preemptoff != "" {
+ print("panic: ")
+ printany(e)
+ print("\n")
+ print("preempt off reason: ")
+ print(gp.m.preemptoff)
+ print("\n")
+ throw("panic during preemptoff")
+ }
+ if gp.m.locks != 0 {
+ print("panic: ")
+ printany(e)
+ print("\n")
+ throw("panic holding locks")
+ }
+
+ var p _panic
+ p.arg = e
+ p.link = gp._panic
+ gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
+
+ runningPanicDefers.Add(1)
+
+ // By calculating getcallerpc/getcallersp here, we avoid scanning the
+ // gopanic frame (stack scanning is slow...)
+ addOneOpenDeferFrame(gp, getcallerpc(), unsafe.Pointer(getcallersp()))
+
+ for {
+ d := gp._defer
+ if d == nil {
+ break
+ }
+
+ // If defer was started by earlier panic or Goexit (and, since we're back here, that triggered a new panic),
+ // take defer off list. An earlier panic will not continue running, but we will make sure below that an
+ // earlier Goexit does continue running.
+ if d.started {
+ if d._panic != nil {
+ d._panic.aborted = true
+ }
+ d._panic = nil
+ if !d.openDefer {
+ // For open-coded defers, we need to process the
+ // defer again, in case there are any other defers
+ // to call in the frame (not including the defer
+ // call that caused the panic).
+ d.fn = nil
+ gp._defer = d.link
+ freedefer(d)
+ continue
+ }
+ }
+
+ // Mark defer as started, but keep on list, so that traceback
+ // can find and update the defer's argument frame if stack growth
+ // or a garbage collection happens before executing d.fn.
+ d.started = true
+
+ // Record the panic that is running the defer.
+ // If there is a new panic during the deferred call, that panic
+ // will find d in the list and will mark d._panic (this panic) aborted.
+ d._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
+
+ done := true
+ if d.openDefer {
+ done = runOpenDeferFrame(d)
+ if done && !d._panic.recovered {
+ addOneOpenDeferFrame(gp, 0, nil)
+ }
+ } else {
+ p.argp = unsafe.Pointer(getargp())
+ d.fn()
+ }
+ p.argp = nil
+
+ // Deferred function did not panic. Remove d.
+ if gp._defer != d {
+ throw("bad defer entry in panic")
+ }
+ d._panic = nil
+
+ // trigger shrinkage to test stack copy. See stack_test.go:TestStackPanic
+ //GC()
+
+ pc := d.pc
+ sp := unsafe.Pointer(d.sp) // must be pointer so it gets adjusted during stack copy
+ if done {
+ d.fn = nil
+ gp._defer = d.link
+ freedefer(d)
+ }
+ if p.recovered {
+ gp._panic = p.link
+ if gp._panic != nil && gp._panic.goexit && gp._panic.aborted {
+ // A normal recover would bypass/abort the Goexit. Instead,
+ // we return to the processing loop of the Goexit.
+ gp.sigcode0 = uintptr(gp._panic.sp)
+ gp.sigcode1 = uintptr(gp._panic.pc)
+ mcall(recovery)
+ throw("bypassed recovery failed") // mcall should not return
+ }
+ runningPanicDefers.Add(-1)
+
+ // After a recover, remove any remaining non-started,
+ // open-coded defer entries, since the corresponding defers
+ // will be executed normally (inline). Any such entry will
+ // become stale once we run the corresponding defers inline
+ // and exit the associated stack frame. We only remove up to
+ // the first started (in-progress) open defer entry, not
+ // including the current frame, since any higher entries will
+ // be from a higher panic in progress, and will still be
+ // needed.
+ d := gp._defer
+ var prev *_defer
+ if !done {
+ // Skip our current frame, if not done. It is
+ // needed to complete any remaining defers in
+ // deferreturn()
+ prev = d
+ d = d.link
+ }
+ for d != nil {
+ if d.started {
+ // This defer is started but we
+ // are in the middle of a
+ // defer-panic-recover inside of
+ // it, so don't remove it or any
+ // further defer entries
+ break
+ }
+ if d.openDefer {
+ if prev == nil {
+ gp._defer = d.link
+ } else {
+ prev.link = d.link
+ }
+ newd := d.link
+ freedefer(d)
+ d = newd
+ } else {
+ prev = d
+ d = d.link
+ }
+ }
+
+ gp._panic = p.link
+ // Aborted panics are marked but remain on the g.panic list.
+ // Remove them from the list.
+ for gp._panic != nil && gp._panic.aborted {
+ gp._panic = gp._panic.link
+ }
+ if gp._panic == nil { // must be done with signal
+ gp.sig = 0
+ }
+ // Pass information about recovering frame to recovery.
+ gp.sigcode0 = uintptr(sp)
+ gp.sigcode1 = pc
+ mcall(recovery)
+ throw("recovery failed") // mcall should not return
+ }
+ }
+
+ // ran out of deferred calls - old-school panic now
+ // Because it is unsafe to call arbitrary user code after freezing
+ // the world, we call preprintpanics to invoke all necessary Error
+ // and String methods to prepare the panic strings before startpanic.
+ preprintpanics(gp._panic)
+
+ fatalpanic(gp._panic) // should not return
+ *(*int)(nil) = 0 // not reached
+}
+
+// getargp returns the location where the caller
+// writes outgoing function call arguments.
+//
+//go:nosplit
+//go:noinline
+func getargp() uintptr {
+ return getcallersp() + sys.MinFrameSize
+}
+
+// The implementation of the predeclared function recover.
+// Cannot split the stack because it needs to reliably
+// find the stack segment of its caller.
+//
+// TODO(rsc): Once we commit to CopyStackAlways,
+// this doesn't need to be nosplit.
+//
+//go:nosplit
+func gorecover(argp uintptr) any {
+ // Must be in a function running as part of a deferred call during the panic.
+ // Must be called from the topmost function of the call
+ // (the function used in the defer statement).
+ // p.argp is the argument pointer of that topmost deferred function call.
+ // Compare against argp reported by caller.
+ // If they match, the caller is the one who can recover.
+ gp := getg()
+ p := gp._panic
+ if p != nil && !p.goexit && !p.recovered && argp == uintptr(p.argp) {
+ p.recovered = true
+ return p.arg
+ }
+ return nil
+}
+
+//go:linkname sync_throw sync.throw
+func sync_throw(s string) {
+ throw(s)
+}
+
+//go:linkname sync_fatal sync.fatal
+func sync_fatal(s string) {
+ fatal(s)
+}
+
+// throw triggers a fatal error that dumps a stack trace and exits.
+//
+// throw should be used for runtime-internal fatal errors where Go itself,
+// rather than user code, may be at fault for the failure.
+//
+//go:nosplit
+func throw(s string) {
+ // Everything throw does should be recursively nosplit so it
+ // can be called even when it's unsafe to grow the stack.
+ systemstack(func() {
+ print("fatal error: ", s, "\n")
+ })
+
+ fatalthrow(throwTypeRuntime)
+}
+
+// fatal triggers a fatal error that dumps a stack trace and exits.
+//
+// fatal is equivalent to throw, but is used when user code is expected to be
+// at fault for the failure, such as racing map writes.
+//
+// fatal does not include runtime frames, system goroutines, or frame metadata
+// (fp, sp, pc) in the stack trace unless GOTRACEBACK=system or higher.
+//
+//go:nosplit
+func fatal(s string) {
+ // Everything fatal does should be recursively nosplit so it
+ // can be called even when it's unsafe to grow the stack.
+ systemstack(func() {
+ print("fatal error: ", s, "\n")
+ })
+
+ fatalthrow(throwTypeUser)
+}
+
+// runningPanicDefers is non-zero while running deferred functions for panic.
+// This is used to try hard to get a panic stack trace out when exiting.
+var runningPanicDefers atomic.Uint32
+
+// panicking is non-zero when crashing the program for an unrecovered panic.
+var panicking atomic.Uint32
+
+// paniclk is held while printing the panic information and stack trace,
+// so that two concurrent panics don't overlap their output.
+var paniclk mutex
+
+// Unwind the stack after a deferred function calls recover
+// after a panic. Then arrange to continue running as though
+// the caller of the deferred function returned normally.
+func recovery(gp *g) {
+ // Info about defer passed in G struct.
+ sp := gp.sigcode0
+ pc := gp.sigcode1
+
+ // d's arguments need to be in the stack.
+ if sp != 0 && (sp < gp.stack.lo || gp.stack.hi < sp) {
+ print("recover: ", hex(sp), " not in [", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
+ throw("bad recovery")
+ }
+
+ // Make the deferproc for this d return again,
+ // this time returning 1. The calling function will
+ // jump to the standard return epilogue.
+ gp.sched.sp = sp
+ gp.sched.pc = pc
+ gp.sched.lr = 0
+ // Restore the bp on platforms that support frame pointers.
+ // N.B. It's fine to not set anything for platforms that don't
+ // support frame pointers, since nothing consumes them.
+ switch {
+ case goarch.IsAmd64 != 0:
+ // On x86, the architectural bp is stored 2 words below the
+ // stack pointer.
+ gp.sched.bp = *(*uintptr)(unsafe.Pointer(sp - 2*goarch.PtrSize))
+ case goarch.IsArm64 != 0:
+ // on arm64, the architectural bp points one word higher
+ // than the sp.
+ gp.sched.bp = sp - goarch.PtrSize
+ }
+ gp.sched.ret = 1
+ gogo(&gp.sched)
+}
+
+// fatalthrow implements an unrecoverable runtime throw. It freezes the
+// system, prints stack traces starting from its caller, and terminates the
+// process.
+//
+//go:nosplit
+func fatalthrow(t throwType) {
+ pc := getcallerpc()
+ sp := getcallersp()
+ gp := getg()
+
+ if gp.m.throwing == throwTypeNone {
+ gp.m.throwing = t
+ }
+
+ // Switch to the system stack to avoid any stack growth, which may make
+ // things worse if the runtime is in a bad state.
+ systemstack(func() {
+ if isSecureMode() {
+ exit(2)
+ }
+
+ startpanic_m()
+
+ if dopanic_m(gp, pc, sp) {
+ // crash uses a decent amount of nosplit stack and we're already
+ // low on stack in throw, so crash on the system stack (unlike
+ // fatalpanic).
+ crash()
+ }
+
+ exit(2)
+ })
+
+ *(*int)(nil) = 0 // not reached
+}
+
+// fatalpanic implements an unrecoverable panic. It is like fatalthrow, except
+// that if msgs != nil, fatalpanic also prints panic messages and decrements
+// runningPanicDefers once main is blocked from exiting.
+//
+//go:nosplit
+func fatalpanic(msgs *_panic) {
+ pc := getcallerpc()
+ sp := getcallersp()
+ gp := getg()
+ var docrash bool
+ // Switch to the system stack to avoid any stack growth, which
+ // may make things worse if the runtime is in a bad state.
+ systemstack(func() {
+ if startpanic_m() && msgs != nil {
+ // There were panic messages and startpanic_m
+ // says it's okay to try to print them.
+
+ // startpanic_m set panicking, which will
+ // block main from exiting, so now OK to
+ // decrement runningPanicDefers.
+ runningPanicDefers.Add(-1)
+
+ printpanics(msgs)
+ }
+
+ docrash = dopanic_m(gp, pc, sp)
+ })
+
+ if docrash {
+ // By crashing outside the above systemstack call, debuggers
+ // will not be confused when generating a backtrace.
+ // Function crash is marked nosplit to avoid stack growth.
+ crash()
+ }
+
+ systemstack(func() {
+ exit(2)
+ })
+
+ *(*int)(nil) = 0 // not reached
+}
+
+// startpanic_m prepares for an unrecoverable panic.
+//
+// It returns true if panic messages should be printed, or false if
+// the runtime is in bad shape and should just print stacks.
+//
+// It must not have write barriers even though the write barrier
+// explicitly ignores writes once dying > 0. Write barriers still
+// assume that g.m.p != nil, and this function may not have P
+// in some contexts (e.g. a panic in a signal handler for a signal
+// sent to an M with no P).
+//
+//go:nowritebarrierrec
+func startpanic_m() bool {
+ gp := getg()
+ if mheap_.cachealloc.size == 0 { // very early
+ print("runtime: panic before malloc heap initialized\n")
+ }
+ // Disallow malloc during an unrecoverable panic. A panic
+ // could happen in a signal handler, or in a throw, or inside
+ // malloc itself. We want to catch if an allocation ever does
+ // happen (even if we're not in one of these situations).
+ gp.m.mallocing++
+
+ // If we're dying because of a bad lock count, set it to a
+ // good lock count so we don't recursively panic below.
+ if gp.m.locks < 0 {
+ gp.m.locks = 1
+ }
+
+ switch gp.m.dying {
+ case 0:
+ // Setting dying >0 has the side-effect of disabling this G's writebuf.
+ gp.m.dying = 1
+ panicking.Add(1)
+ lock(&paniclk)
+ if debug.schedtrace > 0 || debug.scheddetail > 0 {
+ schedtrace(true)
+ }
+ freezetheworld()
+ return true
+ case 1:
+ // Something failed while panicking.
+ // Just print a stack trace and exit.
+ gp.m.dying = 2
+ print("panic during panic\n")
+ return false
+ case 2:
+ // This is a genuine bug in the runtime, we couldn't even
+ // print the stack trace successfully.
+ gp.m.dying = 3
+ print("stack trace unavailable\n")
+ exit(4)
+ fallthrough
+ default:
+ // Can't even print! Just exit.
+ exit(5)
+ return false // Need to return something.
+ }
+}
+
+var didothers bool
+var deadlock mutex
+
+// gp is the crashing g running on this M, but may be a user G, while getg() is
+// always g0.
+func dopanic_m(gp *g, pc, sp uintptr) bool {
+ if gp.sig != 0 {
+ signame := signame(gp.sig)
+ if signame != "" {
+ print("[signal ", signame)
+ } else {
+ print("[signal ", hex(gp.sig))
+ }
+ print(" code=", hex(gp.sigcode0), " addr=", hex(gp.sigcode1), " pc=", hex(gp.sigpc), "]\n")
+ }
+
+ level, all, docrash := gotraceback()
+ if level > 0 {
+ if gp != gp.m.curg {
+ all = true
+ }
+ if gp != gp.m.g0 {
+ print("\n")
+ goroutineheader(gp)
+ traceback(pc, sp, 0, gp)
+ } else if level >= 2 || gp.m.throwing >= throwTypeRuntime {
+ print("\nruntime stack:\n")
+ traceback(pc, sp, 0, gp)
+ }
+ if !didothers && all {
+ didothers = true
+ tracebackothers(gp)
+ }
+ }
+ unlock(&paniclk)
+
+ if panicking.Add(-1) != 0 {
+ // Some other m is panicking too.
+ // Let it print what it needs to print.
+ // Wait forever without chewing up cpu.
+ // It will exit when it's done.
+ lock(&deadlock)
+ lock(&deadlock)
+ }
+
+ printDebugLog()
+
+ return docrash
+}
+
+// canpanic returns false if a signal should throw instead of
+// panicking.
+//
+//go:nosplit
+func canpanic() bool {
+ gp := getg()
+ mp := acquirem()
+
+ // Is it okay for gp to panic instead of crashing the program?
+ // Yes, as long as it is running Go code, not runtime code,
+ // and not stuck in a system call.
+ if gp != mp.curg {
+ releasem(mp)
+ return false
+ }
+ // N.B. mp.locks != 1 instead of 0 to account for acquirem.
+ if mp.locks != 1 || mp.mallocing != 0 || mp.throwing != throwTypeNone || mp.preemptoff != "" || mp.dying != 0 {
+ releasem(mp)
+ return false
+ }
+ status := readgstatus(gp)
+ if status&^_Gscan != _Grunning || gp.syscallsp != 0 {
+ releasem(mp)
+ return false
+ }
+ if GOOS == "windows" && mp.libcallsp != 0 {
+ releasem(mp)
+ return false
+ }
+ releasem(mp)
+ return true
+}
+
+// shouldPushSigpanic reports whether pc should be used as sigpanic's
+// return PC (pushing a frame for the call). Otherwise, it should be
+// left alone so that LR is used as sigpanic's return PC, effectively
+// replacing the top-most frame with sigpanic. This is used by
+// preparePanic.
+func shouldPushSigpanic(gp *g, pc, lr uintptr) bool {
+ if pc == 0 {
+ // Probably a call to a nil func. The old LR is more
+ // useful in the stack trace. Not pushing the frame
+ // will make the trace look like a call to sigpanic
+ // instead. (Otherwise the trace will end at sigpanic
+ // and we won't get to see who faulted.)
+ return false
+ }
+ // If we don't recognize the PC as code, but we do recognize
+ // the link register as code, then this assumes the panic was
+ // caused by a call to non-code. In this case, we want to
+ // ignore this call to make unwinding show the context.
+ //
+ // If we running C code, we're not going to recognize pc as a
+ // Go function, so just assume it's good. Otherwise, traceback
+ // may try to read a stale LR that looks like a Go code
+ // pointer and wander into the woods.
+ if gp.m.incgo || findfunc(pc).valid() {
+ // This wasn't a bad call, so use PC as sigpanic's
+ // return PC.
+ return true
+ }
+ if findfunc(lr).valid() {
+ // This was a bad call, but the LR is good, so use the
+ // LR as sigpanic's return PC.
+ return false
+ }
+ // Neither the PC or LR is good. Hopefully pushing a frame
+ // will work.
+ return true
+}
+
+// isAbortPC reports whether pc is the program counter at which
+// runtime.abort raises a signal.
+//
+// It is nosplit because it's part of the isgoexception
+// implementation.
+//
+//go:nosplit
+func isAbortPC(pc uintptr) bool {
+ f := findfunc(pc)
+ if !f.valid() {
+ return false
+ }
+ return f.funcID == abi.FuncID_abort
+}
diff --git a/contrib/go/_std_1.21/src/runtime/pinner.go b/contrib/go/_std_1.21/src/runtime/pinner.go
new file mode 100644
index 0000000000..8bb351eb8f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/pinner.go
@@ -0,0 +1,380 @@
+// Copyright 2023 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 runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// A Pinner is a set of pinned Go objects. An object can be pinned with
+// the Pin method and all pinned objects of a Pinner can be unpinned with the
+// Unpin method.
+type Pinner struct {
+ *pinner
+}
+
+// Pin pins a Go object, preventing it from being moved or freed by the garbage
+// collector until the Unpin method has been called.
+//
+// A pointer to a pinned
+// object can be directly stored in C memory or can be contained in Go memory
+// passed to C functions. If the pinned object itself contains pointers to Go
+// objects, these objects must be pinned separately if they are going to be
+// accessed from C code.
+//
+// The argument must be a pointer of any type or an
+// unsafe.Pointer. It must be the result of calling new,
+// taking the address of a composite literal, or taking the address of a
+// local variable. If one of these conditions is not met, Pin will panic.
+func (p *Pinner) Pin(pointer any) {
+ if p.pinner == nil {
+ // Check the pinner cache first.
+ mp := acquirem()
+ if pp := mp.p.ptr(); pp != nil {
+ p.pinner = pp.pinnerCache
+ pp.pinnerCache = nil
+ }
+ releasem(mp)
+
+ if p.pinner == nil {
+ // Didn't get anything from the pinner cache.
+ p.pinner = new(pinner)
+ p.refs = p.refStore[:0]
+
+ // We set this finalizer once and never clear it. Thus, if the
+ // pinner gets cached, we'll reuse it, along with its finalizer.
+ // This lets us avoid the relatively expensive SetFinalizer call
+ // when reusing from the cache. The finalizer however has to be
+ // resilient to an empty pinner being finalized, which is done
+ // by checking p.refs' length.
+ SetFinalizer(p.pinner, func(i *pinner) {
+ if len(i.refs) != 0 {
+ i.unpin() // only required to make the test idempotent
+ pinnerLeakPanic()
+ }
+ })
+ }
+ }
+ ptr := pinnerGetPtr(&pointer)
+ setPinned(ptr, true)
+ p.refs = append(p.refs, ptr)
+}
+
+// Unpin unpins all pinned objects of the Pinner.
+func (p *Pinner) Unpin() {
+ p.pinner.unpin()
+
+ mp := acquirem()
+ if pp := mp.p.ptr(); pp != nil && pp.pinnerCache == nil {
+ // Put the pinner back in the cache, but only if the
+ // cache is empty. If application code is reusing Pinners
+ // on its own, we want to leave the backing store in place
+ // so reuse is more efficient.
+ pp.pinnerCache = p.pinner
+ p.pinner = nil
+ }
+ releasem(mp)
+}
+
+const (
+ pinnerSize = 64
+ pinnerRefStoreSize = (pinnerSize - unsafe.Sizeof([]unsafe.Pointer{})) / unsafe.Sizeof(unsafe.Pointer(nil))
+)
+
+type pinner struct {
+ refs []unsafe.Pointer
+ refStore [pinnerRefStoreSize]unsafe.Pointer
+}
+
+func (p *pinner) unpin() {
+ if p == nil || p.refs == nil {
+ return
+ }
+ for i := range p.refs {
+ setPinned(p.refs[i], false)
+ }
+ // The following two lines make all pointers to references
+ // in p.refs unreachable, either by deleting them or dropping
+ // p.refs' backing store (if it was not backed by refStore).
+ p.refStore = [pinnerRefStoreSize]unsafe.Pointer{}
+ p.refs = p.refStore[:0]
+}
+
+func pinnerGetPtr(i *any) unsafe.Pointer {
+ e := efaceOf(i)
+ etyp := e._type
+ if etyp == nil {
+ panic(errorString("runtime.Pinner: argument is nil"))
+ }
+ if kind := etyp.Kind_ & kindMask; kind != kindPtr && kind != kindUnsafePointer {
+ panic(errorString("runtime.Pinner: argument is not a pointer: " + toRType(etyp).string()))
+ }
+ if inUserArenaChunk(uintptr(e.data)) {
+ // Arena-allocated objects are not eligible for pinning.
+ panic(errorString("runtime.Pinner: object was allocated into an arena"))
+ }
+ return e.data
+}
+
+// isPinned checks if a Go pointer is pinned.
+// nosplit, because it's called from nosplit code in cgocheck.
+//
+//go:nosplit
+func isPinned(ptr unsafe.Pointer) bool {
+ span := spanOfHeap(uintptr(ptr))
+ if span == nil {
+ // this code is only called for Go pointer, so this must be a
+ // linker-allocated global object.
+ return true
+ }
+ pinnerBits := span.getPinnerBits()
+ // these pinnerBits might get unlinked by a concurrently running sweep, but
+ // that's OK because gcBits don't get cleared until the following GC cycle
+ // (nextMarkBitArenaEpoch)
+ if pinnerBits == nil {
+ return false
+ }
+ objIndex := span.objIndex(uintptr(ptr))
+ pinState := pinnerBits.ofObject(objIndex)
+ KeepAlive(ptr) // make sure ptr is alive until we are done so the span can't be freed
+ return pinState.isPinned()
+}
+
+// setPinned marks or unmarks a Go pointer as pinned.
+func setPinned(ptr unsafe.Pointer, pin bool) {
+ span := spanOfHeap(uintptr(ptr))
+ if span == nil {
+ if isGoPointerWithoutSpan(ptr) {
+ // this is a linker-allocated or zero size object, nothing to do.
+ return
+ }
+ panic(errorString("runtime.Pinner.Pin: argument is not a Go pointer"))
+ }
+
+ // ensure that the span is swept, b/c sweeping accesses the specials list
+ // w/o locks.
+ mp := acquirem()
+ span.ensureSwept()
+ KeepAlive(ptr) // make sure ptr is still alive after span is swept
+
+ objIndex := span.objIndex(uintptr(ptr))
+
+ lock(&span.speciallock) // guard against concurrent calls of setPinned on same span
+
+ pinnerBits := span.getPinnerBits()
+ if pinnerBits == nil {
+ pinnerBits = span.newPinnerBits()
+ span.setPinnerBits(pinnerBits)
+ }
+ pinState := pinnerBits.ofObject(objIndex)
+ if pin {
+ if pinState.isPinned() {
+ // multiple pins on same object, set multipin bit
+ pinState.setMultiPinned(true)
+ // and increase the pin counter
+ // TODO(mknyszek): investigate if systemstack is necessary here
+ systemstack(func() {
+ offset := objIndex * span.elemsize
+ span.incPinCounter(offset)
+ })
+ } else {
+ // set pin bit
+ pinState.setPinned(true)
+ }
+ } else {
+ // unpin
+ if pinState.isPinned() {
+ if pinState.isMultiPinned() {
+ var exists bool
+ // TODO(mknyszek): investigate if systemstack is necessary here
+ systemstack(func() {
+ offset := objIndex * span.elemsize
+ exists = span.decPinCounter(offset)
+ })
+ if !exists {
+ // counter is 0, clear multipin bit
+ pinState.setMultiPinned(false)
+ }
+ } else {
+ // no multipins recorded. unpin object.
+ pinState.setPinned(false)
+ }
+ } else {
+ // unpinning unpinned object, bail out
+ throw("runtime.Pinner: object already unpinned")
+ }
+ }
+ unlock(&span.speciallock)
+ releasem(mp)
+ return
+}
+
+type pinState struct {
+ bytep *uint8
+ byteVal uint8
+ mask uint8
+}
+
+// nosplit, because it's called by isPinned, which is nosplit
+//
+//go:nosplit
+func (v *pinState) isPinned() bool {
+ return (v.byteVal & v.mask) != 0
+}
+
+func (v *pinState) isMultiPinned() bool {
+ return (v.byteVal & (v.mask << 1)) != 0
+}
+
+func (v *pinState) setPinned(val bool) {
+ v.set(val, false)
+}
+
+func (v *pinState) setMultiPinned(val bool) {
+ v.set(val, true)
+}
+
+// set sets the pin bit of the pinState to val. If multipin is true, it
+// sets/unsets the multipin bit instead.
+func (v *pinState) set(val bool, multipin bool) {
+ mask := v.mask
+ if multipin {
+ mask <<= 1
+ }
+ if val {
+ atomic.Or8(v.bytep, mask)
+ } else {
+ atomic.And8(v.bytep, ^mask)
+ }
+}
+
+// pinnerBits is the same type as gcBits but has different methods.
+type pinnerBits gcBits
+
+// ofObject returns the pinState of the n'th object.
+// nosplit, because it's called by isPinned, which is nosplit
+//
+//go:nosplit
+func (p *pinnerBits) ofObject(n uintptr) pinState {
+ bytep, mask := (*gcBits)(p).bitp(n * 2)
+ byteVal := atomic.Load8(bytep)
+ return pinState{bytep, byteVal, mask}
+}
+
+func (s *mspan) pinnerBitSize() uintptr {
+ return divRoundUp(s.nelems*2, 8)
+}
+
+// newPinnerBits returns a pointer to 8 byte aligned bytes to be used for this
+// span's pinner bits. newPinneBits is used to mark objects that are pinned.
+// They are copied when the span is swept.
+func (s *mspan) newPinnerBits() *pinnerBits {
+ return (*pinnerBits)(newMarkBits(s.nelems * 2))
+}
+
+// nosplit, because it's called by isPinned, which is nosplit
+//
+//go:nosplit
+func (s *mspan) getPinnerBits() *pinnerBits {
+ return (*pinnerBits)(atomic.Loadp(unsafe.Pointer(&s.pinnerBits)))
+}
+
+func (s *mspan) setPinnerBits(p *pinnerBits) {
+ atomicstorep(unsafe.Pointer(&s.pinnerBits), unsafe.Pointer(p))
+}
+
+// refreshPinnerBits replaces pinnerBits with a fresh copy in the arenas for the
+// next GC cycle. If it does not contain any pinned objects, pinnerBits of the
+// span is set to nil.
+func (s *mspan) refreshPinnerBits() {
+ p := s.getPinnerBits()
+ if p == nil {
+ return
+ }
+
+ hasPins := false
+ bytes := alignUp(s.pinnerBitSize(), 8)
+
+ // Iterate over each 8-byte chunk and check for pins. Note that
+ // newPinnerBits guarantees that pinnerBits will be 8-byte aligned, so we
+ // don't have to worry about edge cases, irrelevant bits will simply be
+ // zero.
+ for _, x := range unsafe.Slice((*uint64)(unsafe.Pointer(&p.x)), bytes/8) {
+ if x != 0 {
+ hasPins = true
+ break
+ }
+ }
+
+ if hasPins {
+ newPinnerBits := s.newPinnerBits()
+ memmove(unsafe.Pointer(&newPinnerBits.x), unsafe.Pointer(&p.x), bytes)
+ s.setPinnerBits(newPinnerBits)
+ } else {
+ s.setPinnerBits(nil)
+ }
+}
+
+// incPinCounter is only called for multiple pins of the same object and records
+// the _additional_ pins.
+func (span *mspan) incPinCounter(offset uintptr) {
+ var rec *specialPinCounter
+ ref, exists := span.specialFindSplicePoint(offset, _KindSpecialPinCounter)
+ if !exists {
+ lock(&mheap_.speciallock)
+ rec = (*specialPinCounter)(mheap_.specialPinCounterAlloc.alloc())
+ unlock(&mheap_.speciallock)
+ // splice in record, fill in offset.
+ rec.special.offset = uint16(offset)
+ rec.special.kind = _KindSpecialPinCounter
+ rec.special.next = *ref
+ *ref = (*special)(unsafe.Pointer(rec))
+ spanHasSpecials(span)
+ } else {
+ rec = (*specialPinCounter)(unsafe.Pointer(*ref))
+ }
+ rec.counter++
+}
+
+// decPinCounter decreases the counter. If the counter reaches 0, the counter
+// special is deleted and false is returned. Otherwise true is returned.
+func (span *mspan) decPinCounter(offset uintptr) bool {
+ ref, exists := span.specialFindSplicePoint(offset, _KindSpecialPinCounter)
+ if !exists {
+ throw("runtime.Pinner: decreased non-existing pin counter")
+ }
+ counter := (*specialPinCounter)(unsafe.Pointer(*ref))
+ counter.counter--
+ if counter.counter == 0 {
+ *ref = counter.special.next
+ if span.specials == nil {
+ spanHasNoSpecials(span)
+ }
+ lock(&mheap_.speciallock)
+ mheap_.specialPinCounterAlloc.free(unsafe.Pointer(counter))
+ unlock(&mheap_.speciallock)
+ return false
+ }
+ return true
+}
+
+// only for tests
+func pinnerGetPinCounter(addr unsafe.Pointer) *uintptr {
+ _, span, objIndex := findObject(uintptr(addr), 0, 0)
+ offset := objIndex * span.elemsize
+ t, exists := span.specialFindSplicePoint(offset, _KindSpecialPinCounter)
+ if !exists {
+ return nil
+ }
+ counter := (*specialPinCounter)(unsafe.Pointer(*t))
+ return &counter.counter
+}
+
+// to be able to test that the GC panics when a pinned pointer is leaking, this
+// panic function is a variable, that can be overwritten by a test.
+var pinnerLeakPanic = func() {
+ panic(errorString("runtime.Pinner: found leaking pinned pointer; forgot to call Unpin()?"))
+}
diff --git a/contrib/go/_std_1.21/src/runtime/plugin.go b/contrib/go/_std_1.21/src/runtime/plugin.go
new file mode 100644
index 0000000000..40dfefde17
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/plugin.go
@@ -0,0 +1,137 @@
+// Copyright 2016 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 runtime
+
+import "unsafe"
+
+//go:linkname plugin_lastmoduleinit plugin.lastmoduleinit
+func plugin_lastmoduleinit() (path string, syms map[string]any, initTasks []*initTask, errstr string) {
+ var md *moduledata
+ for pmd := firstmoduledata.next; pmd != nil; pmd = pmd.next {
+ if pmd.bad {
+ md = nil // we only want the last module
+ continue
+ }
+ md = pmd
+ }
+ if md == nil {
+ throw("runtime: no plugin module data")
+ }
+ if md.pluginpath == "" {
+ throw("runtime: plugin has empty pluginpath")
+ }
+ if md.typemap != nil {
+ return "", nil, nil, "plugin already loaded"
+ }
+
+ for _, pmd := range activeModules() {
+ if pmd.pluginpath == md.pluginpath {
+ md.bad = true
+ return "", nil, nil, "plugin already loaded"
+ }
+
+ if inRange(pmd.text, pmd.etext, md.text, md.etext) ||
+ inRange(pmd.bss, pmd.ebss, md.bss, md.ebss) ||
+ inRange(pmd.data, pmd.edata, md.data, md.edata) ||
+ inRange(pmd.types, pmd.etypes, md.types, md.etypes) {
+ println("plugin: new module data overlaps with previous moduledata")
+ println("\tpmd.text-etext=", hex(pmd.text), "-", hex(pmd.etext))
+ println("\tpmd.bss-ebss=", hex(pmd.bss), "-", hex(pmd.ebss))
+ println("\tpmd.data-edata=", hex(pmd.data), "-", hex(pmd.edata))
+ println("\tpmd.types-etypes=", hex(pmd.types), "-", hex(pmd.etypes))
+ println("\tmd.text-etext=", hex(md.text), "-", hex(md.etext))
+ println("\tmd.bss-ebss=", hex(md.bss), "-", hex(md.ebss))
+ println("\tmd.data-edata=", hex(md.data), "-", hex(md.edata))
+ println("\tmd.types-etypes=", hex(md.types), "-", hex(md.etypes))
+ throw("plugin: new module data overlaps with previous moduledata")
+ }
+ }
+ for _, pkghash := range md.pkghashes {
+ if pkghash.linktimehash != *pkghash.runtimehash {
+ md.bad = true
+ return "", nil, nil, "plugin was built with a different version of package " + pkghash.modulename
+ }
+ }
+
+ // Initialize the freshly loaded module.
+ modulesinit()
+ typelinksinit()
+
+ pluginftabverify(md)
+ moduledataverify1(md)
+
+ lock(&itabLock)
+ for _, i := range md.itablinks {
+ itabAdd(i)
+ }
+ unlock(&itabLock)
+
+ // Build a map of symbol names to symbols. Here in the runtime
+ // we fill out the first word of the interface, the type. We
+ // pass these zero value interfaces to the plugin package,
+ // where the symbol value is filled in (usually via cgo).
+ //
+ // Because functions are handled specially in the plugin package,
+ // function symbol names are prefixed here with '.' to avoid
+ // a dependency on the reflect package.
+ syms = make(map[string]any, len(md.ptab))
+ for _, ptab := range md.ptab {
+ symName := resolveNameOff(unsafe.Pointer(md.types), ptab.name)
+ t := toRType((*_type)(unsafe.Pointer(md.types))).typeOff(ptab.typ) // TODO can this stack of conversions be simpler?
+ var val any
+ valp := (*[2]unsafe.Pointer)(unsafe.Pointer(&val))
+ (*valp)[0] = unsafe.Pointer(t)
+
+ name := symName.Name()
+ if t.Kind_&kindMask == kindFunc {
+ name = "." + name
+ }
+ syms[name] = val
+ }
+ return md.pluginpath, syms, md.inittasks, ""
+}
+
+func pluginftabverify(md *moduledata) {
+ badtable := false
+ for i := 0; i < len(md.ftab); i++ {
+ entry := md.textAddr(md.ftab[i].entryoff)
+ if md.minpc <= entry && entry <= md.maxpc {
+ continue
+ }
+
+ f := funcInfo{(*_func)(unsafe.Pointer(&md.pclntable[md.ftab[i].funcoff])), md}
+ name := funcname(f)
+
+ // A common bug is f.entry has a relocation to a duplicate
+ // function symbol, meaning if we search for its PC we get
+ // a valid entry with a name that is useful for debugging.
+ name2 := "none"
+ entry2 := uintptr(0)
+ f2 := findfunc(entry)
+ if f2.valid() {
+ name2 = funcname(f2)
+ entry2 = f2.entry()
+ }
+ badtable = true
+ println("ftab entry", hex(entry), "/", hex(entry2), ": ",
+ name, "/", name2, "outside pc range:[", hex(md.minpc), ",", hex(md.maxpc), "], modulename=", md.modulename, ", pluginpath=", md.pluginpath)
+ }
+ if badtable {
+ throw("runtime: plugin has bad symbol table")
+ }
+}
+
+// inRange reports whether v0 or v1 are in the range [r0, r1].
+func inRange(r0, r1, v0, v1 uintptr) bool {
+ return (v0 >= r0 && v0 <= r1) || (v1 >= r0 && v1 <= r1)
+}
+
+// A ptabEntry is generated by the compiler for each exported function
+// and global variable in the main package of a plugin. It is used to
+// initialize the plugin module's symbol map.
+type ptabEntry struct {
+ name nameOff
+ typ typeOff
+}
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/elf.go b/contrib/go/_std_1.21/src/runtime/pprof/elf.go
index a8b5ea6817..a8b5ea6817 100644
--- a/contrib/go/_std_1.20/src/runtime/pprof/elf.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/elf.go
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/label.go b/contrib/go/_std_1.21/src/runtime/pprof/label.go
index d39e0ad58e..d39e0ad58e 100644
--- a/contrib/go/_std_1.20/src/runtime/pprof/label.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/label.go
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/map.go b/contrib/go/_std_1.21/src/runtime/pprof/map.go
index 7c75872351..7c75872351 100644
--- a/contrib/go/_std_1.20/src/runtime/pprof/map.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/map.go
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/pe.go b/contrib/go/_std_1.21/src/runtime/pprof/pe.go
index 41054585e9..41054585e9 100644
--- a/contrib/go/_std_1.20/src/runtime/pprof/pe.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/pe.go
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/pprof.go b/contrib/go/_std_1.21/src/runtime/pprof/pprof.go
index 17a490efed..17a490efed 100644
--- a/contrib/go/_std_1.20/src/runtime/pprof/pprof.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/pprof.go
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/pprof_rusage.go b/contrib/go/_std_1.21/src/runtime/pprof/pprof_rusage.go
index aa429fb06a..aa429fb06a 100644
--- a/contrib/go/_std_1.20/src/runtime/pprof/pprof_rusage.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/pprof_rusage.go
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/pprof_windows.go b/contrib/go/_std_1.21/src/runtime/pprof/pprof_windows.go
index 23ef2f80fe..23ef2f80fe 100644
--- a/contrib/go/_std_1.20/src/runtime/pprof/pprof_windows.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/pprof_windows.go
diff --git a/contrib/go/_std_1.21/src/runtime/pprof/proto.go b/contrib/go/_std_1.21/src/runtime/pprof/proto.go
new file mode 100644
index 0000000000..cdc4bd7c80
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/pprof/proto.go
@@ -0,0 +1,761 @@
+// Copyright 2016 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 pprof
+
+import (
+ "bytes"
+ "compress/gzip"
+ "fmt"
+ "internal/abi"
+ "io"
+ "runtime"
+ "strconv"
+ "strings"
+ "time"
+ "unsafe"
+)
+
+// lostProfileEvent is the function to which lost profiling
+// events are attributed.
+// (The name shows up in the pprof graphs.)
+func lostProfileEvent() { lostProfileEvent() }
+
+// A profileBuilder writes a profile incrementally from a
+// stream of profile samples delivered by the runtime.
+type profileBuilder struct {
+ start time.Time
+ end time.Time
+ havePeriod bool
+ period int64
+ m profMap
+
+ // encoding state
+ w io.Writer
+ zw *gzip.Writer
+ pb protobuf
+ strings []string
+ stringMap map[string]int
+ locs map[uintptr]locInfo // list of locInfo starting with the given PC.
+ funcs map[string]int // Package path-qualified function name to Function.ID
+ mem []memMap
+ deck pcDeck
+}
+
+type memMap struct {
+ // initialized as reading mapping
+ start uintptr // Address at which the binary (or DLL) is loaded into memory.
+ end uintptr // The limit of the address range occupied by this mapping.
+ offset uint64 // Offset in the binary that corresponds to the first mapped address.
+ file string // The object this entry is loaded from.
+ buildID string // A string that uniquely identifies a particular program version with high probability.
+
+ funcs symbolizeFlag
+ fake bool // map entry was faked; /proc/self/maps wasn't available
+}
+
+// symbolizeFlag keeps track of symbolization result.
+//
+// 0 : no symbol lookup was performed
+// 1<<0 (lookupTried) : symbol lookup was performed
+// 1<<1 (lookupFailed): symbol lookup was performed but failed
+type symbolizeFlag uint8
+
+const (
+ lookupTried symbolizeFlag = 1 << iota
+ lookupFailed symbolizeFlag = 1 << iota
+)
+
+const (
+ // message Profile
+ tagProfile_SampleType = 1 // repeated ValueType
+ tagProfile_Sample = 2 // repeated Sample
+ tagProfile_Mapping = 3 // repeated Mapping
+ tagProfile_Location = 4 // repeated Location
+ tagProfile_Function = 5 // repeated Function
+ tagProfile_StringTable = 6 // repeated string
+ tagProfile_DropFrames = 7 // int64 (string table index)
+ tagProfile_KeepFrames = 8 // int64 (string table index)
+ tagProfile_TimeNanos = 9 // int64
+ tagProfile_DurationNanos = 10 // int64
+ tagProfile_PeriodType = 11 // ValueType (really optional string???)
+ tagProfile_Period = 12 // int64
+ tagProfile_Comment = 13 // repeated int64
+ tagProfile_DefaultSampleType = 14 // int64
+
+ // message ValueType
+ tagValueType_Type = 1 // int64 (string table index)
+ tagValueType_Unit = 2 // int64 (string table index)
+
+ // message Sample
+ tagSample_Location = 1 // repeated uint64
+ tagSample_Value = 2 // repeated int64
+ tagSample_Label = 3 // repeated Label
+
+ // message Label
+ tagLabel_Key = 1 // int64 (string table index)
+ tagLabel_Str = 2 // int64 (string table index)
+ tagLabel_Num = 3 // int64
+
+ // message Mapping
+ tagMapping_ID = 1 // uint64
+ tagMapping_Start = 2 // uint64
+ tagMapping_Limit = 3 // uint64
+ tagMapping_Offset = 4 // uint64
+ tagMapping_Filename = 5 // int64 (string table index)
+ tagMapping_BuildID = 6 // int64 (string table index)
+ tagMapping_HasFunctions = 7 // bool
+ tagMapping_HasFilenames = 8 // bool
+ tagMapping_HasLineNumbers = 9 // bool
+ tagMapping_HasInlineFrames = 10 // bool
+
+ // message Location
+ tagLocation_ID = 1 // uint64
+ tagLocation_MappingID = 2 // uint64
+ tagLocation_Address = 3 // uint64
+ tagLocation_Line = 4 // repeated Line
+
+ // message Line
+ tagLine_FunctionID = 1 // uint64
+ tagLine_Line = 2 // int64
+
+ // message Function
+ tagFunction_ID = 1 // uint64
+ tagFunction_Name = 2 // int64 (string table index)
+ tagFunction_SystemName = 3 // int64 (string table index)
+ tagFunction_Filename = 4 // int64 (string table index)
+ tagFunction_StartLine = 5 // int64
+)
+
+// stringIndex adds s to the string table if not already present
+// and returns the index of s in the string table.
+func (b *profileBuilder) stringIndex(s string) int64 {
+ id, ok := b.stringMap[s]
+ if !ok {
+ id = len(b.strings)
+ b.strings = append(b.strings, s)
+ b.stringMap[s] = id
+ }
+ return int64(id)
+}
+
+func (b *profileBuilder) flush() {
+ const dataFlush = 4096
+ if b.pb.nest == 0 && len(b.pb.data) > dataFlush {
+ b.zw.Write(b.pb.data)
+ b.pb.data = b.pb.data[:0]
+ }
+}
+
+// pbValueType encodes a ValueType message to b.pb.
+func (b *profileBuilder) pbValueType(tag int, typ, unit string) {
+ start := b.pb.startMessage()
+ b.pb.int64(tagValueType_Type, b.stringIndex(typ))
+ b.pb.int64(tagValueType_Unit, b.stringIndex(unit))
+ b.pb.endMessage(tag, start)
+}
+
+// pbSample encodes a Sample message to b.pb.
+func (b *profileBuilder) pbSample(values []int64, locs []uint64, labels func()) {
+ start := b.pb.startMessage()
+ b.pb.int64s(tagSample_Value, values)
+ b.pb.uint64s(tagSample_Location, locs)
+ if labels != nil {
+ labels()
+ }
+ b.pb.endMessage(tagProfile_Sample, start)
+ b.flush()
+}
+
+// pbLabel encodes a Label message to b.pb.
+func (b *profileBuilder) pbLabel(tag int, key, str string, num int64) {
+ start := b.pb.startMessage()
+ b.pb.int64Opt(tagLabel_Key, b.stringIndex(key))
+ b.pb.int64Opt(tagLabel_Str, b.stringIndex(str))
+ b.pb.int64Opt(tagLabel_Num, num)
+ b.pb.endMessage(tag, start)
+}
+
+// pbLine encodes a Line message to b.pb.
+func (b *profileBuilder) pbLine(tag int, funcID uint64, line int64) {
+ start := b.pb.startMessage()
+ b.pb.uint64Opt(tagLine_FunctionID, funcID)
+ b.pb.int64Opt(tagLine_Line, line)
+ b.pb.endMessage(tag, start)
+}
+
+// pbMapping encodes a Mapping message to b.pb.
+func (b *profileBuilder) pbMapping(tag int, id, base, limit, offset uint64, file, buildID string, hasFuncs bool) {
+ start := b.pb.startMessage()
+ b.pb.uint64Opt(tagMapping_ID, id)
+ b.pb.uint64Opt(tagMapping_Start, base)
+ b.pb.uint64Opt(tagMapping_Limit, limit)
+ b.pb.uint64Opt(tagMapping_Offset, offset)
+ b.pb.int64Opt(tagMapping_Filename, b.stringIndex(file))
+ b.pb.int64Opt(tagMapping_BuildID, b.stringIndex(buildID))
+ // TODO: we set HasFunctions if all symbols from samples were symbolized (hasFuncs).
+ // Decide what to do about HasInlineFrames and HasLineNumbers.
+ // Also, another approach to handle the mapping entry with
+ // incomplete symbolization results is to duplicate the mapping
+ // entry (but with different Has* fields values) and use
+ // different entries for symbolized locations and unsymbolized locations.
+ if hasFuncs {
+ b.pb.bool(tagMapping_HasFunctions, true)
+ }
+ b.pb.endMessage(tag, start)
+}
+
+func allFrames(addr uintptr) ([]runtime.Frame, symbolizeFlag) {
+ // Expand this one address using CallersFrames so we can cache
+ // each expansion. In general, CallersFrames takes a whole
+ // stack, but in this case we know there will be no skips in
+ // the stack and we have return PCs anyway.
+ frames := runtime.CallersFrames([]uintptr{addr})
+ frame, more := frames.Next()
+ if frame.Function == "runtime.goexit" {
+ // Short-circuit if we see runtime.goexit so the loop
+ // below doesn't allocate a useless empty location.
+ return nil, 0
+ }
+
+ symbolizeResult := lookupTried
+ if frame.PC == 0 || frame.Function == "" || frame.File == "" || frame.Line == 0 {
+ symbolizeResult |= lookupFailed
+ }
+
+ if frame.PC == 0 {
+ // If we failed to resolve the frame, at least make up
+ // a reasonable call PC. This mostly happens in tests.
+ frame.PC = addr - 1
+ }
+ ret := []runtime.Frame{frame}
+ for frame.Function != "runtime.goexit" && more {
+ frame, more = frames.Next()
+ ret = append(ret, frame)
+ }
+ return ret, symbolizeResult
+}
+
+type locInfo struct {
+ // location id assigned by the profileBuilder
+ id uint64
+
+ // sequence of PCs, including the fake PCs returned by the traceback
+ // to represent inlined functions
+ // https://github.com/golang/go/blob/d6f2f833c93a41ec1c68e49804b8387a06b131c5/src/runtime/traceback.go#L347-L368
+ pcs []uintptr
+
+ // firstPCFrames and firstPCSymbolizeResult hold the results of the
+ // allFrames call for the first (leaf-most) PC this locInfo represents
+ firstPCFrames []runtime.Frame
+ firstPCSymbolizeResult symbolizeFlag
+}
+
+// newProfileBuilder returns a new profileBuilder.
+// CPU profiling data obtained from the runtime can be added
+// by calling b.addCPUData, and then the eventual profile
+// can be obtained by calling b.finish.
+func newProfileBuilder(w io.Writer) *profileBuilder {
+ zw, _ := gzip.NewWriterLevel(w, gzip.BestSpeed)
+ b := &profileBuilder{
+ w: w,
+ zw: zw,
+ start: time.Now(),
+ strings: []string{""},
+ stringMap: map[string]int{"": 0},
+ locs: map[uintptr]locInfo{},
+ funcs: map[string]int{},
+ }
+ b.readMapping()
+ return b
+}
+
+// addCPUData adds the CPU profiling data to the profile.
+//
+// The data must be a whole number of records, as delivered by the runtime.
+// len(tags) must be equal to the number of records in data.
+func (b *profileBuilder) addCPUData(data []uint64, tags []unsafe.Pointer) error {
+ if !b.havePeriod {
+ // first record is period
+ if len(data) < 3 {
+ return fmt.Errorf("truncated profile")
+ }
+ if data[0] != 3 || data[2] == 0 {
+ return fmt.Errorf("malformed profile")
+ }
+ // data[2] is sampling rate in Hz. Convert to sampling
+ // period in nanoseconds.
+ b.period = 1e9 / int64(data[2])
+ b.havePeriod = true
+ data = data[3:]
+ // Consume tag slot. Note that there isn't a meaningful tag
+ // value for this record.
+ tags = tags[1:]
+ }
+
+ // Parse CPU samples from the profile.
+ // Each sample is 3+n uint64s:
+ // data[0] = 3+n
+ // data[1] = time stamp (ignored)
+ // data[2] = count
+ // data[3:3+n] = stack
+ // If the count is 0 and the stack has length 1,
+ // that's an overflow record inserted by the runtime
+ // to indicate that stack[0] samples were lost.
+ // Otherwise the count is usually 1,
+ // but in a few special cases like lost non-Go samples
+ // there can be larger counts.
+ // Because many samples with the same stack arrive,
+ // we want to deduplicate immediately, which we do
+ // using the b.m profMap.
+ for len(data) > 0 {
+ if len(data) < 3 || data[0] > uint64(len(data)) {
+ return fmt.Errorf("truncated profile")
+ }
+ if data[0] < 3 || tags != nil && len(tags) < 1 {
+ return fmt.Errorf("malformed profile")
+ }
+ if len(tags) < 1 {
+ return fmt.Errorf("mismatched profile records and tags")
+ }
+ count := data[2]
+ stk := data[3:data[0]]
+ data = data[data[0]:]
+ tag := tags[0]
+ tags = tags[1:]
+
+ if count == 0 && len(stk) == 1 {
+ // overflow record
+ count = uint64(stk[0])
+ stk = []uint64{
+ // gentraceback guarantees that PCs in the
+ // stack can be unconditionally decremented and
+ // still be valid, so we must do the same.
+ uint64(abi.FuncPCABIInternal(lostProfileEvent) + 1),
+ }
+ }
+ b.m.lookup(stk, tag).count += int64(count)
+ }
+
+ if len(tags) != 0 {
+ return fmt.Errorf("mismatched profile records and tags")
+ }
+ return nil
+}
+
+// build completes and returns the constructed profile.
+func (b *profileBuilder) build() {
+ b.end = time.Now()
+
+ b.pb.int64Opt(tagProfile_TimeNanos, b.start.UnixNano())
+ if b.havePeriod { // must be CPU profile
+ b.pbValueType(tagProfile_SampleType, "samples", "count")
+ b.pbValueType(tagProfile_SampleType, "cpu", "nanoseconds")
+ b.pb.int64Opt(tagProfile_DurationNanos, b.end.Sub(b.start).Nanoseconds())
+ b.pbValueType(tagProfile_PeriodType, "cpu", "nanoseconds")
+ b.pb.int64Opt(tagProfile_Period, b.period)
+ }
+
+ values := []int64{0, 0}
+ var locs []uint64
+
+ for e := b.m.all; e != nil; e = e.nextAll {
+ values[0] = e.count
+ values[1] = e.count * b.period
+
+ var labels func()
+ if e.tag != nil {
+ labels = func() {
+ for k, v := range *(*labelMap)(e.tag) {
+ b.pbLabel(tagSample_Label, k, v, 0)
+ }
+ }
+ }
+
+ locs = b.appendLocsForStack(locs[:0], e.stk)
+
+ b.pbSample(values, locs, labels)
+ }
+
+ for i, m := range b.mem {
+ hasFunctions := m.funcs == lookupTried // lookupTried but not lookupFailed
+ b.pbMapping(tagProfile_Mapping, uint64(i+1), uint64(m.start), uint64(m.end), m.offset, m.file, m.buildID, hasFunctions)
+ }
+
+ // TODO: Anything for tagProfile_DropFrames?
+ // TODO: Anything for tagProfile_KeepFrames?
+
+ b.pb.strings(tagProfile_StringTable, b.strings)
+ b.zw.Write(b.pb.data)
+ b.zw.Close()
+}
+
+// appendLocsForStack appends the location IDs for the given stack trace to the given
+// location ID slice, locs. The addresses in the stack are return PCs or 1 + the PC of
+// an inline marker as the runtime traceback function returns.
+//
+// It may return an empty slice even if locs is non-empty, for example if locs consists
+// solely of runtime.goexit. We still count these empty stacks in profiles in order to
+// get the right cumulative sample count.
+//
+// It may emit to b.pb, so there must be no message encoding in progress.
+func (b *profileBuilder) appendLocsForStack(locs []uint64, stk []uintptr) (newLocs []uint64) {
+ b.deck.reset()
+
+ // The last frame might be truncated. Recover lost inline frames.
+ stk = runtime_expandFinalInlineFrame(stk)
+
+ for len(stk) > 0 {
+ addr := stk[0]
+ if l, ok := b.locs[addr]; ok {
+ // When generating code for an inlined function, the compiler adds
+ // NOP instructions to the outermost function as a placeholder for
+ // each layer of inlining. When the runtime generates tracebacks for
+ // stacks that include inlined functions, it uses the addresses of
+ // those NOPs as "fake" PCs on the stack as if they were regular
+ // function call sites. But if a profiling signal arrives while the
+ // CPU is executing one of those NOPs, its PC will show up as a leaf
+ // in the profile with its own Location entry. So, always check
+ // whether addr is a "fake" PC in the context of the current call
+ // stack by trying to add it to the inlining deck before assuming
+ // that the deck is complete.
+ if len(b.deck.pcs) > 0 {
+ if added := b.deck.tryAdd(addr, l.firstPCFrames, l.firstPCSymbolizeResult); added {
+ stk = stk[1:]
+ continue
+ }
+ }
+
+ // first record the location if there is any pending accumulated info.
+ if id := b.emitLocation(); id > 0 {
+ locs = append(locs, id)
+ }
+
+ // then, record the cached location.
+ locs = append(locs, l.id)
+
+ // Skip the matching pcs.
+ //
+ // Even if stk was truncated due to the stack depth
+ // limit, expandFinalInlineFrame above has already
+ // fixed the truncation, ensuring it is long enough.
+ stk = stk[len(l.pcs):]
+ continue
+ }
+
+ frames, symbolizeResult := allFrames(addr)
+ if len(frames) == 0 { // runtime.goexit.
+ if id := b.emitLocation(); id > 0 {
+ locs = append(locs, id)
+ }
+ stk = stk[1:]
+ continue
+ }
+
+ if added := b.deck.tryAdd(addr, frames, symbolizeResult); added {
+ stk = stk[1:]
+ continue
+ }
+ // add failed because this addr is not inlined with the
+ // existing PCs in the deck. Flush the deck and retry handling
+ // this pc.
+ if id := b.emitLocation(); id > 0 {
+ locs = append(locs, id)
+ }
+
+ // check cache again - previous emitLocation added a new entry
+ if l, ok := b.locs[addr]; ok {
+ locs = append(locs, l.id)
+ stk = stk[len(l.pcs):] // skip the matching pcs.
+ } else {
+ b.deck.tryAdd(addr, frames, symbolizeResult) // must succeed.
+ stk = stk[1:]
+ }
+ }
+ if id := b.emitLocation(); id > 0 { // emit remaining location.
+ locs = append(locs, id)
+ }
+ return locs
+}
+
+// Here's an example of how Go 1.17 writes out inlined functions, compiled for
+// linux/amd64. The disassembly of main.main shows two levels of inlining: main
+// calls b, b calls a, a does some work.
+//
+// inline.go:9 0x4553ec 90 NOPL // func main() { b(v) }
+// inline.go:6 0x4553ed 90 NOPL // func b(v *int) { a(v) }
+// inline.go:5 0x4553ee 48c7002a000000 MOVQ $0x2a, 0(AX) // func a(v *int) { *v = 42 }
+//
+// If a profiling signal arrives while executing the MOVQ at 0x4553ee (for line
+// 5), the runtime will report the stack as the MOVQ frame being called by the
+// NOPL at 0x4553ed (for line 6) being called by the NOPL at 0x4553ec (for line
+// 9).
+//
+// The role of pcDeck is to collapse those three frames back into a single
+// location at 0x4553ee, with file/line/function symbolization info representing
+// the three layers of calls. It does that via sequential calls to pcDeck.tryAdd
+// starting with the leaf-most address. The fourth call to pcDeck.tryAdd will be
+// for the caller of main.main. Because main.main was not inlined in its caller,
+// the deck will reject the addition, and the fourth PC on the stack will get
+// its own location.
+
+// pcDeck is a helper to detect a sequence of inlined functions from
+// a stack trace returned by the runtime.
+//
+// The stack traces returned by runtime's trackback functions are fully
+// expanded (at least for Go functions) and include the fake pcs representing
+// inlined functions. The profile proto expects the inlined functions to be
+// encoded in one Location message.
+// https://github.com/google/pprof/blob/5e965273ee43930341d897407202dd5e10e952cb/proto/profile.proto#L177-L184
+//
+// Runtime does not directly expose whether a frame is for an inlined function
+// and looking up debug info is not ideal, so we use a heuristic to filter
+// the fake pcs and restore the inlined and entry functions. Inlined functions
+// have the following properties:
+//
+// Frame's Func is nil (note: also true for non-Go functions), and
+// Frame's Entry matches its entry function frame's Entry (note: could also be true for recursive calls and non-Go functions), and
+// Frame's Name does not match its entry function frame's name (note: inlined functions cannot be directly recursive).
+//
+// As reading and processing the pcs in a stack trace one by one (from leaf to the root),
+// we use pcDeck to temporarily hold the observed pcs and their expanded frames
+// until we observe the entry function frame.
+type pcDeck struct {
+ pcs []uintptr
+ frames []runtime.Frame
+ symbolizeResult symbolizeFlag
+
+ // firstPCFrames indicates the number of frames associated with the first
+ // (leaf-most) PC in the deck
+ firstPCFrames int
+ // firstPCSymbolizeResult holds the results of the allFrames call for the
+ // first (leaf-most) PC in the deck
+ firstPCSymbolizeResult symbolizeFlag
+}
+
+func (d *pcDeck) reset() {
+ d.pcs = d.pcs[:0]
+ d.frames = d.frames[:0]
+ d.symbolizeResult = 0
+ d.firstPCFrames = 0
+ d.firstPCSymbolizeResult = 0
+}
+
+// tryAdd tries to add the pc and Frames expanded from it (most likely one,
+// since the stack trace is already fully expanded) and the symbolizeResult
+// to the deck. If it fails the caller needs to flush the deck and retry.
+func (d *pcDeck) tryAdd(pc uintptr, frames []runtime.Frame, symbolizeResult symbolizeFlag) (success bool) {
+ if existing := len(d.frames); existing > 0 {
+ // 'd.frames' are all expanded from one 'pc' and represent all
+ // inlined functions so we check only the last one.
+ newFrame := frames[0]
+ last := d.frames[existing-1]
+ if last.Func != nil { // the last frame can't be inlined. Flush.
+ return false
+ }
+ if last.Entry == 0 || newFrame.Entry == 0 { // Possibly not a Go function. Don't try to merge.
+ return false
+ }
+
+ if last.Entry != newFrame.Entry { // newFrame is for a different function.
+ return false
+ }
+ if last.Function == newFrame.Function { // maybe recursion.
+ return false
+ }
+ }
+ d.pcs = append(d.pcs, pc)
+ d.frames = append(d.frames, frames...)
+ d.symbolizeResult |= symbolizeResult
+ if len(d.pcs) == 1 {
+ d.firstPCFrames = len(d.frames)
+ d.firstPCSymbolizeResult = symbolizeResult
+ }
+ return true
+}
+
+// emitLocation emits the new location and function information recorded in the deck
+// and returns the location ID encoded in the profile protobuf.
+// It emits to b.pb, so there must be no message encoding in progress.
+// It resets the deck.
+func (b *profileBuilder) emitLocation() uint64 {
+ if len(b.deck.pcs) == 0 {
+ return 0
+ }
+ defer b.deck.reset()
+
+ addr := b.deck.pcs[0]
+ firstFrame := b.deck.frames[0]
+
+ // We can't write out functions while in the middle of the
+ // Location message, so record new functions we encounter and
+ // write them out after the Location.
+ type newFunc struct {
+ id uint64
+ name, file string
+ startLine int64
+ }
+ newFuncs := make([]newFunc, 0, 8)
+
+ id := uint64(len(b.locs)) + 1
+ b.locs[addr] = locInfo{
+ id: id,
+ pcs: append([]uintptr{}, b.deck.pcs...),
+ firstPCSymbolizeResult: b.deck.firstPCSymbolizeResult,
+ firstPCFrames: append([]runtime.Frame{}, b.deck.frames[:b.deck.firstPCFrames]...),
+ }
+
+ start := b.pb.startMessage()
+ b.pb.uint64Opt(tagLocation_ID, id)
+ b.pb.uint64Opt(tagLocation_Address, uint64(firstFrame.PC))
+ for _, frame := range b.deck.frames {
+ // Write out each line in frame expansion.
+ funcID := uint64(b.funcs[frame.Function])
+ if funcID == 0 {
+ funcID = uint64(len(b.funcs)) + 1
+ b.funcs[frame.Function] = int(funcID)
+ newFuncs = append(newFuncs, newFunc{
+ id: funcID,
+ name: runtime_FrameSymbolName(&frame),
+ file: frame.File,
+ startLine: int64(runtime_FrameStartLine(&frame)),
+ })
+ }
+ b.pbLine(tagLocation_Line, funcID, int64(frame.Line))
+ }
+ for i := range b.mem {
+ if b.mem[i].start <= addr && addr < b.mem[i].end || b.mem[i].fake {
+ b.pb.uint64Opt(tagLocation_MappingID, uint64(i+1))
+
+ m := b.mem[i]
+ m.funcs |= b.deck.symbolizeResult
+ b.mem[i] = m
+ break
+ }
+ }
+ b.pb.endMessage(tagProfile_Location, start)
+
+ // Write out functions we found during frame expansion.
+ for _, fn := range newFuncs {
+ start := b.pb.startMessage()
+ b.pb.uint64Opt(tagFunction_ID, fn.id)
+ b.pb.int64Opt(tagFunction_Name, b.stringIndex(fn.name))
+ b.pb.int64Opt(tagFunction_SystemName, b.stringIndex(fn.name))
+ b.pb.int64Opt(tagFunction_Filename, b.stringIndex(fn.file))
+ b.pb.int64Opt(tagFunction_StartLine, fn.startLine)
+ b.pb.endMessage(tagProfile_Function, start)
+ }
+
+ b.flush()
+ return id
+}
+
+var space = []byte(" ")
+var newline = []byte("\n")
+
+func parseProcSelfMaps(data []byte, addMapping func(lo, hi, offset uint64, file, buildID string)) {
+ // $ cat /proc/self/maps
+ // 00400000-0040b000 r-xp 00000000 fc:01 787766 /bin/cat
+ // 0060a000-0060b000 r--p 0000a000 fc:01 787766 /bin/cat
+ // 0060b000-0060c000 rw-p 0000b000 fc:01 787766 /bin/cat
+ // 014ab000-014cc000 rw-p 00000000 00:00 0 [heap]
+ // 7f7d76af8000-7f7d7797c000 r--p 00000000 fc:01 1318064 /usr/lib/locale/locale-archive
+ // 7f7d7797c000-7f7d77b36000 r-xp 00000000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
+ // 7f7d77b36000-7f7d77d36000 ---p 001ba000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
+ // 7f7d77d36000-7f7d77d3a000 r--p 001ba000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
+ // 7f7d77d3a000-7f7d77d3c000 rw-p 001be000 fc:01 1180226 /lib/x86_64-linux-gnu/libc-2.19.so
+ // 7f7d77d3c000-7f7d77d41000 rw-p 00000000 00:00 0
+ // 7f7d77d41000-7f7d77d64000 r-xp 00000000 fc:01 1180217 /lib/x86_64-linux-gnu/ld-2.19.so
+ // 7f7d77f3f000-7f7d77f42000 rw-p 00000000 00:00 0
+ // 7f7d77f61000-7f7d77f63000 rw-p 00000000 00:00 0
+ // 7f7d77f63000-7f7d77f64000 r--p 00022000 fc:01 1180217 /lib/x86_64-linux-gnu/ld-2.19.so
+ // 7f7d77f64000-7f7d77f65000 rw-p 00023000 fc:01 1180217 /lib/x86_64-linux-gnu/ld-2.19.so
+ // 7f7d77f65000-7f7d77f66000 rw-p 00000000 00:00 0
+ // 7ffc342a2000-7ffc342c3000 rw-p 00000000 00:00 0 [stack]
+ // 7ffc34343000-7ffc34345000 r-xp 00000000 00:00 0 [vdso]
+ // ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
+
+ var line []byte
+ // next removes and returns the next field in the line.
+ // It also removes from line any spaces following the field.
+ next := func() []byte {
+ var f []byte
+ f, line, _ = bytes.Cut(line, space)
+ line = bytes.TrimLeft(line, " ")
+ return f
+ }
+
+ for len(data) > 0 {
+ line, data, _ = bytes.Cut(data, newline)
+ addr := next()
+ loStr, hiStr, ok := strings.Cut(string(addr), "-")
+ if !ok {
+ continue
+ }
+ lo, err := strconv.ParseUint(loStr, 16, 64)
+ if err != nil {
+ continue
+ }
+ hi, err := strconv.ParseUint(hiStr, 16, 64)
+ if err != nil {
+ continue
+ }
+ perm := next()
+ if len(perm) < 4 || perm[2] != 'x' {
+ // Only interested in executable mappings.
+ continue
+ }
+ offset, err := strconv.ParseUint(string(next()), 16, 64)
+ if err != nil {
+ continue
+ }
+ next() // dev
+ inode := next() // inode
+ if line == nil {
+ continue
+ }
+ file := string(line)
+
+ // Trim deleted file marker.
+ deletedStr := " (deleted)"
+ deletedLen := len(deletedStr)
+ if len(file) >= deletedLen && file[len(file)-deletedLen:] == deletedStr {
+ file = file[:len(file)-deletedLen]
+ }
+
+ if len(inode) == 1 && inode[0] == '0' && file == "" {
+ // Huge-page text mappings list the initial fragment of
+ // mapped but unpopulated memory as being inode 0.
+ // Don't report that part.
+ // But [vdso] and [vsyscall] are inode 0, so let non-empty file names through.
+ continue
+ }
+
+ // TODO: pprof's remapMappingIDs makes one adjustment:
+ // 1. If there is an /anon_hugepage mapping first and it is
+ // consecutive to a next mapping, drop the /anon_hugepage.
+ // There's no indication why this is needed.
+ // Let's try not doing this and see what breaks.
+ // If we do need it, it would go here, before we
+ // enter the mappings into b.mem in the first place.
+
+ buildID, _ := elfBuildID(file)
+ addMapping(lo, hi, offset, file, buildID)
+ }
+}
+
+func (b *profileBuilder) addMapping(lo, hi, offset uint64, file, buildID string) {
+ b.addMappingEntry(lo, hi, offset, file, buildID, false)
+}
+
+func (b *profileBuilder) addMappingEntry(lo, hi, offset uint64, file, buildID string, fake bool) {
+ b.mem = append(b.mem, memMap{
+ start: uintptr(lo),
+ end: uintptr(hi),
+ offset: offset,
+ file: file,
+ buildID: buildID,
+ fake: fake,
+ })
+}
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/proto_other.go b/contrib/go/_std_1.21/src/runtime/pprof/proto_other.go
index 4a7fe79501..4a7fe79501 100644
--- a/contrib/go/_std_1.20/src/runtime/pprof/proto_other.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/proto_other.go
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/proto_windows.go b/contrib/go/_std_1.21/src/runtime/pprof/proto_windows.go
index d5ae4a5eec..d5ae4a5eec 100644
--- a/contrib/go/_std_1.20/src/runtime/pprof/proto_windows.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/proto_windows.go
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/protobuf.go b/contrib/go/_std_1.21/src/runtime/pprof/protobuf.go
index f7ec1ac59c..f7ec1ac59c 100644
--- a/contrib/go/_std_1.20/src/runtime/pprof/protobuf.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/protobuf.go
diff --git a/contrib/go/_std_1.20/src/runtime/pprof/protomem.go b/contrib/go/_std_1.21/src/runtime/pprof/protomem.go
index fa75a28c62..fa75a28c62 100644
--- a/contrib/go/_std_1.20/src/runtime/pprof/protomem.go
+++ b/contrib/go/_std_1.21/src/runtime/pprof/protomem.go
diff --git a/contrib/go/_std_1.21/src/runtime/pprof/runtime.go b/contrib/go/_std_1.21/src/runtime/pprof/runtime.go
new file mode 100644
index 0000000000..71f89ca680
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/pprof/runtime.go
@@ -0,0 +1,52 @@
+// Copyright 2017 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 pprof
+
+import (
+ "context"
+ "runtime"
+ "unsafe"
+)
+
+// runtime_FrameStartLine is defined in runtime/symtab.go.
+//
+//go:noescape
+func runtime_FrameStartLine(f *runtime.Frame) int
+
+// runtime_FrameSymbolName is defined in runtime/symtab.go.
+//
+//go:noescape
+func runtime_FrameSymbolName(f *runtime.Frame) string
+
+// runtime_expandFinalInlineFrame is defined in runtime/symtab.go.
+func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr
+
+// runtime_setProfLabel is defined in runtime/proflabel.go.
+func runtime_setProfLabel(labels unsafe.Pointer)
+
+// runtime_getProfLabel is defined in runtime/proflabel.go.
+func runtime_getProfLabel() unsafe.Pointer
+
+// SetGoroutineLabels sets the current goroutine's labels to match ctx.
+// A new goroutine inherits the labels of the goroutine that created it.
+// This is a lower-level API than Do, which should be used instead when possible.
+func SetGoroutineLabels(ctx context.Context) {
+ ctxLabels, _ := ctx.Value(labelContextKey{}).(*labelMap)
+ runtime_setProfLabel(unsafe.Pointer(ctxLabels))
+}
+
+// Do calls f with a copy of the parent context with the
+// given labels added to the parent's label map.
+// Goroutines spawned while executing f will inherit the augmented label-set.
+// Each key/value pair in labels is inserted into the label map in the
+// order provided, overriding any previous value for the same key.
+// The augmented label map will be set for the duration of the call to f
+// and restored once f returns.
+func Do(ctx context.Context, labels LabelSet, f func(context.Context)) {
+ defer SetGoroutineLabels(ctx)
+ ctx = WithLabels(ctx, labels)
+ SetGoroutineLabels(ctx)
+ f(ctx)
+}
diff --git a/contrib/go/_std_1.21/src/runtime/pprof/ya.make b/contrib/go/_std_1.21/src/runtime/pprof/ya.make
new file mode 100644
index 0000000000..578cc4e9b8
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/pprof/ya.make
@@ -0,0 +1,52 @@
+GO_LIBRARY()
+
+SRCS(
+ elf.go
+ label.go
+ map.go
+ pe.go
+ pprof.go
+ proto.go
+ protobuf.go
+ protomem.go
+ runtime.go
+)
+
+GO_TEST_SRCS(
+ label_test.go
+ mprof_test.go
+ pprof_test.go
+ proto_test.go
+ protomem_test.go
+ runtime_test.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ pprof_rusage.go
+ proto_other.go
+ )
+
+ GO_TEST_SRCS(rusage_test.go)
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ pprof_rusage.go
+ proto_other.go
+ )
+
+ GO_TEST_SRCS(rusage_test.go)
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ pprof_windows.go
+ proto_windows.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/runtime/preempt.go b/contrib/go/_std_1.21/src/runtime/preempt.go
new file mode 100644
index 0000000000..76d8ba4cdf
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/preempt.go
@@ -0,0 +1,447 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Goroutine preemption
+//
+// A goroutine can be preempted at any safe-point. Currently, there
+// are a few categories of safe-points:
+//
+// 1. A blocked safe-point occurs for the duration that a goroutine is
+// descheduled, blocked on synchronization, or in a system call.
+//
+// 2. Synchronous safe-points occur when a running goroutine checks
+// for a preemption request.
+//
+// 3. Asynchronous safe-points occur at any instruction in user code
+// where the goroutine can be safely paused and a conservative
+// stack and register scan can find stack roots. The runtime can
+// stop a goroutine at an async safe-point using a signal.
+//
+// At both blocked and synchronous safe-points, a goroutine's CPU
+// state is minimal and the garbage collector has complete information
+// about its entire stack. This makes it possible to deschedule a
+// goroutine with minimal space, and to precisely scan a goroutine's
+// stack.
+//
+// Synchronous safe-points are implemented by overloading the stack
+// bound check in function prologues. To preempt a goroutine at the
+// next synchronous safe-point, the runtime poisons the goroutine's
+// stack bound to a value that will cause the next stack bound check
+// to fail and enter the stack growth implementation, which will
+// detect that it was actually a preemption and redirect to preemption
+// handling.
+//
+// Preemption at asynchronous safe-points is implemented by suspending
+// the thread using an OS mechanism (e.g., signals) and inspecting its
+// state to determine if the goroutine was at an asynchronous
+// safe-point. Since the thread suspension itself is generally
+// asynchronous, it also checks if the running goroutine wants to be
+// preempted, since this could have changed. If all conditions are
+// satisfied, it adjusts the signal context to make it look like the
+// signaled thread just called asyncPreempt and resumes the thread.
+// asyncPreempt spills all registers and enters the scheduler.
+//
+// (An alternative would be to preempt in the signal handler itself.
+// This would let the OS save and restore the register state and the
+// runtime would only need to know how to extract potentially
+// pointer-containing registers from the signal context. However, this
+// would consume an M for every preempted G, and the scheduler itself
+// is not designed to run from a signal handler, as it tends to
+// allocate memory and start threads in the preemption path.)
+
+package runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+)
+
+type suspendGState struct {
+ g *g
+
+ // dead indicates the goroutine was not suspended because it
+ // is dead. This goroutine could be reused after the dead
+ // state was observed, so the caller must not assume that it
+ // remains dead.
+ dead bool
+
+ // stopped indicates that this suspendG transitioned the G to
+ // _Gwaiting via g.preemptStop and thus is responsible for
+ // readying it when done.
+ stopped bool
+}
+
+// suspendG suspends goroutine gp at a safe-point and returns the
+// state of the suspended goroutine. The caller gets read access to
+// the goroutine until it calls resumeG.
+//
+// It is safe for multiple callers to attempt to suspend the same
+// goroutine at the same time. The goroutine may execute between
+// subsequent successful suspend operations. The current
+// implementation grants exclusive access to the goroutine, and hence
+// multiple callers will serialize. However, the intent is to grant
+// shared read access, so please don't depend on exclusive access.
+//
+// This must be called from the system stack and the user goroutine on
+// the current M (if any) must be in a preemptible state. This
+// prevents deadlocks where two goroutines attempt to suspend each
+// other and both are in non-preemptible states. There are other ways
+// to resolve this deadlock, but this seems simplest.
+//
+// TODO(austin): What if we instead required this to be called from a
+// user goroutine? Then we could deschedule the goroutine while
+// waiting instead of blocking the thread. If two goroutines tried to
+// suspend each other, one of them would win and the other wouldn't
+// complete the suspend until it was resumed. We would have to be
+// careful that they couldn't actually queue up suspend for each other
+// and then both be suspended. This would also avoid the need for a
+// kernel context switch in the synchronous case because we could just
+// directly schedule the waiter. The context switch is unavoidable in
+// the signal case.
+//
+//go:systemstack
+func suspendG(gp *g) suspendGState {
+ if mp := getg().m; mp.curg != nil && readgstatus(mp.curg) == _Grunning {
+ // Since we're on the system stack of this M, the user
+ // G is stuck at an unsafe point. If another goroutine
+ // were to try to preempt m.curg, it could deadlock.
+ throw("suspendG from non-preemptible goroutine")
+ }
+
+ // See https://golang.org/cl/21503 for justification of the yield delay.
+ const yieldDelay = 10 * 1000
+ var nextYield int64
+
+ // Drive the goroutine to a preemption point.
+ stopped := false
+ var asyncM *m
+ var asyncGen uint32
+ var nextPreemptM int64
+ for i := 0; ; i++ {
+ switch s := readgstatus(gp); s {
+ default:
+ if s&_Gscan != 0 {
+ // Someone else is suspending it. Wait
+ // for them to finish.
+ //
+ // TODO: It would be nicer if we could
+ // coalesce suspends.
+ break
+ }
+
+ dumpgstatus(gp)
+ throw("invalid g status")
+
+ case _Gdead:
+ // Nothing to suspend.
+ //
+ // preemptStop may need to be cleared, but
+ // doing that here could race with goroutine
+ // reuse. Instead, goexit0 clears it.
+ return suspendGState{dead: true}
+
+ case _Gcopystack:
+ // The stack is being copied. We need to wait
+ // until this is done.
+
+ case _Gpreempted:
+ // We (or someone else) suspended the G. Claim
+ // ownership of it by transitioning it to
+ // _Gwaiting.
+ if !casGFromPreempted(gp, _Gpreempted, _Gwaiting) {
+ break
+ }
+
+ // We stopped the G, so we have to ready it later.
+ stopped = true
+
+ s = _Gwaiting
+ fallthrough
+
+ case _Grunnable, _Gsyscall, _Gwaiting:
+ // Claim goroutine by setting scan bit.
+ // This may race with execution or readying of gp.
+ // The scan bit keeps it from transition state.
+ if !castogscanstatus(gp, s, s|_Gscan) {
+ break
+ }
+
+ // Clear the preemption request. It's safe to
+ // reset the stack guard because we hold the
+ // _Gscan bit and thus own the stack.
+ gp.preemptStop = false
+ gp.preempt = false
+ gp.stackguard0 = gp.stack.lo + stackGuard
+
+ // The goroutine was already at a safe-point
+ // and we've now locked that in.
+ //
+ // TODO: It would be much better if we didn't
+ // leave it in _Gscan, but instead gently
+ // prevented its scheduling until resumption.
+ // Maybe we only use this to bump a suspended
+ // count and the scheduler skips suspended
+ // goroutines? That wouldn't be enough for
+ // {_Gsyscall,_Gwaiting} -> _Grunning. Maybe
+ // for all those transitions we need to check
+ // suspended and deschedule?
+ return suspendGState{g: gp, stopped: stopped}
+
+ case _Grunning:
+ // Optimization: if there is already a pending preemption request
+ // (from the previous loop iteration), don't bother with the atomics.
+ if gp.preemptStop && gp.preempt && gp.stackguard0 == stackPreempt && asyncM == gp.m && asyncM.preemptGen.Load() == asyncGen {
+ break
+ }
+
+ // Temporarily block state transitions.
+ if !castogscanstatus(gp, _Grunning, _Gscanrunning) {
+ break
+ }
+
+ // Request synchronous preemption.
+ gp.preemptStop = true
+ gp.preempt = true
+ gp.stackguard0 = stackPreempt
+
+ // Prepare for asynchronous preemption.
+ asyncM2 := gp.m
+ asyncGen2 := asyncM2.preemptGen.Load()
+ needAsync := asyncM != asyncM2 || asyncGen != asyncGen2
+ asyncM = asyncM2
+ asyncGen = asyncGen2
+
+ casfrom_Gscanstatus(gp, _Gscanrunning, _Grunning)
+
+ // Send asynchronous preemption. We do this
+ // after CASing the G back to _Grunning
+ // because preemptM may be synchronous and we
+ // don't want to catch the G just spinning on
+ // its status.
+ if preemptMSupported && debug.asyncpreemptoff == 0 && needAsync {
+ // Rate limit preemptM calls. This is
+ // particularly important on Windows
+ // where preemptM is actually
+ // synchronous and the spin loop here
+ // can lead to live-lock.
+ now := nanotime()
+ if now >= nextPreemptM {
+ nextPreemptM = now + yieldDelay/2
+ preemptM(asyncM)
+ }
+ }
+ }
+
+ // TODO: Don't busy wait. This loop should really only
+ // be a simple read/decide/CAS loop that only fails if
+ // there's an active race. Once the CAS succeeds, we
+ // should queue up the preemption (which will require
+ // it to be reliable in the _Grunning case, not
+ // best-effort) and then sleep until we're notified
+ // that the goroutine is suspended.
+ if i == 0 {
+ nextYield = nanotime() + yieldDelay
+ }
+ if nanotime() < nextYield {
+ procyield(10)
+ } else {
+ osyield()
+ nextYield = nanotime() + yieldDelay/2
+ }
+ }
+}
+
+// resumeG undoes the effects of suspendG, allowing the suspended
+// goroutine to continue from its current safe-point.
+func resumeG(state suspendGState) {
+ if state.dead {
+ // We didn't actually stop anything.
+ return
+ }
+
+ gp := state.g
+ switch s := readgstatus(gp); s {
+ default:
+ dumpgstatus(gp)
+ throw("unexpected g status")
+
+ case _Grunnable | _Gscan,
+ _Gwaiting | _Gscan,
+ _Gsyscall | _Gscan:
+ casfrom_Gscanstatus(gp, s, s&^_Gscan)
+ }
+
+ if state.stopped {
+ // We stopped it, so we need to re-schedule it.
+ ready(gp, 0, true)
+ }
+}
+
+// canPreemptM reports whether mp is in a state that is safe to preempt.
+//
+// It is nosplit because it has nosplit callers.
+//
+//go:nosplit
+func canPreemptM(mp *m) bool {
+ return mp.locks == 0 && mp.mallocing == 0 && mp.preemptoff == "" && mp.p.ptr().status == _Prunning
+}
+
+//go:generate go run mkpreempt.go
+
+// asyncPreempt saves all user registers and calls asyncPreempt2.
+//
+// When stack scanning encounters an asyncPreempt frame, it scans that
+// frame and its parent frame conservatively.
+//
+// asyncPreempt is implemented in assembly.
+func asyncPreempt()
+
+//go:nosplit
+func asyncPreempt2() {
+ gp := getg()
+ gp.asyncSafePoint = true
+ if gp.preemptStop {
+ mcall(preemptPark)
+ } else {
+ mcall(gopreempt_m)
+ }
+ gp.asyncSafePoint = false
+}
+
+// asyncPreemptStack is the bytes of stack space required to inject an
+// asyncPreempt call.
+var asyncPreemptStack = ^uintptr(0)
+
+func init() {
+ f := findfunc(abi.FuncPCABI0(asyncPreempt))
+ total := funcMaxSPDelta(f)
+ f = findfunc(abi.FuncPCABIInternal(asyncPreempt2))
+ total += funcMaxSPDelta(f)
+ // Add some overhead for return PCs, etc.
+ asyncPreemptStack = uintptr(total) + 8*goarch.PtrSize
+ if asyncPreemptStack > stackNosplit {
+ // We need more than the nosplit limit. This isn't
+ // unsafe, but it may limit asynchronous preemption.
+ //
+ // This may be a problem if we start using more
+ // registers. In that case, we should store registers
+ // in a context object. If we pre-allocate one per P,
+ // asyncPreempt can spill just a few registers to the
+ // stack, then grab its context object and spill into
+ // it. When it enters the runtime, it would allocate a
+ // new context for the P.
+ print("runtime: asyncPreemptStack=", asyncPreemptStack, "\n")
+ throw("async stack too large")
+ }
+}
+
+// wantAsyncPreempt returns whether an asynchronous preemption is
+// queued for gp.
+func wantAsyncPreempt(gp *g) bool {
+ // Check both the G and the P.
+ return (gp.preempt || gp.m.p != 0 && gp.m.p.ptr().preempt) && readgstatus(gp)&^_Gscan == _Grunning
+}
+
+// isAsyncSafePoint reports whether gp at instruction PC is an
+// asynchronous safe point. This indicates that:
+//
+// 1. It's safe to suspend gp and conservatively scan its stack and
+// registers. There are no potentially hidden pointer values and it's
+// not in the middle of an atomic sequence like a write barrier.
+//
+// 2. gp has enough stack space to inject the asyncPreempt call.
+//
+// 3. It's generally safe to interact with the runtime, even if we're
+// in a signal handler stopped here. For example, there are no runtime
+// locks held, so acquiring a runtime lock won't self-deadlock.
+//
+// In some cases the PC is safe for asynchronous preemption but it
+// also needs to adjust the resumption PC. The new PC is returned in
+// the second result.
+func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) (bool, uintptr) {
+ mp := gp.m
+
+ // Only user Gs can have safe-points. We check this first
+ // because it's extremely common that we'll catch mp in the
+ // scheduler processing this G preemption.
+ if mp.curg != gp {
+ return false, 0
+ }
+
+ // Check M state.
+ if mp.p == 0 || !canPreemptM(mp) {
+ return false, 0
+ }
+
+ // Check stack space.
+ if sp < gp.stack.lo || sp-gp.stack.lo < asyncPreemptStack {
+ return false, 0
+ }
+
+ // Check if PC is an unsafe-point.
+ f := findfunc(pc)
+ if !f.valid() {
+ // Not Go code.
+ return false, 0
+ }
+ if (GOARCH == "mips" || GOARCH == "mipsle" || GOARCH == "mips64" || GOARCH == "mips64le") && lr == pc+8 && funcspdelta(f, pc, nil) == 0 {
+ // We probably stopped at a half-executed CALL instruction,
+ // where the LR is updated but the PC has not. If we preempt
+ // here we'll see a seemingly self-recursive call, which is in
+ // fact not.
+ // This is normally ok, as we use the return address saved on
+ // stack for unwinding, not the LR value. But if this is a
+ // call to morestack, we haven't created the frame, and we'll
+ // use the LR for unwinding, which will be bad.
+ return false, 0
+ }
+ up, startpc := pcdatavalue2(f, abi.PCDATA_UnsafePoint, pc)
+ if up == abi.UnsafePointUnsafe {
+ // Unsafe-point marked by compiler. This includes
+ // atomic sequences (e.g., write barrier) and nosplit
+ // functions (except at calls).
+ return false, 0
+ }
+ if fd := funcdata(f, abi.FUNCDATA_LocalsPointerMaps); fd == nil || f.flag&abi.FuncFlagAsm != 0 {
+ // This is assembly code. Don't assume it's well-formed.
+ // TODO: Empirically we still need the fd == nil check. Why?
+ //
+ // TODO: Are there cases that are safe but don't have a
+ // locals pointer map, like empty frame functions?
+ // It might be possible to preempt any assembly functions
+ // except the ones that have funcFlag_SPWRITE set in f.flag.
+ return false, 0
+ }
+ // Check the inner-most name
+ u, uf := newInlineUnwinder(f, pc, nil)
+ name := u.srcFunc(uf).name()
+ if hasPrefix(name, "runtime.") ||
+ hasPrefix(name, "runtime/internal/") ||
+ hasPrefix(name, "reflect.") {
+ // For now we never async preempt the runtime or
+ // anything closely tied to the runtime. Known issues
+ // include: various points in the scheduler ("don't
+ // preempt between here and here"), much of the defer
+ // implementation (untyped info on stack), bulk write
+ // barriers (write barrier check),
+ // reflect.{makeFuncStub,methodValueCall}.
+ //
+ // TODO(austin): We should improve this, or opt things
+ // in incrementally.
+ return false, 0
+ }
+ switch up {
+ case abi.UnsafePointRestart1, abi.UnsafePointRestart2:
+ // Restartable instruction sequence. Back off PC to
+ // the start PC.
+ if startpc == 0 || startpc > pc || pc-startpc > 20 {
+ throw("bad restart PC")
+ }
+ return true, startpc
+ case abi.UnsafePointRestartAtEntry:
+ // Restart from the function entry at resumption.
+ return true, f.entry()
+ }
+ return true, pc
+}
diff --git a/contrib/go/_std_1.20/src/runtime/preempt_amd64.s b/contrib/go/_std_1.21/src/runtime/preempt_amd64.s
index 94a84fb74c..94a84fb74c 100644
--- a/contrib/go/_std_1.20/src/runtime/preempt_amd64.s
+++ b/contrib/go/_std_1.21/src/runtime/preempt_amd64.s
diff --git a/contrib/go/_std_1.20/src/runtime/preempt_arm64.s b/contrib/go/_std_1.21/src/runtime/preempt_arm64.s
index c27d475dee..c27d475dee 100644
--- a/contrib/go/_std_1.20/src/runtime/preempt_arm64.s
+++ b/contrib/go/_std_1.21/src/runtime/preempt_arm64.s
diff --git a/contrib/go/_std_1.20/src/runtime/preempt_nonwindows.go b/contrib/go/_std_1.21/src/runtime/preempt_nonwindows.go
index d6a2408cb7..d6a2408cb7 100644
--- a/contrib/go/_std_1.20/src/runtime/preempt_nonwindows.go
+++ b/contrib/go/_std_1.21/src/runtime/preempt_nonwindows.go
diff --git a/contrib/go/_std_1.21/src/runtime/print.go b/contrib/go/_std_1.21/src/runtime/print.go
new file mode 100644
index 0000000000..0b05aedad3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/print.go
@@ -0,0 +1,301 @@
+// Copyright 2009 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 runtime
+
+import (
+ "internal/goarch"
+ "unsafe"
+)
+
+// The compiler knows that a print of a value of this type
+// should use printhex instead of printuint (decimal).
+type hex uint64
+
+func bytes(s string) (ret []byte) {
+ rp := (*slice)(unsafe.Pointer(&ret))
+ sp := stringStructOf(&s)
+ rp.array = sp.str
+ rp.len = sp.len
+ rp.cap = sp.len
+ return
+}
+
+var (
+ // printBacklog is a circular buffer of messages written with the builtin
+ // print* functions, for use in postmortem analysis of core dumps.
+ printBacklog [512]byte
+ printBacklogIndex int
+)
+
+// recordForPanic maintains a circular buffer of messages written by the
+// runtime leading up to a process crash, allowing the messages to be
+// extracted from a core dump.
+//
+// The text written during a process crash (following "panic" or "fatal
+// error") is not saved, since the goroutine stacks will generally be readable
+// from the runtime data structures in the core file.
+func recordForPanic(b []byte) {
+ printlock()
+
+ if panicking.Load() == 0 {
+ // Not actively crashing: maintain circular buffer of print output.
+ for i := 0; i < len(b); {
+ n := copy(printBacklog[printBacklogIndex:], b[i:])
+ i += n
+ printBacklogIndex += n
+ printBacklogIndex %= len(printBacklog)
+ }
+ }
+
+ printunlock()
+}
+
+var debuglock mutex
+
+// The compiler emits calls to printlock and printunlock around
+// the multiple calls that implement a single Go print or println
+// statement. Some of the print helpers (printslice, for example)
+// call print recursively. There is also the problem of a crash
+// happening during the print routines and needing to acquire
+// the print lock to print information about the crash.
+// For both these reasons, let a thread acquire the printlock 'recursively'.
+
+func printlock() {
+ mp := getg().m
+ mp.locks++ // do not reschedule between printlock++ and lock(&debuglock).
+ mp.printlock++
+ if mp.printlock == 1 {
+ lock(&debuglock)
+ }
+ mp.locks-- // now we know debuglock is held and holding up mp.locks for us.
+}
+
+func printunlock() {
+ mp := getg().m
+ mp.printlock--
+ if mp.printlock == 0 {
+ unlock(&debuglock)
+ }
+}
+
+// write to goroutine-local buffer if diverting output,
+// or else standard error.
+func gwrite(b []byte) {
+ if len(b) == 0 {
+ return
+ }
+ recordForPanic(b)
+ gp := getg()
+ // Don't use the writebuf if gp.m is dying. We want anything
+ // written through gwrite to appear in the terminal rather
+ // than be written to in some buffer, if we're in a panicking state.
+ // Note that we can't just clear writebuf in the gp.m.dying case
+ // because a panic isn't allowed to have any write barriers.
+ if gp == nil || gp.writebuf == nil || gp.m.dying > 0 {
+ writeErr(b)
+ return
+ }
+
+ n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
+ gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
+}
+
+func printsp() {
+ printstring(" ")
+}
+
+func printnl() {
+ printstring("\n")
+}
+
+func printbool(v bool) {
+ if v {
+ printstring("true")
+ } else {
+ printstring("false")
+ }
+}
+
+func printfloat(v float64) {
+ switch {
+ case v != v:
+ printstring("NaN")
+ return
+ case v+v == v && v > 0:
+ printstring("+Inf")
+ return
+ case v+v == v && v < 0:
+ printstring("-Inf")
+ return
+ }
+
+ const n = 7 // digits printed
+ var buf [n + 7]byte
+ buf[0] = '+'
+ e := 0 // exp
+ if v == 0 {
+ if 1/v < 0 {
+ buf[0] = '-'
+ }
+ } else {
+ if v < 0 {
+ v = -v
+ buf[0] = '-'
+ }
+
+ // normalize
+ for v >= 10 {
+ e++
+ v /= 10
+ }
+ for v < 1 {
+ e--
+ v *= 10
+ }
+
+ // round
+ h := 5.0
+ for i := 0; i < n; i++ {
+ h /= 10
+ }
+ v += h
+ if v >= 10 {
+ e++
+ v /= 10
+ }
+ }
+
+ // format +d.dddd+edd
+ for i := 0; i < n; i++ {
+ s := int(v)
+ buf[i+2] = byte(s + '0')
+ v -= float64(s)
+ v *= 10
+ }
+ buf[1] = buf[2]
+ buf[2] = '.'
+
+ buf[n+2] = 'e'
+ buf[n+3] = '+'
+ if e < 0 {
+ e = -e
+ buf[n+3] = '-'
+ }
+
+ buf[n+4] = byte(e/100) + '0'
+ buf[n+5] = byte(e/10)%10 + '0'
+ buf[n+6] = byte(e%10) + '0'
+ gwrite(buf[:])
+}
+
+func printcomplex(c complex128) {
+ print("(", real(c), imag(c), "i)")
+}
+
+func printuint(v uint64) {
+ var buf [100]byte
+ i := len(buf)
+ for i--; i > 0; i-- {
+ buf[i] = byte(v%10 + '0')
+ if v < 10 {
+ break
+ }
+ v /= 10
+ }
+ gwrite(buf[i:])
+}
+
+func printint(v int64) {
+ if v < 0 {
+ printstring("-")
+ v = -v
+ }
+ printuint(uint64(v))
+}
+
+var minhexdigits = 0 // protected by printlock
+
+func printhex(v uint64) {
+ const dig = "0123456789abcdef"
+ var buf [100]byte
+ i := len(buf)
+ for i--; i > 0; i-- {
+ buf[i] = dig[v%16]
+ if v < 16 && len(buf)-i >= minhexdigits {
+ break
+ }
+ v /= 16
+ }
+ i--
+ buf[i] = 'x'
+ i--
+ buf[i] = '0'
+ gwrite(buf[i:])
+}
+
+func printpointer(p unsafe.Pointer) {
+ printhex(uint64(uintptr(p)))
+}
+func printuintptr(p uintptr) {
+ printhex(uint64(p))
+}
+
+func printstring(s string) {
+ gwrite(bytes(s))
+}
+
+func printslice(s []byte) {
+ sp := (*slice)(unsafe.Pointer(&s))
+ print("[", len(s), "/", cap(s), "]")
+ printpointer(sp.array)
+}
+
+func printeface(e eface) {
+ print("(", e._type, ",", e.data, ")")
+}
+
+func printiface(i iface) {
+ print("(", i.tab, ",", i.data, ")")
+}
+
+// hexdumpWords prints a word-oriented hex dump of [p, end).
+//
+// If mark != nil, it will be called with each printed word's address
+// and should return a character mark to appear just before that
+// word's value. It can return 0 to indicate no mark.
+func hexdumpWords(p, end uintptr, mark func(uintptr) byte) {
+ printlock()
+ var markbuf [1]byte
+ markbuf[0] = ' '
+ minhexdigits = int(unsafe.Sizeof(uintptr(0)) * 2)
+ for i := uintptr(0); p+i < end; i += goarch.PtrSize {
+ if i%16 == 0 {
+ if i != 0 {
+ println()
+ }
+ print(hex(p+i), ": ")
+ }
+
+ if mark != nil {
+ markbuf[0] = mark(p + i)
+ if markbuf[0] == 0 {
+ markbuf[0] = ' '
+ }
+ }
+ gwrite(markbuf[:])
+ val := *(*uintptr)(unsafe.Pointer(p + i))
+ print(hex(val))
+ print(" ")
+
+ // Can we symbolize val?
+ fn := findfunc(val)
+ if fn.valid() {
+ print("<", funcname(fn), "+", hex(val-fn.entry()), "> ")
+ }
+ }
+ minhexdigits = 0
+ println()
+ printunlock()
+}
diff --git a/contrib/go/_std_1.21/src/runtime/proc.go b/contrib/go/_std_1.21/src/runtime/proc.go
new file mode 100644
index 0000000000..afb33c1e8b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/proc.go
@@ -0,0 +1,6762 @@
+// Copyright 2014 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 runtime
+
+import (
+ "internal/abi"
+ "internal/cpu"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// set using cmd/go/internal/modload.ModInfoProg
+var modinfo string
+
+// Goroutine scheduler
+// The scheduler's job is to distribute ready-to-run goroutines over worker threads.
+//
+// The main concepts are:
+// G - goroutine.
+// M - worker thread, or machine.
+// P - processor, a resource that is required to execute Go code.
+// M must have an associated P to execute Go code, however it can be
+// blocked or in a syscall w/o an associated P.
+//
+// Design doc at https://golang.org/s/go11sched.
+
+// Worker thread parking/unparking.
+// We need to balance between keeping enough running worker threads to utilize
+// available hardware parallelism and parking excessive running worker threads
+// to conserve CPU resources and power. This is not simple for two reasons:
+// (1) scheduler state is intentionally distributed (in particular, per-P work
+// queues), so it is not possible to compute global predicates on fast paths;
+// (2) for optimal thread management we would need to know the future (don't park
+// a worker thread when a new goroutine will be readied in near future).
+//
+// Three rejected approaches that would work badly:
+// 1. Centralize all scheduler state (would inhibit scalability).
+// 2. Direct goroutine handoff. That is, when we ready a new goroutine and there
+// is a spare P, unpark a thread and handoff it the thread and the goroutine.
+// This would lead to thread state thrashing, as the thread that readied the
+// goroutine can be out of work the very next moment, we will need to park it.
+// Also, it would destroy locality of computation as we want to preserve
+// dependent goroutines on the same thread; and introduce additional latency.
+// 3. Unpark an additional thread whenever we ready a goroutine and there is an
+// idle P, but don't do handoff. This would lead to excessive thread parking/
+// unparking as the additional threads will instantly park without discovering
+// any work to do.
+//
+// The current approach:
+//
+// This approach applies to three primary sources of potential work: readying a
+// goroutine, new/modified-earlier timers, and idle-priority GC. See below for
+// additional details.
+//
+// We unpark an additional thread when we submit work if (this is wakep()):
+// 1. There is an idle P, and
+// 2. There are no "spinning" worker threads.
+//
+// A worker thread is considered spinning if it is out of local work and did
+// not find work in the global run queue or netpoller; the spinning state is
+// denoted in m.spinning and in sched.nmspinning. Threads unparked this way are
+// also considered spinning; we don't do goroutine handoff so such threads are
+// out of work initially. Spinning threads spin on looking for work in per-P
+// run queues and timer heaps or from the GC before parking. If a spinning
+// thread finds work it takes itself out of the spinning state and proceeds to
+// execution. If it does not find work it takes itself out of the spinning
+// state and then parks.
+//
+// If there is at least one spinning thread (sched.nmspinning>1), we don't
+// unpark new threads when submitting work. To compensate for that, if the last
+// spinning thread finds work and stops spinning, it must unpark a new spinning
+// thread. This approach smooths out unjustified spikes of thread unparking,
+// but at the same time guarantees eventual maximal CPU parallelism
+// utilization.
+//
+// The main implementation complication is that we need to be very careful
+// during spinning->non-spinning thread transition. This transition can race
+// with submission of new work, and either one part or another needs to unpark
+// another worker thread. If they both fail to do that, we can end up with
+// semi-persistent CPU underutilization.
+//
+// The general pattern for submission is:
+// 1. Submit work to the local run queue, timer heap, or GC state.
+// 2. #StoreLoad-style memory barrier.
+// 3. Check sched.nmspinning.
+//
+// The general pattern for spinning->non-spinning transition is:
+// 1. Decrement nmspinning.
+// 2. #StoreLoad-style memory barrier.
+// 3. Check all per-P work queues and GC for new work.
+//
+// Note that all this complexity does not apply to global run queue as we are
+// not sloppy about thread unparking when submitting to global queue. Also see
+// comments for nmspinning manipulation.
+//
+// How these different sources of work behave varies, though it doesn't affect
+// the synchronization approach:
+// * Ready goroutine: this is an obvious source of work; the goroutine is
+// immediately ready and must run on some thread eventually.
+// * New/modified-earlier timer: The current timer implementation (see time.go)
+// uses netpoll in a thread with no work available to wait for the soonest
+// timer. If there is no thread waiting, we want a new spinning thread to go
+// wait.
+// * Idle-priority GC: The GC wakes a stopped idle thread to contribute to
+// background GC work (note: currently disabled per golang.org/issue/19112).
+// Also see golang.org/issue/44313, as this should be extended to all GC
+// workers.
+
+var (
+ m0 m
+ g0 g
+ mcache0 *mcache
+ raceprocctx0 uintptr
+ raceFiniLock mutex
+)
+
+// This slice records the initializing tasks that need to be
+// done to start up the runtime. It is built by the linker.
+var runtime_inittasks []*initTask
+
+// main_init_done is a signal used by cgocallbackg that initialization
+// has been completed. It is made before _cgo_notify_runtime_init_done,
+// so all cgo calls can rely on it existing. When main_init is complete,
+// it is closed, meaning cgocallbackg can reliably receive from it.
+var main_init_done chan bool
+
+//go:linkname main_main main.main
+func main_main()
+
+// mainStarted indicates that the main M has started.
+var mainStarted bool
+
+// runtimeInitTime is the nanotime() at which the runtime started.
+var runtimeInitTime int64
+
+// Value to use for signal mask for newly created M's.
+var initSigmask sigset
+
+// The main goroutine.
+func main() {
+ mp := getg().m
+
+ // Racectx of m0->g0 is used only as the parent of the main goroutine.
+ // It must not be used for anything else.
+ mp.g0.racectx = 0
+
+ // Max stack size is 1 GB on 64-bit, 250 MB on 32-bit.
+ // Using decimal instead of binary GB and MB because
+ // they look nicer in the stack overflow failure message.
+ if goarch.PtrSize == 8 {
+ maxstacksize = 1000000000
+ } else {
+ maxstacksize = 250000000
+ }
+
+ // An upper limit for max stack size. Used to avoid random crashes
+ // after calling SetMaxStack and trying to allocate a stack that is too big,
+ // since stackalloc works with 32-bit sizes.
+ maxstackceiling = 2 * maxstacksize
+
+ // Allow newproc to start new Ms.
+ mainStarted = true
+
+ if GOARCH != "wasm" { // no threads on wasm yet, so no sysmon
+ systemstack(func() {
+ newm(sysmon, nil, -1)
+ })
+ }
+
+ // Lock the main goroutine onto this, the main OS thread,
+ // during initialization. Most programs won't care, but a few
+ // do require certain calls to be made by the main thread.
+ // Those can arrange for main.main to run in the main thread
+ // by calling runtime.LockOSThread during initialization
+ // to preserve the lock.
+ lockOSThread()
+
+ if mp != &m0 {
+ throw("runtime.main not on m0")
+ }
+
+ // Record when the world started.
+ // Must be before doInit for tracing init.
+ runtimeInitTime = nanotime()
+ if runtimeInitTime == 0 {
+ throw("nanotime returning zero")
+ }
+
+ if debug.inittrace != 0 {
+ inittrace.id = getg().goid
+ inittrace.active = true
+ }
+
+ doInit(runtime_inittasks) // Must be before defer.
+
+ // Defer unlock so that runtime.Goexit during init does the unlock too.
+ needUnlock := true
+ defer func() {
+ if needUnlock {
+ unlockOSThread()
+ }
+ }()
+
+ gcenable()
+
+ main_init_done = make(chan bool)
+ if iscgo {
+ if _cgo_pthread_key_created == nil {
+ throw("_cgo_pthread_key_created missing")
+ }
+
+ if _cgo_thread_start == nil {
+ throw("_cgo_thread_start missing")
+ }
+ if GOOS != "windows" {
+ if _cgo_setenv == nil {
+ throw("_cgo_setenv missing")
+ }
+ if _cgo_unsetenv == nil {
+ throw("_cgo_unsetenv missing")
+ }
+ }
+ if _cgo_notify_runtime_init_done == nil {
+ throw("_cgo_notify_runtime_init_done missing")
+ }
+
+ // Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
+ if set_crosscall2 == nil {
+ throw("set_crosscall2 missing")
+ }
+ set_crosscall2()
+
+ // Start the template thread in case we enter Go from
+ // a C-created thread and need to create a new thread.
+ startTemplateThread()
+ cgocall(_cgo_notify_runtime_init_done, nil)
+ }
+
+ // Run the initializing tasks. Depending on build mode this
+ // list can arrive a few different ways, but it will always
+ // contain the init tasks computed by the linker for all the
+ // packages in the program (excluding those added at runtime
+ // by package plugin).
+ for _, m := range activeModules() {
+ doInit(m.inittasks)
+ }
+
+ // Disable init tracing after main init done to avoid overhead
+ // of collecting statistics in malloc and newproc
+ inittrace.active = false
+
+ close(main_init_done)
+
+ needUnlock = false
+ unlockOSThread()
+
+ if isarchive || islibrary {
+ // A program compiled with -buildmode=c-archive or c-shared
+ // has a main, but it is not executed.
+ return
+ }
+ fn := main_main // make an indirect call, as the linker doesn't know the address of the main package when laying down the runtime
+ fn()
+ if raceenabled {
+ runExitHooks(0) // run hooks now, since racefini does not return
+ racefini()
+ }
+
+ // Make racy client program work: if panicking on
+ // another goroutine at the same time as main returns,
+ // let the other goroutine finish printing the panic trace.
+ // Once it does, it will exit. See issues 3934 and 20018.
+ if runningPanicDefers.Load() != 0 {
+ // Running deferred functions should not take long.
+ for c := 0; c < 1000; c++ {
+ if runningPanicDefers.Load() == 0 {
+ break
+ }
+ Gosched()
+ }
+ }
+ if panicking.Load() != 0 {
+ gopark(nil, nil, waitReasonPanicWait, traceBlockForever, 1)
+ }
+ runExitHooks(0)
+
+ exit(0)
+ for {
+ var x *int32
+ *x = 0
+ }
+}
+
+// os_beforeExit is called from os.Exit(0).
+//
+//go:linkname os_beforeExit os.runtime_beforeExit
+func os_beforeExit(exitCode int) {
+ runExitHooks(exitCode)
+ if exitCode == 0 && raceenabled {
+ racefini()
+ }
+}
+
+// start forcegc helper goroutine
+func init() {
+ go forcegchelper()
+}
+
+func forcegchelper() {
+ forcegc.g = getg()
+ lockInit(&forcegc.lock, lockRankForcegc)
+ for {
+ lock(&forcegc.lock)
+ if forcegc.idle.Load() {
+ throw("forcegc: phase error")
+ }
+ forcegc.idle.Store(true)
+ goparkunlock(&forcegc.lock, waitReasonForceGCIdle, traceBlockSystemGoroutine, 1)
+ // this goroutine is explicitly resumed by sysmon
+ if debug.gctrace > 0 {
+ println("GC forced")
+ }
+ // Time-triggered, fully concurrent.
+ gcStart(gcTrigger{kind: gcTriggerTime, now: nanotime()})
+ }
+}
+
+// Gosched yields the processor, allowing other goroutines to run. It does not
+// suspend the current goroutine, so execution resumes automatically.
+//
+//go:nosplit
+func Gosched() {
+ checkTimeouts()
+ mcall(gosched_m)
+}
+
+// goschedguarded yields the processor like gosched, but also checks
+// for forbidden states and opts out of the yield in those cases.
+//
+//go:nosplit
+func goschedguarded() {
+ mcall(goschedguarded_m)
+}
+
+// goschedIfBusy yields the processor like gosched, but only does so if
+// there are no idle Ps or if we're on the only P and there's nothing in
+// the run queue. In both cases, there is freely available idle time.
+//
+//go:nosplit
+func goschedIfBusy() {
+ gp := getg()
+ // Call gosched if gp.preempt is set; we may be in a tight loop that
+ // doesn't otherwise yield.
+ if !gp.preempt && sched.npidle.Load() > 0 {
+ return
+ }
+ mcall(gosched_m)
+}
+
+// Puts the current goroutine into a waiting state and calls unlockf on the
+// system stack.
+//
+// If unlockf returns false, the goroutine is resumed.
+//
+// unlockf must not access this G's stack, as it may be moved between
+// the call to gopark and the call to unlockf.
+//
+// Note that because unlockf is called after putting the G into a waiting
+// state, the G may have already been readied by the time unlockf is called
+// unless there is external synchronization preventing the G from being
+// readied. If unlockf returns false, it must guarantee that the G cannot be
+// externally readied.
+//
+// Reason explains why the goroutine has been parked. It is displayed in stack
+// traces and heap dumps. Reasons should be unique and descriptive. Do not
+// re-use reasons, add new ones.
+func gopark(unlockf func(*g, unsafe.Pointer) bool, lock unsafe.Pointer, reason waitReason, traceReason traceBlockReason, traceskip int) {
+ if reason != waitReasonSleep {
+ checkTimeouts() // timeouts may expire while two goroutines keep the scheduler busy
+ }
+ mp := acquirem()
+ gp := mp.curg
+ status := readgstatus(gp)
+ if status != _Grunning && status != _Gscanrunning {
+ throw("gopark: bad g status")
+ }
+ mp.waitlock = lock
+ mp.waitunlockf = unlockf
+ gp.waitreason = reason
+ mp.waitTraceBlockReason = traceReason
+ mp.waitTraceSkip = traceskip
+ releasem(mp)
+ // can't do anything that might move the G between Ms here.
+ mcall(park_m)
+}
+
+// Puts the current goroutine into a waiting state and unlocks the lock.
+// The goroutine can be made runnable again by calling goready(gp).
+func goparkunlock(lock *mutex, reason waitReason, traceReason traceBlockReason, traceskip int) {
+ gopark(parkunlock_c, unsafe.Pointer(lock), reason, traceReason, traceskip)
+}
+
+func goready(gp *g, traceskip int) {
+ systemstack(func() {
+ ready(gp, traceskip, true)
+ })
+}
+
+//go:nosplit
+func acquireSudog() *sudog {
+ // Delicate dance: the semaphore implementation calls
+ // acquireSudog, acquireSudog calls new(sudog),
+ // new calls malloc, malloc can call the garbage collector,
+ // and the garbage collector calls the semaphore implementation
+ // in stopTheWorld.
+ // Break the cycle by doing acquirem/releasem around new(sudog).
+ // The acquirem/releasem increments m.locks during new(sudog),
+ // which keeps the garbage collector from being invoked.
+ mp := acquirem()
+ pp := mp.p.ptr()
+ if len(pp.sudogcache) == 0 {
+ lock(&sched.sudoglock)
+ // First, try to grab a batch from central cache.
+ for len(pp.sudogcache) < cap(pp.sudogcache)/2 && sched.sudogcache != nil {
+ s := sched.sudogcache
+ sched.sudogcache = s.next
+ s.next = nil
+ pp.sudogcache = append(pp.sudogcache, s)
+ }
+ unlock(&sched.sudoglock)
+ // If the central cache is empty, allocate a new one.
+ if len(pp.sudogcache) == 0 {
+ pp.sudogcache = append(pp.sudogcache, new(sudog))
+ }
+ }
+ n := len(pp.sudogcache)
+ s := pp.sudogcache[n-1]
+ pp.sudogcache[n-1] = nil
+ pp.sudogcache = pp.sudogcache[:n-1]
+ if s.elem != nil {
+ throw("acquireSudog: found s.elem != nil in cache")
+ }
+ releasem(mp)
+ return s
+}
+
+//go:nosplit
+func releaseSudog(s *sudog) {
+ if s.elem != nil {
+ throw("runtime: sudog with non-nil elem")
+ }
+ if s.isSelect {
+ throw("runtime: sudog with non-false isSelect")
+ }
+ if s.next != nil {
+ throw("runtime: sudog with non-nil next")
+ }
+ if s.prev != nil {
+ throw("runtime: sudog with non-nil prev")
+ }
+ if s.waitlink != nil {
+ throw("runtime: sudog with non-nil waitlink")
+ }
+ if s.c != nil {
+ throw("runtime: sudog with non-nil c")
+ }
+ gp := getg()
+ if gp.param != nil {
+ throw("runtime: releaseSudog with non-nil gp.param")
+ }
+ mp := acquirem() // avoid rescheduling to another P
+ pp := mp.p.ptr()
+ if len(pp.sudogcache) == cap(pp.sudogcache) {
+ // Transfer half of local cache to the central cache.
+ var first, last *sudog
+ for len(pp.sudogcache) > cap(pp.sudogcache)/2 {
+ n := len(pp.sudogcache)
+ p := pp.sudogcache[n-1]
+ pp.sudogcache[n-1] = nil
+ pp.sudogcache = pp.sudogcache[:n-1]
+ if first == nil {
+ first = p
+ } else {
+ last.next = p
+ }
+ last = p
+ }
+ lock(&sched.sudoglock)
+ last.next = sched.sudogcache
+ sched.sudogcache = first
+ unlock(&sched.sudoglock)
+ }
+ pp.sudogcache = append(pp.sudogcache, s)
+ releasem(mp)
+}
+
+// called from assembly.
+func badmcall(fn func(*g)) {
+ throw("runtime: mcall called on m->g0 stack")
+}
+
+func badmcall2(fn func(*g)) {
+ throw("runtime: mcall function returned")
+}
+
+func badreflectcall() {
+ panic(plainError("arg size to reflect.call more than 1GB"))
+}
+
+//go:nosplit
+//go:nowritebarrierrec
+func badmorestackg0() {
+ writeErrStr("fatal: morestack on g0\n")
+}
+
+//go:nosplit
+//go:nowritebarrierrec
+func badmorestackgsignal() {
+ writeErrStr("fatal: morestack on gsignal\n")
+}
+
+//go:nosplit
+func badctxt() {
+ throw("ctxt != 0")
+}
+
+func lockedOSThread() bool {
+ gp := getg()
+ return gp.lockedm != 0 && gp.m.lockedg != 0
+}
+
+var (
+ // allgs contains all Gs ever created (including dead Gs), and thus
+ // never shrinks.
+ //
+ // Access via the slice is protected by allglock or stop-the-world.
+ // Readers that cannot take the lock may (carefully!) use the atomic
+ // variables below.
+ allglock mutex
+ allgs []*g
+
+ // allglen and allgptr are atomic variables that contain len(allgs) and
+ // &allgs[0] respectively. Proper ordering depends on totally-ordered
+ // loads and stores. Writes are protected by allglock.
+ //
+ // allgptr is updated before allglen. Readers should read allglen
+ // before allgptr to ensure that allglen is always <= len(allgptr). New
+ // Gs appended during the race can be missed. For a consistent view of
+ // all Gs, allglock must be held.
+ //
+ // allgptr copies should always be stored as a concrete type or
+ // unsafe.Pointer, not uintptr, to ensure that GC can still reach it
+ // even if it points to a stale array.
+ allglen uintptr
+ allgptr **g
+)
+
+func allgadd(gp *g) {
+ if readgstatus(gp) == _Gidle {
+ throw("allgadd: bad status Gidle")
+ }
+
+ lock(&allglock)
+ allgs = append(allgs, gp)
+ if &allgs[0] != allgptr {
+ atomicstorep(unsafe.Pointer(&allgptr), unsafe.Pointer(&allgs[0]))
+ }
+ atomic.Storeuintptr(&allglen, uintptr(len(allgs)))
+ unlock(&allglock)
+}
+
+// allGsSnapshot returns a snapshot of the slice of all Gs.
+//
+// The world must be stopped or allglock must be held.
+func allGsSnapshot() []*g {
+ assertWorldStoppedOrLockHeld(&allglock)
+
+ // Because the world is stopped or allglock is held, allgadd
+ // cannot happen concurrently with this. allgs grows
+ // monotonically and existing entries never change, so we can
+ // simply return a copy of the slice header. For added safety,
+ // we trim everything past len because that can still change.
+ return allgs[:len(allgs):len(allgs)]
+}
+
+// atomicAllG returns &allgs[0] and len(allgs) for use with atomicAllGIndex.
+func atomicAllG() (**g, uintptr) {
+ length := atomic.Loaduintptr(&allglen)
+ ptr := (**g)(atomic.Loadp(unsafe.Pointer(&allgptr)))
+ return ptr, length
+}
+
+// atomicAllGIndex returns ptr[i] with the allgptr returned from atomicAllG.
+func atomicAllGIndex(ptr **g, i uintptr) *g {
+ return *(**g)(add(unsafe.Pointer(ptr), i*goarch.PtrSize))
+}
+
+// forEachG calls fn on every G from allgs.
+//
+// forEachG takes a lock to exclude concurrent addition of new Gs.
+func forEachG(fn func(gp *g)) {
+ lock(&allglock)
+ for _, gp := range allgs {
+ fn(gp)
+ }
+ unlock(&allglock)
+}
+
+// forEachGRace calls fn on every G from allgs.
+//
+// forEachGRace avoids locking, but does not exclude addition of new Gs during
+// execution, which may be missed.
+func forEachGRace(fn func(gp *g)) {
+ ptr, length := atomicAllG()
+ for i := uintptr(0); i < length; i++ {
+ gp := atomicAllGIndex(ptr, i)
+ fn(gp)
+ }
+ return
+}
+
+const (
+ // Number of goroutine ids to grab from sched.goidgen to local per-P cache at once.
+ // 16 seems to provide enough amortization, but other than that it's mostly arbitrary number.
+ _GoidCacheBatch = 16
+)
+
+// cpuinit sets up CPU feature flags and calls internal/cpu.Initialize. env should be the complete
+// value of the GODEBUG environment variable.
+func cpuinit(env string) {
+ switch GOOS {
+ case "aix", "darwin", "ios", "dragonfly", "freebsd", "netbsd", "openbsd", "illumos", "solaris", "linux":
+ cpu.DebugOptions = true
+ }
+ cpu.Initialize(env)
+
+ // Support cpu feature variables are used in code generated by the compiler
+ // to guard execution of instructions that can not be assumed to be always supported.
+ switch GOARCH {
+ case "386", "amd64":
+ x86HasPOPCNT = cpu.X86.HasPOPCNT
+ x86HasSSE41 = cpu.X86.HasSSE41
+ x86HasFMA = cpu.X86.HasFMA
+
+ case "arm":
+ armHasVFPv4 = cpu.ARM.HasVFPv4
+
+ case "arm64":
+ arm64HasATOMICS = cpu.ARM64.HasATOMICS
+ }
+}
+
+// getGodebugEarly extracts the environment variable GODEBUG from the environment on
+// Unix-like operating systems and returns it. This function exists to extract GODEBUG
+// early before much of the runtime is initialized.
+func getGodebugEarly() string {
+ const prefix = "GODEBUG="
+ var env string
+ switch GOOS {
+ case "aix", "darwin", "ios", "dragonfly", "freebsd", "netbsd", "openbsd", "illumos", "solaris", "linux":
+ // Similar to goenv_unix but extracts the environment value for
+ // GODEBUG directly.
+ // TODO(moehrmann): remove when general goenvs() can be called before cpuinit()
+ n := int32(0)
+ for argv_index(argv, argc+1+n) != nil {
+ n++
+ }
+
+ for i := int32(0); i < n; i++ {
+ p := argv_index(argv, argc+1+i)
+ s := unsafe.String(p, findnull(p))
+
+ if hasPrefix(s, prefix) {
+ env = gostring(p)[len(prefix):]
+ break
+ }
+ }
+ }
+ return env
+}
+
+// The bootstrap sequence is:
+//
+// call osinit
+// call schedinit
+// make & queue new G
+// call runtime·mstart
+//
+// The new G calls runtime·main.
+func schedinit() {
+ lockInit(&sched.lock, lockRankSched)
+ lockInit(&sched.sysmonlock, lockRankSysmon)
+ lockInit(&sched.deferlock, lockRankDefer)
+ lockInit(&sched.sudoglock, lockRankSudog)
+ lockInit(&deadlock, lockRankDeadlock)
+ lockInit(&paniclk, lockRankPanic)
+ lockInit(&allglock, lockRankAllg)
+ lockInit(&allpLock, lockRankAllp)
+ lockInit(&reflectOffs.lock, lockRankReflectOffs)
+ lockInit(&finlock, lockRankFin)
+ lockInit(&cpuprof.lock, lockRankCpuprof)
+ traceLockInit()
+ // Enforce that this lock is always a leaf lock.
+ // All of this lock's critical sections should be
+ // extremely short.
+ lockInit(&memstats.heapStats.noPLock, lockRankLeafRank)
+
+ // raceinit must be the first call to race detector.
+ // In particular, it must be done before mallocinit below calls racemapshadow.
+ gp := getg()
+ if raceenabled {
+ gp.racectx, raceprocctx0 = raceinit()
+ }
+
+ sched.maxmcount = 10000
+
+ // The world starts stopped.
+ worldStopped()
+
+ moduledataverify()
+ stackinit()
+ mallocinit()
+ godebug := getGodebugEarly()
+ initPageTrace(godebug) // must run after mallocinit but before anything allocates
+ cpuinit(godebug) // must run before alginit
+ alginit() // maps, hash, fastrand must not be used before this call
+ fastrandinit() // must run before mcommoninit
+ mcommoninit(gp.m, -1)
+ modulesinit() // provides activeModules
+ typelinksinit() // uses maps, activeModules
+ itabsinit() // uses activeModules
+ stkobjinit() // must run before GC starts
+
+ sigsave(&gp.m.sigmask)
+ initSigmask = gp.m.sigmask
+
+ goargs()
+ goenvs()
+ secure()
+ parsedebugvars()
+ gcinit()
+
+ // if disableMemoryProfiling is set, update MemProfileRate to 0 to turn off memprofile.
+ // Note: parsedebugvars may update MemProfileRate, but when disableMemoryProfiling is
+ // set to true by the linker, it means that nothing is consuming the profile, it is
+ // safe to set MemProfileRate to 0.
+ if disableMemoryProfiling {
+ MemProfileRate = 0
+ }
+
+ lock(&sched.lock)
+ sched.lastpoll.Store(nanotime())
+ procs := ncpu
+ if n, ok := atoi32(gogetenv("GOMAXPROCS")); ok && n > 0 {
+ procs = n
+ }
+ if procresize(procs) != nil {
+ throw("unknown runnable goroutine during bootstrap")
+ }
+ unlock(&sched.lock)
+
+ // World is effectively started now, as P's can run.
+ worldStarted()
+
+ if buildVersion == "" {
+ // Condition should never trigger. This code just serves
+ // to ensure runtime·buildVersion is kept in the resulting binary.
+ buildVersion = "unknown"
+ }
+ if len(modinfo) == 1 {
+ // Condition should never trigger. This code just serves
+ // to ensure runtime·modinfo is kept in the resulting binary.
+ modinfo = ""
+ }
+}
+
+func dumpgstatus(gp *g) {
+ thisg := getg()
+ print("runtime: gp: gp=", gp, ", goid=", gp.goid, ", gp->atomicstatus=", readgstatus(gp), "\n")
+ print("runtime: getg: g=", thisg, ", goid=", thisg.goid, ", g->atomicstatus=", readgstatus(thisg), "\n")
+}
+
+// sched.lock must be held.
+func checkmcount() {
+ assertLockHeld(&sched.lock)
+
+ // Exclude extra M's, which are used for cgocallback from threads
+ // created in C.
+ //
+ // The purpose of the SetMaxThreads limit is to avoid accidental fork
+ // bomb from something like millions of goroutines blocking on system
+ // calls, causing the runtime to create millions of threads. By
+ // definition, this isn't a problem for threads created in C, so we
+ // exclude them from the limit. See https://go.dev/issue/60004.
+ count := mcount() - int32(extraMInUse.Load()) - int32(extraMLength.Load())
+ if count > sched.maxmcount {
+ print("runtime: program exceeds ", sched.maxmcount, "-thread limit\n")
+ throw("thread exhaustion")
+ }
+}
+
+// mReserveID returns the next ID to use for a new m. This new m is immediately
+// considered 'running' by checkdead.
+//
+// sched.lock must be held.
+func mReserveID() int64 {
+ assertLockHeld(&sched.lock)
+
+ if sched.mnext+1 < sched.mnext {
+ throw("runtime: thread ID overflow")
+ }
+ id := sched.mnext
+ sched.mnext++
+ checkmcount()
+ return id
+}
+
+// Pre-allocated ID may be passed as 'id', or omitted by passing -1.
+func mcommoninit(mp *m, id int64) {
+ gp := getg()
+
+ // g0 stack won't make sense for user (and is not necessary unwindable).
+ if gp != gp.m.g0 {
+ callers(1, mp.createstack[:])
+ }
+
+ lock(&sched.lock)
+
+ if id >= 0 {
+ mp.id = id
+ } else {
+ mp.id = mReserveID()
+ }
+
+ lo := uint32(int64Hash(uint64(mp.id), fastrandseed))
+ hi := uint32(int64Hash(uint64(cputicks()), ^fastrandseed))
+ if lo|hi == 0 {
+ hi = 1
+ }
+ // Same behavior as for 1.17.
+ // TODO: Simplify this.
+ if goarch.BigEndian {
+ mp.fastrand = uint64(lo)<<32 | uint64(hi)
+ } else {
+ mp.fastrand = uint64(hi)<<32 | uint64(lo)
+ }
+
+ mpreinit(mp)
+ if mp.gsignal != nil {
+ mp.gsignal.stackguard1 = mp.gsignal.stack.lo + stackGuard
+ }
+
+ // Add to allm so garbage collector doesn't free g->m
+ // when it is just in a register or thread-local storage.
+ mp.alllink = allm
+
+ // NumCgoCall() iterates over allm w/o schedlock,
+ // so we need to publish it safely.
+ atomicstorep(unsafe.Pointer(&allm), unsafe.Pointer(mp))
+ unlock(&sched.lock)
+
+ // Allocate memory to hold a cgo traceback if the cgo call crashes.
+ if iscgo || GOOS == "solaris" || GOOS == "illumos" || GOOS == "windows" {
+ mp.cgoCallers = new(cgoCallers)
+ }
+}
+
+func (mp *m) becomeSpinning() {
+ mp.spinning = true
+ sched.nmspinning.Add(1)
+ sched.needspinning.Store(0)
+}
+
+func (mp *m) hasCgoOnStack() bool {
+ return mp.ncgo > 0 || mp.isextra
+}
+
+var fastrandseed uintptr
+
+func fastrandinit() {
+ s := (*[unsafe.Sizeof(fastrandseed)]byte)(unsafe.Pointer(&fastrandseed))[:]
+ getRandomData(s)
+}
+
+// Mark gp ready to run.
+func ready(gp *g, traceskip int, next bool) {
+ if traceEnabled() {
+ traceGoUnpark(gp, traceskip)
+ }
+
+ status := readgstatus(gp)
+
+ // Mark runnable.
+ mp := acquirem() // disable preemption because it can be holding p in a local var
+ if status&^_Gscan != _Gwaiting {
+ dumpgstatus(gp)
+ throw("bad g->status in ready")
+ }
+
+ // status is Gwaiting or Gscanwaiting, make Grunnable and put on runq
+ casgstatus(gp, _Gwaiting, _Grunnable)
+ runqput(mp.p.ptr(), gp, next)
+ wakep()
+ releasem(mp)
+}
+
+// freezeStopWait is a large value that freezetheworld sets
+// sched.stopwait to in order to request that all Gs permanently stop.
+const freezeStopWait = 0x7fffffff
+
+// freezing is set to non-zero if the runtime is trying to freeze the
+// world.
+var freezing atomic.Bool
+
+// Similar to stopTheWorld but best-effort and can be called several times.
+// There is no reverse operation, used during crashing.
+// This function must not lock any mutexes.
+func freezetheworld() {
+ freezing.Store(true)
+ if debug.dontfreezetheworld > 0 {
+ // Don't prempt Ps to stop goroutines. That will perturb
+ // scheduler state, making debugging more difficult. Instead,
+ // allow goroutines to continue execution.
+ //
+ // fatalpanic will tracebackothers to trace all goroutines. It
+ // is unsafe to trace a running goroutine, so tracebackothers
+ // will skip running goroutines. That is OK and expected, we
+ // expect users of dontfreezetheworld to use core files anyway.
+ //
+ // However, allowing the scheduler to continue running free
+ // introduces a race: a goroutine may be stopped when
+ // tracebackothers checks its status, and then start running
+ // later when we are in the middle of traceback, potentially
+ // causing a crash.
+ //
+ // To mitigate this, when an M naturally enters the scheduler,
+ // schedule checks if freezing is set and if so stops
+ // execution. This guarantees that while Gs can transition from
+ // running to stopped, they can never transition from stopped
+ // to running.
+ //
+ // The sleep here allows racing Ms that missed freezing and are
+ // about to run a G to complete the transition to running
+ // before we start traceback.
+ usleep(1000)
+ return
+ }
+
+ // stopwait and preemption requests can be lost
+ // due to races with concurrently executing threads,
+ // so try several times
+ for i := 0; i < 5; i++ {
+ // this should tell the scheduler to not start any new goroutines
+ sched.stopwait = freezeStopWait
+ sched.gcwaiting.Store(true)
+ // this should stop running goroutines
+ if !preemptall() {
+ break // no running goroutines
+ }
+ usleep(1000)
+ }
+ // to be sure
+ usleep(1000)
+ preemptall()
+ usleep(1000)
+}
+
+// All reads and writes of g's status go through readgstatus, casgstatus
+// castogscanstatus, casfrom_Gscanstatus.
+//
+//go:nosplit
+func readgstatus(gp *g) uint32 {
+ return gp.atomicstatus.Load()
+}
+
+// The Gscanstatuses are acting like locks and this releases them.
+// If it proves to be a performance hit we should be able to make these
+// simple atomic stores but for now we are going to throw if
+// we see an inconsistent state.
+func casfrom_Gscanstatus(gp *g, oldval, newval uint32) {
+ success := false
+
+ // Check that transition is valid.
+ switch oldval {
+ default:
+ print("runtime: casfrom_Gscanstatus bad oldval gp=", gp, ", oldval=", hex(oldval), ", newval=", hex(newval), "\n")
+ dumpgstatus(gp)
+ throw("casfrom_Gscanstatus:top gp->status is not in scan state")
+ case _Gscanrunnable,
+ _Gscanwaiting,
+ _Gscanrunning,
+ _Gscansyscall,
+ _Gscanpreempted:
+ if newval == oldval&^_Gscan {
+ success = gp.atomicstatus.CompareAndSwap(oldval, newval)
+ }
+ }
+ if !success {
+ print("runtime: casfrom_Gscanstatus failed gp=", gp, ", oldval=", hex(oldval), ", newval=", hex(newval), "\n")
+ dumpgstatus(gp)
+ throw("casfrom_Gscanstatus: gp->status is not in scan state")
+ }
+ releaseLockRank(lockRankGscan)
+}
+
+// This will return false if the gp is not in the expected status and the cas fails.
+// This acts like a lock acquire while the casfromgstatus acts like a lock release.
+func castogscanstatus(gp *g, oldval, newval uint32) bool {
+ switch oldval {
+ case _Grunnable,
+ _Grunning,
+ _Gwaiting,
+ _Gsyscall:
+ if newval == oldval|_Gscan {
+ r := gp.atomicstatus.CompareAndSwap(oldval, newval)
+ if r {
+ acquireLockRank(lockRankGscan)
+ }
+ return r
+
+ }
+ }
+ print("runtime: castogscanstatus oldval=", hex(oldval), " newval=", hex(newval), "\n")
+ throw("castogscanstatus")
+ panic("not reached")
+}
+
+// casgstatusAlwaysTrack is a debug flag that causes casgstatus to always track
+// various latencies on every transition instead of sampling them.
+var casgstatusAlwaysTrack = false
+
+// If asked to move to or from a Gscanstatus this will throw. Use the castogscanstatus
+// and casfrom_Gscanstatus instead.
+// casgstatus will loop if the g->atomicstatus is in a Gscan status until the routine that
+// put it in the Gscan state is finished.
+//
+//go:nosplit
+func casgstatus(gp *g, oldval, newval uint32) {
+ if (oldval&_Gscan != 0) || (newval&_Gscan != 0) || oldval == newval {
+ systemstack(func() {
+ print("runtime: casgstatus: oldval=", hex(oldval), " newval=", hex(newval), "\n")
+ throw("casgstatus: bad incoming values")
+ })
+ }
+
+ acquireLockRank(lockRankGscan)
+ releaseLockRank(lockRankGscan)
+
+ // See https://golang.org/cl/21503 for justification of the yield delay.
+ const yieldDelay = 5 * 1000
+ var nextYield int64
+
+ // loop if gp->atomicstatus is in a scan state giving
+ // GC time to finish and change the state to oldval.
+ for i := 0; !gp.atomicstatus.CompareAndSwap(oldval, newval); i++ {
+ if oldval == _Gwaiting && gp.atomicstatus.Load() == _Grunnable {
+ throw("casgstatus: waiting for Gwaiting but is Grunnable")
+ }
+ if i == 0 {
+ nextYield = nanotime() + yieldDelay
+ }
+ if nanotime() < nextYield {
+ for x := 0; x < 10 && gp.atomicstatus.Load() != oldval; x++ {
+ procyield(1)
+ }
+ } else {
+ osyield()
+ nextYield = nanotime() + yieldDelay/2
+ }
+ }
+
+ if oldval == _Grunning {
+ // Track every gTrackingPeriod time a goroutine transitions out of running.
+ if casgstatusAlwaysTrack || gp.trackingSeq%gTrackingPeriod == 0 {
+ gp.tracking = true
+ }
+ gp.trackingSeq++
+ }
+ if !gp.tracking {
+ return
+ }
+
+ // Handle various kinds of tracking.
+ //
+ // Currently:
+ // - Time spent in runnable.
+ // - Time spent blocked on a sync.Mutex or sync.RWMutex.
+ switch oldval {
+ case _Grunnable:
+ // We transitioned out of runnable, so measure how much
+ // time we spent in this state and add it to
+ // runnableTime.
+ now := nanotime()
+ gp.runnableTime += now - gp.trackingStamp
+ gp.trackingStamp = 0
+ case _Gwaiting:
+ if !gp.waitreason.isMutexWait() {
+ // Not blocking on a lock.
+ break
+ }
+ // Blocking on a lock, measure it. Note that because we're
+ // sampling, we have to multiply by our sampling period to get
+ // a more representative estimate of the absolute value.
+ // gTrackingPeriod also represents an accurate sampling period
+ // because we can only enter this state from _Grunning.
+ now := nanotime()
+ sched.totalMutexWaitTime.Add((now - gp.trackingStamp) * gTrackingPeriod)
+ gp.trackingStamp = 0
+ }
+ switch newval {
+ case _Gwaiting:
+ if !gp.waitreason.isMutexWait() {
+ // Not blocking on a lock.
+ break
+ }
+ // Blocking on a lock. Write down the timestamp.
+ now := nanotime()
+ gp.trackingStamp = now
+ case _Grunnable:
+ // We just transitioned into runnable, so record what
+ // time that happened.
+ now := nanotime()
+ gp.trackingStamp = now
+ case _Grunning:
+ // We're transitioning into running, so turn off
+ // tracking and record how much time we spent in
+ // runnable.
+ gp.tracking = false
+ sched.timeToRun.record(gp.runnableTime)
+ gp.runnableTime = 0
+ }
+}
+
+// casGToWaiting transitions gp from old to _Gwaiting, and sets the wait reason.
+//
+// Use this over casgstatus when possible to ensure that a waitreason is set.
+func casGToWaiting(gp *g, old uint32, reason waitReason) {
+ // Set the wait reason before calling casgstatus, because casgstatus will use it.
+ gp.waitreason = reason
+ casgstatus(gp, old, _Gwaiting)
+}
+
+// casgstatus(gp, oldstatus, Gcopystack), assuming oldstatus is Gwaiting or Grunnable.
+// Returns old status. Cannot call casgstatus directly, because we are racing with an
+// async wakeup that might come in from netpoll. If we see Gwaiting from the readgstatus,
+// it might have become Grunnable by the time we get to the cas. If we called casgstatus,
+// it would loop waiting for the status to go back to Gwaiting, which it never will.
+//
+//go:nosplit
+func casgcopystack(gp *g) uint32 {
+ for {
+ oldstatus := readgstatus(gp) &^ _Gscan
+ if oldstatus != _Gwaiting && oldstatus != _Grunnable {
+ throw("copystack: bad status, not Gwaiting or Grunnable")
+ }
+ if gp.atomicstatus.CompareAndSwap(oldstatus, _Gcopystack) {
+ return oldstatus
+ }
+ }
+}
+
+// casGToPreemptScan transitions gp from _Grunning to _Gscan|_Gpreempted.
+//
+// TODO(austin): This is the only status operation that both changes
+// the status and locks the _Gscan bit. Rethink this.
+func casGToPreemptScan(gp *g, old, new uint32) {
+ if old != _Grunning || new != _Gscan|_Gpreempted {
+ throw("bad g transition")
+ }
+ acquireLockRank(lockRankGscan)
+ for !gp.atomicstatus.CompareAndSwap(_Grunning, _Gscan|_Gpreempted) {
+ }
+}
+
+// casGFromPreempted attempts to transition gp from _Gpreempted to
+// _Gwaiting. If successful, the caller is responsible for
+// re-scheduling gp.
+func casGFromPreempted(gp *g, old, new uint32) bool {
+ if old != _Gpreempted || new != _Gwaiting {
+ throw("bad g transition")
+ }
+ gp.waitreason = waitReasonPreempted
+ return gp.atomicstatus.CompareAndSwap(_Gpreempted, _Gwaiting)
+}
+
+// stwReason is an enumeration of reasons the world is stopping.
+type stwReason uint8
+
+// Reasons to stop-the-world.
+//
+// Avoid reusing reasons and add new ones instead.
+const (
+ stwUnknown stwReason = iota // "unknown"
+ stwGCMarkTerm // "GC mark termination"
+ stwGCSweepTerm // "GC sweep termination"
+ stwWriteHeapDump // "write heap dump"
+ stwGoroutineProfile // "goroutine profile"
+ stwGoroutineProfileCleanup // "goroutine profile cleanup"
+ stwAllGoroutinesStack // "all goroutines stack trace"
+ stwReadMemStats // "read mem stats"
+ stwAllThreadsSyscall // "AllThreadsSyscall"
+ stwGOMAXPROCS // "GOMAXPROCS"
+ stwStartTrace // "start trace"
+ stwStopTrace // "stop trace"
+ stwForTestCountPagesInUse // "CountPagesInUse (test)"
+ stwForTestReadMetricsSlow // "ReadMetricsSlow (test)"
+ stwForTestReadMemStatsSlow // "ReadMemStatsSlow (test)"
+ stwForTestPageCachePagesLeaked // "PageCachePagesLeaked (test)"
+ stwForTestResetDebugLog // "ResetDebugLog (test)"
+)
+
+func (r stwReason) String() string {
+ return stwReasonStrings[r]
+}
+
+// If you add to this list, also add it to src/internal/trace/parser.go.
+// If you change the values of any of the stw* constants, bump the trace
+// version number and make a copy of this.
+var stwReasonStrings = [...]string{
+ stwUnknown: "unknown",
+ stwGCMarkTerm: "GC mark termination",
+ stwGCSweepTerm: "GC sweep termination",
+ stwWriteHeapDump: "write heap dump",
+ stwGoroutineProfile: "goroutine profile",
+ stwGoroutineProfileCleanup: "goroutine profile cleanup",
+ stwAllGoroutinesStack: "all goroutines stack trace",
+ stwReadMemStats: "read mem stats",
+ stwAllThreadsSyscall: "AllThreadsSyscall",
+ stwGOMAXPROCS: "GOMAXPROCS",
+ stwStartTrace: "start trace",
+ stwStopTrace: "stop trace",
+ stwForTestCountPagesInUse: "CountPagesInUse (test)",
+ stwForTestReadMetricsSlow: "ReadMetricsSlow (test)",
+ stwForTestReadMemStatsSlow: "ReadMemStatsSlow (test)",
+ stwForTestPageCachePagesLeaked: "PageCachePagesLeaked (test)",
+ stwForTestResetDebugLog: "ResetDebugLog (test)",
+}
+
+// stopTheWorld stops all P's from executing goroutines, interrupting
+// all goroutines at GC safe points and records reason as the reason
+// for the stop. On return, only the current goroutine's P is running.
+// stopTheWorld must not be called from a system stack and the caller
+// must not hold worldsema. The caller must call startTheWorld when
+// other P's should resume execution.
+//
+// stopTheWorld is safe for multiple goroutines to call at the
+// same time. Each will execute its own stop, and the stops will
+// be serialized.
+//
+// This is also used by routines that do stack dumps. If the system is
+// in panic or being exited, this may not reliably stop all
+// goroutines.
+func stopTheWorld(reason stwReason) {
+ semacquire(&worldsema)
+ gp := getg()
+ gp.m.preemptoff = reason.String()
+ systemstack(func() {
+ // Mark the goroutine which called stopTheWorld preemptible so its
+ // stack may be scanned.
+ // This lets a mark worker scan us while we try to stop the world
+ // since otherwise we could get in a mutual preemption deadlock.
+ // We must not modify anything on the G stack because a stack shrink
+ // may occur. A stack shrink is otherwise OK though because in order
+ // to return from this function (and to leave the system stack) we
+ // must have preempted all goroutines, including any attempting
+ // to scan our stack, in which case, any stack shrinking will
+ // have already completed by the time we exit.
+ // Don't provide a wait reason because we're still executing.
+ casGToWaiting(gp, _Grunning, waitReasonStoppingTheWorld)
+ stopTheWorldWithSema(reason)
+ casgstatus(gp, _Gwaiting, _Grunning)
+ })
+}
+
+// startTheWorld undoes the effects of stopTheWorld.
+func startTheWorld() {
+ systemstack(func() { startTheWorldWithSema() })
+
+ // worldsema must be held over startTheWorldWithSema to ensure
+ // gomaxprocs cannot change while worldsema is held.
+ //
+ // Release worldsema with direct handoff to the next waiter, but
+ // acquirem so that semrelease1 doesn't try to yield our time.
+ //
+ // Otherwise if e.g. ReadMemStats is being called in a loop,
+ // it might stomp on other attempts to stop the world, such as
+ // for starting or ending GC. The operation this blocks is
+ // so heavy-weight that we should just try to be as fair as
+ // possible here.
+ //
+ // We don't want to just allow us to get preempted between now
+ // and releasing the semaphore because then we keep everyone
+ // (including, for example, GCs) waiting longer.
+ mp := acquirem()
+ mp.preemptoff = ""
+ semrelease1(&worldsema, true, 0)
+ releasem(mp)
+}
+
+// stopTheWorldGC has the same effect as stopTheWorld, but blocks
+// until the GC is not running. It also blocks a GC from starting
+// until startTheWorldGC is called.
+func stopTheWorldGC(reason stwReason) {
+ semacquire(&gcsema)
+ stopTheWorld(reason)
+}
+
+// startTheWorldGC undoes the effects of stopTheWorldGC.
+func startTheWorldGC() {
+ startTheWorld()
+ semrelease(&gcsema)
+}
+
+// Holding worldsema grants an M the right to try to stop the world.
+var worldsema uint32 = 1
+
+// Holding gcsema grants the M the right to block a GC, and blocks
+// until the current GC is done. In particular, it prevents gomaxprocs
+// from changing concurrently.
+//
+// TODO(mknyszek): Once gomaxprocs and the execution tracer can handle
+// being changed/enabled during a GC, remove this.
+var gcsema uint32 = 1
+
+// stopTheWorldWithSema is the core implementation of stopTheWorld.
+// The caller is responsible for acquiring worldsema and disabling
+// preemption first and then should stopTheWorldWithSema on the system
+// stack:
+//
+// semacquire(&worldsema, 0)
+// m.preemptoff = "reason"
+// systemstack(stopTheWorldWithSema)
+//
+// When finished, the caller must either call startTheWorld or undo
+// these three operations separately:
+//
+// m.preemptoff = ""
+// systemstack(startTheWorldWithSema)
+// semrelease(&worldsema)
+//
+// It is allowed to acquire worldsema once and then execute multiple
+// startTheWorldWithSema/stopTheWorldWithSema pairs.
+// Other P's are able to execute between successive calls to
+// startTheWorldWithSema and stopTheWorldWithSema.
+// Holding worldsema causes any other goroutines invoking
+// stopTheWorld to block.
+func stopTheWorldWithSema(reason stwReason) {
+ if traceEnabled() {
+ traceSTWStart(reason)
+ }
+ gp := getg()
+
+ // If we hold a lock, then we won't be able to stop another M
+ // that is blocked trying to acquire the lock.
+ if gp.m.locks > 0 {
+ throw("stopTheWorld: holding locks")
+ }
+
+ lock(&sched.lock)
+ sched.stopwait = gomaxprocs
+ sched.gcwaiting.Store(true)
+ preemptall()
+ // stop current P
+ gp.m.p.ptr().status = _Pgcstop // Pgcstop is only diagnostic.
+ sched.stopwait--
+ // try to retake all P's in Psyscall status
+ for _, pp := range allp {
+ s := pp.status
+ if s == _Psyscall && atomic.Cas(&pp.status, s, _Pgcstop) {
+ if traceEnabled() {
+ traceGoSysBlock(pp)
+ traceProcStop(pp)
+ }
+ pp.syscalltick++
+ sched.stopwait--
+ }
+ }
+ // stop idle P's
+ now := nanotime()
+ for {
+ pp, _ := pidleget(now)
+ if pp == nil {
+ break
+ }
+ pp.status = _Pgcstop
+ sched.stopwait--
+ }
+ wait := sched.stopwait > 0
+ unlock(&sched.lock)
+
+ // wait for remaining P's to stop voluntarily
+ if wait {
+ for {
+ // wait for 100us, then try to re-preempt in case of any races
+ if notetsleep(&sched.stopnote, 100*1000) {
+ noteclear(&sched.stopnote)
+ break
+ }
+ preemptall()
+ }
+ }
+
+ // sanity checks
+ bad := ""
+ if sched.stopwait != 0 {
+ bad = "stopTheWorld: not stopped (stopwait != 0)"
+ } else {
+ for _, pp := range allp {
+ if pp.status != _Pgcstop {
+ bad = "stopTheWorld: not stopped (status != _Pgcstop)"
+ }
+ }
+ }
+ if freezing.Load() {
+ // Some other thread is panicking. This can cause the
+ // sanity checks above to fail if the panic happens in
+ // the signal handler on a stopped thread. Either way,
+ // we should halt this thread.
+ lock(&deadlock)
+ lock(&deadlock)
+ }
+ if bad != "" {
+ throw(bad)
+ }
+
+ worldStopped()
+}
+
+func startTheWorldWithSema() int64 {
+ assertWorldStopped()
+
+ mp := acquirem() // disable preemption because it can be holding p in a local var
+ if netpollinited() {
+ list := netpoll(0) // non-blocking
+ injectglist(&list)
+ }
+ lock(&sched.lock)
+
+ procs := gomaxprocs
+ if newprocs != 0 {
+ procs = newprocs
+ newprocs = 0
+ }
+ p1 := procresize(procs)
+ sched.gcwaiting.Store(false)
+ if sched.sysmonwait.Load() {
+ sched.sysmonwait.Store(false)
+ notewakeup(&sched.sysmonnote)
+ }
+ unlock(&sched.lock)
+
+ worldStarted()
+
+ for p1 != nil {
+ p := p1
+ p1 = p1.link.ptr()
+ if p.m != 0 {
+ mp := p.m.ptr()
+ p.m = 0
+ if mp.nextp != 0 {
+ throw("startTheWorld: inconsistent mp->nextp")
+ }
+ mp.nextp.set(p)
+ notewakeup(&mp.park)
+ } else {
+ // Start M to run P. Do not start another M below.
+ newm(nil, p, -1)
+ }
+ }
+
+ // Capture start-the-world time before doing clean-up tasks.
+ startTime := nanotime()
+ if traceEnabled() {
+ traceSTWDone()
+ }
+
+ // Wakeup an additional proc in case we have excessive runnable goroutines
+ // in local queues or in the global queue. If we don't, the proc will park itself.
+ // If we have lots of excessive work, resetspinning will unpark additional procs as necessary.
+ wakep()
+
+ releasem(mp)
+
+ return startTime
+}
+
+// usesLibcall indicates whether this runtime performs system calls
+// via libcall.
+func usesLibcall() bool {
+ switch GOOS {
+ case "aix", "darwin", "illumos", "ios", "solaris", "windows":
+ return true
+ case "openbsd":
+ return GOARCH == "386" || GOARCH == "amd64" || GOARCH == "arm" || GOARCH == "arm64"
+ }
+ return false
+}
+
+// mStackIsSystemAllocated indicates whether this runtime starts on a
+// system-allocated stack.
+func mStackIsSystemAllocated() bool {
+ switch GOOS {
+ case "aix", "darwin", "plan9", "illumos", "ios", "solaris", "windows":
+ return true
+ case "openbsd":
+ switch GOARCH {
+ case "386", "amd64", "arm", "arm64":
+ return true
+ }
+ }
+ return false
+}
+
+// mstart is the entry-point for new Ms.
+// It is written in assembly, uses ABI0, is marked TOPFRAME, and calls mstart0.
+func mstart()
+
+// mstart0 is the Go entry-point for new Ms.
+// This must not split the stack because we may not even have stack
+// bounds set up yet.
+//
+// May run during STW (because it doesn't have a P yet), so write
+// barriers are not allowed.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func mstart0() {
+ gp := getg()
+
+ osStack := gp.stack.lo == 0
+ if osStack {
+ // Initialize stack bounds from system stack.
+ // Cgo may have left stack size in stack.hi.
+ // minit may update the stack bounds.
+ //
+ // Note: these bounds may not be very accurate.
+ // We set hi to &size, but there are things above
+ // it. The 1024 is supposed to compensate this,
+ // but is somewhat arbitrary.
+ size := gp.stack.hi
+ if size == 0 {
+ size = 16384 * sys.StackGuardMultiplier
+ }
+ gp.stack.hi = uintptr(noescape(unsafe.Pointer(&size)))
+ gp.stack.lo = gp.stack.hi - size + 1024
+ }
+ // Initialize stack guard so that we can start calling regular
+ // Go code.
+ gp.stackguard0 = gp.stack.lo + stackGuard
+ // This is the g0, so we can also call go:systemstack
+ // functions, which check stackguard1.
+ gp.stackguard1 = gp.stackguard0
+ mstart1()
+
+ // Exit this thread.
+ if mStackIsSystemAllocated() {
+ // Windows, Solaris, illumos, Darwin, AIX and Plan 9 always system-allocate
+ // the stack, but put it in gp.stack before mstart,
+ // so the logic above hasn't set osStack yet.
+ osStack = true
+ }
+ mexit(osStack)
+}
+
+// The go:noinline is to guarantee the getcallerpc/getcallersp below are safe,
+// so that we can set up g0.sched to return to the call of mstart1 above.
+//
+//go:noinline
+func mstart1() {
+ gp := getg()
+
+ if gp != gp.m.g0 {
+ throw("bad runtime·mstart")
+ }
+
+ // Set up m.g0.sched as a label returning to just
+ // after the mstart1 call in mstart0 above, for use by goexit0 and mcall.
+ // We're never coming back to mstart1 after we call schedule,
+ // so other calls can reuse the current frame.
+ // And goexit0 does a gogo that needs to return from mstart1
+ // and let mstart0 exit the thread.
+ gp.sched.g = guintptr(unsafe.Pointer(gp))
+ gp.sched.pc = getcallerpc()
+ gp.sched.sp = getcallersp()
+
+ asminit()
+ minit()
+
+ // Install signal handlers; after minit so that minit can
+ // prepare the thread to be able to handle the signals.
+ if gp.m == &m0 {
+ mstartm0()
+ }
+
+ if fn := gp.m.mstartfn; fn != nil {
+ fn()
+ }
+
+ if gp.m != &m0 {
+ acquirep(gp.m.nextp.ptr())
+ gp.m.nextp = 0
+ }
+ schedule()
+}
+
+// mstartm0 implements part of mstart1 that only runs on the m0.
+//
+// Write barriers are allowed here because we know the GC can't be
+// running yet, so they'll be no-ops.
+//
+//go:yeswritebarrierrec
+func mstartm0() {
+ // Create an extra M for callbacks on threads not created by Go.
+ // An extra M is also needed on Windows for callbacks created by
+ // syscall.NewCallback. See issue #6751 for details.
+ if (iscgo || GOOS == "windows") && !cgoHasExtraM {
+ cgoHasExtraM = true
+ newextram()
+ }
+ initsig(false)
+}
+
+// mPark causes a thread to park itself, returning once woken.
+//
+//go:nosplit
+func mPark() {
+ gp := getg()
+ notesleep(&gp.m.park)
+ noteclear(&gp.m.park)
+}
+
+// mexit tears down and exits the current thread.
+//
+// Don't call this directly to exit the thread, since it must run at
+// the top of the thread stack. Instead, use gogo(&gp.m.g0.sched) to
+// unwind the stack to the point that exits the thread.
+//
+// It is entered with m.p != nil, so write barriers are allowed. It
+// will release the P before exiting.
+//
+//go:yeswritebarrierrec
+func mexit(osStack bool) {
+ mp := getg().m
+
+ if mp == &m0 {
+ // This is the main thread. Just wedge it.
+ //
+ // On Linux, exiting the main thread puts the process
+ // into a non-waitable zombie state. On Plan 9,
+ // exiting the main thread unblocks wait even though
+ // other threads are still running. On Solaris we can
+ // neither exitThread nor return from mstart. Other
+ // bad things probably happen on other platforms.
+ //
+ // We could try to clean up this M more before wedging
+ // it, but that complicates signal handling.
+ handoffp(releasep())
+ lock(&sched.lock)
+ sched.nmfreed++
+ checkdead()
+ unlock(&sched.lock)
+ mPark()
+ throw("locked m0 woke up")
+ }
+
+ sigblock(true)
+ unminit()
+
+ // Free the gsignal stack.
+ if mp.gsignal != nil {
+ stackfree(mp.gsignal.stack)
+ // On some platforms, when calling into VDSO (e.g. nanotime)
+ // we store our g on the gsignal stack, if there is one.
+ // Now the stack is freed, unlink it from the m, so we
+ // won't write to it when calling VDSO code.
+ mp.gsignal = nil
+ }
+
+ // Remove m from allm.
+ lock(&sched.lock)
+ for pprev := &allm; *pprev != nil; pprev = &(*pprev).alllink {
+ if *pprev == mp {
+ *pprev = mp.alllink
+ goto found
+ }
+ }
+ throw("m not found in allm")
+found:
+ // Delay reaping m until it's done with the stack.
+ //
+ // Put mp on the free list, though it will not be reaped while freeWait
+ // is freeMWait. mp is no longer reachable via allm, so even if it is
+ // on an OS stack, we must keep a reference to mp alive so that the GC
+ // doesn't free mp while we are still using it.
+ //
+ // Note that the free list must not be linked through alllink because
+ // some functions walk allm without locking, so may be using alllink.
+ mp.freeWait.Store(freeMWait)
+ mp.freelink = sched.freem
+ sched.freem = mp
+ unlock(&sched.lock)
+
+ atomic.Xadd64(&ncgocall, int64(mp.ncgocall))
+
+ // Release the P.
+ handoffp(releasep())
+ // After this point we must not have write barriers.
+
+ // Invoke the deadlock detector. This must happen after
+ // handoffp because it may have started a new M to take our
+ // P's work.
+ lock(&sched.lock)
+ sched.nmfreed++
+ checkdead()
+ unlock(&sched.lock)
+
+ if GOOS == "darwin" || GOOS == "ios" {
+ // Make sure pendingPreemptSignals is correct when an M exits.
+ // For #41702.
+ if mp.signalPending.Load() != 0 {
+ pendingPreemptSignals.Add(-1)
+ }
+ }
+
+ // Destroy all allocated resources. After this is called, we may no
+ // longer take any locks.
+ mdestroy(mp)
+
+ if osStack {
+ // No more uses of mp, so it is safe to drop the reference.
+ mp.freeWait.Store(freeMRef)
+
+ // Return from mstart and let the system thread
+ // library free the g0 stack and terminate the thread.
+ return
+ }
+
+ // mstart is the thread's entry point, so there's nothing to
+ // return to. Exit the thread directly. exitThread will clear
+ // m.freeWait when it's done with the stack and the m can be
+ // reaped.
+ exitThread(&mp.freeWait)
+}
+
+// forEachP calls fn(p) for every P p when p reaches a GC safe point.
+// If a P is currently executing code, this will bring the P to a GC
+// safe point and execute fn on that P. If the P is not executing code
+// (it is idle or in a syscall), this will call fn(p) directly while
+// preventing the P from exiting its state. This does not ensure that
+// fn will run on every CPU executing Go code, but it acts as a global
+// memory barrier. GC uses this as a "ragged barrier."
+//
+// The caller must hold worldsema.
+//
+//go:systemstack
+func forEachP(fn func(*p)) {
+ mp := acquirem()
+ pp := getg().m.p.ptr()
+
+ lock(&sched.lock)
+ if sched.safePointWait != 0 {
+ throw("forEachP: sched.safePointWait != 0")
+ }
+ sched.safePointWait = gomaxprocs - 1
+ sched.safePointFn = fn
+
+ // Ask all Ps to run the safe point function.
+ for _, p2 := range allp {
+ if p2 != pp {
+ atomic.Store(&p2.runSafePointFn, 1)
+ }
+ }
+ preemptall()
+
+ // Any P entering _Pidle or _Psyscall from now on will observe
+ // p.runSafePointFn == 1 and will call runSafePointFn when
+ // changing its status to _Pidle/_Psyscall.
+
+ // Run safe point function for all idle Ps. sched.pidle will
+ // not change because we hold sched.lock.
+ for p := sched.pidle.ptr(); p != nil; p = p.link.ptr() {
+ if atomic.Cas(&p.runSafePointFn, 1, 0) {
+ fn(p)
+ sched.safePointWait--
+ }
+ }
+
+ wait := sched.safePointWait > 0
+ unlock(&sched.lock)
+
+ // Run fn for the current P.
+ fn(pp)
+
+ // Force Ps currently in _Psyscall into _Pidle and hand them
+ // off to induce safe point function execution.
+ for _, p2 := range allp {
+ s := p2.status
+ if s == _Psyscall && p2.runSafePointFn == 1 && atomic.Cas(&p2.status, s, _Pidle) {
+ if traceEnabled() {
+ traceGoSysBlock(p2)
+ traceProcStop(p2)
+ }
+ p2.syscalltick++
+ handoffp(p2)
+ }
+ }
+
+ // Wait for remaining Ps to run fn.
+ if wait {
+ for {
+ // Wait for 100us, then try to re-preempt in
+ // case of any races.
+ //
+ // Requires system stack.
+ if notetsleep(&sched.safePointNote, 100*1000) {
+ noteclear(&sched.safePointNote)
+ break
+ }
+ preemptall()
+ }
+ }
+ if sched.safePointWait != 0 {
+ throw("forEachP: not done")
+ }
+ for _, p2 := range allp {
+ if p2.runSafePointFn != 0 {
+ throw("forEachP: P did not run fn")
+ }
+ }
+
+ lock(&sched.lock)
+ sched.safePointFn = nil
+ unlock(&sched.lock)
+ releasem(mp)
+}
+
+// runSafePointFn runs the safe point function, if any, for this P.
+// This should be called like
+//
+// if getg().m.p.runSafePointFn != 0 {
+// runSafePointFn()
+// }
+//
+// runSafePointFn must be checked on any transition in to _Pidle or
+// _Psyscall to avoid a race where forEachP sees that the P is running
+// just before the P goes into _Pidle/_Psyscall and neither forEachP
+// nor the P run the safe-point function.
+func runSafePointFn() {
+ p := getg().m.p.ptr()
+ // Resolve the race between forEachP running the safe-point
+ // function on this P's behalf and this P running the
+ // safe-point function directly.
+ if !atomic.Cas(&p.runSafePointFn, 1, 0) {
+ return
+ }
+ sched.safePointFn(p)
+ lock(&sched.lock)
+ sched.safePointWait--
+ if sched.safePointWait == 0 {
+ notewakeup(&sched.safePointNote)
+ }
+ unlock(&sched.lock)
+}
+
+// When running with cgo, we call _cgo_thread_start
+// to start threads for us so that we can play nicely with
+// foreign code.
+var cgoThreadStart unsafe.Pointer
+
+type cgothreadstart struct {
+ g guintptr
+ tls *uint64
+ fn unsafe.Pointer
+}
+
+// Allocate a new m unassociated with any thread.
+// Can use p for allocation context if needed.
+// fn is recorded as the new m's m.mstartfn.
+// id is optional pre-allocated m ID. Omit by passing -1.
+//
+// This function is allowed to have write barriers even if the caller
+// isn't because it borrows pp.
+//
+//go:yeswritebarrierrec
+func allocm(pp *p, fn func(), id int64) *m {
+ allocmLock.rlock()
+
+ // The caller owns pp, but we may borrow (i.e., acquirep) it. We must
+ // disable preemption to ensure it is not stolen, which would make the
+ // caller lose ownership.
+ acquirem()
+
+ gp := getg()
+ if gp.m.p == 0 {
+ acquirep(pp) // temporarily borrow p for mallocs in this function
+ }
+
+ // Release the free M list. We need to do this somewhere and
+ // this may free up a stack we can use.
+ if sched.freem != nil {
+ lock(&sched.lock)
+ var newList *m
+ for freem := sched.freem; freem != nil; {
+ wait := freem.freeWait.Load()
+ if wait == freeMWait {
+ next := freem.freelink
+ freem.freelink = newList
+ newList = freem
+ freem = next
+ continue
+ }
+ // Free the stack if needed. For freeMRef, there is
+ // nothing to do except drop freem from the sched.freem
+ // list.
+ if wait == freeMStack {
+ // stackfree must be on the system stack, but allocm is
+ // reachable off the system stack transitively from
+ // startm.
+ systemstack(func() {
+ stackfree(freem.g0.stack)
+ })
+ }
+ freem = freem.freelink
+ }
+ sched.freem = newList
+ unlock(&sched.lock)
+ }
+
+ mp := new(m)
+ mp.mstartfn = fn
+ mcommoninit(mp, id)
+
+ // In case of cgo or Solaris or illumos or Darwin, pthread_create will make us a stack.
+ // Windows and Plan 9 will layout sched stack on OS stack.
+ if iscgo || mStackIsSystemAllocated() {
+ mp.g0 = malg(-1)
+ } else {
+ mp.g0 = malg(16384 * sys.StackGuardMultiplier)
+ }
+ mp.g0.m = mp
+
+ if pp == gp.m.p.ptr() {
+ releasep()
+ }
+
+ releasem(gp.m)
+ allocmLock.runlock()
+ return mp
+}
+
+// needm is called when a cgo callback happens on a
+// thread without an m (a thread not created by Go).
+// In this case, needm is expected to find an m to use
+// and return with m, g initialized correctly.
+// Since m and g are not set now (likely nil, but see below)
+// needm is limited in what routines it can call. In particular
+// it can only call nosplit functions (textflag 7) and cannot
+// do any scheduling that requires an m.
+//
+// In order to avoid needing heavy lifting here, we adopt
+// the following strategy: there is a stack of available m's
+// that can be stolen. Using compare-and-swap
+// to pop from the stack has ABA races, so we simulate
+// a lock by doing an exchange (via Casuintptr) to steal the stack
+// head and replace the top pointer with MLOCKED (1).
+// This serves as a simple spin lock that we can use even
+// without an m. The thread that locks the stack in this way
+// unlocks the stack by storing a valid stack head pointer.
+//
+// In order to make sure that there is always an m structure
+// available to be stolen, we maintain the invariant that there
+// is always one more than needed. At the beginning of the
+// program (if cgo is in use) the list is seeded with a single m.
+// If needm finds that it has taken the last m off the list, its job
+// is - once it has installed its own m so that it can do things like
+// allocate memory - to create a spare m and put it on the list.
+//
+// Each of these extra m's also has a g0 and a curg that are
+// pressed into service as the scheduling stack and current
+// goroutine for the duration of the cgo callback.
+//
+// It calls dropm to put the m back on the list,
+// 1. when the callback is done with the m in non-pthread platforms,
+// 2. or when the C thread exiting on pthread platforms.
+//
+// The signal argument indicates whether we're called from a signal
+// handler.
+//
+//go:nosplit
+func needm(signal bool) {
+ if (iscgo || GOOS == "windows") && !cgoHasExtraM {
+ // Can happen if C/C++ code calls Go from a global ctor.
+ // Can also happen on Windows if a global ctor uses a
+ // callback created by syscall.NewCallback. See issue #6751
+ // for details.
+ //
+ // Can not throw, because scheduler is not initialized yet.
+ writeErrStr("fatal error: cgo callback before cgo call\n")
+ exit(1)
+ }
+
+ // Save and block signals before getting an M.
+ // The signal handler may call needm itself,
+ // and we must avoid a deadlock. Also, once g is installed,
+ // any incoming signals will try to execute,
+ // but we won't have the sigaltstack settings and other data
+ // set up appropriately until the end of minit, which will
+ // unblock the signals. This is the same dance as when
+ // starting a new m to run Go code via newosproc.
+ var sigmask sigset
+ sigsave(&sigmask)
+ sigblock(false)
+
+ // getExtraM is safe here because of the invariant above,
+ // that the extra list always contains or will soon contain
+ // at least one m.
+ mp, last := getExtraM()
+
+ // Set needextram when we've just emptied the list,
+ // so that the eventual call into cgocallbackg will
+ // allocate a new m for the extra list. We delay the
+ // allocation until then so that it can be done
+ // after exitsyscall makes sure it is okay to be
+ // running at all (that is, there's no garbage collection
+ // running right now).
+ mp.needextram = last
+
+ // Store the original signal mask for use by minit.
+ mp.sigmask = sigmask
+
+ // Install TLS on some platforms (previously setg
+ // would do this if necessary).
+ osSetupTLS(mp)
+
+ // Install g (= m->g0) and set the stack bounds
+ // to match the current stack. If we don't actually know
+ // how big the stack is, like we don't know how big any
+ // scheduling stack is, but we assume there's at least 32 kB.
+ // If we can get a more accurate stack bound from pthread,
+ // use that.
+ setg(mp.g0)
+ gp := getg()
+ gp.stack.hi = getcallersp() + 1024
+ gp.stack.lo = getcallersp() - 32*1024
+ if !signal && _cgo_getstackbound != nil {
+ // Don't adjust if called from the signal handler.
+ // We are on the signal stack, not the pthread stack.
+ // (We could get the stack bounds from sigaltstack, but
+ // we're getting out of the signal handler very soon
+ // anyway. Not worth it.)
+ var bounds [2]uintptr
+ asmcgocall(_cgo_getstackbound, unsafe.Pointer(&bounds))
+ // getstackbound is an unsupported no-op on Windows.
+ if bounds[0] != 0 {
+ gp.stack.lo = bounds[0]
+ gp.stack.hi = bounds[1]
+ }
+ }
+ gp.stackguard0 = gp.stack.lo + stackGuard
+
+ // Should mark we are already in Go now.
+ // Otherwise, we may call needm again when we get a signal, before cgocallbackg1,
+ // which means the extram list may be empty, that will cause a deadlock.
+ mp.isExtraInC = false
+
+ // Initialize this thread to use the m.
+ asminit()
+ minit()
+
+ // mp.curg is now a real goroutine.
+ casgstatus(mp.curg, _Gdead, _Gsyscall)
+ sched.ngsys.Add(-1)
+}
+
+// Acquire an extra m and bind it to the C thread when a pthread key has been created.
+//
+//go:nosplit
+func needAndBindM() {
+ needm(false)
+
+ if _cgo_pthread_key_created != nil && *(*uintptr)(_cgo_pthread_key_created) != 0 {
+ cgoBindM()
+ }
+}
+
+// newextram allocates m's and puts them on the extra list.
+// It is called with a working local m, so that it can do things
+// like call schedlock and allocate.
+func newextram() {
+ c := extraMWaiters.Swap(0)
+ if c > 0 {
+ for i := uint32(0); i < c; i++ {
+ oneNewExtraM()
+ }
+ } else if extraMLength.Load() == 0 {
+ // Make sure there is at least one extra M.
+ oneNewExtraM()
+ }
+}
+
+// oneNewExtraM allocates an m and puts it on the extra list.
+func oneNewExtraM() {
+ // Create extra goroutine locked to extra m.
+ // The goroutine is the context in which the cgo callback will run.
+ // The sched.pc will never be returned to, but setting it to
+ // goexit makes clear to the traceback routines where
+ // the goroutine stack ends.
+ mp := allocm(nil, nil, -1)
+ gp := malg(4096)
+ gp.sched.pc = abi.FuncPCABI0(goexit) + sys.PCQuantum
+ gp.sched.sp = gp.stack.hi
+ gp.sched.sp -= 4 * goarch.PtrSize // extra space in case of reads slightly beyond frame
+ gp.sched.lr = 0
+ gp.sched.g = guintptr(unsafe.Pointer(gp))
+ gp.syscallpc = gp.sched.pc
+ gp.syscallsp = gp.sched.sp
+ gp.stktopsp = gp.sched.sp
+ // malg returns status as _Gidle. Change to _Gdead before
+ // adding to allg where GC can see it. We use _Gdead to hide
+ // this from tracebacks and stack scans since it isn't a
+ // "real" goroutine until needm grabs it.
+ casgstatus(gp, _Gidle, _Gdead)
+ gp.m = mp
+ mp.curg = gp
+ mp.isextra = true
+ // mark we are in C by default.
+ mp.isExtraInC = true
+ mp.lockedInt++
+ mp.lockedg.set(gp)
+ gp.lockedm.set(mp)
+ gp.goid = sched.goidgen.Add(1)
+ if raceenabled {
+ gp.racectx = racegostart(abi.FuncPCABIInternal(newextram) + sys.PCQuantum)
+ }
+ if traceEnabled() {
+ traceOneNewExtraM(gp)
+ }
+ // put on allg for garbage collector
+ allgadd(gp)
+
+ // gp is now on the allg list, but we don't want it to be
+ // counted by gcount. It would be more "proper" to increment
+ // sched.ngfree, but that requires locking. Incrementing ngsys
+ // has the same effect.
+ sched.ngsys.Add(1)
+
+ // Add m to the extra list.
+ addExtraM(mp)
+}
+
+// dropm puts the current m back onto the extra list.
+//
+// 1. On systems without pthreads, like Windows
+// dropm is called when a cgo callback has called needm but is now
+// done with the callback and returning back into the non-Go thread.
+//
+// The main expense here is the call to signalstack to release the
+// m's signal stack, and then the call to needm on the next callback
+// from this thread. It is tempting to try to save the m for next time,
+// which would eliminate both these costs, but there might not be
+// a next time: the current thread (which Go does not control) might exit.
+// If we saved the m for that thread, there would be an m leak each time
+// such a thread exited. Instead, we acquire and release an m on each
+// call. These should typically not be scheduling operations, just a few
+// atomics, so the cost should be small.
+//
+// 2. On systems with pthreads
+// dropm is called while a non-Go thread is exiting.
+// We allocate a pthread per-thread variable using pthread_key_create,
+// to register a thread-exit-time destructor.
+// And store the g into a thread-specific value associated with the pthread key,
+// when first return back to C.
+// So that the destructor would invoke dropm while the non-Go thread is exiting.
+// This is much faster since it avoids expensive signal-related syscalls.
+//
+// NOTE: this always runs without a P, so, nowritebarrierrec required.
+//
+//go:nowritebarrierrec
+func dropm() {
+ // Clear m and g, and return m to the extra list.
+ // After the call to setg we can only call nosplit functions
+ // with no pointer manipulation.
+ mp := getg().m
+
+ // Return mp.curg to dead state.
+ casgstatus(mp.curg, _Gsyscall, _Gdead)
+ mp.curg.preemptStop = false
+ sched.ngsys.Add(1)
+
+ // Block signals before unminit.
+ // Unminit unregisters the signal handling stack (but needs g on some systems).
+ // Setg(nil) clears g, which is the signal handler's cue not to run Go handlers.
+ // It's important not to try to handle a signal between those two steps.
+ sigmask := mp.sigmask
+ sigblock(false)
+ unminit()
+
+ setg(nil)
+
+ putExtraM(mp)
+
+ msigrestore(sigmask)
+}
+
+// bindm store the g0 of the current m into a thread-specific value.
+//
+// We allocate a pthread per-thread variable using pthread_key_create,
+// to register a thread-exit-time destructor.
+// We are here setting the thread-specific value of the pthread key, to enable the destructor.
+// So that the pthread_key_destructor would dropm while the C thread is exiting.
+//
+// And the saved g will be used in pthread_key_destructor,
+// since the g stored in the TLS by Go might be cleared in some platforms,
+// before the destructor invoked, so, we restore g by the stored g, before dropm.
+//
+// We store g0 instead of m, to make the assembly code simpler,
+// since we need to restore g0 in runtime.cgocallback.
+//
+// On systems without pthreads, like Windows, bindm shouldn't be used.
+//
+// NOTE: this always runs without a P, so, nowritebarrierrec required.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func cgoBindM() {
+ if GOOS == "windows" || GOOS == "plan9" {
+ fatal("bindm in unexpected GOOS")
+ }
+ g := getg()
+ if g.m.g0 != g {
+ fatal("the current g is not g0")
+ }
+ if _cgo_bindm != nil {
+ asmcgocall(_cgo_bindm, unsafe.Pointer(g))
+ }
+}
+
+// A helper function for EnsureDropM.
+func getm() uintptr {
+ return uintptr(unsafe.Pointer(getg().m))
+}
+
+var (
+ // Locking linked list of extra M's, via mp.schedlink. Must be accessed
+ // only via lockextra/unlockextra.
+ //
+ // Can't be atomic.Pointer[m] because we use an invalid pointer as a
+ // "locked" sentinel value. M's on this list remain visible to the GC
+ // because their mp.curg is on allgs.
+ extraM atomic.Uintptr
+ // Number of M's in the extraM list.
+ extraMLength atomic.Uint32
+ // Number of waiters in lockextra.
+ extraMWaiters atomic.Uint32
+
+ // Number of extra M's in use by threads.
+ extraMInUse atomic.Uint32
+)
+
+// lockextra locks the extra list and returns the list head.
+// The caller must unlock the list by storing a new list head
+// to extram. If nilokay is true, then lockextra will
+// return a nil list head if that's what it finds. If nilokay is false,
+// lockextra will keep waiting until the list head is no longer nil.
+//
+//go:nosplit
+func lockextra(nilokay bool) *m {
+ const locked = 1
+
+ incr := false
+ for {
+ old := extraM.Load()
+ if old == locked {
+ osyield_no_g()
+ continue
+ }
+ if old == 0 && !nilokay {
+ if !incr {
+ // Add 1 to the number of threads
+ // waiting for an M.
+ // This is cleared by newextram.
+ extraMWaiters.Add(1)
+ incr = true
+ }
+ usleep_no_g(1)
+ continue
+ }
+ if extraM.CompareAndSwap(old, locked) {
+ return (*m)(unsafe.Pointer(old))
+ }
+ osyield_no_g()
+ continue
+ }
+}
+
+//go:nosplit
+func unlockextra(mp *m, delta int32) {
+ extraMLength.Add(delta)
+ extraM.Store(uintptr(unsafe.Pointer(mp)))
+}
+
+// Return an M from the extra M list. Returns last == true if the list becomes
+// empty because of this call.
+//
+// Spins waiting for an extra M, so caller must ensure that the list always
+// contains or will soon contain at least one M.
+//
+//go:nosplit
+func getExtraM() (mp *m, last bool) {
+ mp = lockextra(false)
+ extraMInUse.Add(1)
+ unlockextra(mp.schedlink.ptr(), -1)
+ return mp, mp.schedlink.ptr() == nil
+}
+
+// Returns an extra M back to the list. mp must be from getExtraM. Newly
+// allocated M's should use addExtraM.
+//
+//go:nosplit
+func putExtraM(mp *m) {
+ extraMInUse.Add(-1)
+ addExtraM(mp)
+}
+
+// Adds a newly allocated M to the extra M list.
+//
+//go:nosplit
+func addExtraM(mp *m) {
+ mnext := lockextra(true)
+ mp.schedlink.set(mnext)
+ unlockextra(mp, 1)
+}
+
+var (
+ // allocmLock is locked for read when creating new Ms in allocm and their
+ // addition to allm. Thus acquiring this lock for write blocks the
+ // creation of new Ms.
+ allocmLock rwmutex
+
+ // execLock serializes exec and clone to avoid bugs or unspecified
+ // behaviour around exec'ing while creating/destroying threads. See
+ // issue #19546.
+ execLock rwmutex
+)
+
+// These errors are reported (via writeErrStr) by some OS-specific
+// versions of newosproc and newosproc0.
+const (
+ failthreadcreate = "runtime: failed to create new OS thread\n"
+ failallocatestack = "runtime: failed to allocate stack for the new OS thread\n"
+)
+
+// newmHandoff contains a list of m structures that need new OS threads.
+// This is used by newm in situations where newm itself can't safely
+// start an OS thread.
+var newmHandoff struct {
+ lock mutex
+
+ // newm points to a list of M structures that need new OS
+ // threads. The list is linked through m.schedlink.
+ newm muintptr
+
+ // waiting indicates that wake needs to be notified when an m
+ // is put on the list.
+ waiting bool
+ wake note
+
+ // haveTemplateThread indicates that the templateThread has
+ // been started. This is not protected by lock. Use cas to set
+ // to 1.
+ haveTemplateThread uint32
+}
+
+// Create a new m. It will start off with a call to fn, or else the scheduler.
+// fn needs to be static and not a heap allocated closure.
+// May run with m.p==nil, so write barriers are not allowed.
+//
+// id is optional pre-allocated m ID. Omit by passing -1.
+//
+//go:nowritebarrierrec
+func newm(fn func(), pp *p, id int64) {
+ // allocm adds a new M to allm, but they do not start until created by
+ // the OS in newm1 or the template thread.
+ //
+ // doAllThreadsSyscall requires that every M in allm will eventually
+ // start and be signal-able, even with a STW.
+ //
+ // Disable preemption here until we start the thread to ensure that
+ // newm is not preempted between allocm and starting the new thread,
+ // ensuring that anything added to allm is guaranteed to eventually
+ // start.
+ acquirem()
+
+ mp := allocm(pp, fn, id)
+ mp.nextp.set(pp)
+ mp.sigmask = initSigmask
+ if gp := getg(); gp != nil && gp.m != nil && (gp.m.lockedExt != 0 || gp.m.incgo) && GOOS != "plan9" {
+ // We're on a locked M or a thread that may have been
+ // started by C. The kernel state of this thread may
+ // be strange (the user may have locked it for that
+ // purpose). We don't want to clone that into another
+ // thread. Instead, ask a known-good thread to create
+ // the thread for us.
+ //
+ // This is disabled on Plan 9. See golang.org/issue/22227.
+ //
+ // TODO: This may be unnecessary on Windows, which
+ // doesn't model thread creation off fork.
+ lock(&newmHandoff.lock)
+ if newmHandoff.haveTemplateThread == 0 {
+ throw("on a locked thread with no template thread")
+ }
+ mp.schedlink = newmHandoff.newm
+ newmHandoff.newm.set(mp)
+ if newmHandoff.waiting {
+ newmHandoff.waiting = false
+ notewakeup(&newmHandoff.wake)
+ }
+ unlock(&newmHandoff.lock)
+ // The M has not started yet, but the template thread does not
+ // participate in STW, so it will always process queued Ms and
+ // it is safe to releasem.
+ releasem(getg().m)
+ return
+ }
+ newm1(mp)
+ releasem(getg().m)
+}
+
+func newm1(mp *m) {
+ if iscgo {
+ var ts cgothreadstart
+ if _cgo_thread_start == nil {
+ throw("_cgo_thread_start missing")
+ }
+ ts.g.set(mp.g0)
+ ts.tls = (*uint64)(unsafe.Pointer(&mp.tls[0]))
+ ts.fn = unsafe.Pointer(abi.FuncPCABI0(mstart))
+ if msanenabled {
+ msanwrite(unsafe.Pointer(&ts), unsafe.Sizeof(ts))
+ }
+ if asanenabled {
+ asanwrite(unsafe.Pointer(&ts), unsafe.Sizeof(ts))
+ }
+ execLock.rlock() // Prevent process clone.
+ asmcgocall(_cgo_thread_start, unsafe.Pointer(&ts))
+ execLock.runlock()
+ return
+ }
+ execLock.rlock() // Prevent process clone.
+ newosproc(mp)
+ execLock.runlock()
+}
+
+// startTemplateThread starts the template thread if it is not already
+// running.
+//
+// The calling thread must itself be in a known-good state.
+func startTemplateThread() {
+ if GOARCH == "wasm" { // no threads on wasm yet
+ return
+ }
+
+ // Disable preemption to guarantee that the template thread will be
+ // created before a park once haveTemplateThread is set.
+ mp := acquirem()
+ if !atomic.Cas(&newmHandoff.haveTemplateThread, 0, 1) {
+ releasem(mp)
+ return
+ }
+ newm(templateThread, nil, -1)
+ releasem(mp)
+}
+
+// templateThread is a thread in a known-good state that exists solely
+// to start new threads in known-good states when the calling thread
+// may not be in a good state.
+//
+// Many programs never need this, so templateThread is started lazily
+// when we first enter a state that might lead to running on a thread
+// in an unknown state.
+//
+// templateThread runs on an M without a P, so it must not have write
+// barriers.
+//
+//go:nowritebarrierrec
+func templateThread() {
+ lock(&sched.lock)
+ sched.nmsys++
+ checkdead()
+ unlock(&sched.lock)
+
+ for {
+ lock(&newmHandoff.lock)
+ for newmHandoff.newm != 0 {
+ newm := newmHandoff.newm.ptr()
+ newmHandoff.newm = 0
+ unlock(&newmHandoff.lock)
+ for newm != nil {
+ next := newm.schedlink.ptr()
+ newm.schedlink = 0
+ newm1(newm)
+ newm = next
+ }
+ lock(&newmHandoff.lock)
+ }
+ newmHandoff.waiting = true
+ noteclear(&newmHandoff.wake)
+ unlock(&newmHandoff.lock)
+ notesleep(&newmHandoff.wake)
+ }
+}
+
+// Stops execution of the current m until new work is available.
+// Returns with acquired P.
+func stopm() {
+ gp := getg()
+
+ if gp.m.locks != 0 {
+ throw("stopm holding locks")
+ }
+ if gp.m.p != 0 {
+ throw("stopm holding p")
+ }
+ if gp.m.spinning {
+ throw("stopm spinning")
+ }
+
+ lock(&sched.lock)
+ mput(gp.m)
+ unlock(&sched.lock)
+ mPark()
+ acquirep(gp.m.nextp.ptr())
+ gp.m.nextp = 0
+}
+
+func mspinning() {
+ // startm's caller incremented nmspinning. Set the new M's spinning.
+ getg().m.spinning = true
+}
+
+// Schedules some M to run the p (creates an M if necessary).
+// If p==nil, tries to get an idle P, if no idle P's does nothing.
+// May run with m.p==nil, so write barriers are not allowed.
+// If spinning is set, the caller has incremented nmspinning and must provide a
+// P. startm will set m.spinning in the newly started M.
+//
+// Callers passing a non-nil P must call from a non-preemptible context. See
+// comment on acquirem below.
+//
+// Argument lockheld indicates whether the caller already acquired the
+// scheduler lock. Callers holding the lock when making the call must pass
+// true. The lock might be temporarily dropped, but will be reacquired before
+// returning.
+//
+// Must not have write barriers because this may be called without a P.
+//
+//go:nowritebarrierrec
+func startm(pp *p, spinning, lockheld bool) {
+ // Disable preemption.
+ //
+ // Every owned P must have an owner that will eventually stop it in the
+ // event of a GC stop request. startm takes transient ownership of a P
+ // (either from argument or pidleget below) and transfers ownership to
+ // a started M, which will be responsible for performing the stop.
+ //
+ // Preemption must be disabled during this transient ownership,
+ // otherwise the P this is running on may enter GC stop while still
+ // holding the transient P, leaving that P in limbo and deadlocking the
+ // STW.
+ //
+ // Callers passing a non-nil P must already be in non-preemptible
+ // context, otherwise such preemption could occur on function entry to
+ // startm. Callers passing a nil P may be preemptible, so we must
+ // disable preemption before acquiring a P from pidleget below.
+ mp := acquirem()
+ if !lockheld {
+ lock(&sched.lock)
+ }
+ if pp == nil {
+ if spinning {
+ // TODO(prattmic): All remaining calls to this function
+ // with _p_ == nil could be cleaned up to find a P
+ // before calling startm.
+ throw("startm: P required for spinning=true")
+ }
+ pp, _ = pidleget(0)
+ if pp == nil {
+ if !lockheld {
+ unlock(&sched.lock)
+ }
+ releasem(mp)
+ return
+ }
+ }
+ nmp := mget()
+ if nmp == nil {
+ // No M is available, we must drop sched.lock and call newm.
+ // However, we already own a P to assign to the M.
+ //
+ // Once sched.lock is released, another G (e.g., in a syscall),
+ // could find no idle P while checkdead finds a runnable G but
+ // no running M's because this new M hasn't started yet, thus
+ // throwing in an apparent deadlock.
+ // This apparent deadlock is possible when startm is called
+ // from sysmon, which doesn't count as a running M.
+ //
+ // Avoid this situation by pre-allocating the ID for the new M,
+ // thus marking it as 'running' before we drop sched.lock. This
+ // new M will eventually run the scheduler to execute any
+ // queued G's.
+ id := mReserveID()
+ unlock(&sched.lock)
+
+ var fn func()
+ if spinning {
+ // The caller incremented nmspinning, so set m.spinning in the new M.
+ fn = mspinning
+ }
+ newm(fn, pp, id)
+
+ if lockheld {
+ lock(&sched.lock)
+ }
+ // Ownership transfer of pp committed by start in newm.
+ // Preemption is now safe.
+ releasem(mp)
+ return
+ }
+ if !lockheld {
+ unlock(&sched.lock)
+ }
+ if nmp.spinning {
+ throw("startm: m is spinning")
+ }
+ if nmp.nextp != 0 {
+ throw("startm: m has p")
+ }
+ if spinning && !runqempty(pp) {
+ throw("startm: p has runnable gs")
+ }
+ // The caller incremented nmspinning, so set m.spinning in the new M.
+ nmp.spinning = spinning
+ nmp.nextp.set(pp)
+ notewakeup(&nmp.park)
+ // Ownership transfer of pp committed by wakeup. Preemption is now
+ // safe.
+ releasem(mp)
+}
+
+// Hands off P from syscall or locked M.
+// Always runs without a P, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func handoffp(pp *p) {
+ // handoffp must start an M in any situation where
+ // findrunnable would return a G to run on pp.
+
+ // if it has local work, start it straight away
+ if !runqempty(pp) || sched.runqsize != 0 {
+ startm(pp, false, false)
+ return
+ }
+ // if there's trace work to do, start it straight away
+ if (traceEnabled() || traceShuttingDown()) && traceReaderAvailable() != nil {
+ startm(pp, false, false)
+ return
+ }
+ // if it has GC work, start it straight away
+ if gcBlackenEnabled != 0 && gcMarkWorkAvailable(pp) {
+ startm(pp, false, false)
+ return
+ }
+ // no local work, check that there are no spinning/idle M's,
+ // otherwise our help is not required
+ if sched.nmspinning.Load()+sched.npidle.Load() == 0 && sched.nmspinning.CompareAndSwap(0, 1) { // TODO: fast atomic
+ sched.needspinning.Store(0)
+ startm(pp, true, false)
+ return
+ }
+ lock(&sched.lock)
+ if sched.gcwaiting.Load() {
+ pp.status = _Pgcstop
+ sched.stopwait--
+ if sched.stopwait == 0 {
+ notewakeup(&sched.stopnote)
+ }
+ unlock(&sched.lock)
+ return
+ }
+ if pp.runSafePointFn != 0 && atomic.Cas(&pp.runSafePointFn, 1, 0) {
+ sched.safePointFn(pp)
+ sched.safePointWait--
+ if sched.safePointWait == 0 {
+ notewakeup(&sched.safePointNote)
+ }
+ }
+ if sched.runqsize != 0 {
+ unlock(&sched.lock)
+ startm(pp, false, false)
+ return
+ }
+ // If this is the last running P and nobody is polling network,
+ // need to wakeup another M to poll network.
+ if sched.npidle.Load() == gomaxprocs-1 && sched.lastpoll.Load() != 0 {
+ unlock(&sched.lock)
+ startm(pp, false, false)
+ return
+ }
+
+ // The scheduler lock cannot be held when calling wakeNetPoller below
+ // because wakeNetPoller may call wakep which may call startm.
+ when := nobarrierWakeTime(pp)
+ pidleput(pp, 0)
+ unlock(&sched.lock)
+
+ if when != 0 {
+ wakeNetPoller(when)
+ }
+}
+
+// Tries to add one more P to execute G's.
+// Called when a G is made runnable (newproc, ready).
+// Must be called with a P.
+func wakep() {
+ // Be conservative about spinning threads, only start one if none exist
+ // already.
+ if sched.nmspinning.Load() != 0 || !sched.nmspinning.CompareAndSwap(0, 1) {
+ return
+ }
+
+ // Disable preemption until ownership of pp transfers to the next M in
+ // startm. Otherwise preemption here would leave pp stuck waiting to
+ // enter _Pgcstop.
+ //
+ // See preemption comment on acquirem in startm for more details.
+ mp := acquirem()
+
+ var pp *p
+ lock(&sched.lock)
+ pp, _ = pidlegetSpinning(0)
+ if pp == nil {
+ if sched.nmspinning.Add(-1) < 0 {
+ throw("wakep: negative nmspinning")
+ }
+ unlock(&sched.lock)
+ releasem(mp)
+ return
+ }
+ // Since we always have a P, the race in the "No M is available"
+ // comment in startm doesn't apply during the small window between the
+ // unlock here and lock in startm. A checkdead in between will always
+ // see at least one running M (ours).
+ unlock(&sched.lock)
+
+ startm(pp, true, false)
+
+ releasem(mp)
+}
+
+// Stops execution of the current m that is locked to a g until the g is runnable again.
+// Returns with acquired P.
+func stoplockedm() {
+ gp := getg()
+
+ if gp.m.lockedg == 0 || gp.m.lockedg.ptr().lockedm.ptr() != gp.m {
+ throw("stoplockedm: inconsistent locking")
+ }
+ if gp.m.p != 0 {
+ // Schedule another M to run this p.
+ pp := releasep()
+ handoffp(pp)
+ }
+ incidlelocked(1)
+ // Wait until another thread schedules lockedg again.
+ mPark()
+ status := readgstatus(gp.m.lockedg.ptr())
+ if status&^_Gscan != _Grunnable {
+ print("runtime:stoplockedm: lockedg (atomicstatus=", status, ") is not Grunnable or Gscanrunnable\n")
+ dumpgstatus(gp.m.lockedg.ptr())
+ throw("stoplockedm: not runnable")
+ }
+ acquirep(gp.m.nextp.ptr())
+ gp.m.nextp = 0
+}
+
+// Schedules the locked m to run the locked gp.
+// May run during STW, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func startlockedm(gp *g) {
+ mp := gp.lockedm.ptr()
+ if mp == getg().m {
+ throw("startlockedm: locked to me")
+ }
+ if mp.nextp != 0 {
+ throw("startlockedm: m has p")
+ }
+ // directly handoff current P to the locked m
+ incidlelocked(-1)
+ pp := releasep()
+ mp.nextp.set(pp)
+ notewakeup(&mp.park)
+ stopm()
+}
+
+// Stops the current m for stopTheWorld.
+// Returns when the world is restarted.
+func gcstopm() {
+ gp := getg()
+
+ if !sched.gcwaiting.Load() {
+ throw("gcstopm: not waiting for gc")
+ }
+ if gp.m.spinning {
+ gp.m.spinning = false
+ // OK to just drop nmspinning here,
+ // startTheWorld will unpark threads as necessary.
+ if sched.nmspinning.Add(-1) < 0 {
+ throw("gcstopm: negative nmspinning")
+ }
+ }
+ pp := releasep()
+ lock(&sched.lock)
+ pp.status = _Pgcstop
+ sched.stopwait--
+ if sched.stopwait == 0 {
+ notewakeup(&sched.stopnote)
+ }
+ unlock(&sched.lock)
+ stopm()
+}
+
+// Schedules gp to run on the current M.
+// If inheritTime is true, gp inherits the remaining time in the
+// current time slice. Otherwise, it starts a new time slice.
+// Never returns.
+//
+// Write barriers are allowed because this is called immediately after
+// acquiring a P in several places.
+//
+//go:yeswritebarrierrec
+func execute(gp *g, inheritTime bool) {
+ mp := getg().m
+
+ if goroutineProfile.active {
+ // Make sure that gp has had its stack written out to the goroutine
+ // profile, exactly as it was when the goroutine profiler first stopped
+ // the world.
+ tryRecordGoroutineProfile(gp, osyield)
+ }
+
+ // Assign gp.m before entering _Grunning so running Gs have an
+ // M.
+ mp.curg = gp
+ gp.m = mp
+ casgstatus(gp, _Grunnable, _Grunning)
+ gp.waitsince = 0
+ gp.preempt = false
+ gp.stackguard0 = gp.stack.lo + stackGuard
+ if !inheritTime {
+ mp.p.ptr().schedtick++
+ }
+
+ // Check whether the profiler needs to be turned on or off.
+ hz := sched.profilehz
+ if mp.profilehz != hz {
+ setThreadCPUProfiler(hz)
+ }
+
+ if traceEnabled() {
+ // GoSysExit has to happen when we have a P, but before GoStart.
+ // So we emit it here.
+ if gp.syscallsp != 0 {
+ traceGoSysExit()
+ }
+ traceGoStart()
+ }
+
+ gogo(&gp.sched)
+}
+
+// Finds a runnable goroutine to execute.
+// Tries to steal from other P's, get g from local or global queue, poll network.
+// tryWakeP indicates that the returned goroutine is not normal (GC worker, trace
+// reader) so the caller should try to wake a P.
+func findRunnable() (gp *g, inheritTime, tryWakeP bool) {
+ mp := getg().m
+
+ // The conditions here and in handoffp must agree: if
+ // findrunnable would return a G to run, handoffp must start
+ // an M.
+
+top:
+ pp := mp.p.ptr()
+ if sched.gcwaiting.Load() {
+ gcstopm()
+ goto top
+ }
+ if pp.runSafePointFn != 0 {
+ runSafePointFn()
+ }
+
+ // now and pollUntil are saved for work stealing later,
+ // which may steal timers. It's important that between now
+ // and then, nothing blocks, so these numbers remain mostly
+ // relevant.
+ now, pollUntil, _ := checkTimers(pp, 0)
+
+ // Try to schedule the trace reader.
+ if traceEnabled() || traceShuttingDown() {
+ gp := traceReader()
+ if gp != nil {
+ casgstatus(gp, _Gwaiting, _Grunnable)
+ traceGoUnpark(gp, 0)
+ return gp, false, true
+ }
+ }
+
+ // Try to schedule a GC worker.
+ if gcBlackenEnabled != 0 {
+ gp, tnow := gcController.findRunnableGCWorker(pp, now)
+ if gp != nil {
+ return gp, false, true
+ }
+ now = tnow
+ }
+
+ // Check the global runnable queue once in a while to ensure fairness.
+ // Otherwise two goroutines can completely occupy the local runqueue
+ // by constantly respawning each other.
+ if pp.schedtick%61 == 0 && sched.runqsize > 0 {
+ lock(&sched.lock)
+ gp := globrunqget(pp, 1)
+ unlock(&sched.lock)
+ if gp != nil {
+ return gp, false, false
+ }
+ }
+
+ // Wake up the finalizer G.
+ if fingStatus.Load()&(fingWait|fingWake) == fingWait|fingWake {
+ if gp := wakefing(); gp != nil {
+ ready(gp, 0, true)
+ }
+ }
+ if *cgo_yield != nil {
+ asmcgocall(*cgo_yield, nil)
+ }
+
+ // local runq
+ if gp, inheritTime := runqget(pp); gp != nil {
+ return gp, inheritTime, false
+ }
+
+ // global runq
+ if sched.runqsize != 0 {
+ lock(&sched.lock)
+ gp := globrunqget(pp, 0)
+ unlock(&sched.lock)
+ if gp != nil {
+ return gp, false, false
+ }
+ }
+
+ // Poll network.
+ // This netpoll is only an optimization before we resort to stealing.
+ // We can safely skip it if there are no waiters or a thread is blocked
+ // in netpoll already. If there is any kind of logical race with that
+ // blocked thread (e.g. it has already returned from netpoll, but does
+ // not set lastpoll yet), this thread will do blocking netpoll below
+ // anyway.
+ if netpollinited() && netpollWaiters.Load() > 0 && sched.lastpoll.Load() != 0 {
+ if list := netpoll(0); !list.empty() { // non-blocking
+ gp := list.pop()
+ injectglist(&list)
+ casgstatus(gp, _Gwaiting, _Grunnable)
+ if traceEnabled() {
+ traceGoUnpark(gp, 0)
+ }
+ return gp, false, false
+ }
+ }
+
+ // Spinning Ms: steal work from other Ps.
+ //
+ // Limit the number of spinning Ms to half the number of busy Ps.
+ // This is necessary to prevent excessive CPU consumption when
+ // GOMAXPROCS>>1 but the program parallelism is low.
+ if mp.spinning || 2*sched.nmspinning.Load() < gomaxprocs-sched.npidle.Load() {
+ if !mp.spinning {
+ mp.becomeSpinning()
+ }
+
+ gp, inheritTime, tnow, w, newWork := stealWork(now)
+ if gp != nil {
+ // Successfully stole.
+ return gp, inheritTime, false
+ }
+ if newWork {
+ // There may be new timer or GC work; restart to
+ // discover.
+ goto top
+ }
+
+ now = tnow
+ if w != 0 && (pollUntil == 0 || w < pollUntil) {
+ // Earlier timer to wait for.
+ pollUntil = w
+ }
+ }
+
+ // We have nothing to do.
+ //
+ // If we're in the GC mark phase, can safely scan and blacken objects,
+ // and have work to do, run idle-time marking rather than give up the P.
+ if gcBlackenEnabled != 0 && gcMarkWorkAvailable(pp) && gcController.addIdleMarkWorker() {
+ node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
+ if node != nil {
+ pp.gcMarkWorkerMode = gcMarkWorkerIdleMode
+ gp := node.gp.ptr()
+ casgstatus(gp, _Gwaiting, _Grunnable)
+ if traceEnabled() {
+ traceGoUnpark(gp, 0)
+ }
+ return gp, false, false
+ }
+ gcController.removeIdleMarkWorker()
+ }
+
+ // wasm only:
+ // If a callback returned and no other goroutine is awake,
+ // then wake event handler goroutine which pauses execution
+ // until a callback was triggered.
+ gp, otherReady := beforeIdle(now, pollUntil)
+ if gp != nil {
+ casgstatus(gp, _Gwaiting, _Grunnable)
+ if traceEnabled() {
+ traceGoUnpark(gp, 0)
+ }
+ return gp, false, false
+ }
+ if otherReady {
+ goto top
+ }
+
+ // Before we drop our P, make a snapshot of the allp slice,
+ // which can change underfoot once we no longer block
+ // safe-points. We don't need to snapshot the contents because
+ // everything up to cap(allp) is immutable.
+ allpSnapshot := allp
+ // Also snapshot masks. Value changes are OK, but we can't allow
+ // len to change out from under us.
+ idlepMaskSnapshot := idlepMask
+ timerpMaskSnapshot := timerpMask
+
+ // return P and block
+ lock(&sched.lock)
+ if sched.gcwaiting.Load() || pp.runSafePointFn != 0 {
+ unlock(&sched.lock)
+ goto top
+ }
+ if sched.runqsize != 0 {
+ gp := globrunqget(pp, 0)
+ unlock(&sched.lock)
+ return gp, false, false
+ }
+ if !mp.spinning && sched.needspinning.Load() == 1 {
+ // See "Delicate dance" comment below.
+ mp.becomeSpinning()
+ unlock(&sched.lock)
+ goto top
+ }
+ if releasep() != pp {
+ throw("findrunnable: wrong p")
+ }
+ now = pidleput(pp, now)
+ unlock(&sched.lock)
+
+ // Delicate dance: thread transitions from spinning to non-spinning
+ // state, potentially concurrently with submission of new work. We must
+ // drop nmspinning first and then check all sources again (with
+ // #StoreLoad memory barrier in between). If we do it the other way
+ // around, another thread can submit work after we've checked all
+ // sources but before we drop nmspinning; as a result nobody will
+ // unpark a thread to run the work.
+ //
+ // This applies to the following sources of work:
+ //
+ // * Goroutines added to a per-P run queue.
+ // * New/modified-earlier timers on a per-P timer heap.
+ // * Idle-priority GC work (barring golang.org/issue/19112).
+ //
+ // If we discover new work below, we need to restore m.spinning as a
+ // signal for resetspinning to unpark a new worker thread (because
+ // there can be more than one starving goroutine).
+ //
+ // However, if after discovering new work we also observe no idle Ps
+ // (either here or in resetspinning), we have a problem. We may be
+ // racing with a non-spinning M in the block above, having found no
+ // work and preparing to release its P and park. Allowing that P to go
+ // idle will result in loss of work conservation (idle P while there is
+ // runnable work). This could result in complete deadlock in the
+ // unlikely event that we discover new work (from netpoll) right as we
+ // are racing with _all_ other Ps going idle.
+ //
+ // We use sched.needspinning to synchronize with non-spinning Ms going
+ // idle. If needspinning is set when they are about to drop their P,
+ // they abort the drop and instead become a new spinning M on our
+ // behalf. If we are not racing and the system is truly fully loaded
+ // then no spinning threads are required, and the next thread to
+ // naturally become spinning will clear the flag.
+ //
+ // Also see "Worker thread parking/unparking" comment at the top of the
+ // file.
+ wasSpinning := mp.spinning
+ if mp.spinning {
+ mp.spinning = false
+ if sched.nmspinning.Add(-1) < 0 {
+ throw("findrunnable: negative nmspinning")
+ }
+
+ // Note the for correctness, only the last M transitioning from
+ // spinning to non-spinning must perform these rechecks to
+ // ensure no missed work. However, the runtime has some cases
+ // of transient increments of nmspinning that are decremented
+ // without going through this path, so we must be conservative
+ // and perform the check on all spinning Ms.
+ //
+ // See https://go.dev/issue/43997.
+
+ // Check all runqueues once again.
+ pp := checkRunqsNoP(allpSnapshot, idlepMaskSnapshot)
+ if pp != nil {
+ acquirep(pp)
+ mp.becomeSpinning()
+ goto top
+ }
+
+ // Check for idle-priority GC work again.
+ pp, gp := checkIdleGCNoP()
+ if pp != nil {
+ acquirep(pp)
+ mp.becomeSpinning()
+
+ // Run the idle worker.
+ pp.gcMarkWorkerMode = gcMarkWorkerIdleMode
+ casgstatus(gp, _Gwaiting, _Grunnable)
+ if traceEnabled() {
+ traceGoUnpark(gp, 0)
+ }
+ return gp, false, false
+ }
+
+ // Finally, check for timer creation or expiry concurrently with
+ // transitioning from spinning to non-spinning.
+ //
+ // Note that we cannot use checkTimers here because it calls
+ // adjusttimers which may need to allocate memory, and that isn't
+ // allowed when we don't have an active P.
+ pollUntil = checkTimersNoP(allpSnapshot, timerpMaskSnapshot, pollUntil)
+ }
+
+ // Poll network until next timer.
+ if netpollinited() && (netpollWaiters.Load() > 0 || pollUntil != 0) && sched.lastpoll.Swap(0) != 0 {
+ sched.pollUntil.Store(pollUntil)
+ if mp.p != 0 {
+ throw("findrunnable: netpoll with p")
+ }
+ if mp.spinning {
+ throw("findrunnable: netpoll with spinning")
+ }
+ delay := int64(-1)
+ if pollUntil != 0 {
+ if now == 0 {
+ now = nanotime()
+ }
+ delay = pollUntil - now
+ if delay < 0 {
+ delay = 0
+ }
+ }
+ if faketime != 0 {
+ // When using fake time, just poll.
+ delay = 0
+ }
+ list := netpoll(delay) // block until new work is available
+ // Refresh now again, after potentially blocking.
+ now = nanotime()
+ sched.pollUntil.Store(0)
+ sched.lastpoll.Store(now)
+ if faketime != 0 && list.empty() {
+ // Using fake time and nothing is ready; stop M.
+ // When all M's stop, checkdead will call timejump.
+ stopm()
+ goto top
+ }
+ lock(&sched.lock)
+ pp, _ := pidleget(now)
+ unlock(&sched.lock)
+ if pp == nil {
+ injectglist(&list)
+ } else {
+ acquirep(pp)
+ if !list.empty() {
+ gp := list.pop()
+ injectglist(&list)
+ casgstatus(gp, _Gwaiting, _Grunnable)
+ if traceEnabled() {
+ traceGoUnpark(gp, 0)
+ }
+ return gp, false, false
+ }
+ if wasSpinning {
+ mp.becomeSpinning()
+ }
+ goto top
+ }
+ } else if pollUntil != 0 && netpollinited() {
+ pollerPollUntil := sched.pollUntil.Load()
+ if pollerPollUntil == 0 || pollerPollUntil > pollUntil {
+ netpollBreak()
+ }
+ }
+ stopm()
+ goto top
+}
+
+// pollWork reports whether there is non-background work this P could
+// be doing. This is a fairly lightweight check to be used for
+// background work loops, like idle GC. It checks a subset of the
+// conditions checked by the actual scheduler.
+func pollWork() bool {
+ if sched.runqsize != 0 {
+ return true
+ }
+ p := getg().m.p.ptr()
+ if !runqempty(p) {
+ return true
+ }
+ if netpollinited() && netpollWaiters.Load() > 0 && sched.lastpoll.Load() != 0 {
+ if list := netpoll(0); !list.empty() {
+ injectglist(&list)
+ return true
+ }
+ }
+ return false
+}
+
+// stealWork attempts to steal a runnable goroutine or timer from any P.
+//
+// If newWork is true, new work may have been readied.
+//
+// If now is not 0 it is the current time. stealWork returns the passed time or
+// the current time if now was passed as 0.
+func stealWork(now int64) (gp *g, inheritTime bool, rnow, pollUntil int64, newWork bool) {
+ pp := getg().m.p.ptr()
+
+ ranTimer := false
+
+ const stealTries = 4
+ for i := 0; i < stealTries; i++ {
+ stealTimersOrRunNextG := i == stealTries-1
+
+ for enum := stealOrder.start(fastrand()); !enum.done(); enum.next() {
+ if sched.gcwaiting.Load() {
+ // GC work may be available.
+ return nil, false, now, pollUntil, true
+ }
+ p2 := allp[enum.position()]
+ if pp == p2 {
+ continue
+ }
+
+ // Steal timers from p2. This call to checkTimers is the only place
+ // where we might hold a lock on a different P's timers. We do this
+ // once on the last pass before checking runnext because stealing
+ // from the other P's runnext should be the last resort, so if there
+ // are timers to steal do that first.
+ //
+ // We only check timers on one of the stealing iterations because
+ // the time stored in now doesn't change in this loop and checking
+ // the timers for each P more than once with the same value of now
+ // is probably a waste of time.
+ //
+ // timerpMask tells us whether the P may have timers at all. If it
+ // can't, no need to check at all.
+ if stealTimersOrRunNextG && timerpMask.read(enum.position()) {
+ tnow, w, ran := checkTimers(p2, now)
+ now = tnow
+ if w != 0 && (pollUntil == 0 || w < pollUntil) {
+ pollUntil = w
+ }
+ if ran {
+ // Running the timers may have
+ // made an arbitrary number of G's
+ // ready and added them to this P's
+ // local run queue. That invalidates
+ // the assumption of runqsteal
+ // that it always has room to add
+ // stolen G's. So check now if there
+ // is a local G to run.
+ if gp, inheritTime := runqget(pp); gp != nil {
+ return gp, inheritTime, now, pollUntil, ranTimer
+ }
+ ranTimer = true
+ }
+ }
+
+ // Don't bother to attempt to steal if p2 is idle.
+ if !idlepMask.read(enum.position()) {
+ if gp := runqsteal(pp, p2, stealTimersOrRunNextG); gp != nil {
+ return gp, false, now, pollUntil, ranTimer
+ }
+ }
+ }
+ }
+
+ // No goroutines found to steal. Regardless, running a timer may have
+ // made some goroutine ready that we missed. Indicate the next timer to
+ // wait for.
+ return nil, false, now, pollUntil, ranTimer
+}
+
+// Check all Ps for a runnable G to steal.
+//
+// On entry we have no P. If a G is available to steal and a P is available,
+// the P is returned which the caller should acquire and attempt to steal the
+// work to.
+func checkRunqsNoP(allpSnapshot []*p, idlepMaskSnapshot pMask) *p {
+ for id, p2 := range allpSnapshot {
+ if !idlepMaskSnapshot.read(uint32(id)) && !runqempty(p2) {
+ lock(&sched.lock)
+ pp, _ := pidlegetSpinning(0)
+ if pp == nil {
+ // Can't get a P, don't bother checking remaining Ps.
+ unlock(&sched.lock)
+ return nil
+ }
+ unlock(&sched.lock)
+ return pp
+ }
+ }
+
+ // No work available.
+ return nil
+}
+
+// Check all Ps for a timer expiring sooner than pollUntil.
+//
+// Returns updated pollUntil value.
+func checkTimersNoP(allpSnapshot []*p, timerpMaskSnapshot pMask, pollUntil int64) int64 {
+ for id, p2 := range allpSnapshot {
+ if timerpMaskSnapshot.read(uint32(id)) {
+ w := nobarrierWakeTime(p2)
+ if w != 0 && (pollUntil == 0 || w < pollUntil) {
+ pollUntil = w
+ }
+ }
+ }
+
+ return pollUntil
+}
+
+// Check for idle-priority GC, without a P on entry.
+//
+// If some GC work, a P, and a worker G are all available, the P and G will be
+// returned. The returned P has not been wired yet.
+func checkIdleGCNoP() (*p, *g) {
+ // N.B. Since we have no P, gcBlackenEnabled may change at any time; we
+ // must check again after acquiring a P. As an optimization, we also check
+ // if an idle mark worker is needed at all. This is OK here, because if we
+ // observe that one isn't needed, at least one is currently running. Even if
+ // it stops running, its own journey into the scheduler should schedule it
+ // again, if need be (at which point, this check will pass, if relevant).
+ if atomic.Load(&gcBlackenEnabled) == 0 || !gcController.needIdleMarkWorker() {
+ return nil, nil
+ }
+ if !gcMarkWorkAvailable(nil) {
+ return nil, nil
+ }
+
+ // Work is available; we can start an idle GC worker only if there is
+ // an available P and available worker G.
+ //
+ // We can attempt to acquire these in either order, though both have
+ // synchronization concerns (see below). Workers are almost always
+ // available (see comment in findRunnableGCWorker for the one case
+ // there may be none). Since we're slightly less likely to find a P,
+ // check for that first.
+ //
+ // Synchronization: note that we must hold sched.lock until we are
+ // committed to keeping it. Otherwise we cannot put the unnecessary P
+ // back in sched.pidle without performing the full set of idle
+ // transition checks.
+ //
+ // If we were to check gcBgMarkWorkerPool first, we must somehow handle
+ // the assumption in gcControllerState.findRunnableGCWorker that an
+ // empty gcBgMarkWorkerPool is only possible if gcMarkDone is running.
+ lock(&sched.lock)
+ pp, now := pidlegetSpinning(0)
+ if pp == nil {
+ unlock(&sched.lock)
+ return nil, nil
+ }
+
+ // Now that we own a P, gcBlackenEnabled can't change (as it requires STW).
+ if gcBlackenEnabled == 0 || !gcController.addIdleMarkWorker() {
+ pidleput(pp, now)
+ unlock(&sched.lock)
+ return nil, nil
+ }
+
+ node := (*gcBgMarkWorkerNode)(gcBgMarkWorkerPool.pop())
+ if node == nil {
+ pidleput(pp, now)
+ unlock(&sched.lock)
+ gcController.removeIdleMarkWorker()
+ return nil, nil
+ }
+
+ unlock(&sched.lock)
+
+ return pp, node.gp.ptr()
+}
+
+// wakeNetPoller wakes up the thread sleeping in the network poller if it isn't
+// going to wake up before the when argument; or it wakes an idle P to service
+// timers and the network poller if there isn't one already.
+func wakeNetPoller(when int64) {
+ if sched.lastpoll.Load() == 0 {
+ // In findrunnable we ensure that when polling the pollUntil
+ // field is either zero or the time to which the current
+ // poll is expected to run. This can have a spurious wakeup
+ // but should never miss a wakeup.
+ pollerPollUntil := sched.pollUntil.Load()
+ if pollerPollUntil == 0 || pollerPollUntil > when {
+ netpollBreak()
+ }
+ } else {
+ // There are no threads in the network poller, try to get
+ // one there so it can handle new timers.
+ if GOOS != "plan9" { // Temporary workaround - see issue #42303.
+ wakep()
+ }
+ }
+}
+
+func resetspinning() {
+ gp := getg()
+ if !gp.m.spinning {
+ throw("resetspinning: not a spinning m")
+ }
+ gp.m.spinning = false
+ nmspinning := sched.nmspinning.Add(-1)
+ if nmspinning < 0 {
+ throw("findrunnable: negative nmspinning")
+ }
+ // M wakeup policy is deliberately somewhat conservative, so check if we
+ // need to wakeup another P here. See "Worker thread parking/unparking"
+ // comment at the top of the file for details.
+ wakep()
+}
+
+// injectglist adds each runnable G on the list to some run queue,
+// and clears glist. If there is no current P, they are added to the
+// global queue, and up to npidle M's are started to run them.
+// Otherwise, for each idle P, this adds a G to the global queue
+// and starts an M. Any remaining G's are added to the current P's
+// local run queue.
+// This may temporarily acquire sched.lock.
+// Can run concurrently with GC.
+func injectglist(glist *gList) {
+ if glist.empty() {
+ return
+ }
+ if traceEnabled() {
+ for gp := glist.head.ptr(); gp != nil; gp = gp.schedlink.ptr() {
+ traceGoUnpark(gp, 0)
+ }
+ }
+
+ // Mark all the goroutines as runnable before we put them
+ // on the run queues.
+ head := glist.head.ptr()
+ var tail *g
+ qsize := 0
+ for gp := head; gp != nil; gp = gp.schedlink.ptr() {
+ tail = gp
+ qsize++
+ casgstatus(gp, _Gwaiting, _Grunnable)
+ }
+
+ // Turn the gList into a gQueue.
+ var q gQueue
+ q.head.set(head)
+ q.tail.set(tail)
+ *glist = gList{}
+
+ startIdle := func(n int) {
+ for i := 0; i < n; i++ {
+ mp := acquirem() // See comment in startm.
+ lock(&sched.lock)
+
+ pp, _ := pidlegetSpinning(0)
+ if pp == nil {
+ unlock(&sched.lock)
+ releasem(mp)
+ break
+ }
+
+ startm(pp, false, true)
+ unlock(&sched.lock)
+ releasem(mp)
+ }
+ }
+
+ pp := getg().m.p.ptr()
+ if pp == nil {
+ lock(&sched.lock)
+ globrunqputbatch(&q, int32(qsize))
+ unlock(&sched.lock)
+ startIdle(qsize)
+ return
+ }
+
+ npidle := int(sched.npidle.Load())
+ var globq gQueue
+ var n int
+ for n = 0; n < npidle && !q.empty(); n++ {
+ g := q.pop()
+ globq.pushBack(g)
+ }
+ if n > 0 {
+ lock(&sched.lock)
+ globrunqputbatch(&globq, int32(n))
+ unlock(&sched.lock)
+ startIdle(n)
+ qsize -= n
+ }
+
+ if !q.empty() {
+ runqputbatch(pp, &q, qsize)
+ }
+}
+
+// One round of scheduler: find a runnable goroutine and execute it.
+// Never returns.
+func schedule() {
+ mp := getg().m
+
+ if mp.locks != 0 {
+ throw("schedule: holding locks")
+ }
+
+ if mp.lockedg != 0 {
+ stoplockedm()
+ execute(mp.lockedg.ptr(), false) // Never returns.
+ }
+
+ // We should not schedule away from a g that is executing a cgo call,
+ // since the cgo call is using the m's g0 stack.
+ if mp.incgo {
+ throw("schedule: in cgo")
+ }
+
+top:
+ pp := mp.p.ptr()
+ pp.preempt = false
+
+ // Safety check: if we are spinning, the run queue should be empty.
+ // Check this before calling checkTimers, as that might call
+ // goready to put a ready goroutine on the local run queue.
+ if mp.spinning && (pp.runnext != 0 || pp.runqhead != pp.runqtail) {
+ throw("schedule: spinning with local work")
+ }
+
+ gp, inheritTime, tryWakeP := findRunnable() // blocks until work is available
+
+ if debug.dontfreezetheworld > 0 && freezing.Load() {
+ // See comment in freezetheworld. We don't want to perturb
+ // scheduler state, so we didn't gcstopm in findRunnable, but
+ // also don't want to allow new goroutines to run.
+ //
+ // Deadlock here rather than in the findRunnable loop so if
+ // findRunnable is stuck in a loop we don't perturb that
+ // either.
+ lock(&deadlock)
+ lock(&deadlock)
+ }
+
+ // This thread is going to run a goroutine and is not spinning anymore,
+ // so if it was marked as spinning we need to reset it now and potentially
+ // start a new spinning M.
+ if mp.spinning {
+ resetspinning()
+ }
+
+ if sched.disable.user && !schedEnabled(gp) {
+ // Scheduling of this goroutine is disabled. Put it on
+ // the list of pending runnable goroutines for when we
+ // re-enable user scheduling and look again.
+ lock(&sched.lock)
+ if schedEnabled(gp) {
+ // Something re-enabled scheduling while we
+ // were acquiring the lock.
+ unlock(&sched.lock)
+ } else {
+ sched.disable.runnable.pushBack(gp)
+ sched.disable.n++
+ unlock(&sched.lock)
+ goto top
+ }
+ }
+
+ // If about to schedule a not-normal goroutine (a GCworker or tracereader),
+ // wake a P if there is one.
+ if tryWakeP {
+ wakep()
+ }
+ if gp.lockedm != 0 {
+ // Hands off own p to the locked m,
+ // then blocks waiting for a new p.
+ startlockedm(gp)
+ goto top
+ }
+
+ execute(gp, inheritTime)
+}
+
+// dropg removes the association between m and the current goroutine m->curg (gp for short).
+// Typically a caller sets gp's status away from Grunning and then
+// immediately calls dropg to finish the job. The caller is also responsible
+// for arranging that gp will be restarted using ready at an
+// appropriate time. After calling dropg and arranging for gp to be
+// readied later, the caller can do other work but eventually should
+// call schedule to restart the scheduling of goroutines on this m.
+func dropg() {
+ gp := getg()
+
+ setMNoWB(&gp.m.curg.m, nil)
+ setGNoWB(&gp.m.curg, nil)
+}
+
+// checkTimers runs any timers for the P that are ready.
+// If now is not 0 it is the current time.
+// It returns the passed time or the current time if now was passed as 0.
+// and the time when the next timer should run or 0 if there is no next timer,
+// and reports whether it ran any timers.
+// If the time when the next timer should run is not 0,
+// it is always larger than the returned time.
+// We pass now in and out to avoid extra calls of nanotime.
+//
+//go:yeswritebarrierrec
+func checkTimers(pp *p, now int64) (rnow, pollUntil int64, ran bool) {
+ // If it's not yet time for the first timer, or the first adjusted
+ // timer, then there is nothing to do.
+ next := pp.timer0When.Load()
+ nextAdj := pp.timerModifiedEarliest.Load()
+ if next == 0 || (nextAdj != 0 && nextAdj < next) {
+ next = nextAdj
+ }
+
+ if next == 0 {
+ // No timers to run or adjust.
+ return now, 0, false
+ }
+
+ if now == 0 {
+ now = nanotime()
+ }
+ if now < next {
+ // Next timer is not ready to run, but keep going
+ // if we would clear deleted timers.
+ // This corresponds to the condition below where
+ // we decide whether to call clearDeletedTimers.
+ if pp != getg().m.p.ptr() || int(pp.deletedTimers.Load()) <= int(pp.numTimers.Load()/4) {
+ return now, next, false
+ }
+ }
+
+ lock(&pp.timersLock)
+
+ if len(pp.timers) > 0 {
+ adjusttimers(pp, now)
+ for len(pp.timers) > 0 {
+ // Note that runtimer may temporarily unlock
+ // pp.timersLock.
+ if tw := runtimer(pp, now); tw != 0 {
+ if tw > 0 {
+ pollUntil = tw
+ }
+ break
+ }
+ ran = true
+ }
+ }
+
+ // If this is the local P, and there are a lot of deleted timers,
+ // clear them out. We only do this for the local P to reduce
+ // lock contention on timersLock.
+ if pp == getg().m.p.ptr() && int(pp.deletedTimers.Load()) > len(pp.timers)/4 {
+ clearDeletedTimers(pp)
+ }
+
+ unlock(&pp.timersLock)
+
+ return now, pollUntil, ran
+}
+
+func parkunlock_c(gp *g, lock unsafe.Pointer) bool {
+ unlock((*mutex)(lock))
+ return true
+}
+
+// park continuation on g0.
+func park_m(gp *g) {
+ mp := getg().m
+
+ if traceEnabled() {
+ traceGoPark(mp.waitTraceBlockReason, mp.waitTraceSkip)
+ }
+
+ // N.B. Not using casGToWaiting here because the waitreason is
+ // set by park_m's caller.
+ casgstatus(gp, _Grunning, _Gwaiting)
+ dropg()
+
+ if fn := mp.waitunlockf; fn != nil {
+ ok := fn(gp, mp.waitlock)
+ mp.waitunlockf = nil
+ mp.waitlock = nil
+ if !ok {
+ if traceEnabled() {
+ traceGoUnpark(gp, 2)
+ }
+ casgstatus(gp, _Gwaiting, _Grunnable)
+ execute(gp, true) // Schedule it back, never returns.
+ }
+ }
+ schedule()
+}
+
+func goschedImpl(gp *g) {
+ status := readgstatus(gp)
+ if status&^_Gscan != _Grunning {
+ dumpgstatus(gp)
+ throw("bad g status")
+ }
+ casgstatus(gp, _Grunning, _Grunnable)
+ dropg()
+ lock(&sched.lock)
+ globrunqput(gp)
+ unlock(&sched.lock)
+
+ schedule()
+}
+
+// Gosched continuation on g0.
+func gosched_m(gp *g) {
+ if traceEnabled() {
+ traceGoSched()
+ }
+ goschedImpl(gp)
+}
+
+// goschedguarded is a forbidden-states-avoided version of gosched_m.
+func goschedguarded_m(gp *g) {
+
+ if !canPreemptM(gp.m) {
+ gogo(&gp.sched) // never return
+ }
+
+ if traceEnabled() {
+ traceGoSched()
+ }
+ goschedImpl(gp)
+}
+
+func gopreempt_m(gp *g) {
+ if traceEnabled() {
+ traceGoPreempt()
+ }
+ goschedImpl(gp)
+}
+
+// preemptPark parks gp and puts it in _Gpreempted.
+//
+//go:systemstack
+func preemptPark(gp *g) {
+ if traceEnabled() {
+ traceGoPark(traceBlockPreempted, 0)
+ }
+ status := readgstatus(gp)
+ if status&^_Gscan != _Grunning {
+ dumpgstatus(gp)
+ throw("bad g status")
+ }
+
+ if gp.asyncSafePoint {
+ // Double-check that async preemption does not
+ // happen in SPWRITE assembly functions.
+ // isAsyncSafePoint must exclude this case.
+ f := findfunc(gp.sched.pc)
+ if !f.valid() {
+ throw("preempt at unknown pc")
+ }
+ if f.flag&abi.FuncFlagSPWrite != 0 {
+ println("runtime: unexpected SPWRITE function", funcname(f), "in async preempt")
+ throw("preempt SPWRITE")
+ }
+ }
+
+ // Transition from _Grunning to _Gscan|_Gpreempted. We can't
+ // be in _Grunning when we dropg because then we'd be running
+ // without an M, but the moment we're in _Gpreempted,
+ // something could claim this G before we've fully cleaned it
+ // up. Hence, we set the scan bit to lock down further
+ // transitions until we can dropg.
+ casGToPreemptScan(gp, _Grunning, _Gscan|_Gpreempted)
+ dropg()
+ casfrom_Gscanstatus(gp, _Gscan|_Gpreempted, _Gpreempted)
+ schedule()
+}
+
+// goyield is like Gosched, but it:
+// - emits a GoPreempt trace event instead of a GoSched trace event
+// - puts the current G on the runq of the current P instead of the globrunq
+func goyield() {
+ checkTimeouts()
+ mcall(goyield_m)
+}
+
+func goyield_m(gp *g) {
+ if traceEnabled() {
+ traceGoPreempt()
+ }
+ pp := gp.m.p.ptr()
+ casgstatus(gp, _Grunning, _Grunnable)
+ dropg()
+ runqput(pp, gp, false)
+ schedule()
+}
+
+// Finishes execution of the current goroutine.
+func goexit1() {
+ if raceenabled {
+ racegoend()
+ }
+ if traceEnabled() {
+ traceGoEnd()
+ }
+ mcall(goexit0)
+}
+
+// goexit continuation on g0.
+func goexit0(gp *g) {
+ mp := getg().m
+ pp := mp.p.ptr()
+
+ casgstatus(gp, _Grunning, _Gdead)
+ gcController.addScannableStack(pp, -int64(gp.stack.hi-gp.stack.lo))
+ if isSystemGoroutine(gp, false) {
+ sched.ngsys.Add(-1)
+ }
+ gp.m = nil
+ locked := gp.lockedm != 0
+ gp.lockedm = 0
+ mp.lockedg = 0
+ gp.preemptStop = false
+ gp.paniconfault = false
+ gp._defer = nil // should be true already but just in case.
+ gp._panic = nil // non-nil for Goexit during panic. points at stack-allocated data.
+ gp.writebuf = nil
+ gp.waitreason = waitReasonZero
+ gp.param = nil
+ gp.labels = nil
+ gp.timer = nil
+
+ if gcBlackenEnabled != 0 && gp.gcAssistBytes > 0 {
+ // Flush assist credit to the global pool. This gives
+ // better information to pacing if the application is
+ // rapidly creating an exiting goroutines.
+ assistWorkPerByte := gcController.assistWorkPerByte.Load()
+ scanCredit := int64(assistWorkPerByte * float64(gp.gcAssistBytes))
+ gcController.bgScanCredit.Add(scanCredit)
+ gp.gcAssistBytes = 0
+ }
+
+ dropg()
+
+ if GOARCH == "wasm" { // no threads yet on wasm
+ gfput(pp, gp)
+ schedule() // never returns
+ }
+
+ if mp.lockedInt != 0 {
+ print("invalid m->lockedInt = ", mp.lockedInt, "\n")
+ throw("internal lockOSThread error")
+ }
+ gfput(pp, gp)
+ if locked {
+ // The goroutine may have locked this thread because
+ // it put it in an unusual kernel state. Kill it
+ // rather than returning it to the thread pool.
+
+ // Return to mstart, which will release the P and exit
+ // the thread.
+ if GOOS != "plan9" { // See golang.org/issue/22227.
+ gogo(&mp.g0.sched)
+ } else {
+ // Clear lockedExt on plan9 since we may end up re-using
+ // this thread.
+ mp.lockedExt = 0
+ }
+ }
+ schedule()
+}
+
+// save updates getg().sched to refer to pc and sp so that a following
+// gogo will restore pc and sp.
+//
+// save must not have write barriers because invoking a write barrier
+// can clobber getg().sched.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func save(pc, sp uintptr) {
+ gp := getg()
+
+ if gp == gp.m.g0 || gp == gp.m.gsignal {
+ // m.g0.sched is special and must describe the context
+ // for exiting the thread. mstart1 writes to it directly.
+ // m.gsignal.sched should not be used at all.
+ // This check makes sure save calls do not accidentally
+ // run in contexts where they'd write to system g's.
+ throw("save on system g not allowed")
+ }
+
+ gp.sched.pc = pc
+ gp.sched.sp = sp
+ gp.sched.lr = 0
+ gp.sched.ret = 0
+ // We need to ensure ctxt is zero, but can't have a write
+ // barrier here. However, it should always already be zero.
+ // Assert that.
+ if gp.sched.ctxt != nil {
+ badctxt()
+ }
+}
+
+// The goroutine g is about to enter a system call.
+// Record that it's not using the cpu anymore.
+// This is called only from the go syscall library and cgocall,
+// not from the low-level system calls used by the runtime.
+//
+// Entersyscall cannot split the stack: the save must
+// make g->sched refer to the caller's stack segment, because
+// entersyscall is going to return immediately after.
+//
+// Nothing entersyscall calls can split the stack either.
+// We cannot safely move the stack during an active call to syscall,
+// because we do not know which of the uintptr arguments are
+// really pointers (back into the stack).
+// In practice, this means that we make the fast path run through
+// entersyscall doing no-split things, and the slow path has to use systemstack
+// to run bigger things on the system stack.
+//
+// reentersyscall is the entry point used by cgo callbacks, where explicitly
+// saved SP and PC are restored. This is needed when exitsyscall will be called
+// from a function further up in the call stack than the parent, as g->syscallsp
+// must always point to a valid stack frame. entersyscall below is the normal
+// entry point for syscalls, which obtains the SP and PC from the caller.
+//
+// Syscall tracing:
+// At the start of a syscall we emit traceGoSysCall to capture the stack trace.
+// If the syscall does not block, that is it, we do not emit any other events.
+// If the syscall blocks (that is, P is retaken), retaker emits traceGoSysBlock;
+// when syscall returns we emit traceGoSysExit and when the goroutine starts running
+// (potentially instantly, if exitsyscallfast returns true) we emit traceGoStart.
+// To ensure that traceGoSysExit is emitted strictly after traceGoSysBlock,
+// we remember current value of syscalltick in m (gp.m.syscalltick = gp.m.p.ptr().syscalltick),
+// whoever emits traceGoSysBlock increments p.syscalltick afterwards;
+// and we wait for the increment before emitting traceGoSysExit.
+// Note that the increment is done even if tracing is not enabled,
+// because tracing can be enabled in the middle of syscall. We don't want the wait to hang.
+//
+//go:nosplit
+func reentersyscall(pc, sp uintptr) {
+ gp := getg()
+
+ // Disable preemption because during this function g is in Gsyscall status,
+ // but can have inconsistent g->sched, do not let GC observe it.
+ gp.m.locks++
+
+ // Entersyscall must not call any function that might split/grow the stack.
+ // (See details in comment above.)
+ // Catch calls that might, by replacing the stack guard with something that
+ // will trip any stack check and leaving a flag to tell newstack to die.
+ gp.stackguard0 = stackPreempt
+ gp.throwsplit = true
+
+ // Leave SP around for GC and traceback.
+ save(pc, sp)
+ gp.syscallsp = sp
+ gp.syscallpc = pc
+ casgstatus(gp, _Grunning, _Gsyscall)
+ if staticLockRanking {
+ // When doing static lock ranking casgstatus can call
+ // systemstack which clobbers g.sched.
+ save(pc, sp)
+ }
+ if gp.syscallsp < gp.stack.lo || gp.stack.hi < gp.syscallsp {
+ systemstack(func() {
+ print("entersyscall inconsistent ", hex(gp.syscallsp), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n")
+ throw("entersyscall")
+ })
+ }
+
+ if traceEnabled() {
+ systemstack(traceGoSysCall)
+ // systemstack itself clobbers g.sched.{pc,sp} and we might
+ // need them later when the G is genuinely blocked in a
+ // syscall
+ save(pc, sp)
+ }
+
+ if sched.sysmonwait.Load() {
+ systemstack(entersyscall_sysmon)
+ save(pc, sp)
+ }
+
+ if gp.m.p.ptr().runSafePointFn != 0 {
+ // runSafePointFn may stack split if run on this stack
+ systemstack(runSafePointFn)
+ save(pc, sp)
+ }
+
+ gp.m.syscalltick = gp.m.p.ptr().syscalltick
+ pp := gp.m.p.ptr()
+ pp.m = 0
+ gp.m.oldp.set(pp)
+ gp.m.p = 0
+ atomic.Store(&pp.status, _Psyscall)
+ if sched.gcwaiting.Load() {
+ systemstack(entersyscall_gcwait)
+ save(pc, sp)
+ }
+
+ gp.m.locks--
+}
+
+// Standard syscall entry used by the go syscall library and normal cgo calls.
+//
+// This is exported via linkname to assembly in the syscall package and x/sys.
+//
+//go:nosplit
+//go:linkname entersyscall
+func entersyscall() {
+ reentersyscall(getcallerpc(), getcallersp())
+}
+
+func entersyscall_sysmon() {
+ lock(&sched.lock)
+ if sched.sysmonwait.Load() {
+ sched.sysmonwait.Store(false)
+ notewakeup(&sched.sysmonnote)
+ }
+ unlock(&sched.lock)
+}
+
+func entersyscall_gcwait() {
+ gp := getg()
+ pp := gp.m.oldp.ptr()
+
+ lock(&sched.lock)
+ if sched.stopwait > 0 && atomic.Cas(&pp.status, _Psyscall, _Pgcstop) {
+ if traceEnabled() {
+ traceGoSysBlock(pp)
+ traceProcStop(pp)
+ }
+ pp.syscalltick++
+ if sched.stopwait--; sched.stopwait == 0 {
+ notewakeup(&sched.stopnote)
+ }
+ }
+ unlock(&sched.lock)
+}
+
+// The same as entersyscall(), but with a hint that the syscall is blocking.
+//
+//go:nosplit
+func entersyscallblock() {
+ gp := getg()
+
+ gp.m.locks++ // see comment in entersyscall
+ gp.throwsplit = true
+ gp.stackguard0 = stackPreempt // see comment in entersyscall
+ gp.m.syscalltick = gp.m.p.ptr().syscalltick
+ gp.m.p.ptr().syscalltick++
+
+ // Leave SP around for GC and traceback.
+ pc := getcallerpc()
+ sp := getcallersp()
+ save(pc, sp)
+ gp.syscallsp = gp.sched.sp
+ gp.syscallpc = gp.sched.pc
+ if gp.syscallsp < gp.stack.lo || gp.stack.hi < gp.syscallsp {
+ sp1 := sp
+ sp2 := gp.sched.sp
+ sp3 := gp.syscallsp
+ systemstack(func() {
+ print("entersyscallblock inconsistent ", hex(sp1), " ", hex(sp2), " ", hex(sp3), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n")
+ throw("entersyscallblock")
+ })
+ }
+ casgstatus(gp, _Grunning, _Gsyscall)
+ if gp.syscallsp < gp.stack.lo || gp.stack.hi < gp.syscallsp {
+ systemstack(func() {
+ print("entersyscallblock inconsistent ", hex(sp), " ", hex(gp.sched.sp), " ", hex(gp.syscallsp), " [", hex(gp.stack.lo), ",", hex(gp.stack.hi), "]\n")
+ throw("entersyscallblock")
+ })
+ }
+
+ systemstack(entersyscallblock_handoff)
+
+ // Resave for traceback during blocked call.
+ save(getcallerpc(), getcallersp())
+
+ gp.m.locks--
+}
+
+func entersyscallblock_handoff() {
+ if traceEnabled() {
+ traceGoSysCall()
+ traceGoSysBlock(getg().m.p.ptr())
+ }
+ handoffp(releasep())
+}
+
+// The goroutine g exited its system call.
+// Arrange for it to run on a cpu again.
+// This is called only from the go syscall library, not
+// from the low-level system calls used by the runtime.
+//
+// Write barriers are not allowed because our P may have been stolen.
+//
+// This is exported via linkname to assembly in the syscall package.
+//
+//go:nosplit
+//go:nowritebarrierrec
+//go:linkname exitsyscall
+func exitsyscall() {
+ gp := getg()
+
+ gp.m.locks++ // see comment in entersyscall
+ if getcallersp() > gp.syscallsp {
+ throw("exitsyscall: syscall frame is no longer valid")
+ }
+
+ gp.waitsince = 0
+ oldp := gp.m.oldp.ptr()
+ gp.m.oldp = 0
+ if exitsyscallfast(oldp) {
+ // When exitsyscallfast returns success, we have a P so can now use
+ // write barriers
+ if goroutineProfile.active {
+ // Make sure that gp has had its stack written out to the goroutine
+ // profile, exactly as it was when the goroutine profiler first
+ // stopped the world.
+ systemstack(func() {
+ tryRecordGoroutineProfileWB(gp)
+ })
+ }
+ if traceEnabled() {
+ if oldp != gp.m.p.ptr() || gp.m.syscalltick != gp.m.p.ptr().syscalltick {
+ systemstack(traceGoStart)
+ }
+ }
+ // There's a cpu for us, so we can run.
+ gp.m.p.ptr().syscalltick++
+ // We need to cas the status and scan before resuming...
+ casgstatus(gp, _Gsyscall, _Grunning)
+
+ // Garbage collector isn't running (since we are),
+ // so okay to clear syscallsp.
+ gp.syscallsp = 0
+ gp.m.locks--
+ if gp.preempt {
+ // restore the preemption request in case we've cleared it in newstack
+ gp.stackguard0 = stackPreempt
+ } else {
+ // otherwise restore the real stackGuard, we've spoiled it in entersyscall/entersyscallblock
+ gp.stackguard0 = gp.stack.lo + stackGuard
+ }
+ gp.throwsplit = false
+
+ if sched.disable.user && !schedEnabled(gp) {
+ // Scheduling of this goroutine is disabled.
+ Gosched()
+ }
+
+ return
+ }
+
+ if traceEnabled() {
+ // Wait till traceGoSysBlock event is emitted.
+ // This ensures consistency of the trace (the goroutine is started after it is blocked).
+ for oldp != nil && oldp.syscalltick == gp.m.syscalltick {
+ osyield()
+ }
+ // We can't trace syscall exit right now because we don't have a P.
+ // Tracing code can invoke write barriers that cannot run without a P.
+ // So instead we remember the syscall exit time and emit the event
+ // in execute when we have a P.
+ gp.trace.sysExitTime = traceClockNow()
+ }
+
+ gp.m.locks--
+
+ // Call the scheduler.
+ mcall(exitsyscall0)
+
+ // Scheduler returned, so we're allowed to run now.
+ // Delete the syscallsp information that we left for
+ // the garbage collector during the system call.
+ // Must wait until now because until gosched returns
+ // we don't know for sure that the garbage collector
+ // is not running.
+ gp.syscallsp = 0
+ gp.m.p.ptr().syscalltick++
+ gp.throwsplit = false
+}
+
+//go:nosplit
+func exitsyscallfast(oldp *p) bool {
+ gp := getg()
+
+ // Freezetheworld sets stopwait but does not retake P's.
+ if sched.stopwait == freezeStopWait {
+ return false
+ }
+
+ // Try to re-acquire the last P.
+ if oldp != nil && oldp.status == _Psyscall && atomic.Cas(&oldp.status, _Psyscall, _Pidle) {
+ // There's a cpu for us, so we can run.
+ wirep(oldp)
+ exitsyscallfast_reacquired()
+ return true
+ }
+
+ // Try to get any other idle P.
+ if sched.pidle != 0 {
+ var ok bool
+ systemstack(func() {
+ ok = exitsyscallfast_pidle()
+ if ok && traceEnabled() {
+ if oldp != nil {
+ // Wait till traceGoSysBlock event is emitted.
+ // This ensures consistency of the trace (the goroutine is started after it is blocked).
+ for oldp.syscalltick == gp.m.syscalltick {
+ osyield()
+ }
+ }
+ traceGoSysExit()
+ }
+ })
+ if ok {
+ return true
+ }
+ }
+ return false
+}
+
+// exitsyscallfast_reacquired is the exitsyscall path on which this G
+// has successfully reacquired the P it was running on before the
+// syscall.
+//
+//go:nosplit
+func exitsyscallfast_reacquired() {
+ gp := getg()
+ if gp.m.syscalltick != gp.m.p.ptr().syscalltick {
+ if traceEnabled() {
+ // The p was retaken and then enter into syscall again (since gp.m.syscalltick has changed).
+ // traceGoSysBlock for this syscall was already emitted,
+ // but here we effectively retake the p from the new syscall running on the same p.
+ systemstack(func() {
+ // Denote blocking of the new syscall.
+ traceGoSysBlock(gp.m.p.ptr())
+ // Denote completion of the current syscall.
+ traceGoSysExit()
+ })
+ }
+ gp.m.p.ptr().syscalltick++
+ }
+}
+
+func exitsyscallfast_pidle() bool {
+ lock(&sched.lock)
+ pp, _ := pidleget(0)
+ if pp != nil && sched.sysmonwait.Load() {
+ sched.sysmonwait.Store(false)
+ notewakeup(&sched.sysmonnote)
+ }
+ unlock(&sched.lock)
+ if pp != nil {
+ acquirep(pp)
+ return true
+ }
+ return false
+}
+
+// exitsyscall slow path on g0.
+// Failed to acquire P, enqueue gp as runnable.
+//
+// Called via mcall, so gp is the calling g from this M.
+//
+//go:nowritebarrierrec
+func exitsyscall0(gp *g) {
+ casgstatus(gp, _Gsyscall, _Grunnable)
+ dropg()
+ lock(&sched.lock)
+ var pp *p
+ if schedEnabled(gp) {
+ pp, _ = pidleget(0)
+ }
+ var locked bool
+ if pp == nil {
+ globrunqput(gp)
+
+ // Below, we stoplockedm if gp is locked. globrunqput releases
+ // ownership of gp, so we must check if gp is locked prior to
+ // committing the release by unlocking sched.lock, otherwise we
+ // could race with another M transitioning gp from unlocked to
+ // locked.
+ locked = gp.lockedm != 0
+ } else if sched.sysmonwait.Load() {
+ sched.sysmonwait.Store(false)
+ notewakeup(&sched.sysmonnote)
+ }
+ unlock(&sched.lock)
+ if pp != nil {
+ acquirep(pp)
+ execute(gp, false) // Never returns.
+ }
+ if locked {
+ // Wait until another thread schedules gp and so m again.
+ //
+ // N.B. lockedm must be this M, as this g was running on this M
+ // before entersyscall.
+ stoplockedm()
+ execute(gp, false) // Never returns.
+ }
+ stopm()
+ schedule() // Never returns.
+}
+
+// Called from syscall package before fork.
+//
+//go:linkname syscall_runtime_BeforeFork syscall.runtime_BeforeFork
+//go:nosplit
+func syscall_runtime_BeforeFork() {
+ gp := getg().m.curg
+
+ // Block signals during a fork, so that the child does not run
+ // a signal handler before exec if a signal is sent to the process
+ // group. See issue #18600.
+ gp.m.locks++
+ sigsave(&gp.m.sigmask)
+ sigblock(false)
+
+ // This function is called before fork in syscall package.
+ // Code between fork and exec must not allocate memory nor even try to grow stack.
+ // Here we spoil g.stackguard0 to reliably detect any attempts to grow stack.
+ // runtime_AfterFork will undo this in parent process, but not in child.
+ gp.stackguard0 = stackFork
+}
+
+// Called from syscall package after fork in parent.
+//
+//go:linkname syscall_runtime_AfterFork syscall.runtime_AfterFork
+//go:nosplit
+func syscall_runtime_AfterFork() {
+ gp := getg().m.curg
+
+ // See the comments in beforefork.
+ gp.stackguard0 = gp.stack.lo + stackGuard
+
+ msigrestore(gp.m.sigmask)
+
+ gp.m.locks--
+}
+
+// inForkedChild is true while manipulating signals in the child process.
+// This is used to avoid calling libc functions in case we are using vfork.
+var inForkedChild bool
+
+// Called from syscall package after fork in child.
+// It resets non-sigignored signals to the default handler, and
+// restores the signal mask in preparation for the exec.
+//
+// Because this might be called during a vfork, and therefore may be
+// temporarily sharing address space with the parent process, this must
+// not change any global variables or calling into C code that may do so.
+//
+//go:linkname syscall_runtime_AfterForkInChild syscall.runtime_AfterForkInChild
+//go:nosplit
+//go:nowritebarrierrec
+func syscall_runtime_AfterForkInChild() {
+ // It's OK to change the global variable inForkedChild here
+ // because we are going to change it back. There is no race here,
+ // because if we are sharing address space with the parent process,
+ // then the parent process can not be running concurrently.
+ inForkedChild = true
+
+ clearSignalHandlers()
+
+ // When we are the child we are the only thread running,
+ // so we know that nothing else has changed gp.m.sigmask.
+ msigrestore(getg().m.sigmask)
+
+ inForkedChild = false
+}
+
+// pendingPreemptSignals is the number of preemption signals
+// that have been sent but not received. This is only used on Darwin.
+// For #41702.
+var pendingPreemptSignals atomic.Int32
+
+// Called from syscall package before Exec.
+//
+//go:linkname syscall_runtime_BeforeExec syscall.runtime_BeforeExec
+func syscall_runtime_BeforeExec() {
+ // Prevent thread creation during exec.
+ execLock.lock()
+
+ // On Darwin, wait for all pending preemption signals to
+ // be received. See issue #41702.
+ if GOOS == "darwin" || GOOS == "ios" {
+ for pendingPreemptSignals.Load() > 0 {
+ osyield()
+ }
+ }
+}
+
+// Called from syscall package after Exec.
+//
+//go:linkname syscall_runtime_AfterExec syscall.runtime_AfterExec
+func syscall_runtime_AfterExec() {
+ execLock.unlock()
+}
+
+// Allocate a new g, with a stack big enough for stacksize bytes.
+func malg(stacksize int32) *g {
+ newg := new(g)
+ if stacksize >= 0 {
+ stacksize = round2(stackSystem + stacksize)
+ systemstack(func() {
+ newg.stack = stackalloc(uint32(stacksize))
+ })
+ newg.stackguard0 = newg.stack.lo + stackGuard
+ newg.stackguard1 = ^uintptr(0)
+ // Clear the bottom word of the stack. We record g
+ // there on gsignal stack during VDSO on ARM and ARM64.
+ *(*uintptr)(unsafe.Pointer(newg.stack.lo)) = 0
+ }
+ return newg
+}
+
+// Create a new g running fn.
+// Put it on the queue of g's waiting to run.
+// The compiler turns a go statement into a call to this.
+func newproc(fn *funcval) {
+ gp := getg()
+ pc := getcallerpc()
+ systemstack(func() {
+ newg := newproc1(fn, gp, pc)
+
+ pp := getg().m.p.ptr()
+ runqput(pp, newg, true)
+
+ if mainStarted {
+ wakep()
+ }
+ })
+}
+
+// Create a new g in state _Grunnable, starting at fn. callerpc is the
+// address of the go statement that created this. The caller is responsible
+// for adding the new g to the scheduler.
+func newproc1(fn *funcval, callergp *g, callerpc uintptr) *g {
+ if fn == nil {
+ fatal("go of nil func value")
+ }
+
+ mp := acquirem() // disable preemption because we hold M and P in local vars.
+ pp := mp.p.ptr()
+ newg := gfget(pp)
+ if newg == nil {
+ newg = malg(stackMin)
+ casgstatus(newg, _Gidle, _Gdead)
+ allgadd(newg) // publishes with a g->status of Gdead so GC scanner doesn't look at uninitialized stack.
+ }
+ if newg.stack.hi == 0 {
+ throw("newproc1: newg missing stack")
+ }
+
+ if readgstatus(newg) != _Gdead {
+ throw("newproc1: new g is not Gdead")
+ }
+
+ totalSize := uintptr(4*goarch.PtrSize + sys.MinFrameSize) // extra space in case of reads slightly beyond frame
+ totalSize = alignUp(totalSize, sys.StackAlign)
+ sp := newg.stack.hi - totalSize
+ spArg := sp
+ if usesLR {
+ // caller's LR
+ *(*uintptr)(unsafe.Pointer(sp)) = 0
+ prepGoExitFrame(sp)
+ spArg += sys.MinFrameSize
+ }
+
+ memclrNoHeapPointers(unsafe.Pointer(&newg.sched), unsafe.Sizeof(newg.sched))
+ newg.sched.sp = sp
+ newg.stktopsp = sp
+ newg.sched.pc = abi.FuncPCABI0(goexit) + sys.PCQuantum // +PCQuantum so that previous instruction is in same function
+ newg.sched.g = guintptr(unsafe.Pointer(newg))
+ gostartcallfn(&newg.sched, fn)
+ newg.parentGoid = callergp.goid
+ newg.gopc = callerpc
+ newg.ancestors = saveAncestors(callergp)
+ newg.startpc = fn.fn
+ if isSystemGoroutine(newg, false) {
+ sched.ngsys.Add(1)
+ } else {
+ // Only user goroutines inherit pprof labels.
+ if mp.curg != nil {
+ newg.labels = mp.curg.labels
+ }
+ if goroutineProfile.active {
+ // A concurrent goroutine profile is running. It should include
+ // exactly the set of goroutines that were alive when the goroutine
+ // profiler first stopped the world. That does not include newg, so
+ // mark it as not needing a profile before transitioning it from
+ // _Gdead.
+ newg.goroutineProfiled.Store(goroutineProfileSatisfied)
+ }
+ }
+ // Track initial transition?
+ newg.trackingSeq = uint8(fastrand())
+ if newg.trackingSeq%gTrackingPeriod == 0 {
+ newg.tracking = true
+ }
+ casgstatus(newg, _Gdead, _Grunnable)
+ gcController.addScannableStack(pp, int64(newg.stack.hi-newg.stack.lo))
+
+ if pp.goidcache == pp.goidcacheend {
+ // Sched.goidgen is the last allocated id,
+ // this batch must be [sched.goidgen+1, sched.goidgen+GoidCacheBatch].
+ // At startup sched.goidgen=0, so main goroutine receives goid=1.
+ pp.goidcache = sched.goidgen.Add(_GoidCacheBatch)
+ pp.goidcache -= _GoidCacheBatch - 1
+ pp.goidcacheend = pp.goidcache + _GoidCacheBatch
+ }
+ newg.goid = pp.goidcache
+ pp.goidcache++
+ if raceenabled {
+ newg.racectx = racegostart(callerpc)
+ newg.raceignore = 0
+ if newg.labels != nil {
+ // See note in proflabel.go on labelSync's role in synchronizing
+ // with the reads in the signal handler.
+ racereleasemergeg(newg, unsafe.Pointer(&labelSync))
+ }
+ }
+ if traceEnabled() {
+ traceGoCreate(newg, newg.startpc)
+ }
+ releasem(mp)
+
+ return newg
+}
+
+// saveAncestors copies previous ancestors of the given caller g and
+// includes info for the current caller into a new set of tracebacks for
+// a g being created.
+func saveAncestors(callergp *g) *[]ancestorInfo {
+ // Copy all prior info, except for the root goroutine (goid 0).
+ if debug.tracebackancestors <= 0 || callergp.goid == 0 {
+ return nil
+ }
+ var callerAncestors []ancestorInfo
+ if callergp.ancestors != nil {
+ callerAncestors = *callergp.ancestors
+ }
+ n := int32(len(callerAncestors)) + 1
+ if n > debug.tracebackancestors {
+ n = debug.tracebackancestors
+ }
+ ancestors := make([]ancestorInfo, n)
+ copy(ancestors[1:], callerAncestors)
+
+ var pcs [tracebackInnerFrames]uintptr
+ npcs := gcallers(callergp, 0, pcs[:])
+ ipcs := make([]uintptr, npcs)
+ copy(ipcs, pcs[:])
+ ancestors[0] = ancestorInfo{
+ pcs: ipcs,
+ goid: callergp.goid,
+ gopc: callergp.gopc,
+ }
+
+ ancestorsp := new([]ancestorInfo)
+ *ancestorsp = ancestors
+ return ancestorsp
+}
+
+// Put on gfree list.
+// If local list is too long, transfer a batch to the global list.
+func gfput(pp *p, gp *g) {
+ if readgstatus(gp) != _Gdead {
+ throw("gfput: bad status (not Gdead)")
+ }
+
+ stksize := gp.stack.hi - gp.stack.lo
+
+ if stksize != uintptr(startingStackSize) {
+ // non-standard stack size - free it.
+ stackfree(gp.stack)
+ gp.stack.lo = 0
+ gp.stack.hi = 0
+ gp.stackguard0 = 0
+ }
+
+ pp.gFree.push(gp)
+ pp.gFree.n++
+ if pp.gFree.n >= 64 {
+ var (
+ inc int32
+ stackQ gQueue
+ noStackQ gQueue
+ )
+ for pp.gFree.n >= 32 {
+ gp := pp.gFree.pop()
+ pp.gFree.n--
+ if gp.stack.lo == 0 {
+ noStackQ.push(gp)
+ } else {
+ stackQ.push(gp)
+ }
+ inc++
+ }
+ lock(&sched.gFree.lock)
+ sched.gFree.noStack.pushAll(noStackQ)
+ sched.gFree.stack.pushAll(stackQ)
+ sched.gFree.n += inc
+ unlock(&sched.gFree.lock)
+ }
+}
+
+// Get from gfree list.
+// If local list is empty, grab a batch from global list.
+func gfget(pp *p) *g {
+retry:
+ if pp.gFree.empty() && (!sched.gFree.stack.empty() || !sched.gFree.noStack.empty()) {
+ lock(&sched.gFree.lock)
+ // Move a batch of free Gs to the P.
+ for pp.gFree.n < 32 {
+ // Prefer Gs with stacks.
+ gp := sched.gFree.stack.pop()
+ if gp == nil {
+ gp = sched.gFree.noStack.pop()
+ if gp == nil {
+ break
+ }
+ }
+ sched.gFree.n--
+ pp.gFree.push(gp)
+ pp.gFree.n++
+ }
+ unlock(&sched.gFree.lock)
+ goto retry
+ }
+ gp := pp.gFree.pop()
+ if gp == nil {
+ return nil
+ }
+ pp.gFree.n--
+ if gp.stack.lo != 0 && gp.stack.hi-gp.stack.lo != uintptr(startingStackSize) {
+ // Deallocate old stack. We kept it in gfput because it was the
+ // right size when the goroutine was put on the free list, but
+ // the right size has changed since then.
+ systemstack(func() {
+ stackfree(gp.stack)
+ gp.stack.lo = 0
+ gp.stack.hi = 0
+ gp.stackguard0 = 0
+ })
+ }
+ if gp.stack.lo == 0 {
+ // Stack was deallocated in gfput or just above. Allocate a new one.
+ systemstack(func() {
+ gp.stack = stackalloc(startingStackSize)
+ })
+ gp.stackguard0 = gp.stack.lo + stackGuard
+ } else {
+ if raceenabled {
+ racemalloc(unsafe.Pointer(gp.stack.lo), gp.stack.hi-gp.stack.lo)
+ }
+ if msanenabled {
+ msanmalloc(unsafe.Pointer(gp.stack.lo), gp.stack.hi-gp.stack.lo)
+ }
+ if asanenabled {
+ asanunpoison(unsafe.Pointer(gp.stack.lo), gp.stack.hi-gp.stack.lo)
+ }
+ }
+ return gp
+}
+
+// Purge all cached G's from gfree list to the global list.
+func gfpurge(pp *p) {
+ var (
+ inc int32
+ stackQ gQueue
+ noStackQ gQueue
+ )
+ for !pp.gFree.empty() {
+ gp := pp.gFree.pop()
+ pp.gFree.n--
+ if gp.stack.lo == 0 {
+ noStackQ.push(gp)
+ } else {
+ stackQ.push(gp)
+ }
+ inc++
+ }
+ lock(&sched.gFree.lock)
+ sched.gFree.noStack.pushAll(noStackQ)
+ sched.gFree.stack.pushAll(stackQ)
+ sched.gFree.n += inc
+ unlock(&sched.gFree.lock)
+}
+
+// Breakpoint executes a breakpoint trap.
+func Breakpoint() {
+ breakpoint()
+}
+
+// dolockOSThread is called by LockOSThread and lockOSThread below
+// after they modify m.locked. Do not allow preemption during this call,
+// or else the m might be different in this function than in the caller.
+//
+//go:nosplit
+func dolockOSThread() {
+ if GOARCH == "wasm" {
+ return // no threads on wasm yet
+ }
+ gp := getg()
+ gp.m.lockedg.set(gp)
+ gp.lockedm.set(gp.m)
+}
+
+// LockOSThread wires the calling goroutine to its current operating system thread.
+// The calling goroutine will always execute in that thread,
+// and no other goroutine will execute in it,
+// until the calling goroutine has made as many calls to
+// UnlockOSThread as to LockOSThread.
+// If the calling goroutine exits without unlocking the thread,
+// the thread will be terminated.
+//
+// All init functions are run on the startup thread. Calling LockOSThread
+// from an init function will cause the main function to be invoked on
+// that thread.
+//
+// A goroutine should call LockOSThread before calling OS services or
+// non-Go library functions that depend on per-thread state.
+//
+//go:nosplit
+func LockOSThread() {
+ if atomic.Load(&newmHandoff.haveTemplateThread) == 0 && GOOS != "plan9" {
+ // If we need to start a new thread from the locked
+ // thread, we need the template thread. Start it now
+ // while we're in a known-good state.
+ startTemplateThread()
+ }
+ gp := getg()
+ gp.m.lockedExt++
+ if gp.m.lockedExt == 0 {
+ gp.m.lockedExt--
+ panic("LockOSThread nesting overflow")
+ }
+ dolockOSThread()
+}
+
+//go:nosplit
+func lockOSThread() {
+ getg().m.lockedInt++
+ dolockOSThread()
+}
+
+// dounlockOSThread is called by UnlockOSThread and unlockOSThread below
+// after they update m->locked. Do not allow preemption during this call,
+// or else the m might be in different in this function than in the caller.
+//
+//go:nosplit
+func dounlockOSThread() {
+ if GOARCH == "wasm" {
+ return // no threads on wasm yet
+ }
+ gp := getg()
+ if gp.m.lockedInt != 0 || gp.m.lockedExt != 0 {
+ return
+ }
+ gp.m.lockedg = 0
+ gp.lockedm = 0
+}
+
+// UnlockOSThread undoes an earlier call to LockOSThread.
+// If this drops the number of active LockOSThread calls on the
+// calling goroutine to zero, it unwires the calling goroutine from
+// its fixed operating system thread.
+// If there are no active LockOSThread calls, this is a no-op.
+//
+// Before calling UnlockOSThread, the caller must ensure that the OS
+// thread is suitable for running other goroutines. If the caller made
+// any permanent changes to the state of the thread that would affect
+// other goroutines, it should not call this function and thus leave
+// the goroutine locked to the OS thread until the goroutine (and
+// hence the thread) exits.
+//
+//go:nosplit
+func UnlockOSThread() {
+ gp := getg()
+ if gp.m.lockedExt == 0 {
+ return
+ }
+ gp.m.lockedExt--
+ dounlockOSThread()
+}
+
+//go:nosplit
+func unlockOSThread() {
+ gp := getg()
+ if gp.m.lockedInt == 0 {
+ systemstack(badunlockosthread)
+ }
+ gp.m.lockedInt--
+ dounlockOSThread()
+}
+
+func badunlockosthread() {
+ throw("runtime: internal error: misuse of lockOSThread/unlockOSThread")
+}
+
+func gcount() int32 {
+ n := int32(atomic.Loaduintptr(&allglen)) - sched.gFree.n - sched.ngsys.Load()
+ for _, pp := range allp {
+ n -= pp.gFree.n
+ }
+
+ // All these variables can be changed concurrently, so the result can be inconsistent.
+ // But at least the current goroutine is running.
+ if n < 1 {
+ n = 1
+ }
+ return n
+}
+
+func mcount() int32 {
+ return int32(sched.mnext - sched.nmfreed)
+}
+
+var prof struct {
+ signalLock atomic.Uint32
+
+ // Must hold signalLock to write. Reads may be lock-free, but
+ // signalLock should be taken to synchronize with changes.
+ hz atomic.Int32
+}
+
+func _System() { _System() }
+func _ExternalCode() { _ExternalCode() }
+func _LostExternalCode() { _LostExternalCode() }
+func _GC() { _GC() }
+func _LostSIGPROFDuringAtomic64() { _LostSIGPROFDuringAtomic64() }
+func _VDSO() { _VDSO() }
+
+// Called if we receive a SIGPROF signal.
+// Called by the signal handler, may run during STW.
+//
+//go:nowritebarrierrec
+func sigprof(pc, sp, lr uintptr, gp *g, mp *m) {
+ if prof.hz.Load() == 0 {
+ return
+ }
+
+ // If mp.profilehz is 0, then profiling is not enabled for this thread.
+ // We must check this to avoid a deadlock between setcpuprofilerate
+ // and the call to cpuprof.add, below.
+ if mp != nil && mp.profilehz == 0 {
+ return
+ }
+
+ // On mips{,le}/arm, 64bit atomics are emulated with spinlocks, in
+ // runtime/internal/atomic. If SIGPROF arrives while the program is inside
+ // the critical section, it creates a deadlock (when writing the sample).
+ // As a workaround, create a counter of SIGPROFs while in critical section
+ // to store the count, and pass it to sigprof.add() later when SIGPROF is
+ // received from somewhere else (with _LostSIGPROFDuringAtomic64 as pc).
+ if GOARCH == "mips" || GOARCH == "mipsle" || GOARCH == "arm" {
+ if f := findfunc(pc); f.valid() {
+ if hasPrefix(funcname(f), "runtime/internal/atomic") {
+ cpuprof.lostAtomic++
+ return
+ }
+ }
+ if GOARCH == "arm" && goarm < 7 && GOOS == "linux" && pc&0xffff0000 == 0xffff0000 {
+ // runtime/internal/atomic functions call into kernel
+ // helpers on arm < 7. See
+ // runtime/internal/atomic/sys_linux_arm.s.
+ cpuprof.lostAtomic++
+ return
+ }
+ }
+
+ // Profiling runs concurrently with GC, so it must not allocate.
+ // Set a trap in case the code does allocate.
+ // Note that on windows, one thread takes profiles of all the
+ // other threads, so mp is usually not getg().m.
+ // In fact mp may not even be stopped.
+ // See golang.org/issue/17165.
+ getg().m.mallocing++
+
+ var u unwinder
+ var stk [maxCPUProfStack]uintptr
+ n := 0
+ if mp.ncgo > 0 && mp.curg != nil && mp.curg.syscallpc != 0 && mp.curg.syscallsp != 0 {
+ cgoOff := 0
+ // Check cgoCallersUse to make sure that we are not
+ // interrupting other code that is fiddling with
+ // cgoCallers. We are running in a signal handler
+ // with all signals blocked, so we don't have to worry
+ // about any other code interrupting us.
+ if mp.cgoCallersUse.Load() == 0 && mp.cgoCallers != nil && mp.cgoCallers[0] != 0 {
+ for cgoOff < len(mp.cgoCallers) && mp.cgoCallers[cgoOff] != 0 {
+ cgoOff++
+ }
+ n += copy(stk[:], mp.cgoCallers[:cgoOff])
+ mp.cgoCallers[0] = 0
+ }
+
+ // Collect Go stack that leads to the cgo call.
+ u.initAt(mp.curg.syscallpc, mp.curg.syscallsp, 0, mp.curg, unwindSilentErrors)
+ } else if usesLibcall() && mp.libcallg != 0 && mp.libcallpc != 0 && mp.libcallsp != 0 {
+ // Libcall, i.e. runtime syscall on windows.
+ // Collect Go stack that leads to the call.
+ u.initAt(mp.libcallpc, mp.libcallsp, 0, mp.libcallg.ptr(), unwindSilentErrors)
+ } else if mp != nil && mp.vdsoSP != 0 {
+ // VDSO call, e.g. nanotime1 on Linux.
+ // Collect Go stack that leads to the call.
+ u.initAt(mp.vdsoPC, mp.vdsoSP, 0, gp, unwindSilentErrors|unwindJumpStack)
+ } else {
+ u.initAt(pc, sp, lr, gp, unwindSilentErrors|unwindTrap|unwindJumpStack)
+ }
+ n += tracebackPCs(&u, 0, stk[n:])
+
+ if n <= 0 {
+ // Normal traceback is impossible or has failed.
+ // Account it against abstract "System" or "GC".
+ n = 2
+ if inVDSOPage(pc) {
+ pc = abi.FuncPCABIInternal(_VDSO) + sys.PCQuantum
+ } else if pc > firstmoduledata.etext {
+ // "ExternalCode" is better than "etext".
+ pc = abi.FuncPCABIInternal(_ExternalCode) + sys.PCQuantum
+ }
+ stk[0] = pc
+ if mp.preemptoff != "" {
+ stk[1] = abi.FuncPCABIInternal(_GC) + sys.PCQuantum
+ } else {
+ stk[1] = abi.FuncPCABIInternal(_System) + sys.PCQuantum
+ }
+ }
+
+ if prof.hz.Load() != 0 {
+ // Note: it can happen on Windows that we interrupted a system thread
+ // with no g, so gp could nil. The other nil checks are done out of
+ // caution, but not expected to be nil in practice.
+ var tagPtr *unsafe.Pointer
+ if gp != nil && gp.m != nil && gp.m.curg != nil {
+ tagPtr = &gp.m.curg.labels
+ }
+ cpuprof.add(tagPtr, stk[:n])
+
+ gprof := gp
+ var pp *p
+ if gp != nil && gp.m != nil {
+ if gp.m.curg != nil {
+ gprof = gp.m.curg
+ }
+ pp = gp.m.p.ptr()
+ }
+ traceCPUSample(gprof, pp, stk[:n])
+ }
+ getg().m.mallocing--
+}
+
+// setcpuprofilerate sets the CPU profiling rate to hz times per second.
+// If hz <= 0, setcpuprofilerate turns off CPU profiling.
+func setcpuprofilerate(hz int32) {
+ // Force sane arguments.
+ if hz < 0 {
+ hz = 0
+ }
+
+ // Disable preemption, otherwise we can be rescheduled to another thread
+ // that has profiling enabled.
+ gp := getg()
+ gp.m.locks++
+
+ // Stop profiler on this thread so that it is safe to lock prof.
+ // if a profiling signal came in while we had prof locked,
+ // it would deadlock.
+ setThreadCPUProfiler(0)
+
+ for !prof.signalLock.CompareAndSwap(0, 1) {
+ osyield()
+ }
+ if prof.hz.Load() != hz {
+ setProcessCPUProfiler(hz)
+ prof.hz.Store(hz)
+ }
+ prof.signalLock.Store(0)
+
+ lock(&sched.lock)
+ sched.profilehz = hz
+ unlock(&sched.lock)
+
+ if hz != 0 {
+ setThreadCPUProfiler(hz)
+ }
+
+ gp.m.locks--
+}
+
+// init initializes pp, which may be a freshly allocated p or a
+// previously destroyed p, and transitions it to status _Pgcstop.
+func (pp *p) init(id int32) {
+ pp.id = id
+ pp.status = _Pgcstop
+ pp.sudogcache = pp.sudogbuf[:0]
+ pp.deferpool = pp.deferpoolbuf[:0]
+ pp.wbBuf.reset()
+ if pp.mcache == nil {
+ if id == 0 {
+ if mcache0 == nil {
+ throw("missing mcache?")
+ }
+ // Use the bootstrap mcache0. Only one P will get
+ // mcache0: the one with ID 0.
+ pp.mcache = mcache0
+ } else {
+ pp.mcache = allocmcache()
+ }
+ }
+ if raceenabled && pp.raceprocctx == 0 {
+ if id == 0 {
+ pp.raceprocctx = raceprocctx0
+ raceprocctx0 = 0 // bootstrap
+ } else {
+ pp.raceprocctx = raceproccreate()
+ }
+ }
+ lockInit(&pp.timersLock, lockRankTimers)
+
+ // This P may get timers when it starts running. Set the mask here
+ // since the P may not go through pidleget (notably P 0 on startup).
+ timerpMask.set(id)
+ // Similarly, we may not go through pidleget before this P starts
+ // running if it is P 0 on startup.
+ idlepMask.clear(id)
+}
+
+// destroy releases all of the resources associated with pp and
+// transitions it to status _Pdead.
+//
+// sched.lock must be held and the world must be stopped.
+func (pp *p) destroy() {
+ assertLockHeld(&sched.lock)
+ assertWorldStopped()
+
+ // Move all runnable goroutines to the global queue
+ for pp.runqhead != pp.runqtail {
+ // Pop from tail of local queue
+ pp.runqtail--
+ gp := pp.runq[pp.runqtail%uint32(len(pp.runq))].ptr()
+ // Push onto head of global queue
+ globrunqputhead(gp)
+ }
+ if pp.runnext != 0 {
+ globrunqputhead(pp.runnext.ptr())
+ pp.runnext = 0
+ }
+ if len(pp.timers) > 0 {
+ plocal := getg().m.p.ptr()
+ // The world is stopped, but we acquire timersLock to
+ // protect against sysmon calling timeSleepUntil.
+ // This is the only case where we hold the timersLock of
+ // more than one P, so there are no deadlock concerns.
+ lock(&plocal.timersLock)
+ lock(&pp.timersLock)
+ moveTimers(plocal, pp.timers)
+ pp.timers = nil
+ pp.numTimers.Store(0)
+ pp.deletedTimers.Store(0)
+ pp.timer0When.Store(0)
+ unlock(&pp.timersLock)
+ unlock(&plocal.timersLock)
+ }
+ // Flush p's write barrier buffer.
+ if gcphase != _GCoff {
+ wbBufFlush1(pp)
+ pp.gcw.dispose()
+ }
+ for i := range pp.sudogbuf {
+ pp.sudogbuf[i] = nil
+ }
+ pp.sudogcache = pp.sudogbuf[:0]
+ pp.pinnerCache = nil
+ for j := range pp.deferpoolbuf {
+ pp.deferpoolbuf[j] = nil
+ }
+ pp.deferpool = pp.deferpoolbuf[:0]
+ systemstack(func() {
+ for i := 0; i < pp.mspancache.len; i++ {
+ // Safe to call since the world is stopped.
+ mheap_.spanalloc.free(unsafe.Pointer(pp.mspancache.buf[i]))
+ }
+ pp.mspancache.len = 0
+ lock(&mheap_.lock)
+ pp.pcache.flush(&mheap_.pages)
+ unlock(&mheap_.lock)
+ })
+ freemcache(pp.mcache)
+ pp.mcache = nil
+ gfpurge(pp)
+ traceProcFree(pp)
+ if raceenabled {
+ if pp.timerRaceCtx != 0 {
+ // The race detector code uses a callback to fetch
+ // the proc context, so arrange for that callback
+ // to see the right thing.
+ // This hack only works because we are the only
+ // thread running.
+ mp := getg().m
+ phold := mp.p.ptr()
+ mp.p.set(pp)
+
+ racectxend(pp.timerRaceCtx)
+ pp.timerRaceCtx = 0
+
+ mp.p.set(phold)
+ }
+ raceprocdestroy(pp.raceprocctx)
+ pp.raceprocctx = 0
+ }
+ pp.gcAssistTime = 0
+ pp.status = _Pdead
+}
+
+// Change number of processors.
+//
+// sched.lock must be held, and the world must be stopped.
+//
+// gcworkbufs must not be being modified by either the GC or the write barrier
+// code, so the GC must not be running if the number of Ps actually changes.
+//
+// Returns list of Ps with local work, they need to be scheduled by the caller.
+func procresize(nprocs int32) *p {
+ assertLockHeld(&sched.lock)
+ assertWorldStopped()
+
+ old := gomaxprocs
+ if old < 0 || nprocs <= 0 {
+ throw("procresize: invalid arg")
+ }
+ if traceEnabled() {
+ traceGomaxprocs(nprocs)
+ }
+
+ // update statistics
+ now := nanotime()
+ if sched.procresizetime != 0 {
+ sched.totaltime += int64(old) * (now - sched.procresizetime)
+ }
+ sched.procresizetime = now
+
+ maskWords := (nprocs + 31) / 32
+
+ // Grow allp if necessary.
+ if nprocs > int32(len(allp)) {
+ // Synchronize with retake, which could be running
+ // concurrently since it doesn't run on a P.
+ lock(&allpLock)
+ if nprocs <= int32(cap(allp)) {
+ allp = allp[:nprocs]
+ } else {
+ nallp := make([]*p, nprocs)
+ // Copy everything up to allp's cap so we
+ // never lose old allocated Ps.
+ copy(nallp, allp[:cap(allp)])
+ allp = nallp
+ }
+
+ if maskWords <= int32(cap(idlepMask)) {
+ idlepMask = idlepMask[:maskWords]
+ timerpMask = timerpMask[:maskWords]
+ } else {
+ nidlepMask := make([]uint32, maskWords)
+ // No need to copy beyond len, old Ps are irrelevant.
+ copy(nidlepMask, idlepMask)
+ idlepMask = nidlepMask
+
+ ntimerpMask := make([]uint32, maskWords)
+ copy(ntimerpMask, timerpMask)
+ timerpMask = ntimerpMask
+ }
+ unlock(&allpLock)
+ }
+
+ // initialize new P's
+ for i := old; i < nprocs; i++ {
+ pp := allp[i]
+ if pp == nil {
+ pp = new(p)
+ }
+ pp.init(i)
+ atomicstorep(unsafe.Pointer(&allp[i]), unsafe.Pointer(pp))
+ }
+
+ gp := getg()
+ if gp.m.p != 0 && gp.m.p.ptr().id < nprocs {
+ // continue to use the current P
+ gp.m.p.ptr().status = _Prunning
+ gp.m.p.ptr().mcache.prepareForSweep()
+ } else {
+ // release the current P and acquire allp[0].
+ //
+ // We must do this before destroying our current P
+ // because p.destroy itself has write barriers, so we
+ // need to do that from a valid P.
+ if gp.m.p != 0 {
+ if traceEnabled() {
+ // Pretend that we were descheduled
+ // and then scheduled again to keep
+ // the trace sane.
+ traceGoSched()
+ traceProcStop(gp.m.p.ptr())
+ }
+ gp.m.p.ptr().m = 0
+ }
+ gp.m.p = 0
+ pp := allp[0]
+ pp.m = 0
+ pp.status = _Pidle
+ acquirep(pp)
+ if traceEnabled() {
+ traceGoStart()
+ }
+ }
+
+ // g.m.p is now set, so we no longer need mcache0 for bootstrapping.
+ mcache0 = nil
+
+ // release resources from unused P's
+ for i := nprocs; i < old; i++ {
+ pp := allp[i]
+ pp.destroy()
+ // can't free P itself because it can be referenced by an M in syscall
+ }
+
+ // Trim allp.
+ if int32(len(allp)) != nprocs {
+ lock(&allpLock)
+ allp = allp[:nprocs]
+ idlepMask = idlepMask[:maskWords]
+ timerpMask = timerpMask[:maskWords]
+ unlock(&allpLock)
+ }
+
+ var runnablePs *p
+ for i := nprocs - 1; i >= 0; i-- {
+ pp := allp[i]
+ if gp.m.p.ptr() == pp {
+ continue
+ }
+ pp.status = _Pidle
+ if runqempty(pp) {
+ pidleput(pp, now)
+ } else {
+ pp.m.set(mget())
+ pp.link.set(runnablePs)
+ runnablePs = pp
+ }
+ }
+ stealOrder.reset(uint32(nprocs))
+ var int32p *int32 = &gomaxprocs // make compiler check that gomaxprocs is an int32
+ atomic.Store((*uint32)(unsafe.Pointer(int32p)), uint32(nprocs))
+ if old != nprocs {
+ // Notify the limiter that the amount of procs has changed.
+ gcCPULimiter.resetCapacity(now, nprocs)
+ }
+ return runnablePs
+}
+
+// Associate p and the current m.
+//
+// This function is allowed to have write barriers even if the caller
+// isn't because it immediately acquires pp.
+//
+//go:yeswritebarrierrec
+func acquirep(pp *p) {
+ // Do the part that isn't allowed to have write barriers.
+ wirep(pp)
+
+ // Have p; write barriers now allowed.
+
+ // Perform deferred mcache flush before this P can allocate
+ // from a potentially stale mcache.
+ pp.mcache.prepareForSweep()
+
+ if traceEnabled() {
+ traceProcStart()
+ }
+}
+
+// wirep is the first step of acquirep, which actually associates the
+// current M to pp. This is broken out so we can disallow write
+// barriers for this part, since we don't yet have a P.
+//
+//go:nowritebarrierrec
+//go:nosplit
+func wirep(pp *p) {
+ gp := getg()
+
+ if gp.m.p != 0 {
+ throw("wirep: already in go")
+ }
+ if pp.m != 0 || pp.status != _Pidle {
+ id := int64(0)
+ if pp.m != 0 {
+ id = pp.m.ptr().id
+ }
+ print("wirep: p->m=", pp.m, "(", id, ") p->status=", pp.status, "\n")
+ throw("wirep: invalid p state")
+ }
+ gp.m.p.set(pp)
+ pp.m.set(gp.m)
+ pp.status = _Prunning
+}
+
+// Disassociate p and the current m.
+func releasep() *p {
+ gp := getg()
+
+ if gp.m.p == 0 {
+ throw("releasep: invalid arg")
+ }
+ pp := gp.m.p.ptr()
+ if pp.m.ptr() != gp.m || pp.status != _Prunning {
+ print("releasep: m=", gp.m, " m->p=", gp.m.p.ptr(), " p->m=", hex(pp.m), " p->status=", pp.status, "\n")
+ throw("releasep: invalid p state")
+ }
+ if traceEnabled() {
+ traceProcStop(gp.m.p.ptr())
+ }
+ gp.m.p = 0
+ pp.m = 0
+ pp.status = _Pidle
+ return pp
+}
+
+func incidlelocked(v int32) {
+ lock(&sched.lock)
+ sched.nmidlelocked += v
+ if v > 0 {
+ checkdead()
+ }
+ unlock(&sched.lock)
+}
+
+// Check for deadlock situation.
+// The check is based on number of running M's, if 0 -> deadlock.
+// sched.lock must be held.
+func checkdead() {
+ assertLockHeld(&sched.lock)
+
+ // For -buildmode=c-shared or -buildmode=c-archive it's OK if
+ // there are no running goroutines. The calling program is
+ // assumed to be running.
+ if islibrary || isarchive {
+ return
+ }
+
+ // If we are dying because of a signal caught on an already idle thread,
+ // freezetheworld will cause all running threads to block.
+ // And runtime will essentially enter into deadlock state,
+ // except that there is a thread that will call exit soon.
+ if panicking.Load() > 0 {
+ return
+ }
+
+ // If we are not running under cgo, but we have an extra M then account
+ // for it. (It is possible to have an extra M on Windows without cgo to
+ // accommodate callbacks created by syscall.NewCallback. See issue #6751
+ // for details.)
+ var run0 int32
+ if !iscgo && cgoHasExtraM && extraMLength.Load() > 0 {
+ run0 = 1
+ }
+
+ run := mcount() - sched.nmidle - sched.nmidlelocked - sched.nmsys
+ if run > run0 {
+ return
+ }
+ if run < 0 {
+ print("runtime: checkdead: nmidle=", sched.nmidle, " nmidlelocked=", sched.nmidlelocked, " mcount=", mcount(), " nmsys=", sched.nmsys, "\n")
+ unlock(&sched.lock)
+ throw("checkdead: inconsistent counts")
+ }
+
+ grunning := 0
+ forEachG(func(gp *g) {
+ if isSystemGoroutine(gp, false) {
+ return
+ }
+ s := readgstatus(gp)
+ switch s &^ _Gscan {
+ case _Gwaiting,
+ _Gpreempted:
+ grunning++
+ case _Grunnable,
+ _Grunning,
+ _Gsyscall:
+ print("runtime: checkdead: find g ", gp.goid, " in status ", s, "\n")
+ unlock(&sched.lock)
+ throw("checkdead: runnable g")
+ }
+ })
+ if grunning == 0 { // possible if main goroutine calls runtime·Goexit()
+ unlock(&sched.lock) // unlock so that GODEBUG=scheddetail=1 doesn't hang
+ fatal("no goroutines (main called runtime.Goexit) - deadlock!")
+ }
+
+ // Maybe jump time forward for playground.
+ if faketime != 0 {
+ if when := timeSleepUntil(); when < maxWhen {
+ faketime = when
+
+ // Start an M to steal the timer.
+ pp, _ := pidleget(faketime)
+ if pp == nil {
+ // There should always be a free P since
+ // nothing is running.
+ unlock(&sched.lock)
+ throw("checkdead: no p for timer")
+ }
+ mp := mget()
+ if mp == nil {
+ // There should always be a free M since
+ // nothing is running.
+ unlock(&sched.lock)
+ throw("checkdead: no m for timer")
+ }
+ // M must be spinning to steal. We set this to be
+ // explicit, but since this is the only M it would
+ // become spinning on its own anyways.
+ sched.nmspinning.Add(1)
+ mp.spinning = true
+ mp.nextp.set(pp)
+ notewakeup(&mp.park)
+ return
+ }
+ }
+
+ // There are no goroutines running, so we can look at the P's.
+ for _, pp := range allp {
+ if len(pp.timers) > 0 {
+ return
+ }
+ }
+
+ unlock(&sched.lock) // unlock so that GODEBUG=scheddetail=1 doesn't hang
+ fatal("all goroutines are asleep - deadlock!")
+}
+
+// forcegcperiod is the maximum time in nanoseconds between garbage
+// collections. If we go this long without a garbage collection, one
+// is forced to run.
+//
+// This is a variable for testing purposes. It normally doesn't change.
+var forcegcperiod int64 = 2 * 60 * 1e9
+
+// needSysmonWorkaround is true if the workaround for
+// golang.org/issue/42515 is needed on NetBSD.
+var needSysmonWorkaround bool = false
+
+// Always runs without a P, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func sysmon() {
+ lock(&sched.lock)
+ sched.nmsys++
+ checkdead()
+ unlock(&sched.lock)
+
+ lasttrace := int64(0)
+ idle := 0 // how many cycles in succession we had not wokeup somebody
+ delay := uint32(0)
+
+ for {
+ if idle == 0 { // start with 20us sleep...
+ delay = 20
+ } else if idle > 50 { // start doubling the sleep after 1ms...
+ delay *= 2
+ }
+ if delay > 10*1000 { // up to 10ms
+ delay = 10 * 1000
+ }
+ usleep(delay)
+
+ // sysmon should not enter deep sleep if schedtrace is enabled so that
+ // it can print that information at the right time.
+ //
+ // It should also not enter deep sleep if there are any active P's so
+ // that it can retake P's from syscalls, preempt long running G's, and
+ // poll the network if all P's are busy for long stretches.
+ //
+ // It should wakeup from deep sleep if any P's become active either due
+ // to exiting a syscall or waking up due to a timer expiring so that it
+ // can resume performing those duties. If it wakes from a syscall it
+ // resets idle and delay as a bet that since it had retaken a P from a
+ // syscall before, it may need to do it again shortly after the
+ // application starts work again. It does not reset idle when waking
+ // from a timer to avoid adding system load to applications that spend
+ // most of their time sleeping.
+ now := nanotime()
+ if debug.schedtrace <= 0 && (sched.gcwaiting.Load() || sched.npidle.Load() == gomaxprocs) {
+ lock(&sched.lock)
+ if sched.gcwaiting.Load() || sched.npidle.Load() == gomaxprocs {
+ syscallWake := false
+ next := timeSleepUntil()
+ if next > now {
+ sched.sysmonwait.Store(true)
+ unlock(&sched.lock)
+ // Make wake-up period small enough
+ // for the sampling to be correct.
+ sleep := forcegcperiod / 2
+ if next-now < sleep {
+ sleep = next - now
+ }
+ shouldRelax := sleep >= osRelaxMinNS
+ if shouldRelax {
+ osRelax(true)
+ }
+ syscallWake = notetsleep(&sched.sysmonnote, sleep)
+ if shouldRelax {
+ osRelax(false)
+ }
+ lock(&sched.lock)
+ sched.sysmonwait.Store(false)
+ noteclear(&sched.sysmonnote)
+ }
+ if syscallWake {
+ idle = 0
+ delay = 20
+ }
+ }
+ unlock(&sched.lock)
+ }
+
+ lock(&sched.sysmonlock)
+ // Update now in case we blocked on sysmonnote or spent a long time
+ // blocked on schedlock or sysmonlock above.
+ now = nanotime()
+
+ // trigger libc interceptors if needed
+ if *cgo_yield != nil {
+ asmcgocall(*cgo_yield, nil)
+ }
+ // poll network if not polled for more than 10ms
+ lastpoll := sched.lastpoll.Load()
+ if netpollinited() && lastpoll != 0 && lastpoll+10*1000*1000 < now {
+ sched.lastpoll.CompareAndSwap(lastpoll, now)
+ list := netpoll(0) // non-blocking - returns list of goroutines
+ if !list.empty() {
+ // Need to decrement number of idle locked M's
+ // (pretending that one more is running) before injectglist.
+ // Otherwise it can lead to the following situation:
+ // injectglist grabs all P's but before it starts M's to run the P's,
+ // another M returns from syscall, finishes running its G,
+ // observes that there is no work to do and no other running M's
+ // and reports deadlock.
+ incidlelocked(-1)
+ injectglist(&list)
+ incidlelocked(1)
+ }
+ }
+ if GOOS == "netbsd" && needSysmonWorkaround {
+ // netpoll is responsible for waiting for timer
+ // expiration, so we typically don't have to worry
+ // about starting an M to service timers. (Note that
+ // sleep for timeSleepUntil above simply ensures sysmon
+ // starts running again when that timer expiration may
+ // cause Go code to run again).
+ //
+ // However, netbsd has a kernel bug that sometimes
+ // misses netpollBreak wake-ups, which can lead to
+ // unbounded delays servicing timers. If we detect this
+ // overrun, then startm to get something to handle the
+ // timer.
+ //
+ // See issue 42515 and
+ // https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=50094.
+ if next := timeSleepUntil(); next < now {
+ startm(nil, false, false)
+ }
+ }
+ if scavenger.sysmonWake.Load() != 0 {
+ // Kick the scavenger awake if someone requested it.
+ scavenger.wake()
+ }
+ // retake P's blocked in syscalls
+ // and preempt long running G's
+ if retake(now) != 0 {
+ idle = 0
+ } else {
+ idle++
+ }
+ // check if we need to force a GC
+ if t := (gcTrigger{kind: gcTriggerTime, now: now}); t.test() && forcegc.idle.Load() {
+ lock(&forcegc.lock)
+ forcegc.idle.Store(false)
+ var list gList
+ list.push(forcegc.g)
+ injectglist(&list)
+ unlock(&forcegc.lock)
+ }
+ if debug.schedtrace > 0 && lasttrace+int64(debug.schedtrace)*1000000 <= now {
+ lasttrace = now
+ schedtrace(debug.scheddetail > 0)
+ }
+ unlock(&sched.sysmonlock)
+ }
+}
+
+type sysmontick struct {
+ schedtick uint32
+ schedwhen int64
+ syscalltick uint32
+ syscallwhen int64
+}
+
+// forcePreemptNS is the time slice given to a G before it is
+// preempted.
+const forcePreemptNS = 10 * 1000 * 1000 // 10ms
+
+func retake(now int64) uint32 {
+ n := 0
+ // Prevent allp slice changes. This lock will be completely
+ // uncontended unless we're already stopping the world.
+ lock(&allpLock)
+ // We can't use a range loop over allp because we may
+ // temporarily drop the allpLock. Hence, we need to re-fetch
+ // allp each time around the loop.
+ for i := 0; i < len(allp); i++ {
+ pp := allp[i]
+ if pp == nil {
+ // This can happen if procresize has grown
+ // allp but not yet created new Ps.
+ continue
+ }
+ pd := &pp.sysmontick
+ s := pp.status
+ sysretake := false
+ if s == _Prunning || s == _Psyscall {
+ // Preempt G if it's running for too long.
+ t := int64(pp.schedtick)
+ if int64(pd.schedtick) != t {
+ pd.schedtick = uint32(t)
+ pd.schedwhen = now
+ } else if pd.schedwhen+forcePreemptNS <= now {
+ preemptone(pp)
+ // In case of syscall, preemptone() doesn't
+ // work, because there is no M wired to P.
+ sysretake = true
+ }
+ }
+ if s == _Psyscall {
+ // Retake P from syscall if it's there for more than 1 sysmon tick (at least 20us).
+ t := int64(pp.syscalltick)
+ if !sysretake && int64(pd.syscalltick) != t {
+ pd.syscalltick = uint32(t)
+ pd.syscallwhen = now
+ continue
+ }
+ // On the one hand we don't want to retake Ps if there is no other work to do,
+ // but on the other hand we want to retake them eventually
+ // because they can prevent the sysmon thread from deep sleep.
+ if runqempty(pp) && sched.nmspinning.Load()+sched.npidle.Load() > 0 && pd.syscallwhen+10*1000*1000 > now {
+ continue
+ }
+ // Drop allpLock so we can take sched.lock.
+ unlock(&allpLock)
+ // Need to decrement number of idle locked M's
+ // (pretending that one more is running) before the CAS.
+ // Otherwise the M from which we retake can exit the syscall,
+ // increment nmidle and report deadlock.
+ incidlelocked(-1)
+ if atomic.Cas(&pp.status, s, _Pidle) {
+ if traceEnabled() {
+ traceGoSysBlock(pp)
+ traceProcStop(pp)
+ }
+ n++
+ pp.syscalltick++
+ handoffp(pp)
+ }
+ incidlelocked(1)
+ lock(&allpLock)
+ }
+ }
+ unlock(&allpLock)
+ return uint32(n)
+}
+
+// Tell all goroutines that they have been preempted and they should stop.
+// This function is purely best-effort. It can fail to inform a goroutine if a
+// processor just started running it.
+// No locks need to be held.
+// Returns true if preemption request was issued to at least one goroutine.
+func preemptall() bool {
+ res := false
+ for _, pp := range allp {
+ if pp.status != _Prunning {
+ continue
+ }
+ if preemptone(pp) {
+ res = true
+ }
+ }
+ return res
+}
+
+// Tell the goroutine running on processor P to stop.
+// This function is purely best-effort. It can incorrectly fail to inform the
+// goroutine. It can inform the wrong goroutine. Even if it informs the
+// correct goroutine, that goroutine might ignore the request if it is
+// simultaneously executing newstack.
+// No lock needs to be held.
+// Returns true if preemption request was issued.
+// The actual preemption will happen at some point in the future
+// and will be indicated by the gp->status no longer being
+// Grunning
+func preemptone(pp *p) bool {
+ mp := pp.m.ptr()
+ if mp == nil || mp == getg().m {
+ return false
+ }
+ gp := mp.curg
+ if gp == nil || gp == mp.g0 {
+ return false
+ }
+
+ gp.preempt = true
+
+ // Every call in a goroutine checks for stack overflow by
+ // comparing the current stack pointer to gp->stackguard0.
+ // Setting gp->stackguard0 to StackPreempt folds
+ // preemption into the normal stack overflow check.
+ gp.stackguard0 = stackPreempt
+
+ // Request an async preemption of this P.
+ if preemptMSupported && debug.asyncpreemptoff == 0 {
+ pp.preempt = true
+ preemptM(mp)
+ }
+
+ return true
+}
+
+var starttime int64
+
+func schedtrace(detailed bool) {
+ now := nanotime()
+ if starttime == 0 {
+ starttime = now
+ }
+
+ lock(&sched.lock)
+ print("SCHED ", (now-starttime)/1e6, "ms: gomaxprocs=", gomaxprocs, " idleprocs=", sched.npidle.Load(), " threads=", mcount(), " spinningthreads=", sched.nmspinning.Load(), " needspinning=", sched.needspinning.Load(), " idlethreads=", sched.nmidle, " runqueue=", sched.runqsize)
+ if detailed {
+ print(" gcwaiting=", sched.gcwaiting.Load(), " nmidlelocked=", sched.nmidlelocked, " stopwait=", sched.stopwait, " sysmonwait=", sched.sysmonwait.Load(), "\n")
+ }
+ // We must be careful while reading data from P's, M's and G's.
+ // Even if we hold schedlock, most data can be changed concurrently.
+ // E.g. (p->m ? p->m->id : -1) can crash if p->m changes from non-nil to nil.
+ for i, pp := range allp {
+ mp := pp.m.ptr()
+ h := atomic.Load(&pp.runqhead)
+ t := atomic.Load(&pp.runqtail)
+ if detailed {
+ print(" P", i, ": status=", pp.status, " schedtick=", pp.schedtick, " syscalltick=", pp.syscalltick, " m=")
+ if mp != nil {
+ print(mp.id)
+ } else {
+ print("nil")
+ }
+ print(" runqsize=", t-h, " gfreecnt=", pp.gFree.n, " timerslen=", len(pp.timers), "\n")
+ } else {
+ // In non-detailed mode format lengths of per-P run queues as:
+ // [len1 len2 len3 len4]
+ print(" ")
+ if i == 0 {
+ print("[")
+ }
+ print(t - h)
+ if i == len(allp)-1 {
+ print("]\n")
+ }
+ }
+ }
+
+ if !detailed {
+ unlock(&sched.lock)
+ return
+ }
+
+ for mp := allm; mp != nil; mp = mp.alllink {
+ pp := mp.p.ptr()
+ print(" M", mp.id, ": p=")
+ if pp != nil {
+ print(pp.id)
+ } else {
+ print("nil")
+ }
+ print(" curg=")
+ if mp.curg != nil {
+ print(mp.curg.goid)
+ } else {
+ print("nil")
+ }
+ print(" mallocing=", mp.mallocing, " throwing=", mp.throwing, " preemptoff=", mp.preemptoff, " locks=", mp.locks, " dying=", mp.dying, " spinning=", mp.spinning, " blocked=", mp.blocked, " lockedg=")
+ if lockedg := mp.lockedg.ptr(); lockedg != nil {
+ print(lockedg.goid)
+ } else {
+ print("nil")
+ }
+ print("\n")
+ }
+
+ forEachG(func(gp *g) {
+ print(" G", gp.goid, ": status=", readgstatus(gp), "(", gp.waitreason.String(), ") m=")
+ if gp.m != nil {
+ print(gp.m.id)
+ } else {
+ print("nil")
+ }
+ print(" lockedm=")
+ if lockedm := gp.lockedm.ptr(); lockedm != nil {
+ print(lockedm.id)
+ } else {
+ print("nil")
+ }
+ print("\n")
+ })
+ unlock(&sched.lock)
+}
+
+// schedEnableUser enables or disables the scheduling of user
+// goroutines.
+//
+// This does not stop already running user goroutines, so the caller
+// should first stop the world when disabling user goroutines.
+func schedEnableUser(enable bool) {
+ lock(&sched.lock)
+ if sched.disable.user == !enable {
+ unlock(&sched.lock)
+ return
+ }
+ sched.disable.user = !enable
+ if enable {
+ n := sched.disable.n
+ sched.disable.n = 0
+ globrunqputbatch(&sched.disable.runnable, n)
+ unlock(&sched.lock)
+ for ; n != 0 && sched.npidle.Load() != 0; n-- {
+ startm(nil, false, false)
+ }
+ } else {
+ unlock(&sched.lock)
+ }
+}
+
+// schedEnabled reports whether gp should be scheduled. It returns
+// false is scheduling of gp is disabled.
+//
+// sched.lock must be held.
+func schedEnabled(gp *g) bool {
+ assertLockHeld(&sched.lock)
+
+ if sched.disable.user {
+ return isSystemGoroutine(gp, true)
+ }
+ return true
+}
+
+// Put mp on midle list.
+// sched.lock must be held.
+// May run during STW, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func mput(mp *m) {
+ assertLockHeld(&sched.lock)
+
+ mp.schedlink = sched.midle
+ sched.midle.set(mp)
+ sched.nmidle++
+ checkdead()
+}
+
+// Try to get an m from midle list.
+// sched.lock must be held.
+// May run during STW, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func mget() *m {
+ assertLockHeld(&sched.lock)
+
+ mp := sched.midle.ptr()
+ if mp != nil {
+ sched.midle = mp.schedlink
+ sched.nmidle--
+ }
+ return mp
+}
+
+// Put gp on the global runnable queue.
+// sched.lock must be held.
+// May run during STW, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func globrunqput(gp *g) {
+ assertLockHeld(&sched.lock)
+
+ sched.runq.pushBack(gp)
+ sched.runqsize++
+}
+
+// Put gp at the head of the global runnable queue.
+// sched.lock must be held.
+// May run during STW, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func globrunqputhead(gp *g) {
+ assertLockHeld(&sched.lock)
+
+ sched.runq.push(gp)
+ sched.runqsize++
+}
+
+// Put a batch of runnable goroutines on the global runnable queue.
+// This clears *batch.
+// sched.lock must be held.
+// May run during STW, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func globrunqputbatch(batch *gQueue, n int32) {
+ assertLockHeld(&sched.lock)
+
+ sched.runq.pushBackAll(*batch)
+ sched.runqsize += n
+ *batch = gQueue{}
+}
+
+// Try get a batch of G's from the global runnable queue.
+// sched.lock must be held.
+func globrunqget(pp *p, max int32) *g {
+ assertLockHeld(&sched.lock)
+
+ if sched.runqsize == 0 {
+ return nil
+ }
+
+ n := sched.runqsize/gomaxprocs + 1
+ if n > sched.runqsize {
+ n = sched.runqsize
+ }
+ if max > 0 && n > max {
+ n = max
+ }
+ if n > int32(len(pp.runq))/2 {
+ n = int32(len(pp.runq)) / 2
+ }
+
+ sched.runqsize -= n
+
+ gp := sched.runq.pop()
+ n--
+ for ; n > 0; n-- {
+ gp1 := sched.runq.pop()
+ runqput(pp, gp1, false)
+ }
+ return gp
+}
+
+// pMask is an atomic bitstring with one bit per P.
+type pMask []uint32
+
+// read returns true if P id's bit is set.
+func (p pMask) read(id uint32) bool {
+ word := id / 32
+ mask := uint32(1) << (id % 32)
+ return (atomic.Load(&p[word]) & mask) != 0
+}
+
+// set sets P id's bit.
+func (p pMask) set(id int32) {
+ word := id / 32
+ mask := uint32(1) << (id % 32)
+ atomic.Or(&p[word], mask)
+}
+
+// clear clears P id's bit.
+func (p pMask) clear(id int32) {
+ word := id / 32
+ mask := uint32(1) << (id % 32)
+ atomic.And(&p[word], ^mask)
+}
+
+// updateTimerPMask clears pp's timer mask if it has no timers on its heap.
+//
+// Ideally, the timer mask would be kept immediately consistent on any timer
+// operations. Unfortunately, updating a shared global data structure in the
+// timer hot path adds too much overhead in applications frequently switching
+// between no timers and some timers.
+//
+// As a compromise, the timer mask is updated only on pidleget / pidleput. A
+// running P (returned by pidleget) may add a timer at any time, so its mask
+// must be set. An idle P (passed to pidleput) cannot add new timers while
+// idle, so if it has no timers at that time, its mask may be cleared.
+//
+// Thus, we get the following effects on timer-stealing in findrunnable:
+//
+// - Idle Ps with no timers when they go idle are never checked in findrunnable
+// (for work- or timer-stealing; this is the ideal case).
+// - Running Ps must always be checked.
+// - Idle Ps whose timers are stolen must continue to be checked until they run
+// again, even after timer expiration.
+//
+// When the P starts running again, the mask should be set, as a timer may be
+// added at any time.
+//
+// TODO(prattmic): Additional targeted updates may improve the above cases.
+// e.g., updating the mask when stealing a timer.
+func updateTimerPMask(pp *p) {
+ if pp.numTimers.Load() > 0 {
+ return
+ }
+
+ // Looks like there are no timers, however another P may transiently
+ // decrement numTimers when handling a timerModified timer in
+ // checkTimers. We must take timersLock to serialize with these changes.
+ lock(&pp.timersLock)
+ if pp.numTimers.Load() == 0 {
+ timerpMask.clear(pp.id)
+ }
+ unlock(&pp.timersLock)
+}
+
+// pidleput puts p on the _Pidle list. now must be a relatively recent call
+// to nanotime or zero. Returns now or the current time if now was zero.
+//
+// This releases ownership of p. Once sched.lock is released it is no longer
+// safe to use p.
+//
+// sched.lock must be held.
+//
+// May run during STW, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func pidleput(pp *p, now int64) int64 {
+ assertLockHeld(&sched.lock)
+
+ if !runqempty(pp) {
+ throw("pidleput: P has non-empty run queue")
+ }
+ if now == 0 {
+ now = nanotime()
+ }
+ updateTimerPMask(pp) // clear if there are no timers.
+ idlepMask.set(pp.id)
+ pp.link = sched.pidle
+ sched.pidle.set(pp)
+ sched.npidle.Add(1)
+ if !pp.limiterEvent.start(limiterEventIdle, now) {
+ throw("must be able to track idle limiter event")
+ }
+ return now
+}
+
+// pidleget tries to get a p from the _Pidle list, acquiring ownership.
+//
+// sched.lock must be held.
+//
+// May run during STW, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func pidleget(now int64) (*p, int64) {
+ assertLockHeld(&sched.lock)
+
+ pp := sched.pidle.ptr()
+ if pp != nil {
+ // Timer may get added at any time now.
+ if now == 0 {
+ now = nanotime()
+ }
+ timerpMask.set(pp.id)
+ idlepMask.clear(pp.id)
+ sched.pidle = pp.link
+ sched.npidle.Add(-1)
+ pp.limiterEvent.stop(limiterEventIdle, now)
+ }
+ return pp, now
+}
+
+// pidlegetSpinning tries to get a p from the _Pidle list, acquiring ownership.
+// This is called by spinning Ms (or callers than need a spinning M) that have
+// found work. If no P is available, this must synchronized with non-spinning
+// Ms that may be preparing to drop their P without discovering this work.
+//
+// sched.lock must be held.
+//
+// May run during STW, so write barriers are not allowed.
+//
+//go:nowritebarrierrec
+func pidlegetSpinning(now int64) (*p, int64) {
+ assertLockHeld(&sched.lock)
+
+ pp, now := pidleget(now)
+ if pp == nil {
+ // See "Delicate dance" comment in findrunnable. We found work
+ // that we cannot take, we must synchronize with non-spinning
+ // Ms that may be preparing to drop their P.
+ sched.needspinning.Store(1)
+ return nil, now
+ }
+
+ return pp, now
+}
+
+// runqempty reports whether pp has no Gs on its local run queue.
+// It never returns true spuriously.
+func runqempty(pp *p) bool {
+ // Defend against a race where 1) pp has G1 in runqnext but runqhead == runqtail,
+ // 2) runqput on pp kicks G1 to the runq, 3) runqget on pp empties runqnext.
+ // Simply observing that runqhead == runqtail and then observing that runqnext == nil
+ // does not mean the queue is empty.
+ for {
+ head := atomic.Load(&pp.runqhead)
+ tail := atomic.Load(&pp.runqtail)
+ runnext := atomic.Loaduintptr((*uintptr)(unsafe.Pointer(&pp.runnext)))
+ if tail == atomic.Load(&pp.runqtail) {
+ return head == tail && runnext == 0
+ }
+ }
+}
+
+// To shake out latent assumptions about scheduling order,
+// we introduce some randomness into scheduling decisions
+// when running with the race detector.
+// The need for this was made obvious by changing the
+// (deterministic) scheduling order in Go 1.5 and breaking
+// many poorly-written tests.
+// With the randomness here, as long as the tests pass
+// consistently with -race, they shouldn't have latent scheduling
+// assumptions.
+const randomizeScheduler = raceenabled
+
+// runqput tries to put g on the local runnable queue.
+// If next is false, runqput adds g to the tail of the runnable queue.
+// If next is true, runqput puts g in the pp.runnext slot.
+// If the run queue is full, runnext puts g on the global queue.
+// Executed only by the owner P.
+func runqput(pp *p, gp *g, next bool) {
+ if randomizeScheduler && next && fastrandn(2) == 0 {
+ next = false
+ }
+
+ if next {
+ retryNext:
+ oldnext := pp.runnext
+ if !pp.runnext.cas(oldnext, guintptr(unsafe.Pointer(gp))) {
+ goto retryNext
+ }
+ if oldnext == 0 {
+ return
+ }
+ // Kick the old runnext out to the regular run queue.
+ gp = oldnext.ptr()
+ }
+
+retry:
+ h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with consumers
+ t := pp.runqtail
+ if t-h < uint32(len(pp.runq)) {
+ pp.runq[t%uint32(len(pp.runq))].set(gp)
+ atomic.StoreRel(&pp.runqtail, t+1) // store-release, makes the item available for consumption
+ return
+ }
+ if runqputslow(pp, gp, h, t) {
+ return
+ }
+ // the queue is not full, now the put above must succeed
+ goto retry
+}
+
+// Put g and a batch of work from local runnable queue on global queue.
+// Executed only by the owner P.
+func runqputslow(pp *p, gp *g, h, t uint32) bool {
+ var batch [len(pp.runq)/2 + 1]*g
+
+ // First, grab a batch from local queue.
+ n := t - h
+ n = n / 2
+ if n != uint32(len(pp.runq)/2) {
+ throw("runqputslow: queue is not full")
+ }
+ for i := uint32(0); i < n; i++ {
+ batch[i] = pp.runq[(h+i)%uint32(len(pp.runq))].ptr()
+ }
+ if !atomic.CasRel(&pp.runqhead, h, h+n) { // cas-release, commits consume
+ return false
+ }
+ batch[n] = gp
+
+ if randomizeScheduler {
+ for i := uint32(1); i <= n; i++ {
+ j := fastrandn(i + 1)
+ batch[i], batch[j] = batch[j], batch[i]
+ }
+ }
+
+ // Link the goroutines.
+ for i := uint32(0); i < n; i++ {
+ batch[i].schedlink.set(batch[i+1])
+ }
+ var q gQueue
+ q.head.set(batch[0])
+ q.tail.set(batch[n])
+
+ // Now put the batch on global queue.
+ lock(&sched.lock)
+ globrunqputbatch(&q, int32(n+1))
+ unlock(&sched.lock)
+ return true
+}
+
+// runqputbatch tries to put all the G's on q on the local runnable queue.
+// If the queue is full, they are put on the global queue; in that case
+// this will temporarily acquire the scheduler lock.
+// Executed only by the owner P.
+func runqputbatch(pp *p, q *gQueue, qsize int) {
+ h := atomic.LoadAcq(&pp.runqhead)
+ t := pp.runqtail
+ n := uint32(0)
+ for !q.empty() && t-h < uint32(len(pp.runq)) {
+ gp := q.pop()
+ pp.runq[t%uint32(len(pp.runq))].set(gp)
+ t++
+ n++
+ }
+ qsize -= int(n)
+
+ if randomizeScheduler {
+ off := func(o uint32) uint32 {
+ return (pp.runqtail + o) % uint32(len(pp.runq))
+ }
+ for i := uint32(1); i < n; i++ {
+ j := fastrandn(i + 1)
+ pp.runq[off(i)], pp.runq[off(j)] = pp.runq[off(j)], pp.runq[off(i)]
+ }
+ }
+
+ atomic.StoreRel(&pp.runqtail, t)
+ if !q.empty() {
+ lock(&sched.lock)
+ globrunqputbatch(q, int32(qsize))
+ unlock(&sched.lock)
+ }
+}
+
+// Get g from local runnable queue.
+// If inheritTime is true, gp should inherit the remaining time in the
+// current time slice. Otherwise, it should start a new time slice.
+// Executed only by the owner P.
+func runqget(pp *p) (gp *g, inheritTime bool) {
+ // If there's a runnext, it's the next G to run.
+ next := pp.runnext
+ // If the runnext is non-0 and the CAS fails, it could only have been stolen by another P,
+ // because other Ps can race to set runnext to 0, but only the current P can set it to non-0.
+ // Hence, there's no need to retry this CAS if it fails.
+ if next != 0 && pp.runnext.cas(next, 0) {
+ return next.ptr(), true
+ }
+
+ for {
+ h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with other consumers
+ t := pp.runqtail
+ if t == h {
+ return nil, false
+ }
+ gp := pp.runq[h%uint32(len(pp.runq))].ptr()
+ if atomic.CasRel(&pp.runqhead, h, h+1) { // cas-release, commits consume
+ return gp, false
+ }
+ }
+}
+
+// runqdrain drains the local runnable queue of pp and returns all goroutines in it.
+// Executed only by the owner P.
+func runqdrain(pp *p) (drainQ gQueue, n uint32) {
+ oldNext := pp.runnext
+ if oldNext != 0 && pp.runnext.cas(oldNext, 0) {
+ drainQ.pushBack(oldNext.ptr())
+ n++
+ }
+
+retry:
+ h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with other consumers
+ t := pp.runqtail
+ qn := t - h
+ if qn == 0 {
+ return
+ }
+ if qn > uint32(len(pp.runq)) { // read inconsistent h and t
+ goto retry
+ }
+
+ if !atomic.CasRel(&pp.runqhead, h, h+qn) { // cas-release, commits consume
+ goto retry
+ }
+
+ // We've inverted the order in which it gets G's from the local P's runnable queue
+ // and then advances the head pointer because we don't want to mess up the statuses of G's
+ // while runqdrain() and runqsteal() are running in parallel.
+ // Thus we should advance the head pointer before draining the local P into a gQueue,
+ // so that we can update any gp.schedlink only after we take the full ownership of G,
+ // meanwhile, other P's can't access to all G's in local P's runnable queue and steal them.
+ // See https://groups.google.com/g/golang-dev/c/0pTKxEKhHSc/m/6Q85QjdVBQAJ for more details.
+ for i := uint32(0); i < qn; i++ {
+ gp := pp.runq[(h+i)%uint32(len(pp.runq))].ptr()
+ drainQ.pushBack(gp)
+ n++
+ }
+ return
+}
+
+// Grabs a batch of goroutines from pp's runnable queue into batch.
+// Batch is a ring buffer starting at batchHead.
+// Returns number of grabbed goroutines.
+// Can be executed by any P.
+func runqgrab(pp *p, batch *[256]guintptr, batchHead uint32, stealRunNextG bool) uint32 {
+ for {
+ h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with other consumers
+ t := atomic.LoadAcq(&pp.runqtail) // load-acquire, synchronize with the producer
+ n := t - h
+ n = n - n/2
+ if n == 0 {
+ if stealRunNextG {
+ // Try to steal from pp.runnext.
+ if next := pp.runnext; next != 0 {
+ if pp.status == _Prunning {
+ // Sleep to ensure that pp isn't about to run the g
+ // we are about to steal.
+ // The important use case here is when the g running
+ // on pp ready()s another g and then almost
+ // immediately blocks. Instead of stealing runnext
+ // in this window, back off to give pp a chance to
+ // schedule runnext. This will avoid thrashing gs
+ // between different Ps.
+ // A sync chan send/recv takes ~50ns as of time of
+ // writing, so 3us gives ~50x overshoot.
+ if GOOS != "windows" && GOOS != "openbsd" && GOOS != "netbsd" {
+ usleep(3)
+ } else {
+ // On some platforms system timer granularity is
+ // 1-15ms, which is way too much for this
+ // optimization. So just yield.
+ osyield()
+ }
+ }
+ if !pp.runnext.cas(next, 0) {
+ continue
+ }
+ batch[batchHead%uint32(len(batch))] = next
+ return 1
+ }
+ }
+ return 0
+ }
+ if n > uint32(len(pp.runq)/2) { // read inconsistent h and t
+ continue
+ }
+ for i := uint32(0); i < n; i++ {
+ g := pp.runq[(h+i)%uint32(len(pp.runq))]
+ batch[(batchHead+i)%uint32(len(batch))] = g
+ }
+ if atomic.CasRel(&pp.runqhead, h, h+n) { // cas-release, commits consume
+ return n
+ }
+ }
+}
+
+// Steal half of elements from local runnable queue of p2
+// and put onto local runnable queue of p.
+// Returns one of the stolen elements (or nil if failed).
+func runqsteal(pp, p2 *p, stealRunNextG bool) *g {
+ t := pp.runqtail
+ n := runqgrab(p2, &pp.runq, t, stealRunNextG)
+ if n == 0 {
+ return nil
+ }
+ n--
+ gp := pp.runq[(t+n)%uint32(len(pp.runq))].ptr()
+ if n == 0 {
+ return gp
+ }
+ h := atomic.LoadAcq(&pp.runqhead) // load-acquire, synchronize with consumers
+ if t-h+n >= uint32(len(pp.runq)) {
+ throw("runqsteal: runq overflow")
+ }
+ atomic.StoreRel(&pp.runqtail, t+n) // store-release, makes the item available for consumption
+ return gp
+}
+
+// A gQueue is a dequeue of Gs linked through g.schedlink. A G can only
+// be on one gQueue or gList at a time.
+type gQueue struct {
+ head guintptr
+ tail guintptr
+}
+
+// empty reports whether q is empty.
+func (q *gQueue) empty() bool {
+ return q.head == 0
+}
+
+// push adds gp to the head of q.
+func (q *gQueue) push(gp *g) {
+ gp.schedlink = q.head
+ q.head.set(gp)
+ if q.tail == 0 {
+ q.tail.set(gp)
+ }
+}
+
+// pushBack adds gp to the tail of q.
+func (q *gQueue) pushBack(gp *g) {
+ gp.schedlink = 0
+ if q.tail != 0 {
+ q.tail.ptr().schedlink.set(gp)
+ } else {
+ q.head.set(gp)
+ }
+ q.tail.set(gp)
+}
+
+// pushBackAll adds all Gs in q2 to the tail of q. After this q2 must
+// not be used.
+func (q *gQueue) pushBackAll(q2 gQueue) {
+ if q2.tail == 0 {
+ return
+ }
+ q2.tail.ptr().schedlink = 0
+ if q.tail != 0 {
+ q.tail.ptr().schedlink = q2.head
+ } else {
+ q.head = q2.head
+ }
+ q.tail = q2.tail
+}
+
+// pop removes and returns the head of queue q. It returns nil if
+// q is empty.
+func (q *gQueue) pop() *g {
+ gp := q.head.ptr()
+ if gp != nil {
+ q.head = gp.schedlink
+ if q.head == 0 {
+ q.tail = 0
+ }
+ }
+ return gp
+}
+
+// popList takes all Gs in q and returns them as a gList.
+func (q *gQueue) popList() gList {
+ stack := gList{q.head}
+ *q = gQueue{}
+ return stack
+}
+
+// A gList is a list of Gs linked through g.schedlink. A G can only be
+// on one gQueue or gList at a time.
+type gList struct {
+ head guintptr
+}
+
+// empty reports whether l is empty.
+func (l *gList) empty() bool {
+ return l.head == 0
+}
+
+// push adds gp to the head of l.
+func (l *gList) push(gp *g) {
+ gp.schedlink = l.head
+ l.head.set(gp)
+}
+
+// pushAll prepends all Gs in q to l.
+func (l *gList) pushAll(q gQueue) {
+ if !q.empty() {
+ q.tail.ptr().schedlink = l.head
+ l.head = q.head
+ }
+}
+
+// pop removes and returns the head of l. If l is empty, it returns nil.
+func (l *gList) pop() *g {
+ gp := l.head.ptr()
+ if gp != nil {
+ l.head = gp.schedlink
+ }
+ return gp
+}
+
+//go:linkname setMaxThreads runtime/debug.setMaxThreads
+func setMaxThreads(in int) (out int) {
+ lock(&sched.lock)
+ out = int(sched.maxmcount)
+ if in > 0x7fffffff { // MaxInt32
+ sched.maxmcount = 0x7fffffff
+ } else {
+ sched.maxmcount = int32(in)
+ }
+ checkmcount()
+ unlock(&sched.lock)
+ return
+}
+
+//go:nosplit
+func procPin() int {
+ gp := getg()
+ mp := gp.m
+
+ mp.locks++
+ return int(mp.p.ptr().id)
+}
+
+//go:nosplit
+func procUnpin() {
+ gp := getg()
+ gp.m.locks--
+}
+
+//go:linkname sync_runtime_procPin sync.runtime_procPin
+//go:nosplit
+func sync_runtime_procPin() int {
+ return procPin()
+}
+
+//go:linkname sync_runtime_procUnpin sync.runtime_procUnpin
+//go:nosplit
+func sync_runtime_procUnpin() {
+ procUnpin()
+}
+
+//go:linkname sync_atomic_runtime_procPin sync/atomic.runtime_procPin
+//go:nosplit
+func sync_atomic_runtime_procPin() int {
+ return procPin()
+}
+
+//go:linkname sync_atomic_runtime_procUnpin sync/atomic.runtime_procUnpin
+//go:nosplit
+func sync_atomic_runtime_procUnpin() {
+ procUnpin()
+}
+
+// Active spinning for sync.Mutex.
+//
+//go:linkname sync_runtime_canSpin sync.runtime_canSpin
+//go:nosplit
+func sync_runtime_canSpin(i int) bool {
+ // sync.Mutex is cooperative, so we are conservative with spinning.
+ // Spin only few times and only if running on a multicore machine and
+ // GOMAXPROCS>1 and there is at least one other running P and local runq is empty.
+ // As opposed to runtime mutex we don't do passive spinning here,
+ // because there can be work on global runq or on other Ps.
+ if i >= active_spin || ncpu <= 1 || gomaxprocs <= sched.npidle.Load()+sched.nmspinning.Load()+1 {
+ return false
+ }
+ if p := getg().m.p.ptr(); !runqempty(p) {
+ return false
+ }
+ return true
+}
+
+//go:linkname sync_runtime_doSpin sync.runtime_doSpin
+//go:nosplit
+func sync_runtime_doSpin() {
+ procyield(active_spin_cnt)
+}
+
+var stealOrder randomOrder
+
+// randomOrder/randomEnum are helper types for randomized work stealing.
+// They allow to enumerate all Ps in different pseudo-random orders without repetitions.
+// The algorithm is based on the fact that if we have X such that X and GOMAXPROCS
+// are coprime, then a sequences of (i + X) % GOMAXPROCS gives the required enumeration.
+type randomOrder struct {
+ count uint32
+ coprimes []uint32
+}
+
+type randomEnum struct {
+ i uint32
+ count uint32
+ pos uint32
+ inc uint32
+}
+
+func (ord *randomOrder) reset(count uint32) {
+ ord.count = count
+ ord.coprimes = ord.coprimes[:0]
+ for i := uint32(1); i <= count; i++ {
+ if gcd(i, count) == 1 {
+ ord.coprimes = append(ord.coprimes, i)
+ }
+ }
+}
+
+func (ord *randomOrder) start(i uint32) randomEnum {
+ return randomEnum{
+ count: ord.count,
+ pos: i % ord.count,
+ inc: ord.coprimes[i/ord.count%uint32(len(ord.coprimes))],
+ }
+}
+
+func (enum *randomEnum) done() bool {
+ return enum.i == enum.count
+}
+
+func (enum *randomEnum) next() {
+ enum.i++
+ enum.pos = (enum.pos + enum.inc) % enum.count
+}
+
+func (enum *randomEnum) position() uint32 {
+ return enum.pos
+}
+
+func gcd(a, b uint32) uint32 {
+ for b != 0 {
+ a, b = b, a%b
+ }
+ return a
+}
+
+// An initTask represents the set of initializations that need to be done for a package.
+// Keep in sync with ../../test/noinit.go:initTask
+type initTask struct {
+ state uint32 // 0 = uninitialized, 1 = in progress, 2 = done
+ nfns uint32
+ // followed by nfns pcs, uintptr sized, one per init function to run
+}
+
+// inittrace stores statistics for init functions which are
+// updated by malloc and newproc when active is true.
+var inittrace tracestat
+
+type tracestat struct {
+ active bool // init tracing activation status
+ id uint64 // init goroutine id
+ allocs uint64 // heap allocations
+ bytes uint64 // heap allocated bytes
+}
+
+func doInit(ts []*initTask) {
+ for _, t := range ts {
+ doInit1(t)
+ }
+}
+
+func doInit1(t *initTask) {
+ switch t.state {
+ case 2: // fully initialized
+ return
+ case 1: // initialization in progress
+ throw("recursive call during initialization - linker skew")
+ default: // not initialized yet
+ t.state = 1 // initialization in progress
+
+ var (
+ start int64
+ before tracestat
+ )
+
+ if inittrace.active {
+ start = nanotime()
+ // Load stats non-atomically since tracinit is updated only by this init goroutine.
+ before = inittrace
+ }
+
+ if t.nfns == 0 {
+ // We should have pruned all of these in the linker.
+ throw("inittask with no functions")
+ }
+
+ firstFunc := add(unsafe.Pointer(t), 8)
+ for i := uint32(0); i < t.nfns; i++ {
+ p := add(firstFunc, uintptr(i)*goarch.PtrSize)
+ f := *(*func())(unsafe.Pointer(&p))
+ f()
+ }
+
+ if inittrace.active {
+ end := nanotime()
+ // Load stats non-atomically since tracinit is updated only by this init goroutine.
+ after := inittrace
+
+ f := *(*func())(unsafe.Pointer(&firstFunc))
+ pkg := funcpkgpath(findfunc(abi.FuncPCABIInternal(f)))
+
+ var sbuf [24]byte
+ print("init ", pkg, " @")
+ print(string(fmtNSAsMS(sbuf[:], uint64(start-runtimeInitTime))), " ms, ")
+ print(string(fmtNSAsMS(sbuf[:], uint64(end-start))), " ms clock, ")
+ print(string(itoa(sbuf[:], after.bytes-before.bytes)), " bytes, ")
+ print(string(itoa(sbuf[:], after.allocs-before.allocs)), " allocs")
+ print("\n")
+ }
+
+ t.state = 2 // initialization done
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/profbuf.go b/contrib/go/_std_1.21/src/runtime/profbuf.go
new file mode 100644
index 0000000000..083b55a922
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/profbuf.go
@@ -0,0 +1,561 @@
+// Copyright 2017 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 runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// A profBuf is a lock-free buffer for profiling events,
+// safe for concurrent use by one reader and one writer.
+// The writer may be a signal handler running without a user g.
+// The reader is assumed to be a user g.
+//
+// Each logged event corresponds to a fixed size header, a list of
+// uintptrs (typically a stack), and exactly one unsafe.Pointer tag.
+// The header and uintptrs are stored in the circular buffer data and the
+// tag is stored in a circular buffer tags, running in parallel.
+// In the circular buffer data, each event takes 2+hdrsize+len(stk)
+// words: the value 2+hdrsize+len(stk), then the time of the event, then
+// hdrsize words giving the fixed-size header, and then len(stk) words
+// for the stack.
+//
+// The current effective offsets into the tags and data circular buffers
+// for reading and writing are stored in the high 30 and low 32 bits of r and w.
+// The bottom bits of the high 32 are additional flag bits in w, unused in r.
+// "Effective" offsets means the total number of reads or writes, mod 2^length.
+// The offset in the buffer is the effective offset mod the length of the buffer.
+// To make wraparound mod 2^length match wraparound mod length of the buffer,
+// the length of the buffer must be a power of two.
+//
+// If the reader catches up to the writer, a flag passed to read controls
+// whether the read blocks until more data is available. A read returns a
+// pointer to the buffer data itself; the caller is assumed to be done with
+// that data at the next read. The read offset rNext tracks the next offset to
+// be returned by read. By definition, r ≤ rNext ≤ w (before wraparound),
+// and rNext is only used by the reader, so it can be accessed without atomics.
+//
+// If the writer gets ahead of the reader, so that the buffer fills,
+// future writes are discarded and replaced in the output stream by an
+// overflow entry, which has size 2+hdrsize+1, time set to the time of
+// the first discarded write, a header of all zeroed words, and a "stack"
+// containing one word, the number of discarded writes.
+//
+// Between the time the buffer fills and the buffer becomes empty enough
+// to hold more data, the overflow entry is stored as a pending overflow
+// entry in the fields overflow and overflowTime. The pending overflow
+// entry can be turned into a real record by either the writer or the
+// reader. If the writer is called to write a new record and finds that
+// the output buffer has room for both the pending overflow entry and the
+// new record, the writer emits the pending overflow entry and the new
+// record into the buffer. If the reader is called to read data and finds
+// that the output buffer is empty but that there is a pending overflow
+// entry, the reader will return a synthesized record for the pending
+// overflow entry.
+//
+// Only the writer can create or add to a pending overflow entry, but
+// either the reader or the writer can clear the pending overflow entry.
+// A pending overflow entry is indicated by the low 32 bits of 'overflow'
+// holding the number of discarded writes, and overflowTime holding the
+// time of the first discarded write. The high 32 bits of 'overflow'
+// increment each time the low 32 bits transition from zero to non-zero
+// or vice versa. This sequence number avoids ABA problems in the use of
+// compare-and-swap to coordinate between reader and writer.
+// The overflowTime is only written when the low 32 bits of overflow are
+// zero, that is, only when there is no pending overflow entry, in
+// preparation for creating a new one. The reader can therefore fetch and
+// clear the entry atomically using
+//
+// for {
+// overflow = load(&b.overflow)
+// if uint32(overflow) == 0 {
+// // no pending entry
+// break
+// }
+// time = load(&b.overflowTime)
+// if cas(&b.overflow, overflow, ((overflow>>32)+1)<<32) {
+// // pending entry cleared
+// break
+// }
+// }
+// if uint32(overflow) > 0 {
+// emit entry for uint32(overflow), time
+// }
+type profBuf struct {
+ // accessed atomically
+ r, w profAtomic
+ overflow atomic.Uint64
+ overflowTime atomic.Uint64
+ eof atomic.Uint32
+
+ // immutable (excluding slice content)
+ hdrsize uintptr
+ data []uint64
+ tags []unsafe.Pointer
+
+ // owned by reader
+ rNext profIndex
+ overflowBuf []uint64 // for use by reader to return overflow record
+ wait note
+}
+
+// A profAtomic is the atomically-accessed word holding a profIndex.
+type profAtomic uint64
+
+// A profIndex is the packet tag and data counts and flags bits, described above.
+type profIndex uint64
+
+const (
+ profReaderSleeping profIndex = 1 << 32 // reader is sleeping and must be woken up
+ profWriteExtra profIndex = 1 << 33 // overflow or eof waiting
+)
+
+func (x *profAtomic) load() profIndex {
+ return profIndex(atomic.Load64((*uint64)(x)))
+}
+
+func (x *profAtomic) store(new profIndex) {
+ atomic.Store64((*uint64)(x), uint64(new))
+}
+
+func (x *profAtomic) cas(old, new profIndex) bool {
+ return atomic.Cas64((*uint64)(x), uint64(old), uint64(new))
+}
+
+func (x profIndex) dataCount() uint32 {
+ return uint32(x)
+}
+
+func (x profIndex) tagCount() uint32 {
+ return uint32(x >> 34)
+}
+
+// countSub subtracts two counts obtained from profIndex.dataCount or profIndex.tagCount,
+// assuming that they are no more than 2^29 apart (guaranteed since they are never more than
+// len(data) or len(tags) apart, respectively).
+// tagCount wraps at 2^30, while dataCount wraps at 2^32.
+// This function works for both.
+func countSub(x, y uint32) int {
+ // x-y is 32-bit signed or 30-bit signed; sign-extend to 32 bits and convert to int.
+ return int(int32(x-y) << 2 >> 2)
+}
+
+// addCountsAndClearFlags returns the packed form of "x + (data, tag) - all flags".
+func (x profIndex) addCountsAndClearFlags(data, tag int) profIndex {
+ return profIndex((uint64(x)>>34+uint64(uint32(tag)<<2>>2))<<34 | uint64(uint32(x)+uint32(data)))
+}
+
+// hasOverflow reports whether b has any overflow records pending.
+func (b *profBuf) hasOverflow() bool {
+ return uint32(b.overflow.Load()) > 0
+}
+
+// takeOverflow consumes the pending overflow records, returning the overflow count
+// and the time of the first overflow.
+// When called by the reader, it is racing against incrementOverflow.
+func (b *profBuf) takeOverflow() (count uint32, time uint64) {
+ overflow := b.overflow.Load()
+ time = b.overflowTime.Load()
+ for {
+ count = uint32(overflow)
+ if count == 0 {
+ time = 0
+ break
+ }
+ // Increment generation, clear overflow count in low bits.
+ if b.overflow.CompareAndSwap(overflow, ((overflow>>32)+1)<<32) {
+ break
+ }
+ overflow = b.overflow.Load()
+ time = b.overflowTime.Load()
+ }
+ return uint32(overflow), time
+}
+
+// incrementOverflow records a single overflow at time now.
+// It is racing against a possible takeOverflow in the reader.
+func (b *profBuf) incrementOverflow(now int64) {
+ for {
+ overflow := b.overflow.Load()
+
+ // Once we see b.overflow reach 0, it's stable: no one else is changing it underfoot.
+ // We need to set overflowTime if we're incrementing b.overflow from 0.
+ if uint32(overflow) == 0 {
+ // Store overflowTime first so it's always available when overflow != 0.
+ b.overflowTime.Store(uint64(now))
+ b.overflow.Store((((overflow >> 32) + 1) << 32) + 1)
+ break
+ }
+ // Otherwise we're racing to increment against reader
+ // who wants to set b.overflow to 0.
+ // Out of paranoia, leave 2³²-1 a sticky overflow value,
+ // to avoid wrapping around. Extremely unlikely.
+ if int32(overflow) == -1 {
+ break
+ }
+ if b.overflow.CompareAndSwap(overflow, overflow+1) {
+ break
+ }
+ }
+}
+
+// newProfBuf returns a new profiling buffer with room for
+// a header of hdrsize words and a buffer of at least bufwords words.
+func newProfBuf(hdrsize, bufwords, tags int) *profBuf {
+ if min := 2 + hdrsize + 1; bufwords < min {
+ bufwords = min
+ }
+
+ // Buffer sizes must be power of two, so that we don't have to
+ // worry about uint32 wraparound changing the effective position
+ // within the buffers. We store 30 bits of count; limiting to 28
+ // gives us some room for intermediate calculations.
+ if bufwords >= 1<<28 || tags >= 1<<28 {
+ throw("newProfBuf: buffer too large")
+ }
+ var i int
+ for i = 1; i < bufwords; i <<= 1 {
+ }
+ bufwords = i
+ for i = 1; i < tags; i <<= 1 {
+ }
+ tags = i
+
+ b := new(profBuf)
+ b.hdrsize = uintptr(hdrsize)
+ b.data = make([]uint64, bufwords)
+ b.tags = make([]unsafe.Pointer, tags)
+ b.overflowBuf = make([]uint64, 2+b.hdrsize+1)
+ return b
+}
+
+// canWriteRecord reports whether the buffer has room
+// for a single contiguous record with a stack of length nstk.
+func (b *profBuf) canWriteRecord(nstk int) bool {
+ br := b.r.load()
+ bw := b.w.load()
+
+ // room for tag?
+ if countSub(br.tagCount(), bw.tagCount())+len(b.tags) < 1 {
+ return false
+ }
+
+ // room for data?
+ nd := countSub(br.dataCount(), bw.dataCount()) + len(b.data)
+ want := 2 + int(b.hdrsize) + nstk
+ i := int(bw.dataCount() % uint32(len(b.data)))
+ if i+want > len(b.data) {
+ // Can't fit in trailing fragment of slice.
+ // Skip over that and start over at beginning of slice.
+ nd -= len(b.data) - i
+ }
+ return nd >= want
+}
+
+// canWriteTwoRecords reports whether the buffer has room
+// for two records with stack lengths nstk1, nstk2, in that order.
+// Each record must be contiguous on its own, but the two
+// records need not be contiguous (one can be at the end of the buffer
+// and the other can wrap around and start at the beginning of the buffer).
+func (b *profBuf) canWriteTwoRecords(nstk1, nstk2 int) bool {
+ br := b.r.load()
+ bw := b.w.load()
+
+ // room for tag?
+ if countSub(br.tagCount(), bw.tagCount())+len(b.tags) < 2 {
+ return false
+ }
+
+ // room for data?
+ nd := countSub(br.dataCount(), bw.dataCount()) + len(b.data)
+
+ // first record
+ want := 2 + int(b.hdrsize) + nstk1
+ i := int(bw.dataCount() % uint32(len(b.data)))
+ if i+want > len(b.data) {
+ // Can't fit in trailing fragment of slice.
+ // Skip over that and start over at beginning of slice.
+ nd -= len(b.data) - i
+ i = 0
+ }
+ i += want
+ nd -= want
+
+ // second record
+ want = 2 + int(b.hdrsize) + nstk2
+ if i+want > len(b.data) {
+ // Can't fit in trailing fragment of slice.
+ // Skip over that and start over at beginning of slice.
+ nd -= len(b.data) - i
+ i = 0
+ }
+ return nd >= want
+}
+
+// write writes an entry to the profiling buffer b.
+// The entry begins with a fixed hdr, which must have
+// length b.hdrsize, followed by a variable-sized stack
+// and a single tag pointer *tagPtr (or nil if tagPtr is nil).
+// No write barriers allowed because this might be called from a signal handler.
+func (b *profBuf) write(tagPtr *unsafe.Pointer, now int64, hdr []uint64, stk []uintptr) {
+ if b == nil {
+ return
+ }
+ if len(hdr) > int(b.hdrsize) {
+ throw("misuse of profBuf.write")
+ }
+
+ if hasOverflow := b.hasOverflow(); hasOverflow && b.canWriteTwoRecords(1, len(stk)) {
+ // Room for both an overflow record and the one being written.
+ // Write the overflow record if the reader hasn't gotten to it yet.
+ // Only racing against reader, not other writers.
+ count, time := b.takeOverflow()
+ if count > 0 {
+ var stk [1]uintptr
+ stk[0] = uintptr(count)
+ b.write(nil, int64(time), nil, stk[:])
+ }
+ } else if hasOverflow || !b.canWriteRecord(len(stk)) {
+ // Pending overflow without room to write overflow and new records
+ // or no overflow but also no room for new record.
+ b.incrementOverflow(now)
+ b.wakeupExtra()
+ return
+ }
+
+ // There's room: write the record.
+ br := b.r.load()
+ bw := b.w.load()
+
+ // Profiling tag
+ //
+ // The tag is a pointer, but we can't run a write barrier here.
+ // We have interrupted the OS-level execution of gp, but the
+ // runtime still sees gp as executing. In effect, we are running
+ // in place of the real gp. Since gp is the only goroutine that
+ // can overwrite gp.labels, the value of gp.labels is stable during
+ // this signal handler: it will still be reachable from gp when
+ // we finish executing. If a GC is in progress right now, it must
+ // keep gp.labels alive, because gp.labels is reachable from gp.
+ // If gp were to overwrite gp.labels, the deletion barrier would
+ // still shade that pointer, which would preserve it for the
+ // in-progress GC, so all is well. Any future GC will see the
+ // value we copied when scanning b.tags (heap-allocated).
+ // We arrange that the store here is always overwriting a nil,
+ // so there is no need for a deletion barrier on b.tags[wt].
+ wt := int(bw.tagCount() % uint32(len(b.tags)))
+ if tagPtr != nil {
+ *(*uintptr)(unsafe.Pointer(&b.tags[wt])) = uintptr(unsafe.Pointer(*tagPtr))
+ }
+
+ // Main record.
+ // It has to fit in a contiguous section of the slice, so if it doesn't fit at the end,
+ // leave a rewind marker (0) and start over at the beginning of the slice.
+ wd := int(bw.dataCount() % uint32(len(b.data)))
+ nd := countSub(br.dataCount(), bw.dataCount()) + len(b.data)
+ skip := 0
+ if wd+2+int(b.hdrsize)+len(stk) > len(b.data) {
+ b.data[wd] = 0
+ skip = len(b.data) - wd
+ nd -= skip
+ wd = 0
+ }
+ data := b.data[wd:]
+ data[0] = uint64(2 + b.hdrsize + uintptr(len(stk))) // length
+ data[1] = uint64(now) // time stamp
+ // header, zero-padded
+ i := uintptr(copy(data[2:2+b.hdrsize], hdr))
+ for ; i < b.hdrsize; i++ {
+ data[2+i] = 0
+ }
+ for i, pc := range stk {
+ data[2+b.hdrsize+uintptr(i)] = uint64(pc)
+ }
+
+ for {
+ // Commit write.
+ // Racing with reader setting flag bits in b.w, to avoid lost wakeups.
+ old := b.w.load()
+ new := old.addCountsAndClearFlags(skip+2+len(stk)+int(b.hdrsize), 1)
+ if !b.w.cas(old, new) {
+ continue
+ }
+ // If there was a reader, wake it up.
+ if old&profReaderSleeping != 0 {
+ notewakeup(&b.wait)
+ }
+ break
+ }
+}
+
+// close signals that there will be no more writes on the buffer.
+// Once all the data has been read from the buffer, reads will return eof=true.
+func (b *profBuf) close() {
+ if b.eof.Load() > 0 {
+ throw("runtime: profBuf already closed")
+ }
+ b.eof.Store(1)
+ b.wakeupExtra()
+}
+
+// wakeupExtra must be called after setting one of the "extra"
+// atomic fields b.overflow or b.eof.
+// It records the change in b.w and wakes up the reader if needed.
+func (b *profBuf) wakeupExtra() {
+ for {
+ old := b.w.load()
+ new := old | profWriteExtra
+ if !b.w.cas(old, new) {
+ continue
+ }
+ if old&profReaderSleeping != 0 {
+ notewakeup(&b.wait)
+ }
+ break
+ }
+}
+
+// profBufReadMode specifies whether to block when no data is available to read.
+type profBufReadMode int
+
+const (
+ profBufBlocking profBufReadMode = iota
+ profBufNonBlocking
+)
+
+var overflowTag [1]unsafe.Pointer // always nil
+
+func (b *profBuf) read(mode profBufReadMode) (data []uint64, tags []unsafe.Pointer, eof bool) {
+ if b == nil {
+ return nil, nil, true
+ }
+
+ br := b.rNext
+
+ // Commit previous read, returning that part of the ring to the writer.
+ // First clear tags that have now been read, both to avoid holding
+ // up the memory they point at for longer than necessary
+ // and so that b.write can assume it is always overwriting
+ // nil tag entries (see comment in b.write).
+ rPrev := b.r.load()
+ if rPrev != br {
+ ntag := countSub(br.tagCount(), rPrev.tagCount())
+ ti := int(rPrev.tagCount() % uint32(len(b.tags)))
+ for i := 0; i < ntag; i++ {
+ b.tags[ti] = nil
+ if ti++; ti == len(b.tags) {
+ ti = 0
+ }
+ }
+ b.r.store(br)
+ }
+
+Read:
+ bw := b.w.load()
+ numData := countSub(bw.dataCount(), br.dataCount())
+ if numData == 0 {
+ if b.hasOverflow() {
+ // No data to read, but there is overflow to report.
+ // Racing with writer flushing b.overflow into a real record.
+ count, time := b.takeOverflow()
+ if count == 0 {
+ // Lost the race, go around again.
+ goto Read
+ }
+ // Won the race, report overflow.
+ dst := b.overflowBuf
+ dst[0] = uint64(2 + b.hdrsize + 1)
+ dst[1] = uint64(time)
+ for i := uintptr(0); i < b.hdrsize; i++ {
+ dst[2+i] = 0
+ }
+ dst[2+b.hdrsize] = uint64(count)
+ return dst[:2+b.hdrsize+1], overflowTag[:1], false
+ }
+ if b.eof.Load() > 0 {
+ // No data, no overflow, EOF set: done.
+ return nil, nil, true
+ }
+ if bw&profWriteExtra != 0 {
+ // Writer claims to have published extra information (overflow or eof).
+ // Attempt to clear notification and then check again.
+ // If we fail to clear the notification it means b.w changed,
+ // so we still need to check again.
+ b.w.cas(bw, bw&^profWriteExtra)
+ goto Read
+ }
+
+ // Nothing to read right now.
+ // Return or sleep according to mode.
+ if mode == profBufNonBlocking {
+ // Necessary on Darwin, notetsleepg below does not work in signal handler, root cause of #61768.
+ return nil, nil, false
+ }
+ if !b.w.cas(bw, bw|profReaderSleeping) {
+ goto Read
+ }
+ // Committed to sleeping.
+ notetsleepg(&b.wait, -1)
+ noteclear(&b.wait)
+ goto Read
+ }
+ data = b.data[br.dataCount()%uint32(len(b.data)):]
+ if len(data) > numData {
+ data = data[:numData]
+ } else {
+ numData -= len(data) // available in case of wraparound
+ }
+ skip := 0
+ if data[0] == 0 {
+ // Wraparound record. Go back to the beginning of the ring.
+ skip = len(data)
+ data = b.data
+ if len(data) > numData {
+ data = data[:numData]
+ }
+ }
+
+ ntag := countSub(bw.tagCount(), br.tagCount())
+ if ntag == 0 {
+ throw("runtime: malformed profBuf buffer - tag and data out of sync")
+ }
+ tags = b.tags[br.tagCount()%uint32(len(b.tags)):]
+ if len(tags) > ntag {
+ tags = tags[:ntag]
+ }
+
+ // Count out whole data records until either data or tags is done.
+ // They are always in sync in the buffer, but due to an end-of-slice
+ // wraparound we might need to stop early and return the rest
+ // in the next call.
+ di := 0
+ ti := 0
+ for di < len(data) && data[di] != 0 && ti < len(tags) {
+ if uintptr(di)+uintptr(data[di]) > uintptr(len(data)) {
+ throw("runtime: malformed profBuf buffer - invalid size")
+ }
+ di += int(data[di])
+ ti++
+ }
+
+ // Remember how much we returned, to commit read on next call.
+ b.rNext = br.addCountsAndClearFlags(skip+di, ti)
+
+ if raceenabled {
+ // Match racereleasemerge in runtime_setProfLabel,
+ // so that the setting of the labels in runtime_setProfLabel
+ // is treated as happening before any use of the labels
+ // by our caller. The synchronization on labelSync itself is a fiction
+ // for the race detector. The actual synchronization is handled
+ // by the fact that the signal handler only reads from the current
+ // goroutine and uses atomics to write the updated queue indices,
+ // and then the read-out from the signal handler buffer uses
+ // atomics to read those queue indices.
+ raceacquire(unsafe.Pointer(&labelSync))
+ }
+
+ return data[:di], tags[:ti], false
+}
diff --git a/contrib/go/_std_1.20/src/runtime/proflabel.go b/contrib/go/_std_1.21/src/runtime/proflabel.go
index b2a161729e..b2a161729e 100644
--- a/contrib/go/_std_1.20/src/runtime/proflabel.go
+++ b/contrib/go/_std_1.21/src/runtime/proflabel.go
diff --git a/contrib/go/_std_1.20/src/runtime/race/doc.go b/contrib/go/_std_1.21/src/runtime/race/doc.go
index 60a20df5bf..60a20df5bf 100644
--- a/contrib/go/_std_1.20/src/runtime/race/doc.go
+++ b/contrib/go/_std_1.21/src/runtime/race/doc.go
diff --git a/contrib/go/_std_1.20/src/runtime/race/internal/amd64v1/doc.go b/contrib/go/_std_1.21/src/runtime/race/internal/amd64v1/doc.go
index ccb088cc46..ccb088cc46 100644
--- a/contrib/go/_std_1.20/src/runtime/race/internal/amd64v1/doc.go
+++ b/contrib/go/_std_1.21/src/runtime/race/internal/amd64v1/doc.go
diff --git a/contrib/go/_std_1.20/src/runtime/race/internal/amd64v1/ya.make b/contrib/go/_std_1.21/src/runtime/race/internal/amd64v1/ya.make
index 785bdc265b..785bdc265b 100644
--- a/contrib/go/_std_1.20/src/runtime/race/internal/amd64v1/ya.make
+++ b/contrib/go/_std_1.21/src/runtime/race/internal/amd64v1/ya.make
diff --git a/contrib/go/_std_1.20/src/runtime/race/internal/ya.make b/contrib/go/_std_1.21/src/runtime/race/internal/ya.make
index 17640e767a..17640e767a 100644
--- a/contrib/go/_std_1.20/src/runtime/race/internal/ya.make
+++ b/contrib/go/_std_1.21/src/runtime/race/internal/ya.make
diff --git a/contrib/go/_std_1.20/src/runtime/race/race_darwin_amd64.go b/contrib/go/_std_1.21/src/runtime/race/race_darwin_amd64.go
index fbb838aa2e..fbb838aa2e 100644
--- a/contrib/go/_std_1.20/src/runtime/race/race_darwin_amd64.go
+++ b/contrib/go/_std_1.21/src/runtime/race/race_darwin_amd64.go
diff --git a/contrib/go/_std_1.20/src/runtime/race/race_linux_arm64.syso b/contrib/go/_std_1.21/src/runtime/race/race_linux_arm64.syso
index c8b3f48ca7..c8b3f48ca7 100644
--- a/contrib/go/_std_1.20/src/runtime/race/race_linux_arm64.syso
+++ b/contrib/go/_std_1.21/src/runtime/race/race_linux_arm64.syso
Binary files differ
diff --git a/contrib/go/_std_1.20/src/runtime/race/race_v1_amd64.go b/contrib/go/_std_1.21/src/runtime/race/race_v1_amd64.go
index 7c40db1dcf..7c40db1dcf 100644
--- a/contrib/go/_std_1.20/src/runtime/race/race_v1_amd64.go
+++ b/contrib/go/_std_1.21/src/runtime/race/race_v1_amd64.go
diff --git a/contrib/go/_std_1.21/src/runtime/race/ya.make b/contrib/go/_std_1.21/src/runtime/race/ya.make
new file mode 100644
index 0000000000..0663618efe
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/race/ya.make
@@ -0,0 +1,51 @@
+GO_LIBRARY()
+
+NO_COMPILER_WARNINGS()
+
+SRCS(
+ doc.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ race_v1_amd64.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ IF (ARCH_X86_64)
+ SRCS(
+ race_darwin_amd64.go
+ )
+ ENDIF()
+ IF (ARCH_ARM64)
+ SRCS(
+ race_darwin_arm64.go
+ race_darwin_arm64.syso
+ )
+ ENDIF()
+ENDIF()
+
+IF (OS_LINUX)
+ IF (ARCH_ARM64)
+ SRCS(
+ race_linux_arm64.syso
+ )
+ ENDIF()
+ENDIF()
+
+IF (RACE)
+ IF (CGO_ENABLED OR OS_DARWIN)
+ CGO_SRCS(
+ race.go
+ )
+ ENDIF()
+ENDIF()
+
+END()
+
+IF (ARCH_X86_64)
+ RECURSE(
+ internal
+ )
+ENDIF()
diff --git a/contrib/go/_std_1.20/src/runtime/race0.go b/contrib/go/_std_1.21/src/runtime/race0.go
index f36d4387c7..f36d4387c7 100644
--- a/contrib/go/_std_1.20/src/runtime/race0.go
+++ b/contrib/go/_std_1.21/src/runtime/race0.go
diff --git a/contrib/go/_std_1.20/src/runtime/rdebug.go b/contrib/go/_std_1.21/src/runtime/rdebug.go
index c1cf2f4f81..c1cf2f4f81 100644
--- a/contrib/go/_std_1.20/src/runtime/rdebug.go
+++ b/contrib/go/_std_1.21/src/runtime/rdebug.go
diff --git a/contrib/go/_std_1.20/src/runtime/retry.go b/contrib/go/_std_1.21/src/runtime/retry.go
index 2e2f813bbc..2e2f813bbc 100644
--- a/contrib/go/_std_1.20/src/runtime/retry.go
+++ b/contrib/go/_std_1.21/src/runtime/retry.go
diff --git a/contrib/go/_std_1.20/src/runtime/rt0_darwin_amd64.s b/contrib/go/_std_1.21/src/runtime/rt0_darwin_amd64.s
index ed804d47c5..ed804d47c5 100644
--- a/contrib/go/_std_1.20/src/runtime/rt0_darwin_amd64.s
+++ b/contrib/go/_std_1.21/src/runtime/rt0_darwin_amd64.s
diff --git a/contrib/go/_std_1.20/src/runtime/rt0_linux_amd64.s b/contrib/go/_std_1.21/src/runtime/rt0_linux_amd64.s
index 94ff7094d6..94ff7094d6 100644
--- a/contrib/go/_std_1.20/src/runtime/rt0_linux_amd64.s
+++ b/contrib/go/_std_1.21/src/runtime/rt0_linux_amd64.s
diff --git a/contrib/go/_std_1.20/src/runtime/rt0_linux_arm64.s b/contrib/go/_std_1.21/src/runtime/rt0_linux_arm64.s
index 0eb8fc2f48..0eb8fc2f48 100644
--- a/contrib/go/_std_1.20/src/runtime/rt0_linux_arm64.s
+++ b/contrib/go/_std_1.21/src/runtime/rt0_linux_arm64.s
diff --git a/contrib/go/_std_1.21/src/runtime/rt0_windows_amd64.s b/contrib/go/_std_1.21/src/runtime/rt0_windows_amd64.s
new file mode 100644
index 0000000000..bd18bdd311
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/rt0_windows_amd64.s
@@ -0,0 +1,36 @@
+// Copyright 2011 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.
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "textflag.h"
+
+TEXT _rt0_amd64_windows(SB),NOSPLIT|NOFRAME,$-8
+ JMP _rt0_amd64(SB)
+
+// When building with -buildmode=(c-shared or c-archive), this
+// symbol is called. For dynamic libraries it is called when the
+// library is loaded. For static libraries it is called when the
+// final executable starts, during the C runtime initialization
+// phase.
+// Leave space for four pointers on the stack as required
+// by the Windows amd64 calling convention.
+TEXT _rt0_amd64_windows_lib(SB),NOSPLIT|NOFRAME,$40
+ // Create a new thread to do the runtime initialization and return.
+ MOVQ BX, 32(SP) // callee-saved, preserved across the CALL
+ MOVQ SP, BX
+ ANDQ $~15, SP // alignment as per Windows requirement
+ MOVQ _cgo_sys_thread_create(SB), AX
+ MOVQ $_rt0_amd64_windows_lib_go(SB), CX
+ MOVQ $0, DX
+ CALL AX
+ MOVQ BX, SP
+ MOVQ 32(SP), BX
+ RET
+
+TEXT _rt0_amd64_windows_lib_go(SB),NOSPLIT|NOFRAME,$0
+ MOVQ $0, DI
+ MOVQ $0, SI
+ MOVQ $runtime·rt0_go(SB), AX
+ JMP AX
diff --git a/contrib/go/_std_1.21/src/runtime/runtime.go b/contrib/go/_std_1.21/src/runtime/runtime.go
new file mode 100644
index 0000000000..0822d0e805
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/runtime.go
@@ -0,0 +1,162 @@
+// Copyright 2009 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 runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+//go:generate go run wincallback.go
+//go:generate go run mkduff.go
+//go:generate go run mkfastlog2table.go
+//go:generate go run mklockrank.go -o lockrank.go
+
+var ticks ticksType
+
+type ticksType struct {
+ lock mutex
+ val atomic.Int64
+}
+
+// Note: Called by runtime/pprof in addition to runtime code.
+func tickspersecond() int64 {
+ r := ticks.val.Load()
+ if r != 0 {
+ return r
+ }
+ lock(&ticks.lock)
+ r = ticks.val.Load()
+ if r == 0 {
+ t0 := nanotime()
+ c0 := cputicks()
+ usleep(100 * 1000)
+ t1 := nanotime()
+ c1 := cputicks()
+ if t1 == t0 {
+ t1++
+ }
+ r = (c1 - c0) * 1000 * 1000 * 1000 / (t1 - t0)
+ if r == 0 {
+ r++
+ }
+ ticks.val.Store(r)
+ }
+ unlock(&ticks.lock)
+ return r
+}
+
+var envs []string
+var argslice []string
+
+//go:linkname syscall_runtime_envs syscall.runtime_envs
+func syscall_runtime_envs() []string { return append([]string{}, envs...) }
+
+//go:linkname syscall_Getpagesize syscall.Getpagesize
+func syscall_Getpagesize() int { return int(physPageSize) }
+
+//go:linkname os_runtime_args os.runtime_args
+func os_runtime_args() []string { return append([]string{}, argslice...) }
+
+//go:linkname syscall_Exit syscall.Exit
+//go:nosplit
+func syscall_Exit(code int) {
+ exit(int32(code))
+}
+
+var godebugDefault string
+var godebugUpdate atomic.Pointer[func(string, string)]
+var godebugEnv atomic.Pointer[string] // set by parsedebugvars
+var godebugNewIncNonDefault atomic.Pointer[func(string) func()]
+
+//go:linkname godebug_setUpdate internal/godebug.setUpdate
+func godebug_setUpdate(update func(string, string)) {
+ p := new(func(string, string))
+ *p = update
+ godebugUpdate.Store(p)
+ godebugNotify(false)
+}
+
+//go:linkname godebug_setNewIncNonDefault internal/godebug.setNewIncNonDefault
+func godebug_setNewIncNonDefault(newIncNonDefault func(string) func()) {
+ p := new(func(string) func())
+ *p = newIncNonDefault
+ godebugNewIncNonDefault.Store(p)
+}
+
+// A godebugInc provides access to internal/godebug's IncNonDefault function
+// for a given GODEBUG setting.
+// Calls before internal/godebug registers itself are dropped on the floor.
+type godebugInc struct {
+ name string
+ inc atomic.Pointer[func()]
+}
+
+func (g *godebugInc) IncNonDefault() {
+ inc := g.inc.Load()
+ if inc == nil {
+ newInc := godebugNewIncNonDefault.Load()
+ if newInc == nil {
+ return
+ }
+ // If other goroutines are racing here, no big deal. One will win,
+ // and all the inc functions will be using the same underlying
+ // *godebug.Setting.
+ inc = new(func())
+ *inc = (*newInc)(g.name)
+ g.inc.Store(inc)
+ }
+ (*inc)()
+}
+
+func godebugNotify(envChanged bool) {
+ update := godebugUpdate.Load()
+ var env string
+ if p := godebugEnv.Load(); p != nil {
+ env = *p
+ }
+ if envChanged {
+ reparsedebugvars(env)
+ }
+ if update != nil {
+ (*update)(godebugDefault, env)
+ }
+}
+
+//go:linkname syscall_runtimeSetenv syscall.runtimeSetenv
+func syscall_runtimeSetenv(key, value string) {
+ setenv_c(key, value)
+ if key == "GODEBUG" {
+ p := new(string)
+ *p = value
+ godebugEnv.Store(p)
+ godebugNotify(true)
+ }
+}
+
+//go:linkname syscall_runtimeUnsetenv syscall.runtimeUnsetenv
+func syscall_runtimeUnsetenv(key string) {
+ unsetenv_c(key)
+ if key == "GODEBUG" {
+ godebugEnv.Store(nil)
+ godebugNotify(true)
+ }
+}
+
+// writeErrStr writes a string to descriptor 2.
+//
+//go:nosplit
+func writeErrStr(s string) {
+ write(2, unsafe.Pointer(unsafe.StringData(s)), int32(len(s)))
+}
+
+// auxv is populated on relevant platforms but defined here for all platforms
+// so x/sys/cpu can assume the getAuxv symbol exists without keeping its list
+// of auxv-using GOOS build tags in sync.
+//
+// It contains an even number of elements, (tag, value) pairs.
+var auxv []uintptr
+
+func getAuxv() []uintptr { return auxv } // accessed from x/sys/cpu; see issue 57336
diff --git a/contrib/go/_std_1.21/src/runtime/runtime1.go b/contrib/go/_std_1.21/src/runtime/runtime1.go
new file mode 100644
index 0000000000..92a7e021ee
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/runtime1.go
@@ -0,0 +1,655 @@
+// Copyright 2009 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 runtime
+
+import (
+ "internal/bytealg"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// Keep a cached value to make gotraceback fast,
+// since we call it on every call to gentraceback.
+// The cached value is a uint32 in which the low bits
+// are the "crash" and "all" settings and the remaining
+// bits are the traceback value (0 off, 1 on, 2 include system).
+const (
+ tracebackCrash = 1 << iota
+ tracebackAll
+ tracebackShift = iota
+)
+
+var traceback_cache uint32 = 2 << tracebackShift
+var traceback_env uint32
+
+// gotraceback returns the current traceback settings.
+//
+// If level is 0, suppress all tracebacks.
+// If level is 1, show tracebacks, but exclude runtime frames.
+// If level is 2, show tracebacks including runtime frames.
+// If all is set, print all goroutine stacks. Otherwise, print just the current goroutine.
+// If crash is set, crash (core dump, etc) after tracebacking.
+//
+//go:nosplit
+func gotraceback() (level int32, all, crash bool) {
+ gp := getg()
+ t := atomic.Load(&traceback_cache)
+ crash = t&tracebackCrash != 0
+ all = gp.m.throwing >= throwTypeUser || t&tracebackAll != 0
+ if gp.m.traceback != 0 {
+ level = int32(gp.m.traceback)
+ } else if gp.m.throwing >= throwTypeRuntime {
+ // Always include runtime frames in runtime throws unless
+ // otherwise overridden by m.traceback.
+ level = 2
+ } else {
+ level = int32(t >> tracebackShift)
+ }
+ return
+}
+
+var (
+ argc int32
+ argv **byte
+)
+
+// nosplit for use in linux startup sysargs.
+//
+//go:nosplit
+func argv_index(argv **byte, i int32) *byte {
+ return *(**byte)(add(unsafe.Pointer(argv), uintptr(i)*goarch.PtrSize))
+}
+
+func args(c int32, v **byte) {
+ argc = c
+ argv = v
+ sysargs(c, v)
+}
+
+func goargs() {
+ if GOOS == "windows" {
+ return
+ }
+ argslice = make([]string, argc)
+ for i := int32(0); i < argc; i++ {
+ argslice[i] = gostringnocopy(argv_index(argv, i))
+ }
+}
+
+func goenvs_unix() {
+ // TODO(austin): ppc64 in dynamic linking mode doesn't
+ // guarantee env[] will immediately follow argv. Might cause
+ // problems.
+ n := int32(0)
+ for argv_index(argv, argc+1+n) != nil {
+ n++
+ }
+
+ envs = make([]string, n)
+ for i := int32(0); i < n; i++ {
+ envs[i] = gostring(argv_index(argv, argc+1+i))
+ }
+}
+
+func environ() []string {
+ return envs
+}
+
+// TODO: These should be locals in testAtomic64, but we don't 8-byte
+// align stack variables on 386.
+var test_z64, test_x64 uint64
+
+func testAtomic64() {
+ test_z64 = 42
+ test_x64 = 0
+ if atomic.Cas64(&test_z64, test_x64, 1) {
+ throw("cas64 failed")
+ }
+ if test_x64 != 0 {
+ throw("cas64 failed")
+ }
+ test_x64 = 42
+ if !atomic.Cas64(&test_z64, test_x64, 1) {
+ throw("cas64 failed")
+ }
+ if test_x64 != 42 || test_z64 != 1 {
+ throw("cas64 failed")
+ }
+ if atomic.Load64(&test_z64) != 1 {
+ throw("load64 failed")
+ }
+ atomic.Store64(&test_z64, (1<<40)+1)
+ if atomic.Load64(&test_z64) != (1<<40)+1 {
+ throw("store64 failed")
+ }
+ if atomic.Xadd64(&test_z64, (1<<40)+1) != (2<<40)+2 {
+ throw("xadd64 failed")
+ }
+ if atomic.Load64(&test_z64) != (2<<40)+2 {
+ throw("xadd64 failed")
+ }
+ if atomic.Xchg64(&test_z64, (3<<40)+3) != (2<<40)+2 {
+ throw("xchg64 failed")
+ }
+ if atomic.Load64(&test_z64) != (3<<40)+3 {
+ throw("xchg64 failed")
+ }
+}
+
+func check() {
+ var (
+ a int8
+ b uint8
+ c int16
+ d uint16
+ e int32
+ f uint32
+ g int64
+ h uint64
+ i, i1 float32
+ j, j1 float64
+ k unsafe.Pointer
+ l *uint16
+ m [4]byte
+ )
+ type x1t struct {
+ x uint8
+ }
+ type y1t struct {
+ x1 x1t
+ y uint8
+ }
+ var x1 x1t
+ var y1 y1t
+
+ if unsafe.Sizeof(a) != 1 {
+ throw("bad a")
+ }
+ if unsafe.Sizeof(b) != 1 {
+ throw("bad b")
+ }
+ if unsafe.Sizeof(c) != 2 {
+ throw("bad c")
+ }
+ if unsafe.Sizeof(d) != 2 {
+ throw("bad d")
+ }
+ if unsafe.Sizeof(e) != 4 {
+ throw("bad e")
+ }
+ if unsafe.Sizeof(f) != 4 {
+ throw("bad f")
+ }
+ if unsafe.Sizeof(g) != 8 {
+ throw("bad g")
+ }
+ if unsafe.Sizeof(h) != 8 {
+ throw("bad h")
+ }
+ if unsafe.Sizeof(i) != 4 {
+ throw("bad i")
+ }
+ if unsafe.Sizeof(j) != 8 {
+ throw("bad j")
+ }
+ if unsafe.Sizeof(k) != goarch.PtrSize {
+ throw("bad k")
+ }
+ if unsafe.Sizeof(l) != goarch.PtrSize {
+ throw("bad l")
+ }
+ if unsafe.Sizeof(x1) != 1 {
+ throw("bad unsafe.Sizeof x1")
+ }
+ if unsafe.Offsetof(y1.y) != 1 {
+ throw("bad offsetof y1.y")
+ }
+ if unsafe.Sizeof(y1) != 2 {
+ throw("bad unsafe.Sizeof y1")
+ }
+
+ if timediv(12345*1000000000+54321, 1000000000, &e) != 12345 || e != 54321 {
+ throw("bad timediv")
+ }
+
+ var z uint32
+ z = 1
+ if !atomic.Cas(&z, 1, 2) {
+ throw("cas1")
+ }
+ if z != 2 {
+ throw("cas2")
+ }
+
+ z = 4
+ if atomic.Cas(&z, 5, 6) {
+ throw("cas3")
+ }
+ if z != 4 {
+ throw("cas4")
+ }
+
+ z = 0xffffffff
+ if !atomic.Cas(&z, 0xffffffff, 0xfffffffe) {
+ throw("cas5")
+ }
+ if z != 0xfffffffe {
+ throw("cas6")
+ }
+
+ m = [4]byte{1, 1, 1, 1}
+ atomic.Or8(&m[1], 0xf0)
+ if m[0] != 1 || m[1] != 0xf1 || m[2] != 1 || m[3] != 1 {
+ throw("atomicor8")
+ }
+
+ m = [4]byte{0xff, 0xff, 0xff, 0xff}
+ atomic.And8(&m[1], 0x1)
+ if m[0] != 0xff || m[1] != 0x1 || m[2] != 0xff || m[3] != 0xff {
+ throw("atomicand8")
+ }
+
+ *(*uint64)(unsafe.Pointer(&j)) = ^uint64(0)
+ if j == j {
+ throw("float64nan")
+ }
+ if !(j != j) {
+ throw("float64nan1")
+ }
+
+ *(*uint64)(unsafe.Pointer(&j1)) = ^uint64(1)
+ if j == j1 {
+ throw("float64nan2")
+ }
+ if !(j != j1) {
+ throw("float64nan3")
+ }
+
+ *(*uint32)(unsafe.Pointer(&i)) = ^uint32(0)
+ if i == i {
+ throw("float32nan")
+ }
+ if i == i {
+ throw("float32nan1")
+ }
+
+ *(*uint32)(unsafe.Pointer(&i1)) = ^uint32(1)
+ if i == i1 {
+ throw("float32nan2")
+ }
+ if i == i1 {
+ throw("float32nan3")
+ }
+
+ testAtomic64()
+
+ if fixedStack != round2(fixedStack) {
+ throw("FixedStack is not power-of-2")
+ }
+
+ if !checkASM() {
+ throw("assembly checks failed")
+ }
+}
+
+type dbgVar struct {
+ name string
+ value *int32 // for variables that can only be set at startup
+ atomic *atomic.Int32 // for variables that can be changed during execution
+ def int32 // default value (ideally zero)
+}
+
+// Holds variables parsed from GODEBUG env var,
+// except for "memprofilerate" since there is an
+// existing int var for that value, which may
+// already have an initial value.
+var debug struct {
+ cgocheck int32
+ clobberfree int32
+ dontfreezetheworld int32
+ efence int32
+ gccheckmark int32
+ gcpacertrace int32
+ gcshrinkstackoff int32
+ gcstoptheworld int32
+ gctrace int32
+ invalidptr int32
+ madvdontneed int32 // for Linux; issue 28466
+ scavtrace int32
+ scheddetail int32
+ schedtrace int32
+ tracebackancestors int32
+ asyncpreemptoff int32
+ harddecommit int32
+ adaptivestackstart int32
+ tracefpunwindoff int32
+
+ // debug.malloc is used as a combined debug check
+ // in the malloc function and should be set
+ // if any of the below debug options is != 0.
+ malloc bool
+ allocfreetrace int32
+ inittrace int32
+ sbrk int32
+
+ panicnil atomic.Int32
+}
+
+var dbgvars = []*dbgVar{
+ {name: "allocfreetrace", value: &debug.allocfreetrace},
+ {name: "clobberfree", value: &debug.clobberfree},
+ {name: "cgocheck", value: &debug.cgocheck},
+ {name: "dontfreezetheworld", value: &debug.dontfreezetheworld},
+ {name: "efence", value: &debug.efence},
+ {name: "gccheckmark", value: &debug.gccheckmark},
+ {name: "gcpacertrace", value: &debug.gcpacertrace},
+ {name: "gcshrinkstackoff", value: &debug.gcshrinkstackoff},
+ {name: "gcstoptheworld", value: &debug.gcstoptheworld},
+ {name: "gctrace", value: &debug.gctrace},
+ {name: "invalidptr", value: &debug.invalidptr},
+ {name: "madvdontneed", value: &debug.madvdontneed},
+ {name: "sbrk", value: &debug.sbrk},
+ {name: "scavtrace", value: &debug.scavtrace},
+ {name: "scheddetail", value: &debug.scheddetail},
+ {name: "schedtrace", value: &debug.schedtrace},
+ {name: "tracebackancestors", value: &debug.tracebackancestors},
+ {name: "asyncpreemptoff", value: &debug.asyncpreemptoff},
+ {name: "inittrace", value: &debug.inittrace},
+ {name: "harddecommit", value: &debug.harddecommit},
+ {name: "adaptivestackstart", value: &debug.adaptivestackstart},
+ {name: "tracefpunwindoff", value: &debug.tracefpunwindoff},
+ {name: "panicnil", atomic: &debug.panicnil},
+}
+
+func parsedebugvars() {
+ // defaults
+ debug.cgocheck = 1
+ debug.invalidptr = 1
+ debug.adaptivestackstart = 1 // set this to 0 to turn larger initial goroutine stacks off
+ if GOOS == "linux" {
+ // On Linux, MADV_FREE is faster than MADV_DONTNEED,
+ // but doesn't affect many of the statistics that
+ // MADV_DONTNEED does until the memory is actually
+ // reclaimed. This generally leads to poor user
+ // experience, like confusing stats in top and other
+ // monitoring tools; and bad integration with
+ // management systems that respond to memory usage.
+ // Hence, default to MADV_DONTNEED.
+ debug.madvdontneed = 1
+ }
+
+ godebug := gogetenv("GODEBUG")
+
+ p := new(string)
+ *p = godebug
+ godebugEnv.Store(p)
+
+ // apply runtime defaults, if any
+ for _, v := range dbgvars {
+ if v.def != 0 {
+ // Every var should have either v.value or v.atomic set.
+ if v.value != nil {
+ *v.value = v.def
+ } else if v.atomic != nil {
+ v.atomic.Store(v.def)
+ }
+ }
+ }
+
+ // apply compile-time GODEBUG settings
+ parsegodebug(godebugDefault, nil)
+
+ // apply environment settings
+ parsegodebug(godebug, nil)
+
+ debug.malloc = (debug.allocfreetrace | debug.inittrace | debug.sbrk) != 0
+
+ setTraceback(gogetenv("GOTRACEBACK"))
+ traceback_env = traceback_cache
+}
+
+// reparsedebugvars reparses the runtime's debug variables
+// because the environment variable has been changed to env.
+func reparsedebugvars(env string) {
+ seen := make(map[string]bool)
+ // apply environment settings
+ parsegodebug(env, seen)
+ // apply compile-time GODEBUG settings for as-yet-unseen variables
+ parsegodebug(godebugDefault, seen)
+ // apply defaults for as-yet-unseen variables
+ for _, v := range dbgvars {
+ if v.atomic != nil && !seen[v.name] {
+ v.atomic.Store(0)
+ }
+ }
+}
+
+// parsegodebug parses the godebug string, updating variables listed in dbgvars.
+// If seen == nil, this is startup time and we process the string left to right
+// overwriting older settings with newer ones.
+// If seen != nil, $GODEBUG has changed and we are doing an
+// incremental update. To avoid flapping in the case where a value is
+// set multiple times (perhaps in the default and the environment,
+// or perhaps twice in the environment), we process the string right-to-left
+// and only change values not already seen. After doing this for both
+// the environment and the default settings, the caller must also call
+// cleargodebug(seen) to reset any now-unset values back to their defaults.
+func parsegodebug(godebug string, seen map[string]bool) {
+ for p := godebug; p != ""; {
+ var field string
+ if seen == nil {
+ // startup: process left to right, overwriting older settings with newer
+ i := bytealg.IndexByteString(p, ',')
+ if i < 0 {
+ field, p = p, ""
+ } else {
+ field, p = p[:i], p[i+1:]
+ }
+ } else {
+ // incremental update: process right to left, updating and skipping seen
+ i := len(p) - 1
+ for i >= 0 && p[i] != ',' {
+ i--
+ }
+ if i < 0 {
+ p, field = "", p
+ } else {
+ p, field = p[:i], p[i+1:]
+ }
+ }
+ i := bytealg.IndexByteString(field, '=')
+ if i < 0 {
+ continue
+ }
+ key, value := field[:i], field[i+1:]
+ if seen[key] {
+ continue
+ }
+ if seen != nil {
+ seen[key] = true
+ }
+
+ // Update MemProfileRate directly here since it
+ // is int, not int32, and should only be updated
+ // if specified in GODEBUG.
+ if seen == nil && key == "memprofilerate" {
+ if n, ok := atoi(value); ok {
+ MemProfileRate = n
+ }
+ } else {
+ for _, v := range dbgvars {
+ if v.name == key {
+ if n, ok := atoi32(value); ok {
+ if seen == nil && v.value != nil {
+ *v.value = n
+ } else if v.atomic != nil {
+ v.atomic.Store(n)
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if debug.cgocheck > 1 {
+ throw("cgocheck > 1 mode is no longer supported at runtime. Use GOEXPERIMENT=cgocheck2 at build time instead.")
+ }
+}
+
+//go:linkname setTraceback runtime/debug.SetTraceback
+func setTraceback(level string) {
+ var t uint32
+ switch level {
+ case "none":
+ t = 0
+ case "single", "":
+ t = 1 << tracebackShift
+ case "all":
+ t = 1<<tracebackShift | tracebackAll
+ case "system":
+ t = 2<<tracebackShift | tracebackAll
+ case "crash":
+ t = 2<<tracebackShift | tracebackAll | tracebackCrash
+ case "wer":
+ if GOOS == "windows" {
+ t = 2<<tracebackShift | tracebackAll | tracebackCrash
+ enableWER()
+ break
+ }
+ fallthrough
+ default:
+ t = tracebackAll
+ if n, ok := atoi(level); ok && n == int(uint32(n)) {
+ t |= uint32(n) << tracebackShift
+ }
+ }
+ // when C owns the process, simply exit'ing the process on fatal errors
+ // and panics is surprising. Be louder and abort instead.
+ if islibrary || isarchive {
+ t |= tracebackCrash
+ }
+
+ t |= traceback_env
+
+ atomic.Store(&traceback_cache, t)
+}
+
+// Poor mans 64-bit division.
+// This is a very special function, do not use it if you are not sure what you are doing.
+// int64 division is lowered into _divv() call on 386, which does not fit into nosplit functions.
+// Handles overflow in a time-specific manner.
+// This keeps us within no-split stack limits on 32-bit processors.
+//
+//go:nosplit
+func timediv(v int64, div int32, rem *int32) int32 {
+ res := int32(0)
+ for bit := 30; bit >= 0; bit-- {
+ if v >= int64(div)<<uint(bit) {
+ v = v - (int64(div) << uint(bit))
+ // Before this for loop, res was 0, thus all these
+ // power of 2 increments are now just bitsets.
+ res |= 1 << uint(bit)
+ }
+ }
+ if v >= int64(div) {
+ if rem != nil {
+ *rem = 0
+ }
+ return 0x7fffffff
+ }
+ if rem != nil {
+ *rem = int32(v)
+ }
+ return res
+}
+
+// Helpers for Go. Must be NOSPLIT, must only call NOSPLIT functions, and must not block.
+
+//go:nosplit
+func acquirem() *m {
+ gp := getg()
+ gp.m.locks++
+ return gp.m
+}
+
+//go:nosplit
+func releasem(mp *m) {
+ gp := getg()
+ mp.locks--
+ if mp.locks == 0 && gp.preempt {
+ // restore the preemption request in case we've cleared it in newstack
+ gp.stackguard0 = stackPreempt
+ }
+}
+
+//go:linkname reflect_typelinks reflect.typelinks
+func reflect_typelinks() ([]unsafe.Pointer, [][]int32) {
+ modules := activeModules()
+ sections := []unsafe.Pointer{unsafe.Pointer(modules[0].types)}
+ ret := [][]int32{modules[0].typelinks}
+ for _, md := range modules[1:] {
+ sections = append(sections, unsafe.Pointer(md.types))
+ ret = append(ret, md.typelinks)
+ }
+ return sections, ret
+}
+
+// reflect_resolveNameOff resolves a name offset from a base pointer.
+//
+//go:linkname reflect_resolveNameOff reflect.resolveNameOff
+func reflect_resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer {
+ return unsafe.Pointer(resolveNameOff(ptrInModule, nameOff(off)).Bytes)
+}
+
+// reflect_resolveTypeOff resolves an *rtype offset from a base type.
+//
+//go:linkname reflect_resolveTypeOff reflect.resolveTypeOff
+func reflect_resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
+ return unsafe.Pointer(toRType((*_type)(rtype)).typeOff(typeOff(off)))
+}
+
+// reflect_resolveTextOff resolves a function pointer offset from a base type.
+//
+//go:linkname reflect_resolveTextOff reflect.resolveTextOff
+func reflect_resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
+ return toRType((*_type)(rtype)).textOff(textOff(off))
+
+}
+
+// reflectlite_resolveNameOff resolves a name offset from a base pointer.
+//
+//go:linkname reflectlite_resolveNameOff internal/reflectlite.resolveNameOff
+func reflectlite_resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer {
+ return unsafe.Pointer(resolveNameOff(ptrInModule, nameOff(off)).Bytes)
+}
+
+// reflectlite_resolveTypeOff resolves an *rtype offset from a base type.
+//
+//go:linkname reflectlite_resolveTypeOff internal/reflectlite.resolveTypeOff
+func reflectlite_resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
+ return unsafe.Pointer(toRType((*_type)(rtype)).typeOff(typeOff(off)))
+}
+
+// reflect_addReflectOff adds a pointer to the reflection offset lookup map.
+//
+//go:linkname reflect_addReflectOff reflect.addReflectOff
+func reflect_addReflectOff(ptr unsafe.Pointer) int32 {
+ reflectOffsLock()
+ if reflectOffs.m == nil {
+ reflectOffs.m = make(map[int32]unsafe.Pointer)
+ reflectOffs.minv = make(map[unsafe.Pointer]int32)
+ reflectOffs.next = -1
+ }
+ id, found := reflectOffs.minv[ptr]
+ if !found {
+ id = reflectOffs.next
+ reflectOffs.next-- // use negative offsets as IDs to aid debugging
+ reflectOffs.m[id] = ptr
+ reflectOffs.minv[ptr] = id
+ }
+ reflectOffsUnlock()
+ return id
+}
diff --git a/contrib/go/_std_1.21/src/runtime/runtime2.go b/contrib/go/_std_1.21/src/runtime/runtime2.go
new file mode 100644
index 0000000000..f4c76abd1c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/runtime2.go
@@ -0,0 +1,1193 @@
+// Copyright 2009 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// defined constants
+const (
+ // G status
+ //
+ // Beyond indicating the general state of a G, the G status
+ // acts like a lock on the goroutine's stack (and hence its
+ // ability to execute user code).
+ //
+ // If you add to this list, add to the list
+ // of "okay during garbage collection" status
+ // in mgcmark.go too.
+ //
+ // TODO(austin): The _Gscan bit could be much lighter-weight.
+ // For example, we could choose not to run _Gscanrunnable
+ // goroutines found in the run queue, rather than CAS-looping
+ // until they become _Grunnable. And transitions like
+ // _Gscanwaiting -> _Gscanrunnable are actually okay because
+ // they don't affect stack ownership.
+
+ // _Gidle means this goroutine was just allocated and has not
+ // yet been initialized.
+ _Gidle = iota // 0
+
+ // _Grunnable means this goroutine is on a run queue. It is
+ // not currently executing user code. The stack is not owned.
+ _Grunnable // 1
+
+ // _Grunning means this goroutine may execute user code. The
+ // stack is owned by this goroutine. It is not on a run queue.
+ // It is assigned an M and a P (g.m and g.m.p are valid).
+ _Grunning // 2
+
+ // _Gsyscall means this goroutine is executing a system call.
+ // It is not executing user code. The stack is owned by this
+ // goroutine. It is not on a run queue. It is assigned an M.
+ _Gsyscall // 3
+
+ // _Gwaiting means this goroutine is blocked in the runtime.
+ // It is not executing user code. It is not on a run queue,
+ // but should be recorded somewhere (e.g., a channel wait
+ // queue) so it can be ready()d when necessary. The stack is
+ // not owned *except* that a channel operation may read or
+ // write parts of the stack under the appropriate channel
+ // lock. Otherwise, it is not safe to access the stack after a
+ // goroutine enters _Gwaiting (e.g., it may get moved).
+ _Gwaiting // 4
+
+ // _Gmoribund_unused is currently unused, but hardcoded in gdb
+ // scripts.
+ _Gmoribund_unused // 5
+
+ // _Gdead means this goroutine is currently unused. It may be
+ // just exited, on a free list, or just being initialized. It
+ // is not executing user code. It may or may not have a stack
+ // allocated. The G and its stack (if any) are owned by the M
+ // that is exiting the G or that obtained the G from the free
+ // list.
+ _Gdead // 6
+
+ // _Genqueue_unused is currently unused.
+ _Genqueue_unused // 7
+
+ // _Gcopystack means this goroutine's stack is being moved. It
+ // is not executing user code and is not on a run queue. The
+ // stack is owned by the goroutine that put it in _Gcopystack.
+ _Gcopystack // 8
+
+ // _Gpreempted means this goroutine stopped itself for a
+ // suspendG preemption. It is like _Gwaiting, but nothing is
+ // yet responsible for ready()ing it. Some suspendG must CAS
+ // the status to _Gwaiting to take responsibility for
+ // ready()ing this G.
+ _Gpreempted // 9
+
+ // _Gscan combined with one of the above states other than
+ // _Grunning indicates that GC is scanning the stack. The
+ // goroutine is not executing user code and the stack is owned
+ // by the goroutine that set the _Gscan bit.
+ //
+ // _Gscanrunning is different: it is used to briefly block
+ // state transitions while GC signals the G to scan its own
+ // stack. This is otherwise like _Grunning.
+ //
+ // atomicstatus&~Gscan gives the state the goroutine will
+ // return to when the scan completes.
+ _Gscan = 0x1000
+ _Gscanrunnable = _Gscan + _Grunnable // 0x1001
+ _Gscanrunning = _Gscan + _Grunning // 0x1002
+ _Gscansyscall = _Gscan + _Gsyscall // 0x1003
+ _Gscanwaiting = _Gscan + _Gwaiting // 0x1004
+ _Gscanpreempted = _Gscan + _Gpreempted // 0x1009
+)
+
+const (
+ // P status
+
+ // _Pidle means a P is not being used to run user code or the
+ // scheduler. Typically, it's on the idle P list and available
+ // to the scheduler, but it may just be transitioning between
+ // other states.
+ //
+ // The P is owned by the idle list or by whatever is
+ // transitioning its state. Its run queue is empty.
+ _Pidle = iota
+
+ // _Prunning means a P is owned by an M and is being used to
+ // run user code or the scheduler. Only the M that owns this P
+ // is allowed to change the P's status from _Prunning. The M
+ // may transition the P to _Pidle (if it has no more work to
+ // do), _Psyscall (when entering a syscall), or _Pgcstop (to
+ // halt for the GC). The M may also hand ownership of the P
+ // off directly to another M (e.g., to schedule a locked G).
+ _Prunning
+
+ // _Psyscall means a P is not running user code. It has
+ // affinity to an M in a syscall but is not owned by it and
+ // may be stolen by another M. This is similar to _Pidle but
+ // uses lightweight transitions and maintains M affinity.
+ //
+ // Leaving _Psyscall must be done with a CAS, either to steal
+ // or retake the P. Note that there's an ABA hazard: even if
+ // an M successfully CASes its original P back to _Prunning
+ // after a syscall, it must understand the P may have been
+ // used by another M in the interim.
+ _Psyscall
+
+ // _Pgcstop means a P is halted for STW and owned by the M
+ // that stopped the world. The M that stopped the world
+ // continues to use its P, even in _Pgcstop. Transitioning
+ // from _Prunning to _Pgcstop causes an M to release its P and
+ // park.
+ //
+ // The P retains its run queue and startTheWorld will restart
+ // the scheduler on Ps with non-empty run queues.
+ _Pgcstop
+
+ // _Pdead means a P is no longer used (GOMAXPROCS shrank). We
+ // reuse Ps if GOMAXPROCS increases. A dead P is mostly
+ // stripped of its resources, though a few things remain
+ // (e.g., trace buffers).
+ _Pdead
+)
+
+// Mutual exclusion locks. In the uncontended case,
+// as fast as spin locks (just a few user-level instructions),
+// but on the contention path they sleep in the kernel.
+// A zeroed Mutex is unlocked (no need to initialize each lock).
+// Initialization is helpful for static lock ranking, but not required.
+type mutex struct {
+ // Empty struct if lock ranking is disabled, otherwise includes the lock rank
+ lockRankStruct
+ // Futex-based impl treats it as uint32 key,
+ // while sema-based impl as M* waitm.
+ // Used to be a union, but unions break precise GC.
+ key uintptr
+}
+
+// sleep and wakeup on one-time events.
+// before any calls to notesleep or notewakeup,
+// must call noteclear to initialize the Note.
+// then, exactly one thread can call notesleep
+// and exactly one thread can call notewakeup (once).
+// once notewakeup has been called, the notesleep
+// will return. future notesleep will return immediately.
+// subsequent noteclear must be called only after
+// previous notesleep has returned, e.g. it's disallowed
+// to call noteclear straight after notewakeup.
+//
+// notetsleep is like notesleep but wakes up after
+// a given number of nanoseconds even if the event
+// has not yet happened. if a goroutine uses notetsleep to
+// wake up early, it must wait to call noteclear until it
+// can be sure that no other goroutine is calling
+// notewakeup.
+//
+// notesleep/notetsleep are generally called on g0,
+// notetsleepg is similar to notetsleep but is called on user g.
+type note struct {
+ // Futex-based impl treats it as uint32 key,
+ // while sema-based impl as M* waitm.
+ // Used to be a union, but unions break precise GC.
+ key uintptr
+}
+
+type funcval struct {
+ fn uintptr
+ // variable-size, fn-specific data here
+}
+
+type iface struct {
+ tab *itab
+ data unsafe.Pointer
+}
+
+type eface struct {
+ _type *_type
+ data unsafe.Pointer
+}
+
+func efaceOf(ep *any) *eface {
+ return (*eface)(unsafe.Pointer(ep))
+}
+
+// The guintptr, muintptr, and puintptr are all used to bypass write barriers.
+// It is particularly important to avoid write barriers when the current P has
+// been released, because the GC thinks the world is stopped, and an
+// unexpected write barrier would not be synchronized with the GC,
+// which can lead to a half-executed write barrier that has marked the object
+// but not queued it. If the GC skips the object and completes before the
+// queuing can occur, it will incorrectly free the object.
+//
+// We tried using special assignment functions invoked only when not
+// holding a running P, but then some updates to a particular memory
+// word went through write barriers and some did not. This breaks the
+// write barrier shadow checking mode, and it is also scary: better to have
+// a word that is completely ignored by the GC than to have one for which
+// only a few updates are ignored.
+//
+// Gs and Ps are always reachable via true pointers in the
+// allgs and allp lists or (during allocation before they reach those lists)
+// from stack variables.
+//
+// Ms are always reachable via true pointers either from allm or
+// freem. Unlike Gs and Ps we do free Ms, so it's important that
+// nothing ever hold an muintptr across a safe point.
+
+// A guintptr holds a goroutine pointer, but typed as a uintptr
+// to bypass write barriers. It is used in the Gobuf goroutine state
+// and in scheduling lists that are manipulated without a P.
+//
+// The Gobuf.g goroutine pointer is almost always updated by assembly code.
+// In one of the few places it is updated by Go code - func save - it must be
+// treated as a uintptr to avoid a write barrier being emitted at a bad time.
+// Instead of figuring out how to emit the write barriers missing in the
+// assembly manipulation, we change the type of the field to uintptr,
+// so that it does not require write barriers at all.
+//
+// Goroutine structs are published in the allg list and never freed.
+// That will keep the goroutine structs from being collected.
+// There is never a time that Gobuf.g's contain the only references
+// to a goroutine: the publishing of the goroutine in allg comes first.
+// Goroutine pointers are also kept in non-GC-visible places like TLS,
+// so I can't see them ever moving. If we did want to start moving data
+// in the GC, we'd need to allocate the goroutine structs from an
+// alternate arena. Using guintptr doesn't make that problem any worse.
+// Note that pollDesc.rg, pollDesc.wg also store g in uintptr form,
+// so they would need to be updated too if g's start moving.
+type guintptr uintptr
+
+//go:nosplit
+func (gp guintptr) ptr() *g { return (*g)(unsafe.Pointer(gp)) }
+
+//go:nosplit
+func (gp *guintptr) set(g *g) { *gp = guintptr(unsafe.Pointer(g)) }
+
+//go:nosplit
+func (gp *guintptr) cas(old, new guintptr) bool {
+ return atomic.Casuintptr((*uintptr)(unsafe.Pointer(gp)), uintptr(old), uintptr(new))
+}
+
+//go:nosplit
+func (gp *g) guintptr() guintptr {
+ return guintptr(unsafe.Pointer(gp))
+}
+
+// setGNoWB performs *gp = new without a write barrier.
+// For times when it's impractical to use a guintptr.
+//
+//go:nosplit
+//go:nowritebarrier
+func setGNoWB(gp **g, new *g) {
+ (*guintptr)(unsafe.Pointer(gp)).set(new)
+}
+
+type puintptr uintptr
+
+//go:nosplit
+func (pp puintptr) ptr() *p { return (*p)(unsafe.Pointer(pp)) }
+
+//go:nosplit
+func (pp *puintptr) set(p *p) { *pp = puintptr(unsafe.Pointer(p)) }
+
+// muintptr is a *m that is not tracked by the garbage collector.
+//
+// Because we do free Ms, there are some additional constrains on
+// muintptrs:
+//
+// 1. Never hold an muintptr locally across a safe point.
+//
+// 2. Any muintptr in the heap must be owned by the M itself so it can
+// ensure it is not in use when the last true *m is released.
+type muintptr uintptr
+
+//go:nosplit
+func (mp muintptr) ptr() *m { return (*m)(unsafe.Pointer(mp)) }
+
+//go:nosplit
+func (mp *muintptr) set(m *m) { *mp = muintptr(unsafe.Pointer(m)) }
+
+// setMNoWB performs *mp = new without a write barrier.
+// For times when it's impractical to use an muintptr.
+//
+//go:nosplit
+//go:nowritebarrier
+func setMNoWB(mp **m, new *m) {
+ (*muintptr)(unsafe.Pointer(mp)).set(new)
+}
+
+type gobuf struct {
+ // The offsets of sp, pc, and g are known to (hard-coded in) libmach.
+ //
+ // ctxt is unusual with respect to GC: it may be a
+ // heap-allocated funcval, so GC needs to track it, but it
+ // needs to be set and cleared from assembly, where it's
+ // difficult to have write barriers. However, ctxt is really a
+ // saved, live register, and we only ever exchange it between
+ // the real register and the gobuf. Hence, we treat it as a
+ // root during stack scanning, which means assembly that saves
+ // and restores it doesn't need write barriers. It's still
+ // typed as a pointer so that any other writes from Go get
+ // write barriers.
+ sp uintptr
+ pc uintptr
+ g guintptr
+ ctxt unsafe.Pointer
+ ret uintptr
+ lr uintptr
+ bp uintptr // for framepointer-enabled architectures
+}
+
+// sudog represents a g in a wait list, such as for sending/receiving
+// on a channel.
+//
+// sudog is necessary because the g ↔ synchronization object relation
+// is many-to-many. A g can be on many wait lists, so there may be
+// many sudogs for one g; and many gs may be waiting on the same
+// synchronization object, so there may be many sudogs for one object.
+//
+// sudogs are allocated from a special pool. Use acquireSudog and
+// releaseSudog to allocate and free them.
+type sudog struct {
+ // The following fields are protected by the hchan.lock of the
+ // channel this sudog is blocking on. shrinkstack depends on
+ // this for sudogs involved in channel ops.
+
+ g *g
+
+ next *sudog
+ prev *sudog
+ elem unsafe.Pointer // data element (may point to stack)
+
+ // The following fields are never accessed concurrently.
+ // For channels, waitlink is only accessed by g.
+ // For semaphores, all fields (including the ones above)
+ // are only accessed when holding a semaRoot lock.
+
+ acquiretime int64
+ releasetime int64
+ ticket uint32
+
+ // isSelect indicates g is participating in a select, so
+ // g.selectDone must be CAS'd to win the wake-up race.
+ isSelect bool
+
+ // success indicates whether communication over channel c
+ // succeeded. It is true if the goroutine was awoken because a
+ // value was delivered over channel c, and false if awoken
+ // because c was closed.
+ success bool
+
+ parent *sudog // semaRoot binary tree
+ waitlink *sudog // g.waiting list or semaRoot
+ waittail *sudog // semaRoot
+ c *hchan // channel
+}
+
+type libcall struct {
+ fn uintptr
+ n uintptr // number of parameters
+ args uintptr // parameters
+ r1 uintptr // return values
+ r2 uintptr
+ err uintptr // error number
+}
+
+// Stack describes a Go execution stack.
+// The bounds of the stack are exactly [lo, hi),
+// with no implicit data structures on either side.
+type stack struct {
+ lo uintptr
+ hi uintptr
+}
+
+// heldLockInfo gives info on a held lock and the rank of that lock
+type heldLockInfo struct {
+ lockAddr uintptr
+ rank lockRank
+}
+
+type g struct {
+ // Stack parameters.
+ // stack describes the actual stack memory: [stack.lo, stack.hi).
+ // stackguard0 is the stack pointer compared in the Go stack growth prologue.
+ // It is stack.lo+StackGuard normally, but can be StackPreempt to trigger a preemption.
+ // stackguard1 is the stack pointer compared in the C stack growth prologue.
+ // It is stack.lo+StackGuard on g0 and gsignal stacks.
+ // It is ~0 on other goroutine stacks, to trigger a call to morestackc (and crash).
+ stack stack // offset known to runtime/cgo
+ stackguard0 uintptr // offset known to liblink
+ stackguard1 uintptr // offset known to liblink
+
+ _panic *_panic // innermost panic - offset known to liblink
+ _defer *_defer // innermost defer
+ m *m // current m; offset known to arm liblink
+ sched gobuf
+ syscallsp uintptr // if status==Gsyscall, syscallsp = sched.sp to use during gc
+ syscallpc uintptr // if status==Gsyscall, syscallpc = sched.pc to use during gc
+ stktopsp uintptr // expected sp at top of stack, to check in traceback
+ // param is a generic pointer parameter field used to pass
+ // values in particular contexts where other storage for the
+ // parameter would be difficult to find. It is currently used
+ // in three ways:
+ // 1. When a channel operation wakes up a blocked goroutine, it sets param to
+ // point to the sudog of the completed blocking operation.
+ // 2. By gcAssistAlloc1 to signal back to its caller that the goroutine completed
+ // the GC cycle. It is unsafe to do so in any other way, because the goroutine's
+ // stack may have moved in the meantime.
+ // 3. By debugCallWrap to pass parameters to a new goroutine because allocating a
+ // closure in the runtime is forbidden.
+ param unsafe.Pointer
+ atomicstatus atomic.Uint32
+ stackLock uint32 // sigprof/scang lock; TODO: fold in to atomicstatus
+ goid uint64
+ schedlink guintptr
+ waitsince int64 // approx time when the g become blocked
+ waitreason waitReason // if status==Gwaiting
+
+ preempt bool // preemption signal, duplicates stackguard0 = stackpreempt
+ preemptStop bool // transition to _Gpreempted on preemption; otherwise, just deschedule
+ preemptShrink bool // shrink stack at synchronous safe point
+
+ // asyncSafePoint is set if g is stopped at an asynchronous
+ // safe point. This means there are frames on the stack
+ // without precise pointer information.
+ asyncSafePoint bool
+
+ paniconfault bool // panic (instead of crash) on unexpected fault address
+ gcscandone bool // g has scanned stack; protected by _Gscan bit in status
+ throwsplit bool // must not split stack
+ // activeStackChans indicates that there are unlocked channels
+ // pointing into this goroutine's stack. If true, stack
+ // copying needs to acquire channel locks to protect these
+ // areas of the stack.
+ activeStackChans bool
+ // parkingOnChan indicates that the goroutine is about to
+ // park on a chansend or chanrecv. Used to signal an unsafe point
+ // for stack shrinking.
+ parkingOnChan atomic.Bool
+
+ raceignore int8 // ignore race detection events
+ tracking bool // whether we're tracking this G for sched latency statistics
+ trackingSeq uint8 // used to decide whether to track this G
+ trackingStamp int64 // timestamp of when the G last started being tracked
+ runnableTime int64 // the amount of time spent runnable, cleared when running, only used when tracking
+ lockedm muintptr
+ sig uint32
+ writebuf []byte
+ sigcode0 uintptr
+ sigcode1 uintptr
+ sigpc uintptr
+ parentGoid uint64 // goid of goroutine that created this goroutine
+ gopc uintptr // pc of go statement that created this goroutine
+ ancestors *[]ancestorInfo // ancestor information goroutine(s) that created this goroutine (only used if debug.tracebackancestors)
+ startpc uintptr // pc of goroutine function
+ racectx uintptr
+ waiting *sudog // sudog structures this g is waiting on (that have a valid elem ptr); in lock order
+ cgoCtxt []uintptr // cgo traceback context
+ labels unsafe.Pointer // profiler labels
+ timer *timer // cached timer for time.Sleep
+ selectDone atomic.Uint32 // are we participating in a select and did someone win the race?
+
+ // goroutineProfiled indicates the status of this goroutine's stack for the
+ // current in-progress goroutine profile
+ goroutineProfiled goroutineProfileStateHolder
+
+ // Per-G tracer state.
+ trace gTraceState
+
+ // Per-G GC state
+
+ // gcAssistBytes is this G's GC assist credit in terms of
+ // bytes allocated. If this is positive, then the G has credit
+ // to allocate gcAssistBytes bytes without assisting. If this
+ // is negative, then the G must correct this by performing
+ // scan work. We track this in bytes to make it fast to update
+ // and check for debt in the malloc hot path. The assist ratio
+ // determines how this corresponds to scan work debt.
+ gcAssistBytes int64
+}
+
+// gTrackingPeriod is the number of transitions out of _Grunning between
+// latency tracking runs.
+const gTrackingPeriod = 8
+
+const (
+ // tlsSlots is the number of pointer-sized slots reserved for TLS on some platforms,
+ // like Windows.
+ tlsSlots = 6
+ tlsSize = tlsSlots * goarch.PtrSize
+)
+
+// Values for m.freeWait.
+const (
+ freeMStack = 0 // M done, free stack and reference.
+ freeMRef = 1 // M done, free reference.
+ freeMWait = 2 // M still in use.
+)
+
+type m struct {
+ g0 *g // goroutine with scheduling stack
+ morebuf gobuf // gobuf arg to morestack
+ divmod uint32 // div/mod denominator for arm - known to liblink
+ _ uint32 // align next field to 8 bytes
+
+ // Fields not known to debuggers.
+ procid uint64 // for debuggers, but offset not hard-coded
+ gsignal *g // signal-handling g
+ goSigStack gsignalStack // Go-allocated signal handling stack
+ sigmask sigset // storage for saved signal mask
+ tls [tlsSlots]uintptr // thread-local storage (for x86 extern register)
+ mstartfn func()
+ curg *g // current running goroutine
+ caughtsig guintptr // goroutine running during fatal signal
+ p puintptr // attached p for executing go code (nil if not executing go code)
+ nextp puintptr
+ oldp puintptr // the p that was attached before executing a syscall
+ id int64
+ mallocing int32
+ throwing throwType
+ preemptoff string // if != "", keep curg running on this m
+ locks int32
+ dying int32
+ profilehz int32
+ spinning bool // m is out of work and is actively looking for work
+ blocked bool // m is blocked on a note
+ newSigstack bool // minit on C thread called sigaltstack
+ printlock int8
+ incgo bool // m is executing a cgo call
+ isextra bool // m is an extra m
+ isExtraInC bool // m is an extra m that is not executing Go code
+ freeWait atomic.Uint32 // Whether it is safe to free g0 and delete m (one of freeMRef, freeMStack, freeMWait)
+ fastrand uint64
+ needextram bool
+ traceback uint8
+ ncgocall uint64 // number of cgo calls in total
+ ncgo int32 // number of cgo calls currently in progress
+ cgoCallersUse atomic.Uint32 // if non-zero, cgoCallers in use temporarily
+ cgoCallers *cgoCallers // cgo traceback if crashing in cgo call
+ park note
+ alllink *m // on allm
+ schedlink muintptr
+ lockedg guintptr
+ createstack [32]uintptr // stack that created this thread.
+ lockedExt uint32 // tracking for external LockOSThread
+ lockedInt uint32 // tracking for internal lockOSThread
+ nextwaitm muintptr // next m waiting for lock
+
+ // wait* are used to carry arguments from gopark into park_m, because
+ // there's no stack to put them on. That is their sole purpose.
+ waitunlockf func(*g, unsafe.Pointer) bool
+ waitlock unsafe.Pointer
+ waitTraceBlockReason traceBlockReason
+ waitTraceSkip int
+
+ syscalltick uint32
+ freelink *m // on sched.freem
+ trace mTraceState
+
+ // these are here because they are too large to be on the stack
+ // of low-level NOSPLIT functions.
+ libcall libcall
+ libcallpc uintptr // for cpu profiler
+ libcallsp uintptr
+ libcallg guintptr
+ syscall libcall // stores syscall parameters on windows
+
+ vdsoSP uintptr // SP for traceback while in VDSO call (0 if not in call)
+ vdsoPC uintptr // PC for traceback while in VDSO call
+
+ // preemptGen counts the number of completed preemption
+ // signals. This is used to detect when a preemption is
+ // requested, but fails.
+ preemptGen atomic.Uint32
+
+ // Whether this is a pending preemption signal on this M.
+ signalPending atomic.Uint32
+
+ dlogPerM
+
+ mOS
+
+ // Up to 10 locks held by this m, maintained by the lock ranking code.
+ locksHeldLen int
+ locksHeld [10]heldLockInfo
+}
+
+type p struct {
+ id int32
+ status uint32 // one of pidle/prunning/...
+ link puintptr
+ schedtick uint32 // incremented on every scheduler call
+ syscalltick uint32 // incremented on every system call
+ sysmontick sysmontick // last tick observed by sysmon
+ m muintptr // back-link to associated m (nil if idle)
+ mcache *mcache
+ pcache pageCache
+ raceprocctx uintptr
+
+ deferpool []*_defer // pool of available defer structs (see panic.go)
+ deferpoolbuf [32]*_defer
+
+ // Cache of goroutine ids, amortizes accesses to runtime·sched.goidgen.
+ goidcache uint64
+ goidcacheend uint64
+
+ // Queue of runnable goroutines. Accessed without lock.
+ runqhead uint32
+ runqtail uint32
+ runq [256]guintptr
+ // runnext, if non-nil, is a runnable G that was ready'd by
+ // the current G and should be run next instead of what's in
+ // runq if there's time remaining in the running G's time
+ // slice. It will inherit the time left in the current time
+ // slice. If a set of goroutines is locked in a
+ // communicate-and-wait pattern, this schedules that set as a
+ // unit and eliminates the (potentially large) scheduling
+ // latency that otherwise arises from adding the ready'd
+ // goroutines to the end of the run queue.
+ //
+ // Note that while other P's may atomically CAS this to zero,
+ // only the owner P can CAS it to a valid G.
+ runnext guintptr
+
+ // Available G's (status == Gdead)
+ gFree struct {
+ gList
+ n int32
+ }
+
+ sudogcache []*sudog
+ sudogbuf [128]*sudog
+
+ // Cache of mspan objects from the heap.
+ mspancache struct {
+ // We need an explicit length here because this field is used
+ // in allocation codepaths where write barriers are not allowed,
+ // and eliminating the write barrier/keeping it eliminated from
+ // slice updates is tricky, more so than just managing the length
+ // ourselves.
+ len int
+ buf [128]*mspan
+ }
+
+ // Cache of a single pinner object to reduce allocations from repeated
+ // pinner creation.
+ pinnerCache *pinner
+
+ trace pTraceState
+
+ palloc persistentAlloc // per-P to avoid mutex
+
+ // The when field of the first entry on the timer heap.
+ // This is 0 if the timer heap is empty.
+ timer0When atomic.Int64
+
+ // The earliest known nextwhen field of a timer with
+ // timerModifiedEarlier status. Because the timer may have been
+ // modified again, there need not be any timer with this value.
+ // This is 0 if there are no timerModifiedEarlier timers.
+ timerModifiedEarliest atomic.Int64
+
+ // Per-P GC state
+ gcAssistTime int64 // Nanoseconds in assistAlloc
+ gcFractionalMarkTime int64 // Nanoseconds in fractional mark worker (atomic)
+
+ // limiterEvent tracks events for the GC CPU limiter.
+ limiterEvent limiterEvent
+
+ // gcMarkWorkerMode is the mode for the next mark worker to run in.
+ // That is, this is used to communicate with the worker goroutine
+ // selected for immediate execution by
+ // gcController.findRunnableGCWorker. When scheduling other goroutines,
+ // this field must be set to gcMarkWorkerNotWorker.
+ gcMarkWorkerMode gcMarkWorkerMode
+ // gcMarkWorkerStartTime is the nanotime() at which the most recent
+ // mark worker started.
+ gcMarkWorkerStartTime int64
+
+ // gcw is this P's GC work buffer cache. The work buffer is
+ // filled by write barriers, drained by mutator assists, and
+ // disposed on certain GC state transitions.
+ gcw gcWork
+
+ // wbBuf is this P's GC write barrier buffer.
+ //
+ // TODO: Consider caching this in the running G.
+ wbBuf wbBuf
+
+ runSafePointFn uint32 // if 1, run sched.safePointFn at next safe point
+
+ // statsSeq is a counter indicating whether this P is currently
+ // writing any stats. Its value is even when not, odd when it is.
+ statsSeq atomic.Uint32
+
+ // Lock for timers. We normally access the timers while running
+ // on this P, but the scheduler can also do it from a different P.
+ timersLock mutex
+
+ // Actions to take at some time. This is used to implement the
+ // standard library's time package.
+ // Must hold timersLock to access.
+ timers []*timer
+
+ // Number of timers in P's heap.
+ numTimers atomic.Uint32
+
+ // Number of timerDeleted timers in P's heap.
+ deletedTimers atomic.Uint32
+
+ // Race context used while executing timer functions.
+ timerRaceCtx uintptr
+
+ // maxStackScanDelta accumulates the amount of stack space held by
+ // live goroutines (i.e. those eligible for stack scanning).
+ // Flushed to gcController.maxStackScan once maxStackScanSlack
+ // or -maxStackScanSlack is reached.
+ maxStackScanDelta int64
+
+ // gc-time statistics about current goroutines
+ // Note that this differs from maxStackScan in that this
+ // accumulates the actual stack observed to be used at GC time (hi - sp),
+ // not an instantaneous measure of the total stack size that might need
+ // to be scanned (hi - lo).
+ scannedStackSize uint64 // stack size of goroutines scanned by this P
+ scannedStacks uint64 // number of goroutines scanned by this P
+
+ // preempt is set to indicate that this P should be enter the
+ // scheduler ASAP (regardless of what G is running on it).
+ preempt bool
+
+ // pageTraceBuf is a buffer for writing out page allocation/free/scavenge traces.
+ //
+ // Used only if GOEXPERIMENT=pagetrace.
+ pageTraceBuf pageTraceBuf
+
+ // Padding is no longer needed. False sharing is now not a worry because p is large enough
+ // that its size class is an integer multiple of the cache line size (for any of our architectures).
+}
+
+type schedt struct {
+ goidgen atomic.Uint64
+ lastpoll atomic.Int64 // time of last network poll, 0 if currently polling
+ pollUntil atomic.Int64 // time to which current poll is sleeping
+
+ lock mutex
+
+ // When increasing nmidle, nmidlelocked, nmsys, or nmfreed, be
+ // sure to call checkdead().
+
+ midle muintptr // idle m's waiting for work
+ nmidle int32 // number of idle m's waiting for work
+ nmidlelocked int32 // number of locked m's waiting for work
+ mnext int64 // number of m's that have been created and next M ID
+ maxmcount int32 // maximum number of m's allowed (or die)
+ nmsys int32 // number of system m's not counted for deadlock
+ nmfreed int64 // cumulative number of freed m's
+
+ ngsys atomic.Int32 // number of system goroutines
+
+ pidle puintptr // idle p's
+ npidle atomic.Int32
+ nmspinning atomic.Int32 // See "Worker thread parking/unparking" comment in proc.go.
+ needspinning atomic.Uint32 // See "Delicate dance" comment in proc.go. Boolean. Must hold sched.lock to set to 1.
+
+ // Global runnable queue.
+ runq gQueue
+ runqsize int32
+
+ // disable controls selective disabling of the scheduler.
+ //
+ // Use schedEnableUser to control this.
+ //
+ // disable is protected by sched.lock.
+ disable struct {
+ // user disables scheduling of user goroutines.
+ user bool
+ runnable gQueue // pending runnable Gs
+ n int32 // length of runnable
+ }
+
+ // Global cache of dead G's.
+ gFree struct {
+ lock mutex
+ stack gList // Gs with stacks
+ noStack gList // Gs without stacks
+ n int32
+ }
+
+ // Central cache of sudog structs.
+ sudoglock mutex
+ sudogcache *sudog
+
+ // Central pool of available defer structs.
+ deferlock mutex
+ deferpool *_defer
+
+ // freem is the list of m's waiting to be freed when their
+ // m.exited is set. Linked through m.freelink.
+ freem *m
+
+ gcwaiting atomic.Bool // gc is waiting to run
+ stopwait int32
+ stopnote note
+ sysmonwait atomic.Bool
+ sysmonnote note
+
+ // safepointFn should be called on each P at the next GC
+ // safepoint if p.runSafePointFn is set.
+ safePointFn func(*p)
+ safePointWait int32
+ safePointNote note
+
+ profilehz int32 // cpu profiling rate
+
+ procresizetime int64 // nanotime() of last change to gomaxprocs
+ totaltime int64 // ∫gomaxprocs dt up to procresizetime
+
+ // sysmonlock protects sysmon's actions on the runtime.
+ //
+ // Acquire and hold this mutex to block sysmon from interacting
+ // with the rest of the runtime.
+ sysmonlock mutex
+
+ // timeToRun is a distribution of scheduling latencies, defined
+ // as the sum of time a G spends in the _Grunnable state before
+ // it transitions to _Grunning.
+ timeToRun timeHistogram
+
+ // idleTime is the total CPU time Ps have "spent" idle.
+ //
+ // Reset on each GC cycle.
+ idleTime atomic.Int64
+
+ // totalMutexWaitTime is the sum of time goroutines have spent in _Gwaiting
+ // with a waitreason of the form waitReasonSync{RW,}Mutex{R,}Lock.
+ totalMutexWaitTime atomic.Int64
+}
+
+// Values for the flags field of a sigTabT.
+const (
+ _SigNotify = 1 << iota // let signal.Notify have signal, even if from kernel
+ _SigKill // if signal.Notify doesn't take it, exit quietly
+ _SigThrow // if signal.Notify doesn't take it, exit loudly
+ _SigPanic // if the signal is from the kernel, panic
+ _SigDefault // if the signal isn't explicitly requested, don't monitor it
+ _SigGoExit // cause all runtime procs to exit (only used on Plan 9).
+ _SigSetStack // Don't explicitly install handler, but add SA_ONSTACK to existing libc handler
+ _SigUnblock // always unblock; see blockableSig
+ _SigIgn // _SIG_DFL action is to ignore the signal
+)
+
+// Layout of in-memory per-function information prepared by linker
+// See https://golang.org/s/go12symtab.
+// Keep in sync with linker (../cmd/link/internal/ld/pcln.go:/pclntab)
+// and with package debug/gosym and with symtab.go in package runtime.
+type _func struct {
+ sys.NotInHeap // Only in static data
+
+ entryOff uint32 // start pc, as offset from moduledata.text/pcHeader.textStart
+ nameOff int32 // function name, as index into moduledata.funcnametab.
+
+ args int32 // in/out args size
+ deferreturn uint32 // offset of start of a deferreturn call instruction from entry, if any.
+
+ pcsp uint32
+ pcfile uint32
+ pcln uint32
+ npcdata uint32
+ cuOffset uint32 // runtime.cutab offset of this function's CU
+ startLine int32 // line number of start of function (func keyword/TEXT directive)
+ funcID abi.FuncID // set for certain special runtime functions
+ flag abi.FuncFlag
+ _ [1]byte // pad
+ nfuncdata uint8 // must be last, must end on a uint32-aligned boundary
+
+ // The end of the struct is followed immediately by two variable-length
+ // arrays that reference the pcdata and funcdata locations for this
+ // function.
+
+ // pcdata contains the offset into moduledata.pctab for the start of
+ // that index's table. e.g.,
+ // &moduledata.pctab[_func.pcdata[_PCDATA_UnsafePoint]] is the start of
+ // the unsafe point table.
+ //
+ // An offset of 0 indicates that there is no table.
+ //
+ // pcdata [npcdata]uint32
+
+ // funcdata contains the offset past moduledata.gofunc which contains a
+ // pointer to that index's funcdata. e.g.,
+ // *(moduledata.gofunc + _func.funcdata[_FUNCDATA_ArgsPointerMaps]) is
+ // the argument pointer map.
+ //
+ // An offset of ^uint32(0) indicates that there is no entry.
+ //
+ // funcdata [nfuncdata]uint32
+}
+
+// Pseudo-Func that is returned for PCs that occur in inlined code.
+// A *Func can be either a *_func or a *funcinl, and they are distinguished
+// by the first uintptr.
+//
+// TODO(austin): Can we merge this with inlinedCall?
+type funcinl struct {
+ ones uint32 // set to ^0 to distinguish from _func
+ entry uintptr // entry of the real (the "outermost") frame
+ name string
+ file string
+ line int32
+ startLine int32
+}
+
+// layout of Itab known to compilers
+// allocated in non-garbage-collected memory
+// Needs to be in sync with
+// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs.
+type itab struct {
+ inter *interfacetype
+ _type *_type
+ hash uint32 // copy of _type.hash. Used for type switches.
+ _ [4]byte
+ fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
+}
+
+// Lock-free stack node.
+// Also known to export_test.go.
+type lfnode struct {
+ next uint64
+ pushcnt uintptr
+}
+
+type forcegcstate struct {
+ lock mutex
+ g *g
+ idle atomic.Bool
+}
+
+// extendRandom extends the random numbers in r[:n] to the whole slice r.
+// Treats n<0 as n==0.
+func extendRandom(r []byte, n int) {
+ if n < 0 {
+ n = 0
+ }
+ for n < len(r) {
+ // Extend random bits using hash function & time seed
+ w := n
+ if w > 16 {
+ w = 16
+ }
+ h := memhash(unsafe.Pointer(&r[n-w]), uintptr(nanotime()), uintptr(w))
+ for i := 0; i < goarch.PtrSize && n < len(r); i++ {
+ r[n] = byte(h)
+ n++
+ h >>= 8
+ }
+ }
+}
+
+// A _defer holds an entry on the list of deferred calls.
+// If you add a field here, add code to clear it in deferProcStack.
+// This struct must match the code in cmd/compile/internal/ssagen/ssa.go:deferstruct
+// and cmd/compile/internal/ssagen/ssa.go:(*state).call.
+// Some defers will be allocated on the stack and some on the heap.
+// All defers are logically part of the stack, so write barriers to
+// initialize them are not required. All defers must be manually scanned,
+// and for heap defers, marked.
+type _defer struct {
+ started bool
+ heap bool
+ // openDefer indicates that this _defer is for a frame with open-coded
+ // defers. We have only one defer record for the entire frame (which may
+ // currently have 0, 1, or more defers active).
+ openDefer bool
+ sp uintptr // sp at time of defer
+ pc uintptr // pc at time of defer
+ fn func() // can be nil for open-coded defers
+ _panic *_panic // panic that is running defer
+ link *_defer // next defer on G; can point to either heap or stack!
+
+ // If openDefer is true, the fields below record values about the stack
+ // frame and associated function that has the open-coded defer(s). sp
+ // above will be the sp for the frame, and pc will be address of the
+ // deferreturn call in the function.
+ fd unsafe.Pointer // funcdata for the function associated with the frame
+ varp uintptr // value of varp for the stack frame
+ // framepc is the current pc associated with the stack frame. Together,
+ // with sp above (which is the sp associated with the stack frame),
+ // framepc/sp can be used as pc/sp pair to continue a stack trace via
+ // gentraceback().
+ framepc uintptr
+}
+
+// A _panic holds information about an active panic.
+//
+// A _panic value must only ever live on the stack.
+//
+// The argp and link fields are stack pointers, but don't need special
+// handling during stack growth: because they are pointer-typed and
+// _panic values only live on the stack, regular stack pointer
+// adjustment takes care of them.
+type _panic struct {
+ argp unsafe.Pointer // pointer to arguments of deferred call run during panic; cannot move - known to liblink
+ arg any // argument to panic
+ link *_panic // link to earlier panic
+ pc uintptr // where to return to in runtime if this panic is bypassed
+ sp unsafe.Pointer // where to return to in runtime if this panic is bypassed
+ recovered bool // whether this panic is over
+ aborted bool // the panic was aborted
+ goexit bool
+}
+
+// ancestorInfo records details of where a goroutine was started.
+type ancestorInfo struct {
+ pcs []uintptr // pcs from the stack of this goroutine
+ goid uint64 // goroutine id of this goroutine; original goroutine possibly dead
+ gopc uintptr // pc of go statement that created this goroutine
+}
+
+// A waitReason explains why a goroutine has been stopped.
+// See gopark. Do not re-use waitReasons, add new ones.
+type waitReason uint8
+
+const (
+ waitReasonZero waitReason = iota // ""
+ waitReasonGCAssistMarking // "GC assist marking"
+ waitReasonIOWait // "IO wait"
+ waitReasonChanReceiveNilChan // "chan receive (nil chan)"
+ waitReasonChanSendNilChan // "chan send (nil chan)"
+ waitReasonDumpingHeap // "dumping heap"
+ waitReasonGarbageCollection // "garbage collection"
+ waitReasonGarbageCollectionScan // "garbage collection scan"
+ waitReasonPanicWait // "panicwait"
+ waitReasonSelect // "select"
+ waitReasonSelectNoCases // "select (no cases)"
+ waitReasonGCAssistWait // "GC assist wait"
+ waitReasonGCSweepWait // "GC sweep wait"
+ waitReasonGCScavengeWait // "GC scavenge wait"
+ waitReasonChanReceive // "chan receive"
+ waitReasonChanSend // "chan send"
+ waitReasonFinalizerWait // "finalizer wait"
+ waitReasonForceGCIdle // "force gc (idle)"
+ waitReasonSemacquire // "semacquire"
+ waitReasonSleep // "sleep"
+ waitReasonSyncCondWait // "sync.Cond.Wait"
+ waitReasonSyncMutexLock // "sync.Mutex.Lock"
+ waitReasonSyncRWMutexRLock // "sync.RWMutex.RLock"
+ waitReasonSyncRWMutexLock // "sync.RWMutex.Lock"
+ waitReasonTraceReaderBlocked // "trace reader (blocked)"
+ waitReasonWaitForGCCycle // "wait for GC cycle"
+ waitReasonGCWorkerIdle // "GC worker (idle)"
+ waitReasonGCWorkerActive // "GC worker (active)"
+ waitReasonPreempted // "preempted"
+ waitReasonDebugCall // "debug call"
+ waitReasonGCMarkTermination // "GC mark termination"
+ waitReasonStoppingTheWorld // "stopping the world"
+)
+
+var waitReasonStrings = [...]string{
+ waitReasonZero: "",
+ waitReasonGCAssistMarking: "GC assist marking",
+ waitReasonIOWait: "IO wait",
+ waitReasonChanReceiveNilChan: "chan receive (nil chan)",
+ waitReasonChanSendNilChan: "chan send (nil chan)",
+ waitReasonDumpingHeap: "dumping heap",
+ waitReasonGarbageCollection: "garbage collection",
+ waitReasonGarbageCollectionScan: "garbage collection scan",
+ waitReasonPanicWait: "panicwait",
+ waitReasonSelect: "select",
+ waitReasonSelectNoCases: "select (no cases)",
+ waitReasonGCAssistWait: "GC assist wait",
+ waitReasonGCSweepWait: "GC sweep wait",
+ waitReasonGCScavengeWait: "GC scavenge wait",
+ waitReasonChanReceive: "chan receive",
+ waitReasonChanSend: "chan send",
+ waitReasonFinalizerWait: "finalizer wait",
+ waitReasonForceGCIdle: "force gc (idle)",
+ waitReasonSemacquire: "semacquire",
+ waitReasonSleep: "sleep",
+ waitReasonSyncCondWait: "sync.Cond.Wait",
+ waitReasonSyncMutexLock: "sync.Mutex.Lock",
+ waitReasonSyncRWMutexRLock: "sync.RWMutex.RLock",
+ waitReasonSyncRWMutexLock: "sync.RWMutex.Lock",
+ waitReasonTraceReaderBlocked: "trace reader (blocked)",
+ waitReasonWaitForGCCycle: "wait for GC cycle",
+ waitReasonGCWorkerIdle: "GC worker (idle)",
+ waitReasonGCWorkerActive: "GC worker (active)",
+ waitReasonPreempted: "preempted",
+ waitReasonDebugCall: "debug call",
+ waitReasonGCMarkTermination: "GC mark termination",
+ waitReasonStoppingTheWorld: "stopping the world",
+}
+
+func (w waitReason) String() string {
+ if w < 0 || w >= waitReason(len(waitReasonStrings)) {
+ return "unknown wait reason"
+ }
+ return waitReasonStrings[w]
+}
+
+func (w waitReason) isMutexWait() bool {
+ return w == waitReasonSyncMutexLock ||
+ w == waitReasonSyncRWMutexRLock ||
+ w == waitReasonSyncRWMutexLock
+}
+
+var (
+ allm *m
+ gomaxprocs int32
+ ncpu int32
+ forcegc forcegcstate
+ sched schedt
+ newprocs int32
+
+ // allpLock protects P-less reads and size changes of allp, idlepMask,
+ // and timerpMask, and all writes to allp.
+ allpLock mutex
+ // len(allp) == gomaxprocs; may change at safe points, otherwise
+ // immutable.
+ allp []*p
+ // Bitmask of Ps in _Pidle list, one bit per P. Reads and writes must
+ // be atomic. Length may change at safe points.
+ //
+ // Each P must update only its own bit. In order to maintain
+ // consistency, a P going idle must the idle mask simultaneously with
+ // updates to the idle P list under the sched.lock, otherwise a racing
+ // pidleget may clear the mask before pidleput sets the mask,
+ // corrupting the bitmap.
+ //
+ // N.B., procresize takes ownership of all Ps in stopTheWorldWithSema.
+ idlepMask pMask
+ // Bitmask of Ps that may have a timer, one bit per P. Reads and writes
+ // must be atomic. Length may change at safe points.
+ timerpMask pMask
+
+ // Pool of GC parked background workers. Entries are type
+ // *gcBgMarkWorkerNode.
+ gcBgMarkWorkerPool lfstack
+
+ // Total number of gcBgMarkWorker goroutines. Protected by worldsema.
+ gcBgMarkWorkerCount int32
+
+ // Information about what cpu features are available.
+ // Packages outside the runtime should not use these
+ // as they are not an external api.
+ // Set on startup in asm_{386,amd64}.s
+ processorVersionInfo uint32
+ isIntel bool
+
+ goarm uint8 // set by cmd/link on arm systems
+)
+
+// Set by the linker so the runtime can determine the buildmode.
+var (
+ islibrary bool // -buildmode=c-shared
+ isarchive bool // -buildmode=c-archive
+)
+
+// Must agree with internal/buildcfg.FramePointerEnabled.
+const framepointer_enabled = GOARCH == "amd64" || GOARCH == "arm64"
diff --git a/contrib/go/_std_1.20/src/runtime/runtime_boring.go b/contrib/go/_std_1.21/src/runtime/runtime_boring.go
index 1ee91d667e..1ee91d667e 100644
--- a/contrib/go/_std_1.20/src/runtime/runtime_boring.go
+++ b/contrib/go/_std_1.21/src/runtime/runtime_boring.go
diff --git a/contrib/go/_std_1.20/src/runtime/rwmutex.go b/contrib/go/_std_1.21/src/runtime/rwmutex.go
index ede3d13599..ede3d13599 100644
--- a/contrib/go/_std_1.20/src/runtime/rwmutex.go
+++ b/contrib/go/_std_1.21/src/runtime/rwmutex.go
diff --git a/contrib/go/_std_1.20/src/runtime/security_issetugid.go b/contrib/go/_std_1.21/src/runtime/security_issetugid.go
index 5048632c3a..5048632c3a 100644
--- a/contrib/go/_std_1.20/src/runtime/security_issetugid.go
+++ b/contrib/go/_std_1.21/src/runtime/security_issetugid.go
diff --git a/contrib/go/_std_1.20/src/runtime/security_linux.go b/contrib/go/_std_1.21/src/runtime/security_linux.go
index 181f3a184e..181f3a184e 100644
--- a/contrib/go/_std_1.20/src/runtime/security_linux.go
+++ b/contrib/go/_std_1.21/src/runtime/security_linux.go
diff --git a/contrib/go/_std_1.20/src/runtime/security_nonunix.go b/contrib/go/_std_1.21/src/runtime/security_nonunix.go
index fc9571cfcf..fc9571cfcf 100644
--- a/contrib/go/_std_1.20/src/runtime/security_nonunix.go
+++ b/contrib/go/_std_1.21/src/runtime/security_nonunix.go
diff --git a/contrib/go/_std_1.20/src/runtime/security_unix.go b/contrib/go/_std_1.21/src/runtime/security_unix.go
index 16fc87eece..16fc87eece 100644
--- a/contrib/go/_std_1.20/src/runtime/security_unix.go
+++ b/contrib/go/_std_1.21/src/runtime/security_unix.go
diff --git a/contrib/go/_std_1.21/src/runtime/select.go b/contrib/go/_std_1.21/src/runtime/select.go
new file mode 100644
index 0000000000..34c06375c2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/select.go
@@ -0,0 +1,632 @@
+// Copyright 2009 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 runtime
+
+// This file contains the implementation of Go select statements.
+
+import (
+ "internal/abi"
+ "unsafe"
+)
+
+const debugSelect = false
+
+// Select case descriptor.
+// Known to compiler.
+// Changes here must also be made in src/cmd/compile/internal/walk/select.go's scasetype.
+type scase struct {
+ c *hchan // chan
+ elem unsafe.Pointer // data element
+}
+
+var (
+ chansendpc = abi.FuncPCABIInternal(chansend)
+ chanrecvpc = abi.FuncPCABIInternal(chanrecv)
+)
+
+func selectsetpc(pc *uintptr) {
+ *pc = getcallerpc()
+}
+
+func sellock(scases []scase, lockorder []uint16) {
+ var c *hchan
+ for _, o := range lockorder {
+ c0 := scases[o].c
+ if c0 != c {
+ c = c0
+ lock(&c.lock)
+ }
+ }
+}
+
+func selunlock(scases []scase, lockorder []uint16) {
+ // We must be very careful here to not touch sel after we have unlocked
+ // the last lock, because sel can be freed right after the last unlock.
+ // Consider the following situation.
+ // First M calls runtime·park() in runtime·selectgo() passing the sel.
+ // Once runtime·park() has unlocked the last lock, another M makes
+ // the G that calls select runnable again and schedules it for execution.
+ // When the G runs on another M, it locks all the locks and frees sel.
+ // Now if the first M touches sel, it will access freed memory.
+ for i := len(lockorder) - 1; i >= 0; i-- {
+ c := scases[lockorder[i]].c
+ if i > 0 && c == scases[lockorder[i-1]].c {
+ continue // will unlock it on the next iteration
+ }
+ unlock(&c.lock)
+ }
+}
+
+func selparkcommit(gp *g, _ unsafe.Pointer) bool {
+ // There are unlocked sudogs that point into gp's stack. Stack
+ // copying must lock the channels of those sudogs.
+ // Set activeStackChans here instead of before we try parking
+ // because we could self-deadlock in stack growth on a
+ // channel lock.
+ gp.activeStackChans = true
+ // Mark that it's safe for stack shrinking to occur now,
+ // because any thread acquiring this G's stack for shrinking
+ // is guaranteed to observe activeStackChans after this store.
+ gp.parkingOnChan.Store(false)
+ // Make sure we unlock after setting activeStackChans and
+ // unsetting parkingOnChan. The moment we unlock any of the
+ // channel locks we risk gp getting readied by a channel operation
+ // and so gp could continue running before everything before the
+ // unlock is visible (even to gp itself).
+
+ // This must not access gp's stack (see gopark). In
+ // particular, it must not access the *hselect. That's okay,
+ // because by the time this is called, gp.waiting has all
+ // channels in lock order.
+ var lastc *hchan
+ for sg := gp.waiting; sg != nil; sg = sg.waitlink {
+ if sg.c != lastc && lastc != nil {
+ // As soon as we unlock the channel, fields in
+ // any sudog with that channel may change,
+ // including c and waitlink. Since multiple
+ // sudogs may have the same channel, we unlock
+ // only after we've passed the last instance
+ // of a channel.
+ unlock(&lastc.lock)
+ }
+ lastc = sg.c
+ }
+ if lastc != nil {
+ unlock(&lastc.lock)
+ }
+ return true
+}
+
+func block() {
+ gopark(nil, nil, waitReasonSelectNoCases, traceBlockForever, 1) // forever
+}
+
+// selectgo implements the select statement.
+//
+// cas0 points to an array of type [ncases]scase, and order0 points to
+// an array of type [2*ncases]uint16 where ncases must be <= 65536.
+// Both reside on the goroutine's stack (regardless of any escaping in
+// selectgo).
+//
+// For race detector builds, pc0 points to an array of type
+// [ncases]uintptr (also on the stack); for other builds, it's set to
+// nil.
+//
+// selectgo returns the index of the chosen scase, which matches the
+// ordinal position of its respective select{recv,send,default} call.
+// Also, if the chosen scase was a receive operation, it reports whether
+// a value was received.
+func selectgo(cas0 *scase, order0 *uint16, pc0 *uintptr, nsends, nrecvs int, block bool) (int, bool) {
+ if debugSelect {
+ print("select: cas0=", cas0, "\n")
+ }
+
+ // NOTE: In order to maintain a lean stack size, the number of scases
+ // is capped at 65536.
+ cas1 := (*[1 << 16]scase)(unsafe.Pointer(cas0))
+ order1 := (*[1 << 17]uint16)(unsafe.Pointer(order0))
+
+ ncases := nsends + nrecvs
+ scases := cas1[:ncases:ncases]
+ pollorder := order1[:ncases:ncases]
+ lockorder := order1[ncases:][:ncases:ncases]
+ // NOTE: pollorder/lockorder's underlying array was not zero-initialized by compiler.
+
+ // Even when raceenabled is true, there might be select
+ // statements in packages compiled without -race (e.g.,
+ // ensureSigM in runtime/signal_unix.go).
+ var pcs []uintptr
+ if raceenabled && pc0 != nil {
+ pc1 := (*[1 << 16]uintptr)(unsafe.Pointer(pc0))
+ pcs = pc1[:ncases:ncases]
+ }
+ casePC := func(casi int) uintptr {
+ if pcs == nil {
+ return 0
+ }
+ return pcs[casi]
+ }
+
+ var t0 int64
+ if blockprofilerate > 0 {
+ t0 = cputicks()
+ }
+
+ // The compiler rewrites selects that statically have
+ // only 0 or 1 cases plus default into simpler constructs.
+ // The only way we can end up with such small sel.ncase
+ // values here is for a larger select in which most channels
+ // have been nilled out. The general code handles those
+ // cases correctly, and they are rare enough not to bother
+ // optimizing (and needing to test).
+
+ // generate permuted order
+ norder := 0
+ for i := range scases {
+ cas := &scases[i]
+
+ // Omit cases without channels from the poll and lock orders.
+ if cas.c == nil {
+ cas.elem = nil // allow GC
+ continue
+ }
+
+ j := fastrandn(uint32(norder + 1))
+ pollorder[norder] = pollorder[j]
+ pollorder[j] = uint16(i)
+ norder++
+ }
+ pollorder = pollorder[:norder]
+ lockorder = lockorder[:norder]
+
+ // sort the cases by Hchan address to get the locking order.
+ // simple heap sort, to guarantee n log n time and constant stack footprint.
+ for i := range lockorder {
+ j := i
+ // Start with the pollorder to permute cases on the same channel.
+ c := scases[pollorder[i]].c
+ for j > 0 && scases[lockorder[(j-1)/2]].c.sortkey() < c.sortkey() {
+ k := (j - 1) / 2
+ lockorder[j] = lockorder[k]
+ j = k
+ }
+ lockorder[j] = pollorder[i]
+ }
+ for i := len(lockorder) - 1; i >= 0; i-- {
+ o := lockorder[i]
+ c := scases[o].c
+ lockorder[i] = lockorder[0]
+ j := 0
+ for {
+ k := j*2 + 1
+ if k >= i {
+ break
+ }
+ if k+1 < i && scases[lockorder[k]].c.sortkey() < scases[lockorder[k+1]].c.sortkey() {
+ k++
+ }
+ if c.sortkey() < scases[lockorder[k]].c.sortkey() {
+ lockorder[j] = lockorder[k]
+ j = k
+ continue
+ }
+ break
+ }
+ lockorder[j] = o
+ }
+
+ if debugSelect {
+ for i := 0; i+1 < len(lockorder); i++ {
+ if scases[lockorder[i]].c.sortkey() > scases[lockorder[i+1]].c.sortkey() {
+ print("i=", i, " x=", lockorder[i], " y=", lockorder[i+1], "\n")
+ throw("select: broken sort")
+ }
+ }
+ }
+
+ // lock all the channels involved in the select
+ sellock(scases, lockorder)
+
+ var (
+ gp *g
+ sg *sudog
+ c *hchan
+ k *scase
+ sglist *sudog
+ sgnext *sudog
+ qp unsafe.Pointer
+ nextp **sudog
+ )
+
+ // pass 1 - look for something already waiting
+ var casi int
+ var cas *scase
+ var caseSuccess bool
+ var caseReleaseTime int64 = -1
+ var recvOK bool
+ for _, casei := range pollorder {
+ casi = int(casei)
+ cas = &scases[casi]
+ c = cas.c
+
+ if casi >= nsends {
+ sg = c.sendq.dequeue()
+ if sg != nil {
+ goto recv
+ }
+ if c.qcount > 0 {
+ goto bufrecv
+ }
+ if c.closed != 0 {
+ goto rclose
+ }
+ } else {
+ if raceenabled {
+ racereadpc(c.raceaddr(), casePC(casi), chansendpc)
+ }
+ if c.closed != 0 {
+ goto sclose
+ }
+ sg = c.recvq.dequeue()
+ if sg != nil {
+ goto send
+ }
+ if c.qcount < c.dataqsiz {
+ goto bufsend
+ }
+ }
+ }
+
+ if !block {
+ selunlock(scases, lockorder)
+ casi = -1
+ goto retc
+ }
+
+ // pass 2 - enqueue on all chans
+ gp = getg()
+ if gp.waiting != nil {
+ throw("gp.waiting != nil")
+ }
+ nextp = &gp.waiting
+ for _, casei := range lockorder {
+ casi = int(casei)
+ cas = &scases[casi]
+ c = cas.c
+ sg := acquireSudog()
+ sg.g = gp
+ sg.isSelect = true
+ // No stack splits between assigning elem and enqueuing
+ // sg on gp.waiting where copystack can find it.
+ sg.elem = cas.elem
+ sg.releasetime = 0
+ if t0 != 0 {
+ sg.releasetime = -1
+ }
+ sg.c = c
+ // Construct waiting list in lock order.
+ *nextp = sg
+ nextp = &sg.waitlink
+
+ if casi < nsends {
+ c.sendq.enqueue(sg)
+ } else {
+ c.recvq.enqueue(sg)
+ }
+ }
+
+ // wait for someone to wake us up
+ gp.param = nil
+ // Signal to anyone trying to shrink our stack that we're about
+ // to park on a channel. The window between when this G's status
+ // changes and when we set gp.activeStackChans is not safe for
+ // stack shrinking.
+ gp.parkingOnChan.Store(true)
+ gopark(selparkcommit, nil, waitReasonSelect, traceBlockSelect, 1)
+ gp.activeStackChans = false
+
+ sellock(scases, lockorder)
+
+ gp.selectDone.Store(0)
+ sg = (*sudog)(gp.param)
+ gp.param = nil
+
+ // pass 3 - dequeue from unsuccessful chans
+ // otherwise they stack up on quiet channels
+ // record the successful case, if any.
+ // We singly-linked up the SudoGs in lock order.
+ casi = -1
+ cas = nil
+ caseSuccess = false
+ sglist = gp.waiting
+ // Clear all elem before unlinking from gp.waiting.
+ for sg1 := gp.waiting; sg1 != nil; sg1 = sg1.waitlink {
+ sg1.isSelect = false
+ sg1.elem = nil
+ sg1.c = nil
+ }
+ gp.waiting = nil
+
+ for _, casei := range lockorder {
+ k = &scases[casei]
+ if sg == sglist {
+ // sg has already been dequeued by the G that woke us up.
+ casi = int(casei)
+ cas = k
+ caseSuccess = sglist.success
+ if sglist.releasetime > 0 {
+ caseReleaseTime = sglist.releasetime
+ }
+ } else {
+ c = k.c
+ if int(casei) < nsends {
+ c.sendq.dequeueSudoG(sglist)
+ } else {
+ c.recvq.dequeueSudoG(sglist)
+ }
+ }
+ sgnext = sglist.waitlink
+ sglist.waitlink = nil
+ releaseSudog(sglist)
+ sglist = sgnext
+ }
+
+ if cas == nil {
+ throw("selectgo: bad wakeup")
+ }
+
+ c = cas.c
+
+ if debugSelect {
+ print("wait-return: cas0=", cas0, " c=", c, " cas=", cas, " send=", casi < nsends, "\n")
+ }
+
+ if casi < nsends {
+ if !caseSuccess {
+ goto sclose
+ }
+ } else {
+ recvOK = caseSuccess
+ }
+
+ if raceenabled {
+ if casi < nsends {
+ raceReadObjectPC(c.elemtype, cas.elem, casePC(casi), chansendpc)
+ } else if cas.elem != nil {
+ raceWriteObjectPC(c.elemtype, cas.elem, casePC(casi), chanrecvpc)
+ }
+ }
+ if msanenabled {
+ if casi < nsends {
+ msanread(cas.elem, c.elemtype.Size_)
+ } else if cas.elem != nil {
+ msanwrite(cas.elem, c.elemtype.Size_)
+ }
+ }
+ if asanenabled {
+ if casi < nsends {
+ asanread(cas.elem, c.elemtype.Size_)
+ } else if cas.elem != nil {
+ asanwrite(cas.elem, c.elemtype.Size_)
+ }
+ }
+
+ selunlock(scases, lockorder)
+ goto retc
+
+bufrecv:
+ // can receive from buffer
+ if raceenabled {
+ if cas.elem != nil {
+ raceWriteObjectPC(c.elemtype, cas.elem, casePC(casi), chanrecvpc)
+ }
+ racenotify(c, c.recvx, nil)
+ }
+ if msanenabled && cas.elem != nil {
+ msanwrite(cas.elem, c.elemtype.Size_)
+ }
+ if asanenabled && cas.elem != nil {
+ asanwrite(cas.elem, c.elemtype.Size_)
+ }
+ recvOK = true
+ qp = chanbuf(c, c.recvx)
+ if cas.elem != nil {
+ typedmemmove(c.elemtype, cas.elem, qp)
+ }
+ typedmemclr(c.elemtype, qp)
+ c.recvx++
+ if c.recvx == c.dataqsiz {
+ c.recvx = 0
+ }
+ c.qcount--
+ selunlock(scases, lockorder)
+ goto retc
+
+bufsend:
+ // can send to buffer
+ if raceenabled {
+ racenotify(c, c.sendx, nil)
+ raceReadObjectPC(c.elemtype, cas.elem, casePC(casi), chansendpc)
+ }
+ if msanenabled {
+ msanread(cas.elem, c.elemtype.Size_)
+ }
+ if asanenabled {
+ asanread(cas.elem, c.elemtype.Size_)
+ }
+ typedmemmove(c.elemtype, chanbuf(c, c.sendx), cas.elem)
+ c.sendx++
+ if c.sendx == c.dataqsiz {
+ c.sendx = 0
+ }
+ c.qcount++
+ selunlock(scases, lockorder)
+ goto retc
+
+recv:
+ // can receive from sleeping sender (sg)
+ recv(c, sg, cas.elem, func() { selunlock(scases, lockorder) }, 2)
+ if debugSelect {
+ print("syncrecv: cas0=", cas0, " c=", c, "\n")
+ }
+ recvOK = true
+ goto retc
+
+rclose:
+ // read at end of closed channel
+ selunlock(scases, lockorder)
+ recvOK = false
+ if cas.elem != nil {
+ typedmemclr(c.elemtype, cas.elem)
+ }
+ if raceenabled {
+ raceacquire(c.raceaddr())
+ }
+ goto retc
+
+send:
+ // can send to a sleeping receiver (sg)
+ if raceenabled {
+ raceReadObjectPC(c.elemtype, cas.elem, casePC(casi), chansendpc)
+ }
+ if msanenabled {
+ msanread(cas.elem, c.elemtype.Size_)
+ }
+ if asanenabled {
+ asanread(cas.elem, c.elemtype.Size_)
+ }
+ send(c, sg, cas.elem, func() { selunlock(scases, lockorder) }, 2)
+ if debugSelect {
+ print("syncsend: cas0=", cas0, " c=", c, "\n")
+ }
+ goto retc
+
+retc:
+ if caseReleaseTime > 0 {
+ blockevent(caseReleaseTime-t0, 1)
+ }
+ return casi, recvOK
+
+sclose:
+ // send on closed channel
+ selunlock(scases, lockorder)
+ panic(plainError("send on closed channel"))
+}
+
+func (c *hchan) sortkey() uintptr {
+ return uintptr(unsafe.Pointer(c))
+}
+
+// A runtimeSelect is a single case passed to rselect.
+// This must match ../reflect/value.go:/runtimeSelect
+type runtimeSelect struct {
+ dir selectDir
+ typ unsafe.Pointer // channel type (not used here)
+ ch *hchan // channel
+ val unsafe.Pointer // ptr to data (SendDir) or ptr to receive buffer (RecvDir)
+}
+
+// These values must match ../reflect/value.go:/SelectDir.
+type selectDir int
+
+const (
+ _ selectDir = iota
+ selectSend // case Chan <- Send
+ selectRecv // case <-Chan:
+ selectDefault // default
+)
+
+//go:linkname reflect_rselect reflect.rselect
+func reflect_rselect(cases []runtimeSelect) (int, bool) {
+ if len(cases) == 0 {
+ block()
+ }
+ sel := make([]scase, len(cases))
+ orig := make([]int, len(cases))
+ nsends, nrecvs := 0, 0
+ dflt := -1
+ for i, rc := range cases {
+ var j int
+ switch rc.dir {
+ case selectDefault:
+ dflt = i
+ continue
+ case selectSend:
+ j = nsends
+ nsends++
+ case selectRecv:
+ nrecvs++
+ j = len(cases) - nrecvs
+ }
+
+ sel[j] = scase{c: rc.ch, elem: rc.val}
+ orig[j] = i
+ }
+
+ // Only a default case.
+ if nsends+nrecvs == 0 {
+ return dflt, false
+ }
+
+ // Compact sel and orig if necessary.
+ if nsends+nrecvs < len(cases) {
+ copy(sel[nsends:], sel[len(cases)-nrecvs:])
+ copy(orig[nsends:], orig[len(cases)-nrecvs:])
+ }
+
+ order := make([]uint16, 2*(nsends+nrecvs))
+ var pc0 *uintptr
+ if raceenabled {
+ pcs := make([]uintptr, nsends+nrecvs)
+ for i := range pcs {
+ selectsetpc(&pcs[i])
+ }
+ pc0 = &pcs[0]
+ }
+
+ chosen, recvOK := selectgo(&sel[0], &order[0], pc0, nsends, nrecvs, dflt == -1)
+
+ // Translate chosen back to caller's ordering.
+ if chosen < 0 {
+ chosen = dflt
+ } else {
+ chosen = orig[chosen]
+ }
+ return chosen, recvOK
+}
+
+func (q *waitq) dequeueSudoG(sgp *sudog) {
+ x := sgp.prev
+ y := sgp.next
+ if x != nil {
+ if y != nil {
+ // middle of queue
+ x.next = y
+ y.prev = x
+ sgp.next = nil
+ sgp.prev = nil
+ return
+ }
+ // end of queue
+ x.next = nil
+ q.last = x
+ sgp.prev = nil
+ return
+ }
+ if y != nil {
+ // start of queue
+ y.prev = nil
+ q.first = y
+ sgp.next = nil
+ return
+ }
+
+ // x==y==nil. Either sgp is the only element in the queue,
+ // or it has already been removed. Use q.first to disambiguate.
+ if q.first == sgp {
+ q.first = nil
+ q.last = nil
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/sema.go b/contrib/go/_std_1.21/src/runtime/sema.go
new file mode 100644
index 0000000000..d0a81170c3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/sema.go
@@ -0,0 +1,633 @@
+// Copyright 2009 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.
+
+// Semaphore implementation exposed to Go.
+// Intended use is provide a sleep and wakeup
+// primitive that can be used in the contended case
+// of other synchronization primitives.
+// Thus it targets the same goal as Linux's futex,
+// but it has much simpler semantics.
+//
+// That is, don't think of these as semaphores.
+// Think of them as a way to implement sleep and wakeup
+// such that every sleep is paired with a single wakeup,
+// even if, due to races, the wakeup happens before the sleep.
+//
+// See Mullender and Cox, ``Semaphores in Plan 9,''
+// https://swtch.com/semaphore.pdf
+
+package runtime
+
+import (
+ "internal/cpu"
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// Asynchronous semaphore for sync.Mutex.
+
+// A semaRoot holds a balanced tree of sudog with distinct addresses (s.elem).
+// Each of those sudog may in turn point (through s.waitlink) to a list
+// of other sudogs waiting on the same address.
+// The operations on the inner lists of sudogs with the same address
+// are all O(1). The scanning of the top-level semaRoot list is O(log n),
+// where n is the number of distinct addresses with goroutines blocked
+// on them that hash to the given semaRoot.
+// See golang.org/issue/17953 for a program that worked badly
+// before we introduced the second level of list, and
+// BenchmarkSemTable/OneAddrCollision/* for a benchmark that exercises this.
+type semaRoot struct {
+ lock mutex
+ treap *sudog // root of balanced tree of unique waiters.
+ nwait atomic.Uint32 // Number of waiters. Read w/o the lock.
+}
+
+var semtable semTable
+
+// Prime to not correlate with any user patterns.
+const semTabSize = 251
+
+type semTable [semTabSize]struct {
+ root semaRoot
+ pad [cpu.CacheLinePadSize - unsafe.Sizeof(semaRoot{})]byte
+}
+
+func (t *semTable) rootFor(addr *uint32) *semaRoot {
+ return &t[(uintptr(unsafe.Pointer(addr))>>3)%semTabSize].root
+}
+
+//go:linkname sync_runtime_Semacquire sync.runtime_Semacquire
+func sync_runtime_Semacquire(addr *uint32) {
+ semacquire1(addr, false, semaBlockProfile, 0, waitReasonSemacquire)
+}
+
+//go:linkname poll_runtime_Semacquire internal/poll.runtime_Semacquire
+func poll_runtime_Semacquire(addr *uint32) {
+ semacquire1(addr, false, semaBlockProfile, 0, waitReasonSemacquire)
+}
+
+//go:linkname sync_runtime_Semrelease sync.runtime_Semrelease
+func sync_runtime_Semrelease(addr *uint32, handoff bool, skipframes int) {
+ semrelease1(addr, handoff, skipframes)
+}
+
+//go:linkname sync_runtime_SemacquireMutex sync.runtime_SemacquireMutex
+func sync_runtime_SemacquireMutex(addr *uint32, lifo bool, skipframes int) {
+ semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes, waitReasonSyncMutexLock)
+}
+
+//go:linkname sync_runtime_SemacquireRWMutexR sync.runtime_SemacquireRWMutexR
+func sync_runtime_SemacquireRWMutexR(addr *uint32, lifo bool, skipframes int) {
+ semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes, waitReasonSyncRWMutexRLock)
+}
+
+//go:linkname sync_runtime_SemacquireRWMutex sync.runtime_SemacquireRWMutex
+func sync_runtime_SemacquireRWMutex(addr *uint32, lifo bool, skipframes int) {
+ semacquire1(addr, lifo, semaBlockProfile|semaMutexProfile, skipframes, waitReasonSyncRWMutexLock)
+}
+
+//go:linkname poll_runtime_Semrelease internal/poll.runtime_Semrelease
+func poll_runtime_Semrelease(addr *uint32) {
+ semrelease(addr)
+}
+
+func readyWithTime(s *sudog, traceskip int) {
+ if s.releasetime != 0 {
+ s.releasetime = cputicks()
+ }
+ goready(s.g, traceskip)
+}
+
+type semaProfileFlags int
+
+const (
+ semaBlockProfile semaProfileFlags = 1 << iota
+ semaMutexProfile
+)
+
+// Called from runtime.
+func semacquire(addr *uint32) {
+ semacquire1(addr, false, 0, 0, waitReasonSemacquire)
+}
+
+func semacquire1(addr *uint32, lifo bool, profile semaProfileFlags, skipframes int, reason waitReason) {
+ gp := getg()
+ if gp != gp.m.curg {
+ throw("semacquire not on the G stack")
+ }
+
+ // Easy case.
+ if cansemacquire(addr) {
+ return
+ }
+
+ // Harder case:
+ // increment waiter count
+ // try cansemacquire one more time, return if succeeded
+ // enqueue itself as a waiter
+ // sleep
+ // (waiter descriptor is dequeued by signaler)
+ s := acquireSudog()
+ root := semtable.rootFor(addr)
+ t0 := int64(0)
+ s.releasetime = 0
+ s.acquiretime = 0
+ s.ticket = 0
+ if profile&semaBlockProfile != 0 && blockprofilerate > 0 {
+ t0 = cputicks()
+ s.releasetime = -1
+ }
+ if profile&semaMutexProfile != 0 && mutexprofilerate > 0 {
+ if t0 == 0 {
+ t0 = cputicks()
+ }
+ s.acquiretime = t0
+ }
+ for {
+ lockWithRank(&root.lock, lockRankRoot)
+ // Add ourselves to nwait to disable "easy case" in semrelease.
+ root.nwait.Add(1)
+ // Check cansemacquire to avoid missed wakeup.
+ if cansemacquire(addr) {
+ root.nwait.Add(-1)
+ unlock(&root.lock)
+ break
+ }
+ // Any semrelease after the cansemacquire knows we're waiting
+ // (we set nwait above), so go to sleep.
+ root.queue(addr, s, lifo)
+ goparkunlock(&root.lock, reason, traceBlockSync, 4+skipframes)
+ if s.ticket != 0 || cansemacquire(addr) {
+ break
+ }
+ }
+ if s.releasetime > 0 {
+ blockevent(s.releasetime-t0, 3+skipframes)
+ }
+ releaseSudog(s)
+}
+
+func semrelease(addr *uint32) {
+ semrelease1(addr, false, 0)
+}
+
+func semrelease1(addr *uint32, handoff bool, skipframes int) {
+ root := semtable.rootFor(addr)
+ atomic.Xadd(addr, 1)
+
+ // Easy case: no waiters?
+ // This check must happen after the xadd, to avoid a missed wakeup
+ // (see loop in semacquire).
+ if root.nwait.Load() == 0 {
+ return
+ }
+
+ // Harder case: search for a waiter and wake it.
+ lockWithRank(&root.lock, lockRankRoot)
+ if root.nwait.Load() == 0 {
+ // The count is already consumed by another goroutine,
+ // so no need to wake up another goroutine.
+ unlock(&root.lock)
+ return
+ }
+ s, t0 := root.dequeue(addr)
+ if s != nil {
+ root.nwait.Add(-1)
+ }
+ unlock(&root.lock)
+ if s != nil { // May be slow or even yield, so unlock first
+ acquiretime := s.acquiretime
+ if acquiretime != 0 {
+ mutexevent(t0-acquiretime, 3+skipframes)
+ }
+ if s.ticket != 0 {
+ throw("corrupted semaphore ticket")
+ }
+ if handoff && cansemacquire(addr) {
+ s.ticket = 1
+ }
+ readyWithTime(s, 5+skipframes)
+ if s.ticket == 1 && getg().m.locks == 0 {
+ // Direct G handoff
+ // readyWithTime has added the waiter G as runnext in the
+ // current P; we now call the scheduler so that we start running
+ // the waiter G immediately.
+ // Note that waiter inherits our time slice: this is desirable
+ // to avoid having a highly contended semaphore hog the P
+ // indefinitely. goyield is like Gosched, but it emits a
+ // "preempted" trace event instead and, more importantly, puts
+ // the current G on the local runq instead of the global one.
+ // We only do this in the starving regime (handoff=true), as in
+ // the non-starving case it is possible for a different waiter
+ // to acquire the semaphore while we are yielding/scheduling,
+ // and this would be wasteful. We wait instead to enter starving
+ // regime, and then we start to do direct handoffs of ticket and
+ // P.
+ // See issue 33747 for discussion.
+ goyield()
+ }
+ }
+}
+
+func cansemacquire(addr *uint32) bool {
+ for {
+ v := atomic.Load(addr)
+ if v == 0 {
+ return false
+ }
+ if atomic.Cas(addr, v, v-1) {
+ return true
+ }
+ }
+}
+
+// queue adds s to the blocked goroutines in semaRoot.
+func (root *semaRoot) queue(addr *uint32, s *sudog, lifo bool) {
+ s.g = getg()
+ s.elem = unsafe.Pointer(addr)
+ s.next = nil
+ s.prev = nil
+
+ var last *sudog
+ pt := &root.treap
+ for t := *pt; t != nil; t = *pt {
+ if t.elem == unsafe.Pointer(addr) {
+ // Already have addr in list.
+ if lifo {
+ // Substitute s in t's place in treap.
+ *pt = s
+ s.ticket = t.ticket
+ s.acquiretime = t.acquiretime
+ s.parent = t.parent
+ s.prev = t.prev
+ s.next = t.next
+ if s.prev != nil {
+ s.prev.parent = s
+ }
+ if s.next != nil {
+ s.next.parent = s
+ }
+ // Add t first in s's wait list.
+ s.waitlink = t
+ s.waittail = t.waittail
+ if s.waittail == nil {
+ s.waittail = t
+ }
+ t.parent = nil
+ t.prev = nil
+ t.next = nil
+ t.waittail = nil
+ } else {
+ // Add s to end of t's wait list.
+ if t.waittail == nil {
+ t.waitlink = s
+ } else {
+ t.waittail.waitlink = s
+ }
+ t.waittail = s
+ s.waitlink = nil
+ }
+ return
+ }
+ last = t
+ if uintptr(unsafe.Pointer(addr)) < uintptr(t.elem) {
+ pt = &t.prev
+ } else {
+ pt = &t.next
+ }
+ }
+
+ // Add s as new leaf in tree of unique addrs.
+ // The balanced tree is a treap using ticket as the random heap priority.
+ // That is, it is a binary tree ordered according to the elem addresses,
+ // but then among the space of possible binary trees respecting those
+ // addresses, it is kept balanced on average by maintaining a heap ordering
+ // on the ticket: s.ticket <= both s.prev.ticket and s.next.ticket.
+ // https://en.wikipedia.org/wiki/Treap
+ // https://faculty.washington.edu/aragon/pubs/rst89.pdf
+ //
+ // s.ticket compared with zero in couple of places, therefore set lowest bit.
+ // It will not affect treap's quality noticeably.
+ s.ticket = fastrand() | 1
+ s.parent = last
+ *pt = s
+
+ // Rotate up into tree according to ticket (priority).
+ for s.parent != nil && s.parent.ticket > s.ticket {
+ if s.parent.prev == s {
+ root.rotateRight(s.parent)
+ } else {
+ if s.parent.next != s {
+ panic("semaRoot queue")
+ }
+ root.rotateLeft(s.parent)
+ }
+ }
+}
+
+// dequeue searches for and finds the first goroutine
+// in semaRoot blocked on addr.
+// If the sudog was being profiled, dequeue returns the time
+// at which it was woken up as now. Otherwise now is 0.
+func (root *semaRoot) dequeue(addr *uint32) (found *sudog, now int64) {
+ ps := &root.treap
+ s := *ps
+ for ; s != nil; s = *ps {
+ if s.elem == unsafe.Pointer(addr) {
+ goto Found
+ }
+ if uintptr(unsafe.Pointer(addr)) < uintptr(s.elem) {
+ ps = &s.prev
+ } else {
+ ps = &s.next
+ }
+ }
+ return nil, 0
+
+Found:
+ now = int64(0)
+ if s.acquiretime != 0 {
+ now = cputicks()
+ }
+ if t := s.waitlink; t != nil {
+ // Substitute t, also waiting on addr, for s in root tree of unique addrs.
+ *ps = t
+ t.ticket = s.ticket
+ t.parent = s.parent
+ t.prev = s.prev
+ if t.prev != nil {
+ t.prev.parent = t
+ }
+ t.next = s.next
+ if t.next != nil {
+ t.next.parent = t
+ }
+ if t.waitlink != nil {
+ t.waittail = s.waittail
+ } else {
+ t.waittail = nil
+ }
+ t.acquiretime = now
+ s.waitlink = nil
+ s.waittail = nil
+ } else {
+ // Rotate s down to be leaf of tree for removal, respecting priorities.
+ for s.next != nil || s.prev != nil {
+ if s.next == nil || s.prev != nil && s.prev.ticket < s.next.ticket {
+ root.rotateRight(s)
+ } else {
+ root.rotateLeft(s)
+ }
+ }
+ // Remove s, now a leaf.
+ if s.parent != nil {
+ if s.parent.prev == s {
+ s.parent.prev = nil
+ } else {
+ s.parent.next = nil
+ }
+ } else {
+ root.treap = nil
+ }
+ }
+ s.parent = nil
+ s.elem = nil
+ s.next = nil
+ s.prev = nil
+ s.ticket = 0
+ return s, now
+}
+
+// rotateLeft rotates the tree rooted at node x.
+// turning (x a (y b c)) into (y (x a b) c).
+func (root *semaRoot) rotateLeft(x *sudog) {
+ // p -> (x a (y b c))
+ p := x.parent
+ y := x.next
+ b := y.prev
+
+ y.prev = x
+ x.parent = y
+ x.next = b
+ if b != nil {
+ b.parent = x
+ }
+
+ y.parent = p
+ if p == nil {
+ root.treap = y
+ } else if p.prev == x {
+ p.prev = y
+ } else {
+ if p.next != x {
+ throw("semaRoot rotateLeft")
+ }
+ p.next = y
+ }
+}
+
+// rotateRight rotates the tree rooted at node y.
+// turning (y (x a b) c) into (x a (y b c)).
+func (root *semaRoot) rotateRight(y *sudog) {
+ // p -> (y (x a b) c)
+ p := y.parent
+ x := y.prev
+ b := x.next
+
+ x.next = y
+ y.parent = x
+ y.prev = b
+ if b != nil {
+ b.parent = y
+ }
+
+ x.parent = p
+ if p == nil {
+ root.treap = x
+ } else if p.prev == y {
+ p.prev = x
+ } else {
+ if p.next != y {
+ throw("semaRoot rotateRight")
+ }
+ p.next = x
+ }
+}
+
+// notifyList is a ticket-based notification list used to implement sync.Cond.
+//
+// It must be kept in sync with the sync package.
+type notifyList struct {
+ // wait is the ticket number of the next waiter. It is atomically
+ // incremented outside the lock.
+ wait atomic.Uint32
+
+ // notify is the ticket number of the next waiter to be notified. It can
+ // be read outside the lock, but is only written to with lock held.
+ //
+ // Both wait & notify can wrap around, and such cases will be correctly
+ // handled as long as their "unwrapped" difference is bounded by 2^31.
+ // For this not to be the case, we'd need to have 2^31+ goroutines
+ // blocked on the same condvar, which is currently not possible.
+ notify uint32
+
+ // List of parked waiters.
+ lock mutex
+ head *sudog
+ tail *sudog
+}
+
+// less checks if a < b, considering a & b running counts that may overflow the
+// 32-bit range, and that their "unwrapped" difference is always less than 2^31.
+func less(a, b uint32) bool {
+ return int32(a-b) < 0
+}
+
+// notifyListAdd adds the caller to a notify list such that it can receive
+// notifications. The caller must eventually call notifyListWait to wait for
+// such a notification, passing the returned ticket number.
+//
+//go:linkname notifyListAdd sync.runtime_notifyListAdd
+func notifyListAdd(l *notifyList) uint32 {
+ // This may be called concurrently, for example, when called from
+ // sync.Cond.Wait while holding a RWMutex in read mode.
+ return l.wait.Add(1) - 1
+}
+
+// notifyListWait waits for a notification. If one has been sent since
+// notifyListAdd was called, it returns immediately. Otherwise, it blocks.
+//
+//go:linkname notifyListWait sync.runtime_notifyListWait
+func notifyListWait(l *notifyList, t uint32) {
+ lockWithRank(&l.lock, lockRankNotifyList)
+
+ // Return right away if this ticket has already been notified.
+ if less(t, l.notify) {
+ unlock(&l.lock)
+ return
+ }
+
+ // Enqueue itself.
+ s := acquireSudog()
+ s.g = getg()
+ s.ticket = t
+ s.releasetime = 0
+ t0 := int64(0)
+ if blockprofilerate > 0 {
+ t0 = cputicks()
+ s.releasetime = -1
+ }
+ if l.tail == nil {
+ l.head = s
+ } else {
+ l.tail.next = s
+ }
+ l.tail = s
+ goparkunlock(&l.lock, waitReasonSyncCondWait, traceBlockCondWait, 3)
+ if t0 != 0 {
+ blockevent(s.releasetime-t0, 2)
+ }
+ releaseSudog(s)
+}
+
+// notifyListNotifyAll notifies all entries in the list.
+//
+//go:linkname notifyListNotifyAll sync.runtime_notifyListNotifyAll
+func notifyListNotifyAll(l *notifyList) {
+ // Fast-path: if there are no new waiters since the last notification
+ // we don't need to acquire the lock.
+ if l.wait.Load() == atomic.Load(&l.notify) {
+ return
+ }
+
+ // Pull the list out into a local variable, waiters will be readied
+ // outside the lock.
+ lockWithRank(&l.lock, lockRankNotifyList)
+ s := l.head
+ l.head = nil
+ l.tail = nil
+
+ // Update the next ticket to be notified. We can set it to the current
+ // value of wait because any previous waiters are already in the list
+ // or will notice that they have already been notified when trying to
+ // add themselves to the list.
+ atomic.Store(&l.notify, l.wait.Load())
+ unlock(&l.lock)
+
+ // Go through the local list and ready all waiters.
+ for s != nil {
+ next := s.next
+ s.next = nil
+ readyWithTime(s, 4)
+ s = next
+ }
+}
+
+// notifyListNotifyOne notifies one entry in the list.
+//
+//go:linkname notifyListNotifyOne sync.runtime_notifyListNotifyOne
+func notifyListNotifyOne(l *notifyList) {
+ // Fast-path: if there are no new waiters since the last notification
+ // we don't need to acquire the lock at all.
+ if l.wait.Load() == atomic.Load(&l.notify) {
+ return
+ }
+
+ lockWithRank(&l.lock, lockRankNotifyList)
+
+ // Re-check under the lock if we need to do anything.
+ t := l.notify
+ if t == l.wait.Load() {
+ unlock(&l.lock)
+ return
+ }
+
+ // Update the next notify ticket number.
+ atomic.Store(&l.notify, t+1)
+
+ // Try to find the g that needs to be notified.
+ // If it hasn't made it to the list yet we won't find it,
+ // but it won't park itself once it sees the new notify number.
+ //
+ // This scan looks linear but essentially always stops quickly.
+ // Because g's queue separately from taking numbers,
+ // there may be minor reorderings in the list, but we
+ // expect the g we're looking for to be near the front.
+ // The g has others in front of it on the list only to the
+ // extent that it lost the race, so the iteration will not
+ // be too long. This applies even when the g is missing:
+ // it hasn't yet gotten to sleep and has lost the race to
+ // the (few) other g's that we find on the list.
+ for p, s := (*sudog)(nil), l.head; s != nil; p, s = s, s.next {
+ if s.ticket == t {
+ n := s.next
+ if p != nil {
+ p.next = n
+ } else {
+ l.head = n
+ }
+ if n == nil {
+ l.tail = p
+ }
+ unlock(&l.lock)
+ s.next = nil
+ readyWithTime(s, 4)
+ return
+ }
+ }
+ unlock(&l.lock)
+}
+
+//go:linkname notifyListCheck sync.runtime_notifyListCheck
+func notifyListCheck(sz uintptr) {
+ if sz != unsafe.Sizeof(notifyList{}) {
+ print("runtime: bad notifyList size - sync=", sz, " runtime=", unsafe.Sizeof(notifyList{}), "\n")
+ throw("bad notifyList size")
+ }
+}
+
+//go:linkname sync_nanotime sync.runtime_nanotime
+func sync_nanotime() int64 {
+ return nanotime()
+}
diff --git a/contrib/go/_std_1.20/src/runtime/signal_amd64.go b/contrib/go/_std_1.21/src/runtime/signal_amd64.go
index 8ade208836..8ade208836 100644
--- a/contrib/go/_std_1.20/src/runtime/signal_amd64.go
+++ b/contrib/go/_std_1.21/src/runtime/signal_amd64.go
diff --git a/contrib/go/_std_1.21/src/runtime/signal_arm64.go b/contrib/go/_std_1.21/src/runtime/signal_arm64.go
new file mode 100644
index 0000000000..4a96b3c2e7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/signal_arm64.go
@@ -0,0 +1,107 @@
+// Copyright 2014 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.
+
+//go:build darwin || freebsd || linux || netbsd || openbsd
+
+package runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+func dumpregs(c *sigctxt) {
+ print("r0 ", hex(c.r0()), "\n")
+ print("r1 ", hex(c.r1()), "\n")
+ print("r2 ", hex(c.r2()), "\n")
+ print("r3 ", hex(c.r3()), "\n")
+ print("r4 ", hex(c.r4()), "\n")
+ print("r5 ", hex(c.r5()), "\n")
+ print("r6 ", hex(c.r6()), "\n")
+ print("r7 ", hex(c.r7()), "\n")
+ print("r8 ", hex(c.r8()), "\n")
+ print("r9 ", hex(c.r9()), "\n")
+ print("r10 ", hex(c.r10()), "\n")
+ print("r11 ", hex(c.r11()), "\n")
+ print("r12 ", hex(c.r12()), "\n")
+ print("r13 ", hex(c.r13()), "\n")
+ print("r14 ", hex(c.r14()), "\n")
+ print("r15 ", hex(c.r15()), "\n")
+ print("r16 ", hex(c.r16()), "\n")
+ print("r17 ", hex(c.r17()), "\n")
+ print("r18 ", hex(c.r18()), "\n")
+ print("r19 ", hex(c.r19()), "\n")
+ print("r20 ", hex(c.r20()), "\n")
+ print("r21 ", hex(c.r21()), "\n")
+ print("r22 ", hex(c.r22()), "\n")
+ print("r23 ", hex(c.r23()), "\n")
+ print("r24 ", hex(c.r24()), "\n")
+ print("r25 ", hex(c.r25()), "\n")
+ print("r26 ", hex(c.r26()), "\n")
+ print("r27 ", hex(c.r27()), "\n")
+ print("r28 ", hex(c.r28()), "\n")
+ print("r29 ", hex(c.r29()), "\n")
+ print("lr ", hex(c.lr()), "\n")
+ print("sp ", hex(c.sp()), "\n")
+ print("pc ", hex(c.pc()), "\n")
+ print("fault ", hex(c.fault()), "\n")
+}
+
+//go:nosplit
+//go:nowritebarrierrec
+func (c *sigctxt) sigpc() uintptr { return uintptr(c.pc()) }
+
+func (c *sigctxt) setsigpc(x uint64) { c.set_pc(x) }
+func (c *sigctxt) sigsp() uintptr { return uintptr(c.sp()) }
+func (c *sigctxt) siglr() uintptr { return uintptr(c.lr()) }
+
+// preparePanic sets up the stack to look like a call to sigpanic.
+func (c *sigctxt) preparePanic(sig uint32, gp *g) {
+ // We arrange lr, and pc to pretend the panicking
+ // function calls sigpanic directly.
+ // Always save LR to stack so that panics in leaf
+ // functions are correctly handled. This smashes
+ // the stack frame but we're not going back there
+ // anyway.
+ sp := c.sp() - sys.StackAlign // needs only sizeof uint64, but must align the stack
+ c.set_sp(sp)
+ *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.lr()
+ // Make sure a valid frame pointer is saved on the stack so that the
+ // frame pointer checks in adjustframe are happy, if they're enabled.
+ // Frame pointer unwinding won't visit the sigpanic frame, since
+ // sigpanic will save the same frame pointer before calling into a panic
+ // function.
+ *(*uint64)(unsafe.Pointer(uintptr(sp - goarch.PtrSize))) = c.r29()
+
+ pc := gp.sigpc
+
+ if shouldPushSigpanic(gp, pc, uintptr(c.lr())) {
+ // Make it look the like faulting PC called sigpanic.
+ c.set_lr(uint64(pc))
+ }
+
+ // In case we are panicking from external C code
+ c.set_r28(uint64(uintptr(unsafe.Pointer(gp))))
+ c.set_pc(uint64(abi.FuncPCABIInternal(sigpanic)))
+}
+
+func (c *sigctxt) pushCall(targetPC, resumePC uintptr) {
+ // Push the LR to stack, as we'll clobber it in order to
+ // push the call. The function being pushed is responsible
+ // for restoring the LR and setting the SP back.
+ // This extra space is known to gentraceback.
+ sp := c.sp() - 16 // SP needs 16-byte alignment
+ c.set_sp(sp)
+ *(*uint64)(unsafe.Pointer(uintptr(sp))) = c.lr()
+ // Make sure a valid frame pointer is saved on the stack so that the
+ // frame pointer checks in adjustframe are happy, if they're enabled.
+ // This is not actually used for unwinding.
+ *(*uint64)(unsafe.Pointer(uintptr(sp - goarch.PtrSize))) = c.r29()
+ // Set up PC and LR to pretend the function being signaled
+ // calls targetPC at resumePC.
+ c.set_lr(uint64(resumePC))
+ c.set_pc(uint64(targetPC))
+}
diff --git a/contrib/go/_std_1.20/src/runtime/signal_darwin.go b/contrib/go/_std_1.21/src/runtime/signal_darwin.go
index 8090fb22a5..8090fb22a5 100644
--- a/contrib/go/_std_1.20/src/runtime/signal_darwin.go
+++ b/contrib/go/_std_1.21/src/runtime/signal_darwin.go
diff --git a/contrib/go/_std_1.20/src/runtime/signal_darwin_amd64.go b/contrib/go/_std_1.21/src/runtime/signal_darwin_amd64.go
index 20544d8489..20544d8489 100644
--- a/contrib/go/_std_1.20/src/runtime/signal_darwin_amd64.go
+++ b/contrib/go/_std_1.21/src/runtime/signal_darwin_amd64.go
diff --git a/contrib/go/_std_1.20/src/runtime/signal_linux_amd64.go b/contrib/go/_std_1.21/src/runtime/signal_linux_amd64.go
index 573b118397..573b118397 100644
--- a/contrib/go/_std_1.20/src/runtime/signal_linux_amd64.go
+++ b/contrib/go/_std_1.21/src/runtime/signal_linux_amd64.go
diff --git a/contrib/go/_std_1.20/src/runtime/signal_linux_arm64.go b/contrib/go/_std_1.21/src/runtime/signal_linux_arm64.go
index 4ccc030792..4ccc030792 100644
--- a/contrib/go/_std_1.20/src/runtime/signal_linux_arm64.go
+++ b/contrib/go/_std_1.21/src/runtime/signal_linux_arm64.go
diff --git a/contrib/go/_std_1.21/src/runtime/signal_unix.go b/contrib/go/_std_1.21/src/runtime/signal_unix.go
new file mode 100644
index 0000000000..ae842e9f79
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/signal_unix.go
@@ -0,0 +1,1371 @@
+// Copyright 2012 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.
+
+//go:build unix
+
+package runtime
+
+import (
+ "internal/abi"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// sigTabT is the type of an entry in the global sigtable array.
+// sigtable is inherently system dependent, and appears in OS-specific files,
+// but sigTabT is the same for all Unixy systems.
+// The sigtable array is indexed by a system signal number to get the flags
+// and printable name of each signal.
+type sigTabT struct {
+ flags int32
+ name string
+}
+
+//go:linkname os_sigpipe os.sigpipe
+func os_sigpipe() {
+ systemstack(sigpipe)
+}
+
+func signame(sig uint32) string {
+ if sig >= uint32(len(sigtable)) {
+ return ""
+ }
+ return sigtable[sig].name
+}
+
+const (
+ _SIG_DFL uintptr = 0
+ _SIG_IGN uintptr = 1
+)
+
+// sigPreempt is the signal used for non-cooperative preemption.
+//
+// There's no good way to choose this signal, but there are some
+// heuristics:
+//
+// 1. It should be a signal that's passed-through by debuggers by
+// default. On Linux, this is SIGALRM, SIGURG, SIGCHLD, SIGIO,
+// SIGVTALRM, SIGPROF, and SIGWINCH, plus some glibc-internal signals.
+//
+// 2. It shouldn't be used internally by libc in mixed Go/C binaries
+// because libc may assume it's the only thing that can handle these
+// signals. For example SIGCANCEL or SIGSETXID.
+//
+// 3. It should be a signal that can happen spuriously without
+// consequences. For example, SIGALRM is a bad choice because the
+// signal handler can't tell if it was caused by the real process
+// alarm or not (arguably this means the signal is broken, but I
+// digress). SIGUSR1 and SIGUSR2 are also bad because those are often
+// used in meaningful ways by applications.
+//
+// 4. We need to deal with platforms without real-time signals (like
+// macOS), so those are out.
+//
+// We use SIGURG because it meets all of these criteria, is extremely
+// unlikely to be used by an application for its "real" meaning (both
+// because out-of-band data is basically unused and because SIGURG
+// doesn't report which socket has the condition, making it pretty
+// useless), and even if it is, the application has to be ready for
+// spurious SIGURG. SIGIO wouldn't be a bad choice either, but is more
+// likely to be used for real.
+const sigPreempt = _SIGURG
+
+// Stores the signal handlers registered before Go installed its own.
+// These signal handlers will be invoked in cases where Go doesn't want to
+// handle a particular signal (e.g., signal occurred on a non-Go thread).
+// See sigfwdgo for more information on when the signals are forwarded.
+//
+// This is read by the signal handler; accesses should use
+// atomic.Loaduintptr and atomic.Storeuintptr.
+var fwdSig [_NSIG]uintptr
+
+// handlingSig is indexed by signal number and is non-zero if we are
+// currently handling the signal. Or, to put it another way, whether
+// the signal handler is currently set to the Go signal handler or not.
+// This is uint32 rather than bool so that we can use atomic instructions.
+var handlingSig [_NSIG]uint32
+
+// channels for synchronizing signal mask updates with the signal mask
+// thread
+var (
+ disableSigChan chan uint32
+ enableSigChan chan uint32
+ maskUpdatedChan chan struct{}
+)
+
+func init() {
+ // _NSIG is the number of signals on this operating system.
+ // sigtable should describe what to do for all the possible signals.
+ if len(sigtable) != _NSIG {
+ print("runtime: len(sigtable)=", len(sigtable), " _NSIG=", _NSIG, "\n")
+ throw("bad sigtable len")
+ }
+}
+
+var signalsOK bool
+
+// Initialize signals.
+// Called by libpreinit so runtime may not be initialized.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func initsig(preinit bool) {
+ if !preinit {
+ // It's now OK for signal handlers to run.
+ signalsOK = true
+ }
+
+ // For c-archive/c-shared this is called by libpreinit with
+ // preinit == true.
+ if (isarchive || islibrary) && !preinit {
+ return
+ }
+
+ for i := uint32(0); i < _NSIG; i++ {
+ t := &sigtable[i]
+ if t.flags == 0 || t.flags&_SigDefault != 0 {
+ continue
+ }
+
+ // We don't need to use atomic operations here because
+ // there shouldn't be any other goroutines running yet.
+ fwdSig[i] = getsig(i)
+
+ if !sigInstallGoHandler(i) {
+ // Even if we are not installing a signal handler,
+ // set SA_ONSTACK if necessary.
+ if fwdSig[i] != _SIG_DFL && fwdSig[i] != _SIG_IGN {
+ setsigstack(i)
+ } else if fwdSig[i] == _SIG_IGN {
+ sigInitIgnored(i)
+ }
+ continue
+ }
+
+ handlingSig[i] = 1
+ setsig(i, abi.FuncPCABIInternal(sighandler))
+ }
+}
+
+//go:nosplit
+//go:nowritebarrierrec
+func sigInstallGoHandler(sig uint32) bool {
+ // For some signals, we respect an inherited SIG_IGN handler
+ // rather than insist on installing our own default handler.
+ // Even these signals can be fetched using the os/signal package.
+ switch sig {
+ case _SIGHUP, _SIGINT:
+ if atomic.Loaduintptr(&fwdSig[sig]) == _SIG_IGN {
+ return false
+ }
+ }
+
+ if (GOOS == "linux" || GOOS == "android") && !iscgo && sig == sigPerThreadSyscall {
+ // sigPerThreadSyscall is the same signal used by glibc for
+ // per-thread syscalls on Linux. We use it for the same purpose
+ // in non-cgo binaries.
+ return true
+ }
+
+ t := &sigtable[sig]
+ if t.flags&_SigSetStack != 0 {
+ return false
+ }
+
+ // When built using c-archive or c-shared, only install signal
+ // handlers for synchronous signals and SIGPIPE and sigPreempt.
+ if (isarchive || islibrary) && t.flags&_SigPanic == 0 && sig != _SIGPIPE && sig != sigPreempt {
+ return false
+ }
+
+ return true
+}
+
+// sigenable enables the Go signal handler to catch the signal sig.
+// It is only called while holding the os/signal.handlers lock,
+// via os/signal.enableSignal and signal_enable.
+func sigenable(sig uint32) {
+ if sig >= uint32(len(sigtable)) {
+ return
+ }
+
+ // SIGPROF is handled specially for profiling.
+ if sig == _SIGPROF {
+ return
+ }
+
+ t := &sigtable[sig]
+ if t.flags&_SigNotify != 0 {
+ ensureSigM()
+ enableSigChan <- sig
+ <-maskUpdatedChan
+ if atomic.Cas(&handlingSig[sig], 0, 1) {
+ atomic.Storeuintptr(&fwdSig[sig], getsig(sig))
+ setsig(sig, abi.FuncPCABIInternal(sighandler))
+ }
+ }
+}
+
+// sigdisable disables the Go signal handler for the signal sig.
+// It is only called while holding the os/signal.handlers lock,
+// via os/signal.disableSignal and signal_disable.
+func sigdisable(sig uint32) {
+ if sig >= uint32(len(sigtable)) {
+ return
+ }
+
+ // SIGPROF is handled specially for profiling.
+ if sig == _SIGPROF {
+ return
+ }
+
+ t := &sigtable[sig]
+ if t.flags&_SigNotify != 0 {
+ ensureSigM()
+ disableSigChan <- sig
+ <-maskUpdatedChan
+
+ // If initsig does not install a signal handler for a
+ // signal, then to go back to the state before Notify
+ // we should remove the one we installed.
+ if !sigInstallGoHandler(sig) {
+ atomic.Store(&handlingSig[sig], 0)
+ setsig(sig, atomic.Loaduintptr(&fwdSig[sig]))
+ }
+ }
+}
+
+// sigignore ignores the signal sig.
+// It is only called while holding the os/signal.handlers lock,
+// via os/signal.ignoreSignal and signal_ignore.
+func sigignore(sig uint32) {
+ if sig >= uint32(len(sigtable)) {
+ return
+ }
+
+ // SIGPROF is handled specially for profiling.
+ if sig == _SIGPROF {
+ return
+ }
+
+ t := &sigtable[sig]
+ if t.flags&_SigNotify != 0 {
+ atomic.Store(&handlingSig[sig], 0)
+ setsig(sig, _SIG_IGN)
+ }
+}
+
+// clearSignalHandlers clears all signal handlers that are not ignored
+// back to the default. This is called by the child after a fork, so that
+// we can enable the signal mask for the exec without worrying about
+// running a signal handler in the child.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func clearSignalHandlers() {
+ for i := uint32(0); i < _NSIG; i++ {
+ if atomic.Load(&handlingSig[i]) != 0 {
+ setsig(i, _SIG_DFL)
+ }
+ }
+}
+
+// setProcessCPUProfilerTimer is called when the profiling timer changes.
+// It is called with prof.signalLock held. hz is the new timer, and is 0 if
+// profiling is being disabled. Enable or disable the signal as
+// required for -buildmode=c-archive.
+func setProcessCPUProfilerTimer(hz int32) {
+ if hz != 0 {
+ // Enable the Go signal handler if not enabled.
+ if atomic.Cas(&handlingSig[_SIGPROF], 0, 1) {
+ h := getsig(_SIGPROF)
+ // If no signal handler was installed before, then we record
+ // _SIG_IGN here. When we turn off profiling (below) we'll start
+ // ignoring SIGPROF signals. We do this, rather than change
+ // to SIG_DFL, because there may be a pending SIGPROF
+ // signal that has not yet been delivered to some other thread.
+ // If we change to SIG_DFL when turning off profiling, the
+ // program will crash when that SIGPROF is delivered. We assume
+ // that programs that use profiling don't want to crash on a
+ // stray SIGPROF. See issue 19320.
+ // We do the change here instead of when turning off profiling,
+ // because there we may race with a signal handler running
+ // concurrently, in particular, sigfwdgo may observe _SIG_DFL and
+ // die. See issue 43828.
+ if h == _SIG_DFL {
+ h = _SIG_IGN
+ }
+ atomic.Storeuintptr(&fwdSig[_SIGPROF], h)
+ setsig(_SIGPROF, abi.FuncPCABIInternal(sighandler))
+ }
+
+ var it itimerval
+ it.it_interval.tv_sec = 0
+ it.it_interval.set_usec(1000000 / hz)
+ it.it_value = it.it_interval
+ setitimer(_ITIMER_PROF, &it, nil)
+ } else {
+ setitimer(_ITIMER_PROF, &itimerval{}, nil)
+
+ // If the Go signal handler should be disabled by default,
+ // switch back to the signal handler that was installed
+ // when we enabled profiling. We don't try to handle the case
+ // of a program that changes the SIGPROF handler while Go
+ // profiling is enabled.
+ if !sigInstallGoHandler(_SIGPROF) {
+ if atomic.Cas(&handlingSig[_SIGPROF], 1, 0) {
+ h := atomic.Loaduintptr(&fwdSig[_SIGPROF])
+ setsig(_SIGPROF, h)
+ }
+ }
+ }
+}
+
+// setThreadCPUProfilerHz makes any thread-specific changes required to
+// implement profiling at a rate of hz.
+// No changes required on Unix systems when using setitimer.
+func setThreadCPUProfilerHz(hz int32) {
+ getg().m.profilehz = hz
+}
+
+func sigpipe() {
+ if signal_ignored(_SIGPIPE) || sigsend(_SIGPIPE) {
+ return
+ }
+ dieFromSignal(_SIGPIPE)
+}
+
+// doSigPreempt handles a preemption signal on gp.
+func doSigPreempt(gp *g, ctxt *sigctxt) {
+ // Check if this G wants to be preempted and is safe to
+ // preempt.
+ if wantAsyncPreempt(gp) {
+ if ok, newpc := isAsyncSafePoint(gp, ctxt.sigpc(), ctxt.sigsp(), ctxt.siglr()); ok {
+ // Adjust the PC and inject a call to asyncPreempt.
+ ctxt.pushCall(abi.FuncPCABI0(asyncPreempt), newpc)
+ }
+ }
+
+ // Acknowledge the preemption.
+ gp.m.preemptGen.Add(1)
+ gp.m.signalPending.Store(0)
+
+ if GOOS == "darwin" || GOOS == "ios" {
+ pendingPreemptSignals.Add(-1)
+ }
+}
+
+const preemptMSupported = true
+
+// preemptM sends a preemption request to mp. This request may be
+// handled asynchronously and may be coalesced with other requests to
+// the M. When the request is received, if the running G or P are
+// marked for preemption and the goroutine is at an asynchronous
+// safe-point, it will preempt the goroutine. It always atomically
+// increments mp.preemptGen after handling a preemption request.
+func preemptM(mp *m) {
+ // On Darwin, don't try to preempt threads during exec.
+ // Issue #41702.
+ if GOOS == "darwin" || GOOS == "ios" {
+ execLock.rlock()
+ }
+
+ if mp.signalPending.CompareAndSwap(0, 1) {
+ if GOOS == "darwin" || GOOS == "ios" {
+ pendingPreemptSignals.Add(1)
+ }
+
+ // If multiple threads are preempting the same M, it may send many
+ // signals to the same M such that it hardly make progress, causing
+ // live-lock problem. Apparently this could happen on darwin. See
+ // issue #37741.
+ // Only send a signal if there isn't already one pending.
+ signalM(mp, sigPreempt)
+ }
+
+ if GOOS == "darwin" || GOOS == "ios" {
+ execLock.runlock()
+ }
+}
+
+// sigFetchG fetches the value of G safely when running in a signal handler.
+// On some architectures, the g value may be clobbered when running in a VDSO.
+// See issue #32912.
+//
+//go:nosplit
+func sigFetchG(c *sigctxt) *g {
+ switch GOARCH {
+ case "arm", "arm64", "loong64", "ppc64", "ppc64le", "riscv64", "s390x":
+ if !iscgo && inVDSOPage(c.sigpc()) {
+ // When using cgo, we save the g on TLS and load it from there
+ // in sigtramp. Just use that.
+ // Otherwise, before making a VDSO call we save the g to the
+ // bottom of the signal stack. Fetch from there.
+ // TODO: in efence mode, stack is sysAlloc'd, so this wouldn't
+ // work.
+ sp := getcallersp()
+ s := spanOf(sp)
+ if s != nil && s.state.get() == mSpanManual && s.base() < sp && sp < s.limit {
+ gp := *(**g)(unsafe.Pointer(s.base()))
+ return gp
+ }
+ return nil
+ }
+ }
+ return getg()
+}
+
+// sigtrampgo is called from the signal handler function, sigtramp,
+// written in assembly code.
+// This is called by the signal handler, and the world may be stopped.
+//
+// It must be nosplit because getg() is still the G that was running
+// (if any) when the signal was delivered, but it's (usually) called
+// on the gsignal stack. Until this switches the G to gsignal, the
+// stack bounds check won't work.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
+ if sigfwdgo(sig, info, ctx) {
+ return
+ }
+ c := &sigctxt{info, ctx}
+ gp := sigFetchG(c)
+ setg(gp)
+ if gp == nil || (gp.m != nil && gp.m.isExtraInC) {
+ if sig == _SIGPROF {
+ // Some platforms (Linux) have per-thread timers, which we use in
+ // combination with the process-wide timer. Avoid double-counting.
+ if validSIGPROF(nil, c) {
+ sigprofNonGoPC(c.sigpc())
+ }
+ return
+ }
+ if sig == sigPreempt && preemptMSupported && debug.asyncpreemptoff == 0 {
+ // This is probably a signal from preemptM sent
+ // while executing Go code but received while
+ // executing non-Go code.
+ // We got past sigfwdgo, so we know that there is
+ // no non-Go signal handler for sigPreempt.
+ // The default behavior for sigPreempt is to ignore
+ // the signal, so badsignal will be a no-op anyway.
+ if GOOS == "darwin" || GOOS == "ios" {
+ pendingPreemptSignals.Add(-1)
+ }
+ return
+ }
+ c.fixsigcode(sig)
+ // Set g to nil here and badsignal will use g0 by needm.
+ // TODO: reuse the current m here by using the gsignal and adjustSignalStack,
+ // since the current g maybe a normal goroutine and actually running on the signal stack,
+ // it may hit stack split that is not expected here.
+ if gp != nil {
+ setg(nil)
+ }
+ badsignal(uintptr(sig), c)
+ // Restore g
+ if gp != nil {
+ setg(gp)
+ }
+ return
+ }
+
+ setg(gp.m.gsignal)
+
+ // If some non-Go code called sigaltstack, adjust.
+ var gsignalStack gsignalStack
+ setStack := adjustSignalStack(sig, gp.m, &gsignalStack)
+ if setStack {
+ gp.m.gsignal.stktopsp = getcallersp()
+ }
+
+ if gp.stackguard0 == stackFork {
+ signalDuringFork(sig)
+ }
+
+ c.fixsigcode(sig)
+ sighandler(sig, info, ctx, gp)
+ setg(gp)
+ if setStack {
+ restoreGsignalStack(&gsignalStack)
+ }
+}
+
+// If the signal handler receives a SIGPROF signal on a non-Go thread,
+// it tries to collect a traceback into sigprofCallers.
+// sigprofCallersUse is set to non-zero while sigprofCallers holds a traceback.
+var sigprofCallers cgoCallers
+var sigprofCallersUse uint32
+
+// sigprofNonGo is called if we receive a SIGPROF signal on a non-Go thread,
+// and the signal handler collected a stack trace in sigprofCallers.
+// When this is called, sigprofCallersUse will be non-zero.
+// g is nil, and what we can do is very limited.
+//
+// It is called from the signal handling functions written in assembly code that
+// are active for cgo programs, cgoSigtramp and sigprofNonGoWrapper, which have
+// not verified that the SIGPROF delivery corresponds to the best available
+// profiling source for this thread.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func sigprofNonGo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
+ if prof.hz.Load() != 0 {
+ c := &sigctxt{info, ctx}
+ // Some platforms (Linux) have per-thread timers, which we use in
+ // combination with the process-wide timer. Avoid double-counting.
+ if validSIGPROF(nil, c) {
+ n := 0
+ for n < len(sigprofCallers) && sigprofCallers[n] != 0 {
+ n++
+ }
+ cpuprof.addNonGo(sigprofCallers[:n])
+ }
+ }
+
+ atomic.Store(&sigprofCallersUse, 0)
+}
+
+// sigprofNonGoPC is called when a profiling signal arrived on a
+// non-Go thread and we have a single PC value, not a stack trace.
+// g is nil, and what we can do is very limited.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func sigprofNonGoPC(pc uintptr) {
+ if prof.hz.Load() != 0 {
+ stk := []uintptr{
+ pc,
+ abi.FuncPCABIInternal(_ExternalCode) + sys.PCQuantum,
+ }
+ cpuprof.addNonGo(stk)
+ }
+}
+
+// adjustSignalStack adjusts the current stack guard based on the
+// stack pointer that is actually in use while handling a signal.
+// We do this in case some non-Go code called sigaltstack.
+// This reports whether the stack was adjusted, and if so stores the old
+// signal stack in *gsigstack.
+//
+//go:nosplit
+func adjustSignalStack(sig uint32, mp *m, gsigStack *gsignalStack) bool {
+ sp := uintptr(unsafe.Pointer(&sig))
+ if sp >= mp.gsignal.stack.lo && sp < mp.gsignal.stack.hi {
+ return false
+ }
+
+ var st stackt
+ sigaltstack(nil, &st)
+ stsp := uintptr(unsafe.Pointer(st.ss_sp))
+ if st.ss_flags&_SS_DISABLE == 0 && sp >= stsp && sp < stsp+st.ss_size {
+ setGsignalStack(&st, gsigStack)
+ return true
+ }
+
+ if sp >= mp.g0.stack.lo && sp < mp.g0.stack.hi {
+ // The signal was delivered on the g0 stack.
+ // This can happen when linked with C code
+ // using the thread sanitizer, which collects
+ // signals then delivers them itself by calling
+ // the signal handler directly when C code,
+ // including C code called via cgo, calls a
+ // TSAN-intercepted function such as malloc.
+ //
+ // We check this condition last as g0.stack.lo
+ // may be not very accurate (see mstart).
+ st := stackt{ss_size: mp.g0.stack.hi - mp.g0.stack.lo}
+ setSignalstackSP(&st, mp.g0.stack.lo)
+ setGsignalStack(&st, gsigStack)
+ return true
+ }
+
+ // sp is not within gsignal stack, g0 stack, or sigaltstack. Bad.
+ setg(nil)
+ needm(true)
+ if st.ss_flags&_SS_DISABLE != 0 {
+ noSignalStack(sig)
+ } else {
+ sigNotOnStack(sig, sp, mp)
+ }
+ dropm()
+ return false
+}
+
+// crashing is the number of m's we have waited for when implementing
+// GOTRACEBACK=crash when a signal is received.
+var crashing int32
+
+// testSigtrap and testSigusr1 are used by the runtime tests. If
+// non-nil, it is called on SIGTRAP/SIGUSR1. If it returns true, the
+// normal behavior on this signal is suppressed.
+var testSigtrap func(info *siginfo, ctxt *sigctxt, gp *g) bool
+var testSigusr1 func(gp *g) bool
+
+// sighandler is invoked when a signal occurs. The global g will be
+// set to a gsignal goroutine and we will be running on the alternate
+// signal stack. The parameter gp will be the value of the global g
+// when the signal occurred. The sig, info, and ctxt parameters are
+// from the system signal handler: they are the parameters passed when
+// the SA is passed to the sigaction system call.
+//
+// The garbage collector may have stopped the world, so write barriers
+// are not allowed.
+//
+//go:nowritebarrierrec
+func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) {
+ // The g executing the signal handler. This is almost always
+ // mp.gsignal. See delayedSignal for an exception.
+ gsignal := getg()
+ mp := gsignal.m
+ c := &sigctxt{info, ctxt}
+
+ // Cgo TSAN (not the Go race detector) intercepts signals and calls the
+ // signal handler at a later time. When the signal handler is called, the
+ // memory may have changed, but the signal context remains old. The
+ // unmatched signal context and memory makes it unsafe to unwind or inspect
+ // the stack. So we ignore delayed non-fatal signals that will cause a stack
+ // inspection (profiling signal and preemption signal).
+ // cgo_yield is only non-nil for TSAN, and is specifically used to trigger
+ // signal delivery. We use that as an indicator of delayed signals.
+ // For delayed signals, the handler is called on the g0 stack (see
+ // adjustSignalStack).
+ delayedSignal := *cgo_yield != nil && mp != nil && gsignal.stack == mp.g0.stack
+
+ if sig == _SIGPROF {
+ // Some platforms (Linux) have per-thread timers, which we use in
+ // combination with the process-wide timer. Avoid double-counting.
+ if !delayedSignal && validSIGPROF(mp, c) {
+ sigprof(c.sigpc(), c.sigsp(), c.siglr(), gp, mp)
+ }
+ return
+ }
+
+ if sig == _SIGTRAP && testSigtrap != nil && testSigtrap(info, (*sigctxt)(noescape(unsafe.Pointer(c))), gp) {
+ return
+ }
+
+ if sig == _SIGUSR1 && testSigusr1 != nil && testSigusr1(gp) {
+ return
+ }
+
+ if (GOOS == "linux" || GOOS == "android") && sig == sigPerThreadSyscall {
+ // sigPerThreadSyscall is the same signal used by glibc for
+ // per-thread syscalls on Linux. We use it for the same purpose
+ // in non-cgo binaries. Since this signal is not _SigNotify,
+ // there is nothing more to do once we run the syscall.
+ runPerThreadSyscall()
+ return
+ }
+
+ if sig == sigPreempt && debug.asyncpreemptoff == 0 && !delayedSignal {
+ // Might be a preemption signal.
+ doSigPreempt(gp, c)
+ // Even if this was definitely a preemption signal, it
+ // may have been coalesced with another signal, so we
+ // still let it through to the application.
+ }
+
+ flags := int32(_SigThrow)
+ if sig < uint32(len(sigtable)) {
+ flags = sigtable[sig].flags
+ }
+ if !c.sigFromUser() && flags&_SigPanic != 0 && (gp.throwsplit || gp != mp.curg) {
+ // We can't safely sigpanic because it may grow the
+ // stack. Abort in the signal handler instead.
+ //
+ // Also don't inject a sigpanic if we are not on a
+ // user G stack. Either we're in the runtime, or we're
+ // running C code. Either way we cannot recover.
+ flags = _SigThrow
+ }
+ if isAbortPC(c.sigpc()) {
+ // On many architectures, the abort function just
+ // causes a memory fault. Don't turn that into a panic.
+ flags = _SigThrow
+ }
+ if !c.sigFromUser() && flags&_SigPanic != 0 {
+ // The signal is going to cause a panic.
+ // Arrange the stack so that it looks like the point
+ // where the signal occurred made a call to the
+ // function sigpanic. Then set the PC to sigpanic.
+
+ // Have to pass arguments out of band since
+ // augmenting the stack frame would break
+ // the unwinding code.
+ gp.sig = sig
+ gp.sigcode0 = uintptr(c.sigcode())
+ gp.sigcode1 = uintptr(c.fault())
+ gp.sigpc = c.sigpc()
+
+ c.preparePanic(sig, gp)
+ return
+ }
+
+ if c.sigFromUser() || flags&_SigNotify != 0 {
+ if sigsend(sig) {
+ return
+ }
+ }
+
+ if c.sigFromUser() && signal_ignored(sig) {
+ return
+ }
+
+ if flags&_SigKill != 0 {
+ dieFromSignal(sig)
+ }
+
+ // _SigThrow means that we should exit now.
+ // If we get here with _SigPanic, it means that the signal
+ // was sent to us by a program (c.sigFromUser() is true);
+ // in that case, if we didn't handle it in sigsend, we exit now.
+ if flags&(_SigThrow|_SigPanic) == 0 {
+ return
+ }
+
+ mp.throwing = throwTypeRuntime
+ mp.caughtsig.set(gp)
+
+ if crashing == 0 {
+ startpanic_m()
+ }
+
+ gp = fatalsignal(sig, c, gp, mp)
+
+ level, _, docrash := gotraceback()
+ if level > 0 {
+ goroutineheader(gp)
+ tracebacktrap(c.sigpc(), c.sigsp(), c.siglr(), gp)
+ if crashing > 0 && gp != mp.curg && mp.curg != nil && readgstatus(mp.curg)&^_Gscan == _Grunning {
+ // tracebackothers on original m skipped this one; trace it now.
+ goroutineheader(mp.curg)
+ traceback(^uintptr(0), ^uintptr(0), 0, mp.curg)
+ } else if crashing == 0 {
+ tracebackothers(gp)
+ print("\n")
+ }
+ dumpregs(c)
+ }
+
+ if docrash {
+ crashing++
+ if crashing < mcount()-int32(extraMLength.Load()) {
+ // There are other m's that need to dump their stacks.
+ // Relay SIGQUIT to the next m by sending it to the current process.
+ // All m's that have already received SIGQUIT have signal masks blocking
+ // receipt of any signals, so the SIGQUIT will go to an m that hasn't seen it yet.
+ // When the last m receives the SIGQUIT, it will fall through to the call to
+ // crash below. Just in case the relaying gets botched, each m involved in
+ // the relay sleeps for 5 seconds and then does the crash/exit itself.
+ // In expected operation, the last m has received the SIGQUIT and run
+ // crash/exit and the process is gone, all long before any of the
+ // 5-second sleeps have finished.
+ print("\n-----\n\n")
+ raiseproc(_SIGQUIT)
+ usleep(5 * 1000 * 1000)
+ }
+ crash()
+ }
+
+ printDebugLog()
+
+ exit(2)
+}
+
+func fatalsignal(sig uint32, c *sigctxt, gp *g, mp *m) *g {
+ if sig < uint32(len(sigtable)) {
+ print(sigtable[sig].name, "\n")
+ } else {
+ print("Signal ", sig, "\n")
+ }
+
+ if isSecureMode() {
+ exit(2)
+ }
+
+ print("PC=", hex(c.sigpc()), " m=", mp.id, " sigcode=", c.sigcode(), "\n")
+ if mp.incgo && gp == mp.g0 && mp.curg != nil {
+ print("signal arrived during cgo execution\n")
+ // Switch to curg so that we get a traceback of the Go code
+ // leading up to the cgocall, which switched from curg to g0.
+ gp = mp.curg
+ }
+ if sig == _SIGILL || sig == _SIGFPE {
+ // It would be nice to know how long the instruction is.
+ // Unfortunately, that's complicated to do in general (mostly for x86
+ // and s930x, but other archs have non-standard instruction lengths also).
+ // Opt to print 16 bytes, which covers most instructions.
+ const maxN = 16
+ n := uintptr(maxN)
+ // We have to be careful, though. If we're near the end of
+ // a page and the following page isn't mapped, we could
+ // segfault. So make sure we don't straddle a page (even though
+ // that could lead to printing an incomplete instruction).
+ // We're assuming here we can read at least the page containing the PC.
+ // I suppose it is possible that the page is mapped executable but not readable?
+ pc := c.sigpc()
+ if n > physPageSize-pc%physPageSize {
+ n = physPageSize - pc%physPageSize
+ }
+ print("instruction bytes:")
+ b := (*[maxN]byte)(unsafe.Pointer(pc))
+ for i := uintptr(0); i < n; i++ {
+ print(" ", hex(b[i]))
+ }
+ println()
+ }
+ print("\n")
+ return gp
+}
+
+// sigpanic turns a synchronous signal into a run-time panic.
+// If the signal handler sees a synchronous panic, it arranges the
+// stack to look like the function where the signal occurred called
+// sigpanic, sets the signal's PC value to sigpanic, and returns from
+// the signal handler. The effect is that the program will act as
+// though the function that got the signal simply called sigpanic
+// instead.
+//
+// This must NOT be nosplit because the linker doesn't know where
+// sigpanic calls can be injected.
+//
+// The signal handler must not inject a call to sigpanic if
+// getg().throwsplit, since sigpanic may need to grow the stack.
+//
+// This is exported via linkname to assembly in runtime/cgo.
+//
+//go:linkname sigpanic
+func sigpanic() {
+ gp := getg()
+ if !canpanic() {
+ throw("unexpected signal during runtime execution")
+ }
+
+ switch gp.sig {
+ case _SIGBUS:
+ if gp.sigcode0 == _BUS_ADRERR && gp.sigcode1 < 0x1000 {
+ panicmem()
+ }
+ // Support runtime/debug.SetPanicOnFault.
+ if gp.paniconfault {
+ panicmemAddr(gp.sigcode1)
+ }
+ print("unexpected fault address ", hex(gp.sigcode1), "\n")
+ throw("fault")
+ case _SIGSEGV:
+ if (gp.sigcode0 == 0 || gp.sigcode0 == _SEGV_MAPERR || gp.sigcode0 == _SEGV_ACCERR) && gp.sigcode1 < 0x1000 {
+ panicmem()
+ }
+ // Support runtime/debug.SetPanicOnFault.
+ if gp.paniconfault {
+ panicmemAddr(gp.sigcode1)
+ }
+ if inUserArenaChunk(gp.sigcode1) {
+ // We could check that the arena chunk is explicitly set to fault,
+ // but the fact that we faulted on accessing it is enough to prove
+ // that it is.
+ print("accessed data from freed user arena ", hex(gp.sigcode1), "\n")
+ } else {
+ print("unexpected fault address ", hex(gp.sigcode1), "\n")
+ }
+ throw("fault")
+ case _SIGFPE:
+ switch gp.sigcode0 {
+ case _FPE_INTDIV:
+ panicdivide()
+ case _FPE_INTOVF:
+ panicoverflow()
+ }
+ panicfloat()
+ }
+
+ if gp.sig >= uint32(len(sigtable)) {
+ // can't happen: we looked up gp.sig in sigtable to decide to call sigpanic
+ throw("unexpected signal value")
+ }
+ panic(errorString(sigtable[gp.sig].name))
+}
+
+// dieFromSignal kills the program with a signal.
+// This provides the expected exit status for the shell.
+// This is only called with fatal signals expected to kill the process.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func dieFromSignal(sig uint32) {
+ unblocksig(sig)
+ // Mark the signal as unhandled to ensure it is forwarded.
+ atomic.Store(&handlingSig[sig], 0)
+ raise(sig)
+
+ // That should have killed us. On some systems, though, raise
+ // sends the signal to the whole process rather than to just
+ // the current thread, which means that the signal may not yet
+ // have been delivered. Give other threads a chance to run and
+ // pick up the signal.
+ osyield()
+ osyield()
+ osyield()
+
+ // If that didn't work, try _SIG_DFL.
+ setsig(sig, _SIG_DFL)
+ raise(sig)
+
+ osyield()
+ osyield()
+ osyield()
+
+ // If we are still somehow running, just exit with the wrong status.
+ exit(2)
+}
+
+// raisebadsignal is called when a signal is received on a non-Go
+// thread, and the Go program does not want to handle it (that is, the
+// program has not called os/signal.Notify for the signal).
+func raisebadsignal(sig uint32, c *sigctxt) {
+ if sig == _SIGPROF {
+ // Ignore profiling signals that arrive on non-Go threads.
+ return
+ }
+
+ var handler uintptr
+ if sig >= _NSIG {
+ handler = _SIG_DFL
+ } else {
+ handler = atomic.Loaduintptr(&fwdSig[sig])
+ }
+
+ // Reset the signal handler and raise the signal.
+ // We are currently running inside a signal handler, so the
+ // signal is blocked. We need to unblock it before raising the
+ // signal, or the signal we raise will be ignored until we return
+ // from the signal handler. We know that the signal was unblocked
+ // before entering the handler, or else we would not have received
+ // it. That means that we don't have to worry about blocking it
+ // again.
+ unblocksig(sig)
+ setsig(sig, handler)
+
+ // If we're linked into a non-Go program we want to try to
+ // avoid modifying the original context in which the signal
+ // was raised. If the handler is the default, we know it
+ // is non-recoverable, so we don't have to worry about
+ // re-installing sighandler. At this point we can just
+ // return and the signal will be re-raised and caught by
+ // the default handler with the correct context.
+ //
+ // On FreeBSD, the libthr sigaction code prevents
+ // this from working so we fall through to raise.
+ if GOOS != "freebsd" && (isarchive || islibrary) && handler == _SIG_DFL && !c.sigFromUser() {
+ return
+ }
+
+ raise(sig)
+
+ // Give the signal a chance to be delivered.
+ // In almost all real cases the program is about to crash,
+ // so sleeping here is not a waste of time.
+ usleep(1000)
+
+ // If the signal didn't cause the program to exit, restore the
+ // Go signal handler and carry on.
+ //
+ // We may receive another instance of the signal before we
+ // restore the Go handler, but that is not so bad: we know
+ // that the Go program has been ignoring the signal.
+ setsig(sig, abi.FuncPCABIInternal(sighandler))
+}
+
+//go:nosplit
+func crash() {
+ dieFromSignal(_SIGABRT)
+}
+
+// ensureSigM starts one global, sleeping thread to make sure at least one thread
+// is available to catch signals enabled for os/signal.
+func ensureSigM() {
+ if maskUpdatedChan != nil {
+ return
+ }
+ maskUpdatedChan = make(chan struct{})
+ disableSigChan = make(chan uint32)
+ enableSigChan = make(chan uint32)
+ go func() {
+ // Signal masks are per-thread, so make sure this goroutine stays on one
+ // thread.
+ LockOSThread()
+ defer UnlockOSThread()
+ // The sigBlocked mask contains the signals not active for os/signal,
+ // initially all signals except the essential. When signal.Notify()/Stop is called,
+ // sigenable/sigdisable in turn notify this thread to update its signal
+ // mask accordingly.
+ sigBlocked := sigset_all
+ for i := range sigtable {
+ if !blockableSig(uint32(i)) {
+ sigdelset(&sigBlocked, i)
+ }
+ }
+ sigprocmask(_SIG_SETMASK, &sigBlocked, nil)
+ for {
+ select {
+ case sig := <-enableSigChan:
+ if sig > 0 {
+ sigdelset(&sigBlocked, int(sig))
+ }
+ case sig := <-disableSigChan:
+ if sig > 0 && blockableSig(sig) {
+ sigaddset(&sigBlocked, int(sig))
+ }
+ }
+ sigprocmask(_SIG_SETMASK, &sigBlocked, nil)
+ maskUpdatedChan <- struct{}{}
+ }
+ }()
+}
+
+// This is called when we receive a signal when there is no signal stack.
+// This can only happen if non-Go code calls sigaltstack to disable the
+// signal stack.
+func noSignalStack(sig uint32) {
+ println("signal", sig, "received on thread with no signal stack")
+ throw("non-Go code disabled sigaltstack")
+}
+
+// This is called if we receive a signal when there is a signal stack
+// but we are not on it. This can only happen if non-Go code called
+// sigaction without setting the SS_ONSTACK flag.
+func sigNotOnStack(sig uint32, sp uintptr, mp *m) {
+ println("signal", sig, "received but handler not on signal stack")
+ print("mp.gsignal stack [", hex(mp.gsignal.stack.lo), " ", hex(mp.gsignal.stack.hi), "], ")
+ print("mp.g0 stack [", hex(mp.g0.stack.lo), " ", hex(mp.g0.stack.hi), "], sp=", hex(sp), "\n")
+ throw("non-Go code set up signal handler without SA_ONSTACK flag")
+}
+
+// signalDuringFork is called if we receive a signal while doing a fork.
+// We do not want signals at that time, as a signal sent to the process
+// group may be delivered to the child process, causing confusion.
+// This should never be called, because we block signals across the fork;
+// this function is just a safety check. See issue 18600 for background.
+func signalDuringFork(sig uint32) {
+ println("signal", sig, "received during fork")
+ throw("signal received during fork")
+}
+
+// This runs on a foreign stack, without an m or a g. No stack split.
+//
+//go:nosplit
+//go:norace
+//go:nowritebarrierrec
+func badsignal(sig uintptr, c *sigctxt) {
+ if !iscgo && !cgoHasExtraM {
+ // There is no extra M. needm will not be able to grab
+ // an M. Instead of hanging, just crash.
+ // Cannot call split-stack function as there is no G.
+ writeErrStr("fatal: bad g in signal handler\n")
+ exit(2)
+ *(*uintptr)(unsafe.Pointer(uintptr(123))) = 2
+ }
+ needm(true)
+ if !sigsend(uint32(sig)) {
+ // A foreign thread received the signal sig, and the
+ // Go code does not want to handle it.
+ raisebadsignal(uint32(sig), c)
+ }
+ dropm()
+}
+
+//go:noescape
+func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
+
+// Determines if the signal should be handled by Go and if not, forwards the
+// signal to the handler that was installed before Go's. Returns whether the
+// signal was forwarded.
+// This is called by the signal handler, and the world may be stopped.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool {
+ if sig >= uint32(len(sigtable)) {
+ return false
+ }
+ fwdFn := atomic.Loaduintptr(&fwdSig[sig])
+ flags := sigtable[sig].flags
+
+ // If we aren't handling the signal, forward it.
+ if atomic.Load(&handlingSig[sig]) == 0 || !signalsOK {
+ // If the signal is ignored, doing nothing is the same as forwarding.
+ if fwdFn == _SIG_IGN || (fwdFn == _SIG_DFL && flags&_SigIgn != 0) {
+ return true
+ }
+ // We are not handling the signal and there is no other handler to forward to.
+ // Crash with the default behavior.
+ if fwdFn == _SIG_DFL {
+ setsig(sig, _SIG_DFL)
+ dieFromSignal(sig)
+ return false
+ }
+
+ sigfwd(fwdFn, sig, info, ctx)
+ return true
+ }
+
+ // This function and its caller sigtrampgo assumes SIGPIPE is delivered on the
+ // originating thread. This property does not hold on macOS (golang.org/issue/33384),
+ // so we have no choice but to ignore SIGPIPE.
+ if (GOOS == "darwin" || GOOS == "ios") && sig == _SIGPIPE {
+ return true
+ }
+
+ // If there is no handler to forward to, no need to forward.
+ if fwdFn == _SIG_DFL {
+ return false
+ }
+
+ c := &sigctxt{info, ctx}
+ // Only forward synchronous signals and SIGPIPE.
+ // Unfortunately, user generated SIGPIPEs will also be forwarded, because si_code
+ // is set to _SI_USER even for a SIGPIPE raised from a write to a closed socket
+ // or pipe.
+ if (c.sigFromUser() || flags&_SigPanic == 0) && sig != _SIGPIPE {
+ return false
+ }
+ // Determine if the signal occurred inside Go code. We test that:
+ // (1) we weren't in VDSO page,
+ // (2) we were in a goroutine (i.e., m.curg != nil), and
+ // (3) we weren't in CGO.
+ // (4) we weren't in dropped extra m.
+ gp := sigFetchG(c)
+ if gp != nil && gp.m != nil && gp.m.curg != nil && !gp.m.isExtraInC && !gp.m.incgo {
+ return false
+ }
+
+ // Signal not handled by Go, forward it.
+ if fwdFn != _SIG_IGN {
+ sigfwd(fwdFn, sig, info, ctx)
+ }
+
+ return true
+}
+
+// sigsave saves the current thread's signal mask into *p.
+// This is used to preserve the non-Go signal mask when a non-Go
+// thread calls a Go function.
+// This is nosplit and nowritebarrierrec because it is called by needm
+// which may be called on a non-Go thread with no g available.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func sigsave(p *sigset) {
+ sigprocmask(_SIG_SETMASK, nil, p)
+}
+
+// msigrestore sets the current thread's signal mask to sigmask.
+// This is used to restore the non-Go signal mask when a non-Go thread
+// calls a Go function.
+// This is nosplit and nowritebarrierrec because it is called by dropm
+// after g has been cleared.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func msigrestore(sigmask sigset) {
+ sigprocmask(_SIG_SETMASK, &sigmask, nil)
+}
+
+// sigsetAllExiting is used by sigblock(true) when a thread is
+// exiting. sigset_all is defined in OS specific code, and per GOOS
+// behavior may override this default for sigsetAllExiting: see
+// osinit().
+var sigsetAllExiting = sigset_all
+
+// sigblock blocks signals in the current thread's signal mask.
+// This is used to block signals while setting up and tearing down g
+// when a non-Go thread calls a Go function. When a thread is exiting
+// we use the sigsetAllExiting value, otherwise the OS specific
+// definition of sigset_all is used.
+// This is nosplit and nowritebarrierrec because it is called by needm
+// which may be called on a non-Go thread with no g available.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func sigblock(exiting bool) {
+ if exiting {
+ sigprocmask(_SIG_SETMASK, &sigsetAllExiting, nil)
+ return
+ }
+ sigprocmask(_SIG_SETMASK, &sigset_all, nil)
+}
+
+// unblocksig removes sig from the current thread's signal mask.
+// This is nosplit and nowritebarrierrec because it is called from
+// dieFromSignal, which can be called by sigfwdgo while running in the
+// signal handler, on the signal stack, with no g available.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func unblocksig(sig uint32) {
+ var set sigset
+ sigaddset(&set, int(sig))
+ sigprocmask(_SIG_UNBLOCK, &set, nil)
+}
+
+// minitSignals is called when initializing a new m to set the
+// thread's alternate signal stack and signal mask.
+func minitSignals() {
+ minitSignalStack()
+ minitSignalMask()
+}
+
+// minitSignalStack is called when initializing a new m to set the
+// alternate signal stack. If the alternate signal stack is not set
+// for the thread (the normal case) then set the alternate signal
+// stack to the gsignal stack. If the alternate signal stack is set
+// for the thread (the case when a non-Go thread sets the alternate
+// signal stack and then calls a Go function) then set the gsignal
+// stack to the alternate signal stack. We also set the alternate
+// signal stack to the gsignal stack if cgo is not used (regardless
+// of whether it is already set). Record which choice was made in
+// newSigstack, so that it can be undone in unminit.
+func minitSignalStack() {
+ mp := getg().m
+ var st stackt
+ sigaltstack(nil, &st)
+ if st.ss_flags&_SS_DISABLE != 0 || !iscgo {
+ signalstack(&mp.gsignal.stack)
+ mp.newSigstack = true
+ } else {
+ setGsignalStack(&st, &mp.goSigStack)
+ mp.newSigstack = false
+ }
+}
+
+// minitSignalMask is called when initializing a new m to set the
+// thread's signal mask. When this is called all signals have been
+// blocked for the thread. This starts with m.sigmask, which was set
+// either from initSigmask for a newly created thread or by calling
+// sigsave if this is a non-Go thread calling a Go function. It
+// removes all essential signals from the mask, thus causing those
+// signals to not be blocked. Then it sets the thread's signal mask.
+// After this is called the thread can receive signals.
+func minitSignalMask() {
+ nmask := getg().m.sigmask
+ for i := range sigtable {
+ if !blockableSig(uint32(i)) {
+ sigdelset(&nmask, i)
+ }
+ }
+ sigprocmask(_SIG_SETMASK, &nmask, nil)
+}
+
+// unminitSignals is called from dropm, via unminit, to undo the
+// effect of calling minit on a non-Go thread.
+//
+//go:nosplit
+func unminitSignals() {
+ if getg().m.newSigstack {
+ st := stackt{ss_flags: _SS_DISABLE}
+ sigaltstack(&st, nil)
+ } else {
+ // We got the signal stack from someone else. Restore
+ // the Go-allocated stack in case this M gets reused
+ // for another thread (e.g., it's an extram). Also, on
+ // Android, libc allocates a signal stack for all
+ // threads, so it's important to restore the Go stack
+ // even on Go-created threads so we can free it.
+ restoreGsignalStack(&getg().m.goSigStack)
+ }
+}
+
+// blockableSig reports whether sig may be blocked by the signal mask.
+// We never want to block the signals marked _SigUnblock;
+// these are the synchronous signals that turn into a Go panic.
+// We never want to block the preemption signal if it is being used.
+// In a Go program--not a c-archive/c-shared--we never want to block
+// the signals marked _SigKill or _SigThrow, as otherwise it's possible
+// for all running threads to block them and delay their delivery until
+// we start a new thread. When linked into a C program we let the C code
+// decide on the disposition of those signals.
+func blockableSig(sig uint32) bool {
+ flags := sigtable[sig].flags
+ if flags&_SigUnblock != 0 {
+ return false
+ }
+ if sig == sigPreempt && preemptMSupported && debug.asyncpreemptoff == 0 {
+ return false
+ }
+ if isarchive || islibrary {
+ return true
+ }
+ return flags&(_SigKill|_SigThrow) == 0
+}
+
+// gsignalStack saves the fields of the gsignal stack changed by
+// setGsignalStack.
+type gsignalStack struct {
+ stack stack
+ stackguard0 uintptr
+ stackguard1 uintptr
+ stktopsp uintptr
+}
+
+// setGsignalStack sets the gsignal stack of the current m to an
+// alternate signal stack returned from the sigaltstack system call.
+// It saves the old values in *old for use by restoreGsignalStack.
+// This is used when handling a signal if non-Go code has set the
+// alternate signal stack.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func setGsignalStack(st *stackt, old *gsignalStack) {
+ gp := getg()
+ if old != nil {
+ old.stack = gp.m.gsignal.stack
+ old.stackguard0 = gp.m.gsignal.stackguard0
+ old.stackguard1 = gp.m.gsignal.stackguard1
+ old.stktopsp = gp.m.gsignal.stktopsp
+ }
+ stsp := uintptr(unsafe.Pointer(st.ss_sp))
+ gp.m.gsignal.stack.lo = stsp
+ gp.m.gsignal.stack.hi = stsp + st.ss_size
+ gp.m.gsignal.stackguard0 = stsp + stackGuard
+ gp.m.gsignal.stackguard1 = stsp + stackGuard
+}
+
+// restoreGsignalStack restores the gsignal stack to the value it had
+// before entering the signal handler.
+//
+//go:nosplit
+//go:nowritebarrierrec
+func restoreGsignalStack(st *gsignalStack) {
+ gp := getg().m.gsignal
+ gp.stack = st.stack
+ gp.stackguard0 = st.stackguard0
+ gp.stackguard1 = st.stackguard1
+ gp.stktopsp = st.stktopsp
+}
+
+// signalstack sets the current thread's alternate signal stack to s.
+//
+//go:nosplit
+func signalstack(s *stack) {
+ st := stackt{ss_size: s.hi - s.lo}
+ setSignalstackSP(&st, s.lo)
+ sigaltstack(&st, nil)
+}
+
+// setsigsegv is used on darwin/arm64 to fake a segmentation fault.
+//
+// This is exported via linkname to assembly in runtime/cgo.
+//
+//go:nosplit
+//go:linkname setsigsegv
+func setsigsegv(pc uintptr) {
+ gp := getg()
+ gp.sig = _SIGSEGV
+ gp.sigpc = pc
+ gp.sigcode0 = _SEGV_MAPERR
+ gp.sigcode1 = 0 // TODO: emulate si_addr
+}
diff --git a/contrib/go/_std_1.21/src/runtime/signal_windows.go b/contrib/go/_std_1.21/src/runtime/signal_windows.go
new file mode 100644
index 0000000000..8e0e39cb26
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/signal_windows.go
@@ -0,0 +1,445 @@
+// Copyright 2011 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 runtime
+
+import (
+ "internal/abi"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+const (
+ _SEM_FAILCRITICALERRORS = 0x0001
+ _SEM_NOGPFAULTERRORBOX = 0x0002
+ _SEM_NOOPENFILEERRORBOX = 0x8000
+
+ _WER_FAULT_REPORTING_NO_UI = 0x0020
+)
+
+func preventErrorDialogs() {
+ errormode := stdcall0(_GetErrorMode)
+ stdcall1(_SetErrorMode, errormode|_SEM_FAILCRITICALERRORS|_SEM_NOGPFAULTERRORBOX|_SEM_NOOPENFILEERRORBOX)
+
+ // Disable WER fault reporting UI.
+ // Do this even if WER is disabled as a whole,
+ // as WER might be enabled later with setTraceback("wer")
+ // and we still want the fault reporting UI to be disabled if this happens.
+ var werflags uintptr
+ stdcall2(_WerGetFlags, currentProcess, uintptr(unsafe.Pointer(&werflags)))
+ stdcall1(_WerSetFlags, werflags|_WER_FAULT_REPORTING_NO_UI)
+}
+
+// enableWER re-enables Windows error reporting without fault reporting UI.
+func enableWER() {
+ // re-enable Windows Error Reporting
+ errormode := stdcall0(_GetErrorMode)
+ if errormode&_SEM_NOGPFAULTERRORBOX != 0 {
+ stdcall1(_SetErrorMode, errormode^_SEM_NOGPFAULTERRORBOX)
+ }
+}
+
+// in sys_windows_386.s, sys_windows_amd64.s, sys_windows_arm.s, and sys_windows_arm64.s
+func exceptiontramp()
+func firstcontinuetramp()
+func lastcontinuetramp()
+func sigresume()
+
+func initExceptionHandler() {
+ stdcall2(_AddVectoredExceptionHandler, 1, abi.FuncPCABI0(exceptiontramp))
+ if _AddVectoredContinueHandler == nil || GOARCH == "386" {
+ // use SetUnhandledExceptionFilter for windows-386 or
+ // if VectoredContinueHandler is unavailable.
+ // note: SetUnhandledExceptionFilter handler won't be called, if debugging.
+ stdcall1(_SetUnhandledExceptionFilter, abi.FuncPCABI0(lastcontinuetramp))
+ } else {
+ stdcall2(_AddVectoredContinueHandler, 1, abi.FuncPCABI0(firstcontinuetramp))
+ stdcall2(_AddVectoredContinueHandler, 0, abi.FuncPCABI0(lastcontinuetramp))
+ }
+}
+
+// isAbort returns true, if context r describes exception raised
+// by calling runtime.abort function.
+//
+//go:nosplit
+func isAbort(r *context) bool {
+ pc := r.ip()
+ if GOARCH == "386" || GOARCH == "amd64" || GOARCH == "arm" {
+ // In the case of an abort, the exception IP is one byte after
+ // the INT3 (this differs from UNIX OSes). Note that on ARM,
+ // this means that the exception IP is no longer aligned.
+ pc--
+ }
+ return isAbortPC(pc)
+}
+
+// isgoexception reports whether this exception should be translated
+// into a Go panic or throw.
+//
+// It is nosplit to avoid growing the stack in case we're aborting
+// because of a stack overflow.
+//
+//go:nosplit
+func isgoexception(info *exceptionrecord, r *context) bool {
+ // Only handle exception if executing instructions in Go binary
+ // (not Windows library code).
+ // TODO(mwhudson): needs to loop to support shared libs
+ if r.ip() < firstmoduledata.text || firstmoduledata.etext < r.ip() {
+ return false
+ }
+
+ // Go will only handle some exceptions.
+ switch info.exceptioncode {
+ default:
+ return false
+ case _EXCEPTION_ACCESS_VIOLATION:
+ case _EXCEPTION_IN_PAGE_ERROR:
+ case _EXCEPTION_INT_DIVIDE_BY_ZERO:
+ case _EXCEPTION_INT_OVERFLOW:
+ case _EXCEPTION_FLT_DENORMAL_OPERAND:
+ case _EXCEPTION_FLT_DIVIDE_BY_ZERO:
+ case _EXCEPTION_FLT_INEXACT_RESULT:
+ case _EXCEPTION_FLT_OVERFLOW:
+ case _EXCEPTION_FLT_UNDERFLOW:
+ case _EXCEPTION_BREAKPOINT:
+ case _EXCEPTION_ILLEGAL_INSTRUCTION: // breakpoint arrives this way on arm64
+ }
+ return true
+}
+
+const (
+ callbackVEH = iota
+ callbackFirstVCH
+ callbackLastVCH
+)
+
+// sigFetchGSafe is like getg() but without panicking
+// when TLS is not set.
+// Only implemented on windows/386, which is the only
+// arch that loads TLS when calling getg(). Others
+// use a dedicated register.
+func sigFetchGSafe() *g
+
+func sigFetchG() *g {
+ if GOARCH == "386" {
+ return sigFetchGSafe()
+ }
+ return getg()
+}
+
+// sigtrampgo is called from the exception handler function, sigtramp,
+// written in assembly code.
+// Return EXCEPTION_CONTINUE_EXECUTION if the exception is handled,
+// else return EXCEPTION_CONTINUE_SEARCH.
+//
+// It is nosplit for the same reason as exceptionhandler.
+//
+//go:nosplit
+func sigtrampgo(ep *exceptionpointers, kind int) int32 {
+ gp := sigFetchG()
+ if gp == nil {
+ return _EXCEPTION_CONTINUE_SEARCH
+ }
+
+ var fn func(info *exceptionrecord, r *context, gp *g) int32
+ switch kind {
+ case callbackVEH:
+ fn = exceptionhandler
+ case callbackFirstVCH:
+ fn = firstcontinuehandler
+ case callbackLastVCH:
+ fn = lastcontinuehandler
+ default:
+ throw("unknown sigtramp callback")
+ }
+
+ // Check if we are running on g0 stack, and if we are,
+ // call fn directly instead of creating the closure.
+ // for the systemstack argument.
+ //
+ // A closure can't be marked as nosplit, so it might
+ // call morestack if we are at the g0 stack limit.
+ // If that happens, the runtime will call abort
+ // and end up in sigtrampgo again.
+ // TODO: revisit this workaround if/when closures
+ // can be compiled as nosplit.
+ //
+ // Note that this scenario should only occur on
+ // TestG0StackOverflow. Any other occurrence should
+ // be treated as a bug.
+ var ret int32
+ if gp != gp.m.g0 {
+ systemstack(func() {
+ ret = fn(ep.record, ep.context, gp)
+ })
+ } else {
+ ret = fn(ep.record, ep.context, gp)
+ }
+ if ret == _EXCEPTION_CONTINUE_SEARCH {
+ return ret
+ }
+
+ // Check if we need to set up the control flow guard workaround.
+ // On Windows, the stack pointer in the context must lie within
+ // system stack limits when we resume from exception.
+ // Store the resume SP and PC in alternate registers
+ // and return to sigresume on the g0 stack.
+ // sigresume makes no use of the stack at all,
+ // loading SP from RX and jumping to RY, being RX and RY two scratch registers.
+ // Note that blindly smashing RX and RY is only safe because we know sigpanic
+ // will not actually return to the original frame, so the registers
+ // are effectively dead. But this does mean we can't use the
+ // same mechanism for async preemption.
+ if ep.context.ip() == abi.FuncPCABI0(sigresume) {
+ // sigresume has already been set up by a previous exception.
+ return ret
+ }
+ prepareContextForSigResume(ep.context)
+ ep.context.set_sp(gp.m.g0.sched.sp)
+ ep.context.set_ip(abi.FuncPCABI0(sigresume))
+ return ret
+}
+
+// Called by sigtramp from Windows VEH handler.
+// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
+// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
+//
+// This is nosplit to avoid growing the stack until we've checked for
+// _EXCEPTION_BREAKPOINT, which is raised by abort() if we overflow the g0 stack.
+//
+//go:nosplit
+func exceptionhandler(info *exceptionrecord, r *context, gp *g) int32 {
+ if !isgoexception(info, r) {
+ return _EXCEPTION_CONTINUE_SEARCH
+ }
+
+ if gp.throwsplit || isAbort(r) {
+ // We can't safely sigpanic because it may grow the stack.
+ // Or this is a call to abort.
+ // Don't go through any more of the Windows handler chain.
+ // Crash now.
+ winthrow(info, r, gp)
+ }
+
+ // After this point, it is safe to grow the stack.
+
+ // Make it look like a call to the signal func.
+ // Have to pass arguments out of band since
+ // augmenting the stack frame would break
+ // the unwinding code.
+ gp.sig = info.exceptioncode
+ gp.sigcode0 = info.exceptioninformation[0]
+ gp.sigcode1 = info.exceptioninformation[1]
+ gp.sigpc = r.ip()
+
+ // Only push runtime·sigpanic if r.ip() != 0.
+ // If r.ip() == 0, probably panicked because of a
+ // call to a nil func. Not pushing that onto sp will
+ // make the trace look like a call to runtime·sigpanic instead.
+ // (Otherwise the trace will end at runtime·sigpanic and we
+ // won't get to see who faulted.)
+ // Also don't push a sigpanic frame if the faulting PC
+ // is the entry of asyncPreempt. In this case, we suspended
+ // the thread right between the fault and the exception handler
+ // starting to run, and we have pushed an asyncPreempt call.
+ // The exception is not from asyncPreempt, so not to push a
+ // sigpanic call to make it look like that. Instead, just
+ // overwrite the PC. (See issue #35773)
+ if r.ip() != 0 && r.ip() != abi.FuncPCABI0(asyncPreempt) {
+ sp := unsafe.Pointer(r.sp())
+ delta := uintptr(sys.StackAlign)
+ sp = add(sp, -delta)
+ r.set_sp(uintptr(sp))
+ if usesLR {
+ *((*uintptr)(sp)) = r.lr()
+ r.set_lr(r.ip())
+ } else {
+ *((*uintptr)(sp)) = r.ip()
+ }
+ }
+ r.set_ip(abi.FuncPCABI0(sigpanic0))
+ return _EXCEPTION_CONTINUE_EXECUTION
+}
+
+// It seems Windows searches ContinueHandler's list even
+// if ExceptionHandler returns EXCEPTION_CONTINUE_EXECUTION.
+// firstcontinuehandler will stop that search,
+// if exceptionhandler did the same earlier.
+//
+// It is nosplit for the same reason as exceptionhandler.
+//
+//go:nosplit
+func firstcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
+ if !isgoexception(info, r) {
+ return _EXCEPTION_CONTINUE_SEARCH
+ }
+ return _EXCEPTION_CONTINUE_EXECUTION
+}
+
+// lastcontinuehandler is reached, because runtime cannot handle
+// current exception. lastcontinuehandler will print crash info and exit.
+//
+// It is nosplit for the same reason as exceptionhandler.
+//
+//go:nosplit
+func lastcontinuehandler(info *exceptionrecord, r *context, gp *g) int32 {
+ if islibrary || isarchive {
+ // Go DLL/archive has been loaded in a non-go program.
+ // If the exception does not originate from go, the go runtime
+ // should not take responsibility of crashing the process.
+ return _EXCEPTION_CONTINUE_SEARCH
+ }
+
+ // VEH is called before SEH, but arm64 MSVC DLLs use SEH to trap
+ // illegal instructions during runtime initialization to determine
+ // CPU features, so if we make it to the last handler and we're
+ // arm64 and it's an illegal instruction and this is coming from
+ // non-Go code, then assume it's this runtime probing happen, and
+ // pass that onward to SEH.
+ if GOARCH == "arm64" && info.exceptioncode == _EXCEPTION_ILLEGAL_INSTRUCTION &&
+ (r.ip() < firstmoduledata.text || firstmoduledata.etext < r.ip()) {
+ return _EXCEPTION_CONTINUE_SEARCH
+ }
+
+ winthrow(info, r, gp)
+ return 0 // not reached
+}
+
+// Always called on g0. gp is the G where the exception occurred.
+//
+//go:nosplit
+func winthrow(info *exceptionrecord, r *context, gp *g) {
+ g0 := getg()
+
+ if panicking.Load() != 0 { // traceback already printed
+ exit(2)
+ }
+ panicking.Store(1)
+
+ // In case we're handling a g0 stack overflow, blow away the
+ // g0 stack bounds so we have room to print the traceback. If
+ // this somehow overflows the stack, the OS will trap it.
+ g0.stack.lo = 0
+ g0.stackguard0 = g0.stack.lo + stackGuard
+ g0.stackguard1 = g0.stackguard0
+
+ print("Exception ", hex(info.exceptioncode), " ", hex(info.exceptioninformation[0]), " ", hex(info.exceptioninformation[1]), " ", hex(r.ip()), "\n")
+
+ print("PC=", hex(r.ip()), "\n")
+ if g0.m.incgo && gp == g0.m.g0 && g0.m.curg != nil {
+ if iscgo {
+ print("signal arrived during external code execution\n")
+ }
+ gp = g0.m.curg
+ }
+ print("\n")
+
+ g0.m.throwing = throwTypeRuntime
+ g0.m.caughtsig.set(gp)
+
+ level, _, docrash := gotraceback()
+ if level > 0 {
+ tracebacktrap(r.ip(), r.sp(), r.lr(), gp)
+ tracebackothers(gp)
+ dumpregs(r)
+ }
+
+ if docrash {
+ dieFromException(info, r)
+ }
+
+ exit(2)
+}
+
+func sigpanic() {
+ gp := getg()
+ if !canpanic() {
+ throw("unexpected signal during runtime execution")
+ }
+
+ switch gp.sig {
+ case _EXCEPTION_ACCESS_VIOLATION, _EXCEPTION_IN_PAGE_ERROR:
+ if gp.sigcode1 < 0x1000 {
+ panicmem()
+ }
+ if gp.paniconfault {
+ panicmemAddr(gp.sigcode1)
+ }
+ if inUserArenaChunk(gp.sigcode1) {
+ // We could check that the arena chunk is explicitly set to fault,
+ // but the fact that we faulted on accessing it is enough to prove
+ // that it is.
+ print("accessed data from freed user arena ", hex(gp.sigcode1), "\n")
+ } else {
+ print("unexpected fault address ", hex(gp.sigcode1), "\n")
+ }
+ throw("fault")
+ case _EXCEPTION_INT_DIVIDE_BY_ZERO:
+ panicdivide()
+ case _EXCEPTION_INT_OVERFLOW:
+ panicoverflow()
+ case _EXCEPTION_FLT_DENORMAL_OPERAND,
+ _EXCEPTION_FLT_DIVIDE_BY_ZERO,
+ _EXCEPTION_FLT_INEXACT_RESULT,
+ _EXCEPTION_FLT_OVERFLOW,
+ _EXCEPTION_FLT_UNDERFLOW:
+ panicfloat()
+ }
+ throw("fault")
+}
+
+// Following are not implemented.
+
+func initsig(preinit bool) {
+}
+
+func sigenable(sig uint32) {
+}
+
+func sigdisable(sig uint32) {
+}
+
+func sigignore(sig uint32) {
+}
+
+func signame(sig uint32) string {
+ return ""
+}
+
+//go:nosplit
+func crash() {
+ dieFromException(nil, nil)
+}
+
+// dieFromException raises an exception that bypasses all exception handlers.
+// This provides the expected exit status for the shell.
+//
+//go:nosplit
+func dieFromException(info *exceptionrecord, r *context) {
+ if info == nil {
+ gp := getg()
+ if gp.sig != 0 {
+ // Try to reconstruct an exception record from
+ // the exception information stored in gp.
+ info = &exceptionrecord{
+ exceptionaddress: gp.sigpc,
+ exceptioncode: gp.sig,
+ numberparameters: 2,
+ }
+ info.exceptioninformation[0] = gp.sigcode0
+ info.exceptioninformation[1] = gp.sigcode1
+ } else {
+ // By default, a failing Go application exits with exit code 2.
+ // Use this value when gp does not contain exception info.
+ info = &exceptionrecord{
+ exceptioncode: 2,
+ }
+ }
+ }
+ const FAIL_FAST_GENERATE_EXCEPTION_ADDRESS = 0x1
+ stdcall3(_RaiseFailFastException, uintptr(unsafe.Pointer(info)), uintptr(unsafe.Pointer(r)), FAIL_FAST_GENERATE_EXCEPTION_ADDRESS)
+}
+
+// gsignalStack is unused on Windows.
+type gsignalStack struct{}
diff --git a/contrib/go/_std_1.20/src/runtime/sigqueue.go b/contrib/go/_std_1.21/src/runtime/sigqueue.go
index 886536a1cc..886536a1cc 100644
--- a/contrib/go/_std_1.20/src/runtime/sigqueue.go
+++ b/contrib/go/_std_1.21/src/runtime/sigqueue.go
diff --git a/contrib/go/_std_1.20/src/runtime/sigqueue_note.go b/contrib/go/_std_1.21/src/runtime/sigqueue_note.go
index fb1a517fa5..fb1a517fa5 100644
--- a/contrib/go/_std_1.20/src/runtime/sigqueue_note.go
+++ b/contrib/go/_std_1.21/src/runtime/sigqueue_note.go
diff --git a/contrib/go/_std_1.20/src/runtime/sigtab_linux_generic.go b/contrib/go/_std_1.21/src/runtime/sigtab_linux_generic.go
index fe93bbafb5..fe93bbafb5 100644
--- a/contrib/go/_std_1.20/src/runtime/sigtab_linux_generic.go
+++ b/contrib/go/_std_1.21/src/runtime/sigtab_linux_generic.go
diff --git a/contrib/go/_std_1.21/src/runtime/sizeclasses.go b/contrib/go/_std_1.21/src/runtime/sizeclasses.go
new file mode 100644
index 0000000000..9314623453
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/sizeclasses.go
@@ -0,0 +1,98 @@
+// Code generated by mksizeclasses.go; DO NOT EDIT.
+//go:generate go run mksizeclasses.go
+
+package runtime
+
+// class bytes/obj bytes/span objects tail waste max waste min align
+// 1 8 8192 1024 0 87.50% 8
+// 2 16 8192 512 0 43.75% 16
+// 3 24 8192 341 8 29.24% 8
+// 4 32 8192 256 0 21.88% 32
+// 5 48 8192 170 32 31.52% 16
+// 6 64 8192 128 0 23.44% 64
+// 7 80 8192 102 32 19.07% 16
+// 8 96 8192 85 32 15.95% 32
+// 9 112 8192 73 16 13.56% 16
+// 10 128 8192 64 0 11.72% 128
+// 11 144 8192 56 128 11.82% 16
+// 12 160 8192 51 32 9.73% 32
+// 13 176 8192 46 96 9.59% 16
+// 14 192 8192 42 128 9.25% 64
+// 15 208 8192 39 80 8.12% 16
+// 16 224 8192 36 128 8.15% 32
+// 17 240 8192 34 32 6.62% 16
+// 18 256 8192 32 0 5.86% 256
+// 19 288 8192 28 128 12.16% 32
+// 20 320 8192 25 192 11.80% 64
+// 21 352 8192 23 96 9.88% 32
+// 22 384 8192 21 128 9.51% 128
+// 23 416 8192 19 288 10.71% 32
+// 24 448 8192 18 128 8.37% 64
+// 25 480 8192 17 32 6.82% 32
+// 26 512 8192 16 0 6.05% 512
+// 27 576 8192 14 128 12.33% 64
+// 28 640 8192 12 512 15.48% 128
+// 29 704 8192 11 448 13.93% 64
+// 30 768 8192 10 512 13.94% 256
+// 31 896 8192 9 128 15.52% 128
+// 32 1024 8192 8 0 12.40% 1024
+// 33 1152 8192 7 128 12.41% 128
+// 34 1280 8192 6 512 15.55% 256
+// 35 1408 16384 11 896 14.00% 128
+// 36 1536 8192 5 512 14.00% 512
+// 37 1792 16384 9 256 15.57% 256
+// 38 2048 8192 4 0 12.45% 2048
+// 39 2304 16384 7 256 12.46% 256
+// 40 2688 8192 3 128 15.59% 128
+// 41 3072 24576 8 0 12.47% 1024
+// 42 3200 16384 5 384 6.22% 128
+// 43 3456 24576 7 384 8.83% 128
+// 44 4096 8192 2 0 15.60% 4096
+// 45 4864 24576 5 256 16.65% 256
+// 46 5376 16384 3 256 10.92% 256
+// 47 6144 24576 4 0 12.48% 2048
+// 48 6528 32768 5 128 6.23% 128
+// 49 6784 40960 6 256 4.36% 128
+// 50 6912 49152 7 768 3.37% 256
+// 51 8192 8192 1 0 15.61% 8192
+// 52 9472 57344 6 512 14.28% 256
+// 53 9728 49152 5 512 3.64% 512
+// 54 10240 40960 4 0 4.99% 2048
+// 55 10880 32768 3 128 6.24% 128
+// 56 12288 24576 2 0 11.45% 4096
+// 57 13568 40960 3 256 9.99% 256
+// 58 14336 57344 4 0 5.35% 2048
+// 59 16384 16384 1 0 12.49% 8192
+// 60 18432 73728 4 0 11.11% 2048
+// 61 19072 57344 3 128 3.57% 128
+// 62 20480 40960 2 0 6.87% 4096
+// 63 21760 65536 3 256 6.25% 256
+// 64 24576 24576 1 0 11.45% 8192
+// 65 27264 81920 3 128 10.00% 128
+// 66 28672 57344 2 0 4.91% 4096
+// 67 32768 32768 1 0 12.50% 8192
+
+// alignment bits min obj size
+// 8 3 8
+// 16 4 32
+// 32 5 256
+// 64 6 512
+// 128 7 768
+// 4096 12 28672
+// 8192 13 32768
+
+const (
+ _MaxSmallSize = 32768
+ smallSizeDiv = 8
+ smallSizeMax = 1024
+ largeSizeDiv = 128
+ _NumSizeClasses = 68
+ _PageShift = 13
+ maxObjsPerSpan = 1024
+)
+
+var class_to_size = [_NumSizeClasses]uint16{0, 8, 16, 24, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 288, 320, 352, 384, 416, 448, 480, 512, 576, 640, 704, 768, 896, 1024, 1152, 1280, 1408, 1536, 1792, 2048, 2304, 2688, 3072, 3200, 3456, 4096, 4864, 5376, 6144, 6528, 6784, 6912, 8192, 9472, 9728, 10240, 10880, 12288, 13568, 14336, 16384, 18432, 19072, 20480, 21760, 24576, 27264, 28672, 32768}
+var class_to_allocnpages = [_NumSizeClasses]uint8{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 2, 3, 1, 3, 2, 3, 4, 5, 6, 1, 7, 6, 5, 4, 3, 5, 7, 2, 9, 7, 5, 8, 3, 10, 7, 4}
+var class_to_divmagic = [_NumSizeClasses]uint32{0, ^uint32(0)/8 + 1, ^uint32(0)/16 + 1, ^uint32(0)/24 + 1, ^uint32(0)/32 + 1, ^uint32(0)/48 + 1, ^uint32(0)/64 + 1, ^uint32(0)/80 + 1, ^uint32(0)/96 + 1, ^uint32(0)/112 + 1, ^uint32(0)/128 + 1, ^uint32(0)/144 + 1, ^uint32(0)/160 + 1, ^uint32(0)/176 + 1, ^uint32(0)/192 + 1, ^uint32(0)/208 + 1, ^uint32(0)/224 + 1, ^uint32(0)/240 + 1, ^uint32(0)/256 + 1, ^uint32(0)/288 + 1, ^uint32(0)/320 + 1, ^uint32(0)/352 + 1, ^uint32(0)/384 + 1, ^uint32(0)/416 + 1, ^uint32(0)/448 + 1, ^uint32(0)/480 + 1, ^uint32(0)/512 + 1, ^uint32(0)/576 + 1, ^uint32(0)/640 + 1, ^uint32(0)/704 + 1, ^uint32(0)/768 + 1, ^uint32(0)/896 + 1, ^uint32(0)/1024 + 1, ^uint32(0)/1152 + 1, ^uint32(0)/1280 + 1, ^uint32(0)/1408 + 1, ^uint32(0)/1536 + 1, ^uint32(0)/1792 + 1, ^uint32(0)/2048 + 1, ^uint32(0)/2304 + 1, ^uint32(0)/2688 + 1, ^uint32(0)/3072 + 1, ^uint32(0)/3200 + 1, ^uint32(0)/3456 + 1, ^uint32(0)/4096 + 1, ^uint32(0)/4864 + 1, ^uint32(0)/5376 + 1, ^uint32(0)/6144 + 1, ^uint32(0)/6528 + 1, ^uint32(0)/6784 + 1, ^uint32(0)/6912 + 1, ^uint32(0)/8192 + 1, ^uint32(0)/9472 + 1, ^uint32(0)/9728 + 1, ^uint32(0)/10240 + 1, ^uint32(0)/10880 + 1, ^uint32(0)/12288 + 1, ^uint32(0)/13568 + 1, ^uint32(0)/14336 + 1, ^uint32(0)/16384 + 1, ^uint32(0)/18432 + 1, ^uint32(0)/19072 + 1, ^uint32(0)/20480 + 1, ^uint32(0)/21760 + 1, ^uint32(0)/24576 + 1, ^uint32(0)/27264 + 1, ^uint32(0)/28672 + 1, ^uint32(0)/32768 + 1}
+var size_to_class8 = [smallSizeMax/smallSizeDiv + 1]uint8{0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}
+var size_to_class128 = [(_MaxSmallSize-smallSizeMax)/largeSizeDiv + 1]uint8{32, 33, 34, 35, 36, 37, 37, 38, 38, 39, 39, 40, 40, 40, 41, 41, 41, 42, 43, 43, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 48, 48, 49, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67}
diff --git a/contrib/go/_std_1.21/src/runtime/slice.go b/contrib/go/_std_1.21/src/runtime/slice.go
new file mode 100644
index 0000000000..228697a708
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/slice.go
@@ -0,0 +1,355 @@
+// Copyright 2009 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/math"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+type slice struct {
+ array unsafe.Pointer
+ len int
+ cap int
+}
+
+// A notInHeapSlice is a slice backed by runtime/internal/sys.NotInHeap memory.
+type notInHeapSlice struct {
+ array *notInHeap
+ len int
+ cap int
+}
+
+func panicmakeslicelen() {
+ panic(errorString("makeslice: len out of range"))
+}
+
+func panicmakeslicecap() {
+ panic(errorString("makeslice: cap out of range"))
+}
+
+// makeslicecopy allocates a slice of "tolen" elements of type "et",
+// then copies "fromlen" elements of type "et" into that new allocation from "from".
+func makeslicecopy(et *_type, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer {
+ var tomem, copymem uintptr
+ if uintptr(tolen) > uintptr(fromlen) {
+ var overflow bool
+ tomem, overflow = math.MulUintptr(et.Size_, uintptr(tolen))
+ if overflow || tomem > maxAlloc || tolen < 0 {
+ panicmakeslicelen()
+ }
+ copymem = et.Size_ * uintptr(fromlen)
+ } else {
+ // fromlen is a known good length providing and equal or greater than tolen,
+ // thereby making tolen a good slice length too as from and to slices have the
+ // same element width.
+ tomem = et.Size_ * uintptr(tolen)
+ copymem = tomem
+ }
+
+ var to unsafe.Pointer
+ if et.PtrBytes == 0 {
+ to = mallocgc(tomem, nil, false)
+ if copymem < tomem {
+ memclrNoHeapPointers(add(to, copymem), tomem-copymem)
+ }
+ } else {
+ // Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory.
+ to = mallocgc(tomem, et, true)
+ if copymem > 0 && writeBarrier.enabled {
+ // Only shade the pointers in old.array since we know the destination slice to
+ // only contains nil pointers because it has been cleared during alloc.
+ bulkBarrierPreWriteSrcOnly(uintptr(to), uintptr(from), copymem)
+ }
+ }
+
+ if raceenabled {
+ callerpc := getcallerpc()
+ pc := abi.FuncPCABIInternal(makeslicecopy)
+ racereadrangepc(from, copymem, callerpc, pc)
+ }
+ if msanenabled {
+ msanread(from, copymem)
+ }
+ if asanenabled {
+ asanread(from, copymem)
+ }
+
+ memmove(to, from, copymem)
+
+ return to
+}
+
+func makeslice(et *_type, len, cap int) unsafe.Pointer {
+ mem, overflow := math.MulUintptr(et.Size_, uintptr(cap))
+ if overflow || mem > maxAlloc || len < 0 || len > cap {
+ // NOTE: Produce a 'len out of range' error instead of a
+ // 'cap out of range' error when someone does make([]T, bignumber).
+ // 'cap out of range' is true too, but since the cap is only being
+ // supplied implicitly, saying len is clearer.
+ // See golang.org/issue/4085.
+ mem, overflow := math.MulUintptr(et.Size_, uintptr(len))
+ if overflow || mem > maxAlloc || len < 0 {
+ panicmakeslicelen()
+ }
+ panicmakeslicecap()
+ }
+
+ return mallocgc(mem, et, true)
+}
+
+func makeslice64(et *_type, len64, cap64 int64) unsafe.Pointer {
+ len := int(len64)
+ if int64(len) != len64 {
+ panicmakeslicelen()
+ }
+
+ cap := int(cap64)
+ if int64(cap) != cap64 {
+ panicmakeslicecap()
+ }
+
+ return makeslice(et, len, cap)
+}
+
+// This is a wrapper over runtime/internal/math.MulUintptr,
+// so the compiler can recognize and treat it as an intrinsic.
+func mulUintptr(a, b uintptr) (uintptr, bool) {
+ return math.MulUintptr(a, b)
+}
+
+// growslice allocates new backing store for a slice.
+//
+// arguments:
+//
+// oldPtr = pointer to the slice's backing array
+// newLen = new length (= oldLen + num)
+// oldCap = original slice's capacity.
+// num = number of elements being added
+// et = element type
+//
+// return values:
+//
+// newPtr = pointer to the new backing store
+// newLen = same value as the argument
+// newCap = capacity of the new backing store
+//
+// Requires that uint(newLen) > uint(oldCap).
+// Assumes the original slice length is newLen - num
+//
+// A new backing store is allocated with space for at least newLen elements.
+// Existing entries [0, oldLen) are copied over to the new backing store.
+// Added entries [oldLen, newLen) are not initialized by growslice
+// (although for pointer-containing element types, they are zeroed). They
+// must be initialized by the caller.
+// Trailing entries [newLen, newCap) are zeroed.
+//
+// growslice's odd calling convention makes the generated code that calls
+// this function simpler. In particular, it accepts and returns the
+// new length so that the old length is not live (does not need to be
+// spilled/restored) and the new length is returned (also does not need
+// to be spilled/restored).
+func growslice(oldPtr unsafe.Pointer, newLen, oldCap, num int, et *_type) slice {
+ oldLen := newLen - num
+ if raceenabled {
+ callerpc := getcallerpc()
+ racereadrangepc(oldPtr, uintptr(oldLen*int(et.Size_)), callerpc, abi.FuncPCABIInternal(growslice))
+ }
+ if msanenabled {
+ msanread(oldPtr, uintptr(oldLen*int(et.Size_)))
+ }
+ if asanenabled {
+ asanread(oldPtr, uintptr(oldLen*int(et.Size_)))
+ }
+
+ if newLen < 0 {
+ panic(errorString("growslice: len out of range"))
+ }
+
+ if et.Size_ == 0 {
+ // append should not create a slice with nil pointer but non-zero len.
+ // We assume that append doesn't need to preserve oldPtr in this case.
+ return slice{unsafe.Pointer(&zerobase), newLen, newLen}
+ }
+
+ newcap := oldCap
+ doublecap := newcap + newcap
+ if newLen > doublecap {
+ newcap = newLen
+ } else {
+ const threshold = 256
+ if oldCap < threshold {
+ newcap = doublecap
+ } else {
+ // Check 0 < newcap to detect overflow
+ // and prevent an infinite loop.
+ for 0 < newcap && newcap < newLen {
+ // Transition from growing 2x for small slices
+ // to growing 1.25x for large slices. This formula
+ // gives a smooth-ish transition between the two.
+ newcap += (newcap + 3*threshold) / 4
+ }
+ // Set newcap to the requested cap when
+ // the newcap calculation overflowed.
+ if newcap <= 0 {
+ newcap = newLen
+ }
+ }
+ }
+
+ var overflow bool
+ var lenmem, newlenmem, capmem uintptr
+ // Specialize for common values of et.Size.
+ // For 1 we don't need any division/multiplication.
+ // For goarch.PtrSize, compiler will optimize division/multiplication into a shift by a constant.
+ // For powers of 2, use a variable shift.
+ switch {
+ case et.Size_ == 1:
+ lenmem = uintptr(oldLen)
+ newlenmem = uintptr(newLen)
+ capmem = roundupsize(uintptr(newcap))
+ overflow = uintptr(newcap) > maxAlloc
+ newcap = int(capmem)
+ case et.Size_ == goarch.PtrSize:
+ lenmem = uintptr(oldLen) * goarch.PtrSize
+ newlenmem = uintptr(newLen) * goarch.PtrSize
+ capmem = roundupsize(uintptr(newcap) * goarch.PtrSize)
+ overflow = uintptr(newcap) > maxAlloc/goarch.PtrSize
+ newcap = int(capmem / goarch.PtrSize)
+ case isPowerOfTwo(et.Size_):
+ var shift uintptr
+ if goarch.PtrSize == 8 {
+ // Mask shift for better code generation.
+ shift = uintptr(sys.TrailingZeros64(uint64(et.Size_))) & 63
+ } else {
+ shift = uintptr(sys.TrailingZeros32(uint32(et.Size_))) & 31
+ }
+ lenmem = uintptr(oldLen) << shift
+ newlenmem = uintptr(newLen) << shift
+ capmem = roundupsize(uintptr(newcap) << shift)
+ overflow = uintptr(newcap) > (maxAlloc >> shift)
+ newcap = int(capmem >> shift)
+ capmem = uintptr(newcap) << shift
+ default:
+ lenmem = uintptr(oldLen) * et.Size_
+ newlenmem = uintptr(newLen) * et.Size_
+ capmem, overflow = math.MulUintptr(et.Size_, uintptr(newcap))
+ capmem = roundupsize(capmem)
+ newcap = int(capmem / et.Size_)
+ capmem = uintptr(newcap) * et.Size_
+ }
+
+ // The check of overflow in addition to capmem > maxAlloc is needed
+ // to prevent an overflow which can be used to trigger a segfault
+ // on 32bit architectures with this example program:
+ //
+ // type T [1<<27 + 1]int64
+ //
+ // var d T
+ // var s []T
+ //
+ // func main() {
+ // s = append(s, d, d, d, d)
+ // print(len(s), "\n")
+ // }
+ if overflow || capmem > maxAlloc {
+ panic(errorString("growslice: len out of range"))
+ }
+
+ var p unsafe.Pointer
+ if et.PtrBytes == 0 {
+ p = mallocgc(capmem, nil, false)
+ // The append() that calls growslice is going to overwrite from oldLen to newLen.
+ // Only clear the part that will not be overwritten.
+ // The reflect_growslice() that calls growslice will manually clear
+ // the region not cleared here.
+ memclrNoHeapPointers(add(p, newlenmem), capmem-newlenmem)
+ } else {
+ // Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory.
+ p = mallocgc(capmem, et, true)
+ if lenmem > 0 && writeBarrier.enabled {
+ // Only shade the pointers in oldPtr since we know the destination slice p
+ // only contains nil pointers because it has been cleared during alloc.
+ bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(oldPtr), lenmem-et.Size_+et.PtrBytes)
+ }
+ }
+ memmove(p, oldPtr, lenmem)
+
+ return slice{p, newLen, newcap}
+}
+
+//go:linkname reflect_growslice reflect.growslice
+func reflect_growslice(et *_type, old slice, num int) slice {
+ // Semantically equivalent to slices.Grow, except that the caller
+ // is responsible for ensuring that old.len+num > old.cap.
+ num -= old.cap - old.len // preserve memory of old[old.len:old.cap]
+ new := growslice(old.array, old.cap+num, old.cap, num, et)
+ // growslice does not zero out new[old.cap:new.len] since it assumes that
+ // the memory will be overwritten by an append() that called growslice.
+ // Since the caller of reflect_growslice is not append(),
+ // zero out this region before returning the slice to the reflect package.
+ if et.PtrBytes == 0 {
+ oldcapmem := uintptr(old.cap) * et.Size_
+ newlenmem := uintptr(new.len) * et.Size_
+ memclrNoHeapPointers(add(new.array, oldcapmem), newlenmem-oldcapmem)
+ }
+ new.len = old.len // preserve the old length
+ return new
+}
+
+func isPowerOfTwo(x uintptr) bool {
+ return x&(x-1) == 0
+}
+
+// slicecopy is used to copy from a string or slice of pointerless elements into a slice.
+func slicecopy(toPtr unsafe.Pointer, toLen int, fromPtr unsafe.Pointer, fromLen int, width uintptr) int {
+ if fromLen == 0 || toLen == 0 {
+ return 0
+ }
+
+ n := fromLen
+ if toLen < n {
+ n = toLen
+ }
+
+ if width == 0 {
+ return n
+ }
+
+ size := uintptr(n) * width
+ if raceenabled {
+ callerpc := getcallerpc()
+ pc := abi.FuncPCABIInternal(slicecopy)
+ racereadrangepc(fromPtr, size, callerpc, pc)
+ racewriterangepc(toPtr, size, callerpc, pc)
+ }
+ if msanenabled {
+ msanread(fromPtr, size)
+ msanwrite(toPtr, size)
+ }
+ if asanenabled {
+ asanread(fromPtr, size)
+ asanwrite(toPtr, size)
+ }
+
+ if size == 1 { // common case worth about 2x to do here
+ // TODO: is this still worth it with new memmove impl?
+ *(*byte)(toPtr) = *(*byte)(fromPtr) // known to be a byte pointer
+ } else {
+ memmove(toPtr, fromPtr, size)
+ }
+ return n
+}
+
+//go:linkname bytealg_MakeNoZero internal/bytealg.MakeNoZero
+func bytealg_MakeNoZero(len int) []byte {
+ if uintptr(len) > maxAlloc {
+ panicmakeslicelen()
+ }
+ return unsafe.Slice((*byte)(mallocgc(uintptr(len), nil, false)), len)
+}
diff --git a/contrib/go/_std_1.20/src/runtime/softfloat64.go b/contrib/go/_std_1.21/src/runtime/softfloat64.go
index 42ef009297..42ef009297 100644
--- a/contrib/go/_std_1.20/src/runtime/softfloat64.go
+++ b/contrib/go/_std_1.21/src/runtime/softfloat64.go
diff --git a/contrib/go/_std_1.21/src/runtime/stack.go b/contrib/go/_std_1.21/src/runtime/stack.go
new file mode 100644
index 0000000000..45d66da91f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/stack.go
@@ -0,0 +1,1347 @@
+// Copyright 2013 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 runtime
+
+import (
+ "internal/abi"
+ "internal/cpu"
+ "internal/goarch"
+ "internal/goos"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+/*
+Stack layout parameters.
+Included both by runtime (compiled via 6c) and linkers (compiled via gcc).
+
+The per-goroutine g->stackguard is set to point StackGuard bytes
+above the bottom of the stack. Each function compares its stack
+pointer against g->stackguard to check for overflow. To cut one
+instruction from the check sequence for functions with tiny frames,
+the stack is allowed to protrude StackSmall bytes below the stack
+guard. Functions with large frames don't bother with the check and
+always call morestack. The sequences are (for amd64, others are
+similar):
+
+ guard = g->stackguard
+ frame = function's stack frame size
+ argsize = size of function arguments (call + return)
+
+ stack frame size <= StackSmall:
+ CMPQ guard, SP
+ JHI 3(PC)
+ MOVQ m->morearg, $(argsize << 32)
+ CALL morestack(SB)
+
+ stack frame size > StackSmall but < StackBig
+ LEAQ (frame-StackSmall)(SP), R0
+ CMPQ guard, R0
+ JHI 3(PC)
+ MOVQ m->morearg, $(argsize << 32)
+ CALL morestack(SB)
+
+ stack frame size >= StackBig:
+ MOVQ m->morearg, $((argsize << 32) | frame)
+ CALL morestack(SB)
+
+The bottom StackGuard - StackSmall bytes are important: there has
+to be enough room to execute functions that refuse to check for
+stack overflow, either because they need to be adjacent to the
+actual caller's frame (deferproc) or because they handle the imminent
+stack overflow (morestack).
+
+For example, deferproc might call malloc, which does one of the
+above checks (without allocating a full frame), which might trigger
+a call to morestack. This sequence needs to fit in the bottom
+section of the stack. On amd64, morestack's frame is 40 bytes, and
+deferproc's frame is 56 bytes. That fits well within the
+StackGuard - StackSmall bytes at the bottom.
+The linkers explore all possible call traces involving non-splitting
+functions to make sure that this limit cannot be violated.
+*/
+
+const (
+ // stackSystem is a number of additional bytes to add
+ // to each stack below the usual guard area for OS-specific
+ // purposes like signal handling. Used on Windows, Plan 9,
+ // and iOS because they do not use a separate stack.
+ stackSystem = goos.IsWindows*512*goarch.PtrSize + goos.IsPlan9*512 + goos.IsIos*goarch.IsArm64*1024
+
+ // The minimum size of stack used by Go code
+ stackMin = 2048
+
+ // The minimum stack size to allocate.
+ // The hackery here rounds fixedStack0 up to a power of 2.
+ fixedStack0 = stackMin + stackSystem
+ fixedStack1 = fixedStack0 - 1
+ fixedStack2 = fixedStack1 | (fixedStack1 >> 1)
+ fixedStack3 = fixedStack2 | (fixedStack2 >> 2)
+ fixedStack4 = fixedStack3 | (fixedStack3 >> 4)
+ fixedStack5 = fixedStack4 | (fixedStack4 >> 8)
+ fixedStack6 = fixedStack5 | (fixedStack5 >> 16)
+ fixedStack = fixedStack6 + 1
+
+ // stackNosplit is the maximum number of bytes that a chain of NOSPLIT
+ // functions can use.
+ // This arithmetic must match that in cmd/internal/objabi/stack.go:StackNosplit.
+ stackNosplit = abi.StackNosplitBase * sys.StackGuardMultiplier
+
+ // The stack guard is a pointer this many bytes above the
+ // bottom of the stack.
+ //
+ // The guard leaves enough room for a stackNosplit chain of NOSPLIT calls
+ // plus one stackSmall frame plus stackSystem bytes for the OS.
+ // This arithmetic must match that in cmd/internal/objabi/stack.go:StackLimit.
+ stackGuard = stackNosplit + stackSystem + abi.StackSmall
+)
+
+const (
+ // stackDebug == 0: no logging
+ // == 1: logging of per-stack operations
+ // == 2: logging of per-frame operations
+ // == 3: logging of per-word updates
+ // == 4: logging of per-word reads
+ stackDebug = 0
+ stackFromSystem = 0 // allocate stacks from system memory instead of the heap
+ stackFaultOnFree = 0 // old stacks are mapped noaccess to detect use after free
+ stackNoCache = 0 // disable per-P small stack caches
+
+ // check the BP links during traceback.
+ debugCheckBP = false
+)
+
+var (
+ stackPoisonCopy = 0 // fill stack that should not be accessed with garbage, to detect bad dereferences during copy
+)
+
+const (
+ uintptrMask = 1<<(8*goarch.PtrSize) - 1
+
+ // The values below can be stored to g.stackguard0 to force
+ // the next stack check to fail.
+ // These are all larger than any real SP.
+
+ // Goroutine preemption request.
+ // 0xfffffade in hex.
+ stackPreempt = uintptrMask & -1314
+
+ // Thread is forking. Causes a split stack check failure.
+ // 0xfffffb2e in hex.
+ stackFork = uintptrMask & -1234
+
+ // Force a stack movement. Used for debugging.
+ // 0xfffffeed in hex.
+ stackForceMove = uintptrMask & -275
+
+ // stackPoisonMin is the lowest allowed stack poison value.
+ stackPoisonMin = uintptrMask & -4096
+)
+
+// Global pool of spans that have free stacks.
+// Stacks are assigned an order according to size.
+//
+// order = log_2(size/FixedStack)
+//
+// There is a free list for each order.
+var stackpool [_NumStackOrders]struct {
+ item stackpoolItem
+ _ [(cpu.CacheLinePadSize - unsafe.Sizeof(stackpoolItem{})%cpu.CacheLinePadSize) % cpu.CacheLinePadSize]byte
+}
+
+type stackpoolItem struct {
+ _ sys.NotInHeap
+ mu mutex
+ span mSpanList
+}
+
+// Global pool of large stack spans.
+var stackLarge struct {
+ lock mutex
+ free [heapAddrBits - pageShift]mSpanList // free lists by log_2(s.npages)
+}
+
+func stackinit() {
+ if _StackCacheSize&_PageMask != 0 {
+ throw("cache size must be a multiple of page size")
+ }
+ for i := range stackpool {
+ stackpool[i].item.span.init()
+ lockInit(&stackpool[i].item.mu, lockRankStackpool)
+ }
+ for i := range stackLarge.free {
+ stackLarge.free[i].init()
+ lockInit(&stackLarge.lock, lockRankStackLarge)
+ }
+}
+
+// stacklog2 returns ⌊log_2(n)⌋.
+func stacklog2(n uintptr) int {
+ log2 := 0
+ for n > 1 {
+ n >>= 1
+ log2++
+ }
+ return log2
+}
+
+// Allocates a stack from the free pool. Must be called with
+// stackpool[order].item.mu held.
+func stackpoolalloc(order uint8) gclinkptr {
+ list := &stackpool[order].item.span
+ s := list.first
+ lockWithRankMayAcquire(&mheap_.lock, lockRankMheap)
+ if s == nil {
+ // no free stacks. Allocate another span worth.
+ s = mheap_.allocManual(_StackCacheSize>>_PageShift, spanAllocStack)
+ if s == nil {
+ throw("out of memory")
+ }
+ if s.allocCount != 0 {
+ throw("bad allocCount")
+ }
+ if s.manualFreeList.ptr() != nil {
+ throw("bad manualFreeList")
+ }
+ osStackAlloc(s)
+ s.elemsize = fixedStack << order
+ for i := uintptr(0); i < _StackCacheSize; i += s.elemsize {
+ x := gclinkptr(s.base() + i)
+ x.ptr().next = s.manualFreeList
+ s.manualFreeList = x
+ }
+ list.insert(s)
+ }
+ x := s.manualFreeList
+ if x.ptr() == nil {
+ throw("span has no free stacks")
+ }
+ s.manualFreeList = x.ptr().next
+ s.allocCount++
+ if s.manualFreeList.ptr() == nil {
+ // all stacks in s are allocated.
+ list.remove(s)
+ }
+ return x
+}
+
+// Adds stack x to the free pool. Must be called with stackpool[order].item.mu held.
+func stackpoolfree(x gclinkptr, order uint8) {
+ s := spanOfUnchecked(uintptr(x))
+ if s.state.get() != mSpanManual {
+ throw("freeing stack not in a stack span")
+ }
+ if s.manualFreeList.ptr() == nil {
+ // s will now have a free stack
+ stackpool[order].item.span.insert(s)
+ }
+ x.ptr().next = s.manualFreeList
+ s.manualFreeList = x
+ s.allocCount--
+ if gcphase == _GCoff && s.allocCount == 0 {
+ // Span is completely free. Return it to the heap
+ // immediately if we're sweeping.
+ //
+ // If GC is active, we delay the free until the end of
+ // GC to avoid the following type of situation:
+ //
+ // 1) GC starts, scans a SudoG but does not yet mark the SudoG.elem pointer
+ // 2) The stack that pointer points to is copied
+ // 3) The old stack is freed
+ // 4) The containing span is marked free
+ // 5) GC attempts to mark the SudoG.elem pointer. The
+ // marking fails because the pointer looks like a
+ // pointer into a free span.
+ //
+ // By not freeing, we prevent step #4 until GC is done.
+ stackpool[order].item.span.remove(s)
+ s.manualFreeList = 0
+ osStackFree(s)
+ mheap_.freeManual(s, spanAllocStack)
+ }
+}
+
+// stackcacherefill/stackcacherelease implement a global pool of stack segments.
+// The pool is required to prevent unlimited growth of per-thread caches.
+//
+//go:systemstack
+func stackcacherefill(c *mcache, order uint8) {
+ if stackDebug >= 1 {
+ print("stackcacherefill order=", order, "\n")
+ }
+
+ // Grab some stacks from the global cache.
+ // Grab half of the allowed capacity (to prevent thrashing).
+ var list gclinkptr
+ var size uintptr
+ lock(&stackpool[order].item.mu)
+ for size < _StackCacheSize/2 {
+ x := stackpoolalloc(order)
+ x.ptr().next = list
+ list = x
+ size += fixedStack << order
+ }
+ unlock(&stackpool[order].item.mu)
+ c.stackcache[order].list = list
+ c.stackcache[order].size = size
+}
+
+//go:systemstack
+func stackcacherelease(c *mcache, order uint8) {
+ if stackDebug >= 1 {
+ print("stackcacherelease order=", order, "\n")
+ }
+ x := c.stackcache[order].list
+ size := c.stackcache[order].size
+ lock(&stackpool[order].item.mu)
+ for size > _StackCacheSize/2 {
+ y := x.ptr().next
+ stackpoolfree(x, order)
+ x = y
+ size -= fixedStack << order
+ }
+ unlock(&stackpool[order].item.mu)
+ c.stackcache[order].list = x
+ c.stackcache[order].size = size
+}
+
+//go:systemstack
+func stackcache_clear(c *mcache) {
+ if stackDebug >= 1 {
+ print("stackcache clear\n")
+ }
+ for order := uint8(0); order < _NumStackOrders; order++ {
+ lock(&stackpool[order].item.mu)
+ x := c.stackcache[order].list
+ for x.ptr() != nil {
+ y := x.ptr().next
+ stackpoolfree(x, order)
+ x = y
+ }
+ c.stackcache[order].list = 0
+ c.stackcache[order].size = 0
+ unlock(&stackpool[order].item.mu)
+ }
+}
+
+// stackalloc allocates an n byte stack.
+//
+// stackalloc must run on the system stack because it uses per-P
+// resources and must not split the stack.
+//
+//go:systemstack
+func stackalloc(n uint32) stack {
+ // Stackalloc must be called on scheduler stack, so that we
+ // never try to grow the stack during the code that stackalloc runs.
+ // Doing so would cause a deadlock (issue 1547).
+ thisg := getg()
+ if thisg != thisg.m.g0 {
+ throw("stackalloc not on scheduler stack")
+ }
+ if n&(n-1) != 0 {
+ throw("stack size not a power of 2")
+ }
+ if stackDebug >= 1 {
+ print("stackalloc ", n, "\n")
+ }
+
+ if debug.efence != 0 || stackFromSystem != 0 {
+ n = uint32(alignUp(uintptr(n), physPageSize))
+ v := sysAlloc(uintptr(n), &memstats.stacks_sys)
+ if v == nil {
+ throw("out of memory (stackalloc)")
+ }
+ return stack{uintptr(v), uintptr(v) + uintptr(n)}
+ }
+
+ // Small stacks are allocated with a fixed-size free-list allocator.
+ // If we need a stack of a bigger size, we fall back on allocating
+ // a dedicated span.
+ var v unsafe.Pointer
+ if n < fixedStack<<_NumStackOrders && n < _StackCacheSize {
+ order := uint8(0)
+ n2 := n
+ for n2 > fixedStack {
+ order++
+ n2 >>= 1
+ }
+ var x gclinkptr
+ if stackNoCache != 0 || thisg.m.p == 0 || thisg.m.preemptoff != "" {
+ // thisg.m.p == 0 can happen in the guts of exitsyscall
+ // or procresize. Just get a stack from the global pool.
+ // Also don't touch stackcache during gc
+ // as it's flushed concurrently.
+ lock(&stackpool[order].item.mu)
+ x = stackpoolalloc(order)
+ unlock(&stackpool[order].item.mu)
+ } else {
+ c := thisg.m.p.ptr().mcache
+ x = c.stackcache[order].list
+ if x.ptr() == nil {
+ stackcacherefill(c, order)
+ x = c.stackcache[order].list
+ }
+ c.stackcache[order].list = x.ptr().next
+ c.stackcache[order].size -= uintptr(n)
+ }
+ v = unsafe.Pointer(x)
+ } else {
+ var s *mspan
+ npage := uintptr(n) >> _PageShift
+ log2npage := stacklog2(npage)
+
+ // Try to get a stack from the large stack cache.
+ lock(&stackLarge.lock)
+ if !stackLarge.free[log2npage].isEmpty() {
+ s = stackLarge.free[log2npage].first
+ stackLarge.free[log2npage].remove(s)
+ }
+ unlock(&stackLarge.lock)
+
+ lockWithRankMayAcquire(&mheap_.lock, lockRankMheap)
+
+ if s == nil {
+ // Allocate a new stack from the heap.
+ s = mheap_.allocManual(npage, spanAllocStack)
+ if s == nil {
+ throw("out of memory")
+ }
+ osStackAlloc(s)
+ s.elemsize = uintptr(n)
+ }
+ v = unsafe.Pointer(s.base())
+ }
+
+ if raceenabled {
+ racemalloc(v, uintptr(n))
+ }
+ if msanenabled {
+ msanmalloc(v, uintptr(n))
+ }
+ if asanenabled {
+ asanunpoison(v, uintptr(n))
+ }
+ if stackDebug >= 1 {
+ print(" allocated ", v, "\n")
+ }
+ return stack{uintptr(v), uintptr(v) + uintptr(n)}
+}
+
+// stackfree frees an n byte stack allocation at stk.
+//
+// stackfree must run on the system stack because it uses per-P
+// resources and must not split the stack.
+//
+//go:systemstack
+func stackfree(stk stack) {
+ gp := getg()
+ v := unsafe.Pointer(stk.lo)
+ n := stk.hi - stk.lo
+ if n&(n-1) != 0 {
+ throw("stack not a power of 2")
+ }
+ if stk.lo+n < stk.hi {
+ throw("bad stack size")
+ }
+ if stackDebug >= 1 {
+ println("stackfree", v, n)
+ memclrNoHeapPointers(v, n) // for testing, clobber stack data
+ }
+ if debug.efence != 0 || stackFromSystem != 0 {
+ if debug.efence != 0 || stackFaultOnFree != 0 {
+ sysFault(v, n)
+ } else {
+ sysFree(v, n, &memstats.stacks_sys)
+ }
+ return
+ }
+ if msanenabled {
+ msanfree(v, n)
+ }
+ if asanenabled {
+ asanpoison(v, n)
+ }
+ if n < fixedStack<<_NumStackOrders && n < _StackCacheSize {
+ order := uint8(0)
+ n2 := n
+ for n2 > fixedStack {
+ order++
+ n2 >>= 1
+ }
+ x := gclinkptr(v)
+ if stackNoCache != 0 || gp.m.p == 0 || gp.m.preemptoff != "" {
+ lock(&stackpool[order].item.mu)
+ stackpoolfree(x, order)
+ unlock(&stackpool[order].item.mu)
+ } else {
+ c := gp.m.p.ptr().mcache
+ if c.stackcache[order].size >= _StackCacheSize {
+ stackcacherelease(c, order)
+ }
+ x.ptr().next = c.stackcache[order].list
+ c.stackcache[order].list = x
+ c.stackcache[order].size += n
+ }
+ } else {
+ s := spanOfUnchecked(uintptr(v))
+ if s.state.get() != mSpanManual {
+ println(hex(s.base()), v)
+ throw("bad span state")
+ }
+ if gcphase == _GCoff {
+ // Free the stack immediately if we're
+ // sweeping.
+ osStackFree(s)
+ mheap_.freeManual(s, spanAllocStack)
+ } else {
+ // If the GC is running, we can't return a
+ // stack span to the heap because it could be
+ // reused as a heap span, and this state
+ // change would race with GC. Add it to the
+ // large stack cache instead.
+ log2npage := stacklog2(s.npages)
+ lock(&stackLarge.lock)
+ stackLarge.free[log2npage].insert(s)
+ unlock(&stackLarge.lock)
+ }
+ }
+}
+
+var maxstacksize uintptr = 1 << 20 // enough until runtime.main sets it for real
+
+var maxstackceiling = maxstacksize
+
+var ptrnames = []string{
+ 0: "scalar",
+ 1: "ptr",
+}
+
+// Stack frame layout
+//
+// (x86)
+// +------------------+
+// | args from caller |
+// +------------------+ <- frame->argp
+// | return address |
+// +------------------+
+// | caller's BP (*) | (*) if framepointer_enabled && varp > sp
+// +------------------+ <- frame->varp
+// | locals |
+// +------------------+
+// | args to callee |
+// +------------------+ <- frame->sp
+//
+// (arm)
+// +------------------+
+// | args from caller |
+// +------------------+ <- frame->argp
+// | caller's retaddr |
+// +------------------+
+// | caller's FP (*) | (*) on ARM64, if framepointer_enabled && varp > sp
+// +------------------+ <- frame->varp
+// | locals |
+// +------------------+
+// | args to callee |
+// +------------------+
+// | return address |
+// +------------------+ <- frame->sp
+//
+// varp > sp means that the function has a frame;
+// varp == sp means frameless function.
+
+type adjustinfo struct {
+ old stack
+ delta uintptr // ptr distance from old to new stack (newbase - oldbase)
+ cache pcvalueCache
+
+ // sghi is the highest sudog.elem on the stack.
+ sghi uintptr
+}
+
+// adjustpointer checks whether *vpp is in the old stack described by adjinfo.
+// If so, it rewrites *vpp to point into the new stack.
+func adjustpointer(adjinfo *adjustinfo, vpp unsafe.Pointer) {
+ pp := (*uintptr)(vpp)
+ p := *pp
+ if stackDebug >= 4 {
+ print(" ", pp, ":", hex(p), "\n")
+ }
+ if adjinfo.old.lo <= p && p < adjinfo.old.hi {
+ *pp = p + adjinfo.delta
+ if stackDebug >= 3 {
+ print(" adjust ptr ", pp, ":", hex(p), " -> ", hex(*pp), "\n")
+ }
+ }
+}
+
+// Information from the compiler about the layout of stack frames.
+// Note: this type must agree with reflect.bitVector.
+type bitvector struct {
+ n int32 // # of bits
+ bytedata *uint8
+}
+
+// ptrbit returns the i'th bit in bv.
+// ptrbit is less efficient than iterating directly over bitvector bits,
+// and should only be used in non-performance-critical code.
+// See adjustpointers for an example of a high-efficiency walk of a bitvector.
+func (bv *bitvector) ptrbit(i uintptr) uint8 {
+ b := *(addb(bv.bytedata, i/8))
+ return (b >> (i % 8)) & 1
+}
+
+// bv describes the memory starting at address scanp.
+// Adjust any pointers contained therein.
+func adjustpointers(scanp unsafe.Pointer, bv *bitvector, adjinfo *adjustinfo, f funcInfo) {
+ minp := adjinfo.old.lo
+ maxp := adjinfo.old.hi
+ delta := adjinfo.delta
+ num := uintptr(bv.n)
+ // If this frame might contain channel receive slots, use CAS
+ // to adjust pointers. If the slot hasn't been received into
+ // yet, it may contain stack pointers and a concurrent send
+ // could race with adjusting those pointers. (The sent value
+ // itself can never contain stack pointers.)
+ useCAS := uintptr(scanp) < adjinfo.sghi
+ for i := uintptr(0); i < num; i += 8 {
+ if stackDebug >= 4 {
+ for j := uintptr(0); j < 8; j++ {
+ print(" ", add(scanp, (i+j)*goarch.PtrSize), ":", ptrnames[bv.ptrbit(i+j)], ":", hex(*(*uintptr)(add(scanp, (i+j)*goarch.PtrSize))), " # ", i, " ", *addb(bv.bytedata, i/8), "\n")
+ }
+ }
+ b := *(addb(bv.bytedata, i/8))
+ for b != 0 {
+ j := uintptr(sys.TrailingZeros8(b))
+ b &= b - 1
+ pp := (*uintptr)(add(scanp, (i+j)*goarch.PtrSize))
+ retry:
+ p := *pp
+ if f.valid() && 0 < p && p < minLegalPointer && debug.invalidptr != 0 {
+ // Looks like a junk value in a pointer slot.
+ // Live analysis wrong?
+ getg().m.traceback = 2
+ print("runtime: bad pointer in frame ", funcname(f), " at ", pp, ": ", hex(p), "\n")
+ throw("invalid pointer found on stack")
+ }
+ if minp <= p && p < maxp {
+ if stackDebug >= 3 {
+ print("adjust ptr ", hex(p), " ", funcname(f), "\n")
+ }
+ if useCAS {
+ ppu := (*unsafe.Pointer)(unsafe.Pointer(pp))
+ if !atomic.Casp1(ppu, unsafe.Pointer(p), unsafe.Pointer(p+delta)) {
+ goto retry
+ }
+ } else {
+ *pp = p + delta
+ }
+ }
+ }
+ }
+}
+
+// Note: the argument/return area is adjusted by the callee.
+func adjustframe(frame *stkframe, adjinfo *adjustinfo) {
+ if frame.continpc == 0 {
+ // Frame is dead.
+ return
+ }
+ f := frame.fn
+ if stackDebug >= 2 {
+ print(" adjusting ", funcname(f), " frame=[", hex(frame.sp), ",", hex(frame.fp), "] pc=", hex(frame.pc), " continpc=", hex(frame.continpc), "\n")
+ }
+
+ // Adjust saved frame pointer if there is one.
+ if (goarch.ArchFamily == goarch.AMD64 || goarch.ArchFamily == goarch.ARM64) && frame.argp-frame.varp == 2*goarch.PtrSize {
+ if stackDebug >= 3 {
+ print(" saved bp\n")
+ }
+ if debugCheckBP {
+ // Frame pointers should always point to the next higher frame on
+ // the Go stack (or be nil, for the top frame on the stack).
+ bp := *(*uintptr)(unsafe.Pointer(frame.varp))
+ if bp != 0 && (bp < adjinfo.old.lo || bp >= adjinfo.old.hi) {
+ println("runtime: found invalid frame pointer")
+ print("bp=", hex(bp), " min=", hex(adjinfo.old.lo), " max=", hex(adjinfo.old.hi), "\n")
+ throw("bad frame pointer")
+ }
+ }
+ // On AMD64, this is the caller's frame pointer saved in the current
+ // frame.
+ // On ARM64, this is the frame pointer of the caller's caller saved
+ // by the caller in its frame (one word below its SP).
+ adjustpointer(adjinfo, unsafe.Pointer(frame.varp))
+ }
+
+ locals, args, objs := frame.getStackMap(&adjinfo.cache, true)
+
+ // Adjust local variables if stack frame has been allocated.
+ if locals.n > 0 {
+ size := uintptr(locals.n) * goarch.PtrSize
+ adjustpointers(unsafe.Pointer(frame.varp-size), &locals, adjinfo, f)
+ }
+
+ // Adjust arguments.
+ if args.n > 0 {
+ if stackDebug >= 3 {
+ print(" args\n")
+ }
+ adjustpointers(unsafe.Pointer(frame.argp), &args, adjinfo, funcInfo{})
+ }
+
+ // Adjust pointers in all stack objects (whether they are live or not).
+ // See comments in mgcmark.go:scanframeworker.
+ if frame.varp != 0 {
+ for i := range objs {
+ obj := &objs[i]
+ off := obj.off
+ base := frame.varp // locals base pointer
+ if off >= 0 {
+ base = frame.argp // arguments and return values base pointer
+ }
+ p := base + uintptr(off)
+ if p < frame.sp {
+ // Object hasn't been allocated in the frame yet.
+ // (Happens when the stack bounds check fails and
+ // we call into morestack.)
+ continue
+ }
+ ptrdata := obj.ptrdata()
+ gcdata := obj.gcdata()
+ var s *mspan
+ if obj.useGCProg() {
+ // See comments in mgcmark.go:scanstack
+ s = materializeGCProg(ptrdata, gcdata)
+ gcdata = (*byte)(unsafe.Pointer(s.startAddr))
+ }
+ for i := uintptr(0); i < ptrdata; i += goarch.PtrSize {
+ if *addb(gcdata, i/(8*goarch.PtrSize))>>(i/goarch.PtrSize&7)&1 != 0 {
+ adjustpointer(adjinfo, unsafe.Pointer(p+i))
+ }
+ }
+ if s != nil {
+ dematerializeGCProg(s)
+ }
+ }
+ }
+}
+
+func adjustctxt(gp *g, adjinfo *adjustinfo) {
+ adjustpointer(adjinfo, unsafe.Pointer(&gp.sched.ctxt))
+ if !framepointer_enabled {
+ return
+ }
+ if debugCheckBP {
+ bp := gp.sched.bp
+ if bp != 0 && (bp < adjinfo.old.lo || bp >= adjinfo.old.hi) {
+ println("runtime: found invalid top frame pointer")
+ print("bp=", hex(bp), " min=", hex(adjinfo.old.lo), " max=", hex(adjinfo.old.hi), "\n")
+ throw("bad top frame pointer")
+ }
+ }
+ oldfp := gp.sched.bp
+ adjustpointer(adjinfo, unsafe.Pointer(&gp.sched.bp))
+ if GOARCH == "arm64" {
+ // On ARM64, the frame pointer is saved one word *below* the SP,
+ // which is not copied or adjusted in any frame. Do it explicitly
+ // here.
+ if oldfp == gp.sched.sp-goarch.PtrSize {
+ memmove(unsafe.Pointer(gp.sched.bp), unsafe.Pointer(oldfp), goarch.PtrSize)
+ adjustpointer(adjinfo, unsafe.Pointer(gp.sched.bp))
+ }
+ }
+}
+
+func adjustdefers(gp *g, adjinfo *adjustinfo) {
+ // Adjust pointers in the Defer structs.
+ // We need to do this first because we need to adjust the
+ // defer.link fields so we always work on the new stack.
+ adjustpointer(adjinfo, unsafe.Pointer(&gp._defer))
+ for d := gp._defer; d != nil; d = d.link {
+ adjustpointer(adjinfo, unsafe.Pointer(&d.fn))
+ adjustpointer(adjinfo, unsafe.Pointer(&d.sp))
+ adjustpointer(adjinfo, unsafe.Pointer(&d._panic))
+ adjustpointer(adjinfo, unsafe.Pointer(&d.link))
+ adjustpointer(adjinfo, unsafe.Pointer(&d.varp))
+ adjustpointer(adjinfo, unsafe.Pointer(&d.fd))
+ }
+}
+
+func adjustpanics(gp *g, adjinfo *adjustinfo) {
+ // Panics are on stack and already adjusted.
+ // Update pointer to head of list in G.
+ adjustpointer(adjinfo, unsafe.Pointer(&gp._panic))
+}
+
+func adjustsudogs(gp *g, adjinfo *adjustinfo) {
+ // the data elements pointed to by a SudoG structure
+ // might be in the stack.
+ for s := gp.waiting; s != nil; s = s.waitlink {
+ adjustpointer(adjinfo, unsafe.Pointer(&s.elem))
+ }
+}
+
+func fillstack(stk stack, b byte) {
+ for p := stk.lo; p < stk.hi; p++ {
+ *(*byte)(unsafe.Pointer(p)) = b
+ }
+}
+
+func findsghi(gp *g, stk stack) uintptr {
+ var sghi uintptr
+ for sg := gp.waiting; sg != nil; sg = sg.waitlink {
+ p := uintptr(sg.elem) + uintptr(sg.c.elemsize)
+ if stk.lo <= p && p < stk.hi && p > sghi {
+ sghi = p
+ }
+ }
+ return sghi
+}
+
+// syncadjustsudogs adjusts gp's sudogs and copies the part of gp's
+// stack they refer to while synchronizing with concurrent channel
+// operations. It returns the number of bytes of stack copied.
+func syncadjustsudogs(gp *g, used uintptr, adjinfo *adjustinfo) uintptr {
+ if gp.waiting == nil {
+ return 0
+ }
+
+ // Lock channels to prevent concurrent send/receive.
+ var lastc *hchan
+ for sg := gp.waiting; sg != nil; sg = sg.waitlink {
+ if sg.c != lastc {
+ // There is a ranking cycle here between gscan bit and
+ // hchan locks. Normally, we only allow acquiring hchan
+ // locks and then getting a gscan bit. In this case, we
+ // already have the gscan bit. We allow acquiring hchan
+ // locks here as a special case, since a deadlock can't
+ // happen because the G involved must already be
+ // suspended. So, we get a special hchan lock rank here
+ // that is lower than gscan, but doesn't allow acquiring
+ // any other locks other than hchan.
+ lockWithRank(&sg.c.lock, lockRankHchanLeaf)
+ }
+ lastc = sg.c
+ }
+
+ // Adjust sudogs.
+ adjustsudogs(gp, adjinfo)
+
+ // Copy the part of the stack the sudogs point in to
+ // while holding the lock to prevent races on
+ // send/receive slots.
+ var sgsize uintptr
+ if adjinfo.sghi != 0 {
+ oldBot := adjinfo.old.hi - used
+ newBot := oldBot + adjinfo.delta
+ sgsize = adjinfo.sghi - oldBot
+ memmove(unsafe.Pointer(newBot), unsafe.Pointer(oldBot), sgsize)
+ }
+
+ // Unlock channels.
+ lastc = nil
+ for sg := gp.waiting; sg != nil; sg = sg.waitlink {
+ if sg.c != lastc {
+ unlock(&sg.c.lock)
+ }
+ lastc = sg.c
+ }
+
+ return sgsize
+}
+
+// Copies gp's stack to a new stack of a different size.
+// Caller must have changed gp status to Gcopystack.
+func copystack(gp *g, newsize uintptr) {
+ if gp.syscallsp != 0 {
+ throw("stack growth not allowed in system call")
+ }
+ old := gp.stack
+ if old.lo == 0 {
+ throw("nil stackbase")
+ }
+ used := old.hi - gp.sched.sp
+ // Add just the difference to gcController.addScannableStack.
+ // g0 stacks never move, so this will never account for them.
+ // It's also fine if we have no P, addScannableStack can deal with
+ // that case.
+ gcController.addScannableStack(getg().m.p.ptr(), int64(newsize)-int64(old.hi-old.lo))
+
+ // allocate new stack
+ new := stackalloc(uint32(newsize))
+ if stackPoisonCopy != 0 {
+ fillstack(new, 0xfd)
+ }
+ if stackDebug >= 1 {
+ print("copystack gp=", gp, " [", hex(old.lo), " ", hex(old.hi-used), " ", hex(old.hi), "]", " -> [", hex(new.lo), " ", hex(new.hi-used), " ", hex(new.hi), "]/", newsize, "\n")
+ }
+
+ // Compute adjustment.
+ var adjinfo adjustinfo
+ adjinfo.old = old
+ adjinfo.delta = new.hi - old.hi
+
+ // Adjust sudogs, synchronizing with channel ops if necessary.
+ ncopy := used
+ if !gp.activeStackChans {
+ if newsize < old.hi-old.lo && gp.parkingOnChan.Load() {
+ // It's not safe for someone to shrink this stack while we're actively
+ // parking on a channel, but it is safe to grow since we do that
+ // ourselves and explicitly don't want to synchronize with channels
+ // since we could self-deadlock.
+ throw("racy sudog adjustment due to parking on channel")
+ }
+ adjustsudogs(gp, &adjinfo)
+ } else {
+ // sudogs may be pointing in to the stack and gp has
+ // released channel locks, so other goroutines could
+ // be writing to gp's stack. Find the highest such
+ // pointer so we can handle everything there and below
+ // carefully. (This shouldn't be far from the bottom
+ // of the stack, so there's little cost in handling
+ // everything below it carefully.)
+ adjinfo.sghi = findsghi(gp, old)
+
+ // Synchronize with channel ops and copy the part of
+ // the stack they may interact with.
+ ncopy -= syncadjustsudogs(gp, used, &adjinfo)
+ }
+
+ // Copy the stack (or the rest of it) to the new location
+ memmove(unsafe.Pointer(new.hi-ncopy), unsafe.Pointer(old.hi-ncopy), ncopy)
+
+ // Adjust remaining structures that have pointers into stacks.
+ // We have to do most of these before we traceback the new
+ // stack because gentraceback uses them.
+ adjustctxt(gp, &adjinfo)
+ adjustdefers(gp, &adjinfo)
+ adjustpanics(gp, &adjinfo)
+ if adjinfo.sghi != 0 {
+ adjinfo.sghi += adjinfo.delta
+ }
+
+ // Swap out old stack for new one
+ gp.stack = new
+ gp.stackguard0 = new.lo + stackGuard // NOTE: might clobber a preempt request
+ gp.sched.sp = new.hi - used
+ gp.stktopsp += adjinfo.delta
+
+ // Adjust pointers in the new stack.
+ var u unwinder
+ for u.init(gp, 0); u.valid(); u.next() {
+ adjustframe(&u.frame, &adjinfo)
+ }
+
+ // free old stack
+ if stackPoisonCopy != 0 {
+ fillstack(old, 0xfc)
+ }
+ stackfree(old)
+}
+
+// round x up to a power of 2.
+func round2(x int32) int32 {
+ s := uint(0)
+ for 1<<s < x {
+ s++
+ }
+ return 1 << s
+}
+
+// Called from runtime·morestack when more stack is needed.
+// Allocate larger stack and relocate to new stack.
+// Stack growth is multiplicative, for constant amortized cost.
+//
+// g->atomicstatus will be Grunning or Gscanrunning upon entry.
+// If the scheduler is trying to stop this g, then it will set preemptStop.
+//
+// This must be nowritebarrierrec because it can be called as part of
+// stack growth from other nowritebarrierrec functions, but the
+// compiler doesn't check this.
+//
+//go:nowritebarrierrec
+func newstack() {
+ thisg := getg()
+ // TODO: double check all gp. shouldn't be getg().
+ if thisg.m.morebuf.g.ptr().stackguard0 == stackFork {
+ throw("stack growth after fork")
+ }
+ if thisg.m.morebuf.g.ptr() != thisg.m.curg {
+ print("runtime: newstack called from g=", hex(thisg.m.morebuf.g), "\n"+"\tm=", thisg.m, " m->curg=", thisg.m.curg, " m->g0=", thisg.m.g0, " m->gsignal=", thisg.m.gsignal, "\n")
+ morebuf := thisg.m.morebuf
+ traceback(morebuf.pc, morebuf.sp, morebuf.lr, morebuf.g.ptr())
+ throw("runtime: wrong goroutine in newstack")
+ }
+
+ gp := thisg.m.curg
+
+ if thisg.m.curg.throwsplit {
+ // Update syscallsp, syscallpc in case traceback uses them.
+ morebuf := thisg.m.morebuf
+ gp.syscallsp = morebuf.sp
+ gp.syscallpc = morebuf.pc
+ pcname, pcoff := "(unknown)", uintptr(0)
+ f := findfunc(gp.sched.pc)
+ if f.valid() {
+ pcname = funcname(f)
+ pcoff = gp.sched.pc - f.entry()
+ }
+ print("runtime: newstack at ", pcname, "+", hex(pcoff),
+ " sp=", hex(gp.sched.sp), " stack=[", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n",
+ "\tmorebuf={pc:", hex(morebuf.pc), " sp:", hex(morebuf.sp), " lr:", hex(morebuf.lr), "}\n",
+ "\tsched={pc:", hex(gp.sched.pc), " sp:", hex(gp.sched.sp), " lr:", hex(gp.sched.lr), " ctxt:", gp.sched.ctxt, "}\n")
+
+ thisg.m.traceback = 2 // Include runtime frames
+ traceback(morebuf.pc, morebuf.sp, morebuf.lr, gp)
+ throw("runtime: stack split at bad time")
+ }
+
+ morebuf := thisg.m.morebuf
+ thisg.m.morebuf.pc = 0
+ thisg.m.morebuf.lr = 0
+ thisg.m.morebuf.sp = 0
+ thisg.m.morebuf.g = 0
+
+ // NOTE: stackguard0 may change underfoot, if another thread
+ // is about to try to preempt gp. Read it just once and use that same
+ // value now and below.
+ stackguard0 := atomic.Loaduintptr(&gp.stackguard0)
+
+ // Be conservative about where we preempt.
+ // We are interested in preempting user Go code, not runtime code.
+ // If we're holding locks, mallocing, or preemption is disabled, don't
+ // preempt.
+ // This check is very early in newstack so that even the status change
+ // from Grunning to Gwaiting and back doesn't happen in this case.
+ // That status change by itself can be viewed as a small preemption,
+ // because the GC might change Gwaiting to Gscanwaiting, and then
+ // this goroutine has to wait for the GC to finish before continuing.
+ // If the GC is in some way dependent on this goroutine (for example,
+ // it needs a lock held by the goroutine), that small preemption turns
+ // into a real deadlock.
+ preempt := stackguard0 == stackPreempt
+ if preempt {
+ if !canPreemptM(thisg.m) {
+ // Let the goroutine keep running for now.
+ // gp->preempt is set, so it will be preempted next time.
+ gp.stackguard0 = gp.stack.lo + stackGuard
+ gogo(&gp.sched) // never return
+ }
+ }
+
+ if gp.stack.lo == 0 {
+ throw("missing stack in newstack")
+ }
+ sp := gp.sched.sp
+ if goarch.ArchFamily == goarch.AMD64 || goarch.ArchFamily == goarch.I386 || goarch.ArchFamily == goarch.WASM {
+ // The call to morestack cost a word.
+ sp -= goarch.PtrSize
+ }
+ if stackDebug >= 1 || sp < gp.stack.lo {
+ print("runtime: newstack sp=", hex(sp), " stack=[", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n",
+ "\tmorebuf={pc:", hex(morebuf.pc), " sp:", hex(morebuf.sp), " lr:", hex(morebuf.lr), "}\n",
+ "\tsched={pc:", hex(gp.sched.pc), " sp:", hex(gp.sched.sp), " lr:", hex(gp.sched.lr), " ctxt:", gp.sched.ctxt, "}\n")
+ }
+ if sp < gp.stack.lo {
+ print("runtime: gp=", gp, ", goid=", gp.goid, ", gp->status=", hex(readgstatus(gp)), "\n ")
+ print("runtime: split stack overflow: ", hex(sp), " < ", hex(gp.stack.lo), "\n")
+ throw("runtime: split stack overflow")
+ }
+
+ if preempt {
+ if gp == thisg.m.g0 {
+ throw("runtime: preempt g0")
+ }
+ if thisg.m.p == 0 && thisg.m.locks == 0 {
+ throw("runtime: g is running but p is not")
+ }
+
+ if gp.preemptShrink {
+ // We're at a synchronous safe point now, so
+ // do the pending stack shrink.
+ gp.preemptShrink = false
+ shrinkstack(gp)
+ }
+
+ if gp.preemptStop {
+ preemptPark(gp) // never returns
+ }
+
+ // Act like goroutine called runtime.Gosched.
+ gopreempt_m(gp) // never return
+ }
+
+ // Allocate a bigger segment and move the stack.
+ oldsize := gp.stack.hi - gp.stack.lo
+ newsize := oldsize * 2
+
+ // Make sure we grow at least as much as needed to fit the new frame.
+ // (This is just an optimization - the caller of morestack will
+ // recheck the bounds on return.)
+ if f := findfunc(gp.sched.pc); f.valid() {
+ max := uintptr(funcMaxSPDelta(f))
+ needed := max + stackGuard
+ used := gp.stack.hi - gp.sched.sp
+ for newsize-used < needed {
+ newsize *= 2
+ }
+ }
+
+ if stackguard0 == stackForceMove {
+ // Forced stack movement used for debugging.
+ // Don't double the stack (or we may quickly run out
+ // if this is done repeatedly).
+ newsize = oldsize
+ }
+
+ if newsize > maxstacksize || newsize > maxstackceiling {
+ if maxstacksize < maxstackceiling {
+ print("runtime: goroutine stack exceeds ", maxstacksize, "-byte limit\n")
+ } else {
+ print("runtime: goroutine stack exceeds ", maxstackceiling, "-byte limit\n")
+ }
+ print("runtime: sp=", hex(sp), " stack=[", hex(gp.stack.lo), ", ", hex(gp.stack.hi), "]\n")
+ throw("stack overflow")
+ }
+
+ // The goroutine must be executing in order to call newstack,
+ // so it must be Grunning (or Gscanrunning).
+ casgstatus(gp, _Grunning, _Gcopystack)
+
+ // The concurrent GC will not scan the stack while we are doing the copy since
+ // the gp is in a Gcopystack status.
+ copystack(gp, newsize)
+ if stackDebug >= 1 {
+ print("stack grow done\n")
+ }
+ casgstatus(gp, _Gcopystack, _Grunning)
+ gogo(&gp.sched)
+}
+
+//go:nosplit
+func nilfunc() {
+ *(*uint8)(nil) = 0
+}
+
+// adjust Gobuf as if it executed a call to fn
+// and then stopped before the first instruction in fn.
+func gostartcallfn(gobuf *gobuf, fv *funcval) {
+ var fn unsafe.Pointer
+ if fv != nil {
+ fn = unsafe.Pointer(fv.fn)
+ } else {
+ fn = unsafe.Pointer(abi.FuncPCABIInternal(nilfunc))
+ }
+ gostartcall(gobuf, fn, unsafe.Pointer(fv))
+}
+
+// isShrinkStackSafe returns whether it's safe to attempt to shrink
+// gp's stack. Shrinking the stack is only safe when we have precise
+// pointer maps for all frames on the stack.
+func isShrinkStackSafe(gp *g) bool {
+ // We can't copy the stack if we're in a syscall.
+ // The syscall might have pointers into the stack and
+ // often we don't have precise pointer maps for the innermost
+ // frames.
+ //
+ // We also can't copy the stack if we're at an asynchronous
+ // safe-point because we don't have precise pointer maps for
+ // all frames.
+ //
+ // We also can't *shrink* the stack in the window between the
+ // goroutine calling gopark to park on a channel and
+ // gp.activeStackChans being set.
+ return gp.syscallsp == 0 && !gp.asyncSafePoint && !gp.parkingOnChan.Load()
+}
+
+// Maybe shrink the stack being used by gp.
+//
+// gp must be stopped and we must own its stack. It may be in
+// _Grunning, but only if this is our own user G.
+func shrinkstack(gp *g) {
+ if gp.stack.lo == 0 {
+ throw("missing stack in shrinkstack")
+ }
+ if s := readgstatus(gp); s&_Gscan == 0 {
+ // We don't own the stack via _Gscan. We could still
+ // own it if this is our own user G and we're on the
+ // system stack.
+ if !(gp == getg().m.curg && getg() != getg().m.curg && s == _Grunning) {
+ // We don't own the stack.
+ throw("bad status in shrinkstack")
+ }
+ }
+ if !isShrinkStackSafe(gp) {
+ throw("shrinkstack at bad time")
+ }
+ // Check for self-shrinks while in a libcall. These may have
+ // pointers into the stack disguised as uintptrs, but these
+ // code paths should all be nosplit.
+ if gp == getg().m.curg && gp.m.libcallsp != 0 {
+ throw("shrinking stack in libcall")
+ }
+
+ if debug.gcshrinkstackoff > 0 {
+ return
+ }
+ f := findfunc(gp.startpc)
+ if f.valid() && f.funcID == abi.FuncID_gcBgMarkWorker {
+ // We're not allowed to shrink the gcBgMarkWorker
+ // stack (see gcBgMarkWorker for explanation).
+ return
+ }
+
+ oldsize := gp.stack.hi - gp.stack.lo
+ newsize := oldsize / 2
+ // Don't shrink the allocation below the minimum-sized stack
+ // allocation.
+ if newsize < fixedStack {
+ return
+ }
+ // Compute how much of the stack is currently in use and only
+ // shrink the stack if gp is using less than a quarter of its
+ // current stack. The currently used stack includes everything
+ // down to the SP plus the stack guard space that ensures
+ // there's room for nosplit functions.
+ avail := gp.stack.hi - gp.stack.lo
+ if used := gp.stack.hi - gp.sched.sp + stackNosplit; used >= avail/4 {
+ return
+ }
+
+ if stackDebug > 0 {
+ print("shrinking stack ", oldsize, "->", newsize, "\n")
+ }
+
+ copystack(gp, newsize)
+}
+
+// freeStackSpans frees unused stack spans at the end of GC.
+func freeStackSpans() {
+ // Scan stack pools for empty stack spans.
+ for order := range stackpool {
+ lock(&stackpool[order].item.mu)
+ list := &stackpool[order].item.span
+ for s := list.first; s != nil; {
+ next := s.next
+ if s.allocCount == 0 {
+ list.remove(s)
+ s.manualFreeList = 0
+ osStackFree(s)
+ mheap_.freeManual(s, spanAllocStack)
+ }
+ s = next
+ }
+ unlock(&stackpool[order].item.mu)
+ }
+
+ // Free large stack spans.
+ lock(&stackLarge.lock)
+ for i := range stackLarge.free {
+ for s := stackLarge.free[i].first; s != nil; {
+ next := s.next
+ stackLarge.free[i].remove(s)
+ osStackFree(s)
+ mheap_.freeManual(s, spanAllocStack)
+ s = next
+ }
+ }
+ unlock(&stackLarge.lock)
+}
+
+// A stackObjectRecord is generated by the compiler for each stack object in a stack frame.
+// This record must match the generator code in cmd/compile/internal/liveness/plive.go:emitStackObjects.
+type stackObjectRecord struct {
+ // offset in frame
+ // if negative, offset from varp
+ // if non-negative, offset from argp
+ off int32
+ size int32
+ _ptrdata int32 // ptrdata, or -ptrdata is GC prog is used
+ gcdataoff uint32 // offset to gcdata from moduledata.rodata
+}
+
+func (r *stackObjectRecord) useGCProg() bool {
+ return r._ptrdata < 0
+}
+
+func (r *stackObjectRecord) ptrdata() uintptr {
+ x := r._ptrdata
+ if x < 0 {
+ return uintptr(-x)
+ }
+ return uintptr(x)
+}
+
+// gcdata returns pointer map or GC prog of the type.
+func (r *stackObjectRecord) gcdata() *byte {
+ ptr := uintptr(unsafe.Pointer(r))
+ var mod *moduledata
+ for datap := &firstmoduledata; datap != nil; datap = datap.next {
+ if datap.gofunc <= ptr && ptr < datap.end {
+ mod = datap
+ break
+ }
+ }
+ // If you get a panic here due to a nil mod,
+ // you may have made a copy of a stackObjectRecord.
+ // You must use the original pointer.
+ res := mod.rodata + uintptr(r.gcdataoff)
+ return (*byte)(unsafe.Pointer(res))
+}
+
+// This is exported as ABI0 via linkname so obj can call it.
+//
+//go:nosplit
+//go:linkname morestackc
+func morestackc() {
+ throw("attempt to execute system stack code on user stack")
+}
+
+// startingStackSize is the amount of stack that new goroutines start with.
+// It is a power of 2, and between _FixedStack and maxstacksize, inclusive.
+// startingStackSize is updated every GC by tracking the average size of
+// stacks scanned during the GC.
+var startingStackSize uint32 = fixedStack
+
+func gcComputeStartingStackSize() {
+ if debug.adaptivestackstart == 0 {
+ return
+ }
+ // For details, see the design doc at
+ // https://docs.google.com/document/d/1YDlGIdVTPnmUiTAavlZxBI1d9pwGQgZT7IKFKlIXohQ/edit?usp=sharing
+ // The basic algorithm is to track the average size of stacks
+ // and start goroutines with stack equal to that average size.
+ // Starting at the average size uses at most 2x the space that
+ // an ideal algorithm would have used.
+ // This is just a heuristic to avoid excessive stack growth work
+ // early in a goroutine's lifetime. See issue 18138. Stacks that
+ // are allocated too small can still grow, and stacks allocated
+ // too large can still shrink.
+ var scannedStackSize uint64
+ var scannedStacks uint64
+ for _, p := range allp {
+ scannedStackSize += p.scannedStackSize
+ scannedStacks += p.scannedStacks
+ // Reset for next time
+ p.scannedStackSize = 0
+ p.scannedStacks = 0
+ }
+ if scannedStacks == 0 {
+ startingStackSize = fixedStack
+ return
+ }
+ avg := scannedStackSize/scannedStacks + stackGuard
+ // Note: we add stackGuard to ensure that a goroutine that
+ // uses the average space will not trigger a growth.
+ if avg > uint64(maxstacksize) {
+ avg = uint64(maxstacksize)
+ }
+ if avg < fixedStack {
+ avg = fixedStack
+ }
+ // Note: maxstacksize fits in 30 bits, so avg also does.
+ startingStackSize = uint32(round2(int32(avg)))
+}
diff --git a/contrib/go/_std_1.21/src/runtime/stkframe.go b/contrib/go/_std_1.21/src/runtime/stkframe.go
new file mode 100644
index 0000000000..5caacbacba
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/stkframe.go
@@ -0,0 +1,289 @@
+// Copyright 2022 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// A stkframe holds information about a single physical stack frame.
+type stkframe struct {
+ // fn is the function being run in this frame. If there is
+ // inlining, this is the outermost function.
+ fn funcInfo
+
+ // pc is the program counter within fn.
+ //
+ // The meaning of this is subtle:
+ //
+ // - Typically, this frame performed a regular function call
+ // and this is the return PC (just after the CALL
+ // instruction). In this case, pc-1 reflects the CALL
+ // instruction itself and is the correct source of symbolic
+ // information.
+ //
+ // - If this frame "called" sigpanic, then pc is the
+ // instruction that panicked, and pc is the correct address
+ // to use for symbolic information.
+ //
+ // - If this is the innermost frame, then PC is where
+ // execution will continue, but it may not be the
+ // instruction following a CALL. This may be from
+ // cooperative preemption, in which case this is the
+ // instruction after the call to morestack. Or this may be
+ // from a signal or an un-started goroutine, in which case
+ // PC could be any instruction, including the first
+ // instruction in a function. Conventionally, we use pc-1
+ // for symbolic information, unless pc == fn.entry(), in
+ // which case we use pc.
+ pc uintptr
+
+ // continpc is the PC where execution will continue in fn, or
+ // 0 if execution will not continue in this frame.
+ //
+ // This is usually the same as pc, unless this frame "called"
+ // sigpanic, in which case it's either the address of
+ // deferreturn or 0 if this frame will never execute again.
+ //
+ // This is the PC to use to look up GC liveness for this frame.
+ continpc uintptr
+
+ lr uintptr // program counter at caller aka link register
+ sp uintptr // stack pointer at pc
+ fp uintptr // stack pointer at caller aka frame pointer
+ varp uintptr // top of local variables
+ argp uintptr // pointer to function arguments
+}
+
+// reflectMethodValue is a partial duplicate of reflect.makeFuncImpl
+// and reflect.methodValue.
+type reflectMethodValue struct {
+ fn uintptr
+ stack *bitvector // ptrmap for both args and results
+ argLen uintptr // just args
+}
+
+// argBytes returns the argument frame size for a call to frame.fn.
+func (frame *stkframe) argBytes() uintptr {
+ if frame.fn.args != abi.ArgsSizeUnknown {
+ return uintptr(frame.fn.args)
+ }
+ // This is an uncommon and complicated case. Fall back to fully
+ // fetching the argument map to compute its size.
+ argMap, _ := frame.argMapInternal()
+ return uintptr(argMap.n) * goarch.PtrSize
+}
+
+// argMapInternal is used internally by stkframe to fetch special
+// argument maps.
+//
+// argMap.n is always populated with the size of the argument map.
+//
+// argMap.bytedata is only populated for dynamic argument maps (used
+// by reflect). If the caller requires the argument map, it should use
+// this if non-nil, and otherwise fetch the argument map using the
+// current PC.
+//
+// hasReflectStackObj indicates that this frame also has a reflect
+// function stack object, which the caller must synthesize.
+func (frame *stkframe) argMapInternal() (argMap bitvector, hasReflectStackObj bool) {
+ f := frame.fn
+ if f.args != abi.ArgsSizeUnknown {
+ argMap.n = f.args / goarch.PtrSize
+ return
+ }
+ // Extract argument bitmaps for reflect stubs from the calls they made to reflect.
+ switch funcname(f) {
+ case "reflect.makeFuncStub", "reflect.methodValueCall":
+ // These take a *reflect.methodValue as their
+ // context register and immediately save it to 0(SP).
+ // Get the methodValue from 0(SP).
+ arg0 := frame.sp + sys.MinFrameSize
+
+ minSP := frame.fp
+ if !usesLR {
+ // The CALL itself pushes a word.
+ // Undo that adjustment.
+ minSP -= goarch.PtrSize
+ }
+ if arg0 >= minSP {
+ // The function hasn't started yet.
+ // This only happens if f was the
+ // start function of a new goroutine
+ // that hasn't run yet *and* f takes
+ // no arguments and has no results
+ // (otherwise it will get wrapped in a
+ // closure). In this case, we can't
+ // reach into its locals because it
+ // doesn't have locals yet, but we
+ // also know its argument map is
+ // empty.
+ if frame.pc != f.entry() {
+ print("runtime: confused by ", funcname(f), ": no frame (sp=", hex(frame.sp), " fp=", hex(frame.fp), ") at entry+", hex(frame.pc-f.entry()), "\n")
+ throw("reflect mismatch")
+ }
+ return bitvector{}, false // No locals, so also no stack objects
+ }
+ hasReflectStackObj = true
+ mv := *(**reflectMethodValue)(unsafe.Pointer(arg0))
+ // Figure out whether the return values are valid.
+ // Reflect will update this value after it copies
+ // in the return values.
+ retValid := *(*bool)(unsafe.Pointer(arg0 + 4*goarch.PtrSize))
+ if mv.fn != f.entry() {
+ print("runtime: confused by ", funcname(f), "\n")
+ throw("reflect mismatch")
+ }
+ argMap = *mv.stack
+ if !retValid {
+ // argMap.n includes the results, but
+ // those aren't valid, so drop them.
+ n := int32((uintptr(mv.argLen) &^ (goarch.PtrSize - 1)) / goarch.PtrSize)
+ if n < argMap.n {
+ argMap.n = n
+ }
+ }
+ }
+ return
+}
+
+// getStackMap returns the locals and arguments live pointer maps, and
+// stack object list for frame.
+func (frame *stkframe) getStackMap(cache *pcvalueCache, debug bool) (locals, args bitvector, objs []stackObjectRecord) {
+ targetpc := frame.continpc
+ if targetpc == 0 {
+ // Frame is dead. Return empty bitvectors.
+ return
+ }
+
+ f := frame.fn
+ pcdata := int32(-1)
+ if targetpc != f.entry() {
+ // Back up to the CALL. If we're at the function entry
+ // point, we want to use the entry map (-1), even if
+ // the first instruction of the function changes the
+ // stack map.
+ targetpc--
+ pcdata = pcdatavalue(f, abi.PCDATA_StackMapIndex, targetpc, cache)
+ }
+ if pcdata == -1 {
+ // We do not have a valid pcdata value but there might be a
+ // stackmap for this function. It is likely that we are looking
+ // at the function prologue, assume so and hope for the best.
+ pcdata = 0
+ }
+
+ // Local variables.
+ size := frame.varp - frame.sp
+ var minsize uintptr
+ switch goarch.ArchFamily {
+ case goarch.ARM64:
+ minsize = sys.StackAlign
+ default:
+ minsize = sys.MinFrameSize
+ }
+ if size > minsize {
+ stackid := pcdata
+ stkmap := (*stackmap)(funcdata(f, abi.FUNCDATA_LocalsPointerMaps))
+ if stkmap == nil || stkmap.n <= 0 {
+ print("runtime: frame ", funcname(f), " untyped locals ", hex(frame.varp-size), "+", hex(size), "\n")
+ throw("missing stackmap")
+ }
+ // If nbit == 0, there's no work to do.
+ if stkmap.nbit > 0 {
+ if stackid < 0 || stackid >= stkmap.n {
+ // don't know where we are
+ print("runtime: pcdata is ", stackid, " and ", stkmap.n, " locals stack map entries for ", funcname(f), " (targetpc=", hex(targetpc), ")\n")
+ throw("bad symbol table")
+ }
+ locals = stackmapdata(stkmap, stackid)
+ if stackDebug >= 3 && debug {
+ print(" locals ", stackid, "/", stkmap.n, " ", locals.n, " words ", locals.bytedata, "\n")
+ }
+ } else if stackDebug >= 3 && debug {
+ print(" no locals to adjust\n")
+ }
+ }
+
+ // Arguments. First fetch frame size and special-case argument maps.
+ var isReflect bool
+ args, isReflect = frame.argMapInternal()
+ if args.n > 0 && args.bytedata == nil {
+ // Non-empty argument frame, but not a special map.
+ // Fetch the argument map at pcdata.
+ stackmap := (*stackmap)(funcdata(f, abi.FUNCDATA_ArgsPointerMaps))
+ if stackmap == nil || stackmap.n <= 0 {
+ print("runtime: frame ", funcname(f), " untyped args ", hex(frame.argp), "+", hex(args.n*goarch.PtrSize), "\n")
+ throw("missing stackmap")
+ }
+ if pcdata < 0 || pcdata >= stackmap.n {
+ // don't know where we are
+ print("runtime: pcdata is ", pcdata, " and ", stackmap.n, " args stack map entries for ", funcname(f), " (targetpc=", hex(targetpc), ")\n")
+ throw("bad symbol table")
+ }
+ if stackmap.nbit == 0 {
+ args.n = 0
+ } else {
+ args = stackmapdata(stackmap, pcdata)
+ }
+ }
+
+ // stack objects.
+ if (GOARCH == "amd64" || GOARCH == "arm64" || GOARCH == "ppc64" || GOARCH == "ppc64le" || GOARCH == "riscv64") &&
+ unsafe.Sizeof(abi.RegArgs{}) > 0 && isReflect {
+ // For reflect.makeFuncStub and reflect.methodValueCall,
+ // we need to fake the stack object record.
+ // These frames contain an internal/abi.RegArgs at a hard-coded offset.
+ // This offset matches the assembly code on amd64 and arm64.
+ objs = methodValueCallFrameObjs[:]
+ } else {
+ p := funcdata(f, abi.FUNCDATA_StackObjects)
+ if p != nil {
+ n := *(*uintptr)(p)
+ p = add(p, goarch.PtrSize)
+ r0 := (*stackObjectRecord)(noescape(p))
+ objs = unsafe.Slice(r0, int(n))
+ // Note: the noescape above is needed to keep
+ // getStackMap from "leaking param content:
+ // frame". That leak propagates up to getgcmask, then
+ // GCMask, then verifyGCInfo, which converts the stack
+ // gcinfo tests into heap gcinfo tests :(
+ }
+ }
+
+ return
+}
+
+var methodValueCallFrameObjs [1]stackObjectRecord // initialized in stackobjectinit
+
+func stkobjinit() {
+ var abiRegArgsEface any = abi.RegArgs{}
+ abiRegArgsType := efaceOf(&abiRegArgsEface)._type
+ if abiRegArgsType.Kind_&kindGCProg != 0 {
+ throw("abiRegArgsType needs GC Prog, update methodValueCallFrameObjs")
+ }
+ // Set methodValueCallFrameObjs[0].gcdataoff so that
+ // stackObjectRecord.gcdata() will work correctly with it.
+ ptr := uintptr(unsafe.Pointer(&methodValueCallFrameObjs[0]))
+ var mod *moduledata
+ for datap := &firstmoduledata; datap != nil; datap = datap.next {
+ if datap.gofunc <= ptr && ptr < datap.end {
+ mod = datap
+ break
+ }
+ }
+ if mod == nil {
+ throw("methodValueCallFrameObjs is not in a module")
+ }
+ methodValueCallFrameObjs[0] = stackObjectRecord{
+ off: -int32(alignUp(abiRegArgsType.Size_, 8)), // It's always the highest address local.
+ size: int32(abiRegArgsType.Size_),
+ _ptrdata: int32(abiRegArgsType.PtrBytes),
+ gcdataoff: uint32(uintptr(unsafe.Pointer(abiRegArgsType.GCData)) - mod.rodata),
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/string.go b/contrib/go/_std_1.21/src/runtime/string.go
new file mode 100644
index 0000000000..7ac3e66a3a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/string.go
@@ -0,0 +1,588 @@
+// Copyright 2014 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 runtime
+
+import (
+ "internal/abi"
+ "internal/bytealg"
+ "internal/goarch"
+ "unsafe"
+)
+
+// The constant is known to the compiler.
+// There is no fundamental theory behind this number.
+const tmpStringBufSize = 32
+
+type tmpBuf [tmpStringBufSize]byte
+
+// concatstrings implements a Go string concatenation x+y+z+...
+// The operands are passed in the slice a.
+// If buf != nil, the compiler has determined that the result does not
+// escape the calling function, so the string data can be stored in buf
+// if small enough.
+func concatstrings(buf *tmpBuf, a []string) string {
+ idx := 0
+ l := 0
+ count := 0
+ for i, x := range a {
+ n := len(x)
+ if n == 0 {
+ continue
+ }
+ if l+n < l {
+ throw("string concatenation too long")
+ }
+ l += n
+ count++
+ idx = i
+ }
+ if count == 0 {
+ return ""
+ }
+
+ // If there is just one string and either it is not on the stack
+ // or our result does not escape the calling frame (buf != nil),
+ // then we can return that string directly.
+ if count == 1 && (buf != nil || !stringDataOnStack(a[idx])) {
+ return a[idx]
+ }
+ s, b := rawstringtmp(buf, l)
+ for _, x := range a {
+ copy(b, x)
+ b = b[len(x):]
+ }
+ return s
+}
+
+func concatstring2(buf *tmpBuf, a0, a1 string) string {
+ return concatstrings(buf, []string{a0, a1})
+}
+
+func concatstring3(buf *tmpBuf, a0, a1, a2 string) string {
+ return concatstrings(buf, []string{a0, a1, a2})
+}
+
+func concatstring4(buf *tmpBuf, a0, a1, a2, a3 string) string {
+ return concatstrings(buf, []string{a0, a1, a2, a3})
+}
+
+func concatstring5(buf *tmpBuf, a0, a1, a2, a3, a4 string) string {
+ return concatstrings(buf, []string{a0, a1, a2, a3, a4})
+}
+
+// slicebytetostring converts a byte slice to a string.
+// It is inserted by the compiler into generated code.
+// ptr is a pointer to the first element of the slice;
+// n is the length of the slice.
+// Buf is a fixed-size buffer for the result,
+// it is not nil if the result does not escape.
+func slicebytetostring(buf *tmpBuf, ptr *byte, n int) string {
+ if n == 0 {
+ // Turns out to be a relatively common case.
+ // Consider that you want to parse out data between parens in "foo()bar",
+ // you find the indices and convert the subslice to string.
+ return ""
+ }
+ if raceenabled {
+ racereadrangepc(unsafe.Pointer(ptr),
+ uintptr(n),
+ getcallerpc(),
+ abi.FuncPCABIInternal(slicebytetostring))
+ }
+ if msanenabled {
+ msanread(unsafe.Pointer(ptr), uintptr(n))
+ }
+ if asanenabled {
+ asanread(unsafe.Pointer(ptr), uintptr(n))
+ }
+ if n == 1 {
+ p := unsafe.Pointer(&staticuint64s[*ptr])
+ if goarch.BigEndian {
+ p = add(p, 7)
+ }
+ return unsafe.String((*byte)(p), 1)
+ }
+
+ var p unsafe.Pointer
+ if buf != nil && n <= len(buf) {
+ p = unsafe.Pointer(buf)
+ } else {
+ p = mallocgc(uintptr(n), nil, false)
+ }
+ memmove(p, unsafe.Pointer(ptr), uintptr(n))
+ return unsafe.String((*byte)(p), n)
+}
+
+// stringDataOnStack reports whether the string's data is
+// stored on the current goroutine's stack.
+func stringDataOnStack(s string) bool {
+ ptr := uintptr(unsafe.Pointer(unsafe.StringData(s)))
+ stk := getg().stack
+ return stk.lo <= ptr && ptr < stk.hi
+}
+
+func rawstringtmp(buf *tmpBuf, l int) (s string, b []byte) {
+ if buf != nil && l <= len(buf) {
+ b = buf[:l]
+ s = slicebytetostringtmp(&b[0], len(b))
+ } else {
+ s, b = rawstring(l)
+ }
+ return
+}
+
+// slicebytetostringtmp returns a "string" referring to the actual []byte bytes.
+//
+// Callers need to ensure that the returned string will not be used after
+// the calling goroutine modifies the original slice or synchronizes with
+// another goroutine.
+//
+// The function is only called when instrumenting
+// and otherwise intrinsified by the compiler.
+//
+// Some internal compiler optimizations use this function.
+// - Used for m[T1{... Tn{..., string(k), ...} ...}] and m[string(k)]
+// where k is []byte, T1 to Tn is a nesting of struct and array literals.
+// - Used for "<"+string(b)+">" concatenation where b is []byte.
+// - Used for string(b)=="foo" comparison where b is []byte.
+func slicebytetostringtmp(ptr *byte, n int) string {
+ if raceenabled && n > 0 {
+ racereadrangepc(unsafe.Pointer(ptr),
+ uintptr(n),
+ getcallerpc(),
+ abi.FuncPCABIInternal(slicebytetostringtmp))
+ }
+ if msanenabled && n > 0 {
+ msanread(unsafe.Pointer(ptr), uintptr(n))
+ }
+ if asanenabled && n > 0 {
+ asanread(unsafe.Pointer(ptr), uintptr(n))
+ }
+ return unsafe.String(ptr, n)
+}
+
+func stringtoslicebyte(buf *tmpBuf, s string) []byte {
+ var b []byte
+ if buf != nil && len(s) <= len(buf) {
+ *buf = tmpBuf{}
+ b = buf[:len(s)]
+ } else {
+ b = rawbyteslice(len(s))
+ }
+ copy(b, s)
+ return b
+}
+
+func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune {
+ // two passes.
+ // unlike slicerunetostring, no race because strings are immutable.
+ n := 0
+ for range s {
+ n++
+ }
+
+ var a []rune
+ if buf != nil && n <= len(buf) {
+ *buf = [tmpStringBufSize]rune{}
+ a = buf[:n]
+ } else {
+ a = rawruneslice(n)
+ }
+
+ n = 0
+ for _, r := range s {
+ a[n] = r
+ n++
+ }
+ return a
+}
+
+func slicerunetostring(buf *tmpBuf, a []rune) string {
+ if raceenabled && len(a) > 0 {
+ racereadrangepc(unsafe.Pointer(&a[0]),
+ uintptr(len(a))*unsafe.Sizeof(a[0]),
+ getcallerpc(),
+ abi.FuncPCABIInternal(slicerunetostring))
+ }
+ if msanenabled && len(a) > 0 {
+ msanread(unsafe.Pointer(&a[0]), uintptr(len(a))*unsafe.Sizeof(a[0]))
+ }
+ if asanenabled && len(a) > 0 {
+ asanread(unsafe.Pointer(&a[0]), uintptr(len(a))*unsafe.Sizeof(a[0]))
+ }
+ var dum [4]byte
+ size1 := 0
+ for _, r := range a {
+ size1 += encoderune(dum[:], r)
+ }
+ s, b := rawstringtmp(buf, size1+3)
+ size2 := 0
+ for _, r := range a {
+ // check for race
+ if size2 >= size1 {
+ break
+ }
+ size2 += encoderune(b[size2:], r)
+ }
+ return s[:size2]
+}
+
+type stringStruct struct {
+ str unsafe.Pointer
+ len int
+}
+
+// Variant with *byte pointer type for DWARF debugging.
+type stringStructDWARF struct {
+ str *byte
+ len int
+}
+
+func stringStructOf(sp *string) *stringStruct {
+ return (*stringStruct)(unsafe.Pointer(sp))
+}
+
+func intstring(buf *[4]byte, v int64) (s string) {
+ var b []byte
+ if buf != nil {
+ b = buf[:]
+ s = slicebytetostringtmp(&b[0], len(b))
+ } else {
+ s, b = rawstring(4)
+ }
+ if int64(rune(v)) != v {
+ v = runeError
+ }
+ n := encoderune(b, rune(v))
+ return s[:n]
+}
+
+// rawstring allocates storage for a new string. The returned
+// string and byte slice both refer to the same storage.
+// The storage is not zeroed. Callers should use
+// b to set the string contents and then drop b.
+func rawstring(size int) (s string, b []byte) {
+ p := mallocgc(uintptr(size), nil, false)
+ return unsafe.String((*byte)(p), size), unsafe.Slice((*byte)(p), size)
+}
+
+// rawbyteslice allocates a new byte slice. The byte slice is not zeroed.
+func rawbyteslice(size int) (b []byte) {
+ cap := roundupsize(uintptr(size))
+ p := mallocgc(cap, nil, false)
+ if cap != uintptr(size) {
+ memclrNoHeapPointers(add(p, uintptr(size)), cap-uintptr(size))
+ }
+
+ *(*slice)(unsafe.Pointer(&b)) = slice{p, size, int(cap)}
+ return
+}
+
+// rawruneslice allocates a new rune slice. The rune slice is not zeroed.
+func rawruneslice(size int) (b []rune) {
+ if uintptr(size) > maxAlloc/4 {
+ throw("out of memory")
+ }
+ mem := roundupsize(uintptr(size) * 4)
+ p := mallocgc(mem, nil, false)
+ if mem != uintptr(size)*4 {
+ memclrNoHeapPointers(add(p, uintptr(size)*4), mem-uintptr(size)*4)
+ }
+
+ *(*slice)(unsafe.Pointer(&b)) = slice{p, size, int(mem / 4)}
+ return
+}
+
+// used by cmd/cgo
+func gobytes(p *byte, n int) (b []byte) {
+ if n == 0 {
+ return make([]byte, 0)
+ }
+
+ if n < 0 || uintptr(n) > maxAlloc {
+ panic(errorString("gobytes: length out of range"))
+ }
+
+ bp := mallocgc(uintptr(n), nil, false)
+ memmove(bp, unsafe.Pointer(p), uintptr(n))
+
+ *(*slice)(unsafe.Pointer(&b)) = slice{bp, n, n}
+ return
+}
+
+// This is exported via linkname to assembly in syscall (for Plan9).
+//
+//go:linkname gostring
+func gostring(p *byte) string {
+ l := findnull(p)
+ if l == 0 {
+ return ""
+ }
+ s, b := rawstring(l)
+ memmove(unsafe.Pointer(&b[0]), unsafe.Pointer(p), uintptr(l))
+ return s
+}
+
+// internal_syscall_gostring is a version of gostring for internal/syscall/unix.
+//
+//go:linkname internal_syscall_gostring internal/syscall/unix.gostring
+func internal_syscall_gostring(p *byte) string {
+ return gostring(p)
+}
+
+func gostringn(p *byte, l int) string {
+ if l == 0 {
+ return ""
+ }
+ s, b := rawstring(l)
+ memmove(unsafe.Pointer(&b[0]), unsafe.Pointer(p), uintptr(l))
+ return s
+}
+
+func hasPrefix(s, prefix string) bool {
+ return len(s) >= len(prefix) && s[:len(prefix)] == prefix
+}
+
+func hasSuffix(s, suffix string) bool {
+ return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
+}
+
+const (
+ maxUint64 = ^uint64(0)
+ maxInt64 = int64(maxUint64 >> 1)
+)
+
+// atoi64 parses an int64 from a string s.
+// The bool result reports whether s is a number
+// representable by a value of type int64.
+func atoi64(s string) (int64, bool) {
+ if s == "" {
+ return 0, false
+ }
+
+ neg := false
+ if s[0] == '-' {
+ neg = true
+ s = s[1:]
+ }
+
+ un := uint64(0)
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ if c < '0' || c > '9' {
+ return 0, false
+ }
+ if un > maxUint64/10 {
+ // overflow
+ return 0, false
+ }
+ un *= 10
+ un1 := un + uint64(c) - '0'
+ if un1 < un {
+ // overflow
+ return 0, false
+ }
+ un = un1
+ }
+
+ if !neg && un > uint64(maxInt64) {
+ return 0, false
+ }
+ if neg && un > uint64(maxInt64)+1 {
+ return 0, false
+ }
+
+ n := int64(un)
+ if neg {
+ n = -n
+ }
+
+ return n, true
+}
+
+// atoi is like atoi64 but for integers
+// that fit into an int.
+func atoi(s string) (int, bool) {
+ if n, ok := atoi64(s); n == int64(int(n)) {
+ return int(n), ok
+ }
+ return 0, false
+}
+
+// atoi32 is like atoi but for integers
+// that fit into an int32.
+func atoi32(s string) (int32, bool) {
+ if n, ok := atoi64(s); n == int64(int32(n)) {
+ return int32(n), ok
+ }
+ return 0, false
+}
+
+// parseByteCount parses a string that represents a count of bytes.
+//
+// s must match the following regular expression:
+//
+// ^[0-9]+(([KMGT]i)?B)?$
+//
+// In other words, an integer byte count with an optional unit
+// suffix. Acceptable suffixes include one of
+// - KiB, MiB, GiB, TiB which represent binary IEC/ISO 80000 units, or
+// - B, which just represents bytes.
+//
+// Returns an int64 because that's what its callers want and receive,
+// but the result is always non-negative.
+func parseByteCount(s string) (int64, bool) {
+ // The empty string is not valid.
+ if s == "" {
+ return 0, false
+ }
+ // Handle the easy non-suffix case.
+ last := s[len(s)-1]
+ if last >= '0' && last <= '9' {
+ n, ok := atoi64(s)
+ if !ok || n < 0 {
+ return 0, false
+ }
+ return n, ok
+ }
+ // Failing a trailing digit, this must always end in 'B'.
+ // Also at this point there must be at least one digit before
+ // that B.
+ if last != 'B' || len(s) < 2 {
+ return 0, false
+ }
+ // The one before that must always be a digit or 'i'.
+ if c := s[len(s)-2]; c >= '0' && c <= '9' {
+ // Trivial 'B' suffix.
+ n, ok := atoi64(s[:len(s)-1])
+ if !ok || n < 0 {
+ return 0, false
+ }
+ return n, ok
+ } else if c != 'i' {
+ return 0, false
+ }
+ // Finally, we need at least 4 characters now, for the unit
+ // prefix and at least one digit.
+ if len(s) < 4 {
+ return 0, false
+ }
+ power := 0
+ switch s[len(s)-3] {
+ case 'K':
+ power = 1
+ case 'M':
+ power = 2
+ case 'G':
+ power = 3
+ case 'T':
+ power = 4
+ default:
+ // Invalid suffix.
+ return 0, false
+ }
+ m := uint64(1)
+ for i := 0; i < power; i++ {
+ m *= 1024
+ }
+ n, ok := atoi64(s[:len(s)-3])
+ if !ok || n < 0 {
+ return 0, false
+ }
+ un := uint64(n)
+ if un > maxUint64/m {
+ // Overflow.
+ return 0, false
+ }
+ un *= m
+ if un > uint64(maxInt64) {
+ // Overflow.
+ return 0, false
+ }
+ return int64(un), true
+}
+
+//go:nosplit
+func findnull(s *byte) int {
+ if s == nil {
+ return 0
+ }
+
+ // Avoid IndexByteString on Plan 9 because it uses SSE instructions
+ // on x86 machines, and those are classified as floating point instructions,
+ // which are illegal in a note handler.
+ if GOOS == "plan9" {
+ p := (*[maxAlloc/2 - 1]byte)(unsafe.Pointer(s))
+ l := 0
+ for p[l] != 0 {
+ l++
+ }
+ return l
+ }
+
+ // pageSize is the unit we scan at a time looking for NULL.
+ // It must be the minimum page size for any architecture Go
+ // runs on. It's okay (just a minor performance loss) if the
+ // actual system page size is larger than this value.
+ const pageSize = 4096
+
+ offset := 0
+ ptr := unsafe.Pointer(s)
+ // IndexByteString uses wide reads, so we need to be careful
+ // with page boundaries. Call IndexByteString on
+ // [ptr, endOfPage) interval.
+ safeLen := int(pageSize - uintptr(ptr)%pageSize)
+
+ for {
+ t := *(*string)(unsafe.Pointer(&stringStruct{ptr, safeLen}))
+ // Check one page at a time.
+ if i := bytealg.IndexByteString(t, 0); i != -1 {
+ return offset + i
+ }
+ // Move to next page
+ ptr = unsafe.Pointer(uintptr(ptr) + uintptr(safeLen))
+ offset += safeLen
+ safeLen = pageSize
+ }
+}
+
+func findnullw(s *uint16) int {
+ if s == nil {
+ return 0
+ }
+ p := (*[maxAlloc/2/2 - 1]uint16)(unsafe.Pointer(s))
+ l := 0
+ for p[l] != 0 {
+ l++
+ }
+ return l
+}
+
+//go:nosplit
+func gostringnocopy(str *byte) string {
+ ss := stringStruct{str: unsafe.Pointer(str), len: findnull(str)}
+ s := *(*string)(unsafe.Pointer(&ss))
+ return s
+}
+
+func gostringw(strw *uint16) string {
+ var buf [8]byte
+ str := (*[maxAlloc/2/2 - 1]uint16)(unsafe.Pointer(strw))
+ n1 := 0
+ for i := 0; str[i] != 0; i++ {
+ n1 += encoderune(buf[:], rune(str[i]))
+ }
+ s, b := rawstring(n1 + 4)
+ n2 := 0
+ for i := 0; str[i] != 0; i++ {
+ // check for race
+ if n2 >= n1 {
+ break
+ }
+ n2 += encoderune(b[n2:], rune(str[i]))
+ }
+ b[n2] = 0 // for luck
+ return s[:n2]
+}
diff --git a/contrib/go/_std_1.21/src/runtime/stubs.go b/contrib/go/_std_1.21/src/runtime/stubs.go
new file mode 100644
index 0000000000..65b7299f74
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/stubs.go
@@ -0,0 +1,499 @@
+// Copyright 2014 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/math"
+ "unsafe"
+)
+
+// Should be a built-in for unsafe.Pointer?
+//
+//go:nosplit
+func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
+ return unsafe.Pointer(uintptr(p) + x)
+}
+
+// getg returns the pointer to the current g.
+// The compiler rewrites calls to this function into instructions
+// that fetch the g directly (from TLS or from the dedicated register).
+func getg() *g
+
+// mcall switches from the g to the g0 stack and invokes fn(g),
+// where g is the goroutine that made the call.
+// mcall saves g's current PC/SP in g->sched so that it can be restored later.
+// It is up to fn to arrange for that later execution, typically by recording
+// g in a data structure, causing something to call ready(g) later.
+// mcall returns to the original goroutine g later, when g has been rescheduled.
+// fn must not return at all; typically it ends by calling schedule, to let the m
+// run other goroutines.
+//
+// mcall can only be called from g stacks (not g0, not gsignal).
+//
+// This must NOT be go:noescape: if fn is a stack-allocated closure,
+// fn puts g on a run queue, and g executes before fn returns, the
+// closure will be invalidated while it is still executing.
+func mcall(fn func(*g))
+
+// systemstack runs fn on a system stack.
+// If systemstack is called from the per-OS-thread (g0) stack, or
+// if systemstack is called from the signal handling (gsignal) stack,
+// systemstack calls fn directly and returns.
+// Otherwise, systemstack is being called from the limited stack
+// of an ordinary goroutine. In this case, systemstack switches
+// to the per-OS-thread stack, calls fn, and switches back.
+// It is common to use a func literal as the argument, in order
+// to share inputs and outputs with the code around the call
+// to system stack:
+//
+// ... set up y ...
+// systemstack(func() {
+// x = bigcall(y)
+// })
+// ... use x ...
+//
+//go:noescape
+func systemstack(fn func())
+
+//go:nosplit
+//go:nowritebarrierrec
+func badsystemstack() {
+ writeErrStr("fatal: systemstack called from unexpected goroutine")
+}
+
+// memclrNoHeapPointers clears n bytes starting at ptr.
+//
+// Usually you should use typedmemclr. memclrNoHeapPointers should be
+// used only when the caller knows that *ptr contains no heap pointers
+// because either:
+//
+// *ptr is initialized memory and its type is pointer-free, or
+//
+// *ptr is uninitialized memory (e.g., memory that's being reused
+// for a new allocation) and hence contains only "junk".
+//
+// memclrNoHeapPointers ensures that if ptr is pointer-aligned, and n
+// is a multiple of the pointer size, then any pointer-aligned,
+// pointer-sized portion is cleared atomically. Despite the function
+// name, this is necessary because this function is the underlying
+// implementation of typedmemclr and memclrHasPointers. See the doc of
+// memmove for more details.
+//
+// The (CPU-specific) implementations of this function are in memclr_*.s.
+//
+//go:noescape
+func memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr)
+
+//go:linkname reflect_memclrNoHeapPointers reflect.memclrNoHeapPointers
+func reflect_memclrNoHeapPointers(ptr unsafe.Pointer, n uintptr) {
+ memclrNoHeapPointers(ptr, n)
+}
+
+// memmove copies n bytes from "from" to "to".
+//
+// memmove ensures that any pointer in "from" is written to "to" with
+// an indivisible write, so that racy reads cannot observe a
+// half-written pointer. This is necessary to prevent the garbage
+// collector from observing invalid pointers, and differs from memmove
+// in unmanaged languages. However, memmove is only required to do
+// this if "from" and "to" may contain pointers, which can only be the
+// case if "from", "to", and "n" are all be word-aligned.
+//
+// Implementations are in memmove_*.s.
+//
+//go:noescape
+func memmove(to, from unsafe.Pointer, n uintptr)
+
+// Outside assembly calls memmove. Make sure it has ABI wrappers.
+//
+//go:linkname memmove
+
+//go:linkname reflect_memmove reflect.memmove
+func reflect_memmove(to, from unsafe.Pointer, n uintptr) {
+ memmove(to, from, n)
+}
+
+// exported value for testing
+const hashLoad = float32(loadFactorNum) / float32(loadFactorDen)
+
+//go:nosplit
+func fastrand() uint32 {
+ mp := getg().m
+ // Implement wyrand: https://github.com/wangyi-fudan/wyhash
+ // Only the platform that math.Mul64 can be lowered
+ // by the compiler should be in this list.
+ if goarch.IsAmd64|goarch.IsArm64|goarch.IsPpc64|
+ goarch.IsPpc64le|goarch.IsMips64|goarch.IsMips64le|
+ goarch.IsS390x|goarch.IsRiscv64|goarch.IsLoong64 == 1 {
+ mp.fastrand += 0xa0761d6478bd642f
+ hi, lo := math.Mul64(mp.fastrand, mp.fastrand^0xe7037ed1a0b428db)
+ return uint32(hi ^ lo)
+ }
+
+ // Implement xorshift64+: 2 32-bit xorshift sequences added together.
+ // Shift triplet [17,7,16] was calculated as indicated in Marsaglia's
+ // Xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
+ // This generator passes the SmallCrush suite, part of TestU01 framework:
+ // http://simul.iro.umontreal.ca/testu01/tu01.html
+ t := (*[2]uint32)(unsafe.Pointer(&mp.fastrand))
+ s1, s0 := t[0], t[1]
+ s1 ^= s1 << 17
+ s1 = s1 ^ s0 ^ s1>>7 ^ s0>>16
+ t[0], t[1] = s0, s1
+ return s0 + s1
+}
+
+//go:nosplit
+func fastrandn(n uint32) uint32 {
+ // This is similar to fastrand() % n, but faster.
+ // See https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
+ return uint32(uint64(fastrand()) * uint64(n) >> 32)
+}
+
+func fastrand64() uint64 {
+ mp := getg().m
+ // Implement wyrand: https://github.com/wangyi-fudan/wyhash
+ // Only the platform that math.Mul64 can be lowered
+ // by the compiler should be in this list.
+ if goarch.IsAmd64|goarch.IsArm64|goarch.IsPpc64|
+ goarch.IsPpc64le|goarch.IsMips64|goarch.IsMips64le|
+ goarch.IsS390x|goarch.IsRiscv64 == 1 {
+ mp.fastrand += 0xa0761d6478bd642f
+ hi, lo := math.Mul64(mp.fastrand, mp.fastrand^0xe7037ed1a0b428db)
+ return hi ^ lo
+ }
+
+ // Implement xorshift64+: 2 32-bit xorshift sequences added together.
+ // Xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
+ // This generator passes the SmallCrush suite, part of TestU01 framework:
+ // http://simul.iro.umontreal.ca/testu01/tu01.html
+ t := (*[2]uint32)(unsafe.Pointer(&mp.fastrand))
+ s1, s0 := t[0], t[1]
+ s1 ^= s1 << 17
+ s1 = s1 ^ s0 ^ s1>>7 ^ s0>>16
+ r := uint64(s0 + s1)
+
+ s0, s1 = s1, s0
+ s1 ^= s1 << 17
+ s1 = s1 ^ s0 ^ s1>>7 ^ s0>>16
+ r += uint64(s0+s1) << 32
+
+ t[0], t[1] = s0, s1
+ return r
+}
+
+func fastrandu() uint {
+ if goarch.PtrSize == 4 {
+ return uint(fastrand())
+ }
+ return uint(fastrand64())
+}
+
+//go:linkname rand_fastrand64 math/rand.fastrand64
+func rand_fastrand64() uint64 { return fastrand64() }
+
+//go:linkname sync_fastrandn sync.fastrandn
+func sync_fastrandn(n uint32) uint32 { return fastrandn(n) }
+
+//go:linkname net_fastrandu net.fastrandu
+func net_fastrandu() uint { return fastrandu() }
+
+//go:linkname os_fastrand os.fastrand
+func os_fastrand() uint32 { return fastrand() }
+
+// in internal/bytealg/equal_*.s
+//
+//go:noescape
+func memequal(a, b unsafe.Pointer, size uintptr) bool
+
+// noescape hides a pointer from escape analysis. noescape is
+// the identity function but escape analysis doesn't think the
+// output depends on the input. noescape is inlined and currently
+// compiles down to zero instructions.
+// USE CAREFULLY!
+//
+//go:nosplit
+func noescape(p unsafe.Pointer) unsafe.Pointer {
+ x := uintptr(p)
+ return unsafe.Pointer(x ^ 0)
+}
+
+// noEscapePtr hides a pointer from escape analysis. See noescape.
+// USE CAREFULLY!
+//
+//go:nosplit
+func noEscapePtr[T any](p *T) *T {
+ x := uintptr(unsafe.Pointer(p))
+ return (*T)(unsafe.Pointer(x ^ 0))
+}
+
+// Not all cgocallback frames are actually cgocallback,
+// so not all have these arguments. Mark them uintptr so that the GC
+// does not misinterpret memory when the arguments are not present.
+// cgocallback is not called from Go, only from crosscall2.
+// This in turn calls cgocallbackg, which is where we'll find
+// pointer-declared arguments.
+//
+// When fn is nil (frame is saved g), call dropm instead,
+// this is used when the C thread is exiting.
+func cgocallback(fn, frame, ctxt uintptr)
+
+func gogo(buf *gobuf)
+
+func asminit()
+func setg(gg *g)
+func breakpoint()
+
+// reflectcall calls fn with arguments described by stackArgs, stackArgsSize,
+// frameSize, and regArgs.
+//
+// Arguments passed on the stack and space for return values passed on the stack
+// must be laid out at the space pointed to by stackArgs (with total length
+// stackArgsSize) according to the ABI.
+//
+// stackRetOffset must be some value <= stackArgsSize that indicates the
+// offset within stackArgs where the return value space begins.
+//
+// frameSize is the total size of the argument frame at stackArgs and must
+// therefore be >= stackArgsSize. It must include additional space for spilling
+// register arguments for stack growth and preemption.
+//
+// TODO(mknyszek): Once we don't need the additional spill space, remove frameSize,
+// since frameSize will be redundant with stackArgsSize.
+//
+// Arguments passed in registers must be laid out in regArgs according to the ABI.
+// regArgs will hold any return values passed in registers after the call.
+//
+// reflectcall copies stack arguments from stackArgs to the goroutine stack, and
+// then copies back stackArgsSize-stackRetOffset bytes back to the return space
+// in stackArgs once fn has completed. It also "unspills" argument registers from
+// regArgs before calling fn, and spills them back into regArgs immediately
+// following the call to fn. If there are results being returned on the stack,
+// the caller should pass the argument frame type as stackArgsType so that
+// reflectcall can execute appropriate write barriers during the copy.
+//
+// reflectcall expects regArgs.ReturnIsPtr to be populated indicating which
+// registers on the return path will contain Go pointers. It will then store
+// these pointers in regArgs.Ptrs such that they are visible to the GC.
+//
+// Package reflect passes a frame type. In package runtime, there is only
+// one call that copies results back, in callbackWrap in syscall_windows.go, and it
+// does NOT pass a frame type, meaning there are no write barriers invoked. See that
+// call site for justification.
+//
+// Package reflect accesses this symbol through a linkname.
+//
+// Arguments passed through to reflectcall do not escape. The type is used
+// only in a very limited callee of reflectcall, the stackArgs are copied, and
+// regArgs is only used in the reflectcall frame.
+//
+//go:noescape
+func reflectcall(stackArgsType *_type, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+
+func procyield(cycles uint32)
+
+type neverCallThisFunction struct{}
+
+// goexit is the return stub at the top of every goroutine call stack.
+// Each goroutine stack is constructed as if goexit called the
+// goroutine's entry point function, so that when the entry point
+// function returns, it will return to goexit, which will call goexit1
+// to perform the actual exit.
+//
+// This function must never be called directly. Call goexit1 instead.
+// gentraceback assumes that goexit terminates the stack. A direct
+// call on the stack will cause gentraceback to stop walking the stack
+// prematurely and if there is leftover state it may panic.
+func goexit(neverCallThisFunction)
+
+// publicationBarrier performs a store/store barrier (a "publication"
+// or "export" barrier). Some form of synchronization is required
+// between initializing an object and making that object accessible to
+// another processor. Without synchronization, the initialization
+// writes and the "publication" write may be reordered, allowing the
+// other processor to follow the pointer and observe an uninitialized
+// object. In general, higher-level synchronization should be used,
+// such as locking or an atomic pointer write. publicationBarrier is
+// for when those aren't an option, such as in the implementation of
+// the memory manager.
+//
+// There's no corresponding barrier for the read side because the read
+// side naturally has a data dependency order. All architectures that
+// Go supports or seems likely to ever support automatically enforce
+// data dependency ordering.
+func publicationBarrier()
+
+// getcallerpc returns the program counter (PC) of its caller's caller.
+// getcallersp returns the stack pointer (SP) of its caller's caller.
+// The implementation may be a compiler intrinsic; there is not
+// necessarily code implementing this on every platform.
+//
+// For example:
+//
+// func f(arg1, arg2, arg3 int) {
+// pc := getcallerpc()
+// sp := getcallersp()
+// }
+//
+// These two lines find the PC and SP immediately following
+// the call to f (where f will return).
+//
+// The call to getcallerpc and getcallersp must be done in the
+// frame being asked about.
+//
+// The result of getcallersp is correct at the time of the return,
+// but it may be invalidated by any subsequent call to a function
+// that might relocate the stack in order to grow or shrink it.
+// A general rule is that the result of getcallersp should be used
+// immediately and can only be passed to nosplit functions.
+
+//go:noescape
+func getcallerpc() uintptr
+
+//go:noescape
+func getcallersp() uintptr // implemented as an intrinsic on all platforms
+
+// getclosureptr returns the pointer to the current closure.
+// getclosureptr can only be used in an assignment statement
+// at the entry of a function. Moreover, go:nosplit directive
+// must be specified at the declaration of caller function,
+// so that the function prolog does not clobber the closure register.
+// for example:
+//
+// //go:nosplit
+// func f(arg1, arg2, arg3 int) {
+// dx := getclosureptr()
+// }
+//
+// The compiler rewrites calls to this function into instructions that fetch the
+// pointer from a well-known register (DX on x86 architecture, etc.) directly.
+func getclosureptr() uintptr
+
+//go:noescape
+func asmcgocall(fn, arg unsafe.Pointer) int32
+
+func morestack()
+func morestack_noctxt()
+func rt0_go()
+
+// return0 is a stub used to return 0 from deferproc.
+// It is called at the very end of deferproc to signal
+// the calling Go function that it should not jump
+// to deferreturn.
+// in asm_*.s
+func return0()
+
+// in asm_*.s
+// not called directly; definitions here supply type information for traceback.
+// These must have the same signature (arg pointer map) as reflectcall.
+func call16(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call32(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call64(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call128(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call256(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call512(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call1024(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call2048(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call4096(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call8192(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call16384(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call32768(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call65536(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call131072(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call262144(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call524288(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call1048576(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call2097152(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call4194304(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call8388608(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call16777216(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call33554432(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call67108864(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call134217728(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call268435456(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call536870912(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+func call1073741824(typ, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs)
+
+func systemstack_switch()
+
+// alignUp rounds n up to a multiple of a. a must be a power of 2.
+func alignUp(n, a uintptr) uintptr {
+ return (n + a - 1) &^ (a - 1)
+}
+
+// alignDown rounds n down to a multiple of a. a must be a power of 2.
+func alignDown(n, a uintptr) uintptr {
+ return n &^ (a - 1)
+}
+
+// divRoundUp returns ceil(n / a).
+func divRoundUp(n, a uintptr) uintptr {
+ // a is generally a power of two. This will get inlined and
+ // the compiler will optimize the division.
+ return (n + a - 1) / a
+}
+
+// checkASM reports whether assembly runtime checks have passed.
+func checkASM() bool
+
+func memequal_varlen(a, b unsafe.Pointer) bool
+
+// bool2int returns 0 if x is false or 1 if x is true.
+func bool2int(x bool) int {
+ // Avoid branches. In the SSA compiler, this compiles to
+ // exactly what you would want it to.
+ return int(uint8(*(*uint8)(unsafe.Pointer(&x))))
+}
+
+// abort crashes the runtime in situations where even throw might not
+// work. In general it should do something a debugger will recognize
+// (e.g., an INT3 on x86). A crash in abort is recognized by the
+// signal handler, which will attempt to tear down the runtime
+// immediately.
+func abort()
+
+// Called from compiled code; declared for vet; do NOT call from Go.
+func gcWriteBarrier1()
+func gcWriteBarrier2()
+func gcWriteBarrier3()
+func gcWriteBarrier4()
+func gcWriteBarrier5()
+func gcWriteBarrier6()
+func gcWriteBarrier7()
+func gcWriteBarrier8()
+func duffzero()
+func duffcopy()
+
+// Called from linker-generated .initarray; declared for go vet; do NOT call from Go.
+func addmoduledata()
+
+// Injected by the signal handler for panicking signals.
+// Initializes any registers that have fixed meaning at calls but
+// are scratch in bodies and calls sigpanic.
+// On many platforms it just jumps to sigpanic.
+func sigpanic0()
+
+// intArgRegs is used by the various register assignment
+// algorithm implementations in the runtime. These include:.
+// - Finalizers (mfinal.go)
+// - Windows callbacks (syscall_windows.go)
+//
+// Both are stripped-down versions of the algorithm since they
+// only have to deal with a subset of cases (finalizers only
+// take a pointer or interface argument, Go Windows callbacks
+// don't support floating point).
+//
+// It should be modified with care and are generally only
+// modified when testing this package.
+//
+// It should never be set higher than its internal/abi
+// constant counterparts, because the system relies on a
+// structure that is at least large enough to hold the
+// registers the system supports.
+//
+// Protected by finlock.
+var intArgRegs = abi.IntArgRegs
diff --git a/contrib/go/_std_1.21/src/runtime/stubs2.go b/contrib/go/_std_1.21/src/runtime/stubs2.go
new file mode 100644
index 0000000000..9637347a35
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/stubs2.go
@@ -0,0 +1,44 @@
+// Copyright 2014 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.
+
+//go:build !aix && !darwin && !js && !openbsd && !plan9 && !solaris && !wasip1 && !windows
+
+package runtime
+
+import (
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// read calls the read system call.
+// It returns a non-negative number of bytes written or a negative errno value.
+func read(fd int32, p unsafe.Pointer, n int32) int32
+
+func closefd(fd int32) int32
+
+func exit(code int32)
+func usleep(usec uint32)
+
+//go:nosplit
+func usleep_no_g(usec uint32) {
+ usleep(usec)
+}
+
+// write1 calls the write system call.
+// It returns a non-negative number of bytes written or a negative errno value.
+//
+//go:noescape
+func write1(fd uintptr, p unsafe.Pointer, n int32) int32
+
+//go:noescape
+func open(name *byte, mode, perm int32) int32
+
+// return value is only set on linux to be used in osinit().
+func madvise(addr unsafe.Pointer, n uintptr, flags int32) int32
+
+// exitThread terminates the current thread, writing *wait = freeMStack when
+// the stack is safe to reclaim.
+//
+//go:noescape
+func exitThread(wait *atomic.Uint32)
diff --git a/contrib/go/_std_1.21/src/runtime/stubs3.go b/contrib/go/_std_1.21/src/runtime/stubs3.go
new file mode 100644
index 0000000000..c3749f34ed
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/stubs3.go
@@ -0,0 +1,10 @@
+// Copyright 2018 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.
+
+//go:build !aix && !darwin && !freebsd && !openbsd && !plan9 && !solaris && !wasip1
+
+package runtime
+
+//go:wasmimport gojs runtime.nanotime1
+func nanotime1() int64
diff --git a/contrib/go/_std_1.21/src/runtime/stubs_amd64.go b/contrib/go/_std_1.21/src/runtime/stubs_amd64.go
new file mode 100644
index 0000000000..a86a496457
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/stubs_amd64.go
@@ -0,0 +1,53 @@
+// Copyright 2018 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 runtime
+
+import "unsafe"
+
+// Called from compiled code; declared for vet; do NOT call from Go.
+func gcWriteBarrierCX()
+func gcWriteBarrierDX()
+func gcWriteBarrierBX()
+func gcWriteBarrierBP()
+func gcWriteBarrierSI()
+func gcWriteBarrierR8()
+func gcWriteBarrierR9()
+
+// stackcheck checks that SP is in range [g->stack.lo, g->stack.hi).
+func stackcheck()
+
+// Called from assembly only; declared for go vet.
+func settls() // argument in DI
+
+// Retpolines, used by -spectre=ret flag in cmd/asm, cmd/compile.
+func retpolineAX()
+func retpolineCX()
+func retpolineDX()
+func retpolineBX()
+func retpolineBP()
+func retpolineSI()
+func retpolineDI()
+func retpolineR8()
+func retpolineR9()
+func retpolineR10()
+func retpolineR11()
+func retpolineR12()
+func retpolineR13()
+func retpolineR14()
+func retpolineR15()
+
+//go:noescape
+func asmcgocall_no_g(fn, arg unsafe.Pointer)
+
+// Used by reflectcall and the reflect package.
+//
+// Spills/loads arguments in registers to/from an internal/abi.RegArgs
+// respectively. Does not follow the Go ABI.
+func spillArgs()
+func unspillArgs()
+
+// getfp returns the frame pointer register of its caller or 0 if not implemented.
+// TODO: Make this a compiler intrinsic
+func getfp() uintptr
diff --git a/contrib/go/_std_1.21/src/runtime/stubs_arm64.go b/contrib/go/_std_1.21/src/runtime/stubs_arm64.go
new file mode 100644
index 0000000000..df04e64291
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/stubs_arm64.go
@@ -0,0 +1,27 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+// Called from assembly only; declared for go vet.
+func load_g()
+func save_g()
+
+//go:noescape
+func asmcgocall_no_g(fn, arg unsafe.Pointer)
+
+func emptyfunc()
+
+// Used by reflectcall and the reflect package.
+//
+// Spills/loads arguments in registers to/from an internal/abi.RegArgs
+// respectively. Does not follow the Go ABI.
+func spillArgs()
+func unspillArgs()
+
+// getfp returns the frame pointer register of its caller or 0 if not implemented.
+// TODO: Make this a compiler intrinsic
+func getfp() uintptr
diff --git a/contrib/go/_std_1.20/src/runtime/stubs_linux.go b/contrib/go/_std_1.21/src/runtime/stubs_linux.go
index 2367dc2bd0..2367dc2bd0 100644
--- a/contrib/go/_std_1.20/src/runtime/stubs_linux.go
+++ b/contrib/go/_std_1.21/src/runtime/stubs_linux.go
diff --git a/contrib/go/_std_1.20/src/runtime/stubs_nonlinux.go b/contrib/go/_std_1.21/src/runtime/stubs_nonlinux.go
index 1a06d7cc1d..1a06d7cc1d 100644
--- a/contrib/go/_std_1.20/src/runtime/stubs_nonlinux.go
+++ b/contrib/go/_std_1.21/src/runtime/stubs_nonlinux.go
diff --git a/contrib/go/_std_1.21/src/runtime/symtab.go b/contrib/go/_std_1.21/src/runtime/symtab.go
new file mode 100644
index 0000000000..b47f2d8390
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/symtab.go
@@ -0,0 +1,1125 @@
+// Copyright 2014 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// Frames may be used to get function/file/line information for a
+// slice of PC values returned by Callers.
+type Frames struct {
+ // callers is a slice of PCs that have not yet been expanded to frames.
+ callers []uintptr
+
+ // frames is a slice of Frames that have yet to be returned.
+ frames []Frame
+ frameStore [2]Frame
+}
+
+// Frame is the information returned by Frames for each call frame.
+type Frame struct {
+ // PC is the program counter for the location in this frame.
+ // For a frame that calls another frame, this will be the
+ // program counter of a call instruction. Because of inlining,
+ // multiple frames may have the same PC value, but different
+ // symbolic information.
+ PC uintptr
+
+ // Func is the Func value of this call frame. This may be nil
+ // for non-Go code or fully inlined functions.
+ Func *Func
+
+ // Function is the package path-qualified function name of
+ // this call frame. If non-empty, this string uniquely
+ // identifies a single function in the program.
+ // This may be the empty string if not known.
+ // If Func is not nil then Function == Func.Name().
+ Function string
+
+ // File and Line are the file name and line number of the
+ // location in this frame. For non-leaf frames, this will be
+ // the location of a call. These may be the empty string and
+ // zero, respectively, if not known.
+ File string
+ Line int
+
+ // startLine is the line number of the beginning of the function in
+ // this frame. Specifically, it is the line number of the func keyword
+ // for Go functions. Note that //line directives can change the
+ // filename and/or line number arbitrarily within a function, meaning
+ // that the Line - startLine offset is not always meaningful.
+ //
+ // This may be zero if not known.
+ startLine int
+
+ // Entry point program counter for the function; may be zero
+ // if not known. If Func is not nil then Entry ==
+ // Func.Entry().
+ Entry uintptr
+
+ // The runtime's internal view of the function. This field
+ // is set (funcInfo.valid() returns true) only for Go functions,
+ // not for C functions.
+ funcInfo funcInfo
+}
+
+// CallersFrames takes a slice of PC values returned by Callers and
+// prepares to return function/file/line information.
+// Do not change the slice until you are done with the Frames.
+func CallersFrames(callers []uintptr) *Frames {
+ f := &Frames{callers: callers}
+ f.frames = f.frameStore[:0]
+ return f
+}
+
+// Next returns a Frame representing the next call frame in the slice
+// of PC values. If it has already returned all call frames, Next
+// returns a zero Frame.
+//
+// The more result indicates whether the next call to Next will return
+// a valid Frame. It does not necessarily indicate whether this call
+// returned one.
+//
+// See the Frames example for idiomatic usage.
+func (ci *Frames) Next() (frame Frame, more bool) {
+ for len(ci.frames) < 2 {
+ // Find the next frame.
+ // We need to look for 2 frames so we know what
+ // to return for the "more" result.
+ if len(ci.callers) == 0 {
+ break
+ }
+ pc := ci.callers[0]
+ ci.callers = ci.callers[1:]
+ funcInfo := findfunc(pc)
+ if !funcInfo.valid() {
+ if cgoSymbolizer != nil {
+ // Pre-expand cgo frames. We could do this
+ // incrementally, too, but there's no way to
+ // avoid allocation in this case anyway.
+ ci.frames = append(ci.frames, expandCgoFrames(pc)...)
+ }
+ continue
+ }
+ f := funcInfo._Func()
+ entry := f.Entry()
+ if pc > entry {
+ // We store the pc of the start of the instruction following
+ // the instruction in question (the call or the inline mark).
+ // This is done for historical reasons, and to make FuncForPC
+ // work correctly for entries in the result of runtime.Callers.
+ pc--
+ }
+ // It's important that interpret pc non-strictly as cgoTraceback may
+ // have added bogus PCs with a valid funcInfo but invalid PCDATA.
+ u, uf := newInlineUnwinder(funcInfo, pc, nil)
+ sf := u.srcFunc(uf)
+ if u.isInlined(uf) {
+ // Note: entry is not modified. It always refers to a real frame, not an inlined one.
+ // File/line from funcline1 below are already correct.
+ f = nil
+ }
+ ci.frames = append(ci.frames, Frame{
+ PC: pc,
+ Func: f,
+ Function: funcNameForPrint(sf.name()),
+ Entry: entry,
+ startLine: int(sf.startLine),
+ funcInfo: funcInfo,
+ // Note: File,Line set below
+ })
+ }
+
+ // Pop one frame from the frame list. Keep the rest.
+ // Avoid allocation in the common case, which is 1 or 2 frames.
+ switch len(ci.frames) {
+ case 0: // In the rare case when there are no frames at all, we return Frame{}.
+ return
+ case 1:
+ frame = ci.frames[0]
+ ci.frames = ci.frameStore[:0]
+ case 2:
+ frame = ci.frames[0]
+ ci.frameStore[0] = ci.frames[1]
+ ci.frames = ci.frameStore[:1]
+ default:
+ frame = ci.frames[0]
+ ci.frames = ci.frames[1:]
+ }
+ more = len(ci.frames) > 0
+ if frame.funcInfo.valid() {
+ // Compute file/line just before we need to return it,
+ // as it can be expensive. This avoids computing file/line
+ // for the Frame we find but don't return. See issue 32093.
+ file, line := funcline1(frame.funcInfo, frame.PC, false)
+ frame.File, frame.Line = file, int(line)
+ }
+ return
+}
+
+// runtime_FrameStartLine returns the start line of the function in a Frame.
+//
+//go:linkname runtime_FrameStartLine runtime/pprof.runtime_FrameStartLine
+func runtime_FrameStartLine(f *Frame) int {
+ return f.startLine
+}
+
+// runtime_FrameSymbolName returns the full symbol name of the function in a Frame.
+// For generic functions this differs from f.Function in that this doesn't replace
+// the shape name to "...".
+//
+//go:linkname runtime_FrameSymbolName runtime/pprof.runtime_FrameSymbolName
+func runtime_FrameSymbolName(f *Frame) string {
+ if !f.funcInfo.valid() {
+ return f.Function
+ }
+ u, uf := newInlineUnwinder(f.funcInfo, f.PC, nil)
+ sf := u.srcFunc(uf)
+ return sf.name()
+}
+
+// runtime_expandFinalInlineFrame expands the final pc in stk to include all
+// "callers" if pc is inline.
+//
+//go:linkname runtime_expandFinalInlineFrame runtime/pprof.runtime_expandFinalInlineFrame
+func runtime_expandFinalInlineFrame(stk []uintptr) []uintptr {
+ // TODO: It would be more efficient to report only physical PCs to pprof and
+ // just expand the whole stack.
+ if len(stk) == 0 {
+ return stk
+ }
+ pc := stk[len(stk)-1]
+ tracepc := pc - 1
+
+ f := findfunc(tracepc)
+ if !f.valid() {
+ // Not a Go function.
+ return stk
+ }
+
+ var cache pcvalueCache
+ u, uf := newInlineUnwinder(f, tracepc, &cache)
+ if !u.isInlined(uf) {
+ // Nothing inline at tracepc.
+ return stk
+ }
+
+ // Treat the previous func as normal. We haven't actually checked, but
+ // since this pc was included in the stack, we know it shouldn't be
+ // elided.
+ calleeID := abi.FuncIDNormal
+
+ // Remove pc from stk; we'll re-add it below.
+ stk = stk[:len(stk)-1]
+
+ for ; uf.valid(); uf = u.next(uf) {
+ funcID := u.srcFunc(uf).funcID
+ if funcID == abi.FuncIDWrapper && elideWrapperCalling(calleeID) {
+ // ignore wrappers
+ } else {
+ stk = append(stk, uf.pc+1)
+ }
+ calleeID = funcID
+ }
+
+ return stk
+}
+
+// expandCgoFrames expands frame information for pc, known to be
+// a non-Go function, using the cgoSymbolizer hook. expandCgoFrames
+// returns nil if pc could not be expanded.
+func expandCgoFrames(pc uintptr) []Frame {
+ arg := cgoSymbolizerArg{pc: pc}
+ callCgoSymbolizer(&arg)
+
+ if arg.file == nil && arg.funcName == nil {
+ // No useful information from symbolizer.
+ return nil
+ }
+
+ var frames []Frame
+ for {
+ frames = append(frames, Frame{
+ PC: pc,
+ Func: nil,
+ Function: gostring(arg.funcName),
+ File: gostring(arg.file),
+ Line: int(arg.lineno),
+ Entry: arg.entry,
+ // funcInfo is zero, which implies !funcInfo.valid().
+ // That ensures that we use the File/Line info given here.
+ })
+ if arg.more == 0 {
+ break
+ }
+ callCgoSymbolizer(&arg)
+ }
+
+ // No more frames for this PC. Tell the symbolizer we are done.
+ // We don't try to maintain a single cgoSymbolizerArg for the
+ // whole use of Frames, because there would be no good way to tell
+ // the symbolizer when we are done.
+ arg.pc = 0
+ callCgoSymbolizer(&arg)
+
+ return frames
+}
+
+// NOTE: Func does not expose the actual unexported fields, because we return *Func
+// values to users, and we want to keep them from being able to overwrite the data
+// with (say) *f = Func{}.
+// All code operating on a *Func must call raw() to get the *_func
+// or funcInfo() to get the funcInfo instead.
+
+// A Func represents a Go function in the running binary.
+type Func struct {
+ opaque struct{} // unexported field to disallow conversions
+}
+
+func (f *Func) raw() *_func {
+ return (*_func)(unsafe.Pointer(f))
+}
+
+func (f *Func) funcInfo() funcInfo {
+ return f.raw().funcInfo()
+}
+
+func (f *_func) funcInfo() funcInfo {
+ // Find the module containing fn. fn is located in the pclntable.
+ // The unsafe.Pointer to uintptr conversions and arithmetic
+ // are safe because we are working with module addresses.
+ ptr := uintptr(unsafe.Pointer(f))
+ var mod *moduledata
+ for datap := &firstmoduledata; datap != nil; datap = datap.next {
+ if len(datap.pclntable) == 0 {
+ continue
+ }
+ base := uintptr(unsafe.Pointer(&datap.pclntable[0]))
+ if base <= ptr && ptr < base+uintptr(len(datap.pclntable)) {
+ mod = datap
+ break
+ }
+ }
+ return funcInfo{f, mod}
+}
+
+// pcHeader holds data used by the pclntab lookups.
+type pcHeader struct {
+ magic uint32 // 0xFFFFFFF1
+ pad1, pad2 uint8 // 0,0
+ minLC uint8 // min instruction size
+ ptrSize uint8 // size of a ptr in bytes
+ nfunc int // number of functions in the module
+ nfiles uint // number of entries in the file tab
+ textStart uintptr // base for function entry PC offsets in this module, equal to moduledata.text
+ funcnameOffset uintptr // offset to the funcnametab variable from pcHeader
+ cuOffset uintptr // offset to the cutab variable from pcHeader
+ filetabOffset uintptr // offset to the filetab variable from pcHeader
+ pctabOffset uintptr // offset to the pctab variable from pcHeader
+ pclnOffset uintptr // offset to the pclntab variable from pcHeader
+}
+
+// moduledata records information about the layout of the executable
+// image. It is written by the linker. Any changes here must be
+// matched changes to the code in cmd/link/internal/ld/symtab.go:symtab.
+// moduledata is stored in statically allocated non-pointer memory;
+// none of the pointers here are visible to the garbage collector.
+type moduledata struct {
+ sys.NotInHeap // Only in static data
+
+ pcHeader *pcHeader
+ funcnametab []byte
+ cutab []uint32
+ filetab []byte
+ pctab []byte
+ pclntable []byte
+ ftab []functab
+ findfunctab uintptr
+ minpc, maxpc uintptr
+
+ text, etext uintptr
+ noptrdata, enoptrdata uintptr
+ data, edata uintptr
+ bss, ebss uintptr
+ noptrbss, enoptrbss uintptr
+ covctrs, ecovctrs uintptr
+ end, gcdata, gcbss uintptr
+ types, etypes uintptr
+ rodata uintptr
+ gofunc uintptr // go.func.*
+
+ textsectmap []textsect
+ typelinks []int32 // offsets from types
+ itablinks []*itab
+
+ ptab []ptabEntry
+
+ pluginpath string
+ pkghashes []modulehash
+
+ // This slice records the initializing tasks that need to be
+ // done to start up the program. It is built by the linker.
+ inittasks []*initTask
+
+ modulename string
+ modulehashes []modulehash
+
+ hasmain uint8 // 1 if module contains the main function, 0 otherwise
+
+ gcdatamask, gcbssmask bitvector
+
+ typemap map[typeOff]*_type // offset to *_rtype in previous module
+
+ bad bool // module failed to load and should be ignored
+
+ next *moduledata
+}
+
+// A modulehash is used to compare the ABI of a new module or a
+// package in a new module with the loaded program.
+//
+// For each shared library a module links against, the linker creates an entry in the
+// moduledata.modulehashes slice containing the name of the module, the abi hash seen
+// at link time and a pointer to the runtime abi hash. These are checked in
+// moduledataverify1 below.
+//
+// For each loaded plugin, the pkghashes slice has a modulehash of the
+// newly loaded package that can be used to check the plugin's version of
+// a package against any previously loaded version of the package.
+// This is done in plugin.lastmoduleinit.
+type modulehash struct {
+ modulename string
+ linktimehash string
+ runtimehash *string
+}
+
+// pinnedTypemaps are the map[typeOff]*_type from the moduledata objects.
+//
+// These typemap objects are allocated at run time on the heap, but the
+// only direct reference to them is in the moduledata, created by the
+// linker and marked SNOPTRDATA so it is ignored by the GC.
+//
+// To make sure the map isn't collected, we keep a second reference here.
+var pinnedTypemaps []map[typeOff]*_type
+
+var firstmoduledata moduledata // linker symbol
+var lastmoduledatap *moduledata // linker symbol
+var modulesSlice *[]*moduledata // see activeModules
+
+// activeModules returns a slice of active modules.
+//
+// A module is active once its gcdatamask and gcbssmask have been
+// assembled and it is usable by the GC.
+//
+// This is nosplit/nowritebarrier because it is called by the
+// cgo pointer checking code.
+//
+//go:nosplit
+//go:nowritebarrier
+func activeModules() []*moduledata {
+ p := (*[]*moduledata)(atomic.Loadp(unsafe.Pointer(&modulesSlice)))
+ if p == nil {
+ return nil
+ }
+ return *p
+}
+
+// modulesinit creates the active modules slice out of all loaded modules.
+//
+// When a module is first loaded by the dynamic linker, an .init_array
+// function (written by cmd/link) is invoked to call addmoduledata,
+// appending to the module to the linked list that starts with
+// firstmoduledata.
+//
+// There are two times this can happen in the lifecycle of a Go
+// program. First, if compiled with -linkshared, a number of modules
+// built with -buildmode=shared can be loaded at program initialization.
+// Second, a Go program can load a module while running that was built
+// with -buildmode=plugin.
+//
+// After loading, this function is called which initializes the
+// moduledata so it is usable by the GC and creates a new activeModules
+// list.
+//
+// Only one goroutine may call modulesinit at a time.
+func modulesinit() {
+ modules := new([]*moduledata)
+ for md := &firstmoduledata; md != nil; md = md.next {
+ if md.bad {
+ continue
+ }
+ *modules = append(*modules, md)
+ if md.gcdatamask == (bitvector{}) {
+ scanDataSize := md.edata - md.data
+ md.gcdatamask = progToPointerMask((*byte)(unsafe.Pointer(md.gcdata)), scanDataSize)
+ scanBSSSize := md.ebss - md.bss
+ md.gcbssmask = progToPointerMask((*byte)(unsafe.Pointer(md.gcbss)), scanBSSSize)
+ gcController.addGlobals(int64(scanDataSize + scanBSSSize))
+ }
+ }
+
+ // Modules appear in the moduledata linked list in the order they are
+ // loaded by the dynamic loader, with one exception: the
+ // firstmoduledata itself the module that contains the runtime. This
+ // is not always the first module (when using -buildmode=shared, it
+ // is typically libstd.so, the second module). The order matters for
+ // typelinksinit, so we swap the first module with whatever module
+ // contains the main function.
+ //
+ // See Issue #18729.
+ for i, md := range *modules {
+ if md.hasmain != 0 {
+ (*modules)[0] = md
+ (*modules)[i] = &firstmoduledata
+ break
+ }
+ }
+
+ atomicstorep(unsafe.Pointer(&modulesSlice), unsafe.Pointer(modules))
+}
+
+type functab struct {
+ entryoff uint32 // relative to runtime.text
+ funcoff uint32
+}
+
+// Mapping information for secondary text sections
+
+type textsect struct {
+ vaddr uintptr // prelinked section vaddr
+ end uintptr // vaddr + section length
+ baseaddr uintptr // relocated section address
+}
+
+const minfunc = 16 // minimum function size
+const pcbucketsize = 256 * minfunc // size of bucket in the pc->func lookup table
+
+// findfuncbucket is an array of these structures.
+// Each bucket represents 4096 bytes of the text segment.
+// Each subbucket represents 256 bytes of the text segment.
+// To find a function given a pc, locate the bucket and subbucket for
+// that pc. Add together the idx and subbucket value to obtain a
+// function index. Then scan the functab array starting at that
+// index to find the target function.
+// This table uses 20 bytes for every 4096 bytes of code, or ~0.5% overhead.
+type findfuncbucket struct {
+ idx uint32
+ subbuckets [16]byte
+}
+
+func moduledataverify() {
+ for datap := &firstmoduledata; datap != nil; datap = datap.next {
+ moduledataverify1(datap)
+ }
+}
+
+const debugPcln = false
+
+func moduledataverify1(datap *moduledata) {
+ // Check that the pclntab's format is valid.
+ hdr := datap.pcHeader
+ if hdr.magic != 0xfffffff1 || hdr.pad1 != 0 || hdr.pad2 != 0 ||
+ hdr.minLC != sys.PCQuantum || hdr.ptrSize != goarch.PtrSize || hdr.textStart != datap.text {
+ println("runtime: pcHeader: magic=", hex(hdr.magic), "pad1=", hdr.pad1, "pad2=", hdr.pad2,
+ "minLC=", hdr.minLC, "ptrSize=", hdr.ptrSize, "pcHeader.textStart=", hex(hdr.textStart),
+ "text=", hex(datap.text), "pluginpath=", datap.pluginpath)
+ throw("invalid function symbol table")
+ }
+
+ // ftab is lookup table for function by program counter.
+ nftab := len(datap.ftab) - 1
+ for i := 0; i < nftab; i++ {
+ // NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
+ if datap.ftab[i].entryoff > datap.ftab[i+1].entryoff {
+ f1 := funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i].funcoff])), datap}
+ f2 := funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[i+1].funcoff])), datap}
+ f2name := "end"
+ if i+1 < nftab {
+ f2name = funcname(f2)
+ }
+ println("function symbol table not sorted by PC offset:", hex(datap.ftab[i].entryoff), funcname(f1), ">", hex(datap.ftab[i+1].entryoff), f2name, ", plugin:", datap.pluginpath)
+ for j := 0; j <= i; j++ {
+ println("\t", hex(datap.ftab[j].entryoff), funcname(funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[j].funcoff])), datap}))
+ }
+ if GOOS == "aix" && isarchive {
+ println("-Wl,-bnoobjreorder is mandatory on aix/ppc64 with c-archive")
+ }
+ throw("invalid runtime symbol table")
+ }
+ }
+
+ min := datap.textAddr(datap.ftab[0].entryoff)
+ max := datap.textAddr(datap.ftab[nftab].entryoff)
+ if datap.minpc != min || datap.maxpc != max {
+ println("minpc=", hex(datap.minpc), "min=", hex(min), "maxpc=", hex(datap.maxpc), "max=", hex(max))
+ throw("minpc or maxpc invalid")
+ }
+
+ for _, modulehash := range datap.modulehashes {
+ if modulehash.linktimehash != *modulehash.runtimehash {
+ println("abi mismatch detected between", datap.modulename, "and", modulehash.modulename)
+ throw("abi mismatch")
+ }
+ }
+}
+
+// textAddr returns md.text + off, with special handling for multiple text sections.
+// off is a (virtual) offset computed at internal linking time,
+// before the external linker adjusts the sections' base addresses.
+//
+// The text, or instruction stream is generated as one large buffer.
+// The off (offset) for a function is its offset within this buffer.
+// If the total text size gets too large, there can be issues on platforms like ppc64
+// if the target of calls are too far for the call instruction.
+// To resolve the large text issue, the text is split into multiple text sections
+// to allow the linker to generate long calls when necessary.
+// When this happens, the vaddr for each text section is set to its offset within the text.
+// Each function's offset is compared against the section vaddrs and ends to determine the containing section.
+// Then the section relative offset is added to the section's
+// relocated baseaddr to compute the function address.
+//
+// It is nosplit because it is part of the findfunc implementation.
+//
+//go:nosplit
+func (md *moduledata) textAddr(off32 uint32) uintptr {
+ off := uintptr(off32)
+ res := md.text + off
+ if len(md.textsectmap) > 1 {
+ for i, sect := range md.textsectmap {
+ // For the last section, include the end address (etext), as it is included in the functab.
+ if off >= sect.vaddr && off < sect.end || (i == len(md.textsectmap)-1 && off == sect.end) {
+ res = sect.baseaddr + off - sect.vaddr
+ break
+ }
+ }
+ if res > md.etext && GOARCH != "wasm" { // on wasm, functions do not live in the same address space as the linear memory
+ println("runtime: textAddr", hex(res), "out of range", hex(md.text), "-", hex(md.etext))
+ throw("runtime: text offset out of range")
+ }
+ }
+ return res
+}
+
+// textOff is the opposite of textAddr. It converts a PC to a (virtual) offset
+// to md.text, and returns if the PC is in any Go text section.
+//
+// It is nosplit because it is part of the findfunc implementation.
+//
+//go:nosplit
+func (md *moduledata) textOff(pc uintptr) (uint32, bool) {
+ res := uint32(pc - md.text)
+ if len(md.textsectmap) > 1 {
+ for i, sect := range md.textsectmap {
+ if sect.baseaddr > pc {
+ // pc is not in any section.
+ return 0, false
+ }
+ end := sect.baseaddr + (sect.end - sect.vaddr)
+ // For the last section, include the end address (etext), as it is included in the functab.
+ if i == len(md.textsectmap) {
+ end++
+ }
+ if pc < end {
+ res = uint32(pc - sect.baseaddr + sect.vaddr)
+ break
+ }
+ }
+ }
+ return res, true
+}
+
+// funcName returns the string at nameOff in the function name table.
+func (md *moduledata) funcName(nameOff int32) string {
+ if nameOff == 0 {
+ return ""
+ }
+ return gostringnocopy(&md.funcnametab[nameOff])
+}
+
+// FuncForPC returns a *Func describing the function that contains the
+// given program counter address, or else nil.
+//
+// If pc represents multiple functions because of inlining, it returns
+// the *Func describing the innermost function, but with an entry of
+// the outermost function.
+func FuncForPC(pc uintptr) *Func {
+ f := findfunc(pc)
+ if !f.valid() {
+ return nil
+ }
+ // This must interpret PC non-strictly so bad PCs (those between functions) don't crash the runtime.
+ // We just report the preceding function in that situation. See issue 29735.
+ // TODO: Perhaps we should report no function at all in that case.
+ // The runtime currently doesn't have function end info, alas.
+ u, uf := newInlineUnwinder(f, pc, nil)
+ if !u.isInlined(uf) {
+ return f._Func()
+ }
+ sf := u.srcFunc(uf)
+ file, line := u.fileLine(uf)
+ fi := &funcinl{
+ ones: ^uint32(0),
+ entry: f.entry(), // entry of the real (the outermost) function.
+ name: sf.name(),
+ file: file,
+ line: int32(line),
+ startLine: sf.startLine,
+ }
+ return (*Func)(unsafe.Pointer(fi))
+}
+
+// Name returns the name of the function.
+func (f *Func) Name() string {
+ if f == nil {
+ return ""
+ }
+ fn := f.raw()
+ if fn.isInlined() { // inlined version
+ fi := (*funcinl)(unsafe.Pointer(fn))
+ return funcNameForPrint(fi.name)
+ }
+ return funcNameForPrint(funcname(f.funcInfo()))
+}
+
+// Entry returns the entry address of the function.
+func (f *Func) Entry() uintptr {
+ fn := f.raw()
+ if fn.isInlined() { // inlined version
+ fi := (*funcinl)(unsafe.Pointer(fn))
+ return fi.entry
+ }
+ return fn.funcInfo().entry()
+}
+
+// FileLine returns the file name and line number of the
+// source code corresponding to the program counter pc.
+// The result will not be accurate if pc is not a program
+// counter within f.
+func (f *Func) FileLine(pc uintptr) (file string, line int) {
+ fn := f.raw()
+ if fn.isInlined() { // inlined version
+ fi := (*funcinl)(unsafe.Pointer(fn))
+ return fi.file, int(fi.line)
+ }
+ // Pass strict=false here, because anyone can call this function,
+ // and they might just be wrong about targetpc belonging to f.
+ file, line32 := funcline1(f.funcInfo(), pc, false)
+ return file, int(line32)
+}
+
+// startLine returns the starting line number of the function. i.e., the line
+// number of the func keyword.
+func (f *Func) startLine() int32 {
+ fn := f.raw()
+ if fn.isInlined() { // inlined version
+ fi := (*funcinl)(unsafe.Pointer(fn))
+ return fi.startLine
+ }
+ return fn.funcInfo().startLine
+}
+
+// findmoduledatap looks up the moduledata for a PC.
+//
+// It is nosplit because it's part of the isgoexception
+// implementation.
+//
+//go:nosplit
+func findmoduledatap(pc uintptr) *moduledata {
+ for datap := &firstmoduledata; datap != nil; datap = datap.next {
+ if datap.minpc <= pc && pc < datap.maxpc {
+ return datap
+ }
+ }
+ return nil
+}
+
+type funcInfo struct {
+ *_func
+ datap *moduledata
+}
+
+func (f funcInfo) valid() bool {
+ return f._func != nil
+}
+
+func (f funcInfo) _Func() *Func {
+ return (*Func)(unsafe.Pointer(f._func))
+}
+
+// isInlined reports whether f should be re-interpreted as a *funcinl.
+func (f *_func) isInlined() bool {
+ return f.entryOff == ^uint32(0) // see comment for funcinl.ones
+}
+
+// entry returns the entry PC for f.
+func (f funcInfo) entry() uintptr {
+ return f.datap.textAddr(f.entryOff)
+}
+
+// findfunc looks up function metadata for a PC.
+//
+// It is nosplit because it's part of the isgoexception
+// implementation.
+//
+//go:nosplit
+func findfunc(pc uintptr) funcInfo {
+ datap := findmoduledatap(pc)
+ if datap == nil {
+ return funcInfo{}
+ }
+ const nsub = uintptr(len(findfuncbucket{}.subbuckets))
+
+ pcOff, ok := datap.textOff(pc)
+ if !ok {
+ return funcInfo{}
+ }
+
+ x := uintptr(pcOff) + datap.text - datap.minpc // TODO: are datap.text and datap.minpc always equal?
+ b := x / pcbucketsize
+ i := x % pcbucketsize / (pcbucketsize / nsub)
+
+ ffb := (*findfuncbucket)(add(unsafe.Pointer(datap.findfunctab), b*unsafe.Sizeof(findfuncbucket{})))
+ idx := ffb.idx + uint32(ffb.subbuckets[i])
+
+ // Find the ftab entry.
+ for datap.ftab[idx+1].entryoff <= pcOff {
+ idx++
+ }
+
+ funcoff := datap.ftab[idx].funcoff
+ return funcInfo{(*_func)(unsafe.Pointer(&datap.pclntable[funcoff])), datap}
+}
+
+// A srcFunc represents a logical function in the source code. This may
+// correspond to an actual symbol in the binary text, or it may correspond to a
+// source function that has been inlined.
+type srcFunc struct {
+ datap *moduledata
+ nameOff int32
+ startLine int32
+ funcID abi.FuncID
+}
+
+func (f funcInfo) srcFunc() srcFunc {
+ if !f.valid() {
+ return srcFunc{}
+ }
+ return srcFunc{f.datap, f.nameOff, f.startLine, f.funcID}
+}
+
+func (s srcFunc) name() string {
+ if s.datap == nil {
+ return ""
+ }
+ return s.datap.funcName(s.nameOff)
+}
+
+type pcvalueCache struct {
+ entries [2][8]pcvalueCacheEnt
+}
+
+type pcvalueCacheEnt struct {
+ // targetpc and off together are the key of this cache entry.
+ targetpc uintptr
+ off uint32
+ // val is the value of this cached pcvalue entry.
+ val int32
+}
+
+// pcvalueCacheKey returns the outermost index in a pcvalueCache to use for targetpc.
+// It must be very cheap to calculate.
+// For now, align to goarch.PtrSize and reduce mod the number of entries.
+// In practice, this appears to be fairly randomly and evenly distributed.
+func pcvalueCacheKey(targetpc uintptr) uintptr {
+ return (targetpc / goarch.PtrSize) % uintptr(len(pcvalueCache{}.entries))
+}
+
+// Returns the PCData value, and the PC where this value starts.
+// TODO: the start PC is returned only when cache is nil.
+func pcvalue(f funcInfo, off uint32, targetpc uintptr, cache *pcvalueCache, strict bool) (int32, uintptr) {
+ if off == 0 {
+ return -1, 0
+ }
+
+ // Check the cache. This speeds up walks of deep stacks, which
+ // tend to have the same recursive functions over and over.
+ //
+ // This cache is small enough that full associativity is
+ // cheaper than doing the hashing for a less associative
+ // cache.
+ if cache != nil {
+ x := pcvalueCacheKey(targetpc)
+ for i := range cache.entries[x] {
+ // We check off first because we're more
+ // likely to have multiple entries with
+ // different offsets for the same targetpc
+ // than the other way around, so we'll usually
+ // fail in the first clause.
+ ent := &cache.entries[x][i]
+ if ent.off == off && ent.targetpc == targetpc {
+ return ent.val, 0
+ }
+ }
+ }
+
+ if !f.valid() {
+ if strict && panicking.Load() == 0 {
+ println("runtime: no module data for", hex(f.entry()))
+ throw("no module data")
+ }
+ return -1, 0
+ }
+ datap := f.datap
+ p := datap.pctab[off:]
+ pc := f.entry()
+ prevpc := pc
+ val := int32(-1)
+ for {
+ var ok bool
+ p, ok = step(p, &pc, &val, pc == f.entry())
+ if !ok {
+ break
+ }
+ if targetpc < pc {
+ // Replace a random entry in the cache. Random
+ // replacement prevents a performance cliff if
+ // a recursive stack's cycle is slightly
+ // larger than the cache.
+ // Put the new element at the beginning,
+ // since it is the most likely to be newly used.
+ if cache != nil {
+ x := pcvalueCacheKey(targetpc)
+ e := &cache.entries[x]
+ ci := fastrandn(uint32(len(cache.entries[x])))
+ e[ci] = e[0]
+ e[0] = pcvalueCacheEnt{
+ targetpc: targetpc,
+ off: off,
+ val: val,
+ }
+ }
+
+ return val, prevpc
+ }
+ prevpc = pc
+ }
+
+ // If there was a table, it should have covered all program counters.
+ // If not, something is wrong.
+ if panicking.Load() != 0 || !strict {
+ return -1, 0
+ }
+
+ print("runtime: invalid pc-encoded table f=", funcname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")
+
+ p = datap.pctab[off:]
+ pc = f.entry()
+ val = -1
+ for {
+ var ok bool
+ p, ok = step(p, &pc, &val, pc == f.entry())
+ if !ok {
+ break
+ }
+ print("\tvalue=", val, " until pc=", hex(pc), "\n")
+ }
+
+ throw("invalid runtime symbol table")
+ return -1, 0
+}
+
+func funcname(f funcInfo) string {
+ if !f.valid() {
+ return ""
+ }
+ return f.datap.funcName(f.nameOff)
+}
+
+func funcpkgpath(f funcInfo) string {
+ name := funcNameForPrint(funcname(f))
+ i := len(name) - 1
+ for ; i > 0; i-- {
+ if name[i] == '/' {
+ break
+ }
+ }
+ for ; i < len(name); i++ {
+ if name[i] == '.' {
+ break
+ }
+ }
+ return name[:i]
+}
+
+func funcfile(f funcInfo, fileno int32) string {
+ datap := f.datap
+ if !f.valid() {
+ return "?"
+ }
+ // Make sure the cu index and file offset are valid
+ if fileoff := datap.cutab[f.cuOffset+uint32(fileno)]; fileoff != ^uint32(0) {
+ return gostringnocopy(&datap.filetab[fileoff])
+ }
+ // pcln section is corrupt.
+ return "?"
+}
+
+func funcline1(f funcInfo, targetpc uintptr, strict bool) (file string, line int32) {
+ datap := f.datap
+ if !f.valid() {
+ return "?", 0
+ }
+ fileno, _ := pcvalue(f, f.pcfile, targetpc, nil, strict)
+ line, _ = pcvalue(f, f.pcln, targetpc, nil, strict)
+ if fileno == -1 || line == -1 || int(fileno) >= len(datap.filetab) {
+ // print("looking for ", hex(targetpc), " in ", funcname(f), " got file=", fileno, " line=", lineno, "\n")
+ return "?", 0
+ }
+ file = funcfile(f, fileno)
+ return
+}
+
+func funcline(f funcInfo, targetpc uintptr) (file string, line int32) {
+ return funcline1(f, targetpc, true)
+}
+
+func funcspdelta(f funcInfo, targetpc uintptr, cache *pcvalueCache) int32 {
+ x, _ := pcvalue(f, f.pcsp, targetpc, cache, true)
+ if debugPcln && x&(goarch.PtrSize-1) != 0 {
+ print("invalid spdelta ", funcname(f), " ", hex(f.entry()), " ", hex(targetpc), " ", hex(f.pcsp), " ", x, "\n")
+ throw("bad spdelta")
+ }
+ return x
+}
+
+// funcMaxSPDelta returns the maximum spdelta at any point in f.
+func funcMaxSPDelta(f funcInfo) int32 {
+ datap := f.datap
+ p := datap.pctab[f.pcsp:]
+ pc := f.entry()
+ val := int32(-1)
+ max := int32(0)
+ for {
+ var ok bool
+ p, ok = step(p, &pc, &val, pc == f.entry())
+ if !ok {
+ return max
+ }
+ if val > max {
+ max = val
+ }
+ }
+}
+
+func pcdatastart(f funcInfo, table uint32) uint32 {
+ return *(*uint32)(add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(table)*4))
+}
+
+func pcdatavalue(f funcInfo, table uint32, targetpc uintptr, cache *pcvalueCache) int32 {
+ if table >= f.npcdata {
+ return -1
+ }
+ r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, true)
+ return r
+}
+
+func pcdatavalue1(f funcInfo, table uint32, targetpc uintptr, cache *pcvalueCache, strict bool) int32 {
+ if table >= f.npcdata {
+ return -1
+ }
+ r, _ := pcvalue(f, pcdatastart(f, table), targetpc, cache, strict)
+ return r
+}
+
+// Like pcdatavalue, but also return the start PC of this PCData value.
+// It doesn't take a cache.
+func pcdatavalue2(f funcInfo, table uint32, targetpc uintptr) (int32, uintptr) {
+ if table >= f.npcdata {
+ return -1, 0
+ }
+ return pcvalue(f, pcdatastart(f, table), targetpc, nil, true)
+}
+
+// funcdata returns a pointer to the ith funcdata for f.
+// funcdata should be kept in sync with cmd/link:writeFuncs.
+func funcdata(f funcInfo, i uint8) unsafe.Pointer {
+ if i < 0 || i >= f.nfuncdata {
+ return nil
+ }
+ base := f.datap.gofunc // load gofunc address early so that we calculate during cache misses
+ p := uintptr(unsafe.Pointer(&f.nfuncdata)) + unsafe.Sizeof(f.nfuncdata) + uintptr(f.npcdata)*4 + uintptr(i)*4
+ off := *(*uint32)(unsafe.Pointer(p))
+ // Return off == ^uint32(0) ? 0 : f.datap.gofunc + uintptr(off), but without branches.
+ // The compiler calculates mask on most architectures using conditional assignment.
+ var mask uintptr
+ if off == ^uint32(0) {
+ mask = 1
+ }
+ mask--
+ raw := base + uintptr(off)
+ return unsafe.Pointer(raw & mask)
+}
+
+// step advances to the next pc, value pair in the encoded table.
+func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) {
+ // For both uvdelta and pcdelta, the common case (~70%)
+ // is that they are a single byte. If so, avoid calling readvarint.
+ uvdelta := uint32(p[0])
+ if uvdelta == 0 && !first {
+ return nil, false
+ }
+ n := uint32(1)
+ if uvdelta&0x80 != 0 {
+ n, uvdelta = readvarint(p)
+ }
+ *val += int32(-(uvdelta & 1) ^ (uvdelta >> 1))
+ p = p[n:]
+
+ pcdelta := uint32(p[0])
+ n = 1
+ if pcdelta&0x80 != 0 {
+ n, pcdelta = readvarint(p)
+ }
+ p = p[n:]
+ *pc += uintptr(pcdelta * sys.PCQuantum)
+ return p, true
+}
+
+// readvarint reads a varint from p.
+func readvarint(p []byte) (read uint32, val uint32) {
+ var v, shift, n uint32
+ for {
+ b := p[n]
+ n++
+ v |= uint32(b&0x7F) << (shift & 31)
+ if b&0x80 == 0 {
+ break
+ }
+ shift += 7
+ }
+ return n, v
+}
+
+type stackmap struct {
+ n int32 // number of bitmaps
+ nbit int32 // number of bits in each bitmap
+ bytedata [1]byte // bitmaps, each starting on a byte boundary
+}
+
+//go:nowritebarrier
+func stackmapdata(stkmap *stackmap, n int32) bitvector {
+ // Check this invariant only when stackDebug is on at all.
+ // The invariant is already checked by many of stackmapdata's callers,
+ // and disabling it by default allows stackmapdata to be inlined.
+ if stackDebug > 0 && (n < 0 || n >= stkmap.n) {
+ throw("stackmapdata: index out of range")
+ }
+ return bitvector{stkmap.nbit, addb(&stkmap.bytedata[0], uintptr(n*((stkmap.nbit+7)>>3)))}
+}
diff --git a/contrib/go/_std_1.21/src/runtime/symtabinl.go b/contrib/go/_std_1.21/src/runtime/symtabinl.go
new file mode 100644
index 0000000000..2bb1c4bc6a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/symtabinl.go
@@ -0,0 +1,116 @@
+// Copyright 2023 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 runtime
+
+import "internal/abi"
+
+// inlinedCall is the encoding of entries in the FUNCDATA_InlTree table.
+type inlinedCall struct {
+ funcID abi.FuncID // type of the called function
+ _ [3]byte
+ nameOff int32 // offset into pclntab for name of called function
+ parentPc int32 // position of an instruction whose source position is the call site (offset from entry)
+ startLine int32 // line number of start of function (func keyword/TEXT directive)
+}
+
+// An inlineUnwinder iterates over the stack of inlined calls at a PC by
+// decoding the inline table. The last step of iteration is always the frame of
+// the physical function, so there's always at least one frame.
+//
+// This is typically used as:
+//
+// for u, uf := newInlineUnwinder(...); uf.valid(); uf = u.next(uf) { ... }
+//
+// Implementation note: This is used in contexts that disallow write barriers.
+// Hence, the constructor returns this by value and pointer receiver methods
+// must not mutate pointer fields. Also, we keep the mutable state in a separate
+// struct mostly to keep both structs SSA-able, which generates much better
+// code.
+type inlineUnwinder struct {
+ f funcInfo
+ cache *pcvalueCache
+ inlTree *[1 << 20]inlinedCall
+}
+
+// An inlineFrame is a position in an inlineUnwinder.
+type inlineFrame struct {
+ // pc is the PC giving the file/line metadata of the current frame. This is
+ // always a "call PC" (not a "return PC"). This is 0 when the iterator is
+ // exhausted.
+ pc uintptr
+
+ // index is the index of the current record in inlTree, or -1 if we are in
+ // the outermost function.
+ index int32
+}
+
+// newInlineUnwinder creates an inlineUnwinder initially set to the inner-most
+// inlined frame at PC. PC should be a "call PC" (not a "return PC").
+//
+// This unwinder uses non-strict handling of PC because it's assumed this is
+// only ever used for symbolic debugging. If things go really wrong, it'll just
+// fall back to the outermost frame.
+func newInlineUnwinder(f funcInfo, pc uintptr, cache *pcvalueCache) (inlineUnwinder, inlineFrame) {
+ inldata := funcdata(f, abi.FUNCDATA_InlTree)
+ if inldata == nil {
+ return inlineUnwinder{f: f}, inlineFrame{pc: pc, index: -1}
+ }
+ inlTree := (*[1 << 20]inlinedCall)(inldata)
+ u := inlineUnwinder{f: f, cache: cache, inlTree: inlTree}
+ return u, u.resolveInternal(pc)
+}
+
+func (u *inlineUnwinder) resolveInternal(pc uintptr) inlineFrame {
+ return inlineFrame{
+ pc: pc,
+ // Conveniently, this returns -1 if there's an error, which is the same
+ // value we use for the outermost frame.
+ index: pcdatavalue1(u.f, abi.PCDATA_InlTreeIndex, pc, u.cache, false),
+ }
+}
+
+func (uf inlineFrame) valid() bool {
+ return uf.pc != 0
+}
+
+// next returns the frame representing uf's logical caller.
+func (u *inlineUnwinder) next(uf inlineFrame) inlineFrame {
+ if uf.index < 0 {
+ uf.pc = 0
+ return uf
+ }
+ parentPc := u.inlTree[uf.index].parentPc
+ return u.resolveInternal(u.f.entry() + uintptr(parentPc))
+}
+
+// isInlined returns whether uf is an inlined frame.
+func (u *inlineUnwinder) isInlined(uf inlineFrame) bool {
+ return uf.index >= 0
+}
+
+// srcFunc returns the srcFunc representing the given frame.
+func (u *inlineUnwinder) srcFunc(uf inlineFrame) srcFunc {
+ if uf.index < 0 {
+ return u.f.srcFunc()
+ }
+ t := &u.inlTree[uf.index]
+ return srcFunc{
+ u.f.datap,
+ t.nameOff,
+ t.startLine,
+ t.funcID,
+ }
+}
+
+// fileLine returns the file name and line number of the call within the given
+// frame. As a convenience, for the innermost frame, it returns the file and
+// line of the PC this unwinder was started at (often this is a call to another
+// physical function).
+//
+// It returns "?", 0 if something goes wrong.
+func (u *inlineUnwinder) fileLine(uf inlineFrame) (file string, line int) {
+ file, line32 := funcline1(u.f, uf.pc, false)
+ return file, int(line32)
+}
diff --git a/contrib/go/_std_1.20/src/runtime/sys_arm64.go b/contrib/go/_std_1.21/src/runtime/sys_arm64.go
index 230241d5f2..230241d5f2 100644
--- a/contrib/go/_std_1.20/src/runtime/sys_arm64.go
+++ b/contrib/go/_std_1.21/src/runtime/sys_arm64.go
diff --git a/contrib/go/_std_1.21/src/runtime/sys_darwin.go b/contrib/go/_std_1.21/src/runtime/sys_darwin.go
new file mode 100644
index 0000000000..fa9a2fbd52
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/sys_darwin.go
@@ -0,0 +1,603 @@
+// Copyright 2018 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 runtime
+
+import (
+ "internal/abi"
+ "runtime/internal/atomic"
+ "unsafe"
+)
+
+// The X versions of syscall expect the libc call to return a 64-bit result.
+// Otherwise (the non-X version) expects a 32-bit result.
+// This distinction is required because an error is indicated by returning -1,
+// and we need to know whether to check 32 or 64 bits of the result.
+// (Some libc functions that return 32 bits put junk in the upper 32 bits of AX.)
+
+//go:linkname syscall_syscall syscall.syscall
+//go:nosplit
+func syscall_syscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
+ args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err}
+ entersyscall()
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&args))
+ exitsyscall()
+ return args.r1, args.r2, args.err
+}
+func syscall()
+
+//go:linkname syscall_syscallX syscall.syscallX
+//go:nosplit
+func syscall_syscallX(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
+ args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err}
+ entersyscall()
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallX)), unsafe.Pointer(&args))
+ exitsyscall()
+ return args.r1, args.r2, args.err
+}
+func syscallX()
+
+//go:linkname syscall_syscall6 syscall.syscall6
+//go:nosplit
+func syscall_syscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
+ args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2, err}
+ entersyscall()
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&args))
+ exitsyscall()
+ return args.r1, args.r2, args.err
+}
+func syscall6()
+
+//go:linkname syscall_syscall9 syscall.syscall9
+//go:nosplit
+//go:cgo_unsafe_args
+func syscall_syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
+ entersyscall()
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall9)), unsafe.Pointer(&fn))
+ exitsyscall()
+ return
+}
+func syscall9()
+
+//go:linkname syscall_syscall6X syscall.syscall6X
+//go:nosplit
+func syscall_syscall6X(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
+ args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2, err}
+ entersyscall()
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6X)), unsafe.Pointer(&args))
+ exitsyscall()
+ return args.r1, args.r2, args.err
+}
+func syscall6X()
+
+//go:linkname syscall_syscallPtr syscall.syscallPtr
+//go:nosplit
+func syscall_syscallPtr(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
+ args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err}
+ entersyscall()
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(syscallPtr)), unsafe.Pointer(&args))
+ exitsyscall()
+ return args.r1, args.r2, args.err
+}
+func syscallPtr()
+
+//go:linkname syscall_rawSyscall syscall.rawSyscall
+//go:nosplit
+func syscall_rawSyscall(fn, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
+ args := struct{ fn, a1, a2, a3, r1, r2, err uintptr }{fn, a1, a2, a3, r1, r2, err}
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall)), unsafe.Pointer(&args))
+ return args.r1, args.r2, args.err
+}
+
+//go:linkname syscall_rawSyscall6 syscall.rawSyscall6
+//go:nosplit
+func syscall_rawSyscall6(fn, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
+ args := struct{ fn, a1, a2, a3, a4, a5, a6, r1, r2, err uintptr }{fn, a1, a2, a3, a4, a5, a6, r1, r2, err}
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall6)), unsafe.Pointer(&args))
+ return args.r1, args.r2, args.err
+}
+
+// crypto_x509_syscall is used in crypto/x509/internal/macos to call into Security.framework and CF.
+
+//go:linkname crypto_x509_syscall crypto/x509/internal/macos.syscall
+//go:nosplit
+func crypto_x509_syscall(fn, a1, a2, a3, a4, a5 uintptr, f1 float64) (r1 uintptr) {
+ args := struct {
+ fn, a1, a2, a3, a4, a5 uintptr
+ f1 float64
+ r1 uintptr
+ }{fn, a1, a2, a3, a4, a5, f1, r1}
+ entersyscall()
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(syscall_x509)), unsafe.Pointer(&args))
+ exitsyscall()
+ return args.r1
+}
+func syscall_x509()
+
+// The *_trampoline functions convert from the Go calling convention to the C calling convention
+// and then call the underlying libc function. They are defined in sys_darwin_$ARCH.s.
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_attr_init(attr *pthreadattr) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_init_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ return ret
+}
+func pthread_attr_init_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_attr_getstacksize(attr *pthreadattr, size *uintptr) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_getstacksize_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ KeepAlive(size)
+ return ret
+}
+func pthread_attr_getstacksize_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_attr_setdetachstate(attr *pthreadattr, state int) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_attr_setdetachstate_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ return ret
+}
+func pthread_attr_setdetachstate_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_create(attr *pthreadattr, start uintptr, arg unsafe.Pointer) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_create_trampoline)), unsafe.Pointer(&attr))
+ KeepAlive(attr)
+ KeepAlive(arg) // Just for consistency. Arg of course needs to be kept alive for the start function.
+ return ret
+}
+func pthread_create_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func raise(sig uint32) {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(raise_trampoline)), unsafe.Pointer(&sig))
+}
+func raise_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_self() (t pthread) {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_self_trampoline)), unsafe.Pointer(&t))
+ return
+}
+func pthread_self_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_kill(t pthread, sig uint32) {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_kill_trampoline)), unsafe.Pointer(&t))
+ return
+}
+func pthread_kill_trampoline()
+
+// osinit_hack is a clumsy hack to work around Apple libc bugs
+// causing fork+exec to hang in the child process intermittently.
+// See go.dev/issue/33565 and go.dev/issue/56784 for a few reports.
+//
+// The stacks obtained from the hung child processes are in
+// libSystem_atfork_child, which is supposed to reinitialize various
+// parts of the C library in the new process.
+//
+// One common stack dies in _notify_fork_child calling _notify_globals
+// (inlined) calling _os_alloc_once, because _os_alloc_once detects that
+// the once lock is held by the parent process and then calls
+// _os_once_gate_corruption_abort. The allocation is setting up the
+// globals for the notification subsystem. See the source code at [1].
+// To work around this, we can allocate the globals earlier in the Go
+// program's lifetime, before any execs are involved, by calling any
+// notify routine that is exported, calls _notify_globals, and doesn't do
+// anything too expensive otherwise. notify_is_valid_token(0) fits the bill.
+//
+// The other common stack dies in xpc_atfork_child calling
+// _objc_msgSend_uncached which ends up in
+// WAITING_FOR_ANOTHER_THREAD_TO_FINISH_CALLING_+initialize. Of course,
+// whatever thread the child is waiting for is in the parent process and
+// is not going to finish anything in the child process. There is no
+// public source code for these routines, so it is unclear exactly what
+// the problem is. An Apple engineer suggests using xpc_date_create_from_current,
+// which empirically does fix the problem.
+//
+// So osinit_hack_trampoline (in sys_darwin_$GOARCH.s) calls
+// notify_is_valid_token(0) and xpc_date_create_from_current(), which makes the
+// fork+exec hangs stop happening. If Apple fixes the libc bug in
+// some future version of macOS, then we can remove this awful code.
+//
+//go:nosplit
+func osinit_hack() {
+ if GOOS == "darwin" { // not ios
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(osinit_hack_trampoline)), nil)
+ }
+ return
+}
+func osinit_hack_trampoline()
+
+// mmap is used to do low-level memory allocation via mmap. Don't allow stack
+// splits, since this function (used by sysAlloc) is called in a lot of low-level
+// parts of the runtime and callers often assume it won't acquire any locks.
+//
+//go:nosplit
+func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
+ args := struct {
+ addr unsafe.Pointer
+ n uintptr
+ prot, flags, fd int32
+ off uint32
+ ret1 unsafe.Pointer
+ ret2 int
+ }{addr, n, prot, flags, fd, off, nil, 0}
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(mmap_trampoline)), unsafe.Pointer(&args))
+ return args.ret1, args.ret2
+}
+func mmap_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func munmap(addr unsafe.Pointer, n uintptr) {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(munmap_trampoline)), unsafe.Pointer(&addr))
+ KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
+}
+func munmap_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(madvise_trampoline)), unsafe.Pointer(&addr))
+ KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
+}
+func madvise_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func mlock(addr unsafe.Pointer, n uintptr) {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(mlock_trampoline)), unsafe.Pointer(&addr))
+ KeepAlive(addr) // Just for consistency. Hopefully addr is not a Go address.
+}
+func mlock_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func read(fd int32, p unsafe.Pointer, n int32) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(read_trampoline)), unsafe.Pointer(&fd))
+ KeepAlive(p)
+ return ret
+}
+func read_trampoline()
+
+func pipe() (r, w int32, errno int32) {
+ var p [2]int32
+ errno = libcCall(unsafe.Pointer(abi.FuncPCABI0(pipe_trampoline)), noescape(unsafe.Pointer(&p)))
+ return p[0], p[1], errno
+}
+func pipe_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func closefd(fd int32) int32 {
+ return libcCall(unsafe.Pointer(abi.FuncPCABI0(close_trampoline)), unsafe.Pointer(&fd))
+}
+func close_trampoline()
+
+// This is exported via linkname to assembly in runtime/cgo.
+//
+//go:nosplit
+//go:cgo_unsafe_args
+//go:linkname exit
+func exit(code int32) {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(exit_trampoline)), unsafe.Pointer(&code))
+}
+func exit_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func usleep(usec uint32) {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec))
+}
+func usleep_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func usleep_no_g(usec uint32) {
+ asmcgocall_no_g(unsafe.Pointer(abi.FuncPCABI0(usleep_trampoline)), unsafe.Pointer(&usec))
+}
+
+//go:nosplit
+//go:cgo_unsafe_args
+func write1(fd uintptr, p unsafe.Pointer, n int32) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(write_trampoline)), unsafe.Pointer(&fd))
+ KeepAlive(p)
+ return ret
+}
+func write_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func open(name *byte, mode, perm int32) (ret int32) {
+ ret = libcCall(unsafe.Pointer(abi.FuncPCABI0(open_trampoline)), unsafe.Pointer(&name))
+ KeepAlive(name)
+ return
+}
+func open_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func nanotime1() int64 {
+ var r struct {
+ t int64 // raw timer
+ numer, denom uint32 // conversion factors. nanoseconds = t * numer / denom.
+ }
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(nanotime_trampoline)), unsafe.Pointer(&r))
+ // Note: Apple seems unconcerned about overflow here. See
+ // https://developer.apple.com/library/content/qa/qa1398/_index.html
+ // Note also, numer == denom == 1 is common.
+ t := r.t
+ if r.numer != 1 {
+ t *= int64(r.numer)
+ }
+ if r.denom != 1 {
+ t /= int64(r.denom)
+ }
+ return t
+}
+func nanotime_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func walltime() (int64, int32) {
+ var t timespec
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(walltime_trampoline)), unsafe.Pointer(&t))
+ return t.tv_sec, int32(t.tv_nsec)
+}
+func walltime_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func sigaction(sig uint32, new *usigactiont, old *usigactiont) {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaction_trampoline)), unsafe.Pointer(&sig))
+ KeepAlive(new)
+ KeepAlive(old)
+}
+func sigaction_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func sigprocmask(how uint32, new *sigset, old *sigset) {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(sigprocmask_trampoline)), unsafe.Pointer(&how))
+ KeepAlive(new)
+ KeepAlive(old)
+}
+func sigprocmask_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func sigaltstack(new *stackt, old *stackt) {
+ if new != nil && new.ss_flags&_SS_DISABLE != 0 && new.ss_size == 0 {
+ // Despite the fact that Darwin's sigaltstack man page says it ignores the size
+ // when SS_DISABLE is set, it doesn't. sigaltstack returns ENOMEM
+ // if we don't give it a reasonable size.
+ // ref: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20140421/214296.html
+ new.ss_size = 32768
+ }
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(sigaltstack_trampoline)), unsafe.Pointer(&new))
+ KeepAlive(new)
+ KeepAlive(old)
+}
+func sigaltstack_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func raiseproc(sig uint32) {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(raiseproc_trampoline)), unsafe.Pointer(&sig))
+}
+func raiseproc_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func setitimer(mode int32, new, old *itimerval) {
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(setitimer_trampoline)), unsafe.Pointer(&mode))
+ KeepAlive(new)
+ KeepAlive(old)
+}
+func setitimer_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func sysctl(mib *uint32, miblen uint32, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctl_trampoline)), unsafe.Pointer(&mib))
+ KeepAlive(mib)
+ KeepAlive(oldp)
+ KeepAlive(oldlenp)
+ KeepAlive(newp)
+ return ret
+}
+func sysctl_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func sysctlbyname(name *byte, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(sysctlbyname_trampoline)), unsafe.Pointer(&name))
+ KeepAlive(name)
+ KeepAlive(oldp)
+ KeepAlive(oldlenp)
+ KeepAlive(newp)
+ return ret
+}
+func sysctlbyname_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
+ args := struct {
+ fd, cmd, arg int32
+ ret, errno int32
+ }{fd, cmd, arg, 0, 0}
+ libcCall(unsafe.Pointer(abi.FuncPCABI0(fcntl_trampoline)), unsafe.Pointer(&args))
+ return args.ret, args.errno
+}
+func fcntl_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func kqueue() int32 {
+ v := libcCall(unsafe.Pointer(abi.FuncPCABI0(kqueue_trampoline)), nil)
+ return v
+}
+func kqueue_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(kevent_trampoline)), unsafe.Pointer(&kq))
+ KeepAlive(ch)
+ KeepAlive(ev)
+ KeepAlive(ts)
+ return ret
+}
+func kevent_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_mutex_init(m *pthreadmutex, attr *pthreadmutexattr) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_init_trampoline)), unsafe.Pointer(&m))
+ KeepAlive(m)
+ KeepAlive(attr)
+ return ret
+}
+func pthread_mutex_init_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_mutex_lock(m *pthreadmutex) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_lock_trampoline)), unsafe.Pointer(&m))
+ KeepAlive(m)
+ return ret
+}
+func pthread_mutex_lock_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_mutex_unlock(m *pthreadmutex) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_mutex_unlock_trampoline)), unsafe.Pointer(&m))
+ KeepAlive(m)
+ return ret
+}
+func pthread_mutex_unlock_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_cond_init(c *pthreadcond, attr *pthreadcondattr) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_init_trampoline)), unsafe.Pointer(&c))
+ KeepAlive(c)
+ KeepAlive(attr)
+ return ret
+}
+func pthread_cond_init_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_cond_wait(c *pthreadcond, m *pthreadmutex) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_wait_trampoline)), unsafe.Pointer(&c))
+ KeepAlive(c)
+ KeepAlive(m)
+ return ret
+}
+func pthread_cond_wait_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_cond_timedwait_relative_np(c *pthreadcond, m *pthreadmutex, t *timespec) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_timedwait_relative_np_trampoline)), unsafe.Pointer(&c))
+ KeepAlive(c)
+ KeepAlive(m)
+ KeepAlive(t)
+ return ret
+}
+func pthread_cond_timedwait_relative_np_trampoline()
+
+//go:nosplit
+//go:cgo_unsafe_args
+func pthread_cond_signal(c *pthreadcond) int32 {
+ ret := libcCall(unsafe.Pointer(abi.FuncPCABI0(pthread_cond_signal_trampoline)), unsafe.Pointer(&c))
+ KeepAlive(c)
+ return ret
+}
+func pthread_cond_signal_trampoline()
+
+// Not used on Darwin, but must be defined.
+func exitThread(wait *atomic.Uint32) {
+ throw("exitThread")
+}
+
+//go:nosplit
+func setNonblock(fd int32) {
+ flags, _ := fcntl(fd, _F_GETFL, 0)
+ if flags != -1 {
+ fcntl(fd, _F_SETFL, flags|_O_NONBLOCK)
+ }
+}
+
+func issetugid() int32 {
+ return libcCall(unsafe.Pointer(abi.FuncPCABI0(issetugid_trampoline)), nil)
+}
+func issetugid_trampoline()
+
+// Tell the linker that the libc_* functions are to be found
+// in a system library, with the libc_ prefix missing.
+
+//go:cgo_import_dynamic libc_pthread_attr_init pthread_attr_init "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pthread_attr_getstacksize pthread_attr_getstacksize "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pthread_attr_setdetachstate pthread_attr_setdetachstate "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pthread_create pthread_create "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pthread_self pthread_self "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pthread_kill pthread_kill "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_exit _exit "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_raise raise "/usr/lib/libSystem.B.dylib"
+
+//go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib"
+
+//go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_madvise madvise "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_error __error "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_usleep usleep "/usr/lib/libSystem.B.dylib"
+
+//go:cgo_import_dynamic libc_mach_timebase_info mach_timebase_info "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_mach_absolute_time mach_absolute_time "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_sigaction sigaction "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pthread_sigmask pthread_sigmask "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_sigaltstack sigaltstack "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_setitimer setitimer "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_sysctlbyname sysctlbyname "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib"
+
+//go:cgo_import_dynamic libc_pthread_mutex_init pthread_mutex_init "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pthread_mutex_lock pthread_mutex_lock "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pthread_mutex_unlock pthread_mutex_unlock "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pthread_cond_init pthread_cond_init "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pthread_cond_wait pthread_cond_wait "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pthread_cond_timedwait_relative_np pthread_cond_timedwait_relative_np "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_pthread_cond_signal pthread_cond_signal "/usr/lib/libSystem.B.dylib"
+
+//go:cgo_import_dynamic libc_notify_is_valid_token notify_is_valid_token "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_xpc_date_create_from_current xpc_date_create_from_current "/usr/lib/libSystem.B.dylib"
+
+//go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib"
diff --git a/contrib/go/_std_1.21/src/runtime/sys_darwin_amd64.s b/contrib/go/_std_1.21/src/runtime/sys_darwin_amd64.s
new file mode 100644
index 0000000000..8e8ad9c8f7
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/sys_darwin_amd64.s
@@ -0,0 +1,798 @@
+// Copyright 2009 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.
+
+// System calls and other sys.stuff for AMD64, Darwin
+// System calls are implemented in libSystem, this file contains
+// trampolines that convert from Go to C calling convention.
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "textflag.h"
+#include "cgo/abi_amd64.h"
+
+#define CLOCK_REALTIME 0
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
+ MOVL 0(DI), DI // arg 1 exit status
+ CALL libc_exit(SB)
+ MOVL $0xf1, 0xf1 // crash
+ RET
+
+TEXT runtime·open_trampoline(SB),NOSPLIT,$0
+ MOVL 8(DI), SI // arg 2 flags
+ MOVL 12(DI), DX // arg 3 mode
+ MOVQ 0(DI), DI // arg 1 pathname
+ XORL AX, AX // vararg: say "no float args"
+ CALL libc_open(SB)
+ RET
+
+TEXT runtime·close_trampoline(SB),NOSPLIT,$0
+ MOVL 0(DI), DI // arg 1 fd
+ CALL libc_close(SB)
+ RET
+
+TEXT runtime·read_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 buf
+ MOVL 16(DI), DX // arg 3 count
+ MOVL 0(DI), DI // arg 1 fd
+ CALL libc_read(SB)
+ TESTL AX, AX
+ JGE noerr
+ CALL libc_error(SB)
+ MOVL (AX), AX
+ NEGL AX // caller expects negative errno value
+noerr:
+ RET
+
+TEXT runtime·write_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 buf
+ MOVL 16(DI), DX // arg 3 count
+ MOVQ 0(DI), DI // arg 1 fd
+ CALL libc_write(SB)
+ TESTL AX, AX
+ JGE noerr
+ CALL libc_error(SB)
+ MOVL (AX), AX
+ NEGL AX // caller expects negative errno value
+noerr:
+ RET
+
+TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0
+ CALL libc_pipe(SB) // pointer already in DI
+ TESTL AX, AX
+ JEQ 3(PC)
+ CALL libc_error(SB) // return negative errno value
+ NEGL AX
+ RET
+
+TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 new
+ MOVQ 16(DI), DX // arg 3 old
+ MOVL 0(DI), DI // arg 1 which
+ CALL libc_setitimer(SB)
+ RET
+
+TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
+ MOVQ 8(DI), SI // arg 2 len
+ MOVL 16(DI), DX // arg 3 advice
+ MOVQ 0(DI), DI // arg 1 addr
+ CALL libc_madvise(SB)
+ // ignore failure - maybe pages are locked
+ RET
+
+TEXT runtime·mlock_trampoline(SB), NOSPLIT, $0
+ UNDEF // unimplemented
+
+GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
+
+TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
+ MOVQ DI, BX
+ CALL libc_mach_absolute_time(SB)
+ MOVQ AX, 0(BX)
+ MOVL timebase<>+machTimebaseInfo_numer(SB), SI
+ MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
+ TESTL DI, DI
+ JNE initialized
+
+ SUBQ $(machTimebaseInfo__size+15)/16*16, SP
+ MOVQ SP, DI
+ CALL libc_mach_timebase_info(SB)
+ MOVL machTimebaseInfo_numer(SP), SI
+ MOVL machTimebaseInfo_denom(SP), DI
+ ADDQ $(machTimebaseInfo__size+15)/16*16, SP
+
+ MOVL SI, timebase<>+machTimebaseInfo_numer(SB)
+ MOVL DI, AX
+ XCHGL AX, timebase<>+machTimebaseInfo_denom(SB) // atomic write
+
+initialized:
+ MOVL SI, 8(BX)
+ MOVL DI, 12(BX)
+ RET
+
+TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0
+ MOVQ DI, SI // arg 2 timespec
+ MOVL $CLOCK_REALTIME, DI // arg 1 clock_id
+ CALL libc_clock_gettime(SB)
+ RET
+
+TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 new
+ MOVQ 16(DI), DX // arg 3 old
+ MOVL 0(DI), DI // arg 1 sig
+ CALL libc_sigaction(SB)
+ TESTL AX, AX
+ JEQ 2(PC)
+ MOVL $0xf1, 0xf1 // crash
+ RET
+
+TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 new
+ MOVQ 16(DI), DX // arg 3 old
+ MOVL 0(DI), DI // arg 1 how
+ CALL libc_pthread_sigmask(SB)
+ TESTL AX, AX
+ JEQ 2(PC)
+ MOVL $0xf1, 0xf1 // crash
+ RET
+
+TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 old
+ MOVQ 0(DI), DI // arg 1 new
+ CALL libc_sigaltstack(SB)
+ TESTQ AX, AX
+ JEQ 2(PC)
+ MOVL $0xf1, 0xf1 // crash
+ RET
+
+TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
+ MOVL 0(DI), BX // signal
+ CALL libc_getpid(SB)
+ MOVL AX, DI // arg 1 pid
+ MOVL BX, SI // arg 2 signal
+ CALL libc_kill(SB)
+ RET
+
+TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
+ MOVQ fn+0(FP), AX
+ MOVL sig+8(FP), DI
+ MOVQ info+16(FP), SI
+ MOVQ ctx+24(FP), DX
+ MOVQ SP, BX // callee-saved
+ ANDQ $~15, SP // alignment for x86_64 ABI
+ CALL AX
+ MOVQ BX, SP
+ RET
+
+// This is the function registered during sigaction and is invoked when
+// a signal is received. It just redirects to the Go function sigtrampgo.
+// Called using C ABI.
+TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME|NOFRAME,$0
+ // Transition from C ABI to Go ABI.
+ PUSH_REGS_HOST_TO_ABI0()
+
+ // Set up ABIInternal environment: g in R14, cleared X15.
+ get_tls(R12)
+ MOVQ g(R12), R14
+ PXOR X15, X15
+
+ // Reserve space for spill slots.
+ NOP SP // disable vet stack checking
+ ADJSP $24
+
+ // Call into the Go signal handler
+ MOVQ DI, AX // sig
+ MOVQ SI, BX // info
+ MOVQ DX, CX // ctx
+ CALL ·sigtrampgo<ABIInternal>(SB)
+
+ ADJSP $-24
+
+ POP_REGS_HOST_TO_ABI0()
+ RET
+
+// Called using C ABI.
+TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT|NOFRAME,$0
+ // Transition from C ABI to Go ABI.
+ PUSH_REGS_HOST_TO_ABI0()
+
+ // Call into the Go signal handler
+ NOP SP // disable vet stack checking
+ ADJSP $24
+ MOVL DI, 0(SP) // sig
+ MOVQ SI, 8(SP) // info
+ MOVQ DX, 16(SP) // ctx
+ CALL ·sigprofNonGo(SB)
+ ADJSP $-24
+
+ POP_REGS_HOST_TO_ABI0()
+ RET
+
+// Used instead of sigtramp in programs that use cgo.
+// Arguments from kernel are in DI, SI, DX.
+TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
+ // If no traceback function, do usual sigtramp.
+ MOVQ runtime·cgoTraceback(SB), AX
+ TESTQ AX, AX
+ JZ sigtramp
+
+ // If no traceback support function, which means that
+ // runtime/cgo was not linked in, do usual sigtramp.
+ MOVQ _cgo_callers(SB), AX
+ TESTQ AX, AX
+ JZ sigtramp
+
+ // Figure out if we are currently in a cgo call.
+ // If not, just do usual sigtramp.
+ get_tls(CX)
+ MOVQ g(CX),AX
+ TESTQ AX, AX
+ JZ sigtrampnog // g == nil
+ MOVQ g_m(AX), AX
+ TESTQ AX, AX
+ JZ sigtramp // g.m == nil
+ MOVL m_ncgo(AX), CX
+ TESTL CX, CX
+ JZ sigtramp // g.m.ncgo == 0
+ MOVQ m_curg(AX), CX
+ TESTQ CX, CX
+ JZ sigtramp // g.m.curg == nil
+ MOVQ g_syscallsp(CX), CX
+ TESTQ CX, CX
+ JZ sigtramp // g.m.curg.syscallsp == 0
+ MOVQ m_cgoCallers(AX), R8
+ TESTQ R8, R8
+ JZ sigtramp // g.m.cgoCallers == nil
+ MOVL m_cgoCallersUse(AX), CX
+ TESTL CX, CX
+ JNZ sigtramp // g.m.cgoCallersUse != 0
+
+ // Jump to a function in runtime/cgo.
+ // That function, written in C, will call the user's traceback
+ // function with proper unwind info, and will then call back here.
+ // The first three arguments, and the fifth, are already in registers.
+ // Set the two remaining arguments now.
+ MOVQ runtime·cgoTraceback(SB), CX
+ MOVQ $runtime·sigtramp(SB), R9
+ MOVQ _cgo_callers(SB), AX
+ JMP AX
+
+sigtramp:
+ JMP runtime·sigtramp(SB)
+
+sigtrampnog:
+ // Signal arrived on a non-Go thread. If this is SIGPROF, get a
+ // stack trace.
+ CMPL DI, $27 // 27 == SIGPROF
+ JNZ sigtramp
+
+ // Lock sigprofCallersUse.
+ MOVL $0, AX
+ MOVL $1, CX
+ MOVQ $runtime·sigprofCallersUse(SB), R11
+ LOCK
+ CMPXCHGL CX, 0(R11)
+ JNZ sigtramp // Skip stack trace if already locked.
+
+ // Jump to the traceback function in runtime/cgo.
+ // It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
+ // the arguments to the Go calling convention.
+ // First three arguments to traceback function are in registers already.
+ MOVQ runtime·cgoTraceback(SB), CX
+ MOVQ $runtime·sigprofCallers(SB), R8
+ MOVQ $runtime·sigprofNonGoWrapper<>(SB), R9
+ MOVQ _cgo_callers(SB), AX
+ JMP AX
+
+TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
+ MOVQ DI, BX
+ MOVQ 0(BX), DI // arg 1 addr
+ MOVQ 8(BX), SI // arg 2 len
+ MOVL 16(BX), DX // arg 3 prot
+ MOVL 20(BX), CX // arg 4 flags
+ MOVL 24(BX), R8 // arg 5 fid
+ MOVL 28(BX), R9 // arg 6 offset
+ CALL libc_mmap(SB)
+ XORL DX, DX
+ CMPQ AX, $-1
+ JNE ok
+ CALL libc_error(SB)
+ MOVLQSX (AX), DX // errno
+ XORL AX, AX
+ok:
+ MOVQ AX, 32(BX)
+ MOVQ DX, 40(BX)
+ RET
+
+TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 len
+ MOVQ 0(DI), DI // arg 1 addr
+ CALL libc_munmap(SB)
+ TESTQ AX, AX
+ JEQ 2(PC)
+ MOVL $0xf1, 0xf1 // crash
+ RET
+
+TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
+ MOVL 0(DI), DI // arg 1 usec
+ CALL libc_usleep(SB)
+ RET
+
+TEXT runtime·settls(SB),NOSPLIT,$32
+ // Nothing to do on Darwin, pthread already set thread-local storage up.
+ RET
+
+TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
+ MOVL 8(DI), SI // arg 2 miblen
+ MOVQ 16(DI), DX // arg 3 oldp
+ MOVQ 24(DI), CX // arg 4 oldlenp
+ MOVQ 32(DI), R8 // arg 5 newp
+ MOVQ 40(DI), R9 // arg 6 newlen
+ MOVQ 0(DI), DI // arg 1 mib
+ CALL libc_sysctl(SB)
+ RET
+
+TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 oldp
+ MOVQ 16(DI), DX // arg 3 oldlenp
+ MOVQ 24(DI), CX // arg 4 newp
+ MOVQ 32(DI), R8 // arg 5 newlen
+ MOVQ 0(DI), DI // arg 1 name
+ CALL libc_sysctlbyname(SB)
+ RET
+
+TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
+ CALL libc_kqueue(SB)
+ RET
+
+TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 keventt
+ MOVL 16(DI), DX // arg 3 nch
+ MOVQ 24(DI), CX // arg 4 ev
+ MOVL 32(DI), R8 // arg 5 nev
+ MOVQ 40(DI), R9 // arg 6 ts
+ MOVL 0(DI), DI // arg 1 kq
+ CALL libc_kevent(SB)
+ CMPL AX, $-1
+ JNE ok
+ CALL libc_error(SB)
+ MOVLQSX (AX), AX // errno
+ NEGQ AX // caller wants it as a negative error code
+ok:
+ RET
+
+TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
+ MOVQ DI, BX
+ MOVL 0(BX), DI // arg 1 fd
+ MOVL 4(BX), SI // arg 2 cmd
+ MOVL 8(BX), DX // arg 3 arg
+ XORL AX, AX // vararg: say "no float args"
+ CALL libc_fcntl(SB)
+ XORL DX, DX
+ CMPQ AX, $-1
+ JNE noerr
+ CALL libc_error(SB)
+ MOVL (AX), DX
+ MOVL $-1, AX
+noerr:
+ MOVL AX, 12(BX)
+ MOVL DX, 16(BX)
+ RET
+
+// mstart_stub is the first function executed on a new thread started by pthread_create.
+// It just does some low-level setup and then calls mstart.
+// Note: called with the C calling convention.
+TEXT runtime·mstart_stub(SB),NOSPLIT|NOFRAME,$0
+ // DI points to the m.
+ // We are already on m's g0 stack.
+
+ // Transition from C ABI to Go ABI.
+ PUSH_REGS_HOST_TO_ABI0()
+
+ MOVQ m_g0(DI), DX // g
+
+ // Initialize TLS entry.
+ // See cmd/link/internal/ld/sym.go:computeTLSOffset.
+ MOVQ DX, 0x30(GS)
+
+ CALL runtime·mstart(SB)
+
+ POP_REGS_HOST_TO_ABI0()
+
+ // Go is all done with this OS thread.
+ // Tell pthread everything is ok (we never join with this thread, so
+ // the value here doesn't really matter).
+ XORL AX, AX
+ RET
+
+// These trampolines help convert from Go calling convention to C calling convention.
+// They should be called with asmcgocall.
+// A pointer to the arguments is passed in DI.
+// A single int32 result is returned in AX.
+// (For more results, make an args/results structure.)
+TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
+ MOVQ 0(DI), DI // arg 1 attr
+ CALL libc_pthread_attr_init(SB)
+ RET
+
+TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 size
+ MOVQ 0(DI), DI // arg 1 attr
+ CALL libc_pthread_attr_getstacksize(SB)
+ RET
+
+TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 state
+ MOVQ 0(DI), DI // arg 1 attr
+ CALL libc_pthread_attr_setdetachstate(SB)
+ RET
+
+TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$16
+ MOVQ 0(DI), SI // arg 2 attr
+ MOVQ 8(DI), DX // arg 3 start
+ MOVQ 16(DI), CX // arg 4 arg
+ MOVQ SP, DI // arg 1 &threadid (which we throw away)
+ CALL libc_pthread_create(SB)
+ RET
+
+TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
+ MOVL 0(DI), DI // arg 1 signal
+ CALL libc_raise(SB)
+ RET
+
+TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 attr
+ MOVQ 0(DI), DI // arg 1 mutex
+ CALL libc_pthread_mutex_init(SB)
+ RET
+
+TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0
+ MOVQ 0(DI), DI // arg 1 mutex
+ CALL libc_pthread_mutex_lock(SB)
+ RET
+
+TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0
+ MOVQ 0(DI), DI // arg 1 mutex
+ CALL libc_pthread_mutex_unlock(SB)
+ RET
+
+TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 attr
+ MOVQ 0(DI), DI // arg 1 cond
+ CALL libc_pthread_cond_init(SB)
+ RET
+
+TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 mutex
+ MOVQ 0(DI), DI // arg 1 cond
+ CALL libc_pthread_cond_wait(SB)
+ RET
+
+TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 mutex
+ MOVQ 16(DI), DX // arg 3 timeout
+ MOVQ 0(DI), DI // arg 1 cond
+ CALL libc_pthread_cond_timedwait_relative_np(SB)
+ RET
+
+TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0
+ MOVQ 0(DI), DI // arg 1 cond
+ CALL libc_pthread_cond_signal(SB)
+ RET
+
+TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0
+ MOVQ DI, BX // BX is caller-save
+ CALL libc_pthread_self(SB)
+ MOVQ AX, 0(BX) // return value
+ RET
+
+TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0
+ MOVQ 8(DI), SI // arg 2 sig
+ MOVQ 0(DI), DI // arg 1 thread
+ CALL libc_pthread_kill(SB)
+ RET
+
+TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0
+ MOVQ $0, DI // arg 1 val
+ CALL libc_notify_is_valid_token(SB)
+ CALL libc_xpc_date_create_from_current(SB)
+ RET
+
+// syscall calls a function in libc on behalf of the syscall package.
+// syscall takes a pointer to a struct like:
+// struct {
+// fn uintptr
+// a1 uintptr
+// a2 uintptr
+// a3 uintptr
+// r1 uintptr
+// r2 uintptr
+// err uintptr
+// }
+// syscall must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall expects a 32-bit result and tests for 32-bit -1
+// to decide there was an error.
+TEXT runtime·syscall(SB),NOSPLIT,$16
+ MOVQ (0*8)(DI), CX // fn
+ MOVQ (2*8)(DI), SI // a2
+ MOVQ (3*8)(DI), DX // a3
+ MOVQ DI, (SP)
+ MOVQ (1*8)(DI), DI // a1
+ XORL AX, AX // vararg: say "no float args"
+
+ CALL CX
+
+ MOVQ (SP), DI
+ MOVQ AX, (4*8)(DI) // r1
+ MOVQ DX, (5*8)(DI) // r2
+
+ // Standard libc functions return -1 on error
+ // and set errno.
+ CMPL AX, $-1 // Note: high 32 bits are junk
+ JNE ok
+
+ // Get error code from libc.
+ CALL libc_error(SB)
+ MOVLQSX (AX), AX
+ MOVQ (SP), DI
+ MOVQ AX, (6*8)(DI) // err
+
+ok:
+ XORL AX, AX // no error (it's ignored anyway)
+ RET
+
+// syscallX calls a function in libc on behalf of the syscall package.
+// syscallX takes a pointer to a struct like:
+// struct {
+// fn uintptr
+// a1 uintptr
+// a2 uintptr
+// a3 uintptr
+// r1 uintptr
+// r2 uintptr
+// err uintptr
+// }
+// syscallX must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscallX is like syscall but expects a 64-bit result
+// and tests for 64-bit -1 to decide there was an error.
+TEXT runtime·syscallX(SB),NOSPLIT,$16
+ MOVQ (0*8)(DI), CX // fn
+ MOVQ (2*8)(DI), SI // a2
+ MOVQ (3*8)(DI), DX // a3
+ MOVQ DI, (SP)
+ MOVQ (1*8)(DI), DI // a1
+ XORL AX, AX // vararg: say "no float args"
+
+ CALL CX
+
+ MOVQ (SP), DI
+ MOVQ AX, (4*8)(DI) // r1
+ MOVQ DX, (5*8)(DI) // r2
+
+ // Standard libc functions return -1 on error
+ // and set errno.
+ CMPQ AX, $-1
+ JNE ok
+
+ // Get error code from libc.
+ CALL libc_error(SB)
+ MOVLQSX (AX), AX
+ MOVQ (SP), DI
+ MOVQ AX, (6*8)(DI) // err
+
+ok:
+ XORL AX, AX // no error (it's ignored anyway)
+ RET
+
+// syscallPtr is like syscallX except that the libc function reports an
+// error by returning NULL and setting errno.
+TEXT runtime·syscallPtr(SB),NOSPLIT,$16
+ MOVQ (0*8)(DI), CX // fn
+ MOVQ (2*8)(DI), SI // a2
+ MOVQ (3*8)(DI), DX // a3
+ MOVQ DI, (SP)
+ MOVQ (1*8)(DI), DI // a1
+ XORL AX, AX // vararg: say "no float args"
+
+ CALL CX
+
+ MOVQ (SP), DI
+ MOVQ AX, (4*8)(DI) // r1
+ MOVQ DX, (5*8)(DI) // r2
+
+ // syscallPtr libc functions return NULL on error
+ // and set errno.
+ TESTQ AX, AX
+ JNE ok
+
+ // Get error code from libc.
+ CALL libc_error(SB)
+ MOVLQSX (AX), AX
+ MOVQ (SP), DI
+ MOVQ AX, (6*8)(DI) // err
+
+ok:
+ XORL AX, AX // no error (it's ignored anyway)
+ RET
+
+// syscall6 calls a function in libc on behalf of the syscall package.
+// syscall6 takes a pointer to a struct like:
+// struct {
+// fn uintptr
+// a1 uintptr
+// a2 uintptr
+// a3 uintptr
+// a4 uintptr
+// a5 uintptr
+// a6 uintptr
+// r1 uintptr
+// r2 uintptr
+// err uintptr
+// }
+// syscall6 must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall6 expects a 32-bit result and tests for 32-bit -1
+// to decide there was an error.
+TEXT runtime·syscall6(SB),NOSPLIT,$16
+ MOVQ (0*8)(DI), R11// fn
+ MOVQ (2*8)(DI), SI // a2
+ MOVQ (3*8)(DI), DX // a3
+ MOVQ (4*8)(DI), CX // a4
+ MOVQ (5*8)(DI), R8 // a5
+ MOVQ (6*8)(DI), R9 // a6
+ MOVQ DI, (SP)
+ MOVQ (1*8)(DI), DI // a1
+ XORL AX, AX // vararg: say "no float args"
+
+ CALL R11
+
+ MOVQ (SP), DI
+ MOVQ AX, (7*8)(DI) // r1
+ MOVQ DX, (8*8)(DI) // r2
+
+ CMPL AX, $-1
+ JNE ok
+
+ CALL libc_error(SB)
+ MOVLQSX (AX), AX
+ MOVQ (SP), DI
+ MOVQ AX, (9*8)(DI) // err
+
+ok:
+ XORL AX, AX // no error (it's ignored anyway)
+ RET
+
+// syscall6X calls a function in libc on behalf of the syscall package.
+// syscall6X takes a pointer to a struct like:
+// struct {
+// fn uintptr
+// a1 uintptr
+// a2 uintptr
+// a3 uintptr
+// a4 uintptr
+// a5 uintptr
+// a6 uintptr
+// r1 uintptr
+// r2 uintptr
+// err uintptr
+// }
+// syscall6X must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall6X is like syscall6 but expects a 64-bit result
+// and tests for 64-bit -1 to decide there was an error.
+TEXT runtime·syscall6X(SB),NOSPLIT,$16
+ MOVQ (0*8)(DI), R11// fn
+ MOVQ (2*8)(DI), SI // a2
+ MOVQ (3*8)(DI), DX // a3
+ MOVQ (4*8)(DI), CX // a4
+ MOVQ (5*8)(DI), R8 // a5
+ MOVQ (6*8)(DI), R9 // a6
+ MOVQ DI, (SP)
+ MOVQ (1*8)(DI), DI // a1
+ XORL AX, AX // vararg: say "no float args"
+
+ CALL R11
+
+ MOVQ (SP), DI
+ MOVQ AX, (7*8)(DI) // r1
+ MOVQ DX, (8*8)(DI) // r2
+
+ CMPQ AX, $-1
+ JNE ok
+
+ CALL libc_error(SB)
+ MOVLQSX (AX), AX
+ MOVQ (SP), DI
+ MOVQ AX, (9*8)(DI) // err
+
+ok:
+ XORL AX, AX // no error (it's ignored anyway)
+ RET
+
+// syscall9 calls a function in libc on behalf of the syscall package.
+// syscall9 takes a pointer to a struct like:
+// struct {
+// fn uintptr
+// a1 uintptr
+// a2 uintptr
+// a3 uintptr
+// a4 uintptr
+// a5 uintptr
+// a6 uintptr
+// a7 uintptr
+// a8 uintptr
+// a9 uintptr
+// r1 uintptr
+// r2 uintptr
+// err uintptr
+// }
+// syscall9 must be called on the g0 stack with the
+// C calling convention (use libcCall).
+//
+// syscall9 expects a 32-bit result and tests for 32-bit -1
+// to decide there was an error.
+TEXT runtime·syscall9(SB),NOSPLIT,$16
+ MOVQ (0*8)(DI), R13// fn
+ MOVQ (2*8)(DI), SI // a2
+ MOVQ (3*8)(DI), DX // a3
+ MOVQ (4*8)(DI), CX // a4
+ MOVQ (5*8)(DI), R8 // a5
+ MOVQ (6*8)(DI), R9 // a6
+ MOVQ (7*8)(DI), R10 // a7
+ MOVQ (8*8)(DI), R11 // a8
+ MOVQ (9*8)(DI), R12 // a9
+ MOVQ DI, (SP)
+ MOVQ (1*8)(DI), DI // a1
+ XORL AX, AX // vararg: say "no float args"
+
+ CALL R13
+
+ MOVQ (SP), DI
+ MOVQ AX, (10*8)(DI) // r1
+ MOVQ DX, (11*8)(DI) // r2
+
+ CMPL AX, $-1
+ JNE ok
+
+ CALL libc_error(SB)
+ MOVLQSX (AX), AX
+ MOVQ (SP), DI
+ MOVQ AX, (12*8)(DI) // err
+
+ok:
+ XORL AX, AX // no error (it's ignored anyway)
+ RET
+
+// syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
+// takes 5 uintptrs and 1 float64, and only returns one value,
+// for use with standard C ABI functions.
+TEXT runtime·syscall_x509(SB),NOSPLIT,$16
+ MOVQ (0*8)(DI), R11// fn
+ MOVQ (2*8)(DI), SI // a2
+ MOVQ (3*8)(DI), DX // a3
+ MOVQ (4*8)(DI), CX // a4
+ MOVQ (5*8)(DI), R8 // a5
+ MOVQ (6*8)(DI), X0 // f1
+ MOVQ DI, (SP)
+ MOVQ (1*8)(DI), DI // a1
+ XORL AX, AX // vararg: say "no float args"
+
+ CALL R11
+
+ MOVQ (SP), DI
+ MOVQ AX, (7*8)(DI) // r1
+
+ XORL AX, AX // no error (it's ignored anyway)
+ RET
+
+TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0
+ CALL libc_issetugid(SB)
+ RET
diff --git a/contrib/go/_std_1.20/src/runtime/sys_libc.go b/contrib/go/_std_1.21/src/runtime/sys_libc.go
index 0c6f13ca9f..0c6f13ca9f 100644
--- a/contrib/go/_std_1.20/src/runtime/sys_libc.go
+++ b/contrib/go/_std_1.21/src/runtime/sys_libc.go
diff --git a/contrib/go/_std_1.21/src/runtime/sys_linux_amd64.s b/contrib/go/_std_1.21/src/runtime/sys_linux_amd64.s
new file mode 100644
index 0000000000..b6c64dc095
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/sys_linux_amd64.s
@@ -0,0 +1,706 @@
+// Copyright 2009 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.
+
+//
+// System calls and other sys.stuff for AMD64, Linux
+//
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "textflag.h"
+#include "cgo/abi_amd64.h"
+
+#define AT_FDCWD -100
+
+#define SYS_read 0
+#define SYS_write 1
+#define SYS_close 3
+#define SYS_mmap 9
+#define SYS_munmap 11
+#define SYS_brk 12
+#define SYS_rt_sigaction 13
+#define SYS_rt_sigprocmask 14
+#define SYS_rt_sigreturn 15
+#define SYS_sched_yield 24
+#define SYS_mincore 27
+#define SYS_madvise 28
+#define SYS_nanosleep 35
+#define SYS_setittimer 38
+#define SYS_getpid 39
+#define SYS_socket 41
+#define SYS_connect 42
+#define SYS_clone 56
+#define SYS_exit 60
+#define SYS_kill 62
+#define SYS_sigaltstack 131
+#define SYS_arch_prctl 158
+#define SYS_gettid 186
+#define SYS_futex 202
+#define SYS_sched_getaffinity 204
+#define SYS_timer_create 222
+#define SYS_timer_settime 223
+#define SYS_timer_delete 226
+#define SYS_clock_gettime 228
+#define SYS_exit_group 231
+#define SYS_tgkill 234
+#define SYS_openat 257
+#define SYS_faccessat 269
+#define SYS_pipe2 293
+
+TEXT runtime·exit(SB),NOSPLIT,$0-4
+ MOVL code+0(FP), DI
+ MOVL $SYS_exit_group, AX
+ SYSCALL
+ RET
+
+// func exitThread(wait *atomic.Uint32)
+TEXT runtime·exitThread(SB),NOSPLIT,$0-8
+ MOVQ wait+0(FP), AX
+ // We're done using the stack.
+ MOVL $0, (AX)
+ MOVL $0, DI // exit code
+ MOVL $SYS_exit, AX
+ SYSCALL
+ // We may not even have a stack any more.
+ INT $3
+ JMP 0(PC)
+
+TEXT runtime·open(SB),NOSPLIT,$0-20
+ // This uses openat instead of open, because Android O blocks open.
+ MOVL $AT_FDCWD, DI // AT_FDCWD, so this acts like open
+ MOVQ name+0(FP), SI
+ MOVL mode+8(FP), DX
+ MOVL perm+12(FP), R10
+ MOVL $SYS_openat, AX
+ SYSCALL
+ CMPQ AX, $0xfffffffffffff001
+ JLS 2(PC)
+ MOVL $-1, AX
+ MOVL AX, ret+16(FP)
+ RET
+
+TEXT runtime·closefd(SB),NOSPLIT,$0-12
+ MOVL fd+0(FP), DI
+ MOVL $SYS_close, AX
+ SYSCALL
+ CMPQ AX, $0xfffffffffffff001
+ JLS 2(PC)
+ MOVL $-1, AX
+ MOVL AX, ret+8(FP)
+ RET
+
+TEXT runtime·write1(SB),NOSPLIT,$0-28
+ MOVQ fd+0(FP), DI
+ MOVQ p+8(FP), SI
+ MOVL n+16(FP), DX
+ MOVL $SYS_write, AX
+ SYSCALL
+ MOVL AX, ret+24(FP)
+ RET
+
+TEXT runtime·read(SB),NOSPLIT,$0-28
+ MOVL fd+0(FP), DI
+ MOVQ p+8(FP), SI
+ MOVL n+16(FP), DX
+ MOVL $SYS_read, AX
+ SYSCALL
+ MOVL AX, ret+24(FP)
+ RET
+
+// func pipe2(flags int32) (r, w int32, errno int32)
+TEXT runtime·pipe2(SB),NOSPLIT,$0-20
+ LEAQ r+8(FP), DI
+ MOVL flags+0(FP), SI
+ MOVL $SYS_pipe2, AX
+ SYSCALL
+ MOVL AX, errno+16(FP)
+ RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$16
+ MOVL $0, DX
+ MOVL usec+0(FP), AX
+ MOVL $1000000, CX
+ DIVL CX
+ MOVQ AX, 0(SP)
+ MOVL $1000, AX // usec to nsec
+ MULL DX
+ MOVQ AX, 8(SP)
+
+ // nanosleep(&ts, 0)
+ MOVQ SP, DI
+ MOVL $0, SI
+ MOVL $SYS_nanosleep, AX
+ SYSCALL
+ RET
+
+TEXT runtime·gettid(SB),NOSPLIT,$0-4
+ MOVL $SYS_gettid, AX
+ SYSCALL
+ MOVL AX, ret+0(FP)
+ RET
+
+TEXT runtime·raise(SB),NOSPLIT,$0
+ MOVL $SYS_getpid, AX
+ SYSCALL
+ MOVL AX, R12
+ MOVL $SYS_gettid, AX
+ SYSCALL
+ MOVL AX, SI // arg 2 tid
+ MOVL R12, DI // arg 1 pid
+ MOVL sig+0(FP), DX // arg 3
+ MOVL $SYS_tgkill, AX
+ SYSCALL
+ RET
+
+TEXT runtime·raiseproc(SB),NOSPLIT,$0
+ MOVL $SYS_getpid, AX
+ SYSCALL
+ MOVL AX, DI // arg 1 pid
+ MOVL sig+0(FP), SI // arg 2
+ MOVL $SYS_kill, AX
+ SYSCALL
+ RET
+
+TEXT ·getpid(SB),NOSPLIT,$0-8
+ MOVL $SYS_getpid, AX
+ SYSCALL
+ MOVQ AX, ret+0(FP)
+ RET
+
+TEXT ·tgkill(SB),NOSPLIT,$0
+ MOVQ tgid+0(FP), DI
+ MOVQ tid+8(FP), SI
+ MOVQ sig+16(FP), DX
+ MOVL $SYS_tgkill, AX
+ SYSCALL
+ RET
+
+TEXT runtime·setitimer(SB),NOSPLIT,$0-24
+ MOVL mode+0(FP), DI
+ MOVQ new+8(FP), SI
+ MOVQ old+16(FP), DX
+ MOVL $SYS_setittimer, AX
+ SYSCALL
+ RET
+
+TEXT runtime·timer_create(SB),NOSPLIT,$0-28
+ MOVL clockid+0(FP), DI
+ MOVQ sevp+8(FP), SI
+ MOVQ timerid+16(FP), DX
+ MOVL $SYS_timer_create, AX
+ SYSCALL
+ MOVL AX, ret+24(FP)
+ RET
+
+TEXT runtime·timer_settime(SB),NOSPLIT,$0-28
+ MOVL timerid+0(FP), DI
+ MOVL flags+4(FP), SI
+ MOVQ new+8(FP), DX
+ MOVQ old+16(FP), R10
+ MOVL $SYS_timer_settime, AX
+ SYSCALL
+ MOVL AX, ret+24(FP)
+ RET
+
+TEXT runtime·timer_delete(SB),NOSPLIT,$0-12
+ MOVL timerid+0(FP), DI
+ MOVL $SYS_timer_delete, AX
+ SYSCALL
+ MOVL AX, ret+8(FP)
+ RET
+
+TEXT runtime·mincore(SB),NOSPLIT,$0-28
+ MOVQ addr+0(FP), DI
+ MOVQ n+8(FP), SI
+ MOVQ dst+16(FP), DX
+ MOVL $SYS_mincore, AX
+ SYSCALL
+ MOVL AX, ret+24(FP)
+ RET
+
+// func nanotime1() int64
+TEXT runtime·nanotime1(SB),NOSPLIT,$16-8
+ // We don't know how much stack space the VDSO code will need,
+ // so switch to g0.
+ // In particular, a kernel configured with CONFIG_OPTIMIZE_INLINING=n
+ // and hardening can use a full page of stack space in gettime_sym
+ // due to stack probes inserted to avoid stack/heap collisions.
+ // See issue #20427.
+
+ MOVQ SP, R12 // Save old SP; R12 unchanged by C code.
+
+ MOVQ g_m(R14), BX // BX unchanged by C code.
+
+ // Set vdsoPC and vdsoSP for SIGPROF traceback.
+ // Save the old values on stack and restore them on exit,
+ // so this function is reentrant.
+ MOVQ m_vdsoPC(BX), CX
+ MOVQ m_vdsoSP(BX), DX
+ MOVQ CX, 0(SP)
+ MOVQ DX, 8(SP)
+
+ LEAQ ret+0(FP), DX
+ MOVQ -8(DX), CX
+ MOVQ CX, m_vdsoPC(BX)
+ MOVQ DX, m_vdsoSP(BX)
+
+ CMPQ R14, m_curg(BX) // Only switch if on curg.
+ JNE noswitch
+
+ MOVQ m_g0(BX), DX
+ MOVQ (g_sched+gobuf_sp)(DX), SP // Set SP to g0 stack
+
+noswitch:
+ SUBQ $16, SP // Space for results
+ ANDQ $~15, SP // Align for C code
+
+ MOVL $1, DI // CLOCK_MONOTONIC
+ LEAQ 0(SP), SI
+ MOVQ runtime·vdsoClockgettimeSym(SB), AX
+ CMPQ AX, $0
+ JEQ fallback
+ CALL AX
+ret:
+ MOVQ 0(SP), AX // sec
+ MOVQ 8(SP), DX // nsec
+ MOVQ R12, SP // Restore real SP
+ // Restore vdsoPC, vdsoSP
+ // We don't worry about being signaled between the two stores.
+ // If we are not in a signal handler, we'll restore vdsoSP to 0,
+ // and no one will care about vdsoPC. If we are in a signal handler,
+ // we cannot receive another signal.
+ MOVQ 8(SP), CX
+ MOVQ CX, m_vdsoSP(BX)
+ MOVQ 0(SP), CX
+ MOVQ CX, m_vdsoPC(BX)
+ // sec is in AX, nsec in DX
+ // return nsec in AX
+ IMULQ $1000000000, AX
+ ADDQ DX, AX
+ MOVQ AX, ret+0(FP)
+ RET
+fallback:
+ MOVQ $SYS_clock_gettime, AX
+ SYSCALL
+ JMP ret
+
+TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-28
+ MOVL how+0(FP), DI
+ MOVQ new+8(FP), SI
+ MOVQ old+16(FP), DX
+ MOVL size+24(FP), R10
+ MOVL $SYS_rt_sigprocmask, AX
+ SYSCALL
+ CMPQ AX, $0xfffffffffffff001
+ JLS 2(PC)
+ MOVL $0xf1, 0xf1 // crash
+ RET
+
+TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-36
+ MOVQ sig+0(FP), DI
+ MOVQ new+8(FP), SI
+ MOVQ old+16(FP), DX
+ MOVQ size+24(FP), R10
+ MOVL $SYS_rt_sigaction, AX
+ SYSCALL
+ MOVL AX, ret+32(FP)
+ RET
+
+// Call the function stored in _cgo_sigaction using the GCC calling convention.
+TEXT runtime·callCgoSigaction(SB),NOSPLIT,$16
+ MOVQ sig+0(FP), DI
+ MOVQ new+8(FP), SI
+ MOVQ old+16(FP), DX
+ MOVQ _cgo_sigaction(SB), AX
+ MOVQ SP, BX // callee-saved
+ ANDQ $~15, SP // alignment as per amd64 psABI
+ CALL AX
+ MOVQ BX, SP
+ MOVL AX, ret+24(FP)
+ RET
+
+TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
+ MOVQ fn+0(FP), AX
+ MOVL sig+8(FP), DI
+ MOVQ info+16(FP), SI
+ MOVQ ctx+24(FP), DX
+ MOVQ SP, BX // callee-saved
+ ANDQ $~15, SP // alignment for x86_64 ABI
+ CALL AX
+ MOVQ BX, SP
+ RET
+
+// Called using C ABI.
+TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME|NOFRAME,$0
+ // Transition from C ABI to Go ABI.
+ PUSH_REGS_HOST_TO_ABI0()
+
+ // Set up ABIInternal environment: g in R14, cleared X15.
+ get_tls(R12)
+ MOVQ g(R12), R14
+ PXOR X15, X15
+
+ // Reserve space for spill slots.
+ NOP SP // disable vet stack checking
+ ADJSP $24
+
+ // Call into the Go signal handler
+ MOVQ DI, AX // sig
+ MOVQ SI, BX // info
+ MOVQ DX, CX // ctx
+ CALL ·sigtrampgo<ABIInternal>(SB)
+
+ ADJSP $-24
+
+ POP_REGS_HOST_TO_ABI0()
+ RET
+
+// Called using C ABI.
+TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT|NOFRAME,$0
+ // Transition from C ABI to Go ABI.
+ PUSH_REGS_HOST_TO_ABI0()
+
+ // Set up ABIInternal environment: g in R14, cleared X15.
+ get_tls(R12)
+ MOVQ g(R12), R14
+ PXOR X15, X15
+
+ // Reserve space for spill slots.
+ NOP SP // disable vet stack checking
+ ADJSP $24
+
+ // Call into the Go signal handler
+ MOVQ DI, AX // sig
+ MOVQ SI, BX // info
+ MOVQ DX, CX // ctx
+ CALL ·sigprofNonGo<ABIInternal>(SB)
+
+ ADJSP $-24
+
+ POP_REGS_HOST_TO_ABI0()
+ RET
+
+// Used instead of sigtramp in programs that use cgo.
+// Arguments from kernel are in DI, SI, DX.
+TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
+ // If no traceback function, do usual sigtramp.
+ MOVQ runtime·cgoTraceback(SB), AX
+ TESTQ AX, AX
+ JZ sigtramp
+
+ // If no traceback support function, which means that
+ // runtime/cgo was not linked in, do usual sigtramp.
+ MOVQ _cgo_callers(SB), AX
+ TESTQ AX, AX
+ JZ sigtramp
+
+ // Figure out if we are currently in a cgo call.
+ // If not, just do usual sigtramp.
+ get_tls(CX)
+ MOVQ g(CX),AX
+ TESTQ AX, AX
+ JZ sigtrampnog // g == nil
+ MOVQ g_m(AX), AX
+ TESTQ AX, AX
+ JZ sigtramp // g.m == nil
+ MOVL m_ncgo(AX), CX
+ TESTL CX, CX
+ JZ sigtramp // g.m.ncgo == 0
+ MOVQ m_curg(AX), CX
+ TESTQ CX, CX
+ JZ sigtramp // g.m.curg == nil
+ MOVQ g_syscallsp(CX), CX
+ TESTQ CX, CX
+ JZ sigtramp // g.m.curg.syscallsp == 0
+ MOVQ m_cgoCallers(AX), R8
+ TESTQ R8, R8
+ JZ sigtramp // g.m.cgoCallers == nil
+ MOVL m_cgoCallersUse(AX), CX
+ TESTL CX, CX
+ JNZ sigtramp // g.m.cgoCallersUse != 0
+
+ // Jump to a function in runtime/cgo.
+ // That function, written in C, will call the user's traceback
+ // function with proper unwind info, and will then call back here.
+ // The first three arguments, and the fifth, are already in registers.
+ // Set the two remaining arguments now.
+ MOVQ runtime·cgoTraceback(SB), CX
+ MOVQ $runtime·sigtramp(SB), R9
+ MOVQ _cgo_callers(SB), AX
+ JMP AX
+
+sigtramp:
+ JMP runtime·sigtramp(SB)
+
+sigtrampnog:
+ // Signal arrived on a non-Go thread. If this is SIGPROF, get a
+ // stack trace.
+ CMPL DI, $27 // 27 == SIGPROF
+ JNZ sigtramp
+
+ // Lock sigprofCallersUse.
+ MOVL $0, AX
+ MOVL $1, CX
+ MOVQ $runtime·sigprofCallersUse(SB), R11
+ LOCK
+ CMPXCHGL CX, 0(R11)
+ JNZ sigtramp // Skip stack trace if already locked.
+
+ // Jump to the traceback function in runtime/cgo.
+ // It will call back to sigprofNonGo, via sigprofNonGoWrapper, to convert
+ // the arguments to the Go calling convention.
+ // First three arguments to traceback function are in registers already.
+ MOVQ runtime·cgoTraceback(SB), CX
+ MOVQ $runtime·sigprofCallers(SB), R8
+ MOVQ $runtime·sigprofNonGoWrapper<>(SB), R9
+ MOVQ _cgo_callers(SB), AX
+ JMP AX
+
+// For cgo unwinding to work, this function must look precisely like
+// the one in glibc. The glibc source code is:
+// https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c;h=afdce87381228f0cf32fa9fa6c8c4efa5179065c#l80
+// The code that cares about the precise instructions used is:
+// https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libgcc/config/i386/linux-unwind.h;h=5486223d60272c73d5103b29ae592d2ee998e1cf#l49
+//
+// For gdb unwinding to work, this function must look precisely like the one in
+// glibc and must be named "__restore_rt" or contain the string "sigaction" in
+// the name. The gdb source code is:
+// https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/amd64-linux-tdep.c;h=cbbac1a0c64e1deb8181b9d0ff6404e328e2979d#l178
+TEXT runtime·sigreturn__sigaction(SB),NOSPLIT,$0
+ MOVQ $SYS_rt_sigreturn, AX
+ SYSCALL
+ INT $3 // not reached
+
+TEXT runtime·sysMmap(SB),NOSPLIT,$0
+ MOVQ addr+0(FP), DI
+ MOVQ n+8(FP), SI
+ MOVL prot+16(FP), DX
+ MOVL flags+20(FP), R10
+ MOVL fd+24(FP), R8
+ MOVL off+28(FP), R9
+
+ MOVL $SYS_mmap, AX
+ SYSCALL
+ CMPQ AX, $0xfffffffffffff001
+ JLS ok
+ NOTQ AX
+ INCQ AX
+ MOVQ $0, p+32(FP)
+ MOVQ AX, err+40(FP)
+ RET
+ok:
+ MOVQ AX, p+32(FP)
+ MOVQ $0, err+40(FP)
+ RET
+
+// Call the function stored in _cgo_mmap using the GCC calling convention.
+// This must be called on the system stack.
+TEXT runtime·callCgoMmap(SB),NOSPLIT,$16
+ MOVQ addr+0(FP), DI
+ MOVQ n+8(FP), SI
+ MOVL prot+16(FP), DX
+ MOVL flags+20(FP), CX
+ MOVL fd+24(FP), R8
+ MOVL off+28(FP), R9
+ MOVQ _cgo_mmap(SB), AX
+ MOVQ SP, BX
+ ANDQ $~15, SP // alignment as per amd64 psABI
+ MOVQ BX, 0(SP)
+ CALL AX
+ MOVQ 0(SP), SP
+ MOVQ AX, ret+32(FP)
+ RET
+
+TEXT runtime·sysMunmap(SB),NOSPLIT,$0
+ MOVQ addr+0(FP), DI
+ MOVQ n+8(FP), SI
+ MOVQ $SYS_munmap, AX
+ SYSCALL
+ CMPQ AX, $0xfffffffffffff001
+ JLS 2(PC)
+ MOVL $0xf1, 0xf1 // crash
+ RET
+
+// Call the function stored in _cgo_munmap using the GCC calling convention.
+// This must be called on the system stack.
+TEXT runtime·callCgoMunmap(SB),NOSPLIT,$16-16
+ MOVQ addr+0(FP), DI
+ MOVQ n+8(FP), SI
+ MOVQ _cgo_munmap(SB), AX
+ MOVQ SP, BX
+ ANDQ $~15, SP // alignment as per amd64 psABI
+ MOVQ BX, 0(SP)
+ CALL AX
+ MOVQ 0(SP), SP
+ RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$0
+ MOVQ addr+0(FP), DI
+ MOVQ n+8(FP), SI
+ MOVL flags+16(FP), DX
+ MOVQ $SYS_madvise, AX
+ SYSCALL
+ MOVL AX, ret+24(FP)
+ RET
+
+// int64 futex(int32 *uaddr, int32 op, int32 val,
+// struct timespec *timeout, int32 *uaddr2, int32 val2);
+TEXT runtime·futex(SB),NOSPLIT,$0
+ MOVQ addr+0(FP), DI
+ MOVL op+8(FP), SI
+ MOVL val+12(FP), DX
+ MOVQ ts+16(FP), R10
+ MOVQ addr2+24(FP), R8
+ MOVL val3+32(FP), R9
+ MOVL $SYS_futex, AX
+ SYSCALL
+ MOVL AX, ret+40(FP)
+ RET
+
+// int32 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
+TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
+ MOVL flags+0(FP), DI
+ MOVQ stk+8(FP), SI
+ MOVQ $0, DX
+ MOVQ $0, R10
+ MOVQ $0, R8
+ // Copy mp, gp, fn off parent stack for use by child.
+ // Careful: Linux system call clobbers CX and R11.
+ MOVQ mp+16(FP), R13
+ MOVQ gp+24(FP), R9
+ MOVQ fn+32(FP), R12
+ CMPQ R13, $0 // m
+ JEQ nog1
+ CMPQ R9, $0 // g
+ JEQ nog1
+ LEAQ m_tls(R13), R8
+#ifdef GOOS_android
+ // Android stores the TLS offset in runtime·tls_g.
+ SUBQ runtime·tls_g(SB), R8
+#else
+ ADDQ $8, R8 // ELF wants to use -8(FS)
+#endif
+ ORQ $0x00080000, DI //add flag CLONE_SETTLS(0x00080000) to call clone
+nog1:
+ MOVL $SYS_clone, AX
+ SYSCALL
+
+ // In parent, return.
+ CMPQ AX, $0
+ JEQ 3(PC)
+ MOVL AX, ret+40(FP)
+ RET
+
+ // In child, on new stack.
+ MOVQ SI, SP
+
+ // If g or m are nil, skip Go-related setup.
+ CMPQ R13, $0 // m
+ JEQ nog2
+ CMPQ R9, $0 // g
+ JEQ nog2
+
+ // Initialize m->procid to Linux tid
+ MOVL $SYS_gettid, AX
+ SYSCALL
+ MOVQ AX, m_procid(R13)
+
+ // In child, set up new stack
+ get_tls(CX)
+ MOVQ R13, g_m(R9)
+ MOVQ R9, g(CX)
+ MOVQ R9, R14 // set g register
+ CALL runtime·stackcheck(SB)
+
+nog2:
+ // Call fn. This is the PC of an ABI0 function.
+ CALL R12
+
+ // It shouldn't return. If it does, exit that thread.
+ MOVL $111, DI
+ MOVL $SYS_exit, AX
+ SYSCALL
+ JMP -3(PC) // keep exiting
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$0
+ MOVQ new+0(FP), DI
+ MOVQ old+8(FP), SI
+ MOVQ $SYS_sigaltstack, AX
+ SYSCALL
+ CMPQ AX, $0xfffffffffffff001
+ JLS 2(PC)
+ MOVL $0xf1, 0xf1 // crash
+ RET
+
+// set tls base to DI
+TEXT runtime·settls(SB),NOSPLIT,$32
+#ifdef GOOS_android
+ // Android stores the TLS offset in runtime·tls_g.
+ SUBQ runtime·tls_g(SB), DI
+#else
+ ADDQ $8, DI // ELF wants to use -8(FS)
+#endif
+ MOVQ DI, SI
+ MOVQ $0x1002, DI // ARCH_SET_FS
+ MOVQ $SYS_arch_prctl, AX
+ SYSCALL
+ CMPQ AX, $0xfffffffffffff001
+ JLS 2(PC)
+ MOVL $0xf1, 0xf1 // crash
+ RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$0
+ MOVL $SYS_sched_yield, AX
+ SYSCALL
+ RET
+
+TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
+ MOVQ pid+0(FP), DI
+ MOVQ len+8(FP), SI
+ MOVQ buf+16(FP), DX
+ MOVL $SYS_sched_getaffinity, AX
+ SYSCALL
+ MOVL AX, ret+24(FP)
+ RET
+
+// int access(const char *name, int mode)
+TEXT runtime·access(SB),NOSPLIT,$0
+ // This uses faccessat instead of access, because Android O blocks access.
+ MOVL $AT_FDCWD, DI // AT_FDCWD, so this acts like access
+ MOVQ name+0(FP), SI
+ MOVL mode+8(FP), DX
+ MOVL $0, R10
+ MOVL $SYS_faccessat, AX
+ SYSCALL
+ MOVL AX, ret+16(FP)
+ RET
+
+// int connect(int fd, const struct sockaddr *addr, socklen_t addrlen)
+TEXT runtime·connect(SB),NOSPLIT,$0-28
+ MOVL fd+0(FP), DI
+ MOVQ addr+8(FP), SI
+ MOVL len+16(FP), DX
+ MOVL $SYS_connect, AX
+ SYSCALL
+ MOVL AX, ret+24(FP)
+ RET
+
+// int socket(int domain, int type, int protocol)
+TEXT runtime·socket(SB),NOSPLIT,$0-20
+ MOVL domain+0(FP), DI
+ MOVL typ+4(FP), SI
+ MOVL prot+8(FP), DX
+ MOVL $SYS_socket, AX
+ SYSCALL
+ MOVL AX, ret+16(FP)
+ RET
+
+// func sbrk0() uintptr
+TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
+ // Implemented as brk(NULL).
+ MOVQ $0, DI
+ MOVL $SYS_brk, AX
+ SYSCALL
+ MOVQ AX, ret+0(FP)
+ RET
diff --git a/contrib/go/_std_1.21/src/runtime/sys_linux_arm64.s b/contrib/go/_std_1.21/src/runtime/sys_linux_arm64.s
new file mode 100644
index 0000000000..51c87bea05
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/sys_linux_arm64.s
@@ -0,0 +1,787 @@
+// Copyright 2014 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.
+
+//
+// System calls and other sys.stuff for arm64, Linux
+//
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "textflag.h"
+#include "cgo/abi_arm64.h"
+
+#define AT_FDCWD -100
+
+#define CLOCK_REALTIME 0
+#define CLOCK_MONOTONIC 1
+
+#define SYS_exit 93
+#define SYS_read 63
+#define SYS_write 64
+#define SYS_openat 56
+#define SYS_close 57
+#define SYS_pipe2 59
+#define SYS_nanosleep 101
+#define SYS_mmap 222
+#define SYS_munmap 215
+#define SYS_setitimer 103
+#define SYS_clone 220
+#define SYS_sched_yield 124
+#define SYS_rt_sigreturn 139
+#define SYS_rt_sigaction 134
+#define SYS_rt_sigprocmask 135
+#define SYS_sigaltstack 132
+#define SYS_madvise 233
+#define SYS_mincore 232
+#define SYS_getpid 172
+#define SYS_gettid 178
+#define SYS_kill 129
+#define SYS_tgkill 131
+#define SYS_futex 98
+#define SYS_sched_getaffinity 123
+#define SYS_exit_group 94
+#define SYS_clock_gettime 113
+#define SYS_faccessat 48
+#define SYS_socket 198
+#define SYS_connect 203
+#define SYS_brk 214
+#define SYS_timer_create 107
+#define SYS_timer_settime 110
+#define SYS_timer_delete 111
+
+TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
+ MOVW code+0(FP), R0
+ MOVD $SYS_exit_group, R8
+ SVC
+ RET
+
+// func exitThread(wait *atomic.Uint32)
+TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
+ MOVD wait+0(FP), R0
+ // We're done using the stack.
+ MOVW $0, R1
+ STLRW R1, (R0)
+ MOVW $0, R0 // exit code
+ MOVD $SYS_exit, R8
+ SVC
+ JMP 0(PC)
+
+TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
+ MOVD $AT_FDCWD, R0
+ MOVD name+0(FP), R1
+ MOVW mode+8(FP), R2
+ MOVW perm+12(FP), R3
+ MOVD $SYS_openat, R8
+ SVC
+ CMN $4095, R0
+ BCC done
+ MOVW $-1, R0
+done:
+ MOVW R0, ret+16(FP)
+ RET
+
+TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
+ MOVW fd+0(FP), R0
+ MOVD $SYS_close, R8
+ SVC
+ CMN $4095, R0
+ BCC done
+ MOVW $-1, R0
+done:
+ MOVW R0, ret+8(FP)
+ RET
+
+TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
+ MOVD fd+0(FP), R0
+ MOVD p+8(FP), R1
+ MOVW n+16(FP), R2
+ MOVD $SYS_write, R8
+ SVC
+ MOVW R0, ret+24(FP)
+ RET
+
+TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
+ MOVW fd+0(FP), R0
+ MOVD p+8(FP), R1
+ MOVW n+16(FP), R2
+ MOVD $SYS_read, R8
+ SVC
+ MOVW R0, ret+24(FP)
+ RET
+
+// func pipe2(flags int32) (r, w int32, errno int32)
+TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
+ MOVD $r+8(FP), R0
+ MOVW flags+0(FP), R1
+ MOVW $SYS_pipe2, R8
+ SVC
+ MOVW R0, errno+16(FP)
+ RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$24-4
+ MOVWU usec+0(FP), R3
+ MOVD R3, R5
+ MOVW $1000000, R4
+ UDIV R4, R3
+ MOVD R3, 8(RSP)
+ MUL R3, R4
+ SUB R4, R5
+ MOVW $1000, R4
+ MUL R4, R5
+ MOVD R5, 16(RSP)
+
+ // nanosleep(&ts, 0)
+ ADD $8, RSP, R0
+ MOVD $0, R1
+ MOVD $SYS_nanosleep, R8
+ SVC
+ RET
+
+TEXT runtime·gettid(SB),NOSPLIT,$0-4
+ MOVD $SYS_gettid, R8
+ SVC
+ MOVW R0, ret+0(FP)
+ RET
+
+TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
+ MOVD $SYS_getpid, R8
+ SVC
+ MOVW R0, R19
+ MOVD $SYS_gettid, R8
+ SVC
+ MOVW R0, R1 // arg 2 tid
+ MOVW R19, R0 // arg 1 pid
+ MOVW sig+0(FP), R2 // arg 3
+ MOVD $SYS_tgkill, R8
+ SVC
+ RET
+
+TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
+ MOVD $SYS_getpid, R8
+ SVC
+ MOVW R0, R0 // arg 1 pid
+ MOVW sig+0(FP), R1 // arg 2
+ MOVD $SYS_kill, R8
+ SVC
+ RET
+
+TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
+ MOVD $SYS_getpid, R8
+ SVC
+ MOVD R0, ret+0(FP)
+ RET
+
+TEXT ·tgkill(SB),NOSPLIT,$0-24
+ MOVD tgid+0(FP), R0
+ MOVD tid+8(FP), R1
+ MOVD sig+16(FP), R2
+ MOVD $SYS_tgkill, R8
+ SVC
+ RET
+
+TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
+ MOVW mode+0(FP), R0
+ MOVD new+8(FP), R1
+ MOVD old+16(FP), R2
+ MOVD $SYS_setitimer, R8
+ SVC
+ RET
+
+TEXT runtime·timer_create(SB),NOSPLIT,$0-28
+ MOVW clockid+0(FP), R0
+ MOVD sevp+8(FP), R1
+ MOVD timerid+16(FP), R2
+ MOVD $SYS_timer_create, R8
+ SVC
+ MOVW R0, ret+24(FP)
+ RET
+
+TEXT runtime·timer_settime(SB),NOSPLIT,$0-28
+ MOVW timerid+0(FP), R0
+ MOVW flags+4(FP), R1
+ MOVD new+8(FP), R2
+ MOVD old+16(FP), R3
+ MOVD $SYS_timer_settime, R8
+ SVC
+ MOVW R0, ret+24(FP)
+ RET
+
+TEXT runtime·timer_delete(SB),NOSPLIT,$0-12
+ MOVW timerid+0(FP), R0
+ MOVD $SYS_timer_delete, R8
+ SVC
+ MOVW R0, ret+8(FP)
+ RET
+
+TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
+ MOVD addr+0(FP), R0
+ MOVD n+8(FP), R1
+ MOVD dst+16(FP), R2
+ MOVD $SYS_mincore, R8
+ SVC
+ MOVW R0, ret+24(FP)
+ RET
+
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB),NOSPLIT,$24-12
+ MOVD RSP, R20 // R20 is unchanged by C code
+ MOVD RSP, R1
+
+ MOVD g_m(g), R21 // R21 = m
+
+ // Set vdsoPC and vdsoSP for SIGPROF traceback.
+ // Save the old values on stack and restore them on exit,
+ // so this function is reentrant.
+ MOVD m_vdsoPC(R21), R2
+ MOVD m_vdsoSP(R21), R3
+ MOVD R2, 8(RSP)
+ MOVD R3, 16(RSP)
+
+ MOVD $ret-8(FP), R2 // caller's SP
+ MOVD LR, m_vdsoPC(R21)
+ MOVD R2, m_vdsoSP(R21)
+
+ MOVD m_curg(R21), R0
+ CMP g, R0
+ BNE noswitch
+
+ MOVD m_g0(R21), R3
+ MOVD (g_sched+gobuf_sp)(R3), R1 // Set RSP to g0 stack
+
+noswitch:
+ SUB $16, R1
+ BIC $15, R1 // Align for C code
+ MOVD R1, RSP
+
+ MOVW $CLOCK_REALTIME, R0
+ MOVD runtime·vdsoClockgettimeSym(SB), R2
+ CBZ R2, fallback
+
+ // Store g on gsignal's stack, so if we receive a signal
+ // during VDSO code we can find the g.
+ // If we don't have a signal stack, we won't receive signal,
+ // so don't bother saving g.
+ // When using cgo, we already saved g on TLS, also don't save
+ // g here.
+ // Also don't save g if we are already on the signal stack.
+ // We won't get a nested signal.
+ MOVBU runtime·iscgo(SB), R22
+ CBNZ R22, nosaveg
+ MOVD m_gsignal(R21), R22 // g.m.gsignal
+ CBZ R22, nosaveg
+ CMP g, R22
+ BEQ nosaveg
+ MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
+ MOVD g, (R22)
+
+ BL (R2)
+
+ MOVD ZR, (R22) // clear g slot, R22 is unchanged by C code
+
+ B finish
+
+nosaveg:
+ BL (R2)
+ B finish
+
+fallback:
+ MOVD $SYS_clock_gettime, R8
+ SVC
+
+finish:
+ MOVD 0(RSP), R3 // sec
+ MOVD 8(RSP), R5 // nsec
+
+ MOVD R20, RSP // restore SP
+ // Restore vdsoPC, vdsoSP
+ // We don't worry about being signaled between the two stores.
+ // If we are not in a signal handler, we'll restore vdsoSP to 0,
+ // and no one will care about vdsoPC. If we are in a signal handler,
+ // we cannot receive another signal.
+ MOVD 16(RSP), R1
+ MOVD R1, m_vdsoSP(R21)
+ MOVD 8(RSP), R1
+ MOVD R1, m_vdsoPC(R21)
+
+ MOVD R3, sec+0(FP)
+ MOVW R5, nsec+8(FP)
+ RET
+
+TEXT runtime·nanotime1(SB),NOSPLIT,$24-8
+ MOVD RSP, R20 // R20 is unchanged by C code
+ MOVD RSP, R1
+
+ MOVD g_m(g), R21 // R21 = m
+
+ // Set vdsoPC and vdsoSP for SIGPROF traceback.
+ // Save the old values on stack and restore them on exit,
+ // so this function is reentrant.
+ MOVD m_vdsoPC(R21), R2
+ MOVD m_vdsoSP(R21), R3
+ MOVD R2, 8(RSP)
+ MOVD R3, 16(RSP)
+
+ MOVD $ret-8(FP), R2 // caller's SP
+ MOVD LR, m_vdsoPC(R21)
+ MOVD R2, m_vdsoSP(R21)
+
+ MOVD m_curg(R21), R0
+ CMP g, R0
+ BNE noswitch
+
+ MOVD m_g0(R21), R3
+ MOVD (g_sched+gobuf_sp)(R3), R1 // Set RSP to g0 stack
+
+noswitch:
+ SUB $32, R1
+ BIC $15, R1
+ MOVD R1, RSP
+
+ MOVW $CLOCK_MONOTONIC, R0
+ MOVD runtime·vdsoClockgettimeSym(SB), R2
+ CBZ R2, fallback
+
+ // Store g on gsignal's stack, so if we receive a signal
+ // during VDSO code we can find the g.
+ // If we don't have a signal stack, we won't receive signal,
+ // so don't bother saving g.
+ // When using cgo, we already saved g on TLS, also don't save
+ // g here.
+ // Also don't save g if we are already on the signal stack.
+ // We won't get a nested signal.
+ MOVBU runtime·iscgo(SB), R22
+ CBNZ R22, nosaveg
+ MOVD m_gsignal(R21), R22 // g.m.gsignal
+ CBZ R22, nosaveg
+ CMP g, R22
+ BEQ nosaveg
+ MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo
+ MOVD g, (R22)
+
+ BL (R2)
+
+ MOVD ZR, (R22) // clear g slot, R22 is unchanged by C code
+
+ B finish
+
+nosaveg:
+ BL (R2)
+ B finish
+
+fallback:
+ MOVD $SYS_clock_gettime, R8
+ SVC
+
+finish:
+ MOVD 0(RSP), R3 // sec
+ MOVD 8(RSP), R5 // nsec
+
+ MOVD R20, RSP // restore SP
+ // Restore vdsoPC, vdsoSP
+ // We don't worry about being signaled between the two stores.
+ // If we are not in a signal handler, we'll restore vdsoSP to 0,
+ // and no one will care about vdsoPC. If we are in a signal handler,
+ // we cannot receive another signal.
+ MOVD 16(RSP), R1
+ MOVD R1, m_vdsoSP(R21)
+ MOVD 8(RSP), R1
+ MOVD R1, m_vdsoPC(R21)
+
+ // sec is in R3, nsec in R5
+ // return nsec in R3
+ MOVD $1000000000, R4
+ MUL R4, R3
+ ADD R5, R3
+ MOVD R3, ret+0(FP)
+ RET
+
+TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
+ MOVW how+0(FP), R0
+ MOVD new+8(FP), R1
+ MOVD old+16(FP), R2
+ MOVW size+24(FP), R3
+ MOVD $SYS_rt_sigprocmask, R8
+ SVC
+ CMN $4095, R0
+ BCC done
+ MOVD $0, R0
+ MOVD R0, (R0) // crash
+done:
+ RET
+
+TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
+ MOVD sig+0(FP), R0
+ MOVD new+8(FP), R1
+ MOVD old+16(FP), R2
+ MOVD size+24(FP), R3
+ MOVD $SYS_rt_sigaction, R8
+ SVC
+ MOVW R0, ret+32(FP)
+ RET
+
+// Call the function stored in _cgo_sigaction using the GCC calling convention.
+TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0
+ MOVD sig+0(FP), R0
+ MOVD new+8(FP), R1
+ MOVD old+16(FP), R2
+ MOVD _cgo_sigaction(SB), R3
+ SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
+ BL R3
+ ADD $16, RSP
+ MOVW R0, ret+24(FP)
+ RET
+
+TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
+ MOVW sig+8(FP), R0
+ MOVD info+16(FP), R1
+ MOVD ctx+24(FP), R2
+ MOVD fn+0(FP), R11
+ BL (R11)
+ RET
+
+// Called from c-abi, R0: sig, R1: info, R2: cxt
+TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$176
+ // Save callee-save registers in the case of signal forwarding.
+ // Please refer to https://golang.org/issue/31827 .
+ SAVE_R19_TO_R28(8*4)
+ SAVE_F8_TO_F15(8*14)
+
+ // this might be called in external code context,
+ // where g is not set.
+ // first save R0, because runtime·load_g will clobber it
+ MOVW R0, 8(RSP)
+ MOVBU runtime·iscgo(SB), R0
+ CBZ R0, 2(PC)
+ BL runtime·load_g(SB)
+
+ // Restore signum to R0.
+ MOVW 8(RSP), R0
+ // R1 and R2 already contain info and ctx, respectively.
+ MOVD $runtime·sigtrampgo<ABIInternal>(SB), R3
+ BL (R3)
+
+ // Restore callee-save registers.
+ RESTORE_R19_TO_R28(8*4)
+ RESTORE_F8_TO_F15(8*14)
+
+ RET
+
+// Called from c-abi, R0: sig, R1: info, R2: cxt
+TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$176
+ // Save callee-save registers because it's a callback from c code.
+ SAVE_R19_TO_R28(8*4)
+ SAVE_F8_TO_F15(8*14)
+
+ // R0, R1 and R2 already contain sig, info and ctx, respectively.
+ CALL runtime·sigprofNonGo<ABIInternal>(SB)
+
+ // Restore callee-save registers.
+ RESTORE_R19_TO_R28(8*4)
+ RESTORE_F8_TO_F15(8*14)
+ RET
+
+// Called from c-abi, R0: sig, R1: info, R2: cxt
+TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0
+ // The stack unwinder, presumably written in C, may not be able to
+ // handle Go frame correctly. So, this function is NOFRAME, and we
+ // save/restore LR manually.
+ MOVD LR, R10
+ // Save R27, g because they will be clobbered,
+ // we need to restore them before jump to sigtramp.
+ MOVD R27, R11
+ MOVD g, R12
+
+ // If no traceback function, do usual sigtramp.
+ MOVD runtime·cgoTraceback(SB), R6
+ CBZ R6, sigtramp
+
+ // If no traceback support function, which means that
+ // runtime/cgo was not linked in, do usual sigtramp.
+ MOVD _cgo_callers(SB), R7
+ CBZ R7, sigtramp
+
+ // Figure out if we are currently in a cgo call.
+ // If not, just do usual sigtramp.
+ // first save R0, because runtime·load_g will clobber it.
+ MOVD R0, R8
+ // Set up g register.
+ CALL runtime·load_g(SB)
+ MOVD R8, R0
+
+ CBZ g, sigtrampnog // g == nil
+ MOVD g_m(g), R6
+ CBZ R6, sigtramp // g.m == nil
+ MOVW m_ncgo(R6), R7
+ CBZW R7, sigtramp // g.m.ncgo = 0
+ MOVD m_curg(R6), R8
+ CBZ R8, sigtramp // g.m.curg == nil
+ MOVD g_syscallsp(R8), R7
+ CBZ R7, sigtramp // g.m.curg.syscallsp == 0
+ MOVD m_cgoCallers(R6), R4 // R4 is the fifth arg in C calling convention.
+ CBZ R4, sigtramp // g.m.cgoCallers == nil
+ MOVW m_cgoCallersUse(R6), R8
+ CBNZW R8, sigtramp // g.m.cgoCallersUse != 0
+
+ // Jump to a function in runtime/cgo.
+ // That function, written in C, will call the user's traceback
+ // function with proper unwind info, and will then call back here.
+ // The first three arguments, and the fifth, are already in registers.
+ // Set the two remaining arguments now.
+ MOVD runtime·cgoTraceback(SB), R3
+ MOVD $runtime·sigtramp(SB), R5
+ MOVD _cgo_callers(SB), R13
+ MOVD R10, LR // restore
+ MOVD R11, R27
+ MOVD R12, g
+ B (R13)
+
+sigtramp:
+ MOVD R10, LR // restore
+ MOVD R11, R27
+ MOVD R12, g
+ B runtime·sigtramp(SB)
+
+sigtrampnog:
+ // Signal arrived on a non-Go thread. If this is SIGPROF, get a
+ // stack trace.
+ CMPW $27, R0 // 27 == SIGPROF
+ BNE sigtramp
+
+ // Lock sigprofCallersUse (cas from 0 to 1).
+ MOVW $1, R7
+ MOVD $runtime·sigprofCallersUse(SB), R8
+load_store_loop:
+ LDAXRW (R8), R9
+ CBNZW R9, sigtramp // Skip stack trace if already locked.
+ STLXRW R7, (R8), R9
+ CBNZ R9, load_store_loop
+
+ // Jump to the traceback function in runtime/cgo.
+ // It will call back to sigprofNonGo, which will ignore the
+ // arguments passed in registers.
+ // First three arguments to traceback function are in registers already.
+ MOVD runtime·cgoTraceback(SB), R3
+ MOVD $runtime·sigprofCallers(SB), R4
+ MOVD $runtime·sigprofNonGoWrapper<>(SB), R5
+ MOVD _cgo_callers(SB), R13
+ MOVD R10, LR // restore
+ MOVD R11, R27
+ MOVD R12, g
+ B (R13)
+
+TEXT runtime·sysMmap(SB),NOSPLIT|NOFRAME,$0
+ MOVD addr+0(FP), R0
+ MOVD n+8(FP), R1
+ MOVW prot+16(FP), R2
+ MOVW flags+20(FP), R3
+ MOVW fd+24(FP), R4
+ MOVW off+28(FP), R5
+
+ MOVD $SYS_mmap, R8
+ SVC
+ CMN $4095, R0
+ BCC ok
+ NEG R0,R0
+ MOVD $0, p+32(FP)
+ MOVD R0, err+40(FP)
+ RET
+ok:
+ MOVD R0, p+32(FP)
+ MOVD $0, err+40(FP)
+ RET
+
+// Call the function stored in _cgo_mmap using the GCC calling convention.
+// This must be called on the system stack.
+TEXT runtime·callCgoMmap(SB),NOSPLIT,$0
+ MOVD addr+0(FP), R0
+ MOVD n+8(FP), R1
+ MOVW prot+16(FP), R2
+ MOVW flags+20(FP), R3
+ MOVW fd+24(FP), R4
+ MOVW off+28(FP), R5
+ MOVD _cgo_mmap(SB), R9
+ SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
+ BL R9
+ ADD $16, RSP
+ MOVD R0, ret+32(FP)
+ RET
+
+TEXT runtime·sysMunmap(SB),NOSPLIT|NOFRAME,$0
+ MOVD addr+0(FP), R0
+ MOVD n+8(FP), R1
+ MOVD $SYS_munmap, R8
+ SVC
+ CMN $4095, R0
+ BCC cool
+ MOVD R0, 0xf0(R0)
+cool:
+ RET
+
+// Call the function stored in _cgo_munmap using the GCC calling convention.
+// This must be called on the system stack.
+TEXT runtime·callCgoMunmap(SB),NOSPLIT,$0
+ MOVD addr+0(FP), R0
+ MOVD n+8(FP), R1
+ MOVD _cgo_munmap(SB), R9
+ SUB $16, RSP // reserve 16 bytes for sp-8 where fp may be saved.
+ BL R9
+ ADD $16, RSP
+ RET
+
+TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
+ MOVD addr+0(FP), R0
+ MOVD n+8(FP), R1
+ MOVW flags+16(FP), R2
+ MOVD $SYS_madvise, R8
+ SVC
+ MOVW R0, ret+24(FP)
+ RET
+
+// int64 futex(int32 *uaddr, int32 op, int32 val,
+// struct timespec *timeout, int32 *uaddr2, int32 val2);
+TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
+ MOVD addr+0(FP), R0
+ MOVW op+8(FP), R1
+ MOVW val+12(FP), R2
+ MOVD ts+16(FP), R3
+ MOVD addr2+24(FP), R4
+ MOVW val3+32(FP), R5
+ MOVD $SYS_futex, R8
+ SVC
+ MOVW R0, ret+40(FP)
+ RET
+
+// int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
+TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
+ MOVW flags+0(FP), R0
+ MOVD stk+8(FP), R1
+
+ // Copy mp, gp, fn off parent stack for use by child.
+ MOVD mp+16(FP), R10
+ MOVD gp+24(FP), R11
+ MOVD fn+32(FP), R12
+
+ MOVD R10, -8(R1)
+ MOVD R11, -16(R1)
+ MOVD R12, -24(R1)
+ MOVD $1234, R10
+ MOVD R10, -32(R1)
+
+ MOVD $SYS_clone, R8
+ SVC
+
+ // In parent, return.
+ CMP ZR, R0
+ BEQ child
+ MOVW R0, ret+40(FP)
+ RET
+child:
+
+ // In child, on new stack.
+ MOVD -32(RSP), R10
+ MOVD $1234, R0
+ CMP R0, R10
+ BEQ good
+ MOVD $0, R0
+ MOVD R0, (R0) // crash
+
+good:
+ // Initialize m->procid to Linux tid
+ MOVD $SYS_gettid, R8
+ SVC
+
+ MOVD -24(RSP), R12 // fn
+ MOVD -16(RSP), R11 // g
+ MOVD -8(RSP), R10 // m
+
+ CMP $0, R10
+ BEQ nog
+ CMP $0, R11
+ BEQ nog
+
+ MOVD R0, m_procid(R10)
+
+ // TODO: setup TLS.
+
+ // In child, set up new stack
+ MOVD R10, g_m(R11)
+ MOVD R11, g
+ //CALL runtime·stackcheck(SB)
+
+nog:
+ // Call fn
+ MOVD R12, R0
+ BL (R0)
+
+ // It shouldn't return. If it does, exit that thread.
+ MOVW $111, R0
+again:
+ MOVD $SYS_exit, R8
+ SVC
+ B again // keep exiting
+
+TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
+ MOVD new+0(FP), R0
+ MOVD old+8(FP), R1
+ MOVD $SYS_sigaltstack, R8
+ SVC
+ CMN $4095, R0
+ BCC ok
+ MOVD $0, R0
+ MOVD R0, (R0) // crash
+ok:
+ RET
+
+TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
+ MOVD $SYS_sched_yield, R8
+ SVC
+ RET
+
+TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
+ MOVD pid+0(FP), R0
+ MOVD len+8(FP), R1
+ MOVD buf+16(FP), R2
+ MOVD $SYS_sched_getaffinity, R8
+ SVC
+ MOVW R0, ret+24(FP)
+ RET
+
+// int access(const char *name, int mode)
+TEXT runtime·access(SB),NOSPLIT,$0-20
+ MOVD $AT_FDCWD, R0
+ MOVD name+0(FP), R1
+ MOVW mode+8(FP), R2
+ MOVD $SYS_faccessat, R8
+ SVC
+ MOVW R0, ret+16(FP)
+ RET
+
+// int connect(int fd, const struct sockaddr *addr, socklen_t len)
+TEXT runtime·connect(SB),NOSPLIT,$0-28
+ MOVW fd+0(FP), R0
+ MOVD addr+8(FP), R1
+ MOVW len+16(FP), R2
+ MOVD $SYS_connect, R8
+ SVC
+ MOVW R0, ret+24(FP)
+ RET
+
+// int socket(int domain, int typ, int prot)
+TEXT runtime·socket(SB),NOSPLIT,$0-20
+ MOVW domain+0(FP), R0
+ MOVW typ+4(FP), R1
+ MOVW prot+8(FP), R2
+ MOVD $SYS_socket, R8
+ SVC
+ MOVW R0, ret+16(FP)
+ RET
+
+// func sbrk0() uintptr
+TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
+ // Implemented as brk(NULL).
+ MOVD $0, R0
+ MOVD $SYS_brk, R8
+ SVC
+ MOVD R0, ret+0(FP)
+ RET
diff --git a/contrib/go/_std_1.20/src/runtime/sys_nonppc64x.go b/contrib/go/_std_1.21/src/runtime/sys_nonppc64x.go
index 653f1c999f..653f1c999f 100644
--- a/contrib/go/_std_1.20/src/runtime/sys_nonppc64x.go
+++ b/contrib/go/_std_1.21/src/runtime/sys_nonppc64x.go
diff --git a/contrib/go/_std_1.21/src/runtime/sys_windows_amd64.s b/contrib/go/_std_1.21/src/runtime/sys_windows_amd64.s
new file mode 100644
index 0000000000..e66f444ff5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/sys_windows_amd64.s
@@ -0,0 +1,319 @@
+// Copyright 2011 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.
+
+#include "go_asm.h"
+#include "go_tls.h"
+#include "textflag.h"
+#include "time_windows.h"
+#include "cgo/abi_amd64.h"
+
+// Offsets into Thread Environment Block (pointer in GS)
+#define TEB_TlsSlots 0x1480
+#define TEB_ArbitraryPtr 0x28
+
+// void runtime·asmstdcall(void *c);
+TEXT runtime·asmstdcall(SB),NOSPLIT,$16
+ MOVQ SP, AX
+ ANDQ $~15, SP // alignment as per Windows requirement
+ MOVQ AX, 8(SP)
+ MOVQ CX, 0(SP) // asmcgocall will put first argument into CX.
+
+ MOVQ libcall_fn(CX), AX
+ MOVQ libcall_args(CX), SI
+ MOVQ libcall_n(CX), CX
+
+ // SetLastError(0).
+ MOVQ 0x30(GS), DI
+ MOVL $0, 0x68(DI)
+
+ SUBQ $(const_maxArgs*8), SP // room for args
+
+ // Fast version, do not store args on the stack.
+ CMPL CX, $4
+ JLE loadregs
+
+ // Check we have enough room for args.
+ CMPL CX, $const_maxArgs
+ JLE 2(PC)
+ INT $3 // not enough room -> crash
+
+ // Copy args to the stack.
+ MOVQ SP, DI
+ CLD
+ REP; MOVSQ
+ MOVQ SP, SI
+
+loadregs:
+ // Load first 4 args into correspondent registers.
+ MOVQ 0(SI), CX
+ MOVQ 8(SI), DX
+ MOVQ 16(SI), R8
+ MOVQ 24(SI), R9
+ // Floating point arguments are passed in the XMM
+ // registers. Set them here in case any of the arguments
+ // are floating point values. For details see
+ // https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
+ MOVQ CX, X0
+ MOVQ DX, X1
+ MOVQ R8, X2
+ MOVQ R9, X3
+
+ // Call stdcall function.
+ CALL AX
+
+ ADDQ $(const_maxArgs*8), SP
+
+ // Return result.
+ MOVQ 0(SP), CX
+ MOVQ 8(SP), SP
+ MOVQ AX, libcall_r1(CX)
+ // Floating point return values are returned in XMM0. Setting r2 to this
+ // value in case this call returned a floating point value. For details,
+ // see https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention
+ MOVQ X0, libcall_r2(CX)
+
+ // GetLastError().
+ MOVQ 0x30(GS), DI
+ MOVL 0x68(DI), AX
+ MOVQ AX, libcall_err(CX)
+
+ RET
+
+// faster get/set last error
+TEXT runtime·getlasterror(SB),NOSPLIT,$0
+ MOVQ 0x30(GS), AX
+ MOVL 0x68(AX), AX
+ MOVL AX, ret+0(FP)
+ RET
+
+// Called by Windows as a Vectored Exception Handler (VEH).
+// CX is pointer to struct containing
+// exception record and context pointers.
+// DX is the kind of sigtramp function.
+// Return value of sigtrampgo is stored in AX.
+TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0-0
+ // Switch from the host ABI to the Go ABI.
+ PUSH_REGS_HOST_TO_ABI0()
+
+ // Set up ABIInternal environment: cleared X15 and R14.
+ // R14 is cleared in case there's a non-zero value in there
+ // if called from a non-go thread.
+ XORPS X15, X15
+ XORQ R14, R14
+
+ get_tls(AX)
+ CMPQ AX, $0
+ JE 2(PC)
+ // Exception from Go thread, set R14.
+ MOVQ g(AX), R14
+
+ // Reserve space for spill slots.
+ ADJSP $16
+ MOVQ CX, AX
+ MOVQ DX, BX
+ // Calling ABIInternal because TLS might be nil.
+ CALL runtime·sigtrampgo<ABIInternal>(SB)
+ // Return value is already stored in AX.
+
+ ADJSP $-16
+
+ POP_REGS_HOST_TO_ABI0()
+ RET
+
+// Trampoline to resume execution from exception handler.
+// This is part of the control flow guard workaround.
+// It switches stacks and jumps to the continuation address.
+// R8 and R9 are set above at the end of sigtrampgo
+// in the context that starts executing at sigresume.
+TEXT runtime·sigresume(SB),NOSPLIT|NOFRAME,$0
+ MOVQ R8, SP
+ JMP R9
+
+TEXT runtime·exceptiontramp(SB),NOSPLIT|NOFRAME,$0
+ // PExceptionPointers already on CX
+ MOVQ $const_callbackVEH, DX
+ JMP sigtramp<>(SB)
+
+TEXT runtime·firstcontinuetramp(SB),NOSPLIT|NOFRAME,$0-0
+ // PExceptionPointers already on CX
+ MOVQ $const_callbackFirstVCH, DX
+ JMP sigtramp<>(SB)
+
+TEXT runtime·lastcontinuetramp(SB),NOSPLIT|NOFRAME,$0-0
+ // PExceptionPointers already on CX
+ MOVQ $const_callbackLastVCH, DX
+ JMP sigtramp<>(SB)
+
+TEXT runtime·callbackasm1(SB),NOSPLIT|NOFRAME,$0
+ // Construct args vector for cgocallback().
+ // By windows/amd64 calling convention first 4 args are in CX, DX, R8, R9
+ // args from the 5th on are on the stack.
+ // In any case, even if function has 0,1,2,3,4 args, there is reserved
+ // but uninitialized "shadow space" for the first 4 args.
+ // The values are in registers.
+ MOVQ CX, (16+0)(SP)
+ MOVQ DX, (16+8)(SP)
+ MOVQ R8, (16+16)(SP)
+ MOVQ R9, (16+24)(SP)
+ // R8 = address of args vector
+ LEAQ (16+0)(SP), R8
+
+ // remove return address from stack, we are not returning to callbackasm, but to its caller.
+ MOVQ 0(SP), AX
+ ADDQ $8, SP
+
+ // determine index into runtime·cbs table
+ MOVQ $runtime·callbackasm(SB), DX
+ SUBQ DX, AX
+ MOVQ $0, DX
+ MOVQ $5, CX // divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
+ DIVL CX
+ SUBQ $1, AX // subtract 1 because return PC is to the next slot
+
+ // Switch from the host ABI to the Go ABI.
+ PUSH_REGS_HOST_TO_ABI0()
+
+ // Create a struct callbackArgs on our stack to be passed as
+ // the "frame" to cgocallback and on to callbackWrap.
+ SUBQ $(24+callbackArgs__size), SP
+ MOVQ AX, (24+callbackArgs_index)(SP) // callback index
+ MOVQ R8, (24+callbackArgs_args)(SP) // address of args vector
+ MOVQ $0, (24+callbackArgs_result)(SP) // result
+ LEAQ 24(SP), AX
+ // Call cgocallback, which will call callbackWrap(frame).
+ MOVQ $0, 16(SP) // context
+ MOVQ AX, 8(SP) // frame (address of callbackArgs)
+ LEAQ ·callbackWrap<ABIInternal>(SB), BX // cgocallback takes an ABIInternal entry-point
+ MOVQ BX, 0(SP) // PC of function value to call (callbackWrap)
+ CALL ·cgocallback(SB)
+ // Get callback result.
+ MOVQ (24+callbackArgs_result)(SP), AX
+ ADDQ $(24+callbackArgs__size), SP
+
+ POP_REGS_HOST_TO_ABI0()
+
+ // The return value was placed in AX above.
+ RET
+
+// uint32 tstart_stdcall(M *newm);
+TEXT runtime·tstart_stdcall(SB),NOSPLIT|NOFRAME,$0
+ // Switch from the host ABI to the Go ABI.
+ PUSH_REGS_HOST_TO_ABI0()
+
+ // CX contains first arg newm
+ MOVQ m_g0(CX), DX // g
+
+ // Layout new m scheduler stack on os stack.
+ MOVQ SP, AX
+ MOVQ AX, (g_stack+stack_hi)(DX)
+ SUBQ $(64*1024), AX // initial stack size (adjusted later)
+ MOVQ AX, (g_stack+stack_lo)(DX)
+ ADDQ $const_stackGuard, AX
+ MOVQ AX, g_stackguard0(DX)
+ MOVQ AX, g_stackguard1(DX)
+
+ // Set up tls.
+ LEAQ m_tls(CX), DI
+ MOVQ CX, g_m(DX)
+ MOVQ DX, g(DI)
+ CALL runtime·settls(SB) // clobbers CX
+
+ CALL runtime·stackcheck(SB) // clobbers AX,CX
+ CALL runtime·mstart(SB)
+
+ POP_REGS_HOST_TO_ABI0()
+
+ XORL AX, AX // return 0 == success
+ RET
+
+// set tls base to DI
+TEXT runtime·settls(SB),NOSPLIT,$0
+ MOVQ runtime·tls_g(SB), CX
+ MOVQ DI, 0(CX)(GS)
+ RET
+
+// Runs on OS stack.
+// duration (in -100ns units) is in dt+0(FP).
+// g may be nil.
+// The function leaves room for 4 syscall parameters
+// (as per windows amd64 calling convention).
+TEXT runtime·usleep2(SB),NOSPLIT,$48-4
+ MOVLQSX dt+0(FP), BX
+ MOVQ SP, AX
+ ANDQ $~15, SP // alignment as per Windows requirement
+ MOVQ AX, 40(SP)
+ LEAQ 32(SP), R8 // ptime
+ MOVQ BX, (R8)
+ MOVQ $-1, CX // handle
+ MOVQ $0, DX // alertable
+ MOVQ runtime·_NtWaitForSingleObject(SB), AX
+ CALL AX
+ MOVQ 40(SP), SP
+ RET
+
+// Runs on OS stack.
+TEXT runtime·switchtothread(SB),NOSPLIT,$0
+ MOVQ SP, AX
+ ANDQ $~15, SP // alignment as per Windows requirement
+ SUBQ $(48), SP // room for SP and 4 args as per Windows requirement
+ // plus one extra word to keep stack 16 bytes aligned
+ MOVQ AX, 32(SP)
+ MOVQ runtime·_SwitchToThread(SB), AX
+ CALL AX
+ MOVQ 32(SP), SP
+ RET
+
+TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
+ CMPB runtime·useQPCTime(SB), $0
+ JNE useQPC
+ MOVQ $_INTERRUPT_TIME, DI
+ MOVQ time_lo(DI), AX
+ IMULQ $100, AX
+ MOVQ AX, ret+0(FP)
+ RET
+useQPC:
+ JMP runtime·nanotimeQPC(SB)
+ RET
+
+// func osSetupTLS(mp *m)
+// Setup TLS. for use by needm on Windows.
+TEXT runtime·osSetupTLS(SB),NOSPLIT,$0-8
+ MOVQ mp+0(FP), AX
+ LEAQ m_tls(AX), DI
+ CALL runtime·settls(SB)
+ RET
+
+// This is called from rt0_go, which runs on the system stack
+// using the initial stack allocated by the OS.
+TEXT runtime·wintls(SB),NOSPLIT,$0
+ // Allocate a TLS slot to hold g across calls to external code
+ MOVQ SP, AX
+ ANDQ $~15, SP // alignment as per Windows requirement
+ SUBQ $48, SP // room for SP and 4 args as per Windows requirement
+ // plus one extra word to keep stack 16 bytes aligned
+ MOVQ AX, 32(SP)
+ MOVQ runtime·_TlsAlloc(SB), AX
+ CALL AX
+ MOVQ 32(SP), SP
+
+ MOVQ AX, CX // TLS index
+
+ // Assert that slot is less than 64 so we can use _TEB->TlsSlots
+ CMPQ CX, $64
+ JB ok
+
+ // Fallback to the TEB arbitrary pointer.
+ // TODO: don't use the arbitrary pointer (see go.dev/issue/59824)
+ MOVQ $TEB_ArbitraryPtr, CX
+ JMP settls
+ok:
+ // Convert the TLS index at CX into
+ // an offset from TEB_TlsSlots.
+ SHLQ $3, CX
+
+ // Save offset from TLS into tls_g.
+ ADDQ $TEB_TlsSlots, CX
+settls:
+ MOVQ CX, runtime·tls_g(SB)
+ RET
diff --git a/contrib/go/_std_1.20/src/runtime/sys_x86.go b/contrib/go/_std_1.21/src/runtime/sys_x86.go
index 9fb36c2a66..9fb36c2a66 100644
--- a/contrib/go/_std_1.20/src/runtime/sys_x86.go
+++ b/contrib/go/_std_1.21/src/runtime/sys_x86.go
diff --git a/contrib/go/_std_1.21/src/runtime/syscall_windows.go b/contrib/go/_std_1.21/src/runtime/syscall_windows.go
new file mode 100644
index 0000000000..ba88e93d7d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/syscall_windows.go
@@ -0,0 +1,546 @@
+// Copyright 2014 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 runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "unsafe"
+)
+
+// cbs stores all registered Go callbacks.
+var cbs struct {
+ lock mutex // use cbsLock / cbsUnlock for race instrumentation.
+ ctxt [cb_max]winCallback
+ index map[winCallbackKey]int
+ n int
+}
+
+func cbsLock() {
+ lock(&cbs.lock)
+ // compileCallback is used by goenvs prior to completion of schedinit.
+ // raceacquire involves a racecallback to get the proc, which is not
+ // safe prior to scheduler initialization. Thus avoid instrumentation
+ // until then.
+ if raceenabled && mainStarted {
+ raceacquire(unsafe.Pointer(&cbs.lock))
+ }
+}
+
+func cbsUnlock() {
+ if raceenabled && mainStarted {
+ racerelease(unsafe.Pointer(&cbs.lock))
+ }
+ unlock(&cbs.lock)
+}
+
+// winCallback records information about a registered Go callback.
+type winCallback struct {
+ fn *funcval // Go function
+ retPop uintptr // For 386 cdecl, how many bytes to pop on return
+ abiMap abiDesc
+}
+
+// abiPartKind is the action an abiPart should take.
+type abiPartKind int
+
+const (
+ abiPartBad abiPartKind = iota
+ abiPartStack // Move a value from memory to the stack.
+ abiPartReg // Move a value from memory to a register.
+)
+
+// abiPart encodes a step in translating between calling ABIs.
+type abiPart struct {
+ kind abiPartKind
+ srcStackOffset uintptr
+ dstStackOffset uintptr // used if kind == abiPartStack
+ dstRegister int // used if kind == abiPartReg
+ len uintptr
+}
+
+func (a *abiPart) tryMerge(b abiPart) bool {
+ if a.kind != abiPartStack || b.kind != abiPartStack {
+ return false
+ }
+ if a.srcStackOffset+a.len == b.srcStackOffset && a.dstStackOffset+a.len == b.dstStackOffset {
+ a.len += b.len
+ return true
+ }
+ return false
+}
+
+// abiDesc specifies how to translate from a C frame to a Go
+// frame. This does not specify how to translate back because
+// the result is always a uintptr. If the C ABI is fastcall,
+// this assumes the four fastcall registers were first spilled
+// to the shadow space.
+type abiDesc struct {
+ parts []abiPart
+
+ srcStackSize uintptr // stdcall/fastcall stack space tracking
+ dstStackSize uintptr // Go stack space used
+ dstSpill uintptr // Extra stack space for argument spill slots
+ dstRegisters int // Go ABI int argument registers used
+
+ // retOffset is the offset of the uintptr-sized result in the Go
+ // frame.
+ retOffset uintptr
+}
+
+func (p *abiDesc) assignArg(t *_type) {
+ if t.Size_ > goarch.PtrSize {
+ // We don't support this right now. In
+ // stdcall/cdecl, 64-bit ints and doubles are
+ // passed as two words (little endian); and
+ // structs are pushed on the stack. In
+ // fastcall, arguments larger than the word
+ // size are passed by reference. On arm,
+ // 8-byte aligned arguments round up to the
+ // next even register and can be split across
+ // registers and the stack.
+ panic("compileCallback: argument size is larger than uintptr")
+ }
+ if k := t.Kind_ & kindMask; GOARCH != "386" && (k == kindFloat32 || k == kindFloat64) {
+ // In fastcall, floating-point arguments in
+ // the first four positions are passed in
+ // floating-point registers, which we don't
+ // currently spill. arm passes floating-point
+ // arguments in VFP registers, which we also
+ // don't support.
+ // So basically we only support 386.
+ panic("compileCallback: float arguments not supported")
+ }
+
+ if t.Size_ == 0 {
+ // The Go ABI aligns for zero-sized types.
+ p.dstStackSize = alignUp(p.dstStackSize, uintptr(t.Align_))
+ return
+ }
+
+ // In the C ABI, we're already on a word boundary.
+ // Also, sub-word-sized fastcall register arguments
+ // are stored to the least-significant bytes of the
+ // argument word and all supported Windows
+ // architectures are little endian, so srcStackOffset
+ // is already pointing to the right place for smaller
+ // arguments. The same is true on arm.
+
+ oldParts := p.parts
+ if p.tryRegAssignArg(t, 0) {
+ // Account for spill space.
+ //
+ // TODO(mknyszek): Remove this when we no longer have
+ // caller reserved spill space.
+ p.dstSpill = alignUp(p.dstSpill, uintptr(t.Align_))
+ p.dstSpill += t.Size_
+ } else {
+ // Register assignment failed.
+ // Undo the work and stack assign.
+ p.parts = oldParts
+
+ // The Go ABI aligns arguments.
+ p.dstStackSize = alignUp(p.dstStackSize, uintptr(t.Align_))
+
+ // Copy just the size of the argument. Note that this
+ // could be a small by-value struct, but C and Go
+ // struct layouts are compatible, so we can copy these
+ // directly, too.
+ part := abiPart{
+ kind: abiPartStack,
+ srcStackOffset: p.srcStackSize,
+ dstStackOffset: p.dstStackSize,
+ len: t.Size_,
+ }
+ // Add this step to the adapter.
+ if len(p.parts) == 0 || !p.parts[len(p.parts)-1].tryMerge(part) {
+ p.parts = append(p.parts, part)
+ }
+ // The Go ABI packs arguments.
+ p.dstStackSize += t.Size_
+ }
+
+ // cdecl, stdcall, fastcall, and arm pad arguments to word size.
+ // TODO(rsc): On arm and arm64 do we need to skip the caller's saved LR?
+ p.srcStackSize += goarch.PtrSize
+}
+
+// tryRegAssignArg tries to register-assign a value of type t.
+// If this type is nested in an aggregate type, then offset is the
+// offset of this type within its parent type.
+// Assumes t.size <= goarch.PtrSize and t.size != 0.
+//
+// Returns whether the assignment succeeded.
+func (p *abiDesc) tryRegAssignArg(t *_type, offset uintptr) bool {
+ switch k := t.Kind_ & kindMask; k {
+ case kindBool, kindInt, kindInt8, kindInt16, kindInt32, kindUint, kindUint8, kindUint16, kindUint32, kindUintptr, kindPtr, kindUnsafePointer:
+ // Assign a register for all these types.
+ return p.assignReg(t.Size_, offset)
+ case kindInt64, kindUint64:
+ // Only register-assign if the registers are big enough.
+ if goarch.PtrSize == 8 {
+ return p.assignReg(t.Size_, offset)
+ }
+ case kindArray:
+ at := (*arraytype)(unsafe.Pointer(t))
+ if at.Len == 1 {
+ return p.tryRegAssignArg(at.Elem, offset) // TODO fix when runtime is fully commoned up w/ abi.Type
+ }
+ case kindStruct:
+ st := (*structtype)(unsafe.Pointer(t))
+ for i := range st.Fields {
+ f := &st.Fields[i]
+ if !p.tryRegAssignArg(f.Typ, offset+f.Offset) {
+ return false
+ }
+ }
+ return true
+ }
+ // Pointer-sized types such as maps and channels are currently
+ // not supported.
+ panic("compileCallback: type " + toRType(t).string() + " is currently not supported for use in system callbacks")
+}
+
+// assignReg attempts to assign a single register for an
+// argument with the given size, at the given offset into the
+// value in the C ABI space.
+//
+// Returns whether the assignment was successful.
+func (p *abiDesc) assignReg(size, offset uintptr) bool {
+ if p.dstRegisters >= intArgRegs {
+ return false
+ }
+ p.parts = append(p.parts, abiPart{
+ kind: abiPartReg,
+ srcStackOffset: p.srcStackSize + offset,
+ dstRegister: p.dstRegisters,
+ len: size,
+ })
+ p.dstRegisters++
+ return true
+}
+
+type winCallbackKey struct {
+ fn *funcval
+ cdecl bool
+}
+
+func callbackasm()
+
+// callbackasmAddr returns address of runtime.callbackasm
+// function adjusted by i.
+// On x86 and amd64, runtime.callbackasm is a series of CALL instructions,
+// and we want callback to arrive at
+// correspondent call instruction instead of start of
+// runtime.callbackasm.
+// On ARM, runtime.callbackasm is a series of mov and branch instructions.
+// R12 is loaded with the callback index. Each entry is two instructions,
+// hence 8 bytes.
+func callbackasmAddr(i int) uintptr {
+ var entrySize int
+ switch GOARCH {
+ default:
+ panic("unsupported architecture")
+ case "386", "amd64":
+ entrySize = 5
+ case "arm", "arm64":
+ // On ARM and ARM64, each entry is a MOV instruction
+ // followed by a branch instruction
+ entrySize = 8
+ }
+ return abi.FuncPCABI0(callbackasm) + uintptr(i*entrySize)
+}
+
+const callbackMaxFrame = 64 * goarch.PtrSize
+
+// compileCallback converts a Go function fn into a C function pointer
+// that can be passed to Windows APIs.
+//
+// On 386, if cdecl is true, the returned C function will use the
+// cdecl calling convention; otherwise, it will use stdcall. On amd64,
+// it always uses fastcall. On arm, it always uses the ARM convention.
+//
+//go:linkname compileCallback syscall.compileCallback
+func compileCallback(fn eface, cdecl bool) (code uintptr) {
+ if GOARCH != "386" {
+ // cdecl is only meaningful on 386.
+ cdecl = false
+ }
+
+ if fn._type == nil || (fn._type.Kind_&kindMask) != kindFunc {
+ panic("compileCallback: expected function with one uintptr-sized result")
+ }
+ ft := (*functype)(unsafe.Pointer(fn._type))
+
+ // Check arguments and construct ABI translation.
+ var abiMap abiDesc
+ for _, t := range ft.InSlice() {
+ abiMap.assignArg(t)
+ }
+ // The Go ABI aligns the result to the word size. src is
+ // already aligned.
+ abiMap.dstStackSize = alignUp(abiMap.dstStackSize, goarch.PtrSize)
+ abiMap.retOffset = abiMap.dstStackSize
+
+ if len(ft.OutSlice()) != 1 {
+ panic("compileCallback: expected function with one uintptr-sized result")
+ }
+ if ft.OutSlice()[0].Size_ != goarch.PtrSize {
+ panic("compileCallback: expected function with one uintptr-sized result")
+ }
+ if k := ft.OutSlice()[0].Kind_ & kindMask; k == kindFloat32 || k == kindFloat64 {
+ // In cdecl and stdcall, float results are returned in
+ // ST(0). In fastcall, they're returned in XMM0.
+ // Either way, it's not AX.
+ panic("compileCallback: float results not supported")
+ }
+ if intArgRegs == 0 {
+ // Make room for the uintptr-sized result.
+ // If there are argument registers, the return value will
+ // be passed in the first register.
+ abiMap.dstStackSize += goarch.PtrSize
+ }
+
+ // TODO(mknyszek): Remove dstSpill from this calculation when we no longer have
+ // caller reserved spill space.
+ frameSize := alignUp(abiMap.dstStackSize, goarch.PtrSize)
+ frameSize += abiMap.dstSpill
+ if frameSize > callbackMaxFrame {
+ panic("compileCallback: function argument frame too large")
+ }
+
+ // For cdecl, the callee is responsible for popping its
+ // arguments from the C stack.
+ var retPop uintptr
+ if cdecl {
+ retPop = abiMap.srcStackSize
+ }
+
+ key := winCallbackKey{(*funcval)(fn.data), cdecl}
+
+ cbsLock()
+
+ // Check if this callback is already registered.
+ if n, ok := cbs.index[key]; ok {
+ cbsUnlock()
+ return callbackasmAddr(n)
+ }
+
+ // Register the callback.
+ if cbs.index == nil {
+ cbs.index = make(map[winCallbackKey]int)
+ }
+ n := cbs.n
+ if n >= len(cbs.ctxt) {
+ cbsUnlock()
+ throw("too many callback functions")
+ }
+ c := winCallback{key.fn, retPop, abiMap}
+ cbs.ctxt[n] = c
+ cbs.index[key] = n
+ cbs.n++
+
+ cbsUnlock()
+ return callbackasmAddr(n)
+}
+
+type callbackArgs struct {
+ index uintptr
+ // args points to the argument block.
+ //
+ // For cdecl and stdcall, all arguments are on the stack.
+ //
+ // For fastcall, the trampoline spills register arguments to
+ // the reserved spill slots below the stack arguments,
+ // resulting in a layout equivalent to stdcall.
+ //
+ // For arm, the trampoline stores the register arguments just
+ // below the stack arguments, so again we can treat it as one
+ // big stack arguments frame.
+ args unsafe.Pointer
+ // Below are out-args from callbackWrap
+ result uintptr
+ retPop uintptr // For 386 cdecl, how many bytes to pop on return
+}
+
+// callbackWrap is called by callbackasm to invoke a registered C callback.
+func callbackWrap(a *callbackArgs) {
+ c := cbs.ctxt[a.index]
+ a.retPop = c.retPop
+
+ // Convert from C to Go ABI.
+ var regs abi.RegArgs
+ var frame [callbackMaxFrame]byte
+ goArgs := unsafe.Pointer(&frame)
+ for _, part := range c.abiMap.parts {
+ switch part.kind {
+ case abiPartStack:
+ memmove(add(goArgs, part.dstStackOffset), add(a.args, part.srcStackOffset), part.len)
+ case abiPartReg:
+ goReg := unsafe.Pointer(&regs.Ints[part.dstRegister])
+ memmove(goReg, add(a.args, part.srcStackOffset), part.len)
+ default:
+ panic("bad ABI description")
+ }
+ }
+
+ // TODO(mknyszek): Remove this when we no longer have
+ // caller reserved spill space.
+ frameSize := alignUp(c.abiMap.dstStackSize, goarch.PtrSize)
+ frameSize += c.abiMap.dstSpill
+
+ // Even though this is copying back results, we can pass a nil
+ // type because those results must not require write barriers.
+ reflectcall(nil, unsafe.Pointer(c.fn), noescape(goArgs), uint32(c.abiMap.dstStackSize), uint32(c.abiMap.retOffset), uint32(frameSize), &regs)
+
+ // Extract the result.
+ //
+ // There's always exactly one return value, one pointer in size.
+ // If it's on the stack, then we will have reserved space for it
+ // at the end of the frame, otherwise it was passed in a register.
+ if c.abiMap.dstStackSize != c.abiMap.retOffset {
+ a.result = *(*uintptr)(unsafe.Pointer(&frame[c.abiMap.retOffset]))
+ } else {
+ var zero int
+ // On architectures with no registers, Ints[0] would be a compile error,
+ // so we use a dynamic index. These architectures will never take this
+ // branch, so this won't cause a runtime panic.
+ a.result = regs.Ints[zero]
+ }
+}
+
+const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
+
+//go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary
+//go:nosplit
+//go:cgo_unsafe_args
+func syscall_loadsystemlibrary(filename *uint16) (handle, err uintptr) {
+ lockOSThread()
+ c := &getg().m.syscall
+ c.fn = getLoadLibraryEx()
+ c.n = 3
+ args := struct {
+ lpFileName *uint16
+ hFile uintptr // always 0
+ flags uint32
+ }{filename, 0, _LOAD_LIBRARY_SEARCH_SYSTEM32}
+ c.args = uintptr(noescape(unsafe.Pointer(&args)))
+
+ cgocall(asmstdcallAddr, unsafe.Pointer(c))
+ KeepAlive(filename)
+ handle = c.r1
+ if handle == 0 {
+ err = c.err
+ }
+ unlockOSThread() // not defer'd after the lockOSThread above to save stack frame size.
+ return
+}
+
+//go:linkname syscall_loadlibrary syscall.loadlibrary
+//go:nosplit
+//go:cgo_unsafe_args
+func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
+ lockOSThread()
+ defer unlockOSThread()
+ c := &getg().m.syscall
+ c.fn = getLoadLibrary()
+ c.n = 1
+ c.args = uintptr(noescape(unsafe.Pointer(&filename)))
+ cgocall(asmstdcallAddr, unsafe.Pointer(c))
+ KeepAlive(filename)
+ handle = c.r1
+ if handle == 0 {
+ err = c.err
+ }
+ return
+}
+
+//go:linkname syscall_getprocaddress syscall.getprocaddress
+//go:nosplit
+//go:cgo_unsafe_args
+func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
+ lockOSThread()
+ defer unlockOSThread()
+ c := &getg().m.syscall
+ c.fn = getGetProcAddress()
+ c.n = 2
+ c.args = uintptr(noescape(unsafe.Pointer(&handle)))
+ cgocall(asmstdcallAddr, unsafe.Pointer(c))
+ KeepAlive(procname)
+ outhandle = c.r1
+ if outhandle == 0 {
+ err = c.err
+ }
+ return
+}
+
+//go:linkname syscall_Syscall syscall.Syscall
+//go:nosplit
+func syscall_Syscall(fn, nargs, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
+ return syscall_SyscallN(fn, a1, a2, a3)
+}
+
+//go:linkname syscall_Syscall6 syscall.Syscall6
+//go:nosplit
+func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
+ return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6)
+}
+
+//go:linkname syscall_Syscall9 syscall.Syscall9
+//go:nosplit
+func syscall_Syscall9(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
+ return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9)
+}
+
+//go:linkname syscall_Syscall12 syscall.Syscall12
+//go:nosplit
+func syscall_Syscall12(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2, err uintptr) {
+ return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12)
+}
+
+//go:linkname syscall_Syscall15 syscall.Syscall15
+//go:nosplit
+func syscall_Syscall15(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) {
+ return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
+}
+
+//go:linkname syscall_Syscall18 syscall.Syscall18
+//go:nosplit
+func syscall_Syscall18(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 uintptr) (r1, r2, err uintptr) {
+ return syscall_SyscallN(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18)
+}
+
+// maxArgs should be divisible by 2, as Windows stack
+// must be kept 16-byte aligned on syscall entry.
+//
+// Although it only permits maximum 42 parameters, it
+// is arguably large enough.
+const maxArgs = 42
+
+//go:linkname syscall_SyscallN syscall.SyscallN
+//go:nosplit
+func syscall_SyscallN(trap uintptr, args ...uintptr) (r1, r2, err uintptr) {
+ nargs := len(args)
+
+ // asmstdcall expects it can access the first 4 arguments
+ // to load them into registers.
+ var tmp [4]uintptr
+ switch {
+ case nargs < 4:
+ copy(tmp[:], args)
+ args = tmp[:]
+ case nargs > maxArgs:
+ panic("runtime: SyscallN has too many arguments")
+ }
+
+ lockOSThread()
+ defer unlockOSThread()
+ c := &getg().m.syscall
+ c.fn = trap
+ c.n = uintptr(nargs)
+ c.args = uintptr(noescape(unsafe.Pointer(&args[0])))
+ cgocall(asmstdcallAddr, unsafe.Pointer(c))
+ return c.r1, c.r2, c.err
+}
diff --git a/contrib/go/_std_1.21/src/runtime/tagptr.go b/contrib/go/_std_1.21/src/runtime/tagptr.go
new file mode 100644
index 0000000000..0e17a1598f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/tagptr.go
@@ -0,0 +1,14 @@
+// Copyright 2023 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 runtime
+
+// taggedPointer is a pointer with a numeric tag.
+// The size of the numeric tag is GOARCH-dependent,
+// currently at least 10 bits.
+// This should only be used with pointers allocated outside the Go heap.
+type taggedPointer uint64
+
+// minTagBits is the minimum number of tag bits that we expect.
+const minTagBits = 10
diff --git a/contrib/go/_std_1.21/src/runtime/tagptr_64bit.go b/contrib/go/_std_1.21/src/runtime/tagptr_64bit.go
new file mode 100644
index 0000000000..9ff11ccd16
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/tagptr_64bit.go
@@ -0,0 +1,89 @@
+// Copyright 2014 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.
+
+//go:build amd64 || arm64 || loong64 || mips64 || mips64le || ppc64 || ppc64le || riscv64 || s390x || wasm
+
+package runtime
+
+import (
+ "internal/goarch"
+ "internal/goos"
+ "unsafe"
+)
+
+const (
+ // addrBits is the number of bits needed to represent a virtual address.
+ //
+ // See heapAddrBits for a table of address space sizes on
+ // various architectures. 48 bits is enough for all
+ // architectures except s390x.
+ //
+ // On AMD64, virtual addresses are 48-bit (or 57-bit) numbers sign extended to 64.
+ // We shift the address left 16 to eliminate the sign extended part and make
+ // room in the bottom for the count.
+ //
+ // On s390x, virtual addresses are 64-bit. There's not much we
+ // can do about this, so we just hope that the kernel doesn't
+ // get to really high addresses and panic if it does.
+ addrBits = 48
+
+ // In addition to the 16 bits taken from the top, we can take 3 from the
+ // bottom, because node must be pointer-aligned, giving a total of 19 bits
+ // of count.
+ tagBits = 64 - addrBits + 3
+
+ // On AIX, 64-bit addresses are split into 36-bit segment number and 28-bit
+ // offset in segment. Segment numbers in the range 0x0A0000000-0x0AFFFFFFF(LSA)
+ // are available for mmap.
+ // We assume all tagged addresses are from memory allocated with mmap.
+ // We use one bit to distinguish between the two ranges.
+ aixAddrBits = 57
+ aixTagBits = 64 - aixAddrBits + 3
+
+ // riscv64 SV57 mode gives 56 bits of userspace VA.
+ // tagged pointer code supports it,
+ // but broader support for SV57 mode is incomplete,
+ // and there may be other issues (see #54104).
+ riscv64AddrBits = 56
+ riscv64TagBits = 64 - riscv64AddrBits + 3
+)
+
+// The number of bits stored in the numeric tag of a taggedPointer
+const taggedPointerBits = (goos.IsAix * aixTagBits) + (goarch.IsRiscv64 * riscv64TagBits) + ((1 - goos.IsAix) * (1 - goarch.IsRiscv64) * tagBits)
+
+// taggedPointerPack created a taggedPointer from a pointer and a tag.
+// Tag bits that don't fit in the result are discarded.
+func taggedPointerPack(ptr unsafe.Pointer, tag uintptr) taggedPointer {
+ if GOOS == "aix" {
+ if GOARCH != "ppc64" {
+ throw("check this code for aix on non-ppc64")
+ }
+ return taggedPointer(uint64(uintptr(ptr))<<(64-aixAddrBits) | uint64(tag&(1<<aixTagBits-1)))
+ }
+ if GOARCH == "riscv64" {
+ return taggedPointer(uint64(uintptr(ptr))<<(64-riscv64AddrBits) | uint64(tag&(1<<riscv64TagBits-1)))
+ }
+ return taggedPointer(uint64(uintptr(ptr))<<(64-addrBits) | uint64(tag&(1<<tagBits-1)))
+}
+
+// Pointer returns the pointer from a taggedPointer.
+func (tp taggedPointer) pointer() unsafe.Pointer {
+ if GOARCH == "amd64" {
+ // amd64 systems can place the stack above the VA hole, so we need to sign extend
+ // val before unpacking.
+ return unsafe.Pointer(uintptr(int64(tp) >> tagBits << 3))
+ }
+ if GOOS == "aix" {
+ return unsafe.Pointer(uintptr((tp >> aixTagBits << 3) | 0xa<<56))
+ }
+ if GOARCH == "riscv64" {
+ return unsafe.Pointer(uintptr(tp >> riscv64TagBits << 3))
+ }
+ return unsafe.Pointer(uintptr(tp >> tagBits << 3))
+}
+
+// Tag returns the tag from a taggedPointer.
+func (tp taggedPointer) tag() uintptr {
+ return uintptr(tp & (1<<taggedPointerBits - 1))
+}
diff --git a/contrib/go/_std_1.21/src/runtime/test_amd64.go b/contrib/go/_std_1.21/src/runtime/test_amd64.go
new file mode 100644
index 0000000000..70c7a4fd84
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/test_amd64.go
@@ -0,0 +1,7 @@
+// Copyright 2023 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 runtime
+
+func testSPWrite()
diff --git a/contrib/go/_std_1.21/src/runtime/test_amd64.s b/contrib/go/_std_1.21/src/runtime/test_amd64.s
new file mode 100644
index 0000000000..80fa8c9948
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/test_amd64.s
@@ -0,0 +1,7 @@
+// Create a large frame to force stack growth. See #62326.
+TEXT ·testSPWrite(SB),0,$16384-0
+ // Write to SP
+ MOVQ SP, AX
+ ANDQ $~0xf, SP
+ MOVQ AX, SP
+ RET
diff --git a/contrib/go/_std_1.21/src/runtime/test_stubs.go b/contrib/go/_std_1.21/src/runtime/test_stubs.go
new file mode 100644
index 0000000000..cefc32481d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/test_stubs.go
@@ -0,0 +1,9 @@
+// Copyright 2023 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.
+
+//go:build !amd64
+
+package runtime
+
+func testSPWrite() {}
diff --git a/contrib/go/_std_1.21/src/runtime/textflag.h b/contrib/go/_std_1.21/src/runtime/textflag.h
new file mode 100644
index 0000000000..8930312201
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/textflag.h
@@ -0,0 +1,38 @@
+// Copyright 2013 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.
+
+// This file defines flags attached to various functions
+// and data objects. The compilers, assemblers, and linker must
+// all agree on these values.
+//
+// Keep in sync with src/cmd/internal/obj/textflag.go.
+
+// Don't profile the marked routine. This flag is deprecated.
+#define NOPROF 1
+// It is ok for the linker to get multiple of these symbols. It will
+// pick one of the duplicates to use.
+#define DUPOK 2
+// Don't insert stack check preamble.
+#define NOSPLIT 4
+// Put this data in a read-only section.
+#define RODATA 8
+// This data contains no pointers.
+#define NOPTR 16
+// This is a wrapper function and should not count as disabling 'recover'.
+#define WRAPPER 32
+// This function uses its incoming context register.
+#define NEEDCTXT 64
+// Allocate a word of thread local storage and store the offset from the
+// thread local base to the thread local storage in this variable.
+#define TLSBSS 256
+// Do not insert instructions to allocate a stack frame for this function.
+// Only valid on functions that declare a frame size of 0.
+#define NOFRAME 512
+// Function can call reflect.Type.Method or reflect.Type.MethodByName.
+#define REFLECTMETHOD 1024
+// Function is the outermost frame of the call stack. Call stack unwinders
+// should stop at this function.
+#define TOPFRAME 2048
+// Function is an ABI wrapper.
+#define ABIWRAPPER 4096
diff --git a/contrib/go/_std_1.21/src/runtime/time.go b/contrib/go/_std_1.21/src/runtime/time.go
new file mode 100644
index 0000000000..c05351cb8e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/time.go
@@ -0,0 +1,1144 @@
+// Copyright 2009 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.
+
+// Time-related runtime and pieces of package time.
+
+package runtime
+
+import (
+ "internal/abi"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// Package time knows the layout of this structure.
+// If this struct changes, adjust ../time/sleep.go:/runtimeTimer.
+type timer struct {
+ // If this timer is on a heap, which P's heap it is on.
+ // puintptr rather than *p to match uintptr in the versions
+ // of this struct defined in other packages.
+ pp puintptr
+
+ // Timer wakes up at when, and then at when+period, ... (period > 0 only)
+ // each time calling f(arg, now) in the timer goroutine, so f must be
+ // a well-behaved function and not block.
+ //
+ // when must be positive on an active timer.
+ when int64
+ period int64
+ f func(any, uintptr)
+ arg any
+ seq uintptr
+
+ // What to set the when field to in timerModifiedXX status.
+ nextwhen int64
+
+ // The status field holds one of the values below.
+ status atomic.Uint32
+}
+
+// Code outside this file has to be careful in using a timer value.
+//
+// The pp, status, and nextwhen fields may only be used by code in this file.
+//
+// Code that creates a new timer value can set the when, period, f,
+// arg, and seq fields.
+// A new timer value may be passed to addtimer (called by time.startTimer).
+// After doing that no fields may be touched.
+//
+// An active timer (one that has been passed to addtimer) may be
+// passed to deltimer (time.stopTimer), after which it is no longer an
+// active timer. It is an inactive timer.
+// In an inactive timer the period, f, arg, and seq fields may be modified,
+// but not the when field.
+// It's OK to just drop an inactive timer and let the GC collect it.
+// It's not OK to pass an inactive timer to addtimer.
+// Only newly allocated timer values may be passed to addtimer.
+//
+// An active timer may be passed to modtimer. No fields may be touched.
+// It remains an active timer.
+//
+// An inactive timer may be passed to resettimer to turn into an
+// active timer with an updated when field.
+// It's OK to pass a newly allocated timer value to resettimer.
+//
+// Timer operations are addtimer, deltimer, modtimer, resettimer,
+// cleantimers, adjusttimers, and runtimer.
+//
+// We don't permit calling addtimer/deltimer/modtimer/resettimer simultaneously,
+// but adjusttimers and runtimer can be called at the same time as any of those.
+//
+// Active timers live in heaps attached to P, in the timers field.
+// Inactive timers live there too temporarily, until they are removed.
+//
+// addtimer:
+// timerNoStatus -> timerWaiting
+// anything else -> panic: invalid value
+// deltimer:
+// timerWaiting -> timerModifying -> timerDeleted
+// timerModifiedEarlier -> timerModifying -> timerDeleted
+// timerModifiedLater -> timerModifying -> timerDeleted
+// timerNoStatus -> do nothing
+// timerDeleted -> do nothing
+// timerRemoving -> do nothing
+// timerRemoved -> do nothing
+// timerRunning -> wait until status changes
+// timerMoving -> wait until status changes
+// timerModifying -> wait until status changes
+// modtimer:
+// timerWaiting -> timerModifying -> timerModifiedXX
+// timerModifiedXX -> timerModifying -> timerModifiedYY
+// timerNoStatus -> timerModifying -> timerWaiting
+// timerRemoved -> timerModifying -> timerWaiting
+// timerDeleted -> timerModifying -> timerModifiedXX
+// timerRunning -> wait until status changes
+// timerMoving -> wait until status changes
+// timerRemoving -> wait until status changes
+// timerModifying -> wait until status changes
+// cleantimers (looks in P's timer heap):
+// timerDeleted -> timerRemoving -> timerRemoved
+// timerModifiedXX -> timerMoving -> timerWaiting
+// adjusttimers (looks in P's timer heap):
+// timerDeleted -> timerRemoving -> timerRemoved
+// timerModifiedXX -> timerMoving -> timerWaiting
+// runtimer (looks in P's timer heap):
+// timerNoStatus -> panic: uninitialized timer
+// timerWaiting -> timerWaiting or
+// timerWaiting -> timerRunning -> timerNoStatus or
+// timerWaiting -> timerRunning -> timerWaiting
+// timerModifying -> wait until status changes
+// timerModifiedXX -> timerMoving -> timerWaiting
+// timerDeleted -> timerRemoving -> timerRemoved
+// timerRunning -> panic: concurrent runtimer calls
+// timerRemoved -> panic: inconsistent timer heap
+// timerRemoving -> panic: inconsistent timer heap
+// timerMoving -> panic: inconsistent timer heap
+
+// Values for the timer status field.
+const (
+ // Timer has no status set yet.
+ timerNoStatus = iota
+
+ // Waiting for timer to fire.
+ // The timer is in some P's heap.
+ timerWaiting
+
+ // Running the timer function.
+ // A timer will only have this status briefly.
+ timerRunning
+
+ // The timer is deleted and should be removed.
+ // It should not be run, but it is still in some P's heap.
+ timerDeleted
+
+ // The timer is being removed.
+ // The timer will only have this status briefly.
+ timerRemoving
+
+ // The timer has been stopped.
+ // It is not in any P's heap.
+ timerRemoved
+
+ // The timer is being modified.
+ // The timer will only have this status briefly.
+ timerModifying
+
+ // The timer has been modified to an earlier time.
+ // The new when value is in the nextwhen field.
+ // The timer is in some P's heap, possibly in the wrong place.
+ timerModifiedEarlier
+
+ // The timer has been modified to the same or a later time.
+ // The new when value is in the nextwhen field.
+ // The timer is in some P's heap, possibly in the wrong place.
+ timerModifiedLater
+
+ // The timer has been modified and is being moved.
+ // The timer will only have this status briefly.
+ timerMoving
+)
+
+// maxWhen is the maximum value for timer's when field.
+const maxWhen = 1<<63 - 1
+
+// verifyTimers can be set to true to add debugging checks that the
+// timer heaps are valid.
+const verifyTimers = false
+
+// Package time APIs.
+// Godoc uses the comments in package time, not these.
+
+// time.now is implemented in assembly.
+
+// timeSleep puts the current goroutine to sleep for at least ns nanoseconds.
+//
+//go:linkname timeSleep time.Sleep
+func timeSleep(ns int64) {
+ if ns <= 0 {
+ return
+ }
+
+ gp := getg()
+ t := gp.timer
+ if t == nil {
+ t = new(timer)
+ gp.timer = t
+ }
+ t.f = goroutineReady
+ t.arg = gp
+ t.nextwhen = nanotime() + ns
+ if t.nextwhen < 0 { // check for overflow.
+ t.nextwhen = maxWhen
+ }
+ gopark(resetForSleep, unsafe.Pointer(t), waitReasonSleep, traceBlockSleep, 1)
+}
+
+// resetForSleep is called after the goroutine is parked for timeSleep.
+// We can't call resettimer in timeSleep itself because if this is a short
+// sleep and there are many goroutines then the P can wind up running the
+// timer function, goroutineReady, before the goroutine has been parked.
+func resetForSleep(gp *g, ut unsafe.Pointer) bool {
+ t := (*timer)(ut)
+ resettimer(t, t.nextwhen)
+ return true
+}
+
+// startTimer adds t to the timer heap.
+//
+//go:linkname startTimer time.startTimer
+func startTimer(t *timer) {
+ if raceenabled {
+ racerelease(unsafe.Pointer(t))
+ }
+ addtimer(t)
+}
+
+// stopTimer stops a timer.
+// It reports whether t was stopped before being run.
+//
+//go:linkname stopTimer time.stopTimer
+func stopTimer(t *timer) bool {
+ return deltimer(t)
+}
+
+// resetTimer resets an inactive timer, adding it to the heap.
+//
+// Reports whether the timer was modified before it was run.
+//
+//go:linkname resetTimer time.resetTimer
+func resetTimer(t *timer, when int64) bool {
+ if raceenabled {
+ racerelease(unsafe.Pointer(t))
+ }
+ return resettimer(t, when)
+}
+
+// modTimer modifies an existing timer.
+//
+//go:linkname modTimer time.modTimer
+func modTimer(t *timer, when, period int64, f func(any, uintptr), arg any, seq uintptr) {
+ modtimer(t, when, period, f, arg, seq)
+}
+
+// Go runtime.
+
+// Ready the goroutine arg.
+func goroutineReady(arg any, seq uintptr) {
+ goready(arg.(*g), 0)
+}
+
+// Note: this changes some unsynchronized operations to synchronized operations
+// addtimer adds a timer to the current P.
+// This should only be called with a newly created timer.
+// That avoids the risk of changing the when field of a timer in some P's heap,
+// which could cause the heap to become unsorted.
+func addtimer(t *timer) {
+ // when must be positive. A negative value will cause runtimer to
+ // overflow during its delta calculation and never expire other runtime
+ // timers. Zero will cause checkTimers to fail to notice the timer.
+ if t.when <= 0 {
+ throw("timer when must be positive")
+ }
+ if t.period < 0 {
+ throw("timer period must be non-negative")
+ }
+ if t.status.Load() != timerNoStatus {
+ throw("addtimer called with initialized timer")
+ }
+ t.status.Store(timerWaiting)
+
+ 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)
+ doaddtimer(pp, t)
+ unlock(&pp.timersLock)
+
+ wakeNetPoller(when)
+
+ releasem(mp)
+}
+
+// doaddtimer adds t to the current P's heap.
+// The caller must have locked the timers for pp.
+func doaddtimer(pp *p, t *timer) {
+ // Timers rely on the network poller, so make sure the poller
+ // has started.
+ if netpollInited.Load() == 0 {
+ netpollGenericInit()
+ }
+
+ if t.pp != 0 {
+ throw("doaddtimer: P already set in timer")
+ }
+ t.pp.set(pp)
+ i := len(pp.timers)
+ pp.timers = append(pp.timers, t)
+ siftupTimer(pp.timers, i)
+ if t == pp.timers[0] {
+ pp.timer0When.Store(t.when)
+ }
+ pp.numTimers.Add(1)
+}
+
+// deltimer deletes the timer t. It may be on some other P, so we can't
+// actually remove it from the timers heap. We can only mark it as deleted.
+// It will be removed in due course by the P whose heap it is on.
+// Reports whether the timer was removed before it was run.
+func deltimer(t *timer) bool {
+ for {
+ switch s := t.status.Load(); s {
+ case timerWaiting, timerModifiedLater:
+ // Prevent preemption while the timer is in timerModifying.
+ // This could lead to a self-deadlock. See #38070.
+ mp := acquirem()
+ if t.status.CompareAndSwap(s, timerModifying) {
+ // Must fetch t.pp before changing status,
+ // as cleantimers in another goroutine
+ // can clear t.pp of a timerDeleted timer.
+ tpp := t.pp.ptr()
+ if !t.status.CompareAndSwap(timerModifying, timerDeleted) {
+ badTimer()
+ }
+ releasem(mp)
+ tpp.deletedTimers.Add(1)
+ // Timer was not yet run.
+ return true
+ } else {
+ releasem(mp)
+ }
+ case timerModifiedEarlier:
+ // Prevent preemption while the timer is in timerModifying.
+ // This could lead to a self-deadlock. See #38070.
+ mp := acquirem()
+ if t.status.CompareAndSwap(s, timerModifying) {
+ // Must fetch t.pp before setting status
+ // to timerDeleted.
+ tpp := t.pp.ptr()
+ if !t.status.CompareAndSwap(timerModifying, timerDeleted) {
+ badTimer()
+ }
+ releasem(mp)
+ tpp.deletedTimers.Add(1)
+ // Timer was not yet run.
+ return true
+ } else {
+ releasem(mp)
+ }
+ case timerDeleted, timerRemoving, timerRemoved:
+ // Timer was already run.
+ return false
+ case timerRunning, timerMoving:
+ // The timer is being run or moved, by a different P.
+ // Wait for it to complete.
+ osyield()
+ case timerNoStatus:
+ // Removing timer that was never added or
+ // has already been run. Also see issue 21874.
+ return false
+ case timerModifying:
+ // Simultaneous calls to deltimer and modtimer.
+ // Wait for the other call to complete.
+ osyield()
+ default:
+ badTimer()
+ }
+ }
+}
+
+// dodeltimer removes timer i from the current P's heap.
+// We are locked on the P when this is called.
+// It returns the smallest changed index in pp.timers.
+// The caller must have locked the timers for pp.
+func dodeltimer(pp *p, i int) int {
+ if t := pp.timers[i]; t.pp.ptr() != pp {
+ throw("dodeltimer: wrong P")
+ } else {
+ t.pp = 0
+ }
+ last := len(pp.timers) - 1
+ if i != last {
+ pp.timers[i] = pp.timers[last]
+ }
+ pp.timers[last] = nil
+ pp.timers = pp.timers[:last]
+ smallestChanged := i
+ if i != last {
+ // Moving to i may have moved the last timer to a new parent,
+ // so sift up to preserve the heap guarantee.
+ smallestChanged = siftupTimer(pp.timers, i)
+ siftdownTimer(pp.timers, i)
+ }
+ if i == 0 {
+ updateTimer0When(pp)
+ }
+ n := pp.numTimers.Add(-1)
+ if n == 0 {
+ // If there are no timers, then clearly none are modified.
+ pp.timerModifiedEarliest.Store(0)
+ }
+ return smallestChanged
+}
+
+// dodeltimer0 removes timer 0 from the current P's heap.
+// We are locked on the P when this is called.
+// It reports whether it saw no problems due to races.
+// The caller must have locked the timers for pp.
+func dodeltimer0(pp *p) {
+ if t := pp.timers[0]; t.pp.ptr() != pp {
+ throw("dodeltimer0: wrong P")
+ } else {
+ t.pp = 0
+ }
+ last := len(pp.timers) - 1
+ if last > 0 {
+ pp.timers[0] = pp.timers[last]
+ }
+ pp.timers[last] = nil
+ pp.timers = pp.timers[:last]
+ if last > 0 {
+ siftdownTimer(pp.timers, 0)
+ }
+ updateTimer0When(pp)
+ n := pp.numTimers.Add(-1)
+ if n == 0 {
+ // If there are no timers, then clearly none are modified.
+ pp.timerModifiedEarliest.Store(0)
+ }
+}
+
+// modtimer modifies an existing timer.
+// This is called by the netpoll code or time.Ticker.Reset or time.Timer.Reset.
+// Reports whether the timer was modified before it was run.
+func modtimer(t *timer, when, period int64, f func(any, uintptr), arg any, seq uintptr) bool {
+ if when <= 0 {
+ throw("timer when must be positive")
+ }
+ if period < 0 {
+ throw("timer period must be non-negative")
+ }
+
+ status := uint32(timerNoStatus)
+ wasRemoved := false
+ var pending bool
+ var mp *m
+loop:
+ for {
+ switch status = t.status.Load(); status {
+ case timerWaiting, timerModifiedEarlier, timerModifiedLater:
+ // Prevent preemption while the timer is in timerModifying.
+ // This could lead to a self-deadlock. See #38070.
+ mp = acquirem()
+ if t.status.CompareAndSwap(status, timerModifying) {
+ pending = true // timer not yet run
+ break loop
+ }
+ releasem(mp)
+ case timerNoStatus, timerRemoved:
+ // Prevent preemption while the timer is in timerModifying.
+ // This could lead to a self-deadlock. See #38070.
+ mp = acquirem()
+
+ // Timer was already run and t is no longer in a heap.
+ // Act like addtimer.
+ if t.status.CompareAndSwap(status, timerModifying) {
+ wasRemoved = true
+ pending = false // timer already run or stopped
+ break loop
+ }
+ releasem(mp)
+ case timerDeleted:
+ // Prevent preemption while the timer is in timerModifying.
+ // This could lead to a self-deadlock. See #38070.
+ mp = acquirem()
+ if t.status.CompareAndSwap(status, timerModifying) {
+ t.pp.ptr().deletedTimers.Add(-1)
+ pending = false // timer already stopped
+ break loop
+ }
+ releasem(mp)
+ case timerRunning, timerRemoving, timerMoving:
+ // The timer is being run or moved, by a different P.
+ // Wait for it to complete.
+ osyield()
+ case timerModifying:
+ // Multiple simultaneous calls to modtimer.
+ // Wait for the other call to complete.
+ osyield()
+ default:
+ badTimer()
+ }
+ }
+
+ t.period = period
+ t.f = f
+ t.arg = arg
+ t.seq = seq
+
+ if wasRemoved {
+ t.when = when
+ pp := getg().m.p.ptr()
+ lock(&pp.timersLock)
+ doaddtimer(pp, t)
+ unlock(&pp.timersLock)
+ if !t.status.CompareAndSwap(timerModifying, timerWaiting) {
+ badTimer()
+ }
+ releasem(mp)
+ wakeNetPoller(when)
+ } else {
+ // The timer is in some other P's heap, so we can't change
+ // the when field. If we did, the other P's heap would
+ // be out of order. So we put the new when value in the
+ // nextwhen field, and let the other P set the when field
+ // when it is prepared to resort the heap.
+ t.nextwhen = when
+
+ newStatus := uint32(timerModifiedLater)
+ if when < t.when {
+ newStatus = timerModifiedEarlier
+ }
+
+ tpp := t.pp.ptr()
+
+ if newStatus == timerModifiedEarlier {
+ updateTimerModifiedEarliest(tpp, when)
+ }
+
+ // Set the new status of the timer.
+ if !t.status.CompareAndSwap(timerModifying, newStatus) {
+ badTimer()
+ }
+ releasem(mp)
+
+ // If the new status is earlier, wake up the poller.
+ if newStatus == timerModifiedEarlier {
+ wakeNetPoller(when)
+ }
+ }
+
+ return pending
+}
+
+// resettimer resets the time when a timer should fire.
+// If used for an inactive timer, the timer will become active.
+// This should be called instead of addtimer if the timer value has been,
+// or may have been, used previously.
+// Reports whether the timer was modified before it was run.
+func resettimer(t *timer, when int64) bool {
+ return modtimer(t, when, t.period, t.f, t.arg, t.seq)
+}
+
+// cleantimers cleans up the head of the timer queue. This speeds up
+// programs that create and delete timers; leaving them in the heap
+// slows down addtimer. Reports whether no timer problems were found.
+// The caller must have locked the timers for pp.
+func cleantimers(pp *p) {
+ gp := getg()
+ for {
+ if len(pp.timers) == 0 {
+ return
+ }
+
+ // This loop can theoretically run for a while, and because
+ // it is holding timersLock it cannot be preempted.
+ // If someone is trying to preempt us, just return.
+ // We can clean the timers later.
+ if gp.preemptStop {
+ return
+ }
+
+ t := pp.timers[0]
+ if t.pp.ptr() != pp {
+ throw("cleantimers: bad p")
+ }
+ switch s := t.status.Load(); s {
+ case timerDeleted:
+ if !t.status.CompareAndSwap(s, timerRemoving) {
+ continue
+ }
+ dodeltimer0(pp)
+ if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
+ badTimer()
+ }
+ pp.deletedTimers.Add(-1)
+ case timerModifiedEarlier, timerModifiedLater:
+ if !t.status.CompareAndSwap(s, timerMoving) {
+ continue
+ }
+ // Now we can change the when field.
+ t.when = t.nextwhen
+ // Move t to the right position.
+ dodeltimer0(pp)
+ doaddtimer(pp, t)
+ if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
+ badTimer()
+ }
+ default:
+ // Head of timers does not need adjustment.
+ return
+ }
+ }
+}
+
+// moveTimers moves a slice of timers to pp. The slice has been taken
+// from a different P.
+// This is currently called when the world is stopped, but the caller
+// is expected to have locked the timers for pp.
+func moveTimers(pp *p, timers []*timer) {
+ for _, t := range timers {
+ loop:
+ for {
+ switch s := t.status.Load(); s {
+ case timerWaiting:
+ if !t.status.CompareAndSwap(s, timerMoving) {
+ continue
+ }
+ t.pp = 0
+ doaddtimer(pp, t)
+ if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
+ badTimer()
+ }
+ break loop
+ case timerModifiedEarlier, timerModifiedLater:
+ if !t.status.CompareAndSwap(s, timerMoving) {
+ continue
+ }
+ t.when = t.nextwhen
+ t.pp = 0
+ doaddtimer(pp, t)
+ if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
+ badTimer()
+ }
+ break loop
+ case timerDeleted:
+ if !t.status.CompareAndSwap(s, timerRemoved) {
+ continue
+ }
+ t.pp = 0
+ // We no longer need this timer in the heap.
+ break loop
+ case timerModifying:
+ // Loop until the modification is complete.
+ osyield()
+ case timerNoStatus, timerRemoved:
+ // We should not see these status values in a timers heap.
+ badTimer()
+ case timerRunning, timerRemoving, timerMoving:
+ // Some other P thinks it owns this timer,
+ // which should not happen.
+ badTimer()
+ default:
+ badTimer()
+ }
+ }
+ }
+}
+
+// adjusttimers looks through the timers in the current P's heap for
+// any timers that have been modified to run earlier, and puts them in
+// the correct place in the heap. While looking for those timers,
+// it also moves timers that have been modified to run later,
+// and removes deleted timers. The caller must have locked the timers for pp.
+func adjusttimers(pp *p, now int64) {
+ // If we haven't yet reached the time of the first timerModifiedEarlier
+ // timer, don't do anything. This speeds up programs that adjust
+ // a lot of timers back and forth if the timers rarely expire.
+ // We'll postpone looking through all the adjusted timers until
+ // one would actually expire.
+ first := pp.timerModifiedEarliest.Load()
+ if first == 0 || first > now {
+ if verifyTimers {
+ verifyTimerHeap(pp)
+ }
+ return
+ }
+
+ // We are going to clear all timerModifiedEarlier timers.
+ pp.timerModifiedEarliest.Store(0)
+
+ var moved []*timer
+ for i := 0; i < len(pp.timers); i++ {
+ t := pp.timers[i]
+ if t.pp.ptr() != pp {
+ throw("adjusttimers: bad p")
+ }
+ switch s := t.status.Load(); s {
+ case timerDeleted:
+ if t.status.CompareAndSwap(s, timerRemoving) {
+ changed := dodeltimer(pp, i)
+ if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
+ badTimer()
+ }
+ pp.deletedTimers.Add(-1)
+ // Go back to the earliest changed heap entry.
+ // "- 1" because the loop will add 1.
+ i = changed - 1
+ }
+ case timerModifiedEarlier, timerModifiedLater:
+ if t.status.CompareAndSwap(s, timerMoving) {
+ // Now we can change the when field.
+ t.when = t.nextwhen
+ // Take t off the heap, and hold onto it.
+ // We don't add it back yet because the
+ // heap manipulation could cause our
+ // loop to skip some other timer.
+ changed := dodeltimer(pp, i)
+ moved = append(moved, t)
+ // Go back to the earliest changed heap entry.
+ // "- 1" because the loop will add 1.
+ i = changed - 1
+ }
+ case timerNoStatus, timerRunning, timerRemoving, timerRemoved, timerMoving:
+ badTimer()
+ case timerWaiting:
+ // OK, nothing to do.
+ case timerModifying:
+ // Check again after modification is complete.
+ osyield()
+ i--
+ default:
+ badTimer()
+ }
+ }
+
+ if len(moved) > 0 {
+ addAdjustedTimers(pp, moved)
+ }
+
+ if verifyTimers {
+ verifyTimerHeap(pp)
+ }
+}
+
+// addAdjustedTimers adds any timers we adjusted in adjusttimers
+// back to the timer heap.
+func addAdjustedTimers(pp *p, moved []*timer) {
+ for _, t := range moved {
+ doaddtimer(pp, t)
+ if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
+ badTimer()
+ }
+ }
+}
+
+// nobarrierWakeTime looks at P's timers and returns the time when we
+// should wake up the netpoller. It returns 0 if there are no timers.
+// This function is invoked when dropping a P, and must run without
+// any write barriers.
+//
+//go:nowritebarrierrec
+func nobarrierWakeTime(pp *p) int64 {
+ next := pp.timer0When.Load()
+ nextAdj := pp.timerModifiedEarliest.Load()
+ if next == 0 || (nextAdj != 0 && nextAdj < next) {
+ next = nextAdj
+ }
+ return next
+}
+
+// runtimer examines the first timer in timers. If it is ready based on now,
+// it runs the timer and removes or updates it.
+// Returns 0 if it ran a timer, -1 if there are no more timers, or the time
+// when the first timer should run.
+// The caller must have locked the timers for pp.
+// If a timer is run, this will temporarily unlock the timers.
+//
+//go:systemstack
+func runtimer(pp *p, now int64) int64 {
+ for {
+ t := pp.timers[0]
+ if t.pp.ptr() != pp {
+ throw("runtimer: bad p")
+ }
+ switch s := t.status.Load(); s {
+ case timerWaiting:
+ if t.when > now {
+ // Not ready to run.
+ return t.when
+ }
+
+ if !t.status.CompareAndSwap(s, timerRunning) {
+ continue
+ }
+ // Note that runOneTimer may temporarily unlock
+ // pp.timersLock.
+ runOneTimer(pp, t, now)
+ return 0
+
+ case timerDeleted:
+ if !t.status.CompareAndSwap(s, timerRemoving) {
+ continue
+ }
+ dodeltimer0(pp)
+ if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
+ badTimer()
+ }
+ pp.deletedTimers.Add(-1)
+ if len(pp.timers) == 0 {
+ return -1
+ }
+
+ case timerModifiedEarlier, timerModifiedLater:
+ if !t.status.CompareAndSwap(s, timerMoving) {
+ continue
+ }
+ t.when = t.nextwhen
+ dodeltimer0(pp)
+ doaddtimer(pp, t)
+ if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
+ badTimer()
+ }
+
+ case timerModifying:
+ // Wait for modification to complete.
+ osyield()
+
+ case timerNoStatus, timerRemoved:
+ // Should not see a new or inactive timer on the heap.
+ badTimer()
+ case timerRunning, timerRemoving, timerMoving:
+ // These should only be set when timers are locked,
+ // and we didn't do it.
+ badTimer()
+ default:
+ badTimer()
+ }
+ }
+}
+
+// runOneTimer runs a single timer.
+// The caller must have locked the timers for pp.
+// This will temporarily unlock the timers while running the timer function.
+//
+//go:systemstack
+func runOneTimer(pp *p, t *timer, now int64) {
+ if raceenabled {
+ ppcur := getg().m.p.ptr()
+ if ppcur.timerRaceCtx == 0 {
+ ppcur.timerRaceCtx = racegostart(abi.FuncPCABIInternal(runtimer) + sys.PCQuantum)
+ }
+ raceacquirectx(ppcur.timerRaceCtx, unsafe.Pointer(t))
+ }
+
+ f := t.f
+ arg := t.arg
+ seq := t.seq
+
+ if t.period > 0 {
+ // Leave in heap but adjust next time to fire.
+ delta := t.when - now
+ t.when += t.period * (1 + -delta/t.period)
+ if t.when < 0 { // check for overflow.
+ t.when = maxWhen
+ }
+ siftdownTimer(pp.timers, 0)
+ if !t.status.CompareAndSwap(timerRunning, timerWaiting) {
+ badTimer()
+ }
+ updateTimer0When(pp)
+ } else {
+ // Remove from heap.
+ dodeltimer0(pp)
+ if !t.status.CompareAndSwap(timerRunning, timerNoStatus) {
+ badTimer()
+ }
+ }
+
+ if raceenabled {
+ // Temporarily use the current P's racectx for g0.
+ gp := getg()
+ if gp.racectx != 0 {
+ throw("runOneTimer: unexpected racectx")
+ }
+ gp.racectx = gp.m.p.ptr().timerRaceCtx
+ }
+
+ unlock(&pp.timersLock)
+
+ f(arg, seq)
+
+ lock(&pp.timersLock)
+
+ if raceenabled {
+ gp := getg()
+ gp.racectx = 0
+ }
+}
+
+// clearDeletedTimers removes all deleted timers from the P's timer heap.
+// This is used to avoid clogging up the heap if the program
+// starts a lot of long-running timers and then stops them.
+// For example, this can happen via context.WithTimeout.
+//
+// This is the only function that walks through the entire timer heap,
+// other than moveTimers which only runs when the world is stopped.
+//
+// The caller must have locked the timers for pp.
+func clearDeletedTimers(pp *p) {
+ // We are going to clear all timerModifiedEarlier timers.
+ // Do this now in case new ones show up while we are looping.
+ pp.timerModifiedEarliest.Store(0)
+
+ cdel := int32(0)
+ to := 0
+ changedHeap := false
+ timers := pp.timers
+nextTimer:
+ for _, t := range timers {
+ for {
+ switch s := t.status.Load(); s {
+ case timerWaiting:
+ if changedHeap {
+ timers[to] = t
+ siftupTimer(timers, to)
+ }
+ to++
+ continue nextTimer
+ case timerModifiedEarlier, timerModifiedLater:
+ if t.status.CompareAndSwap(s, timerMoving) {
+ t.when = t.nextwhen
+ timers[to] = t
+ siftupTimer(timers, to)
+ to++
+ changedHeap = true
+ if !t.status.CompareAndSwap(timerMoving, timerWaiting) {
+ badTimer()
+ }
+ continue nextTimer
+ }
+ case timerDeleted:
+ if t.status.CompareAndSwap(s, timerRemoving) {
+ t.pp = 0
+ cdel++
+ if !t.status.CompareAndSwap(timerRemoving, timerRemoved) {
+ badTimer()
+ }
+ changedHeap = true
+ continue nextTimer
+ }
+ case timerModifying:
+ // Loop until modification complete.
+ osyield()
+ case timerNoStatus, timerRemoved:
+ // We should not see these status values in a timer heap.
+ badTimer()
+ case timerRunning, timerRemoving, timerMoving:
+ // Some other P thinks it owns this timer,
+ // which should not happen.
+ badTimer()
+ default:
+ badTimer()
+ }
+ }
+ }
+
+ // Set remaining slots in timers slice to nil,
+ // so that the timer values can be garbage collected.
+ for i := to; i < len(timers); i++ {
+ timers[i] = nil
+ }
+
+ pp.deletedTimers.Add(-cdel)
+ pp.numTimers.Add(-cdel)
+
+ timers = timers[:to]
+ pp.timers = timers
+ updateTimer0When(pp)
+
+ if verifyTimers {
+ verifyTimerHeap(pp)
+ }
+}
+
+// verifyTimerHeap verifies that the timer heap is in a valid state.
+// This is only for debugging, and is only called if verifyTimers is true.
+// The caller must have locked the timers.
+func verifyTimerHeap(pp *p) {
+ for i, t := range pp.timers {
+ if i == 0 {
+ // First timer has no parent.
+ continue
+ }
+
+ // The heap is 4-ary. See siftupTimer and siftdownTimer.
+ p := (i - 1) / 4
+ if t.when < pp.timers[p].when {
+ print("bad timer heap at ", i, ": ", p, ": ", pp.timers[p].when, ", ", i, ": ", t.when, "\n")
+ throw("bad timer heap")
+ }
+ }
+ if numTimers := int(pp.numTimers.Load()); len(pp.timers) != numTimers {
+ println("timer heap len", len(pp.timers), "!= numTimers", numTimers)
+ throw("bad timer heap len")
+ }
+}
+
+// updateTimer0When sets the P's timer0When field.
+// The caller must have locked the timers for pp.
+func updateTimer0When(pp *p) {
+ if len(pp.timers) == 0 {
+ pp.timer0When.Store(0)
+ } else {
+ pp.timer0When.Store(pp.timers[0].when)
+ }
+}
+
+// updateTimerModifiedEarliest updates the recorded nextwhen field of the
+// earlier timerModifiedEarier value.
+// The timers for pp will not be locked.
+func updateTimerModifiedEarliest(pp *p, nextwhen int64) {
+ for {
+ old := pp.timerModifiedEarliest.Load()
+ if old != 0 && int64(old) < nextwhen {
+ return
+ }
+
+ if pp.timerModifiedEarliest.CompareAndSwap(old, nextwhen) {
+ return
+ }
+ }
+}
+
+// timeSleepUntil returns the time when the next timer should fire. Returns
+// maxWhen if there are no timers.
+// This is only called by sysmon and checkdead.
+func timeSleepUntil() int64 {
+ next := int64(maxWhen)
+
+ // Prevent allp slice changes. This is like retake.
+ lock(&allpLock)
+ for _, pp := range allp {
+ if pp == nil {
+ // This can happen if procresize has grown
+ // allp but not yet created new Ps.
+ continue
+ }
+
+ w := pp.timer0When.Load()
+ if w != 0 && w < next {
+ next = w
+ }
+
+ w = pp.timerModifiedEarliest.Load()
+ if w != 0 && w < next {
+ next = w
+ }
+ }
+ unlock(&allpLock)
+
+ return next
+}
+
+// Heap maintenance algorithms.
+// These algorithms check for slice index errors manually.
+// Slice index error can happen if the program is using racy
+// access to timers. We don't want to panic here, because
+// it will cause the program to crash with a mysterious
+// "panic holding locks" message. Instead, we panic while not
+// holding a lock.
+
+// siftupTimer puts the timer at position i in the right place
+// in the heap by moving it up toward the top of the heap.
+// It returns the smallest changed index.
+func siftupTimer(t []*timer, i int) int {
+ if i >= len(t) {
+ badTimer()
+ }
+ when := t[i].when
+ if when <= 0 {
+ badTimer()
+ }
+ tmp := t[i]
+ for i > 0 {
+ p := (i - 1) / 4 // parent
+ if when >= t[p].when {
+ break
+ }
+ t[i] = t[p]
+ i = p
+ }
+ if tmp != t[i] {
+ t[i] = tmp
+ }
+ return i
+}
+
+// siftdownTimer puts the timer at position i in the right place
+// in the heap by moving it down toward the bottom of the heap.
+func siftdownTimer(t []*timer, i int) {
+ n := len(t)
+ if i >= n {
+ badTimer()
+ }
+ when := t[i].when
+ if when <= 0 {
+ badTimer()
+ }
+ tmp := t[i]
+ for {
+ c := i*4 + 1 // left child
+ c3 := c + 2 // mid child
+ if c >= n {
+ break
+ }
+ w := t[c].when
+ if c+1 < n && t[c+1].when < w {
+ w = t[c+1].when
+ c++
+ }
+ if c3 < n {
+ w3 := t[c3].when
+ if c3+1 < n && t[c3+1].when < w3 {
+ w3 = t[c3+1].when
+ c3++
+ }
+ if w3 < w {
+ w = w3
+ c = c3
+ }
+ }
+ if w >= when {
+ break
+ }
+ t[i] = t[c]
+ i = c
+ }
+ if tmp != t[i] {
+ t[i] = tmp
+ }
+}
+
+// badTimer is called if the timer data structures have been corrupted,
+// presumably due to racy use by the program. We panic here rather than
+// panicking due to invalid slice access while holding locks.
+// See issue #25686.
+func badTimer() {
+ throw("timer data corruption")
+}
diff --git a/contrib/go/_std_1.20/src/runtime/time_linux_amd64.s b/contrib/go/_std_1.21/src/runtime/time_linux_amd64.s
index 1416d23230..1416d23230 100644
--- a/contrib/go/_std_1.20/src/runtime/time_linux_amd64.s
+++ b/contrib/go/_std_1.21/src/runtime/time_linux_amd64.s
diff --git a/contrib/go/_std_1.20/src/runtime/time_nofake.go b/contrib/go/_std_1.21/src/runtime/time_nofake.go
index 70a2102b22..70a2102b22 100644
--- a/contrib/go/_std_1.20/src/runtime/time_nofake.go
+++ b/contrib/go/_std_1.21/src/runtime/time_nofake.go
diff --git a/contrib/go/_std_1.20/src/runtime/time_windows.h b/contrib/go/_std_1.21/src/runtime/time_windows.h
index 7c2e65c328..7c2e65c328 100644
--- a/contrib/go/_std_1.20/src/runtime/time_windows.h
+++ b/contrib/go/_std_1.21/src/runtime/time_windows.h
diff --git a/contrib/go/_std_1.20/src/runtime/time_windows_amd64.s b/contrib/go/_std_1.21/src/runtime/time_windows_amd64.s
index 226f2b5136..226f2b5136 100644
--- a/contrib/go/_std_1.20/src/runtime/time_windows_amd64.s
+++ b/contrib/go/_std_1.21/src/runtime/time_windows_amd64.s
diff --git a/contrib/go/_std_1.20/src/runtime/timeasm.go b/contrib/go/_std_1.21/src/runtime/timeasm.go
index 0421388686..0421388686 100644
--- a/contrib/go/_std_1.20/src/runtime/timeasm.go
+++ b/contrib/go/_std_1.21/src/runtime/timeasm.go
diff --git a/contrib/go/_std_1.20/src/runtime/timestub.go b/contrib/go/_std_1.21/src/runtime/timestub.go
index f63bac808a..f63bac808a 100644
--- a/contrib/go/_std_1.20/src/runtime/timestub.go
+++ b/contrib/go/_std_1.21/src/runtime/timestub.go
diff --git a/contrib/go/_std_1.21/src/runtime/timestub2.go b/contrib/go/_std_1.21/src/runtime/timestub2.go
new file mode 100644
index 0000000000..49bfeb60c8
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/timestub2.go
@@ -0,0 +1,10 @@
+// Copyright 2018 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.
+
+//go:build !aix && !darwin && !freebsd && !openbsd && !solaris && !wasip1 && !windows && !(linux && amd64)
+
+package runtime
+
+//go:wasmimport gojs runtime.walltime
+func walltime() (sec int64, nsec int32)
diff --git a/contrib/go/_std_1.20/src/runtime/tls_arm64.h b/contrib/go/_std_1.21/src/runtime/tls_arm64.h
index 3aa8c63d39..3aa8c63d39 100644
--- a/contrib/go/_std_1.20/src/runtime/tls_arm64.h
+++ b/contrib/go/_std_1.21/src/runtime/tls_arm64.h
diff --git a/contrib/go/_std_1.20/src/runtime/tls_arm64.s b/contrib/go/_std_1.21/src/runtime/tls_arm64.s
index 52b3e8f222..52b3e8f222 100644
--- a/contrib/go/_std_1.20/src/runtime/tls_arm64.s
+++ b/contrib/go/_std_1.21/src/runtime/tls_arm64.s
diff --git a/contrib/go/_std_1.20/src/runtime/tls_stub.go b/contrib/go/_std_1.21/src/runtime/tls_stub.go
index 7bdfc6b89a..7bdfc6b89a 100644
--- a/contrib/go/_std_1.20/src/runtime/tls_stub.go
+++ b/contrib/go/_std_1.21/src/runtime/tls_stub.go
diff --git a/contrib/go/_std_1.20/src/runtime/tls_windows_amd64.go b/contrib/go/_std_1.21/src/runtime/tls_windows_amd64.go
index cacaa84496..cacaa84496 100644
--- a/contrib/go/_std_1.20/src/runtime/tls_windows_amd64.go
+++ b/contrib/go/_std_1.21/src/runtime/tls_windows_amd64.go
diff --git a/contrib/go/_std_1.21/src/runtime/trace.go b/contrib/go/_std_1.21/src/runtime/trace.go
new file mode 100644
index 0000000000..7d7987c90c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/trace.go
@@ -0,0 +1,1818 @@
+// Copyright 2014 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.
+
+// Go execution tracer.
+// The tracer captures a wide range of execution events like goroutine
+// creation/blocking/unblocking, syscall enter/exit/block, GC-related events,
+// changes of heap size, processor start/stop, etc and writes them to a buffer
+// in a compact form. A precise nanosecond-precision timestamp and a stack
+// trace is captured for most events.
+// See https://golang.org/s/go15trace for more info.
+
+package runtime
+
+import (
+ "internal/abi"
+ "internal/goarch"
+ "internal/goos"
+ "runtime/internal/atomic"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// Event types in the trace, args are given in square brackets.
+const (
+ traceEvNone = 0 // unused
+ traceEvBatch = 1 // start of per-P batch of events [pid, timestamp]
+ traceEvFrequency = 2 // contains tracer timer frequency [frequency (ticks per second)]
+ traceEvStack = 3 // stack [stack id, number of PCs, array of {PC, func string ID, file string ID, line}]
+ traceEvGomaxprocs = 4 // current value of GOMAXPROCS [timestamp, GOMAXPROCS, stack id]
+ traceEvProcStart = 5 // start of P [timestamp, thread id]
+ traceEvProcStop = 6 // stop of P [timestamp]
+ traceEvGCStart = 7 // GC start [timestamp, seq, stack id]
+ traceEvGCDone = 8 // GC done [timestamp]
+ traceEvSTWStart = 9 // STW start [timestamp, kind]
+ traceEvSTWDone = 10 // STW done [timestamp]
+ traceEvGCSweepStart = 11 // GC sweep start [timestamp, stack id]
+ traceEvGCSweepDone = 12 // GC sweep done [timestamp, swept, reclaimed]
+ traceEvGoCreate = 13 // goroutine creation [timestamp, new goroutine id, new stack id, stack id]
+ traceEvGoStart = 14 // goroutine starts running [timestamp, goroutine id, seq]
+ traceEvGoEnd = 15 // goroutine ends [timestamp]
+ traceEvGoStop = 16 // goroutine stops (like in select{}) [timestamp, stack]
+ traceEvGoSched = 17 // goroutine calls Gosched [timestamp, stack]
+ traceEvGoPreempt = 18 // goroutine is preempted [timestamp, stack]
+ traceEvGoSleep = 19 // goroutine calls Sleep [timestamp, stack]
+ traceEvGoBlock = 20 // goroutine blocks [timestamp, stack]
+ traceEvGoUnblock = 21 // goroutine is unblocked [timestamp, goroutine id, seq, stack]
+ traceEvGoBlockSend = 22 // goroutine blocks on chan send [timestamp, stack]
+ traceEvGoBlockRecv = 23 // goroutine blocks on chan recv [timestamp, stack]
+ traceEvGoBlockSelect = 24 // goroutine blocks on select [timestamp, stack]
+ traceEvGoBlockSync = 25 // goroutine blocks on Mutex/RWMutex [timestamp, stack]
+ traceEvGoBlockCond = 26 // goroutine blocks on Cond [timestamp, stack]
+ traceEvGoBlockNet = 27 // goroutine blocks on network [timestamp, stack]
+ traceEvGoSysCall = 28 // syscall enter [timestamp, stack]
+ traceEvGoSysExit = 29 // syscall exit [timestamp, goroutine id, seq, real timestamp]
+ traceEvGoSysBlock = 30 // syscall blocks [timestamp]
+ traceEvGoWaiting = 31 // denotes that goroutine is blocked when tracing starts [timestamp, goroutine id]
+ traceEvGoInSyscall = 32 // denotes that goroutine is in syscall when tracing starts [timestamp, goroutine id]
+ traceEvHeapAlloc = 33 // gcController.heapLive change [timestamp, heap_alloc]
+ traceEvHeapGoal = 34 // gcController.heapGoal() (formerly next_gc) change [timestamp, heap goal in bytes]
+ traceEvTimerGoroutine = 35 // not currently used; previously denoted timer goroutine [timer goroutine id]
+ traceEvFutileWakeup = 36 // not currently used; denotes that the previous wakeup of this goroutine was futile [timestamp]
+ traceEvString = 37 // string dictionary entry [ID, length, string]
+ traceEvGoStartLocal = 38 // goroutine starts running on the same P as the last event [timestamp, goroutine id]
+ traceEvGoUnblockLocal = 39 // goroutine is unblocked on the same P as the last event [timestamp, goroutine id, stack]
+ traceEvGoSysExitLocal = 40 // syscall exit on the same P as the last event [timestamp, goroutine id, real timestamp]
+ traceEvGoStartLabel = 41 // goroutine starts running with label [timestamp, goroutine id, seq, label string id]
+ traceEvGoBlockGC = 42 // goroutine blocks on GC assist [timestamp, stack]
+ traceEvGCMarkAssistStart = 43 // GC mark assist start [timestamp, stack]
+ traceEvGCMarkAssistDone = 44 // GC mark assist done [timestamp]
+ traceEvUserTaskCreate = 45 // trace.NewTask [timestamp, internal task id, internal parent task id, name string, stack]
+ traceEvUserTaskEnd = 46 // end of a task [timestamp, internal task id, stack]
+ traceEvUserRegion = 47 // trace.WithRegion [timestamp, internal task id, mode(0:start, 1:end), name string, stack]
+ traceEvUserLog = 48 // trace.Log [timestamp, internal task id, key string id, stack, value string]
+ traceEvCPUSample = 49 // CPU profiling sample [timestamp, real timestamp, real P id (-1 when absent), goroutine id, stack]
+ traceEvCount = 50
+ // Byte is used but only 6 bits are available for event type.
+ // The remaining 2 bits are used to specify the number of arguments.
+ // That means, the max event type value is 63.
+)
+
+// traceBlockReason is an enumeration of reasons a goroutine might block.
+// This is the interface the rest of the runtime uses to tell the
+// tracer why a goroutine blocked. The tracer then propagates this information
+// into the trace however it sees fit.
+//
+// Note that traceBlockReasons should not be compared, since reasons that are
+// distinct by name may *not* be distinct by value.
+type traceBlockReason uint8
+
+// For maximal efficiency, just map the trace block reason directly to a trace
+// event.
+const (
+ traceBlockGeneric traceBlockReason = traceEvGoBlock
+ traceBlockForever = traceEvGoStop
+ traceBlockNet = traceEvGoBlockNet
+ traceBlockSelect = traceEvGoBlockSelect
+ traceBlockCondWait = traceEvGoBlockCond
+ traceBlockSync = traceEvGoBlockSync
+ traceBlockChanSend = traceEvGoBlockSend
+ traceBlockChanRecv = traceEvGoBlockRecv
+ traceBlockGCMarkAssist = traceEvGoBlockGC
+ traceBlockGCSweep = traceEvGoBlock
+ traceBlockSystemGoroutine = traceEvGoBlock
+ traceBlockPreempted = traceEvGoBlock
+ traceBlockDebugCall = traceEvGoBlock
+ traceBlockUntilGCEnds = traceEvGoBlock
+ traceBlockSleep = traceEvGoSleep
+)
+
+const (
+ // Timestamps in trace are cputicks/traceTickDiv.
+ // This makes absolute values of timestamp diffs smaller,
+ // and so they are encoded in less number of bytes.
+ // 64 on x86 is somewhat arbitrary (one tick is ~20ns on a 3GHz machine).
+ // The suggested increment frequency for PowerPC's time base register is
+ // 512 MHz according to Power ISA v2.07 section 6.2, so we use 16 on ppc64
+ // and ppc64le.
+ traceTimeDiv = 16 + 48*(goarch.Is386|goarch.IsAmd64)
+ // Maximum number of PCs in a single stack trace.
+ // Since events contain only stack id rather than whole stack trace,
+ // we can allow quite large values here.
+ traceStackSize = 128
+ // Identifier of a fake P that is used when we trace without a real P.
+ traceGlobProc = -1
+ // Maximum number of bytes to encode uint64 in base-128.
+ traceBytesPerNumber = 10
+ // Shift of the number of arguments in the first event byte.
+ traceArgCountShift = 6
+)
+
+// trace is global tracing context.
+var trace struct {
+ // trace.lock must only be acquired on the system stack where
+ // stack splits cannot happen while it is held.
+ lock mutex // protects the following members
+ enabled bool // when set runtime traces events
+ shutdown bool // set when we are waiting for trace reader to finish after setting enabled to false
+ headerWritten bool // whether ReadTrace has emitted trace header
+ footerWritten bool // whether ReadTrace has emitted trace footer
+ shutdownSema uint32 // used to wait for ReadTrace completion
+ seqStart uint64 // sequence number when tracing was started
+ startTicks int64 // cputicks when tracing was started
+ endTicks int64 // cputicks when tracing was stopped
+ startNanotime int64 // nanotime when tracing was started
+ endNanotime int64 // nanotime when tracing was stopped
+ startTime traceTime // traceClockNow when tracing started
+ endTime traceTime // traceClockNow when tracing stopped
+ seqGC uint64 // GC start/done sequencer
+ reading traceBufPtr // buffer currently handed off to user
+ empty traceBufPtr // stack of empty buffers
+ fullHead traceBufPtr // queue of full buffers
+ fullTail traceBufPtr
+ stackTab traceStackTable // maps stack traces to unique ids
+ // cpuLogRead accepts CPU profile samples from the signal handler where
+ // they're generated. It uses a two-word header to hold the IDs of the P and
+ // G (respectively) that were active at the time of the sample. Because
+ // profBuf uses a record with all zeros in its header to indicate overflow,
+ // we make sure to make the P field always non-zero: The ID of a real P will
+ // start at bit 1, and bit 0 will be set. Samples that arrive while no P is
+ // running (such as near syscalls) will set the first header field to 0b10.
+ // This careful handling of the first header field allows us to store ID of
+ // the active G directly in the second field, even though that will be 0
+ // when sampling g0.
+ cpuLogRead *profBuf
+ // cpuLogBuf is a trace buffer to hold events corresponding to CPU profile
+ // samples, which arrive out of band and not directly connected to a
+ // specific P.
+ cpuLogBuf traceBufPtr
+
+ reader atomic.Pointer[g] // goroutine that called ReadTrace, or nil
+
+ signalLock atomic.Uint32 // protects use of the following member, only usable in signal handlers
+ cpuLogWrite *profBuf // copy of cpuLogRead for use in signal handlers, set without signalLock
+
+ // Dictionary for traceEvString.
+ //
+ // TODO: central lock to access the map is not ideal.
+ // option: pre-assign ids to all user annotation region names and tags
+ // option: per-P cache
+ // option: sync.Map like data structure
+ stringsLock mutex
+ strings map[string]uint64
+ stringSeq uint64
+
+ // markWorkerLabels maps gcMarkWorkerMode to string ID.
+ markWorkerLabels [len(gcMarkWorkerModeStrings)]uint64
+
+ bufLock mutex // protects buf
+ buf traceBufPtr // global trace buffer, used when running without a p
+}
+
+// gTraceState is per-G state for the tracer.
+type gTraceState struct {
+ sysExitTime traceTime // timestamp when syscall has returned
+ tracedSyscallEnter bool // syscall or cgo was entered while trace was enabled or StartTrace has emitted EvGoInSyscall about this goroutine
+ seq uint64 // trace event sequencer
+ lastP puintptr // last P emitted an event for this goroutine
+}
+
+// mTraceState is per-M state for the tracer.
+type mTraceState struct {
+ startingTrace bool // this M is in TraceStart, potentially before traceEnabled is true
+ tracedSTWStart bool // this M traced a STW start, so it should trace an end
+}
+
+// pTraceState is per-P state for the tracer.
+type pTraceState struct {
+ buf traceBufPtr
+
+ // inSweep indicates the sweep events should be traced.
+ // This is used to defer the sweep start event until a span
+ // has actually been swept.
+ inSweep bool
+
+ // swept and reclaimed track the number of bytes swept and reclaimed
+ // by sweeping in the current sweep loop (while inSweep was true).
+ swept, reclaimed uintptr
+}
+
+// traceLockInit initializes global trace locks.
+func traceLockInit() {
+ lockInit(&trace.bufLock, lockRankTraceBuf)
+ lockInit(&trace.stringsLock, lockRankTraceStrings)
+ lockInit(&trace.lock, lockRankTrace)
+ lockInit(&trace.stackTab.lock, lockRankTraceStackTab)
+}
+
+// traceBufHeader is per-P tracing buffer.
+type traceBufHeader struct {
+ link traceBufPtr // in trace.empty/full
+ lastTime traceTime // when we wrote the last event
+ pos int // next write offset in arr
+ stk [traceStackSize]uintptr // scratch buffer for traceback
+}
+
+// traceBuf is per-P tracing buffer.
+type traceBuf struct {
+ _ sys.NotInHeap
+ traceBufHeader
+ arr [64<<10 - unsafe.Sizeof(traceBufHeader{})]byte // underlying buffer for traceBufHeader.buf
+}
+
+// traceBufPtr is a *traceBuf that is not traced by the garbage
+// collector and doesn't have write barriers. traceBufs are not
+// allocated from the GC'd heap, so this is safe, and are often
+// manipulated in contexts where write barriers are not allowed, so
+// this is necessary.
+//
+// TODO: Since traceBuf is now embedded runtime/internal/sys.NotInHeap, this isn't necessary.
+type traceBufPtr uintptr
+
+func (tp traceBufPtr) ptr() *traceBuf { return (*traceBuf)(unsafe.Pointer(tp)) }
+func (tp *traceBufPtr) set(b *traceBuf) { *tp = traceBufPtr(unsafe.Pointer(b)) }
+func traceBufPtrOf(b *traceBuf) traceBufPtr {
+ return traceBufPtr(unsafe.Pointer(b))
+}
+
+// traceEnabled returns true if the trace is currently enabled.
+//
+//go:nosplit
+func traceEnabled() bool {
+ return trace.enabled
+}
+
+// traceShuttingDown returns true if the trace is currently shutting down.
+//
+//go:nosplit
+func traceShuttingDown() bool {
+ return trace.shutdown
+}
+
+// StartTrace enables tracing for the current process.
+// While tracing, the data will be buffered and available via ReadTrace.
+// StartTrace returns an error if tracing is already enabled.
+// Most clients should use the runtime/trace package or the testing package's
+// -test.trace flag instead of calling StartTrace directly.
+func StartTrace() error {
+ // Stop the world so that we can take a consistent snapshot
+ // of all goroutines at the beginning of the trace.
+ // Do not stop the world during GC so we ensure we always see
+ // a consistent view of GC-related events (e.g. a start is always
+ // paired with an end).
+ stopTheWorldGC(stwStartTrace)
+
+ // Prevent sysmon from running any code that could generate events.
+ lock(&sched.sysmonlock)
+
+ // We are in stop-the-world, but syscalls can finish and write to trace concurrently.
+ // Exitsyscall could check trace.enabled long before and then suddenly wake up
+ // and decide to write to trace at a random point in time.
+ // However, such syscall will use the global trace.buf buffer, because we've
+ // acquired all p's by doing stop-the-world. So this protects us from such races.
+ lock(&trace.bufLock)
+
+ if trace.enabled || trace.shutdown {
+ unlock(&trace.bufLock)
+ unlock(&sched.sysmonlock)
+ startTheWorldGC()
+ return errorString("tracing is already enabled")
+ }
+
+ // Can't set trace.enabled yet. While the world is stopped, exitsyscall could
+ // already emit a delayed event (see exitTicks in exitsyscall) if we set trace.enabled here.
+ // That would lead to an inconsistent trace:
+ // - either GoSysExit appears before EvGoInSyscall,
+ // - or GoSysExit appears for a goroutine for which we don't emit EvGoInSyscall below.
+ // To instruct traceEvent that it must not ignore events below, we set trace.startingTrace.
+ // trace.enabled is set afterwards once we have emitted all preliminary events.
+ mp := getg().m
+ mp.trace.startingTrace = true
+
+ // Obtain current stack ID to use in all traceEvGoCreate events below.
+ stkBuf := make([]uintptr, traceStackSize)
+ stackID := traceStackID(mp, stkBuf, 2)
+
+ profBuf := newProfBuf(2, profBufWordCount, profBufTagCount) // after the timestamp, header is [pp.id, gp.goid]
+ trace.cpuLogRead = profBuf
+
+ // We must not acquire trace.signalLock outside of a signal handler: a
+ // profiling signal may arrive at any time and try to acquire it, leading to
+ // deadlock. Because we can't use that lock to protect updates to
+ // trace.cpuLogWrite (only use of the structure it references), reads and
+ // writes of the pointer must be atomic. (And although this field is never
+ // the sole pointer to the profBuf value, it's best to allow a write barrier
+ // here.)
+ atomicstorep(unsafe.Pointer(&trace.cpuLogWrite), unsafe.Pointer(profBuf))
+
+ // World is stopped, no need to lock.
+ forEachGRace(func(gp *g) {
+ status := readgstatus(gp)
+ if status != _Gdead {
+ gp.trace.seq = 0
+ gp.trace.lastP = getg().m.p
+ // +PCQuantum because traceFrameForPC expects return PCs and subtracts PCQuantum.
+ id := trace.stackTab.put([]uintptr{logicalStackSentinel, startPCforTrace(gp.startpc) + sys.PCQuantum})
+ traceEvent(traceEvGoCreate, -1, gp.goid, uint64(id), stackID)
+ }
+ if status == _Gwaiting {
+ // traceEvGoWaiting is implied to have seq=1.
+ gp.trace.seq++
+ traceEvent(traceEvGoWaiting, -1, gp.goid)
+ }
+ if status == _Gsyscall {
+ gp.trace.seq++
+ gp.trace.tracedSyscallEnter = true
+ traceEvent(traceEvGoInSyscall, -1, gp.goid)
+ } else if status == _Gdead && gp.m != nil && gp.m.isextra {
+ // Trigger two trace events for the dead g in the extra m,
+ // since the next event of the g will be traceEvGoSysExit in exitsyscall,
+ // while calling from C thread to Go.
+ gp.trace.seq = 0
+ gp.trace.lastP = getg().m.p
+ // +PCQuantum because traceFrameForPC expects return PCs and subtracts PCQuantum.
+ id := trace.stackTab.put([]uintptr{logicalStackSentinel, startPCforTrace(0) + sys.PCQuantum}) // no start pc
+ traceEvent(traceEvGoCreate, -1, gp.goid, uint64(id), stackID)
+ gp.trace.seq++
+ gp.trace.tracedSyscallEnter = true
+ traceEvent(traceEvGoInSyscall, -1, gp.goid)
+ } else {
+ // We need to explicitly clear the flag. A previous trace might have ended with a goroutine
+ // not emitting a GoSysExit and clearing the flag, leaving it in a stale state. Clearing
+ // it here makes it unambiguous to any goroutine exiting a syscall racing with us that
+ // no EvGoInSyscall event was emitted for it. (It's not racy to set this flag here, because
+ // it'll only get checked when the goroutine runs again, which will be after the world starts
+ // again.)
+ gp.trace.tracedSyscallEnter = false
+ }
+ })
+ traceProcStart()
+ traceGoStart()
+ // Note: startTicks needs to be set after we emit traceEvGoInSyscall events.
+ // If we do it the other way around, it is possible that exitsyscall will
+ // query sysExitTime after startTicks but before traceEvGoInSyscall timestamp.
+ // It will lead to a false conclusion that cputicks is broken.
+ trace.startTime = traceClockNow()
+ trace.startTicks = cputicks()
+ trace.startNanotime = nanotime()
+ trace.headerWritten = false
+ trace.footerWritten = false
+
+ // string to id mapping
+ // 0 : reserved for an empty string
+ // remaining: other strings registered by traceString
+ trace.stringSeq = 0
+ trace.strings = make(map[string]uint64)
+
+ trace.seqGC = 0
+ mp.trace.startingTrace = false
+ trace.enabled = true
+
+ // Register runtime goroutine labels.
+ _, pid, bufp := traceAcquireBuffer()
+ for i, label := range gcMarkWorkerModeStrings[:] {
+ trace.markWorkerLabels[i], bufp = traceString(bufp, pid, label)
+ }
+ traceReleaseBuffer(mp, pid)
+
+ unlock(&trace.bufLock)
+
+ unlock(&sched.sysmonlock)
+
+ // Record the current state of HeapGoal to avoid information loss in trace.
+ traceHeapGoal()
+
+ startTheWorldGC()
+ return nil
+}
+
+// StopTrace stops tracing, if it was previously enabled.
+// StopTrace only returns after all the reads for the trace have completed.
+func StopTrace() {
+ // Stop the world so that we can collect the trace buffers from all p's below,
+ // and also to avoid races with traceEvent.
+ stopTheWorldGC(stwStopTrace)
+
+ // See the comment in StartTrace.
+ lock(&sched.sysmonlock)
+
+ // See the comment in StartTrace.
+ lock(&trace.bufLock)
+
+ if !trace.enabled {
+ unlock(&trace.bufLock)
+ unlock(&sched.sysmonlock)
+ startTheWorldGC()
+ return
+ }
+
+ traceGoSched()
+
+ atomicstorep(unsafe.Pointer(&trace.cpuLogWrite), nil)
+ trace.cpuLogRead.close()
+ traceReadCPU()
+
+ // Loop over all allocated Ps because dead Ps may still have
+ // trace buffers.
+ for _, p := range allp[:cap(allp)] {
+ buf := p.trace.buf
+ if buf != 0 {
+ traceFullQueue(buf)
+ p.trace.buf = 0
+ }
+ }
+ if trace.buf != 0 {
+ buf := trace.buf
+ trace.buf = 0
+ if buf.ptr().pos != 0 {
+ traceFullQueue(buf)
+ }
+ }
+ if trace.cpuLogBuf != 0 {
+ buf := trace.cpuLogBuf
+ trace.cpuLogBuf = 0
+ if buf.ptr().pos != 0 {
+ traceFullQueue(buf)
+ }
+ }
+
+ // Wait for startNanotime != endNanotime. On Windows the default interval between
+ // system clock ticks is typically between 1 and 15 milliseconds, which may not
+ // have passed since the trace started. Without nanotime moving forward, trace
+ // tooling has no way of identifying how much real time each cputicks time deltas
+ // represent.
+ for {
+ trace.endTime = traceClockNow()
+ trace.endTicks = cputicks()
+ trace.endNanotime = nanotime()
+
+ if trace.endNanotime != trace.startNanotime || faketime != 0 {
+ break
+ }
+ osyield()
+ }
+
+ trace.enabled = false
+ trace.shutdown = true
+ unlock(&trace.bufLock)
+
+ unlock(&sched.sysmonlock)
+
+ startTheWorldGC()
+
+ // The world is started but we've set trace.shutdown, so new tracing can't start.
+ // Wait for the trace reader to flush pending buffers and stop.
+ semacquire(&trace.shutdownSema)
+ if raceenabled {
+ raceacquire(unsafe.Pointer(&trace.shutdownSema))
+ }
+
+ systemstack(func() {
+ // The lock protects us from races with StartTrace/StopTrace because they do stop-the-world.
+ lock(&trace.lock)
+ for _, p := range allp[:cap(allp)] {
+ if p.trace.buf != 0 {
+ throw("trace: non-empty trace buffer in proc")
+ }
+ }
+ if trace.buf != 0 {
+ throw("trace: non-empty global trace buffer")
+ }
+ if trace.fullHead != 0 || trace.fullTail != 0 {
+ throw("trace: non-empty full trace buffer")
+ }
+ if trace.reading != 0 || trace.reader.Load() != nil {
+ throw("trace: reading after shutdown")
+ }
+ for trace.empty != 0 {
+ buf := trace.empty
+ trace.empty = buf.ptr().link
+ sysFree(unsafe.Pointer(buf), unsafe.Sizeof(*buf.ptr()), &memstats.other_sys)
+ }
+ trace.strings = nil
+ trace.shutdown = false
+ trace.cpuLogRead = nil
+ unlock(&trace.lock)
+ })
+}
+
+// ReadTrace returns the next chunk of binary tracing data, blocking until data
+// is available. If tracing is turned off and all the data accumulated while it
+// was on has been returned, ReadTrace returns nil. The caller must copy the
+// returned data before calling ReadTrace again.
+// ReadTrace must be called from one goroutine at a time.
+func ReadTrace() []byte {
+top:
+ var buf []byte
+ var park bool
+ systemstack(func() {
+ buf, park = readTrace0()
+ })
+ if park {
+ gopark(func(gp *g, _ unsafe.Pointer) bool {
+ if !trace.reader.CompareAndSwapNoWB(nil, gp) {
+ // We're racing with another reader.
+ // Wake up and handle this case.
+ return false
+ }
+
+ if g2 := traceReader(); gp == g2 {
+ // New data arrived between unlocking
+ // and the CAS and we won the wake-up
+ // race, so wake up directly.
+ return false
+ } else if g2 != nil {
+ printlock()
+ println("runtime: got trace reader", g2, g2.goid)
+ throw("unexpected trace reader")
+ }
+
+ return true
+ }, nil, waitReasonTraceReaderBlocked, traceBlockSystemGoroutine, 2)
+ goto top
+ }
+
+ return buf
+}
+
+// readTrace0 is ReadTrace's continuation on g0. This must run on the
+// system stack because it acquires trace.lock.
+//
+//go:systemstack
+func readTrace0() (buf []byte, park bool) {
+ if raceenabled {
+ // g0 doesn't have a race context. Borrow the user G's.
+ if getg().racectx != 0 {
+ throw("expected racectx == 0")
+ }
+ getg().racectx = getg().m.curg.racectx
+ // (This defer should get open-coded, which is safe on
+ // the system stack.)
+ defer func() { getg().racectx = 0 }()
+ }
+
+ // Optimistically look for CPU profile samples. This may write new stack
+ // records, and may write new tracing buffers. This must be done with the
+ // trace lock not held. footerWritten and shutdown are safe to access
+ // here. They are only mutated by this goroutine or during a STW.
+ if !trace.footerWritten && !trace.shutdown {
+ traceReadCPU()
+ }
+
+ // This function must not allocate while holding trace.lock:
+ // allocation can call heap allocate, which will try to emit a trace
+ // event while holding heap lock.
+ lock(&trace.lock)
+
+ if trace.reader.Load() != nil {
+ // More than one goroutine reads trace. This is bad.
+ // But we rather do not crash the program because of tracing,
+ // because tracing can be enabled at runtime on prod servers.
+ unlock(&trace.lock)
+ println("runtime: ReadTrace called from multiple goroutines simultaneously")
+ return nil, false
+ }
+ // Recycle the old buffer.
+ if buf := trace.reading; buf != 0 {
+ buf.ptr().link = trace.empty
+ trace.empty = buf
+ trace.reading = 0
+ }
+ // Write trace header.
+ if !trace.headerWritten {
+ trace.headerWritten = true
+ unlock(&trace.lock)
+ return []byte("go 1.21 trace\x00\x00\x00"), false
+ }
+ // Wait for new data.
+ if trace.fullHead == 0 && !trace.shutdown {
+ // We don't simply use a note because the scheduler
+ // executes this goroutine directly when it wakes up
+ // (also a note would consume an M).
+ unlock(&trace.lock)
+ return nil, true
+ }
+newFull:
+ assertLockHeld(&trace.lock)
+ // Write a buffer.
+ if trace.fullHead != 0 {
+ buf := traceFullDequeue()
+ trace.reading = buf
+ unlock(&trace.lock)
+ return buf.ptr().arr[:buf.ptr().pos], false
+ }
+
+ // Write footer with timer frequency.
+ if !trace.footerWritten {
+ trace.footerWritten = true
+ freq := (float64(trace.endTicks-trace.startTicks) / traceTimeDiv) / (float64(trace.endNanotime-trace.startNanotime) / 1e9)
+ if freq <= 0 {
+ throw("trace: ReadTrace got invalid frequency")
+ }
+ unlock(&trace.lock)
+
+ // Write frequency event.
+ bufp := traceFlush(0, 0)
+ buf := bufp.ptr()
+ buf.byte(traceEvFrequency | 0<<traceArgCountShift)
+ buf.varint(uint64(freq))
+
+ // Dump stack table.
+ // This will emit a bunch of full buffers, we will pick them up
+ // on the next iteration.
+ bufp = trace.stackTab.dump(bufp)
+
+ // Flush final buffer.
+ lock(&trace.lock)
+ traceFullQueue(bufp)
+ goto newFull // trace.lock should be held at newFull
+ }
+ // Done.
+ if trace.shutdown {
+ unlock(&trace.lock)
+ if raceenabled {
+ // Model synchronization on trace.shutdownSema, which race
+ // detector does not see. This is required to avoid false
+ // race reports on writer passed to trace.Start.
+ racerelease(unsafe.Pointer(&trace.shutdownSema))
+ }
+ // trace.enabled is already reset, so can call traceable functions.
+ semrelease(&trace.shutdownSema)
+ return nil, false
+ }
+ // Also bad, but see the comment above.
+ unlock(&trace.lock)
+ println("runtime: spurious wakeup of trace reader")
+ return nil, false
+}
+
+// traceReader returns the trace reader that should be woken up, if any.
+// Callers should first check that trace.enabled or trace.shutdown is set.
+//
+// This must run on the system stack because it acquires trace.lock.
+//
+//go:systemstack
+func traceReader() *g {
+ // Optimistic check first
+ if traceReaderAvailable() == nil {
+ return nil
+ }
+ lock(&trace.lock)
+ gp := traceReaderAvailable()
+ if gp == nil || !trace.reader.CompareAndSwapNoWB(gp, nil) {
+ unlock(&trace.lock)
+ return nil
+ }
+ unlock(&trace.lock)
+ return gp
+}
+
+// traceReaderAvailable returns the trace reader if it is not currently
+// scheduled and should be. Callers should first check that trace.enabled
+// or trace.shutdown is set.
+func traceReaderAvailable() *g {
+ if trace.fullHead != 0 || trace.shutdown {
+ return trace.reader.Load()
+ }
+ return nil
+}
+
+// traceProcFree frees trace buffer associated with pp.
+//
+// This must run on the system stack because it acquires trace.lock.
+//
+//go:systemstack
+func traceProcFree(pp *p) {
+ buf := pp.trace.buf
+ pp.trace.buf = 0
+ if buf == 0 {
+ return
+ }
+ lock(&trace.lock)
+ traceFullQueue(buf)
+ unlock(&trace.lock)
+}
+
+// traceFullQueue queues buf into queue of full buffers.
+func traceFullQueue(buf traceBufPtr) {
+ buf.ptr().link = 0
+ if trace.fullHead == 0 {
+ trace.fullHead = buf
+ } else {
+ trace.fullTail.ptr().link = buf
+ }
+ trace.fullTail = buf
+}
+
+// traceFullDequeue dequeues from queue of full buffers.
+func traceFullDequeue() traceBufPtr {
+ buf := trace.fullHead
+ if buf == 0 {
+ return 0
+ }
+ trace.fullHead = buf.ptr().link
+ if trace.fullHead == 0 {
+ trace.fullTail = 0
+ }
+ buf.ptr().link = 0
+ return buf
+}
+
+// traceEvent writes a single event to trace buffer, flushing the buffer if necessary.
+// ev is event type.
+// If skip > 0, write current stack id as the last argument (skipping skip top frames).
+// If skip = 0, this event type should contain a stack, but we don't want
+// to collect and remember it for this particular call.
+func traceEvent(ev byte, skip int, args ...uint64) {
+ mp, pid, bufp := traceAcquireBuffer()
+ // Double-check trace.enabled now that we've done m.locks++ and acquired bufLock.
+ // This protects from races between traceEvent and StartTrace/StopTrace.
+
+ // The caller checked that trace.enabled == true, but trace.enabled might have been
+ // turned off between the check and now. Check again. traceLockBuffer did mp.locks++,
+ // StopTrace does stopTheWorld, and stopTheWorld waits for mp.locks to go back to zero,
+ // so if we see trace.enabled == true now, we know it's true for the rest of the function.
+ // Exitsyscall can run even during stopTheWorld. The race with StartTrace/StopTrace
+ // during tracing in exitsyscall is resolved by locking trace.bufLock in traceLockBuffer.
+ //
+ // Note trace_userTaskCreate runs the same check.
+ if !trace.enabled && !mp.trace.startingTrace {
+ traceReleaseBuffer(mp, pid)
+ return
+ }
+
+ if skip > 0 {
+ if getg() == mp.curg {
+ skip++ // +1 because stack is captured in traceEventLocked.
+ }
+ }
+ traceEventLocked(0, mp, pid, bufp, ev, 0, skip, args...)
+ traceReleaseBuffer(mp, pid)
+}
+
+// traceEventLocked writes a single event of type ev to the trace buffer bufp,
+// flushing the buffer if necessary. pid is the id of the current P, or
+// traceGlobProc if we're tracing without a real P.
+//
+// Preemption is disabled, and if running without a real P the global tracing
+// buffer is locked.
+//
+// Events types that do not include a stack set skip to -1. Event types that
+// include a stack may explicitly reference a stackID from the trace.stackTab
+// (obtained by an earlier call to traceStackID). Without an explicit stackID,
+// this function will automatically capture the stack of the goroutine currently
+// running on mp, skipping skip top frames or, if skip is 0, writing out an
+// empty stack record.
+//
+// It records the event's args to the traceBuf, and also makes an effort to
+// reserve extraBytes bytes of additional space immediately following the event,
+// in the same traceBuf.
+func traceEventLocked(extraBytes int, mp *m, pid int32, bufp *traceBufPtr, ev byte, stackID uint32, skip int, args ...uint64) {
+ buf := bufp.ptr()
+ // TODO: test on non-zero extraBytes param.
+ maxSize := 2 + 5*traceBytesPerNumber + extraBytes // event type, length, sequence, timestamp, stack id and two add params
+ if buf == nil || len(buf.arr)-buf.pos < maxSize {
+ systemstack(func() {
+ buf = traceFlush(traceBufPtrOf(buf), pid).ptr()
+ })
+ bufp.set(buf)
+ }
+
+ ts := traceClockNow()
+ if ts <= buf.lastTime {
+ ts = buf.lastTime + 1
+ }
+ tsDiff := uint64(ts - buf.lastTime)
+ buf.lastTime = ts
+ narg := byte(len(args))
+ if stackID != 0 || skip >= 0 {
+ narg++
+ }
+ // We have only 2 bits for number of arguments.
+ // If number is >= 3, then the event type is followed by event length in bytes.
+ if narg > 3 {
+ narg = 3
+ }
+ startPos := buf.pos
+ buf.byte(ev | narg<<traceArgCountShift)
+ var lenp *byte
+ if narg == 3 {
+ // Reserve the byte for length assuming that length < 128.
+ buf.varint(0)
+ lenp = &buf.arr[buf.pos-1]
+ }
+ buf.varint(tsDiff)
+ for _, a := range args {
+ buf.varint(a)
+ }
+ if stackID != 0 {
+ buf.varint(uint64(stackID))
+ } else if skip == 0 {
+ buf.varint(0)
+ } else if skip > 0 {
+ buf.varint(traceStackID(mp, buf.stk[:], skip))
+ }
+ evSize := buf.pos - startPos
+ if evSize > maxSize {
+ throw("invalid length of trace event")
+ }
+ if lenp != nil {
+ // Fill in actual length.
+ *lenp = byte(evSize - 2)
+ }
+}
+
+// traceCPUSample writes a CPU profile sample stack to the execution tracer's
+// profiling buffer. It is called from a signal handler, so is limited in what
+// it can do.
+func traceCPUSample(gp *g, pp *p, stk []uintptr) {
+ if !trace.enabled {
+ // Tracing is usually turned off; don't spend time acquiring the signal
+ // lock unless it's active.
+ return
+ }
+
+ // Match the clock used in traceEventLocked
+ now := traceClockNow()
+ // The "header" here is the ID of the P that was running the profiled code,
+ // followed by the ID of the goroutine. (For normal CPU profiling, it's
+ // usually the number of samples with the given stack.) Near syscalls, pp
+ // may be nil. Reporting goid of 0 is fine for either g0 or a nil gp.
+ var hdr [2]uint64
+ if pp != nil {
+ // Overflow records in profBuf have all header values set to zero. Make
+ // sure that real headers have at least one bit set.
+ hdr[0] = uint64(pp.id)<<1 | 0b1
+ } else {
+ hdr[0] = 0b10
+ }
+ if gp != nil {
+ hdr[1] = gp.goid
+ }
+
+ // Allow only one writer at a time
+ for !trace.signalLock.CompareAndSwap(0, 1) {
+ // TODO: Is it safe to osyield here? https://go.dev/issue/52672
+ osyield()
+ }
+
+ if log := (*profBuf)(atomic.Loadp(unsafe.Pointer(&trace.cpuLogWrite))); log != nil {
+ // Note: we don't pass a tag pointer here (how should profiling tags
+ // interact with the execution tracer?), but if we did we'd need to be
+ // careful about write barriers. See the long comment in profBuf.write.
+ log.write(nil, int64(now), hdr[:], stk)
+ }
+
+ trace.signalLock.Store(0)
+}
+
+func traceReadCPU() {
+ bufp := &trace.cpuLogBuf
+
+ for {
+ data, tags, _ := trace.cpuLogRead.read(profBufNonBlocking)
+ if len(data) == 0 {
+ break
+ }
+ for len(data) > 0 {
+ if len(data) < 4 || data[0] > uint64(len(data)) {
+ break // truncated profile
+ }
+ if data[0] < 4 || tags != nil && len(tags) < 1 {
+ break // malformed profile
+ }
+ if len(tags) < 1 {
+ break // mismatched profile records and tags
+ }
+ timestamp := data[1]
+ ppid := data[2] >> 1
+ if hasP := (data[2] & 0b1) != 0; !hasP {
+ ppid = ^uint64(0)
+ }
+ goid := data[3]
+ stk := data[4:data[0]]
+ empty := len(stk) == 1 && data[2] == 0 && data[3] == 0
+ data = data[data[0]:]
+ // No support here for reporting goroutine tags at the moment; if
+ // that information is to be part of the execution trace, we'd
+ // probably want to see when the tags are applied and when they
+ // change, instead of only seeing them when we get a CPU sample.
+ tags = tags[1:]
+
+ if empty {
+ // Looks like an overflow record from the profBuf. Not much to
+ // do here, we only want to report full records.
+ //
+ // TODO: should we start a goroutine to drain the profBuf,
+ // rather than relying on a high-enough volume of tracing events
+ // to keep ReadTrace busy? https://go.dev/issue/52674
+ continue
+ }
+
+ buf := bufp.ptr()
+ if buf == nil {
+ systemstack(func() {
+ *bufp = traceFlush(*bufp, 0)
+ })
+ buf = bufp.ptr()
+ }
+ nstk := 1
+ buf.stk[0] = logicalStackSentinel
+ for ; nstk < len(buf.stk) && nstk-1 < len(stk); nstk++ {
+ buf.stk[nstk] = uintptr(stk[nstk-1])
+ }
+ stackID := trace.stackTab.put(buf.stk[:nstk])
+
+ traceEventLocked(0, nil, 0, bufp, traceEvCPUSample, stackID, 1, uint64(timestamp), ppid, goid)
+ }
+ }
+}
+
+// logicalStackSentinel is a sentinel value at pcBuf[0] signifying that
+// pcBuf[1:] holds a logical stack requiring no further processing. Any other
+// value at pcBuf[0] represents a skip value to apply to the physical stack in
+// pcBuf[1:] after inline expansion.
+const logicalStackSentinel = ^uintptr(0)
+
+// traceStackID captures a stack trace into pcBuf, registers it in the trace
+// stack table, and returns its unique ID. pcBuf should have a length equal to
+// traceStackSize. skip controls the number of leaf frames to omit in order to
+// hide tracer internals from stack traces, see CL 5523.
+func traceStackID(mp *m, pcBuf []uintptr, skip int) uint64 {
+ gp := getg()
+ curgp := mp.curg
+ nstk := 1
+ if tracefpunwindoff() || mp.hasCgoOnStack() {
+ // Slow path: Unwind using default unwinder. Used when frame pointer
+ // unwinding is unavailable or disabled (tracefpunwindoff), or might
+ // produce incomplete results or crashes (hasCgoOnStack). Note that no
+ // cgo callback related crashes have been observed yet. The main
+ // motivation is to take advantage of a potentially registered cgo
+ // symbolizer.
+ pcBuf[0] = logicalStackSentinel
+ if curgp == gp {
+ nstk += callers(skip+1, pcBuf[1:])
+ } else if curgp != nil {
+ nstk += gcallers(curgp, skip, pcBuf[1:])
+ }
+ } else {
+ // Fast path: Unwind using frame pointers.
+ pcBuf[0] = uintptr(skip)
+ if curgp == gp {
+ nstk += fpTracebackPCs(unsafe.Pointer(getfp()), pcBuf[1:])
+ } else if curgp != nil {
+ // We're called on the g0 stack through mcall(fn) or systemstack(fn). To
+ // behave like gcallers above, we start unwinding from sched.bp, which
+ // points to the caller frame of the leaf frame on g's stack. The return
+ // address of the leaf frame is stored in sched.pc, which we manually
+ // capture here.
+ pcBuf[1] = curgp.sched.pc
+ nstk += 1 + fpTracebackPCs(unsafe.Pointer(curgp.sched.bp), pcBuf[2:])
+ }
+ }
+ if nstk > 0 {
+ nstk-- // skip runtime.goexit
+ }
+ if nstk > 0 && curgp.goid == 1 {
+ nstk-- // skip runtime.main
+ }
+ id := trace.stackTab.put(pcBuf[:nstk])
+ return uint64(id)
+}
+
+// tracefpunwindoff returns true if frame pointer unwinding for the tracer is
+// disabled via GODEBUG or not supported by the architecture.
+// TODO(#60254): support frame pointer unwinding on plan9/amd64.
+func tracefpunwindoff() bool {
+ return debug.tracefpunwindoff != 0 || (goarch.ArchFamily != goarch.AMD64 && goarch.ArchFamily != goarch.ARM64) || goos.IsPlan9 == 1
+}
+
+// fpTracebackPCs populates pcBuf with the return addresses for each frame and
+// returns the number of PCs written to pcBuf. The returned PCs correspond to
+// "physical frames" rather than "logical frames"; that is if A is inlined into
+// B, this will return a PC for only B.
+func fpTracebackPCs(fp unsafe.Pointer, pcBuf []uintptr) (i int) {
+ for i = 0; i < len(pcBuf) && fp != nil; i++ {
+ // return addr sits one word above the frame pointer
+ pcBuf[i] = *(*uintptr)(unsafe.Pointer(uintptr(fp) + goarch.PtrSize))
+ // follow the frame pointer to the next one
+ fp = unsafe.Pointer(*(*uintptr)(fp))
+ }
+ return i
+}
+
+// traceAcquireBuffer returns trace buffer to use and, if necessary, locks it.
+func traceAcquireBuffer() (mp *m, pid int32, bufp *traceBufPtr) {
+ // Any time we acquire a buffer, we may end up flushing it,
+ // but flushes are rare. Record the lock edge even if it
+ // doesn't happen this time.
+ lockRankMayTraceFlush()
+
+ mp = acquirem()
+ if p := mp.p.ptr(); p != nil {
+ return mp, p.id, &p.trace.buf
+ }
+ lock(&trace.bufLock)
+ return mp, traceGlobProc, &trace.buf
+}
+
+// traceReleaseBuffer releases a buffer previously acquired with traceAcquireBuffer.
+func traceReleaseBuffer(mp *m, pid int32) {
+ if pid == traceGlobProc {
+ unlock(&trace.bufLock)
+ }
+ releasem(mp)
+}
+
+// lockRankMayTraceFlush records the lock ranking effects of a
+// potential call to traceFlush.
+func lockRankMayTraceFlush() {
+ lockWithRankMayAcquire(&trace.lock, getLockRank(&trace.lock))
+}
+
+// traceFlush puts buf onto stack of full buffers and returns an empty buffer.
+//
+// This must run on the system stack because it acquires trace.lock.
+//
+//go:systemstack
+func traceFlush(buf traceBufPtr, pid int32) traceBufPtr {
+ lock(&trace.lock)
+ if buf != 0 {
+ traceFullQueue(buf)
+ }
+ if trace.empty != 0 {
+ buf = trace.empty
+ trace.empty = buf.ptr().link
+ } else {
+ buf = traceBufPtr(sysAlloc(unsafe.Sizeof(traceBuf{}), &memstats.other_sys))
+ if buf == 0 {
+ throw("trace: out of memory")
+ }
+ }
+ bufp := buf.ptr()
+ bufp.link.set(nil)
+ bufp.pos = 0
+
+ // initialize the buffer for a new batch
+ ts := traceClockNow()
+ if ts <= bufp.lastTime {
+ ts = bufp.lastTime + 1
+ }
+ bufp.lastTime = ts
+ bufp.byte(traceEvBatch | 1<<traceArgCountShift)
+ bufp.varint(uint64(pid))
+ bufp.varint(uint64(ts))
+
+ unlock(&trace.lock)
+ return buf
+}
+
+// traceString adds a string to the trace.strings and returns the id.
+func traceString(bufp *traceBufPtr, pid int32, s string) (uint64, *traceBufPtr) {
+ if s == "" {
+ return 0, bufp
+ }
+
+ lock(&trace.stringsLock)
+ if raceenabled {
+ // raceacquire is necessary because the map access
+ // below is race annotated.
+ raceacquire(unsafe.Pointer(&trace.stringsLock))
+ }
+
+ if id, ok := trace.strings[s]; ok {
+ if raceenabled {
+ racerelease(unsafe.Pointer(&trace.stringsLock))
+ }
+ unlock(&trace.stringsLock)
+
+ return id, bufp
+ }
+
+ trace.stringSeq++
+ id := trace.stringSeq
+ trace.strings[s] = id
+
+ if raceenabled {
+ racerelease(unsafe.Pointer(&trace.stringsLock))
+ }
+ unlock(&trace.stringsLock)
+
+ // memory allocation in above may trigger tracing and
+ // cause *bufp changes. Following code now works with *bufp,
+ // so there must be no memory allocation or any activities
+ // that causes tracing after this point.
+
+ buf := bufp.ptr()
+ size := 1 + 2*traceBytesPerNumber + len(s)
+ if buf == nil || len(buf.arr)-buf.pos < size {
+ systemstack(func() {
+ buf = traceFlush(traceBufPtrOf(buf), pid).ptr()
+ bufp.set(buf)
+ })
+ }
+ buf.byte(traceEvString)
+ buf.varint(id)
+
+ // double-check the string and the length can fit.
+ // Otherwise, truncate the string.
+ slen := len(s)
+ if room := len(buf.arr) - buf.pos; room < slen+traceBytesPerNumber {
+ slen = room
+ }
+
+ buf.varint(uint64(slen))
+ buf.pos += copy(buf.arr[buf.pos:], s[:slen])
+
+ bufp.set(buf)
+ return id, bufp
+}
+
+// varint appends v to buf in little-endian-base-128 encoding.
+func (buf *traceBuf) varint(v uint64) {
+ pos := buf.pos
+ for ; v >= 0x80; v >>= 7 {
+ buf.arr[pos] = 0x80 | byte(v)
+ pos++
+ }
+ buf.arr[pos] = byte(v)
+ pos++
+ buf.pos = pos
+}
+
+// varintAt writes varint v at byte position pos in buf. This always
+// consumes traceBytesPerNumber bytes. This is intended for when the
+// caller needs to reserve space for a varint but can't populate it
+// until later.
+func (buf *traceBuf) varintAt(pos int, v uint64) {
+ for i := 0; i < traceBytesPerNumber; i++ {
+ if i < traceBytesPerNumber-1 {
+ buf.arr[pos] = 0x80 | byte(v)
+ } else {
+ buf.arr[pos] = byte(v)
+ }
+ v >>= 7
+ pos++
+ }
+}
+
+// byte appends v to buf.
+func (buf *traceBuf) byte(v byte) {
+ buf.arr[buf.pos] = v
+ buf.pos++
+}
+
+// traceStackTable maps stack traces (arrays of PC's) to unique uint32 ids.
+// It is lock-free for reading.
+type traceStackTable struct {
+ lock mutex // Must be acquired on the system stack
+ seq uint32
+ mem traceAlloc
+ tab [1 << 13]traceStackPtr
+}
+
+// traceStack is a single stack in traceStackTable.
+type traceStack struct {
+ link traceStackPtr
+ hash uintptr
+ id uint32
+ n int
+ stk [0]uintptr // real type [n]uintptr
+}
+
+type traceStackPtr uintptr
+
+func (tp traceStackPtr) ptr() *traceStack { return (*traceStack)(unsafe.Pointer(tp)) }
+
+// stack returns slice of PCs.
+func (ts *traceStack) stack() []uintptr {
+ return (*[traceStackSize]uintptr)(unsafe.Pointer(&ts.stk))[:ts.n]
+}
+
+// put returns a unique id for the stack trace pcs and caches it in the table,
+// if it sees the trace for the first time.
+func (tab *traceStackTable) put(pcs []uintptr) uint32 {
+ if len(pcs) == 0 {
+ return 0
+ }
+ hash := memhash(unsafe.Pointer(&pcs[0]), 0, uintptr(len(pcs))*unsafe.Sizeof(pcs[0]))
+ // First, search the hashtable w/o the mutex.
+ if id := tab.find(pcs, hash); id != 0 {
+ return id
+ }
+ // Now, double check under the mutex.
+ // Switch to the system stack so we can acquire tab.lock
+ var id uint32
+ systemstack(func() {
+ lock(&tab.lock)
+ if id = tab.find(pcs, hash); id != 0 {
+ unlock(&tab.lock)
+ return
+ }
+ // Create new record.
+ tab.seq++
+ stk := tab.newStack(len(pcs))
+ stk.hash = hash
+ stk.id = tab.seq
+ id = stk.id
+ stk.n = len(pcs)
+ stkpc := stk.stack()
+ copy(stkpc, pcs)
+ part := int(hash % uintptr(len(tab.tab)))
+ stk.link = tab.tab[part]
+ atomicstorep(unsafe.Pointer(&tab.tab[part]), unsafe.Pointer(stk))
+ unlock(&tab.lock)
+ })
+ return id
+}
+
+// find checks if the stack trace pcs is already present in the table.
+func (tab *traceStackTable) find(pcs []uintptr, hash uintptr) uint32 {
+ part := int(hash % uintptr(len(tab.tab)))
+Search:
+ for stk := tab.tab[part].ptr(); stk != nil; stk = stk.link.ptr() {
+ if stk.hash == hash && stk.n == len(pcs) {
+ for i, stkpc := range stk.stack() {
+ if stkpc != pcs[i] {
+ continue Search
+ }
+ }
+ return stk.id
+ }
+ }
+ return 0
+}
+
+// newStack allocates a new stack of size n.
+func (tab *traceStackTable) newStack(n int) *traceStack {
+ return (*traceStack)(tab.mem.alloc(unsafe.Sizeof(traceStack{}) + uintptr(n)*goarch.PtrSize))
+}
+
+// traceFrames returns the frames corresponding to pcs. It may
+// allocate and may emit trace events.
+func traceFrames(bufp traceBufPtr, pcs []uintptr) ([]traceFrame, traceBufPtr) {
+ frames := make([]traceFrame, 0, len(pcs))
+ ci := CallersFrames(pcs)
+ for {
+ var frame traceFrame
+ f, more := ci.Next()
+ frame, bufp = traceFrameForPC(bufp, 0, f)
+ frames = append(frames, frame)
+ if !more {
+ return frames, bufp
+ }
+ }
+}
+
+// dump writes all previously cached stacks to trace buffers,
+// releases all memory and resets state.
+//
+// This must run on the system stack because it calls traceFlush.
+//
+//go:systemstack
+func (tab *traceStackTable) dump(bufp traceBufPtr) traceBufPtr {
+ for i := range tab.tab {
+ stk := tab.tab[i].ptr()
+ for ; stk != nil; stk = stk.link.ptr() {
+ var frames []traceFrame
+ frames, bufp = traceFrames(bufp, fpunwindExpand(stk.stack()))
+
+ // Estimate the size of this record. This
+ // bound is pretty loose, but avoids counting
+ // lots of varint sizes.
+ maxSize := 1 + traceBytesPerNumber + (2+4*len(frames))*traceBytesPerNumber
+ // Make sure we have enough buffer space.
+ if buf := bufp.ptr(); len(buf.arr)-buf.pos < maxSize {
+ bufp = traceFlush(bufp, 0)
+ }
+
+ // Emit header, with space reserved for length.
+ buf := bufp.ptr()
+ buf.byte(traceEvStack | 3<<traceArgCountShift)
+ lenPos := buf.pos
+ buf.pos += traceBytesPerNumber
+
+ // Emit body.
+ recPos := buf.pos
+ buf.varint(uint64(stk.id))
+ buf.varint(uint64(len(frames)))
+ for _, frame := range frames {
+ buf.varint(uint64(frame.PC))
+ buf.varint(frame.funcID)
+ buf.varint(frame.fileID)
+ buf.varint(frame.line)
+ }
+
+ // Fill in size header.
+ buf.varintAt(lenPos, uint64(buf.pos-recPos))
+ }
+ }
+
+ tab.mem.drop()
+ *tab = traceStackTable{}
+ lockInit(&((*tab).lock), lockRankTraceStackTab)
+
+ return bufp
+}
+
+// fpunwindExpand checks if pcBuf contains logical frames (which include inlined
+// frames) or physical frames (produced by frame pointer unwinding) using a
+// sentinel value in pcBuf[0]. Logical frames are simply returned without the
+// sentinel. Physical frames are turned into logical frames via inline unwinding
+// and by applying the skip value that's stored in pcBuf[0].
+func fpunwindExpand(pcBuf []uintptr) []uintptr {
+ if len(pcBuf) > 0 && pcBuf[0] == logicalStackSentinel {
+ // pcBuf contains logical rather than inlined frames, skip has already been
+ // applied, just return it without the sentinel value in pcBuf[0].
+ return pcBuf[1:]
+ }
+
+ var (
+ cache pcvalueCache
+ lastFuncID = abi.FuncIDNormal
+ newPCBuf = make([]uintptr, 0, traceStackSize)
+ skip = pcBuf[0]
+ // skipOrAdd skips or appends retPC to newPCBuf and returns true if more
+ // pcs can be added.
+ skipOrAdd = func(retPC uintptr) bool {
+ if skip > 0 {
+ skip--
+ } else {
+ newPCBuf = append(newPCBuf, retPC)
+ }
+ return len(newPCBuf) < cap(newPCBuf)
+ }
+ )
+
+outer:
+ for _, retPC := range pcBuf[1:] {
+ callPC := retPC - 1
+ fi := findfunc(callPC)
+ if !fi.valid() {
+ // There is no funcInfo if callPC belongs to a C function. In this case
+ // we still keep the pc, but don't attempt to expand inlined frames.
+ if more := skipOrAdd(retPC); !more {
+ break outer
+ }
+ continue
+ }
+
+ u, uf := newInlineUnwinder(fi, callPC, &cache)
+ for ; uf.valid(); uf = u.next(uf) {
+ sf := u.srcFunc(uf)
+ if sf.funcID == abi.FuncIDWrapper && elideWrapperCalling(lastFuncID) {
+ // ignore wrappers
+ } else if more := skipOrAdd(uf.pc + 1); !more {
+ break outer
+ }
+ lastFuncID = sf.funcID
+ }
+ }
+ return newPCBuf
+}
+
+type traceFrame struct {
+ PC uintptr
+ funcID uint64
+ fileID uint64
+ line uint64
+}
+
+// traceFrameForPC records the frame information.
+// It may allocate memory.
+func traceFrameForPC(buf traceBufPtr, pid int32, f Frame) (traceFrame, traceBufPtr) {
+ bufp := &buf
+ var frame traceFrame
+ frame.PC = f.PC
+
+ fn := f.Function
+ const maxLen = 1 << 10
+ if len(fn) > maxLen {
+ fn = fn[len(fn)-maxLen:]
+ }
+ frame.funcID, bufp = traceString(bufp, pid, fn)
+ frame.line = uint64(f.Line)
+ file := f.File
+ if len(file) > maxLen {
+ file = file[len(file)-maxLen:]
+ }
+ frame.fileID, bufp = traceString(bufp, pid, file)
+ return frame, (*bufp)
+}
+
+// traceAlloc is a non-thread-safe region allocator.
+// It holds a linked list of traceAllocBlock.
+type traceAlloc struct {
+ head traceAllocBlockPtr
+ off uintptr
+}
+
+// traceAllocBlock is a block in traceAlloc.
+//
+// traceAllocBlock is allocated from non-GC'd memory, so it must not
+// contain heap pointers. Writes to pointers to traceAllocBlocks do
+// not need write barriers.
+type traceAllocBlock struct {
+ _ sys.NotInHeap
+ next traceAllocBlockPtr
+ data [64<<10 - goarch.PtrSize]byte
+}
+
+// TODO: Since traceAllocBlock is now embedded runtime/internal/sys.NotInHeap, this isn't necessary.
+type traceAllocBlockPtr uintptr
+
+func (p traceAllocBlockPtr) ptr() *traceAllocBlock { return (*traceAllocBlock)(unsafe.Pointer(p)) }
+func (p *traceAllocBlockPtr) set(x *traceAllocBlock) { *p = traceAllocBlockPtr(unsafe.Pointer(x)) }
+
+// alloc allocates n-byte block.
+func (a *traceAlloc) alloc(n uintptr) unsafe.Pointer {
+ n = alignUp(n, goarch.PtrSize)
+ if a.head == 0 || a.off+n > uintptr(len(a.head.ptr().data)) {
+ if n > uintptr(len(a.head.ptr().data)) {
+ throw("trace: alloc too large")
+ }
+ block := (*traceAllocBlock)(sysAlloc(unsafe.Sizeof(traceAllocBlock{}), &memstats.other_sys))
+ if block == nil {
+ throw("trace: out of memory")
+ }
+ block.next.set(a.head.ptr())
+ a.head.set(block)
+ a.off = 0
+ }
+ p := &a.head.ptr().data[a.off]
+ a.off += n
+ return unsafe.Pointer(p)
+}
+
+// drop frees all previously allocated memory and resets the allocator.
+func (a *traceAlloc) drop() {
+ for a.head != 0 {
+ block := a.head.ptr()
+ a.head.set(block.next.ptr())
+ sysFree(unsafe.Pointer(block), unsafe.Sizeof(traceAllocBlock{}), &memstats.other_sys)
+ }
+}
+
+// The following functions write specific events to trace.
+
+func traceGomaxprocs(procs int32) {
+ traceEvent(traceEvGomaxprocs, 1, uint64(procs))
+}
+
+func traceProcStart() {
+ traceEvent(traceEvProcStart, -1, uint64(getg().m.id))
+}
+
+func traceProcStop(pp *p) {
+ // Sysmon and stopTheWorld can stop Ps blocked in syscalls,
+ // to handle this we temporary employ the P.
+ mp := acquirem()
+ oldp := mp.p
+ mp.p.set(pp)
+ traceEvent(traceEvProcStop, -1)
+ mp.p = oldp
+ releasem(mp)
+}
+
+func traceGCStart() {
+ traceEvent(traceEvGCStart, 3, trace.seqGC)
+ trace.seqGC++
+}
+
+func traceGCDone() {
+ traceEvent(traceEvGCDone, -1)
+}
+
+func traceSTWStart(reason stwReason) {
+ // Don't trace if this STW is for trace start/stop, since traceEnabled
+ // switches during a STW.
+ if reason == stwStartTrace || reason == stwStopTrace {
+ return
+ }
+ getg().m.trace.tracedSTWStart = true
+ traceEvent(traceEvSTWStart, -1, uint64(reason))
+}
+
+func traceSTWDone() {
+ mp := getg().m
+ if !mp.trace.tracedSTWStart {
+ return
+ }
+ mp.trace.tracedSTWStart = false
+ traceEvent(traceEvSTWDone, -1)
+}
+
+// traceGCSweepStart prepares to trace a sweep loop. This does not
+// emit any events until traceGCSweepSpan is called.
+//
+// traceGCSweepStart must be paired with traceGCSweepDone and there
+// must be no preemption points between these two calls.
+func traceGCSweepStart() {
+ // Delay the actual GCSweepStart event until the first span
+ // sweep. If we don't sweep anything, don't emit any events.
+ pp := getg().m.p.ptr()
+ if pp.trace.inSweep {
+ throw("double traceGCSweepStart")
+ }
+ pp.trace.inSweep, pp.trace.swept, pp.trace.reclaimed = true, 0, 0
+}
+
+// traceGCSweepSpan traces the sweep of a single page.
+//
+// This may be called outside a traceGCSweepStart/traceGCSweepDone
+// pair; however, it will not emit any trace events in this case.
+func traceGCSweepSpan(bytesSwept uintptr) {
+ pp := getg().m.p.ptr()
+ if pp.trace.inSweep {
+ if pp.trace.swept == 0 {
+ traceEvent(traceEvGCSweepStart, 1)
+ }
+ pp.trace.swept += bytesSwept
+ }
+}
+
+func traceGCSweepDone() {
+ pp := getg().m.p.ptr()
+ if !pp.trace.inSweep {
+ throw("missing traceGCSweepStart")
+ }
+ if pp.trace.swept != 0 {
+ traceEvent(traceEvGCSweepDone, -1, uint64(pp.trace.swept), uint64(pp.trace.reclaimed))
+ }
+ pp.trace.inSweep = false
+}
+
+func traceGCMarkAssistStart() {
+ traceEvent(traceEvGCMarkAssistStart, 1)
+}
+
+func traceGCMarkAssistDone() {
+ traceEvent(traceEvGCMarkAssistDone, -1)
+}
+
+func traceGoCreate(newg *g, pc uintptr) {
+ newg.trace.seq = 0
+ newg.trace.lastP = getg().m.p
+ // +PCQuantum because traceFrameForPC expects return PCs and subtracts PCQuantum.
+ id := trace.stackTab.put([]uintptr{logicalStackSentinel, startPCforTrace(pc) + sys.PCQuantum})
+ traceEvent(traceEvGoCreate, 2, newg.goid, uint64(id))
+}
+
+func traceGoStart() {
+ gp := getg().m.curg
+ pp := gp.m.p
+ gp.trace.seq++
+ if pp.ptr().gcMarkWorkerMode != gcMarkWorkerNotWorker {
+ traceEvent(traceEvGoStartLabel, -1, gp.goid, gp.trace.seq, trace.markWorkerLabels[pp.ptr().gcMarkWorkerMode])
+ } else if gp.trace.lastP == pp {
+ traceEvent(traceEvGoStartLocal, -1, gp.goid)
+ } else {
+ gp.trace.lastP = pp
+ traceEvent(traceEvGoStart, -1, gp.goid, gp.trace.seq)
+ }
+}
+
+func traceGoEnd() {
+ traceEvent(traceEvGoEnd, -1)
+}
+
+func traceGoSched() {
+ gp := getg()
+ gp.trace.lastP = gp.m.p
+ traceEvent(traceEvGoSched, 1)
+}
+
+func traceGoPreempt() {
+ gp := getg()
+ gp.trace.lastP = gp.m.p
+ traceEvent(traceEvGoPreempt, 1)
+}
+
+func traceGoPark(reason traceBlockReason, skip int) {
+ // Convert the block reason directly to a trace event type.
+ // See traceBlockReason for more information.
+ traceEvent(byte(reason), skip)
+}
+
+func traceGoUnpark(gp *g, skip int) {
+ pp := getg().m.p
+ gp.trace.seq++
+ if gp.trace.lastP == pp {
+ traceEvent(traceEvGoUnblockLocal, skip, gp.goid)
+ } else {
+ gp.trace.lastP = pp
+ traceEvent(traceEvGoUnblock, skip, gp.goid, gp.trace.seq)
+ }
+}
+
+func traceGoSysCall() {
+ var skip int
+ switch {
+ case tracefpunwindoff():
+ // Unwind by skipping 1 frame relative to gp.syscallsp which is captured 3
+ // frames above this frame. For frame pointer unwinding we produce the same
+ // results by hard coding the number of frames in between our caller and the
+ // actual syscall, see cases below.
+ // TODO(felixge): Implement gp.syscallbp to avoid this workaround?
+ skip = 1
+ case GOOS == "solaris" || GOOS == "illumos":
+ // These platforms don't use a libc_read_trampoline.
+ skip = 3
+ default:
+ // Skip the extra trampoline frame used on most systems.
+ skip = 4
+ }
+ getg().m.curg.trace.tracedSyscallEnter = true
+ traceEvent(traceEvGoSysCall, skip)
+}
+
+func traceGoSysExit() {
+ gp := getg().m.curg
+ if !gp.trace.tracedSyscallEnter {
+ // There was no syscall entry traced for us at all, so there's definitely
+ // no EvGoSysBlock or EvGoInSyscall before us, which EvGoSysExit requires.
+ return
+ }
+ gp.trace.tracedSyscallEnter = false
+ ts := gp.trace.sysExitTime
+ if ts != 0 && ts < trace.startTime {
+ // There is a race between the code that initializes sysExitTimes
+ // (in exitsyscall, which runs without a P, and therefore is not
+ // stopped with the rest of the world) and the code that initializes
+ // a new trace. The recorded sysExitTime must therefore be treated
+ // as "best effort". If they are valid for this trace, then great,
+ // use them for greater accuracy. But if they're not valid for this
+ // trace, assume that the trace was started after the actual syscall
+ // exit (but before we actually managed to start the goroutine,
+ // aka right now), and assign a fresh time stamp to keep the log consistent.
+ ts = 0
+ }
+ gp.trace.sysExitTime = 0
+ gp.trace.seq++
+ gp.trace.lastP = gp.m.p
+ traceEvent(traceEvGoSysExit, -1, gp.goid, gp.trace.seq, uint64(ts))
+}
+
+func traceGoSysBlock(pp *p) {
+ // Sysmon and stopTheWorld can declare syscalls running on remote Ps as blocked,
+ // to handle this we temporary employ the P.
+ mp := acquirem()
+ oldp := mp.p
+ mp.p.set(pp)
+ traceEvent(traceEvGoSysBlock, -1)
+ mp.p = oldp
+ releasem(mp)
+}
+
+func traceHeapAlloc(live uint64) {
+ traceEvent(traceEvHeapAlloc, -1, live)
+}
+
+func traceHeapGoal() {
+ heapGoal := gcController.heapGoal()
+ if heapGoal == ^uint64(0) {
+ // Heap-based triggering is disabled.
+ traceEvent(traceEvHeapGoal, -1, 0)
+ } else {
+ traceEvent(traceEvHeapGoal, -1, heapGoal)
+ }
+}
+
+// To access runtime functions from runtime/trace.
+// See runtime/trace/annotation.go
+
+//go:linkname trace_userTaskCreate runtime/trace.userTaskCreate
+func trace_userTaskCreate(id, parentID uint64, taskType string) {
+ if !trace.enabled {
+ return
+ }
+
+ // Same as in traceEvent.
+ mp, pid, bufp := traceAcquireBuffer()
+ if !trace.enabled && !mp.trace.startingTrace {
+ traceReleaseBuffer(mp, pid)
+ return
+ }
+
+ typeStringID, bufp := traceString(bufp, pid, taskType)
+ traceEventLocked(0, mp, pid, bufp, traceEvUserTaskCreate, 0, 3, id, parentID, typeStringID)
+ traceReleaseBuffer(mp, pid)
+}
+
+//go:linkname trace_userTaskEnd runtime/trace.userTaskEnd
+func trace_userTaskEnd(id uint64) {
+ traceEvent(traceEvUserTaskEnd, 2, id)
+}
+
+//go:linkname trace_userRegion runtime/trace.userRegion
+func trace_userRegion(id, mode uint64, name string) {
+ if !trace.enabled {
+ return
+ }
+
+ mp, pid, bufp := traceAcquireBuffer()
+ if !trace.enabled && !mp.trace.startingTrace {
+ traceReleaseBuffer(mp, pid)
+ return
+ }
+
+ nameStringID, bufp := traceString(bufp, pid, name)
+ traceEventLocked(0, mp, pid, bufp, traceEvUserRegion, 0, 3, id, mode, nameStringID)
+ traceReleaseBuffer(mp, pid)
+}
+
+//go:linkname trace_userLog runtime/trace.userLog
+func trace_userLog(id uint64, category, message string) {
+ if !trace.enabled {
+ return
+ }
+
+ mp, pid, bufp := traceAcquireBuffer()
+ if !trace.enabled && !mp.trace.startingTrace {
+ traceReleaseBuffer(mp, pid)
+ return
+ }
+
+ categoryID, bufp := traceString(bufp, pid, category)
+
+ // The log message is recorded after all of the normal trace event
+ // arguments, including the task, category, and stack IDs. We must ask
+ // traceEventLocked to reserve extra space for the length of the message
+ // and the message itself.
+ extraSpace := traceBytesPerNumber + len(message)
+ traceEventLocked(extraSpace, mp, pid, bufp, traceEvUserLog, 0, 3, id, categoryID)
+ buf := bufp.ptr()
+
+ // double-check the message and its length can fit.
+ // Otherwise, truncate the message.
+ slen := len(message)
+ if room := len(buf.arr) - buf.pos; room < slen+traceBytesPerNumber {
+ slen = room
+ }
+ buf.varint(uint64(slen))
+ buf.pos += copy(buf.arr[buf.pos:], message[:slen])
+
+ traceReleaseBuffer(mp, pid)
+}
+
+// the start PC of a goroutine for tracing purposes. If pc is a wrapper,
+// it returns the PC of the wrapped function. Otherwise it returns pc.
+func startPCforTrace(pc uintptr) uintptr {
+ f := findfunc(pc)
+ if !f.valid() {
+ return pc // may happen for locked g in extra M since its pc is 0.
+ }
+ w := funcdata(f, abi.FUNCDATA_WrapInfo)
+ if w == nil {
+ return pc // not a wrapper
+ }
+ return f.datap.textAddr(*(*uint32)(w))
+}
+
+// traceOneNewExtraM registers the fact that a new extra M was created with
+// the tracer. This matters if the M (which has an attached G) is used while
+// the trace is still active because if it is, we need the fact that it exists
+// to show up in the final trace.
+func traceOneNewExtraM(gp *g) {
+ // Trigger two trace events for the locked g in the extra m,
+ // since the next event of the g will be traceEvGoSysExit in exitsyscall,
+ // while calling from C thread to Go.
+ traceGoCreate(gp, 0) // no start pc
+ gp.trace.seq++
+ traceEvent(traceEvGoInSyscall, -1, gp.goid)
+}
+
+// traceTime represents a timestamp for the trace.
+type traceTime uint64
+
+// traceClockNow returns a monotonic timestamp. The clock this function gets
+// the timestamp from is specific to tracing, and shouldn't be mixed with other
+// clock sources.
+//
+// nosplit because it's called from exitsyscall, which is nosplit.
+//
+//go:nosplit
+func traceClockNow() traceTime {
+ return traceTime(cputicks() / traceTimeDiv)
+}
diff --git a/contrib/go/_std_1.21/src/runtime/trace/annotation.go b/contrib/go/_std_1.21/src/runtime/trace/annotation.go
new file mode 100644
index 0000000000..2666d14201
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/trace/annotation.go
@@ -0,0 +1,198 @@
+// Copyright 2018 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 trace
+
+import (
+ "context"
+ "fmt"
+ "sync/atomic"
+ _ "unsafe"
+)
+
+type traceContextKey struct{}
+
+// NewTask creates a task instance with the type taskType and returns
+// it along with a Context that carries the task.
+// If the input context contains a task, the new task is its subtask.
+//
+// The taskType is used to classify task instances. Analysis tools
+// like the Go execution tracer may assume there are only a bounded
+// number of unique task types in the system.
+//
+// The returned Task's [Task.End] method is used to mark the task's end.
+// The trace tool measures task latency as the time between task creation
+// and when the End method is called, and provides the latency
+// distribution per task type.
+// If the End method is called multiple times, only the first
+// call is used in the latency measurement.
+//
+// ctx, task := trace.NewTask(ctx, "awesomeTask")
+// trace.WithRegion(ctx, "preparation", prepWork)
+// // preparation of the task
+// go func() { // continue processing the task in a separate goroutine.
+// defer task.End()
+// trace.WithRegion(ctx, "remainingWork", remainingWork)
+// }()
+func NewTask(pctx context.Context, taskType string) (ctx context.Context, task *Task) {
+ pid := fromContext(pctx).id
+ id := newID()
+ userTaskCreate(id, pid, taskType)
+ s := &Task{id: id}
+ return context.WithValue(pctx, traceContextKey{}, s), s
+
+ // We allocate a new task even when
+ // the tracing is disabled because the context and task
+ // can be used across trace enable/disable boundaries,
+ // which complicates the problem.
+ //
+ // For example, consider the following scenario:
+ // - trace is enabled.
+ // - trace.WithRegion is called, so a new context ctx
+ // with a new region is created.
+ // - trace is disabled.
+ // - trace is enabled again.
+ // - trace APIs with the ctx is called. Is the ID in the task
+ // a valid one to use?
+ //
+ // TODO(hyangah): reduce the overhead at least when
+ // tracing is disabled. Maybe the id can embed a tracing
+ // round number and ignore ids generated from previous
+ // tracing round.
+}
+
+func fromContext(ctx context.Context) *Task {
+ if s, ok := ctx.Value(traceContextKey{}).(*Task); ok {
+ return s
+ }
+ return &bgTask
+}
+
+// Task is a data type for tracing a user-defined, logical operation.
+type Task struct {
+ id uint64
+ // TODO(hyangah): record parent id?
+}
+
+// End marks the end of the operation represented by the [Task].
+func (t *Task) End() {
+ userTaskEnd(t.id)
+}
+
+var lastTaskID uint64 = 0 // task id issued last time
+
+func newID() uint64 {
+ // TODO(hyangah): use per-P cache
+ return atomic.AddUint64(&lastTaskID, 1)
+}
+
+var bgTask = Task{id: uint64(0)}
+
+// Log emits a one-off event with the given category and message.
+// Category can be empty and the API assumes there are only a handful of
+// unique categories in the system.
+func Log(ctx context.Context, category, message string) {
+ id := fromContext(ctx).id
+ userLog(id, category, message)
+}
+
+// Logf is like [Log], but the value is formatted using the specified format spec.
+func Logf(ctx context.Context, category, format string, args ...any) {
+ if IsEnabled() {
+ // Ideally this should be just Log, but that will
+ // add one more frame in the stack trace.
+ id := fromContext(ctx).id
+ userLog(id, category, fmt.Sprintf(format, args...))
+ }
+}
+
+const (
+ regionStartCode = uint64(0)
+ regionEndCode = uint64(1)
+)
+
+// WithRegion starts a region associated with its calling goroutine, runs fn,
+// and then ends the region. If the context carries a task, the region is
+// associated with the task. Otherwise, the region is attached to the background
+// task.
+//
+// The regionType is used to classify regions, so there should be only a
+// handful of unique region types.
+func WithRegion(ctx context.Context, regionType string, fn func()) {
+ // NOTE:
+ // WithRegion helps avoiding misuse of the API but in practice,
+ // this is very restrictive:
+ // - Use of WithRegion makes the stack traces captured from
+ // region start and end are identical.
+ // - Refactoring the existing code to use WithRegion is sometimes
+ // hard and makes the code less readable.
+ // e.g. code block nested deep in the loop with various
+ // exit point with return values
+ // - Refactoring the code to use this API with closure can
+ // cause different GC behavior such as retaining some parameters
+ // longer.
+ // This causes more churns in code than I hoped, and sometimes
+ // makes the code less readable.
+
+ id := fromContext(ctx).id
+ userRegion(id, regionStartCode, regionType)
+ defer userRegion(id, regionEndCode, regionType)
+ fn()
+}
+
+// StartRegion starts a region and returns it.
+// The returned Region's [Region.End] method must be called
+// from the same goroutine where the region was started.
+// Within each goroutine, regions must nest. That is, regions started
+// after this region must be ended before this region can be ended.
+// Recommended usage is
+//
+// defer trace.StartRegion(ctx, "myTracedRegion").End()
+func StartRegion(ctx context.Context, regionType string) *Region {
+ if !IsEnabled() {
+ return noopRegion
+ }
+ id := fromContext(ctx).id
+ userRegion(id, regionStartCode, regionType)
+ return &Region{id, regionType}
+}
+
+// Region is a region of code whose execution time interval is traced.
+type Region struct {
+ id uint64
+ regionType string
+}
+
+var noopRegion = &Region{}
+
+// End marks the end of the traced code region.
+func (r *Region) End() {
+ if r == noopRegion {
+ return
+ }
+ userRegion(r.id, regionEndCode, r.regionType)
+}
+
+// IsEnabled reports whether tracing is enabled.
+// The information is advisory only. The tracing status
+// may have changed by the time this function returns.
+func IsEnabled() bool {
+ return tracing.enabled.Load()
+}
+
+//
+// Function bodies are defined in runtime/trace.go
+//
+
+// emits UserTaskCreate event.
+func userTaskCreate(id, parentID uint64, taskType string)
+
+// emits UserTaskEnd event.
+func userTaskEnd(id uint64)
+
+// emits UserRegion event.
+func userRegion(id, mode uint64, regionType string)
+
+// emits UserLog event.
+func userLog(id uint64, category, message string)
diff --git a/contrib/go/_std_1.21/src/runtime/trace/trace.go b/contrib/go/_std_1.21/src/runtime/trace/trace.go
new file mode 100644
index 0000000000..935d222f02
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/trace/trace.go
@@ -0,0 +1,154 @@
+// Copyright 2015 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 trace contains facilities for programs to generate traces
+// for the Go execution tracer.
+//
+// # Tracing runtime activities
+//
+// The execution trace captures a wide range of execution events such as
+// goroutine creation/blocking/unblocking, syscall enter/exit/block,
+// GC-related events, changes of heap size, processor start/stop, etc.
+// When CPU profiling is active, the execution tracer makes an effort to
+// include those samples as well.
+// A precise nanosecond-precision timestamp and a stack trace is
+// captured for most events. The generated trace can be interpreted
+// using `go tool trace`.
+//
+// Support for tracing tests and benchmarks built with the standard
+// testing package is built into `go test`. For example, the following
+// command runs the test in the current directory and writes the trace
+// file (trace.out).
+//
+// go test -trace=trace.out
+//
+// This runtime/trace package provides APIs to add equivalent tracing
+// support to a standalone program. See the Example that demonstrates
+// how to use this API to enable tracing.
+//
+// There is also a standard HTTP interface to trace data. Adding the
+// following line will install a handler under the /debug/pprof/trace URL
+// to download a live trace:
+//
+// import _ "net/http/pprof"
+//
+// See the [net/http/pprof] package for more details about all of the
+// debug endpoints installed by this import.
+//
+// # User annotation
+//
+// Package trace provides user annotation APIs that can be used to
+// log interesting events during execution.
+//
+// There are three types of user annotations: log messages, regions,
+// and tasks.
+//
+// [Log] emits a timestamped message to the execution trace along with
+// additional information such as the category of the message and
+// which goroutine called [Log]. The execution tracer provides UIs to filter
+// and group goroutines using the log category and the message supplied
+// in [Log].
+//
+// A region is for logging a time interval during a goroutine's execution.
+// By definition, a region starts and ends in the same goroutine.
+// Regions can be nested to represent subintervals.
+// For example, the following code records four regions in the execution
+// trace to trace the durations of sequential steps in a cappuccino making
+// operation.
+//
+// trace.WithRegion(ctx, "makeCappuccino", func() {
+//
+// // orderID allows to identify a specific order
+// // among many cappuccino order region records.
+// trace.Log(ctx, "orderID", orderID)
+//
+// trace.WithRegion(ctx, "steamMilk", steamMilk)
+// trace.WithRegion(ctx, "extractCoffee", extractCoffee)
+// trace.WithRegion(ctx, "mixMilkCoffee", mixMilkCoffee)
+// })
+//
+// A task is a higher-level component that aids tracing of logical
+// operations such as an RPC request, an HTTP request, or an
+// interesting local operation which may require multiple goroutines
+// working together. Since tasks can involve multiple goroutines,
+// they are tracked via a [context.Context] object. [NewTask] creates
+// a new task and embeds it in the returned [context.Context] object.
+// Log messages and regions are attached to the task, if any, in the
+// Context passed to [Log] and [WithRegion].
+//
+// For example, assume that we decided to froth milk, extract coffee,
+// and mix milk and coffee in separate goroutines. With a task,
+// the trace tool can identify the goroutines involved in a specific
+// cappuccino order.
+//
+// ctx, task := trace.NewTask(ctx, "makeCappuccino")
+// trace.Log(ctx, "orderID", orderID)
+//
+// milk := make(chan bool)
+// espresso := make(chan bool)
+//
+// go func() {
+// trace.WithRegion(ctx, "steamMilk", steamMilk)
+// milk <- true
+// }()
+// go func() {
+// trace.WithRegion(ctx, "extractCoffee", extractCoffee)
+// espresso <- true
+// }()
+// go func() {
+// defer task.End() // When assemble is done, the order is complete.
+// <-espresso
+// <-milk
+// trace.WithRegion(ctx, "mixMilkCoffee", mixMilkCoffee)
+// }()
+//
+// The trace tool computes the latency of a task by measuring the
+// time between the task creation and the task end and provides
+// latency distributions for each task type found in the trace.
+package trace
+
+import (
+ "io"
+ "runtime"
+ "sync"
+ "sync/atomic"
+)
+
+// Start enables tracing for the current program.
+// While tracing, the trace will be buffered and written to w.
+// Start returns an error if tracing is already enabled.
+func Start(w io.Writer) error {
+ tracing.Lock()
+ defer tracing.Unlock()
+
+ if err := runtime.StartTrace(); err != nil {
+ return err
+ }
+ go func() {
+ for {
+ data := runtime.ReadTrace()
+ if data == nil {
+ break
+ }
+ w.Write(data)
+ }
+ }()
+ tracing.enabled.Store(true)
+ return nil
+}
+
+// Stop stops the current tracing, if any.
+// Stop only returns after all the writes for the trace have completed.
+func Stop() {
+ tracing.Lock()
+ defer tracing.Unlock()
+ tracing.enabled.Store(false)
+
+ runtime.StopTrace()
+}
+
+var tracing struct {
+ sync.Mutex // gate mutators (Start, Stop)
+ enabled atomic.Bool
+}
diff --git a/contrib/go/_std_1.21/src/runtime/trace/ya.make b/contrib/go/_std_1.21/src/runtime/trace/ya.make
new file mode 100644
index 0000000000..1255e88dff
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/trace/ya.make
@@ -0,0 +1,18 @@
+GO_LIBRARY()
+
+SRCS(
+ annotation.go
+ trace.go
+)
+
+GO_XTEST_SRCS(
+ annotation_test.go
+ example_test.go
+ trace_stack_test.go
+ trace_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/runtime/traceback.go b/contrib/go/_std_1.21/src/runtime/traceback.go
new file mode 100644
index 0000000000..72200d436f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/traceback.go
@@ -0,0 +1,1643 @@
+// Copyright 2009 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 runtime
+
+import (
+ "internal/abi"
+ "internal/bytealg"
+ "internal/goarch"
+ "runtime/internal/sys"
+ "unsafe"
+)
+
+// The code in this file implements stack trace walking for all architectures.
+// The most important fact about a given architecture is whether it uses a link register.
+// On systems with link registers, the prologue for a non-leaf function stores the
+// incoming value of LR at the bottom of the newly allocated stack frame.
+// On systems without link registers (x86), the architecture pushes a return PC during
+// the call instruction, so the return PC ends up above the stack frame.
+// In this file, the return PC is always called LR, no matter how it was found.
+
+const usesLR = sys.MinFrameSize > 0
+
+const (
+ // tracebackInnerFrames is the number of innermost frames to print in a
+ // stack trace. The total maximum frames is tracebackInnerFrames +
+ // tracebackOuterFrames.
+ tracebackInnerFrames = 50
+
+ // tracebackOuterFrames is the number of outermost frames to print in a
+ // stack trace.
+ tracebackOuterFrames = 50
+)
+
+// unwindFlags control the behavior of various unwinders.
+type unwindFlags uint8
+
+const (
+ // unwindPrintErrors indicates that if unwinding encounters an error, it
+ // should print a message and stop without throwing. This is used for things
+ // like stack printing, where it's better to get incomplete information than
+ // to crash. This is also used in situations where everything may not be
+ // stopped nicely and the stack walk may not be able to complete, such as
+ // during profiling signals or during a crash.
+ //
+ // If neither unwindPrintErrors or unwindSilentErrors are set, unwinding
+ // performs extra consistency checks and throws on any error.
+ //
+ // Note that there are a small number of fatal situations that will throw
+ // regardless of unwindPrintErrors or unwindSilentErrors.
+ unwindPrintErrors unwindFlags = 1 << iota
+
+ // unwindSilentErrors silently ignores errors during unwinding.
+ unwindSilentErrors
+
+ // unwindTrap indicates that the initial PC and SP are from a trap, not a
+ // return PC from a call.
+ //
+ // The unwindTrap flag is updated during unwinding. If set, frame.pc is the
+ // address of a faulting instruction instead of the return address of a
+ // call. It also means the liveness at pc may not be known.
+ //
+ // TODO: Distinguish frame.continpc, which is really the stack map PC, from
+ // the actual continuation PC, which is computed differently depending on
+ // this flag and a few other things.
+ unwindTrap
+
+ // unwindJumpStack indicates that, if the traceback is on a system stack, it
+ // should resume tracing at the user stack when the system stack is
+ // exhausted.
+ unwindJumpStack
+)
+
+// An unwinder iterates the physical stack frames of a Go sack.
+//
+// Typical use of an unwinder looks like:
+//
+// var u unwinder
+// for u.init(gp, 0); u.valid(); u.next() {
+// // ... use frame info in u ...
+// }
+//
+// Implementation note: This is carefully structured to be pointer-free because
+// tracebacks happen in places that disallow write barriers (e.g., signals).
+// Even if this is stack-allocated, its pointer-receiver methods don't know that
+// their receiver is on the stack, so they still emit write barriers. Here we
+// address that by carefully avoiding any pointers in this type. Another
+// approach would be to split this into a mutable part that's passed by pointer
+// but contains no pointers itself and an immutable part that's passed and
+// returned by value and can contain pointers. We could potentially hide that
+// we're doing that in trivial methods that are inlined into the caller that has
+// the stack allocation, but that's fragile.
+type unwinder struct {
+ // frame is the current physical stack frame, or all 0s if
+ // there is no frame.
+ frame stkframe
+
+ // g is the G who's stack is being unwound. If the
+ // unwindJumpStack flag is set and the unwinder jumps stacks,
+ // this will be different from the initial G.
+ g guintptr
+
+ // cgoCtxt is the index into g.cgoCtxt of the next frame on the cgo stack.
+ // The cgo stack is unwound in tandem with the Go stack as we find marker frames.
+ cgoCtxt int
+
+ // calleeFuncID is the function ID of the caller of the current
+ // frame.
+ calleeFuncID abi.FuncID
+
+ // flags are the flags to this unwind. Some of these are updated as we
+ // unwind (see the flags documentation).
+ flags unwindFlags
+
+ // cache is used to cache pcvalue lookups.
+ cache pcvalueCache
+}
+
+// init initializes u to start unwinding gp's stack and positions the
+// iterator on gp's innermost frame. gp must not be the current G.
+//
+// A single unwinder can be reused for multiple unwinds.
+func (u *unwinder) init(gp *g, flags unwindFlags) {
+ // Implementation note: This starts the iterator on the first frame and we
+ // provide a "valid" method. Alternatively, this could start in a "before
+ // the first frame" state and "next" could return whether it was able to
+ // move to the next frame, but that's both more awkward to use in a "for"
+ // loop and is harder to implement because we have to do things differently
+ // for the first frame.
+ u.initAt(^uintptr(0), ^uintptr(0), ^uintptr(0), gp, flags)
+}
+
+func (u *unwinder) initAt(pc0, sp0, lr0 uintptr, gp *g, flags unwindFlags) {
+ // Don't call this "g"; it's too easy get "g" and "gp" confused.
+ if ourg := getg(); ourg == gp && ourg == ourg.m.curg {
+ // The starting sp has been passed in as a uintptr, and the caller may
+ // have other uintptr-typed stack references as well.
+ // If during one of the calls that got us here or during one of the
+ // callbacks below the stack must be grown, all these uintptr references
+ // to the stack will not be updated, and traceback will continue
+ // to inspect the old stack memory, which may no longer be valid.
+ // Even if all the variables were updated correctly, it is not clear that
+ // we want to expose a traceback that begins on one stack and ends
+ // on another stack. That could confuse callers quite a bit.
+ // Instead, we require that initAt and any other function that
+ // accepts an sp for the current goroutine (typically obtained by
+ // calling getcallersp) must not run on that goroutine's stack but
+ // instead on the g0 stack.
+ throw("cannot trace user goroutine on its own stack")
+ }
+
+ if pc0 == ^uintptr(0) && sp0 == ^uintptr(0) { // Signal to fetch saved values from gp.
+ if gp.syscallsp != 0 {
+ pc0 = gp.syscallpc
+ sp0 = gp.syscallsp
+ if usesLR {
+ lr0 = 0
+ }
+ } else {
+ pc0 = gp.sched.pc
+ sp0 = gp.sched.sp
+ if usesLR {
+ lr0 = gp.sched.lr
+ }
+ }
+ }
+
+ var frame stkframe
+ frame.pc = pc0
+ frame.sp = sp0
+ if usesLR {
+ frame.lr = lr0
+ }
+
+ // If the PC is zero, it's likely a nil function call.
+ // Start in the caller's frame.
+ if frame.pc == 0 {
+ if usesLR {
+ frame.pc = *(*uintptr)(unsafe.Pointer(frame.sp))
+ frame.lr = 0
+ } else {
+ frame.pc = uintptr(*(*uintptr)(unsafe.Pointer(frame.sp)))
+ frame.sp += goarch.PtrSize
+ }
+ }
+
+ // runtime/internal/atomic functions call into kernel helpers on
+ // arm < 7. See runtime/internal/atomic/sys_linux_arm.s.
+ //
+ // Start in the caller's frame.
+ if GOARCH == "arm" && goarm < 7 && GOOS == "linux" && frame.pc&0xffff0000 == 0xffff0000 {
+ // Note that the calls are simple BL without pushing the return
+ // address, so we use LR directly.
+ //
+ // The kernel helpers are frameless leaf functions, so SP and
+ // LR are not touched.
+ frame.pc = frame.lr
+ frame.lr = 0
+ }
+
+ f := findfunc(frame.pc)
+ if !f.valid() {
+ if flags&unwindSilentErrors == 0 {
+ print("runtime: g ", gp.goid, ": unknown pc ", hex(frame.pc), "\n")
+ tracebackHexdump(gp.stack, &frame, 0)
+ }
+ if flags&(unwindPrintErrors|unwindSilentErrors) == 0 {
+ throw("unknown pc")
+ }
+ *u = unwinder{}
+ return
+ }
+ frame.fn = f
+
+ // Populate the unwinder.
+ *u = unwinder{
+ frame: frame,
+ g: gp.guintptr(),
+ cgoCtxt: len(gp.cgoCtxt) - 1,
+ calleeFuncID: abi.FuncIDNormal,
+ flags: flags,
+ }
+
+ isSyscall := frame.pc == pc0 && frame.sp == sp0 && pc0 == gp.syscallpc && sp0 == gp.syscallsp
+ u.resolveInternal(true, isSyscall)
+}
+
+func (u *unwinder) valid() bool {
+ return u.frame.pc != 0
+}
+
+// resolveInternal fills in u.frame based on u.frame.fn, pc, and sp.
+//
+// innermost indicates that this is the first resolve on this stack. If
+// innermost is set, isSyscall indicates that the PC/SP was retrieved from
+// gp.syscall*; this is otherwise ignored.
+//
+// On entry, u.frame contains:
+// - fn is the running function.
+// - pc is the PC in the running function.
+// - sp is the stack pointer at that program counter.
+// - For the innermost frame on LR machines, lr is the program counter that called fn.
+//
+// On return, u.frame contains:
+// - fp is the stack pointer of the caller.
+// - lr is the program counter that called fn.
+// - varp, argp, and continpc are populated for the current frame.
+//
+// If fn is a stack-jumping function, resolveInternal can change the entire
+// frame state to follow that stack jump.
+//
+// This is internal to unwinder.
+func (u *unwinder) resolveInternal(innermost, isSyscall bool) {
+ frame := &u.frame
+ gp := u.g.ptr()
+
+ f := frame.fn
+ if f.pcsp == 0 {
+ // No frame information, must be external function, like race support.
+ // See golang.org/issue/13568.
+ u.finishInternal()
+ return
+ }
+
+ // Compute function info flags.
+ flag := f.flag
+ if f.funcID == abi.FuncID_cgocallback {
+ // cgocallback does write SP to switch from the g0 to the curg stack,
+ // but it carefully arranges that during the transition BOTH stacks
+ // have cgocallback frame valid for unwinding through.
+ // So we don't need to exclude it with the other SP-writing functions.
+ flag &^= abi.FuncFlagSPWrite
+ }
+ if isSyscall {
+ // Some Syscall functions write to SP, but they do so only after
+ // saving the entry PC/SP using entersyscall.
+ // Since we are using the entry PC/SP, the later SP write doesn't matter.
+ flag &^= abi.FuncFlagSPWrite
+ }
+
+ // Found an actual function.
+ // Derive frame pointer.
+ if frame.fp == 0 {
+ // Jump over system stack transitions. If we're on g0 and there's a user
+ // goroutine, try to jump. Otherwise this is a regular call.
+ // We also defensively check that this won't switch M's on us,
+ // which could happen at critical points in the scheduler.
+ // This ensures gp.m doesn't change from a stack jump.
+ if u.flags&unwindJumpStack != 0 && gp == gp.m.g0 && gp.m.curg != nil && gp.m.curg.m == gp.m {
+ switch f.funcID {
+ case abi.FuncID_morestack:
+ // morestack does not return normally -- newstack()
+ // gogo's to curg.sched. Match that.
+ // This keeps morestack() from showing up in the backtrace,
+ // but that makes some sense since it'll never be returned
+ // to.
+ gp = gp.m.curg
+ u.g.set(gp)
+ frame.pc = gp.sched.pc
+ frame.fn = findfunc(frame.pc)
+ f = frame.fn
+ flag = f.flag
+ frame.lr = gp.sched.lr
+ frame.sp = gp.sched.sp
+ u.cgoCtxt = len(gp.cgoCtxt) - 1
+ case abi.FuncID_systemstack:
+ // systemstack returns normally, so just follow the
+ // stack transition.
+ if usesLR && funcspdelta(f, frame.pc, &u.cache) == 0 {
+ // We're at the function prologue and the stack
+ // switch hasn't happened, or epilogue where we're
+ // about to return. Just unwind normally.
+ // Do this only on LR machines because on x86
+ // systemstack doesn't have an SP delta (the CALL
+ // instruction opens the frame), therefore no way
+ // to check.
+ flag &^= abi.FuncFlagSPWrite
+ break
+ }
+ gp = gp.m.curg
+ u.g.set(gp)
+ frame.sp = gp.sched.sp
+ u.cgoCtxt = len(gp.cgoCtxt) - 1
+ flag &^= abi.FuncFlagSPWrite
+ }
+ }
+ frame.fp = frame.sp + uintptr(funcspdelta(f, frame.pc, &u.cache))
+ if !usesLR {
+ // On x86, call instruction pushes return PC before entering new function.
+ frame.fp += goarch.PtrSize
+ }
+ }
+
+ // Derive link register.
+ if flag&abi.FuncFlagTopFrame != 0 {
+ // This function marks the top of the stack. Stop the traceback.
+ frame.lr = 0
+ } else if flag&abi.FuncFlagSPWrite != 0 && (!innermost || u.flags&(unwindPrintErrors|unwindSilentErrors) != 0) {
+ // The function we are in does a write to SP that we don't know
+ // how to encode in the spdelta table. Examples include context
+ // switch routines like runtime.gogo but also any code that switches
+ // to the g0 stack to run host C code.
+ // We can't reliably unwind the SP (we might not even be on
+ // the stack we think we are), so stop the traceback here.
+ //
+ // The one exception (encoded in the complex condition above) is that
+ // we assume if we're doing a precise traceback, and this is the
+ // innermost frame, that the SPWRITE function voluntarily preempted itself on entry
+ // during the stack growth check. In that case, the function has
+ // not yet had a chance to do any writes to SP and is safe to unwind.
+ // isAsyncSafePoint does not allow assembly functions to be async preempted,
+ // and preemptPark double-checks that SPWRITE functions are not async preempted.
+ // So for GC stack traversal, we can safely ignore SPWRITE for the innermost frame,
+ // but farther up the stack we'd better not find any.
+ // This is somewhat imprecise because we're just guessing that we're in the stack
+ // growth check. It would be better if SPWRITE were encoded in the spdelta
+ // table so we would know for sure that we were still in safe code.
+ //
+ // uSE uPE inn | action
+ // T _ _ | frame.lr = 0
+ // F T F | frame.lr = 0; print
+ // F T T | frame.lr = 0
+ // F F F | print; panic
+ // F F T | ignore SPWrite
+ if u.flags&unwindSilentErrors == 0 && !innermost {
+ println("traceback: unexpected SPWRITE function", funcname(f))
+ if u.flags&unwindPrintErrors == 0 {
+ throw("traceback")
+ }
+ }
+ frame.lr = 0
+ } else {
+ var lrPtr uintptr
+ if usesLR {
+ if innermost && frame.sp < frame.fp || frame.lr == 0 {
+ lrPtr = frame.sp
+ frame.lr = *(*uintptr)(unsafe.Pointer(lrPtr))
+ }
+ } else {
+ if frame.lr == 0 {
+ lrPtr = frame.fp - goarch.PtrSize
+ frame.lr = *(*uintptr)(unsafe.Pointer(lrPtr))
+ }
+ }
+ }
+
+ frame.varp = frame.fp
+ if !usesLR {
+ // On x86, call instruction pushes return PC before entering new function.
+ frame.varp -= goarch.PtrSize
+ }
+
+ // For architectures with frame pointers, if there's
+ // a frame, then there's a saved frame pointer here.
+ //
+ // NOTE: This code is not as general as it looks.
+ // On x86, the ABI is to save the frame pointer word at the
+ // top of the stack frame, so we have to back down over it.
+ // On arm64, the frame pointer should be at the bottom of
+ // the stack (with R29 (aka FP) = RSP), in which case we would
+ // not want to do the subtraction here. But we started out without
+ // any frame pointer, and when we wanted to add it, we didn't
+ // want to break all the assembly doing direct writes to 8(RSP)
+ // to set the first parameter to a called function.
+ // So we decided to write the FP link *below* the stack pointer
+ // (with R29 = RSP - 8 in Go functions).
+ // This is technically ABI-compatible but not standard.
+ // And it happens to end up mimicking the x86 layout.
+ // Other architectures may make different decisions.
+ if frame.varp > frame.sp && framepointer_enabled {
+ frame.varp -= goarch.PtrSize
+ }
+
+ frame.argp = frame.fp + sys.MinFrameSize
+
+ // Determine frame's 'continuation PC', where it can continue.
+ // Normally this is the return address on the stack, but if sigpanic
+ // is immediately below this function on the stack, then the frame
+ // stopped executing due to a trap, and frame.pc is probably not
+ // a safe point for looking up liveness information. In this panicking case,
+ // the function either doesn't return at all (if it has no defers or if the
+ // defers do not recover) or it returns from one of the calls to
+ // deferproc a second time (if the corresponding deferred func recovers).
+ // In the latter case, use a deferreturn call site as the continuation pc.
+ frame.continpc = frame.pc
+ if u.calleeFuncID == abi.FuncID_sigpanic {
+ if frame.fn.deferreturn != 0 {
+ frame.continpc = frame.fn.entry() + uintptr(frame.fn.deferreturn) + 1
+ // Note: this may perhaps keep return variables alive longer than
+ // strictly necessary, as we are using "function has a defer statement"
+ // as a proxy for "function actually deferred something". It seems
+ // to be a minor drawback. (We used to actually look through the
+ // gp._defer for a defer corresponding to this function, but that
+ // is hard to do with defer records on the stack during a stack copy.)
+ // Note: the +1 is to offset the -1 that
+ // stack.go:getStackMap does to back up a return
+ // address make sure the pc is in the CALL instruction.
+ } else {
+ frame.continpc = 0
+ }
+ }
+}
+
+func (u *unwinder) next() {
+ frame := &u.frame
+ f := frame.fn
+ gp := u.g.ptr()
+
+ // Do not unwind past the bottom of the stack.
+ if frame.lr == 0 {
+ u.finishInternal()
+ return
+ }
+ flr := findfunc(frame.lr)
+ if !flr.valid() {
+ // This happens if you get a profiling interrupt at just the wrong time.
+ // In that context it is okay to stop early.
+ // But if no error flags are set, we're doing a garbage collection and must
+ // get everything, so crash loudly.
+ fail := u.flags&(unwindPrintErrors|unwindSilentErrors) == 0
+ doPrint := u.flags&unwindSilentErrors == 0
+ if doPrint && gp.m.incgo && f.funcID == abi.FuncID_sigpanic {
+ // We can inject sigpanic
+ // calls directly into C code,
+ // in which case we'll see a C
+ // return PC. Don't complain.
+ doPrint = false
+ }
+ if fail || doPrint {
+ print("runtime: g ", gp.goid, ": unexpected return pc for ", funcname(f), " called from ", hex(frame.lr), "\n")
+ tracebackHexdump(gp.stack, frame, 0)
+ }
+ if fail {
+ throw("unknown caller pc")
+ }
+ frame.lr = 0
+ u.finishInternal()
+ return
+ }
+
+ if frame.pc == frame.lr && frame.sp == frame.fp {
+ // If the next frame is identical to the current frame, we cannot make progress.
+ print("runtime: traceback stuck. pc=", hex(frame.pc), " sp=", hex(frame.sp), "\n")
+ tracebackHexdump(gp.stack, frame, frame.sp)
+ throw("traceback stuck")
+ }
+
+ injectedCall := f.funcID == abi.FuncID_sigpanic || f.funcID == abi.FuncID_asyncPreempt || f.funcID == abi.FuncID_debugCallV2
+ if injectedCall {
+ u.flags |= unwindTrap
+ } else {
+ u.flags &^= unwindTrap
+ }
+
+ // Unwind to next frame.
+ u.calleeFuncID = f.funcID
+ frame.fn = flr
+ frame.pc = frame.lr
+ frame.lr = 0
+ frame.sp = frame.fp
+ frame.fp = 0
+
+ // On link register architectures, sighandler saves the LR on stack
+ // before faking a call.
+ if usesLR && injectedCall {
+ x := *(*uintptr)(unsafe.Pointer(frame.sp))
+ frame.sp += alignUp(sys.MinFrameSize, sys.StackAlign)
+ f = findfunc(frame.pc)
+ frame.fn = f
+ if !f.valid() {
+ frame.pc = x
+ } else if funcspdelta(f, frame.pc, &u.cache) == 0 {
+ frame.lr = x
+ }
+ }
+
+ u.resolveInternal(false, false)
+}
+
+// finishInternal is an unwinder-internal helper called after the stack has been
+// exhausted. It sets the unwinder to an invalid state and checks that it
+// successfully unwound the entire stack.
+func (u *unwinder) finishInternal() {
+ u.frame.pc = 0
+
+ // Note that panic != nil is okay here: there can be leftover panics,
+ // because the defers on the panic stack do not nest in frame order as
+ // they do on the defer stack. If you have:
+ //
+ // frame 1 defers d1
+ // frame 2 defers d2
+ // frame 3 defers d3
+ // frame 4 panics
+ // frame 4's panic starts running defers
+ // frame 5, running d3, defers d4
+ // frame 5 panics
+ // frame 5's panic starts running defers
+ // frame 6, running d4, garbage collects
+ // frame 6, running d2, garbage collects
+ //
+ // During the execution of d4, the panic stack is d4 -> d3, which
+ // is nested properly, and we'll treat frame 3 as resumable, because we
+ // can find d3. (And in fact frame 3 is resumable. If d4 recovers
+ // and frame 5 continues running, d3, d3 can recover and we'll
+ // resume execution in (returning from) frame 3.)
+ //
+ // During the execution of d2, however, the panic stack is d2 -> d3,
+ // which is inverted. The scan will match d2 to frame 2 but having
+ // d2 on the stack until then means it will not match d3 to frame 3.
+ // This is okay: if we're running d2, then all the defers after d2 have
+ // completed and their corresponding frames are dead. Not finding d3
+ // for frame 3 means we'll set frame 3's continpc == 0, which is correct
+ // (frame 3 is dead). At the end of the walk the panic stack can thus
+ // contain defers (d3 in this case) for dead frames. The inversion here
+ // always indicates a dead frame, and the effect of the inversion on the
+ // scan is to hide those dead frames, so the scan is still okay:
+ // what's left on the panic stack are exactly (and only) the dead frames.
+ //
+ // We require callback != nil here because only when callback != nil
+ // do we know that gentraceback is being called in a "must be correct"
+ // context as opposed to a "best effort" context. The tracebacks with
+ // callbacks only happen when everything is stopped nicely.
+ // At other times, such as when gathering a stack for a profiling signal
+ // or when printing a traceback during a crash, everything may not be
+ // stopped nicely, and the stack walk may not be able to complete.
+ gp := u.g.ptr()
+ if u.flags&(unwindPrintErrors|unwindSilentErrors) == 0 && u.frame.sp != gp.stktopsp {
+ print("runtime: g", gp.goid, ": frame.sp=", hex(u.frame.sp), " top=", hex(gp.stktopsp), "\n")
+ print("\tstack=[", hex(gp.stack.lo), "-", hex(gp.stack.hi), "\n")
+ throw("traceback did not unwind completely")
+ }
+}
+
+// symPC returns the PC that should be used for symbolizing the current frame.
+// Specifically, this is the PC of the last instruction executed in this frame.
+//
+// If this frame did a normal call, then frame.pc is a return PC, so this will
+// return frame.pc-1, which points into the CALL instruction. If the frame was
+// interrupted by a signal (e.g., profiler, segv, etc) then frame.pc is for the
+// trapped instruction, so this returns frame.pc. See issue #34123. Finally,
+// frame.pc can be at function entry when the frame is initialized without
+// actually running code, like in runtime.mstart, in which case this returns
+// frame.pc because that's the best we can do.
+func (u *unwinder) symPC() uintptr {
+ if u.flags&unwindTrap == 0 && u.frame.pc > u.frame.fn.entry() {
+ // Regular call.
+ return u.frame.pc - 1
+ }
+ // Trapping instruction or we're at the function entry point.
+ return u.frame.pc
+}
+
+// cgoCallers populates pcBuf with the cgo callers of the current frame using
+// the registered cgo unwinder. It returns the number of PCs written to pcBuf.
+// If the current frame is not a cgo frame or if there's no registered cgo
+// unwinder, it returns 0.
+func (u *unwinder) cgoCallers(pcBuf []uintptr) int {
+ if cgoTraceback == nil || u.frame.fn.funcID != abi.FuncID_cgocallback || u.cgoCtxt < 0 {
+ // We don't have a cgo unwinder (typical case), or we do but we're not
+ // in a cgo frame or we're out of cgo context.
+ return 0
+ }
+
+ ctxt := u.g.ptr().cgoCtxt[u.cgoCtxt]
+ u.cgoCtxt--
+ cgoContextPCs(ctxt, pcBuf)
+ for i, pc := range pcBuf {
+ if pc == 0 {
+ return i
+ }
+ }
+ return len(pcBuf)
+}
+
+// tracebackPCs populates pcBuf with the return addresses for each frame from u
+// and returns the number of PCs written to pcBuf. The returned PCs correspond
+// to "logical frames" rather than "physical frames"; that is if A is inlined
+// into B, this will still return a PCs for both A and B. This also includes PCs
+// generated by the cgo unwinder, if one is registered.
+//
+// If skip != 0, this skips this many logical frames.
+//
+// Callers should set the unwindSilentErrors flag on u.
+func tracebackPCs(u *unwinder, skip int, pcBuf []uintptr) int {
+ var cgoBuf [32]uintptr
+ n := 0
+ for ; n < len(pcBuf) && u.valid(); u.next() {
+ f := u.frame.fn
+ cgoN := u.cgoCallers(cgoBuf[:])
+
+ // TODO: Why does &u.cache cause u to escape? (Same in traceback2)
+ for iu, uf := newInlineUnwinder(f, u.symPC(), noEscapePtr(&u.cache)); n < len(pcBuf) && uf.valid(); uf = iu.next(uf) {
+ sf := iu.srcFunc(uf)
+ if sf.funcID == abi.FuncIDWrapper && elideWrapperCalling(u.calleeFuncID) {
+ // ignore wrappers
+ } else if skip > 0 {
+ skip--
+ } else {
+ // Callers expect the pc buffer to contain return addresses
+ // and do the -1 themselves, so we add 1 to the call PC to
+ // create a return PC.
+ pcBuf[n] = uf.pc + 1
+ n++
+ }
+ u.calleeFuncID = sf.funcID
+ }
+ // Add cgo frames (if we're done skipping over the requested number of
+ // Go frames).
+ if skip == 0 {
+ n += copy(pcBuf[n:], cgoBuf[:cgoN])
+ }
+ }
+ return n
+}
+
+// printArgs prints function arguments in traceback.
+func printArgs(f funcInfo, argp unsafe.Pointer, pc uintptr) {
+ // The "instruction" of argument printing is encoded in _FUNCDATA_ArgInfo.
+ // See cmd/compile/internal/ssagen.emitArgInfo for the description of the
+ // encoding.
+ // These constants need to be in sync with the compiler.
+ const (
+ _endSeq = 0xff
+ _startAgg = 0xfe
+ _endAgg = 0xfd
+ _dotdotdot = 0xfc
+ _offsetTooLarge = 0xfb
+ )
+
+ const (
+ limit = 10 // print no more than 10 args/components
+ maxDepth = 5 // no more than 5 layers of nesting
+ maxLen = (maxDepth*3+2)*limit + 1 // max length of _FUNCDATA_ArgInfo (see the compiler side for reasoning)
+ )
+
+ p := (*[maxLen]uint8)(funcdata(f, abi.FUNCDATA_ArgInfo))
+ if p == nil {
+ return
+ }
+
+ liveInfo := funcdata(f, abi.FUNCDATA_ArgLiveInfo)
+ liveIdx := pcdatavalue(f, abi.PCDATA_ArgLiveIndex, pc, nil)
+ startOffset := uint8(0xff) // smallest offset that needs liveness info (slots with a lower offset is always live)
+ if liveInfo != nil {
+ startOffset = *(*uint8)(liveInfo)
+ }
+
+ isLive := func(off, slotIdx uint8) bool {
+ if liveInfo == nil || liveIdx <= 0 {
+ return true // no liveness info, always live
+ }
+ if off < startOffset {
+ return true
+ }
+ bits := *(*uint8)(add(liveInfo, uintptr(liveIdx)+uintptr(slotIdx/8)))
+ return bits&(1<<(slotIdx%8)) != 0
+ }
+
+ print1 := func(off, sz, slotIdx uint8) {
+ x := readUnaligned64(add(argp, uintptr(off)))
+ // mask out irrelevant bits
+ if sz < 8 {
+ shift := 64 - sz*8
+ if goarch.BigEndian {
+ x = x >> shift
+ } else {
+ x = x << shift >> shift
+ }
+ }
+ print(hex(x))
+ if !isLive(off, slotIdx) {
+ print("?")
+ }
+ }
+
+ start := true
+ printcomma := func() {
+ if !start {
+ print(", ")
+ }
+ }
+ pi := 0
+ slotIdx := uint8(0) // register arg spill slot index
+printloop:
+ for {
+ o := p[pi]
+ pi++
+ switch o {
+ case _endSeq:
+ break printloop
+ case _startAgg:
+ printcomma()
+ print("{")
+ start = true
+ continue
+ case _endAgg:
+ print("}")
+ case _dotdotdot:
+ printcomma()
+ print("...")
+ case _offsetTooLarge:
+ printcomma()
+ print("_")
+ default:
+ printcomma()
+ sz := p[pi]
+ pi++
+ print1(o, sz, slotIdx)
+ if o >= startOffset {
+ slotIdx++
+ }
+ }
+ start = false
+ }
+}
+
+// funcNamePiecesForPrint returns the function name for printing to the user.
+// It returns three pieces so it doesn't need an allocation for string
+// concatenation.
+func funcNamePiecesForPrint(name string) (string, string, string) {
+ // Replace the shape name in generic function with "...".
+ i := bytealg.IndexByteString(name, '[')
+ if i < 0 {
+ return name, "", ""
+ }
+ j := len(name) - 1
+ for name[j] != ']' {
+ j--
+ }
+ if j <= i {
+ return name, "", ""
+ }
+ return name[:i], "[...]", name[j+1:]
+}
+
+// funcNameForPrint returns the function name for printing to the user.
+func funcNameForPrint(name string) string {
+ a, b, c := funcNamePiecesForPrint(name)
+ return a + b + c
+}
+
+// printFuncName prints a function name. name is the function name in
+// the binary's func data table.
+func printFuncName(name string) {
+ if name == "runtime.gopanic" {
+ print("panic")
+ return
+ }
+ a, b, c := funcNamePiecesForPrint(name)
+ print(a, b, c)
+}
+
+func printcreatedby(gp *g) {
+ // Show what created goroutine, except main goroutine (goid 1).
+ pc := gp.gopc
+ f := findfunc(pc)
+ if f.valid() && showframe(f.srcFunc(), gp, false, abi.FuncIDNormal) && gp.goid != 1 {
+ printcreatedby1(f, pc, gp.parentGoid)
+ }
+}
+
+func printcreatedby1(f funcInfo, pc uintptr, goid uint64) {
+ print("created by ")
+ printFuncName(funcname(f))
+ if goid != 0 {
+ print(" in goroutine ", goid)
+ }
+ print("\n")
+ tracepc := pc // back up to CALL instruction for funcline.
+ if pc > f.entry() {
+ tracepc -= sys.PCQuantum
+ }
+ file, line := funcline(f, tracepc)
+ print("\t", file, ":", line)
+ if pc > f.entry() {
+ print(" +", hex(pc-f.entry()))
+ }
+ print("\n")
+}
+
+func traceback(pc, sp, lr uintptr, gp *g) {
+ traceback1(pc, sp, lr, gp, 0)
+}
+
+// tracebacktrap is like traceback but expects that the PC and SP were obtained
+// from a trap, not from gp->sched or gp->syscallpc/gp->syscallsp or getcallerpc/getcallersp.
+// Because they are from a trap instead of from a saved pair,
+// the initial PC must not be rewound to the previous instruction.
+// (All the saved pairs record a PC that is a return address, so we
+// rewind it into the CALL instruction.)
+// If gp.m.libcall{g,pc,sp} information is available, it uses that information in preference to
+// the pc/sp/lr passed in.
+func tracebacktrap(pc, sp, lr uintptr, gp *g) {
+ if gp.m.libcallsp != 0 {
+ // We're in C code somewhere, traceback from the saved position.
+ traceback1(gp.m.libcallpc, gp.m.libcallsp, 0, gp.m.libcallg.ptr(), 0)
+ return
+ }
+ traceback1(pc, sp, lr, gp, unwindTrap)
+}
+
+func traceback1(pc, sp, lr uintptr, gp *g, flags unwindFlags) {
+ // If the goroutine is in cgo, and we have a cgo traceback, print that.
+ if iscgo && gp.m != nil && gp.m.ncgo > 0 && gp.syscallsp != 0 && gp.m.cgoCallers != nil && gp.m.cgoCallers[0] != 0 {
+ // Lock cgoCallers so that a signal handler won't
+ // change it, copy the array, reset it, unlock it.
+ // We are locked to the thread and are not running
+ // concurrently with a signal handler.
+ // We just have to stop a signal handler from interrupting
+ // in the middle of our copy.
+ gp.m.cgoCallersUse.Store(1)
+ cgoCallers := *gp.m.cgoCallers
+ gp.m.cgoCallers[0] = 0
+ gp.m.cgoCallersUse.Store(0)
+
+ printCgoTraceback(&cgoCallers)
+ }
+
+ if readgstatus(gp)&^_Gscan == _Gsyscall {
+ // Override registers if blocked in system call.
+ pc = gp.syscallpc
+ sp = gp.syscallsp
+ flags &^= unwindTrap
+ }
+ if gp.m != nil && gp.m.vdsoSP != 0 {
+ // Override registers if running in VDSO. This comes after the
+ // _Gsyscall check to cover VDSO calls after entersyscall.
+ pc = gp.m.vdsoPC
+ sp = gp.m.vdsoSP
+ flags &^= unwindTrap
+ }
+
+ // Print traceback.
+ //
+ // We print the first tracebackInnerFrames frames, and the last
+ // tracebackOuterFrames frames. There are many possible approaches to this.
+ // There are various complications to this:
+ //
+ // - We'd prefer to walk the stack once because in really bad situations
+ // traceback may crash (and we want as much output as possible) or the stack
+ // may be changing.
+ //
+ // - Each physical frame can represent several logical frames, so we might
+ // have to pause in the middle of a physical frame and pick up in the middle
+ // of a physical frame.
+ //
+ // - The cgo symbolizer can expand a cgo PC to more than one logical frame,
+ // and involves juggling state on the C side that we don't manage. Since its
+ // expansion state is managed on the C side, we can't capture the expansion
+ // state part way through, and because the output strings are managed on the
+ // C side, we can't capture the output. Thus, our only choice is to replay a
+ // whole expansion, potentially discarding some of it.
+ //
+ // Rejected approaches:
+ //
+ // - Do two passes where the first pass just counts and the second pass does
+ // all the printing. This is undesirable if the stack is corrupted or changing
+ // because we won't see a partial stack if we panic.
+ //
+ // - Keep a ring buffer of the last N logical frames and use this to print
+ // the bottom frames once we reach the end of the stack. This works, but
+ // requires keeping a surprising amount of state on the stack, and we have
+ // to run the cgo symbolizer twice—once to count frames, and a second to
+ // print them—since we can't retain the strings it returns.
+ //
+ // Instead, we print the outer frames, and if we reach that limit, we clone
+ // the unwinder, count the remaining frames, and then skip forward and
+ // finish printing from the clone. This makes two passes over the outer part
+ // of the stack, but the single pass over the inner part ensures that's
+ // printed immediately and not revisited. It keeps minimal state on the
+ // stack. And through a combination of skip counts and limits, we can do all
+ // of the steps we need with a single traceback printer implementation.
+ //
+ // We could be more lax about exactly how many frames we print, for example
+ // always stopping and resuming on physical frame boundaries, or at least
+ // cgo expansion boundaries. It's not clear that's much simpler.
+ flags |= unwindPrintErrors
+ var u unwinder
+ tracebackWithRuntime := func(showRuntime bool) int {
+ const maxInt int = 0x7fffffff
+ u.initAt(pc, sp, lr, gp, flags)
+ n, lastN := traceback2(&u, showRuntime, 0, tracebackInnerFrames)
+ if n < tracebackInnerFrames {
+ // We printed the whole stack.
+ return n
+ }
+ // Clone the unwinder and figure out how many frames are left. This
+ // count will include any logical frames already printed for u's current
+ // physical frame.
+ u2 := u
+ remaining, _ := traceback2(&u, showRuntime, maxInt, 0)
+ elide := remaining - lastN - tracebackOuterFrames
+ if elide > 0 {
+ print("...", elide, " frames elided...\n")
+ traceback2(&u2, showRuntime, lastN+elide, tracebackOuterFrames)
+ } else if elide <= 0 {
+ // There are tracebackOuterFrames or fewer frames left to print.
+ // Just print the rest of the stack.
+ traceback2(&u2, showRuntime, lastN, tracebackOuterFrames)
+ }
+ return n
+ }
+ // By default, omits runtime frames. If that means we print nothing at all,
+ // repeat forcing all frames printed.
+ if tracebackWithRuntime(false) == 0 {
+ tracebackWithRuntime(true)
+ }
+ printcreatedby(gp)
+
+ if gp.ancestors == nil {
+ return
+ }
+ for _, ancestor := range *gp.ancestors {
+ printAncestorTraceback(ancestor)
+ }
+}
+
+// traceback2 prints a stack trace starting at u. It skips the first "skip"
+// logical frames, after which it prints at most "max" logical frames. It
+// returns n, which is the number of logical frames skipped and printed, and
+// lastN, which is the number of logical frames skipped or printed just in the
+// physical frame that u references.
+func traceback2(u *unwinder, showRuntime bool, skip, max int) (n, lastN int) {
+ // commitFrame commits to a logical frame and returns whether this frame
+ // should be printed and whether iteration should stop.
+ commitFrame := func() (pr, stop bool) {
+ if skip == 0 && max == 0 {
+ // Stop
+ return false, true
+ }
+ n++
+ lastN++
+ if skip > 0 {
+ // Skip
+ skip--
+ return false, false
+ }
+ // Print
+ max--
+ return true, false
+ }
+
+ gp := u.g.ptr()
+ level, _, _ := gotraceback()
+ var cgoBuf [32]uintptr
+ for ; u.valid(); u.next() {
+ lastN = 0
+ f := u.frame.fn
+ for iu, uf := newInlineUnwinder(f, u.symPC(), noEscapePtr(&u.cache)); uf.valid(); uf = iu.next(uf) {
+ sf := iu.srcFunc(uf)
+ callee := u.calleeFuncID
+ u.calleeFuncID = sf.funcID
+ if !(showRuntime || showframe(sf, gp, n == 0, callee)) {
+ continue
+ }
+
+ if pr, stop := commitFrame(); stop {
+ return
+ } else if !pr {
+ continue
+ }
+
+ name := sf.name()
+ file, line := iu.fileLine(uf)
+ // Print during crash.
+ // main(0x1, 0x2, 0x3)
+ // /home/rsc/go/src/runtime/x.go:23 +0xf
+ //
+ printFuncName(name)
+ print("(")
+ if iu.isInlined(uf) {
+ print("...")
+ } else {
+ argp := unsafe.Pointer(u.frame.argp)
+ printArgs(f, argp, u.symPC())
+ }
+ print(")\n")
+ print("\t", file, ":", line)
+ if !iu.isInlined(uf) {
+ if u.frame.pc > f.entry() {
+ print(" +", hex(u.frame.pc-f.entry()))
+ }
+ if gp.m != nil && gp.m.throwing >= throwTypeRuntime && gp == gp.m.curg || level >= 2 {
+ print(" fp=", hex(u.frame.fp), " sp=", hex(u.frame.sp), " pc=", hex(u.frame.pc))
+ }
+ }
+ print("\n")
+ }
+
+ // Print cgo frames.
+ if cgoN := u.cgoCallers(cgoBuf[:]); cgoN > 0 {
+ var arg cgoSymbolizerArg
+ anySymbolized := false
+ stop := false
+ for _, pc := range cgoBuf[:cgoN] {
+ if cgoSymbolizer == nil {
+ if pr, stop := commitFrame(); stop {
+ break
+ } else if pr {
+ print("non-Go function at pc=", hex(pc), "\n")
+ }
+ } else {
+ stop = printOneCgoTraceback(pc, commitFrame, &arg)
+ anySymbolized = true
+ if stop {
+ break
+ }
+ }
+ }
+ if anySymbolized {
+ // Free symbolization state.
+ arg.pc = 0
+ callCgoSymbolizer(&arg)
+ }
+ if stop {
+ return
+ }
+ }
+ }
+ return n, 0
+}
+
+// printAncestorTraceback prints the traceback of the given ancestor.
+// TODO: Unify this with gentraceback and CallersFrames.
+func printAncestorTraceback(ancestor ancestorInfo) {
+ print("[originating from goroutine ", ancestor.goid, "]:\n")
+ for fidx, pc := range ancestor.pcs {
+ f := findfunc(pc) // f previously validated
+ if showfuncinfo(f.srcFunc(), fidx == 0, abi.FuncIDNormal) {
+ printAncestorTracebackFuncInfo(f, pc)
+ }
+ }
+ if len(ancestor.pcs) == tracebackInnerFrames {
+ print("...additional frames elided...\n")
+ }
+ // Show what created goroutine, except main goroutine (goid 1).
+ f := findfunc(ancestor.gopc)
+ if f.valid() && showfuncinfo(f.srcFunc(), false, abi.FuncIDNormal) && ancestor.goid != 1 {
+ // In ancestor mode, we'll already print the goroutine ancestor.
+ // Pass 0 for the goid parameter so we don't print it again.
+ printcreatedby1(f, ancestor.gopc, 0)
+ }
+}
+
+// printAncestorTracebackFuncInfo prints the given function info at a given pc
+// within an ancestor traceback. The precision of this info is reduced
+// due to only have access to the pcs at the time of the caller
+// goroutine being created.
+func printAncestorTracebackFuncInfo(f funcInfo, pc uintptr) {
+ u, uf := newInlineUnwinder(f, pc, nil)
+ file, line := u.fileLine(uf)
+ printFuncName(u.srcFunc(uf).name())
+ print("(...)\n")
+ print("\t", file, ":", line)
+ if pc > f.entry() {
+ print(" +", hex(pc-f.entry()))
+ }
+ print("\n")
+}
+
+func callers(skip int, pcbuf []uintptr) int {
+ sp := getcallersp()
+ pc := getcallerpc()
+ gp := getg()
+ var n int
+ systemstack(func() {
+ var u unwinder
+ u.initAt(pc, sp, 0, gp, unwindSilentErrors)
+ n = tracebackPCs(&u, skip, pcbuf)
+ })
+ return n
+}
+
+func gcallers(gp *g, skip int, pcbuf []uintptr) int {
+ var u unwinder
+ u.init(gp, unwindSilentErrors)
+ return tracebackPCs(&u, skip, pcbuf)
+}
+
+// showframe reports whether the frame with the given characteristics should
+// be printed during a traceback.
+func showframe(sf srcFunc, gp *g, firstFrame bool, calleeID abi.FuncID) bool {
+ mp := getg().m
+ if mp.throwing >= throwTypeRuntime && gp != nil && (gp == mp.curg || gp == mp.caughtsig.ptr()) {
+ return true
+ }
+ return showfuncinfo(sf, firstFrame, calleeID)
+}
+
+// showfuncinfo reports whether a function with the given characteristics should
+// be printed during a traceback.
+func showfuncinfo(sf srcFunc, firstFrame bool, calleeID abi.FuncID) bool {
+ level, _, _ := gotraceback()
+ if level > 1 {
+ // Show all frames.
+ return true
+ }
+
+ if sf.funcID == abi.FuncIDWrapper && elideWrapperCalling(calleeID) {
+ return false
+ }
+
+ name := sf.name()
+
+ // Special case: always show runtime.gopanic frame
+ // in the middle of a stack trace, so that we can
+ // see the boundary between ordinary code and
+ // panic-induced deferred code.
+ // See golang.org/issue/5832.
+ if name == "runtime.gopanic" && !firstFrame {
+ return true
+ }
+
+ return bytealg.IndexByteString(name, '.') >= 0 && (!hasPrefix(name, "runtime.") || isExportedRuntime(name))
+}
+
+// isExportedRuntime reports whether name is an exported runtime function.
+// It is only for runtime functions, so ASCII A-Z is fine.
+// TODO: this handles exported functions but not exported methods.
+func isExportedRuntime(name string) bool {
+ const n = len("runtime.")
+ return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z'
+}
+
+// elideWrapperCalling reports whether a wrapper function that called
+// function id should be elided from stack traces.
+func elideWrapperCalling(id abi.FuncID) bool {
+ // If the wrapper called a panic function instead of the
+ // wrapped function, we want to include it in stacks.
+ return !(id == abi.FuncID_gopanic || id == abi.FuncID_sigpanic || id == abi.FuncID_panicwrap)
+}
+
+var gStatusStrings = [...]string{
+ _Gidle: "idle",
+ _Grunnable: "runnable",
+ _Grunning: "running",
+ _Gsyscall: "syscall",
+ _Gwaiting: "waiting",
+ _Gdead: "dead",
+ _Gcopystack: "copystack",
+ _Gpreempted: "preempted",
+}
+
+func goroutineheader(gp *g) {
+ gpstatus := readgstatus(gp)
+
+ isScan := gpstatus&_Gscan != 0
+ gpstatus &^= _Gscan // drop the scan bit
+
+ // Basic string status
+ var status string
+ if 0 <= gpstatus && gpstatus < uint32(len(gStatusStrings)) {
+ status = gStatusStrings[gpstatus]
+ } else {
+ status = "???"
+ }
+
+ // Override.
+ if gpstatus == _Gwaiting && gp.waitreason != waitReasonZero {
+ status = gp.waitreason.String()
+ }
+
+ // approx time the G is blocked, in minutes
+ var waitfor int64
+ if (gpstatus == _Gwaiting || gpstatus == _Gsyscall) && gp.waitsince != 0 {
+ waitfor = (nanotime() - gp.waitsince) / 60e9
+ }
+ print("goroutine ", gp.goid, " [", status)
+ if isScan {
+ print(" (scan)")
+ }
+ if waitfor >= 1 {
+ print(", ", waitfor, " minutes")
+ }
+ if gp.lockedm != 0 {
+ print(", locked to thread")
+ }
+ print("]:\n")
+}
+
+func tracebackothers(me *g) {
+ level, _, _ := gotraceback()
+
+ // Show the current goroutine first, if we haven't already.
+ curgp := getg().m.curg
+ if curgp != nil && curgp != me {
+ print("\n")
+ goroutineheader(curgp)
+ traceback(^uintptr(0), ^uintptr(0), 0, curgp)
+ }
+
+ // We can't call locking forEachG here because this may be during fatal
+ // throw/panic, where locking could be out-of-order or a direct
+ // deadlock.
+ //
+ // Instead, use forEachGRace, which requires no locking. We don't lock
+ // against concurrent creation of new Gs, but even with allglock we may
+ // miss Gs created after this loop.
+ forEachGRace(func(gp *g) {
+ if gp == me || gp == curgp || readgstatus(gp) == _Gdead || isSystemGoroutine(gp, false) && level < 2 {
+ return
+ }
+ print("\n")
+ goroutineheader(gp)
+ // Note: gp.m == getg().m occurs when tracebackothers is called
+ // from a signal handler initiated during a systemstack call.
+ // The original G is still in the running state, and we want to
+ // print its stack.
+ if gp.m != getg().m && readgstatus(gp)&^_Gscan == _Grunning {
+ print("\tgoroutine running on other thread; stack unavailable\n")
+ printcreatedby(gp)
+ } else {
+ traceback(^uintptr(0), ^uintptr(0), 0, gp)
+ }
+ })
+}
+
+// tracebackHexdump hexdumps part of stk around frame.sp and frame.fp
+// for debugging purposes. If the address bad is included in the
+// hexdumped range, it will mark it as well.
+func tracebackHexdump(stk stack, frame *stkframe, bad uintptr) {
+ const expand = 32 * goarch.PtrSize
+ const maxExpand = 256 * goarch.PtrSize
+ // Start around frame.sp.
+ lo, hi := frame.sp, frame.sp
+ // Expand to include frame.fp.
+ if frame.fp != 0 && frame.fp < lo {
+ lo = frame.fp
+ }
+ if frame.fp != 0 && frame.fp > hi {
+ hi = frame.fp
+ }
+ // Expand a bit more.
+ lo, hi = lo-expand, hi+expand
+ // But don't go too far from frame.sp.
+ if lo < frame.sp-maxExpand {
+ lo = frame.sp - maxExpand
+ }
+ if hi > frame.sp+maxExpand {
+ hi = frame.sp + maxExpand
+ }
+ // And don't go outside the stack bounds.
+ if lo < stk.lo {
+ lo = stk.lo
+ }
+ if hi > stk.hi {
+ hi = stk.hi
+ }
+
+ // Print the hex dump.
+ print("stack: frame={sp:", hex(frame.sp), ", fp:", hex(frame.fp), "} stack=[", hex(stk.lo), ",", hex(stk.hi), ")\n")
+ hexdumpWords(lo, hi, func(p uintptr) byte {
+ switch p {
+ case frame.fp:
+ return '>'
+ case frame.sp:
+ return '<'
+ case bad:
+ return '!'
+ }
+ return 0
+ })
+}
+
+// isSystemGoroutine reports whether the goroutine g must be omitted
+// in stack dumps and deadlock detector. This is any goroutine that
+// starts at a runtime.* entry point, except for runtime.main,
+// runtime.handleAsyncEvent (wasm only) and sometimes runtime.runfinq.
+//
+// If fixed is true, any goroutine that can vary between user and
+// system (that is, the finalizer goroutine) is considered a user
+// goroutine.
+func isSystemGoroutine(gp *g, fixed bool) bool {
+ // Keep this in sync with internal/trace.IsSystemGoroutine.
+ f := findfunc(gp.startpc)
+ if !f.valid() {
+ return false
+ }
+ if f.funcID == abi.FuncID_runtime_main || f.funcID == abi.FuncID_handleAsyncEvent {
+ return false
+ }
+ if f.funcID == abi.FuncID_runfinq {
+ // We include the finalizer goroutine if it's calling
+ // back into user code.
+ if fixed {
+ // This goroutine can vary. In fixed mode,
+ // always consider it a user goroutine.
+ return false
+ }
+ return fingStatus.Load()&fingRunningFinalizer == 0
+ }
+ return hasPrefix(funcname(f), "runtime.")
+}
+
+// SetCgoTraceback records three C functions to use to gather
+// traceback information from C code and to convert that traceback
+// information into symbolic information. These are used when printing
+// stack traces for a program that uses cgo.
+//
+// The traceback and context functions may be called from a signal
+// handler, and must therefore use only async-signal safe functions.
+// The symbolizer function may be called while the program is
+// crashing, and so must be cautious about using memory. None of the
+// functions may call back into Go.
+//
+// The context function will be called with a single argument, a
+// pointer to a struct:
+//
+// struct {
+// Context uintptr
+// }
+//
+// In C syntax, this struct will be
+//
+// struct {
+// uintptr_t Context;
+// };
+//
+// If the Context field is 0, the context function is being called to
+// record the current traceback context. It should record in the
+// Context field whatever information is needed about the current
+// point of execution to later produce a stack trace, probably the
+// stack pointer and PC. In this case the context function will be
+// called from C code.
+//
+// If the Context field is not 0, then it is a value returned by a
+// previous call to the context function. This case is called when the
+// context is no longer needed; that is, when the Go code is returning
+// to its C code caller. This permits the context function to release
+// any associated resources.
+//
+// While it would be correct for the context function to record a
+// complete a stack trace whenever it is called, and simply copy that
+// out in the traceback function, in a typical program the context
+// function will be called many times without ever recording a
+// traceback for that context. Recording a complete stack trace in a
+// call to the context function is likely to be inefficient.
+//
+// The traceback function will be called with a single argument, a
+// pointer to a struct:
+//
+// struct {
+// Context uintptr
+// SigContext uintptr
+// Buf *uintptr
+// Max uintptr
+// }
+//
+// In C syntax, this struct will be
+//
+// struct {
+// uintptr_t Context;
+// uintptr_t SigContext;
+// uintptr_t* Buf;
+// uintptr_t Max;
+// };
+//
+// The Context field will be zero to gather a traceback from the
+// current program execution point. In this case, the traceback
+// function will be called from C code.
+//
+// Otherwise Context will be a value previously returned by a call to
+// the context function. The traceback function should gather a stack
+// trace from that saved point in the program execution. The traceback
+// function may be called from an execution thread other than the one
+// that recorded the context, but only when the context is known to be
+// valid and unchanging. The traceback function may also be called
+// deeper in the call stack on the same thread that recorded the
+// context. The traceback function may be called multiple times with
+// the same Context value; it will usually be appropriate to cache the
+// result, if possible, the first time this is called for a specific
+// context value.
+//
+// If the traceback function is called from a signal handler on a Unix
+// system, SigContext will be the signal context argument passed to
+// the signal handler (a C ucontext_t* cast to uintptr_t). This may be
+// used to start tracing at the point where the signal occurred. If
+// the traceback function is not called from a signal handler,
+// SigContext will be zero.
+//
+// Buf is where the traceback information should be stored. It should
+// be PC values, such that Buf[0] is the PC of the caller, Buf[1] is
+// the PC of that function's caller, and so on. Max is the maximum
+// number of entries to store. The function should store a zero to
+// indicate the top of the stack, or that the caller is on a different
+// stack, presumably a Go stack.
+//
+// Unlike runtime.Callers, the PC values returned should, when passed
+// to the symbolizer function, return the file/line of the call
+// instruction. No additional subtraction is required or appropriate.
+//
+// On all platforms, the traceback function is invoked when a call from
+// Go to C to Go requests a stack trace. On linux/amd64, linux/ppc64le,
+// linux/arm64, and freebsd/amd64, the traceback function is also invoked
+// when a signal is received by a thread that is executing a cgo call.
+// The traceback function should not make assumptions about when it is
+// called, as future versions of Go may make additional calls.
+//
+// The symbolizer function will be called with a single argument, a
+// pointer to a struct:
+//
+// struct {
+// PC uintptr // program counter to fetch information for
+// File *byte // file name (NUL terminated)
+// Lineno uintptr // line number
+// Func *byte // function name (NUL terminated)
+// Entry uintptr // function entry point
+// More uintptr // set non-zero if more info for this PC
+// Data uintptr // unused by runtime, available for function
+// }
+//
+// In C syntax, this struct will be
+//
+// struct {
+// uintptr_t PC;
+// char* File;
+// uintptr_t Lineno;
+// char* Func;
+// uintptr_t Entry;
+// uintptr_t More;
+// uintptr_t Data;
+// };
+//
+// The PC field will be a value returned by a call to the traceback
+// function.
+//
+// The first time the function is called for a particular traceback,
+// all the fields except PC will be 0. The function should fill in the
+// other fields if possible, setting them to 0/nil if the information
+// is not available. The Data field may be used to store any useful
+// information across calls. The More field should be set to non-zero
+// if there is more information for this PC, zero otherwise. If More
+// is set non-zero, the function will be called again with the same
+// PC, and may return different information (this is intended for use
+// with inlined functions). If More is zero, the function will be
+// called with the next PC value in the traceback. When the traceback
+// is complete, the function will be called once more with PC set to
+// zero; this may be used to free any information. Each call will
+// leave the fields of the struct set to the same values they had upon
+// return, except for the PC field when the More field is zero. The
+// function must not keep a copy of the struct pointer between calls.
+//
+// When calling SetCgoTraceback, the version argument is the version
+// number of the structs that the functions expect to receive.
+// Currently this must be zero.
+//
+// The symbolizer function may be nil, in which case the results of
+// the traceback function will be displayed as numbers. If the
+// traceback function is nil, the symbolizer function will never be
+// called. The context function may be nil, in which case the
+// traceback function will only be called with the context field set
+// to zero. If the context function is nil, then calls from Go to C
+// to Go will not show a traceback for the C portion of the call stack.
+//
+// SetCgoTraceback should be called only once, ideally from an init function.
+func SetCgoTraceback(version int, traceback, context, symbolizer unsafe.Pointer) {
+ if version != 0 {
+ panic("unsupported version")
+ }
+
+ if cgoTraceback != nil && cgoTraceback != traceback ||
+ cgoContext != nil && cgoContext != context ||
+ cgoSymbolizer != nil && cgoSymbolizer != symbolizer {
+ panic("call SetCgoTraceback only once")
+ }
+
+ cgoTraceback = traceback
+ cgoContext = context
+ cgoSymbolizer = symbolizer
+
+ // The context function is called when a C function calls a Go
+ // function. As such it is only called by C code in runtime/cgo.
+ if _cgo_set_context_function != nil {
+ cgocall(_cgo_set_context_function, context)
+ }
+}
+
+var cgoTraceback unsafe.Pointer
+var cgoContext unsafe.Pointer
+var cgoSymbolizer unsafe.Pointer
+
+// cgoTracebackArg is the type passed to cgoTraceback.
+type cgoTracebackArg struct {
+ context uintptr
+ sigContext uintptr
+ buf *uintptr
+ max uintptr
+}
+
+// cgoContextArg is the type passed to the context function.
+type cgoContextArg struct {
+ context uintptr
+}
+
+// cgoSymbolizerArg is the type passed to cgoSymbolizer.
+type cgoSymbolizerArg struct {
+ pc uintptr
+ file *byte
+ lineno uintptr
+ funcName *byte
+ entry uintptr
+ more uintptr
+ data uintptr
+}
+
+// printCgoTraceback prints a traceback of callers.
+func printCgoTraceback(callers *cgoCallers) {
+ if cgoSymbolizer == nil {
+ for _, c := range callers {
+ if c == 0 {
+ break
+ }
+ print("non-Go function at pc=", hex(c), "\n")
+ }
+ return
+ }
+
+ commitFrame := func() (pr, stop bool) { return true, false }
+ var arg cgoSymbolizerArg
+ for _, c := range callers {
+ if c == 0 {
+ break
+ }
+ printOneCgoTraceback(c, commitFrame, &arg)
+ }
+ arg.pc = 0
+ callCgoSymbolizer(&arg)
+}
+
+// printOneCgoTraceback prints the traceback of a single cgo caller.
+// This can print more than one line because of inlining.
+// It returns the "stop" result of commitFrame.
+func printOneCgoTraceback(pc uintptr, commitFrame func() (pr, stop bool), arg *cgoSymbolizerArg) bool {
+ arg.pc = pc
+ for {
+ if pr, stop := commitFrame(); stop {
+ return true
+ } else if !pr {
+ continue
+ }
+
+ callCgoSymbolizer(arg)
+ if arg.funcName != nil {
+ // Note that we don't print any argument
+ // information here, not even parentheses.
+ // The symbolizer must add that if appropriate.
+ println(gostringnocopy(arg.funcName))
+ } else {
+ println("non-Go function")
+ }
+ print("\t")
+ if arg.file != nil {
+ print(gostringnocopy(arg.file), ":", arg.lineno, " ")
+ }
+ print("pc=", hex(pc), "\n")
+ if arg.more == 0 {
+ return false
+ }
+ }
+}
+
+// callCgoSymbolizer calls the cgoSymbolizer function.
+func callCgoSymbolizer(arg *cgoSymbolizerArg) {
+ call := cgocall
+ if panicking.Load() > 0 || getg().m.curg != getg() {
+ // We do not want to call into the scheduler when panicking
+ // or when on the system stack.
+ call = asmcgocall
+ }
+ if msanenabled {
+ msanwrite(unsafe.Pointer(arg), unsafe.Sizeof(cgoSymbolizerArg{}))
+ }
+ if asanenabled {
+ asanwrite(unsafe.Pointer(arg), unsafe.Sizeof(cgoSymbolizerArg{}))
+ }
+ call(cgoSymbolizer, noescape(unsafe.Pointer(arg)))
+}
+
+// cgoContextPCs gets the PC values from a cgo traceback.
+func cgoContextPCs(ctxt uintptr, buf []uintptr) {
+ if cgoTraceback == nil {
+ return
+ }
+ call := cgocall
+ if panicking.Load() > 0 || getg().m.curg != getg() {
+ // We do not want to call into the scheduler when panicking
+ // or when on the system stack.
+ call = asmcgocall
+ }
+ arg := cgoTracebackArg{
+ context: ctxt,
+ buf: (*uintptr)(noescape(unsafe.Pointer(&buf[0]))),
+ max: uintptr(len(buf)),
+ }
+ if msanenabled {
+ msanwrite(unsafe.Pointer(&arg), unsafe.Sizeof(arg))
+ }
+ if asanenabled {
+ asanwrite(unsafe.Pointer(&arg), unsafe.Sizeof(arg))
+ }
+ call(cgoTraceback, noescape(unsafe.Pointer(&arg)))
+}
diff --git a/contrib/go/_std_1.21/src/runtime/type.go b/contrib/go/_std_1.21/src/runtime/type.go
new file mode 100644
index 0000000000..1150a53208
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/type.go
@@ -0,0 +1,469 @@
+// Copyright 2009 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.
+
+// Runtime type representation.
+
+package runtime
+
+import (
+ "internal/abi"
+ "unsafe"
+)
+
+type nameOff = abi.NameOff
+type typeOff = abi.TypeOff
+type textOff = abi.TextOff
+
+type _type = abi.Type
+
+// rtype is a wrapper that allows us to define additional methods.
+type rtype struct {
+ *abi.Type // embedding is okay here (unlike reflect) because none of this is public
+}
+
+func (t rtype) string() string {
+ s := t.nameOff(t.Str).Name()
+ if t.TFlag&abi.TFlagExtraStar != 0 {
+ return s[1:]
+ }
+ return s
+}
+
+func (t rtype) uncommon() *uncommontype {
+ return t.Uncommon()
+}
+
+func (t rtype) name() string {
+ if t.TFlag&abi.TFlagNamed == 0 {
+ return ""
+ }
+ s := t.string()
+ i := len(s) - 1
+ sqBrackets := 0
+ for i >= 0 && (s[i] != '.' || sqBrackets != 0) {
+ switch s[i] {
+ case ']':
+ sqBrackets++
+ case '[':
+ sqBrackets--
+ }
+ i--
+ }
+ return s[i+1:]
+}
+
+// pkgpath returns the path of the package where t was defined, if
+// available. This is not the same as the reflect package's PkgPath
+// method, in that it returns the package path for struct and interface
+// types, not just named types.
+func (t rtype) pkgpath() string {
+ if u := t.uncommon(); u != nil {
+ return t.nameOff(u.PkgPath).Name()
+ }
+ switch t.Kind_ & kindMask {
+ case kindStruct:
+ st := (*structtype)(unsafe.Pointer(t.Type))
+ return st.PkgPath.Name()
+ case kindInterface:
+ it := (*interfacetype)(unsafe.Pointer(t.Type))
+ return it.PkgPath.Name()
+ }
+ return ""
+}
+
+// reflectOffs holds type offsets defined at run time by the reflect package.
+//
+// When a type is defined at run time, its *rtype data lives on the heap.
+// There are a wide range of possible addresses the heap may use, that
+// may not be representable as a 32-bit offset. Moreover the GC may
+// one day start moving heap memory, in which case there is no stable
+// offset that can be defined.
+//
+// To provide stable offsets, we add pin *rtype objects in a global map
+// and treat the offset as an identifier. We use negative offsets that
+// do not overlap with any compile-time module offsets.
+//
+// Entries are created by reflect.addReflectOff.
+var reflectOffs struct {
+ lock mutex
+ next int32
+ m map[int32]unsafe.Pointer
+ minv map[unsafe.Pointer]int32
+}
+
+func reflectOffsLock() {
+ lock(&reflectOffs.lock)
+ if raceenabled {
+ raceacquire(unsafe.Pointer(&reflectOffs.lock))
+ }
+}
+
+func reflectOffsUnlock() {
+ if raceenabled {
+ racerelease(unsafe.Pointer(&reflectOffs.lock))
+ }
+ unlock(&reflectOffs.lock)
+}
+
+func resolveNameOff(ptrInModule unsafe.Pointer, off nameOff) name {
+ if off == 0 {
+ return name{}
+ }
+ base := uintptr(ptrInModule)
+ for md := &firstmoduledata; md != nil; md = md.next {
+ if base >= md.types && base < md.etypes {
+ res := md.types + uintptr(off)
+ if res > md.etypes {
+ println("runtime: nameOff", hex(off), "out of range", hex(md.types), "-", hex(md.etypes))
+ throw("runtime: name offset out of range")
+ }
+ return name{Bytes: (*byte)(unsafe.Pointer(res))}
+ }
+ }
+
+ // No module found. see if it is a run time name.
+ reflectOffsLock()
+ res, found := reflectOffs.m[int32(off)]
+ reflectOffsUnlock()
+ if !found {
+ println("runtime: nameOff", hex(off), "base", hex(base), "not in ranges:")
+ for next := &firstmoduledata; next != nil; next = next.next {
+ println("\ttypes", hex(next.types), "etypes", hex(next.etypes))
+ }
+ throw("runtime: name offset base pointer out of range")
+ }
+ return name{Bytes: (*byte)(res)}
+}
+
+func (t rtype) nameOff(off nameOff) name {
+ return resolveNameOff(unsafe.Pointer(t.Type), off)
+}
+
+func resolveTypeOff(ptrInModule unsafe.Pointer, off typeOff) *_type {
+ if off == 0 || off == -1 {
+ // -1 is the sentinel value for unreachable code.
+ // See cmd/link/internal/ld/data.go:relocsym.
+ return nil
+ }
+ base := uintptr(ptrInModule)
+ var md *moduledata
+ for next := &firstmoduledata; next != nil; next = next.next {
+ if base >= next.types && base < next.etypes {
+ md = next
+ break
+ }
+ }
+ if md == nil {
+ reflectOffsLock()
+ res := reflectOffs.m[int32(off)]
+ reflectOffsUnlock()
+ if res == nil {
+ println("runtime: typeOff", hex(off), "base", hex(base), "not in ranges:")
+ for next := &firstmoduledata; next != nil; next = next.next {
+ println("\ttypes", hex(next.types), "etypes", hex(next.etypes))
+ }
+ throw("runtime: type offset base pointer out of range")
+ }
+ return (*_type)(res)
+ }
+ if t := md.typemap[off]; t != nil {
+ return t
+ }
+ res := md.types + uintptr(off)
+ if res > md.etypes {
+ println("runtime: typeOff", hex(off), "out of range", hex(md.types), "-", hex(md.etypes))
+ throw("runtime: type offset out of range")
+ }
+ return (*_type)(unsafe.Pointer(res))
+}
+
+func (t rtype) typeOff(off typeOff) *_type {
+ return resolveTypeOff(unsafe.Pointer(t.Type), off)
+}
+
+func (t rtype) textOff(off textOff) unsafe.Pointer {
+ if off == -1 {
+ // -1 is the sentinel value for unreachable code.
+ // See cmd/link/internal/ld/data.go:relocsym.
+ return unsafe.Pointer(abi.FuncPCABIInternal(unreachableMethod))
+ }
+ base := uintptr(unsafe.Pointer(t.Type))
+ var md *moduledata
+ for next := &firstmoduledata; next != nil; next = next.next {
+ if base >= next.types && base < next.etypes {
+ md = next
+ break
+ }
+ }
+ if md == nil {
+ reflectOffsLock()
+ res := reflectOffs.m[int32(off)]
+ reflectOffsUnlock()
+ if res == nil {
+ println("runtime: textOff", hex(off), "base", hex(base), "not in ranges:")
+ for next := &firstmoduledata; next != nil; next = next.next {
+ println("\ttypes", hex(next.types), "etypes", hex(next.etypes))
+ }
+ throw("runtime: text offset base pointer out of range")
+ }
+ return res
+ }
+ res := md.textAddr(uint32(off))
+ return unsafe.Pointer(res)
+}
+
+type uncommontype = abi.UncommonType
+
+type interfacetype = abi.InterfaceType
+
+type maptype = abi.MapType
+
+type arraytype = abi.ArrayType
+
+type chantype = abi.ChanType
+
+type slicetype = abi.SliceType
+
+type functype = abi.FuncType
+
+type ptrtype = abi.PtrType
+
+type name = abi.Name
+
+type structtype = abi.StructType
+
+func pkgPath(n name) string {
+ if n.Bytes == nil || *n.Data(0)&(1<<2) == 0 {
+ return ""
+ }
+ i, l := n.ReadVarint(1)
+ off := 1 + i + l
+ if *n.Data(0)&(1<<1) != 0 {
+ i2, l2 := n.ReadVarint(off)
+ off += i2 + l2
+ }
+ var nameOff nameOff
+ copy((*[4]byte)(unsafe.Pointer(&nameOff))[:], (*[4]byte)(unsafe.Pointer(n.Data(off)))[:])
+ pkgPathName := resolveNameOff(unsafe.Pointer(n.Bytes), nameOff)
+ return pkgPathName.Name()
+}
+
+// typelinksinit scans the types from extra modules and builds the
+// moduledata typemap used to de-duplicate type pointers.
+func typelinksinit() {
+ if firstmoduledata.next == nil {
+ return
+ }
+ typehash := make(map[uint32][]*_type, len(firstmoduledata.typelinks))
+
+ modules := activeModules()
+ prev := modules[0]
+ for _, md := range modules[1:] {
+ // Collect types from the previous module into typehash.
+ collect:
+ for _, tl := range prev.typelinks {
+ var t *_type
+ if prev.typemap == nil {
+ t = (*_type)(unsafe.Pointer(prev.types + uintptr(tl)))
+ } else {
+ t = prev.typemap[typeOff(tl)]
+ }
+ // Add to typehash if not seen before.
+ tlist := typehash[t.Hash]
+ for _, tcur := range tlist {
+ if tcur == t {
+ continue collect
+ }
+ }
+ typehash[t.Hash] = append(tlist, t)
+ }
+
+ if md.typemap == nil {
+ // If any of this module's typelinks match a type from a
+ // prior module, prefer that prior type by adding the offset
+ // to this module's typemap.
+ tm := make(map[typeOff]*_type, len(md.typelinks))
+ pinnedTypemaps = append(pinnedTypemaps, tm)
+ md.typemap = tm
+ for _, tl := range md.typelinks {
+ t := (*_type)(unsafe.Pointer(md.types + uintptr(tl)))
+ for _, candidate := range typehash[t.Hash] {
+ seen := map[_typePair]struct{}{}
+ if typesEqual(t, candidate, seen) {
+ t = candidate
+ break
+ }
+ }
+ md.typemap[typeOff(tl)] = t
+ }
+ }
+
+ prev = md
+ }
+}
+
+type _typePair struct {
+ t1 *_type
+ t2 *_type
+}
+
+func toRType(t *abi.Type) rtype {
+ return rtype{t}
+}
+
+// typesEqual reports whether two types are equal.
+//
+// Everywhere in the runtime and reflect packages, it is assumed that
+// there is exactly one *_type per Go type, so that pointer equality
+// can be used to test if types are equal. There is one place that
+// breaks this assumption: buildmode=shared. In this case a type can
+// appear as two different pieces of memory. This is hidden from the
+// runtime and reflect package by the per-module typemap built in
+// typelinksinit. It uses typesEqual to map types from later modules
+// back into earlier ones.
+//
+// Only typelinksinit needs this function.
+func typesEqual(t, v *_type, seen map[_typePair]struct{}) bool {
+ tp := _typePair{t, v}
+ if _, ok := seen[tp]; ok {
+ return true
+ }
+
+ // mark these types as seen, and thus equivalent which prevents an infinite loop if
+ // the two types are identical, but recursively defined and loaded from
+ // different modules
+ seen[tp] = struct{}{}
+
+ if t == v {
+ return true
+ }
+ kind := t.Kind_ & kindMask
+ if kind != v.Kind_&kindMask {
+ return false
+ }
+ rt, rv := toRType(t), toRType(v)
+ if rt.string() != rv.string() {
+ return false
+ }
+ ut := t.Uncommon()
+ uv := v.Uncommon()
+ if ut != nil || uv != nil {
+ if ut == nil || uv == nil {
+ return false
+ }
+ pkgpatht := rt.nameOff(ut.PkgPath).Name()
+ pkgpathv := rv.nameOff(uv.PkgPath).Name()
+ if pkgpatht != pkgpathv {
+ return false
+ }
+ }
+ if kindBool <= kind && kind <= kindComplex128 {
+ return true
+ }
+ switch kind {
+ case kindString, kindUnsafePointer:
+ return true
+ case kindArray:
+ at := (*arraytype)(unsafe.Pointer(t))
+ av := (*arraytype)(unsafe.Pointer(v))
+ return typesEqual(at.Elem, av.Elem, seen) && at.Len == av.Len
+ case kindChan:
+ ct := (*chantype)(unsafe.Pointer(t))
+ cv := (*chantype)(unsafe.Pointer(v))
+ return ct.Dir == cv.Dir && typesEqual(ct.Elem, cv.Elem, seen)
+ case kindFunc:
+ ft := (*functype)(unsafe.Pointer(t))
+ fv := (*functype)(unsafe.Pointer(v))
+ if ft.OutCount != fv.OutCount || ft.InCount != fv.InCount {
+ return false
+ }
+ tin, vin := ft.InSlice(), fv.InSlice()
+ for i := 0; i < len(tin); i++ {
+ if !typesEqual(tin[i], vin[i], seen) {
+ return false
+ }
+ }
+ tout, vout := ft.OutSlice(), fv.OutSlice()
+ for i := 0; i < len(tout); i++ {
+ if !typesEqual(tout[i], vout[i], seen) {
+ return false
+ }
+ }
+ return true
+ case kindInterface:
+ it := (*interfacetype)(unsafe.Pointer(t))
+ iv := (*interfacetype)(unsafe.Pointer(v))
+ if it.PkgPath.Name() != iv.PkgPath.Name() {
+ return false
+ }
+ if len(it.Methods) != len(iv.Methods) {
+ return false
+ }
+ for i := range it.Methods {
+ tm := &it.Methods[i]
+ vm := &iv.Methods[i]
+ // Note the mhdr array can be relocated from
+ // another module. See #17724.
+ tname := resolveNameOff(unsafe.Pointer(tm), tm.Name)
+ vname := resolveNameOff(unsafe.Pointer(vm), vm.Name)
+ if tname.Name() != vname.Name() {
+ return false
+ }
+ if pkgPath(tname) != pkgPath(vname) {
+ return false
+ }
+ tityp := resolveTypeOff(unsafe.Pointer(tm), tm.Typ)
+ vityp := resolveTypeOff(unsafe.Pointer(vm), vm.Typ)
+ if !typesEqual(tityp, vityp, seen) {
+ return false
+ }
+ }
+ return true
+ case kindMap:
+ mt := (*maptype)(unsafe.Pointer(t))
+ mv := (*maptype)(unsafe.Pointer(v))
+ return typesEqual(mt.Key, mv.Key, seen) && typesEqual(mt.Elem, mv.Elem, seen)
+ case kindPtr:
+ pt := (*ptrtype)(unsafe.Pointer(t))
+ pv := (*ptrtype)(unsafe.Pointer(v))
+ return typesEqual(pt.Elem, pv.Elem, seen)
+ case kindSlice:
+ st := (*slicetype)(unsafe.Pointer(t))
+ sv := (*slicetype)(unsafe.Pointer(v))
+ return typesEqual(st.Elem, sv.Elem, seen)
+ case kindStruct:
+ st := (*structtype)(unsafe.Pointer(t))
+ sv := (*structtype)(unsafe.Pointer(v))
+ if len(st.Fields) != len(sv.Fields) {
+ return false
+ }
+ if st.PkgPath.Name() != sv.PkgPath.Name() {
+ return false
+ }
+ for i := range st.Fields {
+ tf := &st.Fields[i]
+ vf := &sv.Fields[i]
+ if tf.Name.Name() != vf.Name.Name() {
+ return false
+ }
+ if !typesEqual(tf.Typ, vf.Typ, seen) {
+ return false
+ }
+ if tf.Name.Tag() != vf.Name.Tag() {
+ return false
+ }
+ if tf.Offset != vf.Offset {
+ return false
+ }
+ if tf.Name.IsEmbedded() != vf.Name.IsEmbedded() {
+ return false
+ }
+ }
+ return true
+ default:
+ println("runtime: impossible type kind", kind)
+ throw("runtime: impossible type kind")
+ return false
+ }
+}
diff --git a/contrib/go/_std_1.21/src/runtime/typekind.go b/contrib/go/_std_1.21/src/runtime/typekind.go
new file mode 100644
index 0000000000..bd2dec94c4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/typekind.go
@@ -0,0 +1,43 @@
+// Copyright 2014 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 runtime
+
+const (
+ kindBool = 1 + iota
+ kindInt
+ kindInt8
+ kindInt16
+ kindInt32
+ kindInt64
+ kindUint
+ kindUint8
+ kindUint16
+ kindUint32
+ kindUint64
+ kindUintptr
+ kindFloat32
+ kindFloat64
+ kindComplex64
+ kindComplex128
+ kindArray
+ kindChan
+ kindFunc
+ kindInterface
+ kindMap
+ kindPtr
+ kindSlice
+ kindString
+ kindStruct
+ kindUnsafePointer
+
+ kindDirectIface = 1 << 5
+ kindGCProg = 1 << 6
+ kindMask = (1 << 5) - 1
+)
+
+// isDirectIface reports whether t is stored directly in an interface value.
+func isDirectIface(t *_type) bool {
+ return t.Kind_&kindDirectIface != 0
+}
diff --git a/contrib/go/_std_1.21/src/runtime/unsafe.go b/contrib/go/_std_1.21/src/runtime/unsafe.go
new file mode 100644
index 0000000000..6675264f59
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/unsafe.go
@@ -0,0 +1,114 @@
+// Copyright 2022 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 runtime
+
+import (
+ "runtime/internal/math"
+ "unsafe"
+)
+
+func unsafestring(ptr unsafe.Pointer, len int) {
+ if len < 0 {
+ panicunsafestringlen()
+ }
+
+ if uintptr(len) > -uintptr(ptr) {
+ if ptr == nil {
+ panicunsafestringnilptr()
+ }
+ panicunsafestringlen()
+ }
+}
+
+// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeString
+func unsafestring64(ptr unsafe.Pointer, len64 int64) {
+ len := int(len64)
+ if int64(len) != len64 {
+ panicunsafestringlen()
+ }
+ unsafestring(ptr, len)
+}
+
+func unsafestringcheckptr(ptr unsafe.Pointer, len64 int64) {
+ unsafestring64(ptr, len64)
+
+ // Check that underlying array doesn't straddle multiple heap objects.
+ // unsafestring64 has already checked for overflow.
+ if checkptrStraddles(ptr, uintptr(len64)) {
+ throw("checkptr: unsafe.String result straddles multiple allocations")
+ }
+}
+
+func panicunsafestringlen() {
+ panic(errorString("unsafe.String: len out of range"))
+}
+
+func panicunsafestringnilptr() {
+ panic(errorString("unsafe.String: ptr is nil and len is not zero"))
+}
+
+// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
+func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
+ if len < 0 {
+ panicunsafeslicelen1(getcallerpc())
+ }
+
+ if et.Size_ == 0 {
+ if ptr == nil && len > 0 {
+ panicunsafeslicenilptr1(getcallerpc())
+ }
+ }
+
+ mem, overflow := math.MulUintptr(et.Size_, uintptr(len))
+ if overflow || mem > -uintptr(ptr) {
+ if ptr == nil {
+ panicunsafeslicenilptr1(getcallerpc())
+ }
+ panicunsafeslicelen1(getcallerpc())
+ }
+}
+
+// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
+func unsafeslice64(et *_type, ptr unsafe.Pointer, len64 int64) {
+ len := int(len64)
+ if int64(len) != len64 {
+ panicunsafeslicelen1(getcallerpc())
+ }
+ unsafeslice(et, ptr, len)
+}
+
+func unsafeslicecheckptr(et *_type, ptr unsafe.Pointer, len64 int64) {
+ unsafeslice64(et, ptr, len64)
+
+ // Check that underlying array doesn't straddle multiple heap objects.
+ // unsafeslice64 has already checked for overflow.
+ if checkptrStraddles(ptr, uintptr(len64)*et.Size_) {
+ throw("checkptr: unsafe.Slice result straddles multiple allocations")
+ }
+}
+
+func panicunsafeslicelen() {
+ // This is called only from compiler-generated code, so we can get the
+ // source of the panic.
+ panicunsafeslicelen1(getcallerpc())
+}
+
+//go:yeswritebarrierrec
+func panicunsafeslicelen1(pc uintptr) {
+ panicCheck1(pc, "unsafe.Slice: len out of range")
+ panic(errorString("unsafe.Slice: len out of range"))
+}
+
+func panicunsafeslicenilptr() {
+ // This is called only from compiler-generated code, so we can get the
+ // source of the panic.
+ panicunsafeslicenilptr1(getcallerpc())
+}
+
+//go:yeswritebarrierrec
+func panicunsafeslicenilptr1(pc uintptr) {
+ panicCheck1(pc, "unsafe.Slice: ptr is nil and len is not zero")
+ panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
+}
diff --git a/contrib/go/_std_1.20/src/runtime/utf8.go b/contrib/go/_std_1.21/src/runtime/utf8.go
index 52b757662d..52b757662d 100644
--- a/contrib/go/_std_1.20/src/runtime/utf8.go
+++ b/contrib/go/_std_1.21/src/runtime/utf8.go
diff --git a/contrib/go/_std_1.20/src/runtime/vdso_elf64.go b/contrib/go/_std_1.21/src/runtime/vdso_elf64.go
index d41d25e770..d41d25e770 100644
--- a/contrib/go/_std_1.20/src/runtime/vdso_elf64.go
+++ b/contrib/go/_std_1.21/src/runtime/vdso_elf64.go
diff --git a/contrib/go/_std_1.20/src/runtime/vdso_in_none.go b/contrib/go/_std_1.21/src/runtime/vdso_in_none.go
index 3a6ee6f049..3a6ee6f049 100644
--- a/contrib/go/_std_1.20/src/runtime/vdso_in_none.go
+++ b/contrib/go/_std_1.21/src/runtime/vdso_in_none.go
diff --git a/contrib/go/_std_1.20/src/runtime/vdso_linux.go b/contrib/go/_std_1.21/src/runtime/vdso_linux.go
index 4523615711..4523615711 100644
--- a/contrib/go/_std_1.20/src/runtime/vdso_linux.go
+++ b/contrib/go/_std_1.21/src/runtime/vdso_linux.go
diff --git a/contrib/go/_std_1.20/src/runtime/vdso_linux_amd64.go b/contrib/go/_std_1.21/src/runtime/vdso_linux_amd64.go
index 4e9f748f4a..4e9f748f4a 100644
--- a/contrib/go/_std_1.20/src/runtime/vdso_linux_amd64.go
+++ b/contrib/go/_std_1.21/src/runtime/vdso_linux_amd64.go
diff --git a/contrib/go/_std_1.20/src/runtime/vdso_linux_arm64.go b/contrib/go/_std_1.21/src/runtime/vdso_linux_arm64.go
index 2f003cd645..2f003cd645 100644
--- a/contrib/go/_std_1.20/src/runtime/vdso_linux_arm64.go
+++ b/contrib/go/_std_1.21/src/runtime/vdso_linux_arm64.go
diff --git a/contrib/go/_std_1.20/src/runtime/write_err.go b/contrib/go/_std_1.21/src/runtime/write_err.go
index 81ae872e9c..81ae872e9c 100644
--- a/contrib/go/_std_1.20/src/runtime/write_err.go
+++ b/contrib/go/_std_1.21/src/runtime/write_err.go
diff --git a/contrib/go/_std_1.21/src/runtime/ya.make b/contrib/go/_std_1.21/src/runtime/ya.make
new file mode 100644
index 0000000000..0ee1028e60
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/ya.make
@@ -0,0 +1,480 @@
+GO_LIBRARY()
+
+SRCS(
+ alg.go
+ arena.go
+ asan0.go
+ asm.s
+ atomic_pointer.go
+ cgo.go
+ cgocall.go
+ cgocallback.go
+ cgocheck.go
+ chan.go
+ checkptr.go
+ compiler.go
+ complex.go
+ covercounter.go
+ covermeta.go
+ cpuflags.go
+ cpuprof.go
+ debug.go
+ debugcall.go
+ debuglog.go
+ debuglog_off.go
+ env_posix.go
+ error.go
+ exithook.go
+ extern.go
+ fastlog2.go
+ fastlog2table.go
+ float.go
+ hash64.go
+ heapdump.go
+ histogram.go
+ iface.go
+ lfstack.go
+ lockrank.go
+ lockrank_off.go
+ malloc.go
+ map.go
+ map_fast32.go
+ map_fast64.go
+ map_faststr.go
+ mbarrier.go
+ mbitmap.go
+ mcache.go
+ mcentral.go
+ mcheckmark.go
+ mem.go
+ metrics.go
+ mfinal.go
+ mfixalloc.go
+ mgc.go
+ mgclimit.go
+ mgcmark.go
+ mgcpacer.go
+ mgcscavenge.go
+ mgcstack.go
+ mgcsweep.go
+ mgcwork.go
+ mheap.go
+ minmax.go
+ mpagealloc.go
+ mpagealloc_64bit.go
+ mpagecache.go
+ mpallocbits.go
+ mprof.go
+ mranges.go
+ msan0.go
+ msize.go
+ mspanset.go
+ mstats.go
+ mwbbuf.go
+ netpoll.go
+ os_nonopenbsd.go
+ pagetrace_off.go
+ panic.go
+ pinner.go
+ plugin.go
+ preempt.go
+ print.go
+ proc.go
+ profbuf.go
+ proflabel.go
+ rdebug.go
+ runtime.go
+ runtime1.go
+ runtime2.go
+ runtime_boring.go
+ rwmutex.go
+ select.go
+ sema.go
+ sigqueue.go
+ sizeclasses.go
+ slice.go
+ softfloat64.go
+ stack.go
+ stkframe.go
+ string.go
+ stubs.go
+ symtab.go
+ symtabinl.go
+ sys_nonppc64x.go
+ tagptr.go
+ tagptr_64bit.go
+ time.go
+ time_nofake.go
+ trace.go
+ traceback.go
+ type.go
+ typekind.go
+ unsafe.go
+ utf8.go
+ write_err.go
+)
+
+GO_TEST_SRCS(
+ align_runtime_test.go
+ export_debuglog_test.go
+ export_test.go
+ importx_test.go
+ proc_runtime_test.go
+ symtabinl_test.go
+ tracebackx_test.go
+)
+
+GO_XTEST_SRCS(
+ abi_test.go
+ align_test.go
+ arena_test.go
+ callers_test.go
+ chan_test.go
+ chanbarrier_test.go
+ checkptr_test.go
+ closure_test.go
+ complex_test.go
+ crash_cgo_test.go
+ crash_test.go
+ debuglog_test.go
+ defer_test.go
+ ehooks_test.go
+ env_test.go
+ example_test.go
+ fastlog2_test.go
+ float_test.go
+ gc_test.go
+ gcinfo_test.go
+ hash_test.go
+ heap_test.go
+ histogram_test.go
+ iface_test.go
+ import_test.go
+ lfstack_test.go
+ lockrank_test.go
+ malloc_test.go
+ map_benchmark_test.go
+ map_test.go
+ memmove_test.go
+ metrics_test.go
+ mfinal_test.go
+ mgclimit_test.go
+ mgcpacer_test.go
+ mgcscavenge_test.go
+ minmax_test.go
+ mpagealloc_test.go
+ mpagecache_test.go
+ mpallocbits_test.go
+ mranges_test.go
+ netpoll_os_test.go
+ norace_test.go
+ panic_test.go
+ panicnil_test.go
+ pinner_test.go
+ proc_test.go
+ profbuf_test.go
+ rand_test.go
+ runtime-gdb_test.go
+ runtime-lldb_test.go
+ runtime_test.go
+ rwmutex_test.go
+ sema_test.go
+ sizeof_test.go
+ slice_test.go
+ softfloat64_test.go
+ stack_test.go
+ start_line_test.go
+ string_test.go
+ symtab_test.go
+ time_test.go
+ trace_cgo_test.go
+ traceback_test.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ asm_amd64.s
+ cpuflags_amd64.go
+ cputicks.go
+ duff_amd64.s
+ memclr_amd64.s
+ memmove_amd64.s
+ preempt_amd64.s
+ stubs_amd64.go
+ sys_x86.go
+ test_amd64.go
+ test_amd64.s
+ )
+
+ GO_XTEST_SRCS(start_line_amd64_test.go)
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ asm_arm64.s
+ atomic_arm64.s
+ cpuflags_arm64.go
+ duff_arm64.s
+ memclr_arm64.s
+ memmove_arm64.s
+ preempt_arm64.s
+ stubs_arm64.go
+ sys_arm64.go
+ test_stubs.go
+ tls_arm64.s
+ tls_stub.go
+ )
+ENDIF()
+
+IF (OS_LINUX)
+ SRCS(
+ cgo_mmap.go
+ cgo_sigaction.go
+ create_file_unix.go
+ lock_futex.go
+ mem_linux.go
+ nbpipe_pipe2.go
+ netpoll_epoll.go
+ nonwindows_stub.go
+ os_linux.go
+ os_linux_generic.go
+ os_unix.go
+ preempt_nonwindows.go
+ retry.go
+ security_linux.go
+ security_unix.go
+ signal_unix.go
+ sigqueue_note.go
+ sigtab_linux_generic.go
+ stubs2.go
+ stubs3.go
+ stubs_linux.go
+ vdso_elf64.go
+ vdso_linux.go
+ )
+
+ GO_TEST_SRCS(
+ export_debug_test.go
+ export_linux_test.go
+ export_mmap_test.go
+ export_pipe2_test.go
+ export_unix_test.go
+ )
+
+ GO_XTEST_SRCS(
+ crash_unix_test.go
+ debug_test.go
+ nbpipe_fcntl_unix_test.go
+ nbpipe_test.go
+ norace_linux_test.go
+ runtime-gdb_unix_test.go
+ runtime_linux_test.go
+ runtime_mmap_test.go
+ runtime_unix_test.go
+ security_test.go
+ semasleep_test.go
+ syscall_unix_test.go
+ )
+ENDIF()
+
+IF (OS_LINUX AND ARCH_X86_64)
+ SRCS(
+ defs_linux_amd64.go
+ os_linux_noauxv.go
+ os_linux_x86.go
+ rt0_linux_amd64.s
+ signal_amd64.go
+ signal_linux_amd64.go
+ sys_linux_amd64.s
+ time_linux_amd64.s
+ timeasm.go
+ tls_stub.go
+ vdso_linux_amd64.go
+ )
+
+ GO_TEST_SRCS(export_debug_amd64_test.go)
+
+ GO_XTEST_SRCS(memmove_linux_amd64_test.go)
+ENDIF()
+
+IF (OS_LINUX AND ARCH_ARM64)
+ SRCS(
+ defs_linux_arm64.go
+ os_linux_arm64.go
+ rt0_linux_arm64.s
+ signal_arm64.go
+ signal_linux_arm64.go
+ sys_linux_arm64.s
+ timestub.go
+ timestub2.go
+ vdso_linux_arm64.go
+ )
+
+ GO_TEST_SRCS(export_debug_arm64_test.go)
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ create_file_unix.go
+ lock_sema.go
+ mem_darwin.go
+ nbpipe_pipe.go
+ netpoll_kqueue.go
+ nonwindows_stub.go
+ os_darwin.go
+ os_unix.go
+ os_unix_nonlinux.go
+ preempt_nonwindows.go
+ retry.go
+ security_issetugid.go
+ security_unix.go
+ signal_darwin.go
+ signal_unix.go
+ stubs_nonlinux.go
+ sys_darwin.go
+ sys_libc.go
+ timestub.go
+ vdso_in_none.go
+ )
+
+ GO_TEST_SRCS(
+ export_darwin_test.go
+ export_mmap_test.go
+ export_pipe_test.go
+ export_unix_test.go
+ )
+
+ GO_XTEST_SRCS(
+ crash_unix_test.go
+ nbpipe_fcntl_libc_test.go
+ nbpipe_pipe_test.go
+ nbpipe_test.go
+ runtime-gdb_unix_test.go
+ runtime_mmap_test.go
+ runtime_unix_test.go
+ security_test.go
+ semasleep_test.go
+ syscall_unix_test.go
+ )
+ENDIF()
+
+IF (OS_DARWIN AND ARCH_X86_64)
+ SRCS(
+ defs_darwin_amd64.go
+ rt0_darwin_amd64.s
+ signal_amd64.go
+ signal_darwin_amd64.go
+ sys_darwin_amd64.s
+ tls_stub.go
+ )
+ENDIF()
+
+IF (OS_DARWIN AND ARCH_ARM64)
+ SRCS(
+ defs_darwin_arm64.go
+ os_darwin_arm64.go
+ rt0_darwin_arm64.s
+ signal_arm64.go
+ signal_darwin_arm64.go
+ sys_darwin_arm64.go
+ sys_darwin_arm64.s
+ )
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ auxv_none.go
+ create_file_nounix.go
+ defs_windows.go
+ lock_sema.go
+ mem_windows.go
+ netpoll_windows.go
+ os_windows.go
+ security_nonunix.go
+ signal_windows.go
+ sigqueue_note.go
+ stubs3.go
+ stubs_nonlinux.go
+ syscall_windows.go
+ timeasm.go
+ vdso_in_none.go
+ zcallback_windows.go
+ )
+
+ GO_TEST_SRCS(export_windows_test.go)
+
+ GO_XTEST_SRCS(
+ runtime-seh_windows_test.go
+ signal_windows_test.go
+ syscall_windows_test.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS AND ARCH_X86_64)
+ SRCS(
+ defs_windows_amd64.go
+ rt0_windows_amd64.s
+ sys_windows_amd64.s
+ time_windows_amd64.s
+ tls_windows_amd64.go
+ zcallback_windows.s
+ )
+ENDIF()
+
+IF (OS_WINDOWS AND ARCH_ARM64)
+ SRCS(
+ defs_windows_arm64.go
+ os_windows_arm64.go
+ rt0_windows_arm64.s
+ sys_windows_arm64.s
+ time_windows_arm64.s
+ zcallback_windows_arm64.s
+ )
+ENDIF()
+
+IF (CGO_ENABLED OR OS_DARWIN)
+ IF (RACE)
+ SRCS(
+ race.go
+ )
+
+ IF (ARCH_ARM64)
+ SRCS(
+ race_arm64.s
+ )
+ ENDIF()
+
+ IF (ARCH_X86_64)
+ SRCS(
+ race_amd64.s
+ )
+ ENDIF()
+ ELSE()
+ SRCS(
+ race0.go
+ )
+ ENDIF()
+ELSE()
+ SRCS(
+ race0.go
+ )
+ENDIF()
+
+
+END()
+
+RECURSE(
+ coverage
+ debug
+ internal
+ metrics
+ pprof
+ race
+ trace
+)
+
+IF (CGO_ENABLED)
+ RECURSE(
+ cgo
+ )
+ENDIF()
diff --git a/contrib/go/_std_1.20/src/runtime/zcallback_windows.go b/contrib/go/_std_1.21/src/runtime/zcallback_windows.go
index 2c3cb28518..2c3cb28518 100644
--- a/contrib/go/_std_1.20/src/runtime/zcallback_windows.go
+++ b/contrib/go/_std_1.21/src/runtime/zcallback_windows.go
diff --git a/contrib/go/_std_1.21/src/runtime/zcallback_windows.s b/contrib/go/_std_1.21/src/runtime/zcallback_windows.s
new file mode 100644
index 0000000000..86d70d61e3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/runtime/zcallback_windows.s
@@ -0,0 +1,2015 @@
+// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
+
+//go:build 386 || amd64
+
+#include "textflag.h"
+
+// runtime·callbackasm is called by external code to
+// execute Go implemented callback function. It is not
+// called from the start, instead runtime·compilecallback
+// always returns address into runtime·callbackasm offset
+// appropriately so different callbacks start with different
+// CALL instruction in runtime·callbackasm. This determines
+// which Go callback function is executed later on.
+
+TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
+ CALL runtime·callbackasm1(SB)
diff --git a/contrib/go/_std_1.21/src/slices/slices.go b/contrib/go/_std_1.21/src/slices/slices.go
new file mode 100644
index 0000000000..afeed0afb5
--- /dev/null
+++ b/contrib/go/_std_1.21/src/slices/slices.go
@@ -0,0 +1,498 @@
+// 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 slices defines various functions useful with slices of any type.
+package slices
+
+import (
+ "cmp"
+ "unsafe"
+)
+
+// Equal reports whether two slices are equal: the same length and all
+// elements equal. If the lengths are different, Equal returns false.
+// Otherwise, the elements are compared in increasing index order, and the
+// comparison stops at the first unequal pair.
+// Floating point NaNs are not considered equal.
+func Equal[S ~[]E, E comparable](s1, s2 S) bool {
+ if len(s1) != len(s2) {
+ return false
+ }
+ for i := range s1 {
+ if s1[i] != s2[i] {
+ return false
+ }
+ }
+ return true
+}
+
+// EqualFunc reports whether two slices are equal using an equality
+// function on each pair of elements. If the lengths are different,
+// EqualFunc returns false. Otherwise, the elements are compared in
+// increasing index order, and the comparison stops at the first index
+// for which eq returns false.
+func EqualFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, eq func(E1, E2) bool) bool {
+ if len(s1) != len(s2) {
+ return false
+ }
+ for i, v1 := range s1 {
+ v2 := s2[i]
+ if !eq(v1, v2) {
+ return false
+ }
+ }
+ return true
+}
+
+// Compare compares the elements of s1 and s2, using [cmp.Compare] on each pair
+// of elements. The elements are compared sequentially, starting at index 0,
+// until one element is not equal to the other.
+// The result of comparing the first non-matching elements is returned.
+// If both slices are equal until one of them ends, the shorter slice is
+// considered less than the longer one.
+// The result is 0 if s1 == s2, -1 if s1 < s2, and +1 if s1 > s2.
+func Compare[S ~[]E, E cmp.Ordered](s1, s2 S) int {
+ for i, v1 := range s1 {
+ if i >= len(s2) {
+ return +1
+ }
+ v2 := s2[i]
+ if c := cmp.Compare(v1, v2); c != 0 {
+ return c
+ }
+ }
+ if len(s1) < len(s2) {
+ return -1
+ }
+ return 0
+}
+
+// CompareFunc is like [Compare] but uses a custom comparison function on each
+// pair of elements.
+// The result is the first non-zero result of cmp; if cmp always
+// returns 0 the result is 0 if len(s1) == len(s2), -1 if len(s1) < len(s2),
+// and +1 if len(s1) > len(s2).
+func CompareFunc[S1 ~[]E1, S2 ~[]E2, E1, E2 any](s1 S1, s2 S2, cmp func(E1, E2) int) int {
+ for i, v1 := range s1 {
+ if i >= len(s2) {
+ return +1
+ }
+ v2 := s2[i]
+ if c := cmp(v1, v2); c != 0 {
+ return c
+ }
+ }
+ if len(s1) < len(s2) {
+ return -1
+ }
+ return 0
+}
+
+// Index returns the index of the first occurrence of v in s,
+// or -1 if not present.
+func Index[S ~[]E, E comparable](s S, v E) int {
+ for i := range s {
+ if v == s[i] {
+ return i
+ }
+ }
+ return -1
+}
+
+// IndexFunc returns the first index i satisfying f(s[i]),
+// or -1 if none do.
+func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int {
+ for i := range s {
+ if f(s[i]) {
+ return i
+ }
+ }
+ return -1
+}
+
+// Contains reports whether v is present in s.
+func Contains[S ~[]E, E comparable](s S, v E) bool {
+ return Index(s, v) >= 0
+}
+
+// ContainsFunc reports whether at least one
+// element e of s satisfies f(e).
+func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool {
+ return IndexFunc(s, f) >= 0
+}
+
+// Insert inserts the values v... into s at index i,
+// returning the modified slice.
+// The elements at s[i:] are shifted up to make room.
+// In the returned slice r, r[i] == v[0],
+// and r[i+len(v)] == value originally at r[i].
+// Insert panics if i is out of range.
+// This function is O(len(s) + len(v)).
+func Insert[S ~[]E, E any](s S, i int, v ...E) S {
+ m := len(v)
+ if m == 0 {
+ return s
+ }
+ n := len(s)
+ if i == n {
+ return append(s, v...)
+ }
+ if n+m > cap(s) {
+ // Use append rather than make so that we bump the size of
+ // the slice up to the next storage class.
+ // This is what Grow does but we don't call Grow because
+ // that might copy the values twice.
+ s2 := append(s[:i], make(S, n+m-i)...)
+ copy(s2[i:], v)
+ copy(s2[i+m:], s[i:])
+ return s2
+ }
+ s = s[:n+m]
+
+ // before:
+ // s: aaaaaaaabbbbccccccccdddd
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ // after:
+ // s: aaaaaaaavvvvbbbbcccccccc
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ //
+ // a are the values that don't move in s.
+ // v are the values copied in from v.
+ // b and c are the values from s that are shifted up in index.
+ // d are the values that get overwritten, never to be seen again.
+
+ if !overlaps(v, s[i+m:]) {
+ // Easy case - v does not overlap either the c or d regions.
+ // (It might be in some of a or b, or elsewhere entirely.)
+ // The data we copy up doesn't write to v at all, so just do it.
+
+ copy(s[i+m:], s[i:])
+
+ // Now we have
+ // s: aaaaaaaabbbbbbbbcccccccc
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ // Note the b values are duplicated.
+
+ copy(s[i:], v)
+
+ // Now we have
+ // s: aaaaaaaavvvvbbbbcccccccc
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ // That's the result we want.
+ return s
+ }
+
+ // The hard case - v overlaps c or d. We can't just shift up
+ // the data because we'd move or clobber the values we're trying
+ // to insert.
+ // So instead, write v on top of d, then rotate.
+ copy(s[n:], v)
+
+ // Now we have
+ // s: aaaaaaaabbbbccccccccvvvv
+ // ^ ^ ^ ^
+ // i i+m n n+m
+
+ rotateRight(s[i:], m)
+
+ // Now we have
+ // s: aaaaaaaavvvvbbbbcccccccc
+ // ^ ^ ^ ^
+ // i i+m n n+m
+ // That's the result we want.
+ return s
+}
+
+// Delete removes the elements s[i:j] from s, returning the modified slice.
+// Delete panics if s[i:j] is not a valid slice of s.
+// Delete is O(len(s)-j), so if many items must be deleted, it is better to
+// make a single call deleting them all together than to delete one at a time.
+// Delete might not modify the elements s[len(s)-(j-i):len(s)]. If those
+// elements contain pointers you might consider zeroing those elements so that
+// objects they reference can be garbage collected.
+func Delete[S ~[]E, E any](s S, i, j int) S {
+ _ = s[i:j] // bounds check
+
+ return append(s[:i], s[j:]...)
+}
+
+// DeleteFunc removes any elements from s for which del returns true,
+// returning the modified slice.
+// When DeleteFunc removes m elements, it might not modify the elements
+// s[len(s)-m:len(s)]. If those elements contain pointers you might consider
+// zeroing those elements so that objects they reference can be garbage
+// collected.
+func DeleteFunc[S ~[]E, E any](s S, del func(E) bool) S {
+ // Don't start copying elements until we find one to delete.
+ for i, v := range s {
+ if del(v) {
+ j := i
+ for i++; i < len(s); i++ {
+ v = s[i]
+ if !del(v) {
+ s[j] = v
+ j++
+ }
+ }
+ return s[:j]
+ }
+ }
+ return s
+}
+
+// Replace replaces the elements s[i:j] by the given v, and returns the
+// modified slice. Replace panics if s[i:j] is not a valid slice of s.
+func Replace[S ~[]E, E any](s S, i, j int, v ...E) S {
+ _ = s[i:j] // verify that i:j is a valid subslice
+
+ if i == j {
+ return Insert(s, i, v...)
+ }
+ if j == len(s) {
+ return append(s[:i], v...)
+ }
+
+ tot := len(s[:i]) + len(v) + len(s[j:])
+ if tot > cap(s) {
+ // Too big to fit, allocate and copy over.
+ s2 := append(s[:i], make(S, tot-i)...) // See Insert
+ copy(s2[i:], v)
+ copy(s2[i+len(v):], s[j:])
+ return s2
+ }
+
+ r := s[:tot]
+
+ if i+len(v) <= j {
+ // Easy, as v fits in the deleted portion.
+ copy(r[i:], v)
+ if i+len(v) != j {
+ copy(r[i+len(v):], s[j:])
+ }
+ return r
+ }
+
+ // We are expanding (v is bigger than j-i).
+ // The situation is something like this:
+ // (example has i=4,j=8,len(s)=16,len(v)=6)
+ // s: aaaaxxxxbbbbbbbbyy
+ // ^ ^ ^ ^
+ // i j len(s) tot
+ // a: prefix of s
+ // x: deleted range
+ // b: more of s
+ // y: area to expand into
+
+ if !overlaps(r[i+len(v):], v) {
+ // Easy, as v is not clobbered by the first copy.
+ copy(r[i+len(v):], s[j:])
+ copy(r[i:], v)
+ return r
+ }
+
+ // This is a situation where we don't have a single place to which
+ // we can copy v. Parts of it need to go to two different places.
+ // We want to copy the prefix of v into y and the suffix into x, then
+ // rotate |y| spots to the right.
+ //
+ // v[2:] v[:2]
+ // | |
+ // s: aaaavvvvbbbbbbbbvv
+ // ^ ^ ^ ^
+ // i j len(s) tot
+ //
+ // If either of those two destinations don't alias v, then we're good.
+ y := len(v) - (j - i) // length of y portion
+
+ if !overlaps(r[i:j], v) {
+ copy(r[i:j], v[y:])
+ copy(r[len(s):], v[:y])
+ rotateRight(r[i:], y)
+ return r
+ }
+ if !overlaps(r[len(s):], v) {
+ copy(r[len(s):], v[:y])
+ copy(r[i:j], v[y:])
+ rotateRight(r[i:], y)
+ return r
+ }
+
+ // Now we know that v overlaps both x and y.
+ // That means that the entirety of b is *inside* v.
+ // So we don't need to preserve b at all; instead we
+ // can copy v first, then copy the b part of v out of
+ // v to the right destination.
+ k := startIdx(v, s[j:])
+ copy(r[i:], v)
+ copy(r[i+len(v):], r[i+k:])
+ return r
+}
+
+// Clone returns a copy of the slice.
+// The elements are copied using assignment, so this is a shallow clone.
+func Clone[S ~[]E, E any](s S) S {
+ // Preserve nil in case it matters.
+ if s == nil {
+ return nil
+ }
+ return append(S([]E{}), s...)
+}
+
+// Compact replaces consecutive runs of equal elements with a single copy.
+// This is like the uniq command found on Unix.
+// Compact modifies the contents of the slice s and returns the modified slice,
+// which may have a smaller length.
+// When Compact discards m elements in total, it might not modify the elements
+// s[len(s)-m:len(s)]. If those elements contain pointers you might consider
+// zeroing those elements so that objects they reference can be garbage collected.
+func Compact[S ~[]E, E comparable](s S) S {
+ if len(s) < 2 {
+ return s
+ }
+ i := 1
+ for k := 1; k < len(s); k++ {
+ if s[k] != s[k-1] {
+ if i != k {
+ s[i] = s[k]
+ }
+ i++
+ }
+ }
+ return s[:i]
+}
+
+// CompactFunc is like [Compact] but uses an equality function to compare elements.
+// For runs of elements that compare equal, CompactFunc keeps the first one.
+func CompactFunc[S ~[]E, E any](s S, eq func(E, E) bool) S {
+ if len(s) < 2 {
+ return s
+ }
+ i := 1
+ for k := 1; k < len(s); k++ {
+ if !eq(s[k], s[k-1]) {
+ if i != k {
+ s[i] = s[k]
+ }
+ i++
+ }
+ }
+ return s[:i]
+}
+
+// Grow increases the slice's capacity, if necessary, to guarantee space for
+// another n elements. After Grow(n), at least n elements can be appended
+// to the slice without another allocation. If n is negative or too large to
+// allocate the memory, Grow panics.
+func Grow[S ~[]E, E any](s S, n int) S {
+ if n < 0 {
+ panic("cannot be negative")
+ }
+ if n -= cap(s) - len(s); n > 0 {
+ s = append(s[:cap(s)], make([]E, n)...)[:len(s)]
+ }
+ return s
+}
+
+// Clip removes unused capacity from the slice, returning s[:len(s):len(s)].
+func Clip[S ~[]E, E any](s S) S {
+ return s[:len(s):len(s)]
+}
+
+// Rotation algorithm explanation:
+//
+// rotate left by 2
+// start with
+// 0123456789
+// split up like this
+// 01 234567 89
+// swap first 2 and last 2
+// 89 234567 01
+// join first parts
+// 89234567 01
+// recursively rotate first left part by 2
+// 23456789 01
+// join at the end
+// 2345678901
+//
+// rotate left by 8
+// start with
+// 0123456789
+// split up like this
+// 01 234567 89
+// swap first 2 and last 2
+// 89 234567 01
+// join last parts
+// 89 23456701
+// recursively rotate second part left by 6
+// 89 01234567
+// join at the end
+// 8901234567
+
+// TODO: There are other rotate algorithms.
+// This algorithm has the desirable property that it moves each element exactly twice.
+// The triple-reverse algorithm is simpler and more cache friendly, but takes more writes.
+// The follow-cycles algorithm can be 1-write but it is not very cache friendly.
+
+// rotateLeft rotates b left by n spaces.
+// s_final[i] = s_orig[i+r], wrapping around.
+func rotateLeft[E any](s []E, r int) {
+ for r != 0 && r != len(s) {
+ if r*2 <= len(s) {
+ swap(s[:r], s[len(s)-r:])
+ s = s[:len(s)-r]
+ } else {
+ swap(s[:len(s)-r], s[r:])
+ s, r = s[len(s)-r:], r*2-len(s)
+ }
+ }
+}
+func rotateRight[E any](s []E, r int) {
+ rotateLeft(s, len(s)-r)
+}
+
+// swap swaps the contents of x and y. x and y must be equal length and disjoint.
+func swap[E any](x, y []E) {
+ for i := 0; i < len(x); i++ {
+ x[i], y[i] = y[i], x[i]
+ }
+}
+
+// overlaps reports whether the memory ranges a[0:len(a)] and b[0:len(b)] overlap.
+func overlaps[E any](a, b []E) bool {
+ if len(a) == 0 || len(b) == 0 {
+ return false
+ }
+ elemSize := unsafe.Sizeof(a[0])
+ if elemSize == 0 {
+ return false
+ }
+ // TODO: use a runtime/unsafe facility once one becomes available. See issue 12445.
+ // Also see crypto/internal/alias/alias.go:AnyOverlap
+ return uintptr(unsafe.Pointer(&a[0])) <= uintptr(unsafe.Pointer(&b[len(b)-1]))+(elemSize-1) &&
+ uintptr(unsafe.Pointer(&b[0])) <= uintptr(unsafe.Pointer(&a[len(a)-1]))+(elemSize-1)
+}
+
+// startIdx returns the index in haystack where the needle starts.
+// prerequisite: the needle must be aliased entirely inside the haystack.
+func startIdx[E any](haystack, needle []E) int {
+ p := &needle[0]
+ for i := range haystack {
+ if p == &haystack[i] {
+ return i
+ }
+ }
+ // TODO: what if the overlap is by a non-integral number of Es?
+ panic("needle not found")
+}
+
+// Reverse reverses the elements of the slice in place.
+func Reverse[S ~[]E, E any](s S) {
+ for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
+ s[i], s[j] = s[j], s[i]
+ }
+}
diff --git a/contrib/go/_std_1.21/src/slices/sort.go b/contrib/go/_std_1.21/src/slices/sort.go
new file mode 100644
index 0000000000..822f2fceb4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/slices/sort.go
@@ -0,0 +1,192 @@
+// Copyright 2023 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 slices
+
+import (
+ "cmp"
+ "math/bits"
+)
+
+// Sort sorts a slice of any ordered type in ascending order.
+// When sorting floating-point numbers, NaNs are ordered before other values.
+func Sort[S ~[]E, E cmp.Ordered](x S) {
+ n := len(x)
+ pdqsortOrdered(x, 0, n, bits.Len(uint(n)))
+}
+
+// SortFunc sorts the slice x in ascending order as determined by the cmp
+// function. This sort is not guaranteed to be stable.
+// cmp(a, b) should return a negative number when a < b, a positive number when
+// a > b and zero when a == b.
+//
+// SortFunc requires that cmp is a strict weak ordering.
+// See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings.
+func SortFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
+ n := len(x)
+ pdqsortCmpFunc(x, 0, n, bits.Len(uint(n)), cmp)
+}
+
+// SortStableFunc sorts the slice x while keeping the original order of equal
+// elements, using cmp to compare elements in the same way as [SortFunc].
+func SortStableFunc[S ~[]E, E any](x S, cmp func(a, b E) int) {
+ stableCmpFunc(x, len(x), cmp)
+}
+
+// IsSorted reports whether x is sorted in ascending order.
+func IsSorted[S ~[]E, E cmp.Ordered](x S) bool {
+ for i := len(x) - 1; i > 0; i-- {
+ if cmp.Less(x[i], x[i-1]) {
+ return false
+ }
+ }
+ return true
+}
+
+// IsSortedFunc reports whether x is sorted in ascending order, with cmp as the
+// comparison function as defined by [SortFunc].
+func IsSortedFunc[S ~[]E, E any](x S, cmp func(a, b E) int) bool {
+ for i := len(x) - 1; i > 0; i-- {
+ if cmp(x[i], x[i-1]) < 0 {
+ return false
+ }
+ }
+ return true
+}
+
+// Min returns the minimal value in x. It panics if x is empty.
+// For floating-point numbers, Min propagates NaNs (any NaN value in x
+// forces the output to be NaN).
+func Min[S ~[]E, E cmp.Ordered](x S) E {
+ if len(x) < 1 {
+ panic("slices.Min: empty list")
+ }
+ m := x[0]
+ for i := 1; i < len(x); i++ {
+ m = min(m, x[i])
+ }
+ return m
+}
+
+// MinFunc returns the minimal value in x, using cmp to compare elements.
+// It panics if x is empty. If there is more than one minimal element
+// according to the cmp function, MinFunc returns the first one.
+func MinFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
+ if len(x) < 1 {
+ panic("slices.MinFunc: empty list")
+ }
+ m := x[0]
+ for i := 1; i < len(x); i++ {
+ if cmp(x[i], m) < 0 {
+ m = x[i]
+ }
+ }
+ return m
+}
+
+// Max returns the maximal value in x. It panics if x is empty.
+// For floating-point E, Max propagates NaNs (any NaN value in x
+// forces the output to be NaN).
+func Max[S ~[]E, E cmp.Ordered](x S) E {
+ if len(x) < 1 {
+ panic("slices.Max: empty list")
+ }
+ m := x[0]
+ for i := 1; i < len(x); i++ {
+ m = max(m, x[i])
+ }
+ return m
+}
+
+// MaxFunc returns the maximal value in x, using cmp to compare elements.
+// It panics if x is empty. If there is more than one maximal element
+// according to the cmp function, MaxFunc returns the first one.
+func MaxFunc[S ~[]E, E any](x S, cmp func(a, b E) int) E {
+ if len(x) < 1 {
+ panic("slices.MaxFunc: empty list")
+ }
+ m := x[0]
+ for i := 1; i < len(x); i++ {
+ if cmp(x[i], m) > 0 {
+ m = x[i]
+ }
+ }
+ return m
+}
+
+// BinarySearch searches for target in a sorted slice and returns the position
+// where target is found, or the position where target would appear in the
+// sort order; it also returns a bool saying whether the target is really found
+// in the slice. The slice must be sorted in increasing order.
+func BinarySearch[S ~[]E, E cmp.Ordered](x S, target E) (int, bool) {
+ // Inlining is faster than calling BinarySearchFunc with a lambda.
+ n := len(x)
+ // Define x[-1] < target and x[n] >= target.
+ // Invariant: x[i-1] < target, x[j] >= target.
+ i, j := 0, n
+ for i < j {
+ h := int(uint(i+j) >> 1) // avoid overflow when computing h
+ // i ≤ h < j
+ if cmp.Less(x[h], target) {
+ i = h + 1 // preserves x[i-1] < target
+ } else {
+ j = h // preserves x[j] >= target
+ }
+ }
+ // i == j, x[i-1] < target, and x[j] (= x[i]) >= target => answer is i.
+ return i, i < n && (x[i] == target || (isNaN(x[i]) && isNaN(target)))
+}
+
+// BinarySearchFunc works like [BinarySearch], but uses a custom comparison
+// function. The slice must be sorted in increasing order, where "increasing"
+// is defined by cmp. cmp should return 0 if the slice element matches
+// the target, a negative number if the slice element precedes the target,
+// or a positive number if the slice element follows the target.
+// cmp must implement the same ordering as the slice, such that if
+// cmp(a, t) < 0 and cmp(b, t) >= 0, then a must precede b in the slice.
+func BinarySearchFunc[S ~[]E, E, T any](x S, target T, cmp func(E, T) int) (int, bool) {
+ n := len(x)
+ // Define cmp(x[-1], target) < 0 and cmp(x[n], target) >= 0 .
+ // Invariant: cmp(x[i - 1], target) < 0, cmp(x[j], target) >= 0.
+ i, j := 0, n
+ for i < j {
+ h := int(uint(i+j) >> 1) // avoid overflow when computing h
+ // i ≤ h < j
+ if cmp(x[h], target) < 0 {
+ i = h + 1 // preserves cmp(x[i - 1], target) < 0
+ } else {
+ j = h // preserves cmp(x[j], target) >= 0
+ }
+ }
+ // i == j, cmp(x[i-1], target) < 0, and cmp(x[j], target) (= cmp(x[i], target)) >= 0 => answer is i.
+ return i, i < n && cmp(x[i], target) == 0
+}
+
+type sortedHint int // hint for pdqsort when choosing the pivot
+
+const (
+ unknownHint sortedHint = iota
+ increasingHint
+ decreasingHint
+)
+
+// xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
+type xorshift uint64
+
+func (r *xorshift) Next() uint64 {
+ *r ^= *r << 13
+ *r ^= *r >> 17
+ *r ^= *r << 5
+ return uint64(*r)
+}
+
+func nextPowerOfTwo(length int) uint {
+ return 1 << bits.Len(uint(length))
+}
+
+// isNaN reports whether x is a NaN without requiring the math package.
+// This will always return false if T is not floating-point.
+func isNaN[T cmp.Ordered](x T) bool {
+ return x != x
+}
diff --git a/contrib/go/_std_1.21/src/slices/ya.make b/contrib/go/_std_1.21/src/slices/ya.make
new file mode 100644
index 0000000000..dcccf79f2c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/slices/ya.make
@@ -0,0 +1,21 @@
+GO_LIBRARY()
+
+SRCS(
+ slices.go
+ sort.go
+ zsortanyfunc.go
+ zsortordered.go
+)
+
+GO_TEST_SRCS(
+ slices_test.go
+ sort_benchmark_test.go
+ sort_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/slices/zsortanyfunc.go b/contrib/go/_std_1.21/src/slices/zsortanyfunc.go
new file mode 100644
index 0000000000..06f2c7a248
--- /dev/null
+++ b/contrib/go/_std_1.21/src/slices/zsortanyfunc.go
@@ -0,0 +1,479 @@
+// Code generated by gen_sort_variants.go; DO NOT EDIT.
+
+// Copyright 2022 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 slices
+
+// insertionSortCmpFunc sorts data[a:b] using insertion sort.
+func insertionSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
+ for i := a + 1; i < b; i++ {
+ for j := i; j > a && (cmp(data[j], data[j-1]) < 0); j-- {
+ data[j], data[j-1] = data[j-1], data[j]
+ }
+ }
+}
+
+// siftDownCmpFunc implements the heap property on data[lo:hi].
+// first is an offset into the array where the root of the heap lies.
+func siftDownCmpFunc[E any](data []E, lo, hi, first int, cmp func(a, b E) int) {
+ root := lo
+ for {
+ child := 2*root + 1
+ if child >= hi {
+ break
+ }
+ if child+1 < hi && (cmp(data[first+child], data[first+child+1]) < 0) {
+ child++
+ }
+ if !(cmp(data[first+root], data[first+child]) < 0) {
+ return
+ }
+ data[first+root], data[first+child] = data[first+child], data[first+root]
+ root = child
+ }
+}
+
+func heapSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
+ first := a
+ lo := 0
+ hi := b - a
+
+ // Build heap with greatest element at top.
+ for i := (hi - 1) / 2; i >= 0; i-- {
+ siftDownCmpFunc(data, i, hi, first, cmp)
+ }
+
+ // Pop elements, largest first, into end of data.
+ for i := hi - 1; i >= 0; i-- {
+ data[first], data[first+i] = data[first+i], data[first]
+ siftDownCmpFunc(data, lo, i, first, cmp)
+ }
+}
+
+// pdqsortCmpFunc sorts data[a:b].
+// The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort.
+// pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf
+// C++ implementation: https://github.com/orlp/pdqsort
+// Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/
+// limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort.
+func pdqsortCmpFunc[E any](data []E, a, b, limit int, cmp func(a, b E) int) {
+ const maxInsertion = 12
+
+ var (
+ wasBalanced = true // whether the last partitioning was reasonably balanced
+ wasPartitioned = true // whether the slice was already partitioned
+ )
+
+ for {
+ length := b - a
+
+ if length <= maxInsertion {
+ insertionSortCmpFunc(data, a, b, cmp)
+ return
+ }
+
+ // Fall back to heapsort if too many bad choices were made.
+ if limit == 0 {
+ heapSortCmpFunc(data, a, b, cmp)
+ return
+ }
+
+ // If the last partitioning was imbalanced, we need to breaking patterns.
+ if !wasBalanced {
+ breakPatternsCmpFunc(data, a, b, cmp)
+ limit--
+ }
+
+ pivot, hint := choosePivotCmpFunc(data, a, b, cmp)
+ if hint == decreasingHint {
+ reverseRangeCmpFunc(data, a, b, cmp)
+ // The chosen pivot was pivot-a elements after the start of the array.
+ // After reversing it is pivot-a elements before the end of the array.
+ // The idea came from Rust's implementation.
+ pivot = (b - 1) - (pivot - a)
+ hint = increasingHint
+ }
+
+ // The slice is likely already sorted.
+ if wasBalanced && wasPartitioned && hint == increasingHint {
+ if partialInsertionSortCmpFunc(data, a, b, cmp) {
+ return
+ }
+ }
+
+ // Probably the slice contains many duplicate elements, partition the slice into
+ // elements equal to and elements greater than the pivot.
+ if a > 0 && !(cmp(data[a-1], data[pivot]) < 0) {
+ mid := partitionEqualCmpFunc(data, a, b, pivot, cmp)
+ a = mid
+ continue
+ }
+
+ mid, alreadyPartitioned := partitionCmpFunc(data, a, b, pivot, cmp)
+ wasPartitioned = alreadyPartitioned
+
+ leftLen, rightLen := mid-a, b-mid
+ balanceThreshold := length / 8
+ if leftLen < rightLen {
+ wasBalanced = leftLen >= balanceThreshold
+ pdqsortCmpFunc(data, a, mid, limit, cmp)
+ a = mid + 1
+ } else {
+ wasBalanced = rightLen >= balanceThreshold
+ pdqsortCmpFunc(data, mid+1, b, limit, cmp)
+ b = mid
+ }
+ }
+}
+
+// partitionCmpFunc does one quicksort partition.
+// Let p = data[pivot]
+// Moves elements in data[a:b] around, so that data[i]<p and data[j]>=p for i<newpivot and j>newpivot.
+// On return, data[newpivot] = p
+func partitionCmpFunc[E any](data []E, a, b, pivot int, cmp func(a, b E) int) (newpivot int, alreadyPartitioned bool) {
+ data[a], data[pivot] = data[pivot], data[a]
+ i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
+
+ for i <= j && (cmp(data[i], data[a]) < 0) {
+ i++
+ }
+ for i <= j && !(cmp(data[j], data[a]) < 0) {
+ j--
+ }
+ if i > j {
+ data[j], data[a] = data[a], data[j]
+ return j, true
+ }
+ data[i], data[j] = data[j], data[i]
+ i++
+ j--
+
+ for {
+ for i <= j && (cmp(data[i], data[a]) < 0) {
+ i++
+ }
+ for i <= j && !(cmp(data[j], data[a]) < 0) {
+ j--
+ }
+ if i > j {
+ break
+ }
+ data[i], data[j] = data[j], data[i]
+ i++
+ j--
+ }
+ data[j], data[a] = data[a], data[j]
+ return j, false
+}
+
+// partitionEqualCmpFunc partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot].
+// It assumed that data[a:b] does not contain elements smaller than the data[pivot].
+func partitionEqualCmpFunc[E any](data []E, a, b, pivot int, cmp func(a, b E) int) (newpivot int) {
+ data[a], data[pivot] = data[pivot], data[a]
+ i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
+
+ for {
+ for i <= j && !(cmp(data[a], data[i]) < 0) {
+ i++
+ }
+ for i <= j && (cmp(data[a], data[j]) < 0) {
+ j--
+ }
+ if i > j {
+ break
+ }
+ data[i], data[j] = data[j], data[i]
+ i++
+ j--
+ }
+ return i
+}
+
+// partialInsertionSortCmpFunc partially sorts a slice, returns true if the slice is sorted at the end.
+func partialInsertionSortCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) bool {
+ const (
+ maxSteps = 5 // maximum number of adjacent out-of-order pairs that will get shifted
+ shortestShifting = 50 // don't shift any elements on short arrays
+ )
+ i := a + 1
+ for j := 0; j < maxSteps; j++ {
+ for i < b && !(cmp(data[i], data[i-1]) < 0) {
+ i++
+ }
+
+ if i == b {
+ return true
+ }
+
+ if b-a < shortestShifting {
+ return false
+ }
+
+ data[i], data[i-1] = data[i-1], data[i]
+
+ // Shift the smaller one to the left.
+ if i-a >= 2 {
+ for j := i - 1; j >= 1; j-- {
+ if !(cmp(data[j], data[j-1]) < 0) {
+ break
+ }
+ data[j], data[j-1] = data[j-1], data[j]
+ }
+ }
+ // Shift the greater one to the right.
+ if b-i >= 2 {
+ for j := i + 1; j < b; j++ {
+ if !(cmp(data[j], data[j-1]) < 0) {
+ break
+ }
+ data[j], data[j-1] = data[j-1], data[j]
+ }
+ }
+ }
+ return false
+}
+
+// breakPatternsCmpFunc scatters some elements around in an attempt to break some patterns
+// that might cause imbalanced partitions in quicksort.
+func breakPatternsCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
+ length := b - a
+ if length >= 8 {
+ random := xorshift(length)
+ modulus := nextPowerOfTwo(length)
+
+ for idx := a + (length/4)*2 - 1; idx <= a+(length/4)*2+1; idx++ {
+ other := int(uint(random.Next()) & (modulus - 1))
+ if other >= length {
+ other -= length
+ }
+ data[idx], data[a+other] = data[a+other], data[idx]
+ }
+ }
+}
+
+// choosePivotCmpFunc chooses a pivot in data[a:b].
+//
+// [0,8): chooses a static pivot.
+// [8,shortestNinther): uses the simple median-of-three method.
+// [shortestNinther,∞): uses the Tukey ninther method.
+func choosePivotCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) (pivot int, hint sortedHint) {
+ const (
+ shortestNinther = 50
+ maxSwaps = 4 * 3
+ )
+
+ l := b - a
+
+ var (
+ swaps int
+ i = a + l/4*1
+ j = a + l/4*2
+ k = a + l/4*3
+ )
+
+ if l >= 8 {
+ if l >= shortestNinther {
+ // Tukey ninther method, the idea came from Rust's implementation.
+ i = medianAdjacentCmpFunc(data, i, &swaps, cmp)
+ j = medianAdjacentCmpFunc(data, j, &swaps, cmp)
+ k = medianAdjacentCmpFunc(data, k, &swaps, cmp)
+ }
+ // Find the median among i, j, k and stores it into j.
+ j = medianCmpFunc(data, i, j, k, &swaps, cmp)
+ }
+
+ switch swaps {
+ case 0:
+ return j, increasingHint
+ case maxSwaps:
+ return j, decreasingHint
+ default:
+ return j, unknownHint
+ }
+}
+
+// order2CmpFunc returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a.
+func order2CmpFunc[E any](data []E, a, b int, swaps *int, cmp func(a, b E) int) (int, int) {
+ if cmp(data[b], data[a]) < 0 {
+ *swaps++
+ return b, a
+ }
+ return a, b
+}
+
+// medianCmpFunc returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c.
+func medianCmpFunc[E any](data []E, a, b, c int, swaps *int, cmp func(a, b E) int) int {
+ a, b = order2CmpFunc(data, a, b, swaps, cmp)
+ b, c = order2CmpFunc(data, b, c, swaps, cmp)
+ a, b = order2CmpFunc(data, a, b, swaps, cmp)
+ return b
+}
+
+// medianAdjacentCmpFunc finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a.
+func medianAdjacentCmpFunc[E any](data []E, a int, swaps *int, cmp func(a, b E) int) int {
+ return medianCmpFunc(data, a-1, a, a+1, swaps, cmp)
+}
+
+func reverseRangeCmpFunc[E any](data []E, a, b int, cmp func(a, b E) int) {
+ i := a
+ j := b - 1
+ for i < j {
+ data[i], data[j] = data[j], data[i]
+ i++
+ j--
+ }
+}
+
+func swapRangeCmpFunc[E any](data []E, a, b, n int, cmp func(a, b E) int) {
+ for i := 0; i < n; i++ {
+ data[a+i], data[b+i] = data[b+i], data[a+i]
+ }
+}
+
+func stableCmpFunc[E any](data []E, n int, cmp func(a, b E) int) {
+ blockSize := 20 // must be > 0
+ a, b := 0, blockSize
+ for b <= n {
+ insertionSortCmpFunc(data, a, b, cmp)
+ a = b
+ b += blockSize
+ }
+ insertionSortCmpFunc(data, a, n, cmp)
+
+ for blockSize < n {
+ a, b = 0, 2*blockSize
+ for b <= n {
+ symMergeCmpFunc(data, a, a+blockSize, b, cmp)
+ a = b
+ b += 2 * blockSize
+ }
+ if m := a + blockSize; m < n {
+ symMergeCmpFunc(data, a, m, n, cmp)
+ }
+ blockSize *= 2
+ }
+}
+
+// symMergeCmpFunc merges the two sorted subsequences data[a:m] and data[m:b] using
+// the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum
+// Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz
+// Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in
+// Computer Science, pages 714-723. Springer, 2004.
+//
+// Let M = m-a and N = b-n. Wolog M < N.
+// The recursion depth is bound by ceil(log(N+M)).
+// The algorithm needs O(M*log(N/M + 1)) calls to data.Less.
+// The algorithm needs O((M+N)*log(M)) calls to data.Swap.
+//
+// The paper gives O((M+N)*log(M)) as the number of assignments assuming a
+// rotation algorithm which uses O(M+N+gcd(M+N)) assignments. The argumentation
+// in the paper carries through for Swap operations, especially as the block
+// swapping rotate uses only O(M+N) Swaps.
+//
+// symMerge assumes non-degenerate arguments: a < m && m < b.
+// Having the caller check this condition eliminates many leaf recursion calls,
+// which improves performance.
+func symMergeCmpFunc[E any](data []E, a, m, b int, cmp func(a, b E) int) {
+ // Avoid unnecessary recursions of symMerge
+ // by direct insertion of data[a] into data[m:b]
+ // if data[a:m] only contains one element.
+ if m-a == 1 {
+ // Use binary search to find the lowest index i
+ // such that data[i] >= data[a] for m <= i < b.
+ // Exit the search loop with i == b in case no such index exists.
+ i := m
+ j := b
+ for i < j {
+ h := int(uint(i+j) >> 1)
+ if cmp(data[h], data[a]) < 0 {
+ i = h + 1
+ } else {
+ j = h
+ }
+ }
+ // Swap values until data[a] reaches the position before i.
+ for k := a; k < i-1; k++ {
+ data[k], data[k+1] = data[k+1], data[k]
+ }
+ return
+ }
+
+ // Avoid unnecessary recursions of symMerge
+ // by direct insertion of data[m] into data[a:m]
+ // if data[m:b] only contains one element.
+ if b-m == 1 {
+ // Use binary search to find the lowest index i
+ // such that data[i] > data[m] for a <= i < m.
+ // Exit the search loop with i == m in case no such index exists.
+ i := a
+ j := m
+ for i < j {
+ h := int(uint(i+j) >> 1)
+ if !(cmp(data[m], data[h]) < 0) {
+ i = h + 1
+ } else {
+ j = h
+ }
+ }
+ // Swap values until data[m] reaches the position i.
+ for k := m; k > i; k-- {
+ data[k], data[k-1] = data[k-1], data[k]
+ }
+ return
+ }
+
+ mid := int(uint(a+b) >> 1)
+ n := mid + m
+ var start, r int
+ if m > mid {
+ start = n - b
+ r = mid
+ } else {
+ start = a
+ r = m
+ }
+ p := n - 1
+
+ for start < r {
+ c := int(uint(start+r) >> 1)
+ if !(cmp(data[p-c], data[c]) < 0) {
+ start = c + 1
+ } else {
+ r = c
+ }
+ }
+
+ end := n - start
+ if start < m && m < end {
+ rotateCmpFunc(data, start, m, end, cmp)
+ }
+ if a < start && start < mid {
+ symMergeCmpFunc(data, a, start, mid, cmp)
+ }
+ if mid < end && end < b {
+ symMergeCmpFunc(data, mid, end, b, cmp)
+ }
+}
+
+// rotateCmpFunc rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data:
+// Data of the form 'x u v y' is changed to 'x v u y'.
+// rotate performs at most b-a many calls to data.Swap,
+// and it assumes non-degenerate arguments: a < m && m < b.
+func rotateCmpFunc[E any](data []E, a, m, b int, cmp func(a, b E) int) {
+ i := m - a
+ j := b - m
+
+ for i != j {
+ if i > j {
+ swapRangeCmpFunc(data, m-i, m, j, cmp)
+ i -= j
+ } else {
+ swapRangeCmpFunc(data, m-i, m+j-i, i, cmp)
+ j -= i
+ }
+ }
+ // i == j
+ swapRangeCmpFunc(data, m-i, m, i, cmp)
+}
diff --git a/contrib/go/_std_1.21/src/slices/zsortordered.go b/contrib/go/_std_1.21/src/slices/zsortordered.go
new file mode 100644
index 0000000000..0822dbc6de
--- /dev/null
+++ b/contrib/go/_std_1.21/src/slices/zsortordered.go
@@ -0,0 +1,481 @@
+// Code generated by gen_sort_variants.go; DO NOT EDIT.
+
+// Copyright 2022 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 slices
+
+import "cmp"
+
+// insertionSortOrdered sorts data[a:b] using insertion sort.
+func insertionSortOrdered[E cmp.Ordered](data []E, a, b int) {
+ for i := a + 1; i < b; i++ {
+ for j := i; j > a && cmp.Less(data[j], data[j-1]); j-- {
+ data[j], data[j-1] = data[j-1], data[j]
+ }
+ }
+}
+
+// siftDownOrdered implements the heap property on data[lo:hi].
+// first is an offset into the array where the root of the heap lies.
+func siftDownOrdered[E cmp.Ordered](data []E, lo, hi, first int) {
+ root := lo
+ for {
+ child := 2*root + 1
+ if child >= hi {
+ break
+ }
+ if child+1 < hi && cmp.Less(data[first+child], data[first+child+1]) {
+ child++
+ }
+ if !cmp.Less(data[first+root], data[first+child]) {
+ return
+ }
+ data[first+root], data[first+child] = data[first+child], data[first+root]
+ root = child
+ }
+}
+
+func heapSortOrdered[E cmp.Ordered](data []E, a, b int) {
+ first := a
+ lo := 0
+ hi := b - a
+
+ // Build heap with greatest element at top.
+ for i := (hi - 1) / 2; i >= 0; i-- {
+ siftDownOrdered(data, i, hi, first)
+ }
+
+ // Pop elements, largest first, into end of data.
+ for i := hi - 1; i >= 0; i-- {
+ data[first], data[first+i] = data[first+i], data[first]
+ siftDownOrdered(data, lo, i, first)
+ }
+}
+
+// pdqsortOrdered sorts data[a:b].
+// The algorithm based on pattern-defeating quicksort(pdqsort), but without the optimizations from BlockQuicksort.
+// pdqsort paper: https://arxiv.org/pdf/2106.05123.pdf
+// C++ implementation: https://github.com/orlp/pdqsort
+// Rust implementation: https://docs.rs/pdqsort/latest/pdqsort/
+// limit is the number of allowed bad (very unbalanced) pivots before falling back to heapsort.
+func pdqsortOrdered[E cmp.Ordered](data []E, a, b, limit int) {
+ const maxInsertion = 12
+
+ var (
+ wasBalanced = true // whether the last partitioning was reasonably balanced
+ wasPartitioned = true // whether the slice was already partitioned
+ )
+
+ for {
+ length := b - a
+
+ if length <= maxInsertion {
+ insertionSortOrdered(data, a, b)
+ return
+ }
+
+ // Fall back to heapsort if too many bad choices were made.
+ if limit == 0 {
+ heapSortOrdered(data, a, b)
+ return
+ }
+
+ // If the last partitioning was imbalanced, we need to breaking patterns.
+ if !wasBalanced {
+ breakPatternsOrdered(data, a, b)
+ limit--
+ }
+
+ pivot, hint := choosePivotOrdered(data, a, b)
+ if hint == decreasingHint {
+ reverseRangeOrdered(data, a, b)
+ // The chosen pivot was pivot-a elements after the start of the array.
+ // After reversing it is pivot-a elements before the end of the array.
+ // The idea came from Rust's implementation.
+ pivot = (b - 1) - (pivot - a)
+ hint = increasingHint
+ }
+
+ // The slice is likely already sorted.
+ if wasBalanced && wasPartitioned && hint == increasingHint {
+ if partialInsertionSortOrdered(data, a, b) {
+ return
+ }
+ }
+
+ // Probably the slice contains many duplicate elements, partition the slice into
+ // elements equal to and elements greater than the pivot.
+ if a > 0 && !cmp.Less(data[a-1], data[pivot]) {
+ mid := partitionEqualOrdered(data, a, b, pivot)
+ a = mid
+ continue
+ }
+
+ mid, alreadyPartitioned := partitionOrdered(data, a, b, pivot)
+ wasPartitioned = alreadyPartitioned
+
+ leftLen, rightLen := mid-a, b-mid
+ balanceThreshold := length / 8
+ if leftLen < rightLen {
+ wasBalanced = leftLen >= balanceThreshold
+ pdqsortOrdered(data, a, mid, limit)
+ a = mid + 1
+ } else {
+ wasBalanced = rightLen >= balanceThreshold
+ pdqsortOrdered(data, mid+1, b, limit)
+ b = mid
+ }
+ }
+}
+
+// partitionOrdered does one quicksort partition.
+// Let p = data[pivot]
+// Moves elements in data[a:b] around, so that data[i]<p and data[j]>=p for i<newpivot and j>newpivot.
+// On return, data[newpivot] = p
+func partitionOrdered[E cmp.Ordered](data []E, a, b, pivot int) (newpivot int, alreadyPartitioned bool) {
+ data[a], data[pivot] = data[pivot], data[a]
+ i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
+
+ for i <= j && cmp.Less(data[i], data[a]) {
+ i++
+ }
+ for i <= j && !cmp.Less(data[j], data[a]) {
+ j--
+ }
+ if i > j {
+ data[j], data[a] = data[a], data[j]
+ return j, true
+ }
+ data[i], data[j] = data[j], data[i]
+ i++
+ j--
+
+ for {
+ for i <= j && cmp.Less(data[i], data[a]) {
+ i++
+ }
+ for i <= j && !cmp.Less(data[j], data[a]) {
+ j--
+ }
+ if i > j {
+ break
+ }
+ data[i], data[j] = data[j], data[i]
+ i++
+ j--
+ }
+ data[j], data[a] = data[a], data[j]
+ return j, false
+}
+
+// partitionEqualOrdered partitions data[a:b] into elements equal to data[pivot] followed by elements greater than data[pivot].
+// It assumed that data[a:b] does not contain elements smaller than the data[pivot].
+func partitionEqualOrdered[E cmp.Ordered](data []E, a, b, pivot int) (newpivot int) {
+ data[a], data[pivot] = data[pivot], data[a]
+ i, j := a+1, b-1 // i and j are inclusive of the elements remaining to be partitioned
+
+ for {
+ for i <= j && !cmp.Less(data[a], data[i]) {
+ i++
+ }
+ for i <= j && cmp.Less(data[a], data[j]) {
+ j--
+ }
+ if i > j {
+ break
+ }
+ data[i], data[j] = data[j], data[i]
+ i++
+ j--
+ }
+ return i
+}
+
+// partialInsertionSortOrdered partially sorts a slice, returns true if the slice is sorted at the end.
+func partialInsertionSortOrdered[E cmp.Ordered](data []E, a, b int) bool {
+ const (
+ maxSteps = 5 // maximum number of adjacent out-of-order pairs that will get shifted
+ shortestShifting = 50 // don't shift any elements on short arrays
+ )
+ i := a + 1
+ for j := 0; j < maxSteps; j++ {
+ for i < b && !cmp.Less(data[i], data[i-1]) {
+ i++
+ }
+
+ if i == b {
+ return true
+ }
+
+ if b-a < shortestShifting {
+ return false
+ }
+
+ data[i], data[i-1] = data[i-1], data[i]
+
+ // Shift the smaller one to the left.
+ if i-a >= 2 {
+ for j := i - 1; j >= 1; j-- {
+ if !cmp.Less(data[j], data[j-1]) {
+ break
+ }
+ data[j], data[j-1] = data[j-1], data[j]
+ }
+ }
+ // Shift the greater one to the right.
+ if b-i >= 2 {
+ for j := i + 1; j < b; j++ {
+ if !cmp.Less(data[j], data[j-1]) {
+ break
+ }
+ data[j], data[j-1] = data[j-1], data[j]
+ }
+ }
+ }
+ return false
+}
+
+// breakPatternsOrdered scatters some elements around in an attempt to break some patterns
+// that might cause imbalanced partitions in quicksort.
+func breakPatternsOrdered[E cmp.Ordered](data []E, a, b int) {
+ length := b - a
+ if length >= 8 {
+ random := xorshift(length)
+ modulus := nextPowerOfTwo(length)
+
+ for idx := a + (length/4)*2 - 1; idx <= a+(length/4)*2+1; idx++ {
+ other := int(uint(random.Next()) & (modulus - 1))
+ if other >= length {
+ other -= length
+ }
+ data[idx], data[a+other] = data[a+other], data[idx]
+ }
+ }
+}
+
+// choosePivotOrdered chooses a pivot in data[a:b].
+//
+// [0,8): chooses a static pivot.
+// [8,shortestNinther): uses the simple median-of-three method.
+// [shortestNinther,∞): uses the Tukey ninther method.
+func choosePivotOrdered[E cmp.Ordered](data []E, a, b int) (pivot int, hint sortedHint) {
+ const (
+ shortestNinther = 50
+ maxSwaps = 4 * 3
+ )
+
+ l := b - a
+
+ var (
+ swaps int
+ i = a + l/4*1
+ j = a + l/4*2
+ k = a + l/4*3
+ )
+
+ if l >= 8 {
+ if l >= shortestNinther {
+ // Tukey ninther method, the idea came from Rust's implementation.
+ i = medianAdjacentOrdered(data, i, &swaps)
+ j = medianAdjacentOrdered(data, j, &swaps)
+ k = medianAdjacentOrdered(data, k, &swaps)
+ }
+ // Find the median among i, j, k and stores it into j.
+ j = medianOrdered(data, i, j, k, &swaps)
+ }
+
+ switch swaps {
+ case 0:
+ return j, increasingHint
+ case maxSwaps:
+ return j, decreasingHint
+ default:
+ return j, unknownHint
+ }
+}
+
+// order2Ordered returns x,y where data[x] <= data[y], where x,y=a,b or x,y=b,a.
+func order2Ordered[E cmp.Ordered](data []E, a, b int, swaps *int) (int, int) {
+ if cmp.Less(data[b], data[a]) {
+ *swaps++
+ return b, a
+ }
+ return a, b
+}
+
+// medianOrdered returns x where data[x] is the median of data[a],data[b],data[c], where x is a, b, or c.
+func medianOrdered[E cmp.Ordered](data []E, a, b, c int, swaps *int) int {
+ a, b = order2Ordered(data, a, b, swaps)
+ b, c = order2Ordered(data, b, c, swaps)
+ a, b = order2Ordered(data, a, b, swaps)
+ return b
+}
+
+// medianAdjacentOrdered finds the median of data[a - 1], data[a], data[a + 1] and stores the index into a.
+func medianAdjacentOrdered[E cmp.Ordered](data []E, a int, swaps *int) int {
+ return medianOrdered(data, a-1, a, a+1, swaps)
+}
+
+func reverseRangeOrdered[E cmp.Ordered](data []E, a, b int) {
+ i := a
+ j := b - 1
+ for i < j {
+ data[i], data[j] = data[j], data[i]
+ i++
+ j--
+ }
+}
+
+func swapRangeOrdered[E cmp.Ordered](data []E, a, b, n int) {
+ for i := 0; i < n; i++ {
+ data[a+i], data[b+i] = data[b+i], data[a+i]
+ }
+}
+
+func stableOrdered[E cmp.Ordered](data []E, n int) {
+ blockSize := 20 // must be > 0
+ a, b := 0, blockSize
+ for b <= n {
+ insertionSortOrdered(data, a, b)
+ a = b
+ b += blockSize
+ }
+ insertionSortOrdered(data, a, n)
+
+ for blockSize < n {
+ a, b = 0, 2*blockSize
+ for b <= n {
+ symMergeOrdered(data, a, a+blockSize, b)
+ a = b
+ b += 2 * blockSize
+ }
+ if m := a + blockSize; m < n {
+ symMergeOrdered(data, a, m, n)
+ }
+ blockSize *= 2
+ }
+}
+
+// symMergeOrdered merges the two sorted subsequences data[a:m] and data[m:b] using
+// the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum
+// Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz
+// Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in
+// Computer Science, pages 714-723. Springer, 2004.
+//
+// Let M = m-a and N = b-n. Wolog M < N.
+// The recursion depth is bound by ceil(log(N+M)).
+// The algorithm needs O(M*log(N/M + 1)) calls to data.Less.
+// The algorithm needs O((M+N)*log(M)) calls to data.Swap.
+//
+// The paper gives O((M+N)*log(M)) as the number of assignments assuming a
+// rotation algorithm which uses O(M+N+gcd(M+N)) assignments. The argumentation
+// in the paper carries through for Swap operations, especially as the block
+// swapping rotate uses only O(M+N) Swaps.
+//
+// symMerge assumes non-degenerate arguments: a < m && m < b.
+// Having the caller check this condition eliminates many leaf recursion calls,
+// which improves performance.
+func symMergeOrdered[E cmp.Ordered](data []E, a, m, b int) {
+ // Avoid unnecessary recursions of symMerge
+ // by direct insertion of data[a] into data[m:b]
+ // if data[a:m] only contains one element.
+ if m-a == 1 {
+ // Use binary search to find the lowest index i
+ // such that data[i] >= data[a] for m <= i < b.
+ // Exit the search loop with i == b in case no such index exists.
+ i := m
+ j := b
+ for i < j {
+ h := int(uint(i+j) >> 1)
+ if cmp.Less(data[h], data[a]) {
+ i = h + 1
+ } else {
+ j = h
+ }
+ }
+ // Swap values until data[a] reaches the position before i.
+ for k := a; k < i-1; k++ {
+ data[k], data[k+1] = data[k+1], data[k]
+ }
+ return
+ }
+
+ // Avoid unnecessary recursions of symMerge
+ // by direct insertion of data[m] into data[a:m]
+ // if data[m:b] only contains one element.
+ if b-m == 1 {
+ // Use binary search to find the lowest index i
+ // such that data[i] > data[m] for a <= i < m.
+ // Exit the search loop with i == m in case no such index exists.
+ i := a
+ j := m
+ for i < j {
+ h := int(uint(i+j) >> 1)
+ if !cmp.Less(data[m], data[h]) {
+ i = h + 1
+ } else {
+ j = h
+ }
+ }
+ // Swap values until data[m] reaches the position i.
+ for k := m; k > i; k-- {
+ data[k], data[k-1] = data[k-1], data[k]
+ }
+ return
+ }
+
+ mid := int(uint(a+b) >> 1)
+ n := mid + m
+ var start, r int
+ if m > mid {
+ start = n - b
+ r = mid
+ } else {
+ start = a
+ r = m
+ }
+ p := n - 1
+
+ for start < r {
+ c := int(uint(start+r) >> 1)
+ if !cmp.Less(data[p-c], data[c]) {
+ start = c + 1
+ } else {
+ r = c
+ }
+ }
+
+ end := n - start
+ if start < m && m < end {
+ rotateOrdered(data, start, m, end)
+ }
+ if a < start && start < mid {
+ symMergeOrdered(data, a, start, mid)
+ }
+ if mid < end && end < b {
+ symMergeOrdered(data, mid, end, b)
+ }
+}
+
+// rotateOrdered rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data:
+// Data of the form 'x u v y' is changed to 'x v u y'.
+// rotate performs at most b-a many calls to data.Swap,
+// and it assumes non-degenerate arguments: a < m && m < b.
+func rotateOrdered[E cmp.Ordered](data []E, a, m, b int) {
+ i := m - a
+ j := b - m
+
+ for i != j {
+ if i > j {
+ swapRangeOrdered(data, m-i, m, j)
+ i -= j
+ } else {
+ swapRangeOrdered(data, m-i, m+j-i, i)
+ j -= i
+ }
+ }
+ // i == j
+ swapRangeOrdered(data, m-i, m, i)
+}
diff --git a/contrib/go/_std_1.20/src/sort/search.go b/contrib/go/_std_1.21/src/sort/search.go
index 874e40813d..874e40813d 100644
--- a/contrib/go/_std_1.20/src/sort/search.go
+++ b/contrib/go/_std_1.21/src/sort/search.go
diff --git a/contrib/go/_std_1.20/src/sort/slice.go b/contrib/go/_std_1.21/src/sort/slice.go
index d0b2102013..d0b2102013 100644
--- a/contrib/go/_std_1.20/src/sort/slice.go
+++ b/contrib/go/_std_1.21/src/sort/slice.go
diff --git a/contrib/go/_std_1.21/src/sort/sort.go b/contrib/go/_std_1.21/src/sort/sort.go
new file mode 100644
index 0000000000..1760e12c25
--- /dev/null
+++ b/contrib/go/_std_1.21/src/sort/sort.go
@@ -0,0 +1,283 @@
+// Copyright 2009 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.
+
+//go:generate go run gen_sort_variants.go
+
+// Package sort provides primitives for sorting slices and user-defined collections.
+package sort
+
+import "math/bits"
+
+// An implementation of Interface can be sorted by the routines in this package.
+// The methods refer to elements of the underlying collection by integer index.
+type Interface interface {
+ // Len is the number of elements in the collection.
+ Len() int
+
+ // Less reports whether the element with index i
+ // must sort before the element with index j.
+ //
+ // If both Less(i, j) and Less(j, i) are false,
+ // then the elements at index i and j are considered equal.
+ // Sort may place equal elements in any order in the final result,
+ // while Stable preserves the original input order of equal elements.
+ //
+ // Less must describe a transitive ordering:
+ // - if both Less(i, j) and Less(j, k) are true, then Less(i, k) must be true as well.
+ // - if both Less(i, j) and Less(j, k) are false, then Less(i, k) must be false as well.
+ //
+ // Note that floating-point comparison (the < operator on float32 or float64 values)
+ // is not a transitive ordering when not-a-number (NaN) values are involved.
+ // See Float64Slice.Less for a correct implementation for floating-point values.
+ Less(i, j int) bool
+
+ // Swap swaps the elements with indexes i and j.
+ Swap(i, j int)
+}
+
+// Sort sorts data in ascending order as determined by the Less method.
+// It makes one call to data.Len to determine n and O(n*log(n)) calls to
+// data.Less and data.Swap. The sort is not guaranteed to be stable.
+//
+// Note: in many situations, the newer slices.SortFunc function is more
+// ergonomic and runs faster.
+func Sort(data Interface) {
+ n := data.Len()
+ if n <= 1 {
+ return
+ }
+ limit := bits.Len(uint(n))
+ pdqsort(data, 0, n, limit)
+}
+
+type sortedHint int // hint for pdqsort when choosing the pivot
+
+const (
+ unknownHint sortedHint = iota
+ increasingHint
+ decreasingHint
+)
+
+// xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
+type xorshift uint64
+
+func (r *xorshift) Next() uint64 {
+ *r ^= *r << 13
+ *r ^= *r >> 17
+ *r ^= *r << 5
+ return uint64(*r)
+}
+
+func nextPowerOfTwo(length int) uint {
+ shift := uint(bits.Len(uint(length)))
+ return uint(1 << shift)
+}
+
+// lessSwap is a pair of Less and Swap function for use with the
+// auto-generated func-optimized variant of sort.go in
+// zfuncversion.go.
+type lessSwap struct {
+ Less func(i, j int) bool
+ Swap func(i, j int)
+}
+
+type reverse struct {
+ // This embedded Interface permits Reverse to use the methods of
+ // another Interface implementation.
+ Interface
+}
+
+// Less returns the opposite of the embedded implementation's Less method.
+func (r reverse) Less(i, j int) bool {
+ return r.Interface.Less(j, i)
+}
+
+// Reverse returns the reverse order for data.
+func Reverse(data Interface) Interface {
+ return &reverse{data}
+}
+
+// IsSorted reports whether data is sorted.
+//
+// Note: in many situations, the newer slices.IsSortedFunc function is more
+// ergonomic and runs faster.
+func IsSorted(data Interface) bool {
+ n := data.Len()
+ for i := n - 1; i > 0; i-- {
+ if data.Less(i, i-1) {
+ return false
+ }
+ }
+ return true
+}
+
+// Convenience types for common cases
+
+// IntSlice attaches the methods of Interface to []int, sorting in increasing order.
+type IntSlice []int
+
+func (x IntSlice) Len() int { return len(x) }
+func (x IntSlice) Less(i, j int) bool { return x[i] < x[j] }
+func (x IntSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+// Sort is a convenience method: x.Sort() calls Sort(x).
+func (x IntSlice) Sort() { Sort(x) }
+
+// Float64Slice implements Interface for a []float64, sorting in increasing order,
+// with not-a-number (NaN) values ordered before other values.
+type Float64Slice []float64
+
+func (x Float64Slice) Len() int { return len(x) }
+
+// Less reports whether x[i] should be ordered before x[j], as required by the sort Interface.
+// Note that floating-point comparison by itself is not a transitive relation: it does not
+// report a consistent ordering for not-a-number (NaN) values.
+// This implementation of Less places NaN values before any others, by using:
+//
+// x[i] < x[j] || (math.IsNaN(x[i]) && !math.IsNaN(x[j]))
+func (x Float64Slice) Less(i, j int) bool { return x[i] < x[j] || (isNaN(x[i]) && !isNaN(x[j])) }
+func (x Float64Slice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+// isNaN is a copy of math.IsNaN to avoid a dependency on the math package.
+func isNaN(f float64) bool {
+ return f != f
+}
+
+// Sort is a convenience method: x.Sort() calls Sort(x).
+func (x Float64Slice) Sort() { Sort(x) }
+
+// StringSlice attaches the methods of Interface to []string, sorting in increasing order.
+type StringSlice []string
+
+func (x StringSlice) Len() int { return len(x) }
+func (x StringSlice) Less(i, j int) bool { return x[i] < x[j] }
+func (x StringSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+// Sort is a convenience method: x.Sort() calls Sort(x).
+func (x StringSlice) Sort() { Sort(x) }
+
+// Convenience wrappers for common cases
+
+// Ints sorts a slice of ints in increasing order.
+//
+// Note: consider using the newer slices.Sort function, which runs faster.
+func Ints(x []int) { Sort(IntSlice(x)) }
+
+// Float64s sorts a slice of float64s in increasing order.
+// Not-a-number (NaN) values are ordered before other values.
+//
+// Note: consider using the newer slices.Sort function, which runs faster.
+func Float64s(x []float64) { Sort(Float64Slice(x)) }
+
+// Strings sorts a slice of strings in increasing order.
+//
+// Note: consider using the newer slices.Sort function, which runs faster.
+func Strings(x []string) { Sort(StringSlice(x)) }
+
+// IntsAreSorted reports whether the slice x is sorted in increasing order.
+//
+// Note: consider using the newer slices.IsSorted function, which runs faster.
+func IntsAreSorted(x []int) bool { return IsSorted(IntSlice(x)) }
+
+// Float64sAreSorted reports whether the slice x is sorted in increasing order,
+// with not-a-number (NaN) values before any other values.
+//
+// Note: consider using the newer slices.IsSorted function, which runs faster.
+func Float64sAreSorted(x []float64) bool { return IsSorted(Float64Slice(x)) }
+
+// StringsAreSorted reports whether the slice x is sorted in increasing order.
+//
+// Note: consider using the newer slices.IsSorted function, which runs faster.
+func StringsAreSorted(x []string) bool { return IsSorted(StringSlice(x)) }
+
+// Notes on stable sorting:
+// The used algorithms are simple and provable correct on all input and use
+// only logarithmic additional stack space. They perform well if compared
+// experimentally to other stable in-place sorting algorithms.
+//
+// Remarks on other algorithms evaluated:
+// - GCC's 4.6.3 stable_sort with merge_without_buffer from libstdc++:
+// Not faster.
+// - GCC's __rotate for block rotations: Not faster.
+// - "Practical in-place mergesort" from Jyrki Katajainen, Tomi A. Pasanen
+// and Jukka Teuhola; Nordic Journal of Computing 3,1 (1996), 27-40:
+// The given algorithms are in-place, number of Swap and Assignments
+// grow as n log n but the algorithm is not stable.
+// - "Fast Stable In-Place Sorting with O(n) Data Moves" J.I. Munro and
+// V. Raman in Algorithmica (1996) 16, 115-160:
+// This algorithm either needs additional 2n bits or works only if there
+// are enough different elements available to encode some permutations
+// which have to be undone later (so not stable on any input).
+// - All the optimal in-place sorting/merging algorithms I found are either
+// unstable or rely on enough different elements in each step to encode the
+// performed block rearrangements. See also "In-Place Merging Algorithms",
+// Denham Coates-Evely, Department of Computer Science, Kings College,
+// January 2004 and the references in there.
+// - Often "optimal" algorithms are optimal in the number of assignments
+// but Interface has only Swap as operation.
+
+// Stable sorts data in ascending order as determined by the Less method,
+// while keeping the original order of equal elements.
+//
+// It makes one call to data.Len to determine n, O(n*log(n)) calls to
+// data.Less and O(n*log(n)*log(n)) calls to data.Swap.
+//
+// Note: in many situations, the newer slices.SortStableFunc function is more
+// ergonomic and runs faster.
+func Stable(data Interface) {
+ stable(data, data.Len())
+}
+
+/*
+Complexity of Stable Sorting
+
+
+Complexity of block swapping rotation
+
+Each Swap puts one new element into its correct, final position.
+Elements which reach their final position are no longer moved.
+Thus block swapping rotation needs |u|+|v| calls to Swaps.
+This is best possible as each element might need a move.
+
+Pay attention when comparing to other optimal algorithms which
+typically count the number of assignments instead of swaps:
+E.g. the optimal algorithm of Dudzinski and Dydek for in-place
+rotations uses O(u + v + gcd(u,v)) assignments which is
+better than our O(3 * (u+v)) as gcd(u,v) <= u.
+
+
+Stable sorting by SymMerge and BlockSwap rotations
+
+SymMerg complexity for same size input M = N:
+Calls to Less: O(M*log(N/M+1)) = O(N*log(2)) = O(N)
+Calls to Swap: O((M+N)*log(M)) = O(2*N*log(N)) = O(N*log(N))
+
+(The following argument does not fuzz over a missing -1 or
+other stuff which does not impact the final result).
+
+Let n = data.Len(). Assume n = 2^k.
+
+Plain merge sort performs log(n) = k iterations.
+On iteration i the algorithm merges 2^(k-i) blocks, each of size 2^i.
+
+Thus iteration i of merge sort performs:
+Calls to Less O(2^(k-i) * 2^i) = O(2^k) = O(2^log(n)) = O(n)
+Calls to Swap O(2^(k-i) * 2^i * log(2^i)) = O(2^k * i) = O(n*i)
+
+In total k = log(n) iterations are performed; so in total:
+Calls to Less O(log(n) * n)
+Calls to Swap O(n + 2*n + 3*n + ... + (k-1)*n + k*n)
+ = O((k/2) * k * n) = O(n * k^2) = O(n * log^2(n))
+
+
+Above results should generalize to arbitrary n = 2^k + p
+and should not be influenced by the initial insertion sort phase:
+Insertion sort is O(n^2) on Swap and Less, thus O(bs^2) per block of
+size bs at n/bs blocks: O(bs*n) Swaps and Less during insertion sort.
+Merge sort iterations start at i = log(bs). With t = log(bs) constant:
+Calls to Less O((log(n)-t) * n + bs*n) = O(log(n)*n + (bs-t)*n)
+ = O(n * log(n))
+Calls to Swap O(n * log^2(n) - (t^2+t)/2*n) = O(n * log^2(n))
+
+*/
diff --git a/contrib/go/_std_1.21/src/sort/ya.make b/contrib/go/_std_1.21/src/sort/ya.make
new file mode 100644
index 0000000000..2148cdfd6f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/sort/ya.make
@@ -0,0 +1,27 @@
+GO_LIBRARY()
+
+SRCS(
+ search.go
+ slice.go
+ sort.go
+ zsortfunc.go
+ zsortinterface.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ example_interface_test.go
+ example_keys_test.go
+ example_multi_test.go
+ example_search_test.go
+ example_test.go
+ example_wrapper_test.go
+ search_test.go
+ sort_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/sort/zsortfunc.go b/contrib/go/_std_1.21/src/sort/zsortfunc.go
index 49b6169b97..49b6169b97 100644
--- a/contrib/go/_std_1.20/src/sort/zsortfunc.go
+++ b/contrib/go/_std_1.21/src/sort/zsortfunc.go
diff --git a/contrib/go/_std_1.20/src/sort/zsortinterface.go b/contrib/go/_std_1.21/src/sort/zsortinterface.go
index 51fa5032e9..51fa5032e9 100644
--- a/contrib/go/_std_1.20/src/sort/zsortinterface.go
+++ b/contrib/go/_std_1.21/src/sort/zsortinterface.go
diff --git a/contrib/go/_std_1.20/src/strconv/atob.go b/contrib/go/_std_1.21/src/strconv/atob.go
index 0a495008d7..0a495008d7 100644
--- a/contrib/go/_std_1.20/src/strconv/atob.go
+++ b/contrib/go/_std_1.21/src/strconv/atob.go
diff --git a/contrib/go/_std_1.20/src/strconv/atoc.go b/contrib/go/_std_1.21/src/strconv/atoc.go
index f6fdd14e64..f6fdd14e64 100644
--- a/contrib/go/_std_1.20/src/strconv/atoc.go
+++ b/contrib/go/_std_1.21/src/strconv/atoc.go
diff --git a/contrib/go/_std_1.20/src/strconv/atof.go b/contrib/go/_std_1.21/src/strconv/atof.go
index 8fc90425f6..8fc90425f6 100644
--- a/contrib/go/_std_1.20/src/strconv/atof.go
+++ b/contrib/go/_std_1.21/src/strconv/atof.go
diff --git a/contrib/go/_std_1.20/src/strconv/atoi.go b/contrib/go/_std_1.21/src/strconv/atoi.go
index 520d826323..520d826323 100644
--- a/contrib/go/_std_1.20/src/strconv/atoi.go
+++ b/contrib/go/_std_1.21/src/strconv/atoi.go
diff --git a/contrib/go/_std_1.20/src/strconv/bytealg.go b/contrib/go/_std_1.21/src/strconv/bytealg.go
index a2bb12c5f2..a2bb12c5f2 100644
--- a/contrib/go/_std_1.20/src/strconv/bytealg.go
+++ b/contrib/go/_std_1.21/src/strconv/bytealg.go
diff --git a/contrib/go/_std_1.20/src/strconv/ctoa.go b/contrib/go/_std_1.21/src/strconv/ctoa.go
index c16a2e579c..c16a2e579c 100644
--- a/contrib/go/_std_1.20/src/strconv/ctoa.go
+++ b/contrib/go/_std_1.21/src/strconv/ctoa.go
diff --git a/contrib/go/_std_1.20/src/strconv/decimal.go b/contrib/go/_std_1.21/src/strconv/decimal.go
index b58001888e..b58001888e 100644
--- a/contrib/go/_std_1.20/src/strconv/decimal.go
+++ b/contrib/go/_std_1.21/src/strconv/decimal.go
diff --git a/contrib/go/_std_1.21/src/strconv/doc.go b/contrib/go/_std_1.21/src/strconv/doc.go
new file mode 100644
index 0000000000..fa20f902d0
--- /dev/null
+++ b/contrib/go/_std_1.21/src/strconv/doc.go
@@ -0,0 +1,56 @@
+// Copyright 2015 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 strconv implements conversions to and from string representations
+// of basic data types.
+//
+// # Numeric Conversions
+//
+// The most common numeric conversions are Atoi (string to int) and Itoa (int to string).
+//
+// i, err := strconv.Atoi("-42")
+// s := strconv.Itoa(-42)
+//
+// These assume decimal and the Go int type.
+//
+// [ParseBool], [ParseFloat], [ParseInt], and [ParseUint] convert strings to values:
+//
+// b, err := strconv.ParseBool("true")
+// f, err := strconv.ParseFloat("3.1415", 64)
+// i, err := strconv.ParseInt("-42", 10, 64)
+// u, err := strconv.ParseUint("42", 10, 64)
+//
+// The parse functions return the widest type (float64, int64, and uint64),
+// but if the size argument specifies a narrower width the result can be
+// converted to that narrower type without data loss:
+//
+// s := "2147483647" // biggest int32
+// i64, err := strconv.ParseInt(s, 10, 32)
+// ...
+// i := int32(i64)
+//
+// [FormatBool], [FormatFloat], [FormatInt], and [FormatUint] convert values to strings:
+//
+// s := strconv.FormatBool(true)
+// s := strconv.FormatFloat(3.1415, 'E', -1, 64)
+// s := strconv.FormatInt(-42, 16)
+// s := strconv.FormatUint(42, 16)
+//
+// [AppendBool], [AppendFloat], [AppendInt], and [AppendUint] are similar but
+// append the formatted value to a destination slice.
+//
+// # String Conversions
+//
+// [Quote] and [QuoteToASCII] convert strings to quoted Go string literals.
+// The latter guarantees that the result is an ASCII string, by escaping
+// any non-ASCII Unicode with \u:
+//
+// q := strconv.Quote("Hello, 世界")
+// q := strconv.QuoteToASCII("Hello, 世界")
+//
+// [QuoteRune] and [QuoteRuneToASCII] are similar but accept runes and
+// return quoted Go rune literals.
+//
+// [Unquote] and [UnquoteChar] unquote Go string and rune literals.
+package strconv
diff --git a/contrib/go/_std_1.20/src/strconv/eisel_lemire.go b/contrib/go/_std_1.21/src/strconv/eisel_lemire.go
index 03842e5079..03842e5079 100644
--- a/contrib/go/_std_1.20/src/strconv/eisel_lemire.go
+++ b/contrib/go/_std_1.21/src/strconv/eisel_lemire.go
diff --git a/contrib/go/_std_1.20/src/strconv/ftoa.go b/contrib/go/_std_1.21/src/strconv/ftoa.go
index fcbf4df13b..fcbf4df13b 100644
--- a/contrib/go/_std_1.20/src/strconv/ftoa.go
+++ b/contrib/go/_std_1.21/src/strconv/ftoa.go
diff --git a/contrib/go/_std_1.20/src/strconv/ftoaryu.go b/contrib/go/_std_1.21/src/strconv/ftoaryu.go
index 2e7bf71df0..2e7bf71df0 100644
--- a/contrib/go/_std_1.20/src/strconv/ftoaryu.go
+++ b/contrib/go/_std_1.21/src/strconv/ftoaryu.go
diff --git a/contrib/go/_std_1.21/src/strconv/isprint.go b/contrib/go/_std_1.21/src/strconv/isprint.go
new file mode 100644
index 0000000000..baa14a65bd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/strconv/isprint.go
@@ -0,0 +1,752 @@
+// Copyright 2013 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.
+
+// Code generated by go run makeisprint.go -output isprint.go; DO NOT EDIT.
+
+package strconv
+
+// (424+133+112)*2 + (508)*4 = 3370 bytes
+
+var isPrint16 = []uint16{
+ 0x0020, 0x007e,
+ 0x00a1, 0x0377,
+ 0x037a, 0x037f,
+ 0x0384, 0x0556,
+ 0x0559, 0x058a,
+ 0x058d, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05ef, 0x05f4,
+ 0x0606, 0x070d,
+ 0x0710, 0x074a,
+ 0x074d, 0x07b1,
+ 0x07c0, 0x07fa,
+ 0x07fd, 0x082d,
+ 0x0830, 0x085b,
+ 0x085e, 0x086a,
+ 0x0870, 0x088e,
+ 0x0898, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09e3,
+ 0x09e6, 0x09fe,
+ 0x0a01, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a39,
+ 0x0a3c, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a51, 0x0a51,
+ 0x0a59, 0x0a5e,
+ 0x0a66, 0x0a76,
+ 0x0a81, 0x0ab9,
+ 0x0abc, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0af1,
+ 0x0af9, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b39,
+ 0x0b3c, 0x0b44,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b55, 0x0b57,
+ 0x0b5c, 0x0b63,
+ 0x0b66, 0x0b77,
+ 0x0b82, 0x0b8a,
+ 0x0b8e, 0x0b95,
+ 0x0b99, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bcd,
+ 0x0bd0, 0x0bd0,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c00, 0x0c39,
+ 0x0c3c, 0x0c4d,
+ 0x0c55, 0x0c5a,
+ 0x0c5d, 0x0c5d,
+ 0x0c60, 0x0c63,
+ 0x0c66, 0x0c6f,
+ 0x0c77, 0x0cb9,
+ 0x0cbc, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cdd, 0x0ce3,
+ 0x0ce6, 0x0cf3,
+ 0x0d00, 0x0d4f,
+ 0x0d54, 0x0d63,
+ 0x0d66, 0x0d96,
+ 0x0d9a, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0ddf,
+ 0x0de6, 0x0def,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0ebd,
+ 0x0ec0, 0x0ed9,
+ 0x0edc, 0x0edf,
+ 0x0f00, 0x0f6c,
+ 0x0f71, 0x0fda,
+ 0x1000, 0x10c7,
+ 0x10cd, 0x10cd,
+ 0x10d0, 0x124d,
+ 0x1250, 0x125d,
+ 0x1260, 0x128d,
+ 0x1290, 0x12b5,
+ 0x12b8, 0x12c5,
+ 0x12c8, 0x1315,
+ 0x1318, 0x135a,
+ 0x135d, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f5,
+ 0x13f8, 0x13fd,
+ 0x1400, 0x169c,
+ 0x16a0, 0x16f8,
+ 0x1700, 0x1715,
+ 0x171f, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x1819,
+ 0x1820, 0x1878,
+ 0x1880, 0x18aa,
+ 0x18b0, 0x18f5,
+ 0x1900, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19ab,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19da,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a7c,
+ 0x1a7f, 0x1a89,
+ 0x1a90, 0x1a99,
+ 0x1aa0, 0x1aad,
+ 0x1ab0, 0x1ace,
+ 0x1b00, 0x1b4c,
+ 0x1b50, 0x1bf3,
+ 0x1bfc, 0x1c37,
+ 0x1c3b, 0x1c49,
+ 0x1c4d, 0x1c88,
+ 0x1c90, 0x1cba,
+ 0x1cbd, 0x1cc7,
+ 0x1cd0, 0x1cfa,
+ 0x1d00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f7d,
+ 0x1f80, 0x1fd3,
+ 0x1fd6, 0x1fef,
+ 0x1ff2, 0x1ffe,
+ 0x2010, 0x2027,
+ 0x2030, 0x205e,
+ 0x2070, 0x2071,
+ 0x2074, 0x209c,
+ 0x20a0, 0x20c0,
+ 0x20d0, 0x20f0,
+ 0x2100, 0x218b,
+ 0x2190, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x2b73,
+ 0x2b76, 0x2cf3,
+ 0x2cf9, 0x2d27,
+ 0x2d2d, 0x2d2d,
+ 0x2d30, 0x2d67,
+ 0x2d6f, 0x2d70,
+ 0x2d7f, 0x2d96,
+ 0x2da0, 0x2e5d,
+ 0x2e80, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3001, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x31e3,
+ 0x31f0, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa4d0, 0xa62b,
+ 0xa640, 0xa6f7,
+ 0xa700, 0xa7ca,
+ 0xa7d0, 0xa7d9,
+ 0xa7f2, 0xa82c,
+ 0xa830, 0xa839,
+ 0xa840, 0xa877,
+ 0xa880, 0xa8c5,
+ 0xa8ce, 0xa8d9,
+ 0xa8e0, 0xa953,
+ 0xa95f, 0xa97c,
+ 0xa980, 0xa9d9,
+ 0xa9de, 0xaa36,
+ 0xaa40, 0xaa4d,
+ 0xaa50, 0xaa59,
+ 0xaa5c, 0xaac2,
+ 0xaadb, 0xaaf6,
+ 0xab01, 0xab06,
+ 0xab09, 0xab0e,
+ 0xab11, 0xab16,
+ 0xab20, 0xab6b,
+ 0xab70, 0xabed,
+ 0xabf0, 0xabf9,
+ 0xac00, 0xd7a3,
+ 0xd7b0, 0xd7c6,
+ 0xd7cb, 0xd7fb,
+ 0xf900, 0xfa6d,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfbc2,
+ 0xfbd3, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdcf, 0xfdcf,
+ 0xfdf0, 0xfe19,
+ 0xfe20, 0xfe6b,
+ 0xfe70, 0xfefc,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffee,
+ 0xfffc, 0xfffd,
+}
+
+var isNotPrint16 = []uint16{
+ 0x00ad,
+ 0x038b,
+ 0x038d,
+ 0x03a2,
+ 0x0530,
+ 0x0590,
+ 0x061c,
+ 0x06dd,
+ 0x083f,
+ 0x085f,
+ 0x08e2,
+ 0x0984,
+ 0x09a9,
+ 0x09b1,
+ 0x09de,
+ 0x0a04,
+ 0x0a29,
+ 0x0a31,
+ 0x0a34,
+ 0x0a37,
+ 0x0a3d,
+ 0x0a5d,
+ 0x0a84,
+ 0x0a8e,
+ 0x0a92,
+ 0x0aa9,
+ 0x0ab1,
+ 0x0ab4,
+ 0x0ac6,
+ 0x0aca,
+ 0x0b00,
+ 0x0b04,
+ 0x0b29,
+ 0x0b31,
+ 0x0b34,
+ 0x0b5e,
+ 0x0b84,
+ 0x0b91,
+ 0x0b9b,
+ 0x0b9d,
+ 0x0bc9,
+ 0x0c0d,
+ 0x0c11,
+ 0x0c29,
+ 0x0c45,
+ 0x0c49,
+ 0x0c57,
+ 0x0c8d,
+ 0x0c91,
+ 0x0ca9,
+ 0x0cb4,
+ 0x0cc5,
+ 0x0cc9,
+ 0x0cdf,
+ 0x0cf0,
+ 0x0d0d,
+ 0x0d11,
+ 0x0d45,
+ 0x0d49,
+ 0x0d80,
+ 0x0d84,
+ 0x0db2,
+ 0x0dbc,
+ 0x0dd5,
+ 0x0dd7,
+ 0x0e83,
+ 0x0e85,
+ 0x0e8b,
+ 0x0ea4,
+ 0x0ea6,
+ 0x0ec5,
+ 0x0ec7,
+ 0x0ecf,
+ 0x0f48,
+ 0x0f98,
+ 0x0fbd,
+ 0x0fcd,
+ 0x10c6,
+ 0x1249,
+ 0x1257,
+ 0x1259,
+ 0x1289,
+ 0x12b1,
+ 0x12bf,
+ 0x12c1,
+ 0x12d7,
+ 0x1311,
+ 0x1680,
+ 0x176d,
+ 0x1771,
+ 0x180e,
+ 0x191f,
+ 0x1a5f,
+ 0x1b7f,
+ 0x1f58,
+ 0x1f5a,
+ 0x1f5c,
+ 0x1f5e,
+ 0x1fb5,
+ 0x1fc5,
+ 0x1fdc,
+ 0x1ff5,
+ 0x208f,
+ 0x2b96,
+ 0x2d26,
+ 0x2da7,
+ 0x2daf,
+ 0x2db7,
+ 0x2dbf,
+ 0x2dc7,
+ 0x2dcf,
+ 0x2dd7,
+ 0x2ddf,
+ 0x2e9a,
+ 0x3040,
+ 0x3130,
+ 0x318f,
+ 0x321f,
+ 0xa7d2,
+ 0xa7d4,
+ 0xa9ce,
+ 0xa9ff,
+ 0xab27,
+ 0xab2f,
+ 0xfb37,
+ 0xfb3d,
+ 0xfb3f,
+ 0xfb42,
+ 0xfb45,
+ 0xfe53,
+ 0xfe67,
+ 0xfe75,
+ 0xffe7,
+}
+
+var isPrint32 = []uint32{
+ 0x010000, 0x01004d,
+ 0x010050, 0x01005d,
+ 0x010080, 0x0100fa,
+ 0x010100, 0x010102,
+ 0x010107, 0x010133,
+ 0x010137, 0x01019c,
+ 0x0101a0, 0x0101a0,
+ 0x0101d0, 0x0101fd,
+ 0x010280, 0x01029c,
+ 0x0102a0, 0x0102d0,
+ 0x0102e0, 0x0102fb,
+ 0x010300, 0x010323,
+ 0x01032d, 0x01034a,
+ 0x010350, 0x01037a,
+ 0x010380, 0x0103c3,
+ 0x0103c8, 0x0103d5,
+ 0x010400, 0x01049d,
+ 0x0104a0, 0x0104a9,
+ 0x0104b0, 0x0104d3,
+ 0x0104d8, 0x0104fb,
+ 0x010500, 0x010527,
+ 0x010530, 0x010563,
+ 0x01056f, 0x0105bc,
+ 0x010600, 0x010736,
+ 0x010740, 0x010755,
+ 0x010760, 0x010767,
+ 0x010780, 0x0107ba,
+ 0x010800, 0x010805,
+ 0x010808, 0x010838,
+ 0x01083c, 0x01083c,
+ 0x01083f, 0x01089e,
+ 0x0108a7, 0x0108af,
+ 0x0108e0, 0x0108f5,
+ 0x0108fb, 0x01091b,
+ 0x01091f, 0x010939,
+ 0x01093f, 0x01093f,
+ 0x010980, 0x0109b7,
+ 0x0109bc, 0x0109cf,
+ 0x0109d2, 0x010a06,
+ 0x010a0c, 0x010a35,
+ 0x010a38, 0x010a3a,
+ 0x010a3f, 0x010a48,
+ 0x010a50, 0x010a58,
+ 0x010a60, 0x010a9f,
+ 0x010ac0, 0x010ae6,
+ 0x010aeb, 0x010af6,
+ 0x010b00, 0x010b35,
+ 0x010b39, 0x010b55,
+ 0x010b58, 0x010b72,
+ 0x010b78, 0x010b91,
+ 0x010b99, 0x010b9c,
+ 0x010ba9, 0x010baf,
+ 0x010c00, 0x010c48,
+ 0x010c80, 0x010cb2,
+ 0x010cc0, 0x010cf2,
+ 0x010cfa, 0x010d27,
+ 0x010d30, 0x010d39,
+ 0x010e60, 0x010ead,
+ 0x010eb0, 0x010eb1,
+ 0x010efd, 0x010f27,
+ 0x010f30, 0x010f59,
+ 0x010f70, 0x010f89,
+ 0x010fb0, 0x010fcb,
+ 0x010fe0, 0x010ff6,
+ 0x011000, 0x01104d,
+ 0x011052, 0x011075,
+ 0x01107f, 0x0110c2,
+ 0x0110d0, 0x0110e8,
+ 0x0110f0, 0x0110f9,
+ 0x011100, 0x011147,
+ 0x011150, 0x011176,
+ 0x011180, 0x0111f4,
+ 0x011200, 0x011241,
+ 0x011280, 0x0112a9,
+ 0x0112b0, 0x0112ea,
+ 0x0112f0, 0x0112f9,
+ 0x011300, 0x01130c,
+ 0x01130f, 0x011310,
+ 0x011313, 0x011344,
+ 0x011347, 0x011348,
+ 0x01134b, 0x01134d,
+ 0x011350, 0x011350,
+ 0x011357, 0x011357,
+ 0x01135d, 0x011363,
+ 0x011366, 0x01136c,
+ 0x011370, 0x011374,
+ 0x011400, 0x011461,
+ 0x011480, 0x0114c7,
+ 0x0114d0, 0x0114d9,
+ 0x011580, 0x0115b5,
+ 0x0115b8, 0x0115dd,
+ 0x011600, 0x011644,
+ 0x011650, 0x011659,
+ 0x011660, 0x01166c,
+ 0x011680, 0x0116b9,
+ 0x0116c0, 0x0116c9,
+ 0x011700, 0x01171a,
+ 0x01171d, 0x01172b,
+ 0x011730, 0x011746,
+ 0x011800, 0x01183b,
+ 0x0118a0, 0x0118f2,
+ 0x0118ff, 0x011906,
+ 0x011909, 0x011909,
+ 0x01190c, 0x011938,
+ 0x01193b, 0x011946,
+ 0x011950, 0x011959,
+ 0x0119a0, 0x0119a7,
+ 0x0119aa, 0x0119d7,
+ 0x0119da, 0x0119e4,
+ 0x011a00, 0x011a47,
+ 0x011a50, 0x011aa2,
+ 0x011ab0, 0x011af8,
+ 0x011b00, 0x011b09,
+ 0x011c00, 0x011c45,
+ 0x011c50, 0x011c6c,
+ 0x011c70, 0x011c8f,
+ 0x011c92, 0x011cb6,
+ 0x011d00, 0x011d36,
+ 0x011d3a, 0x011d47,
+ 0x011d50, 0x011d59,
+ 0x011d60, 0x011d98,
+ 0x011da0, 0x011da9,
+ 0x011ee0, 0x011ef8,
+ 0x011f00, 0x011f3a,
+ 0x011f3e, 0x011f59,
+ 0x011fb0, 0x011fb0,
+ 0x011fc0, 0x011ff1,
+ 0x011fff, 0x012399,
+ 0x012400, 0x012474,
+ 0x012480, 0x012543,
+ 0x012f90, 0x012ff2,
+ 0x013000, 0x01342f,
+ 0x013440, 0x013455,
+ 0x014400, 0x014646,
+ 0x016800, 0x016a38,
+ 0x016a40, 0x016a69,
+ 0x016a6e, 0x016ac9,
+ 0x016ad0, 0x016aed,
+ 0x016af0, 0x016af5,
+ 0x016b00, 0x016b45,
+ 0x016b50, 0x016b77,
+ 0x016b7d, 0x016b8f,
+ 0x016e40, 0x016e9a,
+ 0x016f00, 0x016f4a,
+ 0x016f4f, 0x016f87,
+ 0x016f8f, 0x016f9f,
+ 0x016fe0, 0x016fe4,
+ 0x016ff0, 0x016ff1,
+ 0x017000, 0x0187f7,
+ 0x018800, 0x018cd5,
+ 0x018d00, 0x018d08,
+ 0x01aff0, 0x01b122,
+ 0x01b132, 0x01b132,
+ 0x01b150, 0x01b152,
+ 0x01b155, 0x01b155,
+ 0x01b164, 0x01b167,
+ 0x01b170, 0x01b2fb,
+ 0x01bc00, 0x01bc6a,
+ 0x01bc70, 0x01bc7c,
+ 0x01bc80, 0x01bc88,
+ 0x01bc90, 0x01bc99,
+ 0x01bc9c, 0x01bc9f,
+ 0x01cf00, 0x01cf2d,
+ 0x01cf30, 0x01cf46,
+ 0x01cf50, 0x01cfc3,
+ 0x01d000, 0x01d0f5,
+ 0x01d100, 0x01d126,
+ 0x01d129, 0x01d172,
+ 0x01d17b, 0x01d1ea,
+ 0x01d200, 0x01d245,
+ 0x01d2c0, 0x01d2d3,
+ 0x01d2e0, 0x01d2f3,
+ 0x01d300, 0x01d356,
+ 0x01d360, 0x01d378,
+ 0x01d400, 0x01d49f,
+ 0x01d4a2, 0x01d4a2,
+ 0x01d4a5, 0x01d4a6,
+ 0x01d4a9, 0x01d50a,
+ 0x01d50d, 0x01d546,
+ 0x01d54a, 0x01d6a5,
+ 0x01d6a8, 0x01d7cb,
+ 0x01d7ce, 0x01da8b,
+ 0x01da9b, 0x01daaf,
+ 0x01df00, 0x01df1e,
+ 0x01df25, 0x01df2a,
+ 0x01e000, 0x01e018,
+ 0x01e01b, 0x01e02a,
+ 0x01e030, 0x01e06d,
+ 0x01e08f, 0x01e08f,
+ 0x01e100, 0x01e12c,
+ 0x01e130, 0x01e13d,
+ 0x01e140, 0x01e149,
+ 0x01e14e, 0x01e14f,
+ 0x01e290, 0x01e2ae,
+ 0x01e2c0, 0x01e2f9,
+ 0x01e2ff, 0x01e2ff,
+ 0x01e4d0, 0x01e4f9,
+ 0x01e7e0, 0x01e8c4,
+ 0x01e8c7, 0x01e8d6,
+ 0x01e900, 0x01e94b,
+ 0x01e950, 0x01e959,
+ 0x01e95e, 0x01e95f,
+ 0x01ec71, 0x01ecb4,
+ 0x01ed01, 0x01ed3d,
+ 0x01ee00, 0x01ee24,
+ 0x01ee27, 0x01ee3b,
+ 0x01ee42, 0x01ee42,
+ 0x01ee47, 0x01ee54,
+ 0x01ee57, 0x01ee64,
+ 0x01ee67, 0x01ee9b,
+ 0x01eea1, 0x01eebb,
+ 0x01eef0, 0x01eef1,
+ 0x01f000, 0x01f02b,
+ 0x01f030, 0x01f093,
+ 0x01f0a0, 0x01f0ae,
+ 0x01f0b1, 0x01f0f5,
+ 0x01f100, 0x01f1ad,
+ 0x01f1e6, 0x01f202,
+ 0x01f210, 0x01f23b,
+ 0x01f240, 0x01f248,
+ 0x01f250, 0x01f251,
+ 0x01f260, 0x01f265,
+ 0x01f300, 0x01f6d7,
+ 0x01f6dc, 0x01f6ec,
+ 0x01f6f0, 0x01f6fc,
+ 0x01f700, 0x01f776,
+ 0x01f77b, 0x01f7d9,
+ 0x01f7e0, 0x01f7eb,
+ 0x01f7f0, 0x01f7f0,
+ 0x01f800, 0x01f80b,
+ 0x01f810, 0x01f847,
+ 0x01f850, 0x01f859,
+ 0x01f860, 0x01f887,
+ 0x01f890, 0x01f8ad,
+ 0x01f8b0, 0x01f8b1,
+ 0x01f900, 0x01fa53,
+ 0x01fa60, 0x01fa6d,
+ 0x01fa70, 0x01fa7c,
+ 0x01fa80, 0x01fa88,
+ 0x01fa90, 0x01fac5,
+ 0x01face, 0x01fadb,
+ 0x01fae0, 0x01fae8,
+ 0x01faf0, 0x01faf8,
+ 0x01fb00, 0x01fbca,
+ 0x01fbf0, 0x01fbf9,
+ 0x020000, 0x02a6df,
+ 0x02a700, 0x02b739,
+ 0x02b740, 0x02b81d,
+ 0x02b820, 0x02cea1,
+ 0x02ceb0, 0x02ebe0,
+ 0x02f800, 0x02fa1d,
+ 0x030000, 0x03134a,
+ 0x031350, 0x0323af,
+ 0x0e0100, 0x0e01ef,
+}
+
+var isNotPrint32 = []uint16{ // add 0x10000 to each entry
+ 0x000c,
+ 0x0027,
+ 0x003b,
+ 0x003e,
+ 0x018f,
+ 0x039e,
+ 0x057b,
+ 0x058b,
+ 0x0593,
+ 0x0596,
+ 0x05a2,
+ 0x05b2,
+ 0x05ba,
+ 0x0786,
+ 0x07b1,
+ 0x0809,
+ 0x0836,
+ 0x0856,
+ 0x08f3,
+ 0x0a04,
+ 0x0a14,
+ 0x0a18,
+ 0x0e7f,
+ 0x0eaa,
+ 0x10bd,
+ 0x1135,
+ 0x11e0,
+ 0x1212,
+ 0x1287,
+ 0x1289,
+ 0x128e,
+ 0x129e,
+ 0x1304,
+ 0x1329,
+ 0x1331,
+ 0x1334,
+ 0x133a,
+ 0x145c,
+ 0x1914,
+ 0x1917,
+ 0x1936,
+ 0x1c09,
+ 0x1c37,
+ 0x1ca8,
+ 0x1d07,
+ 0x1d0a,
+ 0x1d3b,
+ 0x1d3e,
+ 0x1d66,
+ 0x1d69,
+ 0x1d8f,
+ 0x1d92,
+ 0x1f11,
+ 0x246f,
+ 0x6a5f,
+ 0x6abf,
+ 0x6b5a,
+ 0x6b62,
+ 0xaff4,
+ 0xaffc,
+ 0xafff,
+ 0xd455,
+ 0xd49d,
+ 0xd4ad,
+ 0xd4ba,
+ 0xd4bc,
+ 0xd4c4,
+ 0xd506,
+ 0xd515,
+ 0xd51d,
+ 0xd53a,
+ 0xd53f,
+ 0xd545,
+ 0xd551,
+ 0xdaa0,
+ 0xe007,
+ 0xe022,
+ 0xe025,
+ 0xe7e7,
+ 0xe7ec,
+ 0xe7ef,
+ 0xe7ff,
+ 0xee04,
+ 0xee20,
+ 0xee23,
+ 0xee28,
+ 0xee33,
+ 0xee38,
+ 0xee3a,
+ 0xee48,
+ 0xee4a,
+ 0xee4c,
+ 0xee50,
+ 0xee53,
+ 0xee58,
+ 0xee5a,
+ 0xee5c,
+ 0xee5e,
+ 0xee60,
+ 0xee63,
+ 0xee6b,
+ 0xee73,
+ 0xee78,
+ 0xee7d,
+ 0xee7f,
+ 0xee8a,
+ 0xeea4,
+ 0xeeaa,
+ 0xf0c0,
+ 0xf0d0,
+ 0xfabe,
+ 0xfb93,
+}
+
+// isGraphic lists the graphic runes not matched by IsPrint.
+var isGraphic = []uint16{
+ 0x00a0,
+ 0x1680,
+ 0x2000,
+ 0x2001,
+ 0x2002,
+ 0x2003,
+ 0x2004,
+ 0x2005,
+ 0x2006,
+ 0x2007,
+ 0x2008,
+ 0x2009,
+ 0x200a,
+ 0x202f,
+ 0x205f,
+ 0x3000,
+}
diff --git a/contrib/go/_std_1.20/src/strconv/itoa.go b/contrib/go/_std_1.21/src/strconv/itoa.go
index b0c2666e7c..b0c2666e7c 100644
--- a/contrib/go/_std_1.20/src/strconv/itoa.go
+++ b/contrib/go/_std_1.21/src/strconv/itoa.go
diff --git a/contrib/go/_std_1.20/src/strconv/quote.go b/contrib/go/_std_1.21/src/strconv/quote.go
index 1b5bddfeae..1b5bddfeae 100644
--- a/contrib/go/_std_1.20/src/strconv/quote.go
+++ b/contrib/go/_std_1.21/src/strconv/quote.go
diff --git a/contrib/go/_std_1.21/src/strconv/ya.make b/contrib/go/_std_1.21/src/strconv/ya.make
new file mode 100644
index 0000000000..fff536084d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/strconv/ya.make
@@ -0,0 +1,44 @@
+GO_LIBRARY()
+
+SRCS(
+ atob.go
+ atoc.go
+ atof.go
+ atoi.go
+ bytealg.go
+ ctoa.go
+ decimal.go
+ doc.go
+ eisel_lemire.go
+ ftoa.go
+ ftoaryu.go
+ isprint.go
+ itoa.go
+ quote.go
+)
+
+GO_TEST_SRCS(
+ export_test.go
+ internal_test.go
+)
+
+GO_XTEST_SRCS(
+ atob_test.go
+ atoc_test.go
+ atof_test.go
+ atoi_test.go
+ ctoa_test.go
+ decimal_test.go
+ example_test.go
+ fp_test.go
+ ftoa_test.go
+ ftoaryu_test.go
+ itoa_test.go
+ quote_test.go
+ strconv_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/strings/builder.go b/contrib/go/_std_1.21/src/strings/builder.go
new file mode 100644
index 0000000000..299ad51255
--- /dev/null
+++ b/contrib/go/_std_1.21/src/strings/builder.go
@@ -0,0 +1,118 @@
+// Copyright 2017 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 strings
+
+import (
+ "internal/bytealg"
+ "unicode/utf8"
+ "unsafe"
+)
+
+// A Builder is used to efficiently build a string using Write methods.
+// It minimizes memory copying. The zero value is ready to use.
+// Do not copy a non-zero Builder.
+type Builder struct {
+ addr *Builder // of receiver, to detect copies by value
+ buf []byte
+}
+
+// noescape hides a pointer from escape analysis. It is the identity function
+// but escape analysis doesn't think the output depends on the input.
+// noescape is inlined and currently compiles down to zero instructions.
+// USE CAREFULLY!
+// This was copied from the runtime; see issues 23382 and 7921.
+//
+//go:nosplit
+//go:nocheckptr
+func noescape(p unsafe.Pointer) unsafe.Pointer {
+ x := uintptr(p)
+ return unsafe.Pointer(x ^ 0)
+}
+
+func (b *Builder) copyCheck() {
+ if b.addr == nil {
+ // This hack works around a failing of Go's escape analysis
+ // that was causing b to escape and be heap allocated.
+ // See issue 23382.
+ // TODO: once issue 7921 is fixed, this should be reverted to
+ // just "b.addr = b".
+ b.addr = (*Builder)(noescape(unsafe.Pointer(b)))
+ } else if b.addr != b {
+ panic("strings: illegal use of non-zero Builder copied by value")
+ }
+}
+
+// String returns the accumulated string.
+func (b *Builder) String() string {
+ return unsafe.String(unsafe.SliceData(b.buf), len(b.buf))
+}
+
+// Len returns the number of accumulated bytes; b.Len() == len(b.String()).
+func (b *Builder) Len() int { return len(b.buf) }
+
+// Cap returns the capacity of the builder's underlying byte slice. It is the
+// total space allocated for the string being built and includes any bytes
+// already written.
+func (b *Builder) Cap() int { return cap(b.buf) }
+
+// Reset resets the Builder to be empty.
+func (b *Builder) Reset() {
+ b.addr = nil
+ b.buf = nil
+}
+
+// grow copies the buffer to a new, larger buffer so that there are at least n
+// bytes of capacity beyond len(b.buf).
+func (b *Builder) grow(n int) {
+ buf := bytealg.MakeNoZero(2*cap(b.buf) + n)[:len(b.buf)]
+ copy(buf, b.buf)
+ b.buf = buf
+}
+
+// Grow grows b's capacity, if necessary, to guarantee space for
+// another n bytes. After Grow(n), at least n bytes can be written to b
+// without another allocation. If n is negative, Grow panics.
+func (b *Builder) Grow(n int) {
+ b.copyCheck()
+ if n < 0 {
+ panic("strings.Builder.Grow: negative count")
+ }
+ if cap(b.buf)-len(b.buf) < n {
+ b.grow(n)
+ }
+}
+
+// Write appends the contents of p to b's buffer.
+// Write always returns len(p), nil.
+func (b *Builder) Write(p []byte) (int, error) {
+ b.copyCheck()
+ b.buf = append(b.buf, p...)
+ return len(p), nil
+}
+
+// WriteByte appends the byte c to b's buffer.
+// The returned error is always nil.
+func (b *Builder) WriteByte(c byte) error {
+ b.copyCheck()
+ b.buf = append(b.buf, c)
+ return nil
+}
+
+// WriteRune appends the UTF-8 encoding of Unicode code point r to b's buffer.
+// It returns the length of r and a nil error.
+func (b *Builder) WriteRune(r rune) (int, error) {
+ b.copyCheck()
+ n := len(b.buf)
+ b.buf = utf8.AppendRune(b.buf, r)
+ return len(b.buf) - n, nil
+}
+
+// WriteString appends the contents of s to b's buffer.
+// It returns the length of s and a nil error.
+func (b *Builder) WriteString(s string) (int, error) {
+ b.copyCheck()
+ b.buf = append(b.buf, s...)
+ return len(s), nil
+}
diff --git a/contrib/go/_std_1.20/src/strings/clone.go b/contrib/go/_std_1.21/src/strings/clone.go
index d14df11d49..d14df11d49 100644
--- a/contrib/go/_std_1.20/src/strings/clone.go
+++ b/contrib/go/_std_1.21/src/strings/clone.go
diff --git a/contrib/go/_std_1.20/src/strings/compare.go b/contrib/go/_std_1.21/src/strings/compare.go
index 2bd4a243db..2bd4a243db 100644
--- a/contrib/go/_std_1.20/src/strings/compare.go
+++ b/contrib/go/_std_1.21/src/strings/compare.go
diff --git a/contrib/go/_std_1.21/src/strings/reader.go b/contrib/go/_std_1.21/src/strings/reader.go
new file mode 100644
index 0000000000..04f31a1e8f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/strings/reader.go
@@ -0,0 +1,160 @@
+// Copyright 2009 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 strings
+
+import (
+ "errors"
+ "io"
+ "unicode/utf8"
+)
+
+// A Reader implements the io.Reader, io.ReaderAt, io.ByteReader, io.ByteScanner,
+// io.RuneReader, io.RuneScanner, io.Seeker, and io.WriterTo interfaces by reading
+// from a string.
+// The zero value for Reader operates like a Reader of an empty string.
+type Reader struct {
+ s string
+ i int64 // current reading index
+ prevRune int // index of previous rune; or < 0
+}
+
+// Len returns the number of bytes of the unread portion of the
+// string.
+func (r *Reader) Len() int {
+ if r.i >= int64(len(r.s)) {
+ return 0
+ }
+ return int(int64(len(r.s)) - r.i)
+}
+
+// Size returns the original length of the underlying string.
+// Size is the number of bytes available for reading via ReadAt.
+// The returned value is always the same and is not affected by calls
+// to any other method.
+func (r *Reader) Size() int64 { return int64(len(r.s)) }
+
+// Read implements the io.Reader interface.
+func (r *Reader) Read(b []byte) (n int, err error) {
+ if r.i >= int64(len(r.s)) {
+ return 0, io.EOF
+ }
+ r.prevRune = -1
+ n = copy(b, r.s[r.i:])
+ r.i += int64(n)
+ return
+}
+
+// ReadAt implements the io.ReaderAt interface.
+func (r *Reader) ReadAt(b []byte, off int64) (n int, err error) {
+ // cannot modify state - see io.ReaderAt
+ if off < 0 {
+ return 0, errors.New("strings.Reader.ReadAt: negative offset")
+ }
+ if off >= int64(len(r.s)) {
+ return 0, io.EOF
+ }
+ n = copy(b, r.s[off:])
+ if n < len(b) {
+ err = io.EOF
+ }
+ return
+}
+
+// ReadByte implements the io.ByteReader interface.
+func (r *Reader) ReadByte() (byte, error) {
+ r.prevRune = -1
+ if r.i >= int64(len(r.s)) {
+ return 0, io.EOF
+ }
+ b := r.s[r.i]
+ r.i++
+ return b, nil
+}
+
+// UnreadByte implements the io.ByteScanner interface.
+func (r *Reader) UnreadByte() error {
+ if r.i <= 0 {
+ return errors.New("strings.Reader.UnreadByte: at beginning of string")
+ }
+ r.prevRune = -1
+ r.i--
+ return nil
+}
+
+// ReadRune implements the io.RuneReader interface.
+func (r *Reader) ReadRune() (ch rune, size int, err error) {
+ if r.i >= int64(len(r.s)) {
+ r.prevRune = -1
+ return 0, 0, io.EOF
+ }
+ r.prevRune = int(r.i)
+ if c := r.s[r.i]; c < utf8.RuneSelf {
+ r.i++
+ return rune(c), 1, nil
+ }
+ ch, size = utf8.DecodeRuneInString(r.s[r.i:])
+ r.i += int64(size)
+ return
+}
+
+// UnreadRune implements the io.RuneScanner interface.
+func (r *Reader) UnreadRune() error {
+ if r.i <= 0 {
+ return errors.New("strings.Reader.UnreadRune: at beginning of string")
+ }
+ if r.prevRune < 0 {
+ return errors.New("strings.Reader.UnreadRune: previous operation was not ReadRune")
+ }
+ r.i = int64(r.prevRune)
+ r.prevRune = -1
+ return nil
+}
+
+// Seek implements the io.Seeker interface.
+func (r *Reader) Seek(offset int64, whence int) (int64, error) {
+ r.prevRune = -1
+ var abs int64
+ switch whence {
+ case io.SeekStart:
+ abs = offset
+ case io.SeekCurrent:
+ abs = r.i + offset
+ case io.SeekEnd:
+ abs = int64(len(r.s)) + offset
+ default:
+ return 0, errors.New("strings.Reader.Seek: invalid whence")
+ }
+ if abs < 0 {
+ return 0, errors.New("strings.Reader.Seek: negative position")
+ }
+ r.i = abs
+ return abs, nil
+}
+
+// WriteTo implements the io.WriterTo interface.
+func (r *Reader) WriteTo(w io.Writer) (n int64, err error) {
+ r.prevRune = -1
+ if r.i >= int64(len(r.s)) {
+ return 0, nil
+ }
+ s := r.s[r.i:]
+ m, err := io.WriteString(w, s)
+ if m > len(s) {
+ panic("strings.Reader.WriteTo: invalid WriteString count")
+ }
+ r.i += int64(m)
+ n = int64(m)
+ if m != len(s) && err == nil {
+ err = io.ErrShortWrite
+ }
+ return
+}
+
+// Reset resets the Reader to be reading from s.
+func (r *Reader) Reset(s string) { *r = Reader{s, 0, -1} }
+
+// NewReader returns a new Reader reading from s.
+// It is similar to bytes.NewBufferString but more efficient and non-writable.
+func NewReader(s string) *Reader { return &Reader{s, 0, -1} }
diff --git a/contrib/go/_std_1.20/src/strings/replace.go b/contrib/go/_std_1.21/src/strings/replace.go
index f504fb48df..f504fb48df 100644
--- a/contrib/go/_std_1.20/src/strings/replace.go
+++ b/contrib/go/_std_1.21/src/strings/replace.go
diff --git a/contrib/go/_std_1.20/src/strings/search.go b/contrib/go/_std_1.21/src/strings/search.go
index e5bffbbfe8..e5bffbbfe8 100644
--- a/contrib/go/_std_1.20/src/strings/search.go
+++ b/contrib/go/_std_1.21/src/strings/search.go
diff --git a/contrib/go/_std_1.21/src/strings/strings.go b/contrib/go/_std_1.21/src/strings/strings.go
new file mode 100644
index 0000000000..2dd4321142
--- /dev/null
+++ b/contrib/go/_std_1.21/src/strings/strings.go
@@ -0,0 +1,1305 @@
+// Copyright 2009 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 strings implements simple functions to manipulate UTF-8 encoded strings.
+//
+// For information about UTF-8 strings in Go, see https://blog.golang.org/strings.
+package strings
+
+import (
+ "internal/bytealg"
+ "unicode"
+ "unicode/utf8"
+)
+
+const maxInt = int(^uint(0) >> 1)
+
+// explode splits s into a slice of UTF-8 strings,
+// one string per Unicode character up to a maximum of n (n < 0 means no limit).
+// Invalid UTF-8 bytes are sliced individually.
+func explode(s string, n int) []string {
+ l := utf8.RuneCountInString(s)
+ if n < 0 || n > l {
+ n = l
+ }
+ a := make([]string, n)
+ for i := 0; i < n-1; i++ {
+ _, size := utf8.DecodeRuneInString(s)
+ a[i] = s[:size]
+ s = s[size:]
+ }
+ if n > 0 {
+ a[n-1] = s
+ }
+ return a
+}
+
+// Count counts the number of non-overlapping instances of substr in s.
+// If substr is an empty string, Count returns 1 + the number of Unicode code points in s.
+func Count(s, substr string) int {
+ // special case
+ if len(substr) == 0 {
+ return utf8.RuneCountInString(s) + 1
+ }
+ if len(substr) == 1 {
+ return bytealg.CountString(s, substr[0])
+ }
+ n := 0
+ for {
+ i := Index(s, substr)
+ if i == -1 {
+ return n
+ }
+ n++
+ s = s[i+len(substr):]
+ }
+}
+
+// Contains reports whether substr is within s.
+func Contains(s, substr string) bool {
+ return Index(s, substr) >= 0
+}
+
+// ContainsAny reports whether any Unicode code points in chars are within s.
+func ContainsAny(s, chars string) bool {
+ return IndexAny(s, chars) >= 0
+}
+
+// ContainsRune reports whether the Unicode code point r is within s.
+func ContainsRune(s string, r rune) bool {
+ return IndexRune(s, r) >= 0
+}
+
+// ContainsFunc reports whether any Unicode code points r within s satisfy f(r).
+func ContainsFunc(s string, f func(rune) bool) bool {
+ return IndexFunc(s, f) >= 0
+}
+
+// LastIndex returns the index of the last instance of substr in s, or -1 if substr is not present in s.
+func LastIndex(s, substr string) int {
+ n := len(substr)
+ switch {
+ case n == 0:
+ return len(s)
+ case n == 1:
+ return LastIndexByte(s, substr[0])
+ case n == len(s):
+ if substr == s {
+ return 0
+ }
+ return -1
+ case n > len(s):
+ return -1
+ }
+ // Rabin-Karp search from the end of the string
+ hashss, pow := bytealg.HashStrRev(substr)
+ last := len(s) - n
+ var h uint32
+ for i := len(s) - 1; i >= last; i-- {
+ h = h*bytealg.PrimeRK + uint32(s[i])
+ }
+ if h == hashss && s[last:] == substr {
+ return last
+ }
+ for i := last - 1; i >= 0; i-- {
+ h *= bytealg.PrimeRK
+ h += uint32(s[i])
+ h -= pow * uint32(s[i+n])
+ if h == hashss && s[i:i+n] == substr {
+ return i
+ }
+ }
+ return -1
+}
+
+// IndexByte returns the index of the first instance of c in s, or -1 if c is not present in s.
+func IndexByte(s string, c byte) int {
+ return bytealg.IndexByteString(s, c)
+}
+
+// IndexRune returns the index of the first instance of the Unicode code point
+// r, or -1 if rune is not present in s.
+// If r is utf8.RuneError, it returns the first instance of any
+// invalid UTF-8 byte sequence.
+func IndexRune(s string, r rune) int {
+ switch {
+ case 0 <= r && r < utf8.RuneSelf:
+ return IndexByte(s, byte(r))
+ case r == utf8.RuneError:
+ for i, r := range s {
+ if r == utf8.RuneError {
+ return i
+ }
+ }
+ return -1
+ case !utf8.ValidRune(r):
+ return -1
+ default:
+ return Index(s, string(r))
+ }
+}
+
+// IndexAny returns the index of the first instance of any Unicode code point
+// from chars in s, or -1 if no Unicode code point from chars is present in s.
+func IndexAny(s, chars string) int {
+ if chars == "" {
+ // Avoid scanning all of s.
+ return -1
+ }
+ if len(chars) == 1 {
+ // Avoid scanning all of s.
+ r := rune(chars[0])
+ if r >= utf8.RuneSelf {
+ r = utf8.RuneError
+ }
+ return IndexRune(s, r)
+ }
+ if len(s) > 8 {
+ if as, isASCII := makeASCIISet(chars); isASCII {
+ for i := 0; i < len(s); i++ {
+ if as.contains(s[i]) {
+ return i
+ }
+ }
+ return -1
+ }
+ }
+ for i, c := range s {
+ if IndexRune(chars, c) >= 0 {
+ return i
+ }
+ }
+ return -1
+}
+
+// LastIndexAny returns the index of the last instance of any Unicode code
+// point from chars in s, or -1 if no Unicode code point from chars is
+// present in s.
+func LastIndexAny(s, chars string) int {
+ if chars == "" {
+ // Avoid scanning all of s.
+ return -1
+ }
+ if len(s) == 1 {
+ rc := rune(s[0])
+ if rc >= utf8.RuneSelf {
+ rc = utf8.RuneError
+ }
+ if IndexRune(chars, rc) >= 0 {
+ return 0
+ }
+ return -1
+ }
+ if len(s) > 8 {
+ if as, isASCII := makeASCIISet(chars); isASCII {
+ for i := len(s) - 1; i >= 0; i-- {
+ if as.contains(s[i]) {
+ return i
+ }
+ }
+ return -1
+ }
+ }
+ if len(chars) == 1 {
+ rc := rune(chars[0])
+ if rc >= utf8.RuneSelf {
+ rc = utf8.RuneError
+ }
+ for i := len(s); i > 0; {
+ r, size := utf8.DecodeLastRuneInString(s[:i])
+ i -= size
+ if rc == r {
+ return i
+ }
+ }
+ return -1
+ }
+ for i := len(s); i > 0; {
+ r, size := utf8.DecodeLastRuneInString(s[:i])
+ i -= size
+ if IndexRune(chars, r) >= 0 {
+ return i
+ }
+ }
+ return -1
+}
+
+// LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
+func LastIndexByte(s string, c byte) int {
+ for i := len(s) - 1; i >= 0; i-- {
+ if s[i] == c {
+ return i
+ }
+ }
+ return -1
+}
+
+// Generic split: splits after each instance of sep,
+// including sepSave bytes of sep in the subarrays.
+func genSplit(s, sep string, sepSave, n int) []string {
+ if n == 0 {
+ return nil
+ }
+ if sep == "" {
+ return explode(s, n)
+ }
+ if n < 0 {
+ n = Count(s, sep) + 1
+ }
+
+ if n > len(s)+1 {
+ n = len(s) + 1
+ }
+ a := make([]string, n)
+ n--
+ i := 0
+ for i < n {
+ m := Index(s, sep)
+ if m < 0 {
+ break
+ }
+ a[i] = s[:m+sepSave]
+ s = s[m+len(sep):]
+ i++
+ }
+ a[i] = s
+ return a[:i+1]
+}
+
+// SplitN slices s into substrings separated by sep and returns a slice of
+// the substrings between those separators.
+//
+// The count determines the number of substrings to return:
+//
+// n > 0: at most n substrings; the last substring will be the unsplit remainder.
+// n == 0: the result is nil (zero substrings)
+// n < 0: all substrings
+//
+// Edge cases for s and sep (for example, empty strings) are handled
+// as described in the documentation for Split.
+//
+// To split around the first instance of a separator, see Cut.
+func SplitN(s, sep string, n int) []string { return genSplit(s, sep, 0, n) }
+
+// SplitAfterN slices s into substrings after each instance of sep and
+// returns a slice of those substrings.
+//
+// The count determines the number of substrings to return:
+//
+// n > 0: at most n substrings; the last substring will be the unsplit remainder.
+// n == 0: the result is nil (zero substrings)
+// n < 0: all substrings
+//
+// Edge cases for s and sep (for example, empty strings) are handled
+// as described in the documentation for SplitAfter.
+func SplitAfterN(s, sep string, n int) []string {
+ return genSplit(s, sep, len(sep), n)
+}
+
+// Split slices s into all substrings separated by sep and returns a slice of
+// the substrings between those separators.
+//
+// If s does not contain sep and sep is not empty, Split returns a
+// slice of length 1 whose only element is s.
+//
+// If sep is empty, Split splits after each UTF-8 sequence. If both s
+// and sep are empty, Split returns an empty slice.
+//
+// It is equivalent to SplitN with a count of -1.
+//
+// To split around the first instance of a separator, see Cut.
+func Split(s, sep string) []string { return genSplit(s, sep, 0, -1) }
+
+// SplitAfter slices s into all substrings after each instance of sep and
+// returns a slice of those substrings.
+//
+// If s does not contain sep and sep is not empty, SplitAfter returns
+// a slice of length 1 whose only element is s.
+//
+// If sep is empty, SplitAfter splits after each UTF-8 sequence. If
+// both s and sep are empty, SplitAfter returns an empty slice.
+//
+// It is equivalent to SplitAfterN with a count of -1.
+func SplitAfter(s, sep string) []string {
+ return genSplit(s, sep, len(sep), -1)
+}
+
+var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
+
+// Fields splits the string s around each instance of one or more consecutive white space
+// characters, as defined by unicode.IsSpace, returning a slice of substrings of s or an
+// empty slice if s contains only white space.
+func Fields(s string) []string {
+ // First count the fields.
+ // This is an exact count if s is ASCII, otherwise it is an approximation.
+ n := 0
+ wasSpace := 1
+ // setBits is used to track which bits are set in the bytes of s.
+ setBits := uint8(0)
+ for i := 0; i < len(s); i++ {
+ r := s[i]
+ setBits |= r
+ isSpace := int(asciiSpace[r])
+ n += wasSpace & ^isSpace
+ wasSpace = isSpace
+ }
+
+ if setBits >= utf8.RuneSelf {
+ // Some runes in the input string are not ASCII.
+ return FieldsFunc(s, unicode.IsSpace)
+ }
+ // ASCII fast path
+ a := make([]string, n)
+ na := 0
+ fieldStart := 0
+ i := 0
+ // Skip spaces in the front of the input.
+ for i < len(s) && asciiSpace[s[i]] != 0 {
+ i++
+ }
+ fieldStart = i
+ for i < len(s) {
+ if asciiSpace[s[i]] == 0 {
+ i++
+ continue
+ }
+ a[na] = s[fieldStart:i]
+ na++
+ i++
+ // Skip spaces in between fields.
+ for i < len(s) && asciiSpace[s[i]] != 0 {
+ i++
+ }
+ fieldStart = i
+ }
+ if fieldStart < len(s) { // Last field might end at EOF.
+ a[na] = s[fieldStart:]
+ }
+ return a
+}
+
+// FieldsFunc splits the string s at each run of Unicode code points c satisfying f(c)
+// and returns an array of slices of s. If all code points in s satisfy f(c) or the
+// string is empty, an empty slice is returned.
+//
+// FieldsFunc makes no guarantees about the order in which it calls f(c)
+// and assumes that f always returns the same value for a given c.
+func FieldsFunc(s string, f func(rune) bool) []string {
+ // A span is used to record a slice of s of the form s[start:end].
+ // The start index is inclusive and the end index is exclusive.
+ type span struct {
+ start int
+ end int
+ }
+ spans := make([]span, 0, 32)
+
+ // Find the field start and end indices.
+ // Doing this in a separate pass (rather than slicing the string s
+ // and collecting the result substrings right away) is significantly
+ // more efficient, possibly due to cache effects.
+ start := -1 // valid span start if >= 0
+ for end, rune := range s {
+ if f(rune) {
+ if start >= 0 {
+ spans = append(spans, span{start, end})
+ // Set start to a negative value.
+ // Note: using -1 here consistently and reproducibly
+ // slows down this code by a several percent on amd64.
+ start = ^start
+ }
+ } else {
+ if start < 0 {
+ start = end
+ }
+ }
+ }
+
+ // Last field might end at EOF.
+ if start >= 0 {
+ spans = append(spans, span{start, len(s)})
+ }
+
+ // Create strings from recorded field indices.
+ a := make([]string, len(spans))
+ for i, span := range spans {
+ a[i] = s[span.start:span.end]
+ }
+
+ return a
+}
+
+// Join concatenates the elements of its first argument to create a single string. The separator
+// string sep is placed between elements in the resulting string.
+func Join(elems []string, sep string) string {
+ switch len(elems) {
+ case 0:
+ return ""
+ case 1:
+ return elems[0]
+ }
+
+ var n int
+ if len(sep) > 0 {
+ if len(sep) >= maxInt/(len(elems)-1) {
+ panic("strings: Join output length overflow")
+ }
+ n += len(sep) * (len(elems) - 1)
+ }
+ for _, elem := range elems {
+ if len(elem) > maxInt-n {
+ panic("strings: Join output length overflow")
+ }
+ n += len(elem)
+ }
+
+ var b Builder
+ b.Grow(n)
+ b.WriteString(elems[0])
+ for _, s := range elems[1:] {
+ b.WriteString(sep)
+ b.WriteString(s)
+ }
+ return b.String()
+}
+
+// HasPrefix tests whether the string s begins with prefix.
+func HasPrefix(s, prefix string) bool {
+ return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
+}
+
+// HasSuffix tests whether the string s ends with suffix.
+func HasSuffix(s, suffix string) bool {
+ return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
+}
+
+// Map returns a copy of the string s with all its characters modified
+// according to the mapping function. If mapping returns a negative value, the character is
+// dropped from the string with no replacement.
+func Map(mapping func(rune) rune, s string) string {
+ // In the worst case, the string can grow when mapped, making
+ // things unpleasant. But it's so rare we barge in assuming it's
+ // fine. It could also shrink but that falls out naturally.
+
+ // The output buffer b is initialized on demand, the first
+ // time a character differs.
+ var b Builder
+
+ for i, c := range s {
+ r := mapping(c)
+ if r == c && c != utf8.RuneError {
+ continue
+ }
+
+ var width int
+ if c == utf8.RuneError {
+ c, width = utf8.DecodeRuneInString(s[i:])
+ if width != 1 && r == c {
+ continue
+ }
+ } else {
+ width = utf8.RuneLen(c)
+ }
+
+ b.Grow(len(s) + utf8.UTFMax)
+ b.WriteString(s[:i])
+ if r >= 0 {
+ b.WriteRune(r)
+ }
+
+ s = s[i+width:]
+ break
+ }
+
+ // Fast path for unchanged input
+ if b.Cap() == 0 { // didn't call b.Grow above
+ return s
+ }
+
+ for _, c := range s {
+ r := mapping(c)
+
+ if r >= 0 {
+ // common case
+ // Due to inlining, it is more performant to determine if WriteByte should be
+ // invoked rather than always call WriteRune
+ if r < utf8.RuneSelf {
+ b.WriteByte(byte(r))
+ } else {
+ // r is not a ASCII rune.
+ b.WriteRune(r)
+ }
+ }
+ }
+
+ return b.String()
+}
+
+// Repeat returns a new string consisting of count copies of the string s.
+//
+// It panics if count is negative or if the result of (len(s) * count)
+// overflows.
+func Repeat(s string, count int) string {
+ switch count {
+ case 0:
+ return ""
+ case 1:
+ return s
+ }
+
+ // Since we cannot return an error on overflow,
+ // we should panic if the repeat will generate an overflow.
+ // See golang.org/issue/16237.
+ if count < 0 {
+ panic("strings: negative Repeat count")
+ }
+ if len(s) >= maxInt/count {
+ panic("strings: Repeat output length overflow")
+ }
+ n := len(s) * count
+
+ if len(s) == 0 {
+ return ""
+ }
+
+ // Past a certain chunk size it is counterproductive to use
+ // larger chunks as the source of the write, as when the source
+ // is too large we are basically just thrashing the CPU D-cache.
+ // So if the result length is larger than an empirically-found
+ // limit (8KB), we stop growing the source string once the limit
+ // is reached and keep reusing the same source string - that
+ // should therefore be always resident in the L1 cache - until we
+ // have completed the construction of the result.
+ // This yields significant speedups (up to +100%) in cases where
+ // the result length is large (roughly, over L2 cache size).
+ const chunkLimit = 8 * 1024
+ chunkMax := n
+ if n > chunkLimit {
+ chunkMax = chunkLimit / len(s) * len(s)
+ if chunkMax == 0 {
+ chunkMax = len(s)
+ }
+ }
+
+ var b Builder
+ b.Grow(n)
+ b.WriteString(s)
+ for b.Len() < n {
+ chunk := n - b.Len()
+ if chunk > b.Len() {
+ chunk = b.Len()
+ }
+ if chunk > chunkMax {
+ chunk = chunkMax
+ }
+ b.WriteString(b.String()[:chunk])
+ }
+ return b.String()
+}
+
+// ToUpper returns s with all Unicode letters mapped to their upper case.
+func ToUpper(s string) string {
+ isASCII, hasLower := true, false
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ if c >= utf8.RuneSelf {
+ isASCII = false
+ break
+ }
+ hasLower = hasLower || ('a' <= c && c <= 'z')
+ }
+
+ if isASCII { // optimize for ASCII-only strings.
+ if !hasLower {
+ return s
+ }
+ var (
+ b Builder
+ pos int
+ )
+ b.Grow(len(s))
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ if 'a' <= c && c <= 'z' {
+ c -= 'a' - 'A'
+ if pos < i {
+ b.WriteString(s[pos:i])
+ }
+ b.WriteByte(c)
+ pos = i + 1
+ }
+ }
+ if pos < len(s) {
+ b.WriteString(s[pos:])
+ }
+ return b.String()
+ }
+ return Map(unicode.ToUpper, s)
+}
+
+// ToLower returns s with all Unicode letters mapped to their lower case.
+func ToLower(s string) string {
+ isASCII, hasUpper := true, false
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ if c >= utf8.RuneSelf {
+ isASCII = false
+ break
+ }
+ hasUpper = hasUpper || ('A' <= c && c <= 'Z')
+ }
+
+ if isASCII { // optimize for ASCII-only strings.
+ if !hasUpper {
+ return s
+ }
+ var (
+ b Builder
+ pos int
+ )
+ b.Grow(len(s))
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ if 'A' <= c && c <= 'Z' {
+ c += 'a' - 'A'
+ if pos < i {
+ b.WriteString(s[pos:i])
+ }
+ b.WriteByte(c)
+ pos = i + 1
+ }
+ }
+ if pos < len(s) {
+ b.WriteString(s[pos:])
+ }
+ return b.String()
+ }
+ return Map(unicode.ToLower, s)
+}
+
+// ToTitle returns a copy of the string s with all Unicode letters mapped to
+// their Unicode title case.
+func ToTitle(s string) string { return Map(unicode.ToTitle, s) }
+
+// ToUpperSpecial returns a copy of the string s with all Unicode letters mapped to their
+// upper case using the case mapping specified by c.
+func ToUpperSpecial(c unicode.SpecialCase, s string) string {
+ return Map(c.ToUpper, s)
+}
+
+// ToLowerSpecial returns a copy of the string s with all Unicode letters mapped to their
+// lower case using the case mapping specified by c.
+func ToLowerSpecial(c unicode.SpecialCase, s string) string {
+ return Map(c.ToLower, s)
+}
+
+// ToTitleSpecial returns a copy of the string s with all Unicode letters mapped to their
+// Unicode title case, giving priority to the special casing rules.
+func ToTitleSpecial(c unicode.SpecialCase, s string) string {
+ return Map(c.ToTitle, s)
+}
+
+// ToValidUTF8 returns a copy of the string s with each run of invalid UTF-8 byte sequences
+// replaced by the replacement string, which may be empty.
+func ToValidUTF8(s, replacement string) string {
+ var b Builder
+
+ for i, c := range s {
+ if c != utf8.RuneError {
+ continue
+ }
+
+ _, wid := utf8.DecodeRuneInString(s[i:])
+ if wid == 1 {
+ b.Grow(len(s) + len(replacement))
+ b.WriteString(s[:i])
+ s = s[i:]
+ break
+ }
+ }
+
+ // Fast path for unchanged input
+ if b.Cap() == 0 { // didn't call b.Grow above
+ return s
+ }
+
+ invalid := false // previous byte was from an invalid UTF-8 sequence
+ for i := 0; i < len(s); {
+ c := s[i]
+ if c < utf8.RuneSelf {
+ i++
+ invalid = false
+ b.WriteByte(c)
+ continue
+ }
+ _, wid := utf8.DecodeRuneInString(s[i:])
+ if wid == 1 {
+ i++
+ if !invalid {
+ invalid = true
+ b.WriteString(replacement)
+ }
+ continue
+ }
+ invalid = false
+ b.WriteString(s[i : i+wid])
+ i += wid
+ }
+
+ return b.String()
+}
+
+// isSeparator reports whether the rune could mark a word boundary.
+// TODO: update when package unicode captures more of the properties.
+func isSeparator(r rune) bool {
+ // ASCII alphanumerics and underscore are not separators
+ if r <= 0x7F {
+ switch {
+ case '0' <= r && r <= '9':
+ return false
+ case 'a' <= r && r <= 'z':
+ return false
+ case 'A' <= r && r <= 'Z':
+ return false
+ case r == '_':
+ return false
+ }
+ return true
+ }
+ // Letters and digits are not separators
+ if unicode.IsLetter(r) || unicode.IsDigit(r) {
+ return false
+ }
+ // Otherwise, all we can do for now is treat spaces as separators.
+ return unicode.IsSpace(r)
+}
+
+// Title returns a copy of the string s with all Unicode letters that begin words
+// mapped to their Unicode title case.
+//
+// Deprecated: The rule Title uses for word boundaries does not handle Unicode
+// punctuation properly. Use golang.org/x/text/cases instead.
+func Title(s string) string {
+ // Use a closure here to remember state.
+ // Hackish but effective. Depends on Map scanning in order and calling
+ // the closure once per rune.
+ prev := ' '
+ return Map(
+ func(r rune) rune {
+ if isSeparator(prev) {
+ prev = r
+ return unicode.ToTitle(r)
+ }
+ prev = r
+ return r
+ },
+ s)
+}
+
+// TrimLeftFunc returns a slice of the string s with all leading
+// Unicode code points c satisfying f(c) removed.
+func TrimLeftFunc(s string, f func(rune) bool) string {
+ i := indexFunc(s, f, false)
+ if i == -1 {
+ return ""
+ }
+ return s[i:]
+}
+
+// TrimRightFunc returns a slice of the string s with all trailing
+// Unicode code points c satisfying f(c) removed.
+func TrimRightFunc(s string, f func(rune) bool) string {
+ i := lastIndexFunc(s, f, false)
+ if i >= 0 && s[i] >= utf8.RuneSelf {
+ _, wid := utf8.DecodeRuneInString(s[i:])
+ i += wid
+ } else {
+ i++
+ }
+ return s[0:i]
+}
+
+// TrimFunc returns a slice of the string s with all leading
+// and trailing Unicode code points c satisfying f(c) removed.
+func TrimFunc(s string, f func(rune) bool) string {
+ return TrimRightFunc(TrimLeftFunc(s, f), f)
+}
+
+// IndexFunc returns the index into s of the first Unicode
+// code point satisfying f(c), or -1 if none do.
+func IndexFunc(s string, f func(rune) bool) int {
+ return indexFunc(s, f, true)
+}
+
+// LastIndexFunc returns the index into s of the last
+// Unicode code point satisfying f(c), or -1 if none do.
+func LastIndexFunc(s string, f func(rune) bool) int {
+ return lastIndexFunc(s, f, true)
+}
+
+// indexFunc is the same as IndexFunc except that if
+// truth==false, the sense of the predicate function is
+// inverted.
+func indexFunc(s string, f func(rune) bool, truth bool) int {
+ for i, r := range s {
+ if f(r) == truth {
+ return i
+ }
+ }
+ return -1
+}
+
+// lastIndexFunc is the same as LastIndexFunc except that if
+// truth==false, the sense of the predicate function is
+// inverted.
+func lastIndexFunc(s string, f func(rune) bool, truth bool) int {
+ for i := len(s); i > 0; {
+ r, size := utf8.DecodeLastRuneInString(s[0:i])
+ i -= size
+ if f(r) == truth {
+ return i
+ }
+ }
+ return -1
+}
+
+// asciiSet is a 32-byte value, where each bit represents the presence of a
+// given ASCII character in the set. The 128-bits of the lower 16 bytes,
+// starting with the least-significant bit of the lowest word to the
+// most-significant bit of the highest word, map to the full range of all
+// 128 ASCII characters. The 128-bits of the upper 16 bytes will be zeroed,
+// ensuring that any non-ASCII character will be reported as not in the set.
+// This allocates a total of 32 bytes even though the upper half
+// is unused to avoid bounds checks in asciiSet.contains.
+type asciiSet [8]uint32
+
+// makeASCIISet creates a set of ASCII characters and reports whether all
+// characters in chars are ASCII.
+func makeASCIISet(chars string) (as asciiSet, ok bool) {
+ for i := 0; i < len(chars); i++ {
+ c := chars[i]
+ if c >= utf8.RuneSelf {
+ return as, false
+ }
+ as[c/32] |= 1 << (c % 32)
+ }
+ return as, true
+}
+
+// contains reports whether c is inside the set.
+func (as *asciiSet) contains(c byte) bool {
+ return (as[c/32] & (1 << (c % 32))) != 0
+}
+
+// Trim returns a slice of the string s with all leading and
+// trailing Unicode code points contained in cutset removed.
+func Trim(s, cutset string) string {
+ if s == "" || cutset == "" {
+ return s
+ }
+ if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
+ return trimLeftByte(trimRightByte(s, cutset[0]), cutset[0])
+ }
+ if as, ok := makeASCIISet(cutset); ok {
+ return trimLeftASCII(trimRightASCII(s, &as), &as)
+ }
+ return trimLeftUnicode(trimRightUnicode(s, cutset), cutset)
+}
+
+// TrimLeft returns a slice of the string s with all leading
+// Unicode code points contained in cutset removed.
+//
+// To remove a prefix, use TrimPrefix instead.
+func TrimLeft(s, cutset string) string {
+ if s == "" || cutset == "" {
+ return s
+ }
+ if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
+ return trimLeftByte(s, cutset[0])
+ }
+ if as, ok := makeASCIISet(cutset); ok {
+ return trimLeftASCII(s, &as)
+ }
+ return trimLeftUnicode(s, cutset)
+}
+
+func trimLeftByte(s string, c byte) string {
+ for len(s) > 0 && s[0] == c {
+ s = s[1:]
+ }
+ return s
+}
+
+func trimLeftASCII(s string, as *asciiSet) string {
+ for len(s) > 0 {
+ if !as.contains(s[0]) {
+ break
+ }
+ s = s[1:]
+ }
+ return s
+}
+
+func trimLeftUnicode(s, cutset string) string {
+ for len(s) > 0 {
+ r, n := rune(s[0]), 1
+ if r >= utf8.RuneSelf {
+ r, n = utf8.DecodeRuneInString(s)
+ }
+ if !ContainsRune(cutset, r) {
+ break
+ }
+ s = s[n:]
+ }
+ return s
+}
+
+// TrimRight returns a slice of the string s, with all trailing
+// Unicode code points contained in cutset removed.
+//
+// To remove a suffix, use TrimSuffix instead.
+func TrimRight(s, cutset string) string {
+ if s == "" || cutset == "" {
+ return s
+ }
+ if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
+ return trimRightByte(s, cutset[0])
+ }
+ if as, ok := makeASCIISet(cutset); ok {
+ return trimRightASCII(s, &as)
+ }
+ return trimRightUnicode(s, cutset)
+}
+
+func trimRightByte(s string, c byte) string {
+ for len(s) > 0 && s[len(s)-1] == c {
+ s = s[:len(s)-1]
+ }
+ return s
+}
+
+func trimRightASCII(s string, as *asciiSet) string {
+ for len(s) > 0 {
+ if !as.contains(s[len(s)-1]) {
+ break
+ }
+ s = s[:len(s)-1]
+ }
+ return s
+}
+
+func trimRightUnicode(s, cutset string) string {
+ for len(s) > 0 {
+ r, n := rune(s[len(s)-1]), 1
+ if r >= utf8.RuneSelf {
+ r, n = utf8.DecodeLastRuneInString(s)
+ }
+ if !ContainsRune(cutset, r) {
+ break
+ }
+ s = s[:len(s)-n]
+ }
+ return s
+}
+
+// TrimSpace returns a slice of the string s, with all leading
+// and trailing white space removed, as defined by Unicode.
+func TrimSpace(s string) string {
+ // Fast path for ASCII: look for the first ASCII non-space byte
+ start := 0
+ for ; start < len(s); start++ {
+ c := s[start]
+ if c >= utf8.RuneSelf {
+ // If we run into a non-ASCII byte, fall back to the
+ // slower unicode-aware method on the remaining bytes
+ return TrimFunc(s[start:], unicode.IsSpace)
+ }
+ if asciiSpace[c] == 0 {
+ break
+ }
+ }
+
+ // Now look for the first ASCII non-space byte from the end
+ stop := len(s)
+ for ; stop > start; stop-- {
+ c := s[stop-1]
+ if c >= utf8.RuneSelf {
+ // start has been already trimmed above, should trim end only
+ return TrimRightFunc(s[start:stop], unicode.IsSpace)
+ }
+ if asciiSpace[c] == 0 {
+ break
+ }
+ }
+
+ // At this point s[start:stop] starts and ends with an ASCII
+ // non-space bytes, so we're done. Non-ASCII cases have already
+ // been handled above.
+ return s[start:stop]
+}
+
+// TrimPrefix returns s without the provided leading prefix string.
+// If s doesn't start with prefix, s is returned unchanged.
+func TrimPrefix(s, prefix string) string {
+ if HasPrefix(s, prefix) {
+ return s[len(prefix):]
+ }
+ return s
+}
+
+// TrimSuffix returns s without the provided trailing suffix string.
+// If s doesn't end with suffix, s is returned unchanged.
+func TrimSuffix(s, suffix string) string {
+ if HasSuffix(s, suffix) {
+ return s[:len(s)-len(suffix)]
+ }
+ return s
+}
+
+// Replace returns a copy of the string s with the first n
+// non-overlapping instances of old replaced by new.
+// If old is empty, it matches at the beginning of the string
+// and after each UTF-8 sequence, yielding up to k+1 replacements
+// for a k-rune string.
+// If n < 0, there is no limit on the number of replacements.
+func Replace(s, old, new string, n int) string {
+ if old == new || n == 0 {
+ return s // avoid allocation
+ }
+
+ // Compute number of replacements.
+ if m := Count(s, old); m == 0 {
+ return s // avoid allocation
+ } else if n < 0 || m < n {
+ n = m
+ }
+
+ // Apply replacements to buffer.
+ var b Builder
+ b.Grow(len(s) + n*(len(new)-len(old)))
+ start := 0
+ for i := 0; i < n; i++ {
+ j := start
+ if len(old) == 0 {
+ if i > 0 {
+ _, wid := utf8.DecodeRuneInString(s[start:])
+ j += wid
+ }
+ } else {
+ j += Index(s[start:], old)
+ }
+ b.WriteString(s[start:j])
+ b.WriteString(new)
+ start = j + len(old)
+ }
+ b.WriteString(s[start:])
+ return b.String()
+}
+
+// ReplaceAll returns a copy of the string s with all
+// non-overlapping instances of old replaced by new.
+// If old is empty, it matches at the beginning of the string
+// and after each UTF-8 sequence, yielding up to k+1 replacements
+// for a k-rune string.
+func ReplaceAll(s, old, new string) string {
+ return Replace(s, old, new, -1)
+}
+
+// EqualFold reports whether s and t, interpreted as UTF-8 strings,
+// are equal under simple Unicode case-folding, which is a more general
+// form of case-insensitivity.
+func EqualFold(s, t string) bool {
+ // ASCII fast path
+ i := 0
+ for ; i < len(s) && i < len(t); i++ {
+ sr := s[i]
+ tr := t[i]
+ if sr|tr >= utf8.RuneSelf {
+ goto hasUnicode
+ }
+
+ // Easy case.
+ if tr == sr {
+ continue
+ }
+
+ // Make sr < tr to simplify what follows.
+ if tr < sr {
+ tr, sr = sr, tr
+ }
+ // ASCII only, sr/tr must be upper/lower case
+ if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
+ continue
+ }
+ return false
+ }
+ // Check if we've exhausted both strings.
+ return len(s) == len(t)
+
+hasUnicode:
+ s = s[i:]
+ t = t[i:]
+ for _, sr := range s {
+ // If t is exhausted the strings are not equal.
+ if len(t) == 0 {
+ return false
+ }
+
+ // Extract first rune from second string.
+ var tr rune
+ if t[0] < utf8.RuneSelf {
+ tr, t = rune(t[0]), t[1:]
+ } else {
+ r, size := utf8.DecodeRuneInString(t)
+ tr, t = r, t[size:]
+ }
+
+ // If they match, keep going; if not, return false.
+
+ // Easy case.
+ if tr == sr {
+ continue
+ }
+
+ // Make sr < tr to simplify what follows.
+ if tr < sr {
+ tr, sr = sr, tr
+ }
+ // Fast check for ASCII.
+ if tr < utf8.RuneSelf {
+ // ASCII only, sr/tr must be upper/lower case
+ if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
+ continue
+ }
+ return false
+ }
+
+ // General case. SimpleFold(x) returns the next equivalent rune > x
+ // or wraps around to smaller values.
+ r := unicode.SimpleFold(sr)
+ for r != sr && r < tr {
+ r = unicode.SimpleFold(r)
+ }
+ if r == tr {
+ continue
+ }
+ return false
+ }
+
+ // First string is empty, so check if the second one is also empty.
+ return len(t) == 0
+}
+
+// Index returns the index of the first instance of substr in s, or -1 if substr is not present in s.
+func Index(s, substr string) int {
+ n := len(substr)
+ switch {
+ case n == 0:
+ return 0
+ case n == 1:
+ return IndexByte(s, substr[0])
+ case n == len(s):
+ if substr == s {
+ return 0
+ }
+ return -1
+ case n > len(s):
+ return -1
+ case n <= bytealg.MaxLen:
+ // Use brute force when s and substr both are small
+ if len(s) <= bytealg.MaxBruteForce {
+ return bytealg.IndexString(s, substr)
+ }
+ c0 := substr[0]
+ c1 := substr[1]
+ i := 0
+ t := len(s) - n + 1
+ fails := 0
+ for i < t {
+ if s[i] != c0 {
+ // IndexByte is faster than bytealg.IndexString, so use it as long as
+ // we're not getting lots of false positives.
+ o := IndexByte(s[i+1:t], c0)
+ if o < 0 {
+ return -1
+ }
+ i += o + 1
+ }
+ if s[i+1] == c1 && s[i:i+n] == substr {
+ return i
+ }
+ fails++
+ i++
+ // Switch to bytealg.IndexString when IndexByte produces too many false positives.
+ if fails > bytealg.Cutover(i) {
+ r := bytealg.IndexString(s[i:], substr)
+ if r >= 0 {
+ return r + i
+ }
+ return -1
+ }
+ }
+ return -1
+ }
+ c0 := substr[0]
+ c1 := substr[1]
+ i := 0
+ t := len(s) - n + 1
+ fails := 0
+ for i < t {
+ if s[i] != c0 {
+ o := IndexByte(s[i+1:t], c0)
+ if o < 0 {
+ return -1
+ }
+ i += o + 1
+ }
+ if s[i+1] == c1 && s[i:i+n] == substr {
+ return i
+ }
+ i++
+ fails++
+ if fails >= 4+i>>4 && i < t {
+ // See comment in ../bytes/bytes.go.
+ j := bytealg.IndexRabinKarp(s[i:], substr)
+ if j < 0 {
+ return -1
+ }
+ return i + j
+ }
+ }
+ return -1
+}
+
+// Cut slices s around the first instance of sep,
+// returning the text before and after sep.
+// The found result reports whether sep appears in s.
+// If sep does not appear in s, cut returns s, "", false.
+func Cut(s, sep string) (before, after string, found bool) {
+ if i := Index(s, sep); i >= 0 {
+ return s[:i], s[i+len(sep):], true
+ }
+ return s, "", false
+}
+
+// CutPrefix returns s without the provided leading prefix string
+// and reports whether it found the prefix.
+// If s doesn't start with prefix, CutPrefix returns s, false.
+// If prefix is the empty string, CutPrefix returns s, true.
+func CutPrefix(s, prefix string) (after string, found bool) {
+ if !HasPrefix(s, prefix) {
+ return s, false
+ }
+ return s[len(prefix):], true
+}
+
+// CutSuffix returns s without the provided ending suffix string
+// and reports whether it found the suffix.
+// If s doesn't end with suffix, CutSuffix returns s, false.
+// If suffix is the empty string, CutSuffix returns s, true.
+func CutSuffix(s, suffix string) (before string, found bool) {
+ if !HasSuffix(s, suffix) {
+ return s, false
+ }
+ return s[:len(s)-len(suffix)], true
+}
diff --git a/contrib/go/_std_1.21/src/strings/ya.make b/contrib/go/_std_1.21/src/strings/ya.make
new file mode 100644
index 0000000000..4ddb166e9a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/strings/ya.make
@@ -0,0 +1,29 @@
+GO_LIBRARY()
+
+SRCS(
+ builder.go
+ clone.go
+ compare.go
+ reader.go
+ replace.go
+ search.go
+ strings.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ builder_test.go
+ clone_test.go
+ compare_test.go
+ example_test.go
+ reader_test.go
+ replace_test.go
+ search_test.go
+ strings_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/sync/atomic/asm.s b/contrib/go/_std_1.21/src/sync/atomic/asm.s
index 2022304665..2022304665 100644
--- a/contrib/go/_std_1.20/src/sync/atomic/asm.s
+++ b/contrib/go/_std_1.21/src/sync/atomic/asm.s
diff --git a/contrib/go/_std_1.21/src/sync/atomic/doc.go b/contrib/go/_std_1.21/src/sync/atomic/doc.go
new file mode 100644
index 0000000000..c22d1159af
--- /dev/null
+++ b/contrib/go/_std_1.21/src/sync/atomic/doc.go
@@ -0,0 +1,192 @@
+// Copyright 2011 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 atomic provides low-level atomic memory primitives
+// useful for implementing synchronization algorithms.
+//
+// These functions require great care to be used correctly.
+// Except for special, low-level applications, synchronization is better
+// done with channels or the facilities of the [sync] package.
+// Share memory by communicating;
+// don't communicate by sharing memory.
+//
+// The swap operation, implemented by the SwapT functions, is the atomic
+// equivalent of:
+//
+// old = *addr
+// *addr = new
+// return old
+//
+// The compare-and-swap operation, implemented by the CompareAndSwapT
+// functions, is the atomic equivalent of:
+//
+// if *addr == old {
+// *addr = new
+// return true
+// }
+// return false
+//
+// The add operation, implemented by the AddT functions, is the atomic
+// equivalent of:
+//
+// *addr += delta
+// return *addr
+//
+// The load and store operations, implemented by the LoadT and StoreT
+// functions, are the atomic equivalents of "return *addr" and
+// "*addr = val".
+//
+// In the terminology of the Go memory model, if the effect of
+// an atomic operation A is observed by atomic operation B,
+// then A “synchronizes before” B.
+// Additionally, all the atomic operations executed in a program
+// behave as though executed in some sequentially consistent order.
+// This definition provides the same semantics as
+// C++'s sequentially consistent atomics and Java's volatile variables.
+package atomic
+
+import (
+ "unsafe"
+)
+
+// BUG(rsc): On 386, the 64-bit functions use instructions unavailable before the Pentium MMX.
+//
+// On non-Linux ARM, the 64-bit functions use instructions unavailable before the ARMv6k core.
+//
+// On ARM, 386, and 32-bit MIPS, it is the caller's responsibility to arrange
+// for 64-bit alignment of 64-bit words accessed atomically via the primitive
+// atomic functions (types [Int64] and [Uint64] are automatically aligned).
+// The first word in an allocated struct, array, or slice; in a global
+// variable; or in a local variable (because the subject of all atomic operations
+// will escape to the heap) can be relied upon to be 64-bit aligned.
+
+// SwapInt32 atomically stores new into *addr and returns the previous *addr value.
+// Consider using the more ergonomic and less error-prone [Int32.Swap] instead.
+func SwapInt32(addr *int32, new int32) (old int32)
+
+// SwapInt64 atomically stores new into *addr and returns the previous *addr value.
+// Consider using the more ergonomic and less error-prone [Int64.Swap] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
+func SwapInt64(addr *int64, new int64) (old int64)
+
+// SwapUint32 atomically stores new into *addr and returns the previous *addr value.
+// Consider using the more ergonomic and less error-prone [Uint32.Swap] instead.
+func SwapUint32(addr *uint32, new uint32) (old uint32)
+
+// SwapUint64 atomically stores new into *addr and returns the previous *addr value.
+// Consider using the more ergonomic and less error-prone [Uint64.Swap] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
+func SwapUint64(addr *uint64, new uint64) (old uint64)
+
+// SwapUintptr atomically stores new into *addr and returns the previous *addr value.
+// Consider using the more ergonomic and less error-prone [Uintptr.Swap] instead.
+func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)
+
+// SwapPointer atomically stores new into *addr and returns the previous *addr value.
+// Consider using the more ergonomic and less error-prone [Pointer.Swap] instead.
+func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)
+
+// CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value.
+// Consider using the more ergonomic and less error-prone [Int32.CompareAndSwap] instead.
+func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
+
+// CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value.
+// Consider using the more ergonomic and less error-prone [Int64.CompareAndSwap] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
+func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
+
+// CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value.
+// Consider using the more ergonomic and less error-prone [Uint32.CompareAndSwap] instead.
+func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
+
+// CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value.
+// Consider using the more ergonomic and less error-prone [Uint64.CompareAndSwap] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
+func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
+
+// CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value.
+// Consider using the more ergonomic and less error-prone [Uintptr.CompareAndSwap] instead.
+func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)
+
+// CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value.
+// Consider using the more ergonomic and less error-prone [Pointer.CompareAndSwap] instead.
+func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)
+
+// AddInt32 atomically adds delta to *addr and returns the new value.
+// Consider using the more ergonomic and less error-prone [Int32.Add] instead.
+func AddInt32(addr *int32, delta int32) (new int32)
+
+// AddUint32 atomically adds delta to *addr and returns the new value.
+// To subtract a signed positive constant value c from x, do AddUint32(&x, ^uint32(c-1)).
+// In particular, to decrement x, do AddUint32(&x, ^uint32(0)).
+// Consider using the more ergonomic and less error-prone [Uint32.Add] instead.
+func AddUint32(addr *uint32, delta uint32) (new uint32)
+
+// AddInt64 atomically adds delta to *addr and returns the new value.
+// Consider using the more ergonomic and less error-prone [Int64.Add] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
+func AddInt64(addr *int64, delta int64) (new int64)
+
+// AddUint64 atomically adds delta to *addr and returns the new value.
+// To subtract a signed positive constant value c from x, do AddUint64(&x, ^uint64(c-1)).
+// In particular, to decrement x, do AddUint64(&x, ^uint64(0)).
+// Consider using the more ergonomic and less error-prone [Uint64.Add] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
+func AddUint64(addr *uint64, delta uint64) (new uint64)
+
+// AddUintptr atomically adds delta to *addr and returns the new value.
+// Consider using the more ergonomic and less error-prone [Uintptr.Add] instead.
+func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
+
+// LoadInt32 atomically loads *addr.
+// Consider using the more ergonomic and less error-prone [Int32.Load] instead.
+func LoadInt32(addr *int32) (val int32)
+
+// LoadInt64 atomically loads *addr.
+// Consider using the more ergonomic and less error-prone [Int64.Load] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
+func LoadInt64(addr *int64) (val int64)
+
+// LoadUint32 atomically loads *addr.
+// Consider using the more ergonomic and less error-prone [Uint32.Load] instead.
+func LoadUint32(addr *uint32) (val uint32)
+
+// LoadUint64 atomically loads *addr.
+// Consider using the more ergonomic and less error-prone [Uint64.Load] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
+func LoadUint64(addr *uint64) (val uint64)
+
+// LoadUintptr atomically loads *addr.
+// Consider using the more ergonomic and less error-prone [Uintptr.Load] instead.
+func LoadUintptr(addr *uintptr) (val uintptr)
+
+// LoadPointer atomically loads *addr.
+// Consider using the more ergonomic and less error-prone [Pointer.Load] instead.
+func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
+
+// StoreInt32 atomically stores val into *addr.
+// Consider using the more ergonomic and less error-prone [Int32.Store] instead.
+func StoreInt32(addr *int32, val int32)
+
+// StoreInt64 atomically stores val into *addr.
+// Consider using the more ergonomic and less error-prone [Int64.Store] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
+func StoreInt64(addr *int64, val int64)
+
+// StoreUint32 atomically stores val into *addr.
+// Consider using the more ergonomic and less error-prone [Uint32.Store] instead.
+func StoreUint32(addr *uint32, val uint32)
+
+// StoreUint64 atomically stores val into *addr.
+// Consider using the more ergonomic and less error-prone [Uint64.Store] instead
+// (particularly if you target 32-bit platforms; see the bugs section).
+func StoreUint64(addr *uint64, val uint64)
+
+// StoreUintptr atomically stores val into *addr.
+// Consider using the more ergonomic and less error-prone [Uintptr.Store] instead.
+func StoreUintptr(addr *uintptr, val uintptr)
+
+// StorePointer atomically stores val into *addr.
+// Consider using the more ergonomic and less error-prone [Pointer.Store] instead.
+func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)
diff --git a/contrib/go/_std_1.21/src/sync/atomic/type.go b/contrib/go/_std_1.21/src/sync/atomic/type.go
new file mode 100644
index 0000000000..179fa93092
--- /dev/null
+++ b/contrib/go/_std_1.21/src/sync/atomic/type.go
@@ -0,0 +1,200 @@
+// Copyright 2022 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 atomic
+
+import "unsafe"
+
+// A Bool is an atomic boolean value.
+// The zero value is false.
+type Bool struct {
+ _ noCopy
+ v uint32
+}
+
+// Load atomically loads and returns the value stored in x.
+func (x *Bool) Load() bool { return LoadUint32(&x.v) != 0 }
+
+// Store atomically stores val into x.
+func (x *Bool) Store(val bool) { StoreUint32(&x.v, b32(val)) }
+
+// Swap atomically stores new into x and returns the previous value.
+func (x *Bool) Swap(new bool) (old bool) { return SwapUint32(&x.v, b32(new)) != 0 }
+
+// CompareAndSwap executes the compare-and-swap operation for the boolean value x.
+func (x *Bool) CompareAndSwap(old, new bool) (swapped bool) {
+ return CompareAndSwapUint32(&x.v, b32(old), b32(new))
+}
+
+// b32 returns a uint32 0 or 1 representing b.
+func b32(b bool) uint32 {
+ if b {
+ return 1
+ }
+ return 0
+}
+
+// For testing *Pointer[T]'s methods can be inlined.
+// Keep in sync with cmd/compile/internal/test/inl_test.go:TestIntendedInlining.
+var _ = &Pointer[int]{}
+
+// A Pointer is an atomic pointer of type *T. The zero value is a nil *T.
+type Pointer[T any] struct {
+ // Mention *T in a field to disallow conversion between Pointer types.
+ // See go.dev/issue/56603 for more details.
+ // Use *T, not T, to avoid spurious recursive type definition errors.
+ _ [0]*T
+
+ _ noCopy
+ v unsafe.Pointer
+}
+
+// Load atomically loads and returns the value stored in x.
+func (x *Pointer[T]) Load() *T { return (*T)(LoadPointer(&x.v)) }
+
+// Store atomically stores val into x.
+func (x *Pointer[T]) Store(val *T) { StorePointer(&x.v, unsafe.Pointer(val)) }
+
+// Swap atomically stores new into x and returns the previous value.
+func (x *Pointer[T]) Swap(new *T) (old *T) { return (*T)(SwapPointer(&x.v, unsafe.Pointer(new))) }
+
+// CompareAndSwap executes the compare-and-swap operation for x.
+func (x *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) {
+ return CompareAndSwapPointer(&x.v, unsafe.Pointer(old), unsafe.Pointer(new))
+}
+
+// An Int32 is an atomic int32. The zero value is zero.
+type Int32 struct {
+ _ noCopy
+ v int32
+}
+
+// Load atomically loads and returns the value stored in x.
+func (x *Int32) Load() int32 { return LoadInt32(&x.v) }
+
+// Store atomically stores val into x.
+func (x *Int32) Store(val int32) { StoreInt32(&x.v, val) }
+
+// Swap atomically stores new into x and returns the previous value.
+func (x *Int32) Swap(new int32) (old int32) { return SwapInt32(&x.v, new) }
+
+// CompareAndSwap executes the compare-and-swap operation for x.
+func (x *Int32) CompareAndSwap(old, new int32) (swapped bool) {
+ return CompareAndSwapInt32(&x.v, old, new)
+}
+
+// Add atomically adds delta to x and returns the new value.
+func (x *Int32) Add(delta int32) (new int32) { return AddInt32(&x.v, delta) }
+
+// An Int64 is an atomic int64. The zero value is zero.
+type Int64 struct {
+ _ noCopy
+ _ align64
+ v int64
+}
+
+// Load atomically loads and returns the value stored in x.
+func (x *Int64) Load() int64 { return LoadInt64(&x.v) }
+
+// Store atomically stores val into x.
+func (x *Int64) Store(val int64) { StoreInt64(&x.v, val) }
+
+// Swap atomically stores new into x and returns the previous value.
+func (x *Int64) Swap(new int64) (old int64) { return SwapInt64(&x.v, new) }
+
+// CompareAndSwap executes the compare-and-swap operation for x.
+func (x *Int64) CompareAndSwap(old, new int64) (swapped bool) {
+ return CompareAndSwapInt64(&x.v, old, new)
+}
+
+// Add atomically adds delta to x and returns the new value.
+func (x *Int64) Add(delta int64) (new int64) { return AddInt64(&x.v, delta) }
+
+// A Uint32 is an atomic uint32. The zero value is zero.
+type Uint32 struct {
+ _ noCopy
+ v uint32
+}
+
+// Load atomically loads and returns the value stored in x.
+func (x *Uint32) Load() uint32 { return LoadUint32(&x.v) }
+
+// Store atomically stores val into x.
+func (x *Uint32) Store(val uint32) { StoreUint32(&x.v, val) }
+
+// Swap atomically stores new into x and returns the previous value.
+func (x *Uint32) Swap(new uint32) (old uint32) { return SwapUint32(&x.v, new) }
+
+// CompareAndSwap executes the compare-and-swap operation for x.
+func (x *Uint32) CompareAndSwap(old, new uint32) (swapped bool) {
+ return CompareAndSwapUint32(&x.v, old, new)
+}
+
+// Add atomically adds delta to x and returns the new value.
+func (x *Uint32) Add(delta uint32) (new uint32) { return AddUint32(&x.v, delta) }
+
+// A Uint64 is an atomic uint64. The zero value is zero.
+type Uint64 struct {
+ _ noCopy
+ _ align64
+ v uint64
+}
+
+// Load atomically loads and returns the value stored in x.
+func (x *Uint64) Load() uint64 { return LoadUint64(&x.v) }
+
+// Store atomically stores val into x.
+func (x *Uint64) Store(val uint64) { StoreUint64(&x.v, val) }
+
+// Swap atomically stores new into x and returns the previous value.
+func (x *Uint64) Swap(new uint64) (old uint64) { return SwapUint64(&x.v, new) }
+
+// CompareAndSwap executes the compare-and-swap operation for x.
+func (x *Uint64) CompareAndSwap(old, new uint64) (swapped bool) {
+ return CompareAndSwapUint64(&x.v, old, new)
+}
+
+// Add atomically adds delta to x and returns the new value.
+func (x *Uint64) Add(delta uint64) (new uint64) { return AddUint64(&x.v, delta) }
+
+// A Uintptr is an atomic uintptr. The zero value is zero.
+type Uintptr struct {
+ _ noCopy
+ v uintptr
+}
+
+// Load atomically loads and returns the value stored in x.
+func (x *Uintptr) Load() uintptr { return LoadUintptr(&x.v) }
+
+// Store atomically stores val into x.
+func (x *Uintptr) Store(val uintptr) { StoreUintptr(&x.v, val) }
+
+// Swap atomically stores new into x and returns the previous value.
+func (x *Uintptr) Swap(new uintptr) (old uintptr) { return SwapUintptr(&x.v, new) }
+
+// CompareAndSwap executes the compare-and-swap operation for x.
+func (x *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) {
+ return CompareAndSwapUintptr(&x.v, old, new)
+}
+
+// Add atomically adds delta to x and returns the new value.
+func (x *Uintptr) Add(delta uintptr) (new uintptr) { return AddUintptr(&x.v, delta) }
+
+// noCopy may be added to structs which must not be copied
+// after the first use.
+//
+// See https://golang.org/issues/8005#issuecomment-190753527
+// for details.
+//
+// Note that it must not be embedded, due to the Lock and Unlock methods.
+type noCopy struct{}
+
+// Lock is a no-op used by -copylocks checker from `go vet`.
+func (*noCopy) Lock() {}
+func (*noCopy) Unlock() {}
+
+// align64 may be added to structs that must be 64-bit aligned.
+// This struct is recognized by a special case in the compiler
+// and will not work if copied to any other package.
+type align64 struct{}
diff --git a/contrib/go/_std_1.20/src/sync/atomic/value.go b/contrib/go/_std_1.21/src/sync/atomic/value.go
index a57b08a6b8..a57b08a6b8 100644
--- a/contrib/go/_std_1.20/src/sync/atomic/value.go
+++ b/contrib/go/_std_1.21/src/sync/atomic/value.go
diff --git a/contrib/go/_std_1.21/src/sync/atomic/ya.make b/contrib/go/_std_1.21/src/sync/atomic/ya.make
new file mode 100644
index 0000000000..b36a6ba016
--- /dev/null
+++ b/contrib/go/_std_1.21/src/sync/atomic/ya.make
@@ -0,0 +1,28 @@
+GO_LIBRARY()
+
+SRCS(
+ doc.go
+ type.go
+ value.go
+)
+
+IF (RACE)
+ SRCS(
+ race.s
+ )
+ELSE()
+ SRCS(
+ asm.s
+ )
+ENDIF()
+
+GO_XTEST_SRCS(
+ atomic_test.go
+ example_test.go
+ value_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/sync/cond.go b/contrib/go/_std_1.21/src/sync/cond.go
index cc927adf58..cc927adf58 100644
--- a/contrib/go/_std_1.20/src/sync/cond.go
+++ b/contrib/go/_std_1.21/src/sync/cond.go
diff --git a/contrib/go/_std_1.20/src/sync/map.go b/contrib/go/_std_1.21/src/sync/map.go
index e8ccf58b56..e8ccf58b56 100644
--- a/contrib/go/_std_1.20/src/sync/map.go
+++ b/contrib/go/_std_1.21/src/sync/map.go
diff --git a/contrib/go/_std_1.20/src/sync/mutex.go b/contrib/go/_std_1.21/src/sync/mutex.go
index 2ea024e585..2ea024e585 100644
--- a/contrib/go/_std_1.20/src/sync/mutex.go
+++ b/contrib/go/_std_1.21/src/sync/mutex.go
diff --git a/contrib/go/_std_1.20/src/sync/once.go b/contrib/go/_std_1.21/src/sync/once.go
index b6399cfc3d..b6399cfc3d 100644
--- a/contrib/go/_std_1.20/src/sync/once.go
+++ b/contrib/go/_std_1.21/src/sync/once.go
diff --git a/contrib/go/_std_1.21/src/sync/oncefunc.go b/contrib/go/_std_1.21/src/sync/oncefunc.go
new file mode 100644
index 0000000000..9ef8344132
--- /dev/null
+++ b/contrib/go/_std_1.21/src/sync/oncefunc.go
@@ -0,0 +1,97 @@
+// Copyright 2022 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 sync
+
+// OnceFunc returns a function that invokes f only once. The returned function
+// may be called concurrently.
+//
+// If f panics, the returned function will panic with the same value on every call.
+func OnceFunc(f func()) func() {
+ var (
+ once Once
+ valid bool
+ p any
+ )
+ // Construct the inner closure just once to reduce costs on the fast path.
+ g := func() {
+ defer func() {
+ p = recover()
+ if !valid {
+ // Re-panic immediately so on the first call the user gets a
+ // complete stack trace into f.
+ panic(p)
+ }
+ }()
+ f()
+ valid = true // Set only if f does not panic
+ }
+ return func() {
+ once.Do(g)
+ if !valid {
+ panic(p)
+ }
+ }
+}
+
+// OnceValue returns a function that invokes f only once and returns the value
+// returned by f. The returned function may be called concurrently.
+//
+// If f panics, the returned function will panic with the same value on every call.
+func OnceValue[T any](f func() T) func() T {
+ var (
+ once Once
+ valid bool
+ p any
+ result T
+ )
+ g := func() {
+ defer func() {
+ p = recover()
+ if !valid {
+ panic(p)
+ }
+ }()
+ result = f()
+ valid = true
+ }
+ return func() T {
+ once.Do(g)
+ if !valid {
+ panic(p)
+ }
+ return result
+ }
+}
+
+// OnceValues returns a function that invokes f only once and returns the values
+// returned by f. The returned function may be called concurrently.
+//
+// If f panics, the returned function will panic with the same value on every call.
+func OnceValues[T1, T2 any](f func() (T1, T2)) func() (T1, T2) {
+ var (
+ once Once
+ valid bool
+ p any
+ r1 T1
+ r2 T2
+ )
+ g := func() {
+ defer func() {
+ p = recover()
+ if !valid {
+ panic(p)
+ }
+ }()
+ r1, r2 = f()
+ valid = true
+ }
+ return func() (T1, T2) {
+ once.Do(g)
+ if !valid {
+ panic(p)
+ }
+ return r1, r2
+ }
+}
diff --git a/contrib/go/_std_1.20/src/sync/pool.go b/contrib/go/_std_1.21/src/sync/pool.go
index cf01e2e189..cf01e2e189 100644
--- a/contrib/go/_std_1.20/src/sync/pool.go
+++ b/contrib/go/_std_1.21/src/sync/pool.go
diff --git a/contrib/go/_std_1.20/src/sync/poolqueue.go b/contrib/go/_std_1.21/src/sync/poolqueue.go
index 631f2c15fd..631f2c15fd 100644
--- a/contrib/go/_std_1.20/src/sync/poolqueue.go
+++ b/contrib/go/_std_1.21/src/sync/poolqueue.go
diff --git a/contrib/go/_std_1.20/src/sync/runtime.go b/contrib/go/_std_1.21/src/sync/runtime.go
index 5a90813585..5a90813585 100644
--- a/contrib/go/_std_1.20/src/sync/runtime.go
+++ b/contrib/go/_std_1.21/src/sync/runtime.go
diff --git a/contrib/go/_std_1.20/src/sync/runtime2.go b/contrib/go/_std_1.21/src/sync/runtime2.go
index 9b7e9922fb..9b7e9922fb 100644
--- a/contrib/go/_std_1.20/src/sync/runtime2.go
+++ b/contrib/go/_std_1.21/src/sync/runtime2.go
diff --git a/contrib/go/_std_1.21/src/sync/rwmutex.go b/contrib/go/_std_1.21/src/sync/rwmutex.go
new file mode 100644
index 0000000000..1317624035
--- /dev/null
+++ b/contrib/go/_std_1.21/src/sync/rwmutex.go
@@ -0,0 +1,244 @@
+// Copyright 2009 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 sync
+
+import (
+ "internal/race"
+ "sync/atomic"
+ "unsafe"
+)
+
+// There is a modified copy of this file in runtime/rwmutex.go.
+// If you make any changes here, see if you should make them there.
+
+// A RWMutex is a reader/writer mutual exclusion lock.
+// The lock can be held by an arbitrary number of readers or a single writer.
+// The zero value for a RWMutex is an unlocked mutex.
+//
+// A RWMutex must not be copied after first use.
+//
+// If a goroutine holds a RWMutex for reading and another goroutine might
+// call Lock, no goroutine should expect to be able to acquire a read lock
+// until the initial read lock is released. In particular, this prohibits
+// recursive read locking. This is to ensure that the lock eventually becomes
+// available; a blocked Lock call excludes new readers from acquiring the
+// lock.
+//
+// In the terminology of the Go memory model,
+// the n'th call to Unlock “synchronizes before” the m'th call to Lock
+// for any n < m, just as for Mutex.
+// For any call to RLock, there exists an n such that
+// the n'th call to Unlock “synchronizes before” that call to RLock,
+// and the corresponding call to RUnlock “synchronizes before”
+// the n+1'th call to Lock.
+type RWMutex struct {
+ w Mutex // held if there are pending writers
+ writerSem uint32 // semaphore for writers to wait for completing readers
+ readerSem uint32 // semaphore for readers to wait for completing writers
+ readerCount atomic.Int32 // number of pending readers
+ readerWait atomic.Int32 // number of departing readers
+}
+
+const rwmutexMaxReaders = 1 << 30
+
+// Happens-before relationships are indicated to the race detector via:
+// - Unlock -> Lock: readerSem
+// - Unlock -> RLock: readerSem
+// - RUnlock -> Lock: writerSem
+//
+// The methods below temporarily disable handling of race synchronization
+// events in order to provide the more precise model above to the race
+// detector.
+//
+// For example, atomic.AddInt32 in RLock should not appear to provide
+// acquire-release semantics, which would incorrectly synchronize racing
+// readers, thus potentially missing races.
+
+// RLock locks rw for reading.
+//
+// It should not be used for recursive read locking; a blocked Lock
+// call excludes new readers from acquiring the lock. See the
+// documentation on the RWMutex type.
+func (rw *RWMutex) RLock() {
+ if race.Enabled {
+ _ = rw.w.state
+ race.Disable()
+ }
+ if rw.readerCount.Add(1) < 0 {
+ // A writer is pending, wait for it.
+ runtime_SemacquireRWMutexR(&rw.readerSem, false, 0)
+ }
+ if race.Enabled {
+ race.Enable()
+ race.Acquire(unsafe.Pointer(&rw.readerSem))
+ }
+}
+
+// TryRLock tries to lock rw for reading and reports whether it succeeded.
+//
+// Note that while correct uses of TryRLock do exist, they are rare,
+// and use of TryRLock is often a sign of a deeper problem
+// in a particular use of mutexes.
+func (rw *RWMutex) TryRLock() bool {
+ if race.Enabled {
+ _ = rw.w.state
+ race.Disable()
+ }
+ for {
+ c := rw.readerCount.Load()
+ if c < 0 {
+ if race.Enabled {
+ race.Enable()
+ }
+ return false
+ }
+ if rw.readerCount.CompareAndSwap(c, c+1) {
+ if race.Enabled {
+ race.Enable()
+ race.Acquire(unsafe.Pointer(&rw.readerSem))
+ }
+ return true
+ }
+ }
+}
+
+// RUnlock undoes a single RLock call;
+// it does not affect other simultaneous readers.
+// It is a run-time error if rw is not locked for reading
+// on entry to RUnlock.
+func (rw *RWMutex) RUnlock() {
+ if race.Enabled {
+ _ = rw.w.state
+ race.ReleaseMerge(unsafe.Pointer(&rw.writerSem))
+ race.Disable()
+ }
+ if r := rw.readerCount.Add(-1); r < 0 {
+ // Outlined slow-path to allow the fast-path to be inlined
+ rw.rUnlockSlow(r)
+ }
+ if race.Enabled {
+ race.Enable()
+ }
+}
+
+func (rw *RWMutex) rUnlockSlow(r int32) {
+ if r+1 == 0 || r+1 == -rwmutexMaxReaders {
+ race.Enable()
+ fatal("sync: RUnlock of unlocked RWMutex")
+ }
+ // A writer is pending.
+ if rw.readerWait.Add(-1) == 0 {
+ // The last reader unblocks the writer.
+ runtime_Semrelease(&rw.writerSem, false, 1)
+ }
+}
+
+// Lock locks rw for writing.
+// If the lock is already locked for reading or writing,
+// Lock blocks until the lock is available.
+func (rw *RWMutex) Lock() {
+ if race.Enabled {
+ _ = rw.w.state
+ race.Disable()
+ }
+ // First, resolve competition with other writers.
+ rw.w.Lock()
+ // Announce to readers there is a pending writer.
+ r := rw.readerCount.Add(-rwmutexMaxReaders) + rwmutexMaxReaders
+ // Wait for active readers.
+ if r != 0 && rw.readerWait.Add(r) != 0 {
+ runtime_SemacquireRWMutex(&rw.writerSem, false, 0)
+ }
+ if race.Enabled {
+ race.Enable()
+ race.Acquire(unsafe.Pointer(&rw.readerSem))
+ race.Acquire(unsafe.Pointer(&rw.writerSem))
+ }
+}
+
+// TryLock tries to lock rw for writing and reports whether it succeeded.
+//
+// Note that while correct uses of TryLock do exist, they are rare,
+// and use of TryLock is often a sign of a deeper problem
+// in a particular use of mutexes.
+func (rw *RWMutex) TryLock() bool {
+ if race.Enabled {
+ _ = rw.w.state
+ race.Disable()
+ }
+ if !rw.w.TryLock() {
+ if race.Enabled {
+ race.Enable()
+ }
+ return false
+ }
+ if !rw.readerCount.CompareAndSwap(0, -rwmutexMaxReaders) {
+ rw.w.Unlock()
+ if race.Enabled {
+ race.Enable()
+ }
+ return false
+ }
+ if race.Enabled {
+ race.Enable()
+ race.Acquire(unsafe.Pointer(&rw.readerSem))
+ race.Acquire(unsafe.Pointer(&rw.writerSem))
+ }
+ return true
+}
+
+// Unlock unlocks rw for writing. It is a run-time error if rw is
+// not locked for writing on entry to Unlock.
+//
+// As with Mutexes, a locked RWMutex is not associated with a particular
+// goroutine. One goroutine may RLock (Lock) a RWMutex and then
+// arrange for another goroutine to RUnlock (Unlock) it.
+func (rw *RWMutex) Unlock() {
+ if race.Enabled {
+ _ = rw.w.state
+ race.Release(unsafe.Pointer(&rw.readerSem))
+ race.Disable()
+ }
+
+ // Announce to readers there is no active writer.
+ r := rw.readerCount.Add(rwmutexMaxReaders)
+ if r >= rwmutexMaxReaders {
+ race.Enable()
+ fatal("sync: Unlock of unlocked RWMutex")
+ }
+ // Unblock blocked readers, if any.
+ for i := 0; i < int(r); i++ {
+ runtime_Semrelease(&rw.readerSem, false, 0)
+ }
+ // Allow other writers to proceed.
+ rw.w.Unlock()
+ if race.Enabled {
+ race.Enable()
+ }
+}
+
+// syscall_hasWaitingReaders reports whether any goroutine is waiting
+// to acquire a read lock on rw. This exists because syscall.ForkLock
+// is an RWMutex, and we can't change that without breaking compatibility.
+// We don't need or want RWMutex semantics for ForkLock, and we use
+// this private API to avoid having to change the type of ForkLock.
+// For more details see the syscall package.
+//
+//go:linkname syscall_hasWaitingReaders syscall.hasWaitingReaders
+func syscall_hasWaitingReaders(rw *RWMutex) bool {
+ r := rw.readerCount.Load()
+ return r < 0 && r+rwmutexMaxReaders > 0
+}
+
+// RLocker returns a Locker interface that implements
+// the Lock and Unlock methods by calling rw.RLock and rw.RUnlock.
+func (rw *RWMutex) RLocker() Locker {
+ return (*rlocker)(rw)
+}
+
+type rlocker RWMutex
+
+func (r *rlocker) Lock() { (*RWMutex)(r).RLock() }
+func (r *rlocker) Unlock() { (*RWMutex)(r).RUnlock() }
diff --git a/contrib/go/_std_1.20/src/sync/waitgroup.go b/contrib/go/_std_1.21/src/sync/waitgroup.go
index be21417f9c..be21417f9c 100644
--- a/contrib/go/_std_1.20/src/sync/waitgroup.go
+++ b/contrib/go/_std_1.21/src/sync/waitgroup.go
diff --git a/contrib/go/_std_1.21/src/sync/ya.make b/contrib/go/_std_1.21/src/sync/ya.make
new file mode 100644
index 0000000000..1e45f81ebf
--- /dev/null
+++ b/contrib/go/_std_1.21/src/sync/ya.make
@@ -0,0 +1,39 @@
+GO_LIBRARY()
+
+SRCS(
+ cond.go
+ map.go
+ mutex.go
+ once.go
+ oncefunc.go
+ pool.go
+ poolqueue.go
+ runtime.go
+ runtime2.go
+ rwmutex.go
+ waitgroup.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(
+ cond_test.go
+ example_pool_test.go
+ example_test.go
+ map_bench_test.go
+ map_reference_test.go
+ map_test.go
+ mutex_test.go
+ once_test.go
+ oncefunc_test.go
+ pool_test.go
+ runtime_sema_test.go
+ rwmutex_test.go
+ waitgroup_test.go
+)
+
+END()
+
+RECURSE(
+ atomic
+)
diff --git a/contrib/go/_std_1.20/src/syscall/asan0.go b/contrib/go/_std_1.21/src/syscall/asan0.go
index 08bc44dea1..08bc44dea1 100644
--- a/contrib/go/_std_1.20/src/syscall/asan0.go
+++ b/contrib/go/_std_1.21/src/syscall/asan0.go
diff --git a/contrib/go/_std_1.20/src/syscall/asm_darwin_amd64.s b/contrib/go/_std_1.21/src/syscall/asm_darwin_amd64.s
index 77b58e051b..77b58e051b 100644
--- a/contrib/go/_std_1.20/src/syscall/asm_darwin_amd64.s
+++ b/contrib/go/_std_1.21/src/syscall/asm_darwin_amd64.s
diff --git a/contrib/go/_std_1.20/src/syscall/asm_linux_amd64.s b/contrib/go/_std_1.21/src/syscall/asm_linux_amd64.s
index 00d6fedc62..00d6fedc62 100644
--- a/contrib/go/_std_1.20/src/syscall/asm_linux_amd64.s
+++ b/contrib/go/_std_1.21/src/syscall/asm_linux_amd64.s
diff --git a/contrib/go/_std_1.20/src/syscall/asm_linux_arm64.s b/contrib/go/_std_1.21/src/syscall/asm_linux_arm64.s
index 7fa789a349..7fa789a349 100644
--- a/contrib/go/_std_1.20/src/syscall/asm_linux_arm64.s
+++ b/contrib/go/_std_1.21/src/syscall/asm_linux_arm64.s
diff --git a/contrib/go/_std_1.20/src/syscall/bpf_darwin.go b/contrib/go/_std_1.21/src/syscall/bpf_darwin.go
index fb86049ae9..fb86049ae9 100644
--- a/contrib/go/_std_1.20/src/syscall/bpf_darwin.go
+++ b/contrib/go/_std_1.21/src/syscall/bpf_darwin.go
diff --git a/contrib/go/_std_1.21/src/syscall/dirent.go b/contrib/go/_std_1.21/src/syscall/dirent.go
new file mode 100644
index 0000000000..1a0f1eec11
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/dirent.go
@@ -0,0 +1,107 @@
+// Copyright 2009 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package syscall
+
+import (
+ "runtime"
+ "unsafe"
+)
+
+// readInt returns the size-bytes unsigned integer in native byte order at offset off.
+func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
+ if len(b) < int(off+size) {
+ return 0, false
+ }
+ if isBigEndian {
+ return readIntBE(b[off:], size), true
+ }
+ return readIntLE(b[off:], size), true
+}
+
+func readIntBE(b []byte, size uintptr) uint64 {
+ switch size {
+ case 1:
+ return uint64(b[0])
+ case 2:
+ _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[1]) | uint64(b[0])<<8
+ case 4:
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24
+ case 8:
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+ uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+ default:
+ panic("syscall: readInt with unsupported size")
+ }
+}
+
+func readIntLE(b []byte, size uintptr) uint64 {
+ switch size {
+ case 1:
+ return uint64(b[0])
+ case 2:
+ _ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8
+ case 4:
+ _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
+ case 8:
+ _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
+ return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
+ uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+ default:
+ panic("syscall: readInt with unsupported size")
+ }
+}
+
+// ParseDirent parses up to max directory entries in buf,
+// appending the names to names. It returns the number of
+// bytes consumed from buf, the number of entries added
+// to names, and the new names slice.
+func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
+ origlen := len(buf)
+ count = 0
+ for max != 0 && len(buf) > 0 {
+ reclen, ok := direntReclen(buf)
+ if !ok || reclen > uint64(len(buf)) {
+ return origlen, count, names
+ }
+ rec := buf[:reclen]
+ buf = buf[reclen:]
+ ino, ok := direntIno(rec)
+ if !ok {
+ break
+ }
+ // See src/os/dir_unix.go for the reason why this condition is
+ // excluded on wasip1.
+ if ino == 0 && runtime.GOOS != "wasip1" { // File absent in directory.
+ continue
+ }
+ const namoff = uint64(unsafe.Offsetof(Dirent{}.Name))
+ namlen, ok := direntNamlen(rec)
+ if !ok || namoff+namlen > uint64(len(rec)) {
+ break
+ }
+ name := rec[namoff : namoff+namlen]
+ for i, c := range name {
+ if c == 0 {
+ name = name[:i]
+ break
+ }
+ }
+ // Check for useless names before allocating a string.
+ if string(name) == "." || string(name) == ".." {
+ continue
+ }
+ max--
+ count++
+ names = append(names, string(name))
+ }
+ return origlen - len(buf), count, names
+}
diff --git a/contrib/go/_std_1.21/src/syscall/dll_windows.go b/contrib/go/_std_1.21/src/syscall/dll_windows.go
new file mode 100644
index 0000000000..5f62b5512c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/dll_windows.go
@@ -0,0 +1,287 @@
+// Copyright 2011 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 syscall
+
+import (
+ "internal/syscall/windows/sysdll"
+ "sync"
+ "sync/atomic"
+ "unsafe"
+)
+
+// DLLError describes reasons for DLL load failures.
+type DLLError struct {
+ Err error
+ ObjName string
+ Msg string
+}
+
+func (e *DLLError) Error() string { return e.Msg }
+
+func (e *DLLError) Unwrap() error { return e.Err }
+
+// Implemented in ../runtime/syscall_windows.go.
+
+// Deprecated: Use SyscallN instead.
+func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+
+// Deprecated: Use SyscallN instead.
+func Syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+
+// Deprecated: Use SyscallN instead.
+func Syscall9(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
+
+// Deprecated: Use SyscallN instead.
+func Syscall12(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2 uintptr, err Errno)
+
+// Deprecated: Use SyscallN instead.
+func Syscall15(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2 uintptr, err Errno)
+
+// Deprecated: Use SyscallN instead.
+func Syscall18(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 uintptr) (r1, r2 uintptr, err Errno)
+
+func SyscallN(trap uintptr, args ...uintptr) (r1, r2 uintptr, err Errno)
+func loadlibrary(filename *uint16) (handle uintptr, err Errno)
+func loadsystemlibrary(filename *uint16) (handle uintptr, err Errno)
+func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno)
+
+// A DLL implements access to a single DLL.
+type DLL struct {
+ Name string
+ Handle Handle
+}
+
+// LoadDLL loads the named DLL file into memory.
+//
+// If name is not an absolute path and is not a known system DLL used by
+// Go, Windows will search for the named DLL in many locations, causing
+// potential DLL preloading attacks.
+//
+// Use LazyDLL in golang.org/x/sys/windows for a secure way to
+// load system DLLs.
+func LoadDLL(name string) (*DLL, error) {
+ namep, err := UTF16PtrFromString(name)
+ if err != nil {
+ return nil, err
+ }
+ var h uintptr
+ var e Errno
+ if sysdll.IsSystemDLL[name] {
+ h, e = loadsystemlibrary(namep)
+ } else {
+ h, e = loadlibrary(namep)
+ }
+ if e != 0 {
+ return nil, &DLLError{
+ Err: e,
+ ObjName: name,
+ Msg: "Failed to load " + name + ": " + e.Error(),
+ }
+ }
+ d := &DLL{
+ Name: name,
+ Handle: Handle(h),
+ }
+ return d, nil
+}
+
+// MustLoadDLL is like LoadDLL but panics if load operation fails.
+func MustLoadDLL(name string) *DLL {
+ d, e := LoadDLL(name)
+ if e != nil {
+ panic(e)
+ }
+ return d
+}
+
+// FindProc searches DLL d for procedure named name and returns *Proc
+// if found. It returns an error if search fails.
+func (d *DLL) FindProc(name string) (proc *Proc, err error) {
+ namep, err := BytePtrFromString(name)
+ if err != nil {
+ return nil, err
+ }
+ a, e := getprocaddress(uintptr(d.Handle), namep)
+ if e != 0 {
+ return nil, &DLLError{
+ Err: e,
+ ObjName: name,
+ Msg: "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
+ }
+ }
+ p := &Proc{
+ Dll: d,
+ Name: name,
+ addr: a,
+ }
+ return p, nil
+}
+
+// MustFindProc is like FindProc but panics if search fails.
+func (d *DLL) MustFindProc(name string) *Proc {
+ p, e := d.FindProc(name)
+ if e != nil {
+ panic(e)
+ }
+ return p
+}
+
+// Release unloads DLL d from memory.
+func (d *DLL) Release() (err error) {
+ return FreeLibrary(d.Handle)
+}
+
+// A Proc implements access to a procedure inside a DLL.
+type Proc struct {
+ Dll *DLL
+ Name string
+ addr uintptr
+}
+
+// Addr returns the address of the procedure represented by p.
+// The return value can be passed to Syscall to run the procedure.
+func (p *Proc) Addr() uintptr {
+ return p.addr
+}
+
+// Call executes procedure p with arguments a.
+//
+// The returned error is always non-nil, constructed from the result of GetLastError.
+// Callers must inspect the primary return value to decide whether an error occurred
+// (according to the semantics of the specific function being called) before consulting
+// the error. The error always has type syscall.Errno.
+//
+// On amd64, Call can pass and return floating-point values. To pass
+// an argument x with C type "float", use
+// uintptr(math.Float32bits(x)). To pass an argument with C type
+// "double", use uintptr(math.Float64bits(x)). Floating-point return
+// values are returned in r2. The return value for C type "float" is
+// math.Float32frombits(uint32(r2)). For C type "double", it is
+// math.Float64frombits(uint64(r2)).
+//
+//go:uintptrescapes
+func (p *Proc) Call(a ...uintptr) (uintptr, uintptr, error) {
+ return SyscallN(p.Addr(), a...)
+}
+
+// A LazyDLL implements access to a single DLL.
+// It will delay the load of the DLL until the first
+// call to its Handle method or to one of its
+// LazyProc's Addr method.
+//
+// LazyDLL is subject to the same DLL preloading attacks as documented
+// on LoadDLL.
+//
+// Use LazyDLL in golang.org/x/sys/windows for a secure way to
+// load system DLLs.
+type LazyDLL struct {
+ mu sync.Mutex
+ dll *DLL // non nil once DLL is loaded
+ Name string
+}
+
+// Load loads DLL file d.Name into memory. It returns an error if fails.
+// Load will not try to load DLL, if it is already loaded into memory.
+func (d *LazyDLL) Load() error {
+ // Non-racy version of:
+ // if d.dll == nil {
+ if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) == nil {
+ d.mu.Lock()
+ defer d.mu.Unlock()
+ if d.dll == nil {
+ dll, e := LoadDLL(d.Name)
+ if e != nil {
+ return e
+ }
+ // Non-racy version of:
+ // d.dll = dll
+ atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll))
+ }
+ }
+ return nil
+}
+
+// mustLoad is like Load but panics if search fails.
+func (d *LazyDLL) mustLoad() {
+ e := d.Load()
+ if e != nil {
+ panic(e)
+ }
+}
+
+// Handle returns d's module handle.
+func (d *LazyDLL) Handle() uintptr {
+ d.mustLoad()
+ return uintptr(d.dll.Handle)
+}
+
+// NewProc returns a LazyProc for accessing the named procedure in the DLL d.
+func (d *LazyDLL) NewProc(name string) *LazyProc {
+ return &LazyProc{l: d, Name: name}
+}
+
+// NewLazyDLL creates new LazyDLL associated with DLL file.
+func NewLazyDLL(name string) *LazyDLL {
+ return &LazyDLL{Name: name}
+}
+
+// A LazyProc implements access to a procedure inside a LazyDLL.
+// It delays the lookup until the Addr, Call, or Find method is called.
+type LazyProc struct {
+ mu sync.Mutex
+ Name string
+ l *LazyDLL
+ proc *Proc
+}
+
+// Find searches DLL for procedure named p.Name. It returns
+// an error if search fails. Find will not search procedure,
+// if it is already found and loaded into memory.
+func (p *LazyProc) Find() error {
+ // Non-racy version of:
+ // if p.proc == nil {
+ if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil {
+ p.mu.Lock()
+ defer p.mu.Unlock()
+ if p.proc == nil {
+ e := p.l.Load()
+ if e != nil {
+ return e
+ }
+ proc, e := p.l.dll.FindProc(p.Name)
+ if e != nil {
+ return e
+ }
+ // Non-racy version of:
+ // p.proc = proc
+ atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc))
+ }
+ }
+ return nil
+}
+
+// mustFind is like Find but panics if search fails.
+func (p *LazyProc) mustFind() {
+ e := p.Find()
+ if e != nil {
+ panic(e)
+ }
+}
+
+// Addr returns the address of the procedure represented by p.
+// The return value can be passed to Syscall to run the procedure.
+func (p *LazyProc) Addr() uintptr {
+ p.mustFind()
+ return p.proc.Addr()
+}
+
+// Call executes procedure p with arguments a. See the documentation of
+// Proc.Call for more information.
+//
+//go:uintptrescapes
+func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
+ p.mustFind()
+ return p.proc.Call(a...)
+}
diff --git a/contrib/go/_std_1.20/src/syscall/endian_little.go b/contrib/go/_std_1.21/src/syscall/endian_little.go
index f5fcb58db4..f5fcb58db4 100644
--- a/contrib/go/_std_1.20/src/syscall/endian_little.go
+++ b/contrib/go/_std_1.21/src/syscall/endian_little.go
diff --git a/contrib/go/_std_1.21/src/syscall/env_unix.go b/contrib/go/_std_1.21/src/syscall/env_unix.go
new file mode 100644
index 0000000000..8e87e018e8
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/env_unix.go
@@ -0,0 +1,150 @@
+// Copyright 2010 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.
+
+//go:build unix || (js && wasm) || plan9 || wasip1
+
+// Unix environment variables.
+
+package syscall
+
+import (
+ "runtime"
+ "sync"
+)
+
+var (
+ // envOnce guards initialization by copyenv, which populates env.
+ envOnce sync.Once
+
+ // envLock guards env and envs.
+ envLock sync.RWMutex
+
+ // env maps from an environment variable to its first occurrence in envs.
+ env map[string]int
+
+ // envs is provided by the runtime. elements are expected to
+ // be of the form "key=value". An empty string means deleted
+ // (or a duplicate to be ignored).
+ envs []string = runtime_envs()
+)
+
+func runtime_envs() []string // in package runtime
+
+func copyenv() {
+ env = make(map[string]int)
+ for i, s := range envs {
+ for j := 0; j < len(s); j++ {
+ if s[j] == '=' {
+ key := s[:j]
+ if _, ok := env[key]; !ok {
+ env[key] = i // first mention of key
+ } else {
+ // Clear duplicate keys. This permits Unsetenv to
+ // safely delete only the first item without
+ // worrying about unshadowing a later one,
+ // which might be a security problem.
+ envs[i] = ""
+ }
+ break
+ }
+ }
+ }
+}
+
+func Unsetenv(key string) error {
+ envOnce.Do(copyenv)
+
+ envLock.Lock()
+ defer envLock.Unlock()
+
+ if i, ok := env[key]; ok {
+ envs[i] = ""
+ delete(env, key)
+ }
+ runtimeUnsetenv(key)
+ return nil
+}
+
+func Getenv(key string) (value string, found bool) {
+ envOnce.Do(copyenv)
+ if len(key) == 0 {
+ return "", false
+ }
+
+ envLock.RLock()
+ defer envLock.RUnlock()
+
+ i, ok := env[key]
+ if !ok {
+ return "", false
+ }
+ s := envs[i]
+ for i := 0; i < len(s); i++ {
+ if s[i] == '=' {
+ return s[i+1:], true
+ }
+ }
+ return "", false
+}
+
+func Setenv(key, value string) error {
+ envOnce.Do(copyenv)
+ if len(key) == 0 {
+ return EINVAL
+ }
+ for i := 0; i < len(key); i++ {
+ if key[i] == '=' || key[i] == 0 {
+ return EINVAL
+ }
+ }
+ // On Plan 9, null is used as a separator, eg in $path.
+ if runtime.GOOS != "plan9" {
+ for i := 0; i < len(value); i++ {
+ if value[i] == 0 {
+ return EINVAL
+ }
+ }
+ }
+
+ envLock.Lock()
+ defer envLock.Unlock()
+
+ i, ok := env[key]
+ kv := key + "=" + value
+ if ok {
+ envs[i] = kv
+ } else {
+ i = len(envs)
+ envs = append(envs, kv)
+ }
+ env[key] = i
+ runtimeSetenv(key, value)
+ return nil
+}
+
+func Clearenv() {
+ envOnce.Do(copyenv) // prevent copyenv in Getenv/Setenv
+
+ envLock.Lock()
+ defer envLock.Unlock()
+
+ for k := range env {
+ runtimeUnsetenv(k)
+ }
+ env = make(map[string]int)
+ envs = []string{}
+}
+
+func Environ() []string {
+ envOnce.Do(copyenv)
+ envLock.RLock()
+ defer envLock.RUnlock()
+ a := make([]string, 0, len(envs))
+ for _, env := range envs {
+ if env != "" {
+ a = append(a, env)
+ }
+ }
+ return a
+}
diff --git a/contrib/go/_std_1.21/src/syscall/env_windows.go b/contrib/go/_std_1.21/src/syscall/env_windows.go
new file mode 100644
index 0000000000..220a005e1a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/env_windows.go
@@ -0,0 +1,96 @@
+// Copyright 2010 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.
+
+// Windows environment variables.
+
+package syscall
+
+import (
+ "unsafe"
+)
+
+func Getenv(key string) (value string, found bool) {
+ keyp, err := UTF16PtrFromString(key)
+ if err != nil {
+ return "", false
+ }
+ n := uint32(100)
+ for {
+ b := make([]uint16, n)
+ n, err = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
+ if n == 0 && err == ERROR_ENVVAR_NOT_FOUND {
+ return "", false
+ }
+ if n <= uint32(len(b)) {
+ return UTF16ToString(b[:n]), true
+ }
+ }
+}
+
+func Setenv(key, value string) error {
+ v, err := UTF16PtrFromString(value)
+ if err != nil {
+ return err
+ }
+ keyp, err := UTF16PtrFromString(key)
+ if err != nil {
+ return err
+ }
+ e := SetEnvironmentVariable(keyp, v)
+ if e != nil {
+ return e
+ }
+ runtimeSetenv(key, value)
+ return nil
+}
+
+func Unsetenv(key string) error {
+ keyp, err := UTF16PtrFromString(key)
+ if err != nil {
+ return err
+ }
+ e := SetEnvironmentVariable(keyp, nil)
+ if e != nil {
+ return e
+ }
+ runtimeUnsetenv(key)
+ return nil
+}
+
+func Clearenv() {
+ for _, s := range Environ() {
+ // Environment variables can begin with =
+ // so start looking for the separator = at j=1.
+ // https://devblogs.microsoft.com/oldnewthing/20100506-00/?p=14133
+ for j := 1; j < len(s); j++ {
+ if s[j] == '=' {
+ Unsetenv(s[0:j])
+ break
+ }
+ }
+ }
+}
+
+func Environ() []string {
+ envp, e := GetEnvironmentStrings()
+ if e != nil {
+ return nil
+ }
+ defer FreeEnvironmentStrings(envp)
+
+ r := make([]string, 0, 50) // Empty with room to grow.
+ const size = unsafe.Sizeof(*envp)
+ for *envp != 0 { // environment block ends with empty string
+ // find NUL terminator
+ end := unsafe.Pointer(envp)
+ for *(*uint16)(end) != 0 {
+ end = unsafe.Add(end, size)
+ }
+
+ entry := unsafe.Slice(envp, (uintptr(end)-uintptr(unsafe.Pointer(envp)))/size)
+ r = append(r, UTF16ToString(entry))
+ envp = (*uint16)(unsafe.Add(end, size))
+ }
+ return r
+}
diff --git a/contrib/go/_std_1.21/src/syscall/exec_libc2.go b/contrib/go/_std_1.21/src/syscall/exec_libc2.go
new file mode 100644
index 0000000000..4fca701d6b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/exec_libc2.go
@@ -0,0 +1,291 @@
+// Copyright 2011 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.
+
+//go:build darwin || (openbsd && !mips64)
+
+package syscall
+
+import (
+ "internal/abi"
+ "runtime"
+ "unsafe"
+)
+
+type SysProcAttr struct {
+ Chroot string // Chroot.
+ Credential *Credential // Credential.
+ Ptrace bool // Enable tracing.
+ Setsid bool // Create session.
+ // Setpgid sets the process group ID of the child to Pgid,
+ // or, if Pgid == 0, to the new child's process ID.
+ Setpgid bool
+ // Setctty sets the controlling terminal of the child to
+ // file descriptor Ctty. Ctty must be a descriptor number
+ // in the child process: an index into ProcAttr.Files.
+ // This is only meaningful if Setsid is true.
+ Setctty bool
+ Noctty bool // Detach fd 0 from controlling terminal
+ Ctty int // Controlling TTY fd
+ // Foreground places the child process group in the foreground.
+ // This implies Setpgid. The Ctty field must be set to
+ // the descriptor of the controlling TTY.
+ // Unlike Setctty, in this case Ctty must be a descriptor
+ // number in the parent process.
+ Foreground bool
+ Pgid int // Child's process group ID if Setpgid.
+}
+
+// Implemented in runtime package.
+func runtime_BeforeFork()
+func runtime_AfterFork()
+func runtime_AfterForkInChild()
+
+// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
+// If a dup or exec fails, write the errno error to pipe.
+// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
+// In the child, this function must not acquire any locks, because
+// they might have been locked at the time of the fork. This means
+// no rescheduling, no malloc calls, and no new stack segments.
+// For the same reason compiler does not race instrument it.
+// The calls to rawSyscall are okay because they are assembly
+// functions that do not grow the stack.
+//
+//go:norace
+func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err1 Errno) {
+ // Declare all variables at top in case any
+ // declarations require heap allocation (e.g., err1).
+ var (
+ r1 uintptr
+ nextfd int
+ i int
+ err error
+ pgrp _C_int
+ cred *Credential
+ ngroups, groups uintptr
+ )
+
+ rlim, rlimOK := origRlimitNofile.Load().(Rlimit)
+
+ // guard against side effects of shuffling fds below.
+ // Make sure that nextfd is beyond any currently open files so
+ // that we can't run the risk of overwriting any of them.
+ fd := make([]int, len(attr.Files))
+ nextfd = len(attr.Files)
+ for i, ufd := range attr.Files {
+ if nextfd < int(ufd) {
+ nextfd = int(ufd)
+ }
+ fd[i] = int(ufd)
+ }
+ nextfd++
+
+ // About to call fork.
+ // No more allocation or calls of non-assembly functions.
+ runtime_BeforeFork()
+ r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
+ if err1 != 0 {
+ runtime_AfterFork()
+ return 0, err1
+ }
+
+ if r1 != 0 {
+ // parent; return PID
+ runtime_AfterFork()
+ return int(r1), 0
+ }
+
+ // Fork succeeded, now in child.
+
+ // Enable tracing if requested.
+ if sys.Ptrace {
+ if err = ptrace(PTRACE_TRACEME, 0, 0, 0); err != nil {
+ err1 = err.(Errno)
+ goto childerror
+ }
+ }
+
+ // Session ID
+ if sys.Setsid {
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Set process group
+ if sys.Setpgid || sys.Foreground {
+ // Place child in process group.
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), 0, uintptr(sys.Pgid), 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ if sys.Foreground {
+ // This should really be pid_t, however _C_int (aka int32) is
+ // generally equivalent.
+ pgrp = _C_int(sys.Pgid)
+ if pgrp == 0 {
+ r1, _, err1 = rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ pgrp = _C_int(r1)
+ }
+
+ // Place process group in foreground.
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSPGRP), uintptr(unsafe.Pointer(&pgrp)))
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Restore the signal mask. We do this after TIOCSPGRP to avoid
+ // having the kernel send a SIGTTOU signal to the process group.
+ runtime_AfterForkInChild()
+
+ // Chroot
+ if chroot != nil {
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(chroot)), 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // User and groups
+ if cred = sys.Credential; cred != nil {
+ ngroups = uintptr(len(cred.Groups))
+ groups = uintptr(0)
+ if ngroups > 0 {
+ groups = uintptr(unsafe.Pointer(&cred.Groups[0]))
+ }
+ if !cred.NoSetGroups {
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), ngroups, groups, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(cred.Gid), 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(cred.Uid), 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Chdir
+ if dir != nil {
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(dir)), 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Pass 1: look for fd[i] < i and move those up above len(fd)
+ // so that pass 2 won't stomp on an fd it needs later.
+ if pipe < nextfd {
+ if runtime.GOOS == "openbsd" {
+ _, _, err1 = rawSyscall(dupTrampoline, uintptr(pipe), uintptr(nextfd), O_CLOEXEC)
+ } else {
+ _, _, err1 = rawSyscall(dupTrampoline, uintptr(pipe), uintptr(nextfd), 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+ }
+ if err1 != 0 {
+ goto childerror
+ }
+ pipe = nextfd
+ nextfd++
+ }
+ for i = 0; i < len(fd); i++ {
+ if fd[i] >= 0 && fd[i] < i {
+ if nextfd == pipe { // don't stomp on pipe
+ nextfd++
+ }
+ if runtime.GOOS == "openbsd" {
+ _, _, err1 = rawSyscall(dupTrampoline, uintptr(fd[i]), uintptr(nextfd), O_CLOEXEC)
+ } else {
+ _, _, err1 = rawSyscall(dupTrampoline, uintptr(fd[i]), uintptr(nextfd), 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+ }
+ if err1 != 0 {
+ goto childerror
+ }
+ fd[i] = nextfd
+ nextfd++
+ }
+ }
+
+ // Pass 2: dup fd[i] down onto i.
+ for i = 0; i < len(fd); i++ {
+ if fd[i] == -1 {
+ rawSyscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(i), 0, 0)
+ continue
+ }
+ if fd[i] == i {
+ // dup2(i, i) won't clear close-on-exec flag on Linux,
+ // probably not elsewhere either.
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd[i]), F_SETFD, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ continue
+ }
+ // The new fd is created NOT close-on-exec,
+ // which is exactly what we want.
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(fd[i]), uintptr(i), 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // By convention, we don't close-on-exec the fds we are
+ // started with, so if len(fd) < 3, close 0, 1, 2 as needed.
+ // Programs that know they inherit fds >= 3 will need
+ // to set them close-on-exec.
+ for i = len(fd); i < 3; i++ {
+ rawSyscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(i), 0, 0)
+ }
+
+ // Detach fd 0 from tty
+ if sys.Noctty {
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), 0, uintptr(TIOCNOTTY), 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Set the controlling TTY to Ctty
+ if sys.Setctty {
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Restore original rlimit.
+ if rlimOK && rlim.Cur != 0 {
+ rawSyscall(abi.FuncPCABI0(libc_setrlimit_trampoline), uintptr(RLIMIT_NOFILE), uintptr(unsafe.Pointer(&rlim)), 0)
+ }
+
+ // Time to exec.
+ _, _, err1 = rawSyscall(abi.FuncPCABI0(libc_execve_trampoline),
+ uintptr(unsafe.Pointer(argv0)),
+ uintptr(unsafe.Pointer(&argv[0])),
+ uintptr(unsafe.Pointer(&envv[0])))
+
+childerror:
+ // send error code on pipe
+ rawSyscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
+ for {
+ rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), 253, 0, 0)
+ }
+}
diff --git a/contrib/go/_std_1.21/src/syscall/exec_linux.go b/contrib/go/_std_1.21/src/syscall/exec_linux.go
new file mode 100644
index 0000000000..dfbb38ac16
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/exec_linux.go
@@ -0,0 +1,719 @@
+// Copyright 2011 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.
+
+//go:build linux
+
+package syscall
+
+import (
+ "internal/itoa"
+ "runtime"
+ "unsafe"
+)
+
+// Linux unshare/clone/clone2/clone3 flags, architecture-independent,
+// copied from linux/sched.h.
+const (
+ CLONE_VM = 0x00000100 // set if VM shared between processes
+ CLONE_FS = 0x00000200 // set if fs info shared between processes
+ CLONE_FILES = 0x00000400 // set if open files shared between processes
+ CLONE_SIGHAND = 0x00000800 // set if signal handlers and blocked signals shared
+ CLONE_PIDFD = 0x00001000 // set if a pidfd should be placed in parent
+ CLONE_PTRACE = 0x00002000 // set if we want to let tracing continue on the child too
+ CLONE_VFORK = 0x00004000 // set if the parent wants the child to wake it up on mm_release
+ CLONE_PARENT = 0x00008000 // set if we want to have the same parent as the cloner
+ CLONE_THREAD = 0x00010000 // Same thread group?
+ CLONE_NEWNS = 0x00020000 // New mount namespace group
+ CLONE_SYSVSEM = 0x00040000 // share system V SEM_UNDO semantics
+ CLONE_SETTLS = 0x00080000 // create a new TLS for the child
+ CLONE_PARENT_SETTID = 0x00100000 // set the TID in the parent
+ CLONE_CHILD_CLEARTID = 0x00200000 // clear the TID in the child
+ CLONE_DETACHED = 0x00400000 // Unused, ignored
+ CLONE_UNTRACED = 0x00800000 // set if the tracing process can't force CLONE_PTRACE on this clone
+ CLONE_CHILD_SETTID = 0x01000000 // set the TID in the child
+ CLONE_NEWCGROUP = 0x02000000 // New cgroup namespace
+ CLONE_NEWUTS = 0x04000000 // New utsname namespace
+ CLONE_NEWIPC = 0x08000000 // New ipc namespace
+ CLONE_NEWUSER = 0x10000000 // New user namespace
+ CLONE_NEWPID = 0x20000000 // New pid namespace
+ CLONE_NEWNET = 0x40000000 // New network namespace
+ CLONE_IO = 0x80000000 // Clone io context
+
+ // Flags for the clone3() syscall.
+
+ CLONE_CLEAR_SIGHAND = 0x100000000 // Clear any signal handler and reset to SIG_DFL.
+ CLONE_INTO_CGROUP = 0x200000000 // Clone into a specific cgroup given the right permissions.
+
+ // Cloning flags intersect with CSIGNAL so can be used with unshare and clone3
+ // syscalls only:
+
+ CLONE_NEWTIME = 0x00000080 // New time namespace
+)
+
+// SysProcIDMap holds Container ID to Host ID mappings used for User Namespaces in Linux.
+// See user_namespaces(7).
+type SysProcIDMap struct {
+ ContainerID int // Container ID.
+ HostID int // Host ID.
+ Size int // Size.
+}
+
+type SysProcAttr struct {
+ Chroot string // Chroot.
+ Credential *Credential // Credential.
+ // Ptrace tells the child to call ptrace(PTRACE_TRACEME).
+ // Call runtime.LockOSThread before starting a process with this set,
+ // and don't call UnlockOSThread until done with PtraceSyscall calls.
+ Ptrace bool
+ Setsid bool // Create session.
+ // Setpgid sets the process group ID of the child to Pgid,
+ // or, if Pgid == 0, to the new child's process ID.
+ Setpgid bool
+ // Setctty sets the controlling terminal of the child to
+ // file descriptor Ctty. Ctty must be a descriptor number
+ // in the child process: an index into ProcAttr.Files.
+ // This is only meaningful if Setsid is true.
+ Setctty bool
+ Noctty bool // Detach fd 0 from controlling terminal
+ Ctty int // Controlling TTY fd
+ // Foreground places the child process group in the foreground.
+ // This implies Setpgid. The Ctty field must be set to
+ // the descriptor of the controlling TTY.
+ // Unlike Setctty, in this case Ctty must be a descriptor
+ // number in the parent process.
+ Foreground bool
+ Pgid int // Child's process group ID if Setpgid.
+ // Pdeathsig, if non-zero, is a signal that the kernel will send to
+ // the child process when the creating thread dies. Note that the signal
+ // is sent on thread termination, which may happen before process termination.
+ // There are more details at https://go.dev/issue/27505.
+ Pdeathsig Signal
+ Cloneflags uintptr // Flags for clone calls (Linux only)
+ Unshareflags uintptr // Flags for unshare calls (Linux only)
+ UidMappings []SysProcIDMap // User ID mappings for user namespaces.
+ GidMappings []SysProcIDMap // Group ID mappings for user namespaces.
+ // GidMappingsEnableSetgroups enabling setgroups syscall.
+ // If false, then setgroups syscall will be disabled for the child process.
+ // This parameter is no-op if GidMappings == nil. Otherwise for unprivileged
+ // users this should be set to false for mappings work.
+ GidMappingsEnableSetgroups bool
+ AmbientCaps []uintptr // Ambient capabilities (Linux only)
+ UseCgroupFD bool // Whether to make use of the CgroupFD field.
+ CgroupFD int // File descriptor of a cgroup to put the new process into.
+}
+
+var (
+ none = [...]byte{'n', 'o', 'n', 'e', 0}
+ slash = [...]byte{'/', 0}
+)
+
+// Implemented in runtime package.
+func runtime_BeforeFork()
+func runtime_AfterFork()
+func runtime_AfterForkInChild()
+
+// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
+// If a dup or exec fails, write the errno error to pipe.
+// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
+// In the child, this function must not acquire any locks, because
+// they might have been locked at the time of the fork. This means
+// no rescheduling, no malloc calls, and no new stack segments.
+// For the same reason compiler does not race instrument it.
+// The calls to RawSyscall are okay because they are assembly
+// functions that do not grow the stack.
+//
+//go:norace
+func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
+ // Set up and fork. This returns immediately in the parent or
+ // if there's an error.
+ upid, err, mapPipe, locked := forkAndExecInChild1(argv0, argv, envv, chroot, dir, attr, sys, pipe)
+ if locked {
+ runtime_AfterFork()
+ }
+ if err != 0 {
+ return 0, err
+ }
+
+ // parent; return PID
+ pid = int(upid)
+
+ if sys.UidMappings != nil || sys.GidMappings != nil {
+ Close(mapPipe[0])
+ var err2 Errno
+ // uid/gid mappings will be written after fork and unshare(2) for user
+ // namespaces.
+ if sys.Unshareflags&CLONE_NEWUSER == 0 {
+ if err := writeUidGidMappings(pid, sys); err != nil {
+ err2 = err.(Errno)
+ }
+ }
+ RawSyscall(SYS_WRITE, uintptr(mapPipe[1]), uintptr(unsafe.Pointer(&err2)), unsafe.Sizeof(err2))
+ Close(mapPipe[1])
+ }
+
+ return pid, 0
+}
+
+const _LINUX_CAPABILITY_VERSION_3 = 0x20080522
+
+type capHeader struct {
+ version uint32
+ pid int32
+}
+
+type capData struct {
+ effective uint32
+ permitted uint32
+ inheritable uint32
+}
+type caps struct {
+ hdr capHeader
+ data [2]capData
+}
+
+// See CAP_TO_INDEX in linux/capability.h:
+func capToIndex(cap uintptr) uintptr { return cap >> 5 }
+
+// See CAP_TO_MASK in linux/capability.h:
+func capToMask(cap uintptr) uint32 { return 1 << uint(cap&31) }
+
+// cloneArgs holds arguments for clone3 Linux syscall.
+type cloneArgs struct {
+ flags uint64 // Flags bit mask
+ pidFD uint64 // Where to store PID file descriptor (int *)
+ childTID uint64 // Where to store child TID, in child's memory (pid_t *)
+ parentTID uint64 // Where to store child TID, in parent's memory (pid_t *)
+ exitSignal uint64 // Signal to deliver to parent on child termination
+ stack uint64 // Pointer to lowest byte of stack
+ stackSize uint64 // Size of stack
+ tls uint64 // Location of new TLS
+ setTID uint64 // Pointer to a pid_t array (since Linux 5.5)
+ setTIDSize uint64 // Number of elements in set_tid (since Linux 5.5)
+ cgroup uint64 // File descriptor for target cgroup of child (since Linux 5.7)
+}
+
+// forkAndExecInChild1 implements the body of forkAndExecInChild up to
+// the parent's post-fork path. This is a separate function so we can
+// separate the child's and parent's stack frames if we're using
+// vfork.
+//
+// This is go:noinline because the point is to keep the stack frames
+// of this and forkAndExecInChild separate.
+//
+//go:noinline
+//go:norace
+//go:nocheckptr
+func forkAndExecInChild1(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid uintptr, err1 Errno, mapPipe [2]int, locked bool) {
+ // Defined in linux/prctl.h starting with Linux 4.3.
+ const (
+ PR_CAP_AMBIENT = 0x2f
+ PR_CAP_AMBIENT_RAISE = 0x2
+ )
+
+ // vfork requires that the child not touch any of the parent's
+ // active stack frames. Hence, the child does all post-fork
+ // processing in this stack frame and never returns, while the
+ // parent returns immediately from this frame and does all
+ // post-fork processing in the outer frame.
+ //
+ // Declare all variables at top in case any
+ // declarations require heap allocation (e.g., err2).
+ // ":=" should not be used to declare any variable after
+ // the call to runtime_BeforeFork.
+ //
+ // NOTE(bcmills): The allocation behavior described in the above comment
+ // seems to lack a corresponding test, and it may be rendered invalid
+ // by an otherwise-correct change in the compiler.
+ var (
+ err2 Errno
+ nextfd int
+ i int
+ caps caps
+ fd1, flags uintptr
+ puid, psetgroups, pgid []byte
+ uidmap, setgroups, gidmap []byte
+ clone3 *cloneArgs
+ pgrp int32
+ dirfd int
+ cred *Credential
+ ngroups, groups uintptr
+ c uintptr
+ )
+
+ rlim, rlimOK := origRlimitNofile.Load().(Rlimit)
+
+ if sys.UidMappings != nil {
+ puid = []byte("/proc/self/uid_map\000")
+ uidmap = formatIDMappings(sys.UidMappings)
+ }
+
+ if sys.GidMappings != nil {
+ psetgroups = []byte("/proc/self/setgroups\000")
+ pgid = []byte("/proc/self/gid_map\000")
+
+ if sys.GidMappingsEnableSetgroups {
+ setgroups = []byte("allow\000")
+ } else {
+ setgroups = []byte("deny\000")
+ }
+ gidmap = formatIDMappings(sys.GidMappings)
+ }
+
+ // Record parent PID so child can test if it has died.
+ ppid, _ := rawSyscallNoError(SYS_GETPID, 0, 0, 0)
+
+ // Guard against side effects of shuffling fds below.
+ // Make sure that nextfd is beyond any currently open files so
+ // that we can't run the risk of overwriting any of them.
+ fd := make([]int, len(attr.Files))
+ nextfd = len(attr.Files)
+ for i, ufd := range attr.Files {
+ if nextfd < int(ufd) {
+ nextfd = int(ufd)
+ }
+ fd[i] = int(ufd)
+ }
+ nextfd++
+
+ // Allocate another pipe for parent to child communication for
+ // synchronizing writing of User ID/Group ID mappings.
+ if sys.UidMappings != nil || sys.GidMappings != nil {
+ if err := forkExecPipe(mapPipe[:]); err != nil {
+ err1 = err.(Errno)
+ return
+ }
+ }
+
+ flags = sys.Cloneflags
+ if sys.Cloneflags&CLONE_NEWUSER == 0 && sys.Unshareflags&CLONE_NEWUSER == 0 {
+ flags |= CLONE_VFORK | CLONE_VM
+ }
+ // Whether to use clone3.
+ if sys.UseCgroupFD {
+ clone3 = &cloneArgs{
+ flags: uint64(flags) | CLONE_INTO_CGROUP,
+ exitSignal: uint64(SIGCHLD),
+ cgroup: uint64(sys.CgroupFD),
+ }
+ } else if flags&CLONE_NEWTIME != 0 {
+ clone3 = &cloneArgs{
+ flags: uint64(flags),
+ exitSignal: uint64(SIGCHLD),
+ }
+ }
+
+ // About to call fork.
+ // No more allocation or calls of non-assembly functions.
+ runtime_BeforeFork()
+ locked = true
+ if clone3 != nil {
+ pid, err1 = rawVforkSyscall(_SYS_clone3, uintptr(unsafe.Pointer(clone3)), unsafe.Sizeof(*clone3))
+ } else {
+ flags |= uintptr(SIGCHLD)
+ if runtime.GOARCH == "s390x" {
+ // On Linux/s390, the first two arguments of clone(2) are swapped.
+ pid, err1 = rawVforkSyscall(SYS_CLONE, 0, flags)
+ } else {
+ pid, err1 = rawVforkSyscall(SYS_CLONE, flags, 0)
+ }
+ }
+ if err1 != 0 || pid != 0 {
+ // If we're in the parent, we must return immediately
+ // so we're not in the same stack frame as the child.
+ // This can at most use the return PC, which the child
+ // will not modify, and the results of
+ // rawVforkSyscall, which must have been written after
+ // the child was replaced.
+ return
+ }
+
+ // Fork succeeded, now in child.
+
+ // Enable the "keep capabilities" flag to set ambient capabilities later.
+ if len(sys.AmbientCaps) > 0 {
+ _, _, err1 = RawSyscall6(SYS_PRCTL, PR_SET_KEEPCAPS, 1, 0, 0, 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Wait for User ID/Group ID mappings to be written.
+ if sys.UidMappings != nil || sys.GidMappings != nil {
+ if _, _, err1 = RawSyscall(SYS_CLOSE, uintptr(mapPipe[1]), 0, 0); err1 != 0 {
+ goto childerror
+ }
+ pid, _, err1 = RawSyscall(SYS_READ, uintptr(mapPipe[0]), uintptr(unsafe.Pointer(&err2)), unsafe.Sizeof(err2))
+ if err1 != 0 {
+ goto childerror
+ }
+ if pid != unsafe.Sizeof(err2) {
+ err1 = EINVAL
+ goto childerror
+ }
+ if err2 != 0 {
+ err1 = err2
+ goto childerror
+ }
+ }
+
+ // Session ID
+ if sys.Setsid {
+ _, _, err1 = RawSyscall(SYS_SETSID, 0, 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Set process group
+ if sys.Setpgid || sys.Foreground {
+ // Place child in process group.
+ _, _, err1 = RawSyscall(SYS_SETPGID, 0, uintptr(sys.Pgid), 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ if sys.Foreground {
+ pgrp = int32(sys.Pgid)
+ if pgrp == 0 {
+ pid, _ = rawSyscallNoError(SYS_GETPID, 0, 0, 0)
+
+ pgrp = int32(pid)
+ }
+
+ // Place process group in foreground.
+ _, _, err1 = RawSyscall(SYS_IOCTL, uintptr(sys.Ctty), uintptr(TIOCSPGRP), uintptr(unsafe.Pointer(&pgrp)))
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Restore the signal mask. We do this after TIOCSPGRP to avoid
+ // having the kernel send a SIGTTOU signal to the process group.
+ runtime_AfterForkInChild()
+
+ // Unshare
+ if sys.Unshareflags != 0 {
+ _, _, err1 = RawSyscall(SYS_UNSHARE, sys.Unshareflags, 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+
+ if sys.Unshareflags&CLONE_NEWUSER != 0 && sys.GidMappings != nil {
+ dirfd = int(_AT_FDCWD)
+ if fd1, _, err1 = RawSyscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(&psetgroups[0])), uintptr(O_WRONLY), 0, 0, 0); err1 != 0 {
+ goto childerror
+ }
+ pid, _, err1 = RawSyscall(SYS_WRITE, uintptr(fd1), uintptr(unsafe.Pointer(&setgroups[0])), uintptr(len(setgroups)))
+ if err1 != 0 {
+ goto childerror
+ }
+ if _, _, err1 = RawSyscall(SYS_CLOSE, uintptr(fd1), 0, 0); err1 != 0 {
+ goto childerror
+ }
+
+ if fd1, _, err1 = RawSyscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(&pgid[0])), uintptr(O_WRONLY), 0, 0, 0); err1 != 0 {
+ goto childerror
+ }
+ pid, _, err1 = RawSyscall(SYS_WRITE, uintptr(fd1), uintptr(unsafe.Pointer(&gidmap[0])), uintptr(len(gidmap)))
+ if err1 != 0 {
+ goto childerror
+ }
+ if _, _, err1 = RawSyscall(SYS_CLOSE, uintptr(fd1), 0, 0); err1 != 0 {
+ goto childerror
+ }
+ }
+
+ if sys.Unshareflags&CLONE_NEWUSER != 0 && sys.UidMappings != nil {
+ dirfd = int(_AT_FDCWD)
+ if fd1, _, err1 = RawSyscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(&puid[0])), uintptr(O_WRONLY), 0, 0, 0); err1 != 0 {
+ goto childerror
+ }
+ pid, _, err1 = RawSyscall(SYS_WRITE, uintptr(fd1), uintptr(unsafe.Pointer(&uidmap[0])), uintptr(len(uidmap)))
+ if err1 != 0 {
+ goto childerror
+ }
+ if _, _, err1 = RawSyscall(SYS_CLOSE, uintptr(fd1), 0, 0); err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // The unshare system call in Linux doesn't unshare mount points
+ // mounted with --shared. Systemd mounts / with --shared. For a
+ // long discussion of the pros and cons of this see debian bug 739593.
+ // The Go model of unsharing is more like Plan 9, where you ask
+ // to unshare and the namespaces are unconditionally unshared.
+ // To make this model work we must further mark / as MS_PRIVATE.
+ // This is what the standard unshare command does.
+ if sys.Unshareflags&CLONE_NEWNS == CLONE_NEWNS {
+ _, _, err1 = RawSyscall6(SYS_MOUNT, uintptr(unsafe.Pointer(&none[0])), uintptr(unsafe.Pointer(&slash[0])), 0, MS_REC|MS_PRIVATE, 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+ }
+
+ // Chroot
+ if chroot != nil {
+ _, _, err1 = RawSyscall(SYS_CHROOT, uintptr(unsafe.Pointer(chroot)), 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // User and groups
+ if cred = sys.Credential; cred != nil {
+ ngroups = uintptr(len(cred.Groups))
+ groups = uintptr(0)
+ if ngroups > 0 {
+ groups = uintptr(unsafe.Pointer(&cred.Groups[0]))
+ }
+ if !(sys.GidMappings != nil && !sys.GidMappingsEnableSetgroups && ngroups == 0) && !cred.NoSetGroups {
+ _, _, err1 = RawSyscall(_SYS_setgroups, ngroups, groups, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+ _, _, err1 = RawSyscall(sys_SETGID, uintptr(cred.Gid), 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ _, _, err1 = RawSyscall(sys_SETUID, uintptr(cred.Uid), 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ if len(sys.AmbientCaps) != 0 {
+ // Ambient capabilities were added in the 4.3 kernel,
+ // so it is safe to always use _LINUX_CAPABILITY_VERSION_3.
+ caps.hdr.version = _LINUX_CAPABILITY_VERSION_3
+
+ if _, _, err1 = RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&caps.hdr)), uintptr(unsafe.Pointer(&caps.data[0])), 0); err1 != 0 {
+ goto childerror
+ }
+
+ for _, c = range sys.AmbientCaps {
+ // Add the c capability to the permitted and inheritable capability mask,
+ // otherwise we will not be able to add it to the ambient capability mask.
+ caps.data[capToIndex(c)].permitted |= capToMask(c)
+ caps.data[capToIndex(c)].inheritable |= capToMask(c)
+ }
+
+ if _, _, err1 = RawSyscall(SYS_CAPSET, uintptr(unsafe.Pointer(&caps.hdr)), uintptr(unsafe.Pointer(&caps.data[0])), 0); err1 != 0 {
+ goto childerror
+ }
+
+ for _, c = range sys.AmbientCaps {
+ _, _, err1 = RawSyscall6(SYS_PRCTL, PR_CAP_AMBIENT, uintptr(PR_CAP_AMBIENT_RAISE), c, 0, 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+ }
+
+ // Chdir
+ if dir != nil {
+ _, _, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)), 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Parent death signal
+ if sys.Pdeathsig != 0 {
+ _, _, err1 = RawSyscall6(SYS_PRCTL, PR_SET_PDEATHSIG, uintptr(sys.Pdeathsig), 0, 0, 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+
+ // Signal self if parent is already dead. This might cause a
+ // duplicate signal in rare cases, but it won't matter when
+ // using SIGKILL.
+ pid, _ = rawSyscallNoError(SYS_GETPPID, 0, 0, 0)
+ if pid != ppid {
+ pid, _ = rawSyscallNoError(SYS_GETPID, 0, 0, 0)
+ _, _, err1 = RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+ }
+
+ // Pass 1: look for fd[i] < i and move those up above len(fd)
+ // so that pass 2 won't stomp on an fd it needs later.
+ if pipe < nextfd {
+ _, _, err1 = RawSyscall(SYS_DUP3, uintptr(pipe), uintptr(nextfd), O_CLOEXEC)
+ if err1 != 0 {
+ goto childerror
+ }
+ pipe = nextfd
+ nextfd++
+ }
+ for i = 0; i < len(fd); i++ {
+ if fd[i] >= 0 && fd[i] < i {
+ if nextfd == pipe { // don't stomp on pipe
+ nextfd++
+ }
+ _, _, err1 = RawSyscall(SYS_DUP3, uintptr(fd[i]), uintptr(nextfd), O_CLOEXEC)
+ if err1 != 0 {
+ goto childerror
+ }
+ fd[i] = nextfd
+ nextfd++
+ }
+ }
+
+ // Pass 2: dup fd[i] down onto i.
+ for i = 0; i < len(fd); i++ {
+ if fd[i] == -1 {
+ RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
+ continue
+ }
+ if fd[i] == i {
+ // dup2(i, i) won't clear close-on-exec flag on Linux,
+ // probably not elsewhere either.
+ _, _, err1 = RawSyscall(fcntl64Syscall, uintptr(fd[i]), F_SETFD, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ continue
+ }
+ // The new fd is created NOT close-on-exec,
+ // which is exactly what we want.
+ _, _, err1 = RawSyscall(SYS_DUP3, uintptr(fd[i]), uintptr(i), 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // By convention, we don't close-on-exec the fds we are
+ // started with, so if len(fd) < 3, close 0, 1, 2 as needed.
+ // Programs that know they inherit fds >= 3 will need
+ // to set them close-on-exec.
+ for i = len(fd); i < 3; i++ {
+ RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
+ }
+
+ // Detach fd 0 from tty
+ if sys.Noctty {
+ _, _, err1 = RawSyscall(SYS_IOCTL, 0, uintptr(TIOCNOTTY), 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Set the controlling TTY to Ctty
+ if sys.Setctty {
+ _, _, err1 = RawSyscall(SYS_IOCTL, uintptr(sys.Ctty), uintptr(TIOCSCTTY), 1)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Restore original rlimit.
+ if rlimOK && rlim.Cur != 0 {
+ rawSetrlimit(RLIMIT_NOFILE, &rlim)
+ }
+
+ // Enable tracing if requested.
+ // Do this right before exec so that we don't unnecessarily trace the runtime
+ // setting up after the fork. See issue #21428.
+ if sys.Ptrace {
+ _, _, err1 = RawSyscall(SYS_PTRACE, uintptr(PTRACE_TRACEME), 0, 0)
+ if err1 != 0 {
+ goto childerror
+ }
+ }
+
+ // Time to exec.
+ _, _, err1 = RawSyscall(SYS_EXECVE,
+ uintptr(unsafe.Pointer(argv0)),
+ uintptr(unsafe.Pointer(&argv[0])),
+ uintptr(unsafe.Pointer(&envv[0])))
+
+childerror:
+ // send error code on pipe
+ RawSyscall(SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
+ for {
+ RawSyscall(SYS_EXIT, 253, 0, 0)
+ }
+}
+
+func formatIDMappings(idMap []SysProcIDMap) []byte {
+ var data []byte
+ for _, im := range idMap {
+ data = append(data, itoa.Itoa(im.ContainerID)+" "+itoa.Itoa(im.HostID)+" "+itoa.Itoa(im.Size)+"\n"...)
+ }
+ return data
+}
+
+// writeIDMappings writes the user namespace User ID or Group ID mappings to the specified path.
+func writeIDMappings(path string, idMap []SysProcIDMap) error {
+ fd, err := Open(path, O_RDWR, 0)
+ if err != nil {
+ return err
+ }
+
+ if _, err := Write(fd, formatIDMappings(idMap)); err != nil {
+ Close(fd)
+ return err
+ }
+
+ if err := Close(fd); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// writeSetgroups writes to /proc/PID/setgroups "deny" if enable is false
+// and "allow" if enable is true.
+// This is needed since kernel 3.19, because you can't write gid_map without
+// disabling setgroups() system call.
+func writeSetgroups(pid int, enable bool) error {
+ sgf := "/proc/" + itoa.Itoa(pid) + "/setgroups"
+ fd, err := Open(sgf, O_RDWR, 0)
+ if err != nil {
+ return err
+ }
+
+ var data []byte
+ if enable {
+ data = []byte("allow")
+ } else {
+ data = []byte("deny")
+ }
+
+ if _, err := Write(fd, data); err != nil {
+ Close(fd)
+ return err
+ }
+
+ return Close(fd)
+}
+
+// writeUidGidMappings writes User ID and Group ID mappings for user namespaces
+// for a process and it is called from the parent process.
+func writeUidGidMappings(pid int, sys *SysProcAttr) error {
+ if sys.UidMappings != nil {
+ uidf := "/proc/" + itoa.Itoa(pid) + "/uid_map"
+ if err := writeIDMappings(uidf, sys.UidMappings); err != nil {
+ return err
+ }
+ }
+
+ if sys.GidMappings != nil {
+ // If the kernel is too old to support /proc/PID/setgroups, writeSetGroups will return ENOENT; this is OK.
+ if err := writeSetgroups(pid, sys.GidMappingsEnableSetgroups); err != nil && err != ENOENT {
+ return err
+ }
+ gidf := "/proc/" + itoa.Itoa(pid) + "/gid_map"
+ if err := writeIDMappings(gidf, sys.GidMappings); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/syscall/exec_unix.go b/contrib/go/_std_1.21/src/syscall/exec_unix.go
new file mode 100644
index 0000000000..9a5f2d3295
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/exec_unix.go
@@ -0,0 +1,307 @@
+// Copyright 2009 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.
+
+//go:build unix
+
+// Fork, exec, wait, etc.
+
+package syscall
+
+import (
+ errorspkg "errors"
+ "internal/bytealg"
+ "runtime"
+ "sync"
+ "unsafe"
+)
+
+// ForkLock is used to synchronize creation of new file descriptors
+// with fork.
+//
+// We want the child in a fork/exec sequence to inherit only the
+// file descriptors we intend. To do that, we mark all file
+// descriptors close-on-exec and then, in the child, explicitly
+// unmark the ones we want the exec'ed program to keep.
+// Unix doesn't make this easy: there is, in general, no way to
+// allocate a new file descriptor close-on-exec. Instead you
+// have to allocate the descriptor and then mark it close-on-exec.
+// If a fork happens between those two events, the child's exec
+// will inherit an unwanted file descriptor.
+//
+// This lock solves that race: the create new fd/mark close-on-exec
+// operation is done holding ForkLock for reading, and the fork itself
+// is done holding ForkLock for writing. At least, that's the idea.
+// There are some complications.
+//
+// Some system calls that create new file descriptors can block
+// for arbitrarily long times: open on a hung NFS server or named
+// pipe, accept on a socket, and so on. We can't reasonably grab
+// the lock across those operations.
+//
+// It is worse to inherit some file descriptors than others.
+// If a non-malicious child accidentally inherits an open ordinary file,
+// that's not a big deal. On the other hand, if a long-lived child
+// accidentally inherits the write end of a pipe, then the reader
+// of that pipe will not see EOF until that child exits, potentially
+// causing the parent program to hang. This is a common problem
+// in threaded C programs that use popen.
+//
+// Luckily, the file descriptors that are most important not to
+// inherit are not the ones that can take an arbitrarily long time
+// to create: pipe returns instantly, and the net package uses
+// non-blocking I/O to accept on a listening socket.
+// The rules for which file descriptor-creating operations use the
+// ForkLock are as follows:
+//
+// - Pipe. Use pipe2 if available. Otherwise, does not block,
+// so use ForkLock.
+// - Socket. Use SOCK_CLOEXEC if available. Otherwise, does not
+// block, so use ForkLock.
+// - Open. Use O_CLOEXEC if available. Otherwise, may block,
+// so live with the race.
+// - Dup. Use F_DUPFD_CLOEXEC or dup3 if available. Otherwise,
+// does not block, so use ForkLock.
+var ForkLock sync.RWMutex
+
+// StringSlicePtr converts a slice of strings to a slice of pointers
+// to NUL-terminated byte arrays. If any string contains a NUL byte
+// this function panics instead of returning an error.
+//
+// Deprecated: Use SlicePtrFromStrings instead.
+func StringSlicePtr(ss []string) []*byte {
+ bb := make([]*byte, len(ss)+1)
+ for i := 0; i < len(ss); i++ {
+ bb[i] = StringBytePtr(ss[i])
+ }
+ bb[len(ss)] = nil
+ return bb
+}
+
+// SlicePtrFromStrings converts a slice of strings to a slice of
+// pointers to NUL-terminated byte arrays. If any string contains
+// a NUL byte, it returns (nil, EINVAL).
+func SlicePtrFromStrings(ss []string) ([]*byte, error) {
+ n := 0
+ for _, s := range ss {
+ if bytealg.IndexByteString(s, 0) != -1 {
+ return nil, EINVAL
+ }
+ n += len(s) + 1 // +1 for NUL
+ }
+ bb := make([]*byte, len(ss)+1)
+ b := make([]byte, n)
+ n = 0
+ for i, s := range ss {
+ bb[i] = &b[n]
+ copy(b[n:], s)
+ n += len(s) + 1
+ }
+ return bb, nil
+}
+
+func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
+
+func SetNonblock(fd int, nonblocking bool) (err error) {
+ flag, err := fcntl(fd, F_GETFL, 0)
+ if err != nil {
+ return err
+ }
+ if nonblocking {
+ flag |= O_NONBLOCK
+ } else {
+ flag &^= O_NONBLOCK
+ }
+ _, err = fcntl(fd, F_SETFL, flag)
+ return err
+}
+
+// Credential holds user and group identities to be assumed
+// by a child process started by StartProcess.
+type Credential struct {
+ Uid uint32 // User ID.
+ Gid uint32 // Group ID.
+ Groups []uint32 // Supplementary group IDs.
+ NoSetGroups bool // If true, don't set supplementary groups
+}
+
+// ProcAttr holds attributes that will be applied to a new process started
+// by StartProcess.
+type ProcAttr struct {
+ Dir string // Current working directory.
+ Env []string // Environment.
+ Files []uintptr // File descriptors.
+ Sys *SysProcAttr
+}
+
+var zeroProcAttr ProcAttr
+var zeroSysProcAttr SysProcAttr
+
+func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
+ var p [2]int
+ var n int
+ var err1 Errno
+ var wstatus WaitStatus
+
+ if attr == nil {
+ attr = &zeroProcAttr
+ }
+ sys := attr.Sys
+ if sys == nil {
+ sys = &zeroSysProcAttr
+ }
+
+ // Convert args to C form.
+ argv0p, err := BytePtrFromString(argv0)
+ if err != nil {
+ return 0, err
+ }
+ argvp, err := SlicePtrFromStrings(argv)
+ if err != nil {
+ return 0, err
+ }
+ envvp, err := SlicePtrFromStrings(attr.Env)
+ if err != nil {
+ return 0, err
+ }
+
+ if (runtime.GOOS == "freebsd" || runtime.GOOS == "dragonfly") && len(argv) > 0 && len(argv[0]) > len(argv0) {
+ argvp[0] = argv0p
+ }
+
+ var chroot *byte
+ if sys.Chroot != "" {
+ chroot, err = BytePtrFromString(sys.Chroot)
+ if err != nil {
+ return 0, err
+ }
+ }
+ var dir *byte
+ if attr.Dir != "" {
+ dir, err = BytePtrFromString(attr.Dir)
+ if err != nil {
+ return 0, err
+ }
+ }
+
+ // Both Setctty and Foreground use the Ctty field,
+ // but they give it slightly different meanings.
+ if sys.Setctty && sys.Foreground {
+ return 0, errorspkg.New("both Setctty and Foreground set in SysProcAttr")
+ }
+ if sys.Setctty && sys.Ctty >= len(attr.Files) {
+ return 0, errorspkg.New("Setctty set but Ctty not valid in child")
+ }
+
+ acquireForkLock()
+
+ // Allocate child status pipe close on exec.
+ if err = forkExecPipe(p[:]); err != nil {
+ releaseForkLock()
+ return 0, err
+ }
+
+ // Kick off child.
+ pid, err1 = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1])
+ if err1 != 0 {
+ Close(p[0])
+ Close(p[1])
+ releaseForkLock()
+ return 0, Errno(err1)
+ }
+ releaseForkLock()
+
+ // Read child error status from pipe.
+ Close(p[1])
+ for {
+ n, err = readlen(p[0], (*byte)(unsafe.Pointer(&err1)), int(unsafe.Sizeof(err1)))
+ if err != EINTR {
+ break
+ }
+ }
+ Close(p[0])
+ if err != nil || n != 0 {
+ if n == int(unsafe.Sizeof(err1)) {
+ err = Errno(err1)
+ }
+ if err == nil {
+ err = EPIPE
+ }
+
+ // Child failed; wait for it to exit, to make sure
+ // the zombies don't accumulate.
+ _, err1 := Wait4(pid, &wstatus, 0, nil)
+ for err1 == EINTR {
+ _, err1 = Wait4(pid, &wstatus, 0, nil)
+ }
+ return 0, err
+ }
+
+ // Read got EOF, so pipe closed on exec, so exec succeeded.
+ return pid, nil
+}
+
+// Combination of fork and exec, careful to be thread safe.
+func ForkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) {
+ return forkExec(argv0, argv, attr)
+}
+
+// StartProcess wraps ForkExec for package os.
+func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
+ pid, err = forkExec(argv0, argv, attr)
+ return pid, 0, err
+}
+
+// Implemented in runtime package.
+func runtime_BeforeExec()
+func runtime_AfterExec()
+
+// execveLibc is non-nil on OS using libc syscall, set to execve in exec_libc.go; this
+// avoids a build dependency for other platforms.
+var execveLibc func(path uintptr, argv uintptr, envp uintptr) Errno
+var execveDarwin func(path *byte, argv **byte, envp **byte) error
+var execveOpenBSD func(path *byte, argv **byte, envp **byte) error
+
+// Exec invokes the execve(2) system call.
+func Exec(argv0 string, argv []string, envv []string) (err error) {
+ argv0p, err := BytePtrFromString(argv0)
+ if err != nil {
+ return err
+ }
+ argvp, err := SlicePtrFromStrings(argv)
+ if err != nil {
+ return err
+ }
+ envvp, err := SlicePtrFromStrings(envv)
+ if err != nil {
+ return err
+ }
+ runtime_BeforeExec()
+
+ rlim, rlimOK := origRlimitNofile.Load().(Rlimit)
+ if rlimOK && rlim.Cur != 0 {
+ Setrlimit(RLIMIT_NOFILE, &rlim)
+ }
+
+ var err1 error
+ if runtime.GOOS == "solaris" || runtime.GOOS == "illumos" || runtime.GOOS == "aix" {
+ // RawSyscall should never be used on Solaris, illumos, or AIX.
+ err1 = execveLibc(
+ uintptr(unsafe.Pointer(argv0p)),
+ uintptr(unsafe.Pointer(&argvp[0])),
+ uintptr(unsafe.Pointer(&envvp[0])))
+ } else if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
+ // Similarly on Darwin.
+ err1 = execveDarwin(argv0p, &argvp[0], &envvp[0])
+ } else if runtime.GOOS == "openbsd" && (runtime.GOARCH == "386" || runtime.GOARCH == "amd64" || runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
+ // Similarly on OpenBSD.
+ err1 = execveOpenBSD(argv0p, &argvp[0], &envvp[0])
+ } else {
+ _, _, err1 = RawSyscall(SYS_EXECVE,
+ uintptr(unsafe.Pointer(argv0p)),
+ uintptr(unsafe.Pointer(&argvp[0])),
+ uintptr(unsafe.Pointer(&envvp[0])))
+ }
+ runtime_AfterExec()
+ return err1
+}
diff --git a/contrib/go/_std_1.21/src/syscall/exec_windows.go b/contrib/go/_std_1.21/src/syscall/exec_windows.go
new file mode 100644
index 0000000000..0a93bc0a80
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/exec_windows.go
@@ -0,0 +1,432 @@
+// Copyright 2009 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.
+
+// Fork, exec, wait, etc.
+
+package syscall
+
+import (
+ "internal/bytealg"
+ "runtime"
+ "sync"
+ "unicode/utf16"
+ "unsafe"
+)
+
+var ForkLock sync.RWMutex
+
+// EscapeArg rewrites command line argument s as prescribed
+// in https://msdn.microsoft.com/en-us/library/ms880421.
+// This function returns "" (2 double quotes) if s is empty.
+// Alternatively, these transformations are done:
+// - every back slash (\) is doubled, but only if immediately
+// followed by double quote (");
+// - every double quote (") is escaped by back slash (\);
+// - finally, s is wrapped with double quotes (arg -> "arg"),
+// but only if there is space or tab inside s.
+func EscapeArg(s string) string {
+ if len(s) == 0 {
+ return `""`
+ }
+ for i := 0; i < len(s); i++ {
+ switch s[i] {
+ case '"', '\\', ' ', '\t':
+ // Some escaping required.
+ b := make([]byte, 0, len(s)+2)
+ b = appendEscapeArg(b, s)
+ return string(b)
+ }
+ }
+ return s
+}
+
+// appendEscapeArg escapes the string s, as per escapeArg,
+// appends the result to b, and returns the updated slice.
+func appendEscapeArg(b []byte, s string) []byte {
+ if len(s) == 0 {
+ return append(b, `""`...)
+ }
+
+ needsBackslash := false
+ hasSpace := false
+ for i := 0; i < len(s); i++ {
+ switch s[i] {
+ case '"', '\\':
+ needsBackslash = true
+ case ' ', '\t':
+ hasSpace = true
+ }
+ }
+
+ if !needsBackslash && !hasSpace {
+ // No special handling required; normal case.
+ return append(b, s...)
+ }
+ if !needsBackslash {
+ // hasSpace is true, so we need to quote the string.
+ b = append(b, '"')
+ b = append(b, s...)
+ return append(b, '"')
+ }
+
+ if hasSpace {
+ b = append(b, '"')
+ }
+ slashes := 0
+ for i := 0; i < len(s); i++ {
+ c := s[i]
+ switch c {
+ default:
+ slashes = 0
+ case '\\':
+ slashes++
+ case '"':
+ for ; slashes > 0; slashes-- {
+ b = append(b, '\\')
+ }
+ b = append(b, '\\')
+ }
+ b = append(b, c)
+ }
+ if hasSpace {
+ for ; slashes > 0; slashes-- {
+ b = append(b, '\\')
+ }
+ b = append(b, '"')
+ }
+
+ return b
+}
+
+// makeCmdLine builds a command line out of args by escaping "special"
+// characters and joining the arguments with spaces.
+func makeCmdLine(args []string) string {
+ var b []byte
+ for _, v := range args {
+ if len(b) > 0 {
+ b = append(b, ' ')
+ }
+ b = appendEscapeArg(b, v)
+ }
+ return string(b)
+}
+
+// createEnvBlock converts an array of environment strings into
+// the representation required by CreateProcess: a sequence of NUL
+// terminated strings followed by a nil.
+// Last bytes are two UCS-2 NULs, or four NUL bytes.
+// If any string contains a NUL, it returns (nil, EINVAL).
+func createEnvBlock(envv []string) (*uint16, error) {
+ if len(envv) == 0 {
+ return &utf16.Encode([]rune("\x00\x00"))[0], nil
+ }
+ length := 0
+ for _, s := range envv {
+ if bytealg.IndexByteString(s, 0) != -1 {
+ return nil, EINVAL
+ }
+ length += len(s) + 1
+ }
+ length += 1
+
+ b := make([]byte, length)
+ i := 0
+ for _, s := range envv {
+ l := len(s)
+ copy(b[i:i+l], []byte(s))
+ copy(b[i+l:i+l+1], []byte{0})
+ i = i + l + 1
+ }
+ copy(b[i:i+1], []byte{0})
+
+ return &utf16.Encode([]rune(string(b)))[0], nil
+}
+
+func CloseOnExec(fd Handle) {
+ SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
+}
+
+func SetNonblock(fd Handle, nonblocking bool) (err error) {
+ return nil
+}
+
+// FullPath retrieves the full path of the specified file.
+func FullPath(name string) (path string, err error) {
+ p, err := UTF16PtrFromString(name)
+ if err != nil {
+ return "", err
+ }
+ n := uint32(100)
+ for {
+ buf := make([]uint16, n)
+ n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
+ if err != nil {
+ return "", err
+ }
+ if n <= uint32(len(buf)) {
+ return UTF16ToString(buf[:n]), nil
+ }
+ }
+}
+
+func isSlash(c uint8) bool {
+ return c == '\\' || c == '/'
+}
+
+func normalizeDir(dir string) (name string, err error) {
+ ndir, err := FullPath(dir)
+ if err != nil {
+ return "", err
+ }
+ if len(ndir) > 2 && isSlash(ndir[0]) && isSlash(ndir[1]) {
+ // dir cannot have \\server\share\path form
+ return "", EINVAL
+ }
+ return ndir, nil
+}
+
+func volToUpper(ch int) int {
+ if 'a' <= ch && ch <= 'z' {
+ ch += 'A' - 'a'
+ }
+ return ch
+}
+
+func joinExeDirAndFName(dir, p string) (name string, err error) {
+ if len(p) == 0 {
+ return "", EINVAL
+ }
+ if len(p) > 2 && isSlash(p[0]) && isSlash(p[1]) {
+ // \\server\share\path form
+ return p, nil
+ }
+ if len(p) > 1 && p[1] == ':' {
+ // has drive letter
+ if len(p) == 2 {
+ return "", EINVAL
+ }
+ if isSlash(p[2]) {
+ return p, nil
+ } else {
+ d, err := normalizeDir(dir)
+ if err != nil {
+ return "", err
+ }
+ if volToUpper(int(p[0])) == volToUpper(int(d[0])) {
+ return FullPath(d + "\\" + p[2:])
+ } else {
+ return FullPath(p)
+ }
+ }
+ } else {
+ // no drive letter
+ d, err := normalizeDir(dir)
+ if err != nil {
+ return "", err
+ }
+ if isSlash(p[0]) {
+ return FullPath(d[:2] + p)
+ } else {
+ return FullPath(d + "\\" + p)
+ }
+ }
+}
+
+type ProcAttr struct {
+ Dir string
+ Env []string
+ Files []uintptr
+ Sys *SysProcAttr
+}
+
+type SysProcAttr struct {
+ HideWindow bool
+ CmdLine string // used if non-empty, else the windows command line is built by escaping the arguments passed to StartProcess
+ CreationFlags uint32
+ Token Token // if set, runs new process in the security context represented by the token
+ ProcessAttributes *SecurityAttributes // if set, applies these security attributes as the descriptor for the new process
+ ThreadAttributes *SecurityAttributes // if set, applies these security attributes as the descriptor for the main thread of the new process
+ NoInheritHandles bool // if set, no handles are inherited by the new process, not even the standard handles, contained in ProcAttr.Files, nor the ones contained in AdditionalInheritedHandles
+ AdditionalInheritedHandles []Handle // a list of additional handles, already marked as inheritable, that will be inherited by the new process
+ ParentProcess Handle // if non-zero, the new process regards the process given by this handle as its parent process, and AdditionalInheritedHandles, if set, should exist in this parent process
+}
+
+var zeroProcAttr ProcAttr
+var zeroSysProcAttr SysProcAttr
+
+func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
+ if len(argv0) == 0 {
+ return 0, 0, EWINDOWS
+ }
+ if attr == nil {
+ attr = &zeroProcAttr
+ }
+ sys := attr.Sys
+ if sys == nil {
+ sys = &zeroSysProcAttr
+ }
+
+ if len(attr.Files) > 3 {
+ return 0, 0, EWINDOWS
+ }
+ if len(attr.Files) < 3 {
+ return 0, 0, EINVAL
+ }
+
+ if len(attr.Dir) != 0 {
+ // StartProcess assumes that argv0 is relative to attr.Dir,
+ // because it implies Chdir(attr.Dir) before executing argv0.
+ // Windows CreateProcess assumes the opposite: it looks for
+ // argv0 relative to the current directory, and, only once the new
+ // process is started, it does Chdir(attr.Dir). We are adjusting
+ // for that difference here by making argv0 absolute.
+ var err error
+ argv0, err = joinExeDirAndFName(attr.Dir, argv0)
+ if err != nil {
+ return 0, 0, err
+ }
+ }
+ argv0p, err := UTF16PtrFromString(argv0)
+ if err != nil {
+ return 0, 0, err
+ }
+
+ var cmdline string
+ // Windows CreateProcess takes the command line as a single string:
+ // use attr.CmdLine if set, else build the command line by escaping
+ // and joining each argument with spaces
+ if sys.CmdLine != "" {
+ cmdline = sys.CmdLine
+ } else {
+ cmdline = makeCmdLine(argv)
+ }
+
+ var argvp *uint16
+ if len(cmdline) != 0 {
+ argvp, err = UTF16PtrFromString(cmdline)
+ if err != nil {
+ return 0, 0, err
+ }
+ }
+
+ var dirp *uint16
+ if len(attr.Dir) != 0 {
+ dirp, err = UTF16PtrFromString(attr.Dir)
+ if err != nil {
+ return 0, 0, err
+ }
+ }
+
+ var maj, min, build uint32
+ rtlGetNtVersionNumbers(&maj, &min, &build)
+ isWin7 := maj < 6 || (maj == 6 && min <= 1)
+ // NT kernel handles are divisible by 4, with the bottom 3 bits left as
+ // a tag. The fully set tag correlates with the types of handles we're
+ // concerned about here. Except, the kernel will interpret some
+ // special handle values, like -1, -2, and so forth, so kernelbase.dll
+ // checks to see that those bottom three bits are checked, but that top
+ // bit is not checked.
+ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 }
+
+ p, _ := GetCurrentProcess()
+ parentProcess := p
+ if sys.ParentProcess != 0 {
+ parentProcess = sys.ParentProcess
+ }
+ fd := make([]Handle, len(attr.Files))
+ for i := range attr.Files {
+ if attr.Files[i] > 0 {
+ destinationProcessHandle := parentProcess
+
+ // On Windows 7, console handles aren't real handles, and can only be duplicated
+ // into the current process, not a parent one, which amounts to the same thing.
+ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) {
+ destinationProcessHandle = p
+ }
+
+ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS)
+ if err != nil {
+ return 0, 0, err
+ }
+ defer DuplicateHandle(parentProcess, fd[i], 0, nil, 0, false, DUPLICATE_CLOSE_SOURCE)
+ }
+ }
+ si := new(_STARTUPINFOEXW)
+ si.ProcThreadAttributeList, err = newProcThreadAttributeList(2)
+ if err != nil {
+ return 0, 0, err
+ }
+ defer deleteProcThreadAttributeList(si.ProcThreadAttributeList)
+ si.Cb = uint32(unsafe.Sizeof(*si))
+ si.Flags = STARTF_USESTDHANDLES
+ if sys.HideWindow {
+ si.Flags |= STARTF_USESHOWWINDOW
+ si.ShowWindow = SW_HIDE
+ }
+ if sys.ParentProcess != 0 {
+ err = updateProcThreadAttribute(si.ProcThreadAttributeList, 0, _PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, unsafe.Pointer(&sys.ParentProcess), unsafe.Sizeof(sys.ParentProcess), nil, nil)
+ if err != nil {
+ return 0, 0, err
+ }
+ }
+ si.StdInput = fd[0]
+ si.StdOutput = fd[1]
+ si.StdErr = fd[2]
+
+ fd = append(fd, sys.AdditionalInheritedHandles...)
+
+ // On Windows 7, console handles aren't real handles, so don't pass them
+ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST.
+ for i := range fd {
+ if isLegacyWin7ConsoleHandle(fd[i]) {
+ fd[i] = 0
+ }
+ }
+
+ // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST
+ // to treat the entire list as empty, so remove NULL handles.
+ j := 0
+ for i := range fd {
+ if fd[i] != 0 {
+ fd[j] = fd[i]
+ j++
+ }
+ }
+ fd = fd[:j]
+
+ willInheritHandles := len(fd) > 0 && !sys.NoInheritHandles
+
+ // Do not accidentally inherit more than these handles.
+ if willInheritHandles {
+ err = updateProcThreadAttribute(si.ProcThreadAttributeList, 0, _PROC_THREAD_ATTRIBUTE_HANDLE_LIST, unsafe.Pointer(&fd[0]), uintptr(len(fd))*unsafe.Sizeof(fd[0]), nil, nil)
+ if err != nil {
+ return 0, 0, err
+ }
+ }
+
+ envBlock, err := createEnvBlock(attr.Env)
+ if err != nil {
+ return 0, 0, err
+ }
+
+ pi := new(ProcessInformation)
+ flags := sys.CreationFlags | CREATE_UNICODE_ENVIRONMENT | _EXTENDED_STARTUPINFO_PRESENT
+ if sys.Token != 0 {
+ err = CreateProcessAsUser(sys.Token, argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, willInheritHandles, flags, envBlock, dirp, &si.StartupInfo, pi)
+ } else {
+ err = CreateProcess(argv0p, argvp, sys.ProcessAttributes, sys.ThreadAttributes, willInheritHandles, flags, envBlock, dirp, &si.StartupInfo, pi)
+ }
+ if err != nil {
+ return 0, 0, err
+ }
+ defer CloseHandle(Handle(pi.Thread))
+ runtime.KeepAlive(fd)
+ runtime.KeepAlive(sys)
+
+ return int(pi.ProcessId), uintptr(pi.Process), nil
+}
+
+func Exec(argv0 string, argv []string, envv []string) (err error) {
+ return EWINDOWS
+}
diff --git a/contrib/go/_std_1.20/src/syscall/flock.go b/contrib/go/_std_1.21/src/syscall/flock.go
index 820f526fe0..820f526fe0 100644
--- a/contrib/go/_std_1.20/src/syscall/flock.go
+++ b/contrib/go/_std_1.21/src/syscall/flock.go
diff --git a/contrib/go/_std_1.20/src/syscall/flock_darwin.go b/contrib/go/_std_1.21/src/syscall/flock_darwin.go
index d2bd84130c..d2bd84130c 100644
--- a/contrib/go/_std_1.20/src/syscall/flock_darwin.go
+++ b/contrib/go/_std_1.21/src/syscall/flock_darwin.go
diff --git a/contrib/go/_std_1.21/src/syscall/forkpipe.go b/contrib/go/_std_1.21/src/syscall/forkpipe.go
new file mode 100644
index 0000000000..1f4292f686
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/forkpipe.go
@@ -0,0 +1,30 @@
+// Copyright 2011 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.
+
+//go:build aix || darwin
+
+package syscall
+
+// forkExecPipe opens a pipe and non-atomically sets O_CLOEXEC on both file
+// descriptors.
+func forkExecPipe(p []int) error {
+ err := Pipe(p)
+ if err != nil {
+ return err
+ }
+ _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC)
+ if err != nil {
+ return err
+ }
+ _, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
+ return err
+}
+
+func acquireForkLock() {
+ ForkLock.Lock()
+}
+
+func releaseForkLock() {
+ ForkLock.Unlock()
+}
diff --git a/contrib/go/_std_1.21/src/syscall/forkpipe2.go b/contrib/go/_std_1.21/src/syscall/forkpipe2.go
new file mode 100644
index 0000000000..bbecfdabf8
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/forkpipe2.go
@@ -0,0 +1,98 @@
+// Copyright 2017 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.
+
+//go:build dragonfly || freebsd || linux || netbsd || openbsd || solaris
+
+package syscall
+
+import "sync"
+
+// forkExecPipe atomically opens a pipe with O_CLOEXEC set on both file
+// descriptors.
+func forkExecPipe(p []int) error {
+ return Pipe2(p, O_CLOEXEC)
+}
+
+var (
+ // Guard the forking variable.
+ forkingLock sync.Mutex
+ // Number of goroutines currently forking, and thus the
+ // number of goroutines holding a conceptual write lock
+ // on ForkLock.
+ forking int
+)
+
+// hasWaitingReaders reports whether any goroutine is waiting
+// to acquire a read lock on rw. It is defined in the sync package.
+func hasWaitingReaders(rw *sync.RWMutex) bool
+
+// acquireForkLock acquires a write lock on ForkLock.
+// ForkLock is exported and we've promised that during a fork
+// we will call ForkLock.Lock, so that no other threads create
+// new fds that are not yet close-on-exec before we fork.
+// But that forces all fork calls to be serialized, which is bad.
+// But we haven't promised that serialization, and it is essentially
+// undetectable by other users of ForkLock, which is good.
+// Avoid the serialization by ensuring that ForkLock is locked
+// at the first fork and unlocked when there are no more forks.
+func acquireForkLock() {
+ forkingLock.Lock()
+ defer forkingLock.Unlock()
+
+ if forking == 0 {
+ // There is no current write lock on ForkLock.
+ ForkLock.Lock()
+ forking++
+ return
+ }
+
+ // ForkLock is currently locked for writing.
+
+ if hasWaitingReaders(&ForkLock) {
+ // ForkLock is locked for writing, and at least one
+ // goroutine is waiting to read from it.
+ // To avoid lock starvation, allow readers to proceed.
+ // The simple way to do this is for us to acquire a
+ // read lock. That will block us until all current
+ // conceptual write locks are released.
+ //
+ // Note that this case is unusual on modern systems
+ // with O_CLOEXEC and SOCK_CLOEXEC. On those systems
+ // the standard library should never take a read
+ // lock on ForkLock.
+
+ forkingLock.Unlock()
+
+ ForkLock.RLock()
+ ForkLock.RUnlock()
+
+ forkingLock.Lock()
+
+ // Readers got a chance, so now take the write lock.
+
+ if forking == 0 {
+ ForkLock.Lock()
+ }
+ }
+
+ forking++
+}
+
+// releaseForkLock releases the conceptual write lock on ForkLock
+// acquired by acquireForkLock.
+func releaseForkLock() {
+ forkingLock.Lock()
+ defer forkingLock.Unlock()
+
+ if forking <= 0 {
+ panic("syscall.releaseForkLock: negative count")
+ }
+
+ forking--
+
+ if forking == 0 {
+ // No more conceptual write locks.
+ ForkLock.Unlock()
+ }
+}
diff --git a/contrib/go/_std_1.20/src/syscall/lsf_linux.go b/contrib/go/_std_1.21/src/syscall/lsf_linux.go
index 838acc5fb1..838acc5fb1 100644
--- a/contrib/go/_std_1.20/src/syscall/lsf_linux.go
+++ b/contrib/go/_std_1.21/src/syscall/lsf_linux.go
diff --git a/contrib/go/_std_1.20/src/syscall/msan0.go b/contrib/go/_std_1.21/src/syscall/msan0.go
index fba8a5f716..fba8a5f716 100644
--- a/contrib/go/_std_1.20/src/syscall/msan0.go
+++ b/contrib/go/_std_1.21/src/syscall/msan0.go
diff --git a/contrib/go/_std_1.20/src/syscall/net.go b/contrib/go/_std_1.21/src/syscall/net.go
index 531fa80d8f..531fa80d8f 100644
--- a/contrib/go/_std_1.20/src/syscall/net.go
+++ b/contrib/go/_std_1.21/src/syscall/net.go
diff --git a/contrib/go/_std_1.21/src/syscall/netlink_linux.go b/contrib/go/_std_1.21/src/syscall/netlink_linux.go
new file mode 100644
index 0000000000..a503a07440
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/netlink_linux.go
@@ -0,0 +1,188 @@
+// Copyright 2011 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.
+
+// Netlink sockets and messages
+
+package syscall
+
+import (
+ "sync"
+ "unsafe"
+)
+
+// Round the length of a netlink message up to align it properly.
+func nlmAlignOf(msglen int) int {
+ return (msglen + NLMSG_ALIGNTO - 1) & ^(NLMSG_ALIGNTO - 1)
+}
+
+// Round the length of a netlink route attribute up to align it
+// properly.
+func rtaAlignOf(attrlen int) int {
+ return (attrlen + RTA_ALIGNTO - 1) & ^(RTA_ALIGNTO - 1)
+}
+
+// NetlinkRouteRequest represents a request message to receive routing
+// and link states from the kernel.
+type NetlinkRouteRequest struct {
+ Header NlMsghdr
+ Data RtGenmsg
+}
+
+func (rr *NetlinkRouteRequest) toWireFormat() []byte {
+ b := make([]byte, rr.Header.Len)
+ *(*uint32)(unsafe.Pointer(&b[0:4][0])) = rr.Header.Len
+ *(*uint16)(unsafe.Pointer(&b[4:6][0])) = rr.Header.Type
+ *(*uint16)(unsafe.Pointer(&b[6:8][0])) = rr.Header.Flags
+ *(*uint32)(unsafe.Pointer(&b[8:12][0])) = rr.Header.Seq
+ *(*uint32)(unsafe.Pointer(&b[12:16][0])) = rr.Header.Pid
+ b[16] = byte(rr.Data.Family)
+ return b
+}
+
+func newNetlinkRouteRequest(proto, seq, family int) []byte {
+ rr := &NetlinkRouteRequest{}
+ rr.Header.Len = uint32(NLMSG_HDRLEN + SizeofRtGenmsg)
+ rr.Header.Type = uint16(proto)
+ rr.Header.Flags = NLM_F_DUMP | NLM_F_REQUEST
+ rr.Header.Seq = uint32(seq)
+ rr.Data.Family = uint8(family)
+ return rr.toWireFormat()
+}
+
+var pageBufPool = &sync.Pool{New: func() any {
+ b := make([]byte, Getpagesize())
+ return &b
+}}
+
+// NetlinkRIB returns routing information base, as known as RIB, which
+// consists of network facility information, states and parameters.
+func NetlinkRIB(proto, family int) ([]byte, error) {
+ s, err := Socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE)
+ if err != nil {
+ return nil, err
+ }
+ defer Close(s)
+ sa := &SockaddrNetlink{Family: AF_NETLINK}
+ if err := Bind(s, sa); err != nil {
+ return nil, err
+ }
+ wb := newNetlinkRouteRequest(proto, 1, family)
+ if err := Sendto(s, wb, 0, sa); err != nil {
+ return nil, err
+ }
+ lsa, err := Getsockname(s)
+ if err != nil {
+ return nil, err
+ }
+ lsanl, ok := lsa.(*SockaddrNetlink)
+ if !ok {
+ return nil, EINVAL
+ }
+ var tab []byte
+
+ rbNew := pageBufPool.Get().(*[]byte)
+ defer pageBufPool.Put(rbNew)
+done:
+ for {
+ rb := *rbNew
+ nr, _, err := Recvfrom(s, rb, 0)
+ if err != nil {
+ return nil, err
+ }
+ if nr < NLMSG_HDRLEN {
+ return nil, EINVAL
+ }
+ rb = rb[:nr]
+ tab = append(tab, rb...)
+ msgs, err := ParseNetlinkMessage(rb)
+ if err != nil {
+ return nil, err
+ }
+ for _, m := range msgs {
+ if m.Header.Seq != 1 || m.Header.Pid != lsanl.Pid {
+ return nil, EINVAL
+ }
+ if m.Header.Type == NLMSG_DONE {
+ break done
+ }
+ if m.Header.Type == NLMSG_ERROR {
+ return nil, EINVAL
+ }
+ }
+ }
+ return tab, nil
+}
+
+// NetlinkMessage represents a netlink message.
+type NetlinkMessage struct {
+ Header NlMsghdr
+ Data []byte
+}
+
+// ParseNetlinkMessage parses b as an array of netlink messages and
+// returns the slice containing the NetlinkMessage structures.
+func ParseNetlinkMessage(b []byte) ([]NetlinkMessage, error) {
+ var msgs []NetlinkMessage
+ for len(b) >= NLMSG_HDRLEN {
+ h, dbuf, dlen, err := netlinkMessageHeaderAndData(b)
+ if err != nil {
+ return nil, err
+ }
+ m := NetlinkMessage{Header: *h, Data: dbuf[:int(h.Len)-NLMSG_HDRLEN]}
+ msgs = append(msgs, m)
+ b = b[dlen:]
+ }
+ return msgs, nil
+}
+
+func netlinkMessageHeaderAndData(b []byte) (*NlMsghdr, []byte, int, error) {
+ h := (*NlMsghdr)(unsafe.Pointer(&b[0]))
+ l := nlmAlignOf(int(h.Len))
+ if int(h.Len) < NLMSG_HDRLEN || l > len(b) {
+ return nil, nil, 0, EINVAL
+ }
+ return h, b[NLMSG_HDRLEN:], l, nil
+}
+
+// NetlinkRouteAttr represents a netlink route attribute.
+type NetlinkRouteAttr struct {
+ Attr RtAttr
+ Value []byte
+}
+
+// ParseNetlinkRouteAttr parses m's payload as an array of netlink
+// route attributes and returns the slice containing the
+// NetlinkRouteAttr structures.
+func ParseNetlinkRouteAttr(m *NetlinkMessage) ([]NetlinkRouteAttr, error) {
+ var b []byte
+ switch m.Header.Type {
+ case RTM_NEWLINK, RTM_DELLINK:
+ b = m.Data[SizeofIfInfomsg:]
+ case RTM_NEWADDR, RTM_DELADDR:
+ b = m.Data[SizeofIfAddrmsg:]
+ case RTM_NEWROUTE, RTM_DELROUTE:
+ b = m.Data[SizeofRtMsg:]
+ default:
+ return nil, EINVAL
+ }
+ var attrs []NetlinkRouteAttr
+ for len(b) >= SizeofRtAttr {
+ a, vbuf, alen, err := netlinkRouteAttrAndValue(b)
+ if err != nil {
+ return nil, err
+ }
+ ra := NetlinkRouteAttr{Attr: *a, Value: vbuf[:int(a.Len)-SizeofRtAttr]}
+ attrs = append(attrs, ra)
+ b = b[alen:]
+ }
+ return attrs, nil
+}
+
+func netlinkRouteAttrAndValue(b []byte) (*RtAttr, []byte, int, error) {
+ a := (*RtAttr)(unsafe.Pointer(&b[0]))
+ if int(a.Len) < SizeofRtAttr || int(a.Len) > len(b) {
+ return nil, nil, 0, EINVAL
+ }
+ return a, b[SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil
+}
diff --git a/contrib/go/_std_1.21/src/syscall/ptrace_darwin.go b/contrib/go/_std_1.21/src/syscall/ptrace_darwin.go
new file mode 100644
index 0000000000..466f8135b4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/ptrace_darwin.go
@@ -0,0 +1,21 @@
+// 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.
+
+//go:build !ios
+
+package syscall
+
+import "unsafe"
+
+// Nosplit because it is called from forkAndExecInChild.
+//
+//go:nosplit
+func ptrace(request int, pid int, addr uintptr, data uintptr) error {
+ return ptrace1(request, pid, addr, data)
+}
+
+//go:nosplit
+func ptracePtr(request int, pid int, addr unsafe.Pointer, data uintptr) error {
+ return ptrace1Ptr(request, pid, addr, data)
+}
diff --git a/contrib/go/_std_1.20/src/syscall/rlimit.go b/contrib/go/_std_1.21/src/syscall/rlimit.go
index cc7935d37b..cc7935d37b 100644
--- a/contrib/go/_std_1.20/src/syscall/rlimit.go
+++ b/contrib/go/_std_1.21/src/syscall/rlimit.go
diff --git a/contrib/go/_std_1.20/src/syscall/rlimit_darwin.go b/contrib/go/_std_1.21/src/syscall/rlimit_darwin.go
index 73e49646b3..73e49646b3 100644
--- a/contrib/go/_std_1.20/src/syscall/rlimit_darwin.go
+++ b/contrib/go/_std_1.21/src/syscall/rlimit_darwin.go
diff --git a/contrib/go/_std_1.20/src/syscall/rlimit_stub.go b/contrib/go/_std_1.21/src/syscall/rlimit_stub.go
index e8f839dd99..e8f839dd99 100644
--- a/contrib/go/_std_1.20/src/syscall/rlimit_stub.go
+++ b/contrib/go/_std_1.21/src/syscall/rlimit_stub.go
diff --git a/contrib/go/_std_1.20/src/syscall/route_bsd.go b/contrib/go/_std_1.21/src/syscall/route_bsd.go
index 8e47ff888e..8e47ff888e 100644
--- a/contrib/go/_std_1.20/src/syscall/route_bsd.go
+++ b/contrib/go/_std_1.21/src/syscall/route_bsd.go
diff --git a/contrib/go/_std_1.20/src/syscall/route_darwin.go b/contrib/go/_std_1.21/src/syscall/route_darwin.go
index b0636ed07c..b0636ed07c 100644
--- a/contrib/go/_std_1.20/src/syscall/route_darwin.go
+++ b/contrib/go/_std_1.21/src/syscall/route_darwin.go
diff --git a/contrib/go/_std_1.21/src/syscall/security_windows.go b/contrib/go/_std_1.21/src/syscall/security_windows.go
new file mode 100644
index 0000000000..00dc920974
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/security_windows.go
@@ -0,0 +1,378 @@
+// Copyright 2012 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 syscall
+
+import (
+ "unsafe"
+)
+
+const (
+ STANDARD_RIGHTS_REQUIRED = 0xf0000
+ STANDARD_RIGHTS_READ = 0x20000
+ STANDARD_RIGHTS_WRITE = 0x20000
+ STANDARD_RIGHTS_EXECUTE = 0x20000
+ STANDARD_RIGHTS_ALL = 0x1F0000
+)
+
+const (
+ NameUnknown = 0
+ NameFullyQualifiedDN = 1
+ NameSamCompatible = 2
+ NameDisplay = 3
+ NameUniqueId = 6
+ NameCanonical = 7
+ NameUserPrincipal = 8
+ NameCanonicalEx = 9
+ NameServicePrincipal = 10
+ NameDnsDomain = 12
+)
+
+// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
+// https://blogs.msdn.com/b/drnick/archive/2007/12/19/windows-and-upn-format-credentials.aspx
+//sys TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.TranslateNameW
+//sys GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) [failretval&0xff==0] = secur32.GetUserNameExW
+
+// TranslateAccountName converts a directory service
+// object name from one format to another.
+func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
+ u, e := UTF16PtrFromString(username)
+ if e != nil {
+ return "", e
+ }
+ n := uint32(50)
+ for {
+ b := make([]uint16, n)
+ e = TranslateName(u, from, to, &b[0], &n)
+ if e == nil {
+ return UTF16ToString(b[:n]), nil
+ }
+ if e != ERROR_INSUFFICIENT_BUFFER {
+ return "", e
+ }
+ if n <= uint32(len(b)) {
+ return "", e
+ }
+ }
+}
+
+const (
+ // do not reorder
+ NetSetupUnknownStatus = iota
+ NetSetupUnjoined
+ NetSetupWorkgroupName
+ NetSetupDomainName
+)
+
+type UserInfo10 struct {
+ Name *uint16
+ Comment *uint16
+ UsrComment *uint16
+ FullName *uint16
+}
+
+//sys NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) = netapi32.NetUserGetInfo
+//sys NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) = netapi32.NetGetJoinInformation
+//sys NetApiBufferFree(buf *byte) (neterr error) = netapi32.NetApiBufferFree
+
+const (
+ // do not reorder
+ SidTypeUser = 1 + iota
+ SidTypeGroup
+ SidTypeDomain
+ SidTypeAlias
+ SidTypeWellKnownGroup
+ SidTypeDeletedAccount
+ SidTypeInvalid
+ SidTypeUnknown
+ SidTypeComputer
+ SidTypeLabel
+)
+
+//sys LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountSidW
+//sys LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) = advapi32.LookupAccountNameW
+//sys ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) = advapi32.ConvertSidToStringSidW
+//sys ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) = advapi32.ConvertStringSidToSidW
+//sys GetLengthSid(sid *SID) (len uint32) = advapi32.GetLengthSid
+//sys CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) = advapi32.CopySid
+
+// The security identifier (SID) structure is a variable-length
+// structure used to uniquely identify users or groups.
+type SID struct{}
+
+// StringToSid converts a string-format security identifier
+// sid into a valid, functional sid.
+func StringToSid(s string) (*SID, error) {
+ var sid *SID
+ p, e := UTF16PtrFromString(s)
+ if e != nil {
+ return nil, e
+ }
+ e = ConvertStringSidToSid(p, &sid)
+ if e != nil {
+ return nil, e
+ }
+ defer LocalFree((Handle)(unsafe.Pointer(sid)))
+ return sid.Copy()
+}
+
+// LookupSID retrieves a security identifier sid for the account
+// and the name of the domain on which the account was found.
+// System specify target computer to search.
+func LookupSID(system, account string) (sid *SID, domain string, accType uint32, err error) {
+ if len(account) == 0 {
+ return nil, "", 0, EINVAL
+ }
+ acc, e := UTF16PtrFromString(account)
+ if e != nil {
+ return nil, "", 0, e
+ }
+ var sys *uint16
+ if len(system) > 0 {
+ sys, e = UTF16PtrFromString(system)
+ if e != nil {
+ return nil, "", 0, e
+ }
+ }
+ n := uint32(50)
+ dn := uint32(50)
+ for {
+ b := make([]byte, n)
+ db := make([]uint16, dn)
+ sid = (*SID)(unsafe.Pointer(&b[0]))
+ e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
+ if e == nil {
+ return sid, UTF16ToString(db), accType, nil
+ }
+ if e != ERROR_INSUFFICIENT_BUFFER {
+ return nil, "", 0, e
+ }
+ if n <= uint32(len(b)) {
+ return nil, "", 0, e
+ }
+ }
+}
+
+// String converts sid to a string format
+// suitable for display, storage, or transmission.
+func (sid *SID) String() (string, error) {
+ var s *uint16
+ e := ConvertSidToStringSid(sid, &s)
+ if e != nil {
+ return "", e
+ }
+ defer LocalFree((Handle)(unsafe.Pointer(s)))
+ return utf16PtrToString(s), nil
+}
+
+// Len returns the length, in bytes, of a valid security identifier sid.
+func (sid *SID) Len() int {
+ return int(GetLengthSid(sid))
+}
+
+// Copy creates a duplicate of security identifier sid.
+func (sid *SID) Copy() (*SID, error) {
+ b := make([]byte, sid.Len())
+ sid2 := (*SID)(unsafe.Pointer(&b[0]))
+ e := CopySid(uint32(len(b)), sid2, sid)
+ if e != nil {
+ return nil, e
+ }
+ return sid2, nil
+}
+
+// LookupAccount retrieves the name of the account for this sid
+// and the name of the first domain on which this sid is found.
+// System specify target computer to search for.
+func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
+ var sys *uint16
+ if len(system) > 0 {
+ sys, err = UTF16PtrFromString(system)
+ if err != nil {
+ return "", "", 0, err
+ }
+ }
+ n := uint32(50)
+ dn := uint32(50)
+ for {
+ b := make([]uint16, n)
+ db := make([]uint16, dn)
+ e := LookupAccountSid(sys, sid, &b[0], &n, &db[0], &dn, &accType)
+ if e == nil {
+ return UTF16ToString(b), UTF16ToString(db), accType, nil
+ }
+ if e != ERROR_INSUFFICIENT_BUFFER {
+ return "", "", 0, e
+ }
+ if n <= uint32(len(b)) {
+ return "", "", 0, e
+ }
+ }
+}
+
+const (
+ // do not reorder
+ TOKEN_ASSIGN_PRIMARY = 1 << iota
+ TOKEN_DUPLICATE
+ TOKEN_IMPERSONATE
+ TOKEN_QUERY
+ TOKEN_QUERY_SOURCE
+ TOKEN_ADJUST_PRIVILEGES
+ TOKEN_ADJUST_GROUPS
+ TOKEN_ADJUST_DEFAULT
+ TOKEN_ADJUST_SESSIONID
+
+ TOKEN_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
+ TOKEN_ASSIGN_PRIMARY |
+ TOKEN_DUPLICATE |
+ TOKEN_IMPERSONATE |
+ TOKEN_QUERY |
+ TOKEN_QUERY_SOURCE |
+ TOKEN_ADJUST_PRIVILEGES |
+ TOKEN_ADJUST_GROUPS |
+ TOKEN_ADJUST_DEFAULT |
+ TOKEN_ADJUST_SESSIONID
+ TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY
+ TOKEN_WRITE = STANDARD_RIGHTS_WRITE |
+ TOKEN_ADJUST_PRIVILEGES |
+ TOKEN_ADJUST_GROUPS |
+ TOKEN_ADJUST_DEFAULT
+ TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE
+)
+
+const (
+ // do not reorder
+ TokenUser = 1 + iota
+ TokenGroups
+ TokenPrivileges
+ TokenOwner
+ TokenPrimaryGroup
+ TokenDefaultDacl
+ TokenSource
+ TokenType
+ TokenImpersonationLevel
+ TokenStatistics
+ TokenRestrictedSids
+ TokenSessionId
+ TokenGroupsAndPrivileges
+ TokenSessionReference
+ TokenSandBoxInert
+ TokenAuditPolicy
+ TokenOrigin
+ TokenElevationType
+ TokenLinkedToken
+ TokenElevation
+ TokenHasRestrictions
+ TokenAccessInformation
+ TokenVirtualizationAllowed
+ TokenVirtualizationEnabled
+ TokenIntegrityLevel
+ TokenUIAccess
+ TokenMandatoryPolicy
+ TokenLogonSid
+ MaxTokenInfoClass
+)
+
+type SIDAndAttributes struct {
+ Sid *SID
+ Attributes uint32
+}
+
+type Tokenuser struct {
+ User SIDAndAttributes
+}
+
+type Tokenprimarygroup struct {
+ PrimaryGroup *SID
+}
+
+//sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
+//sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
+//sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
+
+// An access token contains the security information for a logon session.
+// The system creates an access token when a user logs on, and every
+// process executed on behalf of the user has a copy of the token.
+// The token identifies the user, the user's groups, and the user's
+// privileges. The system uses the token to control access to securable
+// objects and to control the ability of the user to perform various
+// system-related operations on the local computer.
+type Token Handle
+
+// OpenCurrentProcessToken opens the access token
+// associated with current process.
+func OpenCurrentProcessToken() (Token, error) {
+ p, e := GetCurrentProcess()
+ if e != nil {
+ return 0, e
+ }
+ var t Token
+ e = OpenProcessToken(p, TOKEN_QUERY, &t)
+ if e != nil {
+ return 0, e
+ }
+ return t, nil
+}
+
+// Close releases access to access token.
+func (t Token) Close() error {
+ return CloseHandle(Handle(t))
+}
+
+// getInfo retrieves a specified type of information about an access token.
+func (t Token) getInfo(class uint32, initSize int) (unsafe.Pointer, error) {
+ n := uint32(initSize)
+ for {
+ b := make([]byte, n)
+ e := GetTokenInformation(t, class, &b[0], uint32(len(b)), &n)
+ if e == nil {
+ return unsafe.Pointer(&b[0]), nil
+ }
+ if e != ERROR_INSUFFICIENT_BUFFER {
+ return nil, e
+ }
+ if n <= uint32(len(b)) {
+ return nil, e
+ }
+ }
+}
+
+// GetTokenUser retrieves access token t user account information.
+func (t Token) GetTokenUser() (*Tokenuser, error) {
+ i, e := t.getInfo(TokenUser, 50)
+ if e != nil {
+ return nil, e
+ }
+ return (*Tokenuser)(i), nil
+}
+
+// GetTokenPrimaryGroup retrieves access token t primary group information.
+// A pointer to a SID structure representing a group that will become
+// the primary group of any objects created by a process using this access token.
+func (t Token) GetTokenPrimaryGroup() (*Tokenprimarygroup, error) {
+ i, e := t.getInfo(TokenPrimaryGroup, 50)
+ if e != nil {
+ return nil, e
+ }
+ return (*Tokenprimarygroup)(i), nil
+}
+
+// GetUserProfileDirectory retrieves path to the
+// root directory of the access token t user's profile.
+func (t Token) GetUserProfileDirectory() (string, error) {
+ n := uint32(100)
+ for {
+ b := make([]uint16, n)
+ e := GetUserProfileDirectory(t, &b[0], &n)
+ if e == nil {
+ return UTF16ToString(b), nil
+ }
+ if e != ERROR_INSUFFICIENT_BUFFER {
+ return "", e
+ }
+ if n <= uint32(len(b)) {
+ return "", e
+ }
+ }
+}
diff --git a/contrib/go/_std_1.20/src/syscall/setuidgid_linux.go b/contrib/go/_std_1.21/src/syscall/setuidgid_linux.go
index c995d258eb..c995d258eb 100644
--- a/contrib/go/_std_1.20/src/syscall/setuidgid_linux.go
+++ b/contrib/go/_std_1.21/src/syscall/setuidgid_linux.go
diff --git a/contrib/go/_std_1.20/src/syscall/sockcmsg_linux.go b/contrib/go/_std_1.21/src/syscall/sockcmsg_linux.go
index d97667cf7e..d97667cf7e 100644
--- a/contrib/go/_std_1.20/src/syscall/sockcmsg_linux.go
+++ b/contrib/go/_std_1.21/src/syscall/sockcmsg_linux.go
diff --git a/contrib/go/_std_1.20/src/syscall/sockcmsg_unix.go b/contrib/go/_std_1.21/src/syscall/sockcmsg_unix.go
index 6ade73e87e..6ade73e87e 100644
--- a/contrib/go/_std_1.20/src/syscall/sockcmsg_unix.go
+++ b/contrib/go/_std_1.21/src/syscall/sockcmsg_unix.go
diff --git a/contrib/go/_std_1.20/src/syscall/sockcmsg_unix_other.go b/contrib/go/_std_1.21/src/syscall/sockcmsg_unix_other.go
index 845bd9df99..845bd9df99 100644
--- a/contrib/go/_std_1.20/src/syscall/sockcmsg_unix_other.go
+++ b/contrib/go/_std_1.21/src/syscall/sockcmsg_unix_other.go
diff --git a/contrib/go/_std_1.20/src/syscall/syscall.go b/contrib/go/_std_1.21/src/syscall/syscall.go
index 446a299f57..446a299f57 100644
--- a/contrib/go/_std_1.20/src/syscall/syscall.go
+++ b/contrib/go/_std_1.21/src/syscall/syscall.go
diff --git a/contrib/go/_std_1.21/src/syscall/syscall_bsd.go b/contrib/go/_std_1.21/src/syscall/syscall_bsd.go
new file mode 100644
index 0000000000..0bb3cdf54b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/syscall_bsd.go
@@ -0,0 +1,531 @@
+// Copyright 2009 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.
+
+//go:build darwin || dragonfly || freebsd || netbsd || openbsd
+
+// BSD system call wrappers shared by *BSD based systems
+// including OS X (Darwin) and FreeBSD. Like the other
+// syscall_*.go files it is compiled as Go code but also
+// used as input to mksyscall which parses the //sys
+// lines and generates system call stubs.
+
+package syscall
+
+import (
+ "runtime"
+ "unsafe"
+)
+
+const ImplementsGetwd = true
+
+func Getwd() (string, error) {
+ var buf [pathMax]byte
+ _, err := getcwd(buf[:])
+ if err != nil {
+ return "", err
+ }
+ n := clen(buf[:])
+ if n < 1 {
+ return "", EINVAL
+ }
+ return string(buf[:n]), nil
+}
+
+/*
+ * Wrapped
+ */
+
+//sysnb getgroups(ngid int, gid *_Gid_t) (n int, err error)
+//sysnb setgroups(ngid int, gid *_Gid_t) (err error)
+
+func Getgroups() (gids []int, err error) {
+ n, err := getgroups(0, nil)
+ if err != nil {
+ return nil, err
+ }
+ if n == 0 {
+ return nil, nil
+ }
+
+ // Sanity check group count. Max is 16 on BSD.
+ if n < 0 || n > 1000 {
+ return nil, EINVAL
+ }
+
+ a := make([]_Gid_t, n)
+ n, err = getgroups(n, &a[0])
+ if err != nil {
+ return nil, err
+ }
+ gids = make([]int, n)
+ for i, v := range a[0:n] {
+ gids[i] = int(v)
+ }
+ return
+}
+
+func Setgroups(gids []int) (err error) {
+ if len(gids) == 0 {
+ return setgroups(0, nil)
+ }
+
+ a := make([]_Gid_t, len(gids))
+ for i, v := range gids {
+ a[i] = _Gid_t(v)
+ }
+ return setgroups(len(a), &a[0])
+}
+
+func ReadDirent(fd int, buf []byte) (n int, err error) {
+ // Final argument is (basep *uintptr) and the syscall doesn't take nil.
+ // 64 bits should be enough. (32 bits isn't even on 386). Since the
+ // actual system call is getdirentries64, 64 is a good guess.
+ // TODO(rsc): Can we use a single global basep for all calls?
+ var base = (*uintptr)(unsafe.Pointer(new(uint64)))
+ return Getdirentries(fd, buf, base)
+}
+
+// Wait status is 7 bits at bottom, either 0 (exited),
+// 0x7F (stopped), or a signal number that caused an exit.
+// The 0x80 bit is whether there was a core dump.
+// An extra number (exit code, signal causing a stop)
+// is in the high bits.
+
+type WaitStatus uint32
+
+const (
+ mask = 0x7F
+ core = 0x80
+ shift = 8
+
+ exited = 0
+ stopped = 0x7F
+)
+
+func (w WaitStatus) Exited() bool { return w&mask == exited }
+
+func (w WaitStatus) ExitStatus() int {
+ if w&mask != exited {
+ return -1
+ }
+ return int(w >> shift)
+}
+
+func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
+
+func (w WaitStatus) Signal() Signal {
+ sig := Signal(w & mask)
+ if sig == stopped || sig == 0 {
+ return -1
+ }
+ return sig
+}
+
+func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
+
+func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP }
+
+func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP }
+
+func (w WaitStatus) StopSignal() Signal {
+ if !w.Stopped() {
+ return -1
+ }
+ return Signal(w>>shift) & 0xFF
+}
+
+func (w WaitStatus) TrapCause() int { return -1 }
+
+//sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
+
+func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
+ var status _C_int
+ wpid, err = wait4(pid, &status, options, rusage)
+ if wstatus != nil {
+ *wstatus = WaitStatus(status)
+ }
+ return
+}
+
+//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
+//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
+//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
+//sysnb socket(domain int, typ int, proto int) (fd int, err error)
+//sys getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
+//sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
+//sysnb getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
+//sysnb getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
+//sys Shutdown(s int, how int) (err error)
+
+func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ if sa.Port < 0 || sa.Port > 0xFFFF {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Len = SizeofSockaddrInet4
+ sa.raw.Family = AF_INET
+ p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+ p[0] = byte(sa.Port >> 8)
+ p[1] = byte(sa.Port)
+ sa.raw.Addr = sa.Addr
+ return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
+}
+
+func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ if sa.Port < 0 || sa.Port > 0xFFFF {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Len = SizeofSockaddrInet6
+ sa.raw.Family = AF_INET6
+ p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+ p[0] = byte(sa.Port >> 8)
+ p[1] = byte(sa.Port)
+ sa.raw.Scope_id = sa.ZoneId
+ sa.raw.Addr = sa.Addr
+ return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
+}
+
+func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ name := sa.Name
+ n := len(name)
+ if n >= len(sa.raw.Path) || n == 0 {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
+ sa.raw.Family = AF_UNIX
+ for i := 0; i < n; i++ {
+ sa.raw.Path[i] = int8(name[i])
+ }
+ return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
+}
+
+func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ if sa.Index == 0 {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Len = sa.Len
+ sa.raw.Family = AF_LINK
+ sa.raw.Index = sa.Index
+ sa.raw.Type = sa.Type
+ sa.raw.Nlen = sa.Nlen
+ sa.raw.Alen = sa.Alen
+ sa.raw.Slen = sa.Slen
+ sa.raw.Data = sa.Data
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
+}
+
+func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
+ switch rsa.Addr.Family {
+ case AF_LINK:
+ pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
+ sa := new(SockaddrDatalink)
+ sa.Len = pp.Len
+ sa.Family = pp.Family
+ sa.Index = pp.Index
+ sa.Type = pp.Type
+ sa.Nlen = pp.Nlen
+ sa.Alen = pp.Alen
+ sa.Slen = pp.Slen
+ sa.Data = pp.Data
+ return sa, nil
+
+ case AF_UNIX:
+ pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
+ if pp.Len < 2 || pp.Len > SizeofSockaddrUnix {
+ return nil, EINVAL
+ }
+ sa := new(SockaddrUnix)
+
+ // Some BSDs include the trailing NUL in the length, whereas
+ // others do not. Work around this by subtracting the leading
+ // family and len. The path is then scanned to see if a NUL
+ // terminator still exists within the length.
+ n := int(pp.Len) - 2 // subtract leading Family, Len
+ for i := 0; i < n; i++ {
+ if pp.Path[i] == 0 {
+ // found early NUL; assume Len included the NUL
+ // or was overestimating.
+ n = i
+ break
+ }
+ }
+ sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
+ return sa, nil
+
+ case AF_INET:
+ pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
+ sa := new(SockaddrInet4)
+ p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ sa.Port = int(p[0])<<8 + int(p[1])
+ sa.Addr = pp.Addr
+ return sa, nil
+
+ case AF_INET6:
+ pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
+ sa := new(SockaddrInet6)
+ p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ sa.Port = int(p[0])<<8 + int(p[1])
+ sa.ZoneId = pp.Scope_id
+ sa.Addr = pp.Addr
+ return sa, nil
+ }
+ return nil, EAFNOSUPPORT
+}
+
+func Accept(fd int) (nfd int, sa Sockaddr, err error) {
+ var rsa RawSockaddrAny
+ var len _Socklen = SizeofSockaddrAny
+ nfd, err = accept(fd, &rsa, &len)
+ if err != nil {
+ return
+ }
+ if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && len == 0 {
+ // Accepted socket has no address.
+ // This is likely due to a bug in xnu kernels,
+ // where instead of ECONNABORTED error socket
+ // is accepted, but has no address.
+ Close(nfd)
+ return 0, nil, ECONNABORTED
+ }
+ sa, err = anyToSockaddr(&rsa)
+ if err != nil {
+ Close(nfd)
+ nfd = 0
+ }
+ return
+}
+
+func Getsockname(fd int) (sa Sockaddr, err error) {
+ var rsa RawSockaddrAny
+ var len _Socklen = SizeofSockaddrAny
+ if err = getsockname(fd, &rsa, &len); err != nil {
+ return
+ }
+ // TODO(jsing): DragonFly has a "bug" (see issue 3349), which should be
+ // reported upstream.
+ if runtime.GOOS == "dragonfly" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 {
+ rsa.Addr.Family = AF_UNIX
+ rsa.Addr.Len = SizeofSockaddrUnix
+ }
+ return anyToSockaddr(&rsa)
+}
+
+//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
+
+func GetsockoptByte(fd, level, opt int) (value byte, err error) {
+ var n byte
+ vallen := _Socklen(1)
+ err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
+ return n, err
+}
+
+func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
+ vallen := _Socklen(4)
+ err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
+ return value, err
+}
+
+func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
+ var value IPMreq
+ vallen := _Socklen(SizeofIPMreq)
+ err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+ return &value, err
+}
+
+func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
+ var value IPv6Mreq
+ vallen := _Socklen(SizeofIPv6Mreq)
+ err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+ return &value, err
+}
+
+func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
+ var value IPv6MTUInfo
+ vallen := _Socklen(SizeofIPv6MTUInfo)
+ err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+ return &value, err
+}
+
+func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
+ var value ICMPv6Filter
+ vallen := _Socklen(SizeofICMPv6Filter)
+ err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+ return &value, err
+}
+
+//sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
+//sys sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
+//sys recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
+
+func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
+ var msg Msghdr
+ msg.Name = (*byte)(unsafe.Pointer(rsa))
+ msg.Namelen = uint32(SizeofSockaddrAny)
+ var iov Iovec
+ if len(p) > 0 {
+ iov.Base = &p[0]
+ iov.SetLen(len(p))
+ }
+ var dummy byte
+ if len(oob) > 0 {
+ // receive at least one normal byte
+ if len(p) == 0 {
+ iov.Base = &dummy
+ iov.SetLen(1)
+ }
+ msg.Control = &oob[0]
+ msg.SetControllen(len(oob))
+ }
+ msg.Iov = &iov
+ msg.Iovlen = 1
+ if n, err = recvmsg(fd, &msg, flags); err != nil {
+ return
+ }
+ oobn = int(msg.Controllen)
+ recvflags = int(msg.Flags)
+ return
+}
+
+//sys sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
+
+func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
+ var msg Msghdr
+ msg.Name = (*byte)(ptr)
+ msg.Namelen = uint32(salen)
+ var iov Iovec
+ if len(p) > 0 {
+ iov.Base = &p[0]
+ iov.SetLen(len(p))
+ }
+ var dummy byte
+ if len(oob) > 0 {
+ // send at least one normal byte
+ if len(p) == 0 {
+ iov.Base = &dummy
+ iov.SetLen(1)
+ }
+ msg.Control = &oob[0]
+ msg.SetControllen(len(oob))
+ }
+ msg.Iov = &iov
+ msg.Iovlen = 1
+ if n, err = sendmsg(fd, &msg, flags); err != nil {
+ return 0, err
+ }
+ if len(oob) > 0 && len(p) == 0 {
+ n = 0
+ }
+ return n, nil
+}
+
+//sys kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error)
+
+func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err error) {
+ var change, event unsafe.Pointer
+ if len(changes) > 0 {
+ change = unsafe.Pointer(&changes[0])
+ }
+ if len(events) > 0 {
+ event = unsafe.Pointer(&events[0])
+ }
+ return kevent(kq, change, len(changes), event, len(events), timeout)
+}
+
+func Sysctl(name string) (value string, err error) {
+ // Translate name to mib number.
+ mib, err := nametomib(name)
+ if err != nil {
+ return "", err
+ }
+
+ // Find size.
+ n := uintptr(0)
+ if err = sysctl(mib, nil, &n, nil, 0); err != nil {
+ return "", err
+ }
+ if n == 0 {
+ return "", nil
+ }
+
+ // Read into buffer of that size.
+ buf := make([]byte, n)
+ if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil {
+ return "", err
+ }
+
+ // Throw away terminating NUL.
+ if n > 0 && buf[n-1] == '\x00' {
+ n--
+ }
+ return string(buf[0:n]), nil
+}
+
+func SysctlUint32(name string) (value uint32, err error) {
+ // Translate name to mib number.
+ mib, err := nametomib(name)
+ if err != nil {
+ return 0, err
+ }
+
+ // Read into buffer of that size.
+ n := uintptr(4)
+ buf := make([]byte, 4)
+ if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil {
+ return 0, err
+ }
+ if n != 4 {
+ return 0, EIO
+ }
+ return *(*uint32)(unsafe.Pointer(&buf[0])), nil
+}
+
+//sys utimes(path string, timeval *[2]Timeval) (err error)
+
+func Utimes(path string, tv []Timeval) (err error) {
+ if len(tv) != 2 {
+ return EINVAL
+ }
+ return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+}
+
+func UtimesNano(path string, ts []Timespec) error {
+ if len(ts) != 2 {
+ return EINVAL
+ }
+ err := utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
+ if err != ENOSYS {
+ return err
+ }
+ // Not as efficient as it could be because Timespec and
+ // Timeval have different types in the different OSes
+ tv := [2]Timeval{
+ NsecToTimeval(TimespecToNsec(ts[0])),
+ NsecToTimeval(TimespecToNsec(ts[1])),
+ }
+ return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+}
+
+//sys futimes(fd int, timeval *[2]Timeval) (err error)
+
+func Futimes(fd int, tv []Timeval) (err error) {
+ if len(tv) != 2 {
+ return EINVAL
+ }
+ return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+}
+
+//sys fcntl(fd int, cmd int, arg int) (val int, err error)
+
+var mapper = &mmapper{
+ active: make(map[*byte][]byte),
+ mmap: mmap,
+ munmap: munmap,
+}
+
+func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
+ return mapper.Mmap(fd, offset, length, prot, flags)
+}
+
+func Munmap(b []byte) (err error) {
+ return mapper.Munmap(b)
+}
diff --git a/contrib/go/_std_1.20/src/syscall/syscall_darwin.go b/contrib/go/_std_1.21/src/syscall/syscall_darwin.go
index a9639e3913..a9639e3913 100644
--- a/contrib/go/_std_1.20/src/syscall/syscall_darwin.go
+++ b/contrib/go/_std_1.21/src/syscall/syscall_darwin.go
diff --git a/contrib/go/_std_1.21/src/syscall/syscall_darwin_amd64.go b/contrib/go/_std_1.21/src/syscall/syscall_darwin_amd64.go
new file mode 100644
index 0000000000..52ca3c8d5a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/syscall_darwin_amd64.go
@@ -0,0 +1,68 @@
+// Copyright 2009 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 syscall
+
+import (
+ "internal/abi"
+ "unsafe"
+)
+
+func setTimespec(sec, nsec int64) Timespec {
+ return Timespec{Sec: sec, Nsec: nsec}
+}
+
+func setTimeval(sec, usec int64) Timeval {
+ return Timeval{Sec: sec, Usec: int32(usec)}
+}
+
+//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_fstat64
+//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_fstatfs64
+//sysnb Gettimeofday(tp *Timeval) (err error)
+//sys Lstat(path string, stat *Stat_t) (err error) = SYS_lstat64
+//sys Stat(path string, stat *Stat_t) (err error) = SYS_stat64
+//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_statfs64
+//sys fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_fstatat64
+//sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace
+//sys ptrace1Ptr(request int, pid int, addr unsafe.Pointer, data uintptr) (err error) = SYS_ptrace
+
+func SetKevent(k *Kevent_t, fd, mode, flags int) {
+ k.Ident = uint64(fd)
+ k.Filter = int16(mode)
+ k.Flags = uint16(flags)
+}
+
+func (iov *Iovec) SetLen(length int) {
+ iov.Len = uint64(length)
+}
+
+func (msghdr *Msghdr) SetControllen(length int) {
+ msghdr.Controllen = uint32(length)
+}
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+ cmsg.Len = uint32(length)
+}
+
+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+ var length = uint64(count)
+
+ _, _, e1 := syscall6(abi.FuncPCABI0(libc_sendfile_trampoline), uintptr(infd), uintptr(outfd), uintptr(*offset), uintptr(unsafe.Pointer(&length)), 0, 0)
+
+ written = int(length)
+
+ if e1 != 0 {
+ err = e1
+ }
+ return
+}
+
+func libc_sendfile_trampoline()
+
+//go:cgo_import_dynamic libc_sendfile sendfile "/usr/lib/libSystem.B.dylib"
+
+// Implemented in the runtime package (runtime/sys_darwin_64.go)
+func syscallX(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+
+func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
diff --git a/contrib/go/_std_1.21/src/syscall/syscall_linux.go b/contrib/go/_std_1.21/src/syscall/syscall_linux.go
new file mode 100644
index 0000000000..8b0a57b502
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/syscall_linux.go
@@ -0,0 +1,1284 @@
+// Copyright 2009 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.
+
+// Linux system calls.
+// This file is compiled as ordinary Go code,
+// but it is also input to mksyscall,
+// which parses the //sys lines and generates system call stubs.
+// Note that sometimes we use a lowercase //sys name and
+// wrap it in our own nicer implementation.
+
+package syscall
+
+import (
+ "internal/itoa"
+ "runtime"
+ "unsafe"
+)
+
+// N.B. RawSyscall6 is provided via linkname by runtime/internal/syscall.
+//
+// Errno is uintptr and thus compatible with the runtime/internal/syscall
+// definition.
+
+func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+
+// Pull in entersyscall/exitsyscall for Syscall/Syscall6.
+//
+// Note that this can't be a push linkname because the runtime already has a
+// nameless linkname to export to assembly here and in x/sys. Additionally,
+// entersyscall fetches the caller PC and SP and thus can't have a wrapper
+// inbetween.
+
+//go:linkname runtime_entersyscall runtime.entersyscall
+func runtime_entersyscall()
+
+//go:linkname runtime_exitsyscall runtime.exitsyscall
+func runtime_exitsyscall()
+
+// N.B. For the Syscall functions below:
+//
+// //go:uintptrkeepalive because the uintptr argument may be converted pointers
+// that need to be kept alive in the caller (this is implied for RawSyscall6
+// since it has no body).
+//
+// //go:nosplit because stack copying does not account for uintptrkeepalive, so
+// the stack must not grow. Stack copying cannot blindly assume that all
+// uintptr arguments are pointers, because some values may look like pointers,
+// but not really be pointers, and adjusting their value would break the call.
+//
+// //go:norace, on RawSyscall, to avoid race instrumentation if RawSyscall is
+// called after fork, or from a signal handler.
+//
+// //go:linkname to ensure ABI wrappers are generated for external callers
+// (notably x/sys/unix assembly).
+
+//go:uintptrkeepalive
+//go:nosplit
+//go:norace
+//go:linkname RawSyscall
+func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
+ return RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
+}
+
+//go:uintptrkeepalive
+//go:nosplit
+//go:linkname Syscall
+func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
+ runtime_entersyscall()
+ // N.B. Calling RawSyscall here is unsafe with atomic coverage
+ // instrumentation and race mode.
+ //
+ // Coverage instrumentation will add a sync/atomic call to RawSyscall.
+ // Race mode will add race instrumentation to sync/atomic. Race
+ // instrumentation requires a P, which we no longer have.
+ //
+ // RawSyscall6 is fine because it is implemented in assembly and thus
+ // has no coverage instrumentation.
+ //
+ // This is typically not a problem in the runtime because cmd/go avoids
+ // adding coverage instrumentation to the runtime in race mode.
+ r1, r2, err = RawSyscall6(trap, a1, a2, a3, 0, 0, 0)
+ runtime_exitsyscall()
+ return
+}
+
+//go:uintptrkeepalive
+//go:nosplit
+//go:linkname Syscall6
+func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
+ runtime_entersyscall()
+ r1, r2, err = RawSyscall6(trap, a1, a2, a3, a4, a5, a6)
+ runtime_exitsyscall()
+ return
+}
+
+func rawSyscallNoError(trap, a1, a2, a3 uintptr) (r1, r2 uintptr)
+func rawVforkSyscall(trap, a1, a2 uintptr) (r1 uintptr, err Errno)
+
+/*
+ * Wrapped
+ */
+
+func Access(path string, mode uint32) (err error) {
+ return Faccessat(_AT_FDCWD, path, mode, 0)
+}
+
+func Chmod(path string, mode uint32) (err error) {
+ return Fchmodat(_AT_FDCWD, path, mode, 0)
+}
+
+func Chown(path string, uid int, gid int) (err error) {
+ return Fchownat(_AT_FDCWD, path, uid, gid, 0)
+}
+
+func Creat(path string, mode uint32) (fd int, err error) {
+ return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode)
+}
+
+func EpollCreate(size int) (fd int, err error) {
+ if size <= 0 {
+ return -1, EINVAL
+ }
+ return EpollCreate1(0)
+}
+
+func isGroupMember(gid int) bool {
+ groups, err := Getgroups()
+ if err != nil {
+ return false
+ }
+
+ for _, g := range groups {
+ if g == gid {
+ return true
+ }
+ }
+ return false
+}
+
+func isCapDacOverrideSet() bool {
+ const _CAP_DAC_OVERRIDE = 1
+ var c caps
+ c.hdr.version = _LINUX_CAPABILITY_VERSION_3
+
+ _, _, err := RawSyscall(SYS_CAPGET, uintptr(unsafe.Pointer(&c.hdr)), uintptr(unsafe.Pointer(&c.data[0])), 0)
+
+ return err == 0 && c.data[0].effective&capToMask(_CAP_DAC_OVERRIDE) != 0
+}
+
+//sys faccessat(dirfd int, path string, mode uint32) (err error)
+//sys faccessat2(dirfd int, path string, mode uint32, flags int) (err error) = _SYS_faccessat2
+
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+ if flags == 0 {
+ return faccessat(dirfd, path, mode)
+ }
+
+ // Attempt to use the newer faccessat2, which supports flags directly,
+ // falling back if it doesn't exist.
+ //
+ // Don't attempt on Android, which does not allow faccessat2 through
+ // its seccomp policy [1] on any version of Android as of 2022-12-20.
+ //
+ // [1] https://cs.android.com/android/platform/superproject/+/master:bionic/libc/SECCOMP_BLOCKLIST_APP.TXT;l=4;drc=dbb8670dfdcc677f7e3b9262e93800fa14c4e417
+ if runtime.GOOS != "android" {
+ if err := faccessat2(dirfd, path, mode, flags); err != ENOSYS && err != EPERM {
+ return err
+ }
+ }
+
+ // The Linux kernel faccessat system call does not take any flags.
+ // The glibc faccessat implements the flags itself; see
+ // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/faccessat.c;hb=HEAD
+ // Because people naturally expect syscall.Faccessat to act
+ // like C faccessat, we do the same.
+
+ if flags & ^(_AT_SYMLINK_NOFOLLOW|_AT_EACCESS) != 0 {
+ return EINVAL
+ }
+
+ var st Stat_t
+ if err := fstatat(dirfd, path, &st, flags&_AT_SYMLINK_NOFOLLOW); err != nil {
+ return err
+ }
+
+ mode &= 7
+ if mode == 0 {
+ return nil
+ }
+
+ // Fallback to checking permission bits.
+ var uid int
+ if flags&_AT_EACCESS != 0 {
+ uid = Geteuid()
+ if uid != 0 && isCapDacOverrideSet() {
+ // If CAP_DAC_OVERRIDE is set, file access check is
+ // done by the kernel in the same way as for root
+ // (see generic_permission() in the Linux sources).
+ uid = 0
+ }
+ } else {
+ uid = Getuid()
+ }
+
+ if uid == 0 {
+ if mode&1 == 0 {
+ // Root can read and write any file.
+ return nil
+ }
+ if st.Mode&0111 != 0 {
+ // Root can execute any file that anybody can execute.
+ return nil
+ }
+ return EACCES
+ }
+
+ var fmode uint32
+ if uint32(uid) == st.Uid {
+ fmode = (st.Mode >> 6) & 7
+ } else {
+ var gid int
+ if flags&_AT_EACCESS != 0 {
+ gid = Getegid()
+ } else {
+ gid = Getgid()
+ }
+
+ if uint32(gid) == st.Gid || isGroupMember(int(st.Gid)) {
+ fmode = (st.Mode >> 3) & 7
+ } else {
+ fmode = st.Mode & 7
+ }
+ }
+
+ if fmode&mode == mode {
+ return nil
+ }
+
+ return EACCES
+}
+
+//sys fchmodat(dirfd int, path string, mode uint32) (err error)
+
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+ // Linux fchmodat doesn't support the flags parameter. Mimic glibc's behavior
+ // and check the flags. Otherwise the mode would be applied to the symlink
+ // destination which is not what the user expects.
+ if flags&^_AT_SYMLINK_NOFOLLOW != 0 {
+ return EINVAL
+ } else if flags&_AT_SYMLINK_NOFOLLOW != 0 {
+ return EOPNOTSUPP
+ }
+ return fchmodat(dirfd, path, mode)
+}
+
+//sys linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error)
+
+func Link(oldpath string, newpath string) (err error) {
+ return linkat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath, 0)
+}
+
+func Mkdir(path string, mode uint32) (err error) {
+ return Mkdirat(_AT_FDCWD, path, mode)
+}
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+ return Mknodat(_AT_FDCWD, path, mode, dev)
+}
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+ return openat(_AT_FDCWD, path, mode|O_LARGEFILE, perm)
+}
+
+//sys openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
+
+func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+ return openat(dirfd, path, flags|O_LARGEFILE, mode)
+}
+
+func Pipe(p []int) error {
+ return Pipe2(p, 0)
+}
+
+//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+
+func Pipe2(p []int, flags int) error {
+ if len(p) != 2 {
+ return EINVAL
+ }
+ var pp [2]_C_int
+ err := pipe2(&pp, flags)
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
+ return err
+}
+
+//sys readlinkat(dirfd int, path string, buf []byte) (n int, err error)
+
+func Readlink(path string, buf []byte) (n int, err error) {
+ return readlinkat(_AT_FDCWD, path, buf)
+}
+
+func Rename(oldpath string, newpath string) (err error) {
+ return Renameat(_AT_FDCWD, oldpath, _AT_FDCWD, newpath)
+}
+
+func Rmdir(path string) error {
+ return unlinkat(_AT_FDCWD, path, _AT_REMOVEDIR)
+}
+
+//sys symlinkat(oldpath string, newdirfd int, newpath string) (err error)
+
+func Symlink(oldpath string, newpath string) (err error) {
+ return symlinkat(oldpath, _AT_FDCWD, newpath)
+}
+
+func Unlink(path string) error {
+ return unlinkat(_AT_FDCWD, path, 0)
+}
+
+//sys unlinkat(dirfd int, path string, flags int) (err error)
+
+func Unlinkat(dirfd int, path string) error {
+ return unlinkat(dirfd, path, 0)
+}
+
+func Utimes(path string, tv []Timeval) (err error) {
+ if len(tv) != 2 {
+ return EINVAL
+ }
+ return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+}
+
+//sys utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error)
+
+func UtimesNano(path string, ts []Timespec) (err error) {
+ if len(ts) != 2 {
+ return EINVAL
+ }
+ return utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])), 0)
+}
+
+func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
+ if len(tv) != 2 {
+ return EINVAL
+ }
+ return futimesat(dirfd, path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+}
+
+func Futimes(fd int, tv []Timeval) (err error) {
+ // Believe it or not, this is the best we can do on Linux
+ // (and is what glibc does).
+ return Utimes("/proc/self/fd/"+itoa.Itoa(fd), tv)
+}
+
+const ImplementsGetwd = true
+
+//sys Getcwd(buf []byte) (n int, err error)
+
+func Getwd() (wd string, err error) {
+ var buf [PathMax]byte
+ n, err := Getcwd(buf[0:])
+ if err != nil {
+ return "", err
+ }
+ // Getcwd returns the number of bytes written to buf, including the NUL.
+ if n < 1 || n > len(buf) || buf[n-1] != 0 {
+ return "", EINVAL
+ }
+ // In some cases, Linux can return a path that starts with the
+ // "(unreachable)" prefix, which can potentially be a valid relative
+ // path. To work around that, return ENOENT if path is not absolute.
+ if buf[0] != '/' {
+ return "", ENOENT
+ }
+
+ return string(buf[0 : n-1]), nil
+}
+
+func Getgroups() (gids []int, err error) {
+ n, err := getgroups(0, nil)
+ if err != nil {
+ return nil, err
+ }
+ if n == 0 {
+ return nil, nil
+ }
+
+ // Sanity check group count. Max is 1<<16 on Linux.
+ if n < 0 || n > 1<<20 {
+ return nil, EINVAL
+ }
+
+ a := make([]_Gid_t, n)
+ n, err = getgroups(n, &a[0])
+ if err != nil {
+ return nil, err
+ }
+ gids = make([]int, n)
+ for i, v := range a[0:n] {
+ gids[i] = int(v)
+ }
+ return
+}
+
+var cgo_libc_setgroups unsafe.Pointer // non-nil if cgo linked.
+
+func Setgroups(gids []int) (err error) {
+ n := uintptr(len(gids))
+ if n == 0 {
+ if cgo_libc_setgroups == nil {
+ if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, 0, 0, 0); e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+ }
+ if ret := cgocaller(cgo_libc_setgroups, 0, 0); ret != 0 {
+ err = errnoErr(Errno(ret))
+ }
+ return
+ }
+
+ a := make([]_Gid_t, len(gids))
+ for i, v := range gids {
+ a[i] = _Gid_t(v)
+ }
+ if cgo_libc_setgroups == nil {
+ if _, _, e1 := AllThreadsSyscall(_SYS_setgroups, n, uintptr(unsafe.Pointer(&a[0])), 0); e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+ }
+ if ret := cgocaller(cgo_libc_setgroups, n, uintptr(unsafe.Pointer(&a[0]))); ret != 0 {
+ err = errnoErr(Errno(ret))
+ }
+ return
+}
+
+type WaitStatus uint32
+
+// Wait status is 7 bits at bottom, either 0 (exited),
+// 0x7F (stopped), or a signal number that caused an exit.
+// The 0x80 bit is whether there was a core dump.
+// An extra number (exit code, signal causing a stop)
+// is in the high bits. At least that's the idea.
+// There are various irregularities. For example, the
+// "continued" status is 0xFFFF, distinguishing itself
+// from stopped via the core dump bit.
+
+const (
+ mask = 0x7F
+ core = 0x80
+ exited = 0x00
+ stopped = 0x7F
+ shift = 8
+)
+
+func (w WaitStatus) Exited() bool { return w&mask == exited }
+
+func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
+
+func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
+
+func (w WaitStatus) Continued() bool { return w == 0xFFFF }
+
+func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
+
+func (w WaitStatus) ExitStatus() int {
+ if !w.Exited() {
+ return -1
+ }
+ return int(w>>shift) & 0xFF
+}
+
+func (w WaitStatus) Signal() Signal {
+ if !w.Signaled() {
+ return -1
+ }
+ return Signal(w & mask)
+}
+
+func (w WaitStatus) StopSignal() Signal {
+ if !w.Stopped() {
+ return -1
+ }
+ return Signal(w>>shift) & 0xFF
+}
+
+func (w WaitStatus) TrapCause() int {
+ if w.StopSignal() != SIGTRAP {
+ return -1
+ }
+ return int(w>>shift) >> 8
+}
+
+//sys wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
+
+func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
+ var status _C_int
+ wpid, err = wait4(pid, &status, options, rusage)
+ if wstatus != nil {
+ *wstatus = WaitStatus(status)
+ }
+ return
+}
+
+func Mkfifo(path string, mode uint32) (err error) {
+ return Mknod(path, mode|S_IFIFO, 0)
+}
+
+func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ if sa.Port < 0 || sa.Port > 0xFFFF {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Family = AF_INET
+ p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+ p[0] = byte(sa.Port >> 8)
+ p[1] = byte(sa.Port)
+ sa.raw.Addr = sa.Addr
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
+}
+
+func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ if sa.Port < 0 || sa.Port > 0xFFFF {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Family = AF_INET6
+ p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+ p[0] = byte(sa.Port >> 8)
+ p[1] = byte(sa.Port)
+ sa.raw.Scope_id = sa.ZoneId
+ sa.raw.Addr = sa.Addr
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
+}
+
+func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ name := sa.Name
+ n := len(name)
+ if n > len(sa.raw.Path) {
+ return nil, 0, EINVAL
+ }
+ if n == len(sa.raw.Path) && name[0] != '@' {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Family = AF_UNIX
+ for i := 0; i < n; i++ {
+ sa.raw.Path[i] = int8(name[i])
+ }
+ // length is family (uint16), name, NUL.
+ sl := _Socklen(2)
+ if n > 0 {
+ sl += _Socklen(n) + 1
+ }
+ if sa.raw.Path[0] == '@' {
+ sa.raw.Path[0] = 0
+ // Don't count trailing NUL for abstract address.
+ sl--
+ }
+
+ return unsafe.Pointer(&sa.raw), sl, nil
+}
+
+type SockaddrLinklayer struct {
+ Protocol uint16
+ Ifindex int
+ Hatype uint16
+ Pkttype uint8
+ Halen uint8
+ Addr [8]byte
+ raw RawSockaddrLinklayer
+}
+
+func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Family = AF_PACKET
+ sa.raw.Protocol = sa.Protocol
+ sa.raw.Ifindex = int32(sa.Ifindex)
+ sa.raw.Hatype = sa.Hatype
+ sa.raw.Pkttype = sa.Pkttype
+ sa.raw.Halen = sa.Halen
+ sa.raw.Addr = sa.Addr
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
+}
+
+type SockaddrNetlink struct {
+ Family uint16
+ Pad uint16
+ Pid uint32
+ Groups uint32
+ raw RawSockaddrNetlink
+}
+
+func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
+ sa.raw.Family = AF_NETLINK
+ sa.raw.Pad = sa.Pad
+ sa.raw.Pid = sa.Pid
+ sa.raw.Groups = sa.Groups
+ return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
+}
+
+func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
+ switch rsa.Addr.Family {
+ case AF_NETLINK:
+ pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
+ sa := new(SockaddrNetlink)
+ sa.Family = pp.Family
+ sa.Pad = pp.Pad
+ sa.Pid = pp.Pid
+ sa.Groups = pp.Groups
+ return sa, nil
+
+ case AF_PACKET:
+ pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
+ sa := new(SockaddrLinklayer)
+ sa.Protocol = pp.Protocol
+ sa.Ifindex = int(pp.Ifindex)
+ sa.Hatype = pp.Hatype
+ sa.Pkttype = pp.Pkttype
+ sa.Halen = pp.Halen
+ sa.Addr = pp.Addr
+ return sa, nil
+
+ case AF_UNIX:
+ pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
+ sa := new(SockaddrUnix)
+ if pp.Path[0] == 0 {
+ // "Abstract" Unix domain socket.
+ // Rewrite leading NUL as @ for textual display.
+ // (This is the standard convention.)
+ // Not friendly to overwrite in place,
+ // but the callers below don't care.
+ pp.Path[0] = '@'
+ }
+
+ // Assume path ends at NUL.
+ // This is not technically the Linux semantics for
+ // abstract Unix domain sockets--they are supposed
+ // to be uninterpreted fixed-size binary blobs--but
+ // everyone uses this convention.
+ n := 0
+ for n < len(pp.Path) && pp.Path[n] != 0 {
+ n++
+ }
+ sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
+ return sa, nil
+
+ case AF_INET:
+ pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
+ sa := new(SockaddrInet4)
+ p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ sa.Port = int(p[0])<<8 + int(p[1])
+ sa.Addr = pp.Addr
+ return sa, nil
+
+ case AF_INET6:
+ pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
+ sa := new(SockaddrInet6)
+ p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ sa.Port = int(p[0])<<8 + int(p[1])
+ sa.ZoneId = pp.Scope_id
+ sa.Addr = pp.Addr
+ return sa, nil
+ }
+ return nil, EAFNOSUPPORT
+}
+
+func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
+ var rsa RawSockaddrAny
+ var len _Socklen = SizeofSockaddrAny
+ nfd, err = accept4(fd, &rsa, &len, flags)
+ if err != nil {
+ return
+ }
+ if len > SizeofSockaddrAny {
+ panic("RawSockaddrAny too small")
+ }
+ sa, err = anyToSockaddr(&rsa)
+ if err != nil {
+ Close(nfd)
+ nfd = 0
+ }
+ return
+}
+
+func Getsockname(fd int) (sa Sockaddr, err error) {
+ var rsa RawSockaddrAny
+ var len _Socklen = SizeofSockaddrAny
+ if err = getsockname(fd, &rsa, &len); err != nil {
+ return
+ }
+ return anyToSockaddr(&rsa)
+}
+
+func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
+ vallen := _Socklen(4)
+ err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
+ return value, err
+}
+
+func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
+ var value IPMreq
+ vallen := _Socklen(SizeofIPMreq)
+ err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+ return &value, err
+}
+
+func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
+ var value IPMreqn
+ vallen := _Socklen(SizeofIPMreqn)
+ err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+ return &value, err
+}
+
+func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
+ var value IPv6Mreq
+ vallen := _Socklen(SizeofIPv6Mreq)
+ err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+ return &value, err
+}
+
+func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
+ var value IPv6MTUInfo
+ vallen := _Socklen(SizeofIPv6MTUInfo)
+ err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+ return &value, err
+}
+
+func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
+ var value ICMPv6Filter
+ vallen := _Socklen(SizeofICMPv6Filter)
+ err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+ return &value, err
+}
+
+func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
+ var value Ucred
+ vallen := _Socklen(SizeofUcred)
+ err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+ return &value, err
+}
+
+func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
+ return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
+}
+
+func recvmsgRaw(fd int, p, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) {
+ var msg Msghdr
+ msg.Name = (*byte)(unsafe.Pointer(rsa))
+ msg.Namelen = uint32(SizeofSockaddrAny)
+ var iov Iovec
+ if len(p) > 0 {
+ iov.Base = &p[0]
+ iov.SetLen(len(p))
+ }
+ var dummy byte
+ if len(oob) > 0 {
+ if len(p) == 0 {
+ var sockType int
+ sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
+ if err != nil {
+ return
+ }
+ // receive at least one normal byte
+ if sockType != SOCK_DGRAM {
+ iov.Base = &dummy
+ iov.SetLen(1)
+ }
+ }
+ msg.Control = &oob[0]
+ msg.SetControllen(len(oob))
+ }
+ msg.Iov = &iov
+ msg.Iovlen = 1
+ if n, err = recvmsg(fd, &msg, flags); err != nil {
+ return
+ }
+ oobn = int(msg.Controllen)
+ recvflags = int(msg.Flags)
+ return
+}
+
+func sendmsgN(fd int, p, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) {
+ var msg Msghdr
+ msg.Name = (*byte)(ptr)
+ msg.Namelen = uint32(salen)
+ var iov Iovec
+ if len(p) > 0 {
+ iov.Base = &p[0]
+ iov.SetLen(len(p))
+ }
+ var dummy byte
+ if len(oob) > 0 {
+ if len(p) == 0 {
+ var sockType int
+ sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE)
+ if err != nil {
+ return 0, err
+ }
+ // send at least one normal byte
+ if sockType != SOCK_DGRAM {
+ iov.Base = &dummy
+ iov.SetLen(1)
+ }
+ }
+ msg.Control = &oob[0]
+ msg.SetControllen(len(oob))
+ }
+ msg.Iov = &iov
+ msg.Iovlen = 1
+ if n, err = sendmsg(fd, &msg, flags); err != nil {
+ return 0, err
+ }
+ if len(oob) > 0 && len(p) == 0 {
+ n = 0
+ }
+ return n, nil
+}
+
+// BindToDevice binds the socket associated with fd to device.
+func BindToDevice(fd int, device string) (err error) {
+ return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
+}
+
+//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
+//sys ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) = SYS_PTRACE
+
+func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
+ // The peek requests are machine-size oriented, so we wrap it
+ // to retrieve arbitrary-length data.
+
+ // The ptrace syscall differs from glibc's ptrace.
+ // Peeks returns the word in *data, not as the return value.
+
+ var buf [sizeofPtr]byte
+
+ // Leading edge. PEEKTEXT/PEEKDATA don't require aligned
+ // access (PEEKUSER warns that it might), but if we don't
+ // align our reads, we might straddle an unmapped page
+ // boundary and not get the bytes leading up to the page
+ // boundary.
+ n := 0
+ if addr%sizeofPtr != 0 {
+ err = ptracePtr(req, pid, addr-addr%sizeofPtr, unsafe.Pointer(&buf[0]))
+ if err != nil {
+ return 0, err
+ }
+ n += copy(out, buf[addr%sizeofPtr:])
+ out = out[n:]
+ }
+
+ // Remainder.
+ for len(out) > 0 {
+ // We use an internal buffer to guarantee alignment.
+ // It's not documented if this is necessary, but we're paranoid.
+ err = ptracePtr(req, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
+ if err != nil {
+ return n, err
+ }
+ copied := copy(out, buf[0:])
+ n += copied
+ out = out[copied:]
+ }
+
+ return n, nil
+}
+
+func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
+ return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
+}
+
+func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
+ return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
+}
+
+func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
+ // As for ptracePeek, we need to align our accesses to deal
+ // with the possibility of straddling an invalid page.
+
+ // Leading edge.
+ n := 0
+ if addr%sizeofPtr != 0 {
+ var buf [sizeofPtr]byte
+ err = ptracePtr(peekReq, pid, addr-addr%sizeofPtr, unsafe.Pointer(&buf[0]))
+ if err != nil {
+ return 0, err
+ }
+ n += copy(buf[addr%sizeofPtr:], data)
+ word := *((*uintptr)(unsafe.Pointer(&buf[0])))
+ err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
+ if err != nil {
+ return 0, err
+ }
+ data = data[n:]
+ }
+
+ // Interior.
+ for len(data) > sizeofPtr {
+ word := *((*uintptr)(unsafe.Pointer(&data[0])))
+ err = ptrace(pokeReq, pid, addr+uintptr(n), word)
+ if err != nil {
+ return n, err
+ }
+ n += sizeofPtr
+ data = data[sizeofPtr:]
+ }
+
+ // Trailing edge.
+ if len(data) > 0 {
+ var buf [sizeofPtr]byte
+ err = ptracePtr(peekReq, pid, addr+uintptr(n), unsafe.Pointer(&buf[0]))
+ if err != nil {
+ return n, err
+ }
+ copy(buf[0:], data)
+ word := *((*uintptr)(unsafe.Pointer(&buf[0])))
+ err = ptrace(pokeReq, pid, addr+uintptr(n), word)
+ if err != nil {
+ return n, err
+ }
+ n += len(data)
+ }
+
+ return n, nil
+}
+
+func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
+ return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
+}
+
+func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
+ return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
+}
+
+const (
+ _NT_PRSTATUS = 1
+)
+
+func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
+ var iov Iovec
+ iov.Base = (*byte)(unsafe.Pointer(regsout))
+ iov.SetLen(int(unsafe.Sizeof(*regsout)))
+ return ptracePtr(PTRACE_GETREGSET, pid, uintptr(_NT_PRSTATUS), unsafe.Pointer(&iov))
+}
+
+func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
+ var iov Iovec
+ iov.Base = (*byte)(unsafe.Pointer(regs))
+ iov.SetLen(int(unsafe.Sizeof(*regs)))
+ return ptracePtr(PTRACE_SETREGSET, pid, uintptr(_NT_PRSTATUS), unsafe.Pointer(&iov))
+}
+
+func PtraceSetOptions(pid int, options int) (err error) {
+ return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
+}
+
+func PtraceGetEventMsg(pid int) (msg uint, err error) {
+ var data _C_long
+ err = ptracePtr(PTRACE_GETEVENTMSG, pid, 0, unsafe.Pointer(&data))
+ msg = uint(data)
+ return
+}
+
+func PtraceCont(pid int, signal int) (err error) {
+ return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
+}
+
+func PtraceSyscall(pid int, signal int) (err error) {
+ return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
+}
+
+func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
+
+func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
+
+func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
+
+//sys reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
+
+func Reboot(cmd int) (err error) {
+ return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
+}
+
+func ReadDirent(fd int, buf []byte) (n int, err error) {
+ return Getdents(fd, buf)
+}
+
+func direntIno(buf []byte) (uint64, bool) {
+ return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
+}
+
+func direntReclen(buf []byte) (uint64, bool) {
+ return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
+}
+
+func direntNamlen(buf []byte) (uint64, bool) {
+ reclen, ok := direntReclen(buf)
+ if !ok {
+ return 0, false
+ }
+ return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
+}
+
+//sys mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
+
+func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
+ // Certain file systems get rather angry and EINVAL if you give
+ // them an empty string of data, rather than NULL.
+ if data == "" {
+ return mount(source, target, fstype, flags, nil)
+ }
+ datap, err := BytePtrFromString(data)
+ if err != nil {
+ return err
+ }
+ return mount(source, target, fstype, flags, datap)
+}
+
+// Sendto
+// Recvfrom
+// Socketpair
+
+/*
+ * Direct access
+ */
+//sys Acct(path string) (err error)
+//sys Adjtimex(buf *Timex) (state int, err error)
+//sys Chdir(path string) (err error)
+//sys Chroot(path string) (err error)
+//sys Close(fd int) (err error)
+//sys Dup(oldfd int) (fd int, err error)
+//sys Dup3(oldfd int, newfd int, flags int) (err error)
+//sysnb EpollCreate1(flag int) (fd int, err error)
+//sysnb EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
+//sys Fallocate(fd int, mode uint32, off int64, len int64) (err error)
+//sys Fchdir(fd int) (err error)
+//sys Fchmod(fd int, mode uint32) (err error)
+//sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
+//sys fcntl(fd int, cmd int, arg int) (val int, err error)
+//sys Fdatasync(fd int) (err error)
+//sys Flock(fd int, how int) (err error)
+//sys Fsync(fd int) (err error)
+//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
+//sysnb Getpgid(pid int) (pgid int, err error)
+
+func Getpgrp() (pid int) {
+ pid, _ = Getpgid(0)
+ return
+}
+
+//sysnb Getpid() (pid int)
+//sysnb Getppid() (ppid int)
+//sys Getpriority(which int, who int) (prio int, err error)
+//sysnb Getrusage(who int, rusage *Rusage) (err error)
+//sysnb Gettid() (tid int)
+//sys Getxattr(path string, attr string, dest []byte) (sz int, err error)
+//sys InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
+//sysnb InotifyInit1(flags int) (fd int, err error)
+//sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
+//sysnb Kill(pid int, sig Signal) (err error)
+//sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
+//sys Listxattr(path string, dest []byte) (sz int, err error)
+//sys Mkdirat(dirfd int, path string, mode uint32) (err error)
+//sys Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
+//sys Nanosleep(time *Timespec, leftover *Timespec) (err error)
+//sys PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
+//sysnb prlimit1(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) = SYS_PRLIMIT64
+//sys read(fd int, p []byte) (n int, err error)
+//sys Removexattr(path string, attr string) (err error)
+//sys Setdomainname(p []byte) (err error)
+//sys Sethostname(p []byte) (err error)
+//sysnb Setpgid(pid int, pgid int) (err error)
+//sysnb Setsid() (pid int, err error)
+//sysnb Settimeofday(tv *Timeval) (err error)
+
+// Provided by runtime.syscall_runtime_doAllThreadsSyscall which stops the
+// world and invokes the syscall on each OS thread. Once this function returns,
+// all threads are in sync.
+//
+//go:uintptrescapes
+func runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
+
+// AllThreadsSyscall performs a syscall on each OS thread of the Go
+// runtime. It first invokes the syscall on one thread. Should that
+// invocation fail, it returns immediately with the error status.
+// Otherwise, it invokes the syscall on all of the remaining threads
+// in parallel. It will terminate the program if it observes any
+// invoked syscall's return value differs from that of the first
+// invocation.
+//
+// AllThreadsSyscall is intended for emulating simultaneous
+// process-wide state changes that require consistently modifying
+// per-thread state of the Go runtime.
+//
+// AllThreadsSyscall is unaware of any threads that are launched
+// explicitly by cgo linked code, so the function always returns
+// ENOTSUP in binaries that use cgo.
+//
+//go:uintptrescapes
+func AllThreadsSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) {
+ if cgo_libc_setegid != nil {
+ return minus1, minus1, ENOTSUP
+ }
+ r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, 0, 0, 0)
+ return r1, r2, Errno(errno)
+}
+
+// AllThreadsSyscall6 is like AllThreadsSyscall, but extended to six
+// arguments.
+//
+//go:uintptrescapes
+func AllThreadsSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno) {
+ if cgo_libc_setegid != nil {
+ return minus1, minus1, ENOTSUP
+ }
+ r1, r2, errno := runtime_doAllThreadsSyscall(trap, a1, a2, a3, a4, a5, a6)
+ return r1, r2, Errno(errno)
+}
+
+// linked by runtime.cgocall.go
+//
+//go:uintptrescapes
+func cgocaller(unsafe.Pointer, ...uintptr) uintptr
+
+var cgo_libc_setegid unsafe.Pointer // non-nil if cgo linked.
+
+const minus1 = ^uintptr(0)
+
+func Setegid(egid int) (err error) {
+ if cgo_libc_setegid == nil {
+ if _, _, e1 := AllThreadsSyscall(SYS_SETRESGID, minus1, uintptr(egid), minus1); e1 != 0 {
+ err = errnoErr(e1)
+ }
+ } else if ret := cgocaller(cgo_libc_setegid, uintptr(egid)); ret != 0 {
+ err = errnoErr(Errno(ret))
+ }
+ return
+}
+
+var cgo_libc_seteuid unsafe.Pointer // non-nil if cgo linked.
+
+func Seteuid(euid int) (err error) {
+ if cgo_libc_seteuid == nil {
+ if _, _, e1 := AllThreadsSyscall(SYS_SETRESUID, minus1, uintptr(euid), minus1); e1 != 0 {
+ err = errnoErr(e1)
+ }
+ } else if ret := cgocaller(cgo_libc_seteuid, uintptr(euid)); ret != 0 {
+ err = errnoErr(Errno(ret))
+ }
+ return
+}
+
+var cgo_libc_setgid unsafe.Pointer // non-nil if cgo linked.
+
+func Setgid(gid int) (err error) {
+ if cgo_libc_setgid == nil {
+ if _, _, e1 := AllThreadsSyscall(sys_SETGID, uintptr(gid), 0, 0); e1 != 0 {
+ err = errnoErr(e1)
+ }
+ } else if ret := cgocaller(cgo_libc_setgid, uintptr(gid)); ret != 0 {
+ err = errnoErr(Errno(ret))
+ }
+ return
+}
+
+var cgo_libc_setregid unsafe.Pointer // non-nil if cgo linked.
+
+func Setregid(rgid, egid int) (err error) {
+ if cgo_libc_setregid == nil {
+ if _, _, e1 := AllThreadsSyscall(sys_SETREGID, uintptr(rgid), uintptr(egid), 0); e1 != 0 {
+ err = errnoErr(e1)
+ }
+ } else if ret := cgocaller(cgo_libc_setregid, uintptr(rgid), uintptr(egid)); ret != 0 {
+ err = errnoErr(Errno(ret))
+ }
+ return
+}
+
+var cgo_libc_setresgid unsafe.Pointer // non-nil if cgo linked.
+
+func Setresgid(rgid, egid, sgid int) (err error) {
+ if cgo_libc_setresgid == nil {
+ if _, _, e1 := AllThreadsSyscall(sys_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid)); e1 != 0 {
+ err = errnoErr(e1)
+ }
+ } else if ret := cgocaller(cgo_libc_setresgid, uintptr(rgid), uintptr(egid), uintptr(sgid)); ret != 0 {
+ err = errnoErr(Errno(ret))
+ }
+ return
+}
+
+var cgo_libc_setresuid unsafe.Pointer // non-nil if cgo linked.
+
+func Setresuid(ruid, euid, suid int) (err error) {
+ if cgo_libc_setresuid == nil {
+ if _, _, e1 := AllThreadsSyscall(sys_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid)); e1 != 0 {
+ err = errnoErr(e1)
+ }
+ } else if ret := cgocaller(cgo_libc_setresuid, uintptr(ruid), uintptr(euid), uintptr(suid)); ret != 0 {
+ err = errnoErr(Errno(ret))
+ }
+ return
+}
+
+var cgo_libc_setreuid unsafe.Pointer // non-nil if cgo linked.
+
+func Setreuid(ruid, euid int) (err error) {
+ if cgo_libc_setreuid == nil {
+ if _, _, e1 := AllThreadsSyscall(sys_SETREUID, uintptr(ruid), uintptr(euid), 0); e1 != 0 {
+ err = errnoErr(e1)
+ }
+ } else if ret := cgocaller(cgo_libc_setreuid, uintptr(ruid), uintptr(euid)); ret != 0 {
+ err = errnoErr(Errno(ret))
+ }
+ return
+}
+
+var cgo_libc_setuid unsafe.Pointer // non-nil if cgo linked.
+
+func Setuid(uid int) (err error) {
+ if cgo_libc_setuid == nil {
+ if _, _, e1 := AllThreadsSyscall(sys_SETUID, uintptr(uid), 0, 0); e1 != 0 {
+ err = errnoErr(e1)
+ }
+ } else if ret := cgocaller(cgo_libc_setuid, uintptr(uid)); ret != 0 {
+ err = errnoErr(Errno(ret))
+ }
+ return
+}
+
+//sys Setpriority(which int, who int, prio int) (err error)
+//sys Setxattr(path string, attr string, data []byte, flags int) (err error)
+//sys Sync()
+//sysnb Sysinfo(info *Sysinfo_t) (err error)
+//sys Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
+//sysnb Tgkill(tgid int, tid int, sig Signal) (err error)
+//sysnb Times(tms *Tms) (ticks uintptr, err error)
+//sysnb Umask(mask int) (oldmask int)
+//sysnb Uname(buf *Utsname) (err error)
+//sys Unmount(target string, flags int) (err error) = SYS_UMOUNT2
+//sys Unshare(flags int) (err error)
+//sys write(fd int, p []byte) (n int, err error)
+//sys exitThread(code int) (err error) = SYS_EXIT
+//sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
+//sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE
+
+// mmap varies by architecture; see syscall_linux_*.go.
+//sys munmap(addr uintptr, length uintptr) (err error)
+
+var mapper = &mmapper{
+ active: make(map[*byte][]byte),
+ mmap: mmap,
+ munmap: munmap,
+}
+
+func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
+ return mapper.Mmap(fd, offset, length, prot, flags)
+}
+
+func Munmap(b []byte) (err error) {
+ return mapper.Munmap(b)
+}
+
+//sys Madvise(b []byte, advice int) (err error)
+//sys Mprotect(b []byte, prot int) (err error)
+//sys Mlock(b []byte) (err error)
+//sys Munlock(b []byte) (err error)
+//sys Mlockall(flags int) (err error)
+//sys Munlockall() (err error)
+
+// prlimit changes a resource limit. We use a single definition so that
+// we can tell StartProcess to not restore the original NOFILE limit.
+// This is unexported but can be called from x/sys/unix.
+func prlimit(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
+ err = prlimit1(pid, resource, newlimit, old)
+ if err == nil && newlimit != nil && resource == RLIMIT_NOFILE {
+ origRlimitNofile.Store(Rlimit{0, 0})
+ }
+ return err
+}
diff --git a/contrib/go/_std_1.20/src/syscall/syscall_linux_accept4.go b/contrib/go/_std_1.21/src/syscall/syscall_linux_accept4.go
index 74898672c0..74898672c0 100644
--- a/contrib/go/_std_1.20/src/syscall/syscall_linux_accept4.go
+++ b/contrib/go/_std_1.21/src/syscall/syscall_linux_accept4.go
diff --git a/contrib/go/_std_1.20/src/syscall/syscall_linux_amd64.go b/contrib/go/_std_1.21/src/syscall/syscall_linux_amd64.go
index aa85a523b2..aa85a523b2 100644
--- a/contrib/go/_std_1.20/src/syscall/syscall_linux_amd64.go
+++ b/contrib/go/_std_1.21/src/syscall/syscall_linux_amd64.go
diff --git a/contrib/go/_std_1.20/src/syscall/syscall_linux_arm64.go b/contrib/go/_std_1.21/src/syscall/syscall_linux_arm64.go
index 42984ba2ed..42984ba2ed 100644
--- a/contrib/go/_std_1.20/src/syscall/syscall_linux_arm64.go
+++ b/contrib/go/_std_1.21/src/syscall/syscall_linux_arm64.go
diff --git a/contrib/go/_std_1.21/src/syscall/syscall_unix.go b/contrib/go/_std_1.21/src/syscall/syscall_unix.go
new file mode 100644
index 0000000000..4c48f29744
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/syscall_unix.go
@@ -0,0 +1,522 @@
+// Copyright 2009 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.
+
+//go:build unix
+
+package syscall
+
+import (
+ errorspkg "errors"
+ "internal/bytealg"
+ "internal/itoa"
+ "internal/oserror"
+ "internal/race"
+ "runtime"
+ "sync"
+ "unsafe"
+)
+
+var (
+ Stdin = 0
+ Stdout = 1
+ Stderr = 2
+)
+
+const (
+ darwin64Bit = (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && sizeofPtr == 8
+ netbsd32Bit = runtime.GOOS == "netbsd" && sizeofPtr == 4
+)
+
+// clen returns the index of the first NULL byte in n or len(n) if n contains no NULL byte.
+func clen(n []byte) int {
+ if i := bytealg.IndexByte(n, 0); i != -1 {
+ return i
+ }
+ return len(n)
+}
+
+// Mmap manager, for use by operating system-specific implementations.
+
+type mmapper struct {
+ sync.Mutex
+ active map[*byte][]byte // active mappings; key is last byte in mapping
+ mmap func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
+ munmap func(addr uintptr, length uintptr) error
+}
+
+func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
+ if length <= 0 {
+ return nil, EINVAL
+ }
+
+ // Map the requested memory.
+ addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
+ if errno != nil {
+ return nil, errno
+ }
+
+ // Use unsafe to turn addr into a []byte.
+ b := unsafe.Slice((*byte)(unsafe.Pointer(addr)), length)
+
+ // Register mapping in m and return it.
+ p := &b[cap(b)-1]
+ m.Lock()
+ defer m.Unlock()
+ m.active[p] = b
+ return b, nil
+}
+
+func (m *mmapper) Munmap(data []byte) (err error) {
+ if len(data) == 0 || len(data) != cap(data) {
+ return EINVAL
+ }
+
+ // Find the base of the mapping.
+ p := &data[cap(data)-1]
+ m.Lock()
+ defer m.Unlock()
+ b := m.active[p]
+ if b == nil || &b[0] != &data[0] {
+ return EINVAL
+ }
+
+ // Unmap the memory and update m.
+ if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
+ return errno
+ }
+ delete(m.active, p)
+ return nil
+}
+
+// An Errno is an unsigned number describing an error condition.
+// It implements the error interface. The zero Errno is by convention
+// a non-error, so code to convert from Errno to error should use:
+//
+// err = nil
+// if errno != 0 {
+// err = errno
+// }
+//
+// Errno values can be tested against error values using errors.Is.
+// For example:
+//
+// _, _, err := syscall.Syscall(...)
+// if errors.Is(err, fs.ErrNotExist) ...
+type Errno uintptr
+
+func (e Errno) Error() string {
+ if 0 <= int(e) && int(e) < len(errors) {
+ s := errors[e]
+ if s != "" {
+ return s
+ }
+ }
+ return "errno " + itoa.Itoa(int(e))
+}
+
+func (e Errno) Is(target error) bool {
+ switch target {
+ case oserror.ErrPermission:
+ return e == EACCES || e == EPERM
+ case oserror.ErrExist:
+ return e == EEXIST || e == ENOTEMPTY
+ case oserror.ErrNotExist:
+ return e == ENOENT
+ case errorspkg.ErrUnsupported:
+ return e == ENOSYS || e == ENOTSUP || e == EOPNOTSUPP
+ }
+ return false
+}
+
+func (e Errno) Temporary() bool {
+ return e == EINTR || e == EMFILE || e == ENFILE || e.Timeout()
+}
+
+func (e Errno) Timeout() bool {
+ return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
+}
+
+// Do the interface allocations only once for common
+// Errno values.
+var (
+ errEAGAIN error = EAGAIN
+ errEINVAL error = EINVAL
+ errENOENT error = ENOENT
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e Errno) error {
+ switch e {
+ case 0:
+ return nil
+ case EAGAIN:
+ return errEAGAIN
+ case EINVAL:
+ return errEINVAL
+ case ENOENT:
+ return errENOENT
+ }
+ return e
+}
+
+// A Signal is a number describing a process signal.
+// It implements the os.Signal interface.
+type Signal int
+
+func (s Signal) Signal() {}
+
+func (s Signal) String() string {
+ if 0 <= s && int(s) < len(signals) {
+ str := signals[s]
+ if str != "" {
+ return str
+ }
+ }
+ return "signal " + itoa.Itoa(int(s))
+}
+
+func Read(fd int, p []byte) (n int, err error) {
+ n, err = read(fd, p)
+ if race.Enabled {
+ if n > 0 {
+ race.WriteRange(unsafe.Pointer(&p[0]), n)
+ }
+ if err == nil {
+ race.Acquire(unsafe.Pointer(&ioSync))
+ }
+ }
+ if msanenabled && n > 0 {
+ msanWrite(unsafe.Pointer(&p[0]), n)
+ }
+ if asanenabled && n > 0 {
+ asanWrite(unsafe.Pointer(&p[0]), n)
+ }
+ return
+}
+
+func Write(fd int, p []byte) (n int, err error) {
+ if race.Enabled {
+ race.ReleaseMerge(unsafe.Pointer(&ioSync))
+ }
+ if faketime && (fd == 1 || fd == 2) {
+ n = faketimeWrite(fd, p)
+ if n < 0 {
+ n, err = 0, errnoErr(Errno(-n))
+ }
+ } else {
+ n, err = write(fd, p)
+ }
+ if race.Enabled && n > 0 {
+ race.ReadRange(unsafe.Pointer(&p[0]), n)
+ }
+ if msanenabled && n > 0 {
+ msanRead(unsafe.Pointer(&p[0]), n)
+ }
+ if asanenabled && n > 0 {
+ asanRead(unsafe.Pointer(&p[0]), n)
+ }
+ return
+}
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+ n, err = pread(fd, p, offset)
+ if race.Enabled {
+ if n > 0 {
+ race.WriteRange(unsafe.Pointer(&p[0]), n)
+ }
+ if err == nil {
+ race.Acquire(unsafe.Pointer(&ioSync))
+ }
+ }
+ if msanenabled && n > 0 {
+ msanWrite(unsafe.Pointer(&p[0]), n)
+ }
+ if asanenabled && n > 0 {
+ asanWrite(unsafe.Pointer(&p[0]), n)
+ }
+ return
+}
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+ if race.Enabled {
+ race.ReleaseMerge(unsafe.Pointer(&ioSync))
+ }
+ n, err = pwrite(fd, p, offset)
+ if race.Enabled && n > 0 {
+ race.ReadRange(unsafe.Pointer(&p[0]), n)
+ }
+ if msanenabled && n > 0 {
+ msanRead(unsafe.Pointer(&p[0]), n)
+ }
+ if asanenabled && n > 0 {
+ asanRead(unsafe.Pointer(&p[0]), n)
+ }
+ return
+}
+
+// For testing: clients can set this flag to force
+// creation of IPv6 sockets to return EAFNOSUPPORT.
+var SocketDisableIPv6 bool
+
+type Sockaddr interface {
+ sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
+}
+
+type SockaddrInet4 struct {
+ Port int
+ Addr [4]byte
+ raw RawSockaddrInet4
+}
+
+type SockaddrInet6 struct {
+ Port int
+ ZoneId uint32
+ Addr [16]byte
+ raw RawSockaddrInet6
+}
+
+type SockaddrUnix struct {
+ Name string
+ raw RawSockaddrUnix
+}
+
+func Bind(fd int, sa Sockaddr) (err error) {
+ ptr, n, err := sa.sockaddr()
+ if err != nil {
+ return err
+ }
+ return bind(fd, ptr, n)
+}
+
+func Connect(fd int, sa Sockaddr) (err error) {
+ ptr, n, err := sa.sockaddr()
+ if err != nil {
+ return err
+ }
+ return connect(fd, ptr, n)
+}
+
+func Getpeername(fd int) (sa Sockaddr, err error) {
+ var rsa RawSockaddrAny
+ var len _Socklen = SizeofSockaddrAny
+ if err = getpeername(fd, &rsa, &len); err != nil {
+ return
+ }
+ return anyToSockaddr(&rsa)
+}
+
+func GetsockoptInt(fd, level, opt int) (value int, err error) {
+ var n int32
+ vallen := _Socklen(4)
+ err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
+ return int(n), err
+}
+
+func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
+ var rsa RawSockaddrAny
+ var len _Socklen = SizeofSockaddrAny
+ if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
+ return
+ }
+ if rsa.Addr.Family != AF_UNSPEC {
+ from, err = anyToSockaddr(&rsa)
+ }
+ return
+}
+
+func recvfromInet4(fd int, p []byte, flags int, from *SockaddrInet4) (n int, err error) {
+ var rsa RawSockaddrAny
+ var socklen _Socklen = SizeofSockaddrAny
+ if n, err = recvfrom(fd, p, flags, &rsa, &socklen); err != nil {
+ return
+ }
+ pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
+ port := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ from.Port = int(port[0])<<8 + int(port[1])
+ from.Addr = pp.Addr
+ return
+}
+
+func recvfromInet6(fd int, p []byte, flags int, from *SockaddrInet6) (n int, err error) {
+ var rsa RawSockaddrAny
+ var socklen _Socklen = SizeofSockaddrAny
+ if n, err = recvfrom(fd, p, flags, &rsa, &socklen); err != nil {
+ return
+ }
+ pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa))
+ port := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ from.Port = int(port[0])<<8 + int(port[1])
+ from.ZoneId = pp.Scope_id
+ from.Addr = pp.Addr
+ return
+}
+
+func recvmsgInet4(fd int, p, oob []byte, flags int, from *SockaddrInet4) (n, oobn int, recvflags int, err error) {
+ var rsa RawSockaddrAny
+ n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
+ if err != nil {
+ return
+ }
+ pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
+ port := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ from.Port = int(port[0])<<8 + int(port[1])
+ from.Addr = pp.Addr
+ return
+}
+
+func recvmsgInet6(fd int, p, oob []byte, flags int, from *SockaddrInet6) (n, oobn int, recvflags int, err error) {
+ var rsa RawSockaddrAny
+ n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
+ if err != nil {
+ return
+ }
+ pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa))
+ port := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ from.Port = int(port[0])<<8 + int(port[1])
+ from.ZoneId = pp.Scope_id
+ from.Addr = pp.Addr
+ return
+}
+
+func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
+ var rsa RawSockaddrAny
+ n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
+ // source address is only specified if the socket is unconnected
+ if rsa.Addr.Family != AF_UNSPEC {
+ from, err = anyToSockaddr(&rsa)
+ }
+ return
+}
+
+func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
+ _, err = SendmsgN(fd, p, oob, to, flags)
+ return
+}
+
+func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
+ var ptr unsafe.Pointer
+ var salen _Socklen
+ if to != nil {
+ ptr, salen, err = to.sockaddr()
+ if err != nil {
+ return 0, err
+ }
+ }
+ return sendmsgN(fd, p, oob, ptr, salen, flags)
+}
+
+func sendmsgNInet4(fd int, p, oob []byte, to *SockaddrInet4, flags int) (n int, err error) {
+ ptr, salen, err := to.sockaddr()
+ if err != nil {
+ return 0, err
+ }
+ return sendmsgN(fd, p, oob, ptr, salen, flags)
+}
+
+func sendmsgNInet6(fd int, p, oob []byte, to *SockaddrInet6, flags int) (n int, err error) {
+ ptr, salen, err := to.sockaddr()
+ if err != nil {
+ return 0, err
+ }
+ return sendmsgN(fd, p, oob, ptr, salen, flags)
+}
+
+func sendtoInet4(fd int, p []byte, flags int, to *SockaddrInet4) (err error) {
+ ptr, n, err := to.sockaddr()
+ if err != nil {
+ return err
+ }
+ return sendto(fd, p, flags, ptr, n)
+}
+
+func sendtoInet6(fd int, p []byte, flags int, to *SockaddrInet6) (err error) {
+ ptr, n, err := to.sockaddr()
+ if err != nil {
+ return err
+ }
+ return sendto(fd, p, flags, ptr, n)
+}
+
+func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
+ var (
+ ptr unsafe.Pointer
+ salen _Socklen
+ )
+ if to != nil {
+ ptr, salen, err = to.sockaddr()
+ if err != nil {
+ return err
+ }
+ }
+ return sendto(fd, p, flags, ptr, salen)
+}
+
+func SetsockoptByte(fd, level, opt int, value byte) (err error) {
+ return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
+}
+
+func SetsockoptInt(fd, level, opt int, value int) (err error) {
+ var n = int32(value)
+ return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
+}
+
+func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
+ return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
+}
+
+func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
+ return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
+}
+
+func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
+ return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
+}
+
+func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
+ return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
+}
+
+func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
+ return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
+}
+
+func SetsockoptString(fd, level, opt int, s string) (err error) {
+ var p unsafe.Pointer
+ if len(s) > 0 {
+ p = unsafe.Pointer(&[]byte(s)[0])
+ }
+ return setsockopt(fd, level, opt, p, uintptr(len(s)))
+}
+
+func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
+ return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
+}
+
+func Socket(domain, typ, proto int) (fd int, err error) {
+ if domain == AF_INET6 && SocketDisableIPv6 {
+ return -1, EAFNOSUPPORT
+ }
+ fd, err = socket(domain, typ, proto)
+ return
+}
+
+func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
+ var fdx [2]int32
+ err = socketpair(domain, typ, proto, &fdx)
+ if err == nil {
+ fd[0] = int(fdx[0])
+ fd[1] = int(fdx[1])
+ }
+ return
+}
+
+func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+ if race.Enabled {
+ race.ReleaseMerge(unsafe.Pointer(&ioSync))
+ }
+ return sendfile(outfd, infd, offset, count)
+}
+
+var ioSync int64
diff --git a/contrib/go/_std_1.21/src/syscall/syscall_windows.go b/contrib/go/_std_1.21/src/syscall/syscall_windows.go
new file mode 100644
index 0000000000..e348905abf
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/syscall_windows.go
@@ -0,0 +1,1439 @@
+// Copyright 2009 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.
+
+// Windows system calls.
+
+package syscall
+
+import (
+ errorspkg "errors"
+ "internal/bytealg"
+ "internal/itoa"
+ "internal/oserror"
+ "internal/race"
+ "runtime"
+ "sync"
+ "unsafe"
+)
+
+type Handle uintptr
+
+const InvalidHandle = ^Handle(0)
+
+// StringToUTF16 returns the UTF-16 encoding of the UTF-8 string s,
+// with a terminating NUL added. If s contains a NUL byte this
+// function panics instead of returning an error.
+//
+// Deprecated: Use UTF16FromString instead.
+func StringToUTF16(s string) []uint16 {
+ a, err := UTF16FromString(s)
+ if err != nil {
+ panic("syscall: string with NUL passed to StringToUTF16")
+ }
+ return a
+}
+
+// UTF16FromString returns the UTF-16 encoding of the UTF-8 string
+// s, with a terminating NUL added. If s contains a NUL byte at any
+// location, it returns (nil, EINVAL). Unpaired surrogates
+// are encoded using WTF-8.
+func UTF16FromString(s string) ([]uint16, error) {
+ if bytealg.IndexByteString(s, 0) != -1 {
+ return nil, EINVAL
+ }
+ // Valid UTF-8 characters between 1 and 3 bytes require one uint16.
+ // Valid UTF-8 characters of 4 bytes require two uint16.
+ // Bytes with invalid UTF-8 encoding require maximum one uint16 per byte.
+ // So the number of UTF-8 code units (len(s)) is always greater or
+ // equal than the number of UTF-16 code units.
+ // Also account for the terminating NUL character.
+ buf := make([]uint16, 0, len(s)+1)
+ buf = encodeWTF16(s, buf)
+ return append(buf, 0), nil
+}
+
+// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s,
+// with a terminating NUL removed. Unpaired surrogates are decoded
+// using WTF-8 instead of UTF-8 encoding.
+func UTF16ToString(s []uint16) string {
+ maxLen := 0
+ for i, v := range s {
+ if v == 0 {
+ s = s[0:i]
+ break
+ }
+ switch {
+ case v <= rune1Max:
+ maxLen += 1
+ case v <= rune2Max:
+ maxLen += 2
+ default:
+ // r is a non-surrogate that decodes to 3 bytes,
+ // or is an unpaired surrogate (also 3 bytes in WTF-8),
+ // or is one half of a valid surrogate pair.
+ // If it is half of a pair, we will add 3 for the second surrogate
+ // (total of 6) and overestimate by 2 bytes for the pair,
+ // since the resulting rune only requires 4 bytes.
+ maxLen += 3
+ }
+ }
+ buf := decodeWTF16(s, make([]byte, 0, maxLen))
+ return unsafe.String(unsafe.SliceData(buf), len(buf))
+}
+
+// utf16PtrToString is like UTF16ToString, but takes *uint16
+// as a parameter instead of []uint16.
+func utf16PtrToString(p *uint16) string {
+ if p == nil {
+ return ""
+ }
+ end := unsafe.Pointer(p)
+ n := 0
+ for *(*uint16)(end) != 0 {
+ end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p))
+ n++
+ }
+ return UTF16ToString(unsafe.Slice(p, n))
+}
+
+// StringToUTF16Ptr returns pointer to the UTF-16 encoding of
+// the UTF-8 string s, with a terminating NUL added. If s
+// contains a NUL byte this function panics instead of
+// returning an error.
+//
+// Deprecated: Use UTF16PtrFromString instead.
+func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] }
+
+// UTF16PtrFromString returns pointer to the UTF-16 encoding of
+// the UTF-8 string s, with a terminating NUL added. If s
+// contains a NUL byte at any location, it returns (nil, EINVAL).
+// Unpaired surrogates are encoded using WTF-8.
+func UTF16PtrFromString(s string) (*uint16, error) {
+ a, err := UTF16FromString(s)
+ if err != nil {
+ return nil, err
+ }
+ return &a[0], nil
+}
+
+// Errno is the Windows error number.
+//
+// Errno values can be tested against error values using errors.Is.
+// For example:
+//
+// _, _, err := syscall.Syscall(...)
+// if errors.Is(err, fs.ErrNotExist) ...
+type Errno uintptr
+
+func langid(pri, sub uint16) uint32 { return uint32(sub)<<10 | uint32(pri) }
+
+// FormatMessage is deprecated (msgsrc should be uintptr, not uint32, but can
+// not be changed due to the Go 1 compatibility guarantee).
+//
+// Deprecated: Use FormatMessage from golang.org/x/sys/windows instead.
+func FormatMessage(flags uint32, msgsrc uint32, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) {
+ return formatMessage(flags, uintptr(msgsrc), msgid, langid, buf, args)
+}
+
+func (e Errno) Error() string {
+ // deal with special go errors
+ idx := int(e - APPLICATION_ERROR)
+ if 0 <= idx && idx < len(errors) {
+ return errors[idx]
+ }
+ // ask windows for the remaining errors
+ var flags uint32 = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_IGNORE_INSERTS
+ b := make([]uint16, 300)
+ n, err := formatMessage(flags, 0, uint32(e), langid(LANG_ENGLISH, SUBLANG_ENGLISH_US), b, nil)
+ if err != nil {
+ n, err = formatMessage(flags, 0, uint32(e), 0, b, nil)
+ if err != nil {
+ return "winapi error #" + itoa.Itoa(int(e))
+ }
+ }
+ // trim terminating \r and \n
+ for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- {
+ }
+ return UTF16ToString(b[:n])
+}
+
+const (
+ _ERROR_NOT_ENOUGH_MEMORY = Errno(8)
+ _ERROR_NOT_SUPPORTED = Errno(50)
+ _ERROR_BAD_NETPATH = Errno(53)
+ _ERROR_CALL_NOT_IMPLEMENTED = Errno(120)
+)
+
+func (e Errno) Is(target error) bool {
+ switch target {
+ case oserror.ErrPermission:
+ return e == ERROR_ACCESS_DENIED ||
+ e == EACCES ||
+ e == EPERM
+ case oserror.ErrExist:
+ return e == ERROR_ALREADY_EXISTS ||
+ e == ERROR_DIR_NOT_EMPTY ||
+ e == ERROR_FILE_EXISTS ||
+ e == EEXIST ||
+ e == ENOTEMPTY
+ case oserror.ErrNotExist:
+ return e == ERROR_FILE_NOT_FOUND ||
+ e == _ERROR_BAD_NETPATH ||
+ e == ERROR_PATH_NOT_FOUND ||
+ e == ENOENT
+ case errorspkg.ErrUnsupported:
+ return e == _ERROR_NOT_SUPPORTED ||
+ e == _ERROR_CALL_NOT_IMPLEMENTED ||
+ e == ENOSYS ||
+ e == ENOTSUP ||
+ e == EOPNOTSUPP ||
+ e == EWINDOWS
+ }
+ return false
+}
+
+func (e Errno) Temporary() bool {
+ return e == EINTR || e == EMFILE || e.Timeout()
+}
+
+func (e Errno) Timeout() bool {
+ return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
+}
+
+// Implemented in runtime/syscall_windows.go.
+func compileCallback(fn any, cleanstack bool) uintptr
+
+// NewCallback converts a Go function to a function pointer conforming to the stdcall calling convention.
+// This is useful when interoperating with Windows code requiring callbacks.
+// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
+// Only a limited number of callbacks may be created in a single Go process, and any memory allocated
+// for these callbacks is never released.
+// Between NewCallback and NewCallbackCDecl, at least 1024 callbacks can always be created.
+func NewCallback(fn any) uintptr {
+ return compileCallback(fn, true)
+}
+
+// NewCallbackCDecl converts a Go function to a function pointer conforming to the cdecl calling convention.
+// This is useful when interoperating with Windows code requiring callbacks.
+// The argument is expected to be a function with one uintptr-sized result. The function must not have arguments with size larger than the size of uintptr.
+// Only a limited number of callbacks may be created in a single Go process, and any memory allocated
+// for these callbacks is never released.
+// Between NewCallback and NewCallbackCDecl, at least 1024 callbacks can always be created.
+func NewCallbackCDecl(fn any) uintptr {
+ return compileCallback(fn, false)
+}
+
+// windows api calls
+
+//sys GetLastError() (lasterr error)
+//sys LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW
+//sys FreeLibrary(handle Handle) (err error)
+//sys GetProcAddress(module Handle, procname string) (proc uintptr, err error)
+//sys GetVersion() (ver uint32, err error)
+//sys rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) = ntdll.RtlGetNtVersionNumbers
+//sys formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
+//sys ExitProcess(exitcode uint32)
+//sys CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
+//sys readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = ReadFile
+//sys writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) = WriteFile
+//sys SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff]
+//sys CloseHandle(handle Handle) (err error)
+//sys GetStdHandle(stdhandle int) (handle Handle, err error) [failretval==InvalidHandle]
+//sys findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW
+//sys findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW
+//sys FindClose(handle Handle) (err error)
+//sys GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error)
+//sys GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW
+//sys SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW
+//sys CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW
+//sys RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW
+//sys DeleteFile(path *uint16) (err error) = DeleteFileW
+//sys MoveFile(from *uint16, to *uint16) (err error) = MoveFileW
+//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
+//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 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
+//sys CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = advapi32.CreateProcessAsUserW
+//sys OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error)
+//sys TerminateProcess(handle Handle, exitcode uint32) (err error)
+//sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
+//sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW
+//sys GetCurrentProcess() (pseudoHandle Handle, err error)
+//sys GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error)
+//sys DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error)
+//sys WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff]
+//sys GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW
+//sys CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error)
+//sys GetFileType(filehandle Handle) (n uint32, err error)
+//sys CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW
+//sys CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext
+//sys CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom
+//sys GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW
+//sys FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW
+//sys GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW
+//sys SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW
+//sys SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
+//sys GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW
+//sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW
+//sys GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW
+//sys GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW
+//sys CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW
+//sys LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0]
+//sys SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error)
+//sys FlushFileBuffers(handle Handle) (err error)
+//sys GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW
+//sys GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW
+//sys GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW
+//sys CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW
+//sys MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error)
+//sys UnmapViewOfFile(addr uintptr) (err error)
+//sys FlushViewOfFile(addr uintptr, length uintptr) (err error)
+//sys VirtualLock(addr uintptr, length uintptr) (err error)
+//sys VirtualUnlock(addr uintptr, length uintptr) (err error)
+//sys TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile
+//sys ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW
+//sys CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW
+//sys CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) = crypt32.CertOpenStore
+//sys CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore
+//sys CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore
+//sys CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore
+//sys CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain
+//sys CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain
+//sys CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext
+//sys CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext
+//sys CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy
+//sys RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW
+//sys RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey
+//sys RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW
+//sys regEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW
+//sys RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW
+//sys getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId
+//sys GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode
+//sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
+//sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
+//sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot
+//sys Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW
+//sys Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW
+//sys DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error)
+// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
+//sys CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW
+//sys CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW
+//sys initializeProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, attrcount uint32, flags uint32, size *uintptr) (err error) = InitializeProcThreadAttributeList
+//sys deleteProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST) = DeleteProcThreadAttributeList
+//sys updateProcThreadAttribute(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) = UpdateProcThreadAttribute
+//sys getFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) [n == 0 || n >= filePathSize] = kernel32.GetFinalPathNameByHandleW
+
+// syscall interface implementation for other packages
+
+func makeInheritSa() *SecurityAttributes {
+ var sa SecurityAttributes
+ sa.Length = uint32(unsafe.Sizeof(sa))
+ sa.InheritHandle = 1
+ return &sa
+}
+
+func Open(path string, mode int, perm uint32) (fd Handle, err error) {
+ if len(path) == 0 {
+ return InvalidHandle, ERROR_FILE_NOT_FOUND
+ }
+ pathp, err := UTF16PtrFromString(path)
+ if err != nil {
+ return InvalidHandle, err
+ }
+ var access uint32
+ switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
+ case O_RDONLY:
+ access = GENERIC_READ
+ case O_WRONLY:
+ access = GENERIC_WRITE
+ case O_RDWR:
+ access = GENERIC_READ | GENERIC_WRITE
+ }
+ if mode&O_CREAT != 0 {
+ access |= GENERIC_WRITE
+ }
+ if mode&O_APPEND != 0 {
+ access &^= GENERIC_WRITE
+ access |= FILE_APPEND_DATA
+ }
+ sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE)
+ var sa *SecurityAttributes
+ if mode&O_CLOEXEC == 0 {
+ sa = makeInheritSa()
+ }
+ var createmode uint32
+ switch {
+ case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
+ createmode = CREATE_NEW
+ case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
+ createmode = CREATE_ALWAYS
+ case mode&O_CREAT == O_CREAT:
+ createmode = OPEN_ALWAYS
+ case mode&O_TRUNC == O_TRUNC:
+ createmode = TRUNCATE_EXISTING
+ default:
+ createmode = OPEN_EXISTING
+ }
+ var attrs uint32 = FILE_ATTRIBUTE_NORMAL
+ if perm&S_IWRITE == 0 {
+ attrs = FILE_ATTRIBUTE_READONLY
+ if createmode == CREATE_ALWAYS {
+ // We have been asked to create a read-only file.
+ // If the file already exists, the semantics of
+ // the Unix open system call is to preserve the
+ // existing permissions. If we pass CREATE_ALWAYS
+ // and FILE_ATTRIBUTE_READONLY to CreateFile,
+ // and the file already exists, CreateFile will
+ // change the file permissions.
+ // Avoid that to preserve the Unix semantics.
+ h, e := CreateFile(pathp, access, sharemode, sa, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
+ switch e {
+ case ERROR_FILE_NOT_FOUND, _ERROR_BAD_NETPATH, ERROR_PATH_NOT_FOUND:
+ // File does not exist. These are the same
+ // errors as Errno.Is checks for ErrNotExist.
+ // Carry on to create the file.
+ default:
+ // Success or some different error.
+ return h, e
+ }
+ }
+ }
+ if createmode == OPEN_EXISTING && access == GENERIC_READ {
+ // Necessary for opening directory handles.
+ attrs |= FILE_FLAG_BACKUP_SEMANTICS
+ }
+ return CreateFile(pathp, access, sharemode, sa, createmode, attrs, 0)
+}
+
+func Read(fd Handle, p []byte) (n int, err error) {
+ var done uint32
+ e := ReadFile(fd, p, &done, nil)
+ if e != nil {
+ if e == ERROR_BROKEN_PIPE {
+ // NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin
+ return 0, nil
+ }
+ return 0, e
+ }
+ return int(done), nil
+}
+
+func Write(fd Handle, p []byte) (n int, err error) {
+ var done uint32
+ e := WriteFile(fd, p, &done, nil)
+ if e != nil {
+ return 0, e
+ }
+ return int(done), nil
+}
+
+func ReadFile(fd Handle, p []byte, done *uint32, overlapped *Overlapped) error {
+ err := readFile(fd, p, done, overlapped)
+ if race.Enabled {
+ if *done > 0 {
+ race.WriteRange(unsafe.Pointer(&p[0]), int(*done))
+ }
+ race.Acquire(unsafe.Pointer(&ioSync))
+ }
+ if msanenabled && *done > 0 {
+ msanWrite(unsafe.Pointer(&p[0]), int(*done))
+ }
+ if asanenabled && *done > 0 {
+ asanWrite(unsafe.Pointer(&p[0]), int(*done))
+ }
+ return err
+}
+
+func WriteFile(fd Handle, p []byte, done *uint32, overlapped *Overlapped) error {
+ if race.Enabled {
+ race.ReleaseMerge(unsafe.Pointer(&ioSync))
+ }
+ err := writeFile(fd, p, done, overlapped)
+ if race.Enabled && *done > 0 {
+ race.ReadRange(unsafe.Pointer(&p[0]), int(*done))
+ }
+ if msanenabled && *done > 0 {
+ msanRead(unsafe.Pointer(&p[0]), int(*done))
+ }
+ if asanenabled && *done > 0 {
+ asanRead(unsafe.Pointer(&p[0]), int(*done))
+ }
+ return err
+}
+
+var ioSync int64
+
+var procSetFilePointerEx = modkernel32.NewProc("SetFilePointerEx")
+
+const ptrSize = unsafe.Sizeof(uintptr(0))
+
+// setFilePointerEx calls SetFilePointerEx.
+// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365542(v=vs.85).aspx
+func setFilePointerEx(handle Handle, distToMove int64, newFilePointer *int64, whence uint32) error {
+ var e1 Errno
+ if unsafe.Sizeof(uintptr(0)) == 8 {
+ _, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 4, uintptr(handle), uintptr(distToMove), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0, 0)
+ } else {
+ // Different 32-bit systems disgaree about whether distToMove starts 8-byte aligned.
+ switch runtime.GOARCH {
+ default:
+ panic("unsupported 32-bit architecture")
+ case "386":
+ // distToMove is a LARGE_INTEGER, which is 64 bits.
+ _, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 5, uintptr(handle), uintptr(distToMove), uintptr(distToMove>>32), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0)
+ case "arm":
+ // distToMove must be 8-byte aligned per ARM calling convention
+ // https://docs.microsoft.com/en-us/cpp/build/overview-of-arm-abi-conventions#stage-c-assignment-of-arguments-to-registers-and-stack
+ _, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 6, uintptr(handle), 0, uintptr(distToMove), uintptr(distToMove>>32), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence))
+ }
+ }
+ if e1 != 0 {
+ return errnoErr(e1)
+ }
+ return nil
+}
+
+func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
+ var w uint32
+ switch whence {
+ case 0:
+ w = FILE_BEGIN
+ case 1:
+ w = FILE_CURRENT
+ case 2:
+ w = FILE_END
+ }
+ err = setFilePointerEx(fd, offset, &newoffset, w)
+ return
+}
+
+func Close(fd Handle) (err error) {
+ return CloseHandle(fd)
+}
+
+var (
+ Stdin = getStdHandle(STD_INPUT_HANDLE)
+ Stdout = getStdHandle(STD_OUTPUT_HANDLE)
+ Stderr = getStdHandle(STD_ERROR_HANDLE)
+)
+
+func getStdHandle(h int) (fd Handle) {
+ r, _ := GetStdHandle(h)
+ return r
+}
+
+const ImplementsGetwd = true
+
+func Getwd() (wd string, err error) {
+ b := make([]uint16, 300)
+ // The path of the current directory may not fit in the initial 300-word
+ // buffer when long path support is enabled. The current directory may also
+ // change between subsequent calls of GetCurrentDirectory. As a result, we
+ // need to retry the call in a loop until the current directory fits, each
+ // time with a bigger buffer.
+ for {
+ n, e := GetCurrentDirectory(uint32(len(b)), &b[0])
+ if e != nil {
+ return "", e
+ }
+ if int(n) <= len(b) {
+ return UTF16ToString(b[:n]), nil
+ }
+ b = make([]uint16, n)
+ }
+}
+
+func Chdir(path string) (err error) {
+ pathp, err := UTF16PtrFromString(path)
+ if err != nil {
+ return err
+ }
+ return SetCurrentDirectory(pathp)
+}
+
+func Mkdir(path string, mode uint32) (err error) {
+ pathp, err := UTF16PtrFromString(path)
+ if err != nil {
+ return err
+ }
+ return CreateDirectory(pathp, nil)
+}
+
+func Rmdir(path string) (err error) {
+ pathp, err := UTF16PtrFromString(path)
+ if err != nil {
+ return err
+ }
+ return RemoveDirectory(pathp)
+}
+
+func Unlink(path string) (err error) {
+ pathp, err := UTF16PtrFromString(path)
+ if err != nil {
+ return err
+ }
+ return DeleteFile(pathp)
+}
+
+func Rename(oldpath, newpath string) (err error) {
+ from, err := UTF16PtrFromString(oldpath)
+ if err != nil {
+ return err
+ }
+ to, err := UTF16PtrFromString(newpath)
+ if err != nil {
+ return err
+ }
+ return MoveFile(from, to)
+}
+
+func ComputerName() (name string, err error) {
+ var n uint32 = MAX_COMPUTERNAME_LENGTH + 1
+ b := make([]uint16, n)
+ e := GetComputerName(&b[0], &n)
+ if e != nil {
+ return "", e
+ }
+ return UTF16ToString(b[:n]), nil
+}
+
+func Ftruncate(fd Handle, length int64) (err error) {
+ curoffset, e := Seek(fd, 0, 1)
+ if e != nil {
+ return e
+ }
+ defer Seek(fd, curoffset, 0)
+ _, e = Seek(fd, length, 0)
+ if e != nil {
+ return e
+ }
+ e = SetEndOfFile(fd)
+ if e != nil {
+ return e
+ }
+ return nil
+}
+
+func Gettimeofday(tv *Timeval) (err error) {
+ var ft Filetime
+ GetSystemTimeAsFileTime(&ft)
+ *tv = NsecToTimeval(ft.Nanoseconds())
+ return nil
+}
+
+func Pipe(p []Handle) (err error) {
+ if len(p) != 2 {
+ return EINVAL
+ }
+ var r, w Handle
+ e := CreatePipe(&r, &w, makeInheritSa(), 0)
+ if e != nil {
+ return e
+ }
+ p[0] = r
+ p[1] = w
+ return nil
+}
+
+func Utimes(path string, tv []Timeval) (err error) {
+ if len(tv) != 2 {
+ return EINVAL
+ }
+ pathp, e := UTF16PtrFromString(path)
+ if e != nil {
+ return e
+ }
+ h, e := CreateFile(pathp,
+ FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
+ if e != nil {
+ return e
+ }
+ defer Close(h)
+ a := Filetime{}
+ w := Filetime{}
+ if tv[0].Nanoseconds() != 0 {
+ a = NsecToFiletime(tv[0].Nanoseconds())
+ }
+ if tv[0].Nanoseconds() != 0 {
+ w = NsecToFiletime(tv[1].Nanoseconds())
+ }
+ return SetFileTime(h, nil, &a, &w)
+}
+
+// This matches the value in os/file_windows.go.
+const _UTIME_OMIT = -1
+
+func UtimesNano(path string, ts []Timespec) (err error) {
+ if len(ts) != 2 {
+ return EINVAL
+ }
+ pathp, e := UTF16PtrFromString(path)
+ if e != nil {
+ return e
+ }
+ h, e := CreateFile(pathp,
+ FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
+ if e != nil {
+ return e
+ }
+ defer Close(h)
+ a := Filetime{}
+ w := Filetime{}
+ if ts[0].Nsec != _UTIME_OMIT {
+ a = NsecToFiletime(TimespecToNsec(ts[0]))
+ }
+ if ts[1].Nsec != _UTIME_OMIT {
+ w = NsecToFiletime(TimespecToNsec(ts[1]))
+ }
+ return SetFileTime(h, nil, &a, &w)
+}
+
+func Fsync(fd Handle) (err error) {
+ return FlushFileBuffers(fd)
+}
+
+func Chmod(path string, mode uint32) (err error) {
+ p, e := UTF16PtrFromString(path)
+ if e != nil {
+ return e
+ }
+ attrs, e := GetFileAttributes(p)
+ if e != nil {
+ return e
+ }
+ if mode&S_IWRITE != 0 {
+ attrs &^= FILE_ATTRIBUTE_READONLY
+ } else {
+ attrs |= FILE_ATTRIBUTE_READONLY
+ }
+ return SetFileAttributes(p, attrs)
+}
+
+func LoadCancelIoEx() error {
+ return procCancelIoEx.Find()
+}
+
+func LoadSetFileCompletionNotificationModes() error {
+ return procSetFileCompletionNotificationModes.Find()
+}
+
+// net api calls
+
+const socket_error = uintptr(^uint32(0))
+
+//sys WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup
+//sys WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup
+//sys WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==socket_error] = ws2_32.WSAIoctl
+//sys socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket
+//sys Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt
+//sys Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt
+//sys bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind
+//sys connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect
+//sys getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname
+//sys getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername
+//sys listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen
+//sys shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown
+//sys Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket
+//sys AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx
+//sys GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs
+//sys WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv
+//sys WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend
+//sys WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom
+//sys WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo
+//sys GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname
+//sys GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname
+//sys Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
+//sys GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname
+//sys DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W
+//sys DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree
+//sys DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W
+//sys GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW
+//sys FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW
+//sys GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry
+//sys GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo
+//sys SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes
+//sys WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW
+
+// For testing: clients can set this flag to force
+// creation of IPv6 sockets to return EAFNOSUPPORT.
+var SocketDisableIPv6 bool
+
+type RawSockaddrInet4 struct {
+ Family uint16
+ Port uint16
+ Addr [4]byte /* in_addr */
+ Zero [8]uint8
+}
+
+type RawSockaddrInet6 struct {
+ Family uint16
+ Port uint16
+ Flowinfo uint32
+ Addr [16]byte /* in6_addr */
+ Scope_id uint32
+}
+
+type RawSockaddr struct {
+ Family uint16
+ Data [14]int8
+}
+
+type RawSockaddrAny struct {
+ Addr RawSockaddr
+ Pad [100]int8
+}
+
+type Sockaddr interface {
+ sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs
+}
+
+type SockaddrInet4 struct {
+ Port int
+ Addr [4]byte
+ raw RawSockaddrInet4
+}
+
+func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) {
+ if sa.Port < 0 || sa.Port > 0xFFFF {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Family = AF_INET
+ p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+ p[0] = byte(sa.Port >> 8)
+ p[1] = byte(sa.Port)
+ sa.raw.Addr = sa.Addr
+ return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
+}
+
+type SockaddrInet6 struct {
+ Port int
+ ZoneId uint32
+ Addr [16]byte
+ raw RawSockaddrInet6
+}
+
+func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) {
+ if sa.Port < 0 || sa.Port > 0xFFFF {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Family = AF_INET6
+ p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+ p[0] = byte(sa.Port >> 8)
+ p[1] = byte(sa.Port)
+ sa.raw.Scope_id = sa.ZoneId
+ sa.raw.Addr = sa.Addr
+ return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
+}
+
+type RawSockaddrUnix struct {
+ Family uint16
+ Path [UNIX_PATH_MAX]int8
+}
+
+type SockaddrUnix struct {
+ Name string
+ raw RawSockaddrUnix
+}
+
+func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
+ name := sa.Name
+ n := len(name)
+ if n > len(sa.raw.Path) {
+ return nil, 0, EINVAL
+ }
+ if n == len(sa.raw.Path) && name[0] != '@' {
+ return nil, 0, EINVAL
+ }
+ sa.raw.Family = AF_UNIX
+ for i := 0; i < n; i++ {
+ sa.raw.Path[i] = int8(name[i])
+ }
+ // length is family (uint16), name, NUL.
+ sl := int32(2)
+ if n > 0 {
+ sl += int32(n) + 1
+ }
+ if sa.raw.Path[0] == '@' {
+ sa.raw.Path[0] = 0
+ // Don't count trailing NUL for abstract address.
+ sl--
+ }
+
+ return unsafe.Pointer(&sa.raw), sl, nil
+}
+
+func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
+ switch rsa.Addr.Family {
+ case AF_UNIX:
+ pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
+ sa := new(SockaddrUnix)
+ if pp.Path[0] == 0 {
+ // "Abstract" Unix domain socket.
+ // Rewrite leading NUL as @ for textual display.
+ // (This is the standard convention.)
+ // Not friendly to overwrite in place,
+ // but the callers below don't care.
+ pp.Path[0] = '@'
+ }
+
+ // Assume path ends at NUL.
+ // This is not technically the Linux semantics for
+ // abstract Unix domain sockets--they are supposed
+ // to be uninterpreted fixed-size binary blobs--but
+ // everyone uses this convention.
+ n := 0
+ for n < len(pp.Path) && pp.Path[n] != 0 {
+ n++
+ }
+ sa.Name = string(unsafe.Slice((*byte)(unsafe.Pointer(&pp.Path[0])), n))
+ return sa, nil
+
+ case AF_INET:
+ pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
+ sa := new(SockaddrInet4)
+ p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ sa.Port = int(p[0])<<8 + int(p[1])
+ sa.Addr = pp.Addr
+ return sa, nil
+
+ case AF_INET6:
+ pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
+ sa := new(SockaddrInet6)
+ p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+ sa.Port = int(p[0])<<8 + int(p[1])
+ sa.ZoneId = pp.Scope_id
+ sa.Addr = pp.Addr
+ return sa, nil
+ }
+ return nil, EAFNOSUPPORT
+}
+
+func Socket(domain, typ, proto int) (fd Handle, err error) {
+ if domain == AF_INET6 && SocketDisableIPv6 {
+ return InvalidHandle, EAFNOSUPPORT
+ }
+ return socket(int32(domain), int32(typ), int32(proto))
+}
+
+func SetsockoptInt(fd Handle, level, opt int, value int) (err error) {
+ v := int32(value)
+ return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v)))
+}
+
+func Bind(fd Handle, sa Sockaddr) (err error) {
+ ptr, n, err := sa.sockaddr()
+ if err != nil {
+ return err
+ }
+ return bind(fd, ptr, n)
+}
+
+func Connect(fd Handle, sa Sockaddr) (err error) {
+ ptr, n, err := sa.sockaddr()
+ if err != nil {
+ return err
+ }
+ return connect(fd, ptr, n)
+}
+
+func Getsockname(fd Handle) (sa Sockaddr, err error) {
+ var rsa RawSockaddrAny
+ l := int32(unsafe.Sizeof(rsa))
+ if err = getsockname(fd, &rsa, &l); err != nil {
+ return
+ }
+ return rsa.Sockaddr()
+}
+
+func Getpeername(fd Handle) (sa Sockaddr, err error) {
+ var rsa RawSockaddrAny
+ l := int32(unsafe.Sizeof(rsa))
+ if err = getpeername(fd, &rsa, &l); err != nil {
+ return
+ }
+ return rsa.Sockaddr()
+}
+
+func Listen(s Handle, n int) (err error) {
+ return listen(s, int32(n))
+}
+
+func Shutdown(fd Handle, how int) (err error) {
+ return shutdown(fd, int32(how))
+}
+
+func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) {
+ var rsa unsafe.Pointer
+ var len int32
+ if to != nil {
+ rsa, len, err = to.sockaddr()
+ if err != nil {
+ return err
+ }
+ }
+ r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(rsa)), uintptr(len), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+ if r1 == socket_error {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = EINVAL
+ }
+ }
+ return err
+}
+
+func wsaSendtoInet4(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *SockaddrInet4, overlapped *Overlapped, croutine *byte) (err error) {
+ rsa, len, err := to.sockaddr()
+ if err != nil {
+ return err
+ }
+ r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(rsa)), uintptr(len), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+ if r1 == socket_error {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = EINVAL
+ }
+ }
+ return err
+}
+
+func wsaSendtoInet6(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *SockaddrInet6, overlapped *Overlapped, croutine *byte) (err error) {
+ rsa, len, err := to.sockaddr()
+ if err != nil {
+ return err
+ }
+ r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(rsa)), uintptr(len), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+ if r1 == socket_error {
+ if e1 != 0 {
+ err = errnoErr(e1)
+ } else {
+ err = EINVAL
+ }
+ }
+ return err
+}
+
+func LoadGetAddrInfo() error {
+ return procGetAddrInfoW.Find()
+}
+
+var connectExFunc struct {
+ once sync.Once
+ addr uintptr
+ err error
+}
+
+func LoadConnectEx() error {
+ connectExFunc.once.Do(func() {
+ var s Handle
+ s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
+ if connectExFunc.err != nil {
+ return
+ }
+ defer CloseHandle(s)
+ var n uint32
+ connectExFunc.err = WSAIoctl(s,
+ SIO_GET_EXTENSION_FUNCTION_POINTER,
+ (*byte)(unsafe.Pointer(&WSAID_CONNECTEX)),
+ uint32(unsafe.Sizeof(WSAID_CONNECTEX)),
+ (*byte)(unsafe.Pointer(&connectExFunc.addr)),
+ uint32(unsafe.Sizeof(connectExFunc.addr)),
+ &n, nil, 0)
+ })
+ return connectExFunc.err
+}
+
+func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) {
+ r1, _, e1 := Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0)
+ if r1 == 0 {
+ if e1 != 0 {
+ err = error(e1)
+ } else {
+ err = EINVAL
+ }
+ }
+ return
+}
+
+func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error {
+ err := LoadConnectEx()
+ if err != nil {
+ return errorspkg.New("failed to find ConnectEx: " + err.Error())
+ }
+ ptr, n, err := sa.sockaddr()
+ if err != nil {
+ return err
+ }
+ return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
+}
+
+// Invented structures to support what package os expects.
+type Rusage struct {
+ CreationTime Filetime
+ ExitTime Filetime
+ KernelTime Filetime
+ UserTime Filetime
+}
+
+type WaitStatus struct {
+ ExitCode uint32
+}
+
+func (w WaitStatus) Exited() bool { return true }
+
+func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) }
+
+func (w WaitStatus) Signal() Signal { return -1 }
+
+func (w WaitStatus) CoreDump() bool { return false }
+
+func (w WaitStatus) Stopped() bool { return false }
+
+func (w WaitStatus) Continued() bool { return false }
+
+func (w WaitStatus) StopSignal() Signal { return -1 }
+
+func (w WaitStatus) Signaled() bool { return false }
+
+func (w WaitStatus) TrapCause() int { return -1 }
+
+// Timespec is an invented structure on Windows, but here for
+// consistency with the syscall package for other operating systems.
+type Timespec struct {
+ Sec int64
+ Nsec int64
+}
+
+func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
+
+func NsecToTimespec(nsec int64) (ts Timespec) {
+ ts.Sec = nsec / 1e9
+ ts.Nsec = nsec % 1e9
+ return
+}
+
+// TODO(brainman): fix all needed for net
+
+func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, EWINDOWS }
+func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) {
+ return 0, nil, EWINDOWS
+}
+func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error) { return EWINDOWS }
+func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return EWINDOWS }
+
+// The Linger struct is wrong but we only noticed after Go 1.
+// sysLinger is the real system call structure.
+
+// BUG(brainman): The definition of Linger is not appropriate for direct use
+// with Setsockopt and Getsockopt.
+// Use SetsockoptLinger instead.
+
+type Linger struct {
+ Onoff int32
+ Linger int32
+}
+
+type sysLinger struct {
+ Onoff uint16
+ Linger uint16
+}
+
+type IPMreq struct {
+ Multiaddr [4]byte /* in_addr */
+ Interface [4]byte /* in_addr */
+}
+
+type IPv6Mreq struct {
+ Multiaddr [16]byte /* in6_addr */
+ Interface uint32
+}
+
+func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, EWINDOWS }
+
+func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
+ sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)}
+ return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys)))
+}
+
+func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
+ return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
+}
+func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
+ return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
+}
+func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { return EWINDOWS }
+
+func Getpid() (pid int) { return int(getCurrentProcessId()) }
+
+func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) {
+ // NOTE(rsc): The Win32finddata struct is wrong for the system call:
+ // the two paths are each one uint16 short. Use the correct struct,
+ // a win32finddata1, and then copy the results out.
+ // There is no loss of expressivity here, because the final
+ // uint16, if it is used, is supposed to be a NUL, and Go doesn't need that.
+ // For Go 1.1, we might avoid the allocation of win32finddata1 here
+ // by adding a final Bug [2]uint16 field to the struct and then
+ // adjusting the fields in the result directly.
+ var data1 win32finddata1
+ handle, err = findFirstFile1(name, &data1)
+ if err == nil {
+ copyFindData(data, &data1)
+ }
+ return
+}
+
+func FindNextFile(handle Handle, data *Win32finddata) (err error) {
+ var data1 win32finddata1
+ err = findNextFile1(handle, &data1)
+ if err == nil {
+ copyFindData(data, &data1)
+ }
+ return
+}
+
+func getProcessEntry(pid int) (*ProcessEntry32, error) {
+ snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
+ if err != nil {
+ return nil, err
+ }
+ defer CloseHandle(snapshot)
+ var procEntry ProcessEntry32
+ procEntry.Size = uint32(unsafe.Sizeof(procEntry))
+ if err = Process32First(snapshot, &procEntry); err != nil {
+ return nil, err
+ }
+ for {
+ if procEntry.ProcessID == uint32(pid) {
+ return &procEntry, nil
+ }
+ err = Process32Next(snapshot, &procEntry)
+ if err != nil {
+ return nil, err
+ }
+ }
+}
+
+func Getppid() (ppid int) {
+ pe, err := getProcessEntry(Getpid())
+ if err != nil {
+ return -1
+ }
+ return int(pe.ParentProcessID)
+}
+
+func fdpath(fd Handle, buf []uint16) ([]uint16, error) {
+ const (
+ FILE_NAME_NORMALIZED = 0
+ VOLUME_NAME_DOS = 0
+ )
+ for {
+ n, err := getFinalPathNameByHandle(fd, &buf[0], uint32(len(buf)), FILE_NAME_NORMALIZED|VOLUME_NAME_DOS)
+ if err == nil {
+ buf = buf[:n]
+ break
+ }
+ if err != _ERROR_NOT_ENOUGH_MEMORY {
+ return nil, err
+ }
+ buf = append(buf, make([]uint16, n-uint32(len(buf)))...)
+ }
+ return buf, nil
+}
+
+func Fchdir(fd Handle) (err error) {
+ var buf [MAX_PATH + 1]uint16
+ path, err := fdpath(fd, buf[:])
+ if err != nil {
+ return err
+ }
+ // When using VOLUME_NAME_DOS, the path is always pefixed by "\\?\".
+ // That prefix tells the Windows APIs to disable all string parsing and to send
+ // the string that follows it straight to the file system.
+ // Although SetCurrentDirectory and GetCurrentDirectory do support the "\\?\" prefix,
+ // some other Windows APIs don't. If the prefix is not removed here, it will leak
+ // to Getwd, and we don't want such a general-purpose function to always return a
+ // path with the "\\?\" prefix after Fchdir is called.
+ // The downside is that APIs that do support it will parse the path and try to normalize it,
+ // when it's already normalized.
+ if len(path) >= 4 && path[0] == '\\' && path[1] == '\\' && path[2] == '?' && path[3] == '\\' {
+ path = path[4:]
+ }
+ return SetCurrentDirectory(&path[0])
+}
+
+// TODO(brainman): fix all needed for os
+func Link(oldpath, newpath string) (err error) { return EWINDOWS }
+func Symlink(path, link string) (err error) { return EWINDOWS }
+
+func Fchmod(fd Handle, mode uint32) (err error) { return EWINDOWS }
+func Chown(path string, uid int, gid int) (err error) { return EWINDOWS }
+func Lchown(path string, uid int, gid int) (err error) { return EWINDOWS }
+func Fchown(fd Handle, uid int, gid int) (err error) { return EWINDOWS }
+
+func Getuid() (uid int) { return -1 }
+func Geteuid() (euid int) { return -1 }
+func Getgid() (gid int) { return -1 }
+func Getegid() (egid int) { return -1 }
+func Getgroups() (gids []int, err error) { return nil, EWINDOWS }
+
+type Signal int
+
+func (s Signal) Signal() {}
+
+func (s Signal) String() string {
+ if 0 <= s && int(s) < len(signals) {
+ str := signals[s]
+ if str != "" {
+ return str
+ }
+ }
+ return "signal " + itoa.Itoa(int(s))
+}
+
+func LoadCreateSymbolicLink() error {
+ return procCreateSymbolicLinkW.Find()
+}
+
+// Readlink returns the destination of the named symbolic link.
+func Readlink(path string, buf []byte) (n int, err error) {
+ fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING,
+ FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0)
+ if err != nil {
+ return -1, err
+ }
+ defer CloseHandle(fd)
+
+ rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
+ var bytesReturned uint32
+ err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
+ if err != nil {
+ return -1, err
+ }
+
+ rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
+ var s string
+ switch rdb.ReparseTag {
+ case IO_REPARSE_TAG_SYMLINK:
+ data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
+ p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
+ s = UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2])
+ if data.Flags&_SYMLINK_FLAG_RELATIVE == 0 {
+ if len(s) >= 4 && s[:4] == `\??\` {
+ s = s[4:]
+ switch {
+ case len(s) >= 2 && s[1] == ':': // \??\C:\foo\bar
+ // do nothing
+ case len(s) >= 4 && s[:4] == `UNC\`: // \??\UNC\foo\bar
+ s = `\\` + s[4:]
+ default:
+ // unexpected; do nothing
+ }
+ } else {
+ // unexpected; do nothing
+ }
+ }
+ case _IO_REPARSE_TAG_MOUNT_POINT:
+ data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
+ p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
+ s = UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2])
+ if len(s) >= 4 && s[:4] == `\??\` { // \??\C:\foo\bar
+ s = s[4:]
+ } else {
+ // unexpected; do nothing
+ }
+ default:
+ // the path is not a symlink or junction but another type of reparse
+ // point
+ return -1, ENOENT
+ }
+ n = copy(buf, []byte(s))
+
+ 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)
+}
+
+// newProcThreadAttributeList allocates new PROC_THREAD_ATTRIBUTE_LIST, with
+// the requested maximum number of attributes, which must be cleaned up by
+// deleteProcThreadAttributeList.
+func newProcThreadAttributeList(maxAttrCount uint32) (*_PROC_THREAD_ATTRIBUTE_LIST, error) {
+ var size uintptr
+ err := initializeProcThreadAttributeList(nil, maxAttrCount, 0, &size)
+ if err != ERROR_INSUFFICIENT_BUFFER {
+ if err == nil {
+ return nil, errorspkg.New("unable to query buffer size from InitializeProcThreadAttributeList")
+ }
+ return nil, err
+ }
+ // size is guaranteed to be ≥1 by initializeProcThreadAttributeList.
+ al := (*_PROC_THREAD_ATTRIBUTE_LIST)(unsafe.Pointer(&make([]byte, size)[0]))
+ err = initializeProcThreadAttributeList(al, maxAttrCount, 0, &size)
+ if err != nil {
+ return nil, err
+ }
+ return al, nil
+}
+
+// RegEnumKeyEx enumerates the subkeys of an open registry key.
+// Each call retrieves information about one subkey. name is
+// a buffer that should be large enough to hold the name of the
+// subkey plus a null terminating character. nameLen is its
+// length. On return, nameLen will contain the actual length of the
+// subkey.
+//
+// Should name not be large enough to hold the subkey, this function
+// will return ERROR_MORE_DATA, and must be called again with an
+// appropriately sized buffer.
+//
+// reserved must be nil. class and classLen behave like name and nameLen
+// but for the class of the subkey, except that they are optional.
+// lastWriteTime, if not nil, will be populated with the time the subkey
+// was last written.
+//
+// The caller must enumerate all subkeys in order. That is
+// RegEnumKeyEx must be called with index starting at 0, incrementing
+// the index until the function returns ERROR_NO_MORE_ITEMS, or with
+// the index of the last subkey (obtainable from RegQueryInfoKey),
+// decrementing until index 0 is enumerated.
+//
+// Successive calls to this API must happen on the same OS thread,
+// so call runtime.LockOSThread before calling this function.
+func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) {
+ return regEnumKeyEx(key, index, name, nameLen, reserved, class, classLen, lastWriteTime)
+}
diff --git a/contrib/go/_std_1.20/src/syscall/time_nofake.go b/contrib/go/_std_1.21/src/syscall/time_nofake.go
index 231875d8c3..231875d8c3 100644
--- a/contrib/go/_std_1.20/src/syscall/time_nofake.go
+++ b/contrib/go/_std_1.21/src/syscall/time_nofake.go
diff --git a/contrib/go/_std_1.21/src/syscall/timestruct.go b/contrib/go/_std_1.21/src/syscall/timestruct.go
new file mode 100644
index 0000000000..4fca63cc40
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/timestruct.go
@@ -0,0 +1,36 @@
+// Copyright 2016 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package syscall
+
+// TimespecToNsec returns the time stored in ts as nanoseconds.
+func TimespecToNsec(ts Timespec) int64 { return ts.Nano() }
+
+// NsecToTimespec converts a number of nanoseconds into a Timespec.
+func NsecToTimespec(nsec int64) Timespec {
+ sec := nsec / 1e9
+ nsec = nsec % 1e9
+ if nsec < 0 {
+ nsec += 1e9
+ sec--
+ }
+ return setTimespec(sec, nsec)
+}
+
+// TimevalToNsec returns the time stored in tv as nanoseconds.
+func TimevalToNsec(tv Timeval) int64 { return tv.Nano() }
+
+// NsecToTimeval converts a number of nanoseconds into a Timeval.
+func NsecToTimeval(nsec int64) Timeval {
+ nsec += 999 // round up to microsecond
+ usec := nsec % 1e9 / 1e3
+ sec := nsec / 1e9
+ if usec < 0 {
+ usec += 1e6
+ sec--
+ }
+ return setTimeval(sec, usec)
+}
diff --git a/contrib/go/_std_1.20/src/syscall/types_windows.go b/contrib/go/_std_1.21/src/syscall/types_windows.go
index 384b5b4f2c..384b5b4f2c 100644
--- a/contrib/go/_std_1.20/src/syscall/types_windows.go
+++ b/contrib/go/_std_1.21/src/syscall/types_windows.go
diff --git a/contrib/go/_std_1.20/src/syscall/types_windows_amd64.go b/contrib/go/_std_1.21/src/syscall/types_windows_amd64.go
index 7d45ddbc0b..7d45ddbc0b 100644
--- a/contrib/go/_std_1.20/src/syscall/types_windows_amd64.go
+++ b/contrib/go/_std_1.21/src/syscall/types_windows_amd64.go
diff --git a/contrib/go/_std_1.21/src/syscall/wtf8_windows.go b/contrib/go/_std_1.21/src/syscall/wtf8_windows.go
new file mode 100644
index 0000000000..f166021b7c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/wtf8_windows.go
@@ -0,0 +1,92 @@
+// Copyright 2023 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.
+
+// Windows UTF-16 strings can contain unpaired surrogates, which can't be
+// decoded into a valid UTF-8 string. This file defines a set of functions
+// that can be used to encode and decode potentially ill-formed UTF-16 strings
+// by using the [the WTF-8 encoding](https://simonsapin.github.io/wtf-8/).
+//
+// WTF-8 is a strict superset of UTF-8, i.e. any string that is
+// well-formed in UTF-8 is also well-formed in WTF-8 and the content
+// is unchanged. Also, the conversion never fails and is lossless.
+//
+// The benefit of using WTF-8 instead of UTF-8 when decoding a UTF-16 string
+// is that the conversion is lossless even for ill-formed UTF-16 strings.
+// This property allows to read an ill-formed UTF-16 string, convert it
+// to a Go string, and convert it back to the same original UTF-16 string.
+//
+// See go.dev/issues/59971 for more info.
+
+package syscall
+
+import (
+ "unicode/utf16"
+ "unicode/utf8"
+)
+
+const (
+ surr1 = 0xd800
+ surr2 = 0xdc00
+ surr3 = 0xe000
+
+ tx = 0b10000000
+ t3 = 0b11100000
+ maskx = 0b00111111
+ mask3 = 0b00001111
+
+ rune1Max = 1<<7 - 1
+ rune2Max = 1<<11 - 1
+)
+
+// encodeWTF16 returns the potentially ill-formed
+// UTF-16 encoding of s.
+func encodeWTF16(s string, buf []uint16) []uint16 {
+ for i := 0; i < len(s); {
+ // Cannot use 'for range s' because it expects valid
+ // UTF-8 runes.
+ r, size := utf8.DecodeRuneInString(s[i:])
+ if r == utf8.RuneError {
+ // Check if s[i:] contains a valid WTF-8 encoded surrogate.
+ if sc := s[i:]; len(sc) >= 3 && sc[0] == 0xED && 0xA0 <= sc[1] && sc[1] <= 0xBF && 0x80 <= sc[2] && sc[2] <= 0xBF {
+ r = rune(sc[0]&mask3)<<12 + rune(sc[1]&maskx)<<6 + rune(sc[2]&maskx)
+ buf = append(buf, uint16(r))
+ i += 3
+ continue
+ }
+ }
+ i += size
+ buf = utf16.AppendRune(buf, r)
+ }
+ return buf
+}
+
+// decodeWTF16 returns the WTF-8 encoding of
+// the potentially ill-formed UTF-16 s.
+func decodeWTF16(s []uint16, buf []byte) []byte {
+ for i := 0; i < len(s); i++ {
+ var ar rune
+ switch r := s[i]; {
+ case r < surr1, surr3 <= r:
+ // normal rune
+ ar = rune(r)
+ case surr1 <= r && r < surr2 && i+1 < len(s) &&
+ surr2 <= s[i+1] && s[i+1] < surr3:
+ // valid surrogate sequence
+ ar = utf16.DecodeRune(rune(r), rune(s[i+1]))
+ i++
+ default:
+ // WTF-8 fallback.
+ // This only handles the 3-byte case of utf8.AppendRune,
+ // as surrogates always fall in that case.
+ ar = rune(r)
+ if ar > utf8.MaxRune {
+ ar = utf8.RuneError
+ }
+ buf = append(buf, t3|byte(ar>>12), tx|byte(ar>>6)&maskx, tx|byte(ar)&maskx)
+ continue
+ }
+ buf = utf8.AppendRune(buf, ar)
+ }
+ return buf
+}
diff --git a/contrib/go/_std_1.21/src/syscall/ya.make b/contrib/go/_std_1.21/src/syscall/ya.make
new file mode 100644
index 0000000000..e296b41f6d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/ya.make
@@ -0,0 +1,130 @@
+GO_LIBRARY()
+
+SRCS(
+ asan0.go
+ endian_little.go
+ msan0.go
+ net.go
+ syscall.go
+ time_nofake.go
+)
+
+IF (OS_DARWIN)
+ SRCS(
+ bpf_darwin.go
+ dirent.go
+ env_unix.go
+ exec_libc2.go
+ exec_unix.go
+ flock_darwin.go
+ forkpipe.go
+ ptrace_darwin.go
+ rlimit.go
+ rlimit_darwin.go
+ route_bsd.go
+ route_darwin.go
+ sockcmsg_unix.go
+ sockcmsg_unix_other.go
+ syscall_bsd.go
+ syscall_darwin.go
+ syscall_unix.go
+ timestruct.go
+ )
+
+ IF (ARCH_ARM64)
+ SRCS(
+ asm_darwin_arm64.s
+ syscall_darwin_arm64.go
+ zerrors_darwin_arm64.go
+ zsyscall_darwin_arm64.go
+ zsyscall_darwin_arm64.s
+ zsysnum_darwin_arm64.go
+ ztypes_darwin_arm64.go
+ )
+ ENDIF()
+
+ IF (ARCH_X86_64)
+ SRCS(
+ asm_darwin_amd64.s
+ syscall_darwin_amd64.go
+ zerrors_darwin_amd64.go
+ zsyscall_darwin_amd64.go
+ zsyscall_darwin_amd64.s
+ zsysnum_darwin_amd64.go
+ ztypes_darwin_amd64.go
+ )
+ ENDIF()
+ENDIF()
+
+IF (OS_LINUX)
+ SRCS(
+ dirent.go
+ env_unix.go
+ exec_linux.go
+ exec_unix.go
+ flock.go
+ forkpipe2.go
+ lsf_linux.go
+ netlink_linux.go
+ rlimit.go
+ rlimit_stub.go
+ setuidgid_linux.go
+ sockcmsg_linux.go
+ sockcmsg_unix.go
+ sockcmsg_unix_other.go
+ syscall_linux.go
+ syscall_linux_accept4.go
+ syscall_unix.go
+ timestruct.go
+ )
+
+ IF (ARCH_ARM64)
+ SRCS(
+ asm_linux_arm64.s
+ syscall_linux_arm64.go
+ zerrors_linux_arm64.go
+ zsyscall_linux_arm64.go
+ zsysnum_linux_arm64.go
+ ztypes_linux_arm64.go
+ )
+ ENDIF()
+
+ IF (ARCH_X86_64)
+ SRCS(
+ asm_linux_amd64.s
+ syscall_linux_amd64.go
+ zerrors_linux_amd64.go
+ zsyscall_linux_amd64.go
+ zsysnum_linux_amd64.go
+ ztypes_linux_amd64.go
+ )
+ ENDIF()
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ dll_windows.go
+ env_windows.go
+ exec_windows.go
+ security_windows.go
+ syscall_windows.go
+ types_windows.go
+ wtf8_windows.go
+ zerrors_windows.go
+ zsyscall_windows.go
+ )
+
+ IF (ARCH_ARM64)
+ SRCS(
+ types_windows_arm64.go
+ )
+ ENDIF()
+
+ IF (ARCH_X86_64)
+ SRCS(
+ types_windows_amd64.go
+ )
+ ENDIF()
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.20/src/syscall/zerrors_darwin_amd64.go b/contrib/go/_std_1.21/src/syscall/zerrors_darwin_amd64.go
index ecbe89c547..ecbe89c547 100644
--- a/contrib/go/_std_1.20/src/syscall/zerrors_darwin_amd64.go
+++ b/contrib/go/_std_1.21/src/syscall/zerrors_darwin_amd64.go
diff --git a/contrib/go/_std_1.20/src/syscall/zerrors_linux_amd64.go b/contrib/go/_std_1.21/src/syscall/zerrors_linux_amd64.go
index 4eb4474648..4eb4474648 100644
--- a/contrib/go/_std_1.20/src/syscall/zerrors_linux_amd64.go
+++ b/contrib/go/_std_1.21/src/syscall/zerrors_linux_amd64.go
diff --git a/contrib/go/_std_1.20/src/syscall/zerrors_linux_arm64.go b/contrib/go/_std_1.21/src/syscall/zerrors_linux_arm64.go
index ec8ac0708e..ec8ac0708e 100644
--- a/contrib/go/_std_1.20/src/syscall/zerrors_linux_arm64.go
+++ b/contrib/go/_std_1.21/src/syscall/zerrors_linux_arm64.go
diff --git a/contrib/go/_std_1.20/src/syscall/zerrors_windows.go b/contrib/go/_std_1.21/src/syscall/zerrors_windows.go
index 0a971c7dc0..0a971c7dc0 100644
--- a/contrib/go/_std_1.20/src/syscall/zerrors_windows.go
+++ b/contrib/go/_std_1.21/src/syscall/zerrors_windows.go
diff --git a/contrib/go/_std_1.21/src/syscall/zsyscall_darwin_amd64.go b/contrib/go/_std_1.21/src/syscall/zsyscall_darwin_amd64.go
new file mode 100644
index 0000000000..83680b381a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/zsyscall_darwin_amd64.go
@@ -0,0 +1,2035 @@
+// mksyscall.pl -darwin -tags darwin,amd64 syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go
+// Code generated by the command above; DO NOT EDIT.
+
+//go:build darwin && amd64
+
+package syscall
+
+import "unsafe"
+import "internal/abi"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+ r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_getgroups_trampoline()
+
+//go:cgo_import_dynamic libc_getgroups getgroups "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgroups_trampoline), uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setgroups_trampoline()
+
+//go:cgo_import_dynamic libc_setgroups setgroups "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+ r0, _, e1 := syscall6(abi.FuncPCABI0(libc_wait4_trampoline), uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+ wpid = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_wait4_trampoline()
+
+//go:cgo_import_dynamic libc_wait4 wait4 "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_accept_trampoline), uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_accept_trampoline()
+
+//go:cgo_import_dynamic libc_accept accept "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_bind_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_bind_trampoline()
+
+//go:cgo_import_dynamic libc_bind bind "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_connect_trampoline), uintptr(s), uintptr(addr), uintptr(addrlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_connect_trampoline()
+
+//go:cgo_import_dynamic libc_connect connect "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+ r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_socket_trampoline), uintptr(domain), uintptr(typ), uintptr(proto))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_socket_trampoline()
+
+//go:cgo_import_dynamic libc_socket socket "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+ _, _, e1 := syscall6(abi.FuncPCABI0(libc_getsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_getsockopt_trampoline()
+
+//go:cgo_import_dynamic libc_getsockopt getsockopt "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+ _, _, e1 := syscall6(abi.FuncPCABI0(libc_setsockopt_trampoline), uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setsockopt_trampoline()
+
+//go:cgo_import_dynamic libc_setsockopt setsockopt "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpeername_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_getpeername_trampoline()
+
+//go:cgo_import_dynamic libc_getpeername getpeername "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsockname_trampoline), uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_getsockname_trampoline()
+
+//go:cgo_import_dynamic libc_getsockname getsockname "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_shutdown_trampoline), uintptr(s), uintptr(how), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_shutdown_trampoline()
+
+//go:cgo_import_dynamic libc_shutdown shutdown "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+ _, _, e1 := rawSyscall6(abi.FuncPCABI0(libc_socketpair_trampoline), uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_socketpair_trampoline()
+
+//go:cgo_import_dynamic libc_socketpair socketpair "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := syscall6(abi.FuncPCABI0(libc_recvfrom_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_recvfrom_trampoline()
+
+//go:cgo_import_dynamic libc_recvfrom recvfrom "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := syscall6(abi.FuncPCABI0(libc_sendto_trampoline), uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_sendto_trampoline()
+
+//go:cgo_import_dynamic libc_sendto sendto "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_recvmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_recvmsg_trampoline()
+
+//go:cgo_import_dynamic libc_recvmsg recvmsg "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_sendmsg_trampoline), uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_sendmsg_trampoline()
+
+//go:cgo_import_dynamic libc_sendmsg sendmsg "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+ r0, _, e1 := syscall6(abi.FuncPCABI0(libc_kevent_trampoline), uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_kevent_trampoline()
+
+//go:cgo_import_dynamic libc_kevent kevent "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_utimes_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_utimes_trampoline()
+
+//go:cgo_import_dynamic libc_utimes utimes "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_futimes_trampoline), uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_futimes_trampoline()
+
+//go:cgo_import_dynamic libc_futimes futimes "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+ val = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_fcntl_trampoline()
+
+//go:cgo_import_dynamic libc_fcntl fcntl "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]int32) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_pipe_trampoline), uintptr(unsafe.Pointer(p)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_pipe_trampoline()
+
+//go:cgo_import_dynamic libc_pipe pipe "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall6(abi.FuncPCABI0(libc_utimensat_trampoline), uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_utimensat_trampoline()
+
+//go:cgo_import_dynamic libc_utimensat utimensat "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kill(pid int, signum int, posix int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_kill_trampoline), uintptr(pid), uintptr(signum), uintptr(posix))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_kill_trampoline()
+
+//go:cgo_import_dynamic libc_kill kill "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_access_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_access_trampoline()
+
+//go:cgo_import_dynamic libc_access access "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_adjtime_trampoline), uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_adjtime_trampoline()
+
+//go:cgo_import_dynamic libc_adjtime adjtime "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_chdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_chdir_trampoline()
+
+//go:cgo_import_dynamic libc_chdir chdir "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_chflags_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_chflags_trampoline()
+
+//go:cgo_import_dynamic libc_chflags chflags "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_chmod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_chmod_trampoline()
+
+//go:cgo_import_dynamic libc_chmod chmod "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_chown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_chown_trampoline()
+
+//go:cgo_import_dynamic libc_chown chown "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_chroot_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_chroot_trampoline()
+
+//go:cgo_import_dynamic libc_chroot chroot "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_close_trampoline), uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_close_trampoline()
+
+//go:cgo_import_dynamic libc_close close "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func closedir(dir uintptr) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_closedir_trampoline), uintptr(dir), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_closedir_trampoline()
+
+//go:cgo_import_dynamic libc_closedir closedir "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_dup_trampoline), uintptr(fd), 0, 0)
+ nfd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_dup_trampoline()
+
+//go:cgo_import_dynamic libc_dup dup "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_dup2_trampoline), uintptr(from), uintptr(to), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_dup2_trampoline()
+
+//go:cgo_import_dynamic libc_dup2 dup2 "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exchangedata(path1 string, path2 string, options int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path1)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(path2)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_exchangedata_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_exchangedata_trampoline()
+
+//go:cgo_import_dynamic libc_exchangedata exchangedata "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_fchdir_trampoline), uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_fchdir_trampoline()
+
+//go:cgo_import_dynamic libc_fchdir fchdir "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_fchflags_trampoline), uintptr(fd), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_fchflags_trampoline()
+
+//go:cgo_import_dynamic libc_fchflags fchflags "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_fchmod_trampoline), uintptr(fd), uintptr(mode), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_fchmod_trampoline()
+
+//go:cgo_import_dynamic libc_fchmod fchmod "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_fchown_trampoline), uintptr(fd), uintptr(uid), uintptr(gid))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_fchown_trampoline()
+
+//go:cgo_import_dynamic libc_fchown fchown "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_flock_trampoline), uintptr(fd), uintptr(how), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_flock_trampoline()
+
+//go:cgo_import_dynamic libc_flock flock "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_fpathconf_trampoline), uintptr(fd), uintptr(name), 0)
+ val = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_fpathconf_trampoline()
+
+//go:cgo_import_dynamic libc_fpathconf fpathconf "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_fsync_trampoline), uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_fsync_trampoline()
+
+//go:cgo_import_dynamic libc_fsync fsync "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_ftruncate_trampoline), uintptr(fd), uintptr(length), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_ftruncate_trampoline()
+
+//go:cgo_import_dynamic libc_ftruncate ftruncate "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdtablesize() (size int) {
+ r0, _, _ := syscall(abi.FuncPCABI0(libc_getdtablesize_trampoline), 0, 0, 0)
+ size = int(r0)
+ return
+}
+
+func libc_getdtablesize_trampoline()
+
+//go:cgo_import_dynamic libc_getdtablesize getdtablesize "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+ r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getegid_trampoline), 0, 0, 0)
+ egid = int(r0)
+ return
+}
+
+func libc_getegid_trampoline()
+
+//go:cgo_import_dynamic libc_getegid getegid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+ r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_geteuid_trampoline), 0, 0, 0)
+ uid = int(r0)
+ return
+}
+
+func libc_geteuid_trampoline()
+
+//go:cgo_import_dynamic libc_geteuid geteuid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+ r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getgid_trampoline), 0, 0, 0)
+ gid = int(r0)
+ return
+}
+
+func libc_getgid_trampoline()
+
+//go:cgo_import_dynamic libc_getgid getgid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+ r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getpgid_trampoline), uintptr(pid), 0, 0)
+ pgid = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_getpgid_trampoline()
+
+//go:cgo_import_dynamic libc_getpgid getpgid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+ r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpgrp_trampoline), 0, 0, 0)
+ pgrp = int(r0)
+ return
+}
+
+func libc_getpgrp_trampoline()
+
+//go:cgo_import_dynamic libc_getpgrp getpgrp "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+ r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getpid_trampoline), 0, 0, 0)
+ pid = int(r0)
+ return
+}
+
+func libc_getpid_trampoline()
+
+//go:cgo_import_dynamic libc_getpid getpid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+ r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getppid_trampoline), 0, 0, 0)
+ ppid = int(r0)
+ return
+}
+
+func libc_getppid_trampoline()
+
+//go:cgo_import_dynamic libc_getppid getppid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_getpriority_trampoline), uintptr(which), uintptr(who), 0)
+ prio = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_getpriority_trampoline()
+
+//go:cgo_import_dynamic libc_getpriority getpriority "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_getrlimit_trampoline()
+
+//go:cgo_import_dynamic libc_getrlimit getrlimit "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getrusage_trampoline), uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_getrusage_trampoline()
+
+//go:cgo_import_dynamic libc_getrusage getrusage "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+ r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_getsid_trampoline), uintptr(pid), 0, 0)
+ sid = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_getsid_trampoline()
+
+//go:cgo_import_dynamic libc_getsid getsid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+ r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_getuid_trampoline), 0, 0, 0)
+ uid = int(r0)
+ return
+}
+
+func libc_getuid_trampoline()
+
+//go:cgo_import_dynamic libc_getuid getuid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+ r0, _, _ := rawSyscall(abi.FuncPCABI0(libc_issetugid_trampoline), 0, 0, 0)
+ tainted = bool(r0 != 0)
+ return
+}
+
+func libc_issetugid_trampoline()
+
+//go:cgo_import_dynamic libc_issetugid issetugid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_kqueue_trampoline), 0, 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_kqueue_trampoline()
+
+//go:cgo_import_dynamic libc_kqueue kqueue "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_lchown_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_lchown_trampoline()
+
+//go:cgo_import_dynamic libc_lchown lchown "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(link)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_link_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_link_trampoline()
+
+//go:cgo_import_dynamic libc_link link "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_listen_trampoline), uintptr(s), uintptr(backlog), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_listen_trampoline()
+
+//go:cgo_import_dynamic libc_listen listen "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_mkdir_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_mkdir_trampoline()
+
+//go:cgo_import_dynamic libc_mkdir mkdir "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_mkfifo_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_mkfifo_trampoline()
+
+//go:cgo_import_dynamic libc_mkfifo mkfifo "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_mknod_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_mknod_trampoline()
+
+//go:cgo_import_dynamic libc_mknod mknod "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(b) > 0 {
+ _p0 = unsafe.Pointer(&b[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_mlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_mlock_trampoline()
+
+//go:cgo_import_dynamic libc_mlock mlock "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_mlockall_trampoline), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_mlockall_trampoline()
+
+//go:cgo_import_dynamic libc_mlockall mlockall "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+ var _p0 unsafe.Pointer
+ if len(b) > 0 {
+ _p0 = unsafe.Pointer(&b[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_mprotect_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(prot))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_mprotect_trampoline()
+
+//go:cgo_import_dynamic libc_mprotect mprotect "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func msync(b []byte, flags int) (err error) {
+ var _p0 unsafe.Pointer
+ if len(b) > 0 {
+ _p0 = unsafe.Pointer(&b[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_msync_trampoline), uintptr(_p0), uintptr(len(b)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_msync_trampoline()
+
+//go:cgo_import_dynamic libc_msync msync "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(b) > 0 {
+ _p0 = unsafe.Pointer(&b[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_munlock_trampoline), uintptr(_p0), uintptr(len(b)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_munlock_trampoline()
+
+//go:cgo_import_dynamic libc_munlock munlock "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_munlockall_trampoline), 0, 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_munlockall_trampoline()
+
+//go:cgo_import_dynamic libc_munlockall munlockall "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_open_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_open_trampoline()
+
+//go:cgo_import_dynamic libc_open open "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_pathconf_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+ val = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_pathconf_trampoline()
+
+//go:cgo_import_dynamic libc_pathconf pathconf "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pread(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pread_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_pread_trampoline()
+
+//go:cgo_import_dynamic libc_pread pread "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pwrite(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := syscall6(abi.FuncPCABI0(libc_pwrite_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_pwrite_trampoline()
+
+//go:cgo_import_dynamic libc_pwrite pwrite "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_read_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_read_trampoline()
+
+//go:cgo_import_dynamic libc_read read "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readdir_r(dir uintptr, entry *Dirent, result **Dirent) (res Errno) {
+ r0, _, _ := syscall(abi.FuncPCABI0(libc_readdir_r_trampoline), uintptr(dir), uintptr(unsafe.Pointer(entry)), uintptr(unsafe.Pointer(result)))
+ res = Errno(r0)
+ return
+}
+
+func libc_readdir_r_trampoline()
+
+//go:cgo_import_dynamic libc_readdir_r readdir_r "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(buf) > 0 {
+ _p1 = unsafe.Pointer(&buf[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_readlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_readlink_trampoline()
+
+//go:cgo_import_dynamic libc_readlink readlink "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(from)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(to)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_rename_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_rename_trampoline()
+
+//go:cgo_import_dynamic libc_rename rename "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_revoke_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_revoke_trampoline()
+
+//go:cgo_import_dynamic libc_revoke revoke "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_rmdir_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_rmdir_trampoline()
+
+//go:cgo_import_dynamic libc_rmdir rmdir "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+ r0, _, e1 := syscallX(abi.FuncPCABI0(libc_lseek_trampoline), uintptr(fd), uintptr(offset), uintptr(whence))
+ newoffset = int64(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_lseek_trampoline()
+
+//go:cgo_import_dynamic libc_lseek lseek "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+ _, _, e1 := syscall6(abi.FuncPCABI0(libc_select_trampoline), uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_select_trampoline()
+
+//go:cgo_import_dynamic libc_select select "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_setegid_trampoline), uintptr(egid), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setegid_trampoline()
+
+//go:cgo_import_dynamic libc_setegid setegid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_seteuid_trampoline), uintptr(euid), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_seteuid_trampoline()
+
+//go:cgo_import_dynamic libc_seteuid seteuid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setgid_trampoline), uintptr(gid), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setgid_trampoline()
+
+//go:cgo_import_dynamic libc_setgid setgid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_setlogin_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setlogin_trampoline()
+
+//go:cgo_import_dynamic libc_setlogin setlogin "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setpgid_trampoline), uintptr(pid), uintptr(pgid), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setpgid_trampoline()
+
+//go:cgo_import_dynamic libc_setpgid setpgid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_setpriority_trampoline), uintptr(which), uintptr(who), uintptr(prio))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setpriority_trampoline()
+
+//go:cgo_import_dynamic libc_setpriority setpriority "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setprivexec(flag int) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_setprivexec_trampoline), uintptr(flag), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setprivexec_trampoline()
+
+//go:cgo_import_dynamic libc_setprivexec setprivexec "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setregid_trampoline), uintptr(rgid), uintptr(egid), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setregid_trampoline()
+
+//go:cgo_import_dynamic libc_setregid setregid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setreuid_trampoline), uintptr(ruid), uintptr(euid), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setreuid_trampoline()
+
+//go:cgo_import_dynamic libc_setreuid setreuid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setrlimit(which int, lim *Rlimit) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setrlimit_trampoline), uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setrlimit_trampoline()
+
+//go:cgo_import_dynamic libc_setrlimit setrlimit "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+ r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setsid_trampoline), 0, 0, 0)
+ pid = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setsid_trampoline()
+
+//go:cgo_import_dynamic libc_setsid setsid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_settimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_settimeofday_trampoline()
+
+//go:cgo_import_dynamic libc_settimeofday settimeofday "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_setuid_trampoline), uintptr(uid), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_setuid_trampoline()
+
+//go:cgo_import_dynamic libc_setuid setuid "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(link)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_symlink_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_symlink_trampoline()
+
+//go:cgo_import_dynamic libc_symlink symlink "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_sync_trampoline), 0, 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_sync_trampoline()
+
+//go:cgo_import_dynamic libc_sync sync "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_truncate_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_truncate_trampoline()
+
+//go:cgo_import_dynamic libc_truncate truncate "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+ r0, _, _ := syscall(abi.FuncPCABI0(libc_umask_trampoline), uintptr(newmask), 0, 0)
+ oldmask = int(r0)
+ return
+}
+
+func libc_umask_trampoline()
+
+//go:cgo_import_dynamic libc_umask umask "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Undelete(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_undelete_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_undelete_trampoline()
+
+//go:cgo_import_dynamic libc_undelete undelete "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_unlink_trampoline), uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_unlink_trampoline()
+
+//go:cgo_import_dynamic libc_unlink unlink "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_unmount_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_unmount_trampoline()
+
+//go:cgo_import_dynamic libc_unmount unmount "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_write_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(p)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_write_trampoline()
+
+//go:cgo_import_dynamic libc_write write "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writev(fd int, iovecs []Iovec) (cnt uintptr, err error) {
+ var _p0 unsafe.Pointer
+ if len(iovecs) > 0 {
+ _p0 = unsafe.Pointer(&iovecs[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := syscallX(abi.FuncPCABI0(libc_writev_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(iovecs)))
+ cnt = uintptr(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_writev_trampoline()
+
+//go:cgo_import_dynamic libc_writev writev "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+ r0, _, e1 := syscall6X(abi.FuncPCABI0(libc_mmap_trampoline), uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+ ret = uintptr(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_mmap_trampoline()
+
+//go:cgo_import_dynamic libc_mmap mmap "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_munmap_trampoline), uintptr(addr), uintptr(length), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_munmap_trampoline()
+
+//go:cgo_import_dynamic libc_munmap munmap "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fork() (pid int, err error) {
+ r0, _, e1 := rawSyscall(abi.FuncPCABI0(libc_fork_trampoline), 0, 0, 0)
+ pid = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_fork_trampoline()
+
+//go:cgo_import_dynamic libc_fork fork "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ioctl(fd int, req int, arg int) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_ioctl_trampoline()
+
+//go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_ioctl_trampoline), uintptr(fd), uintptr(req), uintptr(arg))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func execve(path *byte, argv **byte, envp **byte) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_execve_trampoline), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(argv)), uintptr(unsafe.Pointer(envp)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_execve_trampoline()
+
+//go:cgo_import_dynamic libc_execve execve "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func exit(res int) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_exit_trampoline), uintptr(res), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_exit_trampoline()
+
+//go:cgo_import_dynamic libc_exit exit "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+ var _p0 unsafe.Pointer
+ if len(mib) > 0 {
+ _p0 = unsafe.Pointer(&mib[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := syscall6(abi.FuncPCABI0(libc_sysctl_trampoline), uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_sysctl_trampoline()
+
+//go:cgo_import_dynamic libc_sysctl sysctl "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) {
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_fcntl_trampoline), uintptr(fd), uintptr(cmd), uintptr(arg))
+ val = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func unlinkat(fd int, path string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_unlinkat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_unlinkat_trampoline()
+
+//go:cgo_import_dynamic libc_unlinkat unlinkat "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func openat(fd int, path string, flags int, perm uint32) (fdret int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := syscall6(abi.FuncPCABI0(libc_openat_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(perm), 0, 0)
+ fdret = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_openat_trampoline()
+
+//go:cgo_import_dynamic libc_openat openat "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getcwd(buf []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := syscall(abi.FuncPCABI0(libc_getcwd_trampoline), uintptr(_p0), uintptr(len(buf)), 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_getcwd_trampoline()
+
+//go:cgo_import_dynamic libc_getcwd getcwd "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_fstat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_fstat64_trampoline()
+
+//go:cgo_import_dynamic libc_fstat64 fstat64 "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_fstatfs64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_fstatfs64_trampoline()
+
+//go:cgo_import_dynamic libc_fstatfs64 fstatfs64 "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tp *Timeval) (err error) {
+ _, _, e1 := rawSyscall(abi.FuncPCABI0(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_gettimeofday_trampoline()
+
+//go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_lstat64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_lstat64_trampoline()
+
+//go:cgo_import_dynamic libc_lstat64 lstat64 "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_stat64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_stat64_trampoline()
+
+//go:cgo_import_dynamic libc_stat64 stat64 "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall(abi.FuncPCABI0(libc_statfs64_trampoline), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_statfs64_trampoline()
+
+//go:cgo_import_dynamic libc_statfs64 statfs64 "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := syscall6(abi.FuncPCABI0(libc_fstatat64_trampoline), uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_fstatat64_trampoline()
+
+//go:cgo_import_dynamic libc_fstatat64 fstatat64 "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+//go:nosplit
+func ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) {
+ _, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func libc_ptrace_trampoline()
+
+//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+//go:nosplit
+func ptrace1Ptr(request int, pid int, addr unsafe.Pointer, data uintptr) (err error) {
+ _, _, e1 := syscall6(abi.FuncPCABI0(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/contrib/go/_std_1.20/src/syscall/zsyscall_darwin_amd64.s b/contrib/go/_std_1.21/src/syscall/zsyscall_darwin_amd64.s
index 90e51fb9a4..90e51fb9a4 100644
--- a/contrib/go/_std_1.20/src/syscall/zsyscall_darwin_amd64.s
+++ b/contrib/go/_std_1.21/src/syscall/zsyscall_darwin_amd64.s
diff --git a/contrib/go/_std_1.21/src/syscall/zsyscall_linux_amd64.go b/contrib/go/_std_1.21/src/syscall/zsyscall_linux_amd64.go
new file mode 100644
index 0000000000..c3ee372fec
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/zsyscall_linux_amd64.go
@@ -0,0 +1,1658 @@
+// mksyscall.pl -tags linux,amd64 syscall_linux.go syscall_linux_amd64.go
+// Code generated by the command above; DO NOT EDIT.
+
+//go:build linux && amd64
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func faccessat(dirfd int, path string, mode uint32) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fchmodat(dirfd int, path string, mode uint32) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(oldpath)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(newpath)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_LINKAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe2(p *[2]_C_int, flags int) (err error) {
+ _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(buf) > 0 {
+ _p1 = unsafe.Pointer(&buf[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(oldpath)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(newpath)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func unlinkat(dirfd int, path string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getcwd(buf []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+ r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+ wpid = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
+ _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) {
+ _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(arg)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(source)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(target)
+ if err != nil {
+ return
+ }
+ var _p2 *byte
+ _p2, err = BytePtrFromString(fstype)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Acct(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtimex(buf *Timex) (state int, err error) {
+ r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0)
+ state = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+ _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup3(oldfd int, newfd int, flags int) (err error) {
+ _, _, e1 := Syscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate1(flag int) (fd int, err error) {
+ r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+ _, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
+ _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+ _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+ _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+ r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+ val = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fdatasync(fd int) (err error) {
+ _, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+ _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+ _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdents(fd int, buf []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+ r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+ pgid = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+ r0, _ := rawSyscallNoError(SYS_GETPID, 0, 0, 0)
+ pid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+ r0, _ := rawSyscallNoError(SYS_GETPPID, 0, 0, 0)
+ ppid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+ r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+ prio = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+ _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettid() (tid int) {
+ r0, _ := rawSyscallNoError(SYS_GETTID, 0, 0, 0)
+ tid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(attr)
+ if err != nil {
+ return
+ }
+ var _p2 unsafe.Pointer
+ if len(dest) > 0 {
+ _p2 = unsafe.Pointer(&dest[0])
+ } else {
+ _p2 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0)
+ sz = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(pathname)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
+ watchdesc = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit1(flags int) (fd int, err error) {
+ r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
+ r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0)
+ success = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, sig Signal) (err error) {
+ _, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Klogctl(typ int, buf []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listxattr(path string, dest []byte) (sz int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(dest) > 0 {
+ _p1 = unsafe.Pointer(&dest[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
+ sz = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+ _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func PivotRoot(newroot string, putold string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(newroot)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(putold)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func prlimit1(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
+ _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Removexattr(path string, attr string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(attr)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setdomainname(p []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sethostname(p []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+ _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+ r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+ pid = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tv *Timeval) (err error) {
+ _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+ _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setxattr(path string, attr string, data []byte, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(attr)
+ if err != nil {
+ return
+ }
+ var _p2 unsafe.Pointer
+ if len(data) > 0 {
+ _p2 = unsafe.Pointer(&data[0])
+ } else {
+ _p2 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() {
+ Syscall(SYS_SYNC, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sysinfo(info *Sysinfo_t) (err error) {
+ _, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
+ r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
+ n = int64(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tgkill(tgid int, tid int, sig Signal) (err error) {
+ _, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Times(tms *Tms) (ticks uintptr, err error) {
+ r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
+ ticks = uintptr(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(mask int) (oldmask int) {
+ r0, _ := rawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0)
+ oldmask = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Uname(buf *Utsname) (err error) {
+ _, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(target string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(target)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unshare(flags int) (err error) {
+ _, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func exitThread(code int) (err error) {
+ _, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, p *byte, np int) (n int, err error) {
+ r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, p *byte, np int) (n int, err error) {
+ r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+ _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Madvise(b []byte, advice int) (err error) {
+ var _p0 unsafe.Pointer
+ if len(b) > 0 {
+ _p0 = unsafe.Pointer(&b[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+ var _p0 unsafe.Pointer
+ if len(b) > 0 {
+ _p0 = unsafe.Pointer(&b[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(b) > 0 {
+ _p0 = unsafe.Pointer(&b[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(b) > 0 {
+ _p0 = unsafe.Pointer(&b[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+ _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+ _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(oldfd int, newfd int) (err error) {
+ _, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+ _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+ _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, buf *Statfs_t) (err error) {
+ _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+ _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+ r0, _ := rawSyscallNoError(SYS_GETEGID, 0, 0, 0)
+ egid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (euid int) {
+ r0, _ := rawSyscallNoError(SYS_GETEUID, 0, 0, 0)
+ euid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+ r0, _ := rawSyscallNoError(SYS_GETGID, 0, 0, 0)
+ gid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(resource int, rlim *Rlimit) (err error) {
+ _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+ r0, _ := rawSyscallNoError(SYS_GETUID, 0, 0, 0)
+ uid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit() (fd int, err error) {
+ r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT, 0, 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ioperm(from int, num int, on int) (err error) {
+ _, _, e1 := Syscall(SYS_IOPERM, uintptr(from), uintptr(num), uintptr(on))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Iopl(level int) (err error) {
+ _, _, e1 := Syscall(SYS_IOPL, uintptr(level), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, n int) (err error) {
+ _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pause() (err error) {
+ _, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pread(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pwrite(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(oldpath)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(newpath)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (off int64, err error) {
+ r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
+ off = int64(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
+ r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+ r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
+ written = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsgid(gid int) (err error) {
+ _, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsuid(uid int) (err error) {
+ _, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setrlimit(resource int, rlim *Rlimit) (err error) {
+ _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(fd int, how int) (err error) {
+ _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
+ r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
+ n = int64(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, buf *Statfs_t) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func SyncFileRange(fd int, off int64, n int64, flags int) (err error) {
+ _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ustat(dev int, ubuf *Ustat_t) (err error) {
+ _, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
+ r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+ _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+ _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstatat(fd int, path string, stat *Stat_t, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_NEWFSTATAT, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(n int, list *_Gid_t) (nn int, err error) {
+ r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+ nn = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+ _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+ _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+ r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+ _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+ _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+ _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+ r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+ r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
+ r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset))
+ xaddr = uintptr(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(events) > 0 {
+ _p0 = unsafe.Pointer(&events[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimesat(dirfd int, path string, times *[2]Timeval) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Utime(path string, buf *Utimbuf) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, times *[2]Timeval) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/contrib/go/_std_1.21/src/syscall/zsyscall_linux_arm64.go b/contrib/go/_std_1.21/src/syscall/zsyscall_linux_arm64.go
new file mode 100644
index 0000000000..b7c7a38626
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/zsyscall_linux_arm64.go
@@ -0,0 +1,1573 @@
+// mksyscall.pl -tags linux,arm64 syscall_linux.go syscall_linux_arm64.go
+// Code generated by the command above; DO NOT EDIT.
+
+//go:build linux && arm64
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func faccessat(dirfd int, path string, mode uint32) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func faccessat2(dirfd int, path string, mode uint32, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(_SYS_faccessat2, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fchmodat(dirfd int, path string, mode uint32) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(oldpath)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(newpath)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_LINKAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe2(p *[2]_C_int, flags int) (err error) {
+ _, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlinkat(dirfd int, path string, buf []byte) (n int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(buf) > 0 {
+ _p1 = unsafe.Pointer(&buf[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_READLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func symlinkat(oldpath string, newdirfd int, newpath string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(oldpath)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(newpath)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_SYMLINKAT, uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func unlinkat(dirfd int, path string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec, flag int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getcwd(buf []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+ r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+ wpid = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
+ _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) {
+ _, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(arg)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(source)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(target)
+ if err != nil {
+ return
+ }
+ var _p2 *byte
+ _p2, err = BytePtrFromString(fstype)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Acct(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtimex(buf *Timex) (state int, err error) {
+ r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0)
+ state = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+ _, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup3(oldfd int, newfd int, flags int) (err error) {
+ _, _, e1 := Syscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate1(flag int) (fd int, err error) {
+ r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+ _, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
+ _, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+ _, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+ _, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+ r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+ val = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fdatasync(fd int) (err error) {
+ _, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+ _, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+ _, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdents(fd int, buf []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+ r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+ pgid = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+ r0, _ := rawSyscallNoError(SYS_GETPID, 0, 0, 0)
+ pid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+ r0, _ := rawSyscallNoError(SYS_GETPPID, 0, 0, 0)
+ ppid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+ r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+ prio = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+ _, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettid() (tid int) {
+ r0, _ := rawSyscallNoError(SYS_GETTID, 0, 0, 0)
+ tid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(attr)
+ if err != nil {
+ return
+ }
+ var _p2 unsafe.Pointer
+ if len(dest) > 0 {
+ _p2 = unsafe.Pointer(&dest[0])
+ } else {
+ _p2 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0)
+ sz = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(pathname)
+ if err != nil {
+ return
+ }
+ r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
+ watchdesc = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit1(flags int) (fd int, err error) {
+ r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
+ r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0)
+ success = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, sig Signal) (err error) {
+ _, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Klogctl(typ int, buf []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listxattr(path string, dest []byte) (sz int, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 unsafe.Pointer
+ if len(dest) > 0 {
+ _p1 = unsafe.Pointer(&dest[0])
+ } else {
+ _p1 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
+ sz = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+ _, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func PivotRoot(newroot string, putold string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(newroot)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(putold)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func prlimit1(pid int, resource int, newlimit *Rlimit, old *Rlimit) (err error) {
+ _, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(newlimit)), uintptr(unsafe.Pointer(old)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Removexattr(path string, attr string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(attr)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setdomainname(p []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sethostname(p []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+ _, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+ r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+ pid = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tv *Timeval) (err error) {
+ _, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+ _, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setxattr(path string, attr string, data []byte, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(attr)
+ if err != nil {
+ return
+ }
+ var _p2 unsafe.Pointer
+ if len(data) > 0 {
+ _p2 = unsafe.Pointer(&data[0])
+ } else {
+ _p2 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() {
+ Syscall(SYS_SYNC, 0, 0, 0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sysinfo(info *Sysinfo_t) (err error) {
+ _, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
+ r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
+ n = int64(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tgkill(tgid int, tid int, sig Signal) (err error) {
+ _, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Times(tms *Tms) (ticks uintptr, err error) {
+ r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
+ ticks = uintptr(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(mask int) (oldmask int) {
+ r0, _ := rawSyscallNoError(SYS_UMASK, uintptr(mask), 0, 0)
+ oldmask = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Uname(buf *Utsname) (err error) {
+ _, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(target string, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(target)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unshare(flags int) (err error) {
+ _, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func exitThread(code int) (err error) {
+ _, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, p *byte, np int) (n int, err error) {
+ r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, p *byte, np int) (n int, err error) {
+ r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+ _, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Madvise(b []byte, advice int) (err error) {
+ var _p0 unsafe.Pointer
+ if len(b) > 0 {
+ _p0 = unsafe.Pointer(&b[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+ var _p0 unsafe.Pointer
+ if len(b) > 0 {
+ _p0 = unsafe.Pointer(&b[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(b) > 0 {
+ _p0 = unsafe.Pointer(&b[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+ var _p0 unsafe.Pointer
+ if len(b) > 0 {
+ _p0 = unsafe.Pointer(&b[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+ _, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+ _, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(events) > 0 {
+ _p0 = unsafe.Pointer(&events[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_EPOLL_PWAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+ _, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+ _, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_FSTATAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, buf *Statfs_t) (err error) {
+ _, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+ _, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+ r0, _ := rawSyscallNoError(SYS_GETEGID, 0, 0, 0)
+ egid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (euid int) {
+ r0, _ := rawSyscallNoError(SYS_GETEUID, 0, 0, 0)
+ euid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+ r0, _ := rawSyscallNoError(SYS_GETGID, 0, 0, 0)
+ gid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getrlimit(resource int, rlim *Rlimit) (err error) {
+ _, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+ r0, _ := rawSyscallNoError(SYS_GETUID, 0, 0, 0)
+ uid = int(r0)
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, n int) (err error) {
+ _, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pread(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pwrite(fd int, p []byte, offset int64) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(oldpath)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(newpath)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (off int64, err error) {
+ r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
+ off = int64(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+ r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
+ written = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsgid(gid int) (err error) {
+ _, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsuid(uid int) (err error) {
+ _, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setrlimit1(resource int, rlim *Rlimit) (err error) {
+ _, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(fd int, how int) (err error) {
+ _, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
+ r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
+ n = int64(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, buf *Statfs_t) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func SyncFileRange(fd int, off int64, n int64, flags int) (err error) {
+ _, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE2, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(path)
+ if err != nil {
+ return
+ }
+ _, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
+ r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+ _, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+ _, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(n int, list *_Gid_t) (nn int, err error) {
+ r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+ nn = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+ _, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+ _, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+ r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+ _, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+ _, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+ _, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+ var _p0 unsafe.Pointer
+ if len(p) > 0 {
+ _p0 = unsafe.Pointer(&p[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+ var _p0 unsafe.Pointer
+ if len(buf) > 0 {
+ _p0 = unsafe.Pointer(&buf[0])
+ } else {
+ _p0 = unsafe.Pointer(&_zero)
+ }
+ _, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+ r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+ r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
+ r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset))
+ xaddr = uintptr(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_t) (n int, err error) {
+ r0, _, e1 := Syscall6(SYS_PSELECT6, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)))
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+ _, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ppoll(fds *pollFd, nfds int, timeout *Timespec, sigmask *sigset_t) (n int, err error) {
+ r0, _, e1 := Syscall6(SYS_PPOLL, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(unsafe.Pointer(timeout)), uintptr(unsafe.Pointer(sigmask)), 0, 0)
+ n = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/contrib/go/_std_1.21/src/syscall/zsyscall_windows.go b/contrib/go/_std_1.21/src/syscall/zsyscall_windows.go
new file mode 100644
index 0000000000..68c29d809e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/syscall/zsyscall_windows.go
@@ -0,0 +1,1478 @@
+// Code generated by 'go generate'; DO NOT EDIT.
+
+package syscall
+
+import (
+ "internal/syscall/windows/sysdll"
+ "unsafe"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = Errno(errnoERROR_IO_PENDING)
+ errERROR_EINVAL error = EINVAL
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e Errno) error {
+ switch e {
+ case 0:
+ return errERROR_EINVAL
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
+var (
+ modadvapi32 = NewLazyDLL(sysdll.Add("advapi32.dll"))
+ modcrypt32 = NewLazyDLL(sysdll.Add("crypt32.dll"))
+ moddnsapi = NewLazyDLL(sysdll.Add("dnsapi.dll"))
+ modiphlpapi = NewLazyDLL(sysdll.Add("iphlpapi.dll"))
+ modkernel32 = NewLazyDLL(sysdll.Add("kernel32.dll"))
+ modmswsock = NewLazyDLL(sysdll.Add("mswsock.dll"))
+ modnetapi32 = NewLazyDLL(sysdll.Add("netapi32.dll"))
+ modntdll = NewLazyDLL(sysdll.Add("ntdll.dll"))
+ modsecur32 = NewLazyDLL(sysdll.Add("secur32.dll"))
+ modshell32 = NewLazyDLL(sysdll.Add("shell32.dll"))
+ moduserenv = NewLazyDLL(sysdll.Add("userenv.dll"))
+ modws2_32 = NewLazyDLL(sysdll.Add("ws2_32.dll"))
+
+ procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
+ procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW")
+ procCopySid = modadvapi32.NewProc("CopySid")
+ procCreateProcessAsUserW = modadvapi32.NewProc("CreateProcessAsUserW")
+ procCryptAcquireContextW = modadvapi32.NewProc("CryptAcquireContextW")
+ procCryptGenRandom = modadvapi32.NewProc("CryptGenRandom")
+ procCryptReleaseContext = modadvapi32.NewProc("CryptReleaseContext")
+ procGetLengthSid = modadvapi32.NewProc("GetLengthSid")
+ procGetTokenInformation = modadvapi32.NewProc("GetTokenInformation")
+ procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
+ procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW")
+ procOpenProcessToken = modadvapi32.NewProc("OpenProcessToken")
+ procRegCloseKey = modadvapi32.NewProc("RegCloseKey")
+ procRegEnumKeyExW = modadvapi32.NewProc("RegEnumKeyExW")
+ procRegOpenKeyExW = modadvapi32.NewProc("RegOpenKeyExW")
+ procRegQueryInfoKeyW = modadvapi32.NewProc("RegQueryInfoKeyW")
+ procRegQueryValueExW = modadvapi32.NewProc("RegQueryValueExW")
+ procCertAddCertificateContextToStore = modcrypt32.NewProc("CertAddCertificateContextToStore")
+ procCertCloseStore = modcrypt32.NewProc("CertCloseStore")
+ procCertCreateCertificateContext = modcrypt32.NewProc("CertCreateCertificateContext")
+ procCertEnumCertificatesInStore = modcrypt32.NewProc("CertEnumCertificatesInStore")
+ procCertFreeCertificateChain = modcrypt32.NewProc("CertFreeCertificateChain")
+ procCertFreeCertificateContext = modcrypt32.NewProc("CertFreeCertificateContext")
+ procCertGetCertificateChain = modcrypt32.NewProc("CertGetCertificateChain")
+ procCertOpenStore = modcrypt32.NewProc("CertOpenStore")
+ procCertOpenSystemStoreW = modcrypt32.NewProc("CertOpenSystemStoreW")
+ procCertVerifyCertificateChainPolicy = modcrypt32.NewProc("CertVerifyCertificateChainPolicy")
+ procDnsNameCompare_W = moddnsapi.NewProc("DnsNameCompare_W")
+ procDnsQuery_W = moddnsapi.NewProc("DnsQuery_W")
+ procDnsRecordListFree = moddnsapi.NewProc("DnsRecordListFree")
+ procGetAdaptersInfo = modiphlpapi.NewProc("GetAdaptersInfo")
+ procGetIfEntry = modiphlpapi.NewProc("GetIfEntry")
+ procCancelIo = modkernel32.NewProc("CancelIo")
+ procCancelIoEx = modkernel32.NewProc("CancelIoEx")
+ procCloseHandle = modkernel32.NewProc("CloseHandle")
+ procCreateDirectoryW = modkernel32.NewProc("CreateDirectoryW")
+ procCreateFileMappingW = modkernel32.NewProc("CreateFileMappingW")
+ procCreateFileW = modkernel32.NewProc("CreateFileW")
+ procCreateHardLinkW = modkernel32.NewProc("CreateHardLinkW")
+ procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
+ procCreatePipe = modkernel32.NewProc("CreatePipe")
+ procCreateProcessW = modkernel32.NewProc("CreateProcessW")
+ procCreateSymbolicLinkW = modkernel32.NewProc("CreateSymbolicLinkW")
+ procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot")
+ procDeleteFileW = modkernel32.NewProc("DeleteFileW")
+ procDeleteProcThreadAttributeList = modkernel32.NewProc("DeleteProcThreadAttributeList")
+ procDeviceIoControl = modkernel32.NewProc("DeviceIoControl")
+ procDuplicateHandle = modkernel32.NewProc("DuplicateHandle")
+ procExitProcess = modkernel32.NewProc("ExitProcess")
+ procFindClose = modkernel32.NewProc("FindClose")
+ procFindFirstFileW = modkernel32.NewProc("FindFirstFileW")
+ procFindNextFileW = modkernel32.NewProc("FindNextFileW")
+ procFlushFileBuffers = modkernel32.NewProc("FlushFileBuffers")
+ procFlushViewOfFile = modkernel32.NewProc("FlushViewOfFile")
+ procFormatMessageW = modkernel32.NewProc("FormatMessageW")
+ procFreeEnvironmentStringsW = modkernel32.NewProc("FreeEnvironmentStringsW")
+ procFreeLibrary = modkernel32.NewProc("FreeLibrary")
+ procGetCommandLineW = modkernel32.NewProc("GetCommandLineW")
+ procGetComputerNameW = modkernel32.NewProc("GetComputerNameW")
+ procGetConsoleMode = modkernel32.NewProc("GetConsoleMode")
+ procGetCurrentDirectoryW = modkernel32.NewProc("GetCurrentDirectoryW")
+ procGetCurrentProcess = modkernel32.NewProc("GetCurrentProcess")
+ procGetCurrentProcessId = modkernel32.NewProc("GetCurrentProcessId")
+ procGetEnvironmentStringsW = modkernel32.NewProc("GetEnvironmentStringsW")
+ procGetEnvironmentVariableW = modkernel32.NewProc("GetEnvironmentVariableW")
+ procGetExitCodeProcess = modkernel32.NewProc("GetExitCodeProcess")
+ procGetFileAttributesExW = modkernel32.NewProc("GetFileAttributesExW")
+ procGetFileAttributesW = modkernel32.NewProc("GetFileAttributesW")
+ procGetFileInformationByHandle = modkernel32.NewProc("GetFileInformationByHandle")
+ procGetFileType = modkernel32.NewProc("GetFileType")
+ procGetFinalPathNameByHandleW = modkernel32.NewProc("GetFinalPathNameByHandleW")
+ procGetFullPathNameW = modkernel32.NewProc("GetFullPathNameW")
+ procGetLastError = modkernel32.NewProc("GetLastError")
+ procGetLongPathNameW = modkernel32.NewProc("GetLongPathNameW")
+ procGetProcAddress = modkernel32.NewProc("GetProcAddress")
+ procGetProcessTimes = modkernel32.NewProc("GetProcessTimes")
+ procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
+ procGetShortPathNameW = modkernel32.NewProc("GetShortPathNameW")
+ procGetStartupInfoW = modkernel32.NewProc("GetStartupInfoW")
+ procGetStdHandle = modkernel32.NewProc("GetStdHandle")
+ procGetSystemTimeAsFileTime = modkernel32.NewProc("GetSystemTimeAsFileTime")
+ procGetTempPathW = modkernel32.NewProc("GetTempPathW")
+ procGetTimeZoneInformation = modkernel32.NewProc("GetTimeZoneInformation")
+ procGetVersion = modkernel32.NewProc("GetVersion")
+ procInitializeProcThreadAttributeList = modkernel32.NewProc("InitializeProcThreadAttributeList")
+ procLoadLibraryW = modkernel32.NewProc("LoadLibraryW")
+ procLocalFree = modkernel32.NewProc("LocalFree")
+ procMapViewOfFile = modkernel32.NewProc("MapViewOfFile")
+ procMoveFileW = modkernel32.NewProc("MoveFileW")
+ procOpenProcess = modkernel32.NewProc("OpenProcess")
+ procPostQueuedCompletionStatus = modkernel32.NewProc("PostQueuedCompletionStatus")
+ procProcess32FirstW = modkernel32.NewProc("Process32FirstW")
+ procProcess32NextW = modkernel32.NewProc("Process32NextW")
+ procReadConsoleW = modkernel32.NewProc("ReadConsoleW")
+ procReadDirectoryChangesW = modkernel32.NewProc("ReadDirectoryChangesW")
+ procReadFile = modkernel32.NewProc("ReadFile")
+ procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW")
+ procSetCurrentDirectoryW = modkernel32.NewProc("SetCurrentDirectoryW")
+ procSetEndOfFile = modkernel32.NewProc("SetEndOfFile")
+ procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW")
+ procSetFileAttributesW = modkernel32.NewProc("SetFileAttributesW")
+ procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
+ procSetFilePointer = modkernel32.NewProc("SetFilePointer")
+ procSetFileTime = modkernel32.NewProc("SetFileTime")
+ procSetHandleInformation = modkernel32.NewProc("SetHandleInformation")
+ procTerminateProcess = modkernel32.NewProc("TerminateProcess")
+ procUnmapViewOfFile = modkernel32.NewProc("UnmapViewOfFile")
+ procUpdateProcThreadAttribute = modkernel32.NewProc("UpdateProcThreadAttribute")
+ procVirtualLock = modkernel32.NewProc("VirtualLock")
+ procVirtualUnlock = modkernel32.NewProc("VirtualUnlock")
+ procWaitForSingleObject = modkernel32.NewProc("WaitForSingleObject")
+ procWriteConsoleW = modkernel32.NewProc("WriteConsoleW")
+ procWriteFile = modkernel32.NewProc("WriteFile")
+ procAcceptEx = modmswsock.NewProc("AcceptEx")
+ procGetAcceptExSockaddrs = modmswsock.NewProc("GetAcceptExSockaddrs")
+ procTransmitFile = modmswsock.NewProc("TransmitFile")
+ procNetApiBufferFree = modnetapi32.NewProc("NetApiBufferFree")
+ procNetGetJoinInformation = modnetapi32.NewProc("NetGetJoinInformation")
+ procNetUserGetInfo = modnetapi32.NewProc("NetUserGetInfo")
+ procRtlGetNtVersionNumbers = modntdll.NewProc("RtlGetNtVersionNumbers")
+ procGetUserNameExW = modsecur32.NewProc("GetUserNameExW")
+ procTranslateNameW = modsecur32.NewProc("TranslateNameW")
+ procCommandLineToArgvW = modshell32.NewProc("CommandLineToArgvW")
+ procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW")
+ procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW")
+ procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW")
+ procWSACleanup = modws2_32.NewProc("WSACleanup")
+ procWSAEnumProtocolsW = modws2_32.NewProc("WSAEnumProtocolsW")
+ procWSAIoctl = modws2_32.NewProc("WSAIoctl")
+ procWSARecv = modws2_32.NewProc("WSARecv")
+ procWSARecvFrom = modws2_32.NewProc("WSARecvFrom")
+ procWSASend = modws2_32.NewProc("WSASend")
+ procWSASendTo = modws2_32.NewProc("WSASendTo")
+ procWSAStartup = modws2_32.NewProc("WSAStartup")
+ procbind = modws2_32.NewProc("bind")
+ procclosesocket = modws2_32.NewProc("closesocket")
+ procconnect = modws2_32.NewProc("connect")
+ procgethostbyname = modws2_32.NewProc("gethostbyname")
+ procgetpeername = modws2_32.NewProc("getpeername")
+ procgetprotobyname = modws2_32.NewProc("getprotobyname")
+ procgetservbyname = modws2_32.NewProc("getservbyname")
+ procgetsockname = modws2_32.NewProc("getsockname")
+ procgetsockopt = modws2_32.NewProc("getsockopt")
+ proclisten = modws2_32.NewProc("listen")
+ procntohs = modws2_32.NewProc("ntohs")
+ procsetsockopt = modws2_32.NewProc("setsockopt")
+ procshutdown = modws2_32.NewProc("shutdown")
+ procsocket = modws2_32.NewProc("socket")
+)
+
+func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) {
+ r1, _, e1 := Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) {
+ r1, _, e1 := Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) {
+ r1, _, e1 := Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CreateProcessAsUser(token Token, appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) {
+ var _p0 uint32
+ if inheritHandles {
+ _p0 = 1
+ }
+ r1, _, e1 := Syscall12(procCreateProcessAsUserW.Addr(), 11, uintptr(token), uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) {
+ r1, _, e1 := Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) {
+ r1, _, e1 := Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CryptReleaseContext(provhandle Handle, flags uint32) (err error) {
+ r1, _, e1 := Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetLengthSid(sid *SID) (len uint32) {
+ r0, _, _ := Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
+ len = uint32(r0)
+ return
+}
+
+func GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) {
+ r1, _, e1 := Syscall6(procGetTokenInformation.Addr(), 5, uintptr(t), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
+ r1, _, e1 := Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
+ r1, _, e1 := Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func OpenProcessToken(h Handle, access uint32, token *Token) (err error) {
+ r1, _, e1 := Syscall(procOpenProcessToken.Addr(), 3, uintptr(h), uintptr(access), uintptr(unsafe.Pointer(token)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func RegCloseKey(key Handle) (regerrno error) {
+ r0, _, _ := Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0)
+ if r0 != 0 {
+ regerrno = Errno(r0)
+ }
+ return
+}
+
+func regEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) {
+ r0, _, _ := Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0)
+ if r0 != 0 {
+ regerrno = Errno(r0)
+ }
+ return
+}
+
+func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) {
+ r0, _, _ := Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0)
+ if r0 != 0 {
+ regerrno = Errno(r0)
+ }
+ return
+}
+
+func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) {
+ r0, _, _ := Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime)))
+ if r0 != 0 {
+ regerrno = Errno(r0)
+ }
+ return
+}
+
+func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
+ r0, _, _ := Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)))
+ if r0 != 0 {
+ regerrno = Errno(r0)
+ }
+ return
+}
+
+func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) {
+ r1, _, e1 := Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CertCloseStore(store Handle, flags uint32) (err error) {
+ r1, _, e1 := Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) {
+ r0, _, e1 := Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen))
+ context = (*CertContext)(unsafe.Pointer(r0))
+ if context == nil {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) {
+ r0, _, e1 := Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0)
+ context = (*CertContext)(unsafe.Pointer(r0))
+ if context == nil {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CertFreeCertificateChain(ctx *CertChainContext) {
+ Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
+ return
+}
+
+func CertFreeCertificateContext(ctx *CertContext) (err error) {
+ r1, _, e1 := Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) {
+ r1, _, e1 := Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) {
+ r0, _, e1 := Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0)
+ handle = Handle(r0)
+ if handle == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) {
+ r0, _, e1 := Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0)
+ store = Handle(r0)
+ if store == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) {
+ r1, _, e1 := Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) {
+ r0, _, _ := Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0)
+ same = r0 != 0
+ return
+}
+
+func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
+ var _p0 *uint16
+ _p0, status = UTF16PtrFromString(name)
+ if status != nil {
+ return
+ }
+ return _DnsQuery(_p0, qtype, options, extra, qrs, pr)
+}
+
+func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
+ r0, _, _ := Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
+ if r0 != 0 {
+ status = Errno(r0)
+ }
+ return
+}
+
+func DnsRecordListFree(rl *DNSRecord, freetype uint32) {
+ Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0)
+ return
+}
+
+func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) {
+ r0, _, _ := Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0)
+ if r0 != 0 {
+ errcode = Errno(r0)
+ }
+ return
+}
+
+func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
+ r0, _, _ := Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0)
+ if r0 != 0 {
+ errcode = Errno(r0)
+ }
+ return
+}
+
+func CancelIo(s Handle) (err error) {
+ r1, _, e1 := Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CancelIoEx(s Handle, o *Overlapped) (err error) {
+ r1, _, e1 := Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CloseHandle(handle Handle) (err error) {
+ r1, _, e1 := Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) {
+ r1, _, e1 := Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
+ r0, _, e1 := Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
+ handle = Handle(r0)
+ if handle == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) {
+ r0, _, e1 := Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
+ handle = Handle(r0)
+ if handle == InvalidHandle {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) {
+ r1, _, e1 := Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved))
+ if r1&0xff == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+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 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) {
+ r1, _, e1 := Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) {
+ var _p0 uint32
+ if inheritHandles {
+ _p0 = 1
+ }
+ r1, _, e1 := Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) {
+ r1, _, e1 := Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags))
+ if r1&0xff == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) {
+ r0, _, e1 := Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0)
+ handle = Handle(r0)
+ if handle == InvalidHandle {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func DeleteFile(path *uint16) (err error) {
+ r1, _, e1 := Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func deleteProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST) {
+ Syscall(procDeleteProcThreadAttributeList.Addr(), 1, uintptr(unsafe.Pointer(attrlist)), 0, 0)
+ return
+}
+
+func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) {
+ r1, _, e1 := Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
+ var _p0 uint32
+ if bInheritHandle {
+ _p0 = 1
+ }
+ r1, _, e1 := Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func ExitProcess(exitcode uint32) {
+ Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0)
+ return
+}
+
+func FindClose(handle Handle) (err error) {
+ r1, _, e1 := Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) {
+ r0, _, e1 := Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0)
+ handle = Handle(r0)
+ if handle == InvalidHandle {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func findNextFile1(handle Handle, data *win32finddata1) (err error) {
+ r1, _, e1 := Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func FlushFileBuffers(handle Handle) (err error) {
+ r1, _, e1 := Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func FlushViewOfFile(addr uintptr, length uintptr) (err error) {
+ r1, _, e1 := Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func formatMessage(flags uint32, msgsrc uintptr, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) {
+ var _p0 *uint16
+ if len(buf) > 0 {
+ _p0 = &buf[0]
+ }
+ r0, _, e1 := Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0)
+ n = uint32(r0)
+ if n == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func FreeEnvironmentStrings(envs *uint16) (err error) {
+ r1, _, e1 := Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func FreeLibrary(handle Handle) (err error) {
+ r1, _, e1 := Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetCommandLine() (cmd *uint16) {
+ r0, _, _ := Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0)
+ cmd = (*uint16)(unsafe.Pointer(r0))
+ return
+}
+
+func GetComputerName(buf *uint16, n *uint32) (err error) {
+ r1, _, e1 := Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetConsoleMode(console Handle, mode *uint32) (err error) {
+ r1, _, e1 := Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) {
+ r0, _, e1 := Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
+ n = uint32(r0)
+ if n == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetCurrentProcess() (pseudoHandle Handle, err error) {
+ r0, _, e1 := Syscall(procGetCurrentProcess.Addr(), 0, 0, 0, 0)
+ pseudoHandle = Handle(r0)
+ if pseudoHandle == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getCurrentProcessId() (pid uint32) {
+ r0, _, _ := Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0)
+ pid = uint32(r0)
+ return
+}
+
+func GetEnvironmentStrings() (envs *uint16, err error) {
+ r0, _, e1 := Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0)
+ envs = (*uint16)(unsafe.Pointer(r0))
+ if envs == nil {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) {
+ r0, _, e1 := Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size))
+ n = uint32(r0)
+ if n == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) {
+ r1, _, e1 := Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) {
+ r1, _, e1 := Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetFileAttributes(name *uint16) (attrs uint32, err error) {
+ r0, _, e1 := Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+ attrs = uint32(r0)
+ if attrs == INVALID_FILE_ATTRIBUTES {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) {
+ r1, _, e1 := Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetFileType(filehandle Handle) (n uint32, err error) {
+ r0, _, e1 := Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0)
+ n = uint32(r0)
+ if n == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getFinalPathNameByHandle(file Handle, filePath *uint16, filePathSize uint32, flags uint32) (n uint32, err error) {
+ r0, _, e1 := Syscall6(procGetFinalPathNameByHandleW.Addr(), 4, uintptr(file), uintptr(unsafe.Pointer(filePath)), uintptr(filePathSize), uintptr(flags), 0, 0)
+ n = uint32(r0)
+ if n == 0 || n >= filePathSize {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) {
+ r0, _, e1 := Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0)
+ n = uint32(r0)
+ if n == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetLastError() (lasterr error) {
+ r0, _, _ := Syscall(procGetLastError.Addr(), 0, 0, 0, 0)
+ if r0 != 0 {
+ lasterr = Errno(r0)
+ }
+ return
+}
+
+func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) {
+ r0, _, e1 := Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen))
+ n = uint32(r0)
+ if n == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetProcAddress(module Handle, procname string) (proc uintptr, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(procname)
+ if err != nil {
+ return
+ }
+ return _GetProcAddress(module, _p0)
+}
+
+func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) {
+ r0, _, e1 := Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0)
+ proc = uintptr(r0)
+ if proc == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) {
+ r1, _, e1 := Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+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 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) {
+ r0, _, e1 := Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen))
+ n = uint32(r0)
+ if n == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetStartupInfo(startupInfo *StartupInfo) (err error) {
+ r1, _, e1 := Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetStdHandle(stdhandle int) (handle Handle, err error) {
+ r0, _, e1 := Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0)
+ handle = Handle(r0)
+ if handle == InvalidHandle {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetSystemTimeAsFileTime(time *Filetime) {
+ Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0)
+ return
+}
+
+func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) {
+ r0, _, e1 := Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
+ n = uint32(r0)
+ if n == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) {
+ r0, _, e1 := Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0)
+ rc = uint32(r0)
+ if rc == 0xffffffff {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetVersion() (ver uint32, err error) {
+ r0, _, e1 := Syscall(procGetVersion.Addr(), 0, 0, 0, 0)
+ ver = uint32(r0)
+ if ver == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func initializeProcThreadAttributeList(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, attrcount uint32, flags uint32, size *uintptr) (err error) {
+ r1, _, e1 := Syscall6(procInitializeProcThreadAttributeList.Addr(), 4, uintptr(unsafe.Pointer(attrlist)), uintptr(attrcount), uintptr(flags), uintptr(unsafe.Pointer(size)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func LoadLibrary(libname string) (handle Handle, err error) {
+ var _p0 *uint16
+ _p0, err = UTF16PtrFromString(libname)
+ if err != nil {
+ return
+ }
+ return _LoadLibrary(_p0)
+}
+
+func _LoadLibrary(libname *uint16) (handle Handle, err error) {
+ r0, _, e1 := Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0)
+ handle = Handle(r0)
+ if handle == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func LocalFree(hmem Handle) (handle Handle, err error) {
+ r0, _, e1 := Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0)
+ handle = Handle(r0)
+ if handle != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) {
+ r0, _, e1 := Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0)
+ addr = uintptr(r0)
+ if addr == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func MoveFile(from *uint16, to *uint16) (err error) {
+ r1, _, e1 := Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) {
+ var _p0 uint32
+ if inheritHandle {
+ _p0 = 1
+ }
+ r0, _, e1 := Syscall(procOpenProcess.Addr(), 3, uintptr(da), uintptr(_p0), uintptr(pid))
+ handle = Handle(r0)
+ if handle == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+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 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) {
+ r1, _, e1 := Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) {
+ r1, _, e1 := Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) {
+ r1, _, e1 := Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
+ var _p0 uint32
+ if watchSubTree {
+ _p0 = 1
+ }
+ r1, _, e1 := Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func readFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
+ var _p0 *byte
+ if len(buf) > 0 {
+ _p0 = &buf[0]
+ }
+ r1, _, e1 := Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func RemoveDirectory(path *uint16) (err error) {
+ r1, _, e1 := Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func SetCurrentDirectory(path *uint16) (err error) {
+ r1, _, e1 := Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func SetEndOfFile(handle Handle) (err error) {
+ r1, _, e1 := Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func SetEnvironmentVariable(name *uint16, value *uint16) (err error) {
+ r1, _, e1 := Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func SetFileAttributes(name *uint16, attrs uint32) (err error) {
+ r1, _, e1 := Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) {
+ r1, _, e1 := Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) {
+ r0, _, e1 := Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0)
+ newlowoffset = uint32(r0)
+ if newlowoffset == 0xffffffff {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) {
+ r1, _, e1 := Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) {
+ r1, _, e1 := Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func TerminateProcess(handle Handle, exitcode uint32) (err error) {
+ r1, _, e1 := Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func UnmapViewOfFile(addr uintptr) (err error) {
+ r1, _, e1 := Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func updateProcThreadAttribute(attrlist *_PROC_THREAD_ATTRIBUTE_LIST, flags uint32, attr uintptr, value unsafe.Pointer, size uintptr, prevvalue unsafe.Pointer, returnedsize *uintptr) (err error) {
+ r1, _, e1 := Syscall9(procUpdateProcThreadAttribute.Addr(), 7, uintptr(unsafe.Pointer(attrlist)), uintptr(flags), uintptr(attr), uintptr(value), uintptr(size), uintptr(prevvalue), uintptr(unsafe.Pointer(returnedsize)), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func VirtualLock(addr uintptr, length uintptr) (err error) {
+ r1, _, e1 := Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func VirtualUnlock(addr uintptr, length uintptr) (err error) {
+ r1, _, e1 := Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) {
+ r0, _, e1 := Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0)
+ event = uint32(r0)
+ if event == 0xffffffff {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) {
+ r1, _, e1 := Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func writeFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
+ var _p0 *byte
+ if len(buf) > 0 {
+ _p0 = &buf[0]
+ }
+ r1, _, e1 := Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) {
+ r1, _, e1 := Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) {
+ Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0)
+ return
+}
+
+func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) {
+ r1, _, e1 := Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0)
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func NetApiBufferFree(buf *byte) (neterr error) {
+ r0, _, _ := Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0)
+ if r0 != 0 {
+ neterr = Errno(r0)
+ }
+ return
+}
+
+func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) {
+ r0, _, _ := Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType)))
+ if r0 != 0 {
+ neterr = Errno(r0)
+ }
+ return
+}
+
+func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
+ r0, _, _ := Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
+ if r0 != 0 {
+ neterr = Errno(r0)
+ }
+ return
+}
+
+func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) {
+ Syscall(procRtlGetNtVersionNumbers.Addr(), 3, uintptr(unsafe.Pointer(majorVersion)), uintptr(unsafe.Pointer(minorVersion)), uintptr(unsafe.Pointer(buildNumber)))
+ return
+}
+
+func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) {
+ r1, _, e1 := Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize)))
+ if r1&0xff == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) {
+ r1, _, e1 := Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0)
+ if r1&0xff == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) {
+ r0, _, e1 := Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0)
+ argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0))
+ if argv == nil {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) {
+ r1, _, e1 := Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)))
+ if r1 == 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func FreeAddrInfoW(addrinfo *AddrinfoW) {
+ Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0)
+ return
+}
+
+func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) {
+ r0, _, _ := Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0)
+ if r0 != 0 {
+ sockerr = Errno(r0)
+ }
+ return
+}
+
+func WSACleanup() (err error) {
+ r1, _, e1 := Syscall(procWSACleanup.Addr(), 0, 0, 0, 0)
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) {
+ r0, _, e1 := Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength)))
+ n = int32(r0)
+ if n == -1 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
+ r1, _, e1 := Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine))
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) {
+ r1, _, e1 := Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) {
+ r1, _, e1 := Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) {
+ r1, _, e1 := Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) {
+ r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func WSAStartup(verreq uint32, data *WSAData) (sockerr error) {
+ r0, _, _ := Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
+ if r0 != 0 {
+ sockerr = Errno(r0)
+ }
+ return
+}
+
+func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) {
+ r1, _, e1 := Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func Closesocket(s Handle) (err error) {
+ r1, _, e1 := Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0)
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) {
+ r1, _, e1 := Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetHostByName(name string) (h *Hostent, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ return _GetHostByName(_p0)
+}
+
+func _GetHostByName(name *byte) (h *Hostent, err error) {
+ r0, _, e1 := Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+ h = (*Hostent)(unsafe.Pointer(r0))
+ if h == nil {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
+ r1, _, e1 := Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetProtoByName(name string) (p *Protoent, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ return _GetProtoByName(_p0)
+}
+
+func _GetProtoByName(name *byte) (p *Protoent, err error) {
+ r0, _, e1 := Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+ p = (*Protoent)(unsafe.Pointer(r0))
+ if p == nil {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func GetServByName(name string, proto string) (s *Servent, err error) {
+ var _p0 *byte
+ _p0, err = BytePtrFromString(name)
+ if err != nil {
+ return
+ }
+ var _p1 *byte
+ _p1, err = BytePtrFromString(proto)
+ if err != nil {
+ return
+ }
+ return _GetServByName(_p0, _p1)
+}
+
+func _GetServByName(name *byte, proto *byte) (s *Servent, err error) {
+ r0, _, e1 := Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0)
+ s = (*Servent)(unsafe.Pointer(r0))
+ if s == nil {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
+ r1, _, e1 := Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) {
+ r1, _, e1 := Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0)
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func listen(s Handle, backlog int32) (err error) {
+ r1, _, e1 := Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0)
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func Ntohs(netshort uint16) (u uint16) {
+ r0, _, _ := Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0)
+ u = uint16(r0)
+ return
+}
+
+func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) {
+ r1, _, e1 := Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0)
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func shutdown(s Handle, how int32) (err error) {
+ r1, _, e1 := Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0)
+ if r1 == socket_error {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+func socket(af int32, typ int32, protocol int32) (handle Handle, err error) {
+ r0, _, e1 := Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol))
+ handle = Handle(r0)
+ if handle == InvalidHandle {
+ err = errnoErr(e1)
+ }
+ return
+}
diff --git a/contrib/go/_std_1.20/src/syscall/zsysnum_darwin_amd64.go b/contrib/go/_std_1.21/src/syscall/zsysnum_darwin_amd64.go
index 08e003f292..08e003f292 100644
--- a/contrib/go/_std_1.20/src/syscall/zsysnum_darwin_amd64.go
+++ b/contrib/go/_std_1.21/src/syscall/zsysnum_darwin_amd64.go
diff --git a/contrib/go/_std_1.20/src/syscall/zsysnum_linux_amd64.go b/contrib/go/_std_1.21/src/syscall/zsysnum_linux_amd64.go
index 576c7c36a6..576c7c36a6 100644
--- a/contrib/go/_std_1.20/src/syscall/zsysnum_linux_amd64.go
+++ b/contrib/go/_std_1.21/src/syscall/zsysnum_linux_amd64.go
diff --git a/contrib/go/_std_1.20/src/syscall/zsysnum_linux_arm64.go b/contrib/go/_std_1.21/src/syscall/zsysnum_linux_arm64.go
index 0136d9440b..0136d9440b 100644
--- a/contrib/go/_std_1.20/src/syscall/zsysnum_linux_arm64.go
+++ b/contrib/go/_std_1.21/src/syscall/zsysnum_linux_arm64.go
diff --git a/contrib/go/_std_1.20/src/syscall/ztypes_darwin_amd64.go b/contrib/go/_std_1.21/src/syscall/ztypes_darwin_amd64.go
index 551edc7025..551edc7025 100644
--- a/contrib/go/_std_1.20/src/syscall/ztypes_darwin_amd64.go
+++ b/contrib/go/_std_1.21/src/syscall/ztypes_darwin_amd64.go
diff --git a/contrib/go/_std_1.20/src/syscall/ztypes_linux_amd64.go b/contrib/go/_std_1.21/src/syscall/ztypes_linux_amd64.go
index 1bab13bf43..1bab13bf43 100644
--- a/contrib/go/_std_1.20/src/syscall/ztypes_linux_amd64.go
+++ b/contrib/go/_std_1.21/src/syscall/ztypes_linux_amd64.go
diff --git a/contrib/go/_std_1.20/src/syscall/ztypes_linux_arm64.go b/contrib/go/_std_1.21/src/syscall/ztypes_linux_arm64.go
index 1e469c36d2..1e469c36d2 100644
--- a/contrib/go/_std_1.20/src/syscall/ztypes_linux_arm64.go
+++ b/contrib/go/_std_1.21/src/syscall/ztypes_linux_arm64.go
diff --git a/contrib/go/_std_1.20/src/testing/allocs.go b/contrib/go/_std_1.21/src/testing/allocs.go
index 1eeb2d4802..1eeb2d4802 100644
--- a/contrib/go/_std_1.20/src/testing/allocs.go
+++ b/contrib/go/_std_1.21/src/testing/allocs.go
diff --git a/contrib/go/_std_1.20/src/testing/benchmark.go b/contrib/go/_std_1.21/src/testing/benchmark.go
index be9b87f80b..be9b87f80b 100644
--- a/contrib/go/_std_1.20/src/testing/benchmark.go
+++ b/contrib/go/_std_1.21/src/testing/benchmark.go
diff --git a/contrib/go/_std_1.21/src/testing/cover.go b/contrib/go/_std_1.21/src/testing/cover.go
new file mode 100644
index 0000000000..6ad43ab9ff
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/cover.go
@@ -0,0 +1,124 @@
+// Copyright 2013 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.
+
+// Support for test coverage.
+
+package testing
+
+import (
+ "fmt"
+ "internal/goexperiment"
+ "os"
+ "sync/atomic"
+)
+
+// CoverBlock records the coverage data for a single basic block.
+// The fields are 1-indexed, as in an editor: The opening line of
+// the file is number 1, for example. Columns are measured
+// in bytes.
+// NOTE: This struct is internal to the testing infrastructure and may change.
+// It is not covered (yet) by the Go 1 compatibility guidelines.
+type CoverBlock struct {
+ Line0 uint32 // Line number for block start.
+ Col0 uint16 // Column number for block start.
+ Line1 uint32 // Line number for block end.
+ Col1 uint16 // Column number for block end.
+ Stmts uint16 // Number of statements included in this block.
+}
+
+var cover Cover
+
+// Cover records information about test coverage checking.
+// NOTE: This struct is internal to the testing infrastructure and may change.
+// It is not covered (yet) by the Go 1 compatibility guidelines.
+type Cover struct {
+ Mode string
+ Counters map[string][]uint32
+ Blocks map[string][]CoverBlock
+ CoveredPackages string
+}
+
+// Coverage reports the current code coverage as a fraction in the range [0, 1].
+// If coverage is not enabled, Coverage returns 0.
+//
+// When running a large set of sequential test cases, checking Coverage after each one
+// can be useful for identifying which test cases exercise new code paths.
+// It is not a replacement for the reports generated by 'go test -cover' and
+// 'go tool cover'.
+func Coverage() float64 {
+ if goexperiment.CoverageRedesign {
+ return coverage2()
+ }
+ var n, d int64
+ for _, counters := range cover.Counters {
+ for i := range counters {
+ if atomic.LoadUint32(&counters[i]) > 0 {
+ n++
+ }
+ d++
+ }
+ }
+ if d == 0 {
+ return 0
+ }
+ return float64(n) / float64(d)
+}
+
+// RegisterCover records the coverage data accumulators for the tests.
+// NOTE: This function is internal to the testing infrastructure and may change.
+// It is not covered (yet) by the Go 1 compatibility guidelines.
+func RegisterCover(c Cover) {
+ cover = c
+}
+
+// mustBeNil checks the error and, if present, reports it and exits.
+func mustBeNil(err error) {
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "testing: %s\n", err)
+ os.Exit(2)
+ }
+}
+
+// coverReport reports the coverage percentage and writes a coverage profile if requested.
+func coverReport() {
+ if goexperiment.CoverageRedesign {
+ coverReport2()
+ return
+ }
+ var f *os.File
+ var err error
+ if *coverProfile != "" {
+ f, err = os.Create(toOutputDir(*coverProfile))
+ mustBeNil(err)
+ fmt.Fprintf(f, "mode: %s\n", cover.Mode)
+ defer func() { mustBeNil(f.Close()) }()
+ }
+
+ var active, total int64
+ var count uint32
+ for name, counts := range cover.Counters {
+ blocks := cover.Blocks[name]
+ for i := range counts {
+ stmts := int64(blocks[i].Stmts)
+ total += stmts
+ count = atomic.LoadUint32(&counts[i]) // For -mode=atomic.
+ if count > 0 {
+ active += stmts
+ }
+ if f != nil {
+ _, err := fmt.Fprintf(f, "%s:%d.%d,%d.%d %d %d\n", name,
+ blocks[i].Line0, blocks[i].Col0,
+ blocks[i].Line1, blocks[i].Col1,
+ stmts,
+ count)
+ mustBeNil(err)
+ }
+ }
+ }
+ if total == 0 {
+ fmt.Println("coverage: [no statements]")
+ return
+ }
+ fmt.Printf("coverage: %.1f%% of statements%s\n", 100*float64(active)/float64(total), cover.CoveredPackages)
+}
diff --git a/contrib/go/_std_1.21/src/testing/example.go b/contrib/go/_std_1.21/src/testing/example.go
new file mode 100644
index 0000000000..42ee555cb2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/example.go
@@ -0,0 +1,101 @@
+// Copyright 2009 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 testing
+
+import (
+ "fmt"
+ "os"
+ "sort"
+ "strings"
+ "time"
+)
+
+type InternalExample struct {
+ Name string
+ F func()
+ Output string
+ Unordered bool
+}
+
+// RunExamples is an internal function but exported because it is cross-package;
+// it is part of the implementation of the "go test" command.
+func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) {
+ _, ok = runExamples(matchString, examples)
+ return ok
+}
+
+func runExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ran, ok bool) {
+ ok = true
+
+ var eg InternalExample
+
+ for _, eg = range examples {
+ matched, err := matchString(*match, eg.Name)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
+ os.Exit(1)
+ }
+ if !matched {
+ continue
+ }
+ ran = true
+ if !runExample(eg) {
+ ok = false
+ }
+ }
+
+ return ran, ok
+}
+
+func sortLines(output string) string {
+ lines := strings.Split(output, "\n")
+ sort.Strings(lines)
+ return strings.Join(lines, "\n")
+}
+
+// processRunResult computes a summary and status of the result of running an example test.
+// stdout is the captured output from stdout of the test.
+// recovered is the result of invoking recover after running the test, in case it panicked.
+//
+// If stdout doesn't match the expected output or if recovered is non-nil, it'll print the cause of failure to stdout.
+// If the test is chatty/verbose, it'll print a success message to stdout.
+// If recovered is non-nil, it'll panic with that value.
+// If the test panicked with nil, or invoked runtime.Goexit, it'll be
+// made to fail and panic with errNilPanicOrGoexit
+func (eg *InternalExample) processRunResult(stdout string, timeSpent time.Duration, finished bool, recovered any) (passed bool) {
+ passed = true
+ dstr := fmtDuration(timeSpent)
+ var fail string
+ got := strings.TrimSpace(stdout)
+ want := strings.TrimSpace(eg.Output)
+ if eg.Unordered {
+ if sortLines(got) != sortLines(want) && recovered == nil {
+ fail = fmt.Sprintf("got:\n%s\nwant (unordered):\n%s\n", stdout, eg.Output)
+ }
+ } else {
+ if got != want && recovered == nil {
+ fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", got, want)
+ }
+ }
+ if fail != "" || !finished || recovered != nil {
+ fmt.Printf("%s--- FAIL: %s (%s)\n%s", chatty.prefix(), eg.Name, dstr, fail)
+ passed = false
+ } else if chatty.on {
+ fmt.Printf("%s--- PASS: %s (%s)\n", chatty.prefix(), eg.Name, dstr)
+ }
+
+ if chatty.on && chatty.json {
+ fmt.Printf("%s=== NAME %s\n", chatty.prefix(), "")
+ }
+
+ if recovered != nil {
+ // Propagate the previously recovered result, by panicking.
+ panic(recovered)
+ } else if !finished {
+ panic(errNilPanicOrGoexit)
+ }
+
+ return
+}
diff --git a/contrib/go/_std_1.21/src/testing/fstest/mapfs.go b/contrib/go/_std_1.21/src/testing/fstest/mapfs.go
new file mode 100644
index 0000000000..a0b1f65668
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/fstest/mapfs.go
@@ -0,0 +1,244 @@
+// 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 fstest
+
+import (
+ "io"
+ "io/fs"
+ "path"
+ "sort"
+ "strings"
+ "time"
+)
+
+// A MapFS is a simple in-memory file system for use in tests,
+// represented as a map from path names (arguments to Open)
+// to information about the files or directories they represent.
+//
+// The map need not include parent directories for files contained
+// in the map; those will be synthesized if needed.
+// But a directory can still be included by setting the MapFile.Mode's ModeDir bit;
+// this may be necessary for detailed control over the directory's FileInfo
+// or to create an empty directory.
+//
+// File system operations read directly from the map,
+// so that the file system can be changed by editing the map as needed.
+// An implication is that file system operations must not run concurrently
+// with changes to the map, which would be a race.
+// Another implication is that opening or reading a directory requires
+// iterating over the entire map, so a MapFS should typically be used with not more
+// than a few hundred entries or directory reads.
+type MapFS map[string]*MapFile
+
+// A MapFile describes a single file in a MapFS.
+type MapFile struct {
+ Data []byte // file content
+ Mode fs.FileMode // FileInfo.Mode
+ ModTime time.Time // FileInfo.ModTime
+ Sys any // FileInfo.Sys
+}
+
+var _ fs.FS = MapFS(nil)
+var _ fs.File = (*openMapFile)(nil)
+
+// Open opens the named file.
+func (fsys MapFS) Open(name string) (fs.File, error) {
+ if !fs.ValidPath(name) {
+ return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
+ }
+ file := fsys[name]
+ if file != nil && file.Mode&fs.ModeDir == 0 {
+ // Ordinary file
+ return &openMapFile{name, mapFileInfo{path.Base(name), file}, 0}, nil
+ }
+
+ // Directory, possibly synthesized.
+ // Note that file can be nil here: the map need not contain explicit parent directories for all its files.
+ // But file can also be non-nil, in case the user wants to set metadata for the directory explicitly.
+ // Either way, we need to construct the list of children of this directory.
+ var list []mapFileInfo
+ var elem string
+ var need = make(map[string]bool)
+ if name == "." {
+ elem = "."
+ for fname, f := range fsys {
+ i := strings.Index(fname, "/")
+ if i < 0 {
+ if fname != "." {
+ list = append(list, mapFileInfo{fname, f})
+ }
+ } else {
+ need[fname[:i]] = true
+ }
+ }
+ } else {
+ elem = name[strings.LastIndex(name, "/")+1:]
+ prefix := name + "/"
+ for fname, f := range fsys {
+ if strings.HasPrefix(fname, prefix) {
+ felem := fname[len(prefix):]
+ i := strings.Index(felem, "/")
+ if i < 0 {
+ list = append(list, mapFileInfo{felem, f})
+ } else {
+ need[fname[len(prefix):len(prefix)+i]] = true
+ }
+ }
+ }
+ // If the directory name is not in the map,
+ // and there are no children of the name in the map,
+ // then the directory is treated as not existing.
+ if file == nil && list == nil && len(need) == 0 {
+ return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
+ }
+ }
+ for _, fi := range list {
+ delete(need, fi.name)
+ }
+ for name := range need {
+ list = append(list, mapFileInfo{name, &MapFile{Mode: fs.ModeDir}})
+ }
+ sort.Slice(list, func(i, j int) bool {
+ return list[i].name < list[j].name
+ })
+
+ if file == nil {
+ file = &MapFile{Mode: fs.ModeDir}
+ }
+ return &mapDir{name, mapFileInfo{elem, file}, list, 0}, nil
+}
+
+// fsOnly is a wrapper that hides all but the fs.FS methods,
+// to avoid an infinite recursion when implementing special
+// methods in terms of helpers that would use them.
+// (In general, implementing these methods using the package fs helpers
+// is redundant and unnecessary, but having the methods may make
+// MapFS exercise more code paths when used in tests.)
+type fsOnly struct{ fs.FS }
+
+func (fsys MapFS) ReadFile(name string) ([]byte, error) {
+ return fs.ReadFile(fsOnly{fsys}, name)
+}
+
+func (fsys MapFS) Stat(name string) (fs.FileInfo, error) {
+ return fs.Stat(fsOnly{fsys}, name)
+}
+
+func (fsys MapFS) ReadDir(name string) ([]fs.DirEntry, error) {
+ return fs.ReadDir(fsOnly{fsys}, name)
+}
+
+func (fsys MapFS) Glob(pattern string) ([]string, error) {
+ return fs.Glob(fsOnly{fsys}, pattern)
+}
+
+type noSub struct {
+ MapFS
+}
+
+func (noSub) Sub() {} // not the fs.SubFS signature
+
+func (fsys MapFS) Sub(dir string) (fs.FS, error) {
+ return fs.Sub(noSub{fsys}, dir)
+}
+
+// A mapFileInfo implements fs.FileInfo and fs.DirEntry for a given map file.
+type mapFileInfo struct {
+ name string
+ f *MapFile
+}
+
+func (i *mapFileInfo) Name() string { return i.name }
+func (i *mapFileInfo) Size() int64 { return int64(len(i.f.Data)) }
+func (i *mapFileInfo) Mode() fs.FileMode { return i.f.Mode }
+func (i *mapFileInfo) Type() fs.FileMode { return i.f.Mode.Type() }
+func (i *mapFileInfo) ModTime() time.Time { return i.f.ModTime }
+func (i *mapFileInfo) IsDir() bool { return i.f.Mode&fs.ModeDir != 0 }
+func (i *mapFileInfo) Sys() any { return i.f.Sys }
+func (i *mapFileInfo) Info() (fs.FileInfo, error) { return i, nil }
+
+func (i *mapFileInfo) String() string {
+ return fs.FormatFileInfo(i)
+}
+
+// An openMapFile is a regular (non-directory) fs.File open for reading.
+type openMapFile struct {
+ path string
+ mapFileInfo
+ offset int64
+}
+
+func (f *openMapFile) Stat() (fs.FileInfo, error) { return &f.mapFileInfo, nil }
+
+func (f *openMapFile) Close() error { return nil }
+
+func (f *openMapFile) Read(b []byte) (int, error) {
+ if f.offset >= int64(len(f.f.Data)) {
+ return 0, io.EOF
+ }
+ if f.offset < 0 {
+ return 0, &fs.PathError{Op: "read", Path: f.path, Err: fs.ErrInvalid}
+ }
+ n := copy(b, f.f.Data[f.offset:])
+ f.offset += int64(n)
+ return n, nil
+}
+
+func (f *openMapFile) Seek(offset int64, whence int) (int64, error) {
+ switch whence {
+ case 0:
+ // offset += 0
+ case 1:
+ offset += f.offset
+ case 2:
+ offset += int64(len(f.f.Data))
+ }
+ if offset < 0 || offset > int64(len(f.f.Data)) {
+ return 0, &fs.PathError{Op: "seek", Path: f.path, Err: fs.ErrInvalid}
+ }
+ f.offset = offset
+ return offset, nil
+}
+
+func (f *openMapFile) ReadAt(b []byte, offset int64) (int, error) {
+ if offset < 0 || offset > int64(len(f.f.Data)) {
+ return 0, &fs.PathError{Op: "read", Path: f.path, Err: fs.ErrInvalid}
+ }
+ n := copy(b, f.f.Data[offset:])
+ if n < len(b) {
+ return n, io.EOF
+ }
+ return n, nil
+}
+
+// A mapDir is a directory fs.File (so also an fs.ReadDirFile) open for reading.
+type mapDir struct {
+ path string
+ mapFileInfo
+ entry []mapFileInfo
+ offset int
+}
+
+func (d *mapDir) Stat() (fs.FileInfo, error) { return &d.mapFileInfo, nil }
+func (d *mapDir) Close() error { return nil }
+func (d *mapDir) Read(b []byte) (int, error) {
+ return 0, &fs.PathError{Op: "read", Path: d.path, Err: fs.ErrInvalid}
+}
+
+func (d *mapDir) ReadDir(count int) ([]fs.DirEntry, error) {
+ n := len(d.entry) - d.offset
+ if n == 0 && count > 0 {
+ return nil, io.EOF
+ }
+ if count > 0 && n > count {
+ n = count
+ }
+ list := make([]fs.DirEntry, n)
+ for i := range list {
+ list[i] = &d.entry[d.offset+i]
+ }
+ d.offset += n
+ return list, nil
+}
diff --git a/contrib/go/_std_1.21/src/testing/fstest/testfs.go b/contrib/go/_std_1.21/src/testing/fstest/testfs.go
new file mode 100644
index 0000000000..78b0b82640
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/fstest/testfs.go
@@ -0,0 +1,624 @@
+// 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 fstest implements support for testing implementations and users of file systems.
+package fstest
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "io/fs"
+ "path"
+ "reflect"
+ "sort"
+ "strings"
+ "testing/iotest"
+)
+
+// TestFS tests a file system implementation.
+// It walks the entire tree of files in fsys,
+// opening and checking that each file behaves correctly.
+// It also checks that the file system contains at least the expected files.
+// As a special case, if no expected files are listed, fsys must be empty.
+// Otherwise, fsys must contain at least the listed files; it can also contain others.
+// The contents of fsys must not change concurrently with TestFS.
+//
+// If TestFS finds any misbehaviors, it returns an error reporting all of them.
+// The error text spans multiple lines, one per detected misbehavior.
+//
+// Typical usage inside a test is:
+//
+// if err := fstest.TestFS(myFS, "file/that/should/be/present"); err != nil {
+// t.Fatal(err)
+// }
+func TestFS(fsys fs.FS, expected ...string) error {
+ if err := testFS(fsys, expected...); err != nil {
+ return err
+ }
+ for _, name := range expected {
+ if i := strings.Index(name, "/"); i >= 0 {
+ dir, dirSlash := name[:i], name[:i+1]
+ var subExpected []string
+ for _, name := range expected {
+ if strings.HasPrefix(name, dirSlash) {
+ subExpected = append(subExpected, name[len(dirSlash):])
+ }
+ }
+ sub, err := fs.Sub(fsys, dir)
+ if err != nil {
+ return err
+ }
+ if err := testFS(sub, subExpected...); err != nil {
+ return fmt.Errorf("testing fs.Sub(fsys, %s): %v", dir, err)
+ }
+ break // one sub-test is enough
+ }
+ }
+ return nil
+}
+
+func testFS(fsys fs.FS, expected ...string) error {
+ t := fsTester{fsys: fsys}
+ t.checkDir(".")
+ t.checkOpen(".")
+ found := make(map[string]bool)
+ for _, dir := range t.dirs {
+ found[dir] = true
+ }
+ for _, file := range t.files {
+ found[file] = true
+ }
+ delete(found, ".")
+ if len(expected) == 0 && len(found) > 0 {
+ var list []string
+ for k := range found {
+ if k != "." {
+ list = append(list, k)
+ }
+ }
+ sort.Strings(list)
+ if len(list) > 15 {
+ list = append(list[:10], "...")
+ }
+ t.errorf("expected empty file system but found files:\n%s", strings.Join(list, "\n"))
+ }
+ for _, name := range expected {
+ if !found[name] {
+ t.errorf("expected but not found: %s", name)
+ }
+ }
+ if len(t.errText) == 0 {
+ return nil
+ }
+ return errors.New("TestFS found errors:\n" + string(t.errText))
+}
+
+// An fsTester holds state for running the test.
+type fsTester struct {
+ fsys fs.FS
+ errText []byte
+ dirs []string
+ files []string
+}
+
+// errorf adds an error line to errText.
+func (t *fsTester) errorf(format string, args ...any) {
+ if len(t.errText) > 0 {
+ t.errText = append(t.errText, '\n')
+ }
+ t.errText = append(t.errText, fmt.Sprintf(format, args...)...)
+}
+
+func (t *fsTester) openDir(dir string) fs.ReadDirFile {
+ f, err := t.fsys.Open(dir)
+ if err != nil {
+ t.errorf("%s: Open: %v", dir, err)
+ return nil
+ }
+ d, ok := f.(fs.ReadDirFile)
+ if !ok {
+ f.Close()
+ t.errorf("%s: Open returned File type %T, not a fs.ReadDirFile", dir, f)
+ return nil
+ }
+ return d
+}
+
+// checkDir checks the directory dir, which is expected to exist
+// (it is either the root or was found in a directory listing with IsDir true).
+func (t *fsTester) checkDir(dir string) {
+ // Read entire directory.
+ t.dirs = append(t.dirs, dir)
+ d := t.openDir(dir)
+ if d == nil {
+ return
+ }
+ list, err := d.ReadDir(-1)
+ if err != nil {
+ d.Close()
+ t.errorf("%s: ReadDir(-1): %v", dir, err)
+ return
+ }
+
+ // Check all children.
+ var prefix string
+ if dir == "." {
+ prefix = ""
+ } else {
+ prefix = dir + "/"
+ }
+ for _, info := range list {
+ name := info.Name()
+ switch {
+ case name == ".", name == "..", name == "":
+ t.errorf("%s: ReadDir: child has invalid name: %#q", dir, name)
+ continue
+ case strings.Contains(name, "/"):
+ t.errorf("%s: ReadDir: child name contains slash: %#q", dir, name)
+ continue
+ case strings.Contains(name, `\`):
+ t.errorf("%s: ReadDir: child name contains backslash: %#q", dir, name)
+ continue
+ }
+ path := prefix + name
+ t.checkStat(path, info)
+ t.checkOpen(path)
+ if info.IsDir() {
+ t.checkDir(path)
+ } else {
+ t.checkFile(path)
+ }
+ }
+
+ // Check ReadDir(-1) at EOF.
+ list2, err := d.ReadDir(-1)
+ if len(list2) > 0 || err != nil {
+ d.Close()
+ t.errorf("%s: ReadDir(-1) at EOF = %d entries, %v, wanted 0 entries, nil", dir, len(list2), err)
+ return
+ }
+
+ // Check ReadDir(1) at EOF (different results).
+ list2, err = d.ReadDir(1)
+ if len(list2) > 0 || err != io.EOF {
+ d.Close()
+ t.errorf("%s: ReadDir(1) at EOF = %d entries, %v, wanted 0 entries, EOF", dir, len(list2), err)
+ return
+ }
+
+ // Check that close does not report an error.
+ if err := d.Close(); err != nil {
+ t.errorf("%s: Close: %v", dir, err)
+ }
+
+ // Check that closing twice doesn't crash.
+ // The return value doesn't matter.
+ d.Close()
+
+ // Reopen directory, read a second time, make sure contents match.
+ if d = t.openDir(dir); d == nil {
+ return
+ }
+ defer d.Close()
+ list2, err = d.ReadDir(-1)
+ if err != nil {
+ t.errorf("%s: second Open+ReadDir(-1): %v", dir, err)
+ return
+ }
+ t.checkDirList(dir, "first Open+ReadDir(-1) vs second Open+ReadDir(-1)", list, list2)
+
+ // Reopen directory, read a third time in pieces, make sure contents match.
+ if d = t.openDir(dir); d == nil {
+ return
+ }
+ defer d.Close()
+ list2 = nil
+ for {
+ n := 1
+ if len(list2) > 0 {
+ n = 2
+ }
+ frag, err := d.ReadDir(n)
+ if len(frag) > n {
+ t.errorf("%s: third Open: ReadDir(%d) after %d: %d entries (too many)", dir, n, len(list2), len(frag))
+ return
+ }
+ list2 = append(list2, frag...)
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ t.errorf("%s: third Open: ReadDir(%d) after %d: %v", dir, n, len(list2), err)
+ return
+ }
+ if n == 0 {
+ t.errorf("%s: third Open: ReadDir(%d) after %d: 0 entries but nil error", dir, n, len(list2))
+ return
+ }
+ }
+ t.checkDirList(dir, "first Open+ReadDir(-1) vs third Open+ReadDir(1,2) loop", list, list2)
+
+ // If fsys has ReadDir, check that it matches and is sorted.
+ if fsys, ok := t.fsys.(fs.ReadDirFS); ok {
+ list2, err := fsys.ReadDir(dir)
+ if err != nil {
+ t.errorf("%s: fsys.ReadDir: %v", dir, err)
+ return
+ }
+ t.checkDirList(dir, "first Open+ReadDir(-1) vs fsys.ReadDir", list, list2)
+
+ for i := 0; i+1 < len(list2); i++ {
+ if list2[i].Name() >= list2[i+1].Name() {
+ t.errorf("%s: fsys.ReadDir: list not sorted: %s before %s", dir, list2[i].Name(), list2[i+1].Name())
+ }
+ }
+ }
+
+ // Check fs.ReadDir as well.
+ list2, err = fs.ReadDir(t.fsys, dir)
+ if err != nil {
+ t.errorf("%s: fs.ReadDir: %v", dir, err)
+ return
+ }
+ t.checkDirList(dir, "first Open+ReadDir(-1) vs fs.ReadDir", list, list2)
+
+ for i := 0; i+1 < len(list2); i++ {
+ if list2[i].Name() >= list2[i+1].Name() {
+ t.errorf("%s: fs.ReadDir: list not sorted: %s before %s", dir, list2[i].Name(), list2[i+1].Name())
+ }
+ }
+
+ t.checkGlob(dir, list2)
+}
+
+// formatEntry formats an fs.DirEntry into a string for error messages and comparison.
+func formatEntry(entry fs.DirEntry) string {
+ return fmt.Sprintf("%s IsDir=%v Type=%v", entry.Name(), entry.IsDir(), entry.Type())
+}
+
+// formatInfoEntry formats an fs.FileInfo into a string like the result of formatEntry, for error messages and comparison.
+func formatInfoEntry(info fs.FileInfo) string {
+ return fmt.Sprintf("%s IsDir=%v Type=%v", info.Name(), info.IsDir(), info.Mode().Type())
+}
+
+// formatInfo formats an fs.FileInfo into a string for error messages and comparison.
+func formatInfo(info fs.FileInfo) string {
+ return fmt.Sprintf("%s IsDir=%v Mode=%v Size=%d ModTime=%v", info.Name(), info.IsDir(), info.Mode(), info.Size(), info.ModTime())
+}
+
+// checkGlob checks that various glob patterns work if the file system implements GlobFS.
+func (t *fsTester) checkGlob(dir string, list []fs.DirEntry) {
+ if _, ok := t.fsys.(fs.GlobFS); !ok {
+ return
+ }
+
+ // Make a complex glob pattern prefix that only matches dir.
+ var glob string
+ if dir != "." {
+ elem := strings.Split(dir, "/")
+ for i, e := range elem {
+ var pattern []rune
+ for j, r := range e {
+ if r == '*' || r == '?' || r == '\\' || r == '[' || r == '-' {
+ pattern = append(pattern, '\\', r)
+ continue
+ }
+ switch (i + j) % 5 {
+ case 0:
+ pattern = append(pattern, r)
+ case 1:
+ pattern = append(pattern, '[', r, ']')
+ case 2:
+ pattern = append(pattern, '[', r, '-', r, ']')
+ case 3:
+ pattern = append(pattern, '[', '\\', r, ']')
+ case 4:
+ pattern = append(pattern, '[', '\\', r, '-', '\\', r, ']')
+ }
+ }
+ elem[i] = string(pattern)
+ }
+ glob = strings.Join(elem, "/") + "/"
+ }
+
+ // Test that malformed patterns are detected.
+ // The error is likely path.ErrBadPattern but need not be.
+ if _, err := t.fsys.(fs.GlobFS).Glob(glob + "nonexist/[]"); err == nil {
+ t.errorf("%s: Glob(%#q): bad pattern not detected", dir, glob+"nonexist/[]")
+ }
+
+ // Try to find a letter that appears in only some of the final names.
+ c := rune('a')
+ for ; c <= 'z'; c++ {
+ have, haveNot := false, false
+ for _, d := range list {
+ if strings.ContainsRune(d.Name(), c) {
+ have = true
+ } else {
+ haveNot = true
+ }
+ }
+ if have && haveNot {
+ break
+ }
+ }
+ if c > 'z' {
+ c = 'a'
+ }
+ glob += "*" + string(c) + "*"
+
+ var want []string
+ for _, d := range list {
+ if strings.ContainsRune(d.Name(), c) {
+ want = append(want, path.Join(dir, d.Name()))
+ }
+ }
+
+ names, err := t.fsys.(fs.GlobFS).Glob(glob)
+ if err != nil {
+ t.errorf("%s: Glob(%#q): %v", dir, glob, err)
+ return
+ }
+ if reflect.DeepEqual(want, names) {
+ return
+ }
+
+ if !sort.StringsAreSorted(names) {
+ t.errorf("%s: Glob(%#q): unsorted output:\n%s", dir, glob, strings.Join(names, "\n"))
+ sort.Strings(names)
+ }
+
+ var problems []string
+ for len(want) > 0 || len(names) > 0 {
+ switch {
+ case len(want) > 0 && len(names) > 0 && want[0] == names[0]:
+ want, names = want[1:], names[1:]
+ case len(want) > 0 && (len(names) == 0 || want[0] < names[0]):
+ problems = append(problems, "missing: "+want[0])
+ want = want[1:]
+ default:
+ problems = append(problems, "extra: "+names[0])
+ names = names[1:]
+ }
+ }
+ t.errorf("%s: Glob(%#q): wrong output:\n%s", dir, glob, strings.Join(problems, "\n"))
+}
+
+// checkStat checks that a direct stat of path matches entry,
+// which was found in the parent's directory listing.
+func (t *fsTester) checkStat(path string, entry fs.DirEntry) {
+ file, err := t.fsys.Open(path)
+ if err != nil {
+ t.errorf("%s: Open: %v", path, err)
+ return
+ }
+ info, err := file.Stat()
+ file.Close()
+ if err != nil {
+ t.errorf("%s: Stat: %v", path, err)
+ return
+ }
+ fentry := formatEntry(entry)
+ fientry := formatInfoEntry(info)
+ // Note: mismatch here is OK for symlink, because Open dereferences symlink.
+ if fentry != fientry && entry.Type()&fs.ModeSymlink == 0 {
+ t.errorf("%s: mismatch:\n\tentry = %s\n\tfile.Stat() = %s", path, fentry, fientry)
+ }
+
+ einfo, err := entry.Info()
+ if err != nil {
+ t.errorf("%s: entry.Info: %v", path, err)
+ return
+ }
+ finfo := formatInfo(info)
+ if entry.Type()&fs.ModeSymlink != 0 {
+ // For symlink, just check that entry.Info matches entry on common fields.
+ // Open deferences symlink, so info itself may differ.
+ feentry := formatInfoEntry(einfo)
+ if fentry != feentry {
+ t.errorf("%s: mismatch\n\tentry = %s\n\tentry.Info() = %s\n", path, fentry, feentry)
+ }
+ } else {
+ feinfo := formatInfo(einfo)
+ if feinfo != finfo {
+ t.errorf("%s: mismatch:\n\tentry.Info() = %s\n\tfile.Stat() = %s\n", path, feinfo, finfo)
+ }
+ }
+
+ // Stat should be the same as Open+Stat, even for symlinks.
+ info2, err := fs.Stat(t.fsys, path)
+ if err != nil {
+ t.errorf("%s: fs.Stat: %v", path, err)
+ return
+ }
+ finfo2 := formatInfo(info2)
+ if finfo2 != finfo {
+ t.errorf("%s: fs.Stat(...) = %s\n\twant %s", path, finfo2, finfo)
+ }
+
+ if fsys, ok := t.fsys.(fs.StatFS); ok {
+ info2, err := fsys.Stat(path)
+ if err != nil {
+ t.errorf("%s: fsys.Stat: %v", path, err)
+ return
+ }
+ finfo2 := formatInfo(info2)
+ if finfo2 != finfo {
+ t.errorf("%s: fsys.Stat(...) = %s\n\twant %s", path, finfo2, finfo)
+ }
+ }
+}
+
+// checkDirList checks that two directory lists contain the same files and file info.
+// The order of the lists need not match.
+func (t *fsTester) checkDirList(dir, desc string, list1, list2 []fs.DirEntry) {
+ old := make(map[string]fs.DirEntry)
+ checkMode := func(entry fs.DirEntry) {
+ if entry.IsDir() != (entry.Type()&fs.ModeDir != 0) {
+ if entry.IsDir() {
+ t.errorf("%s: ReadDir returned %s with IsDir() = true, Type() & ModeDir = 0", dir, entry.Name())
+ } else {
+ t.errorf("%s: ReadDir returned %s with IsDir() = false, Type() & ModeDir = ModeDir", dir, entry.Name())
+ }
+ }
+ }
+
+ for _, entry1 := range list1 {
+ old[entry1.Name()] = entry1
+ checkMode(entry1)
+ }
+
+ var diffs []string
+ for _, entry2 := range list2 {
+ entry1 := old[entry2.Name()]
+ if entry1 == nil {
+ checkMode(entry2)
+ diffs = append(diffs, "+ "+formatEntry(entry2))
+ continue
+ }
+ if formatEntry(entry1) != formatEntry(entry2) {
+ diffs = append(diffs, "- "+formatEntry(entry1), "+ "+formatEntry(entry2))
+ }
+ delete(old, entry2.Name())
+ }
+ for _, entry1 := range old {
+ diffs = append(diffs, "- "+formatEntry(entry1))
+ }
+
+ if len(diffs) == 0 {
+ return
+ }
+
+ sort.Slice(diffs, func(i, j int) bool {
+ fi := strings.Fields(diffs[i])
+ fj := strings.Fields(diffs[j])
+ // sort by name (i < j) and then +/- (j < i, because + < -)
+ return fi[1]+" "+fj[0] < fj[1]+" "+fi[0]
+ })
+
+ t.errorf("%s: diff %s:\n\t%s", dir, desc, strings.Join(diffs, "\n\t"))
+}
+
+// checkFile checks that basic file reading works correctly.
+func (t *fsTester) checkFile(file string) {
+ t.files = append(t.files, file)
+
+ // Read entire file.
+ f, err := t.fsys.Open(file)
+ if err != nil {
+ t.errorf("%s: Open: %v", file, err)
+ return
+ }
+
+ data, err := io.ReadAll(f)
+ if err != nil {
+ f.Close()
+ t.errorf("%s: Open+ReadAll: %v", file, err)
+ return
+ }
+
+ if err := f.Close(); err != nil {
+ t.errorf("%s: Close: %v", file, err)
+ }
+
+ // Check that closing twice doesn't crash.
+ // The return value doesn't matter.
+ f.Close()
+
+ // Check that ReadFile works if present.
+ if fsys, ok := t.fsys.(fs.ReadFileFS); ok {
+ data2, err := fsys.ReadFile(file)
+ if err != nil {
+ t.errorf("%s: fsys.ReadFile: %v", file, err)
+ return
+ }
+ t.checkFileRead(file, "ReadAll vs fsys.ReadFile", data, data2)
+
+ // Modify the data and check it again. Modifying the
+ // returned byte slice should not affect the next call.
+ for i := range data2 {
+ data2[i]++
+ }
+ data2, err = fsys.ReadFile(file)
+ if err != nil {
+ t.errorf("%s: second call to fsys.ReadFile: %v", file, err)
+ return
+ }
+ t.checkFileRead(file, "Readall vs second fsys.ReadFile", data, data2)
+
+ t.checkBadPath(file, "ReadFile",
+ func(name string) error { _, err := fsys.ReadFile(name); return err })
+ }
+
+ // Check that fs.ReadFile works with t.fsys.
+ data2, err := fs.ReadFile(t.fsys, file)
+ if err != nil {
+ t.errorf("%s: fs.ReadFile: %v", file, err)
+ return
+ }
+ t.checkFileRead(file, "ReadAll vs fs.ReadFile", data, data2)
+
+ // Use iotest.TestReader to check small reads, Seek, ReadAt.
+ f, err = t.fsys.Open(file)
+ if err != nil {
+ t.errorf("%s: second Open: %v", file, err)
+ return
+ }
+ defer f.Close()
+ if err := iotest.TestReader(f, data); err != nil {
+ t.errorf("%s: failed TestReader:\n\t%s", file, strings.ReplaceAll(err.Error(), "\n", "\n\t"))
+ }
+}
+
+func (t *fsTester) checkFileRead(file, desc string, data1, data2 []byte) {
+ if string(data1) != string(data2) {
+ t.errorf("%s: %s: different data returned\n\t%q\n\t%q", file, desc, data1, data2)
+ return
+ }
+}
+
+// checkBadPath checks that various invalid forms of file's name cannot be opened using t.fsys.Open.
+func (t *fsTester) checkOpen(file string) {
+ t.checkBadPath(file, "Open", func(file string) error {
+ f, err := t.fsys.Open(file)
+ if err == nil {
+ f.Close()
+ }
+ return err
+ })
+}
+
+// checkBadPath checks that various invalid forms of file's name cannot be opened using open.
+func (t *fsTester) checkBadPath(file string, desc string, open func(string) error) {
+ bad := []string{
+ "/" + file,
+ file + "/.",
+ }
+ if file == "." {
+ bad = append(bad, "/")
+ }
+ if i := strings.Index(file, "/"); i >= 0 {
+ bad = append(bad,
+ file[:i]+"//"+file[i+1:],
+ file[:i]+"/./"+file[i+1:],
+ file[:i]+`\`+file[i+1:],
+ file[:i]+"/../"+file,
+ )
+ }
+ if i := strings.LastIndex(file, "/"); i >= 0 {
+ bad = append(bad,
+ file[:i]+"//"+file[i+1:],
+ file[:i]+"/./"+file[i+1:],
+ file[:i]+`\`+file[i+1:],
+ file+"/../"+file[i+1:],
+ )
+ }
+
+ for _, b := range bad {
+ if err := open(b); err == nil {
+ t.errorf("%s: %s(%s) succeeded, want error", file, desc, b)
+ }
+ }
+}
diff --git a/contrib/go/_std_1.21/src/testing/fstest/ya.make b/contrib/go/_std_1.21/src/testing/fstest/ya.make
new file mode 100644
index 0000000000..320a7d80ab
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/fstest/ya.make
@@ -0,0 +1,16 @@
+GO_LIBRARY()
+
+SRCS(
+ mapfs.go
+ testfs.go
+)
+
+GO_TEST_SRCS(
+ mapfs_test.go
+ testfs_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/testing/fuzz.go b/contrib/go/_std_1.21/src/testing/fuzz.go
index d31a3f81f5..d31a3f81f5 100644
--- a/contrib/go/_std_1.20/src/testing/fuzz.go
+++ b/contrib/go/_std_1.21/src/testing/fuzz.go
diff --git a/contrib/go/_std_1.20/src/testing/internal/testdeps/deps.go b/contrib/go/_std_1.21/src/testing/internal/testdeps/deps.go
index 2e85a41b07..2e85a41b07 100644
--- a/contrib/go/_std_1.20/src/testing/internal/testdeps/deps.go
+++ b/contrib/go/_std_1.21/src/testing/internal/testdeps/deps.go
diff --git a/contrib/go/_std_1.20/src/testing/internal/testdeps/ya.make b/contrib/go/_std_1.21/src/testing/internal/testdeps/ya.make
index 7ee6675a3f..7ee6675a3f 100644
--- a/contrib/go/_std_1.20/src/testing/internal/testdeps/ya.make
+++ b/contrib/go/_std_1.21/src/testing/internal/testdeps/ya.make
diff --git a/contrib/go/_std_1.20/src/testing/internal/ya.make b/contrib/go/_std_1.21/src/testing/internal/ya.make
index 11ff590e8c..11ff590e8c 100644
--- a/contrib/go/_std_1.20/src/testing/internal/ya.make
+++ b/contrib/go/_std_1.21/src/testing/internal/ya.make
diff --git a/contrib/go/_std_1.20/src/testing/iotest/logger.go b/contrib/go/_std_1.21/src/testing/iotest/logger.go
index 99548dcfed..99548dcfed 100644
--- a/contrib/go/_std_1.20/src/testing/iotest/logger.go
+++ b/contrib/go/_std_1.21/src/testing/iotest/logger.go
diff --git a/contrib/go/_std_1.20/src/testing/iotest/reader.go b/contrib/go/_std_1.21/src/testing/iotest/reader.go
index 770d87f26b..770d87f26b 100644
--- a/contrib/go/_std_1.20/src/testing/iotest/reader.go
+++ b/contrib/go/_std_1.21/src/testing/iotest/reader.go
diff --git a/contrib/go/_std_1.20/src/testing/iotest/writer.go b/contrib/go/_std_1.21/src/testing/iotest/writer.go
index af61ab8584..af61ab8584 100644
--- a/contrib/go/_std_1.20/src/testing/iotest/writer.go
+++ b/contrib/go/_std_1.21/src/testing/iotest/writer.go
diff --git a/contrib/go/_std_1.21/src/testing/iotest/ya.make b/contrib/go/_std_1.21/src/testing/iotest/ya.make
new file mode 100644
index 0000000000..8371548788
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/iotest/ya.make
@@ -0,0 +1,20 @@
+GO_LIBRARY()
+
+SRCS(
+ logger.go
+ reader.go
+ writer.go
+)
+
+GO_TEST_SRCS(
+ logger_test.go
+ reader_test.go
+ writer_test.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/testing/match.go b/contrib/go/_std_1.21/src/testing/match.go
index 92b7dc622d..92b7dc622d 100644
--- a/contrib/go/_std_1.20/src/testing/match.go
+++ b/contrib/go/_std_1.21/src/testing/match.go
diff --git a/contrib/go/_std_1.21/src/testing/newcover.go b/contrib/go/_std_1.21/src/testing/newcover.go
new file mode 100644
index 0000000000..6199f3bd7b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/newcover.go
@@ -0,0 +1,59 @@
+// Copyright 2022 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.
+
+// Support for test coverage with redesigned coverage implementation.
+
+package testing
+
+import (
+ "fmt"
+ "internal/goexperiment"
+ "os"
+)
+
+// cover2 variable stores the current coverage mode and a
+// tear-down function to be called at the end of the testing run.
+var cover2 struct {
+ mode string
+ tearDown func(coverprofile string, gocoverdir string) (string, error)
+ snapshotcov func() float64
+}
+
+// registerCover2 is invoked during "go test -cover" runs by the test harness
+// code in _testmain.go; it is used to record a 'tear down' function
+// (to be called when the test is complete) and the coverage mode.
+func registerCover2(mode string, tearDown func(coverprofile string, gocoverdir string) (string, error), snapcov func() float64) {
+ cover2.mode = mode
+ cover2.tearDown = tearDown
+ cover2.snapshotcov = snapcov
+}
+
+// coverReport2 invokes a callback in _testmain.go that will
+// emit coverage data at the point where test execution is complete,
+// for "go test -cover" runs.
+func coverReport2() {
+ if !goexperiment.CoverageRedesign {
+ panic("unexpected")
+ }
+ if errmsg, err := cover2.tearDown(*coverProfile, *gocoverdir); err != nil {
+ fmt.Fprintf(os.Stderr, "%s: %v\n", errmsg, err)
+ os.Exit(2)
+ }
+}
+
+// testGoCoverDir returns the value passed to the -test.gocoverdir
+// flag by the Go command, if goexperiment.CoverageRedesign is
+// in effect.
+func testGoCoverDir() string {
+ return *gocoverdir
+}
+
+// coverage2 returns a rough "coverage percentage so far"
+// number to support the testing.Coverage() function.
+func coverage2() float64 {
+ if cover2.mode == "" {
+ return 0.0
+ }
+ return cover2.snapshotcov()
+}
diff --git a/contrib/go/_std_1.21/src/testing/quick/quick.go b/contrib/go/_std_1.21/src/testing/quick/quick.go
new file mode 100644
index 0000000000..d7117420a3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/quick/quick.go
@@ -0,0 +1,385 @@
+// Copyright 2009 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 quick implements utility functions to help with black box testing.
+//
+// The testing/quick package is frozen and is not accepting new features.
+package quick
+
+import (
+ "flag"
+ "fmt"
+ "math"
+ "math/rand"
+ "reflect"
+ "strings"
+ "time"
+)
+
+var defaultMaxCount *int = flag.Int("quickchecks", 100, "The default number of iterations for each check")
+
+// A Generator can generate random values of its own type.
+type Generator interface {
+ // Generate returns a random instance of the type on which it is a
+ // method using the size as a size hint.
+ Generate(rand *rand.Rand, size int) reflect.Value
+}
+
+// randFloat32 generates a random float taking the full range of a float32.
+func randFloat32(rand *rand.Rand) float32 {
+ f := rand.Float64() * math.MaxFloat32
+ if rand.Int()&1 == 1 {
+ f = -f
+ }
+ return float32(f)
+}
+
+// randFloat64 generates a random float taking the full range of a float64.
+func randFloat64(rand *rand.Rand) float64 {
+ f := rand.Float64() * math.MaxFloat64
+ if rand.Int()&1 == 1 {
+ f = -f
+ }
+ return f
+}
+
+// randInt64 returns a random int64.
+func randInt64(rand *rand.Rand) int64 {
+ return int64(rand.Uint64())
+}
+
+// complexSize is the maximum length of arbitrary values that contain other
+// values.
+const complexSize = 50
+
+// Value returns an arbitrary value of the given type.
+// If the type implements the Generator interface, that will be used.
+// Note: To create arbitrary values for structs, all the fields must be exported.
+func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) {
+ return sizedValue(t, rand, complexSize)
+}
+
+// sizedValue returns an arbitrary value of the given type. The size
+// hint is used for shrinking as a function of indirection level so
+// that recursive data structures will terminate.
+func sizedValue(t reflect.Type, rand *rand.Rand, size int) (value reflect.Value, ok bool) {
+ if m, ok := reflect.Zero(t).Interface().(Generator); ok {
+ return m.Generate(rand, size), true
+ }
+
+ v := reflect.New(t).Elem()
+ switch concrete := t; concrete.Kind() {
+ case reflect.Bool:
+ v.SetBool(rand.Int()&1 == 0)
+ case reflect.Float32:
+ v.SetFloat(float64(randFloat32(rand)))
+ case reflect.Float64:
+ v.SetFloat(randFloat64(rand))
+ case reflect.Complex64:
+ v.SetComplex(complex(float64(randFloat32(rand)), float64(randFloat32(rand))))
+ case reflect.Complex128:
+ v.SetComplex(complex(randFloat64(rand), randFloat64(rand)))
+ case reflect.Int16:
+ v.SetInt(randInt64(rand))
+ case reflect.Int32:
+ v.SetInt(randInt64(rand))
+ case reflect.Int64:
+ v.SetInt(randInt64(rand))
+ case reflect.Int8:
+ v.SetInt(randInt64(rand))
+ case reflect.Int:
+ v.SetInt(randInt64(rand))
+ case reflect.Uint16:
+ v.SetUint(uint64(randInt64(rand)))
+ case reflect.Uint32:
+ v.SetUint(uint64(randInt64(rand)))
+ case reflect.Uint64:
+ v.SetUint(uint64(randInt64(rand)))
+ case reflect.Uint8:
+ v.SetUint(uint64(randInt64(rand)))
+ case reflect.Uint:
+ v.SetUint(uint64(randInt64(rand)))
+ case reflect.Uintptr:
+ v.SetUint(uint64(randInt64(rand)))
+ case reflect.Map:
+ numElems := rand.Intn(size)
+ v.Set(reflect.MakeMap(concrete))
+ for i := 0; i < numElems; i++ {
+ key, ok1 := sizedValue(concrete.Key(), rand, size)
+ value, ok2 := sizedValue(concrete.Elem(), rand, size)
+ if !ok1 || !ok2 {
+ return reflect.Value{}, false
+ }
+ v.SetMapIndex(key, value)
+ }
+ case reflect.Pointer:
+ if rand.Intn(size) == 0 {
+ v.SetZero() // Generate nil pointer.
+ } else {
+ elem, ok := sizedValue(concrete.Elem(), rand, size)
+ if !ok {
+ return reflect.Value{}, false
+ }
+ v.Set(reflect.New(concrete.Elem()))
+ v.Elem().Set(elem)
+ }
+ case reflect.Slice:
+ numElems := rand.Intn(size)
+ sizeLeft := size - numElems
+ v.Set(reflect.MakeSlice(concrete, numElems, numElems))
+ for i := 0; i < numElems; i++ {
+ elem, ok := sizedValue(concrete.Elem(), rand, sizeLeft)
+ if !ok {
+ return reflect.Value{}, false
+ }
+ v.Index(i).Set(elem)
+ }
+ case reflect.Array:
+ for i := 0; i < v.Len(); i++ {
+ elem, ok := sizedValue(concrete.Elem(), rand, size)
+ if !ok {
+ return reflect.Value{}, false
+ }
+ v.Index(i).Set(elem)
+ }
+ case reflect.String:
+ numChars := rand.Intn(complexSize)
+ codePoints := make([]rune, numChars)
+ for i := 0; i < numChars; i++ {
+ codePoints[i] = rune(rand.Intn(0x10ffff))
+ }
+ v.SetString(string(codePoints))
+ case reflect.Struct:
+ n := v.NumField()
+ // Divide sizeLeft evenly among the struct fields.
+ sizeLeft := size
+ if n > sizeLeft {
+ sizeLeft = 1
+ } else if n > 0 {
+ sizeLeft /= n
+ }
+ for i := 0; i < n; i++ {
+ elem, ok := sizedValue(concrete.Field(i).Type, rand, sizeLeft)
+ if !ok {
+ return reflect.Value{}, false
+ }
+ v.Field(i).Set(elem)
+ }
+ default:
+ return reflect.Value{}, false
+ }
+
+ return v, true
+}
+
+// A Config structure contains options for running a test.
+type Config struct {
+ // MaxCount sets the maximum number of iterations.
+ // If zero, MaxCountScale is used.
+ MaxCount int
+ // MaxCountScale is a non-negative scale factor applied to the
+ // default maximum.
+ // A count of zero implies the default, which is usually 100
+ // but can be set by the -quickchecks flag.
+ MaxCountScale float64
+ // Rand specifies a source of random numbers.
+ // If nil, a default pseudo-random source will be used.
+ Rand *rand.Rand
+ // Values specifies a function to generate a slice of
+ // arbitrary reflect.Values that are congruent with the
+ // arguments to the function being tested.
+ // If nil, the top-level Value function is used to generate them.
+ Values func([]reflect.Value, *rand.Rand)
+}
+
+var defaultConfig Config
+
+// getRand returns the *rand.Rand to use for a given Config.
+func (c *Config) getRand() *rand.Rand {
+ if c.Rand == nil {
+ return rand.New(rand.NewSource(time.Now().UnixNano()))
+ }
+ return c.Rand
+}
+
+// getMaxCount returns the maximum number of iterations to run for a given
+// Config.
+func (c *Config) getMaxCount() (maxCount int) {
+ maxCount = c.MaxCount
+ if maxCount == 0 {
+ if c.MaxCountScale != 0 {
+ maxCount = int(c.MaxCountScale * float64(*defaultMaxCount))
+ } else {
+ maxCount = *defaultMaxCount
+ }
+ }
+
+ return
+}
+
+// A SetupError is the result of an error in the way that check is being
+// used, independent of the functions being tested.
+type SetupError string
+
+func (s SetupError) Error() string { return string(s) }
+
+// A CheckError is the result of Check finding an error.
+type CheckError struct {
+ Count int
+ In []any
+}
+
+func (s *CheckError) Error() string {
+ return fmt.Sprintf("#%d: failed on input %s", s.Count, toString(s.In))
+}
+
+// A CheckEqualError is the result CheckEqual finding an error.
+type CheckEqualError struct {
+ CheckError
+ Out1 []any
+ Out2 []any
+}
+
+func (s *CheckEqualError) Error() string {
+ return fmt.Sprintf("#%d: failed on input %s. Output 1: %s. Output 2: %s", s.Count, toString(s.In), toString(s.Out1), toString(s.Out2))
+}
+
+// Check looks for an input to f, any function that returns bool,
+// such that f returns false. It calls f repeatedly, with arbitrary
+// values for each argument. If f returns false on a given input,
+// Check returns that input as a *CheckError.
+// For example:
+//
+// func TestOddMultipleOfThree(t *testing.T) {
+// f := func(x int) bool {
+// y := OddMultipleOfThree(x)
+// return y%2 == 1 && y%3 == 0
+// }
+// if err := quick.Check(f, nil); err != nil {
+// t.Error(err)
+// }
+// }
+func Check(f any, config *Config) error {
+ if config == nil {
+ config = &defaultConfig
+ }
+
+ fVal, fType, ok := functionAndType(f)
+ if !ok {
+ return SetupError("argument is not a function")
+ }
+
+ if fType.NumOut() != 1 {
+ return SetupError("function does not return one value")
+ }
+ if fType.Out(0).Kind() != reflect.Bool {
+ return SetupError("function does not return a bool")
+ }
+
+ arguments := make([]reflect.Value, fType.NumIn())
+ rand := config.getRand()
+ maxCount := config.getMaxCount()
+
+ for i := 0; i < maxCount; i++ {
+ err := arbitraryValues(arguments, fType, config, rand)
+ if err != nil {
+ return err
+ }
+
+ if !fVal.Call(arguments)[0].Bool() {
+ return &CheckError{i + 1, toInterfaces(arguments)}
+ }
+ }
+
+ return nil
+}
+
+// CheckEqual looks for an input on which f and g return different results.
+// It calls f and g repeatedly with arbitrary values for each argument.
+// If f and g return different answers, CheckEqual returns a *CheckEqualError
+// describing the input and the outputs.
+func CheckEqual(f, g any, config *Config) error {
+ if config == nil {
+ config = &defaultConfig
+ }
+
+ x, xType, ok := functionAndType(f)
+ if !ok {
+ return SetupError("f is not a function")
+ }
+ y, yType, ok := functionAndType(g)
+ if !ok {
+ return SetupError("g is not a function")
+ }
+
+ if xType != yType {
+ return SetupError("functions have different types")
+ }
+
+ arguments := make([]reflect.Value, xType.NumIn())
+ rand := config.getRand()
+ maxCount := config.getMaxCount()
+
+ for i := 0; i < maxCount; i++ {
+ err := arbitraryValues(arguments, xType, config, rand)
+ if err != nil {
+ return err
+ }
+
+ xOut := toInterfaces(x.Call(arguments))
+ yOut := toInterfaces(y.Call(arguments))
+
+ if !reflect.DeepEqual(xOut, yOut) {
+ return &CheckEqualError{CheckError{i + 1, toInterfaces(arguments)}, xOut, yOut}
+ }
+ }
+
+ return nil
+}
+
+// arbitraryValues writes Values to args such that args contains Values
+// suitable for calling f.
+func arbitraryValues(args []reflect.Value, f reflect.Type, config *Config, rand *rand.Rand) (err error) {
+ if config.Values != nil {
+ config.Values(args, rand)
+ return
+ }
+
+ for j := 0; j < len(args); j++ {
+ var ok bool
+ args[j], ok = Value(f.In(j), rand)
+ if !ok {
+ err = SetupError(fmt.Sprintf("cannot create arbitrary value of type %s for argument %d", f.In(j), j))
+ return
+ }
+ }
+
+ return
+}
+
+func functionAndType(f any) (v reflect.Value, t reflect.Type, ok bool) {
+ v = reflect.ValueOf(f)
+ ok = v.Kind() == reflect.Func
+ if !ok {
+ return
+ }
+ t = v.Type()
+ return
+}
+
+func toInterfaces(values []reflect.Value) []any {
+ ret := make([]any, len(values))
+ for i, v := range values {
+ ret[i] = v.Interface()
+ }
+ return ret
+}
+
+func toString(interfaces []any) string {
+ s := make([]string, len(interfaces))
+ for i, v := range interfaces {
+ s[i] = fmt.Sprintf("%#v", v)
+ }
+ return strings.Join(s, ", ")
+}
diff --git a/contrib/go/_std_1.21/src/testing/quick/ya.make b/contrib/go/_std_1.21/src/testing/quick/ya.make
new file mode 100644
index 0000000000..17ed663d9a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/quick/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ quick.go
+)
+
+GO_TEST_SRCS(quick_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/testing/run_example.go b/contrib/go/_std_1.21/src/testing/run_example.go
new file mode 100644
index 0000000000..b2c5c3d14c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/run_example.go
@@ -0,0 +1,66 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !js && !wasip1
+
+// TODO(@musiol, @odeke-em): re-unify this entire file back into
+// example.go when js/wasm gets an os.Pipe implementation
+// and no longer needs this separation.
+
+package testing
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "strings"
+ "time"
+)
+
+func runExample(eg InternalExample) (ok bool) {
+ if chatty.on {
+ fmt.Printf("%s=== RUN %s\n", chatty.prefix(), eg.Name)
+ }
+
+ // Capture stdout.
+ stdout := os.Stdout
+ r, w, err := os.Pipe()
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ os.Stdout = w
+ outC := make(chan string)
+ go func() {
+ var buf strings.Builder
+ _, err := io.Copy(&buf, r)
+ r.Close()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
+ os.Exit(1)
+ }
+ outC <- buf.String()
+ }()
+
+ finished := false
+ start := time.Now()
+
+ // Clean up in a deferred call so we can recover if the example panics.
+ defer func() {
+ timeSpent := time.Since(start)
+
+ // Close pipe, restore stdout, get output.
+ w.Close()
+ os.Stdout = stdout
+ out := <-outC
+
+ err := recover()
+ ok = eg.processRunResult(out, timeSpent, finished, err)
+ }()
+
+ // Run example.
+ eg.F()
+ finished = true
+ return
+}
diff --git a/contrib/go/_std_1.21/src/testing/slogtest/slogtest.go b/contrib/go/_std_1.21/src/testing/slogtest/slogtest.go
new file mode 100644
index 0000000000..b16d1227dc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/slogtest/slogtest.go
@@ -0,0 +1,322 @@
+// Copyright 2023 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 slogtest implements support for testing implementations of log/slog.Handler.
+package slogtest
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "log/slog"
+ "reflect"
+ "runtime"
+ "time"
+)
+
+type testCase struct {
+ // If non-empty, explanation explains the violated constraint.
+ explanation string
+ // f executes a single log event using its argument logger.
+ // So that mkdescs.sh can generate the right description,
+ // the body of f must appear on a single line whose first
+ // non-whitespace characters are "l.".
+ f func(*slog.Logger)
+ // If mod is not nil, it is called to modify the Record
+ // generated by the Logger before it is passed to the Handler.
+ mod func(*slog.Record)
+ // checks is a list of checks to run on the result.
+ checks []check
+}
+
+// TestHandler tests a [slog.Handler].
+// If TestHandler finds any misbehaviors, it returns an error for each,
+// combined into a single error with errors.Join.
+//
+// TestHandler installs the given Handler in a [slog.Logger] and
+// makes several calls to the Logger's output methods.
+//
+// The results function is invoked after all such calls.
+// It should return a slice of map[string]any, one for each call to a Logger output method.
+// The keys and values of the map should correspond to the keys and values of the Handler's
+// output. Each group in the output should be represented as its own nested map[string]any.
+// The standard keys slog.TimeKey, slog.LevelKey and slog.MessageKey should be used.
+//
+// If the Handler outputs JSON, then calling [encoding/json.Unmarshal] with a `map[string]any`
+// will create the right data structure.
+//
+// If a Handler intentionally drops an attribute that is checked by a test,
+// then the results function should check for its absence and add it to the map it returns.
+func TestHandler(h slog.Handler, results func() []map[string]any) error {
+ cases := []testCase{
+ {
+ explanation: withSource("this test expects slog.TimeKey, slog.LevelKey and slog.MessageKey"),
+ f: func(l *slog.Logger) {
+ l.Info("message")
+ },
+ checks: []check{
+ hasKey(slog.TimeKey),
+ hasKey(slog.LevelKey),
+ hasAttr(slog.MessageKey, "message"),
+ },
+ },
+ {
+ explanation: withSource("a Handler should output attributes passed to the logging function"),
+ f: func(l *slog.Logger) {
+ l.Info("message", "k", "v")
+ },
+ checks: []check{
+ hasAttr("k", "v"),
+ },
+ },
+ {
+ explanation: withSource("a Handler should ignore an empty Attr"),
+ f: func(l *slog.Logger) {
+ l.Info("msg", "a", "b", "", nil, "c", "d")
+ },
+ checks: []check{
+ hasAttr("a", "b"),
+ missingKey(""),
+ hasAttr("c", "d"),
+ },
+ },
+ {
+ explanation: withSource("a Handler should ignore a zero Record.Time"),
+ f: func(l *slog.Logger) {
+ l.Info("msg", "k", "v")
+ },
+ mod: func(r *slog.Record) { r.Time = time.Time{} },
+ checks: []check{
+ missingKey(slog.TimeKey),
+ },
+ },
+ {
+ explanation: withSource("a Handler should include the attributes from the WithAttrs method"),
+ f: func(l *slog.Logger) {
+ l.With("a", "b").Info("msg", "k", "v")
+ },
+ checks: []check{
+ hasAttr("a", "b"),
+ hasAttr("k", "v"),
+ },
+ },
+ {
+ explanation: withSource("a Handler should handle Group attributes"),
+ f: func(l *slog.Logger) {
+ l.Info("msg", "a", "b", slog.Group("G", slog.String("c", "d")), "e", "f")
+ },
+ checks: []check{
+ hasAttr("a", "b"),
+ inGroup("G", hasAttr("c", "d")),
+ hasAttr("e", "f"),
+ },
+ },
+ {
+ explanation: withSource("a Handler should ignore an empty group"),
+ f: func(l *slog.Logger) {
+ l.Info("msg", "a", "b", slog.Group("G"), "e", "f")
+ },
+ checks: []check{
+ hasAttr("a", "b"),
+ missingKey("G"),
+ hasAttr("e", "f"),
+ },
+ },
+ {
+ explanation: withSource("a Handler should inline the Attrs of a group with an empty key"),
+ f: func(l *slog.Logger) {
+ l.Info("msg", "a", "b", slog.Group("", slog.String("c", "d")), "e", "f")
+
+ },
+ checks: []check{
+ hasAttr("a", "b"),
+ hasAttr("c", "d"),
+ hasAttr("e", "f"),
+ },
+ },
+ {
+ explanation: withSource("a Handler should handle the WithGroup method"),
+ f: func(l *slog.Logger) {
+ l.WithGroup("G").Info("msg", "a", "b")
+ },
+ checks: []check{
+ hasKey(slog.TimeKey),
+ hasKey(slog.LevelKey),
+ hasAttr(slog.MessageKey, "msg"),
+ missingKey("a"),
+ inGroup("G", hasAttr("a", "b")),
+ },
+ },
+ {
+ explanation: withSource("a Handler should handle multiple WithGroup and WithAttr calls"),
+ f: func(l *slog.Logger) {
+ l.With("a", "b").WithGroup("G").With("c", "d").WithGroup("H").Info("msg", "e", "f")
+ },
+ checks: []check{
+ hasKey(slog.TimeKey),
+ hasKey(slog.LevelKey),
+ hasAttr(slog.MessageKey, "msg"),
+ hasAttr("a", "b"),
+ inGroup("G", hasAttr("c", "d")),
+ inGroup("G", inGroup("H", hasAttr("e", "f"))),
+ },
+ },
+ {
+ explanation: withSource("a Handler should not output groups for an empty Record"),
+ f: func(l *slog.Logger) {
+ l.With("a", "b").WithGroup("G").With("c", "d").WithGroup("H").Info("msg")
+ },
+ checks: []check{
+ hasKey(slog.TimeKey),
+ hasKey(slog.LevelKey),
+ hasAttr(slog.MessageKey, "msg"),
+ hasAttr("a", "b"),
+ inGroup("G", hasAttr("c", "d")),
+ inGroup("G", missingKey("H")),
+ },
+ },
+ {
+ explanation: withSource("a Handler should call Resolve on attribute values"),
+ f: func(l *slog.Logger) {
+ l.Info("msg", "k", &replace{"replaced"})
+ },
+ checks: []check{hasAttr("k", "replaced")},
+ },
+ {
+ explanation: withSource("a Handler should call Resolve on attribute values in groups"),
+ f: func(l *slog.Logger) {
+ l.Info("msg",
+ slog.Group("G",
+ slog.String("a", "v1"),
+ slog.Any("b", &replace{"v2"})))
+ },
+ checks: []check{
+ inGroup("G", hasAttr("a", "v1")),
+ inGroup("G", hasAttr("b", "v2")),
+ },
+ },
+ {
+ explanation: withSource("a Handler should call Resolve on attribute values from WithAttrs"),
+ f: func(l *slog.Logger) {
+ l = l.With("k", &replace{"replaced"})
+ l.Info("msg")
+ },
+ checks: []check{hasAttr("k", "replaced")},
+ },
+ {
+ explanation: withSource("a Handler should call Resolve on attribute values in groups from WithAttrs"),
+ f: func(l *slog.Logger) {
+ l = l.With(slog.Group("G",
+ slog.String("a", "v1"),
+ slog.Any("b", &replace{"v2"})))
+ l.Info("msg")
+ },
+ checks: []check{
+ inGroup("G", hasAttr("a", "v1")),
+ inGroup("G", hasAttr("b", "v2")),
+ },
+ },
+ }
+
+ // Run the handler on the test cases.
+ for _, c := range cases {
+ ht := h
+ if c.mod != nil {
+ ht = &wrapper{h, c.mod}
+ }
+ l := slog.New(ht)
+ c.f(l)
+ }
+
+ // Collect and check the results.
+ var errs []error
+ res := results()
+ if g, w := len(res), len(cases); g != w {
+ return fmt.Errorf("got %d results, want %d", g, w)
+ }
+ for i, got := range results() {
+ c := cases[i]
+ for _, check := range c.checks {
+ if p := check(got); p != "" {
+ errs = append(errs, fmt.Errorf("%s: %s", p, c.explanation))
+ }
+ }
+ }
+ return errors.Join(errs...)
+}
+
+type check func(map[string]any) string
+
+func hasKey(key string) check {
+ return func(m map[string]any) string {
+ if _, ok := m[key]; !ok {
+ return fmt.Sprintf("missing key %q", key)
+ }
+ return ""
+ }
+}
+
+func missingKey(key string) check {
+ return func(m map[string]any) string {
+ if _, ok := m[key]; ok {
+ return fmt.Sprintf("unexpected key %q", key)
+ }
+ return ""
+ }
+}
+
+func hasAttr(key string, wantVal any) check {
+ return func(m map[string]any) string {
+ if s := hasKey(key)(m); s != "" {
+ return s
+ }
+ gotVal := m[key]
+ if !reflect.DeepEqual(gotVal, wantVal) {
+ return fmt.Sprintf("%q: got %#v, want %#v", key, gotVal, wantVal)
+ }
+ return ""
+ }
+}
+
+func inGroup(name string, c check) check {
+ return func(m map[string]any) string {
+ v, ok := m[name]
+ if !ok {
+ return fmt.Sprintf("missing group %q", name)
+ }
+ g, ok := v.(map[string]any)
+ if !ok {
+ return fmt.Sprintf("value for group %q is not map[string]any", name)
+ }
+ return c(g)
+ }
+}
+
+type wrapper struct {
+ slog.Handler
+ mod func(*slog.Record)
+}
+
+func (h *wrapper) Handle(ctx context.Context, r slog.Record) error {
+ h.mod(&r)
+ return h.Handler.Handle(ctx, r)
+}
+
+func withSource(s string) string {
+ _, file, line, ok := runtime.Caller(1)
+ if !ok {
+ panic("runtime.Caller failed")
+ }
+ return fmt.Sprintf("%s (%s:%d)", s, file, line)
+}
+
+type replace struct {
+ v any
+}
+
+func (r *replace) LogValue() slog.Value { return slog.AnyValue(r.v) }
+
+func (r *replace) String() string {
+ return fmt.Sprintf("<replace(%v)>", r.v)
+}
diff --git a/contrib/go/_std_1.21/src/testing/slogtest/ya.make b/contrib/go/_std_1.21/src/testing/slogtest/ya.make
new file mode 100644
index 0000000000..3d74614016
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/slogtest/ya.make
@@ -0,0 +1,12 @@
+GO_LIBRARY()
+
+SRCS(
+ slogtest.go
+)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/testing/testing.go b/contrib/go/_std_1.21/src/testing/testing.go
new file mode 100644
index 0000000000..fcf7048f23
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/testing.go
@@ -0,0 +1,2302 @@
+// Copyright 2009 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 testing provides support for automated testing of Go packages.
+// It is intended to be used in concert with the "go test" command, which automates
+// execution of any function of the form
+//
+// func TestXxx(*testing.T)
+//
+// where Xxx does not start with a lowercase letter. The function name
+// serves to identify the test routine.
+//
+// Within these functions, use the Error, Fail or related methods to signal failure.
+//
+// To write a new test suite, create a file that
+// contains the TestXxx functions as described here,
+// and give that file a name ending in "_test.go".
+// The file will be excluded from regular
+// package builds but will be included when the "go test" command is run.
+//
+// The test file can be in the same package as the one being tested,
+// or in a corresponding package with the suffix "_test".
+//
+// If the test file is in the same package, it may refer to unexported
+// identifiers within the package, as in this example:
+//
+// package abs
+//
+// import "testing"
+//
+// func TestAbs(t *testing.T) {
+// got := Abs(-1)
+// if got != 1 {
+// t.Errorf("Abs(-1) = %d; want 1", got)
+// }
+// }
+//
+// If the file is in a separate "_test" package, the package being tested
+// must be imported explicitly and only its exported identifiers may be used.
+// This is known as "black box" testing.
+//
+// package abs_test
+//
+// import (
+// "testing"
+//
+// "path_to_pkg/abs"
+// )
+//
+// func TestAbs(t *testing.T) {
+// got := abs.Abs(-1)
+// if got != 1 {
+// t.Errorf("Abs(-1) = %d; want 1", got)
+// }
+// }
+//
+// For more detail, run "go help test" and "go help testflag".
+//
+// # Benchmarks
+//
+// Functions of the form
+//
+// func BenchmarkXxx(*testing.B)
+//
+// are considered benchmarks, and are executed by the "go test" command when
+// its -bench flag is provided. Benchmarks are run sequentially.
+//
+// For a description of the testing flags, see
+// https://golang.org/cmd/go/#hdr-Testing_flags.
+//
+// A sample benchmark function looks like this:
+//
+// func BenchmarkRandInt(b *testing.B) {
+// for i := 0; i < b.N; i++ {
+// rand.Int()
+// }
+// }
+//
+// The benchmark function must run the target code b.N times.
+// During benchmark execution, b.N is adjusted until the benchmark function lasts
+// long enough to be timed reliably. The output
+//
+// BenchmarkRandInt-8 68453040 17.8 ns/op
+//
+// means that the loop ran 68453040 times at a speed of 17.8 ns per loop.
+//
+// If a benchmark needs some expensive setup before running, the timer
+// may be reset:
+//
+// func BenchmarkBigLen(b *testing.B) {
+// big := NewBig()
+// b.ResetTimer()
+// for i := 0; i < b.N; i++ {
+// big.Len()
+// }
+// }
+//
+// If a benchmark needs to test performance in a parallel setting, it may use
+// the RunParallel helper function; such benchmarks are intended to be used with
+// the go test -cpu flag:
+//
+// func BenchmarkTemplateParallel(b *testing.B) {
+// templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
+// b.RunParallel(func(pb *testing.PB) {
+// var buf bytes.Buffer
+// for pb.Next() {
+// buf.Reset()
+// templ.Execute(&buf, "World")
+// }
+// })
+// }
+//
+// A detailed specification of the benchmark results format is given
+// in https://golang.org/design/14313-benchmark-format.
+//
+// There are standard tools for working with benchmark results at
+// https://golang.org/x/perf/cmd.
+// In particular, https://golang.org/x/perf/cmd/benchstat performs
+// statistically robust A/B comparisons.
+//
+// # Examples
+//
+// The package also runs and verifies example code. Example functions may
+// include a concluding line comment that begins with "Output:" and is compared with
+// the standard output of the function when the tests are run. (The comparison
+// ignores leading and trailing space.) These are examples of an example:
+//
+// func ExampleHello() {
+// fmt.Println("hello")
+// // Output: hello
+// }
+//
+// func ExampleSalutations() {
+// fmt.Println("hello, and")
+// fmt.Println("goodbye")
+// // Output:
+// // hello, and
+// // goodbye
+// }
+//
+// The comment prefix "Unordered output:" is like "Output:", but matches any
+// line order:
+//
+// func ExamplePerm() {
+// for _, value := range Perm(5) {
+// fmt.Println(value)
+// }
+// // Unordered output: 4
+// // 2
+// // 1
+// // 3
+// // 0
+// }
+//
+// Example functions without output comments are compiled but not executed.
+//
+// The naming convention to declare examples for the package, a function F, a type T and
+// method M on type T are:
+//
+// func Example() { ... }
+// func ExampleF() { ... }
+// func ExampleT() { ... }
+// func ExampleT_M() { ... }
+//
+// Multiple example functions for a package/type/function/method may be provided by
+// appending a distinct suffix to the name. The suffix must start with a
+// lower-case letter.
+//
+// func Example_suffix() { ... }
+// func ExampleF_suffix() { ... }
+// func ExampleT_suffix() { ... }
+// func ExampleT_M_suffix() { ... }
+//
+// The entire test file is presented as the example when it contains a single
+// example function, at least one other function, type, variable, or constant
+// declaration, and no test or benchmark functions.
+//
+// # Fuzzing
+//
+// 'go test' and the testing package support fuzzing, a testing technique where
+// a function is called with randomly generated inputs to find bugs not
+// anticipated by unit tests.
+//
+// Functions of the form
+//
+// func FuzzXxx(*testing.F)
+//
+// are considered fuzz tests.
+//
+// For example:
+//
+// func FuzzHex(f *testing.F) {
+// for _, seed := range [][]byte{{}, {0}, {9}, {0xa}, {0xf}, {1, 2, 3, 4}} {
+// f.Add(seed)
+// }
+// f.Fuzz(func(t *testing.T, in []byte) {
+// enc := hex.EncodeToString(in)
+// out, err := hex.DecodeString(enc)
+// if err != nil {
+// t.Fatalf("%v: decode: %v", in, err)
+// }
+// if !bytes.Equal(in, out) {
+// t.Fatalf("%v: not equal after round trip: %v", in, out)
+// }
+// })
+// }
+//
+// A fuzz test maintains a seed corpus, or a set of inputs which are run by
+// default, and can seed input generation. Seed inputs may be registered by
+// calling (*F).Add or by storing files in the directory testdata/fuzz/<Name>
+// (where <Name> is the name of the fuzz test) within the package containing
+// the fuzz test. Seed inputs are optional, but the fuzzing engine may find
+// bugs more efficiently when provided with a set of small seed inputs with good
+// code coverage. These seed inputs can also serve as regression tests for bugs
+// identified through fuzzing.
+//
+// The function passed to (*F).Fuzz within the fuzz test is considered the fuzz
+// target. A fuzz target must accept a *T parameter, followed by one or more
+// parameters for random inputs. The types of arguments passed to (*F).Add must
+// be identical to the types of these parameters. The fuzz target may signal
+// that it's found a problem the same way tests do: by calling T.Fail (or any
+// method that calls it like T.Error or T.Fatal) or by panicking.
+//
+// When fuzzing is enabled (by setting the -fuzz flag to a regular expression
+// that matches a specific fuzz test), the fuzz target is called with arguments
+// generated by repeatedly making random changes to the seed inputs. On
+// supported platforms, 'go test' compiles the test executable with fuzzing
+// coverage instrumentation. The fuzzing engine uses that instrumentation to
+// find and cache inputs that expand coverage, increasing the likelihood of
+// finding bugs. If the fuzz target fails for a given input, the fuzzing engine
+// writes the inputs that caused the failure to a file in the directory
+// testdata/fuzz/<Name> within the package directory. This file later serves as
+// a seed input. If the file can't be written at that location (for example,
+// because the directory is read-only), the fuzzing engine writes the file to
+// the fuzz cache directory within the build cache instead.
+//
+// When fuzzing is disabled, the fuzz target is called with the seed inputs
+// registered with F.Add and seed inputs from testdata/fuzz/<Name>. In this
+// mode, the fuzz test acts much like a regular test, with subtests started
+// with F.Fuzz instead of T.Run.
+//
+// See https://go.dev/doc/fuzz for documentation about fuzzing.
+//
+// # Skipping
+//
+// Tests or benchmarks may be skipped at run time with a call to
+// the Skip method of *T or *B:
+//
+// func TestTimeConsuming(t *testing.T) {
+// if testing.Short() {
+// t.Skip("skipping test in short mode.")
+// }
+// ...
+// }
+//
+// The Skip method of *T can be used in a fuzz target if the input is invalid,
+// but should not be considered a failing input. For example:
+//
+// func FuzzJSONMarshaling(f *testing.F) {
+// f.Fuzz(func(t *testing.T, b []byte) {
+// var v interface{}
+// if err := json.Unmarshal(b, &v); err != nil {
+// t.Skip()
+// }
+// if _, err := json.Marshal(v); err != nil {
+// t.Errorf("Marshal: %v", err)
+// }
+// })
+// }
+//
+// # Subtests and Sub-benchmarks
+//
+// The Run methods of T and B allow defining subtests and sub-benchmarks,
+// without having to define separate functions for each. This enables uses
+// like table-driven benchmarks and creating hierarchical tests.
+// It also provides a way to share common setup and tear-down code:
+//
+// func TestFoo(t *testing.T) {
+// // <setup code>
+// t.Run("A=1", func(t *testing.T) { ... })
+// t.Run("A=2", func(t *testing.T) { ... })
+// t.Run("B=1", func(t *testing.T) { ... })
+// // <tear-down code>
+// }
+//
+// Each subtest and sub-benchmark has a unique name: the combination of the name
+// of the top-level test and the sequence of names passed to Run, separated by
+// slashes, with an optional trailing sequence number for disambiguation.
+//
+// The argument to the -run, -bench, and -fuzz command-line flags is an unanchored regular
+// expression that matches the test's name. For tests with multiple slash-separated
+// elements, such as subtests, the argument is itself slash-separated, with
+// expressions matching each name element in turn. Because it is unanchored, an
+// empty expression matches any string.
+// For example, using "matching" to mean "whose name contains":
+//
+// go test -run '' # Run all tests.
+// go test -run Foo # Run top-level tests matching "Foo", such as "TestFooBar".
+// go test -run Foo/A= # For top-level tests matching "Foo", run subtests matching "A=".
+// go test -run /A=1 # For all top-level tests, run subtests matching "A=1".
+// go test -fuzz FuzzFoo # Fuzz the target matching "FuzzFoo"
+//
+// The -run argument can also be used to run a specific value in the seed
+// corpus, for debugging. For example:
+//
+// go test -run=FuzzFoo/9ddb952d9814
+//
+// The -fuzz and -run flags can both be set, in order to fuzz a target but
+// skip the execution of all other tests.
+//
+// Subtests can also be used to control parallelism. A parent test will only
+// complete once all of its subtests complete. In this example, all tests are
+// run in parallel with each other, and only with each other, regardless of
+// other top-level tests that may be defined:
+//
+// func TestGroupedParallel(t *testing.T) {
+// for _, tc := range tests {
+// tc := tc // capture range variable
+// t.Run(tc.Name, func(t *testing.T) {
+// t.Parallel()
+// ...
+// })
+// }
+// }
+//
+// Run does not return until parallel subtests have completed, providing a way
+// to clean up after a group of parallel tests:
+//
+// func TestTeardownParallel(t *testing.T) {
+// // This Run will not return until the parallel tests finish.
+// t.Run("group", func(t *testing.T) {
+// t.Run("Test1", parallelTest1)
+// t.Run("Test2", parallelTest2)
+// t.Run("Test3", parallelTest3)
+// })
+// // <tear-down code>
+// }
+//
+// # Main
+//
+// It is sometimes necessary for a test or benchmark program to do extra setup or teardown
+// before or after it executes. It is also sometimes necessary to control
+// which code runs on the main thread. To support these and other cases,
+// if a test file contains a function:
+//
+// func TestMain(m *testing.M)
+//
+// then the generated test will call TestMain(m) instead of running the tests or benchmarks
+// directly. TestMain runs in the main goroutine and can do whatever setup
+// and teardown is necessary around a call to m.Run. m.Run will return an exit
+// code that may be passed to os.Exit. If TestMain returns, the test wrapper
+// will pass the result of m.Run to os.Exit itself.
+//
+// When TestMain is called, flag.Parse has not been run. If TestMain depends on
+// command-line flags, including those of the testing package, it should call
+// flag.Parse explicitly. Command line flags are always parsed by the time test
+// or benchmark functions run.
+//
+// A simple implementation of TestMain is:
+//
+// func TestMain(m *testing.M) {
+// // call flag.Parse() here if TestMain uses flags
+// os.Exit(m.Run())
+// }
+//
+// TestMain is a low-level primitive and should not be necessary for casual
+// testing needs, where ordinary test functions suffice.
+package testing
+
+import (
+ "bytes"
+ "errors"
+ "flag"
+ "fmt"
+ "internal/goexperiment"
+ "internal/race"
+ "io"
+ "math/rand"
+ "os"
+ "reflect"
+ "runtime"
+ "runtime/debug"
+ "runtime/trace"
+ "sort"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "time"
+ "unicode"
+ "unicode/utf8"
+)
+
+var initRan bool
+
+// Init registers testing flags. These flags are automatically registered by
+// the "go test" command before running test functions, so Init is only needed
+// when calling functions such as Benchmark without using "go test".
+//
+// Init has no effect if it was already called.
+func Init() {
+ if initRan {
+ return
+ }
+ initRan = true
+ // The short flag requests that tests run more quickly, but its functionality
+ // is provided by test writers themselves. The testing package is just its
+ // home. The all.bash installation script sets it to make installation more
+ // efficient, but by default the flag is off so a plain "go test" will do a
+ // full test of the package.
+ short = flag.Bool("test.short", false, "run smaller test suite to save time")
+
+ // The failfast flag requests that test execution stop after the first test failure.
+ failFast = flag.Bool("test.failfast", false, "do not start new tests after the first test failure")
+
+ // The directory in which to create profile files and the like. When run from
+ // "go test", the binary always runs in the source directory for the package;
+ // this flag lets "go test" tell the binary to write the files in the directory where
+ // the "go test" command is run.
+ outputDir = flag.String("test.outputdir", "", "write profiles to `dir`")
+ // Report as tests are run; default is silent for success.
+ flag.Var(&chatty, "test.v", "verbose: print additional output")
+ count = flag.Uint("test.count", 1, "run tests and benchmarks `n` times")
+ coverProfile = flag.String("test.coverprofile", "", "write a coverage profile to `file`")
+ gocoverdir = flag.String("test.gocoverdir", "", "write coverage intermediate files to this directory")
+ matchList = flag.String("test.list", "", "list tests, examples, and benchmarks matching `regexp` then exit")
+ match = flag.String("test.run", "", "run only tests and examples matching `regexp`")
+ skip = flag.String("test.skip", "", "do not list or run tests matching `regexp`")
+ memProfile = flag.String("test.memprofile", "", "write an allocation profile to `file`")
+ memProfileRate = flag.Int("test.memprofilerate", 0, "set memory allocation profiling `rate` (see runtime.MemProfileRate)")
+ cpuProfile = flag.String("test.cpuprofile", "", "write a cpu profile to `file`")
+ blockProfile = flag.String("test.blockprofile", "", "write a goroutine blocking profile to `file`")
+ blockProfileRate = flag.Int("test.blockprofilerate", 1, "set blocking profile `rate` (see runtime.SetBlockProfileRate)")
+ mutexProfile = flag.String("test.mutexprofile", "", "write a mutex contention profile to the named file after execution")
+ mutexProfileFraction = flag.Int("test.mutexprofilefraction", 1, "if >= 0, calls runtime.SetMutexProfileFraction()")
+ panicOnExit0 = flag.Bool("test.paniconexit0", false, "panic on call to os.Exit(0)")
+ traceFile = flag.String("test.trace", "", "write an execution trace to `file`")
+ timeout = flag.Duration("test.timeout", 0, "panic test binary after duration `d` (default 0, timeout disabled)")
+ cpuListStr = flag.String("test.cpu", "", "comma-separated `list` of cpu counts to run each test with")
+ parallel = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "run at most `n` tests in parallel")
+ testlog = flag.String("test.testlogfile", "", "write test action log to `file` (for use only by cmd/go)")
+ shuffle = flag.String("test.shuffle", "off", "randomize the execution order of tests and benchmarks")
+ fullPath = flag.Bool("test.fullpath", false, "show full file names in error messages")
+
+ initBenchmarkFlags()
+ initFuzzFlags()
+}
+
+var (
+ // Flags, registered during Init.
+ short *bool
+ failFast *bool
+ outputDir *string
+ chatty chattyFlag
+ count *uint
+ coverProfile *string
+ gocoverdir *string
+ matchList *string
+ match *string
+ skip *string
+ memProfile *string
+ memProfileRate *int
+ cpuProfile *string
+ blockProfile *string
+ blockProfileRate *int
+ mutexProfile *string
+ mutexProfileFraction *int
+ panicOnExit0 *bool
+ traceFile *string
+ timeout *time.Duration
+ cpuListStr *string
+ parallel *int
+ shuffle *string
+ testlog *string
+ fullPath *bool
+
+ haveExamples bool // are there examples?
+
+ cpuList []int
+ testlogFile *os.File
+
+ numFailed atomic.Uint32 // number of test failures
+
+ running sync.Map // map[string]time.Time of running, unpaused tests
+)
+
+type chattyFlag struct {
+ on bool // -v is set in some form
+ json bool // -v=test2json is set, to make output better for test2json
+}
+
+func (*chattyFlag) IsBoolFlag() bool { return true }
+
+func (f *chattyFlag) Set(arg string) error {
+ switch arg {
+ default:
+ return fmt.Errorf("invalid flag -test.v=%s", arg)
+ case "true", "test2json":
+ f.on = true
+ f.json = arg == "test2json"
+ case "false":
+ f.on = false
+ f.json = false
+ }
+ return nil
+}
+
+func (f *chattyFlag) String() string {
+ if f.json {
+ return "test2json"
+ }
+ if f.on {
+ return "true"
+ }
+ return "false"
+}
+
+func (f *chattyFlag) Get() any {
+ if f.json {
+ return "test2json"
+ }
+ return f.on
+}
+
+const marker = byte(0x16) // ^V for framing
+
+func (f *chattyFlag) prefix() string {
+ if f.json {
+ return string(marker)
+ }
+ return ""
+}
+
+type chattyPrinter struct {
+ w io.Writer
+ lastNameMu sync.Mutex // guards lastName
+ lastName string // last printed test name in chatty mode
+ json bool // -v=json output mode
+}
+
+func newChattyPrinter(w io.Writer) *chattyPrinter {
+ return &chattyPrinter{w: w, json: chatty.json}
+}
+
+// prefix is like chatty.prefix but using p.json instead of chatty.json.
+// Using p.json allows tests to check the json behavior without modifying
+// the global variable. For convenience, we allow p == nil and treat
+// that as not in json mode (because it's not chatty at all).
+func (p *chattyPrinter) prefix() string {
+ if p != nil && p.json {
+ return string(marker)
+ }
+ return ""
+}
+
+// Updatef prints a message about the status of the named test to w.
+//
+// The formatted message must include the test name itself.
+func (p *chattyPrinter) Updatef(testName, format string, args ...any) {
+ p.lastNameMu.Lock()
+ defer p.lastNameMu.Unlock()
+
+ // Since the message already implies an association with a specific new test,
+ // we don't need to check what the old test name was or log an extra NAME line
+ // for it. (We're updating it anyway, and the current message already includes
+ // the test name.)
+ p.lastName = testName
+ fmt.Fprintf(p.w, p.prefix()+format, args...)
+}
+
+// Printf prints a message, generated by the named test, that does not
+// necessarily mention that tests's name itself.
+func (p *chattyPrinter) Printf(testName, format string, args ...any) {
+ p.lastNameMu.Lock()
+ defer p.lastNameMu.Unlock()
+
+ if p.lastName == "" {
+ p.lastName = testName
+ } else if p.lastName != testName {
+ fmt.Fprintf(p.w, "%s=== NAME %s\n", p.prefix(), testName)
+ p.lastName = testName
+ }
+
+ fmt.Fprintf(p.w, format, args...)
+}
+
+// The maximum number of stack frames to go through when skipping helper functions for
+// the purpose of decorating log messages.
+const maxStackLen = 50
+
+// common holds the elements common between T and B and
+// captures common methods such as Errorf.
+type common struct {
+ mu sync.RWMutex // guards this group of fields
+ output []byte // Output generated by test or benchmark.
+ w io.Writer // For flushToParent.
+ ran bool // Test or benchmark (or one of its subtests) was executed.
+ failed bool // Test or benchmark has failed.
+ skipped bool // Test or benchmark has been skipped.
+ done bool // Test is finished and all subtests have completed.
+ helperPCs map[uintptr]struct{} // functions to be skipped when writing file/line info
+ helperNames map[string]struct{} // helperPCs converted to function names
+ cleanups []func() // optional functions to be called at the end of the test
+ cleanupName string // Name of the cleanup function.
+ cleanupPc []uintptr // The stack trace at the point where Cleanup was called.
+ finished bool // Test function has completed.
+ inFuzzFn bool // Whether the fuzz target, if this is one, is running.
+
+ chatty *chattyPrinter // A copy of chattyPrinter, if the chatty flag is set.
+ bench bool // Whether the current test is a benchmark.
+ hasSub atomic.Bool // whether there are sub-benchmarks.
+ cleanupStarted atomic.Bool // Registered cleanup callbacks have started to execute
+ raceErrors int // Number of races detected during test.
+ runner string // Function name of tRunner running the test.
+ isParallel bool // Whether the test is parallel.
+
+ parent *common
+ level int // Nesting depth of test or benchmark.
+ creator []uintptr // If level > 0, the stack trace at the point where the parent called t.Run.
+ name string // Name of test or benchmark.
+ start time.Time // Time test or benchmark started
+ duration time.Duration
+ barrier chan bool // To signal parallel subtests they may start. Nil when T.Parallel is not present (B) or not usable (when fuzzing).
+ signal chan bool // To signal a test is done.
+ sub []*T // Queue of subtests to be run in parallel.
+
+ tempDirMu sync.Mutex
+ tempDir string
+ tempDirErr error
+ tempDirSeq int32
+}
+
+// Short reports whether the -test.short flag is set.
+func Short() bool {
+ if short == nil {
+ panic("testing: Short called before Init")
+ }
+ // Catch code that calls this from TestMain without first calling flag.Parse.
+ if !flag.Parsed() {
+ panic("testing: Short called before Parse")
+ }
+
+ return *short
+}
+
+// testBinary is set by cmd/go to "1" if this is a binary built by "go test".
+// The value is set to "1" by a -X option to cmd/link. We assume that
+// because this is possible, the compiler will not optimize testBinary
+// into a constant on the basis that it is an unexported package-scope
+// variable that is never changed. If the compiler ever starts implementing
+// such an optimization, we will need some technique to mark this variable
+// as "changed by a cmd/link -X option".
+var testBinary = "0"
+
+// Testing reports whether the current code is being run in a test.
+// This will report true in programs created by "go test",
+// false in programs created by "go build".
+func Testing() bool {
+ return testBinary == "1"
+}
+
+// CoverMode reports what the test coverage mode is set to. The
+// values are "set", "count", or "atomic". The return value will be
+// empty if test coverage is not enabled.
+func CoverMode() string {
+ if goexperiment.CoverageRedesign {
+ return cover2.mode
+ }
+ return cover.Mode
+}
+
+// Verbose reports whether the -test.v flag is set.
+func Verbose() bool {
+ // Same as in Short.
+ if !flag.Parsed() {
+ panic("testing: Verbose called before Parse")
+ }
+ return chatty.on
+}
+
+func (c *common) checkFuzzFn(name string) {
+ if c.inFuzzFn {
+ panic(fmt.Sprintf("testing: f.%s was called inside the fuzz target, use t.%s instead", name, name))
+ }
+}
+
+// frameSkip searches, starting after skip frames, for the first caller frame
+// in a function not marked as a helper and returns that frame.
+// The search stops if it finds a tRunner function that
+// was the entry point into the test and the test is not a subtest.
+// This function must be called with c.mu held.
+func (c *common) frameSkip(skip int) runtime.Frame {
+ // If the search continues into the parent test, we'll have to hold
+ // its mu temporarily. If we then return, we need to unlock it.
+ shouldUnlock := false
+ defer func() {
+ if shouldUnlock {
+ c.mu.Unlock()
+ }
+ }()
+ var pc [maxStackLen]uintptr
+ // Skip two extra frames to account for this function
+ // and runtime.Callers itself.
+ n := runtime.Callers(skip+2, pc[:])
+ if n == 0 {
+ panic("testing: zero callers found")
+ }
+ frames := runtime.CallersFrames(pc[:n])
+ var firstFrame, prevFrame, frame runtime.Frame
+ for more := true; more; prevFrame = frame {
+ frame, more = frames.Next()
+ if frame.Function == "runtime.gopanic" {
+ continue
+ }
+ if frame.Function == c.cleanupName {
+ frames = runtime.CallersFrames(c.cleanupPc)
+ continue
+ }
+ if firstFrame.PC == 0 {
+ firstFrame = frame
+ }
+ if frame.Function == c.runner {
+ // We've gone up all the way to the tRunner calling
+ // the test function (so the user must have
+ // called tb.Helper from inside that test function).
+ // If this is a top-level test, only skip up to the test function itself.
+ // If we're in a subtest, continue searching in the parent test,
+ // starting from the point of the call to Run which created this subtest.
+ if c.level > 1 {
+ frames = runtime.CallersFrames(c.creator)
+ parent := c.parent
+ // We're no longer looking at the current c after this point,
+ // so we should unlock its mu, unless it's the original receiver,
+ // in which case our caller doesn't expect us to do that.
+ if shouldUnlock {
+ c.mu.Unlock()
+ }
+ c = parent
+ // Remember to unlock c.mu when we no longer need it, either
+ // because we went up another nesting level, or because we
+ // returned.
+ shouldUnlock = true
+ c.mu.Lock()
+ continue
+ }
+ return prevFrame
+ }
+ // If more helper PCs have been added since we last did the conversion
+ if c.helperNames == nil {
+ c.helperNames = make(map[string]struct{})
+ for pc := range c.helperPCs {
+ c.helperNames[pcToName(pc)] = struct{}{}
+ }
+ }
+ if _, ok := c.helperNames[frame.Function]; !ok {
+ // Found a frame that wasn't inside a helper function.
+ return frame
+ }
+ }
+ return firstFrame
+}
+
+// decorate prefixes the string with the file and line of the call site
+// and inserts the final newline if needed and indentation spaces for formatting.
+// This function must be called with c.mu held.
+func (c *common) decorate(s string, skip int) string {
+ frame := c.frameSkip(skip)
+ file := frame.File
+ line := frame.Line
+ if file != "" {
+ if *fullPath {
+ // If relative path, truncate file name at last file name separator.
+ } else if index := strings.LastIndex(file, "/"); index >= 0 {
+ file = file[index+1:]
+ } else if index = strings.LastIndex(file, "\\"); index >= 0 {
+ file = file[index+1:]
+ }
+ } else {
+ file = "???"
+ }
+ if line == 0 {
+ line = 1
+ }
+ buf := new(strings.Builder)
+ // Every line is indented at least 4 spaces.
+ buf.WriteString(" ")
+ fmt.Fprintf(buf, "%s:%d: ", file, line)
+ lines := strings.Split(s, "\n")
+ if l := len(lines); l > 1 && lines[l-1] == "" {
+ lines = lines[:l-1]
+ }
+ for i, line := range lines {
+ if i > 0 {
+ // Second and subsequent lines are indented an additional 4 spaces.
+ buf.WriteString("\n ")
+ }
+ buf.WriteString(line)
+ }
+ buf.WriteByte('\n')
+ return buf.String()
+}
+
+// flushToParent writes c.output to the parent after first writing the header
+// with the given format and arguments.
+func (c *common) flushToParent(testName, format string, args ...any) {
+ p := c.parent
+ p.mu.Lock()
+ defer p.mu.Unlock()
+
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
+ if len(c.output) > 0 {
+ // Add the current c.output to the print,
+ // and then arrange for the print to replace c.output.
+ // (This displays the logged output after the --- FAIL line.)
+ format += "%s"
+ args = append(args[:len(args):len(args)], c.output)
+ c.output = c.output[:0]
+ }
+
+ if c.chatty != nil && (p.w == c.chatty.w || c.chatty.json) {
+ // We're flushing to the actual output, so track that this output is
+ // associated with a specific test (and, specifically, that the next output
+ // is *not* associated with that test).
+ //
+ // Moreover, if c.output is non-empty it is important that this write be
+ // atomic with respect to the output of other tests, so that we don't end up
+ // with confusing '=== NAME' lines in the middle of our '--- PASS' block.
+ // Neither humans nor cmd/test2json can parse those easily.
+ // (See https://go.dev/issue/40771.)
+ //
+ // If test2json is used, we never flush to parent tests,
+ // so that the json stream shows subtests as they finish.
+ // (See https://go.dev/issue/29811.)
+ c.chatty.Updatef(testName, format, args...)
+ } else {
+ // We're flushing to the output buffer of the parent test, which will
+ // itself follow a test-name header when it is finally flushed to stdout.
+ fmt.Fprintf(p.w, c.chatty.prefix()+format, args...)
+ }
+}
+
+type indenter struct {
+ c *common
+}
+
+func (w indenter) Write(b []byte) (n int, err error) {
+ n = len(b)
+ for len(b) > 0 {
+ end := bytes.IndexByte(b, '\n')
+ if end == -1 {
+ end = len(b)
+ } else {
+ end++
+ }
+ // An indent of 4 spaces will neatly align the dashes with the status
+ // indicator of the parent.
+ line := b[:end]
+ if line[0] == marker {
+ w.c.output = append(w.c.output, marker)
+ line = line[1:]
+ }
+ const indent = " "
+ w.c.output = append(w.c.output, indent...)
+ w.c.output = append(w.c.output, line...)
+ b = b[end:]
+ }
+ return
+}
+
+// fmtDuration returns a string representing d in the form "87.00s".
+func fmtDuration(d time.Duration) string {
+ return fmt.Sprintf("%.2fs", d.Seconds())
+}
+
+// TB is the interface common to T, B, and F.
+type TB interface {
+ Cleanup(func())
+ Error(args ...any)
+ Errorf(format string, args ...any)
+ Fail()
+ FailNow()
+ Failed() bool
+ Fatal(args ...any)
+ Fatalf(format string, args ...any)
+ Helper()
+ Log(args ...any)
+ Logf(format string, args ...any)
+ Name() string
+ Setenv(key, value string)
+ Skip(args ...any)
+ SkipNow()
+ Skipf(format string, args ...any)
+ Skipped() bool
+ TempDir() string
+
+ // A private method to prevent users implementing the
+ // interface and so future additions to it will not
+ // violate Go 1 compatibility.
+ private()
+}
+
+var _ TB = (*T)(nil)
+var _ TB = (*B)(nil)
+
+// T is a type passed to Test functions to manage test state and support formatted test logs.
+//
+// A test ends when its Test function returns or calls any of the methods
+// FailNow, Fatal, Fatalf, SkipNow, Skip, or Skipf. Those methods, as well as
+// the Parallel method, must be called only from the goroutine running the
+// Test function.
+//
+// The other reporting methods, such as the variations of Log and Error,
+// may be called simultaneously from multiple goroutines.
+type T struct {
+ common
+ isEnvSet bool
+ context *testContext // For running tests and subtests.
+}
+
+func (c *common) private() {}
+
+// Name returns the name of the running (sub-) test or benchmark.
+//
+// The name will include the name of the test along with the names of
+// any nested sub-tests. If two sibling sub-tests have the same name,
+// Name will append a suffix to guarantee the returned name is unique.
+func (c *common) Name() string {
+ return c.name
+}
+
+func (c *common) setRan() {
+ if c.parent != nil {
+ c.parent.setRan()
+ }
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ c.ran = true
+}
+
+// Fail marks the function as having failed but continues execution.
+func (c *common) Fail() {
+ if c.parent != nil {
+ c.parent.Fail()
+ }
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ // c.done needs to be locked to synchronize checks to c.done in parent tests.
+ if c.done {
+ panic("Fail in goroutine after " + c.name + " has completed")
+ }
+ c.failed = true
+}
+
+// Failed reports whether the function has failed.
+func (c *common) Failed() bool {
+ c.mu.RLock()
+ failed := c.failed
+ c.mu.RUnlock()
+ return failed || c.raceErrors+race.Errors() > 0
+}
+
+// FailNow marks the function as having failed and stops its execution
+// by calling runtime.Goexit (which then runs all deferred calls in the
+// current goroutine).
+// Execution will continue at the next test or benchmark.
+// FailNow must be called from the goroutine running the
+// test or benchmark function, not from other goroutines
+// created during the test. Calling FailNow does not stop
+// those other goroutines.
+func (c *common) FailNow() {
+ c.checkFuzzFn("FailNow")
+ c.Fail()
+
+ // Calling runtime.Goexit will exit the goroutine, which
+ // will run the deferred functions in this goroutine,
+ // which will eventually run the deferred lines in tRunner,
+ // which will signal to the test loop that this test is done.
+ //
+ // A previous version of this code said:
+ //
+ // c.duration = ...
+ // c.signal <- c.self
+ // runtime.Goexit()
+ //
+ // This previous version duplicated code (those lines are in
+ // tRunner no matter what), but worse the goroutine teardown
+ // implicit in runtime.Goexit was not guaranteed to complete
+ // before the test exited. If a test deferred an important cleanup
+ // function (like removing temporary files), there was no guarantee
+ // it would run on a test failure. Because we send on c.signal during
+ // a top-of-stack deferred function now, we know that the send
+ // only happens after any other stacked defers have completed.
+ c.mu.Lock()
+ c.finished = true
+ c.mu.Unlock()
+ runtime.Goexit()
+}
+
+// log generates the output. It's always at the same stack depth.
+func (c *common) log(s string) {
+ c.logDepth(s, 3) // logDepth + log + public function
+}
+
+// logDepth generates the output at an arbitrary stack depth.
+func (c *common) logDepth(s string, depth int) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if c.done {
+ // This test has already finished. Try and log this message
+ // with our parent. If we don't have a parent, panic.
+ for parent := c.parent; parent != nil; parent = parent.parent {
+ parent.mu.Lock()
+ defer parent.mu.Unlock()
+ if !parent.done {
+ parent.output = append(parent.output, parent.decorate(s, depth+1)...)
+ return
+ }
+ }
+ panic("Log in goroutine after " + c.name + " has completed: " + s)
+ } else {
+ if c.chatty != nil {
+ if c.bench {
+ // Benchmarks don't print === CONT, so we should skip the test
+ // printer and just print straight to stdout.
+ fmt.Print(c.decorate(s, depth+1))
+ } else {
+ c.chatty.Printf(c.name, "%s", c.decorate(s, depth+1))
+ }
+
+ return
+ }
+ c.output = append(c.output, c.decorate(s, depth+1)...)
+ }
+}
+
+// Log formats its arguments using default formatting, analogous to Println,
+// and records the text in the error log. For tests, the text will be printed only if
+// the test fails or the -test.v flag is set. For benchmarks, the text is always
+// printed to avoid having performance depend on the value of the -test.v flag.
+func (c *common) Log(args ...any) {
+ c.checkFuzzFn("Log")
+ c.log(fmt.Sprintln(args...))
+}
+
+// Logf formats its arguments according to the format, analogous to Printf, and
+// records the text in the error log. A final newline is added if not provided. For
+// tests, the text will be printed only if the test fails or the -test.v flag is
+// set. For benchmarks, the text is always printed to avoid having performance
+// depend on the value of the -test.v flag.
+func (c *common) Logf(format string, args ...any) {
+ c.checkFuzzFn("Logf")
+ c.log(fmt.Sprintf(format, args...))
+}
+
+// Error is equivalent to Log followed by Fail.
+func (c *common) Error(args ...any) {
+ c.checkFuzzFn("Error")
+ c.log(fmt.Sprintln(args...))
+ c.Fail()
+}
+
+// Errorf is equivalent to Logf followed by Fail.
+func (c *common) Errorf(format string, args ...any) {
+ c.checkFuzzFn("Errorf")
+ c.log(fmt.Sprintf(format, args...))
+ c.Fail()
+}
+
+// Fatal is equivalent to Log followed by FailNow.
+func (c *common) Fatal(args ...any) {
+ c.checkFuzzFn("Fatal")
+ c.log(fmt.Sprintln(args...))
+ c.FailNow()
+}
+
+// Fatalf is equivalent to Logf followed by FailNow.
+func (c *common) Fatalf(format string, args ...any) {
+ c.checkFuzzFn("Fatalf")
+ c.log(fmt.Sprintf(format, args...))
+ c.FailNow()
+}
+
+// Skip is equivalent to Log followed by SkipNow.
+func (c *common) Skip(args ...any) {
+ c.checkFuzzFn("Skip")
+ c.log(fmt.Sprintln(args...))
+ c.SkipNow()
+}
+
+// Skipf is equivalent to Logf followed by SkipNow.
+func (c *common) Skipf(format string, args ...any) {
+ c.checkFuzzFn("Skipf")
+ c.log(fmt.Sprintf(format, args...))
+ c.SkipNow()
+}
+
+// SkipNow marks the test as having been skipped and stops its execution
+// by calling runtime.Goexit.
+// If a test fails (see Error, Errorf, Fail) and is then skipped,
+// it is still considered to have failed.
+// Execution will continue at the next test or benchmark. See also FailNow.
+// SkipNow must be called from the goroutine running the test, not from
+// other goroutines created during the test. Calling SkipNow does not stop
+// those other goroutines.
+func (c *common) SkipNow() {
+ c.checkFuzzFn("SkipNow")
+ c.mu.Lock()
+ c.skipped = true
+ c.finished = true
+ c.mu.Unlock()
+ runtime.Goexit()
+}
+
+// Skipped reports whether the test was skipped.
+func (c *common) Skipped() bool {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+ return c.skipped
+}
+
+// Helper marks the calling function as a test helper function.
+// When printing file and line information, that function will be skipped.
+// Helper may be called simultaneously from multiple goroutines.
+func (c *common) Helper() {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ if c.helperPCs == nil {
+ c.helperPCs = make(map[uintptr]struct{})
+ }
+ // repeating code from callerName here to save walking a stack frame
+ var pc [1]uintptr
+ n := runtime.Callers(2, pc[:]) // skip runtime.Callers + Helper
+ if n == 0 {
+ panic("testing: zero callers found")
+ }
+ if _, found := c.helperPCs[pc[0]]; !found {
+ c.helperPCs[pc[0]] = struct{}{}
+ c.helperNames = nil // map will be recreated next time it is needed
+ }
+}
+
+// Cleanup registers a function to be called when the test (or subtest) and all its
+// subtests complete. Cleanup functions will be called in last added,
+// first called order.
+func (c *common) Cleanup(f func()) {
+ c.checkFuzzFn("Cleanup")
+ var pc [maxStackLen]uintptr
+ // Skip two extra frames to account for this function and runtime.Callers itself.
+ n := runtime.Callers(2, pc[:])
+ cleanupPc := pc[:n]
+
+ fn := func() {
+ defer func() {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ c.cleanupName = ""
+ c.cleanupPc = nil
+ }()
+
+ name := callerName(0)
+ c.mu.Lock()
+ c.cleanupName = name
+ c.cleanupPc = cleanupPc
+ c.mu.Unlock()
+
+ f()
+ }
+
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ c.cleanups = append(c.cleanups, fn)
+}
+
+// TempDir returns a temporary directory for the test to use.
+// The directory is automatically removed by Cleanup when the test and
+// all its subtests complete.
+// Each subsequent call to t.TempDir returns a unique directory;
+// if the directory creation fails, TempDir terminates the test by calling Fatal.
+func (c *common) TempDir() string {
+ c.checkFuzzFn("TempDir")
+ // Use a single parent directory for all the temporary directories
+ // created by a test, each numbered sequentially.
+ c.tempDirMu.Lock()
+ var nonExistent bool
+ if c.tempDir == "" { // Usually the case with js/wasm
+ nonExistent = true
+ } else {
+ _, err := os.Stat(c.tempDir)
+ nonExistent = os.IsNotExist(err)
+ if err != nil && !nonExistent {
+ c.Fatalf("TempDir: %v", err)
+ }
+ }
+
+ if nonExistent {
+ c.Helper()
+
+ // Drop unusual characters (such as path separators or
+ // characters interacting with globs) from the directory name to
+ // avoid surprising os.MkdirTemp behavior.
+ mapper := func(r rune) rune {
+ if r < utf8.RuneSelf {
+ const allowed = "!#$%&()+,-.=@^_{}~ "
+ if '0' <= r && r <= '9' ||
+ 'a' <= r && r <= 'z' ||
+ 'A' <= r && r <= 'Z' {
+ return r
+ }
+ if strings.ContainsRune(allowed, r) {
+ return r
+ }
+ } else if unicode.IsLetter(r) || unicode.IsNumber(r) {
+ return r
+ }
+ return -1
+ }
+ pattern := strings.Map(mapper, c.Name())
+ c.tempDir, c.tempDirErr = os.MkdirTemp("", pattern)
+ if c.tempDirErr == nil {
+ c.Cleanup(func() {
+ if err := removeAll(c.tempDir); err != nil {
+ c.Errorf("TempDir RemoveAll cleanup: %v", err)
+ }
+ })
+ }
+ }
+
+ if c.tempDirErr == nil {
+ c.tempDirSeq++
+ }
+ seq := c.tempDirSeq
+ c.tempDirMu.Unlock()
+
+ if c.tempDirErr != nil {
+ c.Fatalf("TempDir: %v", c.tempDirErr)
+ }
+
+ dir := fmt.Sprintf("%s%c%03d", c.tempDir, os.PathSeparator, seq)
+ if err := os.Mkdir(dir, 0777); err != nil {
+ c.Fatalf("TempDir: %v", err)
+ }
+ return dir
+}
+
+// removeAll is like os.RemoveAll, but retries Windows "Access is denied."
+// errors up to an arbitrary timeout.
+//
+// Those errors have been known to occur spuriously on at least the
+// windows-amd64-2012 builder (https://go.dev/issue/50051), and can only occur
+// legitimately if the test leaves behind a temp file that either is still open
+// or the test otherwise lacks permission to delete. In the case of legitimate
+// failures, a failing test may take a bit longer to fail, but once the test is
+// fixed the extra latency will go away.
+func removeAll(path string) error {
+ const arbitraryTimeout = 2 * time.Second
+ var (
+ start time.Time
+ nextSleep = 1 * time.Millisecond
+ )
+ for {
+ err := os.RemoveAll(path)
+ if !isWindowsRetryable(err) {
+ return err
+ }
+ if start.IsZero() {
+ start = time.Now()
+ } else if d := time.Since(start) + nextSleep; d >= arbitraryTimeout {
+ return err
+ }
+ time.Sleep(nextSleep)
+ nextSleep += time.Duration(rand.Int63n(int64(nextSleep)))
+ }
+}
+
+// Setenv calls os.Setenv(key, value) and uses Cleanup to
+// restore the environment variable to its original value
+// after the test.
+//
+// Because Setenv affects the whole process, it cannot be used
+// in parallel tests or tests with parallel ancestors.
+func (c *common) Setenv(key, value string) {
+ c.checkFuzzFn("Setenv")
+ prevValue, ok := os.LookupEnv(key)
+
+ if err := os.Setenv(key, value); err != nil {
+ c.Fatalf("cannot set environment variable: %v", err)
+ }
+
+ if ok {
+ c.Cleanup(func() {
+ os.Setenv(key, prevValue)
+ })
+ } else {
+ c.Cleanup(func() {
+ os.Unsetenv(key)
+ })
+ }
+}
+
+// panicHanding is an argument to runCleanup.
+type panicHandling int
+
+const (
+ normalPanic panicHandling = iota
+ recoverAndReturnPanic
+)
+
+// runCleanup is called at the end of the test.
+// If catchPanic is true, this will catch panics, and return the recovered
+// value if any.
+func (c *common) runCleanup(ph panicHandling) (panicVal any) {
+ c.cleanupStarted.Store(true)
+ defer c.cleanupStarted.Store(false)
+
+ if ph == recoverAndReturnPanic {
+ defer func() {
+ panicVal = recover()
+ }()
+ }
+
+ // Make sure that if a cleanup function panics,
+ // we still run the remaining cleanup functions.
+ defer func() {
+ c.mu.Lock()
+ recur := len(c.cleanups) > 0
+ c.mu.Unlock()
+ if recur {
+ c.runCleanup(normalPanic)
+ }
+ }()
+
+ for {
+ var cleanup func()
+ c.mu.Lock()
+ if len(c.cleanups) > 0 {
+ last := len(c.cleanups) - 1
+ cleanup = c.cleanups[last]
+ c.cleanups = c.cleanups[:last]
+ }
+ c.mu.Unlock()
+ if cleanup == nil {
+ return nil
+ }
+ cleanup()
+ }
+}
+
+// callerName gives the function name (qualified with a package path)
+// for the caller after skip frames (where 0 means the current function).
+func callerName(skip int) string {
+ var pc [1]uintptr
+ n := runtime.Callers(skip+2, pc[:]) // skip + runtime.Callers + callerName
+ if n == 0 {
+ panic("testing: zero callers found")
+ }
+ return pcToName(pc[0])
+}
+
+func pcToName(pc uintptr) string {
+ pcs := []uintptr{pc}
+ frames := runtime.CallersFrames(pcs)
+ frame, _ := frames.Next()
+ return frame.Function
+}
+
+// Parallel signals that this test is to be run in parallel with (and only with)
+// other parallel tests. When a test is run multiple times due to use of
+// -test.count or -test.cpu, multiple instances of a single test never run in
+// parallel with each other.
+func (t *T) Parallel() {
+ if t.isParallel {
+ panic("testing: t.Parallel called multiple times")
+ }
+ if t.isEnvSet {
+ panic("testing: t.Parallel called after t.Setenv; cannot set environment variables in parallel tests")
+ }
+ t.isParallel = true
+ if t.parent.barrier == nil {
+ // T.Parallel has no effect when fuzzing.
+ // Multiple processes may run in parallel, but only one input can run at a
+ // time per process so we can attribute crashes to specific inputs.
+ return
+ }
+
+ // We don't want to include the time we spend waiting for serial tests
+ // in the test duration. Record the elapsed time thus far and reset the
+ // timer afterwards.
+ t.duration += time.Since(t.start)
+
+ // Add to the list of tests to be released by the parent.
+ t.parent.sub = append(t.parent.sub, t)
+ t.raceErrors += race.Errors()
+
+ if t.chatty != nil {
+ t.chatty.Updatef(t.name, "=== PAUSE %s\n", t.name)
+ }
+ running.Delete(t.name)
+
+ t.signal <- true // Release calling test.
+ <-t.parent.barrier // Wait for the parent test to complete.
+ t.context.waitParallel()
+
+ if t.chatty != nil {
+ t.chatty.Updatef(t.name, "=== CONT %s\n", t.name)
+ }
+ running.Store(t.name, time.Now())
+
+ t.start = time.Now()
+ t.raceErrors += -race.Errors()
+}
+
+// Setenv calls os.Setenv(key, value) and uses Cleanup to
+// restore the environment variable to its original value
+// after the test.
+//
+// Because Setenv affects the whole process, it cannot be used
+// in parallel tests or tests with parallel ancestors.
+func (t *T) Setenv(key, value string) {
+ // Non-parallel subtests that have parallel ancestors may still
+ // run in parallel with other tests: they are only non-parallel
+ // with respect to the other subtests of the same parent.
+ // Since SetEnv affects the whole process, we need to disallow it
+ // if the current test or any parent is parallel.
+ isParallel := false
+ for c := &t.common; c != nil; c = c.parent {
+ if c.isParallel {
+ isParallel = true
+ break
+ }
+ }
+ if isParallel {
+ panic("testing: t.Setenv called after t.Parallel; cannot set environment variables in parallel tests")
+ }
+
+ t.isEnvSet = true
+
+ t.common.Setenv(key, value)
+}
+
+// InternalTest is an internal type but exported because it is cross-package;
+// it is part of the implementation of the "go test" command.
+type InternalTest struct {
+ Name string
+ F func(*T)
+}
+
+var errNilPanicOrGoexit = errors.New("test executed panic(nil) or runtime.Goexit")
+
+func tRunner(t *T, fn func(t *T)) {
+ t.runner = callerName(0)
+
+ // When this goroutine is done, either because fn(t)
+ // returned normally or because a test failure triggered
+ // a call to runtime.Goexit, record the duration and send
+ // a signal saying that the test is done.
+ defer func() {
+ if t.Failed() {
+ numFailed.Add(1)
+ }
+
+ if t.raceErrors+race.Errors() > 0 {
+ t.Errorf("race detected during execution of test")
+ }
+
+ // Check if the test panicked or Goexited inappropriately.
+ //
+ // If this happens in a normal test, print output but continue panicking.
+ // tRunner is called in its own goroutine, so this terminates the process.
+ //
+ // If this happens while fuzzing, recover from the panic and treat it like a
+ // normal failure. It's important that the process keeps running in order to
+ // find short inputs that cause panics.
+ err := recover()
+ signal := true
+
+ t.mu.RLock()
+ finished := t.finished
+ t.mu.RUnlock()
+ if !finished && err == nil {
+ err = errNilPanicOrGoexit
+ for p := t.parent; p != nil; p = p.parent {
+ p.mu.RLock()
+ finished = p.finished
+ p.mu.RUnlock()
+ if finished {
+ if !t.isParallel {
+ t.Errorf("%v: subtest may have called FailNow on a parent test", err)
+ err = nil
+ }
+ signal = false
+ break
+ }
+ }
+ }
+
+ if err != nil && t.context.isFuzzing {
+ prefix := "panic: "
+ if err == errNilPanicOrGoexit {
+ prefix = ""
+ }
+ t.Errorf("%s%s\n%s\n", prefix, err, string(debug.Stack()))
+ t.mu.Lock()
+ t.finished = true
+ t.mu.Unlock()
+ err = nil
+ }
+
+ // Use a deferred call to ensure that we report that the test is
+ // complete even if a cleanup function calls t.FailNow. See issue 41355.
+ didPanic := false
+ defer func() {
+ // Only report that the test is complete if it doesn't panic,
+ // as otherwise the test binary can exit before the panic is
+ // reported to the user. See issue 41479.
+ if didPanic {
+ return
+ }
+ if err != nil {
+ panic(err)
+ }
+ running.Delete(t.name)
+ t.signal <- signal
+ }()
+
+ doPanic := func(err any) {
+ t.Fail()
+ if r := t.runCleanup(recoverAndReturnPanic); r != nil {
+ t.Logf("cleanup panicked with %v", r)
+ }
+ // Flush the output log up to the root before dying.
+ for root := &t.common; root.parent != nil; root = root.parent {
+ root.mu.Lock()
+ root.duration += time.Since(root.start)
+ d := root.duration
+ root.mu.Unlock()
+ root.flushToParent(root.name, "--- FAIL: %s (%s)\n", root.name, fmtDuration(d))
+ if r := root.parent.runCleanup(recoverAndReturnPanic); r != nil {
+ fmt.Fprintf(root.parent.w, "cleanup panicked with %v", r)
+ }
+ }
+ didPanic = true
+ panic(err)
+ }
+ if err != nil {
+ doPanic(err)
+ }
+
+ t.duration += time.Since(t.start)
+
+ if len(t.sub) > 0 {
+ // Run parallel subtests.
+ // Decrease the running count for this test.
+ t.context.release()
+ // Release the parallel subtests.
+ close(t.barrier)
+ // Wait for subtests to complete.
+ for _, sub := range t.sub {
+ <-sub.signal
+ }
+ cleanupStart := time.Now()
+ err := t.runCleanup(recoverAndReturnPanic)
+ t.duration += time.Since(cleanupStart)
+ if err != nil {
+ doPanic(err)
+ }
+ if !t.isParallel {
+ // Reacquire the count for sequential tests. See comment in Run.
+ t.context.waitParallel()
+ }
+ } else if t.isParallel {
+ // Only release the count for this test if it was run as a parallel
+ // test. See comment in Run method.
+ t.context.release()
+ }
+ t.report() // Report after all subtests have finished.
+
+ // Do not lock t.done to allow race detector to detect race in case
+ // the user does not appropriately synchronize a goroutine.
+ t.done = true
+ if t.parent != nil && !t.hasSub.Load() {
+ t.setRan()
+ }
+ }()
+ defer func() {
+ if len(t.sub) == 0 {
+ t.runCleanup(normalPanic)
+ }
+ }()
+
+ t.start = time.Now()
+ t.raceErrors = -race.Errors()
+ fn(t)
+
+ // code beyond here will not be executed when FailNow is invoked
+ t.mu.Lock()
+ t.finished = true
+ t.mu.Unlock()
+}
+
+// Run runs f as a subtest of t called name. It runs f in a separate goroutine
+// and blocks until f returns or calls t.Parallel to become a parallel test.
+// Run reports whether f succeeded (or at least did not fail before calling t.Parallel).
+//
+// Run may be called simultaneously from multiple goroutines, but all such calls
+// must return before the outer test function for t returns.
+func (t *T) Run(name string, f func(t *T)) bool {
+ if t.cleanupStarted.Load() {
+ panic("testing: t.Run called during t.Cleanup")
+ }
+
+ t.hasSub.Store(true)
+ testName, ok, _ := t.context.match.fullName(&t.common, name)
+ if !ok || shouldFailFast() {
+ return true
+ }
+ // Record the stack trace at the point of this call so that if the subtest
+ // function - which runs in a separate stack - is marked as a helper, we can
+ // continue walking the stack into the parent test.
+ var pc [maxStackLen]uintptr
+ n := runtime.Callers(2, pc[:])
+ t = &T{
+ common: common{
+ barrier: make(chan bool),
+ signal: make(chan bool, 1),
+ name: testName,
+ parent: &t.common,
+ level: t.level + 1,
+ creator: pc[:n],
+ chatty: t.chatty,
+ },
+ context: t.context,
+ }
+ t.w = indenter{&t.common}
+
+ if t.chatty != nil {
+ t.chatty.Updatef(t.name, "=== RUN %s\n", t.name)
+ }
+ running.Store(t.name, time.Now())
+
+ // Instead of reducing the running count of this test before calling the
+ // tRunner and increasing it afterwards, we rely on tRunner keeping the
+ // count correct. This ensures that a sequence of sequential tests runs
+ // without being preempted, even when their parent is a parallel test. This
+ // may especially reduce surprises if *parallel == 1.
+ go tRunner(t, f)
+ if !<-t.signal {
+ // At this point, it is likely that FailNow was called on one of the
+ // parent tests by one of the subtests. Continue aborting up the chain.
+ runtime.Goexit()
+ }
+ if t.chatty != nil && t.chatty.json {
+ t.chatty.Updatef(t.parent.name, "=== NAME %s\n", t.parent.name)
+ }
+ return !t.failed
+}
+
+// Deadline reports the time at which the test binary will have
+// exceeded the timeout specified by the -timeout flag.
+//
+// The ok result is false if the -timeout flag indicates “no timeout” (0).
+func (t *T) Deadline() (deadline time.Time, ok bool) {
+ deadline = t.context.deadline
+ return deadline, !deadline.IsZero()
+}
+
+// testContext holds all fields that are common to all tests. This includes
+// synchronization primitives to run at most *parallel tests.
+type testContext struct {
+ match *matcher
+ deadline time.Time
+
+ // isFuzzing is true in the context used when generating random inputs
+ // for fuzz targets. isFuzzing is false when running normal tests and
+ // when running fuzz tests as unit tests (without -fuzz or when -fuzz
+ // does not match).
+ isFuzzing bool
+
+ mu sync.Mutex
+
+ // Channel used to signal tests that are ready to be run in parallel.
+ startParallel chan bool
+
+ // running is the number of tests currently running in parallel.
+ // This does not include tests that are waiting for subtests to complete.
+ running int
+
+ // numWaiting is the number tests waiting to be run in parallel.
+ numWaiting int
+
+ // maxParallel is a copy of the parallel flag.
+ maxParallel int
+}
+
+func newTestContext(maxParallel int, m *matcher) *testContext {
+ return &testContext{
+ match: m,
+ startParallel: make(chan bool),
+ maxParallel: maxParallel,
+ running: 1, // Set the count to 1 for the main (sequential) test.
+ }
+}
+
+func (c *testContext) waitParallel() {
+ c.mu.Lock()
+ if c.running < c.maxParallel {
+ c.running++
+ c.mu.Unlock()
+ return
+ }
+ c.numWaiting++
+ c.mu.Unlock()
+ <-c.startParallel
+}
+
+func (c *testContext) release() {
+ c.mu.Lock()
+ if c.numWaiting == 0 {
+ c.running--
+ c.mu.Unlock()
+ return
+ }
+ c.numWaiting--
+ c.mu.Unlock()
+ c.startParallel <- true // Pick a waiting test to be run.
+}
+
+// No one should be using func Main anymore.
+// See the doc comment on func Main and use MainStart instead.
+var errMain = errors.New("testing: unexpected use of func Main")
+
+type matchStringOnly func(pat, str string) (bool, error)
+
+func (f matchStringOnly) MatchString(pat, str string) (bool, error) { return f(pat, str) }
+func (f matchStringOnly) StartCPUProfile(w io.Writer) error { return errMain }
+func (f matchStringOnly) StopCPUProfile() {}
+func (f matchStringOnly) WriteProfileTo(string, io.Writer, int) error { return errMain }
+func (f matchStringOnly) ImportPath() string { return "" }
+func (f matchStringOnly) StartTestLog(io.Writer) {}
+func (f matchStringOnly) StopTestLog() error { return errMain }
+func (f matchStringOnly) SetPanicOnExit0(bool) {}
+func (f matchStringOnly) CoordinateFuzzing(time.Duration, int64, time.Duration, int64, int, []corpusEntry, []reflect.Type, string, string) error {
+ return errMain
+}
+func (f matchStringOnly) RunFuzzWorker(func(corpusEntry) error) error { return errMain }
+func (f matchStringOnly) ReadCorpus(string, []reflect.Type) ([]corpusEntry, error) {
+ return nil, errMain
+}
+func (f matchStringOnly) CheckCorpus([]any, []reflect.Type) error { return nil }
+func (f matchStringOnly) ResetCoverage() {}
+func (f matchStringOnly) SnapshotCoverage() {}
+
+// Main is an internal function, part of the implementation of the "go test" command.
+// It was exported because it is cross-package and predates "internal" packages.
+// It is no longer used by "go test" but preserved, as much as possible, for other
+// systems that simulate "go test" using Main, but Main sometimes cannot be updated as
+// new functionality is added to the testing package.
+// Systems simulating "go test" should be updated to use MainStart.
+func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) {
+ os.Exit(MainStart(matchStringOnly(matchString), tests, benchmarks, nil, examples).Run())
+}
+
+// M is a type passed to a TestMain function to run the actual tests.
+type M struct {
+ deps testDeps
+ tests []InternalTest
+ benchmarks []InternalBenchmark
+ fuzzTargets []InternalFuzzTarget
+ examples []InternalExample
+
+ timer *time.Timer
+ afterOnce sync.Once
+
+ numRun int
+
+ // value to pass to os.Exit, the outer test func main
+ // harness calls os.Exit with this code. See #34129.
+ exitCode int
+}
+
+// testDeps is an internal interface of functionality that is
+// passed into this package by a test's generated main package.
+// The canonical implementation of this interface is
+// testing/internal/testdeps's TestDeps.
+type testDeps interface {
+ ImportPath() string
+ MatchString(pat, str string) (bool, error)
+ SetPanicOnExit0(bool)
+ StartCPUProfile(io.Writer) error
+ StopCPUProfile()
+ StartTestLog(io.Writer)
+ StopTestLog() error
+ WriteProfileTo(string, io.Writer, int) error
+ CoordinateFuzzing(time.Duration, int64, time.Duration, int64, int, []corpusEntry, []reflect.Type, string, string) error
+ RunFuzzWorker(func(corpusEntry) error) error
+ ReadCorpus(string, []reflect.Type) ([]corpusEntry, error)
+ CheckCorpus([]any, []reflect.Type) error
+ ResetCoverage()
+ SnapshotCoverage()
+}
+
+// MainStart is meant for use by tests generated by 'go test'.
+// It is not meant to be called directly and is not subject to the Go 1 compatibility document.
+// It may change signature from release to release.
+func MainStart(deps testDeps, tests []InternalTest, benchmarks []InternalBenchmark, fuzzTargets []InternalFuzzTarget, examples []InternalExample) *M {
+ Init()
+ return &M{
+ deps: deps,
+ tests: tests,
+ benchmarks: benchmarks,
+ fuzzTargets: fuzzTargets,
+ examples: examples,
+ }
+}
+
+var testingTesting bool
+var realStderr *os.File
+
+// Run runs the tests. It returns an exit code to pass to os.Exit.
+func (m *M) Run() (code int) {
+ defer func() {
+ code = m.exitCode
+ }()
+
+ // Count the number of calls to m.Run.
+ // We only ever expected 1, but we didn't enforce that,
+ // and now there are tests in the wild that call m.Run multiple times.
+ // Sigh. go.dev/issue/23129.
+ m.numRun++
+
+ // TestMain may have already called flag.Parse.
+ if !flag.Parsed() {
+ flag.Parse()
+ }
+
+ if chatty.json {
+ // With -v=json, stdout and stderr are pointing to the same pipe,
+ // which is leading into test2json. In general, operating systems
+ // do a good job of ensuring that writes to the same pipe through
+ // different file descriptors are delivered whole, so that writing
+ // AAA to stdout and BBB to stderr simultaneously produces
+ // AAABBB or BBBAAA on the pipe, not something like AABBBA.
+ // However, the exception to this is when the pipe fills: in that
+ // case, Go's use of non-blocking I/O means that writing AAA
+ // or BBB might be split across multiple system calls, making it
+ // entirely possible to get output like AABBBA. The same problem
+ // happens inside the operating system kernel if we switch to
+ // blocking I/O on the pipe. This interleaved output can do things
+ // like print unrelated messages in the middle of a TestFoo line,
+ // which confuses test2json. Setting os.Stderr = os.Stdout will make
+ // them share a single pfd, which will hold a lock for each program
+ // write, preventing any interleaving.
+ //
+ // It might be nice to set Stderr = Stdout always, or perhaps if
+ // we can tell they are the same file, but for now -v=json is
+ // a very clear signal. Making the two files the same may cause
+ // surprises if programs close os.Stdout but expect to be able
+ // to continue to write to os.Stderr, but it's hard to see why a
+ // test would think it could take over global state that way.
+ //
+ // This fix only helps programs where the output is coming directly
+ // from Go code. It does not help programs in which a subprocess is
+ // writing to stderr or stdout at the same time that a Go test is writing output.
+ // It also does not help when the output is coming from the runtime,
+ // such as when using the print/println functions, since that code writes
+ // directly to fd 2 without any locking.
+ // We keep realStderr around to prevent fd 2 from being closed.
+ //
+ // See go.dev/issue/33419.
+ realStderr = os.Stderr
+ os.Stderr = os.Stdout
+ }
+
+ if *parallel < 1 {
+ fmt.Fprintln(os.Stderr, "testing: -parallel can only be given a positive integer")
+ flag.Usage()
+ m.exitCode = 2
+ return
+ }
+ if *matchFuzz != "" && *fuzzCacheDir == "" {
+ fmt.Fprintln(os.Stderr, "testing: -test.fuzzcachedir must be set if -test.fuzz is set")
+ flag.Usage()
+ m.exitCode = 2
+ return
+ }
+
+ if *matchList != "" {
+ listTests(m.deps.MatchString, m.tests, m.benchmarks, m.fuzzTargets, m.examples)
+ m.exitCode = 0
+ return
+ }
+
+ if *shuffle != "off" {
+ var n int64
+ var err error
+ if *shuffle == "on" {
+ n = time.Now().UnixNano()
+ } else {
+ n, err = strconv.ParseInt(*shuffle, 10, 64)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, `testing: -shuffle should be "off", "on", or a valid integer:`, err)
+ m.exitCode = 2
+ return
+ }
+ }
+ fmt.Println("-test.shuffle", n)
+ rng := rand.New(rand.NewSource(n))
+ rng.Shuffle(len(m.tests), func(i, j int) { m.tests[i], m.tests[j] = m.tests[j], m.tests[i] })
+ rng.Shuffle(len(m.benchmarks), func(i, j int) { m.benchmarks[i], m.benchmarks[j] = m.benchmarks[j], m.benchmarks[i] })
+ }
+
+ parseCpuList()
+
+ m.before()
+ defer m.after()
+
+ // Run tests, examples, and benchmarks unless this is a fuzz worker process.
+ // Workers start after this is done by their parent process, and they should
+ // not repeat this work.
+ if !*isFuzzWorker {
+ deadline := m.startAlarm()
+ haveExamples = len(m.examples) > 0
+ testRan, testOk := runTests(m.deps.MatchString, m.tests, deadline)
+ fuzzTargetsRan, fuzzTargetsOk := runFuzzTests(m.deps, m.fuzzTargets, deadline)
+ exampleRan, exampleOk := runExamples(m.deps.MatchString, m.examples)
+ m.stopAlarm()
+ if !testRan && !exampleRan && !fuzzTargetsRan && *matchBenchmarks == "" && *matchFuzz == "" {
+ fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
+ if testingTesting && *match != "^$" {
+ // If this happens during testing of package testing it could be that
+ // package testing's own logic for when to run a test is broken,
+ // in which case every test will run nothing and succeed,
+ // with no obvious way to detect this problem (since no tests are running).
+ // So make 'no tests to run' a hard failure when testing package testing itself.
+ fmt.Print(chatty.prefix(), "FAIL: package testing must run tests\n")
+ testOk = false
+ }
+ }
+ if !testOk || !exampleOk || !fuzzTargetsOk || !runBenchmarks(m.deps.ImportPath(), m.deps.MatchString, m.benchmarks) || race.Errors() > 0 {
+ fmt.Print(chatty.prefix(), "FAIL\n")
+ m.exitCode = 1
+ return
+ }
+ }
+
+ fuzzingOk := runFuzzing(m.deps, m.fuzzTargets)
+ if !fuzzingOk {
+ fmt.Print(chatty.prefix(), "FAIL\n")
+ if *isFuzzWorker {
+ m.exitCode = fuzzWorkerExitCode
+ } else {
+ m.exitCode = 1
+ }
+ return
+ }
+
+ m.exitCode = 0
+ if !*isFuzzWorker {
+ fmt.Print(chatty.prefix(), "PASS\n")
+ }
+ return
+}
+
+func (t *T) report() {
+ if t.parent == nil {
+ return
+ }
+ dstr := fmtDuration(t.duration)
+ format := "--- %s: %s (%s)\n"
+ if t.Failed() {
+ t.flushToParent(t.name, format, "FAIL", t.name, dstr)
+ } else if t.chatty != nil {
+ if t.Skipped() {
+ t.flushToParent(t.name, format, "SKIP", t.name, dstr)
+ } else {
+ t.flushToParent(t.name, format, "PASS", t.name, dstr)
+ }
+ }
+}
+
+func listTests(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, fuzzTargets []InternalFuzzTarget, examples []InternalExample) {
+ if _, err := matchString(*matchList, "non-empty"); err != nil {
+ fmt.Fprintf(os.Stderr, "testing: invalid regexp in -test.list (%q): %s\n", *matchList, err)
+ os.Exit(1)
+ }
+
+ for _, test := range tests {
+ if ok, _ := matchString(*matchList, test.Name); ok {
+ fmt.Println(test.Name)
+ }
+ }
+ for _, bench := range benchmarks {
+ if ok, _ := matchString(*matchList, bench.Name); ok {
+ fmt.Println(bench.Name)
+ }
+ }
+ for _, fuzzTarget := range fuzzTargets {
+ if ok, _ := matchString(*matchList, fuzzTarget.Name); ok {
+ fmt.Println(fuzzTarget.Name)
+ }
+ }
+ for _, example := range examples {
+ if ok, _ := matchString(*matchList, example.Name); ok {
+ fmt.Println(example.Name)
+ }
+ }
+}
+
+// RunTests is an internal function but exported because it is cross-package;
+// it is part of the implementation of the "go test" command.
+func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) {
+ var deadline time.Time
+ if *timeout > 0 {
+ deadline = time.Now().Add(*timeout)
+ }
+ ran, ok := runTests(matchString, tests, deadline)
+ if !ran && !haveExamples {
+ fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
+ }
+ return ok
+}
+
+func runTests(matchString func(pat, str string) (bool, error), tests []InternalTest, deadline time.Time) (ran, ok bool) {
+ ok = true
+ for _, procs := range cpuList {
+ runtime.GOMAXPROCS(procs)
+ for i := uint(0); i < *count; i++ {
+ if shouldFailFast() {
+ break
+ }
+ if i > 0 && !ran {
+ // There were no tests to run on the first
+ // iteration. This won't change, so no reason
+ // to keep trying.
+ break
+ }
+ ctx := newTestContext(*parallel, newMatcher(matchString, *match, "-test.run", *skip))
+ ctx.deadline = deadline
+ t := &T{
+ common: common{
+ signal: make(chan bool, 1),
+ barrier: make(chan bool),
+ w: os.Stdout,
+ },
+ context: ctx,
+ }
+ if Verbose() {
+ t.chatty = newChattyPrinter(t.w)
+ }
+ tRunner(t, func(t *T) {
+ for _, test := range tests {
+ t.Run(test.Name, test.F)
+ }
+ })
+ select {
+ case <-t.signal:
+ default:
+ panic("internal error: tRunner exited without sending on t.signal")
+ }
+ ok = ok && !t.Failed()
+ ran = ran || t.ran
+ }
+ }
+ return ran, ok
+}
+
+// before runs before all testing.
+func (m *M) before() {
+ if *memProfileRate > 0 {
+ runtime.MemProfileRate = *memProfileRate
+ }
+ if *cpuProfile != "" {
+ f, err := os.Create(toOutputDir(*cpuProfile))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "testing: %s\n", err)
+ return
+ }
+ if err := m.deps.StartCPUProfile(f); err != nil {
+ fmt.Fprintf(os.Stderr, "testing: can't start cpu profile: %s\n", err)
+ f.Close()
+ return
+ }
+ // Could save f so after can call f.Close; not worth the effort.
+ }
+ if *traceFile != "" {
+ f, err := os.Create(toOutputDir(*traceFile))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "testing: %s\n", err)
+ return
+ }
+ if err := trace.Start(f); err != nil {
+ fmt.Fprintf(os.Stderr, "testing: can't start tracing: %s\n", err)
+ f.Close()
+ return
+ }
+ // Could save f so after can call f.Close; not worth the effort.
+ }
+ if *blockProfile != "" && *blockProfileRate >= 0 {
+ runtime.SetBlockProfileRate(*blockProfileRate)
+ }
+ if *mutexProfile != "" && *mutexProfileFraction >= 0 {
+ runtime.SetMutexProfileFraction(*mutexProfileFraction)
+ }
+ if *coverProfile != "" && CoverMode() == "" {
+ fmt.Fprintf(os.Stderr, "testing: cannot use -test.coverprofile because test binary was not built with coverage enabled\n")
+ os.Exit(2)
+ }
+ if *gocoverdir != "" && CoverMode() == "" {
+ fmt.Fprintf(os.Stderr, "testing: cannot use -test.gocoverdir because test binary was not built with coverage enabled\n")
+ os.Exit(2)
+ }
+ if *testlog != "" {
+ // Note: Not using toOutputDir.
+ // This file is for use by cmd/go, not users.
+ var f *os.File
+ var err error
+ if m.numRun == 1 {
+ f, err = os.Create(*testlog)
+ } else {
+ f, err = os.OpenFile(*testlog, os.O_WRONLY, 0)
+ if err == nil {
+ f.Seek(0, io.SeekEnd)
+ }
+ }
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "testing: %s\n", err)
+ os.Exit(2)
+ }
+ m.deps.StartTestLog(f)
+ testlogFile = f
+ }
+ if *panicOnExit0 {
+ m.deps.SetPanicOnExit0(true)
+ }
+}
+
+// after runs after all testing.
+func (m *M) after() {
+ m.afterOnce.Do(func() {
+ m.writeProfiles()
+ })
+
+ // Restore PanicOnExit0 after every run, because we set it to true before
+ // every run. Otherwise, if m.Run is called multiple times the behavior of
+ // os.Exit(0) will not be restored after the second run.
+ if *panicOnExit0 {
+ m.deps.SetPanicOnExit0(false)
+ }
+}
+
+func (m *M) writeProfiles() {
+ if *testlog != "" {
+ if err := m.deps.StopTestLog(); err != nil {
+ fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *testlog, err)
+ os.Exit(2)
+ }
+ if err := testlogFile.Close(); err != nil {
+ fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *testlog, err)
+ os.Exit(2)
+ }
+ }
+ if *cpuProfile != "" {
+ m.deps.StopCPUProfile() // flushes profile to disk
+ }
+ if *traceFile != "" {
+ trace.Stop() // flushes trace to disk
+ }
+ if *memProfile != "" {
+ f, err := os.Create(toOutputDir(*memProfile))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "testing: %s\n", err)
+ os.Exit(2)
+ }
+ runtime.GC() // materialize all statistics
+ if err = m.deps.WriteProfileTo("allocs", f, 0); err != nil {
+ fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *memProfile, err)
+ os.Exit(2)
+ }
+ f.Close()
+ }
+ if *blockProfile != "" && *blockProfileRate >= 0 {
+ f, err := os.Create(toOutputDir(*blockProfile))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "testing: %s\n", err)
+ os.Exit(2)
+ }
+ if err = m.deps.WriteProfileTo("block", f, 0); err != nil {
+ fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *blockProfile, err)
+ os.Exit(2)
+ }
+ f.Close()
+ }
+ if *mutexProfile != "" && *mutexProfileFraction >= 0 {
+ f, err := os.Create(toOutputDir(*mutexProfile))
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "testing: %s\n", err)
+ os.Exit(2)
+ }
+ if err = m.deps.WriteProfileTo("mutex", f, 0); err != nil {
+ fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *mutexProfile, err)
+ os.Exit(2)
+ }
+ f.Close()
+ }
+ if CoverMode() != "" {
+ coverReport()
+ }
+}
+
+// toOutputDir returns the file name relocated, if required, to outputDir.
+// Simple implementation to avoid pulling in path/filepath.
+func toOutputDir(path string) string {
+ if *outputDir == "" || path == "" {
+ return path
+ }
+ // On Windows, it's clumsy, but we can be almost always correct
+ // by just looking for a drive letter and a colon.
+ // Absolute paths always have a drive letter (ignoring UNC).
+ // Problem: if path == "C:A" and outputdir == "C:\Go" it's unclear
+ // what to do, but even then path/filepath doesn't help.
+ // TODO: Worth doing better? Probably not, because we're here only
+ // under the management of go test.
+ if runtime.GOOS == "windows" && len(path) >= 2 {
+ letter, colon := path[0], path[1]
+ if ('a' <= letter && letter <= 'z' || 'A' <= letter && letter <= 'Z') && colon == ':' {
+ // If path starts with a drive letter we're stuck with it regardless.
+ return path
+ }
+ }
+ if os.IsPathSeparator(path[0]) {
+ return path
+ }
+ return fmt.Sprintf("%s%c%s", *outputDir, os.PathSeparator, path)
+}
+
+// startAlarm starts an alarm if requested.
+func (m *M) startAlarm() time.Time {
+ if *timeout <= 0 {
+ return time.Time{}
+ }
+
+ deadline := time.Now().Add(*timeout)
+ m.timer = time.AfterFunc(*timeout, func() {
+ m.after()
+ debug.SetTraceback("all")
+ extra := ""
+
+ if list := runningList(); len(list) > 0 {
+ var b strings.Builder
+ b.WriteString("\nrunning tests:")
+ for _, name := range list {
+ b.WriteString("\n\t")
+ b.WriteString(name)
+ }
+ extra = b.String()
+ }
+ panic(fmt.Sprintf("test timed out after %v%s", *timeout, extra))
+ })
+ return deadline
+}
+
+// runningList returns the list of running tests.
+func runningList() []string {
+ var list []string
+ running.Range(func(k, v any) bool {
+ list = append(list, fmt.Sprintf("%s (%v)", k.(string), time.Since(v.(time.Time)).Round(time.Second)))
+ return true
+ })
+ sort.Strings(list)
+ return list
+}
+
+// stopAlarm turns off the alarm.
+func (m *M) stopAlarm() {
+ if *timeout > 0 {
+ m.timer.Stop()
+ }
+}
+
+func parseCpuList() {
+ for _, val := range strings.Split(*cpuListStr, ",") {
+ val = strings.TrimSpace(val)
+ if val == "" {
+ continue
+ }
+ cpu, err := strconv.Atoi(val)
+ if err != nil || cpu <= 0 {
+ fmt.Fprintf(os.Stderr, "testing: invalid value %q for -test.cpu\n", val)
+ os.Exit(1)
+ }
+ cpuList = append(cpuList, cpu)
+ }
+ if cpuList == nil {
+ cpuList = append(cpuList, runtime.GOMAXPROCS(-1))
+ }
+}
+
+func shouldFailFast() bool {
+ return *failFast && numFailed.Load() > 0
+}
diff --git a/contrib/go/_std_1.20/src/testing/testing_other.go b/contrib/go/_std_1.21/src/testing/testing_other.go
index 99a6276a4a..99a6276a4a 100644
--- a/contrib/go/_std_1.20/src/testing/testing_other.go
+++ b/contrib/go/_std_1.21/src/testing/testing_other.go
diff --git a/contrib/go/_std_1.20/src/testing/testing_windows.go b/contrib/go/_std_1.21/src/testing/testing_windows.go
index fd48ae9579..fd48ae9579 100644
--- a/contrib/go/_std_1.20/src/testing/testing_windows.go
+++ b/contrib/go/_std_1.21/src/testing/testing_windows.go
diff --git a/contrib/go/_std_1.21/src/testing/ya.make b/contrib/go/_std_1.21/src/testing/ya.make
new file mode 100644
index 0000000000..a615e82f3a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/testing/ya.make
@@ -0,0 +1,57 @@
+GO_LIBRARY()
+
+SRCS(
+ allocs.go
+ benchmark.go
+ cover.go
+ example.go
+ fuzz.go
+ match.go
+ newcover.go
+ run_example.go
+ testing.go
+)
+
+GO_TEST_SRCS(
+ export_test.go
+ helper_test.go
+ helperfuncs_test.go
+ match_test.go
+ sub_test.go
+)
+
+GO_XTEST_SRCS(
+ allocs_test.go
+ benchmark_test.go
+ flag_test.go
+ panic_test.go
+ testing_test.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ testing_other.go
+ )
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ testing_other.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ testing_windows.go
+ )
+ENDIF()
+
+END()
+
+RECURSE(
+ fstest
+ internal
+ iotest
+ quick
+ slogtest
+)
diff --git a/contrib/go/_std_1.20/src/text/scanner/scanner.go b/contrib/go/_std_1.21/src/text/scanner/scanner.go
index 44be0b6bd4..44be0b6bd4 100644
--- a/contrib/go/_std_1.20/src/text/scanner/scanner.go
+++ b/contrib/go/_std_1.21/src/text/scanner/scanner.go
diff --git a/contrib/go/_std_1.21/src/text/scanner/ya.make b/contrib/go/_std_1.21/src/text/scanner/ya.make
new file mode 100644
index 0000000000..4f016c1f32
--- /dev/null
+++ b/contrib/go/_std_1.21/src/text/scanner/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ scanner.go
+)
+
+GO_TEST_SRCS(scanner_test.go)
+
+GO_XTEST_SRCS(example_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/text/tabwriter/tabwriter.go b/contrib/go/_std_1.21/src/text/tabwriter/tabwriter.go
index d4cfcf556a..d4cfcf556a 100644
--- a/contrib/go/_std_1.20/src/text/tabwriter/tabwriter.go
+++ b/contrib/go/_std_1.21/src/text/tabwriter/tabwriter.go
diff --git a/contrib/go/_std_1.21/src/text/tabwriter/ya.make b/contrib/go/_std_1.21/src/text/tabwriter/ya.make
new file mode 100644
index 0000000000..591521852a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/text/tabwriter/ya.make
@@ -0,0 +1,15 @@
+GO_LIBRARY()
+
+SRCS(
+ tabwriter.go
+)
+
+GO_XTEST_SRCS(
+ example_test.go
+ tabwriter_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/text/template/doc.go b/contrib/go/_std_1.21/src/text/template/doc.go
new file mode 100644
index 0000000000..4c01b05ebf
--- /dev/null
+++ b/contrib/go/_std_1.21/src/text/template/doc.go
@@ -0,0 +1,464 @@
+// Copyright 2011 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 template implements data-driven templates for generating textual output.
+
+To generate HTML output, see [html/template], which has the same interface
+as this package but automatically secures HTML output against certain attacks.
+
+Templates are executed by applying them to a data structure. Annotations in the
+template refer to elements of the data structure (typically a field of a struct
+or a key in a map) to control execution and derive values to be displayed.
+Execution of the template walks the structure and sets the cursor, represented
+by a period '.' and called "dot", to the value at the current location in the
+structure as execution proceeds.
+
+The input text for a template is UTF-8-encoded text in any format.
+"Actions"--data evaluations or control structures--are delimited by
+"{{" and "}}"; all text outside actions is copied to the output unchanged.
+
+Once parsed, a template may be executed safely in parallel, although if parallel
+executions share a Writer the output may be interleaved.
+
+Here is a trivial example that prints "17 items are made of wool".
+
+ type Inventory struct {
+ Material string
+ Count uint
+ }
+ sweaters := Inventory{"wool", 17}
+ tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}")
+ if err != nil { panic(err) }
+ err = tmpl.Execute(os.Stdout, sweaters)
+ if err != nil { panic(err) }
+
+More intricate examples appear below.
+
+Text and spaces
+
+By default, all text between actions is copied verbatim when the template is
+executed. For example, the string " items are made of " in the example above
+appears on standard output when the program is run.
+
+However, to aid in formatting template source code, if an action's left
+delimiter (by default "{{") is followed immediately by a minus sign and white
+space, all trailing white space is trimmed from the immediately preceding text.
+Similarly, if the right delimiter ("}}") is preceded by white space and a minus
+sign, all leading white space is trimmed from the immediately following text.
+In these trim markers, the white space must be present:
+"{{- 3}}" is like "{{3}}" but trims the immediately preceding text, while
+"{{-3}}" parses as an action containing the number -3.
+
+For instance, when executing the template whose source is
+
+ "{{23 -}} < {{- 45}}"
+
+the generated output would be
+
+ "23<45"
+
+For this trimming, the definition of white space characters is the same as in Go:
+space, horizontal tab, carriage return, and newline.
+
+Actions
+
+Here is the list of actions. "Arguments" and "pipelines" are evaluations of
+data, defined in detail in the corresponding sections that follow.
+
+*/
+// {{/* a comment */}}
+// {{- /* a comment with white space trimmed from preceding and following text */ -}}
+// A comment; discarded. May contain newlines.
+// Comments do not nest and must start and end at the
+// delimiters, as shown here.
+/*
+
+ {{pipeline}}
+ The default textual representation (the same as would be
+ printed by fmt.Print) of the value of the pipeline is copied
+ to the output.
+
+ {{if pipeline}} T1 {{end}}
+ If the value of the pipeline is empty, no output is generated;
+ otherwise, T1 is executed. The empty values are false, 0, any
+ nil pointer or interface value, and any array, slice, map, or
+ string of length zero.
+ Dot is unaffected.
+
+ {{if pipeline}} T1 {{else}} T0 {{end}}
+ If the value of the pipeline is empty, T0 is executed;
+ otherwise, T1 is executed. Dot is unaffected.
+
+ {{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
+ To simplify the appearance of if-else chains, the else action
+ of an if may include another if directly; the effect is exactly
+ the same as writing
+ {{if pipeline}} T1 {{else}}{{if pipeline}} T0 {{end}}{{end}}
+
+ {{range pipeline}} T1 {{end}}
+ The value of the pipeline must be an array, slice, map, or channel.
+ If the value of the pipeline has length zero, nothing is output;
+ otherwise, dot is set to the successive elements of the array,
+ slice, or map and T1 is executed. If the value is a map and the
+ keys are of basic type with a defined order, the elements will be
+ visited in sorted key order.
+
+ {{range pipeline}} T1 {{else}} T0 {{end}}
+ The value of the pipeline must be an array, slice, map, or channel.
+ If the value of the pipeline has length zero, dot is unaffected and
+ T0 is executed; otherwise, dot is set to the successive elements
+ of the array, slice, or map and T1 is executed.
+
+ {{break}}
+ The innermost {{range pipeline}} loop is ended early, stopping the
+ current iteration and bypassing all remaining iterations.
+
+ {{continue}}
+ The current iteration of the innermost {{range pipeline}} loop is
+ stopped, and the loop starts the next iteration.
+
+ {{template "name"}}
+ The template with the specified name is executed with nil data.
+
+ {{template "name" pipeline}}
+ The template with the specified name is executed with dot set
+ to the value of the pipeline.
+
+ {{block "name" pipeline}} T1 {{end}}
+ A block is shorthand for defining a template
+ {{define "name"}} T1 {{end}}
+ and then executing it in place
+ {{template "name" pipeline}}
+ The typical use is to define a set of root templates that are
+ then customized by redefining the block templates within.
+
+ {{with pipeline}} T1 {{end}}
+ If the value of the pipeline is empty, no output is generated;
+ otherwise, dot is set to the value of the pipeline and T1 is
+ executed.
+
+ {{with pipeline}} T1 {{else}} T0 {{end}}
+ If the value of the pipeline is empty, dot is unaffected and T0
+ is executed; otherwise, dot is set to the value of the pipeline
+ and T1 is executed.
+
+Arguments
+
+An argument is a simple value, denoted by one of the following.
+
+ - A boolean, string, character, integer, floating-point, imaginary
+ or complex constant in Go syntax. These behave like Go's untyped
+ constants. Note that, as in Go, whether a large integer constant
+ overflows when assigned or passed to a function can depend on whether
+ the host machine's ints are 32 or 64 bits.
+ - The keyword nil, representing an untyped Go nil.
+ - The character '.' (period):
+ .
+ The result is the value of dot.
+ - A variable name, which is a (possibly empty) alphanumeric string
+ preceded by a dollar sign, such as
+ $piOver2
+ or
+ $
+ The result is the value of the variable.
+ Variables are described below.
+ - The name of a field of the data, which must be a struct, preceded
+ by a period, such as
+ .Field
+ The result is the value of the field. Field invocations may be
+ chained:
+ .Field1.Field2
+ Fields can also be evaluated on variables, including chaining:
+ $x.Field1.Field2
+ - The name of a key of the data, which must be a map, preceded
+ by a period, such as
+ .Key
+ The result is the map element value indexed by the key.
+ Key invocations may be chained and combined with fields to any
+ depth:
+ .Field1.Key1.Field2.Key2
+ Although the key must be an alphanumeric identifier, unlike with
+ field names they do not need to start with an upper case letter.
+ Keys can also be evaluated on variables, including chaining:
+ $x.key1.key2
+ - The name of a niladic method of the data, preceded by a period,
+ such as
+ .Method
+ The result is the value of invoking the method with dot as the
+ receiver, dot.Method(). Such a method must have one return value (of
+ any type) or two return values, the second of which is an error.
+ If it has two and the returned error is non-nil, execution terminates
+ and an error is returned to the caller as the value of Execute.
+ Method invocations may be chained and combined with fields and keys
+ to any depth:
+ .Field1.Key1.Method1.Field2.Key2.Method2
+ Methods can also be evaluated on variables, including chaining:
+ $x.Method1.Field
+ - The name of a niladic function, such as
+ fun
+ The result is the value of invoking the function, fun(). The return
+ types and values behave as in methods. Functions and function
+ names are described below.
+ - A parenthesized instance of one the above, for grouping. The result
+ may be accessed by a field or map key invocation.
+ print (.F1 arg1) (.F2 arg2)
+ (.StructValuedMethod "arg").Field
+
+Arguments may evaluate to any type; if they are pointers the implementation
+automatically indirects to the base type when required.
+If an evaluation yields a function value, such as a function-valued
+field of a struct, the function is not invoked automatically, but it
+can be used as a truth value for an if action and the like. To invoke
+it, use the call function, defined below.
+
+Pipelines
+
+A pipeline is a possibly chained sequence of "commands". A command is a simple
+value (argument) or a function or method call, possibly with multiple arguments:
+
+ Argument
+ The result is the value of evaluating the argument.
+ .Method [Argument...]
+ The method can be alone or the last element of a chain but,
+ unlike methods in the middle of a chain, it can take arguments.
+ The result is the value of calling the method with the
+ arguments:
+ dot.Method(Argument1, etc.)
+ functionName [Argument...]
+ The result is the value of calling the function associated
+ with the name:
+ function(Argument1, etc.)
+ Functions and function names are described below.
+
+A pipeline may be "chained" by separating a sequence of commands with pipeline
+characters '|'. In a chained pipeline, the result of each command is
+passed as the last argument of the following command. The output of the final
+command in the pipeline is the value of the pipeline.
+
+The output of a command will be either one value or two values, the second of
+which has type error. If that second value is present and evaluates to
+non-nil, execution terminates and the error is returned to the caller of
+Execute.
+
+Variables
+
+A pipeline inside an action may initialize a variable to capture the result.
+The initialization has syntax
+
+ $variable := pipeline
+
+where $variable is the name of the variable. An action that declares a
+variable produces no output.
+
+Variables previously declared can also be assigned, using the syntax
+
+ $variable = pipeline
+
+If a "range" action initializes a variable, the variable is set to the
+successive elements of the iteration. Also, a "range" may declare two
+variables, separated by a comma:
+
+ range $index, $element := pipeline
+
+in which case $index and $element are set to the successive values of the
+array/slice index or map key and element, respectively. Note that if there is
+only one variable, it is assigned the element; this is opposite to the
+convention in Go range clauses.
+
+A variable's scope extends to the "end" action of the control structure ("if",
+"with", or "range") in which it is declared, or to the end of the template if
+there is no such control structure. A template invocation does not inherit
+variables from the point of its invocation.
+
+When execution begins, $ is set to the data argument passed to Execute, that is,
+to the starting value of dot.
+
+Examples
+
+Here are some example one-line templates demonstrating pipelines and variables.
+All produce the quoted word "output":
+
+ {{"\"output\""}}
+ A string constant.
+ {{`"output"`}}
+ A raw string constant.
+ {{printf "%q" "output"}}
+ A function call.
+ {{"output" | printf "%q"}}
+ A function call whose final argument comes from the previous
+ command.
+ {{printf "%q" (print "out" "put")}}
+ A parenthesized argument.
+ {{"put" | printf "%s%s" "out" | printf "%q"}}
+ A more elaborate call.
+ {{"output" | printf "%s" | printf "%q"}}
+ A longer chain.
+ {{with "output"}}{{printf "%q" .}}{{end}}
+ A with action using dot.
+ {{with $x := "output" | printf "%q"}}{{$x}}{{end}}
+ A with action that creates and uses a variable.
+ {{with $x := "output"}}{{printf "%q" $x}}{{end}}
+ A with action that uses the variable in another action.
+ {{with $x := "output"}}{{$x | printf "%q"}}{{end}}
+ The same, but pipelined.
+
+Functions
+
+During execution functions are found in two function maps: first in the
+template, then in the global function map. By default, no functions are defined
+in the template but the Funcs method can be used to add them.
+
+Predefined global functions are named as follows.
+
+ and
+ Returns the boolean AND of its arguments by returning the
+ first empty argument or the last argument. That is,
+ "and x y" behaves as "if x then y else x."
+ Evaluation proceeds through the arguments left to right
+ and returns when the result is determined.
+ call
+ Returns the result of calling the first argument, which
+ must be a function, with the remaining arguments as parameters.
+ Thus "call .X.Y 1 2" is, in Go notation, dot.X.Y(1, 2) where
+ Y is a func-valued field, map entry, or the like.
+ The first argument must be the result of an evaluation
+ that yields a value of function type (as distinct from
+ a predefined function such as print). The function must
+ return either one or two result values, the second of which
+ is of type error. If the arguments don't match the function
+ or the returned error value is non-nil, execution stops.
+ html
+ Returns the escaped HTML equivalent of the textual
+ representation of its arguments. This function is unavailable
+ in html/template, with a few exceptions.
+ index
+ Returns the result of indexing its first argument by the
+ following arguments. Thus "index x 1 2 3" is, in Go syntax,
+ x[1][2][3]. Each indexed item must be a map, slice, or array.
+ slice
+ slice returns the result of slicing its first argument by the
+ remaining arguments. Thus "slice x 1 2" is, in Go syntax, x[1:2],
+ while "slice x" is x[:], "slice x 1" is x[1:], and "slice x 1 2 3"
+ is x[1:2:3]. The first argument must be a string, slice, or array.
+ js
+ Returns the escaped JavaScript equivalent of the textual
+ representation of its arguments.
+ len
+ Returns the integer length of its argument.
+ not
+ Returns the boolean negation of its single argument.
+ or
+ Returns the boolean OR of its arguments by returning the
+ first non-empty argument or the last argument, that is,
+ "or x y" behaves as "if x then x else y".
+ Evaluation proceeds through the arguments left to right
+ and returns when the result is determined.
+ print
+ An alias for fmt.Sprint
+ printf
+ An alias for fmt.Sprintf
+ println
+ An alias for fmt.Sprintln
+ urlquery
+ Returns the escaped value of the textual representation of
+ its arguments in a form suitable for embedding in a URL query.
+ This function is unavailable in html/template, with a few
+ exceptions.
+
+The boolean functions take any zero value to be false and a non-zero
+value to be true.
+
+There is also a set of binary comparison operators defined as
+functions:
+
+ eq
+ Returns the boolean truth of arg1 == arg2
+ ne
+ Returns the boolean truth of arg1 != arg2
+ lt
+ Returns the boolean truth of arg1 < arg2
+ le
+ Returns the boolean truth of arg1 <= arg2
+ gt
+ Returns the boolean truth of arg1 > arg2
+ ge
+ Returns the boolean truth of arg1 >= arg2
+
+For simpler multi-way equality tests, eq (only) accepts two or more
+arguments and compares the second and subsequent to the first,
+returning in effect
+
+ arg1==arg2 || arg1==arg3 || arg1==arg4 ...
+
+(Unlike with || in Go, however, eq is a function call and all the
+arguments will be evaluated.)
+
+The comparison functions work on any values whose type Go defines as
+comparable. For basic types such as integers, the rules are relaxed:
+size and exact type are ignored, so any integer value, signed or unsigned,
+may be compared with any other integer value. (The arithmetic value is compared,
+not the bit pattern, so all negative integers are less than all unsigned integers.)
+However, as usual, one may not compare an int with a float32 and so on.
+
+Associated templates
+
+Each template is named by a string specified when it is created. Also, each
+template is associated with zero or more other templates that it may invoke by
+name; such associations are transitive and form a name space of templates.
+
+A template may use a template invocation to instantiate another associated
+template; see the explanation of the "template" action above. The name must be
+that of a template associated with the template that contains the invocation.
+
+Nested template definitions
+
+When parsing a template, another template may be defined and associated with the
+template being parsed. Template definitions must appear at the top level of the
+template, much like global variables in a Go program.
+
+The syntax of such definitions is to surround each template declaration with a
+"define" and "end" action.
+
+The define action names the template being created by providing a string
+constant. Here is a simple example:
+
+ {{define "T1"}}ONE{{end}}
+ {{define "T2"}}TWO{{end}}
+ {{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}}
+ {{template "T3"}}
+
+This defines two templates, T1 and T2, and a third T3 that invokes the other two
+when it is executed. Finally it invokes T3. If executed this template will
+produce the text
+
+ ONE TWO
+
+By construction, a template may reside in only one association. If it's
+necessary to have a template addressable from multiple associations, the
+template definition must be parsed multiple times to create distinct *Template
+values, or must be copied with the Clone or AddParseTree method.
+
+Parse may be called multiple times to assemble the various associated templates;
+see the ParseFiles and ParseGlob functions and methods for simple ways to parse
+related templates stored in files.
+
+A template may be executed directly or through ExecuteTemplate, which executes
+an associated template identified by name. To invoke our example above, we
+might write,
+
+ err := tmpl.Execute(os.Stdout, "no data needed")
+ if err != nil {
+ log.Fatalf("execution failed: %s", err)
+ }
+
+or to invoke a particular template explicitly by name,
+
+ err := tmpl.ExecuteTemplate(os.Stdout, "T2", "no data needed")
+ if err != nil {
+ log.Fatalf("execution failed: %s", err)
+ }
+
+*/
+package template
diff --git a/contrib/go/_std_1.20/src/text/template/exec.go b/contrib/go/_std_1.21/src/text/template/exec.go
index fd7db657d3..fd7db657d3 100644
--- a/contrib/go/_std_1.20/src/text/template/exec.go
+++ b/contrib/go/_std_1.21/src/text/template/exec.go
diff --git a/contrib/go/_std_1.21/src/text/template/funcs.go b/contrib/go/_std_1.21/src/text/template/funcs.go
new file mode 100644
index 0000000000..b5a8c9ec50
--- /dev/null
+++ b/contrib/go/_std_1.21/src/text/template/funcs.go
@@ -0,0 +1,776 @@
+// Copyright 2011 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 template
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "net/url"
+ "reflect"
+ "strings"
+ "sync"
+ "unicode"
+ "unicode/utf8"
+)
+
+// FuncMap is the type of the map defining the mapping from names to functions.
+// Each function must have either a single return value, or two return values of
+// which the second has type error. In that case, if the second (error)
+// return value evaluates to non-nil during execution, execution terminates and
+// Execute returns that error.
+//
+// Errors returned by Execute wrap the underlying error; call errors.As to
+// unwrap them.
+//
+// When template execution invokes a function with an argument list, that list
+// must be assignable to the function's parameter types. Functions meant to
+// apply to arguments of arbitrary type can use parameters of type interface{} or
+// of type reflect.Value. Similarly, functions meant to return a result of arbitrary
+// type can return interface{} or reflect.Value.
+type FuncMap map[string]any
+
+// builtins returns the FuncMap.
+// It is not a global variable so the linker can dead code eliminate
+// more when this isn't called. See golang.org/issue/36021.
+// TODO: revert this back to a global map once golang.org/issue/2559 is fixed.
+func builtins() FuncMap {
+ return FuncMap{
+ "and": and,
+ "call": call,
+ "html": HTMLEscaper,
+ "index": index,
+ "slice": slice,
+ "js": JSEscaper,
+ "len": length,
+ "not": not,
+ "or": or,
+ "print": fmt.Sprint,
+ "printf": fmt.Sprintf,
+ "println": fmt.Sprintln,
+ "urlquery": URLQueryEscaper,
+
+ // Comparisons
+ "eq": eq, // ==
+ "ge": ge, // >=
+ "gt": gt, // >
+ "le": le, // <=
+ "lt": lt, // <
+ "ne": ne, // !=
+ }
+}
+
+var builtinFuncsOnce struct {
+ sync.Once
+ v map[string]reflect.Value
+}
+
+// builtinFuncsOnce lazily computes & caches the builtinFuncs map.
+// TODO: revert this back to a global map once golang.org/issue/2559 is fixed.
+func builtinFuncs() map[string]reflect.Value {
+ builtinFuncsOnce.Do(func() {
+ builtinFuncsOnce.v = createValueFuncs(builtins())
+ })
+ return builtinFuncsOnce.v
+}
+
+// createValueFuncs turns a FuncMap into a map[string]reflect.Value
+func createValueFuncs(funcMap FuncMap) map[string]reflect.Value {
+ m := make(map[string]reflect.Value)
+ addValueFuncs(m, funcMap)
+ return m
+}
+
+// addValueFuncs adds to values the functions in funcs, converting them to reflect.Values.
+func addValueFuncs(out map[string]reflect.Value, in FuncMap) {
+ for name, fn := range in {
+ if !goodName(name) {
+ panic(fmt.Errorf("function name %q is not a valid identifier", name))
+ }
+ v := reflect.ValueOf(fn)
+ if v.Kind() != reflect.Func {
+ panic("value for " + name + " not a function")
+ }
+ if !goodFunc(v.Type()) {
+ panic(fmt.Errorf("can't install method/function %q with %d results", name, v.Type().NumOut()))
+ }
+ out[name] = v
+ }
+}
+
+// addFuncs adds to values the functions in funcs. It does no checking of the input -
+// call addValueFuncs first.
+func addFuncs(out, in FuncMap) {
+ for name, fn := range in {
+ out[name] = fn
+ }
+}
+
+// goodFunc reports whether the function or method has the right result signature.
+func goodFunc(typ reflect.Type) bool {
+ // We allow functions with 1 result or 2 results where the second is an error.
+ switch {
+ case typ.NumOut() == 1:
+ return true
+ case typ.NumOut() == 2 && typ.Out(1) == errorType:
+ return true
+ }
+ return false
+}
+
+// goodName reports whether the function name is a valid identifier.
+func goodName(name string) bool {
+ if name == "" {
+ return false
+ }
+ for i, r := range name {
+ switch {
+ case r == '_':
+ case i == 0 && !unicode.IsLetter(r):
+ return false
+ case !unicode.IsLetter(r) && !unicode.IsDigit(r):
+ return false
+ }
+ }
+ return true
+}
+
+// findFunction looks for a function in the template, and global map.
+func findFunction(name string, tmpl *Template) (v reflect.Value, isBuiltin, ok bool) {
+ if tmpl != nil && tmpl.common != nil {
+ tmpl.muFuncs.RLock()
+ defer tmpl.muFuncs.RUnlock()
+ if fn := tmpl.execFuncs[name]; fn.IsValid() {
+ return fn, false, true
+ }
+ }
+ if fn := builtinFuncs()[name]; fn.IsValid() {
+ return fn, true, true
+ }
+ return reflect.Value{}, false, false
+}
+
+// prepareArg checks if value can be used as an argument of type argType, and
+// converts an invalid value to appropriate zero if possible.
+func prepareArg(value reflect.Value, argType reflect.Type) (reflect.Value, error) {
+ if !value.IsValid() {
+ if !canBeNil(argType) {
+ return reflect.Value{}, fmt.Errorf("value is nil; should be of type %s", argType)
+ }
+ value = reflect.Zero(argType)
+ }
+ if value.Type().AssignableTo(argType) {
+ return value, nil
+ }
+ if intLike(value.Kind()) && intLike(argType.Kind()) && value.Type().ConvertibleTo(argType) {
+ value = value.Convert(argType)
+ return value, nil
+ }
+ return reflect.Value{}, fmt.Errorf("value has type %s; should be %s", value.Type(), argType)
+}
+
+func intLike(typ reflect.Kind) bool {
+ switch typ {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return true
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return true
+ }
+ return false
+}
+
+// indexArg checks if a reflect.Value can be used as an index, and converts it to int if possible.
+func indexArg(index reflect.Value, cap int) (int, error) {
+ var x int64
+ switch index.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ x = index.Int()
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ x = int64(index.Uint())
+ case reflect.Invalid:
+ return 0, fmt.Errorf("cannot index slice/array with nil")
+ default:
+ return 0, fmt.Errorf("cannot index slice/array with type %s", index.Type())
+ }
+ if x < 0 || int(x) < 0 || int(x) > cap {
+ return 0, fmt.Errorf("index out of range: %d", x)
+ }
+ return int(x), nil
+}
+
+// Indexing.
+
+// index returns the result of indexing its first argument by the following
+// arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each
+// indexed item must be a map, slice, or array.
+func index(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) {
+ item = indirectInterface(item)
+ if !item.IsValid() {
+ return reflect.Value{}, fmt.Errorf("index of untyped nil")
+ }
+ for _, index := range indexes {
+ index = indirectInterface(index)
+ var isNil bool
+ if item, isNil = indirect(item); isNil {
+ return reflect.Value{}, fmt.Errorf("index of nil pointer")
+ }
+ switch item.Kind() {
+ case reflect.Array, reflect.Slice, reflect.String:
+ x, err := indexArg(index, item.Len())
+ if err != nil {
+ return reflect.Value{}, err
+ }
+ item = item.Index(x)
+ case reflect.Map:
+ index, err := prepareArg(index, item.Type().Key())
+ if err != nil {
+ return reflect.Value{}, err
+ }
+ if x := item.MapIndex(index); x.IsValid() {
+ item = x
+ } else {
+ item = reflect.Zero(item.Type().Elem())
+ }
+ case reflect.Invalid:
+ // the loop holds invariant: item.IsValid()
+ panic("unreachable")
+ default:
+ return reflect.Value{}, fmt.Errorf("can't index item of type %s", item.Type())
+ }
+ }
+ return item, nil
+}
+
+// Slicing.
+
+// slice returns the result of slicing its first argument by the remaining
+// arguments. Thus "slice x 1 2" is, in Go syntax, x[1:2], while "slice x"
+// is x[:], "slice x 1" is x[1:], and "slice x 1 2 3" is x[1:2:3]. The first
+// argument must be a string, slice, or array.
+func slice(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) {
+ item = indirectInterface(item)
+ if !item.IsValid() {
+ return reflect.Value{}, fmt.Errorf("slice of untyped nil")
+ }
+ if len(indexes) > 3 {
+ return reflect.Value{}, fmt.Errorf("too many slice indexes: %d", len(indexes))
+ }
+ var cap int
+ switch item.Kind() {
+ case reflect.String:
+ if len(indexes) == 3 {
+ return reflect.Value{}, fmt.Errorf("cannot 3-index slice a string")
+ }
+ cap = item.Len()
+ case reflect.Array, reflect.Slice:
+ cap = item.Cap()
+ default:
+ return reflect.Value{}, fmt.Errorf("can't slice item of type %s", item.Type())
+ }
+ // set default values for cases item[:], item[i:].
+ idx := [3]int{0, item.Len()}
+ for i, index := range indexes {
+ x, err := indexArg(index, cap)
+ if err != nil {
+ return reflect.Value{}, err
+ }
+ idx[i] = x
+ }
+ // given item[i:j], make sure i <= j.
+ if idx[0] > idx[1] {
+ return reflect.Value{}, fmt.Errorf("invalid slice index: %d > %d", idx[0], idx[1])
+ }
+ if len(indexes) < 3 {
+ return item.Slice(idx[0], idx[1]), nil
+ }
+ // given item[i:j:k], make sure i <= j <= k.
+ if idx[1] > idx[2] {
+ return reflect.Value{}, fmt.Errorf("invalid slice index: %d > %d", idx[1], idx[2])
+ }
+ return item.Slice3(idx[0], idx[1], idx[2]), nil
+}
+
+// Length
+
+// length returns the length of the item, with an error if it has no defined length.
+func length(item reflect.Value) (int, error) {
+ item, isNil := indirect(item)
+ if isNil {
+ return 0, fmt.Errorf("len of nil pointer")
+ }
+ switch item.Kind() {
+ case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
+ return item.Len(), nil
+ }
+ return 0, fmt.Errorf("len of type %s", item.Type())
+}
+
+// Function invocation
+
+// call returns the result of evaluating the first argument as a function.
+// The function must return 1 result, or 2 results, the second of which is an error.
+func call(fn reflect.Value, args ...reflect.Value) (reflect.Value, error) {
+ fn = indirectInterface(fn)
+ if !fn.IsValid() {
+ return reflect.Value{}, fmt.Errorf("call of nil")
+ }
+ typ := fn.Type()
+ if typ.Kind() != reflect.Func {
+ return reflect.Value{}, fmt.Errorf("non-function of type %s", typ)
+ }
+ if !goodFunc(typ) {
+ return reflect.Value{}, fmt.Errorf("function called with %d args; should be 1 or 2", typ.NumOut())
+ }
+ numIn := typ.NumIn()
+ var dddType reflect.Type
+ if typ.IsVariadic() {
+ if len(args) < numIn-1 {
+ return reflect.Value{}, fmt.Errorf("wrong number of args: got %d want at least %d", len(args), numIn-1)
+ }
+ dddType = typ.In(numIn - 1).Elem()
+ } else {
+ if len(args) != numIn {
+ return reflect.Value{}, fmt.Errorf("wrong number of args: got %d want %d", len(args), numIn)
+ }
+ }
+ argv := make([]reflect.Value, len(args))
+ for i, arg := range args {
+ arg = indirectInterface(arg)
+ // Compute the expected type. Clumsy because of variadics.
+ argType := dddType
+ if !typ.IsVariadic() || i < numIn-1 {
+ argType = typ.In(i)
+ }
+
+ var err error
+ if argv[i], err = prepareArg(arg, argType); err != nil {
+ return reflect.Value{}, fmt.Errorf("arg %d: %w", i, err)
+ }
+ }
+ return safeCall(fn, argv)
+}
+
+// safeCall runs fun.Call(args), and returns the resulting value and error, if
+// any. If the call panics, the panic value is returned as an error.
+func safeCall(fun reflect.Value, args []reflect.Value) (val reflect.Value, err error) {
+ defer func() {
+ if r := recover(); r != nil {
+ if e, ok := r.(error); ok {
+ err = e
+ } else {
+ err = fmt.Errorf("%v", r)
+ }
+ }
+ }()
+ ret := fun.Call(args)
+ if len(ret) == 2 && !ret[1].IsNil() {
+ return ret[0], ret[1].Interface().(error)
+ }
+ return ret[0], nil
+}
+
+// Boolean logic.
+
+func truth(arg reflect.Value) bool {
+ t, _ := isTrue(indirectInterface(arg))
+ return t
+}
+
+// and computes the Boolean AND of its arguments, returning
+// the first false argument it encounters, or the last argument.
+func and(arg0 reflect.Value, args ...reflect.Value) reflect.Value {
+ panic("unreachable") // implemented as a special case in evalCall
+}
+
+// or computes the Boolean OR of its arguments, returning
+// the first true argument it encounters, or the last argument.
+func or(arg0 reflect.Value, args ...reflect.Value) reflect.Value {
+ panic("unreachable") // implemented as a special case in evalCall
+}
+
+// not returns the Boolean negation of its argument.
+func not(arg reflect.Value) bool {
+ return !truth(arg)
+}
+
+// Comparison.
+
+// TODO: Perhaps allow comparison between signed and unsigned integers.
+
+var (
+ errBadComparisonType = errors.New("invalid type for comparison")
+ errBadComparison = errors.New("incompatible types for comparison")
+ errNoComparison = errors.New("missing argument for comparison")
+)
+
+type kind int
+
+const (
+ invalidKind kind = iota
+ boolKind
+ complexKind
+ intKind
+ floatKind
+ stringKind
+ uintKind
+)
+
+func basicKind(v reflect.Value) (kind, error) {
+ switch v.Kind() {
+ case reflect.Bool:
+ return boolKind, nil
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return intKind, nil
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return uintKind, nil
+ case reflect.Float32, reflect.Float64:
+ return floatKind, nil
+ case reflect.Complex64, reflect.Complex128:
+ return complexKind, nil
+ case reflect.String:
+ return stringKind, nil
+ }
+ return invalidKind, errBadComparisonType
+}
+
+// isNil returns true if v is the zero reflect.Value, or nil of its type.
+func isNil(v reflect.Value) bool {
+ if !v.IsValid() {
+ return true
+ }
+ switch v.Kind() {
+ case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Pointer, reflect.Slice:
+ return v.IsNil()
+ }
+ return false
+}
+
+// canCompare reports whether v1 and v2 are both the same kind, or one is nil.
+// Called only when dealing with nillable types, or there's about to be an error.
+func canCompare(v1, v2 reflect.Value) bool {
+ k1 := v1.Kind()
+ k2 := v2.Kind()
+ if k1 == k2 {
+ return true
+ }
+ // We know the type can be compared to nil.
+ return k1 == reflect.Invalid || k2 == reflect.Invalid
+}
+
+// eq evaluates the comparison a == b || a == c || ...
+func eq(arg1 reflect.Value, arg2 ...reflect.Value) (bool, error) {
+ arg1 = indirectInterface(arg1)
+ if len(arg2) == 0 {
+ return false, errNoComparison
+ }
+ k1, _ := basicKind(arg1)
+ for _, arg := range arg2 {
+ arg = indirectInterface(arg)
+ k2, _ := basicKind(arg)
+ truth := false
+ if k1 != k2 {
+ // Special case: Can compare integer values regardless of type's sign.
+ switch {
+ case k1 == intKind && k2 == uintKind:
+ truth = arg1.Int() >= 0 && uint64(arg1.Int()) == arg.Uint()
+ case k1 == uintKind && k2 == intKind:
+ truth = arg.Int() >= 0 && arg1.Uint() == uint64(arg.Int())
+ default:
+ if arg1 != zero && arg != zero {
+ return false, errBadComparison
+ }
+ }
+ } else {
+ switch k1 {
+ case boolKind:
+ truth = arg1.Bool() == arg.Bool()
+ case complexKind:
+ truth = arg1.Complex() == arg.Complex()
+ case floatKind:
+ truth = arg1.Float() == arg.Float()
+ case intKind:
+ truth = arg1.Int() == arg.Int()
+ case stringKind:
+ truth = arg1.String() == arg.String()
+ case uintKind:
+ truth = arg1.Uint() == arg.Uint()
+ default:
+ if !canCompare(arg1, arg) {
+ return false, fmt.Errorf("non-comparable types %s: %v, %s: %v", arg1, arg1.Type(), arg.Type(), arg)
+ }
+ if isNil(arg1) || isNil(arg) {
+ truth = isNil(arg) == isNil(arg1)
+ } else {
+ if !arg.Type().Comparable() {
+ return false, fmt.Errorf("non-comparable type %s: %v", arg, arg.Type())
+ }
+ truth = arg1.Interface() == arg.Interface()
+ }
+ }
+ }
+ if truth {
+ return true, nil
+ }
+ }
+ return false, nil
+}
+
+// ne evaluates the comparison a != b.
+func ne(arg1, arg2 reflect.Value) (bool, error) {
+ // != is the inverse of ==.
+ equal, err := eq(arg1, arg2)
+ return !equal, err
+}
+
+// lt evaluates the comparison a < b.
+func lt(arg1, arg2 reflect.Value) (bool, error) {
+ arg1 = indirectInterface(arg1)
+ k1, err := basicKind(arg1)
+ if err != nil {
+ return false, err
+ }
+ arg2 = indirectInterface(arg2)
+ k2, err := basicKind(arg2)
+ if err != nil {
+ return false, err
+ }
+ truth := false
+ if k1 != k2 {
+ // Special case: Can compare integer values regardless of type's sign.
+ switch {
+ case k1 == intKind && k2 == uintKind:
+ truth = arg1.Int() < 0 || uint64(arg1.Int()) < arg2.Uint()
+ case k1 == uintKind && k2 == intKind:
+ truth = arg2.Int() >= 0 && arg1.Uint() < uint64(arg2.Int())
+ default:
+ return false, errBadComparison
+ }
+ } else {
+ switch k1 {
+ case boolKind, complexKind:
+ return false, errBadComparisonType
+ case floatKind:
+ truth = arg1.Float() < arg2.Float()
+ case intKind:
+ truth = arg1.Int() < arg2.Int()
+ case stringKind:
+ truth = arg1.String() < arg2.String()
+ case uintKind:
+ truth = arg1.Uint() < arg2.Uint()
+ default:
+ panic("invalid kind")
+ }
+ }
+ return truth, nil
+}
+
+// le evaluates the comparison <= b.
+func le(arg1, arg2 reflect.Value) (bool, error) {
+ // <= is < or ==.
+ lessThan, err := lt(arg1, arg2)
+ if lessThan || err != nil {
+ return lessThan, err
+ }
+ return eq(arg1, arg2)
+}
+
+// gt evaluates the comparison a > b.
+func gt(arg1, arg2 reflect.Value) (bool, error) {
+ // > is the inverse of <=.
+ lessOrEqual, err := le(arg1, arg2)
+ if err != nil {
+ return false, err
+ }
+ return !lessOrEqual, nil
+}
+
+// ge evaluates the comparison a >= b.
+func ge(arg1, arg2 reflect.Value) (bool, error) {
+ // >= is the inverse of <.
+ lessThan, err := lt(arg1, arg2)
+ if err != nil {
+ return false, err
+ }
+ return !lessThan, nil
+}
+
+// HTML escaping.
+
+var (
+ htmlQuot = []byte("&#34;") // shorter than "&quot;"
+ htmlApos = []byte("&#39;") // shorter than "&apos;" and apos was not in HTML until HTML5
+ htmlAmp = []byte("&amp;")
+ htmlLt = []byte("&lt;")
+ htmlGt = []byte("&gt;")
+ htmlNull = []byte("\uFFFD")
+)
+
+// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
+func HTMLEscape(w io.Writer, b []byte) {
+ last := 0
+ for i, c := range b {
+ var html []byte
+ switch c {
+ case '\000':
+ html = htmlNull
+ case '"':
+ html = htmlQuot
+ case '\'':
+ html = htmlApos
+ case '&':
+ html = htmlAmp
+ case '<':
+ html = htmlLt
+ case '>':
+ html = htmlGt
+ default:
+ continue
+ }
+ w.Write(b[last:i])
+ w.Write(html)
+ last = i + 1
+ }
+ w.Write(b[last:])
+}
+
+// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
+func HTMLEscapeString(s string) string {
+ // Avoid allocation if we can.
+ if !strings.ContainsAny(s, "'\"&<>\000") {
+ return s
+ }
+ var b strings.Builder
+ HTMLEscape(&b, []byte(s))
+ return b.String()
+}
+
+// HTMLEscaper returns the escaped HTML equivalent of the textual
+// representation of its arguments.
+func HTMLEscaper(args ...any) string {
+ return HTMLEscapeString(evalArgs(args))
+}
+
+// JavaScript escaping.
+
+var (
+ jsLowUni = []byte(`\u00`)
+ hex = []byte("0123456789ABCDEF")
+
+ jsBackslash = []byte(`\\`)
+ jsApos = []byte(`\'`)
+ jsQuot = []byte(`\"`)
+ jsLt = []byte(`\u003C`)
+ jsGt = []byte(`\u003E`)
+ jsAmp = []byte(`\u0026`)
+ jsEq = []byte(`\u003D`)
+)
+
+// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
+func JSEscape(w io.Writer, b []byte) {
+ last := 0
+ for i := 0; i < len(b); i++ {
+ c := b[i]
+
+ if !jsIsSpecial(rune(c)) {
+ // fast path: nothing to do
+ continue
+ }
+ w.Write(b[last:i])
+
+ if c < utf8.RuneSelf {
+ // Quotes, slashes and angle brackets get quoted.
+ // Control characters get written as \u00XX.
+ switch c {
+ case '\\':
+ w.Write(jsBackslash)
+ case '\'':
+ w.Write(jsApos)
+ case '"':
+ w.Write(jsQuot)
+ case '<':
+ w.Write(jsLt)
+ case '>':
+ w.Write(jsGt)
+ case '&':
+ w.Write(jsAmp)
+ case '=':
+ w.Write(jsEq)
+ default:
+ w.Write(jsLowUni)
+ t, b := c>>4, c&0x0f
+ w.Write(hex[t : t+1])
+ w.Write(hex[b : b+1])
+ }
+ } else {
+ // Unicode rune.
+ r, size := utf8.DecodeRune(b[i:])
+ if unicode.IsPrint(r) {
+ w.Write(b[i : i+size])
+ } else {
+ fmt.Fprintf(w, "\\u%04X", r)
+ }
+ i += size - 1
+ }
+ last = i + 1
+ }
+ w.Write(b[last:])
+}
+
+// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
+func JSEscapeString(s string) string {
+ // Avoid allocation if we can.
+ if strings.IndexFunc(s, jsIsSpecial) < 0 {
+ return s
+ }
+ var b strings.Builder
+ JSEscape(&b, []byte(s))
+ return b.String()
+}
+
+func jsIsSpecial(r rune) bool {
+ switch r {
+ case '\\', '\'', '"', '<', '>', '&', '=':
+ return true
+ }
+ return r < ' ' || utf8.RuneSelf <= r
+}
+
+// JSEscaper returns the escaped JavaScript equivalent of the textual
+// representation of its arguments.
+func JSEscaper(args ...any) string {
+ return JSEscapeString(evalArgs(args))
+}
+
+// URLQueryEscaper returns the escaped value of the textual representation of
+// its arguments in a form suitable for embedding in a URL query.
+func URLQueryEscaper(args ...any) string {
+ return url.QueryEscape(evalArgs(args))
+}
+
+// evalArgs formats the list of arguments into a string. It is therefore equivalent to
+//
+// fmt.Sprint(args...)
+//
+// except that each argument is indirected (if a pointer), as required,
+// using the same rules as the default string evaluation during template
+// execution.
+func evalArgs(args []any) string {
+ ok := false
+ var s string
+ // Fast path for simple common case.
+ if len(args) == 1 {
+ s, ok = args[0].(string)
+ }
+ if !ok {
+ for i, arg := range args {
+ a, ok := printableValue(reflect.ValueOf(arg))
+ if ok {
+ args[i] = a
+ } // else let fmt do its thing
+ }
+ s = fmt.Sprint(args...)
+ }
+ return s
+}
diff --git a/contrib/go/_std_1.20/src/text/template/helper.go b/contrib/go/_std_1.21/src/text/template/helper.go
index 48af3928b3..48af3928b3 100644
--- a/contrib/go/_std_1.20/src/text/template/helper.go
+++ b/contrib/go/_std_1.21/src/text/template/helper.go
diff --git a/contrib/go/_std_1.20/src/text/template/option.go b/contrib/go/_std_1.21/src/text/template/option.go
index ea2fd80c06..ea2fd80c06 100644
--- a/contrib/go/_std_1.20/src/text/template/option.go
+++ b/contrib/go/_std_1.21/src/text/template/option.go
diff --git a/contrib/go/_std_1.20/src/text/template/parse/lex.go b/contrib/go/_std_1.21/src/text/template/parse/lex.go
index 70fc86b63c..70fc86b63c 100644
--- a/contrib/go/_std_1.20/src/text/template/parse/lex.go
+++ b/contrib/go/_std_1.21/src/text/template/parse/lex.go
diff --git a/contrib/go/_std_1.20/src/text/template/parse/node.go b/contrib/go/_std_1.21/src/text/template/parse/node.go
index 47268225c8..47268225c8 100644
--- a/contrib/go/_std_1.20/src/text/template/parse/node.go
+++ b/contrib/go/_std_1.21/src/text/template/parse/node.go
diff --git a/contrib/go/_std_1.20/src/text/template/parse/parse.go b/contrib/go/_std_1.21/src/text/template/parse/parse.go
index d43d5334ba..d43d5334ba 100644
--- a/contrib/go/_std_1.20/src/text/template/parse/parse.go
+++ b/contrib/go/_std_1.21/src/text/template/parse/parse.go
diff --git a/contrib/go/_std_1.21/src/text/template/parse/ya.make b/contrib/go/_std_1.21/src/text/template/parse/ya.make
new file mode 100644
index 0000000000..a2e30aafbb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/text/template/parse/ya.make
@@ -0,0 +1,17 @@
+GO_LIBRARY()
+
+SRCS(
+ lex.go
+ node.go
+ parse.go
+)
+
+GO_TEST_SRCS(
+ lex_test.go
+ parse_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/text/template/template.go b/contrib/go/_std_1.21/src/text/template/template.go
index 776be9cd07..776be9cd07 100644
--- a/contrib/go/_std_1.20/src/text/template/template.go
+++ b/contrib/go/_std_1.21/src/text/template/template.go
diff --git a/contrib/go/_std_1.21/src/text/template/ya.make b/contrib/go/_std_1.21/src/text/template/ya.make
new file mode 100644
index 0000000000..3b553baf0a
--- /dev/null
+++ b/contrib/go/_std_1.21/src/text/template/ya.make
@@ -0,0 +1,28 @@
+GO_LIBRARY()
+
+SRCS(
+ doc.go
+ exec.go
+ funcs.go
+ helper.go
+ option.go
+ template.go
+)
+
+GO_TEST_SRCS(
+ exec_test.go
+ multi_test.go
+)
+
+GO_XTEST_SRCS(
+ example_test.go
+ examplefiles_test.go
+ examplefunc_test.go
+ link_test.go
+)
+
+END()
+
+RECURSE(
+ parse
+)
diff --git a/contrib/go/_std_1.21/src/time/format.go b/contrib/go/_std_1.21/src/time/format.go
new file mode 100644
index 0000000000..7fbeddb540
--- /dev/null
+++ b/contrib/go/_std_1.21/src/time/format.go
@@ -0,0 +1,1686 @@
+// Copyright 2010 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 time
+
+import "errors"
+
+// These are predefined layouts for use in Time.Format and time.Parse.
+// The reference time used in these layouts is the specific time stamp:
+//
+// 01/02 03:04:05PM '06 -0700
+//
+// (January 2, 15:04:05, 2006, in time zone seven hours west of GMT).
+// That value is recorded as the constant named Layout, listed below. As a Unix
+// time, this is 1136239445. Since MST is GMT-0700, the reference would be
+// printed by the Unix date command as:
+//
+// Mon Jan 2 15:04:05 MST 2006
+//
+// It is a regrettable historic error that the date uses the American convention
+// of putting the numerical month before the day.
+//
+// The example for Time.Format demonstrates the working of the layout string
+// in detail and is a good reference.
+//
+// Note that the RFC822, RFC850, and RFC1123 formats should be applied
+// only to local times. Applying them to UTC times will use "UTC" as the
+// time zone abbreviation, while strictly speaking those RFCs require the
+// use of "GMT" in that case.
+// In general RFC1123Z should be used instead of RFC1123 for servers
+// that insist on that format, and RFC3339 should be preferred for new protocols.
+// RFC3339, RFC822, RFC822Z, RFC1123, and RFC1123Z are useful for formatting;
+// when used with time.Parse they do not accept all the time formats
+// permitted by the RFCs and they do accept time formats not formally defined.
+// The RFC3339Nano format removes trailing zeros from the seconds field
+// and thus may not sort correctly once formatted.
+//
+// Most programs can use one of the defined constants as the layout passed to
+// Format or Parse. The rest of this comment can be ignored unless you are
+// creating a custom layout string.
+//
+// To define your own format, write down what the reference time would look like
+// formatted your way; see the values of constants like ANSIC, StampMicro or
+// Kitchen for examples. The model is to demonstrate what the reference time
+// looks like so that the Format and Parse methods can apply the same
+// transformation to a general time value.
+//
+// Here is a summary of the components of a layout string. Each element shows by
+// example the formatting of an element of the reference time. Only these values
+// are recognized. Text in the layout string that is not recognized as part of
+// the reference time is echoed verbatim during Format and expected to appear
+// verbatim in the input to Parse.
+//
+// Year: "2006" "06"
+// Month: "Jan" "January" "01" "1"
+// Day of the week: "Mon" "Monday"
+// Day of the month: "2" "_2" "02"
+// Day of the year: "__2" "002"
+// Hour: "15" "3" "03" (PM or AM)
+// Minute: "4" "04"
+// Second: "5" "05"
+// AM/PM mark: "PM"
+//
+// Numeric time zone offsets format as follows:
+//
+// "-0700" ±hhmm
+// "-07:00" ±hh:mm
+// "-07" ±hh
+// "-070000" ±hhmmss
+// "-07:00:00" ±hh:mm:ss
+//
+// Replacing the sign in the format with a Z triggers
+// the ISO 8601 behavior of printing Z instead of an
+// offset for the UTC zone. Thus:
+//
+// "Z0700" Z or ±hhmm
+// "Z07:00" Z or ±hh:mm
+// "Z07" Z or ±hh
+// "Z070000" Z or ±hhmmss
+// "Z07:00:00" Z or ±hh:mm:ss
+//
+// Within the format string, the underscores in "_2" and "__2" represent spaces
+// that may be replaced by digits if the following number has multiple digits,
+// for compatibility with fixed-width Unix time formats. A leading zero represents
+// a zero-padded value.
+//
+// The formats __2 and 002 are space-padded and zero-padded
+// three-character day of year; there is no unpadded day of year format.
+//
+// A comma or decimal point followed by one or more zeros represents
+// a fractional second, printed to the given number of decimal places.
+// A comma or decimal point followed by one or more nines represents
+// a fractional second, printed to the given number of decimal places, with
+// trailing zeros removed.
+// For example "15:04:05,000" or "15:04:05.000" formats or parses with
+// millisecond precision.
+//
+// Some valid layouts are invalid time values for time.Parse, due to formats
+// such as _ for space padding and Z for zone information.
+const (
+ Layout = "01/02 03:04:05PM '06 -0700" // The reference time, in numerical order.
+ ANSIC = "Mon Jan _2 15:04:05 2006"
+ UnixDate = "Mon Jan _2 15:04:05 MST 2006"
+ RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
+ RFC822 = "02 Jan 06 15:04 MST"
+ RFC822Z = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
+ RFC850 = "Monday, 02-Jan-06 15:04:05 MST"
+ RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
+ RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
+ RFC3339 = "2006-01-02T15:04:05Z07:00"
+ RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
+ Kitchen = "3:04PM"
+ // Handy time stamps.
+ Stamp = "Jan _2 15:04:05"
+ StampMilli = "Jan _2 15:04:05.000"
+ StampMicro = "Jan _2 15:04:05.000000"
+ StampNano = "Jan _2 15:04:05.000000000"
+ DateTime = "2006-01-02 15:04:05"
+ DateOnly = "2006-01-02"
+ TimeOnly = "15:04:05"
+)
+
+const (
+ _ = iota
+ stdLongMonth = iota + stdNeedDate // "January"
+ stdMonth // "Jan"
+ stdNumMonth // "1"
+ stdZeroMonth // "01"
+ stdLongWeekDay // "Monday"
+ stdWeekDay // "Mon"
+ stdDay // "2"
+ stdUnderDay // "_2"
+ stdZeroDay // "02"
+ stdUnderYearDay // "__2"
+ stdZeroYearDay // "002"
+ stdHour = iota + stdNeedClock // "15"
+ stdHour12 // "3"
+ stdZeroHour12 // "03"
+ stdMinute // "4"
+ stdZeroMinute // "04"
+ stdSecond // "5"
+ stdZeroSecond // "05"
+ stdLongYear = iota + stdNeedDate // "2006"
+ stdYear // "06"
+ stdPM = iota + stdNeedClock // "PM"
+ stdpm // "pm"
+ stdTZ = iota // "MST"
+ stdISO8601TZ // "Z0700" // prints Z for UTC
+ stdISO8601SecondsTZ // "Z070000"
+ stdISO8601ShortTZ // "Z07"
+ stdISO8601ColonTZ // "Z07:00" // prints Z for UTC
+ stdISO8601ColonSecondsTZ // "Z07:00:00"
+ stdNumTZ // "-0700" // always numeric
+ stdNumSecondsTz // "-070000"
+ stdNumShortTZ // "-07" // always numeric
+ stdNumColonTZ // "-07:00" // always numeric
+ stdNumColonSecondsTZ // "-07:00:00"
+ stdFracSecond0 // ".0", ".00", ... , trailing zeros included
+ stdFracSecond9 // ".9", ".99", ..., trailing zeros omitted
+
+ stdNeedDate = 1 << 8 // need month, day, year
+ stdNeedClock = 2 << 8 // need hour, minute, second
+ stdArgShift = 16 // extra argument in high bits, above low stdArgShift
+ stdSeparatorShift = 28 // extra argument in high 4 bits for fractional second separators
+ stdMask = 1<<stdArgShift - 1 // mask out argument
+)
+
+// std0x records the std values for "01", "02", ..., "06".
+var std0x = [...]int{stdZeroMonth, stdZeroDay, stdZeroHour12, stdZeroMinute, stdZeroSecond, stdYear}
+
+// startsWithLowerCase reports whether the string has a lower-case letter at the beginning.
+// Its purpose is to prevent matching strings like "Month" when looking for "Mon".
+func startsWithLowerCase(str string) bool {
+ if len(str) == 0 {
+ return false
+ }
+ c := str[0]
+ return 'a' <= c && c <= 'z'
+}
+
+// nextStdChunk finds the first occurrence of a std string in
+// layout and returns the text before, the std string, and the text after.
+func nextStdChunk(layout string) (prefix string, std int, suffix string) {
+ for i := 0; i < len(layout); i++ {
+ switch c := int(layout[i]); c {
+ case 'J': // January, Jan
+ if len(layout) >= i+3 && layout[i:i+3] == "Jan" {
+ if len(layout) >= i+7 && layout[i:i+7] == "January" {
+ return layout[0:i], stdLongMonth, layout[i+7:]
+ }
+ if !startsWithLowerCase(layout[i+3:]) {
+ return layout[0:i], stdMonth, layout[i+3:]
+ }
+ }
+
+ case 'M': // Monday, Mon, MST
+ if len(layout) >= i+3 {
+ if layout[i:i+3] == "Mon" {
+ if len(layout) >= i+6 && layout[i:i+6] == "Monday" {
+ return layout[0:i], stdLongWeekDay, layout[i+6:]
+ }
+ if !startsWithLowerCase(layout[i+3:]) {
+ return layout[0:i], stdWeekDay, layout[i+3:]
+ }
+ }
+ if layout[i:i+3] == "MST" {
+ return layout[0:i], stdTZ, layout[i+3:]
+ }
+ }
+
+ case '0': // 01, 02, 03, 04, 05, 06, 002
+ if len(layout) >= i+2 && '1' <= layout[i+1] && layout[i+1] <= '6' {
+ return layout[0:i], std0x[layout[i+1]-'1'], layout[i+2:]
+ }
+ if len(layout) >= i+3 && layout[i+1] == '0' && layout[i+2] == '2' {
+ return layout[0:i], stdZeroYearDay, layout[i+3:]
+ }
+
+ case '1': // 15, 1
+ if len(layout) >= i+2 && layout[i+1] == '5' {
+ return layout[0:i], stdHour, layout[i+2:]
+ }
+ return layout[0:i], stdNumMonth, layout[i+1:]
+
+ case '2': // 2006, 2
+ if len(layout) >= i+4 && layout[i:i+4] == "2006" {
+ return layout[0:i], stdLongYear, layout[i+4:]
+ }
+ return layout[0:i], stdDay, layout[i+1:]
+
+ case '_': // _2, _2006, __2
+ if len(layout) >= i+2 && layout[i+1] == '2' {
+ //_2006 is really a literal _, followed by stdLongYear
+ if len(layout) >= i+5 && layout[i+1:i+5] == "2006" {
+ return layout[0 : i+1], stdLongYear, layout[i+5:]
+ }
+ return layout[0:i], stdUnderDay, layout[i+2:]
+ }
+ if len(layout) >= i+3 && layout[i+1] == '_' && layout[i+2] == '2' {
+ return layout[0:i], stdUnderYearDay, layout[i+3:]
+ }
+
+ case '3':
+ return layout[0:i], stdHour12, layout[i+1:]
+
+ case '4':
+ return layout[0:i], stdMinute, layout[i+1:]
+
+ case '5':
+ return layout[0:i], stdSecond, layout[i+1:]
+
+ case 'P': // PM
+ if len(layout) >= i+2 && layout[i+1] == 'M' {
+ return layout[0:i], stdPM, layout[i+2:]
+ }
+
+ case 'p': // pm
+ if len(layout) >= i+2 && layout[i+1] == 'm' {
+ return layout[0:i], stdpm, layout[i+2:]
+ }
+
+ case '-': // -070000, -07:00:00, -0700, -07:00, -07
+ if len(layout) >= i+7 && layout[i:i+7] == "-070000" {
+ return layout[0:i], stdNumSecondsTz, layout[i+7:]
+ }
+ if len(layout) >= i+9 && layout[i:i+9] == "-07:00:00" {
+ return layout[0:i], stdNumColonSecondsTZ, layout[i+9:]
+ }
+ if len(layout) >= i+5 && layout[i:i+5] == "-0700" {
+ return layout[0:i], stdNumTZ, layout[i+5:]
+ }
+ if len(layout) >= i+6 && layout[i:i+6] == "-07:00" {
+ return layout[0:i], stdNumColonTZ, layout[i+6:]
+ }
+ if len(layout) >= i+3 && layout[i:i+3] == "-07" {
+ return layout[0:i], stdNumShortTZ, layout[i+3:]
+ }
+
+ case 'Z': // Z070000, Z07:00:00, Z0700, Z07:00,
+ if len(layout) >= i+7 && layout[i:i+7] == "Z070000" {
+ return layout[0:i], stdISO8601SecondsTZ, layout[i+7:]
+ }
+ if len(layout) >= i+9 && layout[i:i+9] == "Z07:00:00" {
+ return layout[0:i], stdISO8601ColonSecondsTZ, layout[i+9:]
+ }
+ if len(layout) >= i+5 && layout[i:i+5] == "Z0700" {
+ return layout[0:i], stdISO8601TZ, layout[i+5:]
+ }
+ if len(layout) >= i+6 && layout[i:i+6] == "Z07:00" {
+ return layout[0:i], stdISO8601ColonTZ, layout[i+6:]
+ }
+ if len(layout) >= i+3 && layout[i:i+3] == "Z07" {
+ return layout[0:i], stdISO8601ShortTZ, layout[i+3:]
+ }
+
+ case '.', ',': // ,000, or .000, or ,999, or .999 - repeated digits for fractional seconds.
+ if i+1 < len(layout) && (layout[i+1] == '0' || layout[i+1] == '9') {
+ ch := layout[i+1]
+ j := i + 1
+ for j < len(layout) && layout[j] == ch {
+ j++
+ }
+ // String of digits must end here - only fractional second is all digits.
+ if !isDigit(layout, j) {
+ code := stdFracSecond0
+ if layout[i+1] == '9' {
+ code = stdFracSecond9
+ }
+ std := stdFracSecond(code, j-(i+1), c)
+ return layout[0:i], std, layout[j:]
+ }
+ }
+ }
+ }
+ return layout, 0, ""
+}
+
+var longDayNames = []string{
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+}
+
+var shortDayNames = []string{
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat",
+}
+
+var shortMonthNames = []string{
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec",
+}
+
+var longMonthNames = []string{
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December",
+}
+
+// match reports whether s1 and s2 match ignoring case.
+// It is assumed s1 and s2 are the same length.
+func match(s1, s2 string) bool {
+ for i := 0; i < len(s1); i++ {
+ c1 := s1[i]
+ c2 := s2[i]
+ if c1 != c2 {
+ // Switch to lower-case; 'a'-'A' is known to be a single bit.
+ c1 |= 'a' - 'A'
+ c2 |= 'a' - 'A'
+ if c1 != c2 || c1 < 'a' || c1 > 'z' {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+func lookup(tab []string, val string) (int, string, error) {
+ for i, v := range tab {
+ if len(val) >= len(v) && match(val[0:len(v)], v) {
+ return i, val[len(v):], nil
+ }
+ }
+ return -1, val, errBad
+}
+
+// appendInt appends the decimal form of x to b and returns the result.
+// If the decimal form (excluding sign) is shorter than width, the result is padded with leading 0's.
+// Duplicates functionality in strconv, but avoids dependency.
+func appendInt(b []byte, x int, width int) []byte {
+ u := uint(x)
+ if x < 0 {
+ b = append(b, '-')
+ u = uint(-x)
+ }
+
+ // 2-digit and 4-digit fields are the most common in time formats.
+ utod := func(u uint) byte { return '0' + byte(u) }
+ switch {
+ case width == 2 && u < 1e2:
+ return append(b, utod(u/1e1), utod(u%1e1))
+ case width == 4 && u < 1e4:
+ return append(b, utod(u/1e3), utod(u/1e2%1e1), utod(u/1e1%1e1), utod(u%1e1))
+ }
+
+ // Compute the number of decimal digits.
+ var n int
+ if u == 0 {
+ n = 1
+ }
+ for u2 := u; u2 > 0; u2 /= 10 {
+ n++
+ }
+
+ // Add 0-padding.
+ for pad := width - n; pad > 0; pad-- {
+ b = append(b, '0')
+ }
+
+ // Ensure capacity.
+ if len(b)+n <= cap(b) {
+ b = b[:len(b)+n]
+ } else {
+ b = append(b, make([]byte, n)...)
+ }
+
+ // Assemble decimal in reverse order.
+ i := len(b) - 1
+ for u >= 10 && i > 0 {
+ q := u / 10
+ b[i] = utod(u - q*10)
+ u = q
+ i--
+ }
+ b[i] = utod(u)
+ return b
+}
+
+// Never printed, just needs to be non-nil for return by atoi.
+var errAtoi = errors.New("time: invalid number")
+
+// Duplicates functionality in strconv, but avoids dependency.
+func atoi[bytes []byte | string](s bytes) (x int, err error) {
+ neg := false
+ if len(s) > 0 && (s[0] == '-' || s[0] == '+') {
+ neg = s[0] == '-'
+ s = s[1:]
+ }
+ q, rem, err := leadingInt(s)
+ x = int(q)
+ if err != nil || len(rem) > 0 {
+ return 0, errAtoi
+ }
+ if neg {
+ x = -x
+ }
+ return x, nil
+}
+
+// The "std" value passed to appendNano contains two packed fields: the number of
+// digits after the decimal and the separator character (period or comma).
+// These functions pack and unpack that variable.
+func stdFracSecond(code, n, c int) int {
+ // Use 0xfff to make the failure case even more absurd.
+ if c == '.' {
+ return code | ((n & 0xfff) << stdArgShift)
+ }
+ return code | ((n & 0xfff) << stdArgShift) | 1<<stdSeparatorShift
+}
+
+func digitsLen(std int) int {
+ return (std >> stdArgShift) & 0xfff
+}
+
+func separator(std int) byte {
+ if (std >> stdSeparatorShift) == 0 {
+ return '.'
+ }
+ return ','
+}
+
+// appendNano appends a fractional second, as nanoseconds, to b
+// and returns the result. The nanosec must be within [0, 999999999].
+func appendNano(b []byte, nanosec int, std int) []byte {
+ trim := std&stdMask == stdFracSecond9
+ n := digitsLen(std)
+ if trim && (n == 0 || nanosec == 0) {
+ return b
+ }
+ dot := separator(std)
+ b = append(b, dot)
+ b = appendInt(b, nanosec, 9)
+ if n < 9 {
+ b = b[:len(b)-9+n]
+ }
+ if trim {
+ for len(b) > 0 && b[len(b)-1] == '0' {
+ b = b[:len(b)-1]
+ }
+ if len(b) > 0 && b[len(b)-1] == dot {
+ b = b[:len(b)-1]
+ }
+ }
+ return b
+}
+
+// String returns the time formatted using the format string
+//
+// "2006-01-02 15:04:05.999999999 -0700 MST"
+//
+// If the time has a monotonic clock reading, the returned string
+// includes a final field "m=±<value>", where value is the monotonic
+// clock reading formatted as a decimal number of seconds.
+//
+// The returned string is meant for debugging; for a stable serialized
+// representation, use t.MarshalText, t.MarshalBinary, or t.Format
+// with an explicit format string.
+func (t Time) String() string {
+ s := t.Format("2006-01-02 15:04:05.999999999 -0700 MST")
+
+ // Format monotonic clock reading as m=±ddd.nnnnnnnnn.
+ if t.wall&hasMonotonic != 0 {
+ m2 := uint64(t.ext)
+ sign := byte('+')
+ if t.ext < 0 {
+ sign = '-'
+ m2 = -m2
+ }
+ m1, m2 := m2/1e9, m2%1e9
+ m0, m1 := m1/1e9, m1%1e9
+ buf := make([]byte, 0, 24)
+ buf = append(buf, " m="...)
+ buf = append(buf, sign)
+ wid := 0
+ if m0 != 0 {
+ buf = appendInt(buf, int(m0), 0)
+ wid = 9
+ }
+ buf = appendInt(buf, int(m1), wid)
+ buf = append(buf, '.')
+ buf = appendInt(buf, int(m2), 9)
+ s += string(buf)
+ }
+ return s
+}
+
+// GoString implements fmt.GoStringer and formats t to be printed in Go source
+// code.
+func (t Time) GoString() string {
+ abs := t.abs()
+ year, month, day, _ := absDate(abs, true)
+ hour, minute, second := absClock(abs)
+
+ buf := make([]byte, 0, len("time.Date(9999, time.September, 31, 23, 59, 59, 999999999, time.Local)"))
+ buf = append(buf, "time.Date("...)
+ buf = appendInt(buf, year, 0)
+ if January <= month && month <= December {
+ buf = append(buf, ", time."...)
+ buf = append(buf, longMonthNames[month-1]...)
+ } else {
+ // It's difficult to construct a time.Time with a date outside the
+ // standard range but we might as well try to handle the case.
+ buf = appendInt(buf, int(month), 0)
+ }
+ buf = append(buf, ", "...)
+ buf = appendInt(buf, day, 0)
+ buf = append(buf, ", "...)
+ buf = appendInt(buf, hour, 0)
+ buf = append(buf, ", "...)
+ buf = appendInt(buf, minute, 0)
+ buf = append(buf, ", "...)
+ buf = appendInt(buf, second, 0)
+ buf = append(buf, ", "...)
+ buf = appendInt(buf, t.Nanosecond(), 0)
+ buf = append(buf, ", "...)
+ switch loc := t.Location(); loc {
+ case UTC, nil:
+ buf = append(buf, "time.UTC"...)
+ case Local:
+ buf = append(buf, "time.Local"...)
+ default:
+ // there are several options for how we could display this, none of
+ // which are great:
+ //
+ // - use Location(loc.name), which is not technically valid syntax
+ // - use LoadLocation(loc.name), which will cause a syntax error when
+ // embedded and also would require us to escape the string without
+ // importing fmt or strconv
+ // - try to use FixedZone, which would also require escaping the name
+ // and would represent e.g. "America/Los_Angeles" daylight saving time
+ // shifts inaccurately
+ // - use the pointer format, which is no worse than you'd get with the
+ // old fmt.Sprintf("%#v", t) format.
+ //
+ // Of these, Location(loc.name) is the least disruptive. This is an edge
+ // case we hope not to hit too often.
+ buf = append(buf, `time.Location(`...)
+ buf = append(buf, quote(loc.name)...)
+ buf = append(buf, ')')
+ }
+ buf = append(buf, ')')
+ return string(buf)
+}
+
+// Format returns a textual representation of the time value formatted according
+// to the layout defined by the argument. See the documentation for the
+// constant called Layout to see how to represent the layout format.
+//
+// The executable example for Time.Format demonstrates the working
+// of the layout string in detail and is a good reference.
+func (t Time) Format(layout string) string {
+ const bufSize = 64
+ var b []byte
+ max := len(layout) + 10
+ if max < bufSize {
+ var buf [bufSize]byte
+ b = buf[:0]
+ } else {
+ b = make([]byte, 0, max)
+ }
+ b = t.AppendFormat(b, layout)
+ return string(b)
+}
+
+// AppendFormat is like Format but appends the textual
+// representation to b and returns the extended buffer.
+func (t Time) AppendFormat(b []byte, layout string) []byte {
+ // Optimize for RFC3339 as it accounts for over half of all representations.
+ switch layout {
+ case RFC3339:
+ return t.appendFormatRFC3339(b, false)
+ case RFC3339Nano:
+ return t.appendFormatRFC3339(b, true)
+ default:
+ return t.appendFormat(b, layout)
+ }
+}
+
+func (t Time) appendFormat(b []byte, layout string) []byte {
+ var (
+ name, offset, abs = t.locabs()
+
+ year int = -1
+ month Month
+ day int
+ yday int
+ hour int = -1
+ min int
+ sec int
+ )
+
+ // Each iteration generates one std value.
+ for layout != "" {
+ prefix, std, suffix := nextStdChunk(layout)
+ if prefix != "" {
+ b = append(b, prefix...)
+ }
+ if std == 0 {
+ break
+ }
+ layout = suffix
+
+ // Compute year, month, day if needed.
+ if year < 0 && std&stdNeedDate != 0 {
+ year, month, day, yday = absDate(abs, true)
+ yday++
+ }
+
+ // Compute hour, minute, second if needed.
+ if hour < 0 && std&stdNeedClock != 0 {
+ hour, min, sec = absClock(abs)
+ }
+
+ switch std & stdMask {
+ case stdYear:
+ y := year
+ if y < 0 {
+ y = -y
+ }
+ b = appendInt(b, y%100, 2)
+ case stdLongYear:
+ b = appendInt(b, year, 4)
+ case stdMonth:
+ b = append(b, month.String()[:3]...)
+ case stdLongMonth:
+ m := month.String()
+ b = append(b, m...)
+ case stdNumMonth:
+ b = appendInt(b, int(month), 0)
+ case stdZeroMonth:
+ b = appendInt(b, int(month), 2)
+ case stdWeekDay:
+ b = append(b, absWeekday(abs).String()[:3]...)
+ case stdLongWeekDay:
+ s := absWeekday(abs).String()
+ b = append(b, s...)
+ case stdDay:
+ b = appendInt(b, day, 0)
+ case stdUnderDay:
+ if day < 10 {
+ b = append(b, ' ')
+ }
+ b = appendInt(b, day, 0)
+ case stdZeroDay:
+ b = appendInt(b, day, 2)
+ case stdUnderYearDay:
+ if yday < 100 {
+ b = append(b, ' ')
+ if yday < 10 {
+ b = append(b, ' ')
+ }
+ }
+ b = appendInt(b, yday, 0)
+ case stdZeroYearDay:
+ b = appendInt(b, yday, 3)
+ case stdHour:
+ b = appendInt(b, hour, 2)
+ case stdHour12:
+ // Noon is 12PM, midnight is 12AM.
+ hr := hour % 12
+ if hr == 0 {
+ hr = 12
+ }
+ b = appendInt(b, hr, 0)
+ case stdZeroHour12:
+ // Noon is 12PM, midnight is 12AM.
+ hr := hour % 12
+ if hr == 0 {
+ hr = 12
+ }
+ b = appendInt(b, hr, 2)
+ case stdMinute:
+ b = appendInt(b, min, 0)
+ case stdZeroMinute:
+ b = appendInt(b, min, 2)
+ case stdSecond:
+ b = appendInt(b, sec, 0)
+ case stdZeroSecond:
+ b = appendInt(b, sec, 2)
+ case stdPM:
+ if hour >= 12 {
+ b = append(b, "PM"...)
+ } else {
+ b = append(b, "AM"...)
+ }
+ case stdpm:
+ if hour >= 12 {
+ b = append(b, "pm"...)
+ } else {
+ b = append(b, "am"...)
+ }
+ case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ShortTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumColonTZ, stdNumSecondsTz, stdNumShortTZ, stdNumColonSecondsTZ:
+ // Ugly special case. We cheat and take the "Z" variants
+ // to mean "the time zone as formatted for ISO 8601".
+ if offset == 0 && (std == stdISO8601TZ || std == stdISO8601ColonTZ || std == stdISO8601SecondsTZ || std == stdISO8601ShortTZ || std == stdISO8601ColonSecondsTZ) {
+ b = append(b, 'Z')
+ break
+ }
+ zone := offset / 60 // convert to minutes
+ absoffset := offset
+ if zone < 0 {
+ b = append(b, '-')
+ zone = -zone
+ absoffset = -absoffset
+ } else {
+ b = append(b, '+')
+ }
+ b = appendInt(b, zone/60, 2)
+ if std == stdISO8601ColonTZ || std == stdNumColonTZ || std == stdISO8601ColonSecondsTZ || std == stdNumColonSecondsTZ {
+ b = append(b, ':')
+ }
+ if std != stdNumShortTZ && std != stdISO8601ShortTZ {
+ b = appendInt(b, zone%60, 2)
+ }
+
+ // append seconds if appropriate
+ if std == stdISO8601SecondsTZ || std == stdNumSecondsTz || std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
+ if std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
+ b = append(b, ':')
+ }
+ b = appendInt(b, absoffset%60, 2)
+ }
+
+ case stdTZ:
+ if name != "" {
+ b = append(b, name...)
+ break
+ }
+ // No time zone known for this time, but we must print one.
+ // Use the -0700 format.
+ zone := offset / 60 // convert to minutes
+ if zone < 0 {
+ b = append(b, '-')
+ zone = -zone
+ } else {
+ b = append(b, '+')
+ }
+ b = appendInt(b, zone/60, 2)
+ b = appendInt(b, zone%60, 2)
+ case stdFracSecond0, stdFracSecond9:
+ b = appendNano(b, t.Nanosecond(), std)
+ }
+ }
+ return b
+}
+
+var errBad = errors.New("bad value for field") // placeholder not passed to user
+
+// ParseError describes a problem parsing a time string.
+type ParseError struct {
+ Layout string
+ Value string
+ LayoutElem string
+ ValueElem string
+ Message string
+}
+
+// newParseError creates a new ParseError.
+// The provided value and valueElem are cloned to avoid escaping their values.
+func newParseError(layout, value, layoutElem, valueElem, message string) *ParseError {
+ valueCopy := cloneString(value)
+ valueElemCopy := cloneString(valueElem)
+ return &ParseError{layout, valueCopy, layoutElem, valueElemCopy, message}
+}
+
+// cloneString returns a string copy of s.
+// Do not use strings.Clone to avoid dependency on strings package.
+func cloneString(s string) string {
+ return string([]byte(s))
+}
+
+// These are borrowed from unicode/utf8 and strconv and replicate behavior in
+// that package, since we can't take a dependency on either.
+const (
+ lowerhex = "0123456789abcdef"
+ runeSelf = 0x80
+ runeError = '\uFFFD'
+)
+
+func quote(s string) string {
+ buf := make([]byte, 1, len(s)+2) // slice will be at least len(s) + quotes
+ buf[0] = '"'
+ for i, c := range s {
+ if c >= runeSelf || c < ' ' {
+ // This means you are asking us to parse a time.Duration or
+ // time.Location with unprintable or non-ASCII characters in it.
+ // We don't expect to hit this case very often. We could try to
+ // reproduce strconv.Quote's behavior with full fidelity but
+ // given how rarely we expect to hit these edge cases, speed and
+ // conciseness are better.
+ var width int
+ if c == runeError {
+ width = 1
+ if i+2 < len(s) && s[i:i+3] == string(runeError) {
+ width = 3
+ }
+ } else {
+ width = len(string(c))
+ }
+ for j := 0; j < width; j++ {
+ buf = append(buf, `\x`...)
+ buf = append(buf, lowerhex[s[i+j]>>4])
+ buf = append(buf, lowerhex[s[i+j]&0xF])
+ }
+ } else {
+ if c == '"' || c == '\\' {
+ buf = append(buf, '\\')
+ }
+ buf = append(buf, string(c)...)
+ }
+ }
+ buf = append(buf, '"')
+ return string(buf)
+}
+
+// Error returns the string representation of a ParseError.
+func (e *ParseError) Error() string {
+ if e.Message == "" {
+ return "parsing time " +
+ quote(e.Value) + " as " +
+ quote(e.Layout) + ": cannot parse " +
+ quote(e.ValueElem) + " as " +
+ quote(e.LayoutElem)
+ }
+ return "parsing time " +
+ quote(e.Value) + e.Message
+}
+
+// isDigit reports whether s[i] is in range and is a decimal digit.
+func isDigit[bytes []byte | string](s bytes, i int) bool {
+ if len(s) <= i {
+ return false
+ }
+ c := s[i]
+ return '0' <= c && c <= '9'
+}
+
+// getnum parses s[0:1] or s[0:2] (fixed forces s[0:2])
+// as a decimal integer and returns the integer and the
+// remainder of the string.
+func getnum(s string, fixed bool) (int, string, error) {
+ if !isDigit(s, 0) {
+ return 0, s, errBad
+ }
+ if !isDigit(s, 1) {
+ if fixed {
+ return 0, s, errBad
+ }
+ return int(s[0] - '0'), s[1:], nil
+ }
+ return int(s[0]-'0')*10 + int(s[1]-'0'), s[2:], nil
+}
+
+// getnum3 parses s[0:1], s[0:2], or s[0:3] (fixed forces s[0:3])
+// as a decimal integer and returns the integer and the remainder
+// of the string.
+func getnum3(s string, fixed bool) (int, string, error) {
+ var n, i int
+ for i = 0; i < 3 && isDigit(s, i); i++ {
+ n = n*10 + int(s[i]-'0')
+ }
+ if i == 0 || fixed && i != 3 {
+ return 0, s, errBad
+ }
+ return n, s[i:], nil
+}
+
+func cutspace(s string) string {
+ for len(s) > 0 && s[0] == ' ' {
+ s = s[1:]
+ }
+ return s
+}
+
+// skip removes the given prefix from value,
+// treating runs of space characters as equivalent.
+func skip(value, prefix string) (string, error) {
+ for len(prefix) > 0 {
+ if prefix[0] == ' ' {
+ if len(value) > 0 && value[0] != ' ' {
+ return value, errBad
+ }
+ prefix = cutspace(prefix)
+ value = cutspace(value)
+ continue
+ }
+ if len(value) == 0 || value[0] != prefix[0] {
+ return value, errBad
+ }
+ prefix = prefix[1:]
+ value = value[1:]
+ }
+ return value, nil
+}
+
+// Parse parses a formatted string and returns the time value it represents.
+// See the documentation for the constant called Layout to see how to
+// represent the format. The second argument must be parseable using
+// the format string (layout) provided as the first argument.
+//
+// The example for Time.Format demonstrates the working of the layout string
+// in detail and is a good reference.
+//
+// When parsing (only), the input may contain a fractional second
+// field immediately after the seconds field, even if the layout does not
+// signify its presence. In that case either a comma or a decimal point
+// followed by a maximal series of digits is parsed as a fractional second.
+// Fractional seconds are truncated to nanosecond precision.
+//
+// Elements omitted from the layout are assumed to be zero or, when
+// zero is impossible, one, so parsing "3:04pm" returns the time
+// corresponding to Jan 1, year 0, 15:04:00 UTC (note that because the year is
+// 0, this time is before the zero Time).
+// Years must be in the range 0000..9999. The day of the week is checked
+// for syntax but it is otherwise ignored.
+//
+// For layouts specifying the two-digit year 06, a value NN >= 69 will be treated
+// as 19NN and a value NN < 69 will be treated as 20NN.
+//
+// The remainder of this comment describes the handling of time zones.
+//
+// In the absence of a time zone indicator, Parse returns a time in UTC.
+//
+// When parsing a time with a zone offset like -0700, if the offset corresponds
+// to a time zone used by the current location (Local), then Parse uses that
+// location and zone in the returned time. Otherwise it records the time as
+// being in a fabricated location with time fixed at the given zone offset.
+//
+// When parsing a time with a zone abbreviation like MST, if the zone abbreviation
+// has a defined offset in the current location, then that offset is used.
+// The zone abbreviation "UTC" is recognized as UTC regardless of location.
+// If the zone abbreviation is unknown, Parse records the time as being
+// in a fabricated location with the given zone abbreviation and a zero offset.
+// This choice means that such a time can be parsed and reformatted with the
+// same layout losslessly, but the exact instant used in the representation will
+// differ by the actual zone offset. To avoid such problems, prefer time layouts
+// that use a numeric zone offset, or use ParseInLocation.
+func Parse(layout, value string) (Time, error) {
+ // Optimize for RFC3339 as it accounts for over half of all representations.
+ if layout == RFC3339 || layout == RFC3339Nano {
+ if t, ok := parseRFC3339(value, Local); ok {
+ return t, nil
+ }
+ }
+ return parse(layout, value, UTC, Local)
+}
+
+// ParseInLocation is like Parse but differs in two important ways.
+// First, in the absence of time zone information, Parse interprets a time as UTC;
+// ParseInLocation interprets the time as in the given location.
+// Second, when given a zone offset or abbreviation, Parse tries to match it
+// against the Local location; ParseInLocation uses the given location.
+func ParseInLocation(layout, value string, loc *Location) (Time, error) {
+ // Optimize for RFC3339 as it accounts for over half of all representations.
+ if layout == RFC3339 || layout == RFC3339Nano {
+ if t, ok := parseRFC3339(value, loc); ok {
+ return t, nil
+ }
+ }
+ return parse(layout, value, loc, loc)
+}
+
+func parse(layout, value string, defaultLocation, local *Location) (Time, error) {
+ alayout, avalue := layout, value
+ rangeErrString := "" // set if a value is out of range
+ amSet := false // do we need to subtract 12 from the hour for midnight?
+ pmSet := false // do we need to add 12 to the hour?
+
+ // Time being constructed.
+ var (
+ year int
+ month int = -1
+ day int = -1
+ yday int = -1
+ hour int
+ min int
+ sec int
+ nsec int
+ z *Location
+ zoneOffset int = -1
+ zoneName string
+ )
+
+ // Each iteration processes one std value.
+ for {
+ var err error
+ prefix, std, suffix := nextStdChunk(layout)
+ stdstr := layout[len(prefix) : len(layout)-len(suffix)]
+ value, err = skip(value, prefix)
+ if err != nil {
+ return Time{}, newParseError(alayout, avalue, prefix, value, "")
+ }
+ if std == 0 {
+ if len(value) != 0 {
+ return Time{}, newParseError(alayout, avalue, "", value, ": extra text: "+quote(value))
+ }
+ break
+ }
+ layout = suffix
+ var p string
+ hold := value
+ switch std & stdMask {
+ case stdYear:
+ if len(value) < 2 {
+ err = errBad
+ break
+ }
+ p, value = value[0:2], value[2:]
+ year, err = atoi(p)
+ if err != nil {
+ break
+ }
+ if year >= 69 { // Unix time starts Dec 31 1969 in some time zones
+ year += 1900
+ } else {
+ year += 2000
+ }
+ case stdLongYear:
+ if len(value) < 4 || !isDigit(value, 0) {
+ err = errBad
+ break
+ }
+ p, value = value[0:4], value[4:]
+ year, err = atoi(p)
+ case stdMonth:
+ month, value, err = lookup(shortMonthNames, value)
+ month++
+ case stdLongMonth:
+ month, value, err = lookup(longMonthNames, value)
+ month++
+ case stdNumMonth, stdZeroMonth:
+ month, value, err = getnum(value, std == stdZeroMonth)
+ if err == nil && (month <= 0 || 12 < month) {
+ rangeErrString = "month"
+ }
+ case stdWeekDay:
+ // Ignore weekday except for error checking.
+ _, value, err = lookup(shortDayNames, value)
+ case stdLongWeekDay:
+ _, value, err = lookup(longDayNames, value)
+ case stdDay, stdUnderDay, stdZeroDay:
+ if std == stdUnderDay && len(value) > 0 && value[0] == ' ' {
+ value = value[1:]
+ }
+ day, value, err = getnum(value, std == stdZeroDay)
+ // Note that we allow any one- or two-digit day here.
+ // The month, day, year combination is validated after we've completed parsing.
+ case stdUnderYearDay, stdZeroYearDay:
+ for i := 0; i < 2; i++ {
+ if std == stdUnderYearDay && len(value) > 0 && value[0] == ' ' {
+ value = value[1:]
+ }
+ }
+ yday, value, err = getnum3(value, std == stdZeroYearDay)
+ // Note that we allow any one-, two-, or three-digit year-day here.
+ // The year-day, year combination is validated after we've completed parsing.
+ case stdHour:
+ hour, value, err = getnum(value, false)
+ if hour < 0 || 24 <= hour {
+ rangeErrString = "hour"
+ }
+ case stdHour12, stdZeroHour12:
+ hour, value, err = getnum(value, std == stdZeroHour12)
+ if hour < 0 || 12 < hour {
+ rangeErrString = "hour"
+ }
+ case stdMinute, stdZeroMinute:
+ min, value, err = getnum(value, std == stdZeroMinute)
+ if min < 0 || 60 <= min {
+ rangeErrString = "minute"
+ }
+ case stdSecond, stdZeroSecond:
+ sec, value, err = getnum(value, std == stdZeroSecond)
+ if err != nil {
+ break
+ }
+ if sec < 0 || 60 <= sec {
+ rangeErrString = "second"
+ break
+ }
+ // Special case: do we have a fractional second but no
+ // fractional second in the format?
+ if len(value) >= 2 && commaOrPeriod(value[0]) && isDigit(value, 1) {
+ _, std, _ = nextStdChunk(layout)
+ std &= stdMask
+ if std == stdFracSecond0 || std == stdFracSecond9 {
+ // Fractional second in the layout; proceed normally
+ break
+ }
+ // No fractional second in the layout but we have one in the input.
+ n := 2
+ for ; n < len(value) && isDigit(value, n); n++ {
+ }
+ nsec, rangeErrString, err = parseNanoseconds(value, n)
+ value = value[n:]
+ }
+ case stdPM:
+ if len(value) < 2 {
+ err = errBad
+ break
+ }
+ p, value = value[0:2], value[2:]
+ switch p {
+ case "PM":
+ pmSet = true
+ case "AM":
+ amSet = true
+ default:
+ err = errBad
+ }
+ case stdpm:
+ if len(value) < 2 {
+ err = errBad
+ break
+ }
+ p, value = value[0:2], value[2:]
+ switch p {
+ case "pm":
+ pmSet = true
+ case "am":
+ amSet = true
+ default:
+ err = errBad
+ }
+ case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ShortTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumShortTZ, stdNumColonTZ, stdNumSecondsTz, stdNumColonSecondsTZ:
+ if (std == stdISO8601TZ || std == stdISO8601ShortTZ || std == stdISO8601ColonTZ) && len(value) >= 1 && value[0] == 'Z' {
+ value = value[1:]
+ z = UTC
+ break
+ }
+ var sign, hour, min, seconds string
+ if std == stdISO8601ColonTZ || std == stdNumColonTZ {
+ if len(value) < 6 {
+ err = errBad
+ break
+ }
+ if value[3] != ':' {
+ err = errBad
+ break
+ }
+ sign, hour, min, seconds, value = value[0:1], value[1:3], value[4:6], "00", value[6:]
+ } else if std == stdNumShortTZ || std == stdISO8601ShortTZ {
+ if len(value) < 3 {
+ err = errBad
+ break
+ }
+ sign, hour, min, seconds, value = value[0:1], value[1:3], "00", "00", value[3:]
+ } else if std == stdISO8601ColonSecondsTZ || std == stdNumColonSecondsTZ {
+ if len(value) < 9 {
+ err = errBad
+ break
+ }
+ if value[3] != ':' || value[6] != ':' {
+ err = errBad
+ break
+ }
+ sign, hour, min, seconds, value = value[0:1], value[1:3], value[4:6], value[7:9], value[9:]
+ } else if std == stdISO8601SecondsTZ || std == stdNumSecondsTz {
+ if len(value) < 7 {
+ err = errBad
+ break
+ }
+ sign, hour, min, seconds, value = value[0:1], value[1:3], value[3:5], value[5:7], value[7:]
+ } else {
+ if len(value) < 5 {
+ err = errBad
+ break
+ }
+ sign, hour, min, seconds, value = value[0:1], value[1:3], value[3:5], "00", value[5:]
+ }
+ var hr, mm, ss int
+ hr, _, err = getnum(hour, true)
+ if err == nil {
+ mm, _, err = getnum(min, true)
+ }
+ if err == nil {
+ ss, _, err = getnum(seconds, true)
+ }
+ zoneOffset = (hr*60+mm)*60 + ss // offset is in seconds
+ switch sign[0] {
+ case '+':
+ case '-':
+ zoneOffset = -zoneOffset
+ default:
+ err = errBad
+ }
+ case stdTZ:
+ // Does it look like a time zone?
+ if len(value) >= 3 && value[0:3] == "UTC" {
+ z = UTC
+ value = value[3:]
+ break
+ }
+ n, ok := parseTimeZone(value)
+ if !ok {
+ err = errBad
+ break
+ }
+ zoneName, value = value[:n], value[n:]
+
+ case stdFracSecond0:
+ // stdFracSecond0 requires the exact number of digits as specified in
+ // the layout.
+ ndigit := 1 + digitsLen(std)
+ if len(value) < ndigit {
+ err = errBad
+ break
+ }
+ nsec, rangeErrString, err = parseNanoseconds(value, ndigit)
+ value = value[ndigit:]
+
+ case stdFracSecond9:
+ if len(value) < 2 || !commaOrPeriod(value[0]) || value[1] < '0' || '9' < value[1] {
+ // Fractional second omitted.
+ break
+ }
+ // Take any number of digits, even more than asked for,
+ // because it is what the stdSecond case would do.
+ i := 0
+ for i+1 < len(value) && '0' <= value[i+1] && value[i+1] <= '9' {
+ i++
+ }
+ nsec, rangeErrString, err = parseNanoseconds(value, 1+i)
+ value = value[1+i:]
+ }
+ if rangeErrString != "" {
+ return Time{}, newParseError(alayout, avalue, stdstr, value, ": "+rangeErrString+" out of range")
+ }
+ if err != nil {
+ return Time{}, newParseError(alayout, avalue, stdstr, hold, "")
+ }
+ }
+ if pmSet && hour < 12 {
+ hour += 12
+ } else if amSet && hour == 12 {
+ hour = 0
+ }
+
+ // Convert yday to day, month.
+ if yday >= 0 {
+ var d int
+ var m int
+ if isLeap(year) {
+ if yday == 31+29 {
+ m = int(February)
+ d = 29
+ } else if yday > 31+29 {
+ yday--
+ }
+ }
+ if yday < 1 || yday > 365 {
+ return Time{}, newParseError(alayout, avalue, "", value, ": day-of-year out of range")
+ }
+ if m == 0 {
+ m = (yday-1)/31 + 1
+ if int(daysBefore[m]) < yday {
+ m++
+ }
+ d = yday - int(daysBefore[m-1])
+ }
+ // If month, day already seen, yday's m, d must match.
+ // Otherwise, set them from m, d.
+ if month >= 0 && month != m {
+ return Time{}, newParseError(alayout, avalue, "", value, ": day-of-year does not match month")
+ }
+ month = m
+ if day >= 0 && day != d {
+ return Time{}, newParseError(alayout, avalue, "", value, ": day-of-year does not match day")
+ }
+ day = d
+ } else {
+ if month < 0 {
+ month = int(January)
+ }
+ if day < 0 {
+ day = 1
+ }
+ }
+
+ // Validate the day of the month.
+ if day < 1 || day > daysIn(Month(month), year) {
+ return Time{}, newParseError(alayout, avalue, "", value, ": day out of range")
+ }
+
+ if z != nil {
+ return Date(year, Month(month), day, hour, min, sec, nsec, z), nil
+ }
+
+ if zoneOffset != -1 {
+ t := Date(year, Month(month), day, hour, min, sec, nsec, UTC)
+ t.addSec(-int64(zoneOffset))
+
+ // Look for local zone with the given offset.
+ // If that zone was in effect at the given time, use it.
+ name, offset, _, _, _ := local.lookup(t.unixSec())
+ if offset == zoneOffset && (zoneName == "" || name == zoneName) {
+ t.setLoc(local)
+ return t, nil
+ }
+
+ // Otherwise create fake zone to record offset.
+ zoneNameCopy := cloneString(zoneName) // avoid leaking the input value
+ t.setLoc(FixedZone(zoneNameCopy, zoneOffset))
+ return t, nil
+ }
+
+ if zoneName != "" {
+ t := Date(year, Month(month), day, hour, min, sec, nsec, UTC)
+ // Look for local zone with the given offset.
+ // If that zone was in effect at the given time, use it.
+ offset, ok := local.lookupName(zoneName, t.unixSec())
+ if ok {
+ t.addSec(-int64(offset))
+ t.setLoc(local)
+ return t, nil
+ }
+
+ // Otherwise, create fake zone with unknown offset.
+ if len(zoneName) > 3 && zoneName[:3] == "GMT" {
+ offset, _ = atoi(zoneName[3:]) // Guaranteed OK by parseGMT.
+ offset *= 3600
+ }
+ zoneNameCopy := cloneString(zoneName) // avoid leaking the input value
+ t.setLoc(FixedZone(zoneNameCopy, offset))
+ return t, nil
+ }
+
+ // Otherwise, fall back to default.
+ return Date(year, Month(month), day, hour, min, sec, nsec, defaultLocation), nil
+}
+
+// parseTimeZone parses a time zone string and returns its length. Time zones
+// are human-generated and unpredictable. We can't do precise error checking.
+// On the other hand, for a correct parse there must be a time zone at the
+// beginning of the string, so it's almost always true that there's one
+// there. We look at the beginning of the string for a run of upper-case letters.
+// If there are more than 5, it's an error.
+// If there are 4 or 5 and the last is a T, it's a time zone.
+// If there are 3, it's a time zone.
+// Otherwise, other than special cases, it's not a time zone.
+// GMT is special because it can have an hour offset.
+func parseTimeZone(value string) (length int, ok bool) {
+ if len(value) < 3 {
+ return 0, false
+ }
+ // Special case 1: ChST and MeST are the only zones with a lower-case letter.
+ if len(value) >= 4 && (value[:4] == "ChST" || value[:4] == "MeST") {
+ return 4, true
+ }
+ // Special case 2: GMT may have an hour offset; treat it specially.
+ if value[:3] == "GMT" {
+ length = parseGMT(value)
+ return length, true
+ }
+ // Special Case 3: Some time zones are not named, but have +/-00 format
+ if value[0] == '+' || value[0] == '-' {
+ length = parseSignedOffset(value)
+ ok := length > 0 // parseSignedOffset returns 0 in case of bad input
+ return length, ok
+ }
+ // How many upper-case letters are there? Need at least three, at most five.
+ var nUpper int
+ for nUpper = 0; nUpper < 6; nUpper++ {
+ if nUpper >= len(value) {
+ break
+ }
+ if c := value[nUpper]; c < 'A' || 'Z' < c {
+ break
+ }
+ }
+ switch nUpper {
+ case 0, 1, 2, 6:
+ return 0, false
+ case 5: // Must end in T to match.
+ if value[4] == 'T' {
+ return 5, true
+ }
+ case 4:
+ // Must end in T, except one special case.
+ if value[3] == 'T' || value[:4] == "WITA" {
+ return 4, true
+ }
+ case 3:
+ return 3, true
+ }
+ return 0, false
+}
+
+// parseGMT parses a GMT time zone. The input string is known to start "GMT".
+// The function checks whether that is followed by a sign and a number in the
+// range -23 through +23 excluding zero.
+func parseGMT(value string) int {
+ value = value[3:]
+ if len(value) == 0 {
+ return 3
+ }
+
+ return 3 + parseSignedOffset(value)
+}
+
+// parseSignedOffset parses a signed timezone offset (e.g. "+03" or "-04").
+// The function checks for a signed number in the range -23 through +23 excluding zero.
+// Returns length of the found offset string or 0 otherwise.
+func parseSignedOffset(value string) int {
+ sign := value[0]
+ if sign != '-' && sign != '+' {
+ return 0
+ }
+ x, rem, err := leadingInt(value[1:])
+
+ // fail if nothing consumed by leadingInt
+ if err != nil || value[1:] == rem {
+ return 0
+ }
+ if x > 23 {
+ return 0
+ }
+ return len(value) - len(rem)
+}
+
+func commaOrPeriod(b byte) bool {
+ return b == '.' || b == ','
+}
+
+func parseNanoseconds[bytes []byte | string](value bytes, nbytes int) (ns int, rangeErrString string, err error) {
+ if !commaOrPeriod(value[0]) {
+ err = errBad
+ return
+ }
+ if nbytes > 10 {
+ value = value[:10]
+ nbytes = 10
+ }
+ if ns, err = atoi(value[1:nbytes]); err != nil {
+ return
+ }
+ if ns < 0 {
+ rangeErrString = "fractional second"
+ return
+ }
+ // We need nanoseconds, which means scaling by the number
+ // of missing digits in the format, maximum length 10.
+ scaleDigits := 10 - nbytes
+ for i := 0; i < scaleDigits; i++ {
+ ns *= 10
+ }
+ return
+}
+
+var errLeadingInt = errors.New("time: bad [0-9]*") // never printed
+
+// leadingInt consumes the leading [0-9]* from s.
+func leadingInt[bytes []byte | string](s bytes) (x uint64, rem bytes, err error) {
+ i := 0
+ for ; i < len(s); i++ {
+ c := s[i]
+ if c < '0' || c > '9' {
+ break
+ }
+ if x > 1<<63/10 {
+ // overflow
+ return 0, rem, errLeadingInt
+ }
+ x = x*10 + uint64(c) - '0'
+ if x > 1<<63 {
+ // overflow
+ return 0, rem, errLeadingInt
+ }
+ }
+ return x, s[i:], nil
+}
+
+// leadingFraction consumes the leading [0-9]* from s.
+// It is used only for fractions, so does not return an error on overflow,
+// it just stops accumulating precision.
+func leadingFraction(s string) (x uint64, scale float64, rem string) {
+ i := 0
+ scale = 1
+ overflow := false
+ for ; i < len(s); i++ {
+ c := s[i]
+ if c < '0' || c > '9' {
+ break
+ }
+ if overflow {
+ continue
+ }
+ if x > (1<<63-1)/10 {
+ // It's possible for overflow to give a positive number, so take care.
+ overflow = true
+ continue
+ }
+ y := x*10 + uint64(c) - '0'
+ if y > 1<<63 {
+ overflow = true
+ continue
+ }
+ x = y
+ scale *= 10
+ }
+ return x, scale, s[i:]
+}
+
+var unitMap = map[string]uint64{
+ "ns": uint64(Nanosecond),
+ "us": uint64(Microsecond),
+ "µs": uint64(Microsecond), // U+00B5 = micro symbol
+ "μs": uint64(Microsecond), // U+03BC = Greek letter mu
+ "ms": uint64(Millisecond),
+ "s": uint64(Second),
+ "m": uint64(Minute),
+ "h": uint64(Hour),
+}
+
+// ParseDuration parses a duration string.
+// A duration string is a possibly signed sequence of
+// decimal numbers, each with optional fraction and a unit suffix,
+// such as "300ms", "-1.5h" or "2h45m".
+// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
+func ParseDuration(s string) (Duration, error) {
+ // [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
+ orig := s
+ var d uint64
+ neg := false
+
+ // Consume [-+]?
+ if s != "" {
+ c := s[0]
+ if c == '-' || c == '+' {
+ neg = c == '-'
+ s = s[1:]
+ }
+ }
+ // Special case: if all that is left is "0", this is zero.
+ if s == "0" {
+ return 0, nil
+ }
+ if s == "" {
+ return 0, errors.New("time: invalid duration " + quote(orig))
+ }
+ for s != "" {
+ var (
+ v, f uint64 // integers before, after decimal point
+ scale float64 = 1 // value = v + f/scale
+ )
+
+ var err error
+
+ // The next character must be [0-9.]
+ if !(s[0] == '.' || '0' <= s[0] && s[0] <= '9') {
+ return 0, errors.New("time: invalid duration " + quote(orig))
+ }
+ // Consume [0-9]*
+ pl := len(s)
+ v, s, err = leadingInt(s)
+ if err != nil {
+ return 0, errors.New("time: invalid duration " + quote(orig))
+ }
+ pre := pl != len(s) // whether we consumed anything before a period
+
+ // Consume (\.[0-9]*)?
+ post := false
+ if s != "" && s[0] == '.' {
+ s = s[1:]
+ pl := len(s)
+ f, scale, s = leadingFraction(s)
+ post = pl != len(s)
+ }
+ if !pre && !post {
+ // no digits (e.g. ".s" or "-.s")
+ return 0, errors.New("time: invalid duration " + quote(orig))
+ }
+
+ // Consume unit.
+ i := 0
+ for ; i < len(s); i++ {
+ c := s[i]
+ if c == '.' || '0' <= c && c <= '9' {
+ break
+ }
+ }
+ if i == 0 {
+ return 0, errors.New("time: missing unit in duration " + quote(orig))
+ }
+ u := s[:i]
+ s = s[i:]
+ unit, ok := unitMap[u]
+ if !ok {
+ return 0, errors.New("time: unknown unit " + quote(u) + " in duration " + quote(orig))
+ }
+ if v > 1<<63/unit {
+ // overflow
+ return 0, errors.New("time: invalid duration " + quote(orig))
+ }
+ v *= unit
+ if f > 0 {
+ // float64 is needed to be nanosecond accurate for fractions of hours.
+ // v >= 0 && (f*unit/scale) <= 3.6e+12 (ns/h, h is the largest unit)
+ v += uint64(float64(f) * (float64(unit) / scale))
+ if v > 1<<63 {
+ // overflow
+ return 0, errors.New("time: invalid duration " + quote(orig))
+ }
+ }
+ d += v
+ if d > 1<<63 {
+ return 0, errors.New("time: invalid duration " + quote(orig))
+ }
+ }
+ if neg {
+ return -Duration(d), nil
+ }
+ if d > 1<<63-1 {
+ return 0, errors.New("time: invalid duration " + quote(orig))
+ }
+ return Duration(d), nil
+}
diff --git a/contrib/go/_std_1.20/src/time/format_rfc3339.go b/contrib/go/_std_1.21/src/time/format_rfc3339.go
index 1151666c3e..1151666c3e 100644
--- a/contrib/go/_std_1.20/src/time/format_rfc3339.go
+++ b/contrib/go/_std_1.21/src/time/format_rfc3339.go
diff --git a/contrib/go/_std_1.20/src/time/sleep.go b/contrib/go/_std_1.21/src/time/sleep.go
index cdab4782ad..cdab4782ad 100644
--- a/contrib/go/_std_1.20/src/time/sleep.go
+++ b/contrib/go/_std_1.21/src/time/sleep.go
diff --git a/contrib/go/_std_1.21/src/time/sys_unix.go b/contrib/go/_std_1.21/src/time/sys_unix.go
new file mode 100644
index 0000000000..63634ace7c
--- /dev/null
+++ b/contrib/go/_std_1.21/src/time/sys_unix.go
@@ -0,0 +1,62 @@
+// Copyright 2011 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.
+
+//go:build unix || (js && wasm) || wasip1
+
+package time
+
+import (
+ "errors"
+ "runtime"
+ "syscall"
+)
+
+// for testing: whatever interrupts a sleep
+func interrupt() {
+ // There is no mechanism in wasi to interrupt the call to poll_oneoff
+ // used to implement runtime.usleep so this function does nothing, which
+ // somewhat defeats the purpose of TestSleep but we are still better off
+ // validating that time elapses when the process calls time.Sleep than
+ // skipping the test altogether.
+ if runtime.GOOS != "wasip1" {
+ syscall.Kill(syscall.Getpid(), syscall.SIGCHLD)
+ }
+}
+
+func open(name string) (uintptr, error) {
+ fd, err := syscall.Open(name, syscall.O_RDONLY, 0)
+ if err != nil {
+ return 0, err
+ }
+ return uintptr(fd), nil
+}
+
+func read(fd uintptr, buf []byte) (int, error) {
+ return syscall.Read(int(fd), buf)
+}
+
+func closefd(fd uintptr) {
+ syscall.Close(int(fd))
+}
+
+func preadn(fd uintptr, buf []byte, off int) error {
+ whence := seekStart
+ if off < 0 {
+ whence = seekEnd
+ }
+ if _, err := syscall.Seek(int(fd), int64(off), whence); err != nil {
+ return err
+ }
+ for len(buf) > 0 {
+ m, err := syscall.Read(int(fd), buf)
+ if m <= 0 {
+ if err == nil {
+ return errors.New("short read")
+ }
+ return err
+ }
+ buf = buf[m:]
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.20/src/time/sys_windows.go b/contrib/go/_std_1.21/src/time/sys_windows.go
index 78e182d4c5..78e182d4c5 100644
--- a/contrib/go/_std_1.20/src/time/sys_windows.go
+++ b/contrib/go/_std_1.21/src/time/sys_windows.go
diff --git a/contrib/go/_std_1.21/src/time/tick.go b/contrib/go/_std_1.21/src/time/tick.go
new file mode 100644
index 0000000000..9da16b5d58
--- /dev/null
+++ b/contrib/go/_std_1.21/src/time/tick.go
@@ -0,0 +1,71 @@
+// Copyright 2009 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 time
+
+// A Ticker holds a channel that delivers “ticks” of a clock
+// at intervals.
+type Ticker struct {
+ C <-chan Time // The channel on which the ticks are delivered.
+ r runtimeTimer
+}
+
+// NewTicker returns a new Ticker containing a channel that will send
+// the current time on the channel after each tick. The period of the
+// ticks is specified by the duration argument. The ticker will adjust
+// the time interval or drop ticks to make up for slow receivers.
+// The duration d must be greater than zero; if not, NewTicker will
+// panic. Stop the ticker to release associated resources.
+func NewTicker(d Duration) *Ticker {
+ if d <= 0 {
+ panic("non-positive interval for NewTicker")
+ }
+ // Give the channel a 1-element time buffer.
+ // If the client falls behind while reading, we drop ticks
+ // on the floor until the client catches up.
+ c := make(chan Time, 1)
+ t := &Ticker{
+ C: c,
+ r: runtimeTimer{
+ when: when(d),
+ period: int64(d),
+ f: sendTime,
+ arg: c,
+ },
+ }
+ startTimer(&t.r)
+ return t
+}
+
+// Stop turns off a ticker. After Stop, no more ticks will be sent.
+// Stop does not close the channel, to prevent a concurrent goroutine
+// reading from the channel from seeing an erroneous "tick".
+func (t *Ticker) Stop() {
+ stopTimer(&t.r)
+}
+
+// Reset stops a ticker and resets its period to the specified duration.
+// The next tick will arrive after the new period elapses. The duration d
+// must be greater than zero; if not, Reset will panic.
+func (t *Ticker) Reset(d Duration) {
+ if d <= 0 {
+ panic("non-positive interval for Ticker.Reset")
+ }
+ if t.r.f == nil {
+ panic("time: Reset called on uninitialized Ticker")
+ }
+ modTimer(&t.r, when(d), int64(d), t.r.f, t.r.arg, t.r.seq)
+}
+
+// Tick is a convenience wrapper for NewTicker providing access to the ticking
+// channel only. While Tick is useful for clients that have no need to shut down
+// the Ticker, be aware that without a way to shut it down the underlying
+// Ticker cannot be recovered by the garbage collector; it "leaks".
+// Unlike NewTicker, Tick will return nil if d <= 0.
+func Tick(d Duration) <-chan Time {
+ if d <= 0 {
+ return nil
+ }
+ return NewTicker(d).C
+}
diff --git a/contrib/go/_std_1.20/src/time/time.go b/contrib/go/_std_1.21/src/time/time.go
index 21ced99c0a..21ced99c0a 100644
--- a/contrib/go/_std_1.20/src/time/time.go
+++ b/contrib/go/_std_1.21/src/time/time.go
diff --git a/contrib/go/_std_1.21/src/time/tzdata/tzdata.go b/contrib/go/_std_1.21/src/time/tzdata/tzdata.go
new file mode 100644
index 0000000000..43dd85c8cc
--- /dev/null
+++ b/contrib/go/_std_1.21/src/time/tzdata/tzdata.go
@@ -0,0 +1,111 @@
+// 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 tzdata provides an embedded copy of the timezone database.
+// If this package is imported anywhere in the program, then if
+// the time package cannot find tzdata files on the system,
+// it will use this embedded information.
+//
+// Importing this package will increase the size of a program by about
+// 450 KB.
+//
+// This package should normally be imported by a program's main package,
+// not by a library. Libraries normally shouldn't decide whether to
+// include the timezone database in a program.
+//
+// This package will be automatically imported if you build with
+// -tags timetzdata.
+package tzdata
+
+// The test for this package is time/tzdata_test.go.
+
+import (
+ "errors"
+ "syscall"
+ _ "unsafe" // for go:linkname
+
+)
+
+// registerLoadFromEmbeddedTZData is defined in package time.
+//
+//go:linkname registerLoadFromEmbeddedTZData time.registerLoadFromEmbeddedTZData
+func registerLoadFromEmbeddedTZData(func(string) (string, error))
+
+func init() {
+ registerLoadFromEmbeddedTZData(loadFromEmbeddedTZData)
+}
+
+// get4s returns the little-endian 32-bit value at the start of s.
+func get4s(s string) int {
+ if len(s) < 4 {
+ return 0
+ }
+ return int(s[0]) | int(s[1])<<8 | int(s[2])<<16 | int(s[3])<<24
+}
+
+// get2s returns the little-endian 16-bit value at the start of s.
+func get2s(s string) int {
+ if len(s) < 2 {
+ return 0
+ }
+ return int(s[0]) | int(s[1])<<8
+}
+
+// loadFromEmbeddedTZData returns the contents of the file with the given
+// name in an uncompressed zip file, where the contents of the file can
+// be found in embeddedTzdata.
+// This is similar to time.loadTzinfoFromZip.
+func loadFromEmbeddedTZData(name string) (string, error) {
+ const (
+ zecheader = 0x06054b50
+ zcheader = 0x02014b50
+ ztailsize = 22
+
+ zheadersize = 30
+ zheader = 0x04034b50
+ )
+
+ // zipdata is provided by zzipdata.go,
+ // which is generated by cmd/dist during make.bash.
+ z := zipdata
+
+ idx := len(z) - ztailsize
+ n := get2s(z[idx+10:])
+ idx = get4s(z[idx+16:])
+
+ for i := 0; i < n; i++ {
+ // See time.loadTzinfoFromZip for zip entry layout.
+ if get4s(z[idx:]) != zcheader {
+ break
+ }
+ meth := get2s(z[idx+10:])
+ size := get4s(z[idx+24:])
+ namelen := get2s(z[idx+28:])
+ xlen := get2s(z[idx+30:])
+ fclen := get2s(z[idx+32:])
+ off := get4s(z[idx+42:])
+ zname := z[idx+46 : idx+46+namelen]
+ idx += 46 + namelen + xlen + fclen
+ if zname != name {
+ continue
+ }
+ if meth != 0 {
+ return "", errors.New("unsupported compression for " + name + " in embedded tzdata")
+ }
+
+ // See time.loadTzinfoFromZip for zip per-file header layout.
+ idx = off
+ if get4s(z[idx:]) != zheader ||
+ get2s(z[idx+8:]) != meth ||
+ get2s(z[idx+26:]) != namelen ||
+ z[idx+30:idx+30+namelen] != name {
+ return "", errors.New("corrupt embedded tzdata")
+ }
+ xlen = get2s(z[idx+28:])
+ idx += 30 + namelen + xlen
+ return z[idx : idx+size], nil
+ }
+
+ return "", syscall.ENOENT
+}
diff --git a/contrib/go/_std_1.21/src/time/tzdata/ya.make b/contrib/go/_std_1.21/src/time/tzdata/ya.make
new file mode 100644
index 0000000000..11435b498f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/time/tzdata/ya.make
@@ -0,0 +1,8 @@
+GO_LIBRARY()
+
+SRCS(
+ tzdata.go
+ zzipdata.go
+)
+
+END()
diff --git a/contrib/go/_std_1.21/src/time/tzdata/zzipdata.go b/contrib/go/_std_1.21/src/time/tzdata/zzipdata.go
new file mode 100644
index 0000000000..bdb5151f66
--- /dev/null
+++ b/contrib/go/_std_1.21/src/time/tzdata/zzipdata.go
@@ -0,0 +1,5 @@
+// Code generated by go tool dist; DO NOT EDIT.
+
+package tzdata
+
+const zipdata = "PK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x00\x00Africa/AbidjanTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0c\x00\x00\x00Africa/AccraTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x12\x00\x00\x00Africa/Addis_AbabaTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\x22\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\x0a\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\x0aEAT-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\x8a\x0e\xc0\xd6\x01\x00\x00\xd6\x01\x00\x00\x0e\x00\x00\x00Africa/AlgiersTZif2\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\x22\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffk\xc9\x9b$\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\x0c\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa4\xb8\x06p\xff\xff\xff\xff\xc6\xff\x06p\xff\xff\xff\xff\xc7X\xba\x80\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x8a\x00\x00\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N$p\xff\xff\xff\xff\xd4K\x07p\xff\xff\xff\xff\xe5\xce\xd3\x00\xff\xff\xff\xff\xf3\x5c\xb0\xf0\x00\x00\x00\x00\x02x\xc1\xf0\x00\x00\x00\x00\x03C\xc8\xf0\x00\x00\x00\x00\x0d\xcf\xd7\x00\x00\x00\x00\x00\x0e\xadD\xf0\x00\x00\x00\x00\x0fxZ\x00\x00\x00\x00\x00\x10hY\x10\x00\x00\x00\x00\x12vCp\x00\x00\x00\x00\x13fB\x80\x00\x00\x00\x00\x14_|\x10\x00\x00\x00\x00\x15O_\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x03\x05\x03\x02\x03\x02\x05\x04\x05\x03\x02\x03\x05\x00\x00\x02\xdc\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\x08\x00\x00\x00\x00\x00\x0d\x00\x00\x1c \x01\x11\x00\x00\x0e\x10\x00\x16LMT\x00PMT\x00WEST\x00WET\x00CEST\x00CET\x00\x0aCET-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0d\x00\x00\x00Africa/AsmaraTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\x22\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\x0a\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\x0aEAT-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0d\x00\x00\x00Africa/AsmeraTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\x22\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\x0a\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\x0aEAT-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0d\x00\x00\x00Africa/BamakoTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0d\x00\x00\x00Africa/BanguiTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x07\x08\x00\x08\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\x0aWAT-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0d\x00\x00\x00Africa/BanjulTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca>\xd5\xe0\x95\x00\x00\x00\x95\x00\x00\x00\x0d\x00\x00\x00Africa/BissauTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x92\xe6\x9c\x90\x00\x00\x00\x00\x09ga\x10\x01\x02\xff\xff\xf1d\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x00\x00\x00\x08LMT\x00-01\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x00\x00Africa/BlantyreTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\x0aCAT-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x12\x00\x00\x00Africa/BrazzavilleTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x07\x08\x00\x08\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\x0aWAT-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x10\x00\x00\x00Africa/BujumburaTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\x0aCAT-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5#)\x16\x1d\x05\x00\x00\x1d\x05\x00\x00\x0c\x00\x00\x00Africa/CairoTZif2\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\x80\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xff}\xbdM\xab\xff\xff\xff\xff\xc8\x93\xb4\xe0\xff\xff\xff\xff\xc8\xfa{\xd0\xff\xff\xff\xff\xc9\xfc\xef\xe0\xff\xff\xff\xff\xca\xc7\xe8\xd0\xff\xff\xff\xff\xcb\xcb\xae`\xff\xff\xff\xff\xcc\xdf)\xd0\xff\xff\xff\xff\xcd\xac\xe1\xe0\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xff\xcf\x8ff\xe0\xff\xff\xff\xff\xd0\xa9y\xd0\xff\xff\xff\xff\xd1\x84`\xe0\xff\xff\xff\xff\xd2\x8a\xadP\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\x0b\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\x7f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xff\xef\xb0\xb3p\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\xc2\xfd\x80\xff\xff\xff\xff\xfc\xdb\xbe\xf0\xff\xff\xff\xff\xfd\xa5\x82\x80\xff\xff\xff\xff\xfe\xbc\xf2p\xff\xff\xff\xff\xff\x86\xb6\x00\x00\x00\x00\x00\x00\x9e%\xf0\x00\x00\x00\x00\x01g\xe9\x80\x00\x00\x00\x00\x02\x7fYp\x00\x00\x00\x00\x03I\x1d\x00\x00\x00\x00\x00\x04a\xdep\x00\x00\x00\x00\x05+\xa2\x00\x00\x00\x00\x00\x06C\x11\xf0\x00\x00\x00\x00\x07\x0c\xd5\x80\x00\x00\x00\x00\x08$Ep\x00\x00\x00\x00\x08\xee\x09\x00\x00\x00\x00\x00\x0a\x05x\xf0\x00\x00\x00\x00\x0a\xcf<\x80\x00\x00\x00\x00\x0b\xe7\xfd\xf0\x00\x00\x00\x00\x0c\xb1\xc1\x80\x00\x00\x00\x00\x0d\xc91p\x00\x00\x00\x00\x0e\x92\xf5\x00\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11\x8b\x98p\x00\x00\x00\x00\x12U\x5c\x00\x00\x00\x00\x00\x13n\x1dp\x00\x00\x00\x00\x147\xe1\x00\x00\x00\x00\x00\x15OP\xf0\x00\x00\x00\x00\x16\x19\x14\x80\x00\x00\x00\x00\x17\xa0\x93\xf0\x00\x00\x00\x00\x17\xfaH\x00\x00\x00\x00\x00\x19p\xa3\xf0\x00\x00\x00\x00\x19\xdb{\x80\x00\x00\x00\x00\x1a\xf4<\xf0\x00\x00\x00\x00\x1b\xbe\x00\x80\x00\x00\x00\x00\x1c\xd5pp\x00\x00\x00\x00\x1d\x9f4\x00\x00\x00\x00\x00\x1e\xb6\xa3\xf0\x00\x00\x00\x00\x1f\x80g\x80\x00\x00\x00\x00 \x97\xd7p\x00\x00\x00\x00!a\x9b\x00\x00\x00\x00\x00\x22z\x5cp\x00\x00\x00\x00#D \x00\x00\x00\x00\x00$b'p\x00\x00\x00\x00%%S\x80\x00\x00\x00\x00&<\xc3p\x00\x00\x00\x00'\x06\x87\x00\x00\x00\x00\x00(\x1d\xf6\xf0\x00\x00\x00\x00(\xe7\xba\x80\x00\x00\x00\x00*\x00{\xf0\x00\x00\x00\x00*\xca?\x80\x00\x00\x00\x00+\xe1\xafp\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\xc2\xe2\xf0\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00\x00/\xa0\x13\xe0\x00\x00\x00\x000k\x0c\xd0\x00\x00\x00\x001\x7f\xf5\xe0\x00\x00\x00\x002J\xee\xd0\x00\x00\x00\x003_\xd7\xe0\x00\x00\x00\x004*\xd0\xd0\x00\x00\x00\x005?\xb9\xe0\x00\x00\x00\x006\x0a\xb2\xd0\x00\x00\x00\x007(\xd6`\x00\x00\x00\x007\xf3\xcfP\x00\x00\x00\x009\x08\xb8`\x00\x00\x00\x009\xd3\xb1P\x00\x00\x00\x00:\xe8\x9a`\x00\x00\x00\x00;\xb3\x93P\x00\x00\x00\x00<\xc8|`\x00\x00\x00\x00=\x93uP\x00\x00\x00\x00>\xa8^`\x00\x00\x00\x00?sWP\x00\x00\x00\x00@\x91z\xe0\x00\x00\x00\x00A\x5cs\xd0\x00\x00\x00\x00Bq\x5c\xe0\x00\x00\x00\x00C<U\xd0\x00\x00\x00\x00DQ>\xe0\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F1 \xe0\x00\x00\x00\x00F\xe0jP\x00\x00\x00\x00H\x11\x02\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xf0\xe4\xe0\x00\x00\x00\x00J\x8d\xb9P\x00\x00\x00\x00K\xda\x01`\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00L\x89X\xe0\x00\x00\x00\x00L\xa4\xfaP\x00\x00\x00\x00Su8\xe0\x00\x00\x00\x00S\xac\x89\xd0\x00\x00\x00\x00S\xda\xbc`\x00\x00\x00\x00T$\x82P\x00\x00\x00\x00dJ\xf0`\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\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\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\x1dU\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\x09LMT\x00EEST\x00EET\x00\x0aEET-2EEST,M4.5.5/0,M10.5.4/24\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001B\xb0;\x7f\x07\x00\x00\x7f\x07\x00\x00\x11\x00\x00\x00Africa/CasablancaTZif2\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\xc5\x00\x00\x00\x05\x00\x00\x00\x0c\xff\xff\xff\xff\x96Q\xf9\x9c\xff\xff\xff\xff\xc6\xff\x14\x80\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xed\x80\xff\xff\xff\xff\xd2\xa12\xf0\xff\xff\xff\xff\xdb5\xa4\x00\xff\xff\xff\xff\xdb\xee'\xf0\xff\xff\xff\xff\xfb%r@\xff\xff\xff\xff\xfb\xc2\xefp\x00\x00\x00\x00\x08k\x84\x80\x00\x00\x00\x00\x08\xc6m\xf0\x00\x00\x00\x00\x0b\xe8\x0c\x00\x00\x00\x00\x00\x0caG\xf0\x00\x00\x00\x00\x0d\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00\x00\x00\x1a\xb7\xa6\x00\x00\x00\x00\x00\x1e\x18o\xf0\x00\x00\x00\x00HA\xe6\x80\x00\x00\x00\x00H\xbb\x22p\x00\x00\x00\x00J#\x1a\x00\x00\x00\x00\x00J\x8d\xd5p\x00\x00\x00\x00K\xdc\xc0\x80\x00\x00\x00\x00L]\xe5p\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00N4\x8c\xf0\x00\x00\x00\x00O\x9c\xa0\xa0\x00\x00\x00\x00P\x08\xbb\xa0\x00\x00\x00\x00P1\x9a \x00\x00\x00\x00Pg\xa7\xa0\x00\x00\x00\x00Q|\x82\xa0\x00\x00\x00\x00Q\xd8\xcb\xa0\x00\x00\x00\x00R\x05\x9e\xa0\x00\x00\x00\x00Rls\xa0\x00\x00\x00\x00S7z\xa0\x00\x00\x00\x00S\xae!\xa0\x00\x00\x00\x00S\xdcF \x00\x00\x00\x00TLU\xa0\x00\x00\x00\x00U\x17\x5c\xa0\x00\x00\x00\x00U|\xe0 \x00\x00\x00\x00U\xab\x04\xa0\x00\x00\x00\x00V,7\xa0\x00\x00\x00\x00V\xf7>\xa0\x00\x00\x00\x00WS\x87\xa0\x00\x00\x00\x00W\x81\xac \x00\x00\x00\x00X\x15T \x00\x00\x00\x00X\xd7 \xa0\x00\x00\x00\x00Y \xf4\xa0\x00\x00\x00\x00YXS\xa0\x00\x00\x00\x00Y\xf56 \x00\x00\x00\x00Z\xb7\x02\xa0\x00\x00\x00\x00Z\xf7\x9c \x00\x00\x00\x00[%\xc0\xa0\x00\x00\x00\x00[\xd5\x18 \x00\x00\x00\x00\x5c\xceC\xa0\x00\x00\x00\x00\x5c\xfch \x00\x00\x00\x00^\x9b\xb0\xa0\x00\x00\x00\x00^\xd3\x0f\xa0\x00\x00\x00\x00`rX \x00\x00\x00\x00`\xa0|\xa0\x00\x00\x00\x00b?\xc5 \x00\x00\x00\x00bw$ \x00\x00\x00\x00d\x16l\xa0\x00\x00\x00\x00dD\x91 \x00\x00\x00\x00e\xed\x14 \x00\x00\x00\x00f\x1b8\xa0\x00\x00\x00\x00g\xba\x81 \x00\x00\x00\x00g\xf1\xe0 \x00\x00\x00\x00i\x91(\xa0\x00\x00\x00\x00i\xbfM \x00\x00\x00\x00kg\xd0 \x00\x00\x00\x00k\x95\xf4\xa0\x00\x00\x00\x00m5= \x00\x00\x00\x00ml\x9c \x00\x00\x00\x00o\x0b\xe4\xa0\x00\x00\x00\x00o:\x09 \x00\x00\x00\x00p\xd9Q\xa0\x00\x00\x00\x00q\x10\xb0\xa0\x00\x00\x00\x00r\xaf\xf9 \x00\x00\x00\x00r\xde\x1d\xa0\x00\x00\x00\x00t\x86\xa0\xa0\x00\x00\x00\x00t\xb4\xc5 \x00\x00\x00\x00vT\x0d\xa0\x00\x00\x00\x00v\x8bl\xa0\x00\x00\x00\x00x*\xb5 \x00\x00\x00\x00xX\xd9\xa0\x00\x00\x00\x00y\xf8\x22 \x00\x00\x00\x00z/\x81 \x00\x00\x00\x00{\xce\xc9\xa0\x00\x00\x00\x00|\x06(\xa0\x00\x00\x00\x00}\xa5q \x00\x00\x00\x00}\xd3\x95\xa0\x00\x00\x00\x00\x7fr\xde \x00\x00\x00\x00\x7f\xaa= \x00\x00\x00\x00\x81I\x85\xa0\x00\x00\x00\x00\x81w\xaa \x00\x00\x00\x00\x83 - \x00\x00\x00\x00\x83NQ\xa0\x00\x00\x00\x00\x84\xed\x9a \x00\x00\x00\x00\x85$\xf9 \x00\x00\x00\x00\x86\xc4A\xa0\x00\x00\x00\x00\x86\xf2f \x00\x00\x00\x00\x88\x91\xae\xa0\x00\x00\x00\x00\x88\xc9\x0d\xa0\x00\x00\x00\x00\x8ahV \x00\x00\x00\x00\x8a\x9f\xb5 \x00\x00\x00\x00\x8c>\xfd\xa0\x00\x00\x00\x00\x8cm\x22 \x00\x00\x00\x00\x8e\x0cj\xa0\x00\x00\x00\x00\x8eC\xc9\xa0\x00\x00\x00\x00\x8f\xe3\x12 \x00\x00\x00\x00\x90\x116\xa0\x00\x00\x00\x00\x91\xb9\xb9\xa0\x00\x00\x00\x00\x91\xe7\xde \x00\x00\x00\x00\x93\x87&\xa0\x00\x00\x00\x00\x93\xbe\x85\xa0\x00\x00\x00\x00\x95]\xce \x00\x00\x00\x00\x95\x8b\xf2\xa0\x00\x00\x00\x00\x97+; \x00\x00\x00\x00\x97b\x9a \x00\x00\x00\x00\x99\x01\xe2\xa0\x00\x00\x00\x00\x999A\xa0\x00\x00\x00\x00\x9a\xd8\x8a \x00\x00\x00\x00\x9b\x06\xae\xa0\x00\x00\x00\x00\x9c\xa5\xf7 \x00\x00\x00\x00\x9c\xddV \x00\x00\x00\x00\x9e|\x9e\xa0\x00\x00\x00\x00\x9e\xaa\xc3 \x00\x00\x00\x00\xa0SF \x00\x00\x00\x00\xa0\x81j\xa0\x00\x00\x00\x00\xa2 \xb3 \x00\x00\x00\x00\xa2X\x12 \x00\x00\x00\x00\xa3\xf7Z\xa0\x00\x00\x00\x00\xa4%\x7f \x00\x00\x00\x00\xa5\xc4\xc7\xa0\x00\x00\x00\x00\xa5\xfc&\xa0\x00\x00\x00\x00\xa7\x9bo \x00\x00\x00\x00\xa7\xd2\xce \x00\x00\x00\x00\xa9r\x16\xa0\x00\x00\x00\x00\xa9\xa0; \x00\x00\x00\x00\xab?\x83\xa0\x00\x00\x00\x00\xabv\xe2\xa0\x00\x00\x00\x00\xad\x16+ \x00\x00\x00\x00\xadDO\xa0\x00\x00\x00\x00\xae\xec\xd2\xa0\x00\x00\x00\x00\xaf\x1a\xf7 \x00\x00\x00\x00\xb0\xba?\xa0\x00\x00\x00\x00\xb0\xf1\x9e\xa0\x00\x00\x00\x00\xb2\x90\xe7 \x00\x00\x00\x00\xb2\xbf\x0b\xa0\x00\x00\x00\x00\xb4^T \x00\x00\x00\x00\xb4\x95\xb3 \x00\x00\x00\x00\xb64\xfb\xa0\x00\x00\x00\x00\xb6lZ\xa0\x00\x00\x00\x00\xb8\x0b\xa3 \x00\x00\x00\x00\xb89\xc7\xa0\x00\x00\x00\x00\xb9\xd9\x10 \x00\x00\x00\x00\xba\x10o \x00\x00\x00\x00\xbb\xaf\xb7\xa0\x00\x00\x00\x00\xbb\xdd\xdc \x00\x00\x00\x00\xbd\x86_ \x00\x00\x00\x00\xbd\xb4\x83\xa0\x00\x00\x00\x00\xbfS\xcc \x00\x00\x00\x00\xbf\x8b+ \x00\x00\x00\x00\xc1*s\xa0\x00\x00\x00\x00\xc1X\x98 \x00\x00\x00\x00\xc2\xf7\xe0\xa0\x00\x00\x00\x00\xc3/?\xa0\x00\x00\x00\x00\xc4\xce\x88 \x00\x00\x00\x00\xc5\x05\xe7 \x00\x00\x00\x00\xc6\xa5/\xa0\x00\x00\x00\x00\xc6\xd3T \x00\x00\x00\x00\xc8r\x9c\xa0\x00\x00\x00\x00\xc8\xa9\xfb\xa0\x00\x00\x00\x00\xcaID \x00\x00\x00\x00\xcawh\xa0\x00\x00\x00\x00\xcc\x1f\xeb\xa0\x00\x00\x00\x00\xccN\x10 \x00\x00\x00\x00\xcd\xedX\xa0\x00\x00\x00\x00\xce$\xb7\xa0\x00\x00\x00\x00\xcf\xc4\x00 \x00\x00\x00\x00\xcf\xf2$\xa0\x00\x00\x00\x00\xd1\x91m \x00\x00\x00\x00\xd1\xc8\xcc \x00\x00\x00\x00\xd3h\x14\xa0\x00\x00\x00\x00\xd3\x969 \x00\x00\x00\x00\xd5>\xbc \x00\x00\x00\x00\xd5l\xe0\xa0\x00\x00\x00\x00\xd7\x0c) \x00\x00\x00\x00\xd7C\x88 \x00\x00\x00\x00\xd8\xe2\xd0\xa0\x00\x00\x00\x00\xd9\x10\xf5 \x00\x00\x00\x00\xda\xb9x \x00\x00\x00\x00\xda\xe7\x9c\xa0\x00\x00\x00\x00\xdc\x86\xe5 \x00\x00\x00\x00\xdc\xbeD \x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\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\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\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\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\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\xff\xff\xf8\xe4\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\x08\x00\x00\x0e\x10\x00\x04\x00\x00\x00\x00\x01\x08LMT\x00+01\x00+00\x00\x0a<+01>-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x1b\xeb\xdd2\x02\x00\x002\x02\x00\x00\x0c\x00\x00\x00Africa/CeutaTZif2\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\x05\x00\x00\x00\x16\xff\xff\xff\xff~6\xb5\x00\xff\xff\xff\xff\x9e\xd6up\xff\xff\xff\xff\x9f\xa1n`\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xe7n\x00\xff\xff\xff\xff\xad\xc9\xa7\xf0\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff\xfb%r@\xff\xff\xff\xff\xfb\xc2\xefp\x00\x00\x00\x00\x08k\x84\x80\x00\x00\x00\x00\x08\xc6m\xf0\x00\x00\x00\x00\x0b\xe8\x0c\x00\x00\x00\x00\x00\x0caG\xf0\x00\x00\x00\x00\x0d\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00\x00\x00\x1a\xb7\xa6\x00\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xff\xfb\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\x08\x00\x00\x0e\x10\x00\x0d\x00\x00\x1c \x01\x11LMT\x00WET\x00WEST\x00CET\x00CEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x00\x00Africa/ConakryTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0c\x00\x00\x00Africa/DakarTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x14\x00\x00\x00Africa/Dar_es_SalaamTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\x22\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\x0a\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\x0aEAT-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0f\x00\x00\x00Africa/DjiboutiTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\x22\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\x0a\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\x0aEAT-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0d\x00\x00\x00Africa/DoualaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x07\x08\x00\x08\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\x0aWAT-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xd3\xc6g&\x07\x00\x00&\x07\x00\x00\x0f\x00\x00\x00Africa/El_AaiunTZif2\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\xba\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xbcH\xf0\xe0\x00\x00\x00\x00\x0b\xd1\xb0\x90\x00\x00\x00\x00\x0b\xe8\x0c\x00\x00\x00\x00\x00\x0caG\xf0\x00\x00\x00\x00\x0d\xc9?\x80\x00\x00\x00\x00\x0e\x8e\xf2p\x00\x00\x00\x00\x0f\xd3Q\x80\x00\x00\x00\x00\x10'\xa3p\x00\x00\x00\x00HA\xe6\x80\x00\x00\x00\x00H\xbb\x22p\x00\x00\x00\x00J#\x1a\x00\x00\x00\x00\x00J\x8d\xd5p\x00\x00\x00\x00K\xdc\xc0\x80\x00\x00\x00\x00L]\xe5p\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00N4\x8c\xf0\x00\x00\x00\x00O\x9c\xa0\xa0\x00\x00\x00\x00P\x08\xbb\xa0\x00\x00\x00\x00P1\x9a \x00\x00\x00\x00Pg\xa7\xa0\x00\x00\x00\x00Q|\x82\xa0\x00\x00\x00\x00Q\xd8\xcb\xa0\x00\x00\x00\x00R\x05\x9e\xa0\x00\x00\x00\x00Rls\xa0\x00\x00\x00\x00S7z\xa0\x00\x00\x00\x00S\xae!\xa0\x00\x00\x00\x00S\xdcF \x00\x00\x00\x00TLU\xa0\x00\x00\x00\x00U\x17\x5c\xa0\x00\x00\x00\x00U|\xe0 \x00\x00\x00\x00U\xab\x04\xa0\x00\x00\x00\x00V,7\xa0\x00\x00\x00\x00V\xf7>\xa0\x00\x00\x00\x00WS\x87\xa0\x00\x00\x00\x00W\x81\xac \x00\x00\x00\x00X\x15T \x00\x00\x00\x00X\xd7 \xa0\x00\x00\x00\x00Y \xf4\xa0\x00\x00\x00\x00YXS\xa0\x00\x00\x00\x00Y\xf56 \x00\x00\x00\x00Z\xb7\x02\xa0\x00\x00\x00\x00Z\xf7\x9c \x00\x00\x00\x00[%\xc0\xa0\x00\x00\x00\x00[\xd5\x18 \x00\x00\x00\x00\x5c\xceC\xa0\x00\x00\x00\x00\x5c\xfch \x00\x00\x00\x00^\x9b\xb0\xa0\x00\x00\x00\x00^\xd3\x0f\xa0\x00\x00\x00\x00`rX \x00\x00\x00\x00`\xa0|\xa0\x00\x00\x00\x00b?\xc5 \x00\x00\x00\x00bw$ \x00\x00\x00\x00d\x16l\xa0\x00\x00\x00\x00dD\x91 \x00\x00\x00\x00e\xed\x14 \x00\x00\x00\x00f\x1b8\xa0\x00\x00\x00\x00g\xba\x81 \x00\x00\x00\x00g\xf1\xe0 \x00\x00\x00\x00i\x91(\xa0\x00\x00\x00\x00i\xbfM \x00\x00\x00\x00kg\xd0 \x00\x00\x00\x00k\x95\xf4\xa0\x00\x00\x00\x00m5= \x00\x00\x00\x00ml\x9c \x00\x00\x00\x00o\x0b\xe4\xa0\x00\x00\x00\x00o:\x09 \x00\x00\x00\x00p\xd9Q\xa0\x00\x00\x00\x00q\x10\xb0\xa0\x00\x00\x00\x00r\xaf\xf9 \x00\x00\x00\x00r\xde\x1d\xa0\x00\x00\x00\x00t\x86\xa0\xa0\x00\x00\x00\x00t\xb4\xc5 \x00\x00\x00\x00vT\x0d\xa0\x00\x00\x00\x00v\x8bl\xa0\x00\x00\x00\x00x*\xb5 \x00\x00\x00\x00xX\xd9\xa0\x00\x00\x00\x00y\xf8\x22 \x00\x00\x00\x00z/\x81 \x00\x00\x00\x00{\xce\xc9\xa0\x00\x00\x00\x00|\x06(\xa0\x00\x00\x00\x00}\xa5q \x00\x00\x00\x00}\xd3\x95\xa0\x00\x00\x00\x00\x7fr\xde \x00\x00\x00\x00\x7f\xaa= \x00\x00\x00\x00\x81I\x85\xa0\x00\x00\x00\x00\x81w\xaa \x00\x00\x00\x00\x83 - \x00\x00\x00\x00\x83NQ\xa0\x00\x00\x00\x00\x84\xed\x9a \x00\x00\x00\x00\x85$\xf9 \x00\x00\x00\x00\x86\xc4A\xa0\x00\x00\x00\x00\x86\xf2f \x00\x00\x00\x00\x88\x91\xae\xa0\x00\x00\x00\x00\x88\xc9\x0d\xa0\x00\x00\x00\x00\x8ahV \x00\x00\x00\x00\x8a\x9f\xb5 \x00\x00\x00\x00\x8c>\xfd\xa0\x00\x00\x00\x00\x8cm\x22 \x00\x00\x00\x00\x8e\x0cj\xa0\x00\x00\x00\x00\x8eC\xc9\xa0\x00\x00\x00\x00\x8f\xe3\x12 \x00\x00\x00\x00\x90\x116\xa0\x00\x00\x00\x00\x91\xb9\xb9\xa0\x00\x00\x00\x00\x91\xe7\xde \x00\x00\x00\x00\x93\x87&\xa0\x00\x00\x00\x00\x93\xbe\x85\xa0\x00\x00\x00\x00\x95]\xce \x00\x00\x00\x00\x95\x8b\xf2\xa0\x00\x00\x00\x00\x97+; \x00\x00\x00\x00\x97b\x9a \x00\x00\x00\x00\x99\x01\xe2\xa0\x00\x00\x00\x00\x999A\xa0\x00\x00\x00\x00\x9a\xd8\x8a \x00\x00\x00\x00\x9b\x06\xae\xa0\x00\x00\x00\x00\x9c\xa5\xf7 \x00\x00\x00\x00\x9c\xddV \x00\x00\x00\x00\x9e|\x9e\xa0\x00\x00\x00\x00\x9e\xaa\xc3 \x00\x00\x00\x00\xa0SF \x00\x00\x00\x00\xa0\x81j\xa0\x00\x00\x00\x00\xa2 \xb3 \x00\x00\x00\x00\xa2X\x12 \x00\x00\x00\x00\xa3\xf7Z\xa0\x00\x00\x00\x00\xa4%\x7f \x00\x00\x00\x00\xa5\xc4\xc7\xa0\x00\x00\x00\x00\xa5\xfc&\xa0\x00\x00\x00\x00\xa7\x9bo \x00\x00\x00\x00\xa7\xd2\xce \x00\x00\x00\x00\xa9r\x16\xa0\x00\x00\x00\x00\xa9\xa0; \x00\x00\x00\x00\xab?\x83\xa0\x00\x00\x00\x00\xabv\xe2\xa0\x00\x00\x00\x00\xad\x16+ \x00\x00\x00\x00\xadDO\xa0\x00\x00\x00\x00\xae\xec\xd2\xa0\x00\x00\x00\x00\xaf\x1a\xf7 \x00\x00\x00\x00\xb0\xba?\xa0\x00\x00\x00\x00\xb0\xf1\x9e\xa0\x00\x00\x00\x00\xb2\x90\xe7 \x00\x00\x00\x00\xb2\xbf\x0b\xa0\x00\x00\x00\x00\xb4^T \x00\x00\x00\x00\xb4\x95\xb3 \x00\x00\x00\x00\xb64\xfb\xa0\x00\x00\x00\x00\xb6lZ\xa0\x00\x00\x00\x00\xb8\x0b\xa3 \x00\x00\x00\x00\xb89\xc7\xa0\x00\x00\x00\x00\xb9\xd9\x10 \x00\x00\x00\x00\xba\x10o \x00\x00\x00\x00\xbb\xaf\xb7\xa0\x00\x00\x00\x00\xbb\xdd\xdc \x00\x00\x00\x00\xbd\x86_ \x00\x00\x00\x00\xbd\xb4\x83\xa0\x00\x00\x00\x00\xbfS\xcc \x00\x00\x00\x00\xbf\x8b+ \x00\x00\x00\x00\xc1*s\xa0\x00\x00\x00\x00\xc1X\x98 \x00\x00\x00\x00\xc2\xf7\xe0\xa0\x00\x00\x00\x00\xc3/?\xa0\x00\x00\x00\x00\xc4\xce\x88 \x00\x00\x00\x00\xc5\x05\xe7 \x00\x00\x00\x00\xc6\xa5/\xa0\x00\x00\x00\x00\xc6\xd3T \x00\x00\x00\x00\xc8r\x9c\xa0\x00\x00\x00\x00\xc8\xa9\xfb\xa0\x00\x00\x00\x00\xcaID \x00\x00\x00\x00\xcawh\xa0\x00\x00\x00\x00\xcc\x1f\xeb\xa0\x00\x00\x00\x00\xccN\x10 \x00\x00\x00\x00\xcd\xedX\xa0\x00\x00\x00\x00\xce$\xb7\xa0\x00\x00\x00\x00\xcf\xc4\x00 \x00\x00\x00\x00\xcf\xf2$\xa0\x00\x00\x00\x00\xd1\x91m \x00\x00\x00\x00\xd1\xc8\xcc \x00\x00\x00\x00\xd3h\x14\xa0\x00\x00\x00\x00\xd3\x969 \x00\x00\x00\x00\xd5>\xbc \x00\x00\x00\x00\xd5l\xe0\xa0\x00\x00\x00\x00\xd7\x0c) \x00\x00\x00\x00\xd7C\x88 \x00\x00\x00\x00\xd8\xe2\xd0\xa0\x00\x00\x00\x00\xd9\x10\xf5 \x00\x00\x00\x00\xda\xb9x \x00\x00\x00\x00\xda\xe7\x9c\xa0\x00\x00\x00\x00\xdc\x86\xe5 \x00\x00\x00\x00\xdc\xbeD \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\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\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\xff\xff\xf3\xa0\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x0e\x10\x01\x08\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x01\x0c\x00\x00\x0e\x10\x00\x08LMT\x00-01\x00+01\x00+00\x00\x0a<+01>-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x00\x00Africa/FreetownTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x00\x00Africa/GaboroneTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\x0aCAT-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0d\x00\x00\x00Africa/HarareTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\x0aCAT-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\x0cT\xce\xbe\x00\x00\x00\xbe\x00\x00\x00\x13\x00\x00\x00Africa/JohannesburgTZif2\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\x06\x00\x00\x00\x04\x00\x00\x00\x09\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff\xcc\xae\x8c\x80\xff\xff\xff\xff\xcd\x9eop\xff\xff\xff\xff\xce\x8en\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00\x0aSAST-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xcf\x10n\xca\x01\x00\x00\xca\x01\x00\x00\x0b\x00\x00\x00Africa/JubaTZif2\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\x11\xff\xff\xff\xff\xb6\xa3\xda\xdc\x00\x00\x00\x00\x00\x9e\x17\xe0\x00\x00\x00\x00\x01z4P\x00\x00\x00\x00\x02}\xf9\xe0\x00\x00\x00\x00\x03[g\xd0\x00\x00\x00\x00\x04`~\xe0\x00\x00\x00\x00\x05=\xec\xd0\x00\x00\x00\x00\x06@`\xe0\x00\x00\x00\x00\x07\x1f P\x00\x00\x00\x00\x08 B\xe0\x00\x00\x00\x00\x09\x00S\xd0\x00\x00\x00\x00\x0a\x00$\xe0\x00\x00\x00\x00\x0a\xe1\x87P\x00\x00\x00\x00\x0b\xe0\x06\xe0\x00\x00\x00\x00\x0c\xc4\x0cP\x00\x00\x00\x00\x0d\xbf\xe8\xe0\x00\x00\x00\x00\x0e\xa5?\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10\x86sP\x00\x00\x00\x00\x11\x88\xe7`\x00\x00\x00\x00\x12g\xa6\xd0\x00\x00\x00\x00\x13h\xc9`\x00\x00\x00\x00\x14J+\xd0\x00\x00\x00\x00\x15H\xab`\x00\x00\x00\x00\x16+_P\x00\x00\x00\x00\x17(\x8d`\x00\x00\x00\x00\x18\x0c\x92\xd0\x00\x00\x00\x00\x19\x08o`\x00\x00\x00\x00\x19\xed\xc6P\x00\x00\x00\x00\x1a\xf1\x8b\xe0\x00\x00\x00\x00\x1b\xd0KP\x00\x00\x00\x00\x1c\xd1m\xe0\x00\x00\x00\x00\x1d\xb1~\xd0\x00\x00\x00\x008\x80E \x00\x00\x00\x00`\x17\x1aP\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\x03\x02\x00\x00\x1d\xa4\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\x09\x00\x00*0\x00\x0dLMT\x00CAST\x00CAT\x00EAT\x00\x0aCAT-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00Africa/KampalaTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\x22\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\x0a\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\x0aEAT-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xadD\xef\xca\x01\x00\x00\xca\x01\x00\x00\x0f\x00\x00\x00Africa/KhartoumTZif2\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\x11\xff\xff\xff\xff\xb6\xa3\xda\x00\x00\x00\x00\x00\x00\x9e\x17\xe0\x00\x00\x00\x00\x01z4P\x00\x00\x00\x00\x02}\xf9\xe0\x00\x00\x00\x00\x03[g\xd0\x00\x00\x00\x00\x04`~\xe0\x00\x00\x00\x00\x05=\xec\xd0\x00\x00\x00\x00\x06@`\xe0\x00\x00\x00\x00\x07\x1f P\x00\x00\x00\x00\x08 B\xe0\x00\x00\x00\x00\x09\x00S\xd0\x00\x00\x00\x00\x0a\x00$\xe0\x00\x00\x00\x00\x0a\xe1\x87P\x00\x00\x00\x00\x0b\xe0\x06\xe0\x00\x00\x00\x00\x0c\xc4\x0cP\x00\x00\x00\x00\x0d\xbf\xe8\xe0\x00\x00\x00\x00\x0e\xa5?\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10\x86sP\x00\x00\x00\x00\x11\x88\xe7`\x00\x00\x00\x00\x12g\xa6\xd0\x00\x00\x00\x00\x13h\xc9`\x00\x00\x00\x00\x14J+\xd0\x00\x00\x00\x00\x15H\xab`\x00\x00\x00\x00\x16+_P\x00\x00\x00\x00\x17(\x8d`\x00\x00\x00\x00\x18\x0c\x92\xd0\x00\x00\x00\x00\x19\x08o`\x00\x00\x00\x00\x19\xed\xc6P\x00\x00\x00\x00\x1a\xf1\x8b\xe0\x00\x00\x00\x00\x1b\xd0KP\x00\x00\x00\x00\x1c\xd1m\xe0\x00\x00\x00\x00\x1d\xb1~\xd0\x00\x00\x00\x008\x80E \x00\x00\x00\x00Y\xf8\xe4P\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\x03\x02\x00\x00\x1e\x80\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\x09\x00\x00*0\x00\x0dLMT\x00CAST\x00CAT\x00EAT\x00\x0aCAT-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0d\x00\x00\x00Africa/KigaliTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\x0aCAT-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0f\x00\x00\x00Africa/KinshasaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x07\x08\x00\x08\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\x0aWAT-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0c\x00\x00\x00Africa/LagosTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x07\x08\x00\x08\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\x0aWAT-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x00\x00Africa/LibrevilleTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x07\x08\x00\x08\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\x0aWAT-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0b\x00\x00\x00Africa/LomeTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0d\x00\x00\x00Africa/LuandaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x07\x08\x00\x08\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\x0aWAT-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x11\x00\x00\x00Africa/LubumbashiTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\x0aCAT-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0d\x00\x00\x00Africa/LusakaTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\x0aCAT-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0d\x00\x00\x00Africa/MalaboTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x07\x08\x00\x08\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\x0aWAT-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0d\x00\x00\x00Africa/MaputoTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x82F\xc5\xf4\x01\x00\x00\x1e\x8c\x00\x00\x00\x00\x1c \x00\x04LMT\x00CAT\x00\x0aCAT-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\x0cT\xce\xbe\x00\x00\x00\xbe\x00\x00\x00\x0d\x00\x00\x00Africa/MaseruTZif2\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\x06\x00\x00\x00\x04\x00\x00\x00\x09\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff\xcc\xae\x8c\x80\xff\xff\xff\xff\xcd\x9eop\xff\xff\xff\xff\xce\x8en\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00\x0aSAST-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\x0cT\xce\xbe\x00\x00\x00\xbe\x00\x00\x00\x0e\x00\x00\x00Africa/MbabaneTZif2\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\x06\x00\x00\x00\x04\x00\x00\x00\x09\xff\xff\xff\xffm{A@\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff\xcc\xae\x8c\x80\xff\xff\xff\xff\xcd\x9eop\xff\xff\xff\xff\xce\x8en\x80\xff\xff\xff\xff\xcf~Qp\x01\x03\x02\x03\x02\x03\x00\x00\x1a@\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00*0\x01\x04\x00\x00\x1c \x00\x04LMT\x00SAST\x00\x0aSAST-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x10\x00\x00\x00Africa/MogadishuTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\x22\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\x0a\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\x0aEAT-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\x99rU\xa4\x00\x00\x00\xa4\x00\x00\x00\x0f\x00\x00\x00Africa/MonroviaTZif2\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\x03\x00\x00\x00\x04\x00\x00\x00\x0c\xff\xff\xff\xffZz\xa6\x9c\xff\xff\xff\xff\xa0_l\x9c\x00\x00\x00\x00\x03\xcaZn\x01\x02\x03\xff\xff\xf5\xe4\x00\x00\xff\xff\xf5\xe4\x00\x04\xff\xff\xf5\x92\x00\x04\x00\x00\x00\x00\x00\x08LMT\x00MMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00Africa/NairobiTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\x22\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\x0a\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\x0aEAT-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x81\x09\x03\xa0\x00\x00\x00\xa0\x00\x00\x00\x0f\x00\x00\x00Africa/NdjamenaTZif2\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\x03\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xff\x92\xe6\x80d\x00\x00\x00\x00\x12fqp\x00\x00\x00\x00\x13&\xde`\x01\x02\x01\x00\x00\x0e\x1c\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\x08LMT\x00WAT\x00WAST\x00\x0aWAT-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0d\x00\x00\x00Africa/NiameyTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x07\x08\x00\x08\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\x0aWAT-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x11\x00\x00\x00Africa/NouakchottTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00Africa/OuagadougouTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x00\x00Africa/Porto-NovoTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x86\xabp\xd1\xff\xff\xff\xff\x8cP`\x00\xff\xff\xff\xff\x96\xaaC\xd1\xff\xff\xff\xff\xa1Q\xefx\x01\x00\x02\x03\x00\x00\x03/\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x07\x08\x00\x08\x00\x00\x0e\x10\x00\x0eLMT\x00GMT\x00+0030\x00WAT\x00\x0aWAT-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\x0a\x8a\x84\xad\x00\x00\x00\xad\x00\x00\x00\x0f\x00\x00\x00Africa/Sao_TomeTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x0c\xff\xff\xff\xff^<\xfd0\xff\xff\xff\xff\x92\xe6\x8e\x80\x00\x00\x00\x00ZI\x88\x10\x00\x00\x00\x00\x5c*\xbb\x90\x01\x02\x03\x02\x00\x00\x06P\x00\x00\xff\xff\xf7c\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\x08LMT\x00GMT\x00WAT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x00\x00Africa/TimbuktuTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x0e\x00\x00\x00Africa/TripoliTZif2\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\x11\xff\xff\xff\xff\xa1\xf2\xc1$\xff\xff\xff\xff\xdd\xbb\xb1\x10\xff\xff\xff\xff\xde#\xad`\xff\xff\xff\xff\xe1x\xd2\x10\xff\xff\xff\xff\xe1\xe7e\xe0\xff\xff\xff\xff\xe5/?p\xff\xff\xff\xff\xe5\xa9\xcc\xe0\xff\xff\xff\xff\xebN\xc6\xf0\x00\x00\x00\x00\x16\x92B`\x00\x00\x00\x00\x17\x08\xf7p\x00\x00\x00\x00\x17\xfa+\xe0\x00\x00\x00\x00\x18\xea*\xf0\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a\xcc\xaf\xf0\x00\x00\x00\x00\x1b\xbd\xe4`\x00\x00\x00\x00\x1c\xb4z\xf0\x00\x00\x00\x00\x1d\x9f\x17\xe0\x00\x00\x00\x00\x1e\x93\x0bp\x00\x00\x00\x00\x1f\x82\xee`\x00\x00\x00\x00 pJp\x00\x00\x00\x00!a~\xe0\x00\x00\x00\x00\x22R\xcfp\x00\x00\x00\x00#D\x03\xe0\x00\x00\x00\x00$4\x02\xf0\x00\x00\x00\x00%%7`\x00\x00\x00\x00&@\xb7\xf0\x00\x00\x00\x002N\xf1`\x00\x00\x00\x003D6p\x00\x00\x00\x0045j\xe0\x00\x00\x00\x00P\x9d\x99\x00\x00\x00\x00\x00QT\xd9\x80\x00\x00\x00\x00Ri\xb4\x80\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x03\x02\x01\x03\x00\x00\x0c\x5c\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\x09\x00\x00\x1c \x00\x0dLMT\x00CEST\x00CET\x00EET\x00\x0aEET-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\xf4\x94\x0b\xc1\x01\x00\x00\xc1\x01\x00\x00\x0c\x00\x00\x00Africa/TunisTZif2\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\x22\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffYF\x13\xf4\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\xc6:\x88\xe0\xff\xff\xff\xff\xc7X\x9e`\xff\xff\xff\xff\xc7\xdb\x22\xe0\xff\xff\xff\xff\xca\xe2T\xe0\xff\xff\xff\xff\xcb\xadi\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xcd\xc2\x16\x00\xff\xff\xff\xff\xcd\xcc\xb0\x10\xff\xff\xff\xff\xce\xa25\x00\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x89\xe3\xe0\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N\x16`\x00\x00\x00\x00\x0d\xc7\xdf\xf0\x00\x00\x00\x00\x0e\x89\xacp\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x22\xa3:\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&<\xc3p\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00Bt\x0d\xf0\x00\x00\x00\x00C<\x80\x00\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05\xc9\x90\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x09\x8c\x00\x00\x00\x00\x021\x00\x04\x00\x00\x1c \x01\x08\x00\x00\x0e\x10\x00\x0dLMT\x00PMT\x00CEST\x00CET\x00\x0aCET-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m)\xb8P~\x02\x00\x00~\x02\x00\x00\x0f\x00\x00\x00Africa/WindhoekTZif2\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\x005\x00\x00\x00\x06\x00\x00\x00\x17\xff\xff\xff\xffm{Kx\xff\xff\xff\xff\x82F\xcfh\xff\xff\xff\xff\xcc\xae\x8c\x80\xff\xff\xff\xff\xcd\x9eop\x00\x00\x00\x00&\x06\xa7\xe0\x00\x00\x00\x00-\x8c\xc7`\x00\x00\x00\x00.i\x1c\x10\x00\x00\x00\x00/}\xe9\x00\x00\x00\x00\x000H\xfe\x10\x00\x00\x00\x001g\x05\x80\x00\x00\x00\x002(\xe0\x10\x00\x00\x00\x003F\xe7\x80\x00\x00\x00\x004\x11\xfc\x90\x00\x00\x00\x005&\xc9\x80\x00\x00\x00\x005\xf1\xde\x90\x00\x00\x00\x007\x06\xab\x80\x00\x00\x00\x007\xd1\xc0\x90\x00\x00\x00\x008\xe6\x8d\x80\x00\x00\x00\x009\xb1\xa2\x90\x00\x00\x00\x00:\xc6o\x80\x00\x00\x00\x00;\x91\x84\x90\x00\x00\x00\x00<\xaf\x8c\x00\x00\x00\x00\x00=qf\x90\x00\x00\x00\x00>\x8fn\x00\x00\x00\x00\x00?Z\x83\x10\x00\x00\x00\x00@oP\x00\x00\x00\x00\x00A:e\x10\x00\x00\x00\x00BO2\x00\x00\x00\x00\x00C\x1aG\x10\x00\x00\x00\x00D/\x14\x00\x00\x00\x00\x00D\xfa)\x10\x00\x00\x00\x00F\x0e\xf6\x00\x00\x00\x00\x00F\xda\x0b\x10\x00\x00\x00\x00G\xf8\x12\x80\x00\x00\x00\x00H\xc3'\x90\x00\x00\x00\x00I\xd7\xf4\x80\x00\x00\x00\x00J\xa3\x09\x90\x00\x00\x00\x00K\xb7\xd6\x80\x00\x00\x00\x00L\x82\xeb\x90\x00\x00\x00\x00M\x97\xb8\x80\x00\x00\x00\x00Nb\xcd\x90\x00\x00\x00\x00Ow\x9a\x80\x00\x00\x00\x00PB\xaf\x90\x00\x00\x00\x00Q`\xb7\x00\x00\x00\x00\x00R\x22\x91\x90\x00\x00\x00\x00S@\x99\x00\x00\x00\x00\x00T\x0b\xae\x10\x00\x00\x00\x00U {\x00\x00\x00\x00\x00U\xeb\x90\x10\x00\x00\x00\x00W\x00]\x00\x00\x00\x00\x00W\xcbr\x10\x00\x00\x00\x00X\xe0?\x00\x00\x00\x00\x00Y\xabT\x10\x01\x02\x03\x02\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\x00\x00\x10\x08\x00\x00\x00\x00\x15\x18\x00\x04\x00\x00\x1c \x00\x0a\x00\x00*0\x01\x0a\x00\x00\x0e\x10\x01\x0f\x00\x00\x1c \x00\x13LMT\x00+0130\x00SAST\x00WAT\x00CAT\x00\x0aCAT-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\x0c\x00\x00\x00America/AdakTZif2\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\x00T\x00\x00\x00\x0a\x00\x00\x00!\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87Z^\xff\xff\xff\xff\xcb\x89D\xd0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\x071\x16\xc0\x00\x00\x00\x00\x07\x8dm\xd0\x00\x00\x00\x00\x09\x10\xf8\xc0\x00\x00\x00\x00\x09\xad\xe9P\x00\x00\x00\x00\x0a\xf0\xda\xc0\x00\x00\x00\x00\x0b\xe0\xd9\xd0\x00\x00\x00\x00\x0c\xd9\xf7@\x00\x00\x00\x00\x0d\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00\x18\x22}\xc0\x00\x00\x00\x00\x19\x09BP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\x22 \x00\x00\x00\x00\x1a\xf2P\xc0\x00\x00\x00\x00\x1b\xe23\xb0\x00\x00\x00\x00\x1c\xd22\xc0\x00\x00\x00\x00\x1d\xc2\x15\xb0\x00\x00\x00\x00\x1e\xb2\x14\xc0\x00\x00\x00\x00\x1f\xa1\xf7\xb0\x00\x00\x00\x00 vG@\x00\x00\x00\x00!\x81\xd9\xb0\x00\x00\x00\x00\x22V)@\x00\x00\x00\x00#j\xf60\x00\x00\x00\x00$6\x0b@\x00\x00\x00\x00%J\xd80\x00\x00\x00\x00&\x15\xed@\x00\x00\x00\x00'*\xba0\x00\x00\x00\x00'\xff\x09\xc0\x00\x00\x00\x00)\x0a\x9c0\x00\x00\x00\x00)\xde\xeb\xc0\x00\x00\x00\x00*\xea~0\x00\x00\x00\x00+\xbe\xcd\xc0\x00\x00\x00\x00,\xd3\x9a\xb0\x00\x00\x00\x00-\x9e\xaf\xc0\x00\x00\x00\x00.\xb3|\xb0\x00\x00\x00\x00/~\x91\xc0\x00\x00\x00\x000\x93^\xb0\x00\x00\x00\x001g\xae@\x00\x00\x00\x002s@\xb0\x00\x00\x00\x003G\x90@\x00\x00\x00\x004S\x22\xb0\x00\x00\x00\x005'r@\x00\x00\x00\x0063\x04\xb0\x00\x00\x00\x007\x07T@\x00\x00\x00\x008\x1c!0\x00\x00\x00\x008\xe76@\x00\x00\x00\x009\xfc\x030\x00\x00\x00\x00:\xc7\x18@\x00\x00\x00\x00;\xdb\xe50\x00\x00\x00\x00<\xb04\xc0\x00\x00\x00\x00=\xbb\xc70\x00\x00\x00\x00>\x90\x16\xc0\x00\x00\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84\xc5\xb0\x00\x00\x00\x00BO\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x07\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x00\x00\xab\xe2\x00\x00\xff\xffZb\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\x08\xff\xffs`\x01\x0c\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xffs`\x00\x18\xff\xff\x81p\x01\x1d\xff\xffs`\x00\x19LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00AHST\x00HDT\x00\x0aHST10HDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\x11\x00\x00\x00America/AnchorageTZif2\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\x00T\x00\x00\x00\x0a\x00\x00\x00(\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87AH\xff\xff\xff\xff\xcb\x896\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aB0\xff\xff\xff\xff\xfa\xd2G\xa0\xff\xff\xff\xff\xfe\xb8c@\xff\xff\xff\xff\xff\xa8F0\x00\x00\x00\x00\x00\x98E@\x00\x00\x00\x00\x01\x88(0\x00\x00\x00\x00\x02x'@\x00\x00\x00\x00\x03qD\xb0\x00\x00\x00\x00\x04aC\xc0\x00\x00\x00\x00\x05Q&\xb0\x00\x00\x00\x00\x06A%\xc0\x00\x00\x00\x00\x071\x08\xb0\x00\x00\x00\x00\x07\x8d_\xc0\x00\x00\x00\x00\x09\x10\xea\xb0\x00\x00\x00\x00\x09\xad\xdb@\x00\x00\x00\x00\x0a\xf0\xcc\xb0\x00\x00\x00\x00\x0b\xe0\xcb\xc0\x00\x00\x00\x00\x0c\xd9\xe90\x00\x00\x00\x00\x0d\xc0\xad\xc0\x00\x00\x00\x00\x0e\xb9\xcb0\x00\x00\x00\x00\x0f\xa9\xca@\x00\x00\x00\x00\x10\x99\xad0\x00\x00\x00\x00\x11\x89\xac@\x00\x00\x00\x00\x12y\x8f0\x00\x00\x00\x00\x13i\x8e@\x00\x00\x00\x00\x14Yq0\x00\x00\x00\x00\x15Ip@\x00\x00\x00\x00\x169S0\x00\x00\x00\x00\x17)R@\x00\x00\x00\x00\x18\x22o\xb0\x00\x00\x00\x00\x19\x094@\x00\x00\x00\x00\x1a\x02Q\xb0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\x07\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81\xcb\xa0\x00\x00\x00\x00\x22V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\x0a\x8e \x00\x00\x00\x00)\xde\xdd\xb0\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,\xd3\x8c\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\x07F0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\x0a0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\x08\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO\xcc\xb0\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x07\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x00\x00\xc4\xf8\x00\x00\xff\xffsx\x00\x00\xff\xffs`\x00\x04\xff\xff\x81p\x01\x08\xff\xff\x81p\x01\x0c\xff\xffs`\x00\x10\xff\xff\x81p\x01\x15\xff\xff\x81p\x00\x1a\xff\xff\x8f\x80\x01\x1e\xff\xff\x81p\x00#LMT\x00AST\x00AWT\x00APT\x00AHST\x00AHDT\x00YST\x00AKDT\x00AKST\x00\x0aAKST9AKDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00America/AnguillaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America/AntiguaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x01V\x0dP\x02\x00\x00P\x02\x00\x00\x11\x00\x00\x00America/AraguainaTZif2\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\x003\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaat0\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xff\xdc\xb9Y \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xff\xde\x9b\xde \xff\xff\xff\xff\xdf\xdd\x9a0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\x0a\xd2\xb0\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1d\xc9\x8e0\x00\x00\x00\x00\x1ex\xd7\xa0\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3\xcf\xa0\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\x22\x0b\xc8\xa0\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=\xc4\x910\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00P\x83e0\x00\x00\x00\x00Q 9\xa0\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\x02\xff\xff\xd2\xd0\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\x08LMT\x00-02\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x00\x00America/Argentina/Buenos_AiresTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xa8L\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc94\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00\x1b\x00\x00\x00America/Argentina/CatamarcaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\x0b\xc0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00 \x00\x00\x00America/Argentina/ComodRivadaviaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\x0b\xc0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00America/Argentina/CordobaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00utZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x00\x00America/Argentina/JujuyTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xb8\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xe2\xdb\xb0\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x04\x05\x04\x05\x03\x05\x04\x05\xff\xff\xc2\xc8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m\x07D\x0e\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00America/Argentina/La_RiojaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb0,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xcd\xb5\xa0\x00\x00\x00\x00(&&@\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\x0b\xc0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc1T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x92Z\x8c\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00America/Argentina/MendozaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2\x04\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'\x194@\x00\x00\x00\x00'\xcd\xc3\xb0\x00\x00\x00\x00(\xfag\xc0\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*\xe0\xe1@\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xb0\x13\xb0\x00\x00\x00\x00AV>\xc0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf|\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ep\xb4c\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x00\x00America/Argentina/Rio_GallegosTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2d\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\x0b\xc0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf\x1c\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t*\x9b!\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x00\x00America/Argentina/SaltaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xd4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\xff\xff\xc2\xac\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfcz=\xe1\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00America/Argentina/San_JuanTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb1\xbc\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xcd\xb5\xa0\x00\x00\x00\x00(&&@\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xba\x9f\xb0\x00\x00\x00\x00A\x030@\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf\xc4\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x80\xb9\x5c\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00America/Argentina/San_LuisTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf\xb4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xfd\xa5\xa0\x00\x00\x00\x00'\x194@\x00\x00\x00\x00'\xcd\xc3\xb0\x00\x00\x00\x00(G\x1b\xc0\x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xba\x9f\xb0\x00\x00\x00\x00A\x030@\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\x93\xfc\xa0\x00\x00\x00\x00G\xd3R\xb0\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xb34\xb0\x00\x00\x00\x00J\xd1X@\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x05\x03\x05\x02\x05\x04\x03\x02\x03\x02\x05\xff\xff\xc1\xcc\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd8\xd6\xad\xd6\x02\x00\x00\xd6\x02\x00\x00\x19\x00\x00\x00America/Argentina/TucumanTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xa4\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xcb\xd1@\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\x04\x05\xff\xff\xc2\xdc\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b}\xb6\x1e\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00America/Argentina/UshuaiaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb1\x88\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xb9N0\x00\x00\x00\x00@\xd5\x0b\xc0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf\xf8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0d\x00\x00\x00America/ArubaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xa9y\x9at\x03\x00\x00t\x03\x00\x00\x10\x00\x00\x00America/AsuncionTZif2\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\x00O\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xffi\x87\x11\x90\xff\xff\xff\xff\xb8\x17\xf5\x90\x00\x00\x00\x00\x05+\xda@\x00\x00\x00\x00\x07\xfc\xf0\xb0\x00\x00\x00\x00\x0a\xcft\xc0\x00\x00\x00\x00\x0b\x97\xca\xb0\x00\x00\x00\x00\x0c\xb1\xf9\xc0\x00\x00\x00\x00\x0dx\xfe0\x00\x00\x00\x00\x0e\x93-@\x00\x00\x00\x00\x0fZ1\xb0\x00\x00\x00\x00\x10t`\xc0\x00\x00\x00\x00\x11dC\xb0\x00\x00\x00\x00\x12U\x94@\x00\x00\x00\x00\x13F\xc8\xb0\x00\x00\x00\x00\x148\x19@\x00\x00\x00\x00\x15'\xfc0\x00\x00\x00\x00\x16\x19L\xc0\x00\x00\x00\x00\x17\x09/\xb0\x00\x00\x00\x00\x17\xfa\x80@\x00\x00\x00\x00\x18\xeac0\x00\x00\x00\x00\x19\xdb\xb3\xc0\x00\x00\x00\x00\x1a\xcc\xe80\x00\x00\x00\x00\x1b\xbe8\xc0\x00\x00\x00\x00\x1c\xae\x1b\xb0\x00\x00\x00\x00\x1d\x9fl@\x00\x00\x00\x00\x1e\x8fO0\x00\x00\x00\x00\x1f\x80\x9f\xc0\x00\x00\x00\x00 p\x82\xb0\x00\x00\x00\x00!a\xd3@\x00\x00\x00\x00\x22S\x07\xb0\x00\x00\x00\x00#DX@\x00\x00\x00\x00$4;0\x00\x00\x00\x00%A;@\x00\x00\x00\x00&\x15n\xb0\x00\x00\x00\x00'\x06\xbf@\x00\x00\x00\x00'\xf6\xa20\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*\xcf\xbd\xc0\x00\x00\x00\x00+\xb9\x090\x00\x00\x00\x00,\xab\xab@\x00\x00\x00\x00-p\x0c\xb0\x00\x00\x00\x00.\x8c\xde\xc0\x00\x00\x00\x00/O\xee\xb0\x00\x00\x00\x000n\x12@\x00\x00\x00\x0016h0\x00\x00\x00\x002W.\xc0\x00\x00\x00\x003\x0f\xb2\xb0\x00\x00\x00\x0047\x10\xc0\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x006\x16\xf2\xc0\x00\x00\x00\x006\xe1\xeb\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xc1\xcd\xb0\x00\x00\x00\x009\xd6\xb6\xc0\x00\x00\x00\x00:\xa1\xaf\xb0\x00\x00\x00\x00;\xbf\xd3@\x00\x00\x00\x00<\xaf\xb60\x00\x00\x00\x00=q\x90\xc0\x00\x00\x00\x00>\x8f\x980\x00\x00\x00\x00?Z\xad@\x00\x00\x00\x00@oz0\x00\x00\x00\x00Aq\xee@\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x1a\xce\xc0\x00\x00\x00\x00G\xd3R\xb0\x00\x00\x00\x00H\xfa\xb0\xc0\x00\x00\x00\x00I\xb34\xb0\x00\x00\x00\x00J\xda\x92\xc0\x00\x00\x00\x00K\xc1;0\x00\x00\x00\x00L\xa7\xff\xc0\x00\x00\x00\x00M\xa1\x1d0\x00\x00\x00\x00N\x87\xe1\xc0\x00\x00\x00\x00O\x80\xff0\x00\x00\x00\x00Pp\xfe@\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\xff\xff\xc9\xf0\x00\x00\xff\xff\xc9\xf0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x00\x0c\xff\xff\xd5\xd0\x01\x0cLMT\x00AMT\x00-04\x00-03\x00\x0a<-04>4<-03>,M10.1.0/0,M3.4.0/0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xbe\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x10\x00\x00\x00America/AtikokanTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\x08LMT\x00CMT\x00EST\x00\x0aEST5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\x0c\x00\x00\x00America/AtkaTZif2\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\x00T\x00\x00\x00\x0a\x00\x00\x00!\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87Z^\xff\xff\xff\xff\xcb\x89D\xd0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\x071\x16\xc0\x00\x00\x00\x00\x07\x8dm\xd0\x00\x00\x00\x00\x09\x10\xf8\xc0\x00\x00\x00\x00\x09\xad\xe9P\x00\x00\x00\x00\x0a\xf0\xda\xc0\x00\x00\x00\x00\x0b\xe0\xd9\xd0\x00\x00\x00\x00\x0c\xd9\xf7@\x00\x00\x00\x00\x0d\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00\x18\x22}\xc0\x00\x00\x00\x00\x19\x09BP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\x22 \x00\x00\x00\x00\x1a\xf2P\xc0\x00\x00\x00\x00\x1b\xe23\xb0\x00\x00\x00\x00\x1c\xd22\xc0\x00\x00\x00\x00\x1d\xc2\x15\xb0\x00\x00\x00\x00\x1e\xb2\x14\xc0\x00\x00\x00\x00\x1f\xa1\xf7\xb0\x00\x00\x00\x00 vG@\x00\x00\x00\x00!\x81\xd9\xb0\x00\x00\x00\x00\x22V)@\x00\x00\x00\x00#j\xf60\x00\x00\x00\x00$6\x0b@\x00\x00\x00\x00%J\xd80\x00\x00\x00\x00&\x15\xed@\x00\x00\x00\x00'*\xba0\x00\x00\x00\x00'\xff\x09\xc0\x00\x00\x00\x00)\x0a\x9c0\x00\x00\x00\x00)\xde\xeb\xc0\x00\x00\x00\x00*\xea~0\x00\x00\x00\x00+\xbe\xcd\xc0\x00\x00\x00\x00,\xd3\x9a\xb0\x00\x00\x00\x00-\x9e\xaf\xc0\x00\x00\x00\x00.\xb3|\xb0\x00\x00\x00\x00/~\x91\xc0\x00\x00\x00\x000\x93^\xb0\x00\x00\x00\x001g\xae@\x00\x00\x00\x002s@\xb0\x00\x00\x00\x003G\x90@\x00\x00\x00\x004S\x22\xb0\x00\x00\x00\x005'r@\x00\x00\x00\x0063\x04\xb0\x00\x00\x00\x007\x07T@\x00\x00\x00\x008\x1c!0\x00\x00\x00\x008\xe76@\x00\x00\x00\x009\xfc\x030\x00\x00\x00\x00:\xc7\x18@\x00\x00\x00\x00;\xdb\xe50\x00\x00\x00\x00<\xb04\xc0\x00\x00\x00\x00=\xbb\xc70\x00\x00\x00\x00>\x90\x16\xc0\x00\x00\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84\xc5\xb0\x00\x00\x00\x00BO\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x07\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x00\x00\xab\xe2\x00\x00\xff\xffZb\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\x08\xff\xffs`\x01\x0c\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xffs`\x00\x18\xff\xff\x81p\x01\x1d\xff\xffs`\x00\x19LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00AHST\x00HDT\x00\x0aHST10HDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00OKj\xc7\xaa\x02\x00\x00\xaa\x02\x00\x00\x0d\x00\x00\x00America/BahiaTZif2\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\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaak\x1c\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xff\xdc\xb9Y \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xff\xde\x9b\xde \xff\xff\xff\xff\xdf\xdd\x9a0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\x0a\xd2\xb0\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1d\xc9\x8e0\x00\x00\x00\x00\x1ex\xd7\xa0\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3\xcf\xa0\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\x22\x0b\xc8\xa0\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\x0d\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00\x00\x00\x00.\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=\xc4\x910\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xdb\xe4\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\x08LMT\x00-02\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\x0e\x01n\xd8\x02\x00\x00\xd8\x02\x00\x00\x16\x00\x00\x00America/Bahia_BanderasTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\x0c6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xff\xd8\x91\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\x0b\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\x09\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00\xcd\x80\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00X\xe0\xaf\x80\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\x5c\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\x22p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x01\x02\x01\x03\x01\x02\x01\x04\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\xff\xff\x9dT\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\x8f\x80\x00\x10\xff\xff\xb9\xb0\x01\x14LMT\x00MST\x00CST\x00MDT\x00PST\x00CDT\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l=\xad\xbe\x16\x01\x00\x00\x16\x01\x00\x00\x10\x00\x00\x00America/BarbadosTZif2\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\x0f\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x92@\xa9e\xff\xff\xff\xff\xcb\xe3\xcb\xd0\xff\xff\xff\xff\xcc\x94\x82\xe0\xff\xff\xff\xff\xcd\xd6\x22\xd0\xff\xff\xff\xff\xce|M\xe0\xff\xff\xff\xff\xcf\x9b\xa6\xd0\xff\xff\xff\xff\xd0ej`\x00\x00\x00\x00\x0e\x00\xf2\xe0\x00\x00\x00\x00\x0e\x94\x8c\xd0\x00\x00\x00\x00\x0f\x97\x00\xe0\x00\x00\x00\x00\x10tn\xd0\x00\x00\x00\x00\x11v\xe2\xe0\x00\x00\x00\x00\x12TP\xd0\x00\x00\x00\x00\x13_\xff`\x00\x00\x00\x00\x140>P\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xc8\x1b\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xce\xc8\x01\x0cLMT\x00ADT\x00AST\x00-0330\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85-\xb9\xf8\x8a\x01\x00\x00\x8a\x01\x00\x00\x0d\x00\x00\x00America/BelemTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaatt\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xff\xdc\xb9Y \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xff\xde\x9b\xde \xff\xff\xff\xff\xdf\xdd\x9a0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\x0a\xd2\xb0\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1d\xc9\x8e0\x00\x00\x00\x00\x1ex\xd7\xa0\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3\xcf\xa0\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\x22\x0b\xc8\xa0\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\xff\xff\xd2\x8c\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\x08LMT\x00-02\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\xd8\xba\xee\x15\x04\x00\x00\x15\x04\x00\x00\x0e\x00\x00\x00America/BelizeTZif2\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\x00b\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xff\x93^\xd9\xb0\xff\xff\xff\xff\x9f\x9f;\xe0\xff\xff\xff\xff\xa0EQ\xd8\xff\xff\xff\xff\xa1\x7f\x1d\xe0\xff\xff\xff\xff\xa2.nX\xff\xff\xff\xff\xa3^\xff\xe0\xff\xff\xff\xff\xa4\x0ePX\xff\xff\xff\xff\xa5>\xe1\xe0\xff\xff\xff\xff\xa5\xee2X\xff\xff\xff\xff\xa7'\xfe`\xff\xff\xff\xff\xa7\xce\x14X\xff\xff\xff\xff\xa9\x07\xe0`\xff\xff\xff\xff\xa9\xad\xf6X\xff\xff\xff\xff\xaa\xe7\xc2`\xff\xff\xff\xff\xab\x97\x12\xd8\xff\xff\xff\xff\xac\xc7\xa4`\xff\xff\xff\xff\xadv\xf4\xd8\xff\xff\xff\xff\xae\xa7\x86`\xff\xff\xff\xff\xafV\xd6\xd8\xff\xff\xff\xff\xb0\x87h`\xff\xff\xff\xff\xb16\xb8\xd8\xff\xff\xff\xff\xb2p\x84\xe0\xff\xff\xff\xff\xb3\x16\x9a\xd8\xff\xff\xff\xff\xb4Pf\xe0\xff\xff\xff\xff\xb4\xf6|\xd8\xff\xff\xff\xff\xb60H\xe0\xff\xff\xff\xff\xb6\xdf\x99X\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb8\xbf{X\xff\xff\xff\xff\xb9\xf0\x0c\xe0\xff\xff\xff\xff\xba\x9f]X\xff\xff\xff\xff\xbb\xd9)`\xff\xff\xff\xff\xbc\x7f?X\xff\xff\xff\xff\xbd\xb9\x0b`\xff\xff\xff\xff\xbe_!X\xff\xff\xff\xff\xbf\x98\xed`\xff\xff\xff\xff\xc0?\x03X\xff\xff\xff\xff\xc1x\xcf`\xff\xff\xff\xff\xc2(\x1f\xd8\xff\xff\xff\xff\xc3X\xb1`\xff\xff\xff\xff\xc4\x08\x01\xd8\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc5\xe7\xe3\xd8\xff\xff\xff\xff\xc7!\xaf\xe0\xff\xff\xff\xff\xc7\xc7\xc5\xd8\xff\xff\xff\xff\xc9\x01\x91\xe0\xff\xff\xff\xff\xc9\xa7\xa7\xd8\xff\xff\xff\xff\xca\xe1s\xe0\xff\xff\xff\xff\xcb\x90\xc4X\xff\xff\xff\xff\xcc@\x22\xe0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2\xc6qP\xff\xff\xff\xff\xd6)\xfa`\xff\xff\xff\xff\xd6\xd9J\xd8\xff\xff\xff\xff\xd8\x09\xdc`\xff\xff\xff\xff\xd8\xb9,\xd8\xff\xff\xff\xff\xd9\xe9\xbe`\xff\xff\xff\xff\xda\x99\x0e\xd8\xff\xff\xff\xff\xdb\xd2\xda\xe0\xff\xff\xff\xff\xdcx\xf0\xd8\xff\xff\xff\xff\xdd\xb2\xbc\xe0\xff\xff\xff\xff\xdeX\xd2\xd8\xff\xff\xff\xff\xdf\x92\x9e\xe0\xff\xff\xff\xff\xe0A\xefX\xff\xff\xff\xff\xe1r\x80\xe0\xff\xff\xff\xff\xe2!\xd1X\xff\xff\xff\xff\xe3Rb\xe0\xff\xff\xff\xff\xe4\x01\xb3X\xff\xff\xff\xff\xe52D\xe0\xff\xff\xff\xff\xe5\xe1\x95X\xff\xff\xff\xff\xe7\x1ba`\xff\xff\xff\xff\xe7\xc1wX\xff\xff\xff\xff\xe8\xfbC`\xff\xff\xff\xff\xe9\xa1YX\xff\xff\xff\xff\xea\xdb%`\xff\xff\xff\xff\xeb\x8au\xd8\xff\xff\xff\xff\xec\xbb\x07`\xff\xff\xff\xff\xedjW\xd8\xff\xff\xff\xff\xee\x9a\xe9`\xff\xff\xff\xff\xefJ9\xd8\xff\xff\xff\xff\xf0\x84\x05\xe0\xff\xff\xff\xff\xf1*\x1b\xd8\xff\xff\xff\xff\xf2c\xe7\xe0\xff\xff\xff\xff\xf3\x09\xfd\xd8\xff\xff\xff\xff\xf4C\xc9\xe0\xff\xff\xff\xff\xf4\xe9\xdf\xd8\xff\xff\xff\xff\xf6#\xab\xe0\xff\xff\xff\xff\xf6\xd2\xfcX\xff\xff\xff\xff\xf8\x03\x8d\xe0\xff\xff\xff\xff\xf8\xb2\xdeX\xff\xff\xff\xff\xf9\xe3o\xe0\xff\xff\xff\xff\xfa\x92\xc0X\xff\xff\xff\xff\xfb\xcc\x8c`\xff\xff\xff\xff\xfcr\xa2X\x00\x00\x00\x00\x07b\xdb`\x00\x00\x00\x00\x07\xb9\xd0P\x00\x00\x00\x00\x18aq`\x00\x00\x00\x00\x18\xab7P\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\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\x05\x02\x05\x02\xff\xff\xadP\x00\x00\xff\xff\xb2\xa8\x01\x04\xff\xff\xab\xa0\x00\x0a\xff\xff\xb9\xb0\x01\x0e\xff\xff\xb9\xb0\x01\x12\xff\xff\xb9\xb0\x01\x16LMT\x00-0530\x00CST\x00CWT\x00CPT\x00CDT\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x14\x00\x00\x00America/Blanc-SablonTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8Dz\x97\xae\x01\x00\x00\xae\x01\x00\x00\x11\x00\x00\x00America/Boa_VistaTZif2\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\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaa\x7f\xe0\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xba\xde\x820\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\x08@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xff\xdc\xb9g0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xff\xde\x9b\xec0\xff\xff\xff\xff\xdf\xdd\xa8@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\x0d\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\x0a\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1d\xc9\x9c@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3\xdd\xb0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\x22\x0b\xd6\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x930\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x009\xe9\x1d\xb0\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\xff\xff\xc7 \x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\x08LMT\x00-03\x00-04\x00\x0a<-04>4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,g\xec\xec\xb3\x00\x00\x00\xb3\x00\x00\x00\x0e\x00\x00\x00America/BogotaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x9c4\xf0\xff\xff\xff\xff\x98XUp\x00\x00\x00\x00*\x03sP\x00\x00\x00\x00+t\x89@\x01\x03\x02\x03\xff\xff\xba\x90\x00\x00\xff\xff\xba\x90\x00\x04\xff\xff\xc7\xc0\x01\x08\xff\xff\xb9\xb0\x00\x0cLMT\x00BMT\x00-04\x00-05\x00\x0a<-05>5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\xbe\x1a>\xe7\x03\x00\x00\xe7\x03\x00\x00\x0d\x00\x00\x00America/BoiseTZif2\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\x00Z\x00\x00\x00\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x04\x1a\xc0\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xff\xa8FL \xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x07\xb2\x1f\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x09\xad\xb1\x10\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x05\x03\x04\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\x93\x0f\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10\xff\xff\x9d\x90\x00\x14\xff\xff\xab\xa0\x01\x18LMT\x00PDT\x00PST\x00MWT\x00MPT\x00MST\x00MDT\x00\x0aMST7MDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x14\x00\x00\x00America/Buenos_AiresTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xa8L\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc94\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\xba\xb2\x94s\x03\x00\x00s\x03\x00\x00\x15\x00\x00\x00America/Cambridge_BayTZif2\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\x00L\x00\x00\x00\x08\x00\x00\x00 \xff\xff\xff\xff\xa1\xf2\xcd\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x08 \xdd\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x0a\x00\xbf\x90\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\x04\xe9P\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x03\x01\x02\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\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\x06\x05\x07\x06\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x00\x00\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\xab\xa0\x01\x08\xff\xff\x9d\x90\x00\x0c\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18\xff\xff\xb9\xb0\x00\x1c-00\x00MWT\x00MPT\x00MST\x00MDT\x00CDT\x00CST\x00EST\x00\x0aMST7MDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xfbn\xdb\xb8\x03\x00\x00\xb8\x03\x00\x00\x14\x00\x00\x00America/Campo_GrandeTZif2\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\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaaz4\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xba\xde\x820\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\x08@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xff\xdc\xb9g0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xff\xde\x9b\xec0\xff\xff\xff\xff\xdf\xdd\xa8@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\x0d\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\x0a\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1d\xc9\x9c@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3\xdd\xb0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\x22\x0b\xd6\xb0\x00\x00\x00\x00#X\x1e\xc0\x00\x00\x00\x00#\xe2~0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xd4\xd50\x00\x00\x00\x00'!\x1d@\x00\x00\x00\x00'\xbd\xf1\xb0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\x94\x990\x00\x00\x00\x00*\xea\x1b\xc0\x00\x00\x00\x00+k@\xb0\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\x00\x00\x00\x00.\xa0\xa5@\x00\x00\x00\x00/F\xb40\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001\x1d[\xb0\x00\x00\x00\x002W.\xc0\x00\x00\x00\x003\x06x0\x00\x00\x00\x0048b@\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x006 -@\x00\x00\x00\x006\xcfv\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x930\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x00:\x8f:\xb0\x00\x00\x00\x00;\xc9\x0d\xc0\x00\x00\x00\x00<o\x1c\xb0\x00\x00\x00\x00=\xc4\x9f@\x00\x00\x00\x00>N\xfe\xb0\x00\x00\x00\x00?\x92\x0c@\x00\x00\x00\x00@.\xe0\xb0\x00\x00\x00\x00A\x87\x06@\x00\x00\x00\x00B\x17\xfd0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00C\xf7\xdf0\x00\x00\x00\x00EMa\xc0\x00\x00\x00\x00E\xe0\xfb\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xb7\xa30\x00\x00\x00\x00H\xfa\xb0\xc0\x00\x00\x00\x00I\x97\x850\x00\x00\x00\x00J\xda\x92\xc0\x00\x00\x00\x00K\x80\xa1\xb0\x00\x00\x00\x00L\xbat\xc0\x00\x00\x00\x00M`\x83\xb0\x00\x00\x00\x00N\x9aV\xc0\x00\x00\x00\x00OI\xa00\x00\x00\x00\x00P\x83s@\x00\x00\x00\x00Q G\xb0\x00\x00\x00\x00RcU@\x00\x00\x00\x00S\x00)\xb0\x00\x00\x00\x00TC7@\x00\x00\x00\x00T\xe9F0\x00\x00\x00\x00V#\x19@\x00\x00\x00\x00V\xc9(0\x00\x00\x00\x00X\x02\xfb@\x00\x00\x00\x00X\xa9\x0a0\x00\x00\x00\x00Y\xe2\xdd@\x00\x00\x00\x00Z\x88\xec0\x00\x00\x00\x00[\xden\xc0\x00\x00\x00\x00\x5ch\xce0\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\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\xff\xff\xcc\xcc\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\x08LMT\x00-03\x00-04\x00\x0a<-04>4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x04\xde\xdd\x11\x02\x00\x00\x11\x02\x00\x00\x0e\x00\x00\x00America/CancunTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\x16\x86\xd5`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x005\xc4\x00`\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\x0b\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\x09\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00T\xcd\xdd\x00\x01\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\xff\xff\xae\xa8\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xc7\xc0\x01\x08\xff\xff\xb9\xb0\x00\x0c\xff\xff\xb9\xb0\x01\x10LMT\x00CST\x00EDT\x00EST\x00CDT\x00\x0aEST5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x8e\xee\x13\xbe\x00\x00\x00\xbe\x00\x00\x00\x0f\x00\x00\x00America/CaracasTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffi\x87\x1a@\xff\xff\xff\xff\x93\x1e,<\xff\xff\xff\xff\xf6\x98\xecH\x00\x00\x00\x00G[\x92p\x00\x00\x00\x00W%\xa9p\x01\x02\x03\x02\x03\xff\xff\xc1@\x00\x00\xff\xff\xc1D\x00\x04\xff\xff\xc0\xb8\x00\x08\xff\xff\xc7\xc0\x00\x0eLMT\x00CMT\x00-0430\x00-04\x00\x0a<-04>4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00\x11\x00\x00\x00America/CatamarcaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xaf,\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xbb\xf10\x00\x00\x00\x00@\xd5\x0b\xc0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xc2T\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1'\x07\xbd\x97\x00\x00\x00\x97\x00\x00\x00\x0f\x00\x00\x00America/CayenneTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x91\xf4+\x90\xff\xff\xff\xff\xfb\xc35\xc0\x01\x02\xff\xff\xce\xf0\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\x08LMT\x00-04\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xbe\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x00\x00America/CaymanTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\x08LMT\x00CMT\x00EST\x00\x0aEST5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xdc\xa9=\xda\x06\x00\x00\xda\x06\x00\x00\x0f\x00\x00\x00America/ChicagoTZif2\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\xaf\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa2\xcbt\x00\xff\xff\xff\xff\xa3\x83\xf7\xf0\xff\xff\xff\xff\xa4E\xd2\x80\xff\xff\xff\xff\xa5c\xd9\xf0\xff\xff\xff\xff\xa6S\xd9\x00\xff\xff\xff\xff\xa7\x15\x97p\xff\xff\xff\xff\xa83\xbb\x00\xff\xff\xff\xff\xa8\xfe\xb3\xf0\xff\xff\xff\xff\xaa\x13\x9d\x00\xff\xff\xff\xff\xaa\xde\x95\xf0\xff\xff\xff\xff\xab\xf3\x7f\x00\xff\xff\xff\xff\xac\xbew\xf0\xff\xff\xff\xff\xad\xd3a\x00\xff\xff\xff\xff\xae\x9eY\xf0\xff\xff\xff\xff\xaf\xb3C\x00\xff\xff\xff\xff\xb0~;\xf0\xff\xff\xff\xff\xb1\x9c_\x80\xff\xff\xff\xff\xb2gXp\xff\xff\xff\xff\xb3|A\x80\xff\xff\xff\xff\xb4G:p\xff\xff\xff\xff\xb5\x5c#\x80\xff\xff\xff\xff\xb6'\x1cp\xff\xff\xff\xff\xb7<\x05\x80\xff\xff\xff\xff\xb8\x06\xfep\xff\xff\xff\xff\xb9\x1b\xe7\x80\xff\xff\xff\xff\xb9\xe6\xe0p\xff\xff\xff\xff\xbb\x05\x04\x00\xff\xff\xff\xff\xbb\xc6\xc2p\xff\xff\xff\xff\xbc\xe4\xe6\x00\xff\xff\xff\xff\xbd\xaf\xde\xf0\xff\xff\xff\xff\xbe\xc4\xc8\x00\xff\xff\xff\xff\xbf\x8f\xc0\xf0\xff\xff\xff\xff\xc0Z\xd6\x00\xff\xff\xff\xff\xc1\xb0<p\xff\xff\xff\xff\xc2\x84\x8c\x00\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xff\xc4dn\x00\xff\xff\xff\xff\xc5/f\xf0\xff\xff\xff\xff\xc6M\x8a\x80\xff\xff\xff\xff\xc7\x0fH\xf0\xff\xff\xff\xff\xc8-l\x80\xff\xff\xff\xff\xc8\xf8ep\xff\xff\xff\xff\xca\x0dN\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\xc2\x80\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xf6?ip\xff\xff\xff\xff\xf7/h\x80\xff\xff\xff\xff\xf8(\x85\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\x08g\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x0d\xf0\x00\x00\x00\x00\x00\x98\x0d\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x0cp\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xd0p\x00\x00\x00\x00\x07\x8d'\x80\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x09\xad\xa3\x00\x00\x00\x00\x00\x0a\xf0\x94p\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xb0\xf0\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x227p\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ac\xf0\x00\x00\x00\x00)\xde\xb3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;\xdb\xac\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\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\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xad\xd4\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x00\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00CDT\x00CST\x00EST\x00CWT\x00CPT\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x111\x04q\xb3\x02\x00\x00\xb3\x02\x00\x00\x11\x00\x00\x00America/ChihuahuaTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\x0c6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\x22\x00\x00\x00\x00\x00M\x987\x10\x00\x00\x00\x00N\xad\x04\x00\x00\x00\x00\x00Ox\x19\x10\x00\x00\x00\x00P\x8c\xe6\x00\x00\x00\x00\x00Qa5\x90\x00\x00\x00\x00Rl\xc8\x00\x00\x00\x00\x00SA\x17\x90\x00\x00\x00\x00TL\xaa\x00\x00\x00\x00\x00U \xf9\x90\x00\x00\x00\x00V,\x8c\x00\x00\x00\x00\x00W\x00\xdb\x90\x00\x00\x00\x00X\x15\xa8\x80\x00\x00\x00\x00X\xe0\xbd\x90\x00\x00\x00\x00Y\xf5\x8a\x80\x00\x00\x00\x00Z\xc0\x9f\x90\x00\x00\x00\x00[\xd5l\x80\x00\x00\x00\x00\x5c\xa9\xbc\x10\x00\x00\x00\x00]\xb5N\x80\x00\x00\x00\x00^\x89\x9e\x10\x00\x00\x00\x00_\x950\x80\x00\x00\x00\x00`i\x80\x10\x00\x00\x00\x00a~M\x00\x00\x00\x00\x00bIb\x10\x00\x00\x00\x00c^/\x00\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x02\xff\xff\x9c\x8c\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00MDT\x00CDT\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\xf2L\x06\xce\x02\x00\x00\xce\x02\x00\x00\x15\x00\x00\x00America/Ciudad_JuarezTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\x0c6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\x5c\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00\x00O\x5ci\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q<K\x90\x00\x00\x00\x00Rv\x02\x80\x00\x00\x00\x00S\x1c-\x90\x00\x00\x00\x00TU\xe4\x80\x00\x00\x00\x00T\xfc\x0f\x90\x00\x00\x00\x00V5\xc6\x80\x00\x00\x00\x00V\xe5,\x10\x00\x00\x00\x00X\x1e\xe3\x00\x00\x00\x00\x00X\xc5\x0e\x10\x00\x00\x00\x00Y\xfe\xc5\x00\x00\x00\x00\x00Z\xa4\xf0\x10\x00\x00\x00\x00[\xde\xa7\x00\x00\x00\x00\x00\x5c\x84\xd2\x10\x00\x00\x00\x00]\xbe\x89\x00\x00\x00\x00\x00^d\xb4\x10\x00\x00\x00\x00_\x9ek\x00\x00\x00\x00\x00`M\xd0\x90\x00\x00\x00\x00a\x87\x87\x80\x00\x00\x00\x00b-\xb2\x90\x00\x00\x00\x00c^/\x00\x00\x00\x00\x00c\x86\xf1`\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x02\x01\xff\xff\x9c,\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00MDT\x00CDT\x00\x0aMST7MDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xbe\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x15\x00\x00\x00America/Coral_HarbourTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\x08LMT\x00CMT\x00EST\x00\x0aEST5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00America/CordobaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1\xdd\x82x\xe8\x00\x00\x00\xe8\x00\x00\x00\x12\x00\x00\x00America/Costa_RicaTZif2\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\x0a\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffi\x87*M\xff\xff\xff\xff\xa3\xe8\x16M\x00\x00\x00\x00\x116I`\x00\x00\x00\x00\x11\xb7nP\x00\x00\x00\x00\x13\x16+`\x00\x00\x00\x00\x13\x97PP\x00\x00\x00\x00'\x97\xe0`\x00\x00\x00\x00(n\xb6\xd0\x00\x00\x00\x00)w\xc2`\x00\x00\x00\x00)\xc2\xd9\xd0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb13\x00\x00\xff\xff\xb13\x00\x04\xff\xff\xb9\xb0\x01\x09\xff\xff\xab\xa0\x00\x0dLMT\x00SJMT\x00CDT\x00CST\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\xb8\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x00\x00America/CrestonTZif2\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\x0b\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x04\x0c\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xcf\x17\xdf\x1c\xff\xff\xff\xff\xcf\x8f\xe5\xac\xff\xff\xff\xff\xd0\x81\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0cLMT\x00MDT\x00MST\x00MWT\x00\x0aMST7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f$*\xa0\xa6\x03\x00\x00\xa6\x03\x00\x00\x0e\x00\x00\x00America/CuiabaTZif2\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\x00Y\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaa{\x94\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xba\xde\x820\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\x08@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xff\xdc\xb9g0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xff\xde\x9b\xec0\xff\xff\xff\xff\xdf\xdd\xa8@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\x0d\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\x0a\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1d\xc9\x9c@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3\xdd\xb0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\x22\x0b\xd6\xb0\x00\x00\x00\x00#X\x1e\xc0\x00\x00\x00\x00#\xe2~0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xd4\xd50\x00\x00\x00\x00'!\x1d@\x00\x00\x00\x00'\xbd\xf1\xb0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\x94\x990\x00\x00\x00\x00*\xea\x1b\xc0\x00\x00\x00\x00+k@\xb0\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\x00\x00\x00\x00.\xa0\xa5@\x00\x00\x00\x00/F\xb40\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001\x1d[\xb0\x00\x00\x00\x002W.\xc0\x00\x00\x00\x003\x06x0\x00\x00\x00\x0048b@\x00\x00\x00\x004\xf8\xcf0\x00\x00\x00\x006 -@\x00\x00\x00\x006\xcfv\xb0\x00\x00\x00\x007\xf6\xd4\xc0\x00\x00\x00\x008\xb8\x930\x00\x00\x00\x009\xdf\xf1@\x00\x00\x00\x00:\x8f:\xb0\x00\x00\x00\x00;\xc9\x0d\xc0\x00\x00\x00\x00<o\x1c\xb0\x00\x00\x00\x00=\xc4\x9f@\x00\x00\x00\x00>N\xfe\xb0\x00\x00\x00\x00A\x87\x06@\x00\x00\x00\x00B\x17\xfd0\x00\x00\x00\x00CQ\xd0@\x00\x00\x00\x00C\xf7\xdf0\x00\x00\x00\x00EMa\xc0\x00\x00\x00\x00E\xe0\xfb\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xb7\xa30\x00\x00\x00\x00H\xfa\xb0\xc0\x00\x00\x00\x00I\x97\x850\x00\x00\x00\x00J\xda\x92\xc0\x00\x00\x00\x00K\x80\xa1\xb0\x00\x00\x00\x00L\xbat\xc0\x00\x00\x00\x00M`\x83\xb0\x00\x00\x00\x00N\x9aV\xc0\x00\x00\x00\x00OI\xa00\x00\x00\x00\x00P\x83s@\x00\x00\x00\x00Q G\xb0\x00\x00\x00\x00RcU@\x00\x00\x00\x00S\x00)\xb0\x00\x00\x00\x00TC7@\x00\x00\x00\x00T\xe9F0\x00\x00\x00\x00V#\x19@\x00\x00\x00\x00V\xc9(0\x00\x00\x00\x00X\x02\xfb@\x00\x00\x00\x00X\xa9\x0a0\x00\x00\x00\x00Y\xe2\xdd@\x00\x00\x00\x00Z\x88\xec0\x00\x00\x00\x00[\xden\xc0\x00\x00\x00\x00\x5ch\xce0\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\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\xff\xff\xcbl\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\x08LMT\x00-03\x00-04\x00\x0a<-04>4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America/CuracaoTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xc2\x0dx\xbf\x01\x00\x00\xbf\x01\x00\x00\x14\x00\x00\x00America/DanmarkshavnTZif2\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\x22\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9b\x80I\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x000\xe7N0\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\x03\xff\xff\xee\x80\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\x08\x00\x00\x00\x00\x00\x0cLMT\x00-03\x00-02\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xe6\xf5J\x05\x04\x00\x00\x05\x04\x00\x00\x0e\x00\x00\x00America/DawsonTZif2\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\x09\x00\x00\x00%\xff\xff\xff\xff}\x86\x8e\xb4\xff\xff\xff\xff\x9e\xb8\xcb\xb0\xff\xff\xff\xff\x9f\xbb#\xa0\xff\xff\xff\xff\xa0\xd0\x0c\xb0\xff\xff\xff\xff\xa1\xa2\xd2\x80\xff\xff\xff\xff\xcb\x89(\xb0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\x00\x00\x00\x00\x070\xec\x90\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00G\xd3\xb5 \x00\x00\x00\x00I\x0dl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\x5cw\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90\x00\x00\x00\x00T\xfc\x1d\xa0\x00\x00\x00\x00V5\xd4\x90\x00\x00\x00\x00V\xe5: \x00\x00\x00\x00X\x1e\xf1\x10\x00\x00\x00\x00X\xc5\x1c \x00\x00\x00\x00Y\xfe\xd3\x10\x00\x00\x00\x00Z\xa4\xfe \x00\x00\x00\x00[\xde\xb5\x10\x00\x00\x00\x00\x5c\x84\xe0 \x00\x00\x00\x00]\xbe\x97\x10\x00\x00\x00\x00^d\xc2 \x00\x00\x00\x00_\x9e\x5c\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x02\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\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\x08\xff\xff}L\x00\x00\xff\xff\x8f\x80\x01\x04\xff\xff\x81p\x00\x08\xff\xff\x8f\x80\x01\x0c\xff\xff\x8f\x80\x01\x10\xff\xff\x9d\x90\x01\x14\xff\xff\x8f\x80\x00\x19\xff\xff\x9d\x90\x01\x1d\xff\xff\x9d\x90\x00!LMT\x00YDT\x00YST\x00YWT\x00YPT\x00YDDT\x00PST\x00PDT\x00MST\x00\x0aMST7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x10`\xc8\xab\x02\x00\x00\xab\x02\x00\x00\x14\x00\x00\x00America/Dawson_CreekTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff^=t8\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xcb\x89\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfe\xd1\xa0\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\xde\xb3\xa0\xff\xff\xff\xff\xdd\xa9\xac\x90\xff\xff\xff\xff\xde\xbe\x95\xa0\xff\xff\xff\xff\xdf\x89\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\x07\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8f\xde\xa0\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\x08\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\x0c\x10\x00\x00\x00\x00\x02x\x0b \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05\x01\xf0\x90\x02\x01\x02\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\x02\x01\x05\xff\xff\x8fH\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x00\x14LMT\x00PDT\x00PST\x00PWT\x00PPT\x00MST\x00\x0aMST7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x0e\x00\x00\x00America/DenverTZif2\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\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\x0c\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\x08v\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x07\x8d5\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x09\xad\xb1\x10\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\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\xff\xff\x9d\x94\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\x0aMST7MDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\x0f\x00\x00\x00America/DetroitTZif2\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\x00P\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x85\xbd\x22[\xff\xff\xff\xff\x99<\x94\x00\xff\xff\xff\xff\xcb\x88\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xfb3\x90\x8c\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x07\x8d\x19p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x0a\x00\xa3p\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\xff\xff\xb2%\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x01\x10\xff\xff\xc7\xc0\x01\x14LMT\x00CST\x00EST\x00EWT\x00EPT\x00EDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00America/DominicaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\x07\x07\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x10\x00\x00\x00America/EdmontonTZif2\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\x00Y\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x88\xde\xce\xe0\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x98\x91\x90\xff\xff\xff\xff\xa0\xd2\x85\x80\xff\xff\xff\xff\xa2\x8a\xe8\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4j\xca\x90\xff\xff\xff\xff\xa55\xc3\x80\xff\xff\xff\xff\xa6S\xe7\x10\xff\xff\xff\xff\xa7\x15\xa5\x80\xff\xff\xff\xff\xa83\xc9\x10\xff\xff\xff\xff\xa8\xfe\xc2\x00\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x08 \xdd\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x0a\x00\xbf\x90\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x95\xa0\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\x0aMST7MDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\xb0\xeau\xb4\x01\x00\x00\xb4\x01\x00\x00\x10\x00\x00\x00America/EirunepeTZif2\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\x0c\xff\xff\xff\xff\x96\xaa\x88\x80\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\x5c\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xba\xde\x90@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xff\xdc\xb9u@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xff\xde\x9b\xfa@\xff\xff\xff\xff\xdf\xdd\xb6P\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\x0a\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\x22P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1d\xc9\xaaP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\x22\x0b\xe4\xc0\x00\x00\x00\x00,\xc0\xd1P\x00\x00\x00\x00-f\xe0@\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\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\x03\x02\xff\xff\xbe\x80\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\x0a<-05>5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea$\xc1\xbf\xb0\x00\x00\x00\xb0\x00\x00\x00\x13\x00\x00\x00America/El_SalvadorTZif2\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\x05\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\xa3\xd5\xa6 \x00\x00\x00\x00 \x9a\xdc\xe0\x00\x00\x00\x00!\x5c\x9bP\x00\x00\x00\x00\x22z\xbe\xe0\x00\x00\x00\x00#<}P\x02\x01\x02\x01\x02\xff\xff\xac`\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08LMT\x00CDT\x00CST\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x00\x00America/EnsenadaTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\x0a\xf2\xf0\xff\xff\xff\xff\xcb\xea\x8d\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2\x99\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff\xff\xff\xd8\x91\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\x07\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\xd8\x81 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00PST\x00PDT\x00PWT\x00PPT\x00\x0aPST8PDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6@\x0dm\xa8\x05\x00\x00\xa8\x05\x00\x00\x13\x00\x00\x00America/Fort_NelsonTZif2\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\x8f\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^=v\x87\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xcb\x89\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfe\xd1\xa0\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\xde\xb3\xa0\xff\xff\xff\xff\xdd\xa9\xac\x90\xff\xff\xff\xff\xde\xbe\x95\xa0\xff\xff\xff\xff\xdf\x89\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\x07\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8f\xde\xa0\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\x08\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\x0c\x10\x00\x00\x00\x00\x02x\x0b \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\x0a\x90\x00\x00\x00\x00\x06A\x09\xa0\x00\x00\x00\x00\x070\xec\x90\x00\x00\x00\x00\x08 \xeb\xa0\x00\x00\x00\x00\x09\x10\xce\x90\x00\x00\x00\x00\x0a\x00\xcd\xa0\x00\x00\x00\x00\x0a\xf0\xb0\x90\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00G\xd3\xb5 \x00\x00\x00\x00I\x0dl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\x5cw\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90\x00\x00\x00\x00T\xfc\x1d\xa0\x02\x01\x02\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\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\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\x05\xff\xff\x8c\xf9\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x00\x14LMT\x00PDT\x00PST\x00PWT\x00PPT\x00MST\x00\x0aMST7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x12\x00\x00\x00America/Fort_WayneTZif2\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\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcaW\x22\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x11Z\xde\xe4\x01\x00\x00\xe4\x01\x00\x00\x11\x00\x00\x00America/FortalezaTZif2\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\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaak\x18\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xff\xdc\xb9Y \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xff\xde\x9b\xde \xff\xff\xff\xff\xdf\xdd\x9a0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\x0a\xd2\xb0\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1d\xc9\x8e0\x00\x00\x00\x00\x1ex\xd7\xa0\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3\xcf\xa0\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\x22\x0b\xc8\xa0\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x009\xf2J \x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\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\xff\xff\xdb\xe8\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\x08LMT\x00-02\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M\x94\xc7Kp\x03\x00\x00p\x03\x00\x00\x11\x00\x00\x00America/Glace_BayTZif2\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\x00O\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x80\xf1\xa84\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xff\xcb\x88\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\x070\xb4P\x00\x00\x00\x00\x08 \xb3`\x00\x00\x00\x00\x09\x10\x96P\x00\x00\x00\x00\x0a\x00\x95`\x00\x00\x00\x00\x0a\xf0xP\x00\x00\x00\x00\x0b\xe0w`\x00\x00\x00\x00\x0c\xd9\x94\xd0\x00\x00\x00\x00\x0d\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\x22\x1bP\x00\x00\x00\x00\x19\x08\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\x22U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\x0aG\xd0\x00\x00\x00\x00)\xde\x97`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\x0aP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;\xdb\x90\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01\x02\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xc7\xcc\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xd5\xd0\x01\x10LMT\x00ADT\x00AST\x00AWT\x00APT\x00\x0aAST4ADT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95'O\xce\xc5\x03\x00\x00\xc5\x03\x00\x00\x0f\x00\x00\x00America/GodthabTZif3\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\x00Y\x00\x00\x00\x04\x00\x00\x00\x0c\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05\xc9\x90\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L\xcc\xbf\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\x0a\x10\x00\x00\x00\x00\x5c\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\x7f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]\xcc\x90\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\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\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\x03\xff\xff\xcf\x80\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\x08\xff\xff\xe3\xe0\x00\x08LMT\x00-03\x00-02\x00\x0a<-02>2<-01>,M3.5.0/-1,M10.5.0/0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\xf7\x07 ,\x06\x00\x00,\x06\x00\x00\x11\x00\x00\x00America/Goose_BayTZif2\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\x98\x00\x00\x00\x0a\x00\x00\x00!\xff\xff\xff\xff^=<$\xff\xff\xff\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xbe\x9eMl\xff\xff\xff\xff\xc0\xb818\xff\xff\xff\xff\xc1y\xef\xa8\xff\xff\xff\xff\xc2\x98\x138\xff\xff\xff\xff\xc3Y\xd1\xa8\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff\xff\xc8@\xf3\xb8\xff\xff\xff\xff\xc9\x02\xb2(\xff\xff\xff\xff\xca \xd5\xb8\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xff\xd3\x88D\xd8\xff\xff\xff\xff\xd4J\x03H\xff\xff\xff\xff\xd5h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\x08\xd8\xff\xff\xff\xff\xd8\x09\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff\xff\xdb\x11\x07X\xff\xff\xff\xff\xdb\xd2\xc5\xc8\xff\xff\xff\xff\xdc\xdetX\xff\xff\xff\xff\xdd\xa9mH\xff\xff\xff\xff\xde\xbeVX\xff\xff\xff\xff\xdf\x89OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1i1H\xff\xff\xff\xff\xe2~\x1aX\xff\xff\xff\xff\xe3I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff\xff\xe8\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06\xdc\xd8\xff\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff\xec\xb1\xb7\xc8\xff\xff\xff\xff\xed\xc6\xa0\xd8\xff\xff\xff\xff\xee\xbf\xbeH\xff\xff\xff\xff\xef\xaf\xbdX\xff\xff\xff\xff\xf0\x9f\xa0H\xff\xff\xff\xff\xf1\x8f\x9fX\xff\xff\xff\xff\xf2\x7f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff\xff\xff\xff\xf7/EX\xff\xff\xff\xff\xf8(b\xc8\xff\xff\xff\xff\xf8\xdakX\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\x08K\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\x070\xb4P\x00\x00\x00\x00\x08 \xb3`\x00\x00\x00\x00\x09\x10\x96P\x00\x00\x00\x00\x0a\x00\x95`\x00\x00\x00\x00\x0a\xf0xP\x00\x00\x00\x00\x0b\xe0w`\x00\x00\x00\x00\x0c\xd9\x94\xd0\x00\x00\x00\x00\x0d\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\x22\x1bP\x00\x00\x00\x00\x19\x08\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xd6\xfc\x00\x00\x00\x00!\x81il\x00\x00\x00\x00\x22U\xb8\xfc\x00\x00\x00\x00#jw\xdc\x00\x00\x00\x00$5\x9a\xfc\x00\x00\x00\x00%Jg\xec\x00\x00\x00\x00&\x15|\xfc\x00\x00\x00\x00'*I\xec\x00\x00\x00\x00'\xfe\x99|\x00\x00\x00\x00)\x0a+\xec\x00\x00\x00\x00)\xde{|\x00\x00\x00\x00*\xea\x0d\xec\x00\x00\x00\x00+\xbe]|\x00\x00\x00\x00,\xd3*l\x00\x00\x00\x00-\x9e?|\x00\x00\x00\x00.\xb3\x0cl\x00\x00\x00\x00/~!|\x00\x00\x00\x000\x92\xeel\x00\x00\x00\x001g=\xfc\x00\x00\x00\x002r\xd0l\x00\x00\x00\x003G\x1f\xfc\x00\x00\x00\x004R\xb2l\x00\x00\x00\x005'\x01\xfc\x00\x00\x00\x0062\x94l\x00\x00\x00\x007\x06\xe3\xfc\x00\x00\x00\x008\x1b\xb0\xec\x00\x00\x00\x008\xe6\xc5\xfc\x00\x00\x00\x009\xfb\x92\xec\x00\x00\x00\x00:\xc6\xa7\xfc\x00\x00\x00\x00;\xdbt\xec\x00\x00\x00\x00<\xaf\xc4|\x00\x00\x00\x00=\xbbV\xec\x00\x00\x00\x00>\x8f\xa6|\x00\x00\x00\x00?\x9b8\xec\x00\x00\x00\x00@o\x88|\x00\x00\x00\x00A\x84Ul\x00\x00\x00\x00BOj|\x00\x00\x00\x00Cd7l\x00\x00\x00\x00D/L|\x00\x00\x00\x00ED\x19l\x00\x00\x00\x00E\xf3~\xfc\x00\x00\x00\x00G-5\xec\x00\x00\x00\x00G\xd3`\xfc\x00\x00\x00\x00I\x0d\x17\xec\x00\x00\x00\x00I\xb3B\xfc\x00\x00\x00\x00J\xec\xf9\xec\x00\x00\x00\x00K\x9c_|\x00\x00\x00\x00L\xd6\x16l\x00\x00\x00\x00M|A|\x00\x00\x00\x00N\xb6\x14P\x01\x02\x01\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x09\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\xff\xff\xc7\x5c\x00\x00\xff\xff\xce\x94\x00\x04\xff\xff\xdc\xa4\x01\x08\xff\xff\xce\xc8\x00\x04\xff\xff\xdc\xd8\x01\x08\xff\xff\xdc\xd8\x01\x0c\xff\xff\xdc\xd8\x01\x10\xff\xff\xd5\xd0\x01\x14\xff\xff\xc7\xc0\x00\x18\xff\xff\xe3\xe0\x01\x1cLMT\x00NST\x00NDT\x00NPT\x00NWT\x00ADT\x00AST\x00ADDT\x00\x0aAST4ADT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xc9I\xd0U\x03\x00\x00U\x03\x00\x00\x12\x00\x00\x00America/Grand_TurkTZif2\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\x00L\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1e0\xff\xff\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x00\x00\x00\x00G-_\xe0\x00\x00\x00\x00G\xd3\x8a\xf0\x00\x00\x00\x00I\x0dA\xe0\x00\x00\x00\x00I\xb3l\xf0\x00\x00\x00\x00J\xed#\xe0\x00\x00\x00\x00K\x9c\x89p\x00\x00\x00\x00L\xd6@`\x00\x00\x00\x00M|kp\x00\x00\x00\x00N\xb6\x22`\x00\x00\x00\x00O\x5cMp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q</p\x00\x00\x00\x00Ru\xe6`\x00\x00\x00\x00S\x1c\x11p\x00\x00\x00\x00TU\xc8`\x00\x00\x00\x00T\xfb\xf3p\x00\x00\x00\x00Z\xa4\xd3\xf0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x03\xff\xff\xbdP\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x00\x10LMT\x00KMT\x00EST\x00EDT\x00AST\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America/GrenadaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00America/GuadeloupeTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x8a\x83S\xd4\x00\x00\x00\xd4\x00\x00\x00\x11\x00\x00\x00America/GuatemalaTZif2\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\x09\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x9f\x9d\xea\xdc\x00\x00\x00\x00\x07U\xac`\x00\x00\x00\x00\x07\xcd\x96\xd0\x00\x00\x00\x00\x19,x`\x00\x00\x00\x00\x19\xcf\xe4P\x00\x00\x00\x00'\xea\xee\xe0\x00\x00\x00\x00(\xc8\x5c\xd0\x00\x00\x00\x00DTR`\x00\x00\x00\x00E\x1fKP\x02\x01\x02\x01\x02\x01\x02\x01\x02\xff\xff\xab$\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08LMT\x00CDT\x00CST\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xc3v\xe3\xb3\x00\x00\x00\xb3\x00\x00\x00\x11\x00\x00\x00America/GuayaquilTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87&X\xff\xff\xff\xff\xb6\xa4B\x18\x00\x00\x00\x00+\x16\xfc\xd0\x00\x00\x00\x00+q\xe6@\x01\x03\x02\x03\xff\xff\xb5(\x00\x00\xff\xff\xb6h\x00\x04\xff\xff\xc7\xc0\x01\x08\xff\xff\xb9\xb0\x00\x0cLMT\x00QMT\x00-04\x00-05\x00\x0a<-05>5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x05\xf3\x89\xb5\x00\x00\x00\xb5\x00\x00\x00\x0e\x00\x00\x00America/GuyanaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\x92\x1d\x0f\x87\xff\xff\xff\xff\x98\xd9{@\x00\x00\x00\x00\x0a\x7f\x05\xbc\x00\x00\x00\x00)\xd5@\xc0\x01\x02\x03\x01\xff\xff\xc9y\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xcbD\x00\x08\xff\xff\xd5\xd0\x00\x0eLMT\x00-04\x00-0345\x00-03\x00\x0a<-04>4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x00\x00America/HalifaxTZif2\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\xa7\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x80\xf1\xab\xa0\xff\xff\xff\xff\x9a\xe4\xde\xc0\xff\xff\xff\xff\x9b\xd6\x130\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xff\xa2\x9d\x17@\xff\xff\xff\xff\xa30\xb10\xff\xff\xff\xff\xa4zV@\xff\xff\xff\xff\xa5\x1b\x1f0\xff\xff\xff\xff\xa6S\xa0\xc0\xff\xff\xff\xff\xa6\xfcR\xb0\xff\xff\xff\xff\xa8<\xbd@\xff\xff\xff\xff\xa8\xdc4\xb0\xff\xff\xff\xff\xaa\x1c\x9f@\xff\xff\xff\xff\xaa\xcd:0\xff\xff\xff\xff\xab\xfc\x81@\xff\xff\xff\xff\xac\xbf\x910\xff\xff\xff\xff\xad\xee\xd8@\xff\xff\xff\xff\xae\x8c\xfe0\xff\xff\xff\xff\xaf\xbcE@\xff\xff\xff\xff\xb0\x7fU0\xff\xff\xff\xff\xb1\xae\x9c@\xff\xff\xff\xff\xb2Kp\xb0\xff\xff\xff\xff\xb3\x8e~@\xff\xff\xff\xff\xb4$\xbb0\xff\xff\xff\xff\xb5n`@\xff\xff\xff\xff\xb6\x15\xc0\xb0\xff\xff\xff\xff\xb7NB@\xff\xff\xff\xff\xb8\x08\x17\xb0\xff\xff\xff\xff\xb9$\xe9\xc0\xff\xff\xff\xff\xb9\xe7\xf9\xb0\xff\xff\xff\xff\xbb\x04\xcb\xc0\xff\xff\xff\xff\xbb\xd1\x160\xff\xff\xff\xff\xbd\x00]@\xff\xff\xff\xff\xbd\x9d1\xb0\xff\xff\xff\xff\xbe\xf2\xb4@\xff\xff\xff\xff\xbf\x90\xda0\xff\xff\xff\xff\xc0\xd3\xe7\xc0\xff\xff\xff\xff\xc1^G0\xff\xff\xff\xff\xc2\x8d\x8e@\xff\xff\xff\xff\xc3P\x9e0\xff\xff\xff\xff\xc4mp@\xff\xff\xff\xff\xc50\x800\xff\xff\xff\xff\xc6r<@\xff\xff\xff\xff\xc7\x10b0\xff\xff\xff\xff\xc86n\xc0\xff\xff\xff\xff\xc8\xf9~\xb0\xff\xff\xff\xff\xca\x16P\xc0\xff\xff\xff\xff\xca\xd9`\xb0\xff\xff\xff\xff\xcb\x88\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xd3u\xd6\xe0\xff\xff\xff\xff\xd4@\xcf\xd0\xff\xff\xff\xff\xd5U\xb8\xe0\xff\xff\xff\xff\xd6 \xb1\xd0\xff\xff\xff\xff\xd75\x9a\xe0\xff\xff\xff\xff\xd8\x00\x93\xd0\xff\xff\xff\xff\xd9\x15|\xe0\xff\xff\xff\xff\xd9\xe0u\xd0\xff\xff\xff\xff\xdc\xde{`\xff\xff\xff\xff\xdd\xa9tP\xff\xff\xff\xff\xde\xbe]`\xff\xff\xff\xff\xdf\x89VP\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\xff\xff\xff\xff\xe2~!`\xff\xff\xff\xff\xe3I\x1aP\xff\xff\xff\xff\xe6G\x1f\xe0\xff\xff\xff\xff\xe7\x12\x18\xd0\xff\xff\xff\xff\xe8'\x01\xe0\xff\xff\xff\xff\xe8\xf1\xfa\xd0\xff\xff\xff\xff\xea\x06\xe3\xe0\xff\xff\xff\xff\xea\xd1\xdc\xd0\xff\xff\xff\xff\xeb\xe6\xc5\xe0\xff\xff\xff\xff\xec\xb1\xbe\xd0\xff\xff\xff\xff\xf1\x8f\xa6`\xff\xff\xff\xff\xf2\x7f\x89P\xff\xff\xff\xff\xf3o\x88`\xff\xff\xff\xff\xf4_kP\xff\xff\xff\xff\xf5Oj`\xff\xff\xff\xff\xf6?MP\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(i\xd0\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\x08K\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\x070\xb4P\x00\x00\x00\x00\x08 \xb3`\x00\x00\x00\x00\x09\x10\x96P\x00\x00\x00\x00\x0a\x00\x95`\x00\x00\x00\x00\x0a\xf0xP\x00\x00\x00\x00\x0b\xe0w`\x00\x00\x00\x00\x0c\xd9\x94\xd0\x00\x00\x00\x00\x0d\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\x22\x1bP\x00\x00\x00\x00\x19\x08\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\x22U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\x0aG\xd0\x00\x00\x00\x00)\xde\x97`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\x0aP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;\xdb\x90\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xc4`\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xd5\xd0\x01\x10LMT\x00ADT\x00AST\x00AWT\x00APT\x00\x0aAST4ADT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x0e\x00\x00\x00America/HavanaTZif2\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\x00j\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87(\xb8\xff\xff\xff\xff\xacb\xc2\x80\xff\xff\xff\xff\xb1\xd3\x94P\xff\xff\xff\xff\xb2t]@\xff\xff\xff\xff\xc8[f\xd0\xff\xff\xff\xff\xc8\xd3Q@\xff\xff\xff\xff\xca;H\xd0\xff\xff\xff\xff\xca\xbcm\xc0\xff\xff\xff\xff\xcc$eP\xff\xff\xff\xff\xcc\x9cO\xc0\xff\xff\xff\xff\xd1\xc4\x0bP\xff\xff\xff\xff\xd2;\xf5\xc0\xff\xff\xff\xff\xd3\xa3\xedP\xff\xff\xff\xff\xd4\x1b\xd7\xc0\xff\xff\xff\xff\xf7`\x05\xd0\xff\xff\xff\xff\xf7\xff}@\xff\xff\xff\xff\xf9=D\xd0\xff\xff\xff\xff\xf9\xe3S\xc0\xff\xff\xff\xff\xfa\xdb;\xd0\xff\xff\xff\xff\xfb\xa7\x86@\xff\xff\xff\xff\xfc\xc5\xa9\xd0\xff\xff\xff\xff\xfd\x87h@\xff\xff\xff\xff\xfe\xb8\x00\xd0\xff\xff\xff\xff\xff\xa7\xe3\xc0\x00\x00\x00\x00\x00\x97\xe2\xd0\x00\x00\x00\x00\x01\x87\xc5\xc0\x00\x00\x00\x00\x02w\xc4\xd0\x00\x00\x00\x00\x03p\xe2@\x00\x00\x00\x00\x04`\xe1P\x00\x00\x00\x00\x055\x14\xc0\x00\x00\x00\x00\x06@\xc3P\x00\x00\x00\x00\x07\x16H@\x00\x00\x00\x00\x08 \xa5P\x00\x00\x00\x00\x08\xf7{\xc0\x00\x00\x00\x00\x0a\x00\x87P\x00\x00\x00\x00\x0a\xf0j@\x00\x00\x00\x00\x0b\xe0iP\x00\x00\x00\x00\x0c\xd9\x86\xc0\x00\x00\x00\x00\x0d\xc0KP\x00\x00\x00\x00\x0e\xb9h\xc0\x00\x00\x00\x00\x0f\xb2\xa2P\x00\x00\x00\x00\x10}\x9b@\x00\x00\x00\x00\x11Q\xea\xd0\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x131\xcc\xd0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15[\x82\xd0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x17;d\xd0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xfb(\xd0\x00\x00\x00\x00\x1b\xcf\x5c@\x00\x00\x00\x00\x1c\xdb\x0a\xd0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ezSP\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 Z5P\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\x22CQ\xd0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$#3\xd0\x00\x00\x00\x00%.\xc6@\x00\x00\x00\x00&\x15\x8a\xd0\x00\x00\x00\x00'\x17\xe2\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00(\xf7\xd2\xd0\x00\x00\x00\x00)\xde\x89P\x00\x00\x00\x00*\xd7\xb4\xd0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xb7\x96\xd0\x00\x00\x00\x00-\x9eMP\x00\x00\x00\x00.\x97x\xd0\x00\x00\x00\x00/~/P\x00\x00\x00\x000wZ\xd0\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002W<\xd0\x00\x00\x00\x003G-\xd0\x00\x00\x00\x004@YP\x00\x00\x00\x005\x1d\xd5P\x00\x00\x00\x0062\xb0P\x00\x00\x00\x006\xfd\xb7P\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xb5\xd0\x00\x00\x00\x00;\xdb\x90\xd0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@f[\xd0\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x8c\xd0\x00\x00\x00\x00G$\x17P\x00\x00\x00\x00G\xdc\xa9P\x00\x00\x00\x00I\x03\xf9P\x00\x00\x00\x00I\xb3P\xd0\x00\x00\x00\x00J\xe3\xdbP\x00\x00\x00\x00K\x9cmP\x00\x00\x00\x00L\xcc\xf7\xd0\x00\x00\x00\x00M\x85\x89\xd0\x00\x00\x00\x00N\xbfN\xd0\x00\x00\x00\x00Ow\xe0\xd0\x00\x00\x00\x00P\x95\xf6P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb2\xc8\x00\x00\xff\xff\xb2\xc0\x00\x04\xff\xff\xc7\xc0\x01\x08\xff\xff\xb9\xb0\x00\x0cLMT\x00HMT\x00CDT\x00CST\x00\x0aCST5CDT,M3.2.0/0,M11.1.0/1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4MS\x99\x1e\x01\x00\x00\x1e\x01\x00\x00\x12\x00\x00\x00America/HermosilloTZif2\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\x0f\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\x0c6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xff\xd8\x91\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x01\x02\x01\x03\x01\x02\x01\x04\x01\x03\x01\x03\x01\x03\x01\xff\xff\x97\xf8\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\x8f\x80\x00\x10LMT\x00MST\x00CST\x00MDT\x00PST\x00\x0aMST7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x1c\x00\x00\x00America/Indiana/IndianapolisTZif2\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\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcaW\x22\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x14\x00\x00\x00America/Indiana/KnoxTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\xc2\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x0d\xf0\x00\x00\x00\x00\x00\x98\x0d\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x0cp\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xd0p\x00\x00\x00\x00\x07\x8d'\x80\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x09\xad\xa3\x00\x00\x00\x00\x00\x0a\xf0\x94p\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xb0\xf0\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x227p\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ac\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\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\x05\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\x05\x01\x02\x01\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M/U\x9f7\x02\x00\x007\x02\x00\x00\x17\x00\x00\x00America/Indiana/MarengoTZif2\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\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\x91\xbc\xf0\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x07\x8d\x19p\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x09\xad\x94\xf0\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x01\x05\x06\x05\x06\x05\x06\xff\xff\xaf\x0d\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xd8N\x8c\xab\x02\x00\x00\xab\x02\x00\x00\x1a\x00\x00\x00America/Indiana/PetersburgTZif2\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\x008\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xe4g=\xe0\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\x91\xbc\xf0\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\xc2\x80\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xf6?ip\xff\xff\xff\xff\xf7/h\x80\xff\xff\xff\xff\xfa\x08g\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x0d\xf0\x00\x00\x00\x00\x00\x98\x0d\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x0cp\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xd0p\x00\x00\x00\x00\x07\x8d'\x80\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x09\xad\xa3\x00\x00\x00\x00\x00\x0a\xf0\x94p\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xb0\xf0\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x05\x01\x02\x01\x05\xff\xff\xae-\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xb5K\xa6\x0a\x02\x00\x00\x0a\x02\x00\x00\x19\x00\x00\x00America/Indiana/Tell_CityTZif2\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\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xe4g=\xe0\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\x91\xbc\xf0\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\xc2\x80\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x01\x02\x06\x05\x06\x05\x01\x02\x01\xff\xff\xae\xa9\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x17\x89}q\x01\x00\x00q\x01\x00\x00\x15\x00\x00\x00America/Indiana/VevayTZif2\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\x14\x00\x00\x00\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xb0@\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\xedsp.\x02\x00\x00.\x02\x00\x00\x19\x00\x00\x00America/Indiana/VincennesTZif2\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\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4g=\xe0\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0q\x9e\xf0\xff\xff\xff\xff\xf1\x8f\xc2\x80\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-m\xf0\x02\x01\x02\x01\x02\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\x05\x06\x05\x06\x05\x01\x02\x01\x05\xff\xff\xad\xf1\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K-E\xfad\x02\x00\x00d\x02\x00\x00\x17\x00\x00\x00America/Indiana/WinamacTZif2\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\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xb1\xda\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\x91\xbc\xf0\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x00\x00\x00\x00G-_\xe0\x02\x01\x02\x01\x02\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\x05\x06\x05\x06\x05\x01\x02\x06\x05\xff\xff\xae\xcf\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x14\x00\x00\x00America/IndianapolisTZif2\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\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcaW\x22\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xbc\x09o1\x03\x00\x001\x03\x00\x00\x0e\x00\x00\x00America/InuvikTZif2\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\x00H\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\xe0\x06N\x80\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\x0a\x90\x00\x00\x00\x00\x06A\x09\xa0\x00\x00\x00\x00\x070\xec\x90\x00\x00\x00\x00\x08 \xeb\xa0\x00\x00\x00\x00\x09\x10\xce\x90\x00\x00\x00\x00\x0a\x00\xcd\xa0\x00\x00\x00\x00\x0a\xf0\xb0\x90\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\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\x00\x00\x00\x00\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\x08\xff\xff\x9d\x90\x00\x0c\xff\xff\xab\xa0\x01\x10-00\x00PDT\x00PST\x00MST\x00MDT\x00\x0aMST7MDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xa0\xd6\x05W\x03\x00\x00W\x03\x00\x00\x0f\x00\x00\x00America/IqaluitTZif2\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\x00J\x00\x00\x00\x07\x00\x00\x00\x1c\xff\xff\xff\xff\xccl\xa1\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x08 \xc1p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x0a\x00\xa3p\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x04\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x06\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x01\x10\xff\xff\xab\xa0\x00\x14\xff\xff\xb9\xb0\x01\x18-00\x00EPT\x00EST\x00EDT\x00EWT\x00CST\x00CDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%J\xd5\xebS\x01\x00\x00S\x01\x00\x00\x0f\x00\x00\x00America/JamaicaTZif2\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\x16\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87#~\xff\xff\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\x07\x8d\x19p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x09\xad\x94\xf0\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xb8\x02\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0cLMT\x00KMT\x00EST\x00EDT\x00\x0aEST5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00utZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\x0d\x00\x00\x00America/JujuyTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xae\xb8\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xe2\xdb\xb0\x00\x00\x00\x00(\xee\x8a@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x04\x05\x04\x05\x03\x05\x04\x05\xff\xff\xc2\xc8\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xc9\x1c\xd4\xc6\x03\x00\x00\xc6\x03\x00\x00\x0e\x00\x00\x00America/JuneauTZif2\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\x00S\x00\x00\x00\x0a\x00\x00\x00&\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x872\xc5\xff\xff\xff\xff\xcb\x89\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\x0c\x10\x00\x00\x00\x00\x02x\x0b \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\x0a\x90\x00\x00\x00\x00\x06A\x09\xa0\x00\x00\x00\x00\x070\xec\x90\x00\x00\x00\x00\x07\x8dC\xa0\x00\x00\x00\x00\x09\x10\xce\x90\x00\x00\x00\x00\x09\xad\xbf \x00\x00\x00\x00\x0a\xf0\xb0\x90\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14Yc \x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\x07\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81\xcb\xa0\x00\x00\x00\x00\x22V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\x0a\x8e \x00\x00\x00\x00)\xde\xdd\xb0\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,\xd3\x8c\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\x07F0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\x0a0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\x08\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO\xcc\xb0\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x06\x02\x05\x02\x05\x02\x05\x07\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x00\x00\xd3{\x00\x00\xff\xff\x81\xfb\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10\xff\xff\x8f\x80\x01\x14\xff\xff\x81p\x00\x18\xff\xff\x8f\x80\x01\x1c\xff\xff\x81p\x00!LMT\x00PST\x00PWT\x00PPT\x00PDT\x00YDT\x00YST\x00AKDT\x00AKST\x00\x0aAKST9AKDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x1b\x00\x00\x00America/Kentucky/LouisvilleTZif2\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\x00u\x00\x00\x00\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa4s\xf7\x00\xff\xff\xff\xff\xa5\x16\x11p\xff\xff\xff\xff\xca\x0dN\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3u\xd7\x1c\xff\xff\xff\xff\xd3\xa4\x09p\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x1e\x90p\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x07\x8d\x19p\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x09\xad\x94\xf0\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf\x9a\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x1a|J\xcc\x03\x00\x00\xcc\x03\x00\x00\x1b\x00\x00\x00America/Kentucky/MonticelloTZif2\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\x00W\x00\x00\x00\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x0d\xf0\x00\x00\x00\x00\x00\x98\x0d\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x0cp\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xd0p\x00\x00\x00\x00\x07\x8d'\x80\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x09\xad\xa3\x00\x00\x00\x00\x00\x0a\xf0\x94p\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xb0\xf0\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x227p\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ac\xf0\x00\x00\x00\x00)\xde\xb3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xb0t\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xc7\xc0\x01\x14\xff\xff\xb9\xb0\x00\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EDT\x00EST\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x0f\x00\x00\x00America/Knox_INTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\xc2\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x0d\xf0\x00\x00\x00\x00\x00\x98\x0d\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x0cp\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xd0p\x00\x00\x00\x00\x07\x8d'\x80\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x09\xad\xa3\x00\x00\x00\x00\x00\x0a\xf0\x94p\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xb0\xf0\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x227p\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ac\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\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\x05\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\x05\x01\x02\x01\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00America/KralendijkTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad`\x12\xe9\xaa\x00\x00\x00\xaa\x00\x00\x00\x0e\x00\x00\x00America/La_PazTZif2\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\x03\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87\x1bd\xff\xff\xff\xff\xb8\x1e\x96\xe4\xff\xff\xff\xff\xb8\xee\xd5\xd4\x01\x02\x03\xff\xff\xc0\x1c\x00\x00\xff\xff\xc0\x1c\x00\x04\xff\xff\xce,\x01\x08\xff\xff\xc7\xc0\x00\x0cLMT\x00CMT\x00BST\x00-04\x00\x0a<-04>4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe7\xa1\x87\x1b\x01\x00\x00\x1b\x01\x00\x00\x0c\x00\x00\x00America/LimaTZif2\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\x10\x00\x00\x00\x04\x00\x00\x00\x0c\xff\xff\xff\xffi\x87#\xbc\xff\xff\xff\xff\x8ct@\xd4\xff\xff\xff\xff\xc3\xcfJP\xff\xff\xff\xff\xc4E\xe3@\xff\xff\xff\xff\xc5/J\xd0\xff\xff\xff\xff\xc6\x1f-\xc0\xff\xff\xff\xff\xc7\x0f,\xd0\xff\xff\xff\xff\xc7\xff\x0f\xc0\x00\x00\x00\x00\x1e\x18\xc4P\x00\x00\x00\x00\x1e\x8f]@\x00\x00\x00\x00\x1f\xf9\xf7\xd0\x00\x00\x00\x00 p\x90\xc0\x00\x00\x00\x00%\x9e\xe3\xd0\x00\x00\x00\x00&\x15|\xc0\x00\x00\x00\x00-%\x03P\x00\x00\x00\x00-\x9b\x9c@\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb7\xc4\x00\x00\xff\xff\xb7\xac\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08LMT\x00-04\x00-05\x00\x0a<-05>5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x22\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\x13\x00\x00\x00America/Los_AngelesTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\x1a\xc0\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xff\xcb\x89\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd6\xfet\x5c\xff\xff\xff\xff\xd8\x80\xad\x90\xff\xff\xff\xff\xda\xfe\xc3\x90\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\xde\xa5\x90\xff\xff\xff\xff\xdd\xa9\xac\x90\xff\xff\xff\xff\xde\xbe\x87\x90\xff\xff\xff\xff\xdf\x89\x8e\x90\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\x07\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8f\xd0\x90\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xb2\x90\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\x94\x90\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\x08\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\x0c\x10\x00\x00\x00\x00\x02x\x0b \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\x0a\x90\x00\x00\x00\x00\x06A\x09\xa0\x00\x00\x00\x00\x070\xec\x90\x00\x00\x00\x00\x07\x8dC\xa0\x00\x00\x00\x00\x09\x10\xce\x90\x00\x00\x00\x00\x09\xad\xbf \x00\x00\x00\x00\x0a\xf0\xb0\x90\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x91&\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00PWT\x00PPT\x00\x0aPST8PDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x12\x00\x00\x00America/LouisvilleTZif2\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\x00u\x00\x00\x00\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa4s\xf7\x00\xff\xff\xff\xff\xa5\x16\x11p\xff\xff\xff\xff\xca\x0dN\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3u\xd7\x1c\xff\xff\xff\xff\xd3\xa4\x09p\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x1e\x90p\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x07\x8d\x19p\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x09\xad\x94\xf0\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x01\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf\x9a\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00America/Lower_PrincesTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\x8c\x8b\x92\xf6\x01\x00\x00\xf6\x01\x00\x00\x0e\x00\x00\x00America/MaceioTZif2\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\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaah|\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xff\xdc\xb9Y \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xff\xde\x9b\xde \xff\xff\xff\xff\xdf\xdd\x9a0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\x0a\xd2\xb0\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1d\xc9\x8e0\x00\x00\x00\x00\x1ex\xd7\xa0\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3\xcf\xa0\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\x22\x0b\xc8\xa0\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x009\xf2J \x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\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\xff\xff\xde\x84\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\x08LMT\x00-02\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5s\xb3\x5c'\x01\x00\x00'\x01\x00\x00\x0f\x00\x00\x00America/ManaguaTZif2\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\x10\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffi\x87,d\xff\xff\xff\xff\xbd-H\xe8\x00\x00\x00\x00\x06Ct`\x00\x00\x00\x00\x09\xa4>P\x00\x00\x00\x00\x11Q\xf8\xe0\x00\x00\x00\x00\x11\xd4oP\x00\x00\x00\x00\x131\xda\xe0\x00\x00\x00\x00\x13\xb4QP\x00\x00\x00\x00)a\x91 \x00\x00\x00\x00*\xc1KP\x00\x00\x00\x00+C\xdd\xe0\x00\x00\x00\x002\xc9\xefP\x00\x00\x00\x00BX\xc0\xe0\x00\x00\x00\x00C?iP\x00\x00\x00\x00DTn\x80\x00\x00\x00\x00E\x1fY`\x01\x02\x03\x02\x04\x02\x04\x02\x03\x02\x03\x02\x04\x02\x04\x02\xff\xff\xaf\x1c\x00\x00\xff\xff\xaf\x18\x00\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x00\x0c\xff\xff\xb9\xb0\x01\x10LMT\x00MMT\x00CST\x00EST\x00CDT\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\x0e\x00\x00\x00America/ManausTZif2\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\x1f\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaa\x7fD\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xba\xde\x820\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\x08@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xff\xdc\xb9g0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xff\xde\x9b\xec0\xff\xff\xff\xff\xdf\xdd\xa8@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\x0d\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\x0a\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1d\xc9\x9c@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3\xdd\xb0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\x22\x0b\xd6\xb0\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\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\xff\xff\xc7\xbc\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\x08LMT\x00-03\x00-04\x00\x0a<-04>4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America/MarigotTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x17j\xd2\xb2\x00\x00\x00\xb2\x00\x00\x00\x12\x00\x00\x00America/MartiniqueTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffi\x87\x14\xc4\xff\xff\xff\xff\x91\xa3\xc8D\x00\x00\x00\x00\x13Mn@\x00\x00\x00\x00\x144\x16\xb0\x01\x02\x03\x02\xff\xff\xc6\xbc\x00\x00\xff\xff\xc6\xbc\x00\x04\xff\xff\xc7\xc0\x00\x09\xff\xff\xd5\xd0\x01\x0dLMT\x00FFMT\x00AST\x00ADT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00((i\xe4\xb5\x01\x00\x00\xb5\x01\x00\x00\x11\x00\x00\x00America/MatamorosTZif2\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\x03\x00\x00\x00\x0c\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\x9c\x97\x80\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\xff\xff\xa4\x98\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\x08LMT\x00CST\x00CDT\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xad=\x98\xce\x02\x00\x00\xce\x02\x00\x00\x10\x00\x00\x00America/MazatlanTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\x0c6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xff\xd8\x91\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\x22\x00\x00\x00\x00\x00M\x987\x10\x00\x00\x00\x00N\xad\x04\x00\x00\x00\x00\x00Ox\x19\x10\x00\x00\x00\x00P\x8c\xe6\x00\x00\x00\x00\x00Qa5\x90\x00\x00\x00\x00Rl\xc8\x00\x00\x00\x00\x00SA\x17\x90\x00\x00\x00\x00TL\xaa\x00\x00\x00\x00\x00U \xf9\x90\x00\x00\x00\x00V,\x8c\x00\x00\x00\x00\x00W\x00\xdb\x90\x00\x00\x00\x00X\x15\xa8\x80\x00\x00\x00\x00X\xe0\xbd\x90\x00\x00\x00\x00Y\xf5\x8a\x80\x00\x00\x00\x00Z\xc0\x9f\x90\x00\x00\x00\x00[\xd5l\x80\x00\x00\x00\x00\x5c\xa9\xbc\x10\x00\x00\x00\x00]\xb5N\x80\x00\x00\x00\x00^\x89\x9e\x10\x00\x00\x00\x00_\x950\x80\x00\x00\x00\x00`i\x80\x10\x00\x00\x00\x00a~M\x00\x00\x00\x00\x00bIb\x10\x00\x00\x00\x00c^/\x00\x01\x02\x01\x03\x01\x02\x01\x04\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\xff\xff\x9c<\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\x8f\x80\x00\x10LMT\x00MST\x00CST\x00MDT\x00PST\x00\x0aMST7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x92Z\x8c\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00America/MendozaTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xb2\x04\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'\x194@\x00\x00\x00\x00'\xcd\xc3\xb0\x00\x00\x00\x00(\xfag\xc0\x00\x00\x00\x00)\xb0H\xb0\x00\x00\x00\x00*\xe0\xe1@\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00@\xb0\x13\xb0\x00\x00\x00\x00AV>\xc0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x02\x03\x02\x03\x02\x04\x05\x03\x05\x02\x05\x04\x05\xff\xff\xbf|\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008O:\xbf\x95\x03\x00\x00\x95\x03\x00\x00\x11\x00\x00\x00America/MenomineeTZif2\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\x00R\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xffawIc\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\x08g\xf0\xff\xff\xff\xff\xfe\xb8+\x00\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xd0p\x00\x00\x00\x00\x07\x8d'\x80\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x09\xad\xa3\x00\x00\x00\x00\x00\x0a\xf0\x94p\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xb0\xf0\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x227p\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ac\xf0\x00\x00\x00\x00)\xde\xb3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;\xdb\xac\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x05\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xad\xdd\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xbd\x809\x8e\x02\x00\x00\x8e\x02\x00\x00\x0e\x00\x00\x00America/MeridaTZif2\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\x009\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\x16\x86\xd5`\x00\x00\x00\x00\x18LKP\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\x0b\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\x09\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00\xcd\x80\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00X\xe0\xaf\x80\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\x5c\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\x22p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\xff\xff\xab\xfc\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xb9\xb0\x01\x0cLMT\x00CST\x00EST\x00CDT\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\x81\xbfyS\x02\x00\x00S\x02\x00\x00\x12\x00\x00\x00America/MetlakatlaTZif2\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\x08\x00\x00\x00\x1e\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x870\x1a\xff\xff\xff\xff\xcb\x89\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\x0c\x10\x00\x00\x00\x00\x02x\x0b \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\x0a\x90\x00\x00\x00\x00\x06A\x09\xa0\x00\x00\x00\x00\x070\xec\x90\x00\x00\x00\x00\x07\x8dC\xa0\x00\x00\x00\x00\x09\x10\xce\x90\x00\x00\x00\x00\x09\xad\xbf \x00\x00\x00\x00\x0a\xf0\xb0\x90\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00V5\xe2\xa0\x00\x00\x00\x00V\xe5H0\x00\x00\x00\x00X\x1e\xff \x00\x00\x00\x00X\xc5*0\x00\x00\x00\x00Y\xfe\xe1 \x00\x00\x00\x00Z\xa5\x0c0\x00\x00\x00\x00[\xde\xc3 \x00\x00\x00\x00\x5cDF\xa0\x00\x00\x00\x00\x5c\x84\xee0\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x06\x07\x06\x07\x06\x07\x02\x06\x07\x00\x00\xd6&\x00\x00\xff\xff\x84\xa6\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10\xff\xff\x81p\x00\x14\xff\xff\x8f\x80\x01\x19LMT\x00PST\x00PWT\x00PPT\x00PDT\x00AKST\x00AKDT\x00\x0aAKST9AKDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\x08\x89\x8c\x05\x03\x00\x00\x05\x03\x00\x00\x13\x00\x00\x00America/Mexico_CityTZif2\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\x00D\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\x0c6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xc5\xde\xb0`\xff\xff\xff\xff\xc6\x974P\xff\xff\xff\xff\xc9U\xf1\xe0\xff\xff\xff\xff\xc9\xea\xddP\xff\xff\xff\xff\xcf\x02\xc6\xe0\xff\xff\xff\xff\xcf\xb7VP\xff\xff\xff\xff\xda\x99\x15\xe0\xff\xff\xff\xff\xdbv\x83\xd0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\x0b\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\x09\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00\xcd\x80\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00X\xe0\xaf\x80\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\x5c\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\x22p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x05\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\xff\xff\xa3\x0c\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00MST\x00CST\x00MDT\x00CDT\x00CWT\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7\x08\x5c\xc6&\x02\x00\x00&\x02\x00\x00\x10\x00\x00\x00America/MiquelonTZif2\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\x10\xff\xff\xff\xff\x91\xb68\xa8\x00\x00\x00\x00\x13nc\xc0\x00\x00\x00\x00 u\xe4\xd0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\x22U\xc6\xd0\x00\x00\x00\x00#j\x93\xc0\x00\x00\x00\x00$5\xa8\xd0\x00\x00\x00\x00%Ju\xc0\x00\x00\x00\x00&\x15\x8a\xd0\x00\x00\x00\x00'*W\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00)\x0a9\xc0\x00\x00\x00\x00)\xde\x89P\x00\x00\x00\x00*\xea\x1b\xc0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xd38@\x00\x00\x00\x00-\x9eMP\x00\x00\x00\x00.\xb3\x1a@\x00\x00\x00\x00/~/P\x00\x00\x00\x000\x92\xfc@\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002r\xde@\x00\x00\x00\x003G-\xd0\x00\x00\x00\x004R\xc0@\x00\x00\x00\x005'\x0f\xd0\x00\x00\x00\x0062\xa2@\x00\x00\x00\x007\x06\xf1\xd0\x00\x00\x00\x008\x1b\xbe\xc0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xa0\xc0\x00\x00\x00\x00:\xc6\xb5\xd0\x00\x00\x00\x00;\xdb\x82\xc0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbd\xc0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bF\xc0\x00\x00\x00\x00@o\x96P\x00\x00\x00\x00A\x84c@\x00\x00\x00\x00BOxP\x00\x00\x00\x00CdE@\x00\x00\x00\x00D/ZP\x00\x00\x00\x00ED'@\x00\x00\x00\x00E\xf3\x8c\xd0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xcbX\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x00\x08\xff\xff\xe3\xe0\x01\x0cLMT\x00AST\x00-03\x00-02\x00\x0a<-03>3<-02>,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\xf9\xc0\x1e\xd5\x05\x00\x00\xd5\x05\x00\x00\x0f\x00\x00\x00America/MonctonTZif2\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\x92\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x1e\xed\xbc\xff\xff\xff\xff\x80\xf1\xb6P\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xff\xbb<8\xd0\xff\xff\xff\xff\xbb\xb4#@\xff\xff\xff\xff\xbd\x1c\x1a\xd0\xff\xff\xff\xff\xbd\x94\x05@\xff\xff\xff\xff\xbe\xfb\xfc\xd0\xff\xff\xff\xff\xbfs\xe7@\xff\xff\xff\xff\xc0\xdb\xde\xd0\xff\xff\xff\xff\xc1S\xc9@\xff\xff\xff\xff\xc2\xbb\xc0\xd0\xff\xff\xff\xff\xc33\xab@\xff\xff\xff\xff\xc4\x9b\xa2\xd0\xff\xff\xff\xff\xc5\x13\x8d@\xff\xff\xff\xff\xc6p\xf8\xd0\xff\xff\xff\xff\xc7\x0d\xcd@\xff\xff\xff\xff\xc8H\xf1\xd0\xff\xff\xff\xff\xc8\xed\xaf@\xff\xff\xff\xff\xca\x16^\xd0\xff\xff\xff\xff\xca\xd6\xcb\xc0\xff\xff\xff\xff\xcb\x88\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xd3u\xd6\xe0\xff\xff\xff\xff\xd4@\xcf\xd0\xff\xff\xff\xff\xd5U\xb8\xe0\xff\xff\xff\xff\xd6 \xb1\xd0\xff\xff\xff\xff\xd75\x9a\xe0\xff\xff\xff\xff\xd8\x00\x93\xd0\xff\xff\xff\xff\xd9\x15|\xe0\xff\xff\xff\xff\xd9\xe0u\xd0\xff\xff\xff\xff\xda\xfe\x99`\xff\xff\xff\xff\xdb\xc0W\xd0\xff\xff\xff\xff\xdc\xde{`\xff\xff\xff\xff\xdd\xa9tP\xff\xff\xff\xff\xde\xbe]`\xff\xff\xff\xff\xdf\x89VP\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\xff\xff\xff\xff\xe2~!`\xff\xff\xff\xff\xe3I\x1aP\xff\xff\xff\xff\xe4^\x03`\xff\xff\xff\xff\xe5(\xfcP\xff\xff\xff\xff\xe6G\x1f\xe0\xff\xff\xff\xff\xe7\x12\x18\xd0\xff\xff\xff\xff\xe8'\x01\xe0\xff\xff\xff\xff\xe9\x16\xe4\xd0\xff\xff\xff\xff\xea\x06\xe3\xe0\xff\xff\xff\xff\xea\xf6\xc6\xd0\xff\xff\xff\xff\xeb\xe6\xc5\xe0\xff\xff\xff\xff\xec\xd6\xa8\xd0\xff\xff\xff\xff\xed\xc6\xa7\xe0\xff\xff\xff\xff\xee\xbf\xc5P\xff\xff\xff\xff\xef\xaf\xc4`\xff\xff\xff\xff\xf0\x9f\xa7P\xff\xff\xff\xff\xf1\x8f\xa6`\xff\xff\xff\xff\xf2\x7f\x89P\xff\xff\xff\xff\xf3o\x88`\xff\xff\xff\xff\xf4_kP\xff\xff\xff\xff\xf5Oj`\xff\xff\xff\xff\xf6?MP\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(i\xd0\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\x08K\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x08 \xb3`\x00\x00\x00\x00\x09\x10\x96P\x00\x00\x00\x00\x0a\x00\x95`\x00\x00\x00\x00\x0a\xf0xP\x00\x00\x00\x00\x0b\xe0w`\x00\x00\x00\x00\x0c\xd9\x94\xd0\x00\x00\x00\x00\x0d\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\x22\x1bP\x00\x00\x00\x00\x19\x08\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\x22U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\x0aG\xd0\x00\x00\x00\x00)\xde\x97`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbe]|\x00\x00\x00\x00,\xd3*l\x00\x00\x00\x00-\x9e?|\x00\x00\x00\x00.\xb3\x0cl\x00\x00\x00\x00/~!|\x00\x00\x00\x000\x92\xeel\x00\x00\x00\x001g=\xfc\x00\x00\x00\x002r\xd0l\x00\x00\x00\x003G\x1f\xfc\x00\x00\x00\x004R\xb2l\x00\x00\x00\x005'\x01\xfc\x00\x00\x00\x0062\x94l\x00\x00\x00\x007\x06\xe3\xfc\x00\x00\x00\x008\x1b\xb0\xec\x00\x00\x00\x008\xe6\xc5\xfc\x00\x00\x00\x009\xfb\x92\xec\x00\x00\x00\x00:\xc6\xa7\xfc\x00\x00\x00\x00;\xdbt\xec\x00\x00\x00\x00<\xaf\xc4|\x00\x00\x00\x00=\xbbV\xec\x00\x00\x00\x00>\x8f\xa6|\x00\x00\x00\x00?\x9b8\xec\x00\x00\x00\x00@o\x88|\x00\x00\x00\x00A\x84Ul\x00\x00\x00\x00BOj|\x00\x00\x00\x00Cd7l\x00\x00\x00\x00D/L|\x00\x00\x00\x00ED\x19l\x00\x00\x00\x00E\xf3\x9a\xe0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xc3D\x00\x00\xff\xff\xb9\xb0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xc7\xc0\x00\x0c\xff\xff\xd5\xd0\x01\x10\xff\xff\xd5\xd0\x01\x14LMT\x00EST\x00ADT\x00AST\x00AWT\x00APT\x00\x0aAST4ADT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L+\xe3u\x84\x02\x00\x00\x84\x02\x00\x00\x11\x00\x00\x00America/MonterreyTZif2\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\x009\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\xa5\xb6\xda`\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\x0b\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\x09\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00\xcd\x80\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00X\xe0\xaf\x80\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\x5c\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\x22p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\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\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa1\xf4\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\x08LMT\x00CST\x00CDT\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x98\x00\x08\xc9\x03\x00\x00\xc9\x03\x00\x00\x12\x00\x00\x00America/MontevideoTZif2\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\x00V\x00\x00\x00\x09\x00\x00\x00&\xff\xff\xff\xff\x8c4\xe53\xff\xff\xff\xff\xa2\x92\x87\xb3\xff\xff\xff\xff\xa8\xff\xdb@\xff\xff\xff\xff\xa9\xf1\x0f\xb0\xff\xff\xff\xff\xaa\xe2Y8\xff\xff\xff\xff\xab\xd2C0\xff\xff\xff\xff\xac\xc3\x8c\xb8\xff\xff\xff\xff\xad\xb3v\xb0\xff\xff\xff\xff\xbb\xf4\xb5\xb8\xff\xff\xff\xff\xbc\xbf\xb5\xb0\xff\xff\xff\xff\xbd\xd4\x97\xb8\xff\xff\xff\xff\xbe\x9f\x97\xb0\xff\xff\xff\xff\xbf\xb4y\xb8\xff\xff\xff\xff\xc0\x7fy\xb0\xff\xff\xff\xff\xc1\x94[\xb8\xff\xff\xff\xff\xc2_[\xb0\xff\xff\xff\xff\xc3}x8\xff\xff\xff\xff\xc4?=\xb0\xff\xff\xff\xff\xc5]Z8\xff\xff\xff\xff\xc6\x1f\x1f\xb0\xff\xff\xff\xff\xc7\x18R8\xff\xff\xff\xff\xc8\x08<0\xff\xff\xff\xff\xc9\x1d\x1e8\xff\xff\xff\xff\xc9\xe8\x1e0\xff\xff\xff\xff\xca\x8b\x9f8\xff\xff\xff\xff\xcd\x1e\xc60\xff\xff\xff\xff\xcd\x95f(\xff\xff\xff\xff\xec\x0b\x85\xb0\xff\xff\xff\xff\xec\xf25(\xff\xff\xff\xff\xedEJ\xb0\xff\xff\xff\xff\xed\x85\xd6 \xff\xff\xff\xff\xf7\x13r\xb0\xff\xff\xff\xff\xf7\xfa\x1b \xff\xff\xff\xff\xfc\xfe>0\xff\xff\xff\xff\xfd\xf6\x11(\x00\x00\x00\x00\x00\x96u0\x00\x00\x00\x00\x00\xd8R \x00\x00\x00\x00\x04W\x8a\xb0\x00\x00\x00\x00\x04\xc6:\xa0\x00\x00\x00\x00\x07\x96\x1b\xb0\x00\x00\x00\x00\x07\xdf\xda\x98\x00\x00\x00\x00\x08\xc6\x9f(\x00\x00\x00\x00\x09ZN0\x00\x00\x00\x00\x09\xdbs \x00\x00\x00\x00\x0d\x1a\x120\x00\x00\x00\x00\x0d\x7f\x87\xa0\x00\x00\x00\x00\x0e\xe7\x7f0\x00\x00\x00\x00\x0f_i\xa0\x00\x00\x00\x00\x10\xd9\xd60\x00\x00\x00\x00\x11?K\xa0\x00\x00\x00\x00\x11\x89-\xb0\x00\x00\x00\x00\x131\xa2\xa0\x00\x00\x00\x00!\xc3T0\x00\x00\x00\x00\x22'x \x00\x00\x00\x00#\xa1\xe4\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%Jg\xb0\x00\x00\x00\x00%\xe7< \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x0a+\xb0\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x90\x1c\xa0\x00\x00\x00\x00AL\xf60\x00\x00\x00\x00BF/\xc0\x00\x00\x00\x00CH\xa3\xd0\x00\x00\x00\x00D\x13\x9c\xc0\x00\x00\x00\x00E\x1fKP\x00\x00\x00\x00E\xf3~\xc0\x00\x00\x00\x00G\x08g\xd0\x00\x00\x00\x00G\xd3`\xc0\x00\x00\x00\x00H\xe8I\xd0\x00\x00\x00\x00I\xb3B\xc0\x00\x00\x00\x00J\xc8+\xd0\x00\x00\x00\x00K\x9c_@\x00\x00\x00\x00L\xa8\x0d\xd0\x00\x00\x00\x00M|A@\x00\x00\x00\x00N\x87\xef\xd0\x00\x00\x00\x00O\x5c#@\x00\x00\x00\x00Pq\x0cP\x00\x00\x00\x00Q<\x05@\x00\x00\x00\x00RP\xeeP\x00\x00\x00\x00S\x1b\xe7@\x00\x00\x00\x00T0\xd0P\x00\x00\x00\x00T\xfb\xc9@\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\x06\x05\x07\x05\x07\x05\x06\x05\x07\x05\x07\x05\x08\x06\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\xff\xff\xcbM\x00\x00\xff\xff\xcbM\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xce\xc8\x00\x0c\xff\xff\xd5\xd0\x01\x12\xff\xff\xd5\xd0\x00\x12\xff\xff\xdc\xd8\x01\x16\xff\xff\xe3\xe0\x01\x1c\xff\xff\xea\xe8\x01 LMT\x00MMT\x00-04\x00-0330\x00-03\x00-0230\x00-02\x00-0130\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x10\x00\x00\x00America/MontrealTZif2\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\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\x0cN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad\xdc\x8dp\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\x5c\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbe\xc4\xb9\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\xc2\x84}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xcb\x88\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdc\xde\x89p\xff\xff\xff\xff\xdd\xa9\x82`\xff\xff\xff\xff\xde\xbekp\xff\xff\xff\xff\xdf\x89d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\x0a`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xec\xd6\xb6\xe0\xff\xff\xff\xff\xed\xc6\xb5\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\x08Y\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x08 \xc1p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x0a\x00\xa3p\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00America/MontserratTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00\x00\x00America/NassauTZif2\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\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\x0cN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad\xdc\x8dp\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\x5c\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbe\xc4\xb9\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\xc2\x84}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xcb\x88\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdc\xde\x89p\xff\xff\xff\xff\xdd\xa9\x82`\xff\xff\xff\xff\xde\xbekp\xff\xff\xff\xff\xdf\x89d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\x0a`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xec\xd6\xb6\xe0\xff\xff\xff\xff\xed\xc6\xb5\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\x08Y\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x08 \xc1p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x0a\x00\xa3p\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\x10\x00\x00\x00America/New_YorkTZif2\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\xaf\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x03\xf0\x90\xff\xff\xff\xff\x9e\xa6\x1ep\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x86\x00p\xff\xff\xff\xff\xa1\x9a\xcd`\xff\xff\xff\xff\xa2e\xe2p\xff\xff\xff\xff\xa3\x83\xe9\xe0\xff\xff\xff\xff\xa4j\xaep\xff\xff\xff\xff\xa55\xa7`\xff\xff\xff\xff\xa6S\xca\xf0\xff\xff\xff\xff\xa7\x15\x89`\xff\xff\xff\xff\xa83\xac\xf0\xff\xff\xff\xff\xa8\xfe\xa5\xe0\xff\xff\xff\xff\xaa\x13\x8e\xf0\xff\xff\xff\xff\xaa\xde\x87\xe0\xff\xff\xff\xff\xab\xf3p\xf0\xff\xff\xff\xff\xac\xbei\xe0\xff\xff\xff\xff\xad\xd3R\xf0\xff\xff\xff\xff\xae\x9eK\xe0\xff\xff\xff\xff\xaf\xb34\xf0\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\x5c\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9\x1b\xd9p\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xc6\xb4`\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbe\xc4\xb9\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\xc2\x84}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xc8\xf8W`\xff\xff\xff\xff\xca\x0d@p\xff\xff\xff\xff\xca\xd89`\xff\xff\xff\xff\xcb\x88\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xc6\xf0\xff\xff\xff\xff\xd6 \xbf\xe0\xff\xff\xff\xff\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xd9\x15\x8a\xf0\xff\xff\xff\xff\xd9\xe0\x83\xe0\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdb\xc0e\xe0\xff\xff\xff\xff\xdc\xde\x89p\xff\xff\xff\xff\xdd\xa9\x82`\xff\xff\xff\xff\xde\xbekp\xff\xff\xff\xff\xdf\x89d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5W.\xe0\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe77\x10\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xec\xd6\xb6\xe0\xff\xff\xff\xff\xed\xc6\xb5\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\x08Y\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x07\x8d\x19p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x09\xad\x94\xf0\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xba\x9e\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x00\x00America/NipigonTZif2\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\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\x0cN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad\xdc\x8dp\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\x5c\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbe\xc4\xb9\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\xc2\x84}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xcb\x88\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdc\xde\x89p\xff\xff\xff\xff\xdd\xa9\x82`\xff\xff\xff\xff\xde\xbekp\xff\xff\xff\xff\xdf\x89d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\x0a`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xec\xd6\xb6\xe0\xff\xff\xff\xff\xed\xc6\xb5\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\x08Y\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x08 \xc1p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x0a\x00\xa3p\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\xab\xd5\xf9\xcf\x03\x00\x00\xcf\x03\x00\x00\x0c\x00\x00\x00America/NomeTZif2\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\x00T\x00\x00\x00\x0a\x00\x00\x00&\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87O\xd2\xff\xff\xff\xff\xcb\x89D\xd0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\x071\x16\xc0\x00\x00\x00\x00\x07\x8dm\xd0\x00\x00\x00\x00\x09\x10\xf8\xc0\x00\x00\x00\x00\x09\xad\xe9P\x00\x00\x00\x00\x0a\xf0\xda\xc0\x00\x00\x00\x00\x0b\xe0\xd9\xd0\x00\x00\x00\x00\x0c\xd9\xf7@\x00\x00\x00\x00\x0d\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00\x18\x22}\xc0\x00\x00\x00\x00\x19\x09BP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\x07\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81\xcb\xa0\x00\x00\x00\x00\x22V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\x0a\x8e \x00\x00\x00\x00)\xde\xdd\xb0\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,\xd3\x8c\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\x07F0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\x0a0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\x08\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO\xcc\xb0\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x07\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x00\x00\xb6n\x00\x00\xff\xffd\xee\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\x08\xff\xffs`\x01\x0c\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xff\x81p\x00\x18\xff\xff\x8f\x80\x01\x1c\xff\xff\x81p\x00!LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00YST\x00AKDT\x00AKST\x00\x0aAKST9AKDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x0f\x00\x00\x00America/NoronhaTZif2\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\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaaed\xff\xff\xff\xff\xb8\x0f;\xd0\xff\xff\xff\xff\xb8\xfd2\x90\xff\xff\xff\xff\xb9\xf1& \xff\xff\xff\xff\xba\xdef\x10\xff\xff\xff\xff\xda8\xa0 \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdc\x19\xd3\xa0\xff\xff\xff\xff\xdc\xb9K\x10\xff\xff\xff\xff\xdd\xfb\x07 \xff\xff\xff\xff\xde\x9b\xd0\x10\xff\xff\xff\xff\xdf\xdd\x8c \xff\xff\xff\xff\xe0T%\x10\xff\xff\xff\xff\xf4\x97\xf1\xa0\xff\xff\xff\xff\xf5\x05P\x10\xff\xff\xff\xff\xf6\xc0V \xff\xff\xff\xff\xf7\x0e\x10\x90\xff\xff\xff\xff\xf8Q\x1e \xff\xff\xff\xff\xf8\xc7\xb7\x10\xff\xff\xff\xff\xfa\x0a\xc4\xa0\xff\xff\xff\xff\xfa\xa8\xea\x90\xff\xff\xff\xff\xfb\xeb\xf8 \xff\xff\xff\xff\xfc\x8bo\x90\x00\x00\x00\x00\x1d\xc9\x80 \x00\x00\x00\x00\x1ex\xc9\x90\x00\x00\x00\x00\x1f\xa0'\xa0\x00\x00\x00\x00 3\xc1\x90\x00\x00\x00\x00!\x81[ \x00\x00\x00\x00\x22\x0b\xba\x90\x00\x00\x00\x00#X\x02\xa0\x00\x00\x00\x00#\xe2b\x10\x00\x00\x00\x00%7\xe4\xa0\x00\x00\x00\x00%\xd4\xb9\x10\x00\x00\x00\x007\xf6\xb8\xa0\x00\x00\x00\x008\xb8w\x10\x00\x00\x00\x009\xdf\xd5 \x00\x00\x00\x009\xe9\x01\x90\x00\x00\x00\x00;\xc8\xf1\xa0\x00\x00\x00\x00<o\x00\x90\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\xff\xff\xe1\x9c\x00\x00\xff\xff\xf1\xf0\x01\x04\xff\xff\xe3\xe0\x00\x08LMT\x00-01\x00-02\x00\x0a<-02>2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7.\xb6*\x13\x04\x00\x00\x13\x04\x00\x00\x1b\x00\x00\x00America/North_Dakota/BeulahTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x04\x0c\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x07\x8d5\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x09\xad\xb1\x10\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x00\x00\x00\x00G-|\x00\x00\x00\x00\x00G\xd3\xa7\x10\x00\x00\x00\x00I\x0d^\x00\x00\x00\x00\x00I\xb3\x89\x10\x00\x00\x00\x00J\xed@\x00\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\x5c\x80\x02\x01\x02\x01\x02\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\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\x05\xff\xff\xa0\x95\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\xeam\xef\xde\x03\x00\x00\xde\x03\x00\x00\x1b\x00\x00\x00America/North_Dakota/CenterTZif2\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\x00Y\x00\x00\x00\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x04\x0c\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x07\x8d5\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x09\xad\xb1\x10\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;\xdb\xac\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\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\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xa1\x08\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CDT\x00CST\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x1b\x8b(\xde\x03\x00\x00\xde\x03\x00\x00\x1e\x00\x00\x00America/North_Dakota/New_SalemTZif2\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\x00Y\x00\x00\x00\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x04\x0c\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x07\x8d5\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x09\xad\xb1\x10\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xa0\xed\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10\xff\xff\xb9\xb0\x01\x14\xff\xff\xab\xa0\x00\x18LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CDT\x00CST\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95'O\xce\xc5\x03\x00\x00\xc5\x03\x00\x00\x0c\x00\x00\x00America/NuukTZif3\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\x00Y\x00\x00\x00\x04\x00\x00\x00\x0c\xff\xff\xff\xff\x9b\x80h\x00\x00\x00\x00\x00\x13M|P\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05\xc9\x90\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L\xcc\xbf\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00X\x15F\x10\x00\x00\x00\x00X\xd7\x12\x90\x00\x00\x00\x00Y\xf5(\x10\x00\x00\x00\x00Z\xb6\xf4\x90\x00\x00\x00\x00[\xd5\x0a\x10\x00\x00\x00\x00\x5c\xa0\x11\x10\x00\x00\x00\x00]\xb4\xec\x10\x00\x00\x00\x00^\x7f\xf3\x10\x00\x00\x00\x00_\x94\xce\x10\x00\x00\x00\x00`_\xd5\x10\x00\x00\x00\x00a}\xea\x90\x00\x00\x00\x00b?\xb7\x10\x00\x00\x00\x00c]\xcc\x90\x00\x00\x00\x00d\x1f\x99\x10\x00\x00\x00\x00e=\xae\x90\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\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\x03\xff\xff\xcf\x80\x00\x00\xff\xff\xd5\xd0\x00\x04\xff\xff\xe3\xe0\x01\x08\xff\xff\xe3\xe0\x00\x08LMT\x00-03\x00-02\x00\x0a<-02>2<-01>,M3.5.0/-1,M10.5.0/0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe5\x9e<\xc5\x02\x00\x00\xc5\x02\x00\x00\x0f\x00\x00\x00America/OjinagaTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\x0c6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\x9c\xa5\x90\x00\x00\x00\x00L\xd6\x5c\x80\x00\x00\x00\x00M|\x87\x90\x00\x00\x00\x00N\xb6>\x80\x00\x00\x00\x00O\x5ci\x90\x00\x00\x00\x00P\x96 \x80\x00\x00\x00\x00Q<K\x90\x00\x00\x00\x00Rv\x02\x80\x00\x00\x00\x00S\x1c-\x90\x00\x00\x00\x00TU\xe4\x80\x00\x00\x00\x00T\xfc\x0f\x90\x00\x00\x00\x00V5\xc6\x80\x00\x00\x00\x00V\xe5,\x10\x00\x00\x00\x00X\x1e\xe3\x00\x00\x00\x00\x00X\xc5\x0e\x10\x00\x00\x00\x00Y\xfe\xc5\x00\x00\x00\x00\x00Z\xa4\xf0\x10\x00\x00\x00\x00[\xde\xa7\x00\x00\x00\x00\x00\x5c\x84\xd2\x10\x00\x00\x00\x00]\xbe\x89\x00\x00\x00\x00\x00^d\xb4\x10\x00\x00\x00\x00_\x9ek\x00\x00\x00\x00\x00`M\xd0\x90\x00\x00\x00\x00a\x87\x87\x80\x00\x00\x00\x00b-\xb2\x90\x00\x00\x00\x00c^/\x00\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x02\xff\xff\x9e\x1c\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xb9\xb0\x01\x10LMT\x00MST\x00CST\x00MDT\x00CDT\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xbe\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x00\x00America/PanamaTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xffi\x87&\x10\xff\xff\xff\xff\x8b\xf4a\xe8\x01\x02\xff\xff\xb5p\x00\x00\xff\xff\xb5\x18\x00\x04\xff\xff\xb9\xb0\x00\x08LMT\x00CMT\x00EST\x00\x0aEST5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xa0\xd6\x05W\x03\x00\x00W\x03\x00\x00\x13\x00\x00\x00America/PangnirtungTZif2\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\x00J\x00\x00\x00\x07\x00\x00\x00\x1c\xff\xff\xff\xff\xccl\xa1\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x08 \xc1p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x0a\x00\xa3p\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x04\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x06\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x01\x10\xff\xff\xab\xa0\x00\x14\xff\xff\xb9\xb0\x01\x18-00\x00EPT\x00EST\x00EDT\x00EWT\x00CST\x00CDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\xf9\x1d\xc9\xbb\x00\x00\x00\xbb\x00\x00\x00\x12\x00\x00\x00America/ParamariboTZif2\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\x04\x00\x00\x00\x05\x00\x00\x00\x12\xff\xff\xff\xff\x91\x05\x8e\xb8\xff\xff\xff\xff\xbe*K\xc4\xff\xff\xff\xff\xd2b,\xb4\x00\x00\x00\x00\x1b\xbe1\xb8\x01\x02\x03\x04\xff\xff\xccH\x00\x00\xff\xff\xcc<\x00\x04\xff\xff\xccL\x00\x04\xff\xff\xce\xc8\x00\x08\xff\xff\xd5\xd0\x00\x0eLMT\x00PMT\x00-0330\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\xb8\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x00\x00America/PhoenixTZif2\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\x0b\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x04\x0c\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xcf\x17\xdf\x1c\xff\xff\xff\xff\xcf\x8f\xe5\xac\xff\xff\xff\xff\xd0\x81\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0cLMT\x00MDT\x00MST\x00MWT\x00\x0aMST7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4T\xbd\xeb5\x02\x00\x005\x02\x00\x00\x16\x00\x00\x00America/Port-au-PrinceTZif2\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\x11\xff\xff\xff\xffi\x87\x1fP\xff\xff\xff\xff\x9cnq\xfc\x00\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x1a\x01\xef@\x00\x00\x00\x00\x1a\xf1\xeeP\x00\x00\x00\x00\x1b\xe1\xd1@\x00\x00\x00\x00\x1c\xd1\xd0P\x00\x00\x00\x00\x1d\xc1\xb3@\x00\x00\x00\x00\x1e\xb1\xb2P\x00\x00\x00\x00\x1f\xa1\x95@\x00\x00\x00\x00 \x91\x94P\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\x22U\xd4\xe0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\x97`\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x00BOxP\x00\x00\x00\x00CdE@\x00\x00\x00\x00D/ZP\x00\x00\x00\x00ED'@\x00\x00\x00\x00O\x5cMp\x00\x00\x00\x00P\x96\x04`\x00\x00\x00\x00Q</p\x00\x00\x00\x00Ru\xe6`\x00\x00\x00\x00S\x1c\x11p\x00\x00\x00\x00TU\xc8`\x00\x00\x00\x00T\xfb\xf3p\x00\x00\x00\x00V5\xaa`\x00\x00\x00\x00X\xc4\xf1\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xbc0\x00\x00\xff\xff\xbcD\x00\x04\xff\xff\xc7\xc0\x01\x09\xff\xff\xb9\xb0\x00\x0dLMT\x00PPMT\x00EDT\x00EST\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00America/Port_of_SpainTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x00\x00America/Porto_AcreTZif2\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\x1f\x00\x00\x00\x04\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\x5c\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xba\xde\x90@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xff\xdc\xb9u@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xff\xde\x9b\xfa@\xff\xff\xff\xff\xdf\xdd\xb6P\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\x0a\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\x22P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1d\xc9\xaaP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\x22\x0b\xe4\xc0\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\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\x03\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\x0a<-05>5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x81-\xa9\x8a\x01\x00\x00\x8a\x01\x00\x00\x13\x00\x00\x00America/Porto_VelhoTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaa\x82\xe8\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xba\xde\x820\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\x08@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xff\xdc\xb9g0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xff\xde\x9b\xec0\xff\xff\xff\xff\xdf\xdd\xa8@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\x0d\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\x0a\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1d\xc9\x9c@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3\xdd\xb0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\x22\x0b\xd6\xb0\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\xff\xff\xc4\x18\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\x08LMT\x00-03\x00-04\x00\x0a<-04>4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x13\x00\x00\x00America/Puerto_RicoTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x13\x9b\xb1\xc2\x04\x00\x00\xc2\x04\x00\x00\x14\x00\x00\x00America/Punta_ArenasTZif2\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\x00u\x00\x00\x00\x07\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d\xfc\xff\xff\xff\xff\x8f0GE\xff\xff\xff\xff\x9b\x5c\xe5P\xff\xff\xff\xff\x9f|\xe2\xc5\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^w\xc5\xff\xff\xff\xff\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\x224P\xff\xff\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\x5c\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff\xff\xd4\x17\xe3@\xff\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00r\xdc\xb0\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\x0d\xb0\x00\x00\x00\x00\x07\x0b\xbc@\x00\x00\x00\x00\x07\xdf\xef\xb0\x00\x00\x00\x00\x08\xfe\x13@\x00\x00\x00\x00\x09\xbf\xd1\xb0\x00\x00\x00\x00\x0a\xdd\xf5@\x00\x00\x00\x00\x0b\xa8\xee0\x00\x00\x00\x00\x0c\xbd\xd7@\x00\x00\x00\x00\x0d\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\x5c@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\x229\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'\xd9\xa10\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)\xc2\xbd\xb0\x00\x00\x00\x00*\xd7\xa6\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\x0bD0\x00\x00\x00\x006\x0d\xb8@\x00\x00\x00\x007\x06\xd5\xb0\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\x080\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\x0d\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@S\xca\xb0\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\x070\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\x5cr\xb0\x00\x00\x00\x00T\x0b\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00XC\x86\xb0\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x04\x02\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x06\xff\xff\xbd\x84\x00\x00\xff\xff\xbd\xbb\x00\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x00\x0c\xff\xff\xc7\xc0\x01\x0c\xff\xff\xd5\xd0\x01\x10\xff\xff\xd5\xd0\x00\x10LMT\x00SMT\x00-05\x00-04\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x13\x00\x00\x00America/Rainy_RiverTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xffd\xe4\xb0\x94\xff\xff\xff\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9b\xc3\xbaP\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xc2\xa0;\x80\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3\x88h\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xdb\x00\x07\x00\xff\xff\xff\xff\xdb\xc8\x5c\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\x91\xbc\xf0\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\x08v\x00\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x0d\x00\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x08 \xcf\x80\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x0a\x00\xb1\x80\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xb3\x80\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa4\xec\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10LMT\x00CDT\x00CST\x00CWT\x00CPT\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xdfH\x0d'\x03\x00\x00'\x03\x00\x00\x14\x00\x00\x00America/Rankin_InletTZif2\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\x00H\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xe7\x8cn\x00\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xd0p\x00\x00\x00\x00\x08 \xcf\x80\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x0a\x00\xb1\x80\x00\x00\x00\x00\x0a\xf0\x94p\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xb0\xf0\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x227p\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ac\xf0\x00\x00\x00\x00)\xde\xb3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;\xdb\xac\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\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\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x00\x00\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x00\x0c-00\x00CDT\x00CST\x00EST\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x03u\xf3\xe4\x01\x00\x00\xe4\x01\x00\x00\x0e\x00\x00\x00America/RecifeTZif2\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\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaag\xb8\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xff\xdc\xb9Y \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xff\xde\x9b\xde \xff\xff\xff\xff\xdf\xdd\x9a0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4\x97\xff\xb0\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\x0a\xd2\xb0\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1d\xc9\x8e0\x00\x00\x00\x00\x1ex\xd7\xa0\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3\xcf\xa0\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\x22\x0b\xc8\xa0\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x009\xe9\x0f\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\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\xff\xff\xdfH\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\x08LMT\x00-02\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc2\x96dK~\x02\x00\x00~\x02\x00\x00\x0e\x00\x00\x00America/ReginaTZif2\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\x005\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x86\xfd\x93\x1c\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xb5eO\xf0\xff\xff\xff\xff\xb60H\xe0\xff\xff\xff\xff\xb7E1\xf0\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xf0\x0c\xe0\xff\xff\xff\xff\xbb\x0e0p\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xee\x12p\xff\xff\xff\xff\xbd\xb9\x0b`\xff\xff\xff\xff\xc2r\x08\xf0\xff\xff\xff\xff\xc3a\xeb\xe0\xff\xff\xff\xff\xc4Q\xea\xf0\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc61\xcc\xf0\xff\xff\xff\xff\xc7!\xaf\xe0\xff\xff\xff\xff\xc8\x1a\xe9p\xff\xff\xff\xff\xc9\x0a\xcc`\xff\xff\xff\xff\xc9\xfa\xcbp\xff\xff\xff\xff\xca\xea\xae`\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3c\x8c\x10\xff\xff\xff\xff\xd4So\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xda\xfe\xc3\x90\xff\xff\xff\xff\xdb\xc0\x82\x00\xff\xff\xff\xff\xdc\xde\xa5\x90\xff\xff\xff\xff\xdd\xa9\x9e\x80\xff\xff\xff\xff\xde\xbe\x87\x90\xff\xff\xff\xff\xdf\x89\x80\x80\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ib\x80\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3ID\x80\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)&\x80\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12C\x00\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf2%\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\x05\xff\xff\x9d\xe4\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0I~D'\x03\x00\x00'\x03\x00\x00\x10\x00\x00\x00America/ResoluteTZif2\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\x00H\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xd5\xfb\x81\x80\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xd0p\x00\x00\x00\x00\x08 \xcf\x80\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x0a\x00\xb1\x80\x00\x00\x00\x00\x0a\xf0\x94p\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xb0\xf0\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x227p\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ac\xf0\x00\x00\x00\x00)\xde\xb3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;\xdb\xac\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\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\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x00\x00\x00\x00\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x00\x0c-00\x00CDT\x00CST\x00EST\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x00\x00America/Rio_BrancoTZif2\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\x1f\x00\x00\x00\x04\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\x5c\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xba\xde\x90@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xff\xdc\xb9u@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xff\xde\x9b\xfa@\xff\xff\xff\xff\xdf\xdd\xb6P\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\x0a\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\x22P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1d\xc9\xaaP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\x22\x0b\xe4\xc0\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\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\x03\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\x0a<-05>5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00America/RosarioTZif2\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\x06\x00\x00\x00\x14\xff\xff\xff\xffr\x9c\xad\xb0\xff\xff\xff\xff\xa2\x92\x8f0\xff\xff\xff\xff\xb6{R@\xff\xff\xff\xff\xb7\x1a\xc9\xb0\xff\xff\xff\xff\xb8\x1e\x8f@\xff\xff\xff\xff\xb8\xd4p0\xff\xff\xff\xff\xba\x17}\xc0\xff\xff\xff\xff\xba\xb5\xa3\xb0\xff\xff\xff\xff\xbb\xf8\xb1@\xff\xff\xff\xff\xbc\x96\xd70\xff\xff\xff\xff\xbd\xd9\xe4\xc0\xff\xff\xff\xff\xbex\x0a\xb0\xff\xff\xff\xff\xbf\xbb\x18@\xff\xff\xff\xff\xc0Z\x8f\xb0\xff\xff\xff\xff\xc1\x9d\x9d@\xff\xff\xff\xff\xc2;\xc30\xff\xff\xff\xff\xc3~\xd0\xc0\xff\xff\xff\xff\xc4\x1c\xf6\xb0\xff\xff\xff\xff\xc5`\x04@\xff\xff\xff\xff\xc5\xfe*0\xff\xff\xff\xff\xc7A7\xc0\xff\xff\xff\xff\xc7\xe0\xaf0\xff\xff\xff\xff\xc8\x81\x94@\xff\xff\xff\xff\xcaM\xa1\xb0\xff\xff\xff\xff\xca\xee\x86\xc0\xff\xff\xff\xff\xceM\xff0\xff\xff\xff\xff\xce\xb0\xed\xc0\xff\xff\xff\xff\xd3)5\xb0\xff\xff\xff\xff\xd4Cd\xc0\xff\xff\xff\xff\xf4=\x080\xff\xff\xff\xff\xf4\x9f\xf6\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf62\x10@\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00#\x94\xb5\xb0\x00\x00\x00\x00$\x10\x94\xa0\x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xf0v\xa0\x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xd0X\xa0\x00\x00\x00\x00)\x00\xff@\x00\x00\x00\x00)\xb0:\xa0\x00\x00\x00\x00*\xe0\xd30\x00\x00\x00\x00+\x99W \x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xbf*\xb0\x00\x00\x00\x00Gw\x09\xb0\x00\x00\x00\x00G\xdc\x7f \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\xbca \x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x04\x05\x04\x02\x04\x05\x04\x05\x03\x05\x04\x05\x04\x05\xff\xff\xc3\xd0\x00\x00\xff\xff\xc3\xd0\x00\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x0cLMT\x00CMT\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x14\x00\x00\x00America/Santa_IsabelTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\x0a\xf2\xf0\xff\xff\xff\xff\xcb\xea\x8d\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2\x99\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff\xff\xff\xd8\x91\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\x07\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\xd8\x81 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00PST\x00PDT\x00PWT\x00PPT\x00\x0aPST8PDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04,2h\x99\x01\x00\x00\x99\x01\x00\x00\x10\x00\x00\x00America/SantaremTZif2\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\x1e\x00\x00\x00\x04\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaazH\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xba\xde\x820\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\x08@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xff\xdc\xb9g0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xff\xde\x9b\xec0\xff\xff\xff\xff\xdf\xdd\xa8@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\x0d\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\x0a\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1d\xc9\x9c@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3\xdd\xb0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\x22\x0b\xd6\xb0\x00\x00\x00\x00H`q@\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\x03\xff\xff\xcc\xb8\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x00\x04LMT\x00-03\x00-04\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x22_WJ\x05\x00\x00J\x05\x00\x00\x10\x00\x00\x00America/SantiagoTZif3\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\x00\x82\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d\xc5\xff\xff\xff\xff\x8f0GE\xff\xff\xff\xff\x9b\x5c\xe5P\xff\xff\xff\xff\x9f|\xe2\xc5\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^w\xc5\xff\xff\xff\xff\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\x224P\xff\xff\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\x5c\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff\xff\xd3\xdc\x8f\xc0\xff\xff\xff\xff\xd4\x17\xd50\xff\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00r\xdc\xb0\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\x0d\xb0\x00\x00\x00\x00\x07\x0b\xbc@\x00\x00\x00\x00\x07\xdf\xef\xb0\x00\x00\x00\x00\x08\xfe\x13@\x00\x00\x00\x00\x09\xbf\xd1\xb0\x00\x00\x00\x00\x0a\xdd\xf5@\x00\x00\x00\x00\x0b\xa8\xee0\x00\x00\x00\x00\x0c\xbd\xd7@\x00\x00\x00\x00\x0d\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\x5c@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\x229\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'\xd9\xa10\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)\xc2\xbd\xb0\x00\x00\x00\x00*\xd7\xa6\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\x0bD0\x00\x00\x00\x006\x0d\xb8@\x00\x00\x00\x007\x06\xd5\xb0\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\x080\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\x0d\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@S\xca\xb0\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\x070\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\x5cr\xb0\x00\x00\x00\x00T\x0b\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\x5c\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\x0d\xb0\x00\x00\x00\x00c\x1d]@\x00\x00\x00\x00d(\xef\xb0\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x05\x04\x02\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\xff\xff\xbd\xbb\x00\x00\xff\xff\xbd\xbb\x00\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x00\x0c\xff\xff\xc7\xc0\x01\x0c\xff\xff\xd5\xd0\x01\x10LMT\x00SMT\x00-05\x00-04\x00-03\x00\x0a<-04>4<-03>,M9.1.6/24,M4.1.6/24\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x0f(\x08=\x01\x00\x00=\x01\x00\x00\x15\x00\x00\x00America/Santo_DomingoTZif2\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\x11\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xffi\x87\x1d\x08\xff\xff\xff\xff\xba\xdfB`\xff\xff\xff\xff\xfa\x08K\xd0\xff\xff\xff\xff\xfa\xa7\xc3@\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00C{\xc8\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x01\xfa\x7fH\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x03\xdd\x04H\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x05\xbf\x89H\x00\x00\x00\x00\x070\xb4P\x00\x00\x00\x00\x07\xa0\xbc\xc8\x00\x00\x00\x00\x09\x10\x96P\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:)\xe1`\x01\x03\x02\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x03\x05\xff\xff\xbex\x00\x00\xff\xff\xbe`\x00\x04\xff\xff\xc7\xc0\x01\x09\xff\xff\xb9\xb0\x00\x0d\xff\xff\xc0\xb8\x01\x11\xff\xff\xc7\xc0\x00\x17LMT\x00SDMT\x00EDT\x00EST\x00-0430\x00AST\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d?\xdf\xda\xb8\x03\x00\x00\xb8\x03\x00\x00\x11\x00\x00\x00America/Sao_PauloTZif2\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\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaar\xb4\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xff\xdc\xb9Y \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xff\xde\x9b\xde \xff\xff\xff\xff\xdf\xdd\x9a0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4Z\x090\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\x0a\xd2\xb0\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1d\xc9\x8e0\x00\x00\x00\x00\x1ex\xd7\xa0\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3\xcf\xa0\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\x22\x0b\xc8\xa0\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\x0d\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00\x00\x00\x00.\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=\xc4\x910\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00?\x91\xfe0\x00\x00\x00\x00@.\xd2\xa0\x00\x00\x00\x00A\x86\xf80\x00\x00\x00\x00B\x17\xef \x00\x00\x00\x00CQ\xc20\x00\x00\x00\x00C\xf7\xd1 \x00\x00\x00\x00EMS\xb0\x00\x00\x00\x00E\xe0\xed\xa0\x00\x00\x00\x00G\x11\x860\x00\x00\x00\x00G\xb7\x95 \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\x97w \x00\x00\x00\x00J\xda\x84\xb0\x00\x00\x00\x00K\x80\x93\xa0\x00\x00\x00\x00L\xbaf\xb0\x00\x00\x00\x00M`u\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \x00\x00\x00\x00P\x83e0\x00\x00\x00\x00Q 9\xa0\x00\x00\x00\x00RcG0\x00\x00\x00\x00S\x00\x1b\xa0\x00\x00\x00\x00TC)0\x00\x00\x00\x00T\xe98 \x00\x00\x00\x00V#\x0b0\x00\x00\x00\x00V\xc9\x1a \x00\x00\x00\x00X\x02\xed0\x00\x00\x00\x00X\xa8\xfc \x00\x00\x00\x00Y\xe2\xcf0\x00\x00\x00\x00Z\x88\xde \x00\x00\x00\x00[\xde`\xb0\x00\x00\x00\x00\x5ch\xc0 \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\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\xff\xff\xd4L\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\x08LMT\x00-02\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x9a1T\xdf\x01\x00\x00\xdf\x01\x00\x00\x14\x00\x00\x00America/ScoresbysundTZif2\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\x22\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\x9b\x80L\x18\x00\x00\x00\x00\x13Mn@\x00\x00\x00\x00\x144$\xc0\x00\x00\x00\x00\x15#\xf9\xa0\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\xff\xff\xebh\x00\x00\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x01\x08\xff\xff\xf1\xf0\x00\x08\x00\x00\x00\x00\x01\x0cLMT\x00-02\x00-01\x00+00\x00\x0a<-01>1<+00>,M3.5.0/0,M10.5.0/1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x10\x00\x00\x00America/ShiprockTZif2\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\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\x0c\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\x08v\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x07\x8d5\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x09\xad\xb1\x10\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\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\xff\xff\x9d\x94\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\x0aMST7MDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81{\xc1\x92\xbc\x03\x00\x00\xbc\x03\x00\x00\x0d\x00\x00\x00America/SitkaTZif2\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\x00S\x00\x00\x00\x09\x00\x00\x00\x22\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x873\x99\xff\xff\xff\xff\xcb\x89\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\x0c\x10\x00\x00\x00\x00\x02x\x0b \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\x0a\x90\x00\x00\x00\x00\x06A\x09\xa0\x00\x00\x00\x00\x070\xec\x90\x00\x00\x00\x00\x07\x8dC\xa0\x00\x00\x00\x00\x09\x10\xce\x90\x00\x00\x00\x00\x09\xad\xbf \x00\x00\x00\x00\x0a\xf0\xb0\x90\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\x07\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81\xcb\xa0\x00\x00\x00\x00\x22V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\x0a\x8e \x00\x00\x00\x00)\xde\xdd\xb0\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,\xd3\x8c\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\x07F0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\x0a0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\x08\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO\xcc\xb0\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x06\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x00\x00\xd2\xa7\x00\x00\xff\xff\x81'\x00\x00\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10\xff\xff\x81p\x00\x14\xff\xff\x8f\x80\x01\x18\xff\xff\x81p\x00\x1dLMT\x00PST\x00PWT\x00PPT\x00PDT\x00YST\x00AKDT\x00AKST\x00\x0aAKST9AKDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00America/St_BarthelemyTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xb2\x0e\x19V\x07\x00\x00V\x07\x00\x00\x10\x00\x00\x00America/St_JohnsTZif2\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\xbb\x00\x00\x00\x08\x00\x00\x00\x19\xff\xff\xff\xff^=4\xec\xff\xff\xff\xff\x9c\xcfb\x0c\xff\xff\xff\xff\x9d\xa4\xe6\xfc\xff\xff\xff\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xa0\xb6\x88\xdc\xff\xff\xff\xff\xa18\xffL\xff\xff\xff\xff\xa2\x95\x19\x5c\xff\xff\xff\xff\xa3\x84\xfcL\xff\xff\xff\xff\xa4t\xfb\x5c\xff\xff\xff\xff\xa5d\xdeL\xff\xff\xff\xff\xa6^\x17\xdc\xff\xff\xff\xff\xa7D\xc0L\xff\xff\xff\xff\xa8=\xf9\xdc\xff\xff\xff\xff\xa9$\xa2L\xff\xff\xff\xff\xaa\x1d\xdb\xdc\xff\xff\xff\xff\xab\x04\x84L\xff\xff\xff\xff\xab\xfd\xbd\xdc\xff\xff\xff\xff\xac\xe4fL\xff\xff\xff\xff\xad\xdd\x9f\xdc\xff\xff\xff\xff\xae\xcd\x82\xcc\xff\xff\xff\xff\xaf\xbd\x81\xdc\xff\xff\xff\xff\xb0\xadd\xcc\xff\xff\xff\xff\xb1\xa6\x9e\x5c\xff\xff\xff\xff\xb2\x8dF\xcc\xff\xff\xff\xff\xb3\x86\x80\x5c\xff\xff\xff\xff\xb4m(\xcc\xff\xff\xff\xff\xb5fb\x5c\xff\xff\xff\xff\xb6M\x0a\xcc\xff\xff\xff\xff\xb7FD\x5c\xff\xff\xff\xff\xb8,\xec\xcc\xff\xff\xff\xff\xb9&&\x5c\xff\xff\xff\xff\xba\x16\x09L\xff\xff\xff\xff\xbb\x0fB\xdc\xff\xff\xff\xff\xbb\xf5\xebL\xff\xff\xff\xff\xbc\xef$\xdc\xff\xff\xff\xff\xbd\xd5\xcdL\xff\xff\xff\xff\xbe\x9eMl\xff\xff\xff\xff\xbe\xcf\x06\xa8\xff\xff\xff\xff\xbf\xb5\xaf\x18\xff\xff\xff\xff\xc0\xb818\xff\xff\xff\xff\xc1y\xef\xa8\xff\xff\xff\xff\xc2\x98\x138\xff\xff\xff\xff\xc3Y\xd1\xa8\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff\xff\xc8@\xf3\xb8\xff\xff\xff\xff\xc9\x02\xb2(\xff\xff\xff\xff\xca \xd5\xb8\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xff\xd3\x88D\xd8\xff\xff\xff\xff\xd4J\x03H\xff\xff\xff\xff\xd5h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\x08\xd8\xff\xff\xff\xff\xd8\x09\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff\xff\xdb\x11\x07X\xff\xff\xff\xff\xdb\xd2\xc5\xc8\xff\xff\xff\xff\xdc\xdetX\xff\xff\xff\xff\xdd\xa9mH\xff\xff\xff\xff\xde\xbeVX\xff\xff\xff\xff\xdf\x89OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1i1H\xff\xff\xff\xff\xe2~\x1aX\xff\xff\xff\xff\xe3I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff\xff\xe8\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06\xdc\xd8\xff\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff\xec\xb1\xb7\xc8\xff\xff\xff\xff\xed\xc6\xa0\xd8\xff\xff\xff\xff\xee\xbf\xbeH\xff\xff\xff\xff\xef\xaf\xbdX\xff\xff\xff\xff\xf0\x9f\xa0H\xff\xff\xff\xff\xf1\x8f\x9fX\xff\xff\xff\xff\xf2\x7f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff\xff\xff\xff\xf7/EX\xff\xff\xff\xff\xf8(b\xc8\xff\xff\xff\xff\xf9\x0f'X\xff\xff\xff\xff\xfa\x08D\xc8\xff\xff\xff\xff\xfa\xf8C\xd8\xff\xff\xff\xff\xfb\xe8&\xc8\xff\xff\xff\xff\xfc\xd8%\xd8\xff\xff\xff\xff\xfd\xc8\x08\xc8\xff\xff\xff\xff\xfe\xb8\x07\xd8\xff\xff\xff\xff\xff\xa7\xea\xc8\x00\x00\x00\x00\x00\x97\xe9\xd8\x00\x00\x00\x00\x01\x87\xcc\xc8\x00\x00\x00\x00\x02w\xcb\xd8\x00\x00\x00\x00\x03p\xe9H\x00\x00\x00\x00\x04`\xe8X\x00\x00\x00\x00\x05P\xcbH\x00\x00\x00\x00\x06@\xcaX\x00\x00\x00\x00\x070\xadH\x00\x00\x00\x00\x08 \xacX\x00\x00\x00\x00\x09\x10\x8fH\x00\x00\x00\x00\x0a\x00\x8eX\x00\x00\x00\x00\x0a\xf0qH\x00\x00\x00\x00\x0b\xe0pX\x00\x00\x00\x00\x0c\xd9\x8d\xc8\x00\x00\x00\x00\x0d\xc0RX\x00\x00\x00\x00\x0e\xb9o\xc8\x00\x00\x00\x00\x0f\xa9n\xd8\x00\x00\x00\x00\x10\x99Q\xc8\x00\x00\x00\x00\x11\x89P\xd8\x00\x00\x00\x00\x12y3\xc8\x00\x00\x00\x00\x13i2\xd8\x00\x00\x00\x00\x14Y\x15\xc8\x00\x00\x00\x00\x15I\x14\xd8\x00\x00\x00\x00\x168\xf7\xc8\x00\x00\x00\x00\x17(\xf6\xd8\x00\x00\x00\x00\x18\x22\x14H\x00\x00\x00\x00\x19\x08\xd8\xd8\x00\x00\x00\x00\x1a\x01\xf6H\x00\x00\x00\x00\x1a\xf1\xf5X\x00\x00\x00\x00\x1b\xe1\xd8H\x00\x00\x00\x00\x1c\xd1\xd7X\x00\x00\x00\x00\x1d\xc1\xbaH\x00\x00\x00\x00\x1e\xb1\xb9X\x00\x00\x00\x00\x1f\xa1\x9cH\x00\x00\x00\x00 u\xcf\xf4\x00\x00\x00\x00!\x81bd\x00\x00\x00\x00\x22U\xb1\xf4\x00\x00\x00\x00#jp\xd4\x00\x00\x00\x00$5\x93\xf4\x00\x00\x00\x00%J`\xe4\x00\x00\x00\x00&\x15u\xf4\x00\x00\x00\x00'*B\xe4\x00\x00\x00\x00'\xfe\x92t\x00\x00\x00\x00)\x0a$\xe4\x00\x00\x00\x00)\xdett\x00\x00\x00\x00*\xea\x06\xe4\x00\x00\x00\x00+\xbeVt\x00\x00\x00\x00,\xd3#d\x00\x00\x00\x00-\x9e8t\x00\x00\x00\x00.\xb3\x05d\x00\x00\x00\x00/~\x1at\x00\x00\x00\x000\x92\xe7d\x00\x00\x00\x001g6\xf4\x00\x00\x00\x002r\xc9d\x00\x00\x00\x003G\x18\xf4\x00\x00\x00\x004R\xabd\x00\x00\x00\x005&\xfa\xf4\x00\x00\x00\x0062\x8dd\x00\x00\x00\x007\x06\xdc\xf4\x00\x00\x00\x008\x1b\xa9\xe4\x00\x00\x00\x008\xe6\xbe\xf4\x00\x00\x00\x009\xfb\x8b\xe4\x00\x00\x00\x00:\xc6\xa0\xf4\x00\x00\x00\x00;\xdbm\xe4\x00\x00\x00\x00<\xaf\xbdt\x00\x00\x00\x00=\xbbO\xe4\x00\x00\x00\x00>\x8f\x9ft\x00\x00\x00\x00?\x9b1\xe4\x00\x00\x00\x00@o\x81t\x00\x00\x00\x00A\x84Nd\x00\x00\x00\x00BOct\x00\x00\x00\x00Cd0d\x00\x00\x00\x00D/Et\x00\x00\x00\x00ED\x12d\x00\x00\x00\x00E\xf3w\xf4\x00\x00\x00\x00G-.\xe4\x00\x00\x00\x00G\xd3Y\xf4\x00\x00\x00\x00I\x0d\x10\xe4\x00\x00\x00\x00I\xb3;\xf4\x00\x00\x00\x00J\xec\xf2\xe4\x00\x00\x00\x00K\x9cXt\x00\x00\x00\x00L\xd6\x0fd\x00\x00\x00\x00M|:t\x00\x00\x00\x00N\xb6\x0dH\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\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\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\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x07\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xff\xce\x94\x00\x00\xff\xff\xdc\xa4\x01\x04\xff\xff\xce\x94\x00\x08\xff\xff\xdc\xd8\x01\x04\xff\xff\xce\xc8\x00\x08\xff\xff\xdc\xd8\x01\x0c\xff\xff\xdc\xd8\x01\x10\xff\xff\xea\xe8\x01\x14LMT\x00NDT\x00NST\x00NPT\x00NWT\x00NDDT\x00\x0aNST3:30NDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00America/St_KittsTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00America/St_LuciaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x11\x00\x00\x00America/St_ThomasTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00America/St_VincentTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xd8\x19\x9dp\x01\x00\x00p\x01\x00\x00\x15\x00\x00\x00America/Swift_CurrentTZif2\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\x17\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x86\xfd\x96\x18\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3v\x01\x10\xff\xff\xff\xff\xd4So\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe9\x17\x0f\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xcb\x00\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xad\x00\x00\x00\x00\x00\x04a\x19\x90\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\xff\xff\x9a\xe8\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x13z\xe2\xc2\x00\x00\x00\xc2\x00\x00\x00\x13\x00\x00\x00America/TegucigalpaTZif2\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\x07\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\xa4LKD\x00\x00\x00\x00 \x9a\xdc\xe0\x00\x00\x00\x00!\x5c\x9bP\x00\x00\x00\x00\x22z\xbe\xe0\x00\x00\x00\x00#<}P\x00\x00\x00\x00D]\x8c\xe0\x00\x00\x00\x00D\xd6\xc8\xd0\x02\x01\x02\x01\x02\x01\x02\xff\xff\xae<\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08LMT\x00CDT\x00CST\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\x0d\xf7\xd3\xc7\x01\x00\x00\xc7\x01\x00\x00\x0d\x00\x00\x00America/ThuleTZif2\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\x22\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x9b\x80w\xfc\x00\x00\x00\x00'\xf5z\xe0\x00\x00\x00\x00(\xe5]\xd0\x00\x00\x00\x00)\xd5\x5c\xe0\x00\x00\x00\x00*\xc5?\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\x0aP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;\xdb\x90\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\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\xff\xff\xbf\x84\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\x08LMT\x00ADT\x00AST\x00\x0aAST4ADT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x13\x00\x00\x00America/Thunder_BayTZif2\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\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\x0cN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad\xdc\x8dp\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\x5c\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbe\xc4\xb9\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\xc2\x84}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xcb\x88\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdc\xde\x89p\xff\xff\xff\xff\xdd\xa9\x82`\xff\xff\xff\xff\xde\xbekp\xff\xff\xff\xff\xdf\x89d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\x0a`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xec\xd6\xb6\xe0\xff\xff\xff\xff\xed\xc6\xb5\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\x08Y\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x08 \xc1p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x0a\x00\xa3p\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x0f\x00\x00\x00America/TijuanaTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\x0a\xf2\xf0\xff\xff\xff\xff\xcb\xea\x8d\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2\x99\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff\xff\xff\xd8\x91\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\x07\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\xd8\x81 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00PST\x00PDT\x00PWT\x00PPT\x00\x0aPST8PDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x00\x00America/TorontoTZif2\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\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\x0cN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad\xdc\x8dp\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\x5c\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbe\xc4\xb9\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\xc2\x84}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xcb\x88\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdc\xde\x89p\xff\xff\xff\xff\xdd\xa9\x82`\xff\xff\xff\xff\xde\xbekp\xff\xff\xff\xff\xdf\x89d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\x0a`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xec\xd6\xb6\xe0\xff\xff\xff\xff\xed\xc6\xb5\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\x08Y\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x08 \xc1p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x0a\x00\xa3p\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00America/TortolaTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U9#\xbe2\x05\x00\x002\x05\x00\x00\x11\x00\x00\x00America/VancouverTZif2\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\x81\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^=v\xec\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xcb\x89\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd3v\x0f \xff\xff\xff\xff\xd4A\x08\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfe\xd1\xa0\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\xde\xb3\xa0\xff\xff\xff\xff\xdd\xa9\xac\x90\xff\xff\xff\xff\xde\xbe\x95\xa0\xff\xff\xff\xff\xdf\x89\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\x07\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8f\xde\xa0\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\x08\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\x0c\x10\x00\x00\x00\x00\x02x\x0b \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\x0a\x90\x00\x00\x00\x00\x06A\x09\xa0\x00\x00\x00\x00\x070\xec\x90\x00\x00\x00\x00\x08 \xeb\xa0\x00\x00\x00\x00\x09\x10\xce\x90\x00\x00\x00\x00\x0a\x00\xcd\xa0\x00\x00\x00\x00\x0a\xf0\xb0\x90\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x8c\x94\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00PWT\x00PPT\x00\x0aPST8PDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0e\x00\x00\x00America/VirginTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffz\xe6\x95\xb9\xff\xff\xff\xff\xcb\xf62\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\x01\x03\x02\x01\xff\xff\xc2\x07\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xd5\xd0\x01\x0cLMT\x00AST\x00APT\x00AWT\x00\x0aAST4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x1d\xee\x91\x05\x04\x00\x00\x05\x04\x00\x00\x12\x00\x00\x00America/WhitehorseTZif2\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\x09\x00\x00\x00%\xff\xff\xff\xff}\x86\x8a\x9c\xff\xff\xff\xff\x9e\xb8\xcb\xb0\xff\xff\xff\xff\x9f\xbb#\xa0\xff\xff\xff\xff\xa0\xd0\x0c\xb0\xff\xff\xff\xff\xa1\xa2\xd2\x80\xff\xff\xff\xff\xcb\x89(\xb0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf8\xc5\x84\x90\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00G\xd3\xb5 \x00\x00\x00\x00I\x0dl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\x5cw\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90\x00\x00\x00\x00T\xfc\x1d\xa0\x00\x00\x00\x00V5\xd4\x90\x00\x00\x00\x00V\xe5: \x00\x00\x00\x00X\x1e\xf1\x10\x00\x00\x00\x00X\xc5\x1c \x00\x00\x00\x00Y\xfe\xd3\x10\x00\x00\x00\x00Z\xa4\xfe \x00\x00\x00\x00[\xde\xb5\x10\x00\x00\x00\x00\x5c\x84\xe0 \x00\x00\x00\x00]\xbe\x97\x10\x00\x00\x00\x00^d\xc2 \x00\x00\x00\x00_\x9e\x5c\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x02\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\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\x08\xff\xff\x81d\x00\x00\xff\xff\x8f\x80\x01\x04\xff\xff\x81p\x00\x08\xff\xff\x8f\x80\x01\x0c\xff\xff\x8f\x80\x01\x10\xff\xff\x9d\x90\x01\x14\xff\xff\x8f\x80\x00\x19\xff\xff\x9d\x90\x01\x1d\xff\xff\x9d\x90\x00!LMT\x00YDT\x00YST\x00YWT\x00YPT\x00YDDT\x00PST\x00PDT\x00MST\x00\x0aMST7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x10\x00\x00\x00America/WinnipegTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xffd\xe4\xb0\x94\xff\xff\xff\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9b\xc3\xbaP\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xc2\xa0;\x80\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3\x88h\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xdb\x00\x07\x00\xff\xff\xff\xff\xdb\xc8\x5c\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\x91\xbc\xf0\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\x08v\x00\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x0d\x00\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x08 \xcf\x80\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x0a\x00\xb1\x80\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xb3\x80\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa4\xec\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10LMT\x00CDT\x00CST\x00CWT\x00CPT\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,\xdb~\xab\xb2\x03\x00\x00\xb2\x03\x00\x00\x0f\x00\x00\x00America/YakutatTZif2\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\x00S\x00\x00\x00\x08\x00\x00\x00\x1e\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x877\xbf\xff\xff\xff\xff\xcb\x89(\xb0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xfe\xb8U0\xff\xff\xff\xff\xff\xa88 \x00\x00\x00\x00\x00\x9870\x00\x00\x00\x00\x01\x88\x1a \x00\x00\x00\x00\x02x\x190\x00\x00\x00\x00\x03q6\xa0\x00\x00\x00\x00\x04a5\xb0\x00\x00\x00\x00\x05Q\x18\xa0\x00\x00\x00\x00\x06A\x17\xb0\x00\x00\x00\x00\x070\xfa\xa0\x00\x00\x00\x00\x07\x8dQ\xb0\x00\x00\x00\x00\x09\x10\xdc\xa0\x00\x00\x00\x00\x09\xad\xcd0\x00\x00\x00\x00\x0a\xf0\xbe\xa0\x00\x00\x00\x00\x0b\xe0\xbd\xb0\x00\x00\x00\x00\x0c\xd9\xdb \x00\x00\x00\x00\x0d\xc0\x9f\xb0\x00\x00\x00\x00\x0e\xb9\xbd \x00\x00\x00\x00\x0f\xa9\xbc0\x00\x00\x00\x00\x10\x99\x9f \x00\x00\x00\x00\x11\x89\x9e0\x00\x00\x00\x00\x12y\x81 \x00\x00\x00\x00\x13i\x800\x00\x00\x00\x00\x14Yc \x00\x00\x00\x00\x15Ib0\x00\x00\x00\x00\x169E \x00\x00\x00\x00\x17)D0\x00\x00\x00\x00\x18\x22a\xa0\x00\x00\x00\x00\x19\x09&0\x00\x00\x00\x00\x1a\x02C\xa0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\x07\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81\xcb\xa0\x00\x00\x00\x00\x22V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\x0a\x8e \x00\x00\x00\x00)\xde\xdd\xb0\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,\xd3\x8c\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\x07F0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\x0a0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\x08\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO\xcc\xb0\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\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\x00\x00\xce\x81\x00\x00\xff\xff}\x01\x00\x00\xff\xff\x81p\x00\x04\xff\xff\x8f\x80\x01\x08\xff\xff\x8f\x80\x01\x0c\xff\xff\x8f\x80\x01\x10\xff\xff\x8f\x80\x01\x14\xff\xff\x81p\x00\x19LMT\x00YST\x00YWT\x00YPT\x00YDT\x00AKDT\x00AKST\x00\x0aAKST9AKDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\x07\x07\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x13\x00\x00\x00America/YellowknifeTZif2\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\x00Y\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x88\xde\xce\xe0\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x98\x91\x90\xff\xff\xff\xff\xa0\xd2\x85\x80\xff\xff\xff\xff\xa2\x8a\xe8\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4j\xca\x90\xff\xff\xff\xff\xa55\xc3\x80\xff\xff\xff\xff\xa6S\xe7\x10\xff\xff\xff\xff\xa7\x15\xa5\x80\xff\xff\xff\xff\xa83\xc9\x10\xff\xff\xff\xff\xa8\xfe\xc2\x00\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x08 \xdd\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x0a\x00\xbf\x90\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x95\xa0\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\x0aMST7MDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xddzAh\xf3\x00\x00\x00\xf3\x00\x00\x00\x10\x00\x00\x00Antarctica/CaseyTZif2\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\x0c\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\xfe\x1e\xcc\x80\x00\x00\x00\x00J\xda\x06 \x00\x00\x00\x00K\x8f\xca\xf0\x00\x00\x00\x00N\xa9\x9c \x00\x00\x00\x00OC\xcd\x90\x00\x00\x00\x00X\x0a;\x80\x00\x00\x00\x00Z\xa4\x0f\x10\x00\x00\x00\x00[\xb9\x14@\x00\x00\x00\x00\x5c\x8d\x1d\x80\x00\x00\x00\x00]\x96E0\x00\x00\x00\x00^c\xc5\x00\x00\x00\x00\x00_x\xa0<\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x9a\xb0\x00\x08-00\x00+08\x00+11\x00\x0a<+11>-11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xea\x06\xd3\xc5\x00\x00\x00\xc5\x00\x00\x00\x10\x00\x00\x00Antarctica/DavisTZif2\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\x07\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\xe7\x9c@\x00\xff\xff\xff\xff\xf6G\xdf\x10\xff\xff\xff\xff\xfeG\xab\x00\x00\x00\x00\x00J\xda\x140\x00\x00\x00\x00K\x97\xfa@\x00\x00\x00\x00N\xa9\xaa0\x00\x00\x00\x00OC\xf7\xc0\x01\x00\x01\x02\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00bp\x00\x04\x00\x00FP\x00\x08-00\x00+07\x00+05\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x19\x00\x00\x00Antarctica/DumontDUrvilleTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xffV\xb6Z\x08\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\x09LMT\x00PMMT\x00+10\x00\x0a<+10>-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\x84J]\xd0\x03\x00\x00\xd0\x03\x00\x00\x14\x00\x00\x00Antarctica/MacquarieTZif2\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\x03\x00\x00\x00\x0e\xff\xff\xff\xff|\x05\x16\x00\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xa0\x87\xb4`\xff\xff\xff\xff\xd7\x0ch\x00\xff\xff\xff\xff\xfb\xc2\x8d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\x07/\xfd\x80\x00\x00\x00\x00\x07\xd6\x1a\x80\x00\x00\x00\x00\x09\x0f\xdf\x80\x00\x00\x00\x00\x09\xb5\xfc\x80\x00\x00\x00\x00\x0a\xef\xc1\x80\x00\x00\x00\x00\x0b\x9f\x19\x00\x00\x00\x00\x00\x0c\xd8\xde\x00\x00\x00\x00\x00\x0d~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\x0a\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\xce\x80\x00\x00\x00\x00\x22B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\x22}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)\xd4\x98\x00\x00\x00\x00\x00*\xcd\xc3\x80\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\x5c\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc\xc4\x80\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\x0c\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^\xd0\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\x07\xb1\x00\x00\x00\x00\x00G\xf7\xa2\x00\x00\x00\x00\x00H\xe7\x93\x00\x00\x00\x00\x00I\xd7\x84\x00\x00\x00\x00\x00J\xc7u\x00\x00\x00\x00\x00M\x97H\x00\x01\x02\x01\x00\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\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\x00\x00\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\x9a\xb0\x01\x09-00\x00AEST\x00AEDT\x00\x0aAEST-10AEDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7N\xab\x8b\x98\x00\x00\x00\x98\x00\x00\x00\x11\x00\x00\x00Antarctica/MawsonTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\xe2 2\x80\x00\x00\x00\x00J\xda\x22@\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00T`\x00\x04\x00\x00FP\x00\x08-00\x00+06\x00+05\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x12\x00\x00\x00Antarctica/McMurdoTZif2\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\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba\xcc\xa7\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\xc2\x83\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2\xda\x9a@\x00\x00\x00\x00\x09\x18\xfd\xe0\x00\x00\x00\x00\x09\xac\xa5\xe0\x00\x00\x00\x00\x0a\xef\xa5`\x00\x00\x00\x00\x0b\x9e\xfc\xe0\x00\x00\x00\x00\x0c\xd8\xc1\xe0\x00\x00\x00\x00\x0d~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\x0c`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\x0b`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\x220\x09\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\x0d\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*\xcd\xa7`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\x0a\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008\xd3\x8b\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\x5cN`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\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\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\x09\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\x0aNZST-12NZDT,M9.5.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95{\xf3\xa9w\x03\x00\x00w\x03\x00\x00\x11\x00\x00\x00Antarctica/PalmerTZif2\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\x00R\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xf6\x98\xad\x00\xff\xff\xff\xff\xf6\xe6\x9f\xb0\xff\xff\xff\xff\xf8\x13C\xc0\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xf9\xf4w@\xff\xff\xff\xff\xfa\xd36\xb0\xff\xff\xff\xff\xfb\xc35\xc0\xff\xff\xff\xff\xfc\xbcS0\xff\xff\xff\xff\xfd\xacR@\xff\xff\xff\xff\xfe\x9c50\xff\xff\xff\xff\xff\x8c4@\x00\x00\x00\x00\x07\xa3J\xb0\x00\x00\x00\x00\x08$o\xa0\x00\x00\x00\x00\x170\xbc\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\x5c@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\x229\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'\xd9\xa10\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)\xc2\xbd\xb0\x00\x00\x00\x00*\xd7\xa6\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\x0bD0\x00\x00\x00\x006\x0d\xb8@\x00\x00\x00\x007\x06\xd5\xb0\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\x080\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\x0d\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@S\xca\xb0\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\x070\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\x5cr\xb0\x00\x00\x00\x00T\x0b\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00XC\x86\xb0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x00\x00\x00\x00\x00\x00\xff\xff\xc7\xc0\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xe3\xe0\x01\x0c\xff\xff\xd5\xd0\x00\x08-00\x00-04\x00-03\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc6\x89\xf71\x84\x00\x00\x00\x84\x00\x00\x00\x12\x00\x00\x00Antarctica/RotheraTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\x00\x00\x00\x00\x0d\x02-\x00\x01\x00\x00\x00\x00\x00\x00\xff\xff\xd5\xd0\x00\x04-00\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x15\x00\x00\x00Antarctica/South_PoleTZif2\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\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba\xcc\xa7\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\xc2\x83\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2\xda\x9a@\x00\x00\x00\x00\x09\x18\xfd\xe0\x00\x00\x00\x00\x09\xac\xa5\xe0\x00\x00\x00\x00\x0a\xef\xa5`\x00\x00\x00\x00\x0b\x9e\xfc\xe0\x00\x00\x00\x00\x0c\xd8\xc1\xe0\x00\x00\x00\x00\x0d~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\x0c`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\x0b`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\x220\x09\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\x0d\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*\xcd\xa7`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\x0a\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008\xd3\x8b\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\x5cN`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\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\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\x09\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\x0aNZST-12NZDT,M9.5.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xd7\x87\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x10\x00\x00\x00Antarctica/SyowaTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\xc8P7\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00Antarctica/TrollTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\x00\x00\x00\x00B\x0dG\x00\x00\x00\x00\x00BF\x05\x90\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x00\x00\x00\x08-00\x00+02\x00+00\x00\x0a<+00>0<+02>-2,M3.5.0/1,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\x11\x00\x00\x00Antarctica/VostokTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\xb0\xfe\xbad\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x13\x00\x00\x00Arctic/LongyearbyenTZif2\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\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x09q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xb6\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xff\xd2\xa1O\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\xd5\xa8s\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\x09\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\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\x0c\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\x09\x00\x00*0\x01\x0dLMT\x00CEST\x00CET\x00CEMT\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xd7\x87\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x09\x00\x00\x00Asia/AdenTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xdd\x5c2a\x02\x00\x00a\x02\x00\x00\x0b\x00\x00\x00Asia/AlmatyTZif2\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\x003\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19{\xdc\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\x08\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\x5c\x1c\xc0\x00\x00\x00\x00\x22L\x0d\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\x0b\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xb2@\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00H$\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\x08\x00\x00T`\x00\x0c\x00\x00T`\x01\x0cLMT\x00+05\x00+07\x00+06\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\x0ds\xad\xa0\x03\x00\x00\xa0\x03\x00\x00\x0a\x00\x00\x00Asia/AmmanTZif2\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\x00W\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xb6\xa3\xd6\xd0\x00\x00\x00\x00\x06ry\xe0\x00\x00\x00\x00\x07\x0c\xabP\x00\x00\x00\x00\x08$7`\x00\x00\x00\x00\x08\xed\xde\xd0\x00\x00\x00\x00\x0a\x05j\xe0\x00\x00\x00\x00\x0a\xcf\x12P\x00\x00\x00\x00\x0b\xe7\xef\xe0\x00\x00\x00\x00\x0c\xdau\xd0\x00\x00\x00\x00\x0d\xc9#`\x00\x00\x00\x00\x0e\x92\xca\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10r\xac\xd0\x00\x00\x00\x00\x1c\xad\xd5`\x00\x00\x00\x00\x1d\x9f\x09\xd0\x00\x00\x00\x00\x1e\x92\xfd`\x00\x00\x00\x00\x1f\x82\xe0P\x00\x00\x00\x00 r\xdf`\x00\x00\x00\x00!b\xc2P\x00\x00\x00\x00\x22R\xc1`\x00\x00\x00\x00#K\xde\xd0\x00\x00\x00\x00$d\xbc`\x00\x00\x00\x00%+\xc0\xd0\x00\x00\x00\x00&7o`\x00\x00\x00\x00'\x0b\xa2\xd0\x00\x00\x00\x00(\x0bs\xe0\x00\x00\x00\x00(\xe2JP\x00\x00\x00\x00)\xe4\xbe`\x00\x00\x00\x00*\xcbf\xd0\x00\x00\x00\x00+\xbbe\xe0\x00\x00\x00\x00,\xabH\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00.x\xb5\xd0\x00\x00\x00\x00/\x84d`\x00\x00\x00\x000X\xa5\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\x0a`\x00\x00\x00\x006\x01\x86`\x00\x00\x00\x007z\x93`\x00\x00\x00\x007\xea\xa2\xe0\x00\x00\x00\x008\xe2|\xe0\x00\x00\x00\x009\xd3\xbf`\x00\x00\x00\x00:\xc2^\xe0\x00\x00\x00\x00;\xb3\xa1`\x00\x00\x00\x00<\xa3\x92`\x00\x00\x00\x00=\x93\x83`\x00\x00\x00\x00>\x83t`\x00\x00\x00\x00?\x98O`\x00\x00\x00\x00@cV`\x00\x00\x00\x00An\xf6\xe0\x00\x00\x00\x00BLr\xe0\x00\x00\x00\x00C<c\xe0\x00\x00\x00\x00D,T\xe0\x00\x00\x00\x00EA/\xe0\x00\x00\x00\x00F\x0c6\xe0\x00\x00\x00\x00G!\x11\xe0\x00\x00\x00\x00G\xec\x18\xe0\x00\x00\x00\x00I\x0a.`\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xea\x10`\x00\x00\x00\x00K\xab\xdc\xe0\x00\x00\x00\x00L\xc9\xf2`\x00\x00\x00\x00M\x94\xf9`\x00\x00\x00\x00N\xa9\xd4`\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00R\xb3^P\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TR\xb4\xe0\x00\x00\x00\x00U\x14\x81`\x00\x00\x00\x00V2\x96\xe0\x00\x00\x00\x00V\xfd\x9d\xe0\x00\x00\x00\x00X\x12x\xe0\x00\x00\x00\x00X\xdd\x7f\xe0\x00\x00\x00\x00Y\xf2Z\xe0\x00\x00\x00\x00Z\xbda\xe0\x00\x00\x00\x00[\xd2<\xe0\x00\x00\x00\x00\x5c\x9dC\xe0\x00\x00\x00\x00]\xb2\x1e\xe0\x00\x00\x00\x00^}%\xe0\x00\x00\x00\x00_\x9b;`\x00\x00\x00\x00`]\x07\xe0\x00\x00\x00\x00a{\x1d`\x00\x00\x00\x00b\x17\xff\xe0\x00\x00\x00\x00cZ\xff`\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\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\x03\x00\x00!\xb0\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\x09\x00\x00*0\x00\x0dLMT\x00EEST\x00EET\x00+03\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xe0\xe7!\xe7\x02\x00\x00\xe7\x02\x00\x00\x0b\x00\x00\x00Asia/AnadyrTZif2\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\x07\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x1d\x9c\xff\xff\xff\xff\xb5\xa3\x8c\xc0\x00\x00\x00\x00\x15'\x1b0\x00\x00\x00\x00\x16\x18O\xa0\x00\x00\x00\x00\x17\x08N\xb0\x00\x00\x00\x00\x17\xf9\x910\x00\x00\x00\x00\x18\xe9\x90@\x00\x00\x00\x00\x19\xda\xc4\xb0\x00\x00\x00\x00\x1a\xcc\x15@\x00\x00\x00\x00\x1b\xbc\x22`\x00\x00\x00\x00\x1c\xac\x13`\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00\x1e\x8b\xf5`\x00\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k\xd7`\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\x22K\xb9`\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\x9b`\x00\x00\x00\x00%\x1b\x8c`\x00\x00\x00\x00&\x0b}`\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00'\xf4\x99\xe0\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)x@\xf0\x00\x00\x00\x00)\xd4{\xe0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4]\xe0\x00\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-\x94?\xe0\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t!\xe0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]>`\x00\x00\x00\x002r\x19`\x00\x00\x00\x003= `\x00\x00\x00\x004Q\xfb`\x00\x00\x00\x005\x1d\x02`\x00\x00\x00\x0061\xdd`\x00\x00\x00\x006\xfc\xe4`\x00\x00\x00\x008\x1a\xf9\xe0\x00\x00\x00\x008\xdc\xc6`\x00\x00\x00\x009\xfa\xdb\xe0\x00\x00\x00\x00:\xbc\xa8`\x00\x00\x00\x00;\xda\xbd\xe0\x00\x00\x00\x00<\xa5\xc4\xe0\x00\x00\x00\x00=\xba\x9f\xe0\x00\x00\x00\x00>\x85\xa6\xe0\x00\x00\x00\x00?\x9a\x81\xe0\x00\x00\x00\x00@e\x88\xe0\x00\x00\x00\x00A\x83\x9e`\x00\x00\x00\x00BEj\xe0\x00\x00\x00\x00Cc\x80`\x00\x00\x00\x00D%L\xe0\x00\x00\x00\x00ECb`\x00\x00\x00\x00F\x05.\xe0\x00\x00\x00\x00G#D`\x00\x00\x00\x00G\xeeK`\x00\x00\x00\x00I\x03&`\x00\x00\x00\x00I\xce-`\x00\x00\x00\x00J\xe3\x08`\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x01\x03\x02\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x05\x06\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x05\x06\x01\x00\x00\xa6d\x00\x00\x00\x00\xa8\xc0\x00\x04\x00\x00\xc4\xe0\x01\x08\x00\x00\xb6\xd0\x00\x0c\x00\x00\xb6\xd0\x01\x0c\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\x10LMT\x00+12\x00+14\x00+13\x00+11\x00\x0a<+12>-12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x81\x18G^\x02\x00\x00^\x02\x00\x00\x0a\x00\x00\x00Asia/AqtauTZif2\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\x002\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x94\xe0\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\x08\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L\x1b\xd0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\x0b\xdf\xd0\x00\x00\x00\x00'\x05\x0bP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x01\x02\x03\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\x01\x02\x04\x02\x04\x02\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x02\x00\x00/ \x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\x08\x00\x00T`\x00\x0c\x00\x00T`\x01\x0c\x00\x00FP\x01\x08LMT\x00+04\x00+05\x00+06\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb\xfa\xb5\xbeg\x02\x00\x00g\x02\x00\x00\x0b\x00\x00\x00Asia/AqtobeTZif2\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\x003\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8eh\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\x08\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L\x1b\xd0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\x0b\xdf\xd0\x00\x00\x00\x00'\x05\x0bP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\x5cP\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\x0a\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\x09P\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x005\x98\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\x08\x00\x00T`\x01\x0c\x00\x00T`\x00\x0c\x00\x00FP\x01\x08LMT\x00+04\x00+05\x00+06\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x1bb2w\x01\x00\x00w\x01\x00\x00\x0d\x00\x00\x00Asia/AshgabatTZif2\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\x19\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8dD\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\x08\xbf0\x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L\x1b\xd0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\x0b\xdf\xd0\x00\x00\x00\x00'\x05\x0bP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x006\xbc\x00\x00\x00\x008@\x00\x04\x00\x00T`\x01\x08\x00\x00FP\x00\x0c\x00\x00FP\x01\x0cLMT\x00+04\x00+06\x00+05\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x1bb2w\x01\x00\x00w\x01\x00\x00\x0e\x00\x00\x00Asia/AshkhabadTZif2\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\x19\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x8dD\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\x08\xbf0\x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L\x1b\xd0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\x0b\xdf\xd0\x00\x00\x00\x00'\x05\x0bP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x006\xbc\x00\x00\x00\x008@\x00\x04\x00\x00T`\x01\x08\x00\x00FP\x00\x0c\x00\x00FP\x01\x0cLMT\x00+04\x00+06\x00+05\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xa7^\xfah\x02\x00\x00h\x02\x00\x00\x0b\x00\x00\x00Asia/AtyrauTZif2\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\x002\x00\x00\x00\x07\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x93P\xff\xff\xff\xff\xb5\xa4\x0bP\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\x08\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L\x1b\xd0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\x0b\xdf\xd0\x00\x00\x00\x00'\x05\x0bP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x01\x02\x03\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\x06\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x02\x00\x000\xb0\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x00\x08\x00\x00T`\x00\x0c\x00\x00T`\x01\x0c\x00\x00FP\x01\x08\x00\x008@\x00\x10LMT\x00+03\x00+05\x00+06\x00+04\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7e&uv\x02\x00\x00v\x02\x00\x00\x0c\x00\x00\x00Asia/BaghdadTZif2\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\x006\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x86\xb1\xdc\xff\xff\xff\xff\x9e0<\xe0\x00\x00\x00\x00\x170hP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xe8\xbdP\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbd\xc8@\x00\x00\x00\x00\x1c\xad\xc7P\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c8\xe0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\x0b\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\x0b\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf6x\x00\x00\x00\x00\x00(\xe7\xba\x80\x00\x00\x00\x00)\xd8\xfd\x00\x00\x00\x00\x00*\xca?\x80\x00\x00\x00\x00+\xba0\x80\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\x9bd\x00\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00\x00/|\x97\x80\x00\x00\x00\x000m\xda\x00\x00\x00\x00\x001_\x1c\x80\x00\x00\x00\x002P_\x00\x00\x00\x00\x003@P\x00\x00\x00\x00\x0041\x92\x80\x00\x00\x00\x005!\x83\x80\x00\x00\x00\x006\x12\xc6\x00\x00\x00\x00\x007\x02\xb7\x00\x00\x00\x00\x007\xf3\xf9\x80\x00\x00\x00\x008\xe5<\x00\x00\x00\x00\x009\xd6~\x80\x00\x00\x00\x00:\xc6o\x80\x00\x00\x00\x00;\xb7\xb2\x00\x00\x00\x00\x00<\xa7\xa3\x00\x00\x00\x00\x00=\x98\xe5\x80\x00\x00\x00\x00>\x88\xd6\x80\x00\x00\x00\x00?z\x19\x00\x00\x00\x00\x00@k[\x80\x00\x00\x00\x00A\x5c\x9e\x00\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00C=\xd1\x80\x00\x00\x00\x00D-\xc2\x80\x00\x00\x00\x00E\x1f\x05\x00\x00\x00\x00\x00F\x0e\xf6\x00\x00\x00\x00\x00G\x008\x80\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00)\xa4\x00\x00\x00\x00)\xa0\x00\x04\x00\x00*0\x00\x08\x00\x008@\x01\x0cLMT\x00BMT\x00+03\x00+04\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdav\x19z\x98\x00\x00\x00\x98\x00\x00\x00\x0c\x00\x00\x00Asia/BahrainTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\xa1\xf2\x9d0\x00\x00\x00\x00\x04\x8a\x92\xc0\x01\x02\x00\x000P\x00\x00\x00\x008@\x00\x04\x00\x00*0\x00\x08LMT\x00+04\x00+03\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x87\xb3<\xe8\x02\x00\x00\xe8\x02\x00\x00\x09\x00\x00\x00Asia/BakuTZif2\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\x00B\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x95D\xff\xff\xff\xff\xe7\xda\x0cP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\x08\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a\xcc\x85\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c8\xe0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\x0b\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\x0b\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\x0a`\x00\x00\x00\x00(\xe5\x09p\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x001]\xd9\x10\x00\x00\x00\x002r\xb4\x10\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\x0d\x00\x00\x00\x00\x00D%\xd9\x80\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00I\xce\xba\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00L\xcc\xb1\x80\x00\x00\x00\x00M\x8e~\x00\x00\x00\x00\x00N\xac\x93\x80\x00\x00\x00\x00On`\x00\x00\x00\x00\x00P\x8cu\x80\x00\x00\x00\x00QW|\x80\x00\x00\x00\x00RlW\x80\x00\x00\x00\x00S7^\x80\x00\x00\x00\x00TL9\x80\x00\x00\x00\x00U\x17@\x80\x00\x00\x00\x00V,\x1b\x80\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00.\xbc\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\x08\x00\x008@\x00\x0c\x00\x008@\x01\x0cLMT\x00+03\x00+05\x00+04\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0c\x00\x00\x00Asia/BangkokTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\x08LMT\x00BMT\x00+07\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\xbd\xedL\xf1\x02\x00\x00\xf1\x02\x00\x00\x0c\x00\x00\x00Asia/BarnaulTZif2\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\x00C\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xd5}\xfc\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\x08\xa3\x10\x00\x00\x00\x00\x17\xf9\xd7\x80\x00\x00\x00\x00\x18\xe9\xd6\x90\x00\x00\x00\x00\x19\xdb\x0b\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\x5c\x0e\xb0\x00\x00\x00\x00\x22K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1b\xd2\xb0\x00\x00\x00\x00&\x0b\xc3\xb0\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*\xc4\xb30\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x00/\xc7L\x80\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\xce\x81\xc0\x00\x00\x00\x00J\xe3\x5c\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00V\xf6\xea@\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00N\x84\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\x08\x00\x00bp\x00\x0c\x00\x00bp\x01\x0cLMT\x00+06\x00+08\x00+07\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\x11\xe1[\xdc\x02\x00\x00\xdc\x02\x00\x00\x0b\x00\x00\x00Asia/BeirutTZif2\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\x03\x00\x00\x00\x0d\xff\xff\xff\xffV\xb6\xc2\xb8\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xa8)\xf3\xe0\xff\xff\xff\xff\xa8\xeb\xb2P\xff\xff\xff\xff\xe8*\x85\xe0\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\x0b\xb9`\xff\xff\xff\xff\xea\xd5`\xd0\xff\xff\xff\xff\xeb\xec\xec\xe0\xff\xff\xff\xff\xec\xb6\x94P\xff\xff\xff\xff\xed\xcfq\xe0\xff\xff\xff\xff\xee\x99\x19P\xff\xff\xff\xff\xef\xb0\xa5`\xff\xff\xff\xff\xf0zL\xd0\x00\x00\x00\x00\x04\xa6^`\x00\x00\x00\x00\x05+w\xd0\x00\x00\x00\x00\x06C\x03\xe0\x00\x00\x00\x00\x07\x0c\xabP\x00\x00\x00\x00\x08$7`\x00\x00\x00\x00\x08\xed\xde\xd0\x00\x00\x00\x00\x0a\x05j\xe0\x00\x00\x00\x00\x0a\xcf\x12P\x00\x00\x00\x00\x0b\xe7\xef\xe0\x00\x00\x00\x00\x0c\xb1\x97P\x00\x00\x00\x00\x0d\xc9#`\x00\x00\x00\x00\x0e\x92\xca\xd0\x00\x00\x00\x00\x0f\xa9\x05`\x00\x00\x00\x00\x10r\xac\xd0\x00\x00\x00\x00\x1a\xf4.\xe0\x00\x00\x00\x00\x1b\xd1\x9c\xd0\x00\x00\x00\x00\x1c\xd5b`\x00\x00\x00\x00\x1d\xb2\xd0P\x00\x00\x00\x00\x1e\xb6\x95\xe0\x00\x00\x00\x00\x1f\x94\x03\xd0\x00\x00\x00\x00 \x97\xc9`\x00\x00\x00\x00!u7P\x00\x00\x00\x00\x22\xa3,\xe0\x00\x00\x00\x00#W\xbcP\x00\x00\x00\x00$g_`\x00\x00\x00\x00%8\xef\xd0\x00\x00\x00\x00&<\xb5`\x00\x00\x00\x00'\x1a#P\x00\x00\x00\x00(\x1d\xe8\xe0\x00\x00\x00\x00(\xfbV\xd0\x00\x00\x00\x00*\x00m\xe0\x00\x00\x00\x00*\xce\x09\xd0\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x006\x0dU\xd0\x00\x00\x00\x006\xfdT\xe0\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00!H\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\x09LMT\x00EEST\x00EET\x00\x0aEET-2EEST,M3.5.0/0,M10.5.0/0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000]*\x1bj\x02\x00\x00j\x02\x00\x00\x0c\x00\x00\x00Asia/BishkekTZif2\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\x004\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19~\x10\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\x08\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\x5c\x1c\xc0\x00\x00\x00\x00\x22L\x0d\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\x0b\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xbe\xa3\xc0\x00\x00\x00\x00)\xe770\x00\x00\x00\x00*\xc4\xa5 \x00\x00\x00\x00+\xc7\x190\x00\x00\x00\x00,\xa4\x87 \x00\x00\x00\x00-\xa6\xfb0\x00\x00\x00\x00.\x84i \x00\x00\x00\x00/\x86\xdd0\x00\x00\x00\x000dK \x00\x00\x00\x001f\xbf0\x00\x00\x00\x002Mg\xa0\x00\x00\x00\x003=\x89\xd8\x00\x00\x00\x004RV\xc8\x00\x00\x00\x005\x1dk\xd8\x00\x00\x00\x00628\xc8\x00\x00\x00\x006\xfdM\xd8\x00\x00\x00\x008\x1bUH\x00\x00\x00\x008\xdd/\xd8\x00\x00\x00\x009\xfb7H\x00\x00\x00\x00:\xbd\x11\xd8\x00\x00\x00\x00;\xdb\x19H\x00\x00\x00\x00<\xa6.X\x00\x00\x00\x00=\xba\xfbH\x00\x00\x00\x00>\x86\x10X\x00\x00\x00\x00?\x9a\xddH\x00\x00\x00\x00@e\xf2X\x00\x00\x00\x00A\x83\xf9\xc8\x00\x00\x00\x00BE\xd4X\x00\x00\x00\x00B\xfb\x92 \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x03\x00\x00E\xf0\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\x08\x00\x00T`\x00\x0c\x00\x00T`\x01\x0cLMT\x00+05\x00+07\x00+06\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7f^]@\x01\x00\x00@\x01\x00\x00\x0b\x00\x00\x00Asia/BruneiTZif2\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\x12\x00\x00\x00\x05\x00\x00\x00\x18\xff\xff\xff\xff\xad\x8a\x06\x90\xff\xff\xff\xff\xbagG\x88\xff\xff\xff\xff\xbf{'\x80\xff\xff\xff\xff\xbf\xf3\x1bP\xff\xff\xff\xff\xc1]\xac\x80\xff\xff\xff\xff\xc1\xd5\xa0P\xff\xff\xff\xff\xc3>\xe0\x00\xff\xff\xff\xff\xc3\xb6\xd3\xd0\xff\xff\xff\xff\xc5 \x13\x80\xff\xff\xff\xff\xc5\x98\x07P\xff\xff\xff\xff\xc7\x01G\x00\xff\xff\xff\xff\xc7y:\xd0\xff\xff\xff\xff\xc8\xe3\xcc\x00\xff\xff\xff\xff\xc9[\xbf\xd0\xff\xff\xff\xff\xca\xc4\xff\x80\xff\xff\xff\xff\xcb<\xf3P\xff\xff\xff\xff\xcb\x91X\x00\xff\xff\xff\xff\xd2Hm\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x00\x00gp\x00\x00\x00\x00ix\x00\x04\x00\x00u0\x01\x0a\x00\x00p\x80\x00\x10\x00\x00~\x90\x00\x14LMT\x00+0730\x00+0820\x00+08\x00+09\x00\x0a<+08>-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\x0d\x00\x00\x00Asia/CalcuttaTZif2\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\x07\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff&\xba\x18(\xff\xff\xff\xffC\xe7\xeb0\xff\xff\xff\xff\x87\x9d\xbc\xba\xff\xff\xff\xff\xca\xdb\x8c(\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff\xcc\x952\xa8\xff\xff\xff\xff\xd2t\x12\x98\x01\x02\x03\x04\x03\x04\x03\x00\x00R\xd8\x00\x00\x00\x00R\xd0\x00\x04\x00\x00KF\x00\x08\x00\x00MX\x00\x0c\x00\x00[h\x01\x10LMT\x00HMT\x00MMT\x00IST\x00+0630\x00\x0aIST-5:30\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\xcd\xdf\x05\xee\x02\x00\x00\xee\x02\x00\x00\x0a\x00\x00\x00Asia/ChitaTZif2\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\x00B\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\xf9\xa0\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\x08\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL\x90\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\x22K\xe3\x90\x00\x00\x00\x00#;\xd4\x90\x00\x00\x00\x00$+\xc5\x90\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&\x0b\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk \x00\x00\x00\x00)\xd4\xa6\x10\x00\x00\x00\x00*\xc4\x97\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\x07\x90\x00\x00\x00\x006\xfd\x0e\x90\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbc\xd2\x90\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00\x00>\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00@e\xb3\x10\x00\x00\x00\x00A\x83\xc8\x90\x00\x00\x00\x00BE\x95\x10\x00\x00\x00\x00Cc\xaa\x90\x00\x00\x00\x00D%w\x10\x00\x00\x00\x00EC\x8c\x90\x00\x00\x00\x00F\x05Y\x10\x00\x00\x00\x00G#n\x90\x00\x00\x00\x00G\xeeu\x90\x00\x00\x00\x00I\x03P\x90\x00\x00\x00\x00I\xceW\x90\x00\x00\x00\x00J\xe32\x90\x00\x00\x00\x00K\xae9\x90\x00\x00\x00\x00L\xccO\x10\x00\x00\x00\x00M\x8e\x1b\x90\x00\x00\x00\x00TK\xc9\x00\x00\x00\x00\x00V\xf6\xce \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x01\x03\x00\x00j`\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\x08\x00\x00~\x90\x00\x0c\x00\x00~\x90\x01\x0c\x00\x00\x8c\xa0\x00\x08LMT\x00+08\x00+10\x00+09\x00\x0a<+09>-9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81z&\x80k\x02\x00\x00k\x02\x00\x00\x0f\x00\x00\x00Asia/ChoibalsanTZif2\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\x003\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\x86\xd3\xe7(\x00\x00\x00\x00\x0f\x0b\xdc\x90\x00\x00\x00\x00\x18\xe9\xc8\x80\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbc\x22`\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\x22K\xc7p\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x8c`\x00\x00\x00\x00&\x0b\x8bp\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\x8a\xe0\x00\x00\x00\x00)\xd4\x89\xf0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]Lp\x00\x00\x00\x002M/`\x00\x00\x00\x003=.p\x00\x00\x00\x004-\x11`\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x006\x0c\xf3`\x00\x00\x00\x00:\xe9\xa5\x90\x00\x00\x00\x00;\xb4\x9e\x80\x00\x00\x00\x00<\xa4\x9d\x90\x00\x00\x00\x00=\x94\x80\x80\x00\x00\x00\x00>\x84\x7f\x90\x00\x00\x00\x00?tb\x80\x00\x00\x00\x00@da\x90\x00\x00\x00\x00ATD\x80\x00\x00\x00\x00BDC\x90\x00\x00\x00\x00C4&\x80\x00\x00\x00\x00D$%\x90\x00\x00\x00\x00E\x1dC\x00\x00\x00\x00\x00G\xef\xaa\xf0\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x01\x02\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x00\x00kX\x00\x00\x00\x00bp\x00\x04\x00\x00p\x80\x00\x08\x00\x00~\x90\x00\x0c\x00\x00\x8c\xa0\x01\x10\x00\x00~\x90\x01\x0cLMT\x00+07\x00+08\x00+09\x00+10\x00\x0a<+08>-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x00\x00Asia/ChongqingTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\x09\xf9p\xff\xff\xff\xff\xc9\xd3\xbd\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd3\x8b{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\x22\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\x22g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\x07G \x00\x00\x00\x00(\xd2@\x10\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\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\x08LMT\x00CDT\x00CST\x00\x0aCST-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x00\x00Asia/ChungkingTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\x09\xf9p\xff\xff\xff\xff\xc9\xd3\xbd\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd3\x8b{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\x22\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\x22g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\x07G \x00\x00\x00\x00(\xd2@\x10\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\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\x08LMT\x00CDT\x00CST\x00\x0aCST-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5c\x91\x87\xbb\xf7\x00\x00\x00\xf7\x00\x00\x00\x0c\x00\x00\x00Asia/ColomboTZif2\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\x08\x00\x00\x00\x07\x00\x00\x00\x18\xff\xff\xff\xffV\xb6\x99$\xff\xff\xff\xff\x87\x9d\xbd\x1c\xff\xff\xff\xff\xcbZ\x1c(\xff\xff\xff\xff\xcc\x95+\xa0\xff\xff\xff\xff\xd2u\x808\x00\x00\x00\x001\xa6\x00(\x00\x00\x00\x002q\x00 \x00\x00\x00\x00D?\xea(\x01\x02\x03\x04\x02\x05\x06\x02\x00\x00J\xdc\x00\x00\x00\x00J\xe4\x00\x04\x00\x00MX\x00\x08\x00\x00T`\x01\x0e\x00\x00[h\x01\x12\x00\x00[h\x00\x12\x00\x00T`\x00\x0eLMT\x00MMT\x00+0530\x00+06\x00+0630\x00\x0a<+0530>-5:30\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\x0a\x00\x00\x00Asia/DaccaTZif2\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\x07\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xffi\x86\x86\xbc\xff\xff\xff\xff\xca\xdb\x86\xb0\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff\xcc\x952\xa8\xff\xff\xff\xff\xdd\xa8\xd2\x98\x00\x00\x00\x00J;\xc4\x10\x00\x00\x00\x00K<\xd8\x90\x01\x02\x03\x02\x04\x05\x04\x00\x00T\xc4\x00\x00\x00\x00R\xd0\x00\x04\x00\x00[h\x00\x08\x00\x00MX\x00\x0e\x00\x00T`\x00\x14\x00\x00bp\x01\x18LMT\x00HMT\x00+0630\x00+0530\x00+06\x00+07\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\x07\xeci\xd2\x04\x00\x00\xd2\x04\x00\x00\x0d\x00\x00\x00Asia/DamascusTZif2\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\x00y\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa1\xf2\xabx\xff\xff\xff\xff\xa2\x81/\x80\xff\xff\xff\xff\xa3^\x9dp\xff\xff\xff\xff\xa4a\x11\x80\xff\xff\xff\xff\xa5>\x7fp\xff\xff\xff\xff\xa6@\xf3\x80\xff\xff\xff\xff\xa7\x1eap\xff\xff\xff\xff\xa8 \xd5\x80\xff\xff\xff\xff\xa9\x07}\xf0\xff\xff\xff\xff\xf1\x8fR\x00\xff\xff\xff\xff\xf2[\x9cp\xff\xff\xff\xff\xf3s(\x80\xff\xff\xff\xff\xf4;~p\xff\xff\xff\xff\xf5U\xad\x80\xff\xff\xff\xff\xf6\x1fT\xf0\xff\xff\xff\xff\xf76\xe1\x00\xff\xff\xff\xff\xf7\xff6\xf0\xff\xff\xff\xff\xf9\x0e\xda\x00\xff\xff\xff\xff\xf9\xe1\xbb\xf0\xff\xff\xff\xff\xfa\xf9H\x00\xff\xff\xff\xff\xfb\xc2\xefp\xff\xff\xff\xff\xfc\xdb\xcd\x00\xff\xff\xff\xff\xfd\xa5tp\xff\xff\xff\xff\xfe\xbd\x00\x80\xff\xff\xff\xff\xff\x86\xa7\xf0\x00\x00\x00\x00\x00\x9e4\x00\x00\x00\x00\x00\x01g\xdbp\x00\x00\x00\x00\x02\x7fg\x80\x00\x00\x00\x00\x03I\x0e\xf0\x00\x00\x00\x00\x04a\xec\x80\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06C \x00\x00\x00\x00\x00\x07\x0c\xc7p\x00\x00\x00\x00\x08$S\x80\x00\x00\x00\x00\x08\xed\xfa\xf0\x00\x00\x00\x00\x0a\x05\x87\x00\x00\x00\x00\x00\x0a\xcf.p\x00\x00\x00\x00\x0b\xe8\x0c\x00\x00\x00\x00\x00\x0c\xb1\xb3p\x00\x00\x00\x00\x0d\xc9?\x80\x00\x00\x00\x00\x0ekY\xf0\x00\x00\x00\x00\x0f\xaas\x00\x00\x00\x00\x00\x10L\x8dp\x00\x00\x00\x00\x18\xf4\xc5\x00\x00\x00\x00\x00\x19\xdbmp\x00\x00\x00\x00\x1a\xd7J\x00\x00\x00\x00\x00\x1b\xbd\xf2p\x00\x00\x00\x00\x1eU#\x00\x00\x00\x00\x00\x1f\x8a\xe5p\x00\x00\x00\x00 Gz\x00\x00\x00\x00\x00!\x89\x19\xf0\x00\x00\x00\x00\x22<t\x00\x00\x00\x00\x00#k\x9e\xf0\x00\x00\x00\x00$2\xbf\x80\x00\x00\x00\x00%%Ep\x00\x00\x00\x00&\x15D\x80\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf6[\xe0\x00\x00\x00\x00(\xe7\x90P\x00\x00\x00\x00)\xe2\x1b`\x00\x00\x00\x00*\xca\x15P\x00\x00\x00\x00+\xb2+`\x00\x00\x00\x00,\xa3_\xd0\x00\x00\x00\x00-\x9bG\xe0\x00\x00\x00\x00.\x8c|P\x00\x00\x00\x00/|{`\x00\x00\x00\x000m\xaf\xd0\x00\x00\x00\x001_\x00`\x00\x00\x00\x002P4\xd0\x00\x00\x00\x003>\xe2`\x00\x00\x00\x0041hP\x00\x00\x00\x005\x1e\xc4`\x00\x00\x00\x006\x12\x9b\xd0\x00\x00\x00\x007\x02\x9a\xe0\x00\x00\x00\x007\xf3\xcfP\x00\x00\x00\x008\xe5\x1f\xe0\x00\x00\x00\x009\xd6TP\x00\x00\x00\x00:\xc6S`\x00\x00\x00\x00;\xb7\x87\xd0\x00\x00\x00\x00<\xa7\x86\xe0\x00\x00\x00\x00=\x98\xbbP\x00\x00\x00\x00>\x88\xba`\x00\x00\x00\x00?y\xee\xd0\x00\x00\x00\x00@k?`\x00\x00\x00\x00A\x5cs\xd0\x00\x00\x00\x00BLr\xe0\x00\x00\x00\x00C=\xa7P\x00\x00\x00\x00D-\xa6`\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F\x0c6\xe0\x00\x00\x00\x00G*>P\x00\x00\x00\x00G\xf5S`\x00\x00\x00\x00I\x0bq\xd0\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xea\x02P\x00\x00\x00\x00K\xb5\x17`\x00\x00\x00\x00L\xc9\xe4P\x00\x00\x00\x00M\x94\xf9`\x00\x00\x00\x00N\xa9\xc6P\x00\x00\x00\x00Ot\xdb`\x00\x00\x00\x00P\x89\xa8P\x00\x00\x00\x00QT\xbd`\x00\x00\x00\x00Ri\x8aP\x00\x00\x00\x00S4\x9f`\x00\x00\x00\x00TR\xa6\xd0\x00\x00\x00\x00U\x14\x81`\x00\x00\x00\x00V2\x88\xd0\x00\x00\x00\x00V\xf4c`\x00\x00\x00\x00X\x12j\xd0\x00\x00\x00\x00X\xdd\x7f\xe0\x00\x00\x00\x00Y\xf2L\xd0\x00\x00\x00\x00Z\xbda\xe0\x00\x00\x00\x00[\xd2.\xd0\x00\x00\x00\x00\x5c\x9dC\xe0\x00\x00\x00\x00]\xb2\x10\xd0\x00\x00\x00\x00^}%\xe0\x00\x00\x00\x00_\x9b-P\x00\x00\x00\x00`]\x07\xe0\x00\x00\x00\x00a{\x0fP\x00\x00\x00\x00b<\xe9\xe0\x00\x00\x00\x00cZ\xf1P\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x00\x00\x22\x08\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\x09\x00\x00*0\x00\x0dLMT\x00EEST\x00EET\x00+03\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\x0a\x00\x00\x00Asia/DhakaTZif2\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\x07\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xffi\x86\x86\xbc\xff\xff\xff\xff\xca\xdb\x86\xb0\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff\xcc\x952\xa8\xff\xff\xff\xff\xdd\xa8\xd2\x98\x00\x00\x00\x00J;\xc4\x10\x00\x00\x00\x00K<\xd8\x90\x01\x02\x03\x02\x04\x05\x04\x00\x00T\xc4\x00\x00\x00\x00R\xd0\x00\x04\x00\x00[h\x00\x08\x00\x00MX\x00\x0e\x00\x00T`\x00\x14\x00\x00bp\x01\x18LMT\x00HMT\x00+0630\x00+0530\x00+06\x00+07\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\x92\x1a\x8c\xaa\x00\x00\x00\xaa\x00\x00\x00\x09\x00\x00\x00Asia/DiliTZif2\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\x04\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x92\xe6\x18\xc4\xff\xff\xff\xff\xcb\x992\xf0\x00\x00\x00\x00\x0b\xea0p\x00\x00\x00\x009\xc3\x99\x00\x01\x02\x01\x02\x00\x00u\xbc\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\x08LMT\x00+08\x00+09\x00\x0a<+09>-9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\x0a\x00\x00\x00Asia/DubaiTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00's\x96\x1en\x01\x00\x00n\x01\x00\x00\x0d\x00\x00\x00Asia/DushanbeTZif2\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\x18\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x83\x80\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\x08\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\x5c\x1c\xc0\x00\x00\x00\x00\x22L\x0d\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\x0b\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xca\x8fP\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x00\x00@\x80\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\x08\x00\x00T`\x00\x0c\x00\x00T`\x01\x0cLMT\x00+05\x00+07\x00+06\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]S\xbb\x12\xac\x03\x00\x00\xac\x03\x00\x00\x0e\x00\x00\x00Asia/FamagustaTZif2\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\x00V\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff\xa5w\x1e,\x00\x00\x00\x00\x09\xed\xaf\xe0\x00\x00\x00\x00\x0a\xdd\x92\xd0\x00\x00\x00\x00\x0b\xfad\xe0\x00\x00\x00\x00\x0c\xbe\xc6P\x00\x00\x00\x00\x0d\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$,\x0b\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\x0b\xed\xe0\x00\x00\x00\x00'\x05\x0bP\x00\x00\x00\x00'\xf5\x0a`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05\xc9\x90\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L\xcc\xbf\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7l\x90\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V,)\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xd0\x7f\xd0\x00\x00\x00\x00Y\xf5(\x10\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\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\x03\x02\x00\x00\x1f\xd4\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\x09\x00\x00*0\x00\x0dLMT\x00EEST\x00EET\x00+03\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xda7\xf5l\xd6\x09\x00\x00\xd6\x09\x00\x00\x09\x00\x00\x00Asia/GazaTZif3\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\x01\x04\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\xcd\xac\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xff\xcf\x8f\x83\x00\xff\xff\xff\xff\xd0\xa9\xa4\x00\xff\xff\xff\xff\xd1\x84}\x00\xff\xff\xff\xff\xd2\x8a\xd7\x80\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\x0b\x00\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\x0b\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\x7f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xff\xef\xb0\xb3p\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\x08|\x8b\xe0\x00\x00\x00\x00\x08\xfd\xb0\xd0\x00\x00\x00\x00\x09\xf6\xea`\x00\x00\x00\x00\x0a\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\x22^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\x0b\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\x07\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\x0a`\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@\x7f\x05\xe0\x00\x00\x00\x00A\x5c\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)\x5c`\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00X\xd5\xa4\xf0\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00\x00\x00\x00[\xd3\x8e`\x00\x00\x00\x00\x5c\x9dC\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00\x00^~w`\x00\x00\x00\x00_\x93R`\x00\x00\x00\x00`^Y`\x00\x00\x00\x00a{\x1d`\x00\x00\x00\x00b?\x8c\xe0\x00\x00\x00\x00c\x5c^\xf0\x00\x00\x00\x00dL^\x00\x00\x00\x00\x00e<@\xf0\x00\x00\x00\x00f\x19\xcb\x00\x00\x00\x00\x00g\x1c\x22\xf0\x00\x00\x00\x00g\xf0r\x80\x00\x00\x00\x00h\xfc\x04\xf0\x00\x00\x00\x00i\xc7\x1a\x00\x00\x00\x00\x00j\xdb\xe6\xf0\x00\x00\x00\x00k\xa6\xfc\x00\x00\x00\x00\x00l\xc5\x03p\x00\x00\x00\x00m\x86\xde\x00\x00\x00\x00\x00n\xa4\xe5p\x00\x00\x00\x00of\xc0\x00\x00\x00\x00\x00p\x84\xc7p\x00\x00\x00\x00qO\xdc\x80\x00\x00\x00\x00rd\xa9p\x00\x00\x00\x00s/\xbe\x80\x00\x00\x00\x00tD\x8bp\x00\x00\x00\x00u\x0f\xa0\x80\x00\x00\x00\x00v-\xa7\xf0\x00\x00\x00\x00v\xef\x82\x80\x00\x00\x00\x00x\x0d\x89\xf0\x00\x00\x00\x00x\xcfd\x80\x00\x00\x00\x00y\xedk\xf0\x00\x00\x00\x00z\xafF\x80\x00\x00\x00\x00{\xcdM\xf0\x00\x00\x00\x00|\x98c\x00\x00\x00\x00\x00}\xa3\xf5p\x00\x00\x00\x00~xE\x00\x00\x00\x00\x00\x7fz\x9c\xf0\x00\x00\x00\x00\x80X'\x00\x00\x00\x00\x00\x81H\x09\xf0\x00\x00\x00\x00\x828\x09\x00\x00\x00\x00\x00\x83\x1e\xb1p\x00\x00\x00\x00\x83L\xe4\x00\x00\x00\x00\x00\x83V\x10p\x00\x00\x00\x00\x84\x17\xeb\x00\x00\x00\x00\x00\x84\xec\x1ep\x00\x00\x00\x00\x85#\x8b\x80\x00\x00\x00\x00\x855\xf2p\x00\x00\x00\x00\x86\x01\x07\x80\x00\x00\x00\x00\x86\xc2\xc5\xf0\x00\x00\x00\x00\x86\xf0\xf8\x80\x00\x00\x00\x00\x87\x15\xd4p\x00\x00\x00\x00\x87\xe0\xe9\x80\x00\x00\x00\x00\x88\x99mp\x00\x00\x00\x00\x88\xc7\xa0\x00\x00\x00\x00\x00\x88\xf5\xb6p\x00\x00\x00\x00\x89\xc0\xcb\x80\x00\x00\x00\x00\x8af\xdap\x00\x00\x00\x00\x8a\x9eG\x80\x00\x00\x00\x00\x8a\xd5\x98p\x00\x00\x00\x00\x8b\xa0\xad\x80\x00\x00\x00\x00\x8c=\x81\xf0\x00\x00\x00\x00\x8ck\xb4\x80\x00\x00\x00\x00\x8c\xbe\xb4\xf0\x00\x00\x00\x00\x8d\x80\x8f\x80\x00\x00\x00\x00\x8e\x14)p\x00\x00\x00\x00\x8eB\x5c\x00\x00\x00\x00\x00\x8e\x9e\x96\xf0\x00\x00\x00\x00\x8f`q\x80\x00\x00\x00\x00\x8f\xe1\x96p\x00\x00\x00\x00\x90\x19\x03\x80\x00\x00\x00\x00\x90~x\xf0\x00\x00\x00\x00\x91I\x8e\x00\x00\x00\x00\x00\x91\xb8=\xf0\x00\x00\x00\x00\x91\xe6p\x80\x00\x00\x00\x00\x92^Z\xf0\x00\x00\x00\x00\x93)p\x00\x00\x00\x00\x00\x93\x85\xaa\xf0\x00\x00\x00\x00\x93\xbd\x18\x00\x00\x00\x00\x00\x94><\xf0\x00\x00\x00\x00\x95\x09R\x00\x00\x00\x00\x00\x95\x5cRp\x00\x00\x00\x00\x95\x8a\x85\x00\x00\x00\x00\x00\x96'Yp\x00\x00\x00\x00\x96\xe94\x00\x00\x00\x00\x00\x972\xf9\xf0\x00\x00\x00\x00\x97a,\x80\x00\x00\x00\x00\x98\x07;p\x00\x00\x00\x00\x98\xc9\x16\x00\x00\x00\x00\x00\x99\x00f\xf0\x00\x00\x00\x00\x997\xd4\x00\x00\x00\x00\x00\x99\xe7\x1dp\x00\x00\x00\x00\x9a\xb22\x80\x00\x00\x00\x00\x9a\xd7\x0ep\x00\x00\x00\x00\x9b\x05A\x00\x00\x00\x00\x00\x9b\xc6\xffp\x00\x00\x00\x00\x9c\x92\x14\x80\x00\x00\x00\x00\x9c\xa4{p\x00\x00\x00\x00\x9c\xdb\xe8\x80\x00\x00\x00\x00\x9d\xa6\xe1p\x00\x00\x00\x00\x9eq\xf6\x80\x00\x00\x00\x00\x9e{\x22\xf0\x00\x00\x00\x00\x9e\xb2\x90\x00\x00\x00\x00\x00\x9f\x86\xc3p\x00\x00\x00\x00\xa0\x7f\xfd\x00\x00\x00\x00\x00\xa1o\xdf\xf0\x00\x00\x00\x00\xa2V\xa4\x80\x00\x00\x00\x00\xa3O\xc1\xf0\x00\x00\x00\x00\xa4$\x11\x80\x00\x00\x00\x00\xa5/\xa3\xf0\x00\x00\x00\x00\xa5\xfa\xb9\x00\x00\x00\x00\x00\xa7\x0f\x85\xf0\x00\x00\x00\x00\xa7\xda\x9b\x00\x00\x00\x00\x00\xa8\xefg\xf0\x00\x00\x00\x00\xa9\xba}\x00\x00\x00\x00\x00\xaa\xd8\x84p\x00\x00\x00\x00\xab\x9a_\x00\x00\x00\x00\x00\xac\xb8fp\x00\x00\x00\x00\xadzA\x00\x00\x00\x00\x00\xae\x98Hp\x00\x00\x00\x00\xafZ#\x00\x00\x00\x00\x00\xb0x*p\x00\x00\x00\x00\xb1C?\x80\x00\x00\x00\x00\xb2X\x0cp\x00\x00\x00\x00\xb3#!\x80\x00\x00\x00\x00\xb47\xeep\x00\x00\x00\x00\xb5\x03\x03\x80\x00\x00\x00\x00\xb6!\x0a\xf0\x00\x00\x00\x00\xb6\xe2\xe5\x80\x00\x00\x00\x00\xb8\x00\xec\xf0\x00\x00\x00\x00\xb8\xc2\xc7\x80\x00\x00\x00\x00\xb9\xd7\x94p\x00\x00\x00\x00\xba\xab\xe4\x00\x00\x00\x00\x00\xbb\xae;\xf0\x00\x00\x00\x00\xbc\x8b\xc6\x00\x00\x00\x00\x00\xbd\x84\xe3p\x00\x00\x00\x00\xbek\xa8\x00\x00\x00\x00\x00\xbfRPp\x00\x00\x00\x00\xc0K\x8a\x00\x00\x00\x00\x00\xc1(\xf7\xf0\x00\x00\x00\x00\xc1W*\x80\x00\x00\x00\x00\xc2\xff\x9fp\x00\x00\x00\x00\xc3-\xd2\x00\x00\x00\x00\x00\xc4\xcd\x0cp\x00\x00\x00\x00\xc5\x04y\x80\x00\x00\x00\x00\xc6\xa3\xb3\xf0\x00\x00\x00\x00\xc6\xd1\xe6\x80\x00\x00\x00\x00\xc7\x097p\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\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\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\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\x00\x00 P\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\x09\x00\x00*0\x01\x0d\x00\x00\x1c \x00\x11LMT\x00EEST\x00EET\x00IDT\x00IST\x00\x0aEET-2EEST,M3.4.4/50,M10.4.4/50\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0b\x00\x00\x00Asia/HarbinTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\x09\xf9p\xff\xff\xff\xff\xc9\xd3\xbd\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd3\x8b{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\x22\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\x22g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\x07G \x00\x00\x00\x00(\xd2@\x10\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\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\x08LMT\x00CDT\x00CST\x00\x0aCST-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xba\xd4\xe5\xe8\x09\x00\x00\xe8\x09\x00\x00\x0b\x00\x00\x00Asia/HebronTZif3\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\x01\x06\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff}\xbdJ\x19\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\xcd\xac\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xff\xcf\x8f\x83\x00\xff\xff\xff\xff\xd0\xa9\xa4\x00\xff\xff\xff\xff\xd1\x84}\x00\xff\xff\xff\xff\xd2\x8a\xd7\x80\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\x0b\x00\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\x0b\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\x7f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xff\xef\xb0\xb3p\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\x08|\x8b\xe0\x00\x00\x00\x00\x08\xfd\xb0\xd0\x00\x00\x00\x00\x09\xf6\xea`\x00\x00\x00\x00\x0a\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\x22^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\x0b\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\x07\xe0\x00\x00\x00\x001dF`\x00\x00\x00\x002A\xc2`\x00\x00\x00\x003D(`\x00\x00\x00\x004!\xa4`\x00\x00\x00\x005$\x0a`\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@\x7f\x05\xe0\x00\x00\x00\x00A\x5c\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\xbb\x06P\x00\x00\x00\x00I\xcb\xfa\xe0\x00\x00\x00\x00J\xa0<`\x00\x00\x00\x00K\xab\xdc\xe0\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00M\x94\xf9\x9c\x00\x00\x00\x00N5\xc2P\x00\x00\x00\x00N\x5c\x0b\xe0\x00\x00\x00\x00N\x84\xdcP\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)\x5c`\x00\x00\x00\x00V\xf5\xc2\xf0\x00\x00\x00\x00X\x13\xca`\x00\x00\x00\x00X\xd5\xa4\xf0\x00\x00\x00\x00Y\xf3\xac`\x00\x00\x00\x00Z\xb5\x86\xf0\x00\x00\x00\x00[\xd3\x8e`\x00\x00\x00\x00\x5c\x9dC\xe0\x00\x00\x00\x00]\xb3bP\x00\x00\x00\x00^~w`\x00\x00\x00\x00_\x93R`\x00\x00\x00\x00`^Y`\x00\x00\x00\x00a{\x1d`\x00\x00\x00\x00b?\x8c\xe0\x00\x00\x00\x00c\x5c^\xf0\x00\x00\x00\x00dL^\x00\x00\x00\x00\x00e<@\xf0\x00\x00\x00\x00f\x19\xcb\x00\x00\x00\x00\x00g\x1c\x22\xf0\x00\x00\x00\x00g\xf0r\x80\x00\x00\x00\x00h\xfc\x04\xf0\x00\x00\x00\x00i\xc7\x1a\x00\x00\x00\x00\x00j\xdb\xe6\xf0\x00\x00\x00\x00k\xa6\xfc\x00\x00\x00\x00\x00l\xc5\x03p\x00\x00\x00\x00m\x86\xde\x00\x00\x00\x00\x00n\xa4\xe5p\x00\x00\x00\x00of\xc0\x00\x00\x00\x00\x00p\x84\xc7p\x00\x00\x00\x00qO\xdc\x80\x00\x00\x00\x00rd\xa9p\x00\x00\x00\x00s/\xbe\x80\x00\x00\x00\x00tD\x8bp\x00\x00\x00\x00u\x0f\xa0\x80\x00\x00\x00\x00v-\xa7\xf0\x00\x00\x00\x00v\xef\x82\x80\x00\x00\x00\x00x\x0d\x89\xf0\x00\x00\x00\x00x\xcfd\x80\x00\x00\x00\x00y\xedk\xf0\x00\x00\x00\x00z\xafF\x80\x00\x00\x00\x00{\xcdM\xf0\x00\x00\x00\x00|\x98c\x00\x00\x00\x00\x00}\xa3\xf5p\x00\x00\x00\x00~xE\x00\x00\x00\x00\x00\x7fz\x9c\xf0\x00\x00\x00\x00\x80X'\x00\x00\x00\x00\x00\x81H\x09\xf0\x00\x00\x00\x00\x828\x09\x00\x00\x00\x00\x00\x83\x1e\xb1p\x00\x00\x00\x00\x83L\xe4\x00\x00\x00\x00\x00\x83V\x10p\x00\x00\x00\x00\x84\x17\xeb\x00\x00\x00\x00\x00\x84\xec\x1ep\x00\x00\x00\x00\x85#\x8b\x80\x00\x00\x00\x00\x855\xf2p\x00\x00\x00\x00\x86\x01\x07\x80\x00\x00\x00\x00\x86\xc2\xc5\xf0\x00\x00\x00\x00\x86\xf0\xf8\x80\x00\x00\x00\x00\x87\x15\xd4p\x00\x00\x00\x00\x87\xe0\xe9\x80\x00\x00\x00\x00\x88\x99mp\x00\x00\x00\x00\x88\xc7\xa0\x00\x00\x00\x00\x00\x88\xf5\xb6p\x00\x00\x00\x00\x89\xc0\xcb\x80\x00\x00\x00\x00\x8af\xdap\x00\x00\x00\x00\x8a\x9eG\x80\x00\x00\x00\x00\x8a\xd5\x98p\x00\x00\x00\x00\x8b\xa0\xad\x80\x00\x00\x00\x00\x8c=\x81\xf0\x00\x00\x00\x00\x8ck\xb4\x80\x00\x00\x00\x00\x8c\xbe\xb4\xf0\x00\x00\x00\x00\x8d\x80\x8f\x80\x00\x00\x00\x00\x8e\x14)p\x00\x00\x00\x00\x8eB\x5c\x00\x00\x00\x00\x00\x8e\x9e\x96\xf0\x00\x00\x00\x00\x8f`q\x80\x00\x00\x00\x00\x8f\xe1\x96p\x00\x00\x00\x00\x90\x19\x03\x80\x00\x00\x00\x00\x90~x\xf0\x00\x00\x00\x00\x91I\x8e\x00\x00\x00\x00\x00\x91\xb8=\xf0\x00\x00\x00\x00\x91\xe6p\x80\x00\x00\x00\x00\x92^Z\xf0\x00\x00\x00\x00\x93)p\x00\x00\x00\x00\x00\x93\x85\xaa\xf0\x00\x00\x00\x00\x93\xbd\x18\x00\x00\x00\x00\x00\x94><\xf0\x00\x00\x00\x00\x95\x09R\x00\x00\x00\x00\x00\x95\x5cRp\x00\x00\x00\x00\x95\x8a\x85\x00\x00\x00\x00\x00\x96'Yp\x00\x00\x00\x00\x96\xe94\x00\x00\x00\x00\x00\x972\xf9\xf0\x00\x00\x00\x00\x97a,\x80\x00\x00\x00\x00\x98\x07;p\x00\x00\x00\x00\x98\xc9\x16\x00\x00\x00\x00\x00\x99\x00f\xf0\x00\x00\x00\x00\x997\xd4\x00\x00\x00\x00\x00\x99\xe7\x1dp\x00\x00\x00\x00\x9a\xb22\x80\x00\x00\x00\x00\x9a\xd7\x0ep\x00\x00\x00\x00\x9b\x05A\x00\x00\x00\x00\x00\x9b\xc6\xffp\x00\x00\x00\x00\x9c\x92\x14\x80\x00\x00\x00\x00\x9c\xa4{p\x00\x00\x00\x00\x9c\xdb\xe8\x80\x00\x00\x00\x00\x9d\xa6\xe1p\x00\x00\x00\x00\x9eq\xf6\x80\x00\x00\x00\x00\x9e{\x22\xf0\x00\x00\x00\x00\x9e\xb2\x90\x00\x00\x00\x00\x00\x9f\x86\xc3p\x00\x00\x00\x00\xa0\x7f\xfd\x00\x00\x00\x00\x00\xa1o\xdf\xf0\x00\x00\x00\x00\xa2V\xa4\x80\x00\x00\x00\x00\xa3O\xc1\xf0\x00\x00\x00\x00\xa4$\x11\x80\x00\x00\x00\x00\xa5/\xa3\xf0\x00\x00\x00\x00\xa5\xfa\xb9\x00\x00\x00\x00\x00\xa7\x0f\x85\xf0\x00\x00\x00\x00\xa7\xda\x9b\x00\x00\x00\x00\x00\xa8\xefg\xf0\x00\x00\x00\x00\xa9\xba}\x00\x00\x00\x00\x00\xaa\xd8\x84p\x00\x00\x00\x00\xab\x9a_\x00\x00\x00\x00\x00\xac\xb8fp\x00\x00\x00\x00\xadzA\x00\x00\x00\x00\x00\xae\x98Hp\x00\x00\x00\x00\xafZ#\x00\x00\x00\x00\x00\xb0x*p\x00\x00\x00\x00\xb1C?\x80\x00\x00\x00\x00\xb2X\x0cp\x00\x00\x00\x00\xb3#!\x80\x00\x00\x00\x00\xb47\xeep\x00\x00\x00\x00\xb5\x03\x03\x80\x00\x00\x00\x00\xb6!\x0a\xf0\x00\x00\x00\x00\xb6\xe2\xe5\x80\x00\x00\x00\x00\xb8\x00\xec\xf0\x00\x00\x00\x00\xb8\xc2\xc7\x80\x00\x00\x00\x00\xb9\xd7\x94p\x00\x00\x00\x00\xba\xab\xe4\x00\x00\x00\x00\x00\xbb\xae;\xf0\x00\x00\x00\x00\xbc\x8b\xc6\x00\x00\x00\x00\x00\xbd\x84\xe3p\x00\x00\x00\x00\xbek\xa8\x00\x00\x00\x00\x00\xbfRPp\x00\x00\x00\x00\xc0K\x8a\x00\x00\x00\x00\x00\xc1(\xf7\xf0\x00\x00\x00\x00\xc1W*\x80\x00\x00\x00\x00\xc2\xff\x9fp\x00\x00\x00\x00\xc3-\xd2\x00\x00\x00\x00\x00\xc4\xcd\x0cp\x00\x00\x00\x00\xc5\x04y\x80\x00\x00\x00\x00\xc6\xa3\xb3\xf0\x00\x00\x00\x00\xc6\xd1\xe6\x80\x00\x00\x00\x00\xc7\x097p\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\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\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\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\x00\x00 \xe7\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\x09\x00\x00*0\x01\x0d\x00\x00\x1c \x00\x11LMT\x00EEST\x00EET\x00IDT\x00IST\x00\x0aEET-2EEST,M3.4.4/50,M10.4.4/50\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000I\xc7\xde\xec\x00\x00\x00\xec\x00\x00\x00\x10\x00\x00\x00Asia/Ho_Chi_MinhTZif2\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\x09\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\x88\x8cC\x8a\xff\xff\xff\xff\x91\xa3+\x0a\xff\xff\xff\xff\xcd5\xe6\x80\xff\xff\xff\xff\xd1Y\xcep\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd52\xbb\x10\xff\xff\xff\xff\xe4\xb6\xe4\x80\xff\xff\xff\xff\xed/\x98\x00\x00\x00\x00\x00\x0a=\xc7\x00\x01\x02\x03\x04\x02\x03\x02\x03\x02\x00\x00c\xf6\x00\x00\x00\x00c\xf6\x00\x04\x00\x00bp\x00\x09\x00\x00p\x80\x00\x0d\x00\x00~\x90\x00\x11LMT\x00PLMT\x00+07\x00+08\x00+09\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x09\xfa-\x07\x03\x00\x00\x07\x03\x00\x00\x0e\x00\x00\x00Asia/Hong_KongTZif2\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\x00E\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff\x85ic\x90\xff\xff\xff\xff\xcaM10\xff\xff\xff\xff\xca\xdb\x930\xff\xff\xff\xff\xcbKqx\xff\xff\xff\xff\xd2\xa0\xde\x90\xff\xff\xff\xff\xd3k\xd7\x80\xff\xff\xff\xff\xd4\x93X\xb8\xff\xff\xff\xff\xd5B\xb08\xff\xff\xff\xff\xd6s:\xb8\xff\xff\xff\xff\xd7>A\xb8\xff\xff\xff\xff\xd8.2\xb8\xff\xff\xff\xff\xd8\xf99\xb8\xff\xff\xff\xff\xda\x0e\x14\xb8\xff\xff\xff\xff\xda\xd9\x1b\xb8\xff\xff\xff\xff\xdb\xed\xf6\xb8\xff\xff\xff\xff\xdc\xb8\xfd\xb8\xff\xff\xff\xff\xdd\xcd\xd8\xb8\xff\xff\xff\xff\xde\xa2\x1a8\xff\xff\xff\xff\xdf\xb6\xf58\xff\xff\xff\xff\xe0\x81\xfc8\xff\xff\xff\xff\xe1\x96\xc9(\xff\xff\xff\xff\xe2Oi8\xff\xff\xff\xff\xe3v\xab(\xff\xff\xff\xff\xe4/K8\xff\xff\xff\xff\xe5_\xc7\xa8\xff\xff\xff\xff\xe6\x0f-8\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\x0d\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefw\xd1\xb8\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15a(\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf5C(\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\x22\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\x07&\xe6(\x00\x00\x00\x00\x07\x83=8\x00\x00\x00\x00\x09\x06\xc8(\x00\x00\x00\x00\x09\xf6\xc78\x00\x00\x00\x00\x0a\xe6\xaa(\x00\x00\x00\x00\x0b\xd6\xa98\x00\x00\x00\x00\x0c\xc6\x8c(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x02\x03\x04\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00k\x0a\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\x08\x00\x00w\x88\x01\x0d\x00\x00~\x90\x00\x12LMT\x00HKT\x00HKST\x00HKWT\x00JST\x00\x0aHKT-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xba\xa3b\xc1R\x02\x00\x00R\x02\x00\x00\x09\x00\x00\x00Asia/HovdTZif2\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\x002\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x86\xd3\xfc\x94\x00\x00\x00\x00\x0f\x0b\xea\xa0\x00\x00\x00\x00\x18\xe9\xd6\x90\x00\x00\x00\x00\x19\xdb\x0b\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbc>\x80\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c \x80\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x02\x80\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xe4\x80\x00\x00\x00\x00\x22K\xe3\x90\x00\x00\x00\x00#;\xc6\x80\x00\x00\x00\x00$+\xc5\x90\x00\x00\x00\x00%\x1b\xa8\x80\x00\x00\x00\x00&\x0b\xa7\x90\x00\x00\x00\x00'\x04\xc5\x00\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)\xd4\xa6\x10\x00\x00\x00\x00*\xc4\x89\x00\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4k\x00\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84M\x00\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d/\x00\x00\x00\x00\x001]h\x90\x00\x00\x00\x002MK\x80\x00\x00\x00\x003=J\x90\x00\x00\x00\x004--\x80\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x006\x0d\x0f\x80\x00\x00\x00\x00:\xe9\xc1\xb0\x00\x00\x00\x00;\xb4\xba\xa0\x00\x00\x00\x00<\xa4\xb9\xb0\x00\x00\x00\x00=\x94\x9c\xa0\x00\x00\x00\x00>\x84\x9b\xb0\x00\x00\x00\x00?t~\xa0\x00\x00\x00\x00@d}\xb0\x00\x00\x00\x00AT`\xa0\x00\x00\x00\x00BD_\xb0\x00\x00\x00\x00C4B\xa0\x00\x00\x00\x00D$A\xb0\x00\x00\x00\x00E\x1d_ \x00\x00\x00\x00U\x15\xa8\xb0\x00\x00\x00\x00V\x05o\x80\x00\x00\x00\x00V\xf5\x8a\xb0\x00\x00\x00\x00W\xe5Q\x80\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00U\xec\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\x08\x00\x00bp\x00\x0cLMT\x00+06\x00+08\x00+07\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9l\x03\x12\xf8\x02\x00\x00\xf8\x02\x00\x00\x0c\x00\x00\x00Asia/IrkutskTZif2\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\x00B\x00\x00\x00\x07\x00\x00\x00\x14\xff\xff\xff\xffV\xb6\x82?\xff\xff\xff\xff\xa2\x12\x0f\xbf\xff\xff\xff\xff\xb5\xa3\xd3\x10\x00\x00\x00\x00\x15'a\x80\x00\x00\x00\x00\x16\x18\x95\xf0\x00\x00\x00\x00\x17\x08\x95\x00\x00\x00\x00\x00\x17\xf9\xc9p\x00\x00\x00\x00\x18\xe9\xc8\x80\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbcZ\xa0\x00\x00\x00\x00\x1c\xacK\xa0\x00\x00\x00\x00\x1d\x9c<\xa0\x00\x00\x00\x00\x1e\x8c-\xa0\x00\x00\x00\x00\x1f|\x1e\xa0\x00\x00\x00\x00 l\x0f\xa0\x00\x00\x00\x00!\x5c\x00\xa0\x00\x00\x00\x00\x22K\xf1\xa0\x00\x00\x00\x00#;\xe2\xa0\x00\x00\x00\x00$+\xd3\xa0\x00\x00\x00\x00%\x1b\xc4\xa0\x00\x00\x00\x00&\x0b\xb5\xa0\x00\x00\x00\x00'\x04\xe1 \x00\x00\x00\x00'\xf4\xd2 \x00\x00\x00\x00(\xe4\xd10\x00\x00\x00\x00)xy0\x00\x00\x00\x00)\xd4\xb4 \x00\x00\x00\x00*\xc4\xa5 \x00\x00\x00\x00+\xb4\x96 \x00\x00\x00\x00,\xa4\x87 \x00\x00\x00\x00-\x94x \x00\x00\x00\x00.\x84i \x00\x00\x00\x00/tZ \x00\x00\x00\x000dK \x00\x00\x00\x001]v\xa0\x00\x00\x00\x002rQ\xa0\x00\x00\x00\x003=X\xa0\x00\x00\x00\x004R3\xa0\x00\x00\x00\x005\x1d:\xa0\x00\x00\x00\x0062\x15\xa0\x00\x00\x00\x006\xfd\x1c\xa0\x00\x00\x00\x008\x1b2 \x00\x00\x00\x008\xdc\xfe\xa0\x00\x00\x00\x009\xfb\x14 \x00\x00\x00\x00:\xbc\xe0\xa0\x00\x00\x00\x00;\xda\xf6 \x00\x00\x00\x00<\xa5\xfd \x00\x00\x00\x00=\xba\xd8 \x00\x00\x00\x00>\x85\xdf \x00\x00\x00\x00?\x9a\xba \x00\x00\x00\x00@e\xc1 \x00\x00\x00\x00A\x83\xd6\xa0\x00\x00\x00\x00BE\xa3 \x00\x00\x00\x00Cc\xb8\xa0\x00\x00\x00\x00D%\x85 \x00\x00\x00\x00EC\x9a\xa0\x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\xee\x83\xa0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x00\x00\x00\x00J\xe3@\xa0\x00\x00\x00\x00K\xaeG\xa0\x00\x00\x00\x00L\xcc] \x00\x00\x00\x00M\x8e)\xa0\x00\x00\x00\x00TK\xd7\x10\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x02\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\x03\x04\x03\x04\x03\x04\x03\x04\x06\x04\x00\x00a\xc1\x00\x00\x00\x00a\xc1\x00\x04\x00\x00bp\x00\x08\x00\x00~\x90\x01\x0c\x00\x00p\x80\x00\x10\x00\x00p\x80\x01\x10\x00\x00~\x90\x00\x0cLMT\x00IMT\x00+07\x00+09\x00+08\x00\x0a<+08>-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07W\x10\xd1\xb0\x04\x00\x00\xb0\x04\x00\x00\x0d\x00\x00\x00Asia/IstanbulTZif2\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\x00s\x00\x00\x00\x06\x00\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xbe\xd0\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xaa((`\xff\xff\xff\xff\xaa\xe1\xfd\xd0\xff\xff\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc31P\xff\xff\xff\xff\xc8\x81?\xe0\xff\xff\xff\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J\xf5`\xff\xff\xff\xff\xca\xce\x80P\xff\xff\xff\xff\xcb\xcb\xae`\xff\xff\xff\xff\xd2k\x09P\xff\xff\xff\xff\xd3\xa29`\xff\xff\xff\xff\xd4C\x02P\xff\xff\xff\xff\xd5L\x0d\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff\xff\xff\xd7+\xef\xe0\xff\xff\xff\xff\xd8\x09]\xd0\xff\xff\xff\xff\xd9\x02\x97`\xff\xff\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff\xdb\xd2\x5cP\xff\xff\xff\xff\xdc\xd4\xd0`\xff\xff\xff\xff\xdd\xb2>P\xff\xff\xff\xff\xf1\xf4\xb9`\xff\xff\xff\xff\xf4b\xefP\xff\xff\xff\xff\xf5h\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\x079\x9ap\x00\x00\x00\x00\x07\xfbu\x00\x00\x00\x00\x00\x09\x19|p\x00\x00\x00\x00\x09\xd0\xcb\x00\x00\x00\x00\x00\x0a\xf9^p\x00\x00\x00\x00\x0b\xb1\xfe\x80\x00\x00\x00\x00\x0c\xd9@p\x00\x00\x00\x00\x0d\xa4U\x80\x00\x00\x00\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x0f\xf8\x11P\x00\x00\x00\x00\x19\x89\xb0p\x00\x00\x00\x00\x19\xdc\xb0\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00\x00\x00\x1c\xc6\xef\xf0\x00\x00\x00\x00\x1d\x9b1p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x09p\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x8b\x83\xf0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\x07p\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xc9\x90\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L\xcc\xbf\x90\x00\x00\x00\x00M\x8f\xdd\x90\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\x08\x00\x00\x1c \x00\x0d\x00\x00*0\x00\x11\x00\x008@\x01\x15LMT\x00IMT\x00EEST\x00EET\x00+03\x00+04\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xad\xc5\xb1\xf8\x00\x00\x00\xf8\x00\x00\x00\x0c\x00\x00\x00Asia/JakartaTZif2\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\x08\x00\x00\x00\x07\x00\x00\x00 \xff\xff\xff\xff?fI`\xff\xff\xff\xff\xa9x\x85\xe0\xff\xff\xff\xff\xba\x16\xde`\xff\xff\xff\xff\xcb\xbf\x83\x88\xff\xff\xff\xff\xd2V\xeep\xff\xff\xff\xff\xd7<\xc6\x08\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xf4\xb5\xbe\x88\x01\x02\x03\x04\x03\x05\x03\x06\x00\x00d \x00\x00\x00\x00d \x00\x04\x00\x00g \x00\x08\x00\x00ix\x00\x0e\x00\x00~\x90\x00\x14\x00\x00p\x80\x00\x18\x00\x00bp\x00\x1cLMT\x00BMT\x00+0720\x00+0730\x00+09\x00+08\x00WIB\x00\x0aWIB-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.>[K\xab\x00\x00\x00\xab\x00\x00\x00\x0d\x00\x00\x00Asia/JayapuraTZif2\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\x03\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\xba\x16\xc1\x98\xff\xff\xff\xff\xd0X\xb9\xf0\xff\xff\xff\xff\xf4\xb5\xa2h\x01\x02\x03\x00\x00\x83\xe8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x00\x08\x00\x00~\x90\x00\x0eLMT\x00+09\x00+0930\x00WIT\x00\x0aWIT-9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\xe2\x9c\xb32\x04\x00\x002\x04\x00\x00\x0e\x00\x00\x00Asia/JerusalemTZif3\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\x00d\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\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\xcd\xac\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xff\xcf\x8f\x83\x00\xff\xff\xff\xff\xd0\xa9\xa4\x00\xff\xff\xff\xff\xd1\x84}\x00\xff\xff\xff\xff\xd2\x8a\xd7\x80\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\x0b\x00\xff\xff\xff\xff\xd7Z0\x80\xff\xff\xff\xff\xd7\xdfX\x00\xff\xff\xff\xff\xd8/\xc3\x80\xff\xff\xff\xff\xd9\x1ec\x00\xff\xff\xff\xff\xda\x10\xf7\x00\xff\xff\xff\xff\xda\xeb\xd0\x00\xff\xff\xff\xff\xdb\xb44\x00\xff\xff\xff\xff\xdc\xb9=\x00\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\xde\xb4\xce\x80\xff\xff\xff\xff\xdf\xa4\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2\xbef\x80\xff\xff\xff\xff\xe36_\x00\xff\xff\xff\xff\xe4\x9eH\x80\xff\xff\xff\xff\xe5\x16A\x00\xff\xff\xff\xff\xe6t\xf0\x00\xff\xff\xff\xff\xe7\x11\xd2\x80\xff\xff\xff\xff\xe8&\xad\x80\xff\xff\xff\xff\xe8\xe8z\x00\x00\x00\x00\x00\x08|\x8b\xe0\x00\x00\x00\x00\x08\xfd\xb0\xd0\x00\x00\x00\x00\x09\xf6\xea`\x00\x00\x00\x00\x0a\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\x22^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\x0b\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\x001H\x96\xe0\x00\x00\x00\x002<nP\x00\x00\x00\x0031\xb3`\x00\x00\x00\x004\x1a\xfe\xd0\x00\x00\x00\x005\x11\x95`\x00\x00\x00\x005\xf1\xa6P\x00\x00\x00\x007\x04\x08\x80\x00\x00\x00\x007\xcf\x01p\x00\x00\x00\x008\xf6_\x80\x00\x00\x00\x009\xdc\xf9\xe0\x00\x00\x00\x00:\xd0\xedp\x00\x00\x00\x00;\xae[`\x00\x00\x00\x00<\xa3\xa0p\x00\x00\x00\x00=\xa0\xb2`\x00\x00\x00\x00>\x83\x82p\x00\x00\x00\x00?|\x9f\xe0\x00\x00\x00\x00@s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F\x0cS\x00\x00\x00\x00\x00F\xecc\xf0\x00\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\x09\xf0\x00\x00\x00\x00M\x95\x15\x80\x00\x00\x00\x00N\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QT\xd9\x80\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\x08\x00\x00\x1c \x00\x0c\x00\x008@\x01\x10LMT\x00JMT\x00IDT\x00IST\x00IDDT\x00\x0aIST-2IDT,M3.4.4/26,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\xe2\x5c\xff\x9f\x00\x00\x00\x9f\x00\x00\x00\x0a\x00\x00\x00Asia/KabulTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffi\x86\x9a\xa0\xff\xff\xff\xff\xd0\xf9\xd7@\x01\x02\x00\x00@\xe0\x00\x00\x00\x008@\x00\x04\x00\x00?H\x00\x08LMT\x00+04\x00+0430\x00\x0a<+0430>-4:30\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x9cf>\xd7\x02\x00\x00\xd7\x02\x00\x00\x0e\x00\x00\x00Asia/KamchatkaTZif2\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\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa7R\x96\xc4\xff\xff\xff\xff\xb5\xa3\x9a\xd0\x00\x00\x00\x00\x15')@\x00\x00\x00\x00\x16\x18]\xb0\x00\x00\x00\x00\x17\x08\x5c\xc0\x00\x00\x00\x00\x17\xf9\x910\x00\x00\x00\x00\x18\xe9\x90@\x00\x00\x00\x00\x19\xda\xc4\xb0\x00\x00\x00\x00\x1a\xcc\x15@\x00\x00\x00\x00\x1b\xbc\x22`\x00\x00\x00\x00\x1c\xac\x13`\x00\x00\x00\x00\x1d\x9c\x04`\x00\x00\x00\x00\x1e\x8b\xf5`\x00\x00\x00\x00\x1f{\xe6`\x00\x00\x00\x00 k\xd7`\x00\x00\x00\x00![\xc8`\x00\x00\x00\x00\x22K\xb9`\x00\x00\x00\x00#;\xaa`\x00\x00\x00\x00$+\x9b`\x00\x00\x00\x00%\x1b\x8c`\x00\x00\x00\x00&\x0b}`\x00\x00\x00\x00'\x04\xa8\xe0\x00\x00\x00\x00'\xf4\x99\xe0\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)x@\xf0\x00\x00\x00\x00)\xd4{\xe0\x00\x00\x00\x00*\xc4l\xe0\x00\x00\x00\x00+\xb4]\xe0\x00\x00\x00\x00,\xa4N\xe0\x00\x00\x00\x00-\x94?\xe0\x00\x00\x00\x00.\x840\xe0\x00\x00\x00\x00/t!\xe0\x00\x00\x00\x000d\x12\xe0\x00\x00\x00\x001]>`\x00\x00\x00\x002r\x19`\x00\x00\x00\x003= `\x00\x00\x00\x004Q\xfb`\x00\x00\x00\x005\x1d\x02`\x00\x00\x00\x0061\xdd`\x00\x00\x00\x006\xfc\xe4`\x00\x00\x00\x008\x1a\xf9\xe0\x00\x00\x00\x008\xdc\xc6`\x00\x00\x00\x009\xfa\xdb\xe0\x00\x00\x00\x00:\xbc\xa8`\x00\x00\x00\x00;\xda\xbd\xe0\x00\x00\x00\x00<\xa5\xc4\xe0\x00\x00\x00\x00=\xba\x9f\xe0\x00\x00\x00\x00>\x85\xa6\xe0\x00\x00\x00\x00?\x9a\x81\xe0\x00\x00\x00\x00@e\x88\xe0\x00\x00\x00\x00A\x83\x9e`\x00\x00\x00\x00BEj\xe0\x00\x00\x00\x00Cc\x80`\x00\x00\x00\x00D%L\xe0\x00\x00\x00\x00ECb`\x00\x00\x00\x00F\x05.\xe0\x00\x00\x00\x00G#D`\x00\x00\x00\x00G\xeeK`\x00\x00\x00\x00I\x03&`\x00\x00\x00\x00I\xce-`\x00\x00\x00\x00J\xe3\x08`\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x00\x94\xbc\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\xb6\xd0\x01\x08\x00\x00\xa8\xc0\x00\x0c\x00\x00\xa8\xc0\x01\x0cLMT\x00+11\x00+13\x00+12\x00\x0a<+12>-12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009Y\xb7\xf1\x0a\x01\x00\x00\x0a\x01\x00\x00\x0c\x00\x00\x00Asia/KarachiTZif2\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\x0b\x00\x00\x00\x06\x00\x00\x00\x1d\xff\xff\xff\xff\x89~\xfc\xa4\xff\xff\xff\xff\xcc\x952\xa8\xff\xff\xff\xff\xd2t\x12\x98\xff\xff\xff\xff\xdd\xa8\xe0\xa8\x00\x00\x00\x00\x02O\xab0\x00\x00\x00\x00<\xafE\xb0\x00\x00\x00\x00=\x9f(\xa0\x00\x00\x00\x00HA\xa00\x00\x00\x00\x00I\x0bG\xa0\x00\x00\x00\x00I\xe4\xdd0\x00\x00\x00\x00J\xec{ \x01\x02\x01\x03\x05\x04\x05\x04\x05\x04\x05\x00\x00>\xdc\x00\x00\x00\x00MX\x00\x04\x00\x00[h\x01\x0a\x00\x00FP\x00\x10\x00\x00T`\x01\x14\x00\x00FP\x00\x19LMT\x00+0530\x00+0630\x00+05\x00PKST\x00PKT\x00\x0aPKT-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\x0c\x00\x00\x00Asia/KashgarTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\xb0\xfe\xbad\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\x0e\x00\x00\x00Asia/KathmanduTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf2}\x84\x00\x00\x00\x00\x1e\x180\xa8\x01\x02\x00\x00O\xfc\x00\x00\x00\x00MX\x00\x04\x00\x00P\xdc\x00\x0aLMT\x00+0530\x00+0545\x00\x0a<+0545>-5:45\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\x0d\x00\x00\x00Asia/KatmanduTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf2}\x84\x00\x00\x00\x00\x1e\x180\xa8\x01\x02\x00\x00O\xfc\x00\x00\x00\x00MX\x00\x04\x00\x00P\xdc\x00\x0aLMT\x00+0530\x00+0545\x00\x0a<+0545>-5:45\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x83g\x95M\x07\x03\x00\x00\x07\x03\x00\x00\x0d\x00\x00\x00Asia/KhandygaTZif2\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\x00C\x00\x00\x00\x08\x00\x00\x00\x14\xff\xff\xff\xff\xa1\xdb\xe4\xeb\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\x08\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL\x90\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\x22K\xe3\x90\x00\x00\x00\x00#;\xd4\x90\x00\x00\x00\x00$+\xc5\x90\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&\x0b\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk \x00\x00\x00\x00)\xd4\xa6\x10\x00\x00\x00\x00*\xc4\x97\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\x07\x90\x00\x00\x00\x006\xfd\x0e\x90\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbc\xd2\x90\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00\x00>\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00?\xf2\xe4p\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D%i\x00\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00\x00\x00\x00K\xae+\x80\x00\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\x0d\x80\x00\x00\x00\x00Nn\x02P\x00\x00\x00\x00TK\xc9\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x07\x06\x03\x00\x00\x7f\x15\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\x08\x00\x00~\x90\x00\x0c\x00\x00~\x90\x01\x0c\x00\x00\x9a\xb0\x01\x10\x00\x00\x8c\xa0\x00\x08\x00\x00\x9a\xb0\x00\x10LMT\x00+08\x00+10\x00+09\x00+11\x00\x0a<+09>-9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\x0c\x00\x00\x00Asia/KolkataTZif2\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\x07\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff&\xba\x18(\xff\xff\xff\xffC\xe7\xeb0\xff\xff\xff\xff\x87\x9d\xbc\xba\xff\xff\xff\xff\xca\xdb\x8c(\xff\xff\xff\xff\xcc\x05q\x18\xff\xff\xff\xff\xcc\x952\xa8\xff\xff\xff\xff\xd2t\x12\x98\x01\x02\x03\x04\x03\x04\x03\x00\x00R\xd8\x00\x00\x00\x00R\xd0\x00\x04\x00\x00KF\x00\x08\x00\x00MX\x00\x0c\x00\x00[h\x01\x10LMT\x00HMT\x00MMT\x00IST\x00+0630\x00\x0aIST-5:30\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\xe0\x91y\xe5\x02\x00\x00\xe5\x02\x00\x00\x10\x00\x00\x00Asia/KrasnoyarskTZif2\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\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xf9\x0d\xf2\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\x08\xa3\x10\x00\x00\x00\x00\x17\xf9\xd7\x80\x00\x00\x00\x00\x18\xe9\xd6\x90\x00\x00\x00\x00\x19\xdb\x0b\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\x5c\x0e\xb0\x00\x00\x00\x00\x22K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1b\xd2\xb0\x00\x00\x00\x00&\x0b\xc3\xb0\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*\xc4\xb30\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dH\xb0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\x0c\xb0\x00\x00\x00\x009\xfb\x220\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\x0b0\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00>\x85\xed0\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xcf0\x00\x00\x00\x00A\x83\xe4\xb0\x00\x00\x00\x00BE\xb10\x00\x00\x00\x00Cc\xc6\xb0\x00\x00\x00\x00D%\x930\x00\x00\x00\x00EC\xa8\xb0\x00\x00\x00\x00F\x05u0\x00\x00\x00\x00G#\x8a\xb0\x00\x00\x00\x00G\xee\x91\xb0\x00\x00\x00\x00I\x03l\xb0\x00\x00\x00\x00I\xces\xb0\x00\x00\x00\x00J\xe3N\xb0\x00\x00\x00\x00K\xaeU\xb0\x00\x00\x00\x00L\xcck0\x00\x00\x00\x00M\x8e7\xb0\x00\x00\x00\x00TK\xe5 \x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00W\x0e\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\x08\x00\x00bp\x00\x0c\x00\x00bp\x01\x0c\x00\x00p\x80\x00\x08LMT\x00+06\x00+08\x00+07\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x11\x00\x00\x00Asia/Kuala_LumpurTZif2\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\x08\x00\x00\x00\x08\x00\x00\x00 \xff\xff\xff\xff~6S\xa3\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xbagN\x90\xff\xff\xff\xff\xc0\x0a\xe4`\xff\xff\xff\xff\xca\xb3\xe5`\xff\xff\xff\xff\xcb\x91_\x08\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xee\x00\x01\x02\x03\x04\x05\x06\x05\x07\x00\x00a]\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\x08\x00\x00g \x01\x0c\x00\x00g \x00\x0c\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0730\x00+09\x00+08\x00\x0a<+08>-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7f^]@\x01\x00\x00@\x01\x00\x00\x0c\x00\x00\x00Asia/KuchingTZif2\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\x12\x00\x00\x00\x05\x00\x00\x00\x18\xff\xff\xff\xff\xad\x8a\x06\x90\xff\xff\xff\xff\xbagG\x88\xff\xff\xff\xff\xbf{'\x80\xff\xff\xff\xff\xbf\xf3\x1bP\xff\xff\xff\xff\xc1]\xac\x80\xff\xff\xff\xff\xc1\xd5\xa0P\xff\xff\xff\xff\xc3>\xe0\x00\xff\xff\xff\xff\xc3\xb6\xd3\xd0\xff\xff\xff\xff\xc5 \x13\x80\xff\xff\xff\xff\xc5\x98\x07P\xff\xff\xff\xff\xc7\x01G\x00\xff\xff\xff\xff\xc7y:\xd0\xff\xff\xff\xff\xc8\xe3\xcc\x00\xff\xff\xff\xff\xc9[\xbf\xd0\xff\xff\xff\xff\xca\xc4\xff\x80\xff\xff\xff\xff\xcb<\xf3P\xff\xff\xff\xff\xcb\x91X\x00\xff\xff\xff\xff\xd2Hm\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x00\x00gp\x00\x00\x00\x00ix\x00\x04\x00\x00u0\x01\x0a\x00\x00p\x80\x00\x10\x00\x00~\x90\x00\x14LMT\x00+0730\x00+0820\x00+08\x00+09\x00\x0a<+08>-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xd7\x87\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x0b\x00\x00\x00Asia/KuwaitTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d?v\x0c\x17\x03\x00\x00\x17\x03\x00\x00\x0a\x00\x00\x00Asia/MacaoTZif2\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\x00G\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x85i[\x8e\xff\xff\xff\xff\xcbGu\xf0\xff\xff\xff\xff\xcb\xf2\xca\xe0\xff\xff\xff\xff\xcc\xfb\xbaP\xff\xff\xff\xff\xcd\xd3\xfe`\xff\xff\xff\xff\xce\x9d\xa5\xd0\xff\xff\xff\xff\xd2azp\xff\xff\xff\xff\xd3x\xf8p\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5K\xabp\xff\xff\xff\xff\xd6tL\xf0\xff\xff\xff\xff\xd7?S\xf0\xff\xff\xff\xff\xd8/D\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xda\x0d\xd5p\xff\xff\xff\xff\xda\xd8\xdcp\xff\xff\xff\xff\xdb\xed\xb7p\xff\xff\xff\xff\xdc\xb8\xbep\xff\xff\xff\xff\xdd\xce\xea\xf0\xff\xff\xff\xff\xde\xa1\xda\xf0\xff\xff\xff\xff\xdf\xb6\xb5\xf0\xff\xff\xff\xff\xe0\x81\xbc\xf0\xff\xff\xff\xff\xe1\x96\x97\xf0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe3vy\xf0\xff\xff\xff\xff\xe4/\x0b\xf0\xff\xff\xff\xff\xe5_\x96p\xff\xff\xff\xff\xe6\x0e\xed\xf0\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\x0d\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefw\xd1\xb8\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15S\x18\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf55\x18\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\x22\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\x07&\xe6(\x00\x00\x00\x00\x07\x83=8\x00\x00\x00\x00\x09\x06\xc8(\x00\x00\x00\x00\x09\xf6\xc78\x00\x00\x00\x00\x0a\xe6\xaa(\x00\x00\x00\x00\x0b\xd6\xa98\x00\x00\x00\x00\x0c\xc6\x8c(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x03\x02\x03\x02\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x00\x00jr\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\x08\x00\x00~\x90\x00\x0c\x00\x00~\x90\x01\x10LMT\x00CST\x00+10\x00+09\x00CDT\x00\x0aCST-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d?v\x0c\x17\x03\x00\x00\x17\x03\x00\x00\x0a\x00\x00\x00Asia/MacauTZif2\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\x00G\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x85i[\x8e\xff\xff\xff\xff\xcbGu\xf0\xff\xff\xff\xff\xcb\xf2\xca\xe0\xff\xff\xff\xff\xcc\xfb\xbaP\xff\xff\xff\xff\xcd\xd3\xfe`\xff\xff\xff\xff\xce\x9d\xa5\xd0\xff\xff\xff\xff\xd2azp\xff\xff\xff\xff\xd3x\xf8p\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5K\xabp\xff\xff\xff\xff\xd6tL\xf0\xff\xff\xff\xff\xd7?S\xf0\xff\xff\xff\xff\xd8/D\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xda\x0d\xd5p\xff\xff\xff\xff\xda\xd8\xdcp\xff\xff\xff\xff\xdb\xed\xb7p\xff\xff\xff\xff\xdc\xb8\xbep\xff\xff\xff\xff\xdd\xce\xea\xf0\xff\xff\xff\xff\xde\xa1\xda\xf0\xff\xff\xff\xff\xdf\xb6\xb5\xf0\xff\xff\xff\xff\xe0\x81\xbc\xf0\xff\xff\xff\xff\xe1\x96\x97\xf0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe3vy\xf0\xff\xff\xff\xff\xe4/\x0b\xf0\xff\xff\xff\xff\xe5_\x96p\xff\xff\xff\xff\xe6\x0e\xed\xf0\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\x0d\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefw\xd1\xb8\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15S\x18\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf55\x18\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\x22\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\x07&\xe6(\x00\x00\x00\x00\x07\x83=8\x00\x00\x00\x00\x09\x06\xc8(\x00\x00\x00\x00\x09\xf6\xc78\x00\x00\x00\x00\x0a\xe6\xaa(\x00\x00\x00\x00\x0b\xd6\xa98\x00\x00\x00\x00\x0c\xc6\x8c(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x03\x02\x03\x02\x03\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x00\x00jr\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\x08\x00\x00~\x90\x00\x0c\x00\x00~\x90\x01\x10LMT\x00CST\x00+10\x00+09\x00CDT\x00\x0aCST-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4_P\x18\xef\x02\x00\x00\xef\x02\x00\x00\x0c\x00\x00\x00Asia/MagadanTZif2\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\x00B\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x196\xa0\xff\xff\xff\xff\xb5\xa3\xa8\xe0\x00\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\x08j\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\x22K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\x0b\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)\xd4\x89\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\x5c\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x09p\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\x07\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xcb\xf0\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce;p\x00\x00\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00TK\xac\xe0\x00\x00\x00\x00W\x1b\x9c\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x01\x03\x00\x00\x8d`\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x01\x08\x00\x00\x9a\xb0\x00\x0c\x00\x00\x9a\xb0\x01\x0c\x00\x00\xa8\xc0\x00\x08LMT\x00+10\x00+12\x00+11\x00\x0a<+11>-11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xc9\xd4\x5c\xbe\x00\x00\x00\xbe\x00\x00\x00\x0d\x00\x00\x00Asia/MakassarTZif2\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\x04\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\xa1\xf2]\x90\xff\xff\xff\xff\xba\x16\xd5\x90\xff\xff\xff\xff\xcb\x88\x1d\x80\xff\xff\xff\xff\xd2V\xeep\x01\x02\x03\x04\x00\x00o\xf0\x00\x00\x00\x00o\xf0\x00\x04\x00\x00p\x80\x00\x08\x00\x00~\x90\x00\x0c\x00\x00p\x80\x00\x10LMT\x00MMT\x00+08\x00+09\x00WITA\x00\x0aWITA-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xaf\xdf\x1c\xee\x00\x00\x00\xee\x00\x00\x00\x0b\x00\x00\x00Asia/ManilaTZif2\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\x0a\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\x14\xe1\xdc\x10\xff\xff\xff\xff{\x1f?\x90\xff\xff\xff\xff\xc1\x9c\xf4\x80\xff\xff\xff\xff\xc2\x160p\xff\xff\xff\xff\xcb\xf2\xe7\x00\xff\xff\xff\xff\xd0\xa9%p\xff\xff\xff\xff\xe2l9\x00\xff\xff\xff\xff\xe2\xd5\xa2\xf0\x00\x00\x00\x00\x0fuF\x80\x00\x00\x00\x00\x10fz\xf0\x01\x03\x02\x03\x04\x03\x02\x03\x02\x03\xff\xff\x1f\xf0\x00\x00\x00\x00qp\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\x08\x00\x00~\x90\x00\x0cLMT\x00PDT\x00PST\x00JST\x00\x0aPST-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\x0b\x00\x00\x00Asia/MuscatTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\x0c\x00\x00\x00Asia/NicosiaTZif2\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\x001\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xff\xa5w\x1e\xb8\x00\x00\x00\x00\x09\xed\xaf\xe0\x00\x00\x00\x00\x0a\xdd\x92\xd0\x00\x00\x00\x00\x0b\xfad\xe0\x00\x00\x00\x00\x0c\xbe\xc6P\x00\x00\x00\x00\x0d\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$,\x0b\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\x0b\xed\xe0\x00\x00\x00\x00'\x05\x0bP\x00\x00\x00\x00'\xf5\x0a`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062x\x10\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\x00\x00\x1fH\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\x09LMT\x00EEST\x00EET\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\x9a\x90\xf7\xd6\x02\x00\x00\xd6\x02\x00\x00\x11\x00\x00\x00Asia/NovokuznetskTZif2\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\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x18 \xc0\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\x08\xa3\x10\x00\x00\x00\x00\x17\xf9\xd7\x80\x00\x00\x00\x00\x18\xe9\xd6\x90\x00\x00\x00\x00\x19\xdb\x0b\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\x5c\x0e\xb0\x00\x00\x00\x00\x22K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1b\xd2\xb0\x00\x00\x00\x00&\x0b\xc3\xb0\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*\xc4\xb30\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dH\xb0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\x0c\xb0\x00\x00\x00\x009\xfb\x220\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\x0b0\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00>\x85\xed0\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xcf0\x00\x00\x00\x00A\x83\xe4\xb0\x00\x00\x00\x00BE\xb10\x00\x00\x00\x00Cc\xc6\xb0\x00\x00\x00\x00D%\x930\x00\x00\x00\x00EC\xa8\xb0\x00\x00\x00\x00F\x05u0\x00\x00\x00\x00G#\x8a\xb0\x00\x00\x00\x00G\xee\x91\xb0\x00\x00\x00\x00I\x03l\xb0\x00\x00\x00\x00I\xces\xb0\x00\x00\x00\x00J\xe3N\xb0\x00\x00\x00\x00K\xaeU\xb0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x00\x00Q\xc0\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\x08\x00\x00bp\x00\x0c\x00\x00bp\x01\x0cLMT\x00+06\x00+08\x00+07\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)p\x1cX\xf1\x02\x00\x00\xf1\x02\x00\x00\x10\x00\x00\x00Asia/NovosibirskTZif2\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\x00C\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\x19$\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\x08\xa3\x10\x00\x00\x00\x00\x17\xf9\xd7\x80\x00\x00\x00\x00\x18\xe9\xd6\x90\x00\x00\x00\x00\x19\xdb\x0b\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\x5c\x0e\xb0\x00\x00\x00\x00\x22K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1b\xd2\xb0\x00\x00\x00\x00&\x0b\xc3\xb0\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*\xc4\xb30\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00+\xfeN\x00\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\xce\x81\xc0\x00\x00\x00\x00J\xe3\x5c\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00W\x93\xcc\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00M\xbc\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\x08\x00\x00bp\x00\x0c\x00\x00bp\x01\x0cLMT\x00+06\x00+08\x00+07\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x11\xea\xa2\xe5\x02\x00\x00\xe5\x02\x00\x00\x09\x00\x00\x00Asia/OmskTZif2\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\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xb3@\xb6\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\x08\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\x5c\x1c\xc0\x00\x00\x00\x00\x22L\x0d\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\x0b\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xb2@\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\x94@\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dg@\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x002rm\xc0\x00\x00\x00\x003=t\xc0\x00\x00\x00\x004RO\xc0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x00621\xc0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1bN@\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb0@\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x12@\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\xce\x81\xc0\x00\x00\x00\x00J\xe3\x5c\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00D\xca\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\x08\x00\x00T`\x00\x0c\x00\x00T`\x01\x0c\x00\x00bp\x00\x08LMT\x00+05\x00+07\x00+06\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\xe9\xd1\xd8q\x02\x00\x00q\x02\x00\x00\x09\x00\x00\x00Asia/OralTZif2\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\x003\x00\x00\x00\x07\x00\x00\x00\x14\xff\xff\xff\xff\xaa\x19\x93\xdc\xff\xff\xff\xff\xb5\xa4\x0bP\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\x08\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L\x1b\xd0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\x0b\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\x0a`\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\xa1`\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x02\x00\x000$\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x00\x08\x00\x00T`\x01\x0c\x00\x00T`\x00\x0c\x00\x00FP\x01\x08\x00\x008@\x00\x10LMT\x00+03\x00+05\x00+06\x00+04\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x00\x00Asia/Phnom_PenhTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\x08LMT\x00BMT\x00+07\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xa5\x81e\xf7\x00\x00\x00\xf7\x00\x00\x00\x0e\x00\x00\x00Asia/PontianakTZif2\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\x08\x00\x00\x00\x07\x00\x00\x00\x1f\xff\xff\xff\xff\x8b\xff\x8e\x00\xff\xff\xff\xff\xba\x16\xdf\x00\xff\xff\xff\xff\xcby\xa4\x08\xff\xff\xff\xff\xd2V\xeep\xff\xff\xff\xff\xd7<\xc6\x08\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xf4\xb5\xbe\x88\x00\x00\x00\x00!\xdat\x80\x01\x02\x03\x02\x04\x02\x05\x06\x00\x00f\x80\x00\x00\x00\x00f\x80\x00\x04\x00\x00ix\x00\x08\x00\x00~\x90\x00\x0e\x00\x00p\x80\x00\x12\x00\x00p\x80\x00\x16\x00\x00bp\x00\x1bLMT\x00PMT\x00+0730\x00+09\x00+08\x00WITA\x00WIB\x00\x0aWIB-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\xc1\x1eB\xb7\x00\x00\x00\xb7\x00\x00\x00\x0e\x00\x00\x00Asia/PyongyangTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x0c\xff\xff\xff\xff\x8b\xd7\xf1\x9c\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2/ap\x00\x00\x00\x00U\xce\x02p\x00\x00\x00\x00Z\xecup\x01\x02\x03\x01\x03\x00\x00u\xe4\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\x08\x00\x00~\x90\x00\x04LMT\x00KST\x00JST\x00\x0aKST-9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdav\x19z\x98\x00\x00\x00\x98\x00\x00\x00\x0a\x00\x00\x00Asia/QatarTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\xa1\xf2\x9d0\x00\x00\x00\x00\x04\x8a\x92\xc0\x01\x02\x00\x000P\x00\x00\x00\x008@\x00\x04\x00\x00*0\x00\x08LMT\x00+04\x00+03\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xfax\x98g\x02\x00\x00g\x02\x00\x00\x0d\x00\x00\x00Asia/QostanayTZif2\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\x003\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x88\x5c\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\x08\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L\x1b\xd0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\x0b\xdf\xd0\x00\x00\x00\x00'\x05\x0bP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\x5cP\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\x0a\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\x09P\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x00\x00;\xa4\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\x08\x00\x00T`\x01\x0c\x00\x00T`\x00\x0c\x00\x00FP\x01\x08LMT\x00+04\x00+05\x00+06\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\xce\x9cGp\x02\x00\x00p\x02\x00\x00\x0e\x00\x00\x00Asia/QyzylordaTZif2\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\x004\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x86\xa0\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\x08\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L\x1b\xd0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\x0b\xdf\xd0\x00\x00\x00\x00'\x05\x0bP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\x95P\x00\x00\x00\x00)\xd4\xd0@\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\x5cP\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\x0a\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\x09P\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x00\x00\x00\x00\x5c\x1b\xd8\xa0\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x02\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x00\x00=`\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\x08\x00\x00T`\x01\x0c\x00\x00T`\x00\x0c\x00\x00FP\x01\x08LMT\x00+04\x00+05\x00+06\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\x87{_\xbb\x00\x00\x00\xbb\x00\x00\x00\x0c\x00\x00\x00Asia/RangoonTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xff\xd1\x9ag\xf0\x01\x02\x03\x02\x00\x00Z/\x00\x00\x00\x00Z/\x00\x04\x00\x00[h\x00\x08\x00\x00~\x90\x00\x0eLMT\x00RMT\x00+0630\x00+09\x00\x0a<+0630>-6:30\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xd7\x87\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x0b\x00\x00\x00Asia/RiyadhTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\xd5\x1b6\xb4\x01\x00\x00+\xcc\x00\x00\x00\x00*0\x00\x04LMT\x00+03\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000I\xc7\xde\xec\x00\x00\x00\xec\x00\x00\x00\x0b\x00\x00\x00Asia/SaigonTZif2\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\x09\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\x88\x8cC\x8a\xff\xff\xff\xff\x91\xa3+\x0a\xff\xff\xff\xff\xcd5\xe6\x80\xff\xff\xff\xff\xd1Y\xcep\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd52\xbb\x10\xff\xff\xff\xff\xe4\xb6\xe4\x80\xff\xff\xff\xff\xed/\x98\x00\x00\x00\x00\x00\x0a=\xc7\x00\x01\x02\x03\x04\x02\x03\x02\x03\x02\x00\x00c\xf6\x00\x00\x00\x00c\xf6\x00\x04\x00\x00bp\x00\x09\x00\x00p\x80\x00\x0d\x00\x00~\x90\x00\x11LMT\x00PLMT\x00+07\x00+08\x00+09\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x15II\xf3\x02\x00\x00\xf3\x02\x00\x00\x0d\x00\x00\x00Asia/SakhalinTZif2\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\x00B\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\x86\xf0\xcd\xb8\xff\xff\xff\xff\xd20\xb2\xf0\x00\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\x08j\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\x22K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\x0b\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)\xd4\x89\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\x5c\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xfa\xf8\x00\x00\x00\x00\x00:\xbc\xc4\x80\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D%i\x00\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00\x00\x00\x00K\xae+\x80\x00\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\x0d\x80\x00\x00\x00\x00TK\xba\xf0\x00\x00\x00\x00V\xf6\xb2\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\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\x03\x05\x03\x00\x00\x85\xc8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\xa8\xc0\x01\x08\x00\x00\x9a\xb0\x00\x0c\x00\x00\x9a\xb0\x01\x0c\x00\x00\x8c\xa0\x00\x10LMT\x00+09\x00+12\x00+11\x00+10\x00\x0a<+11>-11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w\x0dD\x07n\x01\x00\x00n\x01\x00\x00\x0e\x00\x00\x00Asia/SamarkandTZif2\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\x18\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x857\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\x08\xb1 \x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L\x1b\xd0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\x0b\xdf\xd0\x00\x00\x00\x00'\x05\x0bP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xedP\x01\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00>\xc9\x00\x00\x00\x008@\x00\x04\x00\x00FP\x00\x08\x00\x00T`\x01\x0c\x00\x00T`\x00\x0cLMT\x00+04\x00+05\x00+06\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\x0a\x00\x00\x00Asia/SeoulTZif2\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\x1d\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\x8b\xd7\xf0x\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2C'\xf0\xff\xff\xff\xff\xd7e\x8fp\xff\xff\xff\xff\xd7\xee\x9d`\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd-\xe0\xff\xff\xff\xff\xda\xd7\x8a\xf0\xff\xff\xff\xff\xdb\xad\x0f\xe0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\xdd\x8c\xf1\xe0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe4k\xb7\xf8\xff\xff\xff\xff\xe5\x13\x18h\xff\xff\xff\xff\xe6b\x03x\xff\xff\xff\xff\xe7\x11L\xe8\xff\xff\xff\xff\xe8/px\xff\xff\xff\xff\xe8\xe7\xf4h\xff\xff\xff\xff\xea\x0fRx\xff\xff\xff\xff\xea\xc7\xd6h\xff\xff\xff\xff\xeb\xef4x\xff\xff\xff\xff\xec\xa7\xb8h\xff\xff\xff\xff\xed\xcf\x16x\xff\xff\xff\xff\xee\x87\x9ah\xff\xff\xff\xff\xf05qx\x00\x00\x00\x00 \xa3`\x90\x00\x00\x00\x00!ng\x90\x00\x00\x00\x00\x22\x83B\x90\x00\x00\x00\x00#NI\x90\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x04\x03\x04\x03\x04\x00\x00w\x08\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\x08\x00\x00\x8c\xa0\x01\x0c\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x01\x0cLMT\x00KST\x00JST\x00KDT\x00\x0aKST-9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0d\x00\x00\x00Asia/ShanghaiTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\x09\xf9p\xff\xff\xff\xff\xc9\xd3\xbd\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd3\x8b{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\x22\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\x22g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\x07G \x00\x00\x00\x00(\xd2@\x10\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\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\x08LMT\x00CDT\x00CST\x00\x0aCST-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x0e\x00\x00\x00Asia/SingaporeTZif2\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\x08\x00\x00\x00\x08\x00\x00\x00 \xff\xff\xff\xff~6S\xa3\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xbagN\x90\xff\xff\xff\xff\xc0\x0a\xe4`\xff\xff\xff\xff\xca\xb3\xe5`\xff\xff\xff\xff\xcb\x91_\x08\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xee\x00\x01\x02\x03\x04\x05\x06\x05\x07\x00\x00a]\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\x08\x00\x00g \x01\x0c\x00\x00g \x00\x0c\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0730\x00+09\x00+08\x00\x0a<+08>-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4Z\xdf\x90\xe6\x02\x00\x00\xe6\x02\x00\x00\x12\x00\x00\x00Asia/SrednekolymskTZif2\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\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x193\xe4\xff\xff\xff\xff\xb5\xa3\xa8\xe0\x00\x00\x00\x00\x15'7P\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\x08j\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\x22K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\x0b\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)\xd4\x89\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\x5c\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x09p\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\x07\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xcb\xf0\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce;p\x00\x00\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00TK\xac\xe0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00\x90\x1c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa8\xc0\x01\x08\x00\x00\x9a\xb0\x00\x0c\x00\x00\x9a\xb0\x01\x0c\x00\x00\xa8\xc0\x00\x08LMT\x00+10\x00+12\x00+11\x00\x0a<+11>-11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\x0b\x00\x00\x00Asia/TaipeiTZif2\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\x10\xff\xff\xff\xfft\xce\xf0\x18\xff\xff\xff\xff\xc3UI\x80\xff\xff\xff\xff\xd2TY\x80\xff\xff\xff\xff\xd3\x8b{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\x22\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9\xe7\x99\xf0\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xdb\xc8\xcdp\xff\xff\xff\xff\xdc\xe0Y\x80\xff\xff\xff\xff\xdd\xaa\x00\xf0\xff\xff\xff\xff\xders\x00\xff\xff\xff\xff\xdf\xb5dp\xff\xff\xff\xff\xe0|\x85\x00\xff\xff\xff\xff\xe1\x96\x97\xf0\xff\xff\xff\xff\xe2]\xb8\x80\xff\xff\xff\xff\xe3w\xcbp\xff\xff\xff\xff\xe4>\xec\x00\xff\xff\xff\xff\xe50 p\xff\xff\xff\xff\xe6!q\x00\xff\xff\xff\xff\xe7\x12\xa5p\xff\xff\xff\xff\xe8\x02\xa4\x80\xff\xff\xff\xff\xe8\xf3\xd8\xf0\xff\xff\xff\xff\xe9\xe3\xd8\x00\xff\xff\xff\xff\xea\xd5\x0cp\xff\xff\xff\xff\xeb\xc5\x0b\x80\xff\xff\xff\xff\xec\xb6?\xf0\xff\xff\xff\xff\xed\xf7\xfc\x00\xff\xff\xff\xff\xee\x98\xc4\xf0\xff\xff\xff\xff\xef\xd9/\x80\xff\xff\xff\xff\xf0y\xf8p\x00\x00\x00\x00\x07\xfcV\x00\x00\x00\x00\x00\x08\xed\x8ap\x00\x00\x00\x00\x09\xdd\x89\x80\x00\x00\x00\x00\x0a\xce\xbd\xf0\x00\x00\x00\x00\x11\xdb\xa1\x80\x00\x00\x00\x00\x12T\xddp\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x00\x00q\xe8\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\x08\x00\x00~\x90\x01\x0cLMT\x00CST\x00JST\x00CDT\x00\x0aCST-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xe27Yn\x01\x00\x00n\x01\x00\x00\x0d\x00\x00\x00Asia/TashkentTZif2\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\x18\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x83\x09\xff\xff\xff\xff\xb5\xa3\xef0\x00\x00\x00\x00\x15'}\xa0\x00\x00\x00\x00\x16\x18\xb2\x10\x00\x00\x00\x00\x17\x08\xb1 \x00\x00\x00\x00\x17\xf9\xe5\x90\x00\x00\x00\x00\x18\xe9\xe4\xa0\x00\x00\x00\x00\x19\xdb\x19\x10\x00\x00\x00\x00\x1a\xcci\xa0\x00\x00\x00\x00\x1b\xbcv\xc0\x00\x00\x00\x00\x1c\xacg\xc0\x00\x00\x00\x00\x1d\x9cX\xc0\x00\x00\x00\x00\x1e\x8cI\xc0\x00\x00\x00\x00\x1f|:\xc0\x00\x00\x00\x00 l+\xc0\x00\x00\x00\x00!\x5c\x1c\xc0\x00\x00\x00\x00\x22L\x0d\xc0\x00\x00\x00\x00#;\xfe\xc0\x00\x00\x00\x00$+\xef\xc0\x00\x00\x00\x00%\x1b\xe0\xc0\x00\x00\x00\x00&\x0b\xd1\xc0\x00\x00\x00\x00'\x04\xfd@\x00\x00\x00\x00'\xf4\xee@\x00\x00\x00\x00(\xe4\xedP\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x00\x00@\xf7\x00\x00\x00\x00FP\x00\x04\x00\x00bp\x01\x08\x00\x00T`\x00\x0c\x00\x00T`\x01\x0cLMT\x00+05\x00+07\x00+06\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\xbe\xa8\xc7u\x02\x00\x00u\x02\x00\x00\x0c\x00\x00\x00Asia/TbilisiTZif2\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\x004\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xba\x01\xff\xff\xff\xff\xaa\x19\x9a\x01\xff\xff\xff\xff\xe7\xda\x0cP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\x08\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a\xcc\x85\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c8\xe0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\x0b\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\x0b\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\x0a`\x00\x00\x00\x00(\xe5\x09p\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xc1@\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xa3@\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x85@\x00\x00\x00\x00/tv@\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x92\xc0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dV\xc0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd8\xc0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\x1a\xc0\x00\x00\x00\x009\xfb\x220\x00\x00\x00\x00:\xbc\xfc\xc0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\x19@\x00\x00\x00\x00=\xba\xe60\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xc80\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00@\xdd\xc7\xb0\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x02\x05\x02\x05\x02\x05\x04\x03\x04\x03\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x02\x04\x00\x00)\xff\x00\x00\x00\x00)\xff\x00\x04\x00\x00*0\x00\x09\x00\x00FP\x01\x0d\x00\x008@\x00\x11\x00\x008@\x01\x11LMT\x00TBMT\x00+03\x00+05\x00+04\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xdb?\xec,\x03\x00\x00,\x03\x00\x00\x0b\x00\x00\x00Asia/TehranTZif2\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\x00G\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xff\x9al}\xc8\xff\xff\xff\xff\xbf\x00\xccH\x00\x00\x00\x00\x0d\x94D8\x00\x00\x00\x00\x0e\xad\x13\xb8\x00\x00\x00\x00\x0fys@\x00\x00\x00\x00\x10(\xca\xc0\x00\x00\x00\x00\x10\xed:@\x00\x00\x00\x00\x11\xad\xbcH\x00\x00\x00\x00\x12EJ\xb8\x00\x00\x00\x00\x137\xec\xc8\x00\x00\x00\x00\x14-\x15\xb8\x00\x00\x00\x00( v\xc8\x00\x00\x00\x00(\xdb\x9d\xb8\x00\x00\x00\x00)\xcb\x9c\xc8\x00\x00\x00\x00*\xbe\x22\xb8\x00\x00\x00\x00+\xac\xd0H\x00\x00\x00\x00,\x9fV8\x00\x00\x00\x00-\x8e\x03\xc8\x00\x00\x00\x00.\x80\x89\xb8\x00\x00\x00\x00/o7H\x00\x00\x00\x000a\xbd8\x00\x00\x00\x001Pj\xc8\x00\x00\x00\x002B\xf0\xb8\x00\x00\x00\x0032\xef\xc8\x00\x00\x00\x004%u\xb8\x00\x00\x00\x005\x14#H\x00\x00\x00\x006\x06\xa98\x00\x00\x00\x006\xf5V\xc8\x00\x00\x00\x007\xe7\xdc\xb8\x00\x00\x00\x008\xd6\x8aH\x00\x00\x00\x009\xc9\x108\x00\x00\x00\x00:\xb9\x0fH\x00\x00\x00\x00;\xab\x958\x00\x00\x00\x00<\x9aB\xc8\x00\x00\x00\x00=\x8c\xc8\xb8\x00\x00\x00\x00>{vH\x00\x00\x00\x00?m\xfc8\x00\x00\x00\x00@\x5c\xa9\xc8\x00\x00\x00\x00AO/\xb8\x00\x00\x00\x00B?.\xc8\x00\x00\x00\x00C1\xb4\xb8\x00\x00\x00\x00G\xe2\xc9H\x00\x00\x00\x00H\xd5O8\x00\x00\x00\x00I\xc5NH\x00\x00\x00\x00J\xb7\xd48\x00\x00\x00\x00K\xa6\x81\xc8\x00\x00\x00\x00L\x99\x07\xb8\x00\x00\x00\x00M\x87\xb5H\x00\x00\x00\x00Nz;8\x00\x00\x00\x00Oh\xe8\xc8\x00\x00\x00\x00P[n\xb8\x00\x00\x00\x00QKm\xc8\x00\x00\x00\x00R=\xf3\xb8\x00\x00\x00\x00S,\xa1H\x00\x00\x00\x00T\x1f'8\x00\x00\x00\x00U\x0d\xd4\xc8\x00\x00\x00\x00V\x00Z\xb8\x00\x00\x00\x00V\xef\x08H\x00\x00\x00\x00W\xe1\x8e8\x00\x00\x00\x00X\xd1\x8dH\x00\x00\x00\x00Y\xc4\x138\x00\x00\x00\x00Z\xb2\xc0\xc8\x00\x00\x00\x00[\xa5F\xb8\x00\x00\x00\x00\x5c\x93\xf4H\x00\x00\x00\x00]\x86z8\x00\x00\x00\x00^u'\xc8\x00\x00\x00\x00_g\xad\xb8\x00\x00\x00\x00`W\xac\xc8\x00\x00\x00\x00aJ2\xb8\x00\x00\x00\x00b8\xe0H\x00\x00\x00\x00c+f8\x01\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x0008\x00\x00\x00\x0008\x00\x04\x00\x00?H\x01\x08\x00\x0018\x00\x0e\x00\x00FP\x01\x14\x00\x008@\x00\x18LMT\x00TMT\x00+0430\x00+0330\x00+05\x00+04\x00\x0a<+0330>-3:30\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\xe2\x9c\xb32\x04\x00\x002\x04\x00\x00\x0d\x00\x00\x00Asia/Tel_AvivTZif3\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\x00d\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\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\xcd\xac\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xff\xcf\x8f\x83\x00\xff\xff\xff\xff\xd0\xa9\xa4\x00\xff\xff\xff\xff\xd1\x84}\x00\xff\xff\xff\xff\xd2\x8a\xd7\x80\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\x0b\x00\xff\xff\xff\xff\xd7Z0\x80\xff\xff\xff\xff\xd7\xdfX\x00\xff\xff\xff\xff\xd8/\xc3\x80\xff\xff\xff\xff\xd9\x1ec\x00\xff\xff\xff\xff\xda\x10\xf7\x00\xff\xff\xff\xff\xda\xeb\xd0\x00\xff\xff\xff\xff\xdb\xb44\x00\xff\xff\xff\xff\xdc\xb9=\x00\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\xde\xb4\xce\x80\xff\xff\xff\xff\xdf\xa4\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2\xbef\x80\xff\xff\xff\xff\xe36_\x00\xff\xff\xff\xff\xe4\x9eH\x80\xff\xff\xff\xff\xe5\x16A\x00\xff\xff\xff\xff\xe6t\xf0\x00\xff\xff\xff\xff\xe7\x11\xd2\x80\xff\xff\xff\xff\xe8&\xad\x80\xff\xff\xff\xff\xe8\xe8z\x00\x00\x00\x00\x00\x08|\x8b\xe0\x00\x00\x00\x00\x08\xfd\xb0\xd0\x00\x00\x00\x00\x09\xf6\xea`\x00\x00\x00\x00\x0a\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\x22^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\x0b\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\x001H\x96\xe0\x00\x00\x00\x002<nP\x00\x00\x00\x0031\xb3`\x00\x00\x00\x004\x1a\xfe\xd0\x00\x00\x00\x005\x11\x95`\x00\x00\x00\x005\xf1\xa6P\x00\x00\x00\x007\x04\x08\x80\x00\x00\x00\x007\xcf\x01p\x00\x00\x00\x008\xf6_\x80\x00\x00\x00\x009\xdc\xf9\xe0\x00\x00\x00\x00:\xd0\xedp\x00\x00\x00\x00;\xae[`\x00\x00\x00\x00<\xa3\xa0p\x00\x00\x00\x00=\xa0\xb2`\x00\x00\x00\x00>\x83\x82p\x00\x00\x00\x00?|\x9f\xe0\x00\x00\x00\x00@s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F\x0cS\x00\x00\x00\x00\x00F\xecc\xf0\x00\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\x09\xf0\x00\x00\x00\x00M\x95\x15\x80\x00\x00\x00\x00N\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QT\xd9\x80\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\x08\x00\x00\x1c \x00\x0c\x00\x008@\x01\x10LMT\x00JMT\x00IDT\x00IST\x00IDDT\x00\x0aIST-2IDT,M3.4.4/26,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\x0b\x00\x00\x00Asia/ThimbuTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\xd5\xe6\x15t\x00\x00\x00\x00!aM\xa8\x01\x02\x00\x00T\x0c\x00\x00\x00\x00MX\x00\x04\x00\x00T`\x00\x0aLMT\x00+0530\x00+06\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\x0c\x00\x00\x00Asia/ThimphuTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\xd5\xe6\x15t\x00\x00\x00\x00!aM\xa8\x01\x02\x00\x00T\x0c\x00\x00\x00\x00MX\x00\x04\x00\x00T`\x00\x0aLMT\x00+0530\x00+06\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\x0a\x00\x00\x00Asia/TokyoTZif2\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\x09\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xffe\xc2\xa4p\xff\xff\xff\xff\xd7>\x02p\xff\xff\xff\xff\xd7\xedY\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd;\xf0\xff\xff\xff\xff\xdb\x07\x00\xf0\xff\xff\xff\xff\xdb\xad\x1d\xf0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\xdd\x8c\xff\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x83\x03\x00\x00\x00\x00\x8c\xa0\x01\x04\x00\x00~\x90\x00\x08LMT\x00JDT\x00JST\x00\x0aJST-9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[u\x99q\xf1\x02\x00\x00\xf1\x02\x00\x00\x0a\x00\x00\x00Asia/TomskTZif2\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\x00C\x00\x00\x00\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xe5N\xd9\xff\xff\xff\xff\xb5\xa3\xe1 \x00\x00\x00\x00\x15'o\x90\x00\x00\x00\x00\x16\x18\xa4\x00\x00\x00\x00\x00\x17\x08\xa3\x10\x00\x00\x00\x00\x17\xf9\xd7\x80\x00\x00\x00\x00\x18\xe9\xd6\x90\x00\x00\x00\x00\x19\xdb\x0b\x00\x00\x00\x00\x00\x1a\xcc[\x90\x00\x00\x00\x00\x1b\xbch\xb0\x00\x00\x00\x00\x1c\xacY\xb0\x00\x00\x00\x00\x1d\x9cJ\xb0\x00\x00\x00\x00\x1e\x8c;\xb0\x00\x00\x00\x00\x1f|,\xb0\x00\x00\x00\x00 l\x1d\xb0\x00\x00\x00\x00!\x5c\x0e\xb0\x00\x00\x00\x00\x22K\xff\xb0\x00\x00\x00\x00#;\xf0\xb0\x00\x00\x00\x00$+\xe1\xb0\x00\x00\x00\x00%\x1b\xd2\xb0\x00\x00\x00\x00&\x0b\xc3\xb0\x00\x00\x00\x00'\x04\xef0\x00\x00\x00\x00'\xf4\xe00\x00\x00\x00\x00(\xe4\xdf@\x00\x00\x00\x00)x\x87@\x00\x00\x00\x00)\xd4\xc20\x00\x00\x00\x00*\xc4\xb30\x00\x00\x00\x00+\xb4\xa40\x00\x00\x00\x00,\xa4\x950\x00\x00\x00\x00-\x94\x860\x00\x00\x00\x00.\x84w0\x00\x00\x00\x00/th0\x00\x00\x00\x000dY0\x00\x00\x00\x001]\x84\xb0\x00\x00\x00\x002r_\xb0\x00\x00\x00\x003=f\xb0\x00\x00\x00\x004RA\xb0\x00\x00\x00\x005\x1dH\xb0\x00\x00\x00\x0062#\xb0\x00\x00\x00\x006\xfd*\xb0\x00\x00\x00\x008\x1b@0\x00\x00\x00\x008\xdd\x0c\xb0\x00\x00\x00\x009\xfb\x220\x00\x00\x00\x00:\xbc\xee\xb0\x00\x00\x00\x00;\xdb\x040\x00\x00\x00\x00<\xa6\x0b0\x00\x00\x00\x00<\xce\xe9\xb0\x00\x00\x00\x00=\xba\xf4@\x00\x00\x00\x00>\x85\xfb@\x00\x00\x00\x00?\x9a\xd6@\x00\x00\x00\x00@e\xdd@\x00\x00\x00\x00A\x83\xf2\xc0\x00\x00\x00\x00BE\xbf@\x00\x00\x00\x00Cc\xd4\xc0\x00\x00\x00\x00D%\xa1@\x00\x00\x00\x00EC\xb6\xc0\x00\x00\x00\x00F\x05\x83@\x00\x00\x00\x00G#\x98\xc0\x00\x00\x00\x00G\xee\x9f\xc0\x00\x00\x00\x00I\x03z\xc0\x00\x00\x00\x00I\xce\x81\xc0\x00\x00\x00\x00J\xe3\x5c\xc0\x00\x00\x00\x00K\xaec\xc0\x00\x00\x00\x00L\xccy@\x00\x00\x00\x00M\x8eE\xc0\x00\x00\x00\x00TK\xf30\x00\x00\x00\x00WI\xf8\xc0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00O\xa7\x00\x00\x00\x00T`\x00\x04\x00\x00p\x80\x01\x08\x00\x00bp\x00\x0c\x00\x00bp\x01\x0cLMT\x00+06\x00+08\x00+07\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xc9\xd4\x5c\xbe\x00\x00\x00\xbe\x00\x00\x00\x12\x00\x00\x00Asia/Ujung_PandangTZif2\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\x04\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xff\xa1\xf2]\x90\xff\xff\xff\xff\xba\x16\xd5\x90\xff\xff\xff\xff\xcb\x88\x1d\x80\xff\xff\xff\xff\xd2V\xeep\x01\x02\x03\x04\x00\x00o\xf0\x00\x00\x00\x00o\xf0\x00\x04\x00\x00p\x80\x00\x08\x00\x00~\x90\x00\x0c\x00\x00p\x80\x00\x10LMT\x00MMT\x00+08\x00+09\x00WITA\x00\x0aWITA-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x10\x00\x00\x00Asia/UlaanbaatarTZif2\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\x002\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x86\xd3\xeeL\x00\x00\x00\x00\x0f\x0b\xdc\x90\x00\x00\x00\x00\x18\xe9\xc8\x80\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\x22K\xd5\x80\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\x0b\x99\x80\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)\xd4\x98\x00\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xa4\x5c\xf0\x00\x00\x00\x00-\x94\x5c\x00\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002M=p\x00\x00\x00\x003=<\x80\x00\x00\x00\x004-\x1fp\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x0d\x01p\x00\x00\x00\x00:\xe9\xb3\xa0\x00\x00\x00\x00;\xb4\xac\x90\x00\x00\x00\x00<\xa4\xab\xa0\x00\x00\x00\x00=\x94\x8e\x90\x00\x00\x00\x00>\x84\x8d\xa0\x00\x00\x00\x00?tp\x90\x00\x00\x00\x00@do\xa0\x00\x00\x00\x00ATR\x90\x00\x00\x00\x00BDQ\xa0\x00\x00\x00\x00C44\x90\x00\x00\x00\x00D$3\xa0\x00\x00\x00\x00E\x1dQ\x10\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00d4\x00\x00\x00\x00bp\x00\x04\x00\x00~\x90\x01\x08\x00\x00p\x80\x00\x0cLMT\x00+07\x00+09\x00+08\x00\x0a<+08>-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x0f\x00\x00\x00Asia/Ulan_BatorTZif2\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\x002\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x86\xd3\xeeL\x00\x00\x00\x00\x0f\x0b\xdc\x90\x00\x00\x00\x00\x18\xe9\xc8\x80\x00\x00\x00\x00\x19\xda\xfc\xf0\x00\x00\x00\x00\x1a\xccM\x80\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\x22K\xd5\x80\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\x0b\x99\x80\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\x98\xf0\x00\x00\x00\x00)\xd4\x98\x00\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xa4\x5c\xf0\x00\x00\x00\x00-\x94\x5c\x00\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002M=p\x00\x00\x00\x003=<\x80\x00\x00\x00\x004-\x1fp\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x0d\x01p\x00\x00\x00\x00:\xe9\xb3\xa0\x00\x00\x00\x00;\xb4\xac\x90\x00\x00\x00\x00<\xa4\xab\xa0\x00\x00\x00\x00=\x94\x8e\x90\x00\x00\x00\x00>\x84\x8d\xa0\x00\x00\x00\x00?tp\x90\x00\x00\x00\x00@do\xa0\x00\x00\x00\x00ATR\x90\x00\x00\x00\x00BDQ\xa0\x00\x00\x00\x00C44\x90\x00\x00\x00\x00D$3\xa0\x00\x00\x00\x00E\x1dQ\x10\x00\x00\x00\x00U\x15\x9a\xa0\x00\x00\x00\x00V\x05ap\x00\x00\x00\x00V\xf5|\xa0\x00\x00\x00\x00W\xe5Cp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00d4\x00\x00\x00\x00bp\x00\x04\x00\x00~\x90\x01\x08\x00\x00p\x80\x00\x0cLMT\x00+07\x00+09\x00+08\x00\x0a<+08>-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\x0b\x00\x00\x00Asia/UrumqiTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\xb0\xfe\xbad\x01\x00\x00R\x1c\x00\x00\x00\x00T`\x00\x04LMT\x00+06\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w\x86\x8d^\x03\x03\x00\x00\x03\x03\x00\x00\x0d\x00\x00\x00Asia/Ust-NeraTZif2\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\x00B\x00\x00\x00\x08\x00\x00\x00\x18\xff\xff\xff\xff\xa1\xdb\xdd\xba\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18k\xc0\x00\x00\x00\x00\x17\x08j\xd0\x00\x00\x00\x00\x17\xf9\x9f@\x00\x00\x00\x00\x18\xe9\x9eP\x00\x00\x00\x00\x19\xda\xd2\xc0\x00\x00\x00\x00\x1a\xcc#P\x00\x00\x00\x00\x1b\xbc0p\x00\x00\x00\x00\x1c\xac!p\x00\x00\x00\x00\x1d\x9c\x12p\x00\x00\x00\x00\x1e\x8c\x03p\x00\x00\x00\x00\x1f{\xf4p\x00\x00\x00\x00 k\xe5p\x00\x00\x00\x00![\xd6p\x00\x00\x00\x00\x22K\xc7p\x00\x00\x00\x00#;\xb8p\x00\x00\x00\x00$+\xa9p\x00\x00\x00\x00%\x1b\x9ap\x00\x00\x00\x00&\x0b\x8bp\x00\x00\x00\x00'\x04\xb6\xf0\x00\x00\x00\x00'\xf4\xa7\xf0\x00\x00\x00\x00(\xe4\xa7\x00\x00\x00\x00\x00)xO\x00\x00\x00\x00\x00)\xd4\x89\xf0\x00\x00\x00\x00*\xc4z\xf0\x00\x00\x00\x00+\xb4k\xf0\x00\x00\x00\x00,\xa4\x5c\xf0\x00\x00\x00\x00-\x94M\xf0\x00\x00\x00\x00.\x84>\xf0\x00\x00\x00\x00/t/\xf0\x00\x00\x00\x000d \xf0\x00\x00\x00\x001]Lp\x00\x00\x00\x002r'p\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x09p\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xebp\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\x07\xf0\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xfa\xe9\xf0\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xcb\xf0\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xad\xf0\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x8f\xf0\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xacp\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x8ep\x00\x00\x00\x00D%Z\xf0\x00\x00\x00\x00ECpp\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Rp\x00\x00\x00\x00G\xeeYp\x00\x00\x00\x00I\x034p\x00\x00\x00\x00I\xce;p\x00\x00\x00\x00J\xe3\x16p\x00\x00\x00\x00K\xae\x1dp\x00\x00\x00\x00L\xcc2\xf0\x00\x00\x00\x00M\x8d\xffp\x00\x00\x00\x00Nm\xf4@\x00\x00\x00\x00TK\xba\xf0\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x05\x06\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x07\x03\x06\x00\x00\x86F\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\x08\x00\x00\x9a\xb0\x00\x0c\x00\x00\xa8\xc0\x01\x10\x00\x00\x9a\xb0\x01\x0c\x00\x00\x8c\xa0\x00\x14\x00\x00\xa8\xc0\x00\x10LMT\x00+08\x00+09\x00+11\x00+12\x00+10\x00\x0a<+10>-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0e\x00\x00\x00Asia/VientianeTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\x08LMT\x00BMT\x00+07\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d%\x05\xd8\xe6\x02\x00\x00\xe6\x02\x00\x00\x10\x00\x00\x00Asia/VladivostokTZif2\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\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa7YG]\xff\xff\xff\xff\xb5\xa3\xb6\xf0\x00\x00\x00\x00\x15'E`\x00\x00\x00\x00\x16\x18y\xd0\x00\x00\x00\x00\x17\x08x\xe0\x00\x00\x00\x00\x17\xf9\xadP\x00\x00\x00\x00\x18\xe9\xac`\x00\x00\x00\x00\x19\xda\xe0\xd0\x00\x00\x00\x00\x1a\xcc1`\x00\x00\x00\x00\x1b\xbc>\x80\x00\x00\x00\x00\x1c\xac/\x80\x00\x00\x00\x00\x1d\x9c \x80\x00\x00\x00\x00\x1e\x8c\x11\x80\x00\x00\x00\x00\x1f|\x02\x80\x00\x00\x00\x00 k\xf3\x80\x00\x00\x00\x00![\xe4\x80\x00\x00\x00\x00\x22K\xd5\x80\x00\x00\x00\x00#;\xc6\x80\x00\x00\x00\x00$+\xb7\x80\x00\x00\x00\x00%\x1b\xa8\x80\x00\x00\x00\x00&\x0b\x99\x80\x00\x00\x00\x00'\x04\xc5\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xe4\xb5\x10\x00\x00\x00\x00)x]\x10\x00\x00\x00\x00)\xd4\x98\x00\x00\x00\x00\x00*\xc4\x89\x00\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xa4k\x00\x00\x00\x00\x00-\x94\x5c\x00\x00\x00\x00\x00.\x84M\x00\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000d/\x00\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xfa\xf8\x00\x00\x00\x00\x00:\xbc\xc4\x80\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D%i\x00\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xeeg\x80\x00\x00\x00\x00I\x03B\x80\x00\x00\x00\x00I\xceI\x80\x00\x00\x00\x00J\xe3$\x80\x00\x00\x00\x00K\xae+\x80\x00\x00\x00\x00L\xccA\x00\x00\x00\x00\x00M\x8e\x0d\x80\x00\x00\x00\x00TK\xba\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00{\xa3\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x9a\xb0\x01\x08\x00\x00\x8c\xa0\x00\x0c\x00\x00\x8c\xa0\x01\x0c\x00\x00\x9a\xb0\x00\x08LMT\x00+09\x00+11\x00+10\x00\x0a<+10>-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O\xb0\x03\xe9\xe5\x02\x00\x00\xe5\x02\x00\x00\x0c\x00\x00\x00Asia/YakutskTZif2\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\x00A\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\xdb\xea^\xff\xff\xff\xff\xb5\xa3\xc5\x00\x00\x00\x00\x00\x15'Sp\x00\x00\x00\x00\x16\x18\x87\xe0\x00\x00\x00\x00\x17\x08\x86\xf0\x00\x00\x00\x00\x17\xf9\xbb`\x00\x00\x00\x00\x18\xe9\xbap\x00\x00\x00\x00\x19\xda\xee\xe0\x00\x00\x00\x00\x1a\xcc?p\x00\x00\x00\x00\x1b\xbcL\x90\x00\x00\x00\x00\x1c\xac=\x90\x00\x00\x00\x00\x1d\x9c.\x90\x00\x00\x00\x00\x1e\x8c\x1f\x90\x00\x00\x00\x00\x1f|\x10\x90\x00\x00\x00\x00 l\x01\x90\x00\x00\x00\x00![\xf2\x90\x00\x00\x00\x00\x22K\xe3\x90\x00\x00\x00\x00#;\xd4\x90\x00\x00\x00\x00$+\xc5\x90\x00\x00\x00\x00%\x1b\xb6\x90\x00\x00\x00\x00&\x0b\xa7\x90\x00\x00\x00\x00'\x04\xd3\x10\x00\x00\x00\x00'\xf4\xc4\x10\x00\x00\x00\x00(\xe4\xc3 \x00\x00\x00\x00)xk \x00\x00\x00\x00)\xd4\xa6\x10\x00\x00\x00\x00*\xc4\x97\x10\x00\x00\x00\x00+\xb4\x88\x10\x00\x00\x00\x00,\xa4y\x10\x00\x00\x00\x00-\x94j\x10\x00\x00\x00\x00.\x84[\x10\x00\x00\x00\x00/tL\x10\x00\x00\x00\x000d=\x10\x00\x00\x00\x001]h\x90\x00\x00\x00\x002rC\x90\x00\x00\x00\x003=J\x90\x00\x00\x00\x004R%\x90\x00\x00\x00\x005\x1d,\x90\x00\x00\x00\x0062\x07\x90\x00\x00\x00\x006\xfd\x0e\x90\x00\x00\x00\x008\x1b$\x10\x00\x00\x00\x008\xdc\xf0\x90\x00\x00\x00\x009\xfb\x06\x10\x00\x00\x00\x00:\xbc\xd2\x90\x00\x00\x00\x00;\xda\xe8\x10\x00\x00\x00\x00<\xa5\xef\x10\x00\x00\x00\x00=\xba\xca\x10\x00\x00\x00\x00>\x85\xd1\x10\x00\x00\x00\x00?\x9a\xac\x10\x00\x00\x00\x00@e\xb3\x10\x00\x00\x00\x00A\x83\xc8\x90\x00\x00\x00\x00BE\x95\x10\x00\x00\x00\x00Cc\xaa\x90\x00\x00\x00\x00D%w\x10\x00\x00\x00\x00EC\x8c\x90\x00\x00\x00\x00F\x05Y\x10\x00\x00\x00\x00G#n\x90\x00\x00\x00\x00G\xeeu\x90\x00\x00\x00\x00I\x03P\x90\x00\x00\x00\x00I\xceW\x90\x00\x00\x00\x00J\xe32\x90\x00\x00\x00\x00K\xae9\x90\x00\x00\x00\x00L\xccO\x10\x00\x00\x00\x00M\x8e\x1b\x90\x00\x00\x00\x00TK\xc9\x00\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x03\x00\x00y\xa2\x00\x00\x00\x00p\x80\x00\x04\x00\x00\x8c\xa0\x01\x08\x00\x00~\x90\x00\x0c\x00\x00~\x90\x01\x0c\x00\x00\x8c\xa0\x00\x08LMT\x00+08\x00+10\x00+09\x00\x0a<+09>-9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\x87{_\xbb\x00\x00\x00\xbb\x00\x00\x00\x0b\x00\x00\x00Asia/YangonTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xff\xd1\x9ag\xf0\x01\x02\x03\x02\x00\x00Z/\x00\x00\x00\x00Z/\x00\x04\x00\x00[h\x00\x08\x00\x00~\x90\x00\x0eLMT\x00RMT\x00+0630\x00+09\x00\x0a<+0630>-6:30\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xea\x18\xd4\xf8\x02\x00\x00\xf8\x02\x00\x00\x12\x00\x00\x00Asia/YekaterinburgTZif2\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\x00B\x00\x00\x00\x07\x00\x00\x00\x14\xff\xff\xff\xff\x9b_\x09'\xff\xff\xff\xff\xa1\x12\xb1\xff\xff\xff\xff\xff\xb5\xa3\xfd@\x00\x00\x00\x00\x15'\x8b\xb0\x00\x00\x00\x00\x16\x18\xc0 \x00\x00\x00\x00\x17\x08\xbf0\x00\x00\x00\x00\x17\xf9\xf3\xa0\x00\x00\x00\x00\x18\xe9\xf2\xb0\x00\x00\x00\x00\x19\xdb' \x00\x00\x00\x00\x1a\xccw\xb0\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xacu\xd0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8cW\xd0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 l9\xd0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L\x1b\xd0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$+\xfd\xd0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\x0b\xdf\xd0\x00\x00\x00\x00'\x05\x0bP\x00\x00\x00\x00'\xf4\xfcP\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)x\xa3`\x00\x00\x00\x00)\xd4\xdeP\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xc0P\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xa2P\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x84P\x00\x00\x00\x000duP\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\x82\xd0\x00\x00\x00\x004R]\xd0\x00\x00\x00\x005\x1dd\xd0\x00\x00\x00\x0062?\xd0\x00\x00\x00\x006\xfdF\xd0\x00\x00\x00\x008\x1b\x5cP\x00\x00\x00\x008\xdd(\xd0\x00\x00\x00\x009\xfb>P\x00\x00\x00\x00:\xbd\x0a\xd0\x00\x00\x00\x00;\xdb P\x00\x00\x00\x00<\xa6'P\x00\x00\x00\x00=\xbb\x02P\x00\x00\x00\x00>\x86\x09P\x00\x00\x00\x00?\x9a\xe4P\x00\x00\x00\x00@e\xebP\x00\x00\x00\x00A\x84\x00\xd0\x00\x00\x00\x00BE\xcdP\x00\x00\x00\x00Cc\xe2\xd0\x00\x00\x00\x00D%\xafP\x00\x00\x00\x00EC\xc4\xd0\x00\x00\x00\x00F\x05\x91P\x00\x00\x00\x00G#\xa6\xd0\x00\x00\x00\x00G\xee\xad\xd0\x00\x00\x00\x00I\x03\x88\xd0\x00\x00\x00\x00I\xce\x8f\xd0\x00\x00\x00\x00J\xe3j\xd0\x00\x00\x00\x00K\xaeq\xd0\x00\x00\x00\x00L\xcc\x87P\x00\x00\x00\x00M\x8eS\xd0\x00\x00\x00\x00TL\x01@\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x05\x02\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\x03\x04\x03\x04\x03\x04\x03\x04\x06\x04\x00\x008\xd9\x00\x00\x00\x004\xc1\x00\x04\x00\x008@\x00\x08\x00\x00T`\x01\x0c\x00\x00FP\x00\x10\x00\x00FP\x01\x10\x00\x00T`\x00\x0cLMT\x00PMT\x00+04\x00+06\x00+05\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x95-\xad\xc4\x02\x00\x00\xc4\x02\x00\x00\x0c\x00\x00\x00Asia/YerevanTZif2\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\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x19\x9aH\xff\xff\xff\xff\xe7\xda\x0cP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\x08\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a\xcc\x85\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c8\xe0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\x0b\xe0\x00\x00\x00\x00%\x1b\xfc\xe0\x00\x00\x00\x00&\x0b\xed\xe0\x00\x00\x00\x00'\x05\x19`\x00\x00\x00\x00'\xf5\x0a`\x00\x00\x00\x00(\xe5\x09p\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00BE\xdb`\x00\x00\x00\x00Cc\xf0\xe0\x00\x00\x00\x00D%\xbd`\x00\x00\x00\x00EC\xd2\xe0\x00\x00\x00\x00F\x05\x9f`\x00\x00\x00\x00G#\xb4\xe0\x00\x00\x00\x00G\xee\xbb\xe0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00I\xce\x9d\xe0\x00\x00\x00\x00J\xe3x\xe0\x00\x00\x00\x00K\xae\x7f\xe0\x00\x00\x00\x00L\xcc\x95`\x00\x00\x00\x00M\x8ea\xe0\x00\x00\x00\x00N\xacw`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00)\xb8\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\x08\x00\x008@\x00\x0c\x00\x008@\x01\x0cLMT\x00+03\x00+05\x00+04\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x8dY\x80\xad\x05\x00\x00\xad\x05\x00\x00\x0f\x00\x00\x00Atlantic/AzoresTZif2\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\x8c\x00\x00\x00\x07\x00\x00\x00\x18\xff\xff\xff\xff^=\x1b\x90\xff\xff\xff\xff\x92\xe6\xaa\xa0\xff\xff\xff\xff\x9bK\x89\x90\xff\xff\xff\xff\x9b\xfe\xe3\xa0\xff\xff\xff\xff\x9c\x9d\x09\x90\xff\xff\xff\xff\x9d\xc9\x9f\x90\xff\xff\xff\xff\x9e\x7f\x8e\x90\xff\xff\xff\xff\x9f\xaa\xd3\x10\xff\xff\xff\xff\xa0_p\x90\xff\xff\xff\xff\xa1\x8c\x06\x90\xff\xff\xff\xff\xa2A\xf5\x90\xff\xff\xff\xff\xa3n\x8b\x90\xff\xff\xff\xff\xa4#)\x10\xff\xff\xff\xff\xa5O\xbf\x10\xff\xff\xff\xff\xaa\x06\x0b\x90\xff\xff\xff\xff\xaa\xf4\xab\x10\xff\xff\xff\xff\xad\xc9\xc4\x10\xff\xff\xff\xff\xae\xa7@\x10\xff\xff\xff\xff\xaf\xa0k\x90\xff\xff\xff\xff\xb0\x87\x22\x10\xff\xff\xff\xff\xb1\x89\x88\x10\xff\xff\xff\xff\xb2p>\x90\xff\xff\xff\xff\xb3r\xa4\x90\xff\xff\xff\xff\xb4P \x90\xff\xff\xff\xff\xb72h\x90\xff\xff\xff\xff\xb8\x0f\xe4\x90\xff\xff\xff\xff\xb8\xff\xd5\x90\xff\xff\xff\xff\xb9\xef\xc6\x90\xff\xff\xff\xff\xbc\xc8\xd4\x10\xff\xff\xff\xff\xbd\xb8\xc5\x10\xff\xff\xff\xff\xbe\x9f{\x90\xff\xff\xff\xff\xbf\x98\xa7\x10\xff\xff\xff\xff\xc0\x9b\x0d\x10\xff\xff\xff\xff\xc1x\x89\x10\xff\xff\xff\xff\xc2hz\x10\xff\xff\xff\xff\xc3Xk\x10\xff\xff\xff\xff\xc4?!\x90\xff\xff\xff\xff\xc58M\x10\xff\xff\xff\xff\xc6:\xb3\x10\xff\xff\xff\xff\xc7X\xc8\x90\xff\xff\xff\xff\xc7\xd9\xfb\x90\xff\xff\xff\xff\xc9\x01K\x90\xff\xff\xff\xff\xc9\xf1<\x90\xff\xff\xff\xff\xca\xe2\x7f\x10\xff\xff\xff\xff\xcb\xb5o\x10\xff\xff\xff\xff\xcb\xec\xc0\x00\xff\xff\xff\xff\xcc\x80h\x00\xff\xff\xff\xff\xcc\xdc\xbf\x10\xff\xff\xff\xff\xcd\x95Q\x10\xff\xff\xff\xff\xcd\xc3g\x80\xff\xff\xff\xff\xcer\xbf\x00\xff\xff\xff\xff\xce\xc5\xdb\x90\xff\xff\xff\xff\xcfu3\x10\xff\xff\xff\xff\xcf\xac\x84\x00\xff\xff\xff\xff\xd0R\xa1\x00\xff\xff\xff\xff\xd0\xa5\xbd\x90\xff\xff\xff\xff\xd1U\x15\x10\xff\xff\xff\xff\xd1\x8cf\x00\xff\xff\xff\xff\xd22\x83\x00\xff\xff\xff\xff\xd2\x85\x9f\x90\xff\xff\xff\xff\xd3Y\xe1\x10\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd59\xed@\xff\xff\xff\xff\xd6)\xde@\xff\xff\xff\xff\xd7\x19\xcf@\xff\xff\xff\xff\xd8\x09\xc0@\xff\xff\xff\xff\xd8\xf9\xb1@\xff\xff\xff\xff\xd9\xe9\xa2@\xff\xff\xff\xff\xda\xd9\x93@\xff\xff\xff\xff\xdb\xc9\x84@\xff\xff\xff\xff\xdc\xb9u@\xff\xff\xff\xff\xdd\xb2\xa0\xc0\xff\xff\xff\xff\xde\xa2\x91\xc0\xff\xff\xff\xff\xdf\x92\x82\xc0\xff\xff\xff\xff\xe0\x82s\xc0\xff\xff\xff\xff\xe1rd\xc0\xff\xff\xff\xff\xe2bU\xc0\xff\xff\xff\xff\xe3RF\xc0\xff\xff\xff\xff\xe4B7\xc0\xff\xff\xff\xff\xe52(\xc0\xff\xff\xff\xff\xe6\x22\x19\xc0\xff\xff\xff\xff\xe7\x1bE@\xff\xff\xff\xff\xe8\x0b6@\xff\xff\xff\xff\xe8\xfb'@\xff\xff\xff\xff\xe9\xeb\x18@\xff\xff\xff\xff\xea\xdb\x09@\xff\xff\xff\xff\xeb\xca\xfa@\xff\xff\xff\xff\xec\xba\xeb@\xff\xff\xff\xff\xed\xaa\xdc@\xff\xff\xff\xff\xee\x9a\xcd@\xff\xff\xff\xff\xef\x8a\xbe@\xff\xff\xff\xff\xf0z\xaf@\xff\xff\xff\xff\xf1j\xa0@\xff\xff\xff\xff\xf2c\xcb\xc0\xff\xff\xff\xff\xf3S\xbc\xc0\xff\xff\xff\xff\xf4C\xad\xc0\xff\xff\xff\xff\xf53\x9e\xc0\xff\xff\xff\xff\xf6#\x8f\xc0\xff\xff\xff\xff\xf7\x13\x80\xc0\xff\xff\xff\xff\xf8\x03q\xc0\xff\xff\xff\xff\xf8\xf3b\xc0\x00\x00\x00\x00\x0d\x9b)\x10\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T&\xa0\x00\x00\x00\x00\x13D\x09\x90\x00\x00\x00\x00\x144\x08\xa0\x00\x00\x00\x00\x15#\xf9\xa0\x00\x00\x00\x00\x16\x13\xea\xa0\x00\x00\x00\x00\x17\x03\xdb\xa0\x00\x00\x00\x00\x17\xf3\xcc\xa0\x00\x00\x00\x00\x18\xe3\xcb\xb0\x00\x00\x00\x00\x19\xd3\xae\xa0\x00\x00\x00\x00\x1a\xc3\x9f\xa0\x00\x00\x00\x00\x1b\xbc\xcb \x00\x00\x00\x00\x1c\xac\xbc \x00\x00\x00\x00\x1d\x9c\xad \x00\x00\x00\x00\x1e\x8c\x9e \x00\x00\x00\x00\x1f|\x8f \x00\x00\x00\x00 l\x80 \x00\x00\x00\x00!\x5cq \x00\x00\x00\x00\x22Lb \x00\x00\x00\x00#<S \x00\x00\x00\x00$,D \x00\x00\x00\x00%\x1c5 \x00\x00\x00\x00&\x0c& \x00\x00\x00\x00'\x05Q\xa0\x00\x00\x00\x00'\xf5B\xa0\x00\x00\x00\x00(\xe53\xa0\x00\x00\x00\x00)\xd5$\xa0\x00\x00\x00\x00*\xc5\x15\xa0\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\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\x06\x04\x05\x04\x05\x04\x05\x04\xff\xff\xe7\xf0\x00\x00\xff\xff\xe5(\x00\x04\xff\xff\xf1\xf0\x01\x08\xff\xff\xe3\xe0\x00\x0c\x00\x00\x00\x00\x01\x10\xff\xff\xf1\xf0\x00\x08\x00\x00\x00\x00\x00\x14LMT\x00HMT\x00-01\x00-02\x00+00\x00WET\x00\x0a<-01>1<+00>,M3.5.0/0,M10.5.0/1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l&\x04\x99\x00\x04\x00\x00\x00\x04\x00\x00\x10\x00\x00\x00Atlantic/BermudaTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x18F\xff\xff\xff\xff\x9c\xcc\xaeF\xff\xff\xff\xff\x9d\xb7K6\xff\xff\xff\xff\x9e\xb8m\xc6\xff\xff\xff\xff\x9f\x84\xb86\xff\xff\xff\xff\xb4\xc3\x1d\xe6\xff\xff\xff\xff\xcbb\xa6\xe0\xff\xff\xff\xff\xcc\xd3\xbc\xd0\xff\xff\xff\xff\xcd\x9e\xd1\xe0\xff\xff\xff\xff\xce\xc6\x13\xd0\xff\xff\xff\xff\xcfuy`\xff\xff\xff\xff\xd0\xaf0P\xff\xff\xff\xff\xd1U[`\xff\xff\xff\xff\xd2\x8f\x12P\xff\xff\xff\xff\xd5qh`\xff\xff\xff\xff\xd6\x0e<\xd0\xff\xff\xff\xff\xd7Z\x84\xe0\xff\xff\xff\xff\xd7\xe4\xe4P\xff\xff\xff\xff\xd9:f\xe0\xff\xff\xff\xff\xd9\xc4\xc6P\xff\xff\xff\xff\xdb#\x83`\xff\xff\xff\xff\xdb\xa4\xa8P\xff\xff\xff\xff\xdd\x03e`\xff\xff\xff\xff\xdd\x84\x8aP\xff\xff\xff\xff\xde\xe3G`\xff\xff\xff\xff\xdfm\xa6\xd0\xff\xff\xff\xff\xe6l\x09\xe0\xff\xff\xff\xff\xe77\x02\xd0\x00\x00\x00\x00\x08 \xb3`\x00\x00\x00\x00\x09\x10\x96P\x00\x00\x00\x00\x0a\x00\x95`\x00\x00\x00\x00\x0a\xf0xP\x00\x00\x00\x00\x0b\xe0w`\x00\x00\x00\x00\x0c\xd9\x94\xd0\x00\x00\x00\x00\x0d\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\x22\x1bP\x00\x00\x00\x00\x19\x08\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\x22U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\x0aG\xd0\x00\x00\x00\x00)\xde\x97`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\x0aP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;\xdb\x90\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\x02\x01\x02\x01\x02\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\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\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\xff\xff\xc3:\x00\x00\xff\xff\xd1J\x01\x04\xff\xff\xc3:\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xc7\xc0\x00\x10LMT\x00BST\x00BMT\x00ADT\x00AST\x00\x0aAST4ADT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf|7\xb3\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00Atlantic/CanaryTZif2\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\x11\xff\xff\xff\xff\xa6\x04\x5c\xf0\xff\xff\xff\xff\xd4A\xf7 \x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xf1\x90\x00\x00\xff\xff\xf1\xf0\x00\x04\x00\x00\x00\x00\x00\x08\x00\x00\x0e\x10\x01\x0cLMT\x00-01\x00WET\x00WEST\x00\x0aWET0WEST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc2\x97N\xad\xaf\x00\x00\x00\xaf\x00\x00\x00\x13\x00\x00\x00Atlantic/Cape_VerdeTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x0c\xff\xff\xff\xff\x92\xe6\xaa\xa0\xff\xff\xff\xff\xcc\x95\x9c \xff\xff\xff\xff\xd2t|\x10\x00\x00\x00\x00\x0b\x17\xf7@\x01\x02\x01\x03\xff\xff\xe9\xf4\x00\x00\xff\xff\xe3\xe0\x00\x04\xff\xff\xf1\xf0\x01\x08\xff\xff\xf1\xf0\x00\x08LMT\x00-02\x00-01\x00\x0a<-01>1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0f\x00\x00\x00Atlantic/FaeroeTZif2\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\x03\x00\x00\x00\x0d\xff\xff\xff\xff\x8bm\xa4X\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\xff\xff\xf9\xa8\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\x08LMT\x00WET\x00WEST\x00\x0aWET0WEST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0e\x00\x00\x00Atlantic/FaroeTZif2\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\x03\x00\x00\x00\x0d\xff\xff\xff\xff\x8bm\xa4X\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\xff\xff\xf9\xa8\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x01\x08LMT\x00WET\x00WEST\x00\x0aWET0WEST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x12\x00\x00\x00Atlantic/Jan_MayenTZif2\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\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x09q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xb6\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xff\xd2\xa1O\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\xd5\xa8s\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\x09\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\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\x0c\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\x09\x00\x00*0\x01\x0dLMT\x00CEST\x00CET\x00CEMT\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001)7\xad\xad\x05\x00\x00\xad\x05\x00\x00\x10\x00\x00\x00Atlantic/MadeiraTZif2\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\x8c\x00\x00\x00\x07\x00\x00\x00\x1d\xff\xff\xff\xff^=\x13X\xff\xff\xff\xff\x92\xe6\x9c\x90\xff\xff\xff\xff\x9bK{\x80\xff\xff\xff\xff\x9b\xfe\xd5\x90\xff\xff\xff\xff\x9c\x9c\xfb\x80\xff\xff\xff\xff\x9d\xc9\x91\x80\xff\xff\xff\xff\x9e\x7f\x80\x80\xff\xff\xff\xff\x9f\xaa\xc5\x00\xff\xff\xff\xff\xa0_b\x80\xff\xff\xff\xff\xa1\x8b\xf8\x80\xff\xff\xff\xff\xa2A\xe7\x80\xff\xff\xff\xff\xa3n}\x80\xff\xff\xff\xff\xa4#\x1b\x00\xff\xff\xff\xff\xa5O\xb1\x00\xff\xff\xff\xff\xaa\x05\xfd\x80\xff\xff\xff\xff\xaa\xf4\x9d\x00\xff\xff\xff\xff\xad\xc9\xb6\x00\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0]\x80\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff\xb3r\x96\x80\xff\xff\xff\xff\xb4P\x12\x80\xff\xff\xff\xff\xb72Z\x80\xff\xff\xff\xff\xb8\x0f\xd6\x80\xff\xff\xff\xff\xb8\xff\xc7\x80\xff\xff\xff\xff\xb9\xef\xb8\x80\xff\xff\xff\xff\xbc\xc8\xc6\x00\xff\xff\xff\xff\xbd\xb8\xb7\x00\xff\xff\xff\xff\xbe\x9fm\x80\xff\xff\xff\xff\xbf\x98\x99\x00\xff\xff\xff\xff\xc0\x9a\xff\x00\xff\xff\xff\xff\xc1x{\x00\xff\xff\xff\xff\xc2hl\x00\xff\xff\xff\xff\xc3X]\x00\xff\xff\xff\xff\xc4?\x13\x80\xff\xff\xff\xff\xc58?\x00\xff\xff\xff\xff\xc6:\xa5\x00\xff\xff\xff\xff\xc7X\xba\x80\xff\xff\xff\xff\xc7\xd9\xed\x80\xff\xff\xff\xff\xc9\x01=\x80\xff\xff\xff\xff\xc9\xf1.\x80\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xb5a\x00\xff\xff\xff\xff\xcb\xec\xb1\xf0\xff\xff\xff\xff\xcc\x80Y\xf0\xff\xff\xff\xff\xcc\xdc\xb1\x00\xff\xff\xff\xff\xcd\x95C\x00\xff\xff\xff\xff\xcd\xc3Yp\xff\xff\xff\xff\xcer\xb0\xf0\xff\xff\xff\xff\xce\xc5\xcd\x80\xff\xff\xff\xff\xcfu%\x00\xff\xff\xff\xff\xcf\xacu\xf0\xff\xff\xff\xff\xd0R\x92\xf0\xff\xff\xff\xff\xd0\xa5\xaf\x80\xff\xff\xff\xff\xd1U\x07\x00\xff\xff\xff\xff\xd1\x8cW\xf0\xff\xff\xff\xff\xd22t\xf0\xff\xff\xff\xff\xd2\x85\x91\x80\xff\xff\xff\xff\xd3Y\xd3\x00\xff\xff\xff\xff\xd4I\xc4\x00\xff\xff\xff\xff\xd59\xdf0\xff\xff\xff\xff\xd6)\xd00\xff\xff\xff\xff\xd7\x19\xc10\xff\xff\xff\xff\xd8\x09\xb20\xff\xff\xff\xff\xd8\xf9\xa30\xff\xff\xff\xff\xd9\xe9\x940\xff\xff\xff\xff\xda\xd9\x850\xff\xff\xff\xff\xdb\xc9v0\xff\xff\xff\xff\xdc\xb9g0\xff\xff\xff\xff\xdd\xb2\x92\xb0\xff\xff\xff\xff\xde\xa2\x83\xb0\xff\xff\xff\xff\xdf\x92t\xb0\xff\xff\xff\xff\xe0\x82e\xb0\xff\xff\xff\xff\xe1rV\xb0\xff\xff\xff\xff\xe2bG\xb0\xff\xff\xff\xff\xe3R8\xb0\xff\xff\xff\xff\xe4B)\xb0\xff\xff\xff\xff\xe52\x1a\xb0\xff\xff\xff\xff\xe6\x22\x0b\xb0\xff\xff\xff\xff\xe7\x1b70\xff\xff\xff\xff\xe8\x0b(0\xff\xff\xff\xff\xe8\xfb\x190\xff\xff\xff\xff\xe9\xeb\x0a0\xff\xff\xff\xff\xea\xda\xfb0\xff\xff\xff\xff\xeb\xca\xec0\xff\xff\xff\xff\xec\xba\xdd0\xff\xff\xff\xff\xed\xaa\xce0\xff\xff\xff\xff\xee\x9a\xbf0\xff\xff\xff\xff\xef\x8a\xb00\xff\xff\xff\xff\xf0z\xa10\xff\xff\xff\xff\xf1j\x920\xff\xff\xff\xff\xf2c\xbd\xb0\xff\xff\xff\xff\xf3S\xae\xb0\xff\xff\xff\xff\xf4C\x9f\xb0\xff\xff\xff\xff\xf53\x90\xb0\xff\xff\xff\xff\xf6#\x81\xb0\xff\xff\xff\xff\xf7\x13r\xb0\xff\xff\xff\xff\xf8\x03c\xb0\xff\xff\xff\xff\xf8\xf3T\xb0\x00\x00\x00\x00\x0d\x9b\x1b\x00\x00\x00\x00\x00\x0e\x8b\x0c\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xbd\xa0\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\xff\xff\xf0(\x00\x00\xff\xff\xf0(\x00\x04\x00\x00\x00\x00\x01\x08\xff\xff\xf1\xf0\x00\x0c\x00\x00\x0e\x10\x01\x10\x00\x00\x0e\x10\x01\x14\x00\x00\x00\x00\x00\x19LMT\x00FMT\x00+00\x00-01\x00+01\x00WEST\x00WET\x00\x0aWET0WEST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00Atlantic/ReykjavikTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f-\xad\xd7\x84\x00\x00\x00\x84\x00\x00\x00\x16\x00\x00\x00Atlantic/South_GeorgiaTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xffi\x86\xfd\xc0\x01\xff\xff\xdd\xc0\x00\x00\xff\xff\xe3\xe0\x00\x04LMT\x00-02\x00\x0a<-02>2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00Atlantic/St_HelenaTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7\xcf^\xb0\x15\x03\x00\x00\x15\x03\x00\x00\x10\x00\x00\x00Atlantic/StanleyTZif2\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\x00F\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x11\xbc\xff\xff\xff\xff\x93D_<\xff\xff\xff\xff\xc3OZ\xc0\xff\xff\xff\xff\xc46\x030\xff\xff\xff\xff\xc5/<\xc0\xff\xff\xff\xff\xc6\x15\xe50\xff\xff\xff\xff\xc7\x18Y@\xff\xff\xff\xff\xc7\xff\x01\xb0\xff\xff\xff\xff\xc8\xf8;@\xff\xff\xff\xff\xc9\xde\xe3\xb0\xff\xff\xff\xff\xca\xd8\x1d@\xff\xff\xff\xff\xcb\xbe\xc5\xb0\xff\xff\xff\xff\xcc\xb7\xff@\xff\xff\xff\xff\xcd6\x810\x00\x00\x00\x00\x19\x11\xfe@\x00\x00\x00\x00\x19\xd3\xbc\xb0\x00\x00\x00\x00\x1a\xf1\xc4 \x00\x00\x00\x00\x1b\xaad0\x00\x00\x00\x00\x1c\xd1\xa6 \x00\x00\x00\x00\x1d\x8aF0\x00\x00\x00\x00\x1e\xa8[\xb0\x00\x00\x00\x00\x1fj6@\x00\x00\x00\x00 \x88=\xb0\x00\x00\x00\x00!J\x18@\x00\x00\x00\x00\x22h\x1f\xb0\x00\x00\x00\x00#)\xfa@\x00\x00\x00\x00$H\x01\xb0\x00\x00\x00\x00%\x09\xdc@\x00\x00\x00\x00&1\x1e0\x00\x00\x00\x00&\xe9\xbe@\x00\x00\x00\x00(\x11\x000\x00\x00\x00\x00(\xd2\xda\xc0\x00\x00\x00\x00)\xf0\xe20\x00\x00\x00\x00*\xb2\xbc\xc0\x00\x00\x00\x00+\xd0\xc40\x00\x00\x00\x00,\x92\x9e\xc0\x00\x00\x00\x00-\xb0\xa60\x00\x00\x00\x00.r\x80\xc0\x00\x00\x00\x00/\x90\x880\x00\x00\x00\x000Rb\xc0\x00\x00\x00\x001y\xa4\xb0\x00\x00\x00\x002;\x7f@\x00\x00\x00\x003Y\x86\xb0\x00\x00\x00\x004\x1ba@\x00\x00\x00\x0059h\xb0\x00\x00\x00\x005\xfbC@\x00\x00\x00\x007\x19J\xb0\x00\x00\x00\x007\xdb%@\x00\x00\x00\x008\xf9,\xb0\x00\x00\x00\x009\xbb\x07@\x00\x00\x00\x00:\xd9*\xd0\x00\x00\x00\x00;\x91\xca\xe0\x00\x00\x00\x00<\xc2GP\x00\x00\x00\x00=q\xac\xe0\x00\x00\x00\x00>\xa2)P\x00\x00\x00\x00?Z\xc9`\x00\x00\x00\x00@\x82\x0bP\x00\x00\x00\x00A:\xab`\x00\x00\x00\x00Ba\xedP\x00\x00\x00\x00C\x1a\x8d`\x00\x00\x00\x00DA\xcfP\x00\x00\x00\x00D\xfao`\x00\x00\x00\x00F!\xb1P\x00\x00\x00\x00F\xdaQ`\x00\x00\x00\x00H\x0a\xcd\xd0\x00\x00\x00\x00H\xc3m\xe0\x00\x00\x00\x00I\xea\xaf\xd0\x00\x00\x00\x00J\xa3O\xe0\x00\x00\x00\x00K\xca\x91\xd0\x00\x00\x00\x00L\x831\xe0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\x04\x05\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x05\xff\xff\xc9\xc4\x00\x00\xff\xff\xc9\xc4\x00\x04\xff\xff\xd5\xd0\x01\x08\xff\xff\xc7\xc0\x00\x0c\xff\xff\xe3\xe0\x01\x10\xff\xff\xd5\xd0\x00\x08LMT\x00SMT\x00-03\x00-04\x00-02\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x0d\x00\x00\x00Australia/ACTTZif2\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\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x7f<\xff\xff\xff\xff\x9cN\xc2\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff\xcc\xb7V\x80\xff\xff\xff\xff\xcd\xa7G\x80\xff\xff\xff\xff\xce\xa0s\x00\xff\xff\xff\xff\xcf\x87)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\x07/\xfd\x80\x00\x00\x00\x00\x07\xd6\x1a\x80\x00\x00\x00\x00\x09\x0f\xdf\x80\x00\x00\x00\x00\x09\xb5\xfc\x80\x00\x00\x00\x00\x0a\xef\xc1\x80\x00\x00\x00\x00\x0b\x9f\x19\x00\x00\x00\x00\x00\x0c\xd8\xde\x00\x00\x00\x00\x00\x0d~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x0c\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xc7\x81\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\x0a\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\xce\x80\x00\x00\x00\x00\x22B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\x22}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\x09\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98\xca\x80\x00\x00\x00\x00,\xd2\x8f\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc\xc4\x80\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\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\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\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\x09LMT\x00AEDT\x00AEST\x00\x0aAEST-10AEDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ff~\xd5\x99\x03\x00\x00\x99\x03\x00\x00\x12\x00\x00\x00Australia/AdelaideTZif2\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\x00T\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x8b\x14\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cN\xc9\x88\xff\xff\xff\xff\x9c\xbc6\x08\xff\xff\xff\xff\xcbT\xba\x08\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff\xcc\xb7]\x88\xff\xff\xff\xff\xcd\xa7N\x88\xff\xff\xff\xff\xce\xa0z\x08\xff\xff\xff\xff\xcf\x870\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\x0d#\x08\x00\x00\x00\x00\x05P\x22\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\x070\x04\x88\x00\x00\x00\x00\x07\xd6!\x88\x00\x00\x00\x00\x09\x0f\xe6\x88\x00\x00\x00\x00\x09\xb6\x03\x88\x00\x00\x00\x00\x0a\xef\xc8\x88\x00\x00\x00\x00\x0b\x9f \x08\x00\x00\x00\x00\x0c\xd8\xe5\x08\x00\x00\x00\x00\x0d\x7f\x02\x08\x00\x00\x00\x00\x0e\xb8\xc7\x08\x00\x00\x00\x00\x0f^\xe4\x08\x00\x00\x00\x00\x10\x98\xa9\x08\x00\x00\x00\x00\x11>\xc6\x08\x00\x00\x00\x00\x12x\x8b\x08\x00\x00\x00\x00\x13\x1e\xa8\x08\x00\x00\x00\x00\x14Xm\x08\x00\x00\x00\x00\x14\xfe\x8a\x08\x00\x00\x00\x00\x168O\x08\x00\x00\x00\x00\x16\xe7\xa6\x88\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18\xc7\x88\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\x08\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80\xd5\x88\x00\x00\x00\x00\x22B\xa2\x08\x00\x00\x00\x00#i\xf2\x08\x00\x00\x00\x00$\x22\x84\x08\x00\x00\x00\x00%I\xd4\x08\x00\x00\x00\x00&\x02f\x08\x00\x00\x00\x00')\xb6\x08\x00\x00\x00\x00'\xcf\xd3\x08\x00\x00\x00\x00)\x09\x98\x08\x00\x00\x00\x00)\xcbd\x88\x00\x00\x00\x00*\xe9z\x08\x00\x00\x00\x00+\x98\xd1\x88\x00\x00\x00\x00,\xd2\x96\x88\x00\x00\x00\x00-\x8b(\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/tE\x08\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\x07\x88\x00\x00\x00\x008\x1b\x1d\x08\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\x08\x00\x00\x00\x00:\xbc\xcb\x88\x00\x00\x00\x00;\xda\xe1\x08\x00\x00\x00\x00<\xa5\xe8\x08\x00\x00\x00\x00=\xba\xc3\x08\x00\x00\x00\x00>\x85\xca\x08\x00\x00\x00\x00?\x9a\xa5\x08\x00\x00\x00\x00@e\xac\x08\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\x08\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\x08\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\x08\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x81\xec\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\x09\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\x0aACST-9:30ACDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x12\x00\x00\x00Australia/BrisbaneTZif2\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\x11\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffr\xed\x9f\x08\xff\xff\xff\xff\x9cN\xc2\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff\xcc\xb7V\x80\xff\xff\xff\xff\xcd\xa7G\x80\xff\xff\xff\xff\xce\xa0s\x00\xff\xff\xff\xff\xcf\x87)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\x09\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8fx\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\x09LMT\x00AEDT\x00AEST\x00\x0aAEST-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x15\x00\x00\x00Australia/Broken_HillTZif2\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\x00U\x00\x00\x00\x05\x00\x00\x00\x13\xff\xff\xff\xffs\x16\x88d\xff\xff\xff\xffv\x04\xa5\xe0\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cN\xc9\x88\xff\xff\xff\xff\x9c\xbc6\x08\xff\xff\xff\xff\xcbT\xba\x08\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff\xcc\xb7]\x88\xff\xff\xff\xff\xcd\xa7N\x88\xff\xff\xff\xff\xce\xa0z\x08\xff\xff\xff\xff\xcf\x870\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\x0d#\x08\x00\x00\x00\x00\x05P\x22\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\x070\x04\x88\x00\x00\x00\x00\x07\xd6!\x88\x00\x00\x00\x00\x09\x0f\xe6\x88\x00\x00\x00\x00\x09\xb6\x03\x88\x00\x00\x00\x00\x0a\xef\xc8\x88\x00\x00\x00\x00\x0b\x9f \x08\x00\x00\x00\x00\x0c\xd8\xe5\x08\x00\x00\x00\x00\x0d\x7f\x02\x08\x00\x00\x00\x00\x0e\xb8\xc7\x08\x00\x00\x00\x00\x0f^\xe4\x08\x00\x00\x00\x00\x10\x98\xa9\x08\x00\x00\x00\x00\x11>\xc6\x08\x00\x00\x00\x00\x12x\x8b\x08\x00\x00\x00\x00\x13\x1e\xa8\x08\x00\x00\x00\x00\x14Xm\x08\x00\x00\x00\x00\x14\xfe\x8a\x08\x00\x00\x00\x00\x168O\x08\x00\x00\x00\x00\x17\x0c\x90\x88\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18\xc7\x88\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\x08\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80\xd5\x88\x00\x00\x00\x00\x22B\xa2\x08\x00\x00\x00\x00#i\xf2\x08\x00\x00\x00\x00$\x22\x84\x08\x00\x00\x00\x00%I\xd4\x08\x00\x00\x00\x00%\xef\xf1\x08\x00\x00\x00\x00')\xb6\x08\x00\x00\x00\x00'\xcf\xd3\x08\x00\x00\x00\x00)\x09\x98\x08\x00\x00\x00\x00)\xaf\xb5\x08\x00\x00\x00\x00*\xe9z\x08\x00\x00\x00\x00+\x98\xd1\x88\x00\x00\x00\x00,\xd2\x96\x88\x00\x00\x00\x00-x\xb3\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/X\x95\x88\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\x07\x88\x00\x00\x00\x008\x1b\x1d\x08\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\x08\x00\x00\x00\x00:\xbc\xcb\x88\x00\x00\x00\x00;\xda\xe1\x08\x00\x00\x00\x00<\xa5\xe8\x08\x00\x00\x00\x00=\xba\xc3\x08\x00\x00\x00\x00>\x85\xca\x08\x00\x00\x00\x00?\x9a\xa5\x08\x00\x00\x00\x00@e\xac\x08\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\x08\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\x08\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\x08\x01\x02\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\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x84\x9c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\x09\x00\x00\x93\xa8\x01\x0e\x00\x00\x85\x98\x00\x09LMT\x00AEST\x00ACST\x00ACDT\x00\x0aACST-9:30ACDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00Australia/CanberraTZif2\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\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x7f<\xff\xff\xff\xff\x9cN\xc2\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff\xcc\xb7V\x80\xff\xff\xff\xff\xcd\xa7G\x80\xff\xff\xff\xff\xce\xa0s\x00\xff\xff\xff\xff\xcf\x87)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\x07/\xfd\x80\x00\x00\x00\x00\x07\xd6\x1a\x80\x00\x00\x00\x00\x09\x0f\xdf\x80\x00\x00\x00\x00\x09\xb5\xfc\x80\x00\x00\x00\x00\x0a\xef\xc1\x80\x00\x00\x00\x00\x0b\x9f\x19\x00\x00\x00\x00\x00\x0c\xd8\xde\x00\x00\x00\x00\x00\x0d~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x0c\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xc7\x81\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\x0a\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\xce\x80\x00\x00\x00\x00\x22B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\x22}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\x09\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98\xca\x80\x00\x00\x00\x00,\xd2\x8f\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc\xc4\x80\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\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\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\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\x09LMT\x00AEDT\x00AEST\x00\x0aAEST-10AEDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x00\x00Australia/CurrieTZif2\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\x03\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\x9d\xdaD\x80\xff\xff\xff\xff\x9e\x80a\x80\xff\xff\xff\xff\x9f\xba&\x80\xff\xff\xff\xff\xa0`C\x80\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff\xcc\xb7V\x80\xff\xff\xff\xff\xcd\xa7G\x80\xff\xff\xff\xff\xce\xa0s\x00\xff\xff\xff\xff\xcf\x87)\x80\xff\xff\xff\xff\xfb\xc2\x8d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\x07/\xfd\x80\x00\x00\x00\x00\x07\xd6\x1a\x80\x00\x00\x00\x00\x09\x0f\xdf\x80\x00\x00\x00\x00\x09\xb5\xfc\x80\x00\x00\x00\x00\x0a\xef\xc1\x80\x00\x00\x00\x00\x0b\x9f\x19\x00\x00\x00\x00\x00\x0c\xd8\xde\x00\x00\x00\x00\x00\x0d~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\x0a\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\xce\x80\x00\x00\x00\x00\x22B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\x22}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)\xd4\x98\x00\x00\x00\x00\x00*\xcd\xc3\x80\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\x5c\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc\xc4\x80\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\x0c\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^\xd0\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\x07\xb1\x00\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\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\x8a\x1c\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\x09LMT\x00AEDT\x00AEST\x00\x0aAEST-10AEDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x10\x00\x00\x00Australia/DarwinTZif2\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\x0a\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x92X\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cN\xc9\x88\xff\xff\xff\xff\x9c\xbc6\x08\xff\xff\xff\xff\xcbT\xba\x08\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff\xcc\xb7]\x88\xff\xff\xff\xff\xcd\xa7N\x88\xff\xff\xff\xff\xce\xa0z\x08\xff\xff\xff\xff\xcf\x870\x88\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00z\xa8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\x09\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\x0aACST-9:30\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\xdc\xba\xca:\x01\x00\x00:\x01\x00\x00\x0f\x00\x00\x00Australia/EuclaTZif2\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\x13\x00\x00\x00\x03\x00\x00\x00\x10\xff\xff\xff\xfft\xa6\x0a\xb0\xff\xff\xff\xff\x9cN\xd4\x14\xff\xff\xff\xff\x9c\xbc@\x94\xff\xff\xff\xff\xcbT\xc4\x94\xff\xff\xff\xff\xcb\xc7w\x14\xff\xff\xff\xff\xcc\xb7h\x14\xff\xff\xff\xff\xcd\xa7Y\x14\x00\x00\x00\x00\x09\x0f\xf1\x14\x00\x00\x00\x00\x09\xb6\x0e\x14\x00\x00\x00\x00\x1a\x01X\x14\x00\x00\x00\x00\x1a\xa7u\x14\x00\x00\x00\x00)%R\x14\x00\x00\x00\x00)\xaf\xbf\x94\x00\x00\x00\x00Eq\xb4\x94\x00\x00\x00\x00F\x05\x5c\x94\x00\x00\x00\x00G#r\x14\x00\x00\x00\x00G\xeey\x14\x00\x00\x00\x00I\x03T\x14\x00\x00\x00\x00I\xce[\x14\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00x\xd0\x00\x00\x00\x00\x89\x1c\x01\x04\x00\x00{\x0c\x00\x0aLMT\x00+0945\x00+0845\x00\x0a<+0845>-8:45\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x00\x00Australia/HobartTZif2\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\x03\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\x9d\xdaD\x80\xff\xff\xff\xff\x9e\x80a\x80\xff\xff\xff\xff\x9f\xba&\x80\xff\xff\xff\xff\xa0`C\x80\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff\xcc\xb7V\x80\xff\xff\xff\xff\xcd\xa7G\x80\xff\xff\xff\xff\xce\xa0s\x00\xff\xff\xff\xff\xcf\x87)\x80\xff\xff\xff\xff\xfb\xc2\x8d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\x07/\xfd\x80\x00\x00\x00\x00\x07\xd6\x1a\x80\x00\x00\x00\x00\x09\x0f\xdf\x80\x00\x00\x00\x00\x09\xb5\xfc\x80\x00\x00\x00\x00\x0a\xef\xc1\x80\x00\x00\x00\x00\x0b\x9f\x19\x00\x00\x00\x00\x00\x0c\xd8\xde\x00\x00\x00\x00\x00\x0d~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\x0a\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\xce\x80\x00\x00\x00\x00\x22B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\x22}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)\xd4\x98\x00\x00\x00\x00\x00*\xcd\xc3\x80\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\x5c\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc\xc4\x80\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\x0c\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^\xd0\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\x07\xb1\x00\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\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\x8a\x1c\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\x09LMT\x00AEDT\x00AEST\x00\x0aAEST-10AEDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\x0d\x00\x00\x00Australia/LHITZif2\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\x008\x00\x00\x00\x05\x00\x00\x00\x19\xff\xff\xff\xffs\x16w\xdc\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168@\xf8\x00\x00\x00\x00\x16\xe7\x8ah\x00\x00\x00\x00\x18!]x\x00\x00\x00\x00\x18\xc7lh\x00\x00\x00\x00\x1a\x01?x\x00\x00\x00\x00\x1a\xa7Nh\x00\x00\x00\x00\x1b\xe1!x\x00\x00\x00\x00\x1c\x870h\x00\x00\x00\x00\x1d\xc1\x03x\x00\x00\x00\x00\x1ey\x8ep\x00\x00\x00\x00\x1f\x97\xaa\xf8\x00\x00\x00\x00 Ypp\x00\x00\x00\x00!\x80\xc7x\x00\x00\x00\x00\x22B\x8c\xf0\x00\x00\x00\x00#i\xe3\xf8\x00\x00\x00\x00$\x22n\xf0\x00\x00\x00\x00%I\xc5\xf8\x00\x00\x00\x00%\xef\xdb\xf0\x00\x00\x00\x00')\xa7\xf8\x00\x00\x00\x00'\xcf\xbd\xf0\x00\x00\x00\x00)\x09\x89\xf8\x00\x00\x00\x00)\xaf\x9f\xf0\x00\x00\x00\x00*\xe9k\xf8\x00\x00\x00\x00+\x98\xbcp\x00\x00\x00\x00,\xd2\x88x\x00\x00\x00\x00-x\x9ep\x00\x00\x00\x00.\xb2jx\x00\x00\x00\x00/X\x80p\x00\x00\x00\x000\x92Lx\x00\x00\x00\x001]Lp\x00\x00\x00\x002r.x\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x10x\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xf2x\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\x0e\xf8\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xa7\xe2x\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xd2\xf8\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xb4\xf8\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x96\xf8\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xb3x\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x95x\x00\x00\x00\x00D.\x95p\x00\x00\x00\x00ECwx\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Yx\x00\x00\x00\x00G\xf7\x93\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x95$\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa1\xb8\x01\x09\x00\x00\x93\xa8\x00\x0f\x00\x00\x9a\xb0\x01\x15LMT\x00AEST\x00+1130\x00+1030\x00+11\x00\x0a<+1030>-10:30<+11>-11,M10.1.0,M4.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x95\xbd\x12E\x01\x00\x00E\x01\x00\x00\x12\x00\x00\x00Australia/LindemanTZif2\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\x15\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffr\xed\xa2\xd4\xff\xff\xff\xff\x9cN\xc2\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff\xcc\xb7V\x80\xff\xff\xff\xff\xcd\xa7G\x80\xff\xff\xff\xff\xce\xa0s\x00\xff\xff\xff\xff\xcf\x87)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\x09\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98\xca\x80\x00\x00\x00\x00,\xd2\x8f\x80\x00\x00\x00\x00-x\xac\x80\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8b\xac\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\x09LMT\x00AEDT\x00AEST\x00\x0aAEST-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\x13\x00\x00\x00Australia/Lord_HoweTZif2\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\x008\x00\x00\x00\x05\x00\x00\x00\x19\xff\xff\xff\xffs\x16w\xdc\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168@\xf8\x00\x00\x00\x00\x16\xe7\x8ah\x00\x00\x00\x00\x18!]x\x00\x00\x00\x00\x18\xc7lh\x00\x00\x00\x00\x1a\x01?x\x00\x00\x00\x00\x1a\xa7Nh\x00\x00\x00\x00\x1b\xe1!x\x00\x00\x00\x00\x1c\x870h\x00\x00\x00\x00\x1d\xc1\x03x\x00\x00\x00\x00\x1ey\x8ep\x00\x00\x00\x00\x1f\x97\xaa\xf8\x00\x00\x00\x00 Ypp\x00\x00\x00\x00!\x80\xc7x\x00\x00\x00\x00\x22B\x8c\xf0\x00\x00\x00\x00#i\xe3\xf8\x00\x00\x00\x00$\x22n\xf0\x00\x00\x00\x00%I\xc5\xf8\x00\x00\x00\x00%\xef\xdb\xf0\x00\x00\x00\x00')\xa7\xf8\x00\x00\x00\x00'\xcf\xbd\xf0\x00\x00\x00\x00)\x09\x89\xf8\x00\x00\x00\x00)\xaf\x9f\xf0\x00\x00\x00\x00*\xe9k\xf8\x00\x00\x00\x00+\x98\xbcp\x00\x00\x00\x00,\xd2\x88x\x00\x00\x00\x00-x\x9ep\x00\x00\x00\x00.\xb2jx\x00\x00\x00\x00/X\x80p\x00\x00\x00\x000\x92Lx\x00\x00\x00\x001]Lp\x00\x00\x00\x002r.x\x00\x00\x00\x003=.p\x00\x00\x00\x004R\x10x\x00\x00\x00\x005\x1d\x10p\x00\x00\x00\x0061\xf2x\x00\x00\x00\x006\xfc\xf2p\x00\x00\x00\x008\x1b\x0e\xf8\x00\x00\x00\x008\xdc\xd4p\x00\x00\x00\x009\xa7\xe2x\x00\x00\x00\x00:\xbc\xb6p\x00\x00\x00\x00;\xda\xd2\xf8\x00\x00\x00\x00<\xa5\xd2\xf0\x00\x00\x00\x00=\xba\xb4\xf8\x00\x00\x00\x00>\x85\xb4\xf0\x00\x00\x00\x00?\x9a\x96\xf8\x00\x00\x00\x00@e\x96\xf0\x00\x00\x00\x00A\x83\xb3x\x00\x00\x00\x00BEx\xf0\x00\x00\x00\x00Cc\x95x\x00\x00\x00\x00D.\x95p\x00\x00\x00\x00ECwx\x00\x00\x00\x00F\x05<\xf0\x00\x00\x00\x00G#Yx\x00\x00\x00\x00G\xf7\x93\xf0\x01\x03\x02\x03\x02\x03\x02\x03\x02\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x95$\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00\xa1\xb8\x01\x09\x00\x00\x93\xa8\x00\x0f\x00\x00\x9a\xb0\x01\x15LMT\x00AEST\x00+1130\x00+1030\x00+11\x00\x0a<+1030>-10:30<+11>-11,M10.1.0,M4.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x13\x00\x00\x00Australia/MelbourneTZif2\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\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x85\x18\xff\xff\xff\xff\x9cN\xc2\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff\xcc\xb7V\x80\xff\xff\xff\xff\xcd\xa7G\x80\xff\xff\xff\xff\xce\xa0s\x00\xff\xff\xff\xff\xcf\x87)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\x07/\xfd\x80\x00\x00\x00\x00\x07\xd6\x1a\x80\x00\x00\x00\x00\x09\x0f\xdf\x80\x00\x00\x00\x00\x09\xb5\xfc\x80\x00\x00\x00\x00\x0a\xef\xc1\x80\x00\x00\x00\x00\x0b\x9f\x19\x00\x00\x00\x00\x00\x0c\xd8\xde\x00\x00\x00\x00\x00\x0d~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x16\xe7\x9f\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xc7\x81\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\x0a\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!w\x94\x00\x00\x00\x00\x00\x22B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\x22}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\x09\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98\xca\x80\x00\x00\x00\x00,\xd2\x8f\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc\xc4\x80\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\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\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\x00\x00\x87\xe8\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\x09LMT\x00AEDT\x00AEST\x00\x0aAEST-10AEDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x0d\x00\x00\x00Australia/NSWTZif2\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\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x7f<\xff\xff\xff\xff\x9cN\xc2\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff\xcc\xb7V\x80\xff\xff\xff\xff\xcd\xa7G\x80\xff\xff\xff\xff\xce\xa0s\x00\xff\xff\xff\xff\xcf\x87)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\x07/\xfd\x80\x00\x00\x00\x00\x07\xd6\x1a\x80\x00\x00\x00\x00\x09\x0f\xdf\x80\x00\x00\x00\x00\x09\xb5\xfc\x80\x00\x00\x00\x00\x0a\xef\xc1\x80\x00\x00\x00\x00\x0b\x9f\x19\x00\x00\x00\x00\x00\x0c\xd8\xde\x00\x00\x00\x00\x00\x0d~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x0c\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xc7\x81\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\x0a\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\xce\x80\x00\x00\x00\x00\x22B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\x22}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\x09\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98\xca\x80\x00\x00\x00\x00,\xd2\x8f\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc\xc4\x80\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\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\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\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\x09LMT\x00AEDT\x00AEST\x00\x0aAEST-10AEDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x0f\x00\x00\x00Australia/NorthTZif2\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\x0a\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x92X\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cN\xc9\x88\xff\xff\xff\xff\x9c\xbc6\x08\xff\xff\xff\xff\xcbT\xba\x08\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff\xcc\xb7]\x88\xff\xff\xff\xff\xcd\xa7N\x88\xff\xff\xff\xff\xce\xa0z\x08\xff\xff\xff\xff\xcf\x870\x88\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00z\xa8\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\x09\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\x0aACST-9:30\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xbb\xca\x1a2\x01\x00\x002\x01\x00\x00\x0f\x00\x00\x00Australia/PerthTZif2\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\x13\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xfft\xa6\x16\xe4\xff\xff\xff\xff\x9cN\xde\xa0\xff\xff\xff\xff\x9c\xbcK \xff\xff\xff\xff\xcbT\xcf \xff\xff\xff\xff\xcb\xc7\x81\xa0\xff\xff\xff\xff\xcc\xb7r\xa0\xff\xff\xff\xff\xcd\xa7c\xa0\x00\x00\x00\x00\x09\x0f\xfb\xa0\x00\x00\x00\x00\x09\xb6\x18\xa0\x00\x00\x00\x00\x1a\x01b\xa0\x00\x00\x00\x00\x1a\xa7\x7f\xa0\x00\x00\x00\x00)%\x5c\xa0\x00\x00\x00\x00)\xaf\xca \x00\x00\x00\x00Eq\xbf \x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\xee\x83\xa0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00l\x9c\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\x09LMT\x00AWDT\x00AWST\x00\x0aAWST-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x14\x00\x00\x00Australia/QueenslandTZif2\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\x11\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffr\xed\x9f\x08\xff\xff\xff\xff\x9cN\xc2\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff\xcc\xb7V\x80\xff\xff\xff\xff\xcd\xa7G\x80\xff\xff\xff\xff\xce\xa0s\x00\xff\xff\xff\xff\xcf\x87)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\x09\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x8fx\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\x09LMT\x00AEDT\x00AEST\x00\x0aAEST-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ff~\xd5\x99\x03\x00\x00\x99\x03\x00\x00\x0f\x00\x00\x00Australia/SouthTZif2\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\x00T\x00\x00\x00\x04\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x8b\x14\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cN\xc9\x88\xff\xff\xff\xff\x9c\xbc6\x08\xff\xff\xff\xff\xcbT\xba\x08\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff\xcc\xb7]\x88\xff\xff\xff\xff\xcd\xa7N\x88\xff\xff\xff\xff\xce\xa0z\x08\xff\xff\xff\xff\xcf\x870\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\x0d#\x08\x00\x00\x00\x00\x05P\x22\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\x070\x04\x88\x00\x00\x00\x00\x07\xd6!\x88\x00\x00\x00\x00\x09\x0f\xe6\x88\x00\x00\x00\x00\x09\xb6\x03\x88\x00\x00\x00\x00\x0a\xef\xc8\x88\x00\x00\x00\x00\x0b\x9f \x08\x00\x00\x00\x00\x0c\xd8\xe5\x08\x00\x00\x00\x00\x0d\x7f\x02\x08\x00\x00\x00\x00\x0e\xb8\xc7\x08\x00\x00\x00\x00\x0f^\xe4\x08\x00\x00\x00\x00\x10\x98\xa9\x08\x00\x00\x00\x00\x11>\xc6\x08\x00\x00\x00\x00\x12x\x8b\x08\x00\x00\x00\x00\x13\x1e\xa8\x08\x00\x00\x00\x00\x14Xm\x08\x00\x00\x00\x00\x14\xfe\x8a\x08\x00\x00\x00\x00\x168O\x08\x00\x00\x00\x00\x16\xe7\xa6\x88\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18\xc7\x88\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\x08\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80\xd5\x88\x00\x00\x00\x00\x22B\xa2\x08\x00\x00\x00\x00#i\xf2\x08\x00\x00\x00\x00$\x22\x84\x08\x00\x00\x00\x00%I\xd4\x08\x00\x00\x00\x00&\x02f\x08\x00\x00\x00\x00')\xb6\x08\x00\x00\x00\x00'\xcf\xd3\x08\x00\x00\x00\x00)\x09\x98\x08\x00\x00\x00\x00)\xcbd\x88\x00\x00\x00\x00*\xe9z\x08\x00\x00\x00\x00+\x98\xd1\x88\x00\x00\x00\x00,\xd2\x96\x88\x00\x00\x00\x00-\x8b(\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/tE\x08\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\x07\x88\x00\x00\x00\x008\x1b\x1d\x08\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\x08\x00\x00\x00\x00:\xbc\xcb\x88\x00\x00\x00\x00;\xda\xe1\x08\x00\x00\x00\x00<\xa5\xe8\x08\x00\x00\x00\x00=\xba\xc3\x08\x00\x00\x00\x00>\x85\xca\x08\x00\x00\x00\x00?\x9a\xa5\x08\x00\x00\x00\x00@e\xac\x08\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\x08\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\x08\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\x08\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x81\xec\x00\x00\x00\x00~\x90\x00\x04\x00\x00\x93\xa8\x01\x09\x00\x00\x85\x98\x00\x04LMT\x00ACST\x00ACDT\x00\x0aACST-9:30ACDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x10\x00\x00\x00Australia/SydneyTZif2\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\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x7f<\xff\xff\xff\xff\x9cN\xc2\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff\xcc\xb7V\x80\xff\xff\xff\xff\xcd\xa7G\x80\xff\xff\xff\xff\xce\xa0s\x00\xff\xff\xff\xff\xcf\x87)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\x07/\xfd\x80\x00\x00\x00\x00\x07\xd6\x1a\x80\x00\x00\x00\x00\x09\x0f\xdf\x80\x00\x00\x00\x00\x09\xb5\xfc\x80\x00\x00\x00\x00\x0a\xef\xc1\x80\x00\x00\x00\x00\x0b\x9f\x19\x00\x00\x00\x00\x00\x0c\xd8\xde\x00\x00\x00\x00\x00\x0d~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x0c\x89\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xc7\x81\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\x0a\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\xce\x80\x00\x00\x00\x00\x22B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\x22}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00%\xef\xea\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\x09\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98\xca\x80\x00\x00\x00\x00,\xd2\x8f\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/X\x8e\x80\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc\xc4\x80\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\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\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\x00\x00\x8d\xc4\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\x09LMT\x00AEDT\x00AEST\x00\x0aAEST-10AEDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x12\x00\x00\x00Australia/TasmaniaTZif2\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\x03\x00\x00\x00\x0e\xff\xff\xff\xfft.\x00\xe4\xff\xff\xff\xff\x9b\xd5x\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\x9d\xdaD\x80\xff\xff\xff\xff\x9e\x80a\x80\xff\xff\xff\xff\x9f\xba&\x80\xff\xff\xff\xff\xa0`C\x80\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff\xcc\xb7V\x80\xff\xff\xff\xff\xcd\xa7G\x80\xff\xff\xff\xff\xce\xa0s\x00\xff\xff\xff\xff\xcf\x87)\x80\xff\xff\xff\xff\xfb\xc2\x8d\x00\xff\xff\xff\xff\xfc\xb2~\x00\xff\xff\xff\xff\xfd\xc7Y\x00\xff\xff\xff\xff\xfev\xb0\x80\xff\xff\xff\xff\xff\xa7;\x00\x00\x00\x00\x00\x00V\x92\x80\x00\x00\x00\x00\x01\x87\x1d\x00\x00\x00\x00\x00\x02?\xaf\x00\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\x07/\xfd\x80\x00\x00\x00\x00\x07\xd6\x1a\x80\x00\x00\x00\x00\x09\x0f\xdf\x80\x00\x00\x00\x00\x09\xb5\xfc\x80\x00\x00\x00\x00\x0a\xef\xc1\x80\x00\x00\x00\x00\x0b\x9f\x19\x00\x00\x00\x00\x00\x0c\xd8\xde\x00\x00\x00\x00\x00\x0d~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x17\x03O\x00\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xe31\x00\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\x0a\x80\x00\x00\x00\x00\x1eg'\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!\x80\xce\x80\x00\x00\x00\x00\x22B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\x22}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xf4\xb6\x00\x00\x00\x00\x00(\xed\xe1\x80\x00\x00\x00\x00)\xd4\x98\x00\x00\x00\x00\x00*\xcd\xc3\x80\x00\x00\x00\x00+\xb4z\x00\x00\x00\x00\x00,\xad\xa5\x80\x00\x00\x00\x00-\x94\x5c\x00\x00\x00\x00\x00.\x8d\x87\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000mi\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002V\x86\x00\x00\x00\x00\x003=<\x80\x00\x00\x00\x0046h\x00\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x006\x16J\x00\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x007\xf6,\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc\xc4\x80\x00\x00\x00\x00;\xbf*\x80\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\x9f\x0c\x80\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?~\xee\x80\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A^\xd0\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00C>\xb2\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00E\x1e\x94\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G\x07\xb1\x00\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\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\x8a\x1c\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\x09LMT\x00AEDT\x00AEST\x00\x0aAEST-10AEDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00Australia/VictoriaTZif2\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\x00S\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xffs\x16\x85\x18\xff\xff\xff\xff\x9cN\xc2\x80\xff\xff\xff\xff\x9c\xbc/\x00\xff\xff\xff\xff\xcbT\xb3\x00\xff\xff\xff\xff\xcb\xc7e\x80\xff\xff\xff\xff\xcc\xb7V\x80\xff\xff\xff\xff\xcd\xa7G\x80\xff\xff\xff\xff\xce\xa0s\x00\xff\xff\xff\xff\xcf\x87)\x80\x00\x00\x00\x00\x03p9\x80\x00\x00\x00\x00\x04\x0d\x1c\x00\x00\x00\x00\x00\x05P\x1b\x80\x00\x00\x00\x00\x05\xf68\x80\x00\x00\x00\x00\x07/\xfd\x80\x00\x00\x00\x00\x07\xd6\x1a\x80\x00\x00\x00\x00\x09\x0f\xdf\x80\x00\x00\x00\x00\x09\xb5\xfc\x80\x00\x00\x00\x00\x0a\xef\xc1\x80\x00\x00\x00\x00\x0b\x9f\x19\x00\x00\x00\x00\x00\x0c\xd8\xde\x00\x00\x00\x00\x00\x0d~\xfb\x00\x00\x00\x00\x00\x0e\xb8\xc0\x00\x00\x00\x00\x00\x0f^\xdd\x00\x00\x00\x00\x00\x10\x98\xa2\x00\x00\x00\x00\x00\x11>\xbf\x00\x00\x00\x00\x00\x12x\x84\x00\x00\x00\x00\x00\x13\x1e\xa1\x00\x00\x00\x00\x00\x14Xf\x00\x00\x00\x00\x00\x14\xfe\x83\x00\x00\x00\x00\x00\x168H\x00\x00\x00\x00\x00\x16\xe7\x9f\x80\x00\x00\x00\x00\x18!d\x80\x00\x00\x00\x00\x18\xc7\x81\x80\x00\x00\x00\x00\x1a\x01F\x80\x00\x00\x00\x00\x1a\xa7c\x80\x00\x00\x00\x00\x1b\xe1(\x80\x00\x00\x00\x00\x1c\x87E\x80\x00\x00\x00\x00\x1d\xc1\x0a\x80\x00\x00\x00\x00\x1ey\x9c\x80\x00\x00\x00\x00\x1f\x97\xb2\x00\x00\x00\x00\x00 Y~\x80\x00\x00\x00\x00!w\x94\x00\x00\x00\x00\x00\x22B\x9b\x00\x00\x00\x00\x00#i\xeb\x00\x00\x00\x00\x00$\x22}\x00\x00\x00\x00\x00%I\xcd\x00\x00\x00\x00\x00&\x02_\x00\x00\x00\x00\x00')\xaf\x00\x00\x00\x00\x00'\xcf\xcc\x00\x00\x00\x00\x00)\x09\x91\x00\x00\x00\x00\x00)\xaf\xae\x00\x00\x00\x00\x00*\xe9s\x00\x00\x00\x00\x00+\x98\xca\x80\x00\x00\x00\x00,\xd2\x8f\x80\x00\x00\x00\x00-x\xac\x80\x00\x00\x00\x00.\xb2q\x80\x00\x00\x00\x00/t>\x00\x00\x00\x00\x000\x92S\x80\x00\x00\x00\x001]Z\x80\x00\x00\x00\x002r5\x80\x00\x00\x00\x003=<\x80\x00\x00\x00\x004R\x17\x80\x00\x00\x00\x005\x1d\x1e\x80\x00\x00\x00\x0061\xf9\x80\x00\x00\x00\x006\xfd\x00\x80\x00\x00\x00\x008\x1b\x16\x00\x00\x00\x00\x008\xdc\xe2\x80\x00\x00\x00\x009\xa7\xe9\x80\x00\x00\x00\x00:\xbc\xc4\x80\x00\x00\x00\x00;\xda\xda\x00\x00\x00\x00\x00<\xa5\xe1\x00\x00\x00\x00\x00=\xba\xbc\x00\x00\x00\x00\x00>\x85\xc3\x00\x00\x00\x00\x00?\x9a\x9e\x00\x00\x00\x00\x00@e\xa5\x00\x00\x00\x00\x00A\x83\xba\x80\x00\x00\x00\x00BE\x87\x00\x00\x00\x00\x00Cc\x9c\x80\x00\x00\x00\x00D.\xa3\x80\x00\x00\x00\x00EC~\x80\x00\x00\x00\x00F\x05K\x00\x00\x00\x00\x00G#`\x80\x00\x00\x00\x00G\xf7\xa2\x00\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\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\x00\x00\x87\xe8\x00\x00\x00\x00\x9a\xb0\x01\x04\x00\x00\x8c\xa0\x00\x09LMT\x00AEDT\x00AEST\x00\x0aAEST-10AEDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xbb\xca\x1a2\x01\x00\x002\x01\x00\x00\x0e\x00\x00\x00Australia/WestTZif2\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\x13\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xfft\xa6\x16\xe4\xff\xff\xff\xff\x9cN\xde\xa0\xff\xff\xff\xff\x9c\xbcK \xff\xff\xff\xff\xcbT\xcf \xff\xff\xff\xff\xcb\xc7\x81\xa0\xff\xff\xff\xff\xcc\xb7r\xa0\xff\xff\xff\xff\xcd\xa7c\xa0\x00\x00\x00\x00\x09\x0f\xfb\xa0\x00\x00\x00\x00\x09\xb6\x18\xa0\x00\x00\x00\x00\x1a\x01b\xa0\x00\x00\x00\x00\x1a\xa7\x7f\xa0\x00\x00\x00\x00)%\x5c\xa0\x00\x00\x00\x00)\xaf\xca \x00\x00\x00\x00Eq\xbf \x00\x00\x00\x00F\x05g \x00\x00\x00\x00G#|\xa0\x00\x00\x00\x00G\xee\x83\xa0\x00\x00\x00\x00I\x03^\xa0\x00\x00\x00\x00I\xcee\xa0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00l\x9c\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\x09LMT\x00AWDT\x00AWST\x00\x0aAWST-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x14\x00\x00\x00Australia/YancowinnaTZif2\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\x00U\x00\x00\x00\x05\x00\x00\x00\x13\xff\xff\xff\xffs\x16\x88d\xff\xff\xff\xffv\x04\xa5\xe0\xff\xff\xff\xff{\x12\x03p\xff\xff\xff\xff\x9cN\xc9\x88\xff\xff\xff\xff\x9c\xbc6\x08\xff\xff\xff\xff\xcbT\xba\x08\xff\xff\xff\xff\xcb\xc7l\x88\xff\xff\xff\xff\xcc\xb7]\x88\xff\xff\xff\xff\xcd\xa7N\x88\xff\xff\xff\xff\xce\xa0z\x08\xff\xff\xff\xff\xcf\x870\x88\x00\x00\x00\x00\x03p@\x88\x00\x00\x00\x00\x04\x0d#\x08\x00\x00\x00\x00\x05P\x22\x88\x00\x00\x00\x00\x05\xf6?\x88\x00\x00\x00\x00\x070\x04\x88\x00\x00\x00\x00\x07\xd6!\x88\x00\x00\x00\x00\x09\x0f\xe6\x88\x00\x00\x00\x00\x09\xb6\x03\x88\x00\x00\x00\x00\x0a\xef\xc8\x88\x00\x00\x00\x00\x0b\x9f \x08\x00\x00\x00\x00\x0c\xd8\xe5\x08\x00\x00\x00\x00\x0d\x7f\x02\x08\x00\x00\x00\x00\x0e\xb8\xc7\x08\x00\x00\x00\x00\x0f^\xe4\x08\x00\x00\x00\x00\x10\x98\xa9\x08\x00\x00\x00\x00\x11>\xc6\x08\x00\x00\x00\x00\x12x\x8b\x08\x00\x00\x00\x00\x13\x1e\xa8\x08\x00\x00\x00\x00\x14Xm\x08\x00\x00\x00\x00\x14\xfe\x8a\x08\x00\x00\x00\x00\x168O\x08\x00\x00\x00\x00\x17\x0c\x90\x88\x00\x00\x00\x00\x18!k\x88\x00\x00\x00\x00\x18\xc7\x88\x88\x00\x00\x00\x00\x1a\x01M\x88\x00\x00\x00\x00\x1a\xa7j\x88\x00\x00\x00\x00\x1b\xe1/\x88\x00\x00\x00\x00\x1c\x87L\x88\x00\x00\x00\x00\x1d\xc1\x11\x88\x00\x00\x00\x00\x1ey\xa3\x88\x00\x00\x00\x00\x1f\x97\xb9\x08\x00\x00\x00\x00 Y\x85\x88\x00\x00\x00\x00!\x80\xd5\x88\x00\x00\x00\x00\x22B\xa2\x08\x00\x00\x00\x00#i\xf2\x08\x00\x00\x00\x00$\x22\x84\x08\x00\x00\x00\x00%I\xd4\x08\x00\x00\x00\x00%\xef\xf1\x08\x00\x00\x00\x00')\xb6\x08\x00\x00\x00\x00'\xcf\xd3\x08\x00\x00\x00\x00)\x09\x98\x08\x00\x00\x00\x00)\xaf\xb5\x08\x00\x00\x00\x00*\xe9z\x08\x00\x00\x00\x00+\x98\xd1\x88\x00\x00\x00\x00,\xd2\x96\x88\x00\x00\x00\x00-x\xb3\x88\x00\x00\x00\x00.\xb2x\x88\x00\x00\x00\x00/X\x95\x88\x00\x00\x00\x000\x92Z\x88\x00\x00\x00\x001]a\x88\x00\x00\x00\x002r<\x88\x00\x00\x00\x003=C\x88\x00\x00\x00\x004R\x1e\x88\x00\x00\x00\x005\x1d%\x88\x00\x00\x00\x0062\x00\x88\x00\x00\x00\x006\xfd\x07\x88\x00\x00\x00\x008\x1b\x1d\x08\x00\x00\x00\x008\xdc\xe9\x88\x00\x00\x00\x009\xfa\xff\x08\x00\x00\x00\x00:\xbc\xcb\x88\x00\x00\x00\x00;\xda\xe1\x08\x00\x00\x00\x00<\xa5\xe8\x08\x00\x00\x00\x00=\xba\xc3\x08\x00\x00\x00\x00>\x85\xca\x08\x00\x00\x00\x00?\x9a\xa5\x08\x00\x00\x00\x00@e\xac\x08\x00\x00\x00\x00A\x83\xc1\x88\x00\x00\x00\x00BE\x8e\x08\x00\x00\x00\x00Cc\xa3\x88\x00\x00\x00\x00D.\xaa\x88\x00\x00\x00\x00EC\x85\x88\x00\x00\x00\x00F\x05R\x08\x00\x00\x00\x00G#g\x88\x00\x00\x00\x00G\xf7\xa9\x08\x01\x02\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\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x84\x9c\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\x09\x00\x00\x93\xa8\x01\x0e\x00\x00\x85\x98\x00\x09LMT\x00AEST\x00ACST\x00ACDT\x00\x0aACST-9:30ACDT,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x0b\x00\x00\x00Brazil/AcreTZif2\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\x1f\x00\x00\x00\x04\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaa\x86\x90\xff\xff\xff\xff\xb8\x0ff\x00\xff\xff\xff\xff\xb8\xfd\x5c\xc0\xff\xff\xff\xff\xb9\xf1PP\xff\xff\xff\xff\xba\xde\x90@\xff\xff\xff\xff\xda8\xcaP\xff\xff\xff\xff\xda\xec\x16P\xff\xff\xff\xff\xdc\x19\xfd\xd0\xff\xff\xff\xff\xdc\xb9u@\xff\xff\xff\xff\xdd\xfb1P\xff\xff\xff\xff\xde\x9b\xfa@\xff\xff\xff\xff\xdf\xdd\xb6P\xff\xff\xff\xff\xe0TO@\xff\xff\xff\xff\xf4\x98\x1b\xd0\xff\xff\xff\xff\xf5\x05z@\xff\xff\xff\xff\xf6\xc0\x80P\xff\xff\xff\xff\xf7\x0e:\xc0\xff\xff\xff\xff\xf8QHP\xff\xff\xff\xff\xf8\xc7\xe1@\xff\xff\xff\xff\xfa\x0a\xee\xd0\xff\xff\xff\xff\xfa\xa9\x14\xc0\xff\xff\xff\xff\xfb\xec\x22P\xff\xff\xff\xff\xfc\x8b\x99\xc0\x00\x00\x00\x00\x1d\xc9\xaaP\x00\x00\x00\x00\x1ex\xf3\xc0\x00\x00\x00\x00\x1f\xa0Q\xd0\x00\x00\x00\x00 3\xeb\xc0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\x22\x0b\xe4\xc0\x00\x00\x00\x00H`\x7fP\x00\x00\x00\x00R\x7f\x04\xc0\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\x03\x02\xff\xff\xc0p\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x00\x04LMT\x00-04\x00-05\x00\x0a<-05>5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x10\x00\x00\x00Brazil/DeNoronhaTZif2\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\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaaed\xff\xff\xff\xff\xb8\x0f;\xd0\xff\xff\xff\xff\xb8\xfd2\x90\xff\xff\xff\xff\xb9\xf1& \xff\xff\xff\xff\xba\xdef\x10\xff\xff\xff\xff\xda8\xa0 \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdc\x19\xd3\xa0\xff\xff\xff\xff\xdc\xb9K\x10\xff\xff\xff\xff\xdd\xfb\x07 \xff\xff\xff\xff\xde\x9b\xd0\x10\xff\xff\xff\xff\xdf\xdd\x8c \xff\xff\xff\xff\xe0T%\x10\xff\xff\xff\xff\xf4\x97\xf1\xa0\xff\xff\xff\xff\xf5\x05P\x10\xff\xff\xff\xff\xf6\xc0V \xff\xff\xff\xff\xf7\x0e\x10\x90\xff\xff\xff\xff\xf8Q\x1e \xff\xff\xff\xff\xf8\xc7\xb7\x10\xff\xff\xff\xff\xfa\x0a\xc4\xa0\xff\xff\xff\xff\xfa\xa8\xea\x90\xff\xff\xff\xff\xfb\xeb\xf8 \xff\xff\xff\xff\xfc\x8bo\x90\x00\x00\x00\x00\x1d\xc9\x80 \x00\x00\x00\x00\x1ex\xc9\x90\x00\x00\x00\x00\x1f\xa0'\xa0\x00\x00\x00\x00 3\xc1\x90\x00\x00\x00\x00!\x81[ \x00\x00\x00\x00\x22\x0b\xba\x90\x00\x00\x00\x00#X\x02\xa0\x00\x00\x00\x00#\xe2b\x10\x00\x00\x00\x00%7\xe4\xa0\x00\x00\x00\x00%\xd4\xb9\x10\x00\x00\x00\x007\xf6\xb8\xa0\x00\x00\x00\x008\xb8w\x10\x00\x00\x00\x009\xdf\xd5 \x00\x00\x00\x009\xe9\x01\x90\x00\x00\x00\x00;\xc8\xf1\xa0\x00\x00\x00\x00<o\x00\x90\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\xff\xff\xe1\x9c\x00\x00\xff\xff\xf1\xf0\x01\x04\xff\xff\xe3\xe0\x00\x08LMT\x00-01\x00-02\x00\x0a<-02>2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d?\xdf\xda\xb8\x03\x00\x00\xb8\x03\x00\x00\x0b\x00\x00\x00Brazil/EastTZif2\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\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaar\xb4\xff\xff\xff\xff\xb8\x0fI\xe0\xff\xff\xff\xff\xb8\xfd@\xa0\xff\xff\xff\xff\xb9\xf140\xff\xff\xff\xff\xba\xdet \xff\xff\xff\xff\xda8\xae0\xff\xff\xff\xff\xda\xeb\xfa0\xff\xff\xff\xff\xdc\x19\xe1\xb0\xff\xff\xff\xff\xdc\xb9Y \xff\xff\xff\xff\xdd\xfb\x150\xff\xff\xff\xff\xde\x9b\xde \xff\xff\xff\xff\xdf\xdd\x9a0\xff\xff\xff\xff\xe0T3 \xff\xff\xff\xff\xf4Z\x090\xff\xff\xff\xff\xf5\x05^ \xff\xff\xff\xff\xf6\xc0d0\xff\xff\xff\xff\xf7\x0e\x1e\xa0\xff\xff\xff\xff\xf8Q,0\xff\xff\xff\xff\xf8\xc7\xc5 \xff\xff\xff\xff\xfa\x0a\xd2\xb0\xff\xff\xff\xff\xfa\xa8\xf8\xa0\xff\xff\xff\xff\xfb\xec\x060\xff\xff\xff\xff\xfc\x8b}\xa0\x00\x00\x00\x00\x1d\xc9\x8e0\x00\x00\x00\x00\x1ex\xd7\xa0\x00\x00\x00\x00\x1f\xa05\xb0\x00\x00\x00\x00 3\xcf\xa0\x00\x00\x00\x00!\x81i0\x00\x00\x00\x00\x22\x0b\xc8\xa0\x00\x00\x00\x00#X\x10\xb0\x00\x00\x00\x00#\xe2p \x00\x00\x00\x00%7\xf2\xb0\x00\x00\x00\x00%\xd4\xc7 \x00\x00\x00\x00'!\x0f0\x00\x00\x00\x00'\xbd\xe3\xa0\x00\x00\x00\x00)\x00\xf10\x00\x00\x00\x00)\x94\x8b \x00\x00\x00\x00*\xea\x0d\xb0\x00\x00\x00\x00+k2\xa0\x00\x00\x00\x00,\xc0\xb50\x00\x00\x00\x00-f\xc4 \x00\x00\x00\x00.\xa0\x970\x00\x00\x00\x00/F\xa6 \x00\x00\x00\x000\x80y0\x00\x00\x00\x001\x1dM\xa0\x00\x00\x00\x002W \xb0\x00\x00\x00\x003\x06j \x00\x00\x00\x0048T0\x00\x00\x00\x004\xf8\xc1 \x00\x00\x00\x006 \x1f0\x00\x00\x00\x006\xcfh\xa0\x00\x00\x00\x007\xf6\xc6\xb0\x00\x00\x00\x008\xb8\x85 \x00\x00\x00\x009\xdf\xe30\x00\x00\x00\x00:\x8f,\xa0\x00\x00\x00\x00;\xc8\xff\xb0\x00\x00\x00\x00<o\x0e\xa0\x00\x00\x00\x00=\xc4\x910\x00\x00\x00\x00>N\xf0\xa0\x00\x00\x00\x00?\x91\xfe0\x00\x00\x00\x00@.\xd2\xa0\x00\x00\x00\x00A\x86\xf80\x00\x00\x00\x00B\x17\xef \x00\x00\x00\x00CQ\xc20\x00\x00\x00\x00C\xf7\xd1 \x00\x00\x00\x00EMS\xb0\x00\x00\x00\x00E\xe0\xed\xa0\x00\x00\x00\x00G\x11\x860\x00\x00\x00\x00G\xb7\x95 \x00\x00\x00\x00H\xfa\xa2\xb0\x00\x00\x00\x00I\x97w \x00\x00\x00\x00J\xda\x84\xb0\x00\x00\x00\x00K\x80\x93\xa0\x00\x00\x00\x00L\xbaf\xb0\x00\x00\x00\x00M`u\xa0\x00\x00\x00\x00N\x9aH\xb0\x00\x00\x00\x00OI\x92 \x00\x00\x00\x00P\x83e0\x00\x00\x00\x00Q 9\xa0\x00\x00\x00\x00RcG0\x00\x00\x00\x00S\x00\x1b\xa0\x00\x00\x00\x00TC)0\x00\x00\x00\x00T\xe98 \x00\x00\x00\x00V#\x0b0\x00\x00\x00\x00V\xc9\x1a \x00\x00\x00\x00X\x02\xed0\x00\x00\x00\x00X\xa8\xfc \x00\x00\x00\x00Y\xe2\xcf0\x00\x00\x00\x00Z\x88\xde \x00\x00\x00\x00[\xde`\xb0\x00\x00\x00\x00\x5ch\xc0 \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\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\xff\xff\xd4L\x00\x00\xff\xff\xe3\xe0\x01\x04\xff\xff\xd5\xd0\x00\x08LMT\x00-02\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\x0b\x00\x00\x00Brazil/WestTZif2\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\x1f\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x96\xaa\x7fD\xff\xff\xff\xff\xb8\x0fW\xf0\xff\xff\xff\xff\xb8\xfdN\xb0\xff\xff\xff\xff\xb9\xf1B@\xff\xff\xff\xff\xba\xde\x820\xff\xff\xff\xff\xda8\xbc@\xff\xff\xff\xff\xda\xec\x08@\xff\xff\xff\xff\xdc\x19\xef\xc0\xff\xff\xff\xff\xdc\xb9g0\xff\xff\xff\xff\xdd\xfb#@\xff\xff\xff\xff\xde\x9b\xec0\xff\xff\xff\xff\xdf\xdd\xa8@\xff\xff\xff\xff\xe0TA0\xff\xff\xff\xff\xf4\x98\x0d\xc0\xff\xff\xff\xff\xf5\x05l0\xff\xff\xff\xff\xf6\xc0r@\xff\xff\xff\xff\xf7\x0e,\xb0\xff\xff\xff\xff\xf8Q:@\xff\xff\xff\xff\xf8\xc7\xd30\xff\xff\xff\xff\xfa\x0a\xe0\xc0\xff\xff\xff\xff\xfa\xa9\x06\xb0\xff\xff\xff\xff\xfb\xec\x14@\xff\xff\xff\xff\xfc\x8b\x8b\xb0\x00\x00\x00\x00\x1d\xc9\x9c@\x00\x00\x00\x00\x1ex\xe5\xb0\x00\x00\x00\x00\x1f\xa0C\xc0\x00\x00\x00\x00 3\xdd\xb0\x00\x00\x00\x00!\x81w@\x00\x00\x00\x00\x22\x0b\xd6\xb0\x00\x00\x00\x00,\xc0\xc3@\x00\x00\x00\x00-f\xd20\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\xff\xff\xc7\xbc\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\x08LMT\x00-03\x00-04\x00\x0a<-04>4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\x9aM\xbem\x02\x00\x00m\x02\x00\x00\x03\x00\x00\x00CETTZif2\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\x005\x00\x00\x00\x02\x00\x00\x00\x09\xff\xff\xff\xff\x9b\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x09q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x0d\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x05\x00\x00\x1c \x01\x00CEST\x00CET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x8b\x99\x1e\xb7\x03\x00\x00\xb7\x03\x00\x00\x07\x00\x00\x00CST6CDTTZif2\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\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x0d\xf0\x00\x00\x00\x00\x00\x98\x0d\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x0cp\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xd0p\x00\x00\x00\x00\x07\x8d'\x80\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x09\xad\xa3\x00\x00\x00\x00\x00\x0a\xf0\x94p\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xb0\xf0\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x227p\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ac\xf0\x00\x00\x00\x00)\xde\xb3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;\xdb\xac\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x01\x00\xff\xff\xb9\xb0\x01\x08\xff\xff\xb9\xb0\x01\x0cCDT\x00CST\x00CWT\x00CPT\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x00\x00Canada/AtlanticTZif2\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\xa7\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x80\xf1\xab\xa0\xff\xff\xff\xff\x9a\xe4\xde\xc0\xff\xff\xff\xff\x9b\xd6\x130\xff\xff\xff\xff\x9e\xb8\x85`\xff\xff\xff\xff\x9f\xba\xddP\xff\xff\xff\xff\xa2\x9d\x17@\xff\xff\xff\xff\xa30\xb10\xff\xff\xff\xff\xa4zV@\xff\xff\xff\xff\xa5\x1b\x1f0\xff\xff\xff\xff\xa6S\xa0\xc0\xff\xff\xff\xff\xa6\xfcR\xb0\xff\xff\xff\xff\xa8<\xbd@\xff\xff\xff\xff\xa8\xdc4\xb0\xff\xff\xff\xff\xaa\x1c\x9f@\xff\xff\xff\xff\xaa\xcd:0\xff\xff\xff\xff\xab\xfc\x81@\xff\xff\xff\xff\xac\xbf\x910\xff\xff\xff\xff\xad\xee\xd8@\xff\xff\xff\xff\xae\x8c\xfe0\xff\xff\xff\xff\xaf\xbcE@\xff\xff\xff\xff\xb0\x7fU0\xff\xff\xff\xff\xb1\xae\x9c@\xff\xff\xff\xff\xb2Kp\xb0\xff\xff\xff\xff\xb3\x8e~@\xff\xff\xff\xff\xb4$\xbb0\xff\xff\xff\xff\xb5n`@\xff\xff\xff\xff\xb6\x15\xc0\xb0\xff\xff\xff\xff\xb7NB@\xff\xff\xff\xff\xb8\x08\x17\xb0\xff\xff\xff\xff\xb9$\xe9\xc0\xff\xff\xff\xff\xb9\xe7\xf9\xb0\xff\xff\xff\xff\xbb\x04\xcb\xc0\xff\xff\xff\xff\xbb\xd1\x160\xff\xff\xff\xff\xbd\x00]@\xff\xff\xff\xff\xbd\x9d1\xb0\xff\xff\xff\xff\xbe\xf2\xb4@\xff\xff\xff\xff\xbf\x90\xda0\xff\xff\xff\xff\xc0\xd3\xe7\xc0\xff\xff\xff\xff\xc1^G0\xff\xff\xff\xff\xc2\x8d\x8e@\xff\xff\xff\xff\xc3P\x9e0\xff\xff\xff\xff\xc4mp@\xff\xff\xff\xff\xc50\x800\xff\xff\xff\xff\xc6r<@\xff\xff\xff\xff\xc7\x10b0\xff\xff\xff\xff\xc86n\xc0\xff\xff\xff\xff\xc8\xf9~\xb0\xff\xff\xff\xff\xca\x16P\xc0\xff\xff\xff\xff\xca\xd9`\xb0\xff\xff\xff\xff\xcb\x88\xe2`\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xed\xd0\xff\xff\xff\xff\xd3u\xd6\xe0\xff\xff\xff\xff\xd4@\xcf\xd0\xff\xff\xff\xff\xd5U\xb8\xe0\xff\xff\xff\xff\xd6 \xb1\xd0\xff\xff\xff\xff\xd75\x9a\xe0\xff\xff\xff\xff\xd8\x00\x93\xd0\xff\xff\xff\xff\xd9\x15|\xe0\xff\xff\xff\xff\xd9\xe0u\xd0\xff\xff\xff\xff\xdc\xde{`\xff\xff\xff\xff\xdd\xa9tP\xff\xff\xff\xff\xde\xbe]`\xff\xff\xff\xff\xdf\x89VP\xff\xff\xff\xff\xe0\x9e?`\xff\xff\xff\xff\xe1i8P\xff\xff\xff\xff\xe2~!`\xff\xff\xff\xff\xe3I\x1aP\xff\xff\xff\xff\xe6G\x1f\xe0\xff\xff\xff\xff\xe7\x12\x18\xd0\xff\xff\xff\xff\xe8'\x01\xe0\xff\xff\xff\xff\xe8\xf1\xfa\xd0\xff\xff\xff\xff\xea\x06\xe3\xe0\xff\xff\xff\xff\xea\xd1\xdc\xd0\xff\xff\xff\xff\xeb\xe6\xc5\xe0\xff\xff\xff\xff\xec\xb1\xbe\xd0\xff\xff\xff\xff\xf1\x8f\xa6`\xff\xff\xff\xff\xf2\x7f\x89P\xff\xff\xff\xff\xf3o\x88`\xff\xff\xff\xff\xf4_kP\xff\xff\xff\xff\xf5Oj`\xff\xff\xff\xff\xf6?MP\xff\xff\xff\xff\xf7/L`\xff\xff\xff\xff\xf8(i\xd0\xff\xff\xff\xff\xf9\x0f.`\xff\xff\xff\xff\xfa\x08K\xd0\xff\xff\xff\xff\xfa\xf8J\xe0\xff\xff\xff\xff\xfb\xe8-\xd0\xff\xff\xff\xff\xfc\xd8,\xe0\xff\xff\xff\xff\xfd\xc8\x0f\xd0\xff\xff\xff\xff\xfe\xb8\x0e\xe0\xff\xff\xff\xff\xff\xa7\xf1\xd0\x00\x00\x00\x00\x00\x97\xf0\xe0\x00\x00\x00\x00\x01\x87\xd3\xd0\x00\x00\x00\x00\x02w\xd2\xe0\x00\x00\x00\x00\x03p\xf0P\x00\x00\x00\x00\x04`\xef`\x00\x00\x00\x00\x05P\xd2P\x00\x00\x00\x00\x06@\xd1`\x00\x00\x00\x00\x070\xb4P\x00\x00\x00\x00\x08 \xb3`\x00\x00\x00\x00\x09\x10\x96P\x00\x00\x00\x00\x0a\x00\x95`\x00\x00\x00\x00\x0a\xf0xP\x00\x00\x00\x00\x0b\xe0w`\x00\x00\x00\x00\x0c\xd9\x94\xd0\x00\x00\x00\x00\x0d\xc0Y`\x00\x00\x00\x00\x0e\xb9v\xd0\x00\x00\x00\x00\x0f\xa9u\xe0\x00\x00\x00\x00\x10\x99X\xd0\x00\x00\x00\x00\x11\x89W\xe0\x00\x00\x00\x00\x12y:\xd0\x00\x00\x00\x00\x13i9\xe0\x00\x00\x00\x00\x14Y\x1c\xd0\x00\x00\x00\x00\x15I\x1b\xe0\x00\x00\x00\x00\x168\xfe\xd0\x00\x00\x00\x00\x17(\xfd\xe0\x00\x00\x00\x00\x18\x22\x1bP\x00\x00\x00\x00\x19\x08\xdf\xe0\x00\x00\x00\x00\x1a\x01\xfdP\x00\x00\x00\x00\x1a\xf1\xfc`\x00\x00\x00\x00\x1b\xe1\xdfP\x00\x00\x00\x00\x1c\xd1\xde`\x00\x00\x00\x00\x1d\xc1\xc1P\x00\x00\x00\x00\x1e\xb1\xc0`\x00\x00\x00\x00\x1f\xa1\xa3P\x00\x00\x00\x00 u\xf2\xe0\x00\x00\x00\x00!\x81\x85P\x00\x00\x00\x00\x22U\xd4\xe0\x00\x00\x00\x00#j\xa1\xd0\x00\x00\x00\x00$5\xb6\xe0\x00\x00\x00\x00%J\x83\xd0\x00\x00\x00\x00&\x15\x98\xe0\x00\x00\x00\x00'*e\xd0\x00\x00\x00\x00'\xfe\xb5`\x00\x00\x00\x00)\x0aG\xd0\x00\x00\x00\x00)\xde\x97`\x00\x00\x00\x00*\xea)\xd0\x00\x00\x00\x00+\xbey`\x00\x00\x00\x00,\xd3FP\x00\x00\x00\x00-\x9e[`\x00\x00\x00\x00.\xb3(P\x00\x00\x00\x00/~=`\x00\x00\x00\x000\x93\x0aP\x00\x00\x00\x001gY\xe0\x00\x00\x00\x002r\xecP\x00\x00\x00\x003G;\xe0\x00\x00\x00\x004R\xceP\x00\x00\x00\x005'\x1d\xe0\x00\x00\x00\x0062\xb0P\x00\x00\x00\x007\x06\xff\xe0\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xe1\xe0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xc3\xe0\x00\x00\x00\x00;\xdb\x90\xd0\x00\x00\x00\x00<\xaf\xe0`\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xc2`\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@o\xa4`\x00\x00\x00\x00A\x84qP\x00\x00\x00\x00BO\x86`\x00\x00\x00\x00CdSP\x00\x00\x00\x00D/h`\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x9a\xe0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xc4`\x00\x00\xff\xff\xd5\xd0\x01\x04\xff\xff\xc7\xc0\x00\x08\xff\xff\xd5\xd0\x01\x0c\xff\xff\xd5\xd0\x01\x10LMT\x00ADT\x00AST\x00AWT\x00APT\x00\x0aAST4ADT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x0e\x00\x00\x00Canada/CentralTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xffd\xe4\xb0\x94\xff\xff\xff\xff\x9b\x01\xfb\xe0\xff\xff\xff\xff\x9b\xc3\xbaP\xff\xff\xff\xff\x9e\xb8\xa1\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xc2\xa0;\x80\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3\x88h\x00\xff\xff\xff\xff\xd4S`\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xdb\x00\x07\x00\xff\xff\xff\xff\xdb\xc8\x5c\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5)\x18p\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe7\x124\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\x91\xbc\xf0\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf41b\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\x08v\x00\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x0d\x00\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x08 \xcf\x80\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x0a\x00\xb1\x80\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xb3\x80\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xa4\xec\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10LMT\x00CDT\x00CST\x00CWT\x00CPT\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00\x00\x00Canada/EasternTZif2\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\xac\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xffr\xeex\xec\xff\xff\xff\xff\x9e\xb8\x93p\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x87.\xc8\xff\xff\xff\xff\xa1\x9a\xb1@\xff\xff\xff\xff\xa2\x94\x06\xf0\xff\xff\xff\xff\xa3U\xa9@\xff\xff\xff\xff\xa4\x86]\xf0\xff\xff\xff\xff\xa5(x`\xff\xff\xff\xff\xa6f?\xf0\xff\xff\xff\xff\xa7\x0cN\xe0\xff\xff\xff\xff\xa8F!\xf0\xff\xff\xff\xff\xa8\xec0\xe0\xff\xff\xff\xff\xaa\x1c\xc9p\xff\xff\xff\xff\xaa\xd5M`\xff\xff\xff\xff\xab\xfc\xabp\xff\xff\xff\xff\xac\xb5/`\xff\xff\xff\xff\xad\xdc\x8dp\xff\xff\xff\xff\xae\x95\x11`\xff\xff\xff\xff\xaf\xbcop\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\x5c\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbe\xc4\xb9\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\xc2\x84}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xcb\x88\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xaa\xd0\xff\xff\xff\xff\xd6 \xa3\xc0\xff\xff\xff\xff\xd75\x8c\xd0\xff\xff\xff\xff\xd8\x00\x85\xc0\xff\xff\xff\xff\xd9\x15n\xd0\xff\xff\xff\xff\xda3v@\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdc\x13t`\xff\xff\xff\xff\xdc\xde\x89p\xff\xff\xff\xff\xdd\xa9\x82`\xff\xff\xff\xff\xde\xbekp\xff\xff\xff\xff\xdf\x89d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5)\x0a`\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe7\x12&\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xec\xd6\xb6\xe0\xff\xff\xff\xff\xed\xc6\xb5\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\x08Y\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x08 \xc1p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x0a\x00\xa3p\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xb5\x94\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\x07\x07\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x0f\x00\x00\x00Canada/MountainTZif2\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\x00Y\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff\x88\xde\xce\xe0\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x98\x91\x90\xff\xff\xff\xff\xa0\xd2\x85\x80\xff\xff\xff\xff\xa2\x8a\xe8\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4j\xca\x90\xff\xff\xff\xff\xa55\xc3\x80\xff\xff\xff\xff\xa6S\xe7\x10\xff\xff\xff\xff\xa7\x15\xa5\x80\xff\xff\xff\xff\xa83\xc9\x10\xff\xff\xff\xff\xa8\xfe\xc2\x00\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x08 \xdd\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x0a\x00\xbf\x90\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x95\xa0\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\x0aMST7MDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xb2\x0e\x19V\x07\x00\x00V\x07\x00\x00\x13\x00\x00\x00Canada/NewfoundlandTZif2\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\xbb\x00\x00\x00\x08\x00\x00\x00\x19\xff\xff\xff\xff^=4\xec\xff\xff\xff\xff\x9c\xcfb\x0c\xff\xff\xff\xff\x9d\xa4\xe6\xfc\xff\xff\xff\xff\x9e\xb8~\x8c\xff\xff\xff\xff\x9f\xba\xd6|\xff\xff\xff\xff\xa0\xb6\x88\xdc\xff\xff\xff\xff\xa18\xffL\xff\xff\xff\xff\xa2\x95\x19\x5c\xff\xff\xff\xff\xa3\x84\xfcL\xff\xff\xff\xff\xa4t\xfb\x5c\xff\xff\xff\xff\xa5d\xdeL\xff\xff\xff\xff\xa6^\x17\xdc\xff\xff\xff\xff\xa7D\xc0L\xff\xff\xff\xff\xa8=\xf9\xdc\xff\xff\xff\xff\xa9$\xa2L\xff\xff\xff\xff\xaa\x1d\xdb\xdc\xff\xff\xff\xff\xab\x04\x84L\xff\xff\xff\xff\xab\xfd\xbd\xdc\xff\xff\xff\xff\xac\xe4fL\xff\xff\xff\xff\xad\xdd\x9f\xdc\xff\xff\xff\xff\xae\xcd\x82\xcc\xff\xff\xff\xff\xaf\xbd\x81\xdc\xff\xff\xff\xff\xb0\xadd\xcc\xff\xff\xff\xff\xb1\xa6\x9e\x5c\xff\xff\xff\xff\xb2\x8dF\xcc\xff\xff\xff\xff\xb3\x86\x80\x5c\xff\xff\xff\xff\xb4m(\xcc\xff\xff\xff\xff\xb5fb\x5c\xff\xff\xff\xff\xb6M\x0a\xcc\xff\xff\xff\xff\xb7FD\x5c\xff\xff\xff\xff\xb8,\xec\xcc\xff\xff\xff\xff\xb9&&\x5c\xff\xff\xff\xff\xba\x16\x09L\xff\xff\xff\xff\xbb\x0fB\xdc\xff\xff\xff\xff\xbb\xf5\xebL\xff\xff\xff\xff\xbc\xef$\xdc\xff\xff\xff\xff\xbd\xd5\xcdL\xff\xff\xff\xff\xbe\x9eMl\xff\xff\xff\xff\xbe\xcf\x06\xa8\xff\xff\xff\xff\xbf\xb5\xaf\x18\xff\xff\xff\xff\xc0\xb818\xff\xff\xff\xff\xc1y\xef\xa8\xff\xff\xff\xff\xc2\x98\x138\xff\xff\xff\xff\xc3Y\xd1\xa8\xff\xff\xff\xff\xc4w\xf58\xff\xff\xff\xff\xc59\xb3\xa8\xff\xff\xff\xff\xc6a\x11\xb8\xff\xff\xff\xff\xc7\x19\x95\xa8\xff\xff\xff\xff\xc8@\xf3\xb8\xff\xff\xff\xff\xc9\x02\xb2(\xff\xff\xff\xff\xca \xd5\xb8\xff\xff\xff\xff\xca\xe2\x94(\xff\xff\xff\xff\xcc\x00\xb7\xb8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xe6\xc8\xff\xff\xff\xff\xd3\x88D\xd8\xff\xff\xff\xff\xd4J\x03H\xff\xff\xff\xff\xd5h&\xd8\xff\xff\xff\xff\xd6)\xe5H\xff\xff\xff\xff\xd7H\x08\xd8\xff\xff\xff\xff\xd8\x09\xc7H\xff\xff\xff\xff\xd9'\xea\xd8\xff\xff\xff\xff\xd9\xe9\xa9H\xff\xff\xff\xff\xdb\x11\x07X\xff\xff\xff\xff\xdb\xd2\xc5\xc8\xff\xff\xff\xff\xdc\xdetX\xff\xff\xff\xff\xdd\xa9mH\xff\xff\xff\xff\xde\xbeVX\xff\xff\xff\xff\xdf\x89OH\xff\xff\xff\xff\xe0\x9e8X\xff\xff\xff\xff\xe1i1H\xff\xff\xff\xff\xe2~\x1aX\xff\xff\xff\xff\xe3I\x13H\xff\xff\xff\xff\xe4]\xfcX\xff\xff\xff\xff\xe5(\xf5H\xff\xff\xff\xff\xe6G\x18\xd8\xff\xff\xff\xff\xe7\x12\x11\xc8\xff\xff\xff\xff\xe8&\xfa\xd8\xff\xff\xff\xff\xe8\xf1\xf3\xc8\xff\xff\xff\xff\xea\x06\xdc\xd8\xff\xff\xff\xff\xea\xd1\xd5\xc8\xff\xff\xff\xff\xeb\xe6\xbe\xd8\xff\xff\xff\xff\xec\xb1\xb7\xc8\xff\xff\xff\xff\xed\xc6\xa0\xd8\xff\xff\xff\xff\xee\xbf\xbeH\xff\xff\xff\xff\xef\xaf\xbdX\xff\xff\xff\xff\xf0\x9f\xa0H\xff\xff\xff\xff\xf1\x8f\x9fX\xff\xff\xff\xff\xf2\x7f\x82H\xff\xff\xff\xff\xf3o\x81X\xff\xff\xff\xff\xf4_dH\xff\xff\xff\xff\xf5OcX\xff\xff\xff\xff\xf6?FH\xff\xff\xff\xff\xf7/EX\xff\xff\xff\xff\xf8(b\xc8\xff\xff\xff\xff\xf9\x0f'X\xff\xff\xff\xff\xfa\x08D\xc8\xff\xff\xff\xff\xfa\xf8C\xd8\xff\xff\xff\xff\xfb\xe8&\xc8\xff\xff\xff\xff\xfc\xd8%\xd8\xff\xff\xff\xff\xfd\xc8\x08\xc8\xff\xff\xff\xff\xfe\xb8\x07\xd8\xff\xff\xff\xff\xff\xa7\xea\xc8\x00\x00\x00\x00\x00\x97\xe9\xd8\x00\x00\x00\x00\x01\x87\xcc\xc8\x00\x00\x00\x00\x02w\xcb\xd8\x00\x00\x00\x00\x03p\xe9H\x00\x00\x00\x00\x04`\xe8X\x00\x00\x00\x00\x05P\xcbH\x00\x00\x00\x00\x06@\xcaX\x00\x00\x00\x00\x070\xadH\x00\x00\x00\x00\x08 \xacX\x00\x00\x00\x00\x09\x10\x8fH\x00\x00\x00\x00\x0a\x00\x8eX\x00\x00\x00\x00\x0a\xf0qH\x00\x00\x00\x00\x0b\xe0pX\x00\x00\x00\x00\x0c\xd9\x8d\xc8\x00\x00\x00\x00\x0d\xc0RX\x00\x00\x00\x00\x0e\xb9o\xc8\x00\x00\x00\x00\x0f\xa9n\xd8\x00\x00\x00\x00\x10\x99Q\xc8\x00\x00\x00\x00\x11\x89P\xd8\x00\x00\x00\x00\x12y3\xc8\x00\x00\x00\x00\x13i2\xd8\x00\x00\x00\x00\x14Y\x15\xc8\x00\x00\x00\x00\x15I\x14\xd8\x00\x00\x00\x00\x168\xf7\xc8\x00\x00\x00\x00\x17(\xf6\xd8\x00\x00\x00\x00\x18\x22\x14H\x00\x00\x00\x00\x19\x08\xd8\xd8\x00\x00\x00\x00\x1a\x01\xf6H\x00\x00\x00\x00\x1a\xf1\xf5X\x00\x00\x00\x00\x1b\xe1\xd8H\x00\x00\x00\x00\x1c\xd1\xd7X\x00\x00\x00\x00\x1d\xc1\xbaH\x00\x00\x00\x00\x1e\xb1\xb9X\x00\x00\x00\x00\x1f\xa1\x9cH\x00\x00\x00\x00 u\xcf\xf4\x00\x00\x00\x00!\x81bd\x00\x00\x00\x00\x22U\xb1\xf4\x00\x00\x00\x00#jp\xd4\x00\x00\x00\x00$5\x93\xf4\x00\x00\x00\x00%J`\xe4\x00\x00\x00\x00&\x15u\xf4\x00\x00\x00\x00'*B\xe4\x00\x00\x00\x00'\xfe\x92t\x00\x00\x00\x00)\x0a$\xe4\x00\x00\x00\x00)\xdett\x00\x00\x00\x00*\xea\x06\xe4\x00\x00\x00\x00+\xbeVt\x00\x00\x00\x00,\xd3#d\x00\x00\x00\x00-\x9e8t\x00\x00\x00\x00.\xb3\x05d\x00\x00\x00\x00/~\x1at\x00\x00\x00\x000\x92\xe7d\x00\x00\x00\x001g6\xf4\x00\x00\x00\x002r\xc9d\x00\x00\x00\x003G\x18\xf4\x00\x00\x00\x004R\xabd\x00\x00\x00\x005&\xfa\xf4\x00\x00\x00\x0062\x8dd\x00\x00\x00\x007\x06\xdc\xf4\x00\x00\x00\x008\x1b\xa9\xe4\x00\x00\x00\x008\xe6\xbe\xf4\x00\x00\x00\x009\xfb\x8b\xe4\x00\x00\x00\x00:\xc6\xa0\xf4\x00\x00\x00\x00;\xdbm\xe4\x00\x00\x00\x00<\xaf\xbdt\x00\x00\x00\x00=\xbbO\xe4\x00\x00\x00\x00>\x8f\x9ft\x00\x00\x00\x00?\x9b1\xe4\x00\x00\x00\x00@o\x81t\x00\x00\x00\x00A\x84Nd\x00\x00\x00\x00BOct\x00\x00\x00\x00Cd0d\x00\x00\x00\x00D/Et\x00\x00\x00\x00ED\x12d\x00\x00\x00\x00E\xf3w\xf4\x00\x00\x00\x00G-.\xe4\x00\x00\x00\x00G\xd3Y\xf4\x00\x00\x00\x00I\x0d\x10\xe4\x00\x00\x00\x00I\xb3;\xf4\x00\x00\x00\x00J\xec\xf2\xe4\x00\x00\x00\x00K\x9cXt\x00\x00\x00\x00L\xd6\x0fd\x00\x00\x00\x00M|:t\x00\x00\x00\x00N\xb6\x0dH\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\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x06\x05\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\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x07\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\xff\xff\xce\x94\x00\x00\xff\xff\xdc\xa4\x01\x04\xff\xff\xce\x94\x00\x08\xff\xff\xdc\xd8\x01\x04\xff\xff\xce\xc8\x00\x08\xff\xff\xdc\xd8\x01\x0c\xff\xff\xdc\xd8\x01\x10\xff\xff\xea\xe8\x01\x14LMT\x00NDT\x00NST\x00NPT\x00NWT\x00NDDT\x00\x0aNST3:30NDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U9#\xbe2\x05\x00\x002\x05\x00\x00\x0e\x00\x00\x00Canada/PacificTZif2\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\x81\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^=v\xec\xff\xff\xff\xff\x9e\xb8\xbd\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xcb\x89\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd3v\x0f \xff\xff\xff\xff\xd4A\x08\x10\xff\xff\xff\xff\xd5U\xf1 \xff\xff\xff\xff\xd6 \xea\x10\xff\xff\xff\xff\xd75\xd3 \xff\xff\xff\xff\xd8\x00\xcc\x10\xff\xff\xff\xff\xd9\x15\xb5 \xff\xff\xff\xff\xd9\xe0\xae\x10\xff\xff\xff\xff\xda\xfe\xd1\xa0\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\xde\xb3\xa0\xff\xff\xff\xff\xdd\xa9\xac\x90\xff\xff\xff\xff\xde\xbe\x95\xa0\xff\xff\xff\xff\xdf\x89\x8e\x90\xff\xff\xff\xff\xe0\x9ew\xa0\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~Y\xa0\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^;\xa0\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GX \xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8': \xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\x07\x1c \xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xfe \xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xe0 \xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xfc\xa0\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8f\xde\xa0\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xc0\xa0\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\xa2\xa0\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/\x84\xa0\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0ff\xa0\xff\xff\xff\xff\xfa\x08\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\x0c\x10\x00\x00\x00\x00\x02x\x0b \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\x0a\x90\x00\x00\x00\x00\x06A\x09\xa0\x00\x00\x00\x00\x070\xec\x90\x00\x00\x00\x00\x08 \xeb\xa0\x00\x00\x00\x00\x09\x10\xce\x90\x00\x00\x00\x00\x0a\x00\xcd\xa0\x00\x00\x00\x00\x0a\xf0\xb0\x90\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x8c\x94\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00PWT\x00PPT\x00\x0aPST8PDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc2\x96dK~\x02\x00\x00~\x02\x00\x00\x13\x00\x00\x00Canada/SaskatchewanTZif2\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\x005\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x86\xfd\x93\x1c\xff\xff\xff\xff\x9e\xb8\xaf\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xb5eO\xf0\xff\xff\xff\xff\xb60H\xe0\xff\xff\xff\xff\xb7E1\xf0\xff\xff\xff\xff\xb8\x10*\xe0\xff\xff\xff\xff\xb9%\x13\xf0\xff\xff\xff\xff\xb9\xf0\x0c\xe0\xff\xff\xff\xff\xbb\x0e0p\xff\xff\xff\xff\xbb\xcf\xee\xe0\xff\xff\xff\xff\xbc\xee\x12p\xff\xff\xff\xff\xbd\xb9\x0b`\xff\xff\xff\xff\xc2r\x08\xf0\xff\xff\xff\xff\xc3a\xeb\xe0\xff\xff\xff\xff\xc4Q\xea\xf0\xff\xff\xff\xff\xc58\x93`\xff\xff\xff\xff\xc61\xcc\xf0\xff\xff\xff\xff\xc7!\xaf\xe0\xff\xff\xff\xff\xc8\x1a\xe9p\xff\xff\xff\xff\xc9\x0a\xcc`\xff\xff\xff\xff\xc9\xfa\xcbp\xff\xff\xff\xff\xca\xea\xae`\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xd3c\x8c\x10\xff\xff\xff\xff\xd4So\x00\xff\xff\xff\xff\xd5U\xe3\x10\xff\xff\xff\xff\xd6 \xdc\x00\xff\xff\xff\xff\xd75\xc5\x10\xff\xff\xff\xff\xd8\x00\xbe\x00\xff\xff\xff\xff\xd9\x15\xa7\x10\xff\xff\xff\xff\xd9\xe0\xa0\x00\xff\xff\xff\xff\xda\xfe\xc3\x90\xff\xff\xff\xff\xdb\xc0\x82\x00\xff\xff\xff\xff\xdc\xde\xa5\x90\xff\xff\xff\xff\xdd\xa9\x9e\x80\xff\xff\xff\xff\xde\xbe\x87\x90\xff\xff\xff\xff\xdf\x89\x80\x80\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ib\x80\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3ID\x80\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)&\x80\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12C\x00\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf2%\x00\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xd6\xd3\x00\xff\xff\xff\xff\xed\xc6\xd2\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\x05\xff\xff\x9d\xe4\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10\xff\xff\xab\xa0\x00\x14LMT\x00MDT\x00MST\x00MWT\x00MPT\x00CST\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x1d\xee\x91\x05\x04\x00\x00\x05\x04\x00\x00\x0c\x00\x00\x00Canada/YukonTZif2\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\x09\x00\x00\x00%\xff\xff\xff\xff}\x86\x8a\x9c\xff\xff\xff\xff\x9e\xb8\xcb\xb0\xff\xff\xff\xff\x9f\xbb#\xa0\xff\xff\xff\xff\xa0\xd0\x0c\xb0\xff\xff\xff\xff\xa1\xa2\xd2\x80\xff\xff\xff\xff\xcb\x89(\xb0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a4 \xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf8\xc5\x84\x90\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x00\x00\x00\x00G-\x8a\x10\x00\x00\x00\x00G\xd3\xb5 \x00\x00\x00\x00I\x0dl\x10\x00\x00\x00\x00I\xb3\x97 \x00\x00\x00\x00J\xedN\x10\x00\x00\x00\x00K\x9c\xb3\xa0\x00\x00\x00\x00L\xd6j\x90\x00\x00\x00\x00M|\x95\xa0\x00\x00\x00\x00N\xb6L\x90\x00\x00\x00\x00O\x5cw\xa0\x00\x00\x00\x00P\x96.\x90\x00\x00\x00\x00Q<Y\xa0\x00\x00\x00\x00Rv\x10\x90\x00\x00\x00\x00S\x1c;\xa0\x00\x00\x00\x00TU\xf2\x90\x00\x00\x00\x00T\xfc\x1d\xa0\x00\x00\x00\x00V5\xd4\x90\x00\x00\x00\x00V\xe5: \x00\x00\x00\x00X\x1e\xf1\x10\x00\x00\x00\x00X\xc5\x1c \x00\x00\x00\x00Y\xfe\xd3\x10\x00\x00\x00\x00Z\xa4\xfe \x00\x00\x00\x00[\xde\xb5\x10\x00\x00\x00\x00\x5c\x84\xe0 \x00\x00\x00\x00]\xbe\x97\x10\x00\x00\x00\x00^d\xc2 \x00\x00\x00\x00_\x9e\x5c\xf0\x02\x01\x02\x01\x02\x03\x04\x02\x05\x02\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\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\x08\xff\xff\x81d\x00\x00\xff\xff\x8f\x80\x01\x04\xff\xff\x81p\x00\x08\xff\xff\x8f\x80\x01\x0c\xff\xff\x8f\x80\x01\x10\xff\xff\x9d\x90\x01\x14\xff\xff\x8f\x80\x00\x19\xff\xff\x9d\x90\x01\x1d\xff\xff\x9d\x90\x00!LMT\x00YDT\x00YST\x00YWT\x00YPT\x00YDDT\x00PST\x00PDT\x00MST\x00\x0aMST7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x22_WJ\x05\x00\x00J\x05\x00\x00\x11\x00\x00\x00Chile/ContinentalTZif3\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\x00\x82\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87\x1d\xc5\xff\xff\xff\xff\x8f0GE\xff\xff\xff\xff\x9b\x5c\xe5P\xff\xff\xff\xff\x9f|\xe2\xc5\xff\xff\xff\xff\xa1\x00q\xc0\xff\xff\xff\xff\xb0^w\xc5\xff\xff\xff\xff\xb1w=@\xff\xff\xff\xff\xb2A\x00\xd0\xff\xff\xff\xff\xb3Xp\xc0\xff\xff\xff\xff\xb4\x224P\xff\xff\xff\xff\xb59\xa4@\xff\xff\xff\xff\xb6\x03g\xd0\xff\xff\xff\xff\xb7\x1a\xd7\xc0\xff\xff\xff\xff\xb7\xe4\x9bP\xff\xff\xff\xff\xb8\xfd\x5c\xc0\xff\xff\xff\xff\xb9\xc7 P\xff\xff\xff\xff\xcc\x1cn@\xff\xff\xff\xff\xccl\xe7\xd0\xff\xff\xff\xff\xd3\xdc\x8f\xc0\xff\xff\xff\xff\xd4\x17\xd50\xff\xff\xff\xff\xd53U\xc0\xff\xff\xff\xff\xd5v\x92@\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00r\xdc\xb0\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\x0d\xb0\x00\x00\x00\x00\x07\x0b\xbc@\x00\x00\x00\x00\x07\xdf\xef\xb0\x00\x00\x00\x00\x08\xfe\x13@\x00\x00\x00\x00\x09\xbf\xd1\xb0\x00\x00\x00\x00\x0a\xdd\xf5@\x00\x00\x00\x00\x0b\xa8\xee0\x00\x00\x00\x00\x0c\xbd\xd7@\x00\x00\x00\x00\x0d\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\x5c@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\x229\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'\xd9\xa10\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)\xc2\xbd\xb0\x00\x00\x00\x00*\xd7\xa6\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\x0bD0\x00\x00\x00\x006\x0d\xb8@\x00\x00\x00\x007\x06\xd5\xb0\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\x080\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\x0d\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@S\xca\xb0\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\x070\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\x5cr\xb0\x00\x00\x00\x00T\x0b\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\x5c\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\x0d\xb0\x00\x00\x00\x00c\x1d]@\x00\x00\x00\x00d(\xef\xb0\x01\x02\x01\x03\x01\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x03\x02\x03\x05\x04\x02\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\x05\x03\xff\xff\xbd\xbb\x00\x00\xff\xff\xbd\xbb\x00\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x00\x0c\xff\xff\xc7\xc0\x01\x0c\xff\xff\xd5\xd0\x01\x10LMT\x00SMT\x00-05\x00-04\x00-03\x00\x0a<-04>4<-03>,M9.1.6/24,M4.1.6/24\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?X'\x8e\x96\x04\x00\x00\x96\x04\x00\x00\x12\x00\x00\x00Chile/EasterIslandTZif3\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\x00n\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87B\x08\xff\xff\xff\xff\xb9\xc7@\x88\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00r\xdc\xb0\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\x0d\xb0\x00\x00\x00\x00\x07\x0b\xbc@\x00\x00\x00\x00\x07\xdf\xef\xb0\x00\x00\x00\x00\x08\xfe\x13@\x00\x00\x00\x00\x09\xbf\xd1\xb0\x00\x00\x00\x00\x0a\xdd\xf5@\x00\x00\x00\x00\x0b\xa8\xee0\x00\x00\x00\x00\x0c\xbd\xd7@\x00\x00\x00\x00\x0d\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\x5c@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\x229\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'\xd9\xa10\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)\xc2\xbd\xb0\x00\x00\x00\x00*\xd7\xa6\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\x0bD0\x00\x00\x00\x006\x0d\xb8@\x00\x00\x00\x007\x06\xd5\xb0\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\x080\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\x0d\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@S\xca\xb0\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\x070\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\x5cr\xb0\x00\x00\x00\x00T\x0b\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\x5c\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\x0d\xb0\x00\x00\x00\x00c\x1d]@\x00\x00\x00\x00d(\xef\xb0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\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\xff\xff\x99x\x00\x00\xff\xff\x99x\x00\x04\xff\xff\xab\xa0\x01\x08\xff\xff\x9d\x90\x00\x0c\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x10LMT\x00EMT\x00-06\x00-07\x00-05\x00\x0a<-06>6<-05>,M9.1.6/22,M4.1.6/22\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x04\x00\x00\x00CubaTZif2\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\x00j\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87(\xb8\xff\xff\xff\xff\xacb\xc2\x80\xff\xff\xff\xff\xb1\xd3\x94P\xff\xff\xff\xff\xb2t]@\xff\xff\xff\xff\xc8[f\xd0\xff\xff\xff\xff\xc8\xd3Q@\xff\xff\xff\xff\xca;H\xd0\xff\xff\xff\xff\xca\xbcm\xc0\xff\xff\xff\xff\xcc$eP\xff\xff\xff\xff\xcc\x9cO\xc0\xff\xff\xff\xff\xd1\xc4\x0bP\xff\xff\xff\xff\xd2;\xf5\xc0\xff\xff\xff\xff\xd3\xa3\xedP\xff\xff\xff\xff\xd4\x1b\xd7\xc0\xff\xff\xff\xff\xf7`\x05\xd0\xff\xff\xff\xff\xf7\xff}@\xff\xff\xff\xff\xf9=D\xd0\xff\xff\xff\xff\xf9\xe3S\xc0\xff\xff\xff\xff\xfa\xdb;\xd0\xff\xff\xff\xff\xfb\xa7\x86@\xff\xff\xff\xff\xfc\xc5\xa9\xd0\xff\xff\xff\xff\xfd\x87h@\xff\xff\xff\xff\xfe\xb8\x00\xd0\xff\xff\xff\xff\xff\xa7\xe3\xc0\x00\x00\x00\x00\x00\x97\xe2\xd0\x00\x00\x00\x00\x01\x87\xc5\xc0\x00\x00\x00\x00\x02w\xc4\xd0\x00\x00\x00\x00\x03p\xe2@\x00\x00\x00\x00\x04`\xe1P\x00\x00\x00\x00\x055\x14\xc0\x00\x00\x00\x00\x06@\xc3P\x00\x00\x00\x00\x07\x16H@\x00\x00\x00\x00\x08 \xa5P\x00\x00\x00\x00\x08\xf7{\xc0\x00\x00\x00\x00\x0a\x00\x87P\x00\x00\x00\x00\x0a\xf0j@\x00\x00\x00\x00\x0b\xe0iP\x00\x00\x00\x00\x0c\xd9\x86\xc0\x00\x00\x00\x00\x0d\xc0KP\x00\x00\x00\x00\x0e\xb9h\xc0\x00\x00\x00\x00\x0f\xb2\xa2P\x00\x00\x00\x00\x10}\x9b@\x00\x00\x00\x00\x11Q\xea\xd0\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x131\xcc\xd0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15[\x82\xd0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x17;d\xd0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x19\x1bF\xd0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xfb(\xd0\x00\x00\x00\x00\x1b\xcf\x5c@\x00\x00\x00\x00\x1c\xdb\x0a\xd0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ezSP\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 Z5P\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\x22CQ\xd0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$#3\xd0\x00\x00\x00\x00%.\xc6@\x00\x00\x00\x00&\x15\x8a\xd0\x00\x00\x00\x00'\x17\xe2\xc0\x00\x00\x00\x00'\xfe\xa7P\x00\x00\x00\x00(\xf7\xd2\xd0\x00\x00\x00\x00)\xde\x89P\x00\x00\x00\x00*\xd7\xb4\xd0\x00\x00\x00\x00+\xbekP\x00\x00\x00\x00,\xb7\x96\xd0\x00\x00\x00\x00-\x9eMP\x00\x00\x00\x00.\x97x\xd0\x00\x00\x00\x00/~/P\x00\x00\x00\x000wZ\xd0\x00\x00\x00\x001gK\xd0\x00\x00\x00\x002W<\xd0\x00\x00\x00\x003G-\xd0\x00\x00\x00\x004@YP\x00\x00\x00\x005\x1d\xd5P\x00\x00\x00\x0062\xb0P\x00\x00\x00\x006\xfd\xb7P\x00\x00\x00\x008\x1b\xcc\xd0\x00\x00\x00\x008\xe6\xd3\xd0\x00\x00\x00\x009\xfb\xae\xd0\x00\x00\x00\x00:\xc6\xb5\xd0\x00\x00\x00\x00;\xdb\x90\xd0\x00\x00\x00\x00<\xaf\xd2P\x00\x00\x00\x00=\xbbr\xd0\x00\x00\x00\x00>\x8f\xb4P\x00\x00\x00\x00?\x9bT\xd0\x00\x00\x00\x00@f[\xd0\x00\x00\x00\x00ED5P\x00\x00\x00\x00E\xf3\x8c\xd0\x00\x00\x00\x00G$\x17P\x00\x00\x00\x00G\xdc\xa9P\x00\x00\x00\x00I\x03\xf9P\x00\x00\x00\x00I\xb3P\xd0\x00\x00\x00\x00J\xe3\xdbP\x00\x00\x00\x00K\x9cmP\x00\x00\x00\x00L\xcc\xf7\xd0\x00\x00\x00\x00M\x85\x89\xd0\x00\x00\x00\x00N\xbfN\xd0\x00\x00\x00\x00Ow\xe0\xd0\x00\x00\x00\x00P\x95\xf6P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\xb2\xc8\x00\x00\xff\xff\xb2\xc0\x00\x04\xff\xff\xc7\xc0\x01\x08\xff\xff\xb9\xb0\x00\x0cLMT\x00HMT\x00CDT\x00CST\x00\x0aCST5CDT,M3.2.0/0,M11.1.0/1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`l\x8d~\xf1\x01\x00\x00\xf1\x01\x00\x00\x03\x00\x00\x00EETTZif2\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\x02\x00\x00\x00\x09\x00\x00\x00\x00\x0d\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x1c \x00\x05\x00\x00*0\x01\x00EEST\x00EET\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tX\xbe\xe4o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00ESTTZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\xb9\xb0\x00\x00EST\x00\x0aEST5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7/\xebT\xb7\x03\x00\x00\xb7\x03\x00\x00\x07\x00\x00\x00EST5EDTTZif2\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\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6\x1ep\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x86\x00p\xff\xff\xff\xff\xa1\x9a\xcd`\xff\xff\xff\xff\xcb\x88\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x07\x8d\x19p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x09\xad\x94\xf0\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\xb9\xb0\x00\x04\xff\xff\xc7\xc0\x01\x00\xff\xff\xc7\xc0\x01\x08\xff\xff\xc7\xc0\x01\x0cEDT\x00EST\x00EWT\x00EPT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5#)\x16\x1d\x05\x00\x00\x1d\x05\x00\x00\x05\x00\x00\x00EgyptTZif2\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\x80\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xff}\xbdM\xab\xff\xff\xff\xff\xc8\x93\xb4\xe0\xff\xff\xff\xff\xc8\xfa{\xd0\xff\xff\xff\xff\xc9\xfc\xef\xe0\xff\xff\xff\xff\xca\xc7\xe8\xd0\xff\xff\xff\xff\xcb\xcb\xae`\xff\xff\xff\xff\xcc\xdf)\xd0\xff\xff\xff\xff\xcd\xac\xe1\xe0\xff\xff\xff\xff\xce\xc6\xf4\xd0\xff\xff\xff\xff\xcf\x8ff\xe0\xff\xff\xff\xff\xd0\xa9y\xd0\xff\xff\xff\xff\xd1\x84`\xe0\xff\xff\xff\xff\xd2\x8a\xadP\xff\xff\xff\xff\xe86c`\xff\xff\xff\xff\xe8\xf4-P\xff\xff\xff\xff\xea\x0b\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\x7f\xf0\xff\xff\xff\xff\xee\x97\xf2\x00\xff\xff\xff\xff\xef\xb0\xb3p\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\xc2\xfd\x80\xff\xff\xff\xff\xfc\xdb\xbe\xf0\xff\xff\xff\xff\xfd\xa5\x82\x80\xff\xff\xff\xff\xfe\xbc\xf2p\xff\xff\xff\xff\xff\x86\xb6\x00\x00\x00\x00\x00\x00\x9e%\xf0\x00\x00\x00\x00\x01g\xe9\x80\x00\x00\x00\x00\x02\x7fYp\x00\x00\x00\x00\x03I\x1d\x00\x00\x00\x00\x00\x04a\xdep\x00\x00\x00\x00\x05+\xa2\x00\x00\x00\x00\x00\x06C\x11\xf0\x00\x00\x00\x00\x07\x0c\xd5\x80\x00\x00\x00\x00\x08$Ep\x00\x00\x00\x00\x08\xee\x09\x00\x00\x00\x00\x00\x0a\x05x\xf0\x00\x00\x00\x00\x0a\xcf<\x80\x00\x00\x00\x00\x0b\xe7\xfd\xf0\x00\x00\x00\x00\x0c\xb1\xc1\x80\x00\x00\x00\x00\x0d\xc91p\x00\x00\x00\x00\x0e\x92\xf5\x00\x00\x00\x00\x00\x0f\xaad\xf0\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11\x8b\x98p\x00\x00\x00\x00\x12U\x5c\x00\x00\x00\x00\x00\x13n\x1dp\x00\x00\x00\x00\x147\xe1\x00\x00\x00\x00\x00\x15OP\xf0\x00\x00\x00\x00\x16\x19\x14\x80\x00\x00\x00\x00\x17\xa0\x93\xf0\x00\x00\x00\x00\x17\xfaH\x00\x00\x00\x00\x00\x19p\xa3\xf0\x00\x00\x00\x00\x19\xdb{\x80\x00\x00\x00\x00\x1a\xf4<\xf0\x00\x00\x00\x00\x1b\xbe\x00\x80\x00\x00\x00\x00\x1c\xd5pp\x00\x00\x00\x00\x1d\x9f4\x00\x00\x00\x00\x00\x1e\xb6\xa3\xf0\x00\x00\x00\x00\x1f\x80g\x80\x00\x00\x00\x00 \x97\xd7p\x00\x00\x00\x00!a\x9b\x00\x00\x00\x00\x00\x22z\x5cp\x00\x00\x00\x00#D \x00\x00\x00\x00\x00$b'p\x00\x00\x00\x00%%S\x80\x00\x00\x00\x00&<\xc3p\x00\x00\x00\x00'\x06\x87\x00\x00\x00\x00\x00(\x1d\xf6\xf0\x00\x00\x00\x00(\xe7\xba\x80\x00\x00\x00\x00*\x00{\xf0\x00\x00\x00\x00*\xca?\x80\x00\x00\x00\x00+\xe1\xafp\x00\x00\x00\x00,\xabs\x00\x00\x00\x00\x00-\xc2\xe2\xf0\x00\x00\x00\x00.\x8c\xa6\x80\x00\x00\x00\x00/\xa0\x13\xe0\x00\x00\x00\x000k\x0c\xd0\x00\x00\x00\x001\x7f\xf5\xe0\x00\x00\x00\x002J\xee\xd0\x00\x00\x00\x003_\xd7\xe0\x00\x00\x00\x004*\xd0\xd0\x00\x00\x00\x005?\xb9\xe0\x00\x00\x00\x006\x0a\xb2\xd0\x00\x00\x00\x007(\xd6`\x00\x00\x00\x007\xf3\xcfP\x00\x00\x00\x009\x08\xb8`\x00\x00\x00\x009\xd3\xb1P\x00\x00\x00\x00:\xe8\x9a`\x00\x00\x00\x00;\xb3\x93P\x00\x00\x00\x00<\xc8|`\x00\x00\x00\x00=\x93uP\x00\x00\x00\x00>\xa8^`\x00\x00\x00\x00?sWP\x00\x00\x00\x00@\x91z\xe0\x00\x00\x00\x00A\x5cs\xd0\x00\x00\x00\x00Bq\x5c\xe0\x00\x00\x00\x00C<U\xd0\x00\x00\x00\x00DQ>\xe0\x00\x00\x00\x00E\x12\xfdP\x00\x00\x00\x00F1 \xe0\x00\x00\x00\x00F\xe0jP\x00\x00\x00\x00H\x11\x02\xe0\x00\x00\x00\x00H\xb7\x11\xd0\x00\x00\x00\x00I\xf0\xe4\xe0\x00\x00\x00\x00J\x8d\xb9P\x00\x00\x00\x00K\xda\x01`\x00\x00\x00\x00La\xbd\xd0\x00\x00\x00\x00L\x89X\xe0\x00\x00\x00\x00L\xa4\xfaP\x00\x00\x00\x00Su8\xe0\x00\x00\x00\x00S\xac\x89\xd0\x00\x00\x00\x00S\xda\xbc`\x00\x00\x00\x00T$\x82P\x00\x00\x00\x00dJ\xf0`\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\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\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\x1dU\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\x09LMT\x00EEST\x00EET\x00\x0aEET-2EEST,M4.5.5/0,M10.5.4/24\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xd6jL\xd8\x05\x00\x00\xd8\x05\x00\x00\x04\x00\x00\x00EireTZif2\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\x0a\xf1\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 \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{\xc8\xa0\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00\xd3\xa0\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \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 \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 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd7,( \xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde\xb4\xea\xa0\xff\xff\xff\xff\xdf\xae\x16 \xff\xff\xff\xff\xe0\x94\xcc\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \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 \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\x0b \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\xee\x9a\xb1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\x0d\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0\xd1\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \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 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\x09: \x00\x00\x00\x00\x070\x8a \x00\x00\x00\x00\x07\xe9\x1c \x00\x00\x00\x00\x09\x10l \x00\x00\x00\x00\x09\xc8\xfe \x00\x00\x00\x00\x0a\xf0N \x00\x00\x00\x00\x0b\xb2\x1a\xa0\x00\x00\x00\x00\x0c\xd00 \x00\x00\x00\x00\x0d\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \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 lr\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)\x0a\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\x0f\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\x0aIST-1GMT0,M10.5.0,M3.5.0/1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x07\x00\x00\x00Etc/GMTTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x09\x00\x00\x00Etc/GMT+0TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\xb8\xe8\x86q\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00Etc/GMT+1TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\xf1\xf0\x00\x00-01\x00\x0a<-01>1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8e\x1569r\x00\x00\x00r\x00\x00\x00\x0a\x00\x00\x00Etc/GMT+10TZif2\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\x00\x01\x00\x00\x00\x04\xff\xffs`\x00\x00-10\x00\x0a<-10>10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\xb9\xbe\x9dr\x00\x00\x00r\x00\x00\x00\x0a\x00\x00\x00Etc/GMT+11TZif2\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\x00\x01\x00\x00\x00\x04\xff\xffeP\x00\x00-11\x00\x0a<-11>11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xf38cr\x00\x00\x00r\x00\x00\x00\x0a\x00\x00\x00Etc/GMT+12TZif2\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\x00\x01\x00\x00\x00\x04\xff\xffW@\x00\x00-12\x00\x0a<-12>12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9{\xa2qq\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00Etc/GMT+2TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\xe3\xe0\x00\x00-02\x00\x0a<-02>2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\xcb\xe9Qq\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00Etc/GMT+3TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\xd5\xd0\x00\x00-03\x00\x0a<-03>3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\xfaFDq\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00Etc/GMT+4TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\xc7\xc0\x00\x00-04\x00\x0a<-04>4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4X\x9b\xf3q\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00Etc/GMT+5TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\xb9\xb0\x00\x00-05\x00\x0a<-05>5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\x9b\xd1\x04q\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00Etc/GMT+6TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\xab\xa0\x00\x00-06\x00\x0a<-06>6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84+\x9a$q\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00Etc/GMT+7TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\x9d\x90\x00\x00-07\x00\x0a<-07>7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x22\xf8\x8f/q\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00Etc/GMT+8TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\x8f\x80\x00\x00-08\x00\x0a<-08>8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x19\xb3\x09q\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00Etc/GMT+9TZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\x81p\x00\x00-09\x00\x0a<-09>9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x09\x00\x00\x00Etc/GMT-0TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\x1ac\xc3r\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00Etc/GMT-1TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x0e\x10\x00\x00+01\x00\x0a<+01>-1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9|\xbd7s\x00\x00\x00s\x00\x00\x00\x0a\x00\x00\x00Etc/GMT-10TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x8c\xa0\x00\x00+10\x00\x0a<+10>-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xab\xd1Is\x00\x00\x00s\x00\x00\x00\x0a\x00\x00\x00Etc/GMT-11TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x9a\xb0\x00\x00+11\x00\x0a<+11>-11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\x19s\x81s\x00\x00\x00s\x00\x00\x00\x0a\x00\x00\x00Etc/GMT-12TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\xa8\xc0\x00\x00+12\x00\x0a<+12>-12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90`N\xe8s\x00\x00\x00s\x00\x00\x00\x0a\x00\x00\x00Etc/GMT-13TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\xb6\xd0\x00\x00+13\x00\x0a<+13>-13\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,{\xdc;s\x00\x00\x00s\x00\x00\x00\x0a\x00\x00\x00Etc/GMT-14TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\xc4\xe0\x00\x00+14\x00\x0a<+14>-14\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x19y\x04r\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00Etc/GMT-2TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x1c \x00\x00+02\x00\x0a<+02>-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\xfcm\x99r\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00Etc/GMT-3TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00*0\x00\x00+03\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x19<Qr\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00Etc/GMT-4TZif2\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\x00\x01\x00\x00\x00\x04\x00\x008@\x00\x00+04\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\xd6~wr\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00Etc/GMT-5TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00FP\x00\x00+05\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j\xd5d\xb0r\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00Etc/GMT-6TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00T`\x00\x00+06\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J0p-r\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00Etc/GMT-7TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00bp\x00\x00+07\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x18\xb6\xfbr\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00Etc/GMT-8TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00p\x80\x00\x00+08\x00\x0a<+08>-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\x19@\xb9r\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00Etc/GMT-9TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00~\x90\x00\x00+09\x00\x0a<+09>-9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x08\x00\x00\x00Etc/GMT0TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x0d\x00\x00\x00Etc/GreenwichTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x07\x00\x00\x00Etc/UCTTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\x0aUTC0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x07\x00\x00\x00Etc/UTCTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\x0aUTC0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x0d\x00\x00\x00Etc/UniversalTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\x0aUTC0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x08\x00\x00\x00Etc/ZuluTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\x0aUTC0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x10\x00\x00\x00Europe/AmsterdamTZif2\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\x00f\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xdf\xe6\xff\xff\xff\xffm\xe8\xc8\x00\xff\xff\xff\xff\x98DI\x80\xff\xff\xff\xff\x9b\x0c%p\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x9f\xce\xf80\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xbbp\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9\x07}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xad\xc9\xa7\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \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\xb8\xff\xe3\xa0\xff\xff\xff\xff\xb9\xef\xd4\xa0\xff\xff\xff\xff\xba\xd6\x8b \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\x9f\x89\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88 \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xc8J\x19 \xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\xff\xff\xff\xff\xd3\x91@\x10\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\x0d\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x04\x1a\x00\x00\x00\x00\x04\x1a\x00\x04\x00\x00\x00\x00\x00\x08\x00\x00\x0e\x10\x00\x0c\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x01\x15LMT\x00BMT\x00WET\x00CET\x00CEST\x00WEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\x9cv\xcf\x85\x01\x00\x00\x85\x01\x00\x00\x0e\x00\x00\x00Europe/AndorraTZif2\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\x19\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff~6\xb3\x94\xff\xff\xff\xff\xd4A\xdb\x00\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x00\x01l\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x0e\x10\x00\x08\x00\x00\x1c \x01\x0cLMT\x00WET\x00CET\x00CEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]i\x11u\xd6\x02\x00\x00\xd6\x02\x00\x00\x10\x00\x00\x00Europe/AstrakhanTZif2\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\x05\x00\x00\x00\x10\xff\xff\xff\xff\xaa\x18Et\xff\xff\xff\xff\xb5\xa4\x0bP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\x08\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a\xcc\x85\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c8\xe0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\x0b\xe0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\x07p\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00I\xce\xab\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00L\xcc\xa3p\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00V\xf7\x14p\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00-\x0c\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\x08\x00\x008@\x00\x0c\x00\x008@\x01\x0cLMT\x00+03\x00+05\x00+04\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcb*j\x8f\xaa\x02\x00\x00\xaa\x02\x00\x00\x0d\x00\x00\x00Europe/AthensTZif2\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\x007\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xfft?\x98D\xff\xff\xff\xff\x9b\x80!\x80\xff\xff\xff\xff\xb9|\xe9\xe0\xff\xff\xff\xff\xb9\xc6\xaf\xd0\xff\xff\xff\xff\xc9\xf2c\xe0\xff\xff\xff\xff\xca\x10\xa8P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xaaL\xf0\xff\xff\xff\xff\xce\xa2\x18\xe0\xff\xff\xff\xff\xcf\x93ip\xff\xff\xff\xff\xdf\x13\x9e`\xff\xff\xff\xff\xdf\xb7\x0aP\x00\x00\x00\x00\x09\xec^`\x00\x00\x00\x00\x0b\x18\xf4`\x00\x00\x00\x00\x0b\xcd\xae\x00\x00\x00\x00\x00\x0c\xbd\x9f\x00\x00\x00\x00\x00\x0d\xa4U\x80\x00\x00\x00\x00\x0e\x8c]\x80\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10j\xfc\x10\x00\x00\x00\x00\x11d{\xf0\x00\x00\x00\x00\x12R\xaa\xf0\x00\x00\x00\x00\x13F\x82`\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x05\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x16<\x00\x00\x00\x00\x16<\x00\x04\x00\x00*0\x01\x08\x00\x00\x1c \x00\x0d\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15LMT\x00AMT\x00EEST\x00EET\x00CET\x00CEST\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0e\x00\x00\x00Europe/BelfastTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\x09\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \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 \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{\xc8\xa0\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00\xd3\xa0\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \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 \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 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xff\xca\x97Y\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xff\xcd\xb1\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xff\xcf\x90\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde\xb4\xea\xa0\xff\xff\xff\xff\xdf\xae\x16 \xff\xff\xff\xff\xe0\x94\xcc\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \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 \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\x0b \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\xee\x9a\xb1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\x0d\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0\xd1\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \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 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\x09: \x00\x00\x00\x00\x070\x8a \x00\x00\x00\x00\x07\xe9\x1c \x00\x00\x00\x00\x09\x10l \x00\x00\x00\x00\x09\xc8\xfe \x00\x00\x00\x00\x0a\xf0N \x00\x00\x00\x00\x0b\xb2\x1a\xa0\x00\x00\x00\x00\x0c\xd00 \x00\x00\x00\x00\x0d\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \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 lr\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)\x0a\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\x08\x00\x00\x1c \x01\x0c\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\x0aGMT0BST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00Europe/BelgradeTZif2\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\x03\x00\x00\x00\x0d\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1\xa1\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\x08LMT\x00CET\x00CEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x0d\x00\x00\x00Europe/BerlinTZif2\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\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x09q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xb6\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xff\xd2\xa1O\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\xd5\xa8s\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\x09\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\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\x0c\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\x09\x00\x00*0\x01\x0dLMT\x00CEST\x00CET\x00CEMT\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Io\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\x11\x00\x00\x00Europe/BratislavaTZif2\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\x05\x00\x00\x00\x15\xff\xff\xff\xff\x1eI\x92\xf8\xff\xff\xff\xffl\xcf\xea\xf8\xff\xff\xff\xff\x9b\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x09q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2b\x07\x10\xff\xff\xff\xff\xd3\x80\x1c\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd4\x93\xb4 \xff\xff\xff\xff\xd5\x02r \xff\xff\xff\xff\xd5L8\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\x09\x96\x10\xff\xff\xff\xff\xd9\x01p\x10\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x0d\x88\x00\x00\x00\x00\x0d\x88\x00\x04\x00\x00\x1c \x01\x08\x00\x00\x0e\x10\x00\x0d\x00\x00\x00\x00\x01\x11LMT\x00PMT\x00CEST\x00CET\x00GMT\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x0f\x00\x00\x00Europe/BrusselsTZif2\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\x00f\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xdf\xe6\xff\xff\xff\xffm\xe8\xc8\x00\xff\xff\xff\xff\x98DI\x80\xff\xff\xff\xff\x9b\x0c%p\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x9f\xce\xf80\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xbbp\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9\x07}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xad\xc9\xa7\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \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\xb8\xff\xe3\xa0\xff\xff\xff\xff\xb9\xef\xd4\xa0\xff\xff\xff\xff\xba\xd6\x8b \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\x9f\x89\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88 \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xc8J\x19 \xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\xff\xff\xff\xff\xd3\x91@\x10\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\x0d\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x04\x1a\x00\x00\x00\x00\x04\x1a\x00\x04\x00\x00\x00\x00\x00\x08\x00\x00\x0e\x10\x00\x0c\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x01\x15LMT\x00BMT\x00WET\x00CET\x00CEST\x00WEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xa9\xf5\xcf\x95\x02\x00\x00\x95\x02\x00\x00\x10\x00\x00\x00Europe/BucharestTZif2\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\x007\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xffl\xcf\xe0\x08\xff\xff\xff\xff\xb7\xb0\xd2\x08\xff\xff\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xba\xdf\x8d`\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbc\xc8\xa9\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff\xff\xff\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\x22\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff\xff\xff\xc7\x18\x04\xe0\x00\x00\x00\x00\x11\xad\xd1`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\x0b\xd0\x00\x00\x00\x00\x143\xd0`\x00\x00\x00\x00\x15#\xdd\x80\x00\x00\x00\x00\x16\x13\xce\x80\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18\xe3\xa1\x80\x00\x00\x00\x00\x19\xd3\x92\x80\x00\x00\x00\x00\x1a\xc3\x83\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\x5cU\x00\x00\x00\x00\x00\x22LF\x00\x00\x00\x00\x00#<7\x00\x00\x00\x00\x00$,(\x00\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\x0c\x0a\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5\x0a`\x00\x00\x00\x00(\xe4\xfb`\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xbb\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x18x\x00\x00\x00\x00\x18x\x00\x04\x00\x00*0\x01\x08\x00\x00\x1c \x00\x0dLMT\x00BMT\x00EEST\x00EET\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6Kf\xab\xfe\x02\x00\x00\xfe\x02\x00\x00\x0f\x00\x00\x00Europe/BudapestTZif2\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\x00D\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xffk\x17\x91\x9c\xff\xff\xff\xff\x9b\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\xa0\x9a\xc4\x10\xff\xff\xff\xff\xa1dy\x90\xff\xff\xff\xff\xa2p\x1a\x10\xff\xff\xff\xff\xa3M\x96\x10\xff\xff\xff\xff\xc9\xf3\xb5`\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1\x99x\xe0\xff\xff\xff\xff\xd2\x8a\xc9p\xff\xff\xff\xff\xd3P\xa6\x90\xff\xff\xff\xff\xd4K\x15\x80\xff\xff\xff\xff\xd59\xc3\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7\x19\xa5\x10\xff\xff\xff\xff\xd8\x09\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff\xe2\xa2\xa8\xf0\xff\xff\xff\xff\xe3Q\xf2`\xff\xff\xff\xff\xe4\x82\xa7\x10\xff\xff\xff\xff\xe51\xfe\x90\xff\xff\xff\xff\xe6t\xfe\x10\xff\xff\xff\xff\xe7\x11\xe0\x90\xff\xff\xff\xff\xe8T\xe0\x10\xff\xff\xff\xff\xe8\xf1\xc2\x90\x00\x00\x00\x00\x13M'\xf0\x00\x00\x00\x00\x143\xdep\x00\x00\x00\x00\x15#\xcfp\x00\x00\x00\x00\x16\x13\xc0p\x00\x00\x00\x00\x17\x03\xb1p\x00\x00\x00\x00\x17\xf3\xa2p\x00\x00\x00\x00\x18\xe3\x93p\x00\x00\x00\x00\x19\xd3\x84p\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00\x11\xe4\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\x09LMT\x00CEST\x00CET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\x0f\x00\x00\x00Europe/BusingenTZif2\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\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x08\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\x08\x00\x00\x0e\x10\x00\x0dLMT\x00BMT\x00CEST\x00CET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x00\x00Europe/ChisinauTZif2\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\x09\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc8\xf8\xff\xff\xff\xff\x9ek\x9f\x0c\xff\xff\xff\xff\xb7\xb0\xd2\x08\xff\xff\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xba\xdf\x8d`\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbc\xc8\xa9\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff\xff\xff\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\x22\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff\xff\xff\xc7\x18\x04\xe0\xff\xff\xff\xff\xc8\xbc\x93`\xff\xff\xff\xff\xcaw}P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0N\x90`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00&CL\xe0\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xad\x00\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x06\x05\x06\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1b\x08\x00\x00\x00\x00\x1a\xf4\x00\x04\x00\x00\x18x\x00\x08\x00\x00*0\x01\x0c\x00\x00\x1c \x00\x11\x00\x00\x0e\x10\x00\x15\x00\x00\x1c \x01\x19\x00\x008@\x01\x1e\x00\x00*0\x00\x22LMT\x00CMT\x00BMT\x00EEST\x00EET\x00CET\x00CEST\x00MSD\x00MSK\x00\x0aEET-2EEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x11\x00\x00\x00Europe/CopenhagenTZif2\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\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x09q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xb6\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xff\xd2\xa1O\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\xd5\xa8s\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\x09\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\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\x0c\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\x09\x00\x00*0\x01\x0dLMT\x00CEST\x00CET\x00CEMT\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xd6jL\xd8\x05\x00\x00\xd8\x05\x00\x00\x0d\x00\x00\x00Europe/DublinTZif2\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\x0a\xf1\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 \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{\xc8\xa0\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00\xd3\xa0\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \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 \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 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd7,( \xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde\xb4\xea\xa0\xff\xff\xff\xff\xdf\xae\x16 \xff\xff\xff\xff\xe0\x94\xcc\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \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 \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\x0b \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\xee\x9a\xb1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\x0d\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0\xd1\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \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 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\x09: \x00\x00\x00\x00\x070\x8a \x00\x00\x00\x00\x07\xe9\x1c \x00\x00\x00\x00\x09\x10l \x00\x00\x00\x00\x09\xc8\xfe \x00\x00\x00\x00\x0a\xf0N \x00\x00\x00\x00\x0b\xb2\x1a\xa0\x00\x00\x00\x00\x0c\xd00 \x00\x00\x00\x00\x0d\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \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 lr\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)\x0a\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\x0f\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\x0aIST-1GMT0,M10.5.0,M3.5.0/1\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00==\xa4\x16\xc4\x04\x00\x00\xc4\x04\x00\x00\x10\x00\x00\x00Europe/GibraltarTZif2\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\x00s\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffW\xd1\x0a\x04\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \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 \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{\xc8\xa0\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00\xd3\xa0\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \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 \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 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xff\xca\x97Y\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xff\xcd\xb1\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xff\xcf\x90\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde\xb4\xea\xa0\xff\xff\xff\xff\xdf\xae\x16 \xff\xff\xff\xff\xe0\x94\xcc\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \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 \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\xff\xff\xfa\xfc\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\x08\x00\x00\x1c \x01\x0c\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15LMT\x00BST\x00GMT\x00BDST\x00CET\x00CEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0f\x00\x00\x00Europe/GuernseyTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\x09\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \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 \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{\xc8\xa0\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00\xd3\xa0\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \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 \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 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xff\xca\x97Y\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xff\xcd\xb1\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xff\xcf\x90\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde\xb4\xea\xa0\xff\xff\xff\xff\xdf\xae\x16 \xff\xff\xff\xff\xe0\x94\xcc\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \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 \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\x0b \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\xee\x9a\xb1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\x0d\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0\xd1\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \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 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\x09: \x00\x00\x00\x00\x070\x8a \x00\x00\x00\x00\x07\xe9\x1c \x00\x00\x00\x00\x09\x10l \x00\x00\x00\x00\x09\xc8\xfe \x00\x00\x00\x00\x0a\xf0N \x00\x00\x00\x00\x0b\xb2\x1a\xa0\x00\x00\x00\x00\x0c\xd00 \x00\x00\x00\x00\x0d\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \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 lr\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)\x0a\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\x08\x00\x00\x1c \x01\x0c\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\x0aGMT0BST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x0f\x00\x00\x00Europe/HelsinkiTZif2\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\x11\xff\xff\xff\xffS\xba&\x9b\xff\xff\xff\xff\xa4so\x1b\xff\xff\xff\xff\xcb\xceQ`\xff\xff\xff\xff\xcc\xc0\xe5`\x00\x00\x00\x00\x15#\xdd\x80\x00\x00\x00\x00\x16\x13\xce\x80\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x17e\x00\x00\x00\x00\x17e\x00\x04\x00\x00*0\x01\x08\x00\x00\x1c \x00\x0dLMT\x00HMT\x00EEST\x00EET\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x12\x00\x00\x00Europe/Isle_of_ManTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\x09\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \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 \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{\xc8\xa0\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00\xd3\xa0\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \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 \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 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xff\xca\x97Y\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xff\xcd\xb1\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xff\xcf\x90\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde\xb4\xea\xa0\xff\xff\xff\xff\xdf\xae\x16 \xff\xff\xff\xff\xe0\x94\xcc\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \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 \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\x0b \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\xee\x9a\xb1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\x0d\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0\xd1\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \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 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\x09: \x00\x00\x00\x00\x070\x8a \x00\x00\x00\x00\x07\xe9\x1c \x00\x00\x00\x00\x09\x10l \x00\x00\x00\x00\x09\xc8\xfe \x00\x00\x00\x00\x0a\xf0N \x00\x00\x00\x00\x0b\xb2\x1a\xa0\x00\x00\x00\x00\x0c\xd00 \x00\x00\x00\x00\x0d\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \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 lr\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)\x0a\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\x08\x00\x00\x1c \x01\x0c\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\x0aGMT0BST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07W\x10\xd1\xb0\x04\x00\x00\xb0\x04\x00\x00\x0f\x00\x00\x00Europe/IstanbulTZif2\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\x00s\x00\x00\x00\x06\x00\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xbe\xd0\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xaa((`\xff\xff\xff\xff\xaa\xe1\xfd\xd0\xff\xff\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc31P\xff\xff\xff\xff\xc8\x81?\xe0\xff\xff\xff\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J\xf5`\xff\xff\xff\xff\xca\xce\x80P\xff\xff\xff\xff\xcb\xcb\xae`\xff\xff\xff\xff\xd2k\x09P\xff\xff\xff\xff\xd3\xa29`\xff\xff\xff\xff\xd4C\x02P\xff\xff\xff\xff\xd5L\x0d\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff\xff\xff\xd7+\xef\xe0\xff\xff\xff\xff\xd8\x09]\xd0\xff\xff\xff\xff\xd9\x02\x97`\xff\xff\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff\xdb\xd2\x5cP\xff\xff\xff\xff\xdc\xd4\xd0`\xff\xff\xff\xff\xdd\xb2>P\xff\xff\xff\xff\xf1\xf4\xb9`\xff\xff\xff\xff\xf4b\xefP\xff\xff\xff\xff\xf5h\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\x079\x9ap\x00\x00\x00\x00\x07\xfbu\x00\x00\x00\x00\x00\x09\x19|p\x00\x00\x00\x00\x09\xd0\xcb\x00\x00\x00\x00\x00\x0a\xf9^p\x00\x00\x00\x00\x0b\xb1\xfe\x80\x00\x00\x00\x00\x0c\xd9@p\x00\x00\x00\x00\x0d\xa4U\x80\x00\x00\x00\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x0f\xf8\x11P\x00\x00\x00\x00\x19\x89\xb0p\x00\x00\x00\x00\x19\xdc\xb0\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00\x00\x00\x1c\xc6\xef\xf0\x00\x00\x00\x00\x1d\x9b1p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x09p\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x8b\x83\xf0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\x07p\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xc9\x90\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L\xcc\xbf\x90\x00\x00\x00\x00M\x8f\xdd\x90\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\x08\x00\x00\x1c \x00\x0d\x00\x00*0\x00\x11\x00\x008@\x01\x15LMT\x00IMT\x00EEST\x00EET\x00+03\x00+04\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0d\x00\x00\x00Europe/JerseyTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\x09\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \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 \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{\xc8\xa0\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00\xd3\xa0\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \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 \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 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xff\xca\x97Y\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xff\xcd\xb1\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xff\xcf\x90\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde\xb4\xea\xa0\xff\xff\xff\xff\xdf\xae\x16 \xff\xff\xff\xff\xe0\x94\xcc\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \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 \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\x0b \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\xee\x9a\xb1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\x0d\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0\xd1\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \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 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\x09: \x00\x00\x00\x00\x070\x8a \x00\x00\x00\x00\x07\xe9\x1c \x00\x00\x00\x00\x09\x10l \x00\x00\x00\x00\x09\xc8\xfe \x00\x00\x00\x00\x0a\xf0N \x00\x00\x00\x00\x0b\xb2\x1a\xa0\x00\x00\x00\x00\x0c\xd00 \x00\x00\x00\x00\x0d\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \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 lr\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)\x0a\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\x08\x00\x00\x1c \x01\x0c\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\x0aGMT0BST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O+j\x94\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00Europe/KaliningradTZif2\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\x00P\x00\x00\x00\x08\x00\x00\x00\x22\xff\xff\xff\xffo\xa2[H\xff\xff\xff\xff\x9b\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x09q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1|w\xe0\xff\xff\xff\xff\xd1\x95\x84`\xff\xff\xff\xff\xd2\x8a\xadP\xff\xff\xff\xff\xd3Y\xb6\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\x0c\x0a\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\x08\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4\xdb\x80\x00\x00\x00\x00-\x94\xcc\x80\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\x0d\x00\x00\x00\x00\x00D%\xd9\x80\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00I\xce\xba\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00L\xcc\xb1\x80\x00\x00\x00\x00M\x8e~\x00\x00\x00\x00\x00TL+p\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x04\x03\x04\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x07\x04\x00\x00\x138\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\x09\x00\x00*0\x01\x0d\x00\x00\x1c \x00\x12\x00\x008@\x01\x16\x00\x00*0\x00\x1a\x00\x00*0\x00\x1eLMT\x00CEST\x00CET\x00EEST\x00EET\x00MSD\x00MSK\x00+03\x00\x0aEET-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x0b\x00\x00\x00Europe/KievTZif2\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\x08\x00\x00\x00\x22\xff\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xce\xcd\xa8p\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\x08\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4\xdb\x80\x00\x00\x00\x00-\x94\xcc\x80\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c\x9c\x00\x04\x00\x00\x1c \x00\x08\x00\x00*0\x00\x0c\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00KMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f(NN\xdf\x02\x00\x00\xdf\x02\x00\x00\x0c\x00\x00\x00Europe/KirovTZif2\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\x07\x00\x00\x00\x18\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\x0bP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\x08\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a\xcc\x85\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c8\xe0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\x0b\xe0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\x07p\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00I\xce\xab\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00L\xcc\xa3p\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x05\x04\x05\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\x06\x05\x00\x00.\x98\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\x08\x00\x008@\x00\x0c\x00\x008@\x01\x10\x00\x00*0\x00\x14\x00\x008@\x00\x14LMT\x00+03\x00+05\x00+04\x00MSD\x00MSK\x00\x0aMSK-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x0b\x00\x00\x00Europe/KyivTZif2\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\x08\x00\x00\x00\x22\xff\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xce\xcd\xa8p\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\x08\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4\xdb\x80\x00\x00\x00\x00-\x94\xcc\x80\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c\x9c\x00\x04\x00\x00\x1c \x00\x08\x00\x00*0\x00\x0c\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00KMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&S\x03\x09\xae\x05\x00\x00\xae\x05\x00\x00\x0d\x00\x00\x00Europe/LisbonTZif2\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\x8d\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xff^=\x0c\x1d\xff\xff\xff\xff\x92\xe6\x8e\x80\xff\xff\xff\xff\x9bKmp\xff\xff\xff\xff\x9b\xfe\xc7\x80\xff\xff\xff\xff\x9c\x9c\xedp\xff\xff\xff\xff\x9d\xc9\x83p\xff\xff\xff\xff\x9e\x7frp\xff\xff\xff\xff\x9f\xaa\xb6\xf0\xff\xff\xff\xff\xa0_Tp\xff\xff\xff\xff\xa1\x8b\xeap\xff\xff\xff\xff\xa2A\xd9p\xff\xff\xff\xff\xa3nop\xff\xff\xff\xff\xa4#\x0c\xf0\xff\xff\xff\xff\xa5O\xa2\xf0\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xf4\x8e\xf0\xff\xff\xff\xff\xad\xc9\xa7\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\x22p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xbc\xc8\xb7\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xdfp\xff\xff\xff\xff\xc9\x01/p\xff\xff\xff\xff\xc9\xf1 p\xff\xff\xff\xff\xca\xe2b\xf0\xff\xff\xff\xff\xcb\xb5R\xf0\xff\xff\xff\xff\xcb\xec\xa3\xe0\xff\xff\xff\xff\xcc\x80K\xe0\xff\xff\xff\xff\xcc\xdc\xa2\xf0\xff\xff\xff\xff\xcd\x954\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xff\xcer\xa2\xe0\xff\xff\xff\xff\xce\xc5\xbfp\xff\xff\xff\xff\xcfu\x16\xf0\xff\xff\xff\xff\xcf\xacg\xe0\xff\xff\xff\xff\xd0R\x84\xe0\xff\xff\xff\xff\xd0\xa5\xa1p\xff\xff\xff\xff\xd1T\xf8\xf0\xff\xff\xff\xff\xd1\x8cI\xe0\xff\xff\xff\xff\xd22f\xe0\xff\xff\xff\xff\xd2\x85\x83p\xff\xff\xff\xff\xd3Y\xc4\xf0\xff\xff\xff\xff\xd4I\xb5\xf0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6)\xc2 \xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff\xff\xd8\x09\xa4 \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xd9\xe9\x86 \xff\xff\xff\xff\xda\xd9w \xff\xff\xff\xff\xdb\xc9h \xff\xff\xff\xff\xdc\xb9Y \xff\xff\xff\xff\xdd\xb2\x84\xa0\xff\xff\xff\xff\xde\xa2u\xa0\xff\xff\xff\xff\xdf\x92f\xa0\xff\xff\xff\xff\xe0\x82W\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe52\x0c\xa0\xff\xff\xff\xff\xe6!\xfd\xa0\xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x0b\x1a \xff\xff\xff\xff\xe8\xfb\x0b \xff\xff\xff\xff\xe9\xea\xfc \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\xee\x9a\xb1 \xff\xff\xff\xff\xef\x8a\xa2 \xff\xff\xff\xff\xf0z\x93 \xff\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2c\xaf\xa0\xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff\xff\xf4C\x91\xa0\xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff\xf6#s\xa0\xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8\x03U\xa0\xff\xff\xff\xff\xf8\xf3F\xa0\x00\x00\x00\x00\x0c\xab*\x00\x00\x00\x00\x00\x0d\x9b\x1b\x00\x00\x00\x00\x00\x0e\x8b\x0c\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xbd\xa0\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00\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\x03\x01\x02\x01\x03\x01\x02\x01\x03\x01\x02\x01\x03\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\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\x04\x05\x04\x05\x04\x05\x04\x01\xff\xff\xf7c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\x09\x00\x00\x1c \x01\x0d\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16LMT\x00WEST\x00WET\x00WEMT\x00CET\x00CEST\x00\x0aWET0WEST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x00\x00Europe/LjubljanaTZif2\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\x03\x00\x00\x00\x0d\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1\xa1\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\x08LMT\x00CET\x00CEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0d\x00\x00\x00Europe/LondonTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\x09\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \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 \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{\xc8\xa0\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00\xd3\xa0\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \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 \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 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xff\xca\x97Y\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xff\xcd\xb1\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xff\xcf\x90\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde\xb4\xea\xa0\xff\xff\xff\xff\xdf\xae\x16 \xff\xff\xff\xff\xe0\x94\xcc\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \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 \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\x0b \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\xee\x9a\xb1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\x0d\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0\xd1\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \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 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\x09: \x00\x00\x00\x00\x070\x8a \x00\x00\x00\x00\x07\xe9\x1c \x00\x00\x00\x00\x09\x10l \x00\x00\x00\x00\x09\xc8\xfe \x00\x00\x00\x00\x0a\xf0N \x00\x00\x00\x00\x0b\xb2\x1a\xa0\x00\x00\x00\x00\x0c\xd00 \x00\x00\x00\x00\x0d\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \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 lr\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)\x0a\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\x08\x00\x00\x1c \x01\x0c\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\x0aGMT0BST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x11\x00\x00\x00Europe/LuxembourgTZif2\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\x00f\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xdf\xe6\xff\xff\xff\xffm\xe8\xc8\x00\xff\xff\xff\xff\x98DI\x80\xff\xff\xff\xff\x9b\x0c%p\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x9f\xce\xf80\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xbbp\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8*\x01\xf0\xff\xff\xff\xff\xa9\x07}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xad\xc9\xa7\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2pL\xa0\xff\xff\xff\xff\xb3r\xb2\xa0\xff\xff\xff\xff\xb4P.\xa0\xff\xff\xff\xff\xb5IZ \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\xb8\xff\xe3\xa0\xff\xff\xff\xff\xb9\xef\xd4\xa0\xff\xff\xff\xff\xba\xd6\x8b \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xc8\xe2 \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\x9f\x89\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2h\x88 \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4?/\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xc8J\x19 \xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\xff\xff\xff\xff\xd3\x91@\x10\xff\xff\xff\xff\xd4K#\x90\x00\x00\x00\x00\x0d\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x02\x03\x04\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\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\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x00\x00\x04\x1a\x00\x00\x00\x00\x04\x1a\x00\x04\x00\x00\x00\x00\x00\x08\x00\x00\x0e\x10\x00\x0c\x00\x00\x1c \x01\x10\x00\x00\x0e\x10\x01\x15LMT\x00BMT\x00WET\x00CET\x00CEST\x00WEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Zk#V\x81\x03\x00\x00\x81\x03\x00\x00\x0d\x00\x00\x00Europe/MadridTZif2\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\x00O\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xff~6\xb5\x00\xff\xff\xff\xff\x9e\xba\xc5\xf0\xff\xff\xff\xff\x9f\xa09\x00\xff\xff\xff\xff\xa0\x90\x1b\xf0\xff\xff\xff\xff\xa1\x81l\x80\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xe7n\x00\xff\xff\xff\xff\xad\xc9\xa7\xf0\xff\xff\xff\xff\xae\xa72\x00\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x14\x00\xff\xff\xff\xff\xb1\x89z\x00\xff\xff\xff\xff\xb2p0\x80\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x12\x80\xff\xff\xff\xff\xc2\xc9\xec\xf0\xff\xff\xff\xff\xc3X]\x00\xff\xff\xff\xff\xc4H?\xf0\xff\xff\xff\xff\xc4m\x1b\xe0\xff\xff\xff\xff\xc59t`\xff\xff\xff\xff\xc7![\x80\xff\xff\xff\xff\xc7\xf5\x8e\xf0\xff\xff\xff\xff\xcb\xf5\xde`\xff\xff\xff\xff\xcc\x95q\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xff\xce\xa0\xd5p\xff\xff\xff\xff\xcf\xa3-`\xff\xff\xff\xff\xd0\x80\xb7p\xff\xff\xff\xff\xd1\x83\x0f`\xff\xff\xff\xff\xd2`\x99p\xff\xff\xff\xff\xd3b\xf1`\xff\xff\xff\xff\xd4@{p\xff\xff\xff\xff\xd9\x1eF\xe0\xff\xff\xff\xff\xd9\xe9[\xf0\x00\x00\x00\x00\x08\x0d\xcd\xe0\x00\x00\x00\x00\x08\xf4\x92p\x00\x00\x00\x00\x09\xed\xaf\xe0\x00\x00\x00\x00\x0a\xd4tp\x00\x00\x00\x00\x0b\xbb\x1c\xe0\x00\x00\x00\x00\x0c\xab\x1b\xf0\x00\x00\x00\x00\x0d\xa49`\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\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\xff\xff\xfc\x8c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\x09\x00\x00\x1c \x01\x0d\x00\x00\x1c \x01\x12\x00\x00\x0e\x10\x00\x17LMT\x00WEST\x00WET\x00WEMT\x00CEST\x00CET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\xa5J[\xa0\x03\x00\x00\xa0\x03\x00\x00\x0c\x00\x00\x00Europe/MaltaTZif2\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\x00V\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xffp\xbd\xd3d\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\x5c7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x90\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6\xeb\x80\x90\xff\xff\xff\xff\xd8\x09\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00\xc5\xb2\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06\x1a3p\x00\x00\x00\x00\x07\x0a$p\x00\x00\x00\x00\x08\x17\x16p\x00\x00\x00\x00\x08\xda4p\x00\x00\x00\x00\x09\xf7\x14\x90\x00\x00\x00\x00\x0a\xc2\x0d\x80\x00\x00\x00\x00\x0b\xd6\xf6\x90\x00\x00\x00\x00\x0c\xa1\xef\x80\x00\x00\x00\x00\x0d\xb6\xd8\x90\x00\x00\x00\x00\x0e\x81\xd1\x80\x00\x00\x00\x00\x0f\x96\xba\x90\x00\x00\x00\x00\x10a\xb3\x80\x00\x00\x00\x00\x11v\x9c\x90\x00\x00\x00\x00\x12A\x95\x80\x00\x00\x00\x00\x13E[\x10\x00\x00\x00\x00\x14*\xb2\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\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\x0d\x9c\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\x09LMT\x00CEST\x00CET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x10\x00\x00\x00Europe/MariehamnTZif2\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\x11\xff\xff\xff\xffS\xba&\x9b\xff\xff\xff\xff\xa4so\x1b\xff\xff\xff\xff\xcb\xceQ`\xff\xff\xff\xff\xcc\xc0\xe5`\x00\x00\x00\x00\x15#\xdd\x80\x00\x00\x00\x00\x16\x13\xce\x80\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x17e\x00\x00\x00\x00\x17e\x00\x04\x00\x00*0\x01\x08\x00\x00\x1c \x00\x0dLMT\x00HMT\x00EEST\x00EET\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00WI\xc3\x7f(\x03\x00\x00(\x03\x00\x00\x0c\x00\x00\x00Europe/MinskTZif2\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\x00D\x00\x00\x00\x09\x00\x00\x00&\xff\xff\xff\xffV\xb6\xca(\xff\xff\xff\xff\xaa\x19\xaa8\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca^p\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x0a\x02`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\x08\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4\xdb\x80\x00\x00\x00\x00-\x94\xcc\x80\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062j\x00\x00\x00\x00\x006\xfdq\x00\x00\x00\x00\x008\x1b\x86\x80\x00\x00\x00\x008\xddS\x00\x00\x00\x00\x009\xfbh\x80\x00\x00\x00\x00:\xbd5\x00\x00\x00\x00\x00;\xdbJ\x80\x00\x00\x00\x00<\xa6Q\x80\x00\x00\x00\x00=\xbb,\x80\x00\x00\x00\x00>\x863\x80\x00\x00\x00\x00?\x9b\x0e\x80\x00\x00\x00\x00@f\x15\x80\x00\x00\x00\x00A\x84+\x00\x00\x00\x00\x00BE\xf7\x80\x00\x00\x00\x00Cd\x0d\x00\x00\x00\x00\x00D%\xd9\x80\x00\x00\x00\x00EC\xef\x00\x00\x00\x00\x00F\x05\xbb\x80\x00\x00\x00\x00G#\xd1\x00\x00\x00\x00\x00G\xee\xd8\x00\x00\x00\x00\x00I\x03\xb3\x00\x00\x00\x00\x00I\xce\xba\x00\x00\x00\x00\x00J\xe3\x95\x00\x00\x00\x00\x00K\xae\x9c\x00\x00\x00\x00\x00L\xcc\xb1\x80\x00\x00\x00\x00M\x8e~\x00\x01\x02\x03\x05\x04\x05\x04\x05\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x08\x00\x00\x19\xd8\x00\x00\x00\x00\x19\xc8\x00\x04\x00\x00\x1c \x00\x08\x00\x00*0\x00\x0c\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x00*0\x00\x22LMT\x00MMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00+03\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\x0d\x00\x00\x00Europe/MonacoTZif2\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\x00e\x00\x00\x00\x07\x00\x00\x00\x1f\xff\xff\xff\xffk\xc9\x9b\xcf\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\x0c\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8X&p\xff\xff\xff\xff\xa9\x07}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xad\xc9\xa7\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\x22p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb5I/\xf0\xff\xff\xff\xff\xb6/\xe6p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xba\xd6`\xf0\xff\xff\xff\xff\xbb\xd8\xc6\xf0\xff\xff\xff\xff\xbc\xc8\xb7\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xc8l'\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0O\xe1\xe0\xff\xff\xff\xff\xd0\x89\xf1\xf0\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x0b\xbb9\x00\x00\x00\x00\x00\x0c\xab\x1b\xf0\x00\x00\x00\x00\x0d\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x06\x02\x06\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\x00\x00\x021\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\x08\x00\x00\x00\x00\x00\x0d\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15\x00\x00\x1c \x01\x1aLMT\x00PMT\x00WEST\x00WET\x00CET\x00CEST\x00WEMT\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\x0d\x00\x00\x00Europe/MoscowTZif2\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\x00N\x00\x00\x00\x0b\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc0\xc7\xff\xff\xff\xff\x9b_\x1e\xc7\xff\xff\xff\xff\x9d>\xf2y\xff\xff\xff\xff\x9e*\xee\xf9\xff\xff\xff\xff\x9e\xf79i\xff\xff\xff\xff\x9f\x84W\xf9\xff\xff\xff\xff\xa0\xd8l\xe9\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xa1<\xa6@\xff\xff\xff\xff\xa4\x10m\xc0\xff\xff\xff\xff\xa4=2\xb0\xff\xff\xff\xff\xa5\x15h\xb0\xff\xff\xff\xff\xa5=\x03\xc0\xff\xff\xff\xff\xa7\x1eEP\xff\xff\xff\xff\xb5\xa4\x19`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\x07p\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00I\xce\xab\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00L\xcc\xa3p\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x01\x03\x02\x03\x04\x02\x04\x05\x06\x05\x07\x05\x06\x08\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x09\x08\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x0a\x06\x00\x00#9\x00\x00\x00\x00#9\x00\x04\x00\x001\x87\x01\x08\x00\x00#w\x00\x04\x00\x00?\x97\x01\x0c\x00\x008@\x01\x11\x00\x00*0\x00\x15\x00\x00FP\x01\x19\x00\x00\x1c \x00\x1d\x00\x00*0\x01!\x00\x008@\x00\x15LMT\x00MMT\x00MST\x00MDST\x00MSD\x00MSK\x00+05\x00EET\x00EEST\x00\x0aMSK-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\x0e\x00\x00\x00Europe/NicosiaTZif2\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\x001\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xff\xa5w\x1e\xb8\x00\x00\x00\x00\x09\xed\xaf\xe0\x00\x00\x00\x00\x0a\xdd\x92\xd0\x00\x00\x00\x00\x0b\xfad\xe0\x00\x00\x00\x00\x0c\xbe\xc6P\x00\x00\x00\x00\x0d\xa49`\x00\x00\x00\x00\x0e\x8a\xe1\xd0\x00\x00\x00\x00\x0f\x84\x1b`\x00\x00\x00\x00\x10uO\xd0\x00\x00\x00\x00\x11c\xfd`\x00\x00\x00\x00\x12S\xe0P\x00\x00\x00\x00\x13M\x19\xe0\x00\x00\x00\x00\x143\xc2P\x00\x00\x00\x00\x15#\xc1`\x00\x00\x00\x00\x16\x13\xa4P\x00\x00\x00\x00\x17\x03\xa3`\x00\x00\x00\x00\x17\xf3\x86P\x00\x00\x00\x00\x18\xe3\x85`\x00\x00\x00\x00\x19\xd3hP\x00\x00\x00\x00\x1a\xc3g`\x00\x00\x00\x00\x1b\xbc\x84\xd0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9cf\xd0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|H\xd0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c*\xd0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<\x0c\xd0\x00\x00\x00\x00$,\x0b\xe0\x00\x00\x00\x00%\x1b\xee\xd0\x00\x00\x00\x00&\x0b\xed\xe0\x00\x00\x00\x00'\x05\x0bP\x00\x00\x00\x00'\xf5\x0a`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002M\x91\xd0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004-s\xd0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062x\x10\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\x00\x00\x1fH\x00\x00\x00\x00*0\x01\x04\x00\x00\x1c \x00\x09LMT\x00EEST\x00EET\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x0b\x00\x00\x00Europe/OsloTZif2\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\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x09q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xb6\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xff\xd2\xa1O\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\xd5\xa8s\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\x09\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\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\x0c\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\x09\x00\x00*0\x01\x0dLMT\x00CEST\x00CET\x00CEMT\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\x0c\x00\x00\x00Europe/ParisTZif2\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\x00e\x00\x00\x00\x07\x00\x00\x00\x1f\xff\xff\xff\xffk\xc9\x9b\xcf\xff\xff\xff\xff\x91`PO\xff\xff\xff\xff\x9bGx\xf0\xff\xff\xff\xff\x9b\xd7,p\xff\xff\xff\xff\x9c\xbc\x91p\xff\xff\xff\xff\x9d\xc0H\xf0\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0*\xf0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1\x80\x0c\xf0\xff\xff\xff\xff\xa2.\x12\xf0\xff\xff\xff\xff\xa3zL\xf0\xff\xff\xff\xff\xa45\x81\xf0\xff\xff\xff\xff\xa5^#p\xff\xff\xff\xff\xa6%5\xf0\xff\xff\xff\xff\xa7'\x9b\xf0\xff\xff\xff\xff\xa8X&p\xff\xff\xff\xff\xa9\x07}\xf0\xff\xff\xff\xff\xa9\xee4p\xff\xff\xff\xff\xaa\xe7_\xf0\xff\xff\xff\xff\xab\xd7P\xf0\xff\xff\xff\xff\xac\xc7A\xf0\xff\xff\xff\xff\xad\xc9\xa7\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\x22p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb5I/\xf0\xff\xff\xff\xff\xb6/\xe6p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xba\xd6`\xf0\xff\xff\xff\xff\xbb\xd8\xc6\xf0\xff\xff\xff\xff\xbc\xc8\xb7\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xc8l'\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0O\xe1\xe0\xff\xff\xff\xff\xd0\x89\xf1\xf0\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x0b\xbb9\x00\x00\x00\x00\x00\x0c\xab\x1b\xf0\x00\x00\x00\x00\x0d\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x05\x04\x05\x04\x05\x06\x02\x06\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\x00\x00\x021\x00\x00\x00\x00\x021\x00\x04\x00\x00\x0e\x10\x01\x08\x00\x00\x00\x00\x00\x0d\x00\x00\x0e\x10\x00\x11\x00\x00\x1c \x01\x15\x00\x00\x1c \x01\x1aLMT\x00PMT\x00WEST\x00WET\x00CET\x00CEST\x00WEMT\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x00\x00Europe/PodgoricaTZif2\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\x03\x00\x00\x00\x0d\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1\xa1\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\x08LMT\x00CET\x00CEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Io\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\x0d\x00\x00\x00Europe/PragueTZif2\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\x05\x00\x00\x00\x15\xff\xff\xff\xff\x1eI\x92\xf8\xff\xff\xff\xffl\xcf\xea\xf8\xff\xff\xff\xff\x9b\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x09q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2b\x07\x10\xff\xff\xff\xff\xd3\x80\x1c\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd4\x93\xb4 \xff\xff\xff\xff\xd5\x02r \xff\xff\xff\xff\xd5L8\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\x09\x96\x10\xff\xff\xff\xff\xd9\x01p\x10\xff\xff\xff\xff\xd9\xe9x\x10\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x0d\x88\x00\x00\x00\x00\x0d\x88\x00\x04\x00\x00\x1c \x01\x08\x00\x00\x0e\x10\x00\x0d\x00\x00\x00\x00\x01\x11LMT\x00PMT\x00CEST\x00CET\x00GMT\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00gp\xc0\xa7\xb6\x02\x00\x00\xb6\x02\x00\x00\x0b\x00\x00\x00Europe/RigaTZif2\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\x005\x00\x00\x00\x09\x00\x00\x00&\xff\xff\xff\xffV\xb6\xcd^\xff\xff\xff\xff\x9e\xb9\x87\xfe\xff\xff\xff\xff\x9f\x84\x8e\xfe\xff\xff\xff\xff\xa0\x88F~\xff\xff\xff\xff\xa0\xcb\x82\xfe\xff\xff\xff\xff\xad\xe7\xf1\xde\xff\xff\xff\xff\xc8\xafd`\xff\xff\xff\xff\xcabeP\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd0\x90\x89p\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\x0c\x0a\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\x08\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4\xdb\x80\x00\x00\x00\x00-\x94\xcc\x80\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002M\xbc\x00\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00:\xbdC\x10\x01\x02\x01\x02\x01\x03\x04\x06\x05\x06\x05\x06\x05\x04\x07\x04\x07\x04\x07\x04\x07\x04\x07\x04\x07\x04\x07\x04\x07\x04\x08\x03\x08\x03\x08\x03\x08\x03\x08\x03\x08\x03\x08\x03\x08\x03\x08\x03\x08\x03\x08\x03\x08\x00\x00\x16\xa2\x00\x00\x00\x00\x16\xa2\x00\x04\x00\x00$\xb2\x01\x08\x00\x00\x1c \x00\x0c\x00\x00*0\x00\x10\x00\x00\x0e\x10\x00\x14\x00\x00\x1c \x01\x18\x00\x008@\x01\x1d\x00\x00*0\x01!LMT\x00RMT\x00LST\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x0b\x00\x00\x00Europe/RomeTZif2\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\x00W\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\x5c7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6\xeb\x80\x90\xff\xff\xff\xff\xd8\x09\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00\xc5\xb2\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\x07\x0bu\xf0\x00\x00\x00\x00\x08E:\xf0\x00\x00\x00\x00\x08\xebW\xf0\x00\x00\x00\x00\x0a.Wp\x00\x00\x00\x00\x0a\xcb9\xf0\x00\x00\x00\x00\x0c\x0e9p\x00\x00\x00\x00\x0c\xab\x1b\xf0\x00\x00\x00\x00\x0d\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x0b\xb4\x00\x00\x00\x00\x0b\xb4\x00\x04\x00\x00\x1c \x01\x08\x00\x00\x0e\x10\x00\x0dLMT\x00RMT\x00CEST\x00CET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\x7fpp\xdc\x02\x00\x00\xdc\x02\x00\x00\x0d\x00\x00\x00Europe/SamaraTZif2\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\x06\x00\x00\x00\x10\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\x0bP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\x08\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a\xcc\x85\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c8\xe0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\x0b\xe0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\x00\xc7\x00\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xdd`\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xbf`\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\xa1`\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000d\x83`\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r\x89\xe0\x00\x00\x00\x003=\x90\xe0\x00\x00\x00\x004Rk\xe0\x00\x00\x00\x005\x1dr\xe0\x00\x00\x00\x0062M\xe0\x00\x00\x00\x006\xfdT\xe0\x00\x00\x00\x008\x1bj`\x00\x00\x00\x008\xdd6\xe0\x00\x00\x00\x009\xfbL`\x00\x00\x00\x00:\xbd\x18\xe0\x00\x00\x00\x00;\xdb.`\x00\x00\x00\x00<\xa65`\x00\x00\x00\x00=\xbb\x10`\x00\x00\x00\x00>\x86\x17`\x00\x00\x00\x00?\x9a\xf2`\x00\x00\x00\x00@e\xf9`\x00\x00\x00\x00A\x84\x0e\xe0\x00\x00\x00\x00BE\xdb`\x00\x00\x00\x00Cc\xf0\xe0\x00\x00\x00\x00D%\xbd`\x00\x00\x00\x00EC\xd2\xe0\x00\x00\x00\x00F\x05\x9f`\x00\x00\x00\x00G#\xb4\xe0\x00\x00\x00\x00G\xee\xbb\xe0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00I\xce\x9d\xe0\x00\x00\x00\x00J\xe3x\xe0\x00\x00\x00\x00K\xae\x7f\xe0\x00\x00\x00\x00L\xcc\xa3p\x00\x00\x00\x00M\x8eo\xf0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x04\x01\x05\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x01\x02\x00\x00.\xf4\x00\x00\x00\x00*0\x00\x04\x00\x008@\x00\x08\x00\x00FP\x01\x0c\x00\x008@\x01\x08\x00\x00*0\x01\x04LMT\x00+03\x00+04\x00+05\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x11\x00\x00\x00Europe/San_MarinoTZif2\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\x00W\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\x5c7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6\xeb\x80\x90\xff\xff\xff\xff\xd8\x09\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00\xc5\xb2\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\x07\x0bu\xf0\x00\x00\x00\x00\x08E:\xf0\x00\x00\x00\x00\x08\xebW\xf0\x00\x00\x00\x00\x0a.Wp\x00\x00\x00\x00\x0a\xcb9\xf0\x00\x00\x00\x00\x0c\x0e9p\x00\x00\x00\x00\x0c\xab\x1b\xf0\x00\x00\x00\x00\x0d\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x0b\xb4\x00\x00\x00\x00\x0b\xb4\x00\x04\x00\x00\x1c \x01\x08\x00\x00\x0e\x10\x00\x0dLMT\x00RMT\x00CEST\x00CET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00Europe/SarajevoTZif2\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\x03\x00\x00\x00\x0d\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1\xa1\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\x08LMT\x00CET\x00CEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b8\xfel\xd6\x02\x00\x00\xd6\x02\x00\x00\x0e\x00\x00\x00Europe/SaratovTZif2\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\x05\x00\x00\x00\x10\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\x0bP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\x08\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a\xcc\x85\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c8\xe0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\x07p\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00I\xce\xab\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00L\xcc\xa3p\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00XCNp\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x04\x01\x03\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00+2\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\x08\x00\x008@\x00\x0c\x00\x008@\x01\x0cLMT\x00+03\x00+05\x00+04\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\xb4N\xb8a\x03\x00\x00a\x03\x00\x00\x11\x00\x00\x00Europe/SimferopolTZif2\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\x00K\x00\x00\x00\x09\x00\x00\x00\x22\xff\xff\xff\xffV\xb6\xc4\x08\xff\xff\xff\xff\xaa\x19\xa4 \xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xcb\x04\x8d\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xcf\x9f8\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x8d.\xf0\x00\x00\x00\x00)\xd5\x08\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4\xdb\x80\x00\x00\x00\x00-\x94\xcc\x80\x00\x00\x00\x00-\xc2\xc6\xd0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xa0\xd0\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xbb\x10\x00\x00\x00\x004R\x96\x10\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x008\xdda\x10\x00\x00\x00\x009\xfbv\x90\x00\x00\x00\x00:\xbdC\x10\x00\x00\x00\x00;\xdbX\x90\x00\x00\x00\x00<\xa6_\x90\x00\x00\x00\x00=\xbb:\x90\x00\x00\x00\x00>\x86A\x90\x00\x00\x00\x00?\x9b\x1c\x90\x00\x00\x00\x00@f#\x90\x00\x00\x00\x00A\x849\x10\x00\x00\x00\x00BF\x05\x90\x00\x00\x00\x00Cd\x1b\x10\x00\x00\x00\x00D%\xe7\x90\x00\x00\x00\x00EC\xfd\x10\x00\x00\x00\x00F\x05\xc9\x90\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L\xcc\xbf\x90\x00\x00\x00\x00M\x8e\x8c\x10\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S7^\x80\x00\x00\x00\x00TL\x1d`\x01\x02\x03\x05\x04\x05\x04\x05\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x02\x07\x02\x07\x02\x07\x06\x03\x06\x03\x06\x03\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x08\x03\x00\x00\x1f\xf8\x00\x00\x00\x00\x1f\xe0\x00\x04\x00\x00\x1c \x00\x08\x00\x00*0\x00\x0c\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1d\x00\x008@\x00\x0cLMT\x00SMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\x0aMSK-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0d\x00\x00\x00Europe/SkopjeTZif2\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\x03\x00\x00\x00\x0d\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1\xa1\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\x08LMT\x00CET\x00CEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xc8\x15\xd0P\x02\x00\x00P\x02\x00\x00\x0c\x00\x00\x00Europe/SofiaTZif2\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\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xce$\xff\xff\xff\xffr\xc3\xe3\x18\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r$ \x00\x00\x00\x00\x11c\xefP\x00\x00\x00\x00\x12U?\xe0\x00\x00\x00\x00\x13M\x0b\xd0\x00\x00\x00\x00\x145!\xe0\x00\x00\x00\x00\x15,\xed\xd0\x00\x00\x00\x00\x16\x13\xc0p\x00\x00\x00\x00\x17\x0c\xcf\xd0\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18\xe3\xa1\x80\x00\x00\x00\x00\x19\xd3\x92\x80\x00\x00\x00\x00\x1a\xc3\x83\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\x5cU\x00\x00\x00\x00\x00\x22LF\x00\x00\x00\x00\x00#<7\x00\x00\x00\x00\x00$,(\x00\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\x0c\x0a\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5\x0a`\x00\x00\x00\x00(\xe4\xedP\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xbb\x10\x01\x02\x03\x04\x03\x04\x03\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x00\x00\x15\xdc\x00\x00\x00\x00\x1bh\x00\x04\x00\x00\x1c \x00\x08\x00\x00\x0e\x10\x00\x0c\x00\x00\x1c \x01\x10\x00\x00*0\x01\x15LMT\x00IMT\x00EET\x00CET\x00CEST\x00EEST\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x10\x00\x00\x00Europe/StockholmTZif2\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\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x09q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xb6\x96\x00\xff\xff\xff\xff\xd2X\xbe\x80\xff\xff\xff\xff\xd2\xa1O\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\xd5\xa8s\x00\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\x09\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x03\x01\x02\x01\x02\x01\x03\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\x0c\x88\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\x09\x00\x00*0\x01\x0dLMT\x00CEST\x00CET\x00CEMT\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\x16\x9b?\xa3\x02\x00\x00\xa3\x02\x00\x00\x0e\x00\x00\x00Europe/TallinnTZif2\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\x004\x00\x00\x00\x08\x00\x00\x00\x22\xff\xff\xff\xffV\xb6\xcc\xcc\xff\xff\xff\xff\x9eY-\xcc\xff\xff\xff\xff\x9e\xb9\x90\x90\xff\xff\xff\xff\x9f\x84\x97\x90\xff\xff\xff\xff\xa1\x00+p\xff\xff\xff\xff\xa4soL\xff\xff\xff\xff\xc8\xb0\xb5\xe0\xff\xff\xff\xff\xca\xc6\x97P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0t\xcb\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\x0c\x0a\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\x08\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4\xdb\x80\x00\x00\x00\x00-\x94\xcc\x80\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x8f\x00\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00<\xa6_\x90\x01\x03\x02\x03\x01\x04\x05\x02\x03\x02\x03\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x07\x04\x07\x04\x07\x04\x07\x04\x07\x04\x07\x04\x07\x04\x07\x04\x07\x04\x07\x04\x07\x04\x07\x00\x00\x174\x00\x00\x00\x00\x174\x00\x04\x00\x00\x1c \x01\x08\x00\x00\x0e\x10\x00\x0d\x00\x00\x1c \x00\x11\x00\x00*0\x00\x15\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00TMT\x00CEST\x00CET\x00EET\x00MSK\x00MSD\x00EEST\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\xc48\xde\x5c\x02\x00\x00\x5c\x02\x00\x00\x0d\x00\x00\x00Europe/TiraneTZif2\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\x002\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xff\x96\xaa4h\xff\xff\xff\xff\xc8m\x87p\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xcd\xb8\xe9\x90\x00\x00\x00\x00\x08(9\xf0\x00\x00\x00\x00\x08\xef>`\x00\x00\x00\x00\x0a\x05x\xf0\x00\x00\x00\x00\x0a\xd0q\xe0\x00\x00\x00\x00\x0b\xe9Op\x00\x00\x00\x00\x0c\xb4H`\x00\x00\x00\x00\x0d\xd2k\xf0\x00\x00\x00\x00\x0e\x94*`\x00\x00\x00\x00\x0f\xb0\xfcp\x00\x00\x00\x00\x10t\x0c`\x00\x00\x00\x00\x11\x90\xdep\x00\x00\x00\x00\x12S\xee`\x00\x00\x00\x00\x13p\xc0p\x00\x00\x00\x00\x14;\xb9`\x00\x00\x00\x00\x15H\xb9p\x00\x00\x00\x00\x16\x13\xb2`\x00\x00\x00\x00\x171\xd5\xf0\x00\x00\x00\x00\x17\xfc\xce\xe0\x00\x00\x00\x00\x19\x00\x94p\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a\xcc\xaf\xf0\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x02\x00\x00\x12\x98\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\x08LMT\x00CET\x00CEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x00\x00Europe/TiraspolTZif2\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\x09\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc8\xf8\xff\xff\xff\xff\x9ek\x9f\x0c\xff\xff\xff\xff\xb7\xb0\xd2\x08\xff\xff\xff\xff\xb9>\xf3`\xff\xff\xff\xff\xb9\xef\x9c`\xff\xff\xff\xff\xba\xdf\x8d`\xff\xff\xff\xff\xbb\xcf~`\xff\xff\xff\xff\xbc\xc8\xa9\xe0\xff\xff\xff\xff\xbd\xb8\x9a\xe0\xff\xff\xff\xff\xbe\xa8\x8b\xe0\xff\xff\xff\xff\xbf\x98|\xe0\xff\xff\xff\xff\xc0\x88m\xe0\xff\xff\xff\xff\xc1x^\xe0\xff\xff\xff\xff\xc2hO\xe0\xff\xff\xff\xff\xc3X@\xe0\xff\xff\xff\xff\xc4H1\xe0\xff\xff\xff\xff\xc58\x22\xe0\xff\xff\xff\xff\xc6(\x13\xe0\xff\xff\xff\xff\xc7\x18\x04\xe0\xff\xff\xff\xff\xc8\xbc\x93`\xff\xff\xff\xff\xcaw}P\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0N\x90`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00&CL\xe0\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xcfP\x00\x00\x00\x00+\xb4\xce`\x00\x00\x00\x00,\xa4\xb1P\x00\x00\x00\x00-\x94\xb0`\x00\x00\x00\x00.\x84\x93P\x00\x00\x00\x00/t\x92`\x00\x00\x00\x000duP\x00\x00\x00\x001]\xae\xe0\x00\x00\x00\x002r{\xd0\x00\x00\x00\x003=\xad\x00\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x06\x05\x06\x05\x06\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x08\x07\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x04\x03\x00\x00\x1b\x08\x00\x00\x00\x00\x1a\xf4\x00\x04\x00\x00\x18x\x00\x08\x00\x00*0\x01\x0c\x00\x00\x1c \x00\x11\x00\x00\x0e\x10\x00\x15\x00\x00\x1c \x01\x19\x00\x008@\x01\x1e\x00\x00*0\x00\x22LMT\x00CMT\x00BMT\x00EEST\x00EET\x00CET\x00CEST\x00MSD\x00MSK\x00\x0aEET-2EEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u\xb0\xcd\xfc\xf8\x02\x00\x00\xf8\x02\x00\x00\x10\x00\x00\x00Europe/UlyanovskTZif2\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\x00B\x00\x00\x00\x07\x00\x00\x00\x14\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xb5\xa4\x0bP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\x08\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a\xcc\x85\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c8\xe0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<\x1a\xe0\x00\x00\x00\x00$,\x0b\xe0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\x07p\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00I\xce\xab\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00L\xcc\xa3p\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00V\xf7\x14p\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x01\x04\x01\x05\x06\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x04\x01\x03\x01\x03\x00\x00-`\x00\x00\x00\x00*0\x00\x04\x00\x00FP\x01\x08\x00\x008@\x00\x0c\x00\x008@\x01\x0c\x00\x00*0\x01\x04\x00\x00\x1c \x00\x10LMT\x00+03\x00+05\x00+04\x00+02\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x0f\x00\x00\x00Europe/UzhgorodTZif2\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\x08\x00\x00\x00\x22\xff\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xce\xcd\xa8p\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\x08\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4\xdb\x80\x00\x00\x00\x00-\x94\xcc\x80\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c\x9c\x00\x04\x00\x00\x1c \x00\x08\x00\x00*0\x00\x0c\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00KMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\x0c\x00\x00\x00Europe/VaduzTZif2\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\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x08\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\x08\x00\x00\x0e\x10\x00\x0dLMT\x00BMT\x00CEST\x00CET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x0e\x00\x00\x00Europe/VaticanTZif2\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\x00W\x00\x00\x00\x04\x00\x00\x00\x11\xff\xff\xff\xff>(\xe8L\xff\xff\xff\xffp\xbc\x81p\xff\xff\xff\xff\x9b8\xf8p\xff\xff\xff\xff\x9b\xd5\xcc\xe0\xff\xff\xff\xff\x9c\xc5\xcb\xf0\xff\xff\xff\xff\x9d\xb7\x00`\xff\xff\xff\xff\x9e\x89\xfep\xff\xff\xff\xff\x9f\xa0\x1c\xe0\xff\xff\xff\xff\xa0`\xa5\xf0\xff\xff\xff\xff\xa1~\xad`\xff\xff\xff\xff\xa2\x5c7p\xff\xff\xff\xff\xa3L\x1a`\xff\xff\xff\xff\xc8l5\xf0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2L\xd2\xf0\xff\xff\xff\xff\xd3>1\x90\xff\xff\xff\xff\xd4I\xd2\x10\xff\xff\xff\xff\xd5\x1d\xf7p\xff\xff\xff\xff\xd6)\x97\xf0\xff\xff\xff\xff\xd6\xeb\x80\x90\xff\xff\xff\xff\xd8\x09\x96\x10\xff\xff\xff\xff\xf93\xb5\xf0\xff\xff\xff\xff\xf9\xd9\xc4\xe0\xff\xff\xff\xff\xfb\x1c\xd2p\xff\xff\xff\xff\xfb\xb9\xb4\xf0\xff\xff\xff\xff\xfc\xfc\xb4p\xff\xff\xff\xff\xfd\x99\x96\xf0\xff\xff\xff\xff\xfe\xe5\xd0\xf0\xff\xff\xff\xff\xff\x82\xb3p\x00\x00\x00\x00\x00\xc5\xb2\xf0\x00\x00\x00\x00\x01b\x95p\x00\x00\x00\x00\x02\x9cZp\x00\x00\x00\x00\x03Bwp\x00\x00\x00\x00\x04\x85v\xf0\x00\x00\x00\x00\x05+\x93\xf0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\x07\x0bu\xf0\x00\x00\x00\x00\x08E:\xf0\x00\x00\x00\x00\x08\xebW\xf0\x00\x00\x00\x00\x0a.Wp\x00\x00\x00\x00\x0a\xcb9\xf0\x00\x00\x00\x00\x0c\x0e9p\x00\x00\x00\x00\x0c\xab\x1b\xf0\x00\x00\x00\x00\x0d\xe4\xe0\xf0\x00\x00\x00\x00\x0e\x8a\xfd\xf0\x00\x00\x00\x00\x0f\xcd\xfdp\x00\x00\x00\x00\x10t\x1ap\x00\x00\x00\x00\x11\xad\xdfp\x00\x00\x00\x00\x12S\xfcp\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x0b\xb4\x00\x00\x00\x00\x0b\xb4\x00\x04\x00\x00\x1c \x01\x08\x00\x00\x0e\x10\x00\x0dLMT\x00RMT\x00CEST\x00CET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x05w\xd7\x92\x02\x00\x00\x92\x02\x00\x00\x0d\x00\x00\x00Europe/ViennaTZif2\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\x008\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xffo\xa2_/\xff\xff\xff\xff\x9b\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\xa2p\x1a\x10\xff\xff\xff\xff\xa3D[\x90\xff\xff\xff\xff\xc8\x09q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\x7fE\x10\xff\xff\xff\xff\xd3c\x1b\x90\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd59\xc3\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\x09\x96\x10\x00\x00\x00\x00\x13M'\xf0\x00\x00\x00\x00\x143\xd0`\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x02\x01\x02\x01\x02\x01\x00\x00\x0fQ\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\x09LMT\x00CEST\x00CET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xccb\xf72\xa4\x02\x00\x00\xa4\x02\x00\x00\x0e\x00\x00\x00Europe/VilniusTZif2\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\x003\x00\x00\x00\x09\x00\x00\x00&\xff\xff\xff\xffV\xb6\xccD\xff\xff\xff\xff\x9cO\x1fP\xff\xff\xff\xff\xa1\x85J\x98\xff\xff\xff\xff\xa2\xf10\xf0\xff\xff\xff\xff\xa3fx`\xff\xff\xff\xff\xc8\xac\xcfp\xff\xff\xff\xff\xcaY*\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd00=\xe0\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x19\x00\x00\x00\x00\x00&\x0c\x0a\x00\x00\x00\x00\x00'\x055\x80\x00\x00\x00\x00'\xf5&\x80\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\x08\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4\xdb\x80\x00\x00\x00\x00-\x94\xcc\x80\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xa6\x00\x00\x00\x00\x003=\xad\x00\x00\x00\x00\x004R\x88\x00\x00\x00\x00\x005\x1d\x9d\x10\x00\x00\x00\x0062x\x10\x00\x00\x00\x006\xfd\x7f\x10\x00\x00\x00\x008\x1b\x94\x90\x00\x00\x00\x00>\x86A\x90\x01\x02\x03\x04\x03\x05\x06\x03\x06\x03\x06\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x07\x05\x08\x04\x08\x04\x08\x04\x08\x04\x08\x04\x08\x04\x08\x04\x08\x04\x08\x04\x06\x03\x06\x04\x08\x00\x00\x17\xbc\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x16h\x00\x08\x00\x00\x0e\x10\x00\x0c\x00\x00\x1c \x00\x10\x00\x00*0\x00\x14\x00\x00\x1c \x01\x18\x00\x008@\x01\x1d\x00\x00*0\x01!LMT\x00WMT\x00KMT\x00CET\x00EET\x00MSK\x00CEST\x00MSD\x00EEST\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xec\xa0%\xf1\x02\x00\x00\xf1\x02\x00\x00\x10\x00\x00\x00Europe/VolgogradTZif2\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\x00A\x00\x00\x00\x07\x00\x00\x00\x18\xff\xff\xff\xff\xa1\xf5F\xdc\xff\xff\xff\xff\xb5\xa4\x0bP\x00\x00\x00\x00\x15'\x99\xc0\x00\x00\x00\x00\x16\x18\xce0\x00\x00\x00\x00\x17\x08\xcd@\x00\x00\x00\x00\x17\xfa\x01\xb0\x00\x00\x00\x00\x18\xea\x00\xc0\x00\x00\x00\x00\x19\xdb50\x00\x00\x00\x00\x1a\xcc\x85\xc0\x00\x00\x00\x00\x1b\xbc\x92\xe0\x00\x00\x00\x00\x1c\xac\x83\xe0\x00\x00\x00\x00\x1d\x9ct\xe0\x00\x00\x00\x00\x1e\x8ce\xe0\x00\x00\x00\x00\x1f|V\xe0\x00\x00\x00\x00 lG\xe0\x00\x00\x00\x00!\x5c8\xe0\x00\x00\x00\x00\x22L)\xe0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00)\xd4\xec`\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\x07p\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00I\xce\xab\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00L\xcc\xa3p\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x00\x00\x00\x00[\xd4\xed\xf0\x00\x00\x00\x00_\xe7\xb2`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x05\x04\x05\x02\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\x06\x05\x02\x05\x00\x00)\xa4\x00\x00\x00\x00*0\x00\x04\x00\x008@\x00\x08\x00\x00FP\x01\x0c\x00\x008@\x01\x10\x00\x00*0\x00\x14\x00\x008@\x00\x14LMT\x00+03\x00+04\x00+05\x00MSD\x00MSK\x00\x0aMSK-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xfe\xe5\x9e\x9b\x03\x00\x00\x9b\x03\x00\x00\x0d\x00\x00\x00Europe/WarsawTZif2\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\x00R\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xd0P\xff\xff\xff\xff\x99\xa8*\xd0\xff\xff\xff\xff\x9b\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\xa0\x9a\xb6\x00\xff\xff\xff\xff\xa1e\xbd\x00\xff\xff\xff\xff\xa6}|`\xff\xff\xff\xff\xc8v\xde\x10\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x84\xba\x00\xff\xff\xff\xff\xd1\x95\x92p\xff\xff\xff\xff\xd2\x8a\xbb`\xff\xff\xff\xff\xd3b\xffp\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd5^\xad\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\x09\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff\xe8T\xd2\x00\xff\xff\xff\xff\xe8\xf1\xb4\x80\xff\xff\xff\xff\xe9\xe1\xa5\x80\xff\xff\xff\xff\xea\xd1\x96\x80\xff\xff\xff\xff\xec\x14\x96\x00\xff\xff\xff\xff\xec\xba\xb3\x00\xff\xff\xff\xff\xed\xaa\xa4\x00\xff\xff\xff\xff\xee\x9a\x95\x00\xff\xff\xff\xff\xef\xd4Z\x00\xff\xff\xff\xff\xf0zw\x00\xff\xff\xff\xff\xf1\xb4<\x00\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3\x94\x1e\x00\xff\xff\xff\xff\xf4:;\x00\xff\xff\xff\xff\xf5}:\x80\xff\xff\xff\xff\xf6\x1a\x1d\x00\x00\x00\x00\x00\x0d\xa4U\x80\x00\x00\x00\x00\x0e\x8b\x0c\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x0a\x80\x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xec\x80\x00\x00\x00\x00\x15#\xdd\x80\x00\x00\x00\x00\x16\x13\xce\x80\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18\xe3\xa1\x80\x00\x00\x00\x00\x19\xd3\x92\x80\x00\x00\x00\x00\x1a\xc3\x83\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\x5cU\x00\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x13\xb0\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x1c \x01\x08\x00\x00\x0e\x10\x00\x0d\x00\x00*0\x01\x11\x00\x00\x1c \x00\x16LMT\x00WMT\x00CEST\x00CET\x00EEST\x00EET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0d\x00\x00\x00Europe/ZagrebTZif2\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\x03\x00\x00\x00\x0d\xff\xff\xff\xff^<\xf0H\xff\xff\xff\xff\xca\x025\xe0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1\xa1\x8c\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\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\x00\x00\x138\x00\x00\x00\x00\x0e\x10\x00\x04\x00\x00\x1c \x01\x08LMT\x00CET\x00CEST\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x11\x00\x00\x00Europe/ZaporozhyeTZif2\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\x08\x00\x00\x00\x22\xff\xff\xff\xffV\xb6\xc7d\xff\xff\xff\xff\xaa\x19\xa7d\xff\xff\xff\xff\xb5\xa4\x19`\xff\xff\xff\xff\xca\xcd.\xd0\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xce\xcd\xa8p\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00&\x8d \xe0\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)\xd5\x08\x80\x00\x00\x00\x00*\xc4\xf9\x80\x00\x00\x00\x00+\xb4\xea\x80\x00\x00\x00\x00,\xa4\xdb\x80\x00\x00\x00\x00-\x94\xcc\x80\x00\x00\x00\x00.\x84\xbd\x80\x00\x00\x00\x00/t\xae\x80\x00\x00\x00\x000d\x9f\x80\x00\x00\x00\x001]\xcb\x00\x00\x00\x00\x002r\xb4\x10\x01\x02\x03\x05\x04\x05\x04\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x07\x02\x00\x00\x1c\x9c\x00\x00\x00\x00\x1c\x9c\x00\x04\x00\x00\x1c \x00\x08\x00\x00*0\x00\x0c\x00\x00\x0e\x10\x00\x10\x00\x00\x1c \x01\x14\x00\x008@\x01\x19\x00\x00*0\x01\x1dLMT\x00KMT\x00EET\x00MSK\x00CET\x00CEST\x00MSD\x00EEST\x00\x0aEET-2EEST,M3.5.0/3,M10.5.0/4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\x0d\x00\x00\x00Europe/ZurichTZif2\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\x11\xff\xff\xff\xff$\xf0\xea\x80\xff\xff\xff\xffq\xd4\x06\x86\xff\xff\xff\xff\xca\x17j\x00\xff\xff\xff\xff\xca\xe2q\x00\xff\xff\xff\xff\xcb\xf7L\x00\xff\xff\xff\xff\xcc\xc2S\x00\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x08\x00\x00\x00\x00\x00\x06\xfa\x00\x04\x00\x00\x1c \x01\x08\x00\x00\x0e\x10\x00\x0dLMT\x00BMT\x00CEST\x00CET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x80c$q\x00\x00\x00q\x00\x00\x00\x07\x00\x00\x00FactoryTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00-00\x00\x0a<-00>0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x02\x00\x00\x00GBTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\x09\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \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 \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{\xc8\xa0\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00\xd3\xa0\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \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 \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 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xff\xca\x97Y\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xff\xcd\xb1\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xff\xcf\x90\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde\xb4\xea\xa0\xff\xff\xff\xff\xdf\xae\x16 \xff\xff\xff\xff\xe0\x94\xcc\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \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 \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\x0b \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\xee\x9a\xb1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\x0d\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0\xd1\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \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 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\x09: \x00\x00\x00\x00\x070\x8a \x00\x00\x00\x00\x07\xe9\x1c \x00\x00\x00\x00\x09\x10l \x00\x00\x00\x00\x09\xc8\xfe \x00\x00\x00\x00\x0a\xf0N \x00\x00\x00\x00\x0b\xb2\x1a\xa0\x00\x00\x00\x00\x0c\xd00 \x00\x00\x00\x00\x0d\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \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 lr\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)\x0a\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\x08\x00\x00\x1c \x01\x0c\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\x0aGMT0BST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x07\x00\x00\x00GB-EireTZif2\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\x9f\x00\x00\x00\x05\x00\x00\x00\x11\xff\xff\xff\xff\x1a]\x09\xcb\xff\xff\xff\xff\x9b&\xad\xa0\xff\xff\xff\xff\x9b\xd6\x05 \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 \xff\xff\xff\xff\xa1v\xfc\xa0\xff\xff\xff\xff\xa2e\x9c \xff\xff\xff\xff\xa3{\xc8\xa0\xff\xff\xff\xff\xa4N\xb8\xa0\xff\xff\xff\xff\xa5?\xfb \xff\xff\xff\xff\xa6%` \xff\xff\xff\xff\xa7'\xc6 \xff\xff\xff\xff\xa8*, \xff\xff\xff\xff\xa8\xeb\xf8\xa0\xff\xff\xff\xff\xaa\x00\xd3\xa0\xff\xff\xff\xff\xaa\xd5\x15 \xff\xff\xff\xff\xab\xe9\xf0 \xff\xff\xff\xff\xac\xc7l \xff\xff\xff\xff\xad\xc9\xd2 \xff\xff\xff\xff\xae\xa7N \xff\xff\xff\xff\xaf\xa0y\xa0\xff\xff\xff\xff\xb0\x870 \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 \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 \xff\xff\xff\xff\xbb\xd8\xf1 \xff\xff\xff\xff\xbc\xdbW \xff\xff\xff\xff\xbd\xb8\xd3 \xff\xff\xff\xff\xbe\xb1\xfe\xa0\xff\xff\xff\xff\xbf\x98\xb5 \xff\xff\xff\xff\xc0\x9b\x1b \xff\xff\xff\xff\xc1x\x97 \xff\xff\xff\xff\xc2z\xfd \xff\xff\xff\xff\xc3Xy \xff\xff\xff\xff\xc4Q\xa4\xa0\xff\xff\xff\xff\xc58[ \xff\xff\xff\xff\xc6:\xc1 \xff\xff\xff\xff\xc7X\xd6\xa0\xff\xff\xff\xff\xc7\xda\x09\xa0\xff\xff\xff\xff\xca\x16&\x90\xff\xff\xff\xff\xca\x97Y\x90\xff\xff\xff\xff\xcb\xd1\x1e\x90\xff\xff\xff\xff\xccw;\x90\xff\xff\xff\xff\xcd\xb1\x00\x90\xff\xff\xff\xff\xce`X\x10\xff\xff\xff\xff\xcf\x90\xe2\x90\xff\xff\xff\xff\xd0n^\x90\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd1\xfb2\x10\xff\xff\xff\xff\xd2i\xfe \xff\xff\xff\xff\xd3c)\xa0\xff\xff\xff\xff\xd4I\xe0 \xff\xff\xff\xff\xd5\x1e!\xa0\xff\xff\xff\xff\xd5B\xfd\x90\xff\xff\xff\xff\xd5\xdf\xe0\x10\xff\xff\xff\xff\xd6N\xac \xff\xff\xff\xff\xd6\xfe\x03\xa0\xff\xff\xff\xff\xd8.\x8e \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xda\x0ep \xff\xff\xff\xff\xda\xeb\xec \xff\xff\xff\xff\xdb\xe5\x17\xa0\xff\xff\xff\xff\xdc\xcb\xce \xff\xff\xff\xff\xdd\xc4\xf9\xa0\xff\xff\xff\xff\xde\xb4\xea\xa0\xff\xff\xff\xff\xdf\xae\x16 \xff\xff\xff\xff\xe0\x94\xcc\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2kt \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 \xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x14T\xa0\xff\xff\xff\xff\xe8\xfb\x0b \xff\xff\xff\xff\xe9\xfdq \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xddS \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xb3\xfa\xa0\xff\xff\xff\xff\xee\x9a\xb1 \xff\xff\xff\xff\xef\x81g\xa0\xff\xff\xff\xff\xf0\x9f} \xff\xff\xff\xff\xf1aI\xa0\xff\xff\xff\xff\xf2\x7f_ \xff\xff\xff\xff\xf3Jf \xff\xff\xff\xff\xf4_A \xff\xff\xff\xff\xf5!\x0d\xa0\xff\xff\xff\xff\xf6?# \xff\xff\xff\xff\xf7\x00\xef\xa0\xff\xff\xff\xff\xf8\x1f\x05 \xff\xff\xff\xff\xf8\xe0\xd1\xa0\xff\xff\xff\xff\xf9\xfe\xe7 \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 \x00\x00\x00\x00\x04)X \x00\x00\x00\x00\x05P\xa8 \x00\x00\x00\x00\x06\x09: \x00\x00\x00\x00\x070\x8a \x00\x00\x00\x00\x07\xe9\x1c \x00\x00\x00\x00\x09\x10l \x00\x00\x00\x00\x09\xc8\xfe \x00\x00\x00\x00\x0a\xf0N \x00\x00\x00\x00\x0b\xb2\x1a\xa0\x00\x00\x00\x00\x0c\xd00 \x00\x00\x00\x00\x0d\x91\xfc\xa0\x00\x00\x00\x00\x0e\xb0\x12 \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 lr\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)\x0a\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\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\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x02\x01\x02\x01\x03\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\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\xff\xff\xff\xb5\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\x08\x00\x00\x1c \x01\x0c\x00\x00\x0e\x10\x00\x04LMT\x00BST\x00GMT\x00BDST\x00\x0aGMT0BST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00GMTTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x05\x00\x00\x00GMT+0TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x05\x00\x00\x00GMT-0TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x04\x00\x00\x00GMT0TZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x09\x00\x00\x00GreenwichTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\xf7\xfawp\x00\x00\x00p\x00\x00\x00\x03\x00\x00\x00HSTTZif2\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\x00\x01\x00\x00\x00\x04\xff\xffs`\x00\x00HST\x00\x0aHST10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x09\xfa-\x07\x03\x00\x00\x07\x03\x00\x00\x08\x00\x00\x00HongkongTZif2\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\x00E\x00\x00\x00\x05\x00\x00\x00\x16\xff\xff\xff\xff\x85ic\x90\xff\xff\xff\xff\xcaM10\xff\xff\xff\xff\xca\xdb\x930\xff\xff\xff\xff\xcbKqx\xff\xff\xff\xff\xd2\xa0\xde\x90\xff\xff\xff\xff\xd3k\xd7\x80\xff\xff\xff\xff\xd4\x93X\xb8\xff\xff\xff\xff\xd5B\xb08\xff\xff\xff\xff\xd6s:\xb8\xff\xff\xff\xff\xd7>A\xb8\xff\xff\xff\xff\xd8.2\xb8\xff\xff\xff\xff\xd8\xf99\xb8\xff\xff\xff\xff\xda\x0e\x14\xb8\xff\xff\xff\xff\xda\xd9\x1b\xb8\xff\xff\xff\xff\xdb\xed\xf6\xb8\xff\xff\xff\xff\xdc\xb8\xfd\xb8\xff\xff\xff\xff\xdd\xcd\xd8\xb8\xff\xff\xff\xff\xde\xa2\x1a8\xff\xff\xff\xff\xdf\xb6\xf58\xff\xff\xff\xff\xe0\x81\xfc8\xff\xff\xff\xff\xe1\x96\xc9(\xff\xff\xff\xff\xe2Oi8\xff\xff\xff\xff\xe3v\xab(\xff\xff\xff\xff\xe4/K8\xff\xff\xff\xff\xe5_\xc7\xa8\xff\xff\xff\xff\xe6\x0f-8\xff\xff\xff\xff\xe7?\xa9\xa8\xff\xff\xff\xff\xe7\xf8I\xb8\xff\xff\xff\xff\xe9\x1f\x8b\xa8\xff\xff\xff\xff\xe9\xd8+\xb8\xff\xff\xff\xff\xea\xffm\xa8\xff\xff\xff\xff\xeb\xb8\x0d\xb8\xff\xff\xff\xff\xec\xdfO\xa8\xff\xff\xff\xff\xed\x97\xef\xb8\xff\xff\xff\xff\xee\xc8l(\xff\xff\xff\xff\xefw\xd1\xb8\xff\xff\xff\xff\xf0\xa8N(\xff\xff\xff\xff\xf1W\xb3\xb8\xff\xff\xff\xff\xf2\x880(\xff\xff\xff\xff\xf3@\xd08\xff\xff\xff\xff\xf4h\x12(\xff\xff\xff\xff\xf5 \xb28\xff\xff\xff\xff\xf6G\xf4(\xff\xff\xff\xff\xf7%~8\xff\xff\xff\xff\xf8\x15a(\xff\xff\xff\xff\xf9\x05`8\xff\xff\xff\xff\xf9\xf5C(\xff\xff\xff\xff\xfa\xe5B8\xff\xff\xff\xff\xfb\xde_\xa8\xff\xff\xff\xff\xfc\xce^\xb8\xff\xff\xff\xff\xfd\xbeA\xa8\xff\xff\xff\xff\xfe\xae@\xb8\xff\xff\xff\xff\xff\x9e#\xa8\x00\x00\x00\x00\x00\x8e\x22\xb8\x00\x00\x00\x00\x01~\x05\xa8\x00\x00\x00\x00\x02n\x04\xb8\x00\x00\x00\x00\x03]\xe7\xa8\x00\x00\x00\x00\x04M\xe6\xb8\x00\x00\x00\x00\x05G\x04(\x00\x00\x00\x00\x067\x038\x00\x00\x00\x00\x07&\xe6(\x00\x00\x00\x00\x07\x83=8\x00\x00\x00\x00\x09\x06\xc8(\x00\x00\x00\x00\x09\xf6\xc78\x00\x00\x00\x00\x0a\xe6\xaa(\x00\x00\x00\x00\x0b\xd6\xa98\x00\x00\x00\x00\x0c\xc6\x8c(\x00\x00\x00\x00\x11\x9b98\x00\x00\x00\x00\x12ol\xa8\x01\x02\x03\x04\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x00\x00k\x0a\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x01\x08\x00\x00w\x88\x01\x0d\x00\x00~\x90\x00\x12LMT\x00HKT\x00HKST\x00HKWT\x00JST\x00\x0aHKT-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x07\x00\x00\x00IcelandTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x92\xe6\x92H\x01\xff\xff\xfc8\x00\x00\x00\x00\x00\x00\x00\x04LMT\x00GMT\x00\x0aGMT0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x13\x00\x00\x00Indian/AntananarivoTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\x22\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\x0a\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\x0aEAT-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\xb0W\x14\x98\x00\x00\x00\x98\x00\x00\x00\x0d\x00\x00\x00Indian/ChagosTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x89~\xf7\x9c\x00\x00\x00\x000\xe6\xdd\xb0\x01\x02\x00\x00C\xe4\x00\x00\x00\x00FP\x00\x04\x00\x00T`\x00\x08LMT\x00+05\x00+06\x00\x0a<+06>-6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x10\x00\x00\x00Indian/ChristmasTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xffV\xb6\x85\xc4\xff\xff\xff\xff\xa2jg\xc4\x01\x02\x00\x00^<\x00\x00\x00\x00^<\x00\x04\x00\x00bp\x00\x08LMT\x00BMT\x00+07\x00\x0a<+07>-7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\x87{_\xbb\x00\x00\x00\xbb\x00\x00\x00\x0c\x00\x00\x00Indian/CocosTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xffV\xb6\x89\xd1\xff\xff\xff\xff\xa1\xf2sQ\xff\xff\xff\xff\xcb\xf2\xfc\x18\xff\xff\xff\xff\xd1\x9ag\xf0\x01\x02\x03\x02\x00\x00Z/\x00\x00\x00\x00Z/\x00\x04\x00\x00[h\x00\x08\x00\x00~\x90\x00\x0eLMT\x00RMT\x00+0630\x00+09\x00\x0a<+0630>-6:30\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0d\x00\x00\x00Indian/ComoroTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\x22\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\x0a\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\x0aEAT-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x10\x00\x00\x00Indian/KerguelenTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xffV\xb6\x9f\x18\xff\xff\xff\xff\xed/\xc3\x98\x01\x02\x00\x00D\xe8\x00\x00\x00\x00D\xe8\x00\x04\x00\x00FP\x00\x08LMT\x00MMT\x00+05\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\x0b\x00\x00\x00Indian/MaheTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x00\x00Indian/MaldivesTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xffV\xb6\x9f\x18\xff\xff\xff\xff\xed/\xc3\x98\x01\x02\x00\x00D\xe8\x00\x00\x00\x00D\xe8\x00\x04\x00\x00FP\x00\x08LMT\x00MMT\x00+05\x00\x0a<+05>-5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xed=\x98\xb3\x00\x00\x00\xb3\x00\x00\x00\x10\x00\x00\x00Indian/MauritiusTZif2\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\x05\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x89\x7f\x05\x98\x00\x00\x00\x00\x18\x05\xed@\x00\x00\x00\x00\x18\xdbr0\x00\x00\x00\x00I\x03\x96\xe0\x00\x00\x00\x00I\xce\x8f\xd0\x02\x01\x02\x01\x02\x00\x005\xe8\x00\x00\x00\x00FP\x01\x04\x00\x008@\x00\x08LMT\x00+05\x00+04\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00Indian/MayotteTZif2\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\x05\x00\x00\x00\x04\x00\x00\x00\x14\xff\xff\xff\xff\x8b\xff\xd1\xfc\xff\xff\xff\xff\xb1\xee\xdaX\xff\xff\xff\xff\xb4\xc7\xe0\xd0\xff\xff\xff\xff\xc1\xed\xadX\xff\xff\xff\xff\xcclz\xd4\x01\x02\x01\x03\x02\x00\x00\x22\x84\x00\x00\x00\x00#(\x00\x04\x00\x00*0\x00\x0a\x00\x00&\xac\x00\x0eLMT\x00+0230\x00EAT\x00+0245\x00\x0aEAT-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x00\x00Indian/ReunionTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\xa1\xf2\x99\xa8\x01\x00\x003\xd8\x00\x00\x00\x008@\x00\x04LMT\x00+04\x00\x0a<+04>-4\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xdb?\xec,\x03\x00\x00,\x03\x00\x00\x04\x00\x00\x00IranTZif2\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\x00G\x00\x00\x00\x06\x00\x00\x00\x1c\xff\xff\xff\xff\x9al}\xc8\xff\xff\xff\xff\xbf\x00\xccH\x00\x00\x00\x00\x0d\x94D8\x00\x00\x00\x00\x0e\xad\x13\xb8\x00\x00\x00\x00\x0fys@\x00\x00\x00\x00\x10(\xca\xc0\x00\x00\x00\x00\x10\xed:@\x00\x00\x00\x00\x11\xad\xbcH\x00\x00\x00\x00\x12EJ\xb8\x00\x00\x00\x00\x137\xec\xc8\x00\x00\x00\x00\x14-\x15\xb8\x00\x00\x00\x00( v\xc8\x00\x00\x00\x00(\xdb\x9d\xb8\x00\x00\x00\x00)\xcb\x9c\xc8\x00\x00\x00\x00*\xbe\x22\xb8\x00\x00\x00\x00+\xac\xd0H\x00\x00\x00\x00,\x9fV8\x00\x00\x00\x00-\x8e\x03\xc8\x00\x00\x00\x00.\x80\x89\xb8\x00\x00\x00\x00/o7H\x00\x00\x00\x000a\xbd8\x00\x00\x00\x001Pj\xc8\x00\x00\x00\x002B\xf0\xb8\x00\x00\x00\x0032\xef\xc8\x00\x00\x00\x004%u\xb8\x00\x00\x00\x005\x14#H\x00\x00\x00\x006\x06\xa98\x00\x00\x00\x006\xf5V\xc8\x00\x00\x00\x007\xe7\xdc\xb8\x00\x00\x00\x008\xd6\x8aH\x00\x00\x00\x009\xc9\x108\x00\x00\x00\x00:\xb9\x0fH\x00\x00\x00\x00;\xab\x958\x00\x00\x00\x00<\x9aB\xc8\x00\x00\x00\x00=\x8c\xc8\xb8\x00\x00\x00\x00>{vH\x00\x00\x00\x00?m\xfc8\x00\x00\x00\x00@\x5c\xa9\xc8\x00\x00\x00\x00AO/\xb8\x00\x00\x00\x00B?.\xc8\x00\x00\x00\x00C1\xb4\xb8\x00\x00\x00\x00G\xe2\xc9H\x00\x00\x00\x00H\xd5O8\x00\x00\x00\x00I\xc5NH\x00\x00\x00\x00J\xb7\xd48\x00\x00\x00\x00K\xa6\x81\xc8\x00\x00\x00\x00L\x99\x07\xb8\x00\x00\x00\x00M\x87\xb5H\x00\x00\x00\x00Nz;8\x00\x00\x00\x00Oh\xe8\xc8\x00\x00\x00\x00P[n\xb8\x00\x00\x00\x00QKm\xc8\x00\x00\x00\x00R=\xf3\xb8\x00\x00\x00\x00S,\xa1H\x00\x00\x00\x00T\x1f'8\x00\x00\x00\x00U\x0d\xd4\xc8\x00\x00\x00\x00V\x00Z\xb8\x00\x00\x00\x00V\xef\x08H\x00\x00\x00\x00W\xe1\x8e8\x00\x00\x00\x00X\xd1\x8dH\x00\x00\x00\x00Y\xc4\x138\x00\x00\x00\x00Z\xb2\xc0\xc8\x00\x00\x00\x00[\xa5F\xb8\x00\x00\x00\x00\x5c\x93\xf4H\x00\x00\x00\x00]\x86z8\x00\x00\x00\x00^u'\xc8\x00\x00\x00\x00_g\xad\xb8\x00\x00\x00\x00`W\xac\xc8\x00\x00\x00\x00aJ2\xb8\x00\x00\x00\x00b8\xe0H\x00\x00\x00\x00c+f8\x01\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x00\x0008\x00\x00\x00\x0008\x00\x04\x00\x00?H\x01\x08\x00\x0018\x00\x0e\x00\x00FP\x01\x14\x00\x008@\x00\x18LMT\x00TMT\x00+0430\x00+0330\x00+05\x00+04\x00\x0a<+0330>-3:30\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\xe2\x9c\xb32\x04\x00\x002\x04\x00\x00\x06\x00\x00\x00IsraelTZif3\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\x00d\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6\xc2\xfa\xff\xff\xff\xff\x9e0E\x88\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\xcd\xac\xfe\x00\xff\xff\xff\xff\xce\xc7\x1f\x00\xff\xff\xff\xff\xcf\x8f\x83\x00\xff\xff\xff\xff\xd0\xa9\xa4\x00\xff\xff\xff\xff\xd1\x84}\x00\xff\xff\xff\xff\xd2\x8a\xd7\x80\xff\xff\xff\xff\xd3e\xb0\x80\xff\xff\xff\xff\xd4l\x0b\x00\xff\xff\xff\xff\xd7Z0\x80\xff\xff\xff\xff\xd7\xdfX\x00\xff\xff\xff\xff\xd8/\xc3\x80\xff\xff\xff\xff\xd9\x1ec\x00\xff\xff\xff\xff\xda\x10\xf7\x00\xff\xff\xff\xff\xda\xeb\xd0\x00\xff\xff\xff\xff\xdb\xb44\x00\xff\xff\xff\xff\xdc\xb9=\x00\xff\xff\xff\xff\xdd\xe0\x8d\x00\xff\xff\xff\xff\xde\xb4\xce\x80\xff\xff\xff\xff\xdf\xa4\xbf\x80\xff\xff\xff\xff\xe0\x8bv\x00\xff\xff\xff\xff\xe1V}\x00\xff\xff\xff\xff\xe2\xbef\x80\xff\xff\xff\xff\xe36_\x00\xff\xff\xff\xff\xe4\x9eH\x80\xff\xff\xff\xff\xe5\x16A\x00\xff\xff\xff\xff\xe6t\xf0\x00\xff\xff\xff\xff\xe7\x11\xd2\x80\xff\xff\xff\xff\xe8&\xad\x80\xff\xff\xff\xff\xe8\xe8z\x00\x00\x00\x00\x00\x08|\x8b\xe0\x00\x00\x00\x00\x08\xfd\xb0\xd0\x00\x00\x00\x00\x09\xf6\xea`\x00\x00\x00\x00\x0a\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\x22^\x9e\xe0\x00\x00\x00\x00# ]P\x00\x00\x00\x00$Z0`\x00\x00\x00\x00%\x00?P\x00\x00\x00\x00&\x0b\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\x001H\x96\xe0\x00\x00\x00\x002<nP\x00\x00\x00\x0031\xb3`\x00\x00\x00\x004\x1a\xfe\xd0\x00\x00\x00\x005\x11\x95`\x00\x00\x00\x005\xf1\xa6P\x00\x00\x00\x007\x04\x08\x80\x00\x00\x00\x007\xcf\x01p\x00\x00\x00\x008\xf6_\x80\x00\x00\x00\x009\xdc\xf9\xe0\x00\x00\x00\x00:\xd0\xedp\x00\x00\x00\x00;\xae[`\x00\x00\x00\x00<\xa3\xa0p\x00\x00\x00\x00=\xa0\xb2`\x00\x00\x00\x00>\x83\x82p\x00\x00\x00\x00?|\x9f\xe0\x00\x00\x00\x00@s6p\x00\x00\x00\x00AP\xa4`\x00\x00\x00\x00BL\x8f\x00\x00\x00\x00\x00CHOp\x00\x00\x00\x00D,q\x00\x00\x00\x00\x00E\x1e\xf6\xf0\x00\x00\x00\x00F\x0cS\x00\x00\x00\x00\x00F\xecc\xf0\x00\x00\x00\x00G\xec5\x00\x00\x00\x00\x00H\xe7\xf5p\x00\x00\x00\x00I\xcc\x17\x00\x00\x00\x00\x00J\xbe\x9c\xf0\x00\x00\x00\x00K\xab\xf9\x00\x00\x00\x00\x00L\x8c\x09\xf0\x00\x00\x00\x00M\x95\x15\x80\x00\x00\x00\x00N\x87\x9bp\x00\x00\x00\x00Ot\xf7\x80\x00\x00\x00\x00P^B\xf0\x00\x00\x00\x00QT\xd9\x80\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x04\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00!\x06\x00\x00\x00\x00 \xf8\x00\x04\x00\x00*0\x01\x08\x00\x00\x1c \x00\x0c\x00\x008@\x01\x10LMT\x00JMT\x00IDT\x00IST\x00IDDT\x00\x0aIST-2IDT,M3.4.4/26,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%J\xd5\xebS\x01\x00\x00S\x01\x00\x00\x07\x00\x00\x00JamaicaTZif2\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\x16\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xffi\x87#~\xff\xff\xff\xff\x93\x0f\xb4\xfe\x00\x00\x00\x00\x07\x8d\x19p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x09\xad\x94\xf0\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\xff\xff\xb8\x02\x00\x00\xff\xff\xb8\x02\x00\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0cLMT\x00KMT\x00EST\x00EDT\x00\x0aEST5\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\x05\x00\x00\x00JapanTZif2\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\x09\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xffe\xc2\xa4p\xff\xff\xff\xff\xd7>\x02p\xff\xff\xff\xff\xd7\xedY\xf0\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd;\xf0\xff\xff\xff\xff\xdb\x07\x00\xf0\xff\xff\xff\xff\xdb\xad\x1d\xf0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\xdd\x8c\xff\xf0\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x83\x03\x00\x00\x00\x00\x8c\xa0\x01\x04\x00\x00~\x90\x00\x08LMT\x00JDT\x00JST\x00\x0aJST-9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\x09\x00\x00\x00KwajaleinTZif2\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\x06\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff~6\x18 \xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\x0a`\xff\xff\xff\xff\xcfF\x81\xf0\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00\x00,v\x0e@\x01\x02\x03\x01\x04\x05\x00\x00\x9c\xe0\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\x8c\xa0\x00\x08\x00\x00~\x90\x00\x0c\xff\xffW@\x00\x10\x00\x00\xa8\xc0\x00\x14LMT\x00+11\x00+10\x00+09\x00-12\x00+12\x00\x0a<+12>-12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x05\x00\x00\x00LibyaTZif2\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\x11\xff\xff\xff\xff\xa1\xf2\xc1$\xff\xff\xff\xff\xdd\xbb\xb1\x10\xff\xff\xff\xff\xde#\xad`\xff\xff\xff\xff\xe1x\xd2\x10\xff\xff\xff\xff\xe1\xe7e\xe0\xff\xff\xff\xff\xe5/?p\xff\xff\xff\xff\xe5\xa9\xcc\xe0\xff\xff\xff\xff\xebN\xc6\xf0\x00\x00\x00\x00\x16\x92B`\x00\x00\x00\x00\x17\x08\xf7p\x00\x00\x00\x00\x17\xfa+\xe0\x00\x00\x00\x00\x18\xea*\xf0\x00\x00\x00\x00\x19\xdb_`\x00\x00\x00\x00\x1a\xcc\xaf\xf0\x00\x00\x00\x00\x1b\xbd\xe4`\x00\x00\x00\x00\x1c\xb4z\xf0\x00\x00\x00\x00\x1d\x9f\x17\xe0\x00\x00\x00\x00\x1e\x93\x0bp\x00\x00\x00\x00\x1f\x82\xee`\x00\x00\x00\x00 pJp\x00\x00\x00\x00!a~\xe0\x00\x00\x00\x00\x22R\xcfp\x00\x00\x00\x00#D\x03\xe0\x00\x00\x00\x00$4\x02\xf0\x00\x00\x00\x00%%7`\x00\x00\x00\x00&@\xb7\xf0\x00\x00\x00\x002N\xf1`\x00\x00\x00\x003D6p\x00\x00\x00\x0045j\xe0\x00\x00\x00\x00P\x9d\x99\x00\x00\x00\x00\x00QT\xd9\x80\x00\x00\x00\x00Ri\xb4\x80\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x03\x02\x01\x03\x02\x01\x03\x00\x00\x0c\x5c\x00\x00\x00\x00\x1c \x01\x04\x00\x00\x0e\x10\x00\x09\x00\x00\x1c \x00\x0dLMT\x00CEST\x00CET\x00EET\x00\x0aEET-2\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\x9d\x1b\xc9m\x02\x00\x00m\x02\x00\x00\x03\x00\x00\x00METTZif2\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\x005\x00\x00\x00\x02\x00\x00\x00\x09\xff\xff\xff\xff\x9b\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\x09q\x90\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x82%\x10\xff\xff\xff\xff\xd1r\x16\x10\xff\xff\xff\xff\xd2N@\x90\x00\x00\x00\x00\x0d\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x0e\x10\x00\x05\x00\x00\x1c \x01\x00MEST\x00MET\x00\x0aMET-1MEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf5\x8d\x99\x92o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00MSTTZif2\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\x00\x01\x00\x00\x00\x04\xff\xff\x9d\x90\x00\x00MST\x00\x0aMST7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6h\xcac\xb7\x03\x00\x00\xb7\x03\x00\x00\x07\x00\x00\x00MST7MDTTZif2\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\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x07\x8d5\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x09\xad\xb1\x10\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x01\x00\xff\xff\xab\xa0\x01\x08\xff\xff\xab\xa0\x01\x0cMDT\x00MST\x00MWT\x00MPT\x00\x0aMST7MDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x00\x00Mexico/BajaNorteTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xa9yOp\xff\xff\xff\xff\xaf\xf2|\xf0\xff\xff\xff\xff\xb6fdp\xff\xff\xff\xff\xb7\x1b\x10\x00\xff\xff\xff\xff\xb8\x0a\xf2\xf0\xff\xff\xff\xff\xcb\xea\x8d\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2\x99\xbap\xff\xff\xff\xff\xd7\x1bY\x00\xff\xff\xff\xff\xd8\x91\xb4\xf0\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\x07\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00F\x0f\x82\xa0\x00\x00\x00\x00G$O\x90\x00\x00\x00\x00G\xf8\x9f \x00\x00\x00\x00I\x041\x90\x00\x00\x00\x00I\xd8\x81 \x00\x00\x00\x00J\xe4\x13\x90\x00\x00\x00\x00K\x9c\xb3\xa0\x01\x02\x01\x02\x03\x02\x04\x05\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\xff\xff\x92L\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\x8f\x80\x00\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10\xff\xff\x9d\x90\x01\x14LMT\x00MST\x00PST\x00PDT\x00PWT\x00PPT\x00\x0aPST8PDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xad=\x98\xce\x02\x00\x00\xce\x02\x00\x00\x0e\x00\x00\x00Mexico/BajaSurTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\x0c6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xcb\xeaq`\xff\xff\xff\xff\xd8\x91\xb4\xf0\x00\x00\x00\x00\x00\x00p\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xf5\x12\x90\x00\x00\x00\x00;\xb6\xd1\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00F\x0ft\x90\x00\x00\x00\x00G$A\x80\x00\x00\x00\x00G\xf8\x91\x10\x00\x00\x00\x00I\x04#\x80\x00\x00\x00\x00I\xd8s\x10\x00\x00\x00\x00J\xe4\x05\x80\x00\x00\x00\x00K\xb8U\x10\x00\x00\x00\x00L\xcd\x22\x00\x00\x00\x00\x00M\x987\x10\x00\x00\x00\x00N\xad\x04\x00\x00\x00\x00\x00Ox\x19\x10\x00\x00\x00\x00P\x8c\xe6\x00\x00\x00\x00\x00Qa5\x90\x00\x00\x00\x00Rl\xc8\x00\x00\x00\x00\x00SA\x17\x90\x00\x00\x00\x00TL\xaa\x00\x00\x00\x00\x00U \xf9\x90\x00\x00\x00\x00V,\x8c\x00\x00\x00\x00\x00W\x00\xdb\x90\x00\x00\x00\x00X\x15\xa8\x80\x00\x00\x00\x00X\xe0\xbd\x90\x00\x00\x00\x00Y\xf5\x8a\x80\x00\x00\x00\x00Z\xc0\x9f\x90\x00\x00\x00\x00[\xd5l\x80\x00\x00\x00\x00\x5c\xa9\xbc\x10\x00\x00\x00\x00]\xb5N\x80\x00\x00\x00\x00^\x89\x9e\x10\x00\x00\x00\x00_\x950\x80\x00\x00\x00\x00`i\x80\x10\x00\x00\x00\x00a~M\x00\x00\x00\x00\x00bIb\x10\x00\x00\x00\x00c^/\x00\x01\x02\x01\x03\x01\x02\x01\x04\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\xff\xff\x9c<\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\x8f\x80\x00\x10LMT\x00MST\x00CST\x00MDT\x00PST\x00\x0aMST7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\x08\x89\x8c\x05\x03\x00\x00\x05\x03\x00\x00\x0e\x00\x00\x00Mexico/GeneralTZif2\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\x00D\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\xa5\xb6\xe8p\xff\xff\xff\xff\xaf\xf2n\xe0\xff\xff\xff\xff\xb6fV`\xff\xff\xff\xff\xb7C\xd2`\xff\xff\xff\xff\xb8\x0c6`\xff\xff\xff\xff\xb8\xfd\x86\xf0\xff\xff\xff\xff\xc5\xde\xb0`\xff\xff\xff\xff\xc6\x974P\xff\xff\xff\xff\xc9U\xf1\xe0\xff\xff\xff\xff\xc9\xea\xddP\xff\xff\xff\xff\xcf\x02\xc6\xe0\xff\xff\xff\xff\xcf\xb7VP\xff\xff\xff\xff\xda\x99\x15\xe0\xff\xff\xff\xff\xdbv\x83\xd0\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xf5\x04\x80\x00\x00\x00\x00;\xb6\xc2\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00F\x0ff\x80\x00\x00\x00\x00G$3p\x00\x00\x00\x00G\xf8\x83\x00\x00\x00\x00\x00I\x04\x15p\x00\x00\x00\x00I\xd8e\x00\x00\x00\x00\x00J\xe3\xf7p\x00\x00\x00\x00K\xb8G\x00\x00\x00\x00\x00L\xcd\x13\xf0\x00\x00\x00\x00M\x98)\x00\x00\x00\x00\x00N\xac\xf5\xf0\x00\x00\x00\x00Ox\x0b\x00\x00\x00\x00\x00P\x8c\xd7\xf0\x00\x00\x00\x00Qa'\x80\x00\x00\x00\x00Rl\xb9\xf0\x00\x00\x00\x00SA\x09\x80\x00\x00\x00\x00TL\x9b\xf0\x00\x00\x00\x00U \xeb\x80\x00\x00\x00\x00V,}\xf0\x00\x00\x00\x00W\x00\xcd\x80\x00\x00\x00\x00X\x15\x9ap\x00\x00\x00\x00X\xe0\xaf\x80\x00\x00\x00\x00Y\xf5|p\x00\x00\x00\x00Z\xc0\x91\x80\x00\x00\x00\x00[\xd5^p\x00\x00\x00\x00\x5c\xa9\xae\x00\x00\x00\x00\x00]\xb5@p\x00\x00\x00\x00^\x89\x90\x00\x00\x00\x00\x00_\x95\x22p\x00\x00\x00\x00`ir\x00\x00\x00\x00\x00a~>\xf0\x00\x00\x00\x00bIT\x00\x00\x00\x00\x00c^ \xf0\x01\x02\x01\x03\x01\x02\x04\x02\x04\x02\x05\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\xff\xff\xa3\x0c\x00\x00\xff\xff\x9d\x90\x00\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00MST\x00CST\x00MDT\x00CDT\x00CWT\x00\x0aCST6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x02\x00\x00\x00NZTZif2\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\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba\xcc\xa7\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\xc2\x83\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2\xda\x9a@\x00\x00\x00\x00\x09\x18\xfd\xe0\x00\x00\x00\x00\x09\xac\xa5\xe0\x00\x00\x00\x00\x0a\xef\xa5`\x00\x00\x00\x00\x0b\x9e\xfc\xe0\x00\x00\x00\x00\x0c\xd8\xc1\xe0\x00\x00\x00\x00\x0d~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\x0c`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\x0b`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\x220\x09\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\x0d\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*\xcd\xa7`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\x0a\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008\xd3\x8b\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\x5cN`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\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\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\x09\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\x0aNZST-12NZDT,M9.5.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\x07\x00\x00\x00NZ-CHATTZif2\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\x00E\x00\x00\x00\x04\x00\x00\x00\x16\xff\xff\xff\xffA\xb7D\x84\xff\xff\xff\xff\xd2\xda\x96\xbc\x00\x00\x00\x00\x09\x18\xfd\xe0\x00\x00\x00\x00\x09\xac\xa5\xe0\x00\x00\x00\x00\x0a\xef\xa5`\x00\x00\x00\x00\x0b\x9e\xfc\xe0\x00\x00\x00\x00\x0c\xd8\xc1\xe0\x00\x00\x00\x00\x0d~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\x0c`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\x0b`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\x220\x09\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\x0d\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*\xcd\xa7`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\x0a\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008\xd3\x8b\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\x5cN`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\xab\xfc\x00\x00\x00\x00\xacD\x00\x04\x00\x00\xc1\x5c\x01\x0a\x00\x00\xb3L\x00\x10LMT\x00+1215\x00+1345\x00+1245\x00\x0a<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x06\x00\x00\x00NavajoTZif2\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\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\x0c\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\x08v\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x07\x8d5\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x09\xad\xb1\x10\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\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\xff\xff\x9d\x94\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\x0aMST7MDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x03\x00\x00\x00PRCTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff~6C)\xff\xff\xff\xff\xa0\x97\xa2\x80\xff\xff\xff\xff\xa1y\x04\xf0\xff\xff\xff\xff\xc8Y^\x80\xff\xff\xff\xff\xc9\x09\xf9p\xff\xff\xff\xff\xc9\xd3\xbd\x00\xff\xff\xff\xff\xcb\x05\x8a\xf0\xff\xff\xff\xff\xcb|@\x00\xff\xff\xff\xff\xd2;>\xf0\xff\xff\xff\xff\xd3\x8b{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\x22\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9A|\xf0\x00\x00\x00\x00\x1e\xbaR \x00\x00\x00\x00\x1fi\x9b\x90\x00\x00\x00\x00 ~\x84\xa0\x00\x00\x00\x00!I}\x90\x00\x00\x00\x00\x22g\xa1 \x00\x00\x00\x00#)_\x90\x00\x00\x00\x00$G\x83 \x00\x00\x00\x00%\x12|\x10\x00\x00\x00\x00&'e \x00\x00\x00\x00&\xf2^\x10\x00\x00\x00\x00(\x07G \x00\x00\x00\x00(\xd2@\x10\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\x00\x00q\xd7\x00\x00\x00\x00~\x90\x01\x04\x00\x00p\x80\x00\x08LMT\x00CDT\x00CST\x00\x0aCST-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xadV\xad\xb7\x03\x00\x00\xb7\x03\x00\x00\x07\x00\x00\x00PST8PDTTZif2\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\x00X\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xff\xcb\x89\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\x0c\x10\x00\x00\x00\x00\x02x\x0b \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\x0a\x90\x00\x00\x00\x00\x06A\x09\xa0\x00\x00\x00\x00\x070\xec\x90\x00\x00\x00\x00\x07\x8dC\xa0\x00\x00\x00\x00\x09\x10\xce\x90\x00\x00\x00\x00\x09\xad\xbf \x00\x00\x00\x00\x0a\xf0\xb0\x90\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x01\x00\x01\x00\x02\x03\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\xff\xff\x8f\x80\x00\x04\xff\xff\x9d\x90\x01\x00\xff\xff\x9d\x90\x01\x08\xff\xff\x9d\x90\x01\x0cPDT\x00PST\x00PWT\x00PPT\x00\x0aPST8PDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8A\x15\xfe\x97\x01\x00\x00\x97\x01\x00\x00\x0c\x00\x00\x00Pacific/ApiaTZif2\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\x1a\x00\x00\x00\x07\x00\x00\x00\x1a\xff\xff\xff\xffn=\xc9\x00\xff\xff\xff\xff\x91\x05\xfc\x00\xff\xff\xff\xff\xdab\x048\x00\x00\x00\x00L\x9f'\xb0\x00\x00\x00\x00M\x97+\xe0\x00\x00\x00\x00N}\xe2`\x00\x00\x00\x00N\xfd\x8b\xa0\x00\x00\x00\x00Ow\x0d\xe0\x00\x00\x00\x00Pf\xfe\xe0\x00\x00\x00\x00Q`*`\x00\x00\x00\x00RF\xe0\xe0\x00\x00\x00\x00S@\x0c`\x00\x00\x00\x00T&\xc2\xe0\x00\x00\x00\x00U\x1f\xee`\x00\x00\x00\x00V\x06\xa4\xe0\x00\x00\x00\x00V\xff\xd0`\x00\x00\x00\x00W\xe6\x86\xe0\x00\x00\x00\x00X\xdf\xb2`\x00\x00\x00\x00Y\xc6h\xe0\x00\x00\x00\x00Z\xbf\x94`\x00\x00\x00\x00[\xaf\x85`\x00\x00\x00\x00\x5c\xa8\xb0\xe0\x00\x00\x00\x00]\x8fg`\x00\x00\x00\x00^\x88\x92\xe0\x00\x00\x00\x00_oI`\x00\x00\x00\x00`ht\xe0\x01\x02\x04\x03\x04\x03\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x00\x00\xb0\x80\x00\x00\xff\xff_\x00\x00\x00\xff\xff^H\x00\x04\xff\xffs`\x01\x0a\xff\xffeP\x00\x0e\x00\x00\xb6\xd0\x00\x12\x00\x00\xc4\xe0\x01\x16LMT\x00-1130\x00-10\x00-11\x00+13\x00+14\x00\x0a<+13>-13\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x10\x00\x00\x00Pacific/AucklandTZif2\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\x06\x00\x00\x00\x13\xff\xff\xff\xffA\xb7L\xa8\xff\xff\xff\xff\xb0\xb4\xb2\xe8\xff\xff\xff\xff\xb1Q\x87X\xff\xff\xff\xff\xb2x\xe5h\xff\xff\xff\xff\xb3C\xe5`\xff\xff\xff\xff\xb4X\xc7h\xff\xff\xff\xff\xb5#\xc7`\xff\xff\xff\xff\xb68\xa9h\xff\xff\xff\xff\xb7\x03\xa9`\xff\xff\xff\xff\xb8\x18\x8bh\xff\xff\xff\xff\xb8\xec\xc5\xe0\xff\xff\xff\xff\xb9\xf8mh\xff\xff\xff\xff\xba\xcc\xa7\xe0\xff\xff\xff\xff\xbb\xd8Oh\xff\xff\xff\xff\xbc\xe3\xe8\xe0\xff\xff\xff\xff\xbd\xae\xf6\xe8\xff\xff\xff\xff\xbe\xc3\xca\xe0\xff\xff\xff\xff\xbf\x8e\xd8\xe8\xff\xff\xff\xff\xc0\xa3\xac\xe0\xff\xff\xff\xff\xc1n\xba\xe8\xff\xff\xff\xff\xc2\x83\x8e\xe0\xff\xff\xff\xff\xc3N\x9c\xe8\xff\xff\xff\xff\xc4cp\xe0\xff\xff\xff\xff\xc5.~\xe8\xff\xff\xff\xff\xc6L\x8d`\xff\xff\xff\xff\xc7\x0e`\xe8\xff\xff\xff\xff\xc8,o`\xff\xff\xff\xff\xc8\xf7}h\xff\xff\xff\xff\xd2\xda\x9a@\x00\x00\x00\x00\x09\x18\xfd\xe0\x00\x00\x00\x00\x09\xac\xa5\xe0\x00\x00\x00\x00\x0a\xef\xa5`\x00\x00\x00\x00\x0b\x9e\xfc\xe0\x00\x00\x00\x00\x0c\xd8\xc1\xe0\x00\x00\x00\x00\x0d~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\x0c`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\x0b`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\x220\x09\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\x0d\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*\xcd\xa7`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\x0a\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008\xd3\x8b\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\x5cN`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x02\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\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\x00\x00\xa3\xd8\x00\x00\x00\x00\xaf\xc8\x01\x04\x00\x00\xa1\xb8\x00\x09\x00\x00\xa8\xc0\x01\x04\x00\x00\xb6\xd0\x01\x0e\x00\x00\xa8\xc0\x00\x04LMT\x00NZST\x00NZMT\x00NZDT\x00\x0aNZST-12NZDT,M9.5.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xf2:F\xc9\x00\x00\x00\xc9\x00\x00\x00\x14\x00\x00\x00Pacific/BougainvilleTZif2\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\x05\x00\x00\x00\x05\x00\x00\x00\x15\xff\xff\xff\xffV\xb6R(\xff\xff\xff\xffr\xed\xa4\x90\xff\xff\xff\xff\xccC6`\xff\xff\xff\xff\xd2+l\xf0\x00\x00\x00\x00T\x9e\xd7\x80\x01\x02\x03\x02\x04\x00\x00\x91\xd8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\x09\x00\x00~\x90\x00\x0d\x00\x00\x9a\xb0\x00\x11LMT\x00PMMT\x00+10\x00+09\x00+11\x00\x0a<+11>-11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\x0f\x00\x00\x00Pacific/ChathamTZif2\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\x00E\x00\x00\x00\x04\x00\x00\x00\x16\xff\xff\xff\xffA\xb7D\x84\xff\xff\xff\xff\xd2\xda\x96\xbc\x00\x00\x00\x00\x09\x18\xfd\xe0\x00\x00\x00\x00\x09\xac\xa5\xe0\x00\x00\x00\x00\x0a\xef\xa5`\x00\x00\x00\x00\x0b\x9e\xfc\xe0\x00\x00\x00\x00\x0c\xd8\xc1\xe0\x00\x00\x00\x00\x0d~\xde\xe0\x00\x00\x00\x00\x0e\xb8\xa3\xe0\x00\x00\x00\x00\x0f^\xc0\xe0\x00\x00\x00\x00\x10\x98\x85\xe0\x00\x00\x00\x00\x11>\xa2\xe0\x00\x00\x00\x00\x12xg\xe0\x00\x00\x00\x00\x13\x1e\x84\xe0\x00\x00\x00\x00\x14XI\xe0\x00\x00\x00\x00\x14\xfef\xe0\x00\x00\x00\x00\x168+\xe0\x00\x00\x00\x00\x16\xe7\x83`\x00\x00\x00\x00\x18!H`\x00\x00\x00\x00\x18\xc7e`\x00\x00\x00\x00\x1a\x01*`\x00\x00\x00\x00\x1a\xa7G`\x00\x00\x00\x00\x1b\xe1\x0c`\x00\x00\x00\x00\x1c\x87)`\x00\x00\x00\x00\x1d\xc0\xee`\x00\x00\x00\x00\x1eg\x0b`\x00\x00\x00\x00\x1f\xa0\xd0`\x00\x00\x00\x00 F\xed`\x00\x00\x00\x00!\x80\xb2`\x00\x00\x00\x00\x220\x09\xe0\x00\x00\x00\x00#i\xce\xe0\x00\x00\x00\x00$\x0f\xeb\xe0\x00\x00\x00\x00%.\x01`\x00\x00\x00\x00&\x02B\xe0\x00\x00\x00\x00'\x0d\xe3`\x00\x00\x00\x00'\xe2$\xe0\x00\x00\x00\x00(\xed\xc5`\x00\x00\x00\x00)\xc2\x06\xe0\x00\x00\x00\x00*\xcd\xa7`\x00\x00\x00\x00+\xab#`\x00\x00\x00\x00,\xad\x89`\x00\x00\x00\x00-\x8b\x05`\x00\x00\x00\x00.\x8dk`\x00\x00\x00\x00/j\xe7`\x00\x00\x00\x000mM`\x00\x00\x00\x001J\xc9`\x00\x00\x00\x002Vi\xe0\x00\x00\x00\x003*\xab`\x00\x00\x00\x0046K\xe0\x00\x00\x00\x005\x0a\x8d`\x00\x00\x00\x006\x16-\xe0\x00\x00\x00\x006\xf3\xa9\xe0\x00\x00\x00\x007\xf6\x0f\xe0\x00\x00\x00\x008\xd3\x8b\xe0\x00\x00\x00\x009\xd5\xf1\xe0\x00\x00\x00\x00:\xb3m\xe0\x00\x00\x00\x00;\xbf\x0e`\x00\x00\x00\x00<\x93O\xe0\x00\x00\x00\x00=\x9e\xf0`\x00\x00\x00\x00>s1\xe0\x00\x00\x00\x00?~\xd2`\x00\x00\x00\x00@\x5cN`\x00\x00\x00\x00A^\xb4`\x00\x00\x00\x00B<0`\x00\x00\x00\x00C>\x96`\x00\x00\x00\x00D\x1c\x12`\x00\x00\x00\x00E\x1ex`\x00\x00\x00\x00E\xfb\xf4`\x00\x00\x00\x00F\xfeZ`\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\xab\xfc\x00\x00\x00\x00\xacD\x00\x04\x00\x00\xc1\x5c\x01\x0a\x00\x00\xb3L\x00\x10LMT\x00+1215\x00+1345\x00+1245\x00\x0a<+1245>-12:45<+1345>,M9.5.0/2:45,M4.1.0/3:45\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x0d\x00\x00\x00Pacific/ChuukTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xffV\xb6Z\x08\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\x09LMT\x00PMMT\x00+10\x00\x0a<+10>-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?X'\x8e\x96\x04\x00\x00\x96\x04\x00\x00\x0e\x00\x00\x00Pacific/EasterTZif3\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\x00n\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xffi\x87B\x08\xff\xff\xff\xff\xb9\xc7@\x88\xff\xff\xff\xff\xfd\xd1<@\xff\xff\xff\xff\xfe\x92\xfa\xb0\xff\xff\xff\xff\xff\xcc\xcd\xc0\x00\x00\x00\x00\x00r\xdc\xb0\x00\x00\x00\x00\x01uP\xc0\x00\x00\x00\x00\x02@I\xb0\x00\x00\x00\x00\x03U2\xc0\x00\x00\x00\x00\x04 +\xb0\x00\x00\x00\x00\x05>O@\x00\x00\x00\x00\x06\x00\x0d\xb0\x00\x00\x00\x00\x07\x0b\xbc@\x00\x00\x00\x00\x07\xdf\xef\xb0\x00\x00\x00\x00\x08\xfe\x13@\x00\x00\x00\x00\x09\xbf\xd1\xb0\x00\x00\x00\x00\x0a\xdd\xf5@\x00\x00\x00\x00\x0b\xa8\xee0\x00\x00\x00\x00\x0c\xbd\xd7@\x00\x00\x00\x00\x0d\x88\xd00\x00\x00\x00\x00\x0e\x9d\xb9@\x00\x00\x00\x00\x0fh\xb20\x00\x00\x00\x00\x10\x86\xd5\xc0\x00\x00\x00\x00\x11H\x940\x00\x00\x00\x00\x12f\xb7\xc0\x00\x00\x00\x00\x13(v0\x00\x00\x00\x00\x14F\x99\xc0\x00\x00\x00\x00\x15\x11\x92\xb0\x00\x00\x00\x00\x16&{\xc0\x00\x00\x00\x00\x16\xf1t\xb0\x00\x00\x00\x00\x18\x06]\xc0\x00\x00\x00\x00\x18\xd1V\xb0\x00\x00\x00\x00\x19\xe6?\xc0\x00\x00\x00\x00\x1a\xb18\xb0\x00\x00\x00\x00\x1b\xcf\x5c@\x00\x00\x00\x00\x1c\x91\x1a\xb0\x00\x00\x00\x00\x1d\xaf>@\x00\x00\x00\x00\x1ep\xfc\xb0\x00\x00\x00\x00\x1f\x8f @\x00\x00\x00\x00 \x7f\x030\x00\x00\x00\x00!o\x02@\x00\x00\x00\x00\x229\xfb0\x00\x00\x00\x00#N\xe4@\x00\x00\x00\x00$\x19\xdd0\x00\x00\x00\x00%8\x00\xc0\x00\x00\x00\x00%\xf9\xbf0\x00\x00\x00\x00&\xf2\xf8\xc0\x00\x00\x00\x00'\xd9\xa10\x00\x00\x00\x00(\xf7\xc4\xc0\x00\x00\x00\x00)\xc2\xbd\xb0\x00\x00\x00\x00*\xd7\xa6\xc0\x00\x00\x00\x00+\xa2\x9f\xb0\x00\x00\x00\x00,\xb7\x88\xc0\x00\x00\x00\x00-\x82\x81\xb0\x00\x00\x00\x00.\x97j\xc0\x00\x00\x00\x00/bc\xb0\x00\x00\x00\x000\x80\x87@\x00\x00\x00\x001BE\xb0\x00\x00\x00\x002`i@\x00\x00\x00\x003=\xd70\x00\x00\x00\x004@K@\x00\x00\x00\x005\x0bD0\x00\x00\x00\x006\x0d\xb8@\x00\x00\x00\x007\x06\xd5\xb0\x00\x00\x00\x008\x00\x0f@\x00\x00\x00\x008\xcb\x080\x00\x00\x00\x009\xe9+\xc0\x00\x00\x00\x00:\xaa\xea0\x00\x00\x00\x00;\xc9\x0d\xc0\x00\x00\x00\x00<\x8a\xcc0\x00\x00\x00\x00=\xa8\xef\xc0\x00\x00\x00\x00>j\xae0\x00\x00\x00\x00?\x88\xd1\xc0\x00\x00\x00\x00@S\xca\xb0\x00\x00\x00\x00Ah\xb3\xc0\x00\x00\x00\x00B3\xac\xb0\x00\x00\x00\x00CH\x95\xc0\x00\x00\x00\x00D\x13\x8e\xb0\x00\x00\x00\x00E1\xb2@\x00\x00\x00\x00E\xf3p\xb0\x00\x00\x00\x00G\x11\x94@\x00\x00\x00\x00G\xef\x020\x00\x00\x00\x00H\xf1v@\x00\x00\x00\x00I\xbco0\x00\x00\x00\x00J\xd1X@\x00\x00\x00\x00K\xb8\x00\xb0\x00\x00\x00\x00L\xb1:@\x00\x00\x00\x00M\xc6\x070\x00\x00\x00\x00NP\x82\xc0\x00\x00\x00\x00O\x9c\xae\xb0\x00\x00\x00\x00PB\xd9\xc0\x00\x00\x00\x00Q|\x90\xb0\x00\x00\x00\x00R+\xf6@\x00\x00\x00\x00S\x5cr\xb0\x00\x00\x00\x00T\x0b\xd8@\x00\x00\x00\x00W7\xe60\x00\x00\x00\x00W\xaf\xec\xc0\x00\x00\x00\x00Y\x17\xc80\x00\x00\x00\x00Y\x8f\xce\xc0\x00\x00\x00\x00Z\xf7\xaa0\x00\x00\x00\x00[o\xb0\xc0\x00\x00\x00\x00\x5c\xa9g\xb0\x00\x00\x00\x00]t|\xc0\x00\x00\x00\x00^\x89I\xb0\x00\x00\x00\x00_T^\xc0\x00\x00\x00\x00`i+\xb0\x00\x00\x00\x00a4@\xc0\x00\x00\x00\x00bI\x0d\xb0\x00\x00\x00\x00c\x1d]@\x00\x00\x00\x00d(\xef\xb0\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\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\xff\xff\x99x\x00\x00\xff\xff\x99x\x00\x04\xff\xff\xab\xa0\x01\x08\xff\xff\x9d\x90\x00\x0c\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x10LMT\x00EMT\x00-06\x00-07\x00-05\x00\x0a<-06>6<-05>,M9.1.6/22,M4.1.6/22\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9e\x7f\xab\x95V\x01\x00\x00V\x01\x00\x00\x0d\x00\x00\x00Pacific/EfateTZif2\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\x17\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x92\xf5\xc2\xb4\x00\x00\x00\x00\x07y\x99@\x00\x00\x00\x00\x07\xfa\xcc@\x00\x00\x00\x00\x19\xd2\xf7\xd0\x00\x00\x00\x00\x1a\xc2\xda\xc0\x00\x00\x00\x00\x1b\xb2\xd9\xd0\x00\x00\x00\x00\x1c\xa2\xbc\xc0\x00\x00\x00\x00\x1d\x9b\xf6P\x00\x00\x00\x00\x1e\x82\x9e\xc0\x00\x00\x00\x00\x1f{\xd8P\x00\x00\x00\x00 k\xbb@\x00\x00\x00\x00![\xbaP\x00\x00\x00\x00\x22K\x9d@\x00\x00\x00\x00#;\x9cP\x00\x00\x00\x00$+\x7f@\x00\x00\x00\x00%\x1b~P\x00\x00\x00\x00&\x0ba@\x00\x00\x00\x00&\xfb`P\x00\x00\x00\x00'\xebC@\x00\x00\x00\x00(\xe4|\xd0\x00\x00\x00\x00)\x81Q@\x00\x00\x00\x00*\xe9H\xd0\x00\x00\x00\x00+a3@\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x00\x00\x9d\xcc\x00\x00\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\x08LMT\x00+12\x00+11\x00\x0a<+11>-11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x11\x00\x00\x00Pacific/EnderburyTZif2\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\x03\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xc3,\xdb\x80\x00\x00\x00\x00\x12V\x04\xc0\x00\x00\x00\x00/\x059\xb0\x01\x02\x03\x00\x00\x00\x00\x00\x00\xff\xffW@\x00\x04\xff\xffeP\x00\x08\x00\x00\xb6\xd0\x00\x0c-00\x00-12\x00-11\x00+13\x00\x0a<+13>-13\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a|\xdcU\x99\x00\x00\x00\x99\x00\x00\x00\x0f\x00\x00\x00Pacific/FakaofoTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff~7U\x88\x00\x00\x00\x00N\xfd\x99\xb0\x01\x02\xff\xff_x\x00\x00\xff\xffeP\x00\x04\x00\x00\xb6\xd0\x00\x08LMT\x00-11\x00+13\x00\x0a<+13>-13\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd_yl\x8c\x01\x00\x00\x8c\x01\x00\x00\x0c\x00\x00\x00Pacific/FijiTZif2\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\x1d\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x9a\x13\xb1\xc0\x00\x00\x00\x006;\x17\xe0\x00\x00\x00\x006\xd7\xfa`\x00\x00\x00\x008$4`\x00\x00\x00\x008\xb7\xdc`\x00\x00\x00\x00K\x11,\xe0\x00\x00\x00\x00K\xae\x0f`\x00\x00\x00\x00L\xc2\xea`\x00\x00\x00\x00MrA\xe0\x00\x00\x00\x00N\xa2\xcc`\x00\x00\x00\x00O\x1a\xc4\xe0\x00\x00\x00\x00P\x82\xae`\x00\x00\x00\x00P\xfa\xa6\xe0\x00\x00\x00\x00Rk\xca\xe0\x00\x00\x00\x00R\xdaz\xd0\x00\x00\x00\x00TT\xe7`\x00\x00\x00\x00T\xbaj\xe0\x00\x00\x00\x00V4\xc9`\x00\x00\x00\x00V\x9aL\xe0\x00\x00\x00\x00X\x1d\xe5\xe0\x00\x00\x00\x00Xz.\xe0\x00\x00\x00\x00Y\xfd\xc7\xe0\x00\x00\x00\x00ZZ\x10\xe0\x00\x00\x00\x00[\xdd\xa9\xe0\x00\x00\x00\x00\x5c9\xf2\xe0\x00\x00\x00\x00]\xc6\xc6`\x00\x00\x00\x00^\x19\xd4\xe0\x00\x00\x00\x00_\xde\x07`\x00\x00\x00\x00`\x02\xf1`\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\x00\x00\xa7\xc0\x00\x00\x00\x00\xb6\xd0\x01\x04\x00\x00\xa8\xc0\x00\x08LMT\x00+13\x00+12\x00\x0a<+12>-12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x10\x00\x00\x00Pacific/FunafutiTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\x0a<+12>-12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xe3w\x0a\xaf\x00\x00\x00\xaf\x00\x00\x00\x11\x00\x00\x00Pacific/GalapagosTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x0c\xff\xff\xff\xff\xb6\xa4L\x80\x00\x00\x00\x00\x1e\x18\xc4P\x00\x00\x00\x00+\x17\x0a\xe0\x00\x00\x00\x00+q\xf4P\x01\x03\x02\x03\xff\xff\xac\x00\x00\x00\xff\xff\xb9\xb0\x00\x04\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08LMT\x00-05\x00-06\x00\x0a<-06>6\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc23\xa0\xbc\x84\x00\x00\x00\x84\x00\x00\x00\x0f\x00\x00\x00Pacific/GambierTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x94PH\x04\x01\xff\xff\x81|\x00\x00\xff\xff\x81p\x00\x04LMT\x00-09\x00\x0a<-09>9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x13\x00\x00\x00Pacific/GuadalcanalTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x94O3\x8c\x01\x00\x00\x95\xf4\x00\x00\x00\x00\x9a\xb0\x00\x04LMT\x00+11\x00\x0a<+11>-11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FI\xfe\x14^\x01\x00\x00^\x01\x00\x00\x0c\x00\x00\x00Pacific/GuamTZif2\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\x15\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\x14\xe1\xc5\xcc\xff\xff\xff\xff~6-L\xff\xff\xff\xff\xcb7\x95\xe0\xff\xff\xff\xff\xd0.\x89\xf0\xff\xff\xff\xff\xec7\xbe\x00\xff\xff\xff\xff\xef6\xf8\xf0\xff\xff\xff\xff\xfb\x9b\x00\x00\xff\xff\xff\xff\xfe?'\x8c\xff\xff\xff\xff\xff\x01\x1e\x00\xff\xff\xff\xff\xff]X\xf0\x00\x00\x00\x00\x00\x97,\x00\x00\x00\x00\x00\x01Fup\x00\x00\x00\x00\x02w\x0e\x00\x00\x00\x00\x00\x03&Wp\x00\x00\x00\x00\x07p\x97\x00\x00\x00\x00\x00\x07\xcc\xd1\xf0\x00\x00\x00\x00\x0c\x08\x91\x00\x00\x00\x00\x00\x0c|\x87,\x00\x00\x00\x00\x0d\xbf\x94\x80\x00\x00\x00\x00\x0ee\xa3p\x00\x00\x00\x00:C^`\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\xff\xff64\x00\x00\x00\x00\x87\xb4\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\x08\x00\x00\x9a\xb0\x01\x0c\x00\x00\x8c\xa0\x00\x10LMT\x00GST\x00+09\x00GDT\x00ChST\x00\x0aChST-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x00\x00Pacific/HonoluluTZif2\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\x07\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xff\xcb\x89=\xc8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aI8\xff\xff\xff\xff\xd5\x8dsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\x08\xff\xffzh\x01\x0c\xff\xffzh\x01\x10\xff\xffs`\x00\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\x0aHST10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x00\x00Pacific/JohnstonTZif2\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\x07\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xff\xcb\x89=\xc8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aI8\xff\xff\xff\xff\xd5\x8dsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\x08\xff\xffzh\x01\x0c\xff\xffzh\x01\x10\xff\xffs`\x00\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\x0aHST10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x0e\x00\x00\x00Pacific/KantonTZif2\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\x03\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff\xc3,\xdb\x80\x00\x00\x00\x00\x12V\x04\xc0\x00\x00\x00\x00/\x059\xb0\x01\x02\x03\x00\x00\x00\x00\x00\x00\xff\xffW@\x00\x04\xff\xffeP\x00\x08\x00\x00\xb6\xd0\x00\x0c-00\x00-12\x00-11\x00+13\x00\x0a<+13>-13\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8=ku\xae\x00\x00\x00\xae\x00\x00\x00\x12\x00\x00\x00Pacific/KiritimatiTZif2\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\x03\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff~7H\x80\x00\x00\x00\x00\x12U\xf2\x00\x00\x00\x00\x00/\x05+\xa0\x01\x02\x03\xff\xffl\x80\x00\x00\xff\xffj\x00\x00\x04\xff\xffs`\x00\x0a\x00\x00\xc4\xe0\x00\x0eLMT\x00-1040\x00-10\x00+14\x00\x0a<+14>-14\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97n7\x1a\xf2\x00\x00\x00\xf2\x00\x00\x00\x0e\x00\x00\x00Pacific/KosraeTZif2\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\x09\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xff\x14\xe1\xb4\xb4\xff\xff\xff\xff~6\x1c4\xff\xff\xff\xff\x98\x11\x95\xd0\xff\xff\xff\xff\xa09\xf9\xf0\xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\x0a`\xff\xff\xff\xff\xd2\x11\x0e\xf0\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00\x006\x8bg@\x01\x02\x03\x02\x04\x03\x02\x05\x02\xff\xffGL\x00\x00\x00\x00\x98\xcc\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00~\x90\x00\x08\x00\x00\x8c\xa0\x00\x0c\x00\x00\xa8\xc0\x00\x10LMT\x00+11\x00+09\x00+10\x00+12\x00\x0a<+11>-11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\x11\x00\x00\x00Pacific/KwajaleinTZif2\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\x06\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff~6\x18 \xff\xff\xff\xff\xc1\xed5\xd0\xff\xff\xff\xff\xc9\xea\x0a`\xff\xff\xff\xff\xcfF\x81\xf0\xff\xff\xff\xff\xff\x86\x1bP\x00\x00\x00\x00,v\x0e@\x01\x02\x03\x01\x04\x05\x00\x00\x9c\xe0\x00\x00\x00\x00\x9a\xb0\x00\x04\x00\x00\x8c\xa0\x00\x08\x00\x00~\x90\x00\x0c\xff\xffW@\x00\x10\x00\x00\xa8\xc0\x00\x14LMT\x00+11\x00+10\x00+09\x00-12\x00+12\x00\x0a<+12>-12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00Pacific/MajuroTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\x0a<+12>-12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D6\x83\xa1\x8b\x00\x00\x00\x8b\x00\x00\x00\x11\x00\x00\x00Pacific/MarquesasTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x0a\xff\xff\xff\xff\x94PLH\x01\xff\xff}8\x00\x00\xff\xffzh\x00\x04LMT\x00-0930\x00\x0a<-0930>9:30\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x0e\x00\x00\x00Pacific/MidwayTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x08\xff\xff\xff\xffn=\xc8\x08\xff\xff\xff\xff\x91\x05\xfb\x08\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\x0aSST11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2;Z\xf7\xb7\x00\x00\x00\xb7\x00\x00\x00\x0d\x00\x00\x00Pacific/NauruTZif2\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\x04\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\xa3\xe7+\x04\xff\xff\xff\xff\xcc\x90\xe9\xc8\xff\xff\xff\xff\xd2C'\xf0\x00\x00\x00\x00\x11!\xa8\xe8\x01\x02\x01\x03\x00\x00\x9c|\x00\x00\x00\x00\xa1\xb8\x00\x04\x00\x00~\x90\x00\x0a\x00\x00\xa8\xc0\x00\x0eLMT\x00+1130\x00+09\x00+12\x00\x0a<+12>-12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\xd60\x0c\x9a\x00\x00\x00\x9a\x00\x00\x00\x0c\x00\x00\x00Pacific/NiueTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff\xdf\xa1jL\xff\xff\xff\xff\xf5\xa6\xb8`\x01\x02\xff\xff`\xb4\x00\x00\xff\xff`\xa0\x00\x04\xff\xffeP\x00\x0aLMT\x00-1120\x00-11\x00\x0a<-11>11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y5\x1a6\xf7\x00\x00\x00\xf7\x00\x00\x00\x0f\x00\x00\x00Pacific/NorfolkTZif2\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\x06\x00\x00\x00\x06\x00\x00\x00\x1e\xff\xff\xff\xff~6\x17\x88\xff\xff\xff\xff\xdcA\xf8\x80\x00\x00\x00\x00\x09\x0f\xcah\x00\x00\x00\x00\x09\xb5\xe7h\x00\x00\x00\x00V\x0f\xe6h\x00\x00\x00\x00]\x98\xaf\xf0\x01\x02\x03\x02\x04\x05\x00\x00\x9dx\x00\x00\x00\x00\x9d\x80\x00\x04\x00\x00\xa1\xb8\x00\x0a\x00\x00\xaf\xc8\x01\x10\x00\x00\x9a\xb0\x00\x16\x00\x00\xa8\xc0\x01\x1aLMT\x00+1112\x00+1130\x00+1230\x00+11\x00+12\x00\x0a<+11>-11<+12>,M10.1.0,M4.1.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\xef\x97\xc6\xc6\x00\x00\x00\xc6\x00\x00\x00\x0e\x00\x00\x00Pacific/NoumeaTZif2\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\x07\x00\x00\x00\x03\x00\x00\x00\x0c\xff\xff\xff\xff\x92\xf5\xc4t\x00\x00\x00\x00\x0e\xe6\xbaP\x00\x00\x00\x00\x0fV\xbb\xc0\x00\x00\x00\x00\x10\xc6\x9cP\x00\x00\x00\x00\x117\xef@\x00\x00\x00\x002\xa0K\xf0\x00\x00\x00\x003\x18Dp\x02\x01\x02\x01\x02\x01\x02\x00\x00\x9c\x0c\x00\x00\x00\x00\xa8\xc0\x01\x04\x00\x00\x9a\xb0\x00\x08LMT\x00+12\x00+11\x00\x0a<+11>-11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x11\x00\x00\x00Pacific/Pago_PagoTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x08\xff\xff\xff\xffn=\xc8\x08\xff\xff\xff\xff\x91\x05\xfb\x08\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\x0aSST11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xf8v\xdc\x94\x00\x00\x00\x94\x00\x00\x00\x0d\x00\x00\x00Pacific/PalauTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x08\xff\xff\xff\xff\x14\xe1\xcfl\xff\xff\xff\xff~66\xec\x01\x02\xff\xff,\x94\x00\x00\x00\x00~\x14\x00\x00\x00\x00~\x90\x00\x04LMT\x00+09\x00\x0a<+09>-9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x0fA\x05\x99\x00\x00\x00\x99\x00\x00\x00\x10\x00\x00\x00Pacific/PitcairnTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0e\xff\xff\xff\xff~7.\xf4\x00\x00\x00\x005DB\x08\x01\x02\xff\xff\x86\x0c\x00\x00\xff\xff\x88x\x00\x04\xff\xff\x8f\x80\x00\x0aLMT\x00-0830\x00-08\x00\x0a<-08>8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x0f\x00\x00\x00Pacific/PohnpeiTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x94O3\x8c\x01\x00\x00\x95\xf4\x00\x00\x00\x00\x9a\xb0\x00\x04LMT\x00+11\x00\x0a<+11>-11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00Pacific/PonapeTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x94O3\x8c\x01\x00\x00\x95\xf4\x00\x00\x00\x00\x9a\xb0\x00\x04LMT\x00+11\x00\x0a<+11>-11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x14\x00\x00\x00Pacific/Port_MoresbyTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xffV\xb6Z\x08\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\x09LMT\x00PMMT\x00+10\x00\x0a<+10>-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xe3\xa3S\x96\x01\x00\x00\x96\x01\x00\x00\x11\x00\x00\x00Pacific/RarotongaTZif2\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\x1c\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff|L\xdc\xc8\xff\xff\xff\xff\xdf\xa1`\xc8\x00\x00\x00\x00\x10\xac\x1b(\x00\x00\x00\x00\x11?\xb5\x18\x00\x00\x00\x00\x12y\x81 \x00\x00\x00\x00\x13\x1f\x97\x18\x00\x00\x00\x00\x14Yc \x00\x00\x00\x00\x14\xffy\x18\x00\x00\x00\x00\x169E \x00\x00\x00\x00\x16\xe8\x95\x98\x00\x00\x00\x00\x18\x22a\xa0\x00\x00\x00\x00\x18\xc8w\x98\x00\x00\x00\x00\x1a\x02C\xa0\x00\x00\x00\x00\x1a\xa8Y\x98\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\x88;\x98\x00\x00\x00\x00\x1d\xc2\x07\xa0\x00\x00\x00\x00\x1eh\x1d\x98\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 G\xff\x98\x00\x00\x00\x00!\x81\xcb\xa0\x00\x00\x00\x00\x221\x1c\x18\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$\x10\xfe\x18\x00\x00\x00\x00%J\xca \x00\x00\x00\x00%\xf0\xe0\x18\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xd0\xc2\x18\x01\x02\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\x00\x00\xbb\xb8\x00\x00\xff\xffj8\x00\x00\xff\xfflX\x00\x04\xff\xffs`\x00\x0a\xff\xffzh\x01\x0eLMT\x00-1030\x00-10\x00-0930\x00\x0a<-10>10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FI\xfe\x14^\x01\x00\x00^\x01\x00\x00\x0e\x00\x00\x00Pacific/SaipanTZif2\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\x15\x00\x00\x00\x06\x00\x00\x00\x15\xff\xff\xff\xff\x14\xe1\xc5\xcc\xff\xff\xff\xff~6-L\xff\xff\xff\xff\xcb7\x95\xe0\xff\xff\xff\xff\xd0.\x89\xf0\xff\xff\xff\xff\xec7\xbe\x00\xff\xff\xff\xff\xef6\xf8\xf0\xff\xff\xff\xff\xfb\x9b\x00\x00\xff\xff\xff\xff\xfe?'\x8c\xff\xff\xff\xff\xff\x01\x1e\x00\xff\xff\xff\xff\xff]X\xf0\x00\x00\x00\x00\x00\x97,\x00\x00\x00\x00\x00\x01Fup\x00\x00\x00\x00\x02w\x0e\x00\x00\x00\x00\x00\x03&Wp\x00\x00\x00\x00\x07p\x97\x00\x00\x00\x00\x00\x07\xcc\xd1\xf0\x00\x00\x00\x00\x0c\x08\x91\x00\x00\x00\x00\x00\x0c|\x87,\x00\x00\x00\x00\x0d\xbf\x94\x80\x00\x00\x00\x00\x0ee\xa3p\x00\x00\x00\x00:C^`\x01\x02\x03\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x04\x02\x05\xff\xff64\x00\x00\x00\x00\x87\xb4\x00\x00\x00\x00\x8c\xa0\x00\x04\x00\x00~\x90\x00\x08\x00\x00\x9a\xb0\x01\x0c\x00\x00\x8c\xa0\x00\x10LMT\x00GST\x00+09\x00GDT\x00ChST\x00\x0aChST-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x0d\x00\x00\x00Pacific/SamoaTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x08\xff\xff\xff\xffn=\xc8\x08\xff\xff\xff\xff\x91\x05\xfb\x08\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\x0aSST11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\xc1\xda\xcf\x85\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x00\x00Pacific/TahitiTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff\x94PU\xb8\x01\xff\xffs\xc8\x00\x00\xff\xffs`\x00\x04LMT\x00-10\x00\x0a<-10>10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00Pacific/TarawaTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\x0a<+12>-12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97F\x91\xb3\xed\x00\x00\x00\xed\x00\x00\x00\x11\x00\x00\x00Pacific/TongatapuTZif2\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\x0a\x00\x00\x00\x04\x00\x00\x00\x12\xff\xff\xff\xff\xd2E\x9c@\xff\xff\xff\xff\xef\x11\xe0\x10\x00\x00\x00\x007\xfbG\xd0\x00\x00\x00\x008\xd3}\xd0\x00\x00\x00\x00:\x04\x08P\x00\x00\x00\x00:r\xb8@\x00\x00\x00\x00;\xe3\xeaP\x00\x00\x00\x00<R\x9a@\x00\x00\x00\x00X\x1d\xd7\xd0\x00\x00\x00\x00Xz \xd0\x01\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\xad@\x00\x00\x00\x00\xadp\x00\x04\x00\x00\xb6\xd0\x00\x0a\x00\x00\xc4\xe0\x01\x0eLMT\x00+1220\x00+13\x00+14\x00\x0a<+13>-13\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x0c\x00\x00\x00Pacific/TrukTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xffV\xb6Z\x08\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\x09LMT\x00PMMT\x00+10\x00\x0a<+10>-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0c\x00\x00\x00Pacific/WakeTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\x0a<+12>-12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00Pacific/WallisTZif2\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\x01\x00\x00\x00\x02\x00\x00\x00\x08\xff\xff\xff\xff~6\x12\xcc\x01\x00\x00\xa24\x00\x00\x00\x00\xa8\xc0\x00\x04LMT\x00+12\x00\x0a<+12>-12\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x0b\x00\x00\x00Pacific/YapTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x0d\xff\xff\xff\xffV\xb6Z\x08\xff\xff\xff\xffr\xed\xa4\x90\x01\x02\x00\x00\x89\xf8\x00\x00\x00\x00\x89\xf0\x00\x04\x00\x00\x8c\xa0\x00\x09LMT\x00PMMT\x00+10\x00\x0a<+10>-10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xfe\xe5\x9e\x9b\x03\x00\x00\x9b\x03\x00\x00\x06\x00\x00\x00PolandTZif2\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\x00R\x00\x00\x00\x06\x00\x00\x00\x1a\xff\xff\xff\xffV\xb6\xd0P\xff\xff\xff\xff\x99\xa8*\xd0\xff\xff\xff\xff\x9b\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xda\xf0\xff\xff\xff\xff\x9c\xd9\xae\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\xa0\x9a\xb6\x00\xff\xff\xff\xff\xa1e\xbd\x00\xff\xff\xff\xff\xa6}|`\xff\xff\xff\xff\xc8v\xde\x10\xff\xff\xff\xff\xcc\xe7K\x10\xff\xff\xff\xff\xcd\xa9\x17\x90\xff\xff\xff\xff\xce\xa2C\x10\xff\xff\xff\xff\xcf\x924\x10\xff\xff\xff\xff\xd0\x84\xba\x00\xff\xff\xff\xff\xd1\x95\x92p\xff\xff\xff\xff\xd2\x8a\xbb`\xff\xff\xff\xff\xd3b\xffp\xff\xff\xff\xff\xd4K#\x90\xff\xff\xff\xff\xd5^\xad\x10\xff\xff\xff\xff\xd6)\xb4\x10\xff\xff\xff\xff\xd7,\x1a\x10\xff\xff\xff\xff\xd8\x09\x96\x10\xff\xff\xff\xff\xd9\x02\xc1\x90\xff\xff\xff\xff\xd9\xe9x\x10\xff\xff\xff\xff\xe8T\xd2\x00\xff\xff\xff\xff\xe8\xf1\xb4\x80\xff\xff\xff\xff\xe9\xe1\xa5\x80\xff\xff\xff\xff\xea\xd1\x96\x80\xff\xff\xff\xff\xec\x14\x96\x00\xff\xff\xff\xff\xec\xba\xb3\x00\xff\xff\xff\xff\xed\xaa\xa4\x00\xff\xff\xff\xff\xee\x9a\x95\x00\xff\xff\xff\xff\xef\xd4Z\x00\xff\xff\xff\xff\xf0zw\x00\xff\xff\xff\xff\xf1\xb4<\x00\xff\xff\xff\xff\xf2ZY\x00\xff\xff\xff\xff\xf3\x94\x1e\x00\xff\xff\xff\xff\xf4:;\x00\xff\xff\xff\xff\xf5}:\x80\xff\xff\xff\xff\xf6\x1a\x1d\x00\x00\x00\x00\x00\x0d\xa4U\x80\x00\x00\x00\x00\x0e\x8b\x0c\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x0a\x80\x00\x00\x00\x00\x13M6\x00\x00\x00\x00\x00\x143\xec\x80\x00\x00\x00\x00\x15#\xdd\x80\x00\x00\x00\x00\x16\x13\xce\x80\x00\x00\x00\x00\x17\x03\xbf\x80\x00\x00\x00\x00\x17\xf3\xb0\x80\x00\x00\x00\x00\x18\xe3\xa1\x80\x00\x00\x00\x00\x19\xd3\x92\x80\x00\x00\x00\x00\x1a\xc3\x83\x80\x00\x00\x00\x00\x1b\xbc\xaf\x00\x00\x00\x00\x00\x1c\xac\xa0\x00\x00\x00\x00\x00\x1d\x9c\x91\x00\x00\x00\x00\x00\x1e\x8c\x82\x00\x00\x00\x00\x00\x1f|s\x00\x00\x00\x00\x00 ld\x00\x00\x00\x00\x00!\x5cU\x00\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x03\x02\x03\x02\x03\x02\x05\x04\x05\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x00\x00\x13\xb0\x00\x00\x00\x00\x13\xb0\x00\x04\x00\x00\x1c \x01\x08\x00\x00\x0e\x10\x00\x0d\x00\x00*0\x01\x11\x00\x00\x1c \x00\x16LMT\x00WMT\x00CEST\x00CET\x00EEST\x00EET\x00\x0aCET-1CEST,M3.5.0,M10.5.0/3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&S\x03\x09\xae\x05\x00\x00\xae\x05\x00\x00\x08\x00\x00\x00PortugalTZif2\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\x8d\x00\x00\x00\x06\x00\x00\x00\x1b\xff\xff\xff\xff^=\x0c\x1d\xff\xff\xff\xff\x92\xe6\x8e\x80\xff\xff\xff\xff\x9bKmp\xff\xff\xff\xff\x9b\xfe\xc7\x80\xff\xff\xff\xff\x9c\x9c\xedp\xff\xff\xff\xff\x9d\xc9\x83p\xff\xff\xff\xff\x9e\x7frp\xff\xff\xff\xff\x9f\xaa\xb6\xf0\xff\xff\xff\xff\xa0_Tp\xff\xff\xff\xff\xa1\x8b\xeap\xff\xff\xff\xff\xa2A\xd9p\xff\xff\xff\xff\xa3nop\xff\xff\xff\xff\xa4#\x0c\xf0\xff\xff\xff\xff\xa5O\xa2\xf0\xff\xff\xff\xff\xaa\x05\xefp\xff\xff\xff\xff\xaa\xf4\x8e\xf0\xff\xff\xff\xff\xad\xc9\xa7\xf0\xff\xff\xff\xff\xae\xa7#\xf0\xff\xff\xff\xff\xaf\xa0Op\xff\xff\xff\xff\xb0\x87\x05\xf0\xff\xff\xff\xff\xb1\x89k\xf0\xff\xff\xff\xff\xb2p\x22p\xff\xff\xff\xff\xb3r\x88p\xff\xff\xff\xff\xb4P\x04p\xff\xff\xff\xff\xb72Lp\xff\xff\xff\xff\xb8\x0f\xc8p\xff\xff\xff\xff\xb8\xff\xb9p\xff\xff\xff\xff\xb9\xef\xaap\xff\xff\xff\xff\xbc\xc8\xb7\xf0\xff\xff\xff\xff\xbd\xb8\xa8\xf0\xff\xff\xff\xff\xbe\x9f_p\xff\xff\xff\xff\xbf\x98\x8a\xf0\xff\xff\xff\xff\xc0\x9a\xf0\xf0\xff\xff\xff\xff\xc1xl\xf0\xff\xff\xff\xff\xc2h]\xf0\xff\xff\xff\xff\xc3XN\xf0\xff\xff\xff\xff\xc4?\x05p\xff\xff\xff\xff\xc580\xf0\xff\xff\xff\xff\xc6:\x96\xf0\xff\xff\xff\xff\xc7X\xacp\xff\xff\xff\xff\xc7\xd9\xdfp\xff\xff\xff\xff\xc9\x01/p\xff\xff\xff\xff\xc9\xf1 p\xff\xff\xff\xff\xca\xe2b\xf0\xff\xff\xff\xff\xcb\xb5R\xf0\xff\xff\xff\xff\xcb\xec\xa3\xe0\xff\xff\xff\xff\xcc\x80K\xe0\xff\xff\xff\xff\xcc\xdc\xa2\xf0\xff\xff\xff\xff\xcd\x954\xf0\xff\xff\xff\xff\xcd\xc3K`\xff\xff\xff\xff\xcer\xa2\xe0\xff\xff\xff\xff\xce\xc5\xbfp\xff\xff\xff\xff\xcfu\x16\xf0\xff\xff\xff\xff\xcf\xacg\xe0\xff\xff\xff\xff\xd0R\x84\xe0\xff\xff\xff\xff\xd0\xa5\xa1p\xff\xff\xff\xff\xd1T\xf8\xf0\xff\xff\xff\xff\xd1\x8cI\xe0\xff\xff\xff\xff\xd22f\xe0\xff\xff\xff\xff\xd2\x85\x83p\xff\xff\xff\xff\xd3Y\xc4\xf0\xff\xff\xff\xff\xd4I\xb5\xf0\xff\xff\xff\xff\xd59\xd1 \xff\xff\xff\xff\xd6)\xc2 \xff\xff\xff\xff\xd7\x19\xb3 \xff\xff\xff\xff\xd8\x09\xa4 \xff\xff\xff\xff\xd8\xf9\x95 \xff\xff\xff\xff\xd9\xe9\x86 \xff\xff\xff\xff\xda\xd9w \xff\xff\xff\xff\xdb\xc9h \xff\xff\xff\xff\xdc\xb9Y \xff\xff\xff\xff\xdd\xb2\x84\xa0\xff\xff\xff\xff\xde\xa2u\xa0\xff\xff\xff\xff\xdf\x92f\xa0\xff\xff\xff\xff\xe0\x82W\xa0\xff\xff\xff\xff\xe1rH\xa0\xff\xff\xff\xff\xe2b9\xa0\xff\xff\xff\xff\xe3R*\xa0\xff\xff\xff\xff\xe4B\x1b\xa0\xff\xff\xff\xff\xe52\x0c\xa0\xff\xff\xff\xff\xe6!\xfd\xa0\xff\xff\xff\xff\xe7\x1b) \xff\xff\xff\xff\xe8\x0b\x1a \xff\xff\xff\xff\xe8\xfb\x0b \xff\xff\xff\xff\xe9\xea\xfc \xff\xff\xff\xff\xea\xda\xed \xff\xff\xff\xff\xeb\xca\xde \xff\xff\xff\xff\xec\xba\xcf \xff\xff\xff\xff\xed\xaa\xc0 \xff\xff\xff\xff\xee\x9a\xb1 \xff\xff\xff\xff\xef\x8a\xa2 \xff\xff\xff\xff\xf0z\x93 \xff\xff\xff\xff\xf1j\x84 \xff\xff\xff\xff\xf2c\xaf\xa0\xff\xff\xff\xff\xf3S\xa0\xa0\xff\xff\xff\xff\xf4C\x91\xa0\xff\xff\xff\xff\xf53\x82\xa0\xff\xff\xff\xff\xf6#s\xa0\xff\xff\xff\xff\xf7\x13d\xa0\xff\xff\xff\xff\xf8\x03U\xa0\xff\xff\xff\xff\xf8\xf3F\xa0\x00\x00\x00\x00\x0c\xab*\x00\x00\x00\x00\x00\x0d\x9b\x1b\x00\x00\x00\x00\x00\x0e\x8b\x0c\x00\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x10t(\x80\x00\x00\x00\x00\x11d\x19\x80\x00\x00\x00\x00\x12T\x18\x90\x00\x00\x00\x00\x13C\xfb\x80\x00\x00\x00\x00\x143\xfa\x90\x00\x00\x00\x00\x15#\xeb\x90\x00\x00\x00\x00\x16\x13\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xbd\xa0\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x00\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\x03\x01\x02\x01\x03\x01\x02\x01\x03\x01\x02\x01\x03\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\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\x04\x05\x04\x05\x04\x05\x04\x01\xff\xff\xf7c\x00\x00\x00\x00\x0e\x10\x01\x04\x00\x00\x00\x00\x00\x09\x00\x00\x1c \x01\x0d\x00\x00\x0e\x10\x00\x12\x00\x00\x1c \x01\x16LMT\x00WEST\x00WET\x00WEMT\x00CET\x00CEST\x00\x0aWET0WEST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\x03\x00\x00\x00ROCTZif2\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\x10\xff\xff\xff\xfft\xce\xf0\x18\xff\xff\xff\xff\xc3UI\x80\xff\xff\xff\xff\xd2TY\x80\xff\xff\xff\xff\xd3\x8b{\x80\xff\xff\xff\xff\xd4B\xad\xf0\xff\xff\xff\xff\xd5E\x22\x00\xff\xff\xff\xff\xd6L\xbf\xf0\xff\xff\xff\xff\xd7<\xbf\x00\xff\xff\xff\xff\xd8\x06fp\xff\xff\xff\xff\xd9\x1d\xf2\x80\xff\xff\xff\xff\xd9\xe7\x99\xf0\xff\xff\xff\xff\xda\xff&\x00\xff\xff\xff\xff\xdb\xc8\xcdp\xff\xff\xff\xff\xdc\xe0Y\x80\xff\xff\xff\xff\xdd\xaa\x00\xf0\xff\xff\xff\xff\xders\x00\xff\xff\xff\xff\xdf\xb5dp\xff\xff\xff\xff\xe0|\x85\x00\xff\xff\xff\xff\xe1\x96\x97\xf0\xff\xff\xff\xff\xe2]\xb8\x80\xff\xff\xff\xff\xe3w\xcbp\xff\xff\xff\xff\xe4>\xec\x00\xff\xff\xff\xff\xe50 p\xff\xff\xff\xff\xe6!q\x00\xff\xff\xff\xff\xe7\x12\xa5p\xff\xff\xff\xff\xe8\x02\xa4\x80\xff\xff\xff\xff\xe8\xf3\xd8\xf0\xff\xff\xff\xff\xe9\xe3\xd8\x00\xff\xff\xff\xff\xea\xd5\x0cp\xff\xff\xff\xff\xeb\xc5\x0b\x80\xff\xff\xff\xff\xec\xb6?\xf0\xff\xff\xff\xff\xed\xf7\xfc\x00\xff\xff\xff\xff\xee\x98\xc4\xf0\xff\xff\xff\xff\xef\xd9/\x80\xff\xff\xff\xff\xf0y\xf8p\x00\x00\x00\x00\x07\xfcV\x00\x00\x00\x00\x00\x08\xed\x8ap\x00\x00\x00\x00\x09\xdd\x89\x80\x00\x00\x00\x00\x0a\xce\xbd\xf0\x00\x00\x00\x00\x11\xdb\xa1\x80\x00\x00\x00\x00\x12T\xddp\x01\x02\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x03\x01\x00\x00q\xe8\x00\x00\x00\x00p\x80\x00\x04\x00\x00~\x90\x00\x08\x00\x00~\x90\x01\x0cLMT\x00CST\x00JST\x00CDT\x00\x0aCST-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\x03\x00\x00\x00ROKTZif2\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\x1d\x00\x00\x00\x06\x00\x00\x00\x10\xff\xff\xff\xff\x8b\xd7\xf0x\xff\xff\xff\xff\x92\xe6\x16\xf8\xff\xff\xff\xff\xd2C'\xf0\xff\xff\xff\xff\xd7e\x8fp\xff\xff\xff\xff\xd7\xee\x9d`\xff\xff\xff\xff\xd8\xf8\xfap\xff\xff\xff\xff\xd9\xcd-\xe0\xff\xff\xff\xff\xda\xd7\x8a\xf0\xff\xff\xff\xff\xdb\xad\x0f\xe0\xff\xff\xff\xff\xdc\xe6\xe2\xf0\xff\xff\xff\xff\xdd\x8c\xf1\xe0\xff\xff\xff\xff\xe2O)\xf0\xff\xff\xff\xff\xe4k\xb7\xf8\xff\xff\xff\xff\xe5\x13\x18h\xff\xff\xff\xff\xe6b\x03x\xff\xff\xff\xff\xe7\x11L\xe8\xff\xff\xff\xff\xe8/px\xff\xff\xff\xff\xe8\xe7\xf4h\xff\xff\xff\xff\xea\x0fRx\xff\xff\xff\xff\xea\xc7\xd6h\xff\xff\xff\xff\xeb\xef4x\xff\xff\xff\xff\xec\xa7\xb8h\xff\xff\xff\xff\xed\xcf\x16x\xff\xff\xff\xff\xee\x87\x9ah\xff\xff\xff\xff\xf05qx\x00\x00\x00\x00 \xa3`\x90\x00\x00\x00\x00!ng\x90\x00\x00\x00\x00\x22\x83B\x90\x00\x00\x00\x00#NI\x90\x01\x02\x04\x03\x04\x03\x04\x03\x04\x03\x04\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x05\x01\x04\x03\x04\x03\x04\x00\x00w\x08\x00\x00\x00\x00w\x88\x00\x04\x00\x00~\x90\x00\x08\x00\x00\x8c\xa0\x01\x0c\x00\x00~\x90\x00\x04\x00\x00\x85\x98\x01\x0cLMT\x00KST\x00JST\x00KDT\x00\x0aKST-9\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x09\x00\x00\x00SingaporeTZif2\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\x08\x00\x00\x00\x08\x00\x00\x00 \xff\xff\xff\xff~6S\xa3\xff\xff\xff\xff\x86\x83\x85\xa3\xff\xff\xff\xff\xbagN\x90\xff\xff\xff\xff\xc0\x0a\xe4`\xff\xff\xff\xff\xca\xb3\xe5`\xff\xff\xff\xff\xcb\x91_\x08\xff\xff\xff\xff\xd2Hm\xf0\x00\x00\x00\x00\x16\x91\xee\x00\x01\x02\x03\x04\x05\x06\x05\x07\x00\x00a]\x00\x00\x00\x00a]\x00\x04\x00\x00bp\x00\x08\x00\x00g \x01\x0c\x00\x00g \x00\x0c\x00\x00ix\x00\x12\x00\x00~\x90\x00\x18\x00\x00p\x80\x00\x1cLMT\x00SMT\x00+07\x00+0720\x00+0730\x00+09\x00+08\x00\x0a<+08>-8\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07W\x10\xd1\xb0\x04\x00\x00\xb0\x04\x00\x00\x06\x00\x00\x00TurkeyTZif2\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\x00s\x00\x00\x00\x06\x00\x00\x00\x19\xff\xff\xff\xffV\xb6\xc8\xd8\xff\xff\xff\xff\x90\x8b\xf5\x98\xff\xff\xff\xff\x9b\x0c\x17`\xff\xff\xff\xff\x9b\xd5\xbe\xd0\xff\xff\xff\xff\xa2ec\xe0\xff\xff\xff\xff\xa3{\x82P\xff\xff\xff\xff\xa4N\x80`\xff\xff\xff\xff\xa5?\xb4\xd0\xff\xff\xff\xff\xa6%'\xe0\xff\xff\xff\xff\xa7'\x7f\xd0\xff\xff\xff\xff\xaa((`\xff\xff\xff\xff\xaa\xe1\xfd\xd0\xff\xff\xff\xff\xab\xf9\x89\xe0\xff\xff\xff\xff\xac\xc31P\xff\xff\xff\xff\xc8\x81?\xe0\xff\xff\xff\xff\xc9\x01\x13P\xff\xff\xff\xff\xc9J\xf5`\xff\xff\xff\xff\xca\xce\x80P\xff\xff\xff\xff\xcb\xcb\xae`\xff\xff\xff\xff\xd2k\x09P\xff\xff\xff\xff\xd3\xa29`\xff\xff\xff\xff\xd4C\x02P\xff\xff\xff\xff\xd5L\x0d\xe0\xff\xff\xff\xff\xd6){\xd0\xff\xff\xff\xff\xd7+\xef\xe0\xff\xff\xff\xff\xd8\x09]\xd0\xff\xff\xff\xff\xd9\x02\x97`\xff\xff\xff\xff\xd9\xe9?\xd0\xff\xff\xff\xff\xda\xeb\xb3\xe0\xff\xff\xff\xff\xdb\xd2\x5cP\xff\xff\xff\xff\xdc\xd4\xd0`\xff\xff\xff\xff\xdd\xb2>P\xff\xff\xff\xff\xf1\xf4\xb9`\xff\xff\xff\xff\xf4b\xefP\xff\xff\xff\xff\xf5h\x06`\xff\xff\xff\xff\xf6\x1f8\xd0\x00\x00\x00\x00\x06n\x93p\x00\x00\x00\x00\x079\x9ap\x00\x00\x00\x00\x07\xfbu\x00\x00\x00\x00\x00\x09\x19|p\x00\x00\x00\x00\x09\xd0\xcb\x00\x00\x00\x00\x00\x0a\xf9^p\x00\x00\x00\x00\x0b\xb1\xfe\x80\x00\x00\x00\x00\x0c\xd9@p\x00\x00\x00\x00\x0d\xa4U\x80\x00\x00\x00\x00\x0e\xa6\xadp\x00\x00\x00\x00\x0f\x847\x80\x00\x00\x00\x00\x0f\xf8\x11P\x00\x00\x00\x00\x19\x89\xb0p\x00\x00\x00\x00\x19\xdc\xb0\xe0\x00\x00\x00\x00\x1b\xe6\xd0\xf0\x00\x00\x00\x00\x1c\xc6\xef\xf0\x00\x00\x00\x00\x1d\x9b1p\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x09p\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x8b\x83\xf0\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\x07p\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xc9\x90\x00\x00\x00\x00G#\xdf\x10\x00\x00\x00\x00G\xee\xe6\x10\x00\x00\x00\x00I\x03\xc1\x10\x00\x00\x00\x00I\xce\xc8\x10\x00\x00\x00\x00J\xe3\xa3\x10\x00\x00\x00\x00K\xae\xaa\x10\x00\x00\x00\x00L\xcc\xbf\x90\x00\x00\x00\x00M\x8f\xdd\x90\x00\x00\x00\x00N\xac\xa1\x90\x00\x00\x00\x00Onn\x10\x00\x00\x00\x00P\x8c\x83\x90\x00\x00\x00\x00QW\x8a\x90\x00\x00\x00\x00Rle\x90\x00\x00\x00\x00S8\xbe\x10\x00\x00\x00\x00TLG\x90\x00\x00\x00\x00U\x17N\x90\x00\x00\x00\x00V>\x9e\x90\x00\x00\x00\x00V\xf70\x90\x00\x00\x00\x00W\xcf.P\x01\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x05\x04\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x03\x02\x04\x00\x00\x1b(\x00\x00\x00\x00\x1bh\x00\x04\x00\x00*0\x01\x08\x00\x00\x1c \x00\x0d\x00\x00*0\x00\x11\x00\x008@\x01\x15LMT\x00IMT\x00EEST\x00EET\x00+03\x00+04\x00\x0a<+03>-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00UCTTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\x0aUTC0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\x09\x00\x00\x00US/AlaskaTZif2\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\x00T\x00\x00\x00\x0a\x00\x00\x00(\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87AH\xff\xff\xff\xff\xcb\x896\xc0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aB0\xff\xff\xff\xff\xfa\xd2G\xa0\xff\xff\xff\xff\xfe\xb8c@\xff\xff\xff\xff\xff\xa8F0\x00\x00\x00\x00\x00\x98E@\x00\x00\x00\x00\x01\x88(0\x00\x00\x00\x00\x02x'@\x00\x00\x00\x00\x03qD\xb0\x00\x00\x00\x00\x04aC\xc0\x00\x00\x00\x00\x05Q&\xb0\x00\x00\x00\x00\x06A%\xc0\x00\x00\x00\x00\x071\x08\xb0\x00\x00\x00\x00\x07\x8d_\xc0\x00\x00\x00\x00\x09\x10\xea\xb0\x00\x00\x00\x00\x09\xad\xdb@\x00\x00\x00\x00\x0a\xf0\xcc\xb0\x00\x00\x00\x00\x0b\xe0\xcb\xc0\x00\x00\x00\x00\x0c\xd9\xe90\x00\x00\x00\x00\x0d\xc0\xad\xc0\x00\x00\x00\x00\x0e\xb9\xcb0\x00\x00\x00\x00\x0f\xa9\xca@\x00\x00\x00\x00\x10\x99\xad0\x00\x00\x00\x00\x11\x89\xac@\x00\x00\x00\x00\x12y\x8f0\x00\x00\x00\x00\x13i\x8e@\x00\x00\x00\x00\x14Yq0\x00\x00\x00\x00\x15Ip@\x00\x00\x00\x00\x169S0\x00\x00\x00\x00\x17)R@\x00\x00\x00\x00\x18\x22o\xb0\x00\x00\x00\x00\x19\x094@\x00\x00\x00\x00\x1a\x02Q\xb0\x00\x00\x00\x00\x1a+\x14\x10\x00\x00\x00\x00\x1a\xf2B\xb0\x00\x00\x00\x00\x1b\xe2%\xa0\x00\x00\x00\x00\x1c\xd2$\xb0\x00\x00\x00\x00\x1d\xc2\x07\xa0\x00\x00\x00\x00\x1e\xb2\x06\xb0\x00\x00\x00\x00\x1f\xa1\xe9\xa0\x00\x00\x00\x00 v90\x00\x00\x00\x00!\x81\xcb\xa0\x00\x00\x00\x00\x22V\x1b0\x00\x00\x00\x00#j\xe8 \x00\x00\x00\x00$5\xfd0\x00\x00\x00\x00%J\xca \x00\x00\x00\x00&\x15\xdf0\x00\x00\x00\x00'*\xac \x00\x00\x00\x00'\xfe\xfb\xb0\x00\x00\x00\x00)\x0a\x8e \x00\x00\x00\x00)\xde\xdd\xb0\x00\x00\x00\x00*\xeap \x00\x00\x00\x00+\xbe\xbf\xb0\x00\x00\x00\x00,\xd3\x8c\xa0\x00\x00\x00\x00-\x9e\xa1\xb0\x00\x00\x00\x00.\xb3n\xa0\x00\x00\x00\x00/~\x83\xb0\x00\x00\x00\x000\x93P\xa0\x00\x00\x00\x001g\xa00\x00\x00\x00\x002s2\xa0\x00\x00\x00\x003G\x820\x00\x00\x00\x004S\x14\xa0\x00\x00\x00\x005'd0\x00\x00\x00\x0062\xf6\xa0\x00\x00\x00\x007\x07F0\x00\x00\x00\x008\x1c\x13 \x00\x00\x00\x008\xe7(0\x00\x00\x00\x009\xfb\xf5 \x00\x00\x00\x00:\xc7\x0a0\x00\x00\x00\x00;\xdb\xd7 \x00\x00\x00\x00<\xb0&\xb0\x00\x00\x00\x00=\xbb\xb9 \x00\x00\x00\x00>\x90\x08\xb0\x00\x00\x00\x00?\x9b\x9b \x00\x00\x00\x00@o\xea\xb0\x00\x00\x00\x00A\x84\xb7\xa0\x00\x00\x00\x00BO\xcc\xb0\x00\x00\x00\x00Cd\x99\xa0\x00\x00\x00\x00D/\xae\xb0\x00\x00\x00\x00ED{\xa0\x00\x00\x00\x00E\xf3\xe10\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x07\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x00\x00\xc4\xf8\x00\x00\xff\xffsx\x00\x00\xff\xffs`\x00\x04\xff\xff\x81p\x01\x08\xff\xff\x81p\x01\x0c\xff\xffs`\x00\x10\xff\xff\x81p\x01\x15\xff\xff\x81p\x00\x1a\xff\xff\x8f\x80\x01\x1e\xff\xff\x81p\x00#LMT\x00AST\x00AWT\x00APT\x00AHST\x00AHDT\x00YST\x00AKDT\x00AKST\x00\x0aAKST9AKDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\x0b\x00\x00\x00US/AleutianTZif2\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\x00T\x00\x00\x00\x0a\x00\x00\x00!\xff\xff\xff\xff?\xc2\xfd\xd1\xff\xff\xff\xff}\x87Z^\xff\xff\xff\xff\xcb\x89D\xd0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aP@\xff\xff\xff\xff\xfa\xd2U\xb0\xff\xff\xff\xff\xfe\xb8qP\xff\xff\xff\xff\xff\xa8T@\x00\x00\x00\x00\x00\x98SP\x00\x00\x00\x00\x01\x886@\x00\x00\x00\x00\x02x5P\x00\x00\x00\x00\x03qR\xc0\x00\x00\x00\x00\x04aQ\xd0\x00\x00\x00\x00\x05Q4\xc0\x00\x00\x00\x00\x06A3\xd0\x00\x00\x00\x00\x071\x16\xc0\x00\x00\x00\x00\x07\x8dm\xd0\x00\x00\x00\x00\x09\x10\xf8\xc0\x00\x00\x00\x00\x09\xad\xe9P\x00\x00\x00\x00\x0a\xf0\xda\xc0\x00\x00\x00\x00\x0b\xe0\xd9\xd0\x00\x00\x00\x00\x0c\xd9\xf7@\x00\x00\x00\x00\x0d\xc0\xbb\xd0\x00\x00\x00\x00\x0e\xb9\xd9@\x00\x00\x00\x00\x0f\xa9\xd8P\x00\x00\x00\x00\x10\x99\xbb@\x00\x00\x00\x00\x11\x89\xbaP\x00\x00\x00\x00\x12y\x9d@\x00\x00\x00\x00\x13i\x9cP\x00\x00\x00\x00\x14Y\x7f@\x00\x00\x00\x00\x15I~P\x00\x00\x00\x00\x169a@\x00\x00\x00\x00\x17)`P\x00\x00\x00\x00\x18\x22}\xc0\x00\x00\x00\x00\x19\x09BP\x00\x00\x00\x00\x1a\x02_\xc0\x00\x00\x00\x00\x1a+\x22 \x00\x00\x00\x00\x1a\xf2P\xc0\x00\x00\x00\x00\x1b\xe23\xb0\x00\x00\x00\x00\x1c\xd22\xc0\x00\x00\x00\x00\x1d\xc2\x15\xb0\x00\x00\x00\x00\x1e\xb2\x14\xc0\x00\x00\x00\x00\x1f\xa1\xf7\xb0\x00\x00\x00\x00 vG@\x00\x00\x00\x00!\x81\xd9\xb0\x00\x00\x00\x00\x22V)@\x00\x00\x00\x00#j\xf60\x00\x00\x00\x00$6\x0b@\x00\x00\x00\x00%J\xd80\x00\x00\x00\x00&\x15\xed@\x00\x00\x00\x00'*\xba0\x00\x00\x00\x00'\xff\x09\xc0\x00\x00\x00\x00)\x0a\x9c0\x00\x00\x00\x00)\xde\xeb\xc0\x00\x00\x00\x00*\xea~0\x00\x00\x00\x00+\xbe\xcd\xc0\x00\x00\x00\x00,\xd3\x9a\xb0\x00\x00\x00\x00-\x9e\xaf\xc0\x00\x00\x00\x00.\xb3|\xb0\x00\x00\x00\x00/~\x91\xc0\x00\x00\x00\x000\x93^\xb0\x00\x00\x00\x001g\xae@\x00\x00\x00\x002s@\xb0\x00\x00\x00\x003G\x90@\x00\x00\x00\x004S\x22\xb0\x00\x00\x00\x005'r@\x00\x00\x00\x0063\x04\xb0\x00\x00\x00\x007\x07T@\x00\x00\x00\x008\x1c!0\x00\x00\x00\x008\xe76@\x00\x00\x00\x009\xfc\x030\x00\x00\x00\x00:\xc7\x18@\x00\x00\x00\x00;\xdb\xe50\x00\x00\x00\x00<\xb04\xc0\x00\x00\x00\x00=\xbb\xc70\x00\x00\x00\x00>\x90\x16\xc0\x00\x00\x00\x00?\x9b\xa90\x00\x00\x00\x00@o\xf8\xc0\x00\x00\x00\x00A\x84\xc5\xb0\x00\x00\x00\x00BO\xda\xc0\x00\x00\x00\x00Cd\xa7\xb0\x00\x00\x00\x00D/\xbc\xc0\x00\x00\x00\x00ED\x89\xb0\x00\x00\x00\x00E\xf3\xef@\x01\x02\x03\x04\x02\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x07\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x09\x08\x00\x00\xab\xe2\x00\x00\xff\xffZb\x00\x00\xff\xffeP\x00\x04\xff\xffs`\x01\x08\xff\xffs`\x01\x0c\xff\xffeP\x00\x10\xff\xffs`\x01\x14\xff\xffs`\x00\x18\xff\xff\x81p\x01\x1d\xff\xffs`\x00\x19LMT\x00NST\x00NWT\x00NPT\x00BST\x00BDT\x00AHST\x00HDT\x00\x0aHST10HDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\xb8\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0a\x00\x00\x00US/ArizonaTZif2\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\x0b\x00\x00\x00\x04\x00\x00\x00\x10\xff\xff\xff\xff^\x04\x0c\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xcf\x17\xdf\x1c\xff\xff\xff\xff\xcf\x8f\xe5\xac\xff\xff\xff\xff\xd0\x81\x1a\x1c\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\x02\x01\x02\x01\x02\x03\x02\x03\x02\x01\x02\xff\xff\x96\xee\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0cLMT\x00MDT\x00MST\x00MWT\x00\x0aMST7\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xdc\xa9=\xda\x06\x00\x00\xda\x06\x00\x00\x0a\x00\x00\x00US/CentralTZif2\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\xaf\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xa2\xcbt\x00\xff\xff\xff\xff\xa3\x83\xf7\xf0\xff\xff\xff\xff\xa4E\xd2\x80\xff\xff\xff\xff\xa5c\xd9\xf0\xff\xff\xff\xff\xa6S\xd9\x00\xff\xff\xff\xff\xa7\x15\x97p\xff\xff\xff\xff\xa83\xbb\x00\xff\xff\xff\xff\xa8\xfe\xb3\xf0\xff\xff\xff\xff\xaa\x13\x9d\x00\xff\xff\xff\xff\xaa\xde\x95\xf0\xff\xff\xff\xff\xab\xf3\x7f\x00\xff\xff\xff\xff\xac\xbew\xf0\xff\xff\xff\xff\xad\xd3a\x00\xff\xff\xff\xff\xae\x9eY\xf0\xff\xff\xff\xff\xaf\xb3C\x00\xff\xff\xff\xff\xb0~;\xf0\xff\xff\xff\xff\xb1\x9c_\x80\xff\xff\xff\xff\xb2gXp\xff\xff\xff\xff\xb3|A\x80\xff\xff\xff\xff\xb4G:p\xff\xff\xff\xff\xb5\x5c#\x80\xff\xff\xff\xff\xb6'\x1cp\xff\xff\xff\xff\xb7<\x05\x80\xff\xff\xff\xff\xb8\x06\xfep\xff\xff\xff\xff\xb9\x1b\xe7\x80\xff\xff\xff\xff\xb9\xe6\xe0p\xff\xff\xff\xff\xbb\x05\x04\x00\xff\xff\xff\xff\xbb\xc6\xc2p\xff\xff\xff\xff\xbc\xe4\xe6\x00\xff\xff\xff\xff\xbd\xaf\xde\xf0\xff\xff\xff\xff\xbe\xc4\xc8\x00\xff\xff\xff\xff\xbf\x8f\xc0\xf0\xff\xff\xff\xff\xc0Z\xd6\x00\xff\xff\xff\xff\xc1\xb0<p\xff\xff\xff\xff\xc2\x84\x8c\x00\xff\xff\xff\xff\xc3O\x84\xf0\xff\xff\xff\xff\xc4dn\x00\xff\xff\xff\xff\xc5/f\xf0\xff\xff\xff\xff\xc6M\x8a\x80\xff\xff\xff\xff\xc7\x0fH\xf0\xff\xff\xff\xff\xc8-l\x80\xff\xff\xff\xff\xc8\xf8ep\xff\xff\xff\xff\xca\x0dN\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe9\x17\x00\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xf6\xe2\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\xc2\x80\xff\xff\xff\xff\xf2\x7f\xa5p\xff\xff\xff\xff\xf3o\xa4\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xf5O\x86\x80\xff\xff\xff\xff\xf6?ip\xff\xff\xff\xff\xf7/h\x80\xff\xff\xff\xff\xf8(\x85\xf0\xff\xff\xff\xff\xf9\x0fJ\x80\xff\xff\xff\xff\xfa\x08g\xf0\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x0d\xf0\x00\x00\x00\x00\x00\x98\x0d\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x0cp\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xd0p\x00\x00\x00\x00\x07\x8d'\x80\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x09\xad\xa3\x00\x00\x00\x00\x00\x0a\xf0\x94p\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xb0\xf0\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x227p\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ac\xf0\x00\x00\x00\x00)\xde\xb3\x80\x00\x00\x00\x00*\xeaE\xf0\x00\x00\x00\x00+\xbe\x95\x80\x00\x00\x00\x00,\xd3bp\x00\x00\x00\x00-\x9ew\x80\x00\x00\x00\x00.\xb3Dp\x00\x00\x00\x00/~Y\x80\x00\x00\x00\x000\x93&p\x00\x00\x00\x001gv\x00\x00\x00\x00\x002s\x08p\x00\x00\x00\x003GX\x00\x00\x00\x00\x004R\xeap\x00\x00\x00\x005':\x00\x00\x00\x00\x0062\xccp\x00\x00\x00\x007\x07\x1c\x00\x00\x00\x00\x008\x1b\xe8\xf0\x00\x00\x00\x008\xe6\xfe\x00\x00\x00\x00\x009\xfb\xca\xf0\x00\x00\x00\x00:\xc6\xe0\x00\x00\x00\x00\x00;\xdb\xac\xf0\x00\x00\x00\x00<\xaf\xfc\x80\x00\x00\x00\x00=\xbb\x8e\xf0\x00\x00\x00\x00>\x8f\xde\x80\x00\x00\x00\x00?\x9bp\xf0\x00\x00\x00\x00@o\xc0\x80\x00\x00\x00\x00A\x84\x8dp\x00\x00\x00\x00BO\xa2\x80\x00\x00\x00\x00Cdop\x00\x00\x00\x00D/\x84\x80\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\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\x03\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x04\x05\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xad\xd4\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x00\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x01\x14LMT\x00CDT\x00CST\x00EST\x00CWT\x00CPT\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x0f\x00\x00\x00US/East-IndianaTZif2\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\x07\x00\x00\x00\x1c\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcaW\x22\x80\xff\xff\xff\xff\xca\xd8Gp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd3u\xf3\x00\xff\xff\xff\xff\xd4@\xeb\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x02\x01\x02\x01\x02\x01\x02\x03\x04\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x05\x02\x05\x06\x05\x06\x05\x06\x05\x06\xff\xff\xaf:\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14\xff\xff\xc7\xc0\x01\x18LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00EDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\x0a\x00\x00\x00US/EasternTZif2\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\xaf\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x03\xf0\x90\xff\xff\xff\xff\x9e\xa6\x1ep\xff\xff\xff\xff\x9f\xba\xeb`\xff\xff\xff\xff\xa0\x86\x00p\xff\xff\xff\xff\xa1\x9a\xcd`\xff\xff\xff\xff\xa2e\xe2p\xff\xff\xff\xff\xa3\x83\xe9\xe0\xff\xff\xff\xff\xa4j\xaep\xff\xff\xff\xff\xa55\xa7`\xff\xff\xff\xff\xa6S\xca\xf0\xff\xff\xff\xff\xa7\x15\x89`\xff\xff\xff\xff\xa83\xac\xf0\xff\xff\xff\xff\xa8\xfe\xa5\xe0\xff\xff\xff\xff\xaa\x13\x8e\xf0\xff\xff\xff\xff\xaa\xde\x87\xe0\xff\xff\xff\xff\xab\xf3p\xf0\xff\xff\xff\xff\xac\xbei\xe0\xff\xff\xff\xff\xad\xd3R\xf0\xff\xff\xff\xff\xae\x9eK\xe0\xff\xff\xff\xff\xaf\xb34\xf0\xff\xff\xff\xff\xb0~-\xe0\xff\xff\xff\xff\xb1\x9cQp\xff\xff\xff\xff\xb2gJ`\xff\xff\xff\xff\xb3|3p\xff\xff\xff\xff\xb4G,`\xff\xff\xff\xff\xb5\x5c\x15p\xff\xff\xff\xff\xb6'\x0e`\xff\xff\xff\xff\xb7;\xf7p\xff\xff\xff\xff\xb8\x06\xf0`\xff\xff\xff\xff\xb9\x1b\xd9p\xff\xff\xff\xff\xb9\xe6\xd2`\xff\xff\xff\xff\xbb\x04\xf5\xf0\xff\xff\xff\xff\xbb\xc6\xb4`\xff\xff\xff\xff\xbc\xe4\xd7\xf0\xff\xff\xff\xff\xbd\xaf\xd0\xe0\xff\xff\xff\xff\xbe\xc4\xb9\xf0\xff\xff\xff\xff\xbf\x8f\xb2\xe0\xff\xff\xff\xff\xc0\xa4\x9b\xf0\xff\xff\xff\xff\xc1o\x94\xe0\xff\xff\xff\xff\xc2\x84}\xf0\xff\xff\xff\xff\xc3Ov\xe0\xff\xff\xff\xff\xc4d_\xf0\xff\xff\xff\xff\xc5/X\xe0\xff\xff\xff\xff\xc6M|p\xff\xff\xff\xff\xc7\x0f:\xe0\xff\xff\xff\xff\xc8-^p\xff\xff\xff\xff\xc8\xf8W`\xff\xff\xff\xff\xca\x0d@p\xff\xff\xff\xff\xca\xd89`\xff\xff\xff\xff\xcb\x88\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd3u\xe4\xf0\xff\xff\xff\xff\xd4@\xdd\xe0\xff\xff\xff\xff\xd5U\xc6\xf0\xff\xff\xff\xff\xd6 \xbf\xe0\xff\xff\xff\xff\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xd9\x15\x8a\xf0\xff\xff\xff\xff\xd9\xe0\x83\xe0\xff\xff\xff\xff\xda\xfe\xa7p\xff\xff\xff\xff\xdb\xc0e\xe0\xff\xff\xff\xff\xdc\xde\x89p\xff\xff\xff\xff\xdd\xa9\x82`\xff\xff\xff\xff\xde\xbekp\xff\xff\xff\xff\xdf\x89d`\xff\xff\xff\xff\xe0\x9eMp\xff\xff\xff\xff\xe1iF`\xff\xff\xff\xff\xe2~/p\xff\xff\xff\xff\xe3I(`\xff\xff\xff\xff\xe4^\x11p\xff\xff\xff\xff\xe5W.\xe0\xff\xff\xff\xff\xe6G-\xf0\xff\xff\xff\xff\xe77\x10\xe0\xff\xff\xff\xff\xe8'\x0f\xf0\xff\xff\xff\xff\xe9\x16\xf2\xe0\xff\xff\xff\xff\xea\x06\xf1\xf0\xff\xff\xff\xff\xea\xf6\xd4\xe0\xff\xff\xff\xff\xeb\xe6\xd3\xf0\xff\xff\xff\xff\xec\xd6\xb6\xe0\xff\xff\xff\xff\xed\xc6\xb5\xf0\xff\xff\xff\xff\xee\xbf\xd3`\xff\xff\xff\xff\xef\xaf\xd2p\xff\xff\xff\xff\xf0\x9f\xb5`\xff\xff\xff\xff\xf1\x8f\xb4p\xff\xff\xff\xff\xf2\x7f\x97`\xff\xff\xff\xff\xf3o\x96p\xff\xff\xff\xff\xf4_y`\xff\xff\xff\xff\xf5Oxp\xff\xff\xff\xff\xf6?[`\xff\xff\xff\xff\xf7/Zp\xff\xff\xff\xff\xf8(w\xe0\xff\xff\xff\xff\xf9\x0f<p\xff\xff\xff\xff\xfa\x08Y\xe0\xff\xff\xff\xff\xfa\xf8X\xf0\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\xff\xff\xff\xff\xfe\xb8\x1c\xf0\xff\xff\xff\xff\xff\xa7\xff\xe0\x00\x00\x00\x00\x00\x97\xfe\xf0\x00\x00\x00\x00\x01\x87\xe1\xe0\x00\x00\x00\x00\x02w\xe0\xf0\x00\x00\x00\x00\x03p\xfe`\x00\x00\x00\x00\x04`\xfdp\x00\x00\x00\x00\x05P\xe0`\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x07\x8d\x19p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x09\xad\x94\xf0\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\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\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\xba\x9e\x00\x00\xff\xff\xc7\xc0\x01\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x01\x10LMT\x00EDT\x00EST\x00EWT\x00EPT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x09\x00\x00\x00US/HawaiiTZif2\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\x07\x00\x00\x00\x06\x00\x00\x00\x14\xff\xff\xff\xfft\xe0p\xbe\xff\xff\xff\xff\xbb\x05CH\xff\xff\xff\xff\xbb!qX\xff\xff\xff\xff\xcb\x89=\xc8\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2aI8\xff\xff\xff\xff\xd5\x8dsH\x01\x02\x01\x03\x04\x01\x05\xff\xffl\x02\x00\x00\xff\xfflX\x00\x04\xff\xffzh\x01\x08\xff\xffzh\x01\x0c\xff\xffzh\x01\x10\xff\xffs`\x00\x04LMT\x00HST\x00HDT\x00HWT\x00HPT\x00\x0aHST10\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x11\x00\x00\x00US/Indiana-StarkeTZif2\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\x06\x00\x00\x00\x18\xff\xff\xff\xff^\x03\xfe\xa0\xff\xff\xff\xff\x9e\xa6,\x80\xff\xff\xff\xff\x9f\xba\xf9p\xff\xff\xff\xff\xa0\x86\x0e\x80\xff\xff\xff\xff\xa1\x9a\xdbp\xff\xff\xff\xff\xcb\x88\xfe\x80\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x09\xf0\xff\xff\xff\xff\xd5U\xd5\x00\xff\xff\xff\xff\xd6 \xcd\xf0\xff\xff\xff\xff\xd75\xb7\x00\xff\xff\xff\xff\xd8\x00\xaf\xf0\xff\xff\xff\xff\xd9\x15\x99\x00\xff\xff\xff\xff\xd9\xe0\x91\xf0\xff\xff\xff\xff\xda\xfe\xb5\x80\xff\xff\xff\xff\xdb\xc0s\xf0\xff\xff\xff\xff\xdc\xde\x97\x80\xff\xff\xff\xff\xdd\xa9\x90p\xff\xff\xff\xff\xde\xbey\x80\xff\xff\xff\xff\xdf\x89rp\xff\xff\xff\xff\xe0\x9e[\x80\xff\xff\xff\xff\xe1iTp\xff\xff\xff\xff\xe2~=\x80\xff\xff\xff\xff\xe3I6p\xff\xff\xff\xff\xe4^\x1f\x80\xff\xff\xff\xff\xe5W<\xf0\xff\xff\xff\xff\xe6G<\x00\xff\xff\xff\xff\xe77\x1e\xf0\xff\xff\xff\xff\xe8'\x1e\x00\xff\xff\xff\xff\xe8\xf2\x16\xf0\xff\xff\xff\xff\xea\x07\x00\x00\xff\xff\xff\xff\xea\xd1\xf8\xf0\xff\xff\xff\xff\xeb\xe6\xe2\x00\xff\xff\xff\xff\xec\xd6\xc4\xf0\xff\xff\xff\xff\xed\xc6\xc4\x00\xff\xff\xff\xff\xee\xbf\xe1p\xff\xff\xff\xff\xef\xaf\xe0\x80\xff\xff\xff\xff\xf0\x9f\xc3p\xff\xff\xff\xff\xf1\x8f\xc2\x80\xff\xff\xff\xff\xf4_\x87p\xff\xff\xff\xff\xfa\xf8g\x00\xff\xff\xff\xff\xfb\xe8I\xf0\xff\xff\xff\xff\xfc\xd8I\x00\xff\xff\xff\xff\xfd\xc8+\xf0\xff\xff\xff\xff\xfe\xb8+\x00\xff\xff\xff\xff\xff\xa8\x0d\xf0\x00\x00\x00\x00\x00\x98\x0d\x00\x00\x00\x00\x00\x01\x87\xef\xf0\x00\x00\x00\x00\x02w\xef\x00\x00\x00\x00\x00\x03q\x0cp\x00\x00\x00\x00\x04a\x0b\x80\x00\x00\x00\x00\x05P\xeep\x00\x00\x00\x00\x06@\xed\x80\x00\x00\x00\x00\x070\xd0p\x00\x00\x00\x00\x07\x8d'\x80\x00\x00\x00\x00\x09\x10\xb2p\x00\x00\x00\x00\x09\xad\xa3\x00\x00\x00\x00\x00\x0a\xf0\x94p\x00\x00\x00\x00\x0b\xe0\x93\x80\x00\x00\x00\x00\x0c\xd9\xb0\xf0\x00\x00\x00\x00\x0d\xc0u\x80\x00\x00\x00\x00\x0e\xb9\x92\xf0\x00\x00\x00\x00\x0f\xa9\x92\x00\x00\x00\x00\x00\x10\x99t\xf0\x00\x00\x00\x00\x11\x89t\x00\x00\x00\x00\x00\x12yV\xf0\x00\x00\x00\x00\x13iV\x00\x00\x00\x00\x00\x14Y8\xf0\x00\x00\x00\x00\x15I8\x00\x00\x00\x00\x00\x169\x1a\xf0\x00\x00\x00\x00\x17)\x1a\x00\x00\x00\x00\x00\x18\x227p\x00\x00\x00\x00\x19\x08\xfc\x00\x00\x00\x00\x00\x1a\x02\x19p\x00\x00\x00\x00\x1a\xf2\x18\x80\x00\x00\x00\x00\x1b\xe1\xfbp\x00\x00\x00\x00\x1c\xd1\xfa\x80\x00\x00\x00\x00\x1d\xc1\xddp\x00\x00\x00\x00\x1e\xb1\xdc\x80\x00\x00\x00\x00\x1f\xa1\xbfp\x00\x00\x00\x00 v\x0f\x00\x00\x00\x00\x00!\x81\xa1p\x00\x00\x00\x00\x22U\xf1\x00\x00\x00\x00\x00#j\xbd\xf0\x00\x00\x00\x00$5\xd3\x00\x00\x00\x00\x00%J\x9f\xf0\x00\x00\x00\x00&\x15\xb5\x00\x00\x00\x00\x00'*\x81\xf0\x00\x00\x00\x00'\xfe\xd1\x80\x00\x00\x00\x00)\x0ac\xf0\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDQp\x00\x00\x00\x00E\xf3\xb7\x00\x02\x01\x02\x01\x02\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\x05\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\x05\x01\x02\x01\xff\xff\xae\xca\x00\x00\xff\xff\xb9\xb0\x01\x04\xff\xff\xab\xa0\x00\x08\xff\xff\xb9\xb0\x01\x0c\xff\xff\xb9\xb0\x01\x10\xff\xff\xb9\xb0\x00\x14LMT\x00CDT\x00CST\x00CWT\x00CPT\x00EST\x00\x0aCST6CDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\x0b\x00\x00\x00US/MichiganTZif2\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\x00P\x00\x00\x00\x06\x00\x00\x00\x18\xff\xff\xff\xff\x85\xbd\x22[\xff\xff\xff\xff\x99<\x94\x00\xff\xff\xff\xff\xcb\x88\xf0p\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2`\xfb\xe0\xff\xff\xff\xff\xd75\xa8\xf0\xff\xff\xff\xff\xd8\x00\xa1\xe0\xff\xff\xff\xff\xfb3\x90\x8c\xff\xff\xff\xff\xfb\xe8;\xe0\xff\xff\xff\xff\xfc\xd8:\xf0\xff\xff\xff\xff\xfd\xc8\x1d\xe0\x00\x00\x00\x00\x06@\xdfp\x00\x00\x00\x00\x070\xc2`\x00\x00\x00\x00\x07\x8d\x19p\x00\x00\x00\x00\x09\x10\xa4`\x00\x00\x00\x00\x0a\x00\xa3p\x00\x00\x00\x00\x0a\xf0\x86`\x00\x00\x00\x00\x0b\xe0\x85p\x00\x00\x00\x00\x0c\xd9\xa2\xe0\x00\x00\x00\x00\x0d\xc0gp\x00\x00\x00\x00\x0e\xb9\x84\xe0\x00\x00\x00\x00\x0f\xa9\x83\xf0\x00\x00\x00\x00\x10\x99f\xe0\x00\x00\x00\x00\x11\x89e\xf0\x00\x00\x00\x00\x12yH\xe0\x00\x00\x00\x00\x13iG\xf0\x00\x00\x00\x00\x14Y*\xe0\x00\x00\x00\x00\x15I)\xf0\x00\x00\x00\x00\x169\x0c\xe0\x00\x00\x00\x00\x17)\x0b\xf0\x00\x00\x00\x00\x18\x22)`\x00\x00\x00\x00\x19\x08\xed\xf0\x00\x00\x00\x00\x1a\x02\x0b`\x00\x00\x00\x00\x1a\xf2\x0ap\x00\x00\x00\x00\x1b\xe1\xed`\x00\x00\x00\x00\x1c\xd1\xecp\x00\x00\x00\x00\x1d\xc1\xcf`\x00\x00\x00\x00\x1e\xb1\xcep\x00\x00\x00\x00\x1f\xa1\xb1`\x00\x00\x00\x00 v\x00\xf0\x00\x00\x00\x00!\x81\x93`\x00\x00\x00\x00\x22U\xe2\xf0\x00\x00\x00\x00#j\xaf\xe0\x00\x00\x00\x00$5\xc4\xf0\x00\x00\x00\x00%J\x91\xe0\x00\x00\x00\x00&\x15\xa6\xf0\x00\x00\x00\x00'*s\xe0\x00\x00\x00\x00'\xfe\xc3p\x00\x00\x00\x00)\x0aU\xe0\x00\x00\x00\x00)\xde\xa5p\x00\x00\x00\x00*\xea7\xe0\x00\x00\x00\x00+\xbe\x87p\x00\x00\x00\x00,\xd3T`\x00\x00\x00\x00-\x9eip\x00\x00\x00\x00.\xb36`\x00\x00\x00\x00/~Kp\x00\x00\x00\x000\x93\x18`\x00\x00\x00\x001gg\xf0\x00\x00\x00\x002r\xfa`\x00\x00\x00\x003GI\xf0\x00\x00\x00\x004R\xdc`\x00\x00\x00\x005'+\xf0\x00\x00\x00\x0062\xbe`\x00\x00\x00\x007\x07\x0d\xf0\x00\x00\x00\x008\x1b\xda\xe0\x00\x00\x00\x008\xe6\xef\xf0\x00\x00\x00\x009\xfb\xbc\xe0\x00\x00\x00\x00:\xc6\xd1\xf0\x00\x00\x00\x00;\xdb\x9e\xe0\x00\x00\x00\x00<\xaf\xeep\x00\x00\x00\x00=\xbb\x80\xe0\x00\x00\x00\x00>\x8f\xd0p\x00\x00\x00\x00?\x9bb\xe0\x00\x00\x00\x00@o\xb2p\x00\x00\x00\x00A\x84\x7f`\x00\x00\x00\x00BO\x94p\x00\x00\x00\x00Cda`\x00\x00\x00\x00D/vp\x00\x00\x00\x00EDC`\x00\x00\x00\x00E\xf3\xa8\xf0\x01\x02\x03\x04\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\x02\x05\xff\xff\xb2%\x00\x00\xff\xff\xab\xa0\x00\x04\xff\xff\xb9\xb0\x00\x08\xff\xff\xc7\xc0\x01\x0c\xff\xff\xc7\xc0\x01\x10\xff\xff\xc7\xc0\x01\x14LMT\x00CST\x00EST\x00EWT\x00EPT\x00EDT\x00\x0aEST5EDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x0b\x00\x00\x00US/MountainTZif2\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\x00a\x00\x00\x00\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\x0c\xb0\xff\xff\xff\xff\x9e\xa6:\x90\xff\xff\xff\xff\x9f\xbb\x07\x80\xff\xff\xff\xff\xa0\x86\x1c\x90\xff\xff\xff\xff\xa1\x9a\xe9\x80\xff\xff\xff\xff\xa2e\xfe\x90\xff\xff\xff\xff\xa3\x84\x06\x00\xff\xff\xff\xff\xa4E\xe0\x90\xff\xff\xff\xff\xa4\x8f\xa6\x80\xff\xff\xff\xff\xcb\x89\x0c\x90\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a\x18\x00\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\x94\x00\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\x08v\x00\xff\xff\xff\xff\xfa\xf8u\x10\xff\xff\xff\xff\xfb\xe8X\x00\xff\xff\xff\xff\xfc\xd8W\x10\xff\xff\xff\xff\xfd\xc8:\x00\xff\xff\xff\xff\xfe\xb89\x10\xff\xff\xff\xff\xff\xa8\x1c\x00\x00\x00\x00\x00\x00\x98\x1b\x10\x00\x00\x00\x00\x01\x87\xfe\x00\x00\x00\x00\x00\x02w\xfd\x10\x00\x00\x00\x00\x03q\x1a\x80\x00\x00\x00\x00\x04a\x19\x90\x00\x00\x00\x00\x05P\xfc\x80\x00\x00\x00\x00\x06@\xfb\x90\x00\x00\x00\x00\x070\xde\x80\x00\x00\x00\x00\x07\x8d5\x90\x00\x00\x00\x00\x09\x10\xc0\x80\x00\x00\x00\x00\x09\xad\xb1\x10\x00\x00\x00\x00\x0a\xf0\xa2\x80\x00\x00\x00\x00\x0b\xe0\xa1\x90\x00\x00\x00\x00\x0c\xd9\xbf\x00\x00\x00\x00\x00\x0d\xc0\x83\x90\x00\x00\x00\x00\x0e\xb9\xa1\x00\x00\x00\x00\x00\x0f\xa9\xa0\x10\x00\x00\x00\x00\x10\x99\x83\x00\x00\x00\x00\x00\x11\x89\x82\x10\x00\x00\x00\x00\x12ye\x00\x00\x00\x00\x00\x13id\x10\x00\x00\x00\x00\x14YG\x00\x00\x00\x00\x00\x15IF\x10\x00\x00\x00\x00\x169)\x00\x00\x00\x00\x00\x17)(\x10\x00\x00\x00\x00\x18\x22E\x80\x00\x00\x00\x00\x19\x09\x0a\x10\x00\x00\x00\x00\x1a\x02'\x80\x00\x00\x00\x00\x1a\xf2&\x90\x00\x00\x00\x00\x1b\xe2\x09\x80\x00\x00\x00\x00\x1c\xd2\x08\x90\x00\x00\x00\x00\x1d\xc1\xeb\x80\x00\x00\x00\x00\x1e\xb1\xea\x90\x00\x00\x00\x00\x1f\xa1\xcd\x80\x00\x00\x00\x00 v\x1d\x10\x00\x00\x00\x00!\x81\xaf\x80\x00\x00\x00\x00\x22U\xff\x10\x00\x00\x00\x00#j\xcc\x00\x00\x00\x00\x00$5\xe1\x10\x00\x00\x00\x00%J\xae\x00\x00\x00\x00\x00&\x15\xc3\x10\x00\x00\x00\x00'*\x90\x00\x00\x00\x00\x00'\xfe\xdf\x90\x00\x00\x00\x00)\x0ar\x00\x00\x00\x00\x00)\xde\xc1\x90\x00\x00\x00\x00*\xeaT\x00\x00\x00\x00\x00+\xbe\xa3\x90\x00\x00\x00\x00,\xd3p\x80\x00\x00\x00\x00-\x9e\x85\x90\x00\x00\x00\x00.\xb3R\x80\x00\x00\x00\x00/~g\x90\x00\x00\x00\x000\x934\x80\x00\x00\x00\x001g\x84\x10\x00\x00\x00\x002s\x16\x80\x00\x00\x00\x003Gf\x10\x00\x00\x00\x004R\xf8\x80\x00\x00\x00\x005'H\x10\x00\x00\x00\x0062\xda\x80\x00\x00\x00\x007\x07*\x10\x00\x00\x00\x008\x1b\xf7\x00\x00\x00\x00\x008\xe7\x0c\x10\x00\x00\x00\x009\xfb\xd9\x00\x00\x00\x00\x00:\xc6\xee\x10\x00\x00\x00\x00;\xdb\xbb\x00\x00\x00\x00\x00<\xb0\x0a\x90\x00\x00\x00\x00=\xbb\x9d\x00\x00\x00\x00\x00>\x8f\xec\x90\x00\x00\x00\x00?\x9b\x7f\x00\x00\x00\x00\x00@o\xce\x90\x00\x00\x00\x00A\x84\x9b\x80\x00\x00\x00\x00BO\xb0\x90\x00\x00\x00\x00Cd}\x80\x00\x00\x00\x00D/\x92\x90\x00\x00\x00\x00ED_\x80\x00\x00\x00\x00E\xf3\xc5\x10\x02\x01\x02\x01\x02\x01\x02\x01\x02\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\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\xff\xff\x9d\x94\x00\x00\xff\xff\xab\xa0\x01\x04\xff\xff\x9d\x90\x00\x08\xff\xff\xab\xa0\x01\x0c\xff\xff\xab\xa0\x01\x10LMT\x00MDT\x00MST\x00MWT\x00MPT\x00\x0aMST7MDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x22\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\x0a\x00\x00\x00US/PacificTZif2\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\x05\x00\x00\x00\x14\xff\xff\xff\xff^\x04\x1a\xc0\xff\xff\xff\xff\x9e\xa6H\xa0\xff\xff\xff\xff\x9f\xbb\x15\x90\xff\xff\xff\xff\xa0\x86*\xa0\xff\xff\xff\xff\xa1\x9a\xf7\x90\xff\xff\xff\xff\xcb\x89\x1a\xa0\xff\xff\xff\xff\xd2#\xf4p\xff\xff\xff\xff\xd2a&\x10\xff\xff\xff\xff\xd6\xfet\x5c\xff\xff\xff\xff\xd8\x80\xad\x90\xff\xff\xff\xff\xda\xfe\xc3\x90\xff\xff\xff\xff\xdb\xc0\x90\x10\xff\xff\xff\xff\xdc\xde\xa5\x90\xff\xff\xff\xff\xdd\xa9\xac\x90\xff\xff\xff\xff\xde\xbe\x87\x90\xff\xff\xff\xff\xdf\x89\x8e\x90\xff\xff\xff\xff\xe0\x9ei\x90\xff\xff\xff\xff\xe1ip\x90\xff\xff\xff\xff\xe2~K\x90\xff\xff\xff\xff\xe3IR\x90\xff\xff\xff\xff\xe4^-\x90\xff\xff\xff\xff\xe5)4\x90\xff\xff\xff\xff\xe6GJ\x10\xff\xff\xff\xff\xe7\x12Q\x10\xff\xff\xff\xff\xe8',\x10\xff\xff\xff\xff\xe8\xf23\x10\xff\xff\xff\xff\xea\x07\x0e\x10\xff\xff\xff\xff\xea\xd2\x15\x10\xff\xff\xff\xff\xeb\xe6\xf0\x10\xff\xff\xff\xff\xec\xb1\xf7\x10\xff\xff\xff\xff\xed\xc6\xd2\x10\xff\xff\xff\xff\xee\x91\xd9\x10\xff\xff\xff\xff\xef\xaf\xee\x90\xff\xff\xff\xff\xf0q\xbb\x10\xff\xff\xff\xff\xf1\x8f\xd0\x90\xff\xff\xff\xff\xf2\x7f\xc1\x90\xff\xff\xff\xff\xf3o\xb2\x90\xff\xff\xff\xff\xf4_\xa3\x90\xff\xff\xff\xff\xf5O\x94\x90\xff\xff\xff\xff\xf6?\x85\x90\xff\xff\xff\xff\xf7/v\x90\xff\xff\xff\xff\xf8(\xa2\x10\xff\xff\xff\xff\xf9\x0fX\x90\xff\xff\xff\xff\xfa\x08\x84\x10\xff\xff\xff\xff\xfa\xf8\x83 \xff\xff\xff\xff\xfb\xe8f\x10\xff\xff\xff\xff\xfc\xd8e \xff\xff\xff\xff\xfd\xc8H\x10\xff\xff\xff\xff\xfe\xb8G \xff\xff\xff\xff\xff\xa8*\x10\x00\x00\x00\x00\x00\x98) \x00\x00\x00\x00\x01\x88\x0c\x10\x00\x00\x00\x00\x02x\x0b \x00\x00\x00\x00\x03q(\x90\x00\x00\x00\x00\x04a'\xa0\x00\x00\x00\x00\x05Q\x0a\x90\x00\x00\x00\x00\x06A\x09\xa0\x00\x00\x00\x00\x070\xec\x90\x00\x00\x00\x00\x07\x8dC\xa0\x00\x00\x00\x00\x09\x10\xce\x90\x00\x00\x00\x00\x09\xad\xbf \x00\x00\x00\x00\x0a\xf0\xb0\x90\x00\x00\x00\x00\x0b\xe0\xaf\xa0\x00\x00\x00\x00\x0c\xd9\xcd\x10\x00\x00\x00\x00\x0d\xc0\x91\xa0\x00\x00\x00\x00\x0e\xb9\xaf\x10\x00\x00\x00\x00\x0f\xa9\xae \x00\x00\x00\x00\x10\x99\x91\x10\x00\x00\x00\x00\x11\x89\x90 \x00\x00\x00\x00\x12ys\x10\x00\x00\x00\x00\x13ir \x00\x00\x00\x00\x14YU\x10\x00\x00\x00\x00\x15IT \x00\x00\x00\x00\x1697\x10\x00\x00\x00\x00\x17)6 \x00\x00\x00\x00\x18\x22S\x90\x00\x00\x00\x00\x19\x09\x18 \x00\x00\x00\x00\x1a\x025\x90\x00\x00\x00\x00\x1a\xf24\xa0\x00\x00\x00\x00\x1b\xe2\x17\x90\x00\x00\x00\x00\x1c\xd2\x16\xa0\x00\x00\x00\x00\x1d\xc1\xf9\x90\x00\x00\x00\x00\x1e\xb1\xf8\xa0\x00\x00\x00\x00\x1f\xa1\xdb\x90\x00\x00\x00\x00 v+ \x00\x00\x00\x00!\x81\xbd\x90\x00\x00\x00\x00\x22V\x0d \x00\x00\x00\x00#j\xda\x10\x00\x00\x00\x00$5\xef \x00\x00\x00\x00%J\xbc\x10\x00\x00\x00\x00&\x15\xd1 \x00\x00\x00\x00'*\x9e\x10\x00\x00\x00\x00'\xfe\xed\xa0\x00\x00\x00\x00)\x0a\x80\x10\x00\x00\x00\x00)\xde\xcf\xa0\x00\x00\x00\x00*\xeab\x10\x00\x00\x00\x00+\xbe\xb1\xa0\x00\x00\x00\x00,\xd3~\x90\x00\x00\x00\x00-\x9e\x93\xa0\x00\x00\x00\x00.\xb3`\x90\x00\x00\x00\x00/~u\xa0\x00\x00\x00\x000\x93B\x90\x00\x00\x00\x001g\x92 \x00\x00\x00\x002s$\x90\x00\x00\x00\x003Gt \x00\x00\x00\x004S\x06\x90\x00\x00\x00\x005'V \x00\x00\x00\x0062\xe8\x90\x00\x00\x00\x007\x078 \x00\x00\x00\x008\x1c\x05\x10\x00\x00\x00\x008\xe7\x1a \x00\x00\x00\x009\xfb\xe7\x10\x00\x00\x00\x00:\xc6\xfc \x00\x00\x00\x00;\xdb\xc9\x10\x00\x00\x00\x00<\xb0\x18\xa0\x00\x00\x00\x00=\xbb\xab\x10\x00\x00\x00\x00>\x8f\xfa\xa0\x00\x00\x00\x00?\x9b\x8d\x10\x00\x00\x00\x00@o\xdc\xa0\x00\x00\x00\x00A\x84\xa9\x90\x00\x00\x00\x00BO\xbe\xa0\x00\x00\x00\x00Cd\x8b\x90\x00\x00\x00\x00D/\xa0\xa0\x00\x00\x00\x00EDm\x90\x00\x00\x00\x00E\xf3\xd3 \x02\x01\x02\x01\x02\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\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\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\x02\x01\xff\xff\x91&\x00\x00\xff\xff\x9d\x90\x01\x04\xff\xff\x8f\x80\x00\x08\xff\xff\x9d\x90\x01\x0c\xff\xff\x9d\x90\x01\x10LMT\x00PDT\x00PST\x00PWT\x00PPT\x00\x0aPST8PDT,M3.2.0,M11.1.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x08\x00\x00\x00US/SamoaTZif2\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\x02\x00\x00\x00\x03\x00\x00\x00\x08\xff\xff\xff\xffn=\xc8\x08\xff\xff\xff\xff\x91\x05\xfb\x08\x01\x02\x00\x00\xb1x\x00\x00\xff\xff_\xf8\x00\x00\xff\xffeP\x00\x04LMT\x00SST\x00\x0aSST11\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00UTCTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\x0aUTC0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x09\x00\x00\x00UniversalTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\x0aUTC0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\x04\x00\x00\x00W-SUTZif2\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\x00N\x00\x00\x00\x0b\x00\x00\x00&\xff\xff\xff\xffV\xb6\xc0\xc7\xff\xff\xff\xff\x9b_\x1e\xc7\xff\xff\xff\xff\x9d>\xf2y\xff\xff\xff\xff\x9e*\xee\xf9\xff\xff\xff\xff\x9e\xf79i\xff\xff\xff\xff\x9f\x84W\xf9\xff\xff\xff\xff\xa0\xd8l\xe9\xff\xff\xff\xff\xa1\x009\x80\xff\xff\xff\xff\xa1<\xa6@\xff\xff\xff\xff\xa4\x10m\xc0\xff\xff\xff\xff\xa4=2\xb0\xff\xff\xff\xff\xa5\x15h\xb0\xff\xff\xff\xff\xa5=\x03\xc0\xff\xff\xff\xff\xa7\x1eEP\xff\xff\xff\xff\xb5\xa4\x19`\x00\x00\x00\x00\x15'\xa7\xd0\x00\x00\x00\x00\x16\x18\xdc@\x00\x00\x00\x00\x17\x08\xdbP\x00\x00\x00\x00\x17\xfa\x0f\xc0\x00\x00\x00\x00\x18\xea\x0e\xd0\x00\x00\x00\x00\x19\xdbC@\x00\x00\x00\x00\x1a\xcc\x93\xd0\x00\x00\x00\x00\x1b\xbc\xa0\xf0\x00\x00\x00\x00\x1c\xac\x91\xf0\x00\x00\x00\x00\x1d\x9c\x82\xf0\x00\x00\x00\x00\x1e\x8cs\xf0\x00\x00\x00\x00\x1f|d\xf0\x00\x00\x00\x00 lU\xf0\x00\x00\x00\x00!\x5cF\xf0\x00\x00\x00\x00\x22L7\xf0\x00\x00\x00\x00#<(\xf0\x00\x00\x00\x00$,\x19\xf0\x00\x00\x00\x00%\x1c\x0a\xf0\x00\x00\x00\x00&\x0b\xfb\xf0\x00\x00\x00\x00'\x05'p\x00\x00\x00\x00'\xf5\x18p\x00\x00\x00\x00(\xe5\x17\x80\x00\x00\x00\x00)x\xbf\x80\x00\x00\x00\x00)\xd4\xfap\x00\x00\x00\x00*\xc4\xebp\x00\x00\x00\x00+\xb4\xdcp\x00\x00\x00\x00,\xa4\xcdp\x00\x00\x00\x00-\x94\xbep\x00\x00\x00\x00.\x84\xafp\x00\x00\x00\x00/t\xa0p\x00\x00\x00\x000d\x91p\x00\x00\x00\x001]\xbc\xf0\x00\x00\x00\x002r\x97\xf0\x00\x00\x00\x003=\x9e\xf0\x00\x00\x00\x004Ry\xf0\x00\x00\x00\x005\x1d\x80\xf0\x00\x00\x00\x0062[\xf0\x00\x00\x00\x006\xfdb\xf0\x00\x00\x00\x008\x1bxp\x00\x00\x00\x008\xddD\xf0\x00\x00\x00\x009\xfbZp\x00\x00\x00\x00:\xbd&\xf0\x00\x00\x00\x00;\xdb<p\x00\x00\x00\x00<\xa6Cp\x00\x00\x00\x00=\xbb\x1ep\x00\x00\x00\x00>\x86%p\x00\x00\x00\x00?\x9b\x00p\x00\x00\x00\x00@f\x07p\x00\x00\x00\x00A\x84\x1c\xf0\x00\x00\x00\x00BE\xe9p\x00\x00\x00\x00Cc\xfe\xf0\x00\x00\x00\x00D%\xcbp\x00\x00\x00\x00EC\xe0\xf0\x00\x00\x00\x00F\x05\xadp\x00\x00\x00\x00G#\xc2\xf0\x00\x00\x00\x00G\xee\xc9\xf0\x00\x00\x00\x00I\x03\xa4\xf0\x00\x00\x00\x00I\xce\xab\xf0\x00\x00\x00\x00J\xe3\x86\xf0\x00\x00\x00\x00K\xae\x8d\xf0\x00\x00\x00\x00L\xcc\xa3p\x00\x00\x00\x00M\x8eo\xf0\x00\x00\x00\x00TL\x1d`\x01\x03\x02\x03\x04\x02\x04\x05\x06\x05\x07\x05\x06\x08\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x09\x08\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x05\x06\x0a\x06\x00\x00#9\x00\x00\x00\x00#9\x00\x04\x00\x001\x87\x01\x08\x00\x00#w\x00\x04\x00\x00?\x97\x01\x0c\x00\x008@\x01\x11\x00\x00*0\x00\x15\x00\x00FP\x01\x19\x00\x00\x1c \x00\x1d\x00\x00*0\x01!\x00\x008@\x00\x15LMT\x00MMT\x00MST\x00MDST\x00MSD\x00MSK\x00+05\x00EET\x00EEST\x00\x0aMSK-3\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x91B\xc0\xee\x01\x00\x00\xee\x01\x00\x00\x03\x00\x00\x00WETTZif2\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\x02\x00\x00\x00\x09\x00\x00\x00\x00\x0d\xa4c\x90\x00\x00\x00\x00\x0e\x8b\x1a\x10\x00\x00\x00\x00\x0f\x84E\x90\x00\x00\x00\x00\x10t6\x90\x00\x00\x00\x00\x11d'\x90\x00\x00\x00\x00\x12T\x18\x90\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\xdc\x90\x00\x00\x00\x00\x17\x03\xcd\x90\x00\x00\x00\x00\x17\xf3\xbe\x90\x00\x00\x00\x00\x18\xe3\xaf\x90\x00\x00\x00\x00\x19\xd3\xa0\x90\x00\x00\x00\x00\x1a\xc3\x91\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!\x5cc\x10\x00\x00\x00\x00\x22LT\x10\x00\x00\x00\x00#<E\x10\x00\x00\x00\x00$,6\x10\x00\x00\x00\x00%\x1c'\x10\x00\x00\x00\x00&\x0c\x18\x10\x00\x00\x00\x00'\x05C\x90\x00\x00\x00\x00'\xf54\x90\x00\x00\x00\x00(\xe5%\x90\x00\x00\x00\x00)\xd5\x16\x90\x00\x00\x00\x00*\xc5\x07\x90\x00\x00\x00\x00+\xb4\xf8\x90\x00\x00\x00\x00,\xa4\xe9\x90\x00\x00\x00\x00-\x94\xda\x90\x00\x00\x00\x00.\x84\xcb\x90\x00\x00\x00\x00/t\xbc\x90\x00\x00\x00\x000d\xad\x90\x00\x00\x00\x001]\xd9\x10\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00\x05\x00\x00\x0e\x10\x01\x00WEST\x00WET\x00\x0aWET0WEST,M3.5.0/1,M10.5.0\x0aPK\x03\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x04\x00\x00\x00ZuluTZif2\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\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00UTC\x00\x0aUTC0\x0aPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Africa/AbidjanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\x00\x00\x00Africa/AccraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x01\x00\x00Africa/Addis_AbabaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\x8a\x0e\xc0\xd6\x01\x00\x00\xd6\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\x02\x00\x00Africa/AlgiersPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K\x04\x00\x00Africa/AsmaraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x05\x00\x00Africa/AsmeraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x06\x00\x00Africa/BamakoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\x06\x00\x00Africa/BanguiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x07\x00\x00Africa/BanjulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca>\xd5\xe0\x95\x00\x00\x00\x95\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\x08\x00\x00Africa/BissauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x09\x00\x00Africa/BlantyrePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x09\x00\x00Africa/BrazzavillePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x0a\x00\x00Africa/BujumburaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5#)\x16\x1d\x05\x00\x00\x1d\x05\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x0b\x00\x00Africa/CairoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001B\xb0;\x7f\x07\x00\x00\x7f\x07\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x10\x00\x00Africa/CasablancaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\x1b\xeb\xdd2\x02\x00\x002\x02\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x18\x00\x00Africa/CeutaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\x1a\x00\x00Africa/ConakryPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5c\x1b\x00\x00Africa/DakarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x1c\x00\x00Africa/Dar_es_SalaamPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x1c\x00\x00Africa/DjiboutiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\x1d\x00\x00Africa/DoualaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xd3\xc6g&\x07\x00\x00&\x07\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc4\x1e\x00\x00Africa/El_AaiunPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17&\x00\x00Africa/FreetownPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc6&\x00\x00Africa/GaboronePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00v'\x00\x00Africa/HararePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\x0cT\xce\xbe\x00\x00\x00\xbe\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$(\x00\x00Africa/JohannesburgPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xcf\x10n\xca\x01\x00\x00\xca\x01\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13)\x00\x00Africa/JubaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06+\x00\x00Africa/KampalaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xadD\xef\xca\x01\x00\x00\xca\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1+\x00\x00Africa/KhartoumPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8-\x00\x00Africa/KigaliPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96.\x00\x00Africa/KinshasaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w/\x00\x00Africa/LagosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U0\x00\x00Africa/LibrevillePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0081\x00\x00Africa/LomePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe31\x00\x00Africa/LuandaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc22\x00\x00Africa/LubumbashiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t3\x00\x00Africa/LusakaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x224\x00\x00Africa/MalaboPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x1b\xb0_\x83\x00\x00\x00\x83\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x015\x00\x00Africa/MaputoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\x0cT\xce\xbe\x00\x00\x00\xbe\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf5\x00\x00Africa/MaseruPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\x0cT\xce\xbe\x00\x00\x00\xbe\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x986\x00\x00Africa/MbabanePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x827\x00\x00Africa/MogadishuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\x99rU\xa4\x00\x00\x00\xa4\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o8\x00\x00Africa/MonroviaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@9\x00\x00Africa/NairobiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaa\x81\x09\x03\xa0\x00\x00\x00\xa0\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+:\x00\x00Africa/NdjamenaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8:\x00\x00Africa/NiameyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7;\x00\x00Africa/NouakchottPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88<\x00\x00Africa/OuagadougouPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x1d\xb3c\xb4\x00\x00\x00\xb4\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:=\x00\x00Africa/Porto-NovoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\x0a\x8a\x84\xad\x00\x00\x00\xad\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d>\x00\x00Africa/Sao_TomePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7>\x00\x00Africa/TimbuktuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa6?\x00\x00Africa/TripoliPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\xf4\x94\x0b\xc1\x01\x00\x00\xc1\x01\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81A\x00\x00Africa/TunisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m)\xb8P~\x02\x00\x00~\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00lC\x00\x00Africa/WindhoekPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17F\x00\x00America/AdakPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0aJ\x00\x00America/AnchoragePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0aN\x00\x00America/AnguillaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9N\x00\x00America/AntiguaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x01V\x0dP\x02\x00\x00P\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7O\x00\x00America/AraguainaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FR\x00\x00America/Argentina/Buenos_AiresPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FU\x00\x00America/Argentina/CatamarcaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00CX\x00\x00America/Argentina/ComodRivadaviaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E[\x00\x00America/Argentina/CordobaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00utZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@^\x00\x00America/Argentina/JujuyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m\x07D\x0e\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'a\x00\x00America/Argentina/La_RiojaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x92Z\x8c\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,d\x00\x00America/Argentina/MendozaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ep\xb4c\xc4\x02\x00\x00\xc4\x02\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'g\x00\x00America/Argentina/Rio_GallegosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t*\x9b!\xb2\x02\x00\x00\xb2\x02\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'j\x00\x00America/Argentina/SaltaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfcz=\xe1\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0em\x00\x00America/Argentina/San_JuanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\x80\xb9\x5c\xcd\x02\x00\x00\xcd\x02\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13p\x00\x00America/Argentina/San_LuisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd8\xd6\xad\xd6\x02\x00\x00\xd6\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18s\x00\x00America/Argentina/TucumanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b}\xb6\x1e\xc4\x02\x00\x00\xc4\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%v\x00\x00America/Argentina/UshuaiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 y\x00\x00America/ArubaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xa9y\x9at\x03\x00\x00t\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfcy\x00\x00America/AsuncionPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xbe\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9e}\x00\x00America/AtikokanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a~\x00\x00America/AtkaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00OKj\xc7\xaa\x02\x00\x00\xaa\x02\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x82\x00\x00America/BahiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\x0e\x01n\xd8\x02\x00\x00\xd8\x02\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x85\x00\x00America/Bahia_BanderasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l=\xad\xbe\x16\x01\x00\x00\x16\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x88\x00\x00America/BarbadosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85-\xb9\xf8\x8a\x01\x00\x00\x8a\x01\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00y\x89\x00\x00America/BelemPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\xd8\xba\xee\x15\x04\x00\x00\x15\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\x8b\x00\x00America/BelizePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\x8f\x00\x00America/Blanc-SablonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8Dz\x97\xae\x01\x00\x00\xae\x01\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x90\x00\x00America/Boa_VistaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,g\xec\xec\xb3\x00\x00\x00\xb3\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/\x92\x00\x00America/BogotaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\xbe\x1a>\xe7\x03\x00\x00\xe7\x03\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0e\x93\x00\x00America/BoisePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xbf\xf5\xe5\xc4\x02\x00\x00\xc4\x02\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x97\x00\x00America/Buenos_AiresPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\xba\xb2\x94s\x03\x00\x00s\x03\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x9a\x00\x00America/Cambridge_BayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xfbn\xdb\xb8\x03\x00\x00\xb8\x03\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x9d\x00\x00America/Campo_GrandePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x04\xde\xdd\x11\x02\x00\x00\x11\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa6\xa1\x00\x00America/CancunPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x8e\xee\x13\xbe\x00\x00\x00\xbe\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xa3\x00\x00America/CaracasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xc8\xd9\xf6\xc4\x02\x00\x00\xc4\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\xa4\x00\x00America/CatamarcaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1'\x07\xbd\x97\x00\x00\x00\x97\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\xa7\x00\x00America/CayennePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xbe\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\xa8\x00\x00America/CaymanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xdc\xa9=\xda\x06\x00\x00\xda\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F\xa9\x00\x00America/ChicagoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x111\x04q\xb3\x02\x00\x00\xb3\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M\xb0\x00\x00America/ChihuahuaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\xf2L\x06\xce\x02\x00\x00\xce\x02\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/\xb3\x00\x00America/Ciudad_JuarezPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xbe\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000\xb6\x00\x00America/Coral_HarbourPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\xb6\x00\x00America/CordobaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1\xdd\x82x\xe8\x00\x00\x00\xe8\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\xb9\x00\x00America/Costa_RicaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\xb8\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xbb\x00\x00America/CrestonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f$*\xa0\xa6\x03\x00\x00\xa6\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xbc\x00\x00America/CuiabaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xbf\x00\x00America/CuracaoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xc2\x0dx\xbf\x01\x00\x00\xbf\x01\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\xc0\x00\x00America/DanmarkshavnPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xe6\xf5J\x05\x04\x00\x00\x05\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xc2\x00\x00America/DawsonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x10`\xc8\xab\x02\x00\x00\xab\x02\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xc6\x00\x00America/Dawson_CreekPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xc9\x00\x00America/DenverPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\xce\x00\x00America/DetroitPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\xd1\x00\x00America/DominicaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\x07\x07\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xd2\x00\x00America/EdmontonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\xb0\xeau\xb4\x01\x00\x00\xb4\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\xd6\x00\x00America/EirunepePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea$\xc1\xbf\xb0\x00\x00\x00\xb0\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xd8\x00\x00America/El_SalvadorPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\xd9\x00\x00America/EnsenadaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6@\x0dm\xa8\x05\x00\x00\xa8\x05\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\xdd\x00\x00America/Fort_NelsonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\xe3\x00\x00America/Fort_WaynePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x11Z\xde\xe4\x01\x00\x00\xe4\x01\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\xe5\x00\x00America/FortalezaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M\x94\xc7Kp\x03\x00\x00p\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3\xe7\x00\x00America/Glace_BayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95'O\xce\xc5\x03\x00\x00\xc5\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\xeb\x00\x00America/GodthabPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\xf7\x07 ,\x06\x00\x00,\x06\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\xef\x00\x00America/Goose_BayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xc9I\xd0U\x03\x00\x00U\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\xf5\x00\x00America/Grand_TurkPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\xf9\x00\x00America/GrenadaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xfa\x00\x00America/GuadeloupePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x8a\x83S\xd4\x00\x00\x00\xd4\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xfa\x00\x00America/GuatemalaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xc3v\xe3\xb3\x00\x00\x00\xb3\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xfb\x00\x00America/GuayaquilPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x05\xf3\x89\xb5\x00\x00\x00\xb5\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\xfc\x00\x00America/GuyanaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9\xfd\x00\x00America/HalifaxPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\x04\x01\x00America/HavanaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4MS\x99\x1e\x01\x00\x00\x1e\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7\x08\x01\x00America/HermosilloPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x0a\x01\x00America/Indiana/IndianapolisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x0c\x01\x00America/Indiana/KnoxPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M/U\x9f7\x02\x00\x007\x02\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac\x10\x01\x00America/Indiana/MarengoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xd8N\x8c\xab\x02\x00\x00\xab\x02\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x13\x01\x00America/Indiana/PetersburgPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xb5K\xa6\x0a\x02\x00\x00\x0a\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb\x15\x01\x00America/Indiana/Tell_CityPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x17\x89}q\x01\x00\x00q\x01\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x18\x01\x00America/Indiana/VevayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0d\xedsp.\x02\x00\x00.\x02\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\x19\x01\x00America/Indiana/VincennesPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K-E\xfad\x02\x00\x00d\x02\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x1c\x01\x00America/Indiana/WinamacPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\x1e\x01\x00America/IndianapolisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\xbc\x09o1\x03\x00\x001\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00#!\x01\x00America/InuvikPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xa0\xd6\x05W\x03\x00\x00W\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80$\x01\x00America/IqaluitPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%J\xd5\xebS\x01\x00\x00S\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04(\x01\x00America/JamaicaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00utZ\x1a\xb2\x02\x00\x00\xb2\x02\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84)\x01\x00America/JujuyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xc9\x1c\xd4\xc6\x03\x00\x00\xc6\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a,\x01\x00America/JuneauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S0\x01\x00America/Kentucky/LouisvillePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x1a|J\xcc\x03\x00\x00\xcc\x03\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f5\x01\x00America/Kentucky/MonticelloPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k9\x01\x00America/Knox_INPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90=\x01\x00America/KralendijkPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad`\x12\xe9\xaa\x00\x00\x00\xaa\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q>\x01\x00America/La_PazPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe7\xa1\x87\x1b\x01\x00\x00\x1b\x01\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G?\x01\x00America/LimaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x22\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c@\x01\x00America/Los_AngelesPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\xe5\x8d\xc4\xda\x04\x00\x00\xda\x04\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcbE\x01\x00America/LouisvillePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5J\x01\x00America/Lower_PrincesPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\x8c\x8b\x92\xf6\x01\x00\x00\xf6\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9K\x01\x00America/MaceioPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5s\xb3\x5c'\x01\x00\x00'\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdbM\x01\x00America/ManaguaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/O\x01\x00America/ManausPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7P\x01\x00America/MarigotPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7\x17j\xd2\xb2\x00\x00\x00\xb2\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5Q\x01\x00America/MartiniquePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00((i\xe4\xb5\x01\x00\x00\xb5\x01\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7R\x01\x00America/MatamorosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xad=\x98\xce\x02\x00\x00\xce\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9bT\x01\x00America/MazatlanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x92Z\x8c\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97W\x01\x00America/MendozaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x008O:\xbf\x95\x03\x00\x00\x95\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88Z\x01\x00America/MenomineePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xbd\x809\x8e\x02\x00\x00\x8e\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L^\x01\x00America/MeridaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\x81\xbfyS\x02\x00\x00S\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06a\x01\x00America/MetlakatlaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\x08\x89\x8c\x05\x03\x00\x00\x05\x03\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89c\x01\x00America/Mexico_CityPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7\x08\x5c\xc6&\x02\x00\x00&\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbff\x01\x00America/MiquelonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.\xf9\xc0\x1e\xd5\x05\x00\x00\xd5\x05\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13i\x01\x00America/MonctonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L+\xe3u\x84\x02\x00\x00\x84\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15o\x01\x00America/MonterreyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x98\x00\x08\xc9\x03\x00\x00\xc9\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8q\x01\x00America/MontevideoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1u\x01\x00America/MontrealPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4|\x01\x00America/MontserratPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85}\x01\x00America/NassauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f\x84\x01\x00America/New_YorkPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\x8b\x01\x00America/NipigonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\xab\xd5\xf9\xcf\x03\x00\x00\xcf\x03\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F\x92\x01\x00America/NomePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x96\x01\x00America/NoronhaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7.\xb6*\x13\x04\x00\x00\x13\x04\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x98\x01\x00America/North_Dakota/BeulahPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\xeam\xef\xde\x03\x00\x00\xde\x03\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\x9c\x01\x00America/North_Dakota/CenterPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00R\x1b\x8b(\xde\x03\x00\x00\xde\x03\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3\xa0\x01\x00America/North_Dakota/New_SalemPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95'O\xce\xc5\x03\x00\x00\xc5\x03\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd\xa4\x01\x00America/NuukPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe5\x9e<\xc5\x02\x00\x00\xc5\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\xa8\x01\x00America/OjinagaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xbe\xe7#\x95\x00\x00\x00\x95\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae\xab\x01\x00America/PanamaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xa0\xd6\x05W\x03\x00\x00W\x03\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xac\x01\x00America/PangnirtungPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\xf9\x1d\xc9\xbb\x00\x00\x00\xbb\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\xaf\x01\x00America/ParamariboPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\xb8\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\xb0\x01\x00America/PhoenixPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4T\xbd\xeb5\x02\x00\x005\x02\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xb1\x01\x00America/Port-au-PrincePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\xb4\x01\x00America/Port_of_SpainPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\xb5\x01\x00America/Porto_AcrePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\x81-\xa9\x8a\x01\x00\x00\x8a\x01\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xb7\x01\x00America/Porto_VelhoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9\xb8\x01\x00America/Puerto_RicoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x13\x9b\xb1\xc2\x04\x00\x00\xc2\x04\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbb\xb9\x01\x00America/Punta_ArenasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\xbe\x01\x00America/Rainy_RiverPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xdfH\x0d'\x03\x00\x00'\x03\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\xc3\x01\x00America/Rankin_InletPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x03u\xf3\xe4\x01\x00\x00\xe4\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G\xc7\x01\x00America/RecifePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc2\x96dK~\x02\x00\x00~\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\xc9\x01\x00America/ReginaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0I~D'\x03\x00\x00'\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xcc\x01\x00America/ResolutePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xcf\x01\x00America/Rio_BrancoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xf0R\x8a\xc4\x02\x00\x00\xc4\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xd1\x01\x00America/RosarioPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19\xd4\x01\x00America/Santa_IsabelPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04,2h\x99\x01\x00\x00\x99\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\xd8\x01\x00America/SantaremPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x22_WJ\x05\x00\x00J\x05\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\xda\x01\x00America/SantiagoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x0f(\x08=\x01\x00\x00=\x01\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\xdf\x01\x00America/Santo_DomingoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d?\xdf\xda\xb8\x03\x00\x00\xb8\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb\xe0\x01\x00America/Sao_PauloPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x9a1T\xdf\x01\x00\x00\xdf\x01\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2\xe4\x01\x00America/ScoresbysundPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf3\xe6\x01\x00America/ShiprockPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81{\xc1\x92\xbc\x03\x00\x00\xbc\x03\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xeb\x01\x00America/SitkaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\xef\x01\x00America/St_BarthelemyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xb2\x0e\x19V\x07\x00\x00V\x07\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xef\x01\x00America/St_JohnsPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\xf7\x01\x00America/St_KittsPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xf8\x01\x00America/St_LuciaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xf9\x01\x00America/St_ThomasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \xfa\x01\x00America/St_VincentPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xd8\x19\x9dp\x01\x00\x00p\x01\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xfb\x01\x00America/Swift_CurrentPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x13z\xe2\xc2\x00\x00\x00\xc2\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\xfc\x01\x00America/TegucigalpaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\x0d\xf7\xd3\xc7\x01\x00\x00\xc7\x01\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97\xfd\x01\x00America/ThulePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\xff\x01\x00America/Thunder_BayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\x06\x02\x00America/TijuanaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d\x0a\x02\x00America/TorontoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x11\x02\x00America/TortolaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U9#\xbe2\x05\x00\x002\x05\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x12\x02\x00America/VancouverPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xc9*;\xb1\x00\x00\x00\xb1\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe\x17\x02\x00America/VirginPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x1d\xee\x91\x05\x04\x00\x00\x05\x04\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\x18\x02\x00America/WhitehorsePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\x1c\x02\x00America/WinnipegPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,\xdb~\xab\xb2\x03\x00\x00\xb2\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x22\x02\x00America/YakutatPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\x07\x07\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeb%\x02\x00America/YellowknifePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xddzAh\xf3\x00\x00\x00\xf3\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6)\x02\x00Antarctica/CaseyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xea\x06\xd3\xc5\x00\x00\x00\xc5\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07+\x02\x00Antarctica/DavisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa+\x02\x00Antarctica/DumontDUrvillePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\x84J]\xd0\x03\x00\x00\xd0\x03\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcb,\x02\x00Antarctica/MacquariePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7N\xab\x8b\x98\x00\x00\x00\x98\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd0\x02\x00Antarctica/MawsonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x941\x02\x00Antarctica/McMurdoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95{\xf3\xa9w\x03\x00\x00w\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd75\x02\x00Antarctica/PalmerPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc6\x89\xf71\x84\x00\x00\x00\x84\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}9\x02\x00Antarctica/RotheraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001:\x02\x00Antarctica/South_PolePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xd7\x87\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w>\x02\x00Antarctica/SyowaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\xc8P7\xb1\x00\x00\x00\xb1\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*?\x02\x00Antarctica/TrollPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09@\x02\x00Antarctica/VostokPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd@\x02\x00Arctic/LongyearbyenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xd7\x87\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xafC\x02\x00Asia/AdenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xdd\x5c2a\x02\x00\x00a\x02\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[D\x02\x00Asia/AlmatyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\x0ds\xad\xa0\x03\x00\x00\xa0\x03\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5F\x02\x00Asia/AmmanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xe0\xe7!\xe7\x02\x00\x00\xe7\x02\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xadJ\x02\x00Asia/AnadyrPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\x81\x18G^\x02\x00\x00^\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbdM\x02\x00Asia/AqtauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb\xfa\xb5\xbeg\x02\x00\x00g\x02\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00CP\x02\x00Asia/AqtobePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x1bb2w\x01\x00\x00w\x01\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3R\x02\x00Asia/AshgabatPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x1bb2w\x01\x00\x00w\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00uT\x02\x00Asia/AshkhabadPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\xa7^\xfah\x02\x00\x00h\x02\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18V\x02\x00Asia/AtyrauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7e&uv\x02\x00\x00v\x02\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9X\x02\x00Asia/BaghdadPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdav\x19z\x98\x00\x00\x00\x98\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I[\x02\x00Asia/BahrainPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x87\xb3<\xe8\x02\x00\x00\xe8\x02\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x5c\x02\x00Asia/BakuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a_\x02\x00Asia/BangkokPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\xbd\xedL\xf1\x02\x00\x00\xf1\x02\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdc_\x02\x00Asia/BarnaulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\x11\xe1[\xdc\x02\x00\x00\xdc\x02\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7b\x02\x00Asia/BeirutPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000]*\x1bj\x02\x00\x00j\x02\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfce\x02\x00Asia/BishkekPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7f^]@\x01\x00\x00@\x01\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90h\x02\x00Asia/BruneiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9i\x02\x00Asia/CalcuttaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\xcd\xdf\x05\xee\x02\x00\x00\xee\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x02\x00Asia/ChitaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81z&\x80k\x02\x00\x00k\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16n\x02\x00Asia/ChoibalsanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaep\x02\x00Asia/ChongqingPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00cr\x02\x00Asia/ChungkingPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5c\x91\x87\xbb\xf7\x00\x00\x00\xf7\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18t\x02\x00Asia/ColomboPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009u\x02\x00Asia/DaccaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x87\x07\xeci\xd2\x04\x00\x00\xd2\x04\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Hv\x02\x00Asia/DamascusPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?Y\xaf\x19\xe7\x00\x00\x00\xe7\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E{\x02\x00Asia/DhakaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\x92\x1a\x8c\xaa\x00\x00\x00\xaa\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T|\x02\x00Asia/DiliPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%}\x02\x00Asia/DubaiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00's\x96\x1en\x01\x00\x00n\x01\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd2}\x02\x00Asia/DushanbePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]S\xbb\x12\xac\x03\x00\x00\xac\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x7f\x02\x00Asia/FamagustaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xda7\xf5l\xd6\x09\x00\x00\xd6\x09\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\x83\x02\x00Asia/GazaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\x8d\x02\x00Asia/HarbinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xba\xd4\xe5\xe8\x09\x00\x00\xe8\x09\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x8e\x02\x00Asia/HebronPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000I\xc7\xde\xec\x00\x00\x00\xec\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x99\x02\x00Asia/Ho_Chi_MinhPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x09\xfa-\x07\x03\x00\x00\x07\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x9a\x02\x00Asia/Hong_KongPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xba\xa3b\xc1R\x02\x00\x00R\x02\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x9d\x02\x00Asia/HovdPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9l\x03\x12\xf8\x02\x00\x00\xf8\x02\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc9\x9f\x02\x00Asia/IrkutskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07W\x10\xd1\xb0\x04\x00\x00\xb0\x04\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeb\xa2\x02\x00Asia/IstanbulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xad\xc5\xb1\xf8\x00\x00\x00\xf8\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc6\xa7\x02\x00Asia/JakartaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.>[K\xab\x00\x00\x00\xab\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\xa8\x02\x00Asia/JayapuraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\xe2\x9c\xb32\x04\x00\x002\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbe\xa9\x02\x00Asia/JerusalemPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\xe2\x5c\xff\x9f\x00\x00\x00\x9f\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xae\x02\x00Asia/KabulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x9cf>\xd7\x02\x00\x00\xd7\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xae\x02\x00Asia/KamchatkaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009Y\xb7\xf1\x0a\x01\x00\x00\x0a\x01\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xb1\x02\x00Asia/KarachiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1a\xb3\x02\x00Asia/KashgarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc9\xb3\x02\x00Asia/KathmanduPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8bSnT\xa1\x00\x00\x00\xa1\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xb4\x02\x00Asia/KatmanduPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x83g\x95M\x07\x03\x00\x00\x07\x03\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb5\x02\x00Asia/KhandygaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\x1a\xdc\xca\xdc\x00\x00\x00\xdc\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x94\xb8\x02\x00Asia/KolkataPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\xe0\x91y\xe5\x02\x00\x00\xe5\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xb9\x02\x00Asia/KrasnoyarskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xad\xbc\x02\x00Asia/Kuala_LumpurPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa7f^]@\x01\x00\x00@\x01\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdc\xbd\x02\x00Asia/KuchingPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xd7\x87\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F\xbf\x02\x00Asia/KuwaitPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d?v\x0c\x17\x03\x00\x00\x17\x03\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf4\xbf\x02\x00Asia/MacaoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d?v\x0c\x17\x03\x00\x00\x17\x03\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xc3\x02\x00Asia/MacauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4_P\x18\xef\x02\x00\x00\xef\x02\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00r\xc6\x02\x00Asia/MagadanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xc9\xd4\x5c\xbe\x00\x00\x00\xbe\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\xc9\x02\x00Asia/MakassarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xaf\xdf\x1c\xee\x00\x00\x00\xee\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca\x02\x00Asia/ManilaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\xcb\x02\x00Asia/MuscatPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009\xcc\x02\x00Asia/NicosiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\x9a\x90\xf7\xd6\x02\x00\x00\xd6\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8\xce\x02\x00Asia/NovokuznetskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)p\x1cX\xf1\x02\x00\x00\xf1\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xd1\x02\x00Asia/NovosibirskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\x11\xea\xa2\xe5\x02\x00\x00\xe5\x02\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdc\xd4\x02\x00Asia/OmskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&\xe9\xd1\xd8q\x02\x00\x00q\x02\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\xd7\x02\x00Asia/OralPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xda\x02\x00Asia/Phnom_PenhPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xa5\x81e\xf7\x00\x00\x00\xf7\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xdb\x02\x00Asia/PontianakPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a\xc1\x1eB\xb7\x00\x00\x00\xb7\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\xdc\x02\x00Asia/PyongyangPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdav\x19z\x98\x00\x00\x00\x98\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K\xdd\x02\x00Asia/QatarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xfax\x98g\x02\x00\x00g\x02\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\xde\x02\x00Asia/QostanayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\xce\x9cGp\x02\x00\x00p\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d\xe0\x02\x00Asia/QyzylordaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\x87{_\xbb\x00\x00\x00\xbb\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009\xe3\x02\x00Asia/RangoonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xd7\x87\xe1\x85\x00\x00\x00\x85\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1e\xe4\x02\x00Asia/RiyadhPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000I\xc7\xde\xec\x00\x00\x00\xec\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcc\xe4\x02\x00Asia/SaigonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\x15II\xf3\x02\x00\x00\xf3\x02\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xe5\x02\x00Asia/SakhalinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w\x0dD\x07n\x01\x00\x00n\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xe8\x02\x00Asia/SamarkandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\xea\x02\x00Asia/SeoulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xec\x02\x00Asia/ShanghaiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xee\x02\x00Asia/SingaporePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4Z\xdf\x90\xe6\x02\x00\x00\xe6\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xef\x02\x00Asia/SrednekolymskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xf2\x02\x00Asia/TaipeiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xe27Yn\x01\x00\x00n\x01\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xf4\x02\x00Asia/TashkentPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\xbe\xa8\xc7u\x02\x00\x00u\x02\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\xf6\x02\x00Asia/TbilisiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xdb?\xec,\x03\x00\x00,\x03\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb6\xf8\x02\x00Asia/TehranPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\xe2\x9c\xb32\x04\x00\x002\x04\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\xfc\x02\x00Asia/Tel_AvivPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x00\x03\x00Asia/ThimbuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j$\xcd\xf4\x9a\x00\x00\x00\x9a\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x01\x03\x00Asia/ThimphuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\x01\x03\x00Asia/TokyoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[u\x99q\xf1\x02\x00\x00\xf1\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec\x02\x03\x00Asia/TomskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`\xc9\xd4\x5c\xbe\x00\x00\x00\xbe\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x06\x03\x00Asia/Ujung_PandangPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf3\x06\x03\x00Asia/UlaanbaatarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xb9\xf4\xb6R\x02\x00\x00R\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x09\x03\x00Asia/Ulan_BatorPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B\x1d\xc6\x1b\x85\x00\x00\x00\x85\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2\x0b\x03\x00Asia/UrumqiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00w\x86\x8d^\x03\x03\x00\x00\x03\x03\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\x0c\x03\x00Asia/Ust-NeraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xce\x0f\x03\x00Asia/VientianePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d%\x05\xd8\xe6\x02\x00\x00\xe6\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x10\x03\x00Asia/VladivostokPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O\xb0\x03\xe9\xe5\x02\x00\x00\xe5\x02\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa6\x13\x03\x00Asia/YakutskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\x87{_\xbb\x00\x00\x00\xbb\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb5\x16\x03\x00Asia/YangonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xea\x18\xd4\xf8\x02\x00\x00\xf8\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x99\x17\x03\x00Asia/YekaterinburgPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x95-\xad\xc4\x02\x00\x00\xc4\x02\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc1\x1a\x03\x00Asia/YerevanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x8dY\x80\xad\x05\x00\x00\xad\x05\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\x1d\x03\x00Atlantic/AzoresPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l&\x04\x99\x00\x04\x00\x00\x00\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89#\x03\x00Atlantic/BermudaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf|7\xb3\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7'\x03\x00Atlantic/CanaryPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc2\x97N\xad\xaf\x00\x00\x00\xaf\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc2)\x03\x00Atlantic/Cape_VerdePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2*\x03\x00Atlantic/FaeroePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\x0e\xbdm\xb9\x01\x00\x00\xb9\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88,\x03\x00Atlantic/FaroePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m.\x03\x00Atlantic/Jan_MayenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001)7\xad\xad\x05\x00\x00\xad\x05\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^1\x03\x00Atlantic/MadeiraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0097\x03\x00Atlantic/ReykjavikPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f-\xad\xd7\x84\x00\x00\x00\x84\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeb7\x03\x00Atlantic/South_GeorgiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa38\x03\x00Atlantic/St_HelenaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7\xcf^\xb0\x15\x03\x00\x00\x15\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U9\x03\x00Atlantic/StanleyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98<\x03\x00Australia/ACTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ff~\xd5\x99\x03\x00\x00\x99\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00K@\x03\x00Australia/AdelaidePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14D\x03\x00Australia/BrisbanePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00eE\x03\x00Australia/Broken_HillPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00EI\x03\x00Australia/CanberraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfdL\x03\x00Australia/CurriePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16Q\x03\x00Australia/DarwinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa2\xdc\xba\xca:\x01\x00\x00:\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00.R\x03\x00Australia/EuclaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95S\x03\x00Australia/HobartPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaeW\x03\x00Australia/LHIPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?\x95\xbd\x12E\x01\x00\x00E\x01\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8dZ\x03\x00Australia/LindemanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o3\xdaR\xb4\x02\x00\x00\xb4\x02\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x5c\x03\x00Australia/Lord_HowePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7^\x03\x00Australia/MelbournePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0b\x03\x00Australia/NSWPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8R\x1a\x1b\xea\x00\x00\x00\xea\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Sf\x03\x00Australia/NorthPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xbb\xca\x1a2\x01\x00\x002\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00jg\x03\x00Australia/PerthPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\xba\xde\xd3!\x01\x00\x00!\x01\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc9h\x03\x00Australia/QueenslandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8ff~\xd5\x99\x03\x00\x00\x99\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1cj\x03\x00Australia/SouthPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X\xb9\x9ap\x88\x03\x00\x00\x88\x03\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2m\x03\x00Australia/SydneyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xf2\xe6Z\xeb\x03\x00\x00\xeb\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98q\x03\x00Australia/TasmaniaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xe1\xc1\xa9\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3u\x03\x00Australia/VictoriaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcf\xbb\xca\x1a2\x01\x00\x002\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ky\x03\x00Australia/WestPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xca#\x7f\xad\x03\x00\x00\xad\x03\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc9z\x03\x00Australia/YancowinnaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00g\xf5K\x89\xa2\x01\x00\x00\xa2\x01\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8~\x03\x00Brazil/AcrePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7-2f\xe4\x01\x00\x00\xe4\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00s\x80\x03\x00Brazil/DeNoronhaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9d?\xdf\xda\xb8\x03\x00\x00\xb8\x03\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x82\x03\x00Brazil/EastPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\xcb'\xe9\x9c\x01\x00\x00\x9c\x01\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00f\x86\x03\x00Brazil/WestPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\x9aM\xbem\x02\x00\x00m\x02\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x88\x03\x00CETPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<\x8b\x99\x1e\xb7\x03\x00\x00\xb7\x03\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\x8a\x03\x00CST6CDTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00):\x17-\x88\x06\x00\x00\x88\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\x8e\x03\x00Canada/AtlanticPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?_p\x99\x0e\x05\x00\x00\x0e\x05\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\x95\x03\x00Canada/CentralPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3\xbf\x92\xbc\xb5\x06\x00\x00\xb5\x06\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x9a\x03\x00Canada/EasternPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\x07\x07\xdc\xca\x03\x00\x00\xca\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\xa1\x03\x00Canada/MountainPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~\xb2\x0e\x19V\x07\x00\x00V\x07\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5c\xa5\x03\x00Canada/NewfoundlandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U9#\xbe2\x05\x00\x002\x05\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xac\x03\x00Canada/PacificPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc2\x96dK~\x02\x00\x00~\x02\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00A\xb2\x03\x00Canada/SaskatchewanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\x1d\xee\x91\x05\x04\x00\x00\x05\x04\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xb4\x03\x00Canada/YukonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]\x22_WJ\x05\x00\x00J\x05\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\xb9\x03\x00Chile/ContinentalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?X'\x8e\x96\x04\x00\x00\x96\x04\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x98\xbe\x03\x00Chile/EasterIslandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x1c\x9e\x9a]\x04\x00\x00]\x04\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00^\xc3\x03\x00CubaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`l\x8d~\xf1\x01\x00\x00\xf1\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd\xc7\x03\x00EETPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00tX\xbe\xe4o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xef\xc9\x03\x00ESTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe7/\xebT\xb7\x03\x00\x00\xb7\x03\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xca\x03\x00EST5EDTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5#)\x16\x1d\x05\x00\x00\x1d\x05\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00[\xce\x03\x00EgyptPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xd6jL\xd8\x05\x00\x00\xd8\x05\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xd3\x03\x00EirePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xd9\x03\x00Etc/GMTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\xda\x03\x00Etc/GMT+0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\xb8\xe8\x86q\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf\xda\x03\x00Etc/GMT+1PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8e\x1569r\x00\x00\x00r\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00W\xdb\x03\x00Etc/GMT+10PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00)\xb9\xbe\x9dr\x00\x00\x00r\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\xdb\x03\x00Etc/GMT+11PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xf38cr\x00\x00\x00r\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\xdc\x03\x00Etc/GMT+12PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9{\xa2qq\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%\xdd\x03\x00Etc/GMT+2PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\xcb\xe9Qq\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd\xdd\x03\x00Etc/GMT+3PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\xfaFDq\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00U\xde\x03\x00Etc/GMT+4PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4X\x9b\xf3q\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\xde\x03\x00Etc/GMT+5PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\x9b\xd1\x04q\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\xdf\x03\x00Etc/GMT+6PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84+\x9a$q\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\xe0\x03\x00Etc/GMT+7PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x22\xf8\x8f/q\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb5\xe0\x03\x00Etc/GMT+8PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x19\xb3\x09q\x00\x00\x00q\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M\xe1\x03\x00Etc/GMT+9PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xe1\x03\x00Etc/GMT-0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\x1ac\xc3r\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{\xe2\x03\x00Etc/GMT-1PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9|\xbd7s\x00\x00\x00s\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\xe3\x03\x00Etc/GMT-10PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\xab\xd1Is\x00\x00\x00s\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xaf\xe3\x03\x00Etc/GMT-11PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf7\x19s\x81s\x00\x00\x00s\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\xe4\x03\x00Etc/GMT-12PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90`N\xe8s\x00\x00\x00s\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xe4\x03\x00Etc/GMT-13PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00,{\xdc;s\x00\x00\x00s\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xe5\x03\x00Etc/GMT-14PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbc\x19y\x04r\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xe6\x03\x00Etc/GMT-2PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9c\xfcm\x99r\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\xe6\x03\x00Etc/GMT-3PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x19<Qr\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00M\xe7\x03\x00Etc/GMT-4PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\xd6~wr\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xe7\x03\x00Etc/GMT-5PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00j\xd5d\xb0r\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x7f\xe8\x03\x00Etc/GMT-6PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J0p-r\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\xe9\x03\x00Etc/GMT-7PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\x18\xb6\xfbr\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1\xe9\x03\x00Etc/GMT-8PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\x19@\xb9r\x00\x00\x00r\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J\xea\x03\x00Etc/GMT-9PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe3\xea\x03\x00Etc/GMT0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\xeb\x03\x00Etc/GreenwichPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\xec\x03\x00Etc/UCTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa6\xec\x03\x00Etc/UTCPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:\xed\x03\x00Etc/UniversalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\xed\x03\x00Etc/ZuluPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00i\xee\x03\x00Europe/AmsterdamPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdf\x9cv\xcf\x85\x01\x00\x00\x85\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xf2\x03\x00Europe/AndorraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]i\x11u\xd6\x02\x00\x00\xd6\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97\xf4\x03\x00Europe/AstrakhanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcb*j\x8f\xaa\x02\x00\x00\xaa\x02\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xf7\x03\x00Europe/AthensPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xfa\x03\x00Europe/BelfastPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb\x00\x04\x00Europe/BelgradePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\x02\x04\x00Europe/BerlinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Io\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd2\x05\x04\x00Europe/BratislavaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\x08\x04\x00Europe/BrusselsPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x90\xa9\xf5\xcf\x95\x02\x00\x00\x95\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x0d\x04\x00Europe/BucharestPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6Kf\xab\xfe\x02\x00\x00\xfe\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x13\x10\x04\x00Europe/BudapestPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x13\x04\x00Europe/BusingenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x5c\x15\x04\x00Europe/ChisinauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\x18\x04\x00Europe/CopenhagenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\xd6jL\xd8\x05\x00\x00\xd8\x05\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l\x1b\x04\x00Europe/DublinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00==\xa4\x16\xc4\x04\x00\x00\xc4\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o!\x04\x00Europe/GibraltarPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a&\x04\x00Europe/GuernseyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd,\x04\x00Europe/HelsinkiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdb.\x04\x00Europe/Isle_of_ManPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07W\x10\xd1\xb0\x04\x00\x00\xb0\x04\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00J5\x04\x00Europe/IstanbulPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00':\x04\x00Europe/JerseyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00O+j\x94\x88\x03\x00\x00\x88\x03\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91@\x04\x00Europe/KaliningradPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ID\x04\x00Europe/KievPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f(NN\xdf\x02\x00\x00\xdf\x02\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0F\x04\x00Europe/KirovPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9I\x04\x00Europe/KyivPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&S\x03\x09\xae\x05\x00\x00\xae\x05\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00L\x04\x00Europe/LisbonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd9Q\x04\x00Europe/LjubljanaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5S\x04\x00Europe/LondonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00o\xbc\x831O\x04\x00\x00O\x04\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00OZ\x04\x00Europe/LuxembourgPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Zk#V\x81\x03\x00\x00\x81\x03\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xcd^\x04\x00Europe/MadridPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\xa5J[\xa0\x03\x00\x00\xa0\x03\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00yb\x04\x00Europe/MaltaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe5\xc8X\xa7\xe1\x01\x00\x00\xe1\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Cf\x04\x00Europe/MariehamnPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00WI\xc3\x7f(\x03\x00\x00(\x03\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Rh\x04\x00Europe/MinskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4k\x04\x00Europe/MonacoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 p\x04\x00Europe/MoscowPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03R\xda\xedU\x02\x00\x00U\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7s\x04\x00Europe/NicosiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Xv\x04\x00Europe/OsloPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\xf5\x94\xdaQ\x04\x00\x00Q\x04\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00By\x04\x00Europe/ParisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd}\x04\x00Europe/PodgoricaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Io\x11{\xd3\x02\x00\x00\xd3\x02\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc9\x7f\x04\x00Europe/PraguePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00gp\xc0\xa7\xb6\x02\x00\x00\xb6\x02\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\x82\x04\x00Europe/RigaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa6\x85\x04\x00Europe/RomePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\x7fpp\xdc\x02\x00\x00\xdc\x02\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x82\x89\x04\x00Europe/SamaraPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x89\x8c\x04\x00Europe/San_MarinoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x90\x04\x00Europe/SarajevoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b8\xfel\xd6\x02\x00\x00\xd6\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00v\x92\x04\x00Europe/SaratovPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00}\xb4N\xb8a\x03\x00\x00a\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x95\x04\x00Europe/SimferopolPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x99\x04\x00Europe/SkopjePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xc8\x15\xd0P\x02\x00\x00P\x02\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x9b\x04\x00Europe/SofiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17S\x91\xb3\xc1\x02\x00\x00\xc1\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b\x9d\x04\x00Europe/StockholmPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\x16\x9b?\xa3\x02\x00\x00\xa3\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00z\xa0\x04\x00Europe/TallinnPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\xc48\xde\x5c\x02\x00\x00\x5c\x02\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xa3\x04\x00Europe/TiranePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00I\xb8\xbc\xd3\xf3\x02\x00\x00\xf3\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd0\xa5\x04\x00Europe/TiraspolPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u\xb0\xcd\xfc\xf8\x02\x00\x00\xf8\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0\xa8\x04\x00Europe/UlyanovskPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\xac\x04\x00Europe/UzhgorodPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xae\x04\x00Europe/VaduzPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95\xb4\x9e\xe7\xb3\x03\x00\x00\xb3\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xb0\x04\x00Europe/VaticanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\x05w\xd7\x92\x02\x00\x00\x92\x02\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xb4\x04\x00Europe/ViennaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xccb\xf72\xa4\x02\x00\x00\xa4\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00(\xb7\x04\x00Europe/VilniusPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xec\xa0%\xf1\x02\x00\x00\xf1\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\xb9\x04\x00Europe/VolgogradPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xfe\xe5\x9e\x9b\x03\x00\x00\x9b\x03\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\xbd\x04\x00Europe/WarsawPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1C\xf9\xa1\xde\x01\x00\x00\xde\x01\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdd\xc0\x04\x00Europe/ZagrebPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00iS\x18D.\x02\x00\x00.\x02\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6\xc2\x04\x00Europe/ZaporozhyePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Dd#\xc4\xf1\x01\x00\x00\xf1\x01\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C\xc5\x04\x00Europe/ZurichPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x80c$q\x00\x00\x00q\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\xc7\x04\x00FactoryPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf5\xc7\x04\x00GBPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\xa4,\xb6?\x06\x00\x00?\x06\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00T\xce\x04\x00GB-EirePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8\xd4\x04\x00GMTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00H\xd5\x04\x00GMT+0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xda\xd5\x04\x00GMT-0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l\xd6\x04\x00GMT0PK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xda\xfa\x03o\x00\x00\x00o\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd\xd6\x04\x00GreenwichPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00=\xf7\xfawp\x00\x00\x00p\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x93\xd7\x04\x00HSTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\x09\xfa-\x07\x03\x00\x00\x07\x03\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\xd8\x04\x00HongkongPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf1\x08{\x87\x82\x00\x00\x00\x82\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Q\xdb\x04\x00IcelandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\xdb\x04\x00Indian/AntananarivoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\xb0W\x14\x98\x00\x00\x00\x98\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\xdc\x04\x00Indian/ChagosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x88\xf6C\x84\x98\x00\x00\x00\x98\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\xdd\x04\x00Indian/ChristmasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xca\x87{_\xbb\x00\x00\x00\xbb\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\xde\x04\x00Indian/CocosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\xdf\x04\x00Indian/ComoroPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@\xe0\x04\x00Indian/KerguelenPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\xe1\x04\x00Indian/MahePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9\xb2Z\xac\x98\x00\x00\x00\x98\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\xe1\x04\x00Indian/MaldivesPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xed=\x98\xb3\x00\x00\x00\xb3\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00y\xe2\x04\x00Indian/MauritiusPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb4\x8d\x98\xc6\xbf\x00\x00\x00\xbf\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Z\xe3\x04\x00Indian/MayottePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xed\x8c\xf1\x91\x85\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00E\xe4\x04\x00Indian/ReunionPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8c\xdb?\xec,\x03\x00\x00,\x03\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe4\x04\x00IranPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\xe2\x9c\xb32\x04\x00\x002\x04\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D\xe8\x04\x00IsraelPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00%J\xd5\xebS\x01\x00\x00S\x01\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xec\x04\x00JamaicaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xf4\xaeg\xd5\x00\x00\x00\xd5\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\xee\x04\x00JapanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0a\xef\x04\x00KwajaleinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00_\x7f2[\xaf\x01\x00\x00\xaf\x01\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c\xf0\x04\x00LibyaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\x9d\x1b\xc9m\x02\x00\x00m\x02\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xde\xf1\x04\x00METPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf5\x8d\x99\x92o\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00l\xf4\x04\x00MSTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe6h\xcac\xb7\x03\x00\x00\xb7\x03\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfc\xf4\x04\x00MST7MDTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb9B$\x90\x01\x04\x00\x00\x01\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd8\xf8\x04\x00Mexico/BajaNortePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1b\xad=\x98\xce\x02\x00\x00\xce\x02\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\xfd\x04\x00Mexico/BajaSurPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5\x08\x89\x8c\x05\x03\x00\x00\x05\x03\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x05\x00Mexico/GeneralPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x03\x05\x00NZPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e\x07\x05\x00NZ-CHATPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb2\x0a\x05\x00NavajoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00*\xe4@\xa9\x89\x01\x00\x00\x89\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x0e\x05\x00PRCPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc5\xadV\xad\xb7\x03\x00\x00\xb7\x03\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x92\x10\x05\x00PST8PDTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa8A\x15\xfe\x97\x01\x00\x00\x97\x01\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x14\x05\x00Pacific/ApiaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xb2\xaf\xf7\x13\x04\x00\x00\x13\x04\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/\x16\x05\x00Pacific/AucklandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9a\xf2:F\xc9\x00\x00\x00\xc9\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\x1a\x05\x00Pacific/BougainvillePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x96\xc5FF(\x03\x00\x00(\x03\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00k\x1b\x05\x00Pacific/ChathamPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x1e\x05\x00Pacific/ChuukPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00?X'\x8e\x96\x04\x00\x00\x96\x04\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x85\x1f\x05\x00Pacific/EasterPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9e\x7f\xab\x95V\x01\x00\x00V\x01\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G$\x05\x00Pacific/EfatePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8%\x05\x00Pacific/EnderburyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8a|\xdcU\x99\x00\x00\x00\x99\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa3&\x05\x00Pacific/FakaofoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfd_yl\x8c\x01\x00\x00\x8c\x01\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00i'\x05\x00Pacific/FijiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f)\x05\x00Pacific/FunafutiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x81\xe3w\x0a\xaf\x00\x00\x00\xaf\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd3)\x05\x00Pacific/GalapagosPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc23\xa0\xbc\x84\x00\x00\x00\x84\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb1*\x05\x00Pacific/GambierPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b+\x05\x00Pacific/GuadalcanalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FI\xfe\x14^\x01\x00\x00^\x01\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19,\x05\x00Pacific/GuamPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1-\x05\x00Pacific/HonoluluPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xac.\x05\x00Pacific/JohnstonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xec =\x89\xac\x00\x00\x00\xac\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7/\x05\x00Pacific/KantonPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8=ku\xae\x00\x00\x00\xae\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8f0\x05\x00Pacific/KiritimatiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97n7\x1a\xf2\x00\x00\x00\xf2\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00m1\x05\x00Pacific/KosraePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\xe8]*\xdb\x00\x00\x00\xdb\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8b2\x05\x00Pacific/KwajaleinPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x953\x05\x00Pacific/MajuroPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00D6\x83\xa1\x8b\x00\x00\x00\x8b\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00G4\x05\x00Pacific/MarquesasPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x015\x05\x00Pacific/MidwayPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe2;Z\xf7\xb7\x00\x00\x00\xb7\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbf5\x05\x00Pacific/NauruPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91\xd60\x0c\x9a\x00\x00\x00\x9a\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa16\x05\x00Pacific/NiuePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y5\x1a6\xf7\x00\x00\x00\xf7\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e7\x05\x00Pacific/NorfolkPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb7\xef\x97\xc6\xc6\x00\x00\x00\xc6\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x898\x05\x00Pacific/NoumeaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00{9\x05\x00Pacific/Pago_PagoPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xf8v\xdc\x94\x00\x00\x00\x94\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00<:\x05\x00Pacific/PalauPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfa\x0fA\x05\x99\x00\x00\x00\x99\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfb:\x05\x00Pacific/PitcairnPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc2;\x05\x00Pacific/PohnpeiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Y\xd2K|\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u<\x05\x00Pacific/PonapePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'=\x05\x00Pacific/Port_MoresbyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1c\xe3\xa3S\x96\x01\x00\x00\x96\x01\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf3=\x05\x00Pacific/RarotongaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00FI\xfe\x14^\x01\x00\x00^\x01\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb8?\x05\x00Pacific/SaipanPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x0d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00BA\x05\x00Pacific/SamoaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xea\xc1\xda\xcf\x85\x00\x00\x00\x85\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xffA\x05\x00Pacific/TahitiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb0B\x05\x00Pacific/TarawaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x97F\x91\xb3\xed\x00\x00\x00\xed\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00bC\x05\x00Pacific/TongatapuPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00~D\x05\x00Pacific/TrukPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00BE\x05\x00Pacific/WakePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006\xb7S{\x86\x00\x00\x00\x86\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf2E\x05\x00Pacific/WallisPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00n\x04\x19y\x9a\x00\x00\x00\x9a\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4F\x05\x00Pacific/YapPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xfe\xe5\x9e\x9b\x03\x00\x00\x9b\x03\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00gG\x05\x00PolandPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&S\x03\x09\xae\x05\x00\x00\xae\x05\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00&K\x05\x00PortugalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xee\xf0BB\xff\x01\x00\x00\xff\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfaP\x05\x00ROCPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7X,Y\x9f\x01\x00\x00\x9f\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1aS\x05\x00ROKPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00F7k\x1c\x00\x01\x00\x00\x00\x01\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xdaT\x05\x00SingaporePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07W\x10\xd1\xb0\x04\x00\x00\xb0\x04\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01V\x05\x00TurkeyPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd5Z\x05\x00UCTPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x005\x11Q\x06\xd1\x03\x00\x00\xd1\x03\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e[\x05\x00US/AlaskaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xae,\xa44\xc9\x03\x00\x00\xc9\x03\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00]_\x05\x00US/AleutianPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc3\xb8\xab\x9b\xf0\x00\x00\x00\xf0\x00\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Oc\x05\x00US/ArizonaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9b\xdc\xa9=\xda\x06\x00\x00\xda\x06\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00gd\x05\x00US/CentralPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00p\xb6{\xc9\x13\x02\x00\x00\x13\x02\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ik\x05\x00US/East-IndianaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x003\x9aG\xc8\xd0\x06\x00\x00\xd0\x06\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9m\x05\x00US/EasternPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xeaK\x85v\xdd\x00\x00\x00\xdd\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1t\x05\x00US/HawaiiPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ \x873\xf8\x03\x00\x00\xf8\x03\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa5u\x05\x00US/Indiana-StarkePK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\x14\xe7\x03\x83\x03\x00\x00\x83\x03\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xccy\x05\x00US/MichiganPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00V\x80\x94@\x12\x04\x00\x00\x12\x04\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x}\x05\x00US/MountainPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf6\x22\x12\xfe\x0e\x05\x00\x00\x0e\x05\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb3\x81\x05\x00US/PacificPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\xca{e\x92\x00\x00\x00\x92\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe9\x86\x05\x00US/SamoaPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa1\x87\x05\x00UTCPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x001\x88\x05\x00UniversalPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe1\xc1\xeb\x05\x8c\x03\x00\x00\x8c\x03\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc7\x88\x05\x00W-SUPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\x91B\xc0\xee\x01\x00\x00\xee\x01\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00u\x8c\x05\x00WETPK\x01\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f.\xe4xo\x00\x00\x00o\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x84\x8e\x05\x00ZuluPK\x05\x06\x00\x00\x00\x00U\x02U\x02m\x8c\x00\x00\x15\x8f\x05\x00\x00\x00"
diff --git a/contrib/go/_std_1.21/src/time/ya.make b/contrib/go/_std_1.21/src/time/ya.make
new file mode 100644
index 0000000000..0743d37e4d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/time/ya.make
@@ -0,0 +1,64 @@
+GO_LIBRARY()
+
+SRCS(
+ format.go
+ format_rfc3339.go
+ sleep.go
+ tick.go
+ time.go
+ zoneinfo.go
+ zoneinfo_goroot.go
+ zoneinfo_read.go
+)
+
+GO_TEST_SRCS(
+ export_test.go
+ internal_test.go
+)
+
+GO_XTEST_SRCS(
+ example_test.go
+ format_test.go
+ mono_test.go
+ sleep_test.go
+ tick_test.go
+ time_test.go
+ tzdata_test.go
+ zoneinfo_test.go
+)
+
+IF (OS_LINUX)
+ SRCS(
+ sys_unix.go
+ zoneinfo_unix.go
+ )
+
+ GO_XTEST_SRCS(zoneinfo_unix_test.go)
+ENDIF()
+
+IF (OS_DARWIN)
+ SRCS(
+ sys_unix.go
+ zoneinfo_unix.go
+ )
+
+ GO_XTEST_SRCS(zoneinfo_unix_test.go)
+ENDIF()
+
+IF (OS_WINDOWS)
+ SRCS(
+ sys_windows.go
+ zoneinfo_abbrs_windows.go
+ zoneinfo_windows.go
+ )
+
+ GO_TEST_SRCS(export_windows_test.go)
+
+ GO_XTEST_SRCS(zoneinfo_windows_test.go)
+ENDIF()
+
+END()
+
+RECURSE(
+ tzdata
+)
diff --git a/contrib/go/_std_1.20/src/time/zoneinfo.go b/contrib/go/_std_1.21/src/time/zoneinfo.go
index 4edcf3d98f..4edcf3d98f 100644
--- a/contrib/go/_std_1.20/src/time/zoneinfo.go
+++ b/contrib/go/_std_1.21/src/time/zoneinfo.go
diff --git a/contrib/go/_std_1.21/src/time/zoneinfo_abbrs_windows.go b/contrib/go/_std_1.21/src/time/zoneinfo_abbrs_windows.go
new file mode 100644
index 0000000000..27831743e9
--- /dev/null
+++ b/contrib/go/_std_1.21/src/time/zoneinfo_abbrs_windows.go
@@ -0,0 +1,155 @@
+// Copyright 2013 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.
+
+// Code generated by genzabbrs.go; DO NOT EDIT.
+// Based on information from https://raw.githubusercontent.com/unicode-org/cldr/main/common/supplemental/windowsZones.xml
+
+package time
+
+type abbr struct {
+ std string
+ dst string
+}
+
+var abbrs = map[string]abbr{
+ "Egypt Standard Time": {"EET", "EEST"}, // Africa/Cairo
+ "Morocco Standard Time": {"+00", "+01"}, // Africa/Casablanca
+ "South Africa Standard Time": {"SAST", "SAST"}, // Africa/Johannesburg
+ "South Sudan Standard Time": {"CAT", "CAT"}, // Africa/Juba
+ "Sudan Standard Time": {"CAT", "CAT"}, // Africa/Khartoum
+ "W. Central Africa Standard Time": {"WAT", "WAT"}, // Africa/Lagos
+ "E. Africa Standard Time": {"EAT", "EAT"}, // Africa/Nairobi
+ "Sao Tome Standard Time": {"GMT", "GMT"}, // Africa/Sao_Tome
+ "Libya Standard Time": {"EET", "EET"}, // Africa/Tripoli
+ "Namibia Standard Time": {"CAT", "CAT"}, // Africa/Windhoek
+ "Aleutian Standard Time": {"HST", "HDT"}, // America/Adak
+ "Alaskan Standard Time": {"AKST", "AKDT"}, // America/Anchorage
+ "Tocantins Standard Time": {"-03", "-03"}, // America/Araguaina
+ "Paraguay Standard Time": {"-04", "-03"}, // America/Asuncion
+ "Bahia Standard Time": {"-03", "-03"}, // America/Bahia
+ "SA Pacific Standard Time": {"-05", "-05"}, // America/Bogota
+ "Argentina Standard Time": {"-03", "-03"}, // America/Buenos_Aires
+ "Eastern Standard Time (Mexico)": {"EST", "EST"}, // America/Cancun
+ "Venezuela Standard Time": {"-04", "-04"}, // America/Caracas
+ "SA Eastern Standard Time": {"-03", "-03"}, // America/Cayenne
+ "Central Standard Time": {"CST", "CDT"}, // America/Chicago
+ "Central Brazilian Standard Time": {"-04", "-04"}, // America/Cuiaba
+ "Mountain Standard Time": {"MST", "MDT"}, // America/Denver
+ "Greenland Standard Time": {"-03", "-02"}, // America/Godthab
+ "Turks And Caicos Standard Time": {"EST", "EDT"}, // America/Grand_Turk
+ "Central America Standard Time": {"CST", "CST"}, // America/Guatemala
+ "Atlantic Standard Time": {"AST", "ADT"}, // America/Halifax
+ "Cuba Standard Time": {"CST", "CDT"}, // America/Havana
+ "US Eastern Standard Time": {"EST", "EDT"}, // America/Indianapolis
+ "SA Western Standard Time": {"-04", "-04"}, // America/La_Paz
+ "Pacific Standard Time": {"PST", "PDT"}, // America/Los_Angeles
+ "Mountain Standard Time (Mexico)": {"MST", "MST"}, // America/Mazatlan
+ "Central Standard Time (Mexico)": {"CST", "CST"}, // America/Mexico_City
+ "Saint Pierre Standard Time": {"-03", "-02"}, // America/Miquelon
+ "Montevideo Standard Time": {"-03", "-03"}, // America/Montevideo
+ "Eastern Standard Time": {"EST", "EDT"}, // America/New_York
+ "US Mountain Standard Time": {"MST", "MST"}, // America/Phoenix
+ "Haiti Standard Time": {"EST", "EDT"}, // America/Port-au-Prince
+ "Magallanes Standard Time": {"-03", "-03"}, // America/Punta_Arenas
+ "Canada Central Standard Time": {"CST", "CST"}, // America/Regina
+ "Pacific SA Standard Time": {"-04", "-03"}, // America/Santiago
+ "E. South America Standard Time": {"-03", "-03"}, // America/Sao_Paulo
+ "Newfoundland Standard Time": {"NST", "NDT"}, // America/St_Johns
+ "Pacific Standard Time (Mexico)": {"PST", "PDT"}, // America/Tijuana
+ "Yukon Standard Time": {"MST", "MST"}, // America/Whitehorse
+ "Central Asia Standard Time": {"+06", "+06"}, // Asia/Almaty
+ "Jordan Standard Time": {"+03", "+03"}, // Asia/Amman
+ "Arabic Standard Time": {"+03", "+03"}, // Asia/Baghdad
+ "Azerbaijan Standard Time": {"+04", "+04"}, // Asia/Baku
+ "SE Asia Standard Time": {"+07", "+07"}, // Asia/Bangkok
+ "Altai Standard Time": {"+07", "+07"}, // Asia/Barnaul
+ "Middle East Standard Time": {"EET", "EEST"}, // Asia/Beirut
+ "India Standard Time": {"IST", "IST"}, // Asia/Calcutta
+ "Transbaikal Standard Time": {"+09", "+09"}, // Asia/Chita
+ "Sri Lanka Standard Time": {"+0530", "+0530"}, // Asia/Colombo
+ "Syria Standard Time": {"+03", "+03"}, // Asia/Damascus
+ "Bangladesh Standard Time": {"+06", "+06"}, // Asia/Dhaka
+ "Arabian Standard Time": {"+04", "+04"}, // Asia/Dubai
+ "West Bank Standard Time": {"EET", "EEST"}, // Asia/Hebron
+ "W. Mongolia Standard Time": {"+07", "+07"}, // Asia/Hovd
+ "North Asia East Standard Time": {"+08", "+08"}, // Asia/Irkutsk
+ "Israel Standard Time": {"IST", "IDT"}, // Asia/Jerusalem
+ "Afghanistan Standard Time": {"+0430", "+0430"}, // Asia/Kabul
+ "Russia Time Zone 11": {"+12", "+12"}, // Asia/Kamchatka
+ "Pakistan Standard Time": {"PKT", "PKT"}, // Asia/Karachi
+ "Nepal Standard Time": {"+0545", "+0545"}, // Asia/Katmandu
+ "North Asia Standard Time": {"+07", "+07"}, // Asia/Krasnoyarsk
+ "Magadan Standard Time": {"+11", "+11"}, // Asia/Magadan
+ "N. Central Asia Standard Time": {"+07", "+07"}, // Asia/Novosibirsk
+ "Omsk Standard Time": {"+06", "+06"}, // Asia/Omsk
+ "North Korea Standard Time": {"KST", "KST"}, // Asia/Pyongyang
+ "Qyzylorda Standard Time": {"+05", "+05"}, // Asia/Qyzylorda
+ "Myanmar Standard Time": {"+0630", "+0630"}, // Asia/Rangoon
+ "Arab Standard Time": {"+03", "+03"}, // Asia/Riyadh
+ "Sakhalin Standard Time": {"+11", "+11"}, // Asia/Sakhalin
+ "Korea Standard Time": {"KST", "KST"}, // Asia/Seoul
+ "China Standard Time": {"CST", "CST"}, // Asia/Shanghai
+ "Singapore Standard Time": {"+08", "+08"}, // Asia/Singapore
+ "Russia Time Zone 10": {"+11", "+11"}, // Asia/Srednekolymsk
+ "Taipei Standard Time": {"CST", "CST"}, // Asia/Taipei
+ "West Asia Standard Time": {"+05", "+05"}, // Asia/Tashkent
+ "Georgian Standard Time": {"+04", "+04"}, // Asia/Tbilisi
+ "Iran Standard Time": {"+0330", "+0330"}, // Asia/Tehran
+ "Tokyo Standard Time": {"JST", "JST"}, // Asia/Tokyo
+ "Tomsk Standard Time": {"+07", "+07"}, // Asia/Tomsk
+ "Ulaanbaatar Standard Time": {"+08", "+08"}, // Asia/Ulaanbaatar
+ "Vladivostok Standard Time": {"+10", "+10"}, // Asia/Vladivostok
+ "Yakutsk Standard Time": {"+09", "+09"}, // Asia/Yakutsk
+ "Ekaterinburg Standard Time": {"+05", "+05"}, // Asia/Yekaterinburg
+ "Caucasus Standard Time": {"+04", "+04"}, // Asia/Yerevan
+ "Azores Standard Time": {"-01", "+00"}, // Atlantic/Azores
+ "Cape Verde Standard Time": {"-01", "-01"}, // Atlantic/Cape_Verde
+ "Greenwich Standard Time": {"GMT", "GMT"}, // Atlantic/Reykjavik
+ "Cen. Australia Standard Time": {"ACST", "ACDT"}, // Australia/Adelaide
+ "E. Australia Standard Time": {"AEST", "AEST"}, // Australia/Brisbane
+ "AUS Central Standard Time": {"ACST", "ACST"}, // Australia/Darwin
+ "Aus Central W. Standard Time": {"+0845", "+0845"}, // Australia/Eucla
+ "Tasmania Standard Time": {"AEST", "AEDT"}, // Australia/Hobart
+ "Lord Howe Standard Time": {"+1030", "+11"}, // Australia/Lord_Howe
+ "W. Australia Standard Time": {"AWST", "AWST"}, // Australia/Perth
+ "AUS Eastern Standard Time": {"AEST", "AEDT"}, // Australia/Sydney
+ "UTC-11": {"-11", "-11"}, // Etc/GMT+11
+ "Dateline Standard Time": {"-12", "-12"}, // Etc/GMT+12
+ "UTC-02": {"-02", "-02"}, // Etc/GMT+2
+ "UTC-08": {"-08", "-08"}, // Etc/GMT+8
+ "UTC-09": {"-09", "-09"}, // Etc/GMT+9
+ "UTC+12": {"+12", "+12"}, // Etc/GMT-12
+ "UTC+13": {"+13", "+13"}, // Etc/GMT-13
+ "UTC": {"UTC", "UTC"}, // Etc/UTC
+ "Astrakhan Standard Time": {"+04", "+04"}, // Europe/Astrakhan
+ "W. Europe Standard Time": {"CET", "CEST"}, // Europe/Berlin
+ "GTB Standard Time": {"EET", "EEST"}, // Europe/Bucharest
+ "Central Europe Standard Time": {"CET", "CEST"}, // Europe/Budapest
+ "E. Europe Standard Time": {"EET", "EEST"}, // Europe/Chisinau
+ "Turkey Standard Time": {"+03", "+03"}, // Europe/Istanbul
+ "Kaliningrad Standard Time": {"EET", "EET"}, // Europe/Kaliningrad
+ "FLE Standard Time": {"EET", "EEST"}, // Europe/Kiev
+ "GMT Standard Time": {"GMT", "BST"}, // Europe/London
+ "Belarus Standard Time": {"+03", "+03"}, // Europe/Minsk
+ "Russian Standard Time": {"MSK", "MSK"}, // Europe/Moscow
+ "Romance Standard Time": {"CET", "CEST"}, // Europe/Paris
+ "Russia Time Zone 3": {"+04", "+04"}, // Europe/Samara
+ "Saratov Standard Time": {"+04", "+04"}, // Europe/Saratov
+ "Volgograd Standard Time": {"MSK", "MSK"}, // Europe/Volgograd
+ "Central European Standard Time": {"CET", "CEST"}, // Europe/Warsaw
+ "Mauritius Standard Time": {"+04", "+04"}, // Indian/Mauritius
+ "Samoa Standard Time": {"+13", "+13"}, // Pacific/Apia
+ "New Zealand Standard Time": {"NZST", "NZDT"}, // Pacific/Auckland
+ "Bougainville Standard Time": {"+11", "+11"}, // Pacific/Bougainville
+ "Chatham Islands Standard Time": {"+1245", "+1345"}, // Pacific/Chatham
+ "Easter Island Standard Time": {"-06", "-05"}, // Pacific/Easter
+ "Fiji Standard Time": {"+12", "+12"}, // Pacific/Fiji
+ "Central Pacific Standard Time": {"+11", "+11"}, // Pacific/Guadalcanal
+ "Hawaiian Standard Time": {"HST", "HST"}, // Pacific/Honolulu
+ "Line Islands Standard Time": {"+14", "+14"}, // Pacific/Kiritimati
+ "Marquesas Standard Time": {"-0930", "-0930"}, // Pacific/Marquesas
+ "Norfolk Standard Time": {"+11", "+12"}, // Pacific/Norfolk
+ "West Pacific Standard Time": {"+10", "+10"}, // Pacific/Port_Moresby
+ "Tonga Standard Time": {"+13", "+13"}, // Pacific/Tongatapu
+}
diff --git a/contrib/go/_std_1.20/src/time/zoneinfo_goroot.go b/contrib/go/_std_1.21/src/time/zoneinfo_goroot.go
index 92bdcf4afe..92bdcf4afe 100644
--- a/contrib/go/_std_1.20/src/time/zoneinfo_goroot.go
+++ b/contrib/go/_std_1.21/src/time/zoneinfo_goroot.go
diff --git a/contrib/go/_std_1.21/src/time/zoneinfo_read.go b/contrib/go/_std_1.21/src/time/zoneinfo_read.go
new file mode 100644
index 0000000000..4d0e47d890
--- /dev/null
+++ b/contrib/go/_std_1.21/src/time/zoneinfo_read.go
@@ -0,0 +1,597 @@
+// Copyright 2009 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.
+
+// Parse "zoneinfo" time zone file.
+// This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others.
+// See tzfile(5), https://en.wikipedia.org/wiki/Zoneinfo,
+// and ftp://munnari.oz.au/pub/oldtz/
+
+package time
+
+import (
+ "errors"
+ "runtime"
+ "syscall"
+)
+
+// registerLoadFromEmbeddedTZData is called by the time/tzdata package,
+// if it is imported.
+func registerLoadFromEmbeddedTZData(f func(string) (string, error)) {
+ loadFromEmbeddedTZData = f
+}
+
+// loadFromEmbeddedTZData is used to load a specific tzdata file
+// from tzdata information embedded in the binary itself.
+// This is set when the time/tzdata package is imported,
+// via registerLoadFromEmbeddedTzdata.
+var loadFromEmbeddedTZData func(zipname string) (string, error)
+
+// maxFileSize is the max permitted size of files read by readFile.
+// As reference, the zoneinfo.zip distributed by Go is ~350 KB,
+// so 10MB is overkill.
+const maxFileSize = 10 << 20
+
+type fileSizeError string
+
+func (f fileSizeError) Error() string {
+ return "time: file " + string(f) + " is too large"
+}
+
+// Copies of io.Seek* constants to avoid importing "io":
+const (
+ seekStart = 0
+ seekCurrent = 1
+ seekEnd = 2
+)
+
+// Simple I/O interface to binary blob of data.
+type dataIO struct {
+ p []byte
+ error bool
+}
+
+func (d *dataIO) read(n int) []byte {
+ if len(d.p) < n {
+ d.p = nil
+ d.error = true
+ return nil
+ }
+ p := d.p[0:n]
+ d.p = d.p[n:]
+ return p
+}
+
+func (d *dataIO) big4() (n uint32, ok bool) {
+ p := d.read(4)
+ if len(p) < 4 {
+ d.error = true
+ return 0, false
+ }
+ return uint32(p[3]) | uint32(p[2])<<8 | uint32(p[1])<<16 | uint32(p[0])<<24, true
+}
+
+func (d *dataIO) big8() (n uint64, ok bool) {
+ n1, ok1 := d.big4()
+ n2, ok2 := d.big4()
+ if !ok1 || !ok2 {
+ d.error = true
+ return 0, false
+ }
+ return (uint64(n1) << 32) | uint64(n2), true
+}
+
+func (d *dataIO) byte() (n byte, ok bool) {
+ p := d.read(1)
+ if len(p) < 1 {
+ d.error = true
+ return 0, false
+ }
+ return p[0], true
+}
+
+// read returns the read of the data in the buffer.
+func (d *dataIO) rest() []byte {
+ r := d.p
+ d.p = nil
+ return r
+}
+
+// Make a string by stopping at the first NUL
+func byteString(p []byte) string {
+ for i := 0; i < len(p); i++ {
+ if p[i] == 0 {
+ return string(p[0:i])
+ }
+ }
+ return string(p)
+}
+
+var errBadData = errors.New("malformed time zone information")
+
+// LoadLocationFromTZData returns a Location with the given name
+// initialized from the IANA Time Zone database-formatted data.
+// The data should be in the format of a standard IANA time zone file
+// (for example, the content of /etc/localtime on Unix systems).
+func LoadLocationFromTZData(name string, data []byte) (*Location, error) {
+ d := dataIO{data, false}
+
+ // 4-byte magic "TZif"
+ if magic := d.read(4); string(magic) != "TZif" {
+ return nil, errBadData
+ }
+
+ // 1-byte version, then 15 bytes of padding
+ var version int
+ var p []byte
+ if p = d.read(16); len(p) != 16 {
+ return nil, errBadData
+ } else {
+ switch p[0] {
+ case 0:
+ version = 1
+ case '2':
+ version = 2
+ case '3':
+ version = 3
+ default:
+ return nil, errBadData
+ }
+ }
+
+ // six big-endian 32-bit integers:
+ // number of UTC/local indicators
+ // number of standard/wall indicators
+ // number of leap seconds
+ // number of transition times
+ // number of local time zones
+ // number of characters of time zone abbrev strings
+ const (
+ NUTCLocal = iota
+ NStdWall
+ NLeap
+ NTime
+ NZone
+ NChar
+ )
+ var n [6]int
+ for i := 0; i < 6; i++ {
+ nn, ok := d.big4()
+ if !ok {
+ return nil, errBadData
+ }
+ if uint32(int(nn)) != nn {
+ return nil, errBadData
+ }
+ n[i] = int(nn)
+ }
+
+ // If we have version 2 or 3, then the data is first written out
+ // in a 32-bit format, then written out again in a 64-bit format.
+ // Skip the 32-bit format and read the 64-bit one, as it can
+ // describe a broader range of dates.
+
+ is64 := false
+ if version > 1 {
+ // Skip the 32-bit data.
+ skip := n[NTime]*4 +
+ n[NTime] +
+ n[NZone]*6 +
+ n[NChar] +
+ n[NLeap]*8 +
+ n[NStdWall] +
+ n[NUTCLocal]
+ // Skip the version 2 header that we just read.
+ skip += 4 + 16
+ d.read(skip)
+
+ is64 = true
+
+ // Read the counts again, they can differ.
+ for i := 0; i < 6; i++ {
+ nn, ok := d.big4()
+ if !ok {
+ return nil, errBadData
+ }
+ if uint32(int(nn)) != nn {
+ return nil, errBadData
+ }
+ n[i] = int(nn)
+ }
+ }
+
+ size := 4
+ if is64 {
+ size = 8
+ }
+
+ // Transition times.
+ txtimes := dataIO{d.read(n[NTime] * size), false}
+
+ // Time zone indices for transition times.
+ txzones := d.read(n[NTime])
+
+ // Zone info structures
+ zonedata := dataIO{d.read(n[NZone] * 6), false}
+
+ // Time zone abbreviations.
+ abbrev := d.read(n[NChar])
+
+ // Leap-second time pairs
+ d.read(n[NLeap] * (size + 4))
+
+ // Whether tx times associated with local time types
+ // are specified as standard time or wall time.
+ isstd := d.read(n[NStdWall])
+
+ // Whether tx times associated with local time types
+ // are specified as UTC or local time.
+ isutc := d.read(n[NUTCLocal])
+
+ if d.error { // ran out of data
+ return nil, errBadData
+ }
+
+ var extend string
+ rest := d.rest()
+ if len(rest) > 2 && rest[0] == '\n' && rest[len(rest)-1] == '\n' {
+ extend = string(rest[1 : len(rest)-1])
+ }
+
+ // Now we can build up a useful data structure.
+ // First the zone information.
+ // utcoff[4] isdst[1] nameindex[1]
+ nzone := n[NZone]
+ if nzone == 0 {
+ // Reject tzdata files with no zones. There's nothing useful in them.
+ // This also avoids a panic later when we add and then use a fake transition (golang.org/issue/29437).
+ return nil, errBadData
+ }
+ zones := make([]zone, nzone)
+ for i := range zones {
+ var ok bool
+ var n uint32
+ if n, ok = zonedata.big4(); !ok {
+ return nil, errBadData
+ }
+ if uint32(int(n)) != n {
+ return nil, errBadData
+ }
+ zones[i].offset = int(int32(n))
+ var b byte
+ if b, ok = zonedata.byte(); !ok {
+ return nil, errBadData
+ }
+ zones[i].isDST = b != 0
+ if b, ok = zonedata.byte(); !ok || int(b) >= len(abbrev) {
+ return nil, errBadData
+ }
+ 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
+ zones[i].name = name[4:]
+ }
+ }
+ }
+
+ // Now the transition time info.
+ tx := make([]zoneTrans, n[NTime])
+ for i := range tx {
+ var n int64
+ if !is64 {
+ if n4, ok := txtimes.big4(); !ok {
+ return nil, errBadData
+ } else {
+ n = int64(int32(n4))
+ }
+ } else {
+ if n8, ok := txtimes.big8(); !ok {
+ return nil, errBadData
+ } else {
+ n = int64(n8)
+ }
+ }
+ tx[i].when = n
+ if int(txzones[i]) >= len(zones) {
+ return nil, errBadData
+ }
+ tx[i].index = txzones[i]
+ if i < len(isstd) {
+ tx[i].isstd = isstd[i] != 0
+ }
+ if i < len(isutc) {
+ tx[i].isutc = isutc[i] != 0
+ }
+ }
+
+ if len(tx) == 0 {
+ // Build fake transition to cover all time.
+ // This happens in fixed locations like "Etc/GMT0".
+ tx = append(tx, zoneTrans{when: alpha, index: 0})
+ }
+
+ // Committed to succeed.
+ 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.
+ sec, _, _ := now()
+ for i := range tx {
+ if tx[i].when <= sec && (i+1 == len(tx) || sec < tx[i+1].when) {
+ l.cacheStart = tx[i].when
+ l.cacheEnd = omega
+ 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, offset, estart, eend, isDST, ok := tzset(l.extend, l.cacheStart, sec); ok {
+ l.cacheStart = estart
+ l.cacheEnd = eend
+ // 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,
+ }
+ }
+ }
+ }
+ break
+ }
+ }
+
+ 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) {
+ if len(dir) > 4 && dir[len(dir)-4:] == ".zip" {
+ return loadTzinfoFromZip(dir, name)
+ }
+ if dir != "" {
+ name = dir + "/" + name
+ }
+ return readFile(name)
+}
+
+// There are 500+ zoneinfo files. Rather than distribute them all
+// individually, we ship them in an uncompressed zip file.
+// Used this way, the zip file format serves as a commonly readable
+// container for the individual small files. We choose zip over tar
+// because zip files have a contiguous table of contents, making
+// individual file lookups faster, and because the per-file overhead
+// in a zip file is considerably less than tar's 512 bytes.
+
+// get4 returns the little-endian 32-bit value in b.
+func get4(b []byte) int {
+ if len(b) < 4 {
+ return 0
+ }
+ return int(b[0]) | int(b[1])<<8 | int(b[2])<<16 | int(b[3])<<24
+}
+
+// get2 returns the little-endian 16-bit value in b.
+func get2(b []byte) int {
+ if len(b) < 2 {
+ return 0
+ }
+ return int(b[0]) | int(b[1])<<8
+}
+
+// loadTzinfoFromZip returns the contents of the file with the given name
+// in the given uncompressed zip file.
+func loadTzinfoFromZip(zipfile, name string) ([]byte, error) {
+ fd, err := open(zipfile)
+ if err != nil {
+ return nil, err
+ }
+ defer closefd(fd)
+
+ const (
+ zecheader = 0x06054b50
+ zcheader = 0x02014b50
+ ztailsize = 22
+
+ zheadersize = 30
+ zheader = 0x04034b50
+ )
+
+ buf := make([]byte, ztailsize)
+ if err := preadn(fd, buf, -ztailsize); err != nil || get4(buf) != zecheader {
+ return nil, errors.New("corrupt zip file " + zipfile)
+ }
+ n := get2(buf[10:])
+ size := get4(buf[12:])
+ off := get4(buf[16:])
+
+ buf = make([]byte, size)
+ if err := preadn(fd, buf, off); err != nil {
+ return nil, errors.New("corrupt zip file " + zipfile)
+ }
+
+ for i := 0; i < n; i++ {
+ // zip entry layout:
+ // 0 magic[4]
+ // 4 madevers[1]
+ // 5 madeos[1]
+ // 6 extvers[1]
+ // 7 extos[1]
+ // 8 flags[2]
+ // 10 meth[2]
+ // 12 modtime[2]
+ // 14 moddate[2]
+ // 16 crc[4]
+ // 20 csize[4]
+ // 24 uncsize[4]
+ // 28 namelen[2]
+ // 30 xlen[2]
+ // 32 fclen[2]
+ // 34 disknum[2]
+ // 36 iattr[2]
+ // 38 eattr[4]
+ // 42 off[4]
+ // 46 name[namelen]
+ // 46+namelen+xlen+fclen - next header
+ //
+ if get4(buf) != zcheader {
+ break
+ }
+ meth := get2(buf[10:])
+ size := get4(buf[24:])
+ namelen := get2(buf[28:])
+ xlen := get2(buf[30:])
+ fclen := get2(buf[32:])
+ off := get4(buf[42:])
+ zname := buf[46 : 46+namelen]
+ buf = buf[46+namelen+xlen+fclen:]
+ if string(zname) != name {
+ continue
+ }
+ if meth != 0 {
+ return nil, errors.New("unsupported compression for " + name + " in " + zipfile)
+ }
+
+ // zip per-file header layout:
+ // 0 magic[4]
+ // 4 extvers[1]
+ // 5 extos[1]
+ // 6 flags[2]
+ // 8 meth[2]
+ // 10 modtime[2]
+ // 12 moddate[2]
+ // 14 crc[4]
+ // 18 csize[4]
+ // 22 uncsize[4]
+ // 26 namelen[2]
+ // 28 xlen[2]
+ // 30 name[namelen]
+ // 30+namelen+xlen - file data
+ //
+ buf = make([]byte, zheadersize+namelen)
+ if err := preadn(fd, buf, off); err != nil ||
+ get4(buf) != zheader ||
+ get2(buf[8:]) != meth ||
+ get2(buf[26:]) != namelen ||
+ string(buf[30:30+namelen]) != name {
+ return nil, errors.New("corrupt zip file " + zipfile)
+ }
+ xlen = get2(buf[28:])
+
+ buf = make([]byte, size)
+ if err := preadn(fd, buf, off+30+namelen+xlen); err != nil {
+ return nil, errors.New("corrupt zip file " + zipfile)
+ }
+
+ return buf, nil
+ }
+
+ return nil, syscall.ENOENT
+}
+
+// loadTzinfoFromTzdata returns the time zone information of the time zone
+// with the given name, from a tzdata database file as they are typically
+// found on android.
+var loadTzinfoFromTzdata func(file, name string) ([]byte, error)
+
+// loadTzinfo returns the time zone information of the time zone
+// with the given name, from a given source. A source may be a
+// timezone database directory, tzdata database file or an uncompressed
+// zip file, containing the contents of such a directory.
+func loadTzinfo(name string, source string) ([]byte, error) {
+ if len(source) >= 6 && source[len(source)-6:] == "tzdata" {
+ return loadTzinfoFromTzdata(source, name)
+ }
+ return loadTzinfoFromDirOrZip(source, name)
+}
+
+// loadLocation returns the Location with the given name from one of
+// the specified sources. See loadTzinfo for a list of supported sources.
+// The first timezone data matching the given name that is successfully loaded
+// and parsed is returned as a Location.
+func loadLocation(name string, sources []string) (z *Location, firstErr error) {
+ for _, source := range sources {
+ zoneData, err := loadTzinfo(name, source)
+ if err == nil {
+ if z, err = LoadLocationFromTZData(name, zoneData); err == nil {
+ return z, nil
+ }
+ }
+ if firstErr == nil && err != syscall.ENOENT {
+ firstErr = err
+ }
+ }
+ if loadFromEmbeddedTZData != nil {
+ zoneData, err := loadFromEmbeddedTZData(name)
+ if err == nil {
+ if z, err = LoadLocationFromTZData(name, []byte(zoneData)); err == nil {
+ return z, nil
+ }
+ }
+ if firstErr == nil && err != syscall.ENOENT {
+ firstErr = err
+ }
+ }
+ if source, ok := gorootZoneSource(runtime.GOROOT()); ok {
+ zoneData, err := loadTzinfo(name, source)
+ if err == nil {
+ if z, err = LoadLocationFromTZData(name, zoneData); err == nil {
+ return z, nil
+ }
+ }
+ if firstErr == nil && err != syscall.ENOENT {
+ firstErr = err
+ }
+ }
+ if firstErr != nil {
+ return nil, firstErr
+ }
+ return nil, errors.New("unknown time zone " + name)
+}
+
+// readFile reads and returns the content of the named file.
+// It is a trivial implementation of os.ReadFile, reimplemented
+// here to avoid depending on io/ioutil or os.
+// It returns an error if name exceeds maxFileSize bytes.
+func readFile(name string) ([]byte, error) {
+ f, err := open(name)
+ if err != nil {
+ return nil, err
+ }
+ defer closefd(f)
+ var (
+ buf [4096]byte
+ ret []byte
+ n int
+ )
+ for {
+ n, err = read(f, buf[:])
+ if n > 0 {
+ ret = append(ret, buf[:n]...)
+ }
+ if n == 0 || err != nil {
+ break
+ }
+ if len(ret) > maxFileSize {
+ return nil, fileSizeError(name)
+ }
+ }
+ return ret, err
+}
diff --git a/contrib/go/_std_1.21/src/time/zoneinfo_unix.go b/contrib/go/_std_1.21/src/time/zoneinfo_unix.go
new file mode 100644
index 0000000000..b52c67d069
--- /dev/null
+++ b/contrib/go/_std_1.21/src/time/zoneinfo_unix.go
@@ -0,0 +1,69 @@
+// Copyright 2009 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.
+
+//go:build unix && !ios && !android
+
+// Parse "zoneinfo" time zone file.
+// This is a fairly standard file format used on OS X, Linux, BSD, Sun, and others.
+// See tzfile(5), https://en.wikipedia.org/wiki/Zoneinfo,
+// and ftp://munnari.oz.au/pub/oldtz/
+
+package time
+
+import (
+ "syscall"
+)
+
+// Many systems use /usr/share/zoneinfo, Solaris 2 has
+// /usr/share/lib/zoneinfo, IRIX 6 has /usr/lib/locale/TZ,
+// NixOS has /etc/zoneinfo.
+var platformZoneSources = []string{
+ "/usr/share/zoneinfo/",
+ "/usr/share/lib/zoneinfo/",
+ "/usr/lib/locale/TZ/",
+ "/etc/zoneinfo",
+}
+
+func initLocal() {
+ // consult $TZ to find the time zone to use.
+ // no $TZ means use the system default /etc/localtime.
+ // $TZ="" means use UTC.
+ // $TZ="foo" or $TZ=":foo" if foo is an absolute path, then the file pointed
+ // by foo will be used to initialize timezone; otherwise, file
+ // /usr/share/zoneinfo/foo will be used.
+
+ tz, ok := syscall.Getenv("TZ")
+ switch {
+ case !ok:
+ z, err := loadLocation("localtime", []string{"/etc"})
+ if err == nil {
+ localLoc = *z
+ localLoc.name = "Local"
+ return
+ }
+ case tz != "":
+ if tz[0] == ':' {
+ tz = tz[1:]
+ }
+ if tz != "" && tz[0] == '/' {
+ if z, err := loadLocation(tz, []string{""}); err == nil {
+ localLoc = *z
+ if tz == "/etc/localtime" {
+ localLoc.name = "Local"
+ } else {
+ localLoc.name = tz
+ }
+ return
+ }
+ } else if tz != "" && tz != "UTC" {
+ if z, err := loadLocation(tz, platformZoneSources); err == nil {
+ localLoc = *z
+ return
+ }
+ }
+ }
+
+ // Fall back to UTC.
+ localLoc.name = "UTC"
+}
diff --git a/contrib/go/_std_1.20/src/time/zoneinfo_windows.go b/contrib/go/_std_1.21/src/time/zoneinfo_windows.go
index 76d79759f7..76d79759f7 100644
--- a/contrib/go/_std_1.20/src/time/zoneinfo_windows.go
+++ b/contrib/go/_std_1.21/src/time/zoneinfo_windows.go
diff --git a/contrib/go/_std_1.20/src/unicode/casetables.go b/contrib/go/_std_1.21/src/unicode/casetables.go
index 29bf167e56..29bf167e56 100644
--- a/contrib/go/_std_1.20/src/unicode/casetables.go
+++ b/contrib/go/_std_1.21/src/unicode/casetables.go
diff --git a/contrib/go/_std_1.20/src/unicode/digit.go b/contrib/go/_std_1.21/src/unicode/digit.go
index 53171b3969..53171b3969 100644
--- a/contrib/go/_std_1.20/src/unicode/digit.go
+++ b/contrib/go/_std_1.21/src/unicode/digit.go
diff --git a/contrib/go/_std_1.20/src/unicode/graphic.go b/contrib/go/_std_1.21/src/unicode/graphic.go
index 2af29778bf..2af29778bf 100644
--- a/contrib/go/_std_1.20/src/unicode/graphic.go
+++ b/contrib/go/_std_1.21/src/unicode/graphic.go
diff --git a/contrib/go/_std_1.20/src/unicode/letter.go b/contrib/go/_std_1.21/src/unicode/letter.go
index f3f8e52964..f3f8e52964 100644
--- a/contrib/go/_std_1.20/src/unicode/letter.go
+++ b/contrib/go/_std_1.21/src/unicode/letter.go
diff --git a/contrib/go/_std_1.21/src/unicode/tables.go b/contrib/go/_std_1.21/src/unicode/tables.go
new file mode 100644
index 0000000000..a0c0e1ca51
--- /dev/null
+++ b/contrib/go/_std_1.21/src/unicode/tables.go
@@ -0,0 +1,8378 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+package unicode
+
+// Version is the Unicode edition from which the tables are derived.
+const Version = "15.0.0"
+
+// Categories is the set of Unicode category tables.
+var Categories = map[string]*RangeTable{
+ "C": C,
+ "Cc": Cc,
+ "Cf": Cf,
+ "Co": Co,
+ "Cs": Cs,
+ "L": L,
+ "Ll": Ll,
+ "Lm": Lm,
+ "Lo": Lo,
+ "Lt": Lt,
+ "Lu": Lu,
+ "M": M,
+ "Mc": Mc,
+ "Me": Me,
+ "Mn": Mn,
+ "N": N,
+ "Nd": Nd,
+ "Nl": Nl,
+ "No": No,
+ "P": P,
+ "Pc": Pc,
+ "Pd": Pd,
+ "Pe": Pe,
+ "Pf": Pf,
+ "Pi": Pi,
+ "Po": Po,
+ "Ps": Ps,
+ "S": S,
+ "Sc": Sc,
+ "Sk": Sk,
+ "Sm": Sm,
+ "So": So,
+ "Z": Z,
+ "Zl": Zl,
+ "Zp": Zp,
+ "Zs": Zs,
+}
+
+var _C = &RangeTable{
+ R16: []Range16{
+ {0x0000, 0x001f, 1},
+ {0x007f, 0x009f, 1},
+ {0x00ad, 0x0600, 1363},
+ {0x0601, 0x0605, 1},
+ {0x061c, 0x06dd, 193},
+ {0x070f, 0x0890, 385},
+ {0x0891, 0x08e2, 81},
+ {0x180e, 0x200b, 2045},
+ {0x200c, 0x200f, 1},
+ {0x202a, 0x202e, 1},
+ {0x2060, 0x2064, 1},
+ {0x2066, 0x206f, 1},
+ {0xd800, 0xf8ff, 1},
+ {0xfeff, 0xfff9, 250},
+ {0xfffa, 0xfffb, 1},
+ },
+ R32: []Range32{
+ {0x110bd, 0x110cd, 16},
+ {0x13430, 0x1343f, 1},
+ {0x1bca0, 0x1bca3, 1},
+ {0x1d173, 0x1d17a, 1},
+ {0xe0001, 0xe0020, 31},
+ {0xe0021, 0xe007f, 1},
+ {0xf0000, 0xffffd, 1},
+ {0x100000, 0x10fffd, 1},
+ },
+ LatinOffset: 2,
+}
+
+var _Cc = &RangeTable{
+ R16: []Range16{
+ {0x0000, 0x001f, 1},
+ {0x007f, 0x009f, 1},
+ },
+ LatinOffset: 2,
+}
+
+var _Cf = &RangeTable{
+ R16: []Range16{
+ {0x00ad, 0x0600, 1363},
+ {0x0601, 0x0605, 1},
+ {0x061c, 0x06dd, 193},
+ {0x070f, 0x0890, 385},
+ {0x0891, 0x08e2, 81},
+ {0x180e, 0x200b, 2045},
+ {0x200c, 0x200f, 1},
+ {0x202a, 0x202e, 1},
+ {0x2060, 0x2064, 1},
+ {0x2066, 0x206f, 1},
+ {0xfeff, 0xfff9, 250},
+ {0xfffa, 0xfffb, 1},
+ },
+ R32: []Range32{
+ {0x110bd, 0x110cd, 16},
+ {0x13430, 0x1343f, 1},
+ {0x1bca0, 0x1bca3, 1},
+ {0x1d173, 0x1d17a, 1},
+ {0xe0001, 0xe0020, 31},
+ {0xe0021, 0xe007f, 1},
+ },
+}
+
+var _Co = &RangeTable{
+ R16: []Range16{
+ {0xe000, 0xf8ff, 1},
+ },
+ R32: []Range32{
+ {0xf0000, 0xffffd, 1},
+ {0x100000, 0x10fffd, 1},
+ },
+}
+
+var _Cs = &RangeTable{
+ R16: []Range16{
+ {0xd800, 0xdfff, 1},
+ },
+}
+
+var _L = &RangeTable{
+ R16: []Range16{
+ {0x0041, 0x005a, 1},
+ {0x0061, 0x007a, 1},
+ {0x00aa, 0x00b5, 11},
+ {0x00ba, 0x00c0, 6},
+ {0x00c1, 0x00d6, 1},
+ {0x00d8, 0x00f6, 1},
+ {0x00f8, 0x02c1, 1},
+ {0x02c6, 0x02d1, 1},
+ {0x02e0, 0x02e4, 1},
+ {0x02ec, 0x02ee, 2},
+ {0x0370, 0x0374, 1},
+ {0x0376, 0x0377, 1},
+ {0x037a, 0x037d, 1},
+ {0x037f, 0x0386, 7},
+ {0x0388, 0x038a, 1},
+ {0x038c, 0x038e, 2},
+ {0x038f, 0x03a1, 1},
+ {0x03a3, 0x03f5, 1},
+ {0x03f7, 0x0481, 1},
+ {0x048a, 0x052f, 1},
+ {0x0531, 0x0556, 1},
+ {0x0559, 0x0560, 7},
+ {0x0561, 0x0588, 1},
+ {0x05d0, 0x05ea, 1},
+ {0x05ef, 0x05f2, 1},
+ {0x0620, 0x064a, 1},
+ {0x066e, 0x066f, 1},
+ {0x0671, 0x06d3, 1},
+ {0x06d5, 0x06e5, 16},
+ {0x06e6, 0x06ee, 8},
+ {0x06ef, 0x06fa, 11},
+ {0x06fb, 0x06fc, 1},
+ {0x06ff, 0x0710, 17},
+ {0x0712, 0x072f, 1},
+ {0x074d, 0x07a5, 1},
+ {0x07b1, 0x07ca, 25},
+ {0x07cb, 0x07ea, 1},
+ {0x07f4, 0x07f5, 1},
+ {0x07fa, 0x0800, 6},
+ {0x0801, 0x0815, 1},
+ {0x081a, 0x0824, 10},
+ {0x0828, 0x0840, 24},
+ {0x0841, 0x0858, 1},
+ {0x0860, 0x086a, 1},
+ {0x0870, 0x0887, 1},
+ {0x0889, 0x088e, 1},
+ {0x08a0, 0x08c9, 1},
+ {0x0904, 0x0939, 1},
+ {0x093d, 0x0950, 19},
+ {0x0958, 0x0961, 1},
+ {0x0971, 0x0980, 1},
+ {0x0985, 0x098c, 1},
+ {0x098f, 0x0990, 1},
+ {0x0993, 0x09a8, 1},
+ {0x09aa, 0x09b0, 1},
+ {0x09b2, 0x09b6, 4},
+ {0x09b7, 0x09b9, 1},
+ {0x09bd, 0x09ce, 17},
+ {0x09dc, 0x09dd, 1},
+ {0x09df, 0x09e1, 1},
+ {0x09f0, 0x09f1, 1},
+ {0x09fc, 0x0a05, 9},
+ {0x0a06, 0x0a0a, 1},
+ {0x0a0f, 0x0a10, 1},
+ {0x0a13, 0x0a28, 1},
+ {0x0a2a, 0x0a30, 1},
+ {0x0a32, 0x0a33, 1},
+ {0x0a35, 0x0a36, 1},
+ {0x0a38, 0x0a39, 1},
+ {0x0a59, 0x0a5c, 1},
+ {0x0a5e, 0x0a72, 20},
+ {0x0a73, 0x0a74, 1},
+ {0x0a85, 0x0a8d, 1},
+ {0x0a8f, 0x0a91, 1},
+ {0x0a93, 0x0aa8, 1},
+ {0x0aaa, 0x0ab0, 1},
+ {0x0ab2, 0x0ab3, 1},
+ {0x0ab5, 0x0ab9, 1},
+ {0x0abd, 0x0ad0, 19},
+ {0x0ae0, 0x0ae1, 1},
+ {0x0af9, 0x0b05, 12},
+ {0x0b06, 0x0b0c, 1},
+ {0x0b0f, 0x0b10, 1},
+ {0x0b13, 0x0b28, 1},
+ {0x0b2a, 0x0b30, 1},
+ {0x0b32, 0x0b33, 1},
+ {0x0b35, 0x0b39, 1},
+ {0x0b3d, 0x0b5c, 31},
+ {0x0b5d, 0x0b5f, 2},
+ {0x0b60, 0x0b61, 1},
+ {0x0b71, 0x0b83, 18},
+ {0x0b85, 0x0b8a, 1},
+ {0x0b8e, 0x0b90, 1},
+ {0x0b92, 0x0b95, 1},
+ {0x0b99, 0x0b9a, 1},
+ {0x0b9c, 0x0b9e, 2},
+ {0x0b9f, 0x0ba3, 4},
+ {0x0ba4, 0x0ba8, 4},
+ {0x0ba9, 0x0baa, 1},
+ {0x0bae, 0x0bb9, 1},
+ {0x0bd0, 0x0c05, 53},
+ {0x0c06, 0x0c0c, 1},
+ {0x0c0e, 0x0c10, 1},
+ {0x0c12, 0x0c28, 1},
+ {0x0c2a, 0x0c39, 1},
+ {0x0c3d, 0x0c58, 27},
+ {0x0c59, 0x0c5a, 1},
+ {0x0c5d, 0x0c60, 3},
+ {0x0c61, 0x0c80, 31},
+ {0x0c85, 0x0c8c, 1},
+ {0x0c8e, 0x0c90, 1},
+ {0x0c92, 0x0ca8, 1},
+ {0x0caa, 0x0cb3, 1},
+ {0x0cb5, 0x0cb9, 1},
+ {0x0cbd, 0x0cdd, 32},
+ {0x0cde, 0x0ce0, 2},
+ {0x0ce1, 0x0cf1, 16},
+ {0x0cf2, 0x0d04, 18},
+ {0x0d05, 0x0d0c, 1},
+ {0x0d0e, 0x0d10, 1},
+ {0x0d12, 0x0d3a, 1},
+ {0x0d3d, 0x0d4e, 17},
+ {0x0d54, 0x0d56, 1},
+ {0x0d5f, 0x0d61, 1},
+ {0x0d7a, 0x0d7f, 1},
+ {0x0d85, 0x0d96, 1},
+ {0x0d9a, 0x0db1, 1},
+ {0x0db3, 0x0dbb, 1},
+ {0x0dbd, 0x0dc0, 3},
+ {0x0dc1, 0x0dc6, 1},
+ {0x0e01, 0x0e30, 1},
+ {0x0e32, 0x0e33, 1},
+ {0x0e40, 0x0e46, 1},
+ {0x0e81, 0x0e82, 1},
+ {0x0e84, 0x0e86, 2},
+ {0x0e87, 0x0e8a, 1},
+ {0x0e8c, 0x0ea3, 1},
+ {0x0ea5, 0x0ea7, 2},
+ {0x0ea8, 0x0eb0, 1},
+ {0x0eb2, 0x0eb3, 1},
+ {0x0ebd, 0x0ec0, 3},
+ {0x0ec1, 0x0ec4, 1},
+ {0x0ec6, 0x0edc, 22},
+ {0x0edd, 0x0edf, 1},
+ {0x0f00, 0x0f40, 64},
+ {0x0f41, 0x0f47, 1},
+ {0x0f49, 0x0f6c, 1},
+ {0x0f88, 0x0f8c, 1},
+ {0x1000, 0x102a, 1},
+ {0x103f, 0x1050, 17},
+ {0x1051, 0x1055, 1},
+ {0x105a, 0x105d, 1},
+ {0x1061, 0x1065, 4},
+ {0x1066, 0x106e, 8},
+ {0x106f, 0x1070, 1},
+ {0x1075, 0x1081, 1},
+ {0x108e, 0x10a0, 18},
+ {0x10a1, 0x10c5, 1},
+ {0x10c7, 0x10cd, 6},
+ {0x10d0, 0x10fa, 1},
+ {0x10fc, 0x1248, 1},
+ {0x124a, 0x124d, 1},
+ {0x1250, 0x1256, 1},
+ {0x1258, 0x125a, 2},
+ {0x125b, 0x125d, 1},
+ {0x1260, 0x1288, 1},
+ {0x128a, 0x128d, 1},
+ {0x1290, 0x12b0, 1},
+ {0x12b2, 0x12b5, 1},
+ {0x12b8, 0x12be, 1},
+ {0x12c0, 0x12c2, 2},
+ {0x12c3, 0x12c5, 1},
+ {0x12c8, 0x12d6, 1},
+ {0x12d8, 0x1310, 1},
+ {0x1312, 0x1315, 1},
+ {0x1318, 0x135a, 1},
+ {0x1380, 0x138f, 1},
+ {0x13a0, 0x13f5, 1},
+ {0x13f8, 0x13fd, 1},
+ {0x1401, 0x166c, 1},
+ {0x166f, 0x167f, 1},
+ {0x1681, 0x169a, 1},
+ {0x16a0, 0x16ea, 1},
+ {0x16f1, 0x16f8, 1},
+ {0x1700, 0x1711, 1},
+ {0x171f, 0x1731, 1},
+ {0x1740, 0x1751, 1},
+ {0x1760, 0x176c, 1},
+ {0x176e, 0x1770, 1},
+ {0x1780, 0x17b3, 1},
+ {0x17d7, 0x17dc, 5},
+ {0x1820, 0x1878, 1},
+ {0x1880, 0x1884, 1},
+ {0x1887, 0x18a8, 1},
+ {0x18aa, 0x18b0, 6},
+ {0x18b1, 0x18f5, 1},
+ {0x1900, 0x191e, 1},
+ {0x1950, 0x196d, 1},
+ {0x1970, 0x1974, 1},
+ {0x1980, 0x19ab, 1},
+ {0x19b0, 0x19c9, 1},
+ {0x1a00, 0x1a16, 1},
+ {0x1a20, 0x1a54, 1},
+ {0x1aa7, 0x1b05, 94},
+ {0x1b06, 0x1b33, 1},
+ {0x1b45, 0x1b4c, 1},
+ {0x1b83, 0x1ba0, 1},
+ {0x1bae, 0x1baf, 1},
+ {0x1bba, 0x1be5, 1},
+ {0x1c00, 0x1c23, 1},
+ {0x1c4d, 0x1c4f, 1},
+ {0x1c5a, 0x1c7d, 1},
+ {0x1c80, 0x1c88, 1},
+ {0x1c90, 0x1cba, 1},
+ {0x1cbd, 0x1cbf, 1},
+ {0x1ce9, 0x1cec, 1},
+ {0x1cee, 0x1cf3, 1},
+ {0x1cf5, 0x1cf6, 1},
+ {0x1cfa, 0x1d00, 6},
+ {0x1d01, 0x1dbf, 1},
+ {0x1e00, 0x1f15, 1},
+ {0x1f18, 0x1f1d, 1},
+ {0x1f20, 0x1f45, 1},
+ {0x1f48, 0x1f4d, 1},
+ {0x1f50, 0x1f57, 1},
+ {0x1f59, 0x1f5f, 2},
+ {0x1f60, 0x1f7d, 1},
+ {0x1f80, 0x1fb4, 1},
+ {0x1fb6, 0x1fbc, 1},
+ {0x1fbe, 0x1fc2, 4},
+ {0x1fc3, 0x1fc4, 1},
+ {0x1fc6, 0x1fcc, 1},
+ {0x1fd0, 0x1fd3, 1},
+ {0x1fd6, 0x1fdb, 1},
+ {0x1fe0, 0x1fec, 1},
+ {0x1ff2, 0x1ff4, 1},
+ {0x1ff6, 0x1ffc, 1},
+ {0x2071, 0x207f, 14},
+ {0x2090, 0x209c, 1},
+ {0x2102, 0x2107, 5},
+ {0x210a, 0x2113, 1},
+ {0x2115, 0x2119, 4},
+ {0x211a, 0x211d, 1},
+ {0x2124, 0x212a, 2},
+ {0x212b, 0x212d, 1},
+ {0x212f, 0x2139, 1},
+ {0x213c, 0x213f, 1},
+ {0x2145, 0x2149, 1},
+ {0x214e, 0x2183, 53},
+ {0x2184, 0x2c00, 2684},
+ {0x2c01, 0x2ce4, 1},
+ {0x2ceb, 0x2cee, 1},
+ {0x2cf2, 0x2cf3, 1},
+ {0x2d00, 0x2d25, 1},
+ {0x2d27, 0x2d2d, 6},
+ {0x2d30, 0x2d67, 1},
+ {0x2d6f, 0x2d80, 17},
+ {0x2d81, 0x2d96, 1},
+ {0x2da0, 0x2da6, 1},
+ {0x2da8, 0x2dae, 1},
+ {0x2db0, 0x2db6, 1},
+ {0x2db8, 0x2dbe, 1},
+ {0x2dc0, 0x2dc6, 1},
+ {0x2dc8, 0x2dce, 1},
+ {0x2dd0, 0x2dd6, 1},
+ {0x2dd8, 0x2dde, 1},
+ {0x2e2f, 0x3005, 470},
+ {0x3006, 0x3031, 43},
+ {0x3032, 0x3035, 1},
+ {0x303b, 0x303c, 1},
+ {0x3041, 0x3096, 1},
+ {0x309d, 0x309f, 1},
+ {0x30a1, 0x30fa, 1},
+ {0x30fc, 0x30ff, 1},
+ {0x3105, 0x312f, 1},
+ {0x3131, 0x318e, 1},
+ {0x31a0, 0x31bf, 1},
+ {0x31f0, 0x31ff, 1},
+ {0x3400, 0x4dbf, 1},
+ {0x4e00, 0xa48c, 1},
+ {0xa4d0, 0xa4fd, 1},
+ {0xa500, 0xa60c, 1},
+ {0xa610, 0xa61f, 1},
+ {0xa62a, 0xa62b, 1},
+ {0xa640, 0xa66e, 1},
+ {0xa67f, 0xa69d, 1},
+ {0xa6a0, 0xa6e5, 1},
+ {0xa717, 0xa71f, 1},
+ {0xa722, 0xa788, 1},
+ {0xa78b, 0xa7ca, 1},
+ {0xa7d0, 0xa7d1, 1},
+ {0xa7d3, 0xa7d5, 2},
+ {0xa7d6, 0xa7d9, 1},
+ {0xa7f2, 0xa801, 1},
+ {0xa803, 0xa805, 1},
+ {0xa807, 0xa80a, 1},
+ {0xa80c, 0xa822, 1},
+ {0xa840, 0xa873, 1},
+ {0xa882, 0xa8b3, 1},
+ {0xa8f2, 0xa8f7, 1},
+ {0xa8fb, 0xa8fd, 2},
+ {0xa8fe, 0xa90a, 12},
+ {0xa90b, 0xa925, 1},
+ {0xa930, 0xa946, 1},
+ {0xa960, 0xa97c, 1},
+ {0xa984, 0xa9b2, 1},
+ {0xa9cf, 0xa9e0, 17},
+ {0xa9e1, 0xa9e4, 1},
+ {0xa9e6, 0xa9ef, 1},
+ {0xa9fa, 0xa9fe, 1},
+ {0xaa00, 0xaa28, 1},
+ {0xaa40, 0xaa42, 1},
+ {0xaa44, 0xaa4b, 1},
+ {0xaa60, 0xaa76, 1},
+ {0xaa7a, 0xaa7e, 4},
+ {0xaa7f, 0xaaaf, 1},
+ {0xaab1, 0xaab5, 4},
+ {0xaab6, 0xaab9, 3},
+ {0xaaba, 0xaabd, 1},
+ {0xaac0, 0xaac2, 2},
+ {0xaadb, 0xaadd, 1},
+ {0xaae0, 0xaaea, 1},
+ {0xaaf2, 0xaaf4, 1},
+ {0xab01, 0xab06, 1},
+ {0xab09, 0xab0e, 1},
+ {0xab11, 0xab16, 1},
+ {0xab20, 0xab26, 1},
+ {0xab28, 0xab2e, 1},
+ {0xab30, 0xab5a, 1},
+ {0xab5c, 0xab69, 1},
+ {0xab70, 0xabe2, 1},
+ {0xac00, 0xd7a3, 1},
+ {0xd7b0, 0xd7c6, 1},
+ {0xd7cb, 0xd7fb, 1},
+ {0xf900, 0xfa6d, 1},
+ {0xfa70, 0xfad9, 1},
+ {0xfb00, 0xfb06, 1},
+ {0xfb13, 0xfb17, 1},
+ {0xfb1d, 0xfb1f, 2},
+ {0xfb20, 0xfb28, 1},
+ {0xfb2a, 0xfb36, 1},
+ {0xfb38, 0xfb3c, 1},
+ {0xfb3e, 0xfb40, 2},
+ {0xfb41, 0xfb43, 2},
+ {0xfb44, 0xfb46, 2},
+ {0xfb47, 0xfbb1, 1},
+ {0xfbd3, 0xfd3d, 1},
+ {0xfd50, 0xfd8f, 1},
+ {0xfd92, 0xfdc7, 1},
+ {0xfdf0, 0xfdfb, 1},
+ {0xfe70, 0xfe74, 1},
+ {0xfe76, 0xfefc, 1},
+ {0xff21, 0xff3a, 1},
+ {0xff41, 0xff5a, 1},
+ {0xff66, 0xffbe, 1},
+ {0xffc2, 0xffc7, 1},
+ {0xffca, 0xffcf, 1},
+ {0xffd2, 0xffd7, 1},
+ {0xffda, 0xffdc, 1},
+ },
+ R32: []Range32{
+ {0x10000, 0x1000b, 1},
+ {0x1000d, 0x10026, 1},
+ {0x10028, 0x1003a, 1},
+ {0x1003c, 0x1003d, 1},
+ {0x1003f, 0x1004d, 1},
+ {0x10050, 0x1005d, 1},
+ {0x10080, 0x100fa, 1},
+ {0x10280, 0x1029c, 1},
+ {0x102a0, 0x102d0, 1},
+ {0x10300, 0x1031f, 1},
+ {0x1032d, 0x10340, 1},
+ {0x10342, 0x10349, 1},
+ {0x10350, 0x10375, 1},
+ {0x10380, 0x1039d, 1},
+ {0x103a0, 0x103c3, 1},
+ {0x103c8, 0x103cf, 1},
+ {0x10400, 0x1049d, 1},
+ {0x104b0, 0x104d3, 1},
+ {0x104d8, 0x104fb, 1},
+ {0x10500, 0x10527, 1},
+ {0x10530, 0x10563, 1},
+ {0x10570, 0x1057a, 1},
+ {0x1057c, 0x1058a, 1},
+ {0x1058c, 0x10592, 1},
+ {0x10594, 0x10595, 1},
+ {0x10597, 0x105a1, 1},
+ {0x105a3, 0x105b1, 1},
+ {0x105b3, 0x105b9, 1},
+ {0x105bb, 0x105bc, 1},
+ {0x10600, 0x10736, 1},
+ {0x10740, 0x10755, 1},
+ {0x10760, 0x10767, 1},
+ {0x10780, 0x10785, 1},
+ {0x10787, 0x107b0, 1},
+ {0x107b2, 0x107ba, 1},
+ {0x10800, 0x10805, 1},
+ {0x10808, 0x1080a, 2},
+ {0x1080b, 0x10835, 1},
+ {0x10837, 0x10838, 1},
+ {0x1083c, 0x1083f, 3},
+ {0x10840, 0x10855, 1},
+ {0x10860, 0x10876, 1},
+ {0x10880, 0x1089e, 1},
+ {0x108e0, 0x108f2, 1},
+ {0x108f4, 0x108f5, 1},
+ {0x10900, 0x10915, 1},
+ {0x10920, 0x10939, 1},
+ {0x10980, 0x109b7, 1},
+ {0x109be, 0x109bf, 1},
+ {0x10a00, 0x10a10, 16},
+ {0x10a11, 0x10a13, 1},
+ {0x10a15, 0x10a17, 1},
+ {0x10a19, 0x10a35, 1},
+ {0x10a60, 0x10a7c, 1},
+ {0x10a80, 0x10a9c, 1},
+ {0x10ac0, 0x10ac7, 1},
+ {0x10ac9, 0x10ae4, 1},
+ {0x10b00, 0x10b35, 1},
+ {0x10b40, 0x10b55, 1},
+ {0x10b60, 0x10b72, 1},
+ {0x10b80, 0x10b91, 1},
+ {0x10c00, 0x10c48, 1},
+ {0x10c80, 0x10cb2, 1},
+ {0x10cc0, 0x10cf2, 1},
+ {0x10d00, 0x10d23, 1},
+ {0x10e80, 0x10ea9, 1},
+ {0x10eb0, 0x10eb1, 1},
+ {0x10f00, 0x10f1c, 1},
+ {0x10f27, 0x10f30, 9},
+ {0x10f31, 0x10f45, 1},
+ {0x10f70, 0x10f81, 1},
+ {0x10fb0, 0x10fc4, 1},
+ {0x10fe0, 0x10ff6, 1},
+ {0x11003, 0x11037, 1},
+ {0x11071, 0x11072, 1},
+ {0x11075, 0x11083, 14},
+ {0x11084, 0x110af, 1},
+ {0x110d0, 0x110e8, 1},
+ {0x11103, 0x11126, 1},
+ {0x11144, 0x11147, 3},
+ {0x11150, 0x11172, 1},
+ {0x11176, 0x11183, 13},
+ {0x11184, 0x111b2, 1},
+ {0x111c1, 0x111c4, 1},
+ {0x111da, 0x111dc, 2},
+ {0x11200, 0x11211, 1},
+ {0x11213, 0x1122b, 1},
+ {0x1123f, 0x11240, 1},
+ {0x11280, 0x11286, 1},
+ {0x11288, 0x1128a, 2},
+ {0x1128b, 0x1128d, 1},
+ {0x1128f, 0x1129d, 1},
+ {0x1129f, 0x112a8, 1},
+ {0x112b0, 0x112de, 1},
+ {0x11305, 0x1130c, 1},
+ {0x1130f, 0x11310, 1},
+ {0x11313, 0x11328, 1},
+ {0x1132a, 0x11330, 1},
+ {0x11332, 0x11333, 1},
+ {0x11335, 0x11339, 1},
+ {0x1133d, 0x11350, 19},
+ {0x1135d, 0x11361, 1},
+ {0x11400, 0x11434, 1},
+ {0x11447, 0x1144a, 1},
+ {0x1145f, 0x11461, 1},
+ {0x11480, 0x114af, 1},
+ {0x114c4, 0x114c5, 1},
+ {0x114c7, 0x11580, 185},
+ {0x11581, 0x115ae, 1},
+ {0x115d8, 0x115db, 1},
+ {0x11600, 0x1162f, 1},
+ {0x11644, 0x11680, 60},
+ {0x11681, 0x116aa, 1},
+ {0x116b8, 0x11700, 72},
+ {0x11701, 0x1171a, 1},
+ {0x11740, 0x11746, 1},
+ {0x11800, 0x1182b, 1},
+ {0x118a0, 0x118df, 1},
+ {0x118ff, 0x11906, 1},
+ {0x11909, 0x1190c, 3},
+ {0x1190d, 0x11913, 1},
+ {0x11915, 0x11916, 1},
+ {0x11918, 0x1192f, 1},
+ {0x1193f, 0x11941, 2},
+ {0x119a0, 0x119a7, 1},
+ {0x119aa, 0x119d0, 1},
+ {0x119e1, 0x119e3, 2},
+ {0x11a00, 0x11a0b, 11},
+ {0x11a0c, 0x11a32, 1},
+ {0x11a3a, 0x11a50, 22},
+ {0x11a5c, 0x11a89, 1},
+ {0x11a9d, 0x11ab0, 19},
+ {0x11ab1, 0x11af8, 1},
+ {0x11c00, 0x11c08, 1},
+ {0x11c0a, 0x11c2e, 1},
+ {0x11c40, 0x11c72, 50},
+ {0x11c73, 0x11c8f, 1},
+ {0x11d00, 0x11d06, 1},
+ {0x11d08, 0x11d09, 1},
+ {0x11d0b, 0x11d30, 1},
+ {0x11d46, 0x11d60, 26},
+ {0x11d61, 0x11d65, 1},
+ {0x11d67, 0x11d68, 1},
+ {0x11d6a, 0x11d89, 1},
+ {0x11d98, 0x11ee0, 328},
+ {0x11ee1, 0x11ef2, 1},
+ {0x11f02, 0x11f04, 2},
+ {0x11f05, 0x11f10, 1},
+ {0x11f12, 0x11f33, 1},
+ {0x11fb0, 0x12000, 80},
+ {0x12001, 0x12399, 1},
+ {0x12480, 0x12543, 1},
+ {0x12f90, 0x12ff0, 1},
+ {0x13000, 0x1342f, 1},
+ {0x13441, 0x13446, 1},
+ {0x14400, 0x14646, 1},
+ {0x16800, 0x16a38, 1},
+ {0x16a40, 0x16a5e, 1},
+ {0x16a70, 0x16abe, 1},
+ {0x16ad0, 0x16aed, 1},
+ {0x16b00, 0x16b2f, 1},
+ {0x16b40, 0x16b43, 1},
+ {0x16b63, 0x16b77, 1},
+ {0x16b7d, 0x16b8f, 1},
+ {0x16e40, 0x16e7f, 1},
+ {0x16f00, 0x16f4a, 1},
+ {0x16f50, 0x16f93, 67},
+ {0x16f94, 0x16f9f, 1},
+ {0x16fe0, 0x16fe1, 1},
+ {0x16fe3, 0x17000, 29},
+ {0x17001, 0x187f7, 1},
+ {0x18800, 0x18cd5, 1},
+ {0x18d00, 0x18d08, 1},
+ {0x1aff0, 0x1aff3, 1},
+ {0x1aff5, 0x1affb, 1},
+ {0x1affd, 0x1affe, 1},
+ {0x1b000, 0x1b122, 1},
+ {0x1b132, 0x1b150, 30},
+ {0x1b151, 0x1b152, 1},
+ {0x1b155, 0x1b164, 15},
+ {0x1b165, 0x1b167, 1},
+ {0x1b170, 0x1b2fb, 1},
+ {0x1bc00, 0x1bc6a, 1},
+ {0x1bc70, 0x1bc7c, 1},
+ {0x1bc80, 0x1bc88, 1},
+ {0x1bc90, 0x1bc99, 1},
+ {0x1d400, 0x1d454, 1},
+ {0x1d456, 0x1d49c, 1},
+ {0x1d49e, 0x1d49f, 1},
+ {0x1d4a2, 0x1d4a5, 3},
+ {0x1d4a6, 0x1d4a9, 3},
+ {0x1d4aa, 0x1d4ac, 1},
+ {0x1d4ae, 0x1d4b9, 1},
+ {0x1d4bb, 0x1d4bd, 2},
+ {0x1d4be, 0x1d4c3, 1},
+ {0x1d4c5, 0x1d505, 1},
+ {0x1d507, 0x1d50a, 1},
+ {0x1d50d, 0x1d514, 1},
+ {0x1d516, 0x1d51c, 1},
+ {0x1d51e, 0x1d539, 1},
+ {0x1d53b, 0x1d53e, 1},
+ {0x1d540, 0x1d544, 1},
+ {0x1d546, 0x1d54a, 4},
+ {0x1d54b, 0x1d550, 1},
+ {0x1d552, 0x1d6a5, 1},
+ {0x1d6a8, 0x1d6c0, 1},
+ {0x1d6c2, 0x1d6da, 1},
+ {0x1d6dc, 0x1d6fa, 1},
+ {0x1d6fc, 0x1d714, 1},
+ {0x1d716, 0x1d734, 1},
+ {0x1d736, 0x1d74e, 1},
+ {0x1d750, 0x1d76e, 1},
+ {0x1d770, 0x1d788, 1},
+ {0x1d78a, 0x1d7a8, 1},
+ {0x1d7aa, 0x1d7c2, 1},
+ {0x1d7c4, 0x1d7cb, 1},
+ {0x1df00, 0x1df1e, 1},
+ {0x1df25, 0x1df2a, 1},
+ {0x1e030, 0x1e06d, 1},
+ {0x1e100, 0x1e12c, 1},
+ {0x1e137, 0x1e13d, 1},
+ {0x1e14e, 0x1e290, 322},
+ {0x1e291, 0x1e2ad, 1},
+ {0x1e2c0, 0x1e2eb, 1},
+ {0x1e4d0, 0x1e4eb, 1},
+ {0x1e7e0, 0x1e7e6, 1},
+ {0x1e7e8, 0x1e7eb, 1},
+ {0x1e7ed, 0x1e7ee, 1},
+ {0x1e7f0, 0x1e7fe, 1},
+ {0x1e800, 0x1e8c4, 1},
+ {0x1e900, 0x1e943, 1},
+ {0x1e94b, 0x1ee00, 1205},
+ {0x1ee01, 0x1ee03, 1},
+ {0x1ee05, 0x1ee1f, 1},
+ {0x1ee21, 0x1ee22, 1},
+ {0x1ee24, 0x1ee27, 3},
+ {0x1ee29, 0x1ee32, 1},
+ {0x1ee34, 0x1ee37, 1},
+ {0x1ee39, 0x1ee3b, 2},
+ {0x1ee42, 0x1ee47, 5},
+ {0x1ee49, 0x1ee4d, 2},
+ {0x1ee4e, 0x1ee4f, 1},
+ {0x1ee51, 0x1ee52, 1},
+ {0x1ee54, 0x1ee57, 3},
+ {0x1ee59, 0x1ee61, 2},
+ {0x1ee62, 0x1ee64, 2},
+ {0x1ee67, 0x1ee6a, 1},
+ {0x1ee6c, 0x1ee72, 1},
+ {0x1ee74, 0x1ee77, 1},
+ {0x1ee79, 0x1ee7c, 1},
+ {0x1ee7e, 0x1ee80, 2},
+ {0x1ee81, 0x1ee89, 1},
+ {0x1ee8b, 0x1ee9b, 1},
+ {0x1eea1, 0x1eea3, 1},
+ {0x1eea5, 0x1eea9, 1},
+ {0x1eeab, 0x1eebb, 1},
+ {0x20000, 0x2a6df, 1},
+ {0x2a700, 0x2b739, 1},
+ {0x2b740, 0x2b81d, 1},
+ {0x2b820, 0x2cea1, 1},
+ {0x2ceb0, 0x2ebe0, 1},
+ {0x2f800, 0x2fa1d, 1},
+ {0x30000, 0x3134a, 1},
+ {0x31350, 0x323af, 1},
+ },
+ LatinOffset: 6,
+}
+
+var _Ll = &RangeTable{
+ R16: []Range16{
+ {0x0061, 0x007a, 1},
+ {0x00b5, 0x00df, 42},
+ {0x00e0, 0x00f6, 1},
+ {0x00f8, 0x00ff, 1},
+ {0x0101, 0x0137, 2},
+ {0x0138, 0x0148, 2},
+ {0x0149, 0x0177, 2},
+ {0x017a, 0x017e, 2},
+ {0x017f, 0x0180, 1},
+ {0x0183, 0x0185, 2},
+ {0x0188, 0x018c, 4},
+ {0x018d, 0x0192, 5},
+ {0x0195, 0x0199, 4},
+ {0x019a, 0x019b, 1},
+ {0x019e, 0x01a1, 3},
+ {0x01a3, 0x01a5, 2},
+ {0x01a8, 0x01aa, 2},
+ {0x01ab, 0x01ad, 2},
+ {0x01b0, 0x01b4, 4},
+ {0x01b6, 0x01b9, 3},
+ {0x01ba, 0x01bd, 3},
+ {0x01be, 0x01bf, 1},
+ {0x01c6, 0x01cc, 3},
+ {0x01ce, 0x01dc, 2},
+ {0x01dd, 0x01ef, 2},
+ {0x01f0, 0x01f3, 3},
+ {0x01f5, 0x01f9, 4},
+ {0x01fb, 0x0233, 2},
+ {0x0234, 0x0239, 1},
+ {0x023c, 0x023f, 3},
+ {0x0240, 0x0242, 2},
+ {0x0247, 0x024f, 2},
+ {0x0250, 0x0293, 1},
+ {0x0295, 0x02af, 1},
+ {0x0371, 0x0373, 2},
+ {0x0377, 0x037b, 4},
+ {0x037c, 0x037d, 1},
+ {0x0390, 0x03ac, 28},
+ {0x03ad, 0x03ce, 1},
+ {0x03d0, 0x03d1, 1},
+ {0x03d5, 0x03d7, 1},
+ {0x03d9, 0x03ef, 2},
+ {0x03f0, 0x03f3, 1},
+ {0x03f5, 0x03fb, 3},
+ {0x03fc, 0x0430, 52},
+ {0x0431, 0x045f, 1},
+ {0x0461, 0x0481, 2},
+ {0x048b, 0x04bf, 2},
+ {0x04c2, 0x04ce, 2},
+ {0x04cf, 0x052f, 2},
+ {0x0560, 0x0588, 1},
+ {0x10d0, 0x10fa, 1},
+ {0x10fd, 0x10ff, 1},
+ {0x13f8, 0x13fd, 1},
+ {0x1c80, 0x1c88, 1},
+ {0x1d00, 0x1d2b, 1},
+ {0x1d6b, 0x1d77, 1},
+ {0x1d79, 0x1d9a, 1},
+ {0x1e01, 0x1e95, 2},
+ {0x1e96, 0x1e9d, 1},
+ {0x1e9f, 0x1eff, 2},
+ {0x1f00, 0x1f07, 1},
+ {0x1f10, 0x1f15, 1},
+ {0x1f20, 0x1f27, 1},
+ {0x1f30, 0x1f37, 1},
+ {0x1f40, 0x1f45, 1},
+ {0x1f50, 0x1f57, 1},
+ {0x1f60, 0x1f67, 1},
+ {0x1f70, 0x1f7d, 1},
+ {0x1f80, 0x1f87, 1},
+ {0x1f90, 0x1f97, 1},
+ {0x1fa0, 0x1fa7, 1},
+ {0x1fb0, 0x1fb4, 1},
+ {0x1fb6, 0x1fb7, 1},
+ {0x1fbe, 0x1fc2, 4},
+ {0x1fc3, 0x1fc4, 1},
+ {0x1fc6, 0x1fc7, 1},
+ {0x1fd0, 0x1fd3, 1},
+ {0x1fd6, 0x1fd7, 1},
+ {0x1fe0, 0x1fe7, 1},
+ {0x1ff2, 0x1ff4, 1},
+ {0x1ff6, 0x1ff7, 1},
+ {0x210a, 0x210e, 4},
+ {0x210f, 0x2113, 4},
+ {0x212f, 0x2139, 5},
+ {0x213c, 0x213d, 1},
+ {0x2146, 0x2149, 1},
+ {0x214e, 0x2184, 54},
+ {0x2c30, 0x2c5f, 1},
+ {0x2c61, 0x2c65, 4},
+ {0x2c66, 0x2c6c, 2},
+ {0x2c71, 0x2c73, 2},
+ {0x2c74, 0x2c76, 2},
+ {0x2c77, 0x2c7b, 1},
+ {0x2c81, 0x2ce3, 2},
+ {0x2ce4, 0x2cec, 8},
+ {0x2cee, 0x2cf3, 5},
+ {0x2d00, 0x2d25, 1},
+ {0x2d27, 0x2d2d, 6},
+ {0xa641, 0xa66d, 2},
+ {0xa681, 0xa69b, 2},
+ {0xa723, 0xa72f, 2},
+ {0xa730, 0xa731, 1},
+ {0xa733, 0xa771, 2},
+ {0xa772, 0xa778, 1},
+ {0xa77a, 0xa77c, 2},
+ {0xa77f, 0xa787, 2},
+ {0xa78c, 0xa78e, 2},
+ {0xa791, 0xa793, 2},
+ {0xa794, 0xa795, 1},
+ {0xa797, 0xa7a9, 2},
+ {0xa7af, 0xa7b5, 6},
+ {0xa7b7, 0xa7c3, 2},
+ {0xa7c8, 0xa7ca, 2},
+ {0xa7d1, 0xa7d9, 2},
+ {0xa7f6, 0xa7fa, 4},
+ {0xab30, 0xab5a, 1},
+ {0xab60, 0xab68, 1},
+ {0xab70, 0xabbf, 1},
+ {0xfb00, 0xfb06, 1},
+ {0xfb13, 0xfb17, 1},
+ {0xff41, 0xff5a, 1},
+ },
+ R32: []Range32{
+ {0x10428, 0x1044f, 1},
+ {0x104d8, 0x104fb, 1},
+ {0x10597, 0x105a1, 1},
+ {0x105a3, 0x105b1, 1},
+ {0x105b3, 0x105b9, 1},
+ {0x105bb, 0x105bc, 1},
+ {0x10cc0, 0x10cf2, 1},
+ {0x118c0, 0x118df, 1},
+ {0x16e60, 0x16e7f, 1},
+ {0x1d41a, 0x1d433, 1},
+ {0x1d44e, 0x1d454, 1},
+ {0x1d456, 0x1d467, 1},
+ {0x1d482, 0x1d49b, 1},
+ {0x1d4b6, 0x1d4b9, 1},
+ {0x1d4bb, 0x1d4bd, 2},
+ {0x1d4be, 0x1d4c3, 1},
+ {0x1d4c5, 0x1d4cf, 1},
+ {0x1d4ea, 0x1d503, 1},
+ {0x1d51e, 0x1d537, 1},
+ {0x1d552, 0x1d56b, 1},
+ {0x1d586, 0x1d59f, 1},
+ {0x1d5ba, 0x1d5d3, 1},
+ {0x1d5ee, 0x1d607, 1},
+ {0x1d622, 0x1d63b, 1},
+ {0x1d656, 0x1d66f, 1},
+ {0x1d68a, 0x1d6a5, 1},
+ {0x1d6c2, 0x1d6da, 1},
+ {0x1d6dc, 0x1d6e1, 1},
+ {0x1d6fc, 0x1d714, 1},
+ {0x1d716, 0x1d71b, 1},
+ {0x1d736, 0x1d74e, 1},
+ {0x1d750, 0x1d755, 1},
+ {0x1d770, 0x1d788, 1},
+ {0x1d78a, 0x1d78f, 1},
+ {0x1d7aa, 0x1d7c2, 1},
+ {0x1d7c4, 0x1d7c9, 1},
+ {0x1d7cb, 0x1df00, 1845},
+ {0x1df01, 0x1df09, 1},
+ {0x1df0b, 0x1df1e, 1},
+ {0x1df25, 0x1df2a, 1},
+ {0x1e922, 0x1e943, 1},
+ },
+ LatinOffset: 4,
+}
+
+var _Lm = &RangeTable{
+ R16: []Range16{
+ {0x02b0, 0x02c1, 1},
+ {0x02c6, 0x02d1, 1},
+ {0x02e0, 0x02e4, 1},
+ {0x02ec, 0x02ee, 2},
+ {0x0374, 0x037a, 6},
+ {0x0559, 0x0640, 231},
+ {0x06e5, 0x06e6, 1},
+ {0x07f4, 0x07f5, 1},
+ {0x07fa, 0x081a, 32},
+ {0x0824, 0x0828, 4},
+ {0x08c9, 0x0971, 168},
+ {0x0e46, 0x0ec6, 128},
+ {0x10fc, 0x17d7, 1755},
+ {0x1843, 0x1aa7, 612},
+ {0x1c78, 0x1c7d, 1},
+ {0x1d2c, 0x1d6a, 1},
+ {0x1d78, 0x1d9b, 35},
+ {0x1d9c, 0x1dbf, 1},
+ {0x2071, 0x207f, 14},
+ {0x2090, 0x209c, 1},
+ {0x2c7c, 0x2c7d, 1},
+ {0x2d6f, 0x2e2f, 192},
+ {0x3005, 0x3031, 44},
+ {0x3032, 0x3035, 1},
+ {0x303b, 0x309d, 98},
+ {0x309e, 0x30fc, 94},
+ {0x30fd, 0x30fe, 1},
+ {0xa015, 0xa4f8, 1251},
+ {0xa4f9, 0xa4fd, 1},
+ {0xa60c, 0xa67f, 115},
+ {0xa69c, 0xa69d, 1},
+ {0xa717, 0xa71f, 1},
+ {0xa770, 0xa788, 24},
+ {0xa7f2, 0xa7f4, 1},
+ {0xa7f8, 0xa7f9, 1},
+ {0xa9cf, 0xa9e6, 23},
+ {0xaa70, 0xaadd, 109},
+ {0xaaf3, 0xaaf4, 1},
+ {0xab5c, 0xab5f, 1},
+ {0xab69, 0xff70, 21511},
+ {0xff9e, 0xff9f, 1},
+ },
+ R32: []Range32{
+ {0x10780, 0x10785, 1},
+ {0x10787, 0x107b0, 1},
+ {0x107b2, 0x107ba, 1},
+ {0x16b40, 0x16b43, 1},
+ {0x16f93, 0x16f9f, 1},
+ {0x16fe0, 0x16fe1, 1},
+ {0x16fe3, 0x1aff0, 16397},
+ {0x1aff1, 0x1aff3, 1},
+ {0x1aff5, 0x1affb, 1},
+ {0x1affd, 0x1affe, 1},
+ {0x1e030, 0x1e06d, 1},
+ {0x1e137, 0x1e13d, 1},
+ {0x1e4eb, 0x1e94b, 1120},
+ },
+}
+
+var _Lo = &RangeTable{
+ R16: []Range16{
+ {0x00aa, 0x00ba, 16},
+ {0x01bb, 0x01c0, 5},
+ {0x01c1, 0x01c3, 1},
+ {0x0294, 0x05d0, 828},
+ {0x05d1, 0x05ea, 1},
+ {0x05ef, 0x05f2, 1},
+ {0x0620, 0x063f, 1},
+ {0x0641, 0x064a, 1},
+ {0x066e, 0x066f, 1},
+ {0x0671, 0x06d3, 1},
+ {0x06d5, 0x06ee, 25},
+ {0x06ef, 0x06fa, 11},
+ {0x06fb, 0x06fc, 1},
+ {0x06ff, 0x0710, 17},
+ {0x0712, 0x072f, 1},
+ {0x074d, 0x07a5, 1},
+ {0x07b1, 0x07ca, 25},
+ {0x07cb, 0x07ea, 1},
+ {0x0800, 0x0815, 1},
+ {0x0840, 0x0858, 1},
+ {0x0860, 0x086a, 1},
+ {0x0870, 0x0887, 1},
+ {0x0889, 0x088e, 1},
+ {0x08a0, 0x08c8, 1},
+ {0x0904, 0x0939, 1},
+ {0x093d, 0x0950, 19},
+ {0x0958, 0x0961, 1},
+ {0x0972, 0x0980, 1},
+ {0x0985, 0x098c, 1},
+ {0x098f, 0x0990, 1},
+ {0x0993, 0x09a8, 1},
+ {0x09aa, 0x09b0, 1},
+ {0x09b2, 0x09b6, 4},
+ {0x09b7, 0x09b9, 1},
+ {0x09bd, 0x09ce, 17},
+ {0x09dc, 0x09dd, 1},
+ {0x09df, 0x09e1, 1},
+ {0x09f0, 0x09f1, 1},
+ {0x09fc, 0x0a05, 9},
+ {0x0a06, 0x0a0a, 1},
+ {0x0a0f, 0x0a10, 1},
+ {0x0a13, 0x0a28, 1},
+ {0x0a2a, 0x0a30, 1},
+ {0x0a32, 0x0a33, 1},
+ {0x0a35, 0x0a36, 1},
+ {0x0a38, 0x0a39, 1},
+ {0x0a59, 0x0a5c, 1},
+ {0x0a5e, 0x0a72, 20},
+ {0x0a73, 0x0a74, 1},
+ {0x0a85, 0x0a8d, 1},
+ {0x0a8f, 0x0a91, 1},
+ {0x0a93, 0x0aa8, 1},
+ {0x0aaa, 0x0ab0, 1},
+ {0x0ab2, 0x0ab3, 1},
+ {0x0ab5, 0x0ab9, 1},
+ {0x0abd, 0x0ad0, 19},
+ {0x0ae0, 0x0ae1, 1},
+ {0x0af9, 0x0b05, 12},
+ {0x0b06, 0x0b0c, 1},
+ {0x0b0f, 0x0b10, 1},
+ {0x0b13, 0x0b28, 1},
+ {0x0b2a, 0x0b30, 1},
+ {0x0b32, 0x0b33, 1},
+ {0x0b35, 0x0b39, 1},
+ {0x0b3d, 0x0b5c, 31},
+ {0x0b5d, 0x0b5f, 2},
+ {0x0b60, 0x0b61, 1},
+ {0x0b71, 0x0b83, 18},
+ {0x0b85, 0x0b8a, 1},
+ {0x0b8e, 0x0b90, 1},
+ {0x0b92, 0x0b95, 1},
+ {0x0b99, 0x0b9a, 1},
+ {0x0b9c, 0x0b9e, 2},
+ {0x0b9f, 0x0ba3, 4},
+ {0x0ba4, 0x0ba8, 4},
+ {0x0ba9, 0x0baa, 1},
+ {0x0bae, 0x0bb9, 1},
+ {0x0bd0, 0x0c05, 53},
+ {0x0c06, 0x0c0c, 1},
+ {0x0c0e, 0x0c10, 1},
+ {0x0c12, 0x0c28, 1},
+ {0x0c2a, 0x0c39, 1},
+ {0x0c3d, 0x0c58, 27},
+ {0x0c59, 0x0c5a, 1},
+ {0x0c5d, 0x0c60, 3},
+ {0x0c61, 0x0c80, 31},
+ {0x0c85, 0x0c8c, 1},
+ {0x0c8e, 0x0c90, 1},
+ {0x0c92, 0x0ca8, 1},
+ {0x0caa, 0x0cb3, 1},
+ {0x0cb5, 0x0cb9, 1},
+ {0x0cbd, 0x0cdd, 32},
+ {0x0cde, 0x0ce0, 2},
+ {0x0ce1, 0x0cf1, 16},
+ {0x0cf2, 0x0d04, 18},
+ {0x0d05, 0x0d0c, 1},
+ {0x0d0e, 0x0d10, 1},
+ {0x0d12, 0x0d3a, 1},
+ {0x0d3d, 0x0d4e, 17},
+ {0x0d54, 0x0d56, 1},
+ {0x0d5f, 0x0d61, 1},
+ {0x0d7a, 0x0d7f, 1},
+ {0x0d85, 0x0d96, 1},
+ {0x0d9a, 0x0db1, 1},
+ {0x0db3, 0x0dbb, 1},
+ {0x0dbd, 0x0dc0, 3},
+ {0x0dc1, 0x0dc6, 1},
+ {0x0e01, 0x0e30, 1},
+ {0x0e32, 0x0e33, 1},
+ {0x0e40, 0x0e45, 1},
+ {0x0e81, 0x0e82, 1},
+ {0x0e84, 0x0e86, 2},
+ {0x0e87, 0x0e8a, 1},
+ {0x0e8c, 0x0ea3, 1},
+ {0x0ea5, 0x0ea7, 2},
+ {0x0ea8, 0x0eb0, 1},
+ {0x0eb2, 0x0eb3, 1},
+ {0x0ebd, 0x0ec0, 3},
+ {0x0ec1, 0x0ec4, 1},
+ {0x0edc, 0x0edf, 1},
+ {0x0f00, 0x0f40, 64},
+ {0x0f41, 0x0f47, 1},
+ {0x0f49, 0x0f6c, 1},
+ {0x0f88, 0x0f8c, 1},
+ {0x1000, 0x102a, 1},
+ {0x103f, 0x1050, 17},
+ {0x1051, 0x1055, 1},
+ {0x105a, 0x105d, 1},
+ {0x1061, 0x1065, 4},
+ {0x1066, 0x106e, 8},
+ {0x106f, 0x1070, 1},
+ {0x1075, 0x1081, 1},
+ {0x108e, 0x1100, 114},
+ {0x1101, 0x1248, 1},
+ {0x124a, 0x124d, 1},
+ {0x1250, 0x1256, 1},
+ {0x1258, 0x125a, 2},
+ {0x125b, 0x125d, 1},
+ {0x1260, 0x1288, 1},
+ {0x128a, 0x128d, 1},
+ {0x1290, 0x12b0, 1},
+ {0x12b2, 0x12b5, 1},
+ {0x12b8, 0x12be, 1},
+ {0x12c0, 0x12c2, 2},
+ {0x12c3, 0x12c5, 1},
+ {0x12c8, 0x12d6, 1},
+ {0x12d8, 0x1310, 1},
+ {0x1312, 0x1315, 1},
+ {0x1318, 0x135a, 1},
+ {0x1380, 0x138f, 1},
+ {0x1401, 0x166c, 1},
+ {0x166f, 0x167f, 1},
+ {0x1681, 0x169a, 1},
+ {0x16a0, 0x16ea, 1},
+ {0x16f1, 0x16f8, 1},
+ {0x1700, 0x1711, 1},
+ {0x171f, 0x1731, 1},
+ {0x1740, 0x1751, 1},
+ {0x1760, 0x176c, 1},
+ {0x176e, 0x1770, 1},
+ {0x1780, 0x17b3, 1},
+ {0x17dc, 0x1820, 68},
+ {0x1821, 0x1842, 1},
+ {0x1844, 0x1878, 1},
+ {0x1880, 0x1884, 1},
+ {0x1887, 0x18a8, 1},
+ {0x18aa, 0x18b0, 6},
+ {0x18b1, 0x18f5, 1},
+ {0x1900, 0x191e, 1},
+ {0x1950, 0x196d, 1},
+ {0x1970, 0x1974, 1},
+ {0x1980, 0x19ab, 1},
+ {0x19b0, 0x19c9, 1},
+ {0x1a00, 0x1a16, 1},
+ {0x1a20, 0x1a54, 1},
+ {0x1b05, 0x1b33, 1},
+ {0x1b45, 0x1b4c, 1},
+ {0x1b83, 0x1ba0, 1},
+ {0x1bae, 0x1baf, 1},
+ {0x1bba, 0x1be5, 1},
+ {0x1c00, 0x1c23, 1},
+ {0x1c4d, 0x1c4f, 1},
+ {0x1c5a, 0x1c77, 1},
+ {0x1ce9, 0x1cec, 1},
+ {0x1cee, 0x1cf3, 1},
+ {0x1cf5, 0x1cf6, 1},
+ {0x1cfa, 0x2135, 1083},
+ {0x2136, 0x2138, 1},
+ {0x2d30, 0x2d67, 1},
+ {0x2d80, 0x2d96, 1},
+ {0x2da0, 0x2da6, 1},
+ {0x2da8, 0x2dae, 1},
+ {0x2db0, 0x2db6, 1},
+ {0x2db8, 0x2dbe, 1},
+ {0x2dc0, 0x2dc6, 1},
+ {0x2dc8, 0x2dce, 1},
+ {0x2dd0, 0x2dd6, 1},
+ {0x2dd8, 0x2dde, 1},
+ {0x3006, 0x303c, 54},
+ {0x3041, 0x3096, 1},
+ {0x309f, 0x30a1, 2},
+ {0x30a2, 0x30fa, 1},
+ {0x30ff, 0x3105, 6},
+ {0x3106, 0x312f, 1},
+ {0x3131, 0x318e, 1},
+ {0x31a0, 0x31bf, 1},
+ {0x31f0, 0x31ff, 1},
+ {0x3400, 0x4dbf, 1},
+ {0x4e00, 0xa014, 1},
+ {0xa016, 0xa48c, 1},
+ {0xa4d0, 0xa4f7, 1},
+ {0xa500, 0xa60b, 1},
+ {0xa610, 0xa61f, 1},
+ {0xa62a, 0xa62b, 1},
+ {0xa66e, 0xa6a0, 50},
+ {0xa6a1, 0xa6e5, 1},
+ {0xa78f, 0xa7f7, 104},
+ {0xa7fb, 0xa801, 1},
+ {0xa803, 0xa805, 1},
+ {0xa807, 0xa80a, 1},
+ {0xa80c, 0xa822, 1},
+ {0xa840, 0xa873, 1},
+ {0xa882, 0xa8b3, 1},
+ {0xa8f2, 0xa8f7, 1},
+ {0xa8fb, 0xa8fd, 2},
+ {0xa8fe, 0xa90a, 12},
+ {0xa90b, 0xa925, 1},
+ {0xa930, 0xa946, 1},
+ {0xa960, 0xa97c, 1},
+ {0xa984, 0xa9b2, 1},
+ {0xa9e0, 0xa9e4, 1},
+ {0xa9e7, 0xa9ef, 1},
+ {0xa9fa, 0xa9fe, 1},
+ {0xaa00, 0xaa28, 1},
+ {0xaa40, 0xaa42, 1},
+ {0xaa44, 0xaa4b, 1},
+ {0xaa60, 0xaa6f, 1},
+ {0xaa71, 0xaa76, 1},
+ {0xaa7a, 0xaa7e, 4},
+ {0xaa7f, 0xaaaf, 1},
+ {0xaab1, 0xaab5, 4},
+ {0xaab6, 0xaab9, 3},
+ {0xaaba, 0xaabd, 1},
+ {0xaac0, 0xaac2, 2},
+ {0xaadb, 0xaadc, 1},
+ {0xaae0, 0xaaea, 1},
+ {0xaaf2, 0xab01, 15},
+ {0xab02, 0xab06, 1},
+ {0xab09, 0xab0e, 1},
+ {0xab11, 0xab16, 1},
+ {0xab20, 0xab26, 1},
+ {0xab28, 0xab2e, 1},
+ {0xabc0, 0xabe2, 1},
+ {0xac00, 0xd7a3, 1},
+ {0xd7b0, 0xd7c6, 1},
+ {0xd7cb, 0xd7fb, 1},
+ {0xf900, 0xfa6d, 1},
+ {0xfa70, 0xfad9, 1},
+ {0xfb1d, 0xfb1f, 2},
+ {0xfb20, 0xfb28, 1},
+ {0xfb2a, 0xfb36, 1},
+ {0xfb38, 0xfb3c, 1},
+ {0xfb3e, 0xfb40, 2},
+ {0xfb41, 0xfb43, 2},
+ {0xfb44, 0xfb46, 2},
+ {0xfb47, 0xfbb1, 1},
+ {0xfbd3, 0xfd3d, 1},
+ {0xfd50, 0xfd8f, 1},
+ {0xfd92, 0xfdc7, 1},
+ {0xfdf0, 0xfdfb, 1},
+ {0xfe70, 0xfe74, 1},
+ {0xfe76, 0xfefc, 1},
+ {0xff66, 0xff6f, 1},
+ {0xff71, 0xff9d, 1},
+ {0xffa0, 0xffbe, 1},
+ {0xffc2, 0xffc7, 1},
+ {0xffca, 0xffcf, 1},
+ {0xffd2, 0xffd7, 1},
+ {0xffda, 0xffdc, 1},
+ },
+ R32: []Range32{
+ {0x10000, 0x1000b, 1},
+ {0x1000d, 0x10026, 1},
+ {0x10028, 0x1003a, 1},
+ {0x1003c, 0x1003d, 1},
+ {0x1003f, 0x1004d, 1},
+ {0x10050, 0x1005d, 1},
+ {0x10080, 0x100fa, 1},
+ {0x10280, 0x1029c, 1},
+ {0x102a0, 0x102d0, 1},
+ {0x10300, 0x1031f, 1},
+ {0x1032d, 0x10340, 1},
+ {0x10342, 0x10349, 1},
+ {0x10350, 0x10375, 1},
+ {0x10380, 0x1039d, 1},
+ {0x103a0, 0x103c3, 1},
+ {0x103c8, 0x103cf, 1},
+ {0x10450, 0x1049d, 1},
+ {0x10500, 0x10527, 1},
+ {0x10530, 0x10563, 1},
+ {0x10600, 0x10736, 1},
+ {0x10740, 0x10755, 1},
+ {0x10760, 0x10767, 1},
+ {0x10800, 0x10805, 1},
+ {0x10808, 0x1080a, 2},
+ {0x1080b, 0x10835, 1},
+ {0x10837, 0x10838, 1},
+ {0x1083c, 0x1083f, 3},
+ {0x10840, 0x10855, 1},
+ {0x10860, 0x10876, 1},
+ {0x10880, 0x1089e, 1},
+ {0x108e0, 0x108f2, 1},
+ {0x108f4, 0x108f5, 1},
+ {0x10900, 0x10915, 1},
+ {0x10920, 0x10939, 1},
+ {0x10980, 0x109b7, 1},
+ {0x109be, 0x109bf, 1},
+ {0x10a00, 0x10a10, 16},
+ {0x10a11, 0x10a13, 1},
+ {0x10a15, 0x10a17, 1},
+ {0x10a19, 0x10a35, 1},
+ {0x10a60, 0x10a7c, 1},
+ {0x10a80, 0x10a9c, 1},
+ {0x10ac0, 0x10ac7, 1},
+ {0x10ac9, 0x10ae4, 1},
+ {0x10b00, 0x10b35, 1},
+ {0x10b40, 0x10b55, 1},
+ {0x10b60, 0x10b72, 1},
+ {0x10b80, 0x10b91, 1},
+ {0x10c00, 0x10c48, 1},
+ {0x10d00, 0x10d23, 1},
+ {0x10e80, 0x10ea9, 1},
+ {0x10eb0, 0x10eb1, 1},
+ {0x10f00, 0x10f1c, 1},
+ {0x10f27, 0x10f30, 9},
+ {0x10f31, 0x10f45, 1},
+ {0x10f70, 0x10f81, 1},
+ {0x10fb0, 0x10fc4, 1},
+ {0x10fe0, 0x10ff6, 1},
+ {0x11003, 0x11037, 1},
+ {0x11071, 0x11072, 1},
+ {0x11075, 0x11083, 14},
+ {0x11084, 0x110af, 1},
+ {0x110d0, 0x110e8, 1},
+ {0x11103, 0x11126, 1},
+ {0x11144, 0x11147, 3},
+ {0x11150, 0x11172, 1},
+ {0x11176, 0x11183, 13},
+ {0x11184, 0x111b2, 1},
+ {0x111c1, 0x111c4, 1},
+ {0x111da, 0x111dc, 2},
+ {0x11200, 0x11211, 1},
+ {0x11213, 0x1122b, 1},
+ {0x1123f, 0x11240, 1},
+ {0x11280, 0x11286, 1},
+ {0x11288, 0x1128a, 2},
+ {0x1128b, 0x1128d, 1},
+ {0x1128f, 0x1129d, 1},
+ {0x1129f, 0x112a8, 1},
+ {0x112b0, 0x112de, 1},
+ {0x11305, 0x1130c, 1},
+ {0x1130f, 0x11310, 1},
+ {0x11313, 0x11328, 1},
+ {0x1132a, 0x11330, 1},
+ {0x11332, 0x11333, 1},
+ {0x11335, 0x11339, 1},
+ {0x1133d, 0x11350, 19},
+ {0x1135d, 0x11361, 1},
+ {0x11400, 0x11434, 1},
+ {0x11447, 0x1144a, 1},
+ {0x1145f, 0x11461, 1},
+ {0x11480, 0x114af, 1},
+ {0x114c4, 0x114c5, 1},
+ {0x114c7, 0x11580, 185},
+ {0x11581, 0x115ae, 1},
+ {0x115d8, 0x115db, 1},
+ {0x11600, 0x1162f, 1},
+ {0x11644, 0x11680, 60},
+ {0x11681, 0x116aa, 1},
+ {0x116b8, 0x11700, 72},
+ {0x11701, 0x1171a, 1},
+ {0x11740, 0x11746, 1},
+ {0x11800, 0x1182b, 1},
+ {0x118ff, 0x11906, 1},
+ {0x11909, 0x1190c, 3},
+ {0x1190d, 0x11913, 1},
+ {0x11915, 0x11916, 1},
+ {0x11918, 0x1192f, 1},
+ {0x1193f, 0x11941, 2},
+ {0x119a0, 0x119a7, 1},
+ {0x119aa, 0x119d0, 1},
+ {0x119e1, 0x119e3, 2},
+ {0x11a00, 0x11a0b, 11},
+ {0x11a0c, 0x11a32, 1},
+ {0x11a3a, 0x11a50, 22},
+ {0x11a5c, 0x11a89, 1},
+ {0x11a9d, 0x11ab0, 19},
+ {0x11ab1, 0x11af8, 1},
+ {0x11c00, 0x11c08, 1},
+ {0x11c0a, 0x11c2e, 1},
+ {0x11c40, 0x11c72, 50},
+ {0x11c73, 0x11c8f, 1},
+ {0x11d00, 0x11d06, 1},
+ {0x11d08, 0x11d09, 1},
+ {0x11d0b, 0x11d30, 1},
+ {0x11d46, 0x11d60, 26},
+ {0x11d61, 0x11d65, 1},
+ {0x11d67, 0x11d68, 1},
+ {0x11d6a, 0x11d89, 1},
+ {0x11d98, 0x11ee0, 328},
+ {0x11ee1, 0x11ef2, 1},
+ {0x11f02, 0x11f04, 2},
+ {0x11f05, 0x11f10, 1},
+ {0x11f12, 0x11f33, 1},
+ {0x11fb0, 0x12000, 80},
+ {0x12001, 0x12399, 1},
+ {0x12480, 0x12543, 1},
+ {0x12f90, 0x12ff0, 1},
+ {0x13000, 0x1342f, 1},
+ {0x13441, 0x13446, 1},
+ {0x14400, 0x14646, 1},
+ {0x16800, 0x16a38, 1},
+ {0x16a40, 0x16a5e, 1},
+ {0x16a70, 0x16abe, 1},
+ {0x16ad0, 0x16aed, 1},
+ {0x16b00, 0x16b2f, 1},
+ {0x16b63, 0x16b77, 1},
+ {0x16b7d, 0x16b8f, 1},
+ {0x16f00, 0x16f4a, 1},
+ {0x16f50, 0x17000, 176},
+ {0x17001, 0x187f7, 1},
+ {0x18800, 0x18cd5, 1},
+ {0x18d00, 0x18d08, 1},
+ {0x1b000, 0x1b122, 1},
+ {0x1b132, 0x1b150, 30},
+ {0x1b151, 0x1b152, 1},
+ {0x1b155, 0x1b164, 15},
+ {0x1b165, 0x1b167, 1},
+ {0x1b170, 0x1b2fb, 1},
+ {0x1bc00, 0x1bc6a, 1},
+ {0x1bc70, 0x1bc7c, 1},
+ {0x1bc80, 0x1bc88, 1},
+ {0x1bc90, 0x1bc99, 1},
+ {0x1df0a, 0x1e100, 502},
+ {0x1e101, 0x1e12c, 1},
+ {0x1e14e, 0x1e290, 322},
+ {0x1e291, 0x1e2ad, 1},
+ {0x1e2c0, 0x1e2eb, 1},
+ {0x1e4d0, 0x1e4ea, 1},
+ {0x1e7e0, 0x1e7e6, 1},
+ {0x1e7e8, 0x1e7eb, 1},
+ {0x1e7ed, 0x1e7ee, 1},
+ {0x1e7f0, 0x1e7fe, 1},
+ {0x1e800, 0x1e8c4, 1},
+ {0x1ee00, 0x1ee03, 1},
+ {0x1ee05, 0x1ee1f, 1},
+ {0x1ee21, 0x1ee22, 1},
+ {0x1ee24, 0x1ee27, 3},
+ {0x1ee29, 0x1ee32, 1},
+ {0x1ee34, 0x1ee37, 1},
+ {0x1ee39, 0x1ee3b, 2},
+ {0x1ee42, 0x1ee47, 5},
+ {0x1ee49, 0x1ee4d, 2},
+ {0x1ee4e, 0x1ee4f, 1},
+ {0x1ee51, 0x1ee52, 1},
+ {0x1ee54, 0x1ee57, 3},
+ {0x1ee59, 0x1ee61, 2},
+ {0x1ee62, 0x1ee64, 2},
+ {0x1ee67, 0x1ee6a, 1},
+ {0x1ee6c, 0x1ee72, 1},
+ {0x1ee74, 0x1ee77, 1},
+ {0x1ee79, 0x1ee7c, 1},
+ {0x1ee7e, 0x1ee80, 2},
+ {0x1ee81, 0x1ee89, 1},
+ {0x1ee8b, 0x1ee9b, 1},
+ {0x1eea1, 0x1eea3, 1},
+ {0x1eea5, 0x1eea9, 1},
+ {0x1eeab, 0x1eebb, 1},
+ {0x20000, 0x2a6df, 1},
+ {0x2a700, 0x2b739, 1},
+ {0x2b740, 0x2b81d, 1},
+ {0x2b820, 0x2cea1, 1},
+ {0x2ceb0, 0x2ebe0, 1},
+ {0x2f800, 0x2fa1d, 1},
+ {0x30000, 0x3134a, 1},
+ {0x31350, 0x323af, 1},
+ },
+ LatinOffset: 1,
+}
+
+var _Lt = &RangeTable{
+ R16: []Range16{
+ {0x01c5, 0x01cb, 3},
+ {0x01f2, 0x1f88, 7574},
+ {0x1f89, 0x1f8f, 1},
+ {0x1f98, 0x1f9f, 1},
+ {0x1fa8, 0x1faf, 1},
+ {0x1fbc, 0x1fcc, 16},
+ {0x1ffc, 0x1ffc, 1},
+ },
+}
+
+var _Lu = &RangeTable{
+ R16: []Range16{
+ {0x0041, 0x005a, 1},
+ {0x00c0, 0x00d6, 1},
+ {0x00d8, 0x00de, 1},
+ {0x0100, 0x0136, 2},
+ {0x0139, 0x0147, 2},
+ {0x014a, 0x0178, 2},
+ {0x0179, 0x017d, 2},
+ {0x0181, 0x0182, 1},
+ {0x0184, 0x0186, 2},
+ {0x0187, 0x0189, 2},
+ {0x018a, 0x018b, 1},
+ {0x018e, 0x0191, 1},
+ {0x0193, 0x0194, 1},
+ {0x0196, 0x0198, 1},
+ {0x019c, 0x019d, 1},
+ {0x019f, 0x01a0, 1},
+ {0x01a2, 0x01a6, 2},
+ {0x01a7, 0x01a9, 2},
+ {0x01ac, 0x01ae, 2},
+ {0x01af, 0x01b1, 2},
+ {0x01b2, 0x01b3, 1},
+ {0x01b5, 0x01b7, 2},
+ {0x01b8, 0x01bc, 4},
+ {0x01c4, 0x01cd, 3},
+ {0x01cf, 0x01db, 2},
+ {0x01de, 0x01ee, 2},
+ {0x01f1, 0x01f4, 3},
+ {0x01f6, 0x01f8, 1},
+ {0x01fa, 0x0232, 2},
+ {0x023a, 0x023b, 1},
+ {0x023d, 0x023e, 1},
+ {0x0241, 0x0243, 2},
+ {0x0244, 0x0246, 1},
+ {0x0248, 0x024e, 2},
+ {0x0370, 0x0372, 2},
+ {0x0376, 0x037f, 9},
+ {0x0386, 0x0388, 2},
+ {0x0389, 0x038a, 1},
+ {0x038c, 0x038e, 2},
+ {0x038f, 0x0391, 2},
+ {0x0392, 0x03a1, 1},
+ {0x03a3, 0x03ab, 1},
+ {0x03cf, 0x03d2, 3},
+ {0x03d3, 0x03d4, 1},
+ {0x03d8, 0x03ee, 2},
+ {0x03f4, 0x03f7, 3},
+ {0x03f9, 0x03fa, 1},
+ {0x03fd, 0x042f, 1},
+ {0x0460, 0x0480, 2},
+ {0x048a, 0x04c0, 2},
+ {0x04c1, 0x04cd, 2},
+ {0x04d0, 0x052e, 2},
+ {0x0531, 0x0556, 1},
+ {0x10a0, 0x10c5, 1},
+ {0x10c7, 0x10cd, 6},
+ {0x13a0, 0x13f5, 1},
+ {0x1c90, 0x1cba, 1},
+ {0x1cbd, 0x1cbf, 1},
+ {0x1e00, 0x1e94, 2},
+ {0x1e9e, 0x1efe, 2},
+ {0x1f08, 0x1f0f, 1},
+ {0x1f18, 0x1f1d, 1},
+ {0x1f28, 0x1f2f, 1},
+ {0x1f38, 0x1f3f, 1},
+ {0x1f48, 0x1f4d, 1},
+ {0x1f59, 0x1f5f, 2},
+ {0x1f68, 0x1f6f, 1},
+ {0x1fb8, 0x1fbb, 1},
+ {0x1fc8, 0x1fcb, 1},
+ {0x1fd8, 0x1fdb, 1},
+ {0x1fe8, 0x1fec, 1},
+ {0x1ff8, 0x1ffb, 1},
+ {0x2102, 0x2107, 5},
+ {0x210b, 0x210d, 1},
+ {0x2110, 0x2112, 1},
+ {0x2115, 0x2119, 4},
+ {0x211a, 0x211d, 1},
+ {0x2124, 0x212a, 2},
+ {0x212b, 0x212d, 1},
+ {0x2130, 0x2133, 1},
+ {0x213e, 0x213f, 1},
+ {0x2145, 0x2183, 62},
+ {0x2c00, 0x2c2f, 1},
+ {0x2c60, 0x2c62, 2},
+ {0x2c63, 0x2c64, 1},
+ {0x2c67, 0x2c6d, 2},
+ {0x2c6e, 0x2c70, 1},
+ {0x2c72, 0x2c75, 3},
+ {0x2c7e, 0x2c80, 1},
+ {0x2c82, 0x2ce2, 2},
+ {0x2ceb, 0x2ced, 2},
+ {0x2cf2, 0xa640, 31054},
+ {0xa642, 0xa66c, 2},
+ {0xa680, 0xa69a, 2},
+ {0xa722, 0xa72e, 2},
+ {0xa732, 0xa76e, 2},
+ {0xa779, 0xa77d, 2},
+ {0xa77e, 0xa786, 2},
+ {0xa78b, 0xa78d, 2},
+ {0xa790, 0xa792, 2},
+ {0xa796, 0xa7aa, 2},
+ {0xa7ab, 0xa7ae, 1},
+ {0xa7b0, 0xa7b4, 1},
+ {0xa7b6, 0xa7c4, 2},
+ {0xa7c5, 0xa7c7, 1},
+ {0xa7c9, 0xa7d0, 7},
+ {0xa7d6, 0xa7d8, 2},
+ {0xa7f5, 0xff21, 22316},
+ {0xff22, 0xff3a, 1},
+ },
+ R32: []Range32{
+ {0x10400, 0x10427, 1},
+ {0x104b0, 0x104d3, 1},
+ {0x10570, 0x1057a, 1},
+ {0x1057c, 0x1058a, 1},
+ {0x1058c, 0x10592, 1},
+ {0x10594, 0x10595, 1},
+ {0x10c80, 0x10cb2, 1},
+ {0x118a0, 0x118bf, 1},
+ {0x16e40, 0x16e5f, 1},
+ {0x1d400, 0x1d419, 1},
+ {0x1d434, 0x1d44d, 1},
+ {0x1d468, 0x1d481, 1},
+ {0x1d49c, 0x1d49e, 2},
+ {0x1d49f, 0x1d4a5, 3},
+ {0x1d4a6, 0x1d4a9, 3},
+ {0x1d4aa, 0x1d4ac, 1},
+ {0x1d4ae, 0x1d4b5, 1},
+ {0x1d4d0, 0x1d4e9, 1},
+ {0x1d504, 0x1d505, 1},
+ {0x1d507, 0x1d50a, 1},
+ {0x1d50d, 0x1d514, 1},
+ {0x1d516, 0x1d51c, 1},
+ {0x1d538, 0x1d539, 1},
+ {0x1d53b, 0x1d53e, 1},
+ {0x1d540, 0x1d544, 1},
+ {0x1d546, 0x1d54a, 4},
+ {0x1d54b, 0x1d550, 1},
+ {0x1d56c, 0x1d585, 1},
+ {0x1d5a0, 0x1d5b9, 1},
+ {0x1d5d4, 0x1d5ed, 1},
+ {0x1d608, 0x1d621, 1},
+ {0x1d63c, 0x1d655, 1},
+ {0x1d670, 0x1d689, 1},
+ {0x1d6a8, 0x1d6c0, 1},
+ {0x1d6e2, 0x1d6fa, 1},
+ {0x1d71c, 0x1d734, 1},
+ {0x1d756, 0x1d76e, 1},
+ {0x1d790, 0x1d7a8, 1},
+ {0x1d7ca, 0x1e900, 4406},
+ {0x1e901, 0x1e921, 1},
+ },
+ LatinOffset: 3,
+}
+
+var _M = &RangeTable{
+ R16: []Range16{
+ {0x0300, 0x036f, 1},
+ {0x0483, 0x0489, 1},
+ {0x0591, 0x05bd, 1},
+ {0x05bf, 0x05c1, 2},
+ {0x05c2, 0x05c4, 2},
+ {0x05c5, 0x05c7, 2},
+ {0x0610, 0x061a, 1},
+ {0x064b, 0x065f, 1},
+ {0x0670, 0x06d6, 102},
+ {0x06d7, 0x06dc, 1},
+ {0x06df, 0x06e4, 1},
+ {0x06e7, 0x06e8, 1},
+ {0x06ea, 0x06ed, 1},
+ {0x0711, 0x0730, 31},
+ {0x0731, 0x074a, 1},
+ {0x07a6, 0x07b0, 1},
+ {0x07eb, 0x07f3, 1},
+ {0x07fd, 0x0816, 25},
+ {0x0817, 0x0819, 1},
+ {0x081b, 0x0823, 1},
+ {0x0825, 0x0827, 1},
+ {0x0829, 0x082d, 1},
+ {0x0859, 0x085b, 1},
+ {0x0898, 0x089f, 1},
+ {0x08ca, 0x08e1, 1},
+ {0x08e3, 0x0903, 1},
+ {0x093a, 0x093c, 1},
+ {0x093e, 0x094f, 1},
+ {0x0951, 0x0957, 1},
+ {0x0962, 0x0963, 1},
+ {0x0981, 0x0983, 1},
+ {0x09bc, 0x09be, 2},
+ {0x09bf, 0x09c4, 1},
+ {0x09c7, 0x09c8, 1},
+ {0x09cb, 0x09cd, 1},
+ {0x09d7, 0x09e2, 11},
+ {0x09e3, 0x09fe, 27},
+ {0x0a01, 0x0a03, 1},
+ {0x0a3c, 0x0a3e, 2},
+ {0x0a3f, 0x0a42, 1},
+ {0x0a47, 0x0a48, 1},
+ {0x0a4b, 0x0a4d, 1},
+ {0x0a51, 0x0a70, 31},
+ {0x0a71, 0x0a75, 4},
+ {0x0a81, 0x0a83, 1},
+ {0x0abc, 0x0abe, 2},
+ {0x0abf, 0x0ac5, 1},
+ {0x0ac7, 0x0ac9, 1},
+ {0x0acb, 0x0acd, 1},
+ {0x0ae2, 0x0ae3, 1},
+ {0x0afa, 0x0aff, 1},
+ {0x0b01, 0x0b03, 1},
+ {0x0b3c, 0x0b3e, 2},
+ {0x0b3f, 0x0b44, 1},
+ {0x0b47, 0x0b48, 1},
+ {0x0b4b, 0x0b4d, 1},
+ {0x0b55, 0x0b57, 1},
+ {0x0b62, 0x0b63, 1},
+ {0x0b82, 0x0bbe, 60},
+ {0x0bbf, 0x0bc2, 1},
+ {0x0bc6, 0x0bc8, 1},
+ {0x0bca, 0x0bcd, 1},
+ {0x0bd7, 0x0c00, 41},
+ {0x0c01, 0x0c04, 1},
+ {0x0c3c, 0x0c3e, 2},
+ {0x0c3f, 0x0c44, 1},
+ {0x0c46, 0x0c48, 1},
+ {0x0c4a, 0x0c4d, 1},
+ {0x0c55, 0x0c56, 1},
+ {0x0c62, 0x0c63, 1},
+ {0x0c81, 0x0c83, 1},
+ {0x0cbc, 0x0cbe, 2},
+ {0x0cbf, 0x0cc4, 1},
+ {0x0cc6, 0x0cc8, 1},
+ {0x0cca, 0x0ccd, 1},
+ {0x0cd5, 0x0cd6, 1},
+ {0x0ce2, 0x0ce3, 1},
+ {0x0cf3, 0x0d00, 13},
+ {0x0d01, 0x0d03, 1},
+ {0x0d3b, 0x0d3c, 1},
+ {0x0d3e, 0x0d44, 1},
+ {0x0d46, 0x0d48, 1},
+ {0x0d4a, 0x0d4d, 1},
+ {0x0d57, 0x0d62, 11},
+ {0x0d63, 0x0d81, 30},
+ {0x0d82, 0x0d83, 1},
+ {0x0dca, 0x0dcf, 5},
+ {0x0dd0, 0x0dd4, 1},
+ {0x0dd6, 0x0dd8, 2},
+ {0x0dd9, 0x0ddf, 1},
+ {0x0df2, 0x0df3, 1},
+ {0x0e31, 0x0e34, 3},
+ {0x0e35, 0x0e3a, 1},
+ {0x0e47, 0x0e4e, 1},
+ {0x0eb1, 0x0eb4, 3},
+ {0x0eb5, 0x0ebc, 1},
+ {0x0ec8, 0x0ece, 1},
+ {0x0f18, 0x0f19, 1},
+ {0x0f35, 0x0f39, 2},
+ {0x0f3e, 0x0f3f, 1},
+ {0x0f71, 0x0f84, 1},
+ {0x0f86, 0x0f87, 1},
+ {0x0f8d, 0x0f97, 1},
+ {0x0f99, 0x0fbc, 1},
+ {0x0fc6, 0x102b, 101},
+ {0x102c, 0x103e, 1},
+ {0x1056, 0x1059, 1},
+ {0x105e, 0x1060, 1},
+ {0x1062, 0x1064, 1},
+ {0x1067, 0x106d, 1},
+ {0x1071, 0x1074, 1},
+ {0x1082, 0x108d, 1},
+ {0x108f, 0x109a, 11},
+ {0x109b, 0x109d, 1},
+ {0x135d, 0x135f, 1},
+ {0x1712, 0x1715, 1},
+ {0x1732, 0x1734, 1},
+ {0x1752, 0x1753, 1},
+ {0x1772, 0x1773, 1},
+ {0x17b4, 0x17d3, 1},
+ {0x17dd, 0x180b, 46},
+ {0x180c, 0x180d, 1},
+ {0x180f, 0x1885, 118},
+ {0x1886, 0x18a9, 35},
+ {0x1920, 0x192b, 1},
+ {0x1930, 0x193b, 1},
+ {0x1a17, 0x1a1b, 1},
+ {0x1a55, 0x1a5e, 1},
+ {0x1a60, 0x1a7c, 1},
+ {0x1a7f, 0x1ab0, 49},
+ {0x1ab1, 0x1ace, 1},
+ {0x1b00, 0x1b04, 1},
+ {0x1b34, 0x1b44, 1},
+ {0x1b6b, 0x1b73, 1},
+ {0x1b80, 0x1b82, 1},
+ {0x1ba1, 0x1bad, 1},
+ {0x1be6, 0x1bf3, 1},
+ {0x1c24, 0x1c37, 1},
+ {0x1cd0, 0x1cd2, 1},
+ {0x1cd4, 0x1ce8, 1},
+ {0x1ced, 0x1cf4, 7},
+ {0x1cf7, 0x1cf9, 1},
+ {0x1dc0, 0x1dff, 1},
+ {0x20d0, 0x20f0, 1},
+ {0x2cef, 0x2cf1, 1},
+ {0x2d7f, 0x2de0, 97},
+ {0x2de1, 0x2dff, 1},
+ {0x302a, 0x302f, 1},
+ {0x3099, 0x309a, 1},
+ {0xa66f, 0xa672, 1},
+ {0xa674, 0xa67d, 1},
+ {0xa69e, 0xa69f, 1},
+ {0xa6f0, 0xa6f1, 1},
+ {0xa802, 0xa806, 4},
+ {0xa80b, 0xa823, 24},
+ {0xa824, 0xa827, 1},
+ {0xa82c, 0xa880, 84},
+ {0xa881, 0xa8b4, 51},
+ {0xa8b5, 0xa8c5, 1},
+ {0xa8e0, 0xa8f1, 1},
+ {0xa8ff, 0xa926, 39},
+ {0xa927, 0xa92d, 1},
+ {0xa947, 0xa953, 1},
+ {0xa980, 0xa983, 1},
+ {0xa9b3, 0xa9c0, 1},
+ {0xa9e5, 0xaa29, 68},
+ {0xaa2a, 0xaa36, 1},
+ {0xaa43, 0xaa4c, 9},
+ {0xaa4d, 0xaa7b, 46},
+ {0xaa7c, 0xaa7d, 1},
+ {0xaab0, 0xaab2, 2},
+ {0xaab3, 0xaab4, 1},
+ {0xaab7, 0xaab8, 1},
+ {0xaabe, 0xaabf, 1},
+ {0xaac1, 0xaaeb, 42},
+ {0xaaec, 0xaaef, 1},
+ {0xaaf5, 0xaaf6, 1},
+ {0xabe3, 0xabea, 1},
+ {0xabec, 0xabed, 1},
+ {0xfb1e, 0xfe00, 738},
+ {0xfe01, 0xfe0f, 1},
+ {0xfe20, 0xfe2f, 1},
+ },
+ R32: []Range32{
+ {0x101fd, 0x102e0, 227},
+ {0x10376, 0x1037a, 1},
+ {0x10a01, 0x10a03, 1},
+ {0x10a05, 0x10a06, 1},
+ {0x10a0c, 0x10a0f, 1},
+ {0x10a38, 0x10a3a, 1},
+ {0x10a3f, 0x10ae5, 166},
+ {0x10ae6, 0x10d24, 574},
+ {0x10d25, 0x10d27, 1},
+ {0x10eab, 0x10eac, 1},
+ {0x10efd, 0x10eff, 1},
+ {0x10f46, 0x10f50, 1},
+ {0x10f82, 0x10f85, 1},
+ {0x11000, 0x11002, 1},
+ {0x11038, 0x11046, 1},
+ {0x11070, 0x11073, 3},
+ {0x11074, 0x1107f, 11},
+ {0x11080, 0x11082, 1},
+ {0x110b0, 0x110ba, 1},
+ {0x110c2, 0x11100, 62},
+ {0x11101, 0x11102, 1},
+ {0x11127, 0x11134, 1},
+ {0x11145, 0x11146, 1},
+ {0x11173, 0x11180, 13},
+ {0x11181, 0x11182, 1},
+ {0x111b3, 0x111c0, 1},
+ {0x111c9, 0x111cc, 1},
+ {0x111ce, 0x111cf, 1},
+ {0x1122c, 0x11237, 1},
+ {0x1123e, 0x11241, 3},
+ {0x112df, 0x112ea, 1},
+ {0x11300, 0x11303, 1},
+ {0x1133b, 0x1133c, 1},
+ {0x1133e, 0x11344, 1},
+ {0x11347, 0x11348, 1},
+ {0x1134b, 0x1134d, 1},
+ {0x11357, 0x11362, 11},
+ {0x11363, 0x11366, 3},
+ {0x11367, 0x1136c, 1},
+ {0x11370, 0x11374, 1},
+ {0x11435, 0x11446, 1},
+ {0x1145e, 0x114b0, 82},
+ {0x114b1, 0x114c3, 1},
+ {0x115af, 0x115b5, 1},
+ {0x115b8, 0x115c0, 1},
+ {0x115dc, 0x115dd, 1},
+ {0x11630, 0x11640, 1},
+ {0x116ab, 0x116b7, 1},
+ {0x1171d, 0x1172b, 1},
+ {0x1182c, 0x1183a, 1},
+ {0x11930, 0x11935, 1},
+ {0x11937, 0x11938, 1},
+ {0x1193b, 0x1193e, 1},
+ {0x11940, 0x11942, 2},
+ {0x11943, 0x119d1, 142},
+ {0x119d2, 0x119d7, 1},
+ {0x119da, 0x119e0, 1},
+ {0x119e4, 0x11a01, 29},
+ {0x11a02, 0x11a0a, 1},
+ {0x11a33, 0x11a39, 1},
+ {0x11a3b, 0x11a3e, 1},
+ {0x11a47, 0x11a51, 10},
+ {0x11a52, 0x11a5b, 1},
+ {0x11a8a, 0x11a99, 1},
+ {0x11c2f, 0x11c36, 1},
+ {0x11c38, 0x11c3f, 1},
+ {0x11c92, 0x11ca7, 1},
+ {0x11ca9, 0x11cb6, 1},
+ {0x11d31, 0x11d36, 1},
+ {0x11d3a, 0x11d3c, 2},
+ {0x11d3d, 0x11d3f, 2},
+ {0x11d40, 0x11d45, 1},
+ {0x11d47, 0x11d8a, 67},
+ {0x11d8b, 0x11d8e, 1},
+ {0x11d90, 0x11d91, 1},
+ {0x11d93, 0x11d97, 1},
+ {0x11ef3, 0x11ef6, 1},
+ {0x11f00, 0x11f01, 1},
+ {0x11f03, 0x11f34, 49},
+ {0x11f35, 0x11f3a, 1},
+ {0x11f3e, 0x11f42, 1},
+ {0x13440, 0x13447, 7},
+ {0x13448, 0x13455, 1},
+ {0x16af0, 0x16af4, 1},
+ {0x16b30, 0x16b36, 1},
+ {0x16f4f, 0x16f51, 2},
+ {0x16f52, 0x16f87, 1},
+ {0x16f8f, 0x16f92, 1},
+ {0x16fe4, 0x16ff0, 12},
+ {0x16ff1, 0x1bc9d, 19628},
+ {0x1bc9e, 0x1cf00, 4706},
+ {0x1cf01, 0x1cf2d, 1},
+ {0x1cf30, 0x1cf46, 1},
+ {0x1d165, 0x1d169, 1},
+ {0x1d16d, 0x1d172, 1},
+ {0x1d17b, 0x1d182, 1},
+ {0x1d185, 0x1d18b, 1},
+ {0x1d1aa, 0x1d1ad, 1},
+ {0x1d242, 0x1d244, 1},
+ {0x1da00, 0x1da36, 1},
+ {0x1da3b, 0x1da6c, 1},
+ {0x1da75, 0x1da84, 15},
+ {0x1da9b, 0x1da9f, 1},
+ {0x1daa1, 0x1daaf, 1},
+ {0x1e000, 0x1e006, 1},
+ {0x1e008, 0x1e018, 1},
+ {0x1e01b, 0x1e021, 1},
+ {0x1e023, 0x1e024, 1},
+ {0x1e026, 0x1e02a, 1},
+ {0x1e08f, 0x1e130, 161},
+ {0x1e131, 0x1e136, 1},
+ {0x1e2ae, 0x1e2ec, 62},
+ {0x1e2ed, 0x1e2ef, 1},
+ {0x1e4ec, 0x1e4ef, 1},
+ {0x1e8d0, 0x1e8d6, 1},
+ {0x1e944, 0x1e94a, 1},
+ {0xe0100, 0xe01ef, 1},
+ },
+}
+
+var _Mc = &RangeTable{
+ R16: []Range16{
+ {0x0903, 0x093b, 56},
+ {0x093e, 0x0940, 1},
+ {0x0949, 0x094c, 1},
+ {0x094e, 0x094f, 1},
+ {0x0982, 0x0983, 1},
+ {0x09be, 0x09c0, 1},
+ {0x09c7, 0x09c8, 1},
+ {0x09cb, 0x09cc, 1},
+ {0x09d7, 0x0a03, 44},
+ {0x0a3e, 0x0a40, 1},
+ {0x0a83, 0x0abe, 59},
+ {0x0abf, 0x0ac0, 1},
+ {0x0ac9, 0x0acb, 2},
+ {0x0acc, 0x0b02, 54},
+ {0x0b03, 0x0b3e, 59},
+ {0x0b40, 0x0b47, 7},
+ {0x0b48, 0x0b4b, 3},
+ {0x0b4c, 0x0b57, 11},
+ {0x0bbe, 0x0bbf, 1},
+ {0x0bc1, 0x0bc2, 1},
+ {0x0bc6, 0x0bc8, 1},
+ {0x0bca, 0x0bcc, 1},
+ {0x0bd7, 0x0c01, 42},
+ {0x0c02, 0x0c03, 1},
+ {0x0c41, 0x0c44, 1},
+ {0x0c82, 0x0c83, 1},
+ {0x0cbe, 0x0cc0, 2},
+ {0x0cc1, 0x0cc4, 1},
+ {0x0cc7, 0x0cc8, 1},
+ {0x0cca, 0x0ccb, 1},
+ {0x0cd5, 0x0cd6, 1},
+ {0x0cf3, 0x0d02, 15},
+ {0x0d03, 0x0d3e, 59},
+ {0x0d3f, 0x0d40, 1},
+ {0x0d46, 0x0d48, 1},
+ {0x0d4a, 0x0d4c, 1},
+ {0x0d57, 0x0d82, 43},
+ {0x0d83, 0x0dcf, 76},
+ {0x0dd0, 0x0dd1, 1},
+ {0x0dd8, 0x0ddf, 1},
+ {0x0df2, 0x0df3, 1},
+ {0x0f3e, 0x0f3f, 1},
+ {0x0f7f, 0x102b, 172},
+ {0x102c, 0x1031, 5},
+ {0x1038, 0x103b, 3},
+ {0x103c, 0x1056, 26},
+ {0x1057, 0x1062, 11},
+ {0x1063, 0x1064, 1},
+ {0x1067, 0x106d, 1},
+ {0x1083, 0x1084, 1},
+ {0x1087, 0x108c, 1},
+ {0x108f, 0x109a, 11},
+ {0x109b, 0x109c, 1},
+ {0x1715, 0x1734, 31},
+ {0x17b6, 0x17be, 8},
+ {0x17bf, 0x17c5, 1},
+ {0x17c7, 0x17c8, 1},
+ {0x1923, 0x1926, 1},
+ {0x1929, 0x192b, 1},
+ {0x1930, 0x1931, 1},
+ {0x1933, 0x1938, 1},
+ {0x1a19, 0x1a1a, 1},
+ {0x1a55, 0x1a57, 2},
+ {0x1a61, 0x1a63, 2},
+ {0x1a64, 0x1a6d, 9},
+ {0x1a6e, 0x1a72, 1},
+ {0x1b04, 0x1b35, 49},
+ {0x1b3b, 0x1b3d, 2},
+ {0x1b3e, 0x1b41, 1},
+ {0x1b43, 0x1b44, 1},
+ {0x1b82, 0x1ba1, 31},
+ {0x1ba6, 0x1ba7, 1},
+ {0x1baa, 0x1be7, 61},
+ {0x1bea, 0x1bec, 1},
+ {0x1bee, 0x1bf2, 4},
+ {0x1bf3, 0x1c24, 49},
+ {0x1c25, 0x1c2b, 1},
+ {0x1c34, 0x1c35, 1},
+ {0x1ce1, 0x1cf7, 22},
+ {0x302e, 0x302f, 1},
+ {0xa823, 0xa824, 1},
+ {0xa827, 0xa880, 89},
+ {0xa881, 0xa8b4, 51},
+ {0xa8b5, 0xa8c3, 1},
+ {0xa952, 0xa953, 1},
+ {0xa983, 0xa9b4, 49},
+ {0xa9b5, 0xa9ba, 5},
+ {0xa9bb, 0xa9be, 3},
+ {0xa9bf, 0xa9c0, 1},
+ {0xaa2f, 0xaa30, 1},
+ {0xaa33, 0xaa34, 1},
+ {0xaa4d, 0xaa7b, 46},
+ {0xaa7d, 0xaaeb, 110},
+ {0xaaee, 0xaaef, 1},
+ {0xaaf5, 0xabe3, 238},
+ {0xabe4, 0xabe6, 2},
+ {0xabe7, 0xabe9, 2},
+ {0xabea, 0xabec, 2},
+ },
+ R32: []Range32{
+ {0x11000, 0x11002, 2},
+ {0x11082, 0x110b0, 46},
+ {0x110b1, 0x110b2, 1},
+ {0x110b7, 0x110b8, 1},
+ {0x1112c, 0x11145, 25},
+ {0x11146, 0x11182, 60},
+ {0x111b3, 0x111b5, 1},
+ {0x111bf, 0x111c0, 1},
+ {0x111ce, 0x1122c, 94},
+ {0x1122d, 0x1122e, 1},
+ {0x11232, 0x11233, 1},
+ {0x11235, 0x112e0, 171},
+ {0x112e1, 0x112e2, 1},
+ {0x11302, 0x11303, 1},
+ {0x1133e, 0x1133f, 1},
+ {0x11341, 0x11344, 1},
+ {0x11347, 0x11348, 1},
+ {0x1134b, 0x1134d, 1},
+ {0x11357, 0x11362, 11},
+ {0x11363, 0x11435, 210},
+ {0x11436, 0x11437, 1},
+ {0x11440, 0x11441, 1},
+ {0x11445, 0x114b0, 107},
+ {0x114b1, 0x114b2, 1},
+ {0x114b9, 0x114bb, 2},
+ {0x114bc, 0x114be, 1},
+ {0x114c1, 0x115af, 238},
+ {0x115b0, 0x115b1, 1},
+ {0x115b8, 0x115bb, 1},
+ {0x115be, 0x11630, 114},
+ {0x11631, 0x11632, 1},
+ {0x1163b, 0x1163c, 1},
+ {0x1163e, 0x116ac, 110},
+ {0x116ae, 0x116af, 1},
+ {0x116b6, 0x11720, 106},
+ {0x11721, 0x11726, 5},
+ {0x1182c, 0x1182e, 1},
+ {0x11838, 0x11930, 248},
+ {0x11931, 0x11935, 1},
+ {0x11937, 0x11938, 1},
+ {0x1193d, 0x11940, 3},
+ {0x11942, 0x119d1, 143},
+ {0x119d2, 0x119d3, 1},
+ {0x119dc, 0x119df, 1},
+ {0x119e4, 0x11a39, 85},
+ {0x11a57, 0x11a58, 1},
+ {0x11a97, 0x11c2f, 408},
+ {0x11c3e, 0x11ca9, 107},
+ {0x11cb1, 0x11cb4, 3},
+ {0x11d8a, 0x11d8e, 1},
+ {0x11d93, 0x11d94, 1},
+ {0x11d96, 0x11ef5, 351},
+ {0x11ef6, 0x11f03, 13},
+ {0x11f34, 0x11f35, 1},
+ {0x11f3e, 0x11f3f, 1},
+ {0x11f41, 0x16f51, 20496},
+ {0x16f52, 0x16f87, 1},
+ {0x16ff0, 0x16ff1, 1},
+ {0x1d165, 0x1d166, 1},
+ {0x1d16d, 0x1d172, 1},
+ },
+}
+
+var _Me = &RangeTable{
+ R16: []Range16{
+ {0x0488, 0x0489, 1},
+ {0x1abe, 0x20dd, 1567},
+ {0x20de, 0x20e0, 1},
+ {0x20e2, 0x20e4, 1},
+ {0xa670, 0xa672, 1},
+ },
+}
+
+var _Mn = &RangeTable{
+ R16: []Range16{
+ {0x0300, 0x036f, 1},
+ {0x0483, 0x0487, 1},
+ {0x0591, 0x05bd, 1},
+ {0x05bf, 0x05c1, 2},
+ {0x05c2, 0x05c4, 2},
+ {0x05c5, 0x05c7, 2},
+ {0x0610, 0x061a, 1},
+ {0x064b, 0x065f, 1},
+ {0x0670, 0x06d6, 102},
+ {0x06d7, 0x06dc, 1},
+ {0x06df, 0x06e4, 1},
+ {0x06e7, 0x06e8, 1},
+ {0x06ea, 0x06ed, 1},
+ {0x0711, 0x0730, 31},
+ {0x0731, 0x074a, 1},
+ {0x07a6, 0x07b0, 1},
+ {0x07eb, 0x07f3, 1},
+ {0x07fd, 0x0816, 25},
+ {0x0817, 0x0819, 1},
+ {0x081b, 0x0823, 1},
+ {0x0825, 0x0827, 1},
+ {0x0829, 0x082d, 1},
+ {0x0859, 0x085b, 1},
+ {0x0898, 0x089f, 1},
+ {0x08ca, 0x08e1, 1},
+ {0x08e3, 0x0902, 1},
+ {0x093a, 0x093c, 2},
+ {0x0941, 0x0948, 1},
+ {0x094d, 0x0951, 4},
+ {0x0952, 0x0957, 1},
+ {0x0962, 0x0963, 1},
+ {0x0981, 0x09bc, 59},
+ {0x09c1, 0x09c4, 1},
+ {0x09cd, 0x09e2, 21},
+ {0x09e3, 0x09fe, 27},
+ {0x0a01, 0x0a02, 1},
+ {0x0a3c, 0x0a41, 5},
+ {0x0a42, 0x0a47, 5},
+ {0x0a48, 0x0a4b, 3},
+ {0x0a4c, 0x0a4d, 1},
+ {0x0a51, 0x0a70, 31},
+ {0x0a71, 0x0a75, 4},
+ {0x0a81, 0x0a82, 1},
+ {0x0abc, 0x0ac1, 5},
+ {0x0ac2, 0x0ac5, 1},
+ {0x0ac7, 0x0ac8, 1},
+ {0x0acd, 0x0ae2, 21},
+ {0x0ae3, 0x0afa, 23},
+ {0x0afb, 0x0aff, 1},
+ {0x0b01, 0x0b3c, 59},
+ {0x0b3f, 0x0b41, 2},
+ {0x0b42, 0x0b44, 1},
+ {0x0b4d, 0x0b55, 8},
+ {0x0b56, 0x0b62, 12},
+ {0x0b63, 0x0b82, 31},
+ {0x0bc0, 0x0bcd, 13},
+ {0x0c00, 0x0c04, 4},
+ {0x0c3c, 0x0c3e, 2},
+ {0x0c3f, 0x0c40, 1},
+ {0x0c46, 0x0c48, 1},
+ {0x0c4a, 0x0c4d, 1},
+ {0x0c55, 0x0c56, 1},
+ {0x0c62, 0x0c63, 1},
+ {0x0c81, 0x0cbc, 59},
+ {0x0cbf, 0x0cc6, 7},
+ {0x0ccc, 0x0ccd, 1},
+ {0x0ce2, 0x0ce3, 1},
+ {0x0d00, 0x0d01, 1},
+ {0x0d3b, 0x0d3c, 1},
+ {0x0d41, 0x0d44, 1},
+ {0x0d4d, 0x0d62, 21},
+ {0x0d63, 0x0d81, 30},
+ {0x0dca, 0x0dd2, 8},
+ {0x0dd3, 0x0dd4, 1},
+ {0x0dd6, 0x0e31, 91},
+ {0x0e34, 0x0e3a, 1},
+ {0x0e47, 0x0e4e, 1},
+ {0x0eb1, 0x0eb4, 3},
+ {0x0eb5, 0x0ebc, 1},
+ {0x0ec8, 0x0ece, 1},
+ {0x0f18, 0x0f19, 1},
+ {0x0f35, 0x0f39, 2},
+ {0x0f71, 0x0f7e, 1},
+ {0x0f80, 0x0f84, 1},
+ {0x0f86, 0x0f87, 1},
+ {0x0f8d, 0x0f97, 1},
+ {0x0f99, 0x0fbc, 1},
+ {0x0fc6, 0x102d, 103},
+ {0x102e, 0x1030, 1},
+ {0x1032, 0x1037, 1},
+ {0x1039, 0x103a, 1},
+ {0x103d, 0x103e, 1},
+ {0x1058, 0x1059, 1},
+ {0x105e, 0x1060, 1},
+ {0x1071, 0x1074, 1},
+ {0x1082, 0x1085, 3},
+ {0x1086, 0x108d, 7},
+ {0x109d, 0x135d, 704},
+ {0x135e, 0x135f, 1},
+ {0x1712, 0x1714, 1},
+ {0x1732, 0x1733, 1},
+ {0x1752, 0x1753, 1},
+ {0x1772, 0x1773, 1},
+ {0x17b4, 0x17b5, 1},
+ {0x17b7, 0x17bd, 1},
+ {0x17c6, 0x17c9, 3},
+ {0x17ca, 0x17d3, 1},
+ {0x17dd, 0x180b, 46},
+ {0x180c, 0x180d, 1},
+ {0x180f, 0x1885, 118},
+ {0x1886, 0x18a9, 35},
+ {0x1920, 0x1922, 1},
+ {0x1927, 0x1928, 1},
+ {0x1932, 0x1939, 7},
+ {0x193a, 0x193b, 1},
+ {0x1a17, 0x1a18, 1},
+ {0x1a1b, 0x1a56, 59},
+ {0x1a58, 0x1a5e, 1},
+ {0x1a60, 0x1a62, 2},
+ {0x1a65, 0x1a6c, 1},
+ {0x1a73, 0x1a7c, 1},
+ {0x1a7f, 0x1ab0, 49},
+ {0x1ab1, 0x1abd, 1},
+ {0x1abf, 0x1ace, 1},
+ {0x1b00, 0x1b03, 1},
+ {0x1b34, 0x1b36, 2},
+ {0x1b37, 0x1b3a, 1},
+ {0x1b3c, 0x1b42, 6},
+ {0x1b6b, 0x1b73, 1},
+ {0x1b80, 0x1b81, 1},
+ {0x1ba2, 0x1ba5, 1},
+ {0x1ba8, 0x1ba9, 1},
+ {0x1bab, 0x1bad, 1},
+ {0x1be6, 0x1be8, 2},
+ {0x1be9, 0x1bed, 4},
+ {0x1bef, 0x1bf1, 1},
+ {0x1c2c, 0x1c33, 1},
+ {0x1c36, 0x1c37, 1},
+ {0x1cd0, 0x1cd2, 1},
+ {0x1cd4, 0x1ce0, 1},
+ {0x1ce2, 0x1ce8, 1},
+ {0x1ced, 0x1cf4, 7},
+ {0x1cf8, 0x1cf9, 1},
+ {0x1dc0, 0x1dff, 1},
+ {0x20d0, 0x20dc, 1},
+ {0x20e1, 0x20e5, 4},
+ {0x20e6, 0x20f0, 1},
+ {0x2cef, 0x2cf1, 1},
+ {0x2d7f, 0x2de0, 97},
+ {0x2de1, 0x2dff, 1},
+ {0x302a, 0x302d, 1},
+ {0x3099, 0x309a, 1},
+ {0xa66f, 0xa674, 5},
+ {0xa675, 0xa67d, 1},
+ {0xa69e, 0xa69f, 1},
+ {0xa6f0, 0xa6f1, 1},
+ {0xa802, 0xa806, 4},
+ {0xa80b, 0xa825, 26},
+ {0xa826, 0xa82c, 6},
+ {0xa8c4, 0xa8c5, 1},
+ {0xa8e0, 0xa8f1, 1},
+ {0xa8ff, 0xa926, 39},
+ {0xa927, 0xa92d, 1},
+ {0xa947, 0xa951, 1},
+ {0xa980, 0xa982, 1},
+ {0xa9b3, 0xa9b6, 3},
+ {0xa9b7, 0xa9b9, 1},
+ {0xa9bc, 0xa9bd, 1},
+ {0xa9e5, 0xaa29, 68},
+ {0xaa2a, 0xaa2e, 1},
+ {0xaa31, 0xaa32, 1},
+ {0xaa35, 0xaa36, 1},
+ {0xaa43, 0xaa4c, 9},
+ {0xaa7c, 0xaab0, 52},
+ {0xaab2, 0xaab4, 1},
+ {0xaab7, 0xaab8, 1},
+ {0xaabe, 0xaabf, 1},
+ {0xaac1, 0xaaec, 43},
+ {0xaaed, 0xaaf6, 9},
+ {0xabe5, 0xabe8, 3},
+ {0xabed, 0xfb1e, 20273},
+ {0xfe00, 0xfe0f, 1},
+ {0xfe20, 0xfe2f, 1},
+ },
+ R32: []Range32{
+ {0x101fd, 0x102e0, 227},
+ {0x10376, 0x1037a, 1},
+ {0x10a01, 0x10a03, 1},
+ {0x10a05, 0x10a06, 1},
+ {0x10a0c, 0x10a0f, 1},
+ {0x10a38, 0x10a3a, 1},
+ {0x10a3f, 0x10ae5, 166},
+ {0x10ae6, 0x10d24, 574},
+ {0x10d25, 0x10d27, 1},
+ {0x10eab, 0x10eac, 1},
+ {0x10efd, 0x10eff, 1},
+ {0x10f46, 0x10f50, 1},
+ {0x10f82, 0x10f85, 1},
+ {0x11001, 0x11038, 55},
+ {0x11039, 0x11046, 1},
+ {0x11070, 0x11073, 3},
+ {0x11074, 0x1107f, 11},
+ {0x11080, 0x11081, 1},
+ {0x110b3, 0x110b6, 1},
+ {0x110b9, 0x110ba, 1},
+ {0x110c2, 0x11100, 62},
+ {0x11101, 0x11102, 1},
+ {0x11127, 0x1112b, 1},
+ {0x1112d, 0x11134, 1},
+ {0x11173, 0x11180, 13},
+ {0x11181, 0x111b6, 53},
+ {0x111b7, 0x111be, 1},
+ {0x111c9, 0x111cc, 1},
+ {0x111cf, 0x1122f, 96},
+ {0x11230, 0x11231, 1},
+ {0x11234, 0x11236, 2},
+ {0x11237, 0x1123e, 7},
+ {0x11241, 0x112df, 158},
+ {0x112e3, 0x112ea, 1},
+ {0x11300, 0x11301, 1},
+ {0x1133b, 0x1133c, 1},
+ {0x11340, 0x11366, 38},
+ {0x11367, 0x1136c, 1},
+ {0x11370, 0x11374, 1},
+ {0x11438, 0x1143f, 1},
+ {0x11442, 0x11444, 1},
+ {0x11446, 0x1145e, 24},
+ {0x114b3, 0x114b8, 1},
+ {0x114ba, 0x114bf, 5},
+ {0x114c0, 0x114c2, 2},
+ {0x114c3, 0x115b2, 239},
+ {0x115b3, 0x115b5, 1},
+ {0x115bc, 0x115bd, 1},
+ {0x115bf, 0x115c0, 1},
+ {0x115dc, 0x115dd, 1},
+ {0x11633, 0x1163a, 1},
+ {0x1163d, 0x1163f, 2},
+ {0x11640, 0x116ab, 107},
+ {0x116ad, 0x116b0, 3},
+ {0x116b1, 0x116b5, 1},
+ {0x116b7, 0x1171d, 102},
+ {0x1171e, 0x1171f, 1},
+ {0x11722, 0x11725, 1},
+ {0x11727, 0x1172b, 1},
+ {0x1182f, 0x11837, 1},
+ {0x11839, 0x1183a, 1},
+ {0x1193b, 0x1193c, 1},
+ {0x1193e, 0x11943, 5},
+ {0x119d4, 0x119d7, 1},
+ {0x119da, 0x119db, 1},
+ {0x119e0, 0x11a01, 33},
+ {0x11a02, 0x11a0a, 1},
+ {0x11a33, 0x11a38, 1},
+ {0x11a3b, 0x11a3e, 1},
+ {0x11a47, 0x11a51, 10},
+ {0x11a52, 0x11a56, 1},
+ {0x11a59, 0x11a5b, 1},
+ {0x11a8a, 0x11a96, 1},
+ {0x11a98, 0x11a99, 1},
+ {0x11c30, 0x11c36, 1},
+ {0x11c38, 0x11c3d, 1},
+ {0x11c3f, 0x11c92, 83},
+ {0x11c93, 0x11ca7, 1},
+ {0x11caa, 0x11cb0, 1},
+ {0x11cb2, 0x11cb3, 1},
+ {0x11cb5, 0x11cb6, 1},
+ {0x11d31, 0x11d36, 1},
+ {0x11d3a, 0x11d3c, 2},
+ {0x11d3d, 0x11d3f, 2},
+ {0x11d40, 0x11d45, 1},
+ {0x11d47, 0x11d90, 73},
+ {0x11d91, 0x11d95, 4},
+ {0x11d97, 0x11ef3, 348},
+ {0x11ef4, 0x11f00, 12},
+ {0x11f01, 0x11f36, 53},
+ {0x11f37, 0x11f3a, 1},
+ {0x11f40, 0x11f42, 2},
+ {0x13440, 0x13447, 7},
+ {0x13448, 0x13455, 1},
+ {0x16af0, 0x16af4, 1},
+ {0x16b30, 0x16b36, 1},
+ {0x16f4f, 0x16f8f, 64},
+ {0x16f90, 0x16f92, 1},
+ {0x16fe4, 0x1bc9d, 19641},
+ {0x1bc9e, 0x1cf00, 4706},
+ {0x1cf01, 0x1cf2d, 1},
+ {0x1cf30, 0x1cf46, 1},
+ {0x1d167, 0x1d169, 1},
+ {0x1d17b, 0x1d182, 1},
+ {0x1d185, 0x1d18b, 1},
+ {0x1d1aa, 0x1d1ad, 1},
+ {0x1d242, 0x1d244, 1},
+ {0x1da00, 0x1da36, 1},
+ {0x1da3b, 0x1da6c, 1},
+ {0x1da75, 0x1da84, 15},
+ {0x1da9b, 0x1da9f, 1},
+ {0x1daa1, 0x1daaf, 1},
+ {0x1e000, 0x1e006, 1},
+ {0x1e008, 0x1e018, 1},
+ {0x1e01b, 0x1e021, 1},
+ {0x1e023, 0x1e024, 1},
+ {0x1e026, 0x1e02a, 1},
+ {0x1e08f, 0x1e130, 161},
+ {0x1e131, 0x1e136, 1},
+ {0x1e2ae, 0x1e2ec, 62},
+ {0x1e2ed, 0x1e2ef, 1},
+ {0x1e4ec, 0x1e4ef, 1},
+ {0x1e8d0, 0x1e8d6, 1},
+ {0x1e944, 0x1e94a, 1},
+ {0xe0100, 0xe01ef, 1},
+ },
+}
+
+var _N = &RangeTable{
+ R16: []Range16{
+ {0x0030, 0x0039, 1},
+ {0x00b2, 0x00b3, 1},
+ {0x00b9, 0x00bc, 3},
+ {0x00bd, 0x00be, 1},
+ {0x0660, 0x0669, 1},
+ {0x06f0, 0x06f9, 1},
+ {0x07c0, 0x07c9, 1},
+ {0x0966, 0x096f, 1},
+ {0x09e6, 0x09ef, 1},
+ {0x09f4, 0x09f9, 1},
+ {0x0a66, 0x0a6f, 1},
+ {0x0ae6, 0x0aef, 1},
+ {0x0b66, 0x0b6f, 1},
+ {0x0b72, 0x0b77, 1},
+ {0x0be6, 0x0bf2, 1},
+ {0x0c66, 0x0c6f, 1},
+ {0x0c78, 0x0c7e, 1},
+ {0x0ce6, 0x0cef, 1},
+ {0x0d58, 0x0d5e, 1},
+ {0x0d66, 0x0d78, 1},
+ {0x0de6, 0x0def, 1},
+ {0x0e50, 0x0e59, 1},
+ {0x0ed0, 0x0ed9, 1},
+ {0x0f20, 0x0f33, 1},
+ {0x1040, 0x1049, 1},
+ {0x1090, 0x1099, 1},
+ {0x1369, 0x137c, 1},
+ {0x16ee, 0x16f0, 1},
+ {0x17e0, 0x17e9, 1},
+ {0x17f0, 0x17f9, 1},
+ {0x1810, 0x1819, 1},
+ {0x1946, 0x194f, 1},
+ {0x19d0, 0x19da, 1},
+ {0x1a80, 0x1a89, 1},
+ {0x1a90, 0x1a99, 1},
+ {0x1b50, 0x1b59, 1},
+ {0x1bb0, 0x1bb9, 1},
+ {0x1c40, 0x1c49, 1},
+ {0x1c50, 0x1c59, 1},
+ {0x2070, 0x2074, 4},
+ {0x2075, 0x2079, 1},
+ {0x2080, 0x2089, 1},
+ {0x2150, 0x2182, 1},
+ {0x2185, 0x2189, 1},
+ {0x2460, 0x249b, 1},
+ {0x24ea, 0x24ff, 1},
+ {0x2776, 0x2793, 1},
+ {0x2cfd, 0x3007, 778},
+ {0x3021, 0x3029, 1},
+ {0x3038, 0x303a, 1},
+ {0x3192, 0x3195, 1},
+ {0x3220, 0x3229, 1},
+ {0x3248, 0x324f, 1},
+ {0x3251, 0x325f, 1},
+ {0x3280, 0x3289, 1},
+ {0x32b1, 0x32bf, 1},
+ {0xa620, 0xa629, 1},
+ {0xa6e6, 0xa6ef, 1},
+ {0xa830, 0xa835, 1},
+ {0xa8d0, 0xa8d9, 1},
+ {0xa900, 0xa909, 1},
+ {0xa9d0, 0xa9d9, 1},
+ {0xa9f0, 0xa9f9, 1},
+ {0xaa50, 0xaa59, 1},
+ {0xabf0, 0xabf9, 1},
+ {0xff10, 0xff19, 1},
+ },
+ R32: []Range32{
+ {0x10107, 0x10133, 1},
+ {0x10140, 0x10178, 1},
+ {0x1018a, 0x1018b, 1},
+ {0x102e1, 0x102fb, 1},
+ {0x10320, 0x10323, 1},
+ {0x10341, 0x1034a, 9},
+ {0x103d1, 0x103d5, 1},
+ {0x104a0, 0x104a9, 1},
+ {0x10858, 0x1085f, 1},
+ {0x10879, 0x1087f, 1},
+ {0x108a7, 0x108af, 1},
+ {0x108fb, 0x108ff, 1},
+ {0x10916, 0x1091b, 1},
+ {0x109bc, 0x109bd, 1},
+ {0x109c0, 0x109cf, 1},
+ {0x109d2, 0x109ff, 1},
+ {0x10a40, 0x10a48, 1},
+ {0x10a7d, 0x10a7e, 1},
+ {0x10a9d, 0x10a9f, 1},
+ {0x10aeb, 0x10aef, 1},
+ {0x10b58, 0x10b5f, 1},
+ {0x10b78, 0x10b7f, 1},
+ {0x10ba9, 0x10baf, 1},
+ {0x10cfa, 0x10cff, 1},
+ {0x10d30, 0x10d39, 1},
+ {0x10e60, 0x10e7e, 1},
+ {0x10f1d, 0x10f26, 1},
+ {0x10f51, 0x10f54, 1},
+ {0x10fc5, 0x10fcb, 1},
+ {0x11052, 0x1106f, 1},
+ {0x110f0, 0x110f9, 1},
+ {0x11136, 0x1113f, 1},
+ {0x111d0, 0x111d9, 1},
+ {0x111e1, 0x111f4, 1},
+ {0x112f0, 0x112f9, 1},
+ {0x11450, 0x11459, 1},
+ {0x114d0, 0x114d9, 1},
+ {0x11650, 0x11659, 1},
+ {0x116c0, 0x116c9, 1},
+ {0x11730, 0x1173b, 1},
+ {0x118e0, 0x118f2, 1},
+ {0x11950, 0x11959, 1},
+ {0x11c50, 0x11c6c, 1},
+ {0x11d50, 0x11d59, 1},
+ {0x11da0, 0x11da9, 1},
+ {0x11f50, 0x11f59, 1},
+ {0x11fc0, 0x11fd4, 1},
+ {0x12400, 0x1246e, 1},
+ {0x16a60, 0x16a69, 1},
+ {0x16ac0, 0x16ac9, 1},
+ {0x16b50, 0x16b59, 1},
+ {0x16b5b, 0x16b61, 1},
+ {0x16e80, 0x16e96, 1},
+ {0x1d2c0, 0x1d2d3, 1},
+ {0x1d2e0, 0x1d2f3, 1},
+ {0x1d360, 0x1d378, 1},
+ {0x1d7ce, 0x1d7ff, 1},
+ {0x1e140, 0x1e149, 1},
+ {0x1e2f0, 0x1e2f9, 1},
+ {0x1e4f0, 0x1e4f9, 1},
+ {0x1e8c7, 0x1e8cf, 1},
+ {0x1e950, 0x1e959, 1},
+ {0x1ec71, 0x1ecab, 1},
+ {0x1ecad, 0x1ecaf, 1},
+ {0x1ecb1, 0x1ecb4, 1},
+ {0x1ed01, 0x1ed2d, 1},
+ {0x1ed2f, 0x1ed3d, 1},
+ {0x1f100, 0x1f10c, 1},
+ {0x1fbf0, 0x1fbf9, 1},
+ },
+ LatinOffset: 4,
+}
+
+var _Nd = &RangeTable{
+ R16: []Range16{
+ {0x0030, 0x0039, 1},
+ {0x0660, 0x0669, 1},
+ {0x06f0, 0x06f9, 1},
+ {0x07c0, 0x07c9, 1},
+ {0x0966, 0x096f, 1},
+ {0x09e6, 0x09ef, 1},
+ {0x0a66, 0x0a6f, 1},
+ {0x0ae6, 0x0aef, 1},
+ {0x0b66, 0x0b6f, 1},
+ {0x0be6, 0x0bef, 1},
+ {0x0c66, 0x0c6f, 1},
+ {0x0ce6, 0x0cef, 1},
+ {0x0d66, 0x0d6f, 1},
+ {0x0de6, 0x0def, 1},
+ {0x0e50, 0x0e59, 1},
+ {0x0ed0, 0x0ed9, 1},
+ {0x0f20, 0x0f29, 1},
+ {0x1040, 0x1049, 1},
+ {0x1090, 0x1099, 1},
+ {0x17e0, 0x17e9, 1},
+ {0x1810, 0x1819, 1},
+ {0x1946, 0x194f, 1},
+ {0x19d0, 0x19d9, 1},
+ {0x1a80, 0x1a89, 1},
+ {0x1a90, 0x1a99, 1},
+ {0x1b50, 0x1b59, 1},
+ {0x1bb0, 0x1bb9, 1},
+ {0x1c40, 0x1c49, 1},
+ {0x1c50, 0x1c59, 1},
+ {0xa620, 0xa629, 1},
+ {0xa8d0, 0xa8d9, 1},
+ {0xa900, 0xa909, 1},
+ {0xa9d0, 0xa9d9, 1},
+ {0xa9f0, 0xa9f9, 1},
+ {0xaa50, 0xaa59, 1},
+ {0xabf0, 0xabf9, 1},
+ {0xff10, 0xff19, 1},
+ },
+ R32: []Range32{
+ {0x104a0, 0x104a9, 1},
+ {0x10d30, 0x10d39, 1},
+ {0x11066, 0x1106f, 1},
+ {0x110f0, 0x110f9, 1},
+ {0x11136, 0x1113f, 1},
+ {0x111d0, 0x111d9, 1},
+ {0x112f0, 0x112f9, 1},
+ {0x11450, 0x11459, 1},
+ {0x114d0, 0x114d9, 1},
+ {0x11650, 0x11659, 1},
+ {0x116c0, 0x116c9, 1},
+ {0x11730, 0x11739, 1},
+ {0x118e0, 0x118e9, 1},
+ {0x11950, 0x11959, 1},
+ {0x11c50, 0x11c59, 1},
+ {0x11d50, 0x11d59, 1},
+ {0x11da0, 0x11da9, 1},
+ {0x11f50, 0x11f59, 1},
+ {0x16a60, 0x16a69, 1},
+ {0x16ac0, 0x16ac9, 1},
+ {0x16b50, 0x16b59, 1},
+ {0x1d7ce, 0x1d7ff, 1},
+ {0x1e140, 0x1e149, 1},
+ {0x1e2f0, 0x1e2f9, 1},
+ {0x1e4f0, 0x1e4f9, 1},
+ {0x1e950, 0x1e959, 1},
+ {0x1fbf0, 0x1fbf9, 1},
+ },
+ LatinOffset: 1,
+}
+
+var _Nl = &RangeTable{
+ R16: []Range16{
+ {0x16ee, 0x16f0, 1},
+ {0x2160, 0x2182, 1},
+ {0x2185, 0x2188, 1},
+ {0x3007, 0x3021, 26},
+ {0x3022, 0x3029, 1},
+ {0x3038, 0x303a, 1},
+ {0xa6e6, 0xa6ef, 1},
+ },
+ R32: []Range32{
+ {0x10140, 0x10174, 1},
+ {0x10341, 0x1034a, 9},
+ {0x103d1, 0x103d5, 1},
+ {0x12400, 0x1246e, 1},
+ },
+}
+
+var _No = &RangeTable{
+ R16: []Range16{
+ {0x00b2, 0x00b3, 1},
+ {0x00b9, 0x00bc, 3},
+ {0x00bd, 0x00be, 1},
+ {0x09f4, 0x09f9, 1},
+ {0x0b72, 0x0b77, 1},
+ {0x0bf0, 0x0bf2, 1},
+ {0x0c78, 0x0c7e, 1},
+ {0x0d58, 0x0d5e, 1},
+ {0x0d70, 0x0d78, 1},
+ {0x0f2a, 0x0f33, 1},
+ {0x1369, 0x137c, 1},
+ {0x17f0, 0x17f9, 1},
+ {0x19da, 0x2070, 1686},
+ {0x2074, 0x2079, 1},
+ {0x2080, 0x2089, 1},
+ {0x2150, 0x215f, 1},
+ {0x2189, 0x2460, 727},
+ {0x2461, 0x249b, 1},
+ {0x24ea, 0x24ff, 1},
+ {0x2776, 0x2793, 1},
+ {0x2cfd, 0x3192, 1173},
+ {0x3193, 0x3195, 1},
+ {0x3220, 0x3229, 1},
+ {0x3248, 0x324f, 1},
+ {0x3251, 0x325f, 1},
+ {0x3280, 0x3289, 1},
+ {0x32b1, 0x32bf, 1},
+ {0xa830, 0xa835, 1},
+ },
+ R32: []Range32{
+ {0x10107, 0x10133, 1},
+ {0x10175, 0x10178, 1},
+ {0x1018a, 0x1018b, 1},
+ {0x102e1, 0x102fb, 1},
+ {0x10320, 0x10323, 1},
+ {0x10858, 0x1085f, 1},
+ {0x10879, 0x1087f, 1},
+ {0x108a7, 0x108af, 1},
+ {0x108fb, 0x108ff, 1},
+ {0x10916, 0x1091b, 1},
+ {0x109bc, 0x109bd, 1},
+ {0x109c0, 0x109cf, 1},
+ {0x109d2, 0x109ff, 1},
+ {0x10a40, 0x10a48, 1},
+ {0x10a7d, 0x10a7e, 1},
+ {0x10a9d, 0x10a9f, 1},
+ {0x10aeb, 0x10aef, 1},
+ {0x10b58, 0x10b5f, 1},
+ {0x10b78, 0x10b7f, 1},
+ {0x10ba9, 0x10baf, 1},
+ {0x10cfa, 0x10cff, 1},
+ {0x10e60, 0x10e7e, 1},
+ {0x10f1d, 0x10f26, 1},
+ {0x10f51, 0x10f54, 1},
+ {0x10fc5, 0x10fcb, 1},
+ {0x11052, 0x11065, 1},
+ {0x111e1, 0x111f4, 1},
+ {0x1173a, 0x1173b, 1},
+ {0x118ea, 0x118f2, 1},
+ {0x11c5a, 0x11c6c, 1},
+ {0x11fc0, 0x11fd4, 1},
+ {0x16b5b, 0x16b61, 1},
+ {0x16e80, 0x16e96, 1},
+ {0x1d2c0, 0x1d2d3, 1},
+ {0x1d2e0, 0x1d2f3, 1},
+ {0x1d360, 0x1d378, 1},
+ {0x1e8c7, 0x1e8cf, 1},
+ {0x1ec71, 0x1ecab, 1},
+ {0x1ecad, 0x1ecaf, 1},
+ {0x1ecb1, 0x1ecb4, 1},
+ {0x1ed01, 0x1ed2d, 1},
+ {0x1ed2f, 0x1ed3d, 1},
+ {0x1f100, 0x1f10c, 1},
+ },
+ LatinOffset: 3,
+}
+
+var _P = &RangeTable{
+ R16: []Range16{
+ {0x0021, 0x0023, 1},
+ {0x0025, 0x002a, 1},
+ {0x002c, 0x002f, 1},
+ {0x003a, 0x003b, 1},
+ {0x003f, 0x0040, 1},
+ {0x005b, 0x005d, 1},
+ {0x005f, 0x007b, 28},
+ {0x007d, 0x00a1, 36},
+ {0x00a7, 0x00ab, 4},
+ {0x00b6, 0x00b7, 1},
+ {0x00bb, 0x00bf, 4},
+ {0x037e, 0x0387, 9},
+ {0x055a, 0x055f, 1},
+ {0x0589, 0x058a, 1},
+ {0x05be, 0x05c0, 2},
+ {0x05c3, 0x05c6, 3},
+ {0x05f3, 0x05f4, 1},
+ {0x0609, 0x060a, 1},
+ {0x060c, 0x060d, 1},
+ {0x061b, 0x061d, 2},
+ {0x061e, 0x061f, 1},
+ {0x066a, 0x066d, 1},
+ {0x06d4, 0x0700, 44},
+ {0x0701, 0x070d, 1},
+ {0x07f7, 0x07f9, 1},
+ {0x0830, 0x083e, 1},
+ {0x085e, 0x0964, 262},
+ {0x0965, 0x0970, 11},
+ {0x09fd, 0x0a76, 121},
+ {0x0af0, 0x0c77, 391},
+ {0x0c84, 0x0df4, 368},
+ {0x0e4f, 0x0e5a, 11},
+ {0x0e5b, 0x0f04, 169},
+ {0x0f05, 0x0f12, 1},
+ {0x0f14, 0x0f3a, 38},
+ {0x0f3b, 0x0f3d, 1},
+ {0x0f85, 0x0fd0, 75},
+ {0x0fd1, 0x0fd4, 1},
+ {0x0fd9, 0x0fda, 1},
+ {0x104a, 0x104f, 1},
+ {0x10fb, 0x1360, 613},
+ {0x1361, 0x1368, 1},
+ {0x1400, 0x166e, 622},
+ {0x169b, 0x169c, 1},
+ {0x16eb, 0x16ed, 1},
+ {0x1735, 0x1736, 1},
+ {0x17d4, 0x17d6, 1},
+ {0x17d8, 0x17da, 1},
+ {0x1800, 0x180a, 1},
+ {0x1944, 0x1945, 1},
+ {0x1a1e, 0x1a1f, 1},
+ {0x1aa0, 0x1aa6, 1},
+ {0x1aa8, 0x1aad, 1},
+ {0x1b5a, 0x1b60, 1},
+ {0x1b7d, 0x1b7e, 1},
+ {0x1bfc, 0x1bff, 1},
+ {0x1c3b, 0x1c3f, 1},
+ {0x1c7e, 0x1c7f, 1},
+ {0x1cc0, 0x1cc7, 1},
+ {0x1cd3, 0x2010, 829},
+ {0x2011, 0x2027, 1},
+ {0x2030, 0x2043, 1},
+ {0x2045, 0x2051, 1},
+ {0x2053, 0x205e, 1},
+ {0x207d, 0x207e, 1},
+ {0x208d, 0x208e, 1},
+ {0x2308, 0x230b, 1},
+ {0x2329, 0x232a, 1},
+ {0x2768, 0x2775, 1},
+ {0x27c5, 0x27c6, 1},
+ {0x27e6, 0x27ef, 1},
+ {0x2983, 0x2998, 1},
+ {0x29d8, 0x29db, 1},
+ {0x29fc, 0x29fd, 1},
+ {0x2cf9, 0x2cfc, 1},
+ {0x2cfe, 0x2cff, 1},
+ {0x2d70, 0x2e00, 144},
+ {0x2e01, 0x2e2e, 1},
+ {0x2e30, 0x2e4f, 1},
+ {0x2e52, 0x2e5d, 1},
+ {0x3001, 0x3003, 1},
+ {0x3008, 0x3011, 1},
+ {0x3014, 0x301f, 1},
+ {0x3030, 0x303d, 13},
+ {0x30a0, 0x30fb, 91},
+ {0xa4fe, 0xa4ff, 1},
+ {0xa60d, 0xa60f, 1},
+ {0xa673, 0xa67e, 11},
+ {0xa6f2, 0xa6f7, 1},
+ {0xa874, 0xa877, 1},
+ {0xa8ce, 0xa8cf, 1},
+ {0xa8f8, 0xa8fa, 1},
+ {0xa8fc, 0xa92e, 50},
+ {0xa92f, 0xa95f, 48},
+ {0xa9c1, 0xa9cd, 1},
+ {0xa9de, 0xa9df, 1},
+ {0xaa5c, 0xaa5f, 1},
+ {0xaade, 0xaadf, 1},
+ {0xaaf0, 0xaaf1, 1},
+ {0xabeb, 0xfd3e, 20819},
+ {0xfd3f, 0xfe10, 209},
+ {0xfe11, 0xfe19, 1},
+ {0xfe30, 0xfe52, 1},
+ {0xfe54, 0xfe61, 1},
+ {0xfe63, 0xfe68, 5},
+ {0xfe6a, 0xfe6b, 1},
+ {0xff01, 0xff03, 1},
+ {0xff05, 0xff0a, 1},
+ {0xff0c, 0xff0f, 1},
+ {0xff1a, 0xff1b, 1},
+ {0xff1f, 0xff20, 1},
+ {0xff3b, 0xff3d, 1},
+ {0xff3f, 0xff5b, 28},
+ {0xff5d, 0xff5f, 2},
+ {0xff60, 0xff65, 1},
+ },
+ R32: []Range32{
+ {0x10100, 0x10102, 1},
+ {0x1039f, 0x103d0, 49},
+ {0x1056f, 0x10857, 744},
+ {0x1091f, 0x1093f, 32},
+ {0x10a50, 0x10a58, 1},
+ {0x10a7f, 0x10af0, 113},
+ {0x10af1, 0x10af6, 1},
+ {0x10b39, 0x10b3f, 1},
+ {0x10b99, 0x10b9c, 1},
+ {0x10ead, 0x10f55, 168},
+ {0x10f56, 0x10f59, 1},
+ {0x10f86, 0x10f89, 1},
+ {0x11047, 0x1104d, 1},
+ {0x110bb, 0x110bc, 1},
+ {0x110be, 0x110c1, 1},
+ {0x11140, 0x11143, 1},
+ {0x11174, 0x11175, 1},
+ {0x111c5, 0x111c8, 1},
+ {0x111cd, 0x111db, 14},
+ {0x111dd, 0x111df, 1},
+ {0x11238, 0x1123d, 1},
+ {0x112a9, 0x1144b, 418},
+ {0x1144c, 0x1144f, 1},
+ {0x1145a, 0x1145b, 1},
+ {0x1145d, 0x114c6, 105},
+ {0x115c1, 0x115d7, 1},
+ {0x11641, 0x11643, 1},
+ {0x11660, 0x1166c, 1},
+ {0x116b9, 0x1173c, 131},
+ {0x1173d, 0x1173e, 1},
+ {0x1183b, 0x11944, 265},
+ {0x11945, 0x11946, 1},
+ {0x119e2, 0x11a3f, 93},
+ {0x11a40, 0x11a46, 1},
+ {0x11a9a, 0x11a9c, 1},
+ {0x11a9e, 0x11aa2, 1},
+ {0x11b00, 0x11b09, 1},
+ {0x11c41, 0x11c45, 1},
+ {0x11c70, 0x11c71, 1},
+ {0x11ef7, 0x11ef8, 1},
+ {0x11f43, 0x11f4f, 1},
+ {0x11fff, 0x12470, 1137},
+ {0x12471, 0x12474, 1},
+ {0x12ff1, 0x12ff2, 1},
+ {0x16a6e, 0x16a6f, 1},
+ {0x16af5, 0x16b37, 66},
+ {0x16b38, 0x16b3b, 1},
+ {0x16b44, 0x16e97, 851},
+ {0x16e98, 0x16e9a, 1},
+ {0x16fe2, 0x1bc9f, 19645},
+ {0x1da87, 0x1da8b, 1},
+ {0x1e95e, 0x1e95f, 1},
+ },
+ LatinOffset: 11,
+}
+
+var _Pc = &RangeTable{
+ R16: []Range16{
+ {0x005f, 0x203f, 8160},
+ {0x2040, 0x2054, 20},
+ {0xfe33, 0xfe34, 1},
+ {0xfe4d, 0xfe4f, 1},
+ {0xff3f, 0xff3f, 1},
+ },
+}
+
+var _Pd = &RangeTable{
+ R16: []Range16{
+ {0x002d, 0x058a, 1373},
+ {0x05be, 0x1400, 3650},
+ {0x1806, 0x2010, 2058},
+ {0x2011, 0x2015, 1},
+ {0x2e17, 0x2e1a, 3},
+ {0x2e3a, 0x2e3b, 1},
+ {0x2e40, 0x2e5d, 29},
+ {0x301c, 0x3030, 20},
+ {0x30a0, 0xfe31, 52625},
+ {0xfe32, 0xfe58, 38},
+ {0xfe63, 0xff0d, 170},
+ },
+ R32: []Range32{
+ {0x10ead, 0x10ead, 1},
+ },
+}
+
+var _Pe = &RangeTable{
+ R16: []Range16{
+ {0x0029, 0x005d, 52},
+ {0x007d, 0x0f3b, 3774},
+ {0x0f3d, 0x169c, 1887},
+ {0x2046, 0x207e, 56},
+ {0x208e, 0x2309, 635},
+ {0x230b, 0x232a, 31},
+ {0x2769, 0x2775, 2},
+ {0x27c6, 0x27e7, 33},
+ {0x27e9, 0x27ef, 2},
+ {0x2984, 0x2998, 2},
+ {0x29d9, 0x29db, 2},
+ {0x29fd, 0x2e23, 1062},
+ {0x2e25, 0x2e29, 2},
+ {0x2e56, 0x2e5c, 2},
+ {0x3009, 0x3011, 2},
+ {0x3015, 0x301b, 2},
+ {0x301e, 0x301f, 1},
+ {0xfd3e, 0xfe18, 218},
+ {0xfe36, 0xfe44, 2},
+ {0xfe48, 0xfe5a, 18},
+ {0xfe5c, 0xfe5e, 2},
+ {0xff09, 0xff3d, 52},
+ {0xff5d, 0xff63, 3},
+ },
+ LatinOffset: 1,
+}
+
+var _Pf = &RangeTable{
+ R16: []Range16{
+ {0x00bb, 0x2019, 8030},
+ {0x201d, 0x203a, 29},
+ {0x2e03, 0x2e05, 2},
+ {0x2e0a, 0x2e0d, 3},
+ {0x2e1d, 0x2e21, 4},
+ },
+}
+
+var _Pi = &RangeTable{
+ R16: []Range16{
+ {0x00ab, 0x2018, 8045},
+ {0x201b, 0x201c, 1},
+ {0x201f, 0x2039, 26},
+ {0x2e02, 0x2e04, 2},
+ {0x2e09, 0x2e0c, 3},
+ {0x2e1c, 0x2e20, 4},
+ },
+}
+
+var _Po = &RangeTable{
+ R16: []Range16{
+ {0x0021, 0x0023, 1},
+ {0x0025, 0x0027, 1},
+ {0x002a, 0x002e, 2},
+ {0x002f, 0x003a, 11},
+ {0x003b, 0x003f, 4},
+ {0x0040, 0x005c, 28},
+ {0x00a1, 0x00a7, 6},
+ {0x00b6, 0x00b7, 1},
+ {0x00bf, 0x037e, 703},
+ {0x0387, 0x055a, 467},
+ {0x055b, 0x055f, 1},
+ {0x0589, 0x05c0, 55},
+ {0x05c3, 0x05c6, 3},
+ {0x05f3, 0x05f4, 1},
+ {0x0609, 0x060a, 1},
+ {0x060c, 0x060d, 1},
+ {0x061b, 0x061d, 2},
+ {0x061e, 0x061f, 1},
+ {0x066a, 0x066d, 1},
+ {0x06d4, 0x0700, 44},
+ {0x0701, 0x070d, 1},
+ {0x07f7, 0x07f9, 1},
+ {0x0830, 0x083e, 1},
+ {0x085e, 0x0964, 262},
+ {0x0965, 0x0970, 11},
+ {0x09fd, 0x0a76, 121},
+ {0x0af0, 0x0c77, 391},
+ {0x0c84, 0x0df4, 368},
+ {0x0e4f, 0x0e5a, 11},
+ {0x0e5b, 0x0f04, 169},
+ {0x0f05, 0x0f12, 1},
+ {0x0f14, 0x0f85, 113},
+ {0x0fd0, 0x0fd4, 1},
+ {0x0fd9, 0x0fda, 1},
+ {0x104a, 0x104f, 1},
+ {0x10fb, 0x1360, 613},
+ {0x1361, 0x1368, 1},
+ {0x166e, 0x16eb, 125},
+ {0x16ec, 0x16ed, 1},
+ {0x1735, 0x1736, 1},
+ {0x17d4, 0x17d6, 1},
+ {0x17d8, 0x17da, 1},
+ {0x1800, 0x1805, 1},
+ {0x1807, 0x180a, 1},
+ {0x1944, 0x1945, 1},
+ {0x1a1e, 0x1a1f, 1},
+ {0x1aa0, 0x1aa6, 1},
+ {0x1aa8, 0x1aad, 1},
+ {0x1b5a, 0x1b60, 1},
+ {0x1b7d, 0x1b7e, 1},
+ {0x1bfc, 0x1bff, 1},
+ {0x1c3b, 0x1c3f, 1},
+ {0x1c7e, 0x1c7f, 1},
+ {0x1cc0, 0x1cc7, 1},
+ {0x1cd3, 0x2016, 835},
+ {0x2017, 0x2020, 9},
+ {0x2021, 0x2027, 1},
+ {0x2030, 0x2038, 1},
+ {0x203b, 0x203e, 1},
+ {0x2041, 0x2043, 1},
+ {0x2047, 0x2051, 1},
+ {0x2053, 0x2055, 2},
+ {0x2056, 0x205e, 1},
+ {0x2cf9, 0x2cfc, 1},
+ {0x2cfe, 0x2cff, 1},
+ {0x2d70, 0x2e00, 144},
+ {0x2e01, 0x2e06, 5},
+ {0x2e07, 0x2e08, 1},
+ {0x2e0b, 0x2e0e, 3},
+ {0x2e0f, 0x2e16, 1},
+ {0x2e18, 0x2e19, 1},
+ {0x2e1b, 0x2e1e, 3},
+ {0x2e1f, 0x2e2a, 11},
+ {0x2e2b, 0x2e2e, 1},
+ {0x2e30, 0x2e39, 1},
+ {0x2e3c, 0x2e3f, 1},
+ {0x2e41, 0x2e43, 2},
+ {0x2e44, 0x2e4f, 1},
+ {0x2e52, 0x2e54, 1},
+ {0x3001, 0x3003, 1},
+ {0x303d, 0x30fb, 190},
+ {0xa4fe, 0xa4ff, 1},
+ {0xa60d, 0xa60f, 1},
+ {0xa673, 0xa67e, 11},
+ {0xa6f2, 0xa6f7, 1},
+ {0xa874, 0xa877, 1},
+ {0xa8ce, 0xa8cf, 1},
+ {0xa8f8, 0xa8fa, 1},
+ {0xa8fc, 0xa92e, 50},
+ {0xa92f, 0xa95f, 48},
+ {0xa9c1, 0xa9cd, 1},
+ {0xa9de, 0xa9df, 1},
+ {0xaa5c, 0xaa5f, 1},
+ {0xaade, 0xaadf, 1},
+ {0xaaf0, 0xaaf1, 1},
+ {0xabeb, 0xfe10, 21029},
+ {0xfe11, 0xfe16, 1},
+ {0xfe19, 0xfe30, 23},
+ {0xfe45, 0xfe46, 1},
+ {0xfe49, 0xfe4c, 1},
+ {0xfe50, 0xfe52, 1},
+ {0xfe54, 0xfe57, 1},
+ {0xfe5f, 0xfe61, 1},
+ {0xfe68, 0xfe6a, 2},
+ {0xfe6b, 0xff01, 150},
+ {0xff02, 0xff03, 1},
+ {0xff05, 0xff07, 1},
+ {0xff0a, 0xff0e, 2},
+ {0xff0f, 0xff1a, 11},
+ {0xff1b, 0xff1f, 4},
+ {0xff20, 0xff3c, 28},
+ {0xff61, 0xff64, 3},
+ {0xff65, 0xff65, 1},
+ },
+ R32: []Range32{
+ {0x10100, 0x10102, 1},
+ {0x1039f, 0x103d0, 49},
+ {0x1056f, 0x10857, 744},
+ {0x1091f, 0x1093f, 32},
+ {0x10a50, 0x10a58, 1},
+ {0x10a7f, 0x10af0, 113},
+ {0x10af1, 0x10af6, 1},
+ {0x10b39, 0x10b3f, 1},
+ {0x10b99, 0x10b9c, 1},
+ {0x10f55, 0x10f59, 1},
+ {0x10f86, 0x10f89, 1},
+ {0x11047, 0x1104d, 1},
+ {0x110bb, 0x110bc, 1},
+ {0x110be, 0x110c1, 1},
+ {0x11140, 0x11143, 1},
+ {0x11174, 0x11175, 1},
+ {0x111c5, 0x111c8, 1},
+ {0x111cd, 0x111db, 14},
+ {0x111dd, 0x111df, 1},
+ {0x11238, 0x1123d, 1},
+ {0x112a9, 0x1144b, 418},
+ {0x1144c, 0x1144f, 1},
+ {0x1145a, 0x1145b, 1},
+ {0x1145d, 0x114c6, 105},
+ {0x115c1, 0x115d7, 1},
+ {0x11641, 0x11643, 1},
+ {0x11660, 0x1166c, 1},
+ {0x116b9, 0x1173c, 131},
+ {0x1173d, 0x1173e, 1},
+ {0x1183b, 0x11944, 265},
+ {0x11945, 0x11946, 1},
+ {0x119e2, 0x11a3f, 93},
+ {0x11a40, 0x11a46, 1},
+ {0x11a9a, 0x11a9c, 1},
+ {0x11a9e, 0x11aa2, 1},
+ {0x11b00, 0x11b09, 1},
+ {0x11c41, 0x11c45, 1},
+ {0x11c70, 0x11c71, 1},
+ {0x11ef7, 0x11ef8, 1},
+ {0x11f43, 0x11f4f, 1},
+ {0x11fff, 0x12470, 1137},
+ {0x12471, 0x12474, 1},
+ {0x12ff1, 0x12ff2, 1},
+ {0x16a6e, 0x16a6f, 1},
+ {0x16af5, 0x16b37, 66},
+ {0x16b38, 0x16b3b, 1},
+ {0x16b44, 0x16e97, 851},
+ {0x16e98, 0x16e9a, 1},
+ {0x16fe2, 0x1bc9f, 19645},
+ {0x1da87, 0x1da8b, 1},
+ {0x1e95e, 0x1e95f, 1},
+ },
+ LatinOffset: 8,
+}
+
+var _Ps = &RangeTable{
+ R16: []Range16{
+ {0x0028, 0x005b, 51},
+ {0x007b, 0x0f3a, 3775},
+ {0x0f3c, 0x169b, 1887},
+ {0x201a, 0x201e, 4},
+ {0x2045, 0x207d, 56},
+ {0x208d, 0x2308, 635},
+ {0x230a, 0x2329, 31},
+ {0x2768, 0x2774, 2},
+ {0x27c5, 0x27e6, 33},
+ {0x27e8, 0x27ee, 2},
+ {0x2983, 0x2997, 2},
+ {0x29d8, 0x29da, 2},
+ {0x29fc, 0x2e22, 1062},
+ {0x2e24, 0x2e28, 2},
+ {0x2e42, 0x2e55, 19},
+ {0x2e57, 0x2e5b, 2},
+ {0x3008, 0x3010, 2},
+ {0x3014, 0x301a, 2},
+ {0x301d, 0xfd3f, 52514},
+ {0xfe17, 0xfe35, 30},
+ {0xfe37, 0xfe43, 2},
+ {0xfe47, 0xfe59, 18},
+ {0xfe5b, 0xfe5d, 2},
+ {0xff08, 0xff3b, 51},
+ {0xff5b, 0xff5f, 4},
+ {0xff62, 0xff62, 1},
+ },
+ LatinOffset: 1,
+}
+
+var _S = &RangeTable{
+ R16: []Range16{
+ {0x0024, 0x002b, 7},
+ {0x003c, 0x003e, 1},
+ {0x005e, 0x0060, 2},
+ {0x007c, 0x007e, 2},
+ {0x00a2, 0x00a6, 1},
+ {0x00a8, 0x00a9, 1},
+ {0x00ac, 0x00ae, 2},
+ {0x00af, 0x00b1, 1},
+ {0x00b4, 0x00b8, 4},
+ {0x00d7, 0x00f7, 32},
+ {0x02c2, 0x02c5, 1},
+ {0x02d2, 0x02df, 1},
+ {0x02e5, 0x02eb, 1},
+ {0x02ed, 0x02ef, 2},
+ {0x02f0, 0x02ff, 1},
+ {0x0375, 0x0384, 15},
+ {0x0385, 0x03f6, 113},
+ {0x0482, 0x058d, 267},
+ {0x058e, 0x058f, 1},
+ {0x0606, 0x0608, 1},
+ {0x060b, 0x060e, 3},
+ {0x060f, 0x06de, 207},
+ {0x06e9, 0x06fd, 20},
+ {0x06fe, 0x07f6, 248},
+ {0x07fe, 0x07ff, 1},
+ {0x0888, 0x09f2, 362},
+ {0x09f3, 0x09fa, 7},
+ {0x09fb, 0x0af1, 246},
+ {0x0b70, 0x0bf3, 131},
+ {0x0bf4, 0x0bfa, 1},
+ {0x0c7f, 0x0d4f, 208},
+ {0x0d79, 0x0e3f, 198},
+ {0x0f01, 0x0f03, 1},
+ {0x0f13, 0x0f15, 2},
+ {0x0f16, 0x0f17, 1},
+ {0x0f1a, 0x0f1f, 1},
+ {0x0f34, 0x0f38, 2},
+ {0x0fbe, 0x0fc5, 1},
+ {0x0fc7, 0x0fcc, 1},
+ {0x0fce, 0x0fcf, 1},
+ {0x0fd5, 0x0fd8, 1},
+ {0x109e, 0x109f, 1},
+ {0x1390, 0x1399, 1},
+ {0x166d, 0x17db, 366},
+ {0x1940, 0x19de, 158},
+ {0x19df, 0x19ff, 1},
+ {0x1b61, 0x1b6a, 1},
+ {0x1b74, 0x1b7c, 1},
+ {0x1fbd, 0x1fbf, 2},
+ {0x1fc0, 0x1fc1, 1},
+ {0x1fcd, 0x1fcf, 1},
+ {0x1fdd, 0x1fdf, 1},
+ {0x1fed, 0x1fef, 1},
+ {0x1ffd, 0x1ffe, 1},
+ {0x2044, 0x2052, 14},
+ {0x207a, 0x207c, 1},
+ {0x208a, 0x208c, 1},
+ {0x20a0, 0x20c0, 1},
+ {0x2100, 0x2101, 1},
+ {0x2103, 0x2106, 1},
+ {0x2108, 0x2109, 1},
+ {0x2114, 0x2116, 2},
+ {0x2117, 0x2118, 1},
+ {0x211e, 0x2123, 1},
+ {0x2125, 0x2129, 2},
+ {0x212e, 0x213a, 12},
+ {0x213b, 0x2140, 5},
+ {0x2141, 0x2144, 1},
+ {0x214a, 0x214d, 1},
+ {0x214f, 0x218a, 59},
+ {0x218b, 0x2190, 5},
+ {0x2191, 0x2307, 1},
+ {0x230c, 0x2328, 1},
+ {0x232b, 0x2426, 1},
+ {0x2440, 0x244a, 1},
+ {0x249c, 0x24e9, 1},
+ {0x2500, 0x2767, 1},
+ {0x2794, 0x27c4, 1},
+ {0x27c7, 0x27e5, 1},
+ {0x27f0, 0x2982, 1},
+ {0x2999, 0x29d7, 1},
+ {0x29dc, 0x29fb, 1},
+ {0x29fe, 0x2b73, 1},
+ {0x2b76, 0x2b95, 1},
+ {0x2b97, 0x2bff, 1},
+ {0x2ce5, 0x2cea, 1},
+ {0x2e50, 0x2e51, 1},
+ {0x2e80, 0x2e99, 1},
+ {0x2e9b, 0x2ef3, 1},
+ {0x2f00, 0x2fd5, 1},
+ {0x2ff0, 0x2ffb, 1},
+ {0x3004, 0x3012, 14},
+ {0x3013, 0x3020, 13},
+ {0x3036, 0x3037, 1},
+ {0x303e, 0x303f, 1},
+ {0x309b, 0x309c, 1},
+ {0x3190, 0x3191, 1},
+ {0x3196, 0x319f, 1},
+ {0x31c0, 0x31e3, 1},
+ {0x3200, 0x321e, 1},
+ {0x322a, 0x3247, 1},
+ {0x3250, 0x3260, 16},
+ {0x3261, 0x327f, 1},
+ {0x328a, 0x32b0, 1},
+ {0x32c0, 0x33ff, 1},
+ {0x4dc0, 0x4dff, 1},
+ {0xa490, 0xa4c6, 1},
+ {0xa700, 0xa716, 1},
+ {0xa720, 0xa721, 1},
+ {0xa789, 0xa78a, 1},
+ {0xa828, 0xa82b, 1},
+ {0xa836, 0xa839, 1},
+ {0xaa77, 0xaa79, 1},
+ {0xab5b, 0xab6a, 15},
+ {0xab6b, 0xfb29, 20414},
+ {0xfbb2, 0xfbc2, 1},
+ {0xfd40, 0xfd4f, 1},
+ {0xfdcf, 0xfdfc, 45},
+ {0xfdfd, 0xfdff, 1},
+ {0xfe62, 0xfe64, 2},
+ {0xfe65, 0xfe66, 1},
+ {0xfe69, 0xff04, 155},
+ {0xff0b, 0xff1c, 17},
+ {0xff1d, 0xff1e, 1},
+ {0xff3e, 0xff40, 2},
+ {0xff5c, 0xff5e, 2},
+ {0xffe0, 0xffe6, 1},
+ {0xffe8, 0xffee, 1},
+ {0xfffc, 0xfffd, 1},
+ },
+ R32: []Range32{
+ {0x10137, 0x1013f, 1},
+ {0x10179, 0x10189, 1},
+ {0x1018c, 0x1018e, 1},
+ {0x10190, 0x1019c, 1},
+ {0x101a0, 0x101d0, 48},
+ {0x101d1, 0x101fc, 1},
+ {0x10877, 0x10878, 1},
+ {0x10ac8, 0x1173f, 3191},
+ {0x11fd5, 0x11ff1, 1},
+ {0x16b3c, 0x16b3f, 1},
+ {0x16b45, 0x1bc9c, 20823},
+ {0x1cf50, 0x1cfc3, 1},
+ {0x1d000, 0x1d0f5, 1},
+ {0x1d100, 0x1d126, 1},
+ {0x1d129, 0x1d164, 1},
+ {0x1d16a, 0x1d16c, 1},
+ {0x1d183, 0x1d184, 1},
+ {0x1d18c, 0x1d1a9, 1},
+ {0x1d1ae, 0x1d1ea, 1},
+ {0x1d200, 0x1d241, 1},
+ {0x1d245, 0x1d300, 187},
+ {0x1d301, 0x1d356, 1},
+ {0x1d6c1, 0x1d6db, 26},
+ {0x1d6fb, 0x1d715, 26},
+ {0x1d735, 0x1d74f, 26},
+ {0x1d76f, 0x1d789, 26},
+ {0x1d7a9, 0x1d7c3, 26},
+ {0x1d800, 0x1d9ff, 1},
+ {0x1da37, 0x1da3a, 1},
+ {0x1da6d, 0x1da74, 1},
+ {0x1da76, 0x1da83, 1},
+ {0x1da85, 0x1da86, 1},
+ {0x1e14f, 0x1e2ff, 432},
+ {0x1ecac, 0x1ecb0, 4},
+ {0x1ed2e, 0x1eef0, 450},
+ {0x1eef1, 0x1f000, 271},
+ {0x1f001, 0x1f02b, 1},
+ {0x1f030, 0x1f093, 1},
+ {0x1f0a0, 0x1f0ae, 1},
+ {0x1f0b1, 0x1f0bf, 1},
+ {0x1f0c1, 0x1f0cf, 1},
+ {0x1f0d1, 0x1f0f5, 1},
+ {0x1f10d, 0x1f1ad, 1},
+ {0x1f1e6, 0x1f202, 1},
+ {0x1f210, 0x1f23b, 1},
+ {0x1f240, 0x1f248, 1},
+ {0x1f250, 0x1f251, 1},
+ {0x1f260, 0x1f265, 1},
+ {0x1f300, 0x1f6d7, 1},
+ {0x1f6dc, 0x1f6ec, 1},
+ {0x1f6f0, 0x1f6fc, 1},
+ {0x1f700, 0x1f776, 1},
+ {0x1f77b, 0x1f7d9, 1},
+ {0x1f7e0, 0x1f7eb, 1},
+ {0x1f7f0, 0x1f800, 16},
+ {0x1f801, 0x1f80b, 1},
+ {0x1f810, 0x1f847, 1},
+ {0x1f850, 0x1f859, 1},
+ {0x1f860, 0x1f887, 1},
+ {0x1f890, 0x1f8ad, 1},
+ {0x1f8b0, 0x1f8b1, 1},
+ {0x1f900, 0x1fa53, 1},
+ {0x1fa60, 0x1fa6d, 1},
+ {0x1fa70, 0x1fa7c, 1},
+ {0x1fa80, 0x1fa88, 1},
+ {0x1fa90, 0x1fabd, 1},
+ {0x1fabf, 0x1fac5, 1},
+ {0x1face, 0x1fadb, 1},
+ {0x1fae0, 0x1fae8, 1},
+ {0x1faf0, 0x1faf8, 1},
+ {0x1fb00, 0x1fb92, 1},
+ {0x1fb94, 0x1fbca, 1},
+ },
+ LatinOffset: 10,
+}
+
+var _Sc = &RangeTable{
+ R16: []Range16{
+ {0x0024, 0x00a2, 126},
+ {0x00a3, 0x00a5, 1},
+ {0x058f, 0x060b, 124},
+ {0x07fe, 0x07ff, 1},
+ {0x09f2, 0x09f3, 1},
+ {0x09fb, 0x0af1, 246},
+ {0x0bf9, 0x0e3f, 582},
+ {0x17db, 0x20a0, 2245},
+ {0x20a1, 0x20c0, 1},
+ {0xa838, 0xfdfc, 21956},
+ {0xfe69, 0xff04, 155},
+ {0xffe0, 0xffe1, 1},
+ {0xffe5, 0xffe6, 1},
+ },
+ R32: []Range32{
+ {0x11fdd, 0x11fe0, 1},
+ {0x1e2ff, 0x1ecb0, 2481},
+ },
+ LatinOffset: 2,
+}
+
+var _Sk = &RangeTable{
+ R16: []Range16{
+ {0x005e, 0x0060, 2},
+ {0x00a8, 0x00af, 7},
+ {0x00b4, 0x00b8, 4},
+ {0x02c2, 0x02c5, 1},
+ {0x02d2, 0x02df, 1},
+ {0x02e5, 0x02eb, 1},
+ {0x02ed, 0x02ef, 2},
+ {0x02f0, 0x02ff, 1},
+ {0x0375, 0x0384, 15},
+ {0x0385, 0x0888, 1283},
+ {0x1fbd, 0x1fbf, 2},
+ {0x1fc0, 0x1fc1, 1},
+ {0x1fcd, 0x1fcf, 1},
+ {0x1fdd, 0x1fdf, 1},
+ {0x1fed, 0x1fef, 1},
+ {0x1ffd, 0x1ffe, 1},
+ {0x309b, 0x309c, 1},
+ {0xa700, 0xa716, 1},
+ {0xa720, 0xa721, 1},
+ {0xa789, 0xa78a, 1},
+ {0xab5b, 0xab6a, 15},
+ {0xab6b, 0xfbb2, 20551},
+ {0xfbb3, 0xfbc2, 1},
+ {0xff3e, 0xff40, 2},
+ {0xffe3, 0xffe3, 1},
+ },
+ R32: []Range32{
+ {0x1f3fb, 0x1f3ff, 1},
+ },
+ LatinOffset: 3,
+}
+
+var _Sm = &RangeTable{
+ R16: []Range16{
+ {0x002b, 0x003c, 17},
+ {0x003d, 0x003e, 1},
+ {0x007c, 0x007e, 2},
+ {0x00ac, 0x00b1, 5},
+ {0x00d7, 0x00f7, 32},
+ {0x03f6, 0x0606, 528},
+ {0x0607, 0x0608, 1},
+ {0x2044, 0x2052, 14},
+ {0x207a, 0x207c, 1},
+ {0x208a, 0x208c, 1},
+ {0x2118, 0x2140, 40},
+ {0x2141, 0x2144, 1},
+ {0x214b, 0x2190, 69},
+ {0x2191, 0x2194, 1},
+ {0x219a, 0x219b, 1},
+ {0x21a0, 0x21a6, 3},
+ {0x21ae, 0x21ce, 32},
+ {0x21cf, 0x21d2, 3},
+ {0x21d4, 0x21f4, 32},
+ {0x21f5, 0x22ff, 1},
+ {0x2320, 0x2321, 1},
+ {0x237c, 0x239b, 31},
+ {0x239c, 0x23b3, 1},
+ {0x23dc, 0x23e1, 1},
+ {0x25b7, 0x25c1, 10},
+ {0x25f8, 0x25ff, 1},
+ {0x266f, 0x27c0, 337},
+ {0x27c1, 0x27c4, 1},
+ {0x27c7, 0x27e5, 1},
+ {0x27f0, 0x27ff, 1},
+ {0x2900, 0x2982, 1},
+ {0x2999, 0x29d7, 1},
+ {0x29dc, 0x29fb, 1},
+ {0x29fe, 0x2aff, 1},
+ {0x2b30, 0x2b44, 1},
+ {0x2b47, 0x2b4c, 1},
+ {0xfb29, 0xfe62, 825},
+ {0xfe64, 0xfe66, 1},
+ {0xff0b, 0xff1c, 17},
+ {0xff1d, 0xff1e, 1},
+ {0xff5c, 0xff5e, 2},
+ {0xffe2, 0xffe9, 7},
+ {0xffea, 0xffec, 1},
+ },
+ R32: []Range32{
+ {0x1d6c1, 0x1d6db, 26},
+ {0x1d6fb, 0x1d715, 26},
+ {0x1d735, 0x1d74f, 26},
+ {0x1d76f, 0x1d789, 26},
+ {0x1d7a9, 0x1d7c3, 26},
+ {0x1eef0, 0x1eef1, 1},
+ },
+ LatinOffset: 5,
+}
+
+var _So = &RangeTable{
+ R16: []Range16{
+ {0x00a6, 0x00a9, 3},
+ {0x00ae, 0x00b0, 2},
+ {0x0482, 0x058d, 267},
+ {0x058e, 0x060e, 128},
+ {0x060f, 0x06de, 207},
+ {0x06e9, 0x06fd, 20},
+ {0x06fe, 0x07f6, 248},
+ {0x09fa, 0x0b70, 374},
+ {0x0bf3, 0x0bf8, 1},
+ {0x0bfa, 0x0c7f, 133},
+ {0x0d4f, 0x0d79, 42},
+ {0x0f01, 0x0f03, 1},
+ {0x0f13, 0x0f15, 2},
+ {0x0f16, 0x0f17, 1},
+ {0x0f1a, 0x0f1f, 1},
+ {0x0f34, 0x0f38, 2},
+ {0x0fbe, 0x0fc5, 1},
+ {0x0fc7, 0x0fcc, 1},
+ {0x0fce, 0x0fcf, 1},
+ {0x0fd5, 0x0fd8, 1},
+ {0x109e, 0x109f, 1},
+ {0x1390, 0x1399, 1},
+ {0x166d, 0x1940, 723},
+ {0x19de, 0x19ff, 1},
+ {0x1b61, 0x1b6a, 1},
+ {0x1b74, 0x1b7c, 1},
+ {0x2100, 0x2101, 1},
+ {0x2103, 0x2106, 1},
+ {0x2108, 0x2109, 1},
+ {0x2114, 0x2116, 2},
+ {0x2117, 0x211e, 7},
+ {0x211f, 0x2123, 1},
+ {0x2125, 0x2129, 2},
+ {0x212e, 0x213a, 12},
+ {0x213b, 0x214a, 15},
+ {0x214c, 0x214d, 1},
+ {0x214f, 0x218a, 59},
+ {0x218b, 0x2195, 10},
+ {0x2196, 0x2199, 1},
+ {0x219c, 0x219f, 1},
+ {0x21a1, 0x21a2, 1},
+ {0x21a4, 0x21a5, 1},
+ {0x21a7, 0x21ad, 1},
+ {0x21af, 0x21cd, 1},
+ {0x21d0, 0x21d1, 1},
+ {0x21d3, 0x21d5, 2},
+ {0x21d6, 0x21f3, 1},
+ {0x2300, 0x2307, 1},
+ {0x230c, 0x231f, 1},
+ {0x2322, 0x2328, 1},
+ {0x232b, 0x237b, 1},
+ {0x237d, 0x239a, 1},
+ {0x23b4, 0x23db, 1},
+ {0x23e2, 0x2426, 1},
+ {0x2440, 0x244a, 1},
+ {0x249c, 0x24e9, 1},
+ {0x2500, 0x25b6, 1},
+ {0x25b8, 0x25c0, 1},
+ {0x25c2, 0x25f7, 1},
+ {0x2600, 0x266e, 1},
+ {0x2670, 0x2767, 1},
+ {0x2794, 0x27bf, 1},
+ {0x2800, 0x28ff, 1},
+ {0x2b00, 0x2b2f, 1},
+ {0x2b45, 0x2b46, 1},
+ {0x2b4d, 0x2b73, 1},
+ {0x2b76, 0x2b95, 1},
+ {0x2b97, 0x2bff, 1},
+ {0x2ce5, 0x2cea, 1},
+ {0x2e50, 0x2e51, 1},
+ {0x2e80, 0x2e99, 1},
+ {0x2e9b, 0x2ef3, 1},
+ {0x2f00, 0x2fd5, 1},
+ {0x2ff0, 0x2ffb, 1},
+ {0x3004, 0x3012, 14},
+ {0x3013, 0x3020, 13},
+ {0x3036, 0x3037, 1},
+ {0x303e, 0x303f, 1},
+ {0x3190, 0x3191, 1},
+ {0x3196, 0x319f, 1},
+ {0x31c0, 0x31e3, 1},
+ {0x3200, 0x321e, 1},
+ {0x322a, 0x3247, 1},
+ {0x3250, 0x3260, 16},
+ {0x3261, 0x327f, 1},
+ {0x328a, 0x32b0, 1},
+ {0x32c0, 0x33ff, 1},
+ {0x4dc0, 0x4dff, 1},
+ {0xa490, 0xa4c6, 1},
+ {0xa828, 0xa82b, 1},
+ {0xa836, 0xa837, 1},
+ {0xa839, 0xaa77, 574},
+ {0xaa78, 0xaa79, 1},
+ {0xfd40, 0xfd4f, 1},
+ {0xfdcf, 0xfdfd, 46},
+ {0xfdfe, 0xfdff, 1},
+ {0xffe4, 0xffe8, 4},
+ {0xffed, 0xffee, 1},
+ {0xfffc, 0xfffd, 1},
+ },
+ R32: []Range32{
+ {0x10137, 0x1013f, 1},
+ {0x10179, 0x10189, 1},
+ {0x1018c, 0x1018e, 1},
+ {0x10190, 0x1019c, 1},
+ {0x101a0, 0x101d0, 48},
+ {0x101d1, 0x101fc, 1},
+ {0x10877, 0x10878, 1},
+ {0x10ac8, 0x1173f, 3191},
+ {0x11fd5, 0x11fdc, 1},
+ {0x11fe1, 0x11ff1, 1},
+ {0x16b3c, 0x16b3f, 1},
+ {0x16b45, 0x1bc9c, 20823},
+ {0x1cf50, 0x1cfc3, 1},
+ {0x1d000, 0x1d0f5, 1},
+ {0x1d100, 0x1d126, 1},
+ {0x1d129, 0x1d164, 1},
+ {0x1d16a, 0x1d16c, 1},
+ {0x1d183, 0x1d184, 1},
+ {0x1d18c, 0x1d1a9, 1},
+ {0x1d1ae, 0x1d1ea, 1},
+ {0x1d200, 0x1d241, 1},
+ {0x1d245, 0x1d300, 187},
+ {0x1d301, 0x1d356, 1},
+ {0x1d800, 0x1d9ff, 1},
+ {0x1da37, 0x1da3a, 1},
+ {0x1da6d, 0x1da74, 1},
+ {0x1da76, 0x1da83, 1},
+ {0x1da85, 0x1da86, 1},
+ {0x1e14f, 0x1ecac, 2909},
+ {0x1ed2e, 0x1f000, 722},
+ {0x1f001, 0x1f02b, 1},
+ {0x1f030, 0x1f093, 1},
+ {0x1f0a0, 0x1f0ae, 1},
+ {0x1f0b1, 0x1f0bf, 1},
+ {0x1f0c1, 0x1f0cf, 1},
+ {0x1f0d1, 0x1f0f5, 1},
+ {0x1f10d, 0x1f1ad, 1},
+ {0x1f1e6, 0x1f202, 1},
+ {0x1f210, 0x1f23b, 1},
+ {0x1f240, 0x1f248, 1},
+ {0x1f250, 0x1f251, 1},
+ {0x1f260, 0x1f265, 1},
+ {0x1f300, 0x1f3fa, 1},
+ {0x1f400, 0x1f6d7, 1},
+ {0x1f6dc, 0x1f6ec, 1},
+ {0x1f6f0, 0x1f6fc, 1},
+ {0x1f700, 0x1f776, 1},
+ {0x1f77b, 0x1f7d9, 1},
+ {0x1f7e0, 0x1f7eb, 1},
+ {0x1f7f0, 0x1f800, 16},
+ {0x1f801, 0x1f80b, 1},
+ {0x1f810, 0x1f847, 1},
+ {0x1f850, 0x1f859, 1},
+ {0x1f860, 0x1f887, 1},
+ {0x1f890, 0x1f8ad, 1},
+ {0x1f8b0, 0x1f8b1, 1},
+ {0x1f900, 0x1fa53, 1},
+ {0x1fa60, 0x1fa6d, 1},
+ {0x1fa70, 0x1fa7c, 1},
+ {0x1fa80, 0x1fa88, 1},
+ {0x1fa90, 0x1fabd, 1},
+ {0x1fabf, 0x1fac5, 1},
+ {0x1face, 0x1fadb, 1},
+ {0x1fae0, 0x1fae8, 1},
+ {0x1faf0, 0x1faf8, 1},
+ {0x1fb00, 0x1fb92, 1},
+ {0x1fb94, 0x1fbca, 1},
+ },
+ LatinOffset: 2,
+}
+
+var _Z = &RangeTable{
+ R16: []Range16{
+ {0x0020, 0x00a0, 128},
+ {0x1680, 0x2000, 2432},
+ {0x2001, 0x200a, 1},
+ {0x2028, 0x2029, 1},
+ {0x202f, 0x205f, 48},
+ {0x3000, 0x3000, 1},
+ },
+ LatinOffset: 1,
+}
+
+var _Zl = &RangeTable{
+ R16: []Range16{
+ {0x2028, 0x2028, 1},
+ },
+}
+
+var _Zp = &RangeTable{
+ R16: []Range16{
+ {0x2029, 0x2029, 1},
+ },
+}
+
+var _Zs = &RangeTable{
+ R16: []Range16{
+ {0x0020, 0x00a0, 128},
+ {0x1680, 0x2000, 2432},
+ {0x2001, 0x200a, 1},
+ {0x202f, 0x205f, 48},
+ {0x3000, 0x3000, 1},
+ },
+ LatinOffset: 1,
+}
+
+// These variables have type *RangeTable.
+var (
+ Cc = _Cc // Cc is the set of Unicode characters in category Cc (Other, control).
+ Cf = _Cf // Cf is the set of Unicode characters in category Cf (Other, format).
+ Co = _Co // Co is the set of Unicode characters in category Co (Other, private use).
+ Cs = _Cs // Cs is the set of Unicode characters in category Cs (Other, surrogate).
+ Digit = _Nd // Digit is the set of Unicode characters with the "decimal digit" property.
+ Nd = _Nd // Nd is the set of Unicode characters in category Nd (Number, decimal digit).
+ Letter = _L // Letter/L is the set of Unicode letters, category L.
+ L = _L
+ Lm = _Lm // Lm is the set of Unicode characters in category Lm (Letter, modifier).
+ Lo = _Lo // Lo is the set of Unicode characters in category Lo (Letter, other).
+ Lower = _Ll // Lower is the set of Unicode lower case letters.
+ Ll = _Ll // Ll is the set of Unicode characters in category Ll (Letter, lowercase).
+ Mark = _M // Mark/M is the set of Unicode mark characters, category M.
+ M = _M
+ Mc = _Mc // Mc is the set of Unicode characters in category Mc (Mark, spacing combining).
+ Me = _Me // Me is the set of Unicode characters in category Me (Mark, enclosing).
+ Mn = _Mn // Mn is the set of Unicode characters in category Mn (Mark, nonspacing).
+ Nl = _Nl // Nl is the set of Unicode characters in category Nl (Number, letter).
+ No = _No // No is the set of Unicode characters in category No (Number, other).
+ Number = _N // Number/N is the set of Unicode number characters, category N.
+ N = _N
+ Other = _C // Other/C is the set of Unicode control and special characters, category C.
+ C = _C
+ Pc = _Pc // Pc is the set of Unicode characters in category Pc (Punctuation, connector).
+ Pd = _Pd // Pd is the set of Unicode characters in category Pd (Punctuation, dash).
+ Pe = _Pe // Pe is the set of Unicode characters in category Pe (Punctuation, close).
+ Pf = _Pf // Pf is the set of Unicode characters in category Pf (Punctuation, final quote).
+ Pi = _Pi // Pi is the set of Unicode characters in category Pi (Punctuation, initial quote).
+ Po = _Po // Po is the set of Unicode characters in category Po (Punctuation, other).
+ Ps = _Ps // Ps is the set of Unicode characters in category Ps (Punctuation, open).
+ Punct = _P // Punct/P is the set of Unicode punctuation characters, category P.
+ P = _P
+ Sc = _Sc // Sc is the set of Unicode characters in category Sc (Symbol, currency).
+ Sk = _Sk // Sk is the set of Unicode characters in category Sk (Symbol, modifier).
+ Sm = _Sm // Sm is the set of Unicode characters in category Sm (Symbol, math).
+ So = _So // So is the set of Unicode characters in category So (Symbol, other).
+ Space = _Z // Space/Z is the set of Unicode space characters, category Z.
+ Z = _Z
+ Symbol = _S // Symbol/S is the set of Unicode symbol characters, category S.
+ S = _S
+ Title = _Lt // Title is the set of Unicode title case letters.
+ Lt = _Lt // Lt is the set of Unicode characters in category Lt (Letter, titlecase).
+ Upper = _Lu // Upper is the set of Unicode upper case letters.
+ Lu = _Lu // Lu is the set of Unicode characters in category Lu (Letter, uppercase).
+ Zl = _Zl // Zl is the set of Unicode characters in category Zl (Separator, line).
+ Zp = _Zp // Zp is the set of Unicode characters in category Zp (Separator, paragraph).
+ Zs = _Zs // Zs is the set of Unicode characters in category Zs (Separator, space).
+)
+
+// Scripts is the set of Unicode script tables.
+var Scripts = map[string]*RangeTable{
+ "Adlam": Adlam,
+ "Ahom": Ahom,
+ "Anatolian_Hieroglyphs": Anatolian_Hieroglyphs,
+ "Arabic": Arabic,
+ "Armenian": Armenian,
+ "Avestan": Avestan,
+ "Balinese": Balinese,
+ "Bamum": Bamum,
+ "Bassa_Vah": Bassa_Vah,
+ "Batak": Batak,
+ "Bengali": Bengali,
+ "Bhaiksuki": Bhaiksuki,
+ "Bopomofo": Bopomofo,
+ "Brahmi": Brahmi,
+ "Braille": Braille,
+ "Buginese": Buginese,
+ "Buhid": Buhid,
+ "Canadian_Aboriginal": Canadian_Aboriginal,
+ "Carian": Carian,
+ "Caucasian_Albanian": Caucasian_Albanian,
+ "Chakma": Chakma,
+ "Cham": Cham,
+ "Cherokee": Cherokee,
+ "Chorasmian": Chorasmian,
+ "Common": Common,
+ "Coptic": Coptic,
+ "Cuneiform": Cuneiform,
+ "Cypriot": Cypriot,
+ "Cypro_Minoan": Cypro_Minoan,
+ "Cyrillic": Cyrillic,
+ "Deseret": Deseret,
+ "Devanagari": Devanagari,
+ "Dives_Akuru": Dives_Akuru,
+ "Dogra": Dogra,
+ "Duployan": Duployan,
+ "Egyptian_Hieroglyphs": Egyptian_Hieroglyphs,
+ "Elbasan": Elbasan,
+ "Elymaic": Elymaic,
+ "Ethiopic": Ethiopic,
+ "Georgian": Georgian,
+ "Glagolitic": Glagolitic,
+ "Gothic": Gothic,
+ "Grantha": Grantha,
+ "Greek": Greek,
+ "Gujarati": Gujarati,
+ "Gunjala_Gondi": Gunjala_Gondi,
+ "Gurmukhi": Gurmukhi,
+ "Han": Han,
+ "Hangul": Hangul,
+ "Hanifi_Rohingya": Hanifi_Rohingya,
+ "Hanunoo": Hanunoo,
+ "Hatran": Hatran,
+ "Hebrew": Hebrew,
+ "Hiragana": Hiragana,
+ "Imperial_Aramaic": Imperial_Aramaic,
+ "Inherited": Inherited,
+ "Inscriptional_Pahlavi": Inscriptional_Pahlavi,
+ "Inscriptional_Parthian": Inscriptional_Parthian,
+ "Javanese": Javanese,
+ "Kaithi": Kaithi,
+ "Kannada": Kannada,
+ "Katakana": Katakana,
+ "Kawi": Kawi,
+ "Kayah_Li": Kayah_Li,
+ "Kharoshthi": Kharoshthi,
+ "Khitan_Small_Script": Khitan_Small_Script,
+ "Khmer": Khmer,
+ "Khojki": Khojki,
+ "Khudawadi": Khudawadi,
+ "Lao": Lao,
+ "Latin": Latin,
+ "Lepcha": Lepcha,
+ "Limbu": Limbu,
+ "Linear_A": Linear_A,
+ "Linear_B": Linear_B,
+ "Lisu": Lisu,
+ "Lycian": Lycian,
+ "Lydian": Lydian,
+ "Mahajani": Mahajani,
+ "Makasar": Makasar,
+ "Malayalam": Malayalam,
+ "Mandaic": Mandaic,
+ "Manichaean": Manichaean,
+ "Marchen": Marchen,
+ "Masaram_Gondi": Masaram_Gondi,
+ "Medefaidrin": Medefaidrin,
+ "Meetei_Mayek": Meetei_Mayek,
+ "Mende_Kikakui": Mende_Kikakui,
+ "Meroitic_Cursive": Meroitic_Cursive,
+ "Meroitic_Hieroglyphs": Meroitic_Hieroglyphs,
+ "Miao": Miao,
+ "Modi": Modi,
+ "Mongolian": Mongolian,
+ "Mro": Mro,
+ "Multani": Multani,
+ "Myanmar": Myanmar,
+ "Nabataean": Nabataean,
+ "Nag_Mundari": Nag_Mundari,
+ "Nandinagari": Nandinagari,
+ "New_Tai_Lue": New_Tai_Lue,
+ "Newa": Newa,
+ "Nko": Nko,
+ "Nushu": Nushu,
+ "Nyiakeng_Puachue_Hmong": Nyiakeng_Puachue_Hmong,
+ "Ogham": Ogham,
+ "Ol_Chiki": Ol_Chiki,
+ "Old_Hungarian": Old_Hungarian,
+ "Old_Italic": Old_Italic,
+ "Old_North_Arabian": Old_North_Arabian,
+ "Old_Permic": Old_Permic,
+ "Old_Persian": Old_Persian,
+ "Old_Sogdian": Old_Sogdian,
+ "Old_South_Arabian": Old_South_Arabian,
+ "Old_Turkic": Old_Turkic,
+ "Old_Uyghur": Old_Uyghur,
+ "Oriya": Oriya,
+ "Osage": Osage,
+ "Osmanya": Osmanya,
+ "Pahawh_Hmong": Pahawh_Hmong,
+ "Palmyrene": Palmyrene,
+ "Pau_Cin_Hau": Pau_Cin_Hau,
+ "Phags_Pa": Phags_Pa,
+ "Phoenician": Phoenician,
+ "Psalter_Pahlavi": Psalter_Pahlavi,
+ "Rejang": Rejang,
+ "Runic": Runic,
+ "Samaritan": Samaritan,
+ "Saurashtra": Saurashtra,
+ "Sharada": Sharada,
+ "Shavian": Shavian,
+ "Siddham": Siddham,
+ "SignWriting": SignWriting,
+ "Sinhala": Sinhala,
+ "Sogdian": Sogdian,
+ "Sora_Sompeng": Sora_Sompeng,
+ "Soyombo": Soyombo,
+ "Sundanese": Sundanese,
+ "Syloti_Nagri": Syloti_Nagri,
+ "Syriac": Syriac,
+ "Tagalog": Tagalog,
+ "Tagbanwa": Tagbanwa,
+ "Tai_Le": Tai_Le,
+ "Tai_Tham": Tai_Tham,
+ "Tai_Viet": Tai_Viet,
+ "Takri": Takri,
+ "Tamil": Tamil,
+ "Tangsa": Tangsa,
+ "Tangut": Tangut,
+ "Telugu": Telugu,
+ "Thaana": Thaana,
+ "Thai": Thai,
+ "Tibetan": Tibetan,
+ "Tifinagh": Tifinagh,
+ "Tirhuta": Tirhuta,
+ "Toto": Toto,
+ "Ugaritic": Ugaritic,
+ "Vai": Vai,
+ "Vithkuqi": Vithkuqi,
+ "Wancho": Wancho,
+ "Warang_Citi": Warang_Citi,
+ "Yezidi": Yezidi,
+ "Yi": Yi,
+ "Zanabazar_Square": Zanabazar_Square,
+}
+
+var _Adlam = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x1e900, 0x1e94b, 1},
+ {0x1e950, 0x1e959, 1},
+ {0x1e95e, 0x1e95f, 1},
+ },
+}
+
+var _Ahom = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11700, 0x1171a, 1},
+ {0x1171d, 0x1172b, 1},
+ {0x11730, 0x11746, 1},
+ },
+}
+
+var _Anatolian_Hieroglyphs = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x14400, 0x14646, 1},
+ },
+}
+
+var _Arabic = &RangeTable{
+ R16: []Range16{
+ {0x0600, 0x0604, 1},
+ {0x0606, 0x060b, 1},
+ {0x060d, 0x061a, 1},
+ {0x061c, 0x061e, 1},
+ {0x0620, 0x063f, 1},
+ {0x0641, 0x064a, 1},
+ {0x0656, 0x066f, 1},
+ {0x0671, 0x06dc, 1},
+ {0x06de, 0x06ff, 1},
+ {0x0750, 0x077f, 1},
+ {0x0870, 0x088e, 1},
+ {0x0890, 0x0891, 1},
+ {0x0898, 0x08e1, 1},
+ {0x08e3, 0x08ff, 1},
+ {0xfb50, 0xfbc2, 1},
+ {0xfbd3, 0xfd3d, 1},
+ {0xfd40, 0xfd8f, 1},
+ {0xfd92, 0xfdc7, 1},
+ {0xfdcf, 0xfdf0, 33},
+ {0xfdf1, 0xfdff, 1},
+ {0xfe70, 0xfe74, 1},
+ {0xfe76, 0xfefc, 1},
+ },
+ R32: []Range32{
+ {0x10e60, 0x10e7e, 1},
+ {0x10efd, 0x10eff, 1},
+ {0x1ee00, 0x1ee03, 1},
+ {0x1ee05, 0x1ee1f, 1},
+ {0x1ee21, 0x1ee22, 1},
+ {0x1ee24, 0x1ee27, 3},
+ {0x1ee29, 0x1ee32, 1},
+ {0x1ee34, 0x1ee37, 1},
+ {0x1ee39, 0x1ee3b, 2},
+ {0x1ee42, 0x1ee47, 5},
+ {0x1ee49, 0x1ee4d, 2},
+ {0x1ee4e, 0x1ee4f, 1},
+ {0x1ee51, 0x1ee52, 1},
+ {0x1ee54, 0x1ee57, 3},
+ {0x1ee59, 0x1ee61, 2},
+ {0x1ee62, 0x1ee64, 2},
+ {0x1ee67, 0x1ee6a, 1},
+ {0x1ee6c, 0x1ee72, 1},
+ {0x1ee74, 0x1ee77, 1},
+ {0x1ee79, 0x1ee7c, 1},
+ {0x1ee7e, 0x1ee80, 2},
+ {0x1ee81, 0x1ee89, 1},
+ {0x1ee8b, 0x1ee9b, 1},
+ {0x1eea1, 0x1eea3, 1},
+ {0x1eea5, 0x1eea9, 1},
+ {0x1eeab, 0x1eebb, 1},
+ {0x1eef0, 0x1eef1, 1},
+ },
+}
+
+var _Armenian = &RangeTable{
+ R16: []Range16{
+ {0x0531, 0x0556, 1},
+ {0x0559, 0x058a, 1},
+ {0x058d, 0x058f, 1},
+ {0xfb13, 0xfb17, 1},
+ },
+}
+
+var _Avestan = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10b00, 0x10b35, 1},
+ {0x10b39, 0x10b3f, 1},
+ },
+}
+
+var _Balinese = &RangeTable{
+ R16: []Range16{
+ {0x1b00, 0x1b4c, 1},
+ {0x1b50, 0x1b7e, 1},
+ },
+}
+
+var _Bamum = &RangeTable{
+ R16: []Range16{
+ {0xa6a0, 0xa6f7, 1},
+ },
+ R32: []Range32{
+ {0x16800, 0x16a38, 1},
+ },
+}
+
+var _Bassa_Vah = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x16ad0, 0x16aed, 1},
+ {0x16af0, 0x16af5, 1},
+ },
+}
+
+var _Batak = &RangeTable{
+ R16: []Range16{
+ {0x1bc0, 0x1bf3, 1},
+ {0x1bfc, 0x1bff, 1},
+ },
+}
+
+var _Bengali = &RangeTable{
+ R16: []Range16{
+ {0x0980, 0x0983, 1},
+ {0x0985, 0x098c, 1},
+ {0x098f, 0x0990, 1},
+ {0x0993, 0x09a8, 1},
+ {0x09aa, 0x09b0, 1},
+ {0x09b2, 0x09b6, 4},
+ {0x09b7, 0x09b9, 1},
+ {0x09bc, 0x09c4, 1},
+ {0x09c7, 0x09c8, 1},
+ {0x09cb, 0x09ce, 1},
+ {0x09d7, 0x09dc, 5},
+ {0x09dd, 0x09df, 2},
+ {0x09e0, 0x09e3, 1},
+ {0x09e6, 0x09fe, 1},
+ },
+}
+
+var _Bhaiksuki = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11c00, 0x11c08, 1},
+ {0x11c0a, 0x11c36, 1},
+ {0x11c38, 0x11c45, 1},
+ {0x11c50, 0x11c6c, 1},
+ },
+}
+
+var _Bopomofo = &RangeTable{
+ R16: []Range16{
+ {0x02ea, 0x02eb, 1},
+ {0x3105, 0x312f, 1},
+ {0x31a0, 0x31bf, 1},
+ },
+}
+
+var _Brahmi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11000, 0x1104d, 1},
+ {0x11052, 0x11075, 1},
+ {0x1107f, 0x1107f, 1},
+ },
+}
+
+var _Braille = &RangeTable{
+ R16: []Range16{
+ {0x2800, 0x28ff, 1},
+ },
+}
+
+var _Buginese = &RangeTable{
+ R16: []Range16{
+ {0x1a00, 0x1a1b, 1},
+ {0x1a1e, 0x1a1f, 1},
+ },
+}
+
+var _Buhid = &RangeTable{
+ R16: []Range16{
+ {0x1740, 0x1753, 1},
+ },
+}
+
+var _Canadian_Aboriginal = &RangeTable{
+ R16: []Range16{
+ {0x1400, 0x167f, 1},
+ {0x18b0, 0x18f5, 1},
+ },
+ R32: []Range32{
+ {0x11ab0, 0x11abf, 1},
+ },
+}
+
+var _Carian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x102a0, 0x102d0, 1},
+ },
+}
+
+var _Caucasian_Albanian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10530, 0x10563, 1},
+ {0x1056f, 0x1056f, 1},
+ },
+}
+
+var _Chakma = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11100, 0x11134, 1},
+ {0x11136, 0x11147, 1},
+ },
+}
+
+var _Cham = &RangeTable{
+ R16: []Range16{
+ {0xaa00, 0xaa36, 1},
+ {0xaa40, 0xaa4d, 1},
+ {0xaa50, 0xaa59, 1},
+ {0xaa5c, 0xaa5f, 1},
+ },
+}
+
+var _Cherokee = &RangeTable{
+ R16: []Range16{
+ {0x13a0, 0x13f5, 1},
+ {0x13f8, 0x13fd, 1},
+ {0xab70, 0xabbf, 1},
+ },
+}
+
+var _Chorasmian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10fb0, 0x10fcb, 1},
+ },
+}
+
+var _Common = &RangeTable{
+ R16: []Range16{
+ {0x0000, 0x0040, 1},
+ {0x005b, 0x0060, 1},
+ {0x007b, 0x00a9, 1},
+ {0x00ab, 0x00b9, 1},
+ {0x00bb, 0x00bf, 1},
+ {0x00d7, 0x00f7, 32},
+ {0x02b9, 0x02df, 1},
+ {0x02e5, 0x02e9, 1},
+ {0x02ec, 0x02ff, 1},
+ {0x0374, 0x037e, 10},
+ {0x0385, 0x0387, 2},
+ {0x0605, 0x060c, 7},
+ {0x061b, 0x061f, 4},
+ {0x0640, 0x06dd, 157},
+ {0x08e2, 0x0964, 130},
+ {0x0965, 0x0e3f, 1242},
+ {0x0fd5, 0x0fd8, 1},
+ {0x10fb, 0x16eb, 1520},
+ {0x16ec, 0x16ed, 1},
+ {0x1735, 0x1736, 1},
+ {0x1802, 0x1803, 1},
+ {0x1805, 0x1cd3, 1230},
+ {0x1ce1, 0x1ce9, 8},
+ {0x1cea, 0x1cec, 1},
+ {0x1cee, 0x1cf3, 1},
+ {0x1cf5, 0x1cf7, 1},
+ {0x1cfa, 0x2000, 774},
+ {0x2001, 0x200b, 1},
+ {0x200e, 0x2064, 1},
+ {0x2066, 0x2070, 1},
+ {0x2074, 0x207e, 1},
+ {0x2080, 0x208e, 1},
+ {0x20a0, 0x20c0, 1},
+ {0x2100, 0x2125, 1},
+ {0x2127, 0x2129, 1},
+ {0x212c, 0x2131, 1},
+ {0x2133, 0x214d, 1},
+ {0x214f, 0x215f, 1},
+ {0x2189, 0x218b, 1},
+ {0x2190, 0x2426, 1},
+ {0x2440, 0x244a, 1},
+ {0x2460, 0x27ff, 1},
+ {0x2900, 0x2b73, 1},
+ {0x2b76, 0x2b95, 1},
+ {0x2b97, 0x2bff, 1},
+ {0x2e00, 0x2e5d, 1},
+ {0x2ff0, 0x2ffb, 1},
+ {0x3000, 0x3004, 1},
+ {0x3006, 0x3008, 2},
+ {0x3009, 0x3020, 1},
+ {0x3030, 0x3037, 1},
+ {0x303c, 0x303f, 1},
+ {0x309b, 0x309c, 1},
+ {0x30a0, 0x30fb, 91},
+ {0x30fc, 0x3190, 148},
+ {0x3191, 0x319f, 1},
+ {0x31c0, 0x31e3, 1},
+ {0x3220, 0x325f, 1},
+ {0x327f, 0x32cf, 1},
+ {0x32ff, 0x3358, 89},
+ {0x3359, 0x33ff, 1},
+ {0x4dc0, 0x4dff, 1},
+ {0xa700, 0xa721, 1},
+ {0xa788, 0xa78a, 1},
+ {0xa830, 0xa839, 1},
+ {0xa92e, 0xa9cf, 161},
+ {0xab5b, 0xab6a, 15},
+ {0xab6b, 0xfd3e, 20947},
+ {0xfd3f, 0xfe10, 209},
+ {0xfe11, 0xfe19, 1},
+ {0xfe30, 0xfe52, 1},
+ {0xfe54, 0xfe66, 1},
+ {0xfe68, 0xfe6b, 1},
+ {0xfeff, 0xff01, 2},
+ {0xff02, 0xff20, 1},
+ {0xff3b, 0xff40, 1},
+ {0xff5b, 0xff65, 1},
+ {0xff70, 0xff9e, 46},
+ {0xff9f, 0xffe0, 65},
+ {0xffe1, 0xffe6, 1},
+ {0xffe8, 0xffee, 1},
+ {0xfff9, 0xfffd, 1},
+ },
+ R32: []Range32{
+ {0x10100, 0x10102, 1},
+ {0x10107, 0x10133, 1},
+ {0x10137, 0x1013f, 1},
+ {0x10190, 0x1019c, 1},
+ {0x101d0, 0x101fc, 1},
+ {0x102e1, 0x102fb, 1},
+ {0x1bca0, 0x1bca3, 1},
+ {0x1cf50, 0x1cfc3, 1},
+ {0x1d000, 0x1d0f5, 1},
+ {0x1d100, 0x1d126, 1},
+ {0x1d129, 0x1d166, 1},
+ {0x1d16a, 0x1d17a, 1},
+ {0x1d183, 0x1d184, 1},
+ {0x1d18c, 0x1d1a9, 1},
+ {0x1d1ae, 0x1d1ea, 1},
+ {0x1d2c0, 0x1d2d3, 1},
+ {0x1d2e0, 0x1d2f3, 1},
+ {0x1d300, 0x1d356, 1},
+ {0x1d360, 0x1d378, 1},
+ {0x1d400, 0x1d454, 1},
+ {0x1d456, 0x1d49c, 1},
+ {0x1d49e, 0x1d49f, 1},
+ {0x1d4a2, 0x1d4a5, 3},
+ {0x1d4a6, 0x1d4a9, 3},
+ {0x1d4aa, 0x1d4ac, 1},
+ {0x1d4ae, 0x1d4b9, 1},
+ {0x1d4bb, 0x1d4bd, 2},
+ {0x1d4be, 0x1d4c3, 1},
+ {0x1d4c5, 0x1d505, 1},
+ {0x1d507, 0x1d50a, 1},
+ {0x1d50d, 0x1d514, 1},
+ {0x1d516, 0x1d51c, 1},
+ {0x1d51e, 0x1d539, 1},
+ {0x1d53b, 0x1d53e, 1},
+ {0x1d540, 0x1d544, 1},
+ {0x1d546, 0x1d54a, 4},
+ {0x1d54b, 0x1d550, 1},
+ {0x1d552, 0x1d6a5, 1},
+ {0x1d6a8, 0x1d7cb, 1},
+ {0x1d7ce, 0x1d7ff, 1},
+ {0x1ec71, 0x1ecb4, 1},
+ {0x1ed01, 0x1ed3d, 1},
+ {0x1f000, 0x1f02b, 1},
+ {0x1f030, 0x1f093, 1},
+ {0x1f0a0, 0x1f0ae, 1},
+ {0x1f0b1, 0x1f0bf, 1},
+ {0x1f0c1, 0x1f0cf, 1},
+ {0x1f0d1, 0x1f0f5, 1},
+ {0x1f100, 0x1f1ad, 1},
+ {0x1f1e6, 0x1f1ff, 1},
+ {0x1f201, 0x1f202, 1},
+ {0x1f210, 0x1f23b, 1},
+ {0x1f240, 0x1f248, 1},
+ {0x1f250, 0x1f251, 1},
+ {0x1f260, 0x1f265, 1},
+ {0x1f300, 0x1f6d7, 1},
+ {0x1f6dc, 0x1f6ec, 1},
+ {0x1f6f0, 0x1f6fc, 1},
+ {0x1f700, 0x1f776, 1},
+ {0x1f77b, 0x1f7d9, 1},
+ {0x1f7e0, 0x1f7eb, 1},
+ {0x1f7f0, 0x1f800, 16},
+ {0x1f801, 0x1f80b, 1},
+ {0x1f810, 0x1f847, 1},
+ {0x1f850, 0x1f859, 1},
+ {0x1f860, 0x1f887, 1},
+ {0x1f890, 0x1f8ad, 1},
+ {0x1f8b0, 0x1f8b1, 1},
+ {0x1f900, 0x1fa53, 1},
+ {0x1fa60, 0x1fa6d, 1},
+ {0x1fa70, 0x1fa7c, 1},
+ {0x1fa80, 0x1fa88, 1},
+ {0x1fa90, 0x1fabd, 1},
+ {0x1fabf, 0x1fac5, 1},
+ {0x1face, 0x1fadb, 1},
+ {0x1fae0, 0x1fae8, 1},
+ {0x1faf0, 0x1faf8, 1},
+ {0x1fb00, 0x1fb92, 1},
+ {0x1fb94, 0x1fbca, 1},
+ {0x1fbf0, 0x1fbf9, 1},
+ {0xe0001, 0xe0020, 31},
+ {0xe0021, 0xe007f, 1},
+ },
+ LatinOffset: 6,
+}
+
+var _Coptic = &RangeTable{
+ R16: []Range16{
+ {0x03e2, 0x03ef, 1},
+ {0x2c80, 0x2cf3, 1},
+ {0x2cf9, 0x2cff, 1},
+ },
+}
+
+var _Cuneiform = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x12000, 0x12399, 1},
+ {0x12400, 0x1246e, 1},
+ {0x12470, 0x12474, 1},
+ {0x12480, 0x12543, 1},
+ },
+}
+
+var _Cypriot = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10800, 0x10805, 1},
+ {0x10808, 0x1080a, 2},
+ {0x1080b, 0x10835, 1},
+ {0x10837, 0x10838, 1},
+ {0x1083c, 0x1083f, 3},
+ },
+}
+
+var _Cypro_Minoan = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x12f90, 0x12ff2, 1},
+ },
+}
+
+var _Cyrillic = &RangeTable{
+ R16: []Range16{
+ {0x0400, 0x0484, 1},
+ {0x0487, 0x052f, 1},
+ {0x1c80, 0x1c88, 1},
+ {0x1d2b, 0x1d78, 77},
+ {0x2de0, 0x2dff, 1},
+ {0xa640, 0xa69f, 1},
+ {0xfe2e, 0xfe2f, 1},
+ },
+ R32: []Range32{
+ {0x1e030, 0x1e06d, 1},
+ {0x1e08f, 0x1e08f, 1},
+ },
+}
+
+var _Deseret = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10400, 0x1044f, 1},
+ },
+}
+
+var _Devanagari = &RangeTable{
+ R16: []Range16{
+ {0x0900, 0x0950, 1},
+ {0x0955, 0x0963, 1},
+ {0x0966, 0x097f, 1},
+ {0xa8e0, 0xa8ff, 1},
+ },
+ R32: []Range32{
+ {0x11b00, 0x11b09, 1},
+ },
+}
+
+var _Dives_Akuru = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11900, 0x11906, 1},
+ {0x11909, 0x1190c, 3},
+ {0x1190d, 0x11913, 1},
+ {0x11915, 0x11916, 1},
+ {0x11918, 0x11935, 1},
+ {0x11937, 0x11938, 1},
+ {0x1193b, 0x11946, 1},
+ {0x11950, 0x11959, 1},
+ },
+}
+
+var _Dogra = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11800, 0x1183b, 1},
+ },
+}
+
+var _Duployan = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x1bc00, 0x1bc6a, 1},
+ {0x1bc70, 0x1bc7c, 1},
+ {0x1bc80, 0x1bc88, 1},
+ {0x1bc90, 0x1bc99, 1},
+ {0x1bc9c, 0x1bc9f, 1},
+ },
+}
+
+var _Egyptian_Hieroglyphs = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x13000, 0x13455, 1},
+ },
+}
+
+var _Elbasan = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10500, 0x10527, 1},
+ },
+}
+
+var _Elymaic = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10fe0, 0x10ff6, 1},
+ },
+}
+
+var _Ethiopic = &RangeTable{
+ R16: []Range16{
+ {0x1200, 0x1248, 1},
+ {0x124a, 0x124d, 1},
+ {0x1250, 0x1256, 1},
+ {0x1258, 0x125a, 2},
+ {0x125b, 0x125d, 1},
+ {0x1260, 0x1288, 1},
+ {0x128a, 0x128d, 1},
+ {0x1290, 0x12b0, 1},
+ {0x12b2, 0x12b5, 1},
+ {0x12b8, 0x12be, 1},
+ {0x12c0, 0x12c2, 2},
+ {0x12c3, 0x12c5, 1},
+ {0x12c8, 0x12d6, 1},
+ {0x12d8, 0x1310, 1},
+ {0x1312, 0x1315, 1},
+ {0x1318, 0x135a, 1},
+ {0x135d, 0x137c, 1},
+ {0x1380, 0x1399, 1},
+ {0x2d80, 0x2d96, 1},
+ {0x2da0, 0x2da6, 1},
+ {0x2da8, 0x2dae, 1},
+ {0x2db0, 0x2db6, 1},
+ {0x2db8, 0x2dbe, 1},
+ {0x2dc0, 0x2dc6, 1},
+ {0x2dc8, 0x2dce, 1},
+ {0x2dd0, 0x2dd6, 1},
+ {0x2dd8, 0x2dde, 1},
+ {0xab01, 0xab06, 1},
+ {0xab09, 0xab0e, 1},
+ {0xab11, 0xab16, 1},
+ {0xab20, 0xab26, 1},
+ {0xab28, 0xab2e, 1},
+ },
+ R32: []Range32{
+ {0x1e7e0, 0x1e7e6, 1},
+ {0x1e7e8, 0x1e7eb, 1},
+ {0x1e7ed, 0x1e7ee, 1},
+ {0x1e7f0, 0x1e7fe, 1},
+ },
+}
+
+var _Georgian = &RangeTable{
+ R16: []Range16{
+ {0x10a0, 0x10c5, 1},
+ {0x10c7, 0x10cd, 6},
+ {0x10d0, 0x10fa, 1},
+ {0x10fc, 0x10ff, 1},
+ {0x1c90, 0x1cba, 1},
+ {0x1cbd, 0x1cbf, 1},
+ {0x2d00, 0x2d25, 1},
+ {0x2d27, 0x2d2d, 6},
+ },
+}
+
+var _Glagolitic = &RangeTable{
+ R16: []Range16{
+ {0x2c00, 0x2c5f, 1},
+ },
+ R32: []Range32{
+ {0x1e000, 0x1e006, 1},
+ {0x1e008, 0x1e018, 1},
+ {0x1e01b, 0x1e021, 1},
+ {0x1e023, 0x1e024, 1},
+ {0x1e026, 0x1e02a, 1},
+ },
+}
+
+var _Gothic = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10330, 0x1034a, 1},
+ },
+}
+
+var _Grantha = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11300, 0x11303, 1},
+ {0x11305, 0x1130c, 1},
+ {0x1130f, 0x11310, 1},
+ {0x11313, 0x11328, 1},
+ {0x1132a, 0x11330, 1},
+ {0x11332, 0x11333, 1},
+ {0x11335, 0x11339, 1},
+ {0x1133c, 0x11344, 1},
+ {0x11347, 0x11348, 1},
+ {0x1134b, 0x1134d, 1},
+ {0x11350, 0x11357, 7},
+ {0x1135d, 0x11363, 1},
+ {0x11366, 0x1136c, 1},
+ {0x11370, 0x11374, 1},
+ },
+}
+
+var _Greek = &RangeTable{
+ R16: []Range16{
+ {0x0370, 0x0373, 1},
+ {0x0375, 0x0377, 1},
+ {0x037a, 0x037d, 1},
+ {0x037f, 0x0384, 5},
+ {0x0386, 0x0388, 2},
+ {0x0389, 0x038a, 1},
+ {0x038c, 0x038e, 2},
+ {0x038f, 0x03a1, 1},
+ {0x03a3, 0x03e1, 1},
+ {0x03f0, 0x03ff, 1},
+ {0x1d26, 0x1d2a, 1},
+ {0x1d5d, 0x1d61, 1},
+ {0x1d66, 0x1d6a, 1},
+ {0x1dbf, 0x1f00, 321},
+ {0x1f01, 0x1f15, 1},
+ {0x1f18, 0x1f1d, 1},
+ {0x1f20, 0x1f45, 1},
+ {0x1f48, 0x1f4d, 1},
+ {0x1f50, 0x1f57, 1},
+ {0x1f59, 0x1f5f, 2},
+ {0x1f60, 0x1f7d, 1},
+ {0x1f80, 0x1fb4, 1},
+ {0x1fb6, 0x1fc4, 1},
+ {0x1fc6, 0x1fd3, 1},
+ {0x1fd6, 0x1fdb, 1},
+ {0x1fdd, 0x1fef, 1},
+ {0x1ff2, 0x1ff4, 1},
+ {0x1ff6, 0x1ffe, 1},
+ {0x2126, 0xab65, 35391},
+ },
+ R32: []Range32{
+ {0x10140, 0x1018e, 1},
+ {0x101a0, 0x1d200, 53344},
+ {0x1d201, 0x1d245, 1},
+ },
+}
+
+var _Gujarati = &RangeTable{
+ R16: []Range16{
+ {0x0a81, 0x0a83, 1},
+ {0x0a85, 0x0a8d, 1},
+ {0x0a8f, 0x0a91, 1},
+ {0x0a93, 0x0aa8, 1},
+ {0x0aaa, 0x0ab0, 1},
+ {0x0ab2, 0x0ab3, 1},
+ {0x0ab5, 0x0ab9, 1},
+ {0x0abc, 0x0ac5, 1},
+ {0x0ac7, 0x0ac9, 1},
+ {0x0acb, 0x0acd, 1},
+ {0x0ad0, 0x0ae0, 16},
+ {0x0ae1, 0x0ae3, 1},
+ {0x0ae6, 0x0af1, 1},
+ {0x0af9, 0x0aff, 1},
+ },
+}
+
+var _Gunjala_Gondi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11d60, 0x11d65, 1},
+ {0x11d67, 0x11d68, 1},
+ {0x11d6a, 0x11d8e, 1},
+ {0x11d90, 0x11d91, 1},
+ {0x11d93, 0x11d98, 1},
+ {0x11da0, 0x11da9, 1},
+ },
+}
+
+var _Gurmukhi = &RangeTable{
+ R16: []Range16{
+ {0x0a01, 0x0a03, 1},
+ {0x0a05, 0x0a0a, 1},
+ {0x0a0f, 0x0a10, 1},
+ {0x0a13, 0x0a28, 1},
+ {0x0a2a, 0x0a30, 1},
+ {0x0a32, 0x0a33, 1},
+ {0x0a35, 0x0a36, 1},
+ {0x0a38, 0x0a39, 1},
+ {0x0a3c, 0x0a3e, 2},
+ {0x0a3f, 0x0a42, 1},
+ {0x0a47, 0x0a48, 1},
+ {0x0a4b, 0x0a4d, 1},
+ {0x0a51, 0x0a59, 8},
+ {0x0a5a, 0x0a5c, 1},
+ {0x0a5e, 0x0a66, 8},
+ {0x0a67, 0x0a76, 1},
+ },
+}
+
+var _Han = &RangeTable{
+ R16: []Range16{
+ {0x2e80, 0x2e99, 1},
+ {0x2e9b, 0x2ef3, 1},
+ {0x2f00, 0x2fd5, 1},
+ {0x3005, 0x3007, 2},
+ {0x3021, 0x3029, 1},
+ {0x3038, 0x303b, 1},
+ {0x3400, 0x4dbf, 1},
+ {0x4e00, 0x9fff, 1},
+ {0xf900, 0xfa6d, 1},
+ {0xfa70, 0xfad9, 1},
+ },
+ R32: []Range32{
+ {0x16fe2, 0x16fe3, 1},
+ {0x16ff0, 0x16ff1, 1},
+ {0x20000, 0x2a6df, 1},
+ {0x2a700, 0x2b739, 1},
+ {0x2b740, 0x2b81d, 1},
+ {0x2b820, 0x2cea1, 1},
+ {0x2ceb0, 0x2ebe0, 1},
+ {0x2f800, 0x2fa1d, 1},
+ {0x30000, 0x3134a, 1},
+ {0x31350, 0x323af, 1},
+ },
+}
+
+var _Hangul = &RangeTable{
+ R16: []Range16{
+ {0x1100, 0x11ff, 1},
+ {0x302e, 0x302f, 1},
+ {0x3131, 0x318e, 1},
+ {0x3200, 0x321e, 1},
+ {0x3260, 0x327e, 1},
+ {0xa960, 0xa97c, 1},
+ {0xac00, 0xd7a3, 1},
+ {0xd7b0, 0xd7c6, 1},
+ {0xd7cb, 0xd7fb, 1},
+ {0xffa0, 0xffbe, 1},
+ {0xffc2, 0xffc7, 1},
+ {0xffca, 0xffcf, 1},
+ {0xffd2, 0xffd7, 1},
+ {0xffda, 0xffdc, 1},
+ },
+}
+
+var _Hanifi_Rohingya = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10d00, 0x10d27, 1},
+ {0x10d30, 0x10d39, 1},
+ },
+}
+
+var _Hanunoo = &RangeTable{
+ R16: []Range16{
+ {0x1720, 0x1734, 1},
+ },
+}
+
+var _Hatran = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x108e0, 0x108f2, 1},
+ {0x108f4, 0x108f5, 1},
+ {0x108fb, 0x108ff, 1},
+ },
+}
+
+var _Hebrew = &RangeTable{
+ R16: []Range16{
+ {0x0591, 0x05c7, 1},
+ {0x05d0, 0x05ea, 1},
+ {0x05ef, 0x05f4, 1},
+ {0xfb1d, 0xfb36, 1},
+ {0xfb38, 0xfb3c, 1},
+ {0xfb3e, 0xfb40, 2},
+ {0xfb41, 0xfb43, 2},
+ {0xfb44, 0xfb46, 2},
+ {0xfb47, 0xfb4f, 1},
+ },
+}
+
+var _Hiragana = &RangeTable{
+ R16: []Range16{
+ {0x3041, 0x3096, 1},
+ {0x309d, 0x309f, 1},
+ },
+ R32: []Range32{
+ {0x1b001, 0x1b11f, 1},
+ {0x1b132, 0x1b150, 30},
+ {0x1b151, 0x1b152, 1},
+ {0x1f200, 0x1f200, 1},
+ },
+}
+
+var _Imperial_Aramaic = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10840, 0x10855, 1},
+ {0x10857, 0x1085f, 1},
+ },
+}
+
+var _Inherited = &RangeTable{
+ R16: []Range16{
+ {0x0300, 0x036f, 1},
+ {0x0485, 0x0486, 1},
+ {0x064b, 0x0655, 1},
+ {0x0670, 0x0951, 737},
+ {0x0952, 0x0954, 1},
+ {0x1ab0, 0x1ace, 1},
+ {0x1cd0, 0x1cd2, 1},
+ {0x1cd4, 0x1ce0, 1},
+ {0x1ce2, 0x1ce8, 1},
+ {0x1ced, 0x1cf4, 7},
+ {0x1cf8, 0x1cf9, 1},
+ {0x1dc0, 0x1dff, 1},
+ {0x200c, 0x200d, 1},
+ {0x20d0, 0x20f0, 1},
+ {0x302a, 0x302d, 1},
+ {0x3099, 0x309a, 1},
+ {0xfe00, 0xfe0f, 1},
+ {0xfe20, 0xfe2d, 1},
+ },
+ R32: []Range32{
+ {0x101fd, 0x102e0, 227},
+ {0x1133b, 0x1cf00, 48069},
+ {0x1cf01, 0x1cf2d, 1},
+ {0x1cf30, 0x1cf46, 1},
+ {0x1d167, 0x1d169, 1},
+ {0x1d17b, 0x1d182, 1},
+ {0x1d185, 0x1d18b, 1},
+ {0x1d1aa, 0x1d1ad, 1},
+ {0xe0100, 0xe01ef, 1},
+ },
+}
+
+var _Inscriptional_Pahlavi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10b60, 0x10b72, 1},
+ {0x10b78, 0x10b7f, 1},
+ },
+}
+
+var _Inscriptional_Parthian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10b40, 0x10b55, 1},
+ {0x10b58, 0x10b5f, 1},
+ },
+}
+
+var _Javanese = &RangeTable{
+ R16: []Range16{
+ {0xa980, 0xa9cd, 1},
+ {0xa9d0, 0xa9d9, 1},
+ {0xa9de, 0xa9df, 1},
+ },
+}
+
+var _Kaithi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11080, 0x110c2, 1},
+ {0x110cd, 0x110cd, 1},
+ },
+}
+
+var _Kannada = &RangeTable{
+ R16: []Range16{
+ {0x0c80, 0x0c8c, 1},
+ {0x0c8e, 0x0c90, 1},
+ {0x0c92, 0x0ca8, 1},
+ {0x0caa, 0x0cb3, 1},
+ {0x0cb5, 0x0cb9, 1},
+ {0x0cbc, 0x0cc4, 1},
+ {0x0cc6, 0x0cc8, 1},
+ {0x0cca, 0x0ccd, 1},
+ {0x0cd5, 0x0cd6, 1},
+ {0x0cdd, 0x0cde, 1},
+ {0x0ce0, 0x0ce3, 1},
+ {0x0ce6, 0x0cef, 1},
+ {0x0cf1, 0x0cf3, 1},
+ },
+}
+
+var _Katakana = &RangeTable{
+ R16: []Range16{
+ {0x30a1, 0x30fa, 1},
+ {0x30fd, 0x30ff, 1},
+ {0x31f0, 0x31ff, 1},
+ {0x32d0, 0x32fe, 1},
+ {0x3300, 0x3357, 1},
+ {0xff66, 0xff6f, 1},
+ {0xff71, 0xff9d, 1},
+ },
+ R32: []Range32{
+ {0x1aff0, 0x1aff3, 1},
+ {0x1aff5, 0x1affb, 1},
+ {0x1affd, 0x1affe, 1},
+ {0x1b000, 0x1b120, 288},
+ {0x1b121, 0x1b122, 1},
+ {0x1b155, 0x1b164, 15},
+ {0x1b165, 0x1b167, 1},
+ },
+}
+
+var _Kawi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11f00, 0x11f10, 1},
+ {0x11f12, 0x11f3a, 1},
+ {0x11f3e, 0x11f59, 1},
+ },
+}
+
+var _Kayah_Li = &RangeTable{
+ R16: []Range16{
+ {0xa900, 0xa92d, 1},
+ {0xa92f, 0xa92f, 1},
+ },
+}
+
+var _Kharoshthi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10a00, 0x10a03, 1},
+ {0x10a05, 0x10a06, 1},
+ {0x10a0c, 0x10a13, 1},
+ {0x10a15, 0x10a17, 1},
+ {0x10a19, 0x10a35, 1},
+ {0x10a38, 0x10a3a, 1},
+ {0x10a3f, 0x10a48, 1},
+ {0x10a50, 0x10a58, 1},
+ },
+}
+
+var _Khitan_Small_Script = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x16fe4, 0x18b00, 6940},
+ {0x18b01, 0x18cd5, 1},
+ },
+}
+
+var _Khmer = &RangeTable{
+ R16: []Range16{
+ {0x1780, 0x17dd, 1},
+ {0x17e0, 0x17e9, 1},
+ {0x17f0, 0x17f9, 1},
+ {0x19e0, 0x19ff, 1},
+ },
+}
+
+var _Khojki = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11200, 0x11211, 1},
+ {0x11213, 0x11241, 1},
+ },
+}
+
+var _Khudawadi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x112b0, 0x112ea, 1},
+ {0x112f0, 0x112f9, 1},
+ },
+}
+
+var _Lao = &RangeTable{
+ R16: []Range16{
+ {0x0e81, 0x0e82, 1},
+ {0x0e84, 0x0e86, 2},
+ {0x0e87, 0x0e8a, 1},
+ {0x0e8c, 0x0ea3, 1},
+ {0x0ea5, 0x0ea7, 2},
+ {0x0ea8, 0x0ebd, 1},
+ {0x0ec0, 0x0ec4, 1},
+ {0x0ec6, 0x0ec8, 2},
+ {0x0ec9, 0x0ece, 1},
+ {0x0ed0, 0x0ed9, 1},
+ {0x0edc, 0x0edf, 1},
+ },
+}
+
+var _Latin = &RangeTable{
+ R16: []Range16{
+ {0x0041, 0x005a, 1},
+ {0x0061, 0x007a, 1},
+ {0x00aa, 0x00ba, 16},
+ {0x00c0, 0x00d6, 1},
+ {0x00d8, 0x00f6, 1},
+ {0x00f8, 0x02b8, 1},
+ {0x02e0, 0x02e4, 1},
+ {0x1d00, 0x1d25, 1},
+ {0x1d2c, 0x1d5c, 1},
+ {0x1d62, 0x1d65, 1},
+ {0x1d6b, 0x1d77, 1},
+ {0x1d79, 0x1dbe, 1},
+ {0x1e00, 0x1eff, 1},
+ {0x2071, 0x207f, 14},
+ {0x2090, 0x209c, 1},
+ {0x212a, 0x212b, 1},
+ {0x2132, 0x214e, 28},
+ {0x2160, 0x2188, 1},
+ {0x2c60, 0x2c7f, 1},
+ {0xa722, 0xa787, 1},
+ {0xa78b, 0xa7ca, 1},
+ {0xa7d0, 0xa7d1, 1},
+ {0xa7d3, 0xa7d5, 2},
+ {0xa7d6, 0xa7d9, 1},
+ {0xa7f2, 0xa7ff, 1},
+ {0xab30, 0xab5a, 1},
+ {0xab5c, 0xab64, 1},
+ {0xab66, 0xab69, 1},
+ {0xfb00, 0xfb06, 1},
+ {0xff21, 0xff3a, 1},
+ {0xff41, 0xff5a, 1},
+ },
+ R32: []Range32{
+ {0x10780, 0x10785, 1},
+ {0x10787, 0x107b0, 1},
+ {0x107b2, 0x107ba, 1},
+ {0x1df00, 0x1df1e, 1},
+ {0x1df25, 0x1df2a, 1},
+ },
+ LatinOffset: 5,
+}
+
+var _Lepcha = &RangeTable{
+ R16: []Range16{
+ {0x1c00, 0x1c37, 1},
+ {0x1c3b, 0x1c49, 1},
+ {0x1c4d, 0x1c4f, 1},
+ },
+}
+
+var _Limbu = &RangeTable{
+ R16: []Range16{
+ {0x1900, 0x191e, 1},
+ {0x1920, 0x192b, 1},
+ {0x1930, 0x193b, 1},
+ {0x1940, 0x1944, 4},
+ {0x1945, 0x194f, 1},
+ },
+}
+
+var _Linear_A = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10600, 0x10736, 1},
+ {0x10740, 0x10755, 1},
+ {0x10760, 0x10767, 1},
+ },
+}
+
+var _Linear_B = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10000, 0x1000b, 1},
+ {0x1000d, 0x10026, 1},
+ {0x10028, 0x1003a, 1},
+ {0x1003c, 0x1003d, 1},
+ {0x1003f, 0x1004d, 1},
+ {0x10050, 0x1005d, 1},
+ {0x10080, 0x100fa, 1},
+ },
+}
+
+var _Lisu = &RangeTable{
+ R16: []Range16{
+ {0xa4d0, 0xa4ff, 1},
+ },
+ R32: []Range32{
+ {0x11fb0, 0x11fb0, 1},
+ },
+}
+
+var _Lycian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10280, 0x1029c, 1},
+ },
+}
+
+var _Lydian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10920, 0x10939, 1},
+ {0x1093f, 0x1093f, 1},
+ },
+}
+
+var _Mahajani = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11150, 0x11176, 1},
+ },
+}
+
+var _Makasar = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11ee0, 0x11ef8, 1},
+ },
+}
+
+var _Malayalam = &RangeTable{
+ R16: []Range16{
+ {0x0d00, 0x0d0c, 1},
+ {0x0d0e, 0x0d10, 1},
+ {0x0d12, 0x0d44, 1},
+ {0x0d46, 0x0d48, 1},
+ {0x0d4a, 0x0d4f, 1},
+ {0x0d54, 0x0d63, 1},
+ {0x0d66, 0x0d7f, 1},
+ },
+}
+
+var _Mandaic = &RangeTable{
+ R16: []Range16{
+ {0x0840, 0x085b, 1},
+ {0x085e, 0x085e, 1},
+ },
+}
+
+var _Manichaean = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10ac0, 0x10ae6, 1},
+ {0x10aeb, 0x10af6, 1},
+ },
+}
+
+var _Marchen = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11c70, 0x11c8f, 1},
+ {0x11c92, 0x11ca7, 1},
+ {0x11ca9, 0x11cb6, 1},
+ },
+}
+
+var _Masaram_Gondi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11d00, 0x11d06, 1},
+ {0x11d08, 0x11d09, 1},
+ {0x11d0b, 0x11d36, 1},
+ {0x11d3a, 0x11d3c, 2},
+ {0x11d3d, 0x11d3f, 2},
+ {0x11d40, 0x11d47, 1},
+ {0x11d50, 0x11d59, 1},
+ },
+}
+
+var _Medefaidrin = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x16e40, 0x16e9a, 1},
+ },
+}
+
+var _Meetei_Mayek = &RangeTable{
+ R16: []Range16{
+ {0xaae0, 0xaaf6, 1},
+ {0xabc0, 0xabed, 1},
+ {0xabf0, 0xabf9, 1},
+ },
+}
+
+var _Mende_Kikakui = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x1e800, 0x1e8c4, 1},
+ {0x1e8c7, 0x1e8d6, 1},
+ },
+}
+
+var _Meroitic_Cursive = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x109a0, 0x109b7, 1},
+ {0x109bc, 0x109cf, 1},
+ {0x109d2, 0x109ff, 1},
+ },
+}
+
+var _Meroitic_Hieroglyphs = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10980, 0x1099f, 1},
+ },
+}
+
+var _Miao = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x16f00, 0x16f4a, 1},
+ {0x16f4f, 0x16f87, 1},
+ {0x16f8f, 0x16f9f, 1},
+ },
+}
+
+var _Modi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11600, 0x11644, 1},
+ {0x11650, 0x11659, 1},
+ },
+}
+
+var _Mongolian = &RangeTable{
+ R16: []Range16{
+ {0x1800, 0x1801, 1},
+ {0x1804, 0x1806, 2},
+ {0x1807, 0x1819, 1},
+ {0x1820, 0x1878, 1},
+ {0x1880, 0x18aa, 1},
+ },
+ R32: []Range32{
+ {0x11660, 0x1166c, 1},
+ },
+}
+
+var _Mro = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x16a40, 0x16a5e, 1},
+ {0x16a60, 0x16a69, 1},
+ {0x16a6e, 0x16a6f, 1},
+ },
+}
+
+var _Multani = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11280, 0x11286, 1},
+ {0x11288, 0x1128a, 2},
+ {0x1128b, 0x1128d, 1},
+ {0x1128f, 0x1129d, 1},
+ {0x1129f, 0x112a9, 1},
+ },
+}
+
+var _Myanmar = &RangeTable{
+ R16: []Range16{
+ {0x1000, 0x109f, 1},
+ {0xa9e0, 0xa9fe, 1},
+ {0xaa60, 0xaa7f, 1},
+ },
+}
+
+var _Nabataean = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10880, 0x1089e, 1},
+ {0x108a7, 0x108af, 1},
+ },
+}
+
+var _Nag_Mundari = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x1e4d0, 0x1e4f9, 1},
+ },
+}
+
+var _Nandinagari = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x119a0, 0x119a7, 1},
+ {0x119aa, 0x119d7, 1},
+ {0x119da, 0x119e4, 1},
+ },
+}
+
+var _New_Tai_Lue = &RangeTable{
+ R16: []Range16{
+ {0x1980, 0x19ab, 1},
+ {0x19b0, 0x19c9, 1},
+ {0x19d0, 0x19da, 1},
+ {0x19de, 0x19df, 1},
+ },
+}
+
+var _Newa = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11400, 0x1145b, 1},
+ {0x1145d, 0x11461, 1},
+ },
+}
+
+var _Nko = &RangeTable{
+ R16: []Range16{
+ {0x07c0, 0x07fa, 1},
+ {0x07fd, 0x07ff, 1},
+ },
+}
+
+var _Nushu = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x16fe1, 0x1b170, 16783},
+ {0x1b171, 0x1b2fb, 1},
+ },
+}
+
+var _Nyiakeng_Puachue_Hmong = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x1e100, 0x1e12c, 1},
+ {0x1e130, 0x1e13d, 1},
+ {0x1e140, 0x1e149, 1},
+ {0x1e14e, 0x1e14f, 1},
+ },
+}
+
+var _Ogham = &RangeTable{
+ R16: []Range16{
+ {0x1680, 0x169c, 1},
+ },
+}
+
+var _Ol_Chiki = &RangeTable{
+ R16: []Range16{
+ {0x1c50, 0x1c7f, 1},
+ },
+}
+
+var _Old_Hungarian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10c80, 0x10cb2, 1},
+ {0x10cc0, 0x10cf2, 1},
+ {0x10cfa, 0x10cff, 1},
+ },
+}
+
+var _Old_Italic = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10300, 0x10323, 1},
+ {0x1032d, 0x1032f, 1},
+ },
+}
+
+var _Old_North_Arabian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10a80, 0x10a9f, 1},
+ },
+}
+
+var _Old_Permic = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10350, 0x1037a, 1},
+ },
+}
+
+var _Old_Persian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x103a0, 0x103c3, 1},
+ {0x103c8, 0x103d5, 1},
+ },
+}
+
+var _Old_Sogdian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10f00, 0x10f27, 1},
+ },
+}
+
+var _Old_South_Arabian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10a60, 0x10a7f, 1},
+ },
+}
+
+var _Old_Turkic = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10c00, 0x10c48, 1},
+ },
+}
+
+var _Old_Uyghur = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10f70, 0x10f89, 1},
+ },
+}
+
+var _Oriya = &RangeTable{
+ R16: []Range16{
+ {0x0b01, 0x0b03, 1},
+ {0x0b05, 0x0b0c, 1},
+ {0x0b0f, 0x0b10, 1},
+ {0x0b13, 0x0b28, 1},
+ {0x0b2a, 0x0b30, 1},
+ {0x0b32, 0x0b33, 1},
+ {0x0b35, 0x0b39, 1},
+ {0x0b3c, 0x0b44, 1},
+ {0x0b47, 0x0b48, 1},
+ {0x0b4b, 0x0b4d, 1},
+ {0x0b55, 0x0b57, 1},
+ {0x0b5c, 0x0b5d, 1},
+ {0x0b5f, 0x0b63, 1},
+ {0x0b66, 0x0b77, 1},
+ },
+}
+
+var _Osage = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x104b0, 0x104d3, 1},
+ {0x104d8, 0x104fb, 1},
+ },
+}
+
+var _Osmanya = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10480, 0x1049d, 1},
+ {0x104a0, 0x104a9, 1},
+ },
+}
+
+var _Pahawh_Hmong = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x16b00, 0x16b45, 1},
+ {0x16b50, 0x16b59, 1},
+ {0x16b5b, 0x16b61, 1},
+ {0x16b63, 0x16b77, 1},
+ {0x16b7d, 0x16b8f, 1},
+ },
+}
+
+var _Palmyrene = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10860, 0x1087f, 1},
+ },
+}
+
+var _Pau_Cin_Hau = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11ac0, 0x11af8, 1},
+ },
+}
+
+var _Phags_Pa = &RangeTable{
+ R16: []Range16{
+ {0xa840, 0xa877, 1},
+ },
+}
+
+var _Phoenician = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10900, 0x1091b, 1},
+ {0x1091f, 0x1091f, 1},
+ },
+}
+
+var _Psalter_Pahlavi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10b80, 0x10b91, 1},
+ {0x10b99, 0x10b9c, 1},
+ {0x10ba9, 0x10baf, 1},
+ },
+}
+
+var _Rejang = &RangeTable{
+ R16: []Range16{
+ {0xa930, 0xa953, 1},
+ {0xa95f, 0xa95f, 1},
+ },
+}
+
+var _Runic = &RangeTable{
+ R16: []Range16{
+ {0x16a0, 0x16ea, 1},
+ {0x16ee, 0x16f8, 1},
+ },
+}
+
+var _Samaritan = &RangeTable{
+ R16: []Range16{
+ {0x0800, 0x082d, 1},
+ {0x0830, 0x083e, 1},
+ },
+}
+
+var _Saurashtra = &RangeTable{
+ R16: []Range16{
+ {0xa880, 0xa8c5, 1},
+ {0xa8ce, 0xa8d9, 1},
+ },
+}
+
+var _Sharada = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11180, 0x111df, 1},
+ },
+}
+
+var _Shavian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10450, 0x1047f, 1},
+ },
+}
+
+var _Siddham = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11580, 0x115b5, 1},
+ {0x115b8, 0x115dd, 1},
+ },
+}
+
+var _SignWriting = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x1d800, 0x1da8b, 1},
+ {0x1da9b, 0x1da9f, 1},
+ {0x1daa1, 0x1daaf, 1},
+ },
+}
+
+var _Sinhala = &RangeTable{
+ R16: []Range16{
+ {0x0d81, 0x0d83, 1},
+ {0x0d85, 0x0d96, 1},
+ {0x0d9a, 0x0db1, 1},
+ {0x0db3, 0x0dbb, 1},
+ {0x0dbd, 0x0dc0, 3},
+ {0x0dc1, 0x0dc6, 1},
+ {0x0dca, 0x0dcf, 5},
+ {0x0dd0, 0x0dd4, 1},
+ {0x0dd6, 0x0dd8, 2},
+ {0x0dd9, 0x0ddf, 1},
+ {0x0de6, 0x0def, 1},
+ {0x0df2, 0x0df4, 1},
+ },
+ R32: []Range32{
+ {0x111e1, 0x111f4, 1},
+ },
+}
+
+var _Sogdian = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10f30, 0x10f59, 1},
+ },
+}
+
+var _Sora_Sompeng = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x110d0, 0x110e8, 1},
+ {0x110f0, 0x110f9, 1},
+ },
+}
+
+var _Soyombo = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11a50, 0x11aa2, 1},
+ },
+}
+
+var _Sundanese = &RangeTable{
+ R16: []Range16{
+ {0x1b80, 0x1bbf, 1},
+ {0x1cc0, 0x1cc7, 1},
+ },
+}
+
+var _Syloti_Nagri = &RangeTable{
+ R16: []Range16{
+ {0xa800, 0xa82c, 1},
+ },
+}
+
+var _Syriac = &RangeTable{
+ R16: []Range16{
+ {0x0700, 0x070d, 1},
+ {0x070f, 0x074a, 1},
+ {0x074d, 0x074f, 1},
+ {0x0860, 0x086a, 1},
+ },
+}
+
+var _Tagalog = &RangeTable{
+ R16: []Range16{
+ {0x1700, 0x1715, 1},
+ {0x171f, 0x171f, 1},
+ },
+}
+
+var _Tagbanwa = &RangeTable{
+ R16: []Range16{
+ {0x1760, 0x176c, 1},
+ {0x176e, 0x1770, 1},
+ {0x1772, 0x1773, 1},
+ },
+}
+
+var _Tai_Le = &RangeTable{
+ R16: []Range16{
+ {0x1950, 0x196d, 1},
+ {0x1970, 0x1974, 1},
+ },
+}
+
+var _Tai_Tham = &RangeTable{
+ R16: []Range16{
+ {0x1a20, 0x1a5e, 1},
+ {0x1a60, 0x1a7c, 1},
+ {0x1a7f, 0x1a89, 1},
+ {0x1a90, 0x1a99, 1},
+ {0x1aa0, 0x1aad, 1},
+ },
+}
+
+var _Tai_Viet = &RangeTable{
+ R16: []Range16{
+ {0xaa80, 0xaac2, 1},
+ {0xaadb, 0xaadf, 1},
+ },
+}
+
+var _Takri = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11680, 0x116b9, 1},
+ {0x116c0, 0x116c9, 1},
+ },
+}
+
+var _Tamil = &RangeTable{
+ R16: []Range16{
+ {0x0b82, 0x0b83, 1},
+ {0x0b85, 0x0b8a, 1},
+ {0x0b8e, 0x0b90, 1},
+ {0x0b92, 0x0b95, 1},
+ {0x0b99, 0x0b9a, 1},
+ {0x0b9c, 0x0b9e, 2},
+ {0x0b9f, 0x0ba3, 4},
+ {0x0ba4, 0x0ba8, 4},
+ {0x0ba9, 0x0baa, 1},
+ {0x0bae, 0x0bb9, 1},
+ {0x0bbe, 0x0bc2, 1},
+ {0x0bc6, 0x0bc8, 1},
+ {0x0bca, 0x0bcd, 1},
+ {0x0bd0, 0x0bd7, 7},
+ {0x0be6, 0x0bfa, 1},
+ },
+ R32: []Range32{
+ {0x11fc0, 0x11ff1, 1},
+ {0x11fff, 0x11fff, 1},
+ },
+}
+
+var _Tangsa = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x16a70, 0x16abe, 1},
+ {0x16ac0, 0x16ac9, 1},
+ },
+}
+
+var _Tangut = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x16fe0, 0x17000, 32},
+ {0x17001, 0x187f7, 1},
+ {0x18800, 0x18aff, 1},
+ {0x18d00, 0x18d08, 1},
+ },
+}
+
+var _Telugu = &RangeTable{
+ R16: []Range16{
+ {0x0c00, 0x0c0c, 1},
+ {0x0c0e, 0x0c10, 1},
+ {0x0c12, 0x0c28, 1},
+ {0x0c2a, 0x0c39, 1},
+ {0x0c3c, 0x0c44, 1},
+ {0x0c46, 0x0c48, 1},
+ {0x0c4a, 0x0c4d, 1},
+ {0x0c55, 0x0c56, 1},
+ {0x0c58, 0x0c5a, 1},
+ {0x0c5d, 0x0c60, 3},
+ {0x0c61, 0x0c63, 1},
+ {0x0c66, 0x0c6f, 1},
+ {0x0c77, 0x0c7f, 1},
+ },
+}
+
+var _Thaana = &RangeTable{
+ R16: []Range16{
+ {0x0780, 0x07b1, 1},
+ },
+}
+
+var _Thai = &RangeTable{
+ R16: []Range16{
+ {0x0e01, 0x0e3a, 1},
+ {0x0e40, 0x0e5b, 1},
+ },
+}
+
+var _Tibetan = &RangeTable{
+ R16: []Range16{
+ {0x0f00, 0x0f47, 1},
+ {0x0f49, 0x0f6c, 1},
+ {0x0f71, 0x0f97, 1},
+ {0x0f99, 0x0fbc, 1},
+ {0x0fbe, 0x0fcc, 1},
+ {0x0fce, 0x0fd4, 1},
+ {0x0fd9, 0x0fda, 1},
+ },
+}
+
+var _Tifinagh = &RangeTable{
+ R16: []Range16{
+ {0x2d30, 0x2d67, 1},
+ {0x2d6f, 0x2d70, 1},
+ {0x2d7f, 0x2d7f, 1},
+ },
+}
+
+var _Tirhuta = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11480, 0x114c7, 1},
+ {0x114d0, 0x114d9, 1},
+ },
+}
+
+var _Toto = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x1e290, 0x1e2ae, 1},
+ },
+}
+
+var _Ugaritic = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10380, 0x1039d, 1},
+ {0x1039f, 0x1039f, 1},
+ },
+}
+
+var _Vai = &RangeTable{
+ R16: []Range16{
+ {0xa500, 0xa62b, 1},
+ },
+}
+
+var _Vithkuqi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10570, 0x1057a, 1},
+ {0x1057c, 0x1058a, 1},
+ {0x1058c, 0x10592, 1},
+ {0x10594, 0x10595, 1},
+ {0x10597, 0x105a1, 1},
+ {0x105a3, 0x105b1, 1},
+ {0x105b3, 0x105b9, 1},
+ {0x105bb, 0x105bc, 1},
+ },
+}
+
+var _Wancho = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x1e2c0, 0x1e2f9, 1},
+ {0x1e2ff, 0x1e2ff, 1},
+ },
+}
+
+var _Warang_Citi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x118a0, 0x118f2, 1},
+ {0x118ff, 0x118ff, 1},
+ },
+}
+
+var _Yezidi = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x10e80, 0x10ea9, 1},
+ {0x10eab, 0x10ead, 1},
+ {0x10eb0, 0x10eb1, 1},
+ },
+}
+
+var _Yi = &RangeTable{
+ R16: []Range16{
+ {0xa000, 0xa48c, 1},
+ {0xa490, 0xa4c6, 1},
+ },
+}
+
+var _Zanabazar_Square = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x11a00, 0x11a47, 1},
+ },
+}
+
+// These variables have type *RangeTable.
+var (
+ Adlam = _Adlam // Adlam is the set of Unicode characters in script Adlam.
+ Ahom = _Ahom // Ahom is the set of Unicode characters in script Ahom.
+ Anatolian_Hieroglyphs = _Anatolian_Hieroglyphs // Anatolian_Hieroglyphs is the set of Unicode characters in script Anatolian_Hieroglyphs.
+ Arabic = _Arabic // Arabic is the set of Unicode characters in script Arabic.
+ Armenian = _Armenian // Armenian is the set of Unicode characters in script Armenian.
+ Avestan = _Avestan // Avestan is the set of Unicode characters in script Avestan.
+ Balinese = _Balinese // Balinese is the set of Unicode characters in script Balinese.
+ Bamum = _Bamum // Bamum is the set of Unicode characters in script Bamum.
+ Bassa_Vah = _Bassa_Vah // Bassa_Vah is the set of Unicode characters in script Bassa_Vah.
+ Batak = _Batak // Batak is the set of Unicode characters in script Batak.
+ Bengali = _Bengali // Bengali is the set of Unicode characters in script Bengali.
+ Bhaiksuki = _Bhaiksuki // Bhaiksuki is the set of Unicode characters in script Bhaiksuki.
+ Bopomofo = _Bopomofo // Bopomofo is the set of Unicode characters in script Bopomofo.
+ Brahmi = _Brahmi // Brahmi is the set of Unicode characters in script Brahmi.
+ Braille = _Braille // Braille is the set of Unicode characters in script Braille.
+ Buginese = _Buginese // Buginese is the set of Unicode characters in script Buginese.
+ Buhid = _Buhid // Buhid is the set of Unicode characters in script Buhid.
+ Canadian_Aboriginal = _Canadian_Aboriginal // Canadian_Aboriginal is the set of Unicode characters in script Canadian_Aboriginal.
+ Carian = _Carian // Carian is the set of Unicode characters in script Carian.
+ Caucasian_Albanian = _Caucasian_Albanian // Caucasian_Albanian is the set of Unicode characters in script Caucasian_Albanian.
+ Chakma = _Chakma // Chakma is the set of Unicode characters in script Chakma.
+ Cham = _Cham // Cham is the set of Unicode characters in script Cham.
+ Cherokee = _Cherokee // Cherokee is the set of Unicode characters in script Cherokee.
+ Chorasmian = _Chorasmian // Chorasmian is the set of Unicode characters in script Chorasmian.
+ Common = _Common // Common is the set of Unicode characters in script Common.
+ Coptic = _Coptic // Coptic is the set of Unicode characters in script Coptic.
+ Cuneiform = _Cuneiform // Cuneiform is the set of Unicode characters in script Cuneiform.
+ Cypriot = _Cypriot // Cypriot is the set of Unicode characters in script Cypriot.
+ Cypro_Minoan = _Cypro_Minoan // Cypro_Minoan is the set of Unicode characters in script Cypro_Minoan.
+ Cyrillic = _Cyrillic // Cyrillic is the set of Unicode characters in script Cyrillic.
+ Deseret = _Deseret // Deseret is the set of Unicode characters in script Deseret.
+ Devanagari = _Devanagari // Devanagari is the set of Unicode characters in script Devanagari.
+ Dives_Akuru = _Dives_Akuru // Dives_Akuru is the set of Unicode characters in script Dives_Akuru.
+ Dogra = _Dogra // Dogra is the set of Unicode characters in script Dogra.
+ Duployan = _Duployan // Duployan is the set of Unicode characters in script Duployan.
+ Egyptian_Hieroglyphs = _Egyptian_Hieroglyphs // Egyptian_Hieroglyphs is the set of Unicode characters in script Egyptian_Hieroglyphs.
+ Elbasan = _Elbasan // Elbasan is the set of Unicode characters in script Elbasan.
+ Elymaic = _Elymaic // Elymaic is the set of Unicode characters in script Elymaic.
+ Ethiopic = _Ethiopic // Ethiopic is the set of Unicode characters in script Ethiopic.
+ Georgian = _Georgian // Georgian is the set of Unicode characters in script Georgian.
+ Glagolitic = _Glagolitic // Glagolitic is the set of Unicode characters in script Glagolitic.
+ Gothic = _Gothic // Gothic is the set of Unicode characters in script Gothic.
+ Grantha = _Grantha // Grantha is the set of Unicode characters in script Grantha.
+ Greek = _Greek // Greek is the set of Unicode characters in script Greek.
+ Gujarati = _Gujarati // Gujarati is the set of Unicode characters in script Gujarati.
+ Gunjala_Gondi = _Gunjala_Gondi // Gunjala_Gondi is the set of Unicode characters in script Gunjala_Gondi.
+ Gurmukhi = _Gurmukhi // Gurmukhi is the set of Unicode characters in script Gurmukhi.
+ Han = _Han // Han is the set of Unicode characters in script Han.
+ Hangul = _Hangul // Hangul is the set of Unicode characters in script Hangul.
+ Hanifi_Rohingya = _Hanifi_Rohingya // Hanifi_Rohingya is the set of Unicode characters in script Hanifi_Rohingya.
+ Hanunoo = _Hanunoo // Hanunoo is the set of Unicode characters in script Hanunoo.
+ Hatran = _Hatran // Hatran is the set of Unicode characters in script Hatran.
+ Hebrew = _Hebrew // Hebrew is the set of Unicode characters in script Hebrew.
+ Hiragana = _Hiragana // Hiragana is the set of Unicode characters in script Hiragana.
+ Imperial_Aramaic = _Imperial_Aramaic // Imperial_Aramaic is the set of Unicode characters in script Imperial_Aramaic.
+ Inherited = _Inherited // Inherited is the set of Unicode characters in script Inherited.
+ Inscriptional_Pahlavi = _Inscriptional_Pahlavi // Inscriptional_Pahlavi is the set of Unicode characters in script Inscriptional_Pahlavi.
+ Inscriptional_Parthian = _Inscriptional_Parthian // Inscriptional_Parthian is the set of Unicode characters in script Inscriptional_Parthian.
+ Javanese = _Javanese // Javanese is the set of Unicode characters in script Javanese.
+ Kaithi = _Kaithi // Kaithi is the set of Unicode characters in script Kaithi.
+ Kannada = _Kannada // Kannada is the set of Unicode characters in script Kannada.
+ Katakana = _Katakana // Katakana is the set of Unicode characters in script Katakana.
+ Kawi = _Kawi // Kawi is the set of Unicode characters in script Kawi.
+ Kayah_Li = _Kayah_Li // Kayah_Li is the set of Unicode characters in script Kayah_Li.
+ Kharoshthi = _Kharoshthi // Kharoshthi is the set of Unicode characters in script Kharoshthi.
+ Khitan_Small_Script = _Khitan_Small_Script // Khitan_Small_Script is the set of Unicode characters in script Khitan_Small_Script.
+ Khmer = _Khmer // Khmer is the set of Unicode characters in script Khmer.
+ Khojki = _Khojki // Khojki is the set of Unicode characters in script Khojki.
+ Khudawadi = _Khudawadi // Khudawadi is the set of Unicode characters in script Khudawadi.
+ Lao = _Lao // Lao is the set of Unicode characters in script Lao.
+ Latin = _Latin // Latin is the set of Unicode characters in script Latin.
+ Lepcha = _Lepcha // Lepcha is the set of Unicode characters in script Lepcha.
+ Limbu = _Limbu // Limbu is the set of Unicode characters in script Limbu.
+ Linear_A = _Linear_A // Linear_A is the set of Unicode characters in script Linear_A.
+ Linear_B = _Linear_B // Linear_B is the set of Unicode characters in script Linear_B.
+ Lisu = _Lisu // Lisu is the set of Unicode characters in script Lisu.
+ Lycian = _Lycian // Lycian is the set of Unicode characters in script Lycian.
+ Lydian = _Lydian // Lydian is the set of Unicode characters in script Lydian.
+ Mahajani = _Mahajani // Mahajani is the set of Unicode characters in script Mahajani.
+ Makasar = _Makasar // Makasar is the set of Unicode characters in script Makasar.
+ Malayalam = _Malayalam // Malayalam is the set of Unicode characters in script Malayalam.
+ Mandaic = _Mandaic // Mandaic is the set of Unicode characters in script Mandaic.
+ Manichaean = _Manichaean // Manichaean is the set of Unicode characters in script Manichaean.
+ Marchen = _Marchen // Marchen is the set of Unicode characters in script Marchen.
+ Masaram_Gondi = _Masaram_Gondi // Masaram_Gondi is the set of Unicode characters in script Masaram_Gondi.
+ Medefaidrin = _Medefaidrin // Medefaidrin is the set of Unicode characters in script Medefaidrin.
+ Meetei_Mayek = _Meetei_Mayek // Meetei_Mayek is the set of Unicode characters in script Meetei_Mayek.
+ Mende_Kikakui = _Mende_Kikakui // Mende_Kikakui is the set of Unicode characters in script Mende_Kikakui.
+ Meroitic_Cursive = _Meroitic_Cursive // Meroitic_Cursive is the set of Unicode characters in script Meroitic_Cursive.
+ Meroitic_Hieroglyphs = _Meroitic_Hieroglyphs // Meroitic_Hieroglyphs is the set of Unicode characters in script Meroitic_Hieroglyphs.
+ Miao = _Miao // Miao is the set of Unicode characters in script Miao.
+ Modi = _Modi // Modi is the set of Unicode characters in script Modi.
+ Mongolian = _Mongolian // Mongolian is the set of Unicode characters in script Mongolian.
+ Mro = _Mro // Mro is the set of Unicode characters in script Mro.
+ Multani = _Multani // Multani is the set of Unicode characters in script Multani.
+ Myanmar = _Myanmar // Myanmar is the set of Unicode characters in script Myanmar.
+ Nabataean = _Nabataean // Nabataean is the set of Unicode characters in script Nabataean.
+ Nag_Mundari = _Nag_Mundari // Nag_Mundari is the set of Unicode characters in script Nag_Mundari.
+ Nandinagari = _Nandinagari // Nandinagari is the set of Unicode characters in script Nandinagari.
+ New_Tai_Lue = _New_Tai_Lue // New_Tai_Lue is the set of Unicode characters in script New_Tai_Lue.
+ Newa = _Newa // Newa is the set of Unicode characters in script Newa.
+ Nko = _Nko // Nko is the set of Unicode characters in script Nko.
+ Nushu = _Nushu // Nushu is the set of Unicode characters in script Nushu.
+ Nyiakeng_Puachue_Hmong = _Nyiakeng_Puachue_Hmong // Nyiakeng_Puachue_Hmong is the set of Unicode characters in script Nyiakeng_Puachue_Hmong.
+ Ogham = _Ogham // Ogham is the set of Unicode characters in script Ogham.
+ Ol_Chiki = _Ol_Chiki // Ol_Chiki is the set of Unicode characters in script Ol_Chiki.
+ Old_Hungarian = _Old_Hungarian // Old_Hungarian is the set of Unicode characters in script Old_Hungarian.
+ Old_Italic = _Old_Italic // Old_Italic is the set of Unicode characters in script Old_Italic.
+ Old_North_Arabian = _Old_North_Arabian // Old_North_Arabian is the set of Unicode characters in script Old_North_Arabian.
+ Old_Permic = _Old_Permic // Old_Permic is the set of Unicode characters in script Old_Permic.
+ Old_Persian = _Old_Persian // Old_Persian is the set of Unicode characters in script Old_Persian.
+ Old_Sogdian = _Old_Sogdian // Old_Sogdian is the set of Unicode characters in script Old_Sogdian.
+ Old_South_Arabian = _Old_South_Arabian // Old_South_Arabian is the set of Unicode characters in script Old_South_Arabian.
+ Old_Turkic = _Old_Turkic // Old_Turkic is the set of Unicode characters in script Old_Turkic.
+ Old_Uyghur = _Old_Uyghur // Old_Uyghur is the set of Unicode characters in script Old_Uyghur.
+ Oriya = _Oriya // Oriya is the set of Unicode characters in script Oriya.
+ Osage = _Osage // Osage is the set of Unicode characters in script Osage.
+ Osmanya = _Osmanya // Osmanya is the set of Unicode characters in script Osmanya.
+ Pahawh_Hmong = _Pahawh_Hmong // Pahawh_Hmong is the set of Unicode characters in script Pahawh_Hmong.
+ Palmyrene = _Palmyrene // Palmyrene is the set of Unicode characters in script Palmyrene.
+ Pau_Cin_Hau = _Pau_Cin_Hau // Pau_Cin_Hau is the set of Unicode characters in script Pau_Cin_Hau.
+ Phags_Pa = _Phags_Pa // Phags_Pa is the set of Unicode characters in script Phags_Pa.
+ Phoenician = _Phoenician // Phoenician is the set of Unicode characters in script Phoenician.
+ Psalter_Pahlavi = _Psalter_Pahlavi // Psalter_Pahlavi is the set of Unicode characters in script Psalter_Pahlavi.
+ Rejang = _Rejang // Rejang is the set of Unicode characters in script Rejang.
+ Runic = _Runic // Runic is the set of Unicode characters in script Runic.
+ Samaritan = _Samaritan // Samaritan is the set of Unicode characters in script Samaritan.
+ Saurashtra = _Saurashtra // Saurashtra is the set of Unicode characters in script Saurashtra.
+ Sharada = _Sharada // Sharada is the set of Unicode characters in script Sharada.
+ Shavian = _Shavian // Shavian is the set of Unicode characters in script Shavian.
+ Siddham = _Siddham // Siddham is the set of Unicode characters in script Siddham.
+ SignWriting = _SignWriting // SignWriting is the set of Unicode characters in script SignWriting.
+ Sinhala = _Sinhala // Sinhala is the set of Unicode characters in script Sinhala.
+ Sogdian = _Sogdian // Sogdian is the set of Unicode characters in script Sogdian.
+ Sora_Sompeng = _Sora_Sompeng // Sora_Sompeng is the set of Unicode characters in script Sora_Sompeng.
+ Soyombo = _Soyombo // Soyombo is the set of Unicode characters in script Soyombo.
+ Sundanese = _Sundanese // Sundanese is the set of Unicode characters in script Sundanese.
+ Syloti_Nagri = _Syloti_Nagri // Syloti_Nagri is the set of Unicode characters in script Syloti_Nagri.
+ Syriac = _Syriac // Syriac is the set of Unicode characters in script Syriac.
+ Tagalog = _Tagalog // Tagalog is the set of Unicode characters in script Tagalog.
+ Tagbanwa = _Tagbanwa // Tagbanwa is the set of Unicode characters in script Tagbanwa.
+ Tai_Le = _Tai_Le // Tai_Le is the set of Unicode characters in script Tai_Le.
+ Tai_Tham = _Tai_Tham // Tai_Tham is the set of Unicode characters in script Tai_Tham.
+ Tai_Viet = _Tai_Viet // Tai_Viet is the set of Unicode characters in script Tai_Viet.
+ Takri = _Takri // Takri is the set of Unicode characters in script Takri.
+ Tamil = _Tamil // Tamil is the set of Unicode characters in script Tamil.
+ Tangsa = _Tangsa // Tangsa is the set of Unicode characters in script Tangsa.
+ Tangut = _Tangut // Tangut is the set of Unicode characters in script Tangut.
+ Telugu = _Telugu // Telugu is the set of Unicode characters in script Telugu.
+ Thaana = _Thaana // Thaana is the set of Unicode characters in script Thaana.
+ Thai = _Thai // Thai is the set of Unicode characters in script Thai.
+ Tibetan = _Tibetan // Tibetan is the set of Unicode characters in script Tibetan.
+ Tifinagh = _Tifinagh // Tifinagh is the set of Unicode characters in script Tifinagh.
+ Tirhuta = _Tirhuta // Tirhuta is the set of Unicode characters in script Tirhuta.
+ Toto = _Toto // Toto is the set of Unicode characters in script Toto.
+ Ugaritic = _Ugaritic // Ugaritic is the set of Unicode characters in script Ugaritic.
+ Vai = _Vai // Vai is the set of Unicode characters in script Vai.
+ Vithkuqi = _Vithkuqi // Vithkuqi is the set of Unicode characters in script Vithkuqi.
+ Wancho = _Wancho // Wancho is the set of Unicode characters in script Wancho.
+ Warang_Citi = _Warang_Citi // Warang_Citi is the set of Unicode characters in script Warang_Citi.
+ Yezidi = _Yezidi // Yezidi is the set of Unicode characters in script Yezidi.
+ Yi = _Yi // Yi is the set of Unicode characters in script Yi.
+ Zanabazar_Square = _Zanabazar_Square // Zanabazar_Square is the set of Unicode characters in script Zanabazar_Square.
+)
+
+// Properties is the set of Unicode property tables.
+var Properties = map[string]*RangeTable{
+ "ASCII_Hex_Digit": ASCII_Hex_Digit,
+ "Bidi_Control": Bidi_Control,
+ "Dash": Dash,
+ "Deprecated": Deprecated,
+ "Diacritic": Diacritic,
+ "Extender": Extender,
+ "Hex_Digit": Hex_Digit,
+ "Hyphen": Hyphen,
+ "IDS_Binary_Operator": IDS_Binary_Operator,
+ "IDS_Trinary_Operator": IDS_Trinary_Operator,
+ "Ideographic": Ideographic,
+ "Join_Control": Join_Control,
+ "Logical_Order_Exception": Logical_Order_Exception,
+ "Noncharacter_Code_Point": Noncharacter_Code_Point,
+ "Other_Alphabetic": Other_Alphabetic,
+ "Other_Default_Ignorable_Code_Point": Other_Default_Ignorable_Code_Point,
+ "Other_Grapheme_Extend": Other_Grapheme_Extend,
+ "Other_ID_Continue": Other_ID_Continue,
+ "Other_ID_Start": Other_ID_Start,
+ "Other_Lowercase": Other_Lowercase,
+ "Other_Math": Other_Math,
+ "Other_Uppercase": Other_Uppercase,
+ "Pattern_Syntax": Pattern_Syntax,
+ "Pattern_White_Space": Pattern_White_Space,
+ "Prepended_Concatenation_Mark": Prepended_Concatenation_Mark,
+ "Quotation_Mark": Quotation_Mark,
+ "Radical": Radical,
+ "Regional_Indicator": Regional_Indicator,
+ "Sentence_Terminal": Sentence_Terminal,
+ "STerm": Sentence_Terminal,
+ "Soft_Dotted": Soft_Dotted,
+ "Terminal_Punctuation": Terminal_Punctuation,
+ "Unified_Ideograph": Unified_Ideograph,
+ "Variation_Selector": Variation_Selector,
+ "White_Space": White_Space,
+}
+
+var _ASCII_Hex_Digit = &RangeTable{
+ R16: []Range16{
+ {0x0030, 0x0039, 1},
+ {0x0041, 0x0046, 1},
+ {0x0061, 0x0066, 1},
+ },
+ LatinOffset: 3,
+}
+
+var _Bidi_Control = &RangeTable{
+ R16: []Range16{
+ {0x061c, 0x200e, 6642},
+ {0x200f, 0x202a, 27},
+ {0x202b, 0x202e, 1},
+ {0x2066, 0x2069, 1},
+ },
+}
+
+var _Dash = &RangeTable{
+ R16: []Range16{
+ {0x002d, 0x058a, 1373},
+ {0x05be, 0x1400, 3650},
+ {0x1806, 0x2010, 2058},
+ {0x2011, 0x2015, 1},
+ {0x2053, 0x207b, 40},
+ {0x208b, 0x2212, 391},
+ {0x2e17, 0x2e1a, 3},
+ {0x2e3a, 0x2e3b, 1},
+ {0x2e40, 0x2e5d, 29},
+ {0x301c, 0x3030, 20},
+ {0x30a0, 0xfe31, 52625},
+ {0xfe32, 0xfe58, 38},
+ {0xfe63, 0xff0d, 170},
+ },
+ R32: []Range32{
+ {0x10ead, 0x10ead, 1},
+ },
+}
+
+var _Deprecated = &RangeTable{
+ R16: []Range16{
+ {0x0149, 0x0673, 1322},
+ {0x0f77, 0x0f79, 2},
+ {0x17a3, 0x17a4, 1},
+ {0x206a, 0x206f, 1},
+ {0x2329, 0x232a, 1},
+ },
+ R32: []Range32{
+ {0xe0001, 0xe0001, 1},
+ },
+}
+
+var _Diacritic = &RangeTable{
+ R16: []Range16{
+ {0x005e, 0x0060, 2},
+ {0x00a8, 0x00af, 7},
+ {0x00b4, 0x00b7, 3},
+ {0x00b8, 0x02b0, 504},
+ {0x02b1, 0x034e, 1},
+ {0x0350, 0x0357, 1},
+ {0x035d, 0x0362, 1},
+ {0x0374, 0x0375, 1},
+ {0x037a, 0x0384, 10},
+ {0x0385, 0x0483, 254},
+ {0x0484, 0x0487, 1},
+ {0x0559, 0x0591, 56},
+ {0x0592, 0x05a1, 1},
+ {0x05a3, 0x05bd, 1},
+ {0x05bf, 0x05c1, 2},
+ {0x05c2, 0x05c4, 2},
+ {0x064b, 0x0652, 1},
+ {0x0657, 0x0658, 1},
+ {0x06df, 0x06e0, 1},
+ {0x06e5, 0x06e6, 1},
+ {0x06ea, 0x06ec, 1},
+ {0x0730, 0x074a, 1},
+ {0x07a6, 0x07b0, 1},
+ {0x07eb, 0x07f5, 1},
+ {0x0818, 0x0819, 1},
+ {0x0898, 0x089f, 1},
+ {0x08c9, 0x08d2, 1},
+ {0x08e3, 0x08fe, 1},
+ {0x093c, 0x094d, 17},
+ {0x0951, 0x0954, 1},
+ {0x0971, 0x09bc, 75},
+ {0x09cd, 0x0a3c, 111},
+ {0x0a4d, 0x0abc, 111},
+ {0x0acd, 0x0afd, 48},
+ {0x0afe, 0x0aff, 1},
+ {0x0b3c, 0x0b4d, 17},
+ {0x0b55, 0x0bcd, 120},
+ {0x0c3c, 0x0c4d, 17},
+ {0x0cbc, 0x0ccd, 17},
+ {0x0d3b, 0x0d3c, 1},
+ {0x0d4d, 0x0e47, 125},
+ {0x0e48, 0x0e4c, 1},
+ {0x0e4e, 0x0eba, 108},
+ {0x0ec8, 0x0ecc, 1},
+ {0x0f18, 0x0f19, 1},
+ {0x0f35, 0x0f39, 2},
+ {0x0f3e, 0x0f3f, 1},
+ {0x0f82, 0x0f84, 1},
+ {0x0f86, 0x0f87, 1},
+ {0x0fc6, 0x1037, 113},
+ {0x1039, 0x103a, 1},
+ {0x1063, 0x1064, 1},
+ {0x1069, 0x106d, 1},
+ {0x1087, 0x108d, 1},
+ {0x108f, 0x109a, 11},
+ {0x109b, 0x135d, 706},
+ {0x135e, 0x135f, 1},
+ {0x1714, 0x1715, 1},
+ {0x17c9, 0x17d3, 1},
+ {0x17dd, 0x1939, 348},
+ {0x193a, 0x193b, 1},
+ {0x1a75, 0x1a7c, 1},
+ {0x1a7f, 0x1ab0, 49},
+ {0x1ab1, 0x1abe, 1},
+ {0x1ac1, 0x1acb, 1},
+ {0x1b34, 0x1b44, 16},
+ {0x1b6b, 0x1b73, 1},
+ {0x1baa, 0x1bab, 1},
+ {0x1c36, 0x1c37, 1},
+ {0x1c78, 0x1c7d, 1},
+ {0x1cd0, 0x1ce8, 1},
+ {0x1ced, 0x1cf4, 7},
+ {0x1cf7, 0x1cf9, 1},
+ {0x1d2c, 0x1d6a, 1},
+ {0x1dc4, 0x1dcf, 1},
+ {0x1df5, 0x1dff, 1},
+ {0x1fbd, 0x1fbf, 2},
+ {0x1fc0, 0x1fc1, 1},
+ {0x1fcd, 0x1fcf, 1},
+ {0x1fdd, 0x1fdf, 1},
+ {0x1fed, 0x1fef, 1},
+ {0x1ffd, 0x1ffe, 1},
+ {0x2cef, 0x2cf1, 1},
+ {0x2e2f, 0x302a, 507},
+ {0x302b, 0x302f, 1},
+ {0x3099, 0x309c, 1},
+ {0x30fc, 0xa66f, 30067},
+ {0xa67c, 0xa67d, 1},
+ {0xa67f, 0xa69c, 29},
+ {0xa69d, 0xa6f0, 83},
+ {0xa6f1, 0xa700, 15},
+ {0xa701, 0xa721, 1},
+ {0xa788, 0xa78a, 1},
+ {0xa7f8, 0xa7f9, 1},
+ {0xa8c4, 0xa8e0, 28},
+ {0xa8e1, 0xa8f1, 1},
+ {0xa92b, 0xa92e, 1},
+ {0xa953, 0xa9b3, 96},
+ {0xa9c0, 0xa9e5, 37},
+ {0xaa7b, 0xaa7d, 1},
+ {0xaabf, 0xaac2, 1},
+ {0xaaf6, 0xab5b, 101},
+ {0xab5c, 0xab5f, 1},
+ {0xab69, 0xab6b, 1},
+ {0xabec, 0xabed, 1},
+ {0xfb1e, 0xfe20, 770},
+ {0xfe21, 0xfe2f, 1},
+ {0xff3e, 0xff40, 2},
+ {0xff70, 0xff9e, 46},
+ {0xff9f, 0xffe3, 68},
+ },
+ R32: []Range32{
+ {0x102e0, 0x10780, 1184},
+ {0x10781, 0x10785, 1},
+ {0x10787, 0x107b0, 1},
+ {0x107b2, 0x107ba, 1},
+ {0x10ae5, 0x10ae6, 1},
+ {0x10d22, 0x10d27, 1},
+ {0x10efd, 0x10eff, 1},
+ {0x10f46, 0x10f50, 1},
+ {0x10f82, 0x10f85, 1},
+ {0x11046, 0x11070, 42},
+ {0x110b9, 0x110ba, 1},
+ {0x11133, 0x11134, 1},
+ {0x11173, 0x111c0, 77},
+ {0x111ca, 0x111cc, 1},
+ {0x11235, 0x11236, 1},
+ {0x112e9, 0x112ea, 1},
+ {0x1133c, 0x1134d, 17},
+ {0x11366, 0x1136c, 1},
+ {0x11370, 0x11374, 1},
+ {0x11442, 0x11446, 4},
+ {0x114c2, 0x114c3, 1},
+ {0x115bf, 0x115c0, 1},
+ {0x1163f, 0x116b6, 119},
+ {0x116b7, 0x1172b, 116},
+ {0x11839, 0x1183a, 1},
+ {0x1193d, 0x1193e, 1},
+ {0x11943, 0x119e0, 157},
+ {0x11a34, 0x11a47, 19},
+ {0x11a99, 0x11c3f, 422},
+ {0x11d42, 0x11d44, 2},
+ {0x11d45, 0x11d97, 82},
+ {0x13447, 0x13455, 1},
+ {0x16af0, 0x16af4, 1},
+ {0x16b30, 0x16b36, 1},
+ {0x16f8f, 0x16f9f, 1},
+ {0x16ff0, 0x16ff1, 1},
+ {0x1aff0, 0x1aff3, 1},
+ {0x1aff5, 0x1affb, 1},
+ {0x1affd, 0x1affe, 1},
+ {0x1cf00, 0x1cf2d, 1},
+ {0x1cf30, 0x1cf46, 1},
+ {0x1d167, 0x1d169, 1},
+ {0x1d16d, 0x1d172, 1},
+ {0x1d17b, 0x1d182, 1},
+ {0x1d185, 0x1d18b, 1},
+ {0x1d1aa, 0x1d1ad, 1},
+ {0x1e030, 0x1e06d, 1},
+ {0x1e130, 0x1e136, 1},
+ {0x1e2ae, 0x1e2ec, 62},
+ {0x1e2ed, 0x1e2ef, 1},
+ {0x1e8d0, 0x1e8d6, 1},
+ {0x1e944, 0x1e946, 1},
+ {0x1e948, 0x1e94a, 1},
+ },
+ LatinOffset: 3,
+}
+
+var _Extender = &RangeTable{
+ R16: []Range16{
+ {0x00b7, 0x02d0, 537},
+ {0x02d1, 0x0640, 879},
+ {0x07fa, 0x0b55, 859},
+ {0x0e46, 0x0ec6, 128},
+ {0x180a, 0x1843, 57},
+ {0x1aa7, 0x1c36, 399},
+ {0x1c7b, 0x3005, 5002},
+ {0x3031, 0x3035, 1},
+ {0x309d, 0x309e, 1},
+ {0x30fc, 0x30fe, 1},
+ {0xa015, 0xa60c, 1527},
+ {0xa9cf, 0xa9e6, 23},
+ {0xaa70, 0xaadd, 109},
+ {0xaaf3, 0xaaf4, 1},
+ {0xff70, 0xff70, 1},
+ },
+ R32: []Range32{
+ {0x10781, 0x10782, 1},
+ {0x1135d, 0x115c6, 617},
+ {0x115c7, 0x115c8, 1},
+ {0x11a98, 0x16b42, 20650},
+ {0x16b43, 0x16fe0, 1181},
+ {0x16fe1, 0x16fe3, 2},
+ {0x1e13c, 0x1e13d, 1},
+ {0x1e944, 0x1e946, 1},
+ },
+}
+
+var _Hex_Digit = &RangeTable{
+ R16: []Range16{
+ {0x0030, 0x0039, 1},
+ {0x0041, 0x0046, 1},
+ {0x0061, 0x0066, 1},
+ {0xff10, 0xff19, 1},
+ {0xff21, 0xff26, 1},
+ {0xff41, 0xff46, 1},
+ },
+ LatinOffset: 3,
+}
+
+var _Hyphen = &RangeTable{
+ R16: []Range16{
+ {0x002d, 0x00ad, 128},
+ {0x058a, 0x1806, 4732},
+ {0x2010, 0x2011, 1},
+ {0x2e17, 0x30fb, 740},
+ {0xfe63, 0xff0d, 170},
+ {0xff65, 0xff65, 1},
+ },
+ LatinOffset: 1,
+}
+
+var _IDS_Binary_Operator = &RangeTable{
+ R16: []Range16{
+ {0x2ff0, 0x2ff1, 1},
+ {0x2ff4, 0x2ffb, 1},
+ },
+}
+
+var _IDS_Trinary_Operator = &RangeTable{
+ R16: []Range16{
+ {0x2ff2, 0x2ff3, 1},
+ },
+}
+
+var _Ideographic = &RangeTable{
+ R16: []Range16{
+ {0x3006, 0x3007, 1},
+ {0x3021, 0x3029, 1},
+ {0x3038, 0x303a, 1},
+ {0x3400, 0x4dbf, 1},
+ {0x4e00, 0x9fff, 1},
+ {0xf900, 0xfa6d, 1},
+ {0xfa70, 0xfad9, 1},
+ },
+ R32: []Range32{
+ {0x16fe4, 0x17000, 28},
+ {0x17001, 0x187f7, 1},
+ {0x18800, 0x18cd5, 1},
+ {0x18d00, 0x18d08, 1},
+ {0x1b170, 0x1b2fb, 1},
+ {0x20000, 0x2a6df, 1},
+ {0x2a700, 0x2b739, 1},
+ {0x2b740, 0x2b81d, 1},
+ {0x2b820, 0x2cea1, 1},
+ {0x2ceb0, 0x2ebe0, 1},
+ {0x2f800, 0x2fa1d, 1},
+ {0x30000, 0x3134a, 1},
+ {0x31350, 0x323af, 1},
+ },
+}
+
+var _Join_Control = &RangeTable{
+ R16: []Range16{
+ {0x200c, 0x200d, 1},
+ },
+}
+
+var _Logical_Order_Exception = &RangeTable{
+ R16: []Range16{
+ {0x0e40, 0x0e44, 1},
+ {0x0ec0, 0x0ec4, 1},
+ {0x19b5, 0x19b7, 1},
+ {0x19ba, 0xaab5, 37115},
+ {0xaab6, 0xaab9, 3},
+ {0xaabb, 0xaabc, 1},
+ },
+}
+
+var _Noncharacter_Code_Point = &RangeTable{
+ R16: []Range16{
+ {0xfdd0, 0xfdef, 1},
+ {0xfffe, 0xffff, 1},
+ },
+ R32: []Range32{
+ {0x1fffe, 0x1ffff, 1},
+ {0x2fffe, 0x2ffff, 1},
+ {0x3fffe, 0x3ffff, 1},
+ {0x4fffe, 0x4ffff, 1},
+ {0x5fffe, 0x5ffff, 1},
+ {0x6fffe, 0x6ffff, 1},
+ {0x7fffe, 0x7ffff, 1},
+ {0x8fffe, 0x8ffff, 1},
+ {0x9fffe, 0x9ffff, 1},
+ {0xafffe, 0xaffff, 1},
+ {0xbfffe, 0xbffff, 1},
+ {0xcfffe, 0xcffff, 1},
+ {0xdfffe, 0xdffff, 1},
+ {0xefffe, 0xeffff, 1},
+ {0xffffe, 0xfffff, 1},
+ {0x10fffe, 0x10ffff, 1},
+ },
+}
+
+var _Other_Alphabetic = &RangeTable{
+ R16: []Range16{
+ {0x0345, 0x05b0, 619},
+ {0x05b1, 0x05bd, 1},
+ {0x05bf, 0x05c1, 2},
+ {0x05c2, 0x05c4, 2},
+ {0x05c5, 0x05c7, 2},
+ {0x0610, 0x061a, 1},
+ {0x064b, 0x0657, 1},
+ {0x0659, 0x065f, 1},
+ {0x0670, 0x06d6, 102},
+ {0x06d7, 0x06dc, 1},
+ {0x06e1, 0x06e4, 1},
+ {0x06e7, 0x06e8, 1},
+ {0x06ed, 0x0711, 36},
+ {0x0730, 0x073f, 1},
+ {0x07a6, 0x07b0, 1},
+ {0x0816, 0x0817, 1},
+ {0x081b, 0x0823, 1},
+ {0x0825, 0x0827, 1},
+ {0x0829, 0x082c, 1},
+ {0x08d4, 0x08df, 1},
+ {0x08e3, 0x08e9, 1},
+ {0x08f0, 0x0903, 1},
+ {0x093a, 0x093b, 1},
+ {0x093e, 0x094c, 1},
+ {0x094e, 0x094f, 1},
+ {0x0955, 0x0957, 1},
+ {0x0962, 0x0963, 1},
+ {0x0981, 0x0983, 1},
+ {0x09be, 0x09c4, 1},
+ {0x09c7, 0x09c8, 1},
+ {0x09cb, 0x09cc, 1},
+ {0x09d7, 0x09e2, 11},
+ {0x09e3, 0x0a01, 30},
+ {0x0a02, 0x0a03, 1},
+ {0x0a3e, 0x0a42, 1},
+ {0x0a47, 0x0a48, 1},
+ {0x0a4b, 0x0a4c, 1},
+ {0x0a51, 0x0a70, 31},
+ {0x0a71, 0x0a75, 4},
+ {0x0a81, 0x0a83, 1},
+ {0x0abe, 0x0ac5, 1},
+ {0x0ac7, 0x0ac9, 1},
+ {0x0acb, 0x0acc, 1},
+ {0x0ae2, 0x0ae3, 1},
+ {0x0afa, 0x0afc, 1},
+ {0x0b01, 0x0b03, 1},
+ {0x0b3e, 0x0b44, 1},
+ {0x0b47, 0x0b48, 1},
+ {0x0b4b, 0x0b4c, 1},
+ {0x0b56, 0x0b57, 1},
+ {0x0b62, 0x0b63, 1},
+ {0x0b82, 0x0bbe, 60},
+ {0x0bbf, 0x0bc2, 1},
+ {0x0bc6, 0x0bc8, 1},
+ {0x0bca, 0x0bcc, 1},
+ {0x0bd7, 0x0c00, 41},
+ {0x0c01, 0x0c04, 1},
+ {0x0c3e, 0x0c44, 1},
+ {0x0c46, 0x0c48, 1},
+ {0x0c4a, 0x0c4c, 1},
+ {0x0c55, 0x0c56, 1},
+ {0x0c62, 0x0c63, 1},
+ {0x0c81, 0x0c83, 1},
+ {0x0cbe, 0x0cc4, 1},
+ {0x0cc6, 0x0cc8, 1},
+ {0x0cca, 0x0ccc, 1},
+ {0x0cd5, 0x0cd6, 1},
+ {0x0ce2, 0x0ce3, 1},
+ {0x0cf3, 0x0d00, 13},
+ {0x0d01, 0x0d03, 1},
+ {0x0d3e, 0x0d44, 1},
+ {0x0d46, 0x0d48, 1},
+ {0x0d4a, 0x0d4c, 1},
+ {0x0d57, 0x0d62, 11},
+ {0x0d63, 0x0d81, 30},
+ {0x0d82, 0x0d83, 1},
+ {0x0dcf, 0x0dd4, 1},
+ {0x0dd6, 0x0dd8, 2},
+ {0x0dd9, 0x0ddf, 1},
+ {0x0df2, 0x0df3, 1},
+ {0x0e31, 0x0e34, 3},
+ {0x0e35, 0x0e3a, 1},
+ {0x0e4d, 0x0eb1, 100},
+ {0x0eb4, 0x0eb9, 1},
+ {0x0ebb, 0x0ebc, 1},
+ {0x0ecd, 0x0f71, 164},
+ {0x0f72, 0x0f83, 1},
+ {0x0f8d, 0x0f97, 1},
+ {0x0f99, 0x0fbc, 1},
+ {0x102b, 0x1036, 1},
+ {0x1038, 0x103b, 3},
+ {0x103c, 0x103e, 1},
+ {0x1056, 0x1059, 1},
+ {0x105e, 0x1060, 1},
+ {0x1062, 0x1064, 1},
+ {0x1067, 0x106d, 1},
+ {0x1071, 0x1074, 1},
+ {0x1082, 0x108d, 1},
+ {0x108f, 0x109a, 11},
+ {0x109b, 0x109d, 1},
+ {0x1712, 0x1713, 1},
+ {0x1732, 0x1733, 1},
+ {0x1752, 0x1753, 1},
+ {0x1772, 0x1773, 1},
+ {0x17b6, 0x17c8, 1},
+ {0x1885, 0x1886, 1},
+ {0x18a9, 0x1920, 119},
+ {0x1921, 0x192b, 1},
+ {0x1930, 0x1938, 1},
+ {0x1a17, 0x1a1b, 1},
+ {0x1a55, 0x1a5e, 1},
+ {0x1a61, 0x1a74, 1},
+ {0x1abf, 0x1ac0, 1},
+ {0x1acc, 0x1ace, 1},
+ {0x1b00, 0x1b04, 1},
+ {0x1b35, 0x1b43, 1},
+ {0x1b80, 0x1b82, 1},
+ {0x1ba1, 0x1ba9, 1},
+ {0x1bac, 0x1bad, 1},
+ {0x1be7, 0x1bf1, 1},
+ {0x1c24, 0x1c36, 1},
+ {0x1de7, 0x1df4, 1},
+ {0x24b6, 0x24e9, 1},
+ {0x2de0, 0x2dff, 1},
+ {0xa674, 0xa67b, 1},
+ {0xa69e, 0xa69f, 1},
+ {0xa802, 0xa80b, 9},
+ {0xa823, 0xa827, 1},
+ {0xa880, 0xa881, 1},
+ {0xa8b4, 0xa8c3, 1},
+ {0xa8c5, 0xa8ff, 58},
+ {0xa926, 0xa92a, 1},
+ {0xa947, 0xa952, 1},
+ {0xa980, 0xa983, 1},
+ {0xa9b4, 0xa9bf, 1},
+ {0xa9e5, 0xaa29, 68},
+ {0xaa2a, 0xaa36, 1},
+ {0xaa43, 0xaa4c, 9},
+ {0xaa4d, 0xaa7b, 46},
+ {0xaa7c, 0xaa7d, 1},
+ {0xaab0, 0xaab2, 2},
+ {0xaab3, 0xaab4, 1},
+ {0xaab7, 0xaab8, 1},
+ {0xaabe, 0xaaeb, 45},
+ {0xaaec, 0xaaef, 1},
+ {0xaaf5, 0xabe3, 238},
+ {0xabe4, 0xabea, 1},
+ {0xfb1e, 0xfb1e, 1},
+ },
+ R32: []Range32{
+ {0x10376, 0x1037a, 1},
+ {0x10a01, 0x10a03, 1},
+ {0x10a05, 0x10a06, 1},
+ {0x10a0c, 0x10a0f, 1},
+ {0x10d24, 0x10d27, 1},
+ {0x10eab, 0x10eac, 1},
+ {0x11000, 0x11002, 1},
+ {0x11038, 0x11045, 1},
+ {0x11073, 0x11074, 1},
+ {0x11080, 0x11082, 1},
+ {0x110b0, 0x110b8, 1},
+ {0x110c2, 0x11100, 62},
+ {0x11101, 0x11102, 1},
+ {0x11127, 0x11132, 1},
+ {0x11145, 0x11146, 1},
+ {0x11180, 0x11182, 1},
+ {0x111b3, 0x111bf, 1},
+ {0x111ce, 0x111cf, 1},
+ {0x1122c, 0x11234, 1},
+ {0x11237, 0x1123e, 7},
+ {0x11241, 0x112df, 158},
+ {0x112e0, 0x112e8, 1},
+ {0x11300, 0x11303, 1},
+ {0x1133e, 0x11344, 1},
+ {0x11347, 0x11348, 1},
+ {0x1134b, 0x1134c, 1},
+ {0x11357, 0x11362, 11},
+ {0x11363, 0x11435, 210},
+ {0x11436, 0x11441, 1},
+ {0x11443, 0x11445, 1},
+ {0x114b0, 0x114c1, 1},
+ {0x115af, 0x115b5, 1},
+ {0x115b8, 0x115be, 1},
+ {0x115dc, 0x115dd, 1},
+ {0x11630, 0x1163e, 1},
+ {0x11640, 0x116ab, 107},
+ {0x116ac, 0x116b5, 1},
+ {0x1171d, 0x1172a, 1},
+ {0x1182c, 0x11838, 1},
+ {0x11930, 0x11935, 1},
+ {0x11937, 0x11938, 1},
+ {0x1193b, 0x1193c, 1},
+ {0x11940, 0x11942, 2},
+ {0x119d1, 0x119d7, 1},
+ {0x119da, 0x119df, 1},
+ {0x119e4, 0x11a01, 29},
+ {0x11a02, 0x11a0a, 1},
+ {0x11a35, 0x11a39, 1},
+ {0x11a3b, 0x11a3e, 1},
+ {0x11a51, 0x11a5b, 1},
+ {0x11a8a, 0x11a97, 1},
+ {0x11c2f, 0x11c36, 1},
+ {0x11c38, 0x11c3e, 1},
+ {0x11c92, 0x11ca7, 1},
+ {0x11ca9, 0x11cb6, 1},
+ {0x11d31, 0x11d36, 1},
+ {0x11d3a, 0x11d3c, 2},
+ {0x11d3d, 0x11d3f, 2},
+ {0x11d40, 0x11d41, 1},
+ {0x11d43, 0x11d47, 4},
+ {0x11d8a, 0x11d8e, 1},
+ {0x11d90, 0x11d91, 1},
+ {0x11d93, 0x11d96, 1},
+ {0x11ef3, 0x11ef6, 1},
+ {0x11f00, 0x11f01, 1},
+ {0x11f03, 0x11f34, 49},
+ {0x11f35, 0x11f3a, 1},
+ {0x11f3e, 0x11f40, 1},
+ {0x16f4f, 0x16f51, 2},
+ {0x16f52, 0x16f87, 1},
+ {0x16f8f, 0x16f92, 1},
+ {0x16ff0, 0x16ff1, 1},
+ {0x1bc9e, 0x1e000, 9058},
+ {0x1e001, 0x1e006, 1},
+ {0x1e008, 0x1e018, 1},
+ {0x1e01b, 0x1e021, 1},
+ {0x1e023, 0x1e024, 1},
+ {0x1e026, 0x1e02a, 1},
+ {0x1e08f, 0x1e947, 2232},
+ {0x1f130, 0x1f149, 1},
+ {0x1f150, 0x1f169, 1},
+ {0x1f170, 0x1f189, 1},
+ },
+}
+
+var _Other_Default_Ignorable_Code_Point = &RangeTable{
+ R16: []Range16{
+ {0x034f, 0x115f, 3600},
+ {0x1160, 0x17b4, 1620},
+ {0x17b5, 0x2065, 2224},
+ {0x3164, 0xffa0, 52796},
+ {0xfff0, 0xfff8, 1},
+ },
+ R32: []Range32{
+ {0xe0000, 0xe0002, 2},
+ {0xe0003, 0xe001f, 1},
+ {0xe0080, 0xe00ff, 1},
+ {0xe01f0, 0xe0fff, 1},
+ },
+}
+
+var _Other_Grapheme_Extend = &RangeTable{
+ R16: []Range16{
+ {0x09be, 0x09d7, 25},
+ {0x0b3e, 0x0b57, 25},
+ {0x0bbe, 0x0bd7, 25},
+ {0x0cc2, 0x0cd5, 19},
+ {0x0cd6, 0x0d3e, 104},
+ {0x0d57, 0x0dcf, 120},
+ {0x0ddf, 0x1b35, 3414},
+ {0x200c, 0x302e, 4130},
+ {0x302f, 0xff9e, 53103},
+ {0xff9f, 0xff9f, 1},
+ },
+ R32: []Range32{
+ {0x1133e, 0x11357, 25},
+ {0x114b0, 0x114bd, 13},
+ {0x115af, 0x11930, 897},
+ {0x1d165, 0x1d16e, 9},
+ {0x1d16f, 0x1d172, 1},
+ {0xe0020, 0xe007f, 1},
+ },
+}
+
+var _Other_ID_Continue = &RangeTable{
+ R16: []Range16{
+ {0x00b7, 0x0387, 720},
+ {0x1369, 0x1371, 1},
+ {0x19da, 0x19da, 1},
+ },
+}
+
+var _Other_ID_Start = &RangeTable{
+ R16: []Range16{
+ {0x1885, 0x1886, 1},
+ {0x2118, 0x212e, 22},
+ {0x309b, 0x309c, 1},
+ },
+}
+
+var _Other_Lowercase = &RangeTable{
+ R16: []Range16{
+ {0x00aa, 0x00ba, 16},
+ {0x02b0, 0x02b8, 1},
+ {0x02c0, 0x02c1, 1},
+ {0x02e0, 0x02e4, 1},
+ {0x0345, 0x037a, 53},
+ {0x10fc, 0x1d2c, 3120},
+ {0x1d2d, 0x1d6a, 1},
+ {0x1d78, 0x1d9b, 35},
+ {0x1d9c, 0x1dbf, 1},
+ {0x2071, 0x207f, 14},
+ {0x2090, 0x209c, 1},
+ {0x2170, 0x217f, 1},
+ {0x24d0, 0x24e9, 1},
+ {0x2c7c, 0x2c7d, 1},
+ {0xa69c, 0xa69d, 1},
+ {0xa770, 0xa7f2, 130},
+ {0xa7f3, 0xa7f4, 1},
+ {0xa7f8, 0xa7f9, 1},
+ {0xab5c, 0xab5f, 1},
+ {0xab69, 0xab69, 1},
+ },
+ R32: []Range32{
+ {0x10780, 0x10783, 3},
+ {0x10784, 0x10785, 1},
+ {0x10787, 0x107b0, 1},
+ {0x107b2, 0x107ba, 1},
+ {0x1e030, 0x1e06d, 1},
+ },
+ LatinOffset: 1,
+}
+
+var _Other_Math = &RangeTable{
+ R16: []Range16{
+ {0x005e, 0x03d0, 882},
+ {0x03d1, 0x03d2, 1},
+ {0x03d5, 0x03f0, 27},
+ {0x03f1, 0x03f4, 3},
+ {0x03f5, 0x2016, 7201},
+ {0x2032, 0x2034, 1},
+ {0x2040, 0x2061, 33},
+ {0x2062, 0x2064, 1},
+ {0x207d, 0x207e, 1},
+ {0x208d, 0x208e, 1},
+ {0x20d0, 0x20dc, 1},
+ {0x20e1, 0x20e5, 4},
+ {0x20e6, 0x20eb, 5},
+ {0x20ec, 0x20ef, 1},
+ {0x2102, 0x2107, 5},
+ {0x210a, 0x2113, 1},
+ {0x2115, 0x2119, 4},
+ {0x211a, 0x211d, 1},
+ {0x2124, 0x2128, 4},
+ {0x2129, 0x212c, 3},
+ {0x212d, 0x212f, 2},
+ {0x2130, 0x2131, 1},
+ {0x2133, 0x2138, 1},
+ {0x213c, 0x213f, 1},
+ {0x2145, 0x2149, 1},
+ {0x2195, 0x2199, 1},
+ {0x219c, 0x219f, 1},
+ {0x21a1, 0x21a2, 1},
+ {0x21a4, 0x21a5, 1},
+ {0x21a7, 0x21a9, 2},
+ {0x21aa, 0x21ad, 1},
+ {0x21b0, 0x21b1, 1},
+ {0x21b6, 0x21b7, 1},
+ {0x21bc, 0x21cd, 1},
+ {0x21d0, 0x21d1, 1},
+ {0x21d3, 0x21d5, 2},
+ {0x21d6, 0x21db, 1},
+ {0x21dd, 0x21e4, 7},
+ {0x21e5, 0x2308, 291},
+ {0x2309, 0x230b, 1},
+ {0x23b4, 0x23b5, 1},
+ {0x23b7, 0x23d0, 25},
+ {0x23e2, 0x25a0, 446},
+ {0x25a1, 0x25ae, 13},
+ {0x25af, 0x25b6, 1},
+ {0x25bc, 0x25c0, 1},
+ {0x25c6, 0x25c7, 1},
+ {0x25ca, 0x25cb, 1},
+ {0x25cf, 0x25d3, 1},
+ {0x25e2, 0x25e4, 2},
+ {0x25e7, 0x25ec, 1},
+ {0x2605, 0x2606, 1},
+ {0x2640, 0x2642, 2},
+ {0x2660, 0x2663, 1},
+ {0x266d, 0x266e, 1},
+ {0x27c5, 0x27c6, 1},
+ {0x27e6, 0x27ef, 1},
+ {0x2983, 0x2998, 1},
+ {0x29d8, 0x29db, 1},
+ {0x29fc, 0x29fd, 1},
+ {0xfe61, 0xfe63, 2},
+ {0xfe68, 0xff3c, 212},
+ {0xff3e, 0xff3e, 1},
+ },
+ R32: []Range32{
+ {0x1d400, 0x1d454, 1},
+ {0x1d456, 0x1d49c, 1},
+ {0x1d49e, 0x1d49f, 1},
+ {0x1d4a2, 0x1d4a5, 3},
+ {0x1d4a6, 0x1d4a9, 3},
+ {0x1d4aa, 0x1d4ac, 1},
+ {0x1d4ae, 0x1d4b9, 1},
+ {0x1d4bb, 0x1d4bd, 2},
+ {0x1d4be, 0x1d4c3, 1},
+ {0x1d4c5, 0x1d505, 1},
+ {0x1d507, 0x1d50a, 1},
+ {0x1d50d, 0x1d514, 1},
+ {0x1d516, 0x1d51c, 1},
+ {0x1d51e, 0x1d539, 1},
+ {0x1d53b, 0x1d53e, 1},
+ {0x1d540, 0x1d544, 1},
+ {0x1d546, 0x1d54a, 4},
+ {0x1d54b, 0x1d550, 1},
+ {0x1d552, 0x1d6a5, 1},
+ {0x1d6a8, 0x1d6c0, 1},
+ {0x1d6c2, 0x1d6da, 1},
+ {0x1d6dc, 0x1d6fa, 1},
+ {0x1d6fc, 0x1d714, 1},
+ {0x1d716, 0x1d734, 1},
+ {0x1d736, 0x1d74e, 1},
+ {0x1d750, 0x1d76e, 1},
+ {0x1d770, 0x1d788, 1},
+ {0x1d78a, 0x1d7a8, 1},
+ {0x1d7aa, 0x1d7c2, 1},
+ {0x1d7c4, 0x1d7cb, 1},
+ {0x1d7ce, 0x1d7ff, 1},
+ {0x1ee00, 0x1ee03, 1},
+ {0x1ee05, 0x1ee1f, 1},
+ {0x1ee21, 0x1ee22, 1},
+ {0x1ee24, 0x1ee27, 3},
+ {0x1ee29, 0x1ee32, 1},
+ {0x1ee34, 0x1ee37, 1},
+ {0x1ee39, 0x1ee3b, 2},
+ {0x1ee42, 0x1ee47, 5},
+ {0x1ee49, 0x1ee4d, 2},
+ {0x1ee4e, 0x1ee4f, 1},
+ {0x1ee51, 0x1ee52, 1},
+ {0x1ee54, 0x1ee57, 3},
+ {0x1ee59, 0x1ee61, 2},
+ {0x1ee62, 0x1ee64, 2},
+ {0x1ee67, 0x1ee6a, 1},
+ {0x1ee6c, 0x1ee72, 1},
+ {0x1ee74, 0x1ee77, 1},
+ {0x1ee79, 0x1ee7c, 1},
+ {0x1ee7e, 0x1ee80, 2},
+ {0x1ee81, 0x1ee89, 1},
+ {0x1ee8b, 0x1ee9b, 1},
+ {0x1eea1, 0x1eea3, 1},
+ {0x1eea5, 0x1eea9, 1},
+ {0x1eeab, 0x1eebb, 1},
+ },
+}
+
+var _Other_Uppercase = &RangeTable{
+ R16: []Range16{
+ {0x2160, 0x216f, 1},
+ {0x24b6, 0x24cf, 1},
+ },
+ R32: []Range32{
+ {0x1f130, 0x1f149, 1},
+ {0x1f150, 0x1f169, 1},
+ {0x1f170, 0x1f189, 1},
+ },
+}
+
+var _Pattern_Syntax = &RangeTable{
+ R16: []Range16{
+ {0x0021, 0x002f, 1},
+ {0x003a, 0x0040, 1},
+ {0x005b, 0x005e, 1},
+ {0x0060, 0x007b, 27},
+ {0x007c, 0x007e, 1},
+ {0x00a1, 0x00a7, 1},
+ {0x00a9, 0x00ab, 2},
+ {0x00ac, 0x00b0, 2},
+ {0x00b1, 0x00bb, 5},
+ {0x00bf, 0x00d7, 24},
+ {0x00f7, 0x2010, 7961},
+ {0x2011, 0x2027, 1},
+ {0x2030, 0x203e, 1},
+ {0x2041, 0x2053, 1},
+ {0x2055, 0x205e, 1},
+ {0x2190, 0x245f, 1},
+ {0x2500, 0x2775, 1},
+ {0x2794, 0x2bff, 1},
+ {0x2e00, 0x2e7f, 1},
+ {0x3001, 0x3003, 1},
+ {0x3008, 0x3020, 1},
+ {0x3030, 0xfd3e, 52494},
+ {0xfd3f, 0xfe45, 262},
+ {0xfe46, 0xfe46, 1},
+ },
+ LatinOffset: 10,
+}
+
+var _Pattern_White_Space = &RangeTable{
+ R16: []Range16{
+ {0x0009, 0x000d, 1},
+ {0x0020, 0x0085, 101},
+ {0x200e, 0x200f, 1},
+ {0x2028, 0x2029, 1},
+ },
+ LatinOffset: 2,
+}
+
+var _Prepended_Concatenation_Mark = &RangeTable{
+ R16: []Range16{
+ {0x0600, 0x0605, 1},
+ {0x06dd, 0x070f, 50},
+ {0x0890, 0x0891, 1},
+ {0x08e2, 0x08e2, 1},
+ },
+ R32: []Range32{
+ {0x110bd, 0x110cd, 16},
+ },
+}
+
+var _Quotation_Mark = &RangeTable{
+ R16: []Range16{
+ {0x0022, 0x0027, 5},
+ {0x00ab, 0x00bb, 16},
+ {0x2018, 0x201f, 1},
+ {0x2039, 0x203a, 1},
+ {0x2e42, 0x300c, 458},
+ {0x300d, 0x300f, 1},
+ {0x301d, 0x301f, 1},
+ {0xfe41, 0xfe44, 1},
+ {0xff02, 0xff07, 5},
+ {0xff62, 0xff63, 1},
+ },
+ LatinOffset: 2,
+}
+
+var _Radical = &RangeTable{
+ R16: []Range16{
+ {0x2e80, 0x2e99, 1},
+ {0x2e9b, 0x2ef3, 1},
+ {0x2f00, 0x2fd5, 1},
+ },
+}
+
+var _Regional_Indicator = &RangeTable{
+ R16: []Range16{},
+ R32: []Range32{
+ {0x1f1e6, 0x1f1ff, 1},
+ },
+}
+
+var _Sentence_Terminal = &RangeTable{
+ R16: []Range16{
+ {0x0021, 0x002e, 13},
+ {0x003f, 0x0589, 1354},
+ {0x061d, 0x061f, 1},
+ {0x06d4, 0x0700, 44},
+ {0x0701, 0x0702, 1},
+ {0x07f9, 0x0837, 62},
+ {0x0839, 0x083d, 4},
+ {0x083e, 0x0964, 294},
+ {0x0965, 0x104a, 1765},
+ {0x104b, 0x1362, 791},
+ {0x1367, 0x1368, 1},
+ {0x166e, 0x1735, 199},
+ {0x1736, 0x1803, 205},
+ {0x1809, 0x1944, 315},
+ {0x1945, 0x1aa8, 355},
+ {0x1aa9, 0x1aab, 1},
+ {0x1b5a, 0x1b5b, 1},
+ {0x1b5e, 0x1b5f, 1},
+ {0x1b7d, 0x1b7e, 1},
+ {0x1c3b, 0x1c3c, 1},
+ {0x1c7e, 0x1c7f, 1},
+ {0x203c, 0x203d, 1},
+ {0x2047, 0x2049, 1},
+ {0x2e2e, 0x2e3c, 14},
+ {0x2e53, 0x2e54, 1},
+ {0x3002, 0xa4ff, 29949},
+ {0xa60e, 0xa60f, 1},
+ {0xa6f3, 0xa6f7, 4},
+ {0xa876, 0xa877, 1},
+ {0xa8ce, 0xa8cf, 1},
+ {0xa92f, 0xa9c8, 153},
+ {0xa9c9, 0xaa5d, 148},
+ {0xaa5e, 0xaa5f, 1},
+ {0xaaf0, 0xaaf1, 1},
+ {0xabeb, 0xfe52, 21095},
+ {0xfe56, 0xfe57, 1},
+ {0xff01, 0xff0e, 13},
+ {0xff1f, 0xff61, 66},
+ },
+ R32: []Range32{
+ {0x10a56, 0x10a57, 1},
+ {0x10f55, 0x10f59, 1},
+ {0x10f86, 0x10f89, 1},
+ {0x11047, 0x11048, 1},
+ {0x110be, 0x110c1, 1},
+ {0x11141, 0x11143, 1},
+ {0x111c5, 0x111c6, 1},
+ {0x111cd, 0x111de, 17},
+ {0x111df, 0x11238, 89},
+ {0x11239, 0x1123b, 2},
+ {0x1123c, 0x112a9, 109},
+ {0x1144b, 0x1144c, 1},
+ {0x115c2, 0x115c3, 1},
+ {0x115c9, 0x115d7, 1},
+ {0x11641, 0x11642, 1},
+ {0x1173c, 0x1173e, 1},
+ {0x11944, 0x11946, 2},
+ {0x11a42, 0x11a43, 1},
+ {0x11a9b, 0x11a9c, 1},
+ {0x11c41, 0x11c42, 1},
+ {0x11ef7, 0x11ef8, 1},
+ {0x11f43, 0x11f44, 1},
+ {0x16a6e, 0x16a6f, 1},
+ {0x16af5, 0x16b37, 66},
+ {0x16b38, 0x16b44, 12},
+ {0x16e98, 0x1bc9f, 19975},
+ {0x1da88, 0x1da88, 1},
+ },
+ LatinOffset: 1,
+}
+
+var _Soft_Dotted = &RangeTable{
+ R16: []Range16{
+ {0x0069, 0x006a, 1},
+ {0x012f, 0x0249, 282},
+ {0x0268, 0x029d, 53},
+ {0x02b2, 0x03f3, 321},
+ {0x0456, 0x0458, 2},
+ {0x1d62, 0x1d96, 52},
+ {0x1da4, 0x1da8, 4},
+ {0x1e2d, 0x1ecb, 158},
+ {0x2071, 0x2148, 215},
+ {0x2149, 0x2c7c, 2867},
+ },
+ R32: []Range32{
+ {0x1d422, 0x1d423, 1},
+ {0x1d456, 0x1d457, 1},
+ {0x1d48a, 0x1d48b, 1},
+ {0x1d4be, 0x1d4bf, 1},
+ {0x1d4f2, 0x1d4f3, 1},
+ {0x1d526, 0x1d527, 1},
+ {0x1d55a, 0x1d55b, 1},
+ {0x1d58e, 0x1d58f, 1},
+ {0x1d5c2, 0x1d5c3, 1},
+ {0x1d5f6, 0x1d5f7, 1},
+ {0x1d62a, 0x1d62b, 1},
+ {0x1d65e, 0x1d65f, 1},
+ {0x1d692, 0x1d693, 1},
+ {0x1df1a, 0x1e04c, 306},
+ {0x1e04d, 0x1e068, 27},
+ },
+ LatinOffset: 1,
+}
+
+var _Terminal_Punctuation = &RangeTable{
+ R16: []Range16{
+ {0x0021, 0x002c, 11},
+ {0x002e, 0x003a, 12},
+ {0x003b, 0x003f, 4},
+ {0x037e, 0x0387, 9},
+ {0x0589, 0x05c3, 58},
+ {0x060c, 0x061b, 15},
+ {0x061d, 0x061f, 1},
+ {0x06d4, 0x0700, 44},
+ {0x0701, 0x070a, 1},
+ {0x070c, 0x07f8, 236},
+ {0x07f9, 0x0830, 55},
+ {0x0831, 0x083e, 1},
+ {0x085e, 0x0964, 262},
+ {0x0965, 0x0e5a, 1269},
+ {0x0e5b, 0x0f08, 173},
+ {0x0f0d, 0x0f12, 1},
+ {0x104a, 0x104b, 1},
+ {0x1361, 0x1368, 1},
+ {0x166e, 0x16eb, 125},
+ {0x16ec, 0x16ed, 1},
+ {0x1735, 0x1736, 1},
+ {0x17d4, 0x17d6, 1},
+ {0x17da, 0x1802, 40},
+ {0x1803, 0x1805, 1},
+ {0x1808, 0x1809, 1},
+ {0x1944, 0x1945, 1},
+ {0x1aa8, 0x1aab, 1},
+ {0x1b5a, 0x1b5b, 1},
+ {0x1b5d, 0x1b5f, 1},
+ {0x1b7d, 0x1b7e, 1},
+ {0x1c3b, 0x1c3f, 1},
+ {0x1c7e, 0x1c7f, 1},
+ {0x203c, 0x203d, 1},
+ {0x2047, 0x2049, 1},
+ {0x2e2e, 0x2e3c, 14},
+ {0x2e41, 0x2e4c, 11},
+ {0x2e4e, 0x2e4f, 1},
+ {0x2e53, 0x2e54, 1},
+ {0x3001, 0x3002, 1},
+ {0xa4fe, 0xa4ff, 1},
+ {0xa60d, 0xa60f, 1},
+ {0xa6f3, 0xa6f7, 1},
+ {0xa876, 0xa877, 1},
+ {0xa8ce, 0xa8cf, 1},
+ {0xa92f, 0xa9c7, 152},
+ {0xa9c8, 0xa9c9, 1},
+ {0xaa5d, 0xaa5f, 1},
+ {0xaadf, 0xaaf0, 17},
+ {0xaaf1, 0xabeb, 250},
+ {0xfe50, 0xfe52, 1},
+ {0xfe54, 0xfe57, 1},
+ {0xff01, 0xff0c, 11},
+ {0xff0e, 0xff1a, 12},
+ {0xff1b, 0xff1f, 4},
+ {0xff61, 0xff64, 3},
+ },
+ R32: []Range32{
+ {0x1039f, 0x103d0, 49},
+ {0x10857, 0x1091f, 200},
+ {0x10a56, 0x10a57, 1},
+ {0x10af0, 0x10af5, 1},
+ {0x10b3a, 0x10b3f, 1},
+ {0x10b99, 0x10b9c, 1},
+ {0x10f55, 0x10f59, 1},
+ {0x10f86, 0x10f89, 1},
+ {0x11047, 0x1104d, 1},
+ {0x110be, 0x110c1, 1},
+ {0x11141, 0x11143, 1},
+ {0x111c5, 0x111c6, 1},
+ {0x111cd, 0x111de, 17},
+ {0x111df, 0x11238, 89},
+ {0x11239, 0x1123c, 1},
+ {0x112a9, 0x1144b, 418},
+ {0x1144c, 0x1144d, 1},
+ {0x1145a, 0x1145b, 1},
+ {0x115c2, 0x115c5, 1},
+ {0x115c9, 0x115d7, 1},
+ {0x11641, 0x11642, 1},
+ {0x1173c, 0x1173e, 1},
+ {0x11944, 0x11946, 2},
+ {0x11a42, 0x11a43, 1},
+ {0x11a9b, 0x11a9c, 1},
+ {0x11aa1, 0x11aa2, 1},
+ {0x11c41, 0x11c43, 1},
+ {0x11c71, 0x11ef7, 646},
+ {0x11ef8, 0x11f43, 75},
+ {0x11f44, 0x12470, 1324},
+ {0x12471, 0x12474, 1},
+ {0x16a6e, 0x16a6f, 1},
+ {0x16af5, 0x16b37, 66},
+ {0x16b38, 0x16b39, 1},
+ {0x16b44, 0x16e97, 851},
+ {0x16e98, 0x1bc9f, 19975},
+ {0x1da87, 0x1da8a, 1},
+ },
+ LatinOffset: 3,
+}
+
+var _Unified_Ideograph = &RangeTable{
+ R16: []Range16{
+ {0x3400, 0x4dbf, 1},
+ {0x4e00, 0x9fff, 1},
+ {0xfa0e, 0xfa0f, 1},
+ {0xfa11, 0xfa13, 2},
+ {0xfa14, 0xfa1f, 11},
+ {0xfa21, 0xfa23, 2},
+ {0xfa24, 0xfa27, 3},
+ {0xfa28, 0xfa29, 1},
+ },
+ R32: []Range32{
+ {0x20000, 0x2a6df, 1},
+ {0x2a700, 0x2b739, 1},
+ {0x2b740, 0x2b81d, 1},
+ {0x2b820, 0x2cea1, 1},
+ {0x2ceb0, 0x2ebe0, 1},
+ {0x30000, 0x3134a, 1},
+ {0x31350, 0x323af, 1},
+ },
+}
+
+var _Variation_Selector = &RangeTable{
+ R16: []Range16{
+ {0x180b, 0x180d, 1},
+ {0x180f, 0xfe00, 58865},
+ {0xfe01, 0xfe0f, 1},
+ },
+ R32: []Range32{
+ {0xe0100, 0xe01ef, 1},
+ },
+}
+
+var _White_Space = &RangeTable{
+ R16: []Range16{
+ {0x0009, 0x000d, 1},
+ {0x0020, 0x0085, 101},
+ {0x00a0, 0x1680, 5600},
+ {0x2000, 0x200a, 1},
+ {0x2028, 0x2029, 1},
+ {0x202f, 0x205f, 48},
+ {0x3000, 0x3000, 1},
+ },
+ LatinOffset: 2,
+}
+
+// These variables have type *RangeTable.
+var (
+ ASCII_Hex_Digit = _ASCII_Hex_Digit // ASCII_Hex_Digit is the set of Unicode characters with property ASCII_Hex_Digit.
+ Bidi_Control = _Bidi_Control // Bidi_Control is the set of Unicode characters with property Bidi_Control.
+ Dash = _Dash // Dash is the set of Unicode characters with property Dash.
+ Deprecated = _Deprecated // Deprecated is the set of Unicode characters with property Deprecated.
+ Diacritic = _Diacritic // Diacritic is the set of Unicode characters with property Diacritic.
+ Extender = _Extender // Extender is the set of Unicode characters with property Extender.
+ Hex_Digit = _Hex_Digit // Hex_Digit is the set of Unicode characters with property Hex_Digit.
+ Hyphen = _Hyphen // Hyphen is the set of Unicode characters with property Hyphen.
+ IDS_Binary_Operator = _IDS_Binary_Operator // IDS_Binary_Operator is the set of Unicode characters with property IDS_Binary_Operator.
+ IDS_Trinary_Operator = _IDS_Trinary_Operator // IDS_Trinary_Operator is the set of Unicode characters with property IDS_Trinary_Operator.
+ Ideographic = _Ideographic // Ideographic is the set of Unicode characters with property Ideographic.
+ Join_Control = _Join_Control // Join_Control is the set of Unicode characters with property Join_Control.
+ Logical_Order_Exception = _Logical_Order_Exception // Logical_Order_Exception is the set of Unicode characters with property Logical_Order_Exception.
+ Noncharacter_Code_Point = _Noncharacter_Code_Point // Noncharacter_Code_Point is the set of Unicode characters with property Noncharacter_Code_Point.
+ Other_Alphabetic = _Other_Alphabetic // Other_Alphabetic is the set of Unicode characters with property Other_Alphabetic.
+ Other_Default_Ignorable_Code_Point = _Other_Default_Ignorable_Code_Point // Other_Default_Ignorable_Code_Point is the set of Unicode characters with property Other_Default_Ignorable_Code_Point.
+ Other_Grapheme_Extend = _Other_Grapheme_Extend // Other_Grapheme_Extend is the set of Unicode characters with property Other_Grapheme_Extend.
+ Other_ID_Continue = _Other_ID_Continue // Other_ID_Continue is the set of Unicode characters with property Other_ID_Continue.
+ Other_ID_Start = _Other_ID_Start // Other_ID_Start is the set of Unicode characters with property Other_ID_Start.
+ Other_Lowercase = _Other_Lowercase // Other_Lowercase is the set of Unicode characters with property Other_Lowercase.
+ Other_Math = _Other_Math // Other_Math is the set of Unicode characters with property Other_Math.
+ Other_Uppercase = _Other_Uppercase // Other_Uppercase is the set of Unicode characters with property Other_Uppercase.
+ Pattern_Syntax = _Pattern_Syntax // Pattern_Syntax is the set of Unicode characters with property Pattern_Syntax.
+ Pattern_White_Space = _Pattern_White_Space // Pattern_White_Space is the set of Unicode characters with property Pattern_White_Space.
+ Prepended_Concatenation_Mark = _Prepended_Concatenation_Mark // Prepended_Concatenation_Mark is the set of Unicode characters with property Prepended_Concatenation_Mark.
+ Quotation_Mark = _Quotation_Mark // Quotation_Mark is the set of Unicode characters with property Quotation_Mark.
+ Radical = _Radical // Radical is the set of Unicode characters with property Radical.
+ Regional_Indicator = _Regional_Indicator // Regional_Indicator is the set of Unicode characters with property Regional_Indicator.
+ STerm = _Sentence_Terminal // STerm is an alias for Sentence_Terminal.
+ Sentence_Terminal = _Sentence_Terminal // Sentence_Terminal is the set of Unicode characters with property Sentence_Terminal.
+ Soft_Dotted = _Soft_Dotted // Soft_Dotted is the set of Unicode characters with property Soft_Dotted.
+ Terminal_Punctuation = _Terminal_Punctuation // Terminal_Punctuation is the set of Unicode characters with property Terminal_Punctuation.
+ Unified_Ideograph = _Unified_Ideograph // Unified_Ideograph is the set of Unicode characters with property Unified_Ideograph.
+ Variation_Selector = _Variation_Selector // Variation_Selector is the set of Unicode characters with property Variation_Selector.
+ White_Space = _White_Space // White_Space is the set of Unicode characters with property White_Space.
+)
+
+// CaseRanges is the table describing case mappings for all letters with
+// non-self mappings.
+var CaseRanges = _CaseRanges
+var _CaseRanges = []CaseRange{
+ {0x0041, 0x005A, d{0, 32, 0}},
+ {0x0061, 0x007A, d{-32, 0, -32}},
+ {0x00B5, 0x00B5, d{743, 0, 743}},
+ {0x00C0, 0x00D6, d{0, 32, 0}},
+ {0x00D8, 0x00DE, d{0, 32, 0}},
+ {0x00E0, 0x00F6, d{-32, 0, -32}},
+ {0x00F8, 0x00FE, d{-32, 0, -32}},
+ {0x00FF, 0x00FF, d{121, 0, 121}},
+ {0x0100, 0x012F, d{UpperLower, UpperLower, UpperLower}},
+ {0x0130, 0x0130, d{0, -199, 0}},
+ {0x0131, 0x0131, d{-232, 0, -232}},
+ {0x0132, 0x0137, d{UpperLower, UpperLower, UpperLower}},
+ {0x0139, 0x0148, d{UpperLower, UpperLower, UpperLower}},
+ {0x014A, 0x0177, d{UpperLower, UpperLower, UpperLower}},
+ {0x0178, 0x0178, d{0, -121, 0}},
+ {0x0179, 0x017E, d{UpperLower, UpperLower, UpperLower}},
+ {0x017F, 0x017F, d{-300, 0, -300}},
+ {0x0180, 0x0180, d{195, 0, 195}},
+ {0x0181, 0x0181, d{0, 210, 0}},
+ {0x0182, 0x0185, d{UpperLower, UpperLower, UpperLower}},
+ {0x0186, 0x0186, d{0, 206, 0}},
+ {0x0187, 0x0188, d{UpperLower, UpperLower, UpperLower}},
+ {0x0189, 0x018A, d{0, 205, 0}},
+ {0x018B, 0x018C, d{UpperLower, UpperLower, UpperLower}},
+ {0x018E, 0x018E, d{0, 79, 0}},
+ {0x018F, 0x018F, d{0, 202, 0}},
+ {0x0190, 0x0190, d{0, 203, 0}},
+ {0x0191, 0x0192, d{UpperLower, UpperLower, UpperLower}},
+ {0x0193, 0x0193, d{0, 205, 0}},
+ {0x0194, 0x0194, d{0, 207, 0}},
+ {0x0195, 0x0195, d{97, 0, 97}},
+ {0x0196, 0x0196, d{0, 211, 0}},
+ {0x0197, 0x0197, d{0, 209, 0}},
+ {0x0198, 0x0199, d{UpperLower, UpperLower, UpperLower}},
+ {0x019A, 0x019A, d{163, 0, 163}},
+ {0x019C, 0x019C, d{0, 211, 0}},
+ {0x019D, 0x019D, d{0, 213, 0}},
+ {0x019E, 0x019E, d{130, 0, 130}},
+ {0x019F, 0x019F, d{0, 214, 0}},
+ {0x01A0, 0x01A5, d{UpperLower, UpperLower, UpperLower}},
+ {0x01A6, 0x01A6, d{0, 218, 0}},
+ {0x01A7, 0x01A8, d{UpperLower, UpperLower, UpperLower}},
+ {0x01A9, 0x01A9, d{0, 218, 0}},
+ {0x01AC, 0x01AD, d{UpperLower, UpperLower, UpperLower}},
+ {0x01AE, 0x01AE, d{0, 218, 0}},
+ {0x01AF, 0x01B0, d{UpperLower, UpperLower, UpperLower}},
+ {0x01B1, 0x01B2, d{0, 217, 0}},
+ {0x01B3, 0x01B6, d{UpperLower, UpperLower, UpperLower}},
+ {0x01B7, 0x01B7, d{0, 219, 0}},
+ {0x01B8, 0x01B9, d{UpperLower, UpperLower, UpperLower}},
+ {0x01BC, 0x01BD, d{UpperLower, UpperLower, UpperLower}},
+ {0x01BF, 0x01BF, d{56, 0, 56}},
+ {0x01C4, 0x01C4, d{0, 2, 1}},
+ {0x01C5, 0x01C5, d{-1, 1, 0}},
+ {0x01C6, 0x01C6, d{-2, 0, -1}},
+ {0x01C7, 0x01C7, d{0, 2, 1}},
+ {0x01C8, 0x01C8, d{-1, 1, 0}},
+ {0x01C9, 0x01C9, d{-2, 0, -1}},
+ {0x01CA, 0x01CA, d{0, 2, 1}},
+ {0x01CB, 0x01CB, d{-1, 1, 0}},
+ {0x01CC, 0x01CC, d{-2, 0, -1}},
+ {0x01CD, 0x01DC, d{UpperLower, UpperLower, UpperLower}},
+ {0x01DD, 0x01DD, d{-79, 0, -79}},
+ {0x01DE, 0x01EF, d{UpperLower, UpperLower, UpperLower}},
+ {0x01F1, 0x01F1, d{0, 2, 1}},
+ {0x01F2, 0x01F2, d{-1, 1, 0}},
+ {0x01F3, 0x01F3, d{-2, 0, -1}},
+ {0x01F4, 0x01F5, d{UpperLower, UpperLower, UpperLower}},
+ {0x01F6, 0x01F6, d{0, -97, 0}},
+ {0x01F7, 0x01F7, d{0, -56, 0}},
+ {0x01F8, 0x021F, d{UpperLower, UpperLower, UpperLower}},
+ {0x0220, 0x0220, d{0, -130, 0}},
+ {0x0222, 0x0233, d{UpperLower, UpperLower, UpperLower}},
+ {0x023A, 0x023A, d{0, 10795, 0}},
+ {0x023B, 0x023C, d{UpperLower, UpperLower, UpperLower}},
+ {0x023D, 0x023D, d{0, -163, 0}},
+ {0x023E, 0x023E, d{0, 10792, 0}},
+ {0x023F, 0x0240, d{10815, 0, 10815}},
+ {0x0241, 0x0242, d{UpperLower, UpperLower, UpperLower}},
+ {0x0243, 0x0243, d{0, -195, 0}},
+ {0x0244, 0x0244, d{0, 69, 0}},
+ {0x0245, 0x0245, d{0, 71, 0}},
+ {0x0246, 0x024F, d{UpperLower, UpperLower, UpperLower}},
+ {0x0250, 0x0250, d{10783, 0, 10783}},
+ {0x0251, 0x0251, d{10780, 0, 10780}},
+ {0x0252, 0x0252, d{10782, 0, 10782}},
+ {0x0253, 0x0253, d{-210, 0, -210}},
+ {0x0254, 0x0254, d{-206, 0, -206}},
+ {0x0256, 0x0257, d{-205, 0, -205}},
+ {0x0259, 0x0259, d{-202, 0, -202}},
+ {0x025B, 0x025B, d{-203, 0, -203}},
+ {0x025C, 0x025C, d{42319, 0, 42319}},
+ {0x0260, 0x0260, d{-205, 0, -205}},
+ {0x0261, 0x0261, d{42315, 0, 42315}},
+ {0x0263, 0x0263, d{-207, 0, -207}},
+ {0x0265, 0x0265, d{42280, 0, 42280}},
+ {0x0266, 0x0266, d{42308, 0, 42308}},
+ {0x0268, 0x0268, d{-209, 0, -209}},
+ {0x0269, 0x0269, d{-211, 0, -211}},
+ {0x026A, 0x026A, d{42308, 0, 42308}},
+ {0x026B, 0x026B, d{10743, 0, 10743}},
+ {0x026C, 0x026C, d{42305, 0, 42305}},
+ {0x026F, 0x026F, d{-211, 0, -211}},
+ {0x0271, 0x0271, d{10749, 0, 10749}},
+ {0x0272, 0x0272, d{-213, 0, -213}},
+ {0x0275, 0x0275, d{-214, 0, -214}},
+ {0x027D, 0x027D, d{10727, 0, 10727}},
+ {0x0280, 0x0280, d{-218, 0, -218}},
+ {0x0282, 0x0282, d{42307, 0, 42307}},
+ {0x0283, 0x0283, d{-218, 0, -218}},
+ {0x0287, 0x0287, d{42282, 0, 42282}},
+ {0x0288, 0x0288, d{-218, 0, -218}},
+ {0x0289, 0x0289, d{-69, 0, -69}},
+ {0x028A, 0x028B, d{-217, 0, -217}},
+ {0x028C, 0x028C, d{-71, 0, -71}},
+ {0x0292, 0x0292, d{-219, 0, -219}},
+ {0x029D, 0x029D, d{42261, 0, 42261}},
+ {0x029E, 0x029E, d{42258, 0, 42258}},
+ {0x0345, 0x0345, d{84, 0, 84}},
+ {0x0370, 0x0373, d{UpperLower, UpperLower, UpperLower}},
+ {0x0376, 0x0377, d{UpperLower, UpperLower, UpperLower}},
+ {0x037B, 0x037D, d{130, 0, 130}},
+ {0x037F, 0x037F, d{0, 116, 0}},
+ {0x0386, 0x0386, d{0, 38, 0}},
+ {0x0388, 0x038A, d{0, 37, 0}},
+ {0x038C, 0x038C, d{0, 64, 0}},
+ {0x038E, 0x038F, d{0, 63, 0}},
+ {0x0391, 0x03A1, d{0, 32, 0}},
+ {0x03A3, 0x03AB, d{0, 32, 0}},
+ {0x03AC, 0x03AC, d{-38, 0, -38}},
+ {0x03AD, 0x03AF, d{-37, 0, -37}},
+ {0x03B1, 0x03C1, d{-32, 0, -32}},
+ {0x03C2, 0x03C2, d{-31, 0, -31}},
+ {0x03C3, 0x03CB, d{-32, 0, -32}},
+ {0x03CC, 0x03CC, d{-64, 0, -64}},
+ {0x03CD, 0x03CE, d{-63, 0, -63}},
+ {0x03CF, 0x03CF, d{0, 8, 0}},
+ {0x03D0, 0x03D0, d{-62, 0, -62}},
+ {0x03D1, 0x03D1, d{-57, 0, -57}},
+ {0x03D5, 0x03D5, d{-47, 0, -47}},
+ {0x03D6, 0x03D6, d{-54, 0, -54}},
+ {0x03D7, 0x03D7, d{-8, 0, -8}},
+ {0x03D8, 0x03EF, d{UpperLower, UpperLower, UpperLower}},
+ {0x03F0, 0x03F0, d{-86, 0, -86}},
+ {0x03F1, 0x03F1, d{-80, 0, -80}},
+ {0x03F2, 0x03F2, d{7, 0, 7}},
+ {0x03F3, 0x03F3, d{-116, 0, -116}},
+ {0x03F4, 0x03F4, d{0, -60, 0}},
+ {0x03F5, 0x03F5, d{-96, 0, -96}},
+ {0x03F7, 0x03F8, d{UpperLower, UpperLower, UpperLower}},
+ {0x03F9, 0x03F9, d{0, -7, 0}},
+ {0x03FA, 0x03FB, d{UpperLower, UpperLower, UpperLower}},
+ {0x03FD, 0x03FF, d{0, -130, 0}},
+ {0x0400, 0x040F, d{0, 80, 0}},
+ {0x0410, 0x042F, d{0, 32, 0}},
+ {0x0430, 0x044F, d{-32, 0, -32}},
+ {0x0450, 0x045F, d{-80, 0, -80}},
+ {0x0460, 0x0481, d{UpperLower, UpperLower, UpperLower}},
+ {0x048A, 0x04BF, d{UpperLower, UpperLower, UpperLower}},
+ {0x04C0, 0x04C0, d{0, 15, 0}},
+ {0x04C1, 0x04CE, d{UpperLower, UpperLower, UpperLower}},
+ {0x04CF, 0x04CF, d{-15, 0, -15}},
+ {0x04D0, 0x052F, d{UpperLower, UpperLower, UpperLower}},
+ {0x0531, 0x0556, d{0, 48, 0}},
+ {0x0561, 0x0586, d{-48, 0, -48}},
+ {0x10A0, 0x10C5, d{0, 7264, 0}},
+ {0x10C7, 0x10C7, d{0, 7264, 0}},
+ {0x10CD, 0x10CD, d{0, 7264, 0}},
+ {0x10D0, 0x10FA, d{3008, 0, 0}},
+ {0x10FD, 0x10FF, d{3008, 0, 0}},
+ {0x13A0, 0x13EF, d{0, 38864, 0}},
+ {0x13F0, 0x13F5, d{0, 8, 0}},
+ {0x13F8, 0x13FD, d{-8, 0, -8}},
+ {0x1C80, 0x1C80, d{-6254, 0, -6254}},
+ {0x1C81, 0x1C81, d{-6253, 0, -6253}},
+ {0x1C82, 0x1C82, d{-6244, 0, -6244}},
+ {0x1C83, 0x1C84, d{-6242, 0, -6242}},
+ {0x1C85, 0x1C85, d{-6243, 0, -6243}},
+ {0x1C86, 0x1C86, d{-6236, 0, -6236}},
+ {0x1C87, 0x1C87, d{-6181, 0, -6181}},
+ {0x1C88, 0x1C88, d{35266, 0, 35266}},
+ {0x1C90, 0x1CBA, d{0, -3008, 0}},
+ {0x1CBD, 0x1CBF, d{0, -3008, 0}},
+ {0x1D79, 0x1D79, d{35332, 0, 35332}},
+ {0x1D7D, 0x1D7D, d{3814, 0, 3814}},
+ {0x1D8E, 0x1D8E, d{35384, 0, 35384}},
+ {0x1E00, 0x1E95, d{UpperLower, UpperLower, UpperLower}},
+ {0x1E9B, 0x1E9B, d{-59, 0, -59}},
+ {0x1E9E, 0x1E9E, d{0, -7615, 0}},
+ {0x1EA0, 0x1EFF, d{UpperLower, UpperLower, UpperLower}},
+ {0x1F00, 0x1F07, d{8, 0, 8}},
+ {0x1F08, 0x1F0F, d{0, -8, 0}},
+ {0x1F10, 0x1F15, d{8, 0, 8}},
+ {0x1F18, 0x1F1D, d{0, -8, 0}},
+ {0x1F20, 0x1F27, d{8, 0, 8}},
+ {0x1F28, 0x1F2F, d{0, -8, 0}},
+ {0x1F30, 0x1F37, d{8, 0, 8}},
+ {0x1F38, 0x1F3F, d{0, -8, 0}},
+ {0x1F40, 0x1F45, d{8, 0, 8}},
+ {0x1F48, 0x1F4D, d{0, -8, 0}},
+ {0x1F51, 0x1F51, d{8, 0, 8}},
+ {0x1F53, 0x1F53, d{8, 0, 8}},
+ {0x1F55, 0x1F55, d{8, 0, 8}},
+ {0x1F57, 0x1F57, d{8, 0, 8}},
+ {0x1F59, 0x1F59, d{0, -8, 0}},
+ {0x1F5B, 0x1F5B, d{0, -8, 0}},
+ {0x1F5D, 0x1F5D, d{0, -8, 0}},
+ {0x1F5F, 0x1F5F, d{0, -8, 0}},
+ {0x1F60, 0x1F67, d{8, 0, 8}},
+ {0x1F68, 0x1F6F, d{0, -8, 0}},
+ {0x1F70, 0x1F71, d{74, 0, 74}},
+ {0x1F72, 0x1F75, d{86, 0, 86}},
+ {0x1F76, 0x1F77, d{100, 0, 100}},
+ {0x1F78, 0x1F79, d{128, 0, 128}},
+ {0x1F7A, 0x1F7B, d{112, 0, 112}},
+ {0x1F7C, 0x1F7D, d{126, 0, 126}},
+ {0x1F80, 0x1F87, d{8, 0, 8}},
+ {0x1F88, 0x1F8F, d{0, -8, 0}},
+ {0x1F90, 0x1F97, d{8, 0, 8}},
+ {0x1F98, 0x1F9F, d{0, -8, 0}},
+ {0x1FA0, 0x1FA7, d{8, 0, 8}},
+ {0x1FA8, 0x1FAF, d{0, -8, 0}},
+ {0x1FB0, 0x1FB1, d{8, 0, 8}},
+ {0x1FB3, 0x1FB3, d{9, 0, 9}},
+ {0x1FB8, 0x1FB9, d{0, -8, 0}},
+ {0x1FBA, 0x1FBB, d{0, -74, 0}},
+ {0x1FBC, 0x1FBC, d{0, -9, 0}},
+ {0x1FBE, 0x1FBE, d{-7205, 0, -7205}},
+ {0x1FC3, 0x1FC3, d{9, 0, 9}},
+ {0x1FC8, 0x1FCB, d{0, -86, 0}},
+ {0x1FCC, 0x1FCC, d{0, -9, 0}},
+ {0x1FD0, 0x1FD1, d{8, 0, 8}},
+ {0x1FD8, 0x1FD9, d{0, -8, 0}},
+ {0x1FDA, 0x1FDB, d{0, -100, 0}},
+ {0x1FE0, 0x1FE1, d{8, 0, 8}},
+ {0x1FE5, 0x1FE5, d{7, 0, 7}},
+ {0x1FE8, 0x1FE9, d{0, -8, 0}},
+ {0x1FEA, 0x1FEB, d{0, -112, 0}},
+ {0x1FEC, 0x1FEC, d{0, -7, 0}},
+ {0x1FF3, 0x1FF3, d{9, 0, 9}},
+ {0x1FF8, 0x1FF9, d{0, -128, 0}},
+ {0x1FFA, 0x1FFB, d{0, -126, 0}},
+ {0x1FFC, 0x1FFC, d{0, -9, 0}},
+ {0x2126, 0x2126, d{0, -7517, 0}},
+ {0x212A, 0x212A, d{0, -8383, 0}},
+ {0x212B, 0x212B, d{0, -8262, 0}},
+ {0x2132, 0x2132, d{0, 28, 0}},
+ {0x214E, 0x214E, d{-28, 0, -28}},
+ {0x2160, 0x216F, d{0, 16, 0}},
+ {0x2170, 0x217F, d{-16, 0, -16}},
+ {0x2183, 0x2184, d{UpperLower, UpperLower, UpperLower}},
+ {0x24B6, 0x24CF, d{0, 26, 0}},
+ {0x24D0, 0x24E9, d{-26, 0, -26}},
+ {0x2C00, 0x2C2F, d{0, 48, 0}},
+ {0x2C30, 0x2C5F, d{-48, 0, -48}},
+ {0x2C60, 0x2C61, d{UpperLower, UpperLower, UpperLower}},
+ {0x2C62, 0x2C62, d{0, -10743, 0}},
+ {0x2C63, 0x2C63, d{0, -3814, 0}},
+ {0x2C64, 0x2C64, d{0, -10727, 0}},
+ {0x2C65, 0x2C65, d{-10795, 0, -10795}},
+ {0x2C66, 0x2C66, d{-10792, 0, -10792}},
+ {0x2C67, 0x2C6C, d{UpperLower, UpperLower, UpperLower}},
+ {0x2C6D, 0x2C6D, d{0, -10780, 0}},
+ {0x2C6E, 0x2C6E, d{0, -10749, 0}},
+ {0x2C6F, 0x2C6F, d{0, -10783, 0}},
+ {0x2C70, 0x2C70, d{0, -10782, 0}},
+ {0x2C72, 0x2C73, d{UpperLower, UpperLower, UpperLower}},
+ {0x2C75, 0x2C76, d{UpperLower, UpperLower, UpperLower}},
+ {0x2C7E, 0x2C7F, d{0, -10815, 0}},
+ {0x2C80, 0x2CE3, d{UpperLower, UpperLower, UpperLower}},
+ {0x2CEB, 0x2CEE, d{UpperLower, UpperLower, UpperLower}},
+ {0x2CF2, 0x2CF3, d{UpperLower, UpperLower, UpperLower}},
+ {0x2D00, 0x2D25, d{-7264, 0, -7264}},
+ {0x2D27, 0x2D27, d{-7264, 0, -7264}},
+ {0x2D2D, 0x2D2D, d{-7264, 0, -7264}},
+ {0xA640, 0xA66D, d{UpperLower, UpperLower, UpperLower}},
+ {0xA680, 0xA69B, d{UpperLower, UpperLower, UpperLower}},
+ {0xA722, 0xA72F, d{UpperLower, UpperLower, UpperLower}},
+ {0xA732, 0xA76F, d{UpperLower, UpperLower, UpperLower}},
+ {0xA779, 0xA77C, d{UpperLower, UpperLower, UpperLower}},
+ {0xA77D, 0xA77D, d{0, -35332, 0}},
+ {0xA77E, 0xA787, d{UpperLower, UpperLower, UpperLower}},
+ {0xA78B, 0xA78C, d{UpperLower, UpperLower, UpperLower}},
+ {0xA78D, 0xA78D, d{0, -42280, 0}},
+ {0xA790, 0xA793, d{UpperLower, UpperLower, UpperLower}},
+ {0xA794, 0xA794, d{48, 0, 48}},
+ {0xA796, 0xA7A9, d{UpperLower, UpperLower, UpperLower}},
+ {0xA7AA, 0xA7AA, d{0, -42308, 0}},
+ {0xA7AB, 0xA7AB, d{0, -42319, 0}},
+ {0xA7AC, 0xA7AC, d{0, -42315, 0}},
+ {0xA7AD, 0xA7AD, d{0, -42305, 0}},
+ {0xA7AE, 0xA7AE, d{0, -42308, 0}},
+ {0xA7B0, 0xA7B0, d{0, -42258, 0}},
+ {0xA7B1, 0xA7B1, d{0, -42282, 0}},
+ {0xA7B2, 0xA7B2, d{0, -42261, 0}},
+ {0xA7B3, 0xA7B3, d{0, 928, 0}},
+ {0xA7B4, 0xA7C3, d{UpperLower, UpperLower, UpperLower}},
+ {0xA7C4, 0xA7C4, d{0, -48, 0}},
+ {0xA7C5, 0xA7C5, d{0, -42307, 0}},
+ {0xA7C6, 0xA7C6, d{0, -35384, 0}},
+ {0xA7C7, 0xA7CA, d{UpperLower, UpperLower, UpperLower}},
+ {0xA7D0, 0xA7D1, d{UpperLower, UpperLower, UpperLower}},
+ {0xA7D6, 0xA7D9, d{UpperLower, UpperLower, UpperLower}},
+ {0xA7F5, 0xA7F6, d{UpperLower, UpperLower, UpperLower}},
+ {0xAB53, 0xAB53, d{-928, 0, -928}},
+ {0xAB70, 0xABBF, d{-38864, 0, -38864}},
+ {0xFF21, 0xFF3A, d{0, 32, 0}},
+ {0xFF41, 0xFF5A, d{-32, 0, -32}},
+ {0x10400, 0x10427, d{0, 40, 0}},
+ {0x10428, 0x1044F, d{-40, 0, -40}},
+ {0x104B0, 0x104D3, d{0, 40, 0}},
+ {0x104D8, 0x104FB, d{-40, 0, -40}},
+ {0x10570, 0x1057A, d{0, 39, 0}},
+ {0x1057C, 0x1058A, d{0, 39, 0}},
+ {0x1058C, 0x10592, d{0, 39, 0}},
+ {0x10594, 0x10595, d{0, 39, 0}},
+ {0x10597, 0x105A1, d{-39, 0, -39}},
+ {0x105A3, 0x105B1, d{-39, 0, -39}},
+ {0x105B3, 0x105B9, d{-39, 0, -39}},
+ {0x105BB, 0x105BC, d{-39, 0, -39}},
+ {0x10C80, 0x10CB2, d{0, 64, 0}},
+ {0x10CC0, 0x10CF2, d{-64, 0, -64}},
+ {0x118A0, 0x118BF, d{0, 32, 0}},
+ {0x118C0, 0x118DF, d{-32, 0, -32}},
+ {0x16E40, 0x16E5F, d{0, 32, 0}},
+ {0x16E60, 0x16E7F, d{-32, 0, -32}},
+ {0x1E900, 0x1E921, d{0, 34, 0}},
+ {0x1E922, 0x1E943, d{-34, 0, -34}},
+}
+var properties = [MaxLatin1 + 1]uint8{
+ 0x00: pC, // '\x00'
+ 0x01: pC, // '\x01'
+ 0x02: pC, // '\x02'
+ 0x03: pC, // '\x03'
+ 0x04: pC, // '\x04'
+ 0x05: pC, // '\x05'
+ 0x06: pC, // '\x06'
+ 0x07: pC, // '\a'
+ 0x08: pC, // '\b'
+ 0x09: pC, // '\t'
+ 0x0A: pC, // '\n'
+ 0x0B: pC, // '\v'
+ 0x0C: pC, // '\f'
+ 0x0D: pC, // '\r'
+ 0x0E: pC, // '\x0e'
+ 0x0F: pC, // '\x0f'
+ 0x10: pC, // '\x10'
+ 0x11: pC, // '\x11'
+ 0x12: pC, // '\x12'
+ 0x13: pC, // '\x13'
+ 0x14: pC, // '\x14'
+ 0x15: pC, // '\x15'
+ 0x16: pC, // '\x16'
+ 0x17: pC, // '\x17'
+ 0x18: pC, // '\x18'
+ 0x19: pC, // '\x19'
+ 0x1A: pC, // '\x1a'
+ 0x1B: pC, // '\x1b'
+ 0x1C: pC, // '\x1c'
+ 0x1D: pC, // '\x1d'
+ 0x1E: pC, // '\x1e'
+ 0x1F: pC, // '\x1f'
+ 0x20: pZ | pp, // ' '
+ 0x21: pP | pp, // '!'
+ 0x22: pP | pp, // '"'
+ 0x23: pP | pp, // '#'
+ 0x24: pS | pp, // '$'
+ 0x25: pP | pp, // '%'
+ 0x26: pP | pp, // '&'
+ 0x27: pP | pp, // '\''
+ 0x28: pP | pp, // '('
+ 0x29: pP | pp, // ')'
+ 0x2A: pP | pp, // '*'
+ 0x2B: pS | pp, // '+'
+ 0x2C: pP | pp, // ','
+ 0x2D: pP | pp, // '-'
+ 0x2E: pP | pp, // '.'
+ 0x2F: pP | pp, // '/'
+ 0x30: pN | pp, // '0'
+ 0x31: pN | pp, // '1'
+ 0x32: pN | pp, // '2'
+ 0x33: pN | pp, // '3'
+ 0x34: pN | pp, // '4'
+ 0x35: pN | pp, // '5'
+ 0x36: pN | pp, // '6'
+ 0x37: pN | pp, // '7'
+ 0x38: pN | pp, // '8'
+ 0x39: pN | pp, // '9'
+ 0x3A: pP | pp, // ':'
+ 0x3B: pP | pp, // ';'
+ 0x3C: pS | pp, // '<'
+ 0x3D: pS | pp, // '='
+ 0x3E: pS | pp, // '>'
+ 0x3F: pP | pp, // '?'
+ 0x40: pP | pp, // '@'
+ 0x41: pLu | pp, // 'A'
+ 0x42: pLu | pp, // 'B'
+ 0x43: pLu | pp, // 'C'
+ 0x44: pLu | pp, // 'D'
+ 0x45: pLu | pp, // 'E'
+ 0x46: pLu | pp, // 'F'
+ 0x47: pLu | pp, // 'G'
+ 0x48: pLu | pp, // 'H'
+ 0x49: pLu | pp, // 'I'
+ 0x4A: pLu | pp, // 'J'
+ 0x4B: pLu | pp, // 'K'
+ 0x4C: pLu | pp, // 'L'
+ 0x4D: pLu | pp, // 'M'
+ 0x4E: pLu | pp, // 'N'
+ 0x4F: pLu | pp, // 'O'
+ 0x50: pLu | pp, // 'P'
+ 0x51: pLu | pp, // 'Q'
+ 0x52: pLu | pp, // 'R'
+ 0x53: pLu | pp, // 'S'
+ 0x54: pLu | pp, // 'T'
+ 0x55: pLu | pp, // 'U'
+ 0x56: pLu | pp, // 'V'
+ 0x57: pLu | pp, // 'W'
+ 0x58: pLu | pp, // 'X'
+ 0x59: pLu | pp, // 'Y'
+ 0x5A: pLu | pp, // 'Z'
+ 0x5B: pP | pp, // '['
+ 0x5C: pP | pp, // '\\'
+ 0x5D: pP | pp, // ']'
+ 0x5E: pS | pp, // '^'
+ 0x5F: pP | pp, // '_'
+ 0x60: pS | pp, // '`'
+ 0x61: pLl | pp, // 'a'
+ 0x62: pLl | pp, // 'b'
+ 0x63: pLl | pp, // 'c'
+ 0x64: pLl | pp, // 'd'
+ 0x65: pLl | pp, // 'e'
+ 0x66: pLl | pp, // 'f'
+ 0x67: pLl | pp, // 'g'
+ 0x68: pLl | pp, // 'h'
+ 0x69: pLl | pp, // 'i'
+ 0x6A: pLl | pp, // 'j'
+ 0x6B: pLl | pp, // 'k'
+ 0x6C: pLl | pp, // 'l'
+ 0x6D: pLl | pp, // 'm'
+ 0x6E: pLl | pp, // 'n'
+ 0x6F: pLl | pp, // 'o'
+ 0x70: pLl | pp, // 'p'
+ 0x71: pLl | pp, // 'q'
+ 0x72: pLl | pp, // 'r'
+ 0x73: pLl | pp, // 's'
+ 0x74: pLl | pp, // 't'
+ 0x75: pLl | pp, // 'u'
+ 0x76: pLl | pp, // 'v'
+ 0x77: pLl | pp, // 'w'
+ 0x78: pLl | pp, // 'x'
+ 0x79: pLl | pp, // 'y'
+ 0x7A: pLl | pp, // 'z'
+ 0x7B: pP | pp, // '{'
+ 0x7C: pS | pp, // '|'
+ 0x7D: pP | pp, // '}'
+ 0x7E: pS | pp, // '~'
+ 0x7F: pC, // '\x7f'
+ 0x80: pC, // '\u0080'
+ 0x81: pC, // '\u0081'
+ 0x82: pC, // '\u0082'
+ 0x83: pC, // '\u0083'
+ 0x84: pC, // '\u0084'
+ 0x85: pC, // '\u0085'
+ 0x86: pC, // '\u0086'
+ 0x87: pC, // '\u0087'
+ 0x88: pC, // '\u0088'
+ 0x89: pC, // '\u0089'
+ 0x8A: pC, // '\u008a'
+ 0x8B: pC, // '\u008b'
+ 0x8C: pC, // '\u008c'
+ 0x8D: pC, // '\u008d'
+ 0x8E: pC, // '\u008e'
+ 0x8F: pC, // '\u008f'
+ 0x90: pC, // '\u0090'
+ 0x91: pC, // '\u0091'
+ 0x92: pC, // '\u0092'
+ 0x93: pC, // '\u0093'
+ 0x94: pC, // '\u0094'
+ 0x95: pC, // '\u0095'
+ 0x96: pC, // '\u0096'
+ 0x97: pC, // '\u0097'
+ 0x98: pC, // '\u0098'
+ 0x99: pC, // '\u0099'
+ 0x9A: pC, // '\u009a'
+ 0x9B: pC, // '\u009b'
+ 0x9C: pC, // '\u009c'
+ 0x9D: pC, // '\u009d'
+ 0x9E: pC, // '\u009e'
+ 0x9F: pC, // '\u009f'
+ 0xA0: pZ, // '\u00a0'
+ 0xA1: pP | pp, // '¡'
+ 0xA2: pS | pp, // '¢'
+ 0xA3: pS | pp, // '£'
+ 0xA4: pS | pp, // '¤'
+ 0xA5: pS | pp, // '¥'
+ 0xA6: pS | pp, // '¦'
+ 0xA7: pP | pp, // '§'
+ 0xA8: pS | pp, // '¨'
+ 0xA9: pS | pp, // '©'
+ 0xAA: pLo | pp, // 'ª'
+ 0xAB: pP | pp, // '«'
+ 0xAC: pS | pp, // '¬'
+ 0xAD: 0, // '\u00ad'
+ 0xAE: pS | pp, // '®'
+ 0xAF: pS | pp, // '¯'
+ 0xB0: pS | pp, // '°'
+ 0xB1: pS | pp, // '±'
+ 0xB2: pN | pp, // '²'
+ 0xB3: pN | pp, // '³'
+ 0xB4: pS | pp, // '´'
+ 0xB5: pLl | pp, // 'µ'
+ 0xB6: pP | pp, // '¶'
+ 0xB7: pP | pp, // '·'
+ 0xB8: pS | pp, // '¸'
+ 0xB9: pN | pp, // '¹'
+ 0xBA: pLo | pp, // 'º'
+ 0xBB: pP | pp, // '»'
+ 0xBC: pN | pp, // '¼'
+ 0xBD: pN | pp, // '½'
+ 0xBE: pN | pp, // '¾'
+ 0xBF: pP | pp, // '¿'
+ 0xC0: pLu | pp, // 'À'
+ 0xC1: pLu | pp, // 'Á'
+ 0xC2: pLu | pp, // 'Â'
+ 0xC3: pLu | pp, // 'Ã'
+ 0xC4: pLu | pp, // 'Ä'
+ 0xC5: pLu | pp, // 'Å'
+ 0xC6: pLu | pp, // 'Æ'
+ 0xC7: pLu | pp, // 'Ç'
+ 0xC8: pLu | pp, // 'È'
+ 0xC9: pLu | pp, // 'É'
+ 0xCA: pLu | pp, // 'Ê'
+ 0xCB: pLu | pp, // 'Ë'
+ 0xCC: pLu | pp, // 'Ì'
+ 0xCD: pLu | pp, // 'Í'
+ 0xCE: pLu | pp, // 'Î'
+ 0xCF: pLu | pp, // 'Ï'
+ 0xD0: pLu | pp, // 'Ð'
+ 0xD1: pLu | pp, // 'Ñ'
+ 0xD2: pLu | pp, // 'Ò'
+ 0xD3: pLu | pp, // 'Ó'
+ 0xD4: pLu | pp, // 'Ô'
+ 0xD5: pLu | pp, // 'Õ'
+ 0xD6: pLu | pp, // 'Ö'
+ 0xD7: pS | pp, // '×'
+ 0xD8: pLu | pp, // 'Ø'
+ 0xD9: pLu | pp, // 'Ù'
+ 0xDA: pLu | pp, // 'Ú'
+ 0xDB: pLu | pp, // 'Û'
+ 0xDC: pLu | pp, // 'Ü'
+ 0xDD: pLu | pp, // 'Ý'
+ 0xDE: pLu | pp, // 'Þ'
+ 0xDF: pLl | pp, // 'ß'
+ 0xE0: pLl | pp, // 'à'
+ 0xE1: pLl | pp, // 'á'
+ 0xE2: pLl | pp, // 'â'
+ 0xE3: pLl | pp, // 'ã'
+ 0xE4: pLl | pp, // 'ä'
+ 0xE5: pLl | pp, // 'å'
+ 0xE6: pLl | pp, // 'æ'
+ 0xE7: pLl | pp, // 'ç'
+ 0xE8: pLl | pp, // 'è'
+ 0xE9: pLl | pp, // 'é'
+ 0xEA: pLl | pp, // 'ê'
+ 0xEB: pLl | pp, // 'ë'
+ 0xEC: pLl | pp, // 'ì'
+ 0xED: pLl | pp, // 'í'
+ 0xEE: pLl | pp, // 'î'
+ 0xEF: pLl | pp, // 'ï'
+ 0xF0: pLl | pp, // 'ð'
+ 0xF1: pLl | pp, // 'ñ'
+ 0xF2: pLl | pp, // 'ò'
+ 0xF3: pLl | pp, // 'ó'
+ 0xF4: pLl | pp, // 'ô'
+ 0xF5: pLl | pp, // 'õ'
+ 0xF6: pLl | pp, // 'ö'
+ 0xF7: pS | pp, // '÷'
+ 0xF8: pLl | pp, // 'ø'
+ 0xF9: pLl | pp, // 'ù'
+ 0xFA: pLl | pp, // 'ú'
+ 0xFB: pLl | pp, // 'û'
+ 0xFC: pLl | pp, // 'ü'
+ 0xFD: pLl | pp, // 'ý'
+ 0xFE: pLl | pp, // 'þ'
+ 0xFF: pLl | pp, // 'ÿ'
+}
+
+var asciiFold = [MaxASCII + 1]uint16{
+ 0x0000,
+ 0x0001,
+ 0x0002,
+ 0x0003,
+ 0x0004,
+ 0x0005,
+ 0x0006,
+ 0x0007,
+ 0x0008,
+ 0x0009,
+ 0x000A,
+ 0x000B,
+ 0x000C,
+ 0x000D,
+ 0x000E,
+ 0x000F,
+ 0x0010,
+ 0x0011,
+ 0x0012,
+ 0x0013,
+ 0x0014,
+ 0x0015,
+ 0x0016,
+ 0x0017,
+ 0x0018,
+ 0x0019,
+ 0x001A,
+ 0x001B,
+ 0x001C,
+ 0x001D,
+ 0x001E,
+ 0x001F,
+ 0x0020,
+ 0x0021,
+ 0x0022,
+ 0x0023,
+ 0x0024,
+ 0x0025,
+ 0x0026,
+ 0x0027,
+ 0x0028,
+ 0x0029,
+ 0x002A,
+ 0x002B,
+ 0x002C,
+ 0x002D,
+ 0x002E,
+ 0x002F,
+ 0x0030,
+ 0x0031,
+ 0x0032,
+ 0x0033,
+ 0x0034,
+ 0x0035,
+ 0x0036,
+ 0x0037,
+ 0x0038,
+ 0x0039,
+ 0x003A,
+ 0x003B,
+ 0x003C,
+ 0x003D,
+ 0x003E,
+ 0x003F,
+ 0x0040,
+ 0x0061,
+ 0x0062,
+ 0x0063,
+ 0x0064,
+ 0x0065,
+ 0x0066,
+ 0x0067,
+ 0x0068,
+ 0x0069,
+ 0x006A,
+ 0x006B,
+ 0x006C,
+ 0x006D,
+ 0x006E,
+ 0x006F,
+ 0x0070,
+ 0x0071,
+ 0x0072,
+ 0x0073,
+ 0x0074,
+ 0x0075,
+ 0x0076,
+ 0x0077,
+ 0x0078,
+ 0x0079,
+ 0x007A,
+ 0x005B,
+ 0x005C,
+ 0x005D,
+ 0x005E,
+ 0x005F,
+ 0x0060,
+ 0x0041,
+ 0x0042,
+ 0x0043,
+ 0x0044,
+ 0x0045,
+ 0x0046,
+ 0x0047,
+ 0x0048,
+ 0x0049,
+ 0x004A,
+ 0x212A,
+ 0x004C,
+ 0x004D,
+ 0x004E,
+ 0x004F,
+ 0x0050,
+ 0x0051,
+ 0x0052,
+ 0x017F,
+ 0x0054,
+ 0x0055,
+ 0x0056,
+ 0x0057,
+ 0x0058,
+ 0x0059,
+ 0x005A,
+ 0x007B,
+ 0x007C,
+ 0x007D,
+ 0x007E,
+ 0x007F,
+}
+
+var caseOrbit = []foldPair{
+ {0x004B, 0x006B},
+ {0x0053, 0x0073},
+ {0x006B, 0x212A},
+ {0x0073, 0x017F},
+ {0x00B5, 0x039C},
+ {0x00C5, 0x00E5},
+ {0x00DF, 0x1E9E},
+ {0x00E5, 0x212B},
+ {0x0130, 0x0130},
+ {0x0131, 0x0131},
+ {0x017F, 0x0053},
+ {0x01C4, 0x01C5},
+ {0x01C5, 0x01C6},
+ {0x01C6, 0x01C4},
+ {0x01C7, 0x01C8},
+ {0x01C8, 0x01C9},
+ {0x01C9, 0x01C7},
+ {0x01CA, 0x01CB},
+ {0x01CB, 0x01CC},
+ {0x01CC, 0x01CA},
+ {0x01F1, 0x01F2},
+ {0x01F2, 0x01F3},
+ {0x01F3, 0x01F1},
+ {0x0345, 0x0399},
+ {0x0392, 0x03B2},
+ {0x0395, 0x03B5},
+ {0x0398, 0x03B8},
+ {0x0399, 0x03B9},
+ {0x039A, 0x03BA},
+ {0x039C, 0x03BC},
+ {0x03A0, 0x03C0},
+ {0x03A1, 0x03C1},
+ {0x03A3, 0x03C2},
+ {0x03A6, 0x03C6},
+ {0x03A9, 0x03C9},
+ {0x03B2, 0x03D0},
+ {0x03B5, 0x03F5},
+ {0x03B8, 0x03D1},
+ {0x03B9, 0x1FBE},
+ {0x03BA, 0x03F0},
+ {0x03BC, 0x00B5},
+ {0x03C0, 0x03D6},
+ {0x03C1, 0x03F1},
+ {0x03C2, 0x03C3},
+ {0x03C3, 0x03A3},
+ {0x03C6, 0x03D5},
+ {0x03C9, 0x2126},
+ {0x03D0, 0x0392},
+ {0x03D1, 0x03F4},
+ {0x03D5, 0x03A6},
+ {0x03D6, 0x03A0},
+ {0x03F0, 0x039A},
+ {0x03F1, 0x03A1},
+ {0x03F4, 0x0398},
+ {0x03F5, 0x0395},
+ {0x0412, 0x0432},
+ {0x0414, 0x0434},
+ {0x041E, 0x043E},
+ {0x0421, 0x0441},
+ {0x0422, 0x0442},
+ {0x042A, 0x044A},
+ {0x0432, 0x1C80},
+ {0x0434, 0x1C81},
+ {0x043E, 0x1C82},
+ {0x0441, 0x1C83},
+ {0x0442, 0x1C84},
+ {0x044A, 0x1C86},
+ {0x0462, 0x0463},
+ {0x0463, 0x1C87},
+ {0x1C80, 0x0412},
+ {0x1C81, 0x0414},
+ {0x1C82, 0x041E},
+ {0x1C83, 0x0421},
+ {0x1C84, 0x1C85},
+ {0x1C85, 0x0422},
+ {0x1C86, 0x042A},
+ {0x1C87, 0x0462},
+ {0x1C88, 0xA64A},
+ {0x1E60, 0x1E61},
+ {0x1E61, 0x1E9B},
+ {0x1E9B, 0x1E60},
+ {0x1E9E, 0x00DF},
+ {0x1FBE, 0x0345},
+ {0x2126, 0x03A9},
+ {0x212A, 0x004B},
+ {0x212B, 0x00C5},
+ {0xA64A, 0xA64B},
+ {0xA64B, 0x1C88},
+}
+
+// FoldCategory maps a category name to a table of
+// code points outside the category that are equivalent under
+// simple case folding to code points inside the category.
+// If there is no entry for a category name, there are no such points.
+var FoldCategory = map[string]*RangeTable{
+ "L": foldL,
+ "Ll": foldLl,
+ "Lt": foldLt,
+ "Lu": foldLu,
+ "M": foldM,
+ "Mn": foldMn,
+}
+
+var foldL = &RangeTable{
+ R16: []Range16{
+ {0x0345, 0x0345, 1},
+ },
+}
+
+var foldLl = &RangeTable{
+ R16: []Range16{
+ {0x0041, 0x005a, 1},
+ {0x00c0, 0x00d6, 1},
+ {0x00d8, 0x00de, 1},
+ {0x0100, 0x012e, 2},
+ {0x0132, 0x0136, 2},
+ {0x0139, 0x0147, 2},
+ {0x014a, 0x0178, 2},
+ {0x0179, 0x017d, 2},
+ {0x0181, 0x0182, 1},
+ {0x0184, 0x0186, 2},
+ {0x0187, 0x0189, 2},
+ {0x018a, 0x018b, 1},
+ {0x018e, 0x0191, 1},
+ {0x0193, 0x0194, 1},
+ {0x0196, 0x0198, 1},
+ {0x019c, 0x019d, 1},
+ {0x019f, 0x01a0, 1},
+ {0x01a2, 0x01a6, 2},
+ {0x01a7, 0x01a9, 2},
+ {0x01ac, 0x01ae, 2},
+ {0x01af, 0x01b1, 2},
+ {0x01b2, 0x01b3, 1},
+ {0x01b5, 0x01b7, 2},
+ {0x01b8, 0x01bc, 4},
+ {0x01c4, 0x01c5, 1},
+ {0x01c7, 0x01c8, 1},
+ {0x01ca, 0x01cb, 1},
+ {0x01cd, 0x01db, 2},
+ {0x01de, 0x01ee, 2},
+ {0x01f1, 0x01f2, 1},
+ {0x01f4, 0x01f6, 2},
+ {0x01f7, 0x01f8, 1},
+ {0x01fa, 0x0232, 2},
+ {0x023a, 0x023b, 1},
+ {0x023d, 0x023e, 1},
+ {0x0241, 0x0243, 2},
+ {0x0244, 0x0246, 1},
+ {0x0248, 0x024e, 2},
+ {0x0345, 0x0370, 43},
+ {0x0372, 0x0376, 4},
+ {0x037f, 0x0386, 7},
+ {0x0388, 0x038a, 1},
+ {0x038c, 0x038e, 2},
+ {0x038f, 0x0391, 2},
+ {0x0392, 0x03a1, 1},
+ {0x03a3, 0x03ab, 1},
+ {0x03cf, 0x03d8, 9},
+ {0x03da, 0x03ee, 2},
+ {0x03f4, 0x03f7, 3},
+ {0x03f9, 0x03fa, 1},
+ {0x03fd, 0x042f, 1},
+ {0x0460, 0x0480, 2},
+ {0x048a, 0x04c0, 2},
+ {0x04c1, 0x04cd, 2},
+ {0x04d0, 0x052e, 2},
+ {0x0531, 0x0556, 1},
+ {0x10a0, 0x10c5, 1},
+ {0x10c7, 0x10cd, 6},
+ {0x13a0, 0x13f5, 1},
+ {0x1c90, 0x1cba, 1},
+ {0x1cbd, 0x1cbf, 1},
+ {0x1e00, 0x1e94, 2},
+ {0x1e9e, 0x1efe, 2},
+ {0x1f08, 0x1f0f, 1},
+ {0x1f18, 0x1f1d, 1},
+ {0x1f28, 0x1f2f, 1},
+ {0x1f38, 0x1f3f, 1},
+ {0x1f48, 0x1f4d, 1},
+ {0x1f59, 0x1f5f, 2},
+ {0x1f68, 0x1f6f, 1},
+ {0x1f88, 0x1f8f, 1},
+ {0x1f98, 0x1f9f, 1},
+ {0x1fa8, 0x1faf, 1},
+ {0x1fb8, 0x1fbc, 1},
+ {0x1fc8, 0x1fcc, 1},
+ {0x1fd8, 0x1fdb, 1},
+ {0x1fe8, 0x1fec, 1},
+ {0x1ff8, 0x1ffc, 1},
+ {0x2126, 0x212a, 4},
+ {0x212b, 0x2132, 7},
+ {0x2183, 0x2c00, 2685},
+ {0x2c01, 0x2c2f, 1},
+ {0x2c60, 0x2c62, 2},
+ {0x2c63, 0x2c64, 1},
+ {0x2c67, 0x2c6d, 2},
+ {0x2c6e, 0x2c70, 1},
+ {0x2c72, 0x2c75, 3},
+ {0x2c7e, 0x2c80, 1},
+ {0x2c82, 0x2ce2, 2},
+ {0x2ceb, 0x2ced, 2},
+ {0x2cf2, 0xa640, 31054},
+ {0xa642, 0xa66c, 2},
+ {0xa680, 0xa69a, 2},
+ {0xa722, 0xa72e, 2},
+ {0xa732, 0xa76e, 2},
+ {0xa779, 0xa77d, 2},
+ {0xa77e, 0xa786, 2},
+ {0xa78b, 0xa78d, 2},
+ {0xa790, 0xa792, 2},
+ {0xa796, 0xa7aa, 2},
+ {0xa7ab, 0xa7ae, 1},
+ {0xa7b0, 0xa7b4, 1},
+ {0xa7b6, 0xa7c4, 2},
+ {0xa7c5, 0xa7c7, 1},
+ {0xa7c9, 0xa7d0, 7},
+ {0xa7d6, 0xa7d8, 2},
+ {0xa7f5, 0xff21, 22316},
+ {0xff22, 0xff3a, 1},
+ },
+ R32: []Range32{
+ {0x10400, 0x10427, 1},
+ {0x104b0, 0x104d3, 1},
+ {0x10570, 0x1057a, 1},
+ {0x1057c, 0x1058a, 1},
+ {0x1058c, 0x10592, 1},
+ {0x10594, 0x10595, 1},
+ {0x10c80, 0x10cb2, 1},
+ {0x118a0, 0x118bf, 1},
+ {0x16e40, 0x16e5f, 1},
+ {0x1e900, 0x1e921, 1},
+ },
+ LatinOffset: 3,
+}
+
+var foldLt = &RangeTable{
+ R16: []Range16{
+ {0x01c4, 0x01c6, 2},
+ {0x01c7, 0x01c9, 2},
+ {0x01ca, 0x01cc, 2},
+ {0x01f1, 0x01f3, 2},
+ {0x1f80, 0x1f87, 1},
+ {0x1f90, 0x1f97, 1},
+ {0x1fa0, 0x1fa7, 1},
+ {0x1fb3, 0x1fc3, 16},
+ {0x1ff3, 0x1ff3, 1},
+ },
+}
+
+var foldLu = &RangeTable{
+ R16: []Range16{
+ {0x0061, 0x007a, 1},
+ {0x00b5, 0x00df, 42},
+ {0x00e0, 0x00f6, 1},
+ {0x00f8, 0x00ff, 1},
+ {0x0101, 0x012f, 2},
+ {0x0133, 0x0137, 2},
+ {0x013a, 0x0148, 2},
+ {0x014b, 0x0177, 2},
+ {0x017a, 0x017e, 2},
+ {0x017f, 0x0180, 1},
+ {0x0183, 0x0185, 2},
+ {0x0188, 0x018c, 4},
+ {0x0192, 0x0195, 3},
+ {0x0199, 0x019a, 1},
+ {0x019e, 0x01a1, 3},
+ {0x01a3, 0x01a5, 2},
+ {0x01a8, 0x01ad, 5},
+ {0x01b0, 0x01b4, 4},
+ {0x01b6, 0x01b9, 3},
+ {0x01bd, 0x01bf, 2},
+ {0x01c5, 0x01c6, 1},
+ {0x01c8, 0x01c9, 1},
+ {0x01cb, 0x01cc, 1},
+ {0x01ce, 0x01dc, 2},
+ {0x01dd, 0x01ef, 2},
+ {0x01f2, 0x01f3, 1},
+ {0x01f5, 0x01f9, 4},
+ {0x01fb, 0x021f, 2},
+ {0x0223, 0x0233, 2},
+ {0x023c, 0x023f, 3},
+ {0x0240, 0x0242, 2},
+ {0x0247, 0x024f, 2},
+ {0x0250, 0x0254, 1},
+ {0x0256, 0x0257, 1},
+ {0x0259, 0x025b, 2},
+ {0x025c, 0x0260, 4},
+ {0x0261, 0x0265, 2},
+ {0x0266, 0x0268, 2},
+ {0x0269, 0x026c, 1},
+ {0x026f, 0x0271, 2},
+ {0x0272, 0x0275, 3},
+ {0x027d, 0x0280, 3},
+ {0x0282, 0x0283, 1},
+ {0x0287, 0x028c, 1},
+ {0x0292, 0x029d, 11},
+ {0x029e, 0x0345, 167},
+ {0x0371, 0x0373, 2},
+ {0x0377, 0x037b, 4},
+ {0x037c, 0x037d, 1},
+ {0x03ac, 0x03af, 1},
+ {0x03b1, 0x03ce, 1},
+ {0x03d0, 0x03d1, 1},
+ {0x03d5, 0x03d7, 1},
+ {0x03d9, 0x03ef, 2},
+ {0x03f0, 0x03f3, 1},
+ {0x03f5, 0x03fb, 3},
+ {0x0430, 0x045f, 1},
+ {0x0461, 0x0481, 2},
+ {0x048b, 0x04bf, 2},
+ {0x04c2, 0x04ce, 2},
+ {0x04cf, 0x052f, 2},
+ {0x0561, 0x0586, 1},
+ {0x10d0, 0x10fa, 1},
+ {0x10fd, 0x10ff, 1},
+ {0x13f8, 0x13fd, 1},
+ {0x1c80, 0x1c88, 1},
+ {0x1d79, 0x1d7d, 4},
+ {0x1d8e, 0x1e01, 115},
+ {0x1e03, 0x1e95, 2},
+ {0x1e9b, 0x1ea1, 6},
+ {0x1ea3, 0x1eff, 2},
+ {0x1f00, 0x1f07, 1},
+ {0x1f10, 0x1f15, 1},
+ {0x1f20, 0x1f27, 1},
+ {0x1f30, 0x1f37, 1},
+ {0x1f40, 0x1f45, 1},
+ {0x1f51, 0x1f57, 2},
+ {0x1f60, 0x1f67, 1},
+ {0x1f70, 0x1f7d, 1},
+ {0x1fb0, 0x1fb1, 1},
+ {0x1fbe, 0x1fd0, 18},
+ {0x1fd1, 0x1fe0, 15},
+ {0x1fe1, 0x1fe5, 4},
+ {0x214e, 0x2184, 54},
+ {0x2c30, 0x2c5f, 1},
+ {0x2c61, 0x2c65, 4},
+ {0x2c66, 0x2c6c, 2},
+ {0x2c73, 0x2c76, 3},
+ {0x2c81, 0x2ce3, 2},
+ {0x2cec, 0x2cee, 2},
+ {0x2cf3, 0x2d00, 13},
+ {0x2d01, 0x2d25, 1},
+ {0x2d27, 0x2d2d, 6},
+ {0xa641, 0xa66d, 2},
+ {0xa681, 0xa69b, 2},
+ {0xa723, 0xa72f, 2},
+ {0xa733, 0xa76f, 2},
+ {0xa77a, 0xa77c, 2},
+ {0xa77f, 0xa787, 2},
+ {0xa78c, 0xa791, 5},
+ {0xa793, 0xa794, 1},
+ {0xa797, 0xa7a9, 2},
+ {0xa7b5, 0xa7c3, 2},
+ {0xa7c8, 0xa7ca, 2},
+ {0xa7d1, 0xa7d7, 6},
+ {0xa7d9, 0xa7f6, 29},
+ {0xab53, 0xab70, 29},
+ {0xab71, 0xabbf, 1},
+ {0xff41, 0xff5a, 1},
+ },
+ R32: []Range32{
+ {0x10428, 0x1044f, 1},
+ {0x104d8, 0x104fb, 1},
+ {0x10597, 0x105a1, 1},
+ {0x105a3, 0x105b1, 1},
+ {0x105b3, 0x105b9, 1},
+ {0x105bb, 0x105bc, 1},
+ {0x10cc0, 0x10cf2, 1},
+ {0x118c0, 0x118df, 1},
+ {0x16e60, 0x16e7f, 1},
+ {0x1e922, 0x1e943, 1},
+ },
+ LatinOffset: 4,
+}
+
+var foldM = &RangeTable{
+ R16: []Range16{
+ {0x0399, 0x03b9, 32},
+ {0x1fbe, 0x1fbe, 1},
+ },
+}
+
+var foldMn = &RangeTable{
+ R16: []Range16{
+ {0x0399, 0x03b9, 32},
+ {0x1fbe, 0x1fbe, 1},
+ },
+}
+
+// FoldScript maps a script name to a table of
+// code points outside the script that are equivalent under
+// simple case folding to code points inside the script.
+// If there is no entry for a script name, there are no such points.
+var FoldScript = map[string]*RangeTable{
+ "Common": foldCommon,
+ "Greek": foldGreek,
+ "Inherited": foldInherited,
+}
+
+var foldCommon = &RangeTable{
+ R16: []Range16{
+ {0x039c, 0x03bc, 32},
+ },
+}
+
+var foldGreek = &RangeTable{
+ R16: []Range16{
+ {0x00b5, 0x0345, 656},
+ },
+}
+
+var foldInherited = &RangeTable{
+ R16: []Range16{
+ {0x0399, 0x03b9, 32},
+ {0x1fbe, 0x1fbe, 1},
+ },
+}
+
+// Range entries: 3535 16-bit, 2031 32-bit, 5566 total.
+// Range bytes: 21210 16-bit, 24372 32-bit, 45582 total.
+
+// Fold orbit bytes: 88 pairs, 352 bytes
diff --git a/contrib/go/_std_1.21/src/unicode/utf16/utf16.go b/contrib/go/_std_1.21/src/unicode/utf16/utf16.go
new file mode 100644
index 0000000000..1c6d2c66c3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/unicode/utf16/utf16.go
@@ -0,0 +1,133 @@
+// Copyright 2010 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 utf16 implements encoding and decoding of UTF-16 sequences.
+package utf16
+
+// The conditions replacementChar==unicode.ReplacementChar and
+// maxRune==unicode.MaxRune are verified in the tests.
+// Defining them locally avoids this package depending on package unicode.
+
+const (
+ replacementChar = '\uFFFD' // Unicode replacement character
+ maxRune = '\U0010FFFF' // Maximum valid Unicode code point.
+)
+
+const (
+ // 0xd800-0xdc00 encodes the high 10 bits of a pair.
+ // 0xdc00-0xe000 encodes the low 10 bits of a pair.
+ // the value is those 20 bits plus 0x10000.
+ surr1 = 0xd800
+ surr2 = 0xdc00
+ surr3 = 0xe000
+
+ surrSelf = 0x10000
+)
+
+// IsSurrogate reports whether the specified Unicode code point
+// can appear in a surrogate pair.
+func IsSurrogate(r rune) bool {
+ return surr1 <= r && r < surr3
+}
+
+// DecodeRune returns the UTF-16 decoding of a surrogate pair.
+// If the pair is not a valid UTF-16 surrogate pair, DecodeRune returns
+// the Unicode replacement code point U+FFFD.
+func DecodeRune(r1, r2 rune) rune {
+ if surr1 <= r1 && r1 < surr2 && surr2 <= r2 && r2 < surr3 {
+ return (r1-surr1)<<10 | (r2 - surr2) + surrSelf
+ }
+ return replacementChar
+}
+
+// EncodeRune returns the UTF-16 surrogate pair r1, r2 for the given rune.
+// If the rune is not a valid Unicode code point or does not need encoding,
+// EncodeRune returns U+FFFD, U+FFFD.
+func EncodeRune(r rune) (r1, r2 rune) {
+ if r < surrSelf || r > maxRune {
+ return replacementChar, replacementChar
+ }
+ r -= surrSelf
+ return surr1 + (r>>10)&0x3ff, surr2 + r&0x3ff
+}
+
+// Encode returns the UTF-16 encoding of the Unicode code point sequence s.
+func Encode(s []rune) []uint16 {
+ n := len(s)
+ for _, v := range s {
+ if v >= surrSelf {
+ n++
+ }
+ }
+
+ a := make([]uint16, n)
+ n = 0
+ for _, v := range s {
+ switch {
+ case 0 <= v && v < surr1, surr3 <= v && v < surrSelf:
+ // normal rune
+ a[n] = uint16(v)
+ n++
+ case surrSelf <= v && v <= maxRune:
+ // needs surrogate sequence
+ r1, r2 := EncodeRune(v)
+ a[n] = uint16(r1)
+ a[n+1] = uint16(r2)
+ n += 2
+ default:
+ a[n] = uint16(replacementChar)
+ n++
+ }
+ }
+ return a[:n]
+}
+
+// AppendRune appends the UTF-16 encoding of the Unicode code point r
+// to the end of p and returns the extended buffer. If the rune is not
+// a valid Unicode code point, it appends the encoding of U+FFFD.
+func AppendRune(a []uint16, r rune) []uint16 {
+ // This function is inlineable for fast handling of ASCII.
+ switch {
+ case 0 <= r && r < surr1, surr3 <= r && r < surrSelf:
+ // normal rune
+ return append(a, uint16(r))
+ case surrSelf <= r && r <= maxRune:
+ // needs surrogate sequence
+ r1, r2 := EncodeRune(r)
+ return append(a, uint16(r1), uint16(r2))
+ }
+ return append(a, replacementChar)
+}
+
+// Decode returns the Unicode code point sequence represented
+// by the UTF-16 encoding s.
+func Decode(s []uint16) []rune {
+ // Preallocate capacity to hold up to 64 runes.
+ // Decode inlines, so the allocation can live on the stack.
+ buf := make([]rune, 0, 64)
+ return decode(s, buf)
+}
+
+// decode appends to buf the Unicode code point sequence represented
+// by the UTF-16 encoding s and return the extended buffer.
+func decode(s []uint16, buf []rune) []rune {
+ for i := 0; i < len(s); i++ {
+ var ar rune
+ switch r := s[i]; {
+ case r < surr1, surr3 <= r:
+ // normal rune
+ ar = rune(r)
+ case surr1 <= r && r < surr2 && i+1 < len(s) &&
+ surr2 <= s[i+1] && s[i+1] < surr3:
+ // valid surrogate sequence
+ ar = DecodeRune(rune(r), rune(s[i+1]))
+ i++
+ default:
+ // invalid surrogate sequence
+ ar = replacementChar
+ }
+ buf = append(buf, ar)
+ }
+ return buf
+}
diff --git a/contrib/go/_std_1.21/src/unicode/utf16/ya.make b/contrib/go/_std_1.21/src/unicode/utf16/ya.make
new file mode 100644
index 0000000000..8f6f164fc4
--- /dev/null
+++ b/contrib/go/_std_1.21/src/unicode/utf16/ya.make
@@ -0,0 +1,14 @@
+GO_LIBRARY()
+
+SRCS(
+ utf16.go
+)
+
+GO_TEST_SRCS(export_test.go)
+
+GO_XTEST_SRCS(utf16_test.go)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.20/src/unicode/utf8/utf8.go b/contrib/go/_std_1.21/src/unicode/utf8/utf8.go
index 1e9f666e23..1e9f666e23 100644
--- a/contrib/go/_std_1.20/src/unicode/utf8/utf8.go
+++ b/contrib/go/_std_1.21/src/unicode/utf8/utf8.go
diff --git a/contrib/go/_std_1.21/src/unicode/utf8/ya.make b/contrib/go/_std_1.21/src/unicode/utf8/ya.make
new file mode 100644
index 0000000000..15af9c9334
--- /dev/null
+++ b/contrib/go/_std_1.21/src/unicode/utf8/ya.make
@@ -0,0 +1,15 @@
+GO_LIBRARY()
+
+SRCS(
+ utf8.go
+)
+
+GO_XTEST_SRCS(
+ example_test.go
+ utf8_test.go
+)
+
+END()
+
+RECURSE(
+)
diff --git a/contrib/go/_std_1.21/src/unicode/ya.make b/contrib/go/_std_1.21/src/unicode/ya.make
new file mode 100644
index 0000000000..3cc995dbae
--- /dev/null
+++ b/contrib/go/_std_1.21/src/unicode/ya.make
@@ -0,0 +1,24 @@
+GO_LIBRARY()
+
+SRCS(
+ casetables.go
+ digit.go
+ graphic.go
+ letter.go
+ tables.go
+)
+
+GO_XTEST_SRCS(
+ digit_test.go
+ example_test.go
+ graphic_test.go
+ letter_test.go
+ script_test.go
+)
+
+END()
+
+RECURSE(
+ utf16
+ utf8
+)
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
index 94c71ac1ac..94c71ac1ac 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
index 63cae9e6f0..63cae9e6f0 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/chacha_generic.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/chacha_generic.go
index 93eb5ae6de..93eb5ae6de 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/chacha_generic.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/chacha_generic.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
index 025b49897e..025b49897e 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/xor.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/xor.go
index c2d04851e0..c2d04851e0 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20/xor.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/xor.go
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/ya.make
new file mode 100644
index 0000000000..d6d6039a62
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20/ya.make
@@ -0,0 +1,21 @@
+GO_LIBRARY()
+
+SRCS(
+ chacha_generic.go
+ xor.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ chacha_noasm.go
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ chacha_arm64.go
+ chacha_arm64.s
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
index 93da7322bc..93da7322bc 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
index 0c408c5709..0c408c5709 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
index 867c181a14..867c181a14 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_amd64.s
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
index 6313898f0a..6313898f0a 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_generic.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go
index f832b33d45..f832b33d45 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/chacha20poly1305_noasm.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go
index 1cebfe946f..1cebfe946f 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/xchacha20poly1305.go
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/ya.make
new file mode 100644
index 0000000000..91d40bbfef
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/chacha20poly1305/ya.make
@@ -0,0 +1,22 @@
+GO_LIBRARY()
+
+SRCS(
+ chacha20poly1305.go
+ chacha20poly1305_generic.go
+ xchacha20poly1305.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ chacha20poly1305_amd64.go
+ chacha20poly1305_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ chacha20poly1305_noasm.go
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go
new file mode 100644
index 0000000000..6fc2838a3f
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/asn1.go
@@ -0,0 +1,824 @@
+// Copyright 2017 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 cryptobyte
+
+import (
+ encoding_asn1 "encoding/asn1"
+ "fmt"
+ "math/big"
+ "reflect"
+ "time"
+
+ "golang.org/x/crypto/cryptobyte/asn1"
+)
+
+// This file contains ASN.1-related methods for String and Builder.
+
+// Builder
+
+// AddASN1Int64 appends a DER-encoded ASN.1 INTEGER.
+func (b *Builder) AddASN1Int64(v int64) {
+ b.addASN1Signed(asn1.INTEGER, v)
+}
+
+// AddASN1Int64WithTag appends a DER-encoded ASN.1 INTEGER with the
+// given tag.
+func (b *Builder) AddASN1Int64WithTag(v int64, tag asn1.Tag) {
+ b.addASN1Signed(tag, v)
+}
+
+// AddASN1Enum appends a DER-encoded ASN.1 ENUMERATION.
+func (b *Builder) AddASN1Enum(v int64) {
+ b.addASN1Signed(asn1.ENUM, v)
+}
+
+func (b *Builder) addASN1Signed(tag asn1.Tag, v int64) {
+ b.AddASN1(tag, func(c *Builder) {
+ length := 1
+ for i := v; i >= 0x80 || i < -0x80; i >>= 8 {
+ length++
+ }
+
+ for ; length > 0; length-- {
+ i := v >> uint((length-1)*8) & 0xff
+ c.AddUint8(uint8(i))
+ }
+ })
+}
+
+// AddASN1Uint64 appends a DER-encoded ASN.1 INTEGER.
+func (b *Builder) AddASN1Uint64(v uint64) {
+ b.AddASN1(asn1.INTEGER, func(c *Builder) {
+ length := 1
+ for i := v; i >= 0x80; i >>= 8 {
+ length++
+ }
+
+ for ; length > 0; length-- {
+ i := v >> uint((length-1)*8) & 0xff
+ c.AddUint8(uint8(i))
+ }
+ })
+}
+
+// AddASN1BigInt appends a DER-encoded ASN.1 INTEGER.
+func (b *Builder) AddASN1BigInt(n *big.Int) {
+ if b.err != nil {
+ return
+ }
+
+ b.AddASN1(asn1.INTEGER, func(c *Builder) {
+ if n.Sign() < 0 {
+ // A negative number has to be converted to two's-complement form. So we
+ // invert and subtract 1. If the most-significant-bit isn't set then
+ // we'll need to pad the beginning with 0xff in order to keep the number
+ // negative.
+ nMinus1 := new(big.Int).Neg(n)
+ nMinus1.Sub(nMinus1, bigOne)
+ bytes := nMinus1.Bytes()
+ for i := range bytes {
+ bytes[i] ^= 0xff
+ }
+ if len(bytes) == 0 || bytes[0]&0x80 == 0 {
+ c.add(0xff)
+ }
+ c.add(bytes...)
+ } else if n.Sign() == 0 {
+ c.add(0)
+ } else {
+ bytes := n.Bytes()
+ if bytes[0]&0x80 != 0 {
+ c.add(0)
+ }
+ c.add(bytes...)
+ }
+ })
+}
+
+// AddASN1OctetString appends a DER-encoded ASN.1 OCTET STRING.
+func (b *Builder) AddASN1OctetString(bytes []byte) {
+ b.AddASN1(asn1.OCTET_STRING, func(c *Builder) {
+ c.AddBytes(bytes)
+ })
+}
+
+const generalizedTimeFormatStr = "20060102150405Z0700"
+
+// AddASN1GeneralizedTime appends a DER-encoded ASN.1 GENERALIZEDTIME.
+func (b *Builder) AddASN1GeneralizedTime(t time.Time) {
+ if t.Year() < 0 || t.Year() > 9999 {
+ b.err = fmt.Errorf("cryptobyte: cannot represent %v as a GeneralizedTime", t)
+ return
+ }
+ b.AddASN1(asn1.GeneralizedTime, func(c *Builder) {
+ c.AddBytes([]byte(t.Format(generalizedTimeFormatStr)))
+ })
+}
+
+// AddASN1UTCTime appends a DER-encoded ASN.1 UTCTime.
+func (b *Builder) AddASN1UTCTime(t time.Time) {
+ b.AddASN1(asn1.UTCTime, func(c *Builder) {
+ // As utilized by the X.509 profile, UTCTime can only
+ // represent the years 1950 through 2049.
+ if t.Year() < 1950 || t.Year() >= 2050 {
+ b.err = fmt.Errorf("cryptobyte: cannot represent %v as a UTCTime", t)
+ return
+ }
+ c.AddBytes([]byte(t.Format(defaultUTCTimeFormatStr)))
+ })
+}
+
+// AddASN1BitString appends a DER-encoded ASN.1 BIT STRING. This does not
+// support BIT STRINGs that are not a whole number of bytes.
+func (b *Builder) AddASN1BitString(data []byte) {
+ b.AddASN1(asn1.BIT_STRING, func(b *Builder) {
+ b.AddUint8(0)
+ b.AddBytes(data)
+ })
+}
+
+func (b *Builder) addBase128Int(n int64) {
+ var length int
+ if n == 0 {
+ length = 1
+ } else {
+ for i := n; i > 0; i >>= 7 {
+ length++
+ }
+ }
+
+ for i := length - 1; i >= 0; i-- {
+ o := byte(n >> uint(i*7))
+ o &= 0x7f
+ if i != 0 {
+ o |= 0x80
+ }
+
+ b.add(o)
+ }
+}
+
+func isValidOID(oid encoding_asn1.ObjectIdentifier) bool {
+ if len(oid) < 2 {
+ return false
+ }
+
+ if oid[0] > 2 || (oid[0] <= 1 && oid[1] >= 40) {
+ return false
+ }
+
+ for _, v := range oid {
+ if v < 0 {
+ return false
+ }
+ }
+
+ return true
+}
+
+func (b *Builder) AddASN1ObjectIdentifier(oid encoding_asn1.ObjectIdentifier) {
+ b.AddASN1(asn1.OBJECT_IDENTIFIER, func(b *Builder) {
+ if !isValidOID(oid) {
+ b.err = fmt.Errorf("cryptobyte: invalid OID: %v", oid)
+ return
+ }
+
+ b.addBase128Int(int64(oid[0])*40 + int64(oid[1]))
+ for _, v := range oid[2:] {
+ b.addBase128Int(int64(v))
+ }
+ })
+}
+
+func (b *Builder) AddASN1Boolean(v bool) {
+ b.AddASN1(asn1.BOOLEAN, func(b *Builder) {
+ if v {
+ b.AddUint8(0xff)
+ } else {
+ b.AddUint8(0)
+ }
+ })
+}
+
+func (b *Builder) AddASN1NULL() {
+ b.add(uint8(asn1.NULL), 0)
+}
+
+// MarshalASN1 calls encoding_asn1.Marshal on its input and appends the result if
+// successful or records an error if one occurred.
+func (b *Builder) MarshalASN1(v interface{}) {
+ // NOTE(martinkr): This is somewhat of a hack to allow propagation of
+ // encoding_asn1.Marshal errors into Builder.err. N.B. if you call MarshalASN1 with a
+ // value embedded into a struct, its tag information is lost.
+ if b.err != nil {
+ return
+ }
+ bytes, err := encoding_asn1.Marshal(v)
+ if err != nil {
+ b.err = err
+ return
+ }
+ b.AddBytes(bytes)
+}
+
+// AddASN1 appends an ASN.1 object. The object is prefixed with the given tag.
+// Tags greater than 30 are not supported and result in an error (i.e.
+// low-tag-number form only). The child builder passed to the
+// BuilderContinuation can be used to build the content of the ASN.1 object.
+func (b *Builder) AddASN1(tag asn1.Tag, f BuilderContinuation) {
+ if b.err != nil {
+ return
+ }
+ // Identifiers with the low five bits set indicate high-tag-number format
+ // (two or more octets), which we don't support.
+ if tag&0x1f == 0x1f {
+ b.err = fmt.Errorf("cryptobyte: high-tag number identifier octects not supported: 0x%x", tag)
+ return
+ }
+ b.AddUint8(uint8(tag))
+ b.addLengthPrefixed(1, true, f)
+}
+
+// String
+
+// ReadASN1Boolean decodes an ASN.1 BOOLEAN and converts it to a boolean
+// representation into out and advances. It reports whether the read
+// was successful.
+func (s *String) ReadASN1Boolean(out *bool) bool {
+ var bytes String
+ if !s.ReadASN1(&bytes, asn1.BOOLEAN) || len(bytes) != 1 {
+ return false
+ }
+
+ switch bytes[0] {
+ case 0:
+ *out = false
+ case 0xff:
+ *out = true
+ default:
+ return false
+ }
+
+ return true
+}
+
+// ReadASN1Integer decodes an ASN.1 INTEGER into out and advances. If out does
+// not point to an integer, to a big.Int, or to a []byte it panics. Only
+// positive and zero values can be decoded into []byte, and they are returned as
+// big-endian binary values that share memory with s. Positive values will have
+// no leading zeroes, and zero will be returned as a single zero byte.
+// ReadASN1Integer reports whether the read was successful.
+func (s *String) ReadASN1Integer(out interface{}) bool {
+ switch out := out.(type) {
+ case *int, *int8, *int16, *int32, *int64:
+ var i int64
+ if !s.readASN1Int64(&i) || reflect.ValueOf(out).Elem().OverflowInt(i) {
+ return false
+ }
+ reflect.ValueOf(out).Elem().SetInt(i)
+ return true
+ case *uint, *uint8, *uint16, *uint32, *uint64:
+ var u uint64
+ if !s.readASN1Uint64(&u) || reflect.ValueOf(out).Elem().OverflowUint(u) {
+ return false
+ }
+ reflect.ValueOf(out).Elem().SetUint(u)
+ return true
+ case *big.Int:
+ return s.readASN1BigInt(out)
+ case *[]byte:
+ return s.readASN1Bytes(out)
+ default:
+ panic("out does not point to an integer type")
+ }
+}
+
+func checkASN1Integer(bytes []byte) bool {
+ if len(bytes) == 0 {
+ // An INTEGER is encoded with at least one octet.
+ return false
+ }
+ if len(bytes) == 1 {
+ return true
+ }
+ if bytes[0] == 0 && bytes[1]&0x80 == 0 || bytes[0] == 0xff && bytes[1]&0x80 == 0x80 {
+ // Value is not minimally encoded.
+ return false
+ }
+ return true
+}
+
+var bigOne = big.NewInt(1)
+
+func (s *String) readASN1BigInt(out *big.Int) bool {
+ var bytes String
+ if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) {
+ return false
+ }
+ if bytes[0]&0x80 == 0x80 {
+ // Negative number.
+ neg := make([]byte, len(bytes))
+ for i, b := range bytes {
+ neg[i] = ^b
+ }
+ out.SetBytes(neg)
+ out.Add(out, bigOne)
+ out.Neg(out)
+ } else {
+ out.SetBytes(bytes)
+ }
+ return true
+}
+
+func (s *String) readASN1Bytes(out *[]byte) bool {
+ var bytes String
+ if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) {
+ return false
+ }
+ if bytes[0]&0x80 == 0x80 {
+ return false
+ }
+ for len(bytes) > 1 && bytes[0] == 0 {
+ bytes = bytes[1:]
+ }
+ *out = bytes
+ return true
+}
+
+func (s *String) readASN1Int64(out *int64) bool {
+ var bytes String
+ if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Signed(out, bytes) {
+ return false
+ }
+ return true
+}
+
+func asn1Signed(out *int64, n []byte) bool {
+ length := len(n)
+ if length > 8 {
+ return false
+ }
+ for i := 0; i < length; i++ {
+ *out <<= 8
+ *out |= int64(n[i])
+ }
+ // Shift up and down in order to sign extend the result.
+ *out <<= 64 - uint8(length)*8
+ *out >>= 64 - uint8(length)*8
+ return true
+}
+
+func (s *String) readASN1Uint64(out *uint64) bool {
+ var bytes String
+ if !s.ReadASN1(&bytes, asn1.INTEGER) || !checkASN1Integer(bytes) || !asn1Unsigned(out, bytes) {
+ return false
+ }
+ return true
+}
+
+func asn1Unsigned(out *uint64, n []byte) bool {
+ length := len(n)
+ if length > 9 || length == 9 && n[0] != 0 {
+ // Too large for uint64.
+ return false
+ }
+ if n[0]&0x80 != 0 {
+ // Negative number.
+ return false
+ }
+ for i := 0; i < length; i++ {
+ *out <<= 8
+ *out |= uint64(n[i])
+ }
+ return true
+}
+
+// ReadASN1Int64WithTag decodes an ASN.1 INTEGER with the given tag into out
+// and advances. It reports whether the read was successful and resulted in a
+// value that can be represented in an int64.
+func (s *String) ReadASN1Int64WithTag(out *int64, tag asn1.Tag) bool {
+ var bytes String
+ return s.ReadASN1(&bytes, tag) && checkASN1Integer(bytes) && asn1Signed(out, bytes)
+}
+
+// ReadASN1Enum decodes an ASN.1 ENUMERATION into out and advances. It reports
+// whether the read was successful.
+func (s *String) ReadASN1Enum(out *int) bool {
+ var bytes String
+ var i int64
+ if !s.ReadASN1(&bytes, asn1.ENUM) || !checkASN1Integer(bytes) || !asn1Signed(&i, bytes) {
+ return false
+ }
+ if int64(int(i)) != i {
+ return false
+ }
+ *out = int(i)
+ return true
+}
+
+func (s *String) readBase128Int(out *int) bool {
+ ret := 0
+ for i := 0; len(*s) > 0; i++ {
+ if i == 5 {
+ return false
+ }
+ // Avoid overflowing int on a 32-bit platform.
+ // We don't want different behavior based on the architecture.
+ if ret >= 1<<(31-7) {
+ return false
+ }
+ ret <<= 7
+ b := s.read(1)[0]
+
+ // ITU-T X.690, section 8.19.2:
+ // The subidentifier shall be encoded in the fewest possible octets,
+ // that is, the leading octet of the subidentifier shall not have the value 0x80.
+ if i == 0 && b == 0x80 {
+ return false
+ }
+
+ ret |= int(b & 0x7f)
+ if b&0x80 == 0 {
+ *out = ret
+ return true
+ }
+ }
+ return false // truncated
+}
+
+// ReadASN1ObjectIdentifier decodes an ASN.1 OBJECT IDENTIFIER into out and
+// advances. It reports whether the read was successful.
+func (s *String) ReadASN1ObjectIdentifier(out *encoding_asn1.ObjectIdentifier) bool {
+ var bytes String
+ if !s.ReadASN1(&bytes, asn1.OBJECT_IDENTIFIER) || len(bytes) == 0 {
+ return false
+ }
+
+ // In the worst case, we get two elements from the first byte (which is
+ // encoded differently) and then every varint is a single byte long.
+ components := make([]int, len(bytes)+1)
+
+ // The first varint is 40*value1 + value2:
+ // According to this packing, value1 can take the values 0, 1 and 2 only.
+ // When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2,
+ // then there are no restrictions on value2.
+ var v int
+ if !bytes.readBase128Int(&v) {
+ return false
+ }
+ if v < 80 {
+ components[0] = v / 40
+ components[1] = v % 40
+ } else {
+ components[0] = 2
+ components[1] = v - 80
+ }
+
+ i := 2
+ for ; len(bytes) > 0; i++ {
+ if !bytes.readBase128Int(&v) {
+ return false
+ }
+ components[i] = v
+ }
+ *out = components[:i]
+ return true
+}
+
+// ReadASN1GeneralizedTime decodes an ASN.1 GENERALIZEDTIME into out and
+// advances. It reports whether the read was successful.
+func (s *String) ReadASN1GeneralizedTime(out *time.Time) bool {
+ var bytes String
+ if !s.ReadASN1(&bytes, asn1.GeneralizedTime) {
+ return false
+ }
+ t := string(bytes)
+ res, err := time.Parse(generalizedTimeFormatStr, t)
+ if err != nil {
+ return false
+ }
+ if serialized := res.Format(generalizedTimeFormatStr); serialized != t {
+ return false
+ }
+ *out = res
+ return true
+}
+
+const defaultUTCTimeFormatStr = "060102150405Z0700"
+
+// ReadASN1UTCTime decodes an ASN.1 UTCTime into out and advances.
+// It reports whether the read was successful.
+func (s *String) ReadASN1UTCTime(out *time.Time) bool {
+ var bytes String
+ if !s.ReadASN1(&bytes, asn1.UTCTime) {
+ return false
+ }
+ t := string(bytes)
+
+ formatStr := defaultUTCTimeFormatStr
+ var err error
+ res, err := time.Parse(formatStr, t)
+ if err != nil {
+ // Fallback to minute precision if we can't parse second
+ // precision. If we are following X.509 or X.690 we shouldn't
+ // support this, but we do.
+ formatStr = "0601021504Z0700"
+ res, err = time.Parse(formatStr, t)
+ }
+ if err != nil {
+ return false
+ }
+
+ if serialized := res.Format(formatStr); serialized != t {
+ return false
+ }
+
+ if res.Year() >= 2050 {
+ // UTCTime interprets the low order digits 50-99 as 1950-99.
+ // This only applies to its use in the X.509 profile.
+ // See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+ res = res.AddDate(-100, 0, 0)
+ }
+ *out = res
+ return true
+}
+
+// ReadASN1BitString decodes an ASN.1 BIT STRING into out and advances.
+// It reports whether the read was successful.
+func (s *String) ReadASN1BitString(out *encoding_asn1.BitString) bool {
+ var bytes String
+ if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 ||
+ len(bytes)*8/8 != len(bytes) {
+ return false
+ }
+
+ paddingBits := bytes[0]
+ bytes = bytes[1:]
+ if paddingBits > 7 ||
+ len(bytes) == 0 && paddingBits != 0 ||
+ len(bytes) > 0 && bytes[len(bytes)-1]&(1<<paddingBits-1) != 0 {
+ return false
+ }
+
+ out.BitLength = len(bytes)*8 - int(paddingBits)
+ out.Bytes = bytes
+ return true
+}
+
+// ReadASN1BitStringAsBytes decodes an ASN.1 BIT STRING into out and advances. It is
+// an error if the BIT STRING is not a whole number of bytes. It reports
+// whether the read was successful.
+func (s *String) ReadASN1BitStringAsBytes(out *[]byte) bool {
+ var bytes String
+ if !s.ReadASN1(&bytes, asn1.BIT_STRING) || len(bytes) == 0 {
+ return false
+ }
+
+ paddingBits := bytes[0]
+ if paddingBits != 0 {
+ return false
+ }
+ *out = bytes[1:]
+ return true
+}
+
+// ReadASN1Bytes reads the contents of a DER-encoded ASN.1 element (not including
+// tag and length bytes) into out, and advances. The element must match the
+// given tag. It reports whether the read was successful.
+func (s *String) ReadASN1Bytes(out *[]byte, tag asn1.Tag) bool {
+ return s.ReadASN1((*String)(out), tag)
+}
+
+// ReadASN1 reads the contents of a DER-encoded ASN.1 element (not including
+// tag and length bytes) into out, and advances. The element must match the
+// given tag. It reports whether the read was successful.
+//
+// Tags greater than 30 are not supported (i.e. low-tag-number format only).
+func (s *String) ReadASN1(out *String, tag asn1.Tag) bool {
+ var t asn1.Tag
+ if !s.ReadAnyASN1(out, &t) || t != tag {
+ return false
+ }
+ return true
+}
+
+// ReadASN1Element reads the contents of a DER-encoded ASN.1 element (including
+// tag and length bytes) into out, and advances. The element must match the
+// given tag. It reports whether the read was successful.
+//
+// Tags greater than 30 are not supported (i.e. low-tag-number format only).
+func (s *String) ReadASN1Element(out *String, tag asn1.Tag) bool {
+ var t asn1.Tag
+ if !s.ReadAnyASN1Element(out, &t) || t != tag {
+ return false
+ }
+ return true
+}
+
+// ReadAnyASN1 reads the contents of a DER-encoded ASN.1 element (not including
+// tag and length bytes) into out, sets outTag to its tag, and advances.
+// It reports whether the read was successful.
+//
+// Tags greater than 30 are not supported (i.e. low-tag-number format only).
+func (s *String) ReadAnyASN1(out *String, outTag *asn1.Tag) bool {
+ return s.readASN1(out, outTag, true /* skip header */)
+}
+
+// ReadAnyASN1Element reads the contents of a DER-encoded ASN.1 element
+// (including tag and length bytes) into out, sets outTag to is tag, and
+// advances. It reports whether the read was successful.
+//
+// Tags greater than 30 are not supported (i.e. low-tag-number format only).
+func (s *String) ReadAnyASN1Element(out *String, outTag *asn1.Tag) bool {
+ return s.readASN1(out, outTag, false /* include header */)
+}
+
+// PeekASN1Tag reports whether the next ASN.1 value on the string starts with
+// the given tag.
+func (s String) PeekASN1Tag(tag asn1.Tag) bool {
+ if len(s) == 0 {
+ return false
+ }
+ return asn1.Tag(s[0]) == tag
+}
+
+// SkipASN1 reads and discards an ASN.1 element with the given tag. It
+// reports whether the operation was successful.
+func (s *String) SkipASN1(tag asn1.Tag) bool {
+ var unused String
+ return s.ReadASN1(&unused, tag)
+}
+
+// ReadOptionalASN1 attempts to read the contents of a DER-encoded ASN.1
+// element (not including tag and length bytes) tagged with the given tag into
+// out. It stores whether an element with the tag was found in outPresent,
+// unless outPresent is nil. It reports whether the read was successful.
+func (s *String) ReadOptionalASN1(out *String, outPresent *bool, tag asn1.Tag) bool {
+ present := s.PeekASN1Tag(tag)
+ if outPresent != nil {
+ *outPresent = present
+ }
+ if present && !s.ReadASN1(out, tag) {
+ return false
+ }
+ return true
+}
+
+// SkipOptionalASN1 advances s over an ASN.1 element with the given tag, or
+// else leaves s unchanged. It reports whether the operation was successful.
+func (s *String) SkipOptionalASN1(tag asn1.Tag) bool {
+ if !s.PeekASN1Tag(tag) {
+ return true
+ }
+ var unused String
+ return s.ReadASN1(&unused, tag)
+}
+
+// ReadOptionalASN1Integer attempts to read an optional ASN.1 INTEGER explicitly
+// tagged with tag into out and advances. If no element with a matching tag is
+// present, it writes defaultValue into out instead. Otherwise, it behaves like
+// ReadASN1Integer.
+func (s *String) ReadOptionalASN1Integer(out interface{}, tag asn1.Tag, defaultValue interface{}) bool {
+ var present bool
+ var i String
+ if !s.ReadOptionalASN1(&i, &present, tag) {
+ return false
+ }
+ if !present {
+ switch out.(type) {
+ case *int, *int8, *int16, *int32, *int64,
+ *uint, *uint8, *uint16, *uint32, *uint64, *[]byte:
+ reflect.ValueOf(out).Elem().Set(reflect.ValueOf(defaultValue))
+ case *big.Int:
+ if defaultValue, ok := defaultValue.(*big.Int); ok {
+ out.(*big.Int).Set(defaultValue)
+ } else {
+ panic("out points to big.Int, but defaultValue does not")
+ }
+ default:
+ panic("invalid integer type")
+ }
+ return true
+ }
+ if !i.ReadASN1Integer(out) || !i.Empty() {
+ return false
+ }
+ return true
+}
+
+// ReadOptionalASN1OctetString attempts to read an optional ASN.1 OCTET STRING
+// explicitly tagged with tag into out and advances. If no element with a
+// matching tag is present, it sets "out" to nil instead. It reports
+// whether the read was successful.
+func (s *String) ReadOptionalASN1OctetString(out *[]byte, outPresent *bool, tag asn1.Tag) bool {
+ var present bool
+ var child String
+ if !s.ReadOptionalASN1(&child, &present, tag) {
+ return false
+ }
+ if outPresent != nil {
+ *outPresent = present
+ }
+ if present {
+ var oct String
+ if !child.ReadASN1(&oct, asn1.OCTET_STRING) || !child.Empty() {
+ return false
+ }
+ *out = oct
+ } else {
+ *out = nil
+ }
+ return true
+}
+
+// ReadOptionalASN1Boolean sets *out to the value of the next ASN.1 BOOLEAN or,
+// if the next bytes are not an ASN.1 BOOLEAN, to the value of defaultValue.
+// It reports whether the operation was successful.
+func (s *String) ReadOptionalASN1Boolean(out *bool, defaultValue bool) bool {
+ var present bool
+ var child String
+ if !s.ReadOptionalASN1(&child, &present, asn1.BOOLEAN) {
+ return false
+ }
+
+ if !present {
+ *out = defaultValue
+ return true
+ }
+
+ return s.ReadASN1Boolean(out)
+}
+
+func (s *String) readASN1(out *String, outTag *asn1.Tag, skipHeader bool) bool {
+ if len(*s) < 2 {
+ return false
+ }
+ tag, lenByte := (*s)[0], (*s)[1]
+
+ if tag&0x1f == 0x1f {
+ // ITU-T X.690 section 8.1.2
+ //
+ // An identifier octet with a tag part of 0x1f indicates a high-tag-number
+ // form identifier with two or more octets. We only support tags less than
+ // 31 (i.e. low-tag-number form, single octet identifier).
+ return false
+ }
+
+ if outTag != nil {
+ *outTag = asn1.Tag(tag)
+ }
+
+ // ITU-T X.690 section 8.1.3
+ //
+ // Bit 8 of the first length byte indicates whether the length is short- or
+ // long-form.
+ var length, headerLen uint32 // length includes headerLen
+ if lenByte&0x80 == 0 {
+ // Short-form length (section 8.1.3.4), encoded in bits 1-7.
+ length = uint32(lenByte) + 2
+ headerLen = 2
+ } else {
+ // Long-form length (section 8.1.3.5). Bits 1-7 encode the number of octets
+ // used to encode the length.
+ lenLen := lenByte & 0x7f
+ var len32 uint32
+
+ if lenLen == 0 || lenLen > 4 || len(*s) < int(2+lenLen) {
+ return false
+ }
+
+ lenBytes := String((*s)[2 : 2+lenLen])
+ if !lenBytes.readUnsigned(&len32, int(lenLen)) {
+ return false
+ }
+
+ // ITU-T X.690 section 10.1 (DER length forms) requires encoding the length
+ // with the minimum number of octets.
+ if len32 < 128 {
+ // Length should have used short-form encoding.
+ return false
+ }
+ if len32>>((lenLen-1)*8) == 0 {
+ // Leading octet is 0. Length should have been at least one byte shorter.
+ return false
+ }
+
+ headerLen = 2 + uint32(lenLen)
+ if headerLen+len32 < len32 {
+ // Overflow.
+ return false
+ }
+ length = headerLen + len32
+ }
+
+ if int(length) < 0 || !s.ReadBytes((*[]byte)(out), int(length)) {
+ return false
+ }
+ if skipHeader && !out.Skip(int(headerLen)) {
+ panic("cryptobyte: internal error")
+ }
+
+ return true
+}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go
index cda8e3edfd..cda8e3edfd 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/asn1/asn1.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/asn1/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/asn1/ya.make
index 9e121b1b3f..9e121b1b3f 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/asn1/ya.make
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/asn1/ya.make
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/builder.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/builder.go
new file mode 100644
index 0000000000..c05ac7d16d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/builder.go
@@ -0,0 +1,345 @@
+// Copyright 2017 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 cryptobyte
+
+import (
+ "errors"
+ "fmt"
+)
+
+// A Builder builds byte strings from fixed-length and length-prefixed values.
+// Builders either allocate space as needed, or are ‘fixed’, which means that
+// they write into a given buffer and produce an error if it's exhausted.
+//
+// The zero value is a usable Builder that allocates space as needed.
+//
+// Simple values are marshaled and appended to a Builder using methods on the
+// Builder. Length-prefixed values are marshaled by providing a
+// BuilderContinuation, which is a function that writes the inner contents of
+// the value to a given Builder. See the documentation for BuilderContinuation
+// for details.
+type Builder struct {
+ err error
+ result []byte
+ fixedSize bool
+ child *Builder
+ offset int
+ pendingLenLen int
+ pendingIsASN1 bool
+ inContinuation *bool
+}
+
+// NewBuilder creates a Builder that appends its output to the given buffer.
+// Like append(), the slice will be reallocated if its capacity is exceeded.
+// Use Bytes to get the final buffer.
+func NewBuilder(buffer []byte) *Builder {
+ return &Builder{
+ result: buffer,
+ }
+}
+
+// NewFixedBuilder creates a Builder that appends its output into the given
+// buffer. This builder does not reallocate the output buffer. Writes that
+// would exceed the buffer's capacity are treated as an error.
+func NewFixedBuilder(buffer []byte) *Builder {
+ return &Builder{
+ result: buffer,
+ fixedSize: true,
+ }
+}
+
+// SetError sets the value to be returned as the error from Bytes. Writes
+// performed after calling SetError are ignored.
+func (b *Builder) SetError(err error) {
+ b.err = err
+}
+
+// Bytes returns the bytes written by the builder or an error if one has
+// occurred during building.
+func (b *Builder) Bytes() ([]byte, error) {
+ if b.err != nil {
+ return nil, b.err
+ }
+ return b.result[b.offset:], nil
+}
+
+// BytesOrPanic returns the bytes written by the builder or panics if an error
+// has occurred during building.
+func (b *Builder) BytesOrPanic() []byte {
+ if b.err != nil {
+ panic(b.err)
+ }
+ return b.result[b.offset:]
+}
+
+// AddUint8 appends an 8-bit value to the byte string.
+func (b *Builder) AddUint8(v uint8) {
+ b.add(byte(v))
+}
+
+// AddUint16 appends a big-endian, 16-bit value to the byte string.
+func (b *Builder) AddUint16(v uint16) {
+ b.add(byte(v>>8), byte(v))
+}
+
+// AddUint24 appends a big-endian, 24-bit value to the byte string. The highest
+// byte of the 32-bit input value is silently truncated.
+func (b *Builder) AddUint24(v uint32) {
+ b.add(byte(v>>16), byte(v>>8), byte(v))
+}
+
+// AddUint32 appends a big-endian, 32-bit value to the byte string.
+func (b *Builder) AddUint32(v uint32) {
+ b.add(byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
+}
+
+// AddUint64 appends a big-endian, 64-bit value to the byte string.
+func (b *Builder) AddUint64(v uint64) {
+ b.add(byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
+}
+
+// AddBytes appends a sequence of bytes to the byte string.
+func (b *Builder) AddBytes(v []byte) {
+ b.add(v...)
+}
+
+// BuilderContinuation is a continuation-passing interface for building
+// length-prefixed byte sequences. Builder methods for length-prefixed
+// sequences (AddUint8LengthPrefixed etc) will invoke the BuilderContinuation
+// supplied to them. The child builder passed to the continuation can be used
+// to build the content of the length-prefixed sequence. For example:
+//
+// parent := cryptobyte.NewBuilder()
+// parent.AddUint8LengthPrefixed(func (child *Builder) {
+// child.AddUint8(42)
+// child.AddUint8LengthPrefixed(func (grandchild *Builder) {
+// grandchild.AddUint8(5)
+// })
+// })
+//
+// It is an error to write more bytes to the child than allowed by the reserved
+// length prefix. After the continuation returns, the child must be considered
+// invalid, i.e. users must not store any copies or references of the child
+// that outlive the continuation.
+//
+// If the continuation panics with a value of type BuildError then the inner
+// error will be returned as the error from Bytes. If the child panics
+// otherwise then Bytes will repanic with the same value.
+type BuilderContinuation func(child *Builder)
+
+// BuildError wraps an error. If a BuilderContinuation panics with this value,
+// the panic will be recovered and the inner error will be returned from
+// Builder.Bytes.
+type BuildError struct {
+ Err error
+}
+
+// AddUint8LengthPrefixed adds a 8-bit length-prefixed byte sequence.
+func (b *Builder) AddUint8LengthPrefixed(f BuilderContinuation) {
+ b.addLengthPrefixed(1, false, f)
+}
+
+// AddUint16LengthPrefixed adds a big-endian, 16-bit length-prefixed byte sequence.
+func (b *Builder) AddUint16LengthPrefixed(f BuilderContinuation) {
+ b.addLengthPrefixed(2, false, f)
+}
+
+// AddUint24LengthPrefixed adds a big-endian, 24-bit length-prefixed byte sequence.
+func (b *Builder) AddUint24LengthPrefixed(f BuilderContinuation) {
+ b.addLengthPrefixed(3, false, f)
+}
+
+// AddUint32LengthPrefixed adds a big-endian, 32-bit length-prefixed byte sequence.
+func (b *Builder) AddUint32LengthPrefixed(f BuilderContinuation) {
+ b.addLengthPrefixed(4, false, f)
+}
+
+func (b *Builder) callContinuation(f BuilderContinuation, arg *Builder) {
+ if !*b.inContinuation {
+ *b.inContinuation = true
+
+ defer func() {
+ *b.inContinuation = false
+
+ r := recover()
+ if r == nil {
+ return
+ }
+
+ if buildError, ok := r.(BuildError); ok {
+ b.err = buildError.Err
+ } else {
+ panic(r)
+ }
+ }()
+ }
+
+ f(arg)
+}
+
+func (b *Builder) addLengthPrefixed(lenLen int, isASN1 bool, f BuilderContinuation) {
+ // Subsequent writes can be ignored if the builder has encountered an error.
+ if b.err != nil {
+ return
+ }
+
+ offset := len(b.result)
+ b.add(make([]byte, lenLen)...)
+
+ if b.inContinuation == nil {
+ b.inContinuation = new(bool)
+ }
+
+ b.child = &Builder{
+ result: b.result,
+ fixedSize: b.fixedSize,
+ offset: offset,
+ pendingLenLen: lenLen,
+ pendingIsASN1: isASN1,
+ inContinuation: b.inContinuation,
+ }
+
+ b.callContinuation(f, b.child)
+ b.flushChild()
+ if b.child != nil {
+ panic("cryptobyte: internal error")
+ }
+}
+
+func (b *Builder) flushChild() {
+ if b.child == nil {
+ return
+ }
+ b.child.flushChild()
+ child := b.child
+ b.child = nil
+
+ if child.err != nil {
+ b.err = child.err
+ return
+ }
+
+ length := len(child.result) - child.pendingLenLen - child.offset
+
+ if length < 0 {
+ panic("cryptobyte: internal error") // result unexpectedly shrunk
+ }
+
+ if child.pendingIsASN1 {
+ // For ASN.1, we reserved a single byte for the length. If that turned out
+ // to be incorrect, we have to move the contents along in order to make
+ // space.
+ if child.pendingLenLen != 1 {
+ panic("cryptobyte: internal error")
+ }
+ var lenLen, lenByte uint8
+ if int64(length) > 0xfffffffe {
+ b.err = errors.New("pending ASN.1 child too long")
+ return
+ } else if length > 0xffffff {
+ lenLen = 5
+ lenByte = 0x80 | 4
+ } else if length > 0xffff {
+ lenLen = 4
+ lenByte = 0x80 | 3
+ } else if length > 0xff {
+ lenLen = 3
+ lenByte = 0x80 | 2
+ } else if length > 0x7f {
+ lenLen = 2
+ lenByte = 0x80 | 1
+ } else {
+ lenLen = 1
+ lenByte = uint8(length)
+ length = 0
+ }
+
+ // Insert the initial length byte, make space for successive length bytes,
+ // and adjust the offset.
+ child.result[child.offset] = lenByte
+ extraBytes := int(lenLen - 1)
+ if extraBytes != 0 {
+ child.add(make([]byte, extraBytes)...)
+ childStart := child.offset + child.pendingLenLen
+ copy(child.result[childStart+extraBytes:], child.result[childStart:])
+ }
+ child.offset++
+ child.pendingLenLen = extraBytes
+ }
+
+ l := length
+ for i := child.pendingLenLen - 1; i >= 0; i-- {
+ child.result[child.offset+i] = uint8(l)
+ l >>= 8
+ }
+ if l != 0 {
+ b.err = fmt.Errorf("cryptobyte: pending child length %d exceeds %d-byte length prefix", length, child.pendingLenLen)
+ return
+ }
+
+ if b.fixedSize && &b.result[0] != &child.result[0] {
+ panic("cryptobyte: BuilderContinuation reallocated a fixed-size buffer")
+ }
+
+ b.result = child.result
+}
+
+func (b *Builder) add(bytes ...byte) {
+ if b.err != nil {
+ return
+ }
+ if b.child != nil {
+ panic("cryptobyte: attempted write while child is pending")
+ }
+ if len(b.result)+len(bytes) < len(bytes) {
+ b.err = errors.New("cryptobyte: length overflow")
+ }
+ if b.fixedSize && len(b.result)+len(bytes) > cap(b.result) {
+ b.err = errors.New("cryptobyte: Builder is exceeding its fixed-size buffer")
+ return
+ }
+ b.result = append(b.result, bytes...)
+}
+
+// Unwrite rolls back non-negative n bytes written directly to the Builder.
+// An attempt by a child builder passed to a continuation to unwrite bytes
+// from its parent will panic.
+func (b *Builder) Unwrite(n int) {
+ if b.err != nil {
+ return
+ }
+ if b.child != nil {
+ panic("cryptobyte: attempted unwrite while child is pending")
+ }
+ length := len(b.result) - b.pendingLenLen - b.offset
+ if length < 0 {
+ panic("cryptobyte: internal error")
+ }
+ if n < 0 {
+ panic("cryptobyte: attempted to unwrite negative number of bytes")
+ }
+ if n > length {
+ panic("cryptobyte: attempted to unwrite more than was written")
+ }
+ b.result = b.result[:len(b.result)-n]
+}
+
+// A MarshalingValue marshals itself into a Builder.
+type MarshalingValue interface {
+ // Marshal is called by Builder.AddValue. It receives a pointer to a builder
+ // to marshal itself into. It may return an error that occurred during
+ // marshaling, such as unset or invalid values.
+ Marshal(b *Builder) error
+}
+
+// AddValue calls Marshal on v, passing a pointer to the builder to append to.
+// If Marshal returns an error, it is set on the Builder so that subsequent
+// appends don't have an effect.
+func (b *Builder) AddValue(v MarshalingValue) {
+ err := v.Marshal(b)
+ if err != nil {
+ b.err = err
+ }
+}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/string.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/string.go
index 0531a3d6f1..0531a3d6f1 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/string.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/string.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/ya.make
index eeef667c24..eeef667c24 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/cryptobyte/ya.make
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/cryptobyte/ya.make
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/hkdf/hkdf.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/hkdf/hkdf.go
index dda3f143be..dda3f143be 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/hkdf/hkdf.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/hkdf/hkdf.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/hkdf/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/hkdf/ya.make
index c575e2323c..c575e2323c 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/hkdf/ya.make
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/hkdf/ya.make
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/alias/alias.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/alias/alias.go
index 69c17f822b..69c17f822b 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/alias/alias.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/alias/alias.go
diff --git a/contrib/go/_std_1.20/src/crypto/internal/alias/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/alias/ya.make
index a2089740ca..a2089740ca 100644
--- a/contrib/go/_std_1.20/src/crypto/internal/alias/ya.make
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/alias/ya.make
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go
index ed52b3418a..ed52b3418a 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/bits_go1.13.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go
index f184b67d98..f184b67d98 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/mac_noasm.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go
index 4aaea810a2..4aaea810a2 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/poly1305.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go
index 6d522333f2..6d522333f2 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s
index 1d74f0f881..1d74f0f881 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/sum_amd64.s
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go
index e041da5ea3..e041da5ea3 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/sum_generic.go
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/ya.make
new file mode 100644
index 0000000000..0ccd3752c2
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/crypto/internal/poly1305/ya.make
@@ -0,0 +1,22 @@
+GO_LIBRARY()
+
+SRCS(
+ bits_go1.13.go
+ poly1305.go
+ sum_generic.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ sum_amd64.go
+ sum_amd64.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ mac_noasm.go
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/net/dns/dnsmessage/message.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/dns/dnsmessage/message.go
new file mode 100644
index 0000000000..37da3de4d3
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/dns/dnsmessage/message.go
@@ -0,0 +1,2694 @@
+// Copyright 2009 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 dnsmessage provides a mostly RFC 1035 compliant implementation of
+// DNS message packing and unpacking.
+//
+// The package also supports messages with Extension Mechanisms for DNS
+// (EDNS(0)) as defined in RFC 6891.
+//
+// This implementation is designed to minimize heap allocations and avoid
+// unnecessary packing and unpacking as much as possible.
+package dnsmessage
+
+import (
+ "errors"
+)
+
+// Message formats
+
+// A Type is a type of DNS request and response.
+type Type uint16
+
+const (
+ // ResourceHeader.Type and Question.Type
+ TypeA Type = 1
+ TypeNS Type = 2
+ TypeCNAME Type = 5
+ TypeSOA Type = 6
+ TypePTR Type = 12
+ TypeMX Type = 15
+ TypeTXT Type = 16
+ TypeAAAA Type = 28
+ TypeSRV Type = 33
+ TypeOPT Type = 41
+
+ // Question.Type
+ TypeWKS Type = 11
+ TypeHINFO Type = 13
+ TypeMINFO Type = 14
+ TypeAXFR Type = 252
+ TypeALL Type = 255
+)
+
+var typeNames = map[Type]string{
+ TypeA: "TypeA",
+ TypeNS: "TypeNS",
+ TypeCNAME: "TypeCNAME",
+ TypeSOA: "TypeSOA",
+ TypePTR: "TypePTR",
+ TypeMX: "TypeMX",
+ TypeTXT: "TypeTXT",
+ TypeAAAA: "TypeAAAA",
+ TypeSRV: "TypeSRV",
+ TypeOPT: "TypeOPT",
+ TypeWKS: "TypeWKS",
+ TypeHINFO: "TypeHINFO",
+ TypeMINFO: "TypeMINFO",
+ TypeAXFR: "TypeAXFR",
+ TypeALL: "TypeALL",
+}
+
+// String implements fmt.Stringer.String.
+func (t Type) String() string {
+ if n, ok := typeNames[t]; ok {
+ return n
+ }
+ return printUint16(uint16(t))
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (t Type) GoString() string {
+ if n, ok := typeNames[t]; ok {
+ return "dnsmessage." + n
+ }
+ return printUint16(uint16(t))
+}
+
+// A Class is a type of network.
+type Class uint16
+
+const (
+ // ResourceHeader.Class and Question.Class
+ ClassINET Class = 1
+ ClassCSNET Class = 2
+ ClassCHAOS Class = 3
+ ClassHESIOD Class = 4
+
+ // Question.Class
+ ClassANY Class = 255
+)
+
+var classNames = map[Class]string{
+ ClassINET: "ClassINET",
+ ClassCSNET: "ClassCSNET",
+ ClassCHAOS: "ClassCHAOS",
+ ClassHESIOD: "ClassHESIOD",
+ ClassANY: "ClassANY",
+}
+
+// String implements fmt.Stringer.String.
+func (c Class) String() string {
+ if n, ok := classNames[c]; ok {
+ return n
+ }
+ return printUint16(uint16(c))
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (c Class) GoString() string {
+ if n, ok := classNames[c]; ok {
+ return "dnsmessage." + n
+ }
+ return printUint16(uint16(c))
+}
+
+// An OpCode is a DNS operation code.
+type OpCode uint16
+
+// GoString implements fmt.GoStringer.GoString.
+func (o OpCode) GoString() string {
+ return printUint16(uint16(o))
+}
+
+// An RCode is a DNS response status code.
+type RCode uint16
+
+// Header.RCode values.
+const (
+ RCodeSuccess RCode = 0 // NoError
+ RCodeFormatError RCode = 1 // FormErr
+ RCodeServerFailure RCode = 2 // ServFail
+ RCodeNameError RCode = 3 // NXDomain
+ RCodeNotImplemented RCode = 4 // NotImp
+ RCodeRefused RCode = 5 // Refused
+)
+
+var rCodeNames = map[RCode]string{
+ RCodeSuccess: "RCodeSuccess",
+ RCodeFormatError: "RCodeFormatError",
+ RCodeServerFailure: "RCodeServerFailure",
+ RCodeNameError: "RCodeNameError",
+ RCodeNotImplemented: "RCodeNotImplemented",
+ RCodeRefused: "RCodeRefused",
+}
+
+// String implements fmt.Stringer.String.
+func (r RCode) String() string {
+ if n, ok := rCodeNames[r]; ok {
+ return n
+ }
+ return printUint16(uint16(r))
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r RCode) GoString() string {
+ if n, ok := rCodeNames[r]; ok {
+ return "dnsmessage." + n
+ }
+ return printUint16(uint16(r))
+}
+
+func printPaddedUint8(i uint8) string {
+ b := byte(i)
+ return string([]byte{
+ b/100 + '0',
+ b/10%10 + '0',
+ b%10 + '0',
+ })
+}
+
+func printUint8Bytes(buf []byte, i uint8) []byte {
+ b := byte(i)
+ if i >= 100 {
+ buf = append(buf, b/100+'0')
+ }
+ if i >= 10 {
+ buf = append(buf, b/10%10+'0')
+ }
+ return append(buf, b%10+'0')
+}
+
+func printByteSlice(b []byte) string {
+ if len(b) == 0 {
+ return ""
+ }
+ buf := make([]byte, 0, 5*len(b))
+ buf = printUint8Bytes(buf, uint8(b[0]))
+ for _, n := range b[1:] {
+ buf = append(buf, ',', ' ')
+ buf = printUint8Bytes(buf, uint8(n))
+ }
+ return string(buf)
+}
+
+const hexDigits = "0123456789abcdef"
+
+func printString(str []byte) string {
+ buf := make([]byte, 0, len(str))
+ for i := 0; i < len(str); i++ {
+ c := str[i]
+ if c == '.' || c == '-' || c == ' ' ||
+ 'A' <= c && c <= 'Z' ||
+ 'a' <= c && c <= 'z' ||
+ '0' <= c && c <= '9' {
+ buf = append(buf, c)
+ continue
+ }
+
+ upper := c >> 4
+ lower := (c << 4) >> 4
+ buf = append(
+ buf,
+ '\\',
+ 'x',
+ hexDigits[upper],
+ hexDigits[lower],
+ )
+ }
+ return string(buf)
+}
+
+func printUint16(i uint16) string {
+ return printUint32(uint32(i))
+}
+
+func printUint32(i uint32) string {
+ // Max value is 4294967295.
+ buf := make([]byte, 10)
+ for b, d := buf, uint32(1000000000); d > 0; d /= 10 {
+ b[0] = byte(i/d%10 + '0')
+ if b[0] == '0' && len(b) == len(buf) && len(buf) > 1 {
+ buf = buf[1:]
+ }
+ b = b[1:]
+ i %= d
+ }
+ return string(buf)
+}
+
+func printBool(b bool) string {
+ if b {
+ return "true"
+ }
+ return "false"
+}
+
+var (
+ // ErrNotStarted indicates that the prerequisite information isn't
+ // available yet because the previous records haven't been appropriately
+ // parsed, skipped or finished.
+ ErrNotStarted = errors.New("parsing/packing of this type isn't available yet")
+
+ // ErrSectionDone indicated that all records in the section have been
+ // parsed or finished.
+ ErrSectionDone = errors.New("parsing/packing of this section has completed")
+
+ errBaseLen = errors.New("insufficient data for base length type")
+ errCalcLen = errors.New("insufficient data for calculated length type")
+ errReserved = errors.New("segment prefix is reserved")
+ errTooManyPtr = errors.New("too many pointers (>10)")
+ errInvalidPtr = errors.New("invalid pointer")
+ errInvalidName = errors.New("invalid dns name")
+ errNilResouceBody = errors.New("nil resource body")
+ errResourceLen = errors.New("insufficient data for resource body length")
+ errSegTooLong = errors.New("segment length too long")
+ errNameTooLong = errors.New("name too long")
+ errZeroSegLen = errors.New("zero length segment")
+ errResTooLong = errors.New("resource length too long")
+ errTooManyQuestions = errors.New("too many Questions to pack (>65535)")
+ errTooManyAnswers = errors.New("too many Answers to pack (>65535)")
+ errTooManyAuthorities = errors.New("too many Authorities to pack (>65535)")
+ errTooManyAdditionals = errors.New("too many Additionals to pack (>65535)")
+ errNonCanonicalName = errors.New("name is not in canonical format (it must end with a .)")
+ errStringTooLong = errors.New("character string exceeds maximum length (255)")
+ errCompressedSRV = errors.New("compressed name in SRV resource data")
+)
+
+// Internal constants.
+const (
+ // packStartingCap is the default initial buffer size allocated during
+ // packing.
+ //
+ // The starting capacity doesn't matter too much, but most DNS responses
+ // Will be <= 512 bytes as it is the limit for DNS over UDP.
+ packStartingCap = 512
+
+ // uint16Len is the length (in bytes) of a uint16.
+ uint16Len = 2
+
+ // uint32Len is the length (in bytes) of a uint32.
+ uint32Len = 4
+
+ // headerLen is the length (in bytes) of a DNS header.
+ //
+ // A header is comprised of 6 uint16s and no padding.
+ headerLen = 6 * uint16Len
+)
+
+type nestedError struct {
+ // s is the current level's error message.
+ s string
+
+ // err is the nested error.
+ err error
+}
+
+// nestedError implements error.Error.
+func (e *nestedError) Error() string {
+ return e.s + ": " + e.err.Error()
+}
+
+// Header is a representation of a DNS message header.
+type Header struct {
+ ID uint16
+ Response bool
+ OpCode OpCode
+ Authoritative bool
+ Truncated bool
+ RecursionDesired bool
+ RecursionAvailable bool
+ AuthenticData bool
+ CheckingDisabled bool
+ RCode RCode
+}
+
+func (m *Header) pack() (id uint16, bits uint16) {
+ id = m.ID
+ bits = uint16(m.OpCode)<<11 | uint16(m.RCode)
+ if m.RecursionAvailable {
+ bits |= headerBitRA
+ }
+ if m.RecursionDesired {
+ bits |= headerBitRD
+ }
+ if m.Truncated {
+ bits |= headerBitTC
+ }
+ if m.Authoritative {
+ bits |= headerBitAA
+ }
+ if m.Response {
+ bits |= headerBitQR
+ }
+ if m.AuthenticData {
+ bits |= headerBitAD
+ }
+ if m.CheckingDisabled {
+ bits |= headerBitCD
+ }
+ return
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (m *Header) GoString() string {
+ return "dnsmessage.Header{" +
+ "ID: " + printUint16(m.ID) + ", " +
+ "Response: " + printBool(m.Response) + ", " +
+ "OpCode: " + m.OpCode.GoString() + ", " +
+ "Authoritative: " + printBool(m.Authoritative) + ", " +
+ "Truncated: " + printBool(m.Truncated) + ", " +
+ "RecursionDesired: " + printBool(m.RecursionDesired) + ", " +
+ "RecursionAvailable: " + printBool(m.RecursionAvailable) + ", " +
+ "RCode: " + m.RCode.GoString() + "}"
+}
+
+// Message is a representation of a DNS message.
+type Message struct {
+ Header
+ Questions []Question
+ Answers []Resource
+ Authorities []Resource
+ Additionals []Resource
+}
+
+type section uint8
+
+const (
+ sectionNotStarted section = iota
+ sectionHeader
+ sectionQuestions
+ sectionAnswers
+ sectionAuthorities
+ sectionAdditionals
+ sectionDone
+
+ headerBitQR = 1 << 15 // query/response (response=1)
+ headerBitAA = 1 << 10 // authoritative
+ headerBitTC = 1 << 9 // truncated
+ headerBitRD = 1 << 8 // recursion desired
+ headerBitRA = 1 << 7 // recursion available
+ headerBitAD = 1 << 5 // authentic data
+ headerBitCD = 1 << 4 // checking disabled
+)
+
+var sectionNames = map[section]string{
+ sectionHeader: "header",
+ sectionQuestions: "Question",
+ sectionAnswers: "Answer",
+ sectionAuthorities: "Authority",
+ sectionAdditionals: "Additional",
+}
+
+// header is the wire format for a DNS message header.
+type header struct {
+ id uint16
+ bits uint16
+ questions uint16
+ answers uint16
+ authorities uint16
+ additionals uint16
+}
+
+func (h *header) count(sec section) uint16 {
+ switch sec {
+ case sectionQuestions:
+ return h.questions
+ case sectionAnswers:
+ return h.answers
+ case sectionAuthorities:
+ return h.authorities
+ case sectionAdditionals:
+ return h.additionals
+ }
+ return 0
+}
+
+// pack appends the wire format of the header to msg.
+func (h *header) pack(msg []byte) []byte {
+ msg = packUint16(msg, h.id)
+ msg = packUint16(msg, h.bits)
+ msg = packUint16(msg, h.questions)
+ msg = packUint16(msg, h.answers)
+ msg = packUint16(msg, h.authorities)
+ return packUint16(msg, h.additionals)
+}
+
+func (h *header) unpack(msg []byte, off int) (int, error) {
+ newOff := off
+ var err error
+ if h.id, newOff, err = unpackUint16(msg, newOff); err != nil {
+ return off, &nestedError{"id", err}
+ }
+ if h.bits, newOff, err = unpackUint16(msg, newOff); err != nil {
+ return off, &nestedError{"bits", err}
+ }
+ if h.questions, newOff, err = unpackUint16(msg, newOff); err != nil {
+ return off, &nestedError{"questions", err}
+ }
+ if h.answers, newOff, err = unpackUint16(msg, newOff); err != nil {
+ return off, &nestedError{"answers", err}
+ }
+ if h.authorities, newOff, err = unpackUint16(msg, newOff); err != nil {
+ return off, &nestedError{"authorities", err}
+ }
+ if h.additionals, newOff, err = unpackUint16(msg, newOff); err != nil {
+ return off, &nestedError{"additionals", err}
+ }
+ return newOff, nil
+}
+
+func (h *header) header() Header {
+ return Header{
+ ID: h.id,
+ Response: (h.bits & headerBitQR) != 0,
+ OpCode: OpCode(h.bits>>11) & 0xF,
+ Authoritative: (h.bits & headerBitAA) != 0,
+ Truncated: (h.bits & headerBitTC) != 0,
+ RecursionDesired: (h.bits & headerBitRD) != 0,
+ RecursionAvailable: (h.bits & headerBitRA) != 0,
+ AuthenticData: (h.bits & headerBitAD) != 0,
+ CheckingDisabled: (h.bits & headerBitCD) != 0,
+ RCode: RCode(h.bits & 0xF),
+ }
+}
+
+// A Resource is a DNS resource record.
+type Resource struct {
+ Header ResourceHeader
+ Body ResourceBody
+}
+
+func (r *Resource) GoString() string {
+ return "dnsmessage.Resource{" +
+ "Header: " + r.Header.GoString() +
+ ", Body: &" + r.Body.GoString() +
+ "}"
+}
+
+// A ResourceBody is a DNS resource record minus the header.
+type ResourceBody interface {
+ // pack packs a Resource except for its header.
+ pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error)
+
+ // realType returns the actual type of the Resource. This is used to
+ // fill in the header Type field.
+ realType() Type
+
+ // GoString implements fmt.GoStringer.GoString.
+ GoString() string
+}
+
+// pack appends the wire format of the Resource to msg.
+func (r *Resource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ if r.Body == nil {
+ return msg, errNilResouceBody
+ }
+ oldMsg := msg
+ r.Header.Type = r.Body.realType()
+ msg, lenOff, err := r.Header.pack(msg, compression, compressionOff)
+ if err != nil {
+ return msg, &nestedError{"ResourceHeader", err}
+ }
+ preLen := len(msg)
+ msg, err = r.Body.pack(msg, compression, compressionOff)
+ if err != nil {
+ return msg, &nestedError{"content", err}
+ }
+ if err := r.Header.fixLen(msg, lenOff, preLen); err != nil {
+ return oldMsg, err
+ }
+ return msg, nil
+}
+
+// A Parser allows incrementally parsing a DNS message.
+//
+// When parsing is started, the Header is parsed. Next, each Question can be
+// either parsed or skipped. Alternatively, all Questions can be skipped at
+// once. When all Questions have been parsed, attempting to parse Questions
+// will return the [ErrSectionDone] error.
+// After all Questions have been either parsed or skipped, all
+// Answers, Authorities and Additionals can be either parsed or skipped in the
+// same way, and each type of Resource must be fully parsed or skipped before
+// proceeding to the next type of Resource.
+//
+// Parser is safe to copy to preserve the parsing state.
+//
+// Note that there is no requirement to fully skip or parse the message.
+type Parser struct {
+ msg []byte
+ header header
+
+ section section
+ off int
+ index int
+ resHeaderValid bool
+ resHeader ResourceHeader
+}
+
+// Start parses the header and enables the parsing of Questions.
+func (p *Parser) Start(msg []byte) (Header, error) {
+ if p.msg != nil {
+ *p = Parser{}
+ }
+ p.msg = msg
+ var err error
+ if p.off, err = p.header.unpack(msg, 0); err != nil {
+ return Header{}, &nestedError{"unpacking header", err}
+ }
+ p.section = sectionQuestions
+ return p.header.header(), nil
+}
+
+func (p *Parser) checkAdvance(sec section) error {
+ if p.section < sec {
+ return ErrNotStarted
+ }
+ if p.section > sec {
+ return ErrSectionDone
+ }
+ p.resHeaderValid = false
+ if p.index == int(p.header.count(sec)) {
+ p.index = 0
+ p.section++
+ return ErrSectionDone
+ }
+ return nil
+}
+
+func (p *Parser) resource(sec section) (Resource, error) {
+ var r Resource
+ var err error
+ r.Header, err = p.resourceHeader(sec)
+ if err != nil {
+ return r, err
+ }
+ p.resHeaderValid = false
+ r.Body, p.off, err = unpackResourceBody(p.msg, p.off, r.Header)
+ if err != nil {
+ return Resource{}, &nestedError{"unpacking " + sectionNames[sec], err}
+ }
+ p.index++
+ return r, nil
+}
+
+func (p *Parser) resourceHeader(sec section) (ResourceHeader, error) {
+ if p.resHeaderValid {
+ return p.resHeader, nil
+ }
+ if err := p.checkAdvance(sec); err != nil {
+ return ResourceHeader{}, err
+ }
+ var hdr ResourceHeader
+ off, err := hdr.unpack(p.msg, p.off)
+ if err != nil {
+ return ResourceHeader{}, err
+ }
+ p.resHeaderValid = true
+ p.resHeader = hdr
+ p.off = off
+ return hdr, nil
+}
+
+func (p *Parser) skipResource(sec section) error {
+ if p.resHeaderValid {
+ newOff := p.off + int(p.resHeader.Length)
+ if newOff > len(p.msg) {
+ return errResourceLen
+ }
+ p.off = newOff
+ p.resHeaderValid = false
+ p.index++
+ return nil
+ }
+ if err := p.checkAdvance(sec); err != nil {
+ return err
+ }
+ var err error
+ p.off, err = skipResource(p.msg, p.off)
+ if err != nil {
+ return &nestedError{"skipping: " + sectionNames[sec], err}
+ }
+ p.index++
+ return nil
+}
+
+// Question parses a single Question.
+func (p *Parser) Question() (Question, error) {
+ if err := p.checkAdvance(sectionQuestions); err != nil {
+ return Question{}, err
+ }
+ var name Name
+ off, err := name.unpack(p.msg, p.off)
+ if err != nil {
+ return Question{}, &nestedError{"unpacking Question.Name", err}
+ }
+ typ, off, err := unpackType(p.msg, off)
+ if err != nil {
+ return Question{}, &nestedError{"unpacking Question.Type", err}
+ }
+ class, off, err := unpackClass(p.msg, off)
+ if err != nil {
+ return Question{}, &nestedError{"unpacking Question.Class", err}
+ }
+ p.off = off
+ p.index++
+ return Question{name, typ, class}, nil
+}
+
+// AllQuestions parses all Questions.
+func (p *Parser) AllQuestions() ([]Question, error) {
+ // Multiple questions are valid according to the spec,
+ // but servers don't actually support them. There will
+ // be at most one question here.
+ //
+ // Do not pre-allocate based on info in p.header, since
+ // the data is untrusted.
+ qs := []Question{}
+ for {
+ q, err := p.Question()
+ if err == ErrSectionDone {
+ return qs, nil
+ }
+ if err != nil {
+ return nil, err
+ }
+ qs = append(qs, q)
+ }
+}
+
+// SkipQuestion skips a single Question.
+func (p *Parser) SkipQuestion() error {
+ if err := p.checkAdvance(sectionQuestions); err != nil {
+ return err
+ }
+ off, err := skipName(p.msg, p.off)
+ if err != nil {
+ return &nestedError{"skipping Question Name", err}
+ }
+ if off, err = skipType(p.msg, off); err != nil {
+ return &nestedError{"skipping Question Type", err}
+ }
+ if off, err = skipClass(p.msg, off); err != nil {
+ return &nestedError{"skipping Question Class", err}
+ }
+ p.off = off
+ p.index++
+ return nil
+}
+
+// SkipAllQuestions skips all Questions.
+func (p *Parser) SkipAllQuestions() error {
+ for {
+ if err := p.SkipQuestion(); err == ErrSectionDone {
+ return nil
+ } else if err != nil {
+ return err
+ }
+ }
+}
+
+// AnswerHeader parses a single Answer ResourceHeader.
+func (p *Parser) AnswerHeader() (ResourceHeader, error) {
+ return p.resourceHeader(sectionAnswers)
+}
+
+// Answer parses a single Answer Resource.
+func (p *Parser) Answer() (Resource, error) {
+ return p.resource(sectionAnswers)
+}
+
+// AllAnswers parses all Answer Resources.
+func (p *Parser) AllAnswers() ([]Resource, error) {
+ // The most common query is for A/AAAA, which usually returns
+ // a handful of IPs.
+ //
+ // Pre-allocate up to a certain limit, since p.header is
+ // untrusted data.
+ n := int(p.header.answers)
+ if n > 20 {
+ n = 20
+ }
+ as := make([]Resource, 0, n)
+ for {
+ a, err := p.Answer()
+ if err == ErrSectionDone {
+ return as, nil
+ }
+ if err != nil {
+ return nil, err
+ }
+ as = append(as, a)
+ }
+}
+
+// SkipAnswer skips a single Answer Resource.
+func (p *Parser) SkipAnswer() error {
+ return p.skipResource(sectionAnswers)
+}
+
+// SkipAllAnswers skips all Answer Resources.
+func (p *Parser) SkipAllAnswers() error {
+ for {
+ if err := p.SkipAnswer(); err == ErrSectionDone {
+ return nil
+ } else if err != nil {
+ return err
+ }
+ }
+}
+
+// AuthorityHeader parses a single Authority ResourceHeader.
+func (p *Parser) AuthorityHeader() (ResourceHeader, error) {
+ return p.resourceHeader(sectionAuthorities)
+}
+
+// Authority parses a single Authority Resource.
+func (p *Parser) Authority() (Resource, error) {
+ return p.resource(sectionAuthorities)
+}
+
+// AllAuthorities parses all Authority Resources.
+func (p *Parser) AllAuthorities() ([]Resource, error) {
+ // Authorities contains SOA in case of NXDOMAIN and friends,
+ // otherwise it is empty.
+ //
+ // Pre-allocate up to a certain limit, since p.header is
+ // untrusted data.
+ n := int(p.header.authorities)
+ if n > 10 {
+ n = 10
+ }
+ as := make([]Resource, 0, n)
+ for {
+ a, err := p.Authority()
+ if err == ErrSectionDone {
+ return as, nil
+ }
+ if err != nil {
+ return nil, err
+ }
+ as = append(as, a)
+ }
+}
+
+// SkipAuthority skips a single Authority Resource.
+func (p *Parser) SkipAuthority() error {
+ return p.skipResource(sectionAuthorities)
+}
+
+// SkipAllAuthorities skips all Authority Resources.
+func (p *Parser) SkipAllAuthorities() error {
+ for {
+ if err := p.SkipAuthority(); err == ErrSectionDone {
+ return nil
+ } else if err != nil {
+ return err
+ }
+ }
+}
+
+// AdditionalHeader parses a single Additional ResourceHeader.
+func (p *Parser) AdditionalHeader() (ResourceHeader, error) {
+ return p.resourceHeader(sectionAdditionals)
+}
+
+// Additional parses a single Additional Resource.
+func (p *Parser) Additional() (Resource, error) {
+ return p.resource(sectionAdditionals)
+}
+
+// AllAdditionals parses all Additional Resources.
+func (p *Parser) AllAdditionals() ([]Resource, error) {
+ // Additionals usually contain OPT, and sometimes A/AAAA
+ // glue records.
+ //
+ // Pre-allocate up to a certain limit, since p.header is
+ // untrusted data.
+ n := int(p.header.additionals)
+ if n > 10 {
+ n = 10
+ }
+ as := make([]Resource, 0, n)
+ for {
+ a, err := p.Additional()
+ if err == ErrSectionDone {
+ return as, nil
+ }
+ if err != nil {
+ return nil, err
+ }
+ as = append(as, a)
+ }
+}
+
+// SkipAdditional skips a single Additional Resource.
+func (p *Parser) SkipAdditional() error {
+ return p.skipResource(sectionAdditionals)
+}
+
+// SkipAllAdditionals skips all Additional Resources.
+func (p *Parser) SkipAllAdditionals() error {
+ for {
+ if err := p.SkipAdditional(); err == ErrSectionDone {
+ return nil
+ } else if err != nil {
+ return err
+ }
+ }
+}
+
+// CNAMEResource parses a single CNAMEResource.
+//
+// One of the XXXHeader methods must have been called before calling this
+// method.
+func (p *Parser) CNAMEResource() (CNAMEResource, error) {
+ if !p.resHeaderValid || p.resHeader.Type != TypeCNAME {
+ return CNAMEResource{}, ErrNotStarted
+ }
+ r, err := unpackCNAMEResource(p.msg, p.off)
+ if err != nil {
+ return CNAMEResource{}, err
+ }
+ p.off += int(p.resHeader.Length)
+ p.resHeaderValid = false
+ p.index++
+ return r, nil
+}
+
+// MXResource parses a single MXResource.
+//
+// One of the XXXHeader methods must have been called before calling this
+// method.
+func (p *Parser) MXResource() (MXResource, error) {
+ if !p.resHeaderValid || p.resHeader.Type != TypeMX {
+ return MXResource{}, ErrNotStarted
+ }
+ r, err := unpackMXResource(p.msg, p.off)
+ if err != nil {
+ return MXResource{}, err
+ }
+ p.off += int(p.resHeader.Length)
+ p.resHeaderValid = false
+ p.index++
+ return r, nil
+}
+
+// NSResource parses a single NSResource.
+//
+// One of the XXXHeader methods must have been called before calling this
+// method.
+func (p *Parser) NSResource() (NSResource, error) {
+ if !p.resHeaderValid || p.resHeader.Type != TypeNS {
+ return NSResource{}, ErrNotStarted
+ }
+ r, err := unpackNSResource(p.msg, p.off)
+ if err != nil {
+ return NSResource{}, err
+ }
+ p.off += int(p.resHeader.Length)
+ p.resHeaderValid = false
+ p.index++
+ return r, nil
+}
+
+// PTRResource parses a single PTRResource.
+//
+// One of the XXXHeader methods must have been called before calling this
+// method.
+func (p *Parser) PTRResource() (PTRResource, error) {
+ if !p.resHeaderValid || p.resHeader.Type != TypePTR {
+ return PTRResource{}, ErrNotStarted
+ }
+ r, err := unpackPTRResource(p.msg, p.off)
+ if err != nil {
+ return PTRResource{}, err
+ }
+ p.off += int(p.resHeader.Length)
+ p.resHeaderValid = false
+ p.index++
+ return r, nil
+}
+
+// SOAResource parses a single SOAResource.
+//
+// One of the XXXHeader methods must have been called before calling this
+// method.
+func (p *Parser) SOAResource() (SOAResource, error) {
+ if !p.resHeaderValid || p.resHeader.Type != TypeSOA {
+ return SOAResource{}, ErrNotStarted
+ }
+ r, err := unpackSOAResource(p.msg, p.off)
+ if err != nil {
+ return SOAResource{}, err
+ }
+ p.off += int(p.resHeader.Length)
+ p.resHeaderValid = false
+ p.index++
+ return r, nil
+}
+
+// TXTResource parses a single TXTResource.
+//
+// One of the XXXHeader methods must have been called before calling this
+// method.
+func (p *Parser) TXTResource() (TXTResource, error) {
+ if !p.resHeaderValid || p.resHeader.Type != TypeTXT {
+ return TXTResource{}, ErrNotStarted
+ }
+ r, err := unpackTXTResource(p.msg, p.off, p.resHeader.Length)
+ if err != nil {
+ return TXTResource{}, err
+ }
+ p.off += int(p.resHeader.Length)
+ p.resHeaderValid = false
+ p.index++
+ return r, nil
+}
+
+// SRVResource parses a single SRVResource.
+//
+// One of the XXXHeader methods must have been called before calling this
+// method.
+func (p *Parser) SRVResource() (SRVResource, error) {
+ if !p.resHeaderValid || p.resHeader.Type != TypeSRV {
+ return SRVResource{}, ErrNotStarted
+ }
+ r, err := unpackSRVResource(p.msg, p.off)
+ if err != nil {
+ return SRVResource{}, err
+ }
+ p.off += int(p.resHeader.Length)
+ p.resHeaderValid = false
+ p.index++
+ return r, nil
+}
+
+// AResource parses a single AResource.
+//
+// One of the XXXHeader methods must have been called before calling this
+// method.
+func (p *Parser) AResource() (AResource, error) {
+ if !p.resHeaderValid || p.resHeader.Type != TypeA {
+ return AResource{}, ErrNotStarted
+ }
+ r, err := unpackAResource(p.msg, p.off)
+ if err != nil {
+ return AResource{}, err
+ }
+ p.off += int(p.resHeader.Length)
+ p.resHeaderValid = false
+ p.index++
+ return r, nil
+}
+
+// AAAAResource parses a single AAAAResource.
+//
+// One of the XXXHeader methods must have been called before calling this
+// method.
+func (p *Parser) AAAAResource() (AAAAResource, error) {
+ if !p.resHeaderValid || p.resHeader.Type != TypeAAAA {
+ return AAAAResource{}, ErrNotStarted
+ }
+ r, err := unpackAAAAResource(p.msg, p.off)
+ if err != nil {
+ return AAAAResource{}, err
+ }
+ p.off += int(p.resHeader.Length)
+ p.resHeaderValid = false
+ p.index++
+ return r, nil
+}
+
+// OPTResource parses a single OPTResource.
+//
+// One of the XXXHeader methods must have been called before calling this
+// method.
+func (p *Parser) OPTResource() (OPTResource, error) {
+ if !p.resHeaderValid || p.resHeader.Type != TypeOPT {
+ return OPTResource{}, ErrNotStarted
+ }
+ r, err := unpackOPTResource(p.msg, p.off, p.resHeader.Length)
+ if err != nil {
+ return OPTResource{}, err
+ }
+ p.off += int(p.resHeader.Length)
+ p.resHeaderValid = false
+ p.index++
+ return r, nil
+}
+
+// UnknownResource parses a single UnknownResource.
+//
+// One of the XXXHeader methods must have been called before calling this
+// method.
+func (p *Parser) UnknownResource() (UnknownResource, error) {
+ if !p.resHeaderValid {
+ return UnknownResource{}, ErrNotStarted
+ }
+ r, err := unpackUnknownResource(p.resHeader.Type, p.msg, p.off, p.resHeader.Length)
+ if err != nil {
+ return UnknownResource{}, err
+ }
+ p.off += int(p.resHeader.Length)
+ p.resHeaderValid = false
+ p.index++
+ return r, nil
+}
+
+// Unpack parses a full Message.
+func (m *Message) Unpack(msg []byte) error {
+ var p Parser
+ var err error
+ if m.Header, err = p.Start(msg); err != nil {
+ return err
+ }
+ if m.Questions, err = p.AllQuestions(); err != nil {
+ return err
+ }
+ if m.Answers, err = p.AllAnswers(); err != nil {
+ return err
+ }
+ if m.Authorities, err = p.AllAuthorities(); err != nil {
+ return err
+ }
+ if m.Additionals, err = p.AllAdditionals(); err != nil {
+ return err
+ }
+ return nil
+}
+
+// Pack packs a full Message.
+func (m *Message) Pack() ([]byte, error) {
+ return m.AppendPack(make([]byte, 0, packStartingCap))
+}
+
+// AppendPack is like Pack but appends the full Message to b and returns the
+// extended buffer.
+func (m *Message) AppendPack(b []byte) ([]byte, error) {
+ // Validate the lengths. It is very unlikely that anyone will try to
+ // pack more than 65535 of any particular type, but it is possible and
+ // we should fail gracefully.
+ if len(m.Questions) > int(^uint16(0)) {
+ return nil, errTooManyQuestions
+ }
+ if len(m.Answers) > int(^uint16(0)) {
+ return nil, errTooManyAnswers
+ }
+ if len(m.Authorities) > int(^uint16(0)) {
+ return nil, errTooManyAuthorities
+ }
+ if len(m.Additionals) > int(^uint16(0)) {
+ return nil, errTooManyAdditionals
+ }
+
+ var h header
+ h.id, h.bits = m.Header.pack()
+
+ h.questions = uint16(len(m.Questions))
+ h.answers = uint16(len(m.Answers))
+ h.authorities = uint16(len(m.Authorities))
+ h.additionals = uint16(len(m.Additionals))
+
+ compressionOff := len(b)
+ msg := h.pack(b)
+
+ // RFC 1035 allows (but does not require) compression for packing. RFC
+ // 1035 requires unpacking implementations to support compression, so
+ // unconditionally enabling it is fine.
+ //
+ // DNS lookups are typically done over UDP, and RFC 1035 states that UDP
+ // DNS messages can be a maximum of 512 bytes long. Without compression,
+ // many DNS response messages are over this limit, so enabling
+ // compression will help ensure compliance.
+ compression := map[string]int{}
+
+ for i := range m.Questions {
+ var err error
+ if msg, err = m.Questions[i].pack(msg, compression, compressionOff); err != nil {
+ return nil, &nestedError{"packing Question", err}
+ }
+ }
+ for i := range m.Answers {
+ var err error
+ if msg, err = m.Answers[i].pack(msg, compression, compressionOff); err != nil {
+ return nil, &nestedError{"packing Answer", err}
+ }
+ }
+ for i := range m.Authorities {
+ var err error
+ if msg, err = m.Authorities[i].pack(msg, compression, compressionOff); err != nil {
+ return nil, &nestedError{"packing Authority", err}
+ }
+ }
+ for i := range m.Additionals {
+ var err error
+ if msg, err = m.Additionals[i].pack(msg, compression, compressionOff); err != nil {
+ return nil, &nestedError{"packing Additional", err}
+ }
+ }
+
+ return msg, nil
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (m *Message) GoString() string {
+ s := "dnsmessage.Message{Header: " + m.Header.GoString() + ", " +
+ "Questions: []dnsmessage.Question{"
+ if len(m.Questions) > 0 {
+ s += m.Questions[0].GoString()
+ for _, q := range m.Questions[1:] {
+ s += ", " + q.GoString()
+ }
+ }
+ s += "}, Answers: []dnsmessage.Resource{"
+ if len(m.Answers) > 0 {
+ s += m.Answers[0].GoString()
+ for _, a := range m.Answers[1:] {
+ s += ", " + a.GoString()
+ }
+ }
+ s += "}, Authorities: []dnsmessage.Resource{"
+ if len(m.Authorities) > 0 {
+ s += m.Authorities[0].GoString()
+ for _, a := range m.Authorities[1:] {
+ s += ", " + a.GoString()
+ }
+ }
+ s += "}, Additionals: []dnsmessage.Resource{"
+ if len(m.Additionals) > 0 {
+ s += m.Additionals[0].GoString()
+ for _, a := range m.Additionals[1:] {
+ s += ", " + a.GoString()
+ }
+ }
+ return s + "}}"
+}
+
+// A Builder allows incrementally packing a DNS message.
+//
+// Example usage:
+//
+// buf := make([]byte, 2, 514)
+// b := NewBuilder(buf, Header{...})
+// b.EnableCompression()
+// // Optionally start a section and add things to that section.
+// // Repeat adding sections as necessary.
+// buf, err := b.Finish()
+// // If err is nil, buf[2:] will contain the built bytes.
+type Builder struct {
+ // msg is the storage for the message being built.
+ msg []byte
+
+ // section keeps track of the current section being built.
+ section section
+
+ // header keeps track of what should go in the header when Finish is
+ // called.
+ header header
+
+ // start is the starting index of the bytes allocated in msg for header.
+ start int
+
+ // compression is a mapping from name suffixes to their starting index
+ // in msg.
+ compression map[string]int
+}
+
+// NewBuilder creates a new builder with compression disabled.
+//
+// Note: Most users will want to immediately enable compression with the
+// EnableCompression method. See that method's comment for why you may or may
+// not want to enable compression.
+//
+// The DNS message is appended to the provided initial buffer buf (which may be
+// nil) as it is built. The final message is returned by the (*Builder).Finish
+// method, which includes buf[:len(buf)] and may return the same underlying
+// array if there was sufficient capacity in the slice.
+func NewBuilder(buf []byte, h Header) Builder {
+ if buf == nil {
+ buf = make([]byte, 0, packStartingCap)
+ }
+ b := Builder{msg: buf, start: len(buf)}
+ b.header.id, b.header.bits = h.pack()
+ var hb [headerLen]byte
+ b.msg = append(b.msg, hb[:]...)
+ b.section = sectionHeader
+ return b
+}
+
+// EnableCompression enables compression in the Builder.
+//
+// Leaving compression disabled avoids compression related allocations, but can
+// result in larger message sizes. Be careful with this mode as it can cause
+// messages to exceed the UDP size limit.
+//
+// According to RFC 1035, section 4.1.4, the use of compression is optional, but
+// all implementations must accept both compressed and uncompressed DNS
+// messages.
+//
+// Compression should be enabled before any sections are added for best results.
+func (b *Builder) EnableCompression() {
+ b.compression = map[string]int{}
+}
+
+func (b *Builder) startCheck(s section) error {
+ if b.section <= sectionNotStarted {
+ return ErrNotStarted
+ }
+ if b.section > s {
+ return ErrSectionDone
+ }
+ return nil
+}
+
+// StartQuestions prepares the builder for packing Questions.
+func (b *Builder) StartQuestions() error {
+ if err := b.startCheck(sectionQuestions); err != nil {
+ return err
+ }
+ b.section = sectionQuestions
+ return nil
+}
+
+// StartAnswers prepares the builder for packing Answers.
+func (b *Builder) StartAnswers() error {
+ if err := b.startCheck(sectionAnswers); err != nil {
+ return err
+ }
+ b.section = sectionAnswers
+ return nil
+}
+
+// StartAuthorities prepares the builder for packing Authorities.
+func (b *Builder) StartAuthorities() error {
+ if err := b.startCheck(sectionAuthorities); err != nil {
+ return err
+ }
+ b.section = sectionAuthorities
+ return nil
+}
+
+// StartAdditionals prepares the builder for packing Additionals.
+func (b *Builder) StartAdditionals() error {
+ if err := b.startCheck(sectionAdditionals); err != nil {
+ return err
+ }
+ b.section = sectionAdditionals
+ return nil
+}
+
+func (b *Builder) incrementSectionCount() error {
+ var count *uint16
+ var err error
+ switch b.section {
+ case sectionQuestions:
+ count = &b.header.questions
+ err = errTooManyQuestions
+ case sectionAnswers:
+ count = &b.header.answers
+ err = errTooManyAnswers
+ case sectionAuthorities:
+ count = &b.header.authorities
+ err = errTooManyAuthorities
+ case sectionAdditionals:
+ count = &b.header.additionals
+ err = errTooManyAdditionals
+ }
+ if *count == ^uint16(0) {
+ return err
+ }
+ *count++
+ return nil
+}
+
+// Question adds a single Question.
+func (b *Builder) Question(q Question) error {
+ if b.section < sectionQuestions {
+ return ErrNotStarted
+ }
+ if b.section > sectionQuestions {
+ return ErrSectionDone
+ }
+ msg, err := q.pack(b.msg, b.compression, b.start)
+ if err != nil {
+ return err
+ }
+ if err := b.incrementSectionCount(); err != nil {
+ return err
+ }
+ b.msg = msg
+ return nil
+}
+
+func (b *Builder) checkResourceSection() error {
+ if b.section < sectionAnswers {
+ return ErrNotStarted
+ }
+ if b.section > sectionAdditionals {
+ return ErrSectionDone
+ }
+ return nil
+}
+
+// CNAMEResource adds a single CNAMEResource.
+func (b *Builder) CNAMEResource(h ResourceHeader, r CNAMEResource) error {
+ if err := b.checkResourceSection(); err != nil {
+ return err
+ }
+ h.Type = r.realType()
+ msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
+ if err != nil {
+ return &nestedError{"ResourceHeader", err}
+ }
+ preLen := len(msg)
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
+ return &nestedError{"CNAMEResource body", err}
+ }
+ if err := h.fixLen(msg, lenOff, preLen); err != nil {
+ return err
+ }
+ if err := b.incrementSectionCount(); err != nil {
+ return err
+ }
+ b.msg = msg
+ return nil
+}
+
+// MXResource adds a single MXResource.
+func (b *Builder) MXResource(h ResourceHeader, r MXResource) error {
+ if err := b.checkResourceSection(); err != nil {
+ return err
+ }
+ h.Type = r.realType()
+ msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
+ if err != nil {
+ return &nestedError{"ResourceHeader", err}
+ }
+ preLen := len(msg)
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
+ return &nestedError{"MXResource body", err}
+ }
+ if err := h.fixLen(msg, lenOff, preLen); err != nil {
+ return err
+ }
+ if err := b.incrementSectionCount(); err != nil {
+ return err
+ }
+ b.msg = msg
+ return nil
+}
+
+// NSResource adds a single NSResource.
+func (b *Builder) NSResource(h ResourceHeader, r NSResource) error {
+ if err := b.checkResourceSection(); err != nil {
+ return err
+ }
+ h.Type = r.realType()
+ msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
+ if err != nil {
+ return &nestedError{"ResourceHeader", err}
+ }
+ preLen := len(msg)
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
+ return &nestedError{"NSResource body", err}
+ }
+ if err := h.fixLen(msg, lenOff, preLen); err != nil {
+ return err
+ }
+ if err := b.incrementSectionCount(); err != nil {
+ return err
+ }
+ b.msg = msg
+ return nil
+}
+
+// PTRResource adds a single PTRResource.
+func (b *Builder) PTRResource(h ResourceHeader, r PTRResource) error {
+ if err := b.checkResourceSection(); err != nil {
+ return err
+ }
+ h.Type = r.realType()
+ msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
+ if err != nil {
+ return &nestedError{"ResourceHeader", err}
+ }
+ preLen := len(msg)
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
+ return &nestedError{"PTRResource body", err}
+ }
+ if err := h.fixLen(msg, lenOff, preLen); err != nil {
+ return err
+ }
+ if err := b.incrementSectionCount(); err != nil {
+ return err
+ }
+ b.msg = msg
+ return nil
+}
+
+// SOAResource adds a single SOAResource.
+func (b *Builder) SOAResource(h ResourceHeader, r SOAResource) error {
+ if err := b.checkResourceSection(); err != nil {
+ return err
+ }
+ h.Type = r.realType()
+ msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
+ if err != nil {
+ return &nestedError{"ResourceHeader", err}
+ }
+ preLen := len(msg)
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
+ return &nestedError{"SOAResource body", err}
+ }
+ if err := h.fixLen(msg, lenOff, preLen); err != nil {
+ return err
+ }
+ if err := b.incrementSectionCount(); err != nil {
+ return err
+ }
+ b.msg = msg
+ return nil
+}
+
+// TXTResource adds a single TXTResource.
+func (b *Builder) TXTResource(h ResourceHeader, r TXTResource) error {
+ if err := b.checkResourceSection(); err != nil {
+ return err
+ }
+ h.Type = r.realType()
+ msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
+ if err != nil {
+ return &nestedError{"ResourceHeader", err}
+ }
+ preLen := len(msg)
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
+ return &nestedError{"TXTResource body", err}
+ }
+ if err := h.fixLen(msg, lenOff, preLen); err != nil {
+ return err
+ }
+ if err := b.incrementSectionCount(); err != nil {
+ return err
+ }
+ b.msg = msg
+ return nil
+}
+
+// SRVResource adds a single SRVResource.
+func (b *Builder) SRVResource(h ResourceHeader, r SRVResource) error {
+ if err := b.checkResourceSection(); err != nil {
+ return err
+ }
+ h.Type = r.realType()
+ msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
+ if err != nil {
+ return &nestedError{"ResourceHeader", err}
+ }
+ preLen := len(msg)
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
+ return &nestedError{"SRVResource body", err}
+ }
+ if err := h.fixLen(msg, lenOff, preLen); err != nil {
+ return err
+ }
+ if err := b.incrementSectionCount(); err != nil {
+ return err
+ }
+ b.msg = msg
+ return nil
+}
+
+// AResource adds a single AResource.
+func (b *Builder) AResource(h ResourceHeader, r AResource) error {
+ if err := b.checkResourceSection(); err != nil {
+ return err
+ }
+ h.Type = r.realType()
+ msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
+ if err != nil {
+ return &nestedError{"ResourceHeader", err}
+ }
+ preLen := len(msg)
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
+ return &nestedError{"AResource body", err}
+ }
+ if err := h.fixLen(msg, lenOff, preLen); err != nil {
+ return err
+ }
+ if err := b.incrementSectionCount(); err != nil {
+ return err
+ }
+ b.msg = msg
+ return nil
+}
+
+// AAAAResource adds a single AAAAResource.
+func (b *Builder) AAAAResource(h ResourceHeader, r AAAAResource) error {
+ if err := b.checkResourceSection(); err != nil {
+ return err
+ }
+ h.Type = r.realType()
+ msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
+ if err != nil {
+ return &nestedError{"ResourceHeader", err}
+ }
+ preLen := len(msg)
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
+ return &nestedError{"AAAAResource body", err}
+ }
+ if err := h.fixLen(msg, lenOff, preLen); err != nil {
+ return err
+ }
+ if err := b.incrementSectionCount(); err != nil {
+ return err
+ }
+ b.msg = msg
+ return nil
+}
+
+// OPTResource adds a single OPTResource.
+func (b *Builder) OPTResource(h ResourceHeader, r OPTResource) error {
+ if err := b.checkResourceSection(); err != nil {
+ return err
+ }
+ h.Type = r.realType()
+ msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
+ if err != nil {
+ return &nestedError{"ResourceHeader", err}
+ }
+ preLen := len(msg)
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
+ return &nestedError{"OPTResource body", err}
+ }
+ if err := h.fixLen(msg, lenOff, preLen); err != nil {
+ return err
+ }
+ if err := b.incrementSectionCount(); err != nil {
+ return err
+ }
+ b.msg = msg
+ return nil
+}
+
+// UnknownResource adds a single UnknownResource.
+func (b *Builder) UnknownResource(h ResourceHeader, r UnknownResource) error {
+ if err := b.checkResourceSection(); err != nil {
+ return err
+ }
+ h.Type = r.realType()
+ msg, lenOff, err := h.pack(b.msg, b.compression, b.start)
+ if err != nil {
+ return &nestedError{"ResourceHeader", err}
+ }
+ preLen := len(msg)
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
+ return &nestedError{"UnknownResource body", err}
+ }
+ if err := h.fixLen(msg, lenOff, preLen); err != nil {
+ return err
+ }
+ if err := b.incrementSectionCount(); err != nil {
+ return err
+ }
+ b.msg = msg
+ return nil
+}
+
+// Finish ends message building and generates a binary message.
+func (b *Builder) Finish() ([]byte, error) {
+ if b.section < sectionHeader {
+ return nil, ErrNotStarted
+ }
+ b.section = sectionDone
+ // Space for the header was allocated in NewBuilder.
+ b.header.pack(b.msg[b.start:b.start])
+ return b.msg, nil
+}
+
+// A ResourceHeader is the header of a DNS resource record. There are
+// many types of DNS resource records, but they all share the same header.
+type ResourceHeader struct {
+ // Name is the domain name for which this resource record pertains.
+ Name Name
+
+ // Type is the type of DNS resource record.
+ //
+ // This field will be set automatically during packing.
+ Type Type
+
+ // Class is the class of network to which this DNS resource record
+ // pertains.
+ Class Class
+
+ // TTL is the length of time (measured in seconds) which this resource
+ // record is valid for (time to live). All Resources in a set should
+ // have the same TTL (RFC 2181 Section 5.2).
+ TTL uint32
+
+ // Length is the length of data in the resource record after the header.
+ //
+ // This field will be set automatically during packing.
+ Length uint16
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (h *ResourceHeader) GoString() string {
+ return "dnsmessage.ResourceHeader{" +
+ "Name: " + h.Name.GoString() + ", " +
+ "Type: " + h.Type.GoString() + ", " +
+ "Class: " + h.Class.GoString() + ", " +
+ "TTL: " + printUint32(h.TTL) + ", " +
+ "Length: " + printUint16(h.Length) + "}"
+}
+
+// pack appends the wire format of the ResourceHeader to oldMsg.
+//
+// lenOff is the offset in msg where the Length field was packed.
+func (h *ResourceHeader) pack(oldMsg []byte, compression map[string]int, compressionOff int) (msg []byte, lenOff int, err error) {
+ msg = oldMsg
+ if msg, err = h.Name.pack(msg, compression, compressionOff); err != nil {
+ return oldMsg, 0, &nestedError{"Name", err}
+ }
+ msg = packType(msg, h.Type)
+ msg = packClass(msg, h.Class)
+ msg = packUint32(msg, h.TTL)
+ lenOff = len(msg)
+ msg = packUint16(msg, h.Length)
+ return msg, lenOff, nil
+}
+
+func (h *ResourceHeader) unpack(msg []byte, off int) (int, error) {
+ newOff := off
+ var err error
+ if newOff, err = h.Name.unpack(msg, newOff); err != nil {
+ return off, &nestedError{"Name", err}
+ }
+ if h.Type, newOff, err = unpackType(msg, newOff); err != nil {
+ return off, &nestedError{"Type", err}
+ }
+ if h.Class, newOff, err = unpackClass(msg, newOff); err != nil {
+ return off, &nestedError{"Class", err}
+ }
+ if h.TTL, newOff, err = unpackUint32(msg, newOff); err != nil {
+ return off, &nestedError{"TTL", err}
+ }
+ if h.Length, newOff, err = unpackUint16(msg, newOff); err != nil {
+ return off, &nestedError{"Length", err}
+ }
+ return newOff, nil
+}
+
+// fixLen updates a packed ResourceHeader to include the length of the
+// ResourceBody.
+//
+// lenOff is the offset of the ResourceHeader.Length field in msg.
+//
+// preLen is the length that msg was before the ResourceBody was packed.
+func (h *ResourceHeader) fixLen(msg []byte, lenOff int, preLen int) error {
+ conLen := len(msg) - preLen
+ if conLen > int(^uint16(0)) {
+ return errResTooLong
+ }
+
+ // Fill in the length now that we know how long the content is.
+ packUint16(msg[lenOff:lenOff], uint16(conLen))
+ h.Length = uint16(conLen)
+
+ return nil
+}
+
+// EDNS(0) wire constants.
+const (
+ edns0Version = 0
+
+ edns0DNSSECOK = 0x00008000
+ ednsVersionMask = 0x00ff0000
+ edns0DNSSECOKMask = 0x00ff8000
+)
+
+// SetEDNS0 configures h for EDNS(0).
+//
+// The provided extRCode must be an extended RCode.
+func (h *ResourceHeader) SetEDNS0(udpPayloadLen int, extRCode RCode, dnssecOK bool) error {
+ h.Name = Name{Data: [255]byte{'.'}, Length: 1} // RFC 6891 section 6.1.2
+ h.Type = TypeOPT
+ h.Class = Class(udpPayloadLen)
+ h.TTL = uint32(extRCode) >> 4 << 24
+ if dnssecOK {
+ h.TTL |= edns0DNSSECOK
+ }
+ return nil
+}
+
+// DNSSECAllowed reports whether the DNSSEC OK bit is set.
+func (h *ResourceHeader) DNSSECAllowed() bool {
+ return h.TTL&edns0DNSSECOKMask == edns0DNSSECOK // RFC 6891 section 6.1.3
+}
+
+// ExtendedRCode returns an extended RCode.
+//
+// The provided rcode must be the RCode in DNS message header.
+func (h *ResourceHeader) ExtendedRCode(rcode RCode) RCode {
+ if h.TTL&ednsVersionMask == edns0Version { // RFC 6891 section 6.1.3
+ return RCode(h.TTL>>24<<4) | rcode
+ }
+ return rcode
+}
+
+func skipResource(msg []byte, off int) (int, error) {
+ newOff, err := skipName(msg, off)
+ if err != nil {
+ return off, &nestedError{"Name", err}
+ }
+ if newOff, err = skipType(msg, newOff); err != nil {
+ return off, &nestedError{"Type", err}
+ }
+ if newOff, err = skipClass(msg, newOff); err != nil {
+ return off, &nestedError{"Class", err}
+ }
+ if newOff, err = skipUint32(msg, newOff); err != nil {
+ return off, &nestedError{"TTL", err}
+ }
+ length, newOff, err := unpackUint16(msg, newOff)
+ if err != nil {
+ return off, &nestedError{"Length", err}
+ }
+ if newOff += int(length); newOff > len(msg) {
+ return off, errResourceLen
+ }
+ return newOff, nil
+}
+
+// packUint16 appends the wire format of field to msg.
+func packUint16(msg []byte, field uint16) []byte {
+ return append(msg, byte(field>>8), byte(field))
+}
+
+func unpackUint16(msg []byte, off int) (uint16, int, error) {
+ if off+uint16Len > len(msg) {
+ return 0, off, errBaseLen
+ }
+ return uint16(msg[off])<<8 | uint16(msg[off+1]), off + uint16Len, nil
+}
+
+func skipUint16(msg []byte, off int) (int, error) {
+ if off+uint16Len > len(msg) {
+ return off, errBaseLen
+ }
+ return off + uint16Len, nil
+}
+
+// packType appends the wire format of field to msg.
+func packType(msg []byte, field Type) []byte {
+ return packUint16(msg, uint16(field))
+}
+
+func unpackType(msg []byte, off int) (Type, int, error) {
+ t, o, err := unpackUint16(msg, off)
+ return Type(t), o, err
+}
+
+func skipType(msg []byte, off int) (int, error) {
+ return skipUint16(msg, off)
+}
+
+// packClass appends the wire format of field to msg.
+func packClass(msg []byte, field Class) []byte {
+ return packUint16(msg, uint16(field))
+}
+
+func unpackClass(msg []byte, off int) (Class, int, error) {
+ c, o, err := unpackUint16(msg, off)
+ return Class(c), o, err
+}
+
+func skipClass(msg []byte, off int) (int, error) {
+ return skipUint16(msg, off)
+}
+
+// packUint32 appends the wire format of field to msg.
+func packUint32(msg []byte, field uint32) []byte {
+ return append(
+ msg,
+ byte(field>>24),
+ byte(field>>16),
+ byte(field>>8),
+ byte(field),
+ )
+}
+
+func unpackUint32(msg []byte, off int) (uint32, int, error) {
+ if off+uint32Len > len(msg) {
+ return 0, off, errBaseLen
+ }
+ v := uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3])
+ return v, off + uint32Len, nil
+}
+
+func skipUint32(msg []byte, off int) (int, error) {
+ if off+uint32Len > len(msg) {
+ return off, errBaseLen
+ }
+ return off + uint32Len, nil
+}
+
+// packText appends the wire format of field to msg.
+func packText(msg []byte, field string) ([]byte, error) {
+ l := len(field)
+ if l > 255 {
+ return nil, errStringTooLong
+ }
+ msg = append(msg, byte(l))
+ msg = append(msg, field...)
+
+ return msg, nil
+}
+
+func unpackText(msg []byte, off int) (string, int, error) {
+ if off >= len(msg) {
+ return "", off, errBaseLen
+ }
+ beginOff := off + 1
+ endOff := beginOff + int(msg[off])
+ if endOff > len(msg) {
+ return "", off, errCalcLen
+ }
+ return string(msg[beginOff:endOff]), endOff, nil
+}
+
+// packBytes appends the wire format of field to msg.
+func packBytes(msg []byte, field []byte) []byte {
+ return append(msg, field...)
+}
+
+func unpackBytes(msg []byte, off int, field []byte) (int, error) {
+ newOff := off + len(field)
+ if newOff > len(msg) {
+ return off, errBaseLen
+ }
+ copy(field, msg[off:newOff])
+ return newOff, nil
+}
+
+const nonEncodedNameMax = 254
+
+// A Name is a non-encoded domain name. It is used instead of strings to avoid
+// allocations.
+type Name struct {
+ Data [255]byte
+ Length uint8
+}
+
+// NewName creates a new Name from a string.
+func NewName(name string) (Name, error) {
+ n := Name{Length: uint8(len(name))}
+ if len(name) > len(n.Data) {
+ return Name{}, errCalcLen
+ }
+ copy(n.Data[:], name)
+ return n, nil
+}
+
+// MustNewName creates a new Name from a string and panics on error.
+func MustNewName(name string) Name {
+ n, err := NewName(name)
+ if err != nil {
+ panic("creating name: " + err.Error())
+ }
+ return n
+}
+
+// String implements fmt.Stringer.String.
+func (n Name) String() string {
+ return string(n.Data[:n.Length])
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (n *Name) GoString() string {
+ return `dnsmessage.MustNewName("` + printString(n.Data[:n.Length]) + `")`
+}
+
+// pack appends the wire format of the Name to msg.
+//
+// Domain names are a sequence of counted strings split at the dots. They end
+// with a zero-length string. Compression can be used to reuse domain suffixes.
+//
+// The compression map will be updated with new domain suffixes. If compression
+// is nil, compression will not be used.
+func (n *Name) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ oldMsg := msg
+
+ if n.Length > nonEncodedNameMax {
+ return nil, errNameTooLong
+ }
+
+ // Add a trailing dot to canonicalize name.
+ if n.Length == 0 || n.Data[n.Length-1] != '.' {
+ return oldMsg, errNonCanonicalName
+ }
+
+ // Allow root domain.
+ if n.Data[0] == '.' && n.Length == 1 {
+ return append(msg, 0), nil
+ }
+
+ // Emit sequence of counted strings, chopping at dots.
+ for i, begin := 0, 0; i < int(n.Length); i++ {
+ // Check for the end of the segment.
+ if n.Data[i] == '.' {
+ // The two most significant bits have special meaning.
+ // It isn't allowed for segments to be long enough to
+ // need them.
+ if i-begin >= 1<<6 {
+ return oldMsg, errSegTooLong
+ }
+
+ // Segments must have a non-zero length.
+ if i-begin == 0 {
+ return oldMsg, errZeroSegLen
+ }
+
+ msg = append(msg, byte(i-begin))
+
+ for j := begin; j < i; j++ {
+ msg = append(msg, n.Data[j])
+ }
+
+ begin = i + 1
+ continue
+ }
+
+ // We can only compress domain suffixes starting with a new
+ // segment. A pointer is two bytes with the two most significant
+ // bits set to 1 to indicate that it is a pointer.
+ if (i == 0 || n.Data[i-1] == '.') && compression != nil {
+ if ptr, ok := compression[string(n.Data[i:])]; ok {
+ // Hit. Emit a pointer instead of the rest of
+ // the domain.
+ return append(msg, byte(ptr>>8|0xC0), byte(ptr)), nil
+ }
+
+ // Miss. Add the suffix to the compression table if the
+ // offset can be stored in the available 14 bytes.
+ if len(msg) <= int(^uint16(0)>>2) {
+ compression[string(n.Data[i:])] = len(msg) - compressionOff
+ }
+ }
+ }
+ return append(msg, 0), nil
+}
+
+// unpack unpacks a domain name.
+func (n *Name) unpack(msg []byte, off int) (int, error) {
+ return n.unpackCompressed(msg, off, true /* allowCompression */)
+}
+
+func (n *Name) unpackCompressed(msg []byte, off int, allowCompression bool) (int, error) {
+ // currOff is the current working offset.
+ currOff := off
+
+ // newOff is the offset where the next record will start. Pointers lead
+ // to data that belongs to other names and thus doesn't count towards to
+ // the usage of this name.
+ newOff := off
+
+ // ptr is the number of pointers followed.
+ var ptr int
+
+ // Name is a slice representation of the name data.
+ name := n.Data[:0]
+
+Loop:
+ for {
+ if currOff >= len(msg) {
+ return off, errBaseLen
+ }
+ c := int(msg[currOff])
+ currOff++
+ switch c & 0xC0 {
+ case 0x00: // String segment
+ if c == 0x00 {
+ // A zero length signals the end of the name.
+ break Loop
+ }
+ endOff := currOff + c
+ if endOff > len(msg) {
+ return off, errCalcLen
+ }
+
+ // Reject names containing dots.
+ // See issue golang/go#56246
+ for _, v := range msg[currOff:endOff] {
+ if v == '.' {
+ return off, errInvalidName
+ }
+ }
+
+ name = append(name, msg[currOff:endOff]...)
+ name = append(name, '.')
+ currOff = endOff
+ case 0xC0: // Pointer
+ if !allowCompression {
+ return off, errCompressedSRV
+ }
+ if currOff >= len(msg) {
+ return off, errInvalidPtr
+ }
+ c1 := msg[currOff]
+ currOff++
+ if ptr == 0 {
+ newOff = currOff
+ }
+ // Don't follow too many pointers, maybe there's a loop.
+ if ptr++; ptr > 10 {
+ return off, errTooManyPtr
+ }
+ currOff = (c^0xC0)<<8 | int(c1)
+ default:
+ // Prefixes 0x80 and 0x40 are reserved.
+ return off, errReserved
+ }
+ }
+ if len(name) == 0 {
+ name = append(name, '.')
+ }
+ if len(name) > nonEncodedNameMax {
+ return off, errNameTooLong
+ }
+ n.Length = uint8(len(name))
+ if ptr == 0 {
+ newOff = currOff
+ }
+ return newOff, nil
+}
+
+func skipName(msg []byte, off int) (int, error) {
+ // newOff is the offset where the next record will start. Pointers lead
+ // to data that belongs to other names and thus doesn't count towards to
+ // the usage of this name.
+ newOff := off
+
+Loop:
+ for {
+ if newOff >= len(msg) {
+ return off, errBaseLen
+ }
+ c := int(msg[newOff])
+ newOff++
+ switch c & 0xC0 {
+ case 0x00:
+ if c == 0x00 {
+ // A zero length signals the end of the name.
+ break Loop
+ }
+ // literal string
+ newOff += c
+ if newOff > len(msg) {
+ return off, errCalcLen
+ }
+ case 0xC0:
+ // Pointer to somewhere else in msg.
+
+ // Pointers are two bytes.
+ newOff++
+
+ // Don't follow the pointer as the data here has ended.
+ break Loop
+ default:
+ // Prefixes 0x80 and 0x40 are reserved.
+ return off, errReserved
+ }
+ }
+
+ return newOff, nil
+}
+
+// A Question is a DNS query.
+type Question struct {
+ Name Name
+ Type Type
+ Class Class
+}
+
+// pack appends the wire format of the Question to msg.
+func (q *Question) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ msg, err := q.Name.pack(msg, compression, compressionOff)
+ if err != nil {
+ return msg, &nestedError{"Name", err}
+ }
+ msg = packType(msg, q.Type)
+ return packClass(msg, q.Class), nil
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (q *Question) GoString() string {
+ return "dnsmessage.Question{" +
+ "Name: " + q.Name.GoString() + ", " +
+ "Type: " + q.Type.GoString() + ", " +
+ "Class: " + q.Class.GoString() + "}"
+}
+
+func unpackResourceBody(msg []byte, off int, hdr ResourceHeader) (ResourceBody, int, error) {
+ var (
+ r ResourceBody
+ err error
+ name string
+ )
+ switch hdr.Type {
+ case TypeA:
+ var rb AResource
+ rb, err = unpackAResource(msg, off)
+ r = &rb
+ name = "A"
+ case TypeNS:
+ var rb NSResource
+ rb, err = unpackNSResource(msg, off)
+ r = &rb
+ name = "NS"
+ case TypeCNAME:
+ var rb CNAMEResource
+ rb, err = unpackCNAMEResource(msg, off)
+ r = &rb
+ name = "CNAME"
+ case TypeSOA:
+ var rb SOAResource
+ rb, err = unpackSOAResource(msg, off)
+ r = &rb
+ name = "SOA"
+ case TypePTR:
+ var rb PTRResource
+ rb, err = unpackPTRResource(msg, off)
+ r = &rb
+ name = "PTR"
+ case TypeMX:
+ var rb MXResource
+ rb, err = unpackMXResource(msg, off)
+ r = &rb
+ name = "MX"
+ case TypeTXT:
+ var rb TXTResource
+ rb, err = unpackTXTResource(msg, off, hdr.Length)
+ r = &rb
+ name = "TXT"
+ case TypeAAAA:
+ var rb AAAAResource
+ rb, err = unpackAAAAResource(msg, off)
+ r = &rb
+ name = "AAAA"
+ case TypeSRV:
+ var rb SRVResource
+ rb, err = unpackSRVResource(msg, off)
+ r = &rb
+ name = "SRV"
+ case TypeOPT:
+ var rb OPTResource
+ rb, err = unpackOPTResource(msg, off, hdr.Length)
+ r = &rb
+ name = "OPT"
+ default:
+ var rb UnknownResource
+ rb, err = unpackUnknownResource(hdr.Type, msg, off, hdr.Length)
+ r = &rb
+ name = "Unknown"
+ }
+ if err != nil {
+ return nil, off, &nestedError{name + " record", err}
+ }
+ return r, off + int(hdr.Length), nil
+}
+
+// A CNAMEResource is a CNAME Resource record.
+type CNAMEResource struct {
+ CNAME Name
+}
+
+func (r *CNAMEResource) realType() Type {
+ return TypeCNAME
+}
+
+// pack appends the wire format of the CNAMEResource to msg.
+func (r *CNAMEResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ return r.CNAME.pack(msg, compression, compressionOff)
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r *CNAMEResource) GoString() string {
+ return "dnsmessage.CNAMEResource{CNAME: " + r.CNAME.GoString() + "}"
+}
+
+func unpackCNAMEResource(msg []byte, off int) (CNAMEResource, error) {
+ var cname Name
+ if _, err := cname.unpack(msg, off); err != nil {
+ return CNAMEResource{}, err
+ }
+ return CNAMEResource{cname}, nil
+}
+
+// An MXResource is an MX Resource record.
+type MXResource struct {
+ Pref uint16
+ MX Name
+}
+
+func (r *MXResource) realType() Type {
+ return TypeMX
+}
+
+// pack appends the wire format of the MXResource to msg.
+func (r *MXResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ oldMsg := msg
+ msg = packUint16(msg, r.Pref)
+ msg, err := r.MX.pack(msg, compression, compressionOff)
+ if err != nil {
+ return oldMsg, &nestedError{"MXResource.MX", err}
+ }
+ return msg, nil
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r *MXResource) GoString() string {
+ return "dnsmessage.MXResource{" +
+ "Pref: " + printUint16(r.Pref) + ", " +
+ "MX: " + r.MX.GoString() + "}"
+}
+
+func unpackMXResource(msg []byte, off int) (MXResource, error) {
+ pref, off, err := unpackUint16(msg, off)
+ if err != nil {
+ return MXResource{}, &nestedError{"Pref", err}
+ }
+ var mx Name
+ if _, err := mx.unpack(msg, off); err != nil {
+ return MXResource{}, &nestedError{"MX", err}
+ }
+ return MXResource{pref, mx}, nil
+}
+
+// An NSResource is an NS Resource record.
+type NSResource struct {
+ NS Name
+}
+
+func (r *NSResource) realType() Type {
+ return TypeNS
+}
+
+// pack appends the wire format of the NSResource to msg.
+func (r *NSResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ return r.NS.pack(msg, compression, compressionOff)
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r *NSResource) GoString() string {
+ return "dnsmessage.NSResource{NS: " + r.NS.GoString() + "}"
+}
+
+func unpackNSResource(msg []byte, off int) (NSResource, error) {
+ var ns Name
+ if _, err := ns.unpack(msg, off); err != nil {
+ return NSResource{}, err
+ }
+ return NSResource{ns}, nil
+}
+
+// A PTRResource is a PTR Resource record.
+type PTRResource struct {
+ PTR Name
+}
+
+func (r *PTRResource) realType() Type {
+ return TypePTR
+}
+
+// pack appends the wire format of the PTRResource to msg.
+func (r *PTRResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ return r.PTR.pack(msg, compression, compressionOff)
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r *PTRResource) GoString() string {
+ return "dnsmessage.PTRResource{PTR: " + r.PTR.GoString() + "}"
+}
+
+func unpackPTRResource(msg []byte, off int) (PTRResource, error) {
+ var ptr Name
+ if _, err := ptr.unpack(msg, off); err != nil {
+ return PTRResource{}, err
+ }
+ return PTRResource{ptr}, nil
+}
+
+// An SOAResource is an SOA Resource record.
+type SOAResource struct {
+ NS Name
+ MBox Name
+ Serial uint32
+ Refresh uint32
+ Retry uint32
+ Expire uint32
+
+ // MinTTL the is the default TTL of Resources records which did not
+ // contain a TTL value and the TTL of negative responses. (RFC 2308
+ // Section 4)
+ MinTTL uint32
+}
+
+func (r *SOAResource) realType() Type {
+ return TypeSOA
+}
+
+// pack appends the wire format of the SOAResource to msg.
+func (r *SOAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ oldMsg := msg
+ msg, err := r.NS.pack(msg, compression, compressionOff)
+ if err != nil {
+ return oldMsg, &nestedError{"SOAResource.NS", err}
+ }
+ msg, err = r.MBox.pack(msg, compression, compressionOff)
+ if err != nil {
+ return oldMsg, &nestedError{"SOAResource.MBox", err}
+ }
+ msg = packUint32(msg, r.Serial)
+ msg = packUint32(msg, r.Refresh)
+ msg = packUint32(msg, r.Retry)
+ msg = packUint32(msg, r.Expire)
+ return packUint32(msg, r.MinTTL), nil
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r *SOAResource) GoString() string {
+ return "dnsmessage.SOAResource{" +
+ "NS: " + r.NS.GoString() + ", " +
+ "MBox: " + r.MBox.GoString() + ", " +
+ "Serial: " + printUint32(r.Serial) + ", " +
+ "Refresh: " + printUint32(r.Refresh) + ", " +
+ "Retry: " + printUint32(r.Retry) + ", " +
+ "Expire: " + printUint32(r.Expire) + ", " +
+ "MinTTL: " + printUint32(r.MinTTL) + "}"
+}
+
+func unpackSOAResource(msg []byte, off int) (SOAResource, error) {
+ var ns Name
+ off, err := ns.unpack(msg, off)
+ if err != nil {
+ return SOAResource{}, &nestedError{"NS", err}
+ }
+ var mbox Name
+ if off, err = mbox.unpack(msg, off); err != nil {
+ return SOAResource{}, &nestedError{"MBox", err}
+ }
+ serial, off, err := unpackUint32(msg, off)
+ if err != nil {
+ return SOAResource{}, &nestedError{"Serial", err}
+ }
+ refresh, off, err := unpackUint32(msg, off)
+ if err != nil {
+ return SOAResource{}, &nestedError{"Refresh", err}
+ }
+ retry, off, err := unpackUint32(msg, off)
+ if err != nil {
+ return SOAResource{}, &nestedError{"Retry", err}
+ }
+ expire, off, err := unpackUint32(msg, off)
+ if err != nil {
+ return SOAResource{}, &nestedError{"Expire", err}
+ }
+ minTTL, _, err := unpackUint32(msg, off)
+ if err != nil {
+ return SOAResource{}, &nestedError{"MinTTL", err}
+ }
+ return SOAResource{ns, mbox, serial, refresh, retry, expire, minTTL}, nil
+}
+
+// A TXTResource is a TXT Resource record.
+type TXTResource struct {
+ TXT []string
+}
+
+func (r *TXTResource) realType() Type {
+ return TypeTXT
+}
+
+// pack appends the wire format of the TXTResource to msg.
+func (r *TXTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ oldMsg := msg
+ for _, s := range r.TXT {
+ var err error
+ msg, err = packText(msg, s)
+ if err != nil {
+ return oldMsg, err
+ }
+ }
+ return msg, nil
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r *TXTResource) GoString() string {
+ s := "dnsmessage.TXTResource{TXT: []string{"
+ if len(r.TXT) == 0 {
+ return s + "}}"
+ }
+ s += `"` + printString([]byte(r.TXT[0]))
+ for _, t := range r.TXT[1:] {
+ s += `", "` + printString([]byte(t))
+ }
+ return s + `"}}`
+}
+
+func unpackTXTResource(msg []byte, off int, length uint16) (TXTResource, error) {
+ txts := make([]string, 0, 1)
+ for n := uint16(0); n < length; {
+ var t string
+ var err error
+ if t, off, err = unpackText(msg, off); err != nil {
+ return TXTResource{}, &nestedError{"text", err}
+ }
+ // Check if we got too many bytes.
+ if length-n < uint16(len(t))+1 {
+ return TXTResource{}, errCalcLen
+ }
+ n += uint16(len(t)) + 1
+ txts = append(txts, t)
+ }
+ return TXTResource{txts}, nil
+}
+
+// An SRVResource is an SRV Resource record.
+type SRVResource struct {
+ Priority uint16
+ Weight uint16
+ Port uint16
+ Target Name // Not compressed as per RFC 2782.
+}
+
+func (r *SRVResource) realType() Type {
+ return TypeSRV
+}
+
+// pack appends the wire format of the SRVResource to msg.
+func (r *SRVResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ oldMsg := msg
+ msg = packUint16(msg, r.Priority)
+ msg = packUint16(msg, r.Weight)
+ msg = packUint16(msg, r.Port)
+ msg, err := r.Target.pack(msg, nil, compressionOff)
+ if err != nil {
+ return oldMsg, &nestedError{"SRVResource.Target", err}
+ }
+ return msg, nil
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r *SRVResource) GoString() string {
+ return "dnsmessage.SRVResource{" +
+ "Priority: " + printUint16(r.Priority) + ", " +
+ "Weight: " + printUint16(r.Weight) + ", " +
+ "Port: " + printUint16(r.Port) + ", " +
+ "Target: " + r.Target.GoString() + "}"
+}
+
+func unpackSRVResource(msg []byte, off int) (SRVResource, error) {
+ priority, off, err := unpackUint16(msg, off)
+ if err != nil {
+ return SRVResource{}, &nestedError{"Priority", err}
+ }
+ weight, off, err := unpackUint16(msg, off)
+ if err != nil {
+ return SRVResource{}, &nestedError{"Weight", err}
+ }
+ port, off, err := unpackUint16(msg, off)
+ if err != nil {
+ return SRVResource{}, &nestedError{"Port", err}
+ }
+ var target Name
+ if _, err := target.unpackCompressed(msg, off, false /* allowCompression */); err != nil {
+ return SRVResource{}, &nestedError{"Target", err}
+ }
+ return SRVResource{priority, weight, port, target}, nil
+}
+
+// An AResource is an A Resource record.
+type AResource struct {
+ A [4]byte
+}
+
+func (r *AResource) realType() Type {
+ return TypeA
+}
+
+// pack appends the wire format of the AResource to msg.
+func (r *AResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ return packBytes(msg, r.A[:]), nil
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r *AResource) GoString() string {
+ return "dnsmessage.AResource{" +
+ "A: [4]byte{" + printByteSlice(r.A[:]) + "}}"
+}
+
+func unpackAResource(msg []byte, off int) (AResource, error) {
+ var a [4]byte
+ if _, err := unpackBytes(msg, off, a[:]); err != nil {
+ return AResource{}, err
+ }
+ return AResource{a}, nil
+}
+
+// An AAAAResource is an AAAA Resource record.
+type AAAAResource struct {
+ AAAA [16]byte
+}
+
+func (r *AAAAResource) realType() Type {
+ return TypeAAAA
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r *AAAAResource) GoString() string {
+ return "dnsmessage.AAAAResource{" +
+ "AAAA: [16]byte{" + printByteSlice(r.AAAA[:]) + "}}"
+}
+
+// pack appends the wire format of the AAAAResource to msg.
+func (r *AAAAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ return packBytes(msg, r.AAAA[:]), nil
+}
+
+func unpackAAAAResource(msg []byte, off int) (AAAAResource, error) {
+ var aaaa [16]byte
+ if _, err := unpackBytes(msg, off, aaaa[:]); err != nil {
+ return AAAAResource{}, err
+ }
+ return AAAAResource{aaaa}, nil
+}
+
+// An OPTResource is an OPT pseudo Resource record.
+//
+// The pseudo resource record is part of the extension mechanisms for DNS
+// as defined in RFC 6891.
+type OPTResource struct {
+ Options []Option
+}
+
+// An Option represents a DNS message option within OPTResource.
+//
+// The message option is part of the extension mechanisms for DNS as
+// defined in RFC 6891.
+type Option struct {
+ Code uint16 // option code
+ Data []byte
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (o *Option) GoString() string {
+ return "dnsmessage.Option{" +
+ "Code: " + printUint16(o.Code) + ", " +
+ "Data: []byte{" + printByteSlice(o.Data) + "}}"
+}
+
+func (r *OPTResource) realType() Type {
+ return TypeOPT
+}
+
+func (r *OPTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ for _, opt := range r.Options {
+ msg = packUint16(msg, opt.Code)
+ l := uint16(len(opt.Data))
+ msg = packUint16(msg, l)
+ msg = packBytes(msg, opt.Data)
+ }
+ return msg, nil
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r *OPTResource) GoString() string {
+ s := "dnsmessage.OPTResource{Options: []dnsmessage.Option{"
+ if len(r.Options) == 0 {
+ return s + "}}"
+ }
+ s += r.Options[0].GoString()
+ for _, o := range r.Options[1:] {
+ s += ", " + o.GoString()
+ }
+ return s + "}}"
+}
+
+func unpackOPTResource(msg []byte, off int, length uint16) (OPTResource, error) {
+ var opts []Option
+ for oldOff := off; off < oldOff+int(length); {
+ var err error
+ var o Option
+ o.Code, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return OPTResource{}, &nestedError{"Code", err}
+ }
+ var l uint16
+ l, off, err = unpackUint16(msg, off)
+ if err != nil {
+ return OPTResource{}, &nestedError{"Data", err}
+ }
+ o.Data = make([]byte, l)
+ if copy(o.Data, msg[off:]) != int(l) {
+ return OPTResource{}, &nestedError{"Data", errCalcLen}
+ }
+ off += int(l)
+ opts = append(opts, o)
+ }
+ return OPTResource{opts}, nil
+}
+
+// An UnknownResource is a catch-all container for unknown record types.
+type UnknownResource struct {
+ Type Type
+ Data []byte
+}
+
+func (r *UnknownResource) realType() Type {
+ return r.Type
+}
+
+// pack appends the wire format of the UnknownResource to msg.
+func (r *UnknownResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
+ return packBytes(msg, r.Data[:]), nil
+}
+
+// GoString implements fmt.GoStringer.GoString.
+func (r *UnknownResource) GoString() string {
+ return "dnsmessage.UnknownResource{" +
+ "Type: " + r.Type.GoString() + ", " +
+ "Data: []byte{" + printByteSlice(r.Data) + "}}"
+}
+
+func unpackUnknownResource(recordType Type, msg []byte, off int, length uint16) (UnknownResource, error) {
+ parsed := UnknownResource{
+ Type: recordType,
+ Data: make([]byte, length),
+ }
+ if _, err := unpackBytes(msg, off, parsed.Data); err != nil {
+ return UnknownResource{}, err
+ }
+ return parsed, nil
+}
diff --git a/contrib/go/_std_1.20/src/net/mail/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/dns/dnsmessage/ya.make
index 1d67de6dc2..1d67de6dc2 100644
--- a/contrib/go/_std_1.20/src/net/mail/ya.make
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/dns/dnsmessage/ya.make
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpguts/guts.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpguts/guts.go
index e6cd0ced39..e6cd0ced39 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpguts/guts.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpguts/guts.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpguts/httplex.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpguts/httplex.go
index 6e071e8524..6e071e8524 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpguts/httplex.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpguts/httplex.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpguts/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpguts/ya.make
index b5a7930e00..b5a7930e00 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpguts/ya.make
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpguts/ya.make
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpproxy/proxy.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpproxy/proxy.go
index c3bd9a1eeb..c3bd9a1eeb 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpproxy/proxy.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpproxy/proxy.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpproxy/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpproxy/ya.make
index 5b43b47b28..5b43b47b28 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http/httpproxy/ya.make
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http/httpproxy/ya.make
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/encode.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/encode.go
index 46219da2b0..46219da2b0 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/encode.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/encode.go
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/hpack.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/hpack.go
new file mode 100644
index 0000000000..7a1d976696
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/hpack.go
@@ -0,0 +1,523 @@
+// Copyright 2014 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 hpack implements HPACK, a compression format for
+// efficiently representing HTTP header fields in the context of HTTP/2.
+//
+// See http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09
+package hpack
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+)
+
+// A DecodingError is something the spec defines as a decoding error.
+type DecodingError struct {
+ Err error
+}
+
+func (de DecodingError) Error() string {
+ return fmt.Sprintf("decoding error: %v", de.Err)
+}
+
+// An InvalidIndexError is returned when an encoder references a table
+// entry before the static table or after the end of the dynamic table.
+type InvalidIndexError int
+
+func (e InvalidIndexError) Error() string {
+ return fmt.Sprintf("invalid indexed representation index %d", int(e))
+}
+
+// A HeaderField is a name-value pair. Both the name and value are
+// treated as opaque sequences of octets.
+type HeaderField struct {
+ Name, Value string
+
+ // Sensitive means that this header field should never be
+ // indexed.
+ Sensitive bool
+}
+
+// IsPseudo reports whether the header field is an http2 pseudo header.
+// That is, it reports whether it starts with a colon.
+// It is not otherwise guaranteed to be a valid pseudo header field,
+// though.
+func (hf HeaderField) IsPseudo() bool {
+ return len(hf.Name) != 0 && hf.Name[0] == ':'
+}
+
+func (hf HeaderField) String() string {
+ var suffix string
+ if hf.Sensitive {
+ suffix = " (sensitive)"
+ }
+ return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix)
+}
+
+// Size returns the size of an entry per RFC 7541 section 4.1.
+func (hf HeaderField) Size() uint32 {
+ // https://httpwg.org/specs/rfc7541.html#rfc.section.4.1
+ // "The size of the dynamic table is the sum of the size of
+ // its entries. The size of an entry is the sum of its name's
+ // length in octets (as defined in Section 5.2), its value's
+ // length in octets (see Section 5.2), plus 32. The size of
+ // an entry is calculated using the length of the name and
+ // value without any Huffman encoding applied."
+
+ // This can overflow if somebody makes a large HeaderField
+ // Name and/or Value by hand, but we don't care, because that
+ // won't happen on the wire because the encoding doesn't allow
+ // it.
+ return uint32(len(hf.Name) + len(hf.Value) + 32)
+}
+
+// A Decoder is the decoding context for incremental processing of
+// header blocks.
+type Decoder struct {
+ dynTab dynamicTable
+ emit func(f HeaderField)
+
+ emitEnabled bool // whether calls to emit are enabled
+ maxStrLen int // 0 means unlimited
+
+ // buf is the unparsed buffer. It's only written to
+ // saveBuf if it was truncated in the middle of a header
+ // block. Because it's usually not owned, we can only
+ // process it under Write.
+ buf []byte // not owned; only valid during Write
+
+ // saveBuf is previous data passed to Write which we weren't able
+ // to fully parse before. Unlike buf, we own this data.
+ saveBuf bytes.Buffer
+
+ firstField bool // processing the first field of the header block
+}
+
+// NewDecoder returns a new decoder with the provided maximum dynamic
+// table size. The emitFunc will be called for each valid field
+// parsed, in the same goroutine as calls to Write, before Write returns.
+func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder {
+ d := &Decoder{
+ emit: emitFunc,
+ emitEnabled: true,
+ firstField: true,
+ }
+ d.dynTab.table.init()
+ d.dynTab.allowedMaxSize = maxDynamicTableSize
+ d.dynTab.setMaxSize(maxDynamicTableSize)
+ return d
+}
+
+// ErrStringLength is returned by Decoder.Write when the max string length
+// (as configured by Decoder.SetMaxStringLength) would be violated.
+var ErrStringLength = errors.New("hpack: string too long")
+
+// SetMaxStringLength sets the maximum size of a HeaderField name or
+// value string. If a string exceeds this length (even after any
+// decompression), Write will return ErrStringLength.
+// A value of 0 means unlimited and is the default from NewDecoder.
+func (d *Decoder) SetMaxStringLength(n int) {
+ d.maxStrLen = n
+}
+
+// SetEmitFunc changes the callback used when new header fields
+// are decoded.
+// It must be non-nil. It does not affect EmitEnabled.
+func (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) {
+ d.emit = emitFunc
+}
+
+// SetEmitEnabled controls whether the emitFunc provided to NewDecoder
+// should be called. The default is true.
+//
+// This facility exists to let servers enforce MAX_HEADER_LIST_SIZE
+// while still decoding and keeping in-sync with decoder state, but
+// without doing unnecessary decompression or generating unnecessary
+// garbage for header fields past the limit.
+func (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v }
+
+// EmitEnabled reports whether calls to the emitFunc provided to NewDecoder
+// are currently enabled. The default is true.
+func (d *Decoder) EmitEnabled() bool { return d.emitEnabled }
+
+// TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their
+// underlying buffers for garbage reasons.
+
+func (d *Decoder) SetMaxDynamicTableSize(v uint32) {
+ d.dynTab.setMaxSize(v)
+}
+
+// SetAllowedMaxDynamicTableSize sets the upper bound that the encoded
+// stream (via dynamic table size updates) may set the maximum size
+// to.
+func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {
+ d.dynTab.allowedMaxSize = v
+}
+
+type dynamicTable struct {
+ // https://httpwg.org/specs/rfc7541.html#rfc.section.2.3.2
+ table headerFieldTable
+ size uint32 // in bytes
+ maxSize uint32 // current maxSize
+ allowedMaxSize uint32 // maxSize may go up to this, inclusive
+}
+
+func (dt *dynamicTable) setMaxSize(v uint32) {
+ dt.maxSize = v
+ dt.evict()
+}
+
+func (dt *dynamicTable) add(f HeaderField) {
+ dt.table.addEntry(f)
+ dt.size += f.Size()
+ dt.evict()
+}
+
+// If we're too big, evict old stuff.
+func (dt *dynamicTable) evict() {
+ var n int
+ for dt.size > dt.maxSize && n < dt.table.len() {
+ dt.size -= dt.table.ents[n].Size()
+ n++
+ }
+ dt.table.evictOldest(n)
+}
+
+func (d *Decoder) maxTableIndex() int {
+ // This should never overflow. RFC 7540 Section 6.5.2 limits the size of
+ // the dynamic table to 2^32 bytes, where each entry will occupy more than
+ // one byte. Further, the staticTable has a fixed, small length.
+ return d.dynTab.table.len() + staticTable.len()
+}
+
+func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) {
+ // See Section 2.3.3.
+ if i == 0 {
+ return
+ }
+ if i <= uint64(staticTable.len()) {
+ return staticTable.ents[i-1], true
+ }
+ if i > uint64(d.maxTableIndex()) {
+ return
+ }
+ // In the dynamic table, newer entries have lower indices.
+ // However, dt.ents[0] is the oldest entry. Hence, dt.ents is
+ // the reversed dynamic table.
+ dt := d.dynTab.table
+ return dt.ents[dt.len()-(int(i)-staticTable.len())], true
+}
+
+// DecodeFull decodes an entire block.
+//
+// TODO: remove this method and make it incremental later? This is
+// easier for debugging now.
+func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {
+ var hf []HeaderField
+ saveFunc := d.emit
+ defer func() { d.emit = saveFunc }()
+ d.emit = func(f HeaderField) { hf = append(hf, f) }
+ if _, err := d.Write(p); err != nil {
+ return nil, err
+ }
+ if err := d.Close(); err != nil {
+ return nil, err
+ }
+ return hf, nil
+}
+
+// Close declares that the decoding is complete and resets the Decoder
+// to be reused again for a new header block. If there is any remaining
+// data in the decoder's buffer, Close returns an error.
+func (d *Decoder) Close() error {
+ if d.saveBuf.Len() > 0 {
+ d.saveBuf.Reset()
+ return DecodingError{errors.New("truncated headers")}
+ }
+ d.firstField = true
+ return nil
+}
+
+func (d *Decoder) Write(p []byte) (n int, err error) {
+ if len(p) == 0 {
+ // Prevent state machine CPU attacks (making us redo
+ // work up to the point of finding out we don't have
+ // enough data)
+ return
+ }
+ // Only copy the data if we have to. Optimistically assume
+ // that p will contain a complete header block.
+ if d.saveBuf.Len() == 0 {
+ d.buf = p
+ } else {
+ d.saveBuf.Write(p)
+ d.buf = d.saveBuf.Bytes()
+ d.saveBuf.Reset()
+ }
+
+ for len(d.buf) > 0 {
+ err = d.parseHeaderFieldRepr()
+ if err == errNeedMore {
+ // Extra paranoia, making sure saveBuf won't
+ // get too large. All the varint and string
+ // reading code earlier should already catch
+ // overlong things and return ErrStringLength,
+ // but keep this as a last resort.
+ const varIntOverhead = 8 // conservative
+ if d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) {
+ return 0, ErrStringLength
+ }
+ d.saveBuf.Write(d.buf)
+ return len(p), nil
+ }
+ d.firstField = false
+ if err != nil {
+ break
+ }
+ }
+ return len(p), err
+}
+
+// errNeedMore is an internal sentinel error value that means the
+// buffer is truncated and we need to read more data before we can
+// continue parsing.
+var errNeedMore = errors.New("need more data")
+
+type indexType int
+
+const (
+ indexedTrue indexType = iota
+ indexedFalse
+ indexedNever
+)
+
+func (v indexType) indexed() bool { return v == indexedTrue }
+func (v indexType) sensitive() bool { return v == indexedNever }
+
+// returns errNeedMore if there isn't enough data available.
+// any other error is fatal.
+// consumes d.buf iff it returns nil.
+// precondition: must be called with len(d.buf) > 0
+func (d *Decoder) parseHeaderFieldRepr() error {
+ b := d.buf[0]
+ switch {
+ case b&128 != 0:
+ // Indexed representation.
+ // High bit set?
+ // https://httpwg.org/specs/rfc7541.html#rfc.section.6.1
+ return d.parseFieldIndexed()
+ case b&192 == 64:
+ // 6.2.1 Literal Header Field with Incremental Indexing
+ // 0b10xxxxxx: top two bits are 10
+ // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1
+ return d.parseFieldLiteral(6, indexedTrue)
+ case b&240 == 0:
+ // 6.2.2 Literal Header Field without Indexing
+ // 0b0000xxxx: top four bits are 0000
+ // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2
+ return d.parseFieldLiteral(4, indexedFalse)
+ case b&240 == 16:
+ // 6.2.3 Literal Header Field never Indexed
+ // 0b0001xxxx: top four bits are 0001
+ // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3
+ return d.parseFieldLiteral(4, indexedNever)
+ case b&224 == 32:
+ // 6.3 Dynamic Table Size Update
+ // Top three bits are '001'.
+ // https://httpwg.org/specs/rfc7541.html#rfc.section.6.3
+ return d.parseDynamicTableSizeUpdate()
+ }
+
+ return DecodingError{errors.New("invalid encoding")}
+}
+
+// (same invariants and behavior as parseHeaderFieldRepr)
+func (d *Decoder) parseFieldIndexed() error {
+ buf := d.buf
+ idx, buf, err := readVarInt(7, buf)
+ if err != nil {
+ return err
+ }
+ hf, ok := d.at(idx)
+ if !ok {
+ return DecodingError{InvalidIndexError(idx)}
+ }
+ d.buf = buf
+ return d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value})
+}
+
+// (same invariants and behavior as parseHeaderFieldRepr)
+func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
+ buf := d.buf
+ nameIdx, buf, err := readVarInt(n, buf)
+ if err != nil {
+ return err
+ }
+
+ var hf HeaderField
+ wantStr := d.emitEnabled || it.indexed()
+ var undecodedName undecodedString
+ if nameIdx > 0 {
+ ihf, ok := d.at(nameIdx)
+ if !ok {
+ return DecodingError{InvalidIndexError(nameIdx)}
+ }
+ hf.Name = ihf.Name
+ } else {
+ undecodedName, buf, err = d.readString(buf)
+ if err != nil {
+ return err
+ }
+ }
+ undecodedValue, buf, err := d.readString(buf)
+ if err != nil {
+ return err
+ }
+ if wantStr {
+ if nameIdx <= 0 {
+ hf.Name, err = d.decodeString(undecodedName)
+ if err != nil {
+ return err
+ }
+ }
+ hf.Value, err = d.decodeString(undecodedValue)
+ if err != nil {
+ return err
+ }
+ }
+ d.buf = buf
+ if it.indexed() {
+ d.dynTab.add(hf)
+ }
+ hf.Sensitive = it.sensitive()
+ return d.callEmit(hf)
+}
+
+func (d *Decoder) callEmit(hf HeaderField) error {
+ if d.maxStrLen != 0 {
+ if len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen {
+ return ErrStringLength
+ }
+ }
+ if d.emitEnabled {
+ d.emit(hf)
+ }
+ return nil
+}
+
+// (same invariants and behavior as parseHeaderFieldRepr)
+func (d *Decoder) parseDynamicTableSizeUpdate() error {
+ // RFC 7541, sec 4.2: This dynamic table size update MUST occur at the
+ // beginning of the first header block following the change to the dynamic table size.
+ if !d.firstField && d.dynTab.size > 0 {
+ return DecodingError{errors.New("dynamic table size update MUST occur at the beginning of a header block")}
+ }
+
+ buf := d.buf
+ size, buf, err := readVarInt(5, buf)
+ if err != nil {
+ return err
+ }
+ if size > uint64(d.dynTab.allowedMaxSize) {
+ return DecodingError{errors.New("dynamic table size update too large")}
+ }
+ d.dynTab.setMaxSize(uint32(size))
+ d.buf = buf
+ return nil
+}
+
+var errVarintOverflow = DecodingError{errors.New("varint integer overflow")}
+
+// readVarInt reads an unsigned variable length integer off the
+// beginning of p. n is the parameter as described in
+// https://httpwg.org/specs/rfc7541.html#rfc.section.5.1.
+//
+// n must always be between 1 and 8.
+//
+// The returned remain buffer is either a smaller suffix of p, or err != nil.
+// The error is errNeedMore if p doesn't contain a complete integer.
+func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {
+ if n < 1 || n > 8 {
+ panic("bad n")
+ }
+ if len(p) == 0 {
+ return 0, p, errNeedMore
+ }
+ i = uint64(p[0])
+ if n < 8 {
+ i &= (1 << uint64(n)) - 1
+ }
+ if i < (1<<uint64(n))-1 {
+ return i, p[1:], nil
+ }
+
+ origP := p
+ p = p[1:]
+ var m uint64
+ for len(p) > 0 {
+ b := p[0]
+ p = p[1:]
+ i += uint64(b&127) << m
+ if b&128 == 0 {
+ return i, p, nil
+ }
+ m += 7
+ if m >= 63 { // TODO: proper overflow check. making this up.
+ return 0, origP, errVarintOverflow
+ }
+ }
+ return 0, origP, errNeedMore
+}
+
+// readString reads an hpack string from p.
+//
+// It returns a reference to the encoded string data to permit deferring decode costs
+// until after the caller verifies all data is present.
+func (d *Decoder) readString(p []byte) (u undecodedString, remain []byte, err error) {
+ if len(p) == 0 {
+ return u, p, errNeedMore
+ }
+ isHuff := p[0]&128 != 0
+ strLen, p, err := readVarInt(7, p)
+ if err != nil {
+ return u, p, err
+ }
+ if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {
+ // Returning an error here means Huffman decoding errors
+ // for non-indexed strings past the maximum string length
+ // are ignored, but the server is returning an error anyway
+ // and because the string is not indexed the error will not
+ // affect the decoding state.
+ return u, nil, ErrStringLength
+ }
+ if uint64(len(p)) < strLen {
+ return u, p, errNeedMore
+ }
+ u.isHuff = isHuff
+ u.b = p[:strLen]
+ return u, p[strLen:], nil
+}
+
+type undecodedString struct {
+ isHuff bool
+ b []byte
+}
+
+func (d *Decoder) decodeString(u undecodedString) (string, error) {
+ if !u.isHuff {
+ return string(u.b), nil
+ }
+ buf := bufPool.Get().(*bytes.Buffer)
+ buf.Reset() // don't trust others
+ var s string
+ err := huffmanDecode(buf, d.maxStrLen, u.b)
+ if err == nil {
+ s = buf.String()
+ }
+ buf.Reset() // be nice to GC
+ bufPool.Put(buf)
+ return s, err
+}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/huffman.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/huffman.go
index 20d083a716..20d083a716 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/huffman.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/huffman.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/static_table.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/static_table.go
index 754a1eb919..754a1eb919 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/static_table.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/static_table.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/tables.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/tables.go
index 8cbdf3f019..8cbdf3f019 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/tables.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/tables.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/ya.make
index 46ddd662ea..46ddd662ea 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/http2/hpack/ya.make
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/http2/hpack/ya.make
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/go118.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/go118.go
index c5c4338dbe..c5c4338dbe 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/go118.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/go118.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/idna10.0.0.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/idna10.0.0.go
index 64ccf85feb..64ccf85feb 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/idna10.0.0.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/idna10.0.0.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/punycode.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/punycode.go
index e8e3ac11a9..e8e3ac11a9 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/punycode.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/punycode.go
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/tables13.0.0.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/tables13.0.0.go
new file mode 100644
index 0000000000..66701eadfb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/tables13.0.0.go
@@ -0,0 +1,4960 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+//go:build go1.16 && !go1.21
+// +build go1.16,!go1.21
+
+package idna
+
+// UnicodeVersion is the Unicode version from which the tables in this package are derived.
+const UnicodeVersion = "13.0.0"
+
+var mappings string = "" + // Size: 6539 bytes
+ " ̈a ̄23 ́ ̧1o1⁄41⁄23⁄4i̇l·ʼnsdžⱥⱦhjrwy ̆ ̇ ̊ ̨ ̃ ̋lẍ́ ι; ̈́եւاٴوٴۇٴيٴक" +
+ "़ख़ग़ज़ड़ढ़फ़य़ড়ঢ়য়ਲ਼ਸ਼ਖ਼ਗ਼ਜ਼ਫ਼ଡ଼ଢ଼ําໍາຫນຫມགྷཌྷདྷབྷཛྷཀྵཱཱིུྲྀྲཱྀླྀླཱ" +
+ "ཱྀྀྒྷྜྷྡྷྦྷྫྷྐྵвдостъѣæbdeǝgikmnȣptuɐɑəɛɜŋɔɯvβγδφχρнɒcɕðfɟɡɥɨɩɪʝɭʟɱɰɲɳ" +
+ "ɴɵɸʂʃƫʉʊʋʌzʐʑʒθssάέήίόύώἀιἁιἂιἃιἄιἅιἆιἇιἠιἡιἢιἣιἤιἥιἦιἧιὠιὡιὢιὣιὤιὥιὦιὧ" +
+ "ιὰιαιάιᾶιι ̈͂ὴιηιήιῆι ̓̀ ̓́ ̓͂ΐ ̔̀ ̔́ ̔͂ΰ ̈̀`ὼιωιώιῶι′′′′′‵‵‵‵‵!!???!!?" +
+ "′′′′0456789+=()rsħnoqsmtmωåאבגדπ1⁄71⁄91⁄101⁄32⁄31⁄52⁄53⁄54⁄51⁄65⁄61⁄83" +
+ "⁄85⁄87⁄81⁄iiivviviiiixxi0⁄3∫∫∫∫∫∮∮∮∮∮1011121314151617181920(10)(11)(12" +
+ ")(13)(14)(15)(16)(17)(18)(19)(20)∫∫∫∫==⫝̸ɫɽȿɀ. ゙ ゚よりコト(ᄀ)(ᄂ)(ᄃ)(ᄅ)(ᄆ)(ᄇ)" +
+ "(ᄉ)(ᄋ)(ᄌ)(ᄎ)(ᄏ)(ᄐ)(ᄑ)(ᄒ)(가)(나)(다)(라)(마)(바)(사)(아)(자)(차)(카)(타)(파)(하)(주)(오전" +
+ ")(오후)(一)(二)(三)(四)(五)(六)(七)(八)(九)(十)(月)(火)(水)(木)(金)(土)(日)(株)(有)(社)(名)(特)(" +
+ "財)(祝)(労)(代)(呼)(学)(監)(企)(資)(協)(祭)(休)(自)(至)21222324252627282930313233343" +
+ "5참고주의3637383940414243444546474849501月2月3月4月5月6月7月8月9月10月11月12月hgev令和アパート" +
+ "アルファアンペアアールイニングインチウォンエスクードエーカーオンスオームカイリカラットカロリーガロンガンマギガギニーキュリーギルダーキロキロ" +
+ "グラムキロメートルキロワットグラムグラムトンクルゼイロクローネケースコルナコーポサイクルサンチームシリングセンチセントダースデシドルトンナノ" +
+ "ノットハイツパーセントパーツバーレルピアストルピクルピコビルファラッドフィートブッシェルフランヘクタールペソペニヒヘルツペンスページベータポ" +
+ "イントボルトホンポンドホールホーンマイクロマイルマッハマルクマンションミクロンミリミリバールメガメガトンメートルヤードヤールユアンリットルリ" +
+ "ラルピールーブルレムレントゲンワット0点1点2点3点4点5点6点7点8点9点10点11点12点13点14点15点16点17点18点19点20" +
+ "点21点22点23点24点daauovpcdmiu平成昭和大正明治株式会社panamakakbmbgbkcalpfnfmgkghzmldlk" +
+ "lfmnmmmcmkmm2m3m∕sm∕s2rad∕srad∕s2psnsmspvnvmvkvpwnwmwkwbqcccdc∕kgdbgyhah" +
+ "pinkkktlmlnlxphprsrsvwbv∕ma∕m1日2日3日4日5日6日7日8日9日10日11日12日13日14日15日16日17日1" +
+ "8日19日20日21日22日23日24日25日26日27日28日29日30日31日ьɦɬʞʇœʍ𤋮𢡊𢡄𣏕𥉉𥳐𧻓fffiflstմնմեմիվնմ" +
+ "խיִײַעהכלםרתשׁשׂשּׁשּׂאַאָאּבּגּדּהּוּזּטּיּךּכּלּמּנּסּףּפּצּקּרּשּתּו" +
+ "ֹבֿכֿפֿאלٱٻپڀٺٿٹڤڦڄڃچڇڍڌڎڈژڑکگڳڱںڻۀہھےۓڭۇۆۈۋۅۉېىئائەئوئۇئۆئۈئېئىیئجئحئم" +
+ "ئيبجبحبخبمبىبيتجتحتختمتىتيثجثمثىثيجحجمحجحمخجخحخمسجسحسخسمصحصمضجضحضخضمطحط" +
+ "مظمعجعمغجغمفجفحفخفمفىفيقحقمقىقيكاكجكحكخكلكمكىكيلجلحلخلملىليمجمحمخمممىمي" +
+ "نجنحنخنمنىنيهجهمهىهييجيحيخيميىييذٰرٰىٰ ٌّ ٍّ َّ ُّ ِّ ّٰئرئزئنبربزبنترت" +
+ "زتنثرثزثنمانرنزننيريزينئخئهبهتهصخلهنههٰيهثهسهشمشهـَّـُّـِّطىطيعىعيغىغيس" +
+ "ىسيشىشيحىحيجىجيخىخيصىصيضىضيشجشحشخشرسرصرضراًتجمتحجتحمتخمتمجتمحتمخجمححميح" +
+ "مىسحجسجحسجىسمحسمجسممصححصممشحمشجيشمخشممضحىضخمطمحطممطميعجمعممعمىغممغميغمى" +
+ "فخمقمحقمملحملحيلحىلججلخملمحمحجمحممحيمجحمجممخجمخممجخهمجهممنحمنحىنجمنجىنم" +
+ "ينمىيممبخيتجيتجىتخيتخىتميتمىجميجحىجمىسخىصحيشحيضحيلجيلمييحييجييميمميقمين" +
+ "حيعميكمينجحمخيلجمكممجحيحجيمجيفميبحيسخينجيصلےقلےاللهاكبرمحمدصلعمرسولعليه" +
+ "وسلمصلىصلى الله عليه وسلمجل جلالهریال,:!?_{}[]#&*-<>\\$%@ـًـَـُـِـّـْءآ" +
+ "أؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهويلآلألإلا\x22'/^|~¢£¬¦¥𝅗𝅥𝅘𝅥𝅘𝅥𝅮𝅘𝅥𝅯𝅘𝅥𝅰𝅘𝅥𝅱" +
+ "𝅘𝅥𝅲𝆹𝅥𝆺𝅥𝆹𝅥𝅮𝆺𝅥𝅮𝆹𝅥𝅯𝆺𝅥𝅯ıȷαεζηκλμνξοστυψ∇∂ϝٮڡٯ0,1,2,3,4,5,6,7,8,9,(a)(b)(c" +
+ ")(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)(o)(p)(q)(r)(s)(t)(u)(v)(w)(x)(y)(z)〔s" +
+ "〕wzhvsdppvwcmcmdmrdjほかココサ手字双デ二多解天交映無料前後再新初終生販声吹演投捕一三遊左中右指走打禁空合満有月申割営配〔" +
+ "本〕〔三〕〔二〕〔安〕〔点〕〔打〕〔盗〕〔勝〕〔敗〕得可丽丸乁你侮侻倂偺備僧像㒞免兔兤具㒹內冗冤仌冬况凵刃㓟刻剆剷㔕勇勉勤勺包匆北卉卑博即卽" +
+ "卿灰及叟叫叱吆咞吸呈周咢哶唐啓啣善喙喫喳嗂圖嘆圗噑噴切壮城埴堍型堲報墬売壷夆夢奢姬娛娧姘婦㛮嬈嬾寃寘寧寳寿将尢㞁屠屮峀岍嵃嵮嵫嵼巡巢㠯巽帨帽" +
+ "幩㡢㡼庰庳庶廊廾舁弢㣇形彫㣣徚忍志忹悁㤺㤜悔惇慈慌慎慺憎憲憤憯懞懲懶成戛扝抱拔捐挽拼捨掃揤搢揅掩㨮摩摾撝摷㩬敏敬旣書晉㬙暑㬈㫤冒冕最暜肭䏙朗" +
+ "望朡杞杓㭉柺枅桒梅梎栟椔㮝楂榣槪檨櫛㰘次歔㱎歲殟殺殻汎沿泍汧洖派海流浩浸涅洴港湮㴳滋滇淹潮濆瀹瀞瀛㶖灊災灷炭煅熜爨爵牐犀犕獺王㺬玥㺸瑇瑜瑱璅" +
+ "瓊㼛甤甾異瘐㿼䀈直眞真睊䀹瞋䁆䂖硎碌磌䃣祖福秫䄯穀穊穏䈂篆築䈧糒䊠糨糣紀絣䌁緇縂繅䌴䍙罺羕翺者聠聰䏕育脃䐋脾媵舄辞䑫芑芋芝劳花芳芽苦若茝荣莭" +
+ "茣莽菧著荓菊菌菜䔫蓱蓳蔖蕤䕝䕡䕫虐虜虧虩蚩蚈蜎蛢蝹蜨蝫螆蟡蠁䗹衠衣裗裞䘵裺㒻䚾䛇誠諭變豕貫賁贛起跋趼跰軔輸邔郱鄑鄛鈸鋗鋘鉼鏹鐕開䦕閷䧦雃嶲霣" +
+ "䩮䩶韠䪲頋頩飢䬳餩馧駂駾䯎鬒鱀鳽䳎䳭鵧䳸麻䵖黹黾鼅鼏鼖鼻"
+
+var mappingIndex = []uint16{ // 1650 elements
+ // Entry 0 - 3F
+ 0x0000, 0x0000, 0x0001, 0x0004, 0x0005, 0x0008, 0x0009, 0x000a,
+ 0x000d, 0x0010, 0x0011, 0x0012, 0x0017, 0x001c, 0x0021, 0x0024,
+ 0x0027, 0x002a, 0x002b, 0x002e, 0x0031, 0x0034, 0x0035, 0x0036,
+ 0x0037, 0x0038, 0x0039, 0x003c, 0x003f, 0x0042, 0x0045, 0x0048,
+ 0x004b, 0x004c, 0x004d, 0x0051, 0x0054, 0x0055, 0x005a, 0x005e,
+ 0x0062, 0x0066, 0x006a, 0x006e, 0x0074, 0x007a, 0x0080, 0x0086,
+ 0x008c, 0x0092, 0x0098, 0x009e, 0x00a4, 0x00aa, 0x00b0, 0x00b6,
+ 0x00bc, 0x00c2, 0x00c8, 0x00ce, 0x00d4, 0x00da, 0x00e0, 0x00e6,
+ // Entry 40 - 7F
+ 0x00ec, 0x00f2, 0x00f8, 0x00fe, 0x0104, 0x010a, 0x0110, 0x0116,
+ 0x011c, 0x0122, 0x0128, 0x012e, 0x0137, 0x013d, 0x0146, 0x014c,
+ 0x0152, 0x0158, 0x015e, 0x0164, 0x016a, 0x0170, 0x0172, 0x0174,
+ 0x0176, 0x0178, 0x017a, 0x017c, 0x017e, 0x0180, 0x0181, 0x0182,
+ 0x0183, 0x0185, 0x0186, 0x0187, 0x0188, 0x0189, 0x018a, 0x018c,
+ 0x018d, 0x018e, 0x018f, 0x0191, 0x0193, 0x0195, 0x0197, 0x0199,
+ 0x019b, 0x019d, 0x019f, 0x01a0, 0x01a2, 0x01a4, 0x01a6, 0x01a8,
+ 0x01aa, 0x01ac, 0x01ae, 0x01b0, 0x01b1, 0x01b3, 0x01b5, 0x01b6,
+ // Entry 80 - BF
+ 0x01b8, 0x01ba, 0x01bc, 0x01be, 0x01c0, 0x01c2, 0x01c4, 0x01c6,
+ 0x01c8, 0x01ca, 0x01cc, 0x01ce, 0x01d0, 0x01d2, 0x01d4, 0x01d6,
+ 0x01d8, 0x01da, 0x01dc, 0x01de, 0x01e0, 0x01e2, 0x01e4, 0x01e5,
+ 0x01e7, 0x01e9, 0x01eb, 0x01ed, 0x01ef, 0x01f1, 0x01f3, 0x01f5,
+ 0x01f7, 0x01f9, 0x01fb, 0x01fd, 0x0202, 0x0207, 0x020c, 0x0211,
+ 0x0216, 0x021b, 0x0220, 0x0225, 0x022a, 0x022f, 0x0234, 0x0239,
+ 0x023e, 0x0243, 0x0248, 0x024d, 0x0252, 0x0257, 0x025c, 0x0261,
+ 0x0266, 0x026b, 0x0270, 0x0275, 0x027a, 0x027e, 0x0282, 0x0287,
+ // Entry C0 - FF
+ 0x0289, 0x028e, 0x0293, 0x0297, 0x029b, 0x02a0, 0x02a5, 0x02aa,
+ 0x02af, 0x02b1, 0x02b6, 0x02bb, 0x02c0, 0x02c2, 0x02c7, 0x02c8,
+ 0x02cd, 0x02d1, 0x02d5, 0x02da, 0x02e0, 0x02e9, 0x02ef, 0x02f8,
+ 0x02fa, 0x02fc, 0x02fe, 0x0300, 0x030c, 0x030d, 0x030e, 0x030f,
+ 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,
+ 0x0319, 0x031b, 0x031d, 0x031e, 0x0320, 0x0322, 0x0324, 0x0326,
+ 0x0328, 0x032a, 0x032c, 0x032e, 0x0330, 0x0335, 0x033a, 0x0340,
+ 0x0345, 0x034a, 0x034f, 0x0354, 0x0359, 0x035e, 0x0363, 0x0368,
+ // Entry 100 - 13F
+ 0x036d, 0x0372, 0x0377, 0x037c, 0x0380, 0x0382, 0x0384, 0x0386,
+ 0x038a, 0x038c, 0x038e, 0x0393, 0x0399, 0x03a2, 0x03a8, 0x03b1,
+ 0x03b3, 0x03b5, 0x03b7, 0x03b9, 0x03bb, 0x03bd, 0x03bf, 0x03c1,
+ 0x03c3, 0x03c5, 0x03c7, 0x03cb, 0x03cf, 0x03d3, 0x03d7, 0x03db,
+ 0x03df, 0x03e3, 0x03e7, 0x03eb, 0x03ef, 0x03f3, 0x03ff, 0x0401,
+ 0x0406, 0x0408, 0x040a, 0x040c, 0x040e, 0x040f, 0x0413, 0x0417,
+ 0x041d, 0x0423, 0x0428, 0x042d, 0x0432, 0x0437, 0x043c, 0x0441,
+ 0x0446, 0x044b, 0x0450, 0x0455, 0x045a, 0x045f, 0x0464, 0x0469,
+ // Entry 140 - 17F
+ 0x046e, 0x0473, 0x0478, 0x047d, 0x0482, 0x0487, 0x048c, 0x0491,
+ 0x0496, 0x049b, 0x04a0, 0x04a5, 0x04aa, 0x04af, 0x04b4, 0x04bc,
+ 0x04c4, 0x04c9, 0x04ce, 0x04d3, 0x04d8, 0x04dd, 0x04e2, 0x04e7,
+ 0x04ec, 0x04f1, 0x04f6, 0x04fb, 0x0500, 0x0505, 0x050a, 0x050f,
+ 0x0514, 0x0519, 0x051e, 0x0523, 0x0528, 0x052d, 0x0532, 0x0537,
+ 0x053c, 0x0541, 0x0546, 0x054b, 0x0550, 0x0555, 0x055a, 0x055f,
+ 0x0564, 0x0569, 0x056e, 0x0573, 0x0578, 0x057a, 0x057c, 0x057e,
+ 0x0580, 0x0582, 0x0584, 0x0586, 0x0588, 0x058a, 0x058c, 0x058e,
+ // Entry 180 - 1BF
+ 0x0590, 0x0592, 0x0594, 0x0596, 0x059c, 0x05a2, 0x05a4, 0x05a6,
+ 0x05a8, 0x05aa, 0x05ac, 0x05ae, 0x05b0, 0x05b2, 0x05b4, 0x05b6,
+ 0x05b8, 0x05ba, 0x05bc, 0x05be, 0x05c0, 0x05c4, 0x05c8, 0x05cc,
+ 0x05d0, 0x05d4, 0x05d8, 0x05dc, 0x05e0, 0x05e4, 0x05e9, 0x05ee,
+ 0x05f3, 0x05f5, 0x05f7, 0x05fd, 0x0609, 0x0615, 0x0621, 0x062a,
+ 0x0636, 0x063f, 0x0648, 0x0657, 0x0663, 0x066c, 0x0675, 0x067e,
+ 0x068a, 0x0696, 0x069f, 0x06a8, 0x06ae, 0x06b7, 0x06c3, 0x06cf,
+ 0x06d5, 0x06e4, 0x06f6, 0x0705, 0x070e, 0x071d, 0x072c, 0x0738,
+ // Entry 1C0 - 1FF
+ 0x0741, 0x074a, 0x0753, 0x075f, 0x076e, 0x077a, 0x0783, 0x078c,
+ 0x0795, 0x079b, 0x07a1, 0x07a7, 0x07ad, 0x07b6, 0x07bf, 0x07ce,
+ 0x07d7, 0x07e3, 0x07f2, 0x07fb, 0x0801, 0x0807, 0x0816, 0x0822,
+ 0x0831, 0x083a, 0x0849, 0x084f, 0x0858, 0x0861, 0x086a, 0x0873,
+ 0x087c, 0x0888, 0x0891, 0x0897, 0x08a0, 0x08a9, 0x08b2, 0x08be,
+ 0x08c7, 0x08d0, 0x08d9, 0x08e8, 0x08f4, 0x08fa, 0x0909, 0x090f,
+ 0x091b, 0x0927, 0x0930, 0x0939, 0x0942, 0x094e, 0x0954, 0x095d,
+ 0x0969, 0x096f, 0x097e, 0x0987, 0x098b, 0x098f, 0x0993, 0x0997,
+ // Entry 200 - 23F
+ 0x099b, 0x099f, 0x09a3, 0x09a7, 0x09ab, 0x09af, 0x09b4, 0x09b9,
+ 0x09be, 0x09c3, 0x09c8, 0x09cd, 0x09d2, 0x09d7, 0x09dc, 0x09e1,
+ 0x09e6, 0x09eb, 0x09f0, 0x09f5, 0x09fa, 0x09fc, 0x09fe, 0x0a00,
+ 0x0a02, 0x0a04, 0x0a06, 0x0a0c, 0x0a12, 0x0a18, 0x0a1e, 0x0a2a,
+ 0x0a2c, 0x0a2e, 0x0a30, 0x0a32, 0x0a34, 0x0a36, 0x0a38, 0x0a3c,
+ 0x0a3e, 0x0a40, 0x0a42, 0x0a44, 0x0a46, 0x0a48, 0x0a4a, 0x0a4c,
+ 0x0a4e, 0x0a50, 0x0a52, 0x0a54, 0x0a56, 0x0a58, 0x0a5a, 0x0a5f,
+ 0x0a65, 0x0a6c, 0x0a74, 0x0a76, 0x0a78, 0x0a7a, 0x0a7c, 0x0a7e,
+ // Entry 240 - 27F
+ 0x0a80, 0x0a82, 0x0a84, 0x0a86, 0x0a88, 0x0a8a, 0x0a8c, 0x0a8e,
+ 0x0a90, 0x0a96, 0x0a98, 0x0a9a, 0x0a9c, 0x0a9e, 0x0aa0, 0x0aa2,
+ 0x0aa4, 0x0aa6, 0x0aa8, 0x0aaa, 0x0aac, 0x0aae, 0x0ab0, 0x0ab2,
+ 0x0ab4, 0x0ab9, 0x0abe, 0x0ac2, 0x0ac6, 0x0aca, 0x0ace, 0x0ad2,
+ 0x0ad6, 0x0ada, 0x0ade, 0x0ae2, 0x0ae7, 0x0aec, 0x0af1, 0x0af6,
+ 0x0afb, 0x0b00, 0x0b05, 0x0b0a, 0x0b0f, 0x0b14, 0x0b19, 0x0b1e,
+ 0x0b23, 0x0b28, 0x0b2d, 0x0b32, 0x0b37, 0x0b3c, 0x0b41, 0x0b46,
+ 0x0b4b, 0x0b50, 0x0b52, 0x0b54, 0x0b56, 0x0b58, 0x0b5a, 0x0b5c,
+ // Entry 280 - 2BF
+ 0x0b5e, 0x0b62, 0x0b66, 0x0b6a, 0x0b6e, 0x0b72, 0x0b76, 0x0b7a,
+ 0x0b7c, 0x0b7e, 0x0b80, 0x0b82, 0x0b86, 0x0b8a, 0x0b8e, 0x0b92,
+ 0x0b96, 0x0b9a, 0x0b9e, 0x0ba0, 0x0ba2, 0x0ba4, 0x0ba6, 0x0ba8,
+ 0x0baa, 0x0bac, 0x0bb0, 0x0bb4, 0x0bba, 0x0bc0, 0x0bc4, 0x0bc8,
+ 0x0bcc, 0x0bd0, 0x0bd4, 0x0bd8, 0x0bdc, 0x0be0, 0x0be4, 0x0be8,
+ 0x0bec, 0x0bf0, 0x0bf4, 0x0bf8, 0x0bfc, 0x0c00, 0x0c04, 0x0c08,
+ 0x0c0c, 0x0c10, 0x0c14, 0x0c18, 0x0c1c, 0x0c20, 0x0c24, 0x0c28,
+ 0x0c2c, 0x0c30, 0x0c34, 0x0c36, 0x0c38, 0x0c3a, 0x0c3c, 0x0c3e,
+ // Entry 2C0 - 2FF
+ 0x0c40, 0x0c42, 0x0c44, 0x0c46, 0x0c48, 0x0c4a, 0x0c4c, 0x0c4e,
+ 0x0c50, 0x0c52, 0x0c54, 0x0c56, 0x0c58, 0x0c5a, 0x0c5c, 0x0c5e,
+ 0x0c60, 0x0c62, 0x0c64, 0x0c66, 0x0c68, 0x0c6a, 0x0c6c, 0x0c6e,
+ 0x0c70, 0x0c72, 0x0c74, 0x0c76, 0x0c78, 0x0c7a, 0x0c7c, 0x0c7e,
+ 0x0c80, 0x0c82, 0x0c86, 0x0c8a, 0x0c8e, 0x0c92, 0x0c96, 0x0c9a,
+ 0x0c9e, 0x0ca2, 0x0ca4, 0x0ca8, 0x0cac, 0x0cb0, 0x0cb4, 0x0cb8,
+ 0x0cbc, 0x0cc0, 0x0cc4, 0x0cc8, 0x0ccc, 0x0cd0, 0x0cd4, 0x0cd8,
+ 0x0cdc, 0x0ce0, 0x0ce4, 0x0ce8, 0x0cec, 0x0cf0, 0x0cf4, 0x0cf8,
+ // Entry 300 - 33F
+ 0x0cfc, 0x0d00, 0x0d04, 0x0d08, 0x0d0c, 0x0d10, 0x0d14, 0x0d18,
+ 0x0d1c, 0x0d20, 0x0d24, 0x0d28, 0x0d2c, 0x0d30, 0x0d34, 0x0d38,
+ 0x0d3c, 0x0d40, 0x0d44, 0x0d48, 0x0d4c, 0x0d50, 0x0d54, 0x0d58,
+ 0x0d5c, 0x0d60, 0x0d64, 0x0d68, 0x0d6c, 0x0d70, 0x0d74, 0x0d78,
+ 0x0d7c, 0x0d80, 0x0d84, 0x0d88, 0x0d8c, 0x0d90, 0x0d94, 0x0d98,
+ 0x0d9c, 0x0da0, 0x0da4, 0x0da8, 0x0dac, 0x0db0, 0x0db4, 0x0db8,
+ 0x0dbc, 0x0dc0, 0x0dc4, 0x0dc8, 0x0dcc, 0x0dd0, 0x0dd4, 0x0dd8,
+ 0x0ddc, 0x0de0, 0x0de4, 0x0de8, 0x0dec, 0x0df0, 0x0df4, 0x0df8,
+ // Entry 340 - 37F
+ 0x0dfc, 0x0e00, 0x0e04, 0x0e08, 0x0e0c, 0x0e10, 0x0e14, 0x0e18,
+ 0x0e1d, 0x0e22, 0x0e27, 0x0e2c, 0x0e31, 0x0e36, 0x0e3a, 0x0e3e,
+ 0x0e42, 0x0e46, 0x0e4a, 0x0e4e, 0x0e52, 0x0e56, 0x0e5a, 0x0e5e,
+ 0x0e62, 0x0e66, 0x0e6a, 0x0e6e, 0x0e72, 0x0e76, 0x0e7a, 0x0e7e,
+ 0x0e82, 0x0e86, 0x0e8a, 0x0e8e, 0x0e92, 0x0e96, 0x0e9a, 0x0e9e,
+ 0x0ea2, 0x0ea6, 0x0eaa, 0x0eae, 0x0eb2, 0x0eb6, 0x0ebc, 0x0ec2,
+ 0x0ec8, 0x0ecc, 0x0ed0, 0x0ed4, 0x0ed8, 0x0edc, 0x0ee0, 0x0ee4,
+ 0x0ee8, 0x0eec, 0x0ef0, 0x0ef4, 0x0ef8, 0x0efc, 0x0f00, 0x0f04,
+ // Entry 380 - 3BF
+ 0x0f08, 0x0f0c, 0x0f10, 0x0f14, 0x0f18, 0x0f1c, 0x0f20, 0x0f24,
+ 0x0f28, 0x0f2c, 0x0f30, 0x0f34, 0x0f38, 0x0f3e, 0x0f44, 0x0f4a,
+ 0x0f50, 0x0f56, 0x0f5c, 0x0f62, 0x0f68, 0x0f6e, 0x0f74, 0x0f7a,
+ 0x0f80, 0x0f86, 0x0f8c, 0x0f92, 0x0f98, 0x0f9e, 0x0fa4, 0x0faa,
+ 0x0fb0, 0x0fb6, 0x0fbc, 0x0fc2, 0x0fc8, 0x0fce, 0x0fd4, 0x0fda,
+ 0x0fe0, 0x0fe6, 0x0fec, 0x0ff2, 0x0ff8, 0x0ffe, 0x1004, 0x100a,
+ 0x1010, 0x1016, 0x101c, 0x1022, 0x1028, 0x102e, 0x1034, 0x103a,
+ 0x1040, 0x1046, 0x104c, 0x1052, 0x1058, 0x105e, 0x1064, 0x106a,
+ // Entry 3C0 - 3FF
+ 0x1070, 0x1076, 0x107c, 0x1082, 0x1088, 0x108e, 0x1094, 0x109a,
+ 0x10a0, 0x10a6, 0x10ac, 0x10b2, 0x10b8, 0x10be, 0x10c4, 0x10ca,
+ 0x10d0, 0x10d6, 0x10dc, 0x10e2, 0x10e8, 0x10ee, 0x10f4, 0x10fa,
+ 0x1100, 0x1106, 0x110c, 0x1112, 0x1118, 0x111e, 0x1124, 0x112a,
+ 0x1130, 0x1136, 0x113c, 0x1142, 0x1148, 0x114e, 0x1154, 0x115a,
+ 0x1160, 0x1166, 0x116c, 0x1172, 0x1178, 0x1180, 0x1188, 0x1190,
+ 0x1198, 0x11a0, 0x11a8, 0x11b0, 0x11b6, 0x11d7, 0x11e6, 0x11ee,
+ 0x11ef, 0x11f0, 0x11f1, 0x11f2, 0x11f3, 0x11f4, 0x11f5, 0x11f6,
+ // Entry 400 - 43F
+ 0x11f7, 0x11f8, 0x11f9, 0x11fa, 0x11fb, 0x11fc, 0x11fd, 0x11fe,
+ 0x11ff, 0x1200, 0x1201, 0x1205, 0x1209, 0x120d, 0x1211, 0x1215,
+ 0x1219, 0x121b, 0x121d, 0x121f, 0x1221, 0x1223, 0x1225, 0x1227,
+ 0x1229, 0x122b, 0x122d, 0x122f, 0x1231, 0x1233, 0x1235, 0x1237,
+ 0x1239, 0x123b, 0x123d, 0x123f, 0x1241, 0x1243, 0x1245, 0x1247,
+ 0x1249, 0x124b, 0x124d, 0x124f, 0x1251, 0x1253, 0x1255, 0x1257,
+ 0x1259, 0x125b, 0x125d, 0x125f, 0x1263, 0x1267, 0x126b, 0x126f,
+ 0x1270, 0x1271, 0x1272, 0x1273, 0x1274, 0x1275, 0x1277, 0x1279,
+ // Entry 440 - 47F
+ 0x127b, 0x127d, 0x127f, 0x1287, 0x128f, 0x129b, 0x12a7, 0x12b3,
+ 0x12bf, 0x12cb, 0x12d3, 0x12db, 0x12e7, 0x12f3, 0x12ff, 0x130b,
+ 0x130d, 0x130f, 0x1311, 0x1313, 0x1315, 0x1317, 0x1319, 0x131b,
+ 0x131d, 0x131f, 0x1321, 0x1323, 0x1325, 0x1327, 0x1329, 0x132b,
+ 0x132e, 0x1331, 0x1333, 0x1335, 0x1337, 0x1339, 0x133b, 0x133d,
+ 0x133f, 0x1341, 0x1343, 0x1345, 0x1347, 0x1349, 0x134b, 0x134d,
+ 0x1350, 0x1353, 0x1356, 0x1359, 0x135c, 0x135f, 0x1362, 0x1365,
+ 0x1368, 0x136b, 0x136e, 0x1371, 0x1374, 0x1377, 0x137a, 0x137d,
+ // Entry 480 - 4BF
+ 0x1380, 0x1383, 0x1386, 0x1389, 0x138c, 0x138f, 0x1392, 0x1395,
+ 0x1398, 0x139b, 0x13a2, 0x13a4, 0x13a6, 0x13a8, 0x13ab, 0x13ad,
+ 0x13af, 0x13b1, 0x13b3, 0x13b5, 0x13bb, 0x13c1, 0x13c4, 0x13c7,
+ 0x13ca, 0x13cd, 0x13d0, 0x13d3, 0x13d6, 0x13d9, 0x13dc, 0x13df,
+ 0x13e2, 0x13e5, 0x13e8, 0x13eb, 0x13ee, 0x13f1, 0x13f4, 0x13f7,
+ 0x13fa, 0x13fd, 0x1400, 0x1403, 0x1406, 0x1409, 0x140c, 0x140f,
+ 0x1412, 0x1415, 0x1418, 0x141b, 0x141e, 0x1421, 0x1424, 0x1427,
+ 0x142a, 0x142d, 0x1430, 0x1433, 0x1436, 0x1439, 0x143c, 0x143f,
+ // Entry 4C0 - 4FF
+ 0x1442, 0x1445, 0x1448, 0x1451, 0x145a, 0x1463, 0x146c, 0x1475,
+ 0x147e, 0x1487, 0x1490, 0x1499, 0x149c, 0x149f, 0x14a2, 0x14a5,
+ 0x14a8, 0x14ab, 0x14ae, 0x14b1, 0x14b4, 0x14b7, 0x14ba, 0x14bd,
+ 0x14c0, 0x14c3, 0x14c6, 0x14c9, 0x14cc, 0x14cf, 0x14d2, 0x14d5,
+ 0x14d8, 0x14db, 0x14de, 0x14e1, 0x14e4, 0x14e7, 0x14ea, 0x14ed,
+ 0x14f0, 0x14f3, 0x14f6, 0x14f9, 0x14fc, 0x14ff, 0x1502, 0x1505,
+ 0x1508, 0x150b, 0x150e, 0x1511, 0x1514, 0x1517, 0x151a, 0x151d,
+ 0x1520, 0x1523, 0x1526, 0x1529, 0x152c, 0x152f, 0x1532, 0x1535,
+ // Entry 500 - 53F
+ 0x1538, 0x153b, 0x153e, 0x1541, 0x1544, 0x1547, 0x154a, 0x154d,
+ 0x1550, 0x1553, 0x1556, 0x1559, 0x155c, 0x155f, 0x1562, 0x1565,
+ 0x1568, 0x156b, 0x156e, 0x1571, 0x1574, 0x1577, 0x157a, 0x157d,
+ 0x1580, 0x1583, 0x1586, 0x1589, 0x158c, 0x158f, 0x1592, 0x1595,
+ 0x1598, 0x159b, 0x159e, 0x15a1, 0x15a4, 0x15a7, 0x15aa, 0x15ad,
+ 0x15b0, 0x15b3, 0x15b6, 0x15b9, 0x15bc, 0x15bf, 0x15c2, 0x15c5,
+ 0x15c8, 0x15cb, 0x15ce, 0x15d1, 0x15d4, 0x15d7, 0x15da, 0x15dd,
+ 0x15e0, 0x15e3, 0x15e6, 0x15e9, 0x15ec, 0x15ef, 0x15f2, 0x15f5,
+ // Entry 540 - 57F
+ 0x15f8, 0x15fb, 0x15fe, 0x1601, 0x1604, 0x1607, 0x160a, 0x160d,
+ 0x1610, 0x1613, 0x1616, 0x1619, 0x161c, 0x161f, 0x1622, 0x1625,
+ 0x1628, 0x162b, 0x162e, 0x1631, 0x1634, 0x1637, 0x163a, 0x163d,
+ 0x1640, 0x1643, 0x1646, 0x1649, 0x164c, 0x164f, 0x1652, 0x1655,
+ 0x1658, 0x165b, 0x165e, 0x1661, 0x1664, 0x1667, 0x166a, 0x166d,
+ 0x1670, 0x1673, 0x1676, 0x1679, 0x167c, 0x167f, 0x1682, 0x1685,
+ 0x1688, 0x168b, 0x168e, 0x1691, 0x1694, 0x1697, 0x169a, 0x169d,
+ 0x16a0, 0x16a3, 0x16a6, 0x16a9, 0x16ac, 0x16af, 0x16b2, 0x16b5,
+ // Entry 580 - 5BF
+ 0x16b8, 0x16bb, 0x16be, 0x16c1, 0x16c4, 0x16c7, 0x16ca, 0x16cd,
+ 0x16d0, 0x16d3, 0x16d6, 0x16d9, 0x16dc, 0x16df, 0x16e2, 0x16e5,
+ 0x16e8, 0x16eb, 0x16ee, 0x16f1, 0x16f4, 0x16f7, 0x16fa, 0x16fd,
+ 0x1700, 0x1703, 0x1706, 0x1709, 0x170c, 0x170f, 0x1712, 0x1715,
+ 0x1718, 0x171b, 0x171e, 0x1721, 0x1724, 0x1727, 0x172a, 0x172d,
+ 0x1730, 0x1733, 0x1736, 0x1739, 0x173c, 0x173f, 0x1742, 0x1745,
+ 0x1748, 0x174b, 0x174e, 0x1751, 0x1754, 0x1757, 0x175a, 0x175d,
+ 0x1760, 0x1763, 0x1766, 0x1769, 0x176c, 0x176f, 0x1772, 0x1775,
+ // Entry 5C0 - 5FF
+ 0x1778, 0x177b, 0x177e, 0x1781, 0x1784, 0x1787, 0x178a, 0x178d,
+ 0x1790, 0x1793, 0x1796, 0x1799, 0x179c, 0x179f, 0x17a2, 0x17a5,
+ 0x17a8, 0x17ab, 0x17ae, 0x17b1, 0x17b4, 0x17b7, 0x17ba, 0x17bd,
+ 0x17c0, 0x17c3, 0x17c6, 0x17c9, 0x17cc, 0x17cf, 0x17d2, 0x17d5,
+ 0x17d8, 0x17db, 0x17de, 0x17e1, 0x17e4, 0x17e7, 0x17ea, 0x17ed,
+ 0x17f0, 0x17f3, 0x17f6, 0x17f9, 0x17fc, 0x17ff, 0x1802, 0x1805,
+ 0x1808, 0x180b, 0x180e, 0x1811, 0x1814, 0x1817, 0x181a, 0x181d,
+ 0x1820, 0x1823, 0x1826, 0x1829, 0x182c, 0x182f, 0x1832, 0x1835,
+ // Entry 600 - 63F
+ 0x1838, 0x183b, 0x183e, 0x1841, 0x1844, 0x1847, 0x184a, 0x184d,
+ 0x1850, 0x1853, 0x1856, 0x1859, 0x185c, 0x185f, 0x1862, 0x1865,
+ 0x1868, 0x186b, 0x186e, 0x1871, 0x1874, 0x1877, 0x187a, 0x187d,
+ 0x1880, 0x1883, 0x1886, 0x1889, 0x188c, 0x188f, 0x1892, 0x1895,
+ 0x1898, 0x189b, 0x189e, 0x18a1, 0x18a4, 0x18a7, 0x18aa, 0x18ad,
+ 0x18b0, 0x18b3, 0x18b6, 0x18b9, 0x18bc, 0x18bf, 0x18c2, 0x18c5,
+ 0x18c8, 0x18cb, 0x18ce, 0x18d1, 0x18d4, 0x18d7, 0x18da, 0x18dd,
+ 0x18e0, 0x18e3, 0x18e6, 0x18e9, 0x18ec, 0x18ef, 0x18f2, 0x18f5,
+ // Entry 640 - 67F
+ 0x18f8, 0x18fb, 0x18fe, 0x1901, 0x1904, 0x1907, 0x190a, 0x190d,
+ 0x1910, 0x1913, 0x1916, 0x1919, 0x191c, 0x191f, 0x1922, 0x1925,
+ 0x1928, 0x192b, 0x192e, 0x1931, 0x1934, 0x1937, 0x193a, 0x193d,
+ 0x1940, 0x1943, 0x1946, 0x1949, 0x194c, 0x194f, 0x1952, 0x1955,
+ 0x1958, 0x195b, 0x195e, 0x1961, 0x1964, 0x1967, 0x196a, 0x196d,
+ 0x1970, 0x1973, 0x1976, 0x1979, 0x197c, 0x197f, 0x1982, 0x1985,
+ 0x1988, 0x198b,
+} // Size: 3324 bytes
+
+var xorData string = "" + // Size: 4862 bytes
+ "\x02\x0c\x09\x02\xb0\xec\x02\xad\xd8\x02\xad\xd9\x02\x06\x07\x02\x0f\x12" +
+ "\x02\x0f\x1f\x02\x0f\x1d\x02\x01\x13\x02\x0f\x16\x02\x0f\x0b\x02\x0f3" +
+ "\x02\x0f7\x02\x0f?\x02\x0f/\x02\x0f*\x02\x0c&\x02\x0c*\x02\x0c;\x02\x0c9" +
+ "\x02\x0c%\x02\xab\xed\x02\xab\xe2\x02\xab\xe3\x02\xa9\xe0\x02\xa9\xe1" +
+ "\x02\xa9\xe6\x02\xa3\xcb\x02\xa3\xc8\x02\xa3\xc9\x02\x01#\x02\x01\x08" +
+ "\x02\x0e>\x02\x0e'\x02\x0f\x03\x02\x03\x0d\x02\x03\x09\x02\x03\x17\x02" +
+ "\x03\x0e\x02\x02\x03\x02\x011\x02\x01\x00\x02\x01\x10\x02\x03<\x02\x07" +
+ "\x0d\x02\x02\x0c\x02\x0c0\x02\x01\x03\x02\x01\x01\x02\x01 \x02\x01\x22" +
+ "\x02\x01)\x02\x01\x0a\x02\x01\x0c\x02\x02\x06\x02\x02\x02\x02\x03\x10" +
+ "\x03\x037 \x03\x0b+\x03\x021\x00\x02\x01\x04\x02\x01\x02\x02\x019\x02" +
+ "\x03\x1c\x02\x02$\x03\x80p$\x02\x03:\x02\x03\x0a\x03\xc1r.\x03\xc1r,\x03" +
+ "\xc1r\x02\x02\x02:\x02\x02>\x02\x02,\x02\x02\x10\x02\x02\x00\x03\xc1s<" +
+ "\x03\xc1s*\x03\xc2L$\x03\xc2L;\x02\x09)\x02\x0a\x19\x03\x83\xab\xe3\x03" +
+ "\x83\xab\xf2\x03 4\xe0\x03\x81\xab\xea\x03\x81\xab\xf3\x03 4\xef\x03\x96" +
+ "\xe1\xcd\x03\x84\xe5\xc3\x02\x0d\x11\x03\x8b\xec\xcb\x03\x94\xec\xcf\x03" +
+ "\x9a\xec\xc2\x03\x8b\xec\xdb\x03\x94\xec\xdf\x03\x9a\xec\xd2\x03\x01\x0c" +
+ "!\x03\x01\x0c#\x03ʠ\x9d\x03ʣ\x9c\x03ʢ\x9f\x03ʥ\x9e\x03ʤ\x91\x03ʧ\x90\x03" +
+ "ʦ\x93\x03ʩ\x92\x03ʨ\x95\x03\xca\xf3\xb5\x03\xca\xf0\xb4\x03\xca\xf1\xb7" +
+ "\x03\xca\xf6\xb6\x03\xca\xf7\x89\x03\xca\xf4\x88\x03\xca\xf5\x8b\x03\xca" +
+ "\xfa\x8a\x03\xca\xfb\x8d\x03\xca\xf8\x8c\x03\xca\xf9\x8f\x03\xca\xfe\x8e" +
+ "\x03\xca\xff\x81\x03\xca\xfc\x80\x03\xca\xfd\x83\x03\xca\xe2\x82\x03\xca" +
+ "\xe3\x85\x03\xca\xe0\x84\x03\xca\xe1\x87\x03\xca\xe6\x86\x03\xca\xe7\x99" +
+ "\x03\xca\xe4\x98\x03\xca\xe5\x9b\x03\xca\xea\x9a\x03\xca\xeb\x9d\x03\xca" +
+ "\xe8\x9c\x03ؓ\x89\x03ߔ\x8b\x02\x010\x03\x03\x04\x1e\x03\x04\x15\x12\x03" +
+ "\x0b\x05,\x03\x06\x04\x00\x03\x06\x04)\x03\x06\x044\x03\x06\x04<\x03\x06" +
+ "\x05\x1d\x03\x06\x06\x00\x03\x06\x06\x0a\x03\x06\x06'\x03\x06\x062\x03" +
+ "\x0786\x03\x079/\x03\x079 \x03\x07:\x0e\x03\x07:\x1b\x03\x07:%\x03\x07;/" +
+ "\x03\x07;%\x03\x074\x11\x03\x076\x09\x03\x077*\x03\x070\x01\x03\x070\x0f" +
+ "\x03\x070.\x03\x071\x16\x03\x071\x04\x03\x0710\x03\x072\x18\x03\x072-" +
+ "\x03\x073\x14\x03\x073>\x03\x07'\x09\x03\x07 \x00\x03\x07\x1f\x0b\x03" +
+ "\x07\x18#\x03\x07\x18(\x03\x07\x186\x03\x07\x18\x03\x03\x07\x19\x16\x03" +
+ "\x07\x116\x03\x07\x12'\x03\x07\x13\x10\x03\x07\x0c&\x03\x07\x0c\x08\x03" +
+ "\x07\x0c\x13\x03\x07\x0d\x02\x03\x07\x0d\x1c\x03\x07\x0b5\x03\x07\x0b" +
+ "\x0a\x03\x07\x0b\x01\x03\x07\x0b\x0f\x03\x07\x05\x00\x03\x07\x05\x09\x03" +
+ "\x07\x05\x0b\x03\x07\x07\x01\x03\x07\x07\x08\x03\x07\x00<\x03\x07\x00+" +
+ "\x03\x07\x01)\x03\x07\x01\x1b\x03\x07\x01\x08\x03\x07\x03?\x03\x0445\x03" +
+ "\x044\x08\x03\x0454\x03\x04)/\x03\x04)5\x03\x04+\x05\x03\x04+\x14\x03" +
+ "\x04+ \x03\x04+<\x03\x04*&\x03\x04*\x22\x03\x04&8\x03\x04!\x01\x03\x04!" +
+ "\x22\x03\x04\x11+\x03\x04\x10.\x03\x04\x104\x03\x04\x13=\x03\x04\x12\x04" +
+ "\x03\x04\x12\x0a\x03\x04\x0d\x1d\x03\x04\x0d\x07\x03\x04\x0d \x03\x05<>" +
+ "\x03\x055<\x03\x055!\x03\x055#\x03\x055&\x03\x054\x1d\x03\x054\x02\x03" +
+ "\x054\x07\x03\x0571\x03\x053\x1a\x03\x053\x16\x03\x05.<\x03\x05.\x07\x03" +
+ "\x05):\x03\x05)<\x03\x05)\x0c\x03\x05)\x15\x03\x05+-\x03\x05+5\x03\x05$" +
+ "\x1e\x03\x05$\x14\x03\x05'\x04\x03\x05'\x14\x03\x05&\x02\x03\x05\x226" +
+ "\x03\x05\x22\x0c\x03\x05\x22\x1c\x03\x05\x19\x0a\x03\x05\x1b\x09\x03\x05" +
+ "\x1b\x0c\x03\x05\x14\x07\x03\x05\x16?\x03\x05\x16\x0c\x03\x05\x0c\x05" +
+ "\x03\x05\x0e\x0f\x03\x05\x01\x0e\x03\x05\x00(\x03\x05\x030\x03\x05\x03" +
+ "\x06\x03\x0a==\x03\x0a=1\x03\x0a=,\x03\x0a=\x0c\x03\x0a??\x03\x0a<\x08" +
+ "\x03\x0a9!\x03\x0a9)\x03\x0a97\x03\x0a99\x03\x0a6\x0a\x03\x0a6\x1c\x03" +
+ "\x0a6\x17\x03\x0a7'\x03\x0a78\x03\x0a73\x03\x0a'\x01\x03\x0a'&\x03\x0a" +
+ "\x1f\x0e\x03\x0a\x1f\x03\x03\x0a\x1f3\x03\x0a\x1b/\x03\x0a\x18\x19\x03" +
+ "\x0a\x19\x01\x03\x0a\x16\x14\x03\x0a\x0e\x22\x03\x0a\x0f\x10\x03\x0a\x0f" +
+ "\x02\x03\x0a\x0f \x03\x0a\x0c\x04\x03\x0a\x0b>\x03\x0a\x0b+\x03\x0a\x08/" +
+ "\x03\x0a\x046\x03\x0a\x05\x14\x03\x0a\x00\x04\x03\x0a\x00\x10\x03\x0a" +
+ "\x00\x14\x03\x0b<3\x03\x0b;*\x03\x0b9\x22\x03\x0b9)\x03\x0b97\x03\x0b+" +
+ "\x10\x03\x0b((\x03\x0b&5\x03\x0b$\x1c\x03\x0b$\x12\x03\x0b%\x04\x03\x0b#" +
+ "<\x03\x0b#0\x03\x0b#\x0d\x03\x0b#\x19\x03\x0b!:\x03\x0b!\x1f\x03\x0b!" +
+ "\x00\x03\x0b\x1e5\x03\x0b\x1c\x1d\x03\x0b\x1d-\x03\x0b\x1d(\x03\x0b\x18." +
+ "\x03\x0b\x18 \x03\x0b\x18\x16\x03\x0b\x14\x13\x03\x0b\x15$\x03\x0b\x15" +
+ "\x22\x03\x0b\x12\x1b\x03\x0b\x12\x10\x03\x0b\x132\x03\x0b\x13=\x03\x0b" +
+ "\x12\x18\x03\x0b\x0c&\x03\x0b\x061\x03\x0b\x06:\x03\x0b\x05#\x03\x0b\x05" +
+ "<\x03\x0b\x04\x0b\x03\x0b\x04\x04\x03\x0b\x04\x1b\x03\x0b\x042\x03\x0b" +
+ "\x041\x03\x0b\x03\x03\x03\x0b\x03\x1d\x03\x0b\x03/\x03\x0b\x03+\x03\x0b" +
+ "\x02\x1b\x03\x0b\x02\x00\x03\x0b\x01\x1e\x03\x0b\x01\x08\x03\x0b\x015" +
+ "\x03\x06\x0d9\x03\x06\x0d=\x03\x06\x0d?\x03\x02\x001\x03\x02\x003\x03" +
+ "\x02\x02\x19\x03\x02\x006\x03\x02\x02\x1b\x03\x02\x004\x03\x02\x00<\x03" +
+ "\x02\x02\x0a\x03\x02\x02\x0e\x03\x02\x01\x1a\x03\x02\x01\x07\x03\x02\x01" +
+ "\x05\x03\x02\x01\x0b\x03\x02\x01%\x03\x02\x01\x0c\x03\x02\x01\x04\x03" +
+ "\x02\x01\x1c\x03\x02\x00.\x03\x02\x002\x03\x02\x00>\x03\x02\x00\x12\x03" +
+ "\x02\x00\x16\x03\x02\x011\x03\x02\x013\x03\x02\x02 \x03\x02\x02%\x03\x02" +
+ "\x02$\x03\x02\x028\x03\x02\x02;\x03\x02\x024\x03\x02\x012\x03\x02\x022" +
+ "\x03\x02\x02/\x03\x02\x01,\x03\x02\x01\x13\x03\x02\x01\x16\x03\x02\x01" +
+ "\x11\x03\x02\x01\x1e\x03\x02\x01\x15\x03\x02\x01\x17\x03\x02\x01\x0f\x03" +
+ "\x02\x01\x08\x03\x02\x00?\x03\x02\x03\x07\x03\x02\x03\x0d\x03\x02\x03" +
+ "\x13\x03\x02\x03\x1d\x03\x02\x03\x1f\x03\x02\x00\x03\x03\x02\x00\x0d\x03" +
+ "\x02\x00\x01\x03\x02\x00\x1b\x03\x02\x00\x19\x03\x02\x00\x18\x03\x02\x00" +
+ "\x13\x03\x02\x00/\x03\x07>\x12\x03\x07<\x1f\x03\x07>\x1d\x03\x06\x1d\x0e" +
+ "\x03\x07>\x1c\x03\x07>:\x03\x07>\x13\x03\x04\x12+\x03\x07?\x03\x03\x07>" +
+ "\x02\x03\x06\x224\x03\x06\x1a.\x03\x07<%\x03\x06\x1c\x0b\x03\x0609\x03" +
+ "\x05\x1f\x01\x03\x04'\x08\x03\x93\xfd\xf5\x03\x02\x0d \x03\x02\x0d#\x03" +
+ "\x02\x0d!\x03\x02\x0d&\x03\x02\x0d\x22\x03\x02\x0d/\x03\x02\x0d,\x03\x02" +
+ "\x0d$\x03\x02\x0d'\x03\x02\x0d%\x03\x02\x0d;\x03\x02\x0d=\x03\x02\x0d?" +
+ "\x03\x099.\x03\x08\x0b7\x03\x08\x02\x14\x03\x08\x14\x0d\x03\x08.:\x03" +
+ "\x089'\x03\x0f\x0b\x18\x03\x0f\x1c1\x03\x0f\x17&\x03\x0f9\x1f\x03\x0f0" +
+ "\x0c\x03\x0e\x0a9\x03\x0e\x056\x03\x0e\x1c#\x03\x0f\x13\x0e\x03\x072\x00" +
+ "\x03\x070\x0d\x03\x072\x0b\x03\x06\x11\x18\x03\x070\x10\x03\x06\x0f(\x03" +
+ "\x072\x05\x03\x06\x0f,\x03\x073\x15\x03\x06\x07\x08\x03\x05\x16\x02\x03" +
+ "\x04\x0b \x03\x05:8\x03\x05\x16%\x03\x0a\x0d\x1f\x03\x06\x16\x10\x03\x05" +
+ "\x1d5\x03\x05*;\x03\x05\x16\x1b\x03\x04.-\x03\x06\x1a\x19\x03\x04\x03," +
+ "\x03\x0b87\x03\x04/\x0a\x03\x06\x00,\x03\x04-\x01\x03\x04\x1e-\x03\x06/(" +
+ "\x03\x0a\x0b5\x03\x06\x0e7\x03\x06\x07.\x03\x0597\x03\x0a*%\x03\x0760" +
+ "\x03\x06\x0c;\x03\x05'\x00\x03\x072.\x03\x072\x08\x03\x06=\x01\x03\x06" +
+ "\x05\x1b\x03\x06\x06\x12\x03\x06$=\x03\x06'\x0d\x03\x04\x11\x0f\x03\x076" +
+ ",\x03\x06\x07;\x03\x06.,\x03\x86\xf9\xea\x03\x8f\xff\xeb\x02\x092\x02" +
+ "\x095\x02\x094\x02\x09;\x02\x09>\x02\x098\x02\x09*\x02\x09/\x02\x09,\x02" +
+ "\x09%\x02\x09&\x02\x09#\x02\x09 \x02\x08!\x02\x08%\x02\x08$\x02\x08+\x02" +
+ "\x08.\x02\x08*\x02\x08&\x02\x088\x02\x08>\x02\x084\x02\x086\x02\x080\x02" +
+ "\x08\x10\x02\x08\x17\x02\x08\x12\x02\x08\x1d\x02\x08\x1f\x02\x08\x13\x02" +
+ "\x08\x15\x02\x08\x14\x02\x08\x0c\x03\x8b\xfd\xd0\x03\x81\xec\xc6\x03\x87" +
+ "\xe0\x8a\x03-2\xe3\x03\x80\xef\xe4\x03-2\xea\x03\x88\xe6\xeb\x03\x8e\xe6" +
+ "\xe8\x03\x84\xe6\xe9\x03\x97\xe6\xee\x03-2\xf9\x03-2\xf6\x03\x8e\xe3\xad" +
+ "\x03\x80\xe3\x92\x03\x88\xe3\x90\x03\x8e\xe3\x90\x03\x80\xe3\x97\x03\x88" +
+ "\xe3\x95\x03\x88\xfe\xcb\x03\x8e\xfe\xca\x03\x84\xfe\xcd\x03\x91\xef\xc9" +
+ "\x03-2\xc1\x03-2\xc0\x03-2\xcb\x03\x88@\x09\x03\x8e@\x08\x03\x8f\xe0\xf5" +
+ "\x03\x8e\xe6\xf9\x03\x8e\xe0\xfa\x03\x93\xff\xf4\x03\x84\xee\xd3\x03\x0b" +
+ "(\x04\x023 \x03\x0b)\x08\x021;\x02\x01*\x03\x0b#\x10\x03\x0b 0\x03\x0b!" +
+ "\x10\x03\x0b!0\x03\x07\x15\x08\x03\x09?5\x03\x07\x1f\x08\x03\x07\x17\x0b" +
+ "\x03\x09\x1f\x15\x03\x0b\x1c7\x03\x0a+#\x03\x06\x1a\x1b\x03\x06\x1a\x14" +
+ "\x03\x0a\x01\x18\x03\x06#\x1b\x03\x0a2\x0c\x03\x0a\x01\x04\x03\x09#;\x03" +
+ "\x08='\x03\x08\x1a\x0a\x03\x07</\x03\x07:+\x03\x07\x07*\x03\x06&\x1c\x03" +
+ "\x09\x0c\x16\x03\x09\x10\x0e\x03\x08'\x0f\x03\x08+\x09\x03\x074%\x03\x06" +
+ "!3\x03\x06\x03+\x03\x0b\x1e\x19\x03\x0a))\x03\x09\x08\x19\x03\x08,\x05" +
+ "\x03\x07<2\x03\x06\x1c>\x03\x0a\x111\x03\x09\x1b\x09\x03\x073.\x03\x07" +
+ "\x01\x00\x03\x09/,\x03\x07#>\x03\x07\x048\x03\x0a\x1f\x22\x03\x098>\x03" +
+ "\x09\x11\x00\x03\x08/\x17\x03\x06'\x22\x03\x0b\x1a+\x03\x0a\x22\x19\x03" +
+ "\x0a/1\x03\x0974\x03\x09\x0f\x22\x03\x08,\x22\x03\x08?\x14\x03\x07$5\x03" +
+ "\x07<3\x03\x07=*\x03\x07\x13\x18\x03\x068\x0a\x03\x06\x09\x16\x03\x06" +
+ "\x13\x00\x03\x08\x067\x03\x08\x01\x03\x03\x08\x12\x1d\x03\x07+7\x03\x06(" +
+ ";\x03\x06\x1c?\x03\x07\x0e\x17\x03\x0a\x06\x1d\x03\x0a\x19\x07\x03\x08" +
+ "\x14$\x03\x07$;\x03\x08,$\x03\x08\x06\x0d\x03\x07\x16\x0a\x03\x06>>\x03" +
+ "\x0a\x06\x12\x03\x0a\x14)\x03\x09\x0d\x1f\x03\x09\x12\x17\x03\x09\x19" +
+ "\x01\x03\x08\x11 \x03\x08\x1d'\x03\x06<\x1a\x03\x0a.\x00\x03\x07'\x18" +
+ "\x03\x0a\x22\x08\x03\x08\x0d\x0a\x03\x08\x13)\x03\x07*)\x03\x06<,\x03" +
+ "\x07\x0b\x1a\x03\x09.\x14\x03\x09\x0d\x1e\x03\x07\x0e#\x03\x0b\x1d'\x03" +
+ "\x0a\x0a8\x03\x09%2\x03\x08+&\x03\x080\x12\x03\x0a)4\x03\x08\x06\x1f\x03" +
+ "\x0b\x1b\x1a\x03\x0a\x1b\x0f\x03\x0b\x1d*\x03\x09\x16$\x03\x090\x11\x03" +
+ "\x08\x11\x08\x03\x0a*(\x03\x0a\x042\x03\x089,\x03\x074'\x03\x07\x0f\x05" +
+ "\x03\x09\x0b\x0a\x03\x07\x1b\x01\x03\x09\x17:\x03\x09.\x0d\x03\x07.\x11" +
+ "\x03\x09+\x15\x03\x080\x13\x03\x0b\x1f\x19\x03\x0a \x11\x03\x0a\x220\x03" +
+ "\x09\x07;\x03\x08\x16\x1c\x03\x07,\x13\x03\x07\x0e/\x03\x06\x221\x03\x0a" +
+ ".\x0a\x03\x0a7\x02\x03\x0a\x032\x03\x0a\x1d.\x03\x091\x06\x03\x09\x19:" +
+ "\x03\x08\x02/\x03\x060+\x03\x06\x0f-\x03\x06\x1c\x1f\x03\x06\x1d\x07\x03" +
+ "\x0a,\x11\x03\x09=\x0d\x03\x09\x0b;\x03\x07\x1b/\x03\x0a\x1f:\x03\x09 " +
+ "\x1f\x03\x09.\x10\x03\x094\x0b\x03\x09\x1a1\x03\x08#\x1a\x03\x084\x1d" +
+ "\x03\x08\x01\x1f\x03\x08\x11\x22\x03\x07'8\x03\x07\x1a>\x03\x0757\x03" +
+ "\x06&9\x03\x06+\x11\x03\x0a.\x0b\x03\x0a,>\x03\x0a4#\x03\x08%\x17\x03" +
+ "\x07\x05\x22\x03\x07\x0c\x0b\x03\x0a\x1d+\x03\x0a\x19\x16\x03\x09+\x1f" +
+ "\x03\x09\x08\x0b\x03\x08\x16\x18\x03\x08+\x12\x03\x0b\x1d\x0c\x03\x0a=" +
+ "\x10\x03\x0a\x09\x0d\x03\x0a\x10\x11\x03\x09&0\x03\x08(\x1f\x03\x087\x07" +
+ "\x03\x08\x185\x03\x07'6\x03\x06.\x05\x03\x06=\x04\x03\x06;;\x03\x06\x06," +
+ "\x03\x0b\x18>\x03\x08\x00\x18\x03\x06 \x03\x03\x06<\x00\x03\x09%\x18\x03" +
+ "\x0b\x1c<\x03\x0a%!\x03\x0a\x09\x12\x03\x0a\x16\x02\x03\x090'\x03\x09" +
+ "\x0e=\x03\x08 \x0e\x03\x08>\x03\x03\x074>\x03\x06&?\x03\x06\x19\x09\x03" +
+ "\x06?(\x03\x0a-\x0e\x03\x09:3\x03\x098:\x03\x09\x12\x0b\x03\x09\x1d\x17" +
+ "\x03\x087\x05\x03\x082\x14\x03\x08\x06%\x03\x08\x13\x1f\x03\x06\x06\x0e" +
+ "\x03\x0a\x22<\x03\x09/<\x03\x06>+\x03\x0a'?\x03\x0a\x13\x0c\x03\x09\x10<" +
+ "\x03\x07\x1b=\x03\x0a\x19\x13\x03\x09\x22\x1d\x03\x09\x07\x0d\x03\x08)" +
+ "\x1c\x03\x06=\x1a\x03\x0a/4\x03\x0a7\x11\x03\x0a\x16:\x03\x09?3\x03\x09:" +
+ "/\x03\x09\x05\x0a\x03\x09\x14\x06\x03\x087\x22\x03\x080\x07\x03\x08\x1a" +
+ "\x1f\x03\x07\x04(\x03\x07\x04\x09\x03\x06 %\x03\x06<\x08\x03\x0a+\x14" +
+ "\x03\x09\x1d\x16\x03\x0a70\x03\x08 >\x03\x0857\x03\x070\x0a\x03\x06=\x12" +
+ "\x03\x06\x16%\x03\x06\x1d,\x03\x099#\x03\x09\x10>\x03\x07 \x1e\x03\x08" +
+ "\x0c<\x03\x08\x0b\x18\x03\x08\x15+\x03\x08,:\x03\x08%\x22\x03\x07\x0a$" +
+ "\x03\x0b\x1c=\x03\x07+\x08\x03\x0a/\x05\x03\x0a \x07\x03\x0a\x12'\x03" +
+ "\x09#\x11\x03\x08\x1b\x15\x03\x0a\x06\x01\x03\x09\x1c\x1b\x03\x0922\x03" +
+ "\x07\x14<\x03\x07\x09\x04\x03\x061\x04\x03\x07\x0e\x01\x03\x0a\x13\x18" +
+ "\x03\x0a-\x0c\x03\x0a?\x0d\x03\x0a\x09\x0a\x03\x091&\x03\x0a/\x0b\x03" +
+ "\x08$<\x03\x083\x1d\x03\x08\x0c$\x03\x08\x0d\x07\x03\x08\x0d?\x03\x08" +
+ "\x0e\x14\x03\x065\x0a\x03\x08\x1a#\x03\x08\x16#\x03\x0702\x03\x07\x03" +
+ "\x1a\x03\x06(\x1d\x03\x06+\x1b\x03\x06\x0b\x05\x03\x06\x0b\x17\x03\x06" +
+ "\x0c\x04\x03\x06\x1e\x19\x03\x06+0\x03\x062\x18\x03\x0b\x16\x1e\x03\x0a+" +
+ "\x16\x03\x0a-?\x03\x0a#:\x03\x0a#\x10\x03\x0a%$\x03\x0a>+\x03\x0a01\x03" +
+ "\x0a1\x10\x03\x0a\x099\x03\x0a\x0a\x12\x03\x0a\x19\x1f\x03\x0a\x19\x12" +
+ "\x03\x09*)\x03\x09-\x16\x03\x09.1\x03\x09.2\x03\x09<\x0e\x03\x09> \x03" +
+ "\x093\x12\x03\x09\x0b\x01\x03\x09\x1c2\x03\x09\x11\x1c\x03\x09\x15%\x03" +
+ "\x08,&\x03\x08!\x22\x03\x089(\x03\x08\x0b\x1a\x03\x08\x0d2\x03\x08\x0c" +
+ "\x04\x03\x08\x0c\x06\x03\x08\x0c\x1f\x03\x08\x0c\x0c\x03\x08\x0f\x1f\x03" +
+ "\x08\x0f\x1d\x03\x08\x00\x14\x03\x08\x03\x14\x03\x08\x06\x16\x03\x08\x1e" +
+ "#\x03\x08\x11\x11\x03\x08\x10\x18\x03\x08\x14(\x03\x07)\x1e\x03\x07.1" +
+ "\x03\x07 $\x03\x07 '\x03\x078\x08\x03\x07\x0d0\x03\x07\x0f7\x03\x07\x05#" +
+ "\x03\x07\x05\x1a\x03\x07\x1a7\x03\x07\x1d-\x03\x07\x17\x10\x03\x06)\x1f" +
+ "\x03\x062\x0b\x03\x066\x16\x03\x06\x09\x11\x03\x09(\x1e\x03\x07!5\x03" +
+ "\x0b\x11\x16\x03\x0a/\x04\x03\x0a,\x1a\x03\x0b\x173\x03\x0a,1\x03\x0a/5" +
+ "\x03\x0a\x221\x03\x0a\x22\x0d\x03\x0a?%\x03\x0a<,\x03\x0a?#\x03\x0a>\x19" +
+ "\x03\x0a\x08&\x03\x0a\x0b\x0e\x03\x0a\x0c:\x03\x0a\x0c+\x03\x0a\x03\x22" +
+ "\x03\x0a\x06)\x03\x0a\x11\x10\x03\x0a\x11\x1a\x03\x0a\x17-\x03\x0a\x14(" +
+ "\x03\x09)\x1e\x03\x09/\x09\x03\x09.\x00\x03\x09,\x07\x03\x09/*\x03\x09-9" +
+ "\x03\x09\x228\x03\x09%\x09\x03\x09:\x12\x03\x09;\x1d\x03\x09?\x06\x03" +
+ "\x093%\x03\x096\x05\x03\x096\x08\x03\x097\x02\x03\x09\x07,\x03\x09\x04," +
+ "\x03\x09\x1f\x16\x03\x09\x11\x03\x03\x09\x11\x12\x03\x09\x168\x03\x08*" +
+ "\x05\x03\x08/2\x03\x084:\x03\x08\x22+\x03\x08 0\x03\x08&\x0a\x03\x08;" +
+ "\x10\x03\x08>$\x03\x08>\x18\x03\x0829\x03\x082:\x03\x081,\x03\x081<\x03" +
+ "\x081\x1c\x03\x087#\x03\x087*\x03\x08\x09'\x03\x08\x00\x1d\x03\x08\x05-" +
+ "\x03\x08\x1f4\x03\x08\x1d\x04\x03\x08\x16\x0f\x03\x07*7\x03\x07'!\x03" +
+ "\x07%\x1b\x03\x077\x0c\x03\x07\x0c1\x03\x07\x0c.\x03\x07\x00\x06\x03\x07" +
+ "\x01\x02\x03\x07\x010\x03\x07\x06=\x03\x07\x01\x03\x03\x07\x01\x13\x03" +
+ "\x07\x06\x06\x03\x07\x05\x0a\x03\x07\x1f\x09\x03\x07\x17:\x03\x06*1\x03" +
+ "\x06-\x1d\x03\x06\x223\x03\x062:\x03\x060$\x03\x066\x1e\x03\x064\x12\x03" +
+ "\x0645\x03\x06\x0b\x00\x03\x06\x0b7\x03\x06\x07\x1f\x03\x06\x15\x12\x03" +
+ "\x0c\x05\x0f\x03\x0b+\x0b\x03\x0b+-\x03\x06\x16\x1b\x03\x06\x15\x17\x03" +
+ "\x89\xca\xea\x03\x89\xca\xe8\x03\x0c8\x10\x03\x0c8\x01\x03\x0c8\x0f\x03" +
+ "\x0d8%\x03\x0d8!\x03\x0c8-\x03\x0c8/\x03\x0c8+\x03\x0c87\x03\x0c85\x03" +
+ "\x0c9\x09\x03\x0c9\x0d\x03\x0c9\x0f\x03\x0c9\x0b\x03\xcfu\x0c\x03\xcfu" +
+ "\x0f\x03\xcfu\x0e\x03\xcfu\x09\x03\x0c9\x10\x03\x0d9\x0c\x03\xcf`;\x03" +
+ "\xcf`>\x03\xcf`9\x03\xcf`8\x03\xcf`7\x03\xcf`*\x03\xcf`-\x03\xcf`,\x03" +
+ "\x0d\x1b\x1a\x03\x0d\x1b&\x03\x0c=.\x03\x0c=%\x03\x0c>\x1e\x03\x0c>\x14" +
+ "\x03\x0c?\x06\x03\x0c?\x0b\x03\x0c?\x0c\x03\x0c?\x0d\x03\x0c?\x02\x03" +
+ "\x0c>\x0f\x03\x0c>\x08\x03\x0c>\x09\x03\x0c>,\x03\x0c>\x0c\x03\x0c?\x13" +
+ "\x03\x0c?\x16\x03\x0c?\x15\x03\x0c?\x1c\x03\x0c?\x1f\x03\x0c?\x1d\x03" +
+ "\x0c?\x1a\x03\x0c?\x17\x03\x0c?\x08\x03\x0c?\x09\x03\x0c?\x0e\x03\x0c?" +
+ "\x04\x03\x0c?\x05\x03\x0c<?\x03\x0c=\x00\x03\x0c=\x06\x03\x0c=\x05\x03" +
+ "\x0c=\x0c\x03\x0c=\x0f\x03\x0c=\x0d\x03\x0c=\x0b\x03\x0c=\x07\x03\x0c=" +
+ "\x19\x03\x0c=\x15\x03\x0c=\x11\x03\x0c=1\x03\x0c=3\x03\x0c=0\x03\x0c=>" +
+ "\x03\x0c=2\x03\x0c=6\x03\x0c<\x07\x03\x0c<\x05\x03\x0e:!\x03\x0e:#\x03" +
+ "\x0e8\x09\x03\x0e:&\x03\x0e8\x0b\x03\x0e:$\x03\x0e:,\x03\x0e8\x1a\x03" +
+ "\x0e8\x1e\x03\x0e:*\x03\x0e:7\x03\x0e:5\x03\x0e:;\x03\x0e:\x15\x03\x0e:<" +
+ "\x03\x0e:4\x03\x0e:'\x03\x0e:-\x03\x0e:%\x03\x0e:?\x03\x0e:=\x03\x0e:)" +
+ "\x03\x0e:/\x03\xcfs'\x03\x0d=\x0f\x03\x0d+*\x03\x0d99\x03\x0d9;\x03\x0d9" +
+ "?\x03\x0d)\x0d\x03\x0d(%\x02\x01\x18\x02\x01(\x02\x01\x1e\x03\x0f$!\x03" +
+ "\x0f87\x03\x0f4\x0e\x03\x0f5\x1d\x03\x06'\x03\x03\x0f\x08\x18\x03\x0f" +
+ "\x0d\x1b\x03\x0e2=\x03\x0e;\x08\x03\x0e:\x0b\x03\x0e\x06$\x03\x0e\x0d)" +
+ "\x03\x0e\x16\x1f\x03\x0e\x16\x1b\x03\x0d$\x0a\x03\x05,\x1d\x03\x0d. \x03" +
+ "\x0d.#\x03\x0c(/\x03\x09%\x02\x03\x0d90\x03\x0d\x0e4\x03\x0d\x0d\x0f\x03" +
+ "\x0c#\x00\x03\x0c,\x1e\x03\x0c2\x0e\x03\x0c\x01\x17\x03\x0c\x09:\x03\x0e" +
+ "\x173\x03\x0c\x08\x03\x03\x0c\x11\x07\x03\x0c\x10\x18\x03\x0c\x1f\x1c" +
+ "\x03\x0c\x19\x0e\x03\x0c\x1a\x1f\x03\x0f0>\x03\x0b->\x03\x0b<+\x03\x0b8" +
+ "\x13\x03\x0b\x043\x03\x0b\x14\x03\x03\x0b\x16%\x03\x0d\x22&\x03\x0b\x1a" +
+ "\x1a\x03\x0b\x1a\x04\x03\x0a%9\x03\x0a&2\x03\x0a&0\x03\x0a!\x1a\x03\x0a!" +
+ "7\x03\x0a5\x10\x03\x0a=4\x03\x0a?\x0e\x03\x0a>\x10\x03\x0a\x00 \x03\x0a" +
+ "\x0f:\x03\x0a\x0f9\x03\x0a\x0b\x0a\x03\x0a\x17%\x03\x0a\x1b-\x03\x09-" +
+ "\x1a\x03\x09,4\x03\x09.,\x03\x09)\x09\x03\x096!\x03\x091\x1f\x03\x093" +
+ "\x16\x03\x0c+\x1f\x03\x098 \x03\x098=\x03\x0c(\x1a\x03\x0c(\x16\x03\x09" +
+ "\x0a+\x03\x09\x16\x12\x03\x09\x13\x0e\x03\x09\x153\x03\x08)!\x03\x09\x1a" +
+ "\x01\x03\x09\x18\x01\x03\x08%#\x03\x08>\x22\x03\x08\x05%\x03\x08\x02*" +
+ "\x03\x08\x15;\x03\x08\x1b7\x03\x0f\x07\x1d\x03\x0f\x04\x03\x03\x070\x0c" +
+ "\x03\x07;\x0b\x03\x07\x08\x17\x03\x07\x12\x06\x03\x06/-\x03\x0671\x03" +
+ "\x065+\x03\x06>7\x03\x06\x049\x03\x05+\x1e\x03\x05,\x17\x03\x05 \x1d\x03" +
+ "\x05\x22\x05\x03\x050\x1d"
+
+// lookup returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *idnaTrie) lookup(s []byte) (v uint16, sz int) {
+ c0 := s[0]
+ switch {
+ case c0 < 0x80: // is ASCII
+ return idnaValues[c0], 1
+ case c0 < 0xC2:
+ return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+ case c0 < 0xE0: // 2-byte UTF-8
+ if len(s) < 2 {
+ return 0, 0
+ }
+ i := idnaIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c1), 2
+ case c0 < 0xF0: // 3-byte UTF-8
+ if len(s) < 3 {
+ return 0, 0
+ }
+ i := idnaIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = idnaIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c2), 3
+ case c0 < 0xF8: // 4-byte UTF-8
+ if len(s) < 4 {
+ return 0, 0
+ }
+ i := idnaIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = idnaIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ o = uint32(i)<<6 + uint32(c2)
+ i = idnaIndex[o]
+ c3 := s[3]
+ if c3 < 0x80 || 0xC0 <= c3 {
+ return 0, 3 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c3), 4
+ }
+ // Illegal rune
+ return 0, 1
+}
+
+// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *idnaTrie) lookupUnsafe(s []byte) uint16 {
+ c0 := s[0]
+ if c0 < 0x80 { // is ASCII
+ return idnaValues[c0]
+ }
+ i := idnaIndex[c0]
+ if c0 < 0xE0 { // 2-byte UTF-8
+ return t.lookupValue(uint32(i), s[1])
+ }
+ i = idnaIndex[uint32(i)<<6+uint32(s[1])]
+ if c0 < 0xF0 { // 3-byte UTF-8
+ return t.lookupValue(uint32(i), s[2])
+ }
+ i = idnaIndex[uint32(i)<<6+uint32(s[2])]
+ if c0 < 0xF8 { // 4-byte UTF-8
+ return t.lookupValue(uint32(i), s[3])
+ }
+ return 0
+}
+
+// lookupString returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *idnaTrie) lookupString(s string) (v uint16, sz int) {
+ c0 := s[0]
+ switch {
+ case c0 < 0x80: // is ASCII
+ return idnaValues[c0], 1
+ case c0 < 0xC2:
+ return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+ case c0 < 0xE0: // 2-byte UTF-8
+ if len(s) < 2 {
+ return 0, 0
+ }
+ i := idnaIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c1), 2
+ case c0 < 0xF0: // 3-byte UTF-8
+ if len(s) < 3 {
+ return 0, 0
+ }
+ i := idnaIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = idnaIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c2), 3
+ case c0 < 0xF8: // 4-byte UTF-8
+ if len(s) < 4 {
+ return 0, 0
+ }
+ i := idnaIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = idnaIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ o = uint32(i)<<6 + uint32(c2)
+ i = idnaIndex[o]
+ c3 := s[3]
+ if c3 < 0x80 || 0xC0 <= c3 {
+ return 0, 3 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c3), 4
+ }
+ // Illegal rune
+ return 0, 1
+}
+
+// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *idnaTrie) lookupStringUnsafe(s string) uint16 {
+ c0 := s[0]
+ if c0 < 0x80 { // is ASCII
+ return idnaValues[c0]
+ }
+ i := idnaIndex[c0]
+ if c0 < 0xE0 { // 2-byte UTF-8
+ return t.lookupValue(uint32(i), s[1])
+ }
+ i = idnaIndex[uint32(i)<<6+uint32(s[1])]
+ if c0 < 0xF0 { // 3-byte UTF-8
+ return t.lookupValue(uint32(i), s[2])
+ }
+ i = idnaIndex[uint32(i)<<6+uint32(s[2])]
+ if c0 < 0xF8 { // 4-byte UTF-8
+ return t.lookupValue(uint32(i), s[3])
+ }
+ return 0
+}
+
+// idnaTrie. Total size: 30196 bytes (29.49 KiB). Checksum: e2ae95a945f04016.
+type idnaTrie struct{}
+
+func newIdnaTrie(i int) *idnaTrie {
+ return &idnaTrie{}
+}
+
+// lookupValue determines the type of block n and looks up the value for b.
+func (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {
+ switch {
+ case n < 126:
+ return uint16(idnaValues[n<<6+uint32(b)])
+ default:
+ n -= 126
+ return uint16(idnaSparse.lookup(n, b))
+ }
+}
+
+// idnaValues: 128 blocks, 8192 entries, 16384 bytes
+// The third block is the zero block.
+var idnaValues = [8192]uint16{
+ // Block 0x0, offset 0x0
+ 0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,
+ 0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,
+ 0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080,
+ 0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080,
+ 0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080,
+ 0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080,
+ 0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080,
+ 0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080,
+ 0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008,
+ 0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080,
+ 0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080,
+ // Block 0x1, offset 0x40
+ 0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105,
+ 0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105,
+ 0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105,
+ 0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105,
+ 0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080,
+ 0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008,
+ 0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008,
+ 0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008,
+ 0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008,
+ 0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080,
+ 0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080,
+ // Block 0x2, offset 0x80
+ // Block 0x3, offset 0xc0
+ 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040,
+ 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040,
+ 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040,
+ 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040,
+ 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040,
+ 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018,
+ 0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x0012, 0xe9: 0x0018,
+ 0xea: 0x0019, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x0022,
+ 0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0029, 0xf3: 0x0031, 0xf4: 0x003a, 0xf5: 0x0005,
+ 0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x0042, 0xf9: 0x0049, 0xfa: 0x0051, 0xfb: 0x0018,
+ 0xfc: 0x0059, 0xfd: 0x0061, 0xfe: 0x0069, 0xff: 0x0018,
+ // Block 0x4, offset 0x100
+ 0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008,
+ 0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008,
+ 0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008,
+ 0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008,
+ 0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008,
+ 0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008,
+ 0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008,
+ 0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008,
+ 0x130: 0x0071, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008,
+ 0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d,
+ 0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0079,
+ // Block 0x5, offset 0x140
+ 0x140: 0x0079, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d,
+ 0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x0081, 0x14a: 0xe00d, 0x14b: 0x0008,
+ 0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008,
+ 0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008,
+ 0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008,
+ 0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008,
+ 0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008,
+ 0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008,
+ 0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008,
+ 0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d,
+ 0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x0089,
+ // Block 0x6, offset 0x180
+ 0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008,
+ 0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d,
+ 0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d,
+ 0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d,
+ 0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155,
+ 0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008,
+ 0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d,
+ 0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd,
+ 0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d,
+ 0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008,
+ 0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008,
+ // Block 0x7, offset 0x1c0
+ 0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x0091, 0x1c5: 0x0091,
+ 0x1c6: 0x0091, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d,
+ 0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d,
+ 0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d,
+ 0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008,
+ 0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008,
+ 0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008,
+ 0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008,
+ 0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008,
+ 0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008,
+ 0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008,
+ // Block 0x8, offset 0x200
+ 0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008,
+ 0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008,
+ 0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008,
+ 0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008,
+ 0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008,
+ 0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008,
+ 0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008,
+ 0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008,
+ 0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008,
+ 0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0099, 0x23b: 0xe03d,
+ 0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x00a1, 0x23f: 0x0008,
+ // Block 0x9, offset 0x240
+ 0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018,
+ 0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008,
+ 0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008,
+ 0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018,
+ 0x258: 0x00d2, 0x259: 0x00da, 0x25a: 0x00e2, 0x25b: 0x00ea, 0x25c: 0x00f2, 0x25d: 0x00fa,
+ 0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0101, 0x262: 0x0089, 0x263: 0x0109,
+ 0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018,
+ 0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018,
+ 0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018,
+ 0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,
+ 0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,
+ // Block 0xa, offset 0x280
+ 0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0111, 0x285: 0x040d,
+ 0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308,
+ 0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308,
+ 0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308,
+ 0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308,
+ 0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308,
+ 0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308,
+ 0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308,
+ 0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,
+ 0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x011a, 0x2bb: 0x0008,
+ 0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x0122, 0x2bf: 0x043d,
+ // Block 0xb, offset 0x2c0
+ 0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x003a, 0x2c5: 0x012a,
+ 0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040,
+ 0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105,
+ 0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105,
+ 0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105,
+ 0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d,
+ 0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d,
+ 0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008,
+ 0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008,
+ 0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008,
+ 0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008,
+ // Block 0xc, offset 0x300
+ 0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008,
+ 0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008,
+ 0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd,
+ 0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008,
+ 0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008,
+ 0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008,
+ 0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008,
+ 0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008,
+ 0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd,
+ 0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008,
+ 0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d,
+ // Block 0xd, offset 0x340
+ 0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008,
+ 0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008,
+ 0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008,
+ 0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008,
+ 0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008,
+ 0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008,
+ 0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008,
+ 0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008,
+ 0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008,
+ 0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,
+ 0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,
+ // Block 0xe, offset 0x380
+ 0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308,
+ 0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008,
+ 0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,
+ 0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,
+ 0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,
+ 0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008,
+ 0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008,
+ 0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008,
+ 0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008,
+ 0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008,
+ 0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008,
+ // Block 0xf, offset 0x3c0
+ 0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d,
+ 0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d,
+ 0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008,
+ 0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008,
+ 0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008,
+ 0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008,
+ 0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008,
+ 0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008,
+ 0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008,
+ 0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008,
+ 0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008,
+ // Block 0x10, offset 0x400
+ 0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008,
+ 0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008,
+ 0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008,
+ 0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008,
+ 0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008,
+ 0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008,
+ 0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008,
+ 0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008,
+ 0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5,
+ 0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,
+ 0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,
+ // Block 0x11, offset 0x440
+ 0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840,
+ 0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818,
+ 0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308,
+ 0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308,
+ 0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040,
+ 0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08,
+ 0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08,
+ 0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08,
+ 0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08,
+ 0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08,
+ 0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08,
+ // Block 0x12, offset 0x480
+ 0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08,
+ 0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308,
+ 0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308,
+ 0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308,
+ 0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308,
+ 0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808,
+ 0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808,
+ 0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08,
+ 0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0139,
+ 0x4b6: 0x0141, 0x4b7: 0x0149, 0x4b8: 0x0151, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08,
+ 0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08,
+ // Block 0x13, offset 0x4c0
+ 0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08,
+ 0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08,
+ 0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08,
+ 0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308,
+ 0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840,
+ 0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308,
+ 0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018,
+ 0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08,
+ 0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008,
+ 0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08,
+ 0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08,
+ // Block 0x14, offset 0x500
+ 0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818,
+ 0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818,
+ 0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308,
+ 0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08,
+ 0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08,
+ 0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08,
+ 0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08,
+ 0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08,
+ 0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308,
+ 0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308,
+ 0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308,
+ // Block 0x15, offset 0x540
+ 0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08,
+ 0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08,
+ 0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08,
+ 0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0c08, 0x557: 0x0c08,
+ 0x558: 0x0c08, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040,
+ 0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08,
+ 0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08,
+ 0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040,
+ 0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040,
+ 0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040,
+ 0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040,
+ // Block 0x16, offset 0x580
+ 0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308,
+ 0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008,
+ 0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308,
+ 0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308,
+ 0x598: 0x0159, 0x599: 0x0161, 0x59a: 0x0169, 0x59b: 0x0171, 0x59c: 0x0179, 0x59d: 0x0181,
+ 0x59e: 0x0189, 0x59f: 0x0191, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308,
+ 0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008,
+ 0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008,
+ 0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008,
+ 0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008,
+ 0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008,
+ // Block 0x17, offset 0x5c0
+ 0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008,
+ 0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008,
+ 0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040,
+ 0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008,
+ 0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008,
+ 0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008,
+ 0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040,
+ 0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,
+ 0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040,
+ 0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040,
+ 0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008,
+ // Block 0x18, offset 0x600
+ 0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040,
+ 0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008,
+ 0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040,
+ 0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008,
+ 0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0199, 0x61d: 0x01a1,
+ 0x61e: 0x0040, 0x61f: 0x01a9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308,
+ 0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008,
+ 0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,
+ 0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018,
+ 0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018,
+ 0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x3308, 0x63f: 0x0040,
+ // Block 0x19, offset 0x640
+ 0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008,
+ 0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040,
+ 0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040,
+ 0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008,
+ 0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008,
+ 0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008,
+ 0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040,
+ 0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,
+ 0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x01b1, 0x674: 0x0040, 0x675: 0x0008,
+ 0x676: 0x01b9, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040,
+ 0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008,
+ // Block 0x1a, offset 0x680
+ 0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040,
+ 0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308,
+ 0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308,
+ 0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040,
+ 0x698: 0x0040, 0x699: 0x01c1, 0x69a: 0x01c9, 0x69b: 0x01d1, 0x69c: 0x0008, 0x69d: 0x0040,
+ 0x69e: 0x01d9, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040,
+ 0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008,
+ 0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,
+ 0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308,
+ 0x6b6: 0x0018, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040,
+ 0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040,
+ // Block 0x1b, offset 0x6c0
+ 0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008,
+ 0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008,
+ 0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008,
+ 0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008,
+ 0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008,
+ 0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008,
+ 0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040,
+ 0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,
+ 0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008,
+ 0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040,
+ 0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008,
+ // Block 0x1c, offset 0x700
+ 0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308,
+ 0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008,
+ 0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040,
+ 0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040,
+ 0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040,
+ 0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308,
+ 0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008,
+ 0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,
+ 0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040,
+ 0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308,
+ 0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308,
+ // Block 0x1d, offset 0x740
+ 0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008,
+ 0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008,
+ 0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040,
+ 0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008,
+ 0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008,
+ 0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008,
+ 0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040,
+ 0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008,
+ 0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008,
+ 0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040,
+ 0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308,
+ // Block 0x1e, offset 0x780
+ 0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040,
+ 0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008,
+ 0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040,
+ 0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x3308, 0x796: 0x3308, 0x797: 0x3008,
+ 0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x01e1, 0x79d: 0x01e9,
+ 0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308,
+ 0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008,
+ 0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008,
+ 0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018,
+ 0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040,
+ 0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040,
+ // Block 0x1f, offset 0x7c0
+ 0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008,
+ 0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040,
+ 0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040,
+ 0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040,
+ 0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040,
+ 0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008,
+ 0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008,
+ 0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008,
+ 0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008,
+ 0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040,
+ 0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008,
+ // Block 0x20, offset 0x800
+ 0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040,
+ 0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308,
+ 0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040,
+ 0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040,
+ 0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040,
+ 0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308,
+ 0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008,
+ 0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008,
+ 0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040,
+ 0x836: 0x0040, 0x837: 0x0018, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018,
+ 0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018,
+ // Block 0x21, offset 0x840
+ 0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0018, 0x845: 0x0008,
+ 0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008,
+ 0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040,
+ 0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008,
+ 0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008,
+ 0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008,
+ 0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040,
+ 0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,
+ 0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008,
+ 0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040,
+ 0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308,
+ // Block 0x22, offset 0x880
+ 0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040,
+ 0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008,
+ 0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040,
+ 0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040,
+ 0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040,
+ 0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308,
+ 0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008,
+ 0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,
+ 0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040,
+ 0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040,
+ 0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040,
+ // Block 0x23, offset 0x8c0
+ 0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040,
+ 0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008,
+ 0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040,
+ 0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008,
+ 0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018,
+ 0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308,
+ 0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008,
+ 0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008,
+ 0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018,
+ 0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008,
+ 0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008,
+ // Block 0x24, offset 0x900
+ 0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040,
+ 0x906: 0x0008, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0040,
+ 0x90c: 0x0008, 0x90d: 0x0008, 0x90e: 0x0008, 0x90f: 0x0008, 0x910: 0x0008, 0x911: 0x0008,
+ 0x912: 0x0008, 0x913: 0x0008, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008,
+ 0x918: 0x0008, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008,
+ 0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0008, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008,
+ 0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0008, 0x929: 0x0008,
+ 0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0008, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008,
+ 0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x01f9, 0x934: 0x3308, 0x935: 0x3308,
+ 0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x3b08, 0x93b: 0x3308,
+ 0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040,
+ // Block 0x25, offset 0x940
+ 0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x0211, 0x944: 0x0008, 0x945: 0x0008,
+ 0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,
+ 0x94c: 0x0008, 0x94d: 0x0219, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,
+ 0x952: 0x0221, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0229,
+ 0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0231, 0x95d: 0x0008,
+ 0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008,
+ 0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0239,
+ 0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040,
+ 0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0241, 0x974: 0x3308, 0x975: 0x0249,
+ 0x976: 0x0251, 0x977: 0x0259, 0x978: 0x0261, 0x979: 0x0269, 0x97a: 0x3308, 0x97b: 0x3308,
+ 0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008,
+ // Block 0x26, offset 0x980
+ 0x980: 0x3308, 0x981: 0x0271, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018,
+ 0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008,
+ 0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308,
+ 0x992: 0x3308, 0x993: 0x0279, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308,
+ 0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0281,
+ 0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0289, 0x9a3: 0x3308,
+ 0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0291, 0x9a8: 0x3308, 0x9a9: 0x3308,
+ 0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0299, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308,
+ 0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308,
+ 0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x02a1, 0x9ba: 0x3308, 0x9bb: 0x3308,
+ 0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018,
+ // Block 0x27, offset 0x9c0
+ 0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008,
+ 0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008,
+ 0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008,
+ 0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008,
+ 0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008,
+ 0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008,
+ 0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008,
+ 0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0019, 0x9ed: 0x02e1, 0x9ee: 0x02e9, 0x9ef: 0x0008,
+ 0x9f0: 0x02f1, 0x9f1: 0x02f9, 0x9f2: 0x0301, 0x9f3: 0x0309, 0x9f4: 0x00a9, 0x9f5: 0x0311,
+ 0x9f6: 0x00b1, 0x9f7: 0x0319, 0x9f8: 0x0101, 0x9f9: 0x0321, 0x9fa: 0x0329, 0x9fb: 0x0008,
+ 0x9fc: 0x0051, 0x9fd: 0x0331, 0x9fe: 0x0339, 0x9ff: 0x00b9,
+ // Block 0x28, offset 0xa00
+ 0xa00: 0x0341, 0xa01: 0x0349, 0xa02: 0x00c1, 0xa03: 0x0019, 0xa04: 0x0351, 0xa05: 0x0359,
+ 0xa06: 0x05b5, 0xa07: 0x02e9, 0xa08: 0x02f1, 0xa09: 0x02f9, 0xa0a: 0x0361, 0xa0b: 0x0369,
+ 0xa0c: 0x0371, 0xa0d: 0x0309, 0xa0e: 0x0008, 0xa0f: 0x0319, 0xa10: 0x0321, 0xa11: 0x0379,
+ 0xa12: 0x0051, 0xa13: 0x0381, 0xa14: 0x05cd, 0xa15: 0x05cd, 0xa16: 0x0339, 0xa17: 0x0341,
+ 0xa18: 0x0349, 0xa19: 0x05b5, 0xa1a: 0x0389, 0xa1b: 0x0391, 0xa1c: 0x05e5, 0xa1d: 0x0399,
+ 0xa1e: 0x03a1, 0xa1f: 0x03a9, 0xa20: 0x03b1, 0xa21: 0x03b9, 0xa22: 0x0311, 0xa23: 0x00b9,
+ 0xa24: 0x0349, 0xa25: 0x0391, 0xa26: 0x0399, 0xa27: 0x03a1, 0xa28: 0x03c1, 0xa29: 0x03b1,
+ 0xa2a: 0x03b9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008,
+ 0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008,
+ 0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x03c9, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008,
+ 0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008,
+ // Block 0x29, offset 0xa40
+ 0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008,
+ 0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008,
+ 0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008,
+ 0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008,
+ 0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x03d1, 0xa5c: 0x03d9, 0xa5d: 0x03e1,
+ 0xa5e: 0x03e9, 0xa5f: 0x0371, 0xa60: 0x03f1, 0xa61: 0x03f9, 0xa62: 0x0401, 0xa63: 0x0409,
+ 0xa64: 0x0411, 0xa65: 0x0419, 0xa66: 0x0421, 0xa67: 0x05fd, 0xa68: 0x0429, 0xa69: 0x0431,
+ 0xa6a: 0xe17d, 0xa6b: 0x0439, 0xa6c: 0x0441, 0xa6d: 0x0449, 0xa6e: 0x0451, 0xa6f: 0x0459,
+ 0xa70: 0x0461, 0xa71: 0x0469, 0xa72: 0x0471, 0xa73: 0x0479, 0xa74: 0x0481, 0xa75: 0x0489,
+ 0xa76: 0x0491, 0xa77: 0x0499, 0xa78: 0x0615, 0xa79: 0x04a1, 0xa7a: 0x04a9, 0xa7b: 0x04b1,
+ 0xa7c: 0x04b9, 0xa7d: 0x04c1, 0xa7e: 0x04c9, 0xa7f: 0x04d1,
+ // Block 0x2a, offset 0xa80
+ 0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008,
+ 0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008,
+ 0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008,
+ 0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008,
+ 0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008,
+ 0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008,
+ 0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008,
+ 0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008,
+ 0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008,
+ 0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008,
+ 0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008,
+ // Block 0x2b, offset 0xac0
+ 0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008,
+ 0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008,
+ 0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008,
+ 0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008,
+ 0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x062d, 0xadb: 0x064d, 0xadc: 0x0008, 0xadd: 0x0008,
+ 0xade: 0x04d9, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008,
+ 0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008,
+ 0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008,
+ 0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008,
+ 0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008,
+ 0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008,
+ // Block 0x2c, offset 0xb00
+ 0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008,
+ 0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045,
+ 0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008,
+ 0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008,
+ 0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045,
+ 0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008,
+ 0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045,
+ 0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045,
+ 0xb30: 0x0008, 0xb31: 0x04e1, 0xb32: 0x0008, 0xb33: 0x04e9, 0xb34: 0x0008, 0xb35: 0x04f1,
+ 0xb36: 0x0008, 0xb37: 0x04f9, 0xb38: 0x0008, 0xb39: 0x0501, 0xb3a: 0x0008, 0xb3b: 0x0509,
+ 0xb3c: 0x0008, 0xb3d: 0x0511, 0xb3e: 0x0040, 0xb3f: 0x0040,
+ // Block 0x2d, offset 0xb40
+ 0xb40: 0x0519, 0xb41: 0x0521, 0xb42: 0x0529, 0xb43: 0x0531, 0xb44: 0x0539, 0xb45: 0x0541,
+ 0xb46: 0x0549, 0xb47: 0x0551, 0xb48: 0x0519, 0xb49: 0x0521, 0xb4a: 0x0529, 0xb4b: 0x0531,
+ 0xb4c: 0x0539, 0xb4d: 0x0541, 0xb4e: 0x0549, 0xb4f: 0x0551, 0xb50: 0x0559, 0xb51: 0x0561,
+ 0xb52: 0x0569, 0xb53: 0x0571, 0xb54: 0x0579, 0xb55: 0x0581, 0xb56: 0x0589, 0xb57: 0x0591,
+ 0xb58: 0x0559, 0xb59: 0x0561, 0xb5a: 0x0569, 0xb5b: 0x0571, 0xb5c: 0x0579, 0xb5d: 0x0581,
+ 0xb5e: 0x0589, 0xb5f: 0x0591, 0xb60: 0x0599, 0xb61: 0x05a1, 0xb62: 0x05a9, 0xb63: 0x05b1,
+ 0xb64: 0x05b9, 0xb65: 0x05c1, 0xb66: 0x05c9, 0xb67: 0x05d1, 0xb68: 0x0599, 0xb69: 0x05a1,
+ 0xb6a: 0x05a9, 0xb6b: 0x05b1, 0xb6c: 0x05b9, 0xb6d: 0x05c1, 0xb6e: 0x05c9, 0xb6f: 0x05d1,
+ 0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x05d9, 0xb73: 0x05e1, 0xb74: 0x05e9, 0xb75: 0x0040,
+ 0xb76: 0x0008, 0xb77: 0x05f1, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x0665, 0xb7b: 0x04e1,
+ 0xb7c: 0x05e1, 0xb7d: 0x067e, 0xb7e: 0x05f9, 0xb7f: 0x069e,
+ // Block 0x2e, offset 0xb80
+ 0xb80: 0x06be, 0xb81: 0x0602, 0xb82: 0x0609, 0xb83: 0x0611, 0xb84: 0x0619, 0xb85: 0x0040,
+ 0xb86: 0x0008, 0xb87: 0x0621, 0xb88: 0x06dd, 0xb89: 0x04e9, 0xb8a: 0x06f5, 0xb8b: 0x04f1,
+ 0xb8c: 0x0611, 0xb8d: 0x062a, 0xb8e: 0x0632, 0xb8f: 0x063a, 0xb90: 0x0008, 0xb91: 0x0008,
+ 0xb92: 0x0008, 0xb93: 0x0641, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008,
+ 0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x070d, 0xb9b: 0x04f9, 0xb9c: 0x0040, 0xb9d: 0x064a,
+ 0xb9e: 0x0652, 0xb9f: 0x065a, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x0661,
+ 0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045,
+ 0xbaa: 0x0725, 0xbab: 0x0509, 0xbac: 0xe04d, 0xbad: 0x066a, 0xbae: 0x012a, 0xbaf: 0x0672,
+ 0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x0679, 0xbb3: 0x0681, 0xbb4: 0x0689, 0xbb5: 0x0040,
+ 0xbb6: 0x0008, 0xbb7: 0x0691, 0xbb8: 0x073d, 0xbb9: 0x0501, 0xbba: 0x0515, 0xbbb: 0x0511,
+ 0xbbc: 0x0681, 0xbbd: 0x0756, 0xbbe: 0x0776, 0xbbf: 0x0040,
+ // Block 0x2f, offset 0xbc0
+ 0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a,
+ 0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0,
+ 0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d,
+ 0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x0796,
+ 0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018,
+ 0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018,
+ 0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040,
+ 0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a,
+ 0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x0699, 0xbf4: 0x06a1, 0xbf5: 0x0018,
+ 0xbf6: 0x06a9, 0xbf7: 0x06b1, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018,
+ 0xbfc: 0x06ba, 0xbfd: 0x0018, 0xbfe: 0x07b6, 0xbff: 0x0018,
+ // Block 0x30, offset 0xc00
+ 0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018,
+ 0xc06: 0x0018, 0xc07: 0x06c2, 0xc08: 0x06ca, 0xc09: 0x06d2, 0xc0a: 0x0018, 0xc0b: 0x0018,
+ 0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018,
+ 0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x06d9,
+ 0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018,
+ 0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340,
+ 0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040,
+ 0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340,
+ 0xc30: 0x06e1, 0xc31: 0x0311, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x06e9, 0xc35: 0x06f1,
+ 0xc36: 0x06f9, 0xc37: 0x0701, 0xc38: 0x0709, 0xc39: 0x0711, 0xc3a: 0x071a, 0xc3b: 0x07d5,
+ 0xc3c: 0x0722, 0xc3d: 0x072a, 0xc3e: 0x0732, 0xc3f: 0x0329,
+ // Block 0x31, offset 0xc40
+ 0xc40: 0x06e1, 0xc41: 0x0049, 0xc42: 0x0029, 0xc43: 0x0031, 0xc44: 0x06e9, 0xc45: 0x06f1,
+ 0xc46: 0x06f9, 0xc47: 0x0701, 0xc48: 0x0709, 0xc49: 0x0711, 0xc4a: 0x071a, 0xc4b: 0x07ed,
+ 0xc4c: 0x0722, 0xc4d: 0x072a, 0xc4e: 0x0732, 0xc4f: 0x0040, 0xc50: 0x0019, 0xc51: 0x02f9,
+ 0xc52: 0x0051, 0xc53: 0x0109, 0xc54: 0x0361, 0xc55: 0x00a9, 0xc56: 0x0319, 0xc57: 0x0101,
+ 0xc58: 0x0321, 0xc59: 0x0329, 0xc5a: 0x0339, 0xc5b: 0x0089, 0xc5c: 0x0341, 0xc5d: 0x0040,
+ 0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018,
+ 0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x0739, 0xc69: 0x0018,
+ 0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018,
+ 0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018,
+ 0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018,
+ 0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018,
+ // Block 0x32, offset 0xc80
+ 0xc80: 0x0806, 0xc81: 0x0826, 0xc82: 0x03d9, 0xc83: 0x0845, 0xc84: 0x0018, 0xc85: 0x0866,
+ 0xc86: 0x0886, 0xc87: 0x0369, 0xc88: 0x0018, 0xc89: 0x08a5, 0xc8a: 0x0309, 0xc8b: 0x00a9,
+ 0xc8c: 0x00a9, 0xc8d: 0x00a9, 0xc8e: 0x00a9, 0xc8f: 0x0741, 0xc90: 0x0311, 0xc91: 0x0311,
+ 0xc92: 0x0101, 0xc93: 0x0101, 0xc94: 0x0018, 0xc95: 0x0329, 0xc96: 0x0749, 0xc97: 0x0018,
+ 0xc98: 0x0018, 0xc99: 0x0339, 0xc9a: 0x0751, 0xc9b: 0x00b9, 0xc9c: 0x00b9, 0xc9d: 0x00b9,
+ 0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x0759, 0xca1: 0x08c5, 0xca2: 0x0761, 0xca3: 0x0018,
+ 0xca4: 0x04b1, 0xca5: 0x0018, 0xca6: 0x0769, 0xca7: 0x0018, 0xca8: 0x04b1, 0xca9: 0x0018,
+ 0xcaa: 0x0319, 0xcab: 0x0771, 0xcac: 0x02e9, 0xcad: 0x03d9, 0xcae: 0x0018, 0xcaf: 0x02f9,
+ 0xcb0: 0x02f9, 0xcb1: 0x03f1, 0xcb2: 0x0040, 0xcb3: 0x0321, 0xcb4: 0x0051, 0xcb5: 0x0779,
+ 0xcb6: 0x0781, 0xcb7: 0x0789, 0xcb8: 0x0791, 0xcb9: 0x0311, 0xcba: 0x0018, 0xcbb: 0x08e5,
+ 0xcbc: 0x0799, 0xcbd: 0x03a1, 0xcbe: 0x03a1, 0xcbf: 0x0799,
+ // Block 0x33, offset 0xcc0
+ 0xcc0: 0x0905, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x02f1,
+ 0xcc6: 0x02f1, 0xcc7: 0x02f9, 0xcc8: 0x0311, 0xcc9: 0x00b1, 0xcca: 0x0018, 0xccb: 0x0018,
+ 0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x07a1, 0xcd1: 0x07a9,
+ 0xcd2: 0x07b1, 0xcd3: 0x07b9, 0xcd4: 0x07c1, 0xcd5: 0x07c9, 0xcd6: 0x07d1, 0xcd7: 0x07d9,
+ 0xcd8: 0x07e1, 0xcd9: 0x07e9, 0xcda: 0x07f1, 0xcdb: 0x07f9, 0xcdc: 0x0801, 0xcdd: 0x0809,
+ 0xcde: 0x0811, 0xcdf: 0x0819, 0xce0: 0x0311, 0xce1: 0x0821, 0xce2: 0x091d, 0xce3: 0x0829,
+ 0xce4: 0x0391, 0xce5: 0x0831, 0xce6: 0x093d, 0xce7: 0x0839, 0xce8: 0x0841, 0xce9: 0x0109,
+ 0xcea: 0x0849, 0xceb: 0x095d, 0xcec: 0x0101, 0xced: 0x03d9, 0xcee: 0x02f1, 0xcef: 0x0321,
+ 0xcf0: 0x0311, 0xcf1: 0x0821, 0xcf2: 0x097d, 0xcf3: 0x0829, 0xcf4: 0x0391, 0xcf5: 0x0831,
+ 0xcf6: 0x099d, 0xcf7: 0x0839, 0xcf8: 0x0841, 0xcf9: 0x0109, 0xcfa: 0x0849, 0xcfb: 0x09bd,
+ 0xcfc: 0x0101, 0xcfd: 0x03d9, 0xcfe: 0x02f1, 0xcff: 0x0321,
+ // Block 0x34, offset 0xd00
+ 0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018,
+ 0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040,
+ 0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040,
+ 0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040,
+ 0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040,
+ 0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x0049, 0xd21: 0x0029, 0xd22: 0x0031, 0xd23: 0x06e9,
+ 0xd24: 0x06f1, 0xd25: 0x06f9, 0xd26: 0x0701, 0xd27: 0x0709, 0xd28: 0x0711, 0xd29: 0x0879,
+ 0xd2a: 0x0881, 0xd2b: 0x0889, 0xd2c: 0x0891, 0xd2d: 0x0899, 0xd2e: 0x08a1, 0xd2f: 0x08a9,
+ 0xd30: 0x08b1, 0xd31: 0x08b9, 0xd32: 0x08c1, 0xd33: 0x08c9, 0xd34: 0x0a1e, 0xd35: 0x0a3e,
+ 0xd36: 0x0a5e, 0xd37: 0x0a7e, 0xd38: 0x0a9e, 0xd39: 0x0abe, 0xd3a: 0x0ade, 0xd3b: 0x0afe,
+ 0xd3c: 0x0b1e, 0xd3d: 0x08d2, 0xd3e: 0x08da, 0xd3f: 0x08e2,
+ // Block 0x35, offset 0xd40
+ 0xd40: 0x08ea, 0xd41: 0x08f2, 0xd42: 0x08fa, 0xd43: 0x0902, 0xd44: 0x090a, 0xd45: 0x0912,
+ 0xd46: 0x091a, 0xd47: 0x0922, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040,
+ 0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040,
+ 0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040,
+ 0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b3e, 0xd5d: 0x0b5e,
+ 0xd5e: 0x0b7e, 0xd5f: 0x0b9e, 0xd60: 0x0bbe, 0xd61: 0x0bde, 0xd62: 0x0bfe, 0xd63: 0x0c1e,
+ 0xd64: 0x0c3e, 0xd65: 0x0c5e, 0xd66: 0x0c7e, 0xd67: 0x0c9e, 0xd68: 0x0cbe, 0xd69: 0x0cde,
+ 0xd6a: 0x0cfe, 0xd6b: 0x0d1e, 0xd6c: 0x0d3e, 0xd6d: 0x0d5e, 0xd6e: 0x0d7e, 0xd6f: 0x0d9e,
+ 0xd70: 0x0dbe, 0xd71: 0x0dde, 0xd72: 0x0dfe, 0xd73: 0x0e1e, 0xd74: 0x0e3e, 0xd75: 0x0e5e,
+ 0xd76: 0x0019, 0xd77: 0x02e9, 0xd78: 0x03d9, 0xd79: 0x02f1, 0xd7a: 0x02f9, 0xd7b: 0x03f1,
+ 0xd7c: 0x0309, 0xd7d: 0x00a9, 0xd7e: 0x0311, 0xd7f: 0x00b1,
+ // Block 0x36, offset 0xd80
+ 0xd80: 0x0319, 0xd81: 0x0101, 0xd82: 0x0321, 0xd83: 0x0329, 0xd84: 0x0051, 0xd85: 0x0339,
+ 0xd86: 0x0751, 0xd87: 0x00b9, 0xd88: 0x0089, 0xd89: 0x0341, 0xd8a: 0x0349, 0xd8b: 0x0391,
+ 0xd8c: 0x00c1, 0xd8d: 0x0109, 0xd8e: 0x00c9, 0xd8f: 0x04b1, 0xd90: 0x0019, 0xd91: 0x02e9,
+ 0xd92: 0x03d9, 0xd93: 0x02f1, 0xd94: 0x02f9, 0xd95: 0x03f1, 0xd96: 0x0309, 0xd97: 0x00a9,
+ 0xd98: 0x0311, 0xd99: 0x00b1, 0xd9a: 0x0319, 0xd9b: 0x0101, 0xd9c: 0x0321, 0xd9d: 0x0329,
+ 0xd9e: 0x0051, 0xd9f: 0x0339, 0xda0: 0x0751, 0xda1: 0x00b9, 0xda2: 0x0089, 0xda3: 0x0341,
+ 0xda4: 0x0349, 0xda5: 0x0391, 0xda6: 0x00c1, 0xda7: 0x0109, 0xda8: 0x00c9, 0xda9: 0x04b1,
+ 0xdaa: 0x06e1, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018,
+ 0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018,
+ 0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018,
+ 0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018,
+ // Block 0x37, offset 0xdc0
+ 0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008,
+ 0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008,
+ 0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008,
+ 0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008,
+ 0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008,
+ 0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x0941, 0xde3: 0x0ed5,
+ 0xde4: 0x0949, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d,
+ 0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0359, 0xdee: 0x0441, 0xdef: 0x0351,
+ 0xdf0: 0x03d1, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d,
+ 0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008,
+ 0xdfc: 0x00b1, 0xdfd: 0x0391, 0xdfe: 0x0951, 0xdff: 0x0959,
+ // Block 0x38, offset 0xe00
+ 0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008,
+ 0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008,
+ 0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008,
+ 0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008,
+ 0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008,
+ 0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008,
+ 0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018,
+ 0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308,
+ 0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040,
+ 0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018,
+ 0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018,
+ // Block 0x39, offset 0xe40
+ 0xe40: 0x2715, 0xe41: 0x2735, 0xe42: 0x2755, 0xe43: 0x2775, 0xe44: 0x2795, 0xe45: 0x27b5,
+ 0xe46: 0x27d5, 0xe47: 0x27f5, 0xe48: 0x2815, 0xe49: 0x2835, 0xe4a: 0x2855, 0xe4b: 0x2875,
+ 0xe4c: 0x2895, 0xe4d: 0x28b5, 0xe4e: 0x28d5, 0xe4f: 0x28f5, 0xe50: 0x2915, 0xe51: 0x2935,
+ 0xe52: 0x2955, 0xe53: 0x2975, 0xe54: 0x2995, 0xe55: 0x29b5, 0xe56: 0x0040, 0xe57: 0x0040,
+ 0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040,
+ 0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040,
+ 0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040,
+ 0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040,
+ 0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040,
+ 0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040,
+ 0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040,
+ // Block 0x3a, offset 0xe80
+ 0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x0961, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008,
+ 0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018,
+ 0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018,
+ 0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018,
+ 0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018,
+ 0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018,
+ 0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018,
+ 0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018,
+ 0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018,
+ 0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29d5, 0xeb9: 0x29f5, 0xeba: 0x2a15, 0xebb: 0x0018,
+ 0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018,
+ // Block 0x3b, offset 0xec0
+ 0xec0: 0x2b55, 0xec1: 0x2b75, 0xec2: 0x2b95, 0xec3: 0x2bb5, 0xec4: 0x2bd5, 0xec5: 0x2bf5,
+ 0xec6: 0x2bf5, 0xec7: 0x2bf5, 0xec8: 0x2c15, 0xec9: 0x2c15, 0xeca: 0x2c15, 0xecb: 0x2c15,
+ 0xecc: 0x2c35, 0xecd: 0x2c35, 0xece: 0x2c35, 0xecf: 0x2c55, 0xed0: 0x2c75, 0xed1: 0x2c75,
+ 0xed2: 0x2a95, 0xed3: 0x2a95, 0xed4: 0x2c75, 0xed5: 0x2c75, 0xed6: 0x2c95, 0xed7: 0x2c95,
+ 0xed8: 0x2c75, 0xed9: 0x2c75, 0xeda: 0x2a95, 0xedb: 0x2a95, 0xedc: 0x2c75, 0xedd: 0x2c75,
+ 0xede: 0x2c55, 0xedf: 0x2c55, 0xee0: 0x2cb5, 0xee1: 0x2cb5, 0xee2: 0x2cd5, 0xee3: 0x2cd5,
+ 0xee4: 0x0040, 0xee5: 0x2cf5, 0xee6: 0x2d15, 0xee7: 0x2d35, 0xee8: 0x2d35, 0xee9: 0x2d55,
+ 0xeea: 0x2d75, 0xeeb: 0x2d95, 0xeec: 0x2db5, 0xeed: 0x2dd5, 0xeee: 0x2df5, 0xeef: 0x2e15,
+ 0xef0: 0x2e35, 0xef1: 0x2e55, 0xef2: 0x2e55, 0xef3: 0x2e75, 0xef4: 0x2e95, 0xef5: 0x2e95,
+ 0xef6: 0x2eb5, 0xef7: 0x2ed5, 0xef8: 0x2e75, 0xef9: 0x2ef5, 0xefa: 0x2f15, 0xefb: 0x2ef5,
+ 0xefc: 0x2e75, 0xefd: 0x2f35, 0xefe: 0x2f55, 0xeff: 0x2f75,
+ // Block 0x3c, offset 0xf00
+ 0xf00: 0x2f95, 0xf01: 0x2fb5, 0xf02: 0x2d15, 0xf03: 0x2cf5, 0xf04: 0x2fd5, 0xf05: 0x2ff5,
+ 0xf06: 0x3015, 0xf07: 0x3035, 0xf08: 0x3055, 0xf09: 0x3075, 0xf0a: 0x3095, 0xf0b: 0x30b5,
+ 0xf0c: 0x30d5, 0xf0d: 0x30f5, 0xf0e: 0x3115, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018,
+ 0xf12: 0x3135, 0xf13: 0x3155, 0xf14: 0x3175, 0xf15: 0x3195, 0xf16: 0x31b5, 0xf17: 0x31d5,
+ 0xf18: 0x31f5, 0xf19: 0x3215, 0xf1a: 0x3235, 0xf1b: 0x3255, 0xf1c: 0x3175, 0xf1d: 0x3275,
+ 0xf1e: 0x3295, 0xf1f: 0x32b5, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008,
+ 0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008,
+ 0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008,
+ 0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008,
+ 0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0008,
+ 0xf3c: 0x0008, 0xf3d: 0x0008, 0xf3e: 0x0008, 0xf3f: 0x0008,
+ // Block 0x3d, offset 0xf40
+ 0xf40: 0x0b82, 0xf41: 0x0b8a, 0xf42: 0x0b92, 0xf43: 0x0b9a, 0xf44: 0x32d5, 0xf45: 0x32f5,
+ 0xf46: 0x3315, 0xf47: 0x3335, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018,
+ 0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x3355, 0xf51: 0x0ba1,
+ 0xf52: 0x0ba9, 0xf53: 0x0bb1, 0xf54: 0x0bb9, 0xf55: 0x0bc1, 0xf56: 0x0bc9, 0xf57: 0x0bd1,
+ 0xf58: 0x0bd9, 0xf59: 0x0be1, 0xf5a: 0x0be9, 0xf5b: 0x0bf1, 0xf5c: 0x0bf9, 0xf5d: 0x0c01,
+ 0xf5e: 0x0c09, 0xf5f: 0x0c11, 0xf60: 0x3375, 0xf61: 0x3395, 0xf62: 0x33b5, 0xf63: 0x33d5,
+ 0xf64: 0x33f5, 0xf65: 0x33f5, 0xf66: 0x3415, 0xf67: 0x3435, 0xf68: 0x3455, 0xf69: 0x3475,
+ 0xf6a: 0x3495, 0xf6b: 0x34b5, 0xf6c: 0x34d5, 0xf6d: 0x34f5, 0xf6e: 0x3515, 0xf6f: 0x3535,
+ 0xf70: 0x3555, 0xf71: 0x3575, 0xf72: 0x3595, 0xf73: 0x35b5, 0xf74: 0x35d5, 0xf75: 0x35f5,
+ 0xf76: 0x3615, 0xf77: 0x3635, 0xf78: 0x3655, 0xf79: 0x3675, 0xf7a: 0x3695, 0xf7b: 0x36b5,
+ 0xf7c: 0x0c19, 0xf7d: 0x0c21, 0xf7e: 0x36d5, 0xf7f: 0x0018,
+ // Block 0x3e, offset 0xf80
+ 0xf80: 0x36f5, 0xf81: 0x3715, 0xf82: 0x3735, 0xf83: 0x3755, 0xf84: 0x3775, 0xf85: 0x3795,
+ 0xf86: 0x37b5, 0xf87: 0x37d5, 0xf88: 0x37f5, 0xf89: 0x3815, 0xf8a: 0x3835, 0xf8b: 0x3855,
+ 0xf8c: 0x3875, 0xf8d: 0x3895, 0xf8e: 0x38b5, 0xf8f: 0x38d5, 0xf90: 0x38f5, 0xf91: 0x3915,
+ 0xf92: 0x3935, 0xf93: 0x3955, 0xf94: 0x3975, 0xf95: 0x3995, 0xf96: 0x39b5, 0xf97: 0x39d5,
+ 0xf98: 0x39f5, 0xf99: 0x3a15, 0xf9a: 0x3a35, 0xf9b: 0x3a55, 0xf9c: 0x3a75, 0xf9d: 0x3a95,
+ 0xf9e: 0x3ab5, 0xf9f: 0x3ad5, 0xfa0: 0x3af5, 0xfa1: 0x3b15, 0xfa2: 0x3b35, 0xfa3: 0x3b55,
+ 0xfa4: 0x3b75, 0xfa5: 0x3b95, 0xfa6: 0x1295, 0xfa7: 0x3bb5, 0xfa8: 0x3bd5, 0xfa9: 0x3bf5,
+ 0xfaa: 0x3c15, 0xfab: 0x3c35, 0xfac: 0x3c55, 0xfad: 0x3c75, 0xfae: 0x23b5, 0xfaf: 0x3c95,
+ 0xfb0: 0x3cb5, 0xfb1: 0x0c29, 0xfb2: 0x0c31, 0xfb3: 0x0c39, 0xfb4: 0x0c41, 0xfb5: 0x0c49,
+ 0xfb6: 0x0c51, 0xfb7: 0x0c59, 0xfb8: 0x0c61, 0xfb9: 0x0c69, 0xfba: 0x0c71, 0xfbb: 0x0c79,
+ 0xfbc: 0x0c81, 0xfbd: 0x0c89, 0xfbe: 0x0c91, 0xfbf: 0x0c99,
+ // Block 0x3f, offset 0xfc0
+ 0xfc0: 0x0ca1, 0xfc1: 0x0ca9, 0xfc2: 0x0cb1, 0xfc3: 0x0cb9, 0xfc4: 0x0cc1, 0xfc5: 0x0cc9,
+ 0xfc6: 0x0cd1, 0xfc7: 0x0cd9, 0xfc8: 0x0ce1, 0xfc9: 0x0ce9, 0xfca: 0x0cf1, 0xfcb: 0x0cf9,
+ 0xfcc: 0x0d01, 0xfcd: 0x3cd5, 0xfce: 0x0d09, 0xfcf: 0x3cf5, 0xfd0: 0x3d15, 0xfd1: 0x3d2d,
+ 0xfd2: 0x3d45, 0xfd3: 0x3d5d, 0xfd4: 0x3d75, 0xfd5: 0x3d75, 0xfd6: 0x3d5d, 0xfd7: 0x3d8d,
+ 0xfd8: 0x07d5, 0xfd9: 0x3da5, 0xfda: 0x3dbd, 0xfdb: 0x3dd5, 0xfdc: 0x3ded, 0xfdd: 0x3e05,
+ 0xfde: 0x3e1d, 0xfdf: 0x3e35, 0xfe0: 0x3e4d, 0xfe1: 0x3e65, 0xfe2: 0x3e7d, 0xfe3: 0x3e95,
+ 0xfe4: 0x3ead, 0xfe5: 0x3ead, 0xfe6: 0x3ec5, 0xfe7: 0x3ec5, 0xfe8: 0x3edd, 0xfe9: 0x3edd,
+ 0xfea: 0x3ef5, 0xfeb: 0x3f0d, 0xfec: 0x3f25, 0xfed: 0x3f3d, 0xfee: 0x3f55, 0xfef: 0x3f55,
+ 0xff0: 0x3f6d, 0xff1: 0x3f6d, 0xff2: 0x3f6d, 0xff3: 0x3f85, 0xff4: 0x3f9d, 0xff5: 0x3fb5,
+ 0xff6: 0x3fcd, 0xff7: 0x3fb5, 0xff8: 0x3fe5, 0xff9: 0x3ffd, 0xffa: 0x3f85, 0xffb: 0x4015,
+ 0xffc: 0x402d, 0xffd: 0x402d, 0xffe: 0x402d, 0xfff: 0x0d11,
+ // Block 0x40, offset 0x1000
+ 0x1000: 0x10f9, 0x1001: 0x1101, 0x1002: 0x40a5, 0x1003: 0x1109, 0x1004: 0x1111, 0x1005: 0x1119,
+ 0x1006: 0x1121, 0x1007: 0x1129, 0x1008: 0x40c5, 0x1009: 0x1131, 0x100a: 0x1139, 0x100b: 0x1141,
+ 0x100c: 0x40e5, 0x100d: 0x40e5, 0x100e: 0x1149, 0x100f: 0x1151, 0x1010: 0x1159, 0x1011: 0x4105,
+ 0x1012: 0x4125, 0x1013: 0x4145, 0x1014: 0x4165, 0x1015: 0x4185, 0x1016: 0x1161, 0x1017: 0x1169,
+ 0x1018: 0x1171, 0x1019: 0x1179, 0x101a: 0x1181, 0x101b: 0x41a5, 0x101c: 0x1189, 0x101d: 0x1191,
+ 0x101e: 0x1199, 0x101f: 0x41c5, 0x1020: 0x41e5, 0x1021: 0x11a1, 0x1022: 0x4205, 0x1023: 0x4225,
+ 0x1024: 0x4245, 0x1025: 0x11a9, 0x1026: 0x4265, 0x1027: 0x11b1, 0x1028: 0x11b9, 0x1029: 0x10f9,
+ 0x102a: 0x4285, 0x102b: 0x42a5, 0x102c: 0x42c5, 0x102d: 0x42e5, 0x102e: 0x11c1, 0x102f: 0x11c9,
+ 0x1030: 0x11d1, 0x1031: 0x11d9, 0x1032: 0x4305, 0x1033: 0x11e1, 0x1034: 0x11e9, 0x1035: 0x11f1,
+ 0x1036: 0x4325, 0x1037: 0x11f9, 0x1038: 0x1201, 0x1039: 0x11f9, 0x103a: 0x1209, 0x103b: 0x1211,
+ 0x103c: 0x4345, 0x103d: 0x1219, 0x103e: 0x1221, 0x103f: 0x1219,
+ // Block 0x41, offset 0x1040
+ 0x1040: 0x4365, 0x1041: 0x4385, 0x1042: 0x0040, 0x1043: 0x1229, 0x1044: 0x1231, 0x1045: 0x1239,
+ 0x1046: 0x1241, 0x1047: 0x0040, 0x1048: 0x1249, 0x1049: 0x1251, 0x104a: 0x1259, 0x104b: 0x1261,
+ 0x104c: 0x1269, 0x104d: 0x1271, 0x104e: 0x1199, 0x104f: 0x1279, 0x1050: 0x1281, 0x1051: 0x1289,
+ 0x1052: 0x43a5, 0x1053: 0x1291, 0x1054: 0x1121, 0x1055: 0x43c5, 0x1056: 0x43e5, 0x1057: 0x1299,
+ 0x1058: 0x0040, 0x1059: 0x4405, 0x105a: 0x12a1, 0x105b: 0x12a9, 0x105c: 0x12b1, 0x105d: 0x12b9,
+ 0x105e: 0x12c1, 0x105f: 0x12c9, 0x1060: 0x12d1, 0x1061: 0x12d9, 0x1062: 0x12e1, 0x1063: 0x12e9,
+ 0x1064: 0x12f1, 0x1065: 0x12f9, 0x1066: 0x1301, 0x1067: 0x1309, 0x1068: 0x1311, 0x1069: 0x1319,
+ 0x106a: 0x1321, 0x106b: 0x1329, 0x106c: 0x1331, 0x106d: 0x1339, 0x106e: 0x1341, 0x106f: 0x1349,
+ 0x1070: 0x1351, 0x1071: 0x1359, 0x1072: 0x1361, 0x1073: 0x1369, 0x1074: 0x1371, 0x1075: 0x1379,
+ 0x1076: 0x1381, 0x1077: 0x1389, 0x1078: 0x1391, 0x1079: 0x1399, 0x107a: 0x13a1, 0x107b: 0x13a9,
+ 0x107c: 0x13b1, 0x107d: 0x13b9, 0x107e: 0x13c1, 0x107f: 0x4425,
+ // Block 0x42, offset 0x1080
+ 0x1080: 0xe00d, 0x1081: 0x0008, 0x1082: 0xe00d, 0x1083: 0x0008, 0x1084: 0xe00d, 0x1085: 0x0008,
+ 0x1086: 0xe00d, 0x1087: 0x0008, 0x1088: 0xe00d, 0x1089: 0x0008, 0x108a: 0xe00d, 0x108b: 0x0008,
+ 0x108c: 0xe00d, 0x108d: 0x0008, 0x108e: 0xe00d, 0x108f: 0x0008, 0x1090: 0xe00d, 0x1091: 0x0008,
+ 0x1092: 0xe00d, 0x1093: 0x0008, 0x1094: 0xe00d, 0x1095: 0x0008, 0x1096: 0xe00d, 0x1097: 0x0008,
+ 0x1098: 0xe00d, 0x1099: 0x0008, 0x109a: 0xe00d, 0x109b: 0x0008, 0x109c: 0xe00d, 0x109d: 0x0008,
+ 0x109e: 0xe00d, 0x109f: 0x0008, 0x10a0: 0xe00d, 0x10a1: 0x0008, 0x10a2: 0xe00d, 0x10a3: 0x0008,
+ 0x10a4: 0xe00d, 0x10a5: 0x0008, 0x10a6: 0xe00d, 0x10a7: 0x0008, 0x10a8: 0xe00d, 0x10a9: 0x0008,
+ 0x10aa: 0xe00d, 0x10ab: 0x0008, 0x10ac: 0xe00d, 0x10ad: 0x0008, 0x10ae: 0x0008, 0x10af: 0x3308,
+ 0x10b0: 0x3318, 0x10b1: 0x3318, 0x10b2: 0x3318, 0x10b3: 0x0018, 0x10b4: 0x3308, 0x10b5: 0x3308,
+ 0x10b6: 0x3308, 0x10b7: 0x3308, 0x10b8: 0x3308, 0x10b9: 0x3308, 0x10ba: 0x3308, 0x10bb: 0x3308,
+ 0x10bc: 0x3308, 0x10bd: 0x3308, 0x10be: 0x0018, 0x10bf: 0x0008,
+ // Block 0x43, offset 0x10c0
+ 0x10c0: 0xe00d, 0x10c1: 0x0008, 0x10c2: 0xe00d, 0x10c3: 0x0008, 0x10c4: 0xe00d, 0x10c5: 0x0008,
+ 0x10c6: 0xe00d, 0x10c7: 0x0008, 0x10c8: 0xe00d, 0x10c9: 0x0008, 0x10ca: 0xe00d, 0x10cb: 0x0008,
+ 0x10cc: 0xe00d, 0x10cd: 0x0008, 0x10ce: 0xe00d, 0x10cf: 0x0008, 0x10d0: 0xe00d, 0x10d1: 0x0008,
+ 0x10d2: 0xe00d, 0x10d3: 0x0008, 0x10d4: 0xe00d, 0x10d5: 0x0008, 0x10d6: 0xe00d, 0x10d7: 0x0008,
+ 0x10d8: 0xe00d, 0x10d9: 0x0008, 0x10da: 0xe00d, 0x10db: 0x0008, 0x10dc: 0x02d1, 0x10dd: 0x13c9,
+ 0x10de: 0x3308, 0x10df: 0x3308, 0x10e0: 0x0008, 0x10e1: 0x0008, 0x10e2: 0x0008, 0x10e3: 0x0008,
+ 0x10e4: 0x0008, 0x10e5: 0x0008, 0x10e6: 0x0008, 0x10e7: 0x0008, 0x10e8: 0x0008, 0x10e9: 0x0008,
+ 0x10ea: 0x0008, 0x10eb: 0x0008, 0x10ec: 0x0008, 0x10ed: 0x0008, 0x10ee: 0x0008, 0x10ef: 0x0008,
+ 0x10f0: 0x0008, 0x10f1: 0x0008, 0x10f2: 0x0008, 0x10f3: 0x0008, 0x10f4: 0x0008, 0x10f5: 0x0008,
+ 0x10f6: 0x0008, 0x10f7: 0x0008, 0x10f8: 0x0008, 0x10f9: 0x0008, 0x10fa: 0x0008, 0x10fb: 0x0008,
+ 0x10fc: 0x0008, 0x10fd: 0x0008, 0x10fe: 0x0008, 0x10ff: 0x0008,
+ // Block 0x44, offset 0x1100
+ 0x1100: 0x0018, 0x1101: 0x0018, 0x1102: 0x0018, 0x1103: 0x0018, 0x1104: 0x0018, 0x1105: 0x0018,
+ 0x1106: 0x0018, 0x1107: 0x0018, 0x1108: 0x0018, 0x1109: 0x0018, 0x110a: 0x0018, 0x110b: 0x0018,
+ 0x110c: 0x0018, 0x110d: 0x0018, 0x110e: 0x0018, 0x110f: 0x0018, 0x1110: 0x0018, 0x1111: 0x0018,
+ 0x1112: 0x0018, 0x1113: 0x0018, 0x1114: 0x0018, 0x1115: 0x0018, 0x1116: 0x0018, 0x1117: 0x0008,
+ 0x1118: 0x0008, 0x1119: 0x0008, 0x111a: 0x0008, 0x111b: 0x0008, 0x111c: 0x0008, 0x111d: 0x0008,
+ 0x111e: 0x0008, 0x111f: 0x0008, 0x1120: 0x0018, 0x1121: 0x0018, 0x1122: 0xe00d, 0x1123: 0x0008,
+ 0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008,
+ 0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0xe00d, 0x112f: 0x0008,
+ 0x1130: 0x0008, 0x1131: 0x0008, 0x1132: 0xe00d, 0x1133: 0x0008, 0x1134: 0xe00d, 0x1135: 0x0008,
+ 0x1136: 0xe00d, 0x1137: 0x0008, 0x1138: 0xe00d, 0x1139: 0x0008, 0x113a: 0xe00d, 0x113b: 0x0008,
+ 0x113c: 0xe00d, 0x113d: 0x0008, 0x113e: 0xe00d, 0x113f: 0x0008,
+ // Block 0x45, offset 0x1140
+ 0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008,
+ 0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008,
+ 0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008,
+ 0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008,
+ 0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0xe00d, 0x115d: 0x0008,
+ 0x115e: 0xe00d, 0x115f: 0x0008, 0x1160: 0xe00d, 0x1161: 0x0008, 0x1162: 0xe00d, 0x1163: 0x0008,
+ 0x1164: 0xe00d, 0x1165: 0x0008, 0x1166: 0xe00d, 0x1167: 0x0008, 0x1168: 0xe00d, 0x1169: 0x0008,
+ 0x116a: 0xe00d, 0x116b: 0x0008, 0x116c: 0xe00d, 0x116d: 0x0008, 0x116e: 0xe00d, 0x116f: 0x0008,
+ 0x1170: 0xe0fd, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008,
+ 0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0xe01d, 0x117a: 0x0008, 0x117b: 0xe03d,
+ 0x117c: 0x0008, 0x117d: 0x4445, 0x117e: 0xe00d, 0x117f: 0x0008,
+ // Block 0x46, offset 0x1180
+ 0x1180: 0xe00d, 0x1181: 0x0008, 0x1182: 0xe00d, 0x1183: 0x0008, 0x1184: 0xe00d, 0x1185: 0x0008,
+ 0x1186: 0xe00d, 0x1187: 0x0008, 0x1188: 0x0008, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0xe03d,
+ 0x118c: 0x0008, 0x118d: 0x0409, 0x118e: 0x0008, 0x118f: 0x0008, 0x1190: 0xe00d, 0x1191: 0x0008,
+ 0x1192: 0xe00d, 0x1193: 0x0008, 0x1194: 0x0008, 0x1195: 0x0008, 0x1196: 0xe00d, 0x1197: 0x0008,
+ 0x1198: 0xe00d, 0x1199: 0x0008, 0x119a: 0xe00d, 0x119b: 0x0008, 0x119c: 0xe00d, 0x119d: 0x0008,
+ 0x119e: 0xe00d, 0x119f: 0x0008, 0x11a0: 0xe00d, 0x11a1: 0x0008, 0x11a2: 0xe00d, 0x11a3: 0x0008,
+ 0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,
+ 0x11aa: 0x13d1, 0x11ab: 0x0371, 0x11ac: 0x0401, 0x11ad: 0x13d9, 0x11ae: 0x0421, 0x11af: 0x0008,
+ 0x11b0: 0x13e1, 0x11b1: 0x13e9, 0x11b2: 0x0429, 0x11b3: 0x4465, 0x11b4: 0xe00d, 0x11b5: 0x0008,
+ 0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008,
+ 0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008,
+ // Block 0x47, offset 0x11c0
+ 0x11c0: 0x650d, 0x11c1: 0x652d, 0x11c2: 0x654d, 0x11c3: 0x656d, 0x11c4: 0x658d, 0x11c5: 0x65ad,
+ 0x11c6: 0x65cd, 0x11c7: 0x65ed, 0x11c8: 0x660d, 0x11c9: 0x662d, 0x11ca: 0x664d, 0x11cb: 0x666d,
+ 0x11cc: 0x668d, 0x11cd: 0x66ad, 0x11ce: 0x0008, 0x11cf: 0x0008, 0x11d0: 0x66cd, 0x11d1: 0x0008,
+ 0x11d2: 0x66ed, 0x11d3: 0x0008, 0x11d4: 0x0008, 0x11d5: 0x670d, 0x11d6: 0x672d, 0x11d7: 0x674d,
+ 0x11d8: 0x676d, 0x11d9: 0x678d, 0x11da: 0x67ad, 0x11db: 0x67cd, 0x11dc: 0x67ed, 0x11dd: 0x680d,
+ 0x11de: 0x682d, 0x11df: 0x0008, 0x11e0: 0x684d, 0x11e1: 0x0008, 0x11e2: 0x686d, 0x11e3: 0x0008,
+ 0x11e4: 0x0008, 0x11e5: 0x688d, 0x11e6: 0x68ad, 0x11e7: 0x0008, 0x11e8: 0x0008, 0x11e9: 0x0008,
+ 0x11ea: 0x68cd, 0x11eb: 0x68ed, 0x11ec: 0x690d, 0x11ed: 0x692d, 0x11ee: 0x694d, 0x11ef: 0x696d,
+ 0x11f0: 0x698d, 0x11f1: 0x69ad, 0x11f2: 0x69cd, 0x11f3: 0x69ed, 0x11f4: 0x6a0d, 0x11f5: 0x6a2d,
+ 0x11f6: 0x6a4d, 0x11f7: 0x6a6d, 0x11f8: 0x6a8d, 0x11f9: 0x6aad, 0x11fa: 0x6acd, 0x11fb: 0x6aed,
+ 0x11fc: 0x6b0d, 0x11fd: 0x6b2d, 0x11fe: 0x6b4d, 0x11ff: 0x6b6d,
+ // Block 0x48, offset 0x1200
+ 0x1200: 0x7acd, 0x1201: 0x7aed, 0x1202: 0x7b0d, 0x1203: 0x7b2d, 0x1204: 0x7b4d, 0x1205: 0x7b6d,
+ 0x1206: 0x7b8d, 0x1207: 0x7bad, 0x1208: 0x7bcd, 0x1209: 0x7bed, 0x120a: 0x7c0d, 0x120b: 0x7c2d,
+ 0x120c: 0x7c4d, 0x120d: 0x7c6d, 0x120e: 0x7c8d, 0x120f: 0x1409, 0x1210: 0x1411, 0x1211: 0x1419,
+ 0x1212: 0x7cad, 0x1213: 0x7ccd, 0x1214: 0x7ced, 0x1215: 0x1421, 0x1216: 0x1429, 0x1217: 0x1431,
+ 0x1218: 0x7d0d, 0x1219: 0x7d2d, 0x121a: 0x0040, 0x121b: 0x0040, 0x121c: 0x0040, 0x121d: 0x0040,
+ 0x121e: 0x0040, 0x121f: 0x0040, 0x1220: 0x0040, 0x1221: 0x0040, 0x1222: 0x0040, 0x1223: 0x0040,
+ 0x1224: 0x0040, 0x1225: 0x0040, 0x1226: 0x0040, 0x1227: 0x0040, 0x1228: 0x0040, 0x1229: 0x0040,
+ 0x122a: 0x0040, 0x122b: 0x0040, 0x122c: 0x0040, 0x122d: 0x0040, 0x122e: 0x0040, 0x122f: 0x0040,
+ 0x1230: 0x0040, 0x1231: 0x0040, 0x1232: 0x0040, 0x1233: 0x0040, 0x1234: 0x0040, 0x1235: 0x0040,
+ 0x1236: 0x0040, 0x1237: 0x0040, 0x1238: 0x0040, 0x1239: 0x0040, 0x123a: 0x0040, 0x123b: 0x0040,
+ 0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040,
+ // Block 0x49, offset 0x1240
+ 0x1240: 0x1439, 0x1241: 0x1441, 0x1242: 0x1449, 0x1243: 0x7d4d, 0x1244: 0x7d6d, 0x1245: 0x1451,
+ 0x1246: 0x1451, 0x1247: 0x0040, 0x1248: 0x0040, 0x1249: 0x0040, 0x124a: 0x0040, 0x124b: 0x0040,
+ 0x124c: 0x0040, 0x124d: 0x0040, 0x124e: 0x0040, 0x124f: 0x0040, 0x1250: 0x0040, 0x1251: 0x0040,
+ 0x1252: 0x0040, 0x1253: 0x1459, 0x1254: 0x1461, 0x1255: 0x1469, 0x1256: 0x1471, 0x1257: 0x1479,
+ 0x1258: 0x0040, 0x1259: 0x0040, 0x125a: 0x0040, 0x125b: 0x0040, 0x125c: 0x0040, 0x125d: 0x1481,
+ 0x125e: 0x3308, 0x125f: 0x1489, 0x1260: 0x1491, 0x1261: 0x0779, 0x1262: 0x0791, 0x1263: 0x1499,
+ 0x1264: 0x14a1, 0x1265: 0x14a9, 0x1266: 0x14b1, 0x1267: 0x14b9, 0x1268: 0x14c1, 0x1269: 0x071a,
+ 0x126a: 0x14c9, 0x126b: 0x14d1, 0x126c: 0x14d9, 0x126d: 0x14e1, 0x126e: 0x14e9, 0x126f: 0x14f1,
+ 0x1270: 0x14f9, 0x1271: 0x1501, 0x1272: 0x1509, 0x1273: 0x1511, 0x1274: 0x1519, 0x1275: 0x1521,
+ 0x1276: 0x1529, 0x1277: 0x0040, 0x1278: 0x1531, 0x1279: 0x1539, 0x127a: 0x1541, 0x127b: 0x1549,
+ 0x127c: 0x1551, 0x127d: 0x0040, 0x127e: 0x1559, 0x127f: 0x0040,
+ // Block 0x4a, offset 0x1280
+ 0x1280: 0x1561, 0x1281: 0x1569, 0x1282: 0x0040, 0x1283: 0x1571, 0x1284: 0x1579, 0x1285: 0x0040,
+ 0x1286: 0x1581, 0x1287: 0x1589, 0x1288: 0x1591, 0x1289: 0x1599, 0x128a: 0x15a1, 0x128b: 0x15a9,
+ 0x128c: 0x15b1, 0x128d: 0x15b9, 0x128e: 0x15c1, 0x128f: 0x15c9, 0x1290: 0x15d1, 0x1291: 0x15d1,
+ 0x1292: 0x15d9, 0x1293: 0x15d9, 0x1294: 0x15d9, 0x1295: 0x15d9, 0x1296: 0x15e1, 0x1297: 0x15e1,
+ 0x1298: 0x15e1, 0x1299: 0x15e1, 0x129a: 0x15e9, 0x129b: 0x15e9, 0x129c: 0x15e9, 0x129d: 0x15e9,
+ 0x129e: 0x15f1, 0x129f: 0x15f1, 0x12a0: 0x15f1, 0x12a1: 0x15f1, 0x12a2: 0x15f9, 0x12a3: 0x15f9,
+ 0x12a4: 0x15f9, 0x12a5: 0x15f9, 0x12a6: 0x1601, 0x12a7: 0x1601, 0x12a8: 0x1601, 0x12a9: 0x1601,
+ 0x12aa: 0x1609, 0x12ab: 0x1609, 0x12ac: 0x1609, 0x12ad: 0x1609, 0x12ae: 0x1611, 0x12af: 0x1611,
+ 0x12b0: 0x1611, 0x12b1: 0x1611, 0x12b2: 0x1619, 0x12b3: 0x1619, 0x12b4: 0x1619, 0x12b5: 0x1619,
+ 0x12b6: 0x1621, 0x12b7: 0x1621, 0x12b8: 0x1621, 0x12b9: 0x1621, 0x12ba: 0x1629, 0x12bb: 0x1629,
+ 0x12bc: 0x1629, 0x12bd: 0x1629, 0x12be: 0x1631, 0x12bf: 0x1631,
+ // Block 0x4b, offset 0x12c0
+ 0x12c0: 0x1631, 0x12c1: 0x1631, 0x12c2: 0x1639, 0x12c3: 0x1639, 0x12c4: 0x1641, 0x12c5: 0x1641,
+ 0x12c6: 0x1649, 0x12c7: 0x1649, 0x12c8: 0x1651, 0x12c9: 0x1651, 0x12ca: 0x1659, 0x12cb: 0x1659,
+ 0x12cc: 0x1661, 0x12cd: 0x1661, 0x12ce: 0x1669, 0x12cf: 0x1669, 0x12d0: 0x1669, 0x12d1: 0x1669,
+ 0x12d2: 0x1671, 0x12d3: 0x1671, 0x12d4: 0x1671, 0x12d5: 0x1671, 0x12d6: 0x1679, 0x12d7: 0x1679,
+ 0x12d8: 0x1679, 0x12d9: 0x1679, 0x12da: 0x1681, 0x12db: 0x1681, 0x12dc: 0x1681, 0x12dd: 0x1681,
+ 0x12de: 0x1689, 0x12df: 0x1689, 0x12e0: 0x1691, 0x12e1: 0x1691, 0x12e2: 0x1691, 0x12e3: 0x1691,
+ 0x12e4: 0x1699, 0x12e5: 0x1699, 0x12e6: 0x16a1, 0x12e7: 0x16a1, 0x12e8: 0x16a1, 0x12e9: 0x16a1,
+ 0x12ea: 0x16a9, 0x12eb: 0x16a9, 0x12ec: 0x16a9, 0x12ed: 0x16a9, 0x12ee: 0x16b1, 0x12ef: 0x16b1,
+ 0x12f0: 0x16b9, 0x12f1: 0x16b9, 0x12f2: 0x0818, 0x12f3: 0x0818, 0x12f4: 0x0818, 0x12f5: 0x0818,
+ 0x12f6: 0x0818, 0x12f7: 0x0818, 0x12f8: 0x0818, 0x12f9: 0x0818, 0x12fa: 0x0818, 0x12fb: 0x0818,
+ 0x12fc: 0x0818, 0x12fd: 0x0818, 0x12fe: 0x0818, 0x12ff: 0x0818,
+ // Block 0x4c, offset 0x1300
+ 0x1300: 0x0818, 0x1301: 0x0818, 0x1302: 0x0040, 0x1303: 0x0040, 0x1304: 0x0040, 0x1305: 0x0040,
+ 0x1306: 0x0040, 0x1307: 0x0040, 0x1308: 0x0040, 0x1309: 0x0040, 0x130a: 0x0040, 0x130b: 0x0040,
+ 0x130c: 0x0040, 0x130d: 0x0040, 0x130e: 0x0040, 0x130f: 0x0040, 0x1310: 0x0040, 0x1311: 0x0040,
+ 0x1312: 0x0040, 0x1313: 0x16c1, 0x1314: 0x16c1, 0x1315: 0x16c1, 0x1316: 0x16c1, 0x1317: 0x16c9,
+ 0x1318: 0x16c9, 0x1319: 0x16d1, 0x131a: 0x16d1, 0x131b: 0x16d9, 0x131c: 0x16d9, 0x131d: 0x0149,
+ 0x131e: 0x16e1, 0x131f: 0x16e1, 0x1320: 0x16e9, 0x1321: 0x16e9, 0x1322: 0x16f1, 0x1323: 0x16f1,
+ 0x1324: 0x16f9, 0x1325: 0x16f9, 0x1326: 0x16f9, 0x1327: 0x16f9, 0x1328: 0x1701, 0x1329: 0x1701,
+ 0x132a: 0x1709, 0x132b: 0x1709, 0x132c: 0x1711, 0x132d: 0x1711, 0x132e: 0x1719, 0x132f: 0x1719,
+ 0x1330: 0x1721, 0x1331: 0x1721, 0x1332: 0x1729, 0x1333: 0x1729, 0x1334: 0x1731, 0x1335: 0x1731,
+ 0x1336: 0x1739, 0x1337: 0x1739, 0x1338: 0x1739, 0x1339: 0x1741, 0x133a: 0x1741, 0x133b: 0x1741,
+ 0x133c: 0x1749, 0x133d: 0x1749, 0x133e: 0x1749, 0x133f: 0x1749,
+ // Block 0x4d, offset 0x1340
+ 0x1340: 0x1949, 0x1341: 0x1951, 0x1342: 0x1959, 0x1343: 0x1961, 0x1344: 0x1969, 0x1345: 0x1971,
+ 0x1346: 0x1979, 0x1347: 0x1981, 0x1348: 0x1989, 0x1349: 0x1991, 0x134a: 0x1999, 0x134b: 0x19a1,
+ 0x134c: 0x19a9, 0x134d: 0x19b1, 0x134e: 0x19b9, 0x134f: 0x19c1, 0x1350: 0x19c9, 0x1351: 0x19d1,
+ 0x1352: 0x19d9, 0x1353: 0x19e1, 0x1354: 0x19e9, 0x1355: 0x19f1, 0x1356: 0x19f9, 0x1357: 0x1a01,
+ 0x1358: 0x1a09, 0x1359: 0x1a11, 0x135a: 0x1a19, 0x135b: 0x1a21, 0x135c: 0x1a29, 0x135d: 0x1a31,
+ 0x135e: 0x1a3a, 0x135f: 0x1a42, 0x1360: 0x1a4a, 0x1361: 0x1a52, 0x1362: 0x1a5a, 0x1363: 0x1a62,
+ 0x1364: 0x1a69, 0x1365: 0x1a71, 0x1366: 0x1761, 0x1367: 0x1a79, 0x1368: 0x1741, 0x1369: 0x1769,
+ 0x136a: 0x1a81, 0x136b: 0x1a89, 0x136c: 0x1789, 0x136d: 0x1a91, 0x136e: 0x1791, 0x136f: 0x1799,
+ 0x1370: 0x1a99, 0x1371: 0x1aa1, 0x1372: 0x17b9, 0x1373: 0x1aa9, 0x1374: 0x17c1, 0x1375: 0x17c9,
+ 0x1376: 0x1ab1, 0x1377: 0x1ab9, 0x1378: 0x17d9, 0x1379: 0x1ac1, 0x137a: 0x17e1, 0x137b: 0x17e9,
+ 0x137c: 0x18d1, 0x137d: 0x18d9, 0x137e: 0x18f1, 0x137f: 0x18f9,
+ // Block 0x4e, offset 0x1380
+ 0x1380: 0x1901, 0x1381: 0x1921, 0x1382: 0x1929, 0x1383: 0x1931, 0x1384: 0x1939, 0x1385: 0x1959,
+ 0x1386: 0x1961, 0x1387: 0x1969, 0x1388: 0x1ac9, 0x1389: 0x1989, 0x138a: 0x1ad1, 0x138b: 0x1ad9,
+ 0x138c: 0x19b9, 0x138d: 0x1ae1, 0x138e: 0x19c1, 0x138f: 0x19c9, 0x1390: 0x1a31, 0x1391: 0x1ae9,
+ 0x1392: 0x1af1, 0x1393: 0x1a09, 0x1394: 0x1af9, 0x1395: 0x1a11, 0x1396: 0x1a19, 0x1397: 0x1751,
+ 0x1398: 0x1759, 0x1399: 0x1b01, 0x139a: 0x1761, 0x139b: 0x1b09, 0x139c: 0x1771, 0x139d: 0x1779,
+ 0x139e: 0x1781, 0x139f: 0x1789, 0x13a0: 0x1b11, 0x13a1: 0x17a1, 0x13a2: 0x17a9, 0x13a3: 0x17b1,
+ 0x13a4: 0x17b9, 0x13a5: 0x1b19, 0x13a6: 0x17d9, 0x13a7: 0x17f1, 0x13a8: 0x17f9, 0x13a9: 0x1801,
+ 0x13aa: 0x1809, 0x13ab: 0x1811, 0x13ac: 0x1821, 0x13ad: 0x1829, 0x13ae: 0x1831, 0x13af: 0x1839,
+ 0x13b0: 0x1841, 0x13b1: 0x1849, 0x13b2: 0x1b21, 0x13b3: 0x1851, 0x13b4: 0x1859, 0x13b5: 0x1861,
+ 0x13b6: 0x1869, 0x13b7: 0x1871, 0x13b8: 0x1879, 0x13b9: 0x1889, 0x13ba: 0x1891, 0x13bb: 0x1899,
+ 0x13bc: 0x18a1, 0x13bd: 0x18a9, 0x13be: 0x18b1, 0x13bf: 0x18b9,
+ // Block 0x4f, offset 0x13c0
+ 0x13c0: 0x18c1, 0x13c1: 0x18c9, 0x13c2: 0x18e1, 0x13c3: 0x18e9, 0x13c4: 0x1909, 0x13c5: 0x1911,
+ 0x13c6: 0x1919, 0x13c7: 0x1921, 0x13c8: 0x1929, 0x13c9: 0x1941, 0x13ca: 0x1949, 0x13cb: 0x1951,
+ 0x13cc: 0x1959, 0x13cd: 0x1b29, 0x13ce: 0x1971, 0x13cf: 0x1979, 0x13d0: 0x1981, 0x13d1: 0x1989,
+ 0x13d2: 0x19a1, 0x13d3: 0x19a9, 0x13d4: 0x19b1, 0x13d5: 0x19b9, 0x13d6: 0x1b31, 0x13d7: 0x19d1,
+ 0x13d8: 0x19d9, 0x13d9: 0x1b39, 0x13da: 0x19f1, 0x13db: 0x19f9, 0x13dc: 0x1a01, 0x13dd: 0x1a09,
+ 0x13de: 0x1b41, 0x13df: 0x1761, 0x13e0: 0x1b09, 0x13e1: 0x1789, 0x13e2: 0x1b11, 0x13e3: 0x17b9,
+ 0x13e4: 0x1b19, 0x13e5: 0x17d9, 0x13e6: 0x1b49, 0x13e7: 0x1841, 0x13e8: 0x1b51, 0x13e9: 0x1b59,
+ 0x13ea: 0x1b61, 0x13eb: 0x1921, 0x13ec: 0x1929, 0x13ed: 0x1959, 0x13ee: 0x19b9, 0x13ef: 0x1b31,
+ 0x13f0: 0x1a09, 0x13f1: 0x1b41, 0x13f2: 0x1b69, 0x13f3: 0x1b71, 0x13f4: 0x1b79, 0x13f5: 0x1b81,
+ 0x13f6: 0x1b89, 0x13f7: 0x1b91, 0x13f8: 0x1b99, 0x13f9: 0x1ba1, 0x13fa: 0x1ba9, 0x13fb: 0x1bb1,
+ 0x13fc: 0x1bb9, 0x13fd: 0x1bc1, 0x13fe: 0x1bc9, 0x13ff: 0x1bd1,
+ // Block 0x50, offset 0x1400
+ 0x1400: 0x1bd9, 0x1401: 0x1be1, 0x1402: 0x1be9, 0x1403: 0x1bf1, 0x1404: 0x1bf9, 0x1405: 0x1c01,
+ 0x1406: 0x1c09, 0x1407: 0x1c11, 0x1408: 0x1c19, 0x1409: 0x1c21, 0x140a: 0x1c29, 0x140b: 0x1c31,
+ 0x140c: 0x1b59, 0x140d: 0x1c39, 0x140e: 0x1c41, 0x140f: 0x1c49, 0x1410: 0x1c51, 0x1411: 0x1b81,
+ 0x1412: 0x1b89, 0x1413: 0x1b91, 0x1414: 0x1b99, 0x1415: 0x1ba1, 0x1416: 0x1ba9, 0x1417: 0x1bb1,
+ 0x1418: 0x1bb9, 0x1419: 0x1bc1, 0x141a: 0x1bc9, 0x141b: 0x1bd1, 0x141c: 0x1bd9, 0x141d: 0x1be1,
+ 0x141e: 0x1be9, 0x141f: 0x1bf1, 0x1420: 0x1bf9, 0x1421: 0x1c01, 0x1422: 0x1c09, 0x1423: 0x1c11,
+ 0x1424: 0x1c19, 0x1425: 0x1c21, 0x1426: 0x1c29, 0x1427: 0x1c31, 0x1428: 0x1b59, 0x1429: 0x1c39,
+ 0x142a: 0x1c41, 0x142b: 0x1c49, 0x142c: 0x1c51, 0x142d: 0x1c21, 0x142e: 0x1c29, 0x142f: 0x1c31,
+ 0x1430: 0x1b59, 0x1431: 0x1b51, 0x1432: 0x1b61, 0x1433: 0x1881, 0x1434: 0x1829, 0x1435: 0x1831,
+ 0x1436: 0x1839, 0x1437: 0x1c21, 0x1438: 0x1c29, 0x1439: 0x1c31, 0x143a: 0x1881, 0x143b: 0x1889,
+ 0x143c: 0x1c59, 0x143d: 0x1c59, 0x143e: 0x0018, 0x143f: 0x0018,
+ // Block 0x51, offset 0x1440
+ 0x1440: 0x0040, 0x1441: 0x0040, 0x1442: 0x0040, 0x1443: 0x0040, 0x1444: 0x0040, 0x1445: 0x0040,
+ 0x1446: 0x0040, 0x1447: 0x0040, 0x1448: 0x0040, 0x1449: 0x0040, 0x144a: 0x0040, 0x144b: 0x0040,
+ 0x144c: 0x0040, 0x144d: 0x0040, 0x144e: 0x0040, 0x144f: 0x0040, 0x1450: 0x1c61, 0x1451: 0x1c69,
+ 0x1452: 0x1c69, 0x1453: 0x1c71, 0x1454: 0x1c79, 0x1455: 0x1c81, 0x1456: 0x1c89, 0x1457: 0x1c91,
+ 0x1458: 0x1c99, 0x1459: 0x1c99, 0x145a: 0x1ca1, 0x145b: 0x1ca9, 0x145c: 0x1cb1, 0x145d: 0x1cb9,
+ 0x145e: 0x1cc1, 0x145f: 0x1cc9, 0x1460: 0x1cc9, 0x1461: 0x1cd1, 0x1462: 0x1cd9, 0x1463: 0x1cd9,
+ 0x1464: 0x1ce1, 0x1465: 0x1ce1, 0x1466: 0x1ce9, 0x1467: 0x1cf1, 0x1468: 0x1cf1, 0x1469: 0x1cf9,
+ 0x146a: 0x1d01, 0x146b: 0x1d01, 0x146c: 0x1d09, 0x146d: 0x1d09, 0x146e: 0x1d11, 0x146f: 0x1d19,
+ 0x1470: 0x1d19, 0x1471: 0x1d21, 0x1472: 0x1d21, 0x1473: 0x1d29, 0x1474: 0x1d31, 0x1475: 0x1d39,
+ 0x1476: 0x1d41, 0x1477: 0x1d41, 0x1478: 0x1d49, 0x1479: 0x1d51, 0x147a: 0x1d59, 0x147b: 0x1d61,
+ 0x147c: 0x1d69, 0x147d: 0x1d69, 0x147e: 0x1d71, 0x147f: 0x1d79,
+ // Block 0x52, offset 0x1480
+ 0x1480: 0x1f29, 0x1481: 0x1f31, 0x1482: 0x1f39, 0x1483: 0x1f11, 0x1484: 0x1d39, 0x1485: 0x1ce9,
+ 0x1486: 0x1f41, 0x1487: 0x1f49, 0x1488: 0x0040, 0x1489: 0x0040, 0x148a: 0x0040, 0x148b: 0x0040,
+ 0x148c: 0x0040, 0x148d: 0x0040, 0x148e: 0x0040, 0x148f: 0x0040, 0x1490: 0x0040, 0x1491: 0x0040,
+ 0x1492: 0x0040, 0x1493: 0x0040, 0x1494: 0x0040, 0x1495: 0x0040, 0x1496: 0x0040, 0x1497: 0x0040,
+ 0x1498: 0x0040, 0x1499: 0x0040, 0x149a: 0x0040, 0x149b: 0x0040, 0x149c: 0x0040, 0x149d: 0x0040,
+ 0x149e: 0x0040, 0x149f: 0x0040, 0x14a0: 0x0040, 0x14a1: 0x0040, 0x14a2: 0x0040, 0x14a3: 0x0040,
+ 0x14a4: 0x0040, 0x14a5: 0x0040, 0x14a6: 0x0040, 0x14a7: 0x0040, 0x14a8: 0x0040, 0x14a9: 0x0040,
+ 0x14aa: 0x0040, 0x14ab: 0x0040, 0x14ac: 0x0040, 0x14ad: 0x0040, 0x14ae: 0x0040, 0x14af: 0x0040,
+ 0x14b0: 0x1f51, 0x14b1: 0x1f59, 0x14b2: 0x1f61, 0x14b3: 0x1f69, 0x14b4: 0x1f71, 0x14b5: 0x1f79,
+ 0x14b6: 0x1f81, 0x14b7: 0x1f89, 0x14b8: 0x1f91, 0x14b9: 0x1f99, 0x14ba: 0x1fa2, 0x14bb: 0x1faa,
+ 0x14bc: 0x1fb1, 0x14bd: 0x0018, 0x14be: 0x0040, 0x14bf: 0x0040,
+ // Block 0x53, offset 0x14c0
+ 0x14c0: 0x33c0, 0x14c1: 0x33c0, 0x14c2: 0x33c0, 0x14c3: 0x33c0, 0x14c4: 0x33c0, 0x14c5: 0x33c0,
+ 0x14c6: 0x33c0, 0x14c7: 0x33c0, 0x14c8: 0x33c0, 0x14c9: 0x33c0, 0x14ca: 0x33c0, 0x14cb: 0x33c0,
+ 0x14cc: 0x33c0, 0x14cd: 0x33c0, 0x14ce: 0x33c0, 0x14cf: 0x33c0, 0x14d0: 0x1fba, 0x14d1: 0x7d8d,
+ 0x14d2: 0x0040, 0x14d3: 0x1fc2, 0x14d4: 0x0122, 0x14d5: 0x1fca, 0x14d6: 0x1fd2, 0x14d7: 0x7dad,
+ 0x14d8: 0x7dcd, 0x14d9: 0x0040, 0x14da: 0x0040, 0x14db: 0x0040, 0x14dc: 0x0040, 0x14dd: 0x0040,
+ 0x14de: 0x0040, 0x14df: 0x0040, 0x14e0: 0x3308, 0x14e1: 0x3308, 0x14e2: 0x3308, 0x14e3: 0x3308,
+ 0x14e4: 0x3308, 0x14e5: 0x3308, 0x14e6: 0x3308, 0x14e7: 0x3308, 0x14e8: 0x3308, 0x14e9: 0x3308,
+ 0x14ea: 0x3308, 0x14eb: 0x3308, 0x14ec: 0x3308, 0x14ed: 0x3308, 0x14ee: 0x3308, 0x14ef: 0x3308,
+ 0x14f0: 0x0040, 0x14f1: 0x7ded, 0x14f2: 0x7e0d, 0x14f3: 0x1fda, 0x14f4: 0x1fda, 0x14f5: 0x072a,
+ 0x14f6: 0x0732, 0x14f7: 0x1fe2, 0x14f8: 0x1fea, 0x14f9: 0x7e2d, 0x14fa: 0x7e4d, 0x14fb: 0x7e6d,
+ 0x14fc: 0x7e2d, 0x14fd: 0x7e8d, 0x14fe: 0x7ead, 0x14ff: 0x7e8d,
+ // Block 0x54, offset 0x1500
+ 0x1500: 0x7ecd, 0x1501: 0x7eed, 0x1502: 0x7f0d, 0x1503: 0x7eed, 0x1504: 0x7f2d, 0x1505: 0x0018,
+ 0x1506: 0x0018, 0x1507: 0x1ff2, 0x1508: 0x1ffa, 0x1509: 0x7f4e, 0x150a: 0x7f6e, 0x150b: 0x7f8e,
+ 0x150c: 0x7fae, 0x150d: 0x1fda, 0x150e: 0x1fda, 0x150f: 0x1fda, 0x1510: 0x1fba, 0x1511: 0x7fcd,
+ 0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0122, 0x1515: 0x1fc2, 0x1516: 0x1fd2, 0x1517: 0x1fca,
+ 0x1518: 0x7fed, 0x1519: 0x072a, 0x151a: 0x0732, 0x151b: 0x1fe2, 0x151c: 0x1fea, 0x151d: 0x7ecd,
+ 0x151e: 0x7f2d, 0x151f: 0x2002, 0x1520: 0x200a, 0x1521: 0x2012, 0x1522: 0x071a, 0x1523: 0x2019,
+ 0x1524: 0x2022, 0x1525: 0x202a, 0x1526: 0x0722, 0x1527: 0x0040, 0x1528: 0x2032, 0x1529: 0x203a,
+ 0x152a: 0x2042, 0x152b: 0x204a, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,
+ 0x1530: 0x800e, 0x1531: 0x2051, 0x1532: 0x802e, 0x1533: 0x0808, 0x1534: 0x804e, 0x1535: 0x0040,
+ 0x1536: 0x806e, 0x1537: 0x2059, 0x1538: 0x808e, 0x1539: 0x2061, 0x153a: 0x80ae, 0x153b: 0x2069,
+ 0x153c: 0x80ce, 0x153d: 0x2071, 0x153e: 0x80ee, 0x153f: 0x2079,
+ // Block 0x55, offset 0x1540
+ 0x1540: 0x2081, 0x1541: 0x2089, 0x1542: 0x2089, 0x1543: 0x2091, 0x1544: 0x2091, 0x1545: 0x2099,
+ 0x1546: 0x2099, 0x1547: 0x20a1, 0x1548: 0x20a1, 0x1549: 0x20a9, 0x154a: 0x20a9, 0x154b: 0x20a9,
+ 0x154c: 0x20a9, 0x154d: 0x20b1, 0x154e: 0x20b1, 0x154f: 0x20b9, 0x1550: 0x20b9, 0x1551: 0x20b9,
+ 0x1552: 0x20b9, 0x1553: 0x20c1, 0x1554: 0x20c1, 0x1555: 0x20c9, 0x1556: 0x20c9, 0x1557: 0x20c9,
+ 0x1558: 0x20c9, 0x1559: 0x20d1, 0x155a: 0x20d1, 0x155b: 0x20d1, 0x155c: 0x20d1, 0x155d: 0x20d9,
+ 0x155e: 0x20d9, 0x155f: 0x20d9, 0x1560: 0x20d9, 0x1561: 0x20e1, 0x1562: 0x20e1, 0x1563: 0x20e1,
+ 0x1564: 0x20e1, 0x1565: 0x20e9, 0x1566: 0x20e9, 0x1567: 0x20e9, 0x1568: 0x20e9, 0x1569: 0x20f1,
+ 0x156a: 0x20f1, 0x156b: 0x20f9, 0x156c: 0x20f9, 0x156d: 0x2101, 0x156e: 0x2101, 0x156f: 0x2109,
+ 0x1570: 0x2109, 0x1571: 0x2111, 0x1572: 0x2111, 0x1573: 0x2111, 0x1574: 0x2111, 0x1575: 0x2119,
+ 0x1576: 0x2119, 0x1577: 0x2119, 0x1578: 0x2119, 0x1579: 0x2121, 0x157a: 0x2121, 0x157b: 0x2121,
+ 0x157c: 0x2121, 0x157d: 0x2129, 0x157e: 0x2129, 0x157f: 0x2129,
+ // Block 0x56, offset 0x1580
+ 0x1580: 0x2129, 0x1581: 0x2131, 0x1582: 0x2131, 0x1583: 0x2131, 0x1584: 0x2131, 0x1585: 0x2139,
+ 0x1586: 0x2139, 0x1587: 0x2139, 0x1588: 0x2139, 0x1589: 0x2141, 0x158a: 0x2141, 0x158b: 0x2141,
+ 0x158c: 0x2141, 0x158d: 0x2149, 0x158e: 0x2149, 0x158f: 0x2149, 0x1590: 0x2149, 0x1591: 0x2151,
+ 0x1592: 0x2151, 0x1593: 0x2151, 0x1594: 0x2151, 0x1595: 0x2159, 0x1596: 0x2159, 0x1597: 0x2159,
+ 0x1598: 0x2159, 0x1599: 0x2161, 0x159a: 0x2161, 0x159b: 0x2161, 0x159c: 0x2161, 0x159d: 0x2169,
+ 0x159e: 0x2169, 0x159f: 0x2169, 0x15a0: 0x2169, 0x15a1: 0x2171, 0x15a2: 0x2171, 0x15a3: 0x2171,
+ 0x15a4: 0x2171, 0x15a5: 0x2179, 0x15a6: 0x2179, 0x15a7: 0x2179, 0x15a8: 0x2179, 0x15a9: 0x2181,
+ 0x15aa: 0x2181, 0x15ab: 0x2181, 0x15ac: 0x2181, 0x15ad: 0x2189, 0x15ae: 0x2189, 0x15af: 0x1701,
+ 0x15b0: 0x1701, 0x15b1: 0x2191, 0x15b2: 0x2191, 0x15b3: 0x2191, 0x15b4: 0x2191, 0x15b5: 0x2199,
+ 0x15b6: 0x2199, 0x15b7: 0x21a1, 0x15b8: 0x21a1, 0x15b9: 0x21a9, 0x15ba: 0x21a9, 0x15bb: 0x21b1,
+ 0x15bc: 0x21b1, 0x15bd: 0x0040, 0x15be: 0x0040, 0x15bf: 0x03c0,
+ // Block 0x57, offset 0x15c0
+ 0x15c0: 0x0040, 0x15c1: 0x1fca, 0x15c2: 0x21ba, 0x15c3: 0x2002, 0x15c4: 0x203a, 0x15c5: 0x2042,
+ 0x15c6: 0x200a, 0x15c7: 0x21c2, 0x15c8: 0x072a, 0x15c9: 0x0732, 0x15ca: 0x2012, 0x15cb: 0x071a,
+ 0x15cc: 0x1fba, 0x15cd: 0x2019, 0x15ce: 0x0961, 0x15cf: 0x21ca, 0x15d0: 0x06e1, 0x15d1: 0x0049,
+ 0x15d2: 0x0029, 0x15d3: 0x0031, 0x15d4: 0x06e9, 0x15d5: 0x06f1, 0x15d6: 0x06f9, 0x15d7: 0x0701,
+ 0x15d8: 0x0709, 0x15d9: 0x0711, 0x15da: 0x1fc2, 0x15db: 0x0122, 0x15dc: 0x2022, 0x15dd: 0x0722,
+ 0x15de: 0x202a, 0x15df: 0x1fd2, 0x15e0: 0x204a, 0x15e1: 0x0019, 0x15e2: 0x02e9, 0x15e3: 0x03d9,
+ 0x15e4: 0x02f1, 0x15e5: 0x02f9, 0x15e6: 0x03f1, 0x15e7: 0x0309, 0x15e8: 0x00a9, 0x15e9: 0x0311,
+ 0x15ea: 0x00b1, 0x15eb: 0x0319, 0x15ec: 0x0101, 0x15ed: 0x0321, 0x15ee: 0x0329, 0x15ef: 0x0051,
+ 0x15f0: 0x0339, 0x15f1: 0x0751, 0x15f2: 0x00b9, 0x15f3: 0x0089, 0x15f4: 0x0341, 0x15f5: 0x0349,
+ 0x15f6: 0x0391, 0x15f7: 0x00c1, 0x15f8: 0x0109, 0x15f9: 0x00c9, 0x15fa: 0x04b1, 0x15fb: 0x1ff2,
+ 0x15fc: 0x2032, 0x15fd: 0x1ffa, 0x15fe: 0x21d2, 0x15ff: 0x1fda,
+ // Block 0x58, offset 0x1600
+ 0x1600: 0x0672, 0x1601: 0x0019, 0x1602: 0x02e9, 0x1603: 0x03d9, 0x1604: 0x02f1, 0x1605: 0x02f9,
+ 0x1606: 0x03f1, 0x1607: 0x0309, 0x1608: 0x00a9, 0x1609: 0x0311, 0x160a: 0x00b1, 0x160b: 0x0319,
+ 0x160c: 0x0101, 0x160d: 0x0321, 0x160e: 0x0329, 0x160f: 0x0051, 0x1610: 0x0339, 0x1611: 0x0751,
+ 0x1612: 0x00b9, 0x1613: 0x0089, 0x1614: 0x0341, 0x1615: 0x0349, 0x1616: 0x0391, 0x1617: 0x00c1,
+ 0x1618: 0x0109, 0x1619: 0x00c9, 0x161a: 0x04b1, 0x161b: 0x1fe2, 0x161c: 0x21da, 0x161d: 0x1fea,
+ 0x161e: 0x21e2, 0x161f: 0x810d, 0x1620: 0x812d, 0x1621: 0x0961, 0x1622: 0x814d, 0x1623: 0x814d,
+ 0x1624: 0x816d, 0x1625: 0x818d, 0x1626: 0x81ad, 0x1627: 0x81cd, 0x1628: 0x81ed, 0x1629: 0x820d,
+ 0x162a: 0x822d, 0x162b: 0x824d, 0x162c: 0x826d, 0x162d: 0x828d, 0x162e: 0x82ad, 0x162f: 0x82cd,
+ 0x1630: 0x82ed, 0x1631: 0x830d, 0x1632: 0x832d, 0x1633: 0x834d, 0x1634: 0x836d, 0x1635: 0x838d,
+ 0x1636: 0x83ad, 0x1637: 0x83cd, 0x1638: 0x83ed, 0x1639: 0x840d, 0x163a: 0x842d, 0x163b: 0x844d,
+ 0x163c: 0x81ed, 0x163d: 0x846d, 0x163e: 0x848d, 0x163f: 0x824d,
+ // Block 0x59, offset 0x1640
+ 0x1640: 0x84ad, 0x1641: 0x84cd, 0x1642: 0x84ed, 0x1643: 0x850d, 0x1644: 0x852d, 0x1645: 0x854d,
+ 0x1646: 0x856d, 0x1647: 0x858d, 0x1648: 0x850d, 0x1649: 0x85ad, 0x164a: 0x850d, 0x164b: 0x85cd,
+ 0x164c: 0x85cd, 0x164d: 0x85ed, 0x164e: 0x85ed, 0x164f: 0x860d, 0x1650: 0x854d, 0x1651: 0x862d,
+ 0x1652: 0x864d, 0x1653: 0x862d, 0x1654: 0x866d, 0x1655: 0x864d, 0x1656: 0x868d, 0x1657: 0x868d,
+ 0x1658: 0x86ad, 0x1659: 0x86ad, 0x165a: 0x86cd, 0x165b: 0x86cd, 0x165c: 0x864d, 0x165d: 0x814d,
+ 0x165e: 0x86ed, 0x165f: 0x870d, 0x1660: 0x0040, 0x1661: 0x872d, 0x1662: 0x874d, 0x1663: 0x876d,
+ 0x1664: 0x878d, 0x1665: 0x876d, 0x1666: 0x87ad, 0x1667: 0x87cd, 0x1668: 0x87ed, 0x1669: 0x87ed,
+ 0x166a: 0x880d, 0x166b: 0x880d, 0x166c: 0x882d, 0x166d: 0x882d, 0x166e: 0x880d, 0x166f: 0x880d,
+ 0x1670: 0x884d, 0x1671: 0x886d, 0x1672: 0x888d, 0x1673: 0x88ad, 0x1674: 0x88cd, 0x1675: 0x88ed,
+ 0x1676: 0x88ed, 0x1677: 0x88ed, 0x1678: 0x890d, 0x1679: 0x890d, 0x167a: 0x890d, 0x167b: 0x890d,
+ 0x167c: 0x87ed, 0x167d: 0x87ed, 0x167e: 0x87ed, 0x167f: 0x0040,
+ // Block 0x5a, offset 0x1680
+ 0x1680: 0x0040, 0x1681: 0x0040, 0x1682: 0x874d, 0x1683: 0x872d, 0x1684: 0x892d, 0x1685: 0x872d,
+ 0x1686: 0x874d, 0x1687: 0x872d, 0x1688: 0x0040, 0x1689: 0x0040, 0x168a: 0x894d, 0x168b: 0x874d,
+ 0x168c: 0x896d, 0x168d: 0x892d, 0x168e: 0x896d, 0x168f: 0x874d, 0x1690: 0x0040, 0x1691: 0x0040,
+ 0x1692: 0x898d, 0x1693: 0x89ad, 0x1694: 0x88ad, 0x1695: 0x896d, 0x1696: 0x892d, 0x1697: 0x896d,
+ 0x1698: 0x0040, 0x1699: 0x0040, 0x169a: 0x89cd, 0x169b: 0x89ed, 0x169c: 0x89cd, 0x169d: 0x0040,
+ 0x169e: 0x0040, 0x169f: 0x0040, 0x16a0: 0x21e9, 0x16a1: 0x21f1, 0x16a2: 0x21f9, 0x16a3: 0x8a0e,
+ 0x16a4: 0x2201, 0x16a5: 0x2209, 0x16a6: 0x8a2d, 0x16a7: 0x0040, 0x16a8: 0x8a4d, 0x16a9: 0x8a6d,
+ 0x16aa: 0x8a8d, 0x16ab: 0x8a6d, 0x16ac: 0x8aad, 0x16ad: 0x8acd, 0x16ae: 0x8aed, 0x16af: 0x0040,
+ 0x16b0: 0x0040, 0x16b1: 0x0040, 0x16b2: 0x0040, 0x16b3: 0x0040, 0x16b4: 0x0040, 0x16b5: 0x0040,
+ 0x16b6: 0x0040, 0x16b7: 0x0040, 0x16b8: 0x0040, 0x16b9: 0x0340, 0x16ba: 0x0340, 0x16bb: 0x0340,
+ 0x16bc: 0x0040, 0x16bd: 0x0040, 0x16be: 0x0040, 0x16bf: 0x0040,
+ // Block 0x5b, offset 0x16c0
+ 0x16c0: 0x0a08, 0x16c1: 0x0a08, 0x16c2: 0x0a08, 0x16c3: 0x0a08, 0x16c4: 0x0a08, 0x16c5: 0x0c08,
+ 0x16c6: 0x0808, 0x16c7: 0x0c08, 0x16c8: 0x0818, 0x16c9: 0x0c08, 0x16ca: 0x0c08, 0x16cb: 0x0808,
+ 0x16cc: 0x0808, 0x16cd: 0x0908, 0x16ce: 0x0c08, 0x16cf: 0x0c08, 0x16d0: 0x0c08, 0x16d1: 0x0c08,
+ 0x16d2: 0x0c08, 0x16d3: 0x0a08, 0x16d4: 0x0a08, 0x16d5: 0x0a08, 0x16d6: 0x0a08, 0x16d7: 0x0908,
+ 0x16d8: 0x0a08, 0x16d9: 0x0a08, 0x16da: 0x0a08, 0x16db: 0x0a08, 0x16dc: 0x0a08, 0x16dd: 0x0c08,
+ 0x16de: 0x0a08, 0x16df: 0x0a08, 0x16e0: 0x0a08, 0x16e1: 0x0c08, 0x16e2: 0x0808, 0x16e3: 0x0808,
+ 0x16e4: 0x0c08, 0x16e5: 0x3308, 0x16e6: 0x3308, 0x16e7: 0x0040, 0x16e8: 0x0040, 0x16e9: 0x0040,
+ 0x16ea: 0x0040, 0x16eb: 0x0a18, 0x16ec: 0x0a18, 0x16ed: 0x0a18, 0x16ee: 0x0a18, 0x16ef: 0x0c18,
+ 0x16f0: 0x0818, 0x16f1: 0x0818, 0x16f2: 0x0818, 0x16f3: 0x0818, 0x16f4: 0x0818, 0x16f5: 0x0818,
+ 0x16f6: 0x0818, 0x16f7: 0x0040, 0x16f8: 0x0040, 0x16f9: 0x0040, 0x16fa: 0x0040, 0x16fb: 0x0040,
+ 0x16fc: 0x0040, 0x16fd: 0x0040, 0x16fe: 0x0040, 0x16ff: 0x0040,
+ // Block 0x5c, offset 0x1700
+ 0x1700: 0x0a08, 0x1701: 0x0c08, 0x1702: 0x0a08, 0x1703: 0x0c08, 0x1704: 0x0c08, 0x1705: 0x0c08,
+ 0x1706: 0x0a08, 0x1707: 0x0a08, 0x1708: 0x0a08, 0x1709: 0x0c08, 0x170a: 0x0a08, 0x170b: 0x0a08,
+ 0x170c: 0x0c08, 0x170d: 0x0a08, 0x170e: 0x0c08, 0x170f: 0x0c08, 0x1710: 0x0a08, 0x1711: 0x0c08,
+ 0x1712: 0x0040, 0x1713: 0x0040, 0x1714: 0x0040, 0x1715: 0x0040, 0x1716: 0x0040, 0x1717: 0x0040,
+ 0x1718: 0x0040, 0x1719: 0x0818, 0x171a: 0x0818, 0x171b: 0x0818, 0x171c: 0x0818, 0x171d: 0x0040,
+ 0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0x0040, 0x1721: 0x0040, 0x1722: 0x0040, 0x1723: 0x0040,
+ 0x1724: 0x0040, 0x1725: 0x0040, 0x1726: 0x0040, 0x1727: 0x0040, 0x1728: 0x0040, 0x1729: 0x0c18,
+ 0x172a: 0x0c18, 0x172b: 0x0c18, 0x172c: 0x0c18, 0x172d: 0x0a18, 0x172e: 0x0a18, 0x172f: 0x0818,
+ 0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040,
+ 0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0040, 0x173a: 0x0040, 0x173b: 0x0040,
+ 0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,
+ // Block 0x5d, offset 0x1740
+ 0x1740: 0x3308, 0x1741: 0x3308, 0x1742: 0x3008, 0x1743: 0x3008, 0x1744: 0x0040, 0x1745: 0x0008,
+ 0x1746: 0x0008, 0x1747: 0x0008, 0x1748: 0x0008, 0x1749: 0x0008, 0x174a: 0x0008, 0x174b: 0x0008,
+ 0x174c: 0x0008, 0x174d: 0x0040, 0x174e: 0x0040, 0x174f: 0x0008, 0x1750: 0x0008, 0x1751: 0x0040,
+ 0x1752: 0x0040, 0x1753: 0x0008, 0x1754: 0x0008, 0x1755: 0x0008, 0x1756: 0x0008, 0x1757: 0x0008,
+ 0x1758: 0x0008, 0x1759: 0x0008, 0x175a: 0x0008, 0x175b: 0x0008, 0x175c: 0x0008, 0x175d: 0x0008,
+ 0x175e: 0x0008, 0x175f: 0x0008, 0x1760: 0x0008, 0x1761: 0x0008, 0x1762: 0x0008, 0x1763: 0x0008,
+ 0x1764: 0x0008, 0x1765: 0x0008, 0x1766: 0x0008, 0x1767: 0x0008, 0x1768: 0x0008, 0x1769: 0x0040,
+ 0x176a: 0x0008, 0x176b: 0x0008, 0x176c: 0x0008, 0x176d: 0x0008, 0x176e: 0x0008, 0x176f: 0x0008,
+ 0x1770: 0x0008, 0x1771: 0x0040, 0x1772: 0x0008, 0x1773: 0x0008, 0x1774: 0x0040, 0x1775: 0x0008,
+ 0x1776: 0x0008, 0x1777: 0x0008, 0x1778: 0x0008, 0x1779: 0x0008, 0x177a: 0x0040, 0x177b: 0x3308,
+ 0x177c: 0x3308, 0x177d: 0x0008, 0x177e: 0x3008, 0x177f: 0x3008,
+ // Block 0x5e, offset 0x1780
+ 0x1780: 0x3308, 0x1781: 0x3008, 0x1782: 0x3008, 0x1783: 0x3008, 0x1784: 0x3008, 0x1785: 0x0040,
+ 0x1786: 0x0040, 0x1787: 0x3008, 0x1788: 0x3008, 0x1789: 0x0040, 0x178a: 0x0040, 0x178b: 0x3008,
+ 0x178c: 0x3008, 0x178d: 0x3808, 0x178e: 0x0040, 0x178f: 0x0040, 0x1790: 0x0008, 0x1791: 0x0040,
+ 0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x3008,
+ 0x1798: 0x0040, 0x1799: 0x0040, 0x179a: 0x0040, 0x179b: 0x0040, 0x179c: 0x0040, 0x179d: 0x0008,
+ 0x179e: 0x0008, 0x179f: 0x0008, 0x17a0: 0x0008, 0x17a1: 0x0008, 0x17a2: 0x3008, 0x17a3: 0x3008,
+ 0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x3308, 0x17a7: 0x3308, 0x17a8: 0x3308, 0x17a9: 0x3308,
+ 0x17aa: 0x3308, 0x17ab: 0x3308, 0x17ac: 0x3308, 0x17ad: 0x0040, 0x17ae: 0x0040, 0x17af: 0x0040,
+ 0x17b0: 0x3308, 0x17b1: 0x3308, 0x17b2: 0x3308, 0x17b3: 0x3308, 0x17b4: 0x3308, 0x17b5: 0x0040,
+ 0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040,
+ 0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040,
+ // Block 0x5f, offset 0x17c0
+ 0x17c0: 0x0008, 0x17c1: 0x0008, 0x17c2: 0x0008, 0x17c3: 0x0008, 0x17c4: 0x0008, 0x17c5: 0x0008,
+ 0x17c6: 0x0008, 0x17c7: 0x0040, 0x17c8: 0x0040, 0x17c9: 0x0008, 0x17ca: 0x0040, 0x17cb: 0x0040,
+ 0x17cc: 0x0008, 0x17cd: 0x0008, 0x17ce: 0x0008, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0008,
+ 0x17d2: 0x0008, 0x17d3: 0x0008, 0x17d4: 0x0040, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0040,
+ 0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008,
+ 0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008,
+ 0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0008,
+ 0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008,
+ 0x17f0: 0x3008, 0x17f1: 0x3008, 0x17f2: 0x3008, 0x17f3: 0x3008, 0x17f4: 0x3008, 0x17f5: 0x3008,
+ 0x17f6: 0x0040, 0x17f7: 0x3008, 0x17f8: 0x3008, 0x17f9: 0x0040, 0x17fa: 0x0040, 0x17fb: 0x3308,
+ 0x17fc: 0x3308, 0x17fd: 0x3808, 0x17fe: 0x3b08, 0x17ff: 0x0008,
+ // Block 0x60, offset 0x1800
+ 0x1800: 0x0019, 0x1801: 0x02e9, 0x1802: 0x03d9, 0x1803: 0x02f1, 0x1804: 0x02f9, 0x1805: 0x03f1,
+ 0x1806: 0x0309, 0x1807: 0x00a9, 0x1808: 0x0311, 0x1809: 0x00b1, 0x180a: 0x0319, 0x180b: 0x0101,
+ 0x180c: 0x0321, 0x180d: 0x0329, 0x180e: 0x0051, 0x180f: 0x0339, 0x1810: 0x0751, 0x1811: 0x00b9,
+ 0x1812: 0x0089, 0x1813: 0x0341, 0x1814: 0x0349, 0x1815: 0x0391, 0x1816: 0x00c1, 0x1817: 0x0109,
+ 0x1818: 0x00c9, 0x1819: 0x04b1, 0x181a: 0x0019, 0x181b: 0x02e9, 0x181c: 0x03d9, 0x181d: 0x02f1,
+ 0x181e: 0x02f9, 0x181f: 0x03f1, 0x1820: 0x0309, 0x1821: 0x00a9, 0x1822: 0x0311, 0x1823: 0x00b1,
+ 0x1824: 0x0319, 0x1825: 0x0101, 0x1826: 0x0321, 0x1827: 0x0329, 0x1828: 0x0051, 0x1829: 0x0339,
+ 0x182a: 0x0751, 0x182b: 0x00b9, 0x182c: 0x0089, 0x182d: 0x0341, 0x182e: 0x0349, 0x182f: 0x0391,
+ 0x1830: 0x00c1, 0x1831: 0x0109, 0x1832: 0x00c9, 0x1833: 0x04b1, 0x1834: 0x0019, 0x1835: 0x02e9,
+ 0x1836: 0x03d9, 0x1837: 0x02f1, 0x1838: 0x02f9, 0x1839: 0x03f1, 0x183a: 0x0309, 0x183b: 0x00a9,
+ 0x183c: 0x0311, 0x183d: 0x00b1, 0x183e: 0x0319, 0x183f: 0x0101,
+ // Block 0x61, offset 0x1840
+ 0x1840: 0x0321, 0x1841: 0x0329, 0x1842: 0x0051, 0x1843: 0x0339, 0x1844: 0x0751, 0x1845: 0x00b9,
+ 0x1846: 0x0089, 0x1847: 0x0341, 0x1848: 0x0349, 0x1849: 0x0391, 0x184a: 0x00c1, 0x184b: 0x0109,
+ 0x184c: 0x00c9, 0x184d: 0x04b1, 0x184e: 0x0019, 0x184f: 0x02e9, 0x1850: 0x03d9, 0x1851: 0x02f1,
+ 0x1852: 0x02f9, 0x1853: 0x03f1, 0x1854: 0x0309, 0x1855: 0x0040, 0x1856: 0x0311, 0x1857: 0x00b1,
+ 0x1858: 0x0319, 0x1859: 0x0101, 0x185a: 0x0321, 0x185b: 0x0329, 0x185c: 0x0051, 0x185d: 0x0339,
+ 0x185e: 0x0751, 0x185f: 0x00b9, 0x1860: 0x0089, 0x1861: 0x0341, 0x1862: 0x0349, 0x1863: 0x0391,
+ 0x1864: 0x00c1, 0x1865: 0x0109, 0x1866: 0x00c9, 0x1867: 0x04b1, 0x1868: 0x0019, 0x1869: 0x02e9,
+ 0x186a: 0x03d9, 0x186b: 0x02f1, 0x186c: 0x02f9, 0x186d: 0x03f1, 0x186e: 0x0309, 0x186f: 0x00a9,
+ 0x1870: 0x0311, 0x1871: 0x00b1, 0x1872: 0x0319, 0x1873: 0x0101, 0x1874: 0x0321, 0x1875: 0x0329,
+ 0x1876: 0x0051, 0x1877: 0x0339, 0x1878: 0x0751, 0x1879: 0x00b9, 0x187a: 0x0089, 0x187b: 0x0341,
+ 0x187c: 0x0349, 0x187d: 0x0391, 0x187e: 0x00c1, 0x187f: 0x0109,
+ // Block 0x62, offset 0x1880
+ 0x1880: 0x00c9, 0x1881: 0x04b1, 0x1882: 0x0019, 0x1883: 0x02e9, 0x1884: 0x03d9, 0x1885: 0x02f1,
+ 0x1886: 0x02f9, 0x1887: 0x03f1, 0x1888: 0x0309, 0x1889: 0x00a9, 0x188a: 0x0311, 0x188b: 0x00b1,
+ 0x188c: 0x0319, 0x188d: 0x0101, 0x188e: 0x0321, 0x188f: 0x0329, 0x1890: 0x0051, 0x1891: 0x0339,
+ 0x1892: 0x0751, 0x1893: 0x00b9, 0x1894: 0x0089, 0x1895: 0x0341, 0x1896: 0x0349, 0x1897: 0x0391,
+ 0x1898: 0x00c1, 0x1899: 0x0109, 0x189a: 0x00c9, 0x189b: 0x04b1, 0x189c: 0x0019, 0x189d: 0x0040,
+ 0x189e: 0x03d9, 0x189f: 0x02f1, 0x18a0: 0x0040, 0x18a1: 0x0040, 0x18a2: 0x0309, 0x18a3: 0x0040,
+ 0x18a4: 0x0040, 0x18a5: 0x00b1, 0x18a6: 0x0319, 0x18a7: 0x0040, 0x18a8: 0x0040, 0x18a9: 0x0329,
+ 0x18aa: 0x0051, 0x18ab: 0x0339, 0x18ac: 0x0751, 0x18ad: 0x0040, 0x18ae: 0x0089, 0x18af: 0x0341,
+ 0x18b0: 0x0349, 0x18b1: 0x0391, 0x18b2: 0x00c1, 0x18b3: 0x0109, 0x18b4: 0x00c9, 0x18b5: 0x04b1,
+ 0x18b6: 0x0019, 0x18b7: 0x02e9, 0x18b8: 0x03d9, 0x18b9: 0x02f1, 0x18ba: 0x0040, 0x18bb: 0x03f1,
+ 0x18bc: 0x0040, 0x18bd: 0x00a9, 0x18be: 0x0311, 0x18bf: 0x00b1,
+ // Block 0x63, offset 0x18c0
+ 0x18c0: 0x0319, 0x18c1: 0x0101, 0x18c2: 0x0321, 0x18c3: 0x0329, 0x18c4: 0x0040, 0x18c5: 0x0339,
+ 0x18c6: 0x0751, 0x18c7: 0x00b9, 0x18c8: 0x0089, 0x18c9: 0x0341, 0x18ca: 0x0349, 0x18cb: 0x0391,
+ 0x18cc: 0x00c1, 0x18cd: 0x0109, 0x18ce: 0x00c9, 0x18cf: 0x04b1, 0x18d0: 0x0019, 0x18d1: 0x02e9,
+ 0x18d2: 0x03d9, 0x18d3: 0x02f1, 0x18d4: 0x02f9, 0x18d5: 0x03f1, 0x18d6: 0x0309, 0x18d7: 0x00a9,
+ 0x18d8: 0x0311, 0x18d9: 0x00b1, 0x18da: 0x0319, 0x18db: 0x0101, 0x18dc: 0x0321, 0x18dd: 0x0329,
+ 0x18de: 0x0051, 0x18df: 0x0339, 0x18e0: 0x0751, 0x18e1: 0x00b9, 0x18e2: 0x0089, 0x18e3: 0x0341,
+ 0x18e4: 0x0349, 0x18e5: 0x0391, 0x18e6: 0x00c1, 0x18e7: 0x0109, 0x18e8: 0x00c9, 0x18e9: 0x04b1,
+ 0x18ea: 0x0019, 0x18eb: 0x02e9, 0x18ec: 0x03d9, 0x18ed: 0x02f1, 0x18ee: 0x02f9, 0x18ef: 0x03f1,
+ 0x18f0: 0x0309, 0x18f1: 0x00a9, 0x18f2: 0x0311, 0x18f3: 0x00b1, 0x18f4: 0x0319, 0x18f5: 0x0101,
+ 0x18f6: 0x0321, 0x18f7: 0x0329, 0x18f8: 0x0051, 0x18f9: 0x0339, 0x18fa: 0x0751, 0x18fb: 0x00b9,
+ 0x18fc: 0x0089, 0x18fd: 0x0341, 0x18fe: 0x0349, 0x18ff: 0x0391,
+ // Block 0x64, offset 0x1900
+ 0x1900: 0x00c1, 0x1901: 0x0109, 0x1902: 0x00c9, 0x1903: 0x04b1, 0x1904: 0x0019, 0x1905: 0x02e9,
+ 0x1906: 0x0040, 0x1907: 0x02f1, 0x1908: 0x02f9, 0x1909: 0x03f1, 0x190a: 0x0309, 0x190b: 0x0040,
+ 0x190c: 0x0040, 0x190d: 0x00b1, 0x190e: 0x0319, 0x190f: 0x0101, 0x1910: 0x0321, 0x1911: 0x0329,
+ 0x1912: 0x0051, 0x1913: 0x0339, 0x1914: 0x0751, 0x1915: 0x0040, 0x1916: 0x0089, 0x1917: 0x0341,
+ 0x1918: 0x0349, 0x1919: 0x0391, 0x191a: 0x00c1, 0x191b: 0x0109, 0x191c: 0x00c9, 0x191d: 0x0040,
+ 0x191e: 0x0019, 0x191f: 0x02e9, 0x1920: 0x03d9, 0x1921: 0x02f1, 0x1922: 0x02f9, 0x1923: 0x03f1,
+ 0x1924: 0x0309, 0x1925: 0x00a9, 0x1926: 0x0311, 0x1927: 0x00b1, 0x1928: 0x0319, 0x1929: 0x0101,
+ 0x192a: 0x0321, 0x192b: 0x0329, 0x192c: 0x0051, 0x192d: 0x0339, 0x192e: 0x0751, 0x192f: 0x00b9,
+ 0x1930: 0x0089, 0x1931: 0x0341, 0x1932: 0x0349, 0x1933: 0x0391, 0x1934: 0x00c1, 0x1935: 0x0109,
+ 0x1936: 0x00c9, 0x1937: 0x04b1, 0x1938: 0x0019, 0x1939: 0x02e9, 0x193a: 0x0040, 0x193b: 0x02f1,
+ 0x193c: 0x02f9, 0x193d: 0x03f1, 0x193e: 0x0309, 0x193f: 0x0040,
+ // Block 0x65, offset 0x1940
+ 0x1940: 0x0311, 0x1941: 0x00b1, 0x1942: 0x0319, 0x1943: 0x0101, 0x1944: 0x0321, 0x1945: 0x0040,
+ 0x1946: 0x0051, 0x1947: 0x0040, 0x1948: 0x0040, 0x1949: 0x0040, 0x194a: 0x0089, 0x194b: 0x0341,
+ 0x194c: 0x0349, 0x194d: 0x0391, 0x194e: 0x00c1, 0x194f: 0x0109, 0x1950: 0x00c9, 0x1951: 0x0040,
+ 0x1952: 0x0019, 0x1953: 0x02e9, 0x1954: 0x03d9, 0x1955: 0x02f1, 0x1956: 0x02f9, 0x1957: 0x03f1,
+ 0x1958: 0x0309, 0x1959: 0x00a9, 0x195a: 0x0311, 0x195b: 0x00b1, 0x195c: 0x0319, 0x195d: 0x0101,
+ 0x195e: 0x0321, 0x195f: 0x0329, 0x1960: 0x0051, 0x1961: 0x0339, 0x1962: 0x0751, 0x1963: 0x00b9,
+ 0x1964: 0x0089, 0x1965: 0x0341, 0x1966: 0x0349, 0x1967: 0x0391, 0x1968: 0x00c1, 0x1969: 0x0109,
+ 0x196a: 0x00c9, 0x196b: 0x04b1, 0x196c: 0x0019, 0x196d: 0x02e9, 0x196e: 0x03d9, 0x196f: 0x02f1,
+ 0x1970: 0x02f9, 0x1971: 0x03f1, 0x1972: 0x0309, 0x1973: 0x00a9, 0x1974: 0x0311, 0x1975: 0x00b1,
+ 0x1976: 0x0319, 0x1977: 0x0101, 0x1978: 0x0321, 0x1979: 0x0329, 0x197a: 0x0051, 0x197b: 0x0339,
+ 0x197c: 0x0751, 0x197d: 0x00b9, 0x197e: 0x0089, 0x197f: 0x0341,
+ // Block 0x66, offset 0x1980
+ 0x1980: 0x0349, 0x1981: 0x0391, 0x1982: 0x00c1, 0x1983: 0x0109, 0x1984: 0x00c9, 0x1985: 0x04b1,
+ 0x1986: 0x0019, 0x1987: 0x02e9, 0x1988: 0x03d9, 0x1989: 0x02f1, 0x198a: 0x02f9, 0x198b: 0x03f1,
+ 0x198c: 0x0309, 0x198d: 0x00a9, 0x198e: 0x0311, 0x198f: 0x00b1, 0x1990: 0x0319, 0x1991: 0x0101,
+ 0x1992: 0x0321, 0x1993: 0x0329, 0x1994: 0x0051, 0x1995: 0x0339, 0x1996: 0x0751, 0x1997: 0x00b9,
+ 0x1998: 0x0089, 0x1999: 0x0341, 0x199a: 0x0349, 0x199b: 0x0391, 0x199c: 0x00c1, 0x199d: 0x0109,
+ 0x199e: 0x00c9, 0x199f: 0x04b1, 0x19a0: 0x0019, 0x19a1: 0x02e9, 0x19a2: 0x03d9, 0x19a3: 0x02f1,
+ 0x19a4: 0x02f9, 0x19a5: 0x03f1, 0x19a6: 0x0309, 0x19a7: 0x00a9, 0x19a8: 0x0311, 0x19a9: 0x00b1,
+ 0x19aa: 0x0319, 0x19ab: 0x0101, 0x19ac: 0x0321, 0x19ad: 0x0329, 0x19ae: 0x0051, 0x19af: 0x0339,
+ 0x19b0: 0x0751, 0x19b1: 0x00b9, 0x19b2: 0x0089, 0x19b3: 0x0341, 0x19b4: 0x0349, 0x19b5: 0x0391,
+ 0x19b6: 0x00c1, 0x19b7: 0x0109, 0x19b8: 0x00c9, 0x19b9: 0x04b1, 0x19ba: 0x0019, 0x19bb: 0x02e9,
+ 0x19bc: 0x03d9, 0x19bd: 0x02f1, 0x19be: 0x02f9, 0x19bf: 0x03f1,
+ // Block 0x67, offset 0x19c0
+ 0x19c0: 0x0309, 0x19c1: 0x00a9, 0x19c2: 0x0311, 0x19c3: 0x00b1, 0x19c4: 0x0319, 0x19c5: 0x0101,
+ 0x19c6: 0x0321, 0x19c7: 0x0329, 0x19c8: 0x0051, 0x19c9: 0x0339, 0x19ca: 0x0751, 0x19cb: 0x00b9,
+ 0x19cc: 0x0089, 0x19cd: 0x0341, 0x19ce: 0x0349, 0x19cf: 0x0391, 0x19d0: 0x00c1, 0x19d1: 0x0109,
+ 0x19d2: 0x00c9, 0x19d3: 0x04b1, 0x19d4: 0x0019, 0x19d5: 0x02e9, 0x19d6: 0x03d9, 0x19d7: 0x02f1,
+ 0x19d8: 0x02f9, 0x19d9: 0x03f1, 0x19da: 0x0309, 0x19db: 0x00a9, 0x19dc: 0x0311, 0x19dd: 0x00b1,
+ 0x19de: 0x0319, 0x19df: 0x0101, 0x19e0: 0x0321, 0x19e1: 0x0329, 0x19e2: 0x0051, 0x19e3: 0x0339,
+ 0x19e4: 0x0751, 0x19e5: 0x00b9, 0x19e6: 0x0089, 0x19e7: 0x0341, 0x19e8: 0x0349, 0x19e9: 0x0391,
+ 0x19ea: 0x00c1, 0x19eb: 0x0109, 0x19ec: 0x00c9, 0x19ed: 0x04b1, 0x19ee: 0x0019, 0x19ef: 0x02e9,
+ 0x19f0: 0x03d9, 0x19f1: 0x02f1, 0x19f2: 0x02f9, 0x19f3: 0x03f1, 0x19f4: 0x0309, 0x19f5: 0x00a9,
+ 0x19f6: 0x0311, 0x19f7: 0x00b1, 0x19f8: 0x0319, 0x19f9: 0x0101, 0x19fa: 0x0321, 0x19fb: 0x0329,
+ 0x19fc: 0x0051, 0x19fd: 0x0339, 0x19fe: 0x0751, 0x19ff: 0x00b9,
+ // Block 0x68, offset 0x1a00
+ 0x1a00: 0x0089, 0x1a01: 0x0341, 0x1a02: 0x0349, 0x1a03: 0x0391, 0x1a04: 0x00c1, 0x1a05: 0x0109,
+ 0x1a06: 0x00c9, 0x1a07: 0x04b1, 0x1a08: 0x0019, 0x1a09: 0x02e9, 0x1a0a: 0x03d9, 0x1a0b: 0x02f1,
+ 0x1a0c: 0x02f9, 0x1a0d: 0x03f1, 0x1a0e: 0x0309, 0x1a0f: 0x00a9, 0x1a10: 0x0311, 0x1a11: 0x00b1,
+ 0x1a12: 0x0319, 0x1a13: 0x0101, 0x1a14: 0x0321, 0x1a15: 0x0329, 0x1a16: 0x0051, 0x1a17: 0x0339,
+ 0x1a18: 0x0751, 0x1a19: 0x00b9, 0x1a1a: 0x0089, 0x1a1b: 0x0341, 0x1a1c: 0x0349, 0x1a1d: 0x0391,
+ 0x1a1e: 0x00c1, 0x1a1f: 0x0109, 0x1a20: 0x00c9, 0x1a21: 0x04b1, 0x1a22: 0x0019, 0x1a23: 0x02e9,
+ 0x1a24: 0x03d9, 0x1a25: 0x02f1, 0x1a26: 0x02f9, 0x1a27: 0x03f1, 0x1a28: 0x0309, 0x1a29: 0x00a9,
+ 0x1a2a: 0x0311, 0x1a2b: 0x00b1, 0x1a2c: 0x0319, 0x1a2d: 0x0101, 0x1a2e: 0x0321, 0x1a2f: 0x0329,
+ 0x1a30: 0x0051, 0x1a31: 0x0339, 0x1a32: 0x0751, 0x1a33: 0x00b9, 0x1a34: 0x0089, 0x1a35: 0x0341,
+ 0x1a36: 0x0349, 0x1a37: 0x0391, 0x1a38: 0x00c1, 0x1a39: 0x0109, 0x1a3a: 0x00c9, 0x1a3b: 0x04b1,
+ 0x1a3c: 0x0019, 0x1a3d: 0x02e9, 0x1a3e: 0x03d9, 0x1a3f: 0x02f1,
+ // Block 0x69, offset 0x1a40
+ 0x1a40: 0x02f9, 0x1a41: 0x03f1, 0x1a42: 0x0309, 0x1a43: 0x00a9, 0x1a44: 0x0311, 0x1a45: 0x00b1,
+ 0x1a46: 0x0319, 0x1a47: 0x0101, 0x1a48: 0x0321, 0x1a49: 0x0329, 0x1a4a: 0x0051, 0x1a4b: 0x0339,
+ 0x1a4c: 0x0751, 0x1a4d: 0x00b9, 0x1a4e: 0x0089, 0x1a4f: 0x0341, 0x1a50: 0x0349, 0x1a51: 0x0391,
+ 0x1a52: 0x00c1, 0x1a53: 0x0109, 0x1a54: 0x00c9, 0x1a55: 0x04b1, 0x1a56: 0x0019, 0x1a57: 0x02e9,
+ 0x1a58: 0x03d9, 0x1a59: 0x02f1, 0x1a5a: 0x02f9, 0x1a5b: 0x03f1, 0x1a5c: 0x0309, 0x1a5d: 0x00a9,
+ 0x1a5e: 0x0311, 0x1a5f: 0x00b1, 0x1a60: 0x0319, 0x1a61: 0x0101, 0x1a62: 0x0321, 0x1a63: 0x0329,
+ 0x1a64: 0x0051, 0x1a65: 0x0339, 0x1a66: 0x0751, 0x1a67: 0x00b9, 0x1a68: 0x0089, 0x1a69: 0x0341,
+ 0x1a6a: 0x0349, 0x1a6b: 0x0391, 0x1a6c: 0x00c1, 0x1a6d: 0x0109, 0x1a6e: 0x00c9, 0x1a6f: 0x04b1,
+ 0x1a70: 0x0019, 0x1a71: 0x02e9, 0x1a72: 0x03d9, 0x1a73: 0x02f1, 0x1a74: 0x02f9, 0x1a75: 0x03f1,
+ 0x1a76: 0x0309, 0x1a77: 0x00a9, 0x1a78: 0x0311, 0x1a79: 0x00b1, 0x1a7a: 0x0319, 0x1a7b: 0x0101,
+ 0x1a7c: 0x0321, 0x1a7d: 0x0329, 0x1a7e: 0x0051, 0x1a7f: 0x0339,
+ // Block 0x6a, offset 0x1a80
+ 0x1a80: 0x0751, 0x1a81: 0x00b9, 0x1a82: 0x0089, 0x1a83: 0x0341, 0x1a84: 0x0349, 0x1a85: 0x0391,
+ 0x1a86: 0x00c1, 0x1a87: 0x0109, 0x1a88: 0x00c9, 0x1a89: 0x04b1, 0x1a8a: 0x0019, 0x1a8b: 0x02e9,
+ 0x1a8c: 0x03d9, 0x1a8d: 0x02f1, 0x1a8e: 0x02f9, 0x1a8f: 0x03f1, 0x1a90: 0x0309, 0x1a91: 0x00a9,
+ 0x1a92: 0x0311, 0x1a93: 0x00b1, 0x1a94: 0x0319, 0x1a95: 0x0101, 0x1a96: 0x0321, 0x1a97: 0x0329,
+ 0x1a98: 0x0051, 0x1a99: 0x0339, 0x1a9a: 0x0751, 0x1a9b: 0x00b9, 0x1a9c: 0x0089, 0x1a9d: 0x0341,
+ 0x1a9e: 0x0349, 0x1a9f: 0x0391, 0x1aa0: 0x00c1, 0x1aa1: 0x0109, 0x1aa2: 0x00c9, 0x1aa3: 0x04b1,
+ 0x1aa4: 0x2279, 0x1aa5: 0x2281, 0x1aa6: 0x0040, 0x1aa7: 0x0040, 0x1aa8: 0x2289, 0x1aa9: 0x0399,
+ 0x1aaa: 0x03a1, 0x1aab: 0x03a9, 0x1aac: 0x2291, 0x1aad: 0x2299, 0x1aae: 0x22a1, 0x1aaf: 0x04d1,
+ 0x1ab0: 0x05f9, 0x1ab1: 0x22a9, 0x1ab2: 0x22b1, 0x1ab3: 0x22b9, 0x1ab4: 0x22c1, 0x1ab5: 0x22c9,
+ 0x1ab6: 0x22d1, 0x1ab7: 0x0799, 0x1ab8: 0x03c1, 0x1ab9: 0x04d1, 0x1aba: 0x22d9, 0x1abb: 0x22e1,
+ 0x1abc: 0x22e9, 0x1abd: 0x03b1, 0x1abe: 0x03b9, 0x1abf: 0x22f1,
+ // Block 0x6b, offset 0x1ac0
+ 0x1ac0: 0x0769, 0x1ac1: 0x22f9, 0x1ac2: 0x2289, 0x1ac3: 0x0399, 0x1ac4: 0x03a1, 0x1ac5: 0x03a9,
+ 0x1ac6: 0x2291, 0x1ac7: 0x2299, 0x1ac8: 0x22a1, 0x1ac9: 0x04d1, 0x1aca: 0x05f9, 0x1acb: 0x22a9,
+ 0x1acc: 0x22b1, 0x1acd: 0x22b9, 0x1ace: 0x22c1, 0x1acf: 0x22c9, 0x1ad0: 0x22d1, 0x1ad1: 0x0799,
+ 0x1ad2: 0x03c1, 0x1ad3: 0x22d9, 0x1ad4: 0x22d9, 0x1ad5: 0x22e1, 0x1ad6: 0x22e9, 0x1ad7: 0x03b1,
+ 0x1ad8: 0x03b9, 0x1ad9: 0x22f1, 0x1ada: 0x0769, 0x1adb: 0x2301, 0x1adc: 0x2291, 0x1add: 0x04d1,
+ 0x1ade: 0x22a9, 0x1adf: 0x03b1, 0x1ae0: 0x03c1, 0x1ae1: 0x0799, 0x1ae2: 0x2289, 0x1ae3: 0x0399,
+ 0x1ae4: 0x03a1, 0x1ae5: 0x03a9, 0x1ae6: 0x2291, 0x1ae7: 0x2299, 0x1ae8: 0x22a1, 0x1ae9: 0x04d1,
+ 0x1aea: 0x05f9, 0x1aeb: 0x22a9, 0x1aec: 0x22b1, 0x1aed: 0x22b9, 0x1aee: 0x22c1, 0x1aef: 0x22c9,
+ 0x1af0: 0x22d1, 0x1af1: 0x0799, 0x1af2: 0x03c1, 0x1af3: 0x04d1, 0x1af4: 0x22d9, 0x1af5: 0x22e1,
+ 0x1af6: 0x22e9, 0x1af7: 0x03b1, 0x1af8: 0x03b9, 0x1af9: 0x22f1, 0x1afa: 0x0769, 0x1afb: 0x22f9,
+ 0x1afc: 0x2289, 0x1afd: 0x0399, 0x1afe: 0x03a1, 0x1aff: 0x03a9,
+ // Block 0x6c, offset 0x1b00
+ 0x1b00: 0x2291, 0x1b01: 0x2299, 0x1b02: 0x22a1, 0x1b03: 0x04d1, 0x1b04: 0x05f9, 0x1b05: 0x22a9,
+ 0x1b06: 0x22b1, 0x1b07: 0x22b9, 0x1b08: 0x22c1, 0x1b09: 0x22c9, 0x1b0a: 0x22d1, 0x1b0b: 0x0799,
+ 0x1b0c: 0x03c1, 0x1b0d: 0x22d9, 0x1b0e: 0x22d9, 0x1b0f: 0x22e1, 0x1b10: 0x22e9, 0x1b11: 0x03b1,
+ 0x1b12: 0x03b9, 0x1b13: 0x22f1, 0x1b14: 0x0769, 0x1b15: 0x2301, 0x1b16: 0x2291, 0x1b17: 0x04d1,
+ 0x1b18: 0x22a9, 0x1b19: 0x03b1, 0x1b1a: 0x03c1, 0x1b1b: 0x0799, 0x1b1c: 0x2289, 0x1b1d: 0x0399,
+ 0x1b1e: 0x03a1, 0x1b1f: 0x03a9, 0x1b20: 0x2291, 0x1b21: 0x2299, 0x1b22: 0x22a1, 0x1b23: 0x04d1,
+ 0x1b24: 0x05f9, 0x1b25: 0x22a9, 0x1b26: 0x22b1, 0x1b27: 0x22b9, 0x1b28: 0x22c1, 0x1b29: 0x22c9,
+ 0x1b2a: 0x22d1, 0x1b2b: 0x0799, 0x1b2c: 0x03c1, 0x1b2d: 0x04d1, 0x1b2e: 0x22d9, 0x1b2f: 0x22e1,
+ 0x1b30: 0x22e9, 0x1b31: 0x03b1, 0x1b32: 0x03b9, 0x1b33: 0x22f1, 0x1b34: 0x0769, 0x1b35: 0x22f9,
+ 0x1b36: 0x2289, 0x1b37: 0x0399, 0x1b38: 0x03a1, 0x1b39: 0x03a9, 0x1b3a: 0x2291, 0x1b3b: 0x2299,
+ 0x1b3c: 0x22a1, 0x1b3d: 0x04d1, 0x1b3e: 0x05f9, 0x1b3f: 0x22a9,
+ // Block 0x6d, offset 0x1b40
+ 0x1b40: 0x22b1, 0x1b41: 0x22b9, 0x1b42: 0x22c1, 0x1b43: 0x22c9, 0x1b44: 0x22d1, 0x1b45: 0x0799,
+ 0x1b46: 0x03c1, 0x1b47: 0x22d9, 0x1b48: 0x22d9, 0x1b49: 0x22e1, 0x1b4a: 0x22e9, 0x1b4b: 0x03b1,
+ 0x1b4c: 0x03b9, 0x1b4d: 0x22f1, 0x1b4e: 0x0769, 0x1b4f: 0x2301, 0x1b50: 0x2291, 0x1b51: 0x04d1,
+ 0x1b52: 0x22a9, 0x1b53: 0x03b1, 0x1b54: 0x03c1, 0x1b55: 0x0799, 0x1b56: 0x2289, 0x1b57: 0x0399,
+ 0x1b58: 0x03a1, 0x1b59: 0x03a9, 0x1b5a: 0x2291, 0x1b5b: 0x2299, 0x1b5c: 0x22a1, 0x1b5d: 0x04d1,
+ 0x1b5e: 0x05f9, 0x1b5f: 0x22a9, 0x1b60: 0x22b1, 0x1b61: 0x22b9, 0x1b62: 0x22c1, 0x1b63: 0x22c9,
+ 0x1b64: 0x22d1, 0x1b65: 0x0799, 0x1b66: 0x03c1, 0x1b67: 0x04d1, 0x1b68: 0x22d9, 0x1b69: 0x22e1,
+ 0x1b6a: 0x22e9, 0x1b6b: 0x03b1, 0x1b6c: 0x03b9, 0x1b6d: 0x22f1, 0x1b6e: 0x0769, 0x1b6f: 0x22f9,
+ 0x1b70: 0x2289, 0x1b71: 0x0399, 0x1b72: 0x03a1, 0x1b73: 0x03a9, 0x1b74: 0x2291, 0x1b75: 0x2299,
+ 0x1b76: 0x22a1, 0x1b77: 0x04d1, 0x1b78: 0x05f9, 0x1b79: 0x22a9, 0x1b7a: 0x22b1, 0x1b7b: 0x22b9,
+ 0x1b7c: 0x22c1, 0x1b7d: 0x22c9, 0x1b7e: 0x22d1, 0x1b7f: 0x0799,
+ // Block 0x6e, offset 0x1b80
+ 0x1b80: 0x03c1, 0x1b81: 0x22d9, 0x1b82: 0x22d9, 0x1b83: 0x22e1, 0x1b84: 0x22e9, 0x1b85: 0x03b1,
+ 0x1b86: 0x03b9, 0x1b87: 0x22f1, 0x1b88: 0x0769, 0x1b89: 0x2301, 0x1b8a: 0x2291, 0x1b8b: 0x04d1,
+ 0x1b8c: 0x22a9, 0x1b8d: 0x03b1, 0x1b8e: 0x03c1, 0x1b8f: 0x0799, 0x1b90: 0x2289, 0x1b91: 0x0399,
+ 0x1b92: 0x03a1, 0x1b93: 0x03a9, 0x1b94: 0x2291, 0x1b95: 0x2299, 0x1b96: 0x22a1, 0x1b97: 0x04d1,
+ 0x1b98: 0x05f9, 0x1b99: 0x22a9, 0x1b9a: 0x22b1, 0x1b9b: 0x22b9, 0x1b9c: 0x22c1, 0x1b9d: 0x22c9,
+ 0x1b9e: 0x22d1, 0x1b9f: 0x0799, 0x1ba0: 0x03c1, 0x1ba1: 0x04d1, 0x1ba2: 0x22d9, 0x1ba3: 0x22e1,
+ 0x1ba4: 0x22e9, 0x1ba5: 0x03b1, 0x1ba6: 0x03b9, 0x1ba7: 0x22f1, 0x1ba8: 0x0769, 0x1ba9: 0x22f9,
+ 0x1baa: 0x2289, 0x1bab: 0x0399, 0x1bac: 0x03a1, 0x1bad: 0x03a9, 0x1bae: 0x2291, 0x1baf: 0x2299,
+ 0x1bb0: 0x22a1, 0x1bb1: 0x04d1, 0x1bb2: 0x05f9, 0x1bb3: 0x22a9, 0x1bb4: 0x22b1, 0x1bb5: 0x22b9,
+ 0x1bb6: 0x22c1, 0x1bb7: 0x22c9, 0x1bb8: 0x22d1, 0x1bb9: 0x0799, 0x1bba: 0x03c1, 0x1bbb: 0x22d9,
+ 0x1bbc: 0x22d9, 0x1bbd: 0x22e1, 0x1bbe: 0x22e9, 0x1bbf: 0x03b1,
+ // Block 0x6f, offset 0x1bc0
+ 0x1bc0: 0x03b9, 0x1bc1: 0x22f1, 0x1bc2: 0x0769, 0x1bc3: 0x2301, 0x1bc4: 0x2291, 0x1bc5: 0x04d1,
+ 0x1bc6: 0x22a9, 0x1bc7: 0x03b1, 0x1bc8: 0x03c1, 0x1bc9: 0x0799, 0x1bca: 0x2309, 0x1bcb: 0x2309,
+ 0x1bcc: 0x0040, 0x1bcd: 0x0040, 0x1bce: 0x06e1, 0x1bcf: 0x0049, 0x1bd0: 0x0029, 0x1bd1: 0x0031,
+ 0x1bd2: 0x06e9, 0x1bd3: 0x06f1, 0x1bd4: 0x06f9, 0x1bd5: 0x0701, 0x1bd6: 0x0709, 0x1bd7: 0x0711,
+ 0x1bd8: 0x06e1, 0x1bd9: 0x0049, 0x1bda: 0x0029, 0x1bdb: 0x0031, 0x1bdc: 0x06e9, 0x1bdd: 0x06f1,
+ 0x1bde: 0x06f9, 0x1bdf: 0x0701, 0x1be0: 0x0709, 0x1be1: 0x0711, 0x1be2: 0x06e1, 0x1be3: 0x0049,
+ 0x1be4: 0x0029, 0x1be5: 0x0031, 0x1be6: 0x06e9, 0x1be7: 0x06f1, 0x1be8: 0x06f9, 0x1be9: 0x0701,
+ 0x1bea: 0x0709, 0x1beb: 0x0711, 0x1bec: 0x06e1, 0x1bed: 0x0049, 0x1bee: 0x0029, 0x1bef: 0x0031,
+ 0x1bf0: 0x06e9, 0x1bf1: 0x06f1, 0x1bf2: 0x06f9, 0x1bf3: 0x0701, 0x1bf4: 0x0709, 0x1bf5: 0x0711,
+ 0x1bf6: 0x06e1, 0x1bf7: 0x0049, 0x1bf8: 0x0029, 0x1bf9: 0x0031, 0x1bfa: 0x06e9, 0x1bfb: 0x06f1,
+ 0x1bfc: 0x06f9, 0x1bfd: 0x0701, 0x1bfe: 0x0709, 0x1bff: 0x0711,
+ // Block 0x70, offset 0x1c00
+ 0x1c00: 0xe115, 0x1c01: 0xe115, 0x1c02: 0xe135, 0x1c03: 0xe135, 0x1c04: 0xe115, 0x1c05: 0xe115,
+ 0x1c06: 0xe175, 0x1c07: 0xe175, 0x1c08: 0xe115, 0x1c09: 0xe115, 0x1c0a: 0xe135, 0x1c0b: 0xe135,
+ 0x1c0c: 0xe115, 0x1c0d: 0xe115, 0x1c0e: 0xe1f5, 0x1c0f: 0xe1f5, 0x1c10: 0xe115, 0x1c11: 0xe115,
+ 0x1c12: 0xe135, 0x1c13: 0xe135, 0x1c14: 0xe115, 0x1c15: 0xe115, 0x1c16: 0xe175, 0x1c17: 0xe175,
+ 0x1c18: 0xe115, 0x1c19: 0xe115, 0x1c1a: 0xe135, 0x1c1b: 0xe135, 0x1c1c: 0xe115, 0x1c1d: 0xe115,
+ 0x1c1e: 0x8b3d, 0x1c1f: 0x8b3d, 0x1c20: 0x04b5, 0x1c21: 0x04b5, 0x1c22: 0x0a08, 0x1c23: 0x0a08,
+ 0x1c24: 0x0a08, 0x1c25: 0x0a08, 0x1c26: 0x0a08, 0x1c27: 0x0a08, 0x1c28: 0x0a08, 0x1c29: 0x0a08,
+ 0x1c2a: 0x0a08, 0x1c2b: 0x0a08, 0x1c2c: 0x0a08, 0x1c2d: 0x0a08, 0x1c2e: 0x0a08, 0x1c2f: 0x0a08,
+ 0x1c30: 0x0a08, 0x1c31: 0x0a08, 0x1c32: 0x0a08, 0x1c33: 0x0a08, 0x1c34: 0x0a08, 0x1c35: 0x0a08,
+ 0x1c36: 0x0a08, 0x1c37: 0x0a08, 0x1c38: 0x0a08, 0x1c39: 0x0a08, 0x1c3a: 0x0a08, 0x1c3b: 0x0a08,
+ 0x1c3c: 0x0a08, 0x1c3d: 0x0a08, 0x1c3e: 0x0a08, 0x1c3f: 0x0a08,
+ // Block 0x71, offset 0x1c40
+ 0x1c40: 0x20b1, 0x1c41: 0x20b9, 0x1c42: 0x20d9, 0x1c43: 0x20f1, 0x1c44: 0x0040, 0x1c45: 0x2189,
+ 0x1c46: 0x2109, 0x1c47: 0x20e1, 0x1c48: 0x2131, 0x1c49: 0x2191, 0x1c4a: 0x2161, 0x1c4b: 0x2169,
+ 0x1c4c: 0x2171, 0x1c4d: 0x2179, 0x1c4e: 0x2111, 0x1c4f: 0x2141, 0x1c50: 0x2151, 0x1c51: 0x2121,
+ 0x1c52: 0x2159, 0x1c53: 0x2101, 0x1c54: 0x2119, 0x1c55: 0x20c9, 0x1c56: 0x20d1, 0x1c57: 0x20e9,
+ 0x1c58: 0x20f9, 0x1c59: 0x2129, 0x1c5a: 0x2139, 0x1c5b: 0x2149, 0x1c5c: 0x2311, 0x1c5d: 0x1689,
+ 0x1c5e: 0x2319, 0x1c5f: 0x2321, 0x1c60: 0x0040, 0x1c61: 0x20b9, 0x1c62: 0x20d9, 0x1c63: 0x0040,
+ 0x1c64: 0x2181, 0x1c65: 0x0040, 0x1c66: 0x0040, 0x1c67: 0x20e1, 0x1c68: 0x0040, 0x1c69: 0x2191,
+ 0x1c6a: 0x2161, 0x1c6b: 0x2169, 0x1c6c: 0x2171, 0x1c6d: 0x2179, 0x1c6e: 0x2111, 0x1c6f: 0x2141,
+ 0x1c70: 0x2151, 0x1c71: 0x2121, 0x1c72: 0x2159, 0x1c73: 0x0040, 0x1c74: 0x2119, 0x1c75: 0x20c9,
+ 0x1c76: 0x20d1, 0x1c77: 0x20e9, 0x1c78: 0x0040, 0x1c79: 0x2129, 0x1c7a: 0x0040, 0x1c7b: 0x2149,
+ 0x1c7c: 0x0040, 0x1c7d: 0x0040, 0x1c7e: 0x0040, 0x1c7f: 0x0040,
+ // Block 0x72, offset 0x1c80
+ 0x1c80: 0x0040, 0x1c81: 0x0040, 0x1c82: 0x20d9, 0x1c83: 0x0040, 0x1c84: 0x0040, 0x1c85: 0x0040,
+ 0x1c86: 0x0040, 0x1c87: 0x20e1, 0x1c88: 0x0040, 0x1c89: 0x2191, 0x1c8a: 0x0040, 0x1c8b: 0x2169,
+ 0x1c8c: 0x0040, 0x1c8d: 0x2179, 0x1c8e: 0x2111, 0x1c8f: 0x2141, 0x1c90: 0x0040, 0x1c91: 0x2121,
+ 0x1c92: 0x2159, 0x1c93: 0x0040, 0x1c94: 0x2119, 0x1c95: 0x0040, 0x1c96: 0x0040, 0x1c97: 0x20e9,
+ 0x1c98: 0x0040, 0x1c99: 0x2129, 0x1c9a: 0x0040, 0x1c9b: 0x2149, 0x1c9c: 0x0040, 0x1c9d: 0x1689,
+ 0x1c9e: 0x0040, 0x1c9f: 0x2321, 0x1ca0: 0x0040, 0x1ca1: 0x20b9, 0x1ca2: 0x20d9, 0x1ca3: 0x0040,
+ 0x1ca4: 0x2181, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0x20e1, 0x1ca8: 0x2131, 0x1ca9: 0x2191,
+ 0x1caa: 0x2161, 0x1cab: 0x0040, 0x1cac: 0x2171, 0x1cad: 0x2179, 0x1cae: 0x2111, 0x1caf: 0x2141,
+ 0x1cb0: 0x2151, 0x1cb1: 0x2121, 0x1cb2: 0x2159, 0x1cb3: 0x0040, 0x1cb4: 0x2119, 0x1cb5: 0x20c9,
+ 0x1cb6: 0x20d1, 0x1cb7: 0x20e9, 0x1cb8: 0x0040, 0x1cb9: 0x2129, 0x1cba: 0x2139, 0x1cbb: 0x2149,
+ 0x1cbc: 0x2311, 0x1cbd: 0x0040, 0x1cbe: 0x2319, 0x1cbf: 0x0040,
+ // Block 0x73, offset 0x1cc0
+ 0x1cc0: 0x20b1, 0x1cc1: 0x20b9, 0x1cc2: 0x20d9, 0x1cc3: 0x20f1, 0x1cc4: 0x2181, 0x1cc5: 0x2189,
+ 0x1cc6: 0x2109, 0x1cc7: 0x20e1, 0x1cc8: 0x2131, 0x1cc9: 0x2191, 0x1cca: 0x0040, 0x1ccb: 0x2169,
+ 0x1ccc: 0x2171, 0x1ccd: 0x2179, 0x1cce: 0x2111, 0x1ccf: 0x2141, 0x1cd0: 0x2151, 0x1cd1: 0x2121,
+ 0x1cd2: 0x2159, 0x1cd3: 0x2101, 0x1cd4: 0x2119, 0x1cd5: 0x20c9, 0x1cd6: 0x20d1, 0x1cd7: 0x20e9,
+ 0x1cd8: 0x20f9, 0x1cd9: 0x2129, 0x1cda: 0x2139, 0x1cdb: 0x2149, 0x1cdc: 0x0040, 0x1cdd: 0x0040,
+ 0x1cde: 0x0040, 0x1cdf: 0x0040, 0x1ce0: 0x0040, 0x1ce1: 0x20b9, 0x1ce2: 0x20d9, 0x1ce3: 0x20f1,
+ 0x1ce4: 0x0040, 0x1ce5: 0x2189, 0x1ce6: 0x2109, 0x1ce7: 0x20e1, 0x1ce8: 0x2131, 0x1ce9: 0x2191,
+ 0x1cea: 0x0040, 0x1ceb: 0x2169, 0x1cec: 0x2171, 0x1ced: 0x2179, 0x1cee: 0x2111, 0x1cef: 0x2141,
+ 0x1cf0: 0x2151, 0x1cf1: 0x2121, 0x1cf2: 0x2159, 0x1cf3: 0x2101, 0x1cf4: 0x2119, 0x1cf5: 0x20c9,
+ 0x1cf6: 0x20d1, 0x1cf7: 0x20e9, 0x1cf8: 0x20f9, 0x1cf9: 0x2129, 0x1cfa: 0x2139, 0x1cfb: 0x2149,
+ 0x1cfc: 0x0040, 0x1cfd: 0x0040, 0x1cfe: 0x0040, 0x1cff: 0x0040,
+ // Block 0x74, offset 0x1d00
+ 0x1d00: 0x0040, 0x1d01: 0x232a, 0x1d02: 0x2332, 0x1d03: 0x233a, 0x1d04: 0x2342, 0x1d05: 0x234a,
+ 0x1d06: 0x2352, 0x1d07: 0x235a, 0x1d08: 0x2362, 0x1d09: 0x236a, 0x1d0a: 0x2372, 0x1d0b: 0x0018,
+ 0x1d0c: 0x0018, 0x1d0d: 0x0018, 0x1d0e: 0x0018, 0x1d0f: 0x0018, 0x1d10: 0x237a, 0x1d11: 0x2382,
+ 0x1d12: 0x238a, 0x1d13: 0x2392, 0x1d14: 0x239a, 0x1d15: 0x23a2, 0x1d16: 0x23aa, 0x1d17: 0x23b2,
+ 0x1d18: 0x23ba, 0x1d19: 0x23c2, 0x1d1a: 0x23ca, 0x1d1b: 0x23d2, 0x1d1c: 0x23da, 0x1d1d: 0x23e2,
+ 0x1d1e: 0x23ea, 0x1d1f: 0x23f2, 0x1d20: 0x23fa, 0x1d21: 0x2402, 0x1d22: 0x240a, 0x1d23: 0x2412,
+ 0x1d24: 0x241a, 0x1d25: 0x2422, 0x1d26: 0x242a, 0x1d27: 0x2432, 0x1d28: 0x243a, 0x1d29: 0x2442,
+ 0x1d2a: 0x2449, 0x1d2b: 0x03d9, 0x1d2c: 0x00b9, 0x1d2d: 0x1239, 0x1d2e: 0x2451, 0x1d2f: 0x0018,
+ 0x1d30: 0x0019, 0x1d31: 0x02e9, 0x1d32: 0x03d9, 0x1d33: 0x02f1, 0x1d34: 0x02f9, 0x1d35: 0x03f1,
+ 0x1d36: 0x0309, 0x1d37: 0x00a9, 0x1d38: 0x0311, 0x1d39: 0x00b1, 0x1d3a: 0x0319, 0x1d3b: 0x0101,
+ 0x1d3c: 0x0321, 0x1d3d: 0x0329, 0x1d3e: 0x0051, 0x1d3f: 0x0339,
+ // Block 0x75, offset 0x1d40
+ 0x1d40: 0x0751, 0x1d41: 0x00b9, 0x1d42: 0x0089, 0x1d43: 0x0341, 0x1d44: 0x0349, 0x1d45: 0x0391,
+ 0x1d46: 0x00c1, 0x1d47: 0x0109, 0x1d48: 0x00c9, 0x1d49: 0x04b1, 0x1d4a: 0x2459, 0x1d4b: 0x11f9,
+ 0x1d4c: 0x2461, 0x1d4d: 0x04d9, 0x1d4e: 0x2469, 0x1d4f: 0x2471, 0x1d50: 0x0018, 0x1d51: 0x0018,
+ 0x1d52: 0x0018, 0x1d53: 0x0018, 0x1d54: 0x0018, 0x1d55: 0x0018, 0x1d56: 0x0018, 0x1d57: 0x0018,
+ 0x1d58: 0x0018, 0x1d59: 0x0018, 0x1d5a: 0x0018, 0x1d5b: 0x0018, 0x1d5c: 0x0018, 0x1d5d: 0x0018,
+ 0x1d5e: 0x0018, 0x1d5f: 0x0018, 0x1d60: 0x0018, 0x1d61: 0x0018, 0x1d62: 0x0018, 0x1d63: 0x0018,
+ 0x1d64: 0x0018, 0x1d65: 0x0018, 0x1d66: 0x0018, 0x1d67: 0x0018, 0x1d68: 0x0018, 0x1d69: 0x0018,
+ 0x1d6a: 0x2479, 0x1d6b: 0x2481, 0x1d6c: 0x2489, 0x1d6d: 0x0018, 0x1d6e: 0x0018, 0x1d6f: 0x0018,
+ 0x1d70: 0x0018, 0x1d71: 0x0018, 0x1d72: 0x0018, 0x1d73: 0x0018, 0x1d74: 0x0018, 0x1d75: 0x0018,
+ 0x1d76: 0x0018, 0x1d77: 0x0018, 0x1d78: 0x0018, 0x1d79: 0x0018, 0x1d7a: 0x0018, 0x1d7b: 0x0018,
+ 0x1d7c: 0x0018, 0x1d7d: 0x0018, 0x1d7e: 0x0018, 0x1d7f: 0x0018,
+ // Block 0x76, offset 0x1d80
+ 0x1d80: 0x2499, 0x1d81: 0x24a1, 0x1d82: 0x24a9, 0x1d83: 0x0040, 0x1d84: 0x0040, 0x1d85: 0x0040,
+ 0x1d86: 0x0040, 0x1d87: 0x0040, 0x1d88: 0x0040, 0x1d89: 0x0040, 0x1d8a: 0x0040, 0x1d8b: 0x0040,
+ 0x1d8c: 0x0040, 0x1d8d: 0x0040, 0x1d8e: 0x0040, 0x1d8f: 0x0040, 0x1d90: 0x24b1, 0x1d91: 0x24b9,
+ 0x1d92: 0x24c1, 0x1d93: 0x24c9, 0x1d94: 0x24d1, 0x1d95: 0x24d9, 0x1d96: 0x24e1, 0x1d97: 0x24e9,
+ 0x1d98: 0x24f1, 0x1d99: 0x24f9, 0x1d9a: 0x2501, 0x1d9b: 0x2509, 0x1d9c: 0x2511, 0x1d9d: 0x2519,
+ 0x1d9e: 0x2521, 0x1d9f: 0x2529, 0x1da0: 0x2531, 0x1da1: 0x2539, 0x1da2: 0x2541, 0x1da3: 0x2549,
+ 0x1da4: 0x2551, 0x1da5: 0x2559, 0x1da6: 0x2561, 0x1da7: 0x2569, 0x1da8: 0x2571, 0x1da9: 0x2579,
+ 0x1daa: 0x2581, 0x1dab: 0x2589, 0x1dac: 0x2591, 0x1dad: 0x2599, 0x1dae: 0x25a1, 0x1daf: 0x25a9,
+ 0x1db0: 0x25b1, 0x1db1: 0x25b9, 0x1db2: 0x25c1, 0x1db3: 0x25c9, 0x1db4: 0x25d1, 0x1db5: 0x25d9,
+ 0x1db6: 0x25e1, 0x1db7: 0x25e9, 0x1db8: 0x25f1, 0x1db9: 0x25f9, 0x1dba: 0x2601, 0x1dbb: 0x2609,
+ 0x1dbc: 0x0040, 0x1dbd: 0x0040, 0x1dbe: 0x0040, 0x1dbf: 0x0040,
+ // Block 0x77, offset 0x1dc0
+ 0x1dc0: 0x2669, 0x1dc1: 0x2671, 0x1dc2: 0x2679, 0x1dc3: 0x8b55, 0x1dc4: 0x2681, 0x1dc5: 0x2689,
+ 0x1dc6: 0x2691, 0x1dc7: 0x2699, 0x1dc8: 0x26a1, 0x1dc9: 0x26a9, 0x1dca: 0x26b1, 0x1dcb: 0x26b9,
+ 0x1dcc: 0x26c1, 0x1dcd: 0x8b75, 0x1dce: 0x26c9, 0x1dcf: 0x26d1, 0x1dd0: 0x26d9, 0x1dd1: 0x26e1,
+ 0x1dd2: 0x8b95, 0x1dd3: 0x26e9, 0x1dd4: 0x26f1, 0x1dd5: 0x2521, 0x1dd6: 0x8bb5, 0x1dd7: 0x26f9,
+ 0x1dd8: 0x2701, 0x1dd9: 0x2709, 0x1dda: 0x2711, 0x1ddb: 0x2719, 0x1ddc: 0x8bd5, 0x1ddd: 0x2721,
+ 0x1dde: 0x2729, 0x1ddf: 0x2731, 0x1de0: 0x2739, 0x1de1: 0x2741, 0x1de2: 0x25f9, 0x1de3: 0x2749,
+ 0x1de4: 0x2751, 0x1de5: 0x2759, 0x1de6: 0x2761, 0x1de7: 0x2769, 0x1de8: 0x2771, 0x1de9: 0x2779,
+ 0x1dea: 0x2781, 0x1deb: 0x2789, 0x1dec: 0x2791, 0x1ded: 0x2799, 0x1dee: 0x27a1, 0x1def: 0x27a9,
+ 0x1df0: 0x27b1, 0x1df1: 0x27b9, 0x1df2: 0x27b9, 0x1df3: 0x27b9, 0x1df4: 0x8bf5, 0x1df5: 0x27c1,
+ 0x1df6: 0x27c9, 0x1df7: 0x27d1, 0x1df8: 0x8c15, 0x1df9: 0x27d9, 0x1dfa: 0x27e1, 0x1dfb: 0x27e9,
+ 0x1dfc: 0x27f1, 0x1dfd: 0x27f9, 0x1dfe: 0x2801, 0x1dff: 0x2809,
+ // Block 0x78, offset 0x1e00
+ 0x1e00: 0x2811, 0x1e01: 0x2819, 0x1e02: 0x2821, 0x1e03: 0x2829, 0x1e04: 0x2831, 0x1e05: 0x2839,
+ 0x1e06: 0x2839, 0x1e07: 0x2841, 0x1e08: 0x2849, 0x1e09: 0x2851, 0x1e0a: 0x2859, 0x1e0b: 0x2861,
+ 0x1e0c: 0x2869, 0x1e0d: 0x2871, 0x1e0e: 0x2879, 0x1e0f: 0x2881, 0x1e10: 0x2889, 0x1e11: 0x2891,
+ 0x1e12: 0x2899, 0x1e13: 0x28a1, 0x1e14: 0x28a9, 0x1e15: 0x28b1, 0x1e16: 0x28b9, 0x1e17: 0x28c1,
+ 0x1e18: 0x28c9, 0x1e19: 0x8c35, 0x1e1a: 0x28d1, 0x1e1b: 0x28d9, 0x1e1c: 0x28e1, 0x1e1d: 0x24d9,
+ 0x1e1e: 0x28e9, 0x1e1f: 0x28f1, 0x1e20: 0x8c55, 0x1e21: 0x8c75, 0x1e22: 0x28f9, 0x1e23: 0x2901,
+ 0x1e24: 0x2909, 0x1e25: 0x2911, 0x1e26: 0x2919, 0x1e27: 0x2921, 0x1e28: 0x2040, 0x1e29: 0x2929,
+ 0x1e2a: 0x2931, 0x1e2b: 0x2931, 0x1e2c: 0x8c95, 0x1e2d: 0x2939, 0x1e2e: 0x2941, 0x1e2f: 0x2949,
+ 0x1e30: 0x2951, 0x1e31: 0x8cb5, 0x1e32: 0x2959, 0x1e33: 0x2961, 0x1e34: 0x2040, 0x1e35: 0x2969,
+ 0x1e36: 0x2971, 0x1e37: 0x2979, 0x1e38: 0x2981, 0x1e39: 0x2989, 0x1e3a: 0x2991, 0x1e3b: 0x8cd5,
+ 0x1e3c: 0x2999, 0x1e3d: 0x8cf5, 0x1e3e: 0x29a1, 0x1e3f: 0x29a9,
+ // Block 0x79, offset 0x1e40
+ 0x1e40: 0x29b1, 0x1e41: 0x29b9, 0x1e42: 0x29c1, 0x1e43: 0x29c9, 0x1e44: 0x29d1, 0x1e45: 0x29d9,
+ 0x1e46: 0x29e1, 0x1e47: 0x29e9, 0x1e48: 0x29f1, 0x1e49: 0x8d15, 0x1e4a: 0x29f9, 0x1e4b: 0x2a01,
+ 0x1e4c: 0x2a09, 0x1e4d: 0x2a11, 0x1e4e: 0x2a19, 0x1e4f: 0x8d35, 0x1e50: 0x2a21, 0x1e51: 0x8d55,
+ 0x1e52: 0x8d75, 0x1e53: 0x2a29, 0x1e54: 0x2a31, 0x1e55: 0x2a31, 0x1e56: 0x2a39, 0x1e57: 0x8d95,
+ 0x1e58: 0x8db5, 0x1e59: 0x2a41, 0x1e5a: 0x2a49, 0x1e5b: 0x2a51, 0x1e5c: 0x2a59, 0x1e5d: 0x2a61,
+ 0x1e5e: 0x2a69, 0x1e5f: 0x2a71, 0x1e60: 0x2a79, 0x1e61: 0x2a81, 0x1e62: 0x2a89, 0x1e63: 0x2a91,
+ 0x1e64: 0x8dd5, 0x1e65: 0x2a99, 0x1e66: 0x2aa1, 0x1e67: 0x2aa9, 0x1e68: 0x2ab1, 0x1e69: 0x2aa9,
+ 0x1e6a: 0x2ab9, 0x1e6b: 0x2ac1, 0x1e6c: 0x2ac9, 0x1e6d: 0x2ad1, 0x1e6e: 0x2ad9, 0x1e6f: 0x2ae1,
+ 0x1e70: 0x2ae9, 0x1e71: 0x2af1, 0x1e72: 0x2af9, 0x1e73: 0x2b01, 0x1e74: 0x2b09, 0x1e75: 0x2b11,
+ 0x1e76: 0x2b19, 0x1e77: 0x2b21, 0x1e78: 0x8df5, 0x1e79: 0x2b29, 0x1e7a: 0x2b31, 0x1e7b: 0x2b39,
+ 0x1e7c: 0x2b41, 0x1e7d: 0x2b49, 0x1e7e: 0x8e15, 0x1e7f: 0x2b51,
+ // Block 0x7a, offset 0x1e80
+ 0x1e80: 0x2b59, 0x1e81: 0x2b61, 0x1e82: 0x2b69, 0x1e83: 0x2b71, 0x1e84: 0x2b79, 0x1e85: 0x2b81,
+ 0x1e86: 0x2b89, 0x1e87: 0x2b91, 0x1e88: 0x2b99, 0x1e89: 0x2ba1, 0x1e8a: 0x8e35, 0x1e8b: 0x2ba9,
+ 0x1e8c: 0x2bb1, 0x1e8d: 0x2bb9, 0x1e8e: 0x2bc1, 0x1e8f: 0x2bc9, 0x1e90: 0x2bd1, 0x1e91: 0x2bd9,
+ 0x1e92: 0x2be1, 0x1e93: 0x2be9, 0x1e94: 0x2bf1, 0x1e95: 0x2bf9, 0x1e96: 0x2c01, 0x1e97: 0x2c09,
+ 0x1e98: 0x2c11, 0x1e99: 0x2c19, 0x1e9a: 0x2c21, 0x1e9b: 0x2c29, 0x1e9c: 0x2c31, 0x1e9d: 0x8e55,
+ 0x1e9e: 0x2c39, 0x1e9f: 0x2c41, 0x1ea0: 0x2c49, 0x1ea1: 0x2c51, 0x1ea2: 0x2c59, 0x1ea3: 0x8e75,
+ 0x1ea4: 0x2c61, 0x1ea5: 0x2c69, 0x1ea6: 0x2c71, 0x1ea7: 0x2c79, 0x1ea8: 0x2c81, 0x1ea9: 0x2c89,
+ 0x1eaa: 0x2c91, 0x1eab: 0x2c99, 0x1eac: 0x7f0d, 0x1ead: 0x2ca1, 0x1eae: 0x2ca9, 0x1eaf: 0x2cb1,
+ 0x1eb0: 0x8e95, 0x1eb1: 0x2cb9, 0x1eb2: 0x2cc1, 0x1eb3: 0x2cc9, 0x1eb4: 0x2cd1, 0x1eb5: 0x2cd9,
+ 0x1eb6: 0x2ce1, 0x1eb7: 0x8eb5, 0x1eb8: 0x8ed5, 0x1eb9: 0x8ef5, 0x1eba: 0x2ce9, 0x1ebb: 0x8f15,
+ 0x1ebc: 0x2cf1, 0x1ebd: 0x2cf9, 0x1ebe: 0x2d01, 0x1ebf: 0x2d09,
+ // Block 0x7b, offset 0x1ec0
+ 0x1ec0: 0x2d11, 0x1ec1: 0x2d19, 0x1ec2: 0x2d21, 0x1ec3: 0x2d29, 0x1ec4: 0x2d31, 0x1ec5: 0x2d39,
+ 0x1ec6: 0x8f35, 0x1ec7: 0x2d41, 0x1ec8: 0x2d49, 0x1ec9: 0x2d51, 0x1eca: 0x2d59, 0x1ecb: 0x2d61,
+ 0x1ecc: 0x2d69, 0x1ecd: 0x8f55, 0x1ece: 0x2d71, 0x1ecf: 0x2d79, 0x1ed0: 0x8f75, 0x1ed1: 0x8f95,
+ 0x1ed2: 0x2d81, 0x1ed3: 0x2d89, 0x1ed4: 0x2d91, 0x1ed5: 0x2d99, 0x1ed6: 0x2da1, 0x1ed7: 0x2da9,
+ 0x1ed8: 0x2db1, 0x1ed9: 0x2db9, 0x1eda: 0x2dc1, 0x1edb: 0x8fb5, 0x1edc: 0x2dc9, 0x1edd: 0x8fd5,
+ 0x1ede: 0x2dd1, 0x1edf: 0x2040, 0x1ee0: 0x2dd9, 0x1ee1: 0x2de1, 0x1ee2: 0x2de9, 0x1ee3: 0x8ff5,
+ 0x1ee4: 0x2df1, 0x1ee5: 0x2df9, 0x1ee6: 0x9015, 0x1ee7: 0x9035, 0x1ee8: 0x2e01, 0x1ee9: 0x2e09,
+ 0x1eea: 0x2e11, 0x1eeb: 0x2e19, 0x1eec: 0x2e21, 0x1eed: 0x2e21, 0x1eee: 0x2e29, 0x1eef: 0x2e31,
+ 0x1ef0: 0x2e39, 0x1ef1: 0x2e41, 0x1ef2: 0x2e49, 0x1ef3: 0x2e51, 0x1ef4: 0x2e59, 0x1ef5: 0x9055,
+ 0x1ef6: 0x2e61, 0x1ef7: 0x9075, 0x1ef8: 0x2e69, 0x1ef9: 0x9095, 0x1efa: 0x2e71, 0x1efb: 0x90b5,
+ 0x1efc: 0x90d5, 0x1efd: 0x90f5, 0x1efe: 0x2e79, 0x1eff: 0x2e81,
+ // Block 0x7c, offset 0x1f00
+ 0x1f00: 0x2e89, 0x1f01: 0x9115, 0x1f02: 0x9135, 0x1f03: 0x9155, 0x1f04: 0x9175, 0x1f05: 0x2e91,
+ 0x1f06: 0x2e99, 0x1f07: 0x2e99, 0x1f08: 0x2ea1, 0x1f09: 0x2ea9, 0x1f0a: 0x2eb1, 0x1f0b: 0x2eb9,
+ 0x1f0c: 0x2ec1, 0x1f0d: 0x9195, 0x1f0e: 0x2ec9, 0x1f0f: 0x2ed1, 0x1f10: 0x2ed9, 0x1f11: 0x2ee1,
+ 0x1f12: 0x91b5, 0x1f13: 0x2ee9, 0x1f14: 0x91d5, 0x1f15: 0x91f5, 0x1f16: 0x2ef1, 0x1f17: 0x2ef9,
+ 0x1f18: 0x2f01, 0x1f19: 0x2f09, 0x1f1a: 0x2f11, 0x1f1b: 0x2f19, 0x1f1c: 0x9215, 0x1f1d: 0x9235,
+ 0x1f1e: 0x9255, 0x1f1f: 0x2040, 0x1f20: 0x2f21, 0x1f21: 0x9275, 0x1f22: 0x2f29, 0x1f23: 0x2f31,
+ 0x1f24: 0x2f39, 0x1f25: 0x9295, 0x1f26: 0x2f41, 0x1f27: 0x2f49, 0x1f28: 0x2f51, 0x1f29: 0x2f59,
+ 0x1f2a: 0x2f61, 0x1f2b: 0x92b5, 0x1f2c: 0x2f69, 0x1f2d: 0x2f71, 0x1f2e: 0x2f79, 0x1f2f: 0x2f81,
+ 0x1f30: 0x2f89, 0x1f31: 0x2f91, 0x1f32: 0x92d5, 0x1f33: 0x92f5, 0x1f34: 0x2f99, 0x1f35: 0x9315,
+ 0x1f36: 0x2fa1, 0x1f37: 0x9335, 0x1f38: 0x2fa9, 0x1f39: 0x2fb1, 0x1f3a: 0x2fb9, 0x1f3b: 0x9355,
+ 0x1f3c: 0x9375, 0x1f3d: 0x2fc1, 0x1f3e: 0x9395, 0x1f3f: 0x2fc9,
+ // Block 0x7d, offset 0x1f40
+ 0x1f40: 0x93b5, 0x1f41: 0x2fd1, 0x1f42: 0x2fd9, 0x1f43: 0x2fe1, 0x1f44: 0x2fe9, 0x1f45: 0x2ff1,
+ 0x1f46: 0x2ff9, 0x1f47: 0x93d5, 0x1f48: 0x93f5, 0x1f49: 0x9415, 0x1f4a: 0x9435, 0x1f4b: 0x2a29,
+ 0x1f4c: 0x3001, 0x1f4d: 0x3009, 0x1f4e: 0x3011, 0x1f4f: 0x3019, 0x1f50: 0x3021, 0x1f51: 0x3029,
+ 0x1f52: 0x3031, 0x1f53: 0x3039, 0x1f54: 0x3041, 0x1f55: 0x3049, 0x1f56: 0x3051, 0x1f57: 0x9455,
+ 0x1f58: 0x3059, 0x1f59: 0x3061, 0x1f5a: 0x3069, 0x1f5b: 0x3071, 0x1f5c: 0x3079, 0x1f5d: 0x3081,
+ 0x1f5e: 0x3089, 0x1f5f: 0x3091, 0x1f60: 0x3099, 0x1f61: 0x30a1, 0x1f62: 0x30a9, 0x1f63: 0x30b1,
+ 0x1f64: 0x9475, 0x1f65: 0x9495, 0x1f66: 0x94b5, 0x1f67: 0x30b9, 0x1f68: 0x30c1, 0x1f69: 0x30c9,
+ 0x1f6a: 0x30d1, 0x1f6b: 0x94d5, 0x1f6c: 0x30d9, 0x1f6d: 0x94f5, 0x1f6e: 0x30e1, 0x1f6f: 0x30e9,
+ 0x1f70: 0x9515, 0x1f71: 0x9535, 0x1f72: 0x30f1, 0x1f73: 0x30f9, 0x1f74: 0x3101, 0x1f75: 0x3109,
+ 0x1f76: 0x3111, 0x1f77: 0x3119, 0x1f78: 0x3121, 0x1f79: 0x3129, 0x1f7a: 0x3131, 0x1f7b: 0x3139,
+ 0x1f7c: 0x3141, 0x1f7d: 0x3149, 0x1f7e: 0x3151, 0x1f7f: 0x2040,
+ // Block 0x7e, offset 0x1f80
+ 0x1f80: 0x3159, 0x1f81: 0x3161, 0x1f82: 0x3169, 0x1f83: 0x3171, 0x1f84: 0x3179, 0x1f85: 0x9555,
+ 0x1f86: 0x3181, 0x1f87: 0x3189, 0x1f88: 0x3191, 0x1f89: 0x3199, 0x1f8a: 0x31a1, 0x1f8b: 0x9575,
+ 0x1f8c: 0x9595, 0x1f8d: 0x31a9, 0x1f8e: 0x31b1, 0x1f8f: 0x31b9, 0x1f90: 0x31c1, 0x1f91: 0x31c9,
+ 0x1f92: 0x31d1, 0x1f93: 0x95b5, 0x1f94: 0x31d9, 0x1f95: 0x31e1, 0x1f96: 0x31e9, 0x1f97: 0x31f1,
+ 0x1f98: 0x95d5, 0x1f99: 0x95f5, 0x1f9a: 0x31f9, 0x1f9b: 0x3201, 0x1f9c: 0x3209, 0x1f9d: 0x9615,
+ 0x1f9e: 0x3211, 0x1f9f: 0x3219, 0x1fa0: 0x684d, 0x1fa1: 0x9635, 0x1fa2: 0x3221, 0x1fa3: 0x3229,
+ 0x1fa4: 0x3231, 0x1fa5: 0x9655, 0x1fa6: 0x3239, 0x1fa7: 0x3241, 0x1fa8: 0x3249, 0x1fa9: 0x3251,
+ 0x1faa: 0x3259, 0x1fab: 0x3261, 0x1fac: 0x3269, 0x1fad: 0x9675, 0x1fae: 0x3271, 0x1faf: 0x3279,
+ 0x1fb0: 0x3281, 0x1fb1: 0x9695, 0x1fb2: 0x3289, 0x1fb3: 0x3291, 0x1fb4: 0x3299, 0x1fb5: 0x32a1,
+ 0x1fb6: 0x7b6d, 0x1fb7: 0x96b5, 0x1fb8: 0x32a9, 0x1fb9: 0x32b1, 0x1fba: 0x32b9, 0x1fbb: 0x96d5,
+ 0x1fbc: 0x32c1, 0x1fbd: 0x96f5, 0x1fbe: 0x32c9, 0x1fbf: 0x32c9,
+ // Block 0x7f, offset 0x1fc0
+ 0x1fc0: 0x32d1, 0x1fc1: 0x9715, 0x1fc2: 0x32d9, 0x1fc3: 0x32e1, 0x1fc4: 0x32e9, 0x1fc5: 0x32f1,
+ 0x1fc6: 0x32f9, 0x1fc7: 0x3301, 0x1fc8: 0x3309, 0x1fc9: 0x9735, 0x1fca: 0x3311, 0x1fcb: 0x3319,
+ 0x1fcc: 0x3321, 0x1fcd: 0x3329, 0x1fce: 0x3331, 0x1fcf: 0x3339, 0x1fd0: 0x9755, 0x1fd1: 0x3341,
+ 0x1fd2: 0x9775, 0x1fd3: 0x9795, 0x1fd4: 0x97b5, 0x1fd5: 0x3349, 0x1fd6: 0x3351, 0x1fd7: 0x3359,
+ 0x1fd8: 0x3361, 0x1fd9: 0x3369, 0x1fda: 0x3371, 0x1fdb: 0x3379, 0x1fdc: 0x3381, 0x1fdd: 0x97d5,
+ 0x1fde: 0x0040, 0x1fdf: 0x0040, 0x1fe0: 0x0040, 0x1fe1: 0x0040, 0x1fe2: 0x0040, 0x1fe3: 0x0040,
+ 0x1fe4: 0x0040, 0x1fe5: 0x0040, 0x1fe6: 0x0040, 0x1fe7: 0x0040, 0x1fe8: 0x0040, 0x1fe9: 0x0040,
+ 0x1fea: 0x0040, 0x1feb: 0x0040, 0x1fec: 0x0040, 0x1fed: 0x0040, 0x1fee: 0x0040, 0x1fef: 0x0040,
+ 0x1ff0: 0x0040, 0x1ff1: 0x0040, 0x1ff2: 0x0040, 0x1ff3: 0x0040, 0x1ff4: 0x0040, 0x1ff5: 0x0040,
+ 0x1ff6: 0x0040, 0x1ff7: 0x0040, 0x1ff8: 0x0040, 0x1ff9: 0x0040, 0x1ffa: 0x0040, 0x1ffb: 0x0040,
+ 0x1ffc: 0x0040, 0x1ffd: 0x0040, 0x1ffe: 0x0040, 0x1fff: 0x0040,
+}
+
+// idnaIndex: 37 blocks, 2368 entries, 4736 bytes
+// Block 0 is the zero block.
+var idnaIndex = [2368]uint16{
+ // Block 0x0, offset 0x0
+ // Block 0x1, offset 0x40
+ // Block 0x2, offset 0x80
+ // Block 0x3, offset 0xc0
+ 0xc2: 0x01, 0xc3: 0x7e, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,
+ 0xc8: 0x06, 0xc9: 0x7f, 0xca: 0x80, 0xcb: 0x07, 0xcc: 0x81, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,
+ 0xd0: 0x82, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x83, 0xd6: 0x84, 0xd7: 0x85,
+ 0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x86, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x87, 0xde: 0x88, 0xdf: 0x89,
+ 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,
+ 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c,
+ 0xf0: 0x1e, 0xf1: 0x1f, 0xf2: 0x1f, 0xf3: 0x21, 0xf4: 0x22,
+ // Block 0x4, offset 0x100
+ 0x120: 0x8a, 0x121: 0x13, 0x122: 0x8b, 0x123: 0x8c, 0x124: 0x8d, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16,
+ 0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8e,
+ 0x130: 0x8f, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x90, 0x135: 0x21, 0x136: 0x91, 0x137: 0x92,
+ 0x138: 0x93, 0x139: 0x94, 0x13a: 0x22, 0x13b: 0x95, 0x13c: 0x96, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x97,
+ // Block 0x5, offset 0x140
+ 0x140: 0x98, 0x141: 0x99, 0x142: 0x9a, 0x143: 0x9b, 0x144: 0x9c, 0x145: 0x9d, 0x146: 0x9e, 0x147: 0x9f,
+ 0x148: 0xa0, 0x149: 0xa1, 0x14a: 0xa2, 0x14b: 0xa3, 0x14c: 0xa4, 0x14d: 0xa5, 0x14e: 0xa6, 0x14f: 0xa7,
+ 0x150: 0xa8, 0x151: 0xa0, 0x152: 0xa0, 0x153: 0xa0, 0x154: 0xa0, 0x155: 0xa0, 0x156: 0xa0, 0x157: 0xa0,
+ 0x158: 0xa0, 0x159: 0xa9, 0x15a: 0xaa, 0x15b: 0xab, 0x15c: 0xac, 0x15d: 0xad, 0x15e: 0xae, 0x15f: 0xaf,
+ 0x160: 0xb0, 0x161: 0xb1, 0x162: 0xb2, 0x163: 0xb3, 0x164: 0xb4, 0x165: 0xb5, 0x166: 0xb6, 0x167: 0xb7,
+ 0x168: 0xb8, 0x169: 0xb9, 0x16a: 0xba, 0x16b: 0xbb, 0x16c: 0xbc, 0x16d: 0xbd, 0x16e: 0xbe, 0x16f: 0xbf,
+ 0x170: 0xc0, 0x171: 0xc1, 0x172: 0xc2, 0x173: 0xc3, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc4,
+ 0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc5, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c,
+ // Block 0x6, offset 0x180
+ 0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc6, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc7, 0x187: 0x9c,
+ 0x188: 0xc8, 0x189: 0xc9, 0x18a: 0x9c, 0x18b: 0x9c, 0x18c: 0xca, 0x18d: 0x9c, 0x18e: 0x9c, 0x18f: 0x9c,
+ 0x190: 0xcb, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9c, 0x195: 0x9c, 0x196: 0x9c, 0x197: 0x9c,
+ 0x198: 0x9c, 0x199: 0x9c, 0x19a: 0x9c, 0x19b: 0x9c, 0x19c: 0x9c, 0x19d: 0x9c, 0x19e: 0x9c, 0x19f: 0x9c,
+ 0x1a0: 0x9c, 0x1a1: 0x9c, 0x1a2: 0x9c, 0x1a3: 0x9c, 0x1a4: 0x9c, 0x1a5: 0x9c, 0x1a6: 0x9c, 0x1a7: 0x9c,
+ 0x1a8: 0xcc, 0x1a9: 0xcd, 0x1aa: 0x9c, 0x1ab: 0xce, 0x1ac: 0x9c, 0x1ad: 0xcf, 0x1ae: 0xd0, 0x1af: 0x9c,
+ 0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5,
+ 0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37,
+ // Block 0x7, offset 0x1c0
+ 0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1,
+ 0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0xe3, 0x1cd: 0xe4, 0x1ce: 0x3e, 0x1cf: 0x3f,
+ 0x1d0: 0xa0, 0x1d1: 0xa0, 0x1d2: 0xa0, 0x1d3: 0xa0, 0x1d4: 0xa0, 0x1d5: 0xa0, 0x1d6: 0xa0, 0x1d7: 0xa0,
+ 0x1d8: 0xa0, 0x1d9: 0xa0, 0x1da: 0xa0, 0x1db: 0xa0, 0x1dc: 0xa0, 0x1dd: 0xa0, 0x1de: 0xa0, 0x1df: 0xa0,
+ 0x1e0: 0xa0, 0x1e1: 0xa0, 0x1e2: 0xa0, 0x1e3: 0xa0, 0x1e4: 0xa0, 0x1e5: 0xa0, 0x1e6: 0xa0, 0x1e7: 0xa0,
+ 0x1e8: 0xa0, 0x1e9: 0xa0, 0x1ea: 0xa0, 0x1eb: 0xa0, 0x1ec: 0xa0, 0x1ed: 0xa0, 0x1ee: 0xa0, 0x1ef: 0xa0,
+ 0x1f0: 0xa0, 0x1f1: 0xa0, 0x1f2: 0xa0, 0x1f3: 0xa0, 0x1f4: 0xa0, 0x1f5: 0xa0, 0x1f6: 0xa0, 0x1f7: 0xa0,
+ 0x1f8: 0xa0, 0x1f9: 0xa0, 0x1fa: 0xa0, 0x1fb: 0xa0, 0x1fc: 0xa0, 0x1fd: 0xa0, 0x1fe: 0xa0, 0x1ff: 0xa0,
+ // Block 0x8, offset 0x200
+ 0x200: 0xa0, 0x201: 0xa0, 0x202: 0xa0, 0x203: 0xa0, 0x204: 0xa0, 0x205: 0xa0, 0x206: 0xa0, 0x207: 0xa0,
+ 0x208: 0xa0, 0x209: 0xa0, 0x20a: 0xa0, 0x20b: 0xa0, 0x20c: 0xa0, 0x20d: 0xa0, 0x20e: 0xa0, 0x20f: 0xa0,
+ 0x210: 0xa0, 0x211: 0xa0, 0x212: 0xa0, 0x213: 0xa0, 0x214: 0xa0, 0x215: 0xa0, 0x216: 0xa0, 0x217: 0xa0,
+ 0x218: 0xa0, 0x219: 0xa0, 0x21a: 0xa0, 0x21b: 0xa0, 0x21c: 0xa0, 0x21d: 0xa0, 0x21e: 0xa0, 0x21f: 0xa0,
+ 0x220: 0xa0, 0x221: 0xa0, 0x222: 0xa0, 0x223: 0xa0, 0x224: 0xa0, 0x225: 0xa0, 0x226: 0xa0, 0x227: 0xa0,
+ 0x228: 0xa0, 0x229: 0xa0, 0x22a: 0xa0, 0x22b: 0xa0, 0x22c: 0xa0, 0x22d: 0xa0, 0x22e: 0xa0, 0x22f: 0xa0,
+ 0x230: 0xa0, 0x231: 0xa0, 0x232: 0xa0, 0x233: 0xa0, 0x234: 0xa0, 0x235: 0xa0, 0x236: 0xa0, 0x237: 0x9c,
+ 0x238: 0xa0, 0x239: 0xa0, 0x23a: 0xa0, 0x23b: 0xa0, 0x23c: 0xa0, 0x23d: 0xa0, 0x23e: 0xa0, 0x23f: 0xa0,
+ // Block 0x9, offset 0x240
+ 0x240: 0xa0, 0x241: 0xa0, 0x242: 0xa0, 0x243: 0xa0, 0x244: 0xa0, 0x245: 0xa0, 0x246: 0xa0, 0x247: 0xa0,
+ 0x248: 0xa0, 0x249: 0xa0, 0x24a: 0xa0, 0x24b: 0xa0, 0x24c: 0xa0, 0x24d: 0xa0, 0x24e: 0xa0, 0x24f: 0xa0,
+ 0x250: 0xa0, 0x251: 0xa0, 0x252: 0xa0, 0x253: 0xa0, 0x254: 0xa0, 0x255: 0xa0, 0x256: 0xa0, 0x257: 0xa0,
+ 0x258: 0xa0, 0x259: 0xa0, 0x25a: 0xa0, 0x25b: 0xa0, 0x25c: 0xa0, 0x25d: 0xa0, 0x25e: 0xa0, 0x25f: 0xa0,
+ 0x260: 0xa0, 0x261: 0xa0, 0x262: 0xa0, 0x263: 0xa0, 0x264: 0xa0, 0x265: 0xa0, 0x266: 0xa0, 0x267: 0xa0,
+ 0x268: 0xa0, 0x269: 0xa0, 0x26a: 0xa0, 0x26b: 0xa0, 0x26c: 0xa0, 0x26d: 0xa0, 0x26e: 0xa0, 0x26f: 0xa0,
+ 0x270: 0xa0, 0x271: 0xa0, 0x272: 0xa0, 0x273: 0xa0, 0x274: 0xa0, 0x275: 0xa0, 0x276: 0xa0, 0x277: 0xa0,
+ 0x278: 0xa0, 0x279: 0xa0, 0x27a: 0xa0, 0x27b: 0xa0, 0x27c: 0xa0, 0x27d: 0xa0, 0x27e: 0xa0, 0x27f: 0xa0,
+ // Block 0xa, offset 0x280
+ 0x280: 0xa0, 0x281: 0xa0, 0x282: 0xa0, 0x283: 0xa0, 0x284: 0xa0, 0x285: 0xa0, 0x286: 0xa0, 0x287: 0xa0,
+ 0x288: 0xa0, 0x289: 0xa0, 0x28a: 0xa0, 0x28b: 0xa0, 0x28c: 0xa0, 0x28d: 0xa0, 0x28e: 0xa0, 0x28f: 0xa0,
+ 0x290: 0xa0, 0x291: 0xa0, 0x292: 0xa0, 0x293: 0xa0, 0x294: 0xa0, 0x295: 0xa0, 0x296: 0xa0, 0x297: 0xa0,
+ 0x298: 0xa0, 0x299: 0xa0, 0x29a: 0xa0, 0x29b: 0xa0, 0x29c: 0xa0, 0x29d: 0xa0, 0x29e: 0xa0, 0x29f: 0xa0,
+ 0x2a0: 0xa0, 0x2a1: 0xa0, 0x2a2: 0xa0, 0x2a3: 0xa0, 0x2a4: 0xa0, 0x2a5: 0xa0, 0x2a6: 0xa0, 0x2a7: 0xa0,
+ 0x2a8: 0xa0, 0x2a9: 0xa0, 0x2aa: 0xa0, 0x2ab: 0xa0, 0x2ac: 0xa0, 0x2ad: 0xa0, 0x2ae: 0xa0, 0x2af: 0xa0,
+ 0x2b0: 0xa0, 0x2b1: 0xa0, 0x2b2: 0xa0, 0x2b3: 0xa0, 0x2b4: 0xa0, 0x2b5: 0xa0, 0x2b6: 0xa0, 0x2b7: 0xa0,
+ 0x2b8: 0xa0, 0x2b9: 0xa0, 0x2ba: 0xa0, 0x2bb: 0xa0, 0x2bc: 0xa0, 0x2bd: 0xa0, 0x2be: 0xa0, 0x2bf: 0xe5,
+ // Block 0xb, offset 0x2c0
+ 0x2c0: 0xa0, 0x2c1: 0xa0, 0x2c2: 0xa0, 0x2c3: 0xa0, 0x2c4: 0xa0, 0x2c5: 0xa0, 0x2c6: 0xa0, 0x2c7: 0xa0,
+ 0x2c8: 0xa0, 0x2c9: 0xa0, 0x2ca: 0xa0, 0x2cb: 0xa0, 0x2cc: 0xa0, 0x2cd: 0xa0, 0x2ce: 0xa0, 0x2cf: 0xa0,
+ 0x2d0: 0xa0, 0x2d1: 0xa0, 0x2d2: 0xe6, 0x2d3: 0xe7, 0x2d4: 0xa0, 0x2d5: 0xa0, 0x2d6: 0xa0, 0x2d7: 0xa0,
+ 0x2d8: 0xe8, 0x2d9: 0x40, 0x2da: 0x41, 0x2db: 0xe9, 0x2dc: 0x42, 0x2dd: 0x43, 0x2de: 0x44, 0x2df: 0xea,
+ 0x2e0: 0xeb, 0x2e1: 0xec, 0x2e2: 0xed, 0x2e3: 0xee, 0x2e4: 0xef, 0x2e5: 0xf0, 0x2e6: 0xf1, 0x2e7: 0xf2,
+ 0x2e8: 0xf3, 0x2e9: 0xf4, 0x2ea: 0xf5, 0x2eb: 0xf6, 0x2ec: 0xf7, 0x2ed: 0xf8, 0x2ee: 0xf9, 0x2ef: 0xfa,
+ 0x2f0: 0xa0, 0x2f1: 0xa0, 0x2f2: 0xa0, 0x2f3: 0xa0, 0x2f4: 0xa0, 0x2f5: 0xa0, 0x2f6: 0xa0, 0x2f7: 0xa0,
+ 0x2f8: 0xa0, 0x2f9: 0xa0, 0x2fa: 0xa0, 0x2fb: 0xa0, 0x2fc: 0xa0, 0x2fd: 0xa0, 0x2fe: 0xa0, 0x2ff: 0xa0,
+ // Block 0xc, offset 0x300
+ 0x300: 0xa0, 0x301: 0xa0, 0x302: 0xa0, 0x303: 0xa0, 0x304: 0xa0, 0x305: 0xa0, 0x306: 0xa0, 0x307: 0xa0,
+ 0x308: 0xa0, 0x309: 0xa0, 0x30a: 0xa0, 0x30b: 0xa0, 0x30c: 0xa0, 0x30d: 0xa0, 0x30e: 0xa0, 0x30f: 0xa0,
+ 0x310: 0xa0, 0x311: 0xa0, 0x312: 0xa0, 0x313: 0xa0, 0x314: 0xa0, 0x315: 0xa0, 0x316: 0xa0, 0x317: 0xa0,
+ 0x318: 0xa0, 0x319: 0xa0, 0x31a: 0xa0, 0x31b: 0xa0, 0x31c: 0xa0, 0x31d: 0xa0, 0x31e: 0xfb, 0x31f: 0xfc,
+ // Block 0xd, offset 0x340
+ 0x340: 0xfd, 0x341: 0xfd, 0x342: 0xfd, 0x343: 0xfd, 0x344: 0xfd, 0x345: 0xfd, 0x346: 0xfd, 0x347: 0xfd,
+ 0x348: 0xfd, 0x349: 0xfd, 0x34a: 0xfd, 0x34b: 0xfd, 0x34c: 0xfd, 0x34d: 0xfd, 0x34e: 0xfd, 0x34f: 0xfd,
+ 0x350: 0xfd, 0x351: 0xfd, 0x352: 0xfd, 0x353: 0xfd, 0x354: 0xfd, 0x355: 0xfd, 0x356: 0xfd, 0x357: 0xfd,
+ 0x358: 0xfd, 0x359: 0xfd, 0x35a: 0xfd, 0x35b: 0xfd, 0x35c: 0xfd, 0x35d: 0xfd, 0x35e: 0xfd, 0x35f: 0xfd,
+ 0x360: 0xfd, 0x361: 0xfd, 0x362: 0xfd, 0x363: 0xfd, 0x364: 0xfd, 0x365: 0xfd, 0x366: 0xfd, 0x367: 0xfd,
+ 0x368: 0xfd, 0x369: 0xfd, 0x36a: 0xfd, 0x36b: 0xfd, 0x36c: 0xfd, 0x36d: 0xfd, 0x36e: 0xfd, 0x36f: 0xfd,
+ 0x370: 0xfd, 0x371: 0xfd, 0x372: 0xfd, 0x373: 0xfd, 0x374: 0xfd, 0x375: 0xfd, 0x376: 0xfd, 0x377: 0xfd,
+ 0x378: 0xfd, 0x379: 0xfd, 0x37a: 0xfd, 0x37b: 0xfd, 0x37c: 0xfd, 0x37d: 0xfd, 0x37e: 0xfd, 0x37f: 0xfd,
+ // Block 0xe, offset 0x380
+ 0x380: 0xfd, 0x381: 0xfd, 0x382: 0xfd, 0x383: 0xfd, 0x384: 0xfd, 0x385: 0xfd, 0x386: 0xfd, 0x387: 0xfd,
+ 0x388: 0xfd, 0x389: 0xfd, 0x38a: 0xfd, 0x38b: 0xfd, 0x38c: 0xfd, 0x38d: 0xfd, 0x38e: 0xfd, 0x38f: 0xfd,
+ 0x390: 0xfd, 0x391: 0xfd, 0x392: 0xfd, 0x393: 0xfd, 0x394: 0xfd, 0x395: 0xfd, 0x396: 0xfd, 0x397: 0xfd,
+ 0x398: 0xfd, 0x399: 0xfd, 0x39a: 0xfd, 0x39b: 0xfd, 0x39c: 0xfd, 0x39d: 0xfd, 0x39e: 0xfd, 0x39f: 0xfd,
+ 0x3a0: 0xfd, 0x3a1: 0xfd, 0x3a2: 0xfd, 0x3a3: 0xfd, 0x3a4: 0xfe, 0x3a5: 0xff, 0x3a6: 0x100, 0x3a7: 0x101,
+ 0x3a8: 0x45, 0x3a9: 0x102, 0x3aa: 0x103, 0x3ab: 0x46, 0x3ac: 0x47, 0x3ad: 0x48, 0x3ae: 0x49, 0x3af: 0x4a,
+ 0x3b0: 0x104, 0x3b1: 0x4b, 0x3b2: 0x4c, 0x3b3: 0x4d, 0x3b4: 0x4e, 0x3b5: 0x4f, 0x3b6: 0x105, 0x3b7: 0x50,
+ 0x3b8: 0x51, 0x3b9: 0x52, 0x3ba: 0x53, 0x3bb: 0x54, 0x3bc: 0x55, 0x3bd: 0x56, 0x3be: 0x57, 0x3bf: 0x58,
+ // Block 0xf, offset 0x3c0
+ 0x3c0: 0x106, 0x3c1: 0x107, 0x3c2: 0xa0, 0x3c3: 0x108, 0x3c4: 0x109, 0x3c5: 0x9c, 0x3c6: 0x10a, 0x3c7: 0x10b,
+ 0x3c8: 0xfd, 0x3c9: 0xfd, 0x3ca: 0x10c, 0x3cb: 0x10d, 0x3cc: 0x10e, 0x3cd: 0x10f, 0x3ce: 0x110, 0x3cf: 0x111,
+ 0x3d0: 0x112, 0x3d1: 0xa0, 0x3d2: 0x113, 0x3d3: 0x114, 0x3d4: 0x115, 0x3d5: 0x116, 0x3d6: 0xfd, 0x3d7: 0xfd,
+ 0x3d8: 0xa0, 0x3d9: 0xa0, 0x3da: 0xa0, 0x3db: 0xa0, 0x3dc: 0x117, 0x3dd: 0x118, 0x3de: 0xfd, 0x3df: 0xfd,
+ 0x3e0: 0x119, 0x3e1: 0x11a, 0x3e2: 0x11b, 0x3e3: 0x11c, 0x3e4: 0x11d, 0x3e5: 0xfd, 0x3e6: 0x11e, 0x3e7: 0x11f,
+ 0x3e8: 0x120, 0x3e9: 0x121, 0x3ea: 0x122, 0x3eb: 0x59, 0x3ec: 0x123, 0x3ed: 0x124, 0x3ee: 0x5a, 0x3ef: 0xfd,
+ 0x3f0: 0x125, 0x3f1: 0x126, 0x3f2: 0x127, 0x3f3: 0x128, 0x3f4: 0x129, 0x3f5: 0xfd, 0x3f6: 0xfd, 0x3f7: 0xfd,
+ 0x3f8: 0xfd, 0x3f9: 0x12a, 0x3fa: 0x12b, 0x3fb: 0xfd, 0x3fc: 0x12c, 0x3fd: 0x12d, 0x3fe: 0x12e, 0x3ff: 0x12f,
+ // Block 0x10, offset 0x400
+ 0x400: 0x130, 0x401: 0x131, 0x402: 0x132, 0x403: 0x133, 0x404: 0x134, 0x405: 0x135, 0x406: 0x136, 0x407: 0x137,
+ 0x408: 0x138, 0x409: 0xfd, 0x40a: 0x139, 0x40b: 0x13a, 0x40c: 0x5b, 0x40d: 0x5c, 0x40e: 0xfd, 0x40f: 0xfd,
+ 0x410: 0x13b, 0x411: 0x13c, 0x412: 0x13d, 0x413: 0x13e, 0x414: 0xfd, 0x415: 0xfd, 0x416: 0x13f, 0x417: 0x140,
+ 0x418: 0x141, 0x419: 0x142, 0x41a: 0x143, 0x41b: 0x144, 0x41c: 0x145, 0x41d: 0xfd, 0x41e: 0xfd, 0x41f: 0xfd,
+ 0x420: 0x146, 0x421: 0xfd, 0x422: 0x147, 0x423: 0x148, 0x424: 0x5d, 0x425: 0x149, 0x426: 0x14a, 0x427: 0x14b,
+ 0x428: 0x14c, 0x429: 0x14d, 0x42a: 0x14e, 0x42b: 0x14f, 0x42c: 0xfd, 0x42d: 0xfd, 0x42e: 0xfd, 0x42f: 0xfd,
+ 0x430: 0x150, 0x431: 0x151, 0x432: 0x152, 0x433: 0xfd, 0x434: 0x153, 0x435: 0x154, 0x436: 0x155, 0x437: 0xfd,
+ 0x438: 0xfd, 0x439: 0xfd, 0x43a: 0xfd, 0x43b: 0x156, 0x43c: 0xfd, 0x43d: 0xfd, 0x43e: 0x157, 0x43f: 0x158,
+ // Block 0x11, offset 0x440
+ 0x440: 0xa0, 0x441: 0xa0, 0x442: 0xa0, 0x443: 0xa0, 0x444: 0xa0, 0x445: 0xa0, 0x446: 0xa0, 0x447: 0xa0,
+ 0x448: 0xa0, 0x449: 0xa0, 0x44a: 0xa0, 0x44b: 0xa0, 0x44c: 0xa0, 0x44d: 0xa0, 0x44e: 0x159, 0x44f: 0xfd,
+ 0x450: 0x9c, 0x451: 0x15a, 0x452: 0xa0, 0x453: 0xa0, 0x454: 0xa0, 0x455: 0x15b, 0x456: 0xfd, 0x457: 0xfd,
+ 0x458: 0xfd, 0x459: 0xfd, 0x45a: 0xfd, 0x45b: 0xfd, 0x45c: 0xfd, 0x45d: 0xfd, 0x45e: 0xfd, 0x45f: 0xfd,
+ 0x460: 0xfd, 0x461: 0xfd, 0x462: 0xfd, 0x463: 0xfd, 0x464: 0xfd, 0x465: 0xfd, 0x466: 0xfd, 0x467: 0xfd,
+ 0x468: 0xfd, 0x469: 0xfd, 0x46a: 0xfd, 0x46b: 0xfd, 0x46c: 0xfd, 0x46d: 0xfd, 0x46e: 0xfd, 0x46f: 0xfd,
+ 0x470: 0xfd, 0x471: 0xfd, 0x472: 0xfd, 0x473: 0xfd, 0x474: 0xfd, 0x475: 0xfd, 0x476: 0xfd, 0x477: 0xfd,
+ 0x478: 0xfd, 0x479: 0xfd, 0x47a: 0xfd, 0x47b: 0xfd, 0x47c: 0xfd, 0x47d: 0xfd, 0x47e: 0xfd, 0x47f: 0xfd,
+ // Block 0x12, offset 0x480
+ 0x480: 0xa0, 0x481: 0xa0, 0x482: 0xa0, 0x483: 0xa0, 0x484: 0xa0, 0x485: 0xa0, 0x486: 0xa0, 0x487: 0xa0,
+ 0x488: 0xa0, 0x489: 0xa0, 0x48a: 0xa0, 0x48b: 0xa0, 0x48c: 0xa0, 0x48d: 0xa0, 0x48e: 0xa0, 0x48f: 0xa0,
+ 0x490: 0x15c, 0x491: 0xfd, 0x492: 0xfd, 0x493: 0xfd, 0x494: 0xfd, 0x495: 0xfd, 0x496: 0xfd, 0x497: 0xfd,
+ 0x498: 0xfd, 0x499: 0xfd, 0x49a: 0xfd, 0x49b: 0xfd, 0x49c: 0xfd, 0x49d: 0xfd, 0x49e: 0xfd, 0x49f: 0xfd,
+ 0x4a0: 0xfd, 0x4a1: 0xfd, 0x4a2: 0xfd, 0x4a3: 0xfd, 0x4a4: 0xfd, 0x4a5: 0xfd, 0x4a6: 0xfd, 0x4a7: 0xfd,
+ 0x4a8: 0xfd, 0x4a9: 0xfd, 0x4aa: 0xfd, 0x4ab: 0xfd, 0x4ac: 0xfd, 0x4ad: 0xfd, 0x4ae: 0xfd, 0x4af: 0xfd,
+ 0x4b0: 0xfd, 0x4b1: 0xfd, 0x4b2: 0xfd, 0x4b3: 0xfd, 0x4b4: 0xfd, 0x4b5: 0xfd, 0x4b6: 0xfd, 0x4b7: 0xfd,
+ 0x4b8: 0xfd, 0x4b9: 0xfd, 0x4ba: 0xfd, 0x4bb: 0xfd, 0x4bc: 0xfd, 0x4bd: 0xfd, 0x4be: 0xfd, 0x4bf: 0xfd,
+ // Block 0x13, offset 0x4c0
+ 0x4c0: 0xfd, 0x4c1: 0xfd, 0x4c2: 0xfd, 0x4c3: 0xfd, 0x4c4: 0xfd, 0x4c5: 0xfd, 0x4c6: 0xfd, 0x4c7: 0xfd,
+ 0x4c8: 0xfd, 0x4c9: 0xfd, 0x4ca: 0xfd, 0x4cb: 0xfd, 0x4cc: 0xfd, 0x4cd: 0xfd, 0x4ce: 0xfd, 0x4cf: 0xfd,
+ 0x4d0: 0xa0, 0x4d1: 0xa0, 0x4d2: 0xa0, 0x4d3: 0xa0, 0x4d4: 0xa0, 0x4d5: 0xa0, 0x4d6: 0xa0, 0x4d7: 0xa0,
+ 0x4d8: 0xa0, 0x4d9: 0x15d, 0x4da: 0xfd, 0x4db: 0xfd, 0x4dc: 0xfd, 0x4dd: 0xfd, 0x4de: 0xfd, 0x4df: 0xfd,
+ 0x4e0: 0xfd, 0x4e1: 0xfd, 0x4e2: 0xfd, 0x4e3: 0xfd, 0x4e4: 0xfd, 0x4e5: 0xfd, 0x4e6: 0xfd, 0x4e7: 0xfd,
+ 0x4e8: 0xfd, 0x4e9: 0xfd, 0x4ea: 0xfd, 0x4eb: 0xfd, 0x4ec: 0xfd, 0x4ed: 0xfd, 0x4ee: 0xfd, 0x4ef: 0xfd,
+ 0x4f0: 0xfd, 0x4f1: 0xfd, 0x4f2: 0xfd, 0x4f3: 0xfd, 0x4f4: 0xfd, 0x4f5: 0xfd, 0x4f6: 0xfd, 0x4f7: 0xfd,
+ 0x4f8: 0xfd, 0x4f9: 0xfd, 0x4fa: 0xfd, 0x4fb: 0xfd, 0x4fc: 0xfd, 0x4fd: 0xfd, 0x4fe: 0xfd, 0x4ff: 0xfd,
+ // Block 0x14, offset 0x500
+ 0x500: 0xfd, 0x501: 0xfd, 0x502: 0xfd, 0x503: 0xfd, 0x504: 0xfd, 0x505: 0xfd, 0x506: 0xfd, 0x507: 0xfd,
+ 0x508: 0xfd, 0x509: 0xfd, 0x50a: 0xfd, 0x50b: 0xfd, 0x50c: 0xfd, 0x50d: 0xfd, 0x50e: 0xfd, 0x50f: 0xfd,
+ 0x510: 0xfd, 0x511: 0xfd, 0x512: 0xfd, 0x513: 0xfd, 0x514: 0xfd, 0x515: 0xfd, 0x516: 0xfd, 0x517: 0xfd,
+ 0x518: 0xfd, 0x519: 0xfd, 0x51a: 0xfd, 0x51b: 0xfd, 0x51c: 0xfd, 0x51d: 0xfd, 0x51e: 0xfd, 0x51f: 0xfd,
+ 0x520: 0xa0, 0x521: 0xa0, 0x522: 0xa0, 0x523: 0xa0, 0x524: 0xa0, 0x525: 0xa0, 0x526: 0xa0, 0x527: 0xa0,
+ 0x528: 0x14f, 0x529: 0x15e, 0x52a: 0xfd, 0x52b: 0x15f, 0x52c: 0x160, 0x52d: 0x161, 0x52e: 0x162, 0x52f: 0xfd,
+ 0x530: 0xfd, 0x531: 0xfd, 0x532: 0xfd, 0x533: 0xfd, 0x534: 0xfd, 0x535: 0xfd, 0x536: 0xfd, 0x537: 0xfd,
+ 0x538: 0xfd, 0x539: 0x163, 0x53a: 0x164, 0x53b: 0xfd, 0x53c: 0xa0, 0x53d: 0x165, 0x53e: 0x166, 0x53f: 0x167,
+ // Block 0x15, offset 0x540
+ 0x540: 0xa0, 0x541: 0xa0, 0x542: 0xa0, 0x543: 0xa0, 0x544: 0xa0, 0x545: 0xa0, 0x546: 0xa0, 0x547: 0xa0,
+ 0x548: 0xa0, 0x549: 0xa0, 0x54a: 0xa0, 0x54b: 0xa0, 0x54c: 0xa0, 0x54d: 0xa0, 0x54e: 0xa0, 0x54f: 0xa0,
+ 0x550: 0xa0, 0x551: 0xa0, 0x552: 0xa0, 0x553: 0xa0, 0x554: 0xa0, 0x555: 0xa0, 0x556: 0xa0, 0x557: 0xa0,
+ 0x558: 0xa0, 0x559: 0xa0, 0x55a: 0xa0, 0x55b: 0xa0, 0x55c: 0xa0, 0x55d: 0xa0, 0x55e: 0xa0, 0x55f: 0x168,
+ 0x560: 0xa0, 0x561: 0xa0, 0x562: 0xa0, 0x563: 0xa0, 0x564: 0xa0, 0x565: 0xa0, 0x566: 0xa0, 0x567: 0xa0,
+ 0x568: 0xa0, 0x569: 0xa0, 0x56a: 0xa0, 0x56b: 0xa0, 0x56c: 0xa0, 0x56d: 0xa0, 0x56e: 0xa0, 0x56f: 0xa0,
+ 0x570: 0xa0, 0x571: 0xa0, 0x572: 0xa0, 0x573: 0x169, 0x574: 0x16a, 0x575: 0xfd, 0x576: 0xfd, 0x577: 0xfd,
+ 0x578: 0xfd, 0x579: 0xfd, 0x57a: 0xfd, 0x57b: 0xfd, 0x57c: 0xfd, 0x57d: 0xfd, 0x57e: 0xfd, 0x57f: 0xfd,
+ // Block 0x16, offset 0x580
+ 0x580: 0xa0, 0x581: 0xa0, 0x582: 0xa0, 0x583: 0xa0, 0x584: 0x16b, 0x585: 0x16c, 0x586: 0xa0, 0x587: 0xa0,
+ 0x588: 0xa0, 0x589: 0xa0, 0x58a: 0xa0, 0x58b: 0x16d, 0x58c: 0xfd, 0x58d: 0xfd, 0x58e: 0xfd, 0x58f: 0xfd,
+ 0x590: 0xfd, 0x591: 0xfd, 0x592: 0xfd, 0x593: 0xfd, 0x594: 0xfd, 0x595: 0xfd, 0x596: 0xfd, 0x597: 0xfd,
+ 0x598: 0xfd, 0x599: 0xfd, 0x59a: 0xfd, 0x59b: 0xfd, 0x59c: 0xfd, 0x59d: 0xfd, 0x59e: 0xfd, 0x59f: 0xfd,
+ 0x5a0: 0xfd, 0x5a1: 0xfd, 0x5a2: 0xfd, 0x5a3: 0xfd, 0x5a4: 0xfd, 0x5a5: 0xfd, 0x5a6: 0xfd, 0x5a7: 0xfd,
+ 0x5a8: 0xfd, 0x5a9: 0xfd, 0x5aa: 0xfd, 0x5ab: 0xfd, 0x5ac: 0xfd, 0x5ad: 0xfd, 0x5ae: 0xfd, 0x5af: 0xfd,
+ 0x5b0: 0xa0, 0x5b1: 0x16e, 0x5b2: 0x16f, 0x5b3: 0xfd, 0x5b4: 0xfd, 0x5b5: 0xfd, 0x5b6: 0xfd, 0x5b7: 0xfd,
+ 0x5b8: 0xfd, 0x5b9: 0xfd, 0x5ba: 0xfd, 0x5bb: 0xfd, 0x5bc: 0xfd, 0x5bd: 0xfd, 0x5be: 0xfd, 0x5bf: 0xfd,
+ // Block 0x17, offset 0x5c0
+ 0x5c0: 0x9c, 0x5c1: 0x9c, 0x5c2: 0x9c, 0x5c3: 0x170, 0x5c4: 0x171, 0x5c5: 0x172, 0x5c6: 0x173, 0x5c7: 0x174,
+ 0x5c8: 0x9c, 0x5c9: 0x175, 0x5ca: 0xfd, 0x5cb: 0x176, 0x5cc: 0x9c, 0x5cd: 0x177, 0x5ce: 0xfd, 0x5cf: 0xfd,
+ 0x5d0: 0x5e, 0x5d1: 0x5f, 0x5d2: 0x60, 0x5d3: 0x61, 0x5d4: 0x62, 0x5d5: 0x63, 0x5d6: 0x64, 0x5d7: 0x65,
+ 0x5d8: 0x66, 0x5d9: 0x67, 0x5da: 0x68, 0x5db: 0x69, 0x5dc: 0x6a, 0x5dd: 0x6b, 0x5de: 0x6c, 0x5df: 0x6d,
+ 0x5e0: 0x9c, 0x5e1: 0x9c, 0x5e2: 0x9c, 0x5e3: 0x9c, 0x5e4: 0x9c, 0x5e5: 0x9c, 0x5e6: 0x9c, 0x5e7: 0x9c,
+ 0x5e8: 0x178, 0x5e9: 0x179, 0x5ea: 0x17a, 0x5eb: 0xfd, 0x5ec: 0xfd, 0x5ed: 0xfd, 0x5ee: 0xfd, 0x5ef: 0xfd,
+ 0x5f0: 0xfd, 0x5f1: 0xfd, 0x5f2: 0xfd, 0x5f3: 0xfd, 0x5f4: 0xfd, 0x5f5: 0xfd, 0x5f6: 0xfd, 0x5f7: 0xfd,
+ 0x5f8: 0xfd, 0x5f9: 0xfd, 0x5fa: 0xfd, 0x5fb: 0xfd, 0x5fc: 0xfd, 0x5fd: 0xfd, 0x5fe: 0xfd, 0x5ff: 0xfd,
+ // Block 0x18, offset 0x600
+ 0x600: 0x17b, 0x601: 0xfd, 0x602: 0xfd, 0x603: 0xfd, 0x604: 0x17c, 0x605: 0x17d, 0x606: 0xfd, 0x607: 0xfd,
+ 0x608: 0xfd, 0x609: 0xfd, 0x60a: 0xfd, 0x60b: 0x17e, 0x60c: 0xfd, 0x60d: 0xfd, 0x60e: 0xfd, 0x60f: 0xfd,
+ 0x610: 0xfd, 0x611: 0xfd, 0x612: 0xfd, 0x613: 0xfd, 0x614: 0xfd, 0x615: 0xfd, 0x616: 0xfd, 0x617: 0xfd,
+ 0x618: 0xfd, 0x619: 0xfd, 0x61a: 0xfd, 0x61b: 0xfd, 0x61c: 0xfd, 0x61d: 0xfd, 0x61e: 0xfd, 0x61f: 0xfd,
+ 0x620: 0x125, 0x621: 0x125, 0x622: 0x125, 0x623: 0x17f, 0x624: 0x6e, 0x625: 0x180, 0x626: 0xfd, 0x627: 0xfd,
+ 0x628: 0xfd, 0x629: 0xfd, 0x62a: 0xfd, 0x62b: 0xfd, 0x62c: 0xfd, 0x62d: 0xfd, 0x62e: 0xfd, 0x62f: 0xfd,
+ 0x630: 0xfd, 0x631: 0x181, 0x632: 0x182, 0x633: 0xfd, 0x634: 0x183, 0x635: 0xfd, 0x636: 0xfd, 0x637: 0xfd,
+ 0x638: 0x6f, 0x639: 0x70, 0x63a: 0x71, 0x63b: 0x184, 0x63c: 0xfd, 0x63d: 0xfd, 0x63e: 0xfd, 0x63f: 0xfd,
+ // Block 0x19, offset 0x640
+ 0x640: 0x185, 0x641: 0x9c, 0x642: 0x186, 0x643: 0x187, 0x644: 0x72, 0x645: 0x73, 0x646: 0x188, 0x647: 0x189,
+ 0x648: 0x74, 0x649: 0x18a, 0x64a: 0xfd, 0x64b: 0xfd, 0x64c: 0x9c, 0x64d: 0x9c, 0x64e: 0x9c, 0x64f: 0x9c,
+ 0x650: 0x9c, 0x651: 0x9c, 0x652: 0x9c, 0x653: 0x9c, 0x654: 0x9c, 0x655: 0x9c, 0x656: 0x9c, 0x657: 0x9c,
+ 0x658: 0x9c, 0x659: 0x9c, 0x65a: 0x9c, 0x65b: 0x18b, 0x65c: 0x9c, 0x65d: 0x18c, 0x65e: 0x9c, 0x65f: 0x18d,
+ 0x660: 0x18e, 0x661: 0x18f, 0x662: 0x190, 0x663: 0xfd, 0x664: 0x9c, 0x665: 0x191, 0x666: 0x9c, 0x667: 0x192,
+ 0x668: 0x9c, 0x669: 0x193, 0x66a: 0x194, 0x66b: 0x195, 0x66c: 0x9c, 0x66d: 0x9c, 0x66e: 0x196, 0x66f: 0x197,
+ 0x670: 0xfd, 0x671: 0xfd, 0x672: 0xfd, 0x673: 0xfd, 0x674: 0xfd, 0x675: 0xfd, 0x676: 0xfd, 0x677: 0xfd,
+ 0x678: 0xfd, 0x679: 0xfd, 0x67a: 0xfd, 0x67b: 0xfd, 0x67c: 0xfd, 0x67d: 0xfd, 0x67e: 0xfd, 0x67f: 0xfd,
+ // Block 0x1a, offset 0x680
+ 0x680: 0xa0, 0x681: 0xa0, 0x682: 0xa0, 0x683: 0xa0, 0x684: 0xa0, 0x685: 0xa0, 0x686: 0xa0, 0x687: 0xa0,
+ 0x688: 0xa0, 0x689: 0xa0, 0x68a: 0xa0, 0x68b: 0xa0, 0x68c: 0xa0, 0x68d: 0xa0, 0x68e: 0xa0, 0x68f: 0xa0,
+ 0x690: 0xa0, 0x691: 0xa0, 0x692: 0xa0, 0x693: 0xa0, 0x694: 0xa0, 0x695: 0xa0, 0x696: 0xa0, 0x697: 0xa0,
+ 0x698: 0xa0, 0x699: 0xa0, 0x69a: 0xa0, 0x69b: 0x198, 0x69c: 0xa0, 0x69d: 0xa0, 0x69e: 0xa0, 0x69f: 0xa0,
+ 0x6a0: 0xa0, 0x6a1: 0xa0, 0x6a2: 0xa0, 0x6a3: 0xa0, 0x6a4: 0xa0, 0x6a5: 0xa0, 0x6a6: 0xa0, 0x6a7: 0xa0,
+ 0x6a8: 0xa0, 0x6a9: 0xa0, 0x6aa: 0xa0, 0x6ab: 0xa0, 0x6ac: 0xa0, 0x6ad: 0xa0, 0x6ae: 0xa0, 0x6af: 0xa0,
+ 0x6b0: 0xa0, 0x6b1: 0xa0, 0x6b2: 0xa0, 0x6b3: 0xa0, 0x6b4: 0xa0, 0x6b5: 0xa0, 0x6b6: 0xa0, 0x6b7: 0xa0,
+ 0x6b8: 0xa0, 0x6b9: 0xa0, 0x6ba: 0xa0, 0x6bb: 0xa0, 0x6bc: 0xa0, 0x6bd: 0xa0, 0x6be: 0xa0, 0x6bf: 0xa0,
+ // Block 0x1b, offset 0x6c0
+ 0x6c0: 0xa0, 0x6c1: 0xa0, 0x6c2: 0xa0, 0x6c3: 0xa0, 0x6c4: 0xa0, 0x6c5: 0xa0, 0x6c6: 0xa0, 0x6c7: 0xa0,
+ 0x6c8: 0xa0, 0x6c9: 0xa0, 0x6ca: 0xa0, 0x6cb: 0xa0, 0x6cc: 0xa0, 0x6cd: 0xa0, 0x6ce: 0xa0, 0x6cf: 0xa0,
+ 0x6d0: 0xa0, 0x6d1: 0xa0, 0x6d2: 0xa0, 0x6d3: 0xa0, 0x6d4: 0xa0, 0x6d5: 0xa0, 0x6d6: 0xa0, 0x6d7: 0xa0,
+ 0x6d8: 0xa0, 0x6d9: 0xa0, 0x6da: 0xa0, 0x6db: 0xa0, 0x6dc: 0x199, 0x6dd: 0xa0, 0x6de: 0xa0, 0x6df: 0xa0,
+ 0x6e0: 0x19a, 0x6e1: 0xa0, 0x6e2: 0xa0, 0x6e3: 0xa0, 0x6e4: 0xa0, 0x6e5: 0xa0, 0x6e6: 0xa0, 0x6e7: 0xa0,
+ 0x6e8: 0xa0, 0x6e9: 0xa0, 0x6ea: 0xa0, 0x6eb: 0xa0, 0x6ec: 0xa0, 0x6ed: 0xa0, 0x6ee: 0xa0, 0x6ef: 0xa0,
+ 0x6f0: 0xa0, 0x6f1: 0xa0, 0x6f2: 0xa0, 0x6f3: 0xa0, 0x6f4: 0xa0, 0x6f5: 0xa0, 0x6f6: 0xa0, 0x6f7: 0xa0,
+ 0x6f8: 0xa0, 0x6f9: 0xa0, 0x6fa: 0xa0, 0x6fb: 0xa0, 0x6fc: 0xa0, 0x6fd: 0xa0, 0x6fe: 0xa0, 0x6ff: 0xa0,
+ // Block 0x1c, offset 0x700
+ 0x700: 0xa0, 0x701: 0xa0, 0x702: 0xa0, 0x703: 0xa0, 0x704: 0xa0, 0x705: 0xa0, 0x706: 0xa0, 0x707: 0xa0,
+ 0x708: 0xa0, 0x709: 0xa0, 0x70a: 0xa0, 0x70b: 0xa0, 0x70c: 0xa0, 0x70d: 0xa0, 0x70e: 0xa0, 0x70f: 0xa0,
+ 0x710: 0xa0, 0x711: 0xa0, 0x712: 0xa0, 0x713: 0xa0, 0x714: 0xa0, 0x715: 0xa0, 0x716: 0xa0, 0x717: 0xa0,
+ 0x718: 0xa0, 0x719: 0xa0, 0x71a: 0xa0, 0x71b: 0xa0, 0x71c: 0xa0, 0x71d: 0xa0, 0x71e: 0xa0, 0x71f: 0xa0,
+ 0x720: 0xa0, 0x721: 0xa0, 0x722: 0xa0, 0x723: 0xa0, 0x724: 0xa0, 0x725: 0xa0, 0x726: 0xa0, 0x727: 0xa0,
+ 0x728: 0xa0, 0x729: 0xa0, 0x72a: 0xa0, 0x72b: 0xa0, 0x72c: 0xa0, 0x72d: 0xa0, 0x72e: 0xa0, 0x72f: 0xa0,
+ 0x730: 0xa0, 0x731: 0xa0, 0x732: 0xa0, 0x733: 0xa0, 0x734: 0xa0, 0x735: 0xa0, 0x736: 0xa0, 0x737: 0xa0,
+ 0x738: 0xa0, 0x739: 0xa0, 0x73a: 0x19b, 0x73b: 0xa0, 0x73c: 0xa0, 0x73d: 0xa0, 0x73e: 0xa0, 0x73f: 0xa0,
+ // Block 0x1d, offset 0x740
+ 0x740: 0xa0, 0x741: 0xa0, 0x742: 0xa0, 0x743: 0xa0, 0x744: 0xa0, 0x745: 0xa0, 0x746: 0xa0, 0x747: 0xa0,
+ 0x748: 0xa0, 0x749: 0xa0, 0x74a: 0xa0, 0x74b: 0xa0, 0x74c: 0xa0, 0x74d: 0xa0, 0x74e: 0xa0, 0x74f: 0xa0,
+ 0x750: 0xa0, 0x751: 0xa0, 0x752: 0xa0, 0x753: 0xa0, 0x754: 0xa0, 0x755: 0xa0, 0x756: 0xa0, 0x757: 0xa0,
+ 0x758: 0xa0, 0x759: 0xa0, 0x75a: 0xa0, 0x75b: 0xa0, 0x75c: 0xa0, 0x75d: 0xa0, 0x75e: 0xa0, 0x75f: 0xa0,
+ 0x760: 0xa0, 0x761: 0xa0, 0x762: 0xa0, 0x763: 0xa0, 0x764: 0xa0, 0x765: 0xa0, 0x766: 0xa0, 0x767: 0xa0,
+ 0x768: 0xa0, 0x769: 0xa0, 0x76a: 0xa0, 0x76b: 0xa0, 0x76c: 0xa0, 0x76d: 0xa0, 0x76e: 0xa0, 0x76f: 0x19c,
+ 0x770: 0xfd, 0x771: 0xfd, 0x772: 0xfd, 0x773: 0xfd, 0x774: 0xfd, 0x775: 0xfd, 0x776: 0xfd, 0x777: 0xfd,
+ 0x778: 0xfd, 0x779: 0xfd, 0x77a: 0xfd, 0x77b: 0xfd, 0x77c: 0xfd, 0x77d: 0xfd, 0x77e: 0xfd, 0x77f: 0xfd,
+ // Block 0x1e, offset 0x780
+ 0x780: 0xfd, 0x781: 0xfd, 0x782: 0xfd, 0x783: 0xfd, 0x784: 0xfd, 0x785: 0xfd, 0x786: 0xfd, 0x787: 0xfd,
+ 0x788: 0xfd, 0x789: 0xfd, 0x78a: 0xfd, 0x78b: 0xfd, 0x78c: 0xfd, 0x78d: 0xfd, 0x78e: 0xfd, 0x78f: 0xfd,
+ 0x790: 0xfd, 0x791: 0xfd, 0x792: 0xfd, 0x793: 0xfd, 0x794: 0xfd, 0x795: 0xfd, 0x796: 0xfd, 0x797: 0xfd,
+ 0x798: 0xfd, 0x799: 0xfd, 0x79a: 0xfd, 0x79b: 0xfd, 0x79c: 0xfd, 0x79d: 0xfd, 0x79e: 0xfd, 0x79f: 0xfd,
+ 0x7a0: 0x75, 0x7a1: 0x76, 0x7a2: 0x77, 0x7a3: 0x78, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x7b, 0x7a7: 0x7c,
+ 0x7a8: 0x7d, 0x7a9: 0xfd, 0x7aa: 0xfd, 0x7ab: 0xfd, 0x7ac: 0xfd, 0x7ad: 0xfd, 0x7ae: 0xfd, 0x7af: 0xfd,
+ 0x7b0: 0xfd, 0x7b1: 0xfd, 0x7b2: 0xfd, 0x7b3: 0xfd, 0x7b4: 0xfd, 0x7b5: 0xfd, 0x7b6: 0xfd, 0x7b7: 0xfd,
+ 0x7b8: 0xfd, 0x7b9: 0xfd, 0x7ba: 0xfd, 0x7bb: 0xfd, 0x7bc: 0xfd, 0x7bd: 0xfd, 0x7be: 0xfd, 0x7bf: 0xfd,
+ // Block 0x1f, offset 0x7c0
+ 0x7c0: 0xa0, 0x7c1: 0xa0, 0x7c2: 0xa0, 0x7c3: 0xa0, 0x7c4: 0xa0, 0x7c5: 0xa0, 0x7c6: 0xa0, 0x7c7: 0xa0,
+ 0x7c8: 0xa0, 0x7c9: 0xa0, 0x7ca: 0xa0, 0x7cb: 0xa0, 0x7cc: 0xa0, 0x7cd: 0x19d, 0x7ce: 0xfd, 0x7cf: 0xfd,
+ 0x7d0: 0xfd, 0x7d1: 0xfd, 0x7d2: 0xfd, 0x7d3: 0xfd, 0x7d4: 0xfd, 0x7d5: 0xfd, 0x7d6: 0xfd, 0x7d7: 0xfd,
+ 0x7d8: 0xfd, 0x7d9: 0xfd, 0x7da: 0xfd, 0x7db: 0xfd, 0x7dc: 0xfd, 0x7dd: 0xfd, 0x7de: 0xfd, 0x7df: 0xfd,
+ 0x7e0: 0xfd, 0x7e1: 0xfd, 0x7e2: 0xfd, 0x7e3: 0xfd, 0x7e4: 0xfd, 0x7e5: 0xfd, 0x7e6: 0xfd, 0x7e7: 0xfd,
+ 0x7e8: 0xfd, 0x7e9: 0xfd, 0x7ea: 0xfd, 0x7eb: 0xfd, 0x7ec: 0xfd, 0x7ed: 0xfd, 0x7ee: 0xfd, 0x7ef: 0xfd,
+ 0x7f0: 0xfd, 0x7f1: 0xfd, 0x7f2: 0xfd, 0x7f3: 0xfd, 0x7f4: 0xfd, 0x7f5: 0xfd, 0x7f6: 0xfd, 0x7f7: 0xfd,
+ 0x7f8: 0xfd, 0x7f9: 0xfd, 0x7fa: 0xfd, 0x7fb: 0xfd, 0x7fc: 0xfd, 0x7fd: 0xfd, 0x7fe: 0xfd, 0x7ff: 0xfd,
+ // Block 0x20, offset 0x800
+ 0x810: 0x0d, 0x811: 0x0e, 0x812: 0x0f, 0x813: 0x10, 0x814: 0x11, 0x815: 0x0b, 0x816: 0x12, 0x817: 0x07,
+ 0x818: 0x13, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x14, 0x81c: 0x0b, 0x81d: 0x15, 0x81e: 0x16, 0x81f: 0x17,
+ 0x820: 0x07, 0x821: 0x07, 0x822: 0x07, 0x823: 0x07, 0x824: 0x07, 0x825: 0x07, 0x826: 0x07, 0x827: 0x07,
+ 0x828: 0x07, 0x829: 0x07, 0x82a: 0x18, 0x82b: 0x19, 0x82c: 0x1a, 0x82d: 0x07, 0x82e: 0x1b, 0x82f: 0x1c,
+ 0x830: 0x07, 0x831: 0x1d, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b,
+ 0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b,
+ // Block 0x21, offset 0x840
+ 0x840: 0x0b, 0x841: 0x0b, 0x842: 0x0b, 0x843: 0x0b, 0x844: 0x0b, 0x845: 0x0b, 0x846: 0x0b, 0x847: 0x0b,
+ 0x848: 0x0b, 0x849: 0x0b, 0x84a: 0x0b, 0x84b: 0x0b, 0x84c: 0x0b, 0x84d: 0x0b, 0x84e: 0x0b, 0x84f: 0x0b,
+ 0x850: 0x0b, 0x851: 0x0b, 0x852: 0x0b, 0x853: 0x0b, 0x854: 0x0b, 0x855: 0x0b, 0x856: 0x0b, 0x857: 0x0b,
+ 0x858: 0x0b, 0x859: 0x0b, 0x85a: 0x0b, 0x85b: 0x0b, 0x85c: 0x0b, 0x85d: 0x0b, 0x85e: 0x0b, 0x85f: 0x0b,
+ 0x860: 0x0b, 0x861: 0x0b, 0x862: 0x0b, 0x863: 0x0b, 0x864: 0x0b, 0x865: 0x0b, 0x866: 0x0b, 0x867: 0x0b,
+ 0x868: 0x0b, 0x869: 0x0b, 0x86a: 0x0b, 0x86b: 0x0b, 0x86c: 0x0b, 0x86d: 0x0b, 0x86e: 0x0b, 0x86f: 0x0b,
+ 0x870: 0x0b, 0x871: 0x0b, 0x872: 0x0b, 0x873: 0x0b, 0x874: 0x0b, 0x875: 0x0b, 0x876: 0x0b, 0x877: 0x0b,
+ 0x878: 0x0b, 0x879: 0x0b, 0x87a: 0x0b, 0x87b: 0x0b, 0x87c: 0x0b, 0x87d: 0x0b, 0x87e: 0x0b, 0x87f: 0x0b,
+ // Block 0x22, offset 0x880
+ 0x880: 0x19e, 0x881: 0x19f, 0x882: 0xfd, 0x883: 0xfd, 0x884: 0x1a0, 0x885: 0x1a0, 0x886: 0x1a0, 0x887: 0x1a1,
+ 0x888: 0xfd, 0x889: 0xfd, 0x88a: 0xfd, 0x88b: 0xfd, 0x88c: 0xfd, 0x88d: 0xfd, 0x88e: 0xfd, 0x88f: 0xfd,
+ 0x890: 0xfd, 0x891: 0xfd, 0x892: 0xfd, 0x893: 0xfd, 0x894: 0xfd, 0x895: 0xfd, 0x896: 0xfd, 0x897: 0xfd,
+ 0x898: 0xfd, 0x899: 0xfd, 0x89a: 0xfd, 0x89b: 0xfd, 0x89c: 0xfd, 0x89d: 0xfd, 0x89e: 0xfd, 0x89f: 0xfd,
+ 0x8a0: 0xfd, 0x8a1: 0xfd, 0x8a2: 0xfd, 0x8a3: 0xfd, 0x8a4: 0xfd, 0x8a5: 0xfd, 0x8a6: 0xfd, 0x8a7: 0xfd,
+ 0x8a8: 0xfd, 0x8a9: 0xfd, 0x8aa: 0xfd, 0x8ab: 0xfd, 0x8ac: 0xfd, 0x8ad: 0xfd, 0x8ae: 0xfd, 0x8af: 0xfd,
+ 0x8b0: 0xfd, 0x8b1: 0xfd, 0x8b2: 0xfd, 0x8b3: 0xfd, 0x8b4: 0xfd, 0x8b5: 0xfd, 0x8b6: 0xfd, 0x8b7: 0xfd,
+ 0x8b8: 0xfd, 0x8b9: 0xfd, 0x8ba: 0xfd, 0x8bb: 0xfd, 0x8bc: 0xfd, 0x8bd: 0xfd, 0x8be: 0xfd, 0x8bf: 0xfd,
+ // Block 0x23, offset 0x8c0
+ 0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b,
+ 0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b,
+ 0x8d0: 0x0b, 0x8d1: 0x0b, 0x8d2: 0x0b, 0x8d3: 0x0b, 0x8d4: 0x0b, 0x8d5: 0x0b, 0x8d6: 0x0b, 0x8d7: 0x0b,
+ 0x8d8: 0x0b, 0x8d9: 0x0b, 0x8da: 0x0b, 0x8db: 0x0b, 0x8dc: 0x0b, 0x8dd: 0x0b, 0x8de: 0x0b, 0x8df: 0x0b,
+ 0x8e0: 0x20, 0x8e1: 0x0b, 0x8e2: 0x0b, 0x8e3: 0x0b, 0x8e4: 0x0b, 0x8e5: 0x0b, 0x8e6: 0x0b, 0x8e7: 0x0b,
+ 0x8e8: 0x0b, 0x8e9: 0x0b, 0x8ea: 0x0b, 0x8eb: 0x0b, 0x8ec: 0x0b, 0x8ed: 0x0b, 0x8ee: 0x0b, 0x8ef: 0x0b,
+ 0x8f0: 0x0b, 0x8f1: 0x0b, 0x8f2: 0x0b, 0x8f3: 0x0b, 0x8f4: 0x0b, 0x8f5: 0x0b, 0x8f6: 0x0b, 0x8f7: 0x0b,
+ 0x8f8: 0x0b, 0x8f9: 0x0b, 0x8fa: 0x0b, 0x8fb: 0x0b, 0x8fc: 0x0b, 0x8fd: 0x0b, 0x8fe: 0x0b, 0x8ff: 0x0b,
+ // Block 0x24, offset 0x900
+ 0x900: 0x0b, 0x901: 0x0b, 0x902: 0x0b, 0x903: 0x0b, 0x904: 0x0b, 0x905: 0x0b, 0x906: 0x0b, 0x907: 0x0b,
+ 0x908: 0x0b, 0x909: 0x0b, 0x90a: 0x0b, 0x90b: 0x0b, 0x90c: 0x0b, 0x90d: 0x0b, 0x90e: 0x0b, 0x90f: 0x0b,
+}
+
+// idnaSparseOffset: 292 entries, 584 bytes
+var idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x33, 0x3e, 0x4a, 0x4e, 0x5d, 0x62, 0x6c, 0x78, 0x85, 0x8b, 0x94, 0xa4, 0xb2, 0xbd, 0xca, 0xdb, 0xe5, 0xec, 0xf9, 0x10a, 0x111, 0x11c, 0x12b, 0x139, 0x143, 0x145, 0x14a, 0x14d, 0x150, 0x152, 0x15e, 0x169, 0x171, 0x177, 0x17d, 0x182, 0x187, 0x18a, 0x18e, 0x194, 0x199, 0x1a5, 0x1af, 0x1b5, 0x1c6, 0x1d0, 0x1d3, 0x1db, 0x1de, 0x1eb, 0x1f3, 0x1f7, 0x1fe, 0x206, 0x216, 0x222, 0x225, 0x22f, 0x23b, 0x247, 0x253, 0x25b, 0x260, 0x26d, 0x27e, 0x282, 0x28d, 0x291, 0x29a, 0x2a2, 0x2a8, 0x2ad, 0x2b0, 0x2b4, 0x2ba, 0x2be, 0x2c2, 0x2c6, 0x2cc, 0x2d4, 0x2db, 0x2e6, 0x2f0, 0x2f4, 0x2f7, 0x2fd, 0x301, 0x303, 0x306, 0x308, 0x30b, 0x315, 0x318, 0x327, 0x32b, 0x32f, 0x331, 0x33a, 0x33d, 0x341, 0x346, 0x34b, 0x351, 0x362, 0x372, 0x378, 0x37c, 0x38b, 0x390, 0x398, 0x3a2, 0x3ad, 0x3b5, 0x3c6, 0x3cf, 0x3df, 0x3ec, 0x3f8, 0x3fd, 0x40a, 0x40e, 0x413, 0x415, 0x417, 0x41b, 0x41d, 0x421, 0x42a, 0x430, 0x434, 0x444, 0x44e, 0x453, 0x456, 0x45c, 0x463, 0x468, 0x46c, 0x472, 0x477, 0x480, 0x485, 0x48b, 0x492, 0x499, 0x4a0, 0x4a4, 0x4a9, 0x4ac, 0x4b1, 0x4bd, 0x4c3, 0x4c8, 0x4cf, 0x4d7, 0x4dc, 0x4e0, 0x4f0, 0x4f7, 0x4fb, 0x4ff, 0x506, 0x508, 0x50b, 0x50e, 0x512, 0x51b, 0x51f, 0x527, 0x52f, 0x537, 0x543, 0x54f, 0x555, 0x55e, 0x56a, 0x571, 0x57a, 0x585, 0x58c, 0x59b, 0x5a8, 0x5b5, 0x5be, 0x5c2, 0x5d1, 0x5d9, 0x5e4, 0x5ed, 0x5f3, 0x5fb, 0x604, 0x60f, 0x612, 0x61e, 0x627, 0x62a, 0x62f, 0x638, 0x63d, 0x64a, 0x655, 0x65e, 0x668, 0x66b, 0x675, 0x67e, 0x68a, 0x697, 0x6a4, 0x6b2, 0x6b9, 0x6bd, 0x6c1, 0x6c4, 0x6c9, 0x6cc, 0x6d1, 0x6d4, 0x6db, 0x6e2, 0x6e6, 0x6f1, 0x6f4, 0x6f7, 0x6fa, 0x700, 0x706, 0x70f, 0x712, 0x715, 0x718, 0x71b, 0x722, 0x725, 0x72a, 0x734, 0x737, 0x73b, 0x74a, 0x756, 0x75a, 0x75f, 0x763, 0x768, 0x76c, 0x771, 0x77a, 0x785, 0x78b, 0x791, 0x797, 0x79d, 0x7a6, 0x7a9, 0x7ac, 0x7b0, 0x7b4, 0x7b8, 0x7be, 0x7c4, 0x7c9, 0x7cc, 0x7dc, 0x7e3, 0x7e6, 0x7eb, 0x7ef, 0x7f5, 0x7fc, 0x800, 0x804, 0x80d, 0x814, 0x819, 0x81d, 0x82b, 0x82e, 0x831, 0x835, 0x839, 0x83c, 0x83f, 0x844, 0x846, 0x848}
+
+// idnaSparseValues: 2123 entries, 8492 bytes
+var idnaSparseValues = [2123]valueRange{
+ // Block 0x0, offset 0x0
+ {value: 0x0000, lo: 0x07},
+ {value: 0xe105, lo: 0x80, hi: 0x96},
+ {value: 0x0018, lo: 0x97, hi: 0x97},
+ {value: 0xe105, lo: 0x98, hi: 0x9e},
+ {value: 0x001f, lo: 0x9f, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xb6},
+ {value: 0x0018, lo: 0xb7, hi: 0xb7},
+ {value: 0x0008, lo: 0xb8, hi: 0xbf},
+ // Block 0x1, offset 0x8
+ {value: 0x0000, lo: 0x10},
+ {value: 0x0008, lo: 0x80, hi: 0x80},
+ {value: 0xe01d, lo: 0x81, hi: 0x81},
+ {value: 0x0008, lo: 0x82, hi: 0x82},
+ {value: 0x0335, lo: 0x83, hi: 0x83},
+ {value: 0x034d, lo: 0x84, hi: 0x84},
+ {value: 0x0365, lo: 0x85, hi: 0x85},
+ {value: 0xe00d, lo: 0x86, hi: 0x86},
+ {value: 0x0008, lo: 0x87, hi: 0x87},
+ {value: 0xe00d, lo: 0x88, hi: 0x88},
+ {value: 0x0008, lo: 0x89, hi: 0x89},
+ {value: 0xe00d, lo: 0x8a, hi: 0x8a},
+ {value: 0x0008, lo: 0x8b, hi: 0x8b},
+ {value: 0xe00d, lo: 0x8c, hi: 0x8c},
+ {value: 0x0008, lo: 0x8d, hi: 0x8d},
+ {value: 0xe00d, lo: 0x8e, hi: 0x8e},
+ {value: 0x0008, lo: 0x8f, hi: 0xbf},
+ // Block 0x2, offset 0x19
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0008, lo: 0x80, hi: 0xaf},
+ {value: 0x00a9, lo: 0xb0, hi: 0xb0},
+ {value: 0x037d, lo: 0xb1, hi: 0xb1},
+ {value: 0x00b1, lo: 0xb2, hi: 0xb2},
+ {value: 0x00b9, lo: 0xb3, hi: 0xb3},
+ {value: 0x034d, lo: 0xb4, hi: 0xb4},
+ {value: 0x0395, lo: 0xb5, hi: 0xb5},
+ {value: 0xe1bd, lo: 0xb6, hi: 0xb6},
+ {value: 0x00c1, lo: 0xb7, hi: 0xb7},
+ {value: 0x00c9, lo: 0xb8, hi: 0xb8},
+ {value: 0x0008, lo: 0xb9, hi: 0xbf},
+ // Block 0x3, offset 0x25
+ {value: 0x0000, lo: 0x01},
+ {value: 0x3308, lo: 0x80, hi: 0xbf},
+ // Block 0x4, offset 0x27
+ {value: 0x0000, lo: 0x04},
+ {value: 0x03f5, lo: 0x80, hi: 0x8f},
+ {value: 0xe105, lo: 0x90, hi: 0x9f},
+ {value: 0x049d, lo: 0xa0, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbf},
+ // Block 0x5, offset 0x2c
+ {value: 0x0000, lo: 0x06},
+ {value: 0xe185, lo: 0x80, hi: 0x8f},
+ {value: 0x0545, lo: 0x90, hi: 0x96},
+ {value: 0x0040, lo: 0x97, hi: 0x98},
+ {value: 0x0008, lo: 0x99, hi: 0x99},
+ {value: 0x0018, lo: 0x9a, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xbf},
+ // Block 0x6, offset 0x33
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x0008, lo: 0x80, hi: 0x86},
+ {value: 0x0131, lo: 0x87, hi: 0x87},
+ {value: 0x0008, lo: 0x88, hi: 0x88},
+ {value: 0x0018, lo: 0x89, hi: 0x8a},
+ {value: 0x0040, lo: 0x8b, hi: 0x8c},
+ {value: 0x0018, lo: 0x8d, hi: 0x8f},
+ {value: 0x0040, lo: 0x90, hi: 0x90},
+ {value: 0x3308, lo: 0x91, hi: 0xbd},
+ {value: 0x0818, lo: 0xbe, hi: 0xbe},
+ {value: 0x3308, lo: 0xbf, hi: 0xbf},
+ // Block 0x7, offset 0x3e
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0818, lo: 0x80, hi: 0x80},
+ {value: 0x3308, lo: 0x81, hi: 0x82},
+ {value: 0x0818, lo: 0x83, hi: 0x83},
+ {value: 0x3308, lo: 0x84, hi: 0x85},
+ {value: 0x0818, lo: 0x86, hi: 0x86},
+ {value: 0x3308, lo: 0x87, hi: 0x87},
+ {value: 0x0040, lo: 0x88, hi: 0x8f},
+ {value: 0x0808, lo: 0x90, hi: 0xaa},
+ {value: 0x0040, lo: 0xab, hi: 0xae},
+ {value: 0x0808, lo: 0xaf, hi: 0xb4},
+ {value: 0x0040, lo: 0xb5, hi: 0xbf},
+ // Block 0x8, offset 0x4a
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0a08, lo: 0x80, hi: 0x87},
+ {value: 0x0c08, lo: 0x88, hi: 0x99},
+ {value: 0x0a08, lo: 0x9a, hi: 0xbf},
+ // Block 0x9, offset 0x4e
+ {value: 0x0000, lo: 0x0e},
+ {value: 0x3308, lo: 0x80, hi: 0x8a},
+ {value: 0x0040, lo: 0x8b, hi: 0x8c},
+ {value: 0x0c08, lo: 0x8d, hi: 0x8d},
+ {value: 0x0a08, lo: 0x8e, hi: 0x98},
+ {value: 0x0c08, lo: 0x99, hi: 0x9b},
+ {value: 0x0a08, lo: 0x9c, hi: 0xaa},
+ {value: 0x0c08, lo: 0xab, hi: 0xac},
+ {value: 0x0a08, lo: 0xad, hi: 0xb0},
+ {value: 0x0c08, lo: 0xb1, hi: 0xb1},
+ {value: 0x0a08, lo: 0xb2, hi: 0xb2},
+ {value: 0x0c08, lo: 0xb3, hi: 0xb4},
+ {value: 0x0a08, lo: 0xb5, hi: 0xb7},
+ {value: 0x0c08, lo: 0xb8, hi: 0xb9},
+ {value: 0x0a08, lo: 0xba, hi: 0xbf},
+ // Block 0xa, offset 0x5d
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0808, lo: 0x80, hi: 0xa5},
+ {value: 0x3308, lo: 0xa6, hi: 0xb0},
+ {value: 0x0808, lo: 0xb1, hi: 0xb1},
+ {value: 0x0040, lo: 0xb2, hi: 0xbf},
+ // Block 0xb, offset 0x62
+ {value: 0x0000, lo: 0x09},
+ {value: 0x0808, lo: 0x80, hi: 0x89},
+ {value: 0x0a08, lo: 0x8a, hi: 0xaa},
+ {value: 0x3308, lo: 0xab, hi: 0xb3},
+ {value: 0x0808, lo: 0xb4, hi: 0xb5},
+ {value: 0x0018, lo: 0xb6, hi: 0xb9},
+ {value: 0x0818, lo: 0xba, hi: 0xba},
+ {value: 0x0040, lo: 0xbb, hi: 0xbc},
+ {value: 0x3308, lo: 0xbd, hi: 0xbd},
+ {value: 0x0818, lo: 0xbe, hi: 0xbf},
+ // Block 0xc, offset 0x6c
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0808, lo: 0x80, hi: 0x95},
+ {value: 0x3308, lo: 0x96, hi: 0x99},
+ {value: 0x0808, lo: 0x9a, hi: 0x9a},
+ {value: 0x3308, lo: 0x9b, hi: 0xa3},
+ {value: 0x0808, lo: 0xa4, hi: 0xa4},
+ {value: 0x3308, lo: 0xa5, hi: 0xa7},
+ {value: 0x0808, lo: 0xa8, hi: 0xa8},
+ {value: 0x3308, lo: 0xa9, hi: 0xad},
+ {value: 0x0040, lo: 0xae, hi: 0xaf},
+ {value: 0x0818, lo: 0xb0, hi: 0xbe},
+ {value: 0x0040, lo: 0xbf, hi: 0xbf},
+ // Block 0xd, offset 0x78
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x0040, lo: 0x80, hi: 0x9f},
+ {value: 0x0a08, lo: 0xa0, hi: 0xa9},
+ {value: 0x0c08, lo: 0xaa, hi: 0xac},
+ {value: 0x0808, lo: 0xad, hi: 0xad},
+ {value: 0x0c08, lo: 0xae, hi: 0xae},
+ {value: 0x0a08, lo: 0xaf, hi: 0xb0},
+ {value: 0x0c08, lo: 0xb1, hi: 0xb2},
+ {value: 0x0a08, lo: 0xb3, hi: 0xb4},
+ {value: 0x0040, lo: 0xb5, hi: 0xb5},
+ {value: 0x0a08, lo: 0xb6, hi: 0xb8},
+ {value: 0x0c08, lo: 0xb9, hi: 0xb9},
+ {value: 0x0a08, lo: 0xba, hi: 0xbf},
+ // Block 0xe, offset 0x85
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0a08, lo: 0x80, hi: 0x87},
+ {value: 0x0040, lo: 0x88, hi: 0x92},
+ {value: 0x3308, lo: 0x93, hi: 0xa1},
+ {value: 0x0840, lo: 0xa2, hi: 0xa2},
+ {value: 0x3308, lo: 0xa3, hi: 0xbf},
+ // Block 0xf, offset 0x8b
+ {value: 0x0000, lo: 0x08},
+ {value: 0x3308, lo: 0x80, hi: 0x82},
+ {value: 0x3008, lo: 0x83, hi: 0x83},
+ {value: 0x0008, lo: 0x84, hi: 0xb9},
+ {value: 0x3308, lo: 0xba, hi: 0xba},
+ {value: 0x3008, lo: 0xbb, hi: 0xbb},
+ {value: 0x3308, lo: 0xbc, hi: 0xbc},
+ {value: 0x0008, lo: 0xbd, hi: 0xbd},
+ {value: 0x3008, lo: 0xbe, hi: 0xbf},
+ // Block 0x10, offset 0x94
+ {value: 0x0000, lo: 0x0f},
+ {value: 0x3308, lo: 0x80, hi: 0x80},
+ {value: 0x3008, lo: 0x81, hi: 0x82},
+ {value: 0x0040, lo: 0x83, hi: 0x85},
+ {value: 0x3008, lo: 0x86, hi: 0x88},
+ {value: 0x0040, lo: 0x89, hi: 0x89},
+ {value: 0x3008, lo: 0x8a, hi: 0x8c},
+ {value: 0x3b08, lo: 0x8d, hi: 0x8d},
+ {value: 0x0040, lo: 0x8e, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x90},
+ {value: 0x0040, lo: 0x91, hi: 0x96},
+ {value: 0x3008, lo: 0x97, hi: 0x97},
+ {value: 0x0040, lo: 0x98, hi: 0xa5},
+ {value: 0x0008, lo: 0xa6, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xba},
+ {value: 0x0040, lo: 0xbb, hi: 0xbf},
+ // Block 0x11, offset 0xa4
+ {value: 0x0000, lo: 0x0d},
+ {value: 0x3308, lo: 0x80, hi: 0x80},
+ {value: 0x3008, lo: 0x81, hi: 0x83},
+ {value: 0x3308, lo: 0x84, hi: 0x84},
+ {value: 0x0008, lo: 0x85, hi: 0x8c},
+ {value: 0x0040, lo: 0x8d, hi: 0x8d},
+ {value: 0x0008, lo: 0x8e, hi: 0x90},
+ {value: 0x0040, lo: 0x91, hi: 0x91},
+ {value: 0x0008, lo: 0x92, hi: 0xa8},
+ {value: 0x0040, lo: 0xa9, hi: 0xa9},
+ {value: 0x0008, lo: 0xaa, hi: 0xb9},
+ {value: 0x0040, lo: 0xba, hi: 0xbc},
+ {value: 0x0008, lo: 0xbd, hi: 0xbd},
+ {value: 0x3308, lo: 0xbe, hi: 0xbf},
+ // Block 0x12, offset 0xb2
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x3308, lo: 0x80, hi: 0x81},
+ {value: 0x3008, lo: 0x82, hi: 0x83},
+ {value: 0x0008, lo: 0x84, hi: 0x8c},
+ {value: 0x0040, lo: 0x8d, hi: 0x8d},
+ {value: 0x0008, lo: 0x8e, hi: 0x90},
+ {value: 0x0040, lo: 0x91, hi: 0x91},
+ {value: 0x0008, lo: 0x92, hi: 0xba},
+ {value: 0x3b08, lo: 0xbb, hi: 0xbc},
+ {value: 0x0008, lo: 0xbd, hi: 0xbd},
+ {value: 0x3008, lo: 0xbe, hi: 0xbf},
+ // Block 0x13, offset 0xbd
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x0040, lo: 0x80, hi: 0x80},
+ {value: 0x3308, lo: 0x81, hi: 0x81},
+ {value: 0x3008, lo: 0x82, hi: 0x83},
+ {value: 0x0040, lo: 0x84, hi: 0x84},
+ {value: 0x0008, lo: 0x85, hi: 0x96},
+ {value: 0x0040, lo: 0x97, hi: 0x99},
+ {value: 0x0008, lo: 0x9a, hi: 0xb1},
+ {value: 0x0040, lo: 0xb2, hi: 0xb2},
+ {value: 0x0008, lo: 0xb3, hi: 0xbb},
+ {value: 0x0040, lo: 0xbc, hi: 0xbc},
+ {value: 0x0008, lo: 0xbd, hi: 0xbd},
+ {value: 0x0040, lo: 0xbe, hi: 0xbf},
+ // Block 0x14, offset 0xca
+ {value: 0x0000, lo: 0x10},
+ {value: 0x0008, lo: 0x80, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0x89},
+ {value: 0x3b08, lo: 0x8a, hi: 0x8a},
+ {value: 0x0040, lo: 0x8b, hi: 0x8e},
+ {value: 0x3008, lo: 0x8f, hi: 0x91},
+ {value: 0x3308, lo: 0x92, hi: 0x94},
+ {value: 0x0040, lo: 0x95, hi: 0x95},
+ {value: 0x3308, lo: 0x96, hi: 0x96},
+ {value: 0x0040, lo: 0x97, hi: 0x97},
+ {value: 0x3008, lo: 0x98, hi: 0x9f},
+ {value: 0x0040, lo: 0xa0, hi: 0xa5},
+ {value: 0x0008, lo: 0xa6, hi: 0xaf},
+ {value: 0x0040, lo: 0xb0, hi: 0xb1},
+ {value: 0x3008, lo: 0xb2, hi: 0xb3},
+ {value: 0x0018, lo: 0xb4, hi: 0xb4},
+ {value: 0x0040, lo: 0xb5, hi: 0xbf},
+ // Block 0x15, offset 0xdb
+ {value: 0x0000, lo: 0x09},
+ {value: 0x0040, lo: 0x80, hi: 0x80},
+ {value: 0x0008, lo: 0x81, hi: 0xb0},
+ {value: 0x3308, lo: 0xb1, hi: 0xb1},
+ {value: 0x0008, lo: 0xb2, hi: 0xb2},
+ {value: 0x01f1, lo: 0xb3, hi: 0xb3},
+ {value: 0x3308, lo: 0xb4, hi: 0xb9},
+ {value: 0x3b08, lo: 0xba, hi: 0xba},
+ {value: 0x0040, lo: 0xbb, hi: 0xbe},
+ {value: 0x0018, lo: 0xbf, hi: 0xbf},
+ // Block 0x16, offset 0xe5
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0008, lo: 0x80, hi: 0x86},
+ {value: 0x3308, lo: 0x87, hi: 0x8e},
+ {value: 0x0018, lo: 0x8f, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0018, lo: 0x9a, hi: 0x9b},
+ {value: 0x0040, lo: 0x9c, hi: 0xbf},
+ // Block 0x17, offset 0xec
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x0008, lo: 0x80, hi: 0x84},
+ {value: 0x0040, lo: 0x85, hi: 0x85},
+ {value: 0x0008, lo: 0x86, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0x87},
+ {value: 0x3308, lo: 0x88, hi: 0x8d},
+ {value: 0x0040, lo: 0x8e, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9b},
+ {value: 0x0201, lo: 0x9c, hi: 0x9c},
+ {value: 0x0209, lo: 0x9d, hi: 0x9d},
+ {value: 0x0008, lo: 0x9e, hi: 0x9f},
+ {value: 0x0040, lo: 0xa0, hi: 0xbf},
+ // Block 0x18, offset 0xf9
+ {value: 0x0000, lo: 0x10},
+ {value: 0x0008, lo: 0x80, hi: 0x80},
+ {value: 0x0018, lo: 0x81, hi: 0x8a},
+ {value: 0x0008, lo: 0x8b, hi: 0x8b},
+ {value: 0xe03d, lo: 0x8c, hi: 0x8c},
+ {value: 0x0018, lo: 0x8d, hi: 0x97},
+ {value: 0x3308, lo: 0x98, hi: 0x99},
+ {value: 0x0018, lo: 0x9a, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa9},
+ {value: 0x0018, lo: 0xaa, hi: 0xb4},
+ {value: 0x3308, lo: 0xb5, hi: 0xb5},
+ {value: 0x0018, lo: 0xb6, hi: 0xb6},
+ {value: 0x3308, lo: 0xb7, hi: 0xb7},
+ {value: 0x0018, lo: 0xb8, hi: 0xb8},
+ {value: 0x3308, lo: 0xb9, hi: 0xb9},
+ {value: 0x0018, lo: 0xba, hi: 0xbd},
+ {value: 0x3008, lo: 0xbe, hi: 0xbf},
+ // Block 0x19, offset 0x10a
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0018, lo: 0x80, hi: 0x85},
+ {value: 0x3308, lo: 0x86, hi: 0x86},
+ {value: 0x0018, lo: 0x87, hi: 0x8c},
+ {value: 0x0040, lo: 0x8d, hi: 0x8d},
+ {value: 0x0018, lo: 0x8e, hi: 0x9a},
+ {value: 0x0040, lo: 0x9b, hi: 0xbf},
+ // Block 0x1a, offset 0x111
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x0008, lo: 0x80, hi: 0xaa},
+ {value: 0x3008, lo: 0xab, hi: 0xac},
+ {value: 0x3308, lo: 0xad, hi: 0xb0},
+ {value: 0x3008, lo: 0xb1, hi: 0xb1},
+ {value: 0x3308, lo: 0xb2, hi: 0xb7},
+ {value: 0x3008, lo: 0xb8, hi: 0xb8},
+ {value: 0x3b08, lo: 0xb9, hi: 0xba},
+ {value: 0x3008, lo: 0xbb, hi: 0xbc},
+ {value: 0x3308, lo: 0xbd, hi: 0xbe},
+ {value: 0x0008, lo: 0xbf, hi: 0xbf},
+ // Block 0x1b, offset 0x11c
+ {value: 0x0000, lo: 0x0e},
+ {value: 0x0008, lo: 0x80, hi: 0x89},
+ {value: 0x0018, lo: 0x8a, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x95},
+ {value: 0x3008, lo: 0x96, hi: 0x97},
+ {value: 0x3308, lo: 0x98, hi: 0x99},
+ {value: 0x0008, lo: 0x9a, hi: 0x9d},
+ {value: 0x3308, lo: 0x9e, hi: 0xa0},
+ {value: 0x0008, lo: 0xa1, hi: 0xa1},
+ {value: 0x3008, lo: 0xa2, hi: 0xa4},
+ {value: 0x0008, lo: 0xa5, hi: 0xa6},
+ {value: 0x3008, lo: 0xa7, hi: 0xad},
+ {value: 0x0008, lo: 0xae, hi: 0xb0},
+ {value: 0x3308, lo: 0xb1, hi: 0xb4},
+ {value: 0x0008, lo: 0xb5, hi: 0xbf},
+ // Block 0x1c, offset 0x12b
+ {value: 0x0000, lo: 0x0d},
+ {value: 0x0008, lo: 0x80, hi: 0x81},
+ {value: 0x3308, lo: 0x82, hi: 0x82},
+ {value: 0x3008, lo: 0x83, hi: 0x84},
+ {value: 0x3308, lo: 0x85, hi: 0x86},
+ {value: 0x3008, lo: 0x87, hi: 0x8c},
+ {value: 0x3308, lo: 0x8d, hi: 0x8d},
+ {value: 0x0008, lo: 0x8e, hi: 0x8e},
+ {value: 0x3008, lo: 0x8f, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x3008, lo: 0x9a, hi: 0x9c},
+ {value: 0x3308, lo: 0x9d, hi: 0x9d},
+ {value: 0x0018, lo: 0x9e, hi: 0x9f},
+ {value: 0x0040, lo: 0xa0, hi: 0xbf},
+ // Block 0x1d, offset 0x139
+ {value: 0x0000, lo: 0x09},
+ {value: 0x0040, lo: 0x80, hi: 0x86},
+ {value: 0x055d, lo: 0x87, hi: 0x87},
+ {value: 0x0040, lo: 0x88, hi: 0x8c},
+ {value: 0x055d, lo: 0x8d, hi: 0x8d},
+ {value: 0x0040, lo: 0x8e, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0xba},
+ {value: 0x0018, lo: 0xbb, hi: 0xbb},
+ {value: 0xe105, lo: 0xbc, hi: 0xbc},
+ {value: 0x0008, lo: 0xbd, hi: 0xbf},
+ // Block 0x1e, offset 0x143
+ {value: 0x0000, lo: 0x01},
+ {value: 0x0018, lo: 0x80, hi: 0xbf},
+ // Block 0x1f, offset 0x145
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0018, lo: 0x80, hi: 0x9e},
+ {value: 0x0040, lo: 0x9f, hi: 0xa0},
+ {value: 0x2018, lo: 0xa1, hi: 0xb5},
+ {value: 0x0018, lo: 0xb6, hi: 0xbf},
+ // Block 0x20, offset 0x14a
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0018, lo: 0x80, hi: 0xa7},
+ {value: 0x2018, lo: 0xa8, hi: 0xbf},
+ // Block 0x21, offset 0x14d
+ {value: 0x0000, lo: 0x02},
+ {value: 0x2018, lo: 0x80, hi: 0x82},
+ {value: 0x0018, lo: 0x83, hi: 0xbf},
+ // Block 0x22, offset 0x150
+ {value: 0x0000, lo: 0x01},
+ {value: 0x0008, lo: 0x80, hi: 0xbf},
+ // Block 0x23, offset 0x152
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0008, lo: 0x80, hi: 0x88},
+ {value: 0x0040, lo: 0x89, hi: 0x89},
+ {value: 0x0008, lo: 0x8a, hi: 0x8d},
+ {value: 0x0040, lo: 0x8e, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x96},
+ {value: 0x0040, lo: 0x97, hi: 0x97},
+ {value: 0x0008, lo: 0x98, hi: 0x98},
+ {value: 0x0040, lo: 0x99, hi: 0x99},
+ {value: 0x0008, lo: 0x9a, hi: 0x9d},
+ {value: 0x0040, lo: 0x9e, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xbf},
+ // Block 0x24, offset 0x15e
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x0008, lo: 0x80, hi: 0x88},
+ {value: 0x0040, lo: 0x89, hi: 0x89},
+ {value: 0x0008, lo: 0x8a, hi: 0x8d},
+ {value: 0x0040, lo: 0x8e, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0xb0},
+ {value: 0x0040, lo: 0xb1, hi: 0xb1},
+ {value: 0x0008, lo: 0xb2, hi: 0xb5},
+ {value: 0x0040, lo: 0xb6, hi: 0xb7},
+ {value: 0x0008, lo: 0xb8, hi: 0xbe},
+ {value: 0x0040, lo: 0xbf, hi: 0xbf},
+ // Block 0x25, offset 0x169
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0008, lo: 0x80, hi: 0x80},
+ {value: 0x0040, lo: 0x81, hi: 0x81},
+ {value: 0x0008, lo: 0x82, hi: 0x85},
+ {value: 0x0040, lo: 0x86, hi: 0x87},
+ {value: 0x0008, lo: 0x88, hi: 0x96},
+ {value: 0x0040, lo: 0x97, hi: 0x97},
+ {value: 0x0008, lo: 0x98, hi: 0xbf},
+ // Block 0x26, offset 0x171
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0008, lo: 0x80, hi: 0x90},
+ {value: 0x0040, lo: 0x91, hi: 0x91},
+ {value: 0x0008, lo: 0x92, hi: 0x95},
+ {value: 0x0040, lo: 0x96, hi: 0x97},
+ {value: 0x0008, lo: 0x98, hi: 0xbf},
+ // Block 0x27, offset 0x177
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0008, lo: 0x80, hi: 0x9a},
+ {value: 0x0040, lo: 0x9b, hi: 0x9c},
+ {value: 0x3308, lo: 0x9d, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xbc},
+ {value: 0x0040, lo: 0xbd, hi: 0xbf},
+ // Block 0x28, offset 0x17d
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0x8f},
+ {value: 0x0018, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xbf},
+ // Block 0x29, offset 0x182
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0xb5},
+ {value: 0x0040, lo: 0xb6, hi: 0xb7},
+ {value: 0xe045, lo: 0xb8, hi: 0xbd},
+ {value: 0x0040, lo: 0xbe, hi: 0xbf},
+ // Block 0x2a, offset 0x187
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0018, lo: 0x80, hi: 0x80},
+ {value: 0x0008, lo: 0x81, hi: 0xbf},
+ // Block 0x2b, offset 0x18a
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0008, lo: 0x80, hi: 0xac},
+ {value: 0x0018, lo: 0xad, hi: 0xae},
+ {value: 0x0008, lo: 0xaf, hi: 0xbf},
+ // Block 0x2c, offset 0x18e
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0040, lo: 0x80, hi: 0x80},
+ {value: 0x0008, lo: 0x81, hi: 0x9a},
+ {value: 0x0018, lo: 0x9b, hi: 0x9c},
+ {value: 0x0040, lo: 0x9d, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xbf},
+ // Block 0x2d, offset 0x194
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0xaa},
+ {value: 0x0018, lo: 0xab, hi: 0xb0},
+ {value: 0x0008, lo: 0xb1, hi: 0xb8},
+ {value: 0x0040, lo: 0xb9, hi: 0xbf},
+ // Block 0x2e, offset 0x199
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0008, lo: 0x80, hi: 0x8c},
+ {value: 0x0040, lo: 0x8d, hi: 0x8d},
+ {value: 0x0008, lo: 0x8e, hi: 0x91},
+ {value: 0x3308, lo: 0x92, hi: 0x93},
+ {value: 0x3b08, lo: 0x94, hi: 0x94},
+ {value: 0x0040, lo: 0x95, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xb1},
+ {value: 0x3308, lo: 0xb2, hi: 0xb3},
+ {value: 0x3b08, lo: 0xb4, hi: 0xb4},
+ {value: 0x0018, lo: 0xb5, hi: 0xb6},
+ {value: 0x0040, lo: 0xb7, hi: 0xbf},
+ // Block 0x2f, offset 0x1a5
+ {value: 0x0000, lo: 0x09},
+ {value: 0x0008, lo: 0x80, hi: 0x91},
+ {value: 0x3308, lo: 0x92, hi: 0x93},
+ {value: 0x0040, lo: 0x94, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xac},
+ {value: 0x0040, lo: 0xad, hi: 0xad},
+ {value: 0x0008, lo: 0xae, hi: 0xb0},
+ {value: 0x0040, lo: 0xb1, hi: 0xb1},
+ {value: 0x3308, lo: 0xb2, hi: 0xb3},
+ {value: 0x0040, lo: 0xb4, hi: 0xbf},
+ // Block 0x30, offset 0x1af
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0008, lo: 0x80, hi: 0xb3},
+ {value: 0x3340, lo: 0xb4, hi: 0xb5},
+ {value: 0x3008, lo: 0xb6, hi: 0xb6},
+ {value: 0x3308, lo: 0xb7, hi: 0xbd},
+ {value: 0x3008, lo: 0xbe, hi: 0xbf},
+ // Block 0x31, offset 0x1b5
+ {value: 0x0000, lo: 0x10},
+ {value: 0x3008, lo: 0x80, hi: 0x85},
+ {value: 0x3308, lo: 0x86, hi: 0x86},
+ {value: 0x3008, lo: 0x87, hi: 0x88},
+ {value: 0x3308, lo: 0x89, hi: 0x91},
+ {value: 0x3b08, lo: 0x92, hi: 0x92},
+ {value: 0x3308, lo: 0x93, hi: 0x93},
+ {value: 0x0018, lo: 0x94, hi: 0x96},
+ {value: 0x0008, lo: 0x97, hi: 0x97},
+ {value: 0x0018, lo: 0x98, hi: 0x9b},
+ {value: 0x0008, lo: 0x9c, hi: 0x9c},
+ {value: 0x3308, lo: 0x9d, hi: 0x9d},
+ {value: 0x0040, lo: 0x9e, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa9},
+ {value: 0x0040, lo: 0xaa, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xb9},
+ {value: 0x0040, lo: 0xba, hi: 0xbf},
+ // Block 0x32, offset 0x1c6
+ {value: 0x0000, lo: 0x09},
+ {value: 0x0018, lo: 0x80, hi: 0x85},
+ {value: 0x0040, lo: 0x86, hi: 0x86},
+ {value: 0x0218, lo: 0x87, hi: 0x87},
+ {value: 0x0018, lo: 0x88, hi: 0x8a},
+ {value: 0x33c0, lo: 0x8b, hi: 0x8d},
+ {value: 0x0040, lo: 0x8e, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9f},
+ {value: 0x0208, lo: 0xa0, hi: 0xbf},
+ // Block 0x33, offset 0x1d0
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0208, lo: 0x80, hi: 0xb8},
+ {value: 0x0040, lo: 0xb9, hi: 0xbf},
+ // Block 0x34, offset 0x1d3
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0008, lo: 0x80, hi: 0x84},
+ {value: 0x3308, lo: 0x85, hi: 0x86},
+ {value: 0x0208, lo: 0x87, hi: 0xa8},
+ {value: 0x3308, lo: 0xa9, hi: 0xa9},
+ {value: 0x0208, lo: 0xaa, hi: 0xaa},
+ {value: 0x0040, lo: 0xab, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbf},
+ // Block 0x35, offset 0x1db
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0xb5},
+ {value: 0x0040, lo: 0xb6, hi: 0xbf},
+ // Block 0x36, offset 0x1de
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x0008, lo: 0x80, hi: 0x9e},
+ {value: 0x0040, lo: 0x9f, hi: 0x9f},
+ {value: 0x3308, lo: 0xa0, hi: 0xa2},
+ {value: 0x3008, lo: 0xa3, hi: 0xa6},
+ {value: 0x3308, lo: 0xa7, hi: 0xa8},
+ {value: 0x3008, lo: 0xa9, hi: 0xab},
+ {value: 0x0040, lo: 0xac, hi: 0xaf},
+ {value: 0x3008, lo: 0xb0, hi: 0xb1},
+ {value: 0x3308, lo: 0xb2, hi: 0xb2},
+ {value: 0x3008, lo: 0xb3, hi: 0xb8},
+ {value: 0x3308, lo: 0xb9, hi: 0xbb},
+ {value: 0x0040, lo: 0xbc, hi: 0xbf},
+ // Block 0x37, offset 0x1eb
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0018, lo: 0x80, hi: 0x80},
+ {value: 0x0040, lo: 0x81, hi: 0x83},
+ {value: 0x0018, lo: 0x84, hi: 0x85},
+ {value: 0x0008, lo: 0x86, hi: 0xad},
+ {value: 0x0040, lo: 0xae, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xb4},
+ {value: 0x0040, lo: 0xb5, hi: 0xbf},
+ // Block 0x38, offset 0x1f3
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0008, lo: 0x80, hi: 0xab},
+ {value: 0x0040, lo: 0xac, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbf},
+ // Block 0x39, offset 0x1f7
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0008, lo: 0x80, hi: 0x89},
+ {value: 0x0040, lo: 0x8a, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0028, lo: 0x9a, hi: 0x9a},
+ {value: 0x0040, lo: 0x9b, hi: 0x9d},
+ {value: 0x0018, lo: 0x9e, hi: 0xbf},
+ // Block 0x3a, offset 0x1fe
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0008, lo: 0x80, hi: 0x96},
+ {value: 0x3308, lo: 0x97, hi: 0x98},
+ {value: 0x3008, lo: 0x99, hi: 0x9a},
+ {value: 0x3308, lo: 0x9b, hi: 0x9b},
+ {value: 0x0040, lo: 0x9c, hi: 0x9d},
+ {value: 0x0018, lo: 0x9e, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xbf},
+ // Block 0x3b, offset 0x206
+ {value: 0x0000, lo: 0x0f},
+ {value: 0x0008, lo: 0x80, hi: 0x94},
+ {value: 0x3008, lo: 0x95, hi: 0x95},
+ {value: 0x3308, lo: 0x96, hi: 0x96},
+ {value: 0x3008, lo: 0x97, hi: 0x97},
+ {value: 0x3308, lo: 0x98, hi: 0x9e},
+ {value: 0x0040, lo: 0x9f, hi: 0x9f},
+ {value: 0x3b08, lo: 0xa0, hi: 0xa0},
+ {value: 0x3008, lo: 0xa1, hi: 0xa1},
+ {value: 0x3308, lo: 0xa2, hi: 0xa2},
+ {value: 0x3008, lo: 0xa3, hi: 0xa4},
+ {value: 0x3308, lo: 0xa5, hi: 0xac},
+ {value: 0x3008, lo: 0xad, hi: 0xb2},
+ {value: 0x3308, lo: 0xb3, hi: 0xbc},
+ {value: 0x0040, lo: 0xbd, hi: 0xbe},
+ {value: 0x3308, lo: 0xbf, hi: 0xbf},
+ // Block 0x3c, offset 0x216
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0008, lo: 0x80, hi: 0x89},
+ {value: 0x0040, lo: 0x8a, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xa6},
+ {value: 0x0008, lo: 0xa7, hi: 0xa7},
+ {value: 0x0018, lo: 0xa8, hi: 0xad},
+ {value: 0x0040, lo: 0xae, hi: 0xaf},
+ {value: 0x3308, lo: 0xb0, hi: 0xbd},
+ {value: 0x3318, lo: 0xbe, hi: 0xbe},
+ {value: 0x3308, lo: 0xbf, hi: 0xbf},
+ // Block 0x3d, offset 0x222
+ {value: 0x0000, lo: 0x02},
+ {value: 0x3308, lo: 0x80, hi: 0x80},
+ {value: 0x0040, lo: 0x81, hi: 0xbf},
+ // Block 0x3e, offset 0x225
+ {value: 0x0000, lo: 0x09},
+ {value: 0x3308, lo: 0x80, hi: 0x83},
+ {value: 0x3008, lo: 0x84, hi: 0x84},
+ {value: 0x0008, lo: 0x85, hi: 0xb3},
+ {value: 0x3308, lo: 0xb4, hi: 0xb4},
+ {value: 0x3008, lo: 0xb5, hi: 0xb5},
+ {value: 0x3308, lo: 0xb6, hi: 0xba},
+ {value: 0x3008, lo: 0xbb, hi: 0xbb},
+ {value: 0x3308, lo: 0xbc, hi: 0xbc},
+ {value: 0x3008, lo: 0xbd, hi: 0xbf},
+ // Block 0x3f, offset 0x22f
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x3008, lo: 0x80, hi: 0x81},
+ {value: 0x3308, lo: 0x82, hi: 0x82},
+ {value: 0x3008, lo: 0x83, hi: 0x83},
+ {value: 0x3808, lo: 0x84, hi: 0x84},
+ {value: 0x0008, lo: 0x85, hi: 0x8b},
+ {value: 0x0040, lo: 0x8c, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0018, lo: 0x9a, hi: 0xaa},
+ {value: 0x3308, lo: 0xab, hi: 0xb3},
+ {value: 0x0018, lo: 0xb4, hi: 0xbc},
+ {value: 0x0040, lo: 0xbd, hi: 0xbf},
+ // Block 0x40, offset 0x23b
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x3308, lo: 0x80, hi: 0x81},
+ {value: 0x3008, lo: 0x82, hi: 0x82},
+ {value: 0x0008, lo: 0x83, hi: 0xa0},
+ {value: 0x3008, lo: 0xa1, hi: 0xa1},
+ {value: 0x3308, lo: 0xa2, hi: 0xa5},
+ {value: 0x3008, lo: 0xa6, hi: 0xa7},
+ {value: 0x3308, lo: 0xa8, hi: 0xa9},
+ {value: 0x3808, lo: 0xaa, hi: 0xaa},
+ {value: 0x3b08, lo: 0xab, hi: 0xab},
+ {value: 0x3308, lo: 0xac, hi: 0xad},
+ {value: 0x0008, lo: 0xae, hi: 0xbf},
+ // Block 0x41, offset 0x247
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0008, lo: 0x80, hi: 0xa5},
+ {value: 0x3308, lo: 0xa6, hi: 0xa6},
+ {value: 0x3008, lo: 0xa7, hi: 0xa7},
+ {value: 0x3308, lo: 0xa8, hi: 0xa9},
+ {value: 0x3008, lo: 0xaa, hi: 0xac},
+ {value: 0x3308, lo: 0xad, hi: 0xad},
+ {value: 0x3008, lo: 0xae, hi: 0xae},
+ {value: 0x3308, lo: 0xaf, hi: 0xb1},
+ {value: 0x3808, lo: 0xb2, hi: 0xb3},
+ {value: 0x0040, lo: 0xb4, hi: 0xbb},
+ {value: 0x0018, lo: 0xbc, hi: 0xbf},
+ // Block 0x42, offset 0x253
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0008, lo: 0x80, hi: 0xa3},
+ {value: 0x3008, lo: 0xa4, hi: 0xab},
+ {value: 0x3308, lo: 0xac, hi: 0xb3},
+ {value: 0x3008, lo: 0xb4, hi: 0xb5},
+ {value: 0x3308, lo: 0xb6, hi: 0xb7},
+ {value: 0x0040, lo: 0xb8, hi: 0xba},
+ {value: 0x0018, lo: 0xbb, hi: 0xbf},
+ // Block 0x43, offset 0x25b
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0x89},
+ {value: 0x0040, lo: 0x8a, hi: 0x8c},
+ {value: 0x0008, lo: 0x8d, hi: 0xbd},
+ {value: 0x0018, lo: 0xbe, hi: 0xbf},
+ // Block 0x44, offset 0x260
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x02a9, lo: 0x80, hi: 0x80},
+ {value: 0x02b1, lo: 0x81, hi: 0x81},
+ {value: 0x02b9, lo: 0x82, hi: 0x82},
+ {value: 0x02c1, lo: 0x83, hi: 0x83},
+ {value: 0x02c9, lo: 0x84, hi: 0x85},
+ {value: 0x02d1, lo: 0x86, hi: 0x86},
+ {value: 0x02d9, lo: 0x87, hi: 0x87},
+ {value: 0x057d, lo: 0x88, hi: 0x88},
+ {value: 0x0040, lo: 0x89, hi: 0x8f},
+ {value: 0x059d, lo: 0x90, hi: 0xba},
+ {value: 0x0040, lo: 0xbb, hi: 0xbc},
+ {value: 0x059d, lo: 0xbd, hi: 0xbf},
+ // Block 0x45, offset 0x26d
+ {value: 0x0000, lo: 0x10},
+ {value: 0x0018, lo: 0x80, hi: 0x87},
+ {value: 0x0040, lo: 0x88, hi: 0x8f},
+ {value: 0x3308, lo: 0x90, hi: 0x92},
+ {value: 0x0018, lo: 0x93, hi: 0x93},
+ {value: 0x3308, lo: 0x94, hi: 0xa0},
+ {value: 0x3008, lo: 0xa1, hi: 0xa1},
+ {value: 0x3308, lo: 0xa2, hi: 0xa8},
+ {value: 0x0008, lo: 0xa9, hi: 0xac},
+ {value: 0x3308, lo: 0xad, hi: 0xad},
+ {value: 0x0008, lo: 0xae, hi: 0xb3},
+ {value: 0x3308, lo: 0xb4, hi: 0xb4},
+ {value: 0x0008, lo: 0xb5, hi: 0xb6},
+ {value: 0x3008, lo: 0xb7, hi: 0xb7},
+ {value: 0x3308, lo: 0xb8, hi: 0xb9},
+ {value: 0x0008, lo: 0xba, hi: 0xba},
+ {value: 0x0040, lo: 0xbb, hi: 0xbf},
+ // Block 0x46, offset 0x27e
+ {value: 0x0000, lo: 0x03},
+ {value: 0x3308, lo: 0x80, hi: 0xb9},
+ {value: 0x0040, lo: 0xba, hi: 0xba},
+ {value: 0x3308, lo: 0xbb, hi: 0xbf},
+ // Block 0x47, offset 0x282
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x0008, lo: 0x80, hi: 0x87},
+ {value: 0xe045, lo: 0x88, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x95},
+ {value: 0x0040, lo: 0x96, hi: 0x97},
+ {value: 0xe045, lo: 0x98, hi: 0x9d},
+ {value: 0x0040, lo: 0x9e, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa7},
+ {value: 0xe045, lo: 0xa8, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xb7},
+ {value: 0xe045, lo: 0xb8, hi: 0xbf},
+ // Block 0x48, offset 0x28d
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0040, lo: 0x80, hi: 0x8f},
+ {value: 0x3318, lo: 0x90, hi: 0xb0},
+ {value: 0x0040, lo: 0xb1, hi: 0xbf},
+ // Block 0x49, offset 0x291
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0018, lo: 0x80, hi: 0x82},
+ {value: 0x0040, lo: 0x83, hi: 0x83},
+ {value: 0x0008, lo: 0x84, hi: 0x84},
+ {value: 0x0018, lo: 0x85, hi: 0x88},
+ {value: 0x0851, lo: 0x89, hi: 0x89},
+ {value: 0x0018, lo: 0x8a, hi: 0x8b},
+ {value: 0x0040, lo: 0x8c, hi: 0x8f},
+ {value: 0x0018, lo: 0x90, hi: 0xbf},
+ // Block 0x4a, offset 0x29a
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0018, lo: 0x80, hi: 0xab},
+ {value: 0x0859, lo: 0xac, hi: 0xac},
+ {value: 0x0861, lo: 0xad, hi: 0xad},
+ {value: 0x0018, lo: 0xae, hi: 0xae},
+ {value: 0x0869, lo: 0xaf, hi: 0xaf},
+ {value: 0x0871, lo: 0xb0, hi: 0xb0},
+ {value: 0x0018, lo: 0xb1, hi: 0xbf},
+ // Block 0x4b, offset 0x2a2
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0018, lo: 0x80, hi: 0x9f},
+ {value: 0x0080, lo: 0xa0, hi: 0xa0},
+ {value: 0x0018, lo: 0xa1, hi: 0xad},
+ {value: 0x0080, lo: 0xae, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xbf},
+ // Block 0x4c, offset 0x2a8
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0018, lo: 0x80, hi: 0xa8},
+ {value: 0x09dd, lo: 0xa9, hi: 0xa9},
+ {value: 0x09fd, lo: 0xaa, hi: 0xaa},
+ {value: 0x0018, lo: 0xab, hi: 0xbf},
+ // Block 0x4d, offset 0x2ad
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0018, lo: 0x80, hi: 0xa6},
+ {value: 0x0040, lo: 0xa7, hi: 0xbf},
+ // Block 0x4e, offset 0x2b0
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0x8b},
+ {value: 0x0929, lo: 0x8c, hi: 0x8c},
+ {value: 0x0018, lo: 0x8d, hi: 0xbf},
+ // Block 0x4f, offset 0x2b4
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0018, lo: 0x80, hi: 0xb3},
+ {value: 0x0e7e, lo: 0xb4, hi: 0xb4},
+ {value: 0x0932, lo: 0xb5, hi: 0xb5},
+ {value: 0x0e9e, lo: 0xb6, hi: 0xb6},
+ {value: 0x0018, lo: 0xb7, hi: 0xbf},
+ // Block 0x50, offset 0x2ba
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0x9b},
+ {value: 0x0939, lo: 0x9c, hi: 0x9c},
+ {value: 0x0018, lo: 0x9d, hi: 0xbf},
+ // Block 0x51, offset 0x2be
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0xb3},
+ {value: 0x0040, lo: 0xb4, hi: 0xb5},
+ {value: 0x0018, lo: 0xb6, hi: 0xbf},
+ // Block 0x52, offset 0x2c2
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0x95},
+ {value: 0x0040, lo: 0x96, hi: 0x96},
+ {value: 0x0018, lo: 0x97, hi: 0xbf},
+ // Block 0x53, offset 0x2c6
+ {value: 0x0000, lo: 0x05},
+ {value: 0xe185, lo: 0x80, hi: 0x8f},
+ {value: 0x03f5, lo: 0x90, hi: 0x9f},
+ {value: 0x0ebd, lo: 0xa0, hi: 0xae},
+ {value: 0x0040, lo: 0xaf, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbf},
+ // Block 0x54, offset 0x2cc
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0008, lo: 0x80, hi: 0xa5},
+ {value: 0x0040, lo: 0xa6, hi: 0xa6},
+ {value: 0x0008, lo: 0xa7, hi: 0xa7},
+ {value: 0x0040, lo: 0xa8, hi: 0xac},
+ {value: 0x0008, lo: 0xad, hi: 0xad},
+ {value: 0x0040, lo: 0xae, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbf},
+ // Block 0x55, offset 0x2d4
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0008, lo: 0x80, hi: 0xa7},
+ {value: 0x0040, lo: 0xa8, hi: 0xae},
+ {value: 0xe075, lo: 0xaf, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xb0},
+ {value: 0x0040, lo: 0xb1, hi: 0xbe},
+ {value: 0x3b08, lo: 0xbf, hi: 0xbf},
+ // Block 0x56, offset 0x2db
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x0008, lo: 0x80, hi: 0x96},
+ {value: 0x0040, lo: 0x97, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa6},
+ {value: 0x0040, lo: 0xa7, hi: 0xa7},
+ {value: 0x0008, lo: 0xa8, hi: 0xae},
+ {value: 0x0040, lo: 0xaf, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xb6},
+ {value: 0x0040, lo: 0xb7, hi: 0xb7},
+ {value: 0x0008, lo: 0xb8, hi: 0xbe},
+ {value: 0x0040, lo: 0xbf, hi: 0xbf},
+ // Block 0x57, offset 0x2e6
+ {value: 0x0000, lo: 0x09},
+ {value: 0x0008, lo: 0x80, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0x87},
+ {value: 0x0008, lo: 0x88, hi: 0x8e},
+ {value: 0x0040, lo: 0x8f, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x96},
+ {value: 0x0040, lo: 0x97, hi: 0x97},
+ {value: 0x0008, lo: 0x98, hi: 0x9e},
+ {value: 0x0040, lo: 0x9f, hi: 0x9f},
+ {value: 0x3308, lo: 0xa0, hi: 0xbf},
+ // Block 0x58, offset 0x2f0
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0xae},
+ {value: 0x0008, lo: 0xaf, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xbf},
+ // Block 0x59, offset 0x2f4
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0018, lo: 0x80, hi: 0x92},
+ {value: 0x0040, lo: 0x93, hi: 0xbf},
+ // Block 0x5a, offset 0x2f7
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0018, lo: 0x80, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9a},
+ {value: 0x0018, lo: 0x9b, hi: 0x9e},
+ {value: 0x0ef5, lo: 0x9f, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xbf},
+ // Block 0x5b, offset 0x2fd
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0xb2},
+ {value: 0x0f15, lo: 0xb3, hi: 0xb3},
+ {value: 0x0040, lo: 0xb4, hi: 0xbf},
+ // Block 0x5c, offset 0x301
+ {value: 0x0020, lo: 0x01},
+ {value: 0x0f35, lo: 0x80, hi: 0xbf},
+ // Block 0x5d, offset 0x303
+ {value: 0x0020, lo: 0x02},
+ {value: 0x1735, lo: 0x80, hi: 0x8f},
+ {value: 0x1915, lo: 0x90, hi: 0xbf},
+ // Block 0x5e, offset 0x306
+ {value: 0x0020, lo: 0x01},
+ {value: 0x1f15, lo: 0x80, hi: 0xbf},
+ // Block 0x5f, offset 0x308
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0040, lo: 0x80, hi: 0x80},
+ {value: 0x0008, lo: 0x81, hi: 0xbf},
+ // Block 0x60, offset 0x30b
+ {value: 0x0000, lo: 0x09},
+ {value: 0x0008, lo: 0x80, hi: 0x96},
+ {value: 0x0040, lo: 0x97, hi: 0x98},
+ {value: 0x3308, lo: 0x99, hi: 0x9a},
+ {value: 0x096a, lo: 0x9b, hi: 0x9b},
+ {value: 0x0972, lo: 0x9c, hi: 0x9c},
+ {value: 0x0008, lo: 0x9d, hi: 0x9e},
+ {value: 0x0979, lo: 0x9f, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xa0},
+ {value: 0x0008, lo: 0xa1, hi: 0xbf},
+ // Block 0x61, offset 0x315
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0xbe},
+ {value: 0x0981, lo: 0xbf, hi: 0xbf},
+ // Block 0x62, offset 0x318
+ {value: 0x0000, lo: 0x0e},
+ {value: 0x0040, lo: 0x80, hi: 0x84},
+ {value: 0x0008, lo: 0x85, hi: 0xaf},
+ {value: 0x0040, lo: 0xb0, hi: 0xb0},
+ {value: 0x2a35, lo: 0xb1, hi: 0xb1},
+ {value: 0x2a55, lo: 0xb2, hi: 0xb2},
+ {value: 0x2a75, lo: 0xb3, hi: 0xb3},
+ {value: 0x2a95, lo: 0xb4, hi: 0xb4},
+ {value: 0x2a75, lo: 0xb5, hi: 0xb5},
+ {value: 0x2ab5, lo: 0xb6, hi: 0xb6},
+ {value: 0x2ad5, lo: 0xb7, hi: 0xb7},
+ {value: 0x2af5, lo: 0xb8, hi: 0xb9},
+ {value: 0x2b15, lo: 0xba, hi: 0xbb},
+ {value: 0x2b35, lo: 0xbc, hi: 0xbd},
+ {value: 0x2b15, lo: 0xbe, hi: 0xbf},
+ // Block 0x63, offset 0x327
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0xa3},
+ {value: 0x0040, lo: 0xa4, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbf},
+ // Block 0x64, offset 0x32b
+ {value: 0x0008, lo: 0x03},
+ {value: 0x098a, lo: 0x80, hi: 0x9e},
+ {value: 0x0040, lo: 0x9f, hi: 0x9f},
+ {value: 0x0a82, lo: 0xa0, hi: 0xbf},
+ // Block 0x65, offset 0x32f
+ {value: 0x0008, lo: 0x01},
+ {value: 0x0d19, lo: 0x80, hi: 0xbf},
+ // Block 0x66, offset 0x331
+ {value: 0x0008, lo: 0x08},
+ {value: 0x0f19, lo: 0x80, hi: 0xb0},
+ {value: 0x4045, lo: 0xb1, hi: 0xb1},
+ {value: 0x10a1, lo: 0xb2, hi: 0xb3},
+ {value: 0x4065, lo: 0xb4, hi: 0xb4},
+ {value: 0x10b1, lo: 0xb5, hi: 0xb7},
+ {value: 0x4085, lo: 0xb8, hi: 0xb8},
+ {value: 0x4085, lo: 0xb9, hi: 0xb9},
+ {value: 0x10c9, lo: 0xba, hi: 0xbf},
+ // Block 0x67, offset 0x33a
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0xbc},
+ {value: 0x0040, lo: 0xbd, hi: 0xbf},
+ // Block 0x68, offset 0x33d
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0008, lo: 0x80, hi: 0x8c},
+ {value: 0x0040, lo: 0x8d, hi: 0x8f},
+ {value: 0x0018, lo: 0x90, hi: 0xbf},
+ // Block 0x69, offset 0x341
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0018, lo: 0x80, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0xbd},
+ {value: 0x0018, lo: 0xbe, hi: 0xbf},
+ // Block 0x6a, offset 0x346
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0x8c},
+ {value: 0x0018, lo: 0x8d, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0xab},
+ {value: 0x0040, lo: 0xac, hi: 0xbf},
+ // Block 0x6b, offset 0x34b
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0008, lo: 0x80, hi: 0xa5},
+ {value: 0x0018, lo: 0xa6, hi: 0xaf},
+ {value: 0x3308, lo: 0xb0, hi: 0xb1},
+ {value: 0x0018, lo: 0xb2, hi: 0xb7},
+ {value: 0x0040, lo: 0xb8, hi: 0xbf},
+ // Block 0x6c, offset 0x351
+ {value: 0x0000, lo: 0x10},
+ {value: 0x0040, lo: 0x80, hi: 0x81},
+ {value: 0xe00d, lo: 0x82, hi: 0x82},
+ {value: 0x0008, lo: 0x83, hi: 0x83},
+ {value: 0x03f5, lo: 0x84, hi: 0x84},
+ {value: 0x0479, lo: 0x85, hi: 0x85},
+ {value: 0x447d, lo: 0x86, hi: 0x86},
+ {value: 0xe07d, lo: 0x87, hi: 0x87},
+ {value: 0x0008, lo: 0x88, hi: 0x88},
+ {value: 0xe01d, lo: 0x89, hi: 0x89},
+ {value: 0x0008, lo: 0x8a, hi: 0x8a},
+ {value: 0x0040, lo: 0x8b, hi: 0xb4},
+ {value: 0xe01d, lo: 0xb5, hi: 0xb5},
+ {value: 0x0008, lo: 0xb6, hi: 0xb7},
+ {value: 0x0741, lo: 0xb8, hi: 0xb8},
+ {value: 0x13f1, lo: 0xb9, hi: 0xb9},
+ {value: 0x0008, lo: 0xba, hi: 0xbf},
+ // Block 0x6d, offset 0x362
+ {value: 0x0000, lo: 0x0f},
+ {value: 0x0008, lo: 0x80, hi: 0x81},
+ {value: 0x3308, lo: 0x82, hi: 0x82},
+ {value: 0x0008, lo: 0x83, hi: 0x85},
+ {value: 0x3b08, lo: 0x86, hi: 0x86},
+ {value: 0x0008, lo: 0x87, hi: 0x8a},
+ {value: 0x3308, lo: 0x8b, hi: 0x8b},
+ {value: 0x0008, lo: 0x8c, hi: 0xa2},
+ {value: 0x3008, lo: 0xa3, hi: 0xa4},
+ {value: 0x3308, lo: 0xa5, hi: 0xa6},
+ {value: 0x3008, lo: 0xa7, hi: 0xa7},
+ {value: 0x0018, lo: 0xa8, hi: 0xab},
+ {value: 0x3b08, lo: 0xac, hi: 0xac},
+ {value: 0x0040, lo: 0xad, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xb9},
+ {value: 0x0040, lo: 0xba, hi: 0xbf},
+ // Block 0x6e, offset 0x372
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0208, lo: 0x80, hi: 0xb1},
+ {value: 0x0108, lo: 0xb2, hi: 0xb2},
+ {value: 0x0008, lo: 0xb3, hi: 0xb3},
+ {value: 0x0018, lo: 0xb4, hi: 0xb7},
+ {value: 0x0040, lo: 0xb8, hi: 0xbf},
+ // Block 0x6f, offset 0x378
+ {value: 0x0000, lo: 0x03},
+ {value: 0x3008, lo: 0x80, hi: 0x81},
+ {value: 0x0008, lo: 0x82, hi: 0xb3},
+ {value: 0x3008, lo: 0xb4, hi: 0xbf},
+ // Block 0x70, offset 0x37c
+ {value: 0x0000, lo: 0x0e},
+ {value: 0x3008, lo: 0x80, hi: 0x83},
+ {value: 0x3b08, lo: 0x84, hi: 0x84},
+ {value: 0x3308, lo: 0x85, hi: 0x85},
+ {value: 0x0040, lo: 0x86, hi: 0x8d},
+ {value: 0x0018, lo: 0x8e, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9f},
+ {value: 0x3308, lo: 0xa0, hi: 0xb1},
+ {value: 0x0008, lo: 0xb2, hi: 0xb7},
+ {value: 0x0018, lo: 0xb8, hi: 0xba},
+ {value: 0x0008, lo: 0xbb, hi: 0xbb},
+ {value: 0x0018, lo: 0xbc, hi: 0xbc},
+ {value: 0x0008, lo: 0xbd, hi: 0xbe},
+ {value: 0x3308, lo: 0xbf, hi: 0xbf},
+ // Block 0x71, offset 0x38b
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0xa5},
+ {value: 0x3308, lo: 0xa6, hi: 0xad},
+ {value: 0x0018, lo: 0xae, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbf},
+ // Block 0x72, offset 0x390
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0008, lo: 0x80, hi: 0x86},
+ {value: 0x3308, lo: 0x87, hi: 0x91},
+ {value: 0x3008, lo: 0x92, hi: 0x92},
+ {value: 0x3808, lo: 0x93, hi: 0x93},
+ {value: 0x0040, lo: 0x94, hi: 0x9e},
+ {value: 0x0018, lo: 0x9f, hi: 0xbc},
+ {value: 0x0040, lo: 0xbd, hi: 0xbf},
+ // Block 0x73, offset 0x398
+ {value: 0x0000, lo: 0x09},
+ {value: 0x3308, lo: 0x80, hi: 0x82},
+ {value: 0x3008, lo: 0x83, hi: 0x83},
+ {value: 0x0008, lo: 0x84, hi: 0xb2},
+ {value: 0x3308, lo: 0xb3, hi: 0xb3},
+ {value: 0x3008, lo: 0xb4, hi: 0xb5},
+ {value: 0x3308, lo: 0xb6, hi: 0xb9},
+ {value: 0x3008, lo: 0xba, hi: 0xbb},
+ {value: 0x3308, lo: 0xbc, hi: 0xbd},
+ {value: 0x3008, lo: 0xbe, hi: 0xbf},
+ // Block 0x74, offset 0x3a2
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x3808, lo: 0x80, hi: 0x80},
+ {value: 0x0018, lo: 0x81, hi: 0x8d},
+ {value: 0x0040, lo: 0x8e, hi: 0x8e},
+ {value: 0x0008, lo: 0x8f, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9d},
+ {value: 0x0018, lo: 0x9e, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa4},
+ {value: 0x3308, lo: 0xa5, hi: 0xa5},
+ {value: 0x0008, lo: 0xa6, hi: 0xbe},
+ {value: 0x0040, lo: 0xbf, hi: 0xbf},
+ // Block 0x75, offset 0x3ad
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0008, lo: 0x80, hi: 0xa8},
+ {value: 0x3308, lo: 0xa9, hi: 0xae},
+ {value: 0x3008, lo: 0xaf, hi: 0xb0},
+ {value: 0x3308, lo: 0xb1, hi: 0xb2},
+ {value: 0x3008, lo: 0xb3, hi: 0xb4},
+ {value: 0x3308, lo: 0xb5, hi: 0xb6},
+ {value: 0x0040, lo: 0xb7, hi: 0xbf},
+ // Block 0x76, offset 0x3b5
+ {value: 0x0000, lo: 0x10},
+ {value: 0x0008, lo: 0x80, hi: 0x82},
+ {value: 0x3308, lo: 0x83, hi: 0x83},
+ {value: 0x0008, lo: 0x84, hi: 0x8b},
+ {value: 0x3308, lo: 0x8c, hi: 0x8c},
+ {value: 0x3008, lo: 0x8d, hi: 0x8d},
+ {value: 0x0040, lo: 0x8e, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9b},
+ {value: 0x0018, lo: 0x9c, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xb6},
+ {value: 0x0018, lo: 0xb7, hi: 0xb9},
+ {value: 0x0008, lo: 0xba, hi: 0xba},
+ {value: 0x3008, lo: 0xbb, hi: 0xbb},
+ {value: 0x3308, lo: 0xbc, hi: 0xbc},
+ {value: 0x3008, lo: 0xbd, hi: 0xbd},
+ {value: 0x0008, lo: 0xbe, hi: 0xbf},
+ // Block 0x77, offset 0x3c6
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0008, lo: 0x80, hi: 0xaf},
+ {value: 0x3308, lo: 0xb0, hi: 0xb0},
+ {value: 0x0008, lo: 0xb1, hi: 0xb1},
+ {value: 0x3308, lo: 0xb2, hi: 0xb4},
+ {value: 0x0008, lo: 0xb5, hi: 0xb6},
+ {value: 0x3308, lo: 0xb7, hi: 0xb8},
+ {value: 0x0008, lo: 0xb9, hi: 0xbd},
+ {value: 0x3308, lo: 0xbe, hi: 0xbf},
+ // Block 0x78, offset 0x3cf
+ {value: 0x0000, lo: 0x0f},
+ {value: 0x0008, lo: 0x80, hi: 0x80},
+ {value: 0x3308, lo: 0x81, hi: 0x81},
+ {value: 0x0008, lo: 0x82, hi: 0x82},
+ {value: 0x0040, lo: 0x83, hi: 0x9a},
+ {value: 0x0008, lo: 0x9b, hi: 0x9d},
+ {value: 0x0018, lo: 0x9e, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xaa},
+ {value: 0x3008, lo: 0xab, hi: 0xab},
+ {value: 0x3308, lo: 0xac, hi: 0xad},
+ {value: 0x3008, lo: 0xae, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xb1},
+ {value: 0x0008, lo: 0xb2, hi: 0xb4},
+ {value: 0x3008, lo: 0xb5, hi: 0xb5},
+ {value: 0x3b08, lo: 0xb6, hi: 0xb6},
+ {value: 0x0040, lo: 0xb7, hi: 0xbf},
+ // Block 0x79, offset 0x3df
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x0040, lo: 0x80, hi: 0x80},
+ {value: 0x0008, lo: 0x81, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0x88},
+ {value: 0x0008, lo: 0x89, hi: 0x8e},
+ {value: 0x0040, lo: 0x8f, hi: 0x90},
+ {value: 0x0008, lo: 0x91, hi: 0x96},
+ {value: 0x0040, lo: 0x97, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa6},
+ {value: 0x0040, lo: 0xa7, hi: 0xa7},
+ {value: 0x0008, lo: 0xa8, hi: 0xae},
+ {value: 0x0040, lo: 0xaf, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbf},
+ // Block 0x7a, offset 0x3ec
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0008, lo: 0x80, hi: 0x9a},
+ {value: 0x0018, lo: 0x9b, hi: 0x9b},
+ {value: 0x449d, lo: 0x9c, hi: 0x9c},
+ {value: 0x44b5, lo: 0x9d, hi: 0x9d},
+ {value: 0x0941, lo: 0x9e, hi: 0x9e},
+ {value: 0xe06d, lo: 0x9f, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa8},
+ {value: 0x13f9, lo: 0xa9, hi: 0xa9},
+ {value: 0x0018, lo: 0xaa, hi: 0xab},
+ {value: 0x0040, lo: 0xac, hi: 0xaf},
+ {value: 0x44cd, lo: 0xb0, hi: 0xbf},
+ // Block 0x7b, offset 0x3f8
+ {value: 0x0000, lo: 0x04},
+ {value: 0x44ed, lo: 0x80, hi: 0x8f},
+ {value: 0x450d, lo: 0x90, hi: 0x9f},
+ {value: 0x452d, lo: 0xa0, hi: 0xaf},
+ {value: 0x450d, lo: 0xb0, hi: 0xbf},
+ // Block 0x7c, offset 0x3fd
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x0008, lo: 0x80, hi: 0xa2},
+ {value: 0x3008, lo: 0xa3, hi: 0xa4},
+ {value: 0x3308, lo: 0xa5, hi: 0xa5},
+ {value: 0x3008, lo: 0xa6, hi: 0xa7},
+ {value: 0x3308, lo: 0xa8, hi: 0xa8},
+ {value: 0x3008, lo: 0xa9, hi: 0xaa},
+ {value: 0x0018, lo: 0xab, hi: 0xab},
+ {value: 0x3008, lo: 0xac, hi: 0xac},
+ {value: 0x3b08, lo: 0xad, hi: 0xad},
+ {value: 0x0040, lo: 0xae, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xb9},
+ {value: 0x0040, lo: 0xba, hi: 0xbf},
+ // Block 0x7d, offset 0x40a
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0008, lo: 0x80, hi: 0xa3},
+ {value: 0x0040, lo: 0xa4, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xbf},
+ // Block 0x7e, offset 0x40e
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0018, lo: 0x80, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0x8a},
+ {value: 0x0018, lo: 0x8b, hi: 0xbb},
+ {value: 0x0040, lo: 0xbc, hi: 0xbf},
+ // Block 0x7f, offset 0x413
+ {value: 0x0000, lo: 0x01},
+ {value: 0x0040, lo: 0x80, hi: 0xbf},
+ // Block 0x80, offset 0x415
+ {value: 0x0020, lo: 0x01},
+ {value: 0x454d, lo: 0x80, hi: 0xbf},
+ // Block 0x81, offset 0x417
+ {value: 0x0020, lo: 0x03},
+ {value: 0x4d4d, lo: 0x80, hi: 0x94},
+ {value: 0x4b0d, lo: 0x95, hi: 0x95},
+ {value: 0x4fed, lo: 0x96, hi: 0xbf},
+ // Block 0x82, offset 0x41b
+ {value: 0x0020, lo: 0x01},
+ {value: 0x552d, lo: 0x80, hi: 0xbf},
+ // Block 0x83, offset 0x41d
+ {value: 0x0020, lo: 0x03},
+ {value: 0x5d2d, lo: 0x80, hi: 0x84},
+ {value: 0x568d, lo: 0x85, hi: 0x85},
+ {value: 0x5dcd, lo: 0x86, hi: 0xbf},
+ // Block 0x84, offset 0x421
+ {value: 0x0020, lo: 0x08},
+ {value: 0x6b8d, lo: 0x80, hi: 0x8f},
+ {value: 0x6d4d, lo: 0x90, hi: 0x90},
+ {value: 0x6d8d, lo: 0x91, hi: 0xab},
+ {value: 0x1401, lo: 0xac, hi: 0xac},
+ {value: 0x70ed, lo: 0xad, hi: 0xad},
+ {value: 0x0040, lo: 0xae, hi: 0xae},
+ {value: 0x0040, lo: 0xaf, hi: 0xaf},
+ {value: 0x710d, lo: 0xb0, hi: 0xbf},
+ // Block 0x85, offset 0x42a
+ {value: 0x0020, lo: 0x05},
+ {value: 0x730d, lo: 0x80, hi: 0xad},
+ {value: 0x656d, lo: 0xae, hi: 0xae},
+ {value: 0x78cd, lo: 0xaf, hi: 0xb5},
+ {value: 0x6f8d, lo: 0xb6, hi: 0xb6},
+ {value: 0x79ad, lo: 0xb7, hi: 0xbf},
+ // Block 0x86, offset 0x430
+ {value: 0x0008, lo: 0x03},
+ {value: 0x1751, lo: 0x80, hi: 0x82},
+ {value: 0x1741, lo: 0x83, hi: 0x83},
+ {value: 0x1769, lo: 0x84, hi: 0xbf},
+ // Block 0x87, offset 0x434
+ {value: 0x0008, lo: 0x0f},
+ {value: 0x1d81, lo: 0x80, hi: 0x83},
+ {value: 0x1d99, lo: 0x84, hi: 0x85},
+ {value: 0x1da1, lo: 0x86, hi: 0x87},
+ {value: 0x1da9, lo: 0x88, hi: 0x8f},
+ {value: 0x0040, lo: 0x90, hi: 0x90},
+ {value: 0x0040, lo: 0x91, hi: 0x91},
+ {value: 0x1de9, lo: 0x92, hi: 0x97},
+ {value: 0x1e11, lo: 0x98, hi: 0x9c},
+ {value: 0x1e31, lo: 0x9d, hi: 0xb3},
+ {value: 0x1d71, lo: 0xb4, hi: 0xb4},
+ {value: 0x1d81, lo: 0xb5, hi: 0xb5},
+ {value: 0x1ee9, lo: 0xb6, hi: 0xbb},
+ {value: 0x1f09, lo: 0xbc, hi: 0xbc},
+ {value: 0x1ef9, lo: 0xbd, hi: 0xbd},
+ {value: 0x1f19, lo: 0xbe, hi: 0xbf},
+ // Block 0x88, offset 0x444
+ {value: 0x0000, lo: 0x09},
+ {value: 0x0008, lo: 0x80, hi: 0x8b},
+ {value: 0x0040, lo: 0x8c, hi: 0x8c},
+ {value: 0x0008, lo: 0x8d, hi: 0xa6},
+ {value: 0x0040, lo: 0xa7, hi: 0xa7},
+ {value: 0x0008, lo: 0xa8, hi: 0xba},
+ {value: 0x0040, lo: 0xbb, hi: 0xbb},
+ {value: 0x0008, lo: 0xbc, hi: 0xbd},
+ {value: 0x0040, lo: 0xbe, hi: 0xbe},
+ {value: 0x0008, lo: 0xbf, hi: 0xbf},
+ // Block 0x89, offset 0x44e
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0x8d},
+ {value: 0x0040, lo: 0x8e, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x9d},
+ {value: 0x0040, lo: 0x9e, hi: 0xbf},
+ // Block 0x8a, offset 0x453
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0xba},
+ {value: 0x0040, lo: 0xbb, hi: 0xbf},
+ // Block 0x8b, offset 0x456
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0018, lo: 0x80, hi: 0x82},
+ {value: 0x0040, lo: 0x83, hi: 0x86},
+ {value: 0x0018, lo: 0x87, hi: 0xb3},
+ {value: 0x0040, lo: 0xb4, hi: 0xb6},
+ {value: 0x0018, lo: 0xb7, hi: 0xbf},
+ // Block 0x8c, offset 0x45c
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0018, lo: 0x80, hi: 0x8e},
+ {value: 0x0040, lo: 0x8f, hi: 0x8f},
+ {value: 0x0018, lo: 0x90, hi: 0x9c},
+ {value: 0x0040, lo: 0x9d, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xa0},
+ {value: 0x0040, lo: 0xa1, hi: 0xbf},
+ // Block 0x8d, offset 0x463
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0040, lo: 0x80, hi: 0x8f},
+ {value: 0x0018, lo: 0x90, hi: 0xbc},
+ {value: 0x3308, lo: 0xbd, hi: 0xbd},
+ {value: 0x0040, lo: 0xbe, hi: 0xbf},
+ // Block 0x8e, offset 0x468
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0008, lo: 0x80, hi: 0x9c},
+ {value: 0x0040, lo: 0x9d, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xbf},
+ // Block 0x8f, offset 0x46c
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0008, lo: 0x80, hi: 0x90},
+ {value: 0x0040, lo: 0x91, hi: 0x9f},
+ {value: 0x3308, lo: 0xa0, hi: 0xa0},
+ {value: 0x0018, lo: 0xa1, hi: 0xbb},
+ {value: 0x0040, lo: 0xbc, hi: 0xbf},
+ // Block 0x90, offset 0x472
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xa3},
+ {value: 0x0040, lo: 0xa4, hi: 0xac},
+ {value: 0x0008, lo: 0xad, hi: 0xbf},
+ // Block 0x91, offset 0x477
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0008, lo: 0x80, hi: 0x80},
+ {value: 0x0018, lo: 0x81, hi: 0x81},
+ {value: 0x0008, lo: 0x82, hi: 0x89},
+ {value: 0x0018, lo: 0x8a, hi: 0x8a},
+ {value: 0x0040, lo: 0x8b, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0xb5},
+ {value: 0x3308, lo: 0xb6, hi: 0xba},
+ {value: 0x0040, lo: 0xbb, hi: 0xbf},
+ // Block 0x92, offset 0x480
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0x9d},
+ {value: 0x0040, lo: 0x9e, hi: 0x9e},
+ {value: 0x0018, lo: 0x9f, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xbf},
+ // Block 0x93, offset 0x485
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0008, lo: 0x80, hi: 0x83},
+ {value: 0x0040, lo: 0x84, hi: 0x87},
+ {value: 0x0008, lo: 0x88, hi: 0x8f},
+ {value: 0x0018, lo: 0x90, hi: 0x95},
+ {value: 0x0040, lo: 0x96, hi: 0xbf},
+ // Block 0x94, offset 0x48b
+ {value: 0x0000, lo: 0x06},
+ {value: 0xe145, lo: 0x80, hi: 0x87},
+ {value: 0xe1c5, lo: 0x88, hi: 0x8f},
+ {value: 0xe145, lo: 0x90, hi: 0x97},
+ {value: 0x8b0d, lo: 0x98, hi: 0x9f},
+ {value: 0x8b25, lo: 0xa0, hi: 0xa7},
+ {value: 0x0008, lo: 0xa8, hi: 0xbf},
+ // Block 0x95, offset 0x492
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0008, lo: 0x80, hi: 0x9d},
+ {value: 0x0040, lo: 0x9e, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa9},
+ {value: 0x0040, lo: 0xaa, hi: 0xaf},
+ {value: 0x8b25, lo: 0xb0, hi: 0xb7},
+ {value: 0x8b0d, lo: 0xb8, hi: 0xbf},
+ // Block 0x96, offset 0x499
+ {value: 0x0000, lo: 0x06},
+ {value: 0xe145, lo: 0x80, hi: 0x87},
+ {value: 0xe1c5, lo: 0x88, hi: 0x8f},
+ {value: 0xe145, lo: 0x90, hi: 0x93},
+ {value: 0x0040, lo: 0x94, hi: 0x97},
+ {value: 0x0008, lo: 0x98, hi: 0xbb},
+ {value: 0x0040, lo: 0xbc, hi: 0xbf},
+ // Block 0x97, offset 0x4a0
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0008, lo: 0x80, hi: 0xa7},
+ {value: 0x0040, lo: 0xa8, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbf},
+ // Block 0x98, offset 0x4a4
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0xa3},
+ {value: 0x0040, lo: 0xa4, hi: 0xae},
+ {value: 0x0018, lo: 0xaf, hi: 0xaf},
+ {value: 0x0040, lo: 0xb0, hi: 0xbf},
+ // Block 0x99, offset 0x4a9
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0xb6},
+ {value: 0x0040, lo: 0xb7, hi: 0xbf},
+ // Block 0x9a, offset 0x4ac
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0x95},
+ {value: 0x0040, lo: 0x96, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa7},
+ {value: 0x0040, lo: 0xa8, hi: 0xbf},
+ // Block 0x9b, offset 0x4b1
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0808, lo: 0x80, hi: 0x85},
+ {value: 0x0040, lo: 0x86, hi: 0x87},
+ {value: 0x0808, lo: 0x88, hi: 0x88},
+ {value: 0x0040, lo: 0x89, hi: 0x89},
+ {value: 0x0808, lo: 0x8a, hi: 0xb5},
+ {value: 0x0040, lo: 0xb6, hi: 0xb6},
+ {value: 0x0808, lo: 0xb7, hi: 0xb8},
+ {value: 0x0040, lo: 0xb9, hi: 0xbb},
+ {value: 0x0808, lo: 0xbc, hi: 0xbc},
+ {value: 0x0040, lo: 0xbd, hi: 0xbe},
+ {value: 0x0808, lo: 0xbf, hi: 0xbf},
+ // Block 0x9c, offset 0x4bd
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0808, lo: 0x80, hi: 0x95},
+ {value: 0x0040, lo: 0x96, hi: 0x96},
+ {value: 0x0818, lo: 0x97, hi: 0x9f},
+ {value: 0x0808, lo: 0xa0, hi: 0xb6},
+ {value: 0x0818, lo: 0xb7, hi: 0xbf},
+ // Block 0x9d, offset 0x4c3
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0808, lo: 0x80, hi: 0x9e},
+ {value: 0x0040, lo: 0x9f, hi: 0xa6},
+ {value: 0x0818, lo: 0xa7, hi: 0xaf},
+ {value: 0x0040, lo: 0xb0, hi: 0xbf},
+ // Block 0x9e, offset 0x4c8
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0040, lo: 0x80, hi: 0x9f},
+ {value: 0x0808, lo: 0xa0, hi: 0xb2},
+ {value: 0x0040, lo: 0xb3, hi: 0xb3},
+ {value: 0x0808, lo: 0xb4, hi: 0xb5},
+ {value: 0x0040, lo: 0xb6, hi: 0xba},
+ {value: 0x0818, lo: 0xbb, hi: 0xbf},
+ // Block 0x9f, offset 0x4cf
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0808, lo: 0x80, hi: 0x95},
+ {value: 0x0818, lo: 0x96, hi: 0x9b},
+ {value: 0x0040, lo: 0x9c, hi: 0x9e},
+ {value: 0x0018, lo: 0x9f, hi: 0x9f},
+ {value: 0x0808, lo: 0xa0, hi: 0xb9},
+ {value: 0x0040, lo: 0xba, hi: 0xbe},
+ {value: 0x0818, lo: 0xbf, hi: 0xbf},
+ // Block 0xa0, offset 0x4d7
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0808, lo: 0x80, hi: 0xb7},
+ {value: 0x0040, lo: 0xb8, hi: 0xbb},
+ {value: 0x0818, lo: 0xbc, hi: 0xbd},
+ {value: 0x0808, lo: 0xbe, hi: 0xbf},
+ // Block 0xa1, offset 0x4dc
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0818, lo: 0x80, hi: 0x8f},
+ {value: 0x0040, lo: 0x90, hi: 0x91},
+ {value: 0x0818, lo: 0x92, hi: 0xbf},
+ // Block 0xa2, offset 0x4e0
+ {value: 0x0000, lo: 0x0f},
+ {value: 0x0808, lo: 0x80, hi: 0x80},
+ {value: 0x3308, lo: 0x81, hi: 0x83},
+ {value: 0x0040, lo: 0x84, hi: 0x84},
+ {value: 0x3308, lo: 0x85, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0x8b},
+ {value: 0x3308, lo: 0x8c, hi: 0x8f},
+ {value: 0x0808, lo: 0x90, hi: 0x93},
+ {value: 0x0040, lo: 0x94, hi: 0x94},
+ {value: 0x0808, lo: 0x95, hi: 0x97},
+ {value: 0x0040, lo: 0x98, hi: 0x98},
+ {value: 0x0808, lo: 0x99, hi: 0xb5},
+ {value: 0x0040, lo: 0xb6, hi: 0xb7},
+ {value: 0x3308, lo: 0xb8, hi: 0xba},
+ {value: 0x0040, lo: 0xbb, hi: 0xbe},
+ {value: 0x3b08, lo: 0xbf, hi: 0xbf},
+ // Block 0xa3, offset 0x4f0
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0818, lo: 0x80, hi: 0x88},
+ {value: 0x0040, lo: 0x89, hi: 0x8f},
+ {value: 0x0818, lo: 0x90, hi: 0x98},
+ {value: 0x0040, lo: 0x99, hi: 0x9f},
+ {value: 0x0808, lo: 0xa0, hi: 0xbc},
+ {value: 0x0818, lo: 0xbd, hi: 0xbf},
+ // Block 0xa4, offset 0x4f7
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0808, lo: 0x80, hi: 0x9c},
+ {value: 0x0818, lo: 0x9d, hi: 0x9f},
+ {value: 0x0040, lo: 0xa0, hi: 0xbf},
+ // Block 0xa5, offset 0x4fb
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0808, lo: 0x80, hi: 0xb5},
+ {value: 0x0040, lo: 0xb6, hi: 0xb8},
+ {value: 0x0018, lo: 0xb9, hi: 0xbf},
+ // Block 0xa6, offset 0x4ff
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0808, lo: 0x80, hi: 0x95},
+ {value: 0x0040, lo: 0x96, hi: 0x97},
+ {value: 0x0818, lo: 0x98, hi: 0x9f},
+ {value: 0x0808, lo: 0xa0, hi: 0xb2},
+ {value: 0x0040, lo: 0xb3, hi: 0xb7},
+ {value: 0x0818, lo: 0xb8, hi: 0xbf},
+ // Block 0xa7, offset 0x506
+ {value: 0x0000, lo: 0x01},
+ {value: 0x0808, lo: 0x80, hi: 0xbf},
+ // Block 0xa8, offset 0x508
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0808, lo: 0x80, hi: 0x88},
+ {value: 0x0040, lo: 0x89, hi: 0xbf},
+ // Block 0xa9, offset 0x50b
+ {value: 0x0000, lo: 0x02},
+ {value: 0x03dd, lo: 0x80, hi: 0xb2},
+ {value: 0x0040, lo: 0xb3, hi: 0xbf},
+ // Block 0xaa, offset 0x50e
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0808, lo: 0x80, hi: 0xb2},
+ {value: 0x0040, lo: 0xb3, hi: 0xb9},
+ {value: 0x0818, lo: 0xba, hi: 0xbf},
+ // Block 0xab, offset 0x512
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0908, lo: 0x80, hi: 0x80},
+ {value: 0x0a08, lo: 0x81, hi: 0xa1},
+ {value: 0x0c08, lo: 0xa2, hi: 0xa2},
+ {value: 0x0a08, lo: 0xa3, hi: 0xa3},
+ {value: 0x3308, lo: 0xa4, hi: 0xa7},
+ {value: 0x0040, lo: 0xa8, hi: 0xaf},
+ {value: 0x0808, lo: 0xb0, hi: 0xb9},
+ {value: 0x0040, lo: 0xba, hi: 0xbf},
+ // Block 0xac, offset 0x51b
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0040, lo: 0x80, hi: 0x9f},
+ {value: 0x0818, lo: 0xa0, hi: 0xbe},
+ {value: 0x0040, lo: 0xbf, hi: 0xbf},
+ // Block 0xad, offset 0x51f
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0808, lo: 0x80, hi: 0xa9},
+ {value: 0x0040, lo: 0xaa, hi: 0xaa},
+ {value: 0x3308, lo: 0xab, hi: 0xac},
+ {value: 0x0818, lo: 0xad, hi: 0xad},
+ {value: 0x0040, lo: 0xae, hi: 0xaf},
+ {value: 0x0808, lo: 0xb0, hi: 0xb1},
+ {value: 0x0040, lo: 0xb2, hi: 0xbf},
+ // Block 0xae, offset 0x527
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0808, lo: 0x80, hi: 0x9c},
+ {value: 0x0818, lo: 0x9d, hi: 0xa6},
+ {value: 0x0808, lo: 0xa7, hi: 0xa7},
+ {value: 0x0040, lo: 0xa8, hi: 0xaf},
+ {value: 0x0a08, lo: 0xb0, hi: 0xb2},
+ {value: 0x0c08, lo: 0xb3, hi: 0xb3},
+ {value: 0x0a08, lo: 0xb4, hi: 0xbf},
+ // Block 0xaf, offset 0x52f
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0a08, lo: 0x80, hi: 0x84},
+ {value: 0x0808, lo: 0x85, hi: 0x85},
+ {value: 0x3308, lo: 0x86, hi: 0x90},
+ {value: 0x0a18, lo: 0x91, hi: 0x93},
+ {value: 0x0c18, lo: 0x94, hi: 0x94},
+ {value: 0x0818, lo: 0x95, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0xbf},
+ // Block 0xb0, offset 0x537
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0040, lo: 0x80, hi: 0xaf},
+ {value: 0x0a08, lo: 0xb0, hi: 0xb0},
+ {value: 0x0808, lo: 0xb1, hi: 0xb1},
+ {value: 0x0a08, lo: 0xb2, hi: 0xb3},
+ {value: 0x0c08, lo: 0xb4, hi: 0xb6},
+ {value: 0x0808, lo: 0xb7, hi: 0xb7},
+ {value: 0x0a08, lo: 0xb8, hi: 0xb8},
+ {value: 0x0c08, lo: 0xb9, hi: 0xba},
+ {value: 0x0a08, lo: 0xbb, hi: 0xbc},
+ {value: 0x0c08, lo: 0xbd, hi: 0xbd},
+ {value: 0x0a08, lo: 0xbe, hi: 0xbf},
+ // Block 0xb1, offset 0x543
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0808, lo: 0x80, hi: 0x80},
+ {value: 0x0a08, lo: 0x81, hi: 0x81},
+ {value: 0x0c08, lo: 0x82, hi: 0x83},
+ {value: 0x0a08, lo: 0x84, hi: 0x84},
+ {value: 0x0818, lo: 0x85, hi: 0x88},
+ {value: 0x0c18, lo: 0x89, hi: 0x89},
+ {value: 0x0a18, lo: 0x8a, hi: 0x8a},
+ {value: 0x0918, lo: 0x8b, hi: 0x8b},
+ {value: 0x0040, lo: 0x8c, hi: 0x9f},
+ {value: 0x0808, lo: 0xa0, hi: 0xb6},
+ {value: 0x0040, lo: 0xb7, hi: 0xbf},
+ // Block 0xb2, offset 0x54f
+ {value: 0x0000, lo: 0x05},
+ {value: 0x3008, lo: 0x80, hi: 0x80},
+ {value: 0x3308, lo: 0x81, hi: 0x81},
+ {value: 0x3008, lo: 0x82, hi: 0x82},
+ {value: 0x0008, lo: 0x83, hi: 0xb7},
+ {value: 0x3308, lo: 0xb8, hi: 0xbf},
+ // Block 0xb3, offset 0x555
+ {value: 0x0000, lo: 0x08},
+ {value: 0x3308, lo: 0x80, hi: 0x85},
+ {value: 0x3b08, lo: 0x86, hi: 0x86},
+ {value: 0x0018, lo: 0x87, hi: 0x8d},
+ {value: 0x0040, lo: 0x8e, hi: 0x91},
+ {value: 0x0018, lo: 0x92, hi: 0xa5},
+ {value: 0x0008, lo: 0xa6, hi: 0xaf},
+ {value: 0x0040, lo: 0xb0, hi: 0xbe},
+ {value: 0x3b08, lo: 0xbf, hi: 0xbf},
+ // Block 0xb4, offset 0x55e
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x3308, lo: 0x80, hi: 0x81},
+ {value: 0x3008, lo: 0x82, hi: 0x82},
+ {value: 0x0008, lo: 0x83, hi: 0xaf},
+ {value: 0x3008, lo: 0xb0, hi: 0xb2},
+ {value: 0x3308, lo: 0xb3, hi: 0xb6},
+ {value: 0x3008, lo: 0xb7, hi: 0xb8},
+ {value: 0x3b08, lo: 0xb9, hi: 0xb9},
+ {value: 0x3308, lo: 0xba, hi: 0xba},
+ {value: 0x0018, lo: 0xbb, hi: 0xbc},
+ {value: 0x0040, lo: 0xbd, hi: 0xbd},
+ {value: 0x0018, lo: 0xbe, hi: 0xbf},
+ // Block 0xb5, offset 0x56a
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0018, lo: 0x80, hi: 0x81},
+ {value: 0x0040, lo: 0x82, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0xa8},
+ {value: 0x0040, lo: 0xa9, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xb9},
+ {value: 0x0040, lo: 0xba, hi: 0xbf},
+ // Block 0xb6, offset 0x571
+ {value: 0x0000, lo: 0x08},
+ {value: 0x3308, lo: 0x80, hi: 0x82},
+ {value: 0x0008, lo: 0x83, hi: 0xa6},
+ {value: 0x3308, lo: 0xa7, hi: 0xab},
+ {value: 0x3008, lo: 0xac, hi: 0xac},
+ {value: 0x3308, lo: 0xad, hi: 0xb2},
+ {value: 0x3b08, lo: 0xb3, hi: 0xb4},
+ {value: 0x0040, lo: 0xb5, hi: 0xb5},
+ {value: 0x0008, lo: 0xb6, hi: 0xbf},
+ // Block 0xb7, offset 0x57a
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x0018, lo: 0x80, hi: 0x83},
+ {value: 0x0008, lo: 0x84, hi: 0x84},
+ {value: 0x3008, lo: 0x85, hi: 0x86},
+ {value: 0x0008, lo: 0x87, hi: 0x87},
+ {value: 0x0040, lo: 0x88, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0xb2},
+ {value: 0x3308, lo: 0xb3, hi: 0xb3},
+ {value: 0x0018, lo: 0xb4, hi: 0xb5},
+ {value: 0x0008, lo: 0xb6, hi: 0xb6},
+ {value: 0x0040, lo: 0xb7, hi: 0xbf},
+ // Block 0xb8, offset 0x585
+ {value: 0x0000, lo: 0x06},
+ {value: 0x3308, lo: 0x80, hi: 0x81},
+ {value: 0x3008, lo: 0x82, hi: 0x82},
+ {value: 0x0008, lo: 0x83, hi: 0xb2},
+ {value: 0x3008, lo: 0xb3, hi: 0xb5},
+ {value: 0x3308, lo: 0xb6, hi: 0xbe},
+ {value: 0x3008, lo: 0xbf, hi: 0xbf},
+ // Block 0xb9, offset 0x58c
+ {value: 0x0000, lo: 0x0e},
+ {value: 0x3808, lo: 0x80, hi: 0x80},
+ {value: 0x0008, lo: 0x81, hi: 0x84},
+ {value: 0x0018, lo: 0x85, hi: 0x88},
+ {value: 0x3308, lo: 0x89, hi: 0x8c},
+ {value: 0x0018, lo: 0x8d, hi: 0x8d},
+ {value: 0x3008, lo: 0x8e, hi: 0x8e},
+ {value: 0x3308, lo: 0x8f, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x9a},
+ {value: 0x0018, lo: 0x9b, hi: 0x9b},
+ {value: 0x0008, lo: 0x9c, hi: 0x9c},
+ {value: 0x0018, lo: 0x9d, hi: 0x9f},
+ {value: 0x0040, lo: 0xa0, hi: 0xa0},
+ {value: 0x0018, lo: 0xa1, hi: 0xb4},
+ {value: 0x0040, lo: 0xb5, hi: 0xbf},
+ // Block 0xba, offset 0x59b
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x0008, lo: 0x80, hi: 0x91},
+ {value: 0x0040, lo: 0x92, hi: 0x92},
+ {value: 0x0008, lo: 0x93, hi: 0xab},
+ {value: 0x3008, lo: 0xac, hi: 0xae},
+ {value: 0x3308, lo: 0xaf, hi: 0xb1},
+ {value: 0x3008, lo: 0xb2, hi: 0xb3},
+ {value: 0x3308, lo: 0xb4, hi: 0xb4},
+ {value: 0x3808, lo: 0xb5, hi: 0xb5},
+ {value: 0x3308, lo: 0xb6, hi: 0xb7},
+ {value: 0x0018, lo: 0xb8, hi: 0xbd},
+ {value: 0x3308, lo: 0xbe, hi: 0xbe},
+ {value: 0x0040, lo: 0xbf, hi: 0xbf},
+ // Block 0xbb, offset 0x5a8
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x0008, lo: 0x80, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0x87},
+ {value: 0x0008, lo: 0x88, hi: 0x88},
+ {value: 0x0040, lo: 0x89, hi: 0x89},
+ {value: 0x0008, lo: 0x8a, hi: 0x8d},
+ {value: 0x0040, lo: 0x8e, hi: 0x8e},
+ {value: 0x0008, lo: 0x8f, hi: 0x9d},
+ {value: 0x0040, lo: 0x9e, hi: 0x9e},
+ {value: 0x0008, lo: 0x9f, hi: 0xa8},
+ {value: 0x0018, lo: 0xa9, hi: 0xa9},
+ {value: 0x0040, lo: 0xaa, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbf},
+ // Block 0xbc, offset 0x5b5
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0008, lo: 0x80, hi: 0x9e},
+ {value: 0x3308, lo: 0x9f, hi: 0x9f},
+ {value: 0x3008, lo: 0xa0, hi: 0xa2},
+ {value: 0x3308, lo: 0xa3, hi: 0xa9},
+ {value: 0x3b08, lo: 0xaa, hi: 0xaa},
+ {value: 0x0040, lo: 0xab, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xb9},
+ {value: 0x0040, lo: 0xba, hi: 0xbf},
+ // Block 0xbd, offset 0x5be
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0008, lo: 0x80, hi: 0xb4},
+ {value: 0x3008, lo: 0xb5, hi: 0xb7},
+ {value: 0x3308, lo: 0xb8, hi: 0xbf},
+ // Block 0xbe, offset 0x5c2
+ {value: 0x0000, lo: 0x0e},
+ {value: 0x3008, lo: 0x80, hi: 0x81},
+ {value: 0x3b08, lo: 0x82, hi: 0x82},
+ {value: 0x3308, lo: 0x83, hi: 0x84},
+ {value: 0x3008, lo: 0x85, hi: 0x85},
+ {value: 0x3308, lo: 0x86, hi: 0x86},
+ {value: 0x0008, lo: 0x87, hi: 0x8a},
+ {value: 0x0018, lo: 0x8b, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0018, lo: 0x9a, hi: 0x9b},
+ {value: 0x0040, lo: 0x9c, hi: 0x9c},
+ {value: 0x0018, lo: 0x9d, hi: 0x9d},
+ {value: 0x3308, lo: 0x9e, hi: 0x9e},
+ {value: 0x0008, lo: 0x9f, hi: 0xa1},
+ {value: 0x0040, lo: 0xa2, hi: 0xbf},
+ // Block 0xbf, offset 0x5d1
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0008, lo: 0x80, hi: 0xaf},
+ {value: 0x3008, lo: 0xb0, hi: 0xb2},
+ {value: 0x3308, lo: 0xb3, hi: 0xb8},
+ {value: 0x3008, lo: 0xb9, hi: 0xb9},
+ {value: 0x3308, lo: 0xba, hi: 0xba},
+ {value: 0x3008, lo: 0xbb, hi: 0xbe},
+ {value: 0x3308, lo: 0xbf, hi: 0xbf},
+ // Block 0xc0, offset 0x5d9
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x3308, lo: 0x80, hi: 0x80},
+ {value: 0x3008, lo: 0x81, hi: 0x81},
+ {value: 0x3b08, lo: 0x82, hi: 0x82},
+ {value: 0x3308, lo: 0x83, hi: 0x83},
+ {value: 0x0008, lo: 0x84, hi: 0x85},
+ {value: 0x0018, lo: 0x86, hi: 0x86},
+ {value: 0x0008, lo: 0x87, hi: 0x87},
+ {value: 0x0040, lo: 0x88, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0xbf},
+ // Block 0xc1, offset 0x5e4
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0008, lo: 0x80, hi: 0xae},
+ {value: 0x3008, lo: 0xaf, hi: 0xb1},
+ {value: 0x3308, lo: 0xb2, hi: 0xb5},
+ {value: 0x0040, lo: 0xb6, hi: 0xb7},
+ {value: 0x3008, lo: 0xb8, hi: 0xbb},
+ {value: 0x3308, lo: 0xbc, hi: 0xbd},
+ {value: 0x3008, lo: 0xbe, hi: 0xbe},
+ {value: 0x3b08, lo: 0xbf, hi: 0xbf},
+ // Block 0xc2, offset 0x5ed
+ {value: 0x0000, lo: 0x05},
+ {value: 0x3308, lo: 0x80, hi: 0x80},
+ {value: 0x0018, lo: 0x81, hi: 0x97},
+ {value: 0x0008, lo: 0x98, hi: 0x9b},
+ {value: 0x3308, lo: 0x9c, hi: 0x9d},
+ {value: 0x0040, lo: 0x9e, hi: 0xbf},
+ // Block 0xc3, offset 0x5f3
+ {value: 0x0000, lo: 0x07},
+ {value: 0x0008, lo: 0x80, hi: 0xaf},
+ {value: 0x3008, lo: 0xb0, hi: 0xb2},
+ {value: 0x3308, lo: 0xb3, hi: 0xba},
+ {value: 0x3008, lo: 0xbb, hi: 0xbc},
+ {value: 0x3308, lo: 0xbd, hi: 0xbd},
+ {value: 0x3008, lo: 0xbe, hi: 0xbe},
+ {value: 0x3b08, lo: 0xbf, hi: 0xbf},
+ // Block 0xc4, offset 0x5fb
+ {value: 0x0000, lo: 0x08},
+ {value: 0x3308, lo: 0x80, hi: 0x80},
+ {value: 0x0018, lo: 0x81, hi: 0x83},
+ {value: 0x0008, lo: 0x84, hi: 0x84},
+ {value: 0x0040, lo: 0x85, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xac},
+ {value: 0x0040, lo: 0xad, hi: 0xbf},
+ // Block 0xc5, offset 0x604
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x0008, lo: 0x80, hi: 0xaa},
+ {value: 0x3308, lo: 0xab, hi: 0xab},
+ {value: 0x3008, lo: 0xac, hi: 0xac},
+ {value: 0x3308, lo: 0xad, hi: 0xad},
+ {value: 0x3008, lo: 0xae, hi: 0xaf},
+ {value: 0x3308, lo: 0xb0, hi: 0xb5},
+ {value: 0x3808, lo: 0xb6, hi: 0xb6},
+ {value: 0x3308, lo: 0xb7, hi: 0xb7},
+ {value: 0x0008, lo: 0xb8, hi: 0xb8},
+ {value: 0x0040, lo: 0xb9, hi: 0xbf},
+ // Block 0xc6, offset 0x60f
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0x89},
+ {value: 0x0040, lo: 0x8a, hi: 0xbf},
+ // Block 0xc7, offset 0x612
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0008, lo: 0x80, hi: 0x9a},
+ {value: 0x0040, lo: 0x9b, hi: 0x9c},
+ {value: 0x3308, lo: 0x9d, hi: 0x9f},
+ {value: 0x3008, lo: 0xa0, hi: 0xa1},
+ {value: 0x3308, lo: 0xa2, hi: 0xa5},
+ {value: 0x3008, lo: 0xa6, hi: 0xa6},
+ {value: 0x3308, lo: 0xa7, hi: 0xaa},
+ {value: 0x3b08, lo: 0xab, hi: 0xab},
+ {value: 0x0040, lo: 0xac, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xb9},
+ {value: 0x0018, lo: 0xba, hi: 0xbf},
+ // Block 0xc8, offset 0x61e
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0008, lo: 0x80, hi: 0xab},
+ {value: 0x3008, lo: 0xac, hi: 0xae},
+ {value: 0x3308, lo: 0xaf, hi: 0xb7},
+ {value: 0x3008, lo: 0xb8, hi: 0xb8},
+ {value: 0x3b08, lo: 0xb9, hi: 0xb9},
+ {value: 0x3308, lo: 0xba, hi: 0xba},
+ {value: 0x0018, lo: 0xbb, hi: 0xbb},
+ {value: 0x0040, lo: 0xbc, hi: 0xbf},
+ // Block 0xc9, offset 0x627
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0040, lo: 0x80, hi: 0x9f},
+ {value: 0x049d, lo: 0xa0, hi: 0xbf},
+ // Block 0xca, offset 0x62a
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0xa9},
+ {value: 0x0018, lo: 0xaa, hi: 0xb2},
+ {value: 0x0040, lo: 0xb3, hi: 0xbe},
+ {value: 0x0008, lo: 0xbf, hi: 0xbf},
+ // Block 0xcb, offset 0x62f
+ {value: 0x0000, lo: 0x08},
+ {value: 0x3008, lo: 0x80, hi: 0x80},
+ {value: 0x0008, lo: 0x81, hi: 0x81},
+ {value: 0x3008, lo: 0x82, hi: 0x82},
+ {value: 0x3308, lo: 0x83, hi: 0x83},
+ {value: 0x0018, lo: 0x84, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0xbf},
+ // Block 0xcc, offset 0x638
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0040, lo: 0x80, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa7},
+ {value: 0x0040, lo: 0xa8, hi: 0xa9},
+ {value: 0x0008, lo: 0xaa, hi: 0xbf},
+ // Block 0xcd, offset 0x63d
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x0008, lo: 0x80, hi: 0x90},
+ {value: 0x3008, lo: 0x91, hi: 0x93},
+ {value: 0x3308, lo: 0x94, hi: 0x97},
+ {value: 0x0040, lo: 0x98, hi: 0x99},
+ {value: 0x3308, lo: 0x9a, hi: 0x9b},
+ {value: 0x3008, lo: 0x9c, hi: 0x9f},
+ {value: 0x3b08, lo: 0xa0, hi: 0xa0},
+ {value: 0x0008, lo: 0xa1, hi: 0xa1},
+ {value: 0x0018, lo: 0xa2, hi: 0xa2},
+ {value: 0x0008, lo: 0xa3, hi: 0xa3},
+ {value: 0x3008, lo: 0xa4, hi: 0xa4},
+ {value: 0x0040, lo: 0xa5, hi: 0xbf},
+ // Block 0xce, offset 0x64a
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x0008, lo: 0x80, hi: 0x80},
+ {value: 0x3308, lo: 0x81, hi: 0x8a},
+ {value: 0x0008, lo: 0x8b, hi: 0xb2},
+ {value: 0x3308, lo: 0xb3, hi: 0xb3},
+ {value: 0x3b08, lo: 0xb4, hi: 0xb4},
+ {value: 0x3308, lo: 0xb5, hi: 0xb8},
+ {value: 0x3008, lo: 0xb9, hi: 0xb9},
+ {value: 0x0008, lo: 0xba, hi: 0xba},
+ {value: 0x3308, lo: 0xbb, hi: 0xbe},
+ {value: 0x0018, lo: 0xbf, hi: 0xbf},
+ // Block 0xcf, offset 0x655
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0018, lo: 0x80, hi: 0x86},
+ {value: 0x3b08, lo: 0x87, hi: 0x87},
+ {value: 0x0040, lo: 0x88, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x90},
+ {value: 0x3308, lo: 0x91, hi: 0x96},
+ {value: 0x3008, lo: 0x97, hi: 0x98},
+ {value: 0x3308, lo: 0x99, hi: 0x9b},
+ {value: 0x0008, lo: 0x9c, hi: 0xbf},
+ // Block 0xd0, offset 0x65e
+ {value: 0x0000, lo: 0x09},
+ {value: 0x0008, lo: 0x80, hi: 0x89},
+ {value: 0x3308, lo: 0x8a, hi: 0x96},
+ {value: 0x3008, lo: 0x97, hi: 0x97},
+ {value: 0x3308, lo: 0x98, hi: 0x98},
+ {value: 0x3b08, lo: 0x99, hi: 0x99},
+ {value: 0x0018, lo: 0x9a, hi: 0x9c},
+ {value: 0x0008, lo: 0x9d, hi: 0x9d},
+ {value: 0x0018, lo: 0x9e, hi: 0xa2},
+ {value: 0x0040, lo: 0xa3, hi: 0xbf},
+ // Block 0xd1, offset 0x668
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0xb8},
+ {value: 0x0040, lo: 0xb9, hi: 0xbf},
+ // Block 0xd2, offset 0x66b
+ {value: 0x0000, lo: 0x09},
+ {value: 0x0008, lo: 0x80, hi: 0x88},
+ {value: 0x0040, lo: 0x89, hi: 0x89},
+ {value: 0x0008, lo: 0x8a, hi: 0xae},
+ {value: 0x3008, lo: 0xaf, hi: 0xaf},
+ {value: 0x3308, lo: 0xb0, hi: 0xb6},
+ {value: 0x0040, lo: 0xb7, hi: 0xb7},
+ {value: 0x3308, lo: 0xb8, hi: 0xbd},
+ {value: 0x3008, lo: 0xbe, hi: 0xbe},
+ {value: 0x3b08, lo: 0xbf, hi: 0xbf},
+ // Block 0xd3, offset 0x675
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0008, lo: 0x80, hi: 0x80},
+ {value: 0x0018, lo: 0x81, hi: 0x85},
+ {value: 0x0040, lo: 0x86, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0018, lo: 0x9a, hi: 0xac},
+ {value: 0x0040, lo: 0xad, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xb1},
+ {value: 0x0008, lo: 0xb2, hi: 0xbf},
+ // Block 0xd4, offset 0x67e
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x0008, lo: 0x80, hi: 0x8f},
+ {value: 0x0040, lo: 0x90, hi: 0x91},
+ {value: 0x3308, lo: 0x92, hi: 0xa7},
+ {value: 0x0040, lo: 0xa8, hi: 0xa8},
+ {value: 0x3008, lo: 0xa9, hi: 0xa9},
+ {value: 0x3308, lo: 0xaa, hi: 0xb0},
+ {value: 0x3008, lo: 0xb1, hi: 0xb1},
+ {value: 0x3308, lo: 0xb2, hi: 0xb3},
+ {value: 0x3008, lo: 0xb4, hi: 0xb4},
+ {value: 0x3308, lo: 0xb5, hi: 0xb6},
+ {value: 0x0040, lo: 0xb7, hi: 0xbf},
+ // Block 0xd5, offset 0x68a
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x0008, lo: 0x80, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0x87},
+ {value: 0x0008, lo: 0x88, hi: 0x89},
+ {value: 0x0040, lo: 0x8a, hi: 0x8a},
+ {value: 0x0008, lo: 0x8b, hi: 0xb0},
+ {value: 0x3308, lo: 0xb1, hi: 0xb6},
+ {value: 0x0040, lo: 0xb7, hi: 0xb9},
+ {value: 0x3308, lo: 0xba, hi: 0xba},
+ {value: 0x0040, lo: 0xbb, hi: 0xbb},
+ {value: 0x3308, lo: 0xbc, hi: 0xbd},
+ {value: 0x0040, lo: 0xbe, hi: 0xbe},
+ {value: 0x3308, lo: 0xbf, hi: 0xbf},
+ // Block 0xd6, offset 0x697
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x3308, lo: 0x80, hi: 0x83},
+ {value: 0x3b08, lo: 0x84, hi: 0x85},
+ {value: 0x0008, lo: 0x86, hi: 0x86},
+ {value: 0x3308, lo: 0x87, hi: 0x87},
+ {value: 0x0040, lo: 0x88, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa5},
+ {value: 0x0040, lo: 0xa6, hi: 0xa6},
+ {value: 0x0008, lo: 0xa7, hi: 0xa8},
+ {value: 0x0040, lo: 0xa9, hi: 0xa9},
+ {value: 0x0008, lo: 0xaa, hi: 0xbf},
+ // Block 0xd7, offset 0x6a4
+ {value: 0x0000, lo: 0x0d},
+ {value: 0x0008, lo: 0x80, hi: 0x89},
+ {value: 0x3008, lo: 0x8a, hi: 0x8e},
+ {value: 0x0040, lo: 0x8f, hi: 0x8f},
+ {value: 0x3308, lo: 0x90, hi: 0x91},
+ {value: 0x0040, lo: 0x92, hi: 0x92},
+ {value: 0x3008, lo: 0x93, hi: 0x94},
+ {value: 0x3308, lo: 0x95, hi: 0x95},
+ {value: 0x3008, lo: 0x96, hi: 0x96},
+ {value: 0x3b08, lo: 0x97, hi: 0x97},
+ {value: 0x0008, lo: 0x98, hi: 0x98},
+ {value: 0x0040, lo: 0x99, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa9},
+ {value: 0x0040, lo: 0xaa, hi: 0xbf},
+ // Block 0xd8, offset 0x6b2
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0040, lo: 0x80, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xb2},
+ {value: 0x3308, lo: 0xb3, hi: 0xb4},
+ {value: 0x3008, lo: 0xb5, hi: 0xb6},
+ {value: 0x0018, lo: 0xb7, hi: 0xb8},
+ {value: 0x0040, lo: 0xb9, hi: 0xbf},
+ // Block 0xd9, offset 0x6b9
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0040, lo: 0x80, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xb0},
+ {value: 0x0040, lo: 0xb1, hi: 0xbf},
+ // Block 0xda, offset 0x6bd
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0xb1},
+ {value: 0x0040, lo: 0xb2, hi: 0xbe},
+ {value: 0x0018, lo: 0xbf, hi: 0xbf},
+ // Block 0xdb, offset 0x6c1
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0xbf},
+ // Block 0xdc, offset 0x6c4
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0018, lo: 0x80, hi: 0xae},
+ {value: 0x0040, lo: 0xaf, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xb4},
+ {value: 0x0040, lo: 0xb5, hi: 0xbf},
+ // Block 0xdd, offset 0x6c9
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0x83},
+ {value: 0x0040, lo: 0x84, hi: 0xbf},
+ // Block 0xde, offset 0x6cc
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0xae},
+ {value: 0x0040, lo: 0xaf, hi: 0xaf},
+ {value: 0x0340, lo: 0xb0, hi: 0xb8},
+ {value: 0x0040, lo: 0xb9, hi: 0xbf},
+ // Block 0xdf, offset 0x6d1
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0xbf},
+ // Block 0xe0, offset 0x6d4
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0008, lo: 0x80, hi: 0x9e},
+ {value: 0x0040, lo: 0x9f, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa9},
+ {value: 0x0040, lo: 0xaa, hi: 0xad},
+ {value: 0x0018, lo: 0xae, hi: 0xaf},
+ {value: 0x0040, lo: 0xb0, hi: 0xbf},
+ // Block 0xe1, offset 0x6db
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0040, lo: 0x80, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0xad},
+ {value: 0x0040, lo: 0xae, hi: 0xaf},
+ {value: 0x3308, lo: 0xb0, hi: 0xb4},
+ {value: 0x0018, lo: 0xb5, hi: 0xb5},
+ {value: 0x0040, lo: 0xb6, hi: 0xbf},
+ // Block 0xe2, offset 0x6e2
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0008, lo: 0x80, hi: 0xaf},
+ {value: 0x3308, lo: 0xb0, hi: 0xb6},
+ {value: 0x0018, lo: 0xb7, hi: 0xbf},
+ // Block 0xe3, offset 0x6e6
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x0008, lo: 0x80, hi: 0x83},
+ {value: 0x0018, lo: 0x84, hi: 0x85},
+ {value: 0x0040, lo: 0x86, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9a},
+ {value: 0x0018, lo: 0x9b, hi: 0xa1},
+ {value: 0x0040, lo: 0xa2, hi: 0xa2},
+ {value: 0x0008, lo: 0xa3, hi: 0xb7},
+ {value: 0x0040, lo: 0xb8, hi: 0xbc},
+ {value: 0x0008, lo: 0xbd, hi: 0xbf},
+ // Block 0xe4, offset 0x6f1
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0x8f},
+ {value: 0x0040, lo: 0x90, hi: 0xbf},
+ // Block 0xe5, offset 0x6f4
+ {value: 0x0000, lo: 0x02},
+ {value: 0xe105, lo: 0x80, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xbf},
+ // Block 0xe6, offset 0x6f7
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0018, lo: 0x80, hi: 0x9a},
+ {value: 0x0040, lo: 0x9b, hi: 0xbf},
+ // Block 0xe7, offset 0x6fa
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0008, lo: 0x80, hi: 0x8a},
+ {value: 0x0040, lo: 0x8b, hi: 0x8e},
+ {value: 0x3308, lo: 0x8f, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x90},
+ {value: 0x3008, lo: 0x91, hi: 0xbf},
+ // Block 0xe8, offset 0x700
+ {value: 0x0000, lo: 0x05},
+ {value: 0x3008, lo: 0x80, hi: 0x87},
+ {value: 0x0040, lo: 0x88, hi: 0x8e},
+ {value: 0x3308, lo: 0x8f, hi: 0x92},
+ {value: 0x0008, lo: 0x93, hi: 0x9f},
+ {value: 0x0040, lo: 0xa0, hi: 0xbf},
+ // Block 0xe9, offset 0x706
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0040, lo: 0x80, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xa1},
+ {value: 0x0018, lo: 0xa2, hi: 0xa2},
+ {value: 0x0008, lo: 0xa3, hi: 0xa3},
+ {value: 0x3308, lo: 0xa4, hi: 0xa4},
+ {value: 0x0040, lo: 0xa5, hi: 0xaf},
+ {value: 0x3008, lo: 0xb0, hi: 0xb1},
+ {value: 0x0040, lo: 0xb2, hi: 0xbf},
+ // Block 0xea, offset 0x70f
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0xb7},
+ {value: 0x0040, lo: 0xb8, hi: 0xbf},
+ // Block 0xeb, offset 0x712
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0x95},
+ {value: 0x0040, lo: 0x96, hi: 0xbf},
+ // Block 0xec, offset 0x715
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0x88},
+ {value: 0x0040, lo: 0x89, hi: 0xbf},
+ // Block 0xed, offset 0x718
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0x9e},
+ {value: 0x0040, lo: 0x9f, hi: 0xbf},
+ // Block 0xee, offset 0x71b
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0040, lo: 0x80, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x92},
+ {value: 0x0040, lo: 0x93, hi: 0xa3},
+ {value: 0x0008, lo: 0xa4, hi: 0xa7},
+ {value: 0x0040, lo: 0xa8, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbf},
+ // Block 0xef, offset 0x722
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0xbb},
+ {value: 0x0040, lo: 0xbc, hi: 0xbf},
+ // Block 0xf0, offset 0x725
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0008, lo: 0x80, hi: 0xaa},
+ {value: 0x0040, lo: 0xab, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbc},
+ {value: 0x0040, lo: 0xbd, hi: 0xbf},
+ // Block 0xf1, offset 0x72a
+ {value: 0x0000, lo: 0x09},
+ {value: 0x0008, lo: 0x80, hi: 0x88},
+ {value: 0x0040, lo: 0x89, hi: 0x8f},
+ {value: 0x0008, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9b},
+ {value: 0x0018, lo: 0x9c, hi: 0x9c},
+ {value: 0x3308, lo: 0x9d, hi: 0x9e},
+ {value: 0x0018, lo: 0x9f, hi: 0x9f},
+ {value: 0x03c0, lo: 0xa0, hi: 0xa3},
+ {value: 0x0040, lo: 0xa4, hi: 0xbf},
+ // Block 0xf2, offset 0x734
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0018, lo: 0x80, hi: 0xb5},
+ {value: 0x0040, lo: 0xb6, hi: 0xbf},
+ // Block 0xf3, offset 0x737
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0xa6},
+ {value: 0x0040, lo: 0xa7, hi: 0xa8},
+ {value: 0x0018, lo: 0xa9, hi: 0xbf},
+ // Block 0xf4, offset 0x73b
+ {value: 0x0000, lo: 0x0e},
+ {value: 0x0018, lo: 0x80, hi: 0x9d},
+ {value: 0x2211, lo: 0x9e, hi: 0x9e},
+ {value: 0x2219, lo: 0x9f, hi: 0x9f},
+ {value: 0x2221, lo: 0xa0, hi: 0xa0},
+ {value: 0x2229, lo: 0xa1, hi: 0xa1},
+ {value: 0x2231, lo: 0xa2, hi: 0xa2},
+ {value: 0x2239, lo: 0xa3, hi: 0xa3},
+ {value: 0x2241, lo: 0xa4, hi: 0xa4},
+ {value: 0x3018, lo: 0xa5, hi: 0xa6},
+ {value: 0x3318, lo: 0xa7, hi: 0xa9},
+ {value: 0x0018, lo: 0xaa, hi: 0xac},
+ {value: 0x3018, lo: 0xad, hi: 0xb2},
+ {value: 0x0340, lo: 0xb3, hi: 0xba},
+ {value: 0x3318, lo: 0xbb, hi: 0xbf},
+ // Block 0xf5, offset 0x74a
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x3318, lo: 0x80, hi: 0x82},
+ {value: 0x0018, lo: 0x83, hi: 0x84},
+ {value: 0x3318, lo: 0x85, hi: 0x8b},
+ {value: 0x0018, lo: 0x8c, hi: 0xa9},
+ {value: 0x3318, lo: 0xaa, hi: 0xad},
+ {value: 0x0018, lo: 0xae, hi: 0xba},
+ {value: 0x2249, lo: 0xbb, hi: 0xbb},
+ {value: 0x2251, lo: 0xbc, hi: 0xbc},
+ {value: 0x2259, lo: 0xbd, hi: 0xbd},
+ {value: 0x2261, lo: 0xbe, hi: 0xbe},
+ {value: 0x2269, lo: 0xbf, hi: 0xbf},
+ // Block 0xf6, offset 0x756
+ {value: 0x0000, lo: 0x03},
+ {value: 0x2271, lo: 0x80, hi: 0x80},
+ {value: 0x0018, lo: 0x81, hi: 0xa8},
+ {value: 0x0040, lo: 0xa9, hi: 0xbf},
+ // Block 0xf7, offset 0x75a
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0018, lo: 0x80, hi: 0x81},
+ {value: 0x3318, lo: 0x82, hi: 0x84},
+ {value: 0x0018, lo: 0x85, hi: 0x85},
+ {value: 0x0040, lo: 0x86, hi: 0xbf},
+ // Block 0xf8, offset 0x75f
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0040, lo: 0x80, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xb3},
+ {value: 0x0040, lo: 0xb4, hi: 0xbf},
+ // Block 0xf9, offset 0x763
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0018, lo: 0x80, hi: 0x96},
+ {value: 0x0040, lo: 0x97, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xb8},
+ {value: 0x0040, lo: 0xb9, hi: 0xbf},
+ // Block 0xfa, offset 0x768
+ {value: 0x0000, lo: 0x03},
+ {value: 0x3308, lo: 0x80, hi: 0xb6},
+ {value: 0x0018, lo: 0xb7, hi: 0xba},
+ {value: 0x3308, lo: 0xbb, hi: 0xbf},
+ // Block 0xfb, offset 0x76c
+ {value: 0x0000, lo: 0x04},
+ {value: 0x3308, lo: 0x80, hi: 0xac},
+ {value: 0x0018, lo: 0xad, hi: 0xb4},
+ {value: 0x3308, lo: 0xb5, hi: 0xb5},
+ {value: 0x0018, lo: 0xb6, hi: 0xbf},
+ // Block 0xfc, offset 0x771
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0018, lo: 0x80, hi: 0x83},
+ {value: 0x3308, lo: 0x84, hi: 0x84},
+ {value: 0x0018, lo: 0x85, hi: 0x8b},
+ {value: 0x0040, lo: 0x8c, hi: 0x9a},
+ {value: 0x3308, lo: 0x9b, hi: 0x9f},
+ {value: 0x0040, lo: 0xa0, hi: 0xa0},
+ {value: 0x3308, lo: 0xa1, hi: 0xaf},
+ {value: 0x0040, lo: 0xb0, hi: 0xbf},
+ // Block 0xfd, offset 0x77a
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x3308, lo: 0x80, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0x87},
+ {value: 0x3308, lo: 0x88, hi: 0x98},
+ {value: 0x0040, lo: 0x99, hi: 0x9a},
+ {value: 0x3308, lo: 0x9b, hi: 0xa1},
+ {value: 0x0040, lo: 0xa2, hi: 0xa2},
+ {value: 0x3308, lo: 0xa3, hi: 0xa4},
+ {value: 0x0040, lo: 0xa5, hi: 0xa5},
+ {value: 0x3308, lo: 0xa6, hi: 0xaa},
+ {value: 0x0040, lo: 0xab, hi: 0xbf},
+ // Block 0xfe, offset 0x785
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0008, lo: 0x80, hi: 0xac},
+ {value: 0x0040, lo: 0xad, hi: 0xaf},
+ {value: 0x3308, lo: 0xb0, hi: 0xb6},
+ {value: 0x0008, lo: 0xb7, hi: 0xbd},
+ {value: 0x0040, lo: 0xbe, hi: 0xbf},
+ // Block 0xff, offset 0x78b
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0008, lo: 0x80, hi: 0x89},
+ {value: 0x0040, lo: 0x8a, hi: 0x8d},
+ {value: 0x0008, lo: 0x8e, hi: 0x8e},
+ {value: 0x0018, lo: 0x8f, hi: 0x8f},
+ {value: 0x0040, lo: 0x90, hi: 0xbf},
+ // Block 0x100, offset 0x791
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0008, lo: 0x80, hi: 0xab},
+ {value: 0x3308, lo: 0xac, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xb9},
+ {value: 0x0040, lo: 0xba, hi: 0xbe},
+ {value: 0x0018, lo: 0xbf, hi: 0xbf},
+ // Block 0x101, offset 0x797
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0808, lo: 0x80, hi: 0x84},
+ {value: 0x0040, lo: 0x85, hi: 0x86},
+ {value: 0x0818, lo: 0x87, hi: 0x8f},
+ {value: 0x3308, lo: 0x90, hi: 0x96},
+ {value: 0x0040, lo: 0x97, hi: 0xbf},
+ // Block 0x102, offset 0x79d
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0a08, lo: 0x80, hi: 0x83},
+ {value: 0x3308, lo: 0x84, hi: 0x8a},
+ {value: 0x0b08, lo: 0x8b, hi: 0x8b},
+ {value: 0x0040, lo: 0x8c, hi: 0x8f},
+ {value: 0x0808, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9d},
+ {value: 0x0818, lo: 0x9e, hi: 0x9f},
+ {value: 0x0040, lo: 0xa0, hi: 0xbf},
+ // Block 0x103, offset 0x7a6
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0040, lo: 0x80, hi: 0xb0},
+ {value: 0x0818, lo: 0xb1, hi: 0xbf},
+ // Block 0x104, offset 0x7a9
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0818, lo: 0x80, hi: 0xb4},
+ {value: 0x0040, lo: 0xb5, hi: 0xbf},
+ // Block 0x105, offset 0x7ac
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0040, lo: 0x80, hi: 0x80},
+ {value: 0x0818, lo: 0x81, hi: 0xbd},
+ {value: 0x0040, lo: 0xbe, hi: 0xbf},
+ // Block 0x106, offset 0x7b0
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0040, lo: 0x80, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xb1},
+ {value: 0x0040, lo: 0xb2, hi: 0xbf},
+ // Block 0x107, offset 0x7b4
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0xab},
+ {value: 0x0040, lo: 0xac, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xbf},
+ // Block 0x108, offset 0x7b8
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0018, lo: 0x80, hi: 0x93},
+ {value: 0x0040, lo: 0x94, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xae},
+ {value: 0x0040, lo: 0xaf, hi: 0xb0},
+ {value: 0x0018, lo: 0xb1, hi: 0xbf},
+ // Block 0x109, offset 0x7be
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0040, lo: 0x80, hi: 0x80},
+ {value: 0x0018, lo: 0x81, hi: 0x8f},
+ {value: 0x0040, lo: 0x90, hi: 0x90},
+ {value: 0x0018, lo: 0x91, hi: 0xb5},
+ {value: 0x0040, lo: 0xb6, hi: 0xbf},
+ // Block 0x10a, offset 0x7c4
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0018, lo: 0x80, hi: 0x8f},
+ {value: 0x2491, lo: 0x90, hi: 0x90},
+ {value: 0x0018, lo: 0x91, hi: 0xad},
+ {value: 0x0040, lo: 0xae, hi: 0xbf},
+ // Block 0x10b, offset 0x7c9
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0040, lo: 0x80, hi: 0xa5},
+ {value: 0x0018, lo: 0xa6, hi: 0xbf},
+ // Block 0x10c, offset 0x7cc
+ {value: 0x0000, lo: 0x0f},
+ {value: 0x2611, lo: 0x80, hi: 0x80},
+ {value: 0x2619, lo: 0x81, hi: 0x81},
+ {value: 0x2621, lo: 0x82, hi: 0x82},
+ {value: 0x2629, lo: 0x83, hi: 0x83},
+ {value: 0x2631, lo: 0x84, hi: 0x84},
+ {value: 0x2639, lo: 0x85, hi: 0x85},
+ {value: 0x2641, lo: 0x86, hi: 0x86},
+ {value: 0x2649, lo: 0x87, hi: 0x87},
+ {value: 0x2651, lo: 0x88, hi: 0x88},
+ {value: 0x0040, lo: 0x89, hi: 0x8f},
+ {value: 0x2659, lo: 0x90, hi: 0x90},
+ {value: 0x2661, lo: 0x91, hi: 0x91},
+ {value: 0x0040, lo: 0x92, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xa5},
+ {value: 0x0040, lo: 0xa6, hi: 0xbf},
+ // Block 0x10d, offset 0x7dc
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0018, lo: 0x80, hi: 0x97},
+ {value: 0x0040, lo: 0x98, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xac},
+ {value: 0x0040, lo: 0xad, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xbc},
+ {value: 0x0040, lo: 0xbd, hi: 0xbf},
+ // Block 0x10e, offset 0x7e3
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0018, lo: 0x80, hi: 0xb3},
+ {value: 0x0040, lo: 0xb4, hi: 0xbf},
+ // Block 0x10f, offset 0x7e6
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0018, lo: 0x80, hi: 0x98},
+ {value: 0x0040, lo: 0x99, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xab},
+ {value: 0x0040, lo: 0xac, hi: 0xbf},
+ // Block 0x110, offset 0x7eb
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0x8b},
+ {value: 0x0040, lo: 0x8c, hi: 0x8f},
+ {value: 0x0018, lo: 0x90, hi: 0xbf},
+ // Block 0x111, offset 0x7ef
+ {value: 0x0000, lo: 0x05},
+ {value: 0x0018, lo: 0x80, hi: 0x87},
+ {value: 0x0040, lo: 0x88, hi: 0x8f},
+ {value: 0x0018, lo: 0x90, hi: 0x99},
+ {value: 0x0040, lo: 0x9a, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xbf},
+ // Block 0x112, offset 0x7f5
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0018, lo: 0x80, hi: 0x87},
+ {value: 0x0040, lo: 0x88, hi: 0x8f},
+ {value: 0x0018, lo: 0x90, hi: 0xad},
+ {value: 0x0040, lo: 0xae, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xb1},
+ {value: 0x0040, lo: 0xb2, hi: 0xbf},
+ // Block 0x113, offset 0x7fc
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0xb8},
+ {value: 0x0040, lo: 0xb9, hi: 0xb9},
+ {value: 0x0018, lo: 0xba, hi: 0xbf},
+ // Block 0x114, offset 0x800
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0x8b},
+ {value: 0x0040, lo: 0x8c, hi: 0x8c},
+ {value: 0x0018, lo: 0x8d, hi: 0xbf},
+ // Block 0x115, offset 0x804
+ {value: 0x0000, lo: 0x08},
+ {value: 0x0018, lo: 0x80, hi: 0x93},
+ {value: 0x0040, lo: 0x94, hi: 0x9f},
+ {value: 0x0018, lo: 0xa0, hi: 0xad},
+ {value: 0x0040, lo: 0xae, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xb4},
+ {value: 0x0040, lo: 0xb5, hi: 0xb7},
+ {value: 0x0018, lo: 0xb8, hi: 0xba},
+ {value: 0x0040, lo: 0xbb, hi: 0xbf},
+ // Block 0x116, offset 0x80d
+ {value: 0x0000, lo: 0x06},
+ {value: 0x0018, lo: 0x80, hi: 0x86},
+ {value: 0x0040, lo: 0x87, hi: 0x8f},
+ {value: 0x0018, lo: 0x90, hi: 0xa8},
+ {value: 0x0040, lo: 0xa9, hi: 0xaf},
+ {value: 0x0018, lo: 0xb0, hi: 0xb6},
+ {value: 0x0040, lo: 0xb7, hi: 0xbf},
+ // Block 0x117, offset 0x814
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0018, lo: 0x80, hi: 0x82},
+ {value: 0x0040, lo: 0x83, hi: 0x8f},
+ {value: 0x0018, lo: 0x90, hi: 0x96},
+ {value: 0x0040, lo: 0x97, hi: 0xbf},
+ // Block 0x118, offset 0x819
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0018, lo: 0x80, hi: 0x92},
+ {value: 0x0040, lo: 0x93, hi: 0x93},
+ {value: 0x0018, lo: 0x94, hi: 0xbf},
+ // Block 0x119, offset 0x81d
+ {value: 0x0000, lo: 0x0d},
+ {value: 0x0018, lo: 0x80, hi: 0x8a},
+ {value: 0x0040, lo: 0x8b, hi: 0xaf},
+ {value: 0x06e1, lo: 0xb0, hi: 0xb0},
+ {value: 0x0049, lo: 0xb1, hi: 0xb1},
+ {value: 0x0029, lo: 0xb2, hi: 0xb2},
+ {value: 0x0031, lo: 0xb3, hi: 0xb3},
+ {value: 0x06e9, lo: 0xb4, hi: 0xb4},
+ {value: 0x06f1, lo: 0xb5, hi: 0xb5},
+ {value: 0x06f9, lo: 0xb6, hi: 0xb6},
+ {value: 0x0701, lo: 0xb7, hi: 0xb7},
+ {value: 0x0709, lo: 0xb8, hi: 0xb8},
+ {value: 0x0711, lo: 0xb9, hi: 0xb9},
+ {value: 0x0040, lo: 0xba, hi: 0xbf},
+ // Block 0x11a, offset 0x82b
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0x9d},
+ {value: 0x0040, lo: 0x9e, hi: 0xbf},
+ // Block 0x11b, offset 0x82e
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0xb4},
+ {value: 0x0040, lo: 0xb5, hi: 0xbf},
+ // Block 0x11c, offset 0x831
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0008, lo: 0x80, hi: 0x9d},
+ {value: 0x0040, lo: 0x9e, hi: 0x9f},
+ {value: 0x0008, lo: 0xa0, hi: 0xbf},
+ // Block 0x11d, offset 0x835
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0008, lo: 0x80, hi: 0xa1},
+ {value: 0x0040, lo: 0xa2, hi: 0xaf},
+ {value: 0x0008, lo: 0xb0, hi: 0xbf},
+ // Block 0x11e, offset 0x839
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0xa0},
+ {value: 0x0040, lo: 0xa1, hi: 0xbf},
+ // Block 0x11f, offset 0x83c
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0008, lo: 0x80, hi: 0x8a},
+ {value: 0x0040, lo: 0x8b, hi: 0xbf},
+ // Block 0x120, offset 0x83f
+ {value: 0x0000, lo: 0x04},
+ {value: 0x0040, lo: 0x80, hi: 0x80},
+ {value: 0x0340, lo: 0x81, hi: 0x81},
+ {value: 0x0040, lo: 0x82, hi: 0x9f},
+ {value: 0x0340, lo: 0xa0, hi: 0xbf},
+ // Block 0x121, offset 0x844
+ {value: 0x0000, lo: 0x01},
+ {value: 0x0340, lo: 0x80, hi: 0xbf},
+ // Block 0x122, offset 0x846
+ {value: 0x0000, lo: 0x01},
+ {value: 0x33c0, lo: 0x80, hi: 0xbf},
+ // Block 0x123, offset 0x848
+ {value: 0x0000, lo: 0x02},
+ {value: 0x33c0, lo: 0x80, hi: 0xaf},
+ {value: 0x0040, lo: 0xb0, hi: 0xbf},
+}
+
+// Total table size 44953 bytes (43KiB); checksum: D51909DD
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/trie.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/trie.go
new file mode 100644
index 0000000000..4212741728
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/trie.go
@@ -0,0 +1,51 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+// Copyright 2016 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 idna
+
+// Sparse block handling code.
+
+type valueRange struct {
+ value uint16 // header: value:stride
+ lo, hi byte // header: lo:n
+}
+
+type sparseBlocks struct {
+ values []valueRange
+ offset []uint16
+}
+
+var idnaSparse = sparseBlocks{
+ values: idnaSparseValues[:],
+ offset: idnaSparseOffset[:],
+}
+
+// Don't use newIdnaTrie to avoid unconditional linking in of the table.
+var trie = &idnaTrie{}
+
+// lookup determines the type of block n and looks up the value for b.
+// For n < t.cutoff, the block is a simple lookup table. Otherwise, the block
+// is a list of ranges with an accompanying value. Given a matching range r,
+// the value for b is by r.value + (b - r.lo) * stride.
+func (t *sparseBlocks) lookup(n uint32, b byte) uint16 {
+ offset := t.offset[n]
+ header := t.values[offset]
+ lo := offset + 1
+ hi := lo + uint16(header.lo)
+ for lo < hi {
+ m := lo + (hi-lo)/2
+ r := t.values[m]
+ if r.lo <= b && b <= r.hi {
+ return r.value + uint16(b-r.lo)*header.value
+ }
+ if b < r.lo {
+ hi = m
+ } else {
+ lo = m + 1
+ }
+ }
+ return 0
+}
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/trie13.0.0.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/trie13.0.0.go
new file mode 100644
index 0000000000..7d68a8dc13
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/trie13.0.0.go
@@ -0,0 +1,31 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+// Copyright 2016 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.
+
+//go:build go1.16
+// +build go1.16
+
+package idna
+
+// appendMapping appends the mapping for the respective rune. isMapped must be
+// true. A mapping is a categorization of a rune as defined in UTS #46.
+func (c info) appendMapping(b []byte, s string) []byte {
+ index := int(c >> indexShift)
+ if c&xorBit == 0 {
+ p := index
+ return append(b, mappings[mappingIndex[p]:mappingIndex[p+1]]...)
+ }
+ b = append(b, s...)
+ if c&inlineXOR == inlineXOR {
+ // TODO: support and handle two-byte inline masks
+ b[len(b)-1] ^= byte(index)
+ } else {
+ for p := len(b) - int(xorData[index]); p < len(b); p++ {
+ index++
+ b[p] ^= xorData[index]
+ }
+ }
+ return b
+}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/trieval.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/trieval.go
index 9c070a44b3..9c070a44b3 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/idna/trieval.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/trieval.go
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/ya.make
new file mode 100644
index 0000000000..5287d045ae
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/idna/ya.make
@@ -0,0 +1,13 @@
+GO_LIBRARY()
+
+SRCS(
+ go118.go
+ idna10.0.0.go
+ punycode.go
+ tables13.0.0.go
+ trie.go
+ trie13.0.0.go
+ trieval.go
+)
+
+END()
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/address.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/address.go
index 5a3cc06549..5a3cc06549 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/address.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/address.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/binary.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/binary.go
index a5e28f1e9c..a5e28f1e9c 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/binary.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/binary.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/empty.s b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/empty.s
index 90ab4ca3d8..90ab4ca3d8 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/empty.s
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/empty.s
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/interface.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/interface.go
index 9e9407830c..9e9407830c 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/interface.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/interface.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/interface_classic.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/interface_classic.go
index 903a196346..903a196346 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/interface_classic.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/interface_classic.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/interface_multicast.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/interface_multicast.go
index dd0b214baa..dd0b214baa 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/interface_multicast.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/interface_multicast.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/message.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/message.go
index 456a8363fe..456a8363fe 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/message.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/message.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/route.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/route.go
index 3ab5bcdc01..3ab5bcdc01 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/route.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/route.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/route_classic.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/route_classic.go
index d6ee42f1b1..d6ee42f1b1 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/route_classic.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/route_classic.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/sys.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/sys.go
index 7c75574f18..7c75574f18 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/sys.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/sys.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/sys_darwin.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/sys_darwin.go
index c8c4eecb8e..c8c4eecb8e 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/sys_darwin.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/sys_darwin.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/syscall.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/syscall.go
index 68d37c9621..68d37c9621 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/syscall.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/syscall.go
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/ya.make
new file mode 100644
index 0000000000..d079c72bfd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/ya.make
@@ -0,0 +1,26 @@
+GO_LIBRARY()
+
+BUILD_ONLY_IF(
+ WARNING
+ OS_DARWIN
+)
+
+IF (OS_DARWIN)
+ SRCS(
+ address.go
+ binary.go
+ empty.s
+ interface.go
+ interface_classic.go
+ interface_multicast.go
+ message.go
+ route.go
+ route_classic.go
+ sys.go
+ sys_darwin.go
+ syscall.go
+ zsys_darwin.go
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/zsys_darwin.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/zsys_darwin.go
index 56a0c66f44..56a0c66f44 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/net/route/zsys_darwin.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/net/route/zsys_darwin.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/byteorder.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/byteorder.go
index 271055be0b..271055be0b 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/byteorder.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/byteorder.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu.go
index 83f112c4c8..83f112c4c8 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_arm64.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_arm64.go
index f3eb993bf2..f3eb993bf2 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_arm64.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_arm64.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_arm64.s b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_arm64.s
index c61f95a05a..c61f95a05a 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_arm64.s
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_arm64.s
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
index ccf542a73d..ccf542a73d 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
index fa7cdb9bcd..fa7cdb9bcd 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_gc_x86.go
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
new file mode 100644
index 0000000000..a968b80fa6
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go
@@ -0,0 +1,111 @@
+// Copyright 2018 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 cpu
+
+import (
+ "strings"
+ "syscall"
+)
+
+// HWCAP/HWCAP2 bits. These are exposed by Linux.
+const (
+ hwcap_FP = 1 << 0
+ hwcap_ASIMD = 1 << 1
+ hwcap_EVTSTRM = 1 << 2
+ hwcap_AES = 1 << 3
+ hwcap_PMULL = 1 << 4
+ hwcap_SHA1 = 1 << 5
+ hwcap_SHA2 = 1 << 6
+ hwcap_CRC32 = 1 << 7
+ hwcap_ATOMICS = 1 << 8
+ hwcap_FPHP = 1 << 9
+ hwcap_ASIMDHP = 1 << 10
+ hwcap_CPUID = 1 << 11
+ hwcap_ASIMDRDM = 1 << 12
+ hwcap_JSCVT = 1 << 13
+ hwcap_FCMA = 1 << 14
+ hwcap_LRCPC = 1 << 15
+ hwcap_DCPOP = 1 << 16
+ hwcap_SHA3 = 1 << 17
+ hwcap_SM3 = 1 << 18
+ hwcap_SM4 = 1 << 19
+ hwcap_ASIMDDP = 1 << 20
+ hwcap_SHA512 = 1 << 21
+ hwcap_SVE = 1 << 22
+ hwcap_ASIMDFHM = 1 << 23
+)
+
+// linuxKernelCanEmulateCPUID reports whether we're running
+// on Linux 4.11+. Ideally we'd like to ask the question about
+// whether the current kernel contains
+// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=77c97b4ee21290f5f083173d957843b615abbff2
+// but the version number will have to do.
+func linuxKernelCanEmulateCPUID() bool {
+ var un syscall.Utsname
+ syscall.Uname(&un)
+ var sb strings.Builder
+ for _, b := range un.Release[:] {
+ if b == 0 {
+ break
+ }
+ sb.WriteByte(byte(b))
+ }
+ major, minor, _, ok := parseRelease(sb.String())
+ return ok && (major > 4 || major == 4 && minor >= 11)
+}
+
+func doinit() {
+ if err := readHWCAP(); err != nil {
+ // We failed to read /proc/self/auxv. This can happen if the binary has
+ // been given extra capabilities(7) with /bin/setcap.
+ //
+ // When this happens, we have two options. If the Linux kernel is new
+ // enough (4.11+), we can read the arm64 registers directly which'll
+ // trap into the kernel and then return back to userspace.
+ //
+ // But on older kernels, such as Linux 4.4.180 as used on many Synology
+ // devices, calling readARM64Registers (specifically getisar0) will
+ // cause a SIGILL and we'll die. So for older kernels, parse /proc/cpuinfo
+ // instead.
+ //
+ // See golang/go#57336.
+ if linuxKernelCanEmulateCPUID() {
+ readARM64Registers()
+ } else {
+ readLinuxProcCPUInfo()
+ }
+ return
+ }
+
+ // HWCAP feature bits
+ ARM64.HasFP = isSet(hwCap, hwcap_FP)
+ ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD)
+ ARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM)
+ ARM64.HasAES = isSet(hwCap, hwcap_AES)
+ ARM64.HasPMULL = isSet(hwCap, hwcap_PMULL)
+ ARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1)
+ ARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2)
+ ARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32)
+ ARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS)
+ ARM64.HasFPHP = isSet(hwCap, hwcap_FPHP)
+ ARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP)
+ ARM64.HasCPUID = isSet(hwCap, hwcap_CPUID)
+ ARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM)
+ ARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT)
+ ARM64.HasFCMA = isSet(hwCap, hwcap_FCMA)
+ ARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC)
+ ARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP)
+ ARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3)
+ ARM64.HasSM3 = isSet(hwCap, hwcap_SM3)
+ ARM64.HasSM4 = isSet(hwCap, hwcap_SM4)
+ ARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP)
+ ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512)
+ ARM64.HasSVE = isSet(hwCap, hwcap_SVE)
+ ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM)
+}
+
+func isSet(hwc uint, value uint) bool {
+ return hwc&value != 0
+}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go
index f4992b1a59..f4992b1a59 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_x86.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_x86.go
index f5aacfc825..f5aacfc825 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_x86.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_x86.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_x86.s b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_x86.s
index 39acab2ff5..39acab2ff5 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/sys/cpu/cpu_x86.s
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/cpu_x86.s
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/endian_little.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/endian_little.go
new file mode 100644
index 0000000000..55db853efb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/endian_little.go
@@ -0,0 +1,11 @@
+// Copyright 2023 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.
+
+//go:build 386 || amd64 || amd64p32 || alpha || arm || arm64 || loong64 || mipsle || mips64le || mips64p32le || nios2 || ppc64le || riscv || riscv64 || sh || wasm
+// +build 386 amd64 amd64p32 alpha arm arm64 loong64 mipsle mips64le mips64p32le nios2 ppc64le riscv riscv64 sh wasm
+
+package cpu
+
+// IsBigEndian records whether the GOARCH's byte order is big endian.
+const IsBigEndian = false
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/hwcap_linux.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/hwcap_linux.go
new file mode 100644
index 0000000000..1d9d91f3ed
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/hwcap_linux.go
@@ -0,0 +1,71 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cpu
+
+import (
+ "io/ioutil"
+)
+
+const (
+ _AT_HWCAP = 16
+ _AT_HWCAP2 = 26
+
+ procAuxv = "/proc/self/auxv"
+
+ uintSize = int(32 << (^uint(0) >> 63))
+)
+
+// For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2
+// These are initialized in cpu_$GOARCH.go
+// and should not be changed after they are initialized.
+var hwCap uint
+var hwCap2 uint
+
+func readHWCAP() error {
+ // For Go 1.21+, get auxv from the Go runtime.
+ if a := getAuxv(); len(a) > 0 {
+ for len(a) >= 2 {
+ tag, val := a[0], uint(a[1])
+ a = a[2:]
+ switch tag {
+ case _AT_HWCAP:
+ hwCap = val
+ case _AT_HWCAP2:
+ hwCap2 = val
+ }
+ }
+ return nil
+ }
+
+ buf, err := ioutil.ReadFile(procAuxv)
+ if err != nil {
+ // e.g. on android /proc/self/auxv is not accessible, so silently
+ // ignore the error and leave Initialized = false. On some
+ // architectures (e.g. arm64) doinit() implements a fallback
+ // readout and will set Initialized = true again.
+ return err
+ }
+ bo := hostByteOrder()
+ for len(buf) >= 2*(uintSize/8) {
+ var tag, val uint
+ switch uintSize {
+ case 32:
+ tag = uint(bo.Uint32(buf[0:]))
+ val = uint(bo.Uint32(buf[4:]))
+ buf = buf[8:]
+ case 64:
+ tag = uint(bo.Uint64(buf[0:]))
+ val = uint(bo.Uint64(buf[8:]))
+ buf = buf[16:]
+ }
+ switch tag {
+ case _AT_HWCAP:
+ hwCap = val
+ case _AT_HWCAP2:
+ hwCap2 = val
+ }
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/parse.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/parse.go
new file mode 100644
index 0000000000..762b63d688
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/parse.go
@@ -0,0 +1,43 @@
+// Copyright 2022 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 cpu
+
+import "strconv"
+
+// parseRelease parses a dot-separated version number. It follows the semver
+// syntax, but allows the minor and patch versions to be elided.
+//
+// This is a copy of the Go runtime's parseRelease from
+// https://golang.org/cl/209597.
+func parseRelease(rel string) (major, minor, patch int, ok bool) {
+ // Strip anything after a dash or plus.
+ for i := 0; i < len(rel); i++ {
+ if rel[i] == '-' || rel[i] == '+' {
+ rel = rel[:i]
+ break
+ }
+ }
+
+ next := func() (int, bool) {
+ for i := 0; i < len(rel); i++ {
+ if rel[i] == '.' {
+ ver, err := strconv.Atoi(rel[:i])
+ rel = rel[i+1:]
+ return ver, err == nil
+ }
+ }
+ ver, err := strconv.Atoi(rel)
+ rel = ""
+ return ver, err == nil
+ }
+ if major, ok = next(); !ok || rel == "" {
+ return
+ }
+ if minor, ok = next(); !ok || rel == "" {
+ return
+ }
+ patch, ok = next()
+ return
+}
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/proc_cpuinfo_linux.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/proc_cpuinfo_linux.go
new file mode 100644
index 0000000000..d87bd6b3eb
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/proc_cpuinfo_linux.go
@@ -0,0 +1,54 @@
+// Copyright 2022 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.
+
+//go:build linux && arm64
+// +build linux,arm64
+
+package cpu
+
+import (
+ "errors"
+ "io"
+ "os"
+ "strings"
+)
+
+func readLinuxProcCPUInfo() error {
+ f, err := os.Open("/proc/cpuinfo")
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ var buf [1 << 10]byte // enough for first CPU
+ n, err := io.ReadFull(f, buf[:])
+ if err != nil && err != io.ErrUnexpectedEOF {
+ return err
+ }
+ in := string(buf[:n])
+ const features = "\nFeatures : "
+ i := strings.Index(in, features)
+ if i == -1 {
+ return errors.New("no CPU features found")
+ }
+ in = in[i+len(features):]
+ if i := strings.Index(in, "\n"); i != -1 {
+ in = in[:i]
+ }
+ m := map[string]*bool{}
+
+ initOptions() // need it early here; it's harmless to call twice
+ for _, o := range options {
+ m[o.Name] = o.Feature
+ }
+ // The EVTSTRM field has alias "evstrm" in Go, but Linux calls it "evtstrm".
+ m["evtstrm"] = &ARM64.HasEVTSTRM
+
+ for _, f := range strings.Fields(in) {
+ if p, ok := m[f]; ok {
+ *p = true
+ }
+ }
+ return nil
+}
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/runtime_auxv.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/runtime_auxv.go
new file mode 100644
index 0000000000..5f92ac9a2e
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/runtime_auxv.go
@@ -0,0 +1,16 @@
+// Copyright 2023 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 cpu
+
+// getAuxvFn is non-nil on Go 1.21+ (via runtime_auxv_go121.go init)
+// on platforms that use auxv.
+var getAuxvFn func() []uintptr
+
+func getAuxv() []uintptr {
+ if getAuxvFn == nil {
+ return nil
+ }
+ return getAuxvFn()
+}
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/ya.make
new file mode 100644
index 0000000000..e99252386b
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/sys/cpu/ya.make
@@ -0,0 +1,58 @@
+GO_LIBRARY()
+
+SRCS(
+ byteorder.go
+ cpu.go
+ endian_little.go
+ parse.go
+ runtime_auxv.go
+)
+
+IF (ARCH_X86_64)
+ SRCS(
+ cpu_gc_x86.go
+ cpu_x86.go
+ cpu_x86.s
+ )
+ENDIF()
+
+IF (ARCH_ARM64)
+ SRCS(
+ cpu_arm64.go
+ cpu_arm64.s
+ cpu_gc_arm64.go
+ )
+ENDIF()
+
+IF (OS_LINUX)
+ SRCS(
+ hwcap_linux.go
+ )
+ENDIF()
+
+IF (OS_LINUX AND ARCH_X86_64)
+ SRCS(
+ cpu_linux_noinit.go
+ )
+ENDIF()
+
+IF (OS_LINUX AND ARCH_ARM64)
+ SRCS(
+ cpu_linux_arm64.go
+ proc_cpuinfo_linux.go
+ )
+ENDIF()
+
+IF (OS_DARWIN AND ARCH_ARM64)
+ SRCS(
+ cpu_other_arm64.go
+ )
+ENDIF()
+
+IF (OS_WINDOWS AND ARCH_ARM64)
+ SRCS(
+ cpu_other_arm64.go
+ )
+ENDIF()
+
+END()
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/secure/bidirule/bidirule.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/secure/bidirule/bidirule.go
index e2b70f76c2..e2b70f76c2 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/secure/bidirule/bidirule.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/secure/bidirule/bidirule.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go
index 8a7392c4a1..8a7392c4a1 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/secure/bidirule/bidirule10.0.0.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/secure/bidirule/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/secure/bidirule/ya.make
index 680aa64f3d..680aa64f3d 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/secure/bidirule/ya.make
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/secure/bidirule/ya.make
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/transform/transform.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/transform/transform.go
index 48ec64b40c..48ec64b40c 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/transform/transform.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/transform/transform.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/transform/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/transform/ya.make
index a000d18158..a000d18158 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/transform/ya.make
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/transform/ya.make
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/bidi.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/bidi.go
index fd057601bd..fd057601bd 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/bidi.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/bidi.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/bracket.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/bracket.go
index 1853939791..1853939791 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/bracket.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/bracket.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/core.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/core.go
index 9d2ae547b5..9d2ae547b5 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/core.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/core.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/prop.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/prop.go
index 7c9484e1f5..7c9484e1f5 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/prop.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/prop.go
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go
new file mode 100644
index 0000000000..ffadb7bebd
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/tables13.0.0.go
@@ -0,0 +1,1956 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+//go:build go1.16 && !go1.21
+// +build go1.16,!go1.21
+
+package bidi
+
+// UnicodeVersion is the Unicode version from which the tables in this package are derived.
+const UnicodeVersion = "13.0.0"
+
+// xorMasks contains masks to be xor-ed with brackets to get the reverse
+// version.
+var xorMasks = []int32{ // 8 elements
+ 0, 1, 6, 7, 3, 15, 29, 63,
+} // Size: 56 bytes
+
+// lookup returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *bidiTrie) lookup(s []byte) (v uint8, sz int) {
+ c0 := s[0]
+ switch {
+ case c0 < 0x80: // is ASCII
+ return bidiValues[c0], 1
+ case c0 < 0xC2:
+ return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+ case c0 < 0xE0: // 2-byte UTF-8
+ if len(s) < 2 {
+ return 0, 0
+ }
+ i := bidiIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c1), 2
+ case c0 < 0xF0: // 3-byte UTF-8
+ if len(s) < 3 {
+ return 0, 0
+ }
+ i := bidiIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = bidiIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c2), 3
+ case c0 < 0xF8: // 4-byte UTF-8
+ if len(s) < 4 {
+ return 0, 0
+ }
+ i := bidiIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = bidiIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ o = uint32(i)<<6 + uint32(c2)
+ i = bidiIndex[o]
+ c3 := s[3]
+ if c3 < 0x80 || 0xC0 <= c3 {
+ return 0, 3 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c3), 4
+ }
+ // Illegal rune
+ return 0, 1
+}
+
+// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *bidiTrie) lookupUnsafe(s []byte) uint8 {
+ c0 := s[0]
+ if c0 < 0x80 { // is ASCII
+ return bidiValues[c0]
+ }
+ i := bidiIndex[c0]
+ if c0 < 0xE0 { // 2-byte UTF-8
+ return t.lookupValue(uint32(i), s[1])
+ }
+ i = bidiIndex[uint32(i)<<6+uint32(s[1])]
+ if c0 < 0xF0 { // 3-byte UTF-8
+ return t.lookupValue(uint32(i), s[2])
+ }
+ i = bidiIndex[uint32(i)<<6+uint32(s[2])]
+ if c0 < 0xF8 { // 4-byte UTF-8
+ return t.lookupValue(uint32(i), s[3])
+ }
+ return 0
+}
+
+// lookupString returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *bidiTrie) lookupString(s string) (v uint8, sz int) {
+ c0 := s[0]
+ switch {
+ case c0 < 0x80: // is ASCII
+ return bidiValues[c0], 1
+ case c0 < 0xC2:
+ return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+ case c0 < 0xE0: // 2-byte UTF-8
+ if len(s) < 2 {
+ return 0, 0
+ }
+ i := bidiIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c1), 2
+ case c0 < 0xF0: // 3-byte UTF-8
+ if len(s) < 3 {
+ return 0, 0
+ }
+ i := bidiIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = bidiIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c2), 3
+ case c0 < 0xF8: // 4-byte UTF-8
+ if len(s) < 4 {
+ return 0, 0
+ }
+ i := bidiIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = bidiIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ o = uint32(i)<<6 + uint32(c2)
+ i = bidiIndex[o]
+ c3 := s[3]
+ if c3 < 0x80 || 0xC0 <= c3 {
+ return 0, 3 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c3), 4
+ }
+ // Illegal rune
+ return 0, 1
+}
+
+// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *bidiTrie) lookupStringUnsafe(s string) uint8 {
+ c0 := s[0]
+ if c0 < 0x80 { // is ASCII
+ return bidiValues[c0]
+ }
+ i := bidiIndex[c0]
+ if c0 < 0xE0 { // 2-byte UTF-8
+ return t.lookupValue(uint32(i), s[1])
+ }
+ i = bidiIndex[uint32(i)<<6+uint32(s[1])]
+ if c0 < 0xF0 { // 3-byte UTF-8
+ return t.lookupValue(uint32(i), s[2])
+ }
+ i = bidiIndex[uint32(i)<<6+uint32(s[2])]
+ if c0 < 0xF8 { // 4-byte UTF-8
+ return t.lookupValue(uint32(i), s[3])
+ }
+ return 0
+}
+
+// bidiTrie. Total size: 17408 bytes (17.00 KiB). Checksum: df85fcbfe9b8377f.
+type bidiTrie struct{}
+
+func newBidiTrie(i int) *bidiTrie {
+ return &bidiTrie{}
+}
+
+// lookupValue determines the type of block n and looks up the value for b.
+func (t *bidiTrie) lookupValue(n uint32, b byte) uint8 {
+ switch {
+ default:
+ return uint8(bidiValues[n<<6+uint32(b)])
+ }
+}
+
+// bidiValues: 248 blocks, 15872 entries, 15872 bytes
+// The third block is the zero block.
+var bidiValues = [15872]uint8{
+ // Block 0x0, offset 0x0
+ 0x00: 0x000b, 0x01: 0x000b, 0x02: 0x000b, 0x03: 0x000b, 0x04: 0x000b, 0x05: 0x000b,
+ 0x06: 0x000b, 0x07: 0x000b, 0x08: 0x000b, 0x09: 0x0008, 0x0a: 0x0007, 0x0b: 0x0008,
+ 0x0c: 0x0009, 0x0d: 0x0007, 0x0e: 0x000b, 0x0f: 0x000b, 0x10: 0x000b, 0x11: 0x000b,
+ 0x12: 0x000b, 0x13: 0x000b, 0x14: 0x000b, 0x15: 0x000b, 0x16: 0x000b, 0x17: 0x000b,
+ 0x18: 0x000b, 0x19: 0x000b, 0x1a: 0x000b, 0x1b: 0x000b, 0x1c: 0x0007, 0x1d: 0x0007,
+ 0x1e: 0x0007, 0x1f: 0x0008, 0x20: 0x0009, 0x21: 0x000a, 0x22: 0x000a, 0x23: 0x0004,
+ 0x24: 0x0004, 0x25: 0x0004, 0x26: 0x000a, 0x27: 0x000a, 0x28: 0x003a, 0x29: 0x002a,
+ 0x2a: 0x000a, 0x2b: 0x0003, 0x2c: 0x0006, 0x2d: 0x0003, 0x2e: 0x0006, 0x2f: 0x0006,
+ 0x30: 0x0002, 0x31: 0x0002, 0x32: 0x0002, 0x33: 0x0002, 0x34: 0x0002, 0x35: 0x0002,
+ 0x36: 0x0002, 0x37: 0x0002, 0x38: 0x0002, 0x39: 0x0002, 0x3a: 0x0006, 0x3b: 0x000a,
+ 0x3c: 0x000a, 0x3d: 0x000a, 0x3e: 0x000a, 0x3f: 0x000a,
+ // Block 0x1, offset 0x40
+ 0x40: 0x000a,
+ 0x5b: 0x005a, 0x5c: 0x000a, 0x5d: 0x004a,
+ 0x5e: 0x000a, 0x5f: 0x000a, 0x60: 0x000a,
+ 0x7b: 0x005a,
+ 0x7c: 0x000a, 0x7d: 0x004a, 0x7e: 0x000a, 0x7f: 0x000b,
+ // Block 0x2, offset 0x80
+ // Block 0x3, offset 0xc0
+ 0xc0: 0x000b, 0xc1: 0x000b, 0xc2: 0x000b, 0xc3: 0x000b, 0xc4: 0x000b, 0xc5: 0x0007,
+ 0xc6: 0x000b, 0xc7: 0x000b, 0xc8: 0x000b, 0xc9: 0x000b, 0xca: 0x000b, 0xcb: 0x000b,
+ 0xcc: 0x000b, 0xcd: 0x000b, 0xce: 0x000b, 0xcf: 0x000b, 0xd0: 0x000b, 0xd1: 0x000b,
+ 0xd2: 0x000b, 0xd3: 0x000b, 0xd4: 0x000b, 0xd5: 0x000b, 0xd6: 0x000b, 0xd7: 0x000b,
+ 0xd8: 0x000b, 0xd9: 0x000b, 0xda: 0x000b, 0xdb: 0x000b, 0xdc: 0x000b, 0xdd: 0x000b,
+ 0xde: 0x000b, 0xdf: 0x000b, 0xe0: 0x0006, 0xe1: 0x000a, 0xe2: 0x0004, 0xe3: 0x0004,
+ 0xe4: 0x0004, 0xe5: 0x0004, 0xe6: 0x000a, 0xe7: 0x000a, 0xe8: 0x000a, 0xe9: 0x000a,
+ 0xeb: 0x000a, 0xec: 0x000a, 0xed: 0x000b, 0xee: 0x000a, 0xef: 0x000a,
+ 0xf0: 0x0004, 0xf1: 0x0004, 0xf2: 0x0002, 0xf3: 0x0002, 0xf4: 0x000a,
+ 0xf6: 0x000a, 0xf7: 0x000a, 0xf8: 0x000a, 0xf9: 0x0002, 0xfb: 0x000a,
+ 0xfc: 0x000a, 0xfd: 0x000a, 0xfe: 0x000a, 0xff: 0x000a,
+ // Block 0x4, offset 0x100
+ 0x117: 0x000a,
+ 0x137: 0x000a,
+ // Block 0x5, offset 0x140
+ 0x179: 0x000a, 0x17a: 0x000a,
+ // Block 0x6, offset 0x180
+ 0x182: 0x000a, 0x183: 0x000a, 0x184: 0x000a, 0x185: 0x000a,
+ 0x186: 0x000a, 0x187: 0x000a, 0x188: 0x000a, 0x189: 0x000a, 0x18a: 0x000a, 0x18b: 0x000a,
+ 0x18c: 0x000a, 0x18d: 0x000a, 0x18e: 0x000a, 0x18f: 0x000a,
+ 0x192: 0x000a, 0x193: 0x000a, 0x194: 0x000a, 0x195: 0x000a, 0x196: 0x000a, 0x197: 0x000a,
+ 0x198: 0x000a, 0x199: 0x000a, 0x19a: 0x000a, 0x19b: 0x000a, 0x19c: 0x000a, 0x19d: 0x000a,
+ 0x19e: 0x000a, 0x19f: 0x000a,
+ 0x1a5: 0x000a, 0x1a6: 0x000a, 0x1a7: 0x000a, 0x1a8: 0x000a, 0x1a9: 0x000a,
+ 0x1aa: 0x000a, 0x1ab: 0x000a, 0x1ac: 0x000a, 0x1ad: 0x000a, 0x1af: 0x000a,
+ 0x1b0: 0x000a, 0x1b1: 0x000a, 0x1b2: 0x000a, 0x1b3: 0x000a, 0x1b4: 0x000a, 0x1b5: 0x000a,
+ 0x1b6: 0x000a, 0x1b7: 0x000a, 0x1b8: 0x000a, 0x1b9: 0x000a, 0x1ba: 0x000a, 0x1bb: 0x000a,
+ 0x1bc: 0x000a, 0x1bd: 0x000a, 0x1be: 0x000a, 0x1bf: 0x000a,
+ // Block 0x7, offset 0x1c0
+ 0x1c0: 0x000c, 0x1c1: 0x000c, 0x1c2: 0x000c, 0x1c3: 0x000c, 0x1c4: 0x000c, 0x1c5: 0x000c,
+ 0x1c6: 0x000c, 0x1c7: 0x000c, 0x1c8: 0x000c, 0x1c9: 0x000c, 0x1ca: 0x000c, 0x1cb: 0x000c,
+ 0x1cc: 0x000c, 0x1cd: 0x000c, 0x1ce: 0x000c, 0x1cf: 0x000c, 0x1d0: 0x000c, 0x1d1: 0x000c,
+ 0x1d2: 0x000c, 0x1d3: 0x000c, 0x1d4: 0x000c, 0x1d5: 0x000c, 0x1d6: 0x000c, 0x1d7: 0x000c,
+ 0x1d8: 0x000c, 0x1d9: 0x000c, 0x1da: 0x000c, 0x1db: 0x000c, 0x1dc: 0x000c, 0x1dd: 0x000c,
+ 0x1de: 0x000c, 0x1df: 0x000c, 0x1e0: 0x000c, 0x1e1: 0x000c, 0x1e2: 0x000c, 0x1e3: 0x000c,
+ 0x1e4: 0x000c, 0x1e5: 0x000c, 0x1e6: 0x000c, 0x1e7: 0x000c, 0x1e8: 0x000c, 0x1e9: 0x000c,
+ 0x1ea: 0x000c, 0x1eb: 0x000c, 0x1ec: 0x000c, 0x1ed: 0x000c, 0x1ee: 0x000c, 0x1ef: 0x000c,
+ 0x1f0: 0x000c, 0x1f1: 0x000c, 0x1f2: 0x000c, 0x1f3: 0x000c, 0x1f4: 0x000c, 0x1f5: 0x000c,
+ 0x1f6: 0x000c, 0x1f7: 0x000c, 0x1f8: 0x000c, 0x1f9: 0x000c, 0x1fa: 0x000c, 0x1fb: 0x000c,
+ 0x1fc: 0x000c, 0x1fd: 0x000c, 0x1fe: 0x000c, 0x1ff: 0x000c,
+ // Block 0x8, offset 0x200
+ 0x200: 0x000c, 0x201: 0x000c, 0x202: 0x000c, 0x203: 0x000c, 0x204: 0x000c, 0x205: 0x000c,
+ 0x206: 0x000c, 0x207: 0x000c, 0x208: 0x000c, 0x209: 0x000c, 0x20a: 0x000c, 0x20b: 0x000c,
+ 0x20c: 0x000c, 0x20d: 0x000c, 0x20e: 0x000c, 0x20f: 0x000c, 0x210: 0x000c, 0x211: 0x000c,
+ 0x212: 0x000c, 0x213: 0x000c, 0x214: 0x000c, 0x215: 0x000c, 0x216: 0x000c, 0x217: 0x000c,
+ 0x218: 0x000c, 0x219: 0x000c, 0x21a: 0x000c, 0x21b: 0x000c, 0x21c: 0x000c, 0x21d: 0x000c,
+ 0x21e: 0x000c, 0x21f: 0x000c, 0x220: 0x000c, 0x221: 0x000c, 0x222: 0x000c, 0x223: 0x000c,
+ 0x224: 0x000c, 0x225: 0x000c, 0x226: 0x000c, 0x227: 0x000c, 0x228: 0x000c, 0x229: 0x000c,
+ 0x22a: 0x000c, 0x22b: 0x000c, 0x22c: 0x000c, 0x22d: 0x000c, 0x22e: 0x000c, 0x22f: 0x000c,
+ 0x234: 0x000a, 0x235: 0x000a,
+ 0x23e: 0x000a,
+ // Block 0x9, offset 0x240
+ 0x244: 0x000a, 0x245: 0x000a,
+ 0x247: 0x000a,
+ // Block 0xa, offset 0x280
+ 0x2b6: 0x000a,
+ // Block 0xb, offset 0x2c0
+ 0x2c3: 0x000c, 0x2c4: 0x000c, 0x2c5: 0x000c,
+ 0x2c6: 0x000c, 0x2c7: 0x000c, 0x2c8: 0x000c, 0x2c9: 0x000c,
+ // Block 0xc, offset 0x300
+ 0x30a: 0x000a,
+ 0x30d: 0x000a, 0x30e: 0x000a, 0x30f: 0x0004, 0x310: 0x0001, 0x311: 0x000c,
+ 0x312: 0x000c, 0x313: 0x000c, 0x314: 0x000c, 0x315: 0x000c, 0x316: 0x000c, 0x317: 0x000c,
+ 0x318: 0x000c, 0x319: 0x000c, 0x31a: 0x000c, 0x31b: 0x000c, 0x31c: 0x000c, 0x31d: 0x000c,
+ 0x31e: 0x000c, 0x31f: 0x000c, 0x320: 0x000c, 0x321: 0x000c, 0x322: 0x000c, 0x323: 0x000c,
+ 0x324: 0x000c, 0x325: 0x000c, 0x326: 0x000c, 0x327: 0x000c, 0x328: 0x000c, 0x329: 0x000c,
+ 0x32a: 0x000c, 0x32b: 0x000c, 0x32c: 0x000c, 0x32d: 0x000c, 0x32e: 0x000c, 0x32f: 0x000c,
+ 0x330: 0x000c, 0x331: 0x000c, 0x332: 0x000c, 0x333: 0x000c, 0x334: 0x000c, 0x335: 0x000c,
+ 0x336: 0x000c, 0x337: 0x000c, 0x338: 0x000c, 0x339: 0x000c, 0x33a: 0x000c, 0x33b: 0x000c,
+ 0x33c: 0x000c, 0x33d: 0x000c, 0x33e: 0x0001, 0x33f: 0x000c,
+ // Block 0xd, offset 0x340
+ 0x340: 0x0001, 0x341: 0x000c, 0x342: 0x000c, 0x343: 0x0001, 0x344: 0x000c, 0x345: 0x000c,
+ 0x346: 0x0001, 0x347: 0x000c, 0x348: 0x0001, 0x349: 0x0001, 0x34a: 0x0001, 0x34b: 0x0001,
+ 0x34c: 0x0001, 0x34d: 0x0001, 0x34e: 0x0001, 0x34f: 0x0001, 0x350: 0x0001, 0x351: 0x0001,
+ 0x352: 0x0001, 0x353: 0x0001, 0x354: 0x0001, 0x355: 0x0001, 0x356: 0x0001, 0x357: 0x0001,
+ 0x358: 0x0001, 0x359: 0x0001, 0x35a: 0x0001, 0x35b: 0x0001, 0x35c: 0x0001, 0x35d: 0x0001,
+ 0x35e: 0x0001, 0x35f: 0x0001, 0x360: 0x0001, 0x361: 0x0001, 0x362: 0x0001, 0x363: 0x0001,
+ 0x364: 0x0001, 0x365: 0x0001, 0x366: 0x0001, 0x367: 0x0001, 0x368: 0x0001, 0x369: 0x0001,
+ 0x36a: 0x0001, 0x36b: 0x0001, 0x36c: 0x0001, 0x36d: 0x0001, 0x36e: 0x0001, 0x36f: 0x0001,
+ 0x370: 0x0001, 0x371: 0x0001, 0x372: 0x0001, 0x373: 0x0001, 0x374: 0x0001, 0x375: 0x0001,
+ 0x376: 0x0001, 0x377: 0x0001, 0x378: 0x0001, 0x379: 0x0001, 0x37a: 0x0001, 0x37b: 0x0001,
+ 0x37c: 0x0001, 0x37d: 0x0001, 0x37e: 0x0001, 0x37f: 0x0001,
+ // Block 0xe, offset 0x380
+ 0x380: 0x0005, 0x381: 0x0005, 0x382: 0x0005, 0x383: 0x0005, 0x384: 0x0005, 0x385: 0x0005,
+ 0x386: 0x000a, 0x387: 0x000a, 0x388: 0x000d, 0x389: 0x0004, 0x38a: 0x0004, 0x38b: 0x000d,
+ 0x38c: 0x0006, 0x38d: 0x000d, 0x38e: 0x000a, 0x38f: 0x000a, 0x390: 0x000c, 0x391: 0x000c,
+ 0x392: 0x000c, 0x393: 0x000c, 0x394: 0x000c, 0x395: 0x000c, 0x396: 0x000c, 0x397: 0x000c,
+ 0x398: 0x000c, 0x399: 0x000c, 0x39a: 0x000c, 0x39b: 0x000d, 0x39c: 0x000d, 0x39d: 0x000d,
+ 0x39e: 0x000d, 0x39f: 0x000d, 0x3a0: 0x000d, 0x3a1: 0x000d, 0x3a2: 0x000d, 0x3a3: 0x000d,
+ 0x3a4: 0x000d, 0x3a5: 0x000d, 0x3a6: 0x000d, 0x3a7: 0x000d, 0x3a8: 0x000d, 0x3a9: 0x000d,
+ 0x3aa: 0x000d, 0x3ab: 0x000d, 0x3ac: 0x000d, 0x3ad: 0x000d, 0x3ae: 0x000d, 0x3af: 0x000d,
+ 0x3b0: 0x000d, 0x3b1: 0x000d, 0x3b2: 0x000d, 0x3b3: 0x000d, 0x3b4: 0x000d, 0x3b5: 0x000d,
+ 0x3b6: 0x000d, 0x3b7: 0x000d, 0x3b8: 0x000d, 0x3b9: 0x000d, 0x3ba: 0x000d, 0x3bb: 0x000d,
+ 0x3bc: 0x000d, 0x3bd: 0x000d, 0x3be: 0x000d, 0x3bf: 0x000d,
+ // Block 0xf, offset 0x3c0
+ 0x3c0: 0x000d, 0x3c1: 0x000d, 0x3c2: 0x000d, 0x3c3: 0x000d, 0x3c4: 0x000d, 0x3c5: 0x000d,
+ 0x3c6: 0x000d, 0x3c7: 0x000d, 0x3c8: 0x000d, 0x3c9: 0x000d, 0x3ca: 0x000d, 0x3cb: 0x000c,
+ 0x3cc: 0x000c, 0x3cd: 0x000c, 0x3ce: 0x000c, 0x3cf: 0x000c, 0x3d0: 0x000c, 0x3d1: 0x000c,
+ 0x3d2: 0x000c, 0x3d3: 0x000c, 0x3d4: 0x000c, 0x3d5: 0x000c, 0x3d6: 0x000c, 0x3d7: 0x000c,
+ 0x3d8: 0x000c, 0x3d9: 0x000c, 0x3da: 0x000c, 0x3db: 0x000c, 0x3dc: 0x000c, 0x3dd: 0x000c,
+ 0x3de: 0x000c, 0x3df: 0x000c, 0x3e0: 0x0005, 0x3e1: 0x0005, 0x3e2: 0x0005, 0x3e3: 0x0005,
+ 0x3e4: 0x0005, 0x3e5: 0x0005, 0x3e6: 0x0005, 0x3e7: 0x0005, 0x3e8: 0x0005, 0x3e9: 0x0005,
+ 0x3ea: 0x0004, 0x3eb: 0x0005, 0x3ec: 0x0005, 0x3ed: 0x000d, 0x3ee: 0x000d, 0x3ef: 0x000d,
+ 0x3f0: 0x000c, 0x3f1: 0x000d, 0x3f2: 0x000d, 0x3f3: 0x000d, 0x3f4: 0x000d, 0x3f5: 0x000d,
+ 0x3f6: 0x000d, 0x3f7: 0x000d, 0x3f8: 0x000d, 0x3f9: 0x000d, 0x3fa: 0x000d, 0x3fb: 0x000d,
+ 0x3fc: 0x000d, 0x3fd: 0x000d, 0x3fe: 0x000d, 0x3ff: 0x000d,
+ // Block 0x10, offset 0x400
+ 0x400: 0x000d, 0x401: 0x000d, 0x402: 0x000d, 0x403: 0x000d, 0x404: 0x000d, 0x405: 0x000d,
+ 0x406: 0x000d, 0x407: 0x000d, 0x408: 0x000d, 0x409: 0x000d, 0x40a: 0x000d, 0x40b: 0x000d,
+ 0x40c: 0x000d, 0x40d: 0x000d, 0x40e: 0x000d, 0x40f: 0x000d, 0x410: 0x000d, 0x411: 0x000d,
+ 0x412: 0x000d, 0x413: 0x000d, 0x414: 0x000d, 0x415: 0x000d, 0x416: 0x000d, 0x417: 0x000d,
+ 0x418: 0x000d, 0x419: 0x000d, 0x41a: 0x000d, 0x41b: 0x000d, 0x41c: 0x000d, 0x41d: 0x000d,
+ 0x41e: 0x000d, 0x41f: 0x000d, 0x420: 0x000d, 0x421: 0x000d, 0x422: 0x000d, 0x423: 0x000d,
+ 0x424: 0x000d, 0x425: 0x000d, 0x426: 0x000d, 0x427: 0x000d, 0x428: 0x000d, 0x429: 0x000d,
+ 0x42a: 0x000d, 0x42b: 0x000d, 0x42c: 0x000d, 0x42d: 0x000d, 0x42e: 0x000d, 0x42f: 0x000d,
+ 0x430: 0x000d, 0x431: 0x000d, 0x432: 0x000d, 0x433: 0x000d, 0x434: 0x000d, 0x435: 0x000d,
+ 0x436: 0x000d, 0x437: 0x000d, 0x438: 0x000d, 0x439: 0x000d, 0x43a: 0x000d, 0x43b: 0x000d,
+ 0x43c: 0x000d, 0x43d: 0x000d, 0x43e: 0x000d, 0x43f: 0x000d,
+ // Block 0x11, offset 0x440
+ 0x440: 0x000d, 0x441: 0x000d, 0x442: 0x000d, 0x443: 0x000d, 0x444: 0x000d, 0x445: 0x000d,
+ 0x446: 0x000d, 0x447: 0x000d, 0x448: 0x000d, 0x449: 0x000d, 0x44a: 0x000d, 0x44b: 0x000d,
+ 0x44c: 0x000d, 0x44d: 0x000d, 0x44e: 0x000d, 0x44f: 0x000d, 0x450: 0x000d, 0x451: 0x000d,
+ 0x452: 0x000d, 0x453: 0x000d, 0x454: 0x000d, 0x455: 0x000d, 0x456: 0x000c, 0x457: 0x000c,
+ 0x458: 0x000c, 0x459: 0x000c, 0x45a: 0x000c, 0x45b: 0x000c, 0x45c: 0x000c, 0x45d: 0x0005,
+ 0x45e: 0x000a, 0x45f: 0x000c, 0x460: 0x000c, 0x461: 0x000c, 0x462: 0x000c, 0x463: 0x000c,
+ 0x464: 0x000c, 0x465: 0x000d, 0x466: 0x000d, 0x467: 0x000c, 0x468: 0x000c, 0x469: 0x000a,
+ 0x46a: 0x000c, 0x46b: 0x000c, 0x46c: 0x000c, 0x46d: 0x000c, 0x46e: 0x000d, 0x46f: 0x000d,
+ 0x470: 0x0002, 0x471: 0x0002, 0x472: 0x0002, 0x473: 0x0002, 0x474: 0x0002, 0x475: 0x0002,
+ 0x476: 0x0002, 0x477: 0x0002, 0x478: 0x0002, 0x479: 0x0002, 0x47a: 0x000d, 0x47b: 0x000d,
+ 0x47c: 0x000d, 0x47d: 0x000d, 0x47e: 0x000d, 0x47f: 0x000d,
+ // Block 0x12, offset 0x480
+ 0x480: 0x000d, 0x481: 0x000d, 0x482: 0x000d, 0x483: 0x000d, 0x484: 0x000d, 0x485: 0x000d,
+ 0x486: 0x000d, 0x487: 0x000d, 0x488: 0x000d, 0x489: 0x000d, 0x48a: 0x000d, 0x48b: 0x000d,
+ 0x48c: 0x000d, 0x48d: 0x000d, 0x48e: 0x000d, 0x48f: 0x000d, 0x490: 0x000d, 0x491: 0x000c,
+ 0x492: 0x000d, 0x493: 0x000d, 0x494: 0x000d, 0x495: 0x000d, 0x496: 0x000d, 0x497: 0x000d,
+ 0x498: 0x000d, 0x499: 0x000d, 0x49a: 0x000d, 0x49b: 0x000d, 0x49c: 0x000d, 0x49d: 0x000d,
+ 0x49e: 0x000d, 0x49f: 0x000d, 0x4a0: 0x000d, 0x4a1: 0x000d, 0x4a2: 0x000d, 0x4a3: 0x000d,
+ 0x4a4: 0x000d, 0x4a5: 0x000d, 0x4a6: 0x000d, 0x4a7: 0x000d, 0x4a8: 0x000d, 0x4a9: 0x000d,
+ 0x4aa: 0x000d, 0x4ab: 0x000d, 0x4ac: 0x000d, 0x4ad: 0x000d, 0x4ae: 0x000d, 0x4af: 0x000d,
+ 0x4b0: 0x000c, 0x4b1: 0x000c, 0x4b2: 0x000c, 0x4b3: 0x000c, 0x4b4: 0x000c, 0x4b5: 0x000c,
+ 0x4b6: 0x000c, 0x4b7: 0x000c, 0x4b8: 0x000c, 0x4b9: 0x000c, 0x4ba: 0x000c, 0x4bb: 0x000c,
+ 0x4bc: 0x000c, 0x4bd: 0x000c, 0x4be: 0x000c, 0x4bf: 0x000c,
+ // Block 0x13, offset 0x4c0
+ 0x4c0: 0x000c, 0x4c1: 0x000c, 0x4c2: 0x000c, 0x4c3: 0x000c, 0x4c4: 0x000c, 0x4c5: 0x000c,
+ 0x4c6: 0x000c, 0x4c7: 0x000c, 0x4c8: 0x000c, 0x4c9: 0x000c, 0x4ca: 0x000c, 0x4cb: 0x000d,
+ 0x4cc: 0x000d, 0x4cd: 0x000d, 0x4ce: 0x000d, 0x4cf: 0x000d, 0x4d0: 0x000d, 0x4d1: 0x000d,
+ 0x4d2: 0x000d, 0x4d3: 0x000d, 0x4d4: 0x000d, 0x4d5: 0x000d, 0x4d6: 0x000d, 0x4d7: 0x000d,
+ 0x4d8: 0x000d, 0x4d9: 0x000d, 0x4da: 0x000d, 0x4db: 0x000d, 0x4dc: 0x000d, 0x4dd: 0x000d,
+ 0x4de: 0x000d, 0x4df: 0x000d, 0x4e0: 0x000d, 0x4e1: 0x000d, 0x4e2: 0x000d, 0x4e3: 0x000d,
+ 0x4e4: 0x000d, 0x4e5: 0x000d, 0x4e6: 0x000d, 0x4e7: 0x000d, 0x4e8: 0x000d, 0x4e9: 0x000d,
+ 0x4ea: 0x000d, 0x4eb: 0x000d, 0x4ec: 0x000d, 0x4ed: 0x000d, 0x4ee: 0x000d, 0x4ef: 0x000d,
+ 0x4f0: 0x000d, 0x4f1: 0x000d, 0x4f2: 0x000d, 0x4f3: 0x000d, 0x4f4: 0x000d, 0x4f5: 0x000d,
+ 0x4f6: 0x000d, 0x4f7: 0x000d, 0x4f8: 0x000d, 0x4f9: 0x000d, 0x4fa: 0x000d, 0x4fb: 0x000d,
+ 0x4fc: 0x000d, 0x4fd: 0x000d, 0x4fe: 0x000d, 0x4ff: 0x000d,
+ // Block 0x14, offset 0x500
+ 0x500: 0x000d, 0x501: 0x000d, 0x502: 0x000d, 0x503: 0x000d, 0x504: 0x000d, 0x505: 0x000d,
+ 0x506: 0x000d, 0x507: 0x000d, 0x508: 0x000d, 0x509: 0x000d, 0x50a: 0x000d, 0x50b: 0x000d,
+ 0x50c: 0x000d, 0x50d: 0x000d, 0x50e: 0x000d, 0x50f: 0x000d, 0x510: 0x000d, 0x511: 0x000d,
+ 0x512: 0x000d, 0x513: 0x000d, 0x514: 0x000d, 0x515: 0x000d, 0x516: 0x000d, 0x517: 0x000d,
+ 0x518: 0x000d, 0x519: 0x000d, 0x51a: 0x000d, 0x51b: 0x000d, 0x51c: 0x000d, 0x51d: 0x000d,
+ 0x51e: 0x000d, 0x51f: 0x000d, 0x520: 0x000d, 0x521: 0x000d, 0x522: 0x000d, 0x523: 0x000d,
+ 0x524: 0x000d, 0x525: 0x000d, 0x526: 0x000c, 0x527: 0x000c, 0x528: 0x000c, 0x529: 0x000c,
+ 0x52a: 0x000c, 0x52b: 0x000c, 0x52c: 0x000c, 0x52d: 0x000c, 0x52e: 0x000c, 0x52f: 0x000c,
+ 0x530: 0x000c, 0x531: 0x000d, 0x532: 0x000d, 0x533: 0x000d, 0x534: 0x000d, 0x535: 0x000d,
+ 0x536: 0x000d, 0x537: 0x000d, 0x538: 0x000d, 0x539: 0x000d, 0x53a: 0x000d, 0x53b: 0x000d,
+ 0x53c: 0x000d, 0x53d: 0x000d, 0x53e: 0x000d, 0x53f: 0x000d,
+ // Block 0x15, offset 0x540
+ 0x540: 0x0001, 0x541: 0x0001, 0x542: 0x0001, 0x543: 0x0001, 0x544: 0x0001, 0x545: 0x0001,
+ 0x546: 0x0001, 0x547: 0x0001, 0x548: 0x0001, 0x549: 0x0001, 0x54a: 0x0001, 0x54b: 0x0001,
+ 0x54c: 0x0001, 0x54d: 0x0001, 0x54e: 0x0001, 0x54f: 0x0001, 0x550: 0x0001, 0x551: 0x0001,
+ 0x552: 0x0001, 0x553: 0x0001, 0x554: 0x0001, 0x555: 0x0001, 0x556: 0x0001, 0x557: 0x0001,
+ 0x558: 0x0001, 0x559: 0x0001, 0x55a: 0x0001, 0x55b: 0x0001, 0x55c: 0x0001, 0x55d: 0x0001,
+ 0x55e: 0x0001, 0x55f: 0x0001, 0x560: 0x0001, 0x561: 0x0001, 0x562: 0x0001, 0x563: 0x0001,
+ 0x564: 0x0001, 0x565: 0x0001, 0x566: 0x0001, 0x567: 0x0001, 0x568: 0x0001, 0x569: 0x0001,
+ 0x56a: 0x0001, 0x56b: 0x000c, 0x56c: 0x000c, 0x56d: 0x000c, 0x56e: 0x000c, 0x56f: 0x000c,
+ 0x570: 0x000c, 0x571: 0x000c, 0x572: 0x000c, 0x573: 0x000c, 0x574: 0x0001, 0x575: 0x0001,
+ 0x576: 0x000a, 0x577: 0x000a, 0x578: 0x000a, 0x579: 0x000a, 0x57a: 0x0001, 0x57b: 0x0001,
+ 0x57c: 0x0001, 0x57d: 0x000c, 0x57e: 0x0001, 0x57f: 0x0001,
+ // Block 0x16, offset 0x580
+ 0x580: 0x0001, 0x581: 0x0001, 0x582: 0x0001, 0x583: 0x0001, 0x584: 0x0001, 0x585: 0x0001,
+ 0x586: 0x0001, 0x587: 0x0001, 0x588: 0x0001, 0x589: 0x0001, 0x58a: 0x0001, 0x58b: 0x0001,
+ 0x58c: 0x0001, 0x58d: 0x0001, 0x58e: 0x0001, 0x58f: 0x0001, 0x590: 0x0001, 0x591: 0x0001,
+ 0x592: 0x0001, 0x593: 0x0001, 0x594: 0x0001, 0x595: 0x0001, 0x596: 0x000c, 0x597: 0x000c,
+ 0x598: 0x000c, 0x599: 0x000c, 0x59a: 0x0001, 0x59b: 0x000c, 0x59c: 0x000c, 0x59d: 0x000c,
+ 0x59e: 0x000c, 0x59f: 0x000c, 0x5a0: 0x000c, 0x5a1: 0x000c, 0x5a2: 0x000c, 0x5a3: 0x000c,
+ 0x5a4: 0x0001, 0x5a5: 0x000c, 0x5a6: 0x000c, 0x5a7: 0x000c, 0x5a8: 0x0001, 0x5a9: 0x000c,
+ 0x5aa: 0x000c, 0x5ab: 0x000c, 0x5ac: 0x000c, 0x5ad: 0x000c, 0x5ae: 0x0001, 0x5af: 0x0001,
+ 0x5b0: 0x0001, 0x5b1: 0x0001, 0x5b2: 0x0001, 0x5b3: 0x0001, 0x5b4: 0x0001, 0x5b5: 0x0001,
+ 0x5b6: 0x0001, 0x5b7: 0x0001, 0x5b8: 0x0001, 0x5b9: 0x0001, 0x5ba: 0x0001, 0x5bb: 0x0001,
+ 0x5bc: 0x0001, 0x5bd: 0x0001, 0x5be: 0x0001, 0x5bf: 0x0001,
+ // Block 0x17, offset 0x5c0
+ 0x5c0: 0x0001, 0x5c1: 0x0001, 0x5c2: 0x0001, 0x5c3: 0x0001, 0x5c4: 0x0001, 0x5c5: 0x0001,
+ 0x5c6: 0x0001, 0x5c7: 0x0001, 0x5c8: 0x0001, 0x5c9: 0x0001, 0x5ca: 0x0001, 0x5cb: 0x0001,
+ 0x5cc: 0x0001, 0x5cd: 0x0001, 0x5ce: 0x0001, 0x5cf: 0x0001, 0x5d0: 0x0001, 0x5d1: 0x0001,
+ 0x5d2: 0x0001, 0x5d3: 0x0001, 0x5d4: 0x0001, 0x5d5: 0x0001, 0x5d6: 0x0001, 0x5d7: 0x0001,
+ 0x5d8: 0x0001, 0x5d9: 0x000c, 0x5da: 0x000c, 0x5db: 0x000c, 0x5dc: 0x0001, 0x5dd: 0x0001,
+ 0x5de: 0x0001, 0x5df: 0x0001, 0x5e0: 0x000d, 0x5e1: 0x000d, 0x5e2: 0x000d, 0x5e3: 0x000d,
+ 0x5e4: 0x000d, 0x5e5: 0x000d, 0x5e6: 0x000d, 0x5e7: 0x000d, 0x5e8: 0x000d, 0x5e9: 0x000d,
+ 0x5ea: 0x000d, 0x5eb: 0x000d, 0x5ec: 0x000d, 0x5ed: 0x000d, 0x5ee: 0x000d, 0x5ef: 0x000d,
+ 0x5f0: 0x0001, 0x5f1: 0x0001, 0x5f2: 0x0001, 0x5f3: 0x0001, 0x5f4: 0x0001, 0x5f5: 0x0001,
+ 0x5f6: 0x0001, 0x5f7: 0x0001, 0x5f8: 0x0001, 0x5f9: 0x0001, 0x5fa: 0x0001, 0x5fb: 0x0001,
+ 0x5fc: 0x0001, 0x5fd: 0x0001, 0x5fe: 0x0001, 0x5ff: 0x0001,
+ // Block 0x18, offset 0x600
+ 0x600: 0x0001, 0x601: 0x0001, 0x602: 0x0001, 0x603: 0x0001, 0x604: 0x0001, 0x605: 0x0001,
+ 0x606: 0x0001, 0x607: 0x0001, 0x608: 0x0001, 0x609: 0x0001, 0x60a: 0x0001, 0x60b: 0x0001,
+ 0x60c: 0x0001, 0x60d: 0x0001, 0x60e: 0x0001, 0x60f: 0x0001, 0x610: 0x0001, 0x611: 0x0001,
+ 0x612: 0x0001, 0x613: 0x0001, 0x614: 0x0001, 0x615: 0x0001, 0x616: 0x0001, 0x617: 0x0001,
+ 0x618: 0x0001, 0x619: 0x0001, 0x61a: 0x0001, 0x61b: 0x0001, 0x61c: 0x0001, 0x61d: 0x0001,
+ 0x61e: 0x0001, 0x61f: 0x0001, 0x620: 0x000d, 0x621: 0x000d, 0x622: 0x000d, 0x623: 0x000d,
+ 0x624: 0x000d, 0x625: 0x000d, 0x626: 0x000d, 0x627: 0x000d, 0x628: 0x000d, 0x629: 0x000d,
+ 0x62a: 0x000d, 0x62b: 0x000d, 0x62c: 0x000d, 0x62d: 0x000d, 0x62e: 0x000d, 0x62f: 0x000d,
+ 0x630: 0x000d, 0x631: 0x000d, 0x632: 0x000d, 0x633: 0x000d, 0x634: 0x000d, 0x635: 0x000d,
+ 0x636: 0x000d, 0x637: 0x000d, 0x638: 0x000d, 0x639: 0x000d, 0x63a: 0x000d, 0x63b: 0x000d,
+ 0x63c: 0x000d, 0x63d: 0x000d, 0x63e: 0x000d, 0x63f: 0x000d,
+ // Block 0x19, offset 0x640
+ 0x640: 0x000d, 0x641: 0x000d, 0x642: 0x000d, 0x643: 0x000d, 0x644: 0x000d, 0x645: 0x000d,
+ 0x646: 0x000d, 0x647: 0x000d, 0x648: 0x000d, 0x649: 0x000d, 0x64a: 0x000d, 0x64b: 0x000d,
+ 0x64c: 0x000d, 0x64d: 0x000d, 0x64e: 0x000d, 0x64f: 0x000d, 0x650: 0x000d, 0x651: 0x000d,
+ 0x652: 0x000d, 0x653: 0x000c, 0x654: 0x000c, 0x655: 0x000c, 0x656: 0x000c, 0x657: 0x000c,
+ 0x658: 0x000c, 0x659: 0x000c, 0x65a: 0x000c, 0x65b: 0x000c, 0x65c: 0x000c, 0x65d: 0x000c,
+ 0x65e: 0x000c, 0x65f: 0x000c, 0x660: 0x000c, 0x661: 0x000c, 0x662: 0x0005, 0x663: 0x000c,
+ 0x664: 0x000c, 0x665: 0x000c, 0x666: 0x000c, 0x667: 0x000c, 0x668: 0x000c, 0x669: 0x000c,
+ 0x66a: 0x000c, 0x66b: 0x000c, 0x66c: 0x000c, 0x66d: 0x000c, 0x66e: 0x000c, 0x66f: 0x000c,
+ 0x670: 0x000c, 0x671: 0x000c, 0x672: 0x000c, 0x673: 0x000c, 0x674: 0x000c, 0x675: 0x000c,
+ 0x676: 0x000c, 0x677: 0x000c, 0x678: 0x000c, 0x679: 0x000c, 0x67a: 0x000c, 0x67b: 0x000c,
+ 0x67c: 0x000c, 0x67d: 0x000c, 0x67e: 0x000c, 0x67f: 0x000c,
+ // Block 0x1a, offset 0x680
+ 0x680: 0x000c, 0x681: 0x000c, 0x682: 0x000c,
+ 0x6ba: 0x000c,
+ 0x6bc: 0x000c,
+ // Block 0x1b, offset 0x6c0
+ 0x6c1: 0x000c, 0x6c2: 0x000c, 0x6c3: 0x000c, 0x6c4: 0x000c, 0x6c5: 0x000c,
+ 0x6c6: 0x000c, 0x6c7: 0x000c, 0x6c8: 0x000c,
+ 0x6cd: 0x000c, 0x6d1: 0x000c,
+ 0x6d2: 0x000c, 0x6d3: 0x000c, 0x6d4: 0x000c, 0x6d5: 0x000c, 0x6d6: 0x000c, 0x6d7: 0x000c,
+ 0x6e2: 0x000c, 0x6e3: 0x000c,
+ // Block 0x1c, offset 0x700
+ 0x701: 0x000c,
+ 0x73c: 0x000c,
+ // Block 0x1d, offset 0x740
+ 0x741: 0x000c, 0x742: 0x000c, 0x743: 0x000c, 0x744: 0x000c,
+ 0x74d: 0x000c,
+ 0x762: 0x000c, 0x763: 0x000c,
+ 0x772: 0x0004, 0x773: 0x0004,
+ 0x77b: 0x0004,
+ 0x77e: 0x000c,
+ // Block 0x1e, offset 0x780
+ 0x781: 0x000c, 0x782: 0x000c,
+ 0x7bc: 0x000c,
+ // Block 0x1f, offset 0x7c0
+ 0x7c1: 0x000c, 0x7c2: 0x000c,
+ 0x7c7: 0x000c, 0x7c8: 0x000c, 0x7cb: 0x000c,
+ 0x7cc: 0x000c, 0x7cd: 0x000c, 0x7d1: 0x000c,
+ 0x7f0: 0x000c, 0x7f1: 0x000c, 0x7f5: 0x000c,
+ // Block 0x20, offset 0x800
+ 0x801: 0x000c, 0x802: 0x000c, 0x803: 0x000c, 0x804: 0x000c, 0x805: 0x000c,
+ 0x807: 0x000c, 0x808: 0x000c,
+ 0x80d: 0x000c,
+ 0x822: 0x000c, 0x823: 0x000c,
+ 0x831: 0x0004,
+ 0x83a: 0x000c, 0x83b: 0x000c,
+ 0x83c: 0x000c, 0x83d: 0x000c, 0x83e: 0x000c, 0x83f: 0x000c,
+ // Block 0x21, offset 0x840
+ 0x841: 0x000c,
+ 0x87c: 0x000c, 0x87f: 0x000c,
+ // Block 0x22, offset 0x880
+ 0x881: 0x000c, 0x882: 0x000c, 0x883: 0x000c, 0x884: 0x000c,
+ 0x88d: 0x000c,
+ 0x895: 0x000c, 0x896: 0x000c,
+ 0x8a2: 0x000c, 0x8a3: 0x000c,
+ // Block 0x23, offset 0x8c0
+ 0x8c2: 0x000c,
+ // Block 0x24, offset 0x900
+ 0x900: 0x000c,
+ 0x90d: 0x000c,
+ 0x933: 0x000a, 0x934: 0x000a, 0x935: 0x000a,
+ 0x936: 0x000a, 0x937: 0x000a, 0x938: 0x000a, 0x939: 0x0004, 0x93a: 0x000a,
+ // Block 0x25, offset 0x940
+ 0x940: 0x000c, 0x944: 0x000c,
+ 0x97e: 0x000c, 0x97f: 0x000c,
+ // Block 0x26, offset 0x980
+ 0x980: 0x000c,
+ 0x986: 0x000c, 0x987: 0x000c, 0x988: 0x000c, 0x98a: 0x000c, 0x98b: 0x000c,
+ 0x98c: 0x000c, 0x98d: 0x000c,
+ 0x995: 0x000c, 0x996: 0x000c,
+ 0x9a2: 0x000c, 0x9a3: 0x000c,
+ 0x9b8: 0x000a, 0x9b9: 0x000a, 0x9ba: 0x000a, 0x9bb: 0x000a,
+ 0x9bc: 0x000a, 0x9bd: 0x000a, 0x9be: 0x000a,
+ // Block 0x27, offset 0x9c0
+ 0x9cc: 0x000c, 0x9cd: 0x000c,
+ 0x9e2: 0x000c, 0x9e3: 0x000c,
+ // Block 0x28, offset 0xa00
+ 0xa00: 0x000c, 0xa01: 0x000c,
+ 0xa3b: 0x000c,
+ 0xa3c: 0x000c,
+ // Block 0x29, offset 0xa40
+ 0xa41: 0x000c, 0xa42: 0x000c, 0xa43: 0x000c, 0xa44: 0x000c,
+ 0xa4d: 0x000c,
+ 0xa62: 0x000c, 0xa63: 0x000c,
+ // Block 0x2a, offset 0xa80
+ 0xa81: 0x000c,
+ // Block 0x2b, offset 0xac0
+ 0xaca: 0x000c,
+ 0xad2: 0x000c, 0xad3: 0x000c, 0xad4: 0x000c, 0xad6: 0x000c,
+ // Block 0x2c, offset 0xb00
+ 0xb31: 0x000c, 0xb34: 0x000c, 0xb35: 0x000c,
+ 0xb36: 0x000c, 0xb37: 0x000c, 0xb38: 0x000c, 0xb39: 0x000c, 0xb3a: 0x000c,
+ 0xb3f: 0x0004,
+ // Block 0x2d, offset 0xb40
+ 0xb47: 0x000c, 0xb48: 0x000c, 0xb49: 0x000c, 0xb4a: 0x000c, 0xb4b: 0x000c,
+ 0xb4c: 0x000c, 0xb4d: 0x000c, 0xb4e: 0x000c,
+ // Block 0x2e, offset 0xb80
+ 0xbb1: 0x000c, 0xbb4: 0x000c, 0xbb5: 0x000c,
+ 0xbb6: 0x000c, 0xbb7: 0x000c, 0xbb8: 0x000c, 0xbb9: 0x000c, 0xbba: 0x000c, 0xbbb: 0x000c,
+ 0xbbc: 0x000c,
+ // Block 0x2f, offset 0xbc0
+ 0xbc8: 0x000c, 0xbc9: 0x000c, 0xbca: 0x000c, 0xbcb: 0x000c,
+ 0xbcc: 0x000c, 0xbcd: 0x000c,
+ // Block 0x30, offset 0xc00
+ 0xc18: 0x000c, 0xc19: 0x000c,
+ 0xc35: 0x000c,
+ 0xc37: 0x000c, 0xc39: 0x000c, 0xc3a: 0x003a, 0xc3b: 0x002a,
+ 0xc3c: 0x003a, 0xc3d: 0x002a,
+ // Block 0x31, offset 0xc40
+ 0xc71: 0x000c, 0xc72: 0x000c, 0xc73: 0x000c, 0xc74: 0x000c, 0xc75: 0x000c,
+ 0xc76: 0x000c, 0xc77: 0x000c, 0xc78: 0x000c, 0xc79: 0x000c, 0xc7a: 0x000c, 0xc7b: 0x000c,
+ 0xc7c: 0x000c, 0xc7d: 0x000c, 0xc7e: 0x000c,
+ // Block 0x32, offset 0xc80
+ 0xc80: 0x000c, 0xc81: 0x000c, 0xc82: 0x000c, 0xc83: 0x000c, 0xc84: 0x000c,
+ 0xc86: 0x000c, 0xc87: 0x000c,
+ 0xc8d: 0x000c, 0xc8e: 0x000c, 0xc8f: 0x000c, 0xc90: 0x000c, 0xc91: 0x000c,
+ 0xc92: 0x000c, 0xc93: 0x000c, 0xc94: 0x000c, 0xc95: 0x000c, 0xc96: 0x000c, 0xc97: 0x000c,
+ 0xc99: 0x000c, 0xc9a: 0x000c, 0xc9b: 0x000c, 0xc9c: 0x000c, 0xc9d: 0x000c,
+ 0xc9e: 0x000c, 0xc9f: 0x000c, 0xca0: 0x000c, 0xca1: 0x000c, 0xca2: 0x000c, 0xca3: 0x000c,
+ 0xca4: 0x000c, 0xca5: 0x000c, 0xca6: 0x000c, 0xca7: 0x000c, 0xca8: 0x000c, 0xca9: 0x000c,
+ 0xcaa: 0x000c, 0xcab: 0x000c, 0xcac: 0x000c, 0xcad: 0x000c, 0xcae: 0x000c, 0xcaf: 0x000c,
+ 0xcb0: 0x000c, 0xcb1: 0x000c, 0xcb2: 0x000c, 0xcb3: 0x000c, 0xcb4: 0x000c, 0xcb5: 0x000c,
+ 0xcb6: 0x000c, 0xcb7: 0x000c, 0xcb8: 0x000c, 0xcb9: 0x000c, 0xcba: 0x000c, 0xcbb: 0x000c,
+ 0xcbc: 0x000c,
+ // Block 0x33, offset 0xcc0
+ 0xcc6: 0x000c,
+ // Block 0x34, offset 0xd00
+ 0xd2d: 0x000c, 0xd2e: 0x000c, 0xd2f: 0x000c,
+ 0xd30: 0x000c, 0xd32: 0x000c, 0xd33: 0x000c, 0xd34: 0x000c, 0xd35: 0x000c,
+ 0xd36: 0x000c, 0xd37: 0x000c, 0xd39: 0x000c, 0xd3a: 0x000c,
+ 0xd3d: 0x000c, 0xd3e: 0x000c,
+ // Block 0x35, offset 0xd40
+ 0xd58: 0x000c, 0xd59: 0x000c,
+ 0xd5e: 0x000c, 0xd5f: 0x000c, 0xd60: 0x000c,
+ 0xd71: 0x000c, 0xd72: 0x000c, 0xd73: 0x000c, 0xd74: 0x000c,
+ // Block 0x36, offset 0xd80
+ 0xd82: 0x000c, 0xd85: 0x000c,
+ 0xd86: 0x000c,
+ 0xd8d: 0x000c,
+ 0xd9d: 0x000c,
+ // Block 0x37, offset 0xdc0
+ 0xddd: 0x000c,
+ 0xdde: 0x000c, 0xddf: 0x000c,
+ // Block 0x38, offset 0xe00
+ 0xe10: 0x000a, 0xe11: 0x000a,
+ 0xe12: 0x000a, 0xe13: 0x000a, 0xe14: 0x000a, 0xe15: 0x000a, 0xe16: 0x000a, 0xe17: 0x000a,
+ 0xe18: 0x000a, 0xe19: 0x000a,
+ // Block 0x39, offset 0xe40
+ 0xe40: 0x000a,
+ // Block 0x3a, offset 0xe80
+ 0xe80: 0x0009,
+ 0xe9b: 0x007a, 0xe9c: 0x006a,
+ // Block 0x3b, offset 0xec0
+ 0xed2: 0x000c, 0xed3: 0x000c, 0xed4: 0x000c,
+ 0xef2: 0x000c, 0xef3: 0x000c, 0xef4: 0x000c,
+ // Block 0x3c, offset 0xf00
+ 0xf12: 0x000c, 0xf13: 0x000c,
+ 0xf32: 0x000c, 0xf33: 0x000c,
+ // Block 0x3d, offset 0xf40
+ 0xf74: 0x000c, 0xf75: 0x000c,
+ 0xf77: 0x000c, 0xf78: 0x000c, 0xf79: 0x000c, 0xf7a: 0x000c, 0xf7b: 0x000c,
+ 0xf7c: 0x000c, 0xf7d: 0x000c,
+ // Block 0x3e, offset 0xf80
+ 0xf86: 0x000c, 0xf89: 0x000c, 0xf8a: 0x000c, 0xf8b: 0x000c,
+ 0xf8c: 0x000c, 0xf8d: 0x000c, 0xf8e: 0x000c, 0xf8f: 0x000c, 0xf90: 0x000c, 0xf91: 0x000c,
+ 0xf92: 0x000c, 0xf93: 0x000c,
+ 0xf9b: 0x0004, 0xf9d: 0x000c,
+ 0xfb0: 0x000a, 0xfb1: 0x000a, 0xfb2: 0x000a, 0xfb3: 0x000a, 0xfb4: 0x000a, 0xfb5: 0x000a,
+ 0xfb6: 0x000a, 0xfb7: 0x000a, 0xfb8: 0x000a, 0xfb9: 0x000a,
+ // Block 0x3f, offset 0xfc0
+ 0xfc0: 0x000a, 0xfc1: 0x000a, 0xfc2: 0x000a, 0xfc3: 0x000a, 0xfc4: 0x000a, 0xfc5: 0x000a,
+ 0xfc6: 0x000a, 0xfc7: 0x000a, 0xfc8: 0x000a, 0xfc9: 0x000a, 0xfca: 0x000a, 0xfcb: 0x000c,
+ 0xfcc: 0x000c, 0xfcd: 0x000c, 0xfce: 0x000b,
+ // Block 0x40, offset 0x1000
+ 0x1005: 0x000c,
+ 0x1006: 0x000c,
+ 0x1029: 0x000c,
+ // Block 0x41, offset 0x1040
+ 0x1060: 0x000c, 0x1061: 0x000c, 0x1062: 0x000c,
+ 0x1067: 0x000c, 0x1068: 0x000c,
+ 0x1072: 0x000c,
+ 0x1079: 0x000c, 0x107a: 0x000c, 0x107b: 0x000c,
+ // Block 0x42, offset 0x1080
+ 0x1080: 0x000a, 0x1084: 0x000a, 0x1085: 0x000a,
+ // Block 0x43, offset 0x10c0
+ 0x10de: 0x000a, 0x10df: 0x000a, 0x10e0: 0x000a, 0x10e1: 0x000a, 0x10e2: 0x000a, 0x10e3: 0x000a,
+ 0x10e4: 0x000a, 0x10e5: 0x000a, 0x10e6: 0x000a, 0x10e7: 0x000a, 0x10e8: 0x000a, 0x10e9: 0x000a,
+ 0x10ea: 0x000a, 0x10eb: 0x000a, 0x10ec: 0x000a, 0x10ed: 0x000a, 0x10ee: 0x000a, 0x10ef: 0x000a,
+ 0x10f0: 0x000a, 0x10f1: 0x000a, 0x10f2: 0x000a, 0x10f3: 0x000a, 0x10f4: 0x000a, 0x10f5: 0x000a,
+ 0x10f6: 0x000a, 0x10f7: 0x000a, 0x10f8: 0x000a, 0x10f9: 0x000a, 0x10fa: 0x000a, 0x10fb: 0x000a,
+ 0x10fc: 0x000a, 0x10fd: 0x000a, 0x10fe: 0x000a, 0x10ff: 0x000a,
+ // Block 0x44, offset 0x1100
+ 0x1117: 0x000c,
+ 0x1118: 0x000c, 0x111b: 0x000c,
+ // Block 0x45, offset 0x1140
+ 0x1156: 0x000c,
+ 0x1158: 0x000c, 0x1159: 0x000c, 0x115a: 0x000c, 0x115b: 0x000c, 0x115c: 0x000c, 0x115d: 0x000c,
+ 0x115e: 0x000c, 0x1160: 0x000c, 0x1162: 0x000c,
+ 0x1165: 0x000c, 0x1166: 0x000c, 0x1167: 0x000c, 0x1168: 0x000c, 0x1169: 0x000c,
+ 0x116a: 0x000c, 0x116b: 0x000c, 0x116c: 0x000c,
+ 0x1173: 0x000c, 0x1174: 0x000c, 0x1175: 0x000c,
+ 0x1176: 0x000c, 0x1177: 0x000c, 0x1178: 0x000c, 0x1179: 0x000c, 0x117a: 0x000c, 0x117b: 0x000c,
+ 0x117c: 0x000c, 0x117f: 0x000c,
+ // Block 0x46, offset 0x1180
+ 0x11b0: 0x000c, 0x11b1: 0x000c, 0x11b2: 0x000c, 0x11b3: 0x000c, 0x11b4: 0x000c, 0x11b5: 0x000c,
+ 0x11b6: 0x000c, 0x11b7: 0x000c, 0x11b8: 0x000c, 0x11b9: 0x000c, 0x11ba: 0x000c, 0x11bb: 0x000c,
+ 0x11bc: 0x000c, 0x11bd: 0x000c, 0x11be: 0x000c, 0x11bf: 0x000c,
+ // Block 0x47, offset 0x11c0
+ 0x11c0: 0x000c,
+ // Block 0x48, offset 0x1200
+ 0x1200: 0x000c, 0x1201: 0x000c, 0x1202: 0x000c, 0x1203: 0x000c,
+ 0x1234: 0x000c,
+ 0x1236: 0x000c, 0x1237: 0x000c, 0x1238: 0x000c, 0x1239: 0x000c, 0x123a: 0x000c,
+ 0x123c: 0x000c,
+ // Block 0x49, offset 0x1240
+ 0x1242: 0x000c,
+ 0x126b: 0x000c, 0x126c: 0x000c, 0x126d: 0x000c, 0x126e: 0x000c, 0x126f: 0x000c,
+ 0x1270: 0x000c, 0x1271: 0x000c, 0x1272: 0x000c, 0x1273: 0x000c,
+ // Block 0x4a, offset 0x1280
+ 0x1280: 0x000c, 0x1281: 0x000c,
+ 0x12a2: 0x000c, 0x12a3: 0x000c,
+ 0x12a4: 0x000c, 0x12a5: 0x000c, 0x12a8: 0x000c, 0x12a9: 0x000c,
+ 0x12ab: 0x000c, 0x12ac: 0x000c, 0x12ad: 0x000c,
+ // Block 0x4b, offset 0x12c0
+ 0x12e6: 0x000c, 0x12e8: 0x000c, 0x12e9: 0x000c,
+ 0x12ed: 0x000c, 0x12ef: 0x000c,
+ 0x12f0: 0x000c, 0x12f1: 0x000c,
+ // Block 0x4c, offset 0x1300
+ 0x132c: 0x000c, 0x132d: 0x000c, 0x132e: 0x000c, 0x132f: 0x000c,
+ 0x1330: 0x000c, 0x1331: 0x000c, 0x1332: 0x000c, 0x1333: 0x000c,
+ 0x1336: 0x000c, 0x1337: 0x000c,
+ // Block 0x4d, offset 0x1340
+ 0x1350: 0x000c, 0x1351: 0x000c,
+ 0x1352: 0x000c, 0x1354: 0x000c, 0x1355: 0x000c, 0x1356: 0x000c, 0x1357: 0x000c,
+ 0x1358: 0x000c, 0x1359: 0x000c, 0x135a: 0x000c, 0x135b: 0x000c, 0x135c: 0x000c, 0x135d: 0x000c,
+ 0x135e: 0x000c, 0x135f: 0x000c, 0x1360: 0x000c, 0x1362: 0x000c, 0x1363: 0x000c,
+ 0x1364: 0x000c, 0x1365: 0x000c, 0x1366: 0x000c, 0x1367: 0x000c, 0x1368: 0x000c,
+ 0x136d: 0x000c,
+ 0x1374: 0x000c,
+ 0x1378: 0x000c, 0x1379: 0x000c,
+ // Block 0x4e, offset 0x1380
+ 0x1380: 0x000c, 0x1381: 0x000c, 0x1382: 0x000c, 0x1383: 0x000c, 0x1384: 0x000c, 0x1385: 0x000c,
+ 0x1386: 0x000c, 0x1387: 0x000c, 0x1388: 0x000c, 0x1389: 0x000c, 0x138a: 0x000c, 0x138b: 0x000c,
+ 0x138c: 0x000c, 0x138d: 0x000c, 0x138e: 0x000c, 0x138f: 0x000c, 0x1390: 0x000c, 0x1391: 0x000c,
+ 0x1392: 0x000c, 0x1393: 0x000c, 0x1394: 0x000c, 0x1395: 0x000c, 0x1396: 0x000c, 0x1397: 0x000c,
+ 0x1398: 0x000c, 0x1399: 0x000c, 0x139a: 0x000c, 0x139b: 0x000c, 0x139c: 0x000c, 0x139d: 0x000c,
+ 0x139e: 0x000c, 0x139f: 0x000c, 0x13a0: 0x000c, 0x13a1: 0x000c, 0x13a2: 0x000c, 0x13a3: 0x000c,
+ 0x13a4: 0x000c, 0x13a5: 0x000c, 0x13a6: 0x000c, 0x13a7: 0x000c, 0x13a8: 0x000c, 0x13a9: 0x000c,
+ 0x13aa: 0x000c, 0x13ab: 0x000c, 0x13ac: 0x000c, 0x13ad: 0x000c, 0x13ae: 0x000c, 0x13af: 0x000c,
+ 0x13b0: 0x000c, 0x13b1: 0x000c, 0x13b2: 0x000c, 0x13b3: 0x000c, 0x13b4: 0x000c, 0x13b5: 0x000c,
+ 0x13b6: 0x000c, 0x13b7: 0x000c, 0x13b8: 0x000c, 0x13b9: 0x000c, 0x13bb: 0x000c,
+ 0x13bc: 0x000c, 0x13bd: 0x000c, 0x13be: 0x000c, 0x13bf: 0x000c,
+ // Block 0x4f, offset 0x13c0
+ 0x13fd: 0x000a, 0x13ff: 0x000a,
+ // Block 0x50, offset 0x1400
+ 0x1400: 0x000a, 0x1401: 0x000a,
+ 0x140d: 0x000a, 0x140e: 0x000a, 0x140f: 0x000a,
+ 0x141d: 0x000a,
+ 0x141e: 0x000a, 0x141f: 0x000a,
+ 0x142d: 0x000a, 0x142e: 0x000a, 0x142f: 0x000a,
+ 0x143d: 0x000a, 0x143e: 0x000a,
+ // Block 0x51, offset 0x1440
+ 0x1440: 0x0009, 0x1441: 0x0009, 0x1442: 0x0009, 0x1443: 0x0009, 0x1444: 0x0009, 0x1445: 0x0009,
+ 0x1446: 0x0009, 0x1447: 0x0009, 0x1448: 0x0009, 0x1449: 0x0009, 0x144a: 0x0009, 0x144b: 0x000b,
+ 0x144c: 0x000b, 0x144d: 0x000b, 0x144f: 0x0001, 0x1450: 0x000a, 0x1451: 0x000a,
+ 0x1452: 0x000a, 0x1453: 0x000a, 0x1454: 0x000a, 0x1455: 0x000a, 0x1456: 0x000a, 0x1457: 0x000a,
+ 0x1458: 0x000a, 0x1459: 0x000a, 0x145a: 0x000a, 0x145b: 0x000a, 0x145c: 0x000a, 0x145d: 0x000a,
+ 0x145e: 0x000a, 0x145f: 0x000a, 0x1460: 0x000a, 0x1461: 0x000a, 0x1462: 0x000a, 0x1463: 0x000a,
+ 0x1464: 0x000a, 0x1465: 0x000a, 0x1466: 0x000a, 0x1467: 0x000a, 0x1468: 0x0009, 0x1469: 0x0007,
+ 0x146a: 0x000e, 0x146b: 0x000e, 0x146c: 0x000e, 0x146d: 0x000e, 0x146e: 0x000e, 0x146f: 0x0006,
+ 0x1470: 0x0004, 0x1471: 0x0004, 0x1472: 0x0004, 0x1473: 0x0004, 0x1474: 0x0004, 0x1475: 0x000a,
+ 0x1476: 0x000a, 0x1477: 0x000a, 0x1478: 0x000a, 0x1479: 0x000a, 0x147a: 0x000a, 0x147b: 0x000a,
+ 0x147c: 0x000a, 0x147d: 0x000a, 0x147e: 0x000a, 0x147f: 0x000a,
+ // Block 0x52, offset 0x1480
+ 0x1480: 0x000a, 0x1481: 0x000a, 0x1482: 0x000a, 0x1483: 0x000a, 0x1484: 0x0006, 0x1485: 0x009a,
+ 0x1486: 0x008a, 0x1487: 0x000a, 0x1488: 0x000a, 0x1489: 0x000a, 0x148a: 0x000a, 0x148b: 0x000a,
+ 0x148c: 0x000a, 0x148d: 0x000a, 0x148e: 0x000a, 0x148f: 0x000a, 0x1490: 0x000a, 0x1491: 0x000a,
+ 0x1492: 0x000a, 0x1493: 0x000a, 0x1494: 0x000a, 0x1495: 0x000a, 0x1496: 0x000a, 0x1497: 0x000a,
+ 0x1498: 0x000a, 0x1499: 0x000a, 0x149a: 0x000a, 0x149b: 0x000a, 0x149c: 0x000a, 0x149d: 0x000a,
+ 0x149e: 0x000a, 0x149f: 0x0009, 0x14a0: 0x000b, 0x14a1: 0x000b, 0x14a2: 0x000b, 0x14a3: 0x000b,
+ 0x14a4: 0x000b, 0x14a5: 0x000b, 0x14a6: 0x000e, 0x14a7: 0x000e, 0x14a8: 0x000e, 0x14a9: 0x000e,
+ 0x14aa: 0x000b, 0x14ab: 0x000b, 0x14ac: 0x000b, 0x14ad: 0x000b, 0x14ae: 0x000b, 0x14af: 0x000b,
+ 0x14b0: 0x0002, 0x14b4: 0x0002, 0x14b5: 0x0002,
+ 0x14b6: 0x0002, 0x14b7: 0x0002, 0x14b8: 0x0002, 0x14b9: 0x0002, 0x14ba: 0x0003, 0x14bb: 0x0003,
+ 0x14bc: 0x000a, 0x14bd: 0x009a, 0x14be: 0x008a,
+ // Block 0x53, offset 0x14c0
+ 0x14c0: 0x0002, 0x14c1: 0x0002, 0x14c2: 0x0002, 0x14c3: 0x0002, 0x14c4: 0x0002, 0x14c5: 0x0002,
+ 0x14c6: 0x0002, 0x14c7: 0x0002, 0x14c8: 0x0002, 0x14c9: 0x0002, 0x14ca: 0x0003, 0x14cb: 0x0003,
+ 0x14cc: 0x000a, 0x14cd: 0x009a, 0x14ce: 0x008a,
+ 0x14e0: 0x0004, 0x14e1: 0x0004, 0x14e2: 0x0004, 0x14e3: 0x0004,
+ 0x14e4: 0x0004, 0x14e5: 0x0004, 0x14e6: 0x0004, 0x14e7: 0x0004, 0x14e8: 0x0004, 0x14e9: 0x0004,
+ 0x14ea: 0x0004, 0x14eb: 0x0004, 0x14ec: 0x0004, 0x14ed: 0x0004, 0x14ee: 0x0004, 0x14ef: 0x0004,
+ 0x14f0: 0x0004, 0x14f1: 0x0004, 0x14f2: 0x0004, 0x14f3: 0x0004, 0x14f4: 0x0004, 0x14f5: 0x0004,
+ 0x14f6: 0x0004, 0x14f7: 0x0004, 0x14f8: 0x0004, 0x14f9: 0x0004, 0x14fa: 0x0004, 0x14fb: 0x0004,
+ 0x14fc: 0x0004, 0x14fd: 0x0004, 0x14fe: 0x0004, 0x14ff: 0x0004,
+ // Block 0x54, offset 0x1500
+ 0x1500: 0x0004, 0x1501: 0x0004, 0x1502: 0x0004, 0x1503: 0x0004, 0x1504: 0x0004, 0x1505: 0x0004,
+ 0x1506: 0x0004, 0x1507: 0x0004, 0x1508: 0x0004, 0x1509: 0x0004, 0x150a: 0x0004, 0x150b: 0x0004,
+ 0x150c: 0x0004, 0x150d: 0x0004, 0x150e: 0x0004, 0x150f: 0x0004, 0x1510: 0x000c, 0x1511: 0x000c,
+ 0x1512: 0x000c, 0x1513: 0x000c, 0x1514: 0x000c, 0x1515: 0x000c, 0x1516: 0x000c, 0x1517: 0x000c,
+ 0x1518: 0x000c, 0x1519: 0x000c, 0x151a: 0x000c, 0x151b: 0x000c, 0x151c: 0x000c, 0x151d: 0x000c,
+ 0x151e: 0x000c, 0x151f: 0x000c, 0x1520: 0x000c, 0x1521: 0x000c, 0x1522: 0x000c, 0x1523: 0x000c,
+ 0x1524: 0x000c, 0x1525: 0x000c, 0x1526: 0x000c, 0x1527: 0x000c, 0x1528: 0x000c, 0x1529: 0x000c,
+ 0x152a: 0x000c, 0x152b: 0x000c, 0x152c: 0x000c, 0x152d: 0x000c, 0x152e: 0x000c, 0x152f: 0x000c,
+ 0x1530: 0x000c,
+ // Block 0x55, offset 0x1540
+ 0x1540: 0x000a, 0x1541: 0x000a, 0x1543: 0x000a, 0x1544: 0x000a, 0x1545: 0x000a,
+ 0x1546: 0x000a, 0x1548: 0x000a, 0x1549: 0x000a,
+ 0x1554: 0x000a, 0x1556: 0x000a, 0x1557: 0x000a,
+ 0x1558: 0x000a,
+ 0x155e: 0x000a, 0x155f: 0x000a, 0x1560: 0x000a, 0x1561: 0x000a, 0x1562: 0x000a, 0x1563: 0x000a,
+ 0x1565: 0x000a, 0x1567: 0x000a, 0x1569: 0x000a,
+ 0x156e: 0x0004,
+ 0x157a: 0x000a, 0x157b: 0x000a,
+ // Block 0x56, offset 0x1580
+ 0x1580: 0x000a, 0x1581: 0x000a, 0x1582: 0x000a, 0x1583: 0x000a, 0x1584: 0x000a,
+ 0x158a: 0x000a, 0x158b: 0x000a,
+ 0x158c: 0x000a, 0x158d: 0x000a, 0x1590: 0x000a, 0x1591: 0x000a,
+ 0x1592: 0x000a, 0x1593: 0x000a, 0x1594: 0x000a, 0x1595: 0x000a, 0x1596: 0x000a, 0x1597: 0x000a,
+ 0x1598: 0x000a, 0x1599: 0x000a, 0x159a: 0x000a, 0x159b: 0x000a, 0x159c: 0x000a, 0x159d: 0x000a,
+ 0x159e: 0x000a, 0x159f: 0x000a,
+ // Block 0x57, offset 0x15c0
+ 0x15c9: 0x000a, 0x15ca: 0x000a, 0x15cb: 0x000a,
+ 0x15d0: 0x000a, 0x15d1: 0x000a,
+ 0x15d2: 0x000a, 0x15d3: 0x000a, 0x15d4: 0x000a, 0x15d5: 0x000a, 0x15d6: 0x000a, 0x15d7: 0x000a,
+ 0x15d8: 0x000a, 0x15d9: 0x000a, 0x15da: 0x000a, 0x15db: 0x000a, 0x15dc: 0x000a, 0x15dd: 0x000a,
+ 0x15de: 0x000a, 0x15df: 0x000a, 0x15e0: 0x000a, 0x15e1: 0x000a, 0x15e2: 0x000a, 0x15e3: 0x000a,
+ 0x15e4: 0x000a, 0x15e5: 0x000a, 0x15e6: 0x000a, 0x15e7: 0x000a, 0x15e8: 0x000a, 0x15e9: 0x000a,
+ 0x15ea: 0x000a, 0x15eb: 0x000a, 0x15ec: 0x000a, 0x15ed: 0x000a, 0x15ee: 0x000a, 0x15ef: 0x000a,
+ 0x15f0: 0x000a, 0x15f1: 0x000a, 0x15f2: 0x000a, 0x15f3: 0x000a, 0x15f4: 0x000a, 0x15f5: 0x000a,
+ 0x15f6: 0x000a, 0x15f7: 0x000a, 0x15f8: 0x000a, 0x15f9: 0x000a, 0x15fa: 0x000a, 0x15fb: 0x000a,
+ 0x15fc: 0x000a, 0x15fd: 0x000a, 0x15fe: 0x000a, 0x15ff: 0x000a,
+ // Block 0x58, offset 0x1600
+ 0x1600: 0x000a, 0x1601: 0x000a, 0x1602: 0x000a, 0x1603: 0x000a, 0x1604: 0x000a, 0x1605: 0x000a,
+ 0x1606: 0x000a, 0x1607: 0x000a, 0x1608: 0x000a, 0x1609: 0x000a, 0x160a: 0x000a, 0x160b: 0x000a,
+ 0x160c: 0x000a, 0x160d: 0x000a, 0x160e: 0x000a, 0x160f: 0x000a, 0x1610: 0x000a, 0x1611: 0x000a,
+ 0x1612: 0x000a, 0x1613: 0x000a, 0x1614: 0x000a, 0x1615: 0x000a, 0x1616: 0x000a, 0x1617: 0x000a,
+ 0x1618: 0x000a, 0x1619: 0x000a, 0x161a: 0x000a, 0x161b: 0x000a, 0x161c: 0x000a, 0x161d: 0x000a,
+ 0x161e: 0x000a, 0x161f: 0x000a, 0x1620: 0x000a, 0x1621: 0x000a, 0x1622: 0x000a, 0x1623: 0x000a,
+ 0x1624: 0x000a, 0x1625: 0x000a, 0x1626: 0x000a, 0x1627: 0x000a, 0x1628: 0x000a, 0x1629: 0x000a,
+ 0x162a: 0x000a, 0x162b: 0x000a, 0x162c: 0x000a, 0x162d: 0x000a, 0x162e: 0x000a, 0x162f: 0x000a,
+ 0x1630: 0x000a, 0x1631: 0x000a, 0x1632: 0x000a, 0x1633: 0x000a, 0x1634: 0x000a, 0x1635: 0x000a,
+ 0x1636: 0x000a, 0x1637: 0x000a, 0x1638: 0x000a, 0x1639: 0x000a, 0x163a: 0x000a, 0x163b: 0x000a,
+ 0x163c: 0x000a, 0x163d: 0x000a, 0x163e: 0x000a, 0x163f: 0x000a,
+ // Block 0x59, offset 0x1640
+ 0x1640: 0x000a, 0x1641: 0x000a, 0x1642: 0x000a, 0x1643: 0x000a, 0x1644: 0x000a, 0x1645: 0x000a,
+ 0x1646: 0x000a, 0x1647: 0x000a, 0x1648: 0x000a, 0x1649: 0x000a, 0x164a: 0x000a, 0x164b: 0x000a,
+ 0x164c: 0x000a, 0x164d: 0x000a, 0x164e: 0x000a, 0x164f: 0x000a, 0x1650: 0x000a, 0x1651: 0x000a,
+ 0x1652: 0x0003, 0x1653: 0x0004, 0x1654: 0x000a, 0x1655: 0x000a, 0x1656: 0x000a, 0x1657: 0x000a,
+ 0x1658: 0x000a, 0x1659: 0x000a, 0x165a: 0x000a, 0x165b: 0x000a, 0x165c: 0x000a, 0x165d: 0x000a,
+ 0x165e: 0x000a, 0x165f: 0x000a, 0x1660: 0x000a, 0x1661: 0x000a, 0x1662: 0x000a, 0x1663: 0x000a,
+ 0x1664: 0x000a, 0x1665: 0x000a, 0x1666: 0x000a, 0x1667: 0x000a, 0x1668: 0x000a, 0x1669: 0x000a,
+ 0x166a: 0x000a, 0x166b: 0x000a, 0x166c: 0x000a, 0x166d: 0x000a, 0x166e: 0x000a, 0x166f: 0x000a,
+ 0x1670: 0x000a, 0x1671: 0x000a, 0x1672: 0x000a, 0x1673: 0x000a, 0x1674: 0x000a, 0x1675: 0x000a,
+ 0x1676: 0x000a, 0x1677: 0x000a, 0x1678: 0x000a, 0x1679: 0x000a, 0x167a: 0x000a, 0x167b: 0x000a,
+ 0x167c: 0x000a, 0x167d: 0x000a, 0x167e: 0x000a, 0x167f: 0x000a,
+ // Block 0x5a, offset 0x1680
+ 0x1680: 0x000a, 0x1681: 0x000a, 0x1682: 0x000a, 0x1683: 0x000a, 0x1684: 0x000a, 0x1685: 0x000a,
+ 0x1686: 0x000a, 0x1687: 0x000a, 0x1688: 0x003a, 0x1689: 0x002a, 0x168a: 0x003a, 0x168b: 0x002a,
+ 0x168c: 0x000a, 0x168d: 0x000a, 0x168e: 0x000a, 0x168f: 0x000a, 0x1690: 0x000a, 0x1691: 0x000a,
+ 0x1692: 0x000a, 0x1693: 0x000a, 0x1694: 0x000a, 0x1695: 0x000a, 0x1696: 0x000a, 0x1697: 0x000a,
+ 0x1698: 0x000a, 0x1699: 0x000a, 0x169a: 0x000a, 0x169b: 0x000a, 0x169c: 0x000a, 0x169d: 0x000a,
+ 0x169e: 0x000a, 0x169f: 0x000a, 0x16a0: 0x000a, 0x16a1: 0x000a, 0x16a2: 0x000a, 0x16a3: 0x000a,
+ 0x16a4: 0x000a, 0x16a5: 0x000a, 0x16a6: 0x000a, 0x16a7: 0x000a, 0x16a8: 0x000a, 0x16a9: 0x009a,
+ 0x16aa: 0x008a, 0x16ab: 0x000a, 0x16ac: 0x000a, 0x16ad: 0x000a, 0x16ae: 0x000a, 0x16af: 0x000a,
+ 0x16b0: 0x000a, 0x16b1: 0x000a, 0x16b2: 0x000a, 0x16b3: 0x000a, 0x16b4: 0x000a, 0x16b5: 0x000a,
+ // Block 0x5b, offset 0x16c0
+ 0x16fb: 0x000a,
+ 0x16fc: 0x000a, 0x16fd: 0x000a, 0x16fe: 0x000a, 0x16ff: 0x000a,
+ // Block 0x5c, offset 0x1700
+ 0x1700: 0x000a, 0x1701: 0x000a, 0x1702: 0x000a, 0x1703: 0x000a, 0x1704: 0x000a, 0x1705: 0x000a,
+ 0x1706: 0x000a, 0x1707: 0x000a, 0x1708: 0x000a, 0x1709: 0x000a, 0x170a: 0x000a, 0x170b: 0x000a,
+ 0x170c: 0x000a, 0x170d: 0x000a, 0x170e: 0x000a, 0x170f: 0x000a, 0x1710: 0x000a, 0x1711: 0x000a,
+ 0x1712: 0x000a, 0x1713: 0x000a, 0x1714: 0x000a, 0x1716: 0x000a, 0x1717: 0x000a,
+ 0x1718: 0x000a, 0x1719: 0x000a, 0x171a: 0x000a, 0x171b: 0x000a, 0x171c: 0x000a, 0x171d: 0x000a,
+ 0x171e: 0x000a, 0x171f: 0x000a, 0x1720: 0x000a, 0x1721: 0x000a, 0x1722: 0x000a, 0x1723: 0x000a,
+ 0x1724: 0x000a, 0x1725: 0x000a, 0x1726: 0x000a, 0x1727: 0x000a, 0x1728: 0x000a, 0x1729: 0x000a,
+ 0x172a: 0x000a, 0x172b: 0x000a, 0x172c: 0x000a, 0x172d: 0x000a, 0x172e: 0x000a, 0x172f: 0x000a,
+ 0x1730: 0x000a, 0x1731: 0x000a, 0x1732: 0x000a, 0x1733: 0x000a, 0x1734: 0x000a, 0x1735: 0x000a,
+ 0x1736: 0x000a, 0x1737: 0x000a, 0x1738: 0x000a, 0x1739: 0x000a, 0x173a: 0x000a, 0x173b: 0x000a,
+ 0x173c: 0x000a, 0x173d: 0x000a, 0x173e: 0x000a, 0x173f: 0x000a,
+ // Block 0x5d, offset 0x1740
+ 0x1740: 0x000a, 0x1741: 0x000a, 0x1742: 0x000a, 0x1743: 0x000a, 0x1744: 0x000a, 0x1745: 0x000a,
+ 0x1746: 0x000a, 0x1747: 0x000a, 0x1748: 0x000a, 0x1749: 0x000a, 0x174a: 0x000a, 0x174b: 0x000a,
+ 0x174c: 0x000a, 0x174d: 0x000a, 0x174e: 0x000a, 0x174f: 0x000a, 0x1750: 0x000a, 0x1751: 0x000a,
+ 0x1752: 0x000a, 0x1753: 0x000a, 0x1754: 0x000a, 0x1755: 0x000a, 0x1756: 0x000a, 0x1757: 0x000a,
+ 0x1758: 0x000a, 0x1759: 0x000a, 0x175a: 0x000a, 0x175b: 0x000a, 0x175c: 0x000a, 0x175d: 0x000a,
+ 0x175e: 0x000a, 0x175f: 0x000a, 0x1760: 0x000a, 0x1761: 0x000a, 0x1762: 0x000a, 0x1763: 0x000a,
+ 0x1764: 0x000a, 0x1765: 0x000a, 0x1766: 0x000a,
+ // Block 0x5e, offset 0x1780
+ 0x1780: 0x000a, 0x1781: 0x000a, 0x1782: 0x000a, 0x1783: 0x000a, 0x1784: 0x000a, 0x1785: 0x000a,
+ 0x1786: 0x000a, 0x1787: 0x000a, 0x1788: 0x000a, 0x1789: 0x000a, 0x178a: 0x000a,
+ 0x17a0: 0x000a, 0x17a1: 0x000a, 0x17a2: 0x000a, 0x17a3: 0x000a,
+ 0x17a4: 0x000a, 0x17a5: 0x000a, 0x17a6: 0x000a, 0x17a7: 0x000a, 0x17a8: 0x000a, 0x17a9: 0x000a,
+ 0x17aa: 0x000a, 0x17ab: 0x000a, 0x17ac: 0x000a, 0x17ad: 0x000a, 0x17ae: 0x000a, 0x17af: 0x000a,
+ 0x17b0: 0x000a, 0x17b1: 0x000a, 0x17b2: 0x000a, 0x17b3: 0x000a, 0x17b4: 0x000a, 0x17b5: 0x000a,
+ 0x17b6: 0x000a, 0x17b7: 0x000a, 0x17b8: 0x000a, 0x17b9: 0x000a, 0x17ba: 0x000a, 0x17bb: 0x000a,
+ 0x17bc: 0x000a, 0x17bd: 0x000a, 0x17be: 0x000a, 0x17bf: 0x000a,
+ // Block 0x5f, offset 0x17c0
+ 0x17c0: 0x000a, 0x17c1: 0x000a, 0x17c2: 0x000a, 0x17c3: 0x000a, 0x17c4: 0x000a, 0x17c5: 0x000a,
+ 0x17c6: 0x000a, 0x17c7: 0x000a, 0x17c8: 0x0002, 0x17c9: 0x0002, 0x17ca: 0x0002, 0x17cb: 0x0002,
+ 0x17cc: 0x0002, 0x17cd: 0x0002, 0x17ce: 0x0002, 0x17cf: 0x0002, 0x17d0: 0x0002, 0x17d1: 0x0002,
+ 0x17d2: 0x0002, 0x17d3: 0x0002, 0x17d4: 0x0002, 0x17d5: 0x0002, 0x17d6: 0x0002, 0x17d7: 0x0002,
+ 0x17d8: 0x0002, 0x17d9: 0x0002, 0x17da: 0x0002, 0x17db: 0x0002,
+ // Block 0x60, offset 0x1800
+ 0x182a: 0x000a, 0x182b: 0x000a, 0x182c: 0x000a, 0x182d: 0x000a, 0x182e: 0x000a, 0x182f: 0x000a,
+ 0x1830: 0x000a, 0x1831: 0x000a, 0x1832: 0x000a, 0x1833: 0x000a, 0x1834: 0x000a, 0x1835: 0x000a,
+ 0x1836: 0x000a, 0x1837: 0x000a, 0x1838: 0x000a, 0x1839: 0x000a, 0x183a: 0x000a, 0x183b: 0x000a,
+ 0x183c: 0x000a, 0x183d: 0x000a, 0x183e: 0x000a, 0x183f: 0x000a,
+ // Block 0x61, offset 0x1840
+ 0x1840: 0x000a, 0x1841: 0x000a, 0x1842: 0x000a, 0x1843: 0x000a, 0x1844: 0x000a, 0x1845: 0x000a,
+ 0x1846: 0x000a, 0x1847: 0x000a, 0x1848: 0x000a, 0x1849: 0x000a, 0x184a: 0x000a, 0x184b: 0x000a,
+ 0x184c: 0x000a, 0x184d: 0x000a, 0x184e: 0x000a, 0x184f: 0x000a, 0x1850: 0x000a, 0x1851: 0x000a,
+ 0x1852: 0x000a, 0x1853: 0x000a, 0x1854: 0x000a, 0x1855: 0x000a, 0x1856: 0x000a, 0x1857: 0x000a,
+ 0x1858: 0x000a, 0x1859: 0x000a, 0x185a: 0x000a, 0x185b: 0x000a, 0x185c: 0x000a, 0x185d: 0x000a,
+ 0x185e: 0x000a, 0x185f: 0x000a, 0x1860: 0x000a, 0x1861: 0x000a, 0x1862: 0x000a, 0x1863: 0x000a,
+ 0x1864: 0x000a, 0x1865: 0x000a, 0x1866: 0x000a, 0x1867: 0x000a, 0x1868: 0x000a, 0x1869: 0x000a,
+ 0x186a: 0x000a, 0x186b: 0x000a, 0x186d: 0x000a, 0x186e: 0x000a, 0x186f: 0x000a,
+ 0x1870: 0x000a, 0x1871: 0x000a, 0x1872: 0x000a, 0x1873: 0x000a, 0x1874: 0x000a, 0x1875: 0x000a,
+ 0x1876: 0x000a, 0x1877: 0x000a, 0x1878: 0x000a, 0x1879: 0x000a, 0x187a: 0x000a, 0x187b: 0x000a,
+ 0x187c: 0x000a, 0x187d: 0x000a, 0x187e: 0x000a, 0x187f: 0x000a,
+ // Block 0x62, offset 0x1880
+ 0x1880: 0x000a, 0x1881: 0x000a, 0x1882: 0x000a, 0x1883: 0x000a, 0x1884: 0x000a, 0x1885: 0x000a,
+ 0x1886: 0x000a, 0x1887: 0x000a, 0x1888: 0x000a, 0x1889: 0x000a, 0x188a: 0x000a, 0x188b: 0x000a,
+ 0x188c: 0x000a, 0x188d: 0x000a, 0x188e: 0x000a, 0x188f: 0x000a, 0x1890: 0x000a, 0x1891: 0x000a,
+ 0x1892: 0x000a, 0x1893: 0x000a, 0x1894: 0x000a, 0x1895: 0x000a, 0x1896: 0x000a, 0x1897: 0x000a,
+ 0x1898: 0x000a, 0x1899: 0x000a, 0x189a: 0x000a, 0x189b: 0x000a, 0x189c: 0x000a, 0x189d: 0x000a,
+ 0x189e: 0x000a, 0x189f: 0x000a, 0x18a0: 0x000a, 0x18a1: 0x000a, 0x18a2: 0x000a, 0x18a3: 0x000a,
+ 0x18a4: 0x000a, 0x18a5: 0x000a, 0x18a6: 0x000a, 0x18a7: 0x000a, 0x18a8: 0x003a, 0x18a9: 0x002a,
+ 0x18aa: 0x003a, 0x18ab: 0x002a, 0x18ac: 0x003a, 0x18ad: 0x002a, 0x18ae: 0x003a, 0x18af: 0x002a,
+ 0x18b0: 0x003a, 0x18b1: 0x002a, 0x18b2: 0x003a, 0x18b3: 0x002a, 0x18b4: 0x003a, 0x18b5: 0x002a,
+ 0x18b6: 0x000a, 0x18b7: 0x000a, 0x18b8: 0x000a, 0x18b9: 0x000a, 0x18ba: 0x000a, 0x18bb: 0x000a,
+ 0x18bc: 0x000a, 0x18bd: 0x000a, 0x18be: 0x000a, 0x18bf: 0x000a,
+ // Block 0x63, offset 0x18c0
+ 0x18c0: 0x000a, 0x18c1: 0x000a, 0x18c2: 0x000a, 0x18c3: 0x000a, 0x18c4: 0x000a, 0x18c5: 0x009a,
+ 0x18c6: 0x008a, 0x18c7: 0x000a, 0x18c8: 0x000a, 0x18c9: 0x000a, 0x18ca: 0x000a, 0x18cb: 0x000a,
+ 0x18cc: 0x000a, 0x18cd: 0x000a, 0x18ce: 0x000a, 0x18cf: 0x000a, 0x18d0: 0x000a, 0x18d1: 0x000a,
+ 0x18d2: 0x000a, 0x18d3: 0x000a, 0x18d4: 0x000a, 0x18d5: 0x000a, 0x18d6: 0x000a, 0x18d7: 0x000a,
+ 0x18d8: 0x000a, 0x18d9: 0x000a, 0x18da: 0x000a, 0x18db: 0x000a, 0x18dc: 0x000a, 0x18dd: 0x000a,
+ 0x18de: 0x000a, 0x18df: 0x000a, 0x18e0: 0x000a, 0x18e1: 0x000a, 0x18e2: 0x000a, 0x18e3: 0x000a,
+ 0x18e4: 0x000a, 0x18e5: 0x000a, 0x18e6: 0x003a, 0x18e7: 0x002a, 0x18e8: 0x003a, 0x18e9: 0x002a,
+ 0x18ea: 0x003a, 0x18eb: 0x002a, 0x18ec: 0x003a, 0x18ed: 0x002a, 0x18ee: 0x003a, 0x18ef: 0x002a,
+ 0x18f0: 0x000a, 0x18f1: 0x000a, 0x18f2: 0x000a, 0x18f3: 0x000a, 0x18f4: 0x000a, 0x18f5: 0x000a,
+ 0x18f6: 0x000a, 0x18f7: 0x000a, 0x18f8: 0x000a, 0x18f9: 0x000a, 0x18fa: 0x000a, 0x18fb: 0x000a,
+ 0x18fc: 0x000a, 0x18fd: 0x000a, 0x18fe: 0x000a, 0x18ff: 0x000a,
+ // Block 0x64, offset 0x1900
+ 0x1900: 0x000a, 0x1901: 0x000a, 0x1902: 0x000a, 0x1903: 0x007a, 0x1904: 0x006a, 0x1905: 0x009a,
+ 0x1906: 0x008a, 0x1907: 0x00ba, 0x1908: 0x00aa, 0x1909: 0x009a, 0x190a: 0x008a, 0x190b: 0x007a,
+ 0x190c: 0x006a, 0x190d: 0x00da, 0x190e: 0x002a, 0x190f: 0x003a, 0x1910: 0x00ca, 0x1911: 0x009a,
+ 0x1912: 0x008a, 0x1913: 0x007a, 0x1914: 0x006a, 0x1915: 0x009a, 0x1916: 0x008a, 0x1917: 0x00ba,
+ 0x1918: 0x00aa, 0x1919: 0x000a, 0x191a: 0x000a, 0x191b: 0x000a, 0x191c: 0x000a, 0x191d: 0x000a,
+ 0x191e: 0x000a, 0x191f: 0x000a, 0x1920: 0x000a, 0x1921: 0x000a, 0x1922: 0x000a, 0x1923: 0x000a,
+ 0x1924: 0x000a, 0x1925: 0x000a, 0x1926: 0x000a, 0x1927: 0x000a, 0x1928: 0x000a, 0x1929: 0x000a,
+ 0x192a: 0x000a, 0x192b: 0x000a, 0x192c: 0x000a, 0x192d: 0x000a, 0x192e: 0x000a, 0x192f: 0x000a,
+ 0x1930: 0x000a, 0x1931: 0x000a, 0x1932: 0x000a, 0x1933: 0x000a, 0x1934: 0x000a, 0x1935: 0x000a,
+ 0x1936: 0x000a, 0x1937: 0x000a, 0x1938: 0x000a, 0x1939: 0x000a, 0x193a: 0x000a, 0x193b: 0x000a,
+ 0x193c: 0x000a, 0x193d: 0x000a, 0x193e: 0x000a, 0x193f: 0x000a,
+ // Block 0x65, offset 0x1940
+ 0x1940: 0x000a, 0x1941: 0x000a, 0x1942: 0x000a, 0x1943: 0x000a, 0x1944: 0x000a, 0x1945: 0x000a,
+ 0x1946: 0x000a, 0x1947: 0x000a, 0x1948: 0x000a, 0x1949: 0x000a, 0x194a: 0x000a, 0x194b: 0x000a,
+ 0x194c: 0x000a, 0x194d: 0x000a, 0x194e: 0x000a, 0x194f: 0x000a, 0x1950: 0x000a, 0x1951: 0x000a,
+ 0x1952: 0x000a, 0x1953: 0x000a, 0x1954: 0x000a, 0x1955: 0x000a, 0x1956: 0x000a, 0x1957: 0x000a,
+ 0x1958: 0x003a, 0x1959: 0x002a, 0x195a: 0x003a, 0x195b: 0x002a, 0x195c: 0x000a, 0x195d: 0x000a,
+ 0x195e: 0x000a, 0x195f: 0x000a, 0x1960: 0x000a, 0x1961: 0x000a, 0x1962: 0x000a, 0x1963: 0x000a,
+ 0x1964: 0x000a, 0x1965: 0x000a, 0x1966: 0x000a, 0x1967: 0x000a, 0x1968: 0x000a, 0x1969: 0x000a,
+ 0x196a: 0x000a, 0x196b: 0x000a, 0x196c: 0x000a, 0x196d: 0x000a, 0x196e: 0x000a, 0x196f: 0x000a,
+ 0x1970: 0x000a, 0x1971: 0x000a, 0x1972: 0x000a, 0x1973: 0x000a, 0x1974: 0x000a, 0x1975: 0x000a,
+ 0x1976: 0x000a, 0x1977: 0x000a, 0x1978: 0x000a, 0x1979: 0x000a, 0x197a: 0x000a, 0x197b: 0x000a,
+ 0x197c: 0x003a, 0x197d: 0x002a, 0x197e: 0x000a, 0x197f: 0x000a,
+ // Block 0x66, offset 0x1980
+ 0x1980: 0x000a, 0x1981: 0x000a, 0x1982: 0x000a, 0x1983: 0x000a, 0x1984: 0x000a, 0x1985: 0x000a,
+ 0x1986: 0x000a, 0x1987: 0x000a, 0x1988: 0x000a, 0x1989: 0x000a, 0x198a: 0x000a, 0x198b: 0x000a,
+ 0x198c: 0x000a, 0x198d: 0x000a, 0x198e: 0x000a, 0x198f: 0x000a, 0x1990: 0x000a, 0x1991: 0x000a,
+ 0x1992: 0x000a, 0x1993: 0x000a, 0x1994: 0x000a, 0x1995: 0x000a, 0x1996: 0x000a, 0x1997: 0x000a,
+ 0x1998: 0x000a, 0x1999: 0x000a, 0x199a: 0x000a, 0x199b: 0x000a, 0x199c: 0x000a, 0x199d: 0x000a,
+ 0x199e: 0x000a, 0x199f: 0x000a, 0x19a0: 0x000a, 0x19a1: 0x000a, 0x19a2: 0x000a, 0x19a3: 0x000a,
+ 0x19a4: 0x000a, 0x19a5: 0x000a, 0x19a6: 0x000a, 0x19a7: 0x000a, 0x19a8: 0x000a, 0x19a9: 0x000a,
+ 0x19aa: 0x000a, 0x19ab: 0x000a, 0x19ac: 0x000a, 0x19ad: 0x000a, 0x19ae: 0x000a, 0x19af: 0x000a,
+ 0x19b0: 0x000a, 0x19b1: 0x000a, 0x19b2: 0x000a, 0x19b3: 0x000a,
+ 0x19b6: 0x000a, 0x19b7: 0x000a, 0x19b8: 0x000a, 0x19b9: 0x000a, 0x19ba: 0x000a, 0x19bb: 0x000a,
+ 0x19bc: 0x000a, 0x19bd: 0x000a, 0x19be: 0x000a, 0x19bf: 0x000a,
+ // Block 0x67, offset 0x19c0
+ 0x19c0: 0x000a, 0x19c1: 0x000a, 0x19c2: 0x000a, 0x19c3: 0x000a, 0x19c4: 0x000a, 0x19c5: 0x000a,
+ 0x19c6: 0x000a, 0x19c7: 0x000a, 0x19c8: 0x000a, 0x19c9: 0x000a, 0x19ca: 0x000a, 0x19cb: 0x000a,
+ 0x19cc: 0x000a, 0x19cd: 0x000a, 0x19ce: 0x000a, 0x19cf: 0x000a, 0x19d0: 0x000a, 0x19d1: 0x000a,
+ 0x19d2: 0x000a, 0x19d3: 0x000a, 0x19d4: 0x000a, 0x19d5: 0x000a, 0x19d7: 0x000a,
+ 0x19d8: 0x000a, 0x19d9: 0x000a, 0x19da: 0x000a, 0x19db: 0x000a, 0x19dc: 0x000a, 0x19dd: 0x000a,
+ 0x19de: 0x000a, 0x19df: 0x000a, 0x19e0: 0x000a, 0x19e1: 0x000a, 0x19e2: 0x000a, 0x19e3: 0x000a,
+ 0x19e4: 0x000a, 0x19e5: 0x000a, 0x19e6: 0x000a, 0x19e7: 0x000a, 0x19e8: 0x000a, 0x19e9: 0x000a,
+ 0x19ea: 0x000a, 0x19eb: 0x000a, 0x19ec: 0x000a, 0x19ed: 0x000a, 0x19ee: 0x000a, 0x19ef: 0x000a,
+ 0x19f0: 0x000a, 0x19f1: 0x000a, 0x19f2: 0x000a, 0x19f3: 0x000a, 0x19f4: 0x000a, 0x19f5: 0x000a,
+ 0x19f6: 0x000a, 0x19f7: 0x000a, 0x19f8: 0x000a, 0x19f9: 0x000a, 0x19fa: 0x000a, 0x19fb: 0x000a,
+ 0x19fc: 0x000a, 0x19fd: 0x000a, 0x19fe: 0x000a, 0x19ff: 0x000a,
+ // Block 0x68, offset 0x1a00
+ 0x1a25: 0x000a, 0x1a26: 0x000a, 0x1a27: 0x000a, 0x1a28: 0x000a, 0x1a29: 0x000a,
+ 0x1a2a: 0x000a, 0x1a2f: 0x000c,
+ 0x1a30: 0x000c, 0x1a31: 0x000c,
+ 0x1a39: 0x000a, 0x1a3a: 0x000a, 0x1a3b: 0x000a,
+ 0x1a3c: 0x000a, 0x1a3d: 0x000a, 0x1a3e: 0x000a, 0x1a3f: 0x000a,
+ // Block 0x69, offset 0x1a40
+ 0x1a7f: 0x000c,
+ // Block 0x6a, offset 0x1a80
+ 0x1aa0: 0x000c, 0x1aa1: 0x000c, 0x1aa2: 0x000c, 0x1aa3: 0x000c,
+ 0x1aa4: 0x000c, 0x1aa5: 0x000c, 0x1aa6: 0x000c, 0x1aa7: 0x000c, 0x1aa8: 0x000c, 0x1aa9: 0x000c,
+ 0x1aaa: 0x000c, 0x1aab: 0x000c, 0x1aac: 0x000c, 0x1aad: 0x000c, 0x1aae: 0x000c, 0x1aaf: 0x000c,
+ 0x1ab0: 0x000c, 0x1ab1: 0x000c, 0x1ab2: 0x000c, 0x1ab3: 0x000c, 0x1ab4: 0x000c, 0x1ab5: 0x000c,
+ 0x1ab6: 0x000c, 0x1ab7: 0x000c, 0x1ab8: 0x000c, 0x1ab9: 0x000c, 0x1aba: 0x000c, 0x1abb: 0x000c,
+ 0x1abc: 0x000c, 0x1abd: 0x000c, 0x1abe: 0x000c, 0x1abf: 0x000c,
+ // Block 0x6b, offset 0x1ac0
+ 0x1ac0: 0x000a, 0x1ac1: 0x000a, 0x1ac2: 0x000a, 0x1ac3: 0x000a, 0x1ac4: 0x000a, 0x1ac5: 0x000a,
+ 0x1ac6: 0x000a, 0x1ac7: 0x000a, 0x1ac8: 0x000a, 0x1ac9: 0x000a, 0x1aca: 0x000a, 0x1acb: 0x000a,
+ 0x1acc: 0x000a, 0x1acd: 0x000a, 0x1ace: 0x000a, 0x1acf: 0x000a, 0x1ad0: 0x000a, 0x1ad1: 0x000a,
+ 0x1ad2: 0x000a, 0x1ad3: 0x000a, 0x1ad4: 0x000a, 0x1ad5: 0x000a, 0x1ad6: 0x000a, 0x1ad7: 0x000a,
+ 0x1ad8: 0x000a, 0x1ad9: 0x000a, 0x1ada: 0x000a, 0x1adb: 0x000a, 0x1adc: 0x000a, 0x1add: 0x000a,
+ 0x1ade: 0x000a, 0x1adf: 0x000a, 0x1ae0: 0x000a, 0x1ae1: 0x000a, 0x1ae2: 0x003a, 0x1ae3: 0x002a,
+ 0x1ae4: 0x003a, 0x1ae5: 0x002a, 0x1ae6: 0x003a, 0x1ae7: 0x002a, 0x1ae8: 0x003a, 0x1ae9: 0x002a,
+ 0x1aea: 0x000a, 0x1aeb: 0x000a, 0x1aec: 0x000a, 0x1aed: 0x000a, 0x1aee: 0x000a, 0x1aef: 0x000a,
+ 0x1af0: 0x000a, 0x1af1: 0x000a, 0x1af2: 0x000a, 0x1af3: 0x000a, 0x1af4: 0x000a, 0x1af5: 0x000a,
+ 0x1af6: 0x000a, 0x1af7: 0x000a, 0x1af8: 0x000a, 0x1af9: 0x000a, 0x1afa: 0x000a, 0x1afb: 0x000a,
+ 0x1afc: 0x000a, 0x1afd: 0x000a, 0x1afe: 0x000a, 0x1aff: 0x000a,
+ // Block 0x6c, offset 0x1b00
+ 0x1b00: 0x000a, 0x1b01: 0x000a, 0x1b02: 0x000a, 0x1b03: 0x000a, 0x1b04: 0x000a, 0x1b05: 0x000a,
+ 0x1b06: 0x000a, 0x1b07: 0x000a, 0x1b08: 0x000a, 0x1b09: 0x000a, 0x1b0a: 0x000a, 0x1b0b: 0x000a,
+ 0x1b0c: 0x000a, 0x1b0d: 0x000a, 0x1b0e: 0x000a, 0x1b0f: 0x000a, 0x1b10: 0x000a, 0x1b11: 0x000a,
+ 0x1b12: 0x000a,
+ // Block 0x6d, offset 0x1b40
+ 0x1b40: 0x000a, 0x1b41: 0x000a, 0x1b42: 0x000a, 0x1b43: 0x000a, 0x1b44: 0x000a, 0x1b45: 0x000a,
+ 0x1b46: 0x000a, 0x1b47: 0x000a, 0x1b48: 0x000a, 0x1b49: 0x000a, 0x1b4a: 0x000a, 0x1b4b: 0x000a,
+ 0x1b4c: 0x000a, 0x1b4d: 0x000a, 0x1b4e: 0x000a, 0x1b4f: 0x000a, 0x1b50: 0x000a, 0x1b51: 0x000a,
+ 0x1b52: 0x000a, 0x1b53: 0x000a, 0x1b54: 0x000a, 0x1b55: 0x000a, 0x1b56: 0x000a, 0x1b57: 0x000a,
+ 0x1b58: 0x000a, 0x1b59: 0x000a, 0x1b5b: 0x000a, 0x1b5c: 0x000a, 0x1b5d: 0x000a,
+ 0x1b5e: 0x000a, 0x1b5f: 0x000a, 0x1b60: 0x000a, 0x1b61: 0x000a, 0x1b62: 0x000a, 0x1b63: 0x000a,
+ 0x1b64: 0x000a, 0x1b65: 0x000a, 0x1b66: 0x000a, 0x1b67: 0x000a, 0x1b68: 0x000a, 0x1b69: 0x000a,
+ 0x1b6a: 0x000a, 0x1b6b: 0x000a, 0x1b6c: 0x000a, 0x1b6d: 0x000a, 0x1b6e: 0x000a, 0x1b6f: 0x000a,
+ 0x1b70: 0x000a, 0x1b71: 0x000a, 0x1b72: 0x000a, 0x1b73: 0x000a, 0x1b74: 0x000a, 0x1b75: 0x000a,
+ 0x1b76: 0x000a, 0x1b77: 0x000a, 0x1b78: 0x000a, 0x1b79: 0x000a, 0x1b7a: 0x000a, 0x1b7b: 0x000a,
+ 0x1b7c: 0x000a, 0x1b7d: 0x000a, 0x1b7e: 0x000a, 0x1b7f: 0x000a,
+ // Block 0x6e, offset 0x1b80
+ 0x1b80: 0x000a, 0x1b81: 0x000a, 0x1b82: 0x000a, 0x1b83: 0x000a, 0x1b84: 0x000a, 0x1b85: 0x000a,
+ 0x1b86: 0x000a, 0x1b87: 0x000a, 0x1b88: 0x000a, 0x1b89: 0x000a, 0x1b8a: 0x000a, 0x1b8b: 0x000a,
+ 0x1b8c: 0x000a, 0x1b8d: 0x000a, 0x1b8e: 0x000a, 0x1b8f: 0x000a, 0x1b90: 0x000a, 0x1b91: 0x000a,
+ 0x1b92: 0x000a, 0x1b93: 0x000a, 0x1b94: 0x000a, 0x1b95: 0x000a, 0x1b96: 0x000a, 0x1b97: 0x000a,
+ 0x1b98: 0x000a, 0x1b99: 0x000a, 0x1b9a: 0x000a, 0x1b9b: 0x000a, 0x1b9c: 0x000a, 0x1b9d: 0x000a,
+ 0x1b9e: 0x000a, 0x1b9f: 0x000a, 0x1ba0: 0x000a, 0x1ba1: 0x000a, 0x1ba2: 0x000a, 0x1ba3: 0x000a,
+ 0x1ba4: 0x000a, 0x1ba5: 0x000a, 0x1ba6: 0x000a, 0x1ba7: 0x000a, 0x1ba8: 0x000a, 0x1ba9: 0x000a,
+ 0x1baa: 0x000a, 0x1bab: 0x000a, 0x1bac: 0x000a, 0x1bad: 0x000a, 0x1bae: 0x000a, 0x1baf: 0x000a,
+ 0x1bb0: 0x000a, 0x1bb1: 0x000a, 0x1bb2: 0x000a, 0x1bb3: 0x000a,
+ // Block 0x6f, offset 0x1bc0
+ 0x1bc0: 0x000a, 0x1bc1: 0x000a, 0x1bc2: 0x000a, 0x1bc3: 0x000a, 0x1bc4: 0x000a, 0x1bc5: 0x000a,
+ 0x1bc6: 0x000a, 0x1bc7: 0x000a, 0x1bc8: 0x000a, 0x1bc9: 0x000a, 0x1bca: 0x000a, 0x1bcb: 0x000a,
+ 0x1bcc: 0x000a, 0x1bcd: 0x000a, 0x1bce: 0x000a, 0x1bcf: 0x000a, 0x1bd0: 0x000a, 0x1bd1: 0x000a,
+ 0x1bd2: 0x000a, 0x1bd3: 0x000a, 0x1bd4: 0x000a, 0x1bd5: 0x000a,
+ 0x1bf0: 0x000a, 0x1bf1: 0x000a, 0x1bf2: 0x000a, 0x1bf3: 0x000a, 0x1bf4: 0x000a, 0x1bf5: 0x000a,
+ 0x1bf6: 0x000a, 0x1bf7: 0x000a, 0x1bf8: 0x000a, 0x1bf9: 0x000a, 0x1bfa: 0x000a, 0x1bfb: 0x000a,
+ // Block 0x70, offset 0x1c00
+ 0x1c00: 0x0009, 0x1c01: 0x000a, 0x1c02: 0x000a, 0x1c03: 0x000a, 0x1c04: 0x000a,
+ 0x1c08: 0x003a, 0x1c09: 0x002a, 0x1c0a: 0x003a, 0x1c0b: 0x002a,
+ 0x1c0c: 0x003a, 0x1c0d: 0x002a, 0x1c0e: 0x003a, 0x1c0f: 0x002a, 0x1c10: 0x003a, 0x1c11: 0x002a,
+ 0x1c12: 0x000a, 0x1c13: 0x000a, 0x1c14: 0x003a, 0x1c15: 0x002a, 0x1c16: 0x003a, 0x1c17: 0x002a,
+ 0x1c18: 0x003a, 0x1c19: 0x002a, 0x1c1a: 0x003a, 0x1c1b: 0x002a, 0x1c1c: 0x000a, 0x1c1d: 0x000a,
+ 0x1c1e: 0x000a, 0x1c1f: 0x000a, 0x1c20: 0x000a,
+ 0x1c2a: 0x000c, 0x1c2b: 0x000c, 0x1c2c: 0x000c, 0x1c2d: 0x000c,
+ 0x1c30: 0x000a,
+ 0x1c36: 0x000a, 0x1c37: 0x000a,
+ 0x1c3d: 0x000a, 0x1c3e: 0x000a, 0x1c3f: 0x000a,
+ // Block 0x71, offset 0x1c40
+ 0x1c59: 0x000c, 0x1c5a: 0x000c, 0x1c5b: 0x000a, 0x1c5c: 0x000a,
+ 0x1c60: 0x000a,
+ // Block 0x72, offset 0x1c80
+ 0x1cbb: 0x000a,
+ // Block 0x73, offset 0x1cc0
+ 0x1cc0: 0x000a, 0x1cc1: 0x000a, 0x1cc2: 0x000a, 0x1cc3: 0x000a, 0x1cc4: 0x000a, 0x1cc5: 0x000a,
+ 0x1cc6: 0x000a, 0x1cc7: 0x000a, 0x1cc8: 0x000a, 0x1cc9: 0x000a, 0x1cca: 0x000a, 0x1ccb: 0x000a,
+ 0x1ccc: 0x000a, 0x1ccd: 0x000a, 0x1cce: 0x000a, 0x1ccf: 0x000a, 0x1cd0: 0x000a, 0x1cd1: 0x000a,
+ 0x1cd2: 0x000a, 0x1cd3: 0x000a, 0x1cd4: 0x000a, 0x1cd5: 0x000a, 0x1cd6: 0x000a, 0x1cd7: 0x000a,
+ 0x1cd8: 0x000a, 0x1cd9: 0x000a, 0x1cda: 0x000a, 0x1cdb: 0x000a, 0x1cdc: 0x000a, 0x1cdd: 0x000a,
+ 0x1cde: 0x000a, 0x1cdf: 0x000a, 0x1ce0: 0x000a, 0x1ce1: 0x000a, 0x1ce2: 0x000a, 0x1ce3: 0x000a,
+ // Block 0x74, offset 0x1d00
+ 0x1d1d: 0x000a,
+ 0x1d1e: 0x000a,
+ // Block 0x75, offset 0x1d40
+ 0x1d50: 0x000a, 0x1d51: 0x000a,
+ 0x1d52: 0x000a, 0x1d53: 0x000a, 0x1d54: 0x000a, 0x1d55: 0x000a, 0x1d56: 0x000a, 0x1d57: 0x000a,
+ 0x1d58: 0x000a, 0x1d59: 0x000a, 0x1d5a: 0x000a, 0x1d5b: 0x000a, 0x1d5c: 0x000a, 0x1d5d: 0x000a,
+ 0x1d5e: 0x000a, 0x1d5f: 0x000a,
+ 0x1d7c: 0x000a, 0x1d7d: 0x000a, 0x1d7e: 0x000a,
+ // Block 0x76, offset 0x1d80
+ 0x1db1: 0x000a, 0x1db2: 0x000a, 0x1db3: 0x000a, 0x1db4: 0x000a, 0x1db5: 0x000a,
+ 0x1db6: 0x000a, 0x1db7: 0x000a, 0x1db8: 0x000a, 0x1db9: 0x000a, 0x1dba: 0x000a, 0x1dbb: 0x000a,
+ 0x1dbc: 0x000a, 0x1dbd: 0x000a, 0x1dbe: 0x000a, 0x1dbf: 0x000a,
+ // Block 0x77, offset 0x1dc0
+ 0x1dcc: 0x000a, 0x1dcd: 0x000a, 0x1dce: 0x000a, 0x1dcf: 0x000a,
+ // Block 0x78, offset 0x1e00
+ 0x1e37: 0x000a, 0x1e38: 0x000a, 0x1e39: 0x000a, 0x1e3a: 0x000a,
+ // Block 0x79, offset 0x1e40
+ 0x1e5e: 0x000a, 0x1e5f: 0x000a,
+ 0x1e7f: 0x000a,
+ // Block 0x7a, offset 0x1e80
+ 0x1e90: 0x000a, 0x1e91: 0x000a,
+ 0x1e92: 0x000a, 0x1e93: 0x000a, 0x1e94: 0x000a, 0x1e95: 0x000a, 0x1e96: 0x000a, 0x1e97: 0x000a,
+ 0x1e98: 0x000a, 0x1e99: 0x000a, 0x1e9a: 0x000a, 0x1e9b: 0x000a, 0x1e9c: 0x000a, 0x1e9d: 0x000a,
+ 0x1e9e: 0x000a, 0x1e9f: 0x000a, 0x1ea0: 0x000a, 0x1ea1: 0x000a, 0x1ea2: 0x000a, 0x1ea3: 0x000a,
+ 0x1ea4: 0x000a, 0x1ea5: 0x000a, 0x1ea6: 0x000a, 0x1ea7: 0x000a, 0x1ea8: 0x000a, 0x1ea9: 0x000a,
+ 0x1eaa: 0x000a, 0x1eab: 0x000a, 0x1eac: 0x000a, 0x1ead: 0x000a, 0x1eae: 0x000a, 0x1eaf: 0x000a,
+ 0x1eb0: 0x000a, 0x1eb1: 0x000a, 0x1eb2: 0x000a, 0x1eb3: 0x000a, 0x1eb4: 0x000a, 0x1eb5: 0x000a,
+ 0x1eb6: 0x000a, 0x1eb7: 0x000a, 0x1eb8: 0x000a, 0x1eb9: 0x000a, 0x1eba: 0x000a, 0x1ebb: 0x000a,
+ 0x1ebc: 0x000a, 0x1ebd: 0x000a, 0x1ebe: 0x000a, 0x1ebf: 0x000a,
+ // Block 0x7b, offset 0x1ec0
+ 0x1ec0: 0x000a, 0x1ec1: 0x000a, 0x1ec2: 0x000a, 0x1ec3: 0x000a, 0x1ec4: 0x000a, 0x1ec5: 0x000a,
+ 0x1ec6: 0x000a,
+ // Block 0x7c, offset 0x1f00
+ 0x1f0d: 0x000a, 0x1f0e: 0x000a, 0x1f0f: 0x000a,
+ // Block 0x7d, offset 0x1f40
+ 0x1f6f: 0x000c,
+ 0x1f70: 0x000c, 0x1f71: 0x000c, 0x1f72: 0x000c, 0x1f73: 0x000a, 0x1f74: 0x000c, 0x1f75: 0x000c,
+ 0x1f76: 0x000c, 0x1f77: 0x000c, 0x1f78: 0x000c, 0x1f79: 0x000c, 0x1f7a: 0x000c, 0x1f7b: 0x000c,
+ 0x1f7c: 0x000c, 0x1f7d: 0x000c, 0x1f7e: 0x000a, 0x1f7f: 0x000a,
+ // Block 0x7e, offset 0x1f80
+ 0x1f9e: 0x000c, 0x1f9f: 0x000c,
+ // Block 0x7f, offset 0x1fc0
+ 0x1ff0: 0x000c, 0x1ff1: 0x000c,
+ // Block 0x80, offset 0x2000
+ 0x2000: 0x000a, 0x2001: 0x000a, 0x2002: 0x000a, 0x2003: 0x000a, 0x2004: 0x000a, 0x2005: 0x000a,
+ 0x2006: 0x000a, 0x2007: 0x000a, 0x2008: 0x000a, 0x2009: 0x000a, 0x200a: 0x000a, 0x200b: 0x000a,
+ 0x200c: 0x000a, 0x200d: 0x000a, 0x200e: 0x000a, 0x200f: 0x000a, 0x2010: 0x000a, 0x2011: 0x000a,
+ 0x2012: 0x000a, 0x2013: 0x000a, 0x2014: 0x000a, 0x2015: 0x000a, 0x2016: 0x000a, 0x2017: 0x000a,
+ 0x2018: 0x000a, 0x2019: 0x000a, 0x201a: 0x000a, 0x201b: 0x000a, 0x201c: 0x000a, 0x201d: 0x000a,
+ 0x201e: 0x000a, 0x201f: 0x000a, 0x2020: 0x000a, 0x2021: 0x000a,
+ // Block 0x81, offset 0x2040
+ 0x2048: 0x000a,
+ // Block 0x82, offset 0x2080
+ 0x2082: 0x000c,
+ 0x2086: 0x000c, 0x208b: 0x000c,
+ 0x20a5: 0x000c, 0x20a6: 0x000c, 0x20a8: 0x000a, 0x20a9: 0x000a,
+ 0x20aa: 0x000a, 0x20ab: 0x000a, 0x20ac: 0x000c,
+ 0x20b8: 0x0004, 0x20b9: 0x0004,
+ // Block 0x83, offset 0x20c0
+ 0x20f4: 0x000a, 0x20f5: 0x000a,
+ 0x20f6: 0x000a, 0x20f7: 0x000a,
+ // Block 0x84, offset 0x2100
+ 0x2104: 0x000c, 0x2105: 0x000c,
+ 0x2120: 0x000c, 0x2121: 0x000c, 0x2122: 0x000c, 0x2123: 0x000c,
+ 0x2124: 0x000c, 0x2125: 0x000c, 0x2126: 0x000c, 0x2127: 0x000c, 0x2128: 0x000c, 0x2129: 0x000c,
+ 0x212a: 0x000c, 0x212b: 0x000c, 0x212c: 0x000c, 0x212d: 0x000c, 0x212e: 0x000c, 0x212f: 0x000c,
+ 0x2130: 0x000c, 0x2131: 0x000c,
+ 0x213f: 0x000c,
+ // Block 0x85, offset 0x2140
+ 0x2166: 0x000c, 0x2167: 0x000c, 0x2168: 0x000c, 0x2169: 0x000c,
+ 0x216a: 0x000c, 0x216b: 0x000c, 0x216c: 0x000c, 0x216d: 0x000c,
+ // Block 0x86, offset 0x2180
+ 0x2187: 0x000c, 0x2188: 0x000c, 0x2189: 0x000c, 0x218a: 0x000c, 0x218b: 0x000c,
+ 0x218c: 0x000c, 0x218d: 0x000c, 0x218e: 0x000c, 0x218f: 0x000c, 0x2190: 0x000c, 0x2191: 0x000c,
+ // Block 0x87, offset 0x21c0
+ 0x21c0: 0x000c, 0x21c1: 0x000c, 0x21c2: 0x000c,
+ 0x21f3: 0x000c,
+ 0x21f6: 0x000c, 0x21f7: 0x000c, 0x21f8: 0x000c, 0x21f9: 0x000c,
+ 0x21fc: 0x000c, 0x21fd: 0x000c,
+ // Block 0x88, offset 0x2200
+ 0x2225: 0x000c,
+ // Block 0x89, offset 0x2240
+ 0x2269: 0x000c,
+ 0x226a: 0x000c, 0x226b: 0x000c, 0x226c: 0x000c, 0x226d: 0x000c, 0x226e: 0x000c,
+ 0x2271: 0x000c, 0x2272: 0x000c, 0x2275: 0x000c,
+ 0x2276: 0x000c,
+ // Block 0x8a, offset 0x2280
+ 0x2283: 0x000c,
+ 0x228c: 0x000c,
+ 0x22bc: 0x000c,
+ // Block 0x8b, offset 0x22c0
+ 0x22f0: 0x000c, 0x22f2: 0x000c, 0x22f3: 0x000c, 0x22f4: 0x000c,
+ 0x22f7: 0x000c, 0x22f8: 0x000c,
+ 0x22fe: 0x000c, 0x22ff: 0x000c,
+ // Block 0x8c, offset 0x2300
+ 0x2301: 0x000c,
+ 0x232c: 0x000c, 0x232d: 0x000c,
+ 0x2336: 0x000c,
+ // Block 0x8d, offset 0x2340
+ 0x236a: 0x000a, 0x236b: 0x000a,
+ // Block 0x8e, offset 0x2380
+ 0x23a5: 0x000c, 0x23a8: 0x000c,
+ 0x23ad: 0x000c,
+ // Block 0x8f, offset 0x23c0
+ 0x23dd: 0x0001,
+ 0x23de: 0x000c, 0x23df: 0x0001, 0x23e0: 0x0001, 0x23e1: 0x0001, 0x23e2: 0x0001, 0x23e3: 0x0001,
+ 0x23e4: 0x0001, 0x23e5: 0x0001, 0x23e6: 0x0001, 0x23e7: 0x0001, 0x23e8: 0x0001, 0x23e9: 0x0003,
+ 0x23ea: 0x0001, 0x23eb: 0x0001, 0x23ec: 0x0001, 0x23ed: 0x0001, 0x23ee: 0x0001, 0x23ef: 0x0001,
+ 0x23f0: 0x0001, 0x23f1: 0x0001, 0x23f2: 0x0001, 0x23f3: 0x0001, 0x23f4: 0x0001, 0x23f5: 0x0001,
+ 0x23f6: 0x0001, 0x23f7: 0x0001, 0x23f8: 0x0001, 0x23f9: 0x0001, 0x23fa: 0x0001, 0x23fb: 0x0001,
+ 0x23fc: 0x0001, 0x23fd: 0x0001, 0x23fe: 0x0001, 0x23ff: 0x0001,
+ // Block 0x90, offset 0x2400
+ 0x2400: 0x0001, 0x2401: 0x0001, 0x2402: 0x0001, 0x2403: 0x0001, 0x2404: 0x0001, 0x2405: 0x0001,
+ 0x2406: 0x0001, 0x2407: 0x0001, 0x2408: 0x0001, 0x2409: 0x0001, 0x240a: 0x0001, 0x240b: 0x0001,
+ 0x240c: 0x0001, 0x240d: 0x0001, 0x240e: 0x0001, 0x240f: 0x0001, 0x2410: 0x000d, 0x2411: 0x000d,
+ 0x2412: 0x000d, 0x2413: 0x000d, 0x2414: 0x000d, 0x2415: 0x000d, 0x2416: 0x000d, 0x2417: 0x000d,
+ 0x2418: 0x000d, 0x2419: 0x000d, 0x241a: 0x000d, 0x241b: 0x000d, 0x241c: 0x000d, 0x241d: 0x000d,
+ 0x241e: 0x000d, 0x241f: 0x000d, 0x2420: 0x000d, 0x2421: 0x000d, 0x2422: 0x000d, 0x2423: 0x000d,
+ 0x2424: 0x000d, 0x2425: 0x000d, 0x2426: 0x000d, 0x2427: 0x000d, 0x2428: 0x000d, 0x2429: 0x000d,
+ 0x242a: 0x000d, 0x242b: 0x000d, 0x242c: 0x000d, 0x242d: 0x000d, 0x242e: 0x000d, 0x242f: 0x000d,
+ 0x2430: 0x000d, 0x2431: 0x000d, 0x2432: 0x000d, 0x2433: 0x000d, 0x2434: 0x000d, 0x2435: 0x000d,
+ 0x2436: 0x000d, 0x2437: 0x000d, 0x2438: 0x000d, 0x2439: 0x000d, 0x243a: 0x000d, 0x243b: 0x000d,
+ 0x243c: 0x000d, 0x243d: 0x000d, 0x243e: 0x000d, 0x243f: 0x000d,
+ // Block 0x91, offset 0x2440
+ 0x2440: 0x000d, 0x2441: 0x000d, 0x2442: 0x000d, 0x2443: 0x000d, 0x2444: 0x000d, 0x2445: 0x000d,
+ 0x2446: 0x000d, 0x2447: 0x000d, 0x2448: 0x000d, 0x2449: 0x000d, 0x244a: 0x000d, 0x244b: 0x000d,
+ 0x244c: 0x000d, 0x244d: 0x000d, 0x244e: 0x000d, 0x244f: 0x000d, 0x2450: 0x000d, 0x2451: 0x000d,
+ 0x2452: 0x000d, 0x2453: 0x000d, 0x2454: 0x000d, 0x2455: 0x000d, 0x2456: 0x000d, 0x2457: 0x000d,
+ 0x2458: 0x000d, 0x2459: 0x000d, 0x245a: 0x000d, 0x245b: 0x000d, 0x245c: 0x000d, 0x245d: 0x000d,
+ 0x245e: 0x000d, 0x245f: 0x000d, 0x2460: 0x000d, 0x2461: 0x000d, 0x2462: 0x000d, 0x2463: 0x000d,
+ 0x2464: 0x000d, 0x2465: 0x000d, 0x2466: 0x000d, 0x2467: 0x000d, 0x2468: 0x000d, 0x2469: 0x000d,
+ 0x246a: 0x000d, 0x246b: 0x000d, 0x246c: 0x000d, 0x246d: 0x000d, 0x246e: 0x000d, 0x246f: 0x000d,
+ 0x2470: 0x000d, 0x2471: 0x000d, 0x2472: 0x000d, 0x2473: 0x000d, 0x2474: 0x000d, 0x2475: 0x000d,
+ 0x2476: 0x000d, 0x2477: 0x000d, 0x2478: 0x000d, 0x2479: 0x000d, 0x247a: 0x000d, 0x247b: 0x000d,
+ 0x247c: 0x000d, 0x247d: 0x000d, 0x247e: 0x000a, 0x247f: 0x000a,
+ // Block 0x92, offset 0x2480
+ 0x2480: 0x000d, 0x2481: 0x000d, 0x2482: 0x000d, 0x2483: 0x000d, 0x2484: 0x000d, 0x2485: 0x000d,
+ 0x2486: 0x000d, 0x2487: 0x000d, 0x2488: 0x000d, 0x2489: 0x000d, 0x248a: 0x000d, 0x248b: 0x000d,
+ 0x248c: 0x000d, 0x248d: 0x000d, 0x248e: 0x000d, 0x248f: 0x000d, 0x2490: 0x000b, 0x2491: 0x000b,
+ 0x2492: 0x000b, 0x2493: 0x000b, 0x2494: 0x000b, 0x2495: 0x000b, 0x2496: 0x000b, 0x2497: 0x000b,
+ 0x2498: 0x000b, 0x2499: 0x000b, 0x249a: 0x000b, 0x249b: 0x000b, 0x249c: 0x000b, 0x249d: 0x000b,
+ 0x249e: 0x000b, 0x249f: 0x000b, 0x24a0: 0x000b, 0x24a1: 0x000b, 0x24a2: 0x000b, 0x24a3: 0x000b,
+ 0x24a4: 0x000b, 0x24a5: 0x000b, 0x24a6: 0x000b, 0x24a7: 0x000b, 0x24a8: 0x000b, 0x24a9: 0x000b,
+ 0x24aa: 0x000b, 0x24ab: 0x000b, 0x24ac: 0x000b, 0x24ad: 0x000b, 0x24ae: 0x000b, 0x24af: 0x000b,
+ 0x24b0: 0x000d, 0x24b1: 0x000d, 0x24b2: 0x000d, 0x24b3: 0x000d, 0x24b4: 0x000d, 0x24b5: 0x000d,
+ 0x24b6: 0x000d, 0x24b7: 0x000d, 0x24b8: 0x000d, 0x24b9: 0x000d, 0x24ba: 0x000d, 0x24bb: 0x000d,
+ 0x24bc: 0x000d, 0x24bd: 0x000a, 0x24be: 0x000d, 0x24bf: 0x000d,
+ // Block 0x93, offset 0x24c0
+ 0x24c0: 0x000c, 0x24c1: 0x000c, 0x24c2: 0x000c, 0x24c3: 0x000c, 0x24c4: 0x000c, 0x24c5: 0x000c,
+ 0x24c6: 0x000c, 0x24c7: 0x000c, 0x24c8: 0x000c, 0x24c9: 0x000c, 0x24ca: 0x000c, 0x24cb: 0x000c,
+ 0x24cc: 0x000c, 0x24cd: 0x000c, 0x24ce: 0x000c, 0x24cf: 0x000c, 0x24d0: 0x000a, 0x24d1: 0x000a,
+ 0x24d2: 0x000a, 0x24d3: 0x000a, 0x24d4: 0x000a, 0x24d5: 0x000a, 0x24d6: 0x000a, 0x24d7: 0x000a,
+ 0x24d8: 0x000a, 0x24d9: 0x000a,
+ 0x24e0: 0x000c, 0x24e1: 0x000c, 0x24e2: 0x000c, 0x24e3: 0x000c,
+ 0x24e4: 0x000c, 0x24e5: 0x000c, 0x24e6: 0x000c, 0x24e7: 0x000c, 0x24e8: 0x000c, 0x24e9: 0x000c,
+ 0x24ea: 0x000c, 0x24eb: 0x000c, 0x24ec: 0x000c, 0x24ed: 0x000c, 0x24ee: 0x000c, 0x24ef: 0x000c,
+ 0x24f0: 0x000a, 0x24f1: 0x000a, 0x24f2: 0x000a, 0x24f3: 0x000a, 0x24f4: 0x000a, 0x24f5: 0x000a,
+ 0x24f6: 0x000a, 0x24f7: 0x000a, 0x24f8: 0x000a, 0x24f9: 0x000a, 0x24fa: 0x000a, 0x24fb: 0x000a,
+ 0x24fc: 0x000a, 0x24fd: 0x000a, 0x24fe: 0x000a, 0x24ff: 0x000a,
+ // Block 0x94, offset 0x2500
+ 0x2500: 0x000a, 0x2501: 0x000a, 0x2502: 0x000a, 0x2503: 0x000a, 0x2504: 0x000a, 0x2505: 0x000a,
+ 0x2506: 0x000a, 0x2507: 0x000a, 0x2508: 0x000a, 0x2509: 0x000a, 0x250a: 0x000a, 0x250b: 0x000a,
+ 0x250c: 0x000a, 0x250d: 0x000a, 0x250e: 0x000a, 0x250f: 0x000a, 0x2510: 0x0006, 0x2511: 0x000a,
+ 0x2512: 0x0006, 0x2514: 0x000a, 0x2515: 0x0006, 0x2516: 0x000a, 0x2517: 0x000a,
+ 0x2518: 0x000a, 0x2519: 0x009a, 0x251a: 0x008a, 0x251b: 0x007a, 0x251c: 0x006a, 0x251d: 0x009a,
+ 0x251e: 0x008a, 0x251f: 0x0004, 0x2520: 0x000a, 0x2521: 0x000a, 0x2522: 0x0003, 0x2523: 0x0003,
+ 0x2524: 0x000a, 0x2525: 0x000a, 0x2526: 0x000a, 0x2528: 0x000a, 0x2529: 0x0004,
+ 0x252a: 0x0004, 0x252b: 0x000a,
+ 0x2530: 0x000d, 0x2531: 0x000d, 0x2532: 0x000d, 0x2533: 0x000d, 0x2534: 0x000d, 0x2535: 0x000d,
+ 0x2536: 0x000d, 0x2537: 0x000d, 0x2538: 0x000d, 0x2539: 0x000d, 0x253a: 0x000d, 0x253b: 0x000d,
+ 0x253c: 0x000d, 0x253d: 0x000d, 0x253e: 0x000d, 0x253f: 0x000d,
+ // Block 0x95, offset 0x2540
+ 0x2540: 0x000d, 0x2541: 0x000d, 0x2542: 0x000d, 0x2543: 0x000d, 0x2544: 0x000d, 0x2545: 0x000d,
+ 0x2546: 0x000d, 0x2547: 0x000d, 0x2548: 0x000d, 0x2549: 0x000d, 0x254a: 0x000d, 0x254b: 0x000d,
+ 0x254c: 0x000d, 0x254d: 0x000d, 0x254e: 0x000d, 0x254f: 0x000d, 0x2550: 0x000d, 0x2551: 0x000d,
+ 0x2552: 0x000d, 0x2553: 0x000d, 0x2554: 0x000d, 0x2555: 0x000d, 0x2556: 0x000d, 0x2557: 0x000d,
+ 0x2558: 0x000d, 0x2559: 0x000d, 0x255a: 0x000d, 0x255b: 0x000d, 0x255c: 0x000d, 0x255d: 0x000d,
+ 0x255e: 0x000d, 0x255f: 0x000d, 0x2560: 0x000d, 0x2561: 0x000d, 0x2562: 0x000d, 0x2563: 0x000d,
+ 0x2564: 0x000d, 0x2565: 0x000d, 0x2566: 0x000d, 0x2567: 0x000d, 0x2568: 0x000d, 0x2569: 0x000d,
+ 0x256a: 0x000d, 0x256b: 0x000d, 0x256c: 0x000d, 0x256d: 0x000d, 0x256e: 0x000d, 0x256f: 0x000d,
+ 0x2570: 0x000d, 0x2571: 0x000d, 0x2572: 0x000d, 0x2573: 0x000d, 0x2574: 0x000d, 0x2575: 0x000d,
+ 0x2576: 0x000d, 0x2577: 0x000d, 0x2578: 0x000d, 0x2579: 0x000d, 0x257a: 0x000d, 0x257b: 0x000d,
+ 0x257c: 0x000d, 0x257d: 0x000d, 0x257e: 0x000d, 0x257f: 0x000b,
+ // Block 0x96, offset 0x2580
+ 0x2581: 0x000a, 0x2582: 0x000a, 0x2583: 0x0004, 0x2584: 0x0004, 0x2585: 0x0004,
+ 0x2586: 0x000a, 0x2587: 0x000a, 0x2588: 0x003a, 0x2589: 0x002a, 0x258a: 0x000a, 0x258b: 0x0003,
+ 0x258c: 0x0006, 0x258d: 0x0003, 0x258e: 0x0006, 0x258f: 0x0006, 0x2590: 0x0002, 0x2591: 0x0002,
+ 0x2592: 0x0002, 0x2593: 0x0002, 0x2594: 0x0002, 0x2595: 0x0002, 0x2596: 0x0002, 0x2597: 0x0002,
+ 0x2598: 0x0002, 0x2599: 0x0002, 0x259a: 0x0006, 0x259b: 0x000a, 0x259c: 0x000a, 0x259d: 0x000a,
+ 0x259e: 0x000a, 0x259f: 0x000a, 0x25a0: 0x000a,
+ 0x25bb: 0x005a,
+ 0x25bc: 0x000a, 0x25bd: 0x004a, 0x25be: 0x000a, 0x25bf: 0x000a,
+ // Block 0x97, offset 0x25c0
+ 0x25c0: 0x000a,
+ 0x25db: 0x005a, 0x25dc: 0x000a, 0x25dd: 0x004a,
+ 0x25de: 0x000a, 0x25df: 0x00fa, 0x25e0: 0x00ea, 0x25e1: 0x000a, 0x25e2: 0x003a, 0x25e3: 0x002a,
+ 0x25e4: 0x000a, 0x25e5: 0x000a,
+ // Block 0x98, offset 0x2600
+ 0x2620: 0x0004, 0x2621: 0x0004, 0x2622: 0x000a, 0x2623: 0x000a,
+ 0x2624: 0x000a, 0x2625: 0x0004, 0x2626: 0x0004, 0x2628: 0x000a, 0x2629: 0x000a,
+ 0x262a: 0x000a, 0x262b: 0x000a, 0x262c: 0x000a, 0x262d: 0x000a, 0x262e: 0x000a,
+ 0x2630: 0x000b, 0x2631: 0x000b, 0x2632: 0x000b, 0x2633: 0x000b, 0x2634: 0x000b, 0x2635: 0x000b,
+ 0x2636: 0x000b, 0x2637: 0x000b, 0x2638: 0x000b, 0x2639: 0x000a, 0x263a: 0x000a, 0x263b: 0x000a,
+ 0x263c: 0x000a, 0x263d: 0x000a, 0x263e: 0x000b, 0x263f: 0x000b,
+ // Block 0x99, offset 0x2640
+ 0x2641: 0x000a,
+ // Block 0x9a, offset 0x2680
+ 0x2680: 0x000a, 0x2681: 0x000a, 0x2682: 0x000a, 0x2683: 0x000a, 0x2684: 0x000a, 0x2685: 0x000a,
+ 0x2686: 0x000a, 0x2687: 0x000a, 0x2688: 0x000a, 0x2689: 0x000a, 0x268a: 0x000a, 0x268b: 0x000a,
+ 0x268c: 0x000a, 0x2690: 0x000a, 0x2691: 0x000a,
+ 0x2692: 0x000a, 0x2693: 0x000a, 0x2694: 0x000a, 0x2695: 0x000a, 0x2696: 0x000a, 0x2697: 0x000a,
+ 0x2698: 0x000a, 0x2699: 0x000a, 0x269a: 0x000a, 0x269b: 0x000a, 0x269c: 0x000a,
+ 0x26a0: 0x000a,
+ // Block 0x9b, offset 0x26c0
+ 0x26fd: 0x000c,
+ // Block 0x9c, offset 0x2700
+ 0x2720: 0x000c, 0x2721: 0x0002, 0x2722: 0x0002, 0x2723: 0x0002,
+ 0x2724: 0x0002, 0x2725: 0x0002, 0x2726: 0x0002, 0x2727: 0x0002, 0x2728: 0x0002, 0x2729: 0x0002,
+ 0x272a: 0x0002, 0x272b: 0x0002, 0x272c: 0x0002, 0x272d: 0x0002, 0x272e: 0x0002, 0x272f: 0x0002,
+ 0x2730: 0x0002, 0x2731: 0x0002, 0x2732: 0x0002, 0x2733: 0x0002, 0x2734: 0x0002, 0x2735: 0x0002,
+ 0x2736: 0x0002, 0x2737: 0x0002, 0x2738: 0x0002, 0x2739: 0x0002, 0x273a: 0x0002, 0x273b: 0x0002,
+ // Block 0x9d, offset 0x2740
+ 0x2776: 0x000c, 0x2777: 0x000c, 0x2778: 0x000c, 0x2779: 0x000c, 0x277a: 0x000c,
+ // Block 0x9e, offset 0x2780
+ 0x2780: 0x0001, 0x2781: 0x0001, 0x2782: 0x0001, 0x2783: 0x0001, 0x2784: 0x0001, 0x2785: 0x0001,
+ 0x2786: 0x0001, 0x2787: 0x0001, 0x2788: 0x0001, 0x2789: 0x0001, 0x278a: 0x0001, 0x278b: 0x0001,
+ 0x278c: 0x0001, 0x278d: 0x0001, 0x278e: 0x0001, 0x278f: 0x0001, 0x2790: 0x0001, 0x2791: 0x0001,
+ 0x2792: 0x0001, 0x2793: 0x0001, 0x2794: 0x0001, 0x2795: 0x0001, 0x2796: 0x0001, 0x2797: 0x0001,
+ 0x2798: 0x0001, 0x2799: 0x0001, 0x279a: 0x0001, 0x279b: 0x0001, 0x279c: 0x0001, 0x279d: 0x0001,
+ 0x279e: 0x0001, 0x279f: 0x0001, 0x27a0: 0x0001, 0x27a1: 0x0001, 0x27a2: 0x0001, 0x27a3: 0x0001,
+ 0x27a4: 0x0001, 0x27a5: 0x0001, 0x27a6: 0x0001, 0x27a7: 0x0001, 0x27a8: 0x0001, 0x27a9: 0x0001,
+ 0x27aa: 0x0001, 0x27ab: 0x0001, 0x27ac: 0x0001, 0x27ad: 0x0001, 0x27ae: 0x0001, 0x27af: 0x0001,
+ 0x27b0: 0x0001, 0x27b1: 0x0001, 0x27b2: 0x0001, 0x27b3: 0x0001, 0x27b4: 0x0001, 0x27b5: 0x0001,
+ 0x27b6: 0x0001, 0x27b7: 0x0001, 0x27b8: 0x0001, 0x27b9: 0x0001, 0x27ba: 0x0001, 0x27bb: 0x0001,
+ 0x27bc: 0x0001, 0x27bd: 0x0001, 0x27be: 0x0001, 0x27bf: 0x0001,
+ // Block 0x9f, offset 0x27c0
+ 0x27c0: 0x0001, 0x27c1: 0x0001, 0x27c2: 0x0001, 0x27c3: 0x0001, 0x27c4: 0x0001, 0x27c5: 0x0001,
+ 0x27c6: 0x0001, 0x27c7: 0x0001, 0x27c8: 0x0001, 0x27c9: 0x0001, 0x27ca: 0x0001, 0x27cb: 0x0001,
+ 0x27cc: 0x0001, 0x27cd: 0x0001, 0x27ce: 0x0001, 0x27cf: 0x0001, 0x27d0: 0x0001, 0x27d1: 0x0001,
+ 0x27d2: 0x0001, 0x27d3: 0x0001, 0x27d4: 0x0001, 0x27d5: 0x0001, 0x27d6: 0x0001, 0x27d7: 0x0001,
+ 0x27d8: 0x0001, 0x27d9: 0x0001, 0x27da: 0x0001, 0x27db: 0x0001, 0x27dc: 0x0001, 0x27dd: 0x0001,
+ 0x27de: 0x0001, 0x27df: 0x000a, 0x27e0: 0x0001, 0x27e1: 0x0001, 0x27e2: 0x0001, 0x27e3: 0x0001,
+ 0x27e4: 0x0001, 0x27e5: 0x0001, 0x27e6: 0x0001, 0x27e7: 0x0001, 0x27e8: 0x0001, 0x27e9: 0x0001,
+ 0x27ea: 0x0001, 0x27eb: 0x0001, 0x27ec: 0x0001, 0x27ed: 0x0001, 0x27ee: 0x0001, 0x27ef: 0x0001,
+ 0x27f0: 0x0001, 0x27f1: 0x0001, 0x27f2: 0x0001, 0x27f3: 0x0001, 0x27f4: 0x0001, 0x27f5: 0x0001,
+ 0x27f6: 0x0001, 0x27f7: 0x0001, 0x27f8: 0x0001, 0x27f9: 0x0001, 0x27fa: 0x0001, 0x27fb: 0x0001,
+ 0x27fc: 0x0001, 0x27fd: 0x0001, 0x27fe: 0x0001, 0x27ff: 0x0001,
+ // Block 0xa0, offset 0x2800
+ 0x2800: 0x0001, 0x2801: 0x000c, 0x2802: 0x000c, 0x2803: 0x000c, 0x2804: 0x0001, 0x2805: 0x000c,
+ 0x2806: 0x000c, 0x2807: 0x0001, 0x2808: 0x0001, 0x2809: 0x0001, 0x280a: 0x0001, 0x280b: 0x0001,
+ 0x280c: 0x000c, 0x280d: 0x000c, 0x280e: 0x000c, 0x280f: 0x000c, 0x2810: 0x0001, 0x2811: 0x0001,
+ 0x2812: 0x0001, 0x2813: 0x0001, 0x2814: 0x0001, 0x2815: 0x0001, 0x2816: 0x0001, 0x2817: 0x0001,
+ 0x2818: 0x0001, 0x2819: 0x0001, 0x281a: 0x0001, 0x281b: 0x0001, 0x281c: 0x0001, 0x281d: 0x0001,
+ 0x281e: 0x0001, 0x281f: 0x0001, 0x2820: 0x0001, 0x2821: 0x0001, 0x2822: 0x0001, 0x2823: 0x0001,
+ 0x2824: 0x0001, 0x2825: 0x0001, 0x2826: 0x0001, 0x2827: 0x0001, 0x2828: 0x0001, 0x2829: 0x0001,
+ 0x282a: 0x0001, 0x282b: 0x0001, 0x282c: 0x0001, 0x282d: 0x0001, 0x282e: 0x0001, 0x282f: 0x0001,
+ 0x2830: 0x0001, 0x2831: 0x0001, 0x2832: 0x0001, 0x2833: 0x0001, 0x2834: 0x0001, 0x2835: 0x0001,
+ 0x2836: 0x0001, 0x2837: 0x0001, 0x2838: 0x000c, 0x2839: 0x000c, 0x283a: 0x000c, 0x283b: 0x0001,
+ 0x283c: 0x0001, 0x283d: 0x0001, 0x283e: 0x0001, 0x283f: 0x000c,
+ // Block 0xa1, offset 0x2840
+ 0x2840: 0x0001, 0x2841: 0x0001, 0x2842: 0x0001, 0x2843: 0x0001, 0x2844: 0x0001, 0x2845: 0x0001,
+ 0x2846: 0x0001, 0x2847: 0x0001, 0x2848: 0x0001, 0x2849: 0x0001, 0x284a: 0x0001, 0x284b: 0x0001,
+ 0x284c: 0x0001, 0x284d: 0x0001, 0x284e: 0x0001, 0x284f: 0x0001, 0x2850: 0x0001, 0x2851: 0x0001,
+ 0x2852: 0x0001, 0x2853: 0x0001, 0x2854: 0x0001, 0x2855: 0x0001, 0x2856: 0x0001, 0x2857: 0x0001,
+ 0x2858: 0x0001, 0x2859: 0x0001, 0x285a: 0x0001, 0x285b: 0x0001, 0x285c: 0x0001, 0x285d: 0x0001,
+ 0x285e: 0x0001, 0x285f: 0x0001, 0x2860: 0x0001, 0x2861: 0x0001, 0x2862: 0x0001, 0x2863: 0x0001,
+ 0x2864: 0x0001, 0x2865: 0x000c, 0x2866: 0x000c, 0x2867: 0x0001, 0x2868: 0x0001, 0x2869: 0x0001,
+ 0x286a: 0x0001, 0x286b: 0x0001, 0x286c: 0x0001, 0x286d: 0x0001, 0x286e: 0x0001, 0x286f: 0x0001,
+ 0x2870: 0x0001, 0x2871: 0x0001, 0x2872: 0x0001, 0x2873: 0x0001, 0x2874: 0x0001, 0x2875: 0x0001,
+ 0x2876: 0x0001, 0x2877: 0x0001, 0x2878: 0x0001, 0x2879: 0x0001, 0x287a: 0x0001, 0x287b: 0x0001,
+ 0x287c: 0x0001, 0x287d: 0x0001, 0x287e: 0x0001, 0x287f: 0x0001,
+ // Block 0xa2, offset 0x2880
+ 0x2880: 0x0001, 0x2881: 0x0001, 0x2882: 0x0001, 0x2883: 0x0001, 0x2884: 0x0001, 0x2885: 0x0001,
+ 0x2886: 0x0001, 0x2887: 0x0001, 0x2888: 0x0001, 0x2889: 0x0001, 0x288a: 0x0001, 0x288b: 0x0001,
+ 0x288c: 0x0001, 0x288d: 0x0001, 0x288e: 0x0001, 0x288f: 0x0001, 0x2890: 0x0001, 0x2891: 0x0001,
+ 0x2892: 0x0001, 0x2893: 0x0001, 0x2894: 0x0001, 0x2895: 0x0001, 0x2896: 0x0001, 0x2897: 0x0001,
+ 0x2898: 0x0001, 0x2899: 0x0001, 0x289a: 0x0001, 0x289b: 0x0001, 0x289c: 0x0001, 0x289d: 0x0001,
+ 0x289e: 0x0001, 0x289f: 0x0001, 0x28a0: 0x0001, 0x28a1: 0x0001, 0x28a2: 0x0001, 0x28a3: 0x0001,
+ 0x28a4: 0x0001, 0x28a5: 0x0001, 0x28a6: 0x0001, 0x28a7: 0x0001, 0x28a8: 0x0001, 0x28a9: 0x0001,
+ 0x28aa: 0x0001, 0x28ab: 0x0001, 0x28ac: 0x0001, 0x28ad: 0x0001, 0x28ae: 0x0001, 0x28af: 0x0001,
+ 0x28b0: 0x0001, 0x28b1: 0x0001, 0x28b2: 0x0001, 0x28b3: 0x0001, 0x28b4: 0x0001, 0x28b5: 0x0001,
+ 0x28b6: 0x0001, 0x28b7: 0x0001, 0x28b8: 0x0001, 0x28b9: 0x000a, 0x28ba: 0x000a, 0x28bb: 0x000a,
+ 0x28bc: 0x000a, 0x28bd: 0x000a, 0x28be: 0x000a, 0x28bf: 0x000a,
+ // Block 0xa3, offset 0x28c0
+ 0x28c0: 0x000d, 0x28c1: 0x000d, 0x28c2: 0x000d, 0x28c3: 0x000d, 0x28c4: 0x000d, 0x28c5: 0x000d,
+ 0x28c6: 0x000d, 0x28c7: 0x000d, 0x28c8: 0x000d, 0x28c9: 0x000d, 0x28ca: 0x000d, 0x28cb: 0x000d,
+ 0x28cc: 0x000d, 0x28cd: 0x000d, 0x28ce: 0x000d, 0x28cf: 0x000d, 0x28d0: 0x000d, 0x28d1: 0x000d,
+ 0x28d2: 0x000d, 0x28d3: 0x000d, 0x28d4: 0x000d, 0x28d5: 0x000d, 0x28d6: 0x000d, 0x28d7: 0x000d,
+ 0x28d8: 0x000d, 0x28d9: 0x000d, 0x28da: 0x000d, 0x28db: 0x000d, 0x28dc: 0x000d, 0x28dd: 0x000d,
+ 0x28de: 0x000d, 0x28df: 0x000d, 0x28e0: 0x000d, 0x28e1: 0x000d, 0x28e2: 0x000d, 0x28e3: 0x000d,
+ 0x28e4: 0x000c, 0x28e5: 0x000c, 0x28e6: 0x000c, 0x28e7: 0x000c, 0x28e8: 0x000d, 0x28e9: 0x000d,
+ 0x28ea: 0x000d, 0x28eb: 0x000d, 0x28ec: 0x000d, 0x28ed: 0x000d, 0x28ee: 0x000d, 0x28ef: 0x000d,
+ 0x28f0: 0x0005, 0x28f1: 0x0005, 0x28f2: 0x0005, 0x28f3: 0x0005, 0x28f4: 0x0005, 0x28f5: 0x0005,
+ 0x28f6: 0x0005, 0x28f7: 0x0005, 0x28f8: 0x0005, 0x28f9: 0x0005, 0x28fa: 0x000d, 0x28fb: 0x000d,
+ 0x28fc: 0x000d, 0x28fd: 0x000d, 0x28fe: 0x000d, 0x28ff: 0x000d,
+ // Block 0xa4, offset 0x2900
+ 0x2900: 0x0001, 0x2901: 0x0001, 0x2902: 0x0001, 0x2903: 0x0001, 0x2904: 0x0001, 0x2905: 0x0001,
+ 0x2906: 0x0001, 0x2907: 0x0001, 0x2908: 0x0001, 0x2909: 0x0001, 0x290a: 0x0001, 0x290b: 0x0001,
+ 0x290c: 0x0001, 0x290d: 0x0001, 0x290e: 0x0001, 0x290f: 0x0001, 0x2910: 0x0001, 0x2911: 0x0001,
+ 0x2912: 0x0001, 0x2913: 0x0001, 0x2914: 0x0001, 0x2915: 0x0001, 0x2916: 0x0001, 0x2917: 0x0001,
+ 0x2918: 0x0001, 0x2919: 0x0001, 0x291a: 0x0001, 0x291b: 0x0001, 0x291c: 0x0001, 0x291d: 0x0001,
+ 0x291e: 0x0001, 0x291f: 0x0001, 0x2920: 0x0005, 0x2921: 0x0005, 0x2922: 0x0005, 0x2923: 0x0005,
+ 0x2924: 0x0005, 0x2925: 0x0005, 0x2926: 0x0005, 0x2927: 0x0005, 0x2928: 0x0005, 0x2929: 0x0005,
+ 0x292a: 0x0005, 0x292b: 0x0005, 0x292c: 0x0005, 0x292d: 0x0005, 0x292e: 0x0005, 0x292f: 0x0005,
+ 0x2930: 0x0005, 0x2931: 0x0005, 0x2932: 0x0005, 0x2933: 0x0005, 0x2934: 0x0005, 0x2935: 0x0005,
+ 0x2936: 0x0005, 0x2937: 0x0005, 0x2938: 0x0005, 0x2939: 0x0005, 0x293a: 0x0005, 0x293b: 0x0005,
+ 0x293c: 0x0005, 0x293d: 0x0005, 0x293e: 0x0005, 0x293f: 0x0001,
+ // Block 0xa5, offset 0x2940
+ 0x2940: 0x0001, 0x2941: 0x0001, 0x2942: 0x0001, 0x2943: 0x0001, 0x2944: 0x0001, 0x2945: 0x0001,
+ 0x2946: 0x0001, 0x2947: 0x0001, 0x2948: 0x0001, 0x2949: 0x0001, 0x294a: 0x0001, 0x294b: 0x0001,
+ 0x294c: 0x0001, 0x294d: 0x0001, 0x294e: 0x0001, 0x294f: 0x0001, 0x2950: 0x0001, 0x2951: 0x0001,
+ 0x2952: 0x0001, 0x2953: 0x0001, 0x2954: 0x0001, 0x2955: 0x0001, 0x2956: 0x0001, 0x2957: 0x0001,
+ 0x2958: 0x0001, 0x2959: 0x0001, 0x295a: 0x0001, 0x295b: 0x0001, 0x295c: 0x0001, 0x295d: 0x0001,
+ 0x295e: 0x0001, 0x295f: 0x0001, 0x2960: 0x0001, 0x2961: 0x0001, 0x2962: 0x0001, 0x2963: 0x0001,
+ 0x2964: 0x0001, 0x2965: 0x0001, 0x2966: 0x0001, 0x2967: 0x0001, 0x2968: 0x0001, 0x2969: 0x0001,
+ 0x296a: 0x0001, 0x296b: 0x000c, 0x296c: 0x000c, 0x296d: 0x0001, 0x296e: 0x0001, 0x296f: 0x0001,
+ 0x2970: 0x0001, 0x2971: 0x0001, 0x2972: 0x0001, 0x2973: 0x0001, 0x2974: 0x0001, 0x2975: 0x0001,
+ 0x2976: 0x0001, 0x2977: 0x0001, 0x2978: 0x0001, 0x2979: 0x0001, 0x297a: 0x0001, 0x297b: 0x0001,
+ 0x297c: 0x0001, 0x297d: 0x0001, 0x297e: 0x0001, 0x297f: 0x0001,
+ // Block 0xa6, offset 0x2980
+ 0x2980: 0x0001, 0x2981: 0x0001, 0x2982: 0x0001, 0x2983: 0x0001, 0x2984: 0x0001, 0x2985: 0x0001,
+ 0x2986: 0x0001, 0x2987: 0x0001, 0x2988: 0x0001, 0x2989: 0x0001, 0x298a: 0x0001, 0x298b: 0x0001,
+ 0x298c: 0x0001, 0x298d: 0x0001, 0x298e: 0x0001, 0x298f: 0x0001, 0x2990: 0x0001, 0x2991: 0x0001,
+ 0x2992: 0x0001, 0x2993: 0x0001, 0x2994: 0x0001, 0x2995: 0x0001, 0x2996: 0x0001, 0x2997: 0x0001,
+ 0x2998: 0x0001, 0x2999: 0x0001, 0x299a: 0x0001, 0x299b: 0x0001, 0x299c: 0x0001, 0x299d: 0x0001,
+ 0x299e: 0x0001, 0x299f: 0x0001, 0x29a0: 0x0001, 0x29a1: 0x0001, 0x29a2: 0x0001, 0x29a3: 0x0001,
+ 0x29a4: 0x0001, 0x29a5: 0x0001, 0x29a6: 0x0001, 0x29a7: 0x0001, 0x29a8: 0x0001, 0x29a9: 0x0001,
+ 0x29aa: 0x0001, 0x29ab: 0x0001, 0x29ac: 0x0001, 0x29ad: 0x0001, 0x29ae: 0x0001, 0x29af: 0x0001,
+ 0x29b0: 0x000d, 0x29b1: 0x000d, 0x29b2: 0x000d, 0x29b3: 0x000d, 0x29b4: 0x000d, 0x29b5: 0x000d,
+ 0x29b6: 0x000d, 0x29b7: 0x000d, 0x29b8: 0x000d, 0x29b9: 0x000d, 0x29ba: 0x000d, 0x29bb: 0x000d,
+ 0x29bc: 0x000d, 0x29bd: 0x000d, 0x29be: 0x000d, 0x29bf: 0x000d,
+ // Block 0xa7, offset 0x29c0
+ 0x29c0: 0x000d, 0x29c1: 0x000d, 0x29c2: 0x000d, 0x29c3: 0x000d, 0x29c4: 0x000d, 0x29c5: 0x000d,
+ 0x29c6: 0x000c, 0x29c7: 0x000c, 0x29c8: 0x000c, 0x29c9: 0x000c, 0x29ca: 0x000c, 0x29cb: 0x000c,
+ 0x29cc: 0x000c, 0x29cd: 0x000c, 0x29ce: 0x000c, 0x29cf: 0x000c, 0x29d0: 0x000c, 0x29d1: 0x000d,
+ 0x29d2: 0x000d, 0x29d3: 0x000d, 0x29d4: 0x000d, 0x29d5: 0x000d, 0x29d6: 0x000d, 0x29d7: 0x000d,
+ 0x29d8: 0x000d, 0x29d9: 0x000d, 0x29da: 0x000d, 0x29db: 0x000d, 0x29dc: 0x000d, 0x29dd: 0x000d,
+ 0x29de: 0x000d, 0x29df: 0x000d, 0x29e0: 0x000d, 0x29e1: 0x000d, 0x29e2: 0x000d, 0x29e3: 0x000d,
+ 0x29e4: 0x000d, 0x29e5: 0x000d, 0x29e6: 0x000d, 0x29e7: 0x000d, 0x29e8: 0x000d, 0x29e9: 0x000d,
+ 0x29ea: 0x000d, 0x29eb: 0x000d, 0x29ec: 0x000d, 0x29ed: 0x000d, 0x29ee: 0x000d, 0x29ef: 0x000d,
+ 0x29f0: 0x0001, 0x29f1: 0x0001, 0x29f2: 0x0001, 0x29f3: 0x0001, 0x29f4: 0x0001, 0x29f5: 0x0001,
+ 0x29f6: 0x0001, 0x29f7: 0x0001, 0x29f8: 0x0001, 0x29f9: 0x0001, 0x29fa: 0x0001, 0x29fb: 0x0001,
+ 0x29fc: 0x0001, 0x29fd: 0x0001, 0x29fe: 0x0001, 0x29ff: 0x0001,
+ // Block 0xa8, offset 0x2a00
+ 0x2a01: 0x000c,
+ 0x2a38: 0x000c, 0x2a39: 0x000c, 0x2a3a: 0x000c, 0x2a3b: 0x000c,
+ 0x2a3c: 0x000c, 0x2a3d: 0x000c, 0x2a3e: 0x000c, 0x2a3f: 0x000c,
+ // Block 0xa9, offset 0x2a40
+ 0x2a40: 0x000c, 0x2a41: 0x000c, 0x2a42: 0x000c, 0x2a43: 0x000c, 0x2a44: 0x000c, 0x2a45: 0x000c,
+ 0x2a46: 0x000c,
+ 0x2a52: 0x000a, 0x2a53: 0x000a, 0x2a54: 0x000a, 0x2a55: 0x000a, 0x2a56: 0x000a, 0x2a57: 0x000a,
+ 0x2a58: 0x000a, 0x2a59: 0x000a, 0x2a5a: 0x000a, 0x2a5b: 0x000a, 0x2a5c: 0x000a, 0x2a5d: 0x000a,
+ 0x2a5e: 0x000a, 0x2a5f: 0x000a, 0x2a60: 0x000a, 0x2a61: 0x000a, 0x2a62: 0x000a, 0x2a63: 0x000a,
+ 0x2a64: 0x000a, 0x2a65: 0x000a,
+ 0x2a7f: 0x000c,
+ // Block 0xaa, offset 0x2a80
+ 0x2a80: 0x000c, 0x2a81: 0x000c,
+ 0x2ab3: 0x000c, 0x2ab4: 0x000c, 0x2ab5: 0x000c,
+ 0x2ab6: 0x000c, 0x2ab9: 0x000c, 0x2aba: 0x000c,
+ // Block 0xab, offset 0x2ac0
+ 0x2ac0: 0x000c, 0x2ac1: 0x000c, 0x2ac2: 0x000c,
+ 0x2ae7: 0x000c, 0x2ae8: 0x000c, 0x2ae9: 0x000c,
+ 0x2aea: 0x000c, 0x2aeb: 0x000c, 0x2aed: 0x000c, 0x2aee: 0x000c, 0x2aef: 0x000c,
+ 0x2af0: 0x000c, 0x2af1: 0x000c, 0x2af2: 0x000c, 0x2af3: 0x000c, 0x2af4: 0x000c,
+ // Block 0xac, offset 0x2b00
+ 0x2b33: 0x000c,
+ // Block 0xad, offset 0x2b40
+ 0x2b40: 0x000c, 0x2b41: 0x000c,
+ 0x2b76: 0x000c, 0x2b77: 0x000c, 0x2b78: 0x000c, 0x2b79: 0x000c, 0x2b7a: 0x000c, 0x2b7b: 0x000c,
+ 0x2b7c: 0x000c, 0x2b7d: 0x000c, 0x2b7e: 0x000c,
+ // Block 0xae, offset 0x2b80
+ 0x2b89: 0x000c, 0x2b8a: 0x000c, 0x2b8b: 0x000c,
+ 0x2b8c: 0x000c, 0x2b8f: 0x000c,
+ // Block 0xaf, offset 0x2bc0
+ 0x2bef: 0x000c,
+ 0x2bf0: 0x000c, 0x2bf1: 0x000c, 0x2bf4: 0x000c,
+ 0x2bf6: 0x000c, 0x2bf7: 0x000c,
+ 0x2bfe: 0x000c,
+ // Block 0xb0, offset 0x2c00
+ 0x2c1f: 0x000c, 0x2c23: 0x000c,
+ 0x2c24: 0x000c, 0x2c25: 0x000c, 0x2c26: 0x000c, 0x2c27: 0x000c, 0x2c28: 0x000c, 0x2c29: 0x000c,
+ 0x2c2a: 0x000c,
+ // Block 0xb1, offset 0x2c40
+ 0x2c40: 0x000c,
+ 0x2c66: 0x000c, 0x2c67: 0x000c, 0x2c68: 0x000c, 0x2c69: 0x000c,
+ 0x2c6a: 0x000c, 0x2c6b: 0x000c, 0x2c6c: 0x000c,
+ 0x2c70: 0x000c, 0x2c71: 0x000c, 0x2c72: 0x000c, 0x2c73: 0x000c, 0x2c74: 0x000c,
+ // Block 0xb2, offset 0x2c80
+ 0x2cb8: 0x000c, 0x2cb9: 0x000c, 0x2cba: 0x000c, 0x2cbb: 0x000c,
+ 0x2cbc: 0x000c, 0x2cbd: 0x000c, 0x2cbe: 0x000c, 0x2cbf: 0x000c,
+ // Block 0xb3, offset 0x2cc0
+ 0x2cc2: 0x000c, 0x2cc3: 0x000c, 0x2cc4: 0x000c,
+ 0x2cc6: 0x000c,
+ 0x2cde: 0x000c,
+ // Block 0xb4, offset 0x2d00
+ 0x2d33: 0x000c, 0x2d34: 0x000c, 0x2d35: 0x000c,
+ 0x2d36: 0x000c, 0x2d37: 0x000c, 0x2d38: 0x000c, 0x2d3a: 0x000c,
+ 0x2d3f: 0x000c,
+ // Block 0xb5, offset 0x2d40
+ 0x2d40: 0x000c, 0x2d42: 0x000c, 0x2d43: 0x000c,
+ // Block 0xb6, offset 0x2d80
+ 0x2db2: 0x000c, 0x2db3: 0x000c, 0x2db4: 0x000c, 0x2db5: 0x000c,
+ 0x2dbc: 0x000c, 0x2dbd: 0x000c, 0x2dbf: 0x000c,
+ // Block 0xb7, offset 0x2dc0
+ 0x2dc0: 0x000c,
+ 0x2ddc: 0x000c, 0x2ddd: 0x000c,
+ // Block 0xb8, offset 0x2e00
+ 0x2e33: 0x000c, 0x2e34: 0x000c, 0x2e35: 0x000c,
+ 0x2e36: 0x000c, 0x2e37: 0x000c, 0x2e38: 0x000c, 0x2e39: 0x000c, 0x2e3a: 0x000c,
+ 0x2e3d: 0x000c, 0x2e3f: 0x000c,
+ // Block 0xb9, offset 0x2e40
+ 0x2e40: 0x000c,
+ 0x2e60: 0x000a, 0x2e61: 0x000a, 0x2e62: 0x000a, 0x2e63: 0x000a,
+ 0x2e64: 0x000a, 0x2e65: 0x000a, 0x2e66: 0x000a, 0x2e67: 0x000a, 0x2e68: 0x000a, 0x2e69: 0x000a,
+ 0x2e6a: 0x000a, 0x2e6b: 0x000a, 0x2e6c: 0x000a,
+ // Block 0xba, offset 0x2e80
+ 0x2eab: 0x000c, 0x2ead: 0x000c,
+ 0x2eb0: 0x000c, 0x2eb1: 0x000c, 0x2eb2: 0x000c, 0x2eb3: 0x000c, 0x2eb4: 0x000c, 0x2eb5: 0x000c,
+ 0x2eb7: 0x000c,
+ // Block 0xbb, offset 0x2ec0
+ 0x2edd: 0x000c,
+ 0x2ede: 0x000c, 0x2edf: 0x000c, 0x2ee2: 0x000c, 0x2ee3: 0x000c,
+ 0x2ee4: 0x000c, 0x2ee5: 0x000c, 0x2ee7: 0x000c, 0x2ee8: 0x000c, 0x2ee9: 0x000c,
+ 0x2eea: 0x000c, 0x2eeb: 0x000c,
+ // Block 0xbc, offset 0x2f00
+ 0x2f2f: 0x000c,
+ 0x2f30: 0x000c, 0x2f31: 0x000c, 0x2f32: 0x000c, 0x2f33: 0x000c, 0x2f34: 0x000c, 0x2f35: 0x000c,
+ 0x2f36: 0x000c, 0x2f37: 0x000c, 0x2f39: 0x000c, 0x2f3a: 0x000c,
+ // Block 0xbd, offset 0x2f40
+ 0x2f7b: 0x000c,
+ 0x2f7c: 0x000c, 0x2f7e: 0x000c,
+ // Block 0xbe, offset 0x2f80
+ 0x2f83: 0x000c,
+ // Block 0xbf, offset 0x2fc0
+ 0x2fd4: 0x000c, 0x2fd5: 0x000c, 0x2fd6: 0x000c, 0x2fd7: 0x000c,
+ 0x2fda: 0x000c, 0x2fdb: 0x000c,
+ 0x2fe0: 0x000c,
+ // Block 0xc0, offset 0x3000
+ 0x3001: 0x000c, 0x3002: 0x000c, 0x3003: 0x000c, 0x3004: 0x000c, 0x3005: 0x000c,
+ 0x3006: 0x000c, 0x3009: 0x000c, 0x300a: 0x000c,
+ 0x3033: 0x000c, 0x3034: 0x000c, 0x3035: 0x000c,
+ 0x3036: 0x000c, 0x3037: 0x000c, 0x3038: 0x000c, 0x303b: 0x000c,
+ 0x303c: 0x000c, 0x303d: 0x000c, 0x303e: 0x000c,
+ // Block 0xc1, offset 0x3040
+ 0x3047: 0x000c,
+ 0x3051: 0x000c,
+ 0x3052: 0x000c, 0x3053: 0x000c, 0x3054: 0x000c, 0x3055: 0x000c, 0x3056: 0x000c,
+ 0x3059: 0x000c, 0x305a: 0x000c, 0x305b: 0x000c,
+ // Block 0xc2, offset 0x3080
+ 0x308a: 0x000c, 0x308b: 0x000c,
+ 0x308c: 0x000c, 0x308d: 0x000c, 0x308e: 0x000c, 0x308f: 0x000c, 0x3090: 0x000c, 0x3091: 0x000c,
+ 0x3092: 0x000c, 0x3093: 0x000c, 0x3094: 0x000c, 0x3095: 0x000c, 0x3096: 0x000c,
+ 0x3098: 0x000c, 0x3099: 0x000c,
+ // Block 0xc3, offset 0x30c0
+ 0x30f0: 0x000c, 0x30f1: 0x000c, 0x30f2: 0x000c, 0x30f3: 0x000c, 0x30f4: 0x000c, 0x30f5: 0x000c,
+ 0x30f6: 0x000c, 0x30f8: 0x000c, 0x30f9: 0x000c, 0x30fa: 0x000c, 0x30fb: 0x000c,
+ 0x30fc: 0x000c, 0x30fd: 0x000c,
+ // Block 0xc4, offset 0x3100
+ 0x3112: 0x000c, 0x3113: 0x000c, 0x3114: 0x000c, 0x3115: 0x000c, 0x3116: 0x000c, 0x3117: 0x000c,
+ 0x3118: 0x000c, 0x3119: 0x000c, 0x311a: 0x000c, 0x311b: 0x000c, 0x311c: 0x000c, 0x311d: 0x000c,
+ 0x311e: 0x000c, 0x311f: 0x000c, 0x3120: 0x000c, 0x3121: 0x000c, 0x3122: 0x000c, 0x3123: 0x000c,
+ 0x3124: 0x000c, 0x3125: 0x000c, 0x3126: 0x000c, 0x3127: 0x000c,
+ 0x312a: 0x000c, 0x312b: 0x000c, 0x312c: 0x000c, 0x312d: 0x000c, 0x312e: 0x000c, 0x312f: 0x000c,
+ 0x3130: 0x000c, 0x3132: 0x000c, 0x3133: 0x000c, 0x3135: 0x000c,
+ 0x3136: 0x000c,
+ // Block 0xc5, offset 0x3140
+ 0x3171: 0x000c, 0x3172: 0x000c, 0x3173: 0x000c, 0x3174: 0x000c, 0x3175: 0x000c,
+ 0x3176: 0x000c, 0x317a: 0x000c,
+ 0x317c: 0x000c, 0x317d: 0x000c, 0x317f: 0x000c,
+ // Block 0xc6, offset 0x3180
+ 0x3180: 0x000c, 0x3181: 0x000c, 0x3182: 0x000c, 0x3183: 0x000c, 0x3184: 0x000c, 0x3185: 0x000c,
+ 0x3187: 0x000c,
+ // Block 0xc7, offset 0x31c0
+ 0x31d0: 0x000c, 0x31d1: 0x000c,
+ 0x31d5: 0x000c, 0x31d7: 0x000c,
+ // Block 0xc8, offset 0x3200
+ 0x3233: 0x000c, 0x3234: 0x000c,
+ // Block 0xc9, offset 0x3240
+ 0x3255: 0x000a, 0x3256: 0x000a, 0x3257: 0x000a,
+ 0x3258: 0x000a, 0x3259: 0x000a, 0x325a: 0x000a, 0x325b: 0x000a, 0x325c: 0x000a, 0x325d: 0x0004,
+ 0x325e: 0x0004, 0x325f: 0x0004, 0x3260: 0x0004, 0x3261: 0x000a, 0x3262: 0x000a, 0x3263: 0x000a,
+ 0x3264: 0x000a, 0x3265: 0x000a, 0x3266: 0x000a, 0x3267: 0x000a, 0x3268: 0x000a, 0x3269: 0x000a,
+ 0x326a: 0x000a, 0x326b: 0x000a, 0x326c: 0x000a, 0x326d: 0x000a, 0x326e: 0x000a, 0x326f: 0x000a,
+ 0x3270: 0x000a, 0x3271: 0x000a,
+ // Block 0xca, offset 0x3280
+ 0x32b0: 0x000c, 0x32b1: 0x000c, 0x32b2: 0x000c, 0x32b3: 0x000c, 0x32b4: 0x000c,
+ // Block 0xcb, offset 0x32c0
+ 0x32f0: 0x000c, 0x32f1: 0x000c, 0x32f2: 0x000c, 0x32f3: 0x000c, 0x32f4: 0x000c, 0x32f5: 0x000c,
+ 0x32f6: 0x000c,
+ // Block 0xcc, offset 0x3300
+ 0x330f: 0x000c,
+ // Block 0xcd, offset 0x3340
+ 0x334f: 0x000c, 0x3350: 0x000c, 0x3351: 0x000c,
+ 0x3352: 0x000c,
+ // Block 0xce, offset 0x3380
+ 0x33a2: 0x000a,
+ 0x33a4: 0x000c,
+ // Block 0xcf, offset 0x33c0
+ 0x33dd: 0x000c,
+ 0x33de: 0x000c, 0x33e0: 0x000b, 0x33e1: 0x000b, 0x33e2: 0x000b, 0x33e3: 0x000b,
+ // Block 0xd0, offset 0x3400
+ 0x3427: 0x000c, 0x3428: 0x000c, 0x3429: 0x000c,
+ 0x3433: 0x000b, 0x3434: 0x000b, 0x3435: 0x000b,
+ 0x3436: 0x000b, 0x3437: 0x000b, 0x3438: 0x000b, 0x3439: 0x000b, 0x343a: 0x000b, 0x343b: 0x000c,
+ 0x343c: 0x000c, 0x343d: 0x000c, 0x343e: 0x000c, 0x343f: 0x000c,
+ // Block 0xd1, offset 0x3440
+ 0x3440: 0x000c, 0x3441: 0x000c, 0x3442: 0x000c, 0x3445: 0x000c,
+ 0x3446: 0x000c, 0x3447: 0x000c, 0x3448: 0x000c, 0x3449: 0x000c, 0x344a: 0x000c, 0x344b: 0x000c,
+ 0x346a: 0x000c, 0x346b: 0x000c, 0x346c: 0x000c, 0x346d: 0x000c,
+ // Block 0xd2, offset 0x3480
+ 0x3480: 0x000a, 0x3481: 0x000a, 0x3482: 0x000c, 0x3483: 0x000c, 0x3484: 0x000c, 0x3485: 0x000a,
+ // Block 0xd3, offset 0x34c0
+ 0x34c0: 0x000a, 0x34c1: 0x000a, 0x34c2: 0x000a, 0x34c3: 0x000a, 0x34c4: 0x000a, 0x34c5: 0x000a,
+ 0x34c6: 0x000a, 0x34c7: 0x000a, 0x34c8: 0x000a, 0x34c9: 0x000a, 0x34ca: 0x000a, 0x34cb: 0x000a,
+ 0x34cc: 0x000a, 0x34cd: 0x000a, 0x34ce: 0x000a, 0x34cf: 0x000a, 0x34d0: 0x000a, 0x34d1: 0x000a,
+ 0x34d2: 0x000a, 0x34d3: 0x000a, 0x34d4: 0x000a, 0x34d5: 0x000a, 0x34d6: 0x000a,
+ // Block 0xd4, offset 0x3500
+ 0x351b: 0x000a,
+ // Block 0xd5, offset 0x3540
+ 0x3555: 0x000a,
+ // Block 0xd6, offset 0x3580
+ 0x358f: 0x000a,
+ // Block 0xd7, offset 0x35c0
+ 0x35c9: 0x000a,
+ // Block 0xd8, offset 0x3600
+ 0x3603: 0x000a,
+ 0x360e: 0x0002, 0x360f: 0x0002, 0x3610: 0x0002, 0x3611: 0x0002,
+ 0x3612: 0x0002, 0x3613: 0x0002, 0x3614: 0x0002, 0x3615: 0x0002, 0x3616: 0x0002, 0x3617: 0x0002,
+ 0x3618: 0x0002, 0x3619: 0x0002, 0x361a: 0x0002, 0x361b: 0x0002, 0x361c: 0x0002, 0x361d: 0x0002,
+ 0x361e: 0x0002, 0x361f: 0x0002, 0x3620: 0x0002, 0x3621: 0x0002, 0x3622: 0x0002, 0x3623: 0x0002,
+ 0x3624: 0x0002, 0x3625: 0x0002, 0x3626: 0x0002, 0x3627: 0x0002, 0x3628: 0x0002, 0x3629: 0x0002,
+ 0x362a: 0x0002, 0x362b: 0x0002, 0x362c: 0x0002, 0x362d: 0x0002, 0x362e: 0x0002, 0x362f: 0x0002,
+ 0x3630: 0x0002, 0x3631: 0x0002, 0x3632: 0x0002, 0x3633: 0x0002, 0x3634: 0x0002, 0x3635: 0x0002,
+ 0x3636: 0x0002, 0x3637: 0x0002, 0x3638: 0x0002, 0x3639: 0x0002, 0x363a: 0x0002, 0x363b: 0x0002,
+ 0x363c: 0x0002, 0x363d: 0x0002, 0x363e: 0x0002, 0x363f: 0x0002,
+ // Block 0xd9, offset 0x3640
+ 0x3640: 0x000c, 0x3641: 0x000c, 0x3642: 0x000c, 0x3643: 0x000c, 0x3644: 0x000c, 0x3645: 0x000c,
+ 0x3646: 0x000c, 0x3647: 0x000c, 0x3648: 0x000c, 0x3649: 0x000c, 0x364a: 0x000c, 0x364b: 0x000c,
+ 0x364c: 0x000c, 0x364d: 0x000c, 0x364e: 0x000c, 0x364f: 0x000c, 0x3650: 0x000c, 0x3651: 0x000c,
+ 0x3652: 0x000c, 0x3653: 0x000c, 0x3654: 0x000c, 0x3655: 0x000c, 0x3656: 0x000c, 0x3657: 0x000c,
+ 0x3658: 0x000c, 0x3659: 0x000c, 0x365a: 0x000c, 0x365b: 0x000c, 0x365c: 0x000c, 0x365d: 0x000c,
+ 0x365e: 0x000c, 0x365f: 0x000c, 0x3660: 0x000c, 0x3661: 0x000c, 0x3662: 0x000c, 0x3663: 0x000c,
+ 0x3664: 0x000c, 0x3665: 0x000c, 0x3666: 0x000c, 0x3667: 0x000c, 0x3668: 0x000c, 0x3669: 0x000c,
+ 0x366a: 0x000c, 0x366b: 0x000c, 0x366c: 0x000c, 0x366d: 0x000c, 0x366e: 0x000c, 0x366f: 0x000c,
+ 0x3670: 0x000c, 0x3671: 0x000c, 0x3672: 0x000c, 0x3673: 0x000c, 0x3674: 0x000c, 0x3675: 0x000c,
+ 0x3676: 0x000c, 0x367b: 0x000c,
+ 0x367c: 0x000c, 0x367d: 0x000c, 0x367e: 0x000c, 0x367f: 0x000c,
+ // Block 0xda, offset 0x3680
+ 0x3680: 0x000c, 0x3681: 0x000c, 0x3682: 0x000c, 0x3683: 0x000c, 0x3684: 0x000c, 0x3685: 0x000c,
+ 0x3686: 0x000c, 0x3687: 0x000c, 0x3688: 0x000c, 0x3689: 0x000c, 0x368a: 0x000c, 0x368b: 0x000c,
+ 0x368c: 0x000c, 0x368d: 0x000c, 0x368e: 0x000c, 0x368f: 0x000c, 0x3690: 0x000c, 0x3691: 0x000c,
+ 0x3692: 0x000c, 0x3693: 0x000c, 0x3694: 0x000c, 0x3695: 0x000c, 0x3696: 0x000c, 0x3697: 0x000c,
+ 0x3698: 0x000c, 0x3699: 0x000c, 0x369a: 0x000c, 0x369b: 0x000c, 0x369c: 0x000c, 0x369d: 0x000c,
+ 0x369e: 0x000c, 0x369f: 0x000c, 0x36a0: 0x000c, 0x36a1: 0x000c, 0x36a2: 0x000c, 0x36a3: 0x000c,
+ 0x36a4: 0x000c, 0x36a5: 0x000c, 0x36a6: 0x000c, 0x36a7: 0x000c, 0x36a8: 0x000c, 0x36a9: 0x000c,
+ 0x36aa: 0x000c, 0x36ab: 0x000c, 0x36ac: 0x000c,
+ 0x36b5: 0x000c,
+ // Block 0xdb, offset 0x36c0
+ 0x36c4: 0x000c,
+ 0x36db: 0x000c, 0x36dc: 0x000c, 0x36dd: 0x000c,
+ 0x36de: 0x000c, 0x36df: 0x000c, 0x36e1: 0x000c, 0x36e2: 0x000c, 0x36e3: 0x000c,
+ 0x36e4: 0x000c, 0x36e5: 0x000c, 0x36e6: 0x000c, 0x36e7: 0x000c, 0x36e8: 0x000c, 0x36e9: 0x000c,
+ 0x36ea: 0x000c, 0x36eb: 0x000c, 0x36ec: 0x000c, 0x36ed: 0x000c, 0x36ee: 0x000c, 0x36ef: 0x000c,
+ // Block 0xdc, offset 0x3700
+ 0x3700: 0x000c, 0x3701: 0x000c, 0x3702: 0x000c, 0x3703: 0x000c, 0x3704: 0x000c, 0x3705: 0x000c,
+ 0x3706: 0x000c, 0x3708: 0x000c, 0x3709: 0x000c, 0x370a: 0x000c, 0x370b: 0x000c,
+ 0x370c: 0x000c, 0x370d: 0x000c, 0x370e: 0x000c, 0x370f: 0x000c, 0x3710: 0x000c, 0x3711: 0x000c,
+ 0x3712: 0x000c, 0x3713: 0x000c, 0x3714: 0x000c, 0x3715: 0x000c, 0x3716: 0x000c, 0x3717: 0x000c,
+ 0x3718: 0x000c, 0x371b: 0x000c, 0x371c: 0x000c, 0x371d: 0x000c,
+ 0x371e: 0x000c, 0x371f: 0x000c, 0x3720: 0x000c, 0x3721: 0x000c, 0x3723: 0x000c,
+ 0x3724: 0x000c, 0x3726: 0x000c, 0x3727: 0x000c, 0x3728: 0x000c, 0x3729: 0x000c,
+ 0x372a: 0x000c,
+ // Block 0xdd, offset 0x3740
+ 0x376c: 0x000c, 0x376d: 0x000c, 0x376e: 0x000c, 0x376f: 0x000c,
+ 0x377f: 0x0004,
+ // Block 0xde, offset 0x3780
+ 0x3780: 0x0001, 0x3781: 0x0001, 0x3782: 0x0001, 0x3783: 0x0001, 0x3784: 0x0001, 0x3785: 0x0001,
+ 0x3786: 0x0001, 0x3787: 0x0001, 0x3788: 0x0001, 0x3789: 0x0001, 0x378a: 0x0001, 0x378b: 0x0001,
+ 0x378c: 0x0001, 0x378d: 0x0001, 0x378e: 0x0001, 0x378f: 0x0001, 0x3790: 0x000c, 0x3791: 0x000c,
+ 0x3792: 0x000c, 0x3793: 0x000c, 0x3794: 0x000c, 0x3795: 0x000c, 0x3796: 0x000c, 0x3797: 0x0001,
+ 0x3798: 0x0001, 0x3799: 0x0001, 0x379a: 0x0001, 0x379b: 0x0001, 0x379c: 0x0001, 0x379d: 0x0001,
+ 0x379e: 0x0001, 0x379f: 0x0001, 0x37a0: 0x0001, 0x37a1: 0x0001, 0x37a2: 0x0001, 0x37a3: 0x0001,
+ 0x37a4: 0x0001, 0x37a5: 0x0001, 0x37a6: 0x0001, 0x37a7: 0x0001, 0x37a8: 0x0001, 0x37a9: 0x0001,
+ 0x37aa: 0x0001, 0x37ab: 0x0001, 0x37ac: 0x0001, 0x37ad: 0x0001, 0x37ae: 0x0001, 0x37af: 0x0001,
+ 0x37b0: 0x0001, 0x37b1: 0x0001, 0x37b2: 0x0001, 0x37b3: 0x0001, 0x37b4: 0x0001, 0x37b5: 0x0001,
+ 0x37b6: 0x0001, 0x37b7: 0x0001, 0x37b8: 0x0001, 0x37b9: 0x0001, 0x37ba: 0x0001, 0x37bb: 0x0001,
+ 0x37bc: 0x0001, 0x37bd: 0x0001, 0x37be: 0x0001, 0x37bf: 0x0001,
+ // Block 0xdf, offset 0x37c0
+ 0x37c0: 0x0001, 0x37c1: 0x0001, 0x37c2: 0x0001, 0x37c3: 0x0001, 0x37c4: 0x000c, 0x37c5: 0x000c,
+ 0x37c6: 0x000c, 0x37c7: 0x000c, 0x37c8: 0x000c, 0x37c9: 0x000c, 0x37ca: 0x000c, 0x37cb: 0x0001,
+ 0x37cc: 0x0001, 0x37cd: 0x0001, 0x37ce: 0x0001, 0x37cf: 0x0001, 0x37d0: 0x0001, 0x37d1: 0x0001,
+ 0x37d2: 0x0001, 0x37d3: 0x0001, 0x37d4: 0x0001, 0x37d5: 0x0001, 0x37d6: 0x0001, 0x37d7: 0x0001,
+ 0x37d8: 0x0001, 0x37d9: 0x0001, 0x37da: 0x0001, 0x37db: 0x0001, 0x37dc: 0x0001, 0x37dd: 0x0001,
+ 0x37de: 0x0001, 0x37df: 0x0001, 0x37e0: 0x0001, 0x37e1: 0x0001, 0x37e2: 0x0001, 0x37e3: 0x0001,
+ 0x37e4: 0x0001, 0x37e5: 0x0001, 0x37e6: 0x0001, 0x37e7: 0x0001, 0x37e8: 0x0001, 0x37e9: 0x0001,
+ 0x37ea: 0x0001, 0x37eb: 0x0001, 0x37ec: 0x0001, 0x37ed: 0x0001, 0x37ee: 0x0001, 0x37ef: 0x0001,
+ 0x37f0: 0x0001, 0x37f1: 0x0001, 0x37f2: 0x0001, 0x37f3: 0x0001, 0x37f4: 0x0001, 0x37f5: 0x0001,
+ 0x37f6: 0x0001, 0x37f7: 0x0001, 0x37f8: 0x0001, 0x37f9: 0x0001, 0x37fa: 0x0001, 0x37fb: 0x0001,
+ 0x37fc: 0x0001, 0x37fd: 0x0001, 0x37fe: 0x0001, 0x37ff: 0x0001,
+ // Block 0xe0, offset 0x3800
+ 0x3800: 0x000d, 0x3801: 0x000d, 0x3802: 0x000d, 0x3803: 0x000d, 0x3804: 0x000d, 0x3805: 0x000d,
+ 0x3806: 0x000d, 0x3807: 0x000d, 0x3808: 0x000d, 0x3809: 0x000d, 0x380a: 0x000d, 0x380b: 0x000d,
+ 0x380c: 0x000d, 0x380d: 0x000d, 0x380e: 0x000d, 0x380f: 0x000d, 0x3810: 0x0001, 0x3811: 0x0001,
+ 0x3812: 0x0001, 0x3813: 0x0001, 0x3814: 0x0001, 0x3815: 0x0001, 0x3816: 0x0001, 0x3817: 0x0001,
+ 0x3818: 0x0001, 0x3819: 0x0001, 0x381a: 0x0001, 0x381b: 0x0001, 0x381c: 0x0001, 0x381d: 0x0001,
+ 0x381e: 0x0001, 0x381f: 0x0001, 0x3820: 0x0001, 0x3821: 0x0001, 0x3822: 0x0001, 0x3823: 0x0001,
+ 0x3824: 0x0001, 0x3825: 0x0001, 0x3826: 0x0001, 0x3827: 0x0001, 0x3828: 0x0001, 0x3829: 0x0001,
+ 0x382a: 0x0001, 0x382b: 0x0001, 0x382c: 0x0001, 0x382d: 0x0001, 0x382e: 0x0001, 0x382f: 0x0001,
+ 0x3830: 0x0001, 0x3831: 0x0001, 0x3832: 0x0001, 0x3833: 0x0001, 0x3834: 0x0001, 0x3835: 0x0001,
+ 0x3836: 0x0001, 0x3837: 0x0001, 0x3838: 0x0001, 0x3839: 0x0001, 0x383a: 0x0001, 0x383b: 0x0001,
+ 0x383c: 0x0001, 0x383d: 0x0001, 0x383e: 0x0001, 0x383f: 0x0001,
+ // Block 0xe1, offset 0x3840
+ 0x3840: 0x000d, 0x3841: 0x000d, 0x3842: 0x000d, 0x3843: 0x000d, 0x3844: 0x000d, 0x3845: 0x000d,
+ 0x3846: 0x000d, 0x3847: 0x000d, 0x3848: 0x000d, 0x3849: 0x000d, 0x384a: 0x000d, 0x384b: 0x000d,
+ 0x384c: 0x000d, 0x384d: 0x000d, 0x384e: 0x000d, 0x384f: 0x000d, 0x3850: 0x000d, 0x3851: 0x000d,
+ 0x3852: 0x000d, 0x3853: 0x000d, 0x3854: 0x000d, 0x3855: 0x000d, 0x3856: 0x000d, 0x3857: 0x000d,
+ 0x3858: 0x000d, 0x3859: 0x000d, 0x385a: 0x000d, 0x385b: 0x000d, 0x385c: 0x000d, 0x385d: 0x000d,
+ 0x385e: 0x000d, 0x385f: 0x000d, 0x3860: 0x000d, 0x3861: 0x000d, 0x3862: 0x000d, 0x3863: 0x000d,
+ 0x3864: 0x000d, 0x3865: 0x000d, 0x3866: 0x000d, 0x3867: 0x000d, 0x3868: 0x000d, 0x3869: 0x000d,
+ 0x386a: 0x000d, 0x386b: 0x000d, 0x386c: 0x000d, 0x386d: 0x000d, 0x386e: 0x000d, 0x386f: 0x000d,
+ 0x3870: 0x000a, 0x3871: 0x000a, 0x3872: 0x000d, 0x3873: 0x000d, 0x3874: 0x000d, 0x3875: 0x000d,
+ 0x3876: 0x000d, 0x3877: 0x000d, 0x3878: 0x000d, 0x3879: 0x000d, 0x387a: 0x000d, 0x387b: 0x000d,
+ 0x387c: 0x000d, 0x387d: 0x000d, 0x387e: 0x000d, 0x387f: 0x000d,
+ // Block 0xe2, offset 0x3880
+ 0x3880: 0x000a, 0x3881: 0x000a, 0x3882: 0x000a, 0x3883: 0x000a, 0x3884: 0x000a, 0x3885: 0x000a,
+ 0x3886: 0x000a, 0x3887: 0x000a, 0x3888: 0x000a, 0x3889: 0x000a, 0x388a: 0x000a, 0x388b: 0x000a,
+ 0x388c: 0x000a, 0x388d: 0x000a, 0x388e: 0x000a, 0x388f: 0x000a, 0x3890: 0x000a, 0x3891: 0x000a,
+ 0x3892: 0x000a, 0x3893: 0x000a, 0x3894: 0x000a, 0x3895: 0x000a, 0x3896: 0x000a, 0x3897: 0x000a,
+ 0x3898: 0x000a, 0x3899: 0x000a, 0x389a: 0x000a, 0x389b: 0x000a, 0x389c: 0x000a, 0x389d: 0x000a,
+ 0x389e: 0x000a, 0x389f: 0x000a, 0x38a0: 0x000a, 0x38a1: 0x000a, 0x38a2: 0x000a, 0x38a3: 0x000a,
+ 0x38a4: 0x000a, 0x38a5: 0x000a, 0x38a6: 0x000a, 0x38a7: 0x000a, 0x38a8: 0x000a, 0x38a9: 0x000a,
+ 0x38aa: 0x000a, 0x38ab: 0x000a,
+ 0x38b0: 0x000a, 0x38b1: 0x000a, 0x38b2: 0x000a, 0x38b3: 0x000a, 0x38b4: 0x000a, 0x38b5: 0x000a,
+ 0x38b6: 0x000a, 0x38b7: 0x000a, 0x38b8: 0x000a, 0x38b9: 0x000a, 0x38ba: 0x000a, 0x38bb: 0x000a,
+ 0x38bc: 0x000a, 0x38bd: 0x000a, 0x38be: 0x000a, 0x38bf: 0x000a,
+ // Block 0xe3, offset 0x38c0
+ 0x38c0: 0x000a, 0x38c1: 0x000a, 0x38c2: 0x000a, 0x38c3: 0x000a, 0x38c4: 0x000a, 0x38c5: 0x000a,
+ 0x38c6: 0x000a, 0x38c7: 0x000a, 0x38c8: 0x000a, 0x38c9: 0x000a, 0x38ca: 0x000a, 0x38cb: 0x000a,
+ 0x38cc: 0x000a, 0x38cd: 0x000a, 0x38ce: 0x000a, 0x38cf: 0x000a, 0x38d0: 0x000a, 0x38d1: 0x000a,
+ 0x38d2: 0x000a, 0x38d3: 0x000a,
+ 0x38e0: 0x000a, 0x38e1: 0x000a, 0x38e2: 0x000a, 0x38e3: 0x000a,
+ 0x38e4: 0x000a, 0x38e5: 0x000a, 0x38e6: 0x000a, 0x38e7: 0x000a, 0x38e8: 0x000a, 0x38e9: 0x000a,
+ 0x38ea: 0x000a, 0x38eb: 0x000a, 0x38ec: 0x000a, 0x38ed: 0x000a, 0x38ee: 0x000a,
+ 0x38f1: 0x000a, 0x38f2: 0x000a, 0x38f3: 0x000a, 0x38f4: 0x000a, 0x38f5: 0x000a,
+ 0x38f6: 0x000a, 0x38f7: 0x000a, 0x38f8: 0x000a, 0x38f9: 0x000a, 0x38fa: 0x000a, 0x38fb: 0x000a,
+ 0x38fc: 0x000a, 0x38fd: 0x000a, 0x38fe: 0x000a, 0x38ff: 0x000a,
+ // Block 0xe4, offset 0x3900
+ 0x3901: 0x000a, 0x3902: 0x000a, 0x3903: 0x000a, 0x3904: 0x000a, 0x3905: 0x000a,
+ 0x3906: 0x000a, 0x3907: 0x000a, 0x3908: 0x000a, 0x3909: 0x000a, 0x390a: 0x000a, 0x390b: 0x000a,
+ 0x390c: 0x000a, 0x390d: 0x000a, 0x390e: 0x000a, 0x390f: 0x000a, 0x3911: 0x000a,
+ 0x3912: 0x000a, 0x3913: 0x000a, 0x3914: 0x000a, 0x3915: 0x000a, 0x3916: 0x000a, 0x3917: 0x000a,
+ 0x3918: 0x000a, 0x3919: 0x000a, 0x391a: 0x000a, 0x391b: 0x000a, 0x391c: 0x000a, 0x391d: 0x000a,
+ 0x391e: 0x000a, 0x391f: 0x000a, 0x3920: 0x000a, 0x3921: 0x000a, 0x3922: 0x000a, 0x3923: 0x000a,
+ 0x3924: 0x000a, 0x3925: 0x000a, 0x3926: 0x000a, 0x3927: 0x000a, 0x3928: 0x000a, 0x3929: 0x000a,
+ 0x392a: 0x000a, 0x392b: 0x000a, 0x392c: 0x000a, 0x392d: 0x000a, 0x392e: 0x000a, 0x392f: 0x000a,
+ 0x3930: 0x000a, 0x3931: 0x000a, 0x3932: 0x000a, 0x3933: 0x000a, 0x3934: 0x000a, 0x3935: 0x000a,
+ // Block 0xe5, offset 0x3940
+ 0x3940: 0x0002, 0x3941: 0x0002, 0x3942: 0x0002, 0x3943: 0x0002, 0x3944: 0x0002, 0x3945: 0x0002,
+ 0x3946: 0x0002, 0x3947: 0x0002, 0x3948: 0x0002, 0x3949: 0x0002, 0x394a: 0x0002, 0x394b: 0x000a,
+ 0x394c: 0x000a, 0x394d: 0x000a, 0x394e: 0x000a, 0x394f: 0x000a,
+ 0x396f: 0x000a,
+ // Block 0xe6, offset 0x3980
+ 0x39aa: 0x000a, 0x39ab: 0x000a, 0x39ac: 0x000a, 0x39ad: 0x000a, 0x39ae: 0x000a, 0x39af: 0x000a,
+ // Block 0xe7, offset 0x39c0
+ 0x39ed: 0x000a,
+ // Block 0xe8, offset 0x3a00
+ 0x3a20: 0x000a, 0x3a21: 0x000a, 0x3a22: 0x000a, 0x3a23: 0x000a,
+ 0x3a24: 0x000a, 0x3a25: 0x000a,
+ // Block 0xe9, offset 0x3a40
+ 0x3a40: 0x000a, 0x3a41: 0x000a, 0x3a42: 0x000a, 0x3a43: 0x000a, 0x3a44: 0x000a, 0x3a45: 0x000a,
+ 0x3a46: 0x000a, 0x3a47: 0x000a, 0x3a48: 0x000a, 0x3a49: 0x000a, 0x3a4a: 0x000a, 0x3a4b: 0x000a,
+ 0x3a4c: 0x000a, 0x3a4d: 0x000a, 0x3a4e: 0x000a, 0x3a4f: 0x000a, 0x3a50: 0x000a, 0x3a51: 0x000a,
+ 0x3a52: 0x000a, 0x3a53: 0x000a, 0x3a54: 0x000a, 0x3a55: 0x000a, 0x3a56: 0x000a, 0x3a57: 0x000a,
+ 0x3a60: 0x000a, 0x3a61: 0x000a, 0x3a62: 0x000a, 0x3a63: 0x000a,
+ 0x3a64: 0x000a, 0x3a65: 0x000a, 0x3a66: 0x000a, 0x3a67: 0x000a, 0x3a68: 0x000a, 0x3a69: 0x000a,
+ 0x3a6a: 0x000a, 0x3a6b: 0x000a, 0x3a6c: 0x000a,
+ 0x3a70: 0x000a, 0x3a71: 0x000a, 0x3a72: 0x000a, 0x3a73: 0x000a, 0x3a74: 0x000a, 0x3a75: 0x000a,
+ 0x3a76: 0x000a, 0x3a77: 0x000a, 0x3a78: 0x000a, 0x3a79: 0x000a, 0x3a7a: 0x000a, 0x3a7b: 0x000a,
+ 0x3a7c: 0x000a,
+ // Block 0xea, offset 0x3a80
+ 0x3a80: 0x000a, 0x3a81: 0x000a, 0x3a82: 0x000a, 0x3a83: 0x000a, 0x3a84: 0x000a, 0x3a85: 0x000a,
+ 0x3a86: 0x000a, 0x3a87: 0x000a, 0x3a88: 0x000a, 0x3a89: 0x000a, 0x3a8a: 0x000a, 0x3a8b: 0x000a,
+ 0x3a8c: 0x000a, 0x3a8d: 0x000a, 0x3a8e: 0x000a, 0x3a8f: 0x000a, 0x3a90: 0x000a, 0x3a91: 0x000a,
+ 0x3a92: 0x000a, 0x3a93: 0x000a, 0x3a94: 0x000a, 0x3a95: 0x000a, 0x3a96: 0x000a, 0x3a97: 0x000a,
+ 0x3a98: 0x000a,
+ 0x3aa0: 0x000a, 0x3aa1: 0x000a, 0x3aa2: 0x000a, 0x3aa3: 0x000a,
+ 0x3aa4: 0x000a, 0x3aa5: 0x000a, 0x3aa6: 0x000a, 0x3aa7: 0x000a, 0x3aa8: 0x000a, 0x3aa9: 0x000a,
+ 0x3aaa: 0x000a, 0x3aab: 0x000a,
+ // Block 0xeb, offset 0x3ac0
+ 0x3ac0: 0x000a, 0x3ac1: 0x000a, 0x3ac2: 0x000a, 0x3ac3: 0x000a, 0x3ac4: 0x000a, 0x3ac5: 0x000a,
+ 0x3ac6: 0x000a, 0x3ac7: 0x000a, 0x3ac8: 0x000a, 0x3ac9: 0x000a, 0x3aca: 0x000a, 0x3acb: 0x000a,
+ 0x3ad0: 0x000a, 0x3ad1: 0x000a,
+ 0x3ad2: 0x000a, 0x3ad3: 0x000a, 0x3ad4: 0x000a, 0x3ad5: 0x000a, 0x3ad6: 0x000a, 0x3ad7: 0x000a,
+ 0x3ad8: 0x000a, 0x3ad9: 0x000a, 0x3ada: 0x000a, 0x3adb: 0x000a, 0x3adc: 0x000a, 0x3add: 0x000a,
+ 0x3ade: 0x000a, 0x3adf: 0x000a, 0x3ae0: 0x000a, 0x3ae1: 0x000a, 0x3ae2: 0x000a, 0x3ae3: 0x000a,
+ 0x3ae4: 0x000a, 0x3ae5: 0x000a, 0x3ae6: 0x000a, 0x3ae7: 0x000a, 0x3ae8: 0x000a, 0x3ae9: 0x000a,
+ 0x3aea: 0x000a, 0x3aeb: 0x000a, 0x3aec: 0x000a, 0x3aed: 0x000a, 0x3aee: 0x000a, 0x3aef: 0x000a,
+ 0x3af0: 0x000a, 0x3af1: 0x000a, 0x3af2: 0x000a, 0x3af3: 0x000a, 0x3af4: 0x000a, 0x3af5: 0x000a,
+ 0x3af6: 0x000a, 0x3af7: 0x000a, 0x3af8: 0x000a, 0x3af9: 0x000a, 0x3afa: 0x000a, 0x3afb: 0x000a,
+ 0x3afc: 0x000a, 0x3afd: 0x000a, 0x3afe: 0x000a, 0x3aff: 0x000a,
+ // Block 0xec, offset 0x3b00
+ 0x3b00: 0x000a, 0x3b01: 0x000a, 0x3b02: 0x000a, 0x3b03: 0x000a, 0x3b04: 0x000a, 0x3b05: 0x000a,
+ 0x3b06: 0x000a, 0x3b07: 0x000a,
+ 0x3b10: 0x000a, 0x3b11: 0x000a,
+ 0x3b12: 0x000a, 0x3b13: 0x000a, 0x3b14: 0x000a, 0x3b15: 0x000a, 0x3b16: 0x000a, 0x3b17: 0x000a,
+ 0x3b18: 0x000a, 0x3b19: 0x000a,
+ 0x3b20: 0x000a, 0x3b21: 0x000a, 0x3b22: 0x000a, 0x3b23: 0x000a,
+ 0x3b24: 0x000a, 0x3b25: 0x000a, 0x3b26: 0x000a, 0x3b27: 0x000a, 0x3b28: 0x000a, 0x3b29: 0x000a,
+ 0x3b2a: 0x000a, 0x3b2b: 0x000a, 0x3b2c: 0x000a, 0x3b2d: 0x000a, 0x3b2e: 0x000a, 0x3b2f: 0x000a,
+ 0x3b30: 0x000a, 0x3b31: 0x000a, 0x3b32: 0x000a, 0x3b33: 0x000a, 0x3b34: 0x000a, 0x3b35: 0x000a,
+ 0x3b36: 0x000a, 0x3b37: 0x000a, 0x3b38: 0x000a, 0x3b39: 0x000a, 0x3b3a: 0x000a, 0x3b3b: 0x000a,
+ 0x3b3c: 0x000a, 0x3b3d: 0x000a, 0x3b3e: 0x000a, 0x3b3f: 0x000a,
+ // Block 0xed, offset 0x3b40
+ 0x3b40: 0x000a, 0x3b41: 0x000a, 0x3b42: 0x000a, 0x3b43: 0x000a, 0x3b44: 0x000a, 0x3b45: 0x000a,
+ 0x3b46: 0x000a, 0x3b47: 0x000a,
+ 0x3b50: 0x000a, 0x3b51: 0x000a,
+ 0x3b52: 0x000a, 0x3b53: 0x000a, 0x3b54: 0x000a, 0x3b55: 0x000a, 0x3b56: 0x000a, 0x3b57: 0x000a,
+ 0x3b58: 0x000a, 0x3b59: 0x000a, 0x3b5a: 0x000a, 0x3b5b: 0x000a, 0x3b5c: 0x000a, 0x3b5d: 0x000a,
+ 0x3b5e: 0x000a, 0x3b5f: 0x000a, 0x3b60: 0x000a, 0x3b61: 0x000a, 0x3b62: 0x000a, 0x3b63: 0x000a,
+ 0x3b64: 0x000a, 0x3b65: 0x000a, 0x3b66: 0x000a, 0x3b67: 0x000a, 0x3b68: 0x000a, 0x3b69: 0x000a,
+ 0x3b6a: 0x000a, 0x3b6b: 0x000a, 0x3b6c: 0x000a, 0x3b6d: 0x000a,
+ 0x3b70: 0x000a, 0x3b71: 0x000a,
+ // Block 0xee, offset 0x3b80
+ 0x3b80: 0x000a, 0x3b81: 0x000a, 0x3b82: 0x000a, 0x3b83: 0x000a, 0x3b84: 0x000a, 0x3b85: 0x000a,
+ 0x3b86: 0x000a, 0x3b87: 0x000a, 0x3b88: 0x000a, 0x3b89: 0x000a, 0x3b8a: 0x000a, 0x3b8b: 0x000a,
+ 0x3b8c: 0x000a, 0x3b8d: 0x000a, 0x3b8e: 0x000a, 0x3b8f: 0x000a, 0x3b90: 0x000a, 0x3b91: 0x000a,
+ 0x3b92: 0x000a, 0x3b93: 0x000a, 0x3b94: 0x000a, 0x3b95: 0x000a, 0x3b96: 0x000a, 0x3b97: 0x000a,
+ 0x3b98: 0x000a, 0x3b99: 0x000a, 0x3b9a: 0x000a, 0x3b9b: 0x000a, 0x3b9c: 0x000a, 0x3b9d: 0x000a,
+ 0x3b9e: 0x000a, 0x3b9f: 0x000a, 0x3ba0: 0x000a, 0x3ba1: 0x000a, 0x3ba2: 0x000a, 0x3ba3: 0x000a,
+ 0x3ba4: 0x000a, 0x3ba5: 0x000a, 0x3ba6: 0x000a, 0x3ba7: 0x000a, 0x3ba8: 0x000a, 0x3ba9: 0x000a,
+ 0x3baa: 0x000a, 0x3bab: 0x000a, 0x3bac: 0x000a, 0x3bad: 0x000a, 0x3bae: 0x000a, 0x3baf: 0x000a,
+ 0x3bb0: 0x000a, 0x3bb1: 0x000a, 0x3bb2: 0x000a, 0x3bb3: 0x000a, 0x3bb4: 0x000a, 0x3bb5: 0x000a,
+ 0x3bb6: 0x000a, 0x3bb7: 0x000a, 0x3bb8: 0x000a, 0x3bba: 0x000a, 0x3bbb: 0x000a,
+ 0x3bbc: 0x000a, 0x3bbd: 0x000a, 0x3bbe: 0x000a, 0x3bbf: 0x000a,
+ // Block 0xef, offset 0x3bc0
+ 0x3bc0: 0x000a, 0x3bc1: 0x000a, 0x3bc2: 0x000a, 0x3bc3: 0x000a, 0x3bc4: 0x000a, 0x3bc5: 0x000a,
+ 0x3bc6: 0x000a, 0x3bc7: 0x000a, 0x3bc8: 0x000a, 0x3bc9: 0x000a, 0x3bca: 0x000a, 0x3bcb: 0x000a,
+ 0x3bcd: 0x000a, 0x3bce: 0x000a, 0x3bcf: 0x000a, 0x3bd0: 0x000a, 0x3bd1: 0x000a,
+ 0x3bd2: 0x000a, 0x3bd3: 0x000a, 0x3bd4: 0x000a, 0x3bd5: 0x000a, 0x3bd6: 0x000a, 0x3bd7: 0x000a,
+ 0x3bd8: 0x000a, 0x3bd9: 0x000a, 0x3bda: 0x000a, 0x3bdb: 0x000a, 0x3bdc: 0x000a, 0x3bdd: 0x000a,
+ 0x3bde: 0x000a, 0x3bdf: 0x000a, 0x3be0: 0x000a, 0x3be1: 0x000a, 0x3be2: 0x000a, 0x3be3: 0x000a,
+ 0x3be4: 0x000a, 0x3be5: 0x000a, 0x3be6: 0x000a, 0x3be7: 0x000a, 0x3be8: 0x000a, 0x3be9: 0x000a,
+ 0x3bea: 0x000a, 0x3beb: 0x000a, 0x3bec: 0x000a, 0x3bed: 0x000a, 0x3bee: 0x000a, 0x3bef: 0x000a,
+ 0x3bf0: 0x000a, 0x3bf1: 0x000a, 0x3bf2: 0x000a, 0x3bf3: 0x000a, 0x3bf4: 0x000a, 0x3bf5: 0x000a,
+ 0x3bf6: 0x000a, 0x3bf7: 0x000a, 0x3bf8: 0x000a, 0x3bf9: 0x000a, 0x3bfa: 0x000a, 0x3bfb: 0x000a,
+ 0x3bfc: 0x000a, 0x3bfd: 0x000a, 0x3bfe: 0x000a, 0x3bff: 0x000a,
+ // Block 0xf0, offset 0x3c00
+ 0x3c00: 0x000a, 0x3c01: 0x000a, 0x3c02: 0x000a, 0x3c03: 0x000a, 0x3c04: 0x000a, 0x3c05: 0x000a,
+ 0x3c06: 0x000a, 0x3c07: 0x000a, 0x3c08: 0x000a, 0x3c09: 0x000a, 0x3c0a: 0x000a, 0x3c0b: 0x000a,
+ 0x3c0c: 0x000a, 0x3c0d: 0x000a, 0x3c0e: 0x000a, 0x3c0f: 0x000a, 0x3c10: 0x000a, 0x3c11: 0x000a,
+ 0x3c12: 0x000a, 0x3c13: 0x000a,
+ 0x3c20: 0x000a, 0x3c21: 0x000a, 0x3c22: 0x000a, 0x3c23: 0x000a,
+ 0x3c24: 0x000a, 0x3c25: 0x000a, 0x3c26: 0x000a, 0x3c27: 0x000a, 0x3c28: 0x000a, 0x3c29: 0x000a,
+ 0x3c2a: 0x000a, 0x3c2b: 0x000a, 0x3c2c: 0x000a, 0x3c2d: 0x000a,
+ 0x3c30: 0x000a, 0x3c31: 0x000a, 0x3c32: 0x000a, 0x3c33: 0x000a, 0x3c34: 0x000a,
+ 0x3c38: 0x000a, 0x3c39: 0x000a, 0x3c3a: 0x000a,
+ // Block 0xf1, offset 0x3c40
+ 0x3c40: 0x000a, 0x3c41: 0x000a, 0x3c42: 0x000a, 0x3c43: 0x000a, 0x3c44: 0x000a, 0x3c45: 0x000a,
+ 0x3c46: 0x000a,
+ 0x3c50: 0x000a, 0x3c51: 0x000a,
+ 0x3c52: 0x000a, 0x3c53: 0x000a, 0x3c54: 0x000a, 0x3c55: 0x000a, 0x3c56: 0x000a, 0x3c57: 0x000a,
+ 0x3c58: 0x000a, 0x3c59: 0x000a, 0x3c5a: 0x000a, 0x3c5b: 0x000a, 0x3c5c: 0x000a, 0x3c5d: 0x000a,
+ 0x3c5e: 0x000a, 0x3c5f: 0x000a, 0x3c60: 0x000a, 0x3c61: 0x000a, 0x3c62: 0x000a, 0x3c63: 0x000a,
+ 0x3c64: 0x000a, 0x3c65: 0x000a, 0x3c66: 0x000a, 0x3c67: 0x000a, 0x3c68: 0x000a,
+ 0x3c70: 0x000a, 0x3c71: 0x000a, 0x3c72: 0x000a, 0x3c73: 0x000a, 0x3c74: 0x000a, 0x3c75: 0x000a,
+ 0x3c76: 0x000a,
+ // Block 0xf2, offset 0x3c80
+ 0x3c80: 0x000a, 0x3c81: 0x000a, 0x3c82: 0x000a,
+ 0x3c90: 0x000a, 0x3c91: 0x000a,
+ 0x3c92: 0x000a, 0x3c93: 0x000a, 0x3c94: 0x000a, 0x3c95: 0x000a, 0x3c96: 0x000a,
+ // Block 0xf3, offset 0x3cc0
+ 0x3cc0: 0x000a, 0x3cc1: 0x000a, 0x3cc2: 0x000a, 0x3cc3: 0x000a, 0x3cc4: 0x000a, 0x3cc5: 0x000a,
+ 0x3cc6: 0x000a, 0x3cc7: 0x000a, 0x3cc8: 0x000a, 0x3cc9: 0x000a, 0x3cca: 0x000a, 0x3ccb: 0x000a,
+ 0x3ccc: 0x000a, 0x3ccd: 0x000a, 0x3cce: 0x000a, 0x3ccf: 0x000a, 0x3cd0: 0x000a, 0x3cd1: 0x000a,
+ 0x3cd2: 0x000a, 0x3cd4: 0x000a, 0x3cd5: 0x000a, 0x3cd6: 0x000a, 0x3cd7: 0x000a,
+ 0x3cd8: 0x000a, 0x3cd9: 0x000a, 0x3cda: 0x000a, 0x3cdb: 0x000a, 0x3cdc: 0x000a, 0x3cdd: 0x000a,
+ 0x3cde: 0x000a, 0x3cdf: 0x000a, 0x3ce0: 0x000a, 0x3ce1: 0x000a, 0x3ce2: 0x000a, 0x3ce3: 0x000a,
+ 0x3ce4: 0x000a, 0x3ce5: 0x000a, 0x3ce6: 0x000a, 0x3ce7: 0x000a, 0x3ce8: 0x000a, 0x3ce9: 0x000a,
+ 0x3cea: 0x000a, 0x3ceb: 0x000a, 0x3cec: 0x000a, 0x3ced: 0x000a, 0x3cee: 0x000a, 0x3cef: 0x000a,
+ 0x3cf0: 0x000a, 0x3cf1: 0x000a, 0x3cf2: 0x000a, 0x3cf3: 0x000a, 0x3cf4: 0x000a, 0x3cf5: 0x000a,
+ 0x3cf6: 0x000a, 0x3cf7: 0x000a, 0x3cf8: 0x000a, 0x3cf9: 0x000a, 0x3cfa: 0x000a, 0x3cfb: 0x000a,
+ 0x3cfc: 0x000a, 0x3cfd: 0x000a, 0x3cfe: 0x000a, 0x3cff: 0x000a,
+ // Block 0xf4, offset 0x3d00
+ 0x3d00: 0x000a, 0x3d01: 0x000a, 0x3d02: 0x000a, 0x3d03: 0x000a, 0x3d04: 0x000a, 0x3d05: 0x000a,
+ 0x3d06: 0x000a, 0x3d07: 0x000a, 0x3d08: 0x000a, 0x3d09: 0x000a, 0x3d0a: 0x000a,
+ 0x3d30: 0x0002, 0x3d31: 0x0002, 0x3d32: 0x0002, 0x3d33: 0x0002, 0x3d34: 0x0002, 0x3d35: 0x0002,
+ 0x3d36: 0x0002, 0x3d37: 0x0002, 0x3d38: 0x0002, 0x3d39: 0x0002,
+ // Block 0xf5, offset 0x3d40
+ 0x3d7e: 0x000b, 0x3d7f: 0x000b,
+ // Block 0xf6, offset 0x3d80
+ 0x3d80: 0x000b, 0x3d81: 0x000b, 0x3d82: 0x000b, 0x3d83: 0x000b, 0x3d84: 0x000b, 0x3d85: 0x000b,
+ 0x3d86: 0x000b, 0x3d87: 0x000b, 0x3d88: 0x000b, 0x3d89: 0x000b, 0x3d8a: 0x000b, 0x3d8b: 0x000b,
+ 0x3d8c: 0x000b, 0x3d8d: 0x000b, 0x3d8e: 0x000b, 0x3d8f: 0x000b, 0x3d90: 0x000b, 0x3d91: 0x000b,
+ 0x3d92: 0x000b, 0x3d93: 0x000b, 0x3d94: 0x000b, 0x3d95: 0x000b, 0x3d96: 0x000b, 0x3d97: 0x000b,
+ 0x3d98: 0x000b, 0x3d99: 0x000b, 0x3d9a: 0x000b, 0x3d9b: 0x000b, 0x3d9c: 0x000b, 0x3d9d: 0x000b,
+ 0x3d9e: 0x000b, 0x3d9f: 0x000b, 0x3da0: 0x000b, 0x3da1: 0x000b, 0x3da2: 0x000b, 0x3da3: 0x000b,
+ 0x3da4: 0x000b, 0x3da5: 0x000b, 0x3da6: 0x000b, 0x3da7: 0x000b, 0x3da8: 0x000b, 0x3da9: 0x000b,
+ 0x3daa: 0x000b, 0x3dab: 0x000b, 0x3dac: 0x000b, 0x3dad: 0x000b, 0x3dae: 0x000b, 0x3daf: 0x000b,
+ 0x3db0: 0x000b, 0x3db1: 0x000b, 0x3db2: 0x000b, 0x3db3: 0x000b, 0x3db4: 0x000b, 0x3db5: 0x000b,
+ 0x3db6: 0x000b, 0x3db7: 0x000b, 0x3db8: 0x000b, 0x3db9: 0x000b, 0x3dba: 0x000b, 0x3dbb: 0x000b,
+ 0x3dbc: 0x000b, 0x3dbd: 0x000b, 0x3dbe: 0x000b, 0x3dbf: 0x000b,
+ // Block 0xf7, offset 0x3dc0
+ 0x3dc0: 0x000c, 0x3dc1: 0x000c, 0x3dc2: 0x000c, 0x3dc3: 0x000c, 0x3dc4: 0x000c, 0x3dc5: 0x000c,
+ 0x3dc6: 0x000c, 0x3dc7: 0x000c, 0x3dc8: 0x000c, 0x3dc9: 0x000c, 0x3dca: 0x000c, 0x3dcb: 0x000c,
+ 0x3dcc: 0x000c, 0x3dcd: 0x000c, 0x3dce: 0x000c, 0x3dcf: 0x000c, 0x3dd0: 0x000c, 0x3dd1: 0x000c,
+ 0x3dd2: 0x000c, 0x3dd3: 0x000c, 0x3dd4: 0x000c, 0x3dd5: 0x000c, 0x3dd6: 0x000c, 0x3dd7: 0x000c,
+ 0x3dd8: 0x000c, 0x3dd9: 0x000c, 0x3dda: 0x000c, 0x3ddb: 0x000c, 0x3ddc: 0x000c, 0x3ddd: 0x000c,
+ 0x3dde: 0x000c, 0x3ddf: 0x000c, 0x3de0: 0x000c, 0x3de1: 0x000c, 0x3de2: 0x000c, 0x3de3: 0x000c,
+ 0x3de4: 0x000c, 0x3de5: 0x000c, 0x3de6: 0x000c, 0x3de7: 0x000c, 0x3de8: 0x000c, 0x3de9: 0x000c,
+ 0x3dea: 0x000c, 0x3deb: 0x000c, 0x3dec: 0x000c, 0x3ded: 0x000c, 0x3dee: 0x000c, 0x3def: 0x000c,
+ 0x3df0: 0x000b, 0x3df1: 0x000b, 0x3df2: 0x000b, 0x3df3: 0x000b, 0x3df4: 0x000b, 0x3df5: 0x000b,
+ 0x3df6: 0x000b, 0x3df7: 0x000b, 0x3df8: 0x000b, 0x3df9: 0x000b, 0x3dfa: 0x000b, 0x3dfb: 0x000b,
+ 0x3dfc: 0x000b, 0x3dfd: 0x000b, 0x3dfe: 0x000b, 0x3dff: 0x000b,
+}
+
+// bidiIndex: 24 blocks, 1536 entries, 1536 bytes
+// Block 0 is the zero block.
+var bidiIndex = [1536]uint8{
+ // Block 0x0, offset 0x0
+ // Block 0x1, offset 0x40
+ // Block 0x2, offset 0x80
+ // Block 0x3, offset 0xc0
+ 0xc2: 0x01, 0xc3: 0x02,
+ 0xca: 0x03, 0xcb: 0x04, 0xcc: 0x05, 0xcd: 0x06, 0xce: 0x07, 0xcf: 0x08,
+ 0xd2: 0x09, 0xd6: 0x0a, 0xd7: 0x0b,
+ 0xd8: 0x0c, 0xd9: 0x0d, 0xda: 0x0e, 0xdb: 0x0f, 0xdc: 0x10, 0xdd: 0x11, 0xde: 0x12, 0xdf: 0x13,
+ 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06,
+ 0xea: 0x07, 0xef: 0x08,
+ 0xf0: 0x11, 0xf1: 0x12, 0xf2: 0x12, 0xf3: 0x14, 0xf4: 0x15,
+ // Block 0x4, offset 0x100
+ 0x120: 0x14, 0x121: 0x15, 0x122: 0x16, 0x123: 0x17, 0x124: 0x18, 0x125: 0x19, 0x126: 0x1a, 0x127: 0x1b,
+ 0x128: 0x1c, 0x129: 0x1d, 0x12a: 0x1c, 0x12b: 0x1e, 0x12c: 0x1f, 0x12d: 0x20, 0x12e: 0x21, 0x12f: 0x22,
+ 0x130: 0x23, 0x131: 0x24, 0x132: 0x1a, 0x133: 0x25, 0x134: 0x26, 0x135: 0x27, 0x136: 0x28, 0x137: 0x29,
+ 0x138: 0x2a, 0x139: 0x2b, 0x13a: 0x2c, 0x13b: 0x2d, 0x13c: 0x2e, 0x13d: 0x2f, 0x13e: 0x30, 0x13f: 0x31,
+ // Block 0x5, offset 0x140
+ 0x140: 0x32, 0x141: 0x33, 0x142: 0x34,
+ 0x14d: 0x35, 0x14e: 0x36,
+ 0x150: 0x37,
+ 0x15a: 0x38, 0x15c: 0x39, 0x15d: 0x3a, 0x15e: 0x3b, 0x15f: 0x3c,
+ 0x160: 0x3d, 0x162: 0x3e, 0x164: 0x3f, 0x165: 0x40, 0x167: 0x41,
+ 0x168: 0x42, 0x169: 0x43, 0x16a: 0x44, 0x16b: 0x45, 0x16c: 0x46, 0x16d: 0x47, 0x16e: 0x48, 0x16f: 0x49,
+ 0x170: 0x4a, 0x173: 0x4b, 0x177: 0x4c,
+ 0x17e: 0x4d, 0x17f: 0x4e,
+ // Block 0x6, offset 0x180
+ 0x180: 0x4f, 0x181: 0x50, 0x182: 0x51, 0x183: 0x52, 0x184: 0x53, 0x185: 0x54, 0x186: 0x55, 0x187: 0x56,
+ 0x188: 0x57, 0x189: 0x56, 0x18a: 0x56, 0x18b: 0x56, 0x18c: 0x58, 0x18d: 0x59, 0x18e: 0x5a, 0x18f: 0x56,
+ 0x190: 0x5b, 0x191: 0x5c, 0x192: 0x5d, 0x193: 0x5e, 0x194: 0x56, 0x195: 0x56, 0x196: 0x56, 0x197: 0x56,
+ 0x198: 0x56, 0x199: 0x56, 0x19a: 0x5f, 0x19b: 0x56, 0x19c: 0x56, 0x19d: 0x60, 0x19e: 0x56, 0x19f: 0x61,
+ 0x1a4: 0x56, 0x1a5: 0x56, 0x1a6: 0x62, 0x1a7: 0x63,
+ 0x1a8: 0x56, 0x1a9: 0x56, 0x1aa: 0x56, 0x1ab: 0x56, 0x1ac: 0x56, 0x1ad: 0x64, 0x1ae: 0x65, 0x1af: 0x56,
+ 0x1b3: 0x66, 0x1b5: 0x67, 0x1b7: 0x68,
+ 0x1b8: 0x69, 0x1b9: 0x6a, 0x1ba: 0x6b, 0x1bb: 0x6c, 0x1bc: 0x56, 0x1bd: 0x56, 0x1be: 0x56, 0x1bf: 0x6d,
+ // Block 0x7, offset 0x1c0
+ 0x1c0: 0x6e, 0x1c2: 0x6f, 0x1c3: 0x70, 0x1c7: 0x71,
+ 0x1c8: 0x72, 0x1c9: 0x73, 0x1ca: 0x74, 0x1cb: 0x75, 0x1cd: 0x76, 0x1cf: 0x77,
+ // Block 0x8, offset 0x200
+ 0x237: 0x56,
+ // Block 0x9, offset 0x240
+ 0x252: 0x78, 0x253: 0x79,
+ 0x258: 0x7a, 0x259: 0x7b, 0x25a: 0x7c, 0x25b: 0x7d, 0x25c: 0x7e, 0x25e: 0x7f,
+ 0x260: 0x80, 0x261: 0x81, 0x263: 0x82, 0x264: 0x83, 0x265: 0x84, 0x266: 0x85, 0x267: 0x86,
+ 0x268: 0x87, 0x269: 0x88, 0x26a: 0x89, 0x26b: 0x8a, 0x26d: 0x8b, 0x26f: 0x8c,
+ // Block 0xa, offset 0x280
+ 0x2ac: 0x8d, 0x2ad: 0x8e, 0x2ae: 0x0e, 0x2af: 0x0e,
+ 0x2b0: 0x0e, 0x2b1: 0x0e, 0x2b2: 0x0e, 0x2b3: 0x0e, 0x2b4: 0x8f, 0x2b5: 0x0e, 0x2b6: 0x0e, 0x2b7: 0x90,
+ 0x2b8: 0x91, 0x2b9: 0x92, 0x2ba: 0x0e, 0x2bb: 0x93, 0x2bc: 0x94, 0x2bd: 0x95, 0x2bf: 0x96,
+ // Block 0xb, offset 0x2c0
+ 0x2c4: 0x97, 0x2c5: 0x56, 0x2c6: 0x98, 0x2c7: 0x99,
+ 0x2cb: 0x9a, 0x2cd: 0x9b,
+ 0x2e0: 0x9c, 0x2e1: 0x9c, 0x2e2: 0x9c, 0x2e3: 0x9c, 0x2e4: 0x9d, 0x2e5: 0x9c, 0x2e6: 0x9c, 0x2e7: 0x9c,
+ 0x2e8: 0x9e, 0x2e9: 0x9c, 0x2ea: 0x9c, 0x2eb: 0x9f, 0x2ec: 0xa0, 0x2ed: 0x9c, 0x2ee: 0x9c, 0x2ef: 0x9c,
+ 0x2f0: 0x9c, 0x2f1: 0x9c, 0x2f2: 0x9c, 0x2f3: 0x9c, 0x2f4: 0xa1, 0x2f5: 0x9c, 0x2f6: 0x9c, 0x2f7: 0x9c,
+ 0x2f8: 0x9c, 0x2f9: 0xa2, 0x2fa: 0xa3, 0x2fb: 0x9c, 0x2fc: 0xa4, 0x2fd: 0xa5, 0x2fe: 0x9c, 0x2ff: 0x9c,
+ // Block 0xc, offset 0x300
+ 0x300: 0xa6, 0x301: 0xa7, 0x302: 0xa8, 0x304: 0xa9, 0x305: 0xaa, 0x306: 0xab, 0x307: 0xac,
+ 0x308: 0xad, 0x30b: 0xae, 0x30c: 0x26, 0x30d: 0xaf,
+ 0x310: 0xb0, 0x311: 0xb1, 0x312: 0xb2, 0x313: 0xb3, 0x316: 0xb4, 0x317: 0xb5,
+ 0x318: 0xb6, 0x319: 0xb7, 0x31a: 0xb8, 0x31c: 0xb9,
+ 0x320: 0xba, 0x324: 0xbb, 0x325: 0xbc, 0x327: 0xbd,
+ 0x328: 0xbe, 0x329: 0xbf, 0x32a: 0xc0,
+ 0x330: 0xc1, 0x332: 0xc2, 0x334: 0xc3, 0x335: 0xc4, 0x336: 0xc5,
+ 0x33b: 0xc6, 0x33f: 0xc7,
+ // Block 0xd, offset 0x340
+ 0x36b: 0xc8, 0x36c: 0xc9,
+ 0x37d: 0xca, 0x37e: 0xcb, 0x37f: 0xcc,
+ // Block 0xe, offset 0x380
+ 0x3b2: 0xcd,
+ // Block 0xf, offset 0x3c0
+ 0x3c5: 0xce, 0x3c6: 0xcf,
+ 0x3c8: 0x56, 0x3c9: 0xd0, 0x3cc: 0x56, 0x3cd: 0xd1,
+ 0x3db: 0xd2, 0x3dc: 0xd3, 0x3dd: 0xd4, 0x3de: 0xd5, 0x3df: 0xd6,
+ 0x3e8: 0xd7, 0x3e9: 0xd8, 0x3ea: 0xd9,
+ // Block 0x10, offset 0x400
+ 0x400: 0xda, 0x404: 0xc9,
+ 0x40b: 0xdb,
+ 0x420: 0x9c, 0x421: 0x9c, 0x422: 0x9c, 0x423: 0xdc, 0x424: 0x9c, 0x425: 0xdd, 0x426: 0x9c, 0x427: 0x9c,
+ 0x428: 0x9c, 0x429: 0x9c, 0x42a: 0x9c, 0x42b: 0x9c, 0x42c: 0x9c, 0x42d: 0x9c, 0x42e: 0x9c, 0x42f: 0x9c,
+ 0x430: 0x9c, 0x431: 0xa4, 0x432: 0x0e, 0x433: 0x9c, 0x434: 0x0e, 0x435: 0xde, 0x436: 0x9c, 0x437: 0x9c,
+ 0x438: 0x0e, 0x439: 0x0e, 0x43a: 0x0e, 0x43b: 0xdf, 0x43c: 0x9c, 0x43d: 0x9c, 0x43e: 0x9c, 0x43f: 0x9c,
+ // Block 0x11, offset 0x440
+ 0x440: 0xe0, 0x441: 0x56, 0x442: 0xe1, 0x443: 0xe2, 0x444: 0xe3, 0x445: 0xe4, 0x446: 0xe5,
+ 0x449: 0xe6, 0x44c: 0x56, 0x44d: 0x56, 0x44e: 0x56, 0x44f: 0x56,
+ 0x450: 0x56, 0x451: 0x56, 0x452: 0x56, 0x453: 0x56, 0x454: 0x56, 0x455: 0x56, 0x456: 0x56, 0x457: 0x56,
+ 0x458: 0x56, 0x459: 0x56, 0x45a: 0x56, 0x45b: 0xe7, 0x45c: 0x56, 0x45d: 0x6c, 0x45e: 0x56, 0x45f: 0xe8,
+ 0x460: 0xe9, 0x461: 0xea, 0x462: 0xeb, 0x464: 0x56, 0x465: 0xec, 0x466: 0x56, 0x467: 0xed,
+ 0x468: 0x56, 0x469: 0xee, 0x46a: 0xef, 0x46b: 0xf0, 0x46c: 0x56, 0x46d: 0x56, 0x46e: 0xf1, 0x46f: 0xf2,
+ 0x47f: 0xf3,
+ // Block 0x12, offset 0x480
+ 0x4bf: 0xf3,
+ // Block 0x13, offset 0x4c0
+ 0x4d0: 0x09, 0x4d1: 0x0a, 0x4d6: 0x0b,
+ 0x4db: 0x0c, 0x4dd: 0x0d, 0x4de: 0x0e, 0x4df: 0x0f,
+ 0x4ef: 0x10,
+ 0x4ff: 0x10,
+ // Block 0x14, offset 0x500
+ 0x50f: 0x10,
+ 0x51f: 0x10,
+ 0x52f: 0x10,
+ 0x53f: 0x10,
+ // Block 0x15, offset 0x540
+ 0x540: 0xf4, 0x541: 0xf4, 0x542: 0xf4, 0x543: 0xf4, 0x544: 0x05, 0x545: 0x05, 0x546: 0x05, 0x547: 0xf5,
+ 0x548: 0xf4, 0x549: 0xf4, 0x54a: 0xf4, 0x54b: 0xf4, 0x54c: 0xf4, 0x54d: 0xf4, 0x54e: 0xf4, 0x54f: 0xf4,
+ 0x550: 0xf4, 0x551: 0xf4, 0x552: 0xf4, 0x553: 0xf4, 0x554: 0xf4, 0x555: 0xf4, 0x556: 0xf4, 0x557: 0xf4,
+ 0x558: 0xf4, 0x559: 0xf4, 0x55a: 0xf4, 0x55b: 0xf4, 0x55c: 0xf4, 0x55d: 0xf4, 0x55e: 0xf4, 0x55f: 0xf4,
+ 0x560: 0xf4, 0x561: 0xf4, 0x562: 0xf4, 0x563: 0xf4, 0x564: 0xf4, 0x565: 0xf4, 0x566: 0xf4, 0x567: 0xf4,
+ 0x568: 0xf4, 0x569: 0xf4, 0x56a: 0xf4, 0x56b: 0xf4, 0x56c: 0xf4, 0x56d: 0xf4, 0x56e: 0xf4, 0x56f: 0xf4,
+ 0x570: 0xf4, 0x571: 0xf4, 0x572: 0xf4, 0x573: 0xf4, 0x574: 0xf4, 0x575: 0xf4, 0x576: 0xf4, 0x577: 0xf4,
+ 0x578: 0xf4, 0x579: 0xf4, 0x57a: 0xf4, 0x57b: 0xf4, 0x57c: 0xf4, 0x57d: 0xf4, 0x57e: 0xf4, 0x57f: 0xf4,
+ // Block 0x16, offset 0x580
+ 0x58f: 0x10,
+ 0x59f: 0x10,
+ 0x5a0: 0x13,
+ 0x5af: 0x10,
+ 0x5bf: 0x10,
+ // Block 0x17, offset 0x5c0
+ 0x5cf: 0x10,
+}
+
+// Total table size 17464 bytes (17KiB); checksum: F50EF68C
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/trieval.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/trieval.go
index 6a796e2214..6a796e2214 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/trieval.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/trieval.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/ya.make
index acf6ec1d9f..acf6ec1d9f 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/bidi/ya.make
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/bidi/ya.make
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/composition.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/composition.go
index e2087bce52..e2087bce52 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/composition.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/composition.go
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/forminfo.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/forminfo.go
new file mode 100644
index 0000000000..487335d14d
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/forminfo.go
@@ -0,0 +1,279 @@
+// Copyright 2011 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 norm
+
+import "encoding/binary"
+
+// This file contains Form-specific logic and wrappers for data in tables.go.
+
+// Rune info is stored in a separate trie per composing form. A composing form
+// and its corresponding decomposing form share the same trie. Each trie maps
+// a rune to a uint16. The values take two forms. For v >= 0x8000:
+// bits
+// 15: 1 (inverse of NFD_QC bit of qcInfo)
+// 13..7: qcInfo (see below). isYesD is always true (no decomposition).
+// 6..0: ccc (compressed CCC value).
+// For v < 0x8000, the respective rune has a decomposition and v is an index
+// into a byte array of UTF-8 decomposition sequences and additional info and
+// has the form:
+// <header> <decomp_byte>* [<tccc> [<lccc>]]
+// The header contains the number of bytes in the decomposition (excluding this
+// length byte). The two most significant bits of this length byte correspond
+// to bit 5 and 4 of qcInfo (see below). The byte sequence itself starts at v+1.
+// The byte sequence is followed by a trailing and leading CCC if the values
+// for these are not zero. The value of v determines which ccc are appended
+// to the sequences. For v < firstCCC, there are none, for v >= firstCCC,
+// the sequence is followed by a trailing ccc, and for v >= firstLeadingCC
+// there is an additional leading ccc. The value of tccc itself is the
+// trailing CCC shifted left 2 bits. The two least-significant bits of tccc
+// are the number of trailing non-starters.
+
+const (
+ qcInfoMask = 0x3F // to clear all but the relevant bits in a qcInfo
+ headerLenMask = 0x3F // extract the length value from the header byte
+ headerFlagsMask = 0xC0 // extract the qcInfo bits from the header byte
+)
+
+// Properties provides access to normalization properties of a rune.
+type Properties struct {
+ pos uint8 // start position in reorderBuffer; used in composition.go
+ size uint8 // length of UTF-8 encoding of this rune
+ ccc uint8 // leading canonical combining class (ccc if not decomposition)
+ tccc uint8 // trailing canonical combining class (ccc if not decomposition)
+ nLead uint8 // number of leading non-starters.
+ flags qcInfo // quick check flags
+ index uint16
+}
+
+// functions dispatchable per form
+type lookupFunc func(b input, i int) Properties
+
+// formInfo holds Form-specific functions and tables.
+type formInfo struct {
+ form Form
+ composing, compatibility bool // form type
+ info lookupFunc
+ nextMain iterFunc
+}
+
+var formTable = []*formInfo{{
+ form: NFC,
+ composing: true,
+ compatibility: false,
+ info: lookupInfoNFC,
+ nextMain: nextComposed,
+}, {
+ form: NFD,
+ composing: false,
+ compatibility: false,
+ info: lookupInfoNFC,
+ nextMain: nextDecomposed,
+}, {
+ form: NFKC,
+ composing: true,
+ compatibility: true,
+ info: lookupInfoNFKC,
+ nextMain: nextComposed,
+}, {
+ form: NFKD,
+ composing: false,
+ compatibility: true,
+ info: lookupInfoNFKC,
+ nextMain: nextDecomposed,
+}}
+
+// We do not distinguish between boundaries for NFC, NFD, etc. to avoid
+// unexpected behavior for the user. For example, in NFD, there is a boundary
+// after 'a'. However, 'a' might combine with modifiers, so from the application's
+// perspective it is not a good boundary. We will therefore always use the
+// boundaries for the combining variants.
+
+// BoundaryBefore returns true if this rune starts a new segment and
+// cannot combine with any rune on the left.
+func (p Properties) BoundaryBefore() bool {
+ if p.ccc == 0 && !p.combinesBackward() {
+ return true
+ }
+ // We assume that the CCC of the first character in a decomposition
+ // is always non-zero if different from info.ccc and that we can return
+ // false at this point. This is verified by maketables.
+ return false
+}
+
+// BoundaryAfter returns true if runes cannot combine with or otherwise
+// interact with this or previous runes.
+func (p Properties) BoundaryAfter() bool {
+ // TODO: loosen these conditions.
+ return p.isInert()
+}
+
+// We pack quick check data in 4 bits:
+//
+// 5: Combines forward (0 == false, 1 == true)
+// 4..3: NFC_QC Yes(00), No (10), or Maybe (11)
+// 2: NFD_QC Yes (0) or No (1). No also means there is a decomposition.
+// 1..0: Number of trailing non-starters.
+//
+// When all 4 bits are zero, the character is inert, meaning it is never
+// influenced by normalization.
+type qcInfo uint8
+
+func (p Properties) isYesC() bool { return p.flags&0x10 == 0 }
+func (p Properties) isYesD() bool { return p.flags&0x4 == 0 }
+
+func (p Properties) combinesForward() bool { return p.flags&0x20 != 0 }
+func (p Properties) combinesBackward() bool { return p.flags&0x8 != 0 } // == isMaybe
+func (p Properties) hasDecomposition() bool { return p.flags&0x4 != 0 } // == isNoD
+
+func (p Properties) isInert() bool {
+ return p.flags&qcInfoMask == 0 && p.ccc == 0
+}
+
+func (p Properties) multiSegment() bool {
+ return p.index >= firstMulti && p.index < endMulti
+}
+
+func (p Properties) nLeadingNonStarters() uint8 {
+ return p.nLead
+}
+
+func (p Properties) nTrailingNonStarters() uint8 {
+ return uint8(p.flags & 0x03)
+}
+
+// Decomposition returns the decomposition for the underlying rune
+// or nil if there is none.
+func (p Properties) Decomposition() []byte {
+ // TODO: create the decomposition for Hangul?
+ if p.index == 0 {
+ return nil
+ }
+ i := p.index
+ n := decomps[i] & headerLenMask
+ i++
+ return decomps[i : i+uint16(n)]
+}
+
+// Size returns the length of UTF-8 encoding of the rune.
+func (p Properties) Size() int {
+ return int(p.size)
+}
+
+// CCC returns the canonical combining class of the underlying rune.
+func (p Properties) CCC() uint8 {
+ if p.index >= firstCCCZeroExcept {
+ return 0
+ }
+ return ccc[p.ccc]
+}
+
+// LeadCCC returns the CCC of the first rune in the decomposition.
+// If there is no decomposition, LeadCCC equals CCC.
+func (p Properties) LeadCCC() uint8 {
+ return ccc[p.ccc]
+}
+
+// TrailCCC returns the CCC of the last rune in the decomposition.
+// If there is no decomposition, TrailCCC equals CCC.
+func (p Properties) TrailCCC() uint8 {
+ return ccc[p.tccc]
+}
+
+func buildRecompMap() {
+ recompMap = make(map[uint32]rune, len(recompMapPacked)/8)
+ var buf [8]byte
+ for i := 0; i < len(recompMapPacked); i += 8 {
+ copy(buf[:], recompMapPacked[i:i+8])
+ key := binary.BigEndian.Uint32(buf[:4])
+ val := binary.BigEndian.Uint32(buf[4:])
+ recompMap[key] = rune(val)
+ }
+}
+
+// Recomposition
+// We use 32-bit keys instead of 64-bit for the two codepoint keys.
+// This clips off the bits of three entries, but we know this will not
+// result in a collision. In the unlikely event that changes to
+// UnicodeData.txt introduce collisions, the compiler will catch it.
+// Note that the recomposition map for NFC and NFKC are identical.
+
+// combine returns the combined rune or 0 if it doesn't exist.
+//
+// The caller is responsible for calling
+// recompMapOnce.Do(buildRecompMap) sometime before this is called.
+func combine(a, b rune) rune {
+ key := uint32(uint16(a))<<16 + uint32(uint16(b))
+ if recompMap == nil {
+ panic("caller error") // see func comment
+ }
+ return recompMap[key]
+}
+
+func lookupInfoNFC(b input, i int) Properties {
+ v, sz := b.charinfoNFC(i)
+ return compInfo(v, sz)
+}
+
+func lookupInfoNFKC(b input, i int) Properties {
+ v, sz := b.charinfoNFKC(i)
+ return compInfo(v, sz)
+}
+
+// Properties returns properties for the first rune in s.
+func (f Form) Properties(s []byte) Properties {
+ if f == NFC || f == NFD {
+ return compInfo(nfcData.lookup(s))
+ }
+ return compInfo(nfkcData.lookup(s))
+}
+
+// PropertiesString returns properties for the first rune in s.
+func (f Form) PropertiesString(s string) Properties {
+ if f == NFC || f == NFD {
+ return compInfo(nfcData.lookupString(s))
+ }
+ return compInfo(nfkcData.lookupString(s))
+}
+
+// compInfo converts the information contained in v and sz
+// to a Properties. See the comment at the top of the file
+// for more information on the format.
+func compInfo(v uint16, sz int) Properties {
+ if v == 0 {
+ return Properties{size: uint8(sz)}
+ } else if v >= 0x8000 {
+ p := Properties{
+ size: uint8(sz),
+ ccc: uint8(v),
+ tccc: uint8(v),
+ flags: qcInfo(v >> 8),
+ }
+ if p.ccc > 0 || p.combinesBackward() {
+ p.nLead = uint8(p.flags & 0x3)
+ }
+ return p
+ }
+ // has decomposition
+ h := decomps[v]
+ f := (qcInfo(h&headerFlagsMask) >> 2) | 0x4
+ p := Properties{size: uint8(sz), flags: f, index: v}
+ if v >= firstCCC {
+ v += uint16(h&headerLenMask) + 1
+ c := decomps[v]
+ p.tccc = c >> 2
+ p.flags |= qcInfo(c & 0x3)
+ if v >= firstLeadingCCC {
+ p.nLead = c & 0x3
+ if v >= firstStarterWithNLead {
+ // We were tricked. Remove the decomposition.
+ p.flags &= 0x03
+ p.index = 0
+ return p
+ }
+ p.ccc = decomps[v+1]
+ }
+ }
+ return p
+}
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/input.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/input.go
index 479e35bc25..479e35bc25 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/input.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/input.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/iter.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/iter.go
index 417c6b2689..417c6b2689 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/iter.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/iter.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/normalize.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/normalize.go
index 4747ad07a8..4747ad07a8 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/normalize.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/normalize.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/readwriter.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/readwriter.go
index b38096f5ca..b38096f5ca 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/readwriter.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/readwriter.go
diff --git a/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
new file mode 100644
index 0000000000..f65785e8ac
--- /dev/null
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go
@@ -0,0 +1,7761 @@
+// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
+
+//go:build go1.16 && !go1.21
+// +build go1.16,!go1.21
+
+package norm
+
+import "sync"
+
+const (
+ // Version is the Unicode edition from which the tables are derived.
+ Version = "13.0.0"
+
+ // MaxTransformChunkSize indicates the maximum number of bytes that Transform
+ // may need to write atomically for any Form. Making a destination buffer at
+ // least this size ensures that Transform can always make progress and that
+ // the user does not need to grow the buffer on an ErrShortDst.
+ MaxTransformChunkSize = 35 + maxNonStarters*4
+)
+
+var ccc = [56]uint8{
+ 0, 1, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 84, 91, 103, 107, 118, 122, 129,
+ 130, 132, 202, 214, 216, 218, 220, 222,
+ 224, 226, 228, 230, 232, 233, 234, 240,
+}
+
+const (
+ firstMulti = 0x1870
+ firstCCC = 0x2CAB
+ endMulti = 0x2F77
+ firstLeadingCCC = 0x49C5
+ firstCCCZeroExcept = 0x4A8F
+ firstStarterWithNLead = 0x4AB6
+ lastDecomp = 0x4AB8
+ maxDecomp = 0x8000
+)
+
+// decomps: 19128 bytes
+var decomps = [...]byte{
+ // Bytes 0 - 3f
+ 0x00, 0x41, 0x20, 0x41, 0x21, 0x41, 0x22, 0x41,
+ 0x23, 0x41, 0x24, 0x41, 0x25, 0x41, 0x26, 0x41,
+ 0x27, 0x41, 0x28, 0x41, 0x29, 0x41, 0x2A, 0x41,
+ 0x2B, 0x41, 0x2C, 0x41, 0x2D, 0x41, 0x2E, 0x41,
+ 0x2F, 0x41, 0x30, 0x41, 0x31, 0x41, 0x32, 0x41,
+ 0x33, 0x41, 0x34, 0x41, 0x35, 0x41, 0x36, 0x41,
+ 0x37, 0x41, 0x38, 0x41, 0x39, 0x41, 0x3A, 0x41,
+ 0x3B, 0x41, 0x3C, 0x41, 0x3D, 0x41, 0x3E, 0x41,
+ // Bytes 40 - 7f
+ 0x3F, 0x41, 0x40, 0x41, 0x41, 0x41, 0x42, 0x41,
+ 0x43, 0x41, 0x44, 0x41, 0x45, 0x41, 0x46, 0x41,
+ 0x47, 0x41, 0x48, 0x41, 0x49, 0x41, 0x4A, 0x41,
+ 0x4B, 0x41, 0x4C, 0x41, 0x4D, 0x41, 0x4E, 0x41,
+ 0x4F, 0x41, 0x50, 0x41, 0x51, 0x41, 0x52, 0x41,
+ 0x53, 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41,
+ 0x57, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5A, 0x41,
+ 0x5B, 0x41, 0x5C, 0x41, 0x5D, 0x41, 0x5E, 0x41,
+ // Bytes 80 - bf
+ 0x5F, 0x41, 0x60, 0x41, 0x61, 0x41, 0x62, 0x41,
+ 0x63, 0x41, 0x64, 0x41, 0x65, 0x41, 0x66, 0x41,
+ 0x67, 0x41, 0x68, 0x41, 0x69, 0x41, 0x6A, 0x41,
+ 0x6B, 0x41, 0x6C, 0x41, 0x6D, 0x41, 0x6E, 0x41,
+ 0x6F, 0x41, 0x70, 0x41, 0x71, 0x41, 0x72, 0x41,
+ 0x73, 0x41, 0x74, 0x41, 0x75, 0x41, 0x76, 0x41,
+ 0x77, 0x41, 0x78, 0x41, 0x79, 0x41, 0x7A, 0x41,
+ 0x7B, 0x41, 0x7C, 0x41, 0x7D, 0x41, 0x7E, 0x42,
+ // Bytes c0 - ff
+ 0xC2, 0xA2, 0x42, 0xC2, 0xA3, 0x42, 0xC2, 0xA5,
+ 0x42, 0xC2, 0xA6, 0x42, 0xC2, 0xAC, 0x42, 0xC2,
+ 0xB7, 0x42, 0xC3, 0x86, 0x42, 0xC3, 0xB0, 0x42,
+ 0xC4, 0xA6, 0x42, 0xC4, 0xA7, 0x42, 0xC4, 0xB1,
+ 0x42, 0xC5, 0x8B, 0x42, 0xC5, 0x93, 0x42, 0xC6,
+ 0x8E, 0x42, 0xC6, 0x90, 0x42, 0xC6, 0xAB, 0x42,
+ 0xC8, 0xA2, 0x42, 0xC8, 0xB7, 0x42, 0xC9, 0x90,
+ 0x42, 0xC9, 0x91, 0x42, 0xC9, 0x92, 0x42, 0xC9,
+ // Bytes 100 - 13f
+ 0x94, 0x42, 0xC9, 0x95, 0x42, 0xC9, 0x99, 0x42,
+ 0xC9, 0x9B, 0x42, 0xC9, 0x9C, 0x42, 0xC9, 0x9F,
+ 0x42, 0xC9, 0xA1, 0x42, 0xC9, 0xA3, 0x42, 0xC9,
+ 0xA5, 0x42, 0xC9, 0xA6, 0x42, 0xC9, 0xA8, 0x42,
+ 0xC9, 0xA9, 0x42, 0xC9, 0xAA, 0x42, 0xC9, 0xAB,
+ 0x42, 0xC9, 0xAD, 0x42, 0xC9, 0xAF, 0x42, 0xC9,
+ 0xB0, 0x42, 0xC9, 0xB1, 0x42, 0xC9, 0xB2, 0x42,
+ 0xC9, 0xB3, 0x42, 0xC9, 0xB4, 0x42, 0xC9, 0xB5,
+ // Bytes 140 - 17f
+ 0x42, 0xC9, 0xB8, 0x42, 0xC9, 0xB9, 0x42, 0xC9,
+ 0xBB, 0x42, 0xCA, 0x81, 0x42, 0xCA, 0x82, 0x42,
+ 0xCA, 0x83, 0x42, 0xCA, 0x89, 0x42, 0xCA, 0x8A,
+ 0x42, 0xCA, 0x8B, 0x42, 0xCA, 0x8C, 0x42, 0xCA,
+ 0x8D, 0x42, 0xCA, 0x90, 0x42, 0xCA, 0x91, 0x42,
+ 0xCA, 0x92, 0x42, 0xCA, 0x95, 0x42, 0xCA, 0x9D,
+ 0x42, 0xCA, 0x9F, 0x42, 0xCA, 0xB9, 0x42, 0xCE,
+ 0x91, 0x42, 0xCE, 0x92, 0x42, 0xCE, 0x93, 0x42,
+ // Bytes 180 - 1bf
+ 0xCE, 0x94, 0x42, 0xCE, 0x95, 0x42, 0xCE, 0x96,
+ 0x42, 0xCE, 0x97, 0x42, 0xCE, 0x98, 0x42, 0xCE,
+ 0x99, 0x42, 0xCE, 0x9A, 0x42, 0xCE, 0x9B, 0x42,
+ 0xCE, 0x9C, 0x42, 0xCE, 0x9D, 0x42, 0xCE, 0x9E,
+ 0x42, 0xCE, 0x9F, 0x42, 0xCE, 0xA0, 0x42, 0xCE,
+ 0xA1, 0x42, 0xCE, 0xA3, 0x42, 0xCE, 0xA4, 0x42,
+ 0xCE, 0xA5, 0x42, 0xCE, 0xA6, 0x42, 0xCE, 0xA7,
+ 0x42, 0xCE, 0xA8, 0x42, 0xCE, 0xA9, 0x42, 0xCE,
+ // Bytes 1c0 - 1ff
+ 0xB1, 0x42, 0xCE, 0xB2, 0x42, 0xCE, 0xB3, 0x42,
+ 0xCE, 0xB4, 0x42, 0xCE, 0xB5, 0x42, 0xCE, 0xB6,
+ 0x42, 0xCE, 0xB7, 0x42, 0xCE, 0xB8, 0x42, 0xCE,
+ 0xB9, 0x42, 0xCE, 0xBA, 0x42, 0xCE, 0xBB, 0x42,
+ 0xCE, 0xBC, 0x42, 0xCE, 0xBD, 0x42, 0xCE, 0xBE,
+ 0x42, 0xCE, 0xBF, 0x42, 0xCF, 0x80, 0x42, 0xCF,
+ 0x81, 0x42, 0xCF, 0x82, 0x42, 0xCF, 0x83, 0x42,
+ 0xCF, 0x84, 0x42, 0xCF, 0x85, 0x42, 0xCF, 0x86,
+ // Bytes 200 - 23f
+ 0x42, 0xCF, 0x87, 0x42, 0xCF, 0x88, 0x42, 0xCF,
+ 0x89, 0x42, 0xCF, 0x9C, 0x42, 0xCF, 0x9D, 0x42,
+ 0xD0, 0xBD, 0x42, 0xD1, 0x8A, 0x42, 0xD1, 0x8C,
+ 0x42, 0xD7, 0x90, 0x42, 0xD7, 0x91, 0x42, 0xD7,
+ 0x92, 0x42, 0xD7, 0x93, 0x42, 0xD7, 0x94, 0x42,
+ 0xD7, 0x9B, 0x42, 0xD7, 0x9C, 0x42, 0xD7, 0x9D,
+ 0x42, 0xD7, 0xA2, 0x42, 0xD7, 0xA8, 0x42, 0xD7,
+ 0xAA, 0x42, 0xD8, 0xA1, 0x42, 0xD8, 0xA7, 0x42,
+ // Bytes 240 - 27f
+ 0xD8, 0xA8, 0x42, 0xD8, 0xA9, 0x42, 0xD8, 0xAA,
+ 0x42, 0xD8, 0xAB, 0x42, 0xD8, 0xAC, 0x42, 0xD8,
+ 0xAD, 0x42, 0xD8, 0xAE, 0x42, 0xD8, 0xAF, 0x42,
+ 0xD8, 0xB0, 0x42, 0xD8, 0xB1, 0x42, 0xD8, 0xB2,
+ 0x42, 0xD8, 0xB3, 0x42, 0xD8, 0xB4, 0x42, 0xD8,
+ 0xB5, 0x42, 0xD8, 0xB6, 0x42, 0xD8, 0xB7, 0x42,
+ 0xD8, 0xB8, 0x42, 0xD8, 0xB9, 0x42, 0xD8, 0xBA,
+ 0x42, 0xD9, 0x81, 0x42, 0xD9, 0x82, 0x42, 0xD9,
+ // Bytes 280 - 2bf
+ 0x83, 0x42, 0xD9, 0x84, 0x42, 0xD9, 0x85, 0x42,
+ 0xD9, 0x86, 0x42, 0xD9, 0x87, 0x42, 0xD9, 0x88,
+ 0x42, 0xD9, 0x89, 0x42, 0xD9, 0x8A, 0x42, 0xD9,
+ 0xAE, 0x42, 0xD9, 0xAF, 0x42, 0xD9, 0xB1, 0x42,
+ 0xD9, 0xB9, 0x42, 0xD9, 0xBA, 0x42, 0xD9, 0xBB,
+ 0x42, 0xD9, 0xBE, 0x42, 0xD9, 0xBF, 0x42, 0xDA,
+ 0x80, 0x42, 0xDA, 0x83, 0x42, 0xDA, 0x84, 0x42,
+ 0xDA, 0x86, 0x42, 0xDA, 0x87, 0x42, 0xDA, 0x88,
+ // Bytes 2c0 - 2ff
+ 0x42, 0xDA, 0x8C, 0x42, 0xDA, 0x8D, 0x42, 0xDA,
+ 0x8E, 0x42, 0xDA, 0x91, 0x42, 0xDA, 0x98, 0x42,
+ 0xDA, 0xA1, 0x42, 0xDA, 0xA4, 0x42, 0xDA, 0xA6,
+ 0x42, 0xDA, 0xA9, 0x42, 0xDA, 0xAD, 0x42, 0xDA,
+ 0xAF, 0x42, 0xDA, 0xB1, 0x42, 0xDA, 0xB3, 0x42,
+ 0xDA, 0xBA, 0x42, 0xDA, 0xBB, 0x42, 0xDA, 0xBE,
+ 0x42, 0xDB, 0x81, 0x42, 0xDB, 0x85, 0x42, 0xDB,
+ 0x86, 0x42, 0xDB, 0x87, 0x42, 0xDB, 0x88, 0x42,
+ // Bytes 300 - 33f
+ 0xDB, 0x89, 0x42, 0xDB, 0x8B, 0x42, 0xDB, 0x8C,
+ 0x42, 0xDB, 0x90, 0x42, 0xDB, 0x92, 0x43, 0xE0,
+ 0xBC, 0x8B, 0x43, 0xE1, 0x83, 0x9C, 0x43, 0xE1,
+ 0x84, 0x80, 0x43, 0xE1, 0x84, 0x81, 0x43, 0xE1,
+ 0x84, 0x82, 0x43, 0xE1, 0x84, 0x83, 0x43, 0xE1,
+ 0x84, 0x84, 0x43, 0xE1, 0x84, 0x85, 0x43, 0xE1,
+ 0x84, 0x86, 0x43, 0xE1, 0x84, 0x87, 0x43, 0xE1,
+ 0x84, 0x88, 0x43, 0xE1, 0x84, 0x89, 0x43, 0xE1,
+ // Bytes 340 - 37f
+ 0x84, 0x8A, 0x43, 0xE1, 0x84, 0x8B, 0x43, 0xE1,
+ 0x84, 0x8C, 0x43, 0xE1, 0x84, 0x8D, 0x43, 0xE1,
+ 0x84, 0x8E, 0x43, 0xE1, 0x84, 0x8F, 0x43, 0xE1,
+ 0x84, 0x90, 0x43, 0xE1, 0x84, 0x91, 0x43, 0xE1,
+ 0x84, 0x92, 0x43, 0xE1, 0x84, 0x94, 0x43, 0xE1,
+ 0x84, 0x95, 0x43, 0xE1, 0x84, 0x9A, 0x43, 0xE1,
+ 0x84, 0x9C, 0x43, 0xE1, 0x84, 0x9D, 0x43, 0xE1,
+ 0x84, 0x9E, 0x43, 0xE1, 0x84, 0xA0, 0x43, 0xE1,
+ // Bytes 380 - 3bf
+ 0x84, 0xA1, 0x43, 0xE1, 0x84, 0xA2, 0x43, 0xE1,
+ 0x84, 0xA3, 0x43, 0xE1, 0x84, 0xA7, 0x43, 0xE1,
+ 0x84, 0xA9, 0x43, 0xE1, 0x84, 0xAB, 0x43, 0xE1,
+ 0x84, 0xAC, 0x43, 0xE1, 0x84, 0xAD, 0x43, 0xE1,
+ 0x84, 0xAE, 0x43, 0xE1, 0x84, 0xAF, 0x43, 0xE1,
+ 0x84, 0xB2, 0x43, 0xE1, 0x84, 0xB6, 0x43, 0xE1,
+ 0x85, 0x80, 0x43, 0xE1, 0x85, 0x87, 0x43, 0xE1,
+ 0x85, 0x8C, 0x43, 0xE1, 0x85, 0x97, 0x43, 0xE1,
+ // Bytes 3c0 - 3ff
+ 0x85, 0x98, 0x43, 0xE1, 0x85, 0x99, 0x43, 0xE1,
+ 0x85, 0xA0, 0x43, 0xE1, 0x86, 0x84, 0x43, 0xE1,
+ 0x86, 0x85, 0x43, 0xE1, 0x86, 0x88, 0x43, 0xE1,
+ 0x86, 0x91, 0x43, 0xE1, 0x86, 0x92, 0x43, 0xE1,
+ 0x86, 0x94, 0x43, 0xE1, 0x86, 0x9E, 0x43, 0xE1,
+ 0x86, 0xA1, 0x43, 0xE1, 0x87, 0x87, 0x43, 0xE1,
+ 0x87, 0x88, 0x43, 0xE1, 0x87, 0x8C, 0x43, 0xE1,
+ 0x87, 0x8E, 0x43, 0xE1, 0x87, 0x93, 0x43, 0xE1,
+ // Bytes 400 - 43f
+ 0x87, 0x97, 0x43, 0xE1, 0x87, 0x99, 0x43, 0xE1,
+ 0x87, 0x9D, 0x43, 0xE1, 0x87, 0x9F, 0x43, 0xE1,
+ 0x87, 0xB1, 0x43, 0xE1, 0x87, 0xB2, 0x43, 0xE1,
+ 0xB4, 0x82, 0x43, 0xE1, 0xB4, 0x96, 0x43, 0xE1,
+ 0xB4, 0x97, 0x43, 0xE1, 0xB4, 0x9C, 0x43, 0xE1,
+ 0xB4, 0x9D, 0x43, 0xE1, 0xB4, 0xA5, 0x43, 0xE1,
+ 0xB5, 0xBB, 0x43, 0xE1, 0xB6, 0x85, 0x43, 0xE2,
+ 0x80, 0x82, 0x43, 0xE2, 0x80, 0x83, 0x43, 0xE2,
+ // Bytes 440 - 47f
+ 0x80, 0x90, 0x43, 0xE2, 0x80, 0x93, 0x43, 0xE2,
+ 0x80, 0x94, 0x43, 0xE2, 0x82, 0xA9, 0x43, 0xE2,
+ 0x86, 0x90, 0x43, 0xE2, 0x86, 0x91, 0x43, 0xE2,
+ 0x86, 0x92, 0x43, 0xE2, 0x86, 0x93, 0x43, 0xE2,
+ 0x88, 0x82, 0x43, 0xE2, 0x88, 0x87, 0x43, 0xE2,
+ 0x88, 0x91, 0x43, 0xE2, 0x88, 0x92, 0x43, 0xE2,
+ 0x94, 0x82, 0x43, 0xE2, 0x96, 0xA0, 0x43, 0xE2,
+ 0x97, 0x8B, 0x43, 0xE2, 0xA6, 0x85, 0x43, 0xE2,
+ // Bytes 480 - 4bf
+ 0xA6, 0x86, 0x43, 0xE2, 0xB5, 0xA1, 0x43, 0xE3,
+ 0x80, 0x81, 0x43, 0xE3, 0x80, 0x82, 0x43, 0xE3,
+ 0x80, 0x88, 0x43, 0xE3, 0x80, 0x89, 0x43, 0xE3,
+ 0x80, 0x8A, 0x43, 0xE3, 0x80, 0x8B, 0x43, 0xE3,
+ 0x80, 0x8C, 0x43, 0xE3, 0x80, 0x8D, 0x43, 0xE3,
+ 0x80, 0x8E, 0x43, 0xE3, 0x80, 0x8F, 0x43, 0xE3,
+ 0x80, 0x90, 0x43, 0xE3, 0x80, 0x91, 0x43, 0xE3,
+ 0x80, 0x92, 0x43, 0xE3, 0x80, 0x94, 0x43, 0xE3,
+ // Bytes 4c0 - 4ff
+ 0x80, 0x95, 0x43, 0xE3, 0x80, 0x96, 0x43, 0xE3,
+ 0x80, 0x97, 0x43, 0xE3, 0x82, 0xA1, 0x43, 0xE3,
+ 0x82, 0xA2, 0x43, 0xE3, 0x82, 0xA3, 0x43, 0xE3,
+ 0x82, 0xA4, 0x43, 0xE3, 0x82, 0xA5, 0x43, 0xE3,
+ 0x82, 0xA6, 0x43, 0xE3, 0x82, 0xA7, 0x43, 0xE3,
+ 0x82, 0xA8, 0x43, 0xE3, 0x82, 0xA9, 0x43, 0xE3,
+ 0x82, 0xAA, 0x43, 0xE3, 0x82, 0xAB, 0x43, 0xE3,
+ 0x82, 0xAD, 0x43, 0xE3, 0x82, 0xAF, 0x43, 0xE3,
+ // Bytes 500 - 53f
+ 0x82, 0xB1, 0x43, 0xE3, 0x82, 0xB3, 0x43, 0xE3,
+ 0x82, 0xB5, 0x43, 0xE3, 0x82, 0xB7, 0x43, 0xE3,
+ 0x82, 0xB9, 0x43, 0xE3, 0x82, 0xBB, 0x43, 0xE3,
+ 0x82, 0xBD, 0x43, 0xE3, 0x82, 0xBF, 0x43, 0xE3,
+ 0x83, 0x81, 0x43, 0xE3, 0x83, 0x83, 0x43, 0xE3,
+ 0x83, 0x84, 0x43, 0xE3, 0x83, 0x86, 0x43, 0xE3,
+ 0x83, 0x88, 0x43, 0xE3, 0x83, 0x8A, 0x43, 0xE3,
+ 0x83, 0x8B, 0x43, 0xE3, 0x83, 0x8C, 0x43, 0xE3,
+ // Bytes 540 - 57f
+ 0x83, 0x8D, 0x43, 0xE3, 0x83, 0x8E, 0x43, 0xE3,
+ 0x83, 0x8F, 0x43, 0xE3, 0x83, 0x92, 0x43, 0xE3,
+ 0x83, 0x95, 0x43, 0xE3, 0x83, 0x98, 0x43, 0xE3,
+ 0x83, 0x9B, 0x43, 0xE3, 0x83, 0x9E, 0x43, 0xE3,
+ 0x83, 0x9F, 0x43, 0xE3, 0x83, 0xA0, 0x43, 0xE3,
+ 0x83, 0xA1, 0x43, 0xE3, 0x83, 0xA2, 0x43, 0xE3,
+ 0x83, 0xA3, 0x43, 0xE3, 0x83, 0xA4, 0x43, 0xE3,
+ 0x83, 0xA5, 0x43, 0xE3, 0x83, 0xA6, 0x43, 0xE3,
+ // Bytes 580 - 5bf
+ 0x83, 0xA7, 0x43, 0xE3, 0x83, 0xA8, 0x43, 0xE3,
+ 0x83, 0xA9, 0x43, 0xE3, 0x83, 0xAA, 0x43, 0xE3,
+ 0x83, 0xAB, 0x43, 0xE3, 0x83, 0xAC, 0x43, 0xE3,
+ 0x83, 0xAD, 0x43, 0xE3, 0x83, 0xAF, 0x43, 0xE3,
+ 0x83, 0xB0, 0x43, 0xE3, 0x83, 0xB1, 0x43, 0xE3,
+ 0x83, 0xB2, 0x43, 0xE3, 0x83, 0xB3, 0x43, 0xE3,
+ 0x83, 0xBB, 0x43, 0xE3, 0x83, 0xBC, 0x43, 0xE3,
+ 0x92, 0x9E, 0x43, 0xE3, 0x92, 0xB9, 0x43, 0xE3,
+ // Bytes 5c0 - 5ff
+ 0x92, 0xBB, 0x43, 0xE3, 0x93, 0x9F, 0x43, 0xE3,
+ 0x94, 0x95, 0x43, 0xE3, 0x9B, 0xAE, 0x43, 0xE3,
+ 0x9B, 0xBC, 0x43, 0xE3, 0x9E, 0x81, 0x43, 0xE3,
+ 0xA0, 0xAF, 0x43, 0xE3, 0xA1, 0xA2, 0x43, 0xE3,
+ 0xA1, 0xBC, 0x43, 0xE3, 0xA3, 0x87, 0x43, 0xE3,
+ 0xA3, 0xA3, 0x43, 0xE3, 0xA4, 0x9C, 0x43, 0xE3,
+ 0xA4, 0xBA, 0x43, 0xE3, 0xA8, 0xAE, 0x43, 0xE3,
+ 0xA9, 0xAC, 0x43, 0xE3, 0xAB, 0xA4, 0x43, 0xE3,
+ // Bytes 600 - 63f
+ 0xAC, 0x88, 0x43, 0xE3, 0xAC, 0x99, 0x43, 0xE3,
+ 0xAD, 0x89, 0x43, 0xE3, 0xAE, 0x9D, 0x43, 0xE3,
+ 0xB0, 0x98, 0x43, 0xE3, 0xB1, 0x8E, 0x43, 0xE3,
+ 0xB4, 0xB3, 0x43, 0xE3, 0xB6, 0x96, 0x43, 0xE3,
+ 0xBA, 0xAC, 0x43, 0xE3, 0xBA, 0xB8, 0x43, 0xE3,
+ 0xBC, 0x9B, 0x43, 0xE3, 0xBF, 0xBC, 0x43, 0xE4,
+ 0x80, 0x88, 0x43, 0xE4, 0x80, 0x98, 0x43, 0xE4,
+ 0x80, 0xB9, 0x43, 0xE4, 0x81, 0x86, 0x43, 0xE4,
+ // Bytes 640 - 67f
+ 0x82, 0x96, 0x43, 0xE4, 0x83, 0xA3, 0x43, 0xE4,
+ 0x84, 0xAF, 0x43, 0xE4, 0x88, 0x82, 0x43, 0xE4,
+ 0x88, 0xA7, 0x43, 0xE4, 0x8A, 0xA0, 0x43, 0xE4,
+ 0x8C, 0x81, 0x43, 0xE4, 0x8C, 0xB4, 0x43, 0xE4,
+ 0x8D, 0x99, 0x43, 0xE4, 0x8F, 0x95, 0x43, 0xE4,
+ 0x8F, 0x99, 0x43, 0xE4, 0x90, 0x8B, 0x43, 0xE4,
+ 0x91, 0xAB, 0x43, 0xE4, 0x94, 0xAB, 0x43, 0xE4,
+ 0x95, 0x9D, 0x43, 0xE4, 0x95, 0xA1, 0x43, 0xE4,
+ // Bytes 680 - 6bf
+ 0x95, 0xAB, 0x43, 0xE4, 0x97, 0x97, 0x43, 0xE4,
+ 0x97, 0xB9, 0x43, 0xE4, 0x98, 0xB5, 0x43, 0xE4,
+ 0x9A, 0xBE, 0x43, 0xE4, 0x9B, 0x87, 0x43, 0xE4,
+ 0xA6, 0x95, 0x43, 0xE4, 0xA7, 0xA6, 0x43, 0xE4,
+ 0xA9, 0xAE, 0x43, 0xE4, 0xA9, 0xB6, 0x43, 0xE4,
+ 0xAA, 0xB2, 0x43, 0xE4, 0xAC, 0xB3, 0x43, 0xE4,
+ 0xAF, 0x8E, 0x43, 0xE4, 0xB3, 0x8E, 0x43, 0xE4,
+ 0xB3, 0xAD, 0x43, 0xE4, 0xB3, 0xB8, 0x43, 0xE4,
+ // Bytes 6c0 - 6ff
+ 0xB5, 0x96, 0x43, 0xE4, 0xB8, 0x80, 0x43, 0xE4,
+ 0xB8, 0x81, 0x43, 0xE4, 0xB8, 0x83, 0x43, 0xE4,
+ 0xB8, 0x89, 0x43, 0xE4, 0xB8, 0x8A, 0x43, 0xE4,
+ 0xB8, 0x8B, 0x43, 0xE4, 0xB8, 0x8D, 0x43, 0xE4,
+ 0xB8, 0x99, 0x43, 0xE4, 0xB8, 0xA6, 0x43, 0xE4,
+ 0xB8, 0xA8, 0x43, 0xE4, 0xB8, 0xAD, 0x43, 0xE4,
+ 0xB8, 0xB2, 0x43, 0xE4, 0xB8, 0xB6, 0x43, 0xE4,
+ 0xB8, 0xB8, 0x43, 0xE4, 0xB8, 0xB9, 0x43, 0xE4,
+ // Bytes 700 - 73f
+ 0xB8, 0xBD, 0x43, 0xE4, 0xB8, 0xBF, 0x43, 0xE4,
+ 0xB9, 0x81, 0x43, 0xE4, 0xB9, 0x99, 0x43, 0xE4,
+ 0xB9, 0x9D, 0x43, 0xE4, 0xBA, 0x82, 0x43, 0xE4,
+ 0xBA, 0x85, 0x43, 0xE4, 0xBA, 0x86, 0x43, 0xE4,
+ 0xBA, 0x8C, 0x43, 0xE4, 0xBA, 0x94, 0x43, 0xE4,
+ 0xBA, 0xA0, 0x43, 0xE4, 0xBA, 0xA4, 0x43, 0xE4,
+ 0xBA, 0xAE, 0x43, 0xE4, 0xBA, 0xBA, 0x43, 0xE4,
+ 0xBB, 0x80, 0x43, 0xE4, 0xBB, 0x8C, 0x43, 0xE4,
+ // Bytes 740 - 77f
+ 0xBB, 0xA4, 0x43, 0xE4, 0xBC, 0x81, 0x43, 0xE4,
+ 0xBC, 0x91, 0x43, 0xE4, 0xBD, 0xA0, 0x43, 0xE4,
+ 0xBE, 0x80, 0x43, 0xE4, 0xBE, 0x86, 0x43, 0xE4,
+ 0xBE, 0x8B, 0x43, 0xE4, 0xBE, 0xAE, 0x43, 0xE4,
+ 0xBE, 0xBB, 0x43, 0xE4, 0xBE, 0xBF, 0x43, 0xE5,
+ 0x80, 0x82, 0x43, 0xE5, 0x80, 0xAB, 0x43, 0xE5,
+ 0x81, 0xBA, 0x43, 0xE5, 0x82, 0x99, 0x43, 0xE5,
+ 0x83, 0x8F, 0x43, 0xE5, 0x83, 0x9A, 0x43, 0xE5,
+ // Bytes 780 - 7bf
+ 0x83, 0xA7, 0x43, 0xE5, 0x84, 0xAA, 0x43, 0xE5,
+ 0x84, 0xBF, 0x43, 0xE5, 0x85, 0x80, 0x43, 0xE5,
+ 0x85, 0x85, 0x43, 0xE5, 0x85, 0x8D, 0x43, 0xE5,
+ 0x85, 0x94, 0x43, 0xE5, 0x85, 0xA4, 0x43, 0xE5,
+ 0x85, 0xA5, 0x43, 0xE5, 0x85, 0xA7, 0x43, 0xE5,
+ 0x85, 0xA8, 0x43, 0xE5, 0x85, 0xA9, 0x43, 0xE5,
+ 0x85, 0xAB, 0x43, 0xE5, 0x85, 0xAD, 0x43, 0xE5,
+ 0x85, 0xB7, 0x43, 0xE5, 0x86, 0x80, 0x43, 0xE5,
+ // Bytes 7c0 - 7ff
+ 0x86, 0x82, 0x43, 0xE5, 0x86, 0x8D, 0x43, 0xE5,
+ 0x86, 0x92, 0x43, 0xE5, 0x86, 0x95, 0x43, 0xE5,
+ 0x86, 0x96, 0x43, 0xE5, 0x86, 0x97, 0x43, 0xE5,
+ 0x86, 0x99, 0x43, 0xE5, 0x86, 0xA4, 0x43, 0xE5,
+ 0x86, 0xAB, 0x43, 0xE5, 0x86, 0xAC, 0x43, 0xE5,
+ 0x86, 0xB5, 0x43, 0xE5, 0x86, 0xB7, 0x43, 0xE5,
+ 0x87, 0x89, 0x43, 0xE5, 0x87, 0x8C, 0x43, 0xE5,
+ 0x87, 0x9C, 0x43, 0xE5, 0x87, 0x9E, 0x43, 0xE5,
+ // Bytes 800 - 83f
+ 0x87, 0xA0, 0x43, 0xE5, 0x87, 0xB5, 0x43, 0xE5,
+ 0x88, 0x80, 0x43, 0xE5, 0x88, 0x83, 0x43, 0xE5,
+ 0x88, 0x87, 0x43, 0xE5, 0x88, 0x97, 0x43, 0xE5,
+ 0x88, 0x9D, 0x43, 0xE5, 0x88, 0xA9, 0x43, 0xE5,
+ 0x88, 0xBA, 0x43, 0xE5, 0x88, 0xBB, 0x43, 0xE5,
+ 0x89, 0x86, 0x43, 0xE5, 0x89, 0x8D, 0x43, 0xE5,
+ 0x89, 0xB2, 0x43, 0xE5, 0x89, 0xB7, 0x43, 0xE5,
+ 0x8A, 0x89, 0x43, 0xE5, 0x8A, 0x9B, 0x43, 0xE5,
+ // Bytes 840 - 87f
+ 0x8A, 0xA3, 0x43, 0xE5, 0x8A, 0xB3, 0x43, 0xE5,
+ 0x8A, 0xB4, 0x43, 0xE5, 0x8B, 0x87, 0x43, 0xE5,
+ 0x8B, 0x89, 0x43, 0xE5, 0x8B, 0x92, 0x43, 0xE5,
+ 0x8B, 0x9E, 0x43, 0xE5, 0x8B, 0xA4, 0x43, 0xE5,
+ 0x8B, 0xB5, 0x43, 0xE5, 0x8B, 0xB9, 0x43, 0xE5,
+ 0x8B, 0xBA, 0x43, 0xE5, 0x8C, 0x85, 0x43, 0xE5,
+ 0x8C, 0x86, 0x43, 0xE5, 0x8C, 0x95, 0x43, 0xE5,
+ 0x8C, 0x97, 0x43, 0xE5, 0x8C, 0x9A, 0x43, 0xE5,
+ // Bytes 880 - 8bf
+ 0x8C, 0xB8, 0x43, 0xE5, 0x8C, 0xBB, 0x43, 0xE5,
+ 0x8C, 0xBF, 0x43, 0xE5, 0x8D, 0x81, 0x43, 0xE5,
+ 0x8D, 0x84, 0x43, 0xE5, 0x8D, 0x85, 0x43, 0xE5,
+ 0x8D, 0x89, 0x43, 0xE5, 0x8D, 0x91, 0x43, 0xE5,
+ 0x8D, 0x94, 0x43, 0xE5, 0x8D, 0x9A, 0x43, 0xE5,
+ 0x8D, 0x9C, 0x43, 0xE5, 0x8D, 0xA9, 0x43, 0xE5,
+ 0x8D, 0xB0, 0x43, 0xE5, 0x8D, 0xB3, 0x43, 0xE5,
+ 0x8D, 0xB5, 0x43, 0xE5, 0x8D, 0xBD, 0x43, 0xE5,
+ // Bytes 8c0 - 8ff
+ 0x8D, 0xBF, 0x43, 0xE5, 0x8E, 0x82, 0x43, 0xE5,
+ 0x8E, 0xB6, 0x43, 0xE5, 0x8F, 0x83, 0x43, 0xE5,
+ 0x8F, 0x88, 0x43, 0xE5, 0x8F, 0x8A, 0x43, 0xE5,
+ 0x8F, 0x8C, 0x43, 0xE5, 0x8F, 0x9F, 0x43, 0xE5,
+ 0x8F, 0xA3, 0x43, 0xE5, 0x8F, 0xA5, 0x43, 0xE5,
+ 0x8F, 0xAB, 0x43, 0xE5, 0x8F, 0xAF, 0x43, 0xE5,
+ 0x8F, 0xB1, 0x43, 0xE5, 0x8F, 0xB3, 0x43, 0xE5,
+ 0x90, 0x86, 0x43, 0xE5, 0x90, 0x88, 0x43, 0xE5,
+ // Bytes 900 - 93f
+ 0x90, 0x8D, 0x43, 0xE5, 0x90, 0x8F, 0x43, 0xE5,
+ 0x90, 0x9D, 0x43, 0xE5, 0x90, 0xB8, 0x43, 0xE5,
+ 0x90, 0xB9, 0x43, 0xE5, 0x91, 0x82, 0x43, 0xE5,
+ 0x91, 0x88, 0x43, 0xE5, 0x91, 0xA8, 0x43, 0xE5,
+ 0x92, 0x9E, 0x43, 0xE5, 0x92, 0xA2, 0x43, 0xE5,
+ 0x92, 0xBD, 0x43, 0xE5, 0x93, 0xB6, 0x43, 0xE5,
+ 0x94, 0x90, 0x43, 0xE5, 0x95, 0x8F, 0x43, 0xE5,
+ 0x95, 0x93, 0x43, 0xE5, 0x95, 0x95, 0x43, 0xE5,
+ // Bytes 940 - 97f
+ 0x95, 0xA3, 0x43, 0xE5, 0x96, 0x84, 0x43, 0xE5,
+ 0x96, 0x87, 0x43, 0xE5, 0x96, 0x99, 0x43, 0xE5,
+ 0x96, 0x9D, 0x43, 0xE5, 0x96, 0xAB, 0x43, 0xE5,
+ 0x96, 0xB3, 0x43, 0xE5, 0x96, 0xB6, 0x43, 0xE5,
+ 0x97, 0x80, 0x43, 0xE5, 0x97, 0x82, 0x43, 0xE5,
+ 0x97, 0xA2, 0x43, 0xE5, 0x98, 0x86, 0x43, 0xE5,
+ 0x99, 0x91, 0x43, 0xE5, 0x99, 0xA8, 0x43, 0xE5,
+ 0x99, 0xB4, 0x43, 0xE5, 0x9B, 0x97, 0x43, 0xE5,
+ // Bytes 980 - 9bf
+ 0x9B, 0x9B, 0x43, 0xE5, 0x9B, 0xB9, 0x43, 0xE5,
+ 0x9C, 0x96, 0x43, 0xE5, 0x9C, 0x97, 0x43, 0xE5,
+ 0x9C, 0x9F, 0x43, 0xE5, 0x9C, 0xB0, 0x43, 0xE5,
+ 0x9E, 0x8B, 0x43, 0xE5, 0x9F, 0x8E, 0x43, 0xE5,
+ 0x9F, 0xB4, 0x43, 0xE5, 0xA0, 0x8D, 0x43, 0xE5,
+ 0xA0, 0xB1, 0x43, 0xE5, 0xA0, 0xB2, 0x43, 0xE5,
+ 0xA1, 0x80, 0x43, 0xE5, 0xA1, 0x9A, 0x43, 0xE5,
+ 0xA1, 0x9E, 0x43, 0xE5, 0xA2, 0xA8, 0x43, 0xE5,
+ // Bytes 9c0 - 9ff
+ 0xA2, 0xAC, 0x43, 0xE5, 0xA2, 0xB3, 0x43, 0xE5,
+ 0xA3, 0x98, 0x43, 0xE5, 0xA3, 0x9F, 0x43, 0xE5,
+ 0xA3, 0xAB, 0x43, 0xE5, 0xA3, 0xAE, 0x43, 0xE5,
+ 0xA3, 0xB0, 0x43, 0xE5, 0xA3, 0xB2, 0x43, 0xE5,
+ 0xA3, 0xB7, 0x43, 0xE5, 0xA4, 0x82, 0x43, 0xE5,
+ 0xA4, 0x86, 0x43, 0xE5, 0xA4, 0x8A, 0x43, 0xE5,
+ 0xA4, 0x95, 0x43, 0xE5, 0xA4, 0x9A, 0x43, 0xE5,
+ 0xA4, 0x9C, 0x43, 0xE5, 0xA4, 0xA2, 0x43, 0xE5,
+ // Bytes a00 - a3f
+ 0xA4, 0xA7, 0x43, 0xE5, 0xA4, 0xA9, 0x43, 0xE5,
+ 0xA5, 0x84, 0x43, 0xE5, 0xA5, 0x88, 0x43, 0xE5,
+ 0xA5, 0x91, 0x43, 0xE5, 0xA5, 0x94, 0x43, 0xE5,
+ 0xA5, 0xA2, 0x43, 0xE5, 0xA5, 0xB3, 0x43, 0xE5,
+ 0xA7, 0x98, 0x43, 0xE5, 0xA7, 0xAC, 0x43, 0xE5,
+ 0xA8, 0x9B, 0x43, 0xE5, 0xA8, 0xA7, 0x43, 0xE5,
+ 0xA9, 0xA2, 0x43, 0xE5, 0xA9, 0xA6, 0x43, 0xE5,
+ 0xAA, 0xB5, 0x43, 0xE5, 0xAC, 0x88, 0x43, 0xE5,
+ // Bytes a40 - a7f
+ 0xAC, 0xA8, 0x43, 0xE5, 0xAC, 0xBE, 0x43, 0xE5,
+ 0xAD, 0x90, 0x43, 0xE5, 0xAD, 0x97, 0x43, 0xE5,
+ 0xAD, 0xA6, 0x43, 0xE5, 0xAE, 0x80, 0x43, 0xE5,
+ 0xAE, 0x85, 0x43, 0xE5, 0xAE, 0x97, 0x43, 0xE5,
+ 0xAF, 0x83, 0x43, 0xE5, 0xAF, 0x98, 0x43, 0xE5,
+ 0xAF, 0xA7, 0x43, 0xE5, 0xAF, 0xAE, 0x43, 0xE5,
+ 0xAF, 0xB3, 0x43, 0xE5, 0xAF, 0xB8, 0x43, 0xE5,
+ 0xAF, 0xBF, 0x43, 0xE5, 0xB0, 0x86, 0x43, 0xE5,
+ // Bytes a80 - abf
+ 0xB0, 0x8F, 0x43, 0xE5, 0xB0, 0xA2, 0x43, 0xE5,
+ 0xB0, 0xB8, 0x43, 0xE5, 0xB0, 0xBF, 0x43, 0xE5,
+ 0xB1, 0xA0, 0x43, 0xE5, 0xB1, 0xA2, 0x43, 0xE5,
+ 0xB1, 0xA4, 0x43, 0xE5, 0xB1, 0xA5, 0x43, 0xE5,
+ 0xB1, 0xAE, 0x43, 0xE5, 0xB1, 0xB1, 0x43, 0xE5,
+ 0xB2, 0x8D, 0x43, 0xE5, 0xB3, 0x80, 0x43, 0xE5,
+ 0xB4, 0x99, 0x43, 0xE5, 0xB5, 0x83, 0x43, 0xE5,
+ 0xB5, 0x90, 0x43, 0xE5, 0xB5, 0xAB, 0x43, 0xE5,
+ // Bytes ac0 - aff
+ 0xB5, 0xAE, 0x43, 0xE5, 0xB5, 0xBC, 0x43, 0xE5,
+ 0xB6, 0xB2, 0x43, 0xE5, 0xB6, 0xBA, 0x43, 0xE5,
+ 0xB7, 0x9B, 0x43, 0xE5, 0xB7, 0xA1, 0x43, 0xE5,
+ 0xB7, 0xA2, 0x43, 0xE5, 0xB7, 0xA5, 0x43, 0xE5,
+ 0xB7, 0xA6, 0x43, 0xE5, 0xB7, 0xB1, 0x43, 0xE5,
+ 0xB7, 0xBD, 0x43, 0xE5, 0xB7, 0xBE, 0x43, 0xE5,
+ 0xB8, 0xA8, 0x43, 0xE5, 0xB8, 0xBD, 0x43, 0xE5,
+ 0xB9, 0xA9, 0x43, 0xE5, 0xB9, 0xB2, 0x43, 0xE5,
+ // Bytes b00 - b3f
+ 0xB9, 0xB4, 0x43, 0xE5, 0xB9, 0xBA, 0x43, 0xE5,
+ 0xB9, 0xBC, 0x43, 0xE5, 0xB9, 0xBF, 0x43, 0xE5,
+ 0xBA, 0xA6, 0x43, 0xE5, 0xBA, 0xB0, 0x43, 0xE5,
+ 0xBA, 0xB3, 0x43, 0xE5, 0xBA, 0xB6, 0x43, 0xE5,
+ 0xBB, 0x89, 0x43, 0xE5, 0xBB, 0x8A, 0x43, 0xE5,
+ 0xBB, 0x92, 0x43, 0xE5, 0xBB, 0x93, 0x43, 0xE5,
+ 0xBB, 0x99, 0x43, 0xE5, 0xBB, 0xAC, 0x43, 0xE5,
+ 0xBB, 0xB4, 0x43, 0xE5, 0xBB, 0xBE, 0x43, 0xE5,
+ // Bytes b40 - b7f
+ 0xBC, 0x84, 0x43, 0xE5, 0xBC, 0x8B, 0x43, 0xE5,
+ 0xBC, 0x93, 0x43, 0xE5, 0xBC, 0xA2, 0x43, 0xE5,
+ 0xBD, 0x90, 0x43, 0xE5, 0xBD, 0x93, 0x43, 0xE5,
+ 0xBD, 0xA1, 0x43, 0xE5, 0xBD, 0xA2, 0x43, 0xE5,
+ 0xBD, 0xA9, 0x43, 0xE5, 0xBD, 0xAB, 0x43, 0xE5,
+ 0xBD, 0xB3, 0x43, 0xE5, 0xBE, 0x8B, 0x43, 0xE5,
+ 0xBE, 0x8C, 0x43, 0xE5, 0xBE, 0x97, 0x43, 0xE5,
+ 0xBE, 0x9A, 0x43, 0xE5, 0xBE, 0xA9, 0x43, 0xE5,
+ // Bytes b80 - bbf
+ 0xBE, 0xAD, 0x43, 0xE5, 0xBF, 0x83, 0x43, 0xE5,
+ 0xBF, 0x8D, 0x43, 0xE5, 0xBF, 0x97, 0x43, 0xE5,
+ 0xBF, 0xB5, 0x43, 0xE5, 0xBF, 0xB9, 0x43, 0xE6,
+ 0x80, 0x92, 0x43, 0xE6, 0x80, 0x9C, 0x43, 0xE6,
+ 0x81, 0xB5, 0x43, 0xE6, 0x82, 0x81, 0x43, 0xE6,
+ 0x82, 0x94, 0x43, 0xE6, 0x83, 0x87, 0x43, 0xE6,
+ 0x83, 0x98, 0x43, 0xE6, 0x83, 0xA1, 0x43, 0xE6,
+ 0x84, 0x88, 0x43, 0xE6, 0x85, 0x84, 0x43, 0xE6,
+ // Bytes bc0 - bff
+ 0x85, 0x88, 0x43, 0xE6, 0x85, 0x8C, 0x43, 0xE6,
+ 0x85, 0x8E, 0x43, 0xE6, 0x85, 0xA0, 0x43, 0xE6,
+ 0x85, 0xA8, 0x43, 0xE6, 0x85, 0xBA, 0x43, 0xE6,
+ 0x86, 0x8E, 0x43, 0xE6, 0x86, 0x90, 0x43, 0xE6,
+ 0x86, 0xA4, 0x43, 0xE6, 0x86, 0xAF, 0x43, 0xE6,
+ 0x86, 0xB2, 0x43, 0xE6, 0x87, 0x9E, 0x43, 0xE6,
+ 0x87, 0xB2, 0x43, 0xE6, 0x87, 0xB6, 0x43, 0xE6,
+ 0x88, 0x80, 0x43, 0xE6, 0x88, 0x88, 0x43, 0xE6,
+ // Bytes c00 - c3f
+ 0x88, 0x90, 0x43, 0xE6, 0x88, 0x9B, 0x43, 0xE6,
+ 0x88, 0xAE, 0x43, 0xE6, 0x88, 0xB4, 0x43, 0xE6,
+ 0x88, 0xB6, 0x43, 0xE6, 0x89, 0x8B, 0x43, 0xE6,
+ 0x89, 0x93, 0x43, 0xE6, 0x89, 0x9D, 0x43, 0xE6,
+ 0x8A, 0x95, 0x43, 0xE6, 0x8A, 0xB1, 0x43, 0xE6,
+ 0x8B, 0x89, 0x43, 0xE6, 0x8B, 0x8F, 0x43, 0xE6,
+ 0x8B, 0x93, 0x43, 0xE6, 0x8B, 0x94, 0x43, 0xE6,
+ 0x8B, 0xBC, 0x43, 0xE6, 0x8B, 0xBE, 0x43, 0xE6,
+ // Bytes c40 - c7f
+ 0x8C, 0x87, 0x43, 0xE6, 0x8C, 0xBD, 0x43, 0xE6,
+ 0x8D, 0x90, 0x43, 0xE6, 0x8D, 0x95, 0x43, 0xE6,
+ 0x8D, 0xA8, 0x43, 0xE6, 0x8D, 0xBB, 0x43, 0xE6,
+ 0x8E, 0x83, 0x43, 0xE6, 0x8E, 0xA0, 0x43, 0xE6,
+ 0x8E, 0xA9, 0x43, 0xE6, 0x8F, 0x84, 0x43, 0xE6,
+ 0x8F, 0x85, 0x43, 0xE6, 0x8F, 0xA4, 0x43, 0xE6,
+ 0x90, 0x9C, 0x43, 0xE6, 0x90, 0xA2, 0x43, 0xE6,
+ 0x91, 0x92, 0x43, 0xE6, 0x91, 0xA9, 0x43, 0xE6,
+ // Bytes c80 - cbf
+ 0x91, 0xB7, 0x43, 0xE6, 0x91, 0xBE, 0x43, 0xE6,
+ 0x92, 0x9A, 0x43, 0xE6, 0x92, 0x9D, 0x43, 0xE6,
+ 0x93, 0x84, 0x43, 0xE6, 0x94, 0xAF, 0x43, 0xE6,
+ 0x94, 0xB4, 0x43, 0xE6, 0x95, 0x8F, 0x43, 0xE6,
+ 0x95, 0x96, 0x43, 0xE6, 0x95, 0xAC, 0x43, 0xE6,
+ 0x95, 0xB8, 0x43, 0xE6, 0x96, 0x87, 0x43, 0xE6,
+ 0x96, 0x97, 0x43, 0xE6, 0x96, 0x99, 0x43, 0xE6,
+ 0x96, 0xA4, 0x43, 0xE6, 0x96, 0xB0, 0x43, 0xE6,
+ // Bytes cc0 - cff
+ 0x96, 0xB9, 0x43, 0xE6, 0x97, 0x85, 0x43, 0xE6,
+ 0x97, 0xA0, 0x43, 0xE6, 0x97, 0xA2, 0x43, 0xE6,
+ 0x97, 0xA3, 0x43, 0xE6, 0x97, 0xA5, 0x43, 0xE6,
+ 0x98, 0x93, 0x43, 0xE6, 0x98, 0xA0, 0x43, 0xE6,
+ 0x99, 0x89, 0x43, 0xE6, 0x99, 0xB4, 0x43, 0xE6,
+ 0x9A, 0x88, 0x43, 0xE6, 0x9A, 0x91, 0x43, 0xE6,
+ 0x9A, 0x9C, 0x43, 0xE6, 0x9A, 0xB4, 0x43, 0xE6,
+ 0x9B, 0x86, 0x43, 0xE6, 0x9B, 0xB0, 0x43, 0xE6,
+ // Bytes d00 - d3f
+ 0x9B, 0xB4, 0x43, 0xE6, 0x9B, 0xB8, 0x43, 0xE6,
+ 0x9C, 0x80, 0x43, 0xE6, 0x9C, 0x88, 0x43, 0xE6,
+ 0x9C, 0x89, 0x43, 0xE6, 0x9C, 0x97, 0x43, 0xE6,
+ 0x9C, 0x9B, 0x43, 0xE6, 0x9C, 0xA1, 0x43, 0xE6,
+ 0x9C, 0xA8, 0x43, 0xE6, 0x9D, 0x8E, 0x43, 0xE6,
+ 0x9D, 0x93, 0x43, 0xE6, 0x9D, 0x96, 0x43, 0xE6,
+ 0x9D, 0x9E, 0x43, 0xE6, 0x9D, 0xBB, 0x43, 0xE6,
+ 0x9E, 0x85, 0x43, 0xE6, 0x9E, 0x97, 0x43, 0xE6,
+ // Bytes d40 - d7f
+ 0x9F, 0xB3, 0x43, 0xE6, 0x9F, 0xBA, 0x43, 0xE6,
+ 0xA0, 0x97, 0x43, 0xE6, 0xA0, 0x9F, 0x43, 0xE6,
+ 0xA0, 0xAA, 0x43, 0xE6, 0xA1, 0x92, 0x43, 0xE6,
+ 0xA2, 0x81, 0x43, 0xE6, 0xA2, 0x85, 0x43, 0xE6,
+ 0xA2, 0x8E, 0x43, 0xE6, 0xA2, 0xA8, 0x43, 0xE6,
+ 0xA4, 0x94, 0x43, 0xE6, 0xA5, 0x82, 0x43, 0xE6,
+ 0xA6, 0xA3, 0x43, 0xE6, 0xA7, 0xAA, 0x43, 0xE6,
+ 0xA8, 0x82, 0x43, 0xE6, 0xA8, 0x93, 0x43, 0xE6,
+ // Bytes d80 - dbf
+ 0xAA, 0xA8, 0x43, 0xE6, 0xAB, 0x93, 0x43, 0xE6,
+ 0xAB, 0x9B, 0x43, 0xE6, 0xAC, 0x84, 0x43, 0xE6,
+ 0xAC, 0xA0, 0x43, 0xE6, 0xAC, 0xA1, 0x43, 0xE6,
+ 0xAD, 0x94, 0x43, 0xE6, 0xAD, 0xA2, 0x43, 0xE6,
+ 0xAD, 0xA3, 0x43, 0xE6, 0xAD, 0xB2, 0x43, 0xE6,
+ 0xAD, 0xB7, 0x43, 0xE6, 0xAD, 0xB9, 0x43, 0xE6,
+ 0xAE, 0x9F, 0x43, 0xE6, 0xAE, 0xAE, 0x43, 0xE6,
+ 0xAE, 0xB3, 0x43, 0xE6, 0xAE, 0xBA, 0x43, 0xE6,
+ // Bytes dc0 - dff
+ 0xAE, 0xBB, 0x43, 0xE6, 0xAF, 0x8B, 0x43, 0xE6,
+ 0xAF, 0x8D, 0x43, 0xE6, 0xAF, 0x94, 0x43, 0xE6,
+ 0xAF, 0x9B, 0x43, 0xE6, 0xB0, 0x8F, 0x43, 0xE6,
+ 0xB0, 0x94, 0x43, 0xE6, 0xB0, 0xB4, 0x43, 0xE6,
+ 0xB1, 0x8E, 0x43, 0xE6, 0xB1, 0xA7, 0x43, 0xE6,
+ 0xB2, 0x88, 0x43, 0xE6, 0xB2, 0xBF, 0x43, 0xE6,
+ 0xB3, 0x8C, 0x43, 0xE6, 0xB3, 0x8D, 0x43, 0xE6,
+ 0xB3, 0xA5, 0x43, 0xE6, 0xB3, 0xA8, 0x43, 0xE6,
+ // Bytes e00 - e3f
+ 0xB4, 0x96, 0x43, 0xE6, 0xB4, 0x9B, 0x43, 0xE6,
+ 0xB4, 0x9E, 0x43, 0xE6, 0xB4, 0xB4, 0x43, 0xE6,
+ 0xB4, 0xBE, 0x43, 0xE6, 0xB5, 0x81, 0x43, 0xE6,
+ 0xB5, 0xA9, 0x43, 0xE6, 0xB5, 0xAA, 0x43, 0xE6,
+ 0xB5, 0xB7, 0x43, 0xE6, 0xB5, 0xB8, 0x43, 0xE6,
+ 0xB6, 0x85, 0x43, 0xE6, 0xB7, 0x8B, 0x43, 0xE6,
+ 0xB7, 0x9A, 0x43, 0xE6, 0xB7, 0xAA, 0x43, 0xE6,
+ 0xB7, 0xB9, 0x43, 0xE6, 0xB8, 0x9A, 0x43, 0xE6,
+ // Bytes e40 - e7f
+ 0xB8, 0xAF, 0x43, 0xE6, 0xB9, 0xAE, 0x43, 0xE6,
+ 0xBA, 0x80, 0x43, 0xE6, 0xBA, 0x9C, 0x43, 0xE6,
+ 0xBA, 0xBA, 0x43, 0xE6, 0xBB, 0x87, 0x43, 0xE6,
+ 0xBB, 0x8B, 0x43, 0xE6, 0xBB, 0x91, 0x43, 0xE6,
+ 0xBB, 0x9B, 0x43, 0xE6, 0xBC, 0x8F, 0x43, 0xE6,
+ 0xBC, 0x94, 0x43, 0xE6, 0xBC, 0xA2, 0x43, 0xE6,
+ 0xBC, 0xA3, 0x43, 0xE6, 0xBD, 0xAE, 0x43, 0xE6,
+ 0xBF, 0x86, 0x43, 0xE6, 0xBF, 0xAB, 0x43, 0xE6,
+ // Bytes e80 - ebf
+ 0xBF, 0xBE, 0x43, 0xE7, 0x80, 0x9B, 0x43, 0xE7,
+ 0x80, 0x9E, 0x43, 0xE7, 0x80, 0xB9, 0x43, 0xE7,
+ 0x81, 0x8A, 0x43, 0xE7, 0x81, 0xAB, 0x43, 0xE7,
+ 0x81, 0xB0, 0x43, 0xE7, 0x81, 0xB7, 0x43, 0xE7,
+ 0x81, 0xBD, 0x43, 0xE7, 0x82, 0x99, 0x43, 0xE7,
+ 0x82, 0xAD, 0x43, 0xE7, 0x83, 0x88, 0x43, 0xE7,
+ 0x83, 0x99, 0x43, 0xE7, 0x84, 0xA1, 0x43, 0xE7,
+ 0x85, 0x85, 0x43, 0xE7, 0x85, 0x89, 0x43, 0xE7,
+ // Bytes ec0 - eff
+ 0x85, 0xAE, 0x43, 0xE7, 0x86, 0x9C, 0x43, 0xE7,
+ 0x87, 0x8E, 0x43, 0xE7, 0x87, 0x90, 0x43, 0xE7,
+ 0x88, 0x90, 0x43, 0xE7, 0x88, 0x9B, 0x43, 0xE7,
+ 0x88, 0xA8, 0x43, 0xE7, 0x88, 0xAA, 0x43, 0xE7,
+ 0x88, 0xAB, 0x43, 0xE7, 0x88, 0xB5, 0x43, 0xE7,
+ 0x88, 0xB6, 0x43, 0xE7, 0x88, 0xBB, 0x43, 0xE7,
+ 0x88, 0xBF, 0x43, 0xE7, 0x89, 0x87, 0x43, 0xE7,
+ 0x89, 0x90, 0x43, 0xE7, 0x89, 0x99, 0x43, 0xE7,
+ // Bytes f00 - f3f
+ 0x89, 0x9B, 0x43, 0xE7, 0x89, 0xA2, 0x43, 0xE7,
+ 0x89, 0xB9, 0x43, 0xE7, 0x8A, 0x80, 0x43, 0xE7,
+ 0x8A, 0x95, 0x43, 0xE7, 0x8A, 0xAC, 0x43, 0xE7,
+ 0x8A, 0xAF, 0x43, 0xE7, 0x8B, 0x80, 0x43, 0xE7,
+ 0x8B, 0xBC, 0x43, 0xE7, 0x8C, 0xAA, 0x43, 0xE7,
+ 0x8D, 0xB5, 0x43, 0xE7, 0x8D, 0xBA, 0x43, 0xE7,
+ 0x8E, 0x84, 0x43, 0xE7, 0x8E, 0x87, 0x43, 0xE7,
+ 0x8E, 0x89, 0x43, 0xE7, 0x8E, 0x8B, 0x43, 0xE7,
+ // Bytes f40 - f7f
+ 0x8E, 0xA5, 0x43, 0xE7, 0x8E, 0xB2, 0x43, 0xE7,
+ 0x8F, 0x9E, 0x43, 0xE7, 0x90, 0x86, 0x43, 0xE7,
+ 0x90, 0x89, 0x43, 0xE7, 0x90, 0xA2, 0x43, 0xE7,
+ 0x91, 0x87, 0x43, 0xE7, 0x91, 0x9C, 0x43, 0xE7,
+ 0x91, 0xA9, 0x43, 0xE7, 0x91, 0xB1, 0x43, 0xE7,
+ 0x92, 0x85, 0x43, 0xE7, 0x92, 0x89, 0x43, 0xE7,
+ 0x92, 0x98, 0x43, 0xE7, 0x93, 0x8A, 0x43, 0xE7,
+ 0x93, 0x9C, 0x43, 0xE7, 0x93, 0xA6, 0x43, 0xE7,
+ // Bytes f80 - fbf
+ 0x94, 0x86, 0x43, 0xE7, 0x94, 0x98, 0x43, 0xE7,
+ 0x94, 0x9F, 0x43, 0xE7, 0x94, 0xA4, 0x43, 0xE7,
+ 0x94, 0xA8, 0x43, 0xE7, 0x94, 0xB0, 0x43, 0xE7,
+ 0x94, 0xB2, 0x43, 0xE7, 0x94, 0xB3, 0x43, 0xE7,
+ 0x94, 0xB7, 0x43, 0xE7, 0x94, 0xBB, 0x43, 0xE7,
+ 0x94, 0xBE, 0x43, 0xE7, 0x95, 0x99, 0x43, 0xE7,
+ 0x95, 0xA5, 0x43, 0xE7, 0x95, 0xB0, 0x43, 0xE7,
+ 0x96, 0x8B, 0x43, 0xE7, 0x96, 0x92, 0x43, 0xE7,
+ // Bytes fc0 - fff
+ 0x97, 0xA2, 0x43, 0xE7, 0x98, 0x90, 0x43, 0xE7,
+ 0x98, 0x9D, 0x43, 0xE7, 0x98, 0x9F, 0x43, 0xE7,
+ 0x99, 0x82, 0x43, 0xE7, 0x99, 0xA9, 0x43, 0xE7,
+ 0x99, 0xB6, 0x43, 0xE7, 0x99, 0xBD, 0x43, 0xE7,
+ 0x9A, 0xAE, 0x43, 0xE7, 0x9A, 0xBF, 0x43, 0xE7,
+ 0x9B, 0x8A, 0x43, 0xE7, 0x9B, 0x9B, 0x43, 0xE7,
+ 0x9B, 0xA3, 0x43, 0xE7, 0x9B, 0xA7, 0x43, 0xE7,
+ 0x9B, 0xAE, 0x43, 0xE7, 0x9B, 0xB4, 0x43, 0xE7,
+ // Bytes 1000 - 103f
+ 0x9C, 0x81, 0x43, 0xE7, 0x9C, 0x9E, 0x43, 0xE7,
+ 0x9C, 0x9F, 0x43, 0xE7, 0x9D, 0x80, 0x43, 0xE7,
+ 0x9D, 0x8A, 0x43, 0xE7, 0x9E, 0x8B, 0x43, 0xE7,
+ 0x9E, 0xA7, 0x43, 0xE7, 0x9F, 0x9B, 0x43, 0xE7,
+ 0x9F, 0xA2, 0x43, 0xE7, 0x9F, 0xB3, 0x43, 0xE7,
+ 0xA1, 0x8E, 0x43, 0xE7, 0xA1, 0xAB, 0x43, 0xE7,
+ 0xA2, 0x8C, 0x43, 0xE7, 0xA2, 0x91, 0x43, 0xE7,
+ 0xA3, 0x8A, 0x43, 0xE7, 0xA3, 0x8C, 0x43, 0xE7,
+ // Bytes 1040 - 107f
+ 0xA3, 0xBB, 0x43, 0xE7, 0xA4, 0xAA, 0x43, 0xE7,
+ 0xA4, 0xBA, 0x43, 0xE7, 0xA4, 0xBC, 0x43, 0xE7,
+ 0xA4, 0xBE, 0x43, 0xE7, 0xA5, 0x88, 0x43, 0xE7,
+ 0xA5, 0x89, 0x43, 0xE7, 0xA5, 0x90, 0x43, 0xE7,
+ 0xA5, 0x96, 0x43, 0xE7, 0xA5, 0x9D, 0x43, 0xE7,
+ 0xA5, 0x9E, 0x43, 0xE7, 0xA5, 0xA5, 0x43, 0xE7,
+ 0xA5, 0xBF, 0x43, 0xE7, 0xA6, 0x81, 0x43, 0xE7,
+ 0xA6, 0x8D, 0x43, 0xE7, 0xA6, 0x8E, 0x43, 0xE7,
+ // Bytes 1080 - 10bf
+ 0xA6, 0x8F, 0x43, 0xE7, 0xA6, 0xAE, 0x43, 0xE7,
+ 0xA6, 0xB8, 0x43, 0xE7, 0xA6, 0xBE, 0x43, 0xE7,
+ 0xA7, 0x8A, 0x43, 0xE7, 0xA7, 0x98, 0x43, 0xE7,
+ 0xA7, 0xAB, 0x43, 0xE7, 0xA8, 0x9C, 0x43, 0xE7,
+ 0xA9, 0x80, 0x43, 0xE7, 0xA9, 0x8A, 0x43, 0xE7,
+ 0xA9, 0x8F, 0x43, 0xE7, 0xA9, 0xB4, 0x43, 0xE7,
+ 0xA9, 0xBA, 0x43, 0xE7, 0xAA, 0x81, 0x43, 0xE7,
+ 0xAA, 0xB1, 0x43, 0xE7, 0xAB, 0x8B, 0x43, 0xE7,
+ // Bytes 10c0 - 10ff
+ 0xAB, 0xAE, 0x43, 0xE7, 0xAB, 0xB9, 0x43, 0xE7,
+ 0xAC, 0xA0, 0x43, 0xE7, 0xAE, 0x8F, 0x43, 0xE7,
+ 0xAF, 0x80, 0x43, 0xE7, 0xAF, 0x86, 0x43, 0xE7,
+ 0xAF, 0x89, 0x43, 0xE7, 0xB0, 0xBE, 0x43, 0xE7,
+ 0xB1, 0xA0, 0x43, 0xE7, 0xB1, 0xB3, 0x43, 0xE7,
+ 0xB1, 0xBB, 0x43, 0xE7, 0xB2, 0x92, 0x43, 0xE7,
+ 0xB2, 0xBE, 0x43, 0xE7, 0xB3, 0x92, 0x43, 0xE7,
+ 0xB3, 0x96, 0x43, 0xE7, 0xB3, 0xA3, 0x43, 0xE7,
+ // Bytes 1100 - 113f
+ 0xB3, 0xA7, 0x43, 0xE7, 0xB3, 0xA8, 0x43, 0xE7,
+ 0xB3, 0xB8, 0x43, 0xE7, 0xB4, 0x80, 0x43, 0xE7,
+ 0xB4, 0x90, 0x43, 0xE7, 0xB4, 0xA2, 0x43, 0xE7,
+ 0xB4, 0xAF, 0x43, 0xE7, 0xB5, 0x82, 0x43, 0xE7,
+ 0xB5, 0x9B, 0x43, 0xE7, 0xB5, 0xA3, 0x43, 0xE7,
+ 0xB6, 0xA0, 0x43, 0xE7, 0xB6, 0xBE, 0x43, 0xE7,
+ 0xB7, 0x87, 0x43, 0xE7, 0xB7, 0xB4, 0x43, 0xE7,
+ 0xB8, 0x82, 0x43, 0xE7, 0xB8, 0x89, 0x43, 0xE7,
+ // Bytes 1140 - 117f
+ 0xB8, 0xB7, 0x43, 0xE7, 0xB9, 0x81, 0x43, 0xE7,
+ 0xB9, 0x85, 0x43, 0xE7, 0xBC, 0xB6, 0x43, 0xE7,
+ 0xBC, 0xBE, 0x43, 0xE7, 0xBD, 0x91, 0x43, 0xE7,
+ 0xBD, 0xB2, 0x43, 0xE7, 0xBD, 0xB9, 0x43, 0xE7,
+ 0xBD, 0xBA, 0x43, 0xE7, 0xBE, 0x85, 0x43, 0xE7,
+ 0xBE, 0x8A, 0x43, 0xE7, 0xBE, 0x95, 0x43, 0xE7,
+ 0xBE, 0x9A, 0x43, 0xE7, 0xBE, 0xBD, 0x43, 0xE7,
+ 0xBF, 0xBA, 0x43, 0xE8, 0x80, 0x81, 0x43, 0xE8,
+ // Bytes 1180 - 11bf
+ 0x80, 0x85, 0x43, 0xE8, 0x80, 0x8C, 0x43, 0xE8,
+ 0x80, 0x92, 0x43, 0xE8, 0x80, 0xB3, 0x43, 0xE8,
+ 0x81, 0x86, 0x43, 0xE8, 0x81, 0xA0, 0x43, 0xE8,
+ 0x81, 0xAF, 0x43, 0xE8, 0x81, 0xB0, 0x43, 0xE8,
+ 0x81, 0xBE, 0x43, 0xE8, 0x81, 0xBF, 0x43, 0xE8,
+ 0x82, 0x89, 0x43, 0xE8, 0x82, 0x8B, 0x43, 0xE8,
+ 0x82, 0xAD, 0x43, 0xE8, 0x82, 0xB2, 0x43, 0xE8,
+ 0x84, 0x83, 0x43, 0xE8, 0x84, 0xBE, 0x43, 0xE8,
+ // Bytes 11c0 - 11ff
+ 0x87, 0x98, 0x43, 0xE8, 0x87, 0xA3, 0x43, 0xE8,
+ 0x87, 0xA8, 0x43, 0xE8, 0x87, 0xAA, 0x43, 0xE8,
+ 0x87, 0xAD, 0x43, 0xE8, 0x87, 0xB3, 0x43, 0xE8,
+ 0x87, 0xBC, 0x43, 0xE8, 0x88, 0x81, 0x43, 0xE8,
+ 0x88, 0x84, 0x43, 0xE8, 0x88, 0x8C, 0x43, 0xE8,
+ 0x88, 0x98, 0x43, 0xE8, 0x88, 0x9B, 0x43, 0xE8,
+ 0x88, 0x9F, 0x43, 0xE8, 0x89, 0xAE, 0x43, 0xE8,
+ 0x89, 0xAF, 0x43, 0xE8, 0x89, 0xB2, 0x43, 0xE8,
+ // Bytes 1200 - 123f
+ 0x89, 0xB8, 0x43, 0xE8, 0x89, 0xB9, 0x43, 0xE8,
+ 0x8A, 0x8B, 0x43, 0xE8, 0x8A, 0x91, 0x43, 0xE8,
+ 0x8A, 0x9D, 0x43, 0xE8, 0x8A, 0xB1, 0x43, 0xE8,
+ 0x8A, 0xB3, 0x43, 0xE8, 0x8A, 0xBD, 0x43, 0xE8,
+ 0x8B, 0xA5, 0x43, 0xE8, 0x8B, 0xA6, 0x43, 0xE8,
+ 0x8C, 0x9D, 0x43, 0xE8, 0x8C, 0xA3, 0x43, 0xE8,
+ 0x8C, 0xB6, 0x43, 0xE8, 0x8D, 0x92, 0x43, 0xE8,
+ 0x8D, 0x93, 0x43, 0xE8, 0x8D, 0xA3, 0x43, 0xE8,
+ // Bytes 1240 - 127f
+ 0x8E, 0xAD, 0x43, 0xE8, 0x8E, 0xBD, 0x43, 0xE8,
+ 0x8F, 0x89, 0x43, 0xE8, 0x8F, 0x8A, 0x43, 0xE8,
+ 0x8F, 0x8C, 0x43, 0xE8, 0x8F, 0x9C, 0x43, 0xE8,
+ 0x8F, 0xA7, 0x43, 0xE8, 0x8F, 0xAF, 0x43, 0xE8,
+ 0x8F, 0xB1, 0x43, 0xE8, 0x90, 0xBD, 0x43, 0xE8,
+ 0x91, 0x89, 0x43, 0xE8, 0x91, 0x97, 0x43, 0xE8,
+ 0x93, 0xAE, 0x43, 0xE8, 0x93, 0xB1, 0x43, 0xE8,
+ 0x93, 0xB3, 0x43, 0xE8, 0x93, 0xBC, 0x43, 0xE8,
+ // Bytes 1280 - 12bf
+ 0x94, 0x96, 0x43, 0xE8, 0x95, 0xA4, 0x43, 0xE8,
+ 0x97, 0x8D, 0x43, 0xE8, 0x97, 0xBA, 0x43, 0xE8,
+ 0x98, 0x86, 0x43, 0xE8, 0x98, 0x92, 0x43, 0xE8,
+ 0x98, 0xAD, 0x43, 0xE8, 0x98, 0xBF, 0x43, 0xE8,
+ 0x99, 0x8D, 0x43, 0xE8, 0x99, 0x90, 0x43, 0xE8,
+ 0x99, 0x9C, 0x43, 0xE8, 0x99, 0xA7, 0x43, 0xE8,
+ 0x99, 0xA9, 0x43, 0xE8, 0x99, 0xAB, 0x43, 0xE8,
+ 0x9A, 0x88, 0x43, 0xE8, 0x9A, 0xA9, 0x43, 0xE8,
+ // Bytes 12c0 - 12ff
+ 0x9B, 0xA2, 0x43, 0xE8, 0x9C, 0x8E, 0x43, 0xE8,
+ 0x9C, 0xA8, 0x43, 0xE8, 0x9D, 0xAB, 0x43, 0xE8,
+ 0x9D, 0xB9, 0x43, 0xE8, 0x9E, 0x86, 0x43, 0xE8,
+ 0x9E, 0xBA, 0x43, 0xE8, 0x9F, 0xA1, 0x43, 0xE8,
+ 0xA0, 0x81, 0x43, 0xE8, 0xA0, 0x9F, 0x43, 0xE8,
+ 0xA1, 0x80, 0x43, 0xE8, 0xA1, 0x8C, 0x43, 0xE8,
+ 0xA1, 0xA0, 0x43, 0xE8, 0xA1, 0xA3, 0x43, 0xE8,
+ 0xA3, 0x82, 0x43, 0xE8, 0xA3, 0x8F, 0x43, 0xE8,
+ // Bytes 1300 - 133f
+ 0xA3, 0x97, 0x43, 0xE8, 0xA3, 0x9E, 0x43, 0xE8,
+ 0xA3, 0xA1, 0x43, 0xE8, 0xA3, 0xB8, 0x43, 0xE8,
+ 0xA3, 0xBA, 0x43, 0xE8, 0xA4, 0x90, 0x43, 0xE8,
+ 0xA5, 0x81, 0x43, 0xE8, 0xA5, 0xA4, 0x43, 0xE8,
+ 0xA5, 0xBE, 0x43, 0xE8, 0xA6, 0x86, 0x43, 0xE8,
+ 0xA6, 0x8B, 0x43, 0xE8, 0xA6, 0x96, 0x43, 0xE8,
+ 0xA7, 0x92, 0x43, 0xE8, 0xA7, 0xA3, 0x43, 0xE8,
+ 0xA8, 0x80, 0x43, 0xE8, 0xAA, 0xA0, 0x43, 0xE8,
+ // Bytes 1340 - 137f
+ 0xAA, 0xAA, 0x43, 0xE8, 0xAA, 0xBF, 0x43, 0xE8,
+ 0xAB, 0x8B, 0x43, 0xE8, 0xAB, 0x92, 0x43, 0xE8,
+ 0xAB, 0x96, 0x43, 0xE8, 0xAB, 0xAD, 0x43, 0xE8,
+ 0xAB, 0xB8, 0x43, 0xE8, 0xAB, 0xBE, 0x43, 0xE8,
+ 0xAC, 0x81, 0x43, 0xE8, 0xAC, 0xB9, 0x43, 0xE8,
+ 0xAD, 0x98, 0x43, 0xE8, 0xAE, 0x80, 0x43, 0xE8,
+ 0xAE, 0x8A, 0x43, 0xE8, 0xB0, 0xB7, 0x43, 0xE8,
+ 0xB1, 0x86, 0x43, 0xE8, 0xB1, 0x88, 0x43, 0xE8,
+ // Bytes 1380 - 13bf
+ 0xB1, 0x95, 0x43, 0xE8, 0xB1, 0xB8, 0x43, 0xE8,
+ 0xB2, 0x9D, 0x43, 0xE8, 0xB2, 0xA1, 0x43, 0xE8,
+ 0xB2, 0xA9, 0x43, 0xE8, 0xB2, 0xAB, 0x43, 0xE8,
+ 0xB3, 0x81, 0x43, 0xE8, 0xB3, 0x82, 0x43, 0xE8,
+ 0xB3, 0x87, 0x43, 0xE8, 0xB3, 0x88, 0x43, 0xE8,
+ 0xB3, 0x93, 0x43, 0xE8, 0xB4, 0x88, 0x43, 0xE8,
+ 0xB4, 0x9B, 0x43, 0xE8, 0xB5, 0xA4, 0x43, 0xE8,
+ 0xB5, 0xB0, 0x43, 0xE8, 0xB5, 0xB7, 0x43, 0xE8,
+ // Bytes 13c0 - 13ff
+ 0xB6, 0xB3, 0x43, 0xE8, 0xB6, 0xBC, 0x43, 0xE8,
+ 0xB7, 0x8B, 0x43, 0xE8, 0xB7, 0xAF, 0x43, 0xE8,
+ 0xB7, 0xB0, 0x43, 0xE8, 0xBA, 0xAB, 0x43, 0xE8,
+ 0xBB, 0x8A, 0x43, 0xE8, 0xBB, 0x94, 0x43, 0xE8,
+ 0xBC, 0xA6, 0x43, 0xE8, 0xBC, 0xAA, 0x43, 0xE8,
+ 0xBC, 0xB8, 0x43, 0xE8, 0xBC, 0xBB, 0x43, 0xE8,
+ 0xBD, 0xA2, 0x43, 0xE8, 0xBE, 0x9B, 0x43, 0xE8,
+ 0xBE, 0x9E, 0x43, 0xE8, 0xBE, 0xB0, 0x43, 0xE8,
+ // Bytes 1400 - 143f
+ 0xBE, 0xB5, 0x43, 0xE8, 0xBE, 0xB6, 0x43, 0xE9,
+ 0x80, 0xA3, 0x43, 0xE9, 0x80, 0xB8, 0x43, 0xE9,
+ 0x81, 0x8A, 0x43, 0xE9, 0x81, 0xA9, 0x43, 0xE9,
+ 0x81, 0xB2, 0x43, 0xE9, 0x81, 0xBC, 0x43, 0xE9,
+ 0x82, 0x8F, 0x43, 0xE9, 0x82, 0x91, 0x43, 0xE9,
+ 0x82, 0x94, 0x43, 0xE9, 0x83, 0x8E, 0x43, 0xE9,
+ 0x83, 0x9E, 0x43, 0xE9, 0x83, 0xB1, 0x43, 0xE9,
+ 0x83, 0xBD, 0x43, 0xE9, 0x84, 0x91, 0x43, 0xE9,
+ // Bytes 1440 - 147f
+ 0x84, 0x9B, 0x43, 0xE9, 0x85, 0x89, 0x43, 0xE9,
+ 0x85, 0x8D, 0x43, 0xE9, 0x85, 0xAA, 0x43, 0xE9,
+ 0x86, 0x99, 0x43, 0xE9, 0x86, 0xB4, 0x43, 0xE9,
+ 0x87, 0x86, 0x43, 0xE9, 0x87, 0x8C, 0x43, 0xE9,
+ 0x87, 0x8F, 0x43, 0xE9, 0x87, 0x91, 0x43, 0xE9,
+ 0x88, 0xB4, 0x43, 0xE9, 0x88, 0xB8, 0x43, 0xE9,
+ 0x89, 0xB6, 0x43, 0xE9, 0x89, 0xBC, 0x43, 0xE9,
+ 0x8B, 0x97, 0x43, 0xE9, 0x8B, 0x98, 0x43, 0xE9,
+ // Bytes 1480 - 14bf
+ 0x8C, 0x84, 0x43, 0xE9, 0x8D, 0x8A, 0x43, 0xE9,
+ 0x8F, 0xB9, 0x43, 0xE9, 0x90, 0x95, 0x43, 0xE9,
+ 0x95, 0xB7, 0x43, 0xE9, 0x96, 0x80, 0x43, 0xE9,
+ 0x96, 0x8B, 0x43, 0xE9, 0x96, 0xAD, 0x43, 0xE9,
+ 0x96, 0xB7, 0x43, 0xE9, 0x98, 0x9C, 0x43, 0xE9,
+ 0x98, 0xAE, 0x43, 0xE9, 0x99, 0x8B, 0x43, 0xE9,
+ 0x99, 0x8D, 0x43, 0xE9, 0x99, 0xB5, 0x43, 0xE9,
+ 0x99, 0xB8, 0x43, 0xE9, 0x99, 0xBC, 0x43, 0xE9,
+ // Bytes 14c0 - 14ff
+ 0x9A, 0x86, 0x43, 0xE9, 0x9A, 0xA3, 0x43, 0xE9,
+ 0x9A, 0xB6, 0x43, 0xE9, 0x9A, 0xB7, 0x43, 0xE9,
+ 0x9A, 0xB8, 0x43, 0xE9, 0x9A, 0xB9, 0x43, 0xE9,
+ 0x9B, 0x83, 0x43, 0xE9, 0x9B, 0xA2, 0x43, 0xE9,
+ 0x9B, 0xA3, 0x43, 0xE9, 0x9B, 0xA8, 0x43, 0xE9,
+ 0x9B, 0xB6, 0x43, 0xE9, 0x9B, 0xB7, 0x43, 0xE9,
+ 0x9C, 0xA3, 0x43, 0xE9, 0x9C, 0xB2, 0x43, 0xE9,
+ 0x9D, 0x88, 0x43, 0xE9, 0x9D, 0x91, 0x43, 0xE9,
+ // Bytes 1500 - 153f
+ 0x9D, 0x96, 0x43, 0xE9, 0x9D, 0x9E, 0x43, 0xE9,
+ 0x9D, 0xA2, 0x43, 0xE9, 0x9D, 0xA9, 0x43, 0xE9,
+ 0x9F, 0x8B, 0x43, 0xE9, 0x9F, 0x9B, 0x43, 0xE9,
+ 0x9F, 0xA0, 0x43, 0xE9, 0x9F, 0xAD, 0x43, 0xE9,
+ 0x9F, 0xB3, 0x43, 0xE9, 0x9F, 0xBF, 0x43, 0xE9,
+ 0xA0, 0x81, 0x43, 0xE9, 0xA0, 0x85, 0x43, 0xE9,
+ 0xA0, 0x8B, 0x43, 0xE9, 0xA0, 0x98, 0x43, 0xE9,
+ 0xA0, 0xA9, 0x43, 0xE9, 0xA0, 0xBB, 0x43, 0xE9,
+ // Bytes 1540 - 157f
+ 0xA1, 0x9E, 0x43, 0xE9, 0xA2, 0xA8, 0x43, 0xE9,
+ 0xA3, 0x9B, 0x43, 0xE9, 0xA3, 0x9F, 0x43, 0xE9,
+ 0xA3, 0xA2, 0x43, 0xE9, 0xA3, 0xAF, 0x43, 0xE9,
+ 0xA3, 0xBC, 0x43, 0xE9, 0xA4, 0xA8, 0x43, 0xE9,
+ 0xA4, 0xA9, 0x43, 0xE9, 0xA6, 0x96, 0x43, 0xE9,
+ 0xA6, 0x99, 0x43, 0xE9, 0xA6, 0xA7, 0x43, 0xE9,
+ 0xA6, 0xAC, 0x43, 0xE9, 0xA7, 0x82, 0x43, 0xE9,
+ 0xA7, 0xB1, 0x43, 0xE9, 0xA7, 0xBE, 0x43, 0xE9,
+ // Bytes 1580 - 15bf
+ 0xA9, 0xAA, 0x43, 0xE9, 0xAA, 0xA8, 0x43, 0xE9,
+ 0xAB, 0x98, 0x43, 0xE9, 0xAB, 0x9F, 0x43, 0xE9,
+ 0xAC, 0x92, 0x43, 0xE9, 0xAC, 0xA5, 0x43, 0xE9,
+ 0xAC, 0xAF, 0x43, 0xE9, 0xAC, 0xB2, 0x43, 0xE9,
+ 0xAC, 0xBC, 0x43, 0xE9, 0xAD, 0x9A, 0x43, 0xE9,
+ 0xAD, 0xAF, 0x43, 0xE9, 0xB1, 0x80, 0x43, 0xE9,
+ 0xB1, 0x97, 0x43, 0xE9, 0xB3, 0xA5, 0x43, 0xE9,
+ 0xB3, 0xBD, 0x43, 0xE9, 0xB5, 0xA7, 0x43, 0xE9,
+ // Bytes 15c0 - 15ff
+ 0xB6, 0xB4, 0x43, 0xE9, 0xB7, 0xBA, 0x43, 0xE9,
+ 0xB8, 0x9E, 0x43, 0xE9, 0xB9, 0xB5, 0x43, 0xE9,
+ 0xB9, 0xBF, 0x43, 0xE9, 0xBA, 0x97, 0x43, 0xE9,
+ 0xBA, 0x9F, 0x43, 0xE9, 0xBA, 0xA5, 0x43, 0xE9,
+ 0xBA, 0xBB, 0x43, 0xE9, 0xBB, 0x83, 0x43, 0xE9,
+ 0xBB, 0x8D, 0x43, 0xE9, 0xBB, 0x8E, 0x43, 0xE9,
+ 0xBB, 0x91, 0x43, 0xE9, 0xBB, 0xB9, 0x43, 0xE9,
+ 0xBB, 0xBD, 0x43, 0xE9, 0xBB, 0xBE, 0x43, 0xE9,
+ // Bytes 1600 - 163f
+ 0xBC, 0x85, 0x43, 0xE9, 0xBC, 0x8E, 0x43, 0xE9,
+ 0xBC, 0x8F, 0x43, 0xE9, 0xBC, 0x93, 0x43, 0xE9,
+ 0xBC, 0x96, 0x43, 0xE9, 0xBC, 0xA0, 0x43, 0xE9,
+ 0xBC, 0xBB, 0x43, 0xE9, 0xBD, 0x83, 0x43, 0xE9,
+ 0xBD, 0x8A, 0x43, 0xE9, 0xBD, 0x92, 0x43, 0xE9,
+ 0xBE, 0x8D, 0x43, 0xE9, 0xBE, 0x8E, 0x43, 0xE9,
+ 0xBE, 0x9C, 0x43, 0xE9, 0xBE, 0x9F, 0x43, 0xE9,
+ 0xBE, 0xA0, 0x43, 0xEA, 0x9C, 0xA7, 0x43, 0xEA,
+ // Bytes 1640 - 167f
+ 0x9D, 0xAF, 0x43, 0xEA, 0xAC, 0xB7, 0x43, 0xEA,
+ 0xAD, 0x92, 0x44, 0xF0, 0xA0, 0x84, 0xA2, 0x44,
+ 0xF0, 0xA0, 0x94, 0x9C, 0x44, 0xF0, 0xA0, 0x94,
+ 0xA5, 0x44, 0xF0, 0xA0, 0x95, 0x8B, 0x44, 0xF0,
+ 0xA0, 0x98, 0xBA, 0x44, 0xF0, 0xA0, 0xA0, 0x84,
+ 0x44, 0xF0, 0xA0, 0xA3, 0x9E, 0x44, 0xF0, 0xA0,
+ 0xA8, 0xAC, 0x44, 0xF0, 0xA0, 0xAD, 0xA3, 0x44,
+ 0xF0, 0xA1, 0x93, 0xA4, 0x44, 0xF0, 0xA1, 0x9A,
+ // Bytes 1680 - 16bf
+ 0xA8, 0x44, 0xF0, 0xA1, 0x9B, 0xAA, 0x44, 0xF0,
+ 0xA1, 0xA7, 0x88, 0x44, 0xF0, 0xA1, 0xAC, 0x98,
+ 0x44, 0xF0, 0xA1, 0xB4, 0x8B, 0x44, 0xF0, 0xA1,
+ 0xB7, 0xA4, 0x44, 0xF0, 0xA1, 0xB7, 0xA6, 0x44,
+ 0xF0, 0xA2, 0x86, 0x83, 0x44, 0xF0, 0xA2, 0x86,
+ 0x9F, 0x44, 0xF0, 0xA2, 0x8C, 0xB1, 0x44, 0xF0,
+ 0xA2, 0x9B, 0x94, 0x44, 0xF0, 0xA2, 0xA1, 0x84,
+ 0x44, 0xF0, 0xA2, 0xA1, 0x8A, 0x44, 0xF0, 0xA2,
+ // Bytes 16c0 - 16ff
+ 0xAC, 0x8C, 0x44, 0xF0, 0xA2, 0xAF, 0xB1, 0x44,
+ 0xF0, 0xA3, 0x80, 0x8A, 0x44, 0xF0, 0xA3, 0x8A,
+ 0xB8, 0x44, 0xF0, 0xA3, 0x8D, 0x9F, 0x44, 0xF0,
+ 0xA3, 0x8E, 0x93, 0x44, 0xF0, 0xA3, 0x8E, 0x9C,
+ 0x44, 0xF0, 0xA3, 0x8F, 0x83, 0x44, 0xF0, 0xA3,
+ 0x8F, 0x95, 0x44, 0xF0, 0xA3, 0x91, 0xAD, 0x44,
+ 0xF0, 0xA3, 0x9A, 0xA3, 0x44, 0xF0, 0xA3, 0xA2,
+ 0xA7, 0x44, 0xF0, 0xA3, 0xAA, 0x8D, 0x44, 0xF0,
+ // Bytes 1700 - 173f
+ 0xA3, 0xAB, 0xBA, 0x44, 0xF0, 0xA3, 0xB2, 0xBC,
+ 0x44, 0xF0, 0xA3, 0xB4, 0x9E, 0x44, 0xF0, 0xA3,
+ 0xBB, 0x91, 0x44, 0xF0, 0xA3, 0xBD, 0x9E, 0x44,
+ 0xF0, 0xA3, 0xBE, 0x8E, 0x44, 0xF0, 0xA4, 0x89,
+ 0xA3, 0x44, 0xF0, 0xA4, 0x8B, 0xAE, 0x44, 0xF0,
+ 0xA4, 0x8E, 0xAB, 0x44, 0xF0, 0xA4, 0x98, 0x88,
+ 0x44, 0xF0, 0xA4, 0x9C, 0xB5, 0x44, 0xF0, 0xA4,
+ 0xA0, 0x94, 0x44, 0xF0, 0xA4, 0xB0, 0xB6, 0x44,
+ // Bytes 1740 - 177f
+ 0xF0, 0xA4, 0xB2, 0x92, 0x44, 0xF0, 0xA4, 0xBE,
+ 0xA1, 0x44, 0xF0, 0xA4, 0xBE, 0xB8, 0x44, 0xF0,
+ 0xA5, 0x81, 0x84, 0x44, 0xF0, 0xA5, 0x83, 0xB2,
+ 0x44, 0xF0, 0xA5, 0x83, 0xB3, 0x44, 0xF0, 0xA5,
+ 0x84, 0x99, 0x44, 0xF0, 0xA5, 0x84, 0xB3, 0x44,
+ 0xF0, 0xA5, 0x89, 0x89, 0x44, 0xF0, 0xA5, 0x90,
+ 0x9D, 0x44, 0xF0, 0xA5, 0x98, 0xA6, 0x44, 0xF0,
+ 0xA5, 0x9A, 0x9A, 0x44, 0xF0, 0xA5, 0x9B, 0x85,
+ // Bytes 1780 - 17bf
+ 0x44, 0xF0, 0xA5, 0xA5, 0xBC, 0x44, 0xF0, 0xA5,
+ 0xAA, 0xA7, 0x44, 0xF0, 0xA5, 0xAE, 0xAB, 0x44,
+ 0xF0, 0xA5, 0xB2, 0x80, 0x44, 0xF0, 0xA5, 0xB3,
+ 0x90, 0x44, 0xF0, 0xA5, 0xBE, 0x86, 0x44, 0xF0,
+ 0xA6, 0x87, 0x9A, 0x44, 0xF0, 0xA6, 0x88, 0xA8,
+ 0x44, 0xF0, 0xA6, 0x89, 0x87, 0x44, 0xF0, 0xA6,
+ 0x8B, 0x99, 0x44, 0xF0, 0xA6, 0x8C, 0xBE, 0x44,
+ 0xF0, 0xA6, 0x93, 0x9A, 0x44, 0xF0, 0xA6, 0x94,
+ // Bytes 17c0 - 17ff
+ 0xA3, 0x44, 0xF0, 0xA6, 0x96, 0xA8, 0x44, 0xF0,
+ 0xA6, 0x9E, 0xA7, 0x44, 0xF0, 0xA6, 0x9E, 0xB5,
+ 0x44, 0xF0, 0xA6, 0xAC, 0xBC, 0x44, 0xF0, 0xA6,
+ 0xB0, 0xB6, 0x44, 0xF0, 0xA6, 0xB3, 0x95, 0x44,
+ 0xF0, 0xA6, 0xB5, 0xAB, 0x44, 0xF0, 0xA6, 0xBC,
+ 0xAC, 0x44, 0xF0, 0xA6, 0xBE, 0xB1, 0x44, 0xF0,
+ 0xA7, 0x83, 0x92, 0x44, 0xF0, 0xA7, 0x8F, 0x8A,
+ 0x44, 0xF0, 0xA7, 0x99, 0xA7, 0x44, 0xF0, 0xA7,
+ // Bytes 1800 - 183f
+ 0xA2, 0xAE, 0x44, 0xF0, 0xA7, 0xA5, 0xA6, 0x44,
+ 0xF0, 0xA7, 0xB2, 0xA8, 0x44, 0xF0, 0xA7, 0xBB,
+ 0x93, 0x44, 0xF0, 0xA7, 0xBC, 0xAF, 0x44, 0xF0,
+ 0xA8, 0x97, 0x92, 0x44, 0xF0, 0xA8, 0x97, 0xAD,
+ 0x44, 0xF0, 0xA8, 0x9C, 0xAE, 0x44, 0xF0, 0xA8,
+ 0xAF, 0xBA, 0x44, 0xF0, 0xA8, 0xB5, 0xB7, 0x44,
+ 0xF0, 0xA9, 0x85, 0x85, 0x44, 0xF0, 0xA9, 0x87,
+ 0x9F, 0x44, 0xF0, 0xA9, 0x88, 0x9A, 0x44, 0xF0,
+ // Bytes 1840 - 187f
+ 0xA9, 0x90, 0x8A, 0x44, 0xF0, 0xA9, 0x92, 0x96,
+ 0x44, 0xF0, 0xA9, 0x96, 0xB6, 0x44, 0xF0, 0xA9,
+ 0xAC, 0xB0, 0x44, 0xF0, 0xAA, 0x83, 0x8E, 0x44,
+ 0xF0, 0xAA, 0x84, 0x85, 0x44, 0xF0, 0xAA, 0x88,
+ 0x8E, 0x44, 0xF0, 0xAA, 0x8A, 0x91, 0x44, 0xF0,
+ 0xAA, 0x8E, 0x92, 0x44, 0xF0, 0xAA, 0x98, 0x80,
+ 0x42, 0x21, 0x21, 0x42, 0x21, 0x3F, 0x42, 0x2E,
+ 0x2E, 0x42, 0x30, 0x2C, 0x42, 0x30, 0x2E, 0x42,
+ // Bytes 1880 - 18bf
+ 0x31, 0x2C, 0x42, 0x31, 0x2E, 0x42, 0x31, 0x30,
+ 0x42, 0x31, 0x31, 0x42, 0x31, 0x32, 0x42, 0x31,
+ 0x33, 0x42, 0x31, 0x34, 0x42, 0x31, 0x35, 0x42,
+ 0x31, 0x36, 0x42, 0x31, 0x37, 0x42, 0x31, 0x38,
+ 0x42, 0x31, 0x39, 0x42, 0x32, 0x2C, 0x42, 0x32,
+ 0x2E, 0x42, 0x32, 0x30, 0x42, 0x32, 0x31, 0x42,
+ 0x32, 0x32, 0x42, 0x32, 0x33, 0x42, 0x32, 0x34,
+ 0x42, 0x32, 0x35, 0x42, 0x32, 0x36, 0x42, 0x32,
+ // Bytes 18c0 - 18ff
+ 0x37, 0x42, 0x32, 0x38, 0x42, 0x32, 0x39, 0x42,
+ 0x33, 0x2C, 0x42, 0x33, 0x2E, 0x42, 0x33, 0x30,
+ 0x42, 0x33, 0x31, 0x42, 0x33, 0x32, 0x42, 0x33,
+ 0x33, 0x42, 0x33, 0x34, 0x42, 0x33, 0x35, 0x42,
+ 0x33, 0x36, 0x42, 0x33, 0x37, 0x42, 0x33, 0x38,
+ 0x42, 0x33, 0x39, 0x42, 0x34, 0x2C, 0x42, 0x34,
+ 0x2E, 0x42, 0x34, 0x30, 0x42, 0x34, 0x31, 0x42,
+ 0x34, 0x32, 0x42, 0x34, 0x33, 0x42, 0x34, 0x34,
+ // Bytes 1900 - 193f
+ 0x42, 0x34, 0x35, 0x42, 0x34, 0x36, 0x42, 0x34,
+ 0x37, 0x42, 0x34, 0x38, 0x42, 0x34, 0x39, 0x42,
+ 0x35, 0x2C, 0x42, 0x35, 0x2E, 0x42, 0x35, 0x30,
+ 0x42, 0x36, 0x2C, 0x42, 0x36, 0x2E, 0x42, 0x37,
+ 0x2C, 0x42, 0x37, 0x2E, 0x42, 0x38, 0x2C, 0x42,
+ 0x38, 0x2E, 0x42, 0x39, 0x2C, 0x42, 0x39, 0x2E,
+ 0x42, 0x3D, 0x3D, 0x42, 0x3F, 0x21, 0x42, 0x3F,
+ 0x3F, 0x42, 0x41, 0x55, 0x42, 0x42, 0x71, 0x42,
+ // Bytes 1940 - 197f
+ 0x43, 0x44, 0x42, 0x44, 0x4A, 0x42, 0x44, 0x5A,
+ 0x42, 0x44, 0x7A, 0x42, 0x47, 0x42, 0x42, 0x47,
+ 0x79, 0x42, 0x48, 0x50, 0x42, 0x48, 0x56, 0x42,
+ 0x48, 0x67, 0x42, 0x48, 0x7A, 0x42, 0x49, 0x49,
+ 0x42, 0x49, 0x4A, 0x42, 0x49, 0x55, 0x42, 0x49,
+ 0x56, 0x42, 0x49, 0x58, 0x42, 0x4B, 0x42, 0x42,
+ 0x4B, 0x4B, 0x42, 0x4B, 0x4D, 0x42, 0x4C, 0x4A,
+ 0x42, 0x4C, 0x6A, 0x42, 0x4D, 0x42, 0x42, 0x4D,
+ // Bytes 1980 - 19bf
+ 0x43, 0x42, 0x4D, 0x44, 0x42, 0x4D, 0x52, 0x42,
+ 0x4D, 0x56, 0x42, 0x4D, 0x57, 0x42, 0x4E, 0x4A,
+ 0x42, 0x4E, 0x6A, 0x42, 0x4E, 0x6F, 0x42, 0x50,
+ 0x48, 0x42, 0x50, 0x52, 0x42, 0x50, 0x61, 0x42,
+ 0x52, 0x73, 0x42, 0x53, 0x44, 0x42, 0x53, 0x4D,
+ 0x42, 0x53, 0x53, 0x42, 0x53, 0x76, 0x42, 0x54,
+ 0x4D, 0x42, 0x56, 0x49, 0x42, 0x57, 0x43, 0x42,
+ 0x57, 0x5A, 0x42, 0x57, 0x62, 0x42, 0x58, 0x49,
+ // Bytes 19c0 - 19ff
+ 0x42, 0x63, 0x63, 0x42, 0x63, 0x64, 0x42, 0x63,
+ 0x6D, 0x42, 0x64, 0x42, 0x42, 0x64, 0x61, 0x42,
+ 0x64, 0x6C, 0x42, 0x64, 0x6D, 0x42, 0x64, 0x7A,
+ 0x42, 0x65, 0x56, 0x42, 0x66, 0x66, 0x42, 0x66,
+ 0x69, 0x42, 0x66, 0x6C, 0x42, 0x66, 0x6D, 0x42,
+ 0x68, 0x61, 0x42, 0x69, 0x69, 0x42, 0x69, 0x6A,
+ 0x42, 0x69, 0x6E, 0x42, 0x69, 0x76, 0x42, 0x69,
+ 0x78, 0x42, 0x6B, 0x41, 0x42, 0x6B, 0x56, 0x42,
+ // Bytes 1a00 - 1a3f
+ 0x6B, 0x57, 0x42, 0x6B, 0x67, 0x42, 0x6B, 0x6C,
+ 0x42, 0x6B, 0x6D, 0x42, 0x6B, 0x74, 0x42, 0x6C,
+ 0x6A, 0x42, 0x6C, 0x6D, 0x42, 0x6C, 0x6E, 0x42,
+ 0x6C, 0x78, 0x42, 0x6D, 0x32, 0x42, 0x6D, 0x33,
+ 0x42, 0x6D, 0x41, 0x42, 0x6D, 0x56, 0x42, 0x6D,
+ 0x57, 0x42, 0x6D, 0x62, 0x42, 0x6D, 0x67, 0x42,
+ 0x6D, 0x6C, 0x42, 0x6D, 0x6D, 0x42, 0x6D, 0x73,
+ 0x42, 0x6E, 0x41, 0x42, 0x6E, 0x46, 0x42, 0x6E,
+ // Bytes 1a40 - 1a7f
+ 0x56, 0x42, 0x6E, 0x57, 0x42, 0x6E, 0x6A, 0x42,
+ 0x6E, 0x6D, 0x42, 0x6E, 0x73, 0x42, 0x6F, 0x56,
+ 0x42, 0x70, 0x41, 0x42, 0x70, 0x46, 0x42, 0x70,
+ 0x56, 0x42, 0x70, 0x57, 0x42, 0x70, 0x63, 0x42,
+ 0x70, 0x73, 0x42, 0x73, 0x72, 0x42, 0x73, 0x74,
+ 0x42, 0x76, 0x69, 0x42, 0x78, 0x69, 0x43, 0x28,
+ 0x31, 0x29, 0x43, 0x28, 0x32, 0x29, 0x43, 0x28,
+ 0x33, 0x29, 0x43, 0x28, 0x34, 0x29, 0x43, 0x28,
+ // Bytes 1a80 - 1abf
+ 0x35, 0x29, 0x43, 0x28, 0x36, 0x29, 0x43, 0x28,
+ 0x37, 0x29, 0x43, 0x28, 0x38, 0x29, 0x43, 0x28,
+ 0x39, 0x29, 0x43, 0x28, 0x41, 0x29, 0x43, 0x28,
+ 0x42, 0x29, 0x43, 0x28, 0x43, 0x29, 0x43, 0x28,
+ 0x44, 0x29, 0x43, 0x28, 0x45, 0x29, 0x43, 0x28,
+ 0x46, 0x29, 0x43, 0x28, 0x47, 0x29, 0x43, 0x28,
+ 0x48, 0x29, 0x43, 0x28, 0x49, 0x29, 0x43, 0x28,
+ 0x4A, 0x29, 0x43, 0x28, 0x4B, 0x29, 0x43, 0x28,
+ // Bytes 1ac0 - 1aff
+ 0x4C, 0x29, 0x43, 0x28, 0x4D, 0x29, 0x43, 0x28,
+ 0x4E, 0x29, 0x43, 0x28, 0x4F, 0x29, 0x43, 0x28,
+ 0x50, 0x29, 0x43, 0x28, 0x51, 0x29, 0x43, 0x28,
+ 0x52, 0x29, 0x43, 0x28, 0x53, 0x29, 0x43, 0x28,
+ 0x54, 0x29, 0x43, 0x28, 0x55, 0x29, 0x43, 0x28,
+ 0x56, 0x29, 0x43, 0x28, 0x57, 0x29, 0x43, 0x28,
+ 0x58, 0x29, 0x43, 0x28, 0x59, 0x29, 0x43, 0x28,
+ 0x5A, 0x29, 0x43, 0x28, 0x61, 0x29, 0x43, 0x28,
+ // Bytes 1b00 - 1b3f
+ 0x62, 0x29, 0x43, 0x28, 0x63, 0x29, 0x43, 0x28,
+ 0x64, 0x29, 0x43, 0x28, 0x65, 0x29, 0x43, 0x28,
+ 0x66, 0x29, 0x43, 0x28, 0x67, 0x29, 0x43, 0x28,
+ 0x68, 0x29, 0x43, 0x28, 0x69, 0x29, 0x43, 0x28,
+ 0x6A, 0x29, 0x43, 0x28, 0x6B, 0x29, 0x43, 0x28,
+ 0x6C, 0x29, 0x43, 0x28, 0x6D, 0x29, 0x43, 0x28,
+ 0x6E, 0x29, 0x43, 0x28, 0x6F, 0x29, 0x43, 0x28,
+ 0x70, 0x29, 0x43, 0x28, 0x71, 0x29, 0x43, 0x28,
+ // Bytes 1b40 - 1b7f
+ 0x72, 0x29, 0x43, 0x28, 0x73, 0x29, 0x43, 0x28,
+ 0x74, 0x29, 0x43, 0x28, 0x75, 0x29, 0x43, 0x28,
+ 0x76, 0x29, 0x43, 0x28, 0x77, 0x29, 0x43, 0x28,
+ 0x78, 0x29, 0x43, 0x28, 0x79, 0x29, 0x43, 0x28,
+ 0x7A, 0x29, 0x43, 0x2E, 0x2E, 0x2E, 0x43, 0x31,
+ 0x30, 0x2E, 0x43, 0x31, 0x31, 0x2E, 0x43, 0x31,
+ 0x32, 0x2E, 0x43, 0x31, 0x33, 0x2E, 0x43, 0x31,
+ 0x34, 0x2E, 0x43, 0x31, 0x35, 0x2E, 0x43, 0x31,
+ // Bytes 1b80 - 1bbf
+ 0x36, 0x2E, 0x43, 0x31, 0x37, 0x2E, 0x43, 0x31,
+ 0x38, 0x2E, 0x43, 0x31, 0x39, 0x2E, 0x43, 0x32,
+ 0x30, 0x2E, 0x43, 0x3A, 0x3A, 0x3D, 0x43, 0x3D,
+ 0x3D, 0x3D, 0x43, 0x43, 0x6F, 0x2E, 0x43, 0x46,
+ 0x41, 0x58, 0x43, 0x47, 0x48, 0x7A, 0x43, 0x47,
+ 0x50, 0x61, 0x43, 0x49, 0x49, 0x49, 0x43, 0x4C,
+ 0x54, 0x44, 0x43, 0x4C, 0xC2, 0xB7, 0x43, 0x4D,
+ 0x48, 0x7A, 0x43, 0x4D, 0x50, 0x61, 0x43, 0x4D,
+ // Bytes 1bc0 - 1bff
+ 0xCE, 0xA9, 0x43, 0x50, 0x50, 0x4D, 0x43, 0x50,
+ 0x50, 0x56, 0x43, 0x50, 0x54, 0x45, 0x43, 0x54,
+ 0x45, 0x4C, 0x43, 0x54, 0x48, 0x7A, 0x43, 0x56,
+ 0x49, 0x49, 0x43, 0x58, 0x49, 0x49, 0x43, 0x61,
+ 0x2F, 0x63, 0x43, 0x61, 0x2F, 0x73, 0x43, 0x61,
+ 0xCA, 0xBE, 0x43, 0x62, 0x61, 0x72, 0x43, 0x63,
+ 0x2F, 0x6F, 0x43, 0x63, 0x2F, 0x75, 0x43, 0x63,
+ 0x61, 0x6C, 0x43, 0x63, 0x6D, 0x32, 0x43, 0x63,
+ // Bytes 1c00 - 1c3f
+ 0x6D, 0x33, 0x43, 0x64, 0x6D, 0x32, 0x43, 0x64,
+ 0x6D, 0x33, 0x43, 0x65, 0x72, 0x67, 0x43, 0x66,
+ 0x66, 0x69, 0x43, 0x66, 0x66, 0x6C, 0x43, 0x67,
+ 0x61, 0x6C, 0x43, 0x68, 0x50, 0x61, 0x43, 0x69,
+ 0x69, 0x69, 0x43, 0x6B, 0x48, 0x7A, 0x43, 0x6B,
+ 0x50, 0x61, 0x43, 0x6B, 0x6D, 0x32, 0x43, 0x6B,
+ 0x6D, 0x33, 0x43, 0x6B, 0xCE, 0xA9, 0x43, 0x6C,
+ 0x6F, 0x67, 0x43, 0x6C, 0xC2, 0xB7, 0x43, 0x6D,
+ // Bytes 1c40 - 1c7f
+ 0x69, 0x6C, 0x43, 0x6D, 0x6D, 0x32, 0x43, 0x6D,
+ 0x6D, 0x33, 0x43, 0x6D, 0x6F, 0x6C, 0x43, 0x72,
+ 0x61, 0x64, 0x43, 0x76, 0x69, 0x69, 0x43, 0x78,
+ 0x69, 0x69, 0x43, 0xC2, 0xB0, 0x43, 0x43, 0xC2,
+ 0xB0, 0x46, 0x43, 0xCA, 0xBC, 0x6E, 0x43, 0xCE,
+ 0xBC, 0x41, 0x43, 0xCE, 0xBC, 0x46, 0x43, 0xCE,
+ 0xBC, 0x56, 0x43, 0xCE, 0xBC, 0x57, 0x43, 0xCE,
+ 0xBC, 0x67, 0x43, 0xCE, 0xBC, 0x6C, 0x43, 0xCE,
+ // Bytes 1c80 - 1cbf
+ 0xBC, 0x6D, 0x43, 0xCE, 0xBC, 0x73, 0x44, 0x28,
+ 0x31, 0x30, 0x29, 0x44, 0x28, 0x31, 0x31, 0x29,
+ 0x44, 0x28, 0x31, 0x32, 0x29, 0x44, 0x28, 0x31,
+ 0x33, 0x29, 0x44, 0x28, 0x31, 0x34, 0x29, 0x44,
+ 0x28, 0x31, 0x35, 0x29, 0x44, 0x28, 0x31, 0x36,
+ 0x29, 0x44, 0x28, 0x31, 0x37, 0x29, 0x44, 0x28,
+ 0x31, 0x38, 0x29, 0x44, 0x28, 0x31, 0x39, 0x29,
+ 0x44, 0x28, 0x32, 0x30, 0x29, 0x44, 0x30, 0xE7,
+ // Bytes 1cc0 - 1cff
+ 0x82, 0xB9, 0x44, 0x31, 0xE2, 0x81, 0x84, 0x44,
+ 0x31, 0xE6, 0x97, 0xA5, 0x44, 0x31, 0xE6, 0x9C,
+ 0x88, 0x44, 0x31, 0xE7, 0x82, 0xB9, 0x44, 0x32,
+ 0xE6, 0x97, 0xA5, 0x44, 0x32, 0xE6, 0x9C, 0x88,
+ 0x44, 0x32, 0xE7, 0x82, 0xB9, 0x44, 0x33, 0xE6,
+ 0x97, 0xA5, 0x44, 0x33, 0xE6, 0x9C, 0x88, 0x44,
+ 0x33, 0xE7, 0x82, 0xB9, 0x44, 0x34, 0xE6, 0x97,
+ 0xA5, 0x44, 0x34, 0xE6, 0x9C, 0x88, 0x44, 0x34,
+ // Bytes 1d00 - 1d3f
+ 0xE7, 0x82, 0xB9, 0x44, 0x35, 0xE6, 0x97, 0xA5,
+ 0x44, 0x35, 0xE6, 0x9C, 0x88, 0x44, 0x35, 0xE7,
+ 0x82, 0xB9, 0x44, 0x36, 0xE6, 0x97, 0xA5, 0x44,
+ 0x36, 0xE6, 0x9C, 0x88, 0x44, 0x36, 0xE7, 0x82,
+ 0xB9, 0x44, 0x37, 0xE6, 0x97, 0xA5, 0x44, 0x37,
+ 0xE6, 0x9C, 0x88, 0x44, 0x37, 0xE7, 0x82, 0xB9,
+ 0x44, 0x38, 0xE6, 0x97, 0xA5, 0x44, 0x38, 0xE6,
+ 0x9C, 0x88, 0x44, 0x38, 0xE7, 0x82, 0xB9, 0x44,
+ // Bytes 1d40 - 1d7f
+ 0x39, 0xE6, 0x97, 0xA5, 0x44, 0x39, 0xE6, 0x9C,
+ 0x88, 0x44, 0x39, 0xE7, 0x82, 0xB9, 0x44, 0x56,
+ 0x49, 0x49, 0x49, 0x44, 0x61, 0x2E, 0x6D, 0x2E,
+ 0x44, 0x6B, 0x63, 0x61, 0x6C, 0x44, 0x70, 0x2E,
+ 0x6D, 0x2E, 0x44, 0x76, 0x69, 0x69, 0x69, 0x44,
+ 0xD5, 0xA5, 0xD6, 0x82, 0x44, 0xD5, 0xB4, 0xD5,
+ 0xA5, 0x44, 0xD5, 0xB4, 0xD5, 0xAB, 0x44, 0xD5,
+ 0xB4, 0xD5, 0xAD, 0x44, 0xD5, 0xB4, 0xD5, 0xB6,
+ // Bytes 1d80 - 1dbf
+ 0x44, 0xD5, 0xBE, 0xD5, 0xB6, 0x44, 0xD7, 0x90,
+ 0xD7, 0x9C, 0x44, 0xD8, 0xA7, 0xD9, 0xB4, 0x44,
+ 0xD8, 0xA8, 0xD8, 0xAC, 0x44, 0xD8, 0xA8, 0xD8,
+ 0xAD, 0x44, 0xD8, 0xA8, 0xD8, 0xAE, 0x44, 0xD8,
+ 0xA8, 0xD8, 0xB1, 0x44, 0xD8, 0xA8, 0xD8, 0xB2,
+ 0x44, 0xD8, 0xA8, 0xD9, 0x85, 0x44, 0xD8, 0xA8,
+ 0xD9, 0x86, 0x44, 0xD8, 0xA8, 0xD9, 0x87, 0x44,
+ 0xD8, 0xA8, 0xD9, 0x89, 0x44, 0xD8, 0xA8, 0xD9,
+ // Bytes 1dc0 - 1dff
+ 0x8A, 0x44, 0xD8, 0xAA, 0xD8, 0xAC, 0x44, 0xD8,
+ 0xAA, 0xD8, 0xAD, 0x44, 0xD8, 0xAA, 0xD8, 0xAE,
+ 0x44, 0xD8, 0xAA, 0xD8, 0xB1, 0x44, 0xD8, 0xAA,
+ 0xD8, 0xB2, 0x44, 0xD8, 0xAA, 0xD9, 0x85, 0x44,
+ 0xD8, 0xAA, 0xD9, 0x86, 0x44, 0xD8, 0xAA, 0xD9,
+ 0x87, 0x44, 0xD8, 0xAA, 0xD9, 0x89, 0x44, 0xD8,
+ 0xAA, 0xD9, 0x8A, 0x44, 0xD8, 0xAB, 0xD8, 0xAC,
+ 0x44, 0xD8, 0xAB, 0xD8, 0xB1, 0x44, 0xD8, 0xAB,
+ // Bytes 1e00 - 1e3f
+ 0xD8, 0xB2, 0x44, 0xD8, 0xAB, 0xD9, 0x85, 0x44,
+ 0xD8, 0xAB, 0xD9, 0x86, 0x44, 0xD8, 0xAB, 0xD9,
+ 0x87, 0x44, 0xD8, 0xAB, 0xD9, 0x89, 0x44, 0xD8,
+ 0xAB, 0xD9, 0x8A, 0x44, 0xD8, 0xAC, 0xD8, 0xAD,
+ 0x44, 0xD8, 0xAC, 0xD9, 0x85, 0x44, 0xD8, 0xAC,
+ 0xD9, 0x89, 0x44, 0xD8, 0xAC, 0xD9, 0x8A, 0x44,
+ 0xD8, 0xAD, 0xD8, 0xAC, 0x44, 0xD8, 0xAD, 0xD9,
+ 0x85, 0x44, 0xD8, 0xAD, 0xD9, 0x89, 0x44, 0xD8,
+ // Bytes 1e40 - 1e7f
+ 0xAD, 0xD9, 0x8A, 0x44, 0xD8, 0xAE, 0xD8, 0xAC,
+ 0x44, 0xD8, 0xAE, 0xD8, 0xAD, 0x44, 0xD8, 0xAE,
+ 0xD9, 0x85, 0x44, 0xD8, 0xAE, 0xD9, 0x89, 0x44,
+ 0xD8, 0xAE, 0xD9, 0x8A, 0x44, 0xD8, 0xB3, 0xD8,
+ 0xAC, 0x44, 0xD8, 0xB3, 0xD8, 0xAD, 0x44, 0xD8,
+ 0xB3, 0xD8, 0xAE, 0x44, 0xD8, 0xB3, 0xD8, 0xB1,
+ 0x44, 0xD8, 0xB3, 0xD9, 0x85, 0x44, 0xD8, 0xB3,
+ 0xD9, 0x87, 0x44, 0xD8, 0xB3, 0xD9, 0x89, 0x44,
+ // Bytes 1e80 - 1ebf
+ 0xD8, 0xB3, 0xD9, 0x8A, 0x44, 0xD8, 0xB4, 0xD8,
+ 0xAC, 0x44, 0xD8, 0xB4, 0xD8, 0xAD, 0x44, 0xD8,
+ 0xB4, 0xD8, 0xAE, 0x44, 0xD8, 0xB4, 0xD8, 0xB1,
+ 0x44, 0xD8, 0xB4, 0xD9, 0x85, 0x44, 0xD8, 0xB4,
+ 0xD9, 0x87, 0x44, 0xD8, 0xB4, 0xD9, 0x89, 0x44,
+ 0xD8, 0xB4, 0xD9, 0x8A, 0x44, 0xD8, 0xB5, 0xD8,
+ 0xAD, 0x44, 0xD8, 0xB5, 0xD8, 0xAE, 0x44, 0xD8,
+ 0xB5, 0xD8, 0xB1, 0x44, 0xD8, 0xB5, 0xD9, 0x85,
+ // Bytes 1ec0 - 1eff
+ 0x44, 0xD8, 0xB5, 0xD9, 0x89, 0x44, 0xD8, 0xB5,
+ 0xD9, 0x8A, 0x44, 0xD8, 0xB6, 0xD8, 0xAC, 0x44,
+ 0xD8, 0xB6, 0xD8, 0xAD, 0x44, 0xD8, 0xB6, 0xD8,
+ 0xAE, 0x44, 0xD8, 0xB6, 0xD8, 0xB1, 0x44, 0xD8,
+ 0xB6, 0xD9, 0x85, 0x44, 0xD8, 0xB6, 0xD9, 0x89,
+ 0x44, 0xD8, 0xB6, 0xD9, 0x8A, 0x44, 0xD8, 0xB7,
+ 0xD8, 0xAD, 0x44, 0xD8, 0xB7, 0xD9, 0x85, 0x44,
+ 0xD8, 0xB7, 0xD9, 0x89, 0x44, 0xD8, 0xB7, 0xD9,
+ // Bytes 1f00 - 1f3f
+ 0x8A, 0x44, 0xD8, 0xB8, 0xD9, 0x85, 0x44, 0xD8,
+ 0xB9, 0xD8, 0xAC, 0x44, 0xD8, 0xB9, 0xD9, 0x85,
+ 0x44, 0xD8, 0xB9, 0xD9, 0x89, 0x44, 0xD8, 0xB9,
+ 0xD9, 0x8A, 0x44, 0xD8, 0xBA, 0xD8, 0xAC, 0x44,
+ 0xD8, 0xBA, 0xD9, 0x85, 0x44, 0xD8, 0xBA, 0xD9,
+ 0x89, 0x44, 0xD8, 0xBA, 0xD9, 0x8A, 0x44, 0xD9,
+ 0x81, 0xD8, 0xAC, 0x44, 0xD9, 0x81, 0xD8, 0xAD,
+ 0x44, 0xD9, 0x81, 0xD8, 0xAE, 0x44, 0xD9, 0x81,
+ // Bytes 1f40 - 1f7f
+ 0xD9, 0x85, 0x44, 0xD9, 0x81, 0xD9, 0x89, 0x44,
+ 0xD9, 0x81, 0xD9, 0x8A, 0x44, 0xD9, 0x82, 0xD8,
+ 0xAD, 0x44, 0xD9, 0x82, 0xD9, 0x85, 0x44, 0xD9,
+ 0x82, 0xD9, 0x89, 0x44, 0xD9, 0x82, 0xD9, 0x8A,
+ 0x44, 0xD9, 0x83, 0xD8, 0xA7, 0x44, 0xD9, 0x83,
+ 0xD8, 0xAC, 0x44, 0xD9, 0x83, 0xD8, 0xAD, 0x44,
+ 0xD9, 0x83, 0xD8, 0xAE, 0x44, 0xD9, 0x83, 0xD9,
+ 0x84, 0x44, 0xD9, 0x83, 0xD9, 0x85, 0x44, 0xD9,
+ // Bytes 1f80 - 1fbf
+ 0x83, 0xD9, 0x89, 0x44, 0xD9, 0x83, 0xD9, 0x8A,
+ 0x44, 0xD9, 0x84, 0xD8, 0xA7, 0x44, 0xD9, 0x84,
+ 0xD8, 0xAC, 0x44, 0xD9, 0x84, 0xD8, 0xAD, 0x44,
+ 0xD9, 0x84, 0xD8, 0xAE, 0x44, 0xD9, 0x84, 0xD9,
+ 0x85, 0x44, 0xD9, 0x84, 0xD9, 0x87, 0x44, 0xD9,
+ 0x84, 0xD9, 0x89, 0x44, 0xD9, 0x84, 0xD9, 0x8A,
+ 0x44, 0xD9, 0x85, 0xD8, 0xA7, 0x44, 0xD9, 0x85,
+ 0xD8, 0xAC, 0x44, 0xD9, 0x85, 0xD8, 0xAD, 0x44,
+ // Bytes 1fc0 - 1fff
+ 0xD9, 0x85, 0xD8, 0xAE, 0x44, 0xD9, 0x85, 0xD9,
+ 0x85, 0x44, 0xD9, 0x85, 0xD9, 0x89, 0x44, 0xD9,
+ 0x85, 0xD9, 0x8A, 0x44, 0xD9, 0x86, 0xD8, 0xAC,
+ 0x44, 0xD9, 0x86, 0xD8, 0xAD, 0x44, 0xD9, 0x86,
+ 0xD8, 0xAE, 0x44, 0xD9, 0x86, 0xD8, 0xB1, 0x44,
+ 0xD9, 0x86, 0xD8, 0xB2, 0x44, 0xD9, 0x86, 0xD9,
+ 0x85, 0x44, 0xD9, 0x86, 0xD9, 0x86, 0x44, 0xD9,
+ 0x86, 0xD9, 0x87, 0x44, 0xD9, 0x86, 0xD9, 0x89,
+ // Bytes 2000 - 203f
+ 0x44, 0xD9, 0x86, 0xD9, 0x8A, 0x44, 0xD9, 0x87,
+ 0xD8, 0xAC, 0x44, 0xD9, 0x87, 0xD9, 0x85, 0x44,
+ 0xD9, 0x87, 0xD9, 0x89, 0x44, 0xD9, 0x87, 0xD9,
+ 0x8A, 0x44, 0xD9, 0x88, 0xD9, 0xB4, 0x44, 0xD9,
+ 0x8A, 0xD8, 0xAC, 0x44, 0xD9, 0x8A, 0xD8, 0xAD,
+ 0x44, 0xD9, 0x8A, 0xD8, 0xAE, 0x44, 0xD9, 0x8A,
+ 0xD8, 0xB1, 0x44, 0xD9, 0x8A, 0xD8, 0xB2, 0x44,
+ 0xD9, 0x8A, 0xD9, 0x85, 0x44, 0xD9, 0x8A, 0xD9,
+ // Bytes 2040 - 207f
+ 0x86, 0x44, 0xD9, 0x8A, 0xD9, 0x87, 0x44, 0xD9,
+ 0x8A, 0xD9, 0x89, 0x44, 0xD9, 0x8A, 0xD9, 0x8A,
+ 0x44, 0xD9, 0x8A, 0xD9, 0xB4, 0x44, 0xDB, 0x87,
+ 0xD9, 0xB4, 0x45, 0x28, 0xE1, 0x84, 0x80, 0x29,
+ 0x45, 0x28, 0xE1, 0x84, 0x82, 0x29, 0x45, 0x28,
+ 0xE1, 0x84, 0x83, 0x29, 0x45, 0x28, 0xE1, 0x84,
+ 0x85, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x86, 0x29,
+ 0x45, 0x28, 0xE1, 0x84, 0x87, 0x29, 0x45, 0x28,
+ // Bytes 2080 - 20bf
+ 0xE1, 0x84, 0x89, 0x29, 0x45, 0x28, 0xE1, 0x84,
+ 0x8B, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x8C, 0x29,
+ 0x45, 0x28, 0xE1, 0x84, 0x8E, 0x29, 0x45, 0x28,
+ 0xE1, 0x84, 0x8F, 0x29, 0x45, 0x28, 0xE1, 0x84,
+ 0x90, 0x29, 0x45, 0x28, 0xE1, 0x84, 0x91, 0x29,
+ 0x45, 0x28, 0xE1, 0x84, 0x92, 0x29, 0x45, 0x28,
+ 0xE4, 0xB8, 0x80, 0x29, 0x45, 0x28, 0xE4, 0xB8,
+ 0x83, 0x29, 0x45, 0x28, 0xE4, 0xB8, 0x89, 0x29,
+ // Bytes 20c0 - 20ff
+ 0x45, 0x28, 0xE4, 0xB9, 0x9D, 0x29, 0x45, 0x28,
+ 0xE4, 0xBA, 0x8C, 0x29, 0x45, 0x28, 0xE4, 0xBA,
+ 0x94, 0x29, 0x45, 0x28, 0xE4, 0xBB, 0xA3, 0x29,
+ 0x45, 0x28, 0xE4, 0xBC, 0x81, 0x29, 0x45, 0x28,
+ 0xE4, 0xBC, 0x91, 0x29, 0x45, 0x28, 0xE5, 0x85,
+ 0xAB, 0x29, 0x45, 0x28, 0xE5, 0x85, 0xAD, 0x29,
+ 0x45, 0x28, 0xE5, 0x8A, 0xB4, 0x29, 0x45, 0x28,
+ 0xE5, 0x8D, 0x81, 0x29, 0x45, 0x28, 0xE5, 0x8D,
+ // Bytes 2100 - 213f
+ 0x94, 0x29, 0x45, 0x28, 0xE5, 0x90, 0x8D, 0x29,
+ 0x45, 0x28, 0xE5, 0x91, 0xBC, 0x29, 0x45, 0x28,
+ 0xE5, 0x9B, 0x9B, 0x29, 0x45, 0x28, 0xE5, 0x9C,
+ 0x9F, 0x29, 0x45, 0x28, 0xE5, 0xAD, 0xA6, 0x29,
+ 0x45, 0x28, 0xE6, 0x97, 0xA5, 0x29, 0x45, 0x28,
+ 0xE6, 0x9C, 0x88, 0x29, 0x45, 0x28, 0xE6, 0x9C,
+ 0x89, 0x29, 0x45, 0x28, 0xE6, 0x9C, 0xA8, 0x29,
+ 0x45, 0x28, 0xE6, 0xA0, 0xAA, 0x29, 0x45, 0x28,
+ // Bytes 2140 - 217f
+ 0xE6, 0xB0, 0xB4, 0x29, 0x45, 0x28, 0xE7, 0x81,
+ 0xAB, 0x29, 0x45, 0x28, 0xE7, 0x89, 0xB9, 0x29,
+ 0x45, 0x28, 0xE7, 0x9B, 0xA3, 0x29, 0x45, 0x28,
+ 0xE7, 0xA4, 0xBE, 0x29, 0x45, 0x28, 0xE7, 0xA5,
+ 0x9D, 0x29, 0x45, 0x28, 0xE7, 0xA5, 0xAD, 0x29,
+ 0x45, 0x28, 0xE8, 0x87, 0xAA, 0x29, 0x45, 0x28,
+ 0xE8, 0x87, 0xB3, 0x29, 0x45, 0x28, 0xE8, 0xB2,
+ 0xA1, 0x29, 0x45, 0x28, 0xE8, 0xB3, 0x87, 0x29,
+ // Bytes 2180 - 21bf
+ 0x45, 0x28, 0xE9, 0x87, 0x91, 0x29, 0x45, 0x30,
+ 0xE2, 0x81, 0x84, 0x33, 0x45, 0x31, 0x30, 0xE6,
+ 0x97, 0xA5, 0x45, 0x31, 0x30, 0xE6, 0x9C, 0x88,
+ 0x45, 0x31, 0x30, 0xE7, 0x82, 0xB9, 0x45, 0x31,
+ 0x31, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x31, 0xE6,
+ 0x9C, 0x88, 0x45, 0x31, 0x31, 0xE7, 0x82, 0xB9,
+ 0x45, 0x31, 0x32, 0xE6, 0x97, 0xA5, 0x45, 0x31,
+ 0x32, 0xE6, 0x9C, 0x88, 0x45, 0x31, 0x32, 0xE7,
+ // Bytes 21c0 - 21ff
+ 0x82, 0xB9, 0x45, 0x31, 0x33, 0xE6, 0x97, 0xA5,
+ 0x45, 0x31, 0x33, 0xE7, 0x82, 0xB9, 0x45, 0x31,
+ 0x34, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x34, 0xE7,
+ 0x82, 0xB9, 0x45, 0x31, 0x35, 0xE6, 0x97, 0xA5,
+ 0x45, 0x31, 0x35, 0xE7, 0x82, 0xB9, 0x45, 0x31,
+ 0x36, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x36, 0xE7,
+ 0x82, 0xB9, 0x45, 0x31, 0x37, 0xE6, 0x97, 0xA5,
+ 0x45, 0x31, 0x37, 0xE7, 0x82, 0xB9, 0x45, 0x31,
+ // Bytes 2200 - 223f
+ 0x38, 0xE6, 0x97, 0xA5, 0x45, 0x31, 0x38, 0xE7,
+ 0x82, 0xB9, 0x45, 0x31, 0x39, 0xE6, 0x97, 0xA5,
+ 0x45, 0x31, 0x39, 0xE7, 0x82, 0xB9, 0x45, 0x31,
+ 0xE2, 0x81, 0x84, 0x32, 0x45, 0x31, 0xE2, 0x81,
+ 0x84, 0x33, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x34,
+ 0x45, 0x31, 0xE2, 0x81, 0x84, 0x35, 0x45, 0x31,
+ 0xE2, 0x81, 0x84, 0x36, 0x45, 0x31, 0xE2, 0x81,
+ 0x84, 0x37, 0x45, 0x31, 0xE2, 0x81, 0x84, 0x38,
+ // Bytes 2240 - 227f
+ 0x45, 0x31, 0xE2, 0x81, 0x84, 0x39, 0x45, 0x32,
+ 0x30, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x30, 0xE7,
+ 0x82, 0xB9, 0x45, 0x32, 0x31, 0xE6, 0x97, 0xA5,
+ 0x45, 0x32, 0x31, 0xE7, 0x82, 0xB9, 0x45, 0x32,
+ 0x32, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x32, 0xE7,
+ 0x82, 0xB9, 0x45, 0x32, 0x33, 0xE6, 0x97, 0xA5,
+ 0x45, 0x32, 0x33, 0xE7, 0x82, 0xB9, 0x45, 0x32,
+ 0x34, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x34, 0xE7,
+ // Bytes 2280 - 22bf
+ 0x82, 0xB9, 0x45, 0x32, 0x35, 0xE6, 0x97, 0xA5,
+ 0x45, 0x32, 0x36, 0xE6, 0x97, 0xA5, 0x45, 0x32,
+ 0x37, 0xE6, 0x97, 0xA5, 0x45, 0x32, 0x38, 0xE6,
+ 0x97, 0xA5, 0x45, 0x32, 0x39, 0xE6, 0x97, 0xA5,
+ 0x45, 0x32, 0xE2, 0x81, 0x84, 0x33, 0x45, 0x32,
+ 0xE2, 0x81, 0x84, 0x35, 0x45, 0x33, 0x30, 0xE6,
+ 0x97, 0xA5, 0x45, 0x33, 0x31, 0xE6, 0x97, 0xA5,
+ 0x45, 0x33, 0xE2, 0x81, 0x84, 0x34, 0x45, 0x33,
+ // Bytes 22c0 - 22ff
+ 0xE2, 0x81, 0x84, 0x35, 0x45, 0x33, 0xE2, 0x81,
+ 0x84, 0x38, 0x45, 0x34, 0xE2, 0x81, 0x84, 0x35,
+ 0x45, 0x35, 0xE2, 0x81, 0x84, 0x36, 0x45, 0x35,
+ 0xE2, 0x81, 0x84, 0x38, 0x45, 0x37, 0xE2, 0x81,
+ 0x84, 0x38, 0x45, 0x41, 0xE2, 0x88, 0x95, 0x6D,
+ 0x45, 0x56, 0xE2, 0x88, 0x95, 0x6D, 0x45, 0x6D,
+ 0xE2, 0x88, 0x95, 0x73, 0x46, 0x31, 0xE2, 0x81,
+ 0x84, 0x31, 0x30, 0x46, 0x43, 0xE2, 0x88, 0x95,
+ // Bytes 2300 - 233f
+ 0x6B, 0x67, 0x46, 0x6D, 0xE2, 0x88, 0x95, 0x73,
+ 0x32, 0x46, 0xD8, 0xA8, 0xD8, 0xAD, 0xD9, 0x8A,
+ 0x46, 0xD8, 0xA8, 0xD8, 0xAE, 0xD9, 0x8A, 0x46,
+ 0xD8, 0xAA, 0xD8, 0xAC, 0xD9, 0x85, 0x46, 0xD8,
+ 0xAA, 0xD8, 0xAC, 0xD9, 0x89, 0x46, 0xD8, 0xAA,
+ 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, 0xAA, 0xD8,
+ 0xAD, 0xD8, 0xAC, 0x46, 0xD8, 0xAA, 0xD8, 0xAD,
+ 0xD9, 0x85, 0x46, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9,
+ // Bytes 2340 - 237f
+ 0x85, 0x46, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x89,
+ 0x46, 0xD8, 0xAA, 0xD8, 0xAE, 0xD9, 0x8A, 0x46,
+ 0xD8, 0xAA, 0xD9, 0x85, 0xD8, 0xAC, 0x46, 0xD8,
+ 0xAA, 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xAA,
+ 0xD9, 0x85, 0xD8, 0xAE, 0x46, 0xD8, 0xAA, 0xD9,
+ 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAA, 0xD9, 0x85,
+ 0xD9, 0x8A, 0x46, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9,
+ 0x89, 0x46, 0xD8, 0xAC, 0xD8, 0xAD, 0xD9, 0x8A,
+ // Bytes 2380 - 23bf
+ 0x46, 0xD8, 0xAC, 0xD9, 0x85, 0xD8, 0xAD, 0x46,
+ 0xD8, 0xAC, 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8,
+ 0xAC, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8, 0xAD,
+ 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD8, 0xAD, 0xD9,
+ 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xAD, 0xD9, 0x85,
+ 0xD9, 0x8A, 0x46, 0xD8, 0xB3, 0xD8, 0xAC, 0xD8,
+ 0xAD, 0x46, 0xD8, 0xB3, 0xD8, 0xAC, 0xD9, 0x89,
+ 0x46, 0xD8, 0xB3, 0xD8, 0xAD, 0xD8, 0xAC, 0x46,
+ // Bytes 23c0 - 23ff
+ 0xD8, 0xB3, 0xD8, 0xAE, 0xD9, 0x89, 0x46, 0xD8,
+ 0xB3, 0xD8, 0xAE, 0xD9, 0x8A, 0x46, 0xD8, 0xB3,
+ 0xD9, 0x85, 0xD8, 0xAC, 0x46, 0xD8, 0xB3, 0xD9,
+ 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xB3, 0xD9, 0x85,
+ 0xD9, 0x85, 0x46, 0xD8, 0xB4, 0xD8, 0xAC, 0xD9,
+ 0x8A, 0x46, 0xD8, 0xB4, 0xD8, 0xAD, 0xD9, 0x85,
+ 0x46, 0xD8, 0xB4, 0xD8, 0xAD, 0xD9, 0x8A, 0x46,
+ 0xD8, 0xB4, 0xD9, 0x85, 0xD8, 0xAE, 0x46, 0xD8,
+ // Bytes 2400 - 243f
+ 0xB4, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB5,
+ 0xD8, 0xAD, 0xD8, 0xAD, 0x46, 0xD8, 0xB5, 0xD8,
+ 0xAD, 0xD9, 0x8A, 0x46, 0xD8, 0xB5, 0xD9, 0x84,
+ 0xD9, 0x89, 0x46, 0xD8, 0xB5, 0xD9, 0x84, 0xDB,
+ 0x92, 0x46, 0xD8, 0xB5, 0xD9, 0x85, 0xD9, 0x85,
+ 0x46, 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x89, 0x46,
+ 0xD8, 0xB6, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD8,
+ 0xB6, 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD8, 0xB7,
+ // Bytes 2440 - 247f
+ 0xD9, 0x85, 0xD8, 0xAD, 0x46, 0xD8, 0xB7, 0xD9,
+ 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xB7, 0xD9, 0x85,
+ 0xD9, 0x8A, 0x46, 0xD8, 0xB9, 0xD8, 0xAC, 0xD9,
+ 0x85, 0x46, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x85,
+ 0x46, 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x89, 0x46,
+ 0xD8, 0xB9, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD8,
+ 0xBA, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD8, 0xBA,
+ 0xD9, 0x85, 0xD9, 0x89, 0x46, 0xD8, 0xBA, 0xD9,
+ // Bytes 2480 - 24bf
+ 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x81, 0xD8, 0xAE,
+ 0xD9, 0x85, 0x46, 0xD9, 0x81, 0xD9, 0x85, 0xD9,
+ 0x8A, 0x46, 0xD9, 0x82, 0xD9, 0x84, 0xDB, 0x92,
+ 0x46, 0xD9, 0x82, 0xD9, 0x85, 0xD8, 0xAD, 0x46,
+ 0xD9, 0x82, 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9,
+ 0x82, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x83,
+ 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, 0x83, 0xD9,
+ 0x85, 0xD9, 0x8A, 0x46, 0xD9, 0x84, 0xD8, 0xAC,
+ // Bytes 24c0 - 24ff
+ 0xD8, 0xAC, 0x46, 0xD9, 0x84, 0xD8, 0xAC, 0xD9,
+ 0x85, 0x46, 0xD9, 0x84, 0xD8, 0xAC, 0xD9, 0x8A,
+ 0x46, 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x85, 0x46,
+ 0xD9, 0x84, 0xD8, 0xAD, 0xD9, 0x89, 0x46, 0xD9,
+ 0x84, 0xD8, 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x84,
+ 0xD8, 0xAE, 0xD9, 0x85, 0x46, 0xD9, 0x84, 0xD9,
+ 0x85, 0xD8, 0xAD, 0x46, 0xD9, 0x84, 0xD9, 0x85,
+ 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD8,
+ // Bytes 2500 - 253f
+ 0xAD, 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD8, 0xAE,
+ 0x46, 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x85, 0x46,
+ 0xD9, 0x85, 0xD8, 0xAC, 0xD9, 0x8A, 0x46, 0xD9,
+ 0x85, 0xD8, 0xAD, 0xD8, 0xAC, 0x46, 0xD9, 0x85,
+ 0xD8, 0xAD, 0xD9, 0x85, 0x46, 0xD9, 0x85, 0xD8,
+ 0xAD, 0xD9, 0x8A, 0x46, 0xD9, 0x85, 0xD8, 0xAE,
+ 0xD8, 0xAC, 0x46, 0xD9, 0x85, 0xD8, 0xAE, 0xD9,
+ 0x85, 0x46, 0xD9, 0x85, 0xD8, 0xAE, 0xD9, 0x8A,
+ // Bytes 2540 - 257f
+ 0x46, 0xD9, 0x85, 0xD9, 0x85, 0xD9, 0x8A, 0x46,
+ 0xD9, 0x86, 0xD8, 0xAC, 0xD8, 0xAD, 0x46, 0xD9,
+ 0x86, 0xD8, 0xAC, 0xD9, 0x85, 0x46, 0xD9, 0x86,
+ 0xD8, 0xAC, 0xD9, 0x89, 0x46, 0xD9, 0x86, 0xD8,
+ 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x86, 0xD8, 0xAD,
+ 0xD9, 0x85, 0x46, 0xD9, 0x86, 0xD8, 0xAD, 0xD9,
+ 0x89, 0x46, 0xD9, 0x86, 0xD8, 0xAD, 0xD9, 0x8A,
+ 0x46, 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x89, 0x46,
+ // Bytes 2580 - 25bf
+ 0xD9, 0x86, 0xD9, 0x85, 0xD9, 0x8A, 0x46, 0xD9,
+ 0x87, 0xD9, 0x85, 0xD8, 0xAC, 0x46, 0xD9, 0x87,
+ 0xD9, 0x85, 0xD9, 0x85, 0x46, 0xD9, 0x8A, 0xD8,
+ 0xAC, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD8, 0xAD,
+ 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD9, 0x85, 0xD9,
+ 0x85, 0x46, 0xD9, 0x8A, 0xD9, 0x85, 0xD9, 0x8A,
+ 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xA7, 0x46,
+ 0xD9, 0x8A, 0xD9, 0x94, 0xD8, 0xAC, 0x46, 0xD9,
+ // Bytes 25c0 - 25ff
+ 0x8A, 0xD9, 0x94, 0xD8, 0xAD, 0x46, 0xD9, 0x8A,
+ 0xD9, 0x94, 0xD8, 0xAE, 0x46, 0xD9, 0x8A, 0xD9,
+ 0x94, 0xD8, 0xB1, 0x46, 0xD9, 0x8A, 0xD9, 0x94,
+ 0xD8, 0xB2, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9,
+ 0x85, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x86,
+ 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x87, 0x46,
+ 0xD9, 0x8A, 0xD9, 0x94, 0xD9, 0x88, 0x46, 0xD9,
+ 0x8A, 0xD9, 0x94, 0xD9, 0x89, 0x46, 0xD9, 0x8A,
+ // Bytes 2600 - 263f
+ 0xD9, 0x94, 0xD9, 0x8A, 0x46, 0xD9, 0x8A, 0xD9,
+ 0x94, 0xDB, 0x86, 0x46, 0xD9, 0x8A, 0xD9, 0x94,
+ 0xDB, 0x87, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB,
+ 0x88, 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x90,
+ 0x46, 0xD9, 0x8A, 0xD9, 0x94, 0xDB, 0x95, 0x46,
+ 0xE0, 0xB9, 0x8D, 0xE0, 0xB8, 0xB2, 0x46, 0xE0,
+ 0xBA, 0xAB, 0xE0, 0xBA, 0x99, 0x46, 0xE0, 0xBA,
+ 0xAB, 0xE0, 0xBA, 0xA1, 0x46, 0xE0, 0xBB, 0x8D,
+ // Bytes 2640 - 267f
+ 0xE0, 0xBA, 0xB2, 0x46, 0xE0, 0xBD, 0x80, 0xE0,
+ 0xBE, 0xB5, 0x46, 0xE0, 0xBD, 0x82, 0xE0, 0xBE,
+ 0xB7, 0x46, 0xE0, 0xBD, 0x8C, 0xE0, 0xBE, 0xB7,
+ 0x46, 0xE0, 0xBD, 0x91, 0xE0, 0xBE, 0xB7, 0x46,
+ 0xE0, 0xBD, 0x96, 0xE0, 0xBE, 0xB7, 0x46, 0xE0,
+ 0xBD, 0x9B, 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE,
+ 0x90, 0xE0, 0xBE, 0xB5, 0x46, 0xE0, 0xBE, 0x92,
+ 0xE0, 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0x9C, 0xE0,
+ // Bytes 2680 - 26bf
+ 0xBE, 0xB7, 0x46, 0xE0, 0xBE, 0xA1, 0xE0, 0xBE,
+ 0xB7, 0x46, 0xE0, 0xBE, 0xA6, 0xE0, 0xBE, 0xB7,
+ 0x46, 0xE0, 0xBE, 0xAB, 0xE0, 0xBE, 0xB7, 0x46,
+ 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x46, 0xE2,
+ 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x46, 0xE2, 0x88,
+ 0xAB, 0xE2, 0x88, 0xAB, 0x46, 0xE2, 0x88, 0xAE,
+ 0xE2, 0x88, 0xAE, 0x46, 0xE3, 0x81, 0xBB, 0xE3,
+ 0x81, 0x8B, 0x46, 0xE3, 0x82, 0x88, 0xE3, 0x82,
+ // Bytes 26c0 - 26ff
+ 0x8A, 0x46, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD,
+ 0x46, 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0xB3, 0x46,
+ 0xE3, 0x82, 0xB3, 0xE3, 0x83, 0x88, 0x46, 0xE3,
+ 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x46, 0xE3, 0x83,
+ 0x8A, 0xE3, 0x83, 0x8E, 0x46, 0xE3, 0x83, 0x9B,
+ 0xE3, 0x83, 0xB3, 0x46, 0xE3, 0x83, 0x9F, 0xE3,
+ 0x83, 0xAA, 0x46, 0xE3, 0x83, 0xAA, 0xE3, 0x83,
+ 0xA9, 0x46, 0xE3, 0x83, 0xAC, 0xE3, 0x83, 0xA0,
+ // Bytes 2700 - 273f
+ 0x46, 0xE4, 0xBB, 0xA4, 0xE5, 0x92, 0x8C, 0x46,
+ 0xE5, 0xA4, 0xA7, 0xE6, 0xAD, 0xA3, 0x46, 0xE5,
+ 0xB9, 0xB3, 0xE6, 0x88, 0x90, 0x46, 0xE6, 0x98,
+ 0x8E, 0xE6, 0xB2, 0xBB, 0x46, 0xE6, 0x98, 0xAD,
+ 0xE5, 0x92, 0x8C, 0x47, 0x72, 0x61, 0x64, 0xE2,
+ 0x88, 0x95, 0x73, 0x47, 0xE3, 0x80, 0x94, 0x53,
+ 0xE3, 0x80, 0x95, 0x48, 0x28, 0xE1, 0x84, 0x80,
+ 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84,
+ // Bytes 2740 - 277f
+ 0x82, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1,
+ 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28,
+ 0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x29, 0x48,
+ 0x28, 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0x29,
+ 0x48, 0x28, 0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1,
+ 0x29, 0x48, 0x28, 0xE1, 0x84, 0x89, 0xE1, 0x85,
+ 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8B, 0xE1,
+ 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84, 0x8C,
+ // Bytes 2780 - 27bf
+ 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28, 0xE1, 0x84,
+ 0x8C, 0xE1, 0x85, 0xAE, 0x29, 0x48, 0x28, 0xE1,
+ 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x29, 0x48, 0x28,
+ 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x29, 0x48,
+ 0x28, 0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x29,
+ 0x48, 0x28, 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1,
+ 0x29, 0x48, 0x28, 0xE1, 0x84, 0x92, 0xE1, 0x85,
+ 0xA1, 0x29, 0x48, 0x72, 0x61, 0x64, 0xE2, 0x88,
+ // Bytes 27c0 - 27ff
+ 0x95, 0x73, 0x32, 0x48, 0xD8, 0xA7, 0xD9, 0x83,
+ 0xD8, 0xA8, 0xD8, 0xB1, 0x48, 0xD8, 0xA7, 0xD9,
+ 0x84, 0xD9, 0x84, 0xD9, 0x87, 0x48, 0xD8, 0xB1,
+ 0xD8, 0xB3, 0xD9, 0x88, 0xD9, 0x84, 0x48, 0xD8,
+ 0xB1, 0xDB, 0x8C, 0xD8, 0xA7, 0xD9, 0x84, 0x48,
+ 0xD8, 0xB5, 0xD9, 0x84, 0xD8, 0xB9, 0xD9, 0x85,
+ 0x48, 0xD8, 0xB9, 0xD9, 0x84, 0xD9, 0x8A, 0xD9,
+ 0x87, 0x48, 0xD9, 0x85, 0xD8, 0xAD, 0xD9, 0x85,
+ // Bytes 2800 - 283f
+ 0xD8, 0xAF, 0x48, 0xD9, 0x88, 0xD8, 0xB3, 0xD9,
+ 0x84, 0xD9, 0x85, 0x49, 0xE2, 0x80, 0xB2, 0xE2,
+ 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0x49, 0xE2, 0x80,
+ 0xB5, 0xE2, 0x80, 0xB5, 0xE2, 0x80, 0xB5, 0x49,
+ 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2, 0x88,
+ 0xAB, 0x49, 0xE2, 0x88, 0xAE, 0xE2, 0x88, 0xAE,
+ 0xE2, 0x88, 0xAE, 0x49, 0xE3, 0x80, 0x94, 0xE4,
+ 0xB8, 0x89, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80,
+ // Bytes 2840 - 287f
+ 0x94, 0xE4, 0xBA, 0x8C, 0xE3, 0x80, 0x95, 0x49,
+ 0xE3, 0x80, 0x94, 0xE5, 0x8B, 0x9D, 0xE3, 0x80,
+ 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE5, 0xAE, 0x89,
+ 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE6,
+ 0x89, 0x93, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80,
+ 0x94, 0xE6, 0x95, 0x97, 0xE3, 0x80, 0x95, 0x49,
+ 0xE3, 0x80, 0x94, 0xE6, 0x9C, 0xAC, 0xE3, 0x80,
+ 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE7, 0x82, 0xB9,
+ // Bytes 2880 - 28bf
+ 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x80, 0x94, 0xE7,
+ 0x9B, 0x97, 0xE3, 0x80, 0x95, 0x49, 0xE3, 0x82,
+ 0xA2, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49,
+ 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+ 0x81, 0x49, 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0xA9,
+ 0xE3, 0x83, 0xB3, 0x49, 0xE3, 0x82, 0xAA, 0xE3,
+ 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0x49, 0xE3, 0x82,
+ 0xAA, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xA0, 0x49,
+ // Bytes 28c0 - 28ff
+ 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0xA4, 0xE3, 0x83,
+ 0xAA, 0x49, 0xE3, 0x82, 0xB1, 0xE3, 0x83, 0xBC,
+ 0xE3, 0x82, 0xB9, 0x49, 0xE3, 0x82, 0xB3, 0xE3,
+ 0x83, 0xAB, 0xE3, 0x83, 0x8A, 0x49, 0xE3, 0x82,
+ 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x81, 0x49,
+ 0xE3, 0x82, 0xBB, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+ 0x88, 0x49, 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99,
+ 0xE3, 0x82, 0xB7, 0x49, 0xE3, 0x83, 0x88, 0xE3,
+ // Bytes 2900 - 293f
+ 0x82, 0x99, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83,
+ 0x8E, 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x49,
+ 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0xA4, 0xE3, 0x83,
+ 0x84, 0x49, 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99,
+ 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83, 0x92, 0xE3,
+ 0x82, 0x9A, 0xE3, 0x82, 0xB3, 0x49, 0xE3, 0x83,
+ 0x95, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0xB3, 0x49,
+ 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82,
+ // Bytes 2940 - 297f
+ 0xBD, 0x49, 0xE3, 0x83, 0x98, 0xE3, 0x83, 0xAB,
+ 0xE3, 0x83, 0x84, 0x49, 0xE3, 0x83, 0x9B, 0xE3,
+ 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49, 0xE3, 0x83,
+ 0x9B, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xB3, 0x49,
+ 0xE3, 0x83, 0x9E, 0xE3, 0x82, 0xA4, 0xE3, 0x83,
+ 0xAB, 0x49, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0x83,
+ 0xE3, 0x83, 0x8F, 0x49, 0xE3, 0x83, 0x9E, 0xE3,
+ 0x83, 0xAB, 0xE3, 0x82, 0xAF, 0x49, 0xE3, 0x83,
+ // Bytes 2980 - 29bf
+ 0xA4, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x49,
+ 0xE3, 0x83, 0xA6, 0xE3, 0x82, 0xA2, 0xE3, 0x83,
+ 0xB3, 0x49, 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83,
+ 0xE3, 0x83, 0x88, 0x4C, 0xE2, 0x80, 0xB2, 0xE2,
+ 0x80, 0xB2, 0xE2, 0x80, 0xB2, 0xE2, 0x80, 0xB2,
+ 0x4C, 0xE2, 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0xE2,
+ 0x88, 0xAB, 0xE2, 0x88, 0xAB, 0x4C, 0xE3, 0x82,
+ 0xA2, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x95, 0xE3,
+ // Bytes 29c0 - 29ff
+ 0x82, 0xA1, 0x4C, 0xE3, 0x82, 0xA8, 0xE3, 0x83,
+ 0xBC, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xBC, 0x4C,
+ 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+ 0xAD, 0xE3, 0x83, 0xB3, 0x4C, 0xE3, 0x82, 0xAB,
+ 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+ 0x9E, 0x4C, 0xE3, 0x82, 0xAB, 0xE3, 0x83, 0xA9,
+ 0xE3, 0x83, 0x83, 0xE3, 0x83, 0x88, 0x4C, 0xE3,
+ 0x82, 0xAB, 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xAA,
+ // Bytes 2a00 - 2a3f
+ 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82, 0xAD, 0xE3,
+ 0x82, 0x99, 0xE3, 0x83, 0x8B, 0xE3, 0x83, 0xBC,
+ 0x4C, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xA5, 0xE3,
+ 0x83, 0xAA, 0xE3, 0x83, 0xBC, 0x4C, 0xE3, 0x82,
+ 0xAF, 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3,
+ 0x83, 0xA0, 0x4C, 0xE3, 0x82, 0xAF, 0xE3, 0x83,
+ 0xAD, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x8D, 0x4C,
+ 0xE3, 0x82, 0xB5, 0xE3, 0x82, 0xA4, 0xE3, 0x82,
+ // Bytes 2a40 - 2a7f
+ 0xAF, 0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x82, 0xBF,
+ 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0xE3, 0x82,
+ 0xB9, 0x4C, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A,
+ 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x84, 0x4C, 0xE3,
+ 0x83, 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xAF,
+ 0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x83, 0x95, 0xE3,
+ 0x82, 0xA3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88,
+ 0x4C, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, 0xE3,
+ // Bytes 2a80 - 2abf
+ 0x83, 0xBC, 0xE3, 0x82, 0xBF, 0x4C, 0xE3, 0x83,
+ 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0x8B, 0xE3,
+ 0x83, 0x92, 0x4C, 0xE3, 0x83, 0x98, 0xE3, 0x82,
+ 0x9A, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xB9, 0x4C,
+ 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+ 0xAB, 0xE3, 0x83, 0x88, 0x4C, 0xE3, 0x83, 0x9E,
+ 0xE3, 0x82, 0xA4, 0xE3, 0x82, 0xAF, 0xE3, 0x83,
+ 0xAD, 0x4C, 0xE3, 0x83, 0x9F, 0xE3, 0x82, 0xAF,
+ // Bytes 2ac0 - 2aff
+ 0xE3, 0x83, 0xAD, 0xE3, 0x83, 0xB3, 0x4C, 0xE3,
+ 0x83, 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88,
+ 0xE3, 0x83, 0xAB, 0x4C, 0xE3, 0x83, 0xAA, 0xE3,
+ 0x83, 0x83, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB,
+ 0x4C, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0x92, 0xE3,
+ 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0x4C, 0xE6, 0xA0,
+ 0xAA, 0xE5, 0xBC, 0x8F, 0xE4, 0xBC, 0x9A, 0xE7,
+ 0xA4, 0xBE, 0x4E, 0x28, 0xE1, 0x84, 0x8B, 0xE1,
+ // Bytes 2b00 - 2b3f
+ 0x85, 0xA9, 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xAE,
+ 0x29, 0x4F, 0xD8, 0xAC, 0xD9, 0x84, 0x20, 0xD8,
+ 0xAC, 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x84, 0xD9,
+ 0x87, 0x4F, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0x8F,
+ 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+ 0x88, 0x4F, 0xE3, 0x82, 0xA2, 0xE3, 0x83, 0xB3,
+ 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x82,
+ 0xA2, 0x4F, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD,
+ // Bytes 2b40 - 2b7f
+ 0xE3, 0x83, 0xAF, 0xE3, 0x83, 0x83, 0xE3, 0x83,
+ 0x88, 0x4F, 0xE3, 0x82, 0xB5, 0xE3, 0x83, 0xB3,
+ 0xE3, 0x83, 0x81, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+ 0xA0, 0x4F, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99,
+ 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAC, 0xE3, 0x83,
+ 0xAB, 0x4F, 0xE3, 0x83, 0x98, 0xE3, 0x82, 0xAF,
+ 0xE3, 0x82, 0xBF, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+ 0xAB, 0x4F, 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A,
+ // Bytes 2b80 - 2bbf
+ 0xE3, 0x82, 0xA4, 0xE3, 0x83, 0xB3, 0xE3, 0x83,
+ 0x88, 0x4F, 0xE3, 0x83, 0x9E, 0xE3, 0x83, 0xB3,
+ 0xE3, 0x82, 0xB7, 0xE3, 0x83, 0xA7, 0xE3, 0x83,
+ 0xB3, 0x4F, 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB,
+ 0xE3, 0x82, 0x99, 0xE3, 0x83, 0x88, 0xE3, 0x83,
+ 0xB3, 0x4F, 0xE3, 0x83, 0xAB, 0xE3, 0x83, 0xBC,
+ 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+ 0xAB, 0x51, 0x28, 0xE1, 0x84, 0x8B, 0xE1, 0x85,
+ // Bytes 2bc0 - 2bff
+ 0xA9, 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA5, 0xE1,
+ 0x86, 0xAB, 0x29, 0x52, 0xE3, 0x82, 0xAD, 0xE3,
+ 0x82, 0x99, 0xE3, 0x83, 0xAB, 0xE3, 0x82, 0xBF,
+ 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xBC, 0x52, 0xE3,
+ 0x82, 0xAD, 0xE3, 0x83, 0xAD, 0xE3, 0x82, 0xAF,
+ 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3, 0x83,
+ 0xA0, 0x52, 0xE3, 0x82, 0xAD, 0xE3, 0x83, 0xAD,
+ 0xE3, 0x83, 0xA1, 0xE3, 0x83, 0xBC, 0xE3, 0x83,
+ // Bytes 2c00 - 2c3f
+ 0x88, 0xE3, 0x83, 0xAB, 0x52, 0xE3, 0x82, 0xAF,
+ 0xE3, 0x82, 0x99, 0xE3, 0x83, 0xA9, 0xE3, 0x83,
+ 0xA0, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xB3, 0x52,
+ 0xE3, 0x82, 0xAF, 0xE3, 0x83, 0xAB, 0xE3, 0x82,
+ 0xBB, 0xE3, 0x82, 0x99, 0xE3, 0x82, 0xA4, 0xE3,
+ 0x83, 0xAD, 0x52, 0xE3, 0x83, 0x8F, 0xE3, 0x82,
+ 0x9A, 0xE3, 0x83, 0xBC, 0xE3, 0x82, 0xBB, 0xE3,
+ 0x83, 0xB3, 0xE3, 0x83, 0x88, 0x52, 0xE3, 0x83,
+ // Bytes 2c40 - 2c7f
+ 0x92, 0xE3, 0x82, 0x9A, 0xE3, 0x82, 0xA2, 0xE3,
+ 0x82, 0xB9, 0xE3, 0x83, 0x88, 0xE3, 0x83, 0xAB,
+ 0x52, 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0xE3,
+ 0x83, 0x83, 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0xA7,
+ 0xE3, 0x83, 0xAB, 0x52, 0xE3, 0x83, 0x9F, 0xE3,
+ 0x83, 0xAA, 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99,
+ 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0xAB, 0x52, 0xE3,
+ 0x83, 0xAC, 0xE3, 0x83, 0xB3, 0xE3, 0x83, 0x88,
+ // Bytes 2c80 - 2cbf
+ 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0xE3, 0x83,
+ 0xB3, 0x61, 0xD8, 0xB5, 0xD9, 0x84, 0xD9, 0x89,
+ 0x20, 0xD8, 0xA7, 0xD9, 0x84, 0xD9, 0x84, 0xD9,
+ 0x87, 0x20, 0xD8, 0xB9, 0xD9, 0x84, 0xD9, 0x8A,
+ 0xD9, 0x87, 0x20, 0xD9, 0x88, 0xD8, 0xB3, 0xD9,
+ 0x84, 0xD9, 0x85, 0x06, 0xE0, 0xA7, 0x87, 0xE0,
+ 0xA6, 0xBE, 0x01, 0x06, 0xE0, 0xA7, 0x87, 0xE0,
+ 0xA7, 0x97, 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0,
+ // Bytes 2cc0 - 2cff
+ 0xAC, 0xBE, 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0,
+ 0xAD, 0x96, 0x01, 0x06, 0xE0, 0xAD, 0x87, 0xE0,
+ 0xAD, 0x97, 0x01, 0x06, 0xE0, 0xAE, 0x92, 0xE0,
+ 0xAF, 0x97, 0x01, 0x06, 0xE0, 0xAF, 0x86, 0xE0,
+ 0xAE, 0xBE, 0x01, 0x06, 0xE0, 0xAF, 0x86, 0xE0,
+ 0xAF, 0x97, 0x01, 0x06, 0xE0, 0xAF, 0x87, 0xE0,
+ 0xAE, 0xBE, 0x01, 0x06, 0xE0, 0xB2, 0xBF, 0xE0,
+ 0xB3, 0x95, 0x01, 0x06, 0xE0, 0xB3, 0x86, 0xE0,
+ // Bytes 2d00 - 2d3f
+ 0xB3, 0x95, 0x01, 0x06, 0xE0, 0xB3, 0x86, 0xE0,
+ 0xB3, 0x96, 0x01, 0x06, 0xE0, 0xB5, 0x86, 0xE0,
+ 0xB4, 0xBE, 0x01, 0x06, 0xE0, 0xB5, 0x86, 0xE0,
+ 0xB5, 0x97, 0x01, 0x06, 0xE0, 0xB5, 0x87, 0xE0,
+ 0xB4, 0xBE, 0x01, 0x06, 0xE0, 0xB7, 0x99, 0xE0,
+ 0xB7, 0x9F, 0x01, 0x06, 0xE1, 0x80, 0xA5, 0xE1,
+ 0x80, 0xAE, 0x01, 0x06, 0xE1, 0xAC, 0x85, 0xE1,
+ 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x87, 0xE1,
+ // Bytes 2d40 - 2d7f
+ 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x89, 0xE1,
+ 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x8B, 0xE1,
+ 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x8D, 0xE1,
+ 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0x91, 0xE1,
+ 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0xBA, 0xE1,
+ 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0xBC, 0xE1,
+ 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0xBE, 0xE1,
+ 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAC, 0xBF, 0xE1,
+ // Bytes 2d80 - 2dbf
+ 0xAC, 0xB5, 0x01, 0x06, 0xE1, 0xAD, 0x82, 0xE1,
+ 0xAC, 0xB5, 0x01, 0x08, 0xF0, 0x91, 0x84, 0xB1,
+ 0xF0, 0x91, 0x84, 0xA7, 0x01, 0x08, 0xF0, 0x91,
+ 0x84, 0xB2, 0xF0, 0x91, 0x84, 0xA7, 0x01, 0x08,
+ 0xF0, 0x91, 0x8D, 0x87, 0xF0, 0x91, 0x8C, 0xBE,
+ 0x01, 0x08, 0xF0, 0x91, 0x8D, 0x87, 0xF0, 0x91,
+ 0x8D, 0x97, 0x01, 0x08, 0xF0, 0x91, 0x92, 0xB9,
+ 0xF0, 0x91, 0x92, 0xB0, 0x01, 0x08, 0xF0, 0x91,
+ // Bytes 2dc0 - 2dff
+ 0x92, 0xB9, 0xF0, 0x91, 0x92, 0xBA, 0x01, 0x08,
+ 0xF0, 0x91, 0x92, 0xB9, 0xF0, 0x91, 0x92, 0xBD,
+ 0x01, 0x08, 0xF0, 0x91, 0x96, 0xB8, 0xF0, 0x91,
+ 0x96, 0xAF, 0x01, 0x08, 0xF0, 0x91, 0x96, 0xB9,
+ 0xF0, 0x91, 0x96, 0xAF, 0x01, 0x08, 0xF0, 0x91,
+ 0xA4, 0xB5, 0xF0, 0x91, 0xA4, 0xB0, 0x01, 0x09,
+ 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0xE0, 0xB3,
+ 0x95, 0x02, 0x09, 0xE0, 0xB7, 0x99, 0xE0, 0xB7,
+ // Bytes 2e00 - 2e3f
+ 0x8F, 0xE0, 0xB7, 0x8A, 0x16, 0x44, 0x44, 0x5A,
+ 0xCC, 0x8C, 0xCD, 0x44, 0x44, 0x7A, 0xCC, 0x8C,
+ 0xCD, 0x44, 0x64, 0x7A, 0xCC, 0x8C, 0xCD, 0x46,
+ 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x93, 0xCD, 0x46,
+ 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x94, 0xCD, 0x46,
+ 0xD9, 0x84, 0xD8, 0xA7, 0xD9, 0x95, 0xB9, 0x46,
+ 0xE1, 0x84, 0x80, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ 0xE1, 0x84, 0x82, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ // Bytes 2e40 - 2e7f
+ 0xE1, 0x84, 0x83, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ 0xE1, 0x84, 0x85, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ 0xE1, 0x84, 0x86, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ 0xE1, 0x84, 0x87, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ 0xE1, 0x84, 0x89, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xAE, 0x01, 0x46,
+ 0xE1, 0x84, 0x8C, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ // Bytes 2e80 - 2ebf
+ 0xE1, 0x84, 0x8E, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ 0xE1, 0x84, 0x8F, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ 0xE1, 0x84, 0x90, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ 0xE1, 0x84, 0x91, 0xE1, 0x85, 0xA1, 0x01, 0x46,
+ 0xE1, 0x84, 0x92, 0xE1, 0x85, 0xA1, 0x01, 0x49,
+ 0xE3, 0x83, 0xA1, 0xE3, 0x82, 0xAB, 0xE3, 0x82,
+ 0x99, 0x11, 0x4C, 0xE1, 0x84, 0x8C, 0xE1, 0x85,
+ 0xAE, 0xE1, 0x84, 0x8B, 0xE1, 0x85, 0xB4, 0x01,
+ // Bytes 2ec0 - 2eff
+ 0x4C, 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0xE3,
+ 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x11, 0x4C, 0xE3,
+ 0x82, 0xB3, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x9B,
+ 0xE3, 0x82, 0x9A, 0x11, 0x4C, 0xE3, 0x83, 0xA4,
+ 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3, 0x82,
+ 0x99, 0x11, 0x4F, 0xE1, 0x84, 0x8E, 0xE1, 0x85,
+ 0xA1, 0xE1, 0x86, 0xB7, 0xE1, 0x84, 0x80, 0xE1,
+ 0x85, 0xA9, 0x01, 0x4F, 0xE3, 0x82, 0xA4, 0xE3,
+ // Bytes 2f00 - 2f3f
+ 0x83, 0x8B, 0xE3, 0x83, 0xB3, 0xE3, 0x82, 0xAF,
+ 0xE3, 0x82, 0x99, 0x11, 0x4F, 0xE3, 0x82, 0xB7,
+ 0xE3, 0x83, 0xAA, 0xE3, 0x83, 0xB3, 0xE3, 0x82,
+ 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x4F, 0xE3, 0x83,
+ 0x98, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xBC, 0xE3,
+ 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x11, 0x4F, 0xE3,
+ 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0xE3, 0x83, 0xB3,
+ 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x11, 0x52,
+ // Bytes 2f40 - 2f7f
+ 0xE3, 0x82, 0xA8, 0xE3, 0x82, 0xB9, 0xE3, 0x82,
+ 0xAF, 0xE3, 0x83, 0xBC, 0xE3, 0x83, 0x88, 0xE3,
+ 0x82, 0x99, 0x11, 0x52, 0xE3, 0x83, 0x95, 0xE3,
+ 0x82, 0xA1, 0xE3, 0x83, 0xA9, 0xE3, 0x83, 0x83,
+ 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x11, 0x86,
+ 0xE0, 0xB3, 0x86, 0xE0, 0xB3, 0x82, 0x01, 0x86,
+ 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8F, 0x01, 0x03,
+ 0x3C, 0xCC, 0xB8, 0x05, 0x03, 0x3D, 0xCC, 0xB8,
+ // Bytes 2f80 - 2fbf
+ 0x05, 0x03, 0x3E, 0xCC, 0xB8, 0x05, 0x03, 0x41,
+ 0xCC, 0x80, 0xCD, 0x03, 0x41, 0xCC, 0x81, 0xCD,
+ 0x03, 0x41, 0xCC, 0x83, 0xCD, 0x03, 0x41, 0xCC,
+ 0x84, 0xCD, 0x03, 0x41, 0xCC, 0x89, 0xCD, 0x03,
+ 0x41, 0xCC, 0x8C, 0xCD, 0x03, 0x41, 0xCC, 0x8F,
+ 0xCD, 0x03, 0x41, 0xCC, 0x91, 0xCD, 0x03, 0x41,
+ 0xCC, 0xA5, 0xB9, 0x03, 0x41, 0xCC, 0xA8, 0xA9,
+ 0x03, 0x42, 0xCC, 0x87, 0xCD, 0x03, 0x42, 0xCC,
+ // Bytes 2fc0 - 2fff
+ 0xA3, 0xB9, 0x03, 0x42, 0xCC, 0xB1, 0xB9, 0x03,
+ 0x43, 0xCC, 0x81, 0xCD, 0x03, 0x43, 0xCC, 0x82,
+ 0xCD, 0x03, 0x43, 0xCC, 0x87, 0xCD, 0x03, 0x43,
+ 0xCC, 0x8C, 0xCD, 0x03, 0x44, 0xCC, 0x87, 0xCD,
+ 0x03, 0x44, 0xCC, 0x8C, 0xCD, 0x03, 0x44, 0xCC,
+ 0xA3, 0xB9, 0x03, 0x44, 0xCC, 0xA7, 0xA9, 0x03,
+ 0x44, 0xCC, 0xAD, 0xB9, 0x03, 0x44, 0xCC, 0xB1,
+ 0xB9, 0x03, 0x45, 0xCC, 0x80, 0xCD, 0x03, 0x45,
+ // Bytes 3000 - 303f
+ 0xCC, 0x81, 0xCD, 0x03, 0x45, 0xCC, 0x83, 0xCD,
+ 0x03, 0x45, 0xCC, 0x86, 0xCD, 0x03, 0x45, 0xCC,
+ 0x87, 0xCD, 0x03, 0x45, 0xCC, 0x88, 0xCD, 0x03,
+ 0x45, 0xCC, 0x89, 0xCD, 0x03, 0x45, 0xCC, 0x8C,
+ 0xCD, 0x03, 0x45, 0xCC, 0x8F, 0xCD, 0x03, 0x45,
+ 0xCC, 0x91, 0xCD, 0x03, 0x45, 0xCC, 0xA8, 0xA9,
+ 0x03, 0x45, 0xCC, 0xAD, 0xB9, 0x03, 0x45, 0xCC,
+ 0xB0, 0xB9, 0x03, 0x46, 0xCC, 0x87, 0xCD, 0x03,
+ // Bytes 3040 - 307f
+ 0x47, 0xCC, 0x81, 0xCD, 0x03, 0x47, 0xCC, 0x82,
+ 0xCD, 0x03, 0x47, 0xCC, 0x84, 0xCD, 0x03, 0x47,
+ 0xCC, 0x86, 0xCD, 0x03, 0x47, 0xCC, 0x87, 0xCD,
+ 0x03, 0x47, 0xCC, 0x8C, 0xCD, 0x03, 0x47, 0xCC,
+ 0xA7, 0xA9, 0x03, 0x48, 0xCC, 0x82, 0xCD, 0x03,
+ 0x48, 0xCC, 0x87, 0xCD, 0x03, 0x48, 0xCC, 0x88,
+ 0xCD, 0x03, 0x48, 0xCC, 0x8C, 0xCD, 0x03, 0x48,
+ 0xCC, 0xA3, 0xB9, 0x03, 0x48, 0xCC, 0xA7, 0xA9,
+ // Bytes 3080 - 30bf
+ 0x03, 0x48, 0xCC, 0xAE, 0xB9, 0x03, 0x49, 0xCC,
+ 0x80, 0xCD, 0x03, 0x49, 0xCC, 0x81, 0xCD, 0x03,
+ 0x49, 0xCC, 0x82, 0xCD, 0x03, 0x49, 0xCC, 0x83,
+ 0xCD, 0x03, 0x49, 0xCC, 0x84, 0xCD, 0x03, 0x49,
+ 0xCC, 0x86, 0xCD, 0x03, 0x49, 0xCC, 0x87, 0xCD,
+ 0x03, 0x49, 0xCC, 0x89, 0xCD, 0x03, 0x49, 0xCC,
+ 0x8C, 0xCD, 0x03, 0x49, 0xCC, 0x8F, 0xCD, 0x03,
+ 0x49, 0xCC, 0x91, 0xCD, 0x03, 0x49, 0xCC, 0xA3,
+ // Bytes 30c0 - 30ff
+ 0xB9, 0x03, 0x49, 0xCC, 0xA8, 0xA9, 0x03, 0x49,
+ 0xCC, 0xB0, 0xB9, 0x03, 0x4A, 0xCC, 0x82, 0xCD,
+ 0x03, 0x4B, 0xCC, 0x81, 0xCD, 0x03, 0x4B, 0xCC,
+ 0x8C, 0xCD, 0x03, 0x4B, 0xCC, 0xA3, 0xB9, 0x03,
+ 0x4B, 0xCC, 0xA7, 0xA9, 0x03, 0x4B, 0xCC, 0xB1,
+ 0xB9, 0x03, 0x4C, 0xCC, 0x81, 0xCD, 0x03, 0x4C,
+ 0xCC, 0x8C, 0xCD, 0x03, 0x4C, 0xCC, 0xA7, 0xA9,
+ 0x03, 0x4C, 0xCC, 0xAD, 0xB9, 0x03, 0x4C, 0xCC,
+ // Bytes 3100 - 313f
+ 0xB1, 0xB9, 0x03, 0x4D, 0xCC, 0x81, 0xCD, 0x03,
+ 0x4D, 0xCC, 0x87, 0xCD, 0x03, 0x4D, 0xCC, 0xA3,
+ 0xB9, 0x03, 0x4E, 0xCC, 0x80, 0xCD, 0x03, 0x4E,
+ 0xCC, 0x81, 0xCD, 0x03, 0x4E, 0xCC, 0x83, 0xCD,
+ 0x03, 0x4E, 0xCC, 0x87, 0xCD, 0x03, 0x4E, 0xCC,
+ 0x8C, 0xCD, 0x03, 0x4E, 0xCC, 0xA3, 0xB9, 0x03,
+ 0x4E, 0xCC, 0xA7, 0xA9, 0x03, 0x4E, 0xCC, 0xAD,
+ 0xB9, 0x03, 0x4E, 0xCC, 0xB1, 0xB9, 0x03, 0x4F,
+ // Bytes 3140 - 317f
+ 0xCC, 0x80, 0xCD, 0x03, 0x4F, 0xCC, 0x81, 0xCD,
+ 0x03, 0x4F, 0xCC, 0x86, 0xCD, 0x03, 0x4F, 0xCC,
+ 0x89, 0xCD, 0x03, 0x4F, 0xCC, 0x8B, 0xCD, 0x03,
+ 0x4F, 0xCC, 0x8C, 0xCD, 0x03, 0x4F, 0xCC, 0x8F,
+ 0xCD, 0x03, 0x4F, 0xCC, 0x91, 0xCD, 0x03, 0x50,
+ 0xCC, 0x81, 0xCD, 0x03, 0x50, 0xCC, 0x87, 0xCD,
+ 0x03, 0x52, 0xCC, 0x81, 0xCD, 0x03, 0x52, 0xCC,
+ 0x87, 0xCD, 0x03, 0x52, 0xCC, 0x8C, 0xCD, 0x03,
+ // Bytes 3180 - 31bf
+ 0x52, 0xCC, 0x8F, 0xCD, 0x03, 0x52, 0xCC, 0x91,
+ 0xCD, 0x03, 0x52, 0xCC, 0xA7, 0xA9, 0x03, 0x52,
+ 0xCC, 0xB1, 0xB9, 0x03, 0x53, 0xCC, 0x82, 0xCD,
+ 0x03, 0x53, 0xCC, 0x87, 0xCD, 0x03, 0x53, 0xCC,
+ 0xA6, 0xB9, 0x03, 0x53, 0xCC, 0xA7, 0xA9, 0x03,
+ 0x54, 0xCC, 0x87, 0xCD, 0x03, 0x54, 0xCC, 0x8C,
+ 0xCD, 0x03, 0x54, 0xCC, 0xA3, 0xB9, 0x03, 0x54,
+ 0xCC, 0xA6, 0xB9, 0x03, 0x54, 0xCC, 0xA7, 0xA9,
+ // Bytes 31c0 - 31ff
+ 0x03, 0x54, 0xCC, 0xAD, 0xB9, 0x03, 0x54, 0xCC,
+ 0xB1, 0xB9, 0x03, 0x55, 0xCC, 0x80, 0xCD, 0x03,
+ 0x55, 0xCC, 0x81, 0xCD, 0x03, 0x55, 0xCC, 0x82,
+ 0xCD, 0x03, 0x55, 0xCC, 0x86, 0xCD, 0x03, 0x55,
+ 0xCC, 0x89, 0xCD, 0x03, 0x55, 0xCC, 0x8A, 0xCD,
+ 0x03, 0x55, 0xCC, 0x8B, 0xCD, 0x03, 0x55, 0xCC,
+ 0x8C, 0xCD, 0x03, 0x55, 0xCC, 0x8F, 0xCD, 0x03,
+ 0x55, 0xCC, 0x91, 0xCD, 0x03, 0x55, 0xCC, 0xA3,
+ // Bytes 3200 - 323f
+ 0xB9, 0x03, 0x55, 0xCC, 0xA4, 0xB9, 0x03, 0x55,
+ 0xCC, 0xA8, 0xA9, 0x03, 0x55, 0xCC, 0xAD, 0xB9,
+ 0x03, 0x55, 0xCC, 0xB0, 0xB9, 0x03, 0x56, 0xCC,
+ 0x83, 0xCD, 0x03, 0x56, 0xCC, 0xA3, 0xB9, 0x03,
+ 0x57, 0xCC, 0x80, 0xCD, 0x03, 0x57, 0xCC, 0x81,
+ 0xCD, 0x03, 0x57, 0xCC, 0x82, 0xCD, 0x03, 0x57,
+ 0xCC, 0x87, 0xCD, 0x03, 0x57, 0xCC, 0x88, 0xCD,
+ 0x03, 0x57, 0xCC, 0xA3, 0xB9, 0x03, 0x58, 0xCC,
+ // Bytes 3240 - 327f
+ 0x87, 0xCD, 0x03, 0x58, 0xCC, 0x88, 0xCD, 0x03,
+ 0x59, 0xCC, 0x80, 0xCD, 0x03, 0x59, 0xCC, 0x81,
+ 0xCD, 0x03, 0x59, 0xCC, 0x82, 0xCD, 0x03, 0x59,
+ 0xCC, 0x83, 0xCD, 0x03, 0x59, 0xCC, 0x84, 0xCD,
+ 0x03, 0x59, 0xCC, 0x87, 0xCD, 0x03, 0x59, 0xCC,
+ 0x88, 0xCD, 0x03, 0x59, 0xCC, 0x89, 0xCD, 0x03,
+ 0x59, 0xCC, 0xA3, 0xB9, 0x03, 0x5A, 0xCC, 0x81,
+ 0xCD, 0x03, 0x5A, 0xCC, 0x82, 0xCD, 0x03, 0x5A,
+ // Bytes 3280 - 32bf
+ 0xCC, 0x87, 0xCD, 0x03, 0x5A, 0xCC, 0x8C, 0xCD,
+ 0x03, 0x5A, 0xCC, 0xA3, 0xB9, 0x03, 0x5A, 0xCC,
+ 0xB1, 0xB9, 0x03, 0x61, 0xCC, 0x80, 0xCD, 0x03,
+ 0x61, 0xCC, 0x81, 0xCD, 0x03, 0x61, 0xCC, 0x83,
+ 0xCD, 0x03, 0x61, 0xCC, 0x84, 0xCD, 0x03, 0x61,
+ 0xCC, 0x89, 0xCD, 0x03, 0x61, 0xCC, 0x8C, 0xCD,
+ 0x03, 0x61, 0xCC, 0x8F, 0xCD, 0x03, 0x61, 0xCC,
+ 0x91, 0xCD, 0x03, 0x61, 0xCC, 0xA5, 0xB9, 0x03,
+ // Bytes 32c0 - 32ff
+ 0x61, 0xCC, 0xA8, 0xA9, 0x03, 0x62, 0xCC, 0x87,
+ 0xCD, 0x03, 0x62, 0xCC, 0xA3, 0xB9, 0x03, 0x62,
+ 0xCC, 0xB1, 0xB9, 0x03, 0x63, 0xCC, 0x81, 0xCD,
+ 0x03, 0x63, 0xCC, 0x82, 0xCD, 0x03, 0x63, 0xCC,
+ 0x87, 0xCD, 0x03, 0x63, 0xCC, 0x8C, 0xCD, 0x03,
+ 0x64, 0xCC, 0x87, 0xCD, 0x03, 0x64, 0xCC, 0x8C,
+ 0xCD, 0x03, 0x64, 0xCC, 0xA3, 0xB9, 0x03, 0x64,
+ 0xCC, 0xA7, 0xA9, 0x03, 0x64, 0xCC, 0xAD, 0xB9,
+ // Bytes 3300 - 333f
+ 0x03, 0x64, 0xCC, 0xB1, 0xB9, 0x03, 0x65, 0xCC,
+ 0x80, 0xCD, 0x03, 0x65, 0xCC, 0x81, 0xCD, 0x03,
+ 0x65, 0xCC, 0x83, 0xCD, 0x03, 0x65, 0xCC, 0x86,
+ 0xCD, 0x03, 0x65, 0xCC, 0x87, 0xCD, 0x03, 0x65,
+ 0xCC, 0x88, 0xCD, 0x03, 0x65, 0xCC, 0x89, 0xCD,
+ 0x03, 0x65, 0xCC, 0x8C, 0xCD, 0x03, 0x65, 0xCC,
+ 0x8F, 0xCD, 0x03, 0x65, 0xCC, 0x91, 0xCD, 0x03,
+ 0x65, 0xCC, 0xA8, 0xA9, 0x03, 0x65, 0xCC, 0xAD,
+ // Bytes 3340 - 337f
+ 0xB9, 0x03, 0x65, 0xCC, 0xB0, 0xB9, 0x03, 0x66,
+ 0xCC, 0x87, 0xCD, 0x03, 0x67, 0xCC, 0x81, 0xCD,
+ 0x03, 0x67, 0xCC, 0x82, 0xCD, 0x03, 0x67, 0xCC,
+ 0x84, 0xCD, 0x03, 0x67, 0xCC, 0x86, 0xCD, 0x03,
+ 0x67, 0xCC, 0x87, 0xCD, 0x03, 0x67, 0xCC, 0x8C,
+ 0xCD, 0x03, 0x67, 0xCC, 0xA7, 0xA9, 0x03, 0x68,
+ 0xCC, 0x82, 0xCD, 0x03, 0x68, 0xCC, 0x87, 0xCD,
+ 0x03, 0x68, 0xCC, 0x88, 0xCD, 0x03, 0x68, 0xCC,
+ // Bytes 3380 - 33bf
+ 0x8C, 0xCD, 0x03, 0x68, 0xCC, 0xA3, 0xB9, 0x03,
+ 0x68, 0xCC, 0xA7, 0xA9, 0x03, 0x68, 0xCC, 0xAE,
+ 0xB9, 0x03, 0x68, 0xCC, 0xB1, 0xB9, 0x03, 0x69,
+ 0xCC, 0x80, 0xCD, 0x03, 0x69, 0xCC, 0x81, 0xCD,
+ 0x03, 0x69, 0xCC, 0x82, 0xCD, 0x03, 0x69, 0xCC,
+ 0x83, 0xCD, 0x03, 0x69, 0xCC, 0x84, 0xCD, 0x03,
+ 0x69, 0xCC, 0x86, 0xCD, 0x03, 0x69, 0xCC, 0x89,
+ 0xCD, 0x03, 0x69, 0xCC, 0x8C, 0xCD, 0x03, 0x69,
+ // Bytes 33c0 - 33ff
+ 0xCC, 0x8F, 0xCD, 0x03, 0x69, 0xCC, 0x91, 0xCD,
+ 0x03, 0x69, 0xCC, 0xA3, 0xB9, 0x03, 0x69, 0xCC,
+ 0xA8, 0xA9, 0x03, 0x69, 0xCC, 0xB0, 0xB9, 0x03,
+ 0x6A, 0xCC, 0x82, 0xCD, 0x03, 0x6A, 0xCC, 0x8C,
+ 0xCD, 0x03, 0x6B, 0xCC, 0x81, 0xCD, 0x03, 0x6B,
+ 0xCC, 0x8C, 0xCD, 0x03, 0x6B, 0xCC, 0xA3, 0xB9,
+ 0x03, 0x6B, 0xCC, 0xA7, 0xA9, 0x03, 0x6B, 0xCC,
+ 0xB1, 0xB9, 0x03, 0x6C, 0xCC, 0x81, 0xCD, 0x03,
+ // Bytes 3400 - 343f
+ 0x6C, 0xCC, 0x8C, 0xCD, 0x03, 0x6C, 0xCC, 0xA7,
+ 0xA9, 0x03, 0x6C, 0xCC, 0xAD, 0xB9, 0x03, 0x6C,
+ 0xCC, 0xB1, 0xB9, 0x03, 0x6D, 0xCC, 0x81, 0xCD,
+ 0x03, 0x6D, 0xCC, 0x87, 0xCD, 0x03, 0x6D, 0xCC,
+ 0xA3, 0xB9, 0x03, 0x6E, 0xCC, 0x80, 0xCD, 0x03,
+ 0x6E, 0xCC, 0x81, 0xCD, 0x03, 0x6E, 0xCC, 0x83,
+ 0xCD, 0x03, 0x6E, 0xCC, 0x87, 0xCD, 0x03, 0x6E,
+ 0xCC, 0x8C, 0xCD, 0x03, 0x6E, 0xCC, 0xA3, 0xB9,
+ // Bytes 3440 - 347f
+ 0x03, 0x6E, 0xCC, 0xA7, 0xA9, 0x03, 0x6E, 0xCC,
+ 0xAD, 0xB9, 0x03, 0x6E, 0xCC, 0xB1, 0xB9, 0x03,
+ 0x6F, 0xCC, 0x80, 0xCD, 0x03, 0x6F, 0xCC, 0x81,
+ 0xCD, 0x03, 0x6F, 0xCC, 0x86, 0xCD, 0x03, 0x6F,
+ 0xCC, 0x89, 0xCD, 0x03, 0x6F, 0xCC, 0x8B, 0xCD,
+ 0x03, 0x6F, 0xCC, 0x8C, 0xCD, 0x03, 0x6F, 0xCC,
+ 0x8F, 0xCD, 0x03, 0x6F, 0xCC, 0x91, 0xCD, 0x03,
+ 0x70, 0xCC, 0x81, 0xCD, 0x03, 0x70, 0xCC, 0x87,
+ // Bytes 3480 - 34bf
+ 0xCD, 0x03, 0x72, 0xCC, 0x81, 0xCD, 0x03, 0x72,
+ 0xCC, 0x87, 0xCD, 0x03, 0x72, 0xCC, 0x8C, 0xCD,
+ 0x03, 0x72, 0xCC, 0x8F, 0xCD, 0x03, 0x72, 0xCC,
+ 0x91, 0xCD, 0x03, 0x72, 0xCC, 0xA7, 0xA9, 0x03,
+ 0x72, 0xCC, 0xB1, 0xB9, 0x03, 0x73, 0xCC, 0x82,
+ 0xCD, 0x03, 0x73, 0xCC, 0x87, 0xCD, 0x03, 0x73,
+ 0xCC, 0xA6, 0xB9, 0x03, 0x73, 0xCC, 0xA7, 0xA9,
+ 0x03, 0x74, 0xCC, 0x87, 0xCD, 0x03, 0x74, 0xCC,
+ // Bytes 34c0 - 34ff
+ 0x88, 0xCD, 0x03, 0x74, 0xCC, 0x8C, 0xCD, 0x03,
+ 0x74, 0xCC, 0xA3, 0xB9, 0x03, 0x74, 0xCC, 0xA6,
+ 0xB9, 0x03, 0x74, 0xCC, 0xA7, 0xA9, 0x03, 0x74,
+ 0xCC, 0xAD, 0xB9, 0x03, 0x74, 0xCC, 0xB1, 0xB9,
+ 0x03, 0x75, 0xCC, 0x80, 0xCD, 0x03, 0x75, 0xCC,
+ 0x81, 0xCD, 0x03, 0x75, 0xCC, 0x82, 0xCD, 0x03,
+ 0x75, 0xCC, 0x86, 0xCD, 0x03, 0x75, 0xCC, 0x89,
+ 0xCD, 0x03, 0x75, 0xCC, 0x8A, 0xCD, 0x03, 0x75,
+ // Bytes 3500 - 353f
+ 0xCC, 0x8B, 0xCD, 0x03, 0x75, 0xCC, 0x8C, 0xCD,
+ 0x03, 0x75, 0xCC, 0x8F, 0xCD, 0x03, 0x75, 0xCC,
+ 0x91, 0xCD, 0x03, 0x75, 0xCC, 0xA3, 0xB9, 0x03,
+ 0x75, 0xCC, 0xA4, 0xB9, 0x03, 0x75, 0xCC, 0xA8,
+ 0xA9, 0x03, 0x75, 0xCC, 0xAD, 0xB9, 0x03, 0x75,
+ 0xCC, 0xB0, 0xB9, 0x03, 0x76, 0xCC, 0x83, 0xCD,
+ 0x03, 0x76, 0xCC, 0xA3, 0xB9, 0x03, 0x77, 0xCC,
+ 0x80, 0xCD, 0x03, 0x77, 0xCC, 0x81, 0xCD, 0x03,
+ // Bytes 3540 - 357f
+ 0x77, 0xCC, 0x82, 0xCD, 0x03, 0x77, 0xCC, 0x87,
+ 0xCD, 0x03, 0x77, 0xCC, 0x88, 0xCD, 0x03, 0x77,
+ 0xCC, 0x8A, 0xCD, 0x03, 0x77, 0xCC, 0xA3, 0xB9,
+ 0x03, 0x78, 0xCC, 0x87, 0xCD, 0x03, 0x78, 0xCC,
+ 0x88, 0xCD, 0x03, 0x79, 0xCC, 0x80, 0xCD, 0x03,
+ 0x79, 0xCC, 0x81, 0xCD, 0x03, 0x79, 0xCC, 0x82,
+ 0xCD, 0x03, 0x79, 0xCC, 0x83, 0xCD, 0x03, 0x79,
+ 0xCC, 0x84, 0xCD, 0x03, 0x79, 0xCC, 0x87, 0xCD,
+ // Bytes 3580 - 35bf
+ 0x03, 0x79, 0xCC, 0x88, 0xCD, 0x03, 0x79, 0xCC,
+ 0x89, 0xCD, 0x03, 0x79, 0xCC, 0x8A, 0xCD, 0x03,
+ 0x79, 0xCC, 0xA3, 0xB9, 0x03, 0x7A, 0xCC, 0x81,
+ 0xCD, 0x03, 0x7A, 0xCC, 0x82, 0xCD, 0x03, 0x7A,
+ 0xCC, 0x87, 0xCD, 0x03, 0x7A, 0xCC, 0x8C, 0xCD,
+ 0x03, 0x7A, 0xCC, 0xA3, 0xB9, 0x03, 0x7A, 0xCC,
+ 0xB1, 0xB9, 0x04, 0xC2, 0xA8, 0xCC, 0x80, 0xCE,
+ 0x04, 0xC2, 0xA8, 0xCC, 0x81, 0xCE, 0x04, 0xC2,
+ // Bytes 35c0 - 35ff
+ 0xA8, 0xCD, 0x82, 0xCE, 0x04, 0xC3, 0x86, 0xCC,
+ 0x81, 0xCD, 0x04, 0xC3, 0x86, 0xCC, 0x84, 0xCD,
+ 0x04, 0xC3, 0x98, 0xCC, 0x81, 0xCD, 0x04, 0xC3,
+ 0xA6, 0xCC, 0x81, 0xCD, 0x04, 0xC3, 0xA6, 0xCC,
+ 0x84, 0xCD, 0x04, 0xC3, 0xB8, 0xCC, 0x81, 0xCD,
+ 0x04, 0xC5, 0xBF, 0xCC, 0x87, 0xCD, 0x04, 0xC6,
+ 0xB7, 0xCC, 0x8C, 0xCD, 0x04, 0xCA, 0x92, 0xCC,
+ 0x8C, 0xCD, 0x04, 0xCE, 0x91, 0xCC, 0x80, 0xCD,
+ // Bytes 3600 - 363f
+ 0x04, 0xCE, 0x91, 0xCC, 0x81, 0xCD, 0x04, 0xCE,
+ 0x91, 0xCC, 0x84, 0xCD, 0x04, 0xCE, 0x91, 0xCC,
+ 0x86, 0xCD, 0x04, 0xCE, 0x91, 0xCD, 0x85, 0xDD,
+ 0x04, 0xCE, 0x95, 0xCC, 0x80, 0xCD, 0x04, 0xCE,
+ 0x95, 0xCC, 0x81, 0xCD, 0x04, 0xCE, 0x97, 0xCC,
+ 0x80, 0xCD, 0x04, 0xCE, 0x97, 0xCC, 0x81, 0xCD,
+ 0x04, 0xCE, 0x97, 0xCD, 0x85, 0xDD, 0x04, 0xCE,
+ 0x99, 0xCC, 0x80, 0xCD, 0x04, 0xCE, 0x99, 0xCC,
+ // Bytes 3640 - 367f
+ 0x81, 0xCD, 0x04, 0xCE, 0x99, 0xCC, 0x84, 0xCD,
+ 0x04, 0xCE, 0x99, 0xCC, 0x86, 0xCD, 0x04, 0xCE,
+ 0x99, 0xCC, 0x88, 0xCD, 0x04, 0xCE, 0x9F, 0xCC,
+ 0x80, 0xCD, 0x04, 0xCE, 0x9F, 0xCC, 0x81, 0xCD,
+ 0x04, 0xCE, 0xA1, 0xCC, 0x94, 0xCD, 0x04, 0xCE,
+ 0xA5, 0xCC, 0x80, 0xCD, 0x04, 0xCE, 0xA5, 0xCC,
+ 0x81, 0xCD, 0x04, 0xCE, 0xA5, 0xCC, 0x84, 0xCD,
+ 0x04, 0xCE, 0xA5, 0xCC, 0x86, 0xCD, 0x04, 0xCE,
+ // Bytes 3680 - 36bf
+ 0xA5, 0xCC, 0x88, 0xCD, 0x04, 0xCE, 0xA9, 0xCC,
+ 0x80, 0xCD, 0x04, 0xCE, 0xA9, 0xCC, 0x81, 0xCD,
+ 0x04, 0xCE, 0xA9, 0xCD, 0x85, 0xDD, 0x04, 0xCE,
+ 0xB1, 0xCC, 0x84, 0xCD, 0x04, 0xCE, 0xB1, 0xCC,
+ 0x86, 0xCD, 0x04, 0xCE, 0xB1, 0xCD, 0x85, 0xDD,
+ 0x04, 0xCE, 0xB5, 0xCC, 0x80, 0xCD, 0x04, 0xCE,
+ 0xB5, 0xCC, 0x81, 0xCD, 0x04, 0xCE, 0xB7, 0xCD,
+ 0x85, 0xDD, 0x04, 0xCE, 0xB9, 0xCC, 0x80, 0xCD,
+ // Bytes 36c0 - 36ff
+ 0x04, 0xCE, 0xB9, 0xCC, 0x81, 0xCD, 0x04, 0xCE,
+ 0xB9, 0xCC, 0x84, 0xCD, 0x04, 0xCE, 0xB9, 0xCC,
+ 0x86, 0xCD, 0x04, 0xCE, 0xB9, 0xCD, 0x82, 0xCD,
+ 0x04, 0xCE, 0xBF, 0xCC, 0x80, 0xCD, 0x04, 0xCE,
+ 0xBF, 0xCC, 0x81, 0xCD, 0x04, 0xCF, 0x81, 0xCC,
+ 0x93, 0xCD, 0x04, 0xCF, 0x81, 0xCC, 0x94, 0xCD,
+ 0x04, 0xCF, 0x85, 0xCC, 0x80, 0xCD, 0x04, 0xCF,
+ 0x85, 0xCC, 0x81, 0xCD, 0x04, 0xCF, 0x85, 0xCC,
+ // Bytes 3700 - 373f
+ 0x84, 0xCD, 0x04, 0xCF, 0x85, 0xCC, 0x86, 0xCD,
+ 0x04, 0xCF, 0x85, 0xCD, 0x82, 0xCD, 0x04, 0xCF,
+ 0x89, 0xCD, 0x85, 0xDD, 0x04, 0xCF, 0x92, 0xCC,
+ 0x81, 0xCD, 0x04, 0xCF, 0x92, 0xCC, 0x88, 0xCD,
+ 0x04, 0xD0, 0x86, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
+ 0x90, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0x90, 0xCC,
+ 0x88, 0xCD, 0x04, 0xD0, 0x93, 0xCC, 0x81, 0xCD,
+ 0x04, 0xD0, 0x95, 0xCC, 0x80, 0xCD, 0x04, 0xD0,
+ // Bytes 3740 - 377f
+ 0x95, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0x95, 0xCC,
+ 0x88, 0xCD, 0x04, 0xD0, 0x96, 0xCC, 0x86, 0xCD,
+ 0x04, 0xD0, 0x96, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
+ 0x97, 0xCC, 0x88, 0xCD, 0x04, 0xD0, 0x98, 0xCC,
+ 0x80, 0xCD, 0x04, 0xD0, 0x98, 0xCC, 0x84, 0xCD,
+ 0x04, 0xD0, 0x98, 0xCC, 0x86, 0xCD, 0x04, 0xD0,
+ 0x98, 0xCC, 0x88, 0xCD, 0x04, 0xD0, 0x9A, 0xCC,
+ 0x81, 0xCD, 0x04, 0xD0, 0x9E, 0xCC, 0x88, 0xCD,
+ // Bytes 3780 - 37bf
+ 0x04, 0xD0, 0xA3, 0xCC, 0x84, 0xCD, 0x04, 0xD0,
+ 0xA3, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0xA3, 0xCC,
+ 0x88, 0xCD, 0x04, 0xD0, 0xA3, 0xCC, 0x8B, 0xCD,
+ 0x04, 0xD0, 0xA7, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
+ 0xAB, 0xCC, 0x88, 0xCD, 0x04, 0xD0, 0xAD, 0xCC,
+ 0x88, 0xCD, 0x04, 0xD0, 0xB0, 0xCC, 0x86, 0xCD,
+ 0x04, 0xD0, 0xB0, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
+ 0xB3, 0xCC, 0x81, 0xCD, 0x04, 0xD0, 0xB5, 0xCC,
+ // Bytes 37c0 - 37ff
+ 0x80, 0xCD, 0x04, 0xD0, 0xB5, 0xCC, 0x86, 0xCD,
+ 0x04, 0xD0, 0xB5, 0xCC, 0x88, 0xCD, 0x04, 0xD0,
+ 0xB6, 0xCC, 0x86, 0xCD, 0x04, 0xD0, 0xB6, 0xCC,
+ 0x88, 0xCD, 0x04, 0xD0, 0xB7, 0xCC, 0x88, 0xCD,
+ 0x04, 0xD0, 0xB8, 0xCC, 0x80, 0xCD, 0x04, 0xD0,
+ 0xB8, 0xCC, 0x84, 0xCD, 0x04, 0xD0, 0xB8, 0xCC,
+ 0x86, 0xCD, 0x04, 0xD0, 0xB8, 0xCC, 0x88, 0xCD,
+ 0x04, 0xD0, 0xBA, 0xCC, 0x81, 0xCD, 0x04, 0xD0,
+ // Bytes 3800 - 383f
+ 0xBE, 0xCC, 0x88, 0xCD, 0x04, 0xD1, 0x83, 0xCC,
+ 0x84, 0xCD, 0x04, 0xD1, 0x83, 0xCC, 0x86, 0xCD,
+ 0x04, 0xD1, 0x83, 0xCC, 0x88, 0xCD, 0x04, 0xD1,
+ 0x83, 0xCC, 0x8B, 0xCD, 0x04, 0xD1, 0x87, 0xCC,
+ 0x88, 0xCD, 0x04, 0xD1, 0x8B, 0xCC, 0x88, 0xCD,
+ 0x04, 0xD1, 0x8D, 0xCC, 0x88, 0xCD, 0x04, 0xD1,
+ 0x96, 0xCC, 0x88, 0xCD, 0x04, 0xD1, 0xB4, 0xCC,
+ 0x8F, 0xCD, 0x04, 0xD1, 0xB5, 0xCC, 0x8F, 0xCD,
+ // Bytes 3840 - 387f
+ 0x04, 0xD3, 0x98, 0xCC, 0x88, 0xCD, 0x04, 0xD3,
+ 0x99, 0xCC, 0x88, 0xCD, 0x04, 0xD3, 0xA8, 0xCC,
+ 0x88, 0xCD, 0x04, 0xD3, 0xA9, 0xCC, 0x88, 0xCD,
+ 0x04, 0xD8, 0xA7, 0xD9, 0x93, 0xCD, 0x04, 0xD8,
+ 0xA7, 0xD9, 0x94, 0xCD, 0x04, 0xD8, 0xA7, 0xD9,
+ 0x95, 0xB9, 0x04, 0xD9, 0x88, 0xD9, 0x94, 0xCD,
+ 0x04, 0xD9, 0x8A, 0xD9, 0x94, 0xCD, 0x04, 0xDB,
+ 0x81, 0xD9, 0x94, 0xCD, 0x04, 0xDB, 0x92, 0xD9,
+ // Bytes 3880 - 38bf
+ 0x94, 0xCD, 0x04, 0xDB, 0x95, 0xD9, 0x94, 0xCD,
+ 0x05, 0x41, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05,
+ 0x41, 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x41,
+ 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x41, 0xCC,
+ 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x41, 0xCC, 0x86,
+ 0xCC, 0x80, 0xCE, 0x05, 0x41, 0xCC, 0x86, 0xCC,
+ 0x81, 0xCE, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x83,
+ 0xCE, 0x05, 0x41, 0xCC, 0x86, 0xCC, 0x89, 0xCE,
+ // Bytes 38c0 - 38ff
+ 0x05, 0x41, 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05,
+ 0x41, 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x41,
+ 0xCC, 0x8A, 0xCC, 0x81, 0xCE, 0x05, 0x41, 0xCC,
+ 0xA3, 0xCC, 0x82, 0xCE, 0x05, 0x41, 0xCC, 0xA3,
+ 0xCC, 0x86, 0xCE, 0x05, 0x43, 0xCC, 0xA7, 0xCC,
+ 0x81, 0xCE, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x80,
+ 0xCE, 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x81, 0xCE,
+ 0x05, 0x45, 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05,
+ // Bytes 3900 - 393f
+ 0x45, 0xCC, 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x45,
+ 0xCC, 0x84, 0xCC, 0x80, 0xCE, 0x05, 0x45, 0xCC,
+ 0x84, 0xCC, 0x81, 0xCE, 0x05, 0x45, 0xCC, 0xA3,
+ 0xCC, 0x82, 0xCE, 0x05, 0x45, 0xCC, 0xA7, 0xCC,
+ 0x86, 0xCE, 0x05, 0x49, 0xCC, 0x88, 0xCC, 0x81,
+ 0xCE, 0x05, 0x4C, 0xCC, 0xA3, 0xCC, 0x84, 0xCE,
+ 0x05, 0x4F, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05,
+ 0x4F, 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x4F,
+ // Bytes 3940 - 397f
+ 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x4F, 0xCC,
+ 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x4F, 0xCC, 0x83,
+ 0xCC, 0x81, 0xCE, 0x05, 0x4F, 0xCC, 0x83, 0xCC,
+ 0x84, 0xCE, 0x05, 0x4F, 0xCC, 0x83, 0xCC, 0x88,
+ 0xCE, 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x80, 0xCE,
+ 0x05, 0x4F, 0xCC, 0x84, 0xCC, 0x81, 0xCE, 0x05,
+ 0x4F, 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, 0x4F,
+ 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x4F, 0xCC,
+ // Bytes 3980 - 39bf
+ 0x9B, 0xCC, 0x80, 0xCE, 0x05, 0x4F, 0xCC, 0x9B,
+ 0xCC, 0x81, 0xCE, 0x05, 0x4F, 0xCC, 0x9B, 0xCC,
+ 0x83, 0xCE, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0x89,
+ 0xCE, 0x05, 0x4F, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA,
+ 0x05, 0x4F, 0xCC, 0xA3, 0xCC, 0x82, 0xCE, 0x05,
+ 0x4F, 0xCC, 0xA8, 0xCC, 0x84, 0xCE, 0x05, 0x52,
+ 0xCC, 0xA3, 0xCC, 0x84, 0xCE, 0x05, 0x53, 0xCC,
+ 0x81, 0xCC, 0x87, 0xCE, 0x05, 0x53, 0xCC, 0x8C,
+ // Bytes 39c0 - 39ff
+ 0xCC, 0x87, 0xCE, 0x05, 0x53, 0xCC, 0xA3, 0xCC,
+ 0x87, 0xCE, 0x05, 0x55, 0xCC, 0x83, 0xCC, 0x81,
+ 0xCE, 0x05, 0x55, 0xCC, 0x84, 0xCC, 0x88, 0xCE,
+ 0x05, 0x55, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x05,
+ 0x55, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x05, 0x55,
+ 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x55, 0xCC,
+ 0x88, 0xCC, 0x8C, 0xCE, 0x05, 0x55, 0xCC, 0x9B,
+ 0xCC, 0x80, 0xCE, 0x05, 0x55, 0xCC, 0x9B, 0xCC,
+ // Bytes 3a00 - 3a3f
+ 0x81, 0xCE, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x83,
+ 0xCE, 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0x89, 0xCE,
+ 0x05, 0x55, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, 0x05,
+ 0x61, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05, 0x61,
+ 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x61, 0xCC,
+ 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x61, 0xCC, 0x82,
+ 0xCC, 0x89, 0xCE, 0x05, 0x61, 0xCC, 0x86, 0xCC,
+ 0x80, 0xCE, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x81,
+ // Bytes 3a40 - 3a7f
+ 0xCE, 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x83, 0xCE,
+ 0x05, 0x61, 0xCC, 0x86, 0xCC, 0x89, 0xCE, 0x05,
+ 0x61, 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, 0x61,
+ 0xCC, 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x61, 0xCC,
+ 0x8A, 0xCC, 0x81, 0xCE, 0x05, 0x61, 0xCC, 0xA3,
+ 0xCC, 0x82, 0xCE, 0x05, 0x61, 0xCC, 0xA3, 0xCC,
+ 0x86, 0xCE, 0x05, 0x63, 0xCC, 0xA7, 0xCC, 0x81,
+ 0xCE, 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x80, 0xCE,
+ // Bytes 3a80 - 3abf
+ 0x05, 0x65, 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05,
+ 0x65, 0xCC, 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x65,
+ 0xCC, 0x82, 0xCC, 0x89, 0xCE, 0x05, 0x65, 0xCC,
+ 0x84, 0xCC, 0x80, 0xCE, 0x05, 0x65, 0xCC, 0x84,
+ 0xCC, 0x81, 0xCE, 0x05, 0x65, 0xCC, 0xA3, 0xCC,
+ 0x82, 0xCE, 0x05, 0x65, 0xCC, 0xA7, 0xCC, 0x86,
+ 0xCE, 0x05, 0x69, 0xCC, 0x88, 0xCC, 0x81, 0xCE,
+ 0x05, 0x6C, 0xCC, 0xA3, 0xCC, 0x84, 0xCE, 0x05,
+ // Bytes 3ac0 - 3aff
+ 0x6F, 0xCC, 0x82, 0xCC, 0x80, 0xCE, 0x05, 0x6F,
+ 0xCC, 0x82, 0xCC, 0x81, 0xCE, 0x05, 0x6F, 0xCC,
+ 0x82, 0xCC, 0x83, 0xCE, 0x05, 0x6F, 0xCC, 0x82,
+ 0xCC, 0x89, 0xCE, 0x05, 0x6F, 0xCC, 0x83, 0xCC,
+ 0x81, 0xCE, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x84,
+ 0xCE, 0x05, 0x6F, 0xCC, 0x83, 0xCC, 0x88, 0xCE,
+ 0x05, 0x6F, 0xCC, 0x84, 0xCC, 0x80, 0xCE, 0x05,
+ 0x6F, 0xCC, 0x84, 0xCC, 0x81, 0xCE, 0x05, 0x6F,
+ // Bytes 3b00 - 3b3f
+ 0xCC, 0x87, 0xCC, 0x84, 0xCE, 0x05, 0x6F, 0xCC,
+ 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x6F, 0xCC, 0x9B,
+ 0xCC, 0x80, 0xCE, 0x05, 0x6F, 0xCC, 0x9B, 0xCC,
+ 0x81, 0xCE, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x83,
+ 0xCE, 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0x89, 0xCE,
+ 0x05, 0x6F, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, 0x05,
+ 0x6F, 0xCC, 0xA3, 0xCC, 0x82, 0xCE, 0x05, 0x6F,
+ 0xCC, 0xA8, 0xCC, 0x84, 0xCE, 0x05, 0x72, 0xCC,
+ // Bytes 3b40 - 3b7f
+ 0xA3, 0xCC, 0x84, 0xCE, 0x05, 0x73, 0xCC, 0x81,
+ 0xCC, 0x87, 0xCE, 0x05, 0x73, 0xCC, 0x8C, 0xCC,
+ 0x87, 0xCE, 0x05, 0x73, 0xCC, 0xA3, 0xCC, 0x87,
+ 0xCE, 0x05, 0x75, 0xCC, 0x83, 0xCC, 0x81, 0xCE,
+ 0x05, 0x75, 0xCC, 0x84, 0xCC, 0x88, 0xCE, 0x05,
+ 0x75, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x05, 0x75,
+ 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x05, 0x75, 0xCC,
+ 0x88, 0xCC, 0x84, 0xCE, 0x05, 0x75, 0xCC, 0x88,
+ // Bytes 3b80 - 3bbf
+ 0xCC, 0x8C, 0xCE, 0x05, 0x75, 0xCC, 0x9B, 0xCC,
+ 0x80, 0xCE, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x81,
+ 0xCE, 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x83, 0xCE,
+ 0x05, 0x75, 0xCC, 0x9B, 0xCC, 0x89, 0xCE, 0x05,
+ 0x75, 0xCC, 0x9B, 0xCC, 0xA3, 0xBA, 0x05, 0xE1,
+ 0xBE, 0xBF, 0xCC, 0x80, 0xCE, 0x05, 0xE1, 0xBE,
+ 0xBF, 0xCC, 0x81, 0xCE, 0x05, 0xE1, 0xBE, 0xBF,
+ 0xCD, 0x82, 0xCE, 0x05, 0xE1, 0xBF, 0xBE, 0xCC,
+ // Bytes 3bc0 - 3bff
+ 0x80, 0xCE, 0x05, 0xE1, 0xBF, 0xBE, 0xCC, 0x81,
+ 0xCE, 0x05, 0xE1, 0xBF, 0xBE, 0xCD, 0x82, 0xCE,
+ 0x05, 0xE2, 0x86, 0x90, 0xCC, 0xB8, 0x05, 0x05,
+ 0xE2, 0x86, 0x92, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
+ 0x86, 0x94, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87,
+ 0x90, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87, 0x92,
+ 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x87, 0x94, 0xCC,
+ 0xB8, 0x05, 0x05, 0xE2, 0x88, 0x83, 0xCC, 0xB8,
+ // Bytes 3c00 - 3c3f
+ 0x05, 0x05, 0xE2, 0x88, 0x88, 0xCC, 0xB8, 0x05,
+ 0x05, 0xE2, 0x88, 0x8B, 0xCC, 0xB8, 0x05, 0x05,
+ 0xE2, 0x88, 0xA3, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
+ 0x88, 0xA5, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x88,
+ 0xBC, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x83,
+ 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x85, 0xCC,
+ 0xB8, 0x05, 0x05, 0xE2, 0x89, 0x88, 0xCC, 0xB8,
+ 0x05, 0x05, 0xE2, 0x89, 0x8D, 0xCC, 0xB8, 0x05,
+ // Bytes 3c40 - 3c7f
+ 0x05, 0xE2, 0x89, 0xA1, 0xCC, 0xB8, 0x05, 0x05,
+ 0xE2, 0x89, 0xA4, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
+ 0x89, 0xA5, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89,
+ 0xB2, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB3,
+ 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB6, 0xCC,
+ 0xB8, 0x05, 0x05, 0xE2, 0x89, 0xB7, 0xCC, 0xB8,
+ 0x05, 0x05, 0xE2, 0x89, 0xBA, 0xCC, 0xB8, 0x05,
+ 0x05, 0xE2, 0x89, 0xBB, 0xCC, 0xB8, 0x05, 0x05,
+ // Bytes 3c80 - 3cbf
+ 0xE2, 0x89, 0xBC, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
+ 0x89, 0xBD, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A,
+ 0x82, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x83,
+ 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x86, 0xCC,
+ 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0x87, 0xCC, 0xB8,
+ 0x05, 0x05, 0xE2, 0x8A, 0x91, 0xCC, 0xB8, 0x05,
+ 0x05, 0xE2, 0x8A, 0x92, 0xCC, 0xB8, 0x05, 0x05,
+ 0xE2, 0x8A, 0xA2, 0xCC, 0xB8, 0x05, 0x05, 0xE2,
+ // Bytes 3cc0 - 3cff
+ 0x8A, 0xA8, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A,
+ 0xA9, 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xAB,
+ 0xCC, 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB2, 0xCC,
+ 0xB8, 0x05, 0x05, 0xE2, 0x8A, 0xB3, 0xCC, 0xB8,
+ 0x05, 0x05, 0xE2, 0x8A, 0xB4, 0xCC, 0xB8, 0x05,
+ 0x05, 0xE2, 0x8A, 0xB5, 0xCC, 0xB8, 0x05, 0x06,
+ 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
+ // Bytes 3d00 - 3d3f
+ 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0x95, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+ 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0x95, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+ 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0x99, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+ // Bytes 3d40 - 3d7f
+ 0xCE, 0x99, 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x06,
+ 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0x99, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+ 0xCE, 0x99, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06,
+ 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0x9F, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+ 0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0x9F, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+ // Bytes 3d80 - 3dbf
+ 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0xA5, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+ 0xCE, 0xA5, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06,
+ 0xCE, 0xA9, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0xB1, 0xCC, 0x81, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
+ // Bytes 3dc0 - 3dff
+ 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0xB5, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+ 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0xB5, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+ 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x85, 0xDE, 0x06,
+ // Bytes 3e00 - 3e3f
+ 0xCE, 0xB7, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0xB9, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x06,
+ 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x82, 0xCE, 0x06,
+ 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0xB9, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+ // Bytes 3e40 - 3e7f
+ 0xCE, 0xB9, 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x06,
+ 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0xB9, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+ 0xCE, 0xB9, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06,
+ 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0xBF, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+ 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCE, 0xBF, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+ // Bytes 3e80 - 3ebf
+ 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCF, 0x85, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x06,
+ 0xCF, 0x85, 0xCC, 0x88, 0xCD, 0x82, 0xCE, 0x06,
+ 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCF, 0x85, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x06,
+ 0xCF, 0x85, 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x06,
+ 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x06,
+ 0xCF, 0x85, 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x06,
+ // Bytes 3ec0 - 3eff
+ 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x06,
+ 0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x85, 0xDE, 0x06,
+ 0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x85, 0xDE, 0x06,
+ 0xE0, 0xA4, 0xA8, 0xE0, 0xA4, 0xBC, 0x0D, 0x06,
+ 0xE0, 0xA4, 0xB0, 0xE0, 0xA4, 0xBC, 0x0D, 0x06,
+ // Bytes 3f00 - 3f3f
+ 0xE0, 0xA4, 0xB3, 0xE0, 0xA4, 0xBC, 0x0D, 0x06,
+ 0xE0, 0xB1, 0x86, 0xE0, 0xB1, 0x96, 0x89, 0x06,
+ 0xE0, 0xB7, 0x99, 0xE0, 0xB7, 0x8A, 0x15, 0x06,
+ 0xE3, 0x81, 0x86, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0x8B, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0x8D, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0x8F, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0x91, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ // Bytes 3f40 - 3f7f
+ 0xE3, 0x81, 0x93, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0x95, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0x97, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0x99, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0x9B, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0x9D, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0x9F, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ // Bytes 3f80 - 3fbf
+ 0xE3, 0x81, 0xA4, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0xA6, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0xA8, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0xAF, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+ 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0xB2, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+ 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ // Bytes 3fc0 - 3fff
+ 0xE3, 0x81, 0xB5, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+ 0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0xB8, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+ 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x81, 0xBB, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+ 0xE3, 0x82, 0x9D, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x82, 0xA6, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x82, 0xAB, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ // Bytes 4000 - 403f
+ 0xE3, 0x82, 0xAD, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x82, 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x82, 0xB1, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x82, 0xB3, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x82, 0xB5, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x82, 0xB7, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x82, 0xB9, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x82, 0xBB, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ // Bytes 4040 - 407f
+ 0xE3, 0x82, 0xBD, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x82, 0xBF, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0x81, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0x84, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0x86, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0x88, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0x8F, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+ // Bytes 4080 - 40bf
+ 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0x92, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+ 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0x95, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+ 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0x98, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+ 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0x9B, 0xE3, 0x82, 0x9A, 0x11, 0x06,
+ // Bytes 40c0 - 40ff
+ 0xE3, 0x83, 0xAF, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0xB0, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0xB1, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0xB2, 0xE3, 0x82, 0x99, 0x11, 0x06,
+ 0xE3, 0x83, 0xBD, 0xE3, 0x82, 0x99, 0x11, 0x08,
+ 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85,
+ 0xDF, 0x08, 0xCE, 0x91, 0xCC, 0x93, 0xCC, 0x81,
+ 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x91, 0xCC, 0x93,
+ // Bytes 4100 - 413f
+ 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x91,
+ 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08,
+ 0xCE, 0x91, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85,
+ 0xDF, 0x08, 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x82,
+ 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97, 0xCC, 0x93,
+ 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97,
+ 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08,
+ 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85,
+ // Bytes 4140 - 417f
+ 0xDF, 0x08, 0xCE, 0x97, 0xCC, 0x94, 0xCC, 0x80,
+ 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97, 0xCC, 0x94,
+ 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0x97,
+ 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08,
+ 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85,
+ 0xDF, 0x08, 0xCE, 0xA9, 0xCC, 0x93, 0xCC, 0x81,
+ 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xA9, 0xCC, 0x93,
+ 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xA9,
+ // Bytes 4180 - 41bf
+ 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08,
+ 0xCE, 0xA9, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85,
+ 0xDF, 0x08, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x82,
+ 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1, 0xCC, 0x93,
+ 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1,
+ 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08,
+ 0xCE, 0xB1, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85,
+ 0xDF, 0x08, 0xCE, 0xB1, 0xCC, 0x94, 0xCC, 0x80,
+ // Bytes 41c0 - 41ff
+ 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1, 0xCC, 0x94,
+ 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB1,
+ 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08,
+ 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x80, 0xCD, 0x85,
+ 0xDF, 0x08, 0xCE, 0xB7, 0xCC, 0x93, 0xCC, 0x81,
+ 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB7, 0xCC, 0x93,
+ 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08, 0xCE, 0xB7,
+ 0xCC, 0x94, 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08,
+ // Bytes 4200 - 423f
+ 0xCE, 0xB7, 0xCC, 0x94, 0xCC, 0x81, 0xCD, 0x85,
+ 0xDF, 0x08, 0xCE, 0xB7, 0xCC, 0x94, 0xCD, 0x82,
+ 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89, 0xCC, 0x93,
+ 0xCC, 0x80, 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89,
+ 0xCC, 0x93, 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08,
+ 0xCF, 0x89, 0xCC, 0x93, 0xCD, 0x82, 0xCD, 0x85,
+ 0xDF, 0x08, 0xCF, 0x89, 0xCC, 0x94, 0xCC, 0x80,
+ 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89, 0xCC, 0x94,
+ // Bytes 4240 - 427f
+ 0xCC, 0x81, 0xCD, 0x85, 0xDF, 0x08, 0xCF, 0x89,
+ 0xCC, 0x94, 0xCD, 0x82, 0xCD, 0x85, 0xDF, 0x08,
+ 0xF0, 0x91, 0x82, 0x99, 0xF0, 0x91, 0x82, 0xBA,
+ 0x0D, 0x08, 0xF0, 0x91, 0x82, 0x9B, 0xF0, 0x91,
+ 0x82, 0xBA, 0x0D, 0x08, 0xF0, 0x91, 0x82, 0xA5,
+ 0xF0, 0x91, 0x82, 0xBA, 0x0D, 0x42, 0xC2, 0xB4,
+ 0x01, 0x43, 0x20, 0xCC, 0x81, 0xCD, 0x43, 0x20,
+ 0xCC, 0x83, 0xCD, 0x43, 0x20, 0xCC, 0x84, 0xCD,
+ // Bytes 4280 - 42bf
+ 0x43, 0x20, 0xCC, 0x85, 0xCD, 0x43, 0x20, 0xCC,
+ 0x86, 0xCD, 0x43, 0x20, 0xCC, 0x87, 0xCD, 0x43,
+ 0x20, 0xCC, 0x88, 0xCD, 0x43, 0x20, 0xCC, 0x8A,
+ 0xCD, 0x43, 0x20, 0xCC, 0x8B, 0xCD, 0x43, 0x20,
+ 0xCC, 0x93, 0xCD, 0x43, 0x20, 0xCC, 0x94, 0xCD,
+ 0x43, 0x20, 0xCC, 0xA7, 0xA9, 0x43, 0x20, 0xCC,
+ 0xA8, 0xA9, 0x43, 0x20, 0xCC, 0xB3, 0xB9, 0x43,
+ 0x20, 0xCD, 0x82, 0xCD, 0x43, 0x20, 0xCD, 0x85,
+ // Bytes 42c0 - 42ff
+ 0xDD, 0x43, 0x20, 0xD9, 0x8B, 0x5D, 0x43, 0x20,
+ 0xD9, 0x8C, 0x61, 0x43, 0x20, 0xD9, 0x8D, 0x65,
+ 0x43, 0x20, 0xD9, 0x8E, 0x69, 0x43, 0x20, 0xD9,
+ 0x8F, 0x6D, 0x43, 0x20, 0xD9, 0x90, 0x71, 0x43,
+ 0x20, 0xD9, 0x91, 0x75, 0x43, 0x20, 0xD9, 0x92,
+ 0x79, 0x43, 0x41, 0xCC, 0x8A, 0xCD, 0x43, 0x73,
+ 0xCC, 0x87, 0xCD, 0x44, 0x20, 0xE3, 0x82, 0x99,
+ 0x11, 0x44, 0x20, 0xE3, 0x82, 0x9A, 0x11, 0x44,
+ // Bytes 4300 - 433f
+ 0xC2, 0xA8, 0xCC, 0x81, 0xCE, 0x44, 0xCE, 0x91,
+ 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0x95, 0xCC, 0x81,
+ 0xCD, 0x44, 0xCE, 0x97, 0xCC, 0x81, 0xCD, 0x44,
+ 0xCE, 0x99, 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0x9F,
+ 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xA5, 0xCC, 0x81,
+ 0xCD, 0x44, 0xCE, 0xA5, 0xCC, 0x88, 0xCD, 0x44,
+ 0xCE, 0xA9, 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xB1,
+ 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xB5, 0xCC, 0x81,
+ // Bytes 4340 - 437f
+ 0xCD, 0x44, 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x44,
+ 0xCE, 0xB9, 0xCC, 0x81, 0xCD, 0x44, 0xCE, 0xBF,
+ 0xCC, 0x81, 0xCD, 0x44, 0xCF, 0x85, 0xCC, 0x81,
+ 0xCD, 0x44, 0xCF, 0x89, 0xCC, 0x81, 0xCD, 0x44,
+ 0xD7, 0x90, 0xD6, 0xB7, 0x35, 0x44, 0xD7, 0x90,
+ 0xD6, 0xB8, 0x39, 0x44, 0xD7, 0x90, 0xD6, 0xBC,
+ 0x45, 0x44, 0xD7, 0x91, 0xD6, 0xBC, 0x45, 0x44,
+ 0xD7, 0x91, 0xD6, 0xBF, 0x4D, 0x44, 0xD7, 0x92,
+ // Bytes 4380 - 43bf
+ 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x93, 0xD6, 0xBC,
+ 0x45, 0x44, 0xD7, 0x94, 0xD6, 0xBC, 0x45, 0x44,
+ 0xD7, 0x95, 0xD6, 0xB9, 0x3D, 0x44, 0xD7, 0x95,
+ 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x96, 0xD6, 0xBC,
+ 0x45, 0x44, 0xD7, 0x98, 0xD6, 0xBC, 0x45, 0x44,
+ 0xD7, 0x99, 0xD6, 0xB4, 0x29, 0x44, 0xD7, 0x99,
+ 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x9A, 0xD6, 0xBC,
+ 0x45, 0x44, 0xD7, 0x9B, 0xD6, 0xBC, 0x45, 0x44,
+ // Bytes 43c0 - 43ff
+ 0xD7, 0x9B, 0xD6, 0xBF, 0x4D, 0x44, 0xD7, 0x9C,
+ 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0x9E, 0xD6, 0xBC,
+ 0x45, 0x44, 0xD7, 0xA0, 0xD6, 0xBC, 0x45, 0x44,
+ 0xD7, 0xA1, 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA3,
+ 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA4, 0xD6, 0xBC,
+ 0x45, 0x44, 0xD7, 0xA4, 0xD6, 0xBF, 0x4D, 0x44,
+ 0xD7, 0xA6, 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA7,
+ 0xD6, 0xBC, 0x45, 0x44, 0xD7, 0xA8, 0xD6, 0xBC,
+ // Bytes 4400 - 443f
+ 0x45, 0x44, 0xD7, 0xA9, 0xD6, 0xBC, 0x45, 0x44,
+ 0xD7, 0xA9, 0xD7, 0x81, 0x51, 0x44, 0xD7, 0xA9,
+ 0xD7, 0x82, 0x55, 0x44, 0xD7, 0xAA, 0xD6, 0xBC,
+ 0x45, 0x44, 0xD7, 0xB2, 0xD6, 0xB7, 0x35, 0x44,
+ 0xD8, 0xA7, 0xD9, 0x8B, 0x5D, 0x44, 0xD8, 0xA7,
+ 0xD9, 0x93, 0xCD, 0x44, 0xD8, 0xA7, 0xD9, 0x94,
+ 0xCD, 0x44, 0xD8, 0xA7, 0xD9, 0x95, 0xB9, 0x44,
+ 0xD8, 0xB0, 0xD9, 0xB0, 0x7D, 0x44, 0xD8, 0xB1,
+ // Bytes 4440 - 447f
+ 0xD9, 0xB0, 0x7D, 0x44, 0xD9, 0x80, 0xD9, 0x8B,
+ 0x5D, 0x44, 0xD9, 0x80, 0xD9, 0x8E, 0x69, 0x44,
+ 0xD9, 0x80, 0xD9, 0x8F, 0x6D, 0x44, 0xD9, 0x80,
+ 0xD9, 0x90, 0x71, 0x44, 0xD9, 0x80, 0xD9, 0x91,
+ 0x75, 0x44, 0xD9, 0x80, 0xD9, 0x92, 0x79, 0x44,
+ 0xD9, 0x87, 0xD9, 0xB0, 0x7D, 0x44, 0xD9, 0x88,
+ 0xD9, 0x94, 0xCD, 0x44, 0xD9, 0x89, 0xD9, 0xB0,
+ 0x7D, 0x44, 0xD9, 0x8A, 0xD9, 0x94, 0xCD, 0x44,
+ // Bytes 4480 - 44bf
+ 0xDB, 0x92, 0xD9, 0x94, 0xCD, 0x44, 0xDB, 0x95,
+ 0xD9, 0x94, 0xCD, 0x45, 0x20, 0xCC, 0x88, 0xCC,
+ 0x80, 0xCE, 0x45, 0x20, 0xCC, 0x88, 0xCC, 0x81,
+ 0xCE, 0x45, 0x20, 0xCC, 0x88, 0xCD, 0x82, 0xCE,
+ 0x45, 0x20, 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x45,
+ 0x20, 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x45, 0x20,
+ 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x45, 0x20, 0xCC,
+ 0x94, 0xCC, 0x80, 0xCE, 0x45, 0x20, 0xCC, 0x94,
+ // Bytes 44c0 - 44ff
+ 0xCC, 0x81, 0xCE, 0x45, 0x20, 0xCC, 0x94, 0xCD,
+ 0x82, 0xCE, 0x45, 0x20, 0xD9, 0x8C, 0xD9, 0x91,
+ 0x76, 0x45, 0x20, 0xD9, 0x8D, 0xD9, 0x91, 0x76,
+ 0x45, 0x20, 0xD9, 0x8E, 0xD9, 0x91, 0x76, 0x45,
+ 0x20, 0xD9, 0x8F, 0xD9, 0x91, 0x76, 0x45, 0x20,
+ 0xD9, 0x90, 0xD9, 0x91, 0x76, 0x45, 0x20, 0xD9,
+ 0x91, 0xD9, 0xB0, 0x7E, 0x45, 0xE2, 0xAB, 0x9D,
+ 0xCC, 0xB8, 0x05, 0x46, 0xCE, 0xB9, 0xCC, 0x88,
+ // Bytes 4500 - 453f
+ 0xCC, 0x81, 0xCE, 0x46, 0xCF, 0x85, 0xCC, 0x88,
+ 0xCC, 0x81, 0xCE, 0x46, 0xD7, 0xA9, 0xD6, 0xBC,
+ 0xD7, 0x81, 0x52, 0x46, 0xD7, 0xA9, 0xD6, 0xBC,
+ 0xD7, 0x82, 0x56, 0x46, 0xD9, 0x80, 0xD9, 0x8E,
+ 0xD9, 0x91, 0x76, 0x46, 0xD9, 0x80, 0xD9, 0x8F,
+ 0xD9, 0x91, 0x76, 0x46, 0xD9, 0x80, 0xD9, 0x90,
+ 0xD9, 0x91, 0x76, 0x46, 0xE0, 0xA4, 0x95, 0xE0,
+ 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0x96, 0xE0,
+ // Bytes 4540 - 457f
+ 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0x97, 0xE0,
+ 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0x9C, 0xE0,
+ 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xA1, 0xE0,
+ 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xA2, 0xE0,
+ 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xAB, 0xE0,
+ 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA4, 0xAF, 0xE0,
+ 0xA4, 0xBC, 0x0D, 0x46, 0xE0, 0xA6, 0xA1, 0xE0,
+ 0xA6, 0xBC, 0x0D, 0x46, 0xE0, 0xA6, 0xA2, 0xE0,
+ // Bytes 4580 - 45bf
+ 0xA6, 0xBC, 0x0D, 0x46, 0xE0, 0xA6, 0xAF, 0xE0,
+ 0xA6, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0x96, 0xE0,
+ 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0x97, 0xE0,
+ 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0x9C, 0xE0,
+ 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0xAB, 0xE0,
+ 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0xB2, 0xE0,
+ 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xA8, 0xB8, 0xE0,
+ 0xA8, 0xBC, 0x0D, 0x46, 0xE0, 0xAC, 0xA1, 0xE0,
+ // Bytes 45c0 - 45ff
+ 0xAC, 0xBC, 0x0D, 0x46, 0xE0, 0xAC, 0xA2, 0xE0,
+ 0xAC, 0xBC, 0x0D, 0x46, 0xE0, 0xBE, 0xB2, 0xE0,
+ 0xBE, 0x80, 0xA1, 0x46, 0xE0, 0xBE, 0xB3, 0xE0,
+ 0xBE, 0x80, 0xA1, 0x46, 0xE3, 0x83, 0x86, 0xE3,
+ 0x82, 0x99, 0x11, 0x48, 0xF0, 0x9D, 0x85, 0x97,
+ 0xF0, 0x9D, 0x85, 0xA5, 0xB1, 0x48, 0xF0, 0x9D,
+ 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xB1, 0x48,
+ 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5,
+ // Bytes 4600 - 463f
+ 0xB1, 0x48, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D,
+ 0x85, 0xA5, 0xB1, 0x49, 0xE0, 0xBE, 0xB2, 0xE0,
+ 0xBD, 0xB1, 0xE0, 0xBE, 0x80, 0xA2, 0x49, 0xE0,
+ 0xBE, 0xB3, 0xE0, 0xBD, 0xB1, 0xE0, 0xBE, 0x80,
+ 0xA2, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D,
+ 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE, 0xB2, 0x4C,
+ 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5,
+ 0xF0, 0x9D, 0x85, 0xAF, 0xB2, 0x4C, 0xF0, 0x9D,
+ // Bytes 4640 - 467f
+ 0x85, 0x98, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D,
+ 0x85, 0xB0, 0xB2, 0x4C, 0xF0, 0x9D, 0x85, 0x98,
+ 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB1,
+ 0xB2, 0x4C, 0xF0, 0x9D, 0x85, 0x98, 0xF0, 0x9D,
+ 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xB2, 0xB2, 0x4C,
+ 0xF0, 0x9D, 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5,
+ 0xF0, 0x9D, 0x85, 0xAE, 0xB2, 0x4C, 0xF0, 0x9D,
+ 0x86, 0xB9, 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D,
+ // Bytes 4680 - 46bf
+ 0x85, 0xAF, 0xB2, 0x4C, 0xF0, 0x9D, 0x86, 0xBA,
+ 0xF0, 0x9D, 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAE,
+ 0xB2, 0x4C, 0xF0, 0x9D, 0x86, 0xBA, 0xF0, 0x9D,
+ 0x85, 0xA5, 0xF0, 0x9D, 0x85, 0xAF, 0xB2, 0x83,
+ 0x41, 0xCC, 0x82, 0xCD, 0x83, 0x41, 0xCC, 0x86,
+ 0xCD, 0x83, 0x41, 0xCC, 0x87, 0xCD, 0x83, 0x41,
+ 0xCC, 0x88, 0xCD, 0x83, 0x41, 0xCC, 0x8A, 0xCD,
+ 0x83, 0x41, 0xCC, 0xA3, 0xB9, 0x83, 0x43, 0xCC,
+ // Bytes 46c0 - 46ff
+ 0xA7, 0xA9, 0x83, 0x45, 0xCC, 0x82, 0xCD, 0x83,
+ 0x45, 0xCC, 0x84, 0xCD, 0x83, 0x45, 0xCC, 0xA3,
+ 0xB9, 0x83, 0x45, 0xCC, 0xA7, 0xA9, 0x83, 0x49,
+ 0xCC, 0x88, 0xCD, 0x83, 0x4C, 0xCC, 0xA3, 0xB9,
+ 0x83, 0x4F, 0xCC, 0x82, 0xCD, 0x83, 0x4F, 0xCC,
+ 0x83, 0xCD, 0x83, 0x4F, 0xCC, 0x84, 0xCD, 0x83,
+ 0x4F, 0xCC, 0x87, 0xCD, 0x83, 0x4F, 0xCC, 0x88,
+ 0xCD, 0x83, 0x4F, 0xCC, 0x9B, 0xB1, 0x83, 0x4F,
+ // Bytes 4700 - 473f
+ 0xCC, 0xA3, 0xB9, 0x83, 0x4F, 0xCC, 0xA8, 0xA9,
+ 0x83, 0x52, 0xCC, 0xA3, 0xB9, 0x83, 0x53, 0xCC,
+ 0x81, 0xCD, 0x83, 0x53, 0xCC, 0x8C, 0xCD, 0x83,
+ 0x53, 0xCC, 0xA3, 0xB9, 0x83, 0x55, 0xCC, 0x83,
+ 0xCD, 0x83, 0x55, 0xCC, 0x84, 0xCD, 0x83, 0x55,
+ 0xCC, 0x88, 0xCD, 0x83, 0x55, 0xCC, 0x9B, 0xB1,
+ 0x83, 0x61, 0xCC, 0x82, 0xCD, 0x83, 0x61, 0xCC,
+ 0x86, 0xCD, 0x83, 0x61, 0xCC, 0x87, 0xCD, 0x83,
+ // Bytes 4740 - 477f
+ 0x61, 0xCC, 0x88, 0xCD, 0x83, 0x61, 0xCC, 0x8A,
+ 0xCD, 0x83, 0x61, 0xCC, 0xA3, 0xB9, 0x83, 0x63,
+ 0xCC, 0xA7, 0xA9, 0x83, 0x65, 0xCC, 0x82, 0xCD,
+ 0x83, 0x65, 0xCC, 0x84, 0xCD, 0x83, 0x65, 0xCC,
+ 0xA3, 0xB9, 0x83, 0x65, 0xCC, 0xA7, 0xA9, 0x83,
+ 0x69, 0xCC, 0x88, 0xCD, 0x83, 0x6C, 0xCC, 0xA3,
+ 0xB9, 0x83, 0x6F, 0xCC, 0x82, 0xCD, 0x83, 0x6F,
+ 0xCC, 0x83, 0xCD, 0x83, 0x6F, 0xCC, 0x84, 0xCD,
+ // Bytes 4780 - 47bf
+ 0x83, 0x6F, 0xCC, 0x87, 0xCD, 0x83, 0x6F, 0xCC,
+ 0x88, 0xCD, 0x83, 0x6F, 0xCC, 0x9B, 0xB1, 0x83,
+ 0x6F, 0xCC, 0xA3, 0xB9, 0x83, 0x6F, 0xCC, 0xA8,
+ 0xA9, 0x83, 0x72, 0xCC, 0xA3, 0xB9, 0x83, 0x73,
+ 0xCC, 0x81, 0xCD, 0x83, 0x73, 0xCC, 0x8C, 0xCD,
+ 0x83, 0x73, 0xCC, 0xA3, 0xB9, 0x83, 0x75, 0xCC,
+ 0x83, 0xCD, 0x83, 0x75, 0xCC, 0x84, 0xCD, 0x83,
+ 0x75, 0xCC, 0x88, 0xCD, 0x83, 0x75, 0xCC, 0x9B,
+ // Bytes 47c0 - 47ff
+ 0xB1, 0x84, 0xCE, 0x91, 0xCC, 0x93, 0xCD, 0x84,
+ 0xCE, 0x91, 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0x95,
+ 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0x95, 0xCC, 0x94,
+ 0xCD, 0x84, 0xCE, 0x97, 0xCC, 0x93, 0xCD, 0x84,
+ 0xCE, 0x97, 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0x99,
+ 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0x99, 0xCC, 0x94,
+ 0xCD, 0x84, 0xCE, 0x9F, 0xCC, 0x93, 0xCD, 0x84,
+ 0xCE, 0x9F, 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0xA5,
+ // Bytes 4800 - 483f
+ 0xCC, 0x94, 0xCD, 0x84, 0xCE, 0xA9, 0xCC, 0x93,
+ 0xCD, 0x84, 0xCE, 0xA9, 0xCC, 0x94, 0xCD, 0x84,
+ 0xCE, 0xB1, 0xCC, 0x80, 0xCD, 0x84, 0xCE, 0xB1,
+ 0xCC, 0x81, 0xCD, 0x84, 0xCE, 0xB1, 0xCC, 0x93,
+ 0xCD, 0x84, 0xCE, 0xB1, 0xCC, 0x94, 0xCD, 0x84,
+ 0xCE, 0xB1, 0xCD, 0x82, 0xCD, 0x84, 0xCE, 0xB5,
+ 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0xB5, 0xCC, 0x94,
+ 0xCD, 0x84, 0xCE, 0xB7, 0xCC, 0x80, 0xCD, 0x84,
+ // Bytes 4840 - 487f
+ 0xCE, 0xB7, 0xCC, 0x81, 0xCD, 0x84, 0xCE, 0xB7,
+ 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0xB7, 0xCC, 0x94,
+ 0xCD, 0x84, 0xCE, 0xB7, 0xCD, 0x82, 0xCD, 0x84,
+ 0xCE, 0xB9, 0xCC, 0x88, 0xCD, 0x84, 0xCE, 0xB9,
+ 0xCC, 0x93, 0xCD, 0x84, 0xCE, 0xB9, 0xCC, 0x94,
+ 0xCD, 0x84, 0xCE, 0xBF, 0xCC, 0x93, 0xCD, 0x84,
+ 0xCE, 0xBF, 0xCC, 0x94, 0xCD, 0x84, 0xCF, 0x85,
+ 0xCC, 0x88, 0xCD, 0x84, 0xCF, 0x85, 0xCC, 0x93,
+ // Bytes 4880 - 48bf
+ 0xCD, 0x84, 0xCF, 0x85, 0xCC, 0x94, 0xCD, 0x84,
+ 0xCF, 0x89, 0xCC, 0x80, 0xCD, 0x84, 0xCF, 0x89,
+ 0xCC, 0x81, 0xCD, 0x84, 0xCF, 0x89, 0xCC, 0x93,
+ 0xCD, 0x84, 0xCF, 0x89, 0xCC, 0x94, 0xCD, 0x84,
+ 0xCF, 0x89, 0xCD, 0x82, 0xCD, 0x86, 0xCE, 0x91,
+ 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x91,
+ 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x91,
+ 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0x91,
+ // Bytes 48c0 - 48ff
+ 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x91,
+ 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x91,
+ 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0x97,
+ 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x97,
+ 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x97,
+ 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0x97,
+ 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0x97,
+ 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0x97,
+ // Bytes 4900 - 493f
+ 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xA9,
+ 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xA9,
+ 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xA9,
+ 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xA9,
+ 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xA9,
+ 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xA9,
+ 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB1,
+ 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB1,
+ // Bytes 4940 - 497f
+ 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB1,
+ 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB1,
+ 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB1,
+ 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB1,
+ 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB7,
+ 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB7,
+ 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB7,
+ 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCE, 0xB7,
+ // Bytes 4980 - 49bf
+ 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCE, 0xB7,
+ 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCE, 0xB7,
+ 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x86, 0xCF, 0x89,
+ 0xCC, 0x93, 0xCC, 0x80, 0xCE, 0x86, 0xCF, 0x89,
+ 0xCC, 0x93, 0xCC, 0x81, 0xCE, 0x86, 0xCF, 0x89,
+ 0xCC, 0x93, 0xCD, 0x82, 0xCE, 0x86, 0xCF, 0x89,
+ 0xCC, 0x94, 0xCC, 0x80, 0xCE, 0x86, 0xCF, 0x89,
+ 0xCC, 0x94, 0xCC, 0x81, 0xCE, 0x86, 0xCF, 0x89,
+ // Bytes 49c0 - 49ff
+ 0xCC, 0x94, 0xCD, 0x82, 0xCE, 0x42, 0xCC, 0x80,
+ 0xCD, 0x33, 0x42, 0xCC, 0x81, 0xCD, 0x33, 0x42,
+ 0xCC, 0x93, 0xCD, 0x33, 0x43, 0xE1, 0x85, 0xA1,
+ 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA2, 0x01, 0x00,
+ 0x43, 0xE1, 0x85, 0xA3, 0x01, 0x00, 0x43, 0xE1,
+ 0x85, 0xA4, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA5,
+ 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA6, 0x01, 0x00,
+ 0x43, 0xE1, 0x85, 0xA7, 0x01, 0x00, 0x43, 0xE1,
+ // Bytes 4a00 - 4a3f
+ 0x85, 0xA8, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xA9,
+ 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAA, 0x01, 0x00,
+ 0x43, 0xE1, 0x85, 0xAB, 0x01, 0x00, 0x43, 0xE1,
+ 0x85, 0xAC, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAD,
+ 0x01, 0x00, 0x43, 0xE1, 0x85, 0xAE, 0x01, 0x00,
+ 0x43, 0xE1, 0x85, 0xAF, 0x01, 0x00, 0x43, 0xE1,
+ 0x85, 0xB0, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB1,
+ 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB2, 0x01, 0x00,
+ // Bytes 4a40 - 4a7f
+ 0x43, 0xE1, 0x85, 0xB3, 0x01, 0x00, 0x43, 0xE1,
+ 0x85, 0xB4, 0x01, 0x00, 0x43, 0xE1, 0x85, 0xB5,
+ 0x01, 0x00, 0x43, 0xE1, 0x86, 0xAA, 0x01, 0x00,
+ 0x43, 0xE1, 0x86, 0xAC, 0x01, 0x00, 0x43, 0xE1,
+ 0x86, 0xAD, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB0,
+ 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB1, 0x01, 0x00,
+ 0x43, 0xE1, 0x86, 0xB2, 0x01, 0x00, 0x43, 0xE1,
+ 0x86, 0xB3, 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB4,
+ // Bytes 4a80 - 4abf
+ 0x01, 0x00, 0x43, 0xE1, 0x86, 0xB5, 0x01, 0x00,
+ 0x44, 0xCC, 0x88, 0xCC, 0x81, 0xCE, 0x33, 0x43,
+ 0xE3, 0x82, 0x99, 0x11, 0x04, 0x43, 0xE3, 0x82,
+ 0x9A, 0x11, 0x04, 0x46, 0xE0, 0xBD, 0xB1, 0xE0,
+ 0xBD, 0xB2, 0xA2, 0x27, 0x46, 0xE0, 0xBD, 0xB1,
+ 0xE0, 0xBD, 0xB4, 0xA6, 0x27, 0x46, 0xE0, 0xBD,
+ 0xB1, 0xE0, 0xBE, 0x80, 0xA2, 0x27, 0x00, 0x01,
+}
+
+// lookup returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *nfcTrie) lookup(s []byte) (v uint16, sz int) {
+ c0 := s[0]
+ switch {
+ case c0 < 0x80: // is ASCII
+ return nfcValues[c0], 1
+ case c0 < 0xC2:
+ return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+ case c0 < 0xE0: // 2-byte UTF-8
+ if len(s) < 2 {
+ return 0, 0
+ }
+ i := nfcIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c1), 2
+ case c0 < 0xF0: // 3-byte UTF-8
+ if len(s) < 3 {
+ return 0, 0
+ }
+ i := nfcIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = nfcIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c2), 3
+ case c0 < 0xF8: // 4-byte UTF-8
+ if len(s) < 4 {
+ return 0, 0
+ }
+ i := nfcIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = nfcIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ o = uint32(i)<<6 + uint32(c2)
+ i = nfcIndex[o]
+ c3 := s[3]
+ if c3 < 0x80 || 0xC0 <= c3 {
+ return 0, 3 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c3), 4
+ }
+ // Illegal rune
+ return 0, 1
+}
+
+// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *nfcTrie) lookupUnsafe(s []byte) uint16 {
+ c0 := s[0]
+ if c0 < 0x80 { // is ASCII
+ return nfcValues[c0]
+ }
+ i := nfcIndex[c0]
+ if c0 < 0xE0 { // 2-byte UTF-8
+ return t.lookupValue(uint32(i), s[1])
+ }
+ i = nfcIndex[uint32(i)<<6+uint32(s[1])]
+ if c0 < 0xF0 { // 3-byte UTF-8
+ return t.lookupValue(uint32(i), s[2])
+ }
+ i = nfcIndex[uint32(i)<<6+uint32(s[2])]
+ if c0 < 0xF8 { // 4-byte UTF-8
+ return t.lookupValue(uint32(i), s[3])
+ }
+ return 0
+}
+
+// lookupString returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *nfcTrie) lookupString(s string) (v uint16, sz int) {
+ c0 := s[0]
+ switch {
+ case c0 < 0x80: // is ASCII
+ return nfcValues[c0], 1
+ case c0 < 0xC2:
+ return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+ case c0 < 0xE0: // 2-byte UTF-8
+ if len(s) < 2 {
+ return 0, 0
+ }
+ i := nfcIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c1), 2
+ case c0 < 0xF0: // 3-byte UTF-8
+ if len(s) < 3 {
+ return 0, 0
+ }
+ i := nfcIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = nfcIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c2), 3
+ case c0 < 0xF8: // 4-byte UTF-8
+ if len(s) < 4 {
+ return 0, 0
+ }
+ i := nfcIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = nfcIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ o = uint32(i)<<6 + uint32(c2)
+ i = nfcIndex[o]
+ c3 := s[3]
+ if c3 < 0x80 || 0xC0 <= c3 {
+ return 0, 3 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c3), 4
+ }
+ // Illegal rune
+ return 0, 1
+}
+
+// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *nfcTrie) lookupStringUnsafe(s string) uint16 {
+ c0 := s[0]
+ if c0 < 0x80 { // is ASCII
+ return nfcValues[c0]
+ }
+ i := nfcIndex[c0]
+ if c0 < 0xE0 { // 2-byte UTF-8
+ return t.lookupValue(uint32(i), s[1])
+ }
+ i = nfcIndex[uint32(i)<<6+uint32(s[1])]
+ if c0 < 0xF0 { // 3-byte UTF-8
+ return t.lookupValue(uint32(i), s[2])
+ }
+ i = nfcIndex[uint32(i)<<6+uint32(s[2])]
+ if c0 < 0xF8 { // 4-byte UTF-8
+ return t.lookupValue(uint32(i), s[3])
+ }
+ return 0
+}
+
+// nfcTrie. Total size: 10680 bytes (10.43 KiB). Checksum: a555db76d4becdd2.
+type nfcTrie struct{}
+
+func newNfcTrie(i int) *nfcTrie {
+ return &nfcTrie{}
+}
+
+// lookupValue determines the type of block n and looks up the value for b.
+func (t *nfcTrie) lookupValue(n uint32, b byte) uint16 {
+ switch {
+ case n < 46:
+ return uint16(nfcValues[n<<6+uint32(b)])
+ default:
+ n -= 46
+ return uint16(nfcSparse.lookup(n, b))
+ }
+}
+
+// nfcValues: 48 blocks, 3072 entries, 6144 bytes
+// The third block is the zero block.
+var nfcValues = [3072]uint16{
+ // Block 0x0, offset 0x0
+ 0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000,
+ // Block 0x1, offset 0x40
+ 0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000,
+ 0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000,
+ 0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000,
+ 0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000,
+ 0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000,
+ 0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000,
+ 0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000,
+ 0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000,
+ 0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000,
+ 0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000,
+ // Block 0x2, offset 0x80
+ // Block 0x3, offset 0xc0
+ 0xc0: 0x2f86, 0xc1: 0x2f8b, 0xc2: 0x469f, 0xc3: 0x2f90, 0xc4: 0x46ae, 0xc5: 0x46b3,
+ 0xc6: 0xa000, 0xc7: 0x46bd, 0xc8: 0x2ff9, 0xc9: 0x2ffe, 0xca: 0x46c2, 0xcb: 0x3012,
+ 0xcc: 0x3085, 0xcd: 0x308a, 0xce: 0x308f, 0xcf: 0x46d6, 0xd1: 0x311b,
+ 0xd2: 0x313e, 0xd3: 0x3143, 0xd4: 0x46e0, 0xd5: 0x46e5, 0xd6: 0x46f4,
+ 0xd8: 0xa000, 0xd9: 0x31ca, 0xda: 0x31cf, 0xdb: 0x31d4, 0xdc: 0x4726, 0xdd: 0x324c,
+ 0xe0: 0x3292, 0xe1: 0x3297, 0xe2: 0x4730, 0xe3: 0x329c,
+ 0xe4: 0x473f, 0xe5: 0x4744, 0xe6: 0xa000, 0xe7: 0x474e, 0xe8: 0x3305, 0xe9: 0x330a,
+ 0xea: 0x4753, 0xeb: 0x331e, 0xec: 0x3396, 0xed: 0x339b, 0xee: 0x33a0, 0xef: 0x4767,
+ 0xf1: 0x342c, 0xf2: 0x344f, 0xf3: 0x3454, 0xf4: 0x4771, 0xf5: 0x4776,
+ 0xf6: 0x4785, 0xf8: 0xa000, 0xf9: 0x34e0, 0xfa: 0x34e5, 0xfb: 0x34ea,
+ 0xfc: 0x47b7, 0xfd: 0x3567, 0xff: 0x3580,
+ // Block 0x4, offset 0x100
+ 0x100: 0x2f95, 0x101: 0x32a1, 0x102: 0x46a4, 0x103: 0x4735, 0x104: 0x2fb3, 0x105: 0x32bf,
+ 0x106: 0x2fc7, 0x107: 0x32d3, 0x108: 0x2fcc, 0x109: 0x32d8, 0x10a: 0x2fd1, 0x10b: 0x32dd,
+ 0x10c: 0x2fd6, 0x10d: 0x32e2, 0x10e: 0x2fe0, 0x10f: 0x32ec,
+ 0x112: 0x46c7, 0x113: 0x4758, 0x114: 0x3008, 0x115: 0x3314, 0x116: 0x300d, 0x117: 0x3319,
+ 0x118: 0x302b, 0x119: 0x3337, 0x11a: 0x301c, 0x11b: 0x3328, 0x11c: 0x3044, 0x11d: 0x3350,
+ 0x11e: 0x304e, 0x11f: 0x335a, 0x120: 0x3053, 0x121: 0x335f, 0x122: 0x305d, 0x123: 0x3369,
+ 0x124: 0x3062, 0x125: 0x336e, 0x128: 0x3094, 0x129: 0x33a5,
+ 0x12a: 0x3099, 0x12b: 0x33aa, 0x12c: 0x309e, 0x12d: 0x33af, 0x12e: 0x30c1, 0x12f: 0x33cd,
+ 0x130: 0x30a3, 0x134: 0x30cb, 0x135: 0x33d7,
+ 0x136: 0x30df, 0x137: 0x33f0, 0x139: 0x30e9, 0x13a: 0x33fa, 0x13b: 0x30f3,
+ 0x13c: 0x3404, 0x13d: 0x30ee, 0x13e: 0x33ff,
+ // Block 0x5, offset 0x140
+ 0x143: 0x3116, 0x144: 0x3427, 0x145: 0x312f,
+ 0x146: 0x3440, 0x147: 0x3125, 0x148: 0x3436,
+ 0x14c: 0x46ea, 0x14d: 0x477b, 0x14e: 0x3148, 0x14f: 0x3459, 0x150: 0x3152, 0x151: 0x3463,
+ 0x154: 0x3170, 0x155: 0x3481, 0x156: 0x3189, 0x157: 0x349a,
+ 0x158: 0x317a, 0x159: 0x348b, 0x15a: 0x470d, 0x15b: 0x479e, 0x15c: 0x3193, 0x15d: 0x34a4,
+ 0x15e: 0x31a2, 0x15f: 0x34b3, 0x160: 0x4712, 0x161: 0x47a3, 0x162: 0x31bb, 0x163: 0x34d1,
+ 0x164: 0x31ac, 0x165: 0x34c2, 0x168: 0x471c, 0x169: 0x47ad,
+ 0x16a: 0x4721, 0x16b: 0x47b2, 0x16c: 0x31d9, 0x16d: 0x34ef, 0x16e: 0x31e3, 0x16f: 0x34f9,
+ 0x170: 0x31e8, 0x171: 0x34fe, 0x172: 0x3206, 0x173: 0x351c, 0x174: 0x3229, 0x175: 0x353f,
+ 0x176: 0x3251, 0x177: 0x356c, 0x178: 0x3265, 0x179: 0x3274, 0x17a: 0x3594, 0x17b: 0x327e,
+ 0x17c: 0x359e, 0x17d: 0x3283, 0x17e: 0x35a3, 0x17f: 0xa000,
+ // Block 0x6, offset 0x180
+ 0x184: 0x8100, 0x185: 0x8100,
+ 0x186: 0x8100,
+ 0x18d: 0x2f9f, 0x18e: 0x32ab, 0x18f: 0x30ad, 0x190: 0x33b9, 0x191: 0x3157,
+ 0x192: 0x3468, 0x193: 0x31ed, 0x194: 0x3503, 0x195: 0x39e6, 0x196: 0x3b75, 0x197: 0x39df,
+ 0x198: 0x3b6e, 0x199: 0x39ed, 0x19a: 0x3b7c, 0x19b: 0x39d8, 0x19c: 0x3b67,
+ 0x19e: 0x38c7, 0x19f: 0x3a56, 0x1a0: 0x38c0, 0x1a1: 0x3a4f, 0x1a2: 0x35ca, 0x1a3: 0x35dc,
+ 0x1a6: 0x3058, 0x1a7: 0x3364, 0x1a8: 0x30d5, 0x1a9: 0x33e6,
+ 0x1aa: 0x4703, 0x1ab: 0x4794, 0x1ac: 0x39a7, 0x1ad: 0x3b36, 0x1ae: 0x35ee, 0x1af: 0x35f4,
+ 0x1b0: 0x33dc, 0x1b4: 0x303f, 0x1b5: 0x334b,
+ 0x1b8: 0x3111, 0x1b9: 0x3422, 0x1ba: 0x38ce, 0x1bb: 0x3a5d,
+ 0x1bc: 0x35c4, 0x1bd: 0x35d6, 0x1be: 0x35d0, 0x1bf: 0x35e2,
+ // Block 0x7, offset 0x1c0
+ 0x1c0: 0x2fa4, 0x1c1: 0x32b0, 0x1c2: 0x2fa9, 0x1c3: 0x32b5, 0x1c4: 0x3021, 0x1c5: 0x332d,
+ 0x1c6: 0x3026, 0x1c7: 0x3332, 0x1c8: 0x30b2, 0x1c9: 0x33be, 0x1ca: 0x30b7, 0x1cb: 0x33c3,
+ 0x1cc: 0x315c, 0x1cd: 0x346d, 0x1ce: 0x3161, 0x1cf: 0x3472, 0x1d0: 0x317f, 0x1d1: 0x3490,
+ 0x1d2: 0x3184, 0x1d3: 0x3495, 0x1d4: 0x31f2, 0x1d5: 0x3508, 0x1d6: 0x31f7, 0x1d7: 0x350d,
+ 0x1d8: 0x319d, 0x1d9: 0x34ae, 0x1da: 0x31b6, 0x1db: 0x34cc,
+ 0x1de: 0x3071, 0x1df: 0x337d,
+ 0x1e6: 0x46a9, 0x1e7: 0x473a, 0x1e8: 0x46d1, 0x1e9: 0x4762,
+ 0x1ea: 0x3976, 0x1eb: 0x3b05, 0x1ec: 0x3953, 0x1ed: 0x3ae2, 0x1ee: 0x46ef, 0x1ef: 0x4780,
+ 0x1f0: 0x396f, 0x1f1: 0x3afe, 0x1f2: 0x325b, 0x1f3: 0x3576,
+ // Block 0x8, offset 0x200
+ 0x200: 0x9933, 0x201: 0x9933, 0x202: 0x9933, 0x203: 0x9933, 0x204: 0x9933, 0x205: 0x8133,
+ 0x206: 0x9933, 0x207: 0x9933, 0x208: 0x9933, 0x209: 0x9933, 0x20a: 0x9933, 0x20b: 0x9933,
+ 0x20c: 0x9933, 0x20d: 0x8133, 0x20e: 0x8133, 0x20f: 0x9933, 0x210: 0x8133, 0x211: 0x9933,
+ 0x212: 0x8133, 0x213: 0x9933, 0x214: 0x9933, 0x215: 0x8134, 0x216: 0x812e, 0x217: 0x812e,
+ 0x218: 0x812e, 0x219: 0x812e, 0x21a: 0x8134, 0x21b: 0x992c, 0x21c: 0x812e, 0x21d: 0x812e,
+ 0x21e: 0x812e, 0x21f: 0x812e, 0x220: 0x812e, 0x221: 0x812a, 0x222: 0x812a, 0x223: 0x992e,
+ 0x224: 0x992e, 0x225: 0x992e, 0x226: 0x992e, 0x227: 0x992a, 0x228: 0x992a, 0x229: 0x812e,
+ 0x22a: 0x812e, 0x22b: 0x812e, 0x22c: 0x812e, 0x22d: 0x992e, 0x22e: 0x992e, 0x22f: 0x812e,
+ 0x230: 0x992e, 0x231: 0x992e, 0x232: 0x812e, 0x233: 0x812e, 0x234: 0x8101, 0x235: 0x8101,
+ 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812e, 0x23a: 0x812e, 0x23b: 0x812e,
+ 0x23c: 0x812e, 0x23d: 0x8133, 0x23e: 0x8133, 0x23f: 0x8133,
+ // Block 0x9, offset 0x240
+ 0x240: 0x49c5, 0x241: 0x49ca, 0x242: 0x9933, 0x243: 0x49cf, 0x244: 0x4a88, 0x245: 0x9937,
+ 0x246: 0x8133, 0x247: 0x812e, 0x248: 0x812e, 0x249: 0x812e, 0x24a: 0x8133, 0x24b: 0x8133,
+ 0x24c: 0x8133, 0x24d: 0x812e, 0x24e: 0x812e, 0x250: 0x8133, 0x251: 0x8133,
+ 0x252: 0x8133, 0x253: 0x812e, 0x254: 0x812e, 0x255: 0x812e, 0x256: 0x812e, 0x257: 0x8133,
+ 0x258: 0x8134, 0x259: 0x812e, 0x25a: 0x812e, 0x25b: 0x8133, 0x25c: 0x8135, 0x25d: 0x8136,
+ 0x25e: 0x8136, 0x25f: 0x8135, 0x260: 0x8136, 0x261: 0x8136, 0x262: 0x8135, 0x263: 0x8133,
+ 0x264: 0x8133, 0x265: 0x8133, 0x266: 0x8133, 0x267: 0x8133, 0x268: 0x8133, 0x269: 0x8133,
+ 0x26a: 0x8133, 0x26b: 0x8133, 0x26c: 0x8133, 0x26d: 0x8133, 0x26e: 0x8133, 0x26f: 0x8133,
+ 0x274: 0x0173,
+ 0x27a: 0x8100,
+ 0x27e: 0x0037,
+ // Block 0xa, offset 0x280
+ 0x284: 0x8100, 0x285: 0x35b8,
+ 0x286: 0x3600, 0x287: 0x00ce, 0x288: 0x361e, 0x289: 0x362a, 0x28a: 0x363c,
+ 0x28c: 0x365a, 0x28e: 0x366c, 0x28f: 0x368a, 0x290: 0x3e1f, 0x291: 0xa000,
+ 0x295: 0xa000, 0x297: 0xa000,
+ 0x299: 0xa000,
+ 0x29f: 0xa000, 0x2a1: 0xa000,
+ 0x2a5: 0xa000, 0x2a9: 0xa000,
+ 0x2aa: 0x364e, 0x2ab: 0x367e, 0x2ac: 0x4815, 0x2ad: 0x36ae, 0x2ae: 0x483f, 0x2af: 0x36c0,
+ 0x2b0: 0x3e87, 0x2b1: 0xa000, 0x2b5: 0xa000,
+ 0x2b7: 0xa000, 0x2b9: 0xa000,
+ 0x2bf: 0xa000,
+ // Block 0xb, offset 0x2c0
+ 0x2c0: 0x3738, 0x2c1: 0x3744, 0x2c3: 0x3732,
+ 0x2c6: 0xa000, 0x2c7: 0x3720,
+ 0x2cc: 0x3774, 0x2cd: 0x375c, 0x2ce: 0x3786, 0x2d0: 0xa000,
+ 0x2d3: 0xa000, 0x2d5: 0xa000, 0x2d6: 0xa000, 0x2d7: 0xa000,
+ 0x2d8: 0xa000, 0x2d9: 0x3768, 0x2da: 0xa000,
+ 0x2de: 0xa000, 0x2e3: 0xa000,
+ 0x2e7: 0xa000,
+ 0x2eb: 0xa000, 0x2ed: 0xa000,
+ 0x2f0: 0xa000, 0x2f3: 0xa000, 0x2f5: 0xa000,
+ 0x2f6: 0xa000, 0x2f7: 0xa000, 0x2f8: 0xa000, 0x2f9: 0x37ec, 0x2fa: 0xa000,
+ 0x2fe: 0xa000,
+ // Block 0xc, offset 0x300
+ 0x301: 0x374a, 0x302: 0x37ce,
+ 0x310: 0x3726, 0x311: 0x37aa,
+ 0x312: 0x372c, 0x313: 0x37b0, 0x316: 0x373e, 0x317: 0x37c2,
+ 0x318: 0xa000, 0x319: 0xa000, 0x31a: 0x3840, 0x31b: 0x3846, 0x31c: 0x3750, 0x31d: 0x37d4,
+ 0x31e: 0x3756, 0x31f: 0x37da, 0x322: 0x3762, 0x323: 0x37e6,
+ 0x324: 0x376e, 0x325: 0x37f2, 0x326: 0x377a, 0x327: 0x37fe, 0x328: 0xa000, 0x329: 0xa000,
+ 0x32a: 0x384c, 0x32b: 0x3852, 0x32c: 0x37a4, 0x32d: 0x3828, 0x32e: 0x3780, 0x32f: 0x3804,
+ 0x330: 0x378c, 0x331: 0x3810, 0x332: 0x3792, 0x333: 0x3816, 0x334: 0x3798, 0x335: 0x381c,
+ 0x338: 0x379e, 0x339: 0x3822,
+ // Block 0xd, offset 0x340
+ 0x351: 0x812e,
+ 0x352: 0x8133, 0x353: 0x8133, 0x354: 0x8133, 0x355: 0x8133, 0x356: 0x812e, 0x357: 0x8133,
+ 0x358: 0x8133, 0x359: 0x8133, 0x35a: 0x812f, 0x35b: 0x812e, 0x35c: 0x8133, 0x35d: 0x8133,
+ 0x35e: 0x8133, 0x35f: 0x8133, 0x360: 0x8133, 0x361: 0x8133, 0x362: 0x812e, 0x363: 0x812e,
+ 0x364: 0x812e, 0x365: 0x812e, 0x366: 0x812e, 0x367: 0x812e, 0x368: 0x8133, 0x369: 0x8133,
+ 0x36a: 0x812e, 0x36b: 0x8133, 0x36c: 0x8133, 0x36d: 0x812f, 0x36e: 0x8132, 0x36f: 0x8133,
+ 0x370: 0x8106, 0x371: 0x8107, 0x372: 0x8108, 0x373: 0x8109, 0x374: 0x810a, 0x375: 0x810b,
+ 0x376: 0x810c, 0x377: 0x810d, 0x378: 0x810e, 0x379: 0x810f, 0x37a: 0x810f, 0x37b: 0x8110,
+ 0x37c: 0x8111, 0x37d: 0x8112, 0x37f: 0x8113,
+ // Block 0xe, offset 0x380
+ 0x388: 0xa000, 0x38a: 0xa000, 0x38b: 0x8117,
+ 0x38c: 0x8118, 0x38d: 0x8119, 0x38e: 0x811a, 0x38f: 0x811b, 0x390: 0x811c, 0x391: 0x811d,
+ 0x392: 0x811e, 0x393: 0x9933, 0x394: 0x9933, 0x395: 0x992e, 0x396: 0x812e, 0x397: 0x8133,
+ 0x398: 0x8133, 0x399: 0x8133, 0x39a: 0x8133, 0x39b: 0x8133, 0x39c: 0x812e, 0x39d: 0x8133,
+ 0x39e: 0x8133, 0x39f: 0x812e,
+ 0x3b0: 0x811f,
+ // Block 0xf, offset 0x3c0
+ 0x3d3: 0x812e, 0x3d4: 0x8133, 0x3d5: 0x8133, 0x3d6: 0x8133, 0x3d7: 0x8133,
+ 0x3d8: 0x8133, 0x3d9: 0x8133, 0x3da: 0x8133, 0x3db: 0x8133, 0x3dc: 0x8133, 0x3dd: 0x8133,
+ 0x3de: 0x8133, 0x3df: 0x8133, 0x3e0: 0x8133, 0x3e1: 0x8133, 0x3e3: 0x812e,
+ 0x3e4: 0x8133, 0x3e5: 0x8133, 0x3e6: 0x812e, 0x3e7: 0x8133, 0x3e8: 0x8133, 0x3e9: 0x812e,
+ 0x3ea: 0x8133, 0x3eb: 0x8133, 0x3ec: 0x8133, 0x3ed: 0x812e, 0x3ee: 0x812e, 0x3ef: 0x812e,
+ 0x3f0: 0x8117, 0x3f1: 0x8118, 0x3f2: 0x8119, 0x3f3: 0x8133, 0x3f4: 0x8133, 0x3f5: 0x8133,
+ 0x3f6: 0x812e, 0x3f7: 0x8133, 0x3f8: 0x8133, 0x3f9: 0x812e, 0x3fa: 0x812e, 0x3fb: 0x8133,
+ 0x3fc: 0x8133, 0x3fd: 0x8133, 0x3fe: 0x8133, 0x3ff: 0x8133,
+ // Block 0x10, offset 0x400
+ 0x405: 0xa000,
+ 0x406: 0x2d33, 0x407: 0xa000, 0x408: 0x2d3b, 0x409: 0xa000, 0x40a: 0x2d43, 0x40b: 0xa000,
+ 0x40c: 0x2d4b, 0x40d: 0xa000, 0x40e: 0x2d53, 0x411: 0xa000,
+ 0x412: 0x2d5b,
+ 0x434: 0x8103, 0x435: 0x9900,
+ 0x43a: 0xa000, 0x43b: 0x2d63,
+ 0x43c: 0xa000, 0x43d: 0x2d6b, 0x43e: 0xa000, 0x43f: 0xa000,
+ // Block 0x11, offset 0x440
+ 0x440: 0x8133, 0x441: 0x8133, 0x442: 0x812e, 0x443: 0x8133, 0x444: 0x8133, 0x445: 0x8133,
+ 0x446: 0x8133, 0x447: 0x8133, 0x448: 0x8133, 0x449: 0x8133, 0x44a: 0x812e, 0x44b: 0x8133,
+ 0x44c: 0x8133, 0x44d: 0x8136, 0x44e: 0x812b, 0x44f: 0x812e, 0x450: 0x812a, 0x451: 0x8133,
+ 0x452: 0x8133, 0x453: 0x8133, 0x454: 0x8133, 0x455: 0x8133, 0x456: 0x8133, 0x457: 0x8133,
+ 0x458: 0x8133, 0x459: 0x8133, 0x45a: 0x8133, 0x45b: 0x8133, 0x45c: 0x8133, 0x45d: 0x8133,
+ 0x45e: 0x8133, 0x45f: 0x8133, 0x460: 0x8133, 0x461: 0x8133, 0x462: 0x8133, 0x463: 0x8133,
+ 0x464: 0x8133, 0x465: 0x8133, 0x466: 0x8133, 0x467: 0x8133, 0x468: 0x8133, 0x469: 0x8133,
+ 0x46a: 0x8133, 0x46b: 0x8133, 0x46c: 0x8133, 0x46d: 0x8133, 0x46e: 0x8133, 0x46f: 0x8133,
+ 0x470: 0x8133, 0x471: 0x8133, 0x472: 0x8133, 0x473: 0x8133, 0x474: 0x8133, 0x475: 0x8133,
+ 0x476: 0x8134, 0x477: 0x8132, 0x478: 0x8132, 0x479: 0x812e, 0x47b: 0x8133,
+ 0x47c: 0x8135, 0x47d: 0x812e, 0x47e: 0x8133, 0x47f: 0x812e,
+ // Block 0x12, offset 0x480
+ 0x480: 0x2fae, 0x481: 0x32ba, 0x482: 0x2fb8, 0x483: 0x32c4, 0x484: 0x2fbd, 0x485: 0x32c9,
+ 0x486: 0x2fc2, 0x487: 0x32ce, 0x488: 0x38e3, 0x489: 0x3a72, 0x48a: 0x2fdb, 0x48b: 0x32e7,
+ 0x48c: 0x2fe5, 0x48d: 0x32f1, 0x48e: 0x2ff4, 0x48f: 0x3300, 0x490: 0x2fea, 0x491: 0x32f6,
+ 0x492: 0x2fef, 0x493: 0x32fb, 0x494: 0x3906, 0x495: 0x3a95, 0x496: 0x390d, 0x497: 0x3a9c,
+ 0x498: 0x3030, 0x499: 0x333c, 0x49a: 0x3035, 0x49b: 0x3341, 0x49c: 0x391b, 0x49d: 0x3aaa,
+ 0x49e: 0x303a, 0x49f: 0x3346, 0x4a0: 0x3049, 0x4a1: 0x3355, 0x4a2: 0x3067, 0x4a3: 0x3373,
+ 0x4a4: 0x3076, 0x4a5: 0x3382, 0x4a6: 0x306c, 0x4a7: 0x3378, 0x4a8: 0x307b, 0x4a9: 0x3387,
+ 0x4aa: 0x3080, 0x4ab: 0x338c, 0x4ac: 0x30c6, 0x4ad: 0x33d2, 0x4ae: 0x3922, 0x4af: 0x3ab1,
+ 0x4b0: 0x30d0, 0x4b1: 0x33e1, 0x4b2: 0x30da, 0x4b3: 0x33eb, 0x4b4: 0x30e4, 0x4b5: 0x33f5,
+ 0x4b6: 0x46db, 0x4b7: 0x476c, 0x4b8: 0x3929, 0x4b9: 0x3ab8, 0x4ba: 0x30fd, 0x4bb: 0x340e,
+ 0x4bc: 0x30f8, 0x4bd: 0x3409, 0x4be: 0x3102, 0x4bf: 0x3413,
+ // Block 0x13, offset 0x4c0
+ 0x4c0: 0x3107, 0x4c1: 0x3418, 0x4c2: 0x310c, 0x4c3: 0x341d, 0x4c4: 0x3120, 0x4c5: 0x3431,
+ 0x4c6: 0x312a, 0x4c7: 0x343b, 0x4c8: 0x3139, 0x4c9: 0x344a, 0x4ca: 0x3134, 0x4cb: 0x3445,
+ 0x4cc: 0x394c, 0x4cd: 0x3adb, 0x4ce: 0x395a, 0x4cf: 0x3ae9, 0x4d0: 0x3961, 0x4d1: 0x3af0,
+ 0x4d2: 0x3968, 0x4d3: 0x3af7, 0x4d4: 0x3166, 0x4d5: 0x3477, 0x4d6: 0x316b, 0x4d7: 0x347c,
+ 0x4d8: 0x3175, 0x4d9: 0x3486, 0x4da: 0x4708, 0x4db: 0x4799, 0x4dc: 0x39ae, 0x4dd: 0x3b3d,
+ 0x4de: 0x318e, 0x4df: 0x349f, 0x4e0: 0x3198, 0x4e1: 0x34a9, 0x4e2: 0x4717, 0x4e3: 0x47a8,
+ 0x4e4: 0x39b5, 0x4e5: 0x3b44, 0x4e6: 0x39bc, 0x4e7: 0x3b4b, 0x4e8: 0x39c3, 0x4e9: 0x3b52,
+ 0x4ea: 0x31a7, 0x4eb: 0x34b8, 0x4ec: 0x31b1, 0x4ed: 0x34c7, 0x4ee: 0x31c5, 0x4ef: 0x34db,
+ 0x4f0: 0x31c0, 0x4f1: 0x34d6, 0x4f2: 0x3201, 0x4f3: 0x3517, 0x4f4: 0x3210, 0x4f5: 0x3526,
+ 0x4f6: 0x320b, 0x4f7: 0x3521, 0x4f8: 0x39ca, 0x4f9: 0x3b59, 0x4fa: 0x39d1, 0x4fb: 0x3b60,
+ 0x4fc: 0x3215, 0x4fd: 0x352b, 0x4fe: 0x321a, 0x4ff: 0x3530,
+ // Block 0x14, offset 0x500
+ 0x500: 0x321f, 0x501: 0x3535, 0x502: 0x3224, 0x503: 0x353a, 0x504: 0x3233, 0x505: 0x3549,
+ 0x506: 0x322e, 0x507: 0x3544, 0x508: 0x3238, 0x509: 0x3553, 0x50a: 0x323d, 0x50b: 0x3558,
+ 0x50c: 0x3242, 0x50d: 0x355d, 0x50e: 0x3260, 0x50f: 0x357b, 0x510: 0x3279, 0x511: 0x3599,
+ 0x512: 0x3288, 0x513: 0x35a8, 0x514: 0x328d, 0x515: 0x35ad, 0x516: 0x3391, 0x517: 0x34bd,
+ 0x518: 0x354e, 0x519: 0x358a, 0x51b: 0x35e8,
+ 0x520: 0x46b8, 0x521: 0x4749, 0x522: 0x2f9a, 0x523: 0x32a6,
+ 0x524: 0x388f, 0x525: 0x3a1e, 0x526: 0x3888, 0x527: 0x3a17, 0x528: 0x389d, 0x529: 0x3a2c,
+ 0x52a: 0x3896, 0x52b: 0x3a25, 0x52c: 0x38d5, 0x52d: 0x3a64, 0x52e: 0x38ab, 0x52f: 0x3a3a,
+ 0x530: 0x38a4, 0x531: 0x3a33, 0x532: 0x38b9, 0x533: 0x3a48, 0x534: 0x38b2, 0x535: 0x3a41,
+ 0x536: 0x38dc, 0x537: 0x3a6b, 0x538: 0x46cc, 0x539: 0x475d, 0x53a: 0x3017, 0x53b: 0x3323,
+ 0x53c: 0x3003, 0x53d: 0x330f, 0x53e: 0x38f1, 0x53f: 0x3a80,
+ // Block 0x15, offset 0x540
+ 0x540: 0x38ea, 0x541: 0x3a79, 0x542: 0x38ff, 0x543: 0x3a8e, 0x544: 0x38f8, 0x545: 0x3a87,
+ 0x546: 0x3914, 0x547: 0x3aa3, 0x548: 0x30a8, 0x549: 0x33b4, 0x54a: 0x30bc, 0x54b: 0x33c8,
+ 0x54c: 0x46fe, 0x54d: 0x478f, 0x54e: 0x314d, 0x54f: 0x345e, 0x550: 0x3937, 0x551: 0x3ac6,
+ 0x552: 0x3930, 0x553: 0x3abf, 0x554: 0x3945, 0x555: 0x3ad4, 0x556: 0x393e, 0x557: 0x3acd,
+ 0x558: 0x39a0, 0x559: 0x3b2f, 0x55a: 0x3984, 0x55b: 0x3b13, 0x55c: 0x397d, 0x55d: 0x3b0c,
+ 0x55e: 0x3992, 0x55f: 0x3b21, 0x560: 0x398b, 0x561: 0x3b1a, 0x562: 0x3999, 0x563: 0x3b28,
+ 0x564: 0x31fc, 0x565: 0x3512, 0x566: 0x31de, 0x567: 0x34f4, 0x568: 0x39fb, 0x569: 0x3b8a,
+ 0x56a: 0x39f4, 0x56b: 0x3b83, 0x56c: 0x3a09, 0x56d: 0x3b98, 0x56e: 0x3a02, 0x56f: 0x3b91,
+ 0x570: 0x3a10, 0x571: 0x3b9f, 0x572: 0x3247, 0x573: 0x3562, 0x574: 0x326f, 0x575: 0x358f,
+ 0x576: 0x326a, 0x577: 0x3585, 0x578: 0x3256, 0x579: 0x3571,
+ // Block 0x16, offset 0x580
+ 0x580: 0x481b, 0x581: 0x4821, 0x582: 0x4935, 0x583: 0x494d, 0x584: 0x493d, 0x585: 0x4955,
+ 0x586: 0x4945, 0x587: 0x495d, 0x588: 0x47c1, 0x589: 0x47c7, 0x58a: 0x48a5, 0x58b: 0x48bd,
+ 0x58c: 0x48ad, 0x58d: 0x48c5, 0x58e: 0x48b5, 0x58f: 0x48cd, 0x590: 0x482d, 0x591: 0x4833,
+ 0x592: 0x3dcf, 0x593: 0x3ddf, 0x594: 0x3dd7, 0x595: 0x3de7,
+ 0x598: 0x47cd, 0x599: 0x47d3, 0x59a: 0x3cff, 0x59b: 0x3d0f, 0x59c: 0x3d07, 0x59d: 0x3d17,
+ 0x5a0: 0x4845, 0x5a1: 0x484b, 0x5a2: 0x4965, 0x5a3: 0x497d,
+ 0x5a4: 0x496d, 0x5a5: 0x4985, 0x5a6: 0x4975, 0x5a7: 0x498d, 0x5a8: 0x47d9, 0x5a9: 0x47df,
+ 0x5aa: 0x48d5, 0x5ab: 0x48ed, 0x5ac: 0x48dd, 0x5ad: 0x48f5, 0x5ae: 0x48e5, 0x5af: 0x48fd,
+ 0x5b0: 0x485d, 0x5b1: 0x4863, 0x5b2: 0x3e2f, 0x5b3: 0x3e47, 0x5b4: 0x3e37, 0x5b5: 0x3e4f,
+ 0x5b6: 0x3e3f, 0x5b7: 0x3e57, 0x5b8: 0x47e5, 0x5b9: 0x47eb, 0x5ba: 0x3d2f, 0x5bb: 0x3d47,
+ 0x5bc: 0x3d37, 0x5bd: 0x3d4f, 0x5be: 0x3d3f, 0x5bf: 0x3d57,
+ // Block 0x17, offset 0x5c0
+ 0x5c0: 0x4869, 0x5c1: 0x486f, 0x5c2: 0x3e5f, 0x5c3: 0x3e6f, 0x5c4: 0x3e67, 0x5c5: 0x3e77,
+ 0x5c8: 0x47f1, 0x5c9: 0x47f7, 0x5ca: 0x3d5f, 0x5cb: 0x3d6f,
+ 0x5cc: 0x3d67, 0x5cd: 0x3d77, 0x5d0: 0x487b, 0x5d1: 0x4881,
+ 0x5d2: 0x3e97, 0x5d3: 0x3eaf, 0x5d4: 0x3e9f, 0x5d5: 0x3eb7, 0x5d6: 0x3ea7, 0x5d7: 0x3ebf,
+ 0x5d9: 0x47fd, 0x5db: 0x3d7f, 0x5dd: 0x3d87,
+ 0x5df: 0x3d8f, 0x5e0: 0x4893, 0x5e1: 0x4899, 0x5e2: 0x4995, 0x5e3: 0x49ad,
+ 0x5e4: 0x499d, 0x5e5: 0x49b5, 0x5e6: 0x49a5, 0x5e7: 0x49bd, 0x5e8: 0x4803, 0x5e9: 0x4809,
+ 0x5ea: 0x4905, 0x5eb: 0x491d, 0x5ec: 0x490d, 0x5ed: 0x4925, 0x5ee: 0x4915, 0x5ef: 0x492d,
+ 0x5f0: 0x480f, 0x5f1: 0x4335, 0x5f2: 0x36a8, 0x5f3: 0x433b, 0x5f4: 0x4839, 0x5f5: 0x4341,
+ 0x5f6: 0x36ba, 0x5f7: 0x4347, 0x5f8: 0x36d8, 0x5f9: 0x434d, 0x5fa: 0x36f0, 0x5fb: 0x4353,
+ 0x5fc: 0x4887, 0x5fd: 0x4359,
+ // Block 0x18, offset 0x600
+ 0x600: 0x3db7, 0x601: 0x3dbf, 0x602: 0x419b, 0x603: 0x41b9, 0x604: 0x41a5, 0x605: 0x41c3,
+ 0x606: 0x41af, 0x607: 0x41cd, 0x608: 0x3cef, 0x609: 0x3cf7, 0x60a: 0x40e7, 0x60b: 0x4105,
+ 0x60c: 0x40f1, 0x60d: 0x410f, 0x60e: 0x40fb, 0x60f: 0x4119, 0x610: 0x3dff, 0x611: 0x3e07,
+ 0x612: 0x41d7, 0x613: 0x41f5, 0x614: 0x41e1, 0x615: 0x41ff, 0x616: 0x41eb, 0x617: 0x4209,
+ 0x618: 0x3d1f, 0x619: 0x3d27, 0x61a: 0x4123, 0x61b: 0x4141, 0x61c: 0x412d, 0x61d: 0x414b,
+ 0x61e: 0x4137, 0x61f: 0x4155, 0x620: 0x3ed7, 0x621: 0x3edf, 0x622: 0x4213, 0x623: 0x4231,
+ 0x624: 0x421d, 0x625: 0x423b, 0x626: 0x4227, 0x627: 0x4245, 0x628: 0x3d97, 0x629: 0x3d9f,
+ 0x62a: 0x415f, 0x62b: 0x417d, 0x62c: 0x4169, 0x62d: 0x4187, 0x62e: 0x4173, 0x62f: 0x4191,
+ 0x630: 0x369c, 0x631: 0x3696, 0x632: 0x3da7, 0x633: 0x36a2, 0x634: 0x3daf,
+ 0x636: 0x4827, 0x637: 0x3dc7, 0x638: 0x360c, 0x639: 0x3606, 0x63a: 0x35fa, 0x63b: 0x4305,
+ 0x63c: 0x3612, 0x63d: 0x8100, 0x63e: 0x01d6, 0x63f: 0xa100,
+ // Block 0x19, offset 0x640
+ 0x640: 0x8100, 0x641: 0x35be, 0x642: 0x3def, 0x643: 0x36b4, 0x644: 0x3df7,
+ 0x646: 0x4851, 0x647: 0x3e0f, 0x648: 0x3618, 0x649: 0x430b, 0x64a: 0x3624, 0x64b: 0x4311,
+ 0x64c: 0x3630, 0x64d: 0x3ba6, 0x64e: 0x3bad, 0x64f: 0x3bb4, 0x650: 0x36cc, 0x651: 0x36c6,
+ 0x652: 0x3e17, 0x653: 0x44fb, 0x656: 0x36d2, 0x657: 0x3e27,
+ 0x658: 0x3648, 0x659: 0x3642, 0x65a: 0x3636, 0x65b: 0x4317, 0x65d: 0x3bbb,
+ 0x65e: 0x3bc2, 0x65f: 0x3bc9, 0x660: 0x3702, 0x661: 0x36fc, 0x662: 0x3e7f, 0x663: 0x4503,
+ 0x664: 0x36e4, 0x665: 0x36ea, 0x666: 0x3708, 0x667: 0x3e8f, 0x668: 0x3678, 0x669: 0x3672,
+ 0x66a: 0x3666, 0x66b: 0x4323, 0x66c: 0x3660, 0x66d: 0x35b2, 0x66e: 0x42ff, 0x66f: 0x0081,
+ 0x672: 0x3ec7, 0x673: 0x370e, 0x674: 0x3ecf,
+ 0x676: 0x489f, 0x677: 0x3ee7, 0x678: 0x3654, 0x679: 0x431d, 0x67a: 0x3684, 0x67b: 0x432f,
+ 0x67c: 0x3690, 0x67d: 0x426d, 0x67e: 0xa100,
+ // Block 0x1a, offset 0x680
+ 0x681: 0x3c1d, 0x683: 0xa000, 0x684: 0x3c24, 0x685: 0xa000,
+ 0x687: 0x3c2b, 0x688: 0xa000, 0x689: 0x3c32,
+ 0x68d: 0xa000,
+ 0x6a0: 0x2f7c, 0x6a1: 0xa000, 0x6a2: 0x3c40,
+ 0x6a4: 0xa000, 0x6a5: 0xa000,
+ 0x6ad: 0x3c39, 0x6ae: 0x2f77, 0x6af: 0x2f81,
+ 0x6b0: 0x3c47, 0x6b1: 0x3c4e, 0x6b2: 0xa000, 0x6b3: 0xa000, 0x6b4: 0x3c55, 0x6b5: 0x3c5c,
+ 0x6b6: 0xa000, 0x6b7: 0xa000, 0x6b8: 0x3c63, 0x6b9: 0x3c6a, 0x6ba: 0xa000, 0x6bb: 0xa000,
+ 0x6bc: 0xa000, 0x6bd: 0xa000,
+ // Block 0x1b, offset 0x6c0
+ 0x6c0: 0x3c71, 0x6c1: 0x3c78, 0x6c2: 0xa000, 0x6c3: 0xa000, 0x6c4: 0x3c8d, 0x6c5: 0x3c94,
+ 0x6c6: 0xa000, 0x6c7: 0xa000, 0x6c8: 0x3c9b, 0x6c9: 0x3ca2,
+ 0x6d1: 0xa000,
+ 0x6d2: 0xa000,
+ 0x6e2: 0xa000,
+ 0x6e8: 0xa000, 0x6e9: 0xa000,
+ 0x6eb: 0xa000, 0x6ec: 0x3cb7, 0x6ed: 0x3cbe, 0x6ee: 0x3cc5, 0x6ef: 0x3ccc,
+ 0x6f2: 0xa000, 0x6f3: 0xa000, 0x6f4: 0xa000, 0x6f5: 0xa000,
+ // Block 0x1c, offset 0x700
+ 0x706: 0xa000, 0x70b: 0xa000,
+ 0x70c: 0x3f1f, 0x70d: 0xa000, 0x70e: 0x3f27, 0x70f: 0xa000, 0x710: 0x3f2f, 0x711: 0xa000,
+ 0x712: 0x3f37, 0x713: 0xa000, 0x714: 0x3f3f, 0x715: 0xa000, 0x716: 0x3f47, 0x717: 0xa000,
+ 0x718: 0x3f4f, 0x719: 0xa000, 0x71a: 0x3f57, 0x71b: 0xa000, 0x71c: 0x3f5f, 0x71d: 0xa000,
+ 0x71e: 0x3f67, 0x71f: 0xa000, 0x720: 0x3f6f, 0x721: 0xa000, 0x722: 0x3f77,
+ 0x724: 0xa000, 0x725: 0x3f7f, 0x726: 0xa000, 0x727: 0x3f87, 0x728: 0xa000, 0x729: 0x3f8f,
+ 0x72f: 0xa000,
+ 0x730: 0x3f97, 0x731: 0x3f9f, 0x732: 0xa000, 0x733: 0x3fa7, 0x734: 0x3faf, 0x735: 0xa000,
+ 0x736: 0x3fb7, 0x737: 0x3fbf, 0x738: 0xa000, 0x739: 0x3fc7, 0x73a: 0x3fcf, 0x73b: 0xa000,
+ 0x73c: 0x3fd7, 0x73d: 0x3fdf,
+ // Block 0x1d, offset 0x740
+ 0x754: 0x3f17,
+ 0x759: 0x9904, 0x75a: 0x9904, 0x75b: 0x8100, 0x75c: 0x8100, 0x75d: 0xa000,
+ 0x75e: 0x3fe7,
+ 0x766: 0xa000,
+ 0x76b: 0xa000, 0x76c: 0x3ff7, 0x76d: 0xa000, 0x76e: 0x3fff, 0x76f: 0xa000,
+ 0x770: 0x4007, 0x771: 0xa000, 0x772: 0x400f, 0x773: 0xa000, 0x774: 0x4017, 0x775: 0xa000,
+ 0x776: 0x401f, 0x777: 0xa000, 0x778: 0x4027, 0x779: 0xa000, 0x77a: 0x402f, 0x77b: 0xa000,
+ 0x77c: 0x4037, 0x77d: 0xa000, 0x77e: 0x403f, 0x77f: 0xa000,
+ // Block 0x1e, offset 0x780
+ 0x780: 0x4047, 0x781: 0xa000, 0x782: 0x404f, 0x784: 0xa000, 0x785: 0x4057,
+ 0x786: 0xa000, 0x787: 0x405f, 0x788: 0xa000, 0x789: 0x4067,
+ 0x78f: 0xa000, 0x790: 0x406f, 0x791: 0x4077,
+ 0x792: 0xa000, 0x793: 0x407f, 0x794: 0x4087, 0x795: 0xa000, 0x796: 0x408f, 0x797: 0x4097,
+ 0x798: 0xa000, 0x799: 0x409f, 0x79a: 0x40a7, 0x79b: 0xa000, 0x79c: 0x40af, 0x79d: 0x40b7,
+ 0x7af: 0xa000,
+ 0x7b0: 0xa000, 0x7b1: 0xa000, 0x7b2: 0xa000, 0x7b4: 0x3fef,
+ 0x7b7: 0x40bf, 0x7b8: 0x40c7, 0x7b9: 0x40cf, 0x7ba: 0x40d7,
+ 0x7bd: 0xa000, 0x7be: 0x40df,
+ // Block 0x1f, offset 0x7c0
+ 0x7c0: 0x137a, 0x7c1: 0x0cfe, 0x7c2: 0x13d6, 0x7c3: 0x13a2, 0x7c4: 0x0e5a, 0x7c5: 0x06ee,
+ 0x7c6: 0x08e2, 0x7c7: 0x162e, 0x7c8: 0x162e, 0x7c9: 0x0a0e, 0x7ca: 0x1462, 0x7cb: 0x0946,
+ 0x7cc: 0x0a0a, 0x7cd: 0x0bf2, 0x7ce: 0x0fd2, 0x7cf: 0x1162, 0x7d0: 0x129a, 0x7d1: 0x12d6,
+ 0x7d2: 0x130a, 0x7d3: 0x141e, 0x7d4: 0x0d76, 0x7d5: 0x0e02, 0x7d6: 0x0eae, 0x7d7: 0x0f46,
+ 0x7d8: 0x1262, 0x7d9: 0x144a, 0x7da: 0x1576, 0x7db: 0x0712, 0x7dc: 0x08b6, 0x7dd: 0x0d8a,
+ 0x7de: 0x0ed2, 0x7df: 0x1296, 0x7e0: 0x15c6, 0x7e1: 0x0ab6, 0x7e2: 0x0e7a, 0x7e3: 0x1286,
+ 0x7e4: 0x131a, 0x7e5: 0x0c26, 0x7e6: 0x11be, 0x7e7: 0x12e2, 0x7e8: 0x0b22, 0x7e9: 0x0d12,
+ 0x7ea: 0x0e1a, 0x7eb: 0x0f1e, 0x7ec: 0x142a, 0x7ed: 0x0752, 0x7ee: 0x07ea, 0x7ef: 0x0856,
+ 0x7f0: 0x0c8e, 0x7f1: 0x0d82, 0x7f2: 0x0ece, 0x7f3: 0x0ff2, 0x7f4: 0x117a, 0x7f5: 0x128e,
+ 0x7f6: 0x12a6, 0x7f7: 0x13ca, 0x7f8: 0x14f2, 0x7f9: 0x15a6, 0x7fa: 0x15c2, 0x7fb: 0x102e,
+ 0x7fc: 0x106e, 0x7fd: 0x1126, 0x7fe: 0x1246, 0x7ff: 0x147e,
+ // Block 0x20, offset 0x800
+ 0x800: 0x15ce, 0x801: 0x134e, 0x802: 0x09ca, 0x803: 0x0b3e, 0x804: 0x10de, 0x805: 0x119e,
+ 0x806: 0x0f02, 0x807: 0x1036, 0x808: 0x139a, 0x809: 0x14ea, 0x80a: 0x09c6, 0x80b: 0x0a92,
+ 0x80c: 0x0d7a, 0x80d: 0x0e2e, 0x80e: 0x0e62, 0x80f: 0x1116, 0x810: 0x113e, 0x811: 0x14aa,
+ 0x812: 0x0852, 0x813: 0x11aa, 0x814: 0x07f6, 0x815: 0x07f2, 0x816: 0x109a, 0x817: 0x112a,
+ 0x818: 0x125e, 0x819: 0x14b2, 0x81a: 0x136a, 0x81b: 0x0c2a, 0x81c: 0x0d76, 0x81d: 0x135a,
+ 0x81e: 0x06fa, 0x81f: 0x0a66, 0x820: 0x0b96, 0x821: 0x0f32, 0x822: 0x0fb2, 0x823: 0x0876,
+ 0x824: 0x103e, 0x825: 0x0762, 0x826: 0x0b7a, 0x827: 0x06da, 0x828: 0x0dee, 0x829: 0x0ca6,
+ 0x82a: 0x1112, 0x82b: 0x08ca, 0x82c: 0x09b6, 0x82d: 0x0ffe, 0x82e: 0x1266, 0x82f: 0x133e,
+ 0x830: 0x0dba, 0x831: 0x13fa, 0x832: 0x0de6, 0x833: 0x0c3a, 0x834: 0x121e, 0x835: 0x0c5a,
+ 0x836: 0x0fae, 0x837: 0x072e, 0x838: 0x07aa, 0x839: 0x07ee, 0x83a: 0x0d56, 0x83b: 0x10fe,
+ 0x83c: 0x11f6, 0x83d: 0x134a, 0x83e: 0x145e, 0x83f: 0x085e,
+ // Block 0x21, offset 0x840
+ 0x840: 0x0912, 0x841: 0x0a1a, 0x842: 0x0b32, 0x843: 0x0cc2, 0x844: 0x0e7e, 0x845: 0x1042,
+ 0x846: 0x149a, 0x847: 0x157e, 0x848: 0x15d2, 0x849: 0x15ea, 0x84a: 0x083a, 0x84b: 0x0cf6,
+ 0x84c: 0x0da6, 0x84d: 0x13ee, 0x84e: 0x0afe, 0x84f: 0x0bda, 0x850: 0x0bf6, 0x851: 0x0c86,
+ 0x852: 0x0e6e, 0x853: 0x0eba, 0x854: 0x0f6a, 0x855: 0x108e, 0x856: 0x1132, 0x857: 0x1196,
+ 0x858: 0x13de, 0x859: 0x126e, 0x85a: 0x1406, 0x85b: 0x1482, 0x85c: 0x0812, 0x85d: 0x083e,
+ 0x85e: 0x0926, 0x85f: 0x0eaa, 0x860: 0x12f6, 0x861: 0x133e, 0x862: 0x0b1e, 0x863: 0x0b8e,
+ 0x864: 0x0c52, 0x865: 0x0db2, 0x866: 0x10da, 0x867: 0x0f26, 0x868: 0x073e, 0x869: 0x0982,
+ 0x86a: 0x0a66, 0x86b: 0x0aca, 0x86c: 0x0b9a, 0x86d: 0x0f42, 0x86e: 0x0f5e, 0x86f: 0x116e,
+ 0x870: 0x118e, 0x871: 0x1466, 0x872: 0x14e6, 0x873: 0x14f6, 0x874: 0x1532, 0x875: 0x0756,
+ 0x876: 0x1082, 0x877: 0x1452, 0x878: 0x14ce, 0x879: 0x0bb2, 0x87a: 0x071a, 0x87b: 0x077a,
+ 0x87c: 0x0a6a, 0x87d: 0x0a8a, 0x87e: 0x0cb2, 0x87f: 0x0d76,
+ // Block 0x22, offset 0x880
+ 0x880: 0x0ec6, 0x881: 0x0fce, 0x882: 0x127a, 0x883: 0x141a, 0x884: 0x1626, 0x885: 0x0ce6,
+ 0x886: 0x14a6, 0x887: 0x0836, 0x888: 0x0d32, 0x889: 0x0d3e, 0x88a: 0x0e12, 0x88b: 0x0e4a,
+ 0x88c: 0x0f4e, 0x88d: 0x0faa, 0x88e: 0x102a, 0x88f: 0x110e, 0x890: 0x153e, 0x891: 0x07b2,
+ 0x892: 0x0c06, 0x893: 0x14b6, 0x894: 0x076a, 0x895: 0x0aae, 0x896: 0x0e32, 0x897: 0x13e2,
+ 0x898: 0x0b6a, 0x899: 0x0bba, 0x89a: 0x0d46, 0x89b: 0x0f32, 0x89c: 0x14be, 0x89d: 0x081a,
+ 0x89e: 0x0902, 0x89f: 0x0a9a, 0x8a0: 0x0cd6, 0x8a1: 0x0d22, 0x8a2: 0x0d62, 0x8a3: 0x0df6,
+ 0x8a4: 0x0f4a, 0x8a5: 0x0fbe, 0x8a6: 0x115a, 0x8a7: 0x12fa, 0x8a8: 0x1306, 0x8a9: 0x145a,
+ 0x8aa: 0x14da, 0x8ab: 0x0886, 0x8ac: 0x0e4e, 0x8ad: 0x0906, 0x8ae: 0x0eca, 0x8af: 0x0f6e,
+ 0x8b0: 0x128a, 0x8b1: 0x14c2, 0x8b2: 0x15ae, 0x8b3: 0x15d6, 0x8b4: 0x0d3a, 0x8b5: 0x0e2a,
+ 0x8b6: 0x11c6, 0x8b7: 0x10ba, 0x8b8: 0x10c6, 0x8b9: 0x10ea, 0x8ba: 0x0f1a, 0x8bb: 0x0ea2,
+ 0x8bc: 0x1366, 0x8bd: 0x0736, 0x8be: 0x122e, 0x8bf: 0x081e,
+ // Block 0x23, offset 0x8c0
+ 0x8c0: 0x080e, 0x8c1: 0x0b0e, 0x8c2: 0x0c2e, 0x8c3: 0x10f6, 0x8c4: 0x0a56, 0x8c5: 0x0e06,
+ 0x8c6: 0x0cf2, 0x8c7: 0x13ea, 0x8c8: 0x12ea, 0x8c9: 0x14ae, 0x8ca: 0x1326, 0x8cb: 0x0b2a,
+ 0x8cc: 0x078a, 0x8cd: 0x095e, 0x8d0: 0x09b2,
+ 0x8d2: 0x0ce2, 0x8d5: 0x07fa, 0x8d6: 0x0f22, 0x8d7: 0x0fe6,
+ 0x8d8: 0x104a, 0x8d9: 0x1066, 0x8da: 0x106a, 0x8db: 0x107e, 0x8dc: 0x14fe, 0x8dd: 0x10ee,
+ 0x8de: 0x1172, 0x8e0: 0x1292, 0x8e2: 0x1356,
+ 0x8e5: 0x140a, 0x8e6: 0x1436,
+ 0x8ea: 0x1552, 0x8eb: 0x1556, 0x8ec: 0x155a, 0x8ed: 0x15be, 0x8ee: 0x142e, 0x8ef: 0x14ca,
+ 0x8f0: 0x075a, 0x8f1: 0x077e, 0x8f2: 0x0792, 0x8f3: 0x084e, 0x8f4: 0x085a, 0x8f5: 0x089a,
+ 0x8f6: 0x094e, 0x8f7: 0x096a, 0x8f8: 0x0972, 0x8f9: 0x09ae, 0x8fa: 0x09ba, 0x8fb: 0x0a96,
+ 0x8fc: 0x0a9e, 0x8fd: 0x0ba6, 0x8fe: 0x0bce, 0x8ff: 0x0bd6,
+ // Block 0x24, offset 0x900
+ 0x900: 0x0bee, 0x901: 0x0c9a, 0x902: 0x0cca, 0x903: 0x0cea, 0x904: 0x0d5a, 0x905: 0x0e1e,
+ 0x906: 0x0e3a, 0x907: 0x0e6a, 0x908: 0x0ebe, 0x909: 0x0ede, 0x90a: 0x0f52, 0x90b: 0x1032,
+ 0x90c: 0x104e, 0x90d: 0x1056, 0x90e: 0x1052, 0x90f: 0x105a, 0x910: 0x105e, 0x911: 0x1062,
+ 0x912: 0x1076, 0x913: 0x107a, 0x914: 0x109e, 0x915: 0x10b2, 0x916: 0x10ce, 0x917: 0x1132,
+ 0x918: 0x113a, 0x919: 0x1142, 0x91a: 0x1156, 0x91b: 0x117e, 0x91c: 0x11ce, 0x91d: 0x1202,
+ 0x91e: 0x1202, 0x91f: 0x126a, 0x920: 0x1312, 0x921: 0x132a, 0x922: 0x135e, 0x923: 0x1362,
+ 0x924: 0x13a6, 0x925: 0x13aa, 0x926: 0x1402, 0x927: 0x140a, 0x928: 0x14de, 0x929: 0x1522,
+ 0x92a: 0x153a, 0x92b: 0x0b9e, 0x92c: 0x1721, 0x92d: 0x11e6,
+ 0x930: 0x06e2, 0x931: 0x07e6, 0x932: 0x07a6, 0x933: 0x074e, 0x934: 0x078e, 0x935: 0x07ba,
+ 0x936: 0x084a, 0x937: 0x0866, 0x938: 0x094e, 0x939: 0x093a, 0x93a: 0x094a, 0x93b: 0x0966,
+ 0x93c: 0x09b2, 0x93d: 0x09c2, 0x93e: 0x0a06, 0x93f: 0x0a12,
+ // Block 0x25, offset 0x940
+ 0x940: 0x0a2e, 0x941: 0x0a3e, 0x942: 0x0b26, 0x943: 0x0b2e, 0x944: 0x0b5e, 0x945: 0x0b7e,
+ 0x946: 0x0bae, 0x947: 0x0bc6, 0x948: 0x0bb6, 0x949: 0x0bd6, 0x94a: 0x0bca, 0x94b: 0x0bee,
+ 0x94c: 0x0c0a, 0x94d: 0x0c62, 0x94e: 0x0c6e, 0x94f: 0x0c76, 0x950: 0x0c9e, 0x951: 0x0ce2,
+ 0x952: 0x0d12, 0x953: 0x0d16, 0x954: 0x0d2a, 0x955: 0x0daa, 0x956: 0x0dba, 0x957: 0x0e12,
+ 0x958: 0x0e5e, 0x959: 0x0e56, 0x95a: 0x0e6a, 0x95b: 0x0e86, 0x95c: 0x0ebe, 0x95d: 0x1016,
+ 0x95e: 0x0ee2, 0x95f: 0x0f16, 0x960: 0x0f22, 0x961: 0x0f62, 0x962: 0x0f7e, 0x963: 0x0fa2,
+ 0x964: 0x0fc6, 0x965: 0x0fca, 0x966: 0x0fe6, 0x967: 0x0fea, 0x968: 0x0ffa, 0x969: 0x100e,
+ 0x96a: 0x100a, 0x96b: 0x103a, 0x96c: 0x10b6, 0x96d: 0x10ce, 0x96e: 0x10e6, 0x96f: 0x111e,
+ 0x970: 0x1132, 0x971: 0x114e, 0x972: 0x117e, 0x973: 0x1232, 0x974: 0x125a, 0x975: 0x12ce,
+ 0x976: 0x1316, 0x977: 0x1322, 0x978: 0x132a, 0x979: 0x1342, 0x97a: 0x1356, 0x97b: 0x1346,
+ 0x97c: 0x135e, 0x97d: 0x135a, 0x97e: 0x1352, 0x97f: 0x1362,
+ // Block 0x26, offset 0x980
+ 0x980: 0x136e, 0x981: 0x13aa, 0x982: 0x13e6, 0x983: 0x1416, 0x984: 0x144e, 0x985: 0x146e,
+ 0x986: 0x14ba, 0x987: 0x14de, 0x988: 0x14fe, 0x989: 0x1512, 0x98a: 0x1522, 0x98b: 0x152e,
+ 0x98c: 0x153a, 0x98d: 0x158e, 0x98e: 0x162e, 0x98f: 0x16b8, 0x990: 0x16b3, 0x991: 0x16e5,
+ 0x992: 0x060a, 0x993: 0x0632, 0x994: 0x0636, 0x995: 0x1767, 0x996: 0x1794, 0x997: 0x180c,
+ 0x998: 0x161a, 0x999: 0x162a,
+ // Block 0x27, offset 0x9c0
+ 0x9c0: 0x06fe, 0x9c1: 0x06f6, 0x9c2: 0x0706, 0x9c3: 0x164a, 0x9c4: 0x074a, 0x9c5: 0x075a,
+ 0x9c6: 0x075e, 0x9c7: 0x0766, 0x9c8: 0x076e, 0x9c9: 0x0772, 0x9ca: 0x077e, 0x9cb: 0x0776,
+ 0x9cc: 0x05b6, 0x9cd: 0x165e, 0x9ce: 0x0792, 0x9cf: 0x0796, 0x9d0: 0x079a, 0x9d1: 0x07b6,
+ 0x9d2: 0x164f, 0x9d3: 0x05ba, 0x9d4: 0x07a2, 0x9d5: 0x07c2, 0x9d6: 0x1659, 0x9d7: 0x07d2,
+ 0x9d8: 0x07da, 0x9d9: 0x073a, 0x9da: 0x07e2, 0x9db: 0x07e6, 0x9dc: 0x1834, 0x9dd: 0x0802,
+ 0x9de: 0x080a, 0x9df: 0x05c2, 0x9e0: 0x0822, 0x9e1: 0x0826, 0x9e2: 0x082e, 0x9e3: 0x0832,
+ 0x9e4: 0x05c6, 0x9e5: 0x084a, 0x9e6: 0x084e, 0x9e7: 0x085a, 0x9e8: 0x0866, 0x9e9: 0x086a,
+ 0x9ea: 0x086e, 0x9eb: 0x0876, 0x9ec: 0x0896, 0x9ed: 0x089a, 0x9ee: 0x08a2, 0x9ef: 0x08b2,
+ 0x9f0: 0x08ba, 0x9f1: 0x08be, 0x9f2: 0x08be, 0x9f3: 0x08be, 0x9f4: 0x166d, 0x9f5: 0x0e96,
+ 0x9f6: 0x08d2, 0x9f7: 0x08da, 0x9f8: 0x1672, 0x9f9: 0x08e6, 0x9fa: 0x08ee, 0x9fb: 0x08f6,
+ 0x9fc: 0x091e, 0x9fd: 0x090a, 0x9fe: 0x0916, 0x9ff: 0x091a,
+ // Block 0x28, offset 0xa00
+ 0xa00: 0x0922, 0xa01: 0x092a, 0xa02: 0x092e, 0xa03: 0x0936, 0xa04: 0x093e, 0xa05: 0x0942,
+ 0xa06: 0x0942, 0xa07: 0x094a, 0xa08: 0x0952, 0xa09: 0x0956, 0xa0a: 0x0962, 0xa0b: 0x0986,
+ 0xa0c: 0x096a, 0xa0d: 0x098a, 0xa0e: 0x096e, 0xa0f: 0x0976, 0xa10: 0x080e, 0xa11: 0x09d2,
+ 0xa12: 0x099a, 0xa13: 0x099e, 0xa14: 0x09a2, 0xa15: 0x0996, 0xa16: 0x09aa, 0xa17: 0x09a6,
+ 0xa18: 0x09be, 0xa19: 0x1677, 0xa1a: 0x09da, 0xa1b: 0x09de, 0xa1c: 0x09e6, 0xa1d: 0x09f2,
+ 0xa1e: 0x09fa, 0xa1f: 0x0a16, 0xa20: 0x167c, 0xa21: 0x1681, 0xa22: 0x0a22, 0xa23: 0x0a26,
+ 0xa24: 0x0a2a, 0xa25: 0x0a1e, 0xa26: 0x0a32, 0xa27: 0x05ca, 0xa28: 0x05ce, 0xa29: 0x0a3a,
+ 0xa2a: 0x0a42, 0xa2b: 0x0a42, 0xa2c: 0x1686, 0xa2d: 0x0a5e, 0xa2e: 0x0a62, 0xa2f: 0x0a66,
+ 0xa30: 0x0a6e, 0xa31: 0x168b, 0xa32: 0x0a76, 0xa33: 0x0a7a, 0xa34: 0x0b52, 0xa35: 0x0a82,
+ 0xa36: 0x05d2, 0xa37: 0x0a8e, 0xa38: 0x0a9e, 0xa39: 0x0aaa, 0xa3a: 0x0aa6, 0xa3b: 0x1695,
+ 0xa3c: 0x0ab2, 0xa3d: 0x169a, 0xa3e: 0x0abe, 0xa3f: 0x0aba,
+ // Block 0x29, offset 0xa40
+ 0xa40: 0x0ac2, 0xa41: 0x0ad2, 0xa42: 0x0ad6, 0xa43: 0x05d6, 0xa44: 0x0ae6, 0xa45: 0x0aee,
+ 0xa46: 0x0af2, 0xa47: 0x0af6, 0xa48: 0x05da, 0xa49: 0x169f, 0xa4a: 0x05de, 0xa4b: 0x0b12,
+ 0xa4c: 0x0b16, 0xa4d: 0x0b1a, 0xa4e: 0x0b22, 0xa4f: 0x1866, 0xa50: 0x0b3a, 0xa51: 0x16a9,
+ 0xa52: 0x16a9, 0xa53: 0x11da, 0xa54: 0x0b4a, 0xa55: 0x0b4a, 0xa56: 0x05e2, 0xa57: 0x16cc,
+ 0xa58: 0x179e, 0xa59: 0x0b5a, 0xa5a: 0x0b62, 0xa5b: 0x05e6, 0xa5c: 0x0b76, 0xa5d: 0x0b86,
+ 0xa5e: 0x0b8a, 0xa5f: 0x0b92, 0xa60: 0x0ba2, 0xa61: 0x05ee, 0xa62: 0x05ea, 0xa63: 0x0ba6,
+ 0xa64: 0x16ae, 0xa65: 0x0baa, 0xa66: 0x0bbe, 0xa67: 0x0bc2, 0xa68: 0x0bc6, 0xa69: 0x0bc2,
+ 0xa6a: 0x0bd2, 0xa6b: 0x0bd6, 0xa6c: 0x0be6, 0xa6d: 0x0bde, 0xa6e: 0x0be2, 0xa6f: 0x0bea,
+ 0xa70: 0x0bee, 0xa71: 0x0bf2, 0xa72: 0x0bfe, 0xa73: 0x0c02, 0xa74: 0x0c1a, 0xa75: 0x0c22,
+ 0xa76: 0x0c32, 0xa77: 0x0c46, 0xa78: 0x16bd, 0xa79: 0x0c42, 0xa7a: 0x0c36, 0xa7b: 0x0c4e,
+ 0xa7c: 0x0c56, 0xa7d: 0x0c6a, 0xa7e: 0x16c2, 0xa7f: 0x0c72,
+ // Block 0x2a, offset 0xa80
+ 0xa80: 0x0c66, 0xa81: 0x0c5e, 0xa82: 0x05f2, 0xa83: 0x0c7a, 0xa84: 0x0c82, 0xa85: 0x0c8a,
+ 0xa86: 0x0c7e, 0xa87: 0x05f6, 0xa88: 0x0c9a, 0xa89: 0x0ca2, 0xa8a: 0x16c7, 0xa8b: 0x0cce,
+ 0xa8c: 0x0d02, 0xa8d: 0x0cde, 0xa8e: 0x0602, 0xa8f: 0x0cea, 0xa90: 0x05fe, 0xa91: 0x05fa,
+ 0xa92: 0x07c6, 0xa93: 0x07ca, 0xa94: 0x0d06, 0xa95: 0x0cee, 0xa96: 0x11ae, 0xa97: 0x0666,
+ 0xa98: 0x0d12, 0xa99: 0x0d16, 0xa9a: 0x0d1a, 0xa9b: 0x0d2e, 0xa9c: 0x0d26, 0xa9d: 0x16e0,
+ 0xa9e: 0x0606, 0xa9f: 0x0d42, 0xaa0: 0x0d36, 0xaa1: 0x0d52, 0xaa2: 0x0d5a, 0xaa3: 0x16ea,
+ 0xaa4: 0x0d5e, 0xaa5: 0x0d4a, 0xaa6: 0x0d66, 0xaa7: 0x060a, 0xaa8: 0x0d6a, 0xaa9: 0x0d6e,
+ 0xaaa: 0x0d72, 0xaab: 0x0d7e, 0xaac: 0x16ef, 0xaad: 0x0d86, 0xaae: 0x060e, 0xaaf: 0x0d92,
+ 0xab0: 0x16f4, 0xab1: 0x0d96, 0xab2: 0x0612, 0xab3: 0x0da2, 0xab4: 0x0dae, 0xab5: 0x0dba,
+ 0xab6: 0x0dbe, 0xab7: 0x16f9, 0xab8: 0x1690, 0xab9: 0x16fe, 0xaba: 0x0dde, 0xabb: 0x1703,
+ 0xabc: 0x0dea, 0xabd: 0x0df2, 0xabe: 0x0de2, 0xabf: 0x0dfe,
+ // Block 0x2b, offset 0xac0
+ 0xac0: 0x0e0e, 0xac1: 0x0e1e, 0xac2: 0x0e12, 0xac3: 0x0e16, 0xac4: 0x0e22, 0xac5: 0x0e26,
+ 0xac6: 0x1708, 0xac7: 0x0e0a, 0xac8: 0x0e3e, 0xac9: 0x0e42, 0xaca: 0x0616, 0xacb: 0x0e56,
+ 0xacc: 0x0e52, 0xacd: 0x170d, 0xace: 0x0e36, 0xacf: 0x0e72, 0xad0: 0x1712, 0xad1: 0x1717,
+ 0xad2: 0x0e76, 0xad3: 0x0e8a, 0xad4: 0x0e86, 0xad5: 0x0e82, 0xad6: 0x061a, 0xad7: 0x0e8e,
+ 0xad8: 0x0e9e, 0xad9: 0x0e9a, 0xada: 0x0ea6, 0xadb: 0x1654, 0xadc: 0x0eb6, 0xadd: 0x171c,
+ 0xade: 0x0ec2, 0xadf: 0x1726, 0xae0: 0x0ed6, 0xae1: 0x0ee2, 0xae2: 0x0ef6, 0xae3: 0x172b,
+ 0xae4: 0x0f0a, 0xae5: 0x0f0e, 0xae6: 0x1730, 0xae7: 0x1735, 0xae8: 0x0f2a, 0xae9: 0x0f3a,
+ 0xaea: 0x061e, 0xaeb: 0x0f3e, 0xaec: 0x0622, 0xaed: 0x0622, 0xaee: 0x0f56, 0xaef: 0x0f5a,
+ 0xaf0: 0x0f62, 0xaf1: 0x0f66, 0xaf2: 0x0f72, 0xaf3: 0x0626, 0xaf4: 0x0f8a, 0xaf5: 0x173a,
+ 0xaf6: 0x0fa6, 0xaf7: 0x173f, 0xaf8: 0x0fb2, 0xaf9: 0x16a4, 0xafa: 0x0fc2, 0xafb: 0x1744,
+ 0xafc: 0x1749, 0xafd: 0x174e, 0xafe: 0x062a, 0xaff: 0x062e,
+ // Block 0x2c, offset 0xb00
+ 0xb00: 0x0ffa, 0xb01: 0x1758, 0xb02: 0x1753, 0xb03: 0x175d, 0xb04: 0x1762, 0xb05: 0x1002,
+ 0xb06: 0x1006, 0xb07: 0x1006, 0xb08: 0x100e, 0xb09: 0x0636, 0xb0a: 0x1012, 0xb0b: 0x063a,
+ 0xb0c: 0x063e, 0xb0d: 0x176c, 0xb0e: 0x1026, 0xb0f: 0x102e, 0xb10: 0x103a, 0xb11: 0x0642,
+ 0xb12: 0x1771, 0xb13: 0x105e, 0xb14: 0x1776, 0xb15: 0x177b, 0xb16: 0x107e, 0xb17: 0x1096,
+ 0xb18: 0x0646, 0xb19: 0x109e, 0xb1a: 0x10a2, 0xb1b: 0x10a6, 0xb1c: 0x1780, 0xb1d: 0x1785,
+ 0xb1e: 0x1785, 0xb1f: 0x10be, 0xb20: 0x064a, 0xb21: 0x178a, 0xb22: 0x10d2, 0xb23: 0x10d6,
+ 0xb24: 0x064e, 0xb25: 0x178f, 0xb26: 0x10f2, 0xb27: 0x0652, 0xb28: 0x1102, 0xb29: 0x10fa,
+ 0xb2a: 0x110a, 0xb2b: 0x1799, 0xb2c: 0x1122, 0xb2d: 0x0656, 0xb2e: 0x112e, 0xb2f: 0x1136,
+ 0xb30: 0x1146, 0xb31: 0x065a, 0xb32: 0x17a3, 0xb33: 0x17a8, 0xb34: 0x065e, 0xb35: 0x17ad,
+ 0xb36: 0x115e, 0xb37: 0x17b2, 0xb38: 0x116a, 0xb39: 0x1176, 0xb3a: 0x117e, 0xb3b: 0x17b7,
+ 0xb3c: 0x17bc, 0xb3d: 0x1192, 0xb3e: 0x17c1, 0xb3f: 0x119a,
+ // Block 0x2d, offset 0xb40
+ 0xb40: 0x16d1, 0xb41: 0x0662, 0xb42: 0x11b2, 0xb43: 0x11b6, 0xb44: 0x066a, 0xb45: 0x11ba,
+ 0xb46: 0x0a36, 0xb47: 0x17c6, 0xb48: 0x17cb, 0xb49: 0x16d6, 0xb4a: 0x16db, 0xb4b: 0x11da,
+ 0xb4c: 0x11de, 0xb4d: 0x13f6, 0xb4e: 0x066e, 0xb4f: 0x120a, 0xb50: 0x1206, 0xb51: 0x120e,
+ 0xb52: 0x0842, 0xb53: 0x1212, 0xb54: 0x1216, 0xb55: 0x121a, 0xb56: 0x1222, 0xb57: 0x17d0,
+ 0xb58: 0x121e, 0xb59: 0x1226, 0xb5a: 0x123a, 0xb5b: 0x123e, 0xb5c: 0x122a, 0xb5d: 0x1242,
+ 0xb5e: 0x1256, 0xb5f: 0x126a, 0xb60: 0x1236, 0xb61: 0x124a, 0xb62: 0x124e, 0xb63: 0x1252,
+ 0xb64: 0x17d5, 0xb65: 0x17df, 0xb66: 0x17da, 0xb67: 0x0672, 0xb68: 0x1272, 0xb69: 0x1276,
+ 0xb6a: 0x127e, 0xb6b: 0x17f3, 0xb6c: 0x1282, 0xb6d: 0x17e4, 0xb6e: 0x0676, 0xb6f: 0x067a,
+ 0xb70: 0x17e9, 0xb71: 0x17ee, 0xb72: 0x067e, 0xb73: 0x12a2, 0xb74: 0x12a6, 0xb75: 0x12aa,
+ 0xb76: 0x12ae, 0xb77: 0x12ba, 0xb78: 0x12b6, 0xb79: 0x12c2, 0xb7a: 0x12be, 0xb7b: 0x12ce,
+ 0xb7c: 0x12c6, 0xb7d: 0x12ca, 0xb7e: 0x12d2, 0xb7f: 0x0682,
+ // Block 0x2e, offset 0xb80
+ 0xb80: 0x12da, 0xb81: 0x12de, 0xb82: 0x0686, 0xb83: 0x12ee, 0xb84: 0x12f2, 0xb85: 0x17f8,
+ 0xb86: 0x12fe, 0xb87: 0x1302, 0xb88: 0x068a, 0xb89: 0x130e, 0xb8a: 0x05be, 0xb8b: 0x17fd,
+ 0xb8c: 0x1802, 0xb8d: 0x068e, 0xb8e: 0x0692, 0xb8f: 0x133a, 0xb90: 0x1352, 0xb91: 0x136e,
+ 0xb92: 0x137e, 0xb93: 0x1807, 0xb94: 0x1392, 0xb95: 0x1396, 0xb96: 0x13ae, 0xb97: 0x13ba,
+ 0xb98: 0x1811, 0xb99: 0x1663, 0xb9a: 0x13c6, 0xb9b: 0x13c2, 0xb9c: 0x13ce, 0xb9d: 0x1668,
+ 0xb9e: 0x13da, 0xb9f: 0x13e6, 0xba0: 0x1816, 0xba1: 0x181b, 0xba2: 0x1426, 0xba3: 0x1432,
+ 0xba4: 0x143a, 0xba5: 0x1820, 0xba6: 0x143e, 0xba7: 0x146a, 0xba8: 0x1476, 0xba9: 0x147a,
+ 0xbaa: 0x1472, 0xbab: 0x1486, 0xbac: 0x148a, 0xbad: 0x1825, 0xbae: 0x1496, 0xbaf: 0x0696,
+ 0xbb0: 0x149e, 0xbb1: 0x182a, 0xbb2: 0x069a, 0xbb3: 0x14d6, 0xbb4: 0x0ac6, 0xbb5: 0x14ee,
+ 0xbb6: 0x182f, 0xbb7: 0x1839, 0xbb8: 0x069e, 0xbb9: 0x06a2, 0xbba: 0x1516, 0xbbb: 0x183e,
+ 0xbbc: 0x06a6, 0xbbd: 0x1843, 0xbbe: 0x152e, 0xbbf: 0x152e,
+ // Block 0x2f, offset 0xbc0
+ 0xbc0: 0x1536, 0xbc1: 0x1848, 0xbc2: 0x154e, 0xbc3: 0x06aa, 0xbc4: 0x155e, 0xbc5: 0x156a,
+ 0xbc6: 0x1572, 0xbc7: 0x157a, 0xbc8: 0x06ae, 0xbc9: 0x184d, 0xbca: 0x158e, 0xbcb: 0x15aa,
+ 0xbcc: 0x15b6, 0xbcd: 0x06b2, 0xbce: 0x06b6, 0xbcf: 0x15ba, 0xbd0: 0x1852, 0xbd1: 0x06ba,
+ 0xbd2: 0x1857, 0xbd3: 0x185c, 0xbd4: 0x1861, 0xbd5: 0x15de, 0xbd6: 0x06be, 0xbd7: 0x15f2,
+ 0xbd8: 0x15fa, 0xbd9: 0x15fe, 0xbda: 0x1606, 0xbdb: 0x160e, 0xbdc: 0x1616, 0xbdd: 0x186b,
+}
+
+// nfcIndex: 22 blocks, 1408 entries, 1408 bytes
+// Block 0 is the zero block.
+var nfcIndex = [1408]uint8{
+ // Block 0x0, offset 0x0
+ // Block 0x1, offset 0x40
+ // Block 0x2, offset 0x80
+ // Block 0x3, offset 0xc0
+ 0xc2: 0x2e, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x2f, 0xc7: 0x04,
+ 0xc8: 0x05, 0xca: 0x30, 0xcb: 0x31, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x32,
+ 0xd0: 0x09, 0xd1: 0x33, 0xd2: 0x34, 0xd3: 0x0a, 0xd6: 0x0b, 0xd7: 0x35,
+ 0xd8: 0x36, 0xd9: 0x0c, 0xdb: 0x37, 0xdc: 0x38, 0xdd: 0x39, 0xdf: 0x3a,
+ 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05,
+ 0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a,
+ 0xf0: 0x13,
+ // Block 0x4, offset 0x100
+ 0x120: 0x3b, 0x121: 0x3c, 0x123: 0x0d, 0x124: 0x3d, 0x125: 0x3e, 0x126: 0x3f, 0x127: 0x40,
+ 0x128: 0x41, 0x129: 0x42, 0x12a: 0x43, 0x12b: 0x44, 0x12c: 0x3f, 0x12d: 0x45, 0x12e: 0x46, 0x12f: 0x47,
+ 0x131: 0x48, 0x132: 0x49, 0x133: 0x4a, 0x134: 0x4b, 0x135: 0x4c, 0x137: 0x4d,
+ 0x138: 0x4e, 0x139: 0x4f, 0x13a: 0x50, 0x13b: 0x51, 0x13c: 0x52, 0x13d: 0x53, 0x13e: 0x54, 0x13f: 0x55,
+ // Block 0x5, offset 0x140
+ 0x140: 0x56, 0x142: 0x57, 0x144: 0x58, 0x145: 0x59, 0x146: 0x5a, 0x147: 0x5b,
+ 0x14d: 0x5c,
+ 0x15c: 0x5d, 0x15f: 0x5e,
+ 0x162: 0x5f, 0x164: 0x60,
+ 0x168: 0x61, 0x169: 0x62, 0x16a: 0x63, 0x16b: 0x64, 0x16c: 0x0e, 0x16d: 0x65, 0x16e: 0x66, 0x16f: 0x67,
+ 0x170: 0x68, 0x173: 0x69, 0x177: 0x0f,
+ 0x178: 0x10, 0x179: 0x11, 0x17a: 0x12, 0x17b: 0x13, 0x17c: 0x14, 0x17d: 0x15, 0x17e: 0x16, 0x17f: 0x17,
+ // Block 0x6, offset 0x180
+ 0x180: 0x6a, 0x183: 0x6b, 0x184: 0x6c, 0x186: 0x6d, 0x187: 0x6e,
+ 0x188: 0x6f, 0x189: 0x18, 0x18a: 0x19, 0x18b: 0x70, 0x18c: 0x71,
+ 0x1ab: 0x72,
+ 0x1b3: 0x73, 0x1b5: 0x74, 0x1b7: 0x75,
+ // Block 0x7, offset 0x1c0
+ 0x1c0: 0x76, 0x1c1: 0x1a, 0x1c2: 0x1b, 0x1c3: 0x1c, 0x1c4: 0x77, 0x1c5: 0x78,
+ 0x1c9: 0x79, 0x1cc: 0x7a, 0x1cd: 0x7b,
+ // Block 0x8, offset 0x200
+ 0x219: 0x7c, 0x21a: 0x7d, 0x21b: 0x7e,
+ 0x220: 0x7f, 0x223: 0x80, 0x224: 0x81, 0x225: 0x82, 0x226: 0x83, 0x227: 0x84,
+ 0x22a: 0x85, 0x22b: 0x86, 0x22f: 0x87,
+ 0x230: 0x88, 0x231: 0x89, 0x232: 0x8a, 0x233: 0x8b, 0x234: 0x8c, 0x235: 0x8d, 0x236: 0x8e, 0x237: 0x88,
+ 0x238: 0x89, 0x239: 0x8a, 0x23a: 0x8b, 0x23b: 0x8c, 0x23c: 0x8d, 0x23d: 0x8e, 0x23e: 0x88, 0x23f: 0x89,
+ // Block 0x9, offset 0x240
+ 0x240: 0x8a, 0x241: 0x8b, 0x242: 0x8c, 0x243: 0x8d, 0x244: 0x8e, 0x245: 0x88, 0x246: 0x89, 0x247: 0x8a,
+ 0x248: 0x8b, 0x249: 0x8c, 0x24a: 0x8d, 0x24b: 0x8e, 0x24c: 0x88, 0x24d: 0x89, 0x24e: 0x8a, 0x24f: 0x8b,
+ 0x250: 0x8c, 0x251: 0x8d, 0x252: 0x8e, 0x253: 0x88, 0x254: 0x89, 0x255: 0x8a, 0x256: 0x8b, 0x257: 0x8c,
+ 0x258: 0x8d, 0x259: 0x8e, 0x25a: 0x88, 0x25b: 0x89, 0x25c: 0x8a, 0x25d: 0x8b, 0x25e: 0x8c, 0x25f: 0x8d,
+ 0x260: 0x8e, 0x261: 0x88, 0x262: 0x89, 0x263: 0x8a, 0x264: 0x8b, 0x265: 0x8c, 0x266: 0x8d, 0x267: 0x8e,
+ 0x268: 0x88, 0x269: 0x89, 0x26a: 0x8a, 0x26b: 0x8b, 0x26c: 0x8c, 0x26d: 0x8d, 0x26e: 0x8e, 0x26f: 0x88,
+ 0x270: 0x89, 0x271: 0x8a, 0x272: 0x8b, 0x273: 0x8c, 0x274: 0x8d, 0x275: 0x8e, 0x276: 0x88, 0x277: 0x89,
+ 0x278: 0x8a, 0x279: 0x8b, 0x27a: 0x8c, 0x27b: 0x8d, 0x27c: 0x8e, 0x27d: 0x88, 0x27e: 0x89, 0x27f: 0x8a,
+ // Block 0xa, offset 0x280
+ 0x280: 0x8b, 0x281: 0x8c, 0x282: 0x8d, 0x283: 0x8e, 0x284: 0x88, 0x285: 0x89, 0x286: 0x8a, 0x287: 0x8b,
+ 0x288: 0x8c, 0x289: 0x8d, 0x28a: 0x8e, 0x28b: 0x88, 0x28c: 0x89, 0x28d: 0x8a, 0x28e: 0x8b, 0x28f: 0x8c,
+ 0x290: 0x8d, 0x291: 0x8e, 0x292: 0x88, 0x293: 0x89, 0x294: 0x8a, 0x295: 0x8b, 0x296: 0x8c, 0x297: 0x8d,
+ 0x298: 0x8e, 0x299: 0x88, 0x29a: 0x89, 0x29b: 0x8a, 0x29c: 0x8b, 0x29d: 0x8c, 0x29e: 0x8d, 0x29f: 0x8e,
+ 0x2a0: 0x88, 0x2a1: 0x89, 0x2a2: 0x8a, 0x2a3: 0x8b, 0x2a4: 0x8c, 0x2a5: 0x8d, 0x2a6: 0x8e, 0x2a7: 0x88,
+ 0x2a8: 0x89, 0x2a9: 0x8a, 0x2aa: 0x8b, 0x2ab: 0x8c, 0x2ac: 0x8d, 0x2ad: 0x8e, 0x2ae: 0x88, 0x2af: 0x89,
+ 0x2b0: 0x8a, 0x2b1: 0x8b, 0x2b2: 0x8c, 0x2b3: 0x8d, 0x2b4: 0x8e, 0x2b5: 0x88, 0x2b6: 0x89, 0x2b7: 0x8a,
+ 0x2b8: 0x8b, 0x2b9: 0x8c, 0x2ba: 0x8d, 0x2bb: 0x8e, 0x2bc: 0x88, 0x2bd: 0x89, 0x2be: 0x8a, 0x2bf: 0x8b,
+ // Block 0xb, offset 0x2c0
+ 0x2c0: 0x8c, 0x2c1: 0x8d, 0x2c2: 0x8e, 0x2c3: 0x88, 0x2c4: 0x89, 0x2c5: 0x8a, 0x2c6: 0x8b, 0x2c7: 0x8c,
+ 0x2c8: 0x8d, 0x2c9: 0x8e, 0x2ca: 0x88, 0x2cb: 0x89, 0x2cc: 0x8a, 0x2cd: 0x8b, 0x2ce: 0x8c, 0x2cf: 0x8d,
+ 0x2d0: 0x8e, 0x2d1: 0x88, 0x2d2: 0x89, 0x2d3: 0x8a, 0x2d4: 0x8b, 0x2d5: 0x8c, 0x2d6: 0x8d, 0x2d7: 0x8e,
+ 0x2d8: 0x88, 0x2d9: 0x89, 0x2da: 0x8a, 0x2db: 0x8b, 0x2dc: 0x8c, 0x2dd: 0x8d, 0x2de: 0x8f,
+ // Block 0xc, offset 0x300
+ 0x324: 0x1d, 0x325: 0x1e, 0x326: 0x1f, 0x327: 0x20,
+ 0x328: 0x21, 0x329: 0x22, 0x32a: 0x23, 0x32b: 0x24, 0x32c: 0x90, 0x32d: 0x91, 0x32e: 0x92,
+ 0x331: 0x93, 0x332: 0x94, 0x333: 0x95, 0x334: 0x96,
+ 0x338: 0x97, 0x339: 0x98, 0x33a: 0x99, 0x33b: 0x9a, 0x33e: 0x9b, 0x33f: 0x9c,
+ // Block 0xd, offset 0x340
+ 0x347: 0x9d,
+ 0x34b: 0x9e, 0x34d: 0x9f,
+ 0x368: 0xa0, 0x36b: 0xa1,
+ 0x374: 0xa2,
+ 0x37a: 0xa3, 0x37d: 0xa4,
+ // Block 0xe, offset 0x380
+ 0x381: 0xa5, 0x382: 0xa6, 0x384: 0xa7, 0x385: 0x83, 0x387: 0xa8,
+ 0x388: 0xa9, 0x38b: 0xaa, 0x38c: 0xab, 0x38d: 0xac,
+ 0x391: 0xad, 0x392: 0xae, 0x393: 0xaf, 0x396: 0xb0, 0x397: 0xb1,
+ 0x398: 0x74, 0x39a: 0xb2, 0x39c: 0xb3,
+ 0x3a0: 0xb4, 0x3a4: 0xb5, 0x3a5: 0xb6, 0x3a7: 0xb7,
+ 0x3a8: 0xb8, 0x3a9: 0xb9, 0x3aa: 0xba,
+ 0x3b0: 0x74, 0x3b5: 0xbb, 0x3b6: 0xbc,
+ // Block 0xf, offset 0x3c0
+ 0x3eb: 0xbd, 0x3ec: 0xbe,
+ 0x3ff: 0xbf,
+ // Block 0x10, offset 0x400
+ 0x432: 0xc0,
+ // Block 0x11, offset 0x440
+ 0x445: 0xc1, 0x446: 0xc2, 0x447: 0xc3,
+ 0x449: 0xc4,
+ // Block 0x12, offset 0x480
+ 0x480: 0xc5, 0x484: 0xbe,
+ 0x48b: 0xc6,
+ 0x4a3: 0xc7, 0x4a5: 0xc8,
+ // Block 0x13, offset 0x4c0
+ 0x4c8: 0xc9,
+ // Block 0x14, offset 0x500
+ 0x520: 0x25, 0x521: 0x26, 0x522: 0x27, 0x523: 0x28, 0x524: 0x29, 0x525: 0x2a, 0x526: 0x2b, 0x527: 0x2c,
+ 0x528: 0x2d,
+ // Block 0x15, offset 0x540
+ 0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d,
+ 0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11,
+ 0x56f: 0x12,
+}
+
+// nfcSparseOffset: 156 entries, 312 bytes
+var nfcSparseOffset = []uint16{0x0, 0x5, 0x9, 0xb, 0xd, 0x18, 0x28, 0x2a, 0x2f, 0x3a, 0x49, 0x56, 0x5e, 0x63, 0x68, 0x6a, 0x72, 0x79, 0x7c, 0x84, 0x88, 0x8c, 0x8e, 0x90, 0x99, 0x9d, 0xa4, 0xa9, 0xac, 0xb6, 0xb9, 0xc0, 0xc8, 0xcb, 0xcd, 0xd0, 0xd2, 0xd7, 0xe8, 0xf4, 0xf6, 0xfc, 0xfe, 0x100, 0x102, 0x104, 0x106, 0x108, 0x10b, 0x10e, 0x110, 0x113, 0x116, 0x11a, 0x120, 0x122, 0x12b, 0x12d, 0x130, 0x132, 0x13d, 0x141, 0x14f, 0x152, 0x158, 0x15e, 0x169, 0x16d, 0x16f, 0x171, 0x173, 0x175, 0x177, 0x17d, 0x181, 0x183, 0x185, 0x18d, 0x191, 0x194, 0x196, 0x198, 0x19b, 0x19e, 0x1a0, 0x1a2, 0x1a4, 0x1a6, 0x1ac, 0x1af, 0x1b1, 0x1b8, 0x1be, 0x1c4, 0x1cc, 0x1d2, 0x1d8, 0x1de, 0x1e2, 0x1f0, 0x1f9, 0x1fc, 0x1ff, 0x201, 0x204, 0x206, 0x20a, 0x20f, 0x211, 0x213, 0x218, 0x21e, 0x220, 0x222, 0x224, 0x22a, 0x22d, 0x22f, 0x231, 0x237, 0x23a, 0x242, 0x249, 0x24c, 0x24f, 0x251, 0x254, 0x25c, 0x260, 0x267, 0x26a, 0x270, 0x272, 0x275, 0x277, 0x27a, 0x27f, 0x281, 0x283, 0x285, 0x287, 0x289, 0x28c, 0x28e, 0x290, 0x292, 0x294, 0x296, 0x2a3, 0x2ad, 0x2af, 0x2b1, 0x2b7, 0x2b9, 0x2bb, 0x2be}
+
+// nfcSparseValues: 704 entries, 2816 bytes
+var nfcSparseValues = [704]valueRange{
+ // Block 0x0, offset 0x0
+ {value: 0x0000, lo: 0x04},
+ {value: 0xa100, lo: 0xa8, hi: 0xa8},
+ {value: 0x8100, lo: 0xaf, hi: 0xaf},
+ {value: 0x8100, lo: 0xb4, hi: 0xb4},
+ {value: 0x8100, lo: 0xb8, hi: 0xb8},
+ // Block 0x1, offset 0x5
+ {value: 0x0091, lo: 0x03},
+ {value: 0x46f9, lo: 0xa0, hi: 0xa1},
+ {value: 0x472b, lo: 0xaf, hi: 0xb0},
+ {value: 0xa000, lo: 0xb7, hi: 0xb7},
+ // Block 0x2, offset 0x9
+ {value: 0x0000, lo: 0x01},
+ {value: 0xa000, lo: 0x92, hi: 0x92},
+ // Block 0x3, offset 0xb
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8100, lo: 0x98, hi: 0x9d},
+ // Block 0x4, offset 0xd
+ {value: 0x0006, lo: 0x0a},
+ {value: 0xa000, lo: 0x81, hi: 0x81},
+ {value: 0xa000, lo: 0x85, hi: 0x85},
+ {value: 0xa000, lo: 0x89, hi: 0x89},
+ {value: 0x4857, lo: 0x8a, hi: 0x8a},
+ {value: 0x4875, lo: 0x8b, hi: 0x8b},
+ {value: 0x36de, lo: 0x8c, hi: 0x8c},
+ {value: 0x36f6, lo: 0x8d, hi: 0x8d},
+ {value: 0x488d, lo: 0x8e, hi: 0x8e},
+ {value: 0xa000, lo: 0x92, hi: 0x92},
+ {value: 0x3714, lo: 0x93, hi: 0x94},
+ // Block 0x5, offset 0x18
+ {value: 0x0000, lo: 0x0f},
+ {value: 0xa000, lo: 0x83, hi: 0x83},
+ {value: 0xa000, lo: 0x87, hi: 0x87},
+ {value: 0xa000, lo: 0x8b, hi: 0x8b},
+ {value: 0xa000, lo: 0x8d, hi: 0x8d},
+ {value: 0x37bc, lo: 0x90, hi: 0x90},
+ {value: 0x37c8, lo: 0x91, hi: 0x91},
+ {value: 0x37b6, lo: 0x93, hi: 0x93},
+ {value: 0xa000, lo: 0x96, hi: 0x96},
+ {value: 0x382e, lo: 0x97, hi: 0x97},
+ {value: 0x37f8, lo: 0x9c, hi: 0x9c},
+ {value: 0x37e0, lo: 0x9d, hi: 0x9d},
+ {value: 0x380a, lo: 0x9e, hi: 0x9e},
+ {value: 0xa000, lo: 0xb4, hi: 0xb5},
+ {value: 0x3834, lo: 0xb6, hi: 0xb6},
+ {value: 0x383a, lo: 0xb7, hi: 0xb7},
+ // Block 0x6, offset 0x28
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0x83, hi: 0x87},
+ // Block 0x7, offset 0x2a
+ {value: 0x0001, lo: 0x04},
+ {value: 0x8114, lo: 0x81, hi: 0x82},
+ {value: 0x8133, lo: 0x84, hi: 0x84},
+ {value: 0x812e, lo: 0x85, hi: 0x85},
+ {value: 0x810e, lo: 0x87, hi: 0x87},
+ // Block 0x8, offset 0x2f
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x8133, lo: 0x90, hi: 0x97},
+ {value: 0x811a, lo: 0x98, hi: 0x98},
+ {value: 0x811b, lo: 0x99, hi: 0x99},
+ {value: 0x811c, lo: 0x9a, hi: 0x9a},
+ {value: 0x3858, lo: 0xa2, hi: 0xa2},
+ {value: 0x385e, lo: 0xa3, hi: 0xa3},
+ {value: 0x386a, lo: 0xa4, hi: 0xa4},
+ {value: 0x3864, lo: 0xa5, hi: 0xa5},
+ {value: 0x3870, lo: 0xa6, hi: 0xa6},
+ {value: 0xa000, lo: 0xa7, hi: 0xa7},
+ // Block 0x9, offset 0x3a
+ {value: 0x0000, lo: 0x0e},
+ {value: 0x3882, lo: 0x80, hi: 0x80},
+ {value: 0xa000, lo: 0x81, hi: 0x81},
+ {value: 0x3876, lo: 0x82, hi: 0x82},
+ {value: 0xa000, lo: 0x92, hi: 0x92},
+ {value: 0x387c, lo: 0x93, hi: 0x93},
+ {value: 0xa000, lo: 0x95, hi: 0x95},
+ {value: 0x8133, lo: 0x96, hi: 0x9c},
+ {value: 0x8133, lo: 0x9f, hi: 0xa2},
+ {value: 0x812e, lo: 0xa3, hi: 0xa3},
+ {value: 0x8133, lo: 0xa4, hi: 0xa4},
+ {value: 0x8133, lo: 0xa7, hi: 0xa8},
+ {value: 0x812e, lo: 0xaa, hi: 0xaa},
+ {value: 0x8133, lo: 0xab, hi: 0xac},
+ {value: 0x812e, lo: 0xad, hi: 0xad},
+ // Block 0xa, offset 0x49
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x8120, lo: 0x91, hi: 0x91},
+ {value: 0x8133, lo: 0xb0, hi: 0xb0},
+ {value: 0x812e, lo: 0xb1, hi: 0xb1},
+ {value: 0x8133, lo: 0xb2, hi: 0xb3},
+ {value: 0x812e, lo: 0xb4, hi: 0xb4},
+ {value: 0x8133, lo: 0xb5, hi: 0xb6},
+ {value: 0x812e, lo: 0xb7, hi: 0xb9},
+ {value: 0x8133, lo: 0xba, hi: 0xba},
+ {value: 0x812e, lo: 0xbb, hi: 0xbc},
+ {value: 0x8133, lo: 0xbd, hi: 0xbd},
+ {value: 0x812e, lo: 0xbe, hi: 0xbe},
+ {value: 0x8133, lo: 0xbf, hi: 0xbf},
+ // Block 0xb, offset 0x56
+ {value: 0x0005, lo: 0x07},
+ {value: 0x8133, lo: 0x80, hi: 0x80},
+ {value: 0x8133, lo: 0x81, hi: 0x81},
+ {value: 0x812e, lo: 0x82, hi: 0x83},
+ {value: 0x812e, lo: 0x84, hi: 0x85},
+ {value: 0x812e, lo: 0x86, hi: 0x87},
+ {value: 0x812e, lo: 0x88, hi: 0x89},
+ {value: 0x8133, lo: 0x8a, hi: 0x8a},
+ // Block 0xc, offset 0x5e
+ {value: 0x0000, lo: 0x04},
+ {value: 0x8133, lo: 0xab, hi: 0xb1},
+ {value: 0x812e, lo: 0xb2, hi: 0xb2},
+ {value: 0x8133, lo: 0xb3, hi: 0xb3},
+ {value: 0x812e, lo: 0xbd, hi: 0xbd},
+ // Block 0xd, offset 0x63
+ {value: 0x0000, lo: 0x04},
+ {value: 0x8133, lo: 0x96, hi: 0x99},
+ {value: 0x8133, lo: 0x9b, hi: 0xa3},
+ {value: 0x8133, lo: 0xa5, hi: 0xa7},
+ {value: 0x8133, lo: 0xa9, hi: 0xad},
+ // Block 0xe, offset 0x68
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0x99, hi: 0x9b},
+ // Block 0xf, offset 0x6a
+ {value: 0x0000, lo: 0x07},
+ {value: 0xa000, lo: 0xa8, hi: 0xa8},
+ {value: 0x3eef, lo: 0xa9, hi: 0xa9},
+ {value: 0xa000, lo: 0xb0, hi: 0xb0},
+ {value: 0x3ef7, lo: 0xb1, hi: 0xb1},
+ {value: 0xa000, lo: 0xb3, hi: 0xb3},
+ {value: 0x3eff, lo: 0xb4, hi: 0xb4},
+ {value: 0x9903, lo: 0xbc, hi: 0xbc},
+ // Block 0x10, offset 0x72
+ {value: 0x0008, lo: 0x06},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x8133, lo: 0x91, hi: 0x91},
+ {value: 0x812e, lo: 0x92, hi: 0x92},
+ {value: 0x8133, lo: 0x93, hi: 0x93},
+ {value: 0x8133, lo: 0x94, hi: 0x94},
+ {value: 0x4533, lo: 0x98, hi: 0x9f},
+ // Block 0x11, offset 0x79
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8103, lo: 0xbc, hi: 0xbc},
+ {value: 0x9900, lo: 0xbe, hi: 0xbe},
+ // Block 0x12, offset 0x7c
+ {value: 0x0008, lo: 0x07},
+ {value: 0xa000, lo: 0x87, hi: 0x87},
+ {value: 0x2cab, lo: 0x8b, hi: 0x8c},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x9900, lo: 0x97, hi: 0x97},
+ {value: 0x4573, lo: 0x9c, hi: 0x9d},
+ {value: 0x4583, lo: 0x9f, hi: 0x9f},
+ {value: 0x8133, lo: 0xbe, hi: 0xbe},
+ // Block 0x13, offset 0x84
+ {value: 0x0000, lo: 0x03},
+ {value: 0x45ab, lo: 0xb3, hi: 0xb3},
+ {value: 0x45b3, lo: 0xb6, hi: 0xb6},
+ {value: 0x8103, lo: 0xbc, hi: 0xbc},
+ // Block 0x14, offset 0x88
+ {value: 0x0008, lo: 0x03},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x458b, lo: 0x99, hi: 0x9b},
+ {value: 0x45a3, lo: 0x9e, hi: 0x9e},
+ // Block 0x15, offset 0x8c
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8103, lo: 0xbc, hi: 0xbc},
+ // Block 0x16, offset 0x8e
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ // Block 0x17, offset 0x90
+ {value: 0x0000, lo: 0x08},
+ {value: 0xa000, lo: 0x87, hi: 0x87},
+ {value: 0x2cc3, lo: 0x88, hi: 0x88},
+ {value: 0x2cbb, lo: 0x8b, hi: 0x8b},
+ {value: 0x2ccb, lo: 0x8c, hi: 0x8c},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x9900, lo: 0x96, hi: 0x97},
+ {value: 0x45bb, lo: 0x9c, hi: 0x9c},
+ {value: 0x45c3, lo: 0x9d, hi: 0x9d},
+ // Block 0x18, offset 0x99
+ {value: 0x0000, lo: 0x03},
+ {value: 0xa000, lo: 0x92, hi: 0x92},
+ {value: 0x2cd3, lo: 0x94, hi: 0x94},
+ {value: 0x9900, lo: 0xbe, hi: 0xbe},
+ // Block 0x19, offset 0x9d
+ {value: 0x0000, lo: 0x06},
+ {value: 0xa000, lo: 0x86, hi: 0x87},
+ {value: 0x2cdb, lo: 0x8a, hi: 0x8a},
+ {value: 0x2ceb, lo: 0x8b, hi: 0x8b},
+ {value: 0x2ce3, lo: 0x8c, hi: 0x8c},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x9900, lo: 0x97, hi: 0x97},
+ // Block 0x1a, offset 0xa4
+ {value: 0x1801, lo: 0x04},
+ {value: 0xa000, lo: 0x86, hi: 0x86},
+ {value: 0x3f07, lo: 0x88, hi: 0x88},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x8121, lo: 0x95, hi: 0x96},
+ // Block 0x1b, offset 0xa9
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8103, lo: 0xbc, hi: 0xbc},
+ {value: 0xa000, lo: 0xbf, hi: 0xbf},
+ // Block 0x1c, offset 0xac
+ {value: 0x0000, lo: 0x09},
+ {value: 0x2cf3, lo: 0x80, hi: 0x80},
+ {value: 0x9900, lo: 0x82, hi: 0x82},
+ {value: 0xa000, lo: 0x86, hi: 0x86},
+ {value: 0x2cfb, lo: 0x87, hi: 0x87},
+ {value: 0x2d03, lo: 0x88, hi: 0x88},
+ {value: 0x2f67, lo: 0x8a, hi: 0x8a},
+ {value: 0x2def, lo: 0x8b, hi: 0x8b},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x9900, lo: 0x95, hi: 0x96},
+ // Block 0x1d, offset 0xb6
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0xbb, hi: 0xbc},
+ {value: 0x9900, lo: 0xbe, hi: 0xbe},
+ // Block 0x1e, offset 0xb9
+ {value: 0x0000, lo: 0x06},
+ {value: 0xa000, lo: 0x86, hi: 0x87},
+ {value: 0x2d0b, lo: 0x8a, hi: 0x8a},
+ {value: 0x2d1b, lo: 0x8b, hi: 0x8b},
+ {value: 0x2d13, lo: 0x8c, hi: 0x8c},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x9900, lo: 0x97, hi: 0x97},
+ // Block 0x1f, offset 0xc0
+ {value: 0x6bdd, lo: 0x07},
+ {value: 0x9905, lo: 0x8a, hi: 0x8a},
+ {value: 0x9900, lo: 0x8f, hi: 0x8f},
+ {value: 0xa000, lo: 0x99, hi: 0x99},
+ {value: 0x3f0f, lo: 0x9a, hi: 0x9a},
+ {value: 0x2f6f, lo: 0x9c, hi: 0x9c},
+ {value: 0x2dfa, lo: 0x9d, hi: 0x9d},
+ {value: 0x2d23, lo: 0x9e, hi: 0x9f},
+ // Block 0x20, offset 0xc8
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8123, lo: 0xb8, hi: 0xb9},
+ {value: 0x8105, lo: 0xba, hi: 0xba},
+ // Block 0x21, offset 0xcb
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8124, lo: 0x88, hi: 0x8b},
+ // Block 0x22, offset 0xcd
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8125, lo: 0xb8, hi: 0xb9},
+ {value: 0x8105, lo: 0xba, hi: 0xba},
+ // Block 0x23, offset 0xd0
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8126, lo: 0x88, hi: 0x8b},
+ // Block 0x24, offset 0xd2
+ {value: 0x0000, lo: 0x04},
+ {value: 0x812e, lo: 0x98, hi: 0x99},
+ {value: 0x812e, lo: 0xb5, hi: 0xb5},
+ {value: 0x812e, lo: 0xb7, hi: 0xb7},
+ {value: 0x812c, lo: 0xb9, hi: 0xb9},
+ // Block 0x25, offset 0xd7
+ {value: 0x0000, lo: 0x10},
+ {value: 0x264a, lo: 0x83, hi: 0x83},
+ {value: 0x2651, lo: 0x8d, hi: 0x8d},
+ {value: 0x2658, lo: 0x92, hi: 0x92},
+ {value: 0x265f, lo: 0x97, hi: 0x97},
+ {value: 0x2666, lo: 0x9c, hi: 0x9c},
+ {value: 0x2643, lo: 0xa9, hi: 0xa9},
+ {value: 0x8127, lo: 0xb1, hi: 0xb1},
+ {value: 0x8128, lo: 0xb2, hi: 0xb2},
+ {value: 0x4a9b, lo: 0xb3, hi: 0xb3},
+ {value: 0x8129, lo: 0xb4, hi: 0xb4},
+ {value: 0x4aa4, lo: 0xb5, hi: 0xb5},
+ {value: 0x45cb, lo: 0xb6, hi: 0xb6},
+ {value: 0x8200, lo: 0xb7, hi: 0xb7},
+ {value: 0x45d3, lo: 0xb8, hi: 0xb8},
+ {value: 0x8200, lo: 0xb9, hi: 0xb9},
+ {value: 0x8128, lo: 0xba, hi: 0xbd},
+ // Block 0x26, offset 0xe8
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x8128, lo: 0x80, hi: 0x80},
+ {value: 0x4aad, lo: 0x81, hi: 0x81},
+ {value: 0x8133, lo: 0x82, hi: 0x83},
+ {value: 0x8105, lo: 0x84, hi: 0x84},
+ {value: 0x8133, lo: 0x86, hi: 0x87},
+ {value: 0x2674, lo: 0x93, hi: 0x93},
+ {value: 0x267b, lo: 0x9d, hi: 0x9d},
+ {value: 0x2682, lo: 0xa2, hi: 0xa2},
+ {value: 0x2689, lo: 0xa7, hi: 0xa7},
+ {value: 0x2690, lo: 0xac, hi: 0xac},
+ {value: 0x266d, lo: 0xb9, hi: 0xb9},
+ // Block 0x27, offset 0xf4
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0x86, hi: 0x86},
+ // Block 0x28, offset 0xf6
+ {value: 0x0000, lo: 0x05},
+ {value: 0xa000, lo: 0xa5, hi: 0xa5},
+ {value: 0x2d2b, lo: 0xa6, hi: 0xa6},
+ {value: 0x9900, lo: 0xae, hi: 0xae},
+ {value: 0x8103, lo: 0xb7, hi: 0xb7},
+ {value: 0x8105, lo: 0xb9, hi: 0xba},
+ // Block 0x29, offset 0xfc
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0x8d, hi: 0x8d},
+ // Block 0x2a, offset 0xfe
+ {value: 0x0000, lo: 0x01},
+ {value: 0xa000, lo: 0x80, hi: 0x92},
+ // Block 0x2b, offset 0x100
+ {value: 0x0000, lo: 0x01},
+ {value: 0xb900, lo: 0xa1, hi: 0xb5},
+ // Block 0x2c, offset 0x102
+ {value: 0x0000, lo: 0x01},
+ {value: 0x9900, lo: 0xa8, hi: 0xbf},
+ // Block 0x2d, offset 0x104
+ {value: 0x0000, lo: 0x01},
+ {value: 0x9900, lo: 0x80, hi: 0x82},
+ // Block 0x2e, offset 0x106
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0x9d, hi: 0x9f},
+ // Block 0x2f, offset 0x108
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x94, hi: 0x94},
+ {value: 0x8105, lo: 0xb4, hi: 0xb4},
+ // Block 0x30, offset 0x10b
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x92, hi: 0x92},
+ {value: 0x8133, lo: 0x9d, hi: 0x9d},
+ // Block 0x31, offset 0x10e
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8132, lo: 0xa9, hi: 0xa9},
+ // Block 0x32, offset 0x110
+ {value: 0x0004, lo: 0x02},
+ {value: 0x812f, lo: 0xb9, hi: 0xba},
+ {value: 0x812e, lo: 0xbb, hi: 0xbb},
+ // Block 0x33, offset 0x113
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8133, lo: 0x97, hi: 0x97},
+ {value: 0x812e, lo: 0x98, hi: 0x98},
+ // Block 0x34, offset 0x116
+ {value: 0x0000, lo: 0x03},
+ {value: 0x8105, lo: 0xa0, hi: 0xa0},
+ {value: 0x8133, lo: 0xb5, hi: 0xbc},
+ {value: 0x812e, lo: 0xbf, hi: 0xbf},
+ // Block 0x35, offset 0x11a
+ {value: 0x0000, lo: 0x05},
+ {value: 0x8133, lo: 0xb0, hi: 0xb4},
+ {value: 0x812e, lo: 0xb5, hi: 0xba},
+ {value: 0x8133, lo: 0xbb, hi: 0xbc},
+ {value: 0x812e, lo: 0xbd, hi: 0xbd},
+ {value: 0x812e, lo: 0xbf, hi: 0xbf},
+ // Block 0x36, offset 0x120
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0x80, hi: 0x80},
+ // Block 0x37, offset 0x122
+ {value: 0x0000, lo: 0x08},
+ {value: 0x2d73, lo: 0x80, hi: 0x80},
+ {value: 0x2d7b, lo: 0x81, hi: 0x81},
+ {value: 0xa000, lo: 0x82, hi: 0x82},
+ {value: 0x2d83, lo: 0x83, hi: 0x83},
+ {value: 0x8105, lo: 0x84, hi: 0x84},
+ {value: 0x8133, lo: 0xab, hi: 0xab},
+ {value: 0x812e, lo: 0xac, hi: 0xac},
+ {value: 0x8133, lo: 0xad, hi: 0xb3},
+ // Block 0x38, offset 0x12b
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0xaa, hi: 0xab},
+ // Block 0x39, offset 0x12d
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8103, lo: 0xa6, hi: 0xa6},
+ {value: 0x8105, lo: 0xb2, hi: 0xb3},
+ // Block 0x3a, offset 0x130
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8103, lo: 0xb7, hi: 0xb7},
+ // Block 0x3b, offset 0x132
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x8133, lo: 0x90, hi: 0x92},
+ {value: 0x8101, lo: 0x94, hi: 0x94},
+ {value: 0x812e, lo: 0x95, hi: 0x99},
+ {value: 0x8133, lo: 0x9a, hi: 0x9b},
+ {value: 0x812e, lo: 0x9c, hi: 0x9f},
+ {value: 0x8133, lo: 0xa0, hi: 0xa0},
+ {value: 0x8101, lo: 0xa2, hi: 0xa8},
+ {value: 0x812e, lo: 0xad, hi: 0xad},
+ {value: 0x8133, lo: 0xb4, hi: 0xb4},
+ {value: 0x8133, lo: 0xb8, hi: 0xb9},
+ // Block 0x3c, offset 0x13d
+ {value: 0x0004, lo: 0x03},
+ {value: 0x0436, lo: 0x80, hi: 0x81},
+ {value: 0x8100, lo: 0x97, hi: 0x97},
+ {value: 0x8100, lo: 0xbe, hi: 0xbe},
+ // Block 0x3d, offset 0x141
+ {value: 0x0000, lo: 0x0d},
+ {value: 0x8133, lo: 0x90, hi: 0x91},
+ {value: 0x8101, lo: 0x92, hi: 0x93},
+ {value: 0x8133, lo: 0x94, hi: 0x97},
+ {value: 0x8101, lo: 0x98, hi: 0x9a},
+ {value: 0x8133, lo: 0x9b, hi: 0x9c},
+ {value: 0x8133, lo: 0xa1, hi: 0xa1},
+ {value: 0x8101, lo: 0xa5, hi: 0xa6},
+ {value: 0x8133, lo: 0xa7, hi: 0xa7},
+ {value: 0x812e, lo: 0xa8, hi: 0xa8},
+ {value: 0x8133, lo: 0xa9, hi: 0xa9},
+ {value: 0x8101, lo: 0xaa, hi: 0xab},
+ {value: 0x812e, lo: 0xac, hi: 0xaf},
+ {value: 0x8133, lo: 0xb0, hi: 0xb0},
+ // Block 0x3e, offset 0x14f
+ {value: 0x4292, lo: 0x02},
+ {value: 0x01bb, lo: 0xa6, hi: 0xa6},
+ {value: 0x0057, lo: 0xaa, hi: 0xab},
+ // Block 0x3f, offset 0x152
+ {value: 0x0007, lo: 0x05},
+ {value: 0xa000, lo: 0x90, hi: 0x90},
+ {value: 0xa000, lo: 0x92, hi: 0x92},
+ {value: 0xa000, lo: 0x94, hi: 0x94},
+ {value: 0x3bd0, lo: 0x9a, hi: 0x9b},
+ {value: 0x3bde, lo: 0xae, hi: 0xae},
+ // Block 0x40, offset 0x158
+ {value: 0x000e, lo: 0x05},
+ {value: 0x3be5, lo: 0x8d, hi: 0x8e},
+ {value: 0x3bec, lo: 0x8f, hi: 0x8f},
+ {value: 0xa000, lo: 0x90, hi: 0x90},
+ {value: 0xa000, lo: 0x92, hi: 0x92},
+ {value: 0xa000, lo: 0x94, hi: 0x94},
+ // Block 0x41, offset 0x15e
+ {value: 0x63f1, lo: 0x0a},
+ {value: 0xa000, lo: 0x83, hi: 0x83},
+ {value: 0x3bfa, lo: 0x84, hi: 0x84},
+ {value: 0xa000, lo: 0x88, hi: 0x88},
+ {value: 0x3c01, lo: 0x89, hi: 0x89},
+ {value: 0xa000, lo: 0x8b, hi: 0x8b},
+ {value: 0x3c08, lo: 0x8c, hi: 0x8c},
+ {value: 0xa000, lo: 0xa3, hi: 0xa3},
+ {value: 0x3c0f, lo: 0xa4, hi: 0xa5},
+ {value: 0x3c16, lo: 0xa6, hi: 0xa6},
+ {value: 0xa000, lo: 0xbc, hi: 0xbc},
+ // Block 0x42, offset 0x169
+ {value: 0x0007, lo: 0x03},
+ {value: 0x3c7f, lo: 0xa0, hi: 0xa1},
+ {value: 0x3ca9, lo: 0xa2, hi: 0xa3},
+ {value: 0x3cd3, lo: 0xaa, hi: 0xad},
+ // Block 0x43, offset 0x16d
+ {value: 0x0004, lo: 0x01},
+ {value: 0x048e, lo: 0xa9, hi: 0xaa},
+ // Block 0x44, offset 0x16f
+ {value: 0x0000, lo: 0x01},
+ {value: 0x44f4, lo: 0x9c, hi: 0x9c},
+ // Block 0x45, offset 0x171
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xaf, hi: 0xb1},
+ // Block 0x46, offset 0x173
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0xbf, hi: 0xbf},
+ // Block 0x47, offset 0x175
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xa0, hi: 0xbf},
+ // Block 0x48, offset 0x177
+ {value: 0x0000, lo: 0x05},
+ {value: 0x812d, lo: 0xaa, hi: 0xaa},
+ {value: 0x8132, lo: 0xab, hi: 0xab},
+ {value: 0x8134, lo: 0xac, hi: 0xac},
+ {value: 0x812f, lo: 0xad, hi: 0xad},
+ {value: 0x8130, lo: 0xae, hi: 0xaf},
+ // Block 0x49, offset 0x17d
+ {value: 0x0000, lo: 0x03},
+ {value: 0x4ab6, lo: 0xb3, hi: 0xb3},
+ {value: 0x4ab6, lo: 0xb5, hi: 0xb6},
+ {value: 0x4ab6, lo: 0xba, hi: 0xbf},
+ // Block 0x4a, offset 0x181
+ {value: 0x0000, lo: 0x01},
+ {value: 0x4ab6, lo: 0x8f, hi: 0xa3},
+ // Block 0x4b, offset 0x183
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8100, lo: 0xae, hi: 0xbe},
+ // Block 0x4c, offset 0x185
+ {value: 0x0000, lo: 0x07},
+ {value: 0x8100, lo: 0x84, hi: 0x84},
+ {value: 0x8100, lo: 0x87, hi: 0x87},
+ {value: 0x8100, lo: 0x90, hi: 0x90},
+ {value: 0x8100, lo: 0x9e, hi: 0x9e},
+ {value: 0x8100, lo: 0xa1, hi: 0xa1},
+ {value: 0x8100, lo: 0xb2, hi: 0xb2},
+ {value: 0x8100, lo: 0xbb, hi: 0xbb},
+ // Block 0x4d, offset 0x18d
+ {value: 0x0000, lo: 0x03},
+ {value: 0x8100, lo: 0x80, hi: 0x80},
+ {value: 0x8100, lo: 0x8b, hi: 0x8b},
+ {value: 0x8100, lo: 0x8e, hi: 0x8e},
+ // Block 0x4e, offset 0x191
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8133, lo: 0xaf, hi: 0xaf},
+ {value: 0x8133, lo: 0xb4, hi: 0xbd},
+ // Block 0x4f, offset 0x194
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0x9e, hi: 0x9f},
+ // Block 0x50, offset 0x196
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xb0, hi: 0xb1},
+ // Block 0x51, offset 0x198
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x86, hi: 0x86},
+ {value: 0x8105, lo: 0xac, hi: 0xac},
+ // Block 0x52, offset 0x19b
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x84, hi: 0x84},
+ {value: 0x8133, lo: 0xa0, hi: 0xb1},
+ // Block 0x53, offset 0x19e
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0xab, hi: 0xad},
+ // Block 0x54, offset 0x1a0
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0x93, hi: 0x93},
+ // Block 0x55, offset 0x1a2
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8103, lo: 0xb3, hi: 0xb3},
+ // Block 0x56, offset 0x1a4
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0x80, hi: 0x80},
+ // Block 0x57, offset 0x1a6
+ {value: 0x0000, lo: 0x05},
+ {value: 0x8133, lo: 0xb0, hi: 0xb0},
+ {value: 0x8133, lo: 0xb2, hi: 0xb3},
+ {value: 0x812e, lo: 0xb4, hi: 0xb4},
+ {value: 0x8133, lo: 0xb7, hi: 0xb8},
+ {value: 0x8133, lo: 0xbe, hi: 0xbf},
+ // Block 0x58, offset 0x1ac
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8133, lo: 0x81, hi: 0x81},
+ {value: 0x8105, lo: 0xb6, hi: 0xb6},
+ // Block 0x59, offset 0x1af
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0xad, hi: 0xad},
+ // Block 0x5a, offset 0x1b1
+ {value: 0x0000, lo: 0x06},
+ {value: 0xe500, lo: 0x80, hi: 0x80},
+ {value: 0xc600, lo: 0x81, hi: 0x9b},
+ {value: 0xe500, lo: 0x9c, hi: 0x9c},
+ {value: 0xc600, lo: 0x9d, hi: 0xb7},
+ {value: 0xe500, lo: 0xb8, hi: 0xb8},
+ {value: 0xc600, lo: 0xb9, hi: 0xbf},
+ // Block 0x5b, offset 0x1b8
+ {value: 0x0000, lo: 0x05},
+ {value: 0xc600, lo: 0x80, hi: 0x93},
+ {value: 0xe500, lo: 0x94, hi: 0x94},
+ {value: 0xc600, lo: 0x95, hi: 0xaf},
+ {value: 0xe500, lo: 0xb0, hi: 0xb0},
+ {value: 0xc600, lo: 0xb1, hi: 0xbf},
+ // Block 0x5c, offset 0x1be
+ {value: 0x0000, lo: 0x05},
+ {value: 0xc600, lo: 0x80, hi: 0x8b},
+ {value: 0xe500, lo: 0x8c, hi: 0x8c},
+ {value: 0xc600, lo: 0x8d, hi: 0xa7},
+ {value: 0xe500, lo: 0xa8, hi: 0xa8},
+ {value: 0xc600, lo: 0xa9, hi: 0xbf},
+ // Block 0x5d, offset 0x1c4
+ {value: 0x0000, lo: 0x07},
+ {value: 0xc600, lo: 0x80, hi: 0x83},
+ {value: 0xe500, lo: 0x84, hi: 0x84},
+ {value: 0xc600, lo: 0x85, hi: 0x9f},
+ {value: 0xe500, lo: 0xa0, hi: 0xa0},
+ {value: 0xc600, lo: 0xa1, hi: 0xbb},
+ {value: 0xe500, lo: 0xbc, hi: 0xbc},
+ {value: 0xc600, lo: 0xbd, hi: 0xbf},
+ // Block 0x5e, offset 0x1cc
+ {value: 0x0000, lo: 0x05},
+ {value: 0xc600, lo: 0x80, hi: 0x97},
+ {value: 0xe500, lo: 0x98, hi: 0x98},
+ {value: 0xc600, lo: 0x99, hi: 0xb3},
+ {value: 0xe500, lo: 0xb4, hi: 0xb4},
+ {value: 0xc600, lo: 0xb5, hi: 0xbf},
+ // Block 0x5f, offset 0x1d2
+ {value: 0x0000, lo: 0x05},
+ {value: 0xc600, lo: 0x80, hi: 0x8f},
+ {value: 0xe500, lo: 0x90, hi: 0x90},
+ {value: 0xc600, lo: 0x91, hi: 0xab},
+ {value: 0xe500, lo: 0xac, hi: 0xac},
+ {value: 0xc600, lo: 0xad, hi: 0xbf},
+ // Block 0x60, offset 0x1d8
+ {value: 0x0000, lo: 0x05},
+ {value: 0xc600, lo: 0x80, hi: 0x87},
+ {value: 0xe500, lo: 0x88, hi: 0x88},
+ {value: 0xc600, lo: 0x89, hi: 0xa3},
+ {value: 0xe500, lo: 0xa4, hi: 0xa4},
+ {value: 0xc600, lo: 0xa5, hi: 0xbf},
+ // Block 0x61, offset 0x1de
+ {value: 0x0000, lo: 0x03},
+ {value: 0xc600, lo: 0x80, hi: 0x87},
+ {value: 0xe500, lo: 0x88, hi: 0x88},
+ {value: 0xc600, lo: 0x89, hi: 0xa3},
+ // Block 0x62, offset 0x1e2
+ {value: 0x0006, lo: 0x0d},
+ {value: 0x43a7, lo: 0x9d, hi: 0x9d},
+ {value: 0x8116, lo: 0x9e, hi: 0x9e},
+ {value: 0x4419, lo: 0x9f, hi: 0x9f},
+ {value: 0x4407, lo: 0xaa, hi: 0xab},
+ {value: 0x450b, lo: 0xac, hi: 0xac},
+ {value: 0x4513, lo: 0xad, hi: 0xad},
+ {value: 0x435f, lo: 0xae, hi: 0xb1},
+ {value: 0x437d, lo: 0xb2, hi: 0xb4},
+ {value: 0x4395, lo: 0xb5, hi: 0xb6},
+ {value: 0x43a1, lo: 0xb8, hi: 0xb8},
+ {value: 0x43ad, lo: 0xb9, hi: 0xbb},
+ {value: 0x43c5, lo: 0xbc, hi: 0xbc},
+ {value: 0x43cb, lo: 0xbe, hi: 0xbe},
+ // Block 0x63, offset 0x1f0
+ {value: 0x0006, lo: 0x08},
+ {value: 0x43d1, lo: 0x80, hi: 0x81},
+ {value: 0x43dd, lo: 0x83, hi: 0x84},
+ {value: 0x43ef, lo: 0x86, hi: 0x89},
+ {value: 0x4413, lo: 0x8a, hi: 0x8a},
+ {value: 0x438f, lo: 0x8b, hi: 0x8b},
+ {value: 0x4377, lo: 0x8c, hi: 0x8c},
+ {value: 0x43bf, lo: 0x8d, hi: 0x8d},
+ {value: 0x43e9, lo: 0x8e, hi: 0x8e},
+ // Block 0x64, offset 0x1f9
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8100, lo: 0xa4, hi: 0xa5},
+ {value: 0x8100, lo: 0xb0, hi: 0xb1},
+ // Block 0x65, offset 0x1fc
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8100, lo: 0x9b, hi: 0x9d},
+ {value: 0x8200, lo: 0x9e, hi: 0xa3},
+ // Block 0x66, offset 0x1ff
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8100, lo: 0x90, hi: 0x90},
+ // Block 0x67, offset 0x201
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8100, lo: 0x99, hi: 0x99},
+ {value: 0x8200, lo: 0xb2, hi: 0xb4},
+ // Block 0x68, offset 0x204
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8100, lo: 0xbc, hi: 0xbd},
+ // Block 0x69, offset 0x206
+ {value: 0x0000, lo: 0x03},
+ {value: 0x8133, lo: 0xa0, hi: 0xa6},
+ {value: 0x812e, lo: 0xa7, hi: 0xad},
+ {value: 0x8133, lo: 0xae, hi: 0xaf},
+ // Block 0x6a, offset 0x20a
+ {value: 0x0000, lo: 0x04},
+ {value: 0x8100, lo: 0x89, hi: 0x8c},
+ {value: 0x8100, lo: 0xb0, hi: 0xb2},
+ {value: 0x8100, lo: 0xb4, hi: 0xb4},
+ {value: 0x8100, lo: 0xb6, hi: 0xbf},
+ // Block 0x6b, offset 0x20f
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8100, lo: 0x81, hi: 0x8c},
+ // Block 0x6c, offset 0x211
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8100, lo: 0xb5, hi: 0xba},
+ // Block 0x6d, offset 0x213
+ {value: 0x0000, lo: 0x04},
+ {value: 0x4ab6, lo: 0x9e, hi: 0x9f},
+ {value: 0x4ab6, lo: 0xa3, hi: 0xa3},
+ {value: 0x4ab6, lo: 0xa5, hi: 0xa6},
+ {value: 0x4ab6, lo: 0xaa, hi: 0xaf},
+ // Block 0x6e, offset 0x218
+ {value: 0x0000, lo: 0x05},
+ {value: 0x4ab6, lo: 0x82, hi: 0x87},
+ {value: 0x4ab6, lo: 0x8a, hi: 0x8f},
+ {value: 0x4ab6, lo: 0x92, hi: 0x97},
+ {value: 0x4ab6, lo: 0x9a, hi: 0x9c},
+ {value: 0x8100, lo: 0xa3, hi: 0xa3},
+ // Block 0x6f, offset 0x21e
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0xbd, hi: 0xbd},
+ // Block 0x70, offset 0x220
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0xa0, hi: 0xa0},
+ // Block 0x71, offset 0x222
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xb6, hi: 0xba},
+ // Block 0x72, offset 0x224
+ {value: 0x002d, lo: 0x05},
+ {value: 0x812e, lo: 0x8d, hi: 0x8d},
+ {value: 0x8133, lo: 0x8f, hi: 0x8f},
+ {value: 0x8133, lo: 0xb8, hi: 0xb8},
+ {value: 0x8101, lo: 0xb9, hi: 0xba},
+ {value: 0x8105, lo: 0xbf, hi: 0xbf},
+ // Block 0x73, offset 0x22a
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8133, lo: 0xa5, hi: 0xa5},
+ {value: 0x812e, lo: 0xa6, hi: 0xa6},
+ // Block 0x74, offset 0x22d
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xa4, hi: 0xa7},
+ // Block 0x75, offset 0x22f
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xab, hi: 0xac},
+ // Block 0x76, offset 0x231
+ {value: 0x0000, lo: 0x05},
+ {value: 0x812e, lo: 0x86, hi: 0x87},
+ {value: 0x8133, lo: 0x88, hi: 0x8a},
+ {value: 0x812e, lo: 0x8b, hi: 0x8b},
+ {value: 0x8133, lo: 0x8c, hi: 0x8c},
+ {value: 0x812e, lo: 0x8d, hi: 0x90},
+ // Block 0x77, offset 0x237
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x86, hi: 0x86},
+ {value: 0x8105, lo: 0xbf, hi: 0xbf},
+ // Block 0x78, offset 0x23a
+ {value: 0x17fe, lo: 0x07},
+ {value: 0xa000, lo: 0x99, hi: 0x99},
+ {value: 0x424f, lo: 0x9a, hi: 0x9a},
+ {value: 0xa000, lo: 0x9b, hi: 0x9b},
+ {value: 0x4259, lo: 0x9c, hi: 0x9c},
+ {value: 0xa000, lo: 0xa5, hi: 0xa5},
+ {value: 0x4263, lo: 0xab, hi: 0xab},
+ {value: 0x8105, lo: 0xb9, hi: 0xba},
+ // Block 0x79, offset 0x242
+ {value: 0x0000, lo: 0x06},
+ {value: 0x8133, lo: 0x80, hi: 0x82},
+ {value: 0x9900, lo: 0xa7, hi: 0xa7},
+ {value: 0x2d8b, lo: 0xae, hi: 0xae},
+ {value: 0x2d95, lo: 0xaf, hi: 0xaf},
+ {value: 0xa000, lo: 0xb1, hi: 0xb2},
+ {value: 0x8105, lo: 0xb3, hi: 0xb4},
+ // Block 0x7a, offset 0x249
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x80, hi: 0x80},
+ {value: 0x8103, lo: 0x8a, hi: 0x8a},
+ // Block 0x7b, offset 0x24c
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0xb5, hi: 0xb5},
+ {value: 0x8103, lo: 0xb6, hi: 0xb6},
+ // Block 0x7c, offset 0x24f
+ {value: 0x0002, lo: 0x01},
+ {value: 0x8103, lo: 0xa9, hi: 0xaa},
+ // Block 0x7d, offset 0x251
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8103, lo: 0xbb, hi: 0xbc},
+ {value: 0x9900, lo: 0xbe, hi: 0xbe},
+ // Block 0x7e, offset 0x254
+ {value: 0x0000, lo: 0x07},
+ {value: 0xa000, lo: 0x87, hi: 0x87},
+ {value: 0x2d9f, lo: 0x8b, hi: 0x8b},
+ {value: 0x2da9, lo: 0x8c, hi: 0x8c},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x9900, lo: 0x97, hi: 0x97},
+ {value: 0x8133, lo: 0xa6, hi: 0xac},
+ {value: 0x8133, lo: 0xb0, hi: 0xb4},
+ // Block 0x7f, offset 0x25c
+ {value: 0x0000, lo: 0x03},
+ {value: 0x8105, lo: 0x82, hi: 0x82},
+ {value: 0x8103, lo: 0x86, hi: 0x86},
+ {value: 0x8133, lo: 0x9e, hi: 0x9e},
+ // Block 0x80, offset 0x260
+ {value: 0x6b4d, lo: 0x06},
+ {value: 0x9900, lo: 0xb0, hi: 0xb0},
+ {value: 0xa000, lo: 0xb9, hi: 0xb9},
+ {value: 0x9900, lo: 0xba, hi: 0xba},
+ {value: 0x2dbd, lo: 0xbb, hi: 0xbb},
+ {value: 0x2db3, lo: 0xbc, hi: 0xbd},
+ {value: 0x2dc7, lo: 0xbe, hi: 0xbe},
+ // Block 0x81, offset 0x267
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x82, hi: 0x82},
+ {value: 0x8103, lo: 0x83, hi: 0x83},
+ // Block 0x82, offset 0x26a
+ {value: 0x0000, lo: 0x05},
+ {value: 0x9900, lo: 0xaf, hi: 0xaf},
+ {value: 0xa000, lo: 0xb8, hi: 0xb9},
+ {value: 0x2dd1, lo: 0xba, hi: 0xba},
+ {value: 0x2ddb, lo: 0xbb, hi: 0xbb},
+ {value: 0x8105, lo: 0xbf, hi: 0xbf},
+ // Block 0x83, offset 0x270
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8103, lo: 0x80, hi: 0x80},
+ // Block 0x84, offset 0x272
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0xb6, hi: 0xb6},
+ {value: 0x8103, lo: 0xb7, hi: 0xb7},
+ // Block 0x85, offset 0x275
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0xab, hi: 0xab},
+ // Block 0x86, offset 0x277
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0xb9, hi: 0xb9},
+ {value: 0x8103, lo: 0xba, hi: 0xba},
+ // Block 0x87, offset 0x27a
+ {value: 0x0000, lo: 0x04},
+ {value: 0x9900, lo: 0xb0, hi: 0xb0},
+ {value: 0xa000, lo: 0xb5, hi: 0xb5},
+ {value: 0x2de5, lo: 0xb8, hi: 0xb8},
+ {value: 0x8105, lo: 0xbd, hi: 0xbe},
+ // Block 0x88, offset 0x27f
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8103, lo: 0x83, hi: 0x83},
+ // Block 0x89, offset 0x281
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0xa0, hi: 0xa0},
+ // Block 0x8a, offset 0x283
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0xb4, hi: 0xb4},
+ // Block 0x8b, offset 0x285
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0x87, hi: 0x87},
+ // Block 0x8c, offset 0x287
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0x99, hi: 0x99},
+ // Block 0x8d, offset 0x289
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8103, lo: 0x82, hi: 0x82},
+ {value: 0x8105, lo: 0x84, hi: 0x85},
+ // Block 0x8e, offset 0x28c
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0x97, hi: 0x97},
+ // Block 0x8f, offset 0x28e
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8101, lo: 0xb0, hi: 0xb4},
+ // Block 0x90, offset 0x290
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xb0, hi: 0xb6},
+ // Block 0x91, offset 0x292
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8102, lo: 0xb0, hi: 0xb1},
+ // Block 0x92, offset 0x294
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8101, lo: 0x9e, hi: 0x9e},
+ // Block 0x93, offset 0x296
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x45e3, lo: 0x9e, hi: 0x9e},
+ {value: 0x45ed, lo: 0x9f, hi: 0x9f},
+ {value: 0x4621, lo: 0xa0, hi: 0xa0},
+ {value: 0x462f, lo: 0xa1, hi: 0xa1},
+ {value: 0x463d, lo: 0xa2, hi: 0xa2},
+ {value: 0x464b, lo: 0xa3, hi: 0xa3},
+ {value: 0x4659, lo: 0xa4, hi: 0xa4},
+ {value: 0x812c, lo: 0xa5, hi: 0xa6},
+ {value: 0x8101, lo: 0xa7, hi: 0xa9},
+ {value: 0x8131, lo: 0xad, hi: 0xad},
+ {value: 0x812c, lo: 0xae, hi: 0xb2},
+ {value: 0x812e, lo: 0xbb, hi: 0xbf},
+ // Block 0x94, offset 0x2a3
+ {value: 0x0000, lo: 0x09},
+ {value: 0x812e, lo: 0x80, hi: 0x82},
+ {value: 0x8133, lo: 0x85, hi: 0x89},
+ {value: 0x812e, lo: 0x8a, hi: 0x8b},
+ {value: 0x8133, lo: 0xaa, hi: 0xad},
+ {value: 0x45f7, lo: 0xbb, hi: 0xbb},
+ {value: 0x4601, lo: 0xbc, hi: 0xbc},
+ {value: 0x4667, lo: 0xbd, hi: 0xbd},
+ {value: 0x4683, lo: 0xbe, hi: 0xbe},
+ {value: 0x4675, lo: 0xbf, hi: 0xbf},
+ // Block 0x95, offset 0x2ad
+ {value: 0x0000, lo: 0x01},
+ {value: 0x4691, lo: 0x80, hi: 0x80},
+ // Block 0x96, offset 0x2af
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0x82, hi: 0x84},
+ // Block 0x97, offset 0x2b1
+ {value: 0x0000, lo: 0x05},
+ {value: 0x8133, lo: 0x80, hi: 0x86},
+ {value: 0x8133, lo: 0x88, hi: 0x98},
+ {value: 0x8133, lo: 0x9b, hi: 0xa1},
+ {value: 0x8133, lo: 0xa3, hi: 0xa4},
+ {value: 0x8133, lo: 0xa6, hi: 0xaa},
+ // Block 0x98, offset 0x2b7
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xac, hi: 0xaf},
+ // Block 0x99, offset 0x2b9
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0x90, hi: 0x96},
+ // Block 0x9a, offset 0x2bb
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8133, lo: 0x84, hi: 0x89},
+ {value: 0x8103, lo: 0x8a, hi: 0x8a},
+ // Block 0x9b, offset 0x2be
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8100, lo: 0x93, hi: 0x93},
+}
+
+// lookup returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *nfkcTrie) lookup(s []byte) (v uint16, sz int) {
+ c0 := s[0]
+ switch {
+ case c0 < 0x80: // is ASCII
+ return nfkcValues[c0], 1
+ case c0 < 0xC2:
+ return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+ case c0 < 0xE0: // 2-byte UTF-8
+ if len(s) < 2 {
+ return 0, 0
+ }
+ i := nfkcIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c1), 2
+ case c0 < 0xF0: // 3-byte UTF-8
+ if len(s) < 3 {
+ return 0, 0
+ }
+ i := nfkcIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = nfkcIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c2), 3
+ case c0 < 0xF8: // 4-byte UTF-8
+ if len(s) < 4 {
+ return 0, 0
+ }
+ i := nfkcIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = nfkcIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ o = uint32(i)<<6 + uint32(c2)
+ i = nfkcIndex[o]
+ c3 := s[3]
+ if c3 < 0x80 || 0xC0 <= c3 {
+ return 0, 3 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c3), 4
+ }
+ // Illegal rune
+ return 0, 1
+}
+
+// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *nfkcTrie) lookupUnsafe(s []byte) uint16 {
+ c0 := s[0]
+ if c0 < 0x80 { // is ASCII
+ return nfkcValues[c0]
+ }
+ i := nfkcIndex[c0]
+ if c0 < 0xE0 { // 2-byte UTF-8
+ return t.lookupValue(uint32(i), s[1])
+ }
+ i = nfkcIndex[uint32(i)<<6+uint32(s[1])]
+ if c0 < 0xF0 { // 3-byte UTF-8
+ return t.lookupValue(uint32(i), s[2])
+ }
+ i = nfkcIndex[uint32(i)<<6+uint32(s[2])]
+ if c0 < 0xF8 { // 4-byte UTF-8
+ return t.lookupValue(uint32(i), s[3])
+ }
+ return 0
+}
+
+// lookupString returns the trie value for the first UTF-8 encoding in s and
+// the width in bytes of this encoding. The size will be 0 if s does not
+// hold enough bytes to complete the encoding. len(s) must be greater than 0.
+func (t *nfkcTrie) lookupString(s string) (v uint16, sz int) {
+ c0 := s[0]
+ switch {
+ case c0 < 0x80: // is ASCII
+ return nfkcValues[c0], 1
+ case c0 < 0xC2:
+ return 0, 1 // Illegal UTF-8: not a starter, not ASCII.
+ case c0 < 0xE0: // 2-byte UTF-8
+ if len(s) < 2 {
+ return 0, 0
+ }
+ i := nfkcIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c1), 2
+ case c0 < 0xF0: // 3-byte UTF-8
+ if len(s) < 3 {
+ return 0, 0
+ }
+ i := nfkcIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = nfkcIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c2), 3
+ case c0 < 0xF8: // 4-byte UTF-8
+ if len(s) < 4 {
+ return 0, 0
+ }
+ i := nfkcIndex[c0]
+ c1 := s[1]
+ if c1 < 0x80 || 0xC0 <= c1 {
+ return 0, 1 // Illegal UTF-8: not a continuation byte.
+ }
+ o := uint32(i)<<6 + uint32(c1)
+ i = nfkcIndex[o]
+ c2 := s[2]
+ if c2 < 0x80 || 0xC0 <= c2 {
+ return 0, 2 // Illegal UTF-8: not a continuation byte.
+ }
+ o = uint32(i)<<6 + uint32(c2)
+ i = nfkcIndex[o]
+ c3 := s[3]
+ if c3 < 0x80 || 0xC0 <= c3 {
+ return 0, 3 // Illegal UTF-8: not a continuation byte.
+ }
+ return t.lookupValue(uint32(i), c3), 4
+ }
+ // Illegal rune
+ return 0, 1
+}
+
+// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.
+// s must start with a full and valid UTF-8 encoded rune.
+func (t *nfkcTrie) lookupStringUnsafe(s string) uint16 {
+ c0 := s[0]
+ if c0 < 0x80 { // is ASCII
+ return nfkcValues[c0]
+ }
+ i := nfkcIndex[c0]
+ if c0 < 0xE0 { // 2-byte UTF-8
+ return t.lookupValue(uint32(i), s[1])
+ }
+ i = nfkcIndex[uint32(i)<<6+uint32(s[1])]
+ if c0 < 0xF0 { // 3-byte UTF-8
+ return t.lookupValue(uint32(i), s[2])
+ }
+ i = nfkcIndex[uint32(i)<<6+uint32(s[2])]
+ if c0 < 0xF8 { // 4-byte UTF-8
+ return t.lookupValue(uint32(i), s[3])
+ }
+ return 0
+}
+
+// nfkcTrie. Total size: 18768 bytes (18.33 KiB). Checksum: c51186dd2412943d.
+type nfkcTrie struct{}
+
+func newNfkcTrie(i int) *nfkcTrie {
+ return &nfkcTrie{}
+}
+
+// lookupValue determines the type of block n and looks up the value for b.
+func (t *nfkcTrie) lookupValue(n uint32, b byte) uint16 {
+ switch {
+ case n < 92:
+ return uint16(nfkcValues[n<<6+uint32(b)])
+ default:
+ n -= 92
+ return uint16(nfkcSparse.lookup(n, b))
+ }
+}
+
+// nfkcValues: 94 blocks, 6016 entries, 12032 bytes
+// The third block is the zero block.
+var nfkcValues = [6016]uint16{
+ // Block 0x0, offset 0x0
+ 0x3c: 0xa000, 0x3d: 0xa000, 0x3e: 0xa000,
+ // Block 0x1, offset 0x40
+ 0x41: 0xa000, 0x42: 0xa000, 0x43: 0xa000, 0x44: 0xa000, 0x45: 0xa000,
+ 0x46: 0xa000, 0x47: 0xa000, 0x48: 0xa000, 0x49: 0xa000, 0x4a: 0xa000, 0x4b: 0xa000,
+ 0x4c: 0xa000, 0x4d: 0xa000, 0x4e: 0xa000, 0x4f: 0xa000, 0x50: 0xa000,
+ 0x52: 0xa000, 0x53: 0xa000, 0x54: 0xa000, 0x55: 0xa000, 0x56: 0xa000, 0x57: 0xa000,
+ 0x58: 0xa000, 0x59: 0xa000, 0x5a: 0xa000,
+ 0x61: 0xa000, 0x62: 0xa000, 0x63: 0xa000,
+ 0x64: 0xa000, 0x65: 0xa000, 0x66: 0xa000, 0x67: 0xa000, 0x68: 0xa000, 0x69: 0xa000,
+ 0x6a: 0xa000, 0x6b: 0xa000, 0x6c: 0xa000, 0x6d: 0xa000, 0x6e: 0xa000, 0x6f: 0xa000,
+ 0x70: 0xa000, 0x72: 0xa000, 0x73: 0xa000, 0x74: 0xa000, 0x75: 0xa000,
+ 0x76: 0xa000, 0x77: 0xa000, 0x78: 0xa000, 0x79: 0xa000, 0x7a: 0xa000,
+ // Block 0x2, offset 0x80
+ // Block 0x3, offset 0xc0
+ 0xc0: 0x2f86, 0xc1: 0x2f8b, 0xc2: 0x469f, 0xc3: 0x2f90, 0xc4: 0x46ae, 0xc5: 0x46b3,
+ 0xc6: 0xa000, 0xc7: 0x46bd, 0xc8: 0x2ff9, 0xc9: 0x2ffe, 0xca: 0x46c2, 0xcb: 0x3012,
+ 0xcc: 0x3085, 0xcd: 0x308a, 0xce: 0x308f, 0xcf: 0x46d6, 0xd1: 0x311b,
+ 0xd2: 0x313e, 0xd3: 0x3143, 0xd4: 0x46e0, 0xd5: 0x46e5, 0xd6: 0x46f4,
+ 0xd8: 0xa000, 0xd9: 0x31ca, 0xda: 0x31cf, 0xdb: 0x31d4, 0xdc: 0x4726, 0xdd: 0x324c,
+ 0xe0: 0x3292, 0xe1: 0x3297, 0xe2: 0x4730, 0xe3: 0x329c,
+ 0xe4: 0x473f, 0xe5: 0x4744, 0xe6: 0xa000, 0xe7: 0x474e, 0xe8: 0x3305, 0xe9: 0x330a,
+ 0xea: 0x4753, 0xeb: 0x331e, 0xec: 0x3396, 0xed: 0x339b, 0xee: 0x33a0, 0xef: 0x4767,
+ 0xf1: 0x342c, 0xf2: 0x344f, 0xf3: 0x3454, 0xf4: 0x4771, 0xf5: 0x4776,
+ 0xf6: 0x4785, 0xf8: 0xa000, 0xf9: 0x34e0, 0xfa: 0x34e5, 0xfb: 0x34ea,
+ 0xfc: 0x47b7, 0xfd: 0x3567, 0xff: 0x3580,
+ // Block 0x4, offset 0x100
+ 0x100: 0x2f95, 0x101: 0x32a1, 0x102: 0x46a4, 0x103: 0x4735, 0x104: 0x2fb3, 0x105: 0x32bf,
+ 0x106: 0x2fc7, 0x107: 0x32d3, 0x108: 0x2fcc, 0x109: 0x32d8, 0x10a: 0x2fd1, 0x10b: 0x32dd,
+ 0x10c: 0x2fd6, 0x10d: 0x32e2, 0x10e: 0x2fe0, 0x10f: 0x32ec,
+ 0x112: 0x46c7, 0x113: 0x4758, 0x114: 0x3008, 0x115: 0x3314, 0x116: 0x300d, 0x117: 0x3319,
+ 0x118: 0x302b, 0x119: 0x3337, 0x11a: 0x301c, 0x11b: 0x3328, 0x11c: 0x3044, 0x11d: 0x3350,
+ 0x11e: 0x304e, 0x11f: 0x335a, 0x120: 0x3053, 0x121: 0x335f, 0x122: 0x305d, 0x123: 0x3369,
+ 0x124: 0x3062, 0x125: 0x336e, 0x128: 0x3094, 0x129: 0x33a5,
+ 0x12a: 0x3099, 0x12b: 0x33aa, 0x12c: 0x309e, 0x12d: 0x33af, 0x12e: 0x30c1, 0x12f: 0x33cd,
+ 0x130: 0x30a3, 0x132: 0x1960, 0x133: 0x19ed, 0x134: 0x30cb, 0x135: 0x33d7,
+ 0x136: 0x30df, 0x137: 0x33f0, 0x139: 0x30e9, 0x13a: 0x33fa, 0x13b: 0x30f3,
+ 0x13c: 0x3404, 0x13d: 0x30ee, 0x13e: 0x33ff, 0x13f: 0x1bb2,
+ // Block 0x5, offset 0x140
+ 0x140: 0x1c3a, 0x143: 0x3116, 0x144: 0x3427, 0x145: 0x312f,
+ 0x146: 0x3440, 0x147: 0x3125, 0x148: 0x3436, 0x149: 0x1c62,
+ 0x14c: 0x46ea, 0x14d: 0x477b, 0x14e: 0x3148, 0x14f: 0x3459, 0x150: 0x3152, 0x151: 0x3463,
+ 0x154: 0x3170, 0x155: 0x3481, 0x156: 0x3189, 0x157: 0x349a,
+ 0x158: 0x317a, 0x159: 0x348b, 0x15a: 0x470d, 0x15b: 0x479e, 0x15c: 0x3193, 0x15d: 0x34a4,
+ 0x15e: 0x31a2, 0x15f: 0x34b3, 0x160: 0x4712, 0x161: 0x47a3, 0x162: 0x31bb, 0x163: 0x34d1,
+ 0x164: 0x31ac, 0x165: 0x34c2, 0x168: 0x471c, 0x169: 0x47ad,
+ 0x16a: 0x4721, 0x16b: 0x47b2, 0x16c: 0x31d9, 0x16d: 0x34ef, 0x16e: 0x31e3, 0x16f: 0x34f9,
+ 0x170: 0x31e8, 0x171: 0x34fe, 0x172: 0x3206, 0x173: 0x351c, 0x174: 0x3229, 0x175: 0x353f,
+ 0x176: 0x3251, 0x177: 0x356c, 0x178: 0x3265, 0x179: 0x3274, 0x17a: 0x3594, 0x17b: 0x327e,
+ 0x17c: 0x359e, 0x17d: 0x3283, 0x17e: 0x35a3, 0x17f: 0x00a7,
+ // Block 0x6, offset 0x180
+ 0x184: 0x2e05, 0x185: 0x2e0b,
+ 0x186: 0x2e11, 0x187: 0x1975, 0x188: 0x1978, 0x189: 0x1a0e, 0x18a: 0x198d, 0x18b: 0x1990,
+ 0x18c: 0x1a44, 0x18d: 0x2f9f, 0x18e: 0x32ab, 0x18f: 0x30ad, 0x190: 0x33b9, 0x191: 0x3157,
+ 0x192: 0x3468, 0x193: 0x31ed, 0x194: 0x3503, 0x195: 0x39e6, 0x196: 0x3b75, 0x197: 0x39df,
+ 0x198: 0x3b6e, 0x199: 0x39ed, 0x19a: 0x3b7c, 0x19b: 0x39d8, 0x19c: 0x3b67,
+ 0x19e: 0x38c7, 0x19f: 0x3a56, 0x1a0: 0x38c0, 0x1a1: 0x3a4f, 0x1a2: 0x35ca, 0x1a3: 0x35dc,
+ 0x1a6: 0x3058, 0x1a7: 0x3364, 0x1a8: 0x30d5, 0x1a9: 0x33e6,
+ 0x1aa: 0x4703, 0x1ab: 0x4794, 0x1ac: 0x39a7, 0x1ad: 0x3b36, 0x1ae: 0x35ee, 0x1af: 0x35f4,
+ 0x1b0: 0x33dc, 0x1b1: 0x1945, 0x1b2: 0x1948, 0x1b3: 0x19d5, 0x1b4: 0x303f, 0x1b5: 0x334b,
+ 0x1b8: 0x3111, 0x1b9: 0x3422, 0x1ba: 0x38ce, 0x1bb: 0x3a5d,
+ 0x1bc: 0x35c4, 0x1bd: 0x35d6, 0x1be: 0x35d0, 0x1bf: 0x35e2,
+ // Block 0x7, offset 0x1c0
+ 0x1c0: 0x2fa4, 0x1c1: 0x32b0, 0x1c2: 0x2fa9, 0x1c3: 0x32b5, 0x1c4: 0x3021, 0x1c5: 0x332d,
+ 0x1c6: 0x3026, 0x1c7: 0x3332, 0x1c8: 0x30b2, 0x1c9: 0x33be, 0x1ca: 0x30b7, 0x1cb: 0x33c3,
+ 0x1cc: 0x315c, 0x1cd: 0x346d, 0x1ce: 0x3161, 0x1cf: 0x3472, 0x1d0: 0x317f, 0x1d1: 0x3490,
+ 0x1d2: 0x3184, 0x1d3: 0x3495, 0x1d4: 0x31f2, 0x1d5: 0x3508, 0x1d6: 0x31f7, 0x1d7: 0x350d,
+ 0x1d8: 0x319d, 0x1d9: 0x34ae, 0x1da: 0x31b6, 0x1db: 0x34cc,
+ 0x1de: 0x3071, 0x1df: 0x337d,
+ 0x1e6: 0x46a9, 0x1e7: 0x473a, 0x1e8: 0x46d1, 0x1e9: 0x4762,
+ 0x1ea: 0x3976, 0x1eb: 0x3b05, 0x1ec: 0x3953, 0x1ed: 0x3ae2, 0x1ee: 0x46ef, 0x1ef: 0x4780,
+ 0x1f0: 0x396f, 0x1f1: 0x3afe, 0x1f2: 0x325b, 0x1f3: 0x3576,
+ // Block 0x8, offset 0x200
+ 0x200: 0x9933, 0x201: 0x9933, 0x202: 0x9933, 0x203: 0x9933, 0x204: 0x9933, 0x205: 0x8133,
+ 0x206: 0x9933, 0x207: 0x9933, 0x208: 0x9933, 0x209: 0x9933, 0x20a: 0x9933, 0x20b: 0x9933,
+ 0x20c: 0x9933, 0x20d: 0x8133, 0x20e: 0x8133, 0x20f: 0x9933, 0x210: 0x8133, 0x211: 0x9933,
+ 0x212: 0x8133, 0x213: 0x9933, 0x214: 0x9933, 0x215: 0x8134, 0x216: 0x812e, 0x217: 0x812e,
+ 0x218: 0x812e, 0x219: 0x812e, 0x21a: 0x8134, 0x21b: 0x992c, 0x21c: 0x812e, 0x21d: 0x812e,
+ 0x21e: 0x812e, 0x21f: 0x812e, 0x220: 0x812e, 0x221: 0x812a, 0x222: 0x812a, 0x223: 0x992e,
+ 0x224: 0x992e, 0x225: 0x992e, 0x226: 0x992e, 0x227: 0x992a, 0x228: 0x992a, 0x229: 0x812e,
+ 0x22a: 0x812e, 0x22b: 0x812e, 0x22c: 0x812e, 0x22d: 0x992e, 0x22e: 0x992e, 0x22f: 0x812e,
+ 0x230: 0x992e, 0x231: 0x992e, 0x232: 0x812e, 0x233: 0x812e, 0x234: 0x8101, 0x235: 0x8101,
+ 0x236: 0x8101, 0x237: 0x8101, 0x238: 0x9901, 0x239: 0x812e, 0x23a: 0x812e, 0x23b: 0x812e,
+ 0x23c: 0x812e, 0x23d: 0x8133, 0x23e: 0x8133, 0x23f: 0x8133,
+ // Block 0x9, offset 0x240
+ 0x240: 0x49c5, 0x241: 0x49ca, 0x242: 0x9933, 0x243: 0x49cf, 0x244: 0x4a88, 0x245: 0x9937,
+ 0x246: 0x8133, 0x247: 0x812e, 0x248: 0x812e, 0x249: 0x812e, 0x24a: 0x8133, 0x24b: 0x8133,
+ 0x24c: 0x8133, 0x24d: 0x812e, 0x24e: 0x812e, 0x250: 0x8133, 0x251: 0x8133,
+ 0x252: 0x8133, 0x253: 0x812e, 0x254: 0x812e, 0x255: 0x812e, 0x256: 0x812e, 0x257: 0x8133,
+ 0x258: 0x8134, 0x259: 0x812e, 0x25a: 0x812e, 0x25b: 0x8133, 0x25c: 0x8135, 0x25d: 0x8136,
+ 0x25e: 0x8136, 0x25f: 0x8135, 0x260: 0x8136, 0x261: 0x8136, 0x262: 0x8135, 0x263: 0x8133,
+ 0x264: 0x8133, 0x265: 0x8133, 0x266: 0x8133, 0x267: 0x8133, 0x268: 0x8133, 0x269: 0x8133,
+ 0x26a: 0x8133, 0x26b: 0x8133, 0x26c: 0x8133, 0x26d: 0x8133, 0x26e: 0x8133, 0x26f: 0x8133,
+ 0x274: 0x0173,
+ 0x27a: 0x42bc,
+ 0x27e: 0x0037,
+ // Block 0xa, offset 0x280
+ 0x284: 0x4271, 0x285: 0x4492,
+ 0x286: 0x3600, 0x287: 0x00ce, 0x288: 0x361e, 0x289: 0x362a, 0x28a: 0x363c,
+ 0x28c: 0x365a, 0x28e: 0x366c, 0x28f: 0x368a, 0x290: 0x3e1f, 0x291: 0xa000,
+ 0x295: 0xa000, 0x297: 0xa000,
+ 0x299: 0xa000,
+ 0x29f: 0xa000, 0x2a1: 0xa000,
+ 0x2a5: 0xa000, 0x2a9: 0xa000,
+ 0x2aa: 0x364e, 0x2ab: 0x367e, 0x2ac: 0x4815, 0x2ad: 0x36ae, 0x2ae: 0x483f, 0x2af: 0x36c0,
+ 0x2b0: 0x3e87, 0x2b1: 0xa000, 0x2b5: 0xa000,
+ 0x2b7: 0xa000, 0x2b9: 0xa000,
+ 0x2bf: 0xa000,
+ // Block 0xb, offset 0x2c0
+ 0x2c1: 0xa000, 0x2c5: 0xa000,
+ 0x2c9: 0xa000, 0x2ca: 0x4857, 0x2cb: 0x4875,
+ 0x2cc: 0x36de, 0x2cd: 0x36f6, 0x2ce: 0x488d, 0x2d0: 0x01c1, 0x2d1: 0x01d3,
+ 0x2d2: 0x01af, 0x2d3: 0x4323, 0x2d4: 0x4329, 0x2d5: 0x01fd, 0x2d6: 0x01eb,
+ 0x2f0: 0x01d9, 0x2f1: 0x01ee, 0x2f2: 0x01f1, 0x2f4: 0x018b, 0x2f5: 0x01ca,
+ 0x2f9: 0x01a9,
+ // Block 0xc, offset 0x300
+ 0x300: 0x3738, 0x301: 0x3744, 0x303: 0x3732,
+ 0x306: 0xa000, 0x307: 0x3720,
+ 0x30c: 0x3774, 0x30d: 0x375c, 0x30e: 0x3786, 0x310: 0xa000,
+ 0x313: 0xa000, 0x315: 0xa000, 0x316: 0xa000, 0x317: 0xa000,
+ 0x318: 0xa000, 0x319: 0x3768, 0x31a: 0xa000,
+ 0x31e: 0xa000, 0x323: 0xa000,
+ 0x327: 0xa000,
+ 0x32b: 0xa000, 0x32d: 0xa000,
+ 0x330: 0xa000, 0x333: 0xa000, 0x335: 0xa000,
+ 0x336: 0xa000, 0x337: 0xa000, 0x338: 0xa000, 0x339: 0x37ec, 0x33a: 0xa000,
+ 0x33e: 0xa000,
+ // Block 0xd, offset 0x340
+ 0x341: 0x374a, 0x342: 0x37ce,
+ 0x350: 0x3726, 0x351: 0x37aa,
+ 0x352: 0x372c, 0x353: 0x37b0, 0x356: 0x373e, 0x357: 0x37c2,
+ 0x358: 0xa000, 0x359: 0xa000, 0x35a: 0x3840, 0x35b: 0x3846, 0x35c: 0x3750, 0x35d: 0x37d4,
+ 0x35e: 0x3756, 0x35f: 0x37da, 0x362: 0x3762, 0x363: 0x37e6,
+ 0x364: 0x376e, 0x365: 0x37f2, 0x366: 0x377a, 0x367: 0x37fe, 0x368: 0xa000, 0x369: 0xa000,
+ 0x36a: 0x384c, 0x36b: 0x3852, 0x36c: 0x37a4, 0x36d: 0x3828, 0x36e: 0x3780, 0x36f: 0x3804,
+ 0x370: 0x378c, 0x371: 0x3810, 0x372: 0x3792, 0x373: 0x3816, 0x374: 0x3798, 0x375: 0x381c,
+ 0x378: 0x379e, 0x379: 0x3822,
+ // Block 0xe, offset 0x380
+ 0x387: 0x1d67,
+ 0x391: 0x812e,
+ 0x392: 0x8133, 0x393: 0x8133, 0x394: 0x8133, 0x395: 0x8133, 0x396: 0x812e, 0x397: 0x8133,
+ 0x398: 0x8133, 0x399: 0x8133, 0x39a: 0x812f, 0x39b: 0x812e, 0x39c: 0x8133, 0x39d: 0x8133,
+ 0x39e: 0x8133, 0x39f: 0x8133, 0x3a0: 0x8133, 0x3a1: 0x8133, 0x3a2: 0x812e, 0x3a3: 0x812e,
+ 0x3a4: 0x812e, 0x3a5: 0x812e, 0x3a6: 0x812e, 0x3a7: 0x812e, 0x3a8: 0x8133, 0x3a9: 0x8133,
+ 0x3aa: 0x812e, 0x3ab: 0x8133, 0x3ac: 0x8133, 0x3ad: 0x812f, 0x3ae: 0x8132, 0x3af: 0x8133,
+ 0x3b0: 0x8106, 0x3b1: 0x8107, 0x3b2: 0x8108, 0x3b3: 0x8109, 0x3b4: 0x810a, 0x3b5: 0x810b,
+ 0x3b6: 0x810c, 0x3b7: 0x810d, 0x3b8: 0x810e, 0x3b9: 0x810f, 0x3ba: 0x810f, 0x3bb: 0x8110,
+ 0x3bc: 0x8111, 0x3bd: 0x8112, 0x3bf: 0x8113,
+ // Block 0xf, offset 0x3c0
+ 0x3c8: 0xa000, 0x3ca: 0xa000, 0x3cb: 0x8117,
+ 0x3cc: 0x8118, 0x3cd: 0x8119, 0x3ce: 0x811a, 0x3cf: 0x811b, 0x3d0: 0x811c, 0x3d1: 0x811d,
+ 0x3d2: 0x811e, 0x3d3: 0x9933, 0x3d4: 0x9933, 0x3d5: 0x992e, 0x3d6: 0x812e, 0x3d7: 0x8133,
+ 0x3d8: 0x8133, 0x3d9: 0x8133, 0x3da: 0x8133, 0x3db: 0x8133, 0x3dc: 0x812e, 0x3dd: 0x8133,
+ 0x3de: 0x8133, 0x3df: 0x812e,
+ 0x3f0: 0x811f, 0x3f5: 0x1d8a,
+ 0x3f6: 0x2019, 0x3f7: 0x2055, 0x3f8: 0x2050,
+ // Block 0x10, offset 0x400
+ 0x413: 0x812e, 0x414: 0x8133, 0x415: 0x8133, 0x416: 0x8133, 0x417: 0x8133,
+ 0x418: 0x8133, 0x419: 0x8133, 0x41a: 0x8133, 0x41b: 0x8133, 0x41c: 0x8133, 0x41d: 0x8133,
+ 0x41e: 0x8133, 0x41f: 0x8133, 0x420: 0x8133, 0x421: 0x8133, 0x423: 0x812e,
+ 0x424: 0x8133, 0x425: 0x8133, 0x426: 0x812e, 0x427: 0x8133, 0x428: 0x8133, 0x429: 0x812e,
+ 0x42a: 0x8133, 0x42b: 0x8133, 0x42c: 0x8133, 0x42d: 0x812e, 0x42e: 0x812e, 0x42f: 0x812e,
+ 0x430: 0x8117, 0x431: 0x8118, 0x432: 0x8119, 0x433: 0x8133, 0x434: 0x8133, 0x435: 0x8133,
+ 0x436: 0x812e, 0x437: 0x8133, 0x438: 0x8133, 0x439: 0x812e, 0x43a: 0x812e, 0x43b: 0x8133,
+ 0x43c: 0x8133, 0x43d: 0x8133, 0x43e: 0x8133, 0x43f: 0x8133,
+ // Block 0x11, offset 0x440
+ 0x445: 0xa000,
+ 0x446: 0x2d33, 0x447: 0xa000, 0x448: 0x2d3b, 0x449: 0xa000, 0x44a: 0x2d43, 0x44b: 0xa000,
+ 0x44c: 0x2d4b, 0x44d: 0xa000, 0x44e: 0x2d53, 0x451: 0xa000,
+ 0x452: 0x2d5b,
+ 0x474: 0x8103, 0x475: 0x9900,
+ 0x47a: 0xa000, 0x47b: 0x2d63,
+ 0x47c: 0xa000, 0x47d: 0x2d6b, 0x47e: 0xa000, 0x47f: 0xa000,
+ // Block 0x12, offset 0x480
+ 0x480: 0x0069, 0x481: 0x006b, 0x482: 0x006f, 0x483: 0x0083, 0x484: 0x00f5, 0x485: 0x00f8,
+ 0x486: 0x0416, 0x487: 0x0085, 0x488: 0x0089, 0x489: 0x008b, 0x48a: 0x0104, 0x48b: 0x0107,
+ 0x48c: 0x010a, 0x48d: 0x008f, 0x48f: 0x0097, 0x490: 0x009b, 0x491: 0x00e0,
+ 0x492: 0x009f, 0x493: 0x00fe, 0x494: 0x041a, 0x495: 0x041e, 0x496: 0x00a1, 0x497: 0x00a9,
+ 0x498: 0x00ab, 0x499: 0x0426, 0x49a: 0x012b, 0x49b: 0x00ad, 0x49c: 0x042a, 0x49d: 0x01c1,
+ 0x49e: 0x01c4, 0x49f: 0x01c7, 0x4a0: 0x01fd, 0x4a1: 0x0200, 0x4a2: 0x0093, 0x4a3: 0x00a5,
+ 0x4a4: 0x00ab, 0x4a5: 0x00ad, 0x4a6: 0x01c1, 0x4a7: 0x01c4, 0x4a8: 0x01ee, 0x4a9: 0x01fd,
+ 0x4aa: 0x0200,
+ 0x4b8: 0x020f,
+ // Block 0x13, offset 0x4c0
+ 0x4db: 0x00fb, 0x4dc: 0x0087, 0x4dd: 0x0101,
+ 0x4de: 0x00d4, 0x4df: 0x010a, 0x4e0: 0x008d, 0x4e1: 0x010d, 0x4e2: 0x0110, 0x4e3: 0x0116,
+ 0x4e4: 0x011c, 0x4e5: 0x011f, 0x4e6: 0x0122, 0x4e7: 0x042e, 0x4e8: 0x016d, 0x4e9: 0x0128,
+ 0x4ea: 0x0432, 0x4eb: 0x0170, 0x4ec: 0x0131, 0x4ed: 0x012e, 0x4ee: 0x0134, 0x4ef: 0x0137,
+ 0x4f0: 0x013a, 0x4f1: 0x013d, 0x4f2: 0x0140, 0x4f3: 0x014c, 0x4f4: 0x014f, 0x4f5: 0x00ec,
+ 0x4f6: 0x0152, 0x4f7: 0x0155, 0x4f8: 0x0422, 0x4f9: 0x0158, 0x4fa: 0x015b, 0x4fb: 0x00b5,
+ 0x4fc: 0x0161, 0x4fd: 0x0164, 0x4fe: 0x0167, 0x4ff: 0x01d3,
+ // Block 0x14, offset 0x500
+ 0x500: 0x8133, 0x501: 0x8133, 0x502: 0x812e, 0x503: 0x8133, 0x504: 0x8133, 0x505: 0x8133,
+ 0x506: 0x8133, 0x507: 0x8133, 0x508: 0x8133, 0x509: 0x8133, 0x50a: 0x812e, 0x50b: 0x8133,
+ 0x50c: 0x8133, 0x50d: 0x8136, 0x50e: 0x812b, 0x50f: 0x812e, 0x510: 0x812a, 0x511: 0x8133,
+ 0x512: 0x8133, 0x513: 0x8133, 0x514: 0x8133, 0x515: 0x8133, 0x516: 0x8133, 0x517: 0x8133,
+ 0x518: 0x8133, 0x519: 0x8133, 0x51a: 0x8133, 0x51b: 0x8133, 0x51c: 0x8133, 0x51d: 0x8133,
+ 0x51e: 0x8133, 0x51f: 0x8133, 0x520: 0x8133, 0x521: 0x8133, 0x522: 0x8133, 0x523: 0x8133,
+ 0x524: 0x8133, 0x525: 0x8133, 0x526: 0x8133, 0x527: 0x8133, 0x528: 0x8133, 0x529: 0x8133,
+ 0x52a: 0x8133, 0x52b: 0x8133, 0x52c: 0x8133, 0x52d: 0x8133, 0x52e: 0x8133, 0x52f: 0x8133,
+ 0x530: 0x8133, 0x531: 0x8133, 0x532: 0x8133, 0x533: 0x8133, 0x534: 0x8133, 0x535: 0x8133,
+ 0x536: 0x8134, 0x537: 0x8132, 0x538: 0x8132, 0x539: 0x812e, 0x53b: 0x8133,
+ 0x53c: 0x8135, 0x53d: 0x812e, 0x53e: 0x8133, 0x53f: 0x812e,
+ // Block 0x15, offset 0x540
+ 0x540: 0x2fae, 0x541: 0x32ba, 0x542: 0x2fb8, 0x543: 0x32c4, 0x544: 0x2fbd, 0x545: 0x32c9,
+ 0x546: 0x2fc2, 0x547: 0x32ce, 0x548: 0x38e3, 0x549: 0x3a72, 0x54a: 0x2fdb, 0x54b: 0x32e7,
+ 0x54c: 0x2fe5, 0x54d: 0x32f1, 0x54e: 0x2ff4, 0x54f: 0x3300, 0x550: 0x2fea, 0x551: 0x32f6,
+ 0x552: 0x2fef, 0x553: 0x32fb, 0x554: 0x3906, 0x555: 0x3a95, 0x556: 0x390d, 0x557: 0x3a9c,
+ 0x558: 0x3030, 0x559: 0x333c, 0x55a: 0x3035, 0x55b: 0x3341, 0x55c: 0x391b, 0x55d: 0x3aaa,
+ 0x55e: 0x303a, 0x55f: 0x3346, 0x560: 0x3049, 0x561: 0x3355, 0x562: 0x3067, 0x563: 0x3373,
+ 0x564: 0x3076, 0x565: 0x3382, 0x566: 0x306c, 0x567: 0x3378, 0x568: 0x307b, 0x569: 0x3387,
+ 0x56a: 0x3080, 0x56b: 0x338c, 0x56c: 0x30c6, 0x56d: 0x33d2, 0x56e: 0x3922, 0x56f: 0x3ab1,
+ 0x570: 0x30d0, 0x571: 0x33e1, 0x572: 0x30da, 0x573: 0x33eb, 0x574: 0x30e4, 0x575: 0x33f5,
+ 0x576: 0x46db, 0x577: 0x476c, 0x578: 0x3929, 0x579: 0x3ab8, 0x57a: 0x30fd, 0x57b: 0x340e,
+ 0x57c: 0x30f8, 0x57d: 0x3409, 0x57e: 0x3102, 0x57f: 0x3413,
+ // Block 0x16, offset 0x580
+ 0x580: 0x3107, 0x581: 0x3418, 0x582: 0x310c, 0x583: 0x341d, 0x584: 0x3120, 0x585: 0x3431,
+ 0x586: 0x312a, 0x587: 0x343b, 0x588: 0x3139, 0x589: 0x344a, 0x58a: 0x3134, 0x58b: 0x3445,
+ 0x58c: 0x394c, 0x58d: 0x3adb, 0x58e: 0x395a, 0x58f: 0x3ae9, 0x590: 0x3961, 0x591: 0x3af0,
+ 0x592: 0x3968, 0x593: 0x3af7, 0x594: 0x3166, 0x595: 0x3477, 0x596: 0x316b, 0x597: 0x347c,
+ 0x598: 0x3175, 0x599: 0x3486, 0x59a: 0x4708, 0x59b: 0x4799, 0x59c: 0x39ae, 0x59d: 0x3b3d,
+ 0x59e: 0x318e, 0x59f: 0x349f, 0x5a0: 0x3198, 0x5a1: 0x34a9, 0x5a2: 0x4717, 0x5a3: 0x47a8,
+ 0x5a4: 0x39b5, 0x5a5: 0x3b44, 0x5a6: 0x39bc, 0x5a7: 0x3b4b, 0x5a8: 0x39c3, 0x5a9: 0x3b52,
+ 0x5aa: 0x31a7, 0x5ab: 0x34b8, 0x5ac: 0x31b1, 0x5ad: 0x34c7, 0x5ae: 0x31c5, 0x5af: 0x34db,
+ 0x5b0: 0x31c0, 0x5b1: 0x34d6, 0x5b2: 0x3201, 0x5b3: 0x3517, 0x5b4: 0x3210, 0x5b5: 0x3526,
+ 0x5b6: 0x320b, 0x5b7: 0x3521, 0x5b8: 0x39ca, 0x5b9: 0x3b59, 0x5ba: 0x39d1, 0x5bb: 0x3b60,
+ 0x5bc: 0x3215, 0x5bd: 0x352b, 0x5be: 0x321a, 0x5bf: 0x3530,
+ // Block 0x17, offset 0x5c0
+ 0x5c0: 0x321f, 0x5c1: 0x3535, 0x5c2: 0x3224, 0x5c3: 0x353a, 0x5c4: 0x3233, 0x5c5: 0x3549,
+ 0x5c6: 0x322e, 0x5c7: 0x3544, 0x5c8: 0x3238, 0x5c9: 0x3553, 0x5ca: 0x323d, 0x5cb: 0x3558,
+ 0x5cc: 0x3242, 0x5cd: 0x355d, 0x5ce: 0x3260, 0x5cf: 0x357b, 0x5d0: 0x3279, 0x5d1: 0x3599,
+ 0x5d2: 0x3288, 0x5d3: 0x35a8, 0x5d4: 0x328d, 0x5d5: 0x35ad, 0x5d6: 0x3391, 0x5d7: 0x34bd,
+ 0x5d8: 0x354e, 0x5d9: 0x358a, 0x5da: 0x1be6, 0x5db: 0x42ee,
+ 0x5e0: 0x46b8, 0x5e1: 0x4749, 0x5e2: 0x2f9a, 0x5e3: 0x32a6,
+ 0x5e4: 0x388f, 0x5e5: 0x3a1e, 0x5e6: 0x3888, 0x5e7: 0x3a17, 0x5e8: 0x389d, 0x5e9: 0x3a2c,
+ 0x5ea: 0x3896, 0x5eb: 0x3a25, 0x5ec: 0x38d5, 0x5ed: 0x3a64, 0x5ee: 0x38ab, 0x5ef: 0x3a3a,
+ 0x5f0: 0x38a4, 0x5f1: 0x3a33, 0x5f2: 0x38b9, 0x5f3: 0x3a48, 0x5f4: 0x38b2, 0x5f5: 0x3a41,
+ 0x5f6: 0x38dc, 0x5f7: 0x3a6b, 0x5f8: 0x46cc, 0x5f9: 0x475d, 0x5fa: 0x3017, 0x5fb: 0x3323,
+ 0x5fc: 0x3003, 0x5fd: 0x330f, 0x5fe: 0x38f1, 0x5ff: 0x3a80,
+ // Block 0x18, offset 0x600
+ 0x600: 0x38ea, 0x601: 0x3a79, 0x602: 0x38ff, 0x603: 0x3a8e, 0x604: 0x38f8, 0x605: 0x3a87,
+ 0x606: 0x3914, 0x607: 0x3aa3, 0x608: 0x30a8, 0x609: 0x33b4, 0x60a: 0x30bc, 0x60b: 0x33c8,
+ 0x60c: 0x46fe, 0x60d: 0x478f, 0x60e: 0x314d, 0x60f: 0x345e, 0x610: 0x3937, 0x611: 0x3ac6,
+ 0x612: 0x3930, 0x613: 0x3abf, 0x614: 0x3945, 0x615: 0x3ad4, 0x616: 0x393e, 0x617: 0x3acd,
+ 0x618: 0x39a0, 0x619: 0x3b2f, 0x61a: 0x3984, 0x61b: 0x3b13, 0x61c: 0x397d, 0x61d: 0x3b0c,
+ 0x61e: 0x3992, 0x61f: 0x3b21, 0x620: 0x398b, 0x621: 0x3b1a, 0x622: 0x3999, 0x623: 0x3b28,
+ 0x624: 0x31fc, 0x625: 0x3512, 0x626: 0x31de, 0x627: 0x34f4, 0x628: 0x39fb, 0x629: 0x3b8a,
+ 0x62a: 0x39f4, 0x62b: 0x3b83, 0x62c: 0x3a09, 0x62d: 0x3b98, 0x62e: 0x3a02, 0x62f: 0x3b91,
+ 0x630: 0x3a10, 0x631: 0x3b9f, 0x632: 0x3247, 0x633: 0x3562, 0x634: 0x326f, 0x635: 0x358f,
+ 0x636: 0x326a, 0x637: 0x3585, 0x638: 0x3256, 0x639: 0x3571,
+ // Block 0x19, offset 0x640
+ 0x640: 0x481b, 0x641: 0x4821, 0x642: 0x4935, 0x643: 0x494d, 0x644: 0x493d, 0x645: 0x4955,
+ 0x646: 0x4945, 0x647: 0x495d, 0x648: 0x47c1, 0x649: 0x47c7, 0x64a: 0x48a5, 0x64b: 0x48bd,
+ 0x64c: 0x48ad, 0x64d: 0x48c5, 0x64e: 0x48b5, 0x64f: 0x48cd, 0x650: 0x482d, 0x651: 0x4833,
+ 0x652: 0x3dcf, 0x653: 0x3ddf, 0x654: 0x3dd7, 0x655: 0x3de7,
+ 0x658: 0x47cd, 0x659: 0x47d3, 0x65a: 0x3cff, 0x65b: 0x3d0f, 0x65c: 0x3d07, 0x65d: 0x3d17,
+ 0x660: 0x4845, 0x661: 0x484b, 0x662: 0x4965, 0x663: 0x497d,
+ 0x664: 0x496d, 0x665: 0x4985, 0x666: 0x4975, 0x667: 0x498d, 0x668: 0x47d9, 0x669: 0x47df,
+ 0x66a: 0x48d5, 0x66b: 0x48ed, 0x66c: 0x48dd, 0x66d: 0x48f5, 0x66e: 0x48e5, 0x66f: 0x48fd,
+ 0x670: 0x485d, 0x671: 0x4863, 0x672: 0x3e2f, 0x673: 0x3e47, 0x674: 0x3e37, 0x675: 0x3e4f,
+ 0x676: 0x3e3f, 0x677: 0x3e57, 0x678: 0x47e5, 0x679: 0x47eb, 0x67a: 0x3d2f, 0x67b: 0x3d47,
+ 0x67c: 0x3d37, 0x67d: 0x3d4f, 0x67e: 0x3d3f, 0x67f: 0x3d57,
+ // Block 0x1a, offset 0x680
+ 0x680: 0x4869, 0x681: 0x486f, 0x682: 0x3e5f, 0x683: 0x3e6f, 0x684: 0x3e67, 0x685: 0x3e77,
+ 0x688: 0x47f1, 0x689: 0x47f7, 0x68a: 0x3d5f, 0x68b: 0x3d6f,
+ 0x68c: 0x3d67, 0x68d: 0x3d77, 0x690: 0x487b, 0x691: 0x4881,
+ 0x692: 0x3e97, 0x693: 0x3eaf, 0x694: 0x3e9f, 0x695: 0x3eb7, 0x696: 0x3ea7, 0x697: 0x3ebf,
+ 0x699: 0x47fd, 0x69b: 0x3d7f, 0x69d: 0x3d87,
+ 0x69f: 0x3d8f, 0x6a0: 0x4893, 0x6a1: 0x4899, 0x6a2: 0x4995, 0x6a3: 0x49ad,
+ 0x6a4: 0x499d, 0x6a5: 0x49b5, 0x6a6: 0x49a5, 0x6a7: 0x49bd, 0x6a8: 0x4803, 0x6a9: 0x4809,
+ 0x6aa: 0x4905, 0x6ab: 0x491d, 0x6ac: 0x490d, 0x6ad: 0x4925, 0x6ae: 0x4915, 0x6af: 0x492d,
+ 0x6b0: 0x480f, 0x6b1: 0x4335, 0x6b2: 0x36a8, 0x6b3: 0x433b, 0x6b4: 0x4839, 0x6b5: 0x4341,
+ 0x6b6: 0x36ba, 0x6b7: 0x4347, 0x6b8: 0x36d8, 0x6b9: 0x434d, 0x6ba: 0x36f0, 0x6bb: 0x4353,
+ 0x6bc: 0x4887, 0x6bd: 0x4359,
+ // Block 0x1b, offset 0x6c0
+ 0x6c0: 0x3db7, 0x6c1: 0x3dbf, 0x6c2: 0x419b, 0x6c3: 0x41b9, 0x6c4: 0x41a5, 0x6c5: 0x41c3,
+ 0x6c6: 0x41af, 0x6c7: 0x41cd, 0x6c8: 0x3cef, 0x6c9: 0x3cf7, 0x6ca: 0x40e7, 0x6cb: 0x4105,
+ 0x6cc: 0x40f1, 0x6cd: 0x410f, 0x6ce: 0x40fb, 0x6cf: 0x4119, 0x6d0: 0x3dff, 0x6d1: 0x3e07,
+ 0x6d2: 0x41d7, 0x6d3: 0x41f5, 0x6d4: 0x41e1, 0x6d5: 0x41ff, 0x6d6: 0x41eb, 0x6d7: 0x4209,
+ 0x6d8: 0x3d1f, 0x6d9: 0x3d27, 0x6da: 0x4123, 0x6db: 0x4141, 0x6dc: 0x412d, 0x6dd: 0x414b,
+ 0x6de: 0x4137, 0x6df: 0x4155, 0x6e0: 0x3ed7, 0x6e1: 0x3edf, 0x6e2: 0x4213, 0x6e3: 0x4231,
+ 0x6e4: 0x421d, 0x6e5: 0x423b, 0x6e6: 0x4227, 0x6e7: 0x4245, 0x6e8: 0x3d97, 0x6e9: 0x3d9f,
+ 0x6ea: 0x415f, 0x6eb: 0x417d, 0x6ec: 0x4169, 0x6ed: 0x4187, 0x6ee: 0x4173, 0x6ef: 0x4191,
+ 0x6f0: 0x369c, 0x6f1: 0x3696, 0x6f2: 0x3da7, 0x6f3: 0x36a2, 0x6f4: 0x3daf,
+ 0x6f6: 0x4827, 0x6f7: 0x3dc7, 0x6f8: 0x360c, 0x6f9: 0x3606, 0x6fa: 0x35fa, 0x6fb: 0x4305,
+ 0x6fc: 0x3612, 0x6fd: 0x429e, 0x6fe: 0x01d6, 0x6ff: 0x429e,
+ // Block 0x1c, offset 0x700
+ 0x700: 0x42b7, 0x701: 0x4499, 0x702: 0x3def, 0x703: 0x36b4, 0x704: 0x3df7,
+ 0x706: 0x4851, 0x707: 0x3e0f, 0x708: 0x3618, 0x709: 0x430b, 0x70a: 0x3624, 0x70b: 0x4311,
+ 0x70c: 0x3630, 0x70d: 0x44a0, 0x70e: 0x44a7, 0x70f: 0x44ae, 0x710: 0x36cc, 0x711: 0x36c6,
+ 0x712: 0x3e17, 0x713: 0x44fb, 0x716: 0x36d2, 0x717: 0x3e27,
+ 0x718: 0x3648, 0x719: 0x3642, 0x71a: 0x3636, 0x71b: 0x4317, 0x71d: 0x44b5,
+ 0x71e: 0x44bc, 0x71f: 0x44c3, 0x720: 0x3702, 0x721: 0x36fc, 0x722: 0x3e7f, 0x723: 0x4503,
+ 0x724: 0x36e4, 0x725: 0x36ea, 0x726: 0x3708, 0x727: 0x3e8f, 0x728: 0x3678, 0x729: 0x3672,
+ 0x72a: 0x3666, 0x72b: 0x4323, 0x72c: 0x3660, 0x72d: 0x448b, 0x72e: 0x4492, 0x72f: 0x0081,
+ 0x732: 0x3ec7, 0x733: 0x370e, 0x734: 0x3ecf,
+ 0x736: 0x489f, 0x737: 0x3ee7, 0x738: 0x3654, 0x739: 0x431d, 0x73a: 0x3684, 0x73b: 0x432f,
+ 0x73c: 0x3690, 0x73d: 0x4271, 0x73e: 0x42a3,
+ // Block 0x1d, offset 0x740
+ 0x740: 0x1bde, 0x741: 0x1be2, 0x742: 0x0047, 0x743: 0x1c5a, 0x745: 0x1bee,
+ 0x746: 0x1bf2, 0x747: 0x00e9, 0x749: 0x1c5e, 0x74a: 0x008f, 0x74b: 0x0051,
+ 0x74c: 0x0051, 0x74d: 0x0051, 0x74e: 0x0091, 0x74f: 0x00da, 0x750: 0x0053, 0x751: 0x0053,
+ 0x752: 0x0059, 0x753: 0x0099, 0x755: 0x005d, 0x756: 0x1993,
+ 0x759: 0x0061, 0x75a: 0x0063, 0x75b: 0x0065, 0x75c: 0x0065, 0x75d: 0x0065,
+ 0x760: 0x19a5, 0x761: 0x1bce, 0x762: 0x19ae,
+ 0x764: 0x0075, 0x766: 0x01bb, 0x768: 0x0075,
+ 0x76a: 0x0057, 0x76b: 0x42e9, 0x76c: 0x0045, 0x76d: 0x0047, 0x76f: 0x008b,
+ 0x770: 0x004b, 0x771: 0x004d, 0x773: 0x005b, 0x774: 0x009f, 0x775: 0x0218,
+ 0x776: 0x021b, 0x777: 0x021e, 0x778: 0x0221, 0x779: 0x0093, 0x77b: 0x1b9e,
+ 0x77c: 0x01eb, 0x77d: 0x01c4, 0x77e: 0x017c, 0x77f: 0x01a3,
+ // Block 0x1e, offset 0x780
+ 0x780: 0x0466, 0x785: 0x0049,
+ 0x786: 0x0089, 0x787: 0x008b, 0x788: 0x0093, 0x789: 0x0095,
+ 0x790: 0x2234, 0x791: 0x2240,
+ 0x792: 0x22f4, 0x793: 0x221c, 0x794: 0x22a0, 0x795: 0x2228, 0x796: 0x22a6, 0x797: 0x22be,
+ 0x798: 0x22ca, 0x799: 0x222e, 0x79a: 0x22d0, 0x79b: 0x223a, 0x79c: 0x22c4, 0x79d: 0x22d6,
+ 0x79e: 0x22dc, 0x79f: 0x1cc2, 0x7a0: 0x0053, 0x7a1: 0x195d, 0x7a2: 0x1baa, 0x7a3: 0x1966,
+ 0x7a4: 0x006d, 0x7a5: 0x19b1, 0x7a6: 0x1bd6, 0x7a7: 0x1d4e, 0x7a8: 0x1969, 0x7a9: 0x0071,
+ 0x7aa: 0x19bd, 0x7ab: 0x1bda, 0x7ac: 0x0059, 0x7ad: 0x0047, 0x7ae: 0x0049, 0x7af: 0x005b,
+ 0x7b0: 0x0093, 0x7b1: 0x19ea, 0x7b2: 0x1c1e, 0x7b3: 0x19f3, 0x7b4: 0x00ad, 0x7b5: 0x1a68,
+ 0x7b6: 0x1c52, 0x7b7: 0x1d62, 0x7b8: 0x19f6, 0x7b9: 0x00b1, 0x7ba: 0x1a6b, 0x7bb: 0x1c56,
+ 0x7bc: 0x0099, 0x7bd: 0x0087, 0x7be: 0x0089, 0x7bf: 0x009b,
+ // Block 0x1f, offset 0x7c0
+ 0x7c1: 0x3c1d, 0x7c3: 0xa000, 0x7c4: 0x3c24, 0x7c5: 0xa000,
+ 0x7c7: 0x3c2b, 0x7c8: 0xa000, 0x7c9: 0x3c32,
+ 0x7cd: 0xa000,
+ 0x7e0: 0x2f7c, 0x7e1: 0xa000, 0x7e2: 0x3c40,
+ 0x7e4: 0xa000, 0x7e5: 0xa000,
+ 0x7ed: 0x3c39, 0x7ee: 0x2f77, 0x7ef: 0x2f81,
+ 0x7f0: 0x3c47, 0x7f1: 0x3c4e, 0x7f2: 0xa000, 0x7f3: 0xa000, 0x7f4: 0x3c55, 0x7f5: 0x3c5c,
+ 0x7f6: 0xa000, 0x7f7: 0xa000, 0x7f8: 0x3c63, 0x7f9: 0x3c6a, 0x7fa: 0xa000, 0x7fb: 0xa000,
+ 0x7fc: 0xa000, 0x7fd: 0xa000,
+ // Block 0x20, offset 0x800
+ 0x800: 0x3c71, 0x801: 0x3c78, 0x802: 0xa000, 0x803: 0xa000, 0x804: 0x3c8d, 0x805: 0x3c94,
+ 0x806: 0xa000, 0x807: 0xa000, 0x808: 0x3c9b, 0x809: 0x3ca2,
+ 0x811: 0xa000,
+ 0x812: 0xa000,
+ 0x822: 0xa000,
+ 0x828: 0xa000, 0x829: 0xa000,
+ 0x82b: 0xa000, 0x82c: 0x3cb7, 0x82d: 0x3cbe, 0x82e: 0x3cc5, 0x82f: 0x3ccc,
+ 0x832: 0xa000, 0x833: 0xa000, 0x834: 0xa000, 0x835: 0xa000,
+ // Block 0x21, offset 0x840
+ 0x860: 0x0023, 0x861: 0x0025, 0x862: 0x0027, 0x863: 0x0029,
+ 0x864: 0x002b, 0x865: 0x002d, 0x866: 0x002f, 0x867: 0x0031, 0x868: 0x0033, 0x869: 0x1885,
+ 0x86a: 0x1888, 0x86b: 0x188b, 0x86c: 0x188e, 0x86d: 0x1891, 0x86e: 0x1894, 0x86f: 0x1897,
+ 0x870: 0x189a, 0x871: 0x189d, 0x872: 0x18a0, 0x873: 0x18a9, 0x874: 0x1a6e, 0x875: 0x1a72,
+ 0x876: 0x1a76, 0x877: 0x1a7a, 0x878: 0x1a7e, 0x879: 0x1a82, 0x87a: 0x1a86, 0x87b: 0x1a8a,
+ 0x87c: 0x1a8e, 0x87d: 0x1c86, 0x87e: 0x1c8b, 0x87f: 0x1c90,
+ // Block 0x22, offset 0x880
+ 0x880: 0x1c95, 0x881: 0x1c9a, 0x882: 0x1c9f, 0x883: 0x1ca4, 0x884: 0x1ca9, 0x885: 0x1cae,
+ 0x886: 0x1cb3, 0x887: 0x1cb8, 0x888: 0x1882, 0x889: 0x18a6, 0x88a: 0x18ca, 0x88b: 0x18ee,
+ 0x88c: 0x1912, 0x88d: 0x191b, 0x88e: 0x1921, 0x88f: 0x1927, 0x890: 0x192d, 0x891: 0x1b66,
+ 0x892: 0x1b6a, 0x893: 0x1b6e, 0x894: 0x1b72, 0x895: 0x1b76, 0x896: 0x1b7a, 0x897: 0x1b7e,
+ 0x898: 0x1b82, 0x899: 0x1b86, 0x89a: 0x1b8a, 0x89b: 0x1b8e, 0x89c: 0x1afa, 0x89d: 0x1afe,
+ 0x89e: 0x1b02, 0x89f: 0x1b06, 0x8a0: 0x1b0a, 0x8a1: 0x1b0e, 0x8a2: 0x1b12, 0x8a3: 0x1b16,
+ 0x8a4: 0x1b1a, 0x8a5: 0x1b1e, 0x8a6: 0x1b22, 0x8a7: 0x1b26, 0x8a8: 0x1b2a, 0x8a9: 0x1b2e,
+ 0x8aa: 0x1b32, 0x8ab: 0x1b36, 0x8ac: 0x1b3a, 0x8ad: 0x1b3e, 0x8ae: 0x1b42, 0x8af: 0x1b46,
+ 0x8b0: 0x1b4a, 0x8b1: 0x1b4e, 0x8b2: 0x1b52, 0x8b3: 0x1b56, 0x8b4: 0x1b5a, 0x8b5: 0x1b5e,
+ 0x8b6: 0x0043, 0x8b7: 0x0045, 0x8b8: 0x0047, 0x8b9: 0x0049, 0x8ba: 0x004b, 0x8bb: 0x004d,
+ 0x8bc: 0x004f, 0x8bd: 0x0051, 0x8be: 0x0053, 0x8bf: 0x0055,
+ // Block 0x23, offset 0x8c0
+ 0x8c0: 0x06c2, 0x8c1: 0x06e6, 0x8c2: 0x06f2, 0x8c3: 0x0702, 0x8c4: 0x070a, 0x8c5: 0x0716,
+ 0x8c6: 0x071e, 0x8c7: 0x0726, 0x8c8: 0x0732, 0x8c9: 0x0786, 0x8ca: 0x079e, 0x8cb: 0x07ae,
+ 0x8cc: 0x07be, 0x8cd: 0x07ce, 0x8ce: 0x07de, 0x8cf: 0x07fe, 0x8d0: 0x0802, 0x8d1: 0x0806,
+ 0x8d2: 0x083a, 0x8d3: 0x0862, 0x8d4: 0x0872, 0x8d5: 0x087a, 0x8d6: 0x087e, 0x8d7: 0x088a,
+ 0x8d8: 0x08a6, 0x8d9: 0x08aa, 0x8da: 0x08c2, 0x8db: 0x08c6, 0x8dc: 0x08ce, 0x8dd: 0x08de,
+ 0x8de: 0x097a, 0x8df: 0x098e, 0x8e0: 0x09ce, 0x8e1: 0x09e2, 0x8e2: 0x09ea, 0x8e3: 0x09ee,
+ 0x8e4: 0x09fe, 0x8e5: 0x0a1a, 0x8e6: 0x0a46, 0x8e7: 0x0a52, 0x8e8: 0x0a72, 0x8e9: 0x0a7e,
+ 0x8ea: 0x0a82, 0x8eb: 0x0a86, 0x8ec: 0x0a9e, 0x8ed: 0x0aa2, 0x8ee: 0x0ace, 0x8ef: 0x0ada,
+ 0x8f0: 0x0ae2, 0x8f1: 0x0aea, 0x8f2: 0x0afa, 0x8f3: 0x0b02, 0x8f4: 0x0b0a, 0x8f5: 0x0b36,
+ 0x8f6: 0x0b3a, 0x8f7: 0x0b42, 0x8f8: 0x0b46, 0x8f9: 0x0b4e, 0x8fa: 0x0b56, 0x8fb: 0x0b66,
+ 0x8fc: 0x0b82, 0x8fd: 0x0bfa, 0x8fe: 0x0c0e, 0x8ff: 0x0c12,
+ // Block 0x24, offset 0x900
+ 0x900: 0x0c92, 0x901: 0x0c96, 0x902: 0x0caa, 0x903: 0x0cae, 0x904: 0x0cb6, 0x905: 0x0cbe,
+ 0x906: 0x0cc6, 0x907: 0x0cd2, 0x908: 0x0cfa, 0x909: 0x0d0a, 0x90a: 0x0d1e, 0x90b: 0x0d8e,
+ 0x90c: 0x0d9a, 0x90d: 0x0daa, 0x90e: 0x0db6, 0x90f: 0x0dc2, 0x910: 0x0dca, 0x911: 0x0dce,
+ 0x912: 0x0dd2, 0x913: 0x0dd6, 0x914: 0x0dda, 0x915: 0x0e92, 0x916: 0x0eda, 0x917: 0x0ee6,
+ 0x918: 0x0eea, 0x919: 0x0eee, 0x91a: 0x0ef2, 0x91b: 0x0efa, 0x91c: 0x0efe, 0x91d: 0x0f12,
+ 0x91e: 0x0f2e, 0x91f: 0x0f36, 0x920: 0x0f76, 0x921: 0x0f7a, 0x922: 0x0f82, 0x923: 0x0f86,
+ 0x924: 0x0f8e, 0x925: 0x0f92, 0x926: 0x0fb6, 0x927: 0x0fba, 0x928: 0x0fd6, 0x929: 0x0fda,
+ 0x92a: 0x0fde, 0x92b: 0x0fe2, 0x92c: 0x0ff6, 0x92d: 0x101a, 0x92e: 0x101e, 0x92f: 0x1022,
+ 0x930: 0x1046, 0x931: 0x1086, 0x932: 0x108a, 0x933: 0x10aa, 0x934: 0x10ba, 0x935: 0x10c2,
+ 0x936: 0x10e2, 0x937: 0x1106, 0x938: 0x114a, 0x939: 0x1152, 0x93a: 0x1166, 0x93b: 0x1172,
+ 0x93c: 0x117a, 0x93d: 0x1182, 0x93e: 0x1186, 0x93f: 0x118a,
+ // Block 0x25, offset 0x940
+ 0x940: 0x11a2, 0x941: 0x11a6, 0x942: 0x11c2, 0x943: 0x11ca, 0x944: 0x11d2, 0x945: 0x11d6,
+ 0x946: 0x11e2, 0x947: 0x11ea, 0x948: 0x11ee, 0x949: 0x11f2, 0x94a: 0x11fa, 0x94b: 0x11fe,
+ 0x94c: 0x129e, 0x94d: 0x12b2, 0x94e: 0x12e6, 0x94f: 0x12ea, 0x950: 0x12f2, 0x951: 0x131e,
+ 0x952: 0x1326, 0x953: 0x132e, 0x954: 0x1336, 0x955: 0x1372, 0x956: 0x1376, 0x957: 0x137e,
+ 0x958: 0x1382, 0x959: 0x1386, 0x95a: 0x13b2, 0x95b: 0x13b6, 0x95c: 0x13be, 0x95d: 0x13d2,
+ 0x95e: 0x13d6, 0x95f: 0x13f2, 0x960: 0x13fa, 0x961: 0x13fe, 0x962: 0x1422, 0x963: 0x1442,
+ 0x964: 0x1456, 0x965: 0x145a, 0x966: 0x1462, 0x967: 0x148e, 0x968: 0x1492, 0x969: 0x14a2,
+ 0x96a: 0x14c6, 0x96b: 0x14d2, 0x96c: 0x14e2, 0x96d: 0x14fa, 0x96e: 0x1502, 0x96f: 0x1506,
+ 0x970: 0x150a, 0x971: 0x150e, 0x972: 0x151a, 0x973: 0x151e, 0x974: 0x1526, 0x975: 0x1542,
+ 0x976: 0x1546, 0x977: 0x154a, 0x978: 0x1562, 0x979: 0x1566, 0x97a: 0x156e, 0x97b: 0x1582,
+ 0x97c: 0x1586, 0x97d: 0x158a, 0x97e: 0x1592, 0x97f: 0x1596,
+ // Block 0x26, offset 0x980
+ 0x986: 0xa000, 0x98b: 0xa000,
+ 0x98c: 0x3f1f, 0x98d: 0xa000, 0x98e: 0x3f27, 0x98f: 0xa000, 0x990: 0x3f2f, 0x991: 0xa000,
+ 0x992: 0x3f37, 0x993: 0xa000, 0x994: 0x3f3f, 0x995: 0xa000, 0x996: 0x3f47, 0x997: 0xa000,
+ 0x998: 0x3f4f, 0x999: 0xa000, 0x99a: 0x3f57, 0x99b: 0xa000, 0x99c: 0x3f5f, 0x99d: 0xa000,
+ 0x99e: 0x3f67, 0x99f: 0xa000, 0x9a0: 0x3f6f, 0x9a1: 0xa000, 0x9a2: 0x3f77,
+ 0x9a4: 0xa000, 0x9a5: 0x3f7f, 0x9a6: 0xa000, 0x9a7: 0x3f87, 0x9a8: 0xa000, 0x9a9: 0x3f8f,
+ 0x9af: 0xa000,
+ 0x9b0: 0x3f97, 0x9b1: 0x3f9f, 0x9b2: 0xa000, 0x9b3: 0x3fa7, 0x9b4: 0x3faf, 0x9b5: 0xa000,
+ 0x9b6: 0x3fb7, 0x9b7: 0x3fbf, 0x9b8: 0xa000, 0x9b9: 0x3fc7, 0x9ba: 0x3fcf, 0x9bb: 0xa000,
+ 0x9bc: 0x3fd7, 0x9bd: 0x3fdf,
+ // Block 0x27, offset 0x9c0
+ 0x9d4: 0x3f17,
+ 0x9d9: 0x9904, 0x9da: 0x9904, 0x9db: 0x42f3, 0x9dc: 0x42f9, 0x9dd: 0xa000,
+ 0x9de: 0x3fe7, 0x9df: 0x26ba,
+ 0x9e6: 0xa000,
+ 0x9eb: 0xa000, 0x9ec: 0x3ff7, 0x9ed: 0xa000, 0x9ee: 0x3fff, 0x9ef: 0xa000,
+ 0x9f0: 0x4007, 0x9f1: 0xa000, 0x9f2: 0x400f, 0x9f3: 0xa000, 0x9f4: 0x4017, 0x9f5: 0xa000,
+ 0x9f6: 0x401f, 0x9f7: 0xa000, 0x9f8: 0x4027, 0x9f9: 0xa000, 0x9fa: 0x402f, 0x9fb: 0xa000,
+ 0x9fc: 0x4037, 0x9fd: 0xa000, 0x9fe: 0x403f, 0x9ff: 0xa000,
+ // Block 0x28, offset 0xa00
+ 0xa00: 0x4047, 0xa01: 0xa000, 0xa02: 0x404f, 0xa04: 0xa000, 0xa05: 0x4057,
+ 0xa06: 0xa000, 0xa07: 0x405f, 0xa08: 0xa000, 0xa09: 0x4067,
+ 0xa0f: 0xa000, 0xa10: 0x406f, 0xa11: 0x4077,
+ 0xa12: 0xa000, 0xa13: 0x407f, 0xa14: 0x4087, 0xa15: 0xa000, 0xa16: 0x408f, 0xa17: 0x4097,
+ 0xa18: 0xa000, 0xa19: 0x409f, 0xa1a: 0x40a7, 0xa1b: 0xa000, 0xa1c: 0x40af, 0xa1d: 0x40b7,
+ 0xa2f: 0xa000,
+ 0xa30: 0xa000, 0xa31: 0xa000, 0xa32: 0xa000, 0xa34: 0x3fef,
+ 0xa37: 0x40bf, 0xa38: 0x40c7, 0xa39: 0x40cf, 0xa3a: 0x40d7,
+ 0xa3d: 0xa000, 0xa3e: 0x40df, 0xa3f: 0x26cf,
+ // Block 0x29, offset 0xa40
+ 0xa40: 0x036a, 0xa41: 0x032e, 0xa42: 0x0332, 0xa43: 0x0336, 0xa44: 0x037e, 0xa45: 0x033a,
+ 0xa46: 0x033e, 0xa47: 0x0342, 0xa48: 0x0346, 0xa49: 0x034a, 0xa4a: 0x034e, 0xa4b: 0x0352,
+ 0xa4c: 0x0356, 0xa4d: 0x035a, 0xa4e: 0x035e, 0xa4f: 0x49d4, 0xa50: 0x49da, 0xa51: 0x49e0,
+ 0xa52: 0x49e6, 0xa53: 0x49ec, 0xa54: 0x49f2, 0xa55: 0x49f8, 0xa56: 0x49fe, 0xa57: 0x4a04,
+ 0xa58: 0x4a0a, 0xa59: 0x4a10, 0xa5a: 0x4a16, 0xa5b: 0x4a1c, 0xa5c: 0x4a22, 0xa5d: 0x4a28,
+ 0xa5e: 0x4a2e, 0xa5f: 0x4a34, 0xa60: 0x4a3a, 0xa61: 0x4a40, 0xa62: 0x4a46, 0xa63: 0x4a4c,
+ 0xa64: 0x03c6, 0xa65: 0x0362, 0xa66: 0x0366, 0xa67: 0x03ea, 0xa68: 0x03ee, 0xa69: 0x03f2,
+ 0xa6a: 0x03f6, 0xa6b: 0x03fa, 0xa6c: 0x03fe, 0xa6d: 0x0402, 0xa6e: 0x036e, 0xa6f: 0x0406,
+ 0xa70: 0x040a, 0xa71: 0x0372, 0xa72: 0x0376, 0xa73: 0x037a, 0xa74: 0x0382, 0xa75: 0x0386,
+ 0xa76: 0x038a, 0xa77: 0x038e, 0xa78: 0x0392, 0xa79: 0x0396, 0xa7a: 0x039a, 0xa7b: 0x039e,
+ 0xa7c: 0x03a2, 0xa7d: 0x03a6, 0xa7e: 0x03aa, 0xa7f: 0x03ae,
+ // Block 0x2a, offset 0xa80
+ 0xa80: 0x03b2, 0xa81: 0x03b6, 0xa82: 0x040e, 0xa83: 0x0412, 0xa84: 0x03ba, 0xa85: 0x03be,
+ 0xa86: 0x03c2, 0xa87: 0x03ca, 0xa88: 0x03ce, 0xa89: 0x03d2, 0xa8a: 0x03d6, 0xa8b: 0x03da,
+ 0xa8c: 0x03de, 0xa8d: 0x03e2, 0xa8e: 0x03e6,
+ 0xa92: 0x06c2, 0xa93: 0x071e, 0xa94: 0x06ce, 0xa95: 0x097e, 0xa96: 0x06d2, 0xa97: 0x06ea,
+ 0xa98: 0x06d6, 0xa99: 0x0f96, 0xa9a: 0x070a, 0xa9b: 0x06de, 0xa9c: 0x06c6, 0xa9d: 0x0a02,
+ 0xa9e: 0x0992, 0xa9f: 0x0732,
+ // Block 0x2b, offset 0xac0
+ 0xac0: 0x205a, 0xac1: 0x2060, 0xac2: 0x2066, 0xac3: 0x206c, 0xac4: 0x2072, 0xac5: 0x2078,
+ 0xac6: 0x207e, 0xac7: 0x2084, 0xac8: 0x208a, 0xac9: 0x2090, 0xaca: 0x2096, 0xacb: 0x209c,
+ 0xacc: 0x20a2, 0xacd: 0x20a8, 0xace: 0x2733, 0xacf: 0x273c, 0xad0: 0x2745, 0xad1: 0x274e,
+ 0xad2: 0x2757, 0xad3: 0x2760, 0xad4: 0x2769, 0xad5: 0x2772, 0xad6: 0x277b, 0xad7: 0x278d,
+ 0xad8: 0x2796, 0xad9: 0x279f, 0xada: 0x27a8, 0xadb: 0x27b1, 0xadc: 0x2784, 0xadd: 0x2bb9,
+ 0xade: 0x2afa, 0xae0: 0x20ae, 0xae1: 0x20c6, 0xae2: 0x20ba, 0xae3: 0x210e,
+ 0xae4: 0x20cc, 0xae5: 0x20ea, 0xae6: 0x20b4, 0xae7: 0x20e4, 0xae8: 0x20c0, 0xae9: 0x20f6,
+ 0xaea: 0x2126, 0xaeb: 0x2144, 0xaec: 0x213e, 0xaed: 0x2132, 0xaee: 0x2180, 0xaef: 0x2114,
+ 0xaf0: 0x2120, 0xaf1: 0x2138, 0xaf2: 0x212c, 0xaf3: 0x2156, 0xaf4: 0x2102, 0xaf5: 0x214a,
+ 0xaf6: 0x2174, 0xaf7: 0x215c, 0xaf8: 0x20f0, 0xaf9: 0x20d2, 0xafa: 0x2108, 0xafb: 0x211a,
+ 0xafc: 0x2150, 0xafd: 0x20d8, 0xafe: 0x217a, 0xaff: 0x20fc,
+ // Block 0x2c, offset 0xb00
+ 0xb00: 0x2162, 0xb01: 0x20de, 0xb02: 0x2168, 0xb03: 0x216e, 0xb04: 0x0932, 0xb05: 0x0b06,
+ 0xb06: 0x0caa, 0xb07: 0x10ca,
+ 0xb10: 0x1bca, 0xb11: 0x18ac,
+ 0xb12: 0x18af, 0xb13: 0x18b2, 0xb14: 0x18b5, 0xb15: 0x18b8, 0xb16: 0x18bb, 0xb17: 0x18be,
+ 0xb18: 0x18c1, 0xb19: 0x18c4, 0xb1a: 0x18cd, 0xb1b: 0x18d0, 0xb1c: 0x18d3, 0xb1d: 0x18d6,
+ 0xb1e: 0x18d9, 0xb1f: 0x18dc, 0xb20: 0x0316, 0xb21: 0x031e, 0xb22: 0x0322, 0xb23: 0x032a,
+ 0xb24: 0x032e, 0xb25: 0x0332, 0xb26: 0x033a, 0xb27: 0x0342, 0xb28: 0x0346, 0xb29: 0x034e,
+ 0xb2a: 0x0352, 0xb2b: 0x0356, 0xb2c: 0x035a, 0xb2d: 0x035e, 0xb2e: 0x2e2f, 0xb2f: 0x2e37,
+ 0xb30: 0x2e3f, 0xb31: 0x2e47, 0xb32: 0x2e4f, 0xb33: 0x2e57, 0xb34: 0x2e5f, 0xb35: 0x2e67,
+ 0xb36: 0x2e77, 0xb37: 0x2e7f, 0xb38: 0x2e87, 0xb39: 0x2e8f, 0xb3a: 0x2e97, 0xb3b: 0x2e9f,
+ 0xb3c: 0x2eea, 0xb3d: 0x2eb2, 0xb3e: 0x2e6f,
+ // Block 0x2d, offset 0xb40
+ 0xb40: 0x06c2, 0xb41: 0x071e, 0xb42: 0x06ce, 0xb43: 0x097e, 0xb44: 0x0722, 0xb45: 0x07b2,
+ 0xb46: 0x06ca, 0xb47: 0x07ae, 0xb48: 0x070e, 0xb49: 0x088a, 0xb4a: 0x0d0a, 0xb4b: 0x0e92,
+ 0xb4c: 0x0dda, 0xb4d: 0x0d1e, 0xb4e: 0x1462, 0xb4f: 0x098e, 0xb50: 0x0cd2, 0xb51: 0x0d4e,
+ 0xb52: 0x0d0e, 0xb53: 0x104e, 0xb54: 0x08fe, 0xb55: 0x0f06, 0xb56: 0x138a, 0xb57: 0x1062,
+ 0xb58: 0x0846, 0xb59: 0x1092, 0xb5a: 0x0f9e, 0xb5b: 0x0a1a, 0xb5c: 0x1412, 0xb5d: 0x0782,
+ 0xb5e: 0x08ae, 0xb5f: 0x0dfa, 0xb60: 0x152a, 0xb61: 0x0746, 0xb62: 0x07d6, 0xb63: 0x0d9e,
+ 0xb64: 0x06d2, 0xb65: 0x06ea, 0xb66: 0x06d6, 0xb67: 0x0ade, 0xb68: 0x08f2, 0xb69: 0x0882,
+ 0xb6a: 0x0a5a, 0xb6b: 0x0a4e, 0xb6c: 0x0fee, 0xb6d: 0x0742, 0xb6e: 0x139e, 0xb6f: 0x089e,
+ 0xb70: 0x09f6, 0xb71: 0x18df, 0xb72: 0x18e2, 0xb73: 0x18e5, 0xb74: 0x18e8, 0xb75: 0x18f1,
+ 0xb76: 0x18f4, 0xb77: 0x18f7, 0xb78: 0x18fa, 0xb79: 0x18fd, 0xb7a: 0x1900, 0xb7b: 0x1903,
+ 0xb7c: 0x1906, 0xb7d: 0x1909, 0xb7e: 0x190c, 0xb7f: 0x1915,
+ // Block 0x2e, offset 0xb80
+ 0xb80: 0x1ccc, 0xb81: 0x1cdb, 0xb82: 0x1cea, 0xb83: 0x1cf9, 0xb84: 0x1d08, 0xb85: 0x1d17,
+ 0xb86: 0x1d26, 0xb87: 0x1d35, 0xb88: 0x1d44, 0xb89: 0x2192, 0xb8a: 0x21a4, 0xb8b: 0x21b6,
+ 0xb8c: 0x1957, 0xb8d: 0x1c0a, 0xb8e: 0x19d8, 0xb8f: 0x1bae, 0xb90: 0x04ce, 0xb91: 0x04d6,
+ 0xb92: 0x04de, 0xb93: 0x04e6, 0xb94: 0x04ee, 0xb95: 0x04f2, 0xb96: 0x04f6, 0xb97: 0x04fa,
+ 0xb98: 0x04fe, 0xb99: 0x0502, 0xb9a: 0x0506, 0xb9b: 0x050a, 0xb9c: 0x050e, 0xb9d: 0x0512,
+ 0xb9e: 0x0516, 0xb9f: 0x051a, 0xba0: 0x051e, 0xba1: 0x0526, 0xba2: 0x052a, 0xba3: 0x052e,
+ 0xba4: 0x0532, 0xba5: 0x0536, 0xba6: 0x053a, 0xba7: 0x053e, 0xba8: 0x0542, 0xba9: 0x0546,
+ 0xbaa: 0x054a, 0xbab: 0x054e, 0xbac: 0x0552, 0xbad: 0x0556, 0xbae: 0x055a, 0xbaf: 0x055e,
+ 0xbb0: 0x0562, 0xbb1: 0x0566, 0xbb2: 0x056a, 0xbb3: 0x0572, 0xbb4: 0x057a, 0xbb5: 0x0582,
+ 0xbb6: 0x0586, 0xbb7: 0x058a, 0xbb8: 0x058e, 0xbb9: 0x0592, 0xbba: 0x0596, 0xbbb: 0x059a,
+ 0xbbc: 0x059e, 0xbbd: 0x05a2, 0xbbe: 0x05a6, 0xbbf: 0x2700,
+ // Block 0x2f, offset 0xbc0
+ 0xbc0: 0x2b19, 0xbc1: 0x29b5, 0xbc2: 0x2b29, 0xbc3: 0x288d, 0xbc4: 0x2efb, 0xbc5: 0x2897,
+ 0xbc6: 0x28a1, 0xbc7: 0x2f3f, 0xbc8: 0x29c2, 0xbc9: 0x28ab, 0xbca: 0x28b5, 0xbcb: 0x28bf,
+ 0xbcc: 0x29e9, 0xbcd: 0x29f6, 0xbce: 0x29cf, 0xbcf: 0x29dc, 0xbd0: 0x2ec0, 0xbd1: 0x2a03,
+ 0xbd2: 0x2a10, 0xbd3: 0x2bcb, 0xbd4: 0x26c1, 0xbd5: 0x2bde, 0xbd6: 0x2bf1, 0xbd7: 0x2b39,
+ 0xbd8: 0x2a1d, 0xbd9: 0x2c04, 0xbda: 0x2c17, 0xbdb: 0x2a2a, 0xbdc: 0x28c9, 0xbdd: 0x28d3,
+ 0xbde: 0x2ece, 0xbdf: 0x2a37, 0xbe0: 0x2b49, 0xbe1: 0x2f0c, 0xbe2: 0x28dd, 0xbe3: 0x28e7,
+ 0xbe4: 0x2a44, 0xbe5: 0x28f1, 0xbe6: 0x28fb, 0xbe7: 0x26d6, 0xbe8: 0x26dd, 0xbe9: 0x2905,
+ 0xbea: 0x290f, 0xbeb: 0x2c2a, 0xbec: 0x2a51, 0xbed: 0x2b59, 0xbee: 0x2c3d, 0xbef: 0x2a5e,
+ 0xbf0: 0x2923, 0xbf1: 0x2919, 0xbf2: 0x2f53, 0xbf3: 0x2a6b, 0xbf4: 0x2c50, 0xbf5: 0x292d,
+ 0xbf6: 0x2b69, 0xbf7: 0x2937, 0xbf8: 0x2a85, 0xbf9: 0x2941, 0xbfa: 0x2a92, 0xbfb: 0x2f1d,
+ 0xbfc: 0x2a78, 0xbfd: 0x2b79, 0xbfe: 0x2a9f, 0xbff: 0x26e4,
+ // Block 0x30, offset 0xc00
+ 0xc00: 0x2f2e, 0xc01: 0x294b, 0xc02: 0x2955, 0xc03: 0x2aac, 0xc04: 0x295f, 0xc05: 0x2969,
+ 0xc06: 0x2973, 0xc07: 0x2b89, 0xc08: 0x2ab9, 0xc09: 0x26eb, 0xc0a: 0x2c63, 0xc0b: 0x2ea7,
+ 0xc0c: 0x2b99, 0xc0d: 0x2ac6, 0xc0e: 0x2edc, 0xc0f: 0x297d, 0xc10: 0x2987, 0xc11: 0x2ad3,
+ 0xc12: 0x26f2, 0xc13: 0x2ae0, 0xc14: 0x2ba9, 0xc15: 0x26f9, 0xc16: 0x2c76, 0xc17: 0x2991,
+ 0xc18: 0x1cbd, 0xc19: 0x1cd1, 0xc1a: 0x1ce0, 0xc1b: 0x1cef, 0xc1c: 0x1cfe, 0xc1d: 0x1d0d,
+ 0xc1e: 0x1d1c, 0xc1f: 0x1d2b, 0xc20: 0x1d3a, 0xc21: 0x1d49, 0xc22: 0x2198, 0xc23: 0x21aa,
+ 0xc24: 0x21bc, 0xc25: 0x21c8, 0xc26: 0x21d4, 0xc27: 0x21e0, 0xc28: 0x21ec, 0xc29: 0x21f8,
+ 0xc2a: 0x2204, 0xc2b: 0x2210, 0xc2c: 0x224c, 0xc2d: 0x2258, 0xc2e: 0x2264, 0xc2f: 0x2270,
+ 0xc30: 0x227c, 0xc31: 0x1c1a, 0xc32: 0x19cc, 0xc33: 0x1939, 0xc34: 0x1bea, 0xc35: 0x1a4d,
+ 0xc36: 0x1a5c, 0xc37: 0x19d2, 0xc38: 0x1c02, 0xc39: 0x1c06, 0xc3a: 0x1963, 0xc3b: 0x270e,
+ 0xc3c: 0x271c, 0xc3d: 0x2707, 0xc3e: 0x2715, 0xc3f: 0x2aed,
+ // Block 0x31, offset 0xc40
+ 0xc40: 0x1a50, 0xc41: 0x1a38, 0xc42: 0x1c66, 0xc43: 0x1a20, 0xc44: 0x19f9, 0xc45: 0x196c,
+ 0xc46: 0x197b, 0xc47: 0x194b, 0xc48: 0x1bf6, 0xc49: 0x1d58, 0xc4a: 0x1a53, 0xc4b: 0x1a3b,
+ 0xc4c: 0x1c6a, 0xc4d: 0x1c76, 0xc4e: 0x1a2c, 0xc4f: 0x1a02, 0xc50: 0x195a, 0xc51: 0x1c22,
+ 0xc52: 0x1bb6, 0xc53: 0x1ba2, 0xc54: 0x1bd2, 0xc55: 0x1c7a, 0xc56: 0x1a2f, 0xc57: 0x19cf,
+ 0xc58: 0x1a05, 0xc59: 0x19e4, 0xc5a: 0x1a47, 0xc5b: 0x1c7e, 0xc5c: 0x1a32, 0xc5d: 0x19c6,
+ 0xc5e: 0x1a08, 0xc5f: 0x1c42, 0xc60: 0x1bfa, 0xc61: 0x1a1a, 0xc62: 0x1c2a, 0xc63: 0x1c46,
+ 0xc64: 0x1bfe, 0xc65: 0x1a1d, 0xc66: 0x1c2e, 0xc67: 0x22ee, 0xc68: 0x2302, 0xc69: 0x199c,
+ 0xc6a: 0x1c26, 0xc6b: 0x1bba, 0xc6c: 0x1ba6, 0xc6d: 0x1c4e, 0xc6e: 0x2723, 0xc6f: 0x27ba,
+ 0xc70: 0x1a5f, 0xc71: 0x1a4a, 0xc72: 0x1c82, 0xc73: 0x1a35, 0xc74: 0x1a56, 0xc75: 0x1a3e,
+ 0xc76: 0x1c6e, 0xc77: 0x1a23, 0xc78: 0x19fc, 0xc79: 0x1987, 0xc7a: 0x1a59, 0xc7b: 0x1a41,
+ 0xc7c: 0x1c72, 0xc7d: 0x1a26, 0xc7e: 0x19ff, 0xc7f: 0x198a,
+ // Block 0x32, offset 0xc80
+ 0xc80: 0x1c32, 0xc81: 0x1bbe, 0xc82: 0x1d53, 0xc83: 0x193c, 0xc84: 0x19c0, 0xc85: 0x19c3,
+ 0xc86: 0x22fb, 0xc87: 0x1b9a, 0xc88: 0x19c9, 0xc89: 0x194e, 0xc8a: 0x19e7, 0xc8b: 0x1951,
+ 0xc8c: 0x19f0, 0xc8d: 0x196f, 0xc8e: 0x1972, 0xc8f: 0x1a0b, 0xc90: 0x1a11, 0xc91: 0x1a14,
+ 0xc92: 0x1c36, 0xc93: 0x1a17, 0xc94: 0x1a29, 0xc95: 0x1c3e, 0xc96: 0x1c4a, 0xc97: 0x1996,
+ 0xc98: 0x1d5d, 0xc99: 0x1bc2, 0xc9a: 0x1999, 0xc9b: 0x1a62, 0xc9c: 0x19ab, 0xc9d: 0x19ba,
+ 0xc9e: 0x22e8, 0xc9f: 0x22e2, 0xca0: 0x1cc7, 0xca1: 0x1cd6, 0xca2: 0x1ce5, 0xca3: 0x1cf4,
+ 0xca4: 0x1d03, 0xca5: 0x1d12, 0xca6: 0x1d21, 0xca7: 0x1d30, 0xca8: 0x1d3f, 0xca9: 0x218c,
+ 0xcaa: 0x219e, 0xcab: 0x21b0, 0xcac: 0x21c2, 0xcad: 0x21ce, 0xcae: 0x21da, 0xcaf: 0x21e6,
+ 0xcb0: 0x21f2, 0xcb1: 0x21fe, 0xcb2: 0x220a, 0xcb3: 0x2246, 0xcb4: 0x2252, 0xcb5: 0x225e,
+ 0xcb6: 0x226a, 0xcb7: 0x2276, 0xcb8: 0x2282, 0xcb9: 0x2288, 0xcba: 0x228e, 0xcbb: 0x2294,
+ 0xcbc: 0x229a, 0xcbd: 0x22ac, 0xcbe: 0x22b2, 0xcbf: 0x1c16,
+ // Block 0x33, offset 0xcc0
+ 0xcc0: 0x137a, 0xcc1: 0x0cfe, 0xcc2: 0x13d6, 0xcc3: 0x13a2, 0xcc4: 0x0e5a, 0xcc5: 0x06ee,
+ 0xcc6: 0x08e2, 0xcc7: 0x162e, 0xcc8: 0x162e, 0xcc9: 0x0a0e, 0xcca: 0x1462, 0xccb: 0x0946,
+ 0xccc: 0x0a0a, 0xccd: 0x0bf2, 0xcce: 0x0fd2, 0xccf: 0x1162, 0xcd0: 0x129a, 0xcd1: 0x12d6,
+ 0xcd2: 0x130a, 0xcd3: 0x141e, 0xcd4: 0x0d76, 0xcd5: 0x0e02, 0xcd6: 0x0eae, 0xcd7: 0x0f46,
+ 0xcd8: 0x1262, 0xcd9: 0x144a, 0xcda: 0x1576, 0xcdb: 0x0712, 0xcdc: 0x08b6, 0xcdd: 0x0d8a,
+ 0xcde: 0x0ed2, 0xcdf: 0x1296, 0xce0: 0x15c6, 0xce1: 0x0ab6, 0xce2: 0x0e7a, 0xce3: 0x1286,
+ 0xce4: 0x131a, 0xce5: 0x0c26, 0xce6: 0x11be, 0xce7: 0x12e2, 0xce8: 0x0b22, 0xce9: 0x0d12,
+ 0xcea: 0x0e1a, 0xceb: 0x0f1e, 0xcec: 0x142a, 0xced: 0x0752, 0xcee: 0x07ea, 0xcef: 0x0856,
+ 0xcf0: 0x0c8e, 0xcf1: 0x0d82, 0xcf2: 0x0ece, 0xcf3: 0x0ff2, 0xcf4: 0x117a, 0xcf5: 0x128e,
+ 0xcf6: 0x12a6, 0xcf7: 0x13ca, 0xcf8: 0x14f2, 0xcf9: 0x15a6, 0xcfa: 0x15c2, 0xcfb: 0x102e,
+ 0xcfc: 0x106e, 0xcfd: 0x1126, 0xcfe: 0x1246, 0xcff: 0x147e,
+ // Block 0x34, offset 0xd00
+ 0xd00: 0x15ce, 0xd01: 0x134e, 0xd02: 0x09ca, 0xd03: 0x0b3e, 0xd04: 0x10de, 0xd05: 0x119e,
+ 0xd06: 0x0f02, 0xd07: 0x1036, 0xd08: 0x139a, 0xd09: 0x14ea, 0xd0a: 0x09c6, 0xd0b: 0x0a92,
+ 0xd0c: 0x0d7a, 0xd0d: 0x0e2e, 0xd0e: 0x0e62, 0xd0f: 0x1116, 0xd10: 0x113e, 0xd11: 0x14aa,
+ 0xd12: 0x0852, 0xd13: 0x11aa, 0xd14: 0x07f6, 0xd15: 0x07f2, 0xd16: 0x109a, 0xd17: 0x112a,
+ 0xd18: 0x125e, 0xd19: 0x14b2, 0xd1a: 0x136a, 0xd1b: 0x0c2a, 0xd1c: 0x0d76, 0xd1d: 0x135a,
+ 0xd1e: 0x06fa, 0xd1f: 0x0a66, 0xd20: 0x0b96, 0xd21: 0x0f32, 0xd22: 0x0fb2, 0xd23: 0x0876,
+ 0xd24: 0x103e, 0xd25: 0x0762, 0xd26: 0x0b7a, 0xd27: 0x06da, 0xd28: 0x0dee, 0xd29: 0x0ca6,
+ 0xd2a: 0x1112, 0xd2b: 0x08ca, 0xd2c: 0x09b6, 0xd2d: 0x0ffe, 0xd2e: 0x1266, 0xd2f: 0x133e,
+ 0xd30: 0x0dba, 0xd31: 0x13fa, 0xd32: 0x0de6, 0xd33: 0x0c3a, 0xd34: 0x121e, 0xd35: 0x0c5a,
+ 0xd36: 0x0fae, 0xd37: 0x072e, 0xd38: 0x07aa, 0xd39: 0x07ee, 0xd3a: 0x0d56, 0xd3b: 0x10fe,
+ 0xd3c: 0x11f6, 0xd3d: 0x134a, 0xd3e: 0x145e, 0xd3f: 0x085e,
+ // Block 0x35, offset 0xd40
+ 0xd40: 0x0912, 0xd41: 0x0a1a, 0xd42: 0x0b32, 0xd43: 0x0cc2, 0xd44: 0x0e7e, 0xd45: 0x1042,
+ 0xd46: 0x149a, 0xd47: 0x157e, 0xd48: 0x15d2, 0xd49: 0x15ea, 0xd4a: 0x083a, 0xd4b: 0x0cf6,
+ 0xd4c: 0x0da6, 0xd4d: 0x13ee, 0xd4e: 0x0afe, 0xd4f: 0x0bda, 0xd50: 0x0bf6, 0xd51: 0x0c86,
+ 0xd52: 0x0e6e, 0xd53: 0x0eba, 0xd54: 0x0f6a, 0xd55: 0x108e, 0xd56: 0x1132, 0xd57: 0x1196,
+ 0xd58: 0x13de, 0xd59: 0x126e, 0xd5a: 0x1406, 0xd5b: 0x1482, 0xd5c: 0x0812, 0xd5d: 0x083e,
+ 0xd5e: 0x0926, 0xd5f: 0x0eaa, 0xd60: 0x12f6, 0xd61: 0x133e, 0xd62: 0x0b1e, 0xd63: 0x0b8e,
+ 0xd64: 0x0c52, 0xd65: 0x0db2, 0xd66: 0x10da, 0xd67: 0x0f26, 0xd68: 0x073e, 0xd69: 0x0982,
+ 0xd6a: 0x0a66, 0xd6b: 0x0aca, 0xd6c: 0x0b9a, 0xd6d: 0x0f42, 0xd6e: 0x0f5e, 0xd6f: 0x116e,
+ 0xd70: 0x118e, 0xd71: 0x1466, 0xd72: 0x14e6, 0xd73: 0x14f6, 0xd74: 0x1532, 0xd75: 0x0756,
+ 0xd76: 0x1082, 0xd77: 0x1452, 0xd78: 0x14ce, 0xd79: 0x0bb2, 0xd7a: 0x071a, 0xd7b: 0x077a,
+ 0xd7c: 0x0a6a, 0xd7d: 0x0a8a, 0xd7e: 0x0cb2, 0xd7f: 0x0d76,
+ // Block 0x36, offset 0xd80
+ 0xd80: 0x0ec6, 0xd81: 0x0fce, 0xd82: 0x127a, 0xd83: 0x141a, 0xd84: 0x1626, 0xd85: 0x0ce6,
+ 0xd86: 0x14a6, 0xd87: 0x0836, 0xd88: 0x0d32, 0xd89: 0x0d3e, 0xd8a: 0x0e12, 0xd8b: 0x0e4a,
+ 0xd8c: 0x0f4e, 0xd8d: 0x0faa, 0xd8e: 0x102a, 0xd8f: 0x110e, 0xd90: 0x153e, 0xd91: 0x07b2,
+ 0xd92: 0x0c06, 0xd93: 0x14b6, 0xd94: 0x076a, 0xd95: 0x0aae, 0xd96: 0x0e32, 0xd97: 0x13e2,
+ 0xd98: 0x0b6a, 0xd99: 0x0bba, 0xd9a: 0x0d46, 0xd9b: 0x0f32, 0xd9c: 0x14be, 0xd9d: 0x081a,
+ 0xd9e: 0x0902, 0xd9f: 0x0a9a, 0xda0: 0x0cd6, 0xda1: 0x0d22, 0xda2: 0x0d62, 0xda3: 0x0df6,
+ 0xda4: 0x0f4a, 0xda5: 0x0fbe, 0xda6: 0x115a, 0xda7: 0x12fa, 0xda8: 0x1306, 0xda9: 0x145a,
+ 0xdaa: 0x14da, 0xdab: 0x0886, 0xdac: 0x0e4e, 0xdad: 0x0906, 0xdae: 0x0eca, 0xdaf: 0x0f6e,
+ 0xdb0: 0x128a, 0xdb1: 0x14c2, 0xdb2: 0x15ae, 0xdb3: 0x15d6, 0xdb4: 0x0d3a, 0xdb5: 0x0e2a,
+ 0xdb6: 0x11c6, 0xdb7: 0x10ba, 0xdb8: 0x10c6, 0xdb9: 0x10ea, 0xdba: 0x0f1a, 0xdbb: 0x0ea2,
+ 0xdbc: 0x1366, 0xdbd: 0x0736, 0xdbe: 0x122e, 0xdbf: 0x081e,
+ // Block 0x37, offset 0xdc0
+ 0xdc0: 0x080e, 0xdc1: 0x0b0e, 0xdc2: 0x0c2e, 0xdc3: 0x10f6, 0xdc4: 0x0a56, 0xdc5: 0x0e06,
+ 0xdc6: 0x0cf2, 0xdc7: 0x13ea, 0xdc8: 0x12ea, 0xdc9: 0x14ae, 0xdca: 0x1326, 0xdcb: 0x0b2a,
+ 0xdcc: 0x078a, 0xdcd: 0x095e, 0xdd0: 0x09b2,
+ 0xdd2: 0x0ce2, 0xdd5: 0x07fa, 0xdd6: 0x0f22, 0xdd7: 0x0fe6,
+ 0xdd8: 0x104a, 0xdd9: 0x1066, 0xdda: 0x106a, 0xddb: 0x107e, 0xddc: 0x14fe, 0xddd: 0x10ee,
+ 0xdde: 0x1172, 0xde0: 0x1292, 0xde2: 0x1356,
+ 0xde5: 0x140a, 0xde6: 0x1436,
+ 0xdea: 0x1552, 0xdeb: 0x1556, 0xdec: 0x155a, 0xded: 0x15be, 0xdee: 0x142e, 0xdef: 0x14ca,
+ 0xdf0: 0x075a, 0xdf1: 0x077e, 0xdf2: 0x0792, 0xdf3: 0x084e, 0xdf4: 0x085a, 0xdf5: 0x089a,
+ 0xdf6: 0x094e, 0xdf7: 0x096a, 0xdf8: 0x0972, 0xdf9: 0x09ae, 0xdfa: 0x09ba, 0xdfb: 0x0a96,
+ 0xdfc: 0x0a9e, 0xdfd: 0x0ba6, 0xdfe: 0x0bce, 0xdff: 0x0bd6,
+ // Block 0x38, offset 0xe00
+ 0xe00: 0x0bee, 0xe01: 0x0c9a, 0xe02: 0x0cca, 0xe03: 0x0cea, 0xe04: 0x0d5a, 0xe05: 0x0e1e,
+ 0xe06: 0x0e3a, 0xe07: 0x0e6a, 0xe08: 0x0ebe, 0xe09: 0x0ede, 0xe0a: 0x0f52, 0xe0b: 0x1032,
+ 0xe0c: 0x104e, 0xe0d: 0x1056, 0xe0e: 0x1052, 0xe0f: 0x105a, 0xe10: 0x105e, 0xe11: 0x1062,
+ 0xe12: 0x1076, 0xe13: 0x107a, 0xe14: 0x109e, 0xe15: 0x10b2, 0xe16: 0x10ce, 0xe17: 0x1132,
+ 0xe18: 0x113a, 0xe19: 0x1142, 0xe1a: 0x1156, 0xe1b: 0x117e, 0xe1c: 0x11ce, 0xe1d: 0x1202,
+ 0xe1e: 0x1202, 0xe1f: 0x126a, 0xe20: 0x1312, 0xe21: 0x132a, 0xe22: 0x135e, 0xe23: 0x1362,
+ 0xe24: 0x13a6, 0xe25: 0x13aa, 0xe26: 0x1402, 0xe27: 0x140a, 0xe28: 0x14de, 0xe29: 0x1522,
+ 0xe2a: 0x153a, 0xe2b: 0x0b9e, 0xe2c: 0x1721, 0xe2d: 0x11e6,
+ 0xe30: 0x06e2, 0xe31: 0x07e6, 0xe32: 0x07a6, 0xe33: 0x074e, 0xe34: 0x078e, 0xe35: 0x07ba,
+ 0xe36: 0x084a, 0xe37: 0x0866, 0xe38: 0x094e, 0xe39: 0x093a, 0xe3a: 0x094a, 0xe3b: 0x0966,
+ 0xe3c: 0x09b2, 0xe3d: 0x09c2, 0xe3e: 0x0a06, 0xe3f: 0x0a12,
+ // Block 0x39, offset 0xe40
+ 0xe40: 0x0a2e, 0xe41: 0x0a3e, 0xe42: 0x0b26, 0xe43: 0x0b2e, 0xe44: 0x0b5e, 0xe45: 0x0b7e,
+ 0xe46: 0x0bae, 0xe47: 0x0bc6, 0xe48: 0x0bb6, 0xe49: 0x0bd6, 0xe4a: 0x0bca, 0xe4b: 0x0bee,
+ 0xe4c: 0x0c0a, 0xe4d: 0x0c62, 0xe4e: 0x0c6e, 0xe4f: 0x0c76, 0xe50: 0x0c9e, 0xe51: 0x0ce2,
+ 0xe52: 0x0d12, 0xe53: 0x0d16, 0xe54: 0x0d2a, 0xe55: 0x0daa, 0xe56: 0x0dba, 0xe57: 0x0e12,
+ 0xe58: 0x0e5e, 0xe59: 0x0e56, 0xe5a: 0x0e6a, 0xe5b: 0x0e86, 0xe5c: 0x0ebe, 0xe5d: 0x1016,
+ 0xe5e: 0x0ee2, 0xe5f: 0x0f16, 0xe60: 0x0f22, 0xe61: 0x0f62, 0xe62: 0x0f7e, 0xe63: 0x0fa2,
+ 0xe64: 0x0fc6, 0xe65: 0x0fca, 0xe66: 0x0fe6, 0xe67: 0x0fea, 0xe68: 0x0ffa, 0xe69: 0x100e,
+ 0xe6a: 0x100a, 0xe6b: 0x103a, 0xe6c: 0x10b6, 0xe6d: 0x10ce, 0xe6e: 0x10e6, 0xe6f: 0x111e,
+ 0xe70: 0x1132, 0xe71: 0x114e, 0xe72: 0x117e, 0xe73: 0x1232, 0xe74: 0x125a, 0xe75: 0x12ce,
+ 0xe76: 0x1316, 0xe77: 0x1322, 0xe78: 0x132a, 0xe79: 0x1342, 0xe7a: 0x1356, 0xe7b: 0x1346,
+ 0xe7c: 0x135e, 0xe7d: 0x135a, 0xe7e: 0x1352, 0xe7f: 0x1362,
+ // Block 0x3a, offset 0xe80
+ 0xe80: 0x136e, 0xe81: 0x13aa, 0xe82: 0x13e6, 0xe83: 0x1416, 0xe84: 0x144e, 0xe85: 0x146e,
+ 0xe86: 0x14ba, 0xe87: 0x14de, 0xe88: 0x14fe, 0xe89: 0x1512, 0xe8a: 0x1522, 0xe8b: 0x152e,
+ 0xe8c: 0x153a, 0xe8d: 0x158e, 0xe8e: 0x162e, 0xe8f: 0x16b8, 0xe90: 0x16b3, 0xe91: 0x16e5,
+ 0xe92: 0x060a, 0xe93: 0x0632, 0xe94: 0x0636, 0xe95: 0x1767, 0xe96: 0x1794, 0xe97: 0x180c,
+ 0xe98: 0x161a, 0xe99: 0x162a,
+ // Block 0x3b, offset 0xec0
+ 0xec0: 0x19db, 0xec1: 0x19de, 0xec2: 0x19e1, 0xec3: 0x1c0e, 0xec4: 0x1c12, 0xec5: 0x1a65,
+ 0xec6: 0x1a65,
+ 0xed3: 0x1d7b, 0xed4: 0x1d6c, 0xed5: 0x1d71, 0xed6: 0x1d80, 0xed7: 0x1d76,
+ 0xedd: 0x43a7,
+ 0xede: 0x8116, 0xedf: 0x4419, 0xee0: 0x0230, 0xee1: 0x0218, 0xee2: 0x0221, 0xee3: 0x0224,
+ 0xee4: 0x0227, 0xee5: 0x022a, 0xee6: 0x022d, 0xee7: 0x0233, 0xee8: 0x0236, 0xee9: 0x0017,
+ 0xeea: 0x4407, 0xeeb: 0x440d, 0xeec: 0x450b, 0xeed: 0x4513, 0xeee: 0x435f, 0xeef: 0x4365,
+ 0xef0: 0x436b, 0xef1: 0x4371, 0xef2: 0x437d, 0xef3: 0x4383, 0xef4: 0x4389, 0xef5: 0x4395,
+ 0xef6: 0x439b, 0xef8: 0x43a1, 0xef9: 0x43ad, 0xefa: 0x43b3, 0xefb: 0x43b9,
+ 0xefc: 0x43c5, 0xefe: 0x43cb,
+ // Block 0x3c, offset 0xf00
+ 0xf00: 0x43d1, 0xf01: 0x43d7, 0xf03: 0x43dd, 0xf04: 0x43e3,
+ 0xf06: 0x43ef, 0xf07: 0x43f5, 0xf08: 0x43fb, 0xf09: 0x4401, 0xf0a: 0x4413, 0xf0b: 0x438f,
+ 0xf0c: 0x4377, 0xf0d: 0x43bf, 0xf0e: 0x43e9, 0xf0f: 0x1d85, 0xf10: 0x029c, 0xf11: 0x029c,
+ 0xf12: 0x02a5, 0xf13: 0x02a5, 0xf14: 0x02a5, 0xf15: 0x02a5, 0xf16: 0x02a8, 0xf17: 0x02a8,
+ 0xf18: 0x02a8, 0xf19: 0x02a8, 0xf1a: 0x02ae, 0xf1b: 0x02ae, 0xf1c: 0x02ae, 0xf1d: 0x02ae,
+ 0xf1e: 0x02a2, 0xf1f: 0x02a2, 0xf20: 0x02a2, 0xf21: 0x02a2, 0xf22: 0x02ab, 0xf23: 0x02ab,
+ 0xf24: 0x02ab, 0xf25: 0x02ab, 0xf26: 0x029f, 0xf27: 0x029f, 0xf28: 0x029f, 0xf29: 0x029f,
+ 0xf2a: 0x02d2, 0xf2b: 0x02d2, 0xf2c: 0x02d2, 0xf2d: 0x02d2, 0xf2e: 0x02d5, 0xf2f: 0x02d5,
+ 0xf30: 0x02d5, 0xf31: 0x02d5, 0xf32: 0x02b4, 0xf33: 0x02b4, 0xf34: 0x02b4, 0xf35: 0x02b4,
+ 0xf36: 0x02b1, 0xf37: 0x02b1, 0xf38: 0x02b1, 0xf39: 0x02b1, 0xf3a: 0x02b7, 0xf3b: 0x02b7,
+ 0xf3c: 0x02b7, 0xf3d: 0x02b7, 0xf3e: 0x02ba, 0xf3f: 0x02ba,
+ // Block 0x3d, offset 0xf40
+ 0xf40: 0x02ba, 0xf41: 0x02ba, 0xf42: 0x02c3, 0xf43: 0x02c3, 0xf44: 0x02c0, 0xf45: 0x02c0,
+ 0xf46: 0x02c6, 0xf47: 0x02c6, 0xf48: 0x02bd, 0xf49: 0x02bd, 0xf4a: 0x02cc, 0xf4b: 0x02cc,
+ 0xf4c: 0x02c9, 0xf4d: 0x02c9, 0xf4e: 0x02d8, 0xf4f: 0x02d8, 0xf50: 0x02d8, 0xf51: 0x02d8,
+ 0xf52: 0x02de, 0xf53: 0x02de, 0xf54: 0x02de, 0xf55: 0x02de, 0xf56: 0x02e4, 0xf57: 0x02e4,
+ 0xf58: 0x02e4, 0xf59: 0x02e4, 0xf5a: 0x02e1, 0xf5b: 0x02e1, 0xf5c: 0x02e1, 0xf5d: 0x02e1,
+ 0xf5e: 0x02e7, 0xf5f: 0x02e7, 0xf60: 0x02ea, 0xf61: 0x02ea, 0xf62: 0x02ea, 0xf63: 0x02ea,
+ 0xf64: 0x4485, 0xf65: 0x4485, 0xf66: 0x02f0, 0xf67: 0x02f0, 0xf68: 0x02f0, 0xf69: 0x02f0,
+ 0xf6a: 0x02ed, 0xf6b: 0x02ed, 0xf6c: 0x02ed, 0xf6d: 0x02ed, 0xf6e: 0x030b, 0xf6f: 0x030b,
+ 0xf70: 0x447f, 0xf71: 0x447f,
+ // Block 0x3e, offset 0xf80
+ 0xf93: 0x02db, 0xf94: 0x02db, 0xf95: 0x02db, 0xf96: 0x02db, 0xf97: 0x02f9,
+ 0xf98: 0x02f9, 0xf99: 0x02f6, 0xf9a: 0x02f6, 0xf9b: 0x02fc, 0xf9c: 0x02fc, 0xf9d: 0x2055,
+ 0xf9e: 0x0302, 0xf9f: 0x0302, 0xfa0: 0x02f3, 0xfa1: 0x02f3, 0xfa2: 0x02ff, 0xfa3: 0x02ff,
+ 0xfa4: 0x0308, 0xfa5: 0x0308, 0xfa6: 0x0308, 0xfa7: 0x0308, 0xfa8: 0x0290, 0xfa9: 0x0290,
+ 0xfaa: 0x25b0, 0xfab: 0x25b0, 0xfac: 0x2620, 0xfad: 0x2620, 0xfae: 0x25ef, 0xfaf: 0x25ef,
+ 0xfb0: 0x260b, 0xfb1: 0x260b, 0xfb2: 0x2604, 0xfb3: 0x2604, 0xfb4: 0x2612, 0xfb5: 0x2612,
+ 0xfb6: 0x2619, 0xfb7: 0x2619, 0xfb8: 0x2619, 0xfb9: 0x25f6, 0xfba: 0x25f6, 0xfbb: 0x25f6,
+ 0xfbc: 0x0305, 0xfbd: 0x0305, 0xfbe: 0x0305, 0xfbf: 0x0305,
+ // Block 0x3f, offset 0xfc0
+ 0xfc0: 0x25b7, 0xfc1: 0x25be, 0xfc2: 0x25da, 0xfc3: 0x25f6, 0xfc4: 0x25fd, 0xfc5: 0x1d8f,
+ 0xfc6: 0x1d94, 0xfc7: 0x1d99, 0xfc8: 0x1da8, 0xfc9: 0x1db7, 0xfca: 0x1dbc, 0xfcb: 0x1dc1,
+ 0xfcc: 0x1dc6, 0xfcd: 0x1dcb, 0xfce: 0x1dda, 0xfcf: 0x1de9, 0xfd0: 0x1dee, 0xfd1: 0x1df3,
+ 0xfd2: 0x1e02, 0xfd3: 0x1e11, 0xfd4: 0x1e16, 0xfd5: 0x1e1b, 0xfd6: 0x1e20, 0xfd7: 0x1e2f,
+ 0xfd8: 0x1e34, 0xfd9: 0x1e43, 0xfda: 0x1e48, 0xfdb: 0x1e4d, 0xfdc: 0x1e5c, 0xfdd: 0x1e61,
+ 0xfde: 0x1e66, 0xfdf: 0x1e70, 0xfe0: 0x1eac, 0xfe1: 0x1ebb, 0xfe2: 0x1eca, 0xfe3: 0x1ecf,
+ 0xfe4: 0x1ed4, 0xfe5: 0x1ede, 0xfe6: 0x1eed, 0xfe7: 0x1ef2, 0xfe8: 0x1f01, 0xfe9: 0x1f06,
+ 0xfea: 0x1f0b, 0xfeb: 0x1f1a, 0xfec: 0x1f1f, 0xfed: 0x1f2e, 0xfee: 0x1f33, 0xfef: 0x1f38,
+ 0xff0: 0x1f3d, 0xff1: 0x1f42, 0xff2: 0x1f47, 0xff3: 0x1f4c, 0xff4: 0x1f51, 0xff5: 0x1f56,
+ 0xff6: 0x1f5b, 0xff7: 0x1f60, 0xff8: 0x1f65, 0xff9: 0x1f6a, 0xffa: 0x1f6f, 0xffb: 0x1f74,
+ 0xffc: 0x1f79, 0xffd: 0x1f7e, 0xffe: 0x1f83, 0xfff: 0x1f8d,
+ // Block 0x40, offset 0x1000
+ 0x1000: 0x1f92, 0x1001: 0x1f97, 0x1002: 0x1f9c, 0x1003: 0x1fa6, 0x1004: 0x1fab, 0x1005: 0x1fb5,
+ 0x1006: 0x1fba, 0x1007: 0x1fbf, 0x1008: 0x1fc4, 0x1009: 0x1fc9, 0x100a: 0x1fce, 0x100b: 0x1fd3,
+ 0x100c: 0x1fd8, 0x100d: 0x1fdd, 0x100e: 0x1fec, 0x100f: 0x1ffb, 0x1010: 0x2000, 0x1011: 0x2005,
+ 0x1012: 0x200a, 0x1013: 0x200f, 0x1014: 0x2014, 0x1015: 0x201e, 0x1016: 0x2023, 0x1017: 0x2028,
+ 0x1018: 0x2037, 0x1019: 0x2046, 0x101a: 0x204b, 0x101b: 0x4437, 0x101c: 0x443d, 0x101d: 0x4473,
+ 0x101e: 0x44ca, 0x101f: 0x44d1, 0x1020: 0x44d8, 0x1021: 0x44df, 0x1022: 0x44e6, 0x1023: 0x44ed,
+ 0x1024: 0x25cc, 0x1025: 0x25d3, 0x1026: 0x25da, 0x1027: 0x25e1, 0x1028: 0x25f6, 0x1029: 0x25fd,
+ 0x102a: 0x1d9e, 0x102b: 0x1da3, 0x102c: 0x1da8, 0x102d: 0x1dad, 0x102e: 0x1db7, 0x102f: 0x1dbc,
+ 0x1030: 0x1dd0, 0x1031: 0x1dd5, 0x1032: 0x1dda, 0x1033: 0x1ddf, 0x1034: 0x1de9, 0x1035: 0x1dee,
+ 0x1036: 0x1df8, 0x1037: 0x1dfd, 0x1038: 0x1e02, 0x1039: 0x1e07, 0x103a: 0x1e11, 0x103b: 0x1e16,
+ 0x103c: 0x1f42, 0x103d: 0x1f47, 0x103e: 0x1f56, 0x103f: 0x1f5b,
+ // Block 0x41, offset 0x1040
+ 0x1040: 0x1f60, 0x1041: 0x1f74, 0x1042: 0x1f79, 0x1043: 0x1f7e, 0x1044: 0x1f83, 0x1045: 0x1f9c,
+ 0x1046: 0x1fa6, 0x1047: 0x1fab, 0x1048: 0x1fb0, 0x1049: 0x1fc4, 0x104a: 0x1fe2, 0x104b: 0x1fe7,
+ 0x104c: 0x1fec, 0x104d: 0x1ff1, 0x104e: 0x1ffb, 0x104f: 0x2000, 0x1050: 0x4473, 0x1051: 0x202d,
+ 0x1052: 0x2032, 0x1053: 0x2037, 0x1054: 0x203c, 0x1055: 0x2046, 0x1056: 0x204b, 0x1057: 0x25b7,
+ 0x1058: 0x25be, 0x1059: 0x25c5, 0x105a: 0x25da, 0x105b: 0x25e8, 0x105c: 0x1d8f, 0x105d: 0x1d94,
+ 0x105e: 0x1d99, 0x105f: 0x1da8, 0x1060: 0x1db2, 0x1061: 0x1dc1, 0x1062: 0x1dc6, 0x1063: 0x1dcb,
+ 0x1064: 0x1dda, 0x1065: 0x1de4, 0x1066: 0x1e02, 0x1067: 0x1e1b, 0x1068: 0x1e20, 0x1069: 0x1e2f,
+ 0x106a: 0x1e34, 0x106b: 0x1e43, 0x106c: 0x1e4d, 0x106d: 0x1e5c, 0x106e: 0x1e61, 0x106f: 0x1e66,
+ 0x1070: 0x1e70, 0x1071: 0x1eac, 0x1072: 0x1eb1, 0x1073: 0x1ebb, 0x1074: 0x1eca, 0x1075: 0x1ecf,
+ 0x1076: 0x1ed4, 0x1077: 0x1ede, 0x1078: 0x1eed, 0x1079: 0x1f01, 0x107a: 0x1f06, 0x107b: 0x1f0b,
+ 0x107c: 0x1f1a, 0x107d: 0x1f1f, 0x107e: 0x1f2e, 0x107f: 0x1f33,
+ // Block 0x42, offset 0x1080
+ 0x1080: 0x1f38, 0x1081: 0x1f3d, 0x1082: 0x1f4c, 0x1083: 0x1f51, 0x1084: 0x1f65, 0x1085: 0x1f6a,
+ 0x1086: 0x1f6f, 0x1087: 0x1f74, 0x1088: 0x1f79, 0x1089: 0x1f8d, 0x108a: 0x1f92, 0x108b: 0x1f97,
+ 0x108c: 0x1f9c, 0x108d: 0x1fa1, 0x108e: 0x1fb5, 0x108f: 0x1fba, 0x1090: 0x1fbf, 0x1091: 0x1fc4,
+ 0x1092: 0x1fd3, 0x1093: 0x1fd8, 0x1094: 0x1fdd, 0x1095: 0x1fec, 0x1096: 0x1ff6, 0x1097: 0x2005,
+ 0x1098: 0x200a, 0x1099: 0x4467, 0x109a: 0x201e, 0x109b: 0x2023, 0x109c: 0x2028, 0x109d: 0x2037,
+ 0x109e: 0x2041, 0x109f: 0x25da, 0x10a0: 0x25e8, 0x10a1: 0x1da8, 0x10a2: 0x1db2, 0x10a3: 0x1dda,
+ 0x10a4: 0x1de4, 0x10a5: 0x1e02, 0x10a6: 0x1e0c, 0x10a7: 0x1e70, 0x10a8: 0x1e75, 0x10a9: 0x1e98,
+ 0x10aa: 0x1e9d, 0x10ab: 0x1f74, 0x10ac: 0x1f79, 0x10ad: 0x1f9c, 0x10ae: 0x1fec, 0x10af: 0x1ff6,
+ 0x10b0: 0x2037, 0x10b1: 0x2041, 0x10b2: 0x451b, 0x10b3: 0x4523, 0x10b4: 0x452b, 0x10b5: 0x1ef7,
+ 0x10b6: 0x1efc, 0x10b7: 0x1f10, 0x10b8: 0x1f15, 0x10b9: 0x1f24, 0x10ba: 0x1f29, 0x10bb: 0x1e7a,
+ 0x10bc: 0x1e7f, 0x10bd: 0x1ea2, 0x10be: 0x1ea7, 0x10bf: 0x1e39,
+ // Block 0x43, offset 0x10c0
+ 0x10c0: 0x1e3e, 0x10c1: 0x1e25, 0x10c2: 0x1e2a, 0x10c3: 0x1e52, 0x10c4: 0x1e57, 0x10c5: 0x1ec0,
+ 0x10c6: 0x1ec5, 0x10c7: 0x1ee3, 0x10c8: 0x1ee8, 0x10c9: 0x1e84, 0x10ca: 0x1e89, 0x10cb: 0x1e8e,
+ 0x10cc: 0x1e98, 0x10cd: 0x1e93, 0x10ce: 0x1e6b, 0x10cf: 0x1eb6, 0x10d0: 0x1ed9, 0x10d1: 0x1ef7,
+ 0x10d2: 0x1efc, 0x10d3: 0x1f10, 0x10d4: 0x1f15, 0x10d5: 0x1f24, 0x10d6: 0x1f29, 0x10d7: 0x1e7a,
+ 0x10d8: 0x1e7f, 0x10d9: 0x1ea2, 0x10da: 0x1ea7, 0x10db: 0x1e39, 0x10dc: 0x1e3e, 0x10dd: 0x1e25,
+ 0x10de: 0x1e2a, 0x10df: 0x1e52, 0x10e0: 0x1e57, 0x10e1: 0x1ec0, 0x10e2: 0x1ec5, 0x10e3: 0x1ee3,
+ 0x10e4: 0x1ee8, 0x10e5: 0x1e84, 0x10e6: 0x1e89, 0x10e7: 0x1e8e, 0x10e8: 0x1e98, 0x10e9: 0x1e93,
+ 0x10ea: 0x1e6b, 0x10eb: 0x1eb6, 0x10ec: 0x1ed9, 0x10ed: 0x1e84, 0x10ee: 0x1e89, 0x10ef: 0x1e8e,
+ 0x10f0: 0x1e98, 0x10f1: 0x1e75, 0x10f2: 0x1e9d, 0x10f3: 0x1ef2, 0x10f4: 0x1e5c, 0x10f5: 0x1e61,
+ 0x10f6: 0x1e66, 0x10f7: 0x1e84, 0x10f8: 0x1e89, 0x10f9: 0x1e8e, 0x10fa: 0x1ef2, 0x10fb: 0x1f01,
+ 0x10fc: 0x441f, 0x10fd: 0x441f,
+ // Block 0x44, offset 0x1100
+ 0x1110: 0x2317, 0x1111: 0x232c,
+ 0x1112: 0x232c, 0x1113: 0x2333, 0x1114: 0x233a, 0x1115: 0x234f, 0x1116: 0x2356, 0x1117: 0x235d,
+ 0x1118: 0x2380, 0x1119: 0x2380, 0x111a: 0x23a3, 0x111b: 0x239c, 0x111c: 0x23b8, 0x111d: 0x23aa,
+ 0x111e: 0x23b1, 0x111f: 0x23d4, 0x1120: 0x23d4, 0x1121: 0x23cd, 0x1122: 0x23db, 0x1123: 0x23db,
+ 0x1124: 0x2405, 0x1125: 0x2405, 0x1126: 0x2421, 0x1127: 0x23e9, 0x1128: 0x23e9, 0x1129: 0x23e2,
+ 0x112a: 0x23f7, 0x112b: 0x23f7, 0x112c: 0x23fe, 0x112d: 0x23fe, 0x112e: 0x2428, 0x112f: 0x2436,
+ 0x1130: 0x2436, 0x1131: 0x243d, 0x1132: 0x243d, 0x1133: 0x2444, 0x1134: 0x244b, 0x1135: 0x2452,
+ 0x1136: 0x2459, 0x1137: 0x2459, 0x1138: 0x2460, 0x1139: 0x246e, 0x113a: 0x247c, 0x113b: 0x2475,
+ 0x113c: 0x2483, 0x113d: 0x2483, 0x113e: 0x2498, 0x113f: 0x249f,
+ // Block 0x45, offset 0x1140
+ 0x1140: 0x24d0, 0x1141: 0x24de, 0x1142: 0x24d7, 0x1143: 0x24bb, 0x1144: 0x24bb, 0x1145: 0x24e5,
+ 0x1146: 0x24e5, 0x1147: 0x24ec, 0x1148: 0x24ec, 0x1149: 0x2516, 0x114a: 0x251d, 0x114b: 0x2524,
+ 0x114c: 0x24fa, 0x114d: 0x2508, 0x114e: 0x252b, 0x114f: 0x2532,
+ 0x1152: 0x2501, 0x1153: 0x2586, 0x1154: 0x258d, 0x1155: 0x2563, 0x1156: 0x256a, 0x1157: 0x254e,
+ 0x1158: 0x254e, 0x1159: 0x2555, 0x115a: 0x257f, 0x115b: 0x2578, 0x115c: 0x25a2, 0x115d: 0x25a2,
+ 0x115e: 0x2310, 0x115f: 0x2325, 0x1160: 0x231e, 0x1161: 0x2348, 0x1162: 0x2341, 0x1163: 0x236b,
+ 0x1164: 0x2364, 0x1165: 0x238e, 0x1166: 0x2372, 0x1167: 0x2387, 0x1168: 0x23bf, 0x1169: 0x240c,
+ 0x116a: 0x23f0, 0x116b: 0x242f, 0x116c: 0x24c9, 0x116d: 0x24f3, 0x116e: 0x259b, 0x116f: 0x2594,
+ 0x1170: 0x25a9, 0x1171: 0x2540, 0x1172: 0x24a6, 0x1173: 0x2571, 0x1174: 0x2498, 0x1175: 0x24d0,
+ 0x1176: 0x2467, 0x1177: 0x24b4, 0x1178: 0x2547, 0x1179: 0x2539, 0x117a: 0x24c2, 0x117b: 0x24ad,
+ 0x117c: 0x24c2, 0x117d: 0x2547, 0x117e: 0x2379, 0x117f: 0x2395,
+ // Block 0x46, offset 0x1180
+ 0x1180: 0x250f, 0x1181: 0x248a, 0x1182: 0x2309, 0x1183: 0x24ad, 0x1184: 0x2452, 0x1185: 0x2421,
+ 0x1186: 0x23c6, 0x1187: 0x255c,
+ 0x11b0: 0x241a, 0x11b1: 0x2491, 0x11b2: 0x27cc, 0x11b3: 0x27c3, 0x11b4: 0x27f9, 0x11b5: 0x27e7,
+ 0x11b6: 0x27d5, 0x11b7: 0x27f0, 0x11b8: 0x2802, 0x11b9: 0x2413, 0x11ba: 0x2c89, 0x11bb: 0x2b09,
+ 0x11bc: 0x27de,
+ // Block 0x47, offset 0x11c0
+ 0x11d0: 0x0019, 0x11d1: 0x0486,
+ 0x11d2: 0x048a, 0x11d3: 0x0035, 0x11d4: 0x0037, 0x11d5: 0x0003, 0x11d6: 0x003f, 0x11d7: 0x04c2,
+ 0x11d8: 0x04c6, 0x11d9: 0x1b62,
+ 0x11e0: 0x8133, 0x11e1: 0x8133, 0x11e2: 0x8133, 0x11e3: 0x8133,
+ 0x11e4: 0x8133, 0x11e5: 0x8133, 0x11e6: 0x8133, 0x11e7: 0x812e, 0x11e8: 0x812e, 0x11e9: 0x812e,
+ 0x11ea: 0x812e, 0x11eb: 0x812e, 0x11ec: 0x812e, 0x11ed: 0x812e, 0x11ee: 0x8133, 0x11ef: 0x8133,
+ 0x11f0: 0x1876, 0x11f1: 0x0446, 0x11f2: 0x0442, 0x11f3: 0x007f, 0x11f4: 0x007f, 0x11f5: 0x0011,
+ 0x11f6: 0x0013, 0x11f7: 0x00b7, 0x11f8: 0x00bb, 0x11f9: 0x04ba, 0x11fa: 0x04be, 0x11fb: 0x04ae,
+ 0x11fc: 0x04b2, 0x11fd: 0x0496, 0x11fe: 0x049a, 0x11ff: 0x048e,
+ // Block 0x48, offset 0x1200
+ 0x1200: 0x0492, 0x1201: 0x049e, 0x1202: 0x04a2, 0x1203: 0x04a6, 0x1204: 0x04aa,
+ 0x1207: 0x0077, 0x1208: 0x007b, 0x1209: 0x4280, 0x120a: 0x4280, 0x120b: 0x4280,
+ 0x120c: 0x4280, 0x120d: 0x007f, 0x120e: 0x007f, 0x120f: 0x007f, 0x1210: 0x0019, 0x1211: 0x0486,
+ 0x1212: 0x001d, 0x1214: 0x0037, 0x1215: 0x0035, 0x1216: 0x003f, 0x1217: 0x0003,
+ 0x1218: 0x0446, 0x1219: 0x0011, 0x121a: 0x0013, 0x121b: 0x00b7, 0x121c: 0x00bb, 0x121d: 0x04ba,
+ 0x121e: 0x04be, 0x121f: 0x0007, 0x1220: 0x000d, 0x1221: 0x0015, 0x1222: 0x0017, 0x1223: 0x001b,
+ 0x1224: 0x0039, 0x1225: 0x003d, 0x1226: 0x003b, 0x1228: 0x0079, 0x1229: 0x0009,
+ 0x122a: 0x000b, 0x122b: 0x0041,
+ 0x1230: 0x42c1, 0x1231: 0x4443, 0x1232: 0x42c6, 0x1234: 0x42cb,
+ 0x1236: 0x42d0, 0x1237: 0x4449, 0x1238: 0x42d5, 0x1239: 0x444f, 0x123a: 0x42da, 0x123b: 0x4455,
+ 0x123c: 0x42df, 0x123d: 0x445b, 0x123e: 0x42e4, 0x123f: 0x4461,
+ // Block 0x49, offset 0x1240
+ 0x1240: 0x0239, 0x1241: 0x4425, 0x1242: 0x4425, 0x1243: 0x442b, 0x1244: 0x442b, 0x1245: 0x446d,
+ 0x1246: 0x446d, 0x1247: 0x4431, 0x1248: 0x4431, 0x1249: 0x4479, 0x124a: 0x4479, 0x124b: 0x4479,
+ 0x124c: 0x4479, 0x124d: 0x023c, 0x124e: 0x023c, 0x124f: 0x023f, 0x1250: 0x023f, 0x1251: 0x023f,
+ 0x1252: 0x023f, 0x1253: 0x0242, 0x1254: 0x0242, 0x1255: 0x0245, 0x1256: 0x0245, 0x1257: 0x0245,
+ 0x1258: 0x0245, 0x1259: 0x0248, 0x125a: 0x0248, 0x125b: 0x0248, 0x125c: 0x0248, 0x125d: 0x024b,
+ 0x125e: 0x024b, 0x125f: 0x024b, 0x1260: 0x024b, 0x1261: 0x024e, 0x1262: 0x024e, 0x1263: 0x024e,
+ 0x1264: 0x024e, 0x1265: 0x0251, 0x1266: 0x0251, 0x1267: 0x0251, 0x1268: 0x0251, 0x1269: 0x0254,
+ 0x126a: 0x0254, 0x126b: 0x0257, 0x126c: 0x0257, 0x126d: 0x025a, 0x126e: 0x025a, 0x126f: 0x025d,
+ 0x1270: 0x025d, 0x1271: 0x0260, 0x1272: 0x0260, 0x1273: 0x0260, 0x1274: 0x0260, 0x1275: 0x0263,
+ 0x1276: 0x0263, 0x1277: 0x0263, 0x1278: 0x0263, 0x1279: 0x0266, 0x127a: 0x0266, 0x127b: 0x0266,
+ 0x127c: 0x0266, 0x127d: 0x0269, 0x127e: 0x0269, 0x127f: 0x0269,
+ // Block 0x4a, offset 0x1280
+ 0x1280: 0x0269, 0x1281: 0x026c, 0x1282: 0x026c, 0x1283: 0x026c, 0x1284: 0x026c, 0x1285: 0x026f,
+ 0x1286: 0x026f, 0x1287: 0x026f, 0x1288: 0x026f, 0x1289: 0x0272, 0x128a: 0x0272, 0x128b: 0x0272,
+ 0x128c: 0x0272, 0x128d: 0x0275, 0x128e: 0x0275, 0x128f: 0x0275, 0x1290: 0x0275, 0x1291: 0x0278,
+ 0x1292: 0x0278, 0x1293: 0x0278, 0x1294: 0x0278, 0x1295: 0x027b, 0x1296: 0x027b, 0x1297: 0x027b,
+ 0x1298: 0x027b, 0x1299: 0x027e, 0x129a: 0x027e, 0x129b: 0x027e, 0x129c: 0x027e, 0x129d: 0x0281,
+ 0x129e: 0x0281, 0x129f: 0x0281, 0x12a0: 0x0281, 0x12a1: 0x0284, 0x12a2: 0x0284, 0x12a3: 0x0284,
+ 0x12a4: 0x0284, 0x12a5: 0x0287, 0x12a6: 0x0287, 0x12a7: 0x0287, 0x12a8: 0x0287, 0x12a9: 0x028a,
+ 0x12aa: 0x028a, 0x12ab: 0x028a, 0x12ac: 0x028a, 0x12ad: 0x028d, 0x12ae: 0x028d, 0x12af: 0x0290,
+ 0x12b0: 0x0290, 0x12b1: 0x0293, 0x12b2: 0x0293, 0x12b3: 0x0293, 0x12b4: 0x0293, 0x12b5: 0x2e17,
+ 0x12b6: 0x2e17, 0x12b7: 0x2e1f, 0x12b8: 0x2e1f, 0x12b9: 0x2e27, 0x12ba: 0x2e27, 0x12bb: 0x1f88,
+ 0x12bc: 0x1f88,
+ // Block 0x4b, offset 0x12c0
+ 0x12c0: 0x0081, 0x12c1: 0x0083, 0x12c2: 0x0085, 0x12c3: 0x0087, 0x12c4: 0x0089, 0x12c5: 0x008b,
+ 0x12c6: 0x008d, 0x12c7: 0x008f, 0x12c8: 0x0091, 0x12c9: 0x0093, 0x12ca: 0x0095, 0x12cb: 0x0097,
+ 0x12cc: 0x0099, 0x12cd: 0x009b, 0x12ce: 0x009d, 0x12cf: 0x009f, 0x12d0: 0x00a1, 0x12d1: 0x00a3,
+ 0x12d2: 0x00a5, 0x12d3: 0x00a7, 0x12d4: 0x00a9, 0x12d5: 0x00ab, 0x12d6: 0x00ad, 0x12d7: 0x00af,
+ 0x12d8: 0x00b1, 0x12d9: 0x00b3, 0x12da: 0x00b5, 0x12db: 0x00b7, 0x12dc: 0x00b9, 0x12dd: 0x00bb,
+ 0x12de: 0x00bd, 0x12df: 0x047a, 0x12e0: 0x047e, 0x12e1: 0x048a, 0x12e2: 0x049e, 0x12e3: 0x04a2,
+ 0x12e4: 0x0486, 0x12e5: 0x05ae, 0x12e6: 0x05a6, 0x12e7: 0x04ca, 0x12e8: 0x04d2, 0x12e9: 0x04da,
+ 0x12ea: 0x04e2, 0x12eb: 0x04ea, 0x12ec: 0x056e, 0x12ed: 0x0576, 0x12ee: 0x057e, 0x12ef: 0x0522,
+ 0x12f0: 0x05b2, 0x12f1: 0x04ce, 0x12f2: 0x04d6, 0x12f3: 0x04de, 0x12f4: 0x04e6, 0x12f5: 0x04ee,
+ 0x12f6: 0x04f2, 0x12f7: 0x04f6, 0x12f8: 0x04fa, 0x12f9: 0x04fe, 0x12fa: 0x0502, 0x12fb: 0x0506,
+ 0x12fc: 0x050a, 0x12fd: 0x050e, 0x12fe: 0x0512, 0x12ff: 0x0516,
+ // Block 0x4c, offset 0x1300
+ 0x1300: 0x051a, 0x1301: 0x051e, 0x1302: 0x0526, 0x1303: 0x052a, 0x1304: 0x052e, 0x1305: 0x0532,
+ 0x1306: 0x0536, 0x1307: 0x053a, 0x1308: 0x053e, 0x1309: 0x0542, 0x130a: 0x0546, 0x130b: 0x054a,
+ 0x130c: 0x054e, 0x130d: 0x0552, 0x130e: 0x0556, 0x130f: 0x055a, 0x1310: 0x055e, 0x1311: 0x0562,
+ 0x1312: 0x0566, 0x1313: 0x056a, 0x1314: 0x0572, 0x1315: 0x057a, 0x1316: 0x0582, 0x1317: 0x0586,
+ 0x1318: 0x058a, 0x1319: 0x058e, 0x131a: 0x0592, 0x131b: 0x0596, 0x131c: 0x059a, 0x131d: 0x05aa,
+ 0x131e: 0x4a8f, 0x131f: 0x4a95, 0x1320: 0x03c6, 0x1321: 0x0316, 0x1322: 0x031a, 0x1323: 0x4a52,
+ 0x1324: 0x031e, 0x1325: 0x4a58, 0x1326: 0x4a5e, 0x1327: 0x0322, 0x1328: 0x0326, 0x1329: 0x032a,
+ 0x132a: 0x4a64, 0x132b: 0x4a6a, 0x132c: 0x4a70, 0x132d: 0x4a76, 0x132e: 0x4a7c, 0x132f: 0x4a82,
+ 0x1330: 0x036a, 0x1331: 0x032e, 0x1332: 0x0332, 0x1333: 0x0336, 0x1334: 0x037e, 0x1335: 0x033a,
+ 0x1336: 0x033e, 0x1337: 0x0342, 0x1338: 0x0346, 0x1339: 0x034a, 0x133a: 0x034e, 0x133b: 0x0352,
+ 0x133c: 0x0356, 0x133d: 0x035a, 0x133e: 0x035e,
+ // Block 0x4d, offset 0x1340
+ 0x1342: 0x49d4, 0x1343: 0x49da, 0x1344: 0x49e0, 0x1345: 0x49e6,
+ 0x1346: 0x49ec, 0x1347: 0x49f2, 0x134a: 0x49f8, 0x134b: 0x49fe,
+ 0x134c: 0x4a04, 0x134d: 0x4a0a, 0x134e: 0x4a10, 0x134f: 0x4a16,
+ 0x1352: 0x4a1c, 0x1353: 0x4a22, 0x1354: 0x4a28, 0x1355: 0x4a2e, 0x1356: 0x4a34, 0x1357: 0x4a3a,
+ 0x135a: 0x4a40, 0x135b: 0x4a46, 0x135c: 0x4a4c,
+ 0x1360: 0x00bf, 0x1361: 0x00c2, 0x1362: 0x00cb, 0x1363: 0x427b,
+ 0x1364: 0x00c8, 0x1365: 0x00c5, 0x1366: 0x044a, 0x1368: 0x046e, 0x1369: 0x044e,
+ 0x136a: 0x0452, 0x136b: 0x0456, 0x136c: 0x045a, 0x136d: 0x0472, 0x136e: 0x0476,
+ // Block 0x4e, offset 0x1380
+ 0x1380: 0x0063, 0x1381: 0x0065, 0x1382: 0x0067, 0x1383: 0x0069, 0x1384: 0x006b, 0x1385: 0x006d,
+ 0x1386: 0x006f, 0x1387: 0x0071, 0x1388: 0x0073, 0x1389: 0x0075, 0x138a: 0x0083, 0x138b: 0x0085,
+ 0x138c: 0x0087, 0x138d: 0x0089, 0x138e: 0x008b, 0x138f: 0x008d, 0x1390: 0x008f, 0x1391: 0x0091,
+ 0x1392: 0x0093, 0x1393: 0x0095, 0x1394: 0x0097, 0x1395: 0x0099, 0x1396: 0x009b, 0x1397: 0x009d,
+ 0x1398: 0x009f, 0x1399: 0x00a1, 0x139a: 0x00a3, 0x139b: 0x00a5, 0x139c: 0x00a7, 0x139d: 0x00a9,
+ 0x139e: 0x00ab, 0x139f: 0x00ad, 0x13a0: 0x00af, 0x13a1: 0x00b1, 0x13a2: 0x00b3, 0x13a3: 0x00b5,
+ 0x13a4: 0x00dd, 0x13a5: 0x00f2, 0x13a8: 0x0176, 0x13a9: 0x0179,
+ 0x13aa: 0x017c, 0x13ab: 0x017f, 0x13ac: 0x0182, 0x13ad: 0x0185, 0x13ae: 0x0188, 0x13af: 0x018b,
+ 0x13b0: 0x018e, 0x13b1: 0x0191, 0x13b2: 0x0194, 0x13b3: 0x0197, 0x13b4: 0x019a, 0x13b5: 0x019d,
+ 0x13b6: 0x01a0, 0x13b7: 0x01a3, 0x13b8: 0x01a6, 0x13b9: 0x018b, 0x13ba: 0x01a9, 0x13bb: 0x01ac,
+ 0x13bc: 0x01af, 0x13bd: 0x01b2, 0x13be: 0x01b5, 0x13bf: 0x01b8,
+ // Block 0x4f, offset 0x13c0
+ 0x13c0: 0x0200, 0x13c1: 0x0203, 0x13c2: 0x0206, 0x13c3: 0x045e, 0x13c4: 0x01ca, 0x13c5: 0x01d3,
+ 0x13c6: 0x01d9, 0x13c7: 0x01fd, 0x13c8: 0x01ee, 0x13c9: 0x01eb, 0x13ca: 0x0209, 0x13cb: 0x020c,
+ 0x13ce: 0x0021, 0x13cf: 0x0023, 0x13d0: 0x0025, 0x13d1: 0x0027,
+ 0x13d2: 0x0029, 0x13d3: 0x002b, 0x13d4: 0x002d, 0x13d5: 0x002f, 0x13d6: 0x0031, 0x13d7: 0x0033,
+ 0x13d8: 0x0021, 0x13d9: 0x0023, 0x13da: 0x0025, 0x13db: 0x0027, 0x13dc: 0x0029, 0x13dd: 0x002b,
+ 0x13de: 0x002d, 0x13df: 0x002f, 0x13e0: 0x0031, 0x13e1: 0x0033, 0x13e2: 0x0021, 0x13e3: 0x0023,
+ 0x13e4: 0x0025, 0x13e5: 0x0027, 0x13e6: 0x0029, 0x13e7: 0x002b, 0x13e8: 0x002d, 0x13e9: 0x002f,
+ 0x13ea: 0x0031, 0x13eb: 0x0033, 0x13ec: 0x0021, 0x13ed: 0x0023, 0x13ee: 0x0025, 0x13ef: 0x0027,
+ 0x13f0: 0x0029, 0x13f1: 0x002b, 0x13f2: 0x002d, 0x13f3: 0x002f, 0x13f4: 0x0031, 0x13f5: 0x0033,
+ 0x13f6: 0x0021, 0x13f7: 0x0023, 0x13f8: 0x0025, 0x13f9: 0x0027, 0x13fa: 0x0029, 0x13fb: 0x002b,
+ 0x13fc: 0x002d, 0x13fd: 0x002f, 0x13fe: 0x0031, 0x13ff: 0x0033,
+ // Block 0x50, offset 0x1400
+ 0x1400: 0x023c, 0x1401: 0x023f, 0x1402: 0x024b, 0x1403: 0x0254, 0x1405: 0x028d,
+ 0x1406: 0x025d, 0x1407: 0x024e, 0x1408: 0x026c, 0x1409: 0x0293, 0x140a: 0x027e, 0x140b: 0x0281,
+ 0x140c: 0x0284, 0x140d: 0x0287, 0x140e: 0x0260, 0x140f: 0x0272, 0x1410: 0x0278, 0x1411: 0x0266,
+ 0x1412: 0x027b, 0x1413: 0x025a, 0x1414: 0x0263, 0x1415: 0x0245, 0x1416: 0x0248, 0x1417: 0x0251,
+ 0x1418: 0x0257, 0x1419: 0x0269, 0x141a: 0x026f, 0x141b: 0x0275, 0x141c: 0x0296, 0x141d: 0x02e7,
+ 0x141e: 0x02cf, 0x141f: 0x0299, 0x1421: 0x023f, 0x1422: 0x024b,
+ 0x1424: 0x028a, 0x1427: 0x024e, 0x1429: 0x0293,
+ 0x142a: 0x027e, 0x142b: 0x0281, 0x142c: 0x0284, 0x142d: 0x0287, 0x142e: 0x0260, 0x142f: 0x0272,
+ 0x1430: 0x0278, 0x1431: 0x0266, 0x1432: 0x027b, 0x1434: 0x0263, 0x1435: 0x0245,
+ 0x1436: 0x0248, 0x1437: 0x0251, 0x1439: 0x0269, 0x143b: 0x0275,
+ // Block 0x51, offset 0x1440
+ 0x1442: 0x024b,
+ 0x1447: 0x024e, 0x1449: 0x0293, 0x144b: 0x0281,
+ 0x144d: 0x0287, 0x144e: 0x0260, 0x144f: 0x0272, 0x1451: 0x0266,
+ 0x1452: 0x027b, 0x1454: 0x0263, 0x1457: 0x0251,
+ 0x1459: 0x0269, 0x145b: 0x0275, 0x145d: 0x02e7,
+ 0x145f: 0x0299, 0x1461: 0x023f, 0x1462: 0x024b,
+ 0x1464: 0x028a, 0x1467: 0x024e, 0x1468: 0x026c, 0x1469: 0x0293,
+ 0x146a: 0x027e, 0x146c: 0x0284, 0x146d: 0x0287, 0x146e: 0x0260, 0x146f: 0x0272,
+ 0x1470: 0x0278, 0x1471: 0x0266, 0x1472: 0x027b, 0x1474: 0x0263, 0x1475: 0x0245,
+ 0x1476: 0x0248, 0x1477: 0x0251, 0x1479: 0x0269, 0x147a: 0x026f, 0x147b: 0x0275,
+ 0x147c: 0x0296, 0x147e: 0x02cf,
+ // Block 0x52, offset 0x1480
+ 0x1480: 0x023c, 0x1481: 0x023f, 0x1482: 0x024b, 0x1483: 0x0254, 0x1484: 0x028a, 0x1485: 0x028d,
+ 0x1486: 0x025d, 0x1487: 0x024e, 0x1488: 0x026c, 0x1489: 0x0293, 0x148b: 0x0281,
+ 0x148c: 0x0284, 0x148d: 0x0287, 0x148e: 0x0260, 0x148f: 0x0272, 0x1490: 0x0278, 0x1491: 0x0266,
+ 0x1492: 0x027b, 0x1493: 0x025a, 0x1494: 0x0263, 0x1495: 0x0245, 0x1496: 0x0248, 0x1497: 0x0251,
+ 0x1498: 0x0257, 0x1499: 0x0269, 0x149a: 0x026f, 0x149b: 0x0275,
+ 0x14a1: 0x023f, 0x14a2: 0x024b, 0x14a3: 0x0254,
+ 0x14a5: 0x028d, 0x14a6: 0x025d, 0x14a7: 0x024e, 0x14a8: 0x026c, 0x14a9: 0x0293,
+ 0x14ab: 0x0281, 0x14ac: 0x0284, 0x14ad: 0x0287, 0x14ae: 0x0260, 0x14af: 0x0272,
+ 0x14b0: 0x0278, 0x14b1: 0x0266, 0x14b2: 0x027b, 0x14b3: 0x025a, 0x14b4: 0x0263, 0x14b5: 0x0245,
+ 0x14b6: 0x0248, 0x14b7: 0x0251, 0x14b8: 0x0257, 0x14b9: 0x0269, 0x14ba: 0x026f, 0x14bb: 0x0275,
+ // Block 0x53, offset 0x14c0
+ 0x14c0: 0x187c, 0x14c1: 0x1879, 0x14c2: 0x187f, 0x14c3: 0x18a3, 0x14c4: 0x18c7, 0x14c5: 0x18eb,
+ 0x14c6: 0x190f, 0x14c7: 0x1918, 0x14c8: 0x191e, 0x14c9: 0x1924, 0x14ca: 0x192a,
+ 0x14d0: 0x1a92, 0x14d1: 0x1a96,
+ 0x14d2: 0x1a9a, 0x14d3: 0x1a9e, 0x14d4: 0x1aa2, 0x14d5: 0x1aa6, 0x14d6: 0x1aaa, 0x14d7: 0x1aae,
+ 0x14d8: 0x1ab2, 0x14d9: 0x1ab6, 0x14da: 0x1aba, 0x14db: 0x1abe, 0x14dc: 0x1ac2, 0x14dd: 0x1ac6,
+ 0x14de: 0x1aca, 0x14df: 0x1ace, 0x14e0: 0x1ad2, 0x14e1: 0x1ad6, 0x14e2: 0x1ada, 0x14e3: 0x1ade,
+ 0x14e4: 0x1ae2, 0x14e5: 0x1ae6, 0x14e6: 0x1aea, 0x14e7: 0x1aee, 0x14e8: 0x1af2, 0x14e9: 0x1af6,
+ 0x14ea: 0x272b, 0x14eb: 0x0047, 0x14ec: 0x0065, 0x14ed: 0x193f, 0x14ee: 0x19b7,
+ 0x14f0: 0x0043, 0x14f1: 0x0045, 0x14f2: 0x0047, 0x14f3: 0x0049, 0x14f4: 0x004b, 0x14f5: 0x004d,
+ 0x14f6: 0x004f, 0x14f7: 0x0051, 0x14f8: 0x0053, 0x14f9: 0x0055, 0x14fa: 0x0057, 0x14fb: 0x0059,
+ 0x14fc: 0x005b, 0x14fd: 0x005d, 0x14fe: 0x005f, 0x14ff: 0x0061,
+ // Block 0x54, offset 0x1500
+ 0x1500: 0x26b3, 0x1501: 0x26c8, 0x1502: 0x0506,
+ 0x1510: 0x0c12, 0x1511: 0x0a4a,
+ 0x1512: 0x08d6, 0x1513: 0x45db, 0x1514: 0x071e, 0x1515: 0x09f2, 0x1516: 0x1332, 0x1517: 0x0a02,
+ 0x1518: 0x072a, 0x1519: 0x0cda, 0x151a: 0x0eb2, 0x151b: 0x0cb2, 0x151c: 0x082a, 0x151d: 0x0b6e,
+ 0x151e: 0x07c2, 0x151f: 0x0cba, 0x1520: 0x0816, 0x1521: 0x111a, 0x1522: 0x0f86, 0x1523: 0x138e,
+ 0x1524: 0x09d6, 0x1525: 0x090e, 0x1526: 0x0e66, 0x1527: 0x0c1e, 0x1528: 0x0c4a, 0x1529: 0x06c2,
+ 0x152a: 0x06ce, 0x152b: 0x140e, 0x152c: 0x0ade, 0x152d: 0x06ea, 0x152e: 0x08f2, 0x152f: 0x0c3e,
+ 0x1530: 0x13b6, 0x1531: 0x0c16, 0x1532: 0x1072, 0x1533: 0x10ae, 0x1534: 0x08fa, 0x1535: 0x0e46,
+ 0x1536: 0x0d0e, 0x1537: 0x0d0a, 0x1538: 0x0f9a, 0x1539: 0x082e, 0x153a: 0x095a, 0x153b: 0x1446,
+ // Block 0x55, offset 0x1540
+ 0x1540: 0x06fe, 0x1541: 0x06f6, 0x1542: 0x0706, 0x1543: 0x164a, 0x1544: 0x074a, 0x1545: 0x075a,
+ 0x1546: 0x075e, 0x1547: 0x0766, 0x1548: 0x076e, 0x1549: 0x0772, 0x154a: 0x077e, 0x154b: 0x0776,
+ 0x154c: 0x05b6, 0x154d: 0x165e, 0x154e: 0x0792, 0x154f: 0x0796, 0x1550: 0x079a, 0x1551: 0x07b6,
+ 0x1552: 0x164f, 0x1553: 0x05ba, 0x1554: 0x07a2, 0x1555: 0x07c2, 0x1556: 0x1659, 0x1557: 0x07d2,
+ 0x1558: 0x07da, 0x1559: 0x073a, 0x155a: 0x07e2, 0x155b: 0x07e6, 0x155c: 0x1834, 0x155d: 0x0802,
+ 0x155e: 0x080a, 0x155f: 0x05c2, 0x1560: 0x0822, 0x1561: 0x0826, 0x1562: 0x082e, 0x1563: 0x0832,
+ 0x1564: 0x05c6, 0x1565: 0x084a, 0x1566: 0x084e, 0x1567: 0x085a, 0x1568: 0x0866, 0x1569: 0x086a,
+ 0x156a: 0x086e, 0x156b: 0x0876, 0x156c: 0x0896, 0x156d: 0x089a, 0x156e: 0x08a2, 0x156f: 0x08b2,
+ 0x1570: 0x08ba, 0x1571: 0x08be, 0x1572: 0x08be, 0x1573: 0x08be, 0x1574: 0x166d, 0x1575: 0x0e96,
+ 0x1576: 0x08d2, 0x1577: 0x08da, 0x1578: 0x1672, 0x1579: 0x08e6, 0x157a: 0x08ee, 0x157b: 0x08f6,
+ 0x157c: 0x091e, 0x157d: 0x090a, 0x157e: 0x0916, 0x157f: 0x091a,
+ // Block 0x56, offset 0x1580
+ 0x1580: 0x0922, 0x1581: 0x092a, 0x1582: 0x092e, 0x1583: 0x0936, 0x1584: 0x093e, 0x1585: 0x0942,
+ 0x1586: 0x0942, 0x1587: 0x094a, 0x1588: 0x0952, 0x1589: 0x0956, 0x158a: 0x0962, 0x158b: 0x0986,
+ 0x158c: 0x096a, 0x158d: 0x098a, 0x158e: 0x096e, 0x158f: 0x0976, 0x1590: 0x080e, 0x1591: 0x09d2,
+ 0x1592: 0x099a, 0x1593: 0x099e, 0x1594: 0x09a2, 0x1595: 0x0996, 0x1596: 0x09aa, 0x1597: 0x09a6,
+ 0x1598: 0x09be, 0x1599: 0x1677, 0x159a: 0x09da, 0x159b: 0x09de, 0x159c: 0x09e6, 0x159d: 0x09f2,
+ 0x159e: 0x09fa, 0x159f: 0x0a16, 0x15a0: 0x167c, 0x15a1: 0x1681, 0x15a2: 0x0a22, 0x15a3: 0x0a26,
+ 0x15a4: 0x0a2a, 0x15a5: 0x0a1e, 0x15a6: 0x0a32, 0x15a7: 0x05ca, 0x15a8: 0x05ce, 0x15a9: 0x0a3a,
+ 0x15aa: 0x0a42, 0x15ab: 0x0a42, 0x15ac: 0x1686, 0x15ad: 0x0a5e, 0x15ae: 0x0a62, 0x15af: 0x0a66,
+ 0x15b0: 0x0a6e, 0x15b1: 0x168b, 0x15b2: 0x0a76, 0x15b3: 0x0a7a, 0x15b4: 0x0b52, 0x15b5: 0x0a82,
+ 0x15b6: 0x05d2, 0x15b7: 0x0a8e, 0x15b8: 0x0a9e, 0x15b9: 0x0aaa, 0x15ba: 0x0aa6, 0x15bb: 0x1695,
+ 0x15bc: 0x0ab2, 0x15bd: 0x169a, 0x15be: 0x0abe, 0x15bf: 0x0aba,
+ // Block 0x57, offset 0x15c0
+ 0x15c0: 0x0ac2, 0x15c1: 0x0ad2, 0x15c2: 0x0ad6, 0x15c3: 0x05d6, 0x15c4: 0x0ae6, 0x15c5: 0x0aee,
+ 0x15c6: 0x0af2, 0x15c7: 0x0af6, 0x15c8: 0x05da, 0x15c9: 0x169f, 0x15ca: 0x05de, 0x15cb: 0x0b12,
+ 0x15cc: 0x0b16, 0x15cd: 0x0b1a, 0x15ce: 0x0b22, 0x15cf: 0x1866, 0x15d0: 0x0b3a, 0x15d1: 0x16a9,
+ 0x15d2: 0x16a9, 0x15d3: 0x11da, 0x15d4: 0x0b4a, 0x15d5: 0x0b4a, 0x15d6: 0x05e2, 0x15d7: 0x16cc,
+ 0x15d8: 0x179e, 0x15d9: 0x0b5a, 0x15da: 0x0b62, 0x15db: 0x05e6, 0x15dc: 0x0b76, 0x15dd: 0x0b86,
+ 0x15de: 0x0b8a, 0x15df: 0x0b92, 0x15e0: 0x0ba2, 0x15e1: 0x05ee, 0x15e2: 0x05ea, 0x15e3: 0x0ba6,
+ 0x15e4: 0x16ae, 0x15e5: 0x0baa, 0x15e6: 0x0bbe, 0x15e7: 0x0bc2, 0x15e8: 0x0bc6, 0x15e9: 0x0bc2,
+ 0x15ea: 0x0bd2, 0x15eb: 0x0bd6, 0x15ec: 0x0be6, 0x15ed: 0x0bde, 0x15ee: 0x0be2, 0x15ef: 0x0bea,
+ 0x15f0: 0x0bee, 0x15f1: 0x0bf2, 0x15f2: 0x0bfe, 0x15f3: 0x0c02, 0x15f4: 0x0c1a, 0x15f5: 0x0c22,
+ 0x15f6: 0x0c32, 0x15f7: 0x0c46, 0x15f8: 0x16bd, 0x15f9: 0x0c42, 0x15fa: 0x0c36, 0x15fb: 0x0c4e,
+ 0x15fc: 0x0c56, 0x15fd: 0x0c6a, 0x15fe: 0x16c2, 0x15ff: 0x0c72,
+ // Block 0x58, offset 0x1600
+ 0x1600: 0x0c66, 0x1601: 0x0c5e, 0x1602: 0x05f2, 0x1603: 0x0c7a, 0x1604: 0x0c82, 0x1605: 0x0c8a,
+ 0x1606: 0x0c7e, 0x1607: 0x05f6, 0x1608: 0x0c9a, 0x1609: 0x0ca2, 0x160a: 0x16c7, 0x160b: 0x0cce,
+ 0x160c: 0x0d02, 0x160d: 0x0cde, 0x160e: 0x0602, 0x160f: 0x0cea, 0x1610: 0x05fe, 0x1611: 0x05fa,
+ 0x1612: 0x07c6, 0x1613: 0x07ca, 0x1614: 0x0d06, 0x1615: 0x0cee, 0x1616: 0x11ae, 0x1617: 0x0666,
+ 0x1618: 0x0d12, 0x1619: 0x0d16, 0x161a: 0x0d1a, 0x161b: 0x0d2e, 0x161c: 0x0d26, 0x161d: 0x16e0,
+ 0x161e: 0x0606, 0x161f: 0x0d42, 0x1620: 0x0d36, 0x1621: 0x0d52, 0x1622: 0x0d5a, 0x1623: 0x16ea,
+ 0x1624: 0x0d5e, 0x1625: 0x0d4a, 0x1626: 0x0d66, 0x1627: 0x060a, 0x1628: 0x0d6a, 0x1629: 0x0d6e,
+ 0x162a: 0x0d72, 0x162b: 0x0d7e, 0x162c: 0x16ef, 0x162d: 0x0d86, 0x162e: 0x060e, 0x162f: 0x0d92,
+ 0x1630: 0x16f4, 0x1631: 0x0d96, 0x1632: 0x0612, 0x1633: 0x0da2, 0x1634: 0x0dae, 0x1635: 0x0dba,
+ 0x1636: 0x0dbe, 0x1637: 0x16f9, 0x1638: 0x1690, 0x1639: 0x16fe, 0x163a: 0x0dde, 0x163b: 0x1703,
+ 0x163c: 0x0dea, 0x163d: 0x0df2, 0x163e: 0x0de2, 0x163f: 0x0dfe,
+ // Block 0x59, offset 0x1640
+ 0x1640: 0x0e0e, 0x1641: 0x0e1e, 0x1642: 0x0e12, 0x1643: 0x0e16, 0x1644: 0x0e22, 0x1645: 0x0e26,
+ 0x1646: 0x1708, 0x1647: 0x0e0a, 0x1648: 0x0e3e, 0x1649: 0x0e42, 0x164a: 0x0616, 0x164b: 0x0e56,
+ 0x164c: 0x0e52, 0x164d: 0x170d, 0x164e: 0x0e36, 0x164f: 0x0e72, 0x1650: 0x1712, 0x1651: 0x1717,
+ 0x1652: 0x0e76, 0x1653: 0x0e8a, 0x1654: 0x0e86, 0x1655: 0x0e82, 0x1656: 0x061a, 0x1657: 0x0e8e,
+ 0x1658: 0x0e9e, 0x1659: 0x0e9a, 0x165a: 0x0ea6, 0x165b: 0x1654, 0x165c: 0x0eb6, 0x165d: 0x171c,
+ 0x165e: 0x0ec2, 0x165f: 0x1726, 0x1660: 0x0ed6, 0x1661: 0x0ee2, 0x1662: 0x0ef6, 0x1663: 0x172b,
+ 0x1664: 0x0f0a, 0x1665: 0x0f0e, 0x1666: 0x1730, 0x1667: 0x1735, 0x1668: 0x0f2a, 0x1669: 0x0f3a,
+ 0x166a: 0x061e, 0x166b: 0x0f3e, 0x166c: 0x0622, 0x166d: 0x0622, 0x166e: 0x0f56, 0x166f: 0x0f5a,
+ 0x1670: 0x0f62, 0x1671: 0x0f66, 0x1672: 0x0f72, 0x1673: 0x0626, 0x1674: 0x0f8a, 0x1675: 0x173a,
+ 0x1676: 0x0fa6, 0x1677: 0x173f, 0x1678: 0x0fb2, 0x1679: 0x16a4, 0x167a: 0x0fc2, 0x167b: 0x1744,
+ 0x167c: 0x1749, 0x167d: 0x174e, 0x167e: 0x062a, 0x167f: 0x062e,
+ // Block 0x5a, offset 0x1680
+ 0x1680: 0x0ffa, 0x1681: 0x1758, 0x1682: 0x1753, 0x1683: 0x175d, 0x1684: 0x1762, 0x1685: 0x1002,
+ 0x1686: 0x1006, 0x1687: 0x1006, 0x1688: 0x100e, 0x1689: 0x0636, 0x168a: 0x1012, 0x168b: 0x063a,
+ 0x168c: 0x063e, 0x168d: 0x176c, 0x168e: 0x1026, 0x168f: 0x102e, 0x1690: 0x103a, 0x1691: 0x0642,
+ 0x1692: 0x1771, 0x1693: 0x105e, 0x1694: 0x1776, 0x1695: 0x177b, 0x1696: 0x107e, 0x1697: 0x1096,
+ 0x1698: 0x0646, 0x1699: 0x109e, 0x169a: 0x10a2, 0x169b: 0x10a6, 0x169c: 0x1780, 0x169d: 0x1785,
+ 0x169e: 0x1785, 0x169f: 0x10be, 0x16a0: 0x064a, 0x16a1: 0x178a, 0x16a2: 0x10d2, 0x16a3: 0x10d6,
+ 0x16a4: 0x064e, 0x16a5: 0x178f, 0x16a6: 0x10f2, 0x16a7: 0x0652, 0x16a8: 0x1102, 0x16a9: 0x10fa,
+ 0x16aa: 0x110a, 0x16ab: 0x1799, 0x16ac: 0x1122, 0x16ad: 0x0656, 0x16ae: 0x112e, 0x16af: 0x1136,
+ 0x16b0: 0x1146, 0x16b1: 0x065a, 0x16b2: 0x17a3, 0x16b3: 0x17a8, 0x16b4: 0x065e, 0x16b5: 0x17ad,
+ 0x16b6: 0x115e, 0x16b7: 0x17b2, 0x16b8: 0x116a, 0x16b9: 0x1176, 0x16ba: 0x117e, 0x16bb: 0x17b7,
+ 0x16bc: 0x17bc, 0x16bd: 0x1192, 0x16be: 0x17c1, 0x16bf: 0x119a,
+ // Block 0x5b, offset 0x16c0
+ 0x16c0: 0x16d1, 0x16c1: 0x0662, 0x16c2: 0x11b2, 0x16c3: 0x11b6, 0x16c4: 0x066a, 0x16c5: 0x11ba,
+ 0x16c6: 0x0a36, 0x16c7: 0x17c6, 0x16c8: 0x17cb, 0x16c9: 0x16d6, 0x16ca: 0x16db, 0x16cb: 0x11da,
+ 0x16cc: 0x11de, 0x16cd: 0x13f6, 0x16ce: 0x066e, 0x16cf: 0x120a, 0x16d0: 0x1206, 0x16d1: 0x120e,
+ 0x16d2: 0x0842, 0x16d3: 0x1212, 0x16d4: 0x1216, 0x16d5: 0x121a, 0x16d6: 0x1222, 0x16d7: 0x17d0,
+ 0x16d8: 0x121e, 0x16d9: 0x1226, 0x16da: 0x123a, 0x16db: 0x123e, 0x16dc: 0x122a, 0x16dd: 0x1242,
+ 0x16de: 0x1256, 0x16df: 0x126a, 0x16e0: 0x1236, 0x16e1: 0x124a, 0x16e2: 0x124e, 0x16e3: 0x1252,
+ 0x16e4: 0x17d5, 0x16e5: 0x17df, 0x16e6: 0x17da, 0x16e7: 0x0672, 0x16e8: 0x1272, 0x16e9: 0x1276,
+ 0x16ea: 0x127e, 0x16eb: 0x17f3, 0x16ec: 0x1282, 0x16ed: 0x17e4, 0x16ee: 0x0676, 0x16ef: 0x067a,
+ 0x16f0: 0x17e9, 0x16f1: 0x17ee, 0x16f2: 0x067e, 0x16f3: 0x12a2, 0x16f4: 0x12a6, 0x16f5: 0x12aa,
+ 0x16f6: 0x12ae, 0x16f7: 0x12ba, 0x16f8: 0x12b6, 0x16f9: 0x12c2, 0x16fa: 0x12be, 0x16fb: 0x12ce,
+ 0x16fc: 0x12c6, 0x16fd: 0x12ca, 0x16fe: 0x12d2, 0x16ff: 0x0682,
+ // Block 0x5c, offset 0x1700
+ 0x1700: 0x12da, 0x1701: 0x12de, 0x1702: 0x0686, 0x1703: 0x12ee, 0x1704: 0x12f2, 0x1705: 0x17f8,
+ 0x1706: 0x12fe, 0x1707: 0x1302, 0x1708: 0x068a, 0x1709: 0x130e, 0x170a: 0x05be, 0x170b: 0x17fd,
+ 0x170c: 0x1802, 0x170d: 0x068e, 0x170e: 0x0692, 0x170f: 0x133a, 0x1710: 0x1352, 0x1711: 0x136e,
+ 0x1712: 0x137e, 0x1713: 0x1807, 0x1714: 0x1392, 0x1715: 0x1396, 0x1716: 0x13ae, 0x1717: 0x13ba,
+ 0x1718: 0x1811, 0x1719: 0x1663, 0x171a: 0x13c6, 0x171b: 0x13c2, 0x171c: 0x13ce, 0x171d: 0x1668,
+ 0x171e: 0x13da, 0x171f: 0x13e6, 0x1720: 0x1816, 0x1721: 0x181b, 0x1722: 0x1426, 0x1723: 0x1432,
+ 0x1724: 0x143a, 0x1725: 0x1820, 0x1726: 0x143e, 0x1727: 0x146a, 0x1728: 0x1476, 0x1729: 0x147a,
+ 0x172a: 0x1472, 0x172b: 0x1486, 0x172c: 0x148a, 0x172d: 0x1825, 0x172e: 0x1496, 0x172f: 0x0696,
+ 0x1730: 0x149e, 0x1731: 0x182a, 0x1732: 0x069a, 0x1733: 0x14d6, 0x1734: 0x0ac6, 0x1735: 0x14ee,
+ 0x1736: 0x182f, 0x1737: 0x1839, 0x1738: 0x069e, 0x1739: 0x06a2, 0x173a: 0x1516, 0x173b: 0x183e,
+ 0x173c: 0x06a6, 0x173d: 0x1843, 0x173e: 0x152e, 0x173f: 0x152e,
+ // Block 0x5d, offset 0x1740
+ 0x1740: 0x1536, 0x1741: 0x1848, 0x1742: 0x154e, 0x1743: 0x06aa, 0x1744: 0x155e, 0x1745: 0x156a,
+ 0x1746: 0x1572, 0x1747: 0x157a, 0x1748: 0x06ae, 0x1749: 0x184d, 0x174a: 0x158e, 0x174b: 0x15aa,
+ 0x174c: 0x15b6, 0x174d: 0x06b2, 0x174e: 0x06b6, 0x174f: 0x15ba, 0x1750: 0x1852, 0x1751: 0x06ba,
+ 0x1752: 0x1857, 0x1753: 0x185c, 0x1754: 0x1861, 0x1755: 0x15de, 0x1756: 0x06be, 0x1757: 0x15f2,
+ 0x1758: 0x15fa, 0x1759: 0x15fe, 0x175a: 0x1606, 0x175b: 0x160e, 0x175c: 0x1616, 0x175d: 0x186b,
+}
+
+// nfkcIndex: 22 blocks, 1408 entries, 2816 bytes
+// Block 0 is the zero block.
+var nfkcIndex = [1408]uint16{
+ // Block 0x0, offset 0x0
+ // Block 0x1, offset 0x40
+ // Block 0x2, offset 0x80
+ // Block 0x3, offset 0xc0
+ 0xc2: 0x5c, 0xc3: 0x01, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x5d, 0xc7: 0x04,
+ 0xc8: 0x05, 0xca: 0x5e, 0xcb: 0x5f, 0xcc: 0x06, 0xcd: 0x07, 0xce: 0x08, 0xcf: 0x09,
+ 0xd0: 0x0a, 0xd1: 0x60, 0xd2: 0x61, 0xd3: 0x0b, 0xd6: 0x0c, 0xd7: 0x62,
+ 0xd8: 0x63, 0xd9: 0x0d, 0xdb: 0x64, 0xdc: 0x65, 0xdd: 0x66, 0xdf: 0x67,
+ 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05,
+ 0xea: 0x06, 0xeb: 0x07, 0xec: 0x08, 0xed: 0x09, 0xef: 0x0a,
+ 0xf0: 0x13,
+ // Block 0x4, offset 0x100
+ 0x120: 0x68, 0x121: 0x69, 0x123: 0x0e, 0x124: 0x6a, 0x125: 0x6b, 0x126: 0x6c, 0x127: 0x6d,
+ 0x128: 0x6e, 0x129: 0x6f, 0x12a: 0x70, 0x12b: 0x71, 0x12c: 0x6c, 0x12d: 0x72, 0x12e: 0x73, 0x12f: 0x74,
+ 0x131: 0x75, 0x132: 0x76, 0x133: 0x77, 0x134: 0x78, 0x135: 0x79, 0x137: 0x7a,
+ 0x138: 0x7b, 0x139: 0x7c, 0x13a: 0x7d, 0x13b: 0x7e, 0x13c: 0x7f, 0x13d: 0x80, 0x13e: 0x81, 0x13f: 0x82,
+ // Block 0x5, offset 0x140
+ 0x140: 0x83, 0x142: 0x84, 0x143: 0x85, 0x144: 0x86, 0x145: 0x87, 0x146: 0x88, 0x147: 0x89,
+ 0x14d: 0x8a,
+ 0x15c: 0x8b, 0x15f: 0x8c,
+ 0x162: 0x8d, 0x164: 0x8e,
+ 0x168: 0x8f, 0x169: 0x90, 0x16a: 0x91, 0x16b: 0x92, 0x16c: 0x0f, 0x16d: 0x93, 0x16e: 0x94, 0x16f: 0x95,
+ 0x170: 0x96, 0x173: 0x97, 0x174: 0x98, 0x175: 0x10, 0x176: 0x11, 0x177: 0x12,
+ 0x178: 0x13, 0x179: 0x14, 0x17a: 0x15, 0x17b: 0x16, 0x17c: 0x17, 0x17d: 0x18, 0x17e: 0x19, 0x17f: 0x1a,
+ // Block 0x6, offset 0x180
+ 0x180: 0x99, 0x181: 0x9a, 0x182: 0x9b, 0x183: 0x9c, 0x184: 0x1b, 0x185: 0x1c, 0x186: 0x9d, 0x187: 0x9e,
+ 0x188: 0x9f, 0x189: 0x1d, 0x18a: 0x1e, 0x18b: 0xa0, 0x18c: 0xa1,
+ 0x191: 0x1f, 0x192: 0x20, 0x193: 0xa2,
+ 0x1a8: 0xa3, 0x1a9: 0xa4, 0x1ab: 0xa5,
+ 0x1b1: 0xa6, 0x1b3: 0xa7, 0x1b5: 0xa8, 0x1b7: 0xa9,
+ 0x1ba: 0xaa, 0x1bb: 0xab, 0x1bc: 0x21, 0x1bd: 0x22, 0x1be: 0x23, 0x1bf: 0xac,
+ // Block 0x7, offset 0x1c0
+ 0x1c0: 0xad, 0x1c1: 0x24, 0x1c2: 0x25, 0x1c3: 0x26, 0x1c4: 0xae, 0x1c5: 0x27, 0x1c6: 0x28,
+ 0x1c8: 0x29, 0x1c9: 0x2a, 0x1ca: 0x2b, 0x1cb: 0x2c, 0x1cc: 0x2d, 0x1cd: 0x2e, 0x1ce: 0x2f, 0x1cf: 0x30,
+ // Block 0x8, offset 0x200
+ 0x219: 0xaf, 0x21a: 0xb0, 0x21b: 0xb1, 0x21d: 0xb2, 0x21f: 0xb3,
+ 0x220: 0xb4, 0x223: 0xb5, 0x224: 0xb6, 0x225: 0xb7, 0x226: 0xb8, 0x227: 0xb9,
+ 0x22a: 0xba, 0x22b: 0xbb, 0x22d: 0xbc, 0x22f: 0xbd,
+ 0x230: 0xbe, 0x231: 0xbf, 0x232: 0xc0, 0x233: 0xc1, 0x234: 0xc2, 0x235: 0xc3, 0x236: 0xc4, 0x237: 0xbe,
+ 0x238: 0xbf, 0x239: 0xc0, 0x23a: 0xc1, 0x23b: 0xc2, 0x23c: 0xc3, 0x23d: 0xc4, 0x23e: 0xbe, 0x23f: 0xbf,
+ // Block 0x9, offset 0x240
+ 0x240: 0xc0, 0x241: 0xc1, 0x242: 0xc2, 0x243: 0xc3, 0x244: 0xc4, 0x245: 0xbe, 0x246: 0xbf, 0x247: 0xc0,
+ 0x248: 0xc1, 0x249: 0xc2, 0x24a: 0xc3, 0x24b: 0xc4, 0x24c: 0xbe, 0x24d: 0xbf, 0x24e: 0xc0, 0x24f: 0xc1,
+ 0x250: 0xc2, 0x251: 0xc3, 0x252: 0xc4, 0x253: 0xbe, 0x254: 0xbf, 0x255: 0xc0, 0x256: 0xc1, 0x257: 0xc2,
+ 0x258: 0xc3, 0x259: 0xc4, 0x25a: 0xbe, 0x25b: 0xbf, 0x25c: 0xc0, 0x25d: 0xc1, 0x25e: 0xc2, 0x25f: 0xc3,
+ 0x260: 0xc4, 0x261: 0xbe, 0x262: 0xbf, 0x263: 0xc0, 0x264: 0xc1, 0x265: 0xc2, 0x266: 0xc3, 0x267: 0xc4,
+ 0x268: 0xbe, 0x269: 0xbf, 0x26a: 0xc0, 0x26b: 0xc1, 0x26c: 0xc2, 0x26d: 0xc3, 0x26e: 0xc4, 0x26f: 0xbe,
+ 0x270: 0xbf, 0x271: 0xc0, 0x272: 0xc1, 0x273: 0xc2, 0x274: 0xc3, 0x275: 0xc4, 0x276: 0xbe, 0x277: 0xbf,
+ 0x278: 0xc0, 0x279: 0xc1, 0x27a: 0xc2, 0x27b: 0xc3, 0x27c: 0xc4, 0x27d: 0xbe, 0x27e: 0xbf, 0x27f: 0xc0,
+ // Block 0xa, offset 0x280
+ 0x280: 0xc1, 0x281: 0xc2, 0x282: 0xc3, 0x283: 0xc4, 0x284: 0xbe, 0x285: 0xbf, 0x286: 0xc0, 0x287: 0xc1,
+ 0x288: 0xc2, 0x289: 0xc3, 0x28a: 0xc4, 0x28b: 0xbe, 0x28c: 0xbf, 0x28d: 0xc0, 0x28e: 0xc1, 0x28f: 0xc2,
+ 0x290: 0xc3, 0x291: 0xc4, 0x292: 0xbe, 0x293: 0xbf, 0x294: 0xc0, 0x295: 0xc1, 0x296: 0xc2, 0x297: 0xc3,
+ 0x298: 0xc4, 0x299: 0xbe, 0x29a: 0xbf, 0x29b: 0xc0, 0x29c: 0xc1, 0x29d: 0xc2, 0x29e: 0xc3, 0x29f: 0xc4,
+ 0x2a0: 0xbe, 0x2a1: 0xbf, 0x2a2: 0xc0, 0x2a3: 0xc1, 0x2a4: 0xc2, 0x2a5: 0xc3, 0x2a6: 0xc4, 0x2a7: 0xbe,
+ 0x2a8: 0xbf, 0x2a9: 0xc0, 0x2aa: 0xc1, 0x2ab: 0xc2, 0x2ac: 0xc3, 0x2ad: 0xc4, 0x2ae: 0xbe, 0x2af: 0xbf,
+ 0x2b0: 0xc0, 0x2b1: 0xc1, 0x2b2: 0xc2, 0x2b3: 0xc3, 0x2b4: 0xc4, 0x2b5: 0xbe, 0x2b6: 0xbf, 0x2b7: 0xc0,
+ 0x2b8: 0xc1, 0x2b9: 0xc2, 0x2ba: 0xc3, 0x2bb: 0xc4, 0x2bc: 0xbe, 0x2bd: 0xbf, 0x2be: 0xc0, 0x2bf: 0xc1,
+ // Block 0xb, offset 0x2c0
+ 0x2c0: 0xc2, 0x2c1: 0xc3, 0x2c2: 0xc4, 0x2c3: 0xbe, 0x2c4: 0xbf, 0x2c5: 0xc0, 0x2c6: 0xc1, 0x2c7: 0xc2,
+ 0x2c8: 0xc3, 0x2c9: 0xc4, 0x2ca: 0xbe, 0x2cb: 0xbf, 0x2cc: 0xc0, 0x2cd: 0xc1, 0x2ce: 0xc2, 0x2cf: 0xc3,
+ 0x2d0: 0xc4, 0x2d1: 0xbe, 0x2d2: 0xbf, 0x2d3: 0xc0, 0x2d4: 0xc1, 0x2d5: 0xc2, 0x2d6: 0xc3, 0x2d7: 0xc4,
+ 0x2d8: 0xbe, 0x2d9: 0xbf, 0x2da: 0xc0, 0x2db: 0xc1, 0x2dc: 0xc2, 0x2dd: 0xc3, 0x2de: 0xc5,
+ // Block 0xc, offset 0x300
+ 0x324: 0x31, 0x325: 0x32, 0x326: 0x33, 0x327: 0x34,
+ 0x328: 0x35, 0x329: 0x36, 0x32a: 0x37, 0x32b: 0x38, 0x32c: 0x39, 0x32d: 0x3a, 0x32e: 0x3b, 0x32f: 0x3c,
+ 0x330: 0x3d, 0x331: 0x3e, 0x332: 0x3f, 0x333: 0x40, 0x334: 0x41, 0x335: 0x42, 0x336: 0x43, 0x337: 0x44,
+ 0x338: 0x45, 0x339: 0x46, 0x33a: 0x47, 0x33b: 0x48, 0x33c: 0xc6, 0x33d: 0x49, 0x33e: 0x4a, 0x33f: 0x4b,
+ // Block 0xd, offset 0x340
+ 0x347: 0xc7,
+ 0x34b: 0xc8, 0x34d: 0xc9,
+ 0x368: 0xca, 0x36b: 0xcb,
+ 0x374: 0xcc,
+ 0x37a: 0xcd, 0x37d: 0xce,
+ // Block 0xe, offset 0x380
+ 0x381: 0xcf, 0x382: 0xd0, 0x384: 0xd1, 0x385: 0xb8, 0x387: 0xd2,
+ 0x388: 0xd3, 0x38b: 0xd4, 0x38c: 0xd5, 0x38d: 0xd6,
+ 0x391: 0xd7, 0x392: 0xd8, 0x393: 0xd9, 0x396: 0xda, 0x397: 0xdb,
+ 0x398: 0xdc, 0x39a: 0xdd, 0x39c: 0xde,
+ 0x3a0: 0xdf, 0x3a4: 0xe0, 0x3a5: 0xe1, 0x3a7: 0xe2,
+ 0x3a8: 0xe3, 0x3a9: 0xe4, 0x3aa: 0xe5,
+ 0x3b0: 0xdc, 0x3b5: 0xe6, 0x3b6: 0xe7,
+ // Block 0xf, offset 0x3c0
+ 0x3eb: 0xe8, 0x3ec: 0xe9,
+ 0x3ff: 0xea,
+ // Block 0x10, offset 0x400
+ 0x432: 0xeb,
+ // Block 0x11, offset 0x440
+ 0x445: 0xec, 0x446: 0xed, 0x447: 0xee,
+ 0x449: 0xef,
+ 0x450: 0xf0, 0x451: 0xf1, 0x452: 0xf2, 0x453: 0xf3, 0x454: 0xf4, 0x455: 0xf5, 0x456: 0xf6, 0x457: 0xf7,
+ 0x458: 0xf8, 0x459: 0xf9, 0x45a: 0x4c, 0x45b: 0xfa, 0x45c: 0xfb, 0x45d: 0xfc, 0x45e: 0xfd, 0x45f: 0x4d,
+ // Block 0x12, offset 0x480
+ 0x480: 0xfe, 0x484: 0xe9,
+ 0x48b: 0xff,
+ 0x4a3: 0x100, 0x4a5: 0x101,
+ 0x4b8: 0x4e, 0x4b9: 0x4f, 0x4ba: 0x50,
+ // Block 0x13, offset 0x4c0
+ 0x4c4: 0x51, 0x4c5: 0x102, 0x4c6: 0x103,
+ 0x4c8: 0x52, 0x4c9: 0x104,
+ 0x4ef: 0x105,
+ // Block 0x14, offset 0x500
+ 0x520: 0x53, 0x521: 0x54, 0x522: 0x55, 0x523: 0x56, 0x524: 0x57, 0x525: 0x58, 0x526: 0x59, 0x527: 0x5a,
+ 0x528: 0x5b,
+ // Block 0x15, offset 0x540
+ 0x550: 0x0b, 0x551: 0x0c, 0x556: 0x0d,
+ 0x55b: 0x0e, 0x55d: 0x0f, 0x55e: 0x10, 0x55f: 0x11,
+ 0x56f: 0x12,
+}
+
+// nfkcSparseOffset: 170 entries, 340 bytes
+var nfkcSparseOffset = []uint16{0x0, 0xe, 0x12, 0x1b, 0x25, 0x35, 0x37, 0x3c, 0x47, 0x56, 0x63, 0x6b, 0x70, 0x75, 0x77, 0x7f, 0x86, 0x89, 0x91, 0x95, 0x99, 0x9b, 0x9d, 0xa6, 0xaa, 0xb1, 0xb6, 0xb9, 0xc3, 0xc6, 0xcd, 0xd5, 0xd9, 0xdb, 0xdf, 0xe3, 0xe9, 0xfa, 0x106, 0x108, 0x10e, 0x110, 0x112, 0x114, 0x116, 0x118, 0x11a, 0x11c, 0x11f, 0x122, 0x124, 0x127, 0x12a, 0x12e, 0x134, 0x136, 0x13f, 0x141, 0x144, 0x146, 0x151, 0x15c, 0x16a, 0x178, 0x188, 0x196, 0x19d, 0x1a3, 0x1b2, 0x1b6, 0x1b8, 0x1bc, 0x1be, 0x1c1, 0x1c3, 0x1c6, 0x1c8, 0x1cb, 0x1cd, 0x1cf, 0x1d1, 0x1dd, 0x1e7, 0x1f1, 0x1f4, 0x1f8, 0x1fa, 0x1fc, 0x1fe, 0x201, 0x204, 0x206, 0x208, 0x20a, 0x20c, 0x212, 0x215, 0x21a, 0x21c, 0x223, 0x229, 0x22f, 0x237, 0x23d, 0x243, 0x249, 0x24d, 0x24f, 0x251, 0x253, 0x255, 0x25b, 0x25e, 0x260, 0x262, 0x268, 0x26b, 0x273, 0x27a, 0x27d, 0x280, 0x282, 0x285, 0x28d, 0x291, 0x298, 0x29b, 0x2a1, 0x2a3, 0x2a5, 0x2a8, 0x2aa, 0x2ad, 0x2b2, 0x2b4, 0x2b6, 0x2b8, 0x2ba, 0x2bc, 0x2bf, 0x2c1, 0x2c3, 0x2c5, 0x2c7, 0x2c9, 0x2d6, 0x2e0, 0x2e2, 0x2e4, 0x2e8, 0x2ed, 0x2f9, 0x2fe, 0x307, 0x30d, 0x312, 0x316, 0x31b, 0x31f, 0x32f, 0x33d, 0x34b, 0x359, 0x35f, 0x361, 0x363, 0x366, 0x371, 0x373, 0x37d}
+
+// nfkcSparseValues: 895 entries, 3580 bytes
+var nfkcSparseValues = [895]valueRange{
+ // Block 0x0, offset 0x0
+ {value: 0x0002, lo: 0x0d},
+ {value: 0x0001, lo: 0xa0, hi: 0xa0},
+ {value: 0x428f, lo: 0xa8, hi: 0xa8},
+ {value: 0x0083, lo: 0xaa, hi: 0xaa},
+ {value: 0x427b, lo: 0xaf, hi: 0xaf},
+ {value: 0x0025, lo: 0xb2, hi: 0xb3},
+ {value: 0x4271, lo: 0xb4, hi: 0xb4},
+ {value: 0x01df, lo: 0xb5, hi: 0xb5},
+ {value: 0x42a8, lo: 0xb8, hi: 0xb8},
+ {value: 0x0023, lo: 0xb9, hi: 0xb9},
+ {value: 0x009f, lo: 0xba, hi: 0xba},
+ {value: 0x2222, lo: 0xbc, hi: 0xbc},
+ {value: 0x2216, lo: 0xbd, hi: 0xbd},
+ {value: 0x22b8, lo: 0xbe, hi: 0xbe},
+ // Block 0x1, offset 0xe
+ {value: 0x0091, lo: 0x03},
+ {value: 0x46f9, lo: 0xa0, hi: 0xa1},
+ {value: 0x472b, lo: 0xaf, hi: 0xb0},
+ {value: 0xa000, lo: 0xb7, hi: 0xb7},
+ // Block 0x2, offset 0x12
+ {value: 0x0003, lo: 0x08},
+ {value: 0xa000, lo: 0x92, hi: 0x92},
+ {value: 0x0091, lo: 0xb0, hi: 0xb0},
+ {value: 0x0119, lo: 0xb1, hi: 0xb1},
+ {value: 0x0095, lo: 0xb2, hi: 0xb2},
+ {value: 0x00a5, lo: 0xb3, hi: 0xb3},
+ {value: 0x0143, lo: 0xb4, hi: 0xb6},
+ {value: 0x00af, lo: 0xb7, hi: 0xb7},
+ {value: 0x00b3, lo: 0xb8, hi: 0xb8},
+ // Block 0x3, offset 0x1b
+ {value: 0x000a, lo: 0x09},
+ {value: 0x4285, lo: 0x98, hi: 0x98},
+ {value: 0x428a, lo: 0x99, hi: 0x9a},
+ {value: 0x42ad, lo: 0x9b, hi: 0x9b},
+ {value: 0x4276, lo: 0x9c, hi: 0x9c},
+ {value: 0x4299, lo: 0x9d, hi: 0x9d},
+ {value: 0x0113, lo: 0xa0, hi: 0xa0},
+ {value: 0x0099, lo: 0xa1, hi: 0xa1},
+ {value: 0x00a7, lo: 0xa2, hi: 0xa3},
+ {value: 0x016a, lo: 0xa4, hi: 0xa4},
+ // Block 0x4, offset 0x25
+ {value: 0x0000, lo: 0x0f},
+ {value: 0xa000, lo: 0x83, hi: 0x83},
+ {value: 0xa000, lo: 0x87, hi: 0x87},
+ {value: 0xa000, lo: 0x8b, hi: 0x8b},
+ {value: 0xa000, lo: 0x8d, hi: 0x8d},
+ {value: 0x37bc, lo: 0x90, hi: 0x90},
+ {value: 0x37c8, lo: 0x91, hi: 0x91},
+ {value: 0x37b6, lo: 0x93, hi: 0x93},
+ {value: 0xa000, lo: 0x96, hi: 0x96},
+ {value: 0x382e, lo: 0x97, hi: 0x97},
+ {value: 0x37f8, lo: 0x9c, hi: 0x9c},
+ {value: 0x37e0, lo: 0x9d, hi: 0x9d},
+ {value: 0x380a, lo: 0x9e, hi: 0x9e},
+ {value: 0xa000, lo: 0xb4, hi: 0xb5},
+ {value: 0x3834, lo: 0xb6, hi: 0xb6},
+ {value: 0x383a, lo: 0xb7, hi: 0xb7},
+ // Block 0x5, offset 0x35
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0x83, hi: 0x87},
+ // Block 0x6, offset 0x37
+ {value: 0x0001, lo: 0x04},
+ {value: 0x8114, lo: 0x81, hi: 0x82},
+ {value: 0x8133, lo: 0x84, hi: 0x84},
+ {value: 0x812e, lo: 0x85, hi: 0x85},
+ {value: 0x810e, lo: 0x87, hi: 0x87},
+ // Block 0x7, offset 0x3c
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x8133, lo: 0x90, hi: 0x97},
+ {value: 0x811a, lo: 0x98, hi: 0x98},
+ {value: 0x811b, lo: 0x99, hi: 0x99},
+ {value: 0x811c, lo: 0x9a, hi: 0x9a},
+ {value: 0x3858, lo: 0xa2, hi: 0xa2},
+ {value: 0x385e, lo: 0xa3, hi: 0xa3},
+ {value: 0x386a, lo: 0xa4, hi: 0xa4},
+ {value: 0x3864, lo: 0xa5, hi: 0xa5},
+ {value: 0x3870, lo: 0xa6, hi: 0xa6},
+ {value: 0xa000, lo: 0xa7, hi: 0xa7},
+ // Block 0x8, offset 0x47
+ {value: 0x0000, lo: 0x0e},
+ {value: 0x3882, lo: 0x80, hi: 0x80},
+ {value: 0xa000, lo: 0x81, hi: 0x81},
+ {value: 0x3876, lo: 0x82, hi: 0x82},
+ {value: 0xa000, lo: 0x92, hi: 0x92},
+ {value: 0x387c, lo: 0x93, hi: 0x93},
+ {value: 0xa000, lo: 0x95, hi: 0x95},
+ {value: 0x8133, lo: 0x96, hi: 0x9c},
+ {value: 0x8133, lo: 0x9f, hi: 0xa2},
+ {value: 0x812e, lo: 0xa3, hi: 0xa3},
+ {value: 0x8133, lo: 0xa4, hi: 0xa4},
+ {value: 0x8133, lo: 0xa7, hi: 0xa8},
+ {value: 0x812e, lo: 0xaa, hi: 0xaa},
+ {value: 0x8133, lo: 0xab, hi: 0xac},
+ {value: 0x812e, lo: 0xad, hi: 0xad},
+ // Block 0x9, offset 0x56
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x8120, lo: 0x91, hi: 0x91},
+ {value: 0x8133, lo: 0xb0, hi: 0xb0},
+ {value: 0x812e, lo: 0xb1, hi: 0xb1},
+ {value: 0x8133, lo: 0xb2, hi: 0xb3},
+ {value: 0x812e, lo: 0xb4, hi: 0xb4},
+ {value: 0x8133, lo: 0xb5, hi: 0xb6},
+ {value: 0x812e, lo: 0xb7, hi: 0xb9},
+ {value: 0x8133, lo: 0xba, hi: 0xba},
+ {value: 0x812e, lo: 0xbb, hi: 0xbc},
+ {value: 0x8133, lo: 0xbd, hi: 0xbd},
+ {value: 0x812e, lo: 0xbe, hi: 0xbe},
+ {value: 0x8133, lo: 0xbf, hi: 0xbf},
+ // Block 0xa, offset 0x63
+ {value: 0x0005, lo: 0x07},
+ {value: 0x8133, lo: 0x80, hi: 0x80},
+ {value: 0x8133, lo: 0x81, hi: 0x81},
+ {value: 0x812e, lo: 0x82, hi: 0x83},
+ {value: 0x812e, lo: 0x84, hi: 0x85},
+ {value: 0x812e, lo: 0x86, hi: 0x87},
+ {value: 0x812e, lo: 0x88, hi: 0x89},
+ {value: 0x8133, lo: 0x8a, hi: 0x8a},
+ // Block 0xb, offset 0x6b
+ {value: 0x0000, lo: 0x04},
+ {value: 0x8133, lo: 0xab, hi: 0xb1},
+ {value: 0x812e, lo: 0xb2, hi: 0xb2},
+ {value: 0x8133, lo: 0xb3, hi: 0xb3},
+ {value: 0x812e, lo: 0xbd, hi: 0xbd},
+ // Block 0xc, offset 0x70
+ {value: 0x0000, lo: 0x04},
+ {value: 0x8133, lo: 0x96, hi: 0x99},
+ {value: 0x8133, lo: 0x9b, hi: 0xa3},
+ {value: 0x8133, lo: 0xa5, hi: 0xa7},
+ {value: 0x8133, lo: 0xa9, hi: 0xad},
+ // Block 0xd, offset 0x75
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0x99, hi: 0x9b},
+ // Block 0xe, offset 0x77
+ {value: 0x0000, lo: 0x07},
+ {value: 0xa000, lo: 0xa8, hi: 0xa8},
+ {value: 0x3eef, lo: 0xa9, hi: 0xa9},
+ {value: 0xa000, lo: 0xb0, hi: 0xb0},
+ {value: 0x3ef7, lo: 0xb1, hi: 0xb1},
+ {value: 0xa000, lo: 0xb3, hi: 0xb3},
+ {value: 0x3eff, lo: 0xb4, hi: 0xb4},
+ {value: 0x9903, lo: 0xbc, hi: 0xbc},
+ // Block 0xf, offset 0x7f
+ {value: 0x0008, lo: 0x06},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x8133, lo: 0x91, hi: 0x91},
+ {value: 0x812e, lo: 0x92, hi: 0x92},
+ {value: 0x8133, lo: 0x93, hi: 0x93},
+ {value: 0x8133, lo: 0x94, hi: 0x94},
+ {value: 0x4533, lo: 0x98, hi: 0x9f},
+ // Block 0x10, offset 0x86
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8103, lo: 0xbc, hi: 0xbc},
+ {value: 0x9900, lo: 0xbe, hi: 0xbe},
+ // Block 0x11, offset 0x89
+ {value: 0x0008, lo: 0x07},
+ {value: 0xa000, lo: 0x87, hi: 0x87},
+ {value: 0x2cab, lo: 0x8b, hi: 0x8c},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x9900, lo: 0x97, hi: 0x97},
+ {value: 0x4573, lo: 0x9c, hi: 0x9d},
+ {value: 0x4583, lo: 0x9f, hi: 0x9f},
+ {value: 0x8133, lo: 0xbe, hi: 0xbe},
+ // Block 0x12, offset 0x91
+ {value: 0x0000, lo: 0x03},
+ {value: 0x45ab, lo: 0xb3, hi: 0xb3},
+ {value: 0x45b3, lo: 0xb6, hi: 0xb6},
+ {value: 0x8103, lo: 0xbc, hi: 0xbc},
+ // Block 0x13, offset 0x95
+ {value: 0x0008, lo: 0x03},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x458b, lo: 0x99, hi: 0x9b},
+ {value: 0x45a3, lo: 0x9e, hi: 0x9e},
+ // Block 0x14, offset 0x99
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8103, lo: 0xbc, hi: 0xbc},
+ // Block 0x15, offset 0x9b
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ // Block 0x16, offset 0x9d
+ {value: 0x0000, lo: 0x08},
+ {value: 0xa000, lo: 0x87, hi: 0x87},
+ {value: 0x2cc3, lo: 0x88, hi: 0x88},
+ {value: 0x2cbb, lo: 0x8b, hi: 0x8b},
+ {value: 0x2ccb, lo: 0x8c, hi: 0x8c},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x9900, lo: 0x96, hi: 0x97},
+ {value: 0x45bb, lo: 0x9c, hi: 0x9c},
+ {value: 0x45c3, lo: 0x9d, hi: 0x9d},
+ // Block 0x17, offset 0xa6
+ {value: 0x0000, lo: 0x03},
+ {value: 0xa000, lo: 0x92, hi: 0x92},
+ {value: 0x2cd3, lo: 0x94, hi: 0x94},
+ {value: 0x9900, lo: 0xbe, hi: 0xbe},
+ // Block 0x18, offset 0xaa
+ {value: 0x0000, lo: 0x06},
+ {value: 0xa000, lo: 0x86, hi: 0x87},
+ {value: 0x2cdb, lo: 0x8a, hi: 0x8a},
+ {value: 0x2ceb, lo: 0x8b, hi: 0x8b},
+ {value: 0x2ce3, lo: 0x8c, hi: 0x8c},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x9900, lo: 0x97, hi: 0x97},
+ // Block 0x19, offset 0xb1
+ {value: 0x1801, lo: 0x04},
+ {value: 0xa000, lo: 0x86, hi: 0x86},
+ {value: 0x3f07, lo: 0x88, hi: 0x88},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x8121, lo: 0x95, hi: 0x96},
+ // Block 0x1a, offset 0xb6
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8103, lo: 0xbc, hi: 0xbc},
+ {value: 0xa000, lo: 0xbf, hi: 0xbf},
+ // Block 0x1b, offset 0xb9
+ {value: 0x0000, lo: 0x09},
+ {value: 0x2cf3, lo: 0x80, hi: 0x80},
+ {value: 0x9900, lo: 0x82, hi: 0x82},
+ {value: 0xa000, lo: 0x86, hi: 0x86},
+ {value: 0x2cfb, lo: 0x87, hi: 0x87},
+ {value: 0x2d03, lo: 0x88, hi: 0x88},
+ {value: 0x2f67, lo: 0x8a, hi: 0x8a},
+ {value: 0x2def, lo: 0x8b, hi: 0x8b},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x9900, lo: 0x95, hi: 0x96},
+ // Block 0x1c, offset 0xc3
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0xbb, hi: 0xbc},
+ {value: 0x9900, lo: 0xbe, hi: 0xbe},
+ // Block 0x1d, offset 0xc6
+ {value: 0x0000, lo: 0x06},
+ {value: 0xa000, lo: 0x86, hi: 0x87},
+ {value: 0x2d0b, lo: 0x8a, hi: 0x8a},
+ {value: 0x2d1b, lo: 0x8b, hi: 0x8b},
+ {value: 0x2d13, lo: 0x8c, hi: 0x8c},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x9900, lo: 0x97, hi: 0x97},
+ // Block 0x1e, offset 0xcd
+ {value: 0x6bdd, lo: 0x07},
+ {value: 0x9905, lo: 0x8a, hi: 0x8a},
+ {value: 0x9900, lo: 0x8f, hi: 0x8f},
+ {value: 0xa000, lo: 0x99, hi: 0x99},
+ {value: 0x3f0f, lo: 0x9a, hi: 0x9a},
+ {value: 0x2f6f, lo: 0x9c, hi: 0x9c},
+ {value: 0x2dfa, lo: 0x9d, hi: 0x9d},
+ {value: 0x2d23, lo: 0x9e, hi: 0x9f},
+ // Block 0x1f, offset 0xd5
+ {value: 0x0000, lo: 0x03},
+ {value: 0x2627, lo: 0xb3, hi: 0xb3},
+ {value: 0x8123, lo: 0xb8, hi: 0xb9},
+ {value: 0x8105, lo: 0xba, hi: 0xba},
+ // Block 0x20, offset 0xd9
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8124, lo: 0x88, hi: 0x8b},
+ // Block 0x21, offset 0xdb
+ {value: 0x0000, lo: 0x03},
+ {value: 0x263c, lo: 0xb3, hi: 0xb3},
+ {value: 0x8125, lo: 0xb8, hi: 0xb9},
+ {value: 0x8105, lo: 0xba, hi: 0xba},
+ // Block 0x22, offset 0xdf
+ {value: 0x0000, lo: 0x03},
+ {value: 0x8126, lo: 0x88, hi: 0x8b},
+ {value: 0x262e, lo: 0x9c, hi: 0x9c},
+ {value: 0x2635, lo: 0x9d, hi: 0x9d},
+ // Block 0x23, offset 0xe3
+ {value: 0x0000, lo: 0x05},
+ {value: 0x030e, lo: 0x8c, hi: 0x8c},
+ {value: 0x812e, lo: 0x98, hi: 0x99},
+ {value: 0x812e, lo: 0xb5, hi: 0xb5},
+ {value: 0x812e, lo: 0xb7, hi: 0xb7},
+ {value: 0x812c, lo: 0xb9, hi: 0xb9},
+ // Block 0x24, offset 0xe9
+ {value: 0x0000, lo: 0x10},
+ {value: 0x264a, lo: 0x83, hi: 0x83},
+ {value: 0x2651, lo: 0x8d, hi: 0x8d},
+ {value: 0x2658, lo: 0x92, hi: 0x92},
+ {value: 0x265f, lo: 0x97, hi: 0x97},
+ {value: 0x2666, lo: 0x9c, hi: 0x9c},
+ {value: 0x2643, lo: 0xa9, hi: 0xa9},
+ {value: 0x8127, lo: 0xb1, hi: 0xb1},
+ {value: 0x8128, lo: 0xb2, hi: 0xb2},
+ {value: 0x4a9b, lo: 0xb3, hi: 0xb3},
+ {value: 0x8129, lo: 0xb4, hi: 0xb4},
+ {value: 0x4aa4, lo: 0xb5, hi: 0xb5},
+ {value: 0x45cb, lo: 0xb6, hi: 0xb6},
+ {value: 0x460b, lo: 0xb7, hi: 0xb7},
+ {value: 0x45d3, lo: 0xb8, hi: 0xb8},
+ {value: 0x4616, lo: 0xb9, hi: 0xb9},
+ {value: 0x8128, lo: 0xba, hi: 0xbd},
+ // Block 0x25, offset 0xfa
+ {value: 0x0000, lo: 0x0b},
+ {value: 0x8128, lo: 0x80, hi: 0x80},
+ {value: 0x4aad, lo: 0x81, hi: 0x81},
+ {value: 0x8133, lo: 0x82, hi: 0x83},
+ {value: 0x8105, lo: 0x84, hi: 0x84},
+ {value: 0x8133, lo: 0x86, hi: 0x87},
+ {value: 0x2674, lo: 0x93, hi: 0x93},
+ {value: 0x267b, lo: 0x9d, hi: 0x9d},
+ {value: 0x2682, lo: 0xa2, hi: 0xa2},
+ {value: 0x2689, lo: 0xa7, hi: 0xa7},
+ {value: 0x2690, lo: 0xac, hi: 0xac},
+ {value: 0x266d, lo: 0xb9, hi: 0xb9},
+ // Block 0x26, offset 0x106
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0x86, hi: 0x86},
+ // Block 0x27, offset 0x108
+ {value: 0x0000, lo: 0x05},
+ {value: 0xa000, lo: 0xa5, hi: 0xa5},
+ {value: 0x2d2b, lo: 0xa6, hi: 0xa6},
+ {value: 0x9900, lo: 0xae, hi: 0xae},
+ {value: 0x8103, lo: 0xb7, hi: 0xb7},
+ {value: 0x8105, lo: 0xb9, hi: 0xba},
+ // Block 0x28, offset 0x10e
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0x8d, hi: 0x8d},
+ // Block 0x29, offset 0x110
+ {value: 0x0000, lo: 0x01},
+ {value: 0x0312, lo: 0xbc, hi: 0xbc},
+ // Block 0x2a, offset 0x112
+ {value: 0x0000, lo: 0x01},
+ {value: 0xa000, lo: 0x80, hi: 0x92},
+ // Block 0x2b, offset 0x114
+ {value: 0x0000, lo: 0x01},
+ {value: 0xb900, lo: 0xa1, hi: 0xb5},
+ // Block 0x2c, offset 0x116
+ {value: 0x0000, lo: 0x01},
+ {value: 0x9900, lo: 0xa8, hi: 0xbf},
+ // Block 0x2d, offset 0x118
+ {value: 0x0000, lo: 0x01},
+ {value: 0x9900, lo: 0x80, hi: 0x82},
+ // Block 0x2e, offset 0x11a
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0x9d, hi: 0x9f},
+ // Block 0x2f, offset 0x11c
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x94, hi: 0x94},
+ {value: 0x8105, lo: 0xb4, hi: 0xb4},
+ // Block 0x30, offset 0x11f
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x92, hi: 0x92},
+ {value: 0x8133, lo: 0x9d, hi: 0x9d},
+ // Block 0x31, offset 0x122
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8132, lo: 0xa9, hi: 0xa9},
+ // Block 0x32, offset 0x124
+ {value: 0x0004, lo: 0x02},
+ {value: 0x812f, lo: 0xb9, hi: 0xba},
+ {value: 0x812e, lo: 0xbb, hi: 0xbb},
+ // Block 0x33, offset 0x127
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8133, lo: 0x97, hi: 0x97},
+ {value: 0x812e, lo: 0x98, hi: 0x98},
+ // Block 0x34, offset 0x12a
+ {value: 0x0000, lo: 0x03},
+ {value: 0x8105, lo: 0xa0, hi: 0xa0},
+ {value: 0x8133, lo: 0xb5, hi: 0xbc},
+ {value: 0x812e, lo: 0xbf, hi: 0xbf},
+ // Block 0x35, offset 0x12e
+ {value: 0x0000, lo: 0x05},
+ {value: 0x8133, lo: 0xb0, hi: 0xb4},
+ {value: 0x812e, lo: 0xb5, hi: 0xba},
+ {value: 0x8133, lo: 0xbb, hi: 0xbc},
+ {value: 0x812e, lo: 0xbd, hi: 0xbd},
+ {value: 0x812e, lo: 0xbf, hi: 0xbf},
+ // Block 0x36, offset 0x134
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0x80, hi: 0x80},
+ // Block 0x37, offset 0x136
+ {value: 0x0000, lo: 0x08},
+ {value: 0x2d73, lo: 0x80, hi: 0x80},
+ {value: 0x2d7b, lo: 0x81, hi: 0x81},
+ {value: 0xa000, lo: 0x82, hi: 0x82},
+ {value: 0x2d83, lo: 0x83, hi: 0x83},
+ {value: 0x8105, lo: 0x84, hi: 0x84},
+ {value: 0x8133, lo: 0xab, hi: 0xab},
+ {value: 0x812e, lo: 0xac, hi: 0xac},
+ {value: 0x8133, lo: 0xad, hi: 0xb3},
+ // Block 0x38, offset 0x13f
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0xaa, hi: 0xab},
+ // Block 0x39, offset 0x141
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8103, lo: 0xa6, hi: 0xa6},
+ {value: 0x8105, lo: 0xb2, hi: 0xb3},
+ // Block 0x3a, offset 0x144
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8103, lo: 0xb7, hi: 0xb7},
+ // Block 0x3b, offset 0x146
+ {value: 0x0000, lo: 0x0a},
+ {value: 0x8133, lo: 0x90, hi: 0x92},
+ {value: 0x8101, lo: 0x94, hi: 0x94},
+ {value: 0x812e, lo: 0x95, hi: 0x99},
+ {value: 0x8133, lo: 0x9a, hi: 0x9b},
+ {value: 0x812e, lo: 0x9c, hi: 0x9f},
+ {value: 0x8133, lo: 0xa0, hi: 0xa0},
+ {value: 0x8101, lo: 0xa2, hi: 0xa8},
+ {value: 0x812e, lo: 0xad, hi: 0xad},
+ {value: 0x8133, lo: 0xb4, hi: 0xb4},
+ {value: 0x8133, lo: 0xb8, hi: 0xb9},
+ // Block 0x3c, offset 0x151
+ {value: 0x0002, lo: 0x0a},
+ {value: 0x0043, lo: 0xac, hi: 0xac},
+ {value: 0x00d1, lo: 0xad, hi: 0xad},
+ {value: 0x0045, lo: 0xae, hi: 0xae},
+ {value: 0x0049, lo: 0xb0, hi: 0xb1},
+ {value: 0x00e6, lo: 0xb2, hi: 0xb2},
+ {value: 0x004f, lo: 0xb3, hi: 0xba},
+ {value: 0x005f, lo: 0xbc, hi: 0xbc},
+ {value: 0x00ef, lo: 0xbd, hi: 0xbd},
+ {value: 0x0061, lo: 0xbe, hi: 0xbe},
+ {value: 0x0065, lo: 0xbf, hi: 0xbf},
+ // Block 0x3d, offset 0x15c
+ {value: 0x0000, lo: 0x0d},
+ {value: 0x0001, lo: 0x80, hi: 0x8a},
+ {value: 0x043e, lo: 0x91, hi: 0x91},
+ {value: 0x42b2, lo: 0x97, hi: 0x97},
+ {value: 0x001d, lo: 0xa4, hi: 0xa4},
+ {value: 0x1876, lo: 0xa5, hi: 0xa5},
+ {value: 0x1b62, lo: 0xa6, hi: 0xa6},
+ {value: 0x0001, lo: 0xaf, hi: 0xaf},
+ {value: 0x2697, lo: 0xb3, hi: 0xb3},
+ {value: 0x280b, lo: 0xb4, hi: 0xb4},
+ {value: 0x269e, lo: 0xb6, hi: 0xb6},
+ {value: 0x2815, lo: 0xb7, hi: 0xb7},
+ {value: 0x1870, lo: 0xbc, hi: 0xbc},
+ {value: 0x4280, lo: 0xbe, hi: 0xbe},
+ // Block 0x3e, offset 0x16a
+ {value: 0x0002, lo: 0x0d},
+ {value: 0x1936, lo: 0x87, hi: 0x87},
+ {value: 0x1933, lo: 0x88, hi: 0x88},
+ {value: 0x1873, lo: 0x89, hi: 0x89},
+ {value: 0x299b, lo: 0x97, hi: 0x97},
+ {value: 0x0001, lo: 0x9f, hi: 0x9f},
+ {value: 0x0021, lo: 0xb0, hi: 0xb0},
+ {value: 0x0093, lo: 0xb1, hi: 0xb1},
+ {value: 0x0029, lo: 0xb4, hi: 0xb9},
+ {value: 0x0017, lo: 0xba, hi: 0xba},
+ {value: 0x046a, lo: 0xbb, hi: 0xbb},
+ {value: 0x003b, lo: 0xbc, hi: 0xbc},
+ {value: 0x0011, lo: 0xbd, hi: 0xbe},
+ {value: 0x009d, lo: 0xbf, hi: 0xbf},
+ // Block 0x3f, offset 0x178
+ {value: 0x0002, lo: 0x0f},
+ {value: 0x0021, lo: 0x80, hi: 0x89},
+ {value: 0x0017, lo: 0x8a, hi: 0x8a},
+ {value: 0x046a, lo: 0x8b, hi: 0x8b},
+ {value: 0x003b, lo: 0x8c, hi: 0x8c},
+ {value: 0x0011, lo: 0x8d, hi: 0x8e},
+ {value: 0x0083, lo: 0x90, hi: 0x90},
+ {value: 0x008b, lo: 0x91, hi: 0x91},
+ {value: 0x009f, lo: 0x92, hi: 0x92},
+ {value: 0x00b1, lo: 0x93, hi: 0x93},
+ {value: 0x0104, lo: 0x94, hi: 0x94},
+ {value: 0x0091, lo: 0x95, hi: 0x95},
+ {value: 0x0097, lo: 0x96, hi: 0x99},
+ {value: 0x00a1, lo: 0x9a, hi: 0x9a},
+ {value: 0x00a7, lo: 0x9b, hi: 0x9c},
+ {value: 0x199f, lo: 0xa8, hi: 0xa8},
+ // Block 0x40, offset 0x188
+ {value: 0x0000, lo: 0x0d},
+ {value: 0x8133, lo: 0x90, hi: 0x91},
+ {value: 0x8101, lo: 0x92, hi: 0x93},
+ {value: 0x8133, lo: 0x94, hi: 0x97},
+ {value: 0x8101, lo: 0x98, hi: 0x9a},
+ {value: 0x8133, lo: 0x9b, hi: 0x9c},
+ {value: 0x8133, lo: 0xa1, hi: 0xa1},
+ {value: 0x8101, lo: 0xa5, hi: 0xa6},
+ {value: 0x8133, lo: 0xa7, hi: 0xa7},
+ {value: 0x812e, lo: 0xa8, hi: 0xa8},
+ {value: 0x8133, lo: 0xa9, hi: 0xa9},
+ {value: 0x8101, lo: 0xaa, hi: 0xab},
+ {value: 0x812e, lo: 0xac, hi: 0xaf},
+ {value: 0x8133, lo: 0xb0, hi: 0xb0},
+ // Block 0x41, offset 0x196
+ {value: 0x0007, lo: 0x06},
+ {value: 0x2186, lo: 0x89, hi: 0x89},
+ {value: 0xa000, lo: 0x90, hi: 0x90},
+ {value: 0xa000, lo: 0x92, hi: 0x92},
+ {value: 0xa000, lo: 0x94, hi: 0x94},
+ {value: 0x3bd0, lo: 0x9a, hi: 0x9b},
+ {value: 0x3bde, lo: 0xae, hi: 0xae},
+ // Block 0x42, offset 0x19d
+ {value: 0x000e, lo: 0x05},
+ {value: 0x3be5, lo: 0x8d, hi: 0x8e},
+ {value: 0x3bec, lo: 0x8f, hi: 0x8f},
+ {value: 0xa000, lo: 0x90, hi: 0x90},
+ {value: 0xa000, lo: 0x92, hi: 0x92},
+ {value: 0xa000, lo: 0x94, hi: 0x94},
+ // Block 0x43, offset 0x1a3
+ {value: 0x017a, lo: 0x0e},
+ {value: 0xa000, lo: 0x83, hi: 0x83},
+ {value: 0x3bfa, lo: 0x84, hi: 0x84},
+ {value: 0xa000, lo: 0x88, hi: 0x88},
+ {value: 0x3c01, lo: 0x89, hi: 0x89},
+ {value: 0xa000, lo: 0x8b, hi: 0x8b},
+ {value: 0x3c08, lo: 0x8c, hi: 0x8c},
+ {value: 0xa000, lo: 0xa3, hi: 0xa3},
+ {value: 0x3c0f, lo: 0xa4, hi: 0xa4},
+ {value: 0xa000, lo: 0xa5, hi: 0xa5},
+ {value: 0x3c16, lo: 0xa6, hi: 0xa6},
+ {value: 0x26a5, lo: 0xac, hi: 0xad},
+ {value: 0x26ac, lo: 0xaf, hi: 0xaf},
+ {value: 0x2829, lo: 0xb0, hi: 0xb0},
+ {value: 0xa000, lo: 0xbc, hi: 0xbc},
+ // Block 0x44, offset 0x1b2
+ {value: 0x0007, lo: 0x03},
+ {value: 0x3c7f, lo: 0xa0, hi: 0xa1},
+ {value: 0x3ca9, lo: 0xa2, hi: 0xa3},
+ {value: 0x3cd3, lo: 0xaa, hi: 0xad},
+ // Block 0x45, offset 0x1b6
+ {value: 0x0004, lo: 0x01},
+ {value: 0x048e, lo: 0xa9, hi: 0xaa},
+ // Block 0x46, offset 0x1b8
+ {value: 0x0002, lo: 0x03},
+ {value: 0x0057, lo: 0x80, hi: 0x8f},
+ {value: 0x0083, lo: 0x90, hi: 0xa9},
+ {value: 0x0021, lo: 0xaa, hi: 0xaa},
+ // Block 0x47, offset 0x1bc
+ {value: 0x0000, lo: 0x01},
+ {value: 0x29a8, lo: 0x8c, hi: 0x8c},
+ // Block 0x48, offset 0x1be
+ {value: 0x0266, lo: 0x02},
+ {value: 0x1b92, lo: 0xb4, hi: 0xb4},
+ {value: 0x1930, lo: 0xb5, hi: 0xb6},
+ // Block 0x49, offset 0x1c1
+ {value: 0x0000, lo: 0x01},
+ {value: 0x44f4, lo: 0x9c, hi: 0x9c},
+ // Block 0x4a, offset 0x1c3
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0095, lo: 0xbc, hi: 0xbc},
+ {value: 0x006d, lo: 0xbd, hi: 0xbd},
+ // Block 0x4b, offset 0x1c6
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xaf, hi: 0xb1},
+ // Block 0x4c, offset 0x1c8
+ {value: 0x0000, lo: 0x02},
+ {value: 0x0482, lo: 0xaf, hi: 0xaf},
+ {value: 0x8105, lo: 0xbf, hi: 0xbf},
+ // Block 0x4d, offset 0x1cb
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xa0, hi: 0xbf},
+ // Block 0x4e, offset 0x1cd
+ {value: 0x0000, lo: 0x01},
+ {value: 0x0dc6, lo: 0x9f, hi: 0x9f},
+ // Block 0x4f, offset 0x1cf
+ {value: 0x0000, lo: 0x01},
+ {value: 0x1632, lo: 0xb3, hi: 0xb3},
+ // Block 0x50, offset 0x1d1
+ {value: 0x0004, lo: 0x0b},
+ {value: 0x159a, lo: 0x80, hi: 0x82},
+ {value: 0x15b2, lo: 0x83, hi: 0x83},
+ {value: 0x15ca, lo: 0x84, hi: 0x85},
+ {value: 0x15da, lo: 0x86, hi: 0x89},
+ {value: 0x15ee, lo: 0x8a, hi: 0x8c},
+ {value: 0x1602, lo: 0x8d, hi: 0x8d},
+ {value: 0x160a, lo: 0x8e, hi: 0x8e},
+ {value: 0x1612, lo: 0x8f, hi: 0x90},
+ {value: 0x161e, lo: 0x91, hi: 0x93},
+ {value: 0x162e, lo: 0x94, hi: 0x94},
+ {value: 0x1636, lo: 0x95, hi: 0x95},
+ // Block 0x51, offset 0x1dd
+ {value: 0x0004, lo: 0x09},
+ {value: 0x0001, lo: 0x80, hi: 0x80},
+ {value: 0x812d, lo: 0xaa, hi: 0xaa},
+ {value: 0x8132, lo: 0xab, hi: 0xab},
+ {value: 0x8134, lo: 0xac, hi: 0xac},
+ {value: 0x812f, lo: 0xad, hi: 0xad},
+ {value: 0x8130, lo: 0xae, hi: 0xae},
+ {value: 0x8130, lo: 0xaf, hi: 0xaf},
+ {value: 0x04b6, lo: 0xb6, hi: 0xb6},
+ {value: 0x088a, lo: 0xb8, hi: 0xba},
+ // Block 0x52, offset 0x1e7
+ {value: 0x0006, lo: 0x09},
+ {value: 0x0316, lo: 0xb1, hi: 0xb1},
+ {value: 0x031a, lo: 0xb2, hi: 0xb2},
+ {value: 0x4a52, lo: 0xb3, hi: 0xb3},
+ {value: 0x031e, lo: 0xb4, hi: 0xb4},
+ {value: 0x4a58, lo: 0xb5, hi: 0xb6},
+ {value: 0x0322, lo: 0xb7, hi: 0xb7},
+ {value: 0x0326, lo: 0xb8, hi: 0xb8},
+ {value: 0x032a, lo: 0xb9, hi: 0xb9},
+ {value: 0x4a64, lo: 0xba, hi: 0xbf},
+ // Block 0x53, offset 0x1f1
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8133, lo: 0xaf, hi: 0xaf},
+ {value: 0x8133, lo: 0xb4, hi: 0xbd},
+ // Block 0x54, offset 0x1f4
+ {value: 0x0000, lo: 0x03},
+ {value: 0x0212, lo: 0x9c, hi: 0x9c},
+ {value: 0x0215, lo: 0x9d, hi: 0x9d},
+ {value: 0x8133, lo: 0x9e, hi: 0x9f},
+ // Block 0x55, offset 0x1f8
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xb0, hi: 0xb1},
+ // Block 0x56, offset 0x1fa
+ {value: 0x0000, lo: 0x01},
+ {value: 0x163e, lo: 0xb0, hi: 0xb0},
+ // Block 0x57, offset 0x1fc
+ {value: 0x000c, lo: 0x01},
+ {value: 0x00d7, lo: 0xb8, hi: 0xb9},
+ // Block 0x58, offset 0x1fe
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x86, hi: 0x86},
+ {value: 0x8105, lo: 0xac, hi: 0xac},
+ // Block 0x59, offset 0x201
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x84, hi: 0x84},
+ {value: 0x8133, lo: 0xa0, hi: 0xb1},
+ // Block 0x5a, offset 0x204
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0xab, hi: 0xad},
+ // Block 0x5b, offset 0x206
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0x93, hi: 0x93},
+ // Block 0x5c, offset 0x208
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8103, lo: 0xb3, hi: 0xb3},
+ // Block 0x5d, offset 0x20a
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0x80, hi: 0x80},
+ // Block 0x5e, offset 0x20c
+ {value: 0x0000, lo: 0x05},
+ {value: 0x8133, lo: 0xb0, hi: 0xb0},
+ {value: 0x8133, lo: 0xb2, hi: 0xb3},
+ {value: 0x812e, lo: 0xb4, hi: 0xb4},
+ {value: 0x8133, lo: 0xb7, hi: 0xb8},
+ {value: 0x8133, lo: 0xbe, hi: 0xbf},
+ // Block 0x5f, offset 0x212
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8133, lo: 0x81, hi: 0x81},
+ {value: 0x8105, lo: 0xb6, hi: 0xb6},
+ // Block 0x60, offset 0x215
+ {value: 0x0008, lo: 0x04},
+ {value: 0x163a, lo: 0x9c, hi: 0x9d},
+ {value: 0x0125, lo: 0x9e, hi: 0x9e},
+ {value: 0x1646, lo: 0x9f, hi: 0x9f},
+ {value: 0x015e, lo: 0xa9, hi: 0xa9},
+ // Block 0x61, offset 0x21a
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0xad, hi: 0xad},
+ // Block 0x62, offset 0x21c
+ {value: 0x0000, lo: 0x06},
+ {value: 0xe500, lo: 0x80, hi: 0x80},
+ {value: 0xc600, lo: 0x81, hi: 0x9b},
+ {value: 0xe500, lo: 0x9c, hi: 0x9c},
+ {value: 0xc600, lo: 0x9d, hi: 0xb7},
+ {value: 0xe500, lo: 0xb8, hi: 0xb8},
+ {value: 0xc600, lo: 0xb9, hi: 0xbf},
+ // Block 0x63, offset 0x223
+ {value: 0x0000, lo: 0x05},
+ {value: 0xc600, lo: 0x80, hi: 0x93},
+ {value: 0xe500, lo: 0x94, hi: 0x94},
+ {value: 0xc600, lo: 0x95, hi: 0xaf},
+ {value: 0xe500, lo: 0xb0, hi: 0xb0},
+ {value: 0xc600, lo: 0xb1, hi: 0xbf},
+ // Block 0x64, offset 0x229
+ {value: 0x0000, lo: 0x05},
+ {value: 0xc600, lo: 0x80, hi: 0x8b},
+ {value: 0xe500, lo: 0x8c, hi: 0x8c},
+ {value: 0xc600, lo: 0x8d, hi: 0xa7},
+ {value: 0xe500, lo: 0xa8, hi: 0xa8},
+ {value: 0xc600, lo: 0xa9, hi: 0xbf},
+ // Block 0x65, offset 0x22f
+ {value: 0x0000, lo: 0x07},
+ {value: 0xc600, lo: 0x80, hi: 0x83},
+ {value: 0xe500, lo: 0x84, hi: 0x84},
+ {value: 0xc600, lo: 0x85, hi: 0x9f},
+ {value: 0xe500, lo: 0xa0, hi: 0xa0},
+ {value: 0xc600, lo: 0xa1, hi: 0xbb},
+ {value: 0xe500, lo: 0xbc, hi: 0xbc},
+ {value: 0xc600, lo: 0xbd, hi: 0xbf},
+ // Block 0x66, offset 0x237
+ {value: 0x0000, lo: 0x05},
+ {value: 0xc600, lo: 0x80, hi: 0x97},
+ {value: 0xe500, lo: 0x98, hi: 0x98},
+ {value: 0xc600, lo: 0x99, hi: 0xb3},
+ {value: 0xe500, lo: 0xb4, hi: 0xb4},
+ {value: 0xc600, lo: 0xb5, hi: 0xbf},
+ // Block 0x67, offset 0x23d
+ {value: 0x0000, lo: 0x05},
+ {value: 0xc600, lo: 0x80, hi: 0x8f},
+ {value: 0xe500, lo: 0x90, hi: 0x90},
+ {value: 0xc600, lo: 0x91, hi: 0xab},
+ {value: 0xe500, lo: 0xac, hi: 0xac},
+ {value: 0xc600, lo: 0xad, hi: 0xbf},
+ // Block 0x68, offset 0x243
+ {value: 0x0000, lo: 0x05},
+ {value: 0xc600, lo: 0x80, hi: 0x87},
+ {value: 0xe500, lo: 0x88, hi: 0x88},
+ {value: 0xc600, lo: 0x89, hi: 0xa3},
+ {value: 0xe500, lo: 0xa4, hi: 0xa4},
+ {value: 0xc600, lo: 0xa5, hi: 0xbf},
+ // Block 0x69, offset 0x249
+ {value: 0x0000, lo: 0x03},
+ {value: 0xc600, lo: 0x80, hi: 0x87},
+ {value: 0xe500, lo: 0x88, hi: 0x88},
+ {value: 0xc600, lo: 0x89, hi: 0xa3},
+ // Block 0x6a, offset 0x24d
+ {value: 0x0002, lo: 0x01},
+ {value: 0x0003, lo: 0x81, hi: 0xbf},
+ // Block 0x6b, offset 0x24f
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0xbd, hi: 0xbd},
+ // Block 0x6c, offset 0x251
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0xa0, hi: 0xa0},
+ // Block 0x6d, offset 0x253
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xb6, hi: 0xba},
+ // Block 0x6e, offset 0x255
+ {value: 0x002d, lo: 0x05},
+ {value: 0x812e, lo: 0x8d, hi: 0x8d},
+ {value: 0x8133, lo: 0x8f, hi: 0x8f},
+ {value: 0x8133, lo: 0xb8, hi: 0xb8},
+ {value: 0x8101, lo: 0xb9, hi: 0xba},
+ {value: 0x8105, lo: 0xbf, hi: 0xbf},
+ // Block 0x6f, offset 0x25b
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8133, lo: 0xa5, hi: 0xa5},
+ {value: 0x812e, lo: 0xa6, hi: 0xa6},
+ // Block 0x70, offset 0x25e
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xa4, hi: 0xa7},
+ // Block 0x71, offset 0x260
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xab, hi: 0xac},
+ // Block 0x72, offset 0x262
+ {value: 0x0000, lo: 0x05},
+ {value: 0x812e, lo: 0x86, hi: 0x87},
+ {value: 0x8133, lo: 0x88, hi: 0x8a},
+ {value: 0x812e, lo: 0x8b, hi: 0x8b},
+ {value: 0x8133, lo: 0x8c, hi: 0x8c},
+ {value: 0x812e, lo: 0x8d, hi: 0x90},
+ // Block 0x73, offset 0x268
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x86, hi: 0x86},
+ {value: 0x8105, lo: 0xbf, hi: 0xbf},
+ // Block 0x74, offset 0x26b
+ {value: 0x17fe, lo: 0x07},
+ {value: 0xa000, lo: 0x99, hi: 0x99},
+ {value: 0x424f, lo: 0x9a, hi: 0x9a},
+ {value: 0xa000, lo: 0x9b, hi: 0x9b},
+ {value: 0x4259, lo: 0x9c, hi: 0x9c},
+ {value: 0xa000, lo: 0xa5, hi: 0xa5},
+ {value: 0x4263, lo: 0xab, hi: 0xab},
+ {value: 0x8105, lo: 0xb9, hi: 0xba},
+ // Block 0x75, offset 0x273
+ {value: 0x0000, lo: 0x06},
+ {value: 0x8133, lo: 0x80, hi: 0x82},
+ {value: 0x9900, lo: 0xa7, hi: 0xa7},
+ {value: 0x2d8b, lo: 0xae, hi: 0xae},
+ {value: 0x2d95, lo: 0xaf, hi: 0xaf},
+ {value: 0xa000, lo: 0xb1, hi: 0xb2},
+ {value: 0x8105, lo: 0xb3, hi: 0xb4},
+ // Block 0x76, offset 0x27a
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x80, hi: 0x80},
+ {value: 0x8103, lo: 0x8a, hi: 0x8a},
+ // Block 0x77, offset 0x27d
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0xb5, hi: 0xb5},
+ {value: 0x8103, lo: 0xb6, hi: 0xb6},
+ // Block 0x78, offset 0x280
+ {value: 0x0002, lo: 0x01},
+ {value: 0x8103, lo: 0xa9, hi: 0xaa},
+ // Block 0x79, offset 0x282
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8103, lo: 0xbb, hi: 0xbc},
+ {value: 0x9900, lo: 0xbe, hi: 0xbe},
+ // Block 0x7a, offset 0x285
+ {value: 0x0000, lo: 0x07},
+ {value: 0xa000, lo: 0x87, hi: 0x87},
+ {value: 0x2d9f, lo: 0x8b, hi: 0x8b},
+ {value: 0x2da9, lo: 0x8c, hi: 0x8c},
+ {value: 0x8105, lo: 0x8d, hi: 0x8d},
+ {value: 0x9900, lo: 0x97, hi: 0x97},
+ {value: 0x8133, lo: 0xa6, hi: 0xac},
+ {value: 0x8133, lo: 0xb0, hi: 0xb4},
+ // Block 0x7b, offset 0x28d
+ {value: 0x0000, lo: 0x03},
+ {value: 0x8105, lo: 0x82, hi: 0x82},
+ {value: 0x8103, lo: 0x86, hi: 0x86},
+ {value: 0x8133, lo: 0x9e, hi: 0x9e},
+ // Block 0x7c, offset 0x291
+ {value: 0x6b4d, lo: 0x06},
+ {value: 0x9900, lo: 0xb0, hi: 0xb0},
+ {value: 0xa000, lo: 0xb9, hi: 0xb9},
+ {value: 0x9900, lo: 0xba, hi: 0xba},
+ {value: 0x2dbd, lo: 0xbb, hi: 0xbb},
+ {value: 0x2db3, lo: 0xbc, hi: 0xbd},
+ {value: 0x2dc7, lo: 0xbe, hi: 0xbe},
+ // Block 0x7d, offset 0x298
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0x82, hi: 0x82},
+ {value: 0x8103, lo: 0x83, hi: 0x83},
+ // Block 0x7e, offset 0x29b
+ {value: 0x0000, lo: 0x05},
+ {value: 0x9900, lo: 0xaf, hi: 0xaf},
+ {value: 0xa000, lo: 0xb8, hi: 0xb9},
+ {value: 0x2dd1, lo: 0xba, hi: 0xba},
+ {value: 0x2ddb, lo: 0xbb, hi: 0xbb},
+ {value: 0x8105, lo: 0xbf, hi: 0xbf},
+ // Block 0x7f, offset 0x2a1
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8103, lo: 0x80, hi: 0x80},
+ // Block 0x80, offset 0x2a3
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0xbf, hi: 0xbf},
+ // Block 0x81, offset 0x2a5
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0xb6, hi: 0xb6},
+ {value: 0x8103, lo: 0xb7, hi: 0xb7},
+ // Block 0x82, offset 0x2a8
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0xab, hi: 0xab},
+ // Block 0x83, offset 0x2aa
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8105, lo: 0xb9, hi: 0xb9},
+ {value: 0x8103, lo: 0xba, hi: 0xba},
+ // Block 0x84, offset 0x2ad
+ {value: 0x0000, lo: 0x04},
+ {value: 0x9900, lo: 0xb0, hi: 0xb0},
+ {value: 0xa000, lo: 0xb5, hi: 0xb5},
+ {value: 0x2de5, lo: 0xb8, hi: 0xb8},
+ {value: 0x8105, lo: 0xbd, hi: 0xbe},
+ // Block 0x85, offset 0x2b2
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8103, lo: 0x83, hi: 0x83},
+ // Block 0x86, offset 0x2b4
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0xa0, hi: 0xa0},
+ // Block 0x87, offset 0x2b6
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0xb4, hi: 0xb4},
+ // Block 0x88, offset 0x2b8
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0x87, hi: 0x87},
+ // Block 0x89, offset 0x2ba
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0x99, hi: 0x99},
+ // Block 0x8a, offset 0x2bc
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8103, lo: 0x82, hi: 0x82},
+ {value: 0x8105, lo: 0x84, hi: 0x85},
+ // Block 0x8b, offset 0x2bf
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8105, lo: 0x97, hi: 0x97},
+ // Block 0x8c, offset 0x2c1
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8101, lo: 0xb0, hi: 0xb4},
+ // Block 0x8d, offset 0x2c3
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xb0, hi: 0xb6},
+ // Block 0x8e, offset 0x2c5
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8102, lo: 0xb0, hi: 0xb1},
+ // Block 0x8f, offset 0x2c7
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8101, lo: 0x9e, hi: 0x9e},
+ // Block 0x90, offset 0x2c9
+ {value: 0x0000, lo: 0x0c},
+ {value: 0x45e3, lo: 0x9e, hi: 0x9e},
+ {value: 0x45ed, lo: 0x9f, hi: 0x9f},
+ {value: 0x4621, lo: 0xa0, hi: 0xa0},
+ {value: 0x462f, lo: 0xa1, hi: 0xa1},
+ {value: 0x463d, lo: 0xa2, hi: 0xa2},
+ {value: 0x464b, lo: 0xa3, hi: 0xa3},
+ {value: 0x4659, lo: 0xa4, hi: 0xa4},
+ {value: 0x812c, lo: 0xa5, hi: 0xa6},
+ {value: 0x8101, lo: 0xa7, hi: 0xa9},
+ {value: 0x8131, lo: 0xad, hi: 0xad},
+ {value: 0x812c, lo: 0xae, hi: 0xb2},
+ {value: 0x812e, lo: 0xbb, hi: 0xbf},
+ // Block 0x91, offset 0x2d6
+ {value: 0x0000, lo: 0x09},
+ {value: 0x812e, lo: 0x80, hi: 0x82},
+ {value: 0x8133, lo: 0x85, hi: 0x89},
+ {value: 0x812e, lo: 0x8a, hi: 0x8b},
+ {value: 0x8133, lo: 0xaa, hi: 0xad},
+ {value: 0x45f7, lo: 0xbb, hi: 0xbb},
+ {value: 0x4601, lo: 0xbc, hi: 0xbc},
+ {value: 0x4667, lo: 0xbd, hi: 0xbd},
+ {value: 0x4683, lo: 0xbe, hi: 0xbe},
+ {value: 0x4675, lo: 0xbf, hi: 0xbf},
+ // Block 0x92, offset 0x2e0
+ {value: 0x0000, lo: 0x01},
+ {value: 0x4691, lo: 0x80, hi: 0x80},
+ // Block 0x93, offset 0x2e2
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0x82, hi: 0x84},
+ // Block 0x94, offset 0x2e4
+ {value: 0x0002, lo: 0x03},
+ {value: 0x0043, lo: 0x80, hi: 0x99},
+ {value: 0x0083, lo: 0x9a, hi: 0xb3},
+ {value: 0x0043, lo: 0xb4, hi: 0xbf},
+ // Block 0x95, offset 0x2e8
+ {value: 0x0002, lo: 0x04},
+ {value: 0x005b, lo: 0x80, hi: 0x8d},
+ {value: 0x0083, lo: 0x8e, hi: 0x94},
+ {value: 0x0093, lo: 0x96, hi: 0xa7},
+ {value: 0x0043, lo: 0xa8, hi: 0xbf},
+ // Block 0x96, offset 0x2ed
+ {value: 0x0002, lo: 0x0b},
+ {value: 0x0073, lo: 0x80, hi: 0x81},
+ {value: 0x0083, lo: 0x82, hi: 0x9b},
+ {value: 0x0043, lo: 0x9c, hi: 0x9c},
+ {value: 0x0047, lo: 0x9e, hi: 0x9f},
+ {value: 0x004f, lo: 0xa2, hi: 0xa2},
+ {value: 0x0055, lo: 0xa5, hi: 0xa6},
+ {value: 0x005d, lo: 0xa9, hi: 0xac},
+ {value: 0x0067, lo: 0xae, hi: 0xb5},
+ {value: 0x0083, lo: 0xb6, hi: 0xb9},
+ {value: 0x008d, lo: 0xbb, hi: 0xbb},
+ {value: 0x0091, lo: 0xbd, hi: 0xbf},
+ // Block 0x97, offset 0x2f9
+ {value: 0x0002, lo: 0x04},
+ {value: 0x0097, lo: 0x80, hi: 0x83},
+ {value: 0x00a1, lo: 0x85, hi: 0x8f},
+ {value: 0x0043, lo: 0x90, hi: 0xa9},
+ {value: 0x0083, lo: 0xaa, hi: 0xbf},
+ // Block 0x98, offset 0x2fe
+ {value: 0x0002, lo: 0x08},
+ {value: 0x00af, lo: 0x80, hi: 0x83},
+ {value: 0x0043, lo: 0x84, hi: 0x85},
+ {value: 0x0049, lo: 0x87, hi: 0x8a},
+ {value: 0x0055, lo: 0x8d, hi: 0x94},
+ {value: 0x0067, lo: 0x96, hi: 0x9c},
+ {value: 0x0083, lo: 0x9e, hi: 0xb7},
+ {value: 0x0043, lo: 0xb8, hi: 0xb9},
+ {value: 0x0049, lo: 0xbb, hi: 0xbe},
+ // Block 0x99, offset 0x307
+ {value: 0x0002, lo: 0x05},
+ {value: 0x0053, lo: 0x80, hi: 0x84},
+ {value: 0x005f, lo: 0x86, hi: 0x86},
+ {value: 0x0067, lo: 0x8a, hi: 0x90},
+ {value: 0x0083, lo: 0x92, hi: 0xab},
+ {value: 0x0043, lo: 0xac, hi: 0xbf},
+ // Block 0x9a, offset 0x30d
+ {value: 0x0002, lo: 0x04},
+ {value: 0x006b, lo: 0x80, hi: 0x85},
+ {value: 0x0083, lo: 0x86, hi: 0x9f},
+ {value: 0x0043, lo: 0xa0, hi: 0xb9},
+ {value: 0x0083, lo: 0xba, hi: 0xbf},
+ // Block 0x9b, offset 0x312
+ {value: 0x0002, lo: 0x03},
+ {value: 0x008f, lo: 0x80, hi: 0x93},
+ {value: 0x0043, lo: 0x94, hi: 0xad},
+ {value: 0x0083, lo: 0xae, hi: 0xbf},
+ // Block 0x9c, offset 0x316
+ {value: 0x0002, lo: 0x04},
+ {value: 0x00a7, lo: 0x80, hi: 0x87},
+ {value: 0x0043, lo: 0x88, hi: 0xa1},
+ {value: 0x0083, lo: 0xa2, hi: 0xbb},
+ {value: 0x0043, lo: 0xbc, hi: 0xbf},
+ // Block 0x9d, offset 0x31b
+ {value: 0x0002, lo: 0x03},
+ {value: 0x004b, lo: 0x80, hi: 0x95},
+ {value: 0x0083, lo: 0x96, hi: 0xaf},
+ {value: 0x0043, lo: 0xb0, hi: 0xbf},
+ // Block 0x9e, offset 0x31f
+ {value: 0x0003, lo: 0x0f},
+ {value: 0x01bb, lo: 0x80, hi: 0x80},
+ {value: 0x0462, lo: 0x81, hi: 0x81},
+ {value: 0x01be, lo: 0x82, hi: 0x9a},
+ {value: 0x045e, lo: 0x9b, hi: 0x9b},
+ {value: 0x01ca, lo: 0x9c, hi: 0x9c},
+ {value: 0x01d3, lo: 0x9d, hi: 0x9d},
+ {value: 0x01d9, lo: 0x9e, hi: 0x9e},
+ {value: 0x01fd, lo: 0x9f, hi: 0x9f},
+ {value: 0x01ee, lo: 0xa0, hi: 0xa0},
+ {value: 0x01eb, lo: 0xa1, hi: 0xa1},
+ {value: 0x0176, lo: 0xa2, hi: 0xb2},
+ {value: 0x018b, lo: 0xb3, hi: 0xb3},
+ {value: 0x01a9, lo: 0xb4, hi: 0xba},
+ {value: 0x0462, lo: 0xbb, hi: 0xbb},
+ {value: 0x01be, lo: 0xbc, hi: 0xbf},
+ // Block 0x9f, offset 0x32f
+ {value: 0x0003, lo: 0x0d},
+ {value: 0x01ca, lo: 0x80, hi: 0x94},
+ {value: 0x045e, lo: 0x95, hi: 0x95},
+ {value: 0x01ca, lo: 0x96, hi: 0x96},
+ {value: 0x01d3, lo: 0x97, hi: 0x97},
+ {value: 0x01d9, lo: 0x98, hi: 0x98},
+ {value: 0x01fd, lo: 0x99, hi: 0x99},
+ {value: 0x01ee, lo: 0x9a, hi: 0x9a},
+ {value: 0x01eb, lo: 0x9b, hi: 0x9b},
+ {value: 0x0176, lo: 0x9c, hi: 0xac},
+ {value: 0x018b, lo: 0xad, hi: 0xad},
+ {value: 0x01a9, lo: 0xae, hi: 0xb4},
+ {value: 0x0462, lo: 0xb5, hi: 0xb5},
+ {value: 0x01be, lo: 0xb6, hi: 0xbf},
+ // Block 0xa0, offset 0x33d
+ {value: 0x0003, lo: 0x0d},
+ {value: 0x01dc, lo: 0x80, hi: 0x8e},
+ {value: 0x045e, lo: 0x8f, hi: 0x8f},
+ {value: 0x01ca, lo: 0x90, hi: 0x90},
+ {value: 0x01d3, lo: 0x91, hi: 0x91},
+ {value: 0x01d9, lo: 0x92, hi: 0x92},
+ {value: 0x01fd, lo: 0x93, hi: 0x93},
+ {value: 0x01ee, lo: 0x94, hi: 0x94},
+ {value: 0x01eb, lo: 0x95, hi: 0x95},
+ {value: 0x0176, lo: 0x96, hi: 0xa6},
+ {value: 0x018b, lo: 0xa7, hi: 0xa7},
+ {value: 0x01a9, lo: 0xa8, hi: 0xae},
+ {value: 0x0462, lo: 0xaf, hi: 0xaf},
+ {value: 0x01be, lo: 0xb0, hi: 0xbf},
+ // Block 0xa1, offset 0x34b
+ {value: 0x0003, lo: 0x0d},
+ {value: 0x01ee, lo: 0x80, hi: 0x88},
+ {value: 0x045e, lo: 0x89, hi: 0x89},
+ {value: 0x01ca, lo: 0x8a, hi: 0x8a},
+ {value: 0x01d3, lo: 0x8b, hi: 0x8b},
+ {value: 0x01d9, lo: 0x8c, hi: 0x8c},
+ {value: 0x01fd, lo: 0x8d, hi: 0x8d},
+ {value: 0x01ee, lo: 0x8e, hi: 0x8e},
+ {value: 0x01eb, lo: 0x8f, hi: 0x8f},
+ {value: 0x0176, lo: 0x90, hi: 0xa0},
+ {value: 0x018b, lo: 0xa1, hi: 0xa1},
+ {value: 0x01a9, lo: 0xa2, hi: 0xa8},
+ {value: 0x0462, lo: 0xa9, hi: 0xa9},
+ {value: 0x01be, lo: 0xaa, hi: 0xbf},
+ // Block 0xa2, offset 0x359
+ {value: 0x0000, lo: 0x05},
+ {value: 0x8133, lo: 0x80, hi: 0x86},
+ {value: 0x8133, lo: 0x88, hi: 0x98},
+ {value: 0x8133, lo: 0x9b, hi: 0xa1},
+ {value: 0x8133, lo: 0xa3, hi: 0xa4},
+ {value: 0x8133, lo: 0xa6, hi: 0xaa},
+ // Block 0xa3, offset 0x35f
+ {value: 0x0000, lo: 0x01},
+ {value: 0x8133, lo: 0xac, hi: 0xaf},
+ // Block 0xa4, offset 0x361
+ {value: 0x0000, lo: 0x01},
+ {value: 0x812e, lo: 0x90, hi: 0x96},
+ // Block 0xa5, offset 0x363
+ {value: 0x0000, lo: 0x02},
+ {value: 0x8133, lo: 0x84, hi: 0x89},
+ {value: 0x8103, lo: 0x8a, hi: 0x8a},
+ // Block 0xa6, offset 0x366
+ {value: 0x0002, lo: 0x0a},
+ {value: 0x0063, lo: 0x80, hi: 0x89},
+ {value: 0x1954, lo: 0x8a, hi: 0x8a},
+ {value: 0x1987, lo: 0x8b, hi: 0x8b},
+ {value: 0x19a2, lo: 0x8c, hi: 0x8c},
+ {value: 0x19a8, lo: 0x8d, hi: 0x8d},
+ {value: 0x1bc6, lo: 0x8e, hi: 0x8e},
+ {value: 0x19b4, lo: 0x8f, hi: 0x8f},
+ {value: 0x197e, lo: 0xaa, hi: 0xaa},
+ {value: 0x1981, lo: 0xab, hi: 0xab},
+ {value: 0x1984, lo: 0xac, hi: 0xac},
+ // Block 0xa7, offset 0x371
+ {value: 0x0000, lo: 0x01},
+ {value: 0x1942, lo: 0x90, hi: 0x90},
+ // Block 0xa8, offset 0x373
+ {value: 0x0028, lo: 0x09},
+ {value: 0x286f, lo: 0x80, hi: 0x80},
+ {value: 0x2833, lo: 0x81, hi: 0x81},
+ {value: 0x283d, lo: 0x82, hi: 0x82},
+ {value: 0x2851, lo: 0x83, hi: 0x84},
+ {value: 0x285b, lo: 0x85, hi: 0x86},
+ {value: 0x2847, lo: 0x87, hi: 0x87},
+ {value: 0x2865, lo: 0x88, hi: 0x88},
+ {value: 0x0b72, lo: 0x90, hi: 0x90},
+ {value: 0x08ea, lo: 0x91, hi: 0x91},
+ // Block 0xa9, offset 0x37d
+ {value: 0x0002, lo: 0x01},
+ {value: 0x0021, lo: 0xb0, hi: 0xb9},
+}
+
+// recompMap: 7528 bytes (entries only)
+var recompMap map[uint32]rune
+var recompMapOnce sync.Once
+
+const recompMapPacked = "" +
+ "\x00A\x03\x00\x00\x00\x00\xc0" + // 0x00410300: 0x000000C0
+ "\x00A\x03\x01\x00\x00\x00\xc1" + // 0x00410301: 0x000000C1
+ "\x00A\x03\x02\x00\x00\x00\xc2" + // 0x00410302: 0x000000C2
+ "\x00A\x03\x03\x00\x00\x00\xc3" + // 0x00410303: 0x000000C3
+ "\x00A\x03\b\x00\x00\x00\xc4" + // 0x00410308: 0x000000C4
+ "\x00A\x03\n\x00\x00\x00\xc5" + // 0x0041030A: 0x000000C5
+ "\x00C\x03'\x00\x00\x00\xc7" + // 0x00430327: 0x000000C7
+ "\x00E\x03\x00\x00\x00\x00\xc8" + // 0x00450300: 0x000000C8
+ "\x00E\x03\x01\x00\x00\x00\xc9" + // 0x00450301: 0x000000C9
+ "\x00E\x03\x02\x00\x00\x00\xca" + // 0x00450302: 0x000000CA
+ "\x00E\x03\b\x00\x00\x00\xcb" + // 0x00450308: 0x000000CB
+ "\x00I\x03\x00\x00\x00\x00\xcc" + // 0x00490300: 0x000000CC
+ "\x00I\x03\x01\x00\x00\x00\xcd" + // 0x00490301: 0x000000CD
+ "\x00I\x03\x02\x00\x00\x00\xce" + // 0x00490302: 0x000000CE
+ "\x00I\x03\b\x00\x00\x00\xcf" + // 0x00490308: 0x000000CF
+ "\x00N\x03\x03\x00\x00\x00\xd1" + // 0x004E0303: 0x000000D1
+ "\x00O\x03\x00\x00\x00\x00\xd2" + // 0x004F0300: 0x000000D2
+ "\x00O\x03\x01\x00\x00\x00\xd3" + // 0x004F0301: 0x000000D3
+ "\x00O\x03\x02\x00\x00\x00\xd4" + // 0x004F0302: 0x000000D4
+ "\x00O\x03\x03\x00\x00\x00\xd5" + // 0x004F0303: 0x000000D5
+ "\x00O\x03\b\x00\x00\x00\xd6" + // 0x004F0308: 0x000000D6
+ "\x00U\x03\x00\x00\x00\x00\xd9" + // 0x00550300: 0x000000D9
+ "\x00U\x03\x01\x00\x00\x00\xda" + // 0x00550301: 0x000000DA
+ "\x00U\x03\x02\x00\x00\x00\xdb" + // 0x00550302: 0x000000DB
+ "\x00U\x03\b\x00\x00\x00\xdc" + // 0x00550308: 0x000000DC
+ "\x00Y\x03\x01\x00\x00\x00\xdd" + // 0x00590301: 0x000000DD
+ "\x00a\x03\x00\x00\x00\x00\xe0" + // 0x00610300: 0x000000E0
+ "\x00a\x03\x01\x00\x00\x00\xe1" + // 0x00610301: 0x000000E1
+ "\x00a\x03\x02\x00\x00\x00\xe2" + // 0x00610302: 0x000000E2
+ "\x00a\x03\x03\x00\x00\x00\xe3" + // 0x00610303: 0x000000E3
+ "\x00a\x03\b\x00\x00\x00\xe4" + // 0x00610308: 0x000000E4
+ "\x00a\x03\n\x00\x00\x00\xe5" + // 0x0061030A: 0x000000E5
+ "\x00c\x03'\x00\x00\x00\xe7" + // 0x00630327: 0x000000E7
+ "\x00e\x03\x00\x00\x00\x00\xe8" + // 0x00650300: 0x000000E8
+ "\x00e\x03\x01\x00\x00\x00\xe9" + // 0x00650301: 0x000000E9
+ "\x00e\x03\x02\x00\x00\x00\xea" + // 0x00650302: 0x000000EA
+ "\x00e\x03\b\x00\x00\x00\xeb" + // 0x00650308: 0x000000EB
+ "\x00i\x03\x00\x00\x00\x00\xec" + // 0x00690300: 0x000000EC
+ "\x00i\x03\x01\x00\x00\x00\xed" + // 0x00690301: 0x000000ED
+ "\x00i\x03\x02\x00\x00\x00\xee" + // 0x00690302: 0x000000EE
+ "\x00i\x03\b\x00\x00\x00\xef" + // 0x00690308: 0x000000EF
+ "\x00n\x03\x03\x00\x00\x00\xf1" + // 0x006E0303: 0x000000F1
+ "\x00o\x03\x00\x00\x00\x00\xf2" + // 0x006F0300: 0x000000F2
+ "\x00o\x03\x01\x00\x00\x00\xf3" + // 0x006F0301: 0x000000F3
+ "\x00o\x03\x02\x00\x00\x00\xf4" + // 0x006F0302: 0x000000F4
+ "\x00o\x03\x03\x00\x00\x00\xf5" + // 0x006F0303: 0x000000F5
+ "\x00o\x03\b\x00\x00\x00\xf6" + // 0x006F0308: 0x000000F6
+ "\x00u\x03\x00\x00\x00\x00\xf9" + // 0x00750300: 0x000000F9
+ "\x00u\x03\x01\x00\x00\x00\xfa" + // 0x00750301: 0x000000FA
+ "\x00u\x03\x02\x00\x00\x00\xfb" + // 0x00750302: 0x000000FB
+ "\x00u\x03\b\x00\x00\x00\xfc" + // 0x00750308: 0x000000FC
+ "\x00y\x03\x01\x00\x00\x00\xfd" + // 0x00790301: 0x000000FD
+ "\x00y\x03\b\x00\x00\x00\xff" + // 0x00790308: 0x000000FF
+ "\x00A\x03\x04\x00\x00\x01\x00" + // 0x00410304: 0x00000100
+ "\x00a\x03\x04\x00\x00\x01\x01" + // 0x00610304: 0x00000101
+ "\x00A\x03\x06\x00\x00\x01\x02" + // 0x00410306: 0x00000102
+ "\x00a\x03\x06\x00\x00\x01\x03" + // 0x00610306: 0x00000103
+ "\x00A\x03(\x00\x00\x01\x04" + // 0x00410328: 0x00000104
+ "\x00a\x03(\x00\x00\x01\x05" + // 0x00610328: 0x00000105
+ "\x00C\x03\x01\x00\x00\x01\x06" + // 0x00430301: 0x00000106
+ "\x00c\x03\x01\x00\x00\x01\a" + // 0x00630301: 0x00000107
+ "\x00C\x03\x02\x00\x00\x01\b" + // 0x00430302: 0x00000108
+ "\x00c\x03\x02\x00\x00\x01\t" + // 0x00630302: 0x00000109
+ "\x00C\x03\a\x00\x00\x01\n" + // 0x00430307: 0x0000010A
+ "\x00c\x03\a\x00\x00\x01\v" + // 0x00630307: 0x0000010B
+ "\x00C\x03\f\x00\x00\x01\f" + // 0x0043030C: 0x0000010C
+ "\x00c\x03\f\x00\x00\x01\r" + // 0x0063030C: 0x0000010D
+ "\x00D\x03\f\x00\x00\x01\x0e" + // 0x0044030C: 0x0000010E
+ "\x00d\x03\f\x00\x00\x01\x0f" + // 0x0064030C: 0x0000010F
+ "\x00E\x03\x04\x00\x00\x01\x12" + // 0x00450304: 0x00000112
+ "\x00e\x03\x04\x00\x00\x01\x13" + // 0x00650304: 0x00000113
+ "\x00E\x03\x06\x00\x00\x01\x14" + // 0x00450306: 0x00000114
+ "\x00e\x03\x06\x00\x00\x01\x15" + // 0x00650306: 0x00000115
+ "\x00E\x03\a\x00\x00\x01\x16" + // 0x00450307: 0x00000116
+ "\x00e\x03\a\x00\x00\x01\x17" + // 0x00650307: 0x00000117
+ "\x00E\x03(\x00\x00\x01\x18" + // 0x00450328: 0x00000118
+ "\x00e\x03(\x00\x00\x01\x19" + // 0x00650328: 0x00000119
+ "\x00E\x03\f\x00\x00\x01\x1a" + // 0x0045030C: 0x0000011A
+ "\x00e\x03\f\x00\x00\x01\x1b" + // 0x0065030C: 0x0000011B
+ "\x00G\x03\x02\x00\x00\x01\x1c" + // 0x00470302: 0x0000011C
+ "\x00g\x03\x02\x00\x00\x01\x1d" + // 0x00670302: 0x0000011D
+ "\x00G\x03\x06\x00\x00\x01\x1e" + // 0x00470306: 0x0000011E
+ "\x00g\x03\x06\x00\x00\x01\x1f" + // 0x00670306: 0x0000011F
+ "\x00G\x03\a\x00\x00\x01 " + // 0x00470307: 0x00000120
+ "\x00g\x03\a\x00\x00\x01!" + // 0x00670307: 0x00000121
+ "\x00G\x03'\x00\x00\x01\"" + // 0x00470327: 0x00000122
+ "\x00g\x03'\x00\x00\x01#" + // 0x00670327: 0x00000123
+ "\x00H\x03\x02\x00\x00\x01$" + // 0x00480302: 0x00000124
+ "\x00h\x03\x02\x00\x00\x01%" + // 0x00680302: 0x00000125
+ "\x00I\x03\x03\x00\x00\x01(" + // 0x00490303: 0x00000128
+ "\x00i\x03\x03\x00\x00\x01)" + // 0x00690303: 0x00000129
+ "\x00I\x03\x04\x00\x00\x01*" + // 0x00490304: 0x0000012A
+ "\x00i\x03\x04\x00\x00\x01+" + // 0x00690304: 0x0000012B
+ "\x00I\x03\x06\x00\x00\x01," + // 0x00490306: 0x0000012C
+ "\x00i\x03\x06\x00\x00\x01-" + // 0x00690306: 0x0000012D
+ "\x00I\x03(\x00\x00\x01." + // 0x00490328: 0x0000012E
+ "\x00i\x03(\x00\x00\x01/" + // 0x00690328: 0x0000012F
+ "\x00I\x03\a\x00\x00\x010" + // 0x00490307: 0x00000130
+ "\x00J\x03\x02\x00\x00\x014" + // 0x004A0302: 0x00000134
+ "\x00j\x03\x02\x00\x00\x015" + // 0x006A0302: 0x00000135
+ "\x00K\x03'\x00\x00\x016" + // 0x004B0327: 0x00000136
+ "\x00k\x03'\x00\x00\x017" + // 0x006B0327: 0x00000137
+ "\x00L\x03\x01\x00\x00\x019" + // 0x004C0301: 0x00000139
+ "\x00l\x03\x01\x00\x00\x01:" + // 0x006C0301: 0x0000013A
+ "\x00L\x03'\x00\x00\x01;" + // 0x004C0327: 0x0000013B
+ "\x00l\x03'\x00\x00\x01<" + // 0x006C0327: 0x0000013C
+ "\x00L\x03\f\x00\x00\x01=" + // 0x004C030C: 0x0000013D
+ "\x00l\x03\f\x00\x00\x01>" + // 0x006C030C: 0x0000013E
+ "\x00N\x03\x01\x00\x00\x01C" + // 0x004E0301: 0x00000143
+ "\x00n\x03\x01\x00\x00\x01D" + // 0x006E0301: 0x00000144
+ "\x00N\x03'\x00\x00\x01E" + // 0x004E0327: 0x00000145
+ "\x00n\x03'\x00\x00\x01F" + // 0x006E0327: 0x00000146
+ "\x00N\x03\f\x00\x00\x01G" + // 0x004E030C: 0x00000147
+ "\x00n\x03\f\x00\x00\x01H" + // 0x006E030C: 0x00000148
+ "\x00O\x03\x04\x00\x00\x01L" + // 0x004F0304: 0x0000014C
+ "\x00o\x03\x04\x00\x00\x01M" + // 0x006F0304: 0x0000014D
+ "\x00O\x03\x06\x00\x00\x01N" + // 0x004F0306: 0x0000014E
+ "\x00o\x03\x06\x00\x00\x01O" + // 0x006F0306: 0x0000014F
+ "\x00O\x03\v\x00\x00\x01P" + // 0x004F030B: 0x00000150
+ "\x00o\x03\v\x00\x00\x01Q" + // 0x006F030B: 0x00000151
+ "\x00R\x03\x01\x00\x00\x01T" + // 0x00520301: 0x00000154
+ "\x00r\x03\x01\x00\x00\x01U" + // 0x00720301: 0x00000155
+ "\x00R\x03'\x00\x00\x01V" + // 0x00520327: 0x00000156
+ "\x00r\x03'\x00\x00\x01W" + // 0x00720327: 0x00000157
+ "\x00R\x03\f\x00\x00\x01X" + // 0x0052030C: 0x00000158
+ "\x00r\x03\f\x00\x00\x01Y" + // 0x0072030C: 0x00000159
+ "\x00S\x03\x01\x00\x00\x01Z" + // 0x00530301: 0x0000015A
+ "\x00s\x03\x01\x00\x00\x01[" + // 0x00730301: 0x0000015B
+ "\x00S\x03\x02\x00\x00\x01\\" + // 0x00530302: 0x0000015C
+ "\x00s\x03\x02\x00\x00\x01]" + // 0x00730302: 0x0000015D
+ "\x00S\x03'\x00\x00\x01^" + // 0x00530327: 0x0000015E
+ "\x00s\x03'\x00\x00\x01_" + // 0x00730327: 0x0000015F
+ "\x00S\x03\f\x00\x00\x01`" + // 0x0053030C: 0x00000160
+ "\x00s\x03\f\x00\x00\x01a" + // 0x0073030C: 0x00000161
+ "\x00T\x03'\x00\x00\x01b" + // 0x00540327: 0x00000162
+ "\x00t\x03'\x00\x00\x01c" + // 0x00740327: 0x00000163
+ "\x00T\x03\f\x00\x00\x01d" + // 0x0054030C: 0x00000164
+ "\x00t\x03\f\x00\x00\x01e" + // 0x0074030C: 0x00000165
+ "\x00U\x03\x03\x00\x00\x01h" + // 0x00550303: 0x00000168
+ "\x00u\x03\x03\x00\x00\x01i" + // 0x00750303: 0x00000169
+ "\x00U\x03\x04\x00\x00\x01j" + // 0x00550304: 0x0000016A
+ "\x00u\x03\x04\x00\x00\x01k" + // 0x00750304: 0x0000016B
+ "\x00U\x03\x06\x00\x00\x01l" + // 0x00550306: 0x0000016C
+ "\x00u\x03\x06\x00\x00\x01m" + // 0x00750306: 0x0000016D
+ "\x00U\x03\n\x00\x00\x01n" + // 0x0055030A: 0x0000016E
+ "\x00u\x03\n\x00\x00\x01o" + // 0x0075030A: 0x0000016F
+ "\x00U\x03\v\x00\x00\x01p" + // 0x0055030B: 0x00000170
+ "\x00u\x03\v\x00\x00\x01q" + // 0x0075030B: 0x00000171
+ "\x00U\x03(\x00\x00\x01r" + // 0x00550328: 0x00000172
+ "\x00u\x03(\x00\x00\x01s" + // 0x00750328: 0x00000173
+ "\x00W\x03\x02\x00\x00\x01t" + // 0x00570302: 0x00000174
+ "\x00w\x03\x02\x00\x00\x01u" + // 0x00770302: 0x00000175
+ "\x00Y\x03\x02\x00\x00\x01v" + // 0x00590302: 0x00000176
+ "\x00y\x03\x02\x00\x00\x01w" + // 0x00790302: 0x00000177
+ "\x00Y\x03\b\x00\x00\x01x" + // 0x00590308: 0x00000178
+ "\x00Z\x03\x01\x00\x00\x01y" + // 0x005A0301: 0x00000179
+ "\x00z\x03\x01\x00\x00\x01z" + // 0x007A0301: 0x0000017A
+ "\x00Z\x03\a\x00\x00\x01{" + // 0x005A0307: 0x0000017B
+ "\x00z\x03\a\x00\x00\x01|" + // 0x007A0307: 0x0000017C
+ "\x00Z\x03\f\x00\x00\x01}" + // 0x005A030C: 0x0000017D
+ "\x00z\x03\f\x00\x00\x01~" + // 0x007A030C: 0x0000017E
+ "\x00O\x03\x1b\x00\x00\x01\xa0" + // 0x004F031B: 0x000001A0
+ "\x00o\x03\x1b\x00\x00\x01\xa1" + // 0x006F031B: 0x000001A1
+ "\x00U\x03\x1b\x00\x00\x01\xaf" + // 0x0055031B: 0x000001AF
+ "\x00u\x03\x1b\x00\x00\x01\xb0" + // 0x0075031B: 0x000001B0
+ "\x00A\x03\f\x00\x00\x01\xcd" + // 0x0041030C: 0x000001CD
+ "\x00a\x03\f\x00\x00\x01\xce" + // 0x0061030C: 0x000001CE
+ "\x00I\x03\f\x00\x00\x01\xcf" + // 0x0049030C: 0x000001CF
+ "\x00i\x03\f\x00\x00\x01\xd0" + // 0x0069030C: 0x000001D0
+ "\x00O\x03\f\x00\x00\x01\xd1" + // 0x004F030C: 0x000001D1
+ "\x00o\x03\f\x00\x00\x01\xd2" + // 0x006F030C: 0x000001D2
+ "\x00U\x03\f\x00\x00\x01\xd3" + // 0x0055030C: 0x000001D3
+ "\x00u\x03\f\x00\x00\x01\xd4" + // 0x0075030C: 0x000001D4
+ "\x00\xdc\x03\x04\x00\x00\x01\xd5" + // 0x00DC0304: 0x000001D5
+ "\x00\xfc\x03\x04\x00\x00\x01\xd6" + // 0x00FC0304: 0x000001D6
+ "\x00\xdc\x03\x01\x00\x00\x01\xd7" + // 0x00DC0301: 0x000001D7
+ "\x00\xfc\x03\x01\x00\x00\x01\xd8" + // 0x00FC0301: 0x000001D8
+ "\x00\xdc\x03\f\x00\x00\x01\xd9" + // 0x00DC030C: 0x000001D9
+ "\x00\xfc\x03\f\x00\x00\x01\xda" + // 0x00FC030C: 0x000001DA
+ "\x00\xdc\x03\x00\x00\x00\x01\xdb" + // 0x00DC0300: 0x000001DB
+ "\x00\xfc\x03\x00\x00\x00\x01\xdc" + // 0x00FC0300: 0x000001DC
+ "\x00\xc4\x03\x04\x00\x00\x01\xde" + // 0x00C40304: 0x000001DE
+ "\x00\xe4\x03\x04\x00\x00\x01\xdf" + // 0x00E40304: 0x000001DF
+ "\x02&\x03\x04\x00\x00\x01\xe0" + // 0x02260304: 0x000001E0
+ "\x02'\x03\x04\x00\x00\x01\xe1" + // 0x02270304: 0x000001E1
+ "\x00\xc6\x03\x04\x00\x00\x01\xe2" + // 0x00C60304: 0x000001E2
+ "\x00\xe6\x03\x04\x00\x00\x01\xe3" + // 0x00E60304: 0x000001E3
+ "\x00G\x03\f\x00\x00\x01\xe6" + // 0x0047030C: 0x000001E6
+ "\x00g\x03\f\x00\x00\x01\xe7" + // 0x0067030C: 0x000001E7
+ "\x00K\x03\f\x00\x00\x01\xe8" + // 0x004B030C: 0x000001E8
+ "\x00k\x03\f\x00\x00\x01\xe9" + // 0x006B030C: 0x000001E9
+ "\x00O\x03(\x00\x00\x01\xea" + // 0x004F0328: 0x000001EA
+ "\x00o\x03(\x00\x00\x01\xeb" + // 0x006F0328: 0x000001EB
+ "\x01\xea\x03\x04\x00\x00\x01\xec" + // 0x01EA0304: 0x000001EC
+ "\x01\xeb\x03\x04\x00\x00\x01\xed" + // 0x01EB0304: 0x000001ED
+ "\x01\xb7\x03\f\x00\x00\x01\xee" + // 0x01B7030C: 0x000001EE
+ "\x02\x92\x03\f\x00\x00\x01\xef" + // 0x0292030C: 0x000001EF
+ "\x00j\x03\f\x00\x00\x01\xf0" + // 0x006A030C: 0x000001F0
+ "\x00G\x03\x01\x00\x00\x01\xf4" + // 0x00470301: 0x000001F4
+ "\x00g\x03\x01\x00\x00\x01\xf5" + // 0x00670301: 0x000001F5
+ "\x00N\x03\x00\x00\x00\x01\xf8" + // 0x004E0300: 0x000001F8
+ "\x00n\x03\x00\x00\x00\x01\xf9" + // 0x006E0300: 0x000001F9
+ "\x00\xc5\x03\x01\x00\x00\x01\xfa" + // 0x00C50301: 0x000001FA
+ "\x00\xe5\x03\x01\x00\x00\x01\xfb" + // 0x00E50301: 0x000001FB
+ "\x00\xc6\x03\x01\x00\x00\x01\xfc" + // 0x00C60301: 0x000001FC
+ "\x00\xe6\x03\x01\x00\x00\x01\xfd" + // 0x00E60301: 0x000001FD
+ "\x00\xd8\x03\x01\x00\x00\x01\xfe" + // 0x00D80301: 0x000001FE
+ "\x00\xf8\x03\x01\x00\x00\x01\xff" + // 0x00F80301: 0x000001FF
+ "\x00A\x03\x0f\x00\x00\x02\x00" + // 0x0041030F: 0x00000200
+ "\x00a\x03\x0f\x00\x00\x02\x01" + // 0x0061030F: 0x00000201
+ "\x00A\x03\x11\x00\x00\x02\x02" + // 0x00410311: 0x00000202
+ "\x00a\x03\x11\x00\x00\x02\x03" + // 0x00610311: 0x00000203
+ "\x00E\x03\x0f\x00\x00\x02\x04" + // 0x0045030F: 0x00000204
+ "\x00e\x03\x0f\x00\x00\x02\x05" + // 0x0065030F: 0x00000205
+ "\x00E\x03\x11\x00\x00\x02\x06" + // 0x00450311: 0x00000206
+ "\x00e\x03\x11\x00\x00\x02\a" + // 0x00650311: 0x00000207
+ "\x00I\x03\x0f\x00\x00\x02\b" + // 0x0049030F: 0x00000208
+ "\x00i\x03\x0f\x00\x00\x02\t" + // 0x0069030F: 0x00000209
+ "\x00I\x03\x11\x00\x00\x02\n" + // 0x00490311: 0x0000020A
+ "\x00i\x03\x11\x00\x00\x02\v" + // 0x00690311: 0x0000020B
+ "\x00O\x03\x0f\x00\x00\x02\f" + // 0x004F030F: 0x0000020C
+ "\x00o\x03\x0f\x00\x00\x02\r" + // 0x006F030F: 0x0000020D
+ "\x00O\x03\x11\x00\x00\x02\x0e" + // 0x004F0311: 0x0000020E
+ "\x00o\x03\x11\x00\x00\x02\x0f" + // 0x006F0311: 0x0000020F
+ "\x00R\x03\x0f\x00\x00\x02\x10" + // 0x0052030F: 0x00000210
+ "\x00r\x03\x0f\x00\x00\x02\x11" + // 0x0072030F: 0x00000211
+ "\x00R\x03\x11\x00\x00\x02\x12" + // 0x00520311: 0x00000212
+ "\x00r\x03\x11\x00\x00\x02\x13" + // 0x00720311: 0x00000213
+ "\x00U\x03\x0f\x00\x00\x02\x14" + // 0x0055030F: 0x00000214
+ "\x00u\x03\x0f\x00\x00\x02\x15" + // 0x0075030F: 0x00000215
+ "\x00U\x03\x11\x00\x00\x02\x16" + // 0x00550311: 0x00000216
+ "\x00u\x03\x11\x00\x00\x02\x17" + // 0x00750311: 0x00000217
+ "\x00S\x03&\x00\x00\x02\x18" + // 0x00530326: 0x00000218
+ "\x00s\x03&\x00\x00\x02\x19" + // 0x00730326: 0x00000219
+ "\x00T\x03&\x00\x00\x02\x1a" + // 0x00540326: 0x0000021A
+ "\x00t\x03&\x00\x00\x02\x1b" + // 0x00740326: 0x0000021B
+ "\x00H\x03\f\x00\x00\x02\x1e" + // 0x0048030C: 0x0000021E
+ "\x00h\x03\f\x00\x00\x02\x1f" + // 0x0068030C: 0x0000021F
+ "\x00A\x03\a\x00\x00\x02&" + // 0x00410307: 0x00000226
+ "\x00a\x03\a\x00\x00\x02'" + // 0x00610307: 0x00000227
+ "\x00E\x03'\x00\x00\x02(" + // 0x00450327: 0x00000228
+ "\x00e\x03'\x00\x00\x02)" + // 0x00650327: 0x00000229
+ "\x00\xd6\x03\x04\x00\x00\x02*" + // 0x00D60304: 0x0000022A
+ "\x00\xf6\x03\x04\x00\x00\x02+" + // 0x00F60304: 0x0000022B
+ "\x00\xd5\x03\x04\x00\x00\x02," + // 0x00D50304: 0x0000022C
+ "\x00\xf5\x03\x04\x00\x00\x02-" + // 0x00F50304: 0x0000022D
+ "\x00O\x03\a\x00\x00\x02." + // 0x004F0307: 0x0000022E
+ "\x00o\x03\a\x00\x00\x02/" + // 0x006F0307: 0x0000022F
+ "\x02.\x03\x04\x00\x00\x020" + // 0x022E0304: 0x00000230
+ "\x02/\x03\x04\x00\x00\x021" + // 0x022F0304: 0x00000231
+ "\x00Y\x03\x04\x00\x00\x022" + // 0x00590304: 0x00000232
+ "\x00y\x03\x04\x00\x00\x023" + // 0x00790304: 0x00000233
+ "\x00\xa8\x03\x01\x00\x00\x03\x85" + // 0x00A80301: 0x00000385
+ "\x03\x91\x03\x01\x00\x00\x03\x86" + // 0x03910301: 0x00000386
+ "\x03\x95\x03\x01\x00\x00\x03\x88" + // 0x03950301: 0x00000388
+ "\x03\x97\x03\x01\x00\x00\x03\x89" + // 0x03970301: 0x00000389
+ "\x03\x99\x03\x01\x00\x00\x03\x8a" + // 0x03990301: 0x0000038A
+ "\x03\x9f\x03\x01\x00\x00\x03\x8c" + // 0x039F0301: 0x0000038C
+ "\x03\xa5\x03\x01\x00\x00\x03\x8e" + // 0x03A50301: 0x0000038E
+ "\x03\xa9\x03\x01\x00\x00\x03\x8f" + // 0x03A90301: 0x0000038F
+ "\x03\xca\x03\x01\x00\x00\x03\x90" + // 0x03CA0301: 0x00000390
+ "\x03\x99\x03\b\x00\x00\x03\xaa" + // 0x03990308: 0x000003AA
+ "\x03\xa5\x03\b\x00\x00\x03\xab" + // 0x03A50308: 0x000003AB
+ "\x03\xb1\x03\x01\x00\x00\x03\xac" + // 0x03B10301: 0x000003AC
+ "\x03\xb5\x03\x01\x00\x00\x03\xad" + // 0x03B50301: 0x000003AD
+ "\x03\xb7\x03\x01\x00\x00\x03\xae" + // 0x03B70301: 0x000003AE
+ "\x03\xb9\x03\x01\x00\x00\x03\xaf" + // 0x03B90301: 0x000003AF
+ "\x03\xcb\x03\x01\x00\x00\x03\xb0" + // 0x03CB0301: 0x000003B0
+ "\x03\xb9\x03\b\x00\x00\x03\xca" + // 0x03B90308: 0x000003CA
+ "\x03\xc5\x03\b\x00\x00\x03\xcb" + // 0x03C50308: 0x000003CB
+ "\x03\xbf\x03\x01\x00\x00\x03\xcc" + // 0x03BF0301: 0x000003CC
+ "\x03\xc5\x03\x01\x00\x00\x03\xcd" + // 0x03C50301: 0x000003CD
+ "\x03\xc9\x03\x01\x00\x00\x03\xce" + // 0x03C90301: 0x000003CE
+ "\x03\xd2\x03\x01\x00\x00\x03\xd3" + // 0x03D20301: 0x000003D3
+ "\x03\xd2\x03\b\x00\x00\x03\xd4" + // 0x03D20308: 0x000003D4
+ "\x04\x15\x03\x00\x00\x00\x04\x00" + // 0x04150300: 0x00000400
+ "\x04\x15\x03\b\x00\x00\x04\x01" + // 0x04150308: 0x00000401
+ "\x04\x13\x03\x01\x00\x00\x04\x03" + // 0x04130301: 0x00000403
+ "\x04\x06\x03\b\x00\x00\x04\a" + // 0x04060308: 0x00000407
+ "\x04\x1a\x03\x01\x00\x00\x04\f" + // 0x041A0301: 0x0000040C
+ "\x04\x18\x03\x00\x00\x00\x04\r" + // 0x04180300: 0x0000040D
+ "\x04#\x03\x06\x00\x00\x04\x0e" + // 0x04230306: 0x0000040E
+ "\x04\x18\x03\x06\x00\x00\x04\x19" + // 0x04180306: 0x00000419
+ "\x048\x03\x06\x00\x00\x049" + // 0x04380306: 0x00000439
+ "\x045\x03\x00\x00\x00\x04P" + // 0x04350300: 0x00000450
+ "\x045\x03\b\x00\x00\x04Q" + // 0x04350308: 0x00000451
+ "\x043\x03\x01\x00\x00\x04S" + // 0x04330301: 0x00000453
+ "\x04V\x03\b\x00\x00\x04W" + // 0x04560308: 0x00000457
+ "\x04:\x03\x01\x00\x00\x04\\" + // 0x043A0301: 0x0000045C
+ "\x048\x03\x00\x00\x00\x04]" + // 0x04380300: 0x0000045D
+ "\x04C\x03\x06\x00\x00\x04^" + // 0x04430306: 0x0000045E
+ "\x04t\x03\x0f\x00\x00\x04v" + // 0x0474030F: 0x00000476
+ "\x04u\x03\x0f\x00\x00\x04w" + // 0x0475030F: 0x00000477
+ "\x04\x16\x03\x06\x00\x00\x04\xc1" + // 0x04160306: 0x000004C1
+ "\x046\x03\x06\x00\x00\x04\xc2" + // 0x04360306: 0x000004C2
+ "\x04\x10\x03\x06\x00\x00\x04\xd0" + // 0x04100306: 0x000004D0
+ "\x040\x03\x06\x00\x00\x04\xd1" + // 0x04300306: 0x000004D1
+ "\x04\x10\x03\b\x00\x00\x04\xd2" + // 0x04100308: 0x000004D2
+ "\x040\x03\b\x00\x00\x04\xd3" + // 0x04300308: 0x000004D3
+ "\x04\x15\x03\x06\x00\x00\x04\xd6" + // 0x04150306: 0x000004D6
+ "\x045\x03\x06\x00\x00\x04\xd7" + // 0x04350306: 0x000004D7
+ "\x04\xd8\x03\b\x00\x00\x04\xda" + // 0x04D80308: 0x000004DA
+ "\x04\xd9\x03\b\x00\x00\x04\xdb" + // 0x04D90308: 0x000004DB
+ "\x04\x16\x03\b\x00\x00\x04\xdc" + // 0x04160308: 0x000004DC
+ "\x046\x03\b\x00\x00\x04\xdd" + // 0x04360308: 0x000004DD
+ "\x04\x17\x03\b\x00\x00\x04\xde" + // 0x04170308: 0x000004DE
+ "\x047\x03\b\x00\x00\x04\xdf" + // 0x04370308: 0x000004DF
+ "\x04\x18\x03\x04\x00\x00\x04\xe2" + // 0x04180304: 0x000004E2
+ "\x048\x03\x04\x00\x00\x04\xe3" + // 0x04380304: 0x000004E3
+ "\x04\x18\x03\b\x00\x00\x04\xe4" + // 0x04180308: 0x000004E4
+ "\x048\x03\b\x00\x00\x04\xe5" + // 0x04380308: 0x000004E5
+ "\x04\x1e\x03\b\x00\x00\x04\xe6" + // 0x041E0308: 0x000004E6
+ "\x04>\x03\b\x00\x00\x04\xe7" + // 0x043E0308: 0x000004E7
+ "\x04\xe8\x03\b\x00\x00\x04\xea" + // 0x04E80308: 0x000004EA
+ "\x04\xe9\x03\b\x00\x00\x04\xeb" + // 0x04E90308: 0x000004EB
+ "\x04-\x03\b\x00\x00\x04\xec" + // 0x042D0308: 0x000004EC
+ "\x04M\x03\b\x00\x00\x04\xed" + // 0x044D0308: 0x000004ED
+ "\x04#\x03\x04\x00\x00\x04\xee" + // 0x04230304: 0x000004EE
+ "\x04C\x03\x04\x00\x00\x04\xef" + // 0x04430304: 0x000004EF
+ "\x04#\x03\b\x00\x00\x04\xf0" + // 0x04230308: 0x000004F0
+ "\x04C\x03\b\x00\x00\x04\xf1" + // 0x04430308: 0x000004F1
+ "\x04#\x03\v\x00\x00\x04\xf2" + // 0x0423030B: 0x000004F2
+ "\x04C\x03\v\x00\x00\x04\xf3" + // 0x0443030B: 0x000004F3
+ "\x04'\x03\b\x00\x00\x04\xf4" + // 0x04270308: 0x000004F4
+ "\x04G\x03\b\x00\x00\x04\xf5" + // 0x04470308: 0x000004F5
+ "\x04+\x03\b\x00\x00\x04\xf8" + // 0x042B0308: 0x000004F8
+ "\x04K\x03\b\x00\x00\x04\xf9" + // 0x044B0308: 0x000004F9
+ "\x06'\x06S\x00\x00\x06\"" + // 0x06270653: 0x00000622
+ "\x06'\x06T\x00\x00\x06#" + // 0x06270654: 0x00000623
+ "\x06H\x06T\x00\x00\x06$" + // 0x06480654: 0x00000624
+ "\x06'\x06U\x00\x00\x06%" + // 0x06270655: 0x00000625
+ "\x06J\x06T\x00\x00\x06&" + // 0x064A0654: 0x00000626
+ "\x06\xd5\x06T\x00\x00\x06\xc0" + // 0x06D50654: 0x000006C0
+ "\x06\xc1\x06T\x00\x00\x06\xc2" + // 0x06C10654: 0x000006C2
+ "\x06\xd2\x06T\x00\x00\x06\xd3" + // 0x06D20654: 0x000006D3
+ "\t(\t<\x00\x00\t)" + // 0x0928093C: 0x00000929
+ "\t0\t<\x00\x00\t1" + // 0x0930093C: 0x00000931
+ "\t3\t<\x00\x00\t4" + // 0x0933093C: 0x00000934
+ "\t\xc7\t\xbe\x00\x00\t\xcb" + // 0x09C709BE: 0x000009CB
+ "\t\xc7\t\xd7\x00\x00\t\xcc" + // 0x09C709D7: 0x000009CC
+ "\vG\vV\x00\x00\vH" + // 0x0B470B56: 0x00000B48
+ "\vG\v>\x00\x00\vK" + // 0x0B470B3E: 0x00000B4B
+ "\vG\vW\x00\x00\vL" + // 0x0B470B57: 0x00000B4C
+ "\v\x92\v\xd7\x00\x00\v\x94" + // 0x0B920BD7: 0x00000B94
+ "\v\xc6\v\xbe\x00\x00\v\xca" + // 0x0BC60BBE: 0x00000BCA
+ "\v\xc7\v\xbe\x00\x00\v\xcb" + // 0x0BC70BBE: 0x00000BCB
+ "\v\xc6\v\xd7\x00\x00\v\xcc" + // 0x0BC60BD7: 0x00000BCC
+ "\fF\fV\x00\x00\fH" + // 0x0C460C56: 0x00000C48
+ "\f\xbf\f\xd5\x00\x00\f\xc0" + // 0x0CBF0CD5: 0x00000CC0
+ "\f\xc6\f\xd5\x00\x00\f\xc7" + // 0x0CC60CD5: 0x00000CC7
+ "\f\xc6\f\xd6\x00\x00\f\xc8" + // 0x0CC60CD6: 0x00000CC8
+ "\f\xc6\f\xc2\x00\x00\f\xca" + // 0x0CC60CC2: 0x00000CCA
+ "\f\xca\f\xd5\x00\x00\f\xcb" + // 0x0CCA0CD5: 0x00000CCB
+ "\rF\r>\x00\x00\rJ" + // 0x0D460D3E: 0x00000D4A
+ "\rG\r>\x00\x00\rK" + // 0x0D470D3E: 0x00000D4B
+ "\rF\rW\x00\x00\rL" + // 0x0D460D57: 0x00000D4C
+ "\r\xd9\r\xca\x00\x00\r\xda" + // 0x0DD90DCA: 0x00000DDA
+ "\r\xd9\r\xcf\x00\x00\r\xdc" + // 0x0DD90DCF: 0x00000DDC
+ "\r\xdc\r\xca\x00\x00\r\xdd" + // 0x0DDC0DCA: 0x00000DDD
+ "\r\xd9\r\xdf\x00\x00\r\xde" + // 0x0DD90DDF: 0x00000DDE
+ "\x10%\x10.\x00\x00\x10&" + // 0x1025102E: 0x00001026
+ "\x1b\x05\x1b5\x00\x00\x1b\x06" + // 0x1B051B35: 0x00001B06
+ "\x1b\a\x1b5\x00\x00\x1b\b" + // 0x1B071B35: 0x00001B08
+ "\x1b\t\x1b5\x00\x00\x1b\n" + // 0x1B091B35: 0x00001B0A
+ "\x1b\v\x1b5\x00\x00\x1b\f" + // 0x1B0B1B35: 0x00001B0C
+ "\x1b\r\x1b5\x00\x00\x1b\x0e" + // 0x1B0D1B35: 0x00001B0E
+ "\x1b\x11\x1b5\x00\x00\x1b\x12" + // 0x1B111B35: 0x00001B12
+ "\x1b:\x1b5\x00\x00\x1b;" + // 0x1B3A1B35: 0x00001B3B
+ "\x1b<\x1b5\x00\x00\x1b=" + // 0x1B3C1B35: 0x00001B3D
+ "\x1b>\x1b5\x00\x00\x1b@" + // 0x1B3E1B35: 0x00001B40
+ "\x1b?\x1b5\x00\x00\x1bA" + // 0x1B3F1B35: 0x00001B41
+ "\x1bB\x1b5\x00\x00\x1bC" + // 0x1B421B35: 0x00001B43
+ "\x00A\x03%\x00\x00\x1e\x00" + // 0x00410325: 0x00001E00
+ "\x00a\x03%\x00\x00\x1e\x01" + // 0x00610325: 0x00001E01
+ "\x00B\x03\a\x00\x00\x1e\x02" + // 0x00420307: 0x00001E02
+ "\x00b\x03\a\x00\x00\x1e\x03" + // 0x00620307: 0x00001E03
+ "\x00B\x03#\x00\x00\x1e\x04" + // 0x00420323: 0x00001E04
+ "\x00b\x03#\x00\x00\x1e\x05" + // 0x00620323: 0x00001E05
+ "\x00B\x031\x00\x00\x1e\x06" + // 0x00420331: 0x00001E06
+ "\x00b\x031\x00\x00\x1e\a" + // 0x00620331: 0x00001E07
+ "\x00\xc7\x03\x01\x00\x00\x1e\b" + // 0x00C70301: 0x00001E08
+ "\x00\xe7\x03\x01\x00\x00\x1e\t" + // 0x00E70301: 0x00001E09
+ "\x00D\x03\a\x00\x00\x1e\n" + // 0x00440307: 0x00001E0A
+ "\x00d\x03\a\x00\x00\x1e\v" + // 0x00640307: 0x00001E0B
+ "\x00D\x03#\x00\x00\x1e\f" + // 0x00440323: 0x00001E0C
+ "\x00d\x03#\x00\x00\x1e\r" + // 0x00640323: 0x00001E0D
+ "\x00D\x031\x00\x00\x1e\x0e" + // 0x00440331: 0x00001E0E
+ "\x00d\x031\x00\x00\x1e\x0f" + // 0x00640331: 0x00001E0F
+ "\x00D\x03'\x00\x00\x1e\x10" + // 0x00440327: 0x00001E10
+ "\x00d\x03'\x00\x00\x1e\x11" + // 0x00640327: 0x00001E11
+ "\x00D\x03-\x00\x00\x1e\x12" + // 0x0044032D: 0x00001E12
+ "\x00d\x03-\x00\x00\x1e\x13" + // 0x0064032D: 0x00001E13
+ "\x01\x12\x03\x00\x00\x00\x1e\x14" + // 0x01120300: 0x00001E14
+ "\x01\x13\x03\x00\x00\x00\x1e\x15" + // 0x01130300: 0x00001E15
+ "\x01\x12\x03\x01\x00\x00\x1e\x16" + // 0x01120301: 0x00001E16
+ "\x01\x13\x03\x01\x00\x00\x1e\x17" + // 0x01130301: 0x00001E17
+ "\x00E\x03-\x00\x00\x1e\x18" + // 0x0045032D: 0x00001E18
+ "\x00e\x03-\x00\x00\x1e\x19" + // 0x0065032D: 0x00001E19
+ "\x00E\x030\x00\x00\x1e\x1a" + // 0x00450330: 0x00001E1A
+ "\x00e\x030\x00\x00\x1e\x1b" + // 0x00650330: 0x00001E1B
+ "\x02(\x03\x06\x00\x00\x1e\x1c" + // 0x02280306: 0x00001E1C
+ "\x02)\x03\x06\x00\x00\x1e\x1d" + // 0x02290306: 0x00001E1D
+ "\x00F\x03\a\x00\x00\x1e\x1e" + // 0x00460307: 0x00001E1E
+ "\x00f\x03\a\x00\x00\x1e\x1f" + // 0x00660307: 0x00001E1F
+ "\x00G\x03\x04\x00\x00\x1e " + // 0x00470304: 0x00001E20
+ "\x00g\x03\x04\x00\x00\x1e!" + // 0x00670304: 0x00001E21
+ "\x00H\x03\a\x00\x00\x1e\"" + // 0x00480307: 0x00001E22
+ "\x00h\x03\a\x00\x00\x1e#" + // 0x00680307: 0x00001E23
+ "\x00H\x03#\x00\x00\x1e$" + // 0x00480323: 0x00001E24
+ "\x00h\x03#\x00\x00\x1e%" + // 0x00680323: 0x00001E25
+ "\x00H\x03\b\x00\x00\x1e&" + // 0x00480308: 0x00001E26
+ "\x00h\x03\b\x00\x00\x1e'" + // 0x00680308: 0x00001E27
+ "\x00H\x03'\x00\x00\x1e(" + // 0x00480327: 0x00001E28
+ "\x00h\x03'\x00\x00\x1e)" + // 0x00680327: 0x00001E29
+ "\x00H\x03.\x00\x00\x1e*" + // 0x0048032E: 0x00001E2A
+ "\x00h\x03.\x00\x00\x1e+" + // 0x0068032E: 0x00001E2B
+ "\x00I\x030\x00\x00\x1e," + // 0x00490330: 0x00001E2C
+ "\x00i\x030\x00\x00\x1e-" + // 0x00690330: 0x00001E2D
+ "\x00\xcf\x03\x01\x00\x00\x1e." + // 0x00CF0301: 0x00001E2E
+ "\x00\xef\x03\x01\x00\x00\x1e/" + // 0x00EF0301: 0x00001E2F
+ "\x00K\x03\x01\x00\x00\x1e0" + // 0x004B0301: 0x00001E30
+ "\x00k\x03\x01\x00\x00\x1e1" + // 0x006B0301: 0x00001E31
+ "\x00K\x03#\x00\x00\x1e2" + // 0x004B0323: 0x00001E32
+ "\x00k\x03#\x00\x00\x1e3" + // 0x006B0323: 0x00001E33
+ "\x00K\x031\x00\x00\x1e4" + // 0x004B0331: 0x00001E34
+ "\x00k\x031\x00\x00\x1e5" + // 0x006B0331: 0x00001E35
+ "\x00L\x03#\x00\x00\x1e6" + // 0x004C0323: 0x00001E36
+ "\x00l\x03#\x00\x00\x1e7" + // 0x006C0323: 0x00001E37
+ "\x1e6\x03\x04\x00\x00\x1e8" + // 0x1E360304: 0x00001E38
+ "\x1e7\x03\x04\x00\x00\x1e9" + // 0x1E370304: 0x00001E39
+ "\x00L\x031\x00\x00\x1e:" + // 0x004C0331: 0x00001E3A
+ "\x00l\x031\x00\x00\x1e;" + // 0x006C0331: 0x00001E3B
+ "\x00L\x03-\x00\x00\x1e<" + // 0x004C032D: 0x00001E3C
+ "\x00l\x03-\x00\x00\x1e=" + // 0x006C032D: 0x00001E3D
+ "\x00M\x03\x01\x00\x00\x1e>" + // 0x004D0301: 0x00001E3E
+ "\x00m\x03\x01\x00\x00\x1e?" + // 0x006D0301: 0x00001E3F
+ "\x00M\x03\a\x00\x00\x1e@" + // 0x004D0307: 0x00001E40
+ "\x00m\x03\a\x00\x00\x1eA" + // 0x006D0307: 0x00001E41
+ "\x00M\x03#\x00\x00\x1eB" + // 0x004D0323: 0x00001E42
+ "\x00m\x03#\x00\x00\x1eC" + // 0x006D0323: 0x00001E43
+ "\x00N\x03\a\x00\x00\x1eD" + // 0x004E0307: 0x00001E44
+ "\x00n\x03\a\x00\x00\x1eE" + // 0x006E0307: 0x00001E45
+ "\x00N\x03#\x00\x00\x1eF" + // 0x004E0323: 0x00001E46
+ "\x00n\x03#\x00\x00\x1eG" + // 0x006E0323: 0x00001E47
+ "\x00N\x031\x00\x00\x1eH" + // 0x004E0331: 0x00001E48
+ "\x00n\x031\x00\x00\x1eI" + // 0x006E0331: 0x00001E49
+ "\x00N\x03-\x00\x00\x1eJ" + // 0x004E032D: 0x00001E4A
+ "\x00n\x03-\x00\x00\x1eK" + // 0x006E032D: 0x00001E4B
+ "\x00\xd5\x03\x01\x00\x00\x1eL" + // 0x00D50301: 0x00001E4C
+ "\x00\xf5\x03\x01\x00\x00\x1eM" + // 0x00F50301: 0x00001E4D
+ "\x00\xd5\x03\b\x00\x00\x1eN" + // 0x00D50308: 0x00001E4E
+ "\x00\xf5\x03\b\x00\x00\x1eO" + // 0x00F50308: 0x00001E4F
+ "\x01L\x03\x00\x00\x00\x1eP" + // 0x014C0300: 0x00001E50
+ "\x01M\x03\x00\x00\x00\x1eQ" + // 0x014D0300: 0x00001E51
+ "\x01L\x03\x01\x00\x00\x1eR" + // 0x014C0301: 0x00001E52
+ "\x01M\x03\x01\x00\x00\x1eS" + // 0x014D0301: 0x00001E53
+ "\x00P\x03\x01\x00\x00\x1eT" + // 0x00500301: 0x00001E54
+ "\x00p\x03\x01\x00\x00\x1eU" + // 0x00700301: 0x00001E55
+ "\x00P\x03\a\x00\x00\x1eV" + // 0x00500307: 0x00001E56
+ "\x00p\x03\a\x00\x00\x1eW" + // 0x00700307: 0x00001E57
+ "\x00R\x03\a\x00\x00\x1eX" + // 0x00520307: 0x00001E58
+ "\x00r\x03\a\x00\x00\x1eY" + // 0x00720307: 0x00001E59
+ "\x00R\x03#\x00\x00\x1eZ" + // 0x00520323: 0x00001E5A
+ "\x00r\x03#\x00\x00\x1e[" + // 0x00720323: 0x00001E5B
+ "\x1eZ\x03\x04\x00\x00\x1e\\" + // 0x1E5A0304: 0x00001E5C
+ "\x1e[\x03\x04\x00\x00\x1e]" + // 0x1E5B0304: 0x00001E5D
+ "\x00R\x031\x00\x00\x1e^" + // 0x00520331: 0x00001E5E
+ "\x00r\x031\x00\x00\x1e_" + // 0x00720331: 0x00001E5F
+ "\x00S\x03\a\x00\x00\x1e`" + // 0x00530307: 0x00001E60
+ "\x00s\x03\a\x00\x00\x1ea" + // 0x00730307: 0x00001E61
+ "\x00S\x03#\x00\x00\x1eb" + // 0x00530323: 0x00001E62
+ "\x00s\x03#\x00\x00\x1ec" + // 0x00730323: 0x00001E63
+ "\x01Z\x03\a\x00\x00\x1ed" + // 0x015A0307: 0x00001E64
+ "\x01[\x03\a\x00\x00\x1ee" + // 0x015B0307: 0x00001E65
+ "\x01`\x03\a\x00\x00\x1ef" + // 0x01600307: 0x00001E66
+ "\x01a\x03\a\x00\x00\x1eg" + // 0x01610307: 0x00001E67
+ "\x1eb\x03\a\x00\x00\x1eh" + // 0x1E620307: 0x00001E68
+ "\x1ec\x03\a\x00\x00\x1ei" + // 0x1E630307: 0x00001E69
+ "\x00T\x03\a\x00\x00\x1ej" + // 0x00540307: 0x00001E6A
+ "\x00t\x03\a\x00\x00\x1ek" + // 0x00740307: 0x00001E6B
+ "\x00T\x03#\x00\x00\x1el" + // 0x00540323: 0x00001E6C
+ "\x00t\x03#\x00\x00\x1em" + // 0x00740323: 0x00001E6D
+ "\x00T\x031\x00\x00\x1en" + // 0x00540331: 0x00001E6E
+ "\x00t\x031\x00\x00\x1eo" + // 0x00740331: 0x00001E6F
+ "\x00T\x03-\x00\x00\x1ep" + // 0x0054032D: 0x00001E70
+ "\x00t\x03-\x00\x00\x1eq" + // 0x0074032D: 0x00001E71
+ "\x00U\x03$\x00\x00\x1er" + // 0x00550324: 0x00001E72
+ "\x00u\x03$\x00\x00\x1es" + // 0x00750324: 0x00001E73
+ "\x00U\x030\x00\x00\x1et" + // 0x00550330: 0x00001E74
+ "\x00u\x030\x00\x00\x1eu" + // 0x00750330: 0x00001E75
+ "\x00U\x03-\x00\x00\x1ev" + // 0x0055032D: 0x00001E76
+ "\x00u\x03-\x00\x00\x1ew" + // 0x0075032D: 0x00001E77
+ "\x01h\x03\x01\x00\x00\x1ex" + // 0x01680301: 0x00001E78
+ "\x01i\x03\x01\x00\x00\x1ey" + // 0x01690301: 0x00001E79
+ "\x01j\x03\b\x00\x00\x1ez" + // 0x016A0308: 0x00001E7A
+ "\x01k\x03\b\x00\x00\x1e{" + // 0x016B0308: 0x00001E7B
+ "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C
+ "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D
+ "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E
+ "\x00v\x03#\x00\x00\x1e\x7f" + // 0x00760323: 0x00001E7F
+ "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80
+ "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81
+ "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82
+ "\x00w\x03\x01\x00\x00\x1e\x83" + // 0x00770301: 0x00001E83
+ "\x00W\x03\b\x00\x00\x1e\x84" + // 0x00570308: 0x00001E84
+ "\x00w\x03\b\x00\x00\x1e\x85" + // 0x00770308: 0x00001E85
+ "\x00W\x03\a\x00\x00\x1e\x86" + // 0x00570307: 0x00001E86
+ "\x00w\x03\a\x00\x00\x1e\x87" + // 0x00770307: 0x00001E87
+ "\x00W\x03#\x00\x00\x1e\x88" + // 0x00570323: 0x00001E88
+ "\x00w\x03#\x00\x00\x1e\x89" + // 0x00770323: 0x00001E89
+ "\x00X\x03\a\x00\x00\x1e\x8a" + // 0x00580307: 0x00001E8A
+ "\x00x\x03\a\x00\x00\x1e\x8b" + // 0x00780307: 0x00001E8B
+ "\x00X\x03\b\x00\x00\x1e\x8c" + // 0x00580308: 0x00001E8C
+ "\x00x\x03\b\x00\x00\x1e\x8d" + // 0x00780308: 0x00001E8D
+ "\x00Y\x03\a\x00\x00\x1e\x8e" + // 0x00590307: 0x00001E8E
+ "\x00y\x03\a\x00\x00\x1e\x8f" + // 0x00790307: 0x00001E8F
+ "\x00Z\x03\x02\x00\x00\x1e\x90" + // 0x005A0302: 0x00001E90
+ "\x00z\x03\x02\x00\x00\x1e\x91" + // 0x007A0302: 0x00001E91
+ "\x00Z\x03#\x00\x00\x1e\x92" + // 0x005A0323: 0x00001E92
+ "\x00z\x03#\x00\x00\x1e\x93" + // 0x007A0323: 0x00001E93
+ "\x00Z\x031\x00\x00\x1e\x94" + // 0x005A0331: 0x00001E94
+ "\x00z\x031\x00\x00\x1e\x95" + // 0x007A0331: 0x00001E95
+ "\x00h\x031\x00\x00\x1e\x96" + // 0x00680331: 0x00001E96
+ "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97
+ "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98
+ "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99
+ "\x01\x7f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B
+ "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0
+ "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1
+ "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2
+ "\x00a\x03\t\x00\x00\x1e\xa3" + // 0x00610309: 0x00001EA3
+ "\x00\xc2\x03\x01\x00\x00\x1e\xa4" + // 0x00C20301: 0x00001EA4
+ "\x00\xe2\x03\x01\x00\x00\x1e\xa5" + // 0x00E20301: 0x00001EA5
+ "\x00\xc2\x03\x00\x00\x00\x1e\xa6" + // 0x00C20300: 0x00001EA6
+ "\x00\xe2\x03\x00\x00\x00\x1e\xa7" + // 0x00E20300: 0x00001EA7
+ "\x00\xc2\x03\t\x00\x00\x1e\xa8" + // 0x00C20309: 0x00001EA8
+ "\x00\xe2\x03\t\x00\x00\x1e\xa9" + // 0x00E20309: 0x00001EA9
+ "\x00\xc2\x03\x03\x00\x00\x1e\xaa" + // 0x00C20303: 0x00001EAA
+ "\x00\xe2\x03\x03\x00\x00\x1e\xab" + // 0x00E20303: 0x00001EAB
+ "\x1e\xa0\x03\x02\x00\x00\x1e\xac" + // 0x1EA00302: 0x00001EAC
+ "\x1e\xa1\x03\x02\x00\x00\x1e\xad" + // 0x1EA10302: 0x00001EAD
+ "\x01\x02\x03\x01\x00\x00\x1e\xae" + // 0x01020301: 0x00001EAE
+ "\x01\x03\x03\x01\x00\x00\x1e\xaf" + // 0x01030301: 0x00001EAF
+ "\x01\x02\x03\x00\x00\x00\x1e\xb0" + // 0x01020300: 0x00001EB0
+ "\x01\x03\x03\x00\x00\x00\x1e\xb1" + // 0x01030300: 0x00001EB1
+ "\x01\x02\x03\t\x00\x00\x1e\xb2" + // 0x01020309: 0x00001EB2
+ "\x01\x03\x03\t\x00\x00\x1e\xb3" + // 0x01030309: 0x00001EB3
+ "\x01\x02\x03\x03\x00\x00\x1e\xb4" + // 0x01020303: 0x00001EB4
+ "\x01\x03\x03\x03\x00\x00\x1e\xb5" + // 0x01030303: 0x00001EB5
+ "\x1e\xa0\x03\x06\x00\x00\x1e\xb6" + // 0x1EA00306: 0x00001EB6
+ "\x1e\xa1\x03\x06\x00\x00\x1e\xb7" + // 0x1EA10306: 0x00001EB7
+ "\x00E\x03#\x00\x00\x1e\xb8" + // 0x00450323: 0x00001EB8
+ "\x00e\x03#\x00\x00\x1e\xb9" + // 0x00650323: 0x00001EB9
+ "\x00E\x03\t\x00\x00\x1e\xba" + // 0x00450309: 0x00001EBA
+ "\x00e\x03\t\x00\x00\x1e\xbb" + // 0x00650309: 0x00001EBB
+ "\x00E\x03\x03\x00\x00\x1e\xbc" + // 0x00450303: 0x00001EBC
+ "\x00e\x03\x03\x00\x00\x1e\xbd" + // 0x00650303: 0x00001EBD
+ "\x00\xca\x03\x01\x00\x00\x1e\xbe" + // 0x00CA0301: 0x00001EBE
+ "\x00\xea\x03\x01\x00\x00\x1e\xbf" + // 0x00EA0301: 0x00001EBF
+ "\x00\xca\x03\x00\x00\x00\x1e\xc0" + // 0x00CA0300: 0x00001EC0
+ "\x00\xea\x03\x00\x00\x00\x1e\xc1" + // 0x00EA0300: 0x00001EC1
+ "\x00\xca\x03\t\x00\x00\x1e\xc2" + // 0x00CA0309: 0x00001EC2
+ "\x00\xea\x03\t\x00\x00\x1e\xc3" + // 0x00EA0309: 0x00001EC3
+ "\x00\xca\x03\x03\x00\x00\x1e\xc4" + // 0x00CA0303: 0x00001EC4
+ "\x00\xea\x03\x03\x00\x00\x1e\xc5" + // 0x00EA0303: 0x00001EC5
+ "\x1e\xb8\x03\x02\x00\x00\x1e\xc6" + // 0x1EB80302: 0x00001EC6
+ "\x1e\xb9\x03\x02\x00\x00\x1e\xc7" + // 0x1EB90302: 0x00001EC7
+ "\x00I\x03\t\x00\x00\x1e\xc8" + // 0x00490309: 0x00001EC8
+ "\x00i\x03\t\x00\x00\x1e\xc9" + // 0x00690309: 0x00001EC9
+ "\x00I\x03#\x00\x00\x1e\xca" + // 0x00490323: 0x00001ECA
+ "\x00i\x03#\x00\x00\x1e\xcb" + // 0x00690323: 0x00001ECB
+ "\x00O\x03#\x00\x00\x1e\xcc" + // 0x004F0323: 0x00001ECC
+ "\x00o\x03#\x00\x00\x1e\xcd" + // 0x006F0323: 0x00001ECD
+ "\x00O\x03\t\x00\x00\x1e\xce" + // 0x004F0309: 0x00001ECE
+ "\x00o\x03\t\x00\x00\x1e\xcf" + // 0x006F0309: 0x00001ECF
+ "\x00\xd4\x03\x01\x00\x00\x1e\xd0" + // 0x00D40301: 0x00001ED0
+ "\x00\xf4\x03\x01\x00\x00\x1e\xd1" + // 0x00F40301: 0x00001ED1
+ "\x00\xd4\x03\x00\x00\x00\x1e\xd2" + // 0x00D40300: 0x00001ED2
+ "\x00\xf4\x03\x00\x00\x00\x1e\xd3" + // 0x00F40300: 0x00001ED3
+ "\x00\xd4\x03\t\x00\x00\x1e\xd4" + // 0x00D40309: 0x00001ED4
+ "\x00\xf4\x03\t\x00\x00\x1e\xd5" + // 0x00F40309: 0x00001ED5
+ "\x00\xd4\x03\x03\x00\x00\x1e\xd6" + // 0x00D40303: 0x00001ED6
+ "\x00\xf4\x03\x03\x00\x00\x1e\xd7" + // 0x00F40303: 0x00001ED7
+ "\x1e\xcc\x03\x02\x00\x00\x1e\xd8" + // 0x1ECC0302: 0x00001ED8
+ "\x1e\xcd\x03\x02\x00\x00\x1e\xd9" + // 0x1ECD0302: 0x00001ED9
+ "\x01\xa0\x03\x01\x00\x00\x1e\xda" + // 0x01A00301: 0x00001EDA
+ "\x01\xa1\x03\x01\x00\x00\x1e\xdb" + // 0x01A10301: 0x00001EDB
+ "\x01\xa0\x03\x00\x00\x00\x1e\xdc" + // 0x01A00300: 0x00001EDC
+ "\x01\xa1\x03\x00\x00\x00\x1e\xdd" + // 0x01A10300: 0x00001EDD
+ "\x01\xa0\x03\t\x00\x00\x1e\xde" + // 0x01A00309: 0x00001EDE
+ "\x01\xa1\x03\t\x00\x00\x1e\xdf" + // 0x01A10309: 0x00001EDF
+ "\x01\xa0\x03\x03\x00\x00\x1e\xe0" + // 0x01A00303: 0x00001EE0
+ "\x01\xa1\x03\x03\x00\x00\x1e\xe1" + // 0x01A10303: 0x00001EE1
+ "\x01\xa0\x03#\x00\x00\x1e\xe2" + // 0x01A00323: 0x00001EE2
+ "\x01\xa1\x03#\x00\x00\x1e\xe3" + // 0x01A10323: 0x00001EE3
+ "\x00U\x03#\x00\x00\x1e\xe4" + // 0x00550323: 0x00001EE4
+ "\x00u\x03#\x00\x00\x1e\xe5" + // 0x00750323: 0x00001EE5
+ "\x00U\x03\t\x00\x00\x1e\xe6" + // 0x00550309: 0x00001EE6
+ "\x00u\x03\t\x00\x00\x1e\xe7" + // 0x00750309: 0x00001EE7
+ "\x01\xaf\x03\x01\x00\x00\x1e\xe8" + // 0x01AF0301: 0x00001EE8
+ "\x01\xb0\x03\x01\x00\x00\x1e\xe9" + // 0x01B00301: 0x00001EE9
+ "\x01\xaf\x03\x00\x00\x00\x1e\xea" + // 0x01AF0300: 0x00001EEA
+ "\x01\xb0\x03\x00\x00\x00\x1e\xeb" + // 0x01B00300: 0x00001EEB
+ "\x01\xaf\x03\t\x00\x00\x1e\xec" + // 0x01AF0309: 0x00001EEC
+ "\x01\xb0\x03\t\x00\x00\x1e\xed" + // 0x01B00309: 0x00001EED
+ "\x01\xaf\x03\x03\x00\x00\x1e\xee" + // 0x01AF0303: 0x00001EEE
+ "\x01\xb0\x03\x03\x00\x00\x1e\xef" + // 0x01B00303: 0x00001EEF
+ "\x01\xaf\x03#\x00\x00\x1e\xf0" + // 0x01AF0323: 0x00001EF0
+ "\x01\xb0\x03#\x00\x00\x1e\xf1" + // 0x01B00323: 0x00001EF1
+ "\x00Y\x03\x00\x00\x00\x1e\xf2" + // 0x00590300: 0x00001EF2
+ "\x00y\x03\x00\x00\x00\x1e\xf3" + // 0x00790300: 0x00001EF3
+ "\x00Y\x03#\x00\x00\x1e\xf4" + // 0x00590323: 0x00001EF4
+ "\x00y\x03#\x00\x00\x1e\xf5" + // 0x00790323: 0x00001EF5
+ "\x00Y\x03\t\x00\x00\x1e\xf6" + // 0x00590309: 0x00001EF6
+ "\x00y\x03\t\x00\x00\x1e\xf7" + // 0x00790309: 0x00001EF7
+ "\x00Y\x03\x03\x00\x00\x1e\xf8" + // 0x00590303: 0x00001EF8
+ "\x00y\x03\x03\x00\x00\x1e\xf9" + // 0x00790303: 0x00001EF9
+ "\x03\xb1\x03\x13\x00\x00\x1f\x00" + // 0x03B10313: 0x00001F00
+ "\x03\xb1\x03\x14\x00\x00\x1f\x01" + // 0x03B10314: 0x00001F01
+ "\x1f\x00\x03\x00\x00\x00\x1f\x02" + // 0x1F000300: 0x00001F02
+ "\x1f\x01\x03\x00\x00\x00\x1f\x03" + // 0x1F010300: 0x00001F03
+ "\x1f\x00\x03\x01\x00\x00\x1f\x04" + // 0x1F000301: 0x00001F04
+ "\x1f\x01\x03\x01\x00\x00\x1f\x05" + // 0x1F010301: 0x00001F05
+ "\x1f\x00\x03B\x00\x00\x1f\x06" + // 0x1F000342: 0x00001F06
+ "\x1f\x01\x03B\x00\x00\x1f\a" + // 0x1F010342: 0x00001F07
+ "\x03\x91\x03\x13\x00\x00\x1f\b" + // 0x03910313: 0x00001F08
+ "\x03\x91\x03\x14\x00\x00\x1f\t" + // 0x03910314: 0x00001F09
+ "\x1f\b\x03\x00\x00\x00\x1f\n" + // 0x1F080300: 0x00001F0A
+ "\x1f\t\x03\x00\x00\x00\x1f\v" + // 0x1F090300: 0x00001F0B
+ "\x1f\b\x03\x01\x00\x00\x1f\f" + // 0x1F080301: 0x00001F0C
+ "\x1f\t\x03\x01\x00\x00\x1f\r" + // 0x1F090301: 0x00001F0D
+ "\x1f\b\x03B\x00\x00\x1f\x0e" + // 0x1F080342: 0x00001F0E
+ "\x1f\t\x03B\x00\x00\x1f\x0f" + // 0x1F090342: 0x00001F0F
+ "\x03\xb5\x03\x13\x00\x00\x1f\x10" + // 0x03B50313: 0x00001F10
+ "\x03\xb5\x03\x14\x00\x00\x1f\x11" + // 0x03B50314: 0x00001F11
+ "\x1f\x10\x03\x00\x00\x00\x1f\x12" + // 0x1F100300: 0x00001F12
+ "\x1f\x11\x03\x00\x00\x00\x1f\x13" + // 0x1F110300: 0x00001F13
+ "\x1f\x10\x03\x01\x00\x00\x1f\x14" + // 0x1F100301: 0x00001F14
+ "\x1f\x11\x03\x01\x00\x00\x1f\x15" + // 0x1F110301: 0x00001F15
+ "\x03\x95\x03\x13\x00\x00\x1f\x18" + // 0x03950313: 0x00001F18
+ "\x03\x95\x03\x14\x00\x00\x1f\x19" + // 0x03950314: 0x00001F19
+ "\x1f\x18\x03\x00\x00\x00\x1f\x1a" + // 0x1F180300: 0x00001F1A
+ "\x1f\x19\x03\x00\x00\x00\x1f\x1b" + // 0x1F190300: 0x00001F1B
+ "\x1f\x18\x03\x01\x00\x00\x1f\x1c" + // 0x1F180301: 0x00001F1C
+ "\x1f\x19\x03\x01\x00\x00\x1f\x1d" + // 0x1F190301: 0x00001F1D
+ "\x03\xb7\x03\x13\x00\x00\x1f " + // 0x03B70313: 0x00001F20
+ "\x03\xb7\x03\x14\x00\x00\x1f!" + // 0x03B70314: 0x00001F21
+ "\x1f \x03\x00\x00\x00\x1f\"" + // 0x1F200300: 0x00001F22
+ "\x1f!\x03\x00\x00\x00\x1f#" + // 0x1F210300: 0x00001F23
+ "\x1f \x03\x01\x00\x00\x1f$" + // 0x1F200301: 0x00001F24
+ "\x1f!\x03\x01\x00\x00\x1f%" + // 0x1F210301: 0x00001F25
+ "\x1f \x03B\x00\x00\x1f&" + // 0x1F200342: 0x00001F26
+ "\x1f!\x03B\x00\x00\x1f'" + // 0x1F210342: 0x00001F27
+ "\x03\x97\x03\x13\x00\x00\x1f(" + // 0x03970313: 0x00001F28
+ "\x03\x97\x03\x14\x00\x00\x1f)" + // 0x03970314: 0x00001F29
+ "\x1f(\x03\x00\x00\x00\x1f*" + // 0x1F280300: 0x00001F2A
+ "\x1f)\x03\x00\x00\x00\x1f+" + // 0x1F290300: 0x00001F2B
+ "\x1f(\x03\x01\x00\x00\x1f," + // 0x1F280301: 0x00001F2C
+ "\x1f)\x03\x01\x00\x00\x1f-" + // 0x1F290301: 0x00001F2D
+ "\x1f(\x03B\x00\x00\x1f." + // 0x1F280342: 0x00001F2E
+ "\x1f)\x03B\x00\x00\x1f/" + // 0x1F290342: 0x00001F2F
+ "\x03\xb9\x03\x13\x00\x00\x1f0" + // 0x03B90313: 0x00001F30
+ "\x03\xb9\x03\x14\x00\x00\x1f1" + // 0x03B90314: 0x00001F31
+ "\x1f0\x03\x00\x00\x00\x1f2" + // 0x1F300300: 0x00001F32
+ "\x1f1\x03\x00\x00\x00\x1f3" + // 0x1F310300: 0x00001F33
+ "\x1f0\x03\x01\x00\x00\x1f4" + // 0x1F300301: 0x00001F34
+ "\x1f1\x03\x01\x00\x00\x1f5" + // 0x1F310301: 0x00001F35
+ "\x1f0\x03B\x00\x00\x1f6" + // 0x1F300342: 0x00001F36
+ "\x1f1\x03B\x00\x00\x1f7" + // 0x1F310342: 0x00001F37
+ "\x03\x99\x03\x13\x00\x00\x1f8" + // 0x03990313: 0x00001F38
+ "\x03\x99\x03\x14\x00\x00\x1f9" + // 0x03990314: 0x00001F39
+ "\x1f8\x03\x00\x00\x00\x1f:" + // 0x1F380300: 0x00001F3A
+ "\x1f9\x03\x00\x00\x00\x1f;" + // 0x1F390300: 0x00001F3B
+ "\x1f8\x03\x01\x00\x00\x1f<" + // 0x1F380301: 0x00001F3C
+ "\x1f9\x03\x01\x00\x00\x1f=" + // 0x1F390301: 0x00001F3D
+ "\x1f8\x03B\x00\x00\x1f>" + // 0x1F380342: 0x00001F3E
+ "\x1f9\x03B\x00\x00\x1f?" + // 0x1F390342: 0x00001F3F
+ "\x03\xbf\x03\x13\x00\x00\x1f@" + // 0x03BF0313: 0x00001F40
+ "\x03\xbf\x03\x14\x00\x00\x1fA" + // 0x03BF0314: 0x00001F41
+ "\x1f@\x03\x00\x00\x00\x1fB" + // 0x1F400300: 0x00001F42
+ "\x1fA\x03\x00\x00\x00\x1fC" + // 0x1F410300: 0x00001F43
+ "\x1f@\x03\x01\x00\x00\x1fD" + // 0x1F400301: 0x00001F44
+ "\x1fA\x03\x01\x00\x00\x1fE" + // 0x1F410301: 0x00001F45
+ "\x03\x9f\x03\x13\x00\x00\x1fH" + // 0x039F0313: 0x00001F48
+ "\x03\x9f\x03\x14\x00\x00\x1fI" + // 0x039F0314: 0x00001F49
+ "\x1fH\x03\x00\x00\x00\x1fJ" + // 0x1F480300: 0x00001F4A
+ "\x1fI\x03\x00\x00\x00\x1fK" + // 0x1F490300: 0x00001F4B
+ "\x1fH\x03\x01\x00\x00\x1fL" + // 0x1F480301: 0x00001F4C
+ "\x1fI\x03\x01\x00\x00\x1fM" + // 0x1F490301: 0x00001F4D
+ "\x03\xc5\x03\x13\x00\x00\x1fP" + // 0x03C50313: 0x00001F50
+ "\x03\xc5\x03\x14\x00\x00\x1fQ" + // 0x03C50314: 0x00001F51
+ "\x1fP\x03\x00\x00\x00\x1fR" + // 0x1F500300: 0x00001F52
+ "\x1fQ\x03\x00\x00\x00\x1fS" + // 0x1F510300: 0x00001F53
+ "\x1fP\x03\x01\x00\x00\x1fT" + // 0x1F500301: 0x00001F54
+ "\x1fQ\x03\x01\x00\x00\x1fU" + // 0x1F510301: 0x00001F55
+ "\x1fP\x03B\x00\x00\x1fV" + // 0x1F500342: 0x00001F56
+ "\x1fQ\x03B\x00\x00\x1fW" + // 0x1F510342: 0x00001F57
+ "\x03\xa5\x03\x14\x00\x00\x1fY" + // 0x03A50314: 0x00001F59
+ "\x1fY\x03\x00\x00\x00\x1f[" + // 0x1F590300: 0x00001F5B
+ "\x1fY\x03\x01\x00\x00\x1f]" + // 0x1F590301: 0x00001F5D
+ "\x1fY\x03B\x00\x00\x1f_" + // 0x1F590342: 0x00001F5F
+ "\x03\xc9\x03\x13\x00\x00\x1f`" + // 0x03C90313: 0x00001F60
+ "\x03\xc9\x03\x14\x00\x00\x1fa" + // 0x03C90314: 0x00001F61
+ "\x1f`\x03\x00\x00\x00\x1fb" + // 0x1F600300: 0x00001F62
+ "\x1fa\x03\x00\x00\x00\x1fc" + // 0x1F610300: 0x00001F63
+ "\x1f`\x03\x01\x00\x00\x1fd" + // 0x1F600301: 0x00001F64
+ "\x1fa\x03\x01\x00\x00\x1fe" + // 0x1F610301: 0x00001F65
+ "\x1f`\x03B\x00\x00\x1ff" + // 0x1F600342: 0x00001F66
+ "\x1fa\x03B\x00\x00\x1fg" + // 0x1F610342: 0x00001F67
+ "\x03\xa9\x03\x13\x00\x00\x1fh" + // 0x03A90313: 0x00001F68
+ "\x03\xa9\x03\x14\x00\x00\x1fi" + // 0x03A90314: 0x00001F69
+ "\x1fh\x03\x00\x00\x00\x1fj" + // 0x1F680300: 0x00001F6A
+ "\x1fi\x03\x00\x00\x00\x1fk" + // 0x1F690300: 0x00001F6B
+ "\x1fh\x03\x01\x00\x00\x1fl" + // 0x1F680301: 0x00001F6C
+ "\x1fi\x03\x01\x00\x00\x1fm" + // 0x1F690301: 0x00001F6D
+ "\x1fh\x03B\x00\x00\x1fn" + // 0x1F680342: 0x00001F6E
+ "\x1fi\x03B\x00\x00\x1fo" + // 0x1F690342: 0x00001F6F
+ "\x03\xb1\x03\x00\x00\x00\x1fp" + // 0x03B10300: 0x00001F70
+ "\x03\xb5\x03\x00\x00\x00\x1fr" + // 0x03B50300: 0x00001F72
+ "\x03\xb7\x03\x00\x00\x00\x1ft" + // 0x03B70300: 0x00001F74
+ "\x03\xb9\x03\x00\x00\x00\x1fv" + // 0x03B90300: 0x00001F76
+ "\x03\xbf\x03\x00\x00\x00\x1fx" + // 0x03BF0300: 0x00001F78
+ "\x03\xc5\x03\x00\x00\x00\x1fz" + // 0x03C50300: 0x00001F7A
+ "\x03\xc9\x03\x00\x00\x00\x1f|" + // 0x03C90300: 0x00001F7C
+ "\x1f\x00\x03E\x00\x00\x1f\x80" + // 0x1F000345: 0x00001F80
+ "\x1f\x01\x03E\x00\x00\x1f\x81" + // 0x1F010345: 0x00001F81
+ "\x1f\x02\x03E\x00\x00\x1f\x82" + // 0x1F020345: 0x00001F82
+ "\x1f\x03\x03E\x00\x00\x1f\x83" + // 0x1F030345: 0x00001F83
+ "\x1f\x04\x03E\x00\x00\x1f\x84" + // 0x1F040345: 0x00001F84
+ "\x1f\x05\x03E\x00\x00\x1f\x85" + // 0x1F050345: 0x00001F85
+ "\x1f\x06\x03E\x00\x00\x1f\x86" + // 0x1F060345: 0x00001F86
+ "\x1f\a\x03E\x00\x00\x1f\x87" + // 0x1F070345: 0x00001F87
+ "\x1f\b\x03E\x00\x00\x1f\x88" + // 0x1F080345: 0x00001F88
+ "\x1f\t\x03E\x00\x00\x1f\x89" + // 0x1F090345: 0x00001F89
+ "\x1f\n\x03E\x00\x00\x1f\x8a" + // 0x1F0A0345: 0x00001F8A
+ "\x1f\v\x03E\x00\x00\x1f\x8b" + // 0x1F0B0345: 0x00001F8B
+ "\x1f\f\x03E\x00\x00\x1f\x8c" + // 0x1F0C0345: 0x00001F8C
+ "\x1f\r\x03E\x00\x00\x1f\x8d" + // 0x1F0D0345: 0x00001F8D
+ "\x1f\x0e\x03E\x00\x00\x1f\x8e" + // 0x1F0E0345: 0x00001F8E
+ "\x1f\x0f\x03E\x00\x00\x1f\x8f" + // 0x1F0F0345: 0x00001F8F
+ "\x1f \x03E\x00\x00\x1f\x90" + // 0x1F200345: 0x00001F90
+ "\x1f!\x03E\x00\x00\x1f\x91" + // 0x1F210345: 0x00001F91
+ "\x1f\"\x03E\x00\x00\x1f\x92" + // 0x1F220345: 0x00001F92
+ "\x1f#\x03E\x00\x00\x1f\x93" + // 0x1F230345: 0x00001F93
+ "\x1f$\x03E\x00\x00\x1f\x94" + // 0x1F240345: 0x00001F94
+ "\x1f%\x03E\x00\x00\x1f\x95" + // 0x1F250345: 0x00001F95
+ "\x1f&\x03E\x00\x00\x1f\x96" + // 0x1F260345: 0x00001F96
+ "\x1f'\x03E\x00\x00\x1f\x97" + // 0x1F270345: 0x00001F97
+ "\x1f(\x03E\x00\x00\x1f\x98" + // 0x1F280345: 0x00001F98
+ "\x1f)\x03E\x00\x00\x1f\x99" + // 0x1F290345: 0x00001F99
+ "\x1f*\x03E\x00\x00\x1f\x9a" + // 0x1F2A0345: 0x00001F9A
+ "\x1f+\x03E\x00\x00\x1f\x9b" + // 0x1F2B0345: 0x00001F9B
+ "\x1f,\x03E\x00\x00\x1f\x9c" + // 0x1F2C0345: 0x00001F9C
+ "\x1f-\x03E\x00\x00\x1f\x9d" + // 0x1F2D0345: 0x00001F9D
+ "\x1f.\x03E\x00\x00\x1f\x9e" + // 0x1F2E0345: 0x00001F9E
+ "\x1f/\x03E\x00\x00\x1f\x9f" + // 0x1F2F0345: 0x00001F9F
+ "\x1f`\x03E\x00\x00\x1f\xa0" + // 0x1F600345: 0x00001FA0
+ "\x1fa\x03E\x00\x00\x1f\xa1" + // 0x1F610345: 0x00001FA1
+ "\x1fb\x03E\x00\x00\x1f\xa2" + // 0x1F620345: 0x00001FA2
+ "\x1fc\x03E\x00\x00\x1f\xa3" + // 0x1F630345: 0x00001FA3
+ "\x1fd\x03E\x00\x00\x1f\xa4" + // 0x1F640345: 0x00001FA4
+ "\x1fe\x03E\x00\x00\x1f\xa5" + // 0x1F650345: 0x00001FA5
+ "\x1ff\x03E\x00\x00\x1f\xa6" + // 0x1F660345: 0x00001FA6
+ "\x1fg\x03E\x00\x00\x1f\xa7" + // 0x1F670345: 0x00001FA7
+ "\x1fh\x03E\x00\x00\x1f\xa8" + // 0x1F680345: 0x00001FA8
+ "\x1fi\x03E\x00\x00\x1f\xa9" + // 0x1F690345: 0x00001FA9
+ "\x1fj\x03E\x00\x00\x1f\xaa" + // 0x1F6A0345: 0x00001FAA
+ "\x1fk\x03E\x00\x00\x1f\xab" + // 0x1F6B0345: 0x00001FAB
+ "\x1fl\x03E\x00\x00\x1f\xac" + // 0x1F6C0345: 0x00001FAC
+ "\x1fm\x03E\x00\x00\x1f\xad" + // 0x1F6D0345: 0x00001FAD
+ "\x1fn\x03E\x00\x00\x1f\xae" + // 0x1F6E0345: 0x00001FAE
+ "\x1fo\x03E\x00\x00\x1f\xaf" + // 0x1F6F0345: 0x00001FAF
+ "\x03\xb1\x03\x06\x00\x00\x1f\xb0" + // 0x03B10306: 0x00001FB0
+ "\x03\xb1\x03\x04\x00\x00\x1f\xb1" + // 0x03B10304: 0x00001FB1
+ "\x1fp\x03E\x00\x00\x1f\xb2" + // 0x1F700345: 0x00001FB2
+ "\x03\xb1\x03E\x00\x00\x1f\xb3" + // 0x03B10345: 0x00001FB3
+ "\x03\xac\x03E\x00\x00\x1f\xb4" + // 0x03AC0345: 0x00001FB4
+ "\x03\xb1\x03B\x00\x00\x1f\xb6" + // 0x03B10342: 0x00001FB6
+ "\x1f\xb6\x03E\x00\x00\x1f\xb7" + // 0x1FB60345: 0x00001FB7
+ "\x03\x91\x03\x06\x00\x00\x1f\xb8" + // 0x03910306: 0x00001FB8
+ "\x03\x91\x03\x04\x00\x00\x1f\xb9" + // 0x03910304: 0x00001FB9
+ "\x03\x91\x03\x00\x00\x00\x1f\xba" + // 0x03910300: 0x00001FBA
+ "\x03\x91\x03E\x00\x00\x1f\xbc" + // 0x03910345: 0x00001FBC
+ "\x00\xa8\x03B\x00\x00\x1f\xc1" + // 0x00A80342: 0x00001FC1
+ "\x1ft\x03E\x00\x00\x1f\xc2" + // 0x1F740345: 0x00001FC2
+ "\x03\xb7\x03E\x00\x00\x1f\xc3" + // 0x03B70345: 0x00001FC3
+ "\x03\xae\x03E\x00\x00\x1f\xc4" + // 0x03AE0345: 0x00001FC4
+ "\x03\xb7\x03B\x00\x00\x1f\xc6" + // 0x03B70342: 0x00001FC6
+ "\x1f\xc6\x03E\x00\x00\x1f\xc7" + // 0x1FC60345: 0x00001FC7
+ "\x03\x95\x03\x00\x00\x00\x1f\xc8" + // 0x03950300: 0x00001FC8
+ "\x03\x97\x03\x00\x00\x00\x1f\xca" + // 0x03970300: 0x00001FCA
+ "\x03\x97\x03E\x00\x00\x1f\xcc" + // 0x03970345: 0x00001FCC
+ "\x1f\xbf\x03\x00\x00\x00\x1f\xcd" + // 0x1FBF0300: 0x00001FCD
+ "\x1f\xbf\x03\x01\x00\x00\x1f\xce" + // 0x1FBF0301: 0x00001FCE
+ "\x1f\xbf\x03B\x00\x00\x1f\xcf" + // 0x1FBF0342: 0x00001FCF
+ "\x03\xb9\x03\x06\x00\x00\x1f\xd0" + // 0x03B90306: 0x00001FD0
+ "\x03\xb9\x03\x04\x00\x00\x1f\xd1" + // 0x03B90304: 0x00001FD1
+ "\x03\xca\x03\x00\x00\x00\x1f\xd2" + // 0x03CA0300: 0x00001FD2
+ "\x03\xb9\x03B\x00\x00\x1f\xd6" + // 0x03B90342: 0x00001FD6
+ "\x03\xca\x03B\x00\x00\x1f\xd7" + // 0x03CA0342: 0x00001FD7
+ "\x03\x99\x03\x06\x00\x00\x1f\xd8" + // 0x03990306: 0x00001FD8
+ "\x03\x99\x03\x04\x00\x00\x1f\xd9" + // 0x03990304: 0x00001FD9
+ "\x03\x99\x03\x00\x00\x00\x1f\xda" + // 0x03990300: 0x00001FDA
+ "\x1f\xfe\x03\x00\x00\x00\x1f\xdd" + // 0x1FFE0300: 0x00001FDD
+ "\x1f\xfe\x03\x01\x00\x00\x1f\xde" + // 0x1FFE0301: 0x00001FDE
+ "\x1f\xfe\x03B\x00\x00\x1f\xdf" + // 0x1FFE0342: 0x00001FDF
+ "\x03\xc5\x03\x06\x00\x00\x1f\xe0" + // 0x03C50306: 0x00001FE0
+ "\x03\xc5\x03\x04\x00\x00\x1f\xe1" + // 0x03C50304: 0x00001FE1
+ "\x03\xcb\x03\x00\x00\x00\x1f\xe2" + // 0x03CB0300: 0x00001FE2
+ "\x03\xc1\x03\x13\x00\x00\x1f\xe4" + // 0x03C10313: 0x00001FE4
+ "\x03\xc1\x03\x14\x00\x00\x1f\xe5" + // 0x03C10314: 0x00001FE5
+ "\x03\xc5\x03B\x00\x00\x1f\xe6" + // 0x03C50342: 0x00001FE6
+ "\x03\xcb\x03B\x00\x00\x1f\xe7" + // 0x03CB0342: 0x00001FE7
+ "\x03\xa5\x03\x06\x00\x00\x1f\xe8" + // 0x03A50306: 0x00001FE8
+ "\x03\xa5\x03\x04\x00\x00\x1f\xe9" + // 0x03A50304: 0x00001FE9
+ "\x03\xa5\x03\x00\x00\x00\x1f\xea" + // 0x03A50300: 0x00001FEA
+ "\x03\xa1\x03\x14\x00\x00\x1f\xec" + // 0x03A10314: 0x00001FEC
+ "\x00\xa8\x03\x00\x00\x00\x1f\xed" + // 0x00A80300: 0x00001FED
+ "\x1f|\x03E\x00\x00\x1f\xf2" + // 0x1F7C0345: 0x00001FF2
+ "\x03\xc9\x03E\x00\x00\x1f\xf3" + // 0x03C90345: 0x00001FF3
+ "\x03\xce\x03E\x00\x00\x1f\xf4" + // 0x03CE0345: 0x00001FF4
+ "\x03\xc9\x03B\x00\x00\x1f\xf6" + // 0x03C90342: 0x00001FF6
+ "\x1f\xf6\x03E\x00\x00\x1f\xf7" + // 0x1FF60345: 0x00001FF7
+ "\x03\x9f\x03\x00\x00\x00\x1f\xf8" + // 0x039F0300: 0x00001FF8
+ "\x03\xa9\x03\x00\x00\x00\x1f\xfa" + // 0x03A90300: 0x00001FFA
+ "\x03\xa9\x03E\x00\x00\x1f\xfc" + // 0x03A90345: 0x00001FFC
+ "!\x90\x038\x00\x00!\x9a" + // 0x21900338: 0x0000219A
+ "!\x92\x038\x00\x00!\x9b" + // 0x21920338: 0x0000219B
+ "!\x94\x038\x00\x00!\xae" + // 0x21940338: 0x000021AE
+ "!\xd0\x038\x00\x00!\xcd" + // 0x21D00338: 0x000021CD
+ "!\xd4\x038\x00\x00!\xce" + // 0x21D40338: 0x000021CE
+ "!\xd2\x038\x00\x00!\xcf" + // 0x21D20338: 0x000021CF
+ "\"\x03\x038\x00\x00\"\x04" + // 0x22030338: 0x00002204
+ "\"\b\x038\x00\x00\"\t" + // 0x22080338: 0x00002209
+ "\"\v\x038\x00\x00\"\f" + // 0x220B0338: 0x0000220C
+ "\"#\x038\x00\x00\"$" + // 0x22230338: 0x00002224
+ "\"%\x038\x00\x00\"&" + // 0x22250338: 0x00002226
+ "\"<\x038\x00\x00\"A" + // 0x223C0338: 0x00002241
+ "\"C\x038\x00\x00\"D" + // 0x22430338: 0x00002244
+ "\"E\x038\x00\x00\"G" + // 0x22450338: 0x00002247
+ "\"H\x038\x00\x00\"I" + // 0x22480338: 0x00002249
+ "\x00=\x038\x00\x00\"`" + // 0x003D0338: 0x00002260
+ "\"a\x038\x00\x00\"b" + // 0x22610338: 0x00002262
+ "\"M\x038\x00\x00\"m" + // 0x224D0338: 0x0000226D
+ "\x00<\x038\x00\x00\"n" + // 0x003C0338: 0x0000226E
+ "\x00>\x038\x00\x00\"o" + // 0x003E0338: 0x0000226F
+ "\"d\x038\x00\x00\"p" + // 0x22640338: 0x00002270
+ "\"e\x038\x00\x00\"q" + // 0x22650338: 0x00002271
+ "\"r\x038\x00\x00\"t" + // 0x22720338: 0x00002274
+ "\"s\x038\x00\x00\"u" + // 0x22730338: 0x00002275
+ "\"v\x038\x00\x00\"x" + // 0x22760338: 0x00002278
+ "\"w\x038\x00\x00\"y" + // 0x22770338: 0x00002279
+ "\"z\x038\x00\x00\"\x80" + // 0x227A0338: 0x00002280
+ "\"{\x038\x00\x00\"\x81" + // 0x227B0338: 0x00002281
+ "\"\x82\x038\x00\x00\"\x84" + // 0x22820338: 0x00002284
+ "\"\x83\x038\x00\x00\"\x85" + // 0x22830338: 0x00002285
+ "\"\x86\x038\x00\x00\"\x88" + // 0x22860338: 0x00002288
+ "\"\x87\x038\x00\x00\"\x89" + // 0x22870338: 0x00002289
+ "\"\xa2\x038\x00\x00\"\xac" + // 0x22A20338: 0x000022AC
+ "\"\xa8\x038\x00\x00\"\xad" + // 0x22A80338: 0x000022AD
+ "\"\xa9\x038\x00\x00\"\xae" + // 0x22A90338: 0x000022AE
+ "\"\xab\x038\x00\x00\"\xaf" + // 0x22AB0338: 0x000022AF
+ "\"|\x038\x00\x00\"\xe0" + // 0x227C0338: 0x000022E0
+ "\"}\x038\x00\x00\"\xe1" + // 0x227D0338: 0x000022E1
+ "\"\x91\x038\x00\x00\"\xe2" + // 0x22910338: 0x000022E2
+ "\"\x92\x038\x00\x00\"\xe3" + // 0x22920338: 0x000022E3
+ "\"\xb2\x038\x00\x00\"\xea" + // 0x22B20338: 0x000022EA
+ "\"\xb3\x038\x00\x00\"\xeb" + // 0x22B30338: 0x000022EB
+ "\"\xb4\x038\x00\x00\"\xec" + // 0x22B40338: 0x000022EC
+ "\"\xb5\x038\x00\x00\"\xed" + // 0x22B50338: 0x000022ED
+ "0K0\x99\x00\x000L" + // 0x304B3099: 0x0000304C
+ "0M0\x99\x00\x000N" + // 0x304D3099: 0x0000304E
+ "0O0\x99\x00\x000P" + // 0x304F3099: 0x00003050
+ "0Q0\x99\x00\x000R" + // 0x30513099: 0x00003052
+ "0S0\x99\x00\x000T" + // 0x30533099: 0x00003054
+ "0U0\x99\x00\x000V" + // 0x30553099: 0x00003056
+ "0W0\x99\x00\x000X" + // 0x30573099: 0x00003058
+ "0Y0\x99\x00\x000Z" + // 0x30593099: 0x0000305A
+ "0[0\x99\x00\x000\\" + // 0x305B3099: 0x0000305C
+ "0]0\x99\x00\x000^" + // 0x305D3099: 0x0000305E
+ "0_0\x99\x00\x000`" + // 0x305F3099: 0x00003060
+ "0a0\x99\x00\x000b" + // 0x30613099: 0x00003062
+ "0d0\x99\x00\x000e" + // 0x30643099: 0x00003065
+ "0f0\x99\x00\x000g" + // 0x30663099: 0x00003067
+ "0h0\x99\x00\x000i" + // 0x30683099: 0x00003069
+ "0o0\x99\x00\x000p" + // 0x306F3099: 0x00003070
+ "0o0\x9a\x00\x000q" + // 0x306F309A: 0x00003071
+ "0r0\x99\x00\x000s" + // 0x30723099: 0x00003073
+ "0r0\x9a\x00\x000t" + // 0x3072309A: 0x00003074
+ "0u0\x99\x00\x000v" + // 0x30753099: 0x00003076
+ "0u0\x9a\x00\x000w" + // 0x3075309A: 0x00003077
+ "0x0\x99\x00\x000y" + // 0x30783099: 0x00003079
+ "0x0\x9a\x00\x000z" + // 0x3078309A: 0x0000307A
+ "0{0\x99\x00\x000|" + // 0x307B3099: 0x0000307C
+ "0{0\x9a\x00\x000}" + // 0x307B309A: 0x0000307D
+ "0F0\x99\x00\x000\x94" + // 0x30463099: 0x00003094
+ "0\x9d0\x99\x00\x000\x9e" + // 0x309D3099: 0x0000309E
+ "0\xab0\x99\x00\x000\xac" + // 0x30AB3099: 0x000030AC
+ "0\xad0\x99\x00\x000\xae" + // 0x30AD3099: 0x000030AE
+ "0\xaf0\x99\x00\x000\xb0" + // 0x30AF3099: 0x000030B0
+ "0\xb10\x99\x00\x000\xb2" + // 0x30B13099: 0x000030B2
+ "0\xb30\x99\x00\x000\xb4" + // 0x30B33099: 0x000030B4
+ "0\xb50\x99\x00\x000\xb6" + // 0x30B53099: 0x000030B6
+ "0\xb70\x99\x00\x000\xb8" + // 0x30B73099: 0x000030B8
+ "0\xb90\x99\x00\x000\xba" + // 0x30B93099: 0x000030BA
+ "0\xbb0\x99\x00\x000\xbc" + // 0x30BB3099: 0x000030BC
+ "0\xbd0\x99\x00\x000\xbe" + // 0x30BD3099: 0x000030BE
+ "0\xbf0\x99\x00\x000\xc0" + // 0x30BF3099: 0x000030C0
+ "0\xc10\x99\x00\x000\xc2" + // 0x30C13099: 0x000030C2
+ "0\xc40\x99\x00\x000\xc5" + // 0x30C43099: 0x000030C5
+ "0\xc60\x99\x00\x000\xc7" + // 0x30C63099: 0x000030C7
+ "0\xc80\x99\x00\x000\xc9" + // 0x30C83099: 0x000030C9
+ "0\xcf0\x99\x00\x000\xd0" + // 0x30CF3099: 0x000030D0
+ "0\xcf0\x9a\x00\x000\xd1" + // 0x30CF309A: 0x000030D1
+ "0\xd20\x99\x00\x000\xd3" + // 0x30D23099: 0x000030D3
+ "0\xd20\x9a\x00\x000\xd4" + // 0x30D2309A: 0x000030D4
+ "0\xd50\x99\x00\x000\xd6" + // 0x30D53099: 0x000030D6
+ "0\xd50\x9a\x00\x000\xd7" + // 0x30D5309A: 0x000030D7
+ "0\xd80\x99\x00\x000\xd9" + // 0x30D83099: 0x000030D9
+ "0\xd80\x9a\x00\x000\xda" + // 0x30D8309A: 0x000030DA
+ "0\xdb0\x99\x00\x000\xdc" + // 0x30DB3099: 0x000030DC
+ "0\xdb0\x9a\x00\x000\xdd" + // 0x30DB309A: 0x000030DD
+ "0\xa60\x99\x00\x000\xf4" + // 0x30A63099: 0x000030F4
+ "0\xef0\x99\x00\x000\xf7" + // 0x30EF3099: 0x000030F7
+ "0\xf00\x99\x00\x000\xf8" + // 0x30F03099: 0x000030F8
+ "0\xf10\x99\x00\x000\xf9" + // 0x30F13099: 0x000030F9
+ "0\xf20\x99\x00\x000\xfa" + // 0x30F23099: 0x000030FA
+ "0\xfd0\x99\x00\x000\xfe" + // 0x30FD3099: 0x000030FE
+ "\x10\x99\x10\xba\x00\x01\x10\x9a" + // 0x109910BA: 0x0001109A
+ "\x10\x9b\x10\xba\x00\x01\x10\x9c" + // 0x109B10BA: 0x0001109C
+ "\x10\xa5\x10\xba\x00\x01\x10\xab" + // 0x10A510BA: 0x000110AB
+ "\x111\x11'\x00\x01\x11." + // 0x11311127: 0x0001112E
+ "\x112\x11'\x00\x01\x11/" + // 0x11321127: 0x0001112F
+ "\x13G\x13>\x00\x01\x13K" + // 0x1347133E: 0x0001134B
+ "\x13G\x13W\x00\x01\x13L" + // 0x13471357: 0x0001134C
+ "\x14\xb9\x14\xba\x00\x01\x14\xbb" + // 0x14B914BA: 0x000114BB
+ "\x14\xb9\x14\xb0\x00\x01\x14\xbc" + // 0x14B914B0: 0x000114BC
+ "\x14\xb9\x14\xbd\x00\x01\x14\xbe" + // 0x14B914BD: 0x000114BE
+ "\x15\xb8\x15\xaf\x00\x01\x15\xba" + // 0x15B815AF: 0x000115BA
+ "\x15\xb9\x15\xaf\x00\x01\x15\xbb" + // 0x15B915AF: 0x000115BB
+ "\x195\x190\x00\x01\x198" + // 0x19351930: 0x00011938
+ ""
+ // Total size of tables: 55KB (56160 bytes)
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/transform.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/transform.go
index a1d366ae48..a1d366ae48 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/transform.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/transform.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/trie.go b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/trie.go
index 423386bf43..423386bf43 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/trie.go
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/trie.go
diff --git a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/ya.make b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/ya.make
index 214616102d..214616102d 100644
--- a/contrib/go/_std_1.20/src/vendor/golang.org/x/text/unicode/norm/ya.make
+++ b/contrib/go/_std_1.21/src/vendor/golang.org/x/text/unicode/norm/ya.make
diff --git a/vendor/github.com/pkg/errors/gotest/ya.make b/vendor/github.com/pkg/errors/gotest/ya.make
index b45b5d354d..47c01e2289 100644
--- a/vendor/github.com/pkg/errors/gotest/ya.make
+++ b/vendor/github.com/pkg/errors/gotest/ya.make
@@ -2,4 +2,6 @@ GO_TEST_FOR(vendor/github.com/pkg/errors)
LICENSE(BSD-2-Clause)
+GO_SKIP_TESTS(TestStackTrace)
+
END()
diff --git a/vendor/github.com/stretchr/testify/assert/gotest/ya.make b/vendor/github.com/stretchr/testify/assert/gotest/ya.make
index ab1a419f78..4fc9cd56c9 100644
--- a/vendor/github.com/stretchr/testify/assert/gotest/ya.make
+++ b/vendor/github.com/stretchr/testify/assert/gotest/ya.make
@@ -11,6 +11,8 @@ GO_SKIP_TESTS(
TestFileExists
TestNoDirExists
TestNoFileExists
+ TestDidPanic
+ TestPanicsWithValue
)
TAG(ya:go_total_report)
diff --git a/vendor/modernc.org/mathutil/ya.make b/vendor/modernc.org/mathutil/ya.make
index 2670dd3e93..687c674f75 100644
--- a/vendor/modernc.org/mathutil/ya.make
+++ b/vendor/modernc.org/mathutil/ya.make
@@ -26,4 +26,4 @@ GO_TEST_SRCS(
END()
-RECURSE(gotest)
+#RECURSE(gotest)